From d2a3e0931a8f3b95b910096d022ffd98adbd075c Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Thu, 15 Oct 2015 15:10:32 +0200 Subject: [PATCH 0001/2855] iio: mma8452: support either of the available interrupt pins This change is important in order for everyone to be easily able to use the driver for one of the supported accelerometer chips! Until now, the driver blindly assumed that the INT1 interrupt line is wired on a user's board. But these devices have 2 interrupt lines and can route their interrupt sources to one of them. Now, if "INT2" is found and matches i2c_client->irq, INT2 will be used. The chip's default actually is INT2, which is why probably many boards will have it wired and can make use of this. Of course, this also falls back to assuming INT1, so for existing users nothing will break. The new functionality is described in the bindings doc. Signed-off-by: Martin Kepplinger For the binding: Acked-by: Rob Herring Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/accel/mma8452.txt | 6 ++++++ drivers/iio/accel/mma8452.c | 21 +++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/accel/mma8452.txt b/Documentation/devicetree/bindings/iio/accel/mma8452.txt index e3c37467d7dac..3c10e8581144a 100644 --- a/Documentation/devicetree/bindings/iio/accel/mma8452.txt +++ b/Documentation/devicetree/bindings/iio/accel/mma8452.txt @@ -7,13 +7,18 @@ Required properties: * "fsl,mma8453" * "fsl,mma8652" * "fsl,mma8653" + - reg: the I2C address of the chip Optional properties: - interrupt-parent: should be the phandle for the interrupt controller + - interrupts: interrupt mapping for GPIO IRQ + - interrupt-names: should contain "INT1" and/or "INT2", the accelerometer's + interrupt line in use. + Example: mma8453fc@1d { @@ -21,4 +26,5 @@ Example: reg = <0x1d>; interrupt-parent = <&gpio1>; interrupts = <5 0>; + interrupt-names = "INT2"; }; diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 1eccc2dcf14cd..116a6e401a6aa 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -29,6 +29,7 @@ #include #include #include +#include #define MMA8452_STATUS 0x00 #define MMA8452_STATUS_DRDY (BIT(2) | BIT(1) | BIT(0)) @@ -1130,13 +1131,21 @@ static int mma8452_probe(struct i2c_client *client, MMA8452_INT_FF_MT; int enabled_interrupts = MMA8452_INT_TRANS | MMA8452_INT_FF_MT; + int irq2; - /* Assume wired to INT1 pin */ - ret = i2c_smbus_write_byte_data(client, - MMA8452_CTRL_REG5, - supported_interrupts); - if (ret < 0) - return ret; + irq2 = of_irq_get_byname(client->dev.of_node, "INT2"); + + if (irq2 == client->irq) { + dev_dbg(&client->dev, "using interrupt line INT2\n"); + } else { + ret = i2c_smbus_write_byte_data(client, + MMA8452_CTRL_REG5, + supported_interrupts); + if (ret < 0) + return ret; + + dev_dbg(&client->dev, "using interrupt line INT1\n"); + } ret = i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG4, -- GitLab From 75b6548f1793c7a79a8b063cd575df9c04dcc122 Mon Sep 17 00:00:00 2001 From: Teodora Baluta Date: Thu, 22 Oct 2015 15:44:50 +0300 Subject: [PATCH 0002/2855] iio: accel: add support for Memsic MXC6255XC sensor This patch adds a minimal implementation for the Memsic MXC6255XC orientation sensing accelerometer. The supported operations are reading raw acceleration values for X/Y axis that can be scaled using the exposed scale. Signed-off-by: Teodora Baluta Signed-off-by: Jonathan Cameron --- drivers/iio/accel/Kconfig | 11 ++ drivers/iio/accel/Makefile | 1 + drivers/iio/accel/mxc6255.c | 198 ++++++++++++++++++++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 drivers/iio/accel/mxc6255.c diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index 969428dd63299..75ac08790bc5a 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig @@ -158,6 +158,17 @@ config MXC4005 To compile this driver as a module, choose M. The module will be called mxc4005. +config MXC6255 + tristate "Memsic MXC6255 Orientation Sensing Accelerometer Driver" + depends on I2C + select REGMAP_I2C + help + Say yes here to build support for the Memsic MXC6255 Orientation + Sensing Accelerometer Driver. + + To compile this driver as a module, choose M here: the module will be + called mxc6255. + config STK8312 tristate "Sensortek STK8312 3-Axis Accelerometer Driver" depends on I2C diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile index 7925f166e6e95..525ed52fab52f 100644 --- a/drivers/iio/accel/Makefile +++ b/drivers/iio/accel/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_MMA9551) += mma9551.o obj-$(CONFIG_MMA9553) += mma9553.o obj-$(CONFIG_MXC4005) += mxc4005.o +obj-$(CONFIG_MXC6255) += mxc6255.o obj-$(CONFIG_STK8312) += stk8312.o obj-$(CONFIG_STK8BA50) += stk8ba50.o diff --git a/drivers/iio/accel/mxc6255.c b/drivers/iio/accel/mxc6255.c new file mode 100644 index 0000000000000..97ccde722e7ba --- /dev/null +++ b/drivers/iio/accel/mxc6255.c @@ -0,0 +1,198 @@ +/* + * MXC6255 - MEMSIC orientation sensing accelerometer + * + * Copyright (c) 2015, Intel Corporation. + * + * This file is subject to the terms and conditions of version 2 of + * the GNU General Public License. See the file COPYING in the main + * directory of this archive for more details. + * + * IIO driver for MXC6255 (7-bit I2C slave address 0x15). + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MXC6255_DRV_NAME "mxc6255" +#define MXC6255_REGMAP_NAME "mxc6255_regmap" + +#define MXC6255_REG_XOUT 0x00 +#define MXC6255_REG_YOUT 0x01 +#define MXC6255_REG_CHIP_ID 0x08 + +#define MXC6255_CHIP_ID 0x05 + +/* + * MXC6255 has only one measurement range: +/- 2G. + * The acceleration output is an 8-bit value. + * + * Scale is calculated as follows: + * (2 + 2) * 9.80665 / (2^8 - 1) = 0.153829 + * + * Scale value for +/- 2G measurement range + */ +#define MXC6255_SCALE 153829 + +enum mxc6255_axis { + AXIS_X, + AXIS_Y, +}; + +struct mxc6255_data { + struct i2c_client *client; + struct regmap *regmap; +}; + +static int mxc6255_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct mxc6255_data *data = iio_priv(indio_dev); + unsigned int reg; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = regmap_read(data->regmap, chan->address, ®); + if (ret < 0) { + dev_err(&data->client->dev, + "Error reading reg %lu\n", chan->address); + return ret; + } + + *val = sign_extend32(reg, 7); + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + *val = 0; + *val2 = MXC6255_SCALE; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} + +static const struct iio_info mxc6255_info = { + .driver_module = THIS_MODULE, + .read_raw = mxc6255_read_raw, +}; + +#define MXC6255_CHANNEL(_axis, reg) { \ + .type = IIO_ACCEL, \ + .modified = 1, \ + .channel2 = IIO_MOD_##_axis, \ + .address = reg, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ +} + +static const struct iio_chan_spec mxc6255_channels[] = { + MXC6255_CHANNEL(X, MXC6255_REG_XOUT), + MXC6255_CHANNEL(Y, MXC6255_REG_YOUT), +}; + +static bool mxc6255_is_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MXC6255_REG_XOUT: + case MXC6255_REG_YOUT: + case MXC6255_REG_CHIP_ID: + return true; + default: + return false; + } +} + +static const struct regmap_config mxc6255_regmap_config = { + .name = MXC6255_REGMAP_NAME, + + .reg_bits = 8, + .val_bits = 8, + + .readable_reg = mxc6255_is_readable_reg, +}; + +static int mxc6255_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct mxc6255_data *data; + struct iio_dev *indio_dev; + struct regmap *regmap; + unsigned int chip_id; + int ret; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + regmap = devm_regmap_init_i2c(client, &mxc6255_regmap_config); + if (IS_ERR(regmap)) { + dev_err(&client->dev, "Error initializing regmap\n"); + return PTR_ERR(regmap); + } + + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + data->client = client; + data->regmap = regmap; + + indio_dev->name = MXC6255_DRV_NAME; + indio_dev->dev.parent = &client->dev; + indio_dev->channels = mxc6255_channels; + indio_dev->num_channels = ARRAY_SIZE(mxc6255_channels); + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &mxc6255_info; + + ret = regmap_read(data->regmap, MXC6255_REG_CHIP_ID, &chip_id); + if (ret < 0) { + dev_err(&client->dev, "Error reading chip id %d\n", ret); + return ret; + } + + if (chip_id != MXC6255_CHIP_ID) { + dev_err(&client->dev, "Invalid chip id %x\n", chip_id); + return -ENODEV; + } + + dev_dbg(&client->dev, "Chip id %x\n", chip_id); + + ret = devm_iio_device_register(&client->dev, indio_dev); + if (ret < 0) { + dev_err(&client->dev, "Could not register IIO device\n"); + return ret; + } + + return 0; +} + +static const struct acpi_device_id mxc6255_acpi_match[] = { + {"MXC6255", 0}, + { } +}; +MODULE_DEVICE_TABLE(acpi, mxc6255_acpi_match); + +static const struct i2c_device_id mxc6255_id[] = { + {"mxc6255", 0}, + { } +}; +MODULE_DEVICE_TABLE(i2c, mxc6255_id); + +static struct i2c_driver mxc6255_driver = { + .driver = { + .name = MXC6255_DRV_NAME, + .acpi_match_table = ACPI_PTR(mxc6255_acpi_match), + }, + .probe = mxc6255_probe, + .id_table = mxc6255_id, +}; + +module_i2c_driver(mxc6255_driver); + +MODULE_AUTHOR("Teodora Baluta "); +MODULE_DESCRIPTION("MEMSIC MXC6255 orientation sensing accelerometer driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From e08e19c331fb249e6dc86365ee80d16045c4aeb1 Mon Sep 17 00:00:00 2001 From: "H. Nikolaus Schaller" Date: Fri, 16 Oct 2015 14:53:38 +0200 Subject: [PATCH 0003/2855] iio:adc: add iio driver for Palmas (twl6035/7) gpadc This driver code was found as: https://android.googlesource.com/kernel/tegra/+/aaabb2e045f31e5a970109ffdaae900dd403d17e/drivers/staging/iio/adc Fixed various compilation issues and test this driver on omap5 evm. Signed-off-by: Pradeep Goudagunta Signed-off-by: H. Nikolaus Schaller Signed-off-by: Marek Belisko Acked-by: Laxman Dewangan Reviewed-by: Jonathan Cameron Acked-by: Lee Jones Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 8 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/palmas_gpadc.c | 817 +++++++++++++++++++++++++++++++++ include/linux/mfd/palmas.h | 75 ++- 4 files changed, 877 insertions(+), 24 deletions(-) create mode 100644 drivers/iio/adc/palmas_gpadc.c diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 7868c744fd4bd..daad72e1266da 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -275,6 +275,14 @@ config NAU7802 To compile this driver as a module, choose M here: the module will be called nau7802. +config PALMAS_GPADC + tristate "TI Palmas General Purpose ADC" + depends on MFD_PALMAS + help + Palmas series pmic chip by Texas Instruments (twl6035/6037) + is used in smartphones and tablets and supports a 16 channel + general purpose ADC. + config QCOM_SPMI_IADC tristate "Qualcomm SPMI PMIC current ADC" depends on SPMI diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 99b37a963a1ef..11cfdfd767984 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_MCP320X) += mcp320x.o obj-$(CONFIG_MCP3422) += mcp3422.o obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o obj-$(CONFIG_NAU7802) += nau7802.o +obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o diff --git a/drivers/iio/adc/palmas_gpadc.c b/drivers/iio/adc/palmas_gpadc.c new file mode 100644 index 0000000000000..71763c5da2ab1 --- /dev/null +++ b/drivers/iio/adc/palmas_gpadc.c @@ -0,0 +1,817 @@ +/* + * palmas-adc.c -- TI PALMAS GPADC. + * + * Copyright (c) 2013, NVIDIA Corporation. All rights reserved. + * + * Author: Pradeep Goudagunta + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MOD_NAME "palmas-gpadc" +#define PALMAS_ADC_CONVERSION_TIMEOUT (msecs_to_jiffies(5000)) +#define PALMAS_TO_BE_CALCULATED 0 +#define PALMAS_GPADC_TRIMINVALID -1 + +struct palmas_gpadc_info { +/* calibration codes and regs */ + int x1; /* lower ideal code */ + int x2; /* higher ideal code */ + int v1; /* expected lower volt reading */ + int v2; /* expected higher volt reading */ + u8 trim1_reg; /* register number for lower trim */ + u8 trim2_reg; /* register number for upper trim */ + int gain; /* calculated from above (after reading trim regs) */ + int offset; /* calculated from above (after reading trim regs) */ + int gain_error; /* calculated from above (after reading trim regs) */ + bool is_uncalibrated; /* if channel has calibration data */ +}; + +#define PALMAS_ADC_INFO(_chan, _x1, _x2, _v1, _v2, _t1, _t2, _is_uncalibrated) \ + [PALMAS_ADC_CH_##_chan] = { \ + .x1 = _x1, \ + .x2 = _x2, \ + .v1 = _v1, \ + .v2 = _v2, \ + .gain = PALMAS_TO_BE_CALCULATED, \ + .offset = PALMAS_TO_BE_CALCULATED, \ + .gain_error = PALMAS_TO_BE_CALCULATED, \ + .trim1_reg = PALMAS_GPADC_TRIM##_t1, \ + .trim2_reg = PALMAS_GPADC_TRIM##_t2, \ + .is_uncalibrated = _is_uncalibrated \ + } + +static struct palmas_gpadc_info palmas_gpadc_info[] = { + PALMAS_ADC_INFO(IN0, 2064, 3112, 630, 950, 1, 2, false), + PALMAS_ADC_INFO(IN1, 2064, 3112, 630, 950, 1, 2, false), + PALMAS_ADC_INFO(IN2, 2064, 3112, 1260, 1900, 3, 4, false), + PALMAS_ADC_INFO(IN3, 2064, 3112, 630, 950, 1, 2, false), + PALMAS_ADC_INFO(IN4, 2064, 3112, 630, 950, 1, 2, false), + PALMAS_ADC_INFO(IN5, 2064, 3112, 630, 950, 1, 2, false), + PALMAS_ADC_INFO(IN6, 2064, 3112, 2520, 3800, 5, 6, false), + PALMAS_ADC_INFO(IN7, 2064, 3112, 2520, 3800, 7, 8, false), + PALMAS_ADC_INFO(IN8, 2064, 3112, 3150, 4750, 9, 10, false), + PALMAS_ADC_INFO(IN9, 2064, 3112, 5670, 8550, 11, 12, false), + PALMAS_ADC_INFO(IN10, 2064, 3112, 3465, 5225, 13, 14, false), + PALMAS_ADC_INFO(IN11, 0, 0, 0, 0, INVALID, INVALID, true), + PALMAS_ADC_INFO(IN12, 0, 0, 0, 0, INVALID, INVALID, true), + PALMAS_ADC_INFO(IN13, 0, 0, 0, 0, INVALID, INVALID, true), + PALMAS_ADC_INFO(IN14, 2064, 3112, 3645, 5225, 15, 16, false), + PALMAS_ADC_INFO(IN15, 0, 0, 0, 0, INVALID, INVALID, true), +}; + +/** + * struct palmas_gpadc - the palmas_gpadc structure + * @ch0_current: channel 0 current source setting + * 0: 0 uA + * 1: 5 uA + * 2: 15 uA + * 3: 20 uA + * @ch3_current: channel 0 current source setting + * 0: 0 uA + * 1: 10 uA + * 2: 400 uA + * 3: 800 uA + * @extended_delay: enable the gpadc extended delay mode + * @auto_conversion_period: define the auto_conversion_period + * + * This is the palmas_gpadc structure to store run-time information + * and pointers for this driver instance. + */ + +struct palmas_gpadc { + struct device *dev; + struct palmas *palmas; + u8 ch0_current; + u8 ch3_current; + bool extended_delay; + int irq; + int irq_auto_0; + int irq_auto_1; + struct palmas_gpadc_info *adc_info; + struct completion conv_completion; + struct palmas_adc_wakeup_property wakeup1_data; + struct palmas_adc_wakeup_property wakeup2_data; + bool wakeup1_enable; + bool wakeup2_enable; + int auto_conversion_period; +}; + +/* + * GPADC lock issue in AUTO mode. + * Impact: In AUTO mode, GPADC conversion can be locked after disabling AUTO + * mode feature. + * Details: + * When the AUTO mode is the only conversion mode enabled, if the AUTO + * mode feature is disabled with bit GPADC_AUTO_CTRL. AUTO_CONV1_EN = 0 + * or bit GPADC_AUTO_CTRL. AUTO_CONV0_EN = 0 during a conversion, the + * conversion mechanism can be seen as locked meaning that all following + * conversion will give 0 as a result. Bit GPADC_STATUS.GPADC_AVAILABLE + * will stay at 0 meaning that GPADC is busy. An RT conversion can unlock + * the GPADC. + * + * Workaround(s): + * To avoid the lock mechanism, the workaround to follow before any stop + * conversion request is: + * Force the GPADC state machine to be ON by using the GPADC_CTRL1. + * GPADC_FORCE bit = 1 + * Shutdown the GPADC AUTO conversion using + * GPADC_AUTO_CTRL.SHUTDOWN_CONV[01] = 0. + * After 100us, force the GPADC state machine to be OFF by using the + * GPADC_CTRL1. GPADC_FORCE bit = 0 + */ + +static int palmas_disable_auto_conversion(struct palmas_gpadc *adc) +{ + int ret; + + ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_CTRL1, + PALMAS_GPADC_CTRL1_GPADC_FORCE, + PALMAS_GPADC_CTRL1_GPADC_FORCE); + if (ret < 0) { + dev_err(adc->dev, "GPADC_CTRL1 update failed: %d\n", ret); + return ret; + } + + ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_AUTO_CTRL, + PALMAS_GPADC_AUTO_CTRL_SHUTDOWN_CONV1 | + PALMAS_GPADC_AUTO_CTRL_SHUTDOWN_CONV0, + 0); + if (ret < 0) { + dev_err(adc->dev, "AUTO_CTRL update failed: %d\n", ret); + return ret; + } + + udelay(100); + + ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_CTRL1, + PALMAS_GPADC_CTRL1_GPADC_FORCE, 0); + if (ret < 0) + dev_err(adc->dev, "GPADC_CTRL1 update failed: %d\n", ret); + + return ret; +} + +static irqreturn_t palmas_gpadc_irq(int irq, void *data) +{ + struct palmas_gpadc *adc = data; + + complete(&adc->conv_completion); + + return IRQ_HANDLED; +} + +static irqreturn_t palmas_gpadc_irq_auto(int irq, void *data) +{ + struct palmas_gpadc *adc = data; + + dev_dbg(adc->dev, "Threshold interrupt %d occurs\n", irq); + palmas_disable_auto_conversion(adc); + + return IRQ_HANDLED; +} + +static int palmas_gpadc_start_mask_interrupt(struct palmas_gpadc *adc, + bool mask) +{ + int ret; + + if (!mask) + ret = palmas_update_bits(adc->palmas, PALMAS_INTERRUPT_BASE, + PALMAS_INT3_MASK, + PALMAS_INT3_MASK_GPADC_EOC_SW, 0); + else + ret = palmas_update_bits(adc->palmas, PALMAS_INTERRUPT_BASE, + PALMAS_INT3_MASK, + PALMAS_INT3_MASK_GPADC_EOC_SW, + PALMAS_INT3_MASK_GPADC_EOC_SW); + if (ret < 0) + dev_err(adc->dev, "GPADC INT MASK update failed: %d\n", ret); + + return ret; +} + +static int palmas_gpadc_enable(struct palmas_gpadc *adc, int adc_chan, + int enable) +{ + unsigned int mask, val; + int ret; + + if (enable) { + val = (adc->extended_delay + << PALMAS_GPADC_RT_CTRL_EXTEND_DELAY_SHIFT); + ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_RT_CTRL, + PALMAS_GPADC_RT_CTRL_EXTEND_DELAY, val); + if (ret < 0) { + dev_err(adc->dev, "RT_CTRL update failed: %d\n", ret); + return ret; + } + + mask = (PALMAS_GPADC_CTRL1_CURRENT_SRC_CH0_MASK | + PALMAS_GPADC_CTRL1_CURRENT_SRC_CH3_MASK | + PALMAS_GPADC_CTRL1_GPADC_FORCE); + val = (adc->ch0_current + << PALMAS_GPADC_CTRL1_CURRENT_SRC_CH0_SHIFT); + val |= (adc->ch3_current + << PALMAS_GPADC_CTRL1_CURRENT_SRC_CH3_SHIFT); + val |= PALMAS_GPADC_CTRL1_GPADC_FORCE; + ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_CTRL1, mask, val); + if (ret < 0) { + dev_err(adc->dev, + "Failed to update current setting: %d\n", ret); + return ret; + } + + mask = (PALMAS_GPADC_SW_SELECT_SW_CONV0_SEL_MASK | + PALMAS_GPADC_SW_SELECT_SW_CONV_EN); + val = (adc_chan | PALMAS_GPADC_SW_SELECT_SW_CONV_EN); + ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_SW_SELECT, mask, val); + if (ret < 0) { + dev_err(adc->dev, "SW_SELECT update failed: %d\n", ret); + return ret; + } + } else { + ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_SW_SELECT, 0); + if (ret < 0) + dev_err(adc->dev, "SW_SELECT write failed: %d\n", ret); + + ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_CTRL1, + PALMAS_GPADC_CTRL1_GPADC_FORCE, 0); + if (ret < 0) { + dev_err(adc->dev, "CTRL1 update failed: %d\n", ret); + return ret; + } + } + + return ret; +} + +static int palmas_gpadc_read_prepare(struct palmas_gpadc *adc, int adc_chan) +{ + int ret; + + ret = palmas_gpadc_enable(adc, adc_chan, true); + if (ret < 0) + return ret; + + return palmas_gpadc_start_mask_interrupt(adc, 0); +} + +static void palmas_gpadc_read_done(struct palmas_gpadc *adc, int adc_chan) +{ + palmas_gpadc_start_mask_interrupt(adc, 1); + palmas_gpadc_enable(adc, adc_chan, false); +} + +static int palmas_gpadc_calibrate(struct palmas_gpadc *adc, int adc_chan) +{ + int k; + int d1; + int d2; + int ret; + int gain; + int x1 = adc->adc_info[adc_chan].x1; + int x2 = adc->adc_info[adc_chan].x2; + int v1 = adc->adc_info[adc_chan].v1; + int v2 = adc->adc_info[adc_chan].v2; + + ret = palmas_read(adc->palmas, PALMAS_TRIM_GPADC_BASE, + adc->adc_info[adc_chan].trim1_reg, &d1); + if (ret < 0) { + dev_err(adc->dev, "TRIM read failed: %d\n", ret); + goto scrub; + } + + ret = palmas_read(adc->palmas, PALMAS_TRIM_GPADC_BASE, + adc->adc_info[adc_chan].trim2_reg, &d2); + if (ret < 0) { + dev_err(adc->dev, "TRIM read failed: %d\n", ret); + goto scrub; + } + + /* gain error calculation */ + k = (1000 + (1000 * (d2 - d1)) / (x2 - x1)); + + /* gain calculation */ + gain = ((v2 - v1) * 1000) / (x2 - x1); + + adc->adc_info[adc_chan].gain_error = k; + adc->adc_info[adc_chan].gain = gain; + /* offset Calculation */ + adc->adc_info[adc_chan].offset = (d1 * 1000) - ((k - 1000) * x1); + +scrub: + return ret; +} + +static int palmas_gpadc_start_conversion(struct palmas_gpadc *adc, int adc_chan) +{ + unsigned int val; + int ret; + + init_completion(&adc->conv_completion); + ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_SW_SELECT, + PALMAS_GPADC_SW_SELECT_SW_START_CONV0, + PALMAS_GPADC_SW_SELECT_SW_START_CONV0); + if (ret < 0) { + dev_err(adc->dev, "SELECT_SW_START write failed: %d\n", ret); + return ret; + } + + ret = wait_for_completion_timeout(&adc->conv_completion, + PALMAS_ADC_CONVERSION_TIMEOUT); + if (ret == 0) { + dev_err(adc->dev, "conversion not completed\n"); + return -ETIMEDOUT; + } + + ret = palmas_bulk_read(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_SW_CONV0_LSB, &val, 2); + if (ret < 0) { + dev_err(adc->dev, "SW_CONV0_LSB read failed: %d\n", ret); + return ret; + } + + ret = val & 0xFFF; + + return ret; +} + +static int palmas_gpadc_get_calibrated_code(struct palmas_gpadc *adc, + int adc_chan, int val) +{ + if (!adc->adc_info[adc_chan].is_uncalibrated) + val = (val*1000 - adc->adc_info[adc_chan].offset) / + adc->adc_info[adc_chan].gain_error; + + if (val < 0) { + dev_err(adc->dev, "Mismatch with calibration\n"); + return 0; + } + + val = (val * adc->adc_info[adc_chan].gain) / 1000; + + return val; +} + +static int palmas_gpadc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, int *val2, long mask) +{ + struct palmas_gpadc *adc = iio_priv(indio_dev); + int adc_chan = chan->channel; + int ret = 0; + + if (adc_chan > PALMAS_ADC_CH_MAX) + return -EINVAL; + + mutex_lock(&indio_dev->mlock); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: + ret = palmas_gpadc_read_prepare(adc, adc_chan); + if (ret < 0) + goto out; + + ret = palmas_gpadc_start_conversion(adc, adc_chan); + if (ret < 0) { + dev_err(adc->dev, + "ADC start conversion failed\n"); + goto out; + } + + if (mask == IIO_CHAN_INFO_PROCESSED) + ret = palmas_gpadc_get_calibrated_code( + adc, adc_chan, ret); + + *val = ret; + + ret = IIO_VAL_INT; + goto out; + } + + mutex_unlock(&indio_dev->mlock); + return ret; + +out: + palmas_gpadc_read_done(adc, adc_chan); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static const struct iio_info palmas_gpadc_iio_info = { + .read_raw = palmas_gpadc_read_raw, + .driver_module = THIS_MODULE, +}; + +#define PALMAS_ADC_CHAN_IIO(chan, _type, chan_info) \ +{ \ + .datasheet_name = PALMAS_DATASHEET_NAME(chan), \ + .type = _type, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(chan_info), \ + .indexed = 1, \ + .channel = PALMAS_ADC_CH_##chan, \ +} + +static const struct iio_chan_spec palmas_gpadc_iio_channel[] = { + PALMAS_ADC_CHAN_IIO(IN0, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED), + PALMAS_ADC_CHAN_IIO(IN1, IIO_TEMP, IIO_CHAN_INFO_RAW), + PALMAS_ADC_CHAN_IIO(IN2, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED), + PALMAS_ADC_CHAN_IIO(IN3, IIO_TEMP, IIO_CHAN_INFO_RAW), + PALMAS_ADC_CHAN_IIO(IN4, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED), + PALMAS_ADC_CHAN_IIO(IN5, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED), + PALMAS_ADC_CHAN_IIO(IN6, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED), + PALMAS_ADC_CHAN_IIO(IN7, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED), + PALMAS_ADC_CHAN_IIO(IN8, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED), + PALMAS_ADC_CHAN_IIO(IN9, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED), + PALMAS_ADC_CHAN_IIO(IN10, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED), + PALMAS_ADC_CHAN_IIO(IN11, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED), + PALMAS_ADC_CHAN_IIO(IN12, IIO_TEMP, IIO_CHAN_INFO_RAW), + PALMAS_ADC_CHAN_IIO(IN13, IIO_TEMP, IIO_CHAN_INFO_RAW), + PALMAS_ADC_CHAN_IIO(IN14, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED), + PALMAS_ADC_CHAN_IIO(IN15, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED), +}; + +static int palmas_gpadc_probe(struct platform_device *pdev) +{ + struct palmas_gpadc *adc; + struct palmas_platform_data *pdata; + struct palmas_gpadc_platform_data *gpadc_pdata = NULL; + struct iio_dev *indio_dev; + int ret, i; + + pdata = dev_get_platdata(pdev->dev.parent); + if (!pdata || !pdata->gpadc_pdata) { + dev_err(&pdev->dev, "No platform data\n"); + return -ENODEV; + } + + gpadc_pdata = pdata->gpadc_pdata; + + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc)); + if (!indio_dev) { + dev_err(&pdev->dev, "iio_device_alloc failed\n"); + return -ENOMEM; + } + + adc = iio_priv(indio_dev); + adc->dev = &pdev->dev; + adc->palmas = dev_get_drvdata(pdev->dev.parent); + adc->adc_info = palmas_gpadc_info; + init_completion(&adc->conv_completion); + dev_set_drvdata(&pdev->dev, indio_dev); + + adc->auto_conversion_period = gpadc_pdata->auto_conversion_period_ms; + adc->irq = palmas_irq_get_virq(adc->palmas, PALMAS_GPADC_EOC_SW_IRQ); + if (adc->irq < 0) { + dev_err(adc->dev, + "get virq failed: %d\n", adc->irq); + ret = adc->irq; + goto out; + } + ret = request_threaded_irq(adc->irq, NULL, + palmas_gpadc_irq, + IRQF_ONESHOT | IRQF_EARLY_RESUME, dev_name(adc->dev), + adc); + if (ret < 0) { + dev_err(adc->dev, + "request irq %d failed: %d\n", adc->irq, ret); + goto out; + } + + if (gpadc_pdata->adc_wakeup1_data) { + memcpy(&adc->wakeup1_data, gpadc_pdata->adc_wakeup1_data, + sizeof(adc->wakeup1_data)); + adc->wakeup1_enable = true; + adc->irq_auto_0 = platform_get_irq(pdev, 1); + ret = request_threaded_irq(adc->irq_auto_0, NULL, + palmas_gpadc_irq_auto, + IRQF_ONESHOT | IRQF_EARLY_RESUME, + "palmas-adc-auto-0", adc); + if (ret < 0) { + dev_err(adc->dev, "request auto0 irq %d failed: %d\n", + adc->irq_auto_0, ret); + goto out_irq_free; + } + } + + if (gpadc_pdata->adc_wakeup2_data) { + memcpy(&adc->wakeup2_data, gpadc_pdata->adc_wakeup2_data, + sizeof(adc->wakeup2_data)); + adc->wakeup2_enable = true; + adc->irq_auto_1 = platform_get_irq(pdev, 2); + ret = request_threaded_irq(adc->irq_auto_1, NULL, + palmas_gpadc_irq_auto, + IRQF_ONESHOT | IRQF_EARLY_RESUME, + "palmas-adc-auto-1", adc); + if (ret < 0) { + dev_err(adc->dev, "request auto1 irq %d failed: %d\n", + adc->irq_auto_1, ret); + goto out_irq_auto0_free; + } + } + + /* set the current source 0 (value 0/5/15/20 uA => 0..3) */ + if (gpadc_pdata->ch0_current <= 1) + adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_0; + else if (gpadc_pdata->ch0_current <= 5) + adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_5; + else if (gpadc_pdata->ch0_current <= 15) + adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_15; + else + adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_20; + + /* set the current source 3 (value 0/10/400/800 uA => 0..3) */ + if (gpadc_pdata->ch3_current <= 1) + adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_0; + else if (gpadc_pdata->ch3_current <= 10) + adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_10; + else if (gpadc_pdata->ch3_current <= 400) + adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_400; + else + adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_800; + + adc->extended_delay = gpadc_pdata->extended_delay; + + indio_dev->name = MOD_NAME; + indio_dev->dev.parent = &pdev->dev; + indio_dev->info = &palmas_gpadc_iio_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = palmas_gpadc_iio_channel; + indio_dev->num_channels = ARRAY_SIZE(palmas_gpadc_iio_channel); + + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(adc->dev, "iio_device_register() failed: %d\n", ret); + goto out_irq_auto1_free; + } + + device_set_wakeup_capable(&pdev->dev, 1); + for (i = 0; i < PALMAS_ADC_CH_MAX; i++) { + if (!(adc->adc_info[i].is_uncalibrated)) + palmas_gpadc_calibrate(adc, i); + } + + if (adc->wakeup1_enable || adc->wakeup2_enable) + device_wakeup_enable(&pdev->dev); + + return 0; + +out_irq_auto1_free: + if (gpadc_pdata->adc_wakeup2_data) + free_irq(adc->irq_auto_1, adc); +out_irq_auto0_free: + if (gpadc_pdata->adc_wakeup1_data) + free_irq(adc->irq_auto_0, adc); +out_irq_free: + free_irq(adc->irq, adc); +out: + return ret; +} + +static int palmas_gpadc_remove(struct platform_device *pdev) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(&pdev->dev); + struct palmas_gpadc *adc = iio_priv(indio_dev); + + if (adc->wakeup1_enable || adc->wakeup2_enable) + device_wakeup_disable(&pdev->dev); + iio_device_unregister(indio_dev); + free_irq(adc->irq, adc); + if (adc->wakeup1_enable) + free_irq(adc->irq_auto_0, adc); + if (adc->wakeup2_enable) + free_irq(adc->irq_auto_1, adc); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int palmas_adc_wakeup_configure(struct palmas_gpadc *adc) +{ + int adc_period, conv; + int i; + int ch0 = 0, ch1 = 0; + int thres; + int ret; + + adc_period = adc->auto_conversion_period; + for (i = 0; i < 16; ++i) { + if (((1000 * (1 << i)) / 32) < adc_period) + continue; + } + if (i > 0) + i--; + adc_period = i; + ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_AUTO_CTRL, + PALMAS_GPADC_AUTO_CTRL_COUNTER_CONV_MASK, + adc_period); + if (ret < 0) { + dev_err(adc->dev, "AUTO_CTRL write failed: %d\n", ret); + return ret; + } + + conv = 0; + if (adc->wakeup1_enable) { + int polarity; + + ch0 = adc->wakeup1_data.adc_channel_number; + conv |= PALMAS_GPADC_AUTO_CTRL_AUTO_CONV0_EN; + if (adc->wakeup1_data.adc_high_threshold > 0) { + thres = adc->wakeup1_data.adc_high_threshold; + polarity = 0; + } else { + thres = adc->wakeup1_data.adc_low_threshold; + polarity = PALMAS_GPADC_THRES_CONV0_MSB_THRES_CONV0_POL; + } + + ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_THRES_CONV0_LSB, thres & 0xFF); + if (ret < 0) { + dev_err(adc->dev, + "THRES_CONV0_LSB write failed: %d\n", ret); + return ret; + } + + ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_THRES_CONV0_MSB, + ((thres >> 8) & 0xF) | polarity); + if (ret < 0) { + dev_err(adc->dev, + "THRES_CONV0_MSB write failed: %d\n", ret); + return ret; + } + } + + if (adc->wakeup2_enable) { + int polarity; + + ch1 = adc->wakeup2_data.adc_channel_number; + conv |= PALMAS_GPADC_AUTO_CTRL_AUTO_CONV1_EN; + if (adc->wakeup2_data.adc_high_threshold > 0) { + thres = adc->wakeup2_data.adc_high_threshold; + polarity = 0; + } else { + thres = adc->wakeup2_data.adc_low_threshold; + polarity = PALMAS_GPADC_THRES_CONV1_MSB_THRES_CONV1_POL; + } + + ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_THRES_CONV1_LSB, thres & 0xFF); + if (ret < 0) { + dev_err(adc->dev, + "THRES_CONV1_LSB write failed: %d\n", ret); + return ret; + } + + ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_THRES_CONV1_MSB, + ((thres >> 8) & 0xF) | polarity); + if (ret < 0) { + dev_err(adc->dev, + "THRES_CONV1_MSB write failed: %d\n", ret); + return ret; + } + } + + ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_AUTO_SELECT, (ch1 << 4) | ch0); + if (ret < 0) { + dev_err(adc->dev, "AUTO_SELECT write failed: %d\n", ret); + return ret; + } + + ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_AUTO_CTRL, + PALMAS_GPADC_AUTO_CTRL_AUTO_CONV1_EN | + PALMAS_GPADC_AUTO_CTRL_AUTO_CONV0_EN, conv); + if (ret < 0) + dev_err(adc->dev, "AUTO_CTRL write failed: %d\n", ret); + + return ret; +} + +static int palmas_adc_wakeup_reset(struct palmas_gpadc *adc) +{ + int ret; + + ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE, + PALMAS_GPADC_AUTO_SELECT, 0); + if (ret < 0) { + dev_err(adc->dev, "AUTO_SELECT write failed: %d\n", ret); + return ret; + } + + ret = palmas_disable_auto_conversion(adc); + if (ret < 0) + dev_err(adc->dev, "Disable auto conversion failed: %d\n", ret); + + return ret; +} + +static int palmas_gpadc_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct palmas_gpadc *adc = iio_priv(indio_dev); + int wakeup = adc->wakeup1_enable || adc->wakeup2_enable; + int ret; + + if (!device_may_wakeup(dev) || !wakeup) + return 0; + + ret = palmas_adc_wakeup_configure(adc); + if (ret < 0) + return ret; + + if (adc->wakeup1_enable) + enable_irq_wake(adc->irq_auto_0); + + if (adc->wakeup2_enable) + enable_irq_wake(adc->irq_auto_1); + + return 0; +} + +static int palmas_gpadc_resume(struct device *dev) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct palmas_gpadc *adc = iio_priv(indio_dev); + int wakeup = adc->wakeup1_enable || adc->wakeup2_enable; + int ret; + + if (!device_may_wakeup(dev) || !wakeup) + return 0; + + ret = palmas_adc_wakeup_reset(adc); + if (ret < 0) + return ret; + + if (adc->wakeup1_enable) + disable_irq_wake(adc->irq_auto_0); + + if (adc->wakeup2_enable) + disable_irq_wake(adc->irq_auto_1); + + return 0; +}; +#endif + +static const struct dev_pm_ops palmas_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(palmas_gpadc_suspend, + palmas_gpadc_resume) +}; + +static struct platform_driver palmas_gpadc_driver = { + .probe = palmas_gpadc_probe, + .remove = palmas_gpadc_remove, + .driver = { + .name = MOD_NAME, + .pm = &palmas_pm_ops, + }, +}; + +static int __init palmas_gpadc_init(void) +{ + return platform_driver_register(&palmas_gpadc_driver); +} +module_init(palmas_gpadc_init); + +static void __exit palmas_gpadc_exit(void) +{ + platform_driver_unregister(&palmas_gpadc_driver); +} +module_exit(palmas_gpadc_exit); + +MODULE_DESCRIPTION("palmas GPADC driver"); +MODULE_AUTHOR("Pradeep Goudagunta"); +MODULE_ALIAS("platform:palmas-gpadc"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h index 13e1d96935ed7..c800dbc420795 100644 --- a/include/linux/mfd/palmas.h +++ b/include/linux/mfd/palmas.h @@ -134,21 +134,32 @@ struct palmas_pmic_driver_data { struct regulator_config config); }; +struct palmas_adc_wakeup_property { + int adc_channel_number; + int adc_high_threshold; + int adc_low_threshold; +}; + struct palmas_gpadc_platform_data { /* Channel 3 current source is only enabled during conversion */ - int ch3_current; + int ch3_current; /* 0: off; 1: 10uA; 2: 400uA; 3: 800 uA */ /* Channel 0 current source can be used for battery detection. * If used for battery detection this will cause a permanent current * consumption depending on current level set here. */ - int ch0_current; + int ch0_current; /* 0: off; 1: 5uA; 2: 15uA; 3: 20 uA */ + bool extended_delay; /* use extended delay for conversion */ /* default BAT_REMOVAL_DAT setting on device probe */ int bat_removal; /* Sets the START_POLARITY bit in the RT_CTRL register */ int start_polarity; + + int auto_conversion_period_ms; + struct palmas_adc_wakeup_property *adc_wakeup1_data; + struct palmas_adc_wakeup_property *adc_wakeup2_data; }; struct palmas_reg_init { @@ -405,28 +416,7 @@ struct palmas_gpadc_calibration { s32 offset_error; }; -struct palmas_gpadc { - struct device *dev; - struct palmas *palmas; - - int ch3_current; - int ch0_current; - - int gpadc_force; - - int bat_removal; - - struct mutex reading_lock; - struct completion irq_complete; - - int eoc_sw_irq; - - struct palmas_gpadc_calibration *palmas_cal_tbl; - - int conv0_channel; - int conv1_channel; - int rt_channel; -}; +#define PALMAS_DATASHEET_NAME(_name) "palmas-gpadc-chan-"#_name struct palmas_gpadc_result { s32 raw_code; @@ -520,6 +510,43 @@ enum palmas_irqs { PALMAS_NUM_IRQ, }; +/* Palmas GPADC Channels */ +enum { + PALMAS_ADC_CH_IN0, + PALMAS_ADC_CH_IN1, + PALMAS_ADC_CH_IN2, + PALMAS_ADC_CH_IN3, + PALMAS_ADC_CH_IN4, + PALMAS_ADC_CH_IN5, + PALMAS_ADC_CH_IN6, + PALMAS_ADC_CH_IN7, + PALMAS_ADC_CH_IN8, + PALMAS_ADC_CH_IN9, + PALMAS_ADC_CH_IN10, + PALMAS_ADC_CH_IN11, + PALMAS_ADC_CH_IN12, + PALMAS_ADC_CH_IN13, + PALMAS_ADC_CH_IN14, + PALMAS_ADC_CH_IN15, + PALMAS_ADC_CH_MAX, +}; + +/* Palmas GPADC Channel0 Current Source */ +enum { + PALMAS_ADC_CH0_CURRENT_SRC_0, + PALMAS_ADC_CH0_CURRENT_SRC_5, + PALMAS_ADC_CH0_CURRENT_SRC_15, + PALMAS_ADC_CH0_CURRENT_SRC_20, +}; + +/* Palmas GPADC Channel3 Current Source */ +enum { + PALMAS_ADC_CH3_CURRENT_SRC_0, + PALMAS_ADC_CH3_CURRENT_SRC_10, + PALMAS_ADC_CH3_CURRENT_SRC_400, + PALMAS_ADC_CH3_CURRENT_SRC_800, +}; + struct palmas_pmic { struct palmas *palmas; struct device *dev; -- GitLab From f0b1643581b376ebd97a0068cbc3d146d6abdff1 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Fri, 16 Oct 2015 14:53:39 +0200 Subject: [PATCH 0004/2855] iio:adc:palmas: add DT support Code was found at: https://android.googlesource.com/kernel/tegra/+/a90856a6626d502d42c6e7abccbdf9d730b36270%5E%21/#F1 Signed-off-by: Laxman Dewangan Signed-off-by: Marek Belisko [Fixed minor typos + add channels list to documentation] Signed-off-by: Jonathan Cameron --- .../bindings/iio/adc/palmas-gpadc.txt | 48 +++++++++++++++++ drivers/iio/adc/palmas_gpadc.c | 52 +++++++++++++++++-- 2 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 Documentation/devicetree/bindings/iio/adc/palmas-gpadc.txt diff --git a/Documentation/devicetree/bindings/iio/adc/palmas-gpadc.txt b/Documentation/devicetree/bindings/iio/adc/palmas-gpadc.txt new file mode 100644 index 0000000000000..4bb9a86065d13 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/palmas-gpadc.txt @@ -0,0 +1,48 @@ +* Palmas general purpose ADC IP block devicetree bindings + +Channels list: + 0 battery type + 1 battery temp NTC (optional current source) + 2 GP + 3 temp (with ext. diode, optional current source) + 4 GP + 5 GP + 6 VBAT_SENSE + 7 VCC_SENSE + 8 Backup Battery voltage + 9 external charger (VCHG) + 10 VBUS + 11 DC-DC current probe (how does this work?) + 12 internal die temp + 13 internal die temp + 14 USB ID pin voltage + 15 test network + +Required properties: +- compatible : Must be "ti,palmas-gpadc". +- #io-channel-cells: Should be set to <1>. + +Optional sub-nodes: +ti,channel0-current-microamp: Channel 0 current in uA. + Values are rounded to derive 0uA, 5uA, 15uA, 20uA. +ti,channel3-current-microamp: Channel 3 current in uA. + Values are rounded to derive 0uA, 10uA, 400uA, 800uA. +ti,enable-extended-delay: Enable extended delay. + +Example: + +pmic { + compatible = "ti,twl6035-pmic", "ti,palmas-pmic"; + ... + gpadc { + compatible = "ti,palmas-gpadc"; + interrupts = <18 0 + 16 0 + 17 0>; + #io-channel-cells = <1>; + ti,channel0-current-microamp = <5>; + ti,channel3-current-microamp = <10>; + }; + }; + ... +}; diff --git a/drivers/iio/adc/palmas_gpadc.c b/drivers/iio/adc/palmas_gpadc.c index 71763c5da2ab1..f42eb8a7d21f0 100644 --- a/drivers/iio/adc/palmas_gpadc.c +++ b/drivers/iio/adc/palmas_gpadc.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include #include @@ -460,6 +462,34 @@ static const struct iio_chan_spec palmas_gpadc_iio_channel[] = { PALMAS_ADC_CHAN_IIO(IN15, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED), }; +static int palmas_gpadc_get_adc_dt_data(struct platform_device *pdev, + struct palmas_gpadc_platform_data **gpadc_pdata) +{ + struct device_node *np = pdev->dev.of_node; + struct palmas_gpadc_platform_data *gp_data; + int ret; + u32 pval; + + gp_data = devm_kzalloc(&pdev->dev, sizeof(*gp_data), GFP_KERNEL); + if (!gp_data) + return -ENOMEM; + + ret = of_property_read_u32(np, "ti,channel0-current-microamp", &pval); + if (!ret) + gp_data->ch0_current = pval; + + ret = of_property_read_u32(np, "ti,channel3-current-microamp", &pval); + if (!ret) + gp_data->ch3_current = pval; + + gp_data->extended_delay = of_property_read_bool(np, + "ti,enable-extended-delay"); + + *gpadc_pdata = gp_data; + + return 0; +} + static int palmas_gpadc_probe(struct platform_device *pdev) { struct palmas_gpadc *adc; @@ -469,12 +499,17 @@ static int palmas_gpadc_probe(struct platform_device *pdev) int ret, i; pdata = dev_get_platdata(pdev->dev.parent); - if (!pdata || !pdata->gpadc_pdata) { - dev_err(&pdev->dev, "No platform data\n"); - return -ENODEV; - } - gpadc_pdata = pdata->gpadc_pdata; + if (pdata && pdata->gpadc_pdata) + gpadc_pdata = pdata->gpadc_pdata; + + if (!gpadc_pdata && pdev->dev.of_node) { + ret = palmas_gpadc_get_adc_dt_data(pdev, &gpadc_pdata); + if (ret < 0) + return ret; + } + if (!gpadc_pdata) + return -EINVAL; indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc)); if (!indio_dev) { @@ -790,12 +825,19 @@ static const struct dev_pm_ops palmas_pm_ops = { palmas_gpadc_resume) }; +static const struct of_device_id of_palmas_gpadc_match_tbl[] = { + { .compatible = "ti,palmas-gpadc", }, + { /* end */ } +}; +MODULE_DEVICE_TABLE(of, of_palmas_gpadc_match_tbl); + static struct platform_driver palmas_gpadc_driver = { .probe = palmas_gpadc_probe, .remove = palmas_gpadc_remove, .driver = { .name = MOD_NAME, .pm = &palmas_pm_ops, + .of_match_table = of_palmas_gpadc_match_tbl, }, }; -- GitLab From 415f792447572ef1949a3cef5119bbce8cc66373 Mon Sep 17 00:00:00 2001 From: Cristina Opriceana Date: Fri, 9 Oct 2015 16:31:28 +0300 Subject: [PATCH 0005/2855] iio: Move IIO Dummy Driver out of staging This patch moves the reference IIO dummy driver from drivers/staging/iio into a separate folder, drivers/iio/dummy and adds the proper Kconfig and Makefile for it. A new config menu entry called IIO dummy driver has also been added in the Industrial I/O support menu, corresponding to this driver. Signed-off-by: Cristina Opriceana Signed-off-by: Jonathan Cameron --- drivers/iio/Kconfig | 1 + drivers/iio/Makefile | 1 + drivers/iio/dummy/Kconfig | 35 ++++++++++++ drivers/iio/dummy/Makefile | 10 ++++ .../iio => iio/dummy}/iio_dummy_evgen.c | 0 .../iio => iio/dummy}/iio_dummy_evgen.h | 0 .../iio => iio/dummy}/iio_simple_dummy.c | 0 .../iio => iio/dummy}/iio_simple_dummy.h | 0 .../dummy}/iio_simple_dummy_buffer.c | 0 .../dummy}/iio_simple_dummy_events.c | 0 drivers/staging/iio/Kconfig | 54 +++++++++---------- drivers/staging/iio/Makefile | 10 ++-- 12 files changed, 79 insertions(+), 32 deletions(-) create mode 100644 drivers/iio/dummy/Kconfig create mode 100644 drivers/iio/dummy/Makefile rename drivers/{staging/iio => iio/dummy}/iio_dummy_evgen.c (100%) rename drivers/{staging/iio => iio/dummy}/iio_dummy_evgen.h (100%) rename drivers/{staging/iio => iio/dummy}/iio_simple_dummy.c (100%) rename drivers/{staging/iio => iio/dummy}/iio_simple_dummy.h (100%) rename drivers/{staging/iio => iio/dummy}/iio_simple_dummy_buffer.c (100%) rename drivers/{staging/iio => iio/dummy}/iio_simple_dummy_events.c (100%) diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 66792e707d74e..6b8c77c97d40d 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -50,6 +50,7 @@ source "drivers/iio/amplifiers/Kconfig" source "drivers/iio/chemical/Kconfig" source "drivers/iio/common/Kconfig" source "drivers/iio/dac/Kconfig" +source "drivers/iio/dummy/Kconfig" source "drivers/iio/frequency/Kconfig" source "drivers/iio/gyro/Kconfig" source "drivers/iio/humidity/Kconfig" diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index aeca7269fe442..6769f2f43e868 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -16,6 +16,7 @@ obj-y += buffer/ obj-y += chemical/ obj-y += common/ obj-y += dac/ +obj-y += dummy/ obj-y += gyro/ obj-y += frequency/ obj-y += humidity/ diff --git a/drivers/iio/dummy/Kconfig b/drivers/iio/dummy/Kconfig new file mode 100644 index 0000000000000..e8676aa97d62f --- /dev/null +++ b/drivers/iio/dummy/Kconfig @@ -0,0 +1,35 @@ +# +# Industrial I/O subsystem Dummy Driver configuration +# +menu "IIO dummy driver" + depends on IIO + +config IIO_DUMMY_EVGEN + tristate + +config IIO_SIMPLE_DUMMY + tristate "An example driver with no hardware requirements" + help + Driver intended mainly as documentation for how to write + a driver. May also be useful for testing userspace code + without hardware. + +if IIO_SIMPLE_DUMMY + +config IIO_SIMPLE_DUMMY_EVENTS + bool "Event generation support" + select IIO_DUMMY_EVGEN + help + Add some dummy events to the simple dummy driver. + +config IIO_SIMPLE_DUMMY_BUFFER + bool "Buffered capture support" + select IIO_BUFFER + select IIO_TRIGGER + select IIO_KFIFO_BUF + help + Add buffered data capture to the simple dummy driver. + +endif # IIO_SIMPLE_DUMMY + +endmenu diff --git a/drivers/iio/dummy/Makefile b/drivers/iio/dummy/Makefile new file mode 100644 index 0000000000000..0765e93d78040 --- /dev/null +++ b/drivers/iio/dummy/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the IIO Dummy Driver +# + +obj-$(CONFIG_IIO_SIMPLE_DUMMY) += iio_dummy.o +iio_dummy-y := iio_simple_dummy.o +iio_dummy-$(CONFIG_IIO_SIMPLE_DUMMY_EVENTS) += iio_simple_dummy_events.o +iio_dummy-$(CONFIG_IIO_SIMPLE_DUMMY_BUFFER) += iio_simple_dummy_buffer.o + +obj-$(CONFIG_IIO_DUMMY_EVGEN) += iio_dummy_evgen.o diff --git a/drivers/staging/iio/iio_dummy_evgen.c b/drivers/iio/dummy/iio_dummy_evgen.c similarity index 100% rename from drivers/staging/iio/iio_dummy_evgen.c rename to drivers/iio/dummy/iio_dummy_evgen.c diff --git a/drivers/staging/iio/iio_dummy_evgen.h b/drivers/iio/dummy/iio_dummy_evgen.h similarity index 100% rename from drivers/staging/iio/iio_dummy_evgen.h rename to drivers/iio/dummy/iio_dummy_evgen.h diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/iio/dummy/iio_simple_dummy.c similarity index 100% rename from drivers/staging/iio/iio_simple_dummy.c rename to drivers/iio/dummy/iio_simple_dummy.c diff --git a/drivers/staging/iio/iio_simple_dummy.h b/drivers/iio/dummy/iio_simple_dummy.h similarity index 100% rename from drivers/staging/iio/iio_simple_dummy.h rename to drivers/iio/dummy/iio_simple_dummy.h diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/iio/dummy/iio_simple_dummy_buffer.c similarity index 100% rename from drivers/staging/iio/iio_simple_dummy_buffer.c rename to drivers/iio/dummy/iio_simple_dummy_buffer.c diff --git a/drivers/staging/iio/iio_simple_dummy_events.c b/drivers/iio/dummy/iio_simple_dummy_events.c similarity index 100% rename from drivers/staging/iio/iio_simple_dummy_events.c rename to drivers/iio/dummy/iio_simple_dummy_events.c diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index 6d5b38d695785..85de1985df8e1 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -17,32 +17,32 @@ source "drivers/staging/iio/meter/Kconfig" source "drivers/staging/iio/resolver/Kconfig" source "drivers/staging/iio/trigger/Kconfig" -config IIO_DUMMY_EVGEN - tristate - -config IIO_SIMPLE_DUMMY - tristate "An example driver with no hardware requirements" - help - Driver intended mainly as documentation for how to write - a driver. May also be useful for testing userspace code - without hardware. - -if IIO_SIMPLE_DUMMY - -config IIO_SIMPLE_DUMMY_EVENTS - bool "Event generation support" - select IIO_DUMMY_EVGEN - help - Add some dummy events to the simple dummy driver. - -config IIO_SIMPLE_DUMMY_BUFFER - bool "Buffered capture support" - select IIO_BUFFER - select IIO_TRIGGER - select IIO_KFIFO_BUF - help - Add buffered data capture to the simple dummy driver. - -endif # IIO_SIMPLE_DUMMY +#config IIO_DUMMY_EVGEN +# tristate +# +#config IIO_SIMPLE_DUMMY +# tristate "An example driver with no hardware requirements" +# help +# Driver intended mainly as documentation for how to write +# a driver. May also be useful for testing userspace code +# without hardware. + +#if IIO_SIMPLE_DUMMY + +#config IIO_SIMPLE_DUMMY_EVENTS +# bool "Event generation support" +# select IIO_DUMMY_EVGEN +# help +# Add some dummy events to the simple dummy driver. + +#config IIO_SIMPLE_DUMMY_BUFFER +# bool "Buffered capture support" +# select IIO_BUFFER +# select IIO_TRIGGER +# select IIO_KFIFO_BUF +# help +# Add buffered data capture to the simple dummy driver. + +#endif # IIO_SIMPLE_DUMMY endmenu diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index d87106135b270..355824ab733be 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -2,12 +2,12 @@ # Makefile for the industrial I/O core. # -obj-$(CONFIG_IIO_SIMPLE_DUMMY) += iio_dummy.o -iio_dummy-y := iio_simple_dummy.o -iio_dummy-$(CONFIG_IIO_SIMPLE_DUMMY_EVENTS) += iio_simple_dummy_events.o -iio_dummy-$(CONFIG_IIO_SIMPLE_DUMMY_BUFFER) += iio_simple_dummy_buffer.o +#obj-$(CONFIG_IIO_SIMPLE_DUMMY) += iio_dummy.o +#iio_dummy-y := iio_simple_dummy.o +#iio_dummy-$(CONFIG_IIO_SIMPLE_DUMMY_EVENTS) += iio_simple_dummy_events.o +#iio_dummy-$(CONFIG_IIO_SIMPLE_DUMMY_BUFFER) += iio_simple_dummy_buffer.o -obj-$(CONFIG_IIO_DUMMY_EVGEN) += iio_dummy_evgen.o +#obj-$(CONFIG_IIO_DUMMY_EVGEN) += iio_dummy_evgen.o obj-y += accel/ obj-y += adc/ -- GitLab From 3a872138e4b78e7f8bfce63f0da788c0cfd80e53 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Wed, 14 Oct 2015 14:54:38 +0200 Subject: [PATCH 0006/2855] iio: adc: mcp320x: Deprecated compatible strings with no vendor prefix The Microchip Analog to Digital Converter (ADC) Device Tree binding documents compatible strings with no vendor prefix. Since it should compatible strings with also a vendor, add these to the binding doc and mark the old ones as deprecated. The driver says that the device is from Microchip Technology which is listed in Documentation/devicetree/bindings/vendor-prefixes.txt so use the documented prefix. Signed-off-by: Javier Martinez Canillas Acked-by: Michael Welling Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/adc/mcp320x.txt | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/adc/mcp320x.txt b/Documentation/devicetree/bindings/iio/adc/mcp320x.txt index 2a1f3af30155d..bcd3ac8e6e0c5 100644 --- a/Documentation/devicetree/bindings/iio/adc/mcp320x.txt +++ b/Documentation/devicetree/bindings/iio/adc/mcp320x.txt @@ -10,16 +10,28 @@ must be specified. Required properties: - compatible: Must be one of the following, depending on the model: - "mcp3001" - "mcp3002" - "mcp3004" - "mcp3008" - "mcp3201" - "mcp3202" - "mcp3204" - "mcp3208" - "mcp3301" + "mcp3001" (DEPRECATED) + "mcp3002" (DEPRECATED) + "mcp3004" (DEPRECATED) + "mcp3008" (DEPRECATED) + "mcp3201" (DEPRECATED) + "mcp3202" (DEPRECATED) + "mcp3204" (DEPRECATED) + "mcp3208" (DEPRECATED) + "mcp3301" (DEPRECATED) + "microchip,mcp3001" + "microchip,mcp3002" + "microchip,mcp3004" + "microchip,mcp3008" + "microchip,mcp3201" + "microchip,mcp3202" + "microchip,mcp3204" + "microchip,mcp3208" + "microchip,mcp3301" + + NOTE: The use of the compatibles with no vendor prefix + is deprecated and only listed because old DT use them. Examples: spi_controller { -- GitLab From 0d0e53844797200aa026dfbdfe62f90ccff88300 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Wed, 14 Oct 2015 14:54:39 +0200 Subject: [PATCH 0007/2855] iio: adc: mcp320x: Add compatible with vendor prefix to OF table The driver Device Tree binding now documents compatible strings that have a vendor prefix, so add these to the OF device ID table to match and mark the old ones as deprecated explaining that should not be used anymore. Signed-off-by: Javier Martinez Canillas Acked-by: Michael Welling Signed-off-by: Jonathan Cameron --- drivers/iio/adc/mcp320x.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c index 41a21e986c1a3..9fcb8b61e3007 100644 --- a/drivers/iio/adc/mcp320x.c +++ b/drivers/iio/adc/mcp320x.c @@ -354,6 +354,7 @@ static int mcp320x_remove(struct spi_device *spi) #if defined(CONFIG_OF) static const struct of_device_id mcp320x_dt_ids[] = { + /* NOTE: The use of compatibles with no vendor prefix is deprecated. */ { .compatible = "mcp3001", .data = &mcp320x_chip_infos[mcp3001], @@ -381,6 +382,33 @@ static const struct of_device_id mcp320x_dt_ids[] = { }, { .compatible = "mcp3301", .data = &mcp320x_chip_infos[mcp3301], + }, { + .compatible = "microchip,mcp3001", + .data = &mcp320x_chip_infos[mcp3001], + }, { + .compatible = "microchip,mcp3002", + .data = &mcp320x_chip_infos[mcp3002], + }, { + .compatible = "microchip,mcp3004", + .data = &mcp320x_chip_infos[mcp3004], + }, { + .compatible = "microchip,mcp3008", + .data = &mcp320x_chip_infos[mcp3008], + }, { + .compatible = "microchip,mcp3201", + .data = &mcp320x_chip_infos[mcp3201], + }, { + .compatible = "microchip,mcp3202", + .data = &mcp320x_chip_infos[mcp3202], + }, { + .compatible = "microchip,mcp3204", + .data = &mcp320x_chip_infos[mcp3204], + }, { + .compatible = "microchip,mcp3208", + .data = &mcp320x_chip_infos[mcp3208], + }, { + .compatible = "microchip,mcp3301", + .data = &mcp320x_chip_infos[mcp3301], }, { } }; -- GitLab From f0566c0c405de543efb6fb8b8988cc7743d85ea6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Oct 2015 18:10:24 +0200 Subject: [PATCH 0008/2855] iio: Set device watermark based on watermark of all attached buffers Currently the watermark of the device is only set based on the watermark that is set for the user space buffer. This doesn't consider the watermarks set on any attached in-kernel buffers. Change this so that the watermark of the device should be the minimum of the watermarks over all attached buffers. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-buffer.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index d7e908acb4802..7340922d367fe 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -610,6 +610,7 @@ static void iio_free_scan_mask(struct iio_dev *indio_dev, struct iio_device_config { unsigned int mode; + unsigned int watermark; const unsigned long *scan_mask; unsigned int scan_bytes; bool scan_timestamp; @@ -642,10 +643,14 @@ static int iio_verify_update(struct iio_dev *indio_dev, 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) { @@ -743,6 +748,10 @@ static int iio_enable_buffers(struct iio_dev *indio_dev, } } + if (indio_dev->info->hwfifo_set_watermark) + indio_dev->info->hwfifo_set_watermark(indio_dev, + config->watermark); + indio_dev->currentmode = config->mode; if (indio_dev->setup_ops->postenable) { @@ -974,9 +983,6 @@ static ssize_t iio_buffer_store_watermark(struct device *dev, } 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); -- GitLab From 4a60535726d90bfad16b5c52dcffaeede9fb84a9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Oct 2015 18:10:25 +0200 Subject: [PATCH 0009/2855] iio:iio_buffer_init(): Only set watermark if not already set Only initialize the watermark field if it is still 0. This allows drivers to provide a custom default watermark value. E.g. some driver might have a fixed watermark or can only support watermarks within a certain range and the initial value for the watermark should be within this range. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-buffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 7340922d367fe..5f2c8c8c436e5 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -193,7 +193,8 @@ void iio_buffer_init(struct iio_buffer *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); -- GitLab From b440655b896b2d5a2fb5f918801fb0e281a537cd Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Oct 2015 18:10:26 +0200 Subject: [PATCH 0010/2855] iio: Add support for indicating fixed watermarks For buffers which have a fixed wake-up watermark the watermark attribute should be read-only. Add a new FIXED_WATERMARK flag to the struct iio_buffer_access_funcs, which can be set by a buffer implementation. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-buffer.c | 5 +++++ include/linux/iio/buffer.h | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 5f2c8c8c436e5..98a6447a61d30 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -998,6 +998,8 @@ static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, 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, @@ -1040,6 +1042,9 @@ int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) 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); diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index 1600c55828e0f..4d99a53d1fe7e 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -17,6 +17,12 @@ struct iio_buffer; +/** + * INDIO_BUFFER_FLAG_FIXED_WATERMARK - Watermark level of the buffer can not be + * configured. It has a fixed value which will be buffer specific. + */ +#define INDIO_BUFFER_FLAG_FIXED_WATERMARK BIT(0) + /** * struct iio_buffer_access_funcs - access functions for buffers. * @store_to: actually store stuff to the buffer @@ -30,6 +36,7 @@ struct iio_buffer; * @release: called when the last reference to the buffer is dropped, * should free all resources allocated by the buffer. * @modes: Supported operating modes by this buffer type + * @flags: A bitmask combination of INDIO_BUFFER_FLAG_* * * The purpose of this structure is to make the buffer element * modular as event for a given driver, different usecases may require @@ -54,6 +61,7 @@ struct iio_buffer_access_funcs { void (*release)(struct iio_buffer *buffer); unsigned int modes; + unsigned int flags; }; /** -- GitLab From e18a2ad45caeb11226e49c25068d0f2efe2adf6c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Oct 2015 18:10:27 +0200 Subject: [PATCH 0011/2855] iio: Add buffer enable/disable callbacks This patch adds a enable and disable callback that is called when the buffer is enabled/disabled. This can be used by buffer implementations that need to do some setup or teardown work. E.g. a DMA based buffer can use this to start/stop the DMA transfer. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-buffer.c | 36 ++++++++++++++++++++++++++++++- include/linux/iio/buffer.h | 8 +++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 98a6447a61d30..a4b164a478c43 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -568,6 +568,22 @@ static void iio_buffer_deactivate_all(struct iio_dev *indio_dev) 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) { @@ -719,6 +735,7 @@ static int iio_verify_update(struct iio_dev *indio_dev, 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; @@ -753,6 +770,12 @@ static int iio_enable_buffers(struct iio_dev *indio_dev, 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) { @@ -760,12 +783,16 @@ static int iio_enable_buffers(struct iio_dev *indio_dev, 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) @@ -778,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; @@ -798,6 +826,12 @@ static int iio_disable_buffers(struct iio_dev *indio_dev) 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) { diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index 4d99a53d1fe7e..2ec3ad58e8a06 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -33,6 +33,11 @@ struct iio_buffer; * storage. * @set_bytes_per_datum:set number of bytes per datum * @set_length: set number of datums in buffer + * @enable: called if the buffer is attached to a device and the + * device starts sampling. Calls are balanced with + * @disable. + * @disable: called if the buffer is attached to a device and the + * device stops sampling. Calles are balanced with @enable. * @release: called when the last reference to the buffer is dropped, * should free all resources allocated by the buffer. * @modes: Supported operating modes by this buffer type @@ -58,6 +63,9 @@ struct iio_buffer_access_funcs { int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd); int (*set_length)(struct iio_buffer *buffer, int length); + int (*enable)(struct iio_buffer *buffer, struct iio_dev *indio_dev); + int (*disable)(struct iio_buffer *buffer, struct iio_dev *indio_dev); + void (*release)(struct iio_buffer *buffer); unsigned int modes; -- GitLab From 670b19ae9bfdbcb4ce2c2ffb2ec1659a7f4a2074 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Oct 2015 18:10:28 +0200 Subject: [PATCH 0012/2855] iio: Add generic DMA buffer infrastructure The traditional approach used in IIO to implement buffered capture requires the generation of at least one interrupt per sample. In the interrupt handler the driver reads the sample from the device and copies it to a software buffer. This approach has a rather large per sample overhead associated with it. And while it works fine for samplerates in the range of up to 1000 samples per second it starts to consume a rather large share of the available CPU processing time once we go beyond that, this is especially true on an embedded system with limited processing power. The regular interrupt also causes increased power consumption by not allowing the hardware into deeper sleep states, which is something that becomes more and more important on mobile battery powered devices. And while the recently added watermark support mitigates some of the issues by allowing the device to generate interrupts at a rate lower than the data output rate, this still requires a storage buffer inside the device and even if it exists it is only a few 100 samples deep at most. DMA support on the other hand allows to capture multiple millions or even more samples without any CPU interaction. This allows the CPU to either go to sleep for longer periods or focus on other tasks which increases overall system performance and power consumption. In addition to that some devices might not even offer a way to read the data other than using DMA, which makes DMA mandatory to use for them. The tasks involved in implementing a DMA buffer can be divided into two categories. The first category is memory buffer management (allocation, mapping, etc.) and hooking this up the IIO buffer callbacks like read(), enable(), disable(), etc. The second category of tasks is to setup the DMA hardware and manage the DMA transfers. Tasks from the first category will be very similar for all IIO drivers supporting DMA buffers, while the tasks from the second category will be hardware specific. This patch implements a generic infrastructure that take care of the former tasks. It provides a set of functions that implement the standard IIO buffer iio_buffer_access_funcs callbacks. These can either be used as is or be overloaded and augmented with driver specific code where necessary. For the DMA buffer support infrastructure that is introduced in this series sample data is grouped by so called blocks. A block is the basic unit at which data is exchanged between the application and the hardware. The application is responsible for allocating the memory associated with the block and then passes the block to the hardware. When the hardware has captured the amount of samples equal to size of a block it will notify the application, which can then read the data from the block and process it. The block size can freely chosen (within the constraints of the hardware). This allows to make a trade-off between latency and management overhead. The larger the block size the lower the per sample overhead but the latency between when the data was captured and when the application will be able to access it increases, in a similar way smaller block sizes have a larger per sample management overhead but a lower latency. The ideal block size thus depends on system and application requirements. For the time being the infrastructure only implements a simple double buffered scheme which allocates two blocks each with half the size of the configured buffer size. This provides basic support for capturing continuous uninterrupted data over the existing file-IO ABI. Future extensions to the DMA buffer infrastructure will give applications a more fine grained control over how many blocks are allocated and the size of each block. But this requires userspace ABI additions which are intentionally not part of this patch and will be added separately. Tasks of the second category need to be implemented by a device specific driver. They can be hooked up into the generic infrastructure using two simple callbacks, submit() and abort(). The submit() callback is used to schedule DMA transfers for blocks. Once a DMA transfer has been completed it is expected that the buffer driver calls iio_dma_buffer_block_done() to notify. The abort() callback is used for stopping all pending and active DMA transfers when the buffer is disabled. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/buffer/Kconfig | 9 + drivers/iio/buffer/Makefile | 1 + drivers/iio/buffer/industrialio-buffer-dma.c | 683 +++++++++++++++++++ include/linux/iio/buffer-dma.h | 152 +++++ 4 files changed, 845 insertions(+) create mode 100644 drivers/iio/buffer/industrialio-buffer-dma.c create mode 100644 include/linux/iio/buffer-dma.h diff --git a/drivers/iio/buffer/Kconfig b/drivers/iio/buffer/Kconfig index 0a7b2fd3699bf..b2fda1afc03e7 100644 --- a/drivers/iio/buffer/Kconfig +++ b/drivers/iio/buffer/Kconfig @@ -9,6 +9,15 @@ config IIO_BUFFER_CB Should be selected by any drivers that do in-kernel push usage. That is, those where the data is pushed to the consumer. +config IIO_BUFFER_DMA + tristate + help + Provides the generic IIO DMA buffer infrastructure that can be used by + drivers for devices with DMA support to implement the IIO buffer. + + Should be selected by drivers that want to use the generic DMA buffer + infrastructure. + config IIO_KFIFO_BUF tristate "Industrial I/O buffering based on kfifo" help diff --git a/drivers/iio/buffer/Makefile b/drivers/iio/buffer/Makefile index 4d193b9a9123e..bda3f1143e727 100644 --- a/drivers/iio/buffer/Makefile +++ b/drivers/iio/buffer/Makefile @@ -4,5 +4,6 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_IIO_BUFFER_CB) += industrialio-buffer-cb.o +obj-$(CONFIG_IIO_BUFFER_DMA) += industrialio-buffer-dma.o obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o diff --git a/drivers/iio/buffer/industrialio-buffer-dma.c b/drivers/iio/buffer/industrialio-buffer-dma.c new file mode 100644 index 0000000000000..212cbedc7abb6 --- /dev/null +++ b/drivers/iio/buffer/industrialio-buffer-dma.c @@ -0,0 +1,683 @@ +/* + * Copyright 2013-2015 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * For DMA buffers the storage is sub-divided into so called blocks. Each block + * has its own memory buffer. The size of the block is the granularity at which + * memory is exchanged between the hardware and the application. Increasing the + * basic unit of data exchange from one sample to one block decreases the + * management overhead that is associated with each sample. E.g. if we say the + * management overhead for one exchange is x and the unit of exchange is one + * sample the overhead will be x for each sample. Whereas when using a block + * which contains n samples the overhead per sample is reduced to x/n. This + * allows to achieve much higher samplerates than what can be sustained with + * the one sample approach. + * + * Blocks are exchanged between the DMA controller and the application via the + * means of two queues. The incoming queue and the outgoing queue. Blocks on the + * incoming queue are waiting for the DMA controller to pick them up and fill + * them with data. Block on the outgoing queue have been filled with data and + * are waiting for the application to dequeue them and read the data. + * + * A block can be in one of the following states: + * * Owned by the application. In this state the application can read data from + * the block. + * * On the incoming list: Blocks on the incoming list are queued up to be + * processed by the DMA controller. + * * Owned by the DMA controller: The DMA controller is processing the block + * and filling it with data. + * * On the outgoing list: Blocks on the outgoing list have been successfully + * processed by the DMA controller and contain data. They can be dequeued by + * the application. + * * Dead: A block that is dead has been marked as to be freed. It might still + * be owned by either the application or the DMA controller at the moment. + * But once they are done processing it instead of going to either the + * incoming or outgoing queue the block will be freed. + * + * In addition to this blocks are reference counted and the memory associated + * with both the block structure as well as the storage memory for the block + * will be freed when the last reference to the block is dropped. This means a + * block must not be accessed without holding a reference. + * + * The iio_dma_buffer implementation provides a generic infrastructure for + * managing the blocks. + * + * A driver for a specific piece of hardware that has DMA capabilities need to + * implement the submit() callback from the iio_dma_buffer_ops structure. This + * callback is supposed to initiate the DMA transfer copying data from the + * converter to the memory region of the block. Once the DMA transfer has been + * completed the driver must call iio_dma_buffer_block_done() for the completed + * block. + * + * Prior to this it must set the bytes_used field of the block contains + * the actual number of bytes in the buffer. Typically this will be equal to the + * size of the block, but if the DMA hardware has certain alignment requirements + * for the transfer length it might choose to use less than the full size. In + * either case it is expected that bytes_used is a multiple of the bytes per + * datum, i.e. the block must not contain partial samples. + * + * The driver must call iio_dma_buffer_block_done() for each block it has + * received through its submit_block() callback, even if it does not actually + * perform a DMA transfer for the block, e.g. because the buffer was disabled + * before the block transfer was started. In this case it should set bytes_used + * to 0. + * + * In addition it is recommended that a driver implements the abort() callback. + * It will be called when the buffer is disabled and can be used to cancel + * pending and stop active transfers. + * + * The specific driver implementation should use the default callback + * implementations provided by this module for the iio_buffer_access_funcs + * struct. It may overload some callbacks with custom variants if the hardware + * has special requirements that are not handled by the generic functions. If a + * driver chooses to overload a callback it has to ensure that the generic + * callback is called from within the custom callback. + */ + +static void iio_buffer_block_release(struct kref *kref) +{ + struct iio_dma_buffer_block *block = container_of(kref, + struct iio_dma_buffer_block, kref); + + WARN_ON(block->state != IIO_BLOCK_STATE_DEAD); + + dma_free_coherent(block->queue->dev, PAGE_ALIGN(block->size), + block->vaddr, block->phys_addr); + + iio_buffer_put(&block->queue->buffer); + kfree(block); +} + +static void iio_buffer_block_get(struct iio_dma_buffer_block *block) +{ + kref_get(&block->kref); +} + +static void iio_buffer_block_put(struct iio_dma_buffer_block *block) +{ + kref_put(&block->kref, iio_buffer_block_release); +} + +/* + * dma_free_coherent can sleep, hence we need to take some special care to be + * able to drop a reference from an atomic context. + */ +static LIST_HEAD(iio_dma_buffer_dead_blocks); +static DEFINE_SPINLOCK(iio_dma_buffer_dead_blocks_lock); + +static void iio_dma_buffer_cleanup_worker(struct work_struct *work) +{ + struct iio_dma_buffer_block *block, *_block; + LIST_HEAD(block_list); + + spin_lock_irq(&iio_dma_buffer_dead_blocks_lock); + list_splice_tail_init(&iio_dma_buffer_dead_blocks, &block_list); + spin_unlock_irq(&iio_dma_buffer_dead_blocks_lock); + + list_for_each_entry_safe(block, _block, &block_list, head) + iio_buffer_block_release(&block->kref); +} +static DECLARE_WORK(iio_dma_buffer_cleanup_work, iio_dma_buffer_cleanup_worker); + +static void iio_buffer_block_release_atomic(struct kref *kref) +{ + struct iio_dma_buffer_block *block; + unsigned long flags; + + block = container_of(kref, struct iio_dma_buffer_block, kref); + + spin_lock_irqsave(&iio_dma_buffer_dead_blocks_lock, flags); + list_add_tail(&block->head, &iio_dma_buffer_dead_blocks); + spin_unlock_irqrestore(&iio_dma_buffer_dead_blocks_lock, flags); + + schedule_work(&iio_dma_buffer_cleanup_work); +} + +/* + * Version of iio_buffer_block_put() that can be called from atomic context + */ +static void iio_buffer_block_put_atomic(struct iio_dma_buffer_block *block) +{ + kref_put(&block->kref, iio_buffer_block_release_atomic); +} + +static struct iio_dma_buffer_queue *iio_buffer_to_queue(struct iio_buffer *buf) +{ + return container_of(buf, struct iio_dma_buffer_queue, buffer); +} + +static struct iio_dma_buffer_block *iio_dma_buffer_alloc_block( + struct iio_dma_buffer_queue *queue, size_t size) +{ + struct iio_dma_buffer_block *block; + + block = kzalloc(sizeof(*block), GFP_KERNEL); + if (!block) + return NULL; + + block->vaddr = dma_alloc_coherent(queue->dev, PAGE_ALIGN(size), + &block->phys_addr, GFP_KERNEL); + if (!block->vaddr) { + kfree(block); + return NULL; + } + + block->size = size; + block->state = IIO_BLOCK_STATE_DEQUEUED; + block->queue = queue; + INIT_LIST_HEAD(&block->head); + kref_init(&block->kref); + + iio_buffer_get(&queue->buffer); + + return block; +} + +static void _iio_dma_buffer_block_done(struct iio_dma_buffer_block *block) +{ + struct iio_dma_buffer_queue *queue = block->queue; + + /* + * The buffer has already been freed by the application, just drop the + * reference. + */ + if (block->state != IIO_BLOCK_STATE_DEAD) { + block->state = IIO_BLOCK_STATE_DONE; + list_add_tail(&block->head, &queue->outgoing); + } +} + +/** + * iio_dma_buffer_block_done() - Indicate that a block has been completed + * @block: The completed block + * + * Should be called when the DMA controller has finished handling the block to + * pass back ownership of the block to the queue. + */ +void iio_dma_buffer_block_done(struct iio_dma_buffer_block *block) +{ + struct iio_dma_buffer_queue *queue = block->queue; + unsigned long flags; + + spin_lock_irqsave(&queue->list_lock, flags); + _iio_dma_buffer_block_done(block); + spin_unlock_irqrestore(&queue->list_lock, flags); + + iio_buffer_block_put_atomic(block); + wake_up_interruptible_poll(&queue->buffer.pollq, POLLIN | POLLRDNORM); +} +EXPORT_SYMBOL_GPL(iio_dma_buffer_block_done); + +/** + * iio_dma_buffer_block_list_abort() - Indicate that a list block has been + * aborted + * @queue: Queue for which to complete blocks. + * @list: List of aborted blocks. All blocks in this list must be from @queue. + * + * Typically called from the abort() callback after the DMA controller has been + * stopped. This will set bytes_used to 0 for each block in the list and then + * hand the blocks back to the queue. + */ +void iio_dma_buffer_block_list_abort(struct iio_dma_buffer_queue *queue, + struct list_head *list) +{ + struct iio_dma_buffer_block *block, *_block; + unsigned long flags; + + spin_lock_irqsave(&queue->list_lock, flags); + list_for_each_entry_safe(block, _block, list, head) { + list_del(&block->head); + block->bytes_used = 0; + _iio_dma_buffer_block_done(block); + iio_buffer_block_put_atomic(block); + } + spin_unlock_irqrestore(&queue->list_lock, flags); + + wake_up_interruptible_poll(&queue->buffer.pollq, POLLIN | POLLRDNORM); +} +EXPORT_SYMBOL_GPL(iio_dma_buffer_block_list_abort); + +static bool iio_dma_block_reusable(struct iio_dma_buffer_block *block) +{ + /* + * If the core owns the block it can be re-used. This should be the + * default case when enabling the buffer, unless the DMA controller does + * not support abort and has not given back the block yet. + */ + switch (block->state) { + case IIO_BLOCK_STATE_DEQUEUED: + case IIO_BLOCK_STATE_QUEUED: + case IIO_BLOCK_STATE_DONE: + return true; + default: + return false; + } +} + +/** + * iio_dma_buffer_request_update() - DMA buffer request_update callback + * @buffer: The buffer which to request an update + * + * Should be used as the iio_dma_buffer_request_update() callback for + * iio_buffer_access_ops struct for DMA buffers. + */ +int iio_dma_buffer_request_update(struct iio_buffer *buffer) +{ + struct iio_dma_buffer_queue *queue = iio_buffer_to_queue(buffer); + struct iio_dma_buffer_block *block; + bool try_reuse = false; + size_t size; + int ret = 0; + int i; + + /* + * Split the buffer into two even parts. This is used as a double + * buffering scheme with usually one block at a time being used by the + * DMA and the other one by the application. + */ + size = DIV_ROUND_UP(queue->buffer.bytes_per_datum * + queue->buffer.length, 2); + + mutex_lock(&queue->lock); + + /* Allocations are page aligned */ + if (PAGE_ALIGN(queue->fileio.block_size) == PAGE_ALIGN(size)) + try_reuse = true; + + queue->fileio.block_size = size; + queue->fileio.active_block = NULL; + + spin_lock_irq(&queue->list_lock); + for (i = 0; i < 2; i++) { + block = queue->fileio.blocks[i]; + + /* If we can't re-use it free it */ + if (block && (!iio_dma_block_reusable(block) || !try_reuse)) + block->state = IIO_BLOCK_STATE_DEAD; + } + + /* + * At this point all blocks are either owned by the core or marked as + * dead. This means we can reset the lists without having to fear + * corrution. + */ + INIT_LIST_HEAD(&queue->outgoing); + spin_unlock_irq(&queue->list_lock); + + INIT_LIST_HEAD(&queue->incoming); + + for (i = 0; i < 2; i++) { + if (queue->fileio.blocks[i]) { + block = queue->fileio.blocks[i]; + if (block->state == IIO_BLOCK_STATE_DEAD) { + /* Could not reuse it */ + iio_buffer_block_put(block); + block = NULL; + } else { + block->size = size; + } + } else { + block = NULL; + } + + if (!block) { + block = iio_dma_buffer_alloc_block(queue, size); + if (!block) { + ret = -ENOMEM; + goto out_unlock; + } + queue->fileio.blocks[i] = block; + } + + block->state = IIO_BLOCK_STATE_QUEUED; + list_add_tail(&block->head, &queue->incoming); + } + +out_unlock: + mutex_unlock(&queue->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(iio_dma_buffer_request_update); + +static void iio_dma_buffer_submit_block(struct iio_dma_buffer_queue *queue, + struct iio_dma_buffer_block *block) +{ + int ret; + + /* + * If the hardware has already been removed we put the block into + * limbo. It will neither be on the incoming nor outgoing list, nor will + * it ever complete. It will just wait to be freed eventually. + */ + if (!queue->ops) + return; + + block->state = IIO_BLOCK_STATE_ACTIVE; + iio_buffer_block_get(block); + ret = queue->ops->submit(queue, block); + if (ret) { + /* + * This is a bit of a problem and there is not much we can do + * other then wait for the buffer to be disabled and re-enabled + * and try again. But it should not really happen unless we run + * out of memory or something similar. + * + * TODO: Implement support in the IIO core to allow buffers to + * notify consumers that something went wrong and the buffer + * should be disabled. + */ + iio_buffer_block_put(block); + } +} + +/** + * iio_dma_buffer_enable() - Enable DMA buffer + * @buffer: IIO buffer to enable + * @indio_dev: IIO device the buffer is attached to + * + * Needs to be called when the device that the buffer is attached to starts + * sampling. Typically should be the iio_buffer_access_ops enable callback. + * + * This will allocate the DMA buffers and start the DMA transfers. + */ +int iio_dma_buffer_enable(struct iio_buffer *buffer, + struct iio_dev *indio_dev) +{ + struct iio_dma_buffer_queue *queue = iio_buffer_to_queue(buffer); + struct iio_dma_buffer_block *block, *_block; + + mutex_lock(&queue->lock); + queue->active = true; + list_for_each_entry_safe(block, _block, &queue->incoming, head) { + list_del(&block->head); + iio_dma_buffer_submit_block(queue, block); + } + mutex_unlock(&queue->lock); + + return 0; +} +EXPORT_SYMBOL_GPL(iio_dma_buffer_enable); + +/** + * iio_dma_buffer_disable() - Disable DMA buffer + * @buffer: IIO DMA buffer to disable + * @indio_dev: IIO device the buffer is attached to + * + * Needs to be called when the device that the buffer is attached to stops + * sampling. Typically should be the iio_buffer_access_ops disable callback. + */ +int iio_dma_buffer_disable(struct iio_buffer *buffer, + struct iio_dev *indio_dev) +{ + struct iio_dma_buffer_queue *queue = iio_buffer_to_queue(buffer); + + mutex_lock(&queue->lock); + queue->active = false; + + if (queue->ops && queue->ops->abort) + queue->ops->abort(queue); + mutex_unlock(&queue->lock); + + return 0; +} +EXPORT_SYMBOL_GPL(iio_dma_buffer_disable); + +static void iio_dma_buffer_enqueue(struct iio_dma_buffer_queue *queue, + struct iio_dma_buffer_block *block) +{ + if (block->state == IIO_BLOCK_STATE_DEAD) { + iio_buffer_block_put(block); + } else if (queue->active) { + iio_dma_buffer_submit_block(queue, block); + } else { + block->state = IIO_BLOCK_STATE_QUEUED; + list_add_tail(&block->head, &queue->incoming); + } +} + +static struct iio_dma_buffer_block *iio_dma_buffer_dequeue( + struct iio_dma_buffer_queue *queue) +{ + struct iio_dma_buffer_block *block; + + spin_lock_irq(&queue->list_lock); + block = list_first_entry_or_null(&queue->outgoing, struct + iio_dma_buffer_block, head); + if (block != NULL) { + list_del(&block->head); + block->state = IIO_BLOCK_STATE_DEQUEUED; + } + spin_unlock_irq(&queue->list_lock); + + return block; +} + +/** + * iio_dma_buffer_read() - DMA buffer read callback + * @buffer: Buffer to read form + * @n: Number of bytes to read + * @user_buffer: Userspace buffer to copy the data to + * + * Should be used as the read_first_n callback for iio_buffer_access_ops + * struct for DMA buffers. + */ +int iio_dma_buffer_read(struct iio_buffer *buffer, size_t n, + char __user *user_buffer) +{ + struct iio_dma_buffer_queue *queue = iio_buffer_to_queue(buffer); + struct iio_dma_buffer_block *block; + int ret; + + if (n < buffer->bytes_per_datum) + return -EINVAL; + + mutex_lock(&queue->lock); + + if (!queue->fileio.active_block) { + block = iio_dma_buffer_dequeue(queue); + if (block == NULL) { + ret = 0; + goto out_unlock; + } + queue->fileio.pos = 0; + queue->fileio.active_block = block; + } else { + block = queue->fileio.active_block; + } + + n = rounddown(n, buffer->bytes_per_datum); + if (n > block->bytes_used - queue->fileio.pos) + n = block->bytes_used - queue->fileio.pos; + + if (copy_to_user(user_buffer, block->vaddr + queue->fileio.pos, n)) { + ret = -EFAULT; + goto out_unlock; + } + + queue->fileio.pos += n; + + if (queue->fileio.pos == block->bytes_used) { + queue->fileio.active_block = NULL; + iio_dma_buffer_enqueue(queue, block); + } + + ret = n; + +out_unlock: + mutex_unlock(&queue->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(iio_dma_buffer_read); + +/** + * iio_dma_buffer_data_available() - DMA buffer data_available callback + * @buf: Buffer to check for data availability + * + * Should be used as the data_available callback for iio_buffer_access_ops + * struct for DMA buffers. + */ +size_t iio_dma_buffer_data_available(struct iio_buffer *buf) +{ + struct iio_dma_buffer_queue *queue = iio_buffer_to_queue(buf); + struct iio_dma_buffer_block *block; + size_t data_available = 0; + + /* + * For counting the available bytes we'll use the size of the block not + * the number of actual bytes available in the block. Otherwise it is + * possible that we end up with a value that is lower than the watermark + * but won't increase since all blocks are in use. + */ + + mutex_lock(&queue->lock); + if (queue->fileio.active_block) + data_available += queue->fileio.active_block->size; + + spin_lock_irq(&queue->list_lock); + list_for_each_entry(block, &queue->outgoing, head) + data_available += block->size; + spin_unlock_irq(&queue->list_lock); + mutex_unlock(&queue->lock); + + return data_available; +} +EXPORT_SYMBOL_GPL(iio_dma_buffer_data_available); + +/** + * iio_dma_buffer_set_bytes_per_datum() - DMA buffer set_bytes_per_datum callback + * @buffer: Buffer to set the bytes-per-datum for + * @bpd: The new bytes-per-datum value + * + * Should be used as the set_bytes_per_datum callback for iio_buffer_access_ops + * struct for DMA buffers. + */ +int iio_dma_buffer_set_bytes_per_datum(struct iio_buffer *buffer, size_t bpd) +{ + buffer->bytes_per_datum = bpd; + + return 0; +} +EXPORT_SYMBOL_GPL(iio_dma_buffer_set_bytes_per_datum); + +/** + * iio_dma_buffer_set_length - DMA buffer set_length callback + * @buffer: Buffer to set the length for + * @length: The new buffer length + * + * Should be used as the set_length callback for iio_buffer_access_ops + * struct for DMA buffers. + */ +int iio_dma_buffer_set_length(struct iio_buffer *buffer, int length) +{ + /* Avoid an invalid state */ + if (length < 2) + length = 2; + buffer->length = length; + buffer->watermark = length / 2; + + return 0; +} +EXPORT_SYMBOL_GPL(iio_dma_buffer_set_length); + +/** + * iio_dma_buffer_init() - Initialize DMA buffer queue + * @queue: Buffer to initialize + * @dev: DMA device + * @ops: DMA buffer queue callback operations + * + * The DMA device will be used by the queue to do DMA memory allocations. So it + * should refer to the device that will perform the DMA to ensure that + * allocations are done from a memory region that can be accessed by the device. + */ +int iio_dma_buffer_init(struct iio_dma_buffer_queue *queue, + struct device *dev, const struct iio_dma_buffer_ops *ops) +{ + iio_buffer_init(&queue->buffer); + queue->buffer.length = PAGE_SIZE; + queue->buffer.watermark = queue->buffer.length / 2; + queue->dev = dev; + queue->ops = ops; + + INIT_LIST_HEAD(&queue->incoming); + INIT_LIST_HEAD(&queue->outgoing); + + mutex_init(&queue->lock); + spin_lock_init(&queue->list_lock); + + return 0; +} +EXPORT_SYMBOL_GPL(iio_dma_buffer_init); + +/** + * iio_dma_buffer_exit() - Cleanup DMA buffer queue + * @queue: Buffer to cleanup + * + * After this function has completed it is safe to free any resources that are + * associated with the buffer and are accessed inside the callback operations. + */ +void iio_dma_buffer_exit(struct iio_dma_buffer_queue *queue) +{ + unsigned int i; + + mutex_lock(&queue->lock); + + spin_lock_irq(&queue->list_lock); + for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) { + if (!queue->fileio.blocks[i]) + continue; + queue->fileio.blocks[i]->state = IIO_BLOCK_STATE_DEAD; + } + INIT_LIST_HEAD(&queue->outgoing); + spin_unlock_irq(&queue->list_lock); + + INIT_LIST_HEAD(&queue->incoming); + + for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) { + if (!queue->fileio.blocks[i]) + continue; + iio_buffer_block_put(queue->fileio.blocks[i]); + queue->fileio.blocks[i] = NULL; + } + queue->fileio.active_block = NULL; + queue->ops = NULL; + + mutex_unlock(&queue->lock); +} +EXPORT_SYMBOL_GPL(iio_dma_buffer_exit); + +/** + * iio_dma_buffer_release() - Release final buffer resources + * @queue: Buffer to release + * + * Frees resources that can't yet be freed in iio_dma_buffer_exit(). Should be + * called in the buffers release callback implementation right before freeing + * the memory associated with the buffer. + */ +void iio_dma_buffer_release(struct iio_dma_buffer_queue *queue) +{ + mutex_destroy(&queue->lock); +} +EXPORT_SYMBOL_GPL(iio_dma_buffer_release); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("DMA buffer for the IIO framework"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/iio/buffer-dma.h b/include/linux/iio/buffer-dma.h new file mode 100644 index 0000000000000..767467d886de4 --- /dev/null +++ b/include/linux/iio/buffer-dma.h @@ -0,0 +1,152 @@ +/* + * Copyright 2013-2015 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2. + */ + +#ifndef __INDUSTRIALIO_DMA_BUFFER_H__ +#define __INDUSTRIALIO_DMA_BUFFER_H__ + +#include +#include +#include +#include +#include + +struct iio_dma_buffer_queue; +struct iio_dma_buffer_ops; +struct device; + +struct iio_buffer_block { + u32 size; + u32 bytes_used; +}; + +/** + * enum iio_block_state - State of a struct iio_dma_buffer_block + * @IIO_BLOCK_STATE_DEQUEUED: Block is not queued + * @IIO_BLOCK_STATE_QUEUED: Block is on the incoming queue + * @IIO_BLOCK_STATE_ACTIVE: Block is currently being processed by the DMA + * @IIO_BLOCK_STATE_DONE: Block is on the outgoing queue + * @IIO_BLOCK_STATE_DEAD: Block has been marked as to be freed + */ +enum iio_block_state { + IIO_BLOCK_STATE_DEQUEUED, + IIO_BLOCK_STATE_QUEUED, + IIO_BLOCK_STATE_ACTIVE, + IIO_BLOCK_STATE_DONE, + IIO_BLOCK_STATE_DEAD, +}; + +/** + * struct iio_dma_buffer_block - IIO buffer block + * @head: List head + * @size: Total size of the block in bytes + * @bytes_used: Number of bytes that contain valid data + * @vaddr: Virutal address of the blocks memory + * @phys_addr: Physical address of the blocks memory + * @queue: Parent DMA buffer queue + * @kref: kref used to manage the lifetime of block + * @state: Current state of the block + */ +struct iio_dma_buffer_block { + /* May only be accessed by the owner of the block */ + struct list_head head; + size_t bytes_used; + + /* + * Set during allocation, constant thereafter. May be accessed read-only + * by anybody holding a reference to the block. + */ + void *vaddr; + dma_addr_t phys_addr; + size_t size; + struct iio_dma_buffer_queue *queue; + + /* Must not be accessed outside the core. */ + struct kref kref; + /* + * Must not be accessed outside the core. Access needs to hold + * queue->list_lock if the block is not owned by the core. + */ + enum iio_block_state state; +}; + +/** + * struct iio_dma_buffer_queue_fileio - FileIO state for the DMA buffer + * @blocks: Buffer blocks used for fileio + * @active_block: Block being used in read() + * @pos: Read offset in the active block + * @block_size: Size of each block + */ +struct iio_dma_buffer_queue_fileio { + struct iio_dma_buffer_block *blocks[2]; + struct iio_dma_buffer_block *active_block; + size_t pos; + size_t block_size; +}; + +/** + * struct iio_dma_buffer_queue - DMA buffer base structure + * @buffer: IIO buffer base structure + * @dev: Parent device + * @ops: DMA buffer callbacks + * @lock: Protects the incoming list, active and the fields in the fileio + * substruct + * @list_lock: Protects lists that contain blocks which can be modified in + * atomic context as well as blocks on those lists. This is the outgoing queue + * list and typically also a list of active blocks in the part that handles + * the DMA controller + * @incoming: List of buffers on the incoming queue + * @outgoing: List of buffers on the outgoing queue + * @active: Whether the buffer is currently active + * @fileio: FileIO state + */ +struct iio_dma_buffer_queue { + struct iio_buffer buffer; + struct device *dev; + const struct iio_dma_buffer_ops *ops; + + struct mutex lock; + spinlock_t list_lock; + struct list_head incoming; + struct list_head outgoing; + + bool active; + + struct iio_dma_buffer_queue_fileio fileio; +}; + +/** + * struct iio_dma_buffer_ops - DMA buffer callback operations + * @submit: Called when a block is submitted to the DMA controller + * @abort: Should abort all pending transfers + */ +struct iio_dma_buffer_ops { + int (*submit)(struct iio_dma_buffer_queue *queue, + struct iio_dma_buffer_block *block); + void (*abort)(struct iio_dma_buffer_queue *queue); +}; + +void iio_dma_buffer_block_done(struct iio_dma_buffer_block *block); +void iio_dma_buffer_block_list_abort(struct iio_dma_buffer_queue *queue, + struct list_head *list); + +int iio_dma_buffer_enable(struct iio_buffer *buffer, + struct iio_dev *indio_dev); +int iio_dma_buffer_disable(struct iio_buffer *buffer, + struct iio_dev *indio_dev); +int iio_dma_buffer_read(struct iio_buffer *buffer, size_t n, + char __user *user_buffer); +size_t iio_dma_buffer_data_available(struct iio_buffer *buffer); +int iio_dma_buffer_set_bytes_per_datum(struct iio_buffer *buffer, size_t bpd); +int iio_dma_buffer_set_length(struct iio_buffer *buffer, int length); +int iio_dma_buffer_request_update(struct iio_buffer *buffer); + +int iio_dma_buffer_init(struct iio_dma_buffer_queue *queue, + struct device *dma_dev, const struct iio_dma_buffer_ops *ops); +void iio_dma_buffer_exit(struct iio_dma_buffer_queue *queue); +void iio_dma_buffer_release(struct iio_dma_buffer_queue *queue); + +#endif -- GitLab From 2d6ca60f328450ff5c7802d0857d12e3711348ce Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Oct 2015 18:10:29 +0200 Subject: [PATCH 0013/2855] iio: Add a DMAengine framework based buffer Add a generic fully device independent DMA buffer implementation that uses the DMAegnine framework to perform the DMA transfers. This can be used by converter drivers that whish to provide a DMA buffer for converters that are connected to a DMA core that implements the DMAengine API. Apart from allocating the buffer using iio_dmaengine_buffer_alloc() and freeing it using iio_dmaengine_buffer_free() no additional converter driver specific code is required when using this DMA buffer implementation. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/buffer/Kconfig | 11 + drivers/iio/buffer/Makefile | 1 + .../buffer/industrialio-buffer-dmaengine.c | 213 ++++++++++++++++++ include/linux/iio/buffer-dmaengine.h | 18 ++ 4 files changed, 243 insertions(+) create mode 100644 drivers/iio/buffer/industrialio-buffer-dmaengine.c create mode 100644 include/linux/iio/buffer-dmaengine.h diff --git a/drivers/iio/buffer/Kconfig b/drivers/iio/buffer/Kconfig index b2fda1afc03e7..4ffd3db7817f8 100644 --- a/drivers/iio/buffer/Kconfig +++ b/drivers/iio/buffer/Kconfig @@ -18,6 +18,17 @@ config IIO_BUFFER_DMA Should be selected by drivers that want to use the generic DMA buffer infrastructure. +config IIO_BUFFER_DMAENGINE + tristate + select IIO_BUFFER_DMA + help + Provides a bonding of the generic IIO DMA buffer infrastructure with the + DMAengine framework. This can be used by converter drivers with a DMA port + connected to an external DMA controller which is supported by the + DMAengine framework. + + Should be selected by drivers that want to use this functionality. + config IIO_KFIFO_BUF tristate "Industrial I/O buffering based on kfifo" help diff --git a/drivers/iio/buffer/Makefile b/drivers/iio/buffer/Makefile index bda3f1143e727..85beaae831aee 100644 --- a/drivers/iio/buffer/Makefile +++ b/drivers/iio/buffer/Makefile @@ -5,5 +5,6 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_IIO_BUFFER_CB) += industrialio-buffer-cb.o obj-$(CONFIG_IIO_BUFFER_DMA) += industrialio-buffer-dma.o +obj-$(CONFIG_IIO_BUFFER_DMAENGINE) += industrialio-buffer-dmaengine.o obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c new file mode 100644 index 0000000000000..ebdb838d3a1cf --- /dev/null +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c @@ -0,0 +1,213 @@ +/* + * Copyright 2014-2015 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * The IIO DMAengine buffer combines the generic IIO DMA buffer infrastructure + * with the DMAengine framework. The generic IIO DMA buffer infrastructure is + * used to manage the buffer memory and implement the IIO buffer operations + * while the DMAengine framework is used to perform the DMA transfers. Combined + * this results in a device independent fully functional DMA buffer + * implementation that can be used by device drivers for peripherals which are + * connected to a DMA controller which has a DMAengine driver implementation. + */ + +struct dmaengine_buffer { + struct iio_dma_buffer_queue queue; + + struct dma_chan *chan; + struct list_head active; + + size_t align; + size_t max_size; +}; + +static struct dmaengine_buffer *iio_buffer_to_dmaengine_buffer( + struct iio_buffer *buffer) +{ + return container_of(buffer, struct dmaengine_buffer, queue.buffer); +} + +static void iio_dmaengine_buffer_block_done(void *data) +{ + struct iio_dma_buffer_block *block = data; + unsigned long flags; + + spin_lock_irqsave(&block->queue->list_lock, flags); + list_del(&block->head); + spin_unlock_irqrestore(&block->queue->list_lock, flags); + iio_dma_buffer_block_done(block); +} + +static int iio_dmaengine_buffer_submit_block(struct iio_dma_buffer_queue *queue, + struct iio_dma_buffer_block *block) +{ + struct dmaengine_buffer *dmaengine_buffer = + iio_buffer_to_dmaengine_buffer(&queue->buffer); + struct dma_async_tx_descriptor *desc; + dma_cookie_t cookie; + + block->bytes_used = min(block->size, dmaengine_buffer->max_size); + block->bytes_used = rounddown(block->bytes_used, + dmaengine_buffer->align); + + desc = dmaengine_prep_slave_single(dmaengine_buffer->chan, + block->phys_addr, block->bytes_used, DMA_DEV_TO_MEM, + DMA_PREP_INTERRUPT); + if (!desc) + return -ENOMEM; + + desc->callback = iio_dmaengine_buffer_block_done; + desc->callback_param = block; + + cookie = dmaengine_submit(desc); + if (dma_submit_error(cookie)) + return dma_submit_error(cookie); + + spin_lock_irq(&dmaengine_buffer->queue.list_lock); + list_add_tail(&block->head, &dmaengine_buffer->active); + spin_unlock_irq(&dmaengine_buffer->queue.list_lock); + + dma_async_issue_pending(dmaengine_buffer->chan); + + return 0; +} + +static void iio_dmaengine_buffer_abort(struct iio_dma_buffer_queue *queue) +{ + struct dmaengine_buffer *dmaengine_buffer = + iio_buffer_to_dmaengine_buffer(&queue->buffer); + + dmaengine_terminate_all(dmaengine_buffer->chan); + /* FIXME: There is a slight chance of a race condition here. + * dmaengine_terminate_all() does not guarantee that all transfer + * callbacks have finished running. Need to introduce a + * dmaengine_terminate_all_sync(). + */ + iio_dma_buffer_block_list_abort(queue, &dmaengine_buffer->active); +} + +static void iio_dmaengine_buffer_release(struct iio_buffer *buf) +{ + struct dmaengine_buffer *dmaengine_buffer = + iio_buffer_to_dmaengine_buffer(buf); + + iio_dma_buffer_release(&dmaengine_buffer->queue); + kfree(dmaengine_buffer); +} + +static const struct iio_buffer_access_funcs iio_dmaengine_buffer_ops = { + .read_first_n = iio_dma_buffer_read, + .set_bytes_per_datum = iio_dma_buffer_set_bytes_per_datum, + .set_length = iio_dma_buffer_set_length, + .request_update = iio_dma_buffer_request_update, + .enable = iio_dma_buffer_enable, + .disable = iio_dma_buffer_disable, + .data_available = iio_dma_buffer_data_available, + .release = iio_dmaengine_buffer_release, + + .modes = INDIO_BUFFER_HARDWARE, + .flags = INDIO_BUFFER_FLAG_FIXED_WATERMARK, +}; + +static const struct iio_dma_buffer_ops iio_dmaengine_default_ops = { + .submit = iio_dmaengine_buffer_submit_block, + .abort = iio_dmaengine_buffer_abort, +}; + +/** + * iio_dmaengine_buffer_alloc() - Allocate new buffer which uses DMAengine + * @dev: Parent device for the buffer + * @channel: DMA channel name, typically "rx". + * + * This allocates a new IIO buffer which internally uses the DMAengine framework + * to perform its transfers. The parent device will be used to request the DMA + * channel. + * + * Once done using the buffer iio_dmaengine_buffer_free() should be used to + * release it. + */ +struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev, + const char *channel) +{ + struct dmaengine_buffer *dmaengine_buffer; + unsigned int width, src_width, dest_width; + struct dma_slave_caps caps; + struct dma_chan *chan; + int ret; + + dmaengine_buffer = kzalloc(sizeof(*dmaengine_buffer), GFP_KERNEL); + if (!dmaengine_buffer) + return ERR_PTR(-ENOMEM); + + chan = dma_request_slave_channel_reason(dev, channel); + if (IS_ERR(chan)) { + ret = PTR_ERR(chan); + goto err_free; + } + + ret = dma_get_slave_caps(chan, &caps); + if (ret < 0) + goto err_free; + + /* Needs to be aligned to the maximum of the minimums */ + if (caps.src_addr_widths) + src_width = __ffs(caps.src_addr_widths); + else + src_width = 1; + if (caps.dst_addr_widths) + dest_width = __ffs(caps.dst_addr_widths); + else + dest_width = 1; + width = max(src_width, dest_width); + + INIT_LIST_HEAD(&dmaengine_buffer->active); + dmaengine_buffer->chan = chan; + dmaengine_buffer->align = width; + dmaengine_buffer->max_size = dma_get_max_seg_size(chan->device->dev); + + iio_dma_buffer_init(&dmaengine_buffer->queue, chan->device->dev, + &iio_dmaengine_default_ops); + + dmaengine_buffer->queue.buffer.access = &iio_dmaengine_buffer_ops; + + return &dmaengine_buffer->queue.buffer; + +err_free: + kfree(dmaengine_buffer); + return ERR_PTR(ret); +} +EXPORT_SYMBOL(iio_dmaengine_buffer_alloc); + +/** + * iio_dmaengine_buffer_free() - Free dmaengine buffer + * @buffer: Buffer to free + * + * Frees a buffer previously allocated with iio_dmaengine_buffer_alloc(). + */ +void iio_dmaengine_buffer_free(struct iio_buffer *buffer) +{ + struct dmaengine_buffer *dmaengine_buffer = + iio_buffer_to_dmaengine_buffer(buffer); + + iio_dma_buffer_exit(&dmaengine_buffer->queue); + dma_release_channel(dmaengine_buffer->chan); + + iio_buffer_put(buffer); +} +EXPORT_SYMBOL_GPL(iio_dmaengine_buffer_free); diff --git a/include/linux/iio/buffer-dmaengine.h b/include/linux/iio/buffer-dmaengine.h new file mode 100644 index 0000000000000..5dcddf427bb09 --- /dev/null +++ b/include/linux/iio/buffer-dmaengine.h @@ -0,0 +1,18 @@ +/* + * Copyright 2014-2015 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __IIO_DMAENGINE_H__ +#define __IIO_DMAENGINE_H__ + +struct iio_buffer; +struct device; + +struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev, + const char *channel); +void iio_dmaengine_buffer_free(struct iio_buffer *buffer); + +#endif -- GitLab From 18fb1ab0eb81a08ecb00065f3e6c037a37d8e917 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Fri, 30 Oct 2015 16:50:39 -0700 Subject: [PATCH 0014/2855] iio: light: lm3533-als: Print error message on invalid resistance Print an error message to indicate that invalid configuration data was provided in the platform_data, rather than just aborting initialization. Signed-off-by: Bjorn Andersson Signed-off-by: Jonathan Cameron --- drivers/iio/light/lm3533-als.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c index 076bc46fad034..e56937c40a189 100644 --- a/drivers/iio/light/lm3533-als.c +++ b/drivers/iio/light/lm3533-als.c @@ -743,8 +743,10 @@ static int lm3533_als_set_resistor(struct lm3533_als *als, u8 val) { int ret; - if (val < LM3533_ALS_RESISTOR_MIN || val > LM3533_ALS_RESISTOR_MAX) + if (val < LM3533_ALS_RESISTOR_MIN || val > LM3533_ALS_RESISTOR_MAX) { + dev_err(&als->pdev->dev, "invalid resistor value\n"); return -EINVAL; + }; ret = lm3533_write(als->lm3533, LM3533_REG_ALS_RESISTOR_SELECT, val); if (ret) { -- GitLab From a84ef0d181d917125f1f16cffe53f84c19968969 Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Sat, 31 Oct 2015 13:49:16 +0100 Subject: [PATCH 0015/2855] iio: accel: add Freescale MMA7455L/MMA7456L 3-axis accelerometer driver Add support for Freescale MMA7455L/MMA7456L 3-axis in 10-bit mode for I2C and SPI bus. This rather simple driver that currently doesn't support all the hardware features of MMA7455L/MMA7456L. Tested on Embedded Artist's LPC4357 Dev Kit with MMA7455L on I2C bus. Data sheets for the two devices can be found here: http://cache.freescale.com/files/sensors/doc/data_sheet/MMA7455L.pdf http://cache.freescale.com/files/sensors/doc/data_sheet/MMA7456L.pdf Signed-off-by: Joachim Eastwood Signed-off-by: Jonathan Cameron --- drivers/iio/accel/Kconfig | 29 +++ drivers/iio/accel/Makefile | 5 + drivers/iio/accel/mma7455.h | 19 ++ drivers/iio/accel/mma7455_core.c | 311 +++++++++++++++++++++++++++++++ drivers/iio/accel/mma7455_i2c.c | 56 ++++++ drivers/iio/accel/mma7455_spi.c | 52 ++++++ 6 files changed, 472 insertions(+) create mode 100644 drivers/iio/accel/mma7455.h create mode 100644 drivers/iio/accel/mma7455_core.c create mode 100644 drivers/iio/accel/mma7455_i2c.c create mode 100644 drivers/iio/accel/mma7455_spi.c diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index 75ac08790bc5a..87487d377f9b2 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig @@ -107,6 +107,35 @@ config KXCJK1013 To compile this driver as a module, choose M here: the module will be called kxcjk-1013. +config MMA7455 + tristate + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + +config MMA7455_I2C + tristate "Freescale MMA7455L/MMA7456L Accelerometer I2C Driver" + depends on I2C + select MMA7455 + select REGMAP_I2C + help + Say yes here to build support for the Freescale MMA7455L and + MMA7456L 3-axis accelerometer. + + To compile this driver as a module, choose M here: the module + will be called mma7455_i2c. + +config MMA7455_SPI + tristate "Freescale MMA7455L/MMA7456L Accelerometer SPI Driver" + depends on SPI_MASTER + select MMA7455 + select REGMAP_SPI + help + Say yes here to build support for the Freescale MMA7455L and + MMA7456L 3-axis accelerometer. + + To compile this driver as a module, choose M here: the module + will be called mma7455_spi. + config MMA8452 tristate "Freescale MMA8452Q and similar Accelerometers Driver" depends on I2C diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile index 525ed52fab52f..71b6794de8858 100644 --- a/drivers/iio/accel/Makefile +++ b/drivers/iio/accel/Makefile @@ -10,6 +10,11 @@ obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o obj-$(CONFIG_KXSD9) += kxsd9.o + +obj-$(CONFIG_MMA7455) += mma7455_core.o +obj-$(CONFIG_MMA7455_I2C) += mma7455_i2c.o +obj-$(CONFIG_MMA7455_SPI) += mma7455_spi.o + obj-$(CONFIG_MMA8452) += mma8452.o obj-$(CONFIG_MMA9551_CORE) += mma9551_core.o diff --git a/drivers/iio/accel/mma7455.h b/drivers/iio/accel/mma7455.h new file mode 100644 index 0000000000000..2b1152c53d4f5 --- /dev/null +++ b/drivers/iio/accel/mma7455.h @@ -0,0 +1,19 @@ +/* + * IIO accel driver for Freescale MMA7455L 3-axis 10-bit accelerometer + * Copyright 2015 Joachim Eastwood + * + * 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. + */ + +#ifndef __MMA7455_H +#define __MMA7455_H + +extern const struct regmap_config mma7455_core_regmap; + +int mma7455_core_probe(struct device *dev, struct regmap *regmap, + const char *name); +int mma7455_core_remove(struct device *dev); + +#endif diff --git a/drivers/iio/accel/mma7455_core.c b/drivers/iio/accel/mma7455_core.c new file mode 100644 index 0000000000000..c633cc2c0789e --- /dev/null +++ b/drivers/iio/accel/mma7455_core.c @@ -0,0 +1,311 @@ +/* + * IIO accel core driver for Freescale MMA7455L 3-axis 10-bit accelerometer + * Copyright 2015 Joachim Eastwood + * + * 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. + * + * UNSUPPORTED hardware features: + * - 8-bit mode with different scales + * - INT1/INT2 interrupts + * - Offset calibration + * - Events + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mma7455.h" + +#define MMA7455_REG_XOUTL 0x00 +#define MMA7455_REG_XOUTH 0x01 +#define MMA7455_REG_YOUTL 0x02 +#define MMA7455_REG_YOUTH 0x03 +#define MMA7455_REG_ZOUTL 0x04 +#define MMA7455_REG_ZOUTH 0x05 +#define MMA7455_REG_STATUS 0x09 +#define MMA7455_STATUS_DRDY BIT(0) +#define MMA7455_REG_WHOAMI 0x0f +#define MMA7455_WHOAMI_ID 0x55 +#define MMA7455_REG_MCTL 0x16 +#define MMA7455_MCTL_MODE_STANDBY 0x00 +#define MMA7455_MCTL_MODE_MEASURE 0x01 +#define MMA7455_REG_CTL1 0x18 +#define MMA7455_CTL1_DFBW_MASK BIT(7) +#define MMA7455_CTL1_DFBW_125HZ BIT(7) +#define MMA7455_CTL1_DFBW_62_5HZ 0 +#define MMA7455_REG_TW 0x1e + +/* + * When MMA7455 is used in 10-bit it has a fullscale of -8g + * corresponding to raw value -512. The userspace interface + * uses m/s^2 and we declare micro units. + * So scale factor is given by: + * g * 8 * 1e6 / 512 = 153228.90625, with g = 9.80665 + */ +#define MMA7455_10BIT_SCALE 153229 + +struct mma7455_data { + struct regmap *regmap; + struct device *dev; +}; + +static int mma7455_drdy(struct mma7455_data *mma7455) +{ + unsigned int reg; + int tries = 3; + int ret; + + while (tries-- > 0) { + ret = regmap_read(mma7455->regmap, MMA7455_REG_STATUS, ®); + if (ret) + return ret; + + if (reg & MMA7455_STATUS_DRDY) + return 0; + + msleep(20); + } + + dev_warn(mma7455->dev, "data not ready\n"); + + return -EIO; +} + +static irqreturn_t mma7455_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct mma7455_data *mma7455 = iio_priv(indio_dev); + u8 buf[16]; /* 3 x 16-bit channels + padding + ts */ + int ret; + + ret = mma7455_drdy(mma7455); + if (ret) + goto done; + + ret = regmap_bulk_read(mma7455->regmap, MMA7455_REG_XOUTL, buf, + sizeof(__le16) * 3); + if (ret) + goto done; + + iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns()); + +done: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static int mma7455_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct mma7455_data *mma7455 = iio_priv(indio_dev); + unsigned int reg; + __le16 data; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (iio_buffer_enabled(indio_dev)) + return -EBUSY; + + ret = mma7455_drdy(mma7455); + if (ret) + return ret; + + ret = regmap_bulk_read(mma7455->regmap, chan->address, &data, + sizeof(data)); + if (ret) + return ret; + + *val = sign_extend32(le16_to_cpu(data), 9); + + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + *val = 0; + *val2 = MMA7455_10BIT_SCALE; + + return IIO_VAL_INT_PLUS_MICRO; + + case IIO_CHAN_INFO_SAMP_FREQ: + ret = regmap_read(mma7455->regmap, MMA7455_REG_CTL1, ®); + if (ret) + return ret; + + if (reg & MMA7455_CTL1_DFBW_MASK) + *val = 250; + else + *val = 125; + + return IIO_VAL_INT; + } + + return -EINVAL; +} + +static int mma7455_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct mma7455_data *mma7455 = iio_priv(indio_dev); + int i; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + if (val == 250 && val2 == 0) + i = MMA7455_CTL1_DFBW_125HZ; + else if (val == 125 && val2 == 0) + i = MMA7455_CTL1_DFBW_62_5HZ; + else + return -EINVAL; + + return regmap_update_bits(mma7455->regmap, MMA7455_REG_CTL1, + MMA7455_CTL1_DFBW_MASK, i); + + case IIO_CHAN_INFO_SCALE: + /* In 10-bit mode there is only one scale available */ + if (val == 0 && val2 == MMA7455_10BIT_SCALE) + return 0; + break; + } + + return -EINVAL; +} + +static IIO_CONST_ATTR(sampling_frequency_available, "125 250"); + +static struct attribute *mma7455_attributes[] = { + &iio_const_attr_sampling_frequency_available.dev_attr.attr, + NULL +}; + +static const struct attribute_group mma7455_group = { + .attrs = mma7455_attributes, +}; + +static const struct iio_info mma7455_info = { + .attrs = &mma7455_group, + .read_raw = mma7455_read_raw, + .write_raw = mma7455_write_raw, + .driver_module = THIS_MODULE, +}; + +#define MMA7455_CHANNEL(axis, idx) { \ + .type = IIO_ACCEL, \ + .modified = 1, \ + .address = MMA7455_REG_##axis##OUTL,\ + .channel2 = IIO_MOD_##axis, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ + BIT(IIO_CHAN_INFO_SCALE), \ + .scan_index = idx, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 10, \ + .storagebits = 16, \ + .endianness = IIO_LE, \ + }, \ +} + +static const struct iio_chan_spec mma7455_channels[] = { + MMA7455_CHANNEL(X, 0), + MMA7455_CHANNEL(Y, 1), + MMA7455_CHANNEL(Z, 2), + IIO_CHAN_SOFT_TIMESTAMP(3), +}; + +static const unsigned long mma7455_scan_masks[] = {0x7, 0}; + +const struct regmap_config mma7455_core_regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = MMA7455_REG_TW, +}; +EXPORT_SYMBOL_GPL(mma7455_core_regmap); + +int mma7455_core_probe(struct device *dev, struct regmap *regmap, + const char *name) +{ + struct mma7455_data *mma7455; + struct iio_dev *indio_dev; + unsigned int reg; + int ret; + + ret = regmap_read(regmap, MMA7455_REG_WHOAMI, ®); + if (ret) { + dev_err(dev, "unable to read reg\n"); + return ret; + } + + if (reg != MMA7455_WHOAMI_ID) { + dev_err(dev, "device id mismatch\n"); + return -ENODEV; + } + + indio_dev = devm_iio_device_alloc(dev, sizeof(*mma7455)); + if (!indio_dev) + return -ENOMEM; + + dev_set_drvdata(dev, indio_dev); + mma7455 = iio_priv(indio_dev); + mma7455->regmap = regmap; + mma7455->dev = dev; + + indio_dev->info = &mma7455_info; + indio_dev->name = name; + indio_dev->dev.parent = dev; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = mma7455_channels; + indio_dev->num_channels = ARRAY_SIZE(mma7455_channels); + indio_dev->available_scan_masks = mma7455_scan_masks; + + regmap_write(mma7455->regmap, MMA7455_REG_MCTL, + MMA7455_MCTL_MODE_MEASURE); + + ret = iio_triggered_buffer_setup(indio_dev, NULL, + mma7455_trigger_handler, NULL); + if (ret) { + dev_err(dev, "unable to setup triggered buffer\n"); + return ret; + } + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(dev, "unable to register device\n"); + iio_triggered_buffer_cleanup(indio_dev); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(mma7455_core_probe); + +int mma7455_core_remove(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct mma7455_data *mma7455 = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + + regmap_write(mma7455->regmap, MMA7455_REG_MCTL, + MMA7455_MCTL_MODE_STANDBY); + + return 0; +} +EXPORT_SYMBOL_GPL(mma7455_core_remove); + +MODULE_AUTHOR("Joachim Eastwood "); +MODULE_DESCRIPTION("Freescale MMA7455L core accelerometer driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/accel/mma7455_i2c.c b/drivers/iio/accel/mma7455_i2c.c new file mode 100644 index 0000000000000..3cab5fb4a3c49 --- /dev/null +++ b/drivers/iio/accel/mma7455_i2c.c @@ -0,0 +1,56 @@ +/* + * IIO accel I2C driver for Freescale MMA7455L 3-axis 10-bit accelerometer + * Copyright 2015 Joachim Eastwood + * + * 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. + */ + +#include +#include +#include + +#include "mma7455.h" + +static int mma7455_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct regmap *regmap; + const char *name = NULL; + + regmap = devm_regmap_init_i2c(i2c, &mma7455_core_regmap); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + if (id) + name = id->name; + + return mma7455_core_probe(&i2c->dev, regmap, name); +} + +static int mma7455_i2c_remove(struct i2c_client *i2c) +{ + return mma7455_core_remove(&i2c->dev); +} + +static const struct i2c_device_id mma7455_i2c_ids[] = { + { "mma7455", 0 }, + { "mma7456", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mma7455_i2c_ids); + +static struct i2c_driver mma7455_i2c_driver = { + .probe = mma7455_i2c_probe, + .remove = mma7455_i2c_remove, + .id_table = mma7455_i2c_ids, + .driver = { + .name = "mma7455-i2c", + }, +}; +module_i2c_driver(mma7455_i2c_driver); + +MODULE_AUTHOR("Joachim Eastwood "); +MODULE_DESCRIPTION("Freescale MMA7455L I2C accelerometer driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/accel/mma7455_spi.c b/drivers/iio/accel/mma7455_spi.c new file mode 100644 index 0000000000000..79df8f27cf998 --- /dev/null +++ b/drivers/iio/accel/mma7455_spi.c @@ -0,0 +1,52 @@ +/* + * IIO accel SPI driver for Freescale MMA7455L 3-axis 10-bit accelerometer + * Copyright 2015 Joachim Eastwood + * + * 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. + */ + +#include +#include +#include + +#include "mma7455.h" + +static int mma7455_spi_probe(struct spi_device *spi) +{ + const struct spi_device_id *id = spi_get_device_id(spi); + struct regmap *regmap; + + regmap = devm_regmap_init_spi(spi, &mma7455_core_regmap); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + return mma7455_core_probe(&spi->dev, regmap, id->name); +} + +static int mma7455_spi_remove(struct spi_device *spi) +{ + return mma7455_core_remove(&spi->dev); +} + +static const struct spi_device_id mma7455_spi_ids[] = { + { "mma7455", 0 }, + { "mma7456", 0 }, + { } +}; +MODULE_DEVICE_TABLE(spi, mma7455_spi_ids); + +static struct spi_driver mma7455_spi_driver = { + .probe = mma7455_spi_probe, + .remove = mma7455_spi_remove, + .id_table = mma7455_spi_ids, + .driver = { + .name = "mma7455-spi", + }, +}; +module_spi_driver(mma7455_spi_driver); + +MODULE_AUTHOR("Joachim Eastwood "); +MODULE_DESCRIPTION("Freescale MMA7455L SPI accelerometer driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 536bbca7cfc9e7a85704de552fcf4b5d1062a38e Mon Sep 17 00:00:00 2001 From: Adriana Reus Date: Fri, 6 Nov 2015 11:10:37 +0200 Subject: [PATCH 0016/2855] iio: light: pa12203001: Poweroff chip if register fails Make sure we poweroff the chip if for any reason iio_register returns an error. Signed-off-by: Adriana Reus Signed-off-by: Jonathan Cameron --- drivers/iio/light/pa12203001.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/iio/light/pa12203001.c b/drivers/iio/light/pa12203001.c index 45f7bde02bbf7..76a9e12b46bc4 100644 --- a/drivers/iio/light/pa12203001.c +++ b/drivers/iio/light/pa12203001.c @@ -381,17 +381,23 @@ static int pa12203001_probe(struct i2c_client *client, return ret; ret = pm_runtime_set_active(&client->dev); - if (ret < 0) { - pa12203001_power_chip(indio_dev, PA12203001_CHIP_DISABLE); - return ret; - } + if (ret < 0) + goto out_err; pm_runtime_enable(&client->dev); pm_runtime_set_autosuspend_delay(&client->dev, PA12203001_SLEEP_DELAY_MS); pm_runtime_use_autosuspend(&client->dev); - return iio_device_register(indio_dev); + ret = iio_device_register(indio_dev); + if (ret < 0) + goto out_err; + + return 0; + +out_err: + pa12203001_power_chip(indio_dev, PA12203001_CHIP_DISABLE); + return ret; } static int pa12203001_remove(struct i2c_client *client) -- GitLab From 7d0ead5c3f00a0652fa4436f0d2dd05e9f2de140 Mon Sep 17 00:00:00 2001 From: Adriana Reus Date: Thu, 5 Nov 2015 16:25:29 +0200 Subject: [PATCH 0017/2855] iio: Reconcile operation order between iio_register/unregister and pm functions At probe, runtime pm should be setup before registering the sysfs interface so that all the power attributes are accurate and functional when registering. Also, when removing the device we should unregister first to make sure that the interfaces that may result in wakeups are no longer available. Fix this behaviour for the following drivers: bmc150, bmg160, kmx61, kxcj-1013, mma9551, mma9553, rpr0521. Signed-off-by: Adriana Reus Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bmc150-accel-core.c | 20 +++++++++----------- drivers/iio/accel/kxcjk-1013.c | 20 +++++++++----------- drivers/iio/accel/mma9551.c | 19 +++++++++---------- drivers/iio/accel/mma9553.c | 20 +++++++++----------- drivers/iio/gyro/bmg160_core.c | 19 +++++++++---------- drivers/iio/imu/kmx61.c | 24 +++++++++++------------- drivers/iio/light/rpr0521.c | 14 ++++---------- drivers/iio/magnetometer/bmc150_magn.c | 20 +++++++++----------- 8 files changed, 69 insertions(+), 87 deletions(-) diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index 2d33f1e821db0..c73331f7782b8 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -1623,24 +1623,22 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq, } } - ret = iio_device_register(indio_dev); - if (ret < 0) { - dev_err(dev, "Unable to register iio device\n"); - goto err_trigger_unregister; - } - ret = pm_runtime_set_active(dev); if (ret) - goto err_iio_unregister; + goto err_trigger_unregister; pm_runtime_enable(dev); pm_runtime_set_autosuspend_delay(dev, BMC150_AUTO_SUSPEND_DELAY_MS); pm_runtime_use_autosuspend(dev); + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(dev, "Unable to register iio device\n"); + goto err_trigger_unregister; + } + return 0; -err_iio_unregister: - iio_device_unregister(indio_dev); err_trigger_unregister: bmc150_accel_unregister_triggers(data, BMC150_ACCEL_TRIGGERS - 1); err_buffer_cleanup: @@ -1655,12 +1653,12 @@ int bmc150_accel_core_remove(struct device *dev) struct iio_dev *indio_dev = dev_get_drvdata(dev); struct bmc150_accel_data *data = iio_priv(indio_dev); + iio_device_unregister(indio_dev); + pm_runtime_disable(data->dev); pm_runtime_set_suspended(data->dev); pm_runtime_put_noidle(data->dev); - iio_device_unregister(indio_dev); - bmc150_accel_unregister_triggers(data, BMC150_ACCEL_TRIGGERS - 1); iio_triggered_buffer_cleanup(indio_dev); diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index 18c1b06684c1b..edec1d099e917 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -1264,25 +1264,23 @@ static int kxcjk1013_probe(struct i2c_client *client, goto err_trigger_unregister; } - ret = iio_device_register(indio_dev); - if (ret < 0) { - dev_err(&client->dev, "unable to register iio device\n"); - goto err_buffer_cleanup; - } - ret = pm_runtime_set_active(&client->dev); if (ret) - goto err_iio_unregister; + goto err_buffer_cleanup; pm_runtime_enable(&client->dev); pm_runtime_set_autosuspend_delay(&client->dev, KXCJK1013_SLEEP_DELAY_MS); pm_runtime_use_autosuspend(&client->dev); + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(&client->dev, "unable to register iio device\n"); + goto err_buffer_cleanup; + } + return 0; -err_iio_unregister: - iio_device_unregister(indio_dev); err_buffer_cleanup: if (data->dready_trig) iio_triggered_buffer_cleanup(indio_dev); @@ -1302,12 +1300,12 @@ static int kxcjk1013_remove(struct i2c_client *client) struct iio_dev *indio_dev = i2c_get_clientdata(client); struct kxcjk1013_data *data = iio_priv(indio_dev); + iio_device_unregister(indio_dev); + pm_runtime_disable(&client->dev); pm_runtime_set_suspended(&client->dev); pm_runtime_put_noidle(&client->dev); - iio_device_unregister(indio_dev); - if (data->dready_trig) { iio_triggered_buffer_cleanup(indio_dev); iio_trigger_unregister(data->dready_trig); diff --git a/drivers/iio/accel/mma9551.c b/drivers/iio/accel/mma9551.c index 7db7cc0bf362f..d899a4d4307f9 100644 --- a/drivers/iio/accel/mma9551.c +++ b/drivers/iio/accel/mma9551.c @@ -495,25 +495,23 @@ static int mma9551_probe(struct i2c_client *client, if (ret < 0) goto out_poweroff; - ret = iio_device_register(indio_dev); - if (ret < 0) { - dev_err(&client->dev, "unable to register iio device\n"); - goto out_poweroff; - } - ret = pm_runtime_set_active(&client->dev); if (ret < 0) - goto out_iio_unregister; + goto out_poweroff; pm_runtime_enable(&client->dev); pm_runtime_set_autosuspend_delay(&client->dev, MMA9551_AUTO_SUSPEND_DELAY_MS); pm_runtime_use_autosuspend(&client->dev); + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(&client->dev, "unable to register iio device\n"); + goto out_poweroff; + } + return 0; -out_iio_unregister: - iio_device_unregister(indio_dev); out_poweroff: mma9551_set_device_state(client, false); @@ -525,11 +523,12 @@ static int mma9551_remove(struct i2c_client *client) struct iio_dev *indio_dev = i2c_get_clientdata(client); struct mma9551_data *data = iio_priv(indio_dev); + iio_device_unregister(indio_dev); + pm_runtime_disable(&client->dev); pm_runtime_set_suspended(&client->dev); pm_runtime_put_noidle(&client->dev); - iio_device_unregister(indio_dev); mutex_lock(&data->mutex); mma9551_set_device_state(data->client, false); mutex_unlock(&data->mutex); diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c index 9408ef3add58f..fa7d36217c4ba 100644 --- a/drivers/iio/accel/mma9553.c +++ b/drivers/iio/accel/mma9553.c @@ -1133,27 +1133,24 @@ static int mma9553_probe(struct i2c_client *client, } } - ret = iio_device_register(indio_dev); - if (ret < 0) { - dev_err(&client->dev, "unable to register iio device\n"); - goto out_poweroff; - } - ret = pm_runtime_set_active(&client->dev); if (ret < 0) - goto out_iio_unregister; + goto out_poweroff; pm_runtime_enable(&client->dev); pm_runtime_set_autosuspend_delay(&client->dev, MMA9551_AUTO_SUSPEND_DELAY_MS); pm_runtime_use_autosuspend(&client->dev); - dev_dbg(&indio_dev->dev, "Registered device %s\n", name); + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(&client->dev, "unable to register iio device\n"); + goto out_poweroff; + } + dev_dbg(&indio_dev->dev, "Registered device %s\n", name); return 0; -out_iio_unregister: - iio_device_unregister(indio_dev); out_poweroff: mma9551_set_device_state(client, false); return ret; @@ -1164,11 +1161,12 @@ static int mma9553_remove(struct i2c_client *client) struct iio_dev *indio_dev = i2c_get_clientdata(client); struct mma9553_data *data = iio_priv(indio_dev); + iio_device_unregister(indio_dev); + pm_runtime_disable(&client->dev); pm_runtime_set_suspended(&client->dev); pm_runtime_put_noidle(&client->dev); - iio_device_unregister(indio_dev); mutex_lock(&data->mutex); mma9551_set_device_state(data->client, false); mutex_unlock(&data->mutex); diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c index 02ff789852a05..bbce3b09ac45a 100644 --- a/drivers/iio/gyro/bmg160_core.c +++ b/drivers/iio/gyro/bmg160_core.c @@ -1077,25 +1077,23 @@ int bmg160_core_probe(struct device *dev, struct regmap *regmap, int irq, goto err_trigger_unregister; } - ret = iio_device_register(indio_dev); - if (ret < 0) { - dev_err(dev, "unable to register iio device\n"); - goto err_buffer_cleanup; - } - ret = pm_runtime_set_active(dev); if (ret) - goto err_iio_unregister; + goto err_buffer_cleanup; pm_runtime_enable(dev); pm_runtime_set_autosuspend_delay(dev, BMG160_AUTO_SUSPEND_DELAY_MS); pm_runtime_use_autosuspend(dev); + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(dev, "unable to register iio device\n"); + goto err_buffer_cleanup; + } + return 0; -err_iio_unregister: - iio_device_unregister(indio_dev); err_buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); err_trigger_unregister: @@ -1113,11 +1111,12 @@ void bmg160_core_remove(struct device *dev) struct iio_dev *indio_dev = dev_get_drvdata(dev); struct bmg160_data *data = iio_priv(indio_dev); + iio_device_unregister(indio_dev); + pm_runtime_disable(dev); pm_runtime_set_suspended(dev); pm_runtime_put_noidle(dev); - iio_device_unregister(indio_dev); iio_triggered_buffer_cleanup(indio_dev); if (data->dready_trig) { diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c index dbf5e99366358..e5306b4e020ef 100644 --- a/drivers/iio/imu/kmx61.c +++ b/drivers/iio/imu/kmx61.c @@ -1390,6 +1390,14 @@ static int kmx61_probe(struct i2c_client *client, } } + ret = pm_runtime_set_active(&client->dev); + if (ret < 0) + goto err_buffer_cleanup_mag; + + pm_runtime_enable(&client->dev); + pm_runtime_set_autosuspend_delay(&client->dev, KMX61_SLEEP_DELAY_MS); + pm_runtime_use_autosuspend(&client->dev); + ret = iio_device_register(data->acc_indio_dev); if (ret < 0) { dev_err(&client->dev, "Failed to register acc iio device\n"); @@ -1402,18 +1410,8 @@ static int kmx61_probe(struct i2c_client *client, goto err_iio_unregister_acc; } - ret = pm_runtime_set_active(&client->dev); - if (ret < 0) - goto err_iio_unregister_mag; - - pm_runtime_enable(&client->dev); - pm_runtime_set_autosuspend_delay(&client->dev, KMX61_SLEEP_DELAY_MS); - pm_runtime_use_autosuspend(&client->dev); - return 0; -err_iio_unregister_mag: - iio_device_unregister(data->mag_indio_dev); err_iio_unregister_acc: iio_device_unregister(data->acc_indio_dev); err_buffer_cleanup_mag: @@ -1437,13 +1435,13 @@ static int kmx61_remove(struct i2c_client *client) { struct kmx61_data *data = i2c_get_clientdata(client); + iio_device_unregister(data->acc_indio_dev); + iio_device_unregister(data->mag_indio_dev); + pm_runtime_disable(&client->dev); pm_runtime_set_suspended(&client->dev); pm_runtime_put_noidle(&client->dev); - iio_device_unregister(data->acc_indio_dev); - iio_device_unregister(data->mag_indio_dev); - if (client->irq > 0) { iio_triggered_buffer_cleanup(data->acc_indio_dev); iio_triggered_buffer_cleanup(data->mag_indio_dev); diff --git a/drivers/iio/light/rpr0521.c b/drivers/iio/light/rpr0521.c index 4b75bb0998b3b..7de0f397194b0 100644 --- a/drivers/iio/light/rpr0521.c +++ b/drivers/iio/light/rpr0521.c @@ -507,34 +507,28 @@ static int rpr0521_probe(struct i2c_client *client, dev_err(&client->dev, "rpr0521 chip init failed\n"); return ret; } - ret = iio_device_register(indio_dev); - if (ret < 0) - return ret; ret = pm_runtime_set_active(&client->dev); if (ret < 0) - goto err_iio_unregister; + return ret; pm_runtime_enable(&client->dev); pm_runtime_set_autosuspend_delay(&client->dev, RPR0521_SLEEP_DELAY_MS); pm_runtime_use_autosuspend(&client->dev); - return 0; - -err_iio_unregister: - iio_device_unregister(indio_dev); - return ret; + return iio_device_register(indio_dev); } static int rpr0521_remove(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client); + iio_device_unregister(indio_dev); + pm_runtime_disable(&client->dev); pm_runtime_set_suspended(&client->dev); pm_runtime_put_noidle(&client->dev); - iio_device_unregister(indio_dev); rpr0521_poweroff(iio_priv(indio_dev)); return 0; diff --git a/drivers/iio/magnetometer/bmc150_magn.c b/drivers/iio/magnetometer/bmc150_magn.c index 1615b23d7b2a6..ffcb75ea64fb0 100644 --- a/drivers/iio/magnetometer/bmc150_magn.c +++ b/drivers/iio/magnetometer/bmc150_magn.c @@ -928,27 +928,24 @@ static int bmc150_magn_probe(struct i2c_client *client, goto err_free_irq; } - ret = iio_device_register(indio_dev); - if (ret < 0) { - dev_err(&client->dev, "unable to register iio device\n"); - goto err_buffer_cleanup; - } - ret = pm_runtime_set_active(&client->dev); if (ret) - goto err_iio_unregister; + goto err_buffer_cleanup; pm_runtime_enable(&client->dev); pm_runtime_set_autosuspend_delay(&client->dev, BMC150_MAGN_AUTO_SUSPEND_DELAY_MS); pm_runtime_use_autosuspend(&client->dev); - dev_dbg(&indio_dev->dev, "Registered device %s\n", name); + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(&client->dev, "unable to register iio device\n"); + goto err_buffer_cleanup; + } + dev_dbg(&indio_dev->dev, "Registered device %s\n", name); return 0; -err_iio_unregister: - iio_device_unregister(indio_dev); err_buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); err_free_irq: @@ -967,11 +964,12 @@ static int bmc150_magn_remove(struct i2c_client *client) struct iio_dev *indio_dev = i2c_get_clientdata(client); struct bmc150_magn_data *data = iio_priv(indio_dev); + iio_device_unregister(indio_dev); + pm_runtime_disable(&client->dev); pm_runtime_set_suspended(&client->dev); pm_runtime_put_noidle(&client->dev); - iio_device_unregister(indio_dev); iio_triggered_buffer_cleanup(indio_dev); if (client->irq > 0) -- GitLab From a106b4748917ba510d083217dbc25e56299f32d4 Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Sun, 1 Nov 2015 14:58:44 +0200 Subject: [PATCH 0018/2855] iio: gyro: check sscanf return value This patch fixes the checkpatch warnings: WARNING: unchecked sscanf return value Signed-off-by: Ioana Ciornei Acked-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/adis16136.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/iio/gyro/adis16136.c b/drivers/iio/gyro/adis16136.c index 26de876b223d0..bb09bff251031 100644 --- a/drivers/iio/gyro/adis16136.c +++ b/drivers/iio/gyro/adis16136.c @@ -435,7 +435,9 @@ static int adis16136_initial_setup(struct iio_dev *indio_dev) if (ret) return ret; - sscanf(indio_dev->name, "adis%u\n", &device_id); + ret = sscanf(indio_dev->name, "adis%u\n", &device_id); + if (ret != 1) + return -EINVAL; if (prod_id != device_id) dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.", -- GitLab From 72a868b38bdd60cbc4084a91fd7b8df3e2bb96ba Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Sun, 1 Nov 2015 14:58:45 +0200 Subject: [PATCH 0019/2855] iio: imu: check sscanf return value This patch fixes the following checkpatch warning: WARNING: unchecked sscanf return value Signed-off-by: Ioana Ciornei Acked-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/imu/adis16400_core.c | 6 +++++- drivers/iio/imu/adis16480.c | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c index abc4c50de9e8b..72bcc2491d1dd 100644 --- a/drivers/iio/imu/adis16400_core.c +++ b/drivers/iio/imu/adis16400_core.c @@ -288,7 +288,11 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev) if (ret) goto err_ret; - sscanf(indio_dev->name, "adis%u\n", &device_id); + ret = sscanf(indio_dev->name, "adis%u\n", &device_id); + if (ret != 1) { + ret = -EINVAL; + goto err_ret; + } if (prod_id != device_id) dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.", diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c index b94bfd3f595bf..16d430461414a 100644 --- a/drivers/iio/imu/adis16480.c +++ b/drivers/iio/imu/adis16480.c @@ -765,7 +765,9 @@ static int adis16480_initial_setup(struct iio_dev *indio_dev) if (ret) return ret; - sscanf(indio_dev->name, "adis%u\n", &device_id); + ret = sscanf(indio_dev->name, "adis%u\n", &device_id); + if (ret != 1) + return -EINVAL; if (prod_id != device_id) dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.", -- GitLab From 89a41cbba6610b48e793ce6ac5bd46031c7531cc Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Fri, 30 Oct 2015 13:34:00 -0700 Subject: [PATCH 0020/2855] mtd: ofpart: document the lock flag. The lock flag of ofpart is undocumented. Add to binding doc. Signed-off-by: Michal Suchanek Cc: Sascha Hauer Acked-by: Rob Herring Signed-off-by: Brian Norris --- Documentation/devicetree/bindings/mtd/partition.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/mtd/partition.txt b/Documentation/devicetree/bindings/mtd/partition.txt index f1e2a02381a49..8dc4bf9dc8e50 100644 --- a/Documentation/devicetree/bindings/mtd/partition.txt +++ b/Documentation/devicetree/bindings/mtd/partition.txt @@ -30,6 +30,8 @@ Optional properties: partition should only be mounted read-only. This is usually used for flash partitions containing early-boot firmware images or data which should not be clobbered. +- lock : Do not unlock the partition at initialization time (not supported on + all devices) Examples: -- GitLab From a486d11f5d71b88eb235fdfc035eebca5f35f120 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 15 Oct 2015 15:08:44 +0200 Subject: [PATCH 0021/2855] mtd: afs: rename structs and functions for v1 Since we're gonna add the v2 version of flash information structure and we want to avoid confusion, rename the old functions to *v1. Cut the word "structure" from the struct name, it is pretty obvious that it is a struct already from the keyword. Cc: Ryan Harkin Cc: Liviu Dudau Signed-off-by: Linus Walleij Signed-off-by: Brian Norris --- drivers/mtd/afs.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c index 96a33e3f7b000..9af00528586f7 100644 --- a/drivers/mtd/afs.c +++ b/drivers/mtd/afs.c @@ -34,7 +34,7 @@ #include #include -struct footer_struct { +struct footer_v1 { u32 image_info_base; /* Address of first word of ImageFooter */ u32 image_start; /* Start of area reserved by this footer */ u32 signature; /* 'Magic' number proves it's a footer */ @@ -42,7 +42,7 @@ struct footer_struct { u32 checksum; /* Just this structure */ }; -struct image_info_struct { +struct image_info_v1 { u32 bootFlags; /* Boot flags, compression etc. */ u32 imageNumber; /* Unique number, selects for boot etc. */ u32 loadAddress; /* Address program should be loaded to */ @@ -67,10 +67,10 @@ static u32 word_sum(void *words, int num) } static int -afs_read_footer(struct mtd_info *mtd, u_int *img_start, u_int *iis_start, - u_int off, u_int mask) +afs_read_footer_v1(struct mtd_info *mtd, u_int *img_start, u_int *iis_start, + u_int off, u_int mask) { - struct footer_struct fs; + struct footer_v1 fs; u_int ptr = off + mtd->erasesize - sizeof(fs); size_t sz; int ret; @@ -126,7 +126,7 @@ afs_read_footer(struct mtd_info *mtd, u_int *img_start, u_int *iis_start, } static int -afs_read_iis(struct mtd_info *mtd, struct image_info_struct *iis, u_int ptr) +afs_read_iis_v1(struct mtd_info *mtd, struct image_info_v1 *iis, u_int ptr) { size_t sz; int ret, i; @@ -182,16 +182,16 @@ static int parse_afs_partitions(struct mtd_info *mtd, * the strings. */ for (idx = off = sz = 0; off < mtd->size; off += mtd->erasesize) { - struct image_info_struct iis; + struct image_info_v1 iis; u_int iis_ptr, img_ptr; - ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask); + ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask); if (ret < 0) break; if (ret == 0) continue; - ret = afs_read_iis(mtd, &iis, iis_ptr); + ret = afs_read_iis_v1(mtd, &iis, iis_ptr); if (ret < 0) break; if (ret == 0) @@ -215,18 +215,18 @@ static int parse_afs_partitions(struct mtd_info *mtd, * Identify the partitions */ for (idx = off = 0; off < mtd->size; off += mtd->erasesize) { - struct image_info_struct iis; + struct image_info_v1 iis; u_int iis_ptr, img_ptr; /* Read the footer. */ - ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask); + ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask); if (ret < 0) break; if (ret == 0) continue; /* Read the image info block */ - ret = afs_read_iis(mtd, &iis, iis_ptr); + ret = afs_read_iis_v1(mtd, &iis, iis_ptr); if (ret < 0) break; if (ret == 0) -- GitLab From 8cf980185d2bf672a5c1d03935f1f165836bb4b0 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 15 Oct 2015 15:08:45 +0200 Subject: [PATCH 0022/2855] mtd: enable AFS selection for ARM64 ARM use their special partitions also on the ARM64 architecture reference designs, so enable this for ARM64. Cc: Ryan Harkin Cc: Liviu Dudau Signed-off-by: Linus Walleij Signed-off-by: Brian Norris --- drivers/mtd/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index a03ad2951c7b4..42cc953309f1f 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -112,7 +112,7 @@ config MTD_CMDLINE_PARTS config MTD_AFS_PARTS tristate "ARM Firmware Suite partition parsing" - depends on ARM + depends on (ARM || ARM64) ---help--- The ARM Firmware Suite allows the user to divide flash devices into multiple 'images'. Each such image has a header containing its name -- GitLab From 9498440fff21649cabe529f1d9d4e3bc668fc125 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 15 Oct 2015 15:08:46 +0200 Subject: [PATCH 0023/2855] mtd: afs: break out v1 footer magic to a define Break out the magic number to a #defined constant. Cc: Ryan Harkin Cc: Liviu Dudau Signed-off-by: Linus Walleij Signed-off-by: Brian Norris --- drivers/mtd/afs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c index 9af00528586f7..d09280ae12bd9 100644 --- a/drivers/mtd/afs.c +++ b/drivers/mtd/afs.c @@ -34,6 +34,8 @@ #include #include +#define AFSV1_FOOTER_MAGIC 0xA0FFFF9F + struct footer_v1 { u32 image_info_base; /* Address of first word of ImageFooter */ u32 image_start; /* Start of area reserved by this footer */ @@ -90,7 +92,7 @@ afs_read_footer_v1(struct mtd_info *mtd, u_int *img_start, u_int *iis_start, /* * Does it contain the magic number? */ - if (fs.signature != 0xa0ffff9f) + if (fs.signature != AFSV1_FOOTER_MAGIC) ret = 0; /* -- GitLab From d2fd05bb6769d53ab98a11b080b3fb889276049d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 15 Oct 2015 15:08:47 +0200 Subject: [PATCH 0024/2855] mtd: afs: refactor v1 partition parsing Return immediately if we are not finding a valid v1 partition in afs_read_footer_v1(), invert scanning logic so we continue to read image information on v1 if we found a footer. This is needed for the logic we introduce to parse v2 footers. Cc: Ryan Harkin Cc: Liviu Dudau Signed-off-by: Linus Walleij Signed-off-by: Brian Norris --- drivers/mtd/afs.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c index d09280ae12bd9..a1eea50ce1800 100644 --- a/drivers/mtd/afs.c +++ b/drivers/mtd/afs.c @@ -87,25 +87,23 @@ afs_read_footer_v1(struct mtd_info *mtd, u_int *img_start, u_int *iis_start, return ret; } - ret = 1; - /* * Does it contain the magic number? */ if (fs.signature != AFSV1_FOOTER_MAGIC) - ret = 0; + return 0; /* * Check the checksum. */ if (word_sum(&fs, sizeof(fs) / sizeof(u32)) != 0xffffffff) - ret = 0; + return 0; /* * Don't touch the SIB. */ if (fs.type == 2) - ret = 0; + return 0; *iis_start = fs.image_info_base & mask; *img_start = fs.image_start & mask; @@ -115,16 +113,16 @@ afs_read_footer_v1(struct mtd_info *mtd, u_int *img_start, u_int *iis_start, * be located after the footer structure. */ if (*iis_start >= ptr) - ret = 0; + return 0; /* * Check the start of this image. The image * data can not be located after this block. */ if (*img_start > off) - ret = 0; + return 0; - return ret; + return 1; } static int @@ -190,18 +188,17 @@ static int parse_afs_partitions(struct mtd_info *mtd, ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask); if (ret < 0) break; - if (ret == 0) - continue; - - ret = afs_read_iis_v1(mtd, &iis, iis_ptr); - if (ret < 0) - break; - if (ret == 0) - continue; - - sz += sizeof(struct mtd_partition); - sz += strlen(iis.name) + 1; - idx += 1; + if (ret) { + ret = afs_read_iis_v1(mtd, &iis, iis_ptr); + if (ret < 0) + break; + if (ret == 0) + continue; + + sz += sizeof(struct mtd_partition); + sz += strlen(iis.name) + 1; + idx += 1; + } } if (!sz) -- GitLab From bf9c37cb627a3f690e246d9326a4a94913771bbf Mon Sep 17 00:00:00 2001 From: Bayi Cheng Date: Fri, 6 Nov 2015 23:48:07 +0800 Subject: [PATCH 0025/2855] doc: dt: mtd: add documentation for Mediatek spi-nor controller Add device tree binding documentation for serial flash with Mediatek serial flash controller Signed-off-by: Bayi Cheng Acked-by: Rob Herring [Brian: fixed up language] Signed-off-by: Brian Norris --- .../devicetree/bindings/mtd/mtk-quadspi.txt | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Documentation/devicetree/bindings/mtd/mtk-quadspi.txt diff --git a/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt b/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt new file mode 100644 index 0000000000000..fb314f09861b8 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt @@ -0,0 +1,41 @@ +* Serial NOR flash controller for MTK MT81xx (and similar) + +Required properties: +- compatible: should be "mediatek,mt8173-nor"; +- reg: physical base address and length of the controller's register +- clocks: the phandle of the clocks needed by the nor controller +- clock-names: the names of the clocks + the clocks should be named "spi" and "sf". "spi" is used for spi bus, + and "sf" is used for controller, these are the clocks witch + hardware needs to enabling nor flash and nor flash controller. + See Documentation/devicetree/bindings/clock/clock-bindings.txt for details. +- #address-cells: should be <1> +- #size-cells: should be <0> + +The SPI flash must be a child of the nor_flash node and must have a +compatible property. Also see jedec,spi-nor.txt. + +Required properties: +- compatible: May include a device-specific string consisting of the manufacturer + and name of the chip. Must also include "jedec,spi-nor" for any + SPI NOR flash that can be identified by the JEDEC READ ID opcode (0x9F). +- reg : Chip-Select number + +Example: + +nor_flash: spi@1100d000 { + compatible = "mediatek,mt8173-nor"; + reg = <0 0x1100d000 0 0xe0>; + clocks = <&pericfg CLK_PERI_SPI>, + <&topckgen CLK_TOP_SPINFI_IFR_SEL>; + clock-names = "spi", "sf"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + }; +}; + -- GitLab From 28b8b26b308e656edfa9467867d5f79212da2ec3 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 30 Oct 2015 20:33:20 -0700 Subject: [PATCH 0026/2855] mtd: add get/set of_node/flash_node helpers We are going to begin using the mtd->dev.of_node field for MTD device nodes, so let's add helpers for it. Also, we'll be making some conversions on spi_nor (and nand_chip eventually) too, so get that ready with their own helpers. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- include/linux/mtd/mtd.h | 11 +++++++++++ include/linux/mtd/nand.h | 11 +++++++++++ include/linux/mtd/spi-nor.h | 11 +++++++++++ 3 files changed, 33 insertions(+) diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index f17fa75809aa1..cc84923011c06 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -254,6 +254,17 @@ struct mtd_info { int usecount; }; +static inline void mtd_set_of_node(struct mtd_info *mtd, + struct device_node *np) +{ + mtd->dev.of_node = np; +} + +static inline struct device_node *mtd_get_of_node(struct mtd_info *mtd) +{ + return mtd->dev.of_node; +} + int mtd_erase(struct mtd_info *mtd, struct erase_info *instr); int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys); diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 5a9d1d4c2487f..4f7c9b97982f6 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -719,6 +719,17 @@ struct nand_chip { void *priv; }; +static inline void nand_set_flash_node(struct nand_chip *chip, + struct device_node *np) +{ + chip->flash_node = np; +} + +static inline struct device_node *nand_get_flash_node(struct nand_chip *chip) +{ + return chip->flash_node; +} + /* * NAND Flash Manufacturer ID Codes */ diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index c8723b62c4cd2..6d991df8f9863 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -185,6 +185,17 @@ struct spi_nor { void *priv; }; +static inline void spi_nor_set_flash_node(struct spi_nor *nor, + struct device_node *np) +{ + nor->flash_node = np; +} + +static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor) +{ + return nor->flash_node; +} + /** * spi_nor_scan() - scan the SPI NOR * @nor: the spi_nor structure -- GitLab From 3b6521eab0386a4854d47b1a01947d7dc46ec98d Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 30 Oct 2015 20:33:21 -0700 Subject: [PATCH 0027/2855] mtd: ofpart: grab device tree node directly from master device node It seems more logical to use a device node directly associated with the MTD master device (i.e., mtd->dev.of_node field) rather than requiring auxiliary partition parser information to be passed in by the driver in a separate struct. This patch supports the mtd->dev.of_node field and deprecates the parser data 'of_node' field Driver conversions may now follow. Additional side benefit to assigning mtd->dev.of_node rather than using parser data: the driver core will automatically create a device -> node symlink for us. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- drivers/mtd/ofpart.c | 18 ++++++++++-------- include/linux/mtd/partitions.h | 4 +++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index 669c3452f278f..7bf996a4cf5eb 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c @@ -37,10 +37,11 @@ static int parse_ofpart_partitions(struct mtd_info *master, bool dedicated = true; - if (!data) - return 0; - - mtd_node = data->of_node; + /* + * of_node can be provided through auxiliary parser data or (preferred) + * by assigning the master device node + */ + mtd_node = data && data->of_node ? data->of_node : mtd_get_of_node(master); if (!mtd_node) return 0; @@ -149,10 +150,11 @@ static int parse_ofoldpart_partitions(struct mtd_info *master, } *part; const char *names; - if (!data) - return 0; - - dp = data->of_node; + /* + * of_node can be provided through auxiliary parser data or (preferred) + * by assigning the master device node + */ + dp = data && data->of_node ? data->of_node : mtd_get_of_node(master); if (!dp) return 0; diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index 6a35e6de5da17..e742f34b67ebb 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -56,7 +56,9 @@ struct device_node; /** * struct mtd_part_parser_data - used to pass data to MTD partition parsers. * @origin: for RedBoot, start address of MTD device - * @of_node: for OF parsers, device node containing partitioning information + * @of_node: for OF parsers, device node containing partitioning information. + * This field is deprecated, as the device node should simply be + * assigned to the master struct device. */ struct mtd_part_parser_data { unsigned long origin; -- GitLab From 3e63b26bdd4069c3df2cd7ce7217a21d06801b41 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 30 Oct 2015 20:33:22 -0700 Subject: [PATCH 0028/2855] mtd: {nand,spi-nor}: assign MTD of_node We should pass along our flash DT node to the MTD layer, so it can set up ofpart for us. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- drivers/mtd/nand/nand_base.c | 3 +++ drivers/mtd/spi-nor/spi-nor.c | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index cc74142938b0a..939ab3d5acc2b 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3990,6 +3990,9 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, int ret; if (chip->flash_node) { + /* MTD can automatically handle DT partitions, etc. */ + mtd_set_of_node(mtd, chip->flash_node); + ret = nand_dt_init(mtd, chip, chip->flash_node); if (ret) return ret; diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 49883905a434b..1d3107ccee616 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -1258,6 +1258,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) mtd->flags |= MTD_NO_ERASE; mtd->dev.parent = dev; + mtd_set_of_node(mtd, np); nor->page_size = info->page_size; mtd->writebufsize = nor->page_size; -- GitLab From 6375219951a66047805ed977b674615d152001ee Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 30 Oct 2015 20:33:23 -0700 Subject: [PATCH 0029/2855] mtd: nand: convert to nand_set_flash_node() Used semantic patch with 'make coccicheck MODE=patch COCCI=script.cocci': ---8<---- virtual patch @@ struct nand_chip *c; struct device_node *d; @@ -(c)->flash_node = (d) +nand_set_flash_node(c, d) ---8<---- Signed-off-by: Brian Norris Reviewed-by: Marek Vasut Reviewed-by: Boris Brezillon --- drivers/mtd/nand/brcmnand/brcmnand.c | 2 +- drivers/mtd/nand/fsmc_nand.c | 2 +- drivers/mtd/nand/sunxi_nand.c | 2 +- drivers/mtd/nand/vf610_nfc.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index 12c6190c6e338..7bd4102fde421 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -1925,7 +1925,7 @@ static int brcmnand_init_cs(struct brcmnand_host *host) mtd = &host->mtd; chip = &host->chip; - chip->flash_node = dn; + nand_set_flash_node(chip, dn); chip->priv = host; mtd->priv = chip; mtd->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "brcmnand.%d", diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 07af3dc7a4d2d..6f9e422e947e0 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -1033,7 +1033,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) nand->options = pdata->options; nand->select_chip = fsmc_select_chip; nand->badblockbits = 7; - nand->flash_node = np; + nand_set_flash_node(nand, np); if (pdata->width == FSMC_NAND_BW16) nand->options |= NAND_BUSWIDTH_16; diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index 824711845c44c..0775ae4cf676e 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c @@ -1330,7 +1330,7 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc, * in the DT. */ nand->ecc.mode = NAND_ECC_HW; - nand->flash_node = np; + nand_set_flash_node(nand, np); nand->select_chip = sunxi_nfc_select_chip; nand->cmd_ctrl = sunxi_nfc_cmd_ctrl; nand->read_buf = sunxi_nfc_read_buf; diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c index 8805d63255797..7b952abf47221 100644 --- a/drivers/mtd/nand/vf610_nfc.c +++ b/drivers/mtd/nand/vf610_nfc.c @@ -714,7 +714,7 @@ static int vf610_nfc_probe(struct platform_device *pdev) goto error; } - chip->flash_node = child; + nand_set_flash_node(chip, child); } } -- GitLab From 9c7d787508be6d68a6ec66de3c3466b24e820c71 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 30 Oct 2015 20:33:24 -0700 Subject: [PATCH 0030/2855] mtd: spi-nor: convert to spi_nor_{get, set}_flash_node() Used semantic patch with 'make coccicheck MODE=patch COCCI=script.cocci': ---8<---- virtual patch @@ struct spi_nor b; struct spi_nor *c; expression d; @@ ( -(b).flash_node = (d) +spi_nor_set_flash_node(&b, d) | -(c)->flash_node = (d) +spi_nor_set_flash_node(c, d) ) ---8<---- And a manual conversion for the one use of spi_nor_get_flash_node(). Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- drivers/mtd/devices/m25p80.c | 2 +- drivers/mtd/spi-nor/fsl-quadspi.c | 2 +- drivers/mtd/spi-nor/nxp-spifi.c | 2 +- drivers/mtd/spi-nor/spi-nor.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 4b5d7a4655fd4..556b4554007f3 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -199,7 +199,7 @@ static int m25p_probe(struct spi_device *spi) nor->read_reg = m25p80_read_reg; nor->dev = &spi->dev; - nor->flash_node = spi->dev.of_node; + spi_nor_set_flash_node(nor, spi->dev.of_node); nor->priv = flash; spi_set_drvdata(spi, flash); diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c index 7b10ed413983a..8f4d9204d2b2c 100644 --- a/drivers/mtd/spi-nor/fsl-quadspi.c +++ b/drivers/mtd/spi-nor/fsl-quadspi.c @@ -1013,7 +1013,7 @@ static int fsl_qspi_probe(struct platform_device *pdev) mtd = &nor->mtd; nor->dev = dev; - nor->flash_node = np; + spi_nor_set_flash_node(nor, np); nor->priv = q; /* fill the hooks */ diff --git a/drivers/mtd/spi-nor/nxp-spifi.c b/drivers/mtd/spi-nor/nxp-spifi.c index 9e82098ae644d..4524b28869464 100644 --- a/drivers/mtd/spi-nor/nxp-spifi.c +++ b/drivers/mtd/spi-nor/nxp-spifi.c @@ -330,7 +330,7 @@ static int nxp_spifi_setup_flash(struct nxp_spifi *spifi, writel(ctrl, spifi->io_base + SPIFI_CTRL); spifi->nor.dev = spifi->dev; - spifi->nor.flash_node = np; + spi_nor_set_flash_node(&spifi->nor, np); spifi->nor.priv = spifi; spifi->nor.read = nxp_spifi_read; spifi->nor.write = nxp_spifi_write; diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 1d3107ccee616..924d455dadb55 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -1151,7 +1151,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) const struct flash_info *info = NULL; struct device *dev = nor->dev; struct mtd_info *mtd = &nor->mtd; - struct device_node *np = nor->flash_node; + struct device_node *np = spi_nor_get_flash_node(nor); int ret; int i; -- GitLab From a61ae81a1907af1987ad4c77300508327bc48b23 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 30 Oct 2015 20:33:25 -0700 Subject: [PATCH 0031/2855] mtd: nand: drop unnecessary partition parser data All of these drivers set up a parser data struct just to communicate DT partition data. This field has been deprecated and is instead supported by telling nand_scan_ident() about the 'flash_node'. This patch: * sets chip->flash_node for those drivers that didn't already (but used OF partitioning) * drops the parser data * switches to the simpler mtd_device_register() where possible, now that we've eliminated one of the auxiliary parameters Now that we've assigned chip->flash_node for these drivers, we can probably rely on nand_dt_init() to do more of the DT parsing for us, but for now, I don't want to fiddle with each of these drivers. The parsing is done in duplicate for now on some drivers. I don't think this should break things. (Famous last words.) (Rolled in some changes by Boris Brezillon) Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- drivers/mtd/nand/atmel_nand.c | 7 +++---- drivers/mtd/nand/brcmnand/brcmnand.c | 3 +-- drivers/mtd/nand/davinci_nand.c | 10 +++------- drivers/mtd/nand/fsl_elbc_nand.c | 5 ++--- drivers/mtd/nand/fsl_ifc_nand.c | 5 ++--- drivers/mtd/nand/fsl_upm.c | 5 ++--- drivers/mtd/nand/fsmc_nand.c | 7 +++---- drivers/mtd/nand/gpio.c | 8 +++----- drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 5 ++--- drivers/mtd/nand/hisi504_nand.c | 5 ++--- drivers/mtd/nand/lpc32xx_mlc.c | 7 +++---- drivers/mtd/nand/lpc32xx_slc.c | 7 +++---- drivers/mtd/nand/mpc5121_nfc.c | 5 ++--- drivers/mtd/nand/mxc_nand.c | 5 ++--- drivers/mtd/nand/ndfc.c | 5 ++--- drivers/mtd/nand/omap2.c | 6 ++---- drivers/mtd/nand/orion_nand.c | 6 ++---- drivers/mtd/nand/plat_nand.c | 5 ++--- drivers/mtd/nand/pxa3xx_nand.c | 10 +++++----- drivers/mtd/nand/sh_flctl.c | 6 ++---- drivers/mtd/nand/socrates_nand.c | 5 ++--- drivers/mtd/nand/sunxi_nand.c | 4 +--- drivers/mtd/nand/vf610_nfc.c | 6 +----- drivers/staging/mt29f_spinand/mt29f_spinand.c | 5 ++--- 24 files changed, 54 insertions(+), 88 deletions(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 583cdd9bb9710..6ecc1c1ab4375 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -2093,7 +2093,6 @@ static int atmel_nand_probe(struct platform_device *pdev) struct mtd_info *mtd; struct nand_chip *nand_chip; struct resource *mem; - struct mtd_part_parser_data ppdata = {}; int res, irq; /* Allocate memory for the device structure (and zero it) */ @@ -2117,6 +2116,7 @@ static int atmel_nand_probe(struct platform_device *pdev) nand_chip = &host->nand_chip; host->dev = &pdev->dev; if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { + nand_set_flash_node(nand_chip, pdev->dev.of_node); /* Only when CONFIG_OF is enabled of_node can be parsed */ res = atmel_of_init_port(host, pdev->dev.of_node); if (res) @@ -2259,9 +2259,8 @@ static int atmel_nand_probe(struct platform_device *pdev) } mtd->name = "atmel_nand"; - ppdata.of_node = pdev->dev.of_node; - res = mtd_device_parse_register(mtd, NULL, &ppdata, - host->board.parts, host->board.num_parts); + res = mtd_device_register(mtd, host->board.parts, + host->board.num_parts); if (!res) return res; diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index 7bd4102fde421..a37659de025c2 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -1914,7 +1914,6 @@ static int brcmnand_init_cs(struct brcmnand_host *host) struct nand_chip *chip; int ret; u16 cfg_offs; - struct mtd_part_parser_data ppdata = { .of_node = dn }; ret = of_property_read_u32(dn, "reg", &host->cs); if (ret) { @@ -1993,7 +1992,7 @@ static int brcmnand_init_cs(struct brcmnand_host *host) if (nand_scan_tail(mtd)) return -ENXIO; - return mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); + return mtd_device_register(mtd, NULL, 0); } static void brcmnand_save_restore_cs_config(struct brcmnand_host *host, diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index c72313d66cf6a..8e351af31e530 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -684,6 +684,7 @@ static int nand_davinci_probe(struct platform_device *pdev) info->mtd.priv = &info->chip; info->mtd.dev.parent = &pdev->dev; + nand_set_flash_node(&info->chip, pdev->dev.of_node); info->chip.IO_ADDR_R = vaddr; info->chip.IO_ADDR_W = vaddr; @@ -839,13 +840,8 @@ syndrome_done: if (pdata->parts) ret = mtd_device_parse_register(&info->mtd, NULL, NULL, pdata->parts, pdata->nr_parts); - else { - struct mtd_part_parser_data ppdata; - - ppdata.of_node = pdev->dev.of_node; - ret = mtd_device_parse_register(&info->mtd, NULL, &ppdata, - NULL, 0); - } + else + ret = mtd_device_register(&info->mtd, NULL, 0); if (ret < 0) goto err; diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index dcb1f7f4873f3..bd6d49376382d 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -748,6 +748,7 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) /* Fill in fsl_elbc_mtd structure */ priv->mtd.priv = chip; priv->mtd.dev.parent = priv->dev; + nand_set_flash_node(chip, priv->dev->of_node); /* set timeout to maximum */ priv->fmr = 15 << FMR_CWTO_SHIFT; @@ -823,9 +824,7 @@ static int fsl_elbc_nand_probe(struct platform_device *pdev) int bank; struct device *dev; struct device_node *node = pdev->dev.of_node; - struct mtd_part_parser_data ppdata; - ppdata.of_node = pdev->dev.of_node; if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs) return -ENODEV; lbc = fsl_lbc_ctrl_dev->regs; @@ -911,7 +910,7 @@ static int fsl_elbc_nand_probe(struct platform_device *pdev) /* First look for RedBoot table or partitions on the command * line, these take precedence over device tree information */ - mtd_device_parse_register(&priv->mtd, part_probe_types, &ppdata, + mtd_device_parse_register(&priv->mtd, part_probe_types, NULL, NULL, 0); printk(KERN_INFO "eLBC NAND device at 0x%llx, bank %d\n", diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 7f4ac8c190016..f2608315774aa 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -883,6 +883,7 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv) /* Fill in fsl_ifc_mtd structure */ priv->mtd.priv = chip; priv->mtd.dev.parent = priv->dev; + nand_set_flash_node(chip, priv->dev->of_node); /* fill in nand_chip structure */ /* set up function call table */ @@ -1030,9 +1031,7 @@ static int fsl_ifc_nand_probe(struct platform_device *dev) int ret; int bank; struct device_node *node = dev->dev.of_node; - struct mtd_part_parser_data ppdata; - ppdata.of_node = dev->dev.of_node; if (!fsl_ifc_ctrl_dev || !fsl_ifc_ctrl_dev->regs) return -ENODEV; ifc = fsl_ifc_ctrl_dev->regs; @@ -1128,7 +1127,7 @@ static int fsl_ifc_nand_probe(struct platform_device *dev) /* First look for RedBoot table or partitions on the command * line, these take precedence over device tree information */ - mtd_device_parse_register(&priv->mtd, part_probe_types, &ppdata, + mtd_device_parse_register(&priv->mtd, part_probe_types, NULL, NULL, 0); dev_info(priv->dev, "IFC NAND device at 0x%llx, bank %d\n", diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index d326369980c48..b3f4a01621c1d 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -159,7 +159,6 @@ static int fun_chip_init(struct fsl_upm_nand *fun, { int ret; struct device_node *flash_np; - struct mtd_part_parser_data ppdata; fun->chip.IO_ADDR_R = fun->io_base; fun->chip.IO_ADDR_W = fun->io_base; @@ -182,6 +181,7 @@ static int fun_chip_init(struct fsl_upm_nand *fun, if (!flash_np) return -ENODEV; + nand_set_flash_node(&fun->chip, flash_np); fun->mtd.name = kasprintf(GFP_KERNEL, "0x%llx.%s", (u64)io_res->start, flash_np->name); if (!fun->mtd.name) { @@ -193,8 +193,7 @@ static int fun_chip_init(struct fsl_upm_nand *fun, if (ret) goto err; - ppdata.of_node = flash_np; - ret = mtd_device_parse_register(&fun->mtd, NULL, &ppdata, NULL, 0); + ret = mtd_device_register(&fun->mtd, NULL, 0); err: of_node_put(flash_np); if (ret) diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 6f9e422e947e0..59fc6d0c39108 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -926,7 +926,6 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) { struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); struct device_node __maybe_unused *np = pdev->dev.of_node; - struct mtd_part_parser_data ppdata = {}; struct fsmc_nand_data *host; struct mtd_info *mtd; struct nand_chip *nand; @@ -1016,6 +1015,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) nand = &host->nand; mtd->priv = nand; nand->priv = host; + nand_set_flash_node(nand, np); host->mtd.dev.parent = &pdev->dev; nand->IO_ADDR_R = host->data_va; @@ -1175,9 +1175,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) * Check for partition info passed */ host->mtd.name = "nand"; - ppdata.of_node = np; - ret = mtd_device_parse_register(&host->mtd, NULL, &ppdata, - host->partitions, host->nr_partitions); + ret = mtd_device_register(&host->mtd, host->partitions, + host->nr_partitions); if (ret) goto err_probe; diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c index 9ab97f934c375..d57a07a597bec 100644 --- a/drivers/mtd/nand/gpio.c +++ b/drivers/mtd/nand/gpio.c @@ -209,7 +209,6 @@ static int gpio_nand_probe(struct platform_device *pdev) struct gpiomtd *gpiomtd; struct nand_chip *chip; struct resource *res; - struct mtd_part_parser_data ppdata = {}; int ret = 0; if (!pdev->dev.of_node && !dev_get_platdata(&pdev->dev)) @@ -268,6 +267,7 @@ static int gpio_nand_probe(struct platform_device *pdev) chip->dev_ready = gpio_nand_devready; } + nand_set_flash_node(chip, pdev->dev.of_node); chip->IO_ADDR_W = chip->IO_ADDR_R; chip->ecc.mode = NAND_ECC_SOFT; chip->options = gpiomtd->plat.options; @@ -291,10 +291,8 @@ static int gpio_nand_probe(struct platform_device *pdev) gpiomtd->plat.adjust_parts(&gpiomtd->plat, gpiomtd->mtd_info.size); - ppdata.of_node = pdev->dev.of_node; - ret = mtd_device_parse_register(&gpiomtd->mtd_info, NULL, &ppdata, - gpiomtd->plat.parts, - gpiomtd->plat.num_parts); + ret = mtd_device_register(&gpiomtd->mtd_info, gpiomtd->plat.parts, + gpiomtd->plat.num_parts); if (!ret) return 0; diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 2064adac1d177..5a9b6966e97c6 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -1888,7 +1888,6 @@ static int gpmi_nand_init(struct gpmi_nand_data *this) { struct mtd_info *mtd = &this->mtd; struct nand_chip *chip = &this->nand; - struct mtd_part_parser_data ppdata = {}; int ret; /* init current chip */ @@ -1901,6 +1900,7 @@ static int gpmi_nand_init(struct gpmi_nand_data *this) /* init the nand_chip{}, we don't support a 16-bit NAND Flash bus. */ chip->priv = this; + nand_set_flash_node(chip, this->pdev->dev.of_node); chip->select_chip = gpmi_select_chip; chip->cmd_ctrl = gpmi_cmd_ctrl; chip->dev_ready = gpmi_dev_ready; @@ -1954,8 +1954,7 @@ static int gpmi_nand_init(struct gpmi_nand_data *this) if (ret) goto err_out; - ppdata.of_node = this->pdev->dev.of_node; - ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); + ret = mtd_device_register(mtd, NULL, 0); if (ret) goto err_out; return 0; diff --git a/drivers/mtd/nand/hisi504_nand.c b/drivers/mtd/nand/hisi504_nand.c index 0cb2e886937d6..0aad4acab9d61 100644 --- a/drivers/mtd/nand/hisi504_nand.c +++ b/drivers/mtd/nand/hisi504_nand.c @@ -704,7 +704,6 @@ static int hisi_nfc_probe(struct platform_device *pdev) struct mtd_info *mtd; struct resource *res; struct device_node *np = dev->of_node; - struct mtd_part_parser_data ppdata; host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); if (!host) @@ -742,6 +741,7 @@ static int hisi_nfc_probe(struct platform_device *pdev) mtd->dev.parent = &pdev->dev; chip->priv = host; + nand_set_flash_node(chip, np); chip->cmdfunc = hisi_nfc_cmdfunc; chip->select_chip = hisi_nfc_select_chip; chip->read_byte = hisi_nfc_read_byte; @@ -805,8 +805,7 @@ static int hisi_nfc_probe(struct platform_device *pdev) goto err_res; } - ppdata.of_node = np; - ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); + ret = mtd_device_register(mtd, NULL, 0); if (ret) { dev_err(dev, "Err MTD partition=%d\n", ret); goto err_mtd; diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c index 3475109784840..57c4b712cf1a3 100644 --- a/drivers/mtd/nand/lpc32xx_mlc.c +++ b/drivers/mtd/nand/lpc32xx_mlc.c @@ -647,7 +647,6 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) struct nand_chip *nand_chip; struct resource *rc; int res; - struct mtd_part_parser_data ppdata = {}; /* Allocate memory for the device structure (and zero it) */ host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); @@ -682,6 +681,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) host->pdata = dev_get_platdata(&pdev->dev); nand_chip->priv = host; /* link the private data structures */ + nand_set_flash_node(nand_chip, pdev->dev.of_node); mtd->priv = nand_chip; mtd->dev.parent = &pdev->dev; @@ -786,9 +786,8 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) mtd->name = DRV_NAME; - ppdata.of_node = pdev->dev.of_node; - res = mtd_device_parse_register(mtd, NULL, &ppdata, host->ncfg->parts, - host->ncfg->num_parts); + res = mtd_device_register(mtd, host->ncfg->parts, + host->ncfg->num_parts); if (!res) return res; diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c index 4f3d4eb17da0d..277626e46379c 100644 --- a/drivers/mtd/nand/lpc32xx_slc.c +++ b/drivers/mtd/nand/lpc32xx_slc.c @@ -763,7 +763,6 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) struct mtd_info *mtd; struct nand_chip *chip; struct resource *rc; - struct mtd_part_parser_data ppdata = {}; int res; rc = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -803,6 +802,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) mtd = &host->mtd; chip = &host->nand_chip; chip->priv = host; + nand_set_flash_node(chip, pdev->dev.of_node); mtd->priv = chip; mtd->owner = THIS_MODULE; mtd->dev.parent = &pdev->dev; @@ -908,9 +908,8 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) } mtd->name = "nxp_lpc3220_slc"; - ppdata.of_node = pdev->dev.of_node; - res = mtd_device_parse_register(mtd, NULL, &ppdata, host->ncfg->parts, - host->ncfg->num_parts); + res = mtd_device_register(mtd, host->ncfg->parts, + host->ncfg->num_parts); if (!res) return res; diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index d6bbde4a53317..0fdfc42f75f81 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c @@ -639,7 +639,6 @@ static int mpc5121_nfc_probe(struct platform_device *op) int resettime = 0; int retval = 0; int rev, len; - struct mtd_part_parser_data ppdata; /* * Check SoC revision. This driver supports only NFC @@ -661,6 +660,7 @@ static int mpc5121_nfc_probe(struct platform_device *op) mtd->priv = chip; mtd->dev.parent = dev; chip->priv = prv; + nand_set_flash_node(chip, dn); prv->dev = dev; /* Read NFC configuration from Reset Config Word */ @@ -703,7 +703,6 @@ static int mpc5121_nfc_probe(struct platform_device *op) } mtd->name = "MPC5121 NAND"; - ppdata.of_node = dn; chip->dev_ready = mpc5121_nfc_dev_ready; chip->cmdfunc = mpc5121_nfc_command; chip->read_byte = mpc5121_nfc_read_byte; @@ -815,7 +814,7 @@ static int mpc5121_nfc_probe(struct platform_device *op) dev_set_drvdata(dev, mtd); /* Register device in MTD */ - retval = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); + retval = mtd_device_register(mtd, NULL, 0); if (retval) { dev_err(dev, "Error adding MTD device!\n"); goto error; diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 136e73a3e07e5..7922d318ebb8e 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -1524,6 +1524,7 @@ static int mxcnd_probe(struct platform_device *pdev) this->chip_delay = 5; this->priv = host; + nand_set_flash_node(this, pdev->dev.of_node), this->dev_ready = mxc_nand_dev_ready; this->cmdfunc = mxc_nand_command; this->read_byte = mxc_nand_read_byte; @@ -1683,9 +1684,7 @@ static int mxcnd_probe(struct platform_device *pdev) /* Register the partitions */ mtd_device_parse_register(mtd, part_probes, - &(struct mtd_part_parser_data){ - .of_node = pdev->dev.of_node, - }, + NULL, host->pdata.parts, host->pdata.nr_parts); diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 4f0d62f9d22c1..69658584061b4 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -147,7 +147,6 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, { struct device_node *flash_np; struct nand_chip *chip = &ndfc->chip; - struct mtd_part_parser_data ppdata; int ret; chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA; @@ -174,8 +173,8 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, flash_np = of_get_next_child(node, NULL); if (!flash_np) return -ENODEV; + nand_set_flash_node(chip, flash_np); - ppdata.of_node = flash_np; ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s", dev_name(&ndfc->ofdev->dev), flash_np->name); if (!ndfc->mtd.name) { @@ -187,7 +186,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, if (ret) goto err; - ret = mtd_device_parse_register(&ndfc->mtd, NULL, &ppdata, NULL, 0); + ret = mtd_device_register(&ndfc->mtd, NULL, 0); err: of_node_put(flash_np); diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 93f664cd1c906..e307576f300b5 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -1663,7 +1663,6 @@ static int omap_nand_probe(struct platform_device *pdev) unsigned sig; unsigned oob_index; struct resource *res; - struct mtd_part_parser_data ppdata = {}; pdata = dev_get_platdata(&pdev->dev); if (pdata == NULL) { @@ -1688,6 +1687,7 @@ static int omap_nand_probe(struct platform_device *pdev) mtd->dev.parent = &pdev->dev; nand_chip = &info->nand; nand_chip->ecc.priv = NULL; + nand_set_flash_node(nand_chip, pdata->of_node); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); nand_chip->IO_ADDR_R = devm_ioremap_resource(&pdev->dev, res); @@ -2037,9 +2037,7 @@ scan_tail: goto return_error; } - ppdata.of_node = pdata->of_node; - mtd_device_parse_register(mtd, NULL, &ppdata, pdata->parts, - pdata->nr_parts); + mtd_device_register(mtd, pdata->parts, pdata->nr_parts); platform_set_drvdata(pdev, mtd); diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index ee83749fb1d35..5c214161244a0 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -76,7 +76,6 @@ static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static int __init orion_nand_probe(struct platform_device *pdev) { struct mtd_info *mtd; - struct mtd_part_parser_data ppdata = {}; struct nand_chip *nc; struct orion_nand_data *board; struct resource *res; @@ -127,6 +126,7 @@ static int __init orion_nand_probe(struct platform_device *pdev) mtd->dev.parent = &pdev->dev; nc->priv = board; + nand_set_flash_node(nc, pdev->dev.of_node); nc->IO_ADDR_R = nc->IO_ADDR_W = io_base; nc->cmd_ctrl = orion_nand_cmd_ctrl; nc->read_buf = orion_nand_read_buf; @@ -161,9 +161,7 @@ static int __init orion_nand_probe(struct platform_device *pdev) } mtd->name = "orion_nand"; - ppdata.of_node = pdev->dev.of_node; - ret = mtd_device_parse_register(mtd, NULL, &ppdata, - board->parts, board->nr_parts); + ret = mtd_device_register(mtd, board->parts, board->nr_parts); if (ret) { nand_release(mtd); goto no_dev; diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index 65b9dbbe6d6a4..06ac6c64dcd53 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c @@ -30,7 +30,6 @@ struct plat_nand_data { static int plat_nand_probe(struct platform_device *pdev) { struct platform_nand_data *pdata = dev_get_platdata(&pdev->dev); - struct mtd_part_parser_data ppdata; struct plat_nand_data *data; struct resource *res; const char **part_types; @@ -58,6 +57,7 @@ static int plat_nand_probe(struct platform_device *pdev) return PTR_ERR(data->io_base); data->chip.priv = &data; + nand_set_flash_node(&data->chip, pdev->dev.of_node); data->mtd.priv = &data->chip; data->mtd.dev.parent = &pdev->dev; @@ -94,8 +94,7 @@ static int plat_nand_probe(struct platform_device *pdev) part_types = pdata->chip.part_probe_types; - ppdata.of_node = pdev->dev.of_node; - err = mtd_device_parse_register(&data->mtd, part_types, &ppdata, + err = mtd_device_parse_register(&data->mtd, part_types, NULL, pdata->chip.partitions, pdata->chip.nr_partitions); diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index e453ae9a17fa3..37df51df422e9 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -1697,6 +1697,7 @@ KEEP_CONFIG: static int alloc_nand_resource(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; struct pxa3xx_nand_platform_data *pdata; struct pxa3xx_nand_info *info; struct pxa3xx_nand_host *host; @@ -1725,6 +1726,8 @@ static int alloc_nand_resource(struct platform_device *pdev) host->info_data = info; mtd->priv = host; mtd->dev.parent = &pdev->dev; + /* FIXME: all chips use the same device tree partitions */ + nand_set_flash_node(chip, np); chip->ecc.read_page = pxa3xx_nand_read_page_hwecc; chip->ecc.write_page = pxa3xx_nand_write_page_hwecc; @@ -1886,7 +1889,6 @@ static int pxa3xx_nand_probe_dt(struct platform_device *pdev) static int pxa3xx_nand_probe(struct platform_device *pdev) { struct pxa3xx_nand_platform_data *pdata; - struct mtd_part_parser_data ppdata = {}; struct pxa3xx_nand_info *info; int ret, cs, probe_success, dma_available; @@ -1933,10 +1935,8 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) continue; } - ppdata.of_node = pdev->dev.of_node; - ret = mtd_device_parse_register(mtd, NULL, - &ppdata, pdata->parts[cs], - pdata->nr_parts[cs]); + ret = mtd_device_register(mtd, pdata->parts[cs], + pdata->nr_parts[cs]); if (!ret) probe_success = 1; } diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index bcba1a924c75f..57dc52578e078 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c @@ -1086,7 +1086,6 @@ static int flctl_probe(struct platform_device *pdev) struct sh_flctl_platform_data *pdata; int ret; int irq; - struct mtd_part_parser_data ppdata = {}; flctl = devm_kzalloc(&pdev->dev, sizeof(struct sh_flctl), GFP_KERNEL); if (!flctl) @@ -1123,6 +1122,7 @@ static int flctl_probe(struct platform_device *pdev) platform_set_drvdata(pdev, flctl); flctl_mtd = &flctl->mtd; nand = &flctl->chip; + nand_set_flash_node(nand, pdev->dev.of_node); flctl_mtd->priv = nand; flctl_mtd->dev.parent = &pdev->dev; flctl->pdev = pdev; @@ -1163,9 +1163,7 @@ static int flctl_probe(struct platform_device *pdev) if (ret) goto err_chip; - ppdata.of_node = pdev->dev.of_node; - ret = mtd_device_parse_register(flctl_mtd, NULL, &ppdata, pdata->parts, - pdata->nr_parts); + ret = mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts); return 0; diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c index b94f53427f0f9..bde40433b4d9f 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/socrates_nand.c @@ -147,7 +147,6 @@ static int socrates_nand_probe(struct platform_device *ofdev) struct mtd_info *mtd; struct nand_chip *nand_chip; int res; - struct mtd_part_parser_data ppdata; /* Allocate memory for the device structure (and zero it) */ host = devm_kzalloc(&ofdev->dev, sizeof(*host), GFP_KERNEL); @@ -165,10 +164,10 @@ static int socrates_nand_probe(struct platform_device *ofdev) host->dev = &ofdev->dev; nand_chip->priv = host; /* link the private data structures */ + nand_set_flash_node(nand_chip, ofdev->dev.of_node); mtd->priv = nand_chip; mtd->name = "socrates_nand"; mtd->dev.parent = &ofdev->dev; - ppdata.of_node = ofdev->dev.of_node; /*should never be accessed directly */ nand_chip->IO_ADDR_R = (void *)0xdeadbeef; @@ -200,7 +199,7 @@ static int socrates_nand_probe(struct platform_device *ofdev) goto out; } - res = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); + res = mtd_device_register(mtd, NULL, 0); if (!res) return res; diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index 0775ae4cf676e..2ed52e466ea64 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c @@ -1232,7 +1232,6 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc, { const struct nand_sdr_timings *timings; struct sunxi_nand_chip *chip; - struct mtd_part_parser_data ppdata; struct mtd_info *mtd; struct nand_chip *nand; int nsels; @@ -1366,8 +1365,7 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc, return ret; } - ppdata.of_node = np; - ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); + ret = mtd_device_register(mtd, NULL, 0); if (ret) { dev_err(dev, "failed to register mtd device: %d\n", ret); nand_release(mtd); diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c index 7b952abf47221..b6df4c6d60ca9 100644 --- a/drivers/mtd/nand/vf610_nfc.c +++ b/drivers/mtd/nand/vf610_nfc.c @@ -811,11 +811,7 @@ static int vf610_nfc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, mtd); /* Register device in MTD */ - return mtd_device_parse_register(mtd, NULL, - &(struct mtd_part_parser_data){ - .of_node = chip->flash_node, - }, - NULL, 0); + return mtd_device_register(mtd, NULL, 0); error: of_node_put(chip->flash_node); diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c index 405b643189fd5..49807de7d91eb 100644 --- a/drivers/staging/mt29f_spinand/mt29f_spinand.c +++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c @@ -853,7 +853,6 @@ static int spinand_probe(struct spi_device *spi_nand) struct nand_chip *chip; struct spinand_info *info; struct spinand_state *state; - struct mtd_part_parser_data ppdata; info = devm_kzalloc(&spi_nand->dev, sizeof(struct spinand_info), GFP_KERNEL); @@ -897,6 +896,7 @@ static int spinand_probe(struct spi_device *spi_nand) pr_info("%s: disable ecc failed!\n", __func__); #endif + nand_set_flash_node(chip, spi_nand->dev.of_node); chip->priv = info; chip->read_buf = spinand_read_buf; chip->write_buf = spinand_write_buf; @@ -919,8 +919,7 @@ static int spinand_probe(struct spi_device *spi_nand) if (nand_scan(mtd, 1)) return -ENXIO; - ppdata.of_node = spi_nand->dev.of_node; - return mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); + return mtd_device_register(mtd, NULL, 0); } /* -- GitLab From df02c885f8697546da41665f28dde5e30ce99674 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 30 Oct 2015 20:33:26 -0700 Subject: [PATCH 0032/2855] mtd: spi-nor: drop unnecessary partition parser data Now that the SPI-NOR/MTD framework pass the 'flash_node' through to the partition parsing code, we don't have to do it ourselves. Also convert to mtd_device_register(), since we don't need the 2nd and 3rd parameters anymore. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- drivers/mtd/devices/m25p80.c | 8 ++------ drivers/mtd/spi-nor/fsl-quadspi.c | 4 +--- drivers/mtd/spi-nor/nxp-spifi.c | 4 +--- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 556b4554007f3..6dbf7832e77a3 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -175,7 +175,6 @@ static int m25p80_erase(struct spi_nor *nor, loff_t offset) */ static int m25p_probe(struct spi_device *spi) { - struct mtd_part_parser_data ppdata; struct flash_platform_data *data; struct m25p *flash; struct spi_nor *nor; @@ -227,11 +226,8 @@ static int m25p_probe(struct spi_device *spi) if (ret) return ret; - ppdata.of_node = spi->dev.of_node; - - return mtd_device_parse_register(&nor->mtd, NULL, &ppdata, - data ? data->parts : NULL, - data ? data->nr_parts : 0); + return mtd_device_register(&nor->mtd, data ? data->parts : NULL, + data ? data->nr_parts : 0); } diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c index 8f4d9204d2b2c..9e7f657af6a56 100644 --- a/drivers/mtd/spi-nor/fsl-quadspi.c +++ b/drivers/mtd/spi-nor/fsl-quadspi.c @@ -927,7 +927,6 @@ static void fsl_qspi_unprep(struct spi_nor *nor, enum spi_nor_ops ops) static int fsl_qspi_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; - struct mtd_part_parser_data ppdata; struct device *dev = &pdev->dev; struct fsl_qspi *q; struct resource *res; @@ -1038,8 +1037,7 @@ static int fsl_qspi_probe(struct platform_device *pdev) if (ret) goto mutex_failed; - ppdata.of_node = np; - ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); + ret = mtd_device_register(mtd, NULL, 0); if (ret) goto mutex_failed; diff --git a/drivers/mtd/spi-nor/nxp-spifi.c b/drivers/mtd/spi-nor/nxp-spifi.c index 4524b28869464..ae428cb0e04bb 100644 --- a/drivers/mtd/spi-nor/nxp-spifi.c +++ b/drivers/mtd/spi-nor/nxp-spifi.c @@ -271,7 +271,6 @@ static void nxp_spifi_dummy_id_read(struct spi_nor *nor) static int nxp_spifi_setup_flash(struct nxp_spifi *spifi, struct device_node *np) { - struct mtd_part_parser_data ppdata; enum read_mode flash_read; u32 ctrl, property; u16 mode = 0; @@ -361,8 +360,7 @@ static int nxp_spifi_setup_flash(struct nxp_spifi *spifi, return ret; } - ppdata.of_node = np; - ret = mtd_device_parse_register(&spifi->nor.mtd, NULL, &ppdata, NULL, 0); + ret = mtd_device_register(&spifi->nor.mtd, NULL, 0); if (ret) { dev_err(spifi->dev, "mtd device parse failed\n"); return ret; -- GitLab From 30069af7348b56eb8c5e1dda7788a531c5f24ca2 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 30 Oct 2015 20:33:27 -0700 Subject: [PATCH 0033/2855] mtd: spi-nor: drop flash_node field We can just alias to the MTD of_node. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- drivers/mtd/spi-nor/spi-nor.c | 1 - include/linux/mtd/spi-nor.h | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 924d455dadb55..12041e181630c 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -1258,7 +1258,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) mtd->flags |= MTD_NO_ERASE; mtd->dev.parent = dev; - mtd_set_of_node(mtd, np); nor->page_size = info->page_size; mtd->writebufsize = nor->page_size; diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 6d991df8f9863..955f268d159a1 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -124,7 +124,6 @@ struct mtd_info; * @mtd: point to a mtd_info structure * @lock: the lock for the read/write/erase/lock/unlock operations * @dev: point to a spi device, or a spi nor controller device. - * @flash_node: point to a device node describing this flash instance. * @page_size: the page size of the SPI NOR * @addr_width: number of address bytes * @erase_opcode: the opcode for erasing a sector @@ -155,7 +154,6 @@ struct spi_nor { struct mtd_info mtd; struct mutex lock; struct device *dev; - struct device_node *flash_node; u32 page_size; u8 addr_width; u8 erase_opcode; @@ -188,12 +186,12 @@ struct spi_nor { static inline void spi_nor_set_flash_node(struct spi_nor *nor, struct device_node *np) { - nor->flash_node = np; + mtd_set_of_node(&nor->mtd, np); } static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor) { - return nor->flash_node; + return mtd_get_of_node(&nor->mtd); } /** -- GitLab From 004b5e6031f4e9fd90d565fb213b74cd06d03718 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 30 Oct 2015 20:33:28 -0700 Subject: [PATCH 0034/2855] mtd: drop unnecessary partition parser data We should assign the MTD dev.of_node instead of the parser data field. This gets us the equivalent partition parser behavior with fewer special fields and parameter passing. Also convert several of these to mtd_device_register(), since we don't need the 2nd and 3rd parameters anymore. Signed-off-by: Brian Norris Reviewed-by: Marek Vasut Reviewed-by: Boris Brezillon --- drivers/mtd/devices/mtd_dataflash.c | 5 ++--- drivers/mtd/devices/spear_smi.c | 6 ++---- drivers/mtd/devices/st_spi_fsm.c | 5 ++--- drivers/mtd/maps/lantiq-flash.c | 5 ++--- drivers/mtd/maps/physmap_of.c | 5 ++--- drivers/mtd/onenand/omap2.c | 8 +++----- 6 files changed, 13 insertions(+), 21 deletions(-) diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 39666d552682e..0ada3ed6c23fc 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -624,7 +624,6 @@ static int add_dataflash_otp(struct spi_device *spi, char *name, int nr_pages, { struct dataflash *priv; struct mtd_info *device; - struct mtd_part_parser_data ppdata; struct flash_platform_data *pdata = dev_get_platdata(&spi->dev); char *otp_tag = ""; int err = 0; @@ -656,6 +655,7 @@ static int add_dataflash_otp(struct spi_device *spi, char *name, int nr_pages, device->priv = priv; device->dev.parent = &spi->dev; + mtd_set_of_node(device, spi->dev.of_node); if (revision >= 'c') otp_tag = otp_setup(device, revision); @@ -665,8 +665,7 @@ static int add_dataflash_otp(struct spi_device *spi, char *name, int nr_pages, pagesize, otp_tag); spi_set_drvdata(spi, priv); - ppdata.of_node = spi->dev.of_node; - err = mtd_device_parse_register(device, NULL, &ppdata, + err = mtd_device_register(device, pdata ? pdata->parts : NULL, pdata ? pdata->nr_parts : 0); diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index 64c7458344d43..dd50698765370 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -810,7 +810,6 @@ static int spear_smi_setup_banks(struct platform_device *pdev, u32 bank, struct device_node *np) { struct spear_smi *dev = platform_get_drvdata(pdev); - struct mtd_part_parser_data ppdata = {}; struct spear_smi_flash_info *flash_info; struct spear_smi_plat_data *pdata; struct spear_snor_flash *flash; @@ -855,6 +854,7 @@ static int spear_smi_setup_banks(struct platform_device *pdev, flash->mtd.name = flash_devices[flash_index].name; flash->mtd.dev.parent = &pdev->dev; + mtd_set_of_node(&flash->mtd, np); flash->mtd.type = MTD_NORFLASH; flash->mtd.writesize = 1; flash->mtd.flags = MTD_CAP_NORFLASH; @@ -881,10 +881,8 @@ static int spear_smi_setup_banks(struct platform_device *pdev, count = flash_info->nr_partitions; } #endif - ppdata.of_node = np; - ret = mtd_device_parse_register(&flash->mtd, NULL, &ppdata, parts, - count); + ret = mtd_device_register(&flash->mtd, parts, count); if (ret) { dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret); return ret; diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c index 3060025c8af47..5454b41135892 100644 --- a/drivers/mtd/devices/st_spi_fsm.c +++ b/drivers/mtd/devices/st_spi_fsm.c @@ -2025,7 +2025,6 @@ boot_device_fail: static int stfsm_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; - struct mtd_part_parser_data ppdata; struct flash_info *info; struct resource *res; struct stfsm *fsm; @@ -2035,7 +2034,6 @@ static int stfsm_probe(struct platform_device *pdev) dev_err(&pdev->dev, "No DT found\n"); return -EINVAL; } - ppdata.of_node = np; fsm = devm_kzalloc(&pdev->dev, sizeof(*fsm), GFP_KERNEL); if (!fsm) @@ -2106,6 +2104,7 @@ static int stfsm_probe(struct platform_device *pdev) fsm->mtd.name = info->name; fsm->mtd.dev.parent = &pdev->dev; + mtd_set_of_node(&fsm->mtd, np); fsm->mtd.type = MTD_NORFLASH; fsm->mtd.writesize = 4; fsm->mtd.writebufsize = fsm->mtd.writesize; @@ -2124,7 +2123,7 @@ static int stfsm_probe(struct platform_device *pdev) (long long)fsm->mtd.size, (long long)(fsm->mtd.size >> 20), fsm->mtd.erasesize, (fsm->mtd.erasesize >> 10)); - return mtd_device_parse_register(&fsm->mtd, NULL, &ppdata, NULL, 0); + return mtd_device_register(&fsm->mtd, NULL, 0); } static int stfsm_remove(struct platform_device *pdev) diff --git a/drivers/mtd/maps/lantiq-flash.c b/drivers/mtd/maps/lantiq-flash.c index 93852054977ea..c8febb326fa66 100644 --- a/drivers/mtd/maps/lantiq-flash.c +++ b/drivers/mtd/maps/lantiq-flash.c @@ -110,7 +110,6 @@ ltq_copy_to(struct map_info *map, unsigned long to, static int ltq_mtd_probe(struct platform_device *pdev) { - struct mtd_part_parser_data ppdata; struct ltq_mtd *ltq_mtd; struct cfi_private *cfi; int err; @@ -161,13 +160,13 @@ ltq_mtd_probe(struct platform_device *pdev) } ltq_mtd->mtd->dev.parent = &pdev->dev; + mtd_set_of_node(ltq_mtd->mtd, pdev->dev.of_node); cfi = ltq_mtd->map->fldrv_priv; cfi->addr_unlock1 ^= 1; cfi->addr_unlock2 ^= 1; - ppdata.of_node = pdev->dev.of_node; - err = mtd_device_parse_register(ltq_mtd->mtd, NULL, &ppdata, NULL, 0); + err = mtd_device_register(ltq_mtd->mtd, NULL, 0); if (err) { dev_err(&pdev->dev, "failed to add partitions\n"); goto err_destroy; diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index e46b4e9836668..b782656880755 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -166,7 +166,6 @@ static int of_flash_probe(struct platform_device *dev) int reg_tuple_size; struct mtd_info **mtd_list = NULL; resource_size_t res_size; - struct mtd_part_parser_data ppdata; bool map_indirect; const char *mtd_name = NULL; @@ -310,13 +309,13 @@ static int of_flash_probe(struct platform_device *dev) if (err) goto err_out; - ppdata.of_node = dp; + mtd_set_of_node(info->cmtd, dp); part_probe_types = of_get_probes(dp); if (!part_probe_types) { err = -ENOMEM; goto err_out; } - mtd_device_parse_register(info->cmtd, part_probe_types, &ppdata, + mtd_device_parse_register(info->cmtd, part_probe_types, NULL, NULL, 0); of_free_probes(part_probe_types); diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index 3e02856962279..0aacf125938be 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c @@ -614,7 +614,6 @@ static int omap2_onenand_probe(struct platform_device *pdev) struct onenand_chip *this; int r; struct resource *res; - struct mtd_part_parser_data ppdata = {}; pdata = dev_get_platdata(&pdev->dev); if (pdata == NULL) { @@ -713,6 +712,7 @@ static int omap2_onenand_probe(struct platform_device *pdev) c->mtd.priv = &c->onenand; c->mtd.dev.parent = &pdev->dev; + mtd_set_of_node(&c->mtd, pdata->of_node); this = &c->onenand; if (c->dma_channel >= 0) { @@ -743,10 +743,8 @@ static int omap2_onenand_probe(struct platform_device *pdev) if ((r = onenand_scan(&c->mtd, 1)) < 0) goto err_release_regulator; - ppdata.of_node = pdata->of_node; - r = mtd_device_parse_register(&c->mtd, NULL, &ppdata, - pdata ? pdata->parts : NULL, - pdata ? pdata->nr_parts : 0); + r = mtd_device_register(&c->mtd, pdata ? pdata->parts : NULL, + pdata ? pdata->nr_parts : 0); if (r) goto err_release_onenand; -- GitLab From e270bca531b40cd0a143176eb093d173b9c6f418 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 30 Oct 2015 20:33:29 -0700 Subject: [PATCH 0035/2855] mtd: ofpart: drop 'of_node' partition parser data This field is no longer used anywhere, as it is superseded by mtd->dev.of_node. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- drivers/mtd/ofpart.c | 14 ++++---------- include/linux/mtd/partitions.h | 4 ---- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index 7bf996a4cf5eb..f78d2aea5545e 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c @@ -37,11 +37,8 @@ static int parse_ofpart_partitions(struct mtd_info *master, bool dedicated = true; - /* - * of_node can be provided through auxiliary parser data or (preferred) - * by assigning the master device node - */ - mtd_node = data && data->of_node ? data->of_node : mtd_get_of_node(master); + /* Pull of_node from the master device node */ + mtd_node = mtd_get_of_node(master); if (!mtd_node) return 0; @@ -150,11 +147,8 @@ static int parse_ofoldpart_partitions(struct mtd_info *master, } *part; const char *names; - /* - * of_node can be provided through auxiliary parser data or (preferred) - * by assigning the master device node - */ - dp = data && data->of_node ? data->of_node : mtd_get_of_node(master); + /* Pull of_node from the master device node */ + dp = mtd_get_of_node(master); if (!dp) return 0; diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index e742f34b67ebb..773975a3c9e63 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -56,13 +56,9 @@ struct device_node; /** * struct mtd_part_parser_data - used to pass data to MTD partition parsers. * @origin: for RedBoot, start address of MTD device - * @of_node: for OF parsers, device node containing partitioning information. - * This field is deprecated, as the device node should simply be - * assigned to the master struct device. */ struct mtd_part_parser_data { unsigned long origin; - struct device_node *of_node; }; -- GitLab From 8361a9b8cb6a9c71b7cf884a87b2532d8367c185 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 30 Oct 2015 20:33:30 -0700 Subject: [PATCH 0036/2855] mtd: physmap_of: assign parent for the concatenated MTD If there is more than one map region for this device, then the concatenated MTD will not have a parent device assigned to it -- only the sub-devices (which are not actually registered with the framework) will have their parents assigned. Let's assign the concatenated device correctly. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- drivers/mtd/maps/physmap_of.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index b782656880755..70c453144f001 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -309,6 +309,7 @@ static int of_flash_probe(struct platform_device *dev) if (err) goto err_out; + info->cmtd->dev.parent = &dev->dev; mtd_set_of_node(info->cmtd, dp); part_probe_types = of_get_probes(dp); if (!part_probe_types) { -- GitLab From 44ec23c9ecd95d13ec9dd8d0b0dc9e82bd3258ff Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 2 Nov 2015 00:03:38 +0100 Subject: [PATCH 0037/2855] mtd: nand: convert to nand_get_flash_node() Used semantic patch with 'make coccicheck MODE=patch COCCI=script.cocci': ---8<---- virtual patch @@ struct nand_chip c; struct nand_chip *cp; @@ ( -(cp)->flash_node +nand_get_flash_node(cp) | -(c).flash_node +nand_get_flash_node(&c) ) ---8<---- Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/brcmnand/brcmnand.c | 2 +- drivers/mtd/nand/nand_base.c | 6 +++--- drivers/mtd/nand/vf610_nfc.c | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index a37659de025c2..2a437c7ed1759 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -1816,7 +1816,7 @@ static int brcmnand_setup_dev(struct brcmnand_host *host) memset(cfg, 0, sizeof(*cfg)); - ret = of_property_read_u32(chip->flash_node, + ret = of_property_read_u32(nand_get_flash_node(chip), "brcm,nand-oob-sector-size", &oob_sector); if (ret) { diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 939ab3d5acc2b..4ac4efe65c62e 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3989,11 +3989,11 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, struct nand_flash_dev *type; int ret; - if (chip->flash_node) { + if (nand_get_flash_node(chip)) { /* MTD can automatically handle DT partitions, etc. */ - mtd_set_of_node(mtd, chip->flash_node); + mtd_set_of_node(mtd, nand_get_flash_node(chip)); - ret = nand_dt_init(mtd, chip, chip->flash_node); + ret = nand_dt_init(mtd, chip, nand_get_flash_node(chip)); if (ret) return ret; } diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c index b6df4c6d60ca9..1c86c6b42515a 100644 --- a/drivers/mtd/nand/vf610_nfc.c +++ b/drivers/mtd/nand/vf610_nfc.c @@ -707,7 +707,7 @@ static int vf610_nfc_probe(struct platform_device *pdev) for_each_available_child_of_node(nfc->dev->of_node, child) { if (of_device_is_compatible(child, "fsl,vf610-nfc-nandcs")) { - if (chip->flash_node) { + if (nand_get_flash_node(chip)) { dev_err(nfc->dev, "Only one NAND chip supported!\n"); err = -EINVAL; @@ -718,7 +718,7 @@ static int vf610_nfc_probe(struct platform_device *pdev) } } - if (!chip->flash_node) { + if (!nand_get_flash_node(chip)) { dev_err(nfc->dev, "NAND chip sub-node missing!\n"); err = -ENODEV; goto err_clk; @@ -814,7 +814,7 @@ static int vf610_nfc_probe(struct platform_device *pdev) return mtd_device_register(mtd, NULL, 0); error: - of_node_put(chip->flash_node); + of_node_put(nand_get_flash_node(chip)); err_clk: clk_disable_unprepare(nfc->clk); return err; -- GitLab From 215a02fd30871d0d888d27a3154588b66f5dbec2 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 11 Nov 2015 16:26:04 -0800 Subject: [PATCH 0038/2855] mtd: grab a reference to the MTD of_node before registering it We now stick the device node representing the current MTD (if any) into sysfs, so let's make sure we have a reference to it before doing that. Suggested-by: Boris Brezillon Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- drivers/mtd/mtdcore.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index a91cee90aef9e..c393a11553764 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -454,6 +455,7 @@ int add_mtd_device(struct mtd_info *mtd) mtd->dev.devt = MTD_DEVT(i); dev_set_name(&mtd->dev, "mtd%d", i); dev_set_drvdata(&mtd->dev, mtd); + of_node_get(mtd_get_of_node(mtd)); error = device_register(&mtd->dev); if (error) goto fail_added; @@ -476,6 +478,7 @@ int add_mtd_device(struct mtd_info *mtd) return 0; fail_added: + of_node_put(mtd_get_of_node(mtd)); idr_remove(&mtd_idr, i); fail_locked: mutex_unlock(&mtd_table_mutex); @@ -517,6 +520,7 @@ int del_mtd_device(struct mtd_info *mtd) device_unregister(&mtd->dev); idr_remove(&mtd_idr, mtd->index); + of_node_put(mtd_get_of_node(mtd)); module_put(THIS_MODULE); ret = 0; -- GitLab From 938672338991ac8bef5cb025b187ab8d6230ac6c Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 11 Nov 2015 16:47:52 -0800 Subject: [PATCH 0039/2855] mtd: zero out mtd_partition struct before using it It's easier to guarantee we've cleared out all unused fields with memset() than by manually initializing each field. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- drivers/mtd/mtdpart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index f8ba153f63bfe..46dfbf5629c31 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -596,11 +596,10 @@ int mtd_add_partition(struct mtd_info *master, const char *name, if (length <= 0) return -EINVAL; + memset(&part, 0, sizeof(part)); part.name = name; part.size = length; part.offset = offset; - part.mask_flags = 0; - part.ecclayout = NULL; new = allocate_partition(master, &part, -1, offset); if (IS_ERR(new)) -- GitLab From 26add94cd535d1e000e7871fe69c7bb89e942d67 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 11 Nov 2015 17:05:56 -0800 Subject: [PATCH 0040/2855] mtd: partitions: kill unused ecclayout struct This field is not used. Reported here: http://lists.infradead.org/pipermail/linux-mtd/2015-October/062417.html Reported-by: Brian Foster Cc: Brian Foster Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- include/linux/mtd/partitions.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index 773975a3c9e63..8421520c10eb2 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -41,7 +41,6 @@ struct mtd_partition { uint64_t size; /* partition size */ uint64_t offset; /* offset within the master MTD space */ uint32_t mask_flags; /* master MTD flags to mask out for this partition */ - struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only) */ }; #define MTDPART_OFS_RETAIN (-3) -- GitLab From 34dc578d99449a83dcb0f5ef4444215590183af4 Mon Sep 17 00:00:00 2001 From: Giuseppe Barba Date: Thu, 12 Nov 2015 08:36:49 +0100 Subject: [PATCH 0041/2855] iio: st-accel: add support for lis2dh12 This commit add support for STMicroelectronics lis2dh12 accelerometer. Datasheet for this device can be found here: http://www.st.com/st-web-ui/static/active/en/resource/technical/ document/datasheet/DM00091513.pdf Signed-off-by: Giuseppe Barba Acked-by: Denis Ciocca Acked-by: Daniel Baluta Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/st-sensors.txt | 1 + drivers/iio/accel/Kconfig | 2 +- drivers/iio/accel/st_accel.h | 1 + drivers/iio/accel/st_accel_core.c | 1 + drivers/iio/accel/st_accel_i2c.c | 5 +++++ drivers/iio/accel/st_accel_spi.c | 1 + 6 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/iio/st-sensors.txt b/Documentation/devicetree/bindings/iio/st-sensors.txt index d3ccdb190c53b..d4b87cc1e446e 100644 --- a/Documentation/devicetree/bindings/iio/st-sensors.txt +++ b/Documentation/devicetree/bindings/iio/st-sensors.txt @@ -36,6 +36,7 @@ Accelerometers: - st,lsm303dlm-accel - st,lsm330-accel - st,lsm303agr-accel +- st,lis2dh12-accel Gyroscopes: - st,l3g4200d-gyro diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index 87487d377f9b2..edc29b173f6c9 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig @@ -64,7 +64,7 @@ config IIO_ST_ACCEL_3AXIS help Say yes here to build support for STMicroelectronics accelerometers: LSM303DLH, LSM303DLHC, LIS3DH, LSM330D, LSM330DL, LSM330DLC, - LIS331DLH, LSM303DL, LSM303DLM, LSM330. + LIS331DLH, LSM303DL, LSM303DLM, LSM330, LIS2DH12. This driver can also be built as a module. If so, these modules will be created: diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h index 468f21fa2950b..5d4a1897b293e 100644 --- a/drivers/iio/accel/st_accel.h +++ b/drivers/iio/accel/st_accel.h @@ -27,6 +27,7 @@ #define LSM303DLM_ACCEL_DEV_NAME "lsm303dlm_accel" #define LSM330_ACCEL_DEV_NAME "lsm330_accel" #define LSM303AGR_ACCEL_DEV_NAME "lsm303agr_accel" +#define LIS2DH12_ACCEL_DEV_NAME "lis2dh12_accel" /** * struct st_sensors_platform_data - default accel platform data diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index dab8b76c14270..9d973f1e74acd 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -234,6 +234,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { [3] = LSM330DL_ACCEL_DEV_NAME, [4] = LSM330DLC_ACCEL_DEV_NAME, [5] = LSM303AGR_ACCEL_DEV_NAME, + [6] = LIS2DH12_ACCEL_DEV_NAME, }, .ch = (struct iio_chan_spec *)st_accel_12bit_channels, .odr = { diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c index 8b9cc84fd44f9..294a32f89367b 100644 --- a/drivers/iio/accel/st_accel_i2c.c +++ b/drivers/iio/accel/st_accel_i2c.c @@ -72,6 +72,10 @@ static const struct of_device_id st_accel_of_match[] = { .compatible = "st,lsm303agr-accel", .data = LSM303AGR_ACCEL_DEV_NAME, }, + { + .compatible = "st,lis2dh12-accel", + .data = LIS2DH12_ACCEL_DEV_NAME, + }, {}, }; MODULE_DEVICE_TABLE(of, st_accel_of_match); @@ -121,6 +125,7 @@ static const struct i2c_device_id st_accel_id_table[] = { { LSM303DLM_ACCEL_DEV_NAME }, { LSM330_ACCEL_DEV_NAME }, { LSM303AGR_ACCEL_DEV_NAME }, + { LIS2DH12_ACCEL_DEV_NAME }, {}, }; MODULE_DEVICE_TABLE(i2c, st_accel_id_table); diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c index 54b61a3961c30..e82bedfaeb9b1 100644 --- a/drivers/iio/accel/st_accel_spi.c +++ b/drivers/iio/accel/st_accel_spi.c @@ -58,6 +58,7 @@ static const struct spi_device_id st_accel_id_table[] = { { LSM303DLM_ACCEL_DEV_NAME }, { LSM330_ACCEL_DEV_NAME }, { LSM303AGR_ACCEL_DEV_NAME }, + { LIS2DH12_ACCEL_DEV_NAME }, {}, }; MODULE_DEVICE_TABLE(spi, st_accel_id_table); -- GitLab From f47dff323088462e7b0ac52d1ba41ce953a5ce20 Mon Sep 17 00:00:00 2001 From: Sean Nyekjaer Date: Mon, 9 Nov 2015 13:55:34 +0100 Subject: [PATCH 0042/2855] iio: core: added support for IIO_VAL_INT Added core support for IIO_VAL_INT in write_raw_get_fmt function. Signed-off-by: Sean Nyekjaer Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-core.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 208358f9e7e36..d0a84febd435a 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -512,6 +512,12 @@ int iio_str_to_fixpoint(const char *str, int fract_mult, 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++; @@ -571,6 +577,9 @@ static ssize_t iio_write_channel_info(struct device *dev, 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; -- GitLab From 3e87e78383283119a7d41f8a4cab8ef0a5c9acab Mon Sep 17 00:00:00 2001 From: Sean Nyekjaer Date: Mon, 9 Nov 2015 13:52:59 +0100 Subject: [PATCH 0043/2855] iio: adc: Add TI ADS8688 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds support for the Texas Intruments ADS8688 ADC. Signed-off-by: Sean Nyekjaer Reviewed-by: Martin Hundebøll Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 10 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/ti-ads8688.c | 486 +++++++++++++++++++++++++++++++++++ 3 files changed, 497 insertions(+) create mode 100644 drivers/iio/adc/ti-ads8688.c diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index daad72e1266da..9162dfefff30d 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -341,6 +341,16 @@ config TI_ADC128S052 This driver can also be built as a module. If so, the module will be called ti-adc128s052. +config TI_ADS8688 + tristate "Texas Instruments ADS8688" + depends on SPI && OF + help + If you say yes here you get support for Texas Instruments ADS8684 and + and ADS8688 ADC chips + + This driver can also be built as a module. If so, the module will be + called ti-ads8688. + config TI_AM335X_ADC tristate "TI's AM335X ADC driver" depends on MFD_TI_AM335X_TSCADC diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 11cfdfd767984..91a65bf11c584 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o +obj-$(CONFIG_TI_ADS8688) += ti-ads8688.o obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c new file mode 100644 index 0000000000000..03e907028cb6c --- /dev/null +++ b/drivers/iio/adc/ti-ads8688.c @@ -0,0 +1,486 @@ +/* + * Copyright (C) 2015 Prevas A/S + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define ADS8688_CMD_REG(x) (x << 8) +#define ADS8688_CMD_REG_NOOP 0x00 +#define ADS8688_CMD_REG_RST 0x85 +#define ADS8688_CMD_REG_MAN_CH(chan) (0xC0 | (4 * chan)) +#define ADS8688_CMD_DONT_CARE_BITS 16 + +#define ADS8688_PROG_REG(x) (x << 9) +#define ADS8688_PROG_REG_RANGE_CH(chan) (0x05 + chan) +#define ADS8688_PROG_WR_BIT BIT(8) +#define ADS8688_PROG_DONT_CARE_BITS 8 + +#define ADS8688_REG_PLUSMINUS25VREF 0 +#define ADS8688_REG_PLUSMINUS125VREF 1 +#define ADS8688_REG_PLUSMINUS0625VREF 2 +#define ADS8688_REG_PLUS25VREF 5 +#define ADS8688_REG_PLUS125VREF 6 + +#define ADS8688_VREF_MV 4096 +#define ADS8688_REALBITS 16 + +/* + * enum ads8688_range - ADS8688 reference voltage range + * @ADS8688_PLUSMINUS25VREF: Device is configured for input range ±2.5 * VREF + * @ADS8688_PLUSMINUS125VREF: Device is configured for input range ±1.25 * VREF + * @ADS8688_PLUSMINUS0625VREF: Device is configured for input range ±0.625 * VREF + * @ADS8688_PLUS25VREF: Device is configured for input range 0 - 2.5 * VREF + * @ADS8688_PLUS125VREF: Device is configured for input range 0 - 1.25 * VREF + */ +enum ads8688_range { + ADS8688_PLUSMINUS25VREF, + ADS8688_PLUSMINUS125VREF, + ADS8688_PLUSMINUS0625VREF, + ADS8688_PLUS25VREF, + ADS8688_PLUS125VREF, +}; + +struct ads8688_chip_info { + const struct iio_chan_spec *channels; + unsigned int num_channels; +}; + +struct ads8688_state { + struct mutex lock; + const struct ads8688_chip_info *chip_info; + struct spi_device *spi; + struct regulator *reg; + unsigned int vref_mv; + enum ads8688_range range[8]; + union { + __be32 d32; + u8 d8[4]; + } data[2] ____cacheline_aligned; +}; + +enum ads8688_id { + ID_ADS8684, + ID_ADS8688, +}; + +struct ads8688_ranges { + enum ads8688_range range; + unsigned int scale; + int offset; + u8 reg; +}; + +static const struct ads8688_ranges ads8688_range_def[5] = { + { + .range = ADS8688_PLUSMINUS25VREF, + .scale = 76295, + .offset = -(1 << (ADS8688_REALBITS - 1)), + .reg = ADS8688_REG_PLUSMINUS25VREF, + }, { + .range = ADS8688_PLUSMINUS125VREF, + .scale = 38148, + .offset = -(1 << (ADS8688_REALBITS - 1)), + .reg = ADS8688_REG_PLUSMINUS125VREF, + }, { + .range = ADS8688_PLUSMINUS0625VREF, + .scale = 19074, + .offset = -(1 << (ADS8688_REALBITS - 1)), + .reg = ADS8688_REG_PLUSMINUS0625VREF, + }, { + .range = ADS8688_PLUS25VREF, + .scale = 38148, + .offset = 0, + .reg = ADS8688_REG_PLUS25VREF, + }, { + .range = ADS8688_PLUS125VREF, + .scale = 19074, + .offset = 0, + .reg = ADS8688_REG_PLUS125VREF, + } +}; + +static ssize_t ads8688_show_scales(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ads8688_state *st = iio_priv(dev_to_iio_dev(dev)); + + return sprintf(buf, "0.%09u 0.%09u 0.%09u\n", + ads8688_range_def[0].scale * st->vref_mv, + ads8688_range_def[1].scale * st->vref_mv, + ads8688_range_def[2].scale * st->vref_mv); +} + +static ssize_t ads8688_show_offsets(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d %d\n", ads8688_range_def[0].offset, + ads8688_range_def[3].offset); +} + +static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO, + ads8688_show_scales, NULL, 0); +static IIO_DEVICE_ATTR(in_voltage_offset_available, S_IRUGO, + ads8688_show_offsets, NULL, 0); + +static struct attribute *ads8688_attributes[] = { + &iio_dev_attr_in_voltage_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage_offset_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ads8688_attribute_group = { + .attrs = ads8688_attributes, +}; + +#define ADS8688_CHAN(index) \ +{ \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = index, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \ + | BIT(IIO_CHAN_INFO_SCALE) \ + | BIT(IIO_CHAN_INFO_OFFSET), \ +} + +static const struct iio_chan_spec ads8684_channels[] = { + ADS8688_CHAN(0), + ADS8688_CHAN(1), + ADS8688_CHAN(2), + ADS8688_CHAN(3), +}; + +static const struct iio_chan_spec ads8688_channels[] = { + ADS8688_CHAN(0), + ADS8688_CHAN(1), + ADS8688_CHAN(2), + ADS8688_CHAN(3), + ADS8688_CHAN(4), + ADS8688_CHAN(5), + ADS8688_CHAN(6), + ADS8688_CHAN(7), +}; + +static int ads8688_prog_write(struct iio_dev *indio_dev, unsigned int addr, + unsigned int val) +{ + struct ads8688_state *st = iio_priv(indio_dev); + u32 tmp; + + tmp = ADS8688_PROG_REG(addr) | ADS8688_PROG_WR_BIT | val; + tmp <<= ADS8688_PROG_DONT_CARE_BITS; + st->data[0].d32 = cpu_to_be32(tmp); + + return spi_write(st->spi, &st->data[0].d8[1], 3); +} + +static int ads8688_reset(struct iio_dev *indio_dev) +{ + struct ads8688_state *st = iio_priv(indio_dev); + u32 tmp; + + tmp = ADS8688_CMD_REG(ADS8688_CMD_REG_RST); + tmp <<= ADS8688_CMD_DONT_CARE_BITS; + st->data[0].d32 = cpu_to_be32(tmp); + + return spi_write(st->spi, &st->data[0].d8[0], 4); +} + +static int ads8688_read(struct iio_dev *indio_dev, unsigned int chan) +{ + struct ads8688_state *st = iio_priv(indio_dev); + int ret; + u32 tmp; + struct spi_transfer t[] = { + { + .tx_buf = &st->data[0].d8[0], + .len = 4, + .cs_change = 1, + }, { + .tx_buf = &st->data[1].d8[0], + .rx_buf = &st->data[1].d8[0], + .len = 4, + }, + }; + + tmp = ADS8688_CMD_REG(ADS8688_CMD_REG_MAN_CH(chan)); + tmp <<= ADS8688_CMD_DONT_CARE_BITS; + st->data[0].d32 = cpu_to_be32(tmp); + + tmp = ADS8688_CMD_REG(ADS8688_CMD_REG_NOOP); + tmp <<= ADS8688_CMD_DONT_CARE_BITS; + st->data[1].d32 = cpu_to_be32(tmp); + + ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t)); + if (ret < 0) + return ret; + + return be32_to_cpu(st->data[1].d32) & 0xffff; +} + +static int ads8688_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long m) +{ + int ret, offset; + unsigned long scale_mv; + + struct ads8688_state *st = iio_priv(indio_dev); + + mutex_lock(&st->lock); + switch (m) { + case IIO_CHAN_INFO_RAW: + ret = ads8688_read(indio_dev, chan->channel); + mutex_unlock(&st->lock); + if (ret < 0) + return ret; + *val = ret; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + scale_mv = st->vref_mv; + scale_mv *= ads8688_range_def[st->range[chan->channel]].scale; + *val = 0; + *val2 = scale_mv; + mutex_unlock(&st->lock); + return IIO_VAL_INT_PLUS_NANO; + case IIO_CHAN_INFO_OFFSET: + offset = ads8688_range_def[st->range[chan->channel]].offset; + *val = offset; + mutex_unlock(&st->lock); + return IIO_VAL_INT; + } + mutex_unlock(&st->lock); + + return -EINVAL; +} + +static int ads8688_write_reg_range(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + enum ads8688_range range) +{ + unsigned int tmp; + int ret; + + tmp = ADS8688_PROG_REG_RANGE_CH(chan->channel); + ret = ads8688_prog_write(indio_dev, tmp, range); + + return ret; +} + +static int ads8688_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct ads8688_state *st = iio_priv(indio_dev); + unsigned int scale = 0; + int ret = -EINVAL, i, offset = 0; + + mutex_lock(&st->lock); + switch (mask) { + case IIO_CHAN_INFO_SCALE: + /* If the offset is 0 the ±2.5 * VREF mode is not available */ + offset = ads8688_range_def[st->range[chan->channel]].offset; + if (offset == 0 && val2 == ads8688_range_def[0].scale * st->vref_mv) { + mutex_unlock(&st->lock); + return -EINVAL; + } + + /* Lookup new mode */ + for (i = 0; i < ARRAY_SIZE(ads8688_range_def); i++) + if (val2 == ads8688_range_def[i].scale * st->vref_mv && + offset == ads8688_range_def[i].offset) { + ret = ads8688_write_reg_range(indio_dev, chan, + ads8688_range_def[i].reg); + break; + } + break; + case IIO_CHAN_INFO_OFFSET: + /* + * There are only two available offsets: + * 0 and -(1 << (ADS8688_REALBITS - 1)) + */ + if (!(ads8688_range_def[0].offset == val || + ads8688_range_def[3].offset == val)) { + mutex_unlock(&st->lock); + return -EINVAL; + } + + /* + * If the device are in ±2.5 * VREF mode, it's not allowed to + * switch to a mode where the offset is 0 + */ + if (val == 0 && + st->range[chan->channel] == ADS8688_PLUSMINUS25VREF) { + mutex_unlock(&st->lock); + return -EINVAL; + } + + scale = ads8688_range_def[st->range[chan->channel]].scale; + + /* Lookup new mode */ + for (i = 0; i < ARRAY_SIZE(ads8688_range_def); i++) + if (val == ads8688_range_def[i].offset && + scale == ads8688_range_def[i].scale) { + ret = ads8688_write_reg_range(indio_dev, chan, + ads8688_range_def[i].reg); + break; + } + break; + } + + if (!ret) + st->range[chan->channel] = ads8688_range_def[i].range; + + mutex_unlock(&st->lock); + + return ret; +} + +static int ads8688_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SCALE: + return IIO_VAL_INT_PLUS_NANO; + case IIO_CHAN_INFO_OFFSET: + return IIO_VAL_INT; + } + + return -EINVAL; +} + +static const struct iio_info ads8688_info = { + .read_raw = &ads8688_read_raw, + .write_raw = &ads8688_write_raw, + .write_raw_get_fmt = &ads8688_write_raw_get_fmt, + .attrs = &ads8688_attribute_group, + .driver_module = THIS_MODULE, +}; + +static const struct ads8688_chip_info ads8688_chip_info_tbl[] = { + [ID_ADS8684] = { + .channels = ads8684_channels, + .num_channels = ARRAY_SIZE(ads8684_channels), + }, + [ID_ADS8688] = { + .channels = ads8688_channels, + .num_channels = ARRAY_SIZE(ads8688_channels), + }, +}; + +static int ads8688_probe(struct spi_device *spi) +{ + struct ads8688_state *st; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + + st->reg = devm_regulator_get_optional(&spi->dev, "vref"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + return ret; + + ret = regulator_get_voltage(st->reg); + if (ret < 0) + goto error_out; + + st->vref_mv = ret / 1000; + } else { + /* Use internal reference */ + st->vref_mv = ADS8688_VREF_MV; + } + + st->chip_info = &ads8688_chip_info_tbl[spi_get_device_id(spi)->driver_data]; + + spi->mode = SPI_MODE_1; + + spi_set_drvdata(spi, indio_dev); + + st->spi = spi; + + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = st->chip_info->channels; + indio_dev->num_channels = st->chip_info->num_channels; + indio_dev->info = &ads8688_info; + + ads8688_reset(indio_dev); + + mutex_init(&st->lock); + + ret = iio_device_register(indio_dev); + if (ret) + goto error_out; + + return 0; + +error_out: + if (!IS_ERR_OR_NULL(st->reg)) + regulator_disable(st->reg); + + return ret; +} + +static int ads8688_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ads8688_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + + if (!IS_ERR_OR_NULL(st->reg)) + regulator_disable(st->reg); + + return 0; +} + +static const struct spi_device_id ads8688_id[] = { + {"ads8684", ID_ADS8684}, + {"ads8688", ID_ADS8688}, + {} +}; +MODULE_DEVICE_TABLE(spi, ads8688_id); + +static const struct of_device_id ads8688_of_match[] = { + { .compatible = "ti,ads8684" }, + { .compatible = "ti,ads8688" }, + { } +}; +MODULE_DEVICE_TABLE(of, ads8688_of_match); + +static struct spi_driver ads8688_driver = { + .driver = { + .name = "ads8688", + .owner = THIS_MODULE, + }, + .probe = ads8688_probe, + .remove = ads8688_remove, + .id_table = ads8688_id, +}; +module_spi_driver(ads8688_driver); + +MODULE_AUTHOR("Sean Nyekjaer "); +MODULE_DESCRIPTION("Texas Instruments ADS8688 driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From a1513641892b220bc5b7ce63e44b81658702cdae Mon Sep 17 00:00:00 2001 From: Sean Nyekjaer Date: Mon, 9 Nov 2015 13:53:00 +0100 Subject: [PATCH 0044/2855] iio: ti-ads8688: Add DT binding documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding binding documentation for Texas Instruments ADS8688 ADC. Signed-off-by: Sean Nyekjaer Reviewed-by: Martin Hundebøll Acked-by: Rob Herring Signed-off-by: Jonathan Cameron --- .../bindings/iio/adc/ti-ads8688.txt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/ti-ads8688.txt diff --git a/Documentation/devicetree/bindings/iio/adc/ti-ads8688.txt b/Documentation/devicetree/bindings/iio/adc/ti-ads8688.txt new file mode 100644 index 0000000000000..a02337d7efa44 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti-ads8688.txt @@ -0,0 +1,20 @@ +* Texas Instruments' ADS8684 and ADS8688 ADC chip + +Required properties: + - compatible: Should be "ti,ads8684" or "ti,ads8688" + - reg: spi chip select number for the device + +Recommended properties: + - spi-max-frequency: Definition as per + Documentation/devicetree/bindings/spi/spi-bus.txt + +Optional properties: + - vref-supply: The regulator supply for ADC reference voltage + +Example: +adc@0 { + compatible = "ti,ads8688"; + reg = <0>; + vref-supply = <&vdd_supply>; + spi-max-frequency = <1000000>; +}; -- GitLab From e0c961bdaf2786bc9795efff6e87a15491778384 Mon Sep 17 00:00:00 2001 From: Nizam Haider Date: Mon, 9 Nov 2015 19:56:02 +0530 Subject: [PATCH 0045/2855] iio: adc: mxs-lradc: Prefer using the BIT macro Replaces bit shifting on 1 with the BIT(x) macro Signed-off-by: Nizam Haider Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/mxs-lradc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index 407d4a2c8eda0..1f25027b7b61f 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -324,7 +324,7 @@ struct mxs_lradc { #define LRADC_DELAY_TRIGGER(x) \ (((x) << LRADC_DELAY_TRIGGER_LRADCS_OFFSET) & \ LRADC_DELAY_TRIGGER_LRADCS_MASK) -#define LRADC_DELAY_KICK (1 << 20) +#define LRADC_DELAY_KICK BIT(20) #define LRADC_DELAY_TRIGGER_DELAYS_MASK (0xf << 16) #define LRADC_DELAY_TRIGGER_DELAYS_OFFSET 16 #define LRADC_DELAY_TRIGGER_DELAYS(x) \ -- GitLab From 7d173f26353df0e90ea1223b80f6834845f27435 Mon Sep 17 00:00:00 2001 From: Nizam Haider Date: Mon, 9 Nov 2015 18:20:45 +0530 Subject: [PATCH 0046/2855] iio: adc: ad7793: removed unnecessary else. Else is not generally useful after a break or return. Signed-off-by: Nizam Haider Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7793.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c index b84922a4b32e6..d3eeb3fb46c2f 100644 --- a/drivers/iio/adc/ad7793.c +++ b/drivers/iio/adc/ad7793.c @@ -478,10 +478,9 @@ static int ad7793_read_raw(struct iio_dev *indio_dev, *val2 = st-> scale_avail[(st->conf >> 8) & 0x7][1]; return IIO_VAL_INT_PLUS_NANO; - } else { - /* 1170mV / 2^23 * 6 */ - scale_uv = (1170ULL * 1000000000ULL * 6ULL); } + /* 1170mV / 2^23 * 6 */ + scale_uv = (1170ULL * 1000000000ULL * 6ULL); break; case IIO_TEMP: /* 1170mV / 0.81 mV/C / 2^23 */ -- GitLab From b36f09c3c441a6e59eab9315032e7d546571de3f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 20 Oct 2015 11:46:28 +0200 Subject: [PATCH 0047/2855] dmaengine: Add transfer termination synchronization support The DMAengine API has a long standing race condition that is inherent to the API itself. Calling dmaengine_terminate_all() is supposed to stop and abort any pending or active transfers that have previously been submitted. Unfortunately it is possible that this operation races against a currently running (or with some drivers also scheduled) completion callback. Since the API allows dmaengine_terminate_all() to be called from atomic context as well as from within a completion callback it is not possible to synchronize to the execution of the completion callback from within dmaengine_terminate_all() itself. This means that a user of the DMAengine API does not know when it is safe to free resources used in the completion callback, which can result in a use-after-free race condition. This patch addresses the issue by introducing an explicit synchronization primitive to the DMAengine API called dmaengine_synchronize(). The existing dmaengine_terminate_all() is deprecated in favor of dmaengine_terminate_sync() and dmaengine_terminate_async(). The former aborts all pending and active transfers and synchronizes to the current context, meaning it will wait until all running completion callbacks have finished. This means it is only possible to call this function from non-atomic context. The later function does not synchronize, but can still be used in atomic context or from within a complete callback. It has to be followed up by dmaengine_synchronize() before a client can free the resources used in a completion callback. In addition to this the semantics of the device_terminate_all() callback are slightly relaxed by this patch. It is now OK for a driver to only schedule the termination of the active transfer, but does not necessarily have to wait until the DMA controller has completely stopped. The driver must ensure though that the controller has stopped and no longer accesses any memory when the device_synchronize() callback returns. This was in part done since most drivers do not pay attention to this anyway at the moment and to emphasize that this needs to be done when the device_synchronize() callback is implemented. But it also helps with implementing support for devices where stopping the controller can require operations that may sleep. Signed-off-by: Lars-Peter Clausen Signed-off-by: Vinod Koul --- Documentation/dmaengine/client.txt | 38 +++++++++++- Documentation/dmaengine/provider.txt | 20 ++++++- drivers/dma/dmaengine.c | 5 +- include/linux/dmaengine.h | 90 ++++++++++++++++++++++++++++ 4 files changed, 148 insertions(+), 5 deletions(-) diff --git a/Documentation/dmaengine/client.txt b/Documentation/dmaengine/client.txt index 11fb87ff6cd09..d9f9f461102a4 100644 --- a/Documentation/dmaengine/client.txt +++ b/Documentation/dmaengine/client.txt @@ -128,7 +128,7 @@ The slave DMA usage consists of following steps: transaction. For cyclic DMA, a callback function may wish to terminate the - DMA via dmaengine_terminate_all(). + DMA via dmaengine_terminate_async(). Therefore, it is important that DMA engine drivers drop any locks before calling the callback function which may cause a @@ -166,12 +166,29 @@ The slave DMA usage consists of following steps: Further APIs: -1. int dmaengine_terminate_all(struct dma_chan *chan) +1. int dmaengine_terminate_sync(struct dma_chan *chan) + int dmaengine_terminate_async(struct dma_chan *chan) + int dmaengine_terminate_all(struct dma_chan *chan) /* DEPRECATED */ This causes all activity for the DMA channel to be stopped, and may discard data in the DMA FIFO which hasn't been fully transferred. No callback functions will be called for any incomplete transfers. + Two variants of this function are available. + + dmaengine_terminate_async() might not wait until the DMA has been fully + stopped or until any running complete callbacks have finished. But it is + possible to call dmaengine_terminate_async() from atomic context or from + within a complete callback. dmaengine_synchronize() must be called before it + is safe to free the memory accessed by the DMA transfer or free resources + accessed from within the complete callback. + + dmaengine_terminate_sync() will wait for the transfer and any running + complete callbacks to finish before it returns. But the function must not be + called from atomic context or from within a complete callback. + + dmaengine_terminate_all() is deprecated and should not be used in new code. + 2. int dmaengine_pause(struct dma_chan *chan) This pauses activity on the DMA channel without data loss. @@ -197,3 +214,20 @@ Further APIs: a running DMA channel. It is recommended that DMA engine users pause or stop (via dmaengine_terminate_all()) the channel before using this API. + +5. void dmaengine_synchronize(struct dma_chan *chan) + + Synchronize the termination of the DMA channel to the current context. + + This function should be used after dmaengine_terminate_async() to synchronize + the termination of the DMA channel to the current context. The function will + wait for the transfer and any running complete callbacks to finish before it + returns. + + If dmaengine_terminate_async() is used to stop the DMA channel this function + must be called before it is safe to free memory accessed by previously + submitted descriptors or to free any resources accessed within the complete + callback of previously submitted descriptors. + + The behavior of this function is undefined if dma_async_issue_pending() has + been called between dmaengine_terminate_async() and this function. diff --git a/Documentation/dmaengine/provider.txt b/Documentation/dmaengine/provider.txt index 67d4ce4df1096..122b7f4876bb6 100644 --- a/Documentation/dmaengine/provider.txt +++ b/Documentation/dmaengine/provider.txt @@ -327,8 +327,24 @@ supported. * device_terminate_all - Aborts all the pending and ongoing transfers on the channel - - This command should operate synchronously on the channel, - terminating right away all the channels + - For aborted transfers the complete callback should not be called + - Can be called from atomic context or from within a complete + callback of a descriptor. Must not sleep. Drivers must be able + to handle this correctly. + - Termination may be asynchronous. The driver does not have to + wait until the currently active transfer has completely stopped. + See device_synchronize. + + * device_synchronize + - Must synchronize the termination of a channel to the current + context. + - Must make sure that memory for previously submitted + descriptors is no longer accessed by the DMA controller. + - Must make sure that all complete callbacks for previously + submitted descriptors have finished running and none are + scheduled to run. + - May sleep. + Misc notes (stuff that should be documented, but don't really know where to put them) diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 3ecec1445adfc..d6fc82e3986f1 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -265,8 +265,11 @@ static void dma_chan_put(struct dma_chan *chan) module_put(dma_chan_to_owner(chan)); /* This channel is not in use anymore, free it */ - if (!chan->client_count && chan->device->device_free_chan_resources) + if (!chan->client_count && chan->device->device_free_chan_resources) { + /* Make sure all operations have completed */ + dmaengine_synchronize(chan); chan->device->device_free_chan_resources(chan); + } /* If the channel is used via a DMA request router, free the mapping */ if (chan->router && chan->router->route_free) { diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index c47c68e535e8d..4662d9aa6d5a5 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -654,6 +654,8 @@ enum dmaengine_alignment { * paused. Returns 0 or an error code * @device_terminate_all: Aborts all transfers on a channel. Returns 0 * or an error code + * @device_synchronize: Synchronizes the termination of a transfers to the + * current context. * @device_tx_status: poll for transaction completion, the optional * txstate parameter can be supplied with a pointer to get a * struct with auxiliary transfer status information, otherwise the call @@ -737,6 +739,7 @@ struct dma_device { int (*device_pause)(struct dma_chan *chan); int (*device_resume)(struct dma_chan *chan); int (*device_terminate_all)(struct dma_chan *chan); + void (*device_synchronize)(struct dma_chan *chan); enum dma_status (*device_tx_status)(struct dma_chan *chan, dma_cookie_t cookie, @@ -828,6 +831,13 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_sg( src_sg, src_nents, flags); } +/** + * dmaengine_terminate_all() - Terminate all active DMA transfers + * @chan: The channel for which to terminate the transfers + * + * This function is DEPRECATED use either dmaengine_terminate_sync() or + * dmaengine_terminate_async() instead. + */ static inline int dmaengine_terminate_all(struct dma_chan *chan) { if (chan->device->device_terminate_all) @@ -836,6 +846,86 @@ static inline int dmaengine_terminate_all(struct dma_chan *chan) return -ENOSYS; } +/** + * dmaengine_terminate_async() - Terminate all active DMA transfers + * @chan: The channel for which to terminate the transfers + * + * Calling this function will terminate all active and pending descriptors + * that have previously been submitted to the channel. It is not guaranteed + * though that the transfer for the active descriptor has stopped when the + * function returns. Furthermore it is possible the complete callback of a + * submitted transfer is still running when this function returns. + * + * dmaengine_synchronize() needs to be called before it is safe to free + * any memory that is accessed by previously submitted descriptors or before + * freeing any resources accessed from within the completion callback of any + * perviously submitted descriptors. + * + * This function can be called from atomic context as well as from within a + * complete callback of a descriptor submitted on the same channel. + * + * If none of the two conditions above apply consider using + * dmaengine_terminate_sync() instead. + */ +static inline int dmaengine_terminate_async(struct dma_chan *chan) +{ + if (chan->device->device_terminate_all) + return chan->device->device_terminate_all(chan); + + return -EINVAL; +} + +/** + * dmaengine_synchronize() - Synchronize DMA channel termination + * @chan: The channel to synchronize + * + * Synchronizes to the DMA channel termination to the current context. When this + * function returns it is guaranteed that all transfers for previously issued + * descriptors have stopped and and it is safe to free the memory assoicated + * with them. Furthermore it is guaranteed that all complete callback functions + * for a previously submitted descriptor have finished running and it is safe to + * free resources accessed from within the complete callbacks. + * + * The behavior of this function is undefined if dma_async_issue_pending() has + * been called between dmaengine_terminate_async() and this function. + * + * This function must only be called from non-atomic context and must not be + * called from within a complete callback of a descriptor submitted on the same + * channel. + */ +static inline void dmaengine_synchronize(struct dma_chan *chan) +{ + if (chan->device->device_synchronize) + chan->device->device_synchronize(chan); +} + +/** + * dmaengine_terminate_sync() - Terminate all active DMA transfers + * @chan: The channel for which to terminate the transfers + * + * Calling this function will terminate all active and pending transfers + * that have previously been submitted to the channel. It is similar to + * dmaengine_terminate_async() but guarantees that the DMA transfer has actually + * stopped and that all complete callbacks have finished running when the + * function returns. + * + * This function must only be called from non-atomic context and must not be + * called from within a complete callback of a descriptor submitted on the same + * channel. + */ +static inline int dmaengine_terminate_sync(struct dma_chan *chan) +{ + int ret; + + ret = dmaengine_terminate_async(chan); + if (ret) + return ret; + + dmaengine_synchronize(chan); + + return 0; +} + static inline int dmaengine_pause(struct dma_chan *chan) { if (chan->device->device_pause) -- GitLab From 2ed086296e60c3ca9a63a025701f4d104f4ced85 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 20 Oct 2015 11:46:29 +0200 Subject: [PATCH 0048/2855] dmaengine: virt-dma: Add synchronization helper function Add a synchronize helper function for the virt-dma library. The function makes sure that any scheduled descriptor complete callbacks have finished running before the function returns. This needs to be called by drivers using virt-dma in their device_synchronize() callback. Depending on the driver additional operations might be necessary in addition to calling vchan_synchronize() to ensure proper synchronization. Signed-off-by: Lars-Peter Clausen Signed-off-by: Vinod Koul --- drivers/dma/virt-dma.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/dma/virt-dma.h b/drivers/dma/virt-dma.h index 2fa47745a41f1..edbb5751572b5 100644 --- a/drivers/dma/virt-dma.h +++ b/drivers/dma/virt-dma.h @@ -151,4 +151,17 @@ static inline void vchan_free_chan_resources(struct virt_dma_chan *vc) vchan_dma_desc_free_list(vc, &head); } +/** + * vchan_synchronize() - synchronize callback execution to the current context + * @vc: virtual channel to synchronize + * + * Makes sure that all scheduled or active callbacks have finished running. For + * proper operation the caller has to ensure that no new callbacks are scheduled + * after the invocation of this function started. + */ +static inline void vchan_synchronize(struct virt_dma_chan *vc) +{ + tasklet_kill(&vc->task); +} + #endif -- GitLab From 860dd64c4382709a276eb4b7ef36596579dba04a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 20 Oct 2015 11:46:30 +0200 Subject: [PATCH 0049/2855] dmaengine: axi_dmac: Add synchronization support Implement the new device_synchronize() callback to allow proper synchronization when stopping a channel. Since the driver already makes sure that no new complete callbacks are scheduled after the device_terminate_all() callback has been called, all left to do in the device_synchronize() callback is to wait for all currently running complete callbacks to finish. Signed-off-by: Lars-Peter Clausen Signed-off-by: Vinod Koul --- drivers/dma/dma-axi-dmac.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c index 5b2395e7e04d8..c3468094393eb 100644 --- a/drivers/dma/dma-axi-dmac.c +++ b/drivers/dma/dma-axi-dmac.c @@ -307,6 +307,13 @@ static int axi_dmac_terminate_all(struct dma_chan *c) return 0; } +static void axi_dmac_synchronize(struct dma_chan *c) +{ + struct axi_dmac_chan *chan = to_axi_dmac_chan(c); + + vchan_synchronize(&chan->vchan); +} + static void axi_dmac_issue_pending(struct dma_chan *c) { struct axi_dmac_chan *chan = to_axi_dmac_chan(c); @@ -613,6 +620,7 @@ static int axi_dmac_probe(struct platform_device *pdev) dma_dev->device_prep_dma_cyclic = axi_dmac_prep_dma_cyclic; dma_dev->device_prep_interleaved_dma = axi_dmac_prep_interleaved; dma_dev->device_terminate_all = axi_dmac_terminate_all; + dma_dev->device_synchronize = axi_dmac_synchronize; dma_dev->dev = &pdev->dev; dma_dev->chancnt = 1; dma_dev->src_addr_widths = BIT(dmac->chan.src_width); -- GitLab From bc0e7345168c0f7483d2d1da86285d89136417cd Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 20 Oct 2015 11:46:31 +0200 Subject: [PATCH 0050/2855] ALSA: pcm_dmaengine: Properly synchronize DMA on shutdown Use the new dmaengine_synchronize() function to make sure that all complete callbacks have finished running before the runtime data, which is accessed in the completed callback, is freed. This fixes a long standing use-after-free race condition that has been observed on some systems. Signed-off-by: Lars-Peter Clausen Reviewed-by: Takashi Iwai Signed-off-by: Vinod Koul --- sound/core/pcm_dmaengine.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c index fba365a783909..697c166acf05e 100644 --- a/sound/core/pcm_dmaengine.c +++ b/sound/core/pcm_dmaengine.c @@ -202,13 +202,13 @@ int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd) if (runtime->info & SNDRV_PCM_INFO_PAUSE) dmaengine_pause(prtd->dma_chan); else - dmaengine_terminate_all(prtd->dma_chan); + dmaengine_terminate_async(prtd->dma_chan); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: dmaengine_pause(prtd->dma_chan); break; case SNDRV_PCM_TRIGGER_STOP: - dmaengine_terminate_all(prtd->dma_chan); + dmaengine_terminate_async(prtd->dma_chan); break; default: return -EINVAL; @@ -346,6 +346,7 @@ int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream) { struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); + dmaengine_synchronize(prtd->dma_chan); kfree(prtd); return 0; @@ -362,9 +363,11 @@ int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream) { struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); + dmaengine_synchronize(prtd->dma_chan); dma_release_channel(prtd->dma_chan); + kfree(prtd); - return snd_dmaengine_pcm_close(substream); + return 0; } EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close_release_chan); -- GitLab From 13bb26ae8850ede9cfb5ba20e646fe08e23aca97 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Tue, 13 Oct 2015 21:54:28 +0200 Subject: [PATCH 0051/2855] dmaengine: virt-dma: don't always free descriptor upon completion This patch attempts to enhance the case of a transfer submitted multiple times, and where the cost of creating the descriptors chain is not negligible. This happens with big video buffers (several megabytes, ie. several thousands of linked descriptors in one scatter-gather list). In these cases, a video driver would want to do : - tx = dmaengine_prep_slave_sg() - dma_engine_submit(tx); - dma_async_issue_pending() - wait for video completion - read video data (or not, skipping a frame is also possible) - dma_engine_submit(tx) => here, the descriptors chain recalculation will take time => the dma coherent allocation over and over might create holes in the dma pool, which is counter-productive. - dma_async_issue_pending() - etc ... In order to cope with this case, virt-dma is modified to prevent freeing the descriptors upon completion if DMA_CTRL_REUSE flag is set in the transfer. This patch is a respin of the former DMA_CTRL_ACK approach, which was reverted due to a regression in audio drivers. Signed-off-by: Robert Jarzmik Signed-off-by: Vinod Koul --- drivers/dma/virt-dma.c | 46 ++++++++++++++++++++++++++++++++++++------ drivers/dma/virt-dma.h | 12 +++++++++++ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/drivers/dma/virt-dma.c b/drivers/dma/virt-dma.c index 6f80432a3f0a3..a35c211857dd6 100644 --- a/drivers/dma/virt-dma.c +++ b/drivers/dma/virt-dma.c @@ -29,7 +29,7 @@ dma_cookie_t vchan_tx_submit(struct dma_async_tx_descriptor *tx) spin_lock_irqsave(&vc->lock, flags); cookie = dma_cookie_assign(tx); - list_add_tail(&vd->node, &vc->desc_submitted); + list_move_tail(&vd->node, &vc->desc_submitted); spin_unlock_irqrestore(&vc->lock, flags); dev_dbg(vc->chan.device->dev, "vchan %p: txd %p[%x]: submitted\n", @@ -39,6 +39,33 @@ dma_cookie_t vchan_tx_submit(struct dma_async_tx_descriptor *tx) } EXPORT_SYMBOL_GPL(vchan_tx_submit); +/** + * vchan_tx_desc_free - free a reusable descriptor + * @tx: the transfer + * + * This function frees a previously allocated reusable descriptor. The only + * other way is to clear the DMA_CTRL_REUSE flag and submit one last time the + * transfer. + * + * Returns 0 upon success + */ +int vchan_tx_desc_free(struct dma_async_tx_descriptor *tx) +{ + struct virt_dma_chan *vc = to_virt_chan(tx->chan); + struct virt_dma_desc *vd = to_virt_desc(tx); + unsigned long flags; + + spin_lock_irqsave(&vc->lock, flags); + list_del(&vd->node); + spin_unlock_irqrestore(&vc->lock, flags); + + dev_dbg(vc->chan.device->dev, "vchan %p: txd %p[%x]: freeing\n", + vc, vd, vd->tx.cookie); + vc->desc_free(vd); + return 0; +} +EXPORT_SYMBOL_GPL(vchan_tx_desc_free); + struct virt_dma_desc *vchan_find_desc(struct virt_dma_chan *vc, dma_cookie_t cookie) { @@ -83,8 +110,10 @@ static void vchan_complete(unsigned long arg) cb_data = vd->tx.callback_param; list_del(&vd->node); - - vc->desc_free(vd); + if (dmaengine_desc_test_reuse(&vd->tx)) + list_add(&vd->node, &vc->desc_allocated); + else + vc->desc_free(vd); if (cb) cb(cb_data); @@ -96,9 +125,13 @@ void vchan_dma_desc_free_list(struct virt_dma_chan *vc, struct list_head *head) while (!list_empty(head)) { struct virt_dma_desc *vd = list_first_entry(head, struct virt_dma_desc, node); - list_del(&vd->node); - dev_dbg(vc->chan.device->dev, "txd %p: freeing\n", vd); - vc->desc_free(vd); + if (dmaengine_desc_test_reuse(&vd->tx)) { + list_move_tail(&vd->node, &vc->desc_allocated); + } else { + dev_dbg(vc->chan.device->dev, "txd %p: freeing\n", vd); + list_del(&vd->node); + vc->desc_free(vd); + } } } EXPORT_SYMBOL_GPL(vchan_dma_desc_free_list); @@ -108,6 +141,7 @@ void vchan_init(struct virt_dma_chan *vc, struct dma_device *dmadev) dma_cookie_init(&vc->chan); spin_lock_init(&vc->lock); + INIT_LIST_HEAD(&vc->desc_allocated); INIT_LIST_HEAD(&vc->desc_submitted); INIT_LIST_HEAD(&vc->desc_issued); INIT_LIST_HEAD(&vc->desc_completed); diff --git a/drivers/dma/virt-dma.h b/drivers/dma/virt-dma.h index 2fa47745a41f1..bff8c39dd7167 100644 --- a/drivers/dma/virt-dma.h +++ b/drivers/dma/virt-dma.h @@ -29,6 +29,7 @@ struct virt_dma_chan { spinlock_t lock; /* protected by vc.lock */ + struct list_head desc_allocated; struct list_head desc_submitted; struct list_head desc_issued; struct list_head desc_completed; @@ -55,10 +56,17 @@ static inline struct dma_async_tx_descriptor *vchan_tx_prep(struct virt_dma_chan struct virt_dma_desc *vd, unsigned long tx_flags) { extern dma_cookie_t vchan_tx_submit(struct dma_async_tx_descriptor *); + extern int vchan_tx_desc_free(struct dma_async_tx_descriptor *); + unsigned long flags; dma_async_tx_descriptor_init(&vd->tx, &vc->chan); vd->tx.flags = tx_flags; vd->tx.tx_submit = vchan_tx_submit; + vd->tx.desc_free = vchan_tx_desc_free; + + spin_lock_irqsave(&vc->lock, flags); + list_add_tail(&vd->node, &vc->desc_allocated); + spin_unlock_irqrestore(&vc->lock, flags); return &vd->tx; } @@ -134,6 +142,7 @@ static inline struct virt_dma_desc *vchan_next_desc(struct virt_dma_chan *vc) static inline void vchan_get_all_descriptors(struct virt_dma_chan *vc, struct list_head *head) { + list_splice_tail_init(&vc->desc_allocated, head); list_splice_tail_init(&vc->desc_submitted, head); list_splice_tail_init(&vc->desc_issued, head); list_splice_tail_init(&vc->desc_completed, head); @@ -141,11 +150,14 @@ static inline void vchan_get_all_descriptors(struct virt_dma_chan *vc, static inline void vchan_free_chan_resources(struct virt_dma_chan *vc) { + struct virt_dma_desc *vd; unsigned long flags; LIST_HEAD(head); spin_lock_irqsave(&vc->lock, flags); vchan_get_all_descriptors(vc, &head); + list_for_each_entry(vd, &head, node) + dmaengine_desc_clear_reuse(&vd->tx); spin_unlock_irqrestore(&vc->lock, flags); vchan_dma_desc_free_list(vc, &head); -- GitLab From 9eeacd3a2f17438d9d286ff2f78c4709a4148be7 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Tue, 13 Oct 2015 21:54:29 +0200 Subject: [PATCH 0052/2855] dmaengine: enable DMA_CTRL_REUSE In the current state, the capability of transfer reuse can neither be set by a slave dmaengine driver, nor used by a client driver, because the capability is not available to dma_get_slave_caps(). Fix this by adding a way to declare the capability. Fixes: 272420214d26 ("dmaengine: Add DMA_CTRL_REUSE") Signed-off-by: Robert Jarzmik Signed-off-by: Vinod Koul --- drivers/dma/dmaengine.c | 1 + include/linux/dmaengine.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 3ecec1445adfc..4aced66897348 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -493,6 +493,7 @@ int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps) caps->dst_addr_widths = device->dst_addr_widths; caps->directions = device->directions; caps->residue_granularity = device->residue_granularity; + caps->descriptor_reuse = device->descriptor_reuse; /* * Some devices implement only pause (e.g. to get residuum) but no diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index c47c68e535e8d..6f94b5cbd97c1 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -659,6 +659,7 @@ enum dmaengine_alignment { * struct with auxiliary transfer status information, otherwise the call * will just return a simple status code * @device_issue_pending: push pending transactions to hardware + * @descriptor_reuse: a submitted transfer can be resubmitted after completion */ struct dma_device { @@ -681,6 +682,7 @@ struct dma_device { u32 src_addr_widths; u32 dst_addr_widths; u32 directions; + bool descriptor_reuse; enum dma_residue_granularity residue_granularity; int (*device_alloc_chan_resources)(struct dma_chan *chan); -- GitLab From d3651b8e5cdf8773a7d74839e53454e4a0d48ffe Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Tue, 13 Oct 2015 21:54:30 +0200 Subject: [PATCH 0053/2855] dmaengine: pxa_dma: declare transfer are reusable As this driver provides a mechanism to reuse transfers, declare it in its probe function. Signed-off-by: Robert Jarzmik Signed-off-by: Vinod Koul --- drivers/dma/pxa_dma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c index fc4156afa0703..f2a0310ae7718 100644 --- a/drivers/dma/pxa_dma.c +++ b/drivers/dma/pxa_dma.c @@ -1414,6 +1414,7 @@ static int pxad_probe(struct platform_device *op) pdev->slave.dst_addr_widths = widths; pdev->slave.directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM); pdev->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; + pdev->slave.descriptor_reuse = true; pdev->slave.dev = &op->dev; ret = pxad_init_dmadev(op, pdev, dma_channels); -- GitLab From 5827a4bae95b943f2d7dc9b33957c83a69f256eb Mon Sep 17 00:00:00 2001 From: M'boumba Cedric Madianga Date: Fri, 16 Oct 2015 15:59:13 +0200 Subject: [PATCH 0054/2855] dt-bindings: Document the STM32 DMA bindings This patch adds documentation of device tree bindings for the STM32 dma controller. Signed-off-by: M'boumba Cedric Madianga Acked-by: Rob Herring Signed-off-by: Vinod Koul --- .../devicetree/bindings/dma/stm32-dma.txt | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 Documentation/devicetree/bindings/dma/stm32-dma.txt diff --git a/Documentation/devicetree/bindings/dma/stm32-dma.txt b/Documentation/devicetree/bindings/dma/stm32-dma.txt new file mode 100644 index 0000000000000..70cd13f1588ab --- /dev/null +++ b/Documentation/devicetree/bindings/dma/stm32-dma.txt @@ -0,0 +1,82 @@ +* STMicroelectronics STM32 DMA controller + +The STM32 DMA is a general-purpose direct memory access controller capable of +supporting 8 independent DMA channels. Each channel can have up to 8 requests. + +Required properties: +- compatible: Should be "st,stm32-dma" +- reg: Should contain DMA registers location and length. This should include + all of the per-channel registers. +- interrupts: Should contain all of the per-channel DMA interrupts in + ascending order with respect to the DMA channel index. +- clocks: Should contain the input clock of the DMA instance. +- #dma-cells : Must be <4>. See DMA client paragraph for more details. + +Optional properties: +- resets: Reference to a reset controller asserting the DMA controller +- st,mem2mem: boolean; if defined, it indicates that the controller supports + memory-to-memory transfer + +Example: + + dma2: dma-controller@40026400 { + compatible = "st,stm32-dma"; + reg = <0x40026400 0x400>; + interrupts = <56>, + <57>, + <58>, + <59>, + <60>, + <68>, + <69>, + <70>; + clocks = <&clk_hclk>; + #dma-cells = <4>; + st,mem2mem; + resets = <&rcc 150>; + }; + +* DMA client + +DMA clients connected to the STM32 DMA controller must use the format +described in the dma.txt file, using a five-cell specifier for each +channel: a phandle plus four integer cells. +The four cells in order are: + +1. The channel id +2. The request line number +3. A 32bit mask specifying the DMA channel configuration which are device + dependent: + -bit 9: Peripheral Increment Address + 0x0: no address increment between transfers + 0x1: increment address between transfers + -bit 10: Memory Increment Address + 0x0: no address increment between transfers + 0x1: increment address between transfers + -bit 15: Peripheral Increment Offset Size + 0x0: offset size is linked to the peripheral bus width + 0x1: offset size is fixed to 4 (32-bit alignment) + -bit 16-17: Priority level + 0x0: low + 0x1: medium + 0x2: high + 0x3: very high +5. A 32bit mask specifying the DMA FIFO threshold configuration which are device + dependent: + -bit 0-1: Fifo threshold + 0x0: 1/4 full FIFO + 0x1: 1/2 full FIFO + 0x2: 3/4 full FIFO + 0x3: full FIFO + +Example: + + usart1: serial@40011000 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x40011000 0x400>; + interrupts = <37>; + clocks = <&clk_pclk2>; + dmas = <&dma2 2 4 0x10400 0x3>, + <&dma2 7 5 0x10200 0x3>; + dma-names = "rx", "tx"; + }; -- GitLab From d8b468394fb711b077742a5234504c632525a47f Mon Sep 17 00:00:00 2001 From: M'boumba Cedric Madianga Date: Fri, 16 Oct 2015 15:59:14 +0200 Subject: [PATCH 0055/2855] dmaengine: Add STM32 DMA driver This patch adds support for the STM32 DMA controller. Signed-off-by: M'boumba Cedric Madianga Signed-off-by: Vinod Koul --- drivers/dma/Kconfig | 12 + drivers/dma/Makefile | 1 + drivers/dma/stm32-dma.c | 1141 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 1154 insertions(+) create mode 100644 drivers/dma/stm32-dma.c diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index e6cd1a32025a9..3a8ce67910c29 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -431,6 +431,18 @@ config STE_DMA40 help Support for ST-Ericsson DMA40 controller +config STM32_DMA + bool "STMicroelectronics STM32 DMA support" + depends on ARCH_STM32 + select DMA_ENGINE + select DMA_OF + select DMA_VIRTUAL_CHANNELS + help + Enable support for the on-chip DMA controller on STMicroelectronics + STM32 MCUs. + If you have a board based on such a MCU and wish to use DMA say Y or M + here. + config S3C24XX_DMAC tristate "Samsung S3C24XX DMA support" depends on ARCH_S3C24XX diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index ef9c099bd2b6c..2dd0a067a0caa 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -56,6 +56,7 @@ obj-$(CONFIG_QCOM_BAM_DMA) += qcom_bam_dma.o obj-$(CONFIG_RENESAS_DMA) += sh/ obj-$(CONFIG_SIRF_DMA) += sirf-dma.o obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o +obj-$(CONFIG_STM32_DMA) += stm32-dma.o obj-$(CONFIG_S3C24XX_DMAC) += s3c24xx-dma.o obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c new file mode 100644 index 0000000000000..12f3a3eddba92 --- /dev/null +++ b/drivers/dma/stm32-dma.c @@ -0,0 +1,1141 @@ +/* + * Driver for STM32 DMA controller + * + * Inspired by dma-jz4740.c and tegra20-apb-dma.c + * + * Copyright (C) M'boumba Cedric Madianga 2015 + * Author: M'boumba Cedric Madianga + * + * License terms: GNU General Public License (GPL), version 2 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "virt-dma.h" + +#define STM32_DMA_LISR 0x0000 /* DMA Low Int Status Reg */ +#define STM32_DMA_HISR 0x0004 /* DMA High Int Status Reg */ +#define STM32_DMA_LIFCR 0x0008 /* DMA Low Int Flag Clear Reg */ +#define STM32_DMA_HIFCR 0x000c /* DMA High Int Flag Clear Reg */ +#define STM32_DMA_TCI BIT(5) /* Transfer Complete Interrupt */ +#define STM32_DMA_TEI BIT(3) /* Transfer Error Interrupt */ +#define STM32_DMA_DMEI BIT(2) /* Direct Mode Error Interrupt */ +#define STM32_DMA_FEI BIT(0) /* FIFO Error Interrupt */ + +/* DMA Stream x Configuration Register */ +#define STM32_DMA_SCR(x) (0x0010 + 0x18 * (x)) /* x = 0..7 */ +#define STM32_DMA_SCR_REQ(n) ((n & 0x7) << 25) +#define STM32_DMA_SCR_MBURST_MASK GENMASK(24, 23) +#define STM32_DMA_SCR_MBURST(n) ((n & 0x3) << 23) +#define STM32_DMA_SCR_PBURST_MASK GENMASK(22, 21) +#define STM32_DMA_SCR_PBURST(n) ((n & 0x3) << 21) +#define STM32_DMA_SCR_PL_MASK GENMASK(17, 16) +#define STM32_DMA_SCR_PL(n) ((n & 0x3) << 16) +#define STM32_DMA_SCR_MSIZE_MASK GENMASK(14, 13) +#define STM32_DMA_SCR_MSIZE(n) ((n & 0x3) << 13) +#define STM32_DMA_SCR_PSIZE_MASK GENMASK(12, 11) +#define STM32_DMA_SCR_PSIZE(n) ((n & 0x3) << 11) +#define STM32_DMA_SCR_PSIZE_GET(n) ((n & STM32_DMA_SCR_PSIZE_MASK) >> 11) +#define STM32_DMA_SCR_DIR_MASK GENMASK(7, 6) +#define STM32_DMA_SCR_DIR(n) ((n & 0x3) << 6) +#define STM32_DMA_SCR_CT BIT(19) /* Target in double buffer */ +#define STM32_DMA_SCR_DBM BIT(18) /* Double Buffer Mode */ +#define STM32_DMA_SCR_PINCOS BIT(15) /* Peripheral inc offset size */ +#define STM32_DMA_SCR_MINC BIT(10) /* Memory increment mode */ +#define STM32_DMA_SCR_PINC BIT(9) /* Peripheral increment mode */ +#define STM32_DMA_SCR_CIRC BIT(8) /* Circular mode */ +#define STM32_DMA_SCR_PFCTRL BIT(5) /* Peripheral Flow Controller */ +#define STM32_DMA_SCR_TCIE BIT(4) /* Transfer Cplete Int Enable*/ +#define STM32_DMA_SCR_TEIE BIT(2) /* Transfer Error Int Enable */ +#define STM32_DMA_SCR_DMEIE BIT(1) /* Direct Mode Err Int Enable */ +#define STM32_DMA_SCR_EN BIT(0) /* Stream Enable */ +#define STM32_DMA_SCR_CFG_MASK (STM32_DMA_SCR_PINC \ + | STM32_DMA_SCR_MINC \ + | STM32_DMA_SCR_PINCOS \ + | STM32_DMA_SCR_PL_MASK) +#define STM32_DMA_SCR_IRQ_MASK (STM32_DMA_SCR_TCIE \ + | STM32_DMA_SCR_TEIE \ + | STM32_DMA_SCR_DMEIE) + +/* DMA Stream x number of data register */ +#define STM32_DMA_SNDTR(x) (0x0014 + 0x18 * (x)) + +/* DMA stream peripheral address register */ +#define STM32_DMA_SPAR(x) (0x0018 + 0x18 * (x)) + +/* DMA stream x memory 0 address register */ +#define STM32_DMA_SM0AR(x) (0x001c + 0x18 * (x)) + +/* DMA stream x memory 1 address register */ +#define STM32_DMA_SM1AR(x) (0x0020 + 0x18 * (x)) + +/* DMA stream x FIFO control register */ +#define STM32_DMA_SFCR(x) (0x0024 + 0x18 * (x)) +#define STM32_DMA_SFCR_FTH_MASK GENMASK(1, 0) +#define STM32_DMA_SFCR_FTH(n) (n & STM32_DMA_SFCR_FTH_MASK) +#define STM32_DMA_SFCR_FEIE BIT(7) /* FIFO error interrupt enable */ +#define STM32_DMA_SFCR_DMDIS BIT(2) /* Direct mode disable */ +#define STM32_DMA_SFCR_MASK (STM32_DMA_SFCR_FEIE \ + | STM32_DMA_SFCR_DMDIS) + +/* DMA direction */ +#define STM32_DMA_DEV_TO_MEM 0x00 +#define STM32_DMA_MEM_TO_DEV 0x01 +#define STM32_DMA_MEM_TO_MEM 0x02 + +/* DMA priority level */ +#define STM32_DMA_PRIORITY_LOW 0x00 +#define STM32_DMA_PRIORITY_MEDIUM 0x01 +#define STM32_DMA_PRIORITY_HIGH 0x02 +#define STM32_DMA_PRIORITY_VERY_HIGH 0x03 + +/* DMA FIFO threshold selection */ +#define STM32_DMA_FIFO_THRESHOLD_1QUARTERFULL 0x00 +#define STM32_DMA_FIFO_THRESHOLD_HALFFULL 0x01 +#define STM32_DMA_FIFO_THRESHOLD_3QUARTERSFULL 0x02 +#define STM32_DMA_FIFO_THRESHOLD_FULL 0x03 + +#define STM32_DMA_MAX_DATA_ITEMS 0xffff +#define STM32_DMA_MAX_CHANNELS 0x08 +#define STM32_DMA_MAX_REQUEST_ID 0x08 +#define STM32_DMA_MAX_DATA_PARAM 0x03 + +enum stm32_dma_width { + STM32_DMA_BYTE, + STM32_DMA_HALF_WORD, + STM32_DMA_WORD, +}; + +enum stm32_dma_burst_size { + STM32_DMA_BURST_SINGLE, + STM32_DMA_BURST_INCR4, + STM32_DMA_BURST_INCR8, + STM32_DMA_BURST_INCR16, +}; + +struct stm32_dma_cfg { + u32 channel_id; + u32 request_line; + u32 stream_config; + u32 threshold; +}; + +struct stm32_dma_chan_reg { + u32 dma_lisr; + u32 dma_hisr; + u32 dma_lifcr; + u32 dma_hifcr; + u32 dma_scr; + u32 dma_sndtr; + u32 dma_spar; + u32 dma_sm0ar; + u32 dma_sm1ar; + u32 dma_sfcr; +}; + +struct stm32_dma_sg_req { + u32 len; + struct stm32_dma_chan_reg chan_reg; +}; + +struct stm32_dma_desc { + struct virt_dma_desc vdesc; + bool cyclic; + u32 num_sgs; + struct stm32_dma_sg_req sg_req[]; +}; + +struct stm32_dma_chan { + struct virt_dma_chan vchan; + bool config_init; + bool busy; + u32 id; + u32 irq; + struct stm32_dma_desc *desc; + u32 next_sg; + struct dma_slave_config dma_sconfig; + struct stm32_dma_chan_reg chan_reg; +}; + +struct stm32_dma_device { + struct dma_device ddev; + void __iomem *base; + struct clk *clk; + struct reset_control *rst; + bool mem2mem; + struct stm32_dma_chan chan[STM32_DMA_MAX_CHANNELS]; +}; + +static struct stm32_dma_device *stm32_dma_get_dev(struct stm32_dma_chan *chan) +{ + return container_of(chan->vchan.chan.device, struct stm32_dma_device, + ddev); +} + +static struct stm32_dma_chan *to_stm32_dma_chan(struct dma_chan *c) +{ + return container_of(c, struct stm32_dma_chan, vchan.chan); +} + +static struct stm32_dma_desc *to_stm32_dma_desc(struct virt_dma_desc *vdesc) +{ + return container_of(vdesc, struct stm32_dma_desc, vdesc); +} + +static struct device *chan2dev(struct stm32_dma_chan *chan) +{ + return &chan->vchan.chan.dev->device; +} + +static u32 stm32_dma_read(struct stm32_dma_device *dmadev, u32 reg) +{ + return readl_relaxed(dmadev->base + reg); +} + +static void stm32_dma_write(struct stm32_dma_device *dmadev, u32 reg, u32 val) +{ + writel_relaxed(val, dmadev->base + reg); +} + +static struct stm32_dma_desc *stm32_dma_alloc_desc(u32 num_sgs) +{ + return kzalloc(sizeof(struct stm32_dma_desc) + + sizeof(struct stm32_dma_sg_req) * num_sgs, GFP_NOWAIT); +} + +static int stm32_dma_get_width(struct stm32_dma_chan *chan, + enum dma_slave_buswidth width) +{ + switch (width) { + case DMA_SLAVE_BUSWIDTH_1_BYTE: + return STM32_DMA_BYTE; + case DMA_SLAVE_BUSWIDTH_2_BYTES: + return STM32_DMA_HALF_WORD; + case DMA_SLAVE_BUSWIDTH_4_BYTES: + return STM32_DMA_WORD; + default: + dev_err(chan2dev(chan), "Dma bus width not supported\n"); + return -EINVAL; + } +} + +static int stm32_dma_get_burst(struct stm32_dma_chan *chan, u32 maxburst) +{ + switch (maxburst) { + case 0: + case 1: + return STM32_DMA_BURST_SINGLE; + case 4: + return STM32_DMA_BURST_INCR4; + case 8: + return STM32_DMA_BURST_INCR8; + case 16: + return STM32_DMA_BURST_INCR16; + default: + dev_err(chan2dev(chan), "Dma burst size not supported\n"); + return -EINVAL; + } +} + +static void stm32_dma_set_fifo_config(struct stm32_dma_chan *chan, + u32 src_maxburst, u32 dst_maxburst) +{ + chan->chan_reg.dma_sfcr &= ~STM32_DMA_SFCR_MASK; + chan->chan_reg.dma_scr &= ~STM32_DMA_SCR_DMEIE; + + if ((!src_maxburst) && (!dst_maxburst)) { + /* Using direct mode */ + chan->chan_reg.dma_scr |= STM32_DMA_SCR_DMEIE; + } else { + /* Using FIFO mode */ + chan->chan_reg.dma_sfcr |= STM32_DMA_SFCR_MASK; + } +} + +static int stm32_dma_slave_config(struct dma_chan *c, + struct dma_slave_config *config) +{ + struct stm32_dma_chan *chan = to_stm32_dma_chan(c); + + memcpy(&chan->dma_sconfig, config, sizeof(*config)); + + chan->config_init = true; + + return 0; +} + +static u32 stm32_dma_irq_status(struct stm32_dma_chan *chan) +{ + struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); + u32 flags, dma_isr; + + /* + * Read "flags" from DMA_xISR register corresponding to the selected + * DMA channel at the correct bit offset inside that register. + * + * If (ch % 4) is 2 or 3, left shift the mask by 16 bits. + * If (ch % 4) is 1 or 3, additionally left shift the mask by 6 bits. + */ + + if (chan->id & 4) + dma_isr = stm32_dma_read(dmadev, STM32_DMA_HISR); + else + dma_isr = stm32_dma_read(dmadev, STM32_DMA_LISR); + + flags = dma_isr >> (((chan->id & 2) << 3) | ((chan->id & 1) * 6)); + + return flags; +} + +static void stm32_dma_irq_clear(struct stm32_dma_chan *chan, u32 flags) +{ + struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); + u32 dma_ifcr; + + /* + * Write "flags" to the DMA_xIFCR register corresponding to the selected + * DMA channel at the correct bit offset inside that register. + * + * If (ch % 4) is 2 or 3, left shift the mask by 16 bits. + * If (ch % 4) is 1 or 3, additionally left shift the mask by 6 bits. + */ + dma_ifcr = flags << (((chan->id & 2) << 3) | ((chan->id & 1) * 6)); + + if (chan->id & 4) + stm32_dma_write(dmadev, STM32_DMA_HIFCR, dma_ifcr); + else + stm32_dma_write(dmadev, STM32_DMA_LIFCR, dma_ifcr); +} + +static int stm32_dma_disable_chan(struct stm32_dma_chan *chan) +{ + struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); + unsigned long timeout = jiffies + msecs_to_jiffies(5000); + u32 dma_scr, id; + + id = chan->id; + dma_scr = stm32_dma_read(dmadev, STM32_DMA_SCR(id)); + + if (dma_scr & STM32_DMA_SCR_EN) { + dma_scr &= ~STM32_DMA_SCR_EN; + stm32_dma_write(dmadev, STM32_DMA_SCR(id), dma_scr); + + do { + dma_scr = stm32_dma_read(dmadev, STM32_DMA_SCR(id)); + dma_scr &= STM32_DMA_SCR_EN; + if (!dma_scr) + break; + + if (time_after_eq(jiffies, timeout)) { + dev_err(chan2dev(chan), "%s: timeout!\n", + __func__); + return -EBUSY; + } + cond_resched(); + } while (1); + } + + return 0; +} + +static void stm32_dma_stop(struct stm32_dma_chan *chan) +{ + struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); + u32 dma_scr, dma_sfcr, status; + int ret; + + /* Disable interrupts */ + dma_scr = stm32_dma_read(dmadev, STM32_DMA_SCR(chan->id)); + dma_scr &= ~STM32_DMA_SCR_IRQ_MASK; + stm32_dma_write(dmadev, STM32_DMA_SCR(chan->id), dma_scr); + dma_sfcr = stm32_dma_read(dmadev, STM32_DMA_SFCR(chan->id)); + dma_sfcr &= ~STM32_DMA_SFCR_FEIE; + stm32_dma_write(dmadev, STM32_DMA_SFCR(chan->id), dma_sfcr); + + /* Disable DMA */ + ret = stm32_dma_disable_chan(chan); + if (ret < 0) + return; + + /* Clear interrupt status if it is there */ + status = stm32_dma_irq_status(chan); + if (status) { + dev_dbg(chan2dev(chan), "%s(): clearing interrupt: 0x%08x\n", + __func__, status); + stm32_dma_irq_clear(chan, status); + } + + chan->busy = false; +} + +static int stm32_dma_terminate_all(struct dma_chan *c) +{ + struct stm32_dma_chan *chan = to_stm32_dma_chan(c); + unsigned long flags; + LIST_HEAD(head); + + spin_lock_irqsave(&chan->vchan.lock, flags); + + if (chan->busy) { + stm32_dma_stop(chan); + chan->desc = NULL; + } + + vchan_get_all_descriptors(&chan->vchan, &head); + spin_unlock_irqrestore(&chan->vchan.lock, flags); + vchan_dma_desc_free_list(&chan->vchan, &head); + + return 0; +} + +static void stm32_dma_dump_reg(struct stm32_dma_chan *chan) +{ + struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); + u32 scr = stm32_dma_read(dmadev, STM32_DMA_SCR(chan->id)); + u32 ndtr = stm32_dma_read(dmadev, STM32_DMA_SNDTR(chan->id)); + u32 spar = stm32_dma_read(dmadev, STM32_DMA_SPAR(chan->id)); + u32 sm0ar = stm32_dma_read(dmadev, STM32_DMA_SM0AR(chan->id)); + u32 sm1ar = stm32_dma_read(dmadev, STM32_DMA_SM1AR(chan->id)); + u32 sfcr = stm32_dma_read(dmadev, STM32_DMA_SFCR(chan->id)); + + dev_dbg(chan2dev(chan), "SCR: 0x%08x\n", scr); + dev_dbg(chan2dev(chan), "NDTR: 0x%08x\n", ndtr); + dev_dbg(chan2dev(chan), "SPAR: 0x%08x\n", spar); + dev_dbg(chan2dev(chan), "SM0AR: 0x%08x\n", sm0ar); + dev_dbg(chan2dev(chan), "SM1AR: 0x%08x\n", sm1ar); + dev_dbg(chan2dev(chan), "SFCR: 0x%08x\n", sfcr); +} + +static int stm32_dma_start_transfer(struct stm32_dma_chan *chan) +{ + struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); + struct virt_dma_desc *vdesc; + struct stm32_dma_sg_req *sg_req; + struct stm32_dma_chan_reg *reg; + u32 status; + int ret; + + ret = stm32_dma_disable_chan(chan); + if (ret < 0) + return ret; + + if (!chan->desc) { + vdesc = vchan_next_desc(&chan->vchan); + if (!vdesc) + return 0; + + chan->desc = to_stm32_dma_desc(vdesc); + chan->next_sg = 0; + } + + if (chan->next_sg == chan->desc->num_sgs) + chan->next_sg = 0; + + sg_req = &chan->desc->sg_req[chan->next_sg]; + reg = &sg_req->chan_reg; + + stm32_dma_write(dmadev, STM32_DMA_SCR(chan->id), reg->dma_scr); + stm32_dma_write(dmadev, STM32_DMA_SPAR(chan->id), reg->dma_spar); + stm32_dma_write(dmadev, STM32_DMA_SM0AR(chan->id), reg->dma_sm0ar); + stm32_dma_write(dmadev, STM32_DMA_SFCR(chan->id), reg->dma_sfcr); + stm32_dma_write(dmadev, STM32_DMA_SM1AR(chan->id), reg->dma_sm1ar); + stm32_dma_write(dmadev, STM32_DMA_SNDTR(chan->id), reg->dma_sndtr); + + chan->next_sg++; + + /* Clear interrupt status if it is there */ + status = stm32_dma_irq_status(chan); + if (status) + stm32_dma_irq_clear(chan, status); + + stm32_dma_dump_reg(chan); + + /* Start DMA */ + reg->dma_scr |= STM32_DMA_SCR_EN; + stm32_dma_write(dmadev, STM32_DMA_SCR(chan->id), reg->dma_scr); + + chan->busy = true; + + return 0; +} + +static void stm32_dma_configure_next_sg(struct stm32_dma_chan *chan) +{ + struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); + struct stm32_dma_sg_req *sg_req; + u32 dma_scr, dma_sm0ar, dma_sm1ar, id; + + id = chan->id; + dma_scr = stm32_dma_read(dmadev, STM32_DMA_SCR(id)); + + if (dma_scr & STM32_DMA_SCR_DBM) { + if (chan->next_sg == chan->desc->num_sgs) + chan->next_sg = 0; + + sg_req = &chan->desc->sg_req[chan->next_sg]; + + if (dma_scr & STM32_DMA_SCR_CT) { + dma_sm0ar = sg_req->chan_reg.dma_sm0ar; + stm32_dma_write(dmadev, STM32_DMA_SM0AR(id), dma_sm0ar); + dev_dbg(chan2dev(chan), "CT=1 <=> SM0AR: 0x%08x\n", + stm32_dma_read(dmadev, STM32_DMA_SM0AR(id))); + } else { + dma_sm1ar = sg_req->chan_reg.dma_sm1ar; + stm32_dma_write(dmadev, STM32_DMA_SM1AR(id), dma_sm1ar); + dev_dbg(chan2dev(chan), "CT=0 <=> SM1AR: 0x%08x\n", + stm32_dma_read(dmadev, STM32_DMA_SM1AR(id))); + } + + chan->next_sg++; + } +} + +static void stm32_dma_handle_chan_done(struct stm32_dma_chan *chan) +{ + if (chan->desc) { + if (chan->desc->cyclic) { + vchan_cyclic_callback(&chan->desc->vdesc); + stm32_dma_configure_next_sg(chan); + } else { + chan->busy = false; + if (chan->next_sg == chan->desc->num_sgs) { + list_del(&chan->desc->vdesc.node); + vchan_cookie_complete(&chan->desc->vdesc); + chan->desc = NULL; + } + stm32_dma_start_transfer(chan); + } + } +} + +static irqreturn_t stm32_dma_chan_irq(int irq, void *devid) +{ + struct stm32_dma_chan *chan = devid; + struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); + u32 status, scr, sfcr; + + spin_lock(&chan->vchan.lock); + + status = stm32_dma_irq_status(chan); + scr = stm32_dma_read(dmadev, STM32_DMA_SCR(chan->id)); + sfcr = stm32_dma_read(dmadev, STM32_DMA_SFCR(chan->id)); + + if ((status & STM32_DMA_TCI) && (scr & STM32_DMA_SCR_TCIE)) { + stm32_dma_irq_clear(chan, STM32_DMA_TCI); + stm32_dma_handle_chan_done(chan); + + } else { + stm32_dma_irq_clear(chan, status); + dev_err(chan2dev(chan), "DMA error: status=0x%08x\n", status); + } + + spin_unlock(&chan->vchan.lock); + + return IRQ_HANDLED; +} + +static void stm32_dma_issue_pending(struct dma_chan *c) +{ + struct stm32_dma_chan *chan = to_stm32_dma_chan(c); + unsigned long flags; + int ret; + + spin_lock_irqsave(&chan->vchan.lock, flags); + if (!chan->busy) { + if (vchan_issue_pending(&chan->vchan) && !chan->desc) { + ret = stm32_dma_start_transfer(chan); + if ((chan->desc->cyclic) && (!ret)) + stm32_dma_configure_next_sg(chan); + } + } + spin_unlock_irqrestore(&chan->vchan.lock, flags); +} + +static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan, + enum dma_transfer_direction direction, + enum dma_slave_buswidth *buswidth) +{ + enum dma_slave_buswidth src_addr_width, dst_addr_width; + int src_bus_width, dst_bus_width; + int src_burst_size, dst_burst_size; + u32 src_maxburst, dst_maxburst; + dma_addr_t src_addr, dst_addr; + u32 dma_scr = 0; + + src_addr_width = chan->dma_sconfig.src_addr_width; + dst_addr_width = chan->dma_sconfig.dst_addr_width; + src_maxburst = chan->dma_sconfig.src_maxburst; + dst_maxburst = chan->dma_sconfig.dst_maxburst; + src_addr = chan->dma_sconfig.src_addr; + dst_addr = chan->dma_sconfig.dst_addr; + + switch (direction) { + case DMA_MEM_TO_DEV: + dst_bus_width = stm32_dma_get_width(chan, dst_addr_width); + if (dst_bus_width < 0) + return dst_bus_width; + + dst_burst_size = stm32_dma_get_burst(chan, dst_maxburst); + if (dst_burst_size < 0) + return dst_burst_size; + + if (!src_addr_width) + src_addr_width = dst_addr_width; + + src_bus_width = stm32_dma_get_width(chan, src_addr_width); + if (src_bus_width < 0) + return src_bus_width; + + src_burst_size = stm32_dma_get_burst(chan, src_maxburst); + if (src_burst_size < 0) + return src_burst_size; + + dma_scr = STM32_DMA_SCR_DIR(STM32_DMA_MEM_TO_DEV) | + STM32_DMA_SCR_PSIZE(dst_bus_width) | + STM32_DMA_SCR_MSIZE(src_bus_width) | + STM32_DMA_SCR_PBURST(dst_burst_size) | + STM32_DMA_SCR_MBURST(src_burst_size); + + chan->chan_reg.dma_spar = chan->dma_sconfig.dst_addr; + *buswidth = dst_addr_width; + break; + + case DMA_DEV_TO_MEM: + src_bus_width = stm32_dma_get_width(chan, src_addr_width); + if (src_bus_width < 0) + return src_bus_width; + + src_burst_size = stm32_dma_get_burst(chan, src_maxburst); + if (src_burst_size < 0) + return src_burst_size; + + if (!dst_addr_width) + dst_addr_width = src_addr_width; + + dst_bus_width = stm32_dma_get_width(chan, dst_addr_width); + if (dst_bus_width < 0) + return dst_bus_width; + + dst_burst_size = stm32_dma_get_burst(chan, dst_maxburst); + if (dst_burst_size < 0) + return dst_burst_size; + + dma_scr = STM32_DMA_SCR_DIR(STM32_DMA_DEV_TO_MEM) | + STM32_DMA_SCR_PSIZE(src_bus_width) | + STM32_DMA_SCR_MSIZE(dst_bus_width) | + STM32_DMA_SCR_PBURST(src_burst_size) | + STM32_DMA_SCR_MBURST(dst_burst_size); + + chan->chan_reg.dma_spar = chan->dma_sconfig.src_addr; + *buswidth = chan->dma_sconfig.src_addr_width; + break; + + default: + dev_err(chan2dev(chan), "Dma direction is not supported\n"); + return -EINVAL; + } + + stm32_dma_set_fifo_config(chan, src_maxburst, dst_maxburst); + + chan->chan_reg.dma_scr &= ~(STM32_DMA_SCR_DIR_MASK | + STM32_DMA_SCR_PSIZE_MASK | STM32_DMA_SCR_MSIZE_MASK | + STM32_DMA_SCR_PBURST_MASK | STM32_DMA_SCR_MBURST_MASK); + chan->chan_reg.dma_scr |= dma_scr; + + return 0; +} + +static void stm32_dma_clear_reg(struct stm32_dma_chan_reg *regs) +{ + memset(regs, 0, sizeof(struct stm32_dma_chan_reg)); +} + +static struct dma_async_tx_descriptor *stm32_dma_prep_slave_sg( + struct dma_chan *c, struct scatterlist *sgl, + u32 sg_len, enum dma_transfer_direction direction, + unsigned long flags, void *context) +{ + struct stm32_dma_chan *chan = to_stm32_dma_chan(c); + struct stm32_dma_desc *desc; + struct scatterlist *sg; + enum dma_slave_buswidth buswidth; + u32 nb_data_items; + int i, ret; + + if (!chan->config_init) { + dev_err(chan2dev(chan), "dma channel is not configured\n"); + return NULL; + } + + if (sg_len < 1) { + dev_err(chan2dev(chan), "Invalid segment length %d\n", sg_len); + return NULL; + } + + desc = stm32_dma_alloc_desc(sg_len); + if (!desc) + return NULL; + + ret = stm32_dma_set_xfer_param(chan, direction, &buswidth); + if (ret < 0) + goto err; + + /* Set peripheral flow controller */ + if (chan->dma_sconfig.device_fc) + chan->chan_reg.dma_scr |= STM32_DMA_SCR_PFCTRL; + else + chan->chan_reg.dma_scr &= ~STM32_DMA_SCR_PFCTRL; + + for_each_sg(sgl, sg, sg_len, i) { + desc->sg_req[i].len = sg_dma_len(sg); + + nb_data_items = desc->sg_req[i].len / buswidth; + if (nb_data_items > STM32_DMA_MAX_DATA_ITEMS) { + dev_err(chan2dev(chan), "nb items not supported\n"); + goto err; + } + + stm32_dma_clear_reg(&desc->sg_req[i].chan_reg); + desc->sg_req[i].chan_reg.dma_scr = chan->chan_reg.dma_scr; + desc->sg_req[i].chan_reg.dma_sfcr = chan->chan_reg.dma_sfcr; + desc->sg_req[i].chan_reg.dma_spar = chan->chan_reg.dma_spar; + desc->sg_req[i].chan_reg.dma_sm0ar = sg_dma_address(sg); + desc->sg_req[i].chan_reg.dma_sm1ar = sg_dma_address(sg); + desc->sg_req[i].chan_reg.dma_sndtr = nb_data_items; + } + + desc->num_sgs = sg_len; + desc->cyclic = false; + + return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); + +err: + kfree(desc); + return NULL; +} + +static struct dma_async_tx_descriptor *stm32_dma_prep_dma_cyclic( + struct dma_chan *c, dma_addr_t buf_addr, size_t buf_len, + size_t period_len, enum dma_transfer_direction direction, + unsigned long flags) +{ + struct stm32_dma_chan *chan = to_stm32_dma_chan(c); + struct stm32_dma_desc *desc; + enum dma_slave_buswidth buswidth; + u32 num_periods, nb_data_items; + int i, ret; + + if (!buf_len || !period_len) { + dev_err(chan2dev(chan), "Invalid buffer/period len\n"); + return NULL; + } + + if (!chan->config_init) { + dev_err(chan2dev(chan), "dma channel is not configured\n"); + return NULL; + } + + if (buf_len % period_len) { + dev_err(chan2dev(chan), "buf_len not multiple of period_len\n"); + return NULL; + } + + /* + * We allow to take more number of requests till DMA is + * not started. The driver will loop over all requests. + * Once DMA is started then new requests can be queued only after + * terminating the DMA. + */ + if (chan->busy) { + dev_err(chan2dev(chan), "Request not allowed when dma busy\n"); + return NULL; + } + + ret = stm32_dma_set_xfer_param(chan, direction, &buswidth); + if (ret < 0) + return NULL; + + nb_data_items = period_len / buswidth; + if (nb_data_items > STM32_DMA_MAX_DATA_ITEMS) { + dev_err(chan2dev(chan), "number of items not supported\n"); + return NULL; + } + + /* Enable Circular mode or double buffer mode */ + if (buf_len == period_len) + chan->chan_reg.dma_scr |= STM32_DMA_SCR_CIRC; + else + chan->chan_reg.dma_scr |= STM32_DMA_SCR_DBM; + + /* Clear periph ctrl if client set it */ + chan->chan_reg.dma_scr &= ~STM32_DMA_SCR_PFCTRL; + + num_periods = buf_len / period_len; + + desc = stm32_dma_alloc_desc(num_periods); + if (!desc) + return NULL; + + for (i = 0; i < num_periods; i++) { + desc->sg_req[i].len = period_len; + + stm32_dma_clear_reg(&desc->sg_req[i].chan_reg); + desc->sg_req[i].chan_reg.dma_scr = chan->chan_reg.dma_scr; + desc->sg_req[i].chan_reg.dma_sfcr = chan->chan_reg.dma_sfcr; + desc->sg_req[i].chan_reg.dma_spar = chan->chan_reg.dma_spar; + desc->sg_req[i].chan_reg.dma_sm0ar = buf_addr; + desc->sg_req[i].chan_reg.dma_sm1ar = buf_addr; + desc->sg_req[i].chan_reg.dma_sndtr = nb_data_items; + buf_addr += period_len; + } + + desc->num_sgs = num_periods; + desc->cyclic = true; + + return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); +} + +static struct dma_async_tx_descriptor *stm32_dma_prep_dma_memcpy( + struct dma_chan *c, dma_addr_t dest, + dma_addr_t src, size_t len, unsigned long flags) +{ + struct stm32_dma_chan *chan = to_stm32_dma_chan(c); + u32 num_sgs; + struct stm32_dma_desc *desc; + size_t xfer_count, offset; + int i; + + num_sgs = DIV_ROUND_UP(len, STM32_DMA_MAX_DATA_ITEMS); + desc = stm32_dma_alloc_desc(num_sgs); + if (!desc) + return NULL; + + for (offset = 0, i = 0; offset < len; offset += xfer_count, i++) { + xfer_count = min_t(size_t, len - offset, + STM32_DMA_MAX_DATA_ITEMS); + + desc->sg_req[i].len = xfer_count; + + stm32_dma_clear_reg(&desc->sg_req[i].chan_reg); + desc->sg_req[i].chan_reg.dma_scr = + STM32_DMA_SCR_DIR(STM32_DMA_MEM_TO_MEM) | + STM32_DMA_SCR_MINC | + STM32_DMA_SCR_PINC | + STM32_DMA_SCR_TCIE | + STM32_DMA_SCR_TEIE; + desc->sg_req[i].chan_reg.dma_sfcr = STM32_DMA_SFCR_DMDIS | + STM32_DMA_SFCR_FTH(STM32_DMA_FIFO_THRESHOLD_FULL) | + STM32_DMA_SFCR_FEIE; + desc->sg_req[i].chan_reg.dma_spar = src + offset; + desc->sg_req[i].chan_reg.dma_sm0ar = dest + offset; + desc->sg_req[i].chan_reg.dma_sndtr = xfer_count; + } + + desc->num_sgs = num_sgs; + desc->cyclic = false; + + return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); +} + +static size_t stm32_dma_desc_residue(struct stm32_dma_chan *chan, + struct stm32_dma_desc *desc, + u32 next_sg) +{ + struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); + u32 dma_scr, width, residue, count; + int i; + + residue = 0; + + for (i = next_sg; i < desc->num_sgs; i++) + residue += desc->sg_req[i].len; + + if (next_sg != 0) { + dma_scr = stm32_dma_read(dmadev, STM32_DMA_SCR(chan->id)); + width = STM32_DMA_SCR_PSIZE_GET(dma_scr); + count = stm32_dma_read(dmadev, STM32_DMA_SNDTR(chan->id)); + + residue += count << width; + } + + return residue; +} + +static enum dma_status stm32_dma_tx_status(struct dma_chan *c, + dma_cookie_t cookie, + struct dma_tx_state *state) +{ + struct stm32_dma_chan *chan = to_stm32_dma_chan(c); + struct virt_dma_desc *vdesc; + enum dma_status status; + unsigned long flags; + u32 residue; + + status = dma_cookie_status(c, cookie, state); + if ((status == DMA_COMPLETE) || (!state)) + return status; + + spin_lock_irqsave(&chan->vchan.lock, flags); + vdesc = vchan_find_desc(&chan->vchan, cookie); + if (cookie == chan->desc->vdesc.tx.cookie) { + residue = stm32_dma_desc_residue(chan, chan->desc, + chan->next_sg); + } else if (vdesc) { + residue = stm32_dma_desc_residue(chan, + to_stm32_dma_desc(vdesc), 0); + } else { + residue = 0; + } + + dma_set_residue(state, residue); + + spin_unlock_irqrestore(&chan->vchan.lock, flags); + + return status; +} + +static int stm32_dma_alloc_chan_resources(struct dma_chan *c) +{ + struct stm32_dma_chan *chan = to_stm32_dma_chan(c); + struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); + int ret; + + chan->config_init = false; + ret = clk_prepare_enable(dmadev->clk); + if (ret < 0) { + dev_err(chan2dev(chan), "clk_prepare_enable failed: %d\n", ret); + return ret; + } + + ret = stm32_dma_disable_chan(chan); + if (ret < 0) + clk_disable_unprepare(dmadev->clk); + + return ret; +} + +static void stm32_dma_free_chan_resources(struct dma_chan *c) +{ + struct stm32_dma_chan *chan = to_stm32_dma_chan(c); + struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); + unsigned long flags; + + dev_dbg(chan2dev(chan), "Freeing channel %d\n", chan->id); + + if (chan->busy) { + spin_lock_irqsave(&chan->vchan.lock, flags); + stm32_dma_stop(chan); + chan->desc = NULL; + spin_unlock_irqrestore(&chan->vchan.lock, flags); + } + + clk_disable_unprepare(dmadev->clk); + + vchan_free_chan_resources(to_virt_chan(c)); +} + +static void stm32_dma_desc_free(struct virt_dma_desc *vdesc) +{ + kfree(container_of(vdesc, struct stm32_dma_desc, vdesc)); +} + +void stm32_dma_set_config(struct stm32_dma_chan *chan, + struct stm32_dma_cfg *cfg) +{ + stm32_dma_clear_reg(&chan->chan_reg); + + chan->chan_reg.dma_scr = cfg->stream_config & STM32_DMA_SCR_CFG_MASK; + chan->chan_reg.dma_scr |= STM32_DMA_SCR_REQ(cfg->request_line); + + /* Enable Interrupts */ + chan->chan_reg.dma_scr |= STM32_DMA_SCR_TEIE | STM32_DMA_SCR_TCIE; + + chan->chan_reg.dma_sfcr = cfg->threshold & STM32_DMA_SFCR_FTH_MASK; +} + +static struct dma_chan *stm32_dma_of_xlate(struct of_phandle_args *dma_spec, + struct of_dma *ofdma) +{ + struct stm32_dma_device *dmadev = ofdma->of_dma_data; + struct stm32_dma_cfg cfg; + struct stm32_dma_chan *chan; + struct dma_chan *c; + + if (dma_spec->args_count < 3) + return NULL; + + cfg.channel_id = dma_spec->args[0]; + cfg.request_line = dma_spec->args[1]; + cfg.stream_config = dma_spec->args[2]; + cfg.threshold = 0; + + if ((cfg.channel_id >= STM32_DMA_MAX_CHANNELS) || (cfg.request_line >= + STM32_DMA_MAX_REQUEST_ID)) + return NULL; + + if (dma_spec->args_count > 3) + cfg.threshold = dma_spec->args[3]; + + chan = &dmadev->chan[cfg.channel_id]; + + c = dma_get_slave_channel(&chan->vchan.chan); + if (c) + stm32_dma_set_config(chan, &cfg); + + return c; +} + +static const struct of_device_id stm32_dma_of_match[] = { + { .compatible = "st,stm32-dma", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, stm32_dma_of_match); + +static int stm32_dma_probe(struct platform_device *pdev) +{ + struct stm32_dma_chan *chan; + struct stm32_dma_device *dmadev; + struct dma_device *dd; + const struct of_device_id *match; + struct resource *res; + int i, ret; + + match = of_match_device(stm32_dma_of_match, &pdev->dev); + if (!match) { + dev_err(&pdev->dev, "Error: No device match found\n"); + return -ENODEV; + } + + dmadev = devm_kzalloc(&pdev->dev, sizeof(*dmadev), GFP_KERNEL); + if (!dmadev) + return -ENOMEM; + + dd = &dmadev->ddev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + dmadev->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(dmadev->base)) + return PTR_ERR(dmadev->base); + + dmadev->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(dmadev->clk)) { + dev_err(&pdev->dev, "Error: Missing controller clock\n"); + return PTR_ERR(dmadev->clk); + } + + dmadev->mem2mem = of_property_read_bool(pdev->dev.of_node, + "st,mem2mem"); + + dmadev->rst = devm_reset_control_get(&pdev->dev, NULL); + if (!IS_ERR(dmadev->rst)) { + reset_control_assert(dmadev->rst); + udelay(2); + reset_control_deassert(dmadev->rst); + } + + dma_cap_set(DMA_SLAVE, dd->cap_mask); + dma_cap_set(DMA_PRIVATE, dd->cap_mask); + dma_cap_set(DMA_CYCLIC, dd->cap_mask); + dd->device_alloc_chan_resources = stm32_dma_alloc_chan_resources; + dd->device_free_chan_resources = stm32_dma_free_chan_resources; + dd->device_tx_status = stm32_dma_tx_status; + dd->device_issue_pending = stm32_dma_issue_pending; + dd->device_prep_slave_sg = stm32_dma_prep_slave_sg; + dd->device_prep_dma_cyclic = stm32_dma_prep_dma_cyclic; + dd->device_config = stm32_dma_slave_config; + dd->device_terminate_all = stm32_dma_terminate_all; + dd->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | + BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | + BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + dd->dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | + BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | + BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + dd->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); + dd->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; + dd->dev = &pdev->dev; + INIT_LIST_HEAD(&dd->channels); + + if (dmadev->mem2mem) { + dma_cap_set(DMA_MEMCPY, dd->cap_mask); + dd->device_prep_dma_memcpy = stm32_dma_prep_dma_memcpy; + dd->directions |= BIT(DMA_MEM_TO_MEM); + } + + for (i = 0; i < STM32_DMA_MAX_CHANNELS; i++) { + chan = &dmadev->chan[i]; + chan->id = i; + chan->vchan.desc_free = stm32_dma_desc_free; + vchan_init(&chan->vchan, dd); + } + + ret = dma_async_device_register(dd); + if (ret) + return ret; + + for (i = 0; i < STM32_DMA_MAX_CHANNELS; i++) { + chan = &dmadev->chan[i]; + res = platform_get_resource(pdev, IORESOURCE_IRQ, i); + if (!res) { + ret = -EINVAL; + dev_err(&pdev->dev, "No irq resource for chan %d\n", i); + goto err_unregister; + } + chan->irq = res->start; + ret = devm_request_irq(&pdev->dev, chan->irq, + stm32_dma_chan_irq, 0, + dev_name(chan2dev(chan)), chan); + if (ret) { + dev_err(&pdev->dev, + "request_irq failed with err %d channel %d\n", + ret, i); + goto err_unregister; + } + } + + ret = of_dma_controller_register(pdev->dev.of_node, + stm32_dma_of_xlate, dmadev); + if (ret < 0) { + dev_err(&pdev->dev, + "STM32 DMA DMA OF registration failed %d\n", ret); + goto err_unregister; + } + + platform_set_drvdata(pdev, dmadev); + + dev_info(&pdev->dev, "STM32 DMA driver registered\n"); + + return 0; + +err_unregister: + dma_async_device_unregister(dd); + + return ret; +} + +static struct platform_driver stm32_dma_driver = { + .driver = { + .name = "stm32-dma", + .of_match_table = stm32_dma_of_match, + }, +}; + +static int __init stm32_dma_init(void) +{ + return platform_driver_probe(&stm32_dma_driver, stm32_dma_probe); +} +subsys_initcall(stm32_dma_init); -- GitLab From b341b4a13ca2c6ea8a426a9befb4dec0d7040860 Mon Sep 17 00:00:00 2001 From: M'boumba Cedric Madianga Date: Fri, 16 Oct 2015 15:59:16 +0200 Subject: [PATCH 0056/2855] ARM: configs: Add STM32 DMA support in STM32 defconfig This patch adds STM32 DMA support in stm32_defconfig file Signed-off-by: M'boumba Cedric Madianga Signed-off-by: Vinod Koul --- arch/arm/configs/stm32_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig index 4725fab562cb3..ec5250547d145 100644 --- a/arch/arm/configs/stm32_defconfig +++ b/arch/arm/configs/stm32_defconfig @@ -54,6 +54,8 @@ CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_DMADEVICES=y +CONFIG_STM32_DMA=y # CONFIG_FILE_LOCKING is not set # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY_USER is not set -- GitLab From d3cd63f91b84c60e0b30ee8a45b8f291dac7bbff Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Fri, 6 Nov 2015 13:24:01 -0700 Subject: [PATCH 0057/2855] dmaengine: IOATDMA: Cleanup pre v3.0 chansts register reads Remove pre-3.0 channel status reads. 3.0 and later chansts register is 64bit and can be read 64bit. This was clarified with the hardware architects and since the driver now only support 3.0+ we don't need the legacy support Signed-off-by: Dave Jiang Signed-off-by: Vinod Koul --- drivers/dma/ioat/dma.h | 34 +--------------------------------- drivers/dma/ioat/registers.h | 16 +++------------- 2 files changed, 4 insertions(+), 46 deletions(-) diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 8f4e607d5817b..b8f48074789f2 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h @@ -235,43 +235,11 @@ ioat_chan_by_index(struct ioatdma_device *ioat_dma, int index) return ioat_dma->idx[index]; } -static inline u64 ioat_chansts_32(struct ioatdma_chan *ioat_chan) -{ - u8 ver = ioat_chan->ioat_dma->version; - u64 status; - u32 status_lo; - - /* We need to read the low address first as this causes the - * chipset to latch the upper bits for the subsequent read - */ - status_lo = readl(ioat_chan->reg_base + IOAT_CHANSTS_OFFSET_LOW(ver)); - status = readl(ioat_chan->reg_base + IOAT_CHANSTS_OFFSET_HIGH(ver)); - status <<= 32; - status |= status_lo; - - return status; -} - -#if BITS_PER_LONG == 64 - static inline u64 ioat_chansts(struct ioatdma_chan *ioat_chan) { - u8 ver = ioat_chan->ioat_dma->version; - u64 status; - - /* With IOAT v3.3 the status register is 64bit. */ - if (ver >= IOAT_VER_3_3) - status = readq(ioat_chan->reg_base + IOAT_CHANSTS_OFFSET(ver)); - else - status = ioat_chansts_32(ioat_chan); - - return status; + return readq(ioat_chan->reg_base + IOAT_CHANSTS_OFFSET); } -#else -#define ioat_chansts ioat_chansts_32 -#endif - static inline u64 ioat_chansts_to_addr(u64 status) { return status & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR; diff --git a/drivers/dma/ioat/registers.h b/drivers/dma/ioat/registers.h index 909352f74c892..4994a3623aee4 100644 --- a/drivers/dma/ioat/registers.h +++ b/drivers/dma/ioat/registers.h @@ -99,19 +99,9 @@ #define IOAT_DMA_COMP_V1 0x0001 /* Compatibility with DMA version 1 */ #define IOAT_DMA_COMP_V2 0x0002 /* Compatibility with DMA version 2 */ - -#define IOAT1_CHANSTS_OFFSET 0x04 /* 64-bit Channel Status Register */ -#define IOAT2_CHANSTS_OFFSET 0x08 /* 64-bit Channel Status Register */ -#define IOAT_CHANSTS_OFFSET(ver) ((ver) < IOAT_VER_2_0 \ - ? IOAT1_CHANSTS_OFFSET : IOAT2_CHANSTS_OFFSET) -#define IOAT1_CHANSTS_OFFSET_LOW 0x04 -#define IOAT2_CHANSTS_OFFSET_LOW 0x08 -#define IOAT_CHANSTS_OFFSET_LOW(ver) ((ver) < IOAT_VER_2_0 \ - ? IOAT1_CHANSTS_OFFSET_LOW : IOAT2_CHANSTS_OFFSET_LOW) -#define IOAT1_CHANSTS_OFFSET_HIGH 0x08 -#define IOAT2_CHANSTS_OFFSET_HIGH 0x0C -#define IOAT_CHANSTS_OFFSET_HIGH(ver) ((ver) < IOAT_VER_2_0 \ - ? IOAT1_CHANSTS_OFFSET_HIGH : IOAT2_CHANSTS_OFFSET_HIGH) +/* IOAT1 define left for i7300_idle driver to not fail compiling */ +#define IOAT1_CHANSTS_OFFSET 0x04 +#define IOAT_CHANSTS_OFFSET 0x08 /* 64-bit Channel Status Register */ #define IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR (~0x3fULL) #define IOAT_CHANSTS_SOFT_ERR 0x10ULL #define IOAT_CHANSTS_UNAFFILIATED_ERR 0x8ULL -- GitLab From 2bb129ebb23d2dfec3cd9c22dc7defd681cfcd58 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 13 Nov 2015 12:46:00 +0100 Subject: [PATCH 0058/2855] dmaengine: ioatdma: constify dca_ops structures The dca_ops structure is never modified, so declare it as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Acked-by: Dan Williams Signed-off-by: Vinod Koul --- drivers/dca/dca-core.c | 3 ++- drivers/dma/ioat/dca.c | 2 +- include/linux/dca.h | 5 +++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c index 819dfda882362..7afbb28d6a0f9 100644 --- a/drivers/dca/dca-core.c +++ b/drivers/dca/dca-core.c @@ -321,7 +321,8 @@ EXPORT_SYMBOL_GPL(dca_get_tag); * @ops - pointer to struct of dca operation function pointers * @priv_size - size of extra mem to be added for provider's needs */ -struct dca_provider *alloc_dca_provider(struct dca_ops *ops, int priv_size) +struct dca_provider *alloc_dca_provider(const struct dca_ops *ops, + int priv_size) { struct dca_provider *dca; int alloc_size; diff --git a/drivers/dma/ioat/dca.c b/drivers/dma/ioat/dca.c index 2cb7c308d5c72..0b9b6b07db9e9 100644 --- a/drivers/dma/ioat/dca.c +++ b/drivers/dma/ioat/dca.c @@ -224,7 +224,7 @@ static u8 ioat_dca_get_tag(struct dca_provider *dca, return tag; } -static struct dca_ops ioat_dca_ops = { +static const struct dca_ops ioat_dca_ops = { .add_requester = ioat_dca_add_requester, .remove_requester = ioat_dca_remove_requester, .get_tag = ioat_dca_get_tag, diff --git a/include/linux/dca.h b/include/linux/dca.h index d27a7a05718d3..ad956c2e07a86 100644 --- a/include/linux/dca.h +++ b/include/linux/dca.h @@ -34,7 +34,7 @@ void dca_unregister_notify(struct notifier_block *nb); struct dca_provider { struct list_head node; - struct dca_ops *ops; + const struct dca_ops *ops; struct device *cd; int id; }; @@ -53,7 +53,8 @@ struct dca_ops { int (*dev_managed) (struct dca_provider *, struct device *); }; -struct dca_provider *alloc_dca_provider(struct dca_ops *ops, int priv_size); +struct dca_provider *alloc_dca_provider(const struct dca_ops *ops, + int priv_size); void free_dca_provider(struct dca_provider *dca); int register_dca_provider(struct dca_provider *dca, struct device *dev); void unregister_dca_provider(struct dca_provider *dca, struct device *dev); -- GitLab From 90e6228a995816750f96c70d94298e12c08511f4 Mon Sep 17 00:00:00 2001 From: Ksenija Stanojevic Date: Thu, 29 Oct 2015 21:58:16 -0700 Subject: [PATCH 0059/2855] Staging: comedi: das16: Fix sparse endian warning Fix following sparse warning: warning: cast to restricted __le16 This change is safe because array is pointer of type void and can be used to store any type of data, also offset of the array would be the same since unsigned short and __le16 are both 16 bits in size. Signed-off-by: Ksenija Stanojevic Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 056bca9c67d5d..fd8e0b76f7646 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -801,9 +801,10 @@ static void das16_ai_munge(struct comedi_device *dev, unsigned short *data = array; unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes); unsigned int i; + __le16 *buf = array; for (i = 0; i < num_samples; i++) { - data[i] = le16_to_cpu(data[i]); + data[i] = le16_to_cpu(buf[i]); if (s->maxdata == 0x0fff) data[i] >>= 4; data[i] &= s->maxdata; -- GitLab From 212efdb1be77ae97e21afc35310f7f9c428f875c Mon Sep 17 00:00:00 2001 From: Ksenija Stanojevic Date: Sat, 31 Oct 2015 06:34:29 -0700 Subject: [PATCH 0060/2855] Staging: comedi: ni_mio_common: Fix endian sparse warning Fix following sparse warnings: warning: cast to restricted __le32 warning: cast to restricted __le16 warning: incorrect type in assignment (different base types) expected unsigned short [unsigned] [assigned] val got restricted __le16 [usertype] Data is pointer of type void and can be used to store any type of data. In function ni_ai_munge: barray and array have the same 16 bit offset. blarray and larray have the same 32 bit offset. Signed-off-by: Ksenija Stanojevic Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_mio_common.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 6cc304a4c59bf..cbb44fc6940bc 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -1516,13 +1516,17 @@ static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s, unsigned short *array = data; unsigned int *larray = data; unsigned int i; +#ifdef PCIDMA + __le16 *barray = data; + __le32 *blarray = data; +#endif for (i = 0; i < nsamples; i++) { #ifdef PCIDMA if (s->subdev_flags & SDF_LSAMPL) - larray[i] = le32_to_cpu(larray[i]); + larray[i] = le32_to_cpu(blarray[i]); else - array[i] = le16_to_cpu(array[i]); + array[i] = le16_to_cpu(barray[i]); #endif if (s->subdev_flags & SDF_LSAMPL) larray[i] += devpriv->ai_offset[chan_index]; @@ -2574,6 +2578,9 @@ static void ni_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int nsamples = comedi_bytes_to_samples(s, num_bytes); unsigned short *array = data; unsigned int i; +#ifdef PCIDMA + __le16 buf, *barray = data; +#endif for (i = 0; i < nsamples; i++) { unsigned int range = CR_RANGE(cmd->chanlist[chan_index]); @@ -2586,10 +2593,11 @@ static void ni_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s, if (comedi_range_is_bipolar(s, range)) val = comedi_offset_munge(s, val); #ifdef PCIDMA - val = cpu_to_le16(val); -#endif + buf = cpu_to_le16(val); + barray[i] = buf; +#else array[i] = val; - +#endif chan_index++; chan_index %= cmd->chanlist_len; } -- GitLab From 2aadecb60a33c791bfb729d65c158a22f636961a Mon Sep 17 00:00:00 2001 From: Ksenija Stanojevic Date: Sat, 31 Oct 2015 06:36:44 -0700 Subject: [PATCH 0061/2855] Staging: comedi: adl_pci9118: Fix endian sparse warning Fix following sparse warning: warning: cast to restricted __be16 data is pointer of type void and can be used to store any type of data. barray and array have the same 16 bit offset. Signed-off-by: Ksenija Stanojevic Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 0dff1dbb53fbf..4437ea3abe8d0 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -603,10 +603,11 @@ static void pci9118_ai_munge(struct comedi_device *dev, unsigned short *array = data; unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes); unsigned int i; + __be16 *barray = data; for (i = 0; i < num_samples; i++) { if (devpriv->usedma) - array[i] = be16_to_cpu(array[i]); + array[i] = be16_to_cpu(barray[i]); if (s->maxdata == 0xffff) array[i] ^= 0x8000; else -- GitLab From b2cb0686041c91b0bfdd580e1b54eec06af3280d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 30 Oct 2015 11:10:05 -0700 Subject: [PATCH 0062/2855] staging: comedi: adv_pci1710: separate out PCI-1720 support as a new driver The PCI-1710 series boards are multifunction data acquisition boards with analog inputs and outputs, digital inputs and outputs, and counter/timer functions. The PCI-1720 is a simple 4 channel analog output board. It also uses a unique register map. Separate out the PCI-1720 support as a new driver, adv_pci1720, to ease maintainability. Fix some issues with the PCI-1720 support in the new driver: 1) the registers are all 8-bit 2) remove the analog output "reset" when the driver attaches/detaches 3) disable "synchronized output" to simplify the analog outputs 4) remove the need for the private data 5) add support for the BoardID register to allow multiple cards Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 12 +- drivers/staging/comedi/drivers/Makefile | 1 + drivers/staging/comedi/drivers/adv_pci1710.c | 109 +---------- drivers/staging/comedi/drivers/adv_pci1720.c | 195 +++++++++++++++++++ 4 files changed, 212 insertions(+), 105 deletions(-) create mode 100644 drivers/staging/comedi/drivers/adv_pci1720.c diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index ac0f01007abd8..945c85a107930 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -737,15 +737,23 @@ config COMEDI_ADL_PCI9118 called adl_pci9118. config COMEDI_ADV_PCI1710 - tristate "Advantech PCI-171x, PCI-1720 and PCI-1731 support" + tristate "Advantech PCI-171x and PCI-1731 support" select COMEDI_8254 ---help--- Enable support for Advantech PCI-1710, PCI-1710HG, PCI-1711, - PCI-1713, PCI-1720 and PCI-1731 + PCI-1713 and PCI-1731 To compile this driver as a module, choose M here: the module will be called adv_pci1710. +config COMEDI_ADV_PCI1720 + tristate "Advantech PCI-1720 support" + ---help--- + Enable support for Advantech PCI-1720 Analog Output board. + + To compile this driver as a module, choose M here: the module will be + called adv_pci1720. + config COMEDI_ADV_PCI1723 tristate "Advantech PCI-1723 support" ---help--- diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index c3b8f2d7611b9..94c179bea71ef 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -78,6 +78,7 @@ obj-$(CONFIG_COMEDI_ADL_PCI8164) += adl_pci8164.o obj-$(CONFIG_COMEDI_ADL_PCI9111) += adl_pci9111.o obj-$(CONFIG_COMEDI_ADL_PCI9118) += adl_pci9118.o obj-$(CONFIG_COMEDI_ADV_PCI1710) += adv_pci1710.o +obj-$(CONFIG_COMEDI_ADV_PCI1720) += adv_pci1720.o obj-$(CONFIG_COMEDI_ADV_PCI1723) += adv_pci1723.o obj-$(CONFIG_COMEDI_ADV_PCI1724) += adv_pci1724.o obj-$(CONFIG_COMEDI_ADV_PCI_DIO) += adv_pci_dio.o diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 399c511cfe0ab..45d7f42312ec3 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -11,8 +11,9 @@ * Driver: adv_pci1710 * Description: Comedi driver for Advantech PCI-1710 series boards * Devices: [Advantech] PCI-1710 (adv_pci1710), PCI-1710HG, PCI-1711, - * PCI-1713, PCI-1720, PCI-1731 + * PCI-1713, PCI-1731 * Author: Michal Dobes + * Updated: Fri, 29 Oct 2015 17:19:35 -0700 * Status: works * * Configuration options: not applicable, uses PCI auto config @@ -62,16 +63,6 @@ #define PCI171X_DO_REG 0x10 /* W: digital outputs */ #define PCI171X_TIMER_BASE 0x18 /* R/W: 8254 timer */ -/* - * PCI-1720 only has analog outputs and has a different - * register map (dev->iobase) - */ -#define PCI1720_DA_REG(x) (0x00 + ((x) * 2)) /* W: D/A registers */ -#define PCI1720_RANGE_REG 0x08 /* R/W: D/A range register */ -#define PCI1720_SYNC_REG 0x09 /* W: D/A synchronized output */ -#define PCI1720_SYNC_CTRL_REG 0x0f /* R/W: D/A synchronized control */ -#define PCI1720_SYNC_CTRL_SC0 BIT(0) /* set synchronous output mode */ - static const struct comedi_lrange range_pci1710_3 = { 9, { BIP_RANGE(5), @@ -122,15 +113,6 @@ static const struct comedi_lrange range_pci17x1 = { static const char range_codes_pci17x1[] = { 0x00, 0x01, 0x02, 0x03, 0x04 }; -static const struct comedi_lrange pci1720_ao_range = { - 4, { - UNI_RANGE(5), - UNI_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(10) - } -}; - static const struct comedi_lrange pci171x_ao_range = { 2, { UNI_RANGE(5), @@ -143,7 +125,6 @@ enum pci1710_boardid { BOARD_PCI1710HG, BOARD_PCI1711, BOARD_PCI1713, - BOARD_PCI1720, BOARD_PCI1731, }; @@ -153,7 +134,6 @@ struct boardtype { const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ const char *rangecode_ai; /* range codes for programming */ unsigned int is_pci1713:1; - unsigned int is_pci1720:1; unsigned int has_irq:1; unsigned int has_large_fifo:1; /* 4K or 1K FIFO */ unsigned int has_diff_ai:1; @@ -207,11 +187,6 @@ static const struct boardtype boardtypes[] = { .has_large_fifo = 1, .has_diff_ai = 1, }, - [BOARD_PCI1720] = { - .name = "pci1720", - .is_pci1720 = 1, - .has_ao = 1, - }, [BOARD_PCI1731] = { .name = "pci1731", .n_aichan = 16, @@ -465,36 +440,6 @@ static int pci171x_do_insn_bits(struct comedi_device *dev, return insn->n; } -static int pci1720_ao_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct pci1710_private *devpriv = dev->private; - unsigned int chan = CR_CHAN(insn->chanspec); - unsigned int range = CR_RANGE(insn->chanspec); - unsigned int val; - int i; - - val = devpriv->da_ranges & (~(0x03 << (chan << 1))); - val |= (range << (chan << 1)); - if (val != devpriv->da_ranges) { - outb(val, dev->iobase + PCI1720_RANGE_REG); - devpriv->da_ranges = val; - } - - val = s->readback[chan]; - for (i = 0; i < insn->n; i++) { - val = data[i]; - outw(val, dev->iobase + PCI1720_DA_REG(chan)); - outb(0, dev->iobase + PCI1720_SYNC_REG); /* update outputs */ - } - - s->readback[chan] = val; - - return insn->n; -} - static int pci171x_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -790,7 +735,7 @@ static int pci171x_insn_counter_config(struct comedi_device *dev, return insn->n; } -static int pci171x_reset(struct comedi_device *dev) +static int pci1710_reset(struct comedi_device *dev) { const struct boardtype *board = dev->board_ptr; struct pci1710_private *devpriv = dev->private; @@ -815,33 +760,6 @@ static int pci171x_reset(struct comedi_device *dev) return 0; } -static int pci1720_reset(struct comedi_device *dev) -{ - struct pci1710_private *devpriv = dev->private; - /* set synchronous output mode */ - outb(PCI1720_SYNC_CTRL_SC0, dev->iobase + PCI1720_SYNC_CTRL_REG); - devpriv->da_ranges = 0xAA; - /* set all ranges to +/-5V and outputs to 0V */ - outb(devpriv->da_ranges, dev->iobase + PCI1720_RANGE_REG); - outw(0x0800, dev->iobase + PCI1720_DA_REG(0)); - outw(0x0800, dev->iobase + PCI1720_DA_REG(1)); - outw(0x0800, dev->iobase + PCI1720_DA_REG(2)); - outw(0x0800, dev->iobase + PCI1720_DA_REG(3)); - outb(0, dev->iobase + PCI1720_SYNC_REG); /* update outputs */ - - return 0; -} - -static int pci1710_reset(struct comedi_device *dev) -{ - const struct boardtype *board = dev->board_ptr; - - if (board->is_pci1720) - return pci1720_reset(dev); - - return pci171x_reset(dev); -} - static int pci1710_auto_attach(struct comedi_device *dev, unsigned long context) { @@ -922,29 +840,15 @@ static int pci1710_auto_attach(struct comedi_device *dev, s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 2; s->maxdata = 0x0fff; - if (board->is_pci1720) { - s->n_chan = 4; - s->range_table = &pci1720_ao_range; - s->insn_write = pci1720_ao_insn_write; - } else { - s->n_chan = 2; - s->range_table = &pci171x_ao_range; - s->insn_write = pci171x_ao_insn_write; - } + s->range_table = &pci171x_ao_range; + s->insn_write = pci171x_ao_insn_write; ret = comedi_alloc_subdev_readback(s); if (ret) return ret; - /* initialize the readback values to match the board reset */ - if (board->is_pci1720) { - int i; - - for (i = 0; i < s->n_chan; i++) - s->readback[i] = 0x0800; - } - subdev++; } @@ -1063,7 +967,6 @@ static const struct pci_device_id adv_pci1710_pci_table[] = { }, { PCI_VDEVICE(ADVANTECH, 0x1711), BOARD_PCI1711 }, { PCI_VDEVICE(ADVANTECH, 0x1713), BOARD_PCI1713 }, - { PCI_VDEVICE(ADVANTECH, 0x1720), BOARD_PCI1720 }, { PCI_VDEVICE(ADVANTECH, 0x1731), BOARD_PCI1731 }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/adv_pci1720.c b/drivers/staging/comedi/drivers/adv_pci1720.c new file mode 100644 index 0000000000000..4830a1c93d158 --- /dev/null +++ b/drivers/staging/comedi/drivers/adv_pci1720.c @@ -0,0 +1,195 @@ +/* + * COMEDI driver for Advantech PCI-1720U + * Copyright (c) 2015 H Hartley Sweeten + * + * Separated from the adv_pci1710 driver written by: + * Michal Dobes + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 2000 David A. Schleef + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * Driver: adv_pci1720 + * Description: 4-channel Isolated D/A Output board + * Devices: [Advantech] PCI-7120U (adv_pci1720) + * Author: H Hartley Sweeten + * Updated: Fri, 29 Oct 2015 17:19:35 -0700 + * Status: untested + * + * Configuration options: not applicable, uses PCI auto config + * + * The PCI-1720 has 4 isolated 12-bit analog output channels with multiple + * output ranges. It also has a BoardID switch to allow differentiating + * multiple boards in the system. + * + * The analog outputs can operate in two modes, immediate and synchronized. + * This driver currently does not support the synchronized output mode. + * + * Jumpers JP1 to JP4 are used to set the current sink ranges for each + * analog output channel. In order to use the current sink ranges, the + * unipolar 5V range must be used. The voltage output and sink output for + * each channel is available on the connector as separate pins. + * + * Jumper JP5 controls the "hot" reset state of the analog outputs. + * Depending on its setting, the analog outputs will either keep the + * last settings and output values or reset to the default state after + * a "hot" reset. The default state for all channels is uniploar 5V range + * and all the output values are 0V. To allow this feature to work, the + * analog outputs are not "reset" when the driver attaches. + */ + +#include +#include + +#include "../comedi_pci.h" + +/* + * PCI BAR2 Register map (dev->iobase) + */ +#define PCI1720_AO_LSB_REG(x) (0x00 + ((x) * 2)) +#define PCI1720_AO_MSB_REG(x) (0x01 + ((x) * 2)) +#define PCI1720_AO_RANGE_REG 0x08 +#define PCI1720_AO_RANGE(c, r) (((r) & 0x3) << ((c) * 2)) +#define PCI1720_AO_RANGE_MASK(c) PCI1720_AO_RANGE((c), 0x3) +#define PCI1720_SYNC_REG 0x09 +#define PCI1720_SYNC_CTRL_REG 0x0f +#define PCI1720_SYNC_CTRL_SC0 BIT(0) +#define PCI1720_BOARDID_REG 0x14 + +static const struct comedi_lrange pci1720_ao_range = { + 4, { + UNI_RANGE(5), + UNI_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(10) + } +}; + +static int pci1720_ao_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int range = CR_RANGE(insn->chanspec); + unsigned int val; + int i; + + /* set the channel range and polarity */ + val = inb(dev->iobase + PCI1720_AO_RANGE_REG); + val &= ~PCI1720_AO_RANGE_MASK(chan); + val |= PCI1720_AO_RANGE(chan, range); + outb(val, dev->iobase + PCI1720_AO_RANGE_REG); + + val = s->readback[chan]; + for (i = 0; i < insn->n; i++) { + val = data[i]; + + outb(val & 0xff, dev->iobase + PCI1720_AO_LSB_REG(chan)); + outb((val >> 8) & 0xff, dev->iobase + PCI1720_AO_MSB_REG(chan)); + + /* conversion time is 2us (500 kHz throughput) */ + usleep_range(2, 100); + } + + s->readback[chan] = val; + + return insn->n; +} + +static int pci1720_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + data[1] = inb(dev->iobase + PCI1720_BOARDID_REG); + + return insn->n; +} + +static int pci1720_auto_attach(struct comedi_device *dev, + unsigned long context) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct comedi_subdevice *s; + int ret; + + ret = comedi_pci_enable(dev); + if (ret) + return ret; + dev->iobase = pci_resource_start(pcidev, 2); + + ret = comedi_alloc_subdevices(dev, 2); + if (ret) + return ret; + + /* Analog Output subdevice */ + s = &dev->subdevices[0]; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0x0fff; + s->range_table = &pci1720_ao_range; + s->insn_write = pci1720_ao_insn_write; + + ret = comedi_alloc_subdev_readback(s); + if (ret) + return ret; + + /* Digital Input subdevice (BoardID SW1) */ + s = &dev->subdevices[1]; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = 4; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = pci1720_di_insn_bits; + + /* disable synchronized output, channels update when written */ + outb(0, dev->iobase + PCI1720_SYNC_CTRL_REG); + + return 0; +} + +static struct comedi_driver adv_pci1720_driver = { + .driver_name = "adv_pci1720", + .module = THIS_MODULE, + .auto_attach = pci1720_auto_attach, + .detach = comedi_pci_detach, +}; + +static int adv_pci1720_pci_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + return comedi_pci_auto_config(dev, &adv_pci1720_driver, + id->driver_data); +} + +static const struct pci_device_id adv_pci1720_pci_table[] = { + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1720) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, adv_pci1720_pci_table); + +static struct pci_driver adv_pci1720_pci_driver = { + .name = "adv_pci1720", + .id_table = adv_pci1720_pci_table, + .probe = adv_pci1720_pci_probe, + .remove = comedi_pci_auto_unconfig, +}; +module_comedi_pci_driver(adv_pci1720_driver, adv_pci1720_pci_driver); + +MODULE_AUTHOR("H Hartley Sweeten "); +MODULE_DESCRIPTION("Comedi driver for Advantech PCI-1720 Analog Output board"); +MODULE_LICENSE("GPL"); -- GitLab From e5b6b5d48fa26dd5bb1ec8d6829d318ef4c8585b Mon Sep 17 00:00:00 2001 From: Ksenija Stanojevic Date: Wed, 28 Oct 2015 17:30:43 -0700 Subject: [PATCH 0063/2855] Staging: lustre: Replace LPROCFS_CLIMP_EXIT with up_read In all call sites type of argument that macro LPROCFS_CLIMP_EXIT use is the same, so replace it with up_read function. Also remove the macro since it's no longer used. Signed-off-by: Ksenija Stanojevic Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/include/lprocfs_status.h | 3 --- drivers/staging/lustre/lustre/mgc/mgc_request.c | 2 +- .../staging/lustre/lustre/obdclass/lprocfs_status.c | 12 ++++++------ drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c | 6 +++--- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h index 9e654b218ca35..f18c0c75ef1ec 100644 --- a/drivers/staging/lustre/lustre/include/lprocfs_status.h +++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h @@ -624,9 +624,6 @@ void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx, int lprocfs_single_release(struct inode *, struct file *); int lprocfs_seq_release(struct inode *, struct file *); -#define LPROCFS_CLIMP_EXIT(obd) \ - up_read(&(obd)->u.cli.cl_sem) - /* write the name##_seq_show function, call LPROC_SEQ_FOPS_RO for read-only proc entries; otherwise, you will define name##_seq_write function also for a read-write proc entry, and then call LPROC_SEQ_SEQ instead. Finally, diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c index 5f53f3b7cefff..2d6de6c19b9f1 100644 --- a/drivers/staging/lustre/lustre/mgc/mgc_request.c +++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c @@ -463,7 +463,7 @@ int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data) } spin_unlock(&config_list_lock); - LPROCFS_CLIMP_EXIT(obd); + up_read(&obd->u.cli.cl_sem); return 0; } diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c index 333ac7d269b7e..2de3c1b6fa49f 100644 --- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c +++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c @@ -502,7 +502,7 @@ int lprocfs_rd_server_uuid(struct seq_file *m, void *data) obd2cli_tgt(obd), imp_state_name, imp->imp_deactive ? "\tDEACTIVATED" : ""); - LPROCFS_CLIMP_EXIT(obd); + up_read(&obd->u.cli.cl_sem); return 0; } @@ -526,7 +526,7 @@ int lprocfs_rd_conn_uuid(struct seq_file *m, void *data) else seq_puts(m, "\n"); - LPROCFS_CLIMP_EXIT(obd); + up_read(&obd->u.cli.cl_sem); return 0; } @@ -765,7 +765,7 @@ int lprocfs_rd_import(struct seq_file *m, void *data) } out_climp: - LPROCFS_CLIMP_EXIT(obd); + up_read(&obd->u.cli.cl_sem); return 0; } EXPORT_SYMBOL(lprocfs_rd_import); @@ -796,7 +796,7 @@ int lprocfs_rd_state(struct seq_file *m, void *data) ptlrpc_import_state_name(ish->ish_state)); } - LPROCFS_CLIMP_EXIT(obd); + up_read(&obd->u.cli.cl_sem); return 0; } EXPORT_SYMBOL(lprocfs_rd_state); @@ -857,7 +857,7 @@ int lprocfs_rd_timeouts(struct seq_file *m, void *data) lprocfs_at_hist_helper(m, &imp->imp_at.iat_service_estimate[i]); } - LPROCFS_CLIMP_EXIT(obd); + up_read(&obd->u.cli.cl_sem); return 0; } EXPORT_SYMBOL(lprocfs_rd_timeouts); @@ -876,7 +876,7 @@ int lprocfs_rd_connect_flags(struct seq_file *m, void *data) seq_printf(m, "flags=%#llx\n", flags); obd_connect_seq_flags2str(m, flags, "\n"); seq_printf(m, "\n"); - LPROCFS_CLIMP_EXIT(obd); + up_read(&obd->u.cli.cl_sem); return 0; } EXPORT_SYMBOL(lprocfs_rd_connect_flags); diff --git a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c index afab0dee7a5ce..2aecab21e3e1a 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c +++ b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c @@ -1197,7 +1197,7 @@ int lprocfs_wr_ping(struct file *file, const char __user *buffer, return rc; req = ptlrpc_prep_ping(obd->u.cli.cl_import); - LPROCFS_CLIMP_EXIT(obd); + up_read(&obd->u.cli.cl_sem); if (req == NULL) return -ENOMEM; @@ -1291,7 +1291,7 @@ int lprocfs_rd_pinger_recov(struct seq_file *m, void *n) return rc; seq_printf(m, "%d\n", !imp->imp_no_pinger_recover); - LPROCFS_CLIMP_EXIT(obd); + up_read(&obd->u.cli.cl_sem); return 0; } @@ -1319,7 +1319,7 @@ int lprocfs_wr_pinger_recov(struct file *file, const char __user *buffer, spin_lock(&imp->imp_lock); imp->imp_no_pinger_recover = !val; spin_unlock(&imp->imp_lock); - LPROCFS_CLIMP_EXIT(obd); + up_read(&obd->u.cli.cl_sem); return count; -- GitLab From 33db686a22e502ba127138912814e8468ac51ed6 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Thu, 29 Oct 2015 11:02:23 +0530 Subject: [PATCH 0064/2855] Staging: lustre: console: Drop unnecessary wrapper function Remove the function lstcon_group_put() and replace all its calls with the function lstcon_group_decref() because the former function just performs the job of calling the latter. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lnet/selftest/console.c | 78 +++++++++---------- 1 file changed, 36 insertions(+), 42 deletions(-) diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c index d315dd44ae3b3..9748a0907c023 100644 --- a/drivers/staging/lustre/lnet/selftest/console.c +++ b/drivers/staging/lustre/lnet/selftest/console.c @@ -277,12 +277,6 @@ lstcon_group_find(const char *name, lstcon_group_t **grpp) return -ENOENT; } -static void -lstcon_group_put(lstcon_group_t *grp) -{ - lstcon_group_decref(grp); -} - static int lstcon_group_ndlink_find(lstcon_group_t *grp, lnet_process_id_t id, lstcon_ndlink_t **ndlpp, int create) @@ -436,7 +430,7 @@ lstcon_group_nodes_add(lstcon_group_t *grp, } if (rc != 0) { - lstcon_group_put(tmp); + lstcon_group_decref(tmp); return rc; } @@ -445,7 +439,7 @@ lstcon_group_nodes_add(lstcon_group_t *grp, tmp, lstcon_sesrpc_condition, &trans); if (rc != 0) { CERROR("Can't create transaction: %d\n", rc); - lstcon_group_put(tmp); + lstcon_group_decref(tmp); return rc; } @@ -460,7 +454,7 @@ lstcon_group_nodes_add(lstcon_group_t *grp, lstcon_rpc_trans_destroy(trans); lstcon_group_move(tmp, grp); - lstcon_group_put(tmp); + lstcon_group_decref(tmp); return rc; } @@ -510,12 +504,12 @@ lstcon_group_nodes_remove(lstcon_group_t *grp, lstcon_rpc_trans_destroy(trans); /* release nodes anyway, because we can't rollback status */ - lstcon_group_put(tmp); + lstcon_group_decref(tmp); return rc; error: lstcon_group_move(tmp, grp); - lstcon_group_put(tmp); + lstcon_group_decref(tmp); return rc; } @@ -529,7 +523,7 @@ lstcon_group_add(char *name) rc = (lstcon_group_find(name, &grp) == 0) ? -EEXIST : 0; if (rc != 0) { /* find a group with same name */ - lstcon_group_put(grp); + lstcon_group_decref(grp); return rc; } @@ -563,14 +557,14 @@ lstcon_nodes_add(char *name, int count, lnet_process_id_t *ids_up, if (grp->grp_ref > 2) { /* referred by other threads or test */ CDEBUG(D_NET, "Group %s is busy\n", name); - lstcon_group_put(grp); + lstcon_group_decref(grp); return -EBUSY; } rc = lstcon_group_nodes_add(grp, count, ids_up, featp, result_up); - lstcon_group_put(grp); + lstcon_group_decref(grp); return rc; } @@ -591,7 +585,7 @@ lstcon_group_del(char *name) if (grp->grp_ref > 2) { /* referred by others threads or test */ CDEBUG(D_NET, "Group %s is busy\n", name); - lstcon_group_put(grp); + lstcon_group_decref(grp); return -EBUSY; } @@ -600,7 +594,7 @@ lstcon_group_del(char *name) grp, lstcon_sesrpc_condition, &trans); if (rc != 0) { CERROR("Can't create transaction: %d\n", rc); - lstcon_group_put(grp); + lstcon_group_decref(grp); return rc; } @@ -608,10 +602,10 @@ lstcon_group_del(char *name) lstcon_rpc_trans_destroy(trans); - lstcon_group_put(grp); + lstcon_group_decref(grp); /* -ref for session, it's destroyed, * status can't be rolled back, destroy group anyway */ - lstcon_group_put(grp); + lstcon_group_decref(grp); return rc; } @@ -631,7 +625,7 @@ lstcon_group_clean(char *name, int args) if (grp->grp_ref > 2) { /* referred by test */ CDEBUG(D_NET, "Group %s is busy\n", name); - lstcon_group_put(grp); + lstcon_group_decref(grp); return -EBUSY; } @@ -640,10 +634,10 @@ lstcon_group_clean(char *name, int args) lstcon_group_drain(grp, args); - lstcon_group_put(grp); + lstcon_group_decref(grp); /* release empty group */ if (list_empty(&grp->grp_ndl_list)) - lstcon_group_put(grp); + lstcon_group_decref(grp); return 0; } @@ -664,16 +658,16 @@ lstcon_nodes_remove(char *name, int count, if (grp->grp_ref > 2) { /* referred by test */ CDEBUG(D_NET, "Group %s is busy\n", name); - lstcon_group_put(grp); + lstcon_group_decref(grp); return -EBUSY; } rc = lstcon_group_nodes_remove(grp, count, ids_up, result_up); - lstcon_group_put(grp); + lstcon_group_decref(grp); /* release empty group */ if (list_empty(&grp->grp_ndl_list)) - lstcon_group_put(grp); + lstcon_group_decref(grp); return rc; } @@ -694,7 +688,7 @@ lstcon_group_refresh(char *name, struct list_head *result_up) if (grp->grp_ref > 2) { /* referred by test */ CDEBUG(D_NET, "Group %s is busy\n", name); - lstcon_group_put(grp); + lstcon_group_decref(grp); return -EBUSY; } @@ -705,7 +699,7 @@ lstcon_group_refresh(char *name, struct list_head *result_up) if (rc != 0) { /* local error, return */ CDEBUG(D_NET, "Can't create transaction: %d\n", rc); - lstcon_group_put(grp); + lstcon_group_decref(grp); return rc; } @@ -715,7 +709,7 @@ lstcon_group_refresh(char *name, struct list_head *result_up) lstcon_rpc_trans_destroy(trans); /* -ref for me */ - lstcon_group_put(grp); + lstcon_group_decref(grp); return rc; } @@ -797,7 +791,7 @@ lstcon_group_info(char *name, lstcon_ndlist_ent_t *gents_p, /* verbose query */ rc = lstcon_nodes_getent(&grp->grp_ndl_list, index_p, count_p, dents_up); - lstcon_group_put(grp); + lstcon_group_decref(grp); return rc; } @@ -806,7 +800,7 @@ lstcon_group_info(char *name, lstcon_ndlist_ent_t *gents_p, LIBCFS_ALLOC(gentp, sizeof(lstcon_ndlist_ent_t)); if (gentp == NULL) { CERROR("Can't allocate ndlist_ent\n"); - lstcon_group_put(grp); + lstcon_group_decref(grp); return -ENOMEM; } @@ -819,7 +813,7 @@ lstcon_group_info(char *name, lstcon_ndlist_ent_t *gents_p, LIBCFS_FREE(gentp, sizeof(lstcon_ndlist_ent_t)); - lstcon_group_put(grp); + lstcon_group_decref(grp); return 0; } @@ -1096,8 +1090,8 @@ lstcon_batch_destroy(lstcon_batch_t *bat) list_del(&test->tes_link); - lstcon_group_put(test->tes_src_grp); - lstcon_group_put(test->tes_dst_grp); + lstcon_group_decref(test->tes_src_grp); + lstcon_group_decref(test->tes_dst_grp); LIBCFS_FREE(test, offsetof(lstcon_test_t, tes_param[test->tes_paramlen])); @@ -1352,10 +1346,10 @@ out: LIBCFS_FREE(test, offsetof(lstcon_test_t, tes_param[paramlen])); if (dst_grp != NULL) - lstcon_group_put(dst_grp); + lstcon_group_decref(dst_grp); if (src_grp != NULL) - lstcon_group_put(src_grp); + lstcon_group_decref(src_grp); return rc; } @@ -1518,7 +1512,7 @@ lstcon_group_stat(char *grp_name, int timeout, struct list_head *result_up) rc = lstcon_ndlist_stat(&grp->grp_ndl_list, timeout, result_up); - lstcon_group_put(grp); + lstcon_group_decref(grp); return rc; } @@ -1556,13 +1550,13 @@ lstcon_nodes_stat(int count, lnet_process_id_t *ids_up, } if (rc != 0) { - lstcon_group_put(tmp); + lstcon_group_decref(tmp); return rc; } rc = lstcon_ndlist_stat(&tmp->grp_ndl_list, timeout, result_up); - lstcon_group_put(tmp); + lstcon_group_decref(tmp); return rc; } @@ -1629,7 +1623,7 @@ lstcon_group_debug(int timeout, char *name, rc = lstcon_debug_ndlist(&grp->grp_ndl_list, NULL, timeout, result_up); - lstcon_group_put(grp); + lstcon_group_decref(grp); return rc; } @@ -1666,14 +1660,14 @@ lstcon_nodes_debug(int timeout, } if (rc != 0) { - lstcon_group_put(grp); + lstcon_group_decref(grp); return rc; } rc = lstcon_debug_ndlist(&grp->grp_ndl_list, NULL, timeout, result_up); - lstcon_group_put(grp); + lstcon_group_decref(grp); return rc; } @@ -1847,7 +1841,7 @@ lstcon_session_end(void) lstcon_group_t, grp_link); LASSERT(grp->grp_ref == 1); - lstcon_group_put(grp); + lstcon_group_decref(grp); } /* all nodes should be released */ @@ -1966,7 +1960,7 @@ lstcon_acceptor_handle(srpc_server_rpc_t *rpc) out: rep->msg_ses_feats = console_session.ses_features; if (grp != NULL) - lstcon_group_put(grp); + lstcon_group_decref(grp); mutex_unlock(&console_session.ses_mutex); -- GitLab From a2ce13a7bb03f7e09514e2022cf019ae790a97f0 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Thu, 29 Oct 2015 11:50:35 +0530 Subject: [PATCH 0065/2855] Staging: lustre: console: Remove irrelevant return statement Remove return statement from the function lstcon_group_ndlink_move() as its return type is void. Fix checkpatch WARNING: void function return statements are not generally useful Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/console.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c index 9748a0907c023..b1eceb4f48386 100644 --- a/drivers/staging/lustre/lnet/selftest/console.c +++ b/drivers/staging/lustre/lnet/selftest/console.c @@ -318,8 +318,6 @@ lstcon_group_ndlink_move(lstcon_group_t *old, list_add_tail(&ndl->ndl_hlink, &new->grp_ndl_hash[idx]); list_add_tail(&ndl->ndl_link, &new->grp_ndl_list); new->grp_nnode++; - - return; } static void -- GitLab From 7bcd831b8579212303ec7c30e975432b914493dc Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Thu, 29 Oct 2015 12:08:06 +0530 Subject: [PATCH 0066/2855] Staging: lustre: api-ni: Drop unneeded wrapper function Remove the function lnet_create_interface_cookie() and replace its call with the function ktime_get_ns(). Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/lnet/api-ni.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 395412639935c..284150f53f7db 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -356,15 +356,6 @@ lnet_counters_reset(void) } EXPORT_SYMBOL(lnet_counters_reset); -static __u64 -lnet_create_interface_cookie(void) -{ - /* NB the interface cookie in wire handles guards against delayed - * replies and ACKs appearing valid after reboot. - */ - return ktime_get_ns(); -} - static char * lnet_res_type2str(int type) { @@ -553,8 +544,11 @@ lnet_prepare(lnet_pid_t requested_pid) rc = lnet_create_remote_nets_table(); if (rc != 0) goto failed; - - the_lnet.ln_interface_cookie = lnet_create_interface_cookie(); + /* + * NB the interface cookie in wire handles guards against delayed + * replies and ACKs appearing valid after reboot. + */ + the_lnet.ln_interface_cookie = ktime_get_ns(); the_lnet.ln_counters = cfs_percpt_alloc(lnet_cpt_table(), sizeof(lnet_counters_t)); -- GitLab From cfa38118d3d736c7586e5b9a92b36c9b9b2bf5f3 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Thu, 29 Oct 2015 12:28:31 +0530 Subject: [PATCH 0067/2855] Staging: lustre: config: Remove unnecessary wrapper functions Remove the function lnet_ipaddr_free_enumeration() and replace all its calls with LIBCFS_FREE(). Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/lnet/config.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 1b3bc8386524f..4e8b54b86c7d1 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -1103,12 +1103,6 @@ lnet_match_networks(char **networksp, char *ip2nets, __u32 *ipaddrs, int nip) return count; } -static void -lnet_ipaddr_free_enumeration(__u32 *ipaddrs, int nip) -{ - LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs)); -} - static int lnet_ipaddr_enumerate(__u32 **ipaddrsp) { @@ -1169,7 +1163,7 @@ lnet_ipaddr_enumerate(__u32 **ipaddrsp) rc = nip; } } - lnet_ipaddr_free_enumeration(ipaddrs, nif); + LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs)); } return nip; } @@ -1195,7 +1189,7 @@ lnet_parse_ip2nets(char **networksp, char *ip2nets) } rc = lnet_match_networks(networksp, ip2nets, ipaddrs, nip); - lnet_ipaddr_free_enumeration(ipaddrs, nip); + LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs)); if (rc < 0) { LCONSOLE_ERROR_MSG(0x119, "Error %d parsing ip2nets\n", rc); -- GitLab From ab4199034f2ba29f6512e9eccbed46bdb0772e44 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Thu, 29 Oct 2015 18:59:14 +0530 Subject: [PATCH 0068/2855] Staging: lustre: rpc: Drop unnecessary wrapper function Remove the function srpc_post_active_rqtbuf() and replace its only call with the function srpc_post_active_rdma() by adding appropriate parameters. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/rpc.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c index 7005002c15dab..0d1e7caf7cd66 100644 --- a/drivers/staging/lustre/lnet/selftest/rpc.c +++ b/drivers/staging/lustre/lnet/selftest/rpc.c @@ -444,15 +444,6 @@ srpc_post_active_rdma(int portal, __u64 matchbits, void *buf, int len, return 0; } -static int -srpc_post_active_rqtbuf(lnet_process_id_t peer, int service, void *buf, - int len, lnet_handle_md_t *mdh, srpc_event_t *ev) -{ - return srpc_post_active_rdma(srpc_serv_portal(service), service, - buf, len, LNET_MD_OP_PUT, peer, - LNET_NID_ANY, mdh, ev); -} - static int srpc_post_passive_rqtbuf(int service, int local, void *buf, int len, lnet_handle_md_t *mdh, srpc_event_t *ev) @@ -798,9 +789,11 @@ srpc_send_request(srpc_client_rpc_t *rpc) ev->ev_data = rpc; ev->ev_type = SRPC_REQUEST_SENT; - rc = srpc_post_active_rqtbuf(rpc->crpc_dest, rpc->crpc_service, - &rpc->crpc_reqstmsg, sizeof(srpc_msg_t), - &rpc->crpc_reqstmdh, ev); + rc = srpc_post_active_rdma(srpc_serv_portal(rpc->crpc_service), + rpc->crpc_service, &rpc->crpc_reqstmsg, + sizeof(srpc_msg_t), LNET_MD_OP_PUT, + rpc->crpc_dest, LNET_NID_ANY, + &rpc->crpc_reqstmdh, ev); if (rc != 0) { LASSERT(rc == -ENOMEM); ev->ev_fired = 1; /* no more event expected */ -- GitLab From a13b1f3241fcc4fa09851dca1d73d9fca11d6275 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 29 Oct 2015 12:24:40 +0300 Subject: [PATCH 0069/2855] staging: lustre: remove o_ prefix from function pointers We mostly refer to these function pointers using macros that use macro magic to add the "o_" prefix to the front. It means that you can't use cscope to find the caller. Heck, you can't even grep for it. I looked at preserving the "o_" prefix by removing the macro magic and adding "o_" to all the call sites but then I realized that, really, the prefix doesn't add any value. Let's just remove it. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/obd.h | 188 +++++++++--------- .../staging/lustre/lustre/include/obd_class.h | 8 +- drivers/staging/lustre/lustre/lmv/lmv_obd.c | 34 ++-- drivers/staging/lustre/lustre/lov/lov_obd.c | 58 +++--- .../staging/lustre/lustre/mdc/mdc_request.c | 40 ++-- .../staging/lustre/lustre/mgc/mgc_request.c | 28 +-- .../staging/lustre/lustre/obdclass/genops.c | 4 +- .../lustre/lustre/obdecho/echo_client.c | 8 +- .../staging/lustre/lustre/osc/osc_request.c | 54 ++--- 9 files changed, 211 insertions(+), 211 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index 5e93afca34352..5aca9bb4b5364 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -963,123 +963,123 @@ struct md_enqueue_info { }; struct obd_ops { - struct module *o_owner; - int (*o_iocontrol)(unsigned int cmd, struct obd_export *exp, int len, - void *karg, void *uarg); - int (*o_get_info)(const struct lu_env *env, struct obd_export *, - __u32 keylen, void *key, __u32 *vallen, void *val, - struct lov_stripe_md *lsm); - int (*o_set_info_async)(const struct lu_env *, struct obd_export *, - __u32 keylen, void *key, - __u32 vallen, void *val, - struct ptlrpc_request_set *set); - int (*o_attach)(struct obd_device *dev, u32 len, void *data); - int (*o_detach)(struct obd_device *dev); - int (*o_setup)(struct obd_device *dev, struct lustre_cfg *cfg); - int (*o_precleanup)(struct obd_device *dev, - enum obd_cleanup_stage cleanup_stage); - int (*o_cleanup)(struct obd_device *dev); - int (*o_process_config)(struct obd_device *dev, u32 len, void *data); - int (*o_postrecov)(struct obd_device *dev); - int (*o_add_conn)(struct obd_import *imp, struct obd_uuid *uuid, - int priority); - int (*o_del_conn)(struct obd_import *imp, struct obd_uuid *uuid); + struct module *owner; + int (*iocontrol)(unsigned int cmd, struct obd_export *exp, int len, + void *karg, void *uarg); + int (*get_info)(const struct lu_env *env, struct obd_export *, + __u32 keylen, void *key, __u32 *vallen, void *val, + struct lov_stripe_md *lsm); + int (*set_info_async)(const struct lu_env *, struct obd_export *, + __u32 keylen, void *key, + __u32 vallen, void *val, + struct ptlrpc_request_set *set); + int (*attach)(struct obd_device *dev, u32 len, void *data); + int (*detach)(struct obd_device *dev); + int (*setup)(struct obd_device *dev, struct lustre_cfg *cfg); + int (*precleanup)(struct obd_device *dev, + enum obd_cleanup_stage cleanup_stage); + int (*cleanup)(struct obd_device *dev); + int (*process_config)(struct obd_device *dev, u32 len, void *data); + int (*postrecov)(struct obd_device *dev); + int (*add_conn)(struct obd_import *imp, struct obd_uuid *uuid, + int priority); + int (*del_conn)(struct obd_import *imp, struct obd_uuid *uuid); /* connect to the target device with given connection * data. @ocd->ocd_connect_flags is modified to reflect flags actually * granted by the target, which are guaranteed to be a subset of flags * asked for. If @ocd == NULL, use default parameters. */ - int (*o_connect)(const struct lu_env *env, - struct obd_export **exp, struct obd_device *src, - struct obd_uuid *cluuid, struct obd_connect_data *ocd, + int (*connect)(const struct lu_env *env, + struct obd_export **exp, struct obd_device *src, + struct obd_uuid *cluuid, struct obd_connect_data *ocd, + void *localdata); + int (*reconnect)(const struct lu_env *env, + struct obd_export *exp, struct obd_device *src, + struct obd_uuid *cluuid, + struct obd_connect_data *ocd, void *localdata); - int (*o_reconnect)(const struct lu_env *env, - struct obd_export *exp, struct obd_device *src, - struct obd_uuid *cluuid, - struct obd_connect_data *ocd, - void *localdata); - int (*o_disconnect)(struct obd_export *exp); + int (*disconnect)(struct obd_export *exp); /* Initialize/finalize fids infrastructure. */ - int (*o_fid_init)(struct obd_device *obd, - struct obd_export *exp, enum lu_cli_type type); - int (*o_fid_fini)(struct obd_device *obd); + int (*fid_init)(struct obd_device *obd, + struct obd_export *exp, enum lu_cli_type type); + int (*fid_fini)(struct obd_device *obd); /* Allocate new fid according to passed @hint. */ - int (*o_fid_alloc)(struct obd_export *exp, struct lu_fid *fid, - struct md_op_data *op_data); + int (*fid_alloc)(struct obd_export *exp, struct lu_fid *fid, + struct md_op_data *op_data); /* * Object with @fid is getting deleted, we may want to do something * about this. */ - int (*o_statfs)(const struct lu_env *, struct obd_export *exp, - struct obd_statfs *osfs, __u64 max_age, __u32 flags); - int (*o_statfs_async)(struct obd_export *exp, struct obd_info *oinfo, - __u64 max_age, struct ptlrpc_request_set *set); - int (*o_packmd)(struct obd_export *exp, struct lov_mds_md **disk_tgt, - struct lov_stripe_md *mem_src); - int (*o_unpackmd)(struct obd_export *exp, - struct lov_stripe_md **mem_tgt, - struct lov_mds_md *disk_src, int disk_len); - int (*o_preallocate)(struct lustre_handle *, u32 *req, u64 *ids); - int (*o_create)(const struct lu_env *env, struct obd_export *exp, - struct obdo *oa, struct lov_stripe_md **ea, - struct obd_trans_info *oti); - int (*o_destroy)(const struct lu_env *env, struct obd_export *exp, - struct obdo *oa, struct lov_stripe_md *ea, - struct obd_trans_info *oti, struct obd_export *md_exp); - int (*o_setattr)(const struct lu_env *, struct obd_export *exp, - struct obd_info *oinfo, struct obd_trans_info *oti); - int (*o_setattr_async)(struct obd_export *exp, struct obd_info *oinfo, - struct obd_trans_info *oti, - struct ptlrpc_request_set *rqset); - int (*o_getattr)(const struct lu_env *env, struct obd_export *exp, - struct obd_info *oinfo); - int (*o_getattr_async)(struct obd_export *exp, struct obd_info *oinfo, - struct ptlrpc_request_set *set); - int (*o_adjust_kms)(struct obd_export *exp, struct lov_stripe_md *lsm, - u64 size, int shrink); - int (*o_preprw)(const struct lu_env *env, int cmd, - struct obd_export *exp, struct obdo *oa, int objcount, - struct obd_ioobj *obj, struct niobuf_remote *remote, - int *nr_pages, struct niobuf_local *local, - struct obd_trans_info *oti); - int (*o_commitrw)(const struct lu_env *env, int cmd, - struct obd_export *exp, struct obdo *oa, - int objcount, struct obd_ioobj *obj, - struct niobuf_remote *remote, int pages, - struct niobuf_local *local, - struct obd_trans_info *oti, int rc); - int (*o_find_cbdata)(struct obd_export *, struct lov_stripe_md *, - ldlm_iterator_t it, void *data); - int (*o_init_export)(struct obd_export *exp); - int (*o_destroy_export)(struct obd_export *exp); + int (*statfs)(const struct lu_env *, struct obd_export *exp, + struct obd_statfs *osfs, __u64 max_age, __u32 flags); + int (*statfs_async)(struct obd_export *exp, struct obd_info *oinfo, + __u64 max_age, struct ptlrpc_request_set *set); + int (*packmd)(struct obd_export *exp, struct lov_mds_md **disk_tgt, + struct lov_stripe_md *mem_src); + int (*unpackmd)(struct obd_export *exp, + struct lov_stripe_md **mem_tgt, + struct lov_mds_md *disk_src, int disk_len); + int (*preallocate)(struct lustre_handle *, u32 *req, u64 *ids); + int (*create)(const struct lu_env *env, struct obd_export *exp, + struct obdo *oa, struct lov_stripe_md **ea, + struct obd_trans_info *oti); + int (*destroy)(const struct lu_env *env, struct obd_export *exp, + struct obdo *oa, struct lov_stripe_md *ea, + struct obd_trans_info *oti, struct obd_export *md_exp); + int (*setattr)(const struct lu_env *, struct obd_export *exp, + struct obd_info *oinfo, struct obd_trans_info *oti); + int (*setattr_async)(struct obd_export *exp, struct obd_info *oinfo, + struct obd_trans_info *oti, + struct ptlrpc_request_set *rqset); + int (*getattr)(const struct lu_env *env, struct obd_export *exp, + struct obd_info *oinfo); + int (*getattr_async)(struct obd_export *exp, struct obd_info *oinfo, + struct ptlrpc_request_set *set); + int (*adjust_kms)(struct obd_export *exp, struct lov_stripe_md *lsm, + u64 size, int shrink); + int (*preprw)(const struct lu_env *env, int cmd, + struct obd_export *exp, struct obdo *oa, int objcount, + struct obd_ioobj *obj, struct niobuf_remote *remote, + int *nr_pages, struct niobuf_local *local, + struct obd_trans_info *oti); + int (*commitrw)(const struct lu_env *env, int cmd, + struct obd_export *exp, struct obdo *oa, + int objcount, struct obd_ioobj *obj, + struct niobuf_remote *remote, int pages, + struct niobuf_local *local, + struct obd_trans_info *oti, int rc); + int (*find_cbdata)(struct obd_export *, struct lov_stripe_md *, + ldlm_iterator_t it, void *data); + int (*init_export)(struct obd_export *exp); + int (*destroy_export)(struct obd_export *exp); /* metadata-only methods */ - int (*o_import_event)(struct obd_device *, struct obd_import *, - enum obd_import_event); + int (*import_event)(struct obd_device *, struct obd_import *, + enum obd_import_event); - int (*o_notify)(struct obd_device *obd, struct obd_device *watched, - enum obd_notify_event ev, void *data); + int (*notify)(struct obd_device *obd, struct obd_device *watched, + enum obd_notify_event ev, void *data); - int (*o_health_check)(const struct lu_env *env, struct obd_device *); - struct obd_uuid *(*o_get_uuid)(struct obd_export *exp); + int (*health_check)(const struct lu_env *env, struct obd_device *); + struct obd_uuid *(*get_uuid)(struct obd_export *exp); /* quota methods */ - int (*o_quotacheck)(struct obd_device *, struct obd_export *, - struct obd_quotactl *); - int (*o_quotactl)(struct obd_device *, struct obd_export *, + int (*quotacheck)(struct obd_device *, struct obd_export *, struct obd_quotactl *); + int (*quotactl)(struct obd_device *, struct obd_export *, + struct obd_quotactl *); /* pools methods */ - int (*o_pool_new)(struct obd_device *obd, char *poolname); - int (*o_pool_del)(struct obd_device *obd, char *poolname); - int (*o_pool_add)(struct obd_device *obd, char *poolname, - char *ostname); - int (*o_pool_rem)(struct obd_device *obd, char *poolname, - char *ostname); - void (*o_getref)(struct obd_device *obd); - void (*o_putref)(struct obd_device *obd); + int (*pool_new)(struct obd_device *obd, char *poolname); + int (*pool_del)(struct obd_device *obd, char *poolname); + int (*pool_add)(struct obd_device *obd, char *poolname, + char *ostname); + int (*pool_rem)(struct obd_device *obd, char *poolname, + char *ostname); + void (*getref)(struct obd_device *obd); + void (*putref)(struct obd_device *obd); /* * NOTE: If adding ops, add another LPROCFS_OBD_OP_INIT() line * to lprocfs_alloc_obd_stats() in obdclass/lprocfs_status.c. diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index fd5f3731db926..84bd62258d51f 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -270,7 +270,7 @@ void obdo_to_ioobj(struct obdo *oa, struct obd_ioobj *ioobj); void md_from_obdo(struct md_op_data *op_data, struct obdo *oa, u32 valid); #define OBT(dev) (dev)->obd_type -#define OBP(dev, op) (dev)->obd_type->typ_dt_ops->o_ ## op +#define OBP(dev, op) (dev)->obd_type->typ_dt_ops->op #define MDP(dev, op) (dev)->obd_type->typ_md_ops->m_ ## op #define CTXTP(ctxt, op) (ctxt)->loc_logops->lop_##op @@ -301,9 +301,9 @@ static inline int obd_check_dev_active(struct obd_device *obd) } #define OBD_COUNTER_OFFSET(op) \ - ((offsetof(struct obd_ops, o_ ## op) - \ - offsetof(struct obd_ops, o_iocontrol)) \ - / sizeof(((struct obd_ops *)(0))->o_iocontrol)) + ((offsetof(struct obd_ops, op) - \ + offsetof(struct obd_ops, iocontrol)) \ + / sizeof(((struct obd_ops *)(0))->iocontrol)) #define OBD_COUNTER_INCREMENT(obdx, op) \ if ((obdx)->obd_stats != NULL) { \ diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c index 635a93cc94dee..947a127c48d06 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c @@ -2744,23 +2744,23 @@ static int lmv_quotacheck(struct obd_device *unused, struct obd_export *exp, } static struct obd_ops lmv_obd_ops = { - .o_owner = THIS_MODULE, - .o_setup = lmv_setup, - .o_cleanup = lmv_cleanup, - .o_precleanup = lmv_precleanup, - .o_process_config = lmv_process_config, - .o_connect = lmv_connect, - .o_disconnect = lmv_disconnect, - .o_statfs = lmv_statfs, - .o_get_info = lmv_get_info, - .o_set_info_async = lmv_set_info_async, - .o_packmd = lmv_packmd, - .o_unpackmd = lmv_unpackmd, - .o_notify = lmv_notify, - .o_get_uuid = lmv_get_uuid, - .o_iocontrol = lmv_iocontrol, - .o_quotacheck = lmv_quotacheck, - .o_quotactl = lmv_quotactl + .owner = THIS_MODULE, + .setup = lmv_setup, + .cleanup = lmv_cleanup, + .precleanup = lmv_precleanup, + .process_config = lmv_process_config, + .connect = lmv_connect, + .disconnect = lmv_disconnect, + .statfs = lmv_statfs, + .get_info = lmv_get_info, + .set_info_async = lmv_set_info_async, + .packmd = lmv_packmd, + .unpackmd = lmv_unpackmd, + .notify = lmv_notify, + .get_uuid = lmv_get_uuid, + .iocontrol = lmv_iocontrol, + .quotacheck = lmv_quotacheck, + .quotactl = lmv_quotactl }; static struct md_ops lmv_md_ops = { diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c index 7abe484c07c04..6bd4ac051274f 100644 --- a/drivers/staging/lustre/lustre/lov/lov_obd.c +++ b/drivers/staging/lustre/lustre/lov/lov_obd.c @@ -2277,35 +2277,35 @@ out: } static struct obd_ops lov_obd_ops = { - .o_owner = THIS_MODULE, - .o_setup = lov_setup, - .o_precleanup = lov_precleanup, - .o_cleanup = lov_cleanup, - /*.o_process_config = lov_process_config,*/ - .o_connect = lov_connect, - .o_disconnect = lov_disconnect, - .o_statfs = lov_statfs, - .o_statfs_async = lov_statfs_async, - .o_packmd = lov_packmd, - .o_unpackmd = lov_unpackmd, - .o_create = lov_create, - .o_destroy = lov_destroy, - .o_getattr_async = lov_getattr_async, - .o_setattr_async = lov_setattr_async, - .o_adjust_kms = lov_adjust_kms, - .o_find_cbdata = lov_find_cbdata, - .o_iocontrol = lov_iocontrol, - .o_get_info = lov_get_info, - .o_set_info_async = lov_set_info_async, - .o_notify = lov_notify, - .o_pool_new = lov_pool_new, - .o_pool_rem = lov_pool_remove, - .o_pool_add = lov_pool_add, - .o_pool_del = lov_pool_del, - .o_getref = lov_getref, - .o_putref = lov_putref, - .o_quotactl = lov_quotactl, - .o_quotacheck = lov_quotacheck, + .owner = THIS_MODULE, + .setup = lov_setup, + .precleanup = lov_precleanup, + .cleanup = lov_cleanup, + /*.process_config = lov_process_config,*/ + .connect = lov_connect, + .disconnect = lov_disconnect, + .statfs = lov_statfs, + .statfs_async = lov_statfs_async, + .packmd = lov_packmd, + .unpackmd = lov_unpackmd, + .create = lov_create, + .destroy = lov_destroy, + .getattr_async = lov_getattr_async, + .setattr_async = lov_setattr_async, + .adjust_kms = lov_adjust_kms, + .find_cbdata = lov_find_cbdata, + .iocontrol = lov_iocontrol, + .get_info = lov_get_info, + .set_info_async = lov_set_info_async, + .notify = lov_notify, + .pool_new = lov_pool_new, + .pool_rem = lov_pool_remove, + .pool_add = lov_pool_add, + .pool_del = lov_pool_del, + .getref = lov_getref, + .putref = lov_putref, + .quotactl = lov_quotactl, + .quotacheck = lov_quotacheck, }; struct kmem_cache *lov_oinfo_slab; diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 16a5a10d371ed..34a88675e3615 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -2460,26 +2460,26 @@ static int mdc_get_remote_perm(struct obd_export *exp, const struct lu_fid *fid, } static struct obd_ops mdc_obd_ops = { - .o_owner = THIS_MODULE, - .o_setup = mdc_setup, - .o_precleanup = mdc_precleanup, - .o_cleanup = mdc_cleanup, - .o_add_conn = client_import_add_conn, - .o_del_conn = client_import_del_conn, - .o_connect = client_connect_import, - .o_disconnect = client_disconnect_export, - .o_iocontrol = mdc_iocontrol, - .o_set_info_async = mdc_set_info_async, - .o_statfs = mdc_statfs, - .o_fid_init = client_fid_init, - .o_fid_fini = client_fid_fini, - .o_fid_alloc = mdc_fid_alloc, - .o_import_event = mdc_import_event, - .o_get_info = mdc_get_info, - .o_process_config = mdc_process_config, - .o_get_uuid = mdc_get_uuid, - .o_quotactl = mdc_quotactl, - .o_quotacheck = mdc_quotacheck + .owner = THIS_MODULE, + .setup = mdc_setup, + .precleanup = mdc_precleanup, + .cleanup = mdc_cleanup, + .add_conn = client_import_add_conn, + .del_conn = client_import_del_conn, + .connect = client_connect_import, + .disconnect = client_disconnect_export, + .iocontrol = mdc_iocontrol, + .set_info_async = mdc_set_info_async, + .statfs = mdc_statfs, + .fid_init = client_fid_init, + .fid_fini = client_fid_fini, + .fid_alloc = mdc_fid_alloc, + .import_event = mdc_import_event, + .get_info = mdc_get_info, + .process_config = mdc_process_config, + .get_uuid = mdc_get_uuid, + .quotactl = mdc_quotactl, + .quotacheck = mdc_quotacheck }; static struct md_ops mdc_md_ops = { diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c index 2d6de6c19b9f1..b73f8f21b6c52 100644 --- a/drivers/staging/lustre/lustre/mgc/mgc_request.c +++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c @@ -1698,20 +1698,20 @@ out: } static struct obd_ops mgc_obd_ops = { - .o_owner = THIS_MODULE, - .o_setup = mgc_setup, - .o_precleanup = mgc_precleanup, - .o_cleanup = mgc_cleanup, - .o_add_conn = client_import_add_conn, - .o_del_conn = client_import_del_conn, - .o_connect = client_connect_import, - .o_disconnect = client_disconnect_export, - /* .o_enqueue = mgc_enqueue, */ - /* .o_iocontrol = mgc_iocontrol, */ - .o_set_info_async = mgc_set_info_async, - .o_get_info = mgc_get_info, - .o_import_event = mgc_import_event, - .o_process_config = mgc_process_config, + .owner = THIS_MODULE, + .setup = mgc_setup, + .precleanup = mgc_precleanup, + .cleanup = mgc_cleanup, + .add_conn = client_import_add_conn, + .del_conn = client_import_del_conn, + .connect = client_connect_import, + .disconnect = client_disconnect_export, + /* .enqueue = mgc_enqueue, */ + /* .iocontrol = mgc_iocontrol, */ + .set_info_async = mgc_set_info_async, + .get_info = mgc_get_info, + .import_event = mgc_import_event, + .process_config = mgc_process_config, }; static int __init mgc_init(void) diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c index 6477aeb88028c..08966562d7fef 100644 --- a/drivers/staging/lustre/lustre/obdclass/genops.c +++ b/drivers/staging/lustre/lustre/obdclass/genops.c @@ -132,7 +132,7 @@ static struct obd_type *class_get_type(const char *name) if (type) { spin_lock(&type->obd_type_lock); type->typ_refcnt++; - try_module_get(type->typ_dt_ops->o_owner); + try_module_get(type->typ_dt_ops->owner); spin_unlock(&type->obd_type_lock); } return type; @@ -143,7 +143,7 @@ void class_put_type(struct obd_type *type) LASSERT(type); spin_lock(&type->obd_type_lock); type->typ_refcnt--; - module_put(type->typ_dt_ops->o_owner); + module_put(type->typ_dt_ops->owner); spin_unlock(&type->obd_type_lock); } EXPORT_SYMBOL(class_put_type); diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c index f61ef669644cd..f49564f6bb894 100644 --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c @@ -2128,10 +2128,10 @@ static int echo_client_disconnect(struct obd_export *exp) } 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) diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index 367f83af12c00..18118fcf7d37b 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -3255,33 +3255,33 @@ static int osc_process_config(struct obd_device *obd, u32 len, void *buf) } struct obd_ops osc_obd_ops = { - .o_owner = THIS_MODULE, - .o_setup = osc_setup, - .o_precleanup = osc_precleanup, - .o_cleanup = osc_cleanup, - .o_add_conn = client_import_add_conn, - .o_del_conn = client_import_del_conn, - .o_connect = client_connect_import, - .o_reconnect = osc_reconnect, - .o_disconnect = osc_disconnect, - .o_statfs = osc_statfs, - .o_statfs_async = osc_statfs_async, - .o_packmd = osc_packmd, - .o_unpackmd = osc_unpackmd, - .o_create = osc_create, - .o_destroy = osc_destroy, - .o_getattr = osc_getattr, - .o_getattr_async = osc_getattr_async, - .o_setattr = osc_setattr, - .o_setattr_async = osc_setattr_async, - .o_find_cbdata = osc_find_cbdata, - .o_iocontrol = osc_iocontrol, - .o_get_info = osc_get_info, - .o_set_info_async = osc_set_info_async, - .o_import_event = osc_import_event, - .o_process_config = osc_process_config, - .o_quotactl = osc_quotactl, - .o_quotacheck = osc_quotacheck, + .owner = THIS_MODULE, + .setup = osc_setup, + .precleanup = osc_precleanup, + .cleanup = osc_cleanup, + .add_conn = client_import_add_conn, + .del_conn = client_import_del_conn, + .connect = client_connect_import, + .reconnect = osc_reconnect, + .disconnect = osc_disconnect, + .statfs = osc_statfs, + .statfs_async = osc_statfs_async, + .packmd = osc_packmd, + .unpackmd = osc_unpackmd, + .create = osc_create, + .destroy = osc_destroy, + .getattr = osc_getattr, + .getattr_async = osc_getattr_async, + .setattr = osc_setattr, + .setattr_async = osc_setattr_async, + .find_cbdata = osc_find_cbdata, + .iocontrol = osc_iocontrol, + .get_info = osc_get_info, + .set_info_async = osc_set_info_async, + .import_event = osc_import_event, + .process_config = osc_process_config, + .quotactl = osc_quotactl, + .quotacheck = osc_quotacheck, }; extern struct lu_kmem_descr osc_caches[]; -- GitLab From df18a80af3d77d58223d8d88c1660c51108106e8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 29 Oct 2015 12:26:36 +0300 Subject: [PATCH 0070/2855] staging: lustre: remove m_ prefix from function pointers All the callers call these function pointers without the "m_" prefix and use macro magic to add it later behind the scenes. It means that you can't grep for the call sites. I considered modifying the call sites but in the end I decided that the "m_" prefix doesn't add anything so we can just get rid of it. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/obd.h | 134 +++++++++--------- .../staging/lustre/lustre/include/obd_class.h | 8 +- drivers/staging/lustre/lustre/lmv/lmv_obd.c | 58 ++++---- .../staging/lustre/lustre/mdc/mdc_request.c | 60 ++++---- 4 files changed, 130 insertions(+), 130 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index 5aca9bb4b5364..5c90b59cf0db5 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -1124,89 +1124,89 @@ struct md_open_data { struct lookup_intent; struct md_ops { - int (*m_getstatus)(struct obd_export *, struct lu_fid *); - int (*m_null_inode)(struct obd_export *, const struct lu_fid *); - int (*m_find_cbdata)(struct obd_export *, const struct lu_fid *, - ldlm_iterator_t, void *); - int (*m_close)(struct obd_export *, struct md_op_data *, - struct md_open_data *, struct ptlrpc_request **); - int (*m_create)(struct obd_export *, struct md_op_data *, - const void *, int, int, __u32, __u32, cfs_cap_t, - __u64, struct ptlrpc_request **); - int (*m_done_writing)(struct obd_export *, struct md_op_data *, - struct md_open_data *); - int (*m_enqueue)(struct obd_export *, struct ldlm_enqueue_info *, - struct lookup_intent *, struct md_op_data *, - struct lustre_handle *, void *, int, - struct ptlrpc_request **, __u64); - int (*m_getattr)(struct obd_export *, struct md_op_data *, - struct ptlrpc_request **); - int (*m_getattr_name)(struct obd_export *, struct md_op_data *, - struct ptlrpc_request **); - int (*m_intent_lock)(struct obd_export *, struct md_op_data *, - void *, int, struct lookup_intent *, int, - struct ptlrpc_request **, - ldlm_blocking_callback, __u64); - int (*m_link)(struct obd_export *, struct md_op_data *, + int (*getstatus)(struct obd_export *, struct lu_fid *); + int (*null_inode)(struct obd_export *, const struct lu_fid *); + int (*find_cbdata)(struct obd_export *, const struct lu_fid *, + ldlm_iterator_t, void *); + int (*close)(struct obd_export *, struct md_op_data *, + struct md_open_data *, struct ptlrpc_request **); + int (*create)(struct obd_export *, struct md_op_data *, + const void *, int, int, __u32, __u32, cfs_cap_t, + __u64, struct ptlrpc_request **); + int (*done_writing)(struct obd_export *, struct md_op_data *, + struct md_open_data *); + int (*enqueue)(struct obd_export *, struct ldlm_enqueue_info *, + struct lookup_intent *, struct md_op_data *, + struct lustre_handle *, void *, int, + struct ptlrpc_request **, __u64); + int (*getattr)(struct obd_export *, struct md_op_data *, + struct ptlrpc_request **); + int (*getattr_name)(struct obd_export *, struct md_op_data *, + struct ptlrpc_request **); + int (*intent_lock)(struct obd_export *, struct md_op_data *, + void *, int, struct lookup_intent *, int, + struct ptlrpc_request **, + ldlm_blocking_callback, __u64); + int (*link)(struct obd_export *, struct md_op_data *, + struct ptlrpc_request **); + int (*rename)(struct obd_export *, struct md_op_data *, + const char *, int, const char *, int, struct ptlrpc_request **); - int (*m_rename)(struct obd_export *, struct md_op_data *, - const char *, int, const char *, int, - struct ptlrpc_request **); - int (*m_is_subdir)(struct obd_export *, const struct lu_fid *, - const struct lu_fid *, + int (*is_subdir)(struct obd_export *, const struct lu_fid *, + const struct lu_fid *, struct ptlrpc_request **); - int (*m_setattr)(struct obd_export *, struct md_op_data *, void *, - int, void *, int, struct ptlrpc_request **, + int (*setattr)(struct obd_export *, struct md_op_data *, void *, + int, void *, int, struct ptlrpc_request **, struct md_open_data **mod); - int (*m_sync)(struct obd_export *, const struct lu_fid *, + int (*sync)(struct obd_export *, const struct lu_fid *, + struct ptlrpc_request **); + int (*readpage)(struct obd_export *, struct md_op_data *, + struct page **, struct ptlrpc_request **); + + int (*unlink)(struct obd_export *, struct md_op_data *, struct ptlrpc_request **); - int (*m_readpage)(struct obd_export *, struct md_op_data *, - struct page **, struct ptlrpc_request **); - int (*m_unlink)(struct obd_export *, struct md_op_data *, + int (*setxattr)(struct obd_export *, const struct lu_fid *, + u64, const char *, const char *, int, int, int, __u32, struct ptlrpc_request **); - int (*m_setxattr)(struct obd_export *, const struct lu_fid *, - u64, const char *, const char *, int, int, int, __u32, - struct ptlrpc_request **); - - int (*m_getxattr)(struct obd_export *, const struct lu_fid *, - u64, const char *, const char *, int, int, int, - struct ptlrpc_request **); + int (*getxattr)(struct obd_export *, const struct lu_fid *, + u64, const char *, const char *, int, int, int, + struct ptlrpc_request **); - int (*m_init_ea_size)(struct obd_export *, int, int, int, int); + int (*init_ea_size)(struct obd_export *, int, int, int, int); - int (*m_get_lustre_md)(struct obd_export *, struct ptlrpc_request *, - struct obd_export *, struct obd_export *, - struct lustre_md *); + int (*get_lustre_md)(struct obd_export *, struct ptlrpc_request *, + struct obd_export *, struct obd_export *, + struct lustre_md *); - int (*m_free_lustre_md)(struct obd_export *, struct lustre_md *); + int (*free_lustre_md)(struct obd_export *, struct lustre_md *); - int (*m_set_open_replay_data)(struct obd_export *, - struct obd_client_handle *, - struct lookup_intent *); - int (*m_clear_open_replay_data)(struct obd_export *, - struct obd_client_handle *); - int (*m_set_lock_data)(struct obd_export *, __u64 *, void *, __u64 *); + int (*set_open_replay_data)(struct obd_export *, + struct obd_client_handle *, + struct lookup_intent *); + int (*clear_open_replay_data)(struct obd_export *, + struct obd_client_handle *); + int (*set_lock_data)(struct obd_export *, __u64 *, void *, __u64 *); - ldlm_mode_t (*m_lock_match)(struct obd_export *, __u64, - const struct lu_fid *, ldlm_type_t, - ldlm_policy_data_t *, ldlm_mode_t, - struct lustre_handle *); + ldlm_mode_t (*lock_match)(struct obd_export *, __u64, + const struct lu_fid *, ldlm_type_t, + ldlm_policy_data_t *, ldlm_mode_t, + struct lustre_handle *); - int (*m_cancel_unused)(struct obd_export *, const struct lu_fid *, - ldlm_policy_data_t *, ldlm_mode_t, - ldlm_cancel_flags_t flags, void *opaque); + int (*cancel_unused)(struct obd_export *, const struct lu_fid *, + ldlm_policy_data_t *, ldlm_mode_t, + ldlm_cancel_flags_t flags, void *opaque); - int (*m_get_remote_perm)(struct obd_export *, const struct lu_fid *, - __u32, struct ptlrpc_request **); + int (*get_remote_perm)(struct obd_export *, const struct lu_fid *, + __u32, struct ptlrpc_request **); - int (*m_intent_getattr_async)(struct obd_export *, - struct md_enqueue_info *, - struct ldlm_enqueue_info *); + int (*intent_getattr_async)(struct obd_export *, + struct md_enqueue_info *, + struct ldlm_enqueue_info *); - int (*m_revalidate_lock)(struct obd_export *, struct lookup_intent *, - struct lu_fid *, __u64 *bits); + int (*revalidate_lock)(struct obd_export *, struct lookup_intent *, + struct lu_fid *, __u64 *bits); /* * NOTE: If adding ops, add another LPROCFS_MD_OP_INIT() line to diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index 84bd62258d51f..0b7e90ac7818d 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -271,7 +271,7 @@ void md_from_obdo(struct md_op_data *op_data, struct obdo *oa, u32 valid); #define OBT(dev) (dev)->obd_type #define OBP(dev, op) (dev)->obd_type->typ_dt_ops->op -#define MDP(dev, op) (dev)->obd_type->typ_md_ops->m_ ## op +#define MDP(dev, op) (dev)->obd_type->typ_md_ops->op #define CTXTP(ctxt, op) (ctxt)->loc_logops->lop_##op /* Ensure obd_setup: used for cleanup which must be called @@ -324,9 +324,9 @@ static inline int obd_check_dev_active(struct obd_device *obd) } #define MD_COUNTER_OFFSET(op) \ - ((offsetof(struct md_ops, m_ ## op) - \ - offsetof(struct md_ops, m_getstatus)) \ - / sizeof(((struct md_ops *)(0))->m_getstatus)) + ((offsetof(struct md_ops, op) - \ + offsetof(struct md_ops, getstatus)) \ + / sizeof(((struct md_ops *)(0))->getstatus)) #define MD_COUNTER_INCREMENT(obdx, op) \ if ((obd)->md_stats != NULL) { \ diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c index 947a127c48d06..55f801ba98266 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c @@ -2764,35 +2764,35 @@ static struct obd_ops lmv_obd_ops = { }; static struct md_ops lmv_md_ops = { - .m_getstatus = lmv_getstatus, - .m_null_inode = lmv_null_inode, - .m_find_cbdata = lmv_find_cbdata, - .m_close = lmv_close, - .m_create = lmv_create, - .m_done_writing = lmv_done_writing, - .m_enqueue = lmv_enqueue, - .m_getattr = lmv_getattr, - .m_getxattr = lmv_getxattr, - .m_getattr_name = lmv_getattr_name, - .m_intent_lock = lmv_intent_lock, - .m_link = lmv_link, - .m_rename = lmv_rename, - .m_setattr = lmv_setattr, - .m_setxattr = lmv_setxattr, - .m_sync = lmv_sync, - .m_readpage = lmv_readpage, - .m_unlink = lmv_unlink, - .m_init_ea_size = lmv_init_ea_size, - .m_cancel_unused = lmv_cancel_unused, - .m_set_lock_data = lmv_set_lock_data, - .m_lock_match = lmv_lock_match, - .m_get_lustre_md = lmv_get_lustre_md, - .m_free_lustre_md = lmv_free_lustre_md, - .m_set_open_replay_data = lmv_set_open_replay_data, - .m_clear_open_replay_data = lmv_clear_open_replay_data, - .m_get_remote_perm = lmv_get_remote_perm, - .m_intent_getattr_async = lmv_intent_getattr_async, - .m_revalidate_lock = lmv_revalidate_lock + .getstatus = lmv_getstatus, + .null_inode = lmv_null_inode, + .find_cbdata = lmv_find_cbdata, + .close = lmv_close, + .create = lmv_create, + .done_writing = lmv_done_writing, + .enqueue = lmv_enqueue, + .getattr = lmv_getattr, + .getxattr = lmv_getxattr, + .getattr_name = lmv_getattr_name, + .intent_lock = lmv_intent_lock, + .link = lmv_link, + .rename = lmv_rename, + .setattr = lmv_setattr, + .setxattr = lmv_setxattr, + .sync = lmv_sync, + .readpage = lmv_readpage, + .unlink = lmv_unlink, + .init_ea_size = lmv_init_ea_size, + .cancel_unused = lmv_cancel_unused, + .set_lock_data = lmv_set_lock_data, + .lock_match = lmv_lock_match, + .get_lustre_md = lmv_get_lustre_md, + .free_lustre_md = lmv_free_lustre_md, + .set_open_replay_data = lmv_set_open_replay_data, + .clear_open_replay_data = lmv_clear_open_replay_data, + .get_remote_perm = lmv_get_remote_perm, + .intent_getattr_async = lmv_intent_getattr_async, + .revalidate_lock = lmv_revalidate_lock }; static int __init lmv_init(void) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 34a88675e3615..5b78e7ab6d0bb 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -2483,36 +2483,36 @@ static struct obd_ops mdc_obd_ops = { }; static struct md_ops mdc_md_ops = { - .m_getstatus = mdc_getstatus, - .m_null_inode = mdc_null_inode, - .m_find_cbdata = mdc_find_cbdata, - .m_close = mdc_close, - .m_create = mdc_create, - .m_done_writing = mdc_done_writing, - .m_enqueue = mdc_enqueue, - .m_getattr = mdc_getattr, - .m_getattr_name = mdc_getattr_name, - .m_intent_lock = mdc_intent_lock, - .m_link = mdc_link, - .m_is_subdir = mdc_is_subdir, - .m_rename = mdc_rename, - .m_setattr = mdc_setattr, - .m_setxattr = mdc_setxattr, - .m_getxattr = mdc_getxattr, - .m_sync = mdc_sync, - .m_readpage = mdc_readpage, - .m_unlink = mdc_unlink, - .m_cancel_unused = mdc_cancel_unused, - .m_init_ea_size = mdc_init_ea_size, - .m_set_lock_data = mdc_set_lock_data, - .m_lock_match = mdc_lock_match, - .m_get_lustre_md = mdc_get_lustre_md, - .m_free_lustre_md = mdc_free_lustre_md, - .m_set_open_replay_data = mdc_set_open_replay_data, - .m_clear_open_replay_data = mdc_clear_open_replay_data, - .m_get_remote_perm = mdc_get_remote_perm, - .m_intent_getattr_async = mdc_intent_getattr_async, - .m_revalidate_lock = mdc_revalidate_lock + .getstatus = mdc_getstatus, + .null_inode = mdc_null_inode, + .find_cbdata = mdc_find_cbdata, + .close = mdc_close, + .create = mdc_create, + .done_writing = mdc_done_writing, + .enqueue = mdc_enqueue, + .getattr = mdc_getattr, + .getattr_name = mdc_getattr_name, + .intent_lock = mdc_intent_lock, + .link = mdc_link, + .is_subdir = mdc_is_subdir, + .rename = mdc_rename, + .setattr = mdc_setattr, + .setxattr = mdc_setxattr, + .getxattr = mdc_getxattr, + .sync = mdc_sync, + .readpage = mdc_readpage, + .unlink = mdc_unlink, + .cancel_unused = mdc_cancel_unused, + .init_ea_size = mdc_init_ea_size, + .set_lock_data = mdc_set_lock_data, + .lock_match = mdc_lock_match, + .get_lustre_md = mdc_get_lustre_md, + .free_lustre_md = mdc_free_lustre_md, + .set_open_replay_data = mdc_set_open_replay_data, + .clear_open_replay_data = mdc_clear_open_replay_data, + .get_remote_perm = mdc_get_remote_perm, + .intent_getattr_async = mdc_intent_getattr_async, + .revalidate_lock = mdc_revalidate_lock }; static int __init mdc_init(void) -- GitLab From 54cc3794cec410ec2f7daa00089777562218780a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 29 Oct 2015 16:51:23 +0300 Subject: [PATCH 0071/2855] staging: lustre: potential underflow in libcfs_kkuc_group_add() My static checker says that "group" is a user controlled number that can be negative leading to an array underflow. I have looked at it, and I'm not an expert enough in lustre to say for sure if it is really a bug. Anyway, it's simple enough to make the variable unsigned which pleases the static checker and makes it easier to audit. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h | 2 +- drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h index a989d2666230e..41f3d810aea4e 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h @@ -91,7 +91,7 @@ typedef int (*libcfs_kkuc_cb_t)(__u32 data, void *cb_arg); /* Kernel methods */ int libcfs_kkuc_msg_put(struct file *fp, void *payload); int libcfs_kkuc_group_put(int group, void *payload); -int libcfs_kkuc_group_add(struct file *fp, int uid, int group, +int libcfs_kkuc_group_add(struct file *fp, int uid, unsigned int group, __u32 data); int libcfs_kkuc_group_rem(int uid, int group); int libcfs_kkuc_group_foreach(int group, libcfs_kkuc_cb_t cb_func, diff --git a/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c b/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c index ad661a33a2110..d8230aec9a2bf 100644 --- a/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c +++ b/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c @@ -110,7 +110,8 @@ static DECLARE_RWSEM(kg_sem); * @param uid identifier for this receiver * @param group group number */ -int libcfs_kkuc_group_add(struct file *filp, int uid, int group, __u32 data) +int libcfs_kkuc_group_add(struct file *filp, int uid, unsigned int group, + __u32 data) { struct kkuc_reg *reg; -- GitLab From 358855b2681e16d047357599efd0884fab367419 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Fri, 30 Oct 2015 20:59:03 +0530 Subject: [PATCH 0072/2855] Staging: lustre: mdc: Declare local functions as static Declare mdc_get_lustre_md, mdc_free_lustre_md and mdc_clear_open_replay_data as static since they are used only in this particular file. Also remove corresponding declarations from header files. Signed-off-by: Shraddha Barke Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/mdc_internal.h | 8 -------- drivers/staging/lustre/lustre/mdc/mdc_request.c | 14 ++++++++------ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_internal.h b/drivers/staging/lustre/lustre/mdc/mdc_internal.h index 29b46f754726e..5e0c8b5ca573d 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_internal.h +++ b/drivers/staging/lustre/lustre/mdc/mdc_internal.h @@ -104,18 +104,10 @@ int mdc_open(struct obd_export *exp, u64 ino, int type, int flags, struct obd_client_handle; -int mdc_get_lustre_md(struct obd_export *md_exp, struct ptlrpc_request *req, - struct obd_export *dt_exp, struct obd_export *lmv_exp, - struct lustre_md *md); - -int mdc_free_lustre_md(struct obd_export *exp, struct lustre_md *md); - int mdc_set_open_replay_data(struct obd_export *exp, struct obd_client_handle *och, struct lookup_intent *it); -int mdc_clear_open_replay_data(struct obd_export *exp, - struct obd_client_handle *och); void mdc_commit_open(struct ptlrpc_request *req); void mdc_replay_open(struct ptlrpc_request *req); diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 5b78e7ab6d0bb..3dd0d01856f10 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -447,9 +447,11 @@ static int mdc_unpack_acl(struct ptlrpc_request *req, struct lustre_md *md) #define mdc_unpack_acl(req, md) 0 #endif -int mdc_get_lustre_md(struct obd_export *exp, struct ptlrpc_request *req, - struct obd_export *dt_exp, struct obd_export *md_exp, - struct lustre_md *md) +static int mdc_get_lustre_md(struct obd_export *exp, + struct ptlrpc_request *req, + struct obd_export *dt_exp, + struct obd_export *md_exp, + struct lustre_md *md) { struct req_capsule *pill = &req->rq_pill; int rc; @@ -573,7 +575,7 @@ out: return rc; } -int mdc_free_lustre_md(struct obd_export *exp, struct lustre_md *md) +static int mdc_free_lustre_md(struct obd_export *exp, struct lustre_md *md) { return 0; } @@ -737,8 +739,8 @@ static void mdc_free_open(struct md_open_data *mod) ptlrpc_request_committed(mod->mod_close_req, committed); } -int mdc_clear_open_replay_data(struct obd_export *exp, - struct obd_client_handle *och) +static int mdc_clear_open_replay_data(struct obd_export *exp, + struct obd_client_handle *och) { struct md_open_data *mod = och->och_mod; -- GitLab From c3cdad8899c6608a2e928e1ce4fcaaddbf17cc96 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Fri, 30 Oct 2015 20:59:04 +0530 Subject: [PATCH 0073/2855] Staging: lustre: mdc: Remove unused mdc_open function from header Function mdc_open is declared in header file but it is not used anywhere. Hence drop the declaration. Signed-off-by: Shraddha Barke Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/mdc_internal.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_internal.h b/drivers/staging/lustre/lustre/mdc/mdc_internal.h index 5e0c8b5ca573d..a41e2b9396cdd 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_internal.h +++ b/drivers/staging/lustre/lustre/mdc/mdc_internal.h @@ -97,11 +97,6 @@ int mdc_resource_get_unused(struct obd_export *exp, const struct lu_fid *fid, /* mdc/mdc_request.c */ int mdc_fid_alloc(struct obd_export *exp, struct lu_fid *fid, struct md_op_data *op_data); - -int mdc_open(struct obd_export *exp, u64 ino, int type, int flags, - struct lov_mds_md *lmm, int lmm_size, struct lustre_handle *fh, - struct ptlrpc_request **); - struct obd_client_handle; int mdc_set_open_replay_data(struct obd_export *exp, -- GitLab From bbbc18ebdb23ed82424672f25b35aa84b3cdcad9 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Fri, 30 Oct 2015 20:59:05 +0530 Subject: [PATCH 0074/2855] Staging: lustre: fld: Remove unused seq_client_alloc_super Remove function seq_client_alloc_super since it is defined but not used. Also remove corresponding declaration from header file. Signed-off-by: Shraddha Barke Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/fid/fid_internal.h | 2 -- .../staging/lustre/lustre/fid/fid_request.c | 21 ------------------- 2 files changed, 23 deletions(-) diff --git a/drivers/staging/lustre/lustre/fid/fid_internal.h b/drivers/staging/lustre/lustre/fid/fid_internal.h index 84daee1154dc5..b79a813977cfd 100644 --- a/drivers/staging/lustre/lustre/fid/fid_internal.h +++ b/drivers/staging/lustre/lustre/fid/fid_internal.h @@ -44,8 +44,6 @@ #include "../../include/linux/libcfs/libcfs.h" /* Functions used internally in module. */ -int seq_client_alloc_super(struct lu_client_seq *seq, - const struct lu_env *env); extern struct lprocfs_vars seq_client_debugfs_list[]; diff --git a/drivers/staging/lustre/lustre/fid/fid_request.c b/drivers/staging/lustre/lustre/fid/fid_request.c index 7c45e74790873..e8176288452c6 100644 --- a/drivers/staging/lustre/lustre/fid/fid_request.c +++ b/drivers/staging/lustre/lustre/fid/fid_request.c @@ -142,27 +142,6 @@ out_req: return rc; } -/* Request sequence-controller node to allocate new super-sequence. */ -int seq_client_alloc_super(struct lu_client_seq *seq, - const struct lu_env *env) -{ - int rc; - - mutex_lock(&seq->lcs_mutex); - - /* Check whether the connection to seq controller has been - * setup (lcs_exp != NULL) */ - if (!seq->lcs_exp) { - mutex_unlock(&seq->lcs_mutex); - return -EINPROGRESS; - } - - rc = seq_client_rpc(seq, &seq->lcs_space, - SEQ_ALLOC_SUPER, "super"); - mutex_unlock(&seq->lcs_mutex); - return rc; -} - /* Request sequence-controller node to allocate new meta-sequence. */ static int seq_client_alloc_meta(const struct lu_env *env, struct lu_client_seq *seq) -- GitLab From 741fddbf504815e2e19d02c9a0a73757d8afc594 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Fri, 30 Oct 2015 20:59:06 +0530 Subject: [PATCH 0075/2855] Staging: lustre: fld: Declare local functions as static Declare fld_cache_entry_delete and fld_cache_insert_nolock as static since they are used only in this particular file. Also remove corresponding declarations from header file. Signed-off-by: Shraddha Barke Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/fld/fld_cache.c | 8 ++++---- drivers/staging/lustre/lustre/fld/fld_internal.h | 4 ---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/staging/lustre/lustre/fld/fld_cache.c b/drivers/staging/lustre/lustre/fld/fld_cache.c index 446917484637d..c4db390a73d50 100644 --- a/drivers/staging/lustre/lustre/fld/fld_cache.c +++ b/drivers/staging/lustre/lustre/fld/fld_cache.c @@ -121,8 +121,8 @@ void fld_cache_fini(struct fld_cache *cache) /** * delete given node from list. */ -void fld_cache_entry_delete(struct fld_cache *cache, - struct fld_cache_entry *node) +static void fld_cache_entry_delete(struct fld_cache *cache, + struct fld_cache_entry *node) { list_del(&node->fce_list); list_del(&node->fce_lru); @@ -377,8 +377,8 @@ struct fld_cache_entry * This function handles all cases of merging and breaking up of * ranges. */ -int fld_cache_insert_nolock(struct fld_cache *cache, - struct fld_cache_entry *f_new) +static int fld_cache_insert_nolock(struct fld_cache *cache, + struct fld_cache_entry *f_new) { struct fld_cache_entry *f_curr; struct fld_cache_entry *n; diff --git a/drivers/staging/lustre/lustre/fld/fld_internal.h b/drivers/staging/lustre/lustre/fld/fld_internal.h index fbb232de6c741..ab184a6852872 100644 --- a/drivers/staging/lustre/lustre/fld/fld_internal.h +++ b/drivers/staging/lustre/lustre/fld/fld_internal.h @@ -156,8 +156,6 @@ int fld_cache_insert(struct fld_cache *cache, struct fld_cache_entry *fld_cache_entry_create(const struct lu_seq_range *range); -int fld_cache_insert_nolock(struct fld_cache *cache, - struct fld_cache_entry *f_new); void fld_cache_delete(struct fld_cache *cache, const struct lu_seq_range *range); void fld_cache_delete_nolock(struct fld_cache *cache, @@ -167,8 +165,6 @@ int fld_cache_lookup(struct fld_cache *cache, struct fld_cache_entry* fld_cache_entry_lookup(struct fld_cache *cache, struct lu_seq_range *range); -void fld_cache_entry_delete(struct fld_cache *cache, - struct fld_cache_entry *node); void fld_dump_cache_entries(struct fld_cache *cache); struct fld_cache_entry -- GitLab From 649280ab5bcd1918774b6206f410d08c055341a6 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Fri, 30 Oct 2015 20:59:07 +0530 Subject: [PATCH 0076/2855] Staging: lustre: fld: Remove unused functions Remove functions fld_cache_delete and fld_cache_delete_nolock since they are defined but not used. Signed-off-by: Shraddha Barke Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/fld/fld_cache.c | 26 ------------------- .../staging/lustre/lustre/fld/fld_internal.h | 4 --- 2 files changed, 30 deletions(-) diff --git a/drivers/staging/lustre/lustre/fld/fld_cache.c b/drivers/staging/lustre/lustre/fld/fld_cache.c index c4db390a73d50..baa04074a61f6 100644 --- a/drivers/staging/lustre/lustre/fld/fld_cache.c +++ b/drivers/staging/lustre/lustre/fld/fld_cache.c @@ -444,36 +444,10 @@ int fld_cache_insert(struct fld_cache *cache, return rc; } -void fld_cache_delete_nolock(struct fld_cache *cache, - const struct lu_seq_range *range) -{ - struct fld_cache_entry *flde; - struct fld_cache_entry *tmp; - struct list_head *head; - - head = &cache->fci_entries_head; - list_for_each_entry_safe(flde, tmp, head, fce_list) { - /* add list if next is end of list */ - if (range->lsr_start == flde->fce_range.lsr_start || - (range->lsr_end == flde->fce_range.lsr_end && - range->lsr_flags == flde->fce_range.lsr_flags)) { - fld_cache_entry_delete(cache, flde); - break; - } - } -} - /** * Delete FLD entry in FLD cache. * */ -void fld_cache_delete(struct fld_cache *cache, - const struct lu_seq_range *range) -{ - write_lock(&cache->fci_lock); - fld_cache_delete_nolock(cache, range); - write_unlock(&cache->fci_lock); -} struct fld_cache_entry *fld_cache_entry_lookup_nolock(struct fld_cache *cache, diff --git a/drivers/staging/lustre/lustre/fld/fld_internal.h b/drivers/staging/lustre/lustre/fld/fld_internal.h index ab184a6852872..88ec7b114caa9 100644 --- a/drivers/staging/lustre/lustre/fld/fld_internal.h +++ b/drivers/staging/lustre/lustre/fld/fld_internal.h @@ -156,10 +156,6 @@ int fld_cache_insert(struct fld_cache *cache, struct fld_cache_entry *fld_cache_entry_create(const struct lu_seq_range *range); -void fld_cache_delete(struct fld_cache *cache, - const struct lu_seq_range *range); -void fld_cache_delete_nolock(struct fld_cache *cache, - const struct lu_seq_range *range); int fld_cache_lookup(struct fld_cache *cache, const u64 seq, struct lu_seq_range *range); -- GitLab From 66a9c9a8c2fa23476dc2701a69ad09cc3ecf2146 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Fri, 30 Oct 2015 20:59:08 +0530 Subject: [PATCH 0077/2855] Staging: lustre: fld: Remove unused declaration Function fld_dump_cache_entries is declared in header file but not used. Hence remove the declaration. Signed-off-by: Shraddha Barke Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/fld/fld_internal.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/fld/fld_internal.h b/drivers/staging/lustre/lustre/fld/fld_internal.h index 88ec7b114caa9..959b8e6bba951 100644 --- a/drivers/staging/lustre/lustre/fld/fld_internal.h +++ b/drivers/staging/lustre/lustre/fld/fld_internal.h @@ -161,7 +161,6 @@ int fld_cache_lookup(struct fld_cache *cache, struct fld_cache_entry* fld_cache_entry_lookup(struct fld_cache *cache, struct lu_seq_range *range); -void fld_dump_cache_entries(struct fld_cache *cache); struct fld_cache_entry *fld_cache_entry_lookup_nolock(struct fld_cache *cache, -- GitLab From 74d4ec114972d0ea0489db2d1fb772b9d5bd64ce Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Fri, 30 Oct 2015 20:59:09 +0530 Subject: [PATCH 0078/2855] Staging: lustre: osc: Declare local functions as static Declare osc_real_create, osc_create and osc_cleanup as static since they are used only in this particular file. Also remove the corresponding declarations from header file. Signed-off-by: Shraddha Barke Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/osc/osc_internal.h | 6 ------ drivers/staging/lustre/lustre/osc/osc_request.c | 13 +++++++------ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h b/drivers/staging/lustre/lustre/osc/osc_internal.h index 5ed30ecc84e34..db2ee9c23b42d 100644 --- a/drivers/staging/lustre/lustre/osc/osc_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_internal.h @@ -89,11 +89,6 @@ struct osc_cache_waiter { int ocw_rc; }; -int osc_create(const struct lu_env *env, struct obd_export *exp, - struct obdo *oa, struct lov_stripe_md **ea, - struct obd_trans_info *oti); -int osc_real_create(struct obd_export *exp, struct obdo *oa, - struct lov_stripe_md **ea, struct obd_trans_info *oti); void osc_wake_cache_waiters(struct client_obd *cli); int osc_shrink_grant_to_target(struct client_obd *cli, __u64 target_bytes); void osc_update_next_shrink(struct client_obd *cli); @@ -137,7 +132,6 @@ int osc_lru_shrink(struct client_obd *cli, int target); extern spinlock_t osc_ast_guard; -int osc_cleanup(struct obd_device *obd); int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg); int lproc_osc_attach_seqstat(struct obd_device *dev); diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index 18118fcf7d37b..cfb3ce2111f8b 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -104,7 +104,7 @@ struct osc_enqueue_args { static void osc_release_ppga(struct brw_page **ppga, u32 count); static int brw_interpret(const struct lu_env *env, struct ptlrpc_request *req, void *data, int rc); -int osc_cleanup(struct obd_device *obd); +static int osc_cleanup(struct obd_device *obd); /* Pack OSC object metadata for disk storage (LE byte order). */ static int osc_packmd(struct obd_export *exp, struct lov_mds_md **lmmp, @@ -431,8 +431,9 @@ static int osc_setattr_async(struct obd_export *exp, struct obd_info *oinfo, oinfo->oi_cb_up, oinfo, rqset); } -int osc_real_create(struct obd_export *exp, struct obdo *oa, - struct lov_stripe_md **ea, struct obd_trans_info *oti) +static int osc_real_create(struct obd_export *exp, struct obdo *oa, + struct lov_stripe_md **ea, + struct obd_trans_info *oti) { struct ptlrpc_request *req; struct ost_body *body; @@ -689,9 +690,9 @@ static int osc_can_send_destroy(struct client_obd *cli) return 0; } -int osc_create(const struct lu_env *env, struct obd_export *exp, - struct obdo *oa, struct lov_stripe_md **ea, - struct obd_trans_info *oti) +static int osc_create(const struct lu_env *env, struct obd_export *exp, + struct obdo *oa, struct lov_stripe_md **ea, + struct obd_trans_info *oti) { int rc = 0; -- GitLab From abcf8080eb444a432f9166acac940b19b45907b5 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Sat, 31 Oct 2015 15:58:41 +0530 Subject: [PATCH 0079/2855] Staging: lustre: lclient: Remove wrapper functions The functions cl_isize_lock and cl_isize_unlock can be replaced with direct calls to ll_inode_size_lock and ll_inode_size_unlock. Thus drop the wrapper functions. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/lclient/lcommon_cl.c | 4 ++-- drivers/staging/lustre/lustre/llite/llite_internal.h | 10 ---------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c index 0b8e4d2175ae5..12c7f0e669d40 100644 --- a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c @@ -427,7 +427,7 @@ static void ccc_object_size_lock(struct cl_object *obj) { struct inode *inode = ccc_object_inode(obj); - cl_isize_lock(inode); + ll_inode_size_lock(inode); cl_object_attr_lock(obj); } @@ -436,7 +436,7 @@ static void ccc_object_size_unlock(struct cl_object *obj) struct inode *inode = ccc_object_inode(obj); cl_object_attr_unlock(obj); - cl_isize_unlock(inode); + ll_inode_size_unlock(inode); } /***************************************************************************** diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 9096d311e45d7..157c32840e063 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -1285,16 +1285,6 @@ static inline struct ll_file_data *cl_iattr2fd(struct inode *inode, return LUSTRE_FPRIVATE(attr->ia_file); } -static inline void cl_isize_lock(struct inode *inode) -{ - ll_inode_size_lock(inode); -} - -static inline void cl_isize_unlock(struct inode *inode) -{ - ll_inode_size_unlock(inode); -} - static inline void cl_isize_write_nolock(struct inode *inode, loff_t kms) { LASSERT(mutex_is_locked(&ll_i2info(inode)->lli_size_mutex)); -- GitLab From 1251604b0eb7e58110c5d7fc025b01ecb19de9ef Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Sat, 31 Oct 2015 15:58:42 +0530 Subject: [PATCH 0080/2855] Staging: lustre: lmv: Remove unused function declaration The function lmv_blocking_ast is declared in header file but not used. Hence remove the declaration. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/lmv/lmv_internal.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/lmv/lmv_internal.h b/drivers/staging/lustre/lustre/lmv/lmv_internal.h index b808728daee7a..c8f40d9603180 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_internal.h +++ b/drivers/staging/lustre/lustre/lmv/lmv_internal.h @@ -68,8 +68,6 @@ int lmv_intent_open(struct obd_export *exp, struct md_op_data *op_data, ldlm_blocking_callback cb_blocking, __u64 extra_lock_flags); -int lmv_blocking_ast(struct ldlm_lock *, struct ldlm_lock_desc *, - void *, int); int lmv_fld_lookup(struct lmv_obd *lmv, const struct lu_fid *fid, u32 *mds); int __lmv_fid_alloc(struct lmv_obd *lmv, struct lu_fid *fid, u32 mds); int lmv_fid_alloc(struct obd_export *exp, struct lu_fid *fid, -- GitLab From c8b3c83e3b8c45083983c89d3ee08d3c5035c4cf Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Sat, 31 Oct 2015 15:58:43 +0530 Subject: [PATCH 0081/2855] Staging: lustre: lmv: Declare local functions as static Declare functions lmv_intent_open and lmv_intent_lookup as static since they are used only in this particular file. Also remove corresponding declarations from header file. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/lmv/lmv_intent.c | 21 ++++++++++--------- .../staging/lustre/lustre/lmv/lmv_internal.h | 12 ----------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/drivers/staging/lustre/lustre/lmv/lmv_intent.c b/drivers/staging/lustre/lustre/lmv/lmv_intent.c index eebe45bdceb62..3c585aea5bb83 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_intent.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_intent.c @@ -156,11 +156,11 @@ out: * IT_OPEN is intended to open (and create, possible) an object. Parent (pid) * may be split dir. */ -int lmv_intent_open(struct obd_export *exp, struct md_op_data *op_data, - void *lmm, int lmmsize, struct lookup_intent *it, - int flags, struct ptlrpc_request **reqp, - ldlm_blocking_callback cb_blocking, - __u64 extra_lock_flags) +static int lmv_intent_open(struct obd_export *exp, struct md_op_data *op_data, + void *lmm, int lmmsize, struct lookup_intent *it, + int flags, struct ptlrpc_request **reqp, + ldlm_blocking_callback cb_blocking, + __u64 extra_lock_flags) { struct obd_device *obd = exp->exp_obd; struct lmv_obd *lmv = &obd->u.lmv; @@ -239,11 +239,12 @@ int lmv_intent_open(struct obd_export *exp, struct md_op_data *op_data, /* * Handler for: getattr, lookup and revalidate cases. */ -int lmv_intent_lookup(struct obd_export *exp, struct md_op_data *op_data, - void *lmm, int lmmsize, struct lookup_intent *it, - int flags, struct ptlrpc_request **reqp, - ldlm_blocking_callback cb_blocking, - __u64 extra_lock_flags) +static int lmv_intent_lookup(struct obd_export *exp, + struct md_op_data *op_data, + void *lmm, int lmmsize, struct lookup_intent *it, + int flags, struct ptlrpc_request **reqp, + ldlm_blocking_callback cb_blocking, + __u64 extra_lock_flags) { struct obd_device *obd = exp->exp_obd; struct lmv_obd *lmv = &obd->u.lmv; diff --git a/drivers/staging/lustre/lustre/lmv/lmv_internal.h b/drivers/staging/lustre/lustre/lmv/lmv_internal.h index c8f40d9603180..467cfb3e7fca4 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_internal.h +++ b/drivers/staging/lustre/lustre/lmv/lmv_internal.h @@ -56,18 +56,6 @@ int lmv_intent_lock(struct obd_export *exp, struct md_op_data *op_data, ldlm_blocking_callback cb_blocking, __u64 extra_lock_flags); -int lmv_intent_lookup(struct obd_export *exp, struct md_op_data *op_data, - void *lmm, int lmmsize, struct lookup_intent *it, - int flags, struct ptlrpc_request **reqp, - ldlm_blocking_callback cb_blocking, - __u64 extra_lock_flags); - -int lmv_intent_open(struct obd_export *exp, struct md_op_data *op_data, - void *lmm, int lmmsize, struct lookup_intent *it, - int flags, struct ptlrpc_request **reqp, - ldlm_blocking_callback cb_blocking, - __u64 extra_lock_flags); - int lmv_fld_lookup(struct lmv_obd *lmv, const struct lu_fid *fid, u32 *mds); int __lmv_fid_alloc(struct lmv_obd *lmv, struct lu_fid *fid, u32 mds); int lmv_fid_alloc(struct obd_export *exp, struct lu_fid *fid, -- GitLab From 4b520fef890f0963e96496ec4291a98e8f4629a3 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Sat, 31 Oct 2015 15:58:44 +0530 Subject: [PATCH 0082/2855] Staging: lustre: lov: Remove unused function declarations These functions have been declared in header but not used anywhere. Thus drop the declarations. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/lov/lov_internal.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/staging/lustre/lustre/lov/lov_internal.h b/drivers/staging/lustre/lustre/lov/lov_internal.h index 515a5c1478274..87bc1dcb35156 100644 --- a/drivers/staging/lustre/lustre/lov/lov_internal.h +++ b/drivers/staging/lustre/lustre/lov/lov_internal.h @@ -151,14 +151,6 @@ int lov_stripe_number(struct lov_stripe_md *lsm, u64 lov_off); /* lov_qos.c */ #define LOV_USES_ASSIGNED_STRIPE 0 #define LOV_USES_DEFAULT_STRIPE 1 -int qos_add_tgt(struct obd_device *obd, __u32 index); -int qos_del_tgt(struct obd_device *obd, struct lov_tgt_desc *tgt); -void qos_shrink_lsm(struct lov_request_set *set); -int qos_prep_create(struct obd_export *exp, struct lov_request_set *set); -void qos_update(struct lov_obd *lov); -void qos_statfs_done(struct lov_obd *lov); -void qos_statfs_update(struct obd_device *obd, __u64 max_age, int wait); -int qos_remedy_create(struct lov_request_set *set, struct lov_request *req); /* lov_request.c */ void lov_set_add_req(struct lov_request *req, struct lov_request_set *set); -- GitLab From 2408e54dcab7f6faa0099a3cc0f67e2e823c2321 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Sat, 31 Oct 2015 15:58:45 +0530 Subject: [PATCH 0083/2855] Staging: lustre: lov: Declare local functions as static Declare functions lov_set_add_req, lov_set_finished, lov_update_set, lov_check_and_wait_active and lov_update_statfs as static since they are used only in this particular file. Also remove corresponding declarations from header file. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/lov/lov_internal.h | 7 ------- drivers/staging/lustre/lustre/lov/lov_request.c | 16 +++++++++------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/staging/lustre/lustre/lov/lov_internal.h b/drivers/staging/lustre/lustre/lov/lov_internal.h index 87bc1dcb35156..b8028735e5683 100644 --- a/drivers/staging/lustre/lustre/lov/lov_internal.h +++ b/drivers/staging/lustre/lustre/lov/lov_internal.h @@ -153,13 +153,8 @@ int lov_stripe_number(struct lov_stripe_md *lsm, u64 lov_off); #define LOV_USES_DEFAULT_STRIPE 1 /* lov_request.c */ -void lov_set_add_req(struct lov_request *req, struct lov_request_set *set); -int lov_set_finished(struct lov_request_set *set, int idempotent); -void lov_update_set(struct lov_request_set *set, - struct lov_request *req, int rc); int lov_update_common_set(struct lov_request_set *set, struct lov_request *req, int rc); -int lov_check_and_wait_active(struct lov_obd *lov, int ost_idx); int lov_prep_getattr_set(struct obd_export *exp, struct obd_info *oinfo, struct lov_request_set **reqset); int lov_fini_getattr_set(struct lov_request_set *set); @@ -176,8 +171,6 @@ int lov_update_setattr_set(struct lov_request_set *set, int lov_fini_setattr_set(struct lov_request_set *set); int lov_prep_statfs_set(struct obd_device *obd, struct obd_info *oinfo, struct lov_request_set **reqset); -void lov_update_statfs(struct obd_statfs *osfs, struct obd_statfs *lov_sfs, - int success); int lov_fini_statfs(struct obd_device *obd, struct obd_statfs *osfs, int success); int lov_fini_statfs_set(struct lov_request_set *set); diff --git a/drivers/staging/lustre/lustre/lov/lov_request.c b/drivers/staging/lustre/lustre/lov/lov_request.c index 1a150c26798de..bb1a03fef60d9 100644 --- a/drivers/staging/lustre/lustre/lov/lov_request.c +++ b/drivers/staging/lustre/lustre/lov/lov_request.c @@ -74,7 +74,7 @@ void lov_finish_set(struct lov_request_set *set) kfree(set); } -int lov_set_finished(struct lov_request_set *set, int idempotent) +static int lov_set_finished(struct lov_request_set *set, int idempotent) { int completes = atomic_read(&set->set_completes); @@ -89,8 +89,8 @@ int lov_set_finished(struct lov_request_set *set, int idempotent) return 0; } -void lov_update_set(struct lov_request_set *set, - struct lov_request *req, int rc) +static void lov_update_set(struct lov_request_set *set, + struct lov_request *req, int rc) { req->rq_complete = 1; req->rq_rc = rc; @@ -118,7 +118,8 @@ int lov_update_common_set(struct lov_request_set *set, return rc; } -void lov_set_add_req(struct lov_request *req, struct lov_request_set *set) +static void lov_set_add_req(struct lov_request *req, + struct lov_request_set *set) { list_add_tail(&req->rq_link, &set->set_list); set->set_count++; @@ -144,7 +145,7 @@ static int lov_check_set(struct lov_obd *lov, int idx) * If the OSC has not yet had a chance to connect to the OST the first time, * wait once for it to connect instead of returning an error. */ -int lov_check_and_wait_active(struct lov_obd *lov, int ost_idx) +static int lov_check_and_wait_active(struct lov_obd *lov, int ost_idx) { wait_queue_head_t waitq; struct l_wait_info lwi; @@ -591,8 +592,9 @@ int lov_fini_statfs_set(struct lov_request_set *set) return rc; } -void lov_update_statfs(struct obd_statfs *osfs, struct obd_statfs *lov_sfs, - int success) +static void lov_update_statfs(struct obd_statfs *osfs, + struct obd_statfs *lov_sfs, + int success) { int shift = 0, quit = 0; __u64 tmp; -- GitLab From ae0c6f01f3686a1a0dac6f27505f1365102bf5a3 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Sat, 31 Oct 2015 15:58:46 +0530 Subject: [PATCH 0084/2855] Staging: lustre: mdc: Remove unused declarations The functions mdc_pack_req and mdc_getxattr_pack have been declared in header file but not used. Thus remove the declarations. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/mdc_internal.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_internal.h b/drivers/staging/lustre/lustre/mdc/mdc_internal.h index a41e2b9396cdd..df50bdbcde19f 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_internal.h +++ b/drivers/staging/lustre/lustre/mdc/mdc_internal.h @@ -44,7 +44,6 @@ void lprocfs_mdc_init_vars(struct lprocfs_static_vars *lvars); void mdc_pack_body(struct ptlrpc_request *req, const struct lu_fid *fid, __u64 valid, int ea_size, __u32 suppgid, int flags); -int mdc_pack_req(struct ptlrpc_request *req, int version, int opc); void mdc_is_subdir_pack(struct ptlrpc_request *req, const struct lu_fid *pfid, const struct lu_fid *cfid, int flags); void mdc_swap_layouts_pack(struct ptlrpc_request *req, @@ -62,7 +61,6 @@ void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data, __u32 mode, __u64 rdev, __u64 flags, const void *data, int datalen); void mdc_unlink_pack(struct ptlrpc_request *req, struct md_op_data *op_data); -void mdc_getxattr_pack(struct ptlrpc_request *req, struct md_op_data *op_data); void mdc_link_pack(struct ptlrpc_request *req, struct md_op_data *op_data); void mdc_rename_pack(struct ptlrpc_request *req, struct md_op_data *op_data, const char *old, int oldlen, const char *new, int newlen); -- GitLab From 5d21c5a8835795ce8cbd87e5f08b266094a54863 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Sat, 31 Oct 2015 20:26:56 +0530 Subject: [PATCH 0085/2855] Staging: lustre: Drop wrapper functions Remove the functions node_equal() and node_compare() and replace their calls with appropriate functions. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/ldlm/interval_tree.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/staging/lustre/lustre/ldlm/interval_tree.c b/drivers/staging/lustre/lustre/ldlm/interval_tree.c index 39b571721881c..a2ea8e5b93d8d 100644 --- a/drivers/staging/lustre/lustre/ldlm/interval_tree.c +++ b/drivers/staging/lustre/lustre/ldlm/interval_tree.c @@ -96,18 +96,6 @@ static inline int extent_equal(struct interval_node_extent *e1, return (e1->start == e2->start) && (e1->end == e2->end); } -static inline int node_compare(struct interval_node *n1, - struct interval_node *n2) -{ - return extent_compare(&n1->in_extent, &n2->in_extent); -} - -static inline int node_equal(struct interval_node *n1, - struct interval_node *n2) -{ - return extent_equal(&n1->in_extent, &n2->in_extent); -} - static inline __u64 max_u64(__u64 x, __u64 y) { return x > y ? x : y; @@ -278,14 +266,14 @@ struct interval_node *interval_insert(struct interval_node *node, p = root; while (*p) { parent = *p; - if (node_equal(parent, node)) + if (extent_equal(&parent->in_extent, &node->in_extent)) return parent; /* max_high field must be updated after each iteration */ if (parent->in_max_high < interval_high(node)) parent->in_max_high = interval_high(node); - if (node_compare(node, parent) < 0) + if (extent_compare(&node->in_extent, &parent->in_extent) < 0) p = &parent->in_left; else p = &parent->in_right; -- GitLab From bf2ca1b1bc926016bf496b0f13eebd584c41d7a1 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 29 Oct 2015 17:35:17 -0400 Subject: [PATCH 0086/2855] staging: lustre: remove white space in libcfs_hash.h Cleanup all the unneeded white space in libcfs_hash.h. Signed-off-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/linux/libcfs/libcfs_hash.h | 135 +++++++++--------- 1 file changed, 70 insertions(+), 65 deletions(-) diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h index 70b8b29e831c9..4d73f8a2c6d17 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h @@ -66,12 +66,12 @@ #include /** disable debug */ -#define CFS_HASH_DEBUG_NONE 0 +#define CFS_HASH_DEBUG_NONE 0 /** record hash depth and output to console when it's too deep, * computing overhead is low but consume more memory */ -#define CFS_HASH_DEBUG_1 1 +#define CFS_HASH_DEBUG_1 1 /** expensive, check key validation */ -#define CFS_HASH_DEBUG_2 2 +#define CFS_HASH_DEBUG_2 2 #define CFS_HASH_DEBUG_LEVEL CFS_HASH_DEBUG_NONE @@ -108,16 +108,18 @@ struct cfs_hash_bucket { * cfs_hash bucket descriptor, it's normally in stack of caller */ struct cfs_hash_bd { - struct cfs_hash_bucket *bd_bucket; /**< address of bucket */ - unsigned int bd_offset; /**< offset in bucket */ + /* address of bucket */ + struct cfs_hash_bucket *bd_bucket; + /* offset in bucket */ + unsigned int bd_offset; }; -#define CFS_HASH_NAME_LEN 16 /**< default name length */ -#define CFS_HASH_BIGNAME_LEN 64 /**< bigname for param tree */ +#define CFS_HASH_NAME_LEN 16 /**< default name length */ +#define CFS_HASH_BIGNAME_LEN 64 /**< bigname for param tree */ -#define CFS_HASH_BKT_BITS 3 /**< default bits of bucket */ -#define CFS_HASH_BITS_MAX 30 /**< max bits of bucket */ -#define CFS_HASH_BITS_MIN CFS_HASH_BKT_BITS +#define CFS_HASH_BKT_BITS 3 /**< default bits of bucket */ +#define CFS_HASH_BITS_MAX 30 /**< max bits of bucket */ +#define CFS_HASH_BITS_MIN CFS_HASH_BKT_BITS /** * common hash attributes. @@ -133,41 +135,41 @@ enum cfs_hash_tag { */ CFS_HASH_NO_LOCK = 1 << 0, /** no bucket lock, use one spinlock to protect the whole hash */ - CFS_HASH_NO_BKTLOCK = 1 << 1, + CFS_HASH_NO_BKTLOCK = 1 << 1, /** rwlock to protect bucket */ - CFS_HASH_RW_BKTLOCK = 1 << 2, + CFS_HASH_RW_BKTLOCK = 1 << 2, /** spinlock to protect bucket */ - CFS_HASH_SPIN_BKTLOCK = 1 << 3, + CFS_HASH_SPIN_BKTLOCK = 1 << 3, /** always add new item to tail */ - CFS_HASH_ADD_TAIL = 1 << 4, + CFS_HASH_ADD_TAIL = 1 << 4, /** hash-table doesn't have refcount on item */ - CFS_HASH_NO_ITEMREF = 1 << 5, + CFS_HASH_NO_ITEMREF = 1 << 5, /** big name for param-tree */ CFS_HASH_BIGNAME = 1 << 6, /** track global count */ CFS_HASH_COUNTER = 1 << 7, /** rehash item by new key */ - CFS_HASH_REHASH_KEY = 1 << 8, + CFS_HASH_REHASH_KEY = 1 << 8, /** Enable dynamic hash resizing */ - CFS_HASH_REHASH = 1 << 9, + CFS_HASH_REHASH = 1 << 9, /** can shrink hash-size */ - CFS_HASH_SHRINK = 1 << 10, + CFS_HASH_SHRINK = 1 << 10, /** assert hash is empty on exit */ - CFS_HASH_ASSERT_EMPTY = 1 << 11, + CFS_HASH_ASSERT_EMPTY = 1 << 11, /** record hlist depth */ - CFS_HASH_DEPTH = 1 << 12, + CFS_HASH_DEPTH = 1 << 12, /** * rehash is always scheduled in a different thread, so current * change on hash table is non-blocking */ - CFS_HASH_NBLK_CHANGE = 1 << 13, + CFS_HASH_NBLK_CHANGE = 1 << 13, /** NB, we typed hs_flags as __u16, please change it * if you need to extend >=16 flags */ }; /** most used attributes */ -#define CFS_HASH_DEFAULT (CFS_HASH_RW_BKTLOCK | \ - CFS_HASH_COUNTER | CFS_HASH_REHASH) +#define CFS_HASH_DEFAULT (CFS_HASH_RW_BKTLOCK | \ + CFS_HASH_COUNTER | CFS_HASH_REHASH) /** * cfs_hash is a hash-table implementation for general purpose, it can support: @@ -211,7 +213,7 @@ enum cfs_hash_tag { struct cfs_hash { /** serialize with rehash, or serialize all operations if * the hash-table has CFS_HASH_NO_BKTLOCK */ - union cfs_hash_lock hs_lock; + union cfs_hash_lock hs_lock; /** hash operations */ struct cfs_hash_ops *hs_ops; /** hash lock operations */ @@ -219,57 +221,57 @@ struct cfs_hash { /** hash list operations */ struct cfs_hash_hlist_ops *hs_hops; /** hash buckets-table */ - struct cfs_hash_bucket **hs_buckets; + struct cfs_hash_bucket **hs_buckets; /** total number of items on this hash-table */ - atomic_t hs_count; + atomic_t hs_count; /** hash flags, see cfs_hash_tag for detail */ - __u16 hs_flags; + __u16 hs_flags; /** # of extra-bytes for bucket, for user saving extended attributes */ - __u16 hs_extra_bytes; + __u16 hs_extra_bytes; /** wants to iterate */ - __u8 hs_iterating; + __u8 hs_iterating; /** hash-table is dying */ - __u8 hs_exiting; + __u8 hs_exiting; /** current hash bits */ - __u8 hs_cur_bits; + __u8 hs_cur_bits; /** min hash bits */ - __u8 hs_min_bits; + __u8 hs_min_bits; /** max hash bits */ - __u8 hs_max_bits; + __u8 hs_max_bits; /** bits for rehash */ - __u8 hs_rehash_bits; + __u8 hs_rehash_bits; /** bits for each bucket */ - __u8 hs_bkt_bits; + __u8 hs_bkt_bits; /** resize min threshold */ - __u16 hs_min_theta; + __u16 hs_min_theta; /** resize max threshold */ - __u16 hs_max_theta; + __u16 hs_max_theta; /** resize count */ - __u32 hs_rehash_count; + __u32 hs_rehash_count; /** # of iterators (caller of cfs_hash_for_each_*) */ - __u32 hs_iterators; + __u32 hs_iterators; /** rehash workitem */ - cfs_workitem_t hs_rehash_wi; + cfs_workitem_t hs_rehash_wi; /** refcount on this hash table */ - atomic_t hs_refcount; + atomic_t hs_refcount; /** rehash buckets-table */ - struct cfs_hash_bucket **hs_rehash_buckets; + struct cfs_hash_bucket **hs_rehash_buckets; #if CFS_HASH_DEBUG_LEVEL >= CFS_HASH_DEBUG_1 /** serialize debug members */ spinlock_t hs_dep_lock; /** max depth */ - unsigned int hs_dep_max; + unsigned int hs_dep_max; /** id of the deepest bucket */ - unsigned int hs_dep_bkt; + unsigned int hs_dep_bkt; /** offset in the deepest bucket */ - unsigned int hs_dep_off; + unsigned int hs_dep_off; /** bits when we found the max depth */ - unsigned int hs_dep_bits; + unsigned int hs_dep_bits; /** workitem to output max depth */ - cfs_workitem_t hs_dep_wi; + cfs_workitem_t hs_dep_wi; #endif /** name of htable */ - char hs_name[0]; + char hs_name[0]; }; struct cfs_hash_lock_ops { @@ -324,11 +326,11 @@ struct cfs_hash_ops { }; /** total number of buckets in @hs */ -#define CFS_HASH_NBKT(hs) \ +#define CFS_HASH_NBKT(hs) \ (1U << ((hs)->hs_cur_bits - (hs)->hs_bkt_bits)) /** total number of buckets in @hs while rehashing */ -#define CFS_HASH_RH_NBKT(hs) \ +#define CFS_HASH_RH_NBKT(hs) \ (1U << ((hs)->hs_rehash_bits - (hs)->hs_bkt_bits)) /** number of hlist for in bucket */ @@ -433,19 +435,22 @@ cfs_hash_with_nblk_change(struct cfs_hash *hs) static inline int cfs_hash_is_exiting(struct cfs_hash *hs) -{ /* cfs_hash_destroy is called */ +{ + /* cfs_hash_destroy is called */ return hs->hs_exiting; } static inline int cfs_hash_is_rehashing(struct cfs_hash *hs) -{ /* rehash is launched */ +{ + /* rehash is launched */ return hs->hs_rehash_bits != 0; } static inline int cfs_hash_is_iterating(struct cfs_hash *hs) -{ /* someone is calling cfs_hash_for_each_* */ +{ + /* someone is calling cfs_hash_for_each_* */ return hs->hs_iterating || hs->hs_iterators != 0; } @@ -758,7 +763,7 @@ static inline void cfs_hash_bucket_validate(struct cfs_hash *hs, struct cfs_hash_bd *bd, struct hlist_node *hnode) { - struct cfs_hash_bd bds[2]; + struct cfs_hash_bd bds[2]; cfs_hash_dual_bd_get(hs, cfs_hash_key(hs, hnode), bds); LASSERT(bds[0].bd_bucket == bd->bd_bucket || @@ -777,9 +782,9 @@ cfs_hash_bucket_validate(struct cfs_hash *hs, struct cfs_hash_bd *bd, #endif /* CFS_HASH_DEBUG_LEVEL */ -#define CFS_HASH_THETA_BITS 10 -#define CFS_HASH_MIN_THETA (1U << (CFS_HASH_THETA_BITS - 1)) -#define CFS_HASH_MAX_THETA (1U << (CFS_HASH_THETA_BITS + 1)) +#define CFS_HASH_THETA_BITS 10 +#define CFS_HASH_MIN_THETA (1U << (CFS_HASH_THETA_BITS - 1)) +#define CFS_HASH_MAX_THETA (1U << (CFS_HASH_THETA_BITS + 1)) /* Return integer component of theta */ static inline int __cfs_hash_theta_int(int theta) @@ -848,20 +853,20 @@ cfs_hash_u64_hash(const __u64 key, unsigned mask) } /** iterate over all buckets in @bds (array of struct cfs_hash_bd) */ -#define cfs_hash_for_each_bd(bds, n, i) \ +#define cfs_hash_for_each_bd(bds, n, i) \ for (i = 0; i < n && (bds)[i].bd_bucket != NULL; i++) /** iterate over all buckets of @hs */ -#define cfs_hash_for_each_bucket(hs, bd, pos) \ - for (pos = 0; \ - pos < CFS_HASH_NBKT(hs) && \ +#define cfs_hash_for_each_bucket(hs, bd, pos) \ + for (pos = 0; \ + pos < CFS_HASH_NBKT(hs) && \ ((bd)->bd_bucket = (hs)->hs_buckets[pos]) != NULL; pos++) /** iterate over all hlist of bucket @bd */ -#define cfs_hash_bd_for_each_hlist(hs, bd, hlist) \ - for ((bd)->bd_offset = 0; \ - (bd)->bd_offset < CFS_HASH_BKT_NHLIST(hs) && \ - (hlist = cfs_hash_bd_hhead(hs, bd)) != NULL; \ +#define cfs_hash_bd_for_each_hlist(hs, bd, hlist) \ + for ((bd)->bd_offset = 0; \ + (bd)->bd_offset < CFS_HASH_BKT_NHLIST(hs) && \ + (hlist = cfs_hash_bd_hhead(hs, bd)) != NULL; \ (bd)->bd_offset++) /* !__LIBCFS__HASH_H__ */ -- GitLab From 9600d8f80b378e8eae0b55edf937b087d1e4c032 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 29 Oct 2015 17:35:18 -0400 Subject: [PATCH 0087/2855] staging: lustre: remove obsolete comment in libcfs_hash.h Remove comment hash_long which was removed long ago. Signed-off-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h index 4d73f8a2c6d17..4a78e6d8dc1fb 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h @@ -56,13 +56,6 @@ /* 2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */ #define CFS_GOLDEN_RATIO_PRIME_64 0x9e37fffffffc0001ULL -/* - * Ideally we would use HAVE_HASH_LONG for this, but on linux we configure - * the linux kernel and user space at the same time, so we need to differentiate - * between them explicitly. If this is not needed on other architectures, then - * we'll need to move the functions to architecture specific headers. - */ - #include /** disable debug */ -- GitLab From 12550e0cab229fd24241e4950c075361aad76b27 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 29 Oct 2015 17:35:19 -0400 Subject: [PATCH 0088/2855] staging: lustre: move linux hash.h header to start of libcfs_hash.h Minor style cleanup to put hash.h header to the top of the libcfs_hash.h file. Signed-off-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h index 4a78e6d8dc1fb..2e0c892280139 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h @@ -41,6 +41,9 @@ #ifndef __LIBCFS_HASH_H__ #define __LIBCFS_HASH_H__ + +#include + /* * Knuth recommends primes in approximately golden ratio to the maximum * integer representable by a machine word for multiplicative hashing. @@ -56,8 +59,6 @@ /* 2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */ #define CFS_GOLDEN_RATIO_PRIME_64 0x9e37fffffffc0001ULL -#include - /** disable debug */ #define CFS_HASH_DEBUG_NONE 0 /** record hash depth and output to console when it's too deep, -- GitLab From b2f005f7157eb77e6992206f5739effc0051a27a Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 29 Oct 2015 17:35:21 -0400 Subject: [PATCH 0089/2855] staging: lustre: remove white space in hash.c Cleanup all the unneeded white space in hash.c. Signed-off-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/hash.c | 342 ++++++++++---------- 1 file changed, 177 insertions(+), 165 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/hash.c b/drivers/staging/lustre/lustre/libcfs/hash.c index 0308744289521..ed4e1f1c43070 100644 --- a/drivers/staging/lustre/lustre/libcfs/hash.c +++ b/drivers/staging/lustre/lustre/libcfs/hash.c @@ -161,49 +161,49 @@ cfs_hash_rw_unlock(union cfs_hash_lock *lock, int exclusive) /** No lock hash */ static struct cfs_hash_lock_ops cfs_hash_nl_lops = { .hs_lock = cfs_hash_nl_lock, - .hs_unlock = cfs_hash_nl_unlock, - .hs_bkt_lock = cfs_hash_nl_lock, - .hs_bkt_unlock = cfs_hash_nl_unlock, + .hs_unlock = cfs_hash_nl_unlock, + .hs_bkt_lock = cfs_hash_nl_lock, + .hs_bkt_unlock = cfs_hash_nl_unlock, }; /** no bucket lock, one spinlock to protect everything */ static struct cfs_hash_lock_ops cfs_hash_nbl_lops = { .hs_lock = cfs_hash_spin_lock, - .hs_unlock = cfs_hash_spin_unlock, - .hs_bkt_lock = cfs_hash_nl_lock, - .hs_bkt_unlock = cfs_hash_nl_unlock, + .hs_unlock = cfs_hash_spin_unlock, + .hs_bkt_lock = cfs_hash_nl_lock, + .hs_bkt_unlock = cfs_hash_nl_unlock, }; /** spin bucket lock, rehash is enabled */ static struct cfs_hash_lock_ops cfs_hash_bkt_spin_lops = { .hs_lock = cfs_hash_rw_lock, - .hs_unlock = cfs_hash_rw_unlock, - .hs_bkt_lock = cfs_hash_spin_lock, - .hs_bkt_unlock = cfs_hash_spin_unlock, + .hs_unlock = cfs_hash_rw_unlock, + .hs_bkt_lock = cfs_hash_spin_lock, + .hs_bkt_unlock = cfs_hash_spin_unlock, }; /** rw bucket lock, rehash is enabled */ static struct cfs_hash_lock_ops cfs_hash_bkt_rw_lops = { .hs_lock = cfs_hash_rw_lock, - .hs_unlock = cfs_hash_rw_unlock, - .hs_bkt_lock = cfs_hash_rw_lock, - .hs_bkt_unlock = cfs_hash_rw_unlock, + .hs_unlock = cfs_hash_rw_unlock, + .hs_bkt_lock = cfs_hash_rw_lock, + .hs_bkt_unlock = cfs_hash_rw_unlock, }; /** spin bucket lock, rehash is disabled */ static struct cfs_hash_lock_ops cfs_hash_nr_bkt_spin_lops = { .hs_lock = cfs_hash_nl_lock, - .hs_unlock = cfs_hash_nl_unlock, - .hs_bkt_lock = cfs_hash_spin_lock, - .hs_bkt_unlock = cfs_hash_spin_unlock, + .hs_unlock = cfs_hash_nl_unlock, + .hs_bkt_lock = cfs_hash_spin_lock, + .hs_bkt_unlock = cfs_hash_spin_unlock, }; /** rw bucket lock, rehash is disabled */ static struct cfs_hash_lock_ops cfs_hash_nr_bkt_rw_lops = { .hs_lock = cfs_hash_nl_lock, - .hs_unlock = cfs_hash_nl_unlock, - .hs_bkt_lock = cfs_hash_rw_lock, - .hs_bkt_unlock = cfs_hash_rw_unlock, + .hs_unlock = cfs_hash_nl_unlock, + .hs_bkt_lock = cfs_hash_rw_lock, + .hs_bkt_unlock = cfs_hash_rw_unlock, }; static void @@ -280,7 +280,7 @@ cfs_hash_hh_hnode_del(struct cfs_hash *hs, struct cfs_hash_bd *bd, */ struct cfs_hash_head_dep { struct hlist_head hd_head; /**< entries list */ - unsigned int hd_depth; /**< list length */ + unsigned int hd_depth; /**< list length */ }; static int @@ -328,7 +328,7 @@ cfs_hash_hd_hnode_del(struct cfs_hash *hs, struct cfs_hash_bd *bd, */ struct cfs_hash_dhead { struct hlist_head dh_head; /**< entries list */ - struct hlist_node *dh_tail; /**< the last entry */ + struct hlist_node *dh_tail; /**< the last entry */ }; static int @@ -384,8 +384,8 @@ cfs_hash_dh_hnode_del(struct cfs_hash *hs, struct cfs_hash_bd *bd, */ struct cfs_hash_dhead_dep { struct hlist_head dd_head; /**< entries list */ - struct hlist_node *dd_tail; /**< the last entry */ - unsigned int dd_depth; /**< list length */ + struct hlist_node *dd_tail; /**< the last entry */ + unsigned int dd_depth; /**< list length */ }; static int @@ -436,31 +436,31 @@ cfs_hash_dd_hnode_del(struct cfs_hash *hs, struct cfs_hash_bd *bd, } static struct cfs_hash_hlist_ops cfs_hash_hh_hops = { - .hop_hhead = cfs_hash_hh_hhead, - .hop_hhead_size = cfs_hash_hh_hhead_size, - .hop_hnode_add = cfs_hash_hh_hnode_add, - .hop_hnode_del = cfs_hash_hh_hnode_del, + .hop_hhead = cfs_hash_hh_hhead, + .hop_hhead_size = cfs_hash_hh_hhead_size, + .hop_hnode_add = cfs_hash_hh_hnode_add, + .hop_hnode_del = cfs_hash_hh_hnode_del, }; static struct cfs_hash_hlist_ops cfs_hash_hd_hops = { - .hop_hhead = cfs_hash_hd_hhead, - .hop_hhead_size = cfs_hash_hd_hhead_size, - .hop_hnode_add = cfs_hash_hd_hnode_add, - .hop_hnode_del = cfs_hash_hd_hnode_del, + .hop_hhead = cfs_hash_hd_hhead, + .hop_hhead_size = cfs_hash_hd_hhead_size, + .hop_hnode_add = cfs_hash_hd_hnode_add, + .hop_hnode_del = cfs_hash_hd_hnode_del, }; static struct cfs_hash_hlist_ops cfs_hash_dh_hops = { - .hop_hhead = cfs_hash_dh_hhead, - .hop_hhead_size = cfs_hash_dh_hhead_size, - .hop_hnode_add = cfs_hash_dh_hnode_add, - .hop_hnode_del = cfs_hash_dh_hnode_del, + .hop_hhead = cfs_hash_dh_hhead, + .hop_hhead_size = cfs_hash_dh_hhead_size, + .hop_hnode_add = cfs_hash_dh_hnode_add, + .hop_hnode_del = cfs_hash_dh_hnode_del, }; static struct cfs_hash_hlist_ops cfs_hash_dd_hops = { - .hop_hhead = cfs_hash_dd_hhead, - .hop_hhead_size = cfs_hash_dd_hhead_size, - .hop_hnode_add = cfs_hash_dd_hnode_add, - .hop_hnode_del = cfs_hash_dd_hnode_del, + .hop_hhead = cfs_hash_dd_hhead, + .hop_hhead_size = cfs_hash_dd_hhead_size, + .hop_hnode_add = cfs_hash_dd_hnode_add, + .hop_hnode_del = cfs_hash_dd_hnode_del, }; static void @@ -529,7 +529,7 @@ void cfs_hash_bd_add_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd, struct hlist_node *hnode) { - int rc; + int rc; rc = hs->hs_hops->hop_hnode_add(hs, bd, hnode); cfs_hash_bd_dep_record(hs, bd, rc); @@ -572,7 +572,7 @@ cfs_hash_bd_move_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd_old, { struct cfs_hash_bucket *obkt = bd_old->bd_bucket; struct cfs_hash_bucket *nbkt = bd_new->bd_bucket; - int rc; + int rc; if (cfs_hash_bd_compare(bd_old, bd_new) == 0) return; @@ -597,30 +597,30 @@ EXPORT_SYMBOL(cfs_hash_bd_move_locked); enum { /** always set, for sanity (avoid ZERO intent) */ - CFS_HS_LOOKUP_MASK_FIND = BIT(0), + CFS_HS_LOOKUP_MASK_FIND = BIT(0), /** return entry with a ref */ - CFS_HS_LOOKUP_MASK_REF = BIT(1), + CFS_HS_LOOKUP_MASK_REF = BIT(1), /** add entry if not existing */ - CFS_HS_LOOKUP_MASK_ADD = BIT(2), + CFS_HS_LOOKUP_MASK_ADD = BIT(2), /** delete entry, ignore other masks */ - CFS_HS_LOOKUP_MASK_DEL = BIT(3), + CFS_HS_LOOKUP_MASK_DEL = BIT(3), }; enum cfs_hash_lookup_intent { /** return item w/o refcount */ - CFS_HS_LOOKUP_IT_PEEK = CFS_HS_LOOKUP_MASK_FIND, + CFS_HS_LOOKUP_IT_PEEK = CFS_HS_LOOKUP_MASK_FIND, /** return item with refcount */ - CFS_HS_LOOKUP_IT_FIND = (CFS_HS_LOOKUP_MASK_FIND | - CFS_HS_LOOKUP_MASK_REF), + CFS_HS_LOOKUP_IT_FIND = (CFS_HS_LOOKUP_MASK_FIND | + CFS_HS_LOOKUP_MASK_REF), /** return item w/o refcount if existed, otherwise add */ - CFS_HS_LOOKUP_IT_ADD = (CFS_HS_LOOKUP_MASK_FIND | - CFS_HS_LOOKUP_MASK_ADD), + CFS_HS_LOOKUP_IT_ADD = (CFS_HS_LOOKUP_MASK_FIND | + CFS_HS_LOOKUP_MASK_ADD), /** return item with refcount if existed, otherwise add */ - CFS_HS_LOOKUP_IT_FINDADD = (CFS_HS_LOOKUP_IT_FIND | - CFS_HS_LOOKUP_MASK_ADD), + CFS_HS_LOOKUP_IT_FINDADD = (CFS_HS_LOOKUP_IT_FIND | + CFS_HS_LOOKUP_MASK_ADD), /** delete if existed */ - CFS_HS_LOOKUP_IT_FINDDEL = (CFS_HS_LOOKUP_MASK_FIND | - CFS_HS_LOOKUP_MASK_DEL) + CFS_HS_LOOKUP_IT_FINDDEL = (CFS_HS_LOOKUP_MASK_FIND | + CFS_HS_LOOKUP_MASK_DEL) }; static struct hlist_node * @@ -629,10 +629,10 @@ cfs_hash_bd_lookup_intent(struct cfs_hash *hs, struct cfs_hash_bd *bd, enum cfs_hash_lookup_intent intent) { - struct hlist_head *hhead = cfs_hash_bd_hhead(hs, bd); - struct hlist_node *ehnode; - struct hlist_node *match; - int intent_add = (intent & CFS_HS_LOOKUP_MASK_ADD) != 0; + struct hlist_head *hhead = cfs_hash_bd_hhead(hs, bd); + struct hlist_node *ehnode; + struct hlist_node *match; + int intent_add = (intent & CFS_HS_LOOKUP_MASK_ADD) != 0; /* with this function, we can avoid a lot of useless refcount ops, * which are expensive atomic operations most time. */ @@ -665,7 +665,8 @@ cfs_hash_bd_lookup_intent(struct cfs_hash *hs, struct cfs_hash_bd *bd, } struct hlist_node * -cfs_hash_bd_lookup_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd, const void *key) +cfs_hash_bd_lookup_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd, + const void *key) { return cfs_hash_bd_lookup_intent(hs, bd, key, NULL, CFS_HS_LOOKUP_IT_FIND); @@ -673,7 +674,8 @@ cfs_hash_bd_lookup_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd, const voi EXPORT_SYMBOL(cfs_hash_bd_lookup_locked); struct hlist_node * -cfs_hash_bd_peek_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd, const void *key) +cfs_hash_bd_peek_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd, + const void *key) { return cfs_hash_bd_lookup_intent(hs, bd, key, NULL, CFS_HS_LOOKUP_IT_PEEK); @@ -706,7 +708,7 @@ cfs_hash_multi_bd_lock(struct cfs_hash *hs, struct cfs_hash_bd *bds, unsigned n, int excl) { struct cfs_hash_bucket *prev = NULL; - int i; + int i; /** * bds must be ascendantly ordered by bd->bd_bucket->hsb_index. @@ -729,7 +731,7 @@ cfs_hash_multi_bd_unlock(struct cfs_hash *hs, struct cfs_hash_bd *bds, unsigned n, int excl) { struct cfs_hash_bucket *prev = NULL; - int i; + int i; cfs_hash_for_each_bd(bds, n, i) { if (prev != bds[i].bd_bucket) { @@ -743,8 +745,8 @@ static struct hlist_node * cfs_hash_multi_bd_lookup_locked(struct cfs_hash *hs, struct cfs_hash_bd *bds, unsigned n, const void *key) { - struct hlist_node *ehnode; - unsigned i; + struct hlist_node *ehnode; + unsigned i; cfs_hash_for_each_bd(bds, n, i) { ehnode = cfs_hash_bd_lookup_intent(hs, &bds[i], key, NULL, @@ -756,13 +758,13 @@ cfs_hash_multi_bd_lookup_locked(struct cfs_hash *hs, struct cfs_hash_bd *bds, } static struct hlist_node * -cfs_hash_multi_bd_findadd_locked(struct cfs_hash *hs, - struct cfs_hash_bd *bds, unsigned n, const void *key, +cfs_hash_multi_bd_findadd_locked(struct cfs_hash *hs, struct cfs_hash_bd *bds, + unsigned n, const void *key, struct hlist_node *hnode, int noref) { - struct hlist_node *ehnode; - int intent; - unsigned i; + struct hlist_node *ehnode; + int intent; + unsigned i; LASSERT(hnode != NULL); intent = (!noref * CFS_HS_LOOKUP_MASK_REF) | CFS_HS_LOOKUP_IT_PEEK; @@ -777,7 +779,7 @@ cfs_hash_multi_bd_findadd_locked(struct cfs_hash *hs, if (i == 1) { /* only one bucket */ cfs_hash_bd_add_locked(hs, &bds[0], hnode); } else { - struct cfs_hash_bd mybd; + struct cfs_hash_bd mybd; cfs_hash_bd_get(hs, key, &mybd); cfs_hash_bd_add_locked(hs, &mybd, hnode); @@ -791,8 +793,8 @@ cfs_hash_multi_bd_finddel_locked(struct cfs_hash *hs, struct cfs_hash_bd *bds, unsigned n, const void *key, struct hlist_node *hnode) { - struct hlist_node *ehnode; - unsigned i; + struct hlist_node *ehnode; + unsigned int i; cfs_hash_for_each_bd(bds, n, i) { ehnode = cfs_hash_bd_lookup_intent(hs, &bds[i], key, hnode, @@ -806,7 +808,7 @@ cfs_hash_multi_bd_finddel_locked(struct cfs_hash *hs, struct cfs_hash_bd *bds, static void cfs_hash_bd_order(struct cfs_hash_bd *bd1, struct cfs_hash_bd *bd2) { - int rc; + int rc; if (bd2->bd_bucket == NULL) return; @@ -831,7 +833,8 @@ cfs_hash_bd_order(struct cfs_hash_bd *bd1, struct cfs_hash_bd *bd2) } void -cfs_hash_dual_bd_get(struct cfs_hash *hs, const void *key, struct cfs_hash_bd *bds) +cfs_hash_dual_bd_get(struct cfs_hash *hs, const void *key, + struct cfs_hash_bd *bds) { /* NB: caller should hold hs_lock.rw if REHASH is set */ cfs_hash_bd_from_key(hs, hs->hs_buckets, @@ -894,7 +897,7 @@ static void cfs_hash_buckets_free(struct cfs_hash_bucket **buckets, int bkt_size, int prev_size, int size) { - int i; + int i; for (i = prev_size; i < size; i++) { if (buckets[i] != NULL) @@ -914,7 +917,7 @@ cfs_hash_buckets_realloc(struct cfs_hash *hs, struct cfs_hash_bucket **old_bkts, unsigned int old_size, unsigned int new_size) { struct cfs_hash_bucket **new_bkts; - int i; + int i; LASSERT(old_size == 0 || old_bkts != NULL); @@ -932,7 +935,7 @@ cfs_hash_buckets_realloc(struct cfs_hash *hs, struct cfs_hash_bucket **old_bkts, for (i = old_size; i < new_size; i++) { struct hlist_head *hhead; - struct cfs_hash_bd bd; + struct cfs_hash_bd bd; LIBCFS_ALLOC(new_bkts[i], cfs_hash_bkt_size(hs)); if (new_bkts[i] == NULL) { @@ -969,7 +972,7 @@ cfs_hash_buckets_realloc(struct cfs_hash *hs, struct cfs_hash_bucket **old_bkts, * @max_bits - Maximum allowed hash table resize, in bits * @ops - Registered hash table operations * @flags - CFS_HASH_REHASH enable synamic hash resizing - * - CFS_HASH_SORT enable chained hash sort + * - CFS_HASH_SORT enable chained hash sort */ static int cfs_hash_rehash_worker(cfs_workitem_t *wi); @@ -977,10 +980,10 @@ static int cfs_hash_rehash_worker(cfs_workitem_t *wi); static int cfs_hash_dep_print(cfs_workitem_t *wi) { struct cfs_hash *hs = container_of(wi, struct cfs_hash, hs_dep_wi); - int dep; - int bkt; - int off; - int bits; + int dep; + int bkt; + int off; + int bits; spin_lock(&hs->hs_dep_lock); dep = hs->hs_dep_max; @@ -1031,7 +1034,7 @@ cfs_hash_create(char *name, unsigned cur_bits, unsigned max_bits, struct cfs_hash_ops *ops, unsigned flags) { struct cfs_hash *hs; - int len; + int len; CLASSERT(CFS_HASH_THETA_BITS < 15); @@ -1077,7 +1080,7 @@ cfs_hash_create(char *name, unsigned cur_bits, unsigned max_bits, hs->hs_max_bits = (__u8)max_bits; hs->hs_bkt_bits = (__u8)bkt_bits; - hs->hs_ops = ops; + hs->hs_ops = ops; hs->hs_extra_bytes = extra_bytes; hs->hs_rehash_bits = 0; cfs_wi_init(&hs->hs_rehash_wi, hs, cfs_hash_rehash_worker); @@ -1102,10 +1105,10 @@ EXPORT_SYMBOL(cfs_hash_create); static void cfs_hash_destroy(struct cfs_hash *hs) { - struct hlist_node *hnode; - struct hlist_node *pos; - struct cfs_hash_bd bd; - int i; + struct hlist_node *hnode; + struct hlist_node *pos; + struct cfs_hash_bd bd; + int i; LASSERT(hs != NULL); LASSERT(!cfs_hash_is_exiting(hs) && @@ -1223,8 +1226,8 @@ cfs_hash_rehash_inline(struct cfs_hash *hs) void cfs_hash_add(struct cfs_hash *hs, const void *key, struct hlist_node *hnode) { - struct cfs_hash_bd bd; - int bits; + struct cfs_hash_bd bd; + int bits; LASSERT(hlist_unhashed(hnode)); @@ -1248,8 +1251,8 @@ cfs_hash_find_or_add(struct cfs_hash *hs, const void *key, struct hlist_node *hnode, int noref) { struct hlist_node *ehnode; - struct cfs_hash_bd bds[2]; - int bits = 0; + struct cfs_hash_bd bds[2]; + int bits = 0; LASSERT(hlist_unhashed(hnode)); @@ -1261,7 +1264,7 @@ cfs_hash_find_or_add(struct cfs_hash *hs, const void *key, hnode, noref); cfs_hash_dual_bd_unlock(hs, bds, 1); - if (ehnode == hnode) /* new item added */ + if (ehnode == hnode) /* new item added */ bits = cfs_hash_rehash_bits(hs); cfs_hash_unlock(hs, 0); if (bits > 0) @@ -1276,7 +1279,8 @@ cfs_hash_find_or_add(struct cfs_hash *hs, const void *key, * Returns 0 on success or -EALREADY on key collisions. */ int -cfs_hash_add_unique(struct cfs_hash *hs, const void *key, struct hlist_node *hnode) +cfs_hash_add_unique(struct cfs_hash *hs, const void *key, + struct hlist_node *hnode) { return cfs_hash_find_or_add(hs, key, hnode, 1) != hnode ? -EALREADY : 0; @@ -1309,9 +1313,9 @@ EXPORT_SYMBOL(cfs_hash_findadd_unique); void * cfs_hash_del(struct cfs_hash *hs, const void *key, struct hlist_node *hnode) { - void *obj = NULL; - int bits = 0; - struct cfs_hash_bd bds[2]; + void *obj = NULL; + int bits = 0; + struct cfs_hash_bd bds[2]; cfs_hash_lock(hs, 0); cfs_hash_dual_bd_get_and_lock(hs, key, bds, 1); @@ -1364,9 +1368,9 @@ EXPORT_SYMBOL(cfs_hash_del_key); void * cfs_hash_lookup(struct cfs_hash *hs, const void *key) { - void *obj = NULL; - struct hlist_node *hnode; - struct cfs_hash_bd bds[2]; + void *obj = NULL; + struct hlist_node *hnode; + struct cfs_hash_bd bds[2]; cfs_hash_lock(hs, 0); cfs_hash_dual_bd_get_and_lock(hs, key, bds, 0); @@ -1383,7 +1387,8 @@ cfs_hash_lookup(struct cfs_hash *hs, const void *key) EXPORT_SYMBOL(cfs_hash_lookup); static void -cfs_hash_for_each_enter(struct cfs_hash *hs) { +cfs_hash_for_each_enter(struct cfs_hash *hs) +{ LASSERT(!cfs_hash_is_exiting(hs)); if (!cfs_hash_with_rehash(hs)) @@ -1408,7 +1413,8 @@ cfs_hash_for_each_enter(struct cfs_hash *hs) { } static void -cfs_hash_for_each_exit(struct cfs_hash *hs) { +cfs_hash_for_each_exit(struct cfs_hash *hs) +{ int remained; int bits; @@ -1439,14 +1445,15 @@ cfs_hash_for_each_exit(struct cfs_hash *hs) { */ static __u64 cfs_hash_for_each_tight(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, - void *data, int remove_safe) { - struct hlist_node *hnode; - struct hlist_node *pos; - struct cfs_hash_bd bd; - __u64 count = 0; - int excl = !!remove_safe; - int loop = 0; - int i; + void *data, int remove_safe) +{ + struct hlist_node *hnode; + struct hlist_node *pos; + struct cfs_hash_bd bd; + __u64 count = 0; + int excl = !!remove_safe; + int loop = 0; + int i; cfs_hash_for_each_enter(hs); @@ -1514,8 +1521,8 @@ void cfs_hash_cond_del(struct cfs_hash *hs, cfs_hash_cond_opt_cb_t func, void *data) { struct cfs_hash_cond_arg arg = { - .func = func, - .arg = data, + .func = func, + .arg = data, }; cfs_hash_for_each_tight(hs, cfs_hash_cond_del_locked, &arg, 1); @@ -1523,16 +1530,17 @@ cfs_hash_cond_del(struct cfs_hash *hs, cfs_hash_cond_opt_cb_t func, void *data) EXPORT_SYMBOL(cfs_hash_cond_del); void -cfs_hash_for_each(struct cfs_hash *hs, - cfs_hash_for_each_cb_t func, void *data) +cfs_hash_for_each(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, + void *data) { cfs_hash_for_each_tight(hs, func, data, 0); } EXPORT_SYMBOL(cfs_hash_for_each); void -cfs_hash_for_each_safe(struct cfs_hash *hs, - cfs_hash_for_each_cb_t func, void *data) { +cfs_hash_for_each_safe(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, + void *data) +{ cfs_hash_for_each_tight(hs, func, data, 1); } EXPORT_SYMBOL(cfs_hash_for_each_safe); @@ -1581,15 +1589,16 @@ EXPORT_SYMBOL(cfs_hash_size_get); */ static int cfs_hash_for_each_relax(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, - void *data) { + void *data) +{ struct hlist_node *hnode; struct hlist_node *tmp; - struct cfs_hash_bd bd; - __u32 version; - int count = 0; - int stop_on_change; - int rc; - int i; + struct cfs_hash_bd bd; + __u32 version; + int count = 0; + int stop_on_change; + int rc; + int i; stop_on_change = cfs_hash_with_rehash_key(hs) || !cfs_hash_with_no_itemref(hs) || @@ -1645,8 +1654,9 @@ cfs_hash_for_each_relax(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, } int -cfs_hash_for_each_nolock(struct cfs_hash *hs, - cfs_hash_for_each_cb_t func, void *data) { +cfs_hash_for_each_nolock(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, + void *data) +{ if (cfs_hash_with_no_lock(hs) || cfs_hash_with_rehash_key(hs) || !cfs_hash_with_no_itemref(hs)) @@ -1677,9 +1687,10 @@ EXPORT_SYMBOL(cfs_hash_for_each_nolock); * the required locking is in place to prevent concurrent insertions. */ int -cfs_hash_for_each_empty(struct cfs_hash *hs, - cfs_hash_for_each_cb_t func, void *data) { - unsigned i = 0; +cfs_hash_for_each_empty(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, + void *data) +{ + unsigned i = 0; if (cfs_hash_with_no_lock(hs)) return -EOPNOTSUPP; @@ -1703,9 +1714,9 @@ void cfs_hash_hlist_for_each(struct cfs_hash *hs, unsigned hindex, cfs_hash_for_each_cb_t func, void *data) { - struct hlist_head *hhead; - struct hlist_node *hnode; - struct cfs_hash_bd bd; + struct hlist_head *hhead; + struct hlist_node *hnode; + struct cfs_hash_bd bd; cfs_hash_for_each_enter(hs); cfs_hash_lock(hs, 0); @@ -1721,7 +1732,7 @@ cfs_hash_hlist_for_each(struct cfs_hash *hs, unsigned hindex, break; } cfs_hash_bd_unlock(hs, &bd, 0); - out: +out: cfs_hash_unlock(hs, 0); cfs_hash_for_each_exit(hs); } @@ -1736,10 +1747,11 @@ EXPORT_SYMBOL(cfs_hash_hlist_for_each); */ void cfs_hash_for_each_key(struct cfs_hash *hs, const void *key, - cfs_hash_for_each_cb_t func, void *data) { - struct hlist_node *hnode; - struct cfs_hash_bd bds[2]; - unsigned i; + cfs_hash_for_each_cb_t func, void *data) +{ + struct hlist_node *hnode; + struct cfs_hash_bd bds[2]; + unsigned int i; cfs_hash_lock(hs, 0); @@ -1777,7 +1789,7 @@ EXPORT_SYMBOL(cfs_hash_for_each_key); void cfs_hash_rehash_cancel_locked(struct cfs_hash *hs) { - int i; + int i; /* need hold cfs_hash_lock(hs, 1) */ LASSERT(cfs_hash_with_rehash(hs) && @@ -1815,7 +1827,7 @@ EXPORT_SYMBOL(cfs_hash_rehash_cancel); int cfs_hash_rehash(struct cfs_hash *hs, int do_rehash) { - int rc; + int rc; LASSERT(cfs_hash_with_rehash(hs) && !cfs_hash_with_no_lock(hs)); @@ -1845,12 +1857,12 @@ EXPORT_SYMBOL(cfs_hash_rehash); static int cfs_hash_rehash_bd(struct cfs_hash *hs, struct cfs_hash_bd *old) { - struct cfs_hash_bd new; - struct hlist_head *hhead; - struct hlist_node *hnode; - struct hlist_node *pos; - void *key; - int c = 0; + struct cfs_hash_bd new; + struct hlist_head *hhead; + struct hlist_node *hnode; + struct hlist_node *pos; + void *key; + int c = 0; /* hold cfs_hash_lock(hs, 1), so don't need any bucket lock */ cfs_hash_bd_for_each_hlist(hs, old, hhead) { @@ -1876,17 +1888,17 @@ cfs_hash_rehash_bd(struct cfs_hash *hs, struct cfs_hash_bd *old) static int cfs_hash_rehash_worker(cfs_workitem_t *wi) { - struct cfs_hash *hs = container_of(wi, struct cfs_hash, hs_rehash_wi); + struct cfs_hash *hs = container_of(wi, struct cfs_hash, hs_rehash_wi); struct cfs_hash_bucket **bkts; - struct cfs_hash_bd bd; - unsigned int old_size; - unsigned int new_size; - int bsize; - int count = 0; - int rc = 0; - int i; + struct cfs_hash_bd bd; + unsigned int old_size; + unsigned int new_size; + int bsize; + int count = 0; + int rc = 0; + int i; - LASSERT (hs != NULL && cfs_hash_with_rehash(hs)); + LASSERT(hs != NULL && cfs_hash_with_rehash(hs)); cfs_hash_lock(hs, 0); LASSERT(cfs_hash_is_rehashing(hs)); @@ -1958,7 +1970,7 @@ cfs_hash_rehash_worker(cfs_workitem_t *wi) hs->hs_rehash_buckets = NULL; hs->hs_cur_bits = hs->hs_rehash_bits; - out: +out: hs->hs_rehash_bits = 0; if (rc == -ESRCH) /* never be scheduled again */ cfs_wi_exit(cfs_sched_rehash, wi); @@ -1986,9 +1998,9 @@ cfs_hash_rehash_worker(cfs_workitem_t *wi) void cfs_hash_rehash_key(struct cfs_hash *hs, const void *old_key, void *new_key, struct hlist_node *hnode) { - struct cfs_hash_bd bds[3]; - struct cfs_hash_bd old_bds[2]; - struct cfs_hash_bd new_bd; + struct cfs_hash_bd bds[3]; + struct cfs_hash_bd old_bds[2]; + struct cfs_hash_bd new_bd; LASSERT(!hlist_unhashed(hnode)); @@ -2054,12 +2066,12 @@ cfs_hash_full_nbkt(struct cfs_hash *hs) void cfs_hash_debug_str(struct cfs_hash *hs, struct seq_file *m) { - int dist[8] = { 0, }; - int maxdep = -1; - int maxdepb = -1; - int total = 0; - int theta; - int i; + int dist[8] = { 0, }; + int maxdep = -1; + int maxdepb = -1; + int total = 0; + int theta; + int i; cfs_hash_lock(hs, 0); theta = __cfs_hash_theta(hs); @@ -2085,11 +2097,11 @@ void cfs_hash_debug_str(struct cfs_hash *hs, struct seq_file *m) * If you hash function results in a non-uniform hash the will * be observable by outlier bucks in the distribution histogram. * - * Uniform hash distribution: 128/128/0/0/0/0/0/0 - * Non-Uniform hash distribution: 128/125/0/0/0/0/2/1 + * Uniform hash distribution: 128/128/0/0/0/0/0/0 + * Non-Uniform hash distribution: 128/125/0/0/0/0/2/1 */ for (i = 0; i < cfs_hash_full_nbkt(hs); i++) { - struct cfs_hash_bd bd; + struct cfs_hash_bd bd; bd.bd_bucket = cfs_hash_full_bkts(hs)[i]; cfs_hash_bd_lock(hs, &bd, 0); -- GitLab From e72d97994bd7936bd24116b8fd4255e0ea2c1654 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 29 Oct 2015 17:35:22 -0400 Subject: [PATCH 0090/2855] staging: lustre: place linux header first in hash.c Always place linux headers first in libcfs header files. This avoid can potential build issues if any changes to a libcfs header land that starts using a linux header definition. Signed-off-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/libcfs/hash.c b/drivers/staging/lustre/lustre/libcfs/hash.c index ed4e1f1c43070..4cd8776ba84d6 100644 --- a/drivers/staging/lustre/lustre/libcfs/hash.c +++ b/drivers/staging/lustre/lustre/libcfs/hash.c @@ -106,9 +106,9 @@ * Now we support both locked iteration & lockless iteration of hash * table. Also, user can break the iteration by return 1 in callback. */ +#include #include "../../include/linux/libcfs/libcfs.h" -#include #if CFS_HASH_DEBUG_LEVEL >= CFS_HASH_DEBUG_1 static unsigned int warn_on_depth = 8; -- GitLab From 168c7a13d4d923e56f64e34db1562f20006e2a1d Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Sun, 1 Nov 2015 12:21:37 +0530 Subject: [PATCH 0091/2855] Staging: lustre: lnet: Remove typedef srpc_server_rpc_t The Linux kernel coding style guidelines suggest not using typedefs for structure types. This patch gets rid of the typedef for srpc_server_rpc_t. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/brw_test.c | 4 ++-- drivers/staging/lustre/lnet/selftest/console.c | 2 +- drivers/staging/lustre/lnet/selftest/framework.c | 8 ++++---- drivers/staging/lustre/lnet/selftest/rpc.c | 6 +++--- drivers/staging/lustre/lnet/selftest/selftest.h | 14 +++++++------- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c index 0605c651f7973..0f262267e01ed 100644 --- a/drivers/staging/lustre/lnet/selftest/brw_test.c +++ b/drivers/staging/lustre/lnet/selftest/brw_test.c @@ -358,7 +358,7 @@ out: } static void -brw_server_rpc_done(srpc_server_rpc_t *rpc) +brw_server_rpc_done(struct srpc_server_rpc *rpc) { srpc_bulk_t *blk = rpc->srpc_bulk; @@ -378,7 +378,7 @@ brw_server_rpc_done(srpc_server_rpc_t *rpc) } static int -brw_bulk_ready(srpc_server_rpc_t *rpc, int status) +brw_bulk_ready(struct srpc_server_rpc *rpc, int status) { __u64 magic = BRW_MAGIC; srpc_brw_reply_t *reply = &rpc->srpc_replymsg.msg_body.brw_reply; diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c index b1eceb4f48386..6862c9a15556e 100644 --- a/drivers/staging/lustre/lnet/selftest/console.c +++ b/drivers/staging/lustre/lnet/selftest/console.c @@ -1883,7 +1883,7 @@ lstcon_session_feats_check(unsigned feats) } static int -lstcon_acceptor_handle(srpc_server_rpc_t *rpc) +lstcon_acceptor_handle(struct srpc_server_rpc *rpc) { srpc_msg_t *rep = &rpc->srpc_replymsg; srpc_msg_t *req = &rpc->srpc_reqstbuf->buf_msg; diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c index f18e500368090..1a2da7430190a 100644 --- a/drivers/staging/lustre/lnet/selftest/framework.c +++ b/drivers/staging/lustre/lnet/selftest/framework.c @@ -111,7 +111,7 @@ static struct smoketest_framework { spinlock_t fw_lock; /* serialise */ sfw_session_t *fw_session; /* _the_ session */ int fw_shuttingdown; /* shutdown in progress */ - srpc_server_rpc_t *fw_active_srpc; /* running RPC */ + struct srpc_server_rpc *fw_active_srpc;/* running RPC */ } sfw_data; /* forward ref's */ @@ -722,7 +722,7 @@ sfw_unpack_addtest_req(srpc_msg_t *msg) } static int -sfw_add_test_instance(sfw_batch_t *tsb, srpc_server_rpc_t *rpc) +sfw_add_test_instance(sfw_batch_t *tsb, struct srpc_server_rpc *rpc) { srpc_msg_t *msg = &rpc->srpc_reqstbuf->buf_msg; srpc_test_reqst_t *req = &msg->msg_body.tes_reqst; @@ -1091,7 +1091,7 @@ sfw_query_batch(sfw_batch_t *tsb, int testidx, srpc_batch_reply_t *reply) } void -sfw_free_pages(srpc_server_rpc_t *rpc) +sfw_free_pages(struct srpc_server_rpc *rpc) { srpc_free_bulk(rpc->srpc_bulk); rpc->srpc_bulk = NULL; @@ -1112,7 +1112,7 @@ sfw_alloc_pages(struct srpc_server_rpc *rpc, int cpt, int npages, int len, } static int -sfw_add_test(srpc_server_rpc_t *rpc) +sfw_add_test(struct srpc_server_rpc *rpc) { sfw_session_t *sn = sfw_data.fw_session; srpc_test_reply_t *reply = &rpc->srpc_replymsg.msg_body.tes_reply; diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c index 0d1e7caf7cd66..86de68033f85b 100644 --- a/drivers/staging/lustre/lnet/selftest/rpc.c +++ b/drivers/staging/lustre/lnet/selftest/rpc.c @@ -859,7 +859,7 @@ srpc_prepare_bulk(srpc_client_rpc_t *rpc) } static int -srpc_do_bulk(srpc_server_rpc_t *rpc) +srpc_do_bulk(struct srpc_server_rpc *rpc) { srpc_event_t *ev = &rpc->srpc_ev; srpc_bulk_t *bk = rpc->srpc_bulk; @@ -887,7 +887,7 @@ srpc_do_bulk(srpc_server_rpc_t *rpc) /* only called from srpc_handle_rpc */ static void -srpc_server_rpc_done(srpc_server_rpc_t *rpc, int status) +srpc_server_rpc_done(struct srpc_server_rpc *rpc, int status) { struct srpc_service_cd *scd = rpc->srpc_scd; struct srpc_service *sv = scd->scd_svc; @@ -1397,7 +1397,7 @@ srpc_lnet_ev_handler(lnet_event_t *ev) struct srpc_service_cd *scd; srpc_event_t *rpcev = ev->md.user_ptr; srpc_client_rpc_t *crpc; - srpc_server_rpc_t *srpc; + struct srpc_server_rpc *srpc; srpc_buffer_t *buffer; srpc_service_t *sv; srpc_msg_t *msg; diff --git a/drivers/staging/lustre/lnet/selftest/selftest.h b/drivers/staging/lustre/lnet/selftest/selftest.h index 8a77d3fdfa545..0c0f177debc88 100644 --- a/drivers/staging/lustre/lnet/selftest/selftest.h +++ b/drivers/staging/lustre/lnet/selftest/selftest.h @@ -182,7 +182,7 @@ typedef struct swi_workitem { } swi_workitem_t; /* server-side state of a RPC */ -typedef struct srpc_server_rpc { +struct srpc_server_rpc { /* chain on srpc_service::*_rpcq */ struct list_head srpc_list; struct srpc_service_cd *srpc_scd; @@ -198,7 +198,7 @@ typedef struct srpc_server_rpc { unsigned int srpc_aborted; /* being given up */ int srpc_status; void (*srpc_done)(struct srpc_server_rpc *); -} srpc_server_rpc_t; +}; /* client-side state of a RPC */ typedef struct srpc_client_rpc { @@ -318,8 +318,8 @@ typedef struct srpc_service { * - sv_handler: process incoming RPC request * - sv_bulk_ready: notify bulk data */ - int (*sv_handler) (srpc_server_rpc_t *); - int (*sv_bulk_ready) (srpc_server_rpc_t *, int); + int (*sv_handler)(struct srpc_server_rpc *); + int (*sv_bulk_ready)(struct srpc_server_rpc *, int); } srpc_service_t; typedef struct { @@ -423,9 +423,9 @@ void sfw_abort_rpc(srpc_client_rpc_t *rpc); void sfw_post_rpc(srpc_client_rpc_t *rpc); void sfw_client_rpc_done(srpc_client_rpc_t *rpc); void sfw_unpack_message(srpc_msg_t *msg); -void sfw_free_pages(srpc_server_rpc_t *rpc); +void sfw_free_pages(struct srpc_server_rpc *rpc); void sfw_add_bulk_page(srpc_bulk_t *bk, struct page *pg, int i); -int sfw_alloc_pages(srpc_server_rpc_t *rpc, int cpt, int npages, int len, +int sfw_alloc_pages(struct srpc_server_rpc *rpc, int cpt, int npages, int len, int sink); int sfw_make_session (srpc_mksn_reqst_t *request, srpc_mksn_reply_t *reply); @@ -440,7 +440,7 @@ void srpc_free_bulk(srpc_bulk_t *bk); srpc_bulk_t *srpc_alloc_bulk(int cpt, unsigned bulk_npg, unsigned bulk_len, int sink); int srpc_send_rpc(swi_workitem_t *wi); -int srpc_send_reply(srpc_server_rpc_t *rpc); +int srpc_send_reply(struct srpc_server_rpc *rpc); int srpc_add_service(srpc_service_t *sv); int srpc_remove_service(srpc_service_t *sv); void srpc_shutdown_service(srpc_service_t *sv); -- GitLab From fb2358958785fa724a007671eb2bf848e8137354 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Sun, 1 Nov 2015 17:06:33 +0530 Subject: [PATCH 0092/2855] Staging: lustre: ptlrpc: Remove unused function declarations Functions ptlrpc_handle_failed_import and ptlrpc_lprocfs_do_request_stat have been declared but not used. Thus drop the declarations. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h index ab6c4580f91c3..833ed944125e1 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h @@ -73,7 +73,6 @@ void ptlrpc_request_handle_notconn(struct ptlrpc_request *); void lustre_assert_wire_constants(void); int ptlrpc_import_in_recovery(struct obd_import *imp); int ptlrpc_set_import_discon(struct obd_import *imp, __u32 conn_cnt); -void ptlrpc_handle_failed_import(struct obd_import *imp); int ptlrpc_replay_next(struct obd_import *imp, int *inflight); void ptlrpc_initiate_recovery(struct obd_import *imp); @@ -88,8 +87,6 @@ void ptlrpc_ldebugfs_register_service(struct dentry *debugfs_entry, struct ptlrpc_service *svc); void ptlrpc_lprocfs_unregister_service(struct ptlrpc_service *svc); void ptlrpc_lprocfs_rpc_sent(struct ptlrpc_request *req, long amount); -void ptlrpc_lprocfs_do_request_stat(struct ptlrpc_request *req, - long q_usec, long work_usec); /* NRS */ -- GitLab From 5e6f5901f076ec578f68cd100cca8f0d0175c532 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Sun, 1 Nov 2015 17:06:34 +0530 Subject: [PATCH 0093/2855] Staging: lustre: obdclass: Declare local function cl_lock_mutex_try as static Function cl_lock_mutex_try has been used only in this particular file. Thus declare the function as static. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/obdclass/cl_lock.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c index 5621bebf33a9d..1836dc01499a0 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c @@ -687,7 +687,7 @@ EXPORT_SYMBOL(cl_lock_mutex_get); * * \see cl_lock_mutex_get() */ -int cl_lock_mutex_try(const struct lu_env *env, struct cl_lock *lock) +static int cl_lock_mutex_try(const struct lu_env *env, struct cl_lock *lock) { int result; @@ -705,7 +705,6 @@ int cl_lock_mutex_try(const struct lu_env *env, struct cl_lock *lock) result = -EBUSY; return result; } -EXPORT_SYMBOL(cl_lock_mutex_try); /** {* Unlocks cl_lock object. -- GitLab From a2aadf23d1437ddcce86fa0673a6ecb5f932d3ec Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Sun, 1 Nov 2015 17:06:32 +0530 Subject: [PATCH 0094/2855] Staging: lustre: libcfs: Remove unused functions The functions cfs_hash_bd_findadd_locked and cfs_hash_bd_finddel_locked are not used anywhere. Thus remove these functions. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/linux/libcfs/libcfs_hash.h | 7 ------- drivers/staging/lustre/lustre/libcfs/hash.c | 21 ------------------- 2 files changed, 28 deletions(-) diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h index 2e0c892280139..f14db92346bae 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h @@ -640,13 +640,6 @@ cfs_hash_bd_lookup_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd, struct hlist_node * cfs_hash_bd_peek_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd, const void *key); -struct hlist_node * -cfs_hash_bd_findadd_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd, - const void *key, struct hlist_node *hnode, - int insist_add); -struct hlist_node * -cfs_hash_bd_finddel_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd, - const void *key, struct hlist_node *hnode); /** * operations on cfs_hash bucket (bd: bucket descriptor), diff --git a/drivers/staging/lustre/lustre/libcfs/hash.c b/drivers/staging/lustre/lustre/libcfs/hash.c index 4cd8776ba84d6..98c19b6cd1744 100644 --- a/drivers/staging/lustre/lustre/libcfs/hash.c +++ b/drivers/staging/lustre/lustre/libcfs/hash.c @@ -682,27 +682,6 @@ cfs_hash_bd_peek_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd, } EXPORT_SYMBOL(cfs_hash_bd_peek_locked); -struct hlist_node * -cfs_hash_bd_findadd_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd, - const void *key, struct hlist_node *hnode, - int noref) -{ - return cfs_hash_bd_lookup_intent(hs, bd, key, hnode, - (!noref * CFS_HS_LOOKUP_MASK_REF) | - CFS_HS_LOOKUP_IT_ADD); -} -EXPORT_SYMBOL(cfs_hash_bd_findadd_locked); - -struct hlist_node * -cfs_hash_bd_finddel_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd, - const void *key, struct hlist_node *hnode) -{ - /* hnode can be NULL, we find the first item with @key */ - return cfs_hash_bd_lookup_intent(hs, bd, key, hnode, - CFS_HS_LOOKUP_IT_FINDDEL); -} -EXPORT_SYMBOL(cfs_hash_bd_finddel_locked); - static void cfs_hash_multi_bd_lock(struct cfs_hash *hs, struct cfs_hash_bd *bds, unsigned n, int excl) -- GitLab From 90f8b4643023b23061a15229c0c0b8ee747438a8 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Mon, 2 Nov 2015 22:55:36 +0530 Subject: [PATCH 0095/2855] Staging: lustre: linux-crypto-adler: Drop wrapper function Remove the function __adler32() and replace its calls with the function it wrapped. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- .../lustre/lustre/libcfs/linux/linux-crypto-adler.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto-adler.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto-adler.c index 5d8d8b79fa1f3..db0572733712b 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto-adler.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto-adler.c @@ -37,11 +37,6 @@ #define CHKSUM_BLOCK_SIZE 1 #define CHKSUM_DIGEST_SIZE 4 -static u32 __adler32(u32 cksum, unsigned char const *p, size_t len) -{ - return zlib_adler32(cksum, p, len); -} - static int adler32_cra_init(struct crypto_tfm *tfm) { u32 *key = crypto_tfm_ctx(tfm); @@ -79,14 +74,14 @@ static int adler32_update(struct shash_desc *desc, const u8 *data, { u32 *cksump = shash_desc_ctx(desc); - *cksump = __adler32(*cksump, data, len); + *cksump = zlib_adler32(*cksump, data, len); return 0; } static int __adler32_finup(u32 *cksump, const u8 *data, unsigned int len, u8 *out) { - *(u32 *)out = __adler32(*cksump, data, len); + *(u32 *)out = zlib_adler32(*cksump, data, len); return 0; } -- GitLab From 7d6e398ca61427e903246f1c11853f6f967bbb5e Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Mon, 2 Nov 2015 23:19:13 +0530 Subject: [PATCH 0096/2855] Staging: lustre: linux-cpu: Remove wrapper function Remove the function cfs_cpu_core_siblings() and replace its calls with the function it wrapped. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c index 209736454d06e..bd7a9ef0be14a 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c @@ -78,12 +78,6 @@ struct cfs_cpt_data { static struct cfs_cpt_data cpt_data; -static void cfs_cpu_core_siblings(int cpu, cpumask_t *mask) -{ - /* return cpumask of cores in the same socket */ - cpumask_copy(mask, topology_core_cpumask(cpu)); -} - /* return cpumask of HTs in the same core */ static void cfs_cpu_ht_siblings(int cpu, cpumask_t *mask) { @@ -643,7 +637,7 @@ cfs_cpt_choose_ncpus(struct cfs_cpt_table *cptab, int cpt, cpu = cpumask_first(node); /* get cpumask for cores in the same socket */ - cfs_cpu_core_siblings(cpu, socket); + cpumask_copy(socket, topology_core_cpumask(cpu)); cpumask_and(socket, socket, node); LASSERT(!cpumask_empty(socket)); -- GitLab From 9561c25c590afdcb27002dc168bcecbf5a757308 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Mon, 2 Nov 2015 23:19:34 +0530 Subject: [PATCH 0097/2855] Staging: lustre: linux-cpu: Drop wrapper function Remove the function cfs_cpu_ht_siblings() and replace all its calls with the function it wrapped. Siigned-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/libcfs/linux/linux-cpu.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c index bd7a9ef0be14a..df6c049b795a5 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c @@ -78,12 +78,6 @@ struct cfs_cpt_data { static struct cfs_cpt_data cpt_data; -/* return cpumask of HTs in the same core */ -static void cfs_cpu_ht_siblings(int cpu, cpumask_t *mask) -{ - cpumask_copy(mask, topology_sibling_cpumask(cpu)); -} - static void cfs_node_to_cpumask(int node, cpumask_t *mask) { cpumask_copy(mask, cpumask_of_node(node)); @@ -646,7 +640,7 @@ cfs_cpt_choose_ncpus(struct cfs_cpt_table *cptab, int cpt, int i; /* get cpumask for hts in the same core */ - cfs_cpu_ht_siblings(cpu, core); + cpumask_copy(core, topology_sibling_cpumask(cpu)); cpumask_and(core, core, node); LASSERT(!cpumask_empty(core)); @@ -962,7 +956,8 @@ cfs_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) mutex_lock(&cpt_data.cpt_mutex); /* if all HTs in a core are offline, it may break affinity */ - cfs_cpu_ht_siblings(cpu, cpt_data.cpt_cpumask); + cpumask_copy(cpt_data.cpt_cpumask, + topology_sibling_cpumask(cpu)); warn = cpumask_any_and(cpt_data.cpt_cpumask, cpu_online_mask) >= nr_cpu_ids; mutex_unlock(&cpt_data.cpt_mutex); -- GitLab From 26da323423666560dd8ebf05c719f7cbd82e3f62 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Mon, 2 Nov 2015 23:19:55 +0530 Subject: [PATCH 0098/2855] Staging: lustre: linux-cpu: Remove unnecessary wrapper function Remove the function cfs_node_to_cpumask() and replace all its calls with the function it wrapped. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/libcfs/linux/linux-cpu.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c index df6c049b795a5..58a4034be1b85 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c @@ -78,11 +78,6 @@ struct cfs_cpt_data { static struct cfs_cpt_data cpt_data; -static void cfs_node_to_cpumask(int node, cpumask_t *mask) -{ - cpumask_copy(mask, cpumask_of_node(node)); -} - void cfs_cpt_table_free(struct cfs_cpt_table *cptab) { @@ -414,7 +409,7 @@ cfs_cpt_set_node(struct cfs_cpt_table *cptab, int cpt, int node) mutex_lock(&cpt_data.cpt_mutex); mask = cpt_data.cpt_cpumask; - cfs_node_to_cpumask(node, mask); + cpumask_copy(mask, cpumask_of_node(node)); rc = cfs_cpt_set_cpumask(cptab, cpt, mask); @@ -438,7 +433,7 @@ cfs_cpt_unset_node(struct cfs_cpt_table *cptab, int cpt, int node) mutex_lock(&cpt_data.cpt_mutex); mask = cpt_data.cpt_cpumask; - cfs_node_to_cpumask(node, mask); + cpumask_copy(mask, cpumask_of_node(node)); cfs_cpt_unset_cpumask(cptab, cpt, mask); @@ -757,7 +752,7 @@ cfs_cpt_table_create(int ncpt) } for_each_online_node(i) { - cfs_node_to_cpumask(i, mask); + cpumask_copy(mask, cpumask_of_node(i)); while (!cpumask_empty(mask)) { struct cfs_cpu_partition *part; -- GitLab From 87af1d2e0c29ce4f025da0cdbb9c74a3958fd71d Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Tue, 3 Nov 2015 00:29:22 +0530 Subject: [PATCH 0099/2855] Staging: lustre: tracefile: Replace function calls Replace the calls of function cfs_trace_put_console_buffer() with put_cpu() as former is just a wrapper for latter. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/tracefile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.c b/drivers/staging/lustre/lustre/libcfs/tracefile.c index f2d018d7823cd..f99d30f799e0c 100644 --- a/drivers/staging/lustre/lustre/libcfs/tracefile.c +++ b/drivers/staging/lustre/lustre/libcfs/tracefile.c @@ -451,7 +451,7 @@ console: cfs_print_to_console(&header, mask, string_buf, needed, file, msgdata->msg_fn); - cfs_trace_put_console_buffer(string_buf); + put_cpu(); } if (cdls != NULL && cdls->cdls_count != 0) { @@ -465,7 +465,7 @@ console: cfs_print_to_console(&header, mask, string_buf, needed, file, msgdata->msg_fn); - cfs_trace_put_console_buffer(string_buf); + put_cpu(); cdls->cdls_count = 0; } -- GitLab From 5a2f464af23bc90a77df6b9b30815e602efb99af Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Tue, 3 Nov 2015 00:29:43 +0530 Subject: [PATCH 0100/2855] Staging: lustre: tracefile: Remove wrapper function Remove the function cfs_trace_put_console_buffer() as it is no longer required. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/tracefile.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.h b/drivers/staging/lustre/lustre/libcfs/tracefile.h index cb7a3963589f4..73d60e0569226 100644 --- a/drivers/staging/lustre/lustre/libcfs/tracefile.h +++ b/drivers/staging/lustre/lustre/libcfs/tracefile.h @@ -279,12 +279,6 @@ cfs_trace_get_console_buffer(void) return cfs_trace_console_buffers[i][j]; } -static inline void -cfs_trace_put_console_buffer(char *buffer) -{ - put_cpu(); -} - static inline struct cfs_trace_cpu_data * cfs_trace_get_tcd(void) { -- GitLab From c14291d2c3041237c2e26939d26fb67bb689bcc2 Mon Sep 17 00:00:00 2001 From: Ksenija Stanojevic Date: Wed, 28 Oct 2015 18:59:55 -0700 Subject: [PATCH 0101/2855] Staging: rtl8192u: Remove unused function Function rtl8192_try_wake_queue is defined but not used, so remove it. Signed-off-by: Ksenija Stanojevic Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_core.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index e06864f64beb8..f4a4eae72aa42 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -5114,21 +5114,6 @@ static void __exit rtl8192_usb_module_exit(void) RT_TRACE(COMP_DOWN, "Exiting"); } - -void rtl8192_try_wake_queue(struct net_device *dev, int pri) -{ - unsigned long flags; - short enough_desc; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - - spin_lock_irqsave(&priv->tx_lock, flags); - enough_desc = check_nic_enough_desc(dev, pri); - spin_unlock_irqrestore(&priv->tx_lock, flags); - - if (enough_desc) - ieee80211_wake_queue(priv->ieee80211); -} - void EnableHWSecurityConfig8192(struct net_device *dev) { u8 SECR_value = 0x0; -- GitLab From d2071984b917784f74ab32c4f054e3503bc730e5 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Sat, 31 Oct 2015 20:25:29 +0530 Subject: [PATCH 0102/2855] staging: rtl8192u: Remove unnecessary function This patch solves two problems. The function rtl8192_CalculateBitShift() had an unnecessary variable i that could be removed by using a single line of code. After this change, rtl8192_CalculateBitShift() becomes a wrapper function, so the rtl8192_CalculateBitShift() function has been removed completely to replace it with a single line of code. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r819xU_phy.c | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/drivers/staging/rtl8192u/r819xU_phy.c b/drivers/staging/rtl8192u/r819xU_phy.c index 70656441c1455..f264d88364a11 100644 --- a/drivers/staging/rtl8192u/r819xU_phy.c +++ b/drivers/staging/rtl8192u/r819xU_phy.c @@ -37,21 +37,6 @@ static u32 RF_CHANNEL_TABLE_ZEBRA[] = { #define rtl819XRadioD_Array Rtl8192UsbRadioD_Array #define rtl819XAGCTAB_Array Rtl8192UsbAGCTAB_Array -/****************************************************************************** - * function: This function reads BB parameters from header file we generate, - * and does register read/write - * input: u32 bitmask //taget bit pos in the addr to be modified - * output: none - * return: u32 return the shift bit position of the mask - ******************************************************************************/ -static u32 rtl8192_CalculateBitShift(u32 bitmask) -{ - u32 i; - - i = ffs(bitmask) - 1; - return i; -} - /****************************************************************************** * function: This function checks different RF type to execute legal judgement. * If RF Path is illegal, we will return false. @@ -94,7 +79,7 @@ void rtl8192_setBBreg(struct net_device *dev, u32 reg_addr, u32 bitmask, if (bitmask != bMaskDWord) { read_nic_dword(dev, reg_addr, ®); - bitshift = rtl8192_CalculateBitShift(bitmask); + bitshift = ffs(bitmask) - 1; reg &= ~bitmask; reg |= data << bitshift; write_nic_dword(dev, reg_addr, reg); @@ -117,7 +102,7 @@ u32 rtl8192_QueryBBReg(struct net_device *dev, u32 reg_addr, u32 bitmask) u32 reg, bitshift; read_nic_dword(dev, reg_addr, ®); - bitshift = rtl8192_CalculateBitShift(bitmask); + bitshift = ffs(bitmask) - 1; return (reg & bitmask) >> bitshift; } @@ -306,7 +291,7 @@ void rtl8192_phy_SetRFReg(struct net_device *dev, RF90_RADIO_PATH_E eRFPath, if (bitmask != bMask12Bits) { /* RF data is 12 bits only */ reg = phy_FwRFSerialRead(dev, eRFPath, reg_addr); - bitshift = rtl8192_CalculateBitShift(bitmask); + bitshift = ffs(bitmask) - 1; reg &= ~bitmask; reg |= data << bitshift; @@ -321,7 +306,7 @@ void rtl8192_phy_SetRFReg(struct net_device *dev, RF90_RADIO_PATH_E eRFPath, if (bitmask != bMask12Bits) { /* RF data is 12 bits only */ reg = rtl8192_phy_RFSerialRead(dev, eRFPath, reg_addr); - bitshift = rtl8192_CalculateBitShift(bitmask); + bitshift = ffs(bitmask) - 1; reg &= ~bitmask; reg |= data << bitshift; @@ -356,7 +341,7 @@ u32 rtl8192_phy_QueryRFReg(struct net_device *dev, RF90_RADIO_PATH_E eRFPath, } else { reg = rtl8192_phy_RFSerialRead(dev, eRFPath, reg_addr); } - bitshift = rtl8192_CalculateBitShift(bitmask); + bitshift = ffs(bitmask) - 1; reg = (reg & bitmask) >> bitshift; return reg; -- GitLab From e1fec5395af3502efce18906a58dc6a8d1ff697e Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Fri, 30 Oct 2015 02:12:16 +0530 Subject: [PATCH 0103/2855] staging: gdm72xx: Remove wrapper function Remove wrapper function that can be replaced by a single line of code. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_wimax.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c index d9ddced96e194..b8eea21f26557 100644 --- a/drivers/staging/gdm72xx/gdm_wimax.c +++ b/drivers/staging/gdm72xx/gdm_wimax.c @@ -84,11 +84,6 @@ static inline struct evt_entry *alloc_event_entry(void) return kmalloc(sizeof(struct evt_entry), GFP_ATOMIC); } -static inline void free_event_entry(struct evt_entry *e) -{ - kfree(e); -} - static struct evt_entry *get_event_entry(void) { struct evt_entry *e; @@ -180,11 +175,11 @@ static void gdm_wimax_event_exit(void) list_for_each_entry_safe(e, temp, &wm_event.evtq, list) { list_del(&e->list); - free_event_entry(e); + kfree(e); } list_for_each_entry_safe(e, temp, &wm_event.freeq, list) { list_del(&e->list); - free_event_entry(e); + kfree(e); } spin_unlock_irqrestore(&wm_event.evt_lock, flags); -- GitLab From 24f49745df332421230dd613a218e1ce21b0502e Mon Sep 17 00:00:00 2001 From: Burcin Akalin Date: Sun, 1 Nov 2015 01:56:48 +0300 Subject: [PATCH 0104/2855] staging: gdm72xx: Add space around '&' Add space around operator '&'. Problem found using checkpatch.pl CHECK: spaces preferred around that '&' (ctx:VxV) Signed-off-by: Burcin Akalin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_qos.c | 40 +++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c index 81feffa5784ac..220fcd298e05e 100644 --- a/drivers/staging/gdm72xx/gdm_qos.c +++ b/drivers/staging/gdm72xx/gdm_qos.c @@ -143,18 +143,18 @@ static int chk_ipv4_rule(struct gdm_wimax_csr_s *csr, u8 *stream, u8 *port) { int i; - if (csr->classifier_rule_en&IPTYPEOFSERVICE) { + if (csr->classifier_rule_en & IPTYPEOFSERVICE) { if (((stream[1] & csr->ip2s_mask) < csr->ip2s_lo) || ((stream[1] & csr->ip2s_mask) > csr->ip2s_hi)) return 1; } - if (csr->classifier_rule_en&PROTOCOL) { + if (csr->classifier_rule_en & PROTOCOL) { if (stream[9] != csr->protocol) return 1; } - if (csr->classifier_rule_en&IPMASKEDSRCADDRESS) { + if (csr->classifier_rule_en & IPMASKEDSRCADDRESS) { for (i = 0; i < 4; i++) { if ((stream[12 + i] & csr->ipsrc_addrmask[i]) != (csr->ipsrc_addr[i] & csr->ipsrc_addrmask[i])) @@ -162,7 +162,7 @@ static int chk_ipv4_rule(struct gdm_wimax_csr_s *csr, u8 *stream, u8 *port) } } - if (csr->classifier_rule_en&IPMASKEDDSTADDRESS) { + if (csr->classifier_rule_en & IPMASKEDDSTADDRESS) { for (i = 0; i < 4; i++) { if ((stream[16 + i] & csr->ipdst_addrmask[i]) != (csr->ipdst_addr[i] & csr->ipdst_addrmask[i])) @@ -170,14 +170,14 @@ static int chk_ipv4_rule(struct gdm_wimax_csr_s *csr, u8 *stream, u8 *port) } } - if (csr->classifier_rule_en&PROTOCOLSRCPORTRANGE) { - i = ((port[0]<<8)&0xff00)+port[1]; + if (csr->classifier_rule_en & PROTOCOLSRCPORTRANGE) { + i = ((port[0]<<8) & 0xff00)+port[1]; if ((i < csr->srcport_lo) || (i > csr->srcport_hi)) return 1; } - if (csr->classifier_rule_en&PROTOCOLDSTPORTRANGE) { - i = ((port[2]<<8)&0xff00)+port[3]; + if (csr->classifier_rule_en & PROTOCOLDSTPORTRANGE) { + i = ((port[2]<<8) & 0xff00)+port[3]; if ((i < csr->dstport_lo) || (i > csr->dstport_hi)) return 1; } @@ -193,7 +193,7 @@ static int get_qos_index(struct nic *nic, u8 *iph, u8 *tcpudph) if (!iph || !tcpudph) return -1; - ip_ver = (iph[0]>>4)&0xf; + ip_ver = (iph[0]>>4) & 0xf; if (ip_ver != 4) return -1; @@ -342,9 +342,9 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) if (sub_cmd_evt == QOS_REPORT) { spin_lock_irqsave(&qcb->qos_lock, flags); for (i = 0; i < qcb->qos_list_cnt; i++) { - sfid = ((buf[(i*5)+6]<<24)&0xff000000); - sfid += ((buf[(i*5)+7]<<16)&0xff0000); - sfid += ((buf[(i*5)+8]<<8)&0xff00); + sfid = ((buf[(i*5)+6]<<24) & 0xff000000); + sfid += ((buf[(i*5)+7]<<16) & 0xff0000); + sfid += ((buf[(i*5)+8]<<8) & 0xff00); sfid += (buf[(i*5)+9]); index = get_csr(qcb, sfid, 0); if (index == -1) { @@ -363,9 +363,9 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) /* sub_cmd_evt == QOS_ADD || sub_cmd_evt == QOS_CHANG_DEL */ pos = 6; - sfid = ((buf[pos++]<<24)&0xff000000); - sfid += ((buf[pos++]<<16)&0xff0000); - sfid += ((buf[pos++]<<8)&0xff00); + sfid = ((buf[pos++]<<24) & 0xff000000); + sfid += ((buf[pos++]<<16) & 0xff0000); + sfid += ((buf[pos++]<<8) & 0xff00); sfid += (buf[pos++]); index = get_csr(qcb, sfid, 1); @@ -382,7 +382,7 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) spin_lock_irqsave(&qcb->qos_lock, flags); qcb->csr[index].sfid = sfid; - qcb->csr[index].classifier_rule_en = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].classifier_rule_en = ((buf[pos++]<<8) & 0xff00); qcb->csr[index].classifier_rule_en += buf[pos++]; if (qcb->csr[index].classifier_rule_en == 0) qcb->qos_null_idx = index; @@ -406,13 +406,13 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) qcb->csr[index].ipdst_addr[1] = buf[pos++]; qcb->csr[index].ipdst_addr[2] = buf[pos++]; qcb->csr[index].ipdst_addr[3] = buf[pos++]; - qcb->csr[index].srcport_lo = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].srcport_lo = ((buf[pos++]<<8) & 0xff00); qcb->csr[index].srcport_lo += buf[pos++]; - qcb->csr[index].srcport_hi = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].srcport_hi = ((buf[pos++]<<8) & 0xff00); qcb->csr[index].srcport_hi += buf[pos++]; - qcb->csr[index].dstport_lo = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].dstport_lo = ((buf[pos++]<<8) & 0xff00); qcb->csr[index].dstport_lo += buf[pos++]; - qcb->csr[index].dstport_hi = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].dstport_hi = ((buf[pos++]<<8) & 0xff00); qcb->csr[index].dstport_hi += buf[pos++]; qcb->qos_limit_size = 254/qcb->qos_list_cnt; -- GitLab From 053124a34d968417934406c2fb111ae5b397e376 Mon Sep 17 00:00:00 2001 From: Burcin Akalin Date: Sun, 1 Nov 2015 01:56:49 +0300 Subject: [PATCH 0105/2855] staging: gdm72xx: Add space around '-' Add space around operator '-'. Problem found using checkpatch.pl CHECK: spaces preferred around that '-' (ctx:VxV) Signed-off-by: Burcin Akalin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_qos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c index 220fcd298e05e..27f6054cbbf98 100644 --- a/drivers/staging/gdm72xx/gdm_qos.c +++ b/drivers/staging/gdm72xx/gdm_qos.c @@ -101,7 +101,7 @@ void gdm_qos_init(void *nic_ptr) } qcb->qos_list_cnt = 0; - qcb->qos_null_idx = QOS_MAX-1; + qcb->qos_null_idx = QOS_MAX - 1; qcb->qos_limit_size = 255; spin_lock_init(&qcb->qos_lock); @@ -128,7 +128,7 @@ void gdm_qos_release_list(void *nic_ptr) } qcb->qos_list_cnt = 0; - qcb->qos_null_idx = QOS_MAX-1; + qcb->qos_null_idx = QOS_MAX - 1; for (i = 0; i < QOS_MAX; i++) { list_for_each_entry_safe(entry, n, &qcb->qos_list[i], list) { -- GitLab From 20437125c4dc3851d1a4ed9d01827fa8abe97c95 Mon Sep 17 00:00:00 2001 From: Burcin Akalin Date: Sun, 1 Nov 2015 01:56:50 +0300 Subject: [PATCH 0106/2855] staging: gdm72xx: Add space around '+' Add space around operator '+'. Problem found using checkpatch.pl CHECK: spaces preferred around that '+' (ctx:VxV) Signed-off-by: Burcin Akalin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_qos.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c index 27f6054cbbf98..500476daf2b4b 100644 --- a/drivers/staging/gdm72xx/gdm_qos.c +++ b/drivers/staging/gdm72xx/gdm_qos.c @@ -171,13 +171,13 @@ static int chk_ipv4_rule(struct gdm_wimax_csr_s *csr, u8 *stream, u8 *port) } if (csr->classifier_rule_en & PROTOCOLSRCPORTRANGE) { - i = ((port[0]<<8) & 0xff00)+port[1]; + i = ((port[0]<<8) & 0xff00) + port[1]; if ((i < csr->srcport_lo) || (i > csr->srcport_hi)) return 1; } if (csr->classifier_rule_en & PROTOCOLDSTPORTRANGE) { - i = ((port[2]<<8) & 0xff00)+port[3]; + i = ((port[2]<<8) & 0xff00) + port[3]; if ((i < csr->dstport_lo) || (i > csr->dstport_hi)) return 1; } @@ -342,17 +342,17 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) if (sub_cmd_evt == QOS_REPORT) { spin_lock_irqsave(&qcb->qos_lock, flags); for (i = 0; i < qcb->qos_list_cnt; i++) { - sfid = ((buf[(i*5)+6]<<24) & 0xff000000); - sfid += ((buf[(i*5)+7]<<16) & 0xff0000); - sfid += ((buf[(i*5)+8]<<8) & 0xff00); - sfid += (buf[(i*5)+9]); + sfid = ((buf[(i*5) + 6]<<24) & 0xff000000); + sfid += ((buf[(i*5) + 7]<<16) & 0xff0000); + sfid += ((buf[(i*5) + 8]<<8) & 0xff00); + sfid += (buf[(i*5) + 9]); index = get_csr(qcb, sfid, 0); if (index == -1) { spin_unlock_irqrestore(&qcb->qos_lock, flags); netdev_err(nic->netdev, "QoS ERROR: No SF\n"); return; } - qcb->csr[index].qos_buf_count = buf[(i*5)+10]; + qcb->csr[index].qos_buf_count = buf[(i*5) + 10]; } extract_qos_list(nic, &send_list); -- GitLab From 565678ab1ba760ffd31bcd4e7ee9ea6511296ed4 Mon Sep 17 00:00:00 2001 From: Burcin Akalin Date: Sun, 1 Nov 2015 01:56:51 +0300 Subject: [PATCH 0107/2855] staging: gdm72xx: Add space around '/' Add space around operator '/'. Problem found using checkpatch.pl CHECK: spaces preferred around that '/' (ctx:VxV) Signed-off-by: Burcin Akalin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_qos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c index 500476daf2b4b..5db16ea05dbcc 100644 --- a/drivers/staging/gdm72xx/gdm_qos.c +++ b/drivers/staging/gdm72xx/gdm_qos.c @@ -415,7 +415,7 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) qcb->csr[index].dstport_hi = ((buf[pos++]<<8) & 0xff00); qcb->csr[index].dstport_hi += buf[pos++]; - qcb->qos_limit_size = 254/qcb->qos_list_cnt; + qcb->qos_limit_size = 254 / qcb->qos_list_cnt; spin_unlock_irqrestore(&qcb->qos_lock, flags); } else if (sub_cmd_evt == QOS_CHANGE_DEL) { netdev_dbg(nic->netdev, "QOS_CHANGE_DEL SFID = 0x%x, index=%d\n", @@ -426,7 +426,7 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) spin_lock_irqsave(&qcb->qos_lock, flags); qcb->csr[index].enabled = false; qcb->qos_list_cnt--; - qcb->qos_limit_size = 254/qcb->qos_list_cnt; + qcb->qos_limit_size = 254 / qcb->qos_list_cnt; list_for_each_entry_safe(entry, n, &qcb->qos_list[index], list) { -- GitLab From 3979b47c6e97e924dd3b826b573d38f93515c2bf Mon Sep 17 00:00:00 2001 From: Burcin Akalin Date: Sun, 1 Nov 2015 01:56:52 +0300 Subject: [PATCH 0108/2855] staging: gdm72xx: Add space around '>>' Add space around operator '>>'. Problem found using checkpatch.pl CHECK: spaces preferred around that '>>' (ctx:VxV) Signed-off-by: Burcin Akalin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_qos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c index 5db16ea05dbcc..ba5387fa66efa 100644 --- a/drivers/staging/gdm72xx/gdm_qos.c +++ b/drivers/staging/gdm72xx/gdm_qos.c @@ -193,7 +193,7 @@ static int get_qos_index(struct nic *nic, u8 *iph, u8 *tcpudph) if (!iph || !tcpudph) return -1; - ip_ver = (iph[0]>>4) & 0xf; + ip_ver = (iph[0] >> 4) & 0xf; if (ip_ver != 4) return -1; -- GitLab From d3fc05e22d6bba8b118512aabe6e888a30e76e3f Mon Sep 17 00:00:00 2001 From: Burcin Akalin Date: Sun, 1 Nov 2015 14:08:08 +0300 Subject: [PATCH 0109/2855] staging: gdm72xx:Add space around '<<' Add space around operator '<<'. Problem found using checkpatch.pl CHECK: spaces preferred around that '<<' (ctx:VxV) Signed-off-by: Burcin Akalin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_qos.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c index ba5387fa66efa..cad347a05d18a 100644 --- a/drivers/staging/gdm72xx/gdm_qos.c +++ b/drivers/staging/gdm72xx/gdm_qos.c @@ -171,13 +171,13 @@ static int chk_ipv4_rule(struct gdm_wimax_csr_s *csr, u8 *stream, u8 *port) } if (csr->classifier_rule_en & PROTOCOLSRCPORTRANGE) { - i = ((port[0]<<8) & 0xff00) + port[1]; + i = ((port[0] << 8) & 0xff00) + port[1]; if ((i < csr->srcport_lo) || (i > csr->srcport_hi)) return 1; } if (csr->classifier_rule_en & PROTOCOLDSTPORTRANGE) { - i = ((port[2]<<8) & 0xff00) + port[3]; + i = ((port[2] << 8) & 0xff00) + port[3]; if ((i < csr->dstport_lo) || (i > csr->dstport_hi)) return 1; } @@ -342,9 +342,9 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) if (sub_cmd_evt == QOS_REPORT) { spin_lock_irqsave(&qcb->qos_lock, flags); for (i = 0; i < qcb->qos_list_cnt; i++) { - sfid = ((buf[(i*5) + 6]<<24) & 0xff000000); - sfid += ((buf[(i*5) + 7]<<16) & 0xff0000); - sfid += ((buf[(i*5) + 8]<<8) & 0xff00); + sfid = ((buf[(i*5) + 6] << 24) & 0xff000000); + sfid += ((buf[(i*5) + 7] << 16) & 0xff0000); + sfid += ((buf[(i*5) + 8] << 8) & 0xff00); sfid += (buf[(i*5) + 9]); index = get_csr(qcb, sfid, 0); if (index == -1) { @@ -363,9 +363,9 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) /* sub_cmd_evt == QOS_ADD || sub_cmd_evt == QOS_CHANG_DEL */ pos = 6; - sfid = ((buf[pos++]<<24) & 0xff000000); - sfid += ((buf[pos++]<<16) & 0xff0000); - sfid += ((buf[pos++]<<8) & 0xff00); + sfid = ((buf[pos++] << 24) & 0xff000000); + sfid += ((buf[pos++] << 16) & 0xff0000); + sfid += ((buf[pos++] << 8) & 0xff00); sfid += (buf[pos++]); index = get_csr(qcb, sfid, 1); @@ -382,7 +382,7 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) spin_lock_irqsave(&qcb->qos_lock, flags); qcb->csr[index].sfid = sfid; - qcb->csr[index].classifier_rule_en = ((buf[pos++]<<8) & 0xff00); + qcb->csr[index].classifier_rule_en = ((buf[pos++] << 8) & 0xff00); qcb->csr[index].classifier_rule_en += buf[pos++]; if (qcb->csr[index].classifier_rule_en == 0) qcb->qos_null_idx = index; @@ -406,13 +406,13 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) qcb->csr[index].ipdst_addr[1] = buf[pos++]; qcb->csr[index].ipdst_addr[2] = buf[pos++]; qcb->csr[index].ipdst_addr[3] = buf[pos++]; - qcb->csr[index].srcport_lo = ((buf[pos++]<<8) & 0xff00); + qcb->csr[index].srcport_lo = ((buf[pos++] << 8) & 0xff00); qcb->csr[index].srcport_lo += buf[pos++]; - qcb->csr[index].srcport_hi = ((buf[pos++]<<8) & 0xff00); + qcb->csr[index].srcport_hi = ((buf[pos++] << 8) & 0xff00); qcb->csr[index].srcport_hi += buf[pos++]; - qcb->csr[index].dstport_lo = ((buf[pos++]<<8) & 0xff00); + qcb->csr[index].dstport_lo = ((buf[pos++] << 8) & 0xff00); qcb->csr[index].dstport_lo += buf[pos++]; - qcb->csr[index].dstport_hi = ((buf[pos++]<<8) & 0xff00); + qcb->csr[index].dstport_hi = ((buf[pos++] << 8) & 0xff00); qcb->csr[index].dstport_hi += buf[pos++]; qcb->qos_limit_size = 254 / qcb->qos_list_cnt; -- GitLab From f3a2d1adfdcceeb225d7676d31d07c9d6441eb8e Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Thu, 29 Oct 2015 11:47:03 +0530 Subject: [PATCH 0110/2855] staging: rtl8188eu: core: rtw_ap : Remove unnecessary functions Drop unnecessary functions that are declared but not being used. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_ap.c | 54 +------------------------ 1 file changed, 1 insertion(+), 53 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c index 3cdb40fea5ee7..e5d29fe9d4461 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ap.c +++ b/drivers/staging/rtl8188eu/core/rtw_ap.c @@ -1240,11 +1240,6 @@ int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr) return 0; } -static void update_bcn_fixed_ie(struct adapter *padapter) -{ - DBG_88E("%s\n", __func__); -} - static void update_bcn_erpinfo_ie(struct adapter *padapter) { struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); @@ -1279,31 +1274,6 @@ static void update_bcn_erpinfo_ie(struct adapter *padapter) } } -static void update_bcn_htcap_ie(struct adapter *padapter) -{ - DBG_88E("%s\n", __func__); -} - -static void update_bcn_htinfo_ie(struct adapter *padapter) -{ - DBG_88E("%s\n", __func__); -} - -static void update_bcn_rsn_ie(struct adapter *padapter) -{ - DBG_88E("%s\n", __func__); -} - -static void update_bcn_wpa_ie(struct adapter *padapter) -{ - DBG_88E("%s\n", __func__); -} - -static void update_bcn_wmm_ie(struct adapter *padapter) -{ - DBG_88E("%s\n", __func__); -} - static void update_bcn_wps_ie(struct adapter *padapter) { u8 *pwps_ie = NULL, *pwps_ie_src; @@ -1354,22 +1324,12 @@ static void update_bcn_wps_ie(struct adapter *padapter) kfree(pbackup_remainder_ie); } -static void update_bcn_p2p_ie(struct adapter *padapter) -{ -} - static void update_bcn_vendor_spec_ie(struct adapter *padapter, u8 *oui) { DBG_88E("%s\n", __func__); - if (!memcmp(RTW_WPA_OUI, oui, 4)) - update_bcn_wpa_ie(padapter); - else if (!memcmp(WMM_OUI, oui, 4)) - update_bcn_wmm_ie(padapter); - else if (!memcmp(WPS_OUI, oui, 4)) + if (!memcmp(WPS_OUI, oui, 4)) update_bcn_wps_ie(padapter); - else if (!memcmp(P2P_OUI, oui, 4)) - update_bcn_p2p_ie(padapter); else DBG_88E("unknown OUI type!\n"); } @@ -1391,24 +1351,12 @@ void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx) spin_lock_bh(&pmlmepriv->bcn_update_lock); switch (ie_id) { - case 0xFF: - update_bcn_fixed_ie(padapter);/* 8: TimeStamp, 2: Beacon Interval 2:Capability */ - break; case _TIM_IE_: update_BCNTIM(padapter); break; case _ERPINFO_IE_: update_bcn_erpinfo_ie(padapter); break; - case _HT_CAPABILITY_IE_: - update_bcn_htcap_ie(padapter); - break; - case _RSN_IE_2_: - update_bcn_rsn_ie(padapter); - break; - case _HT_ADD_INFO_IE_: - update_bcn_htinfo_ie(padapter); - break; case _VENDOR_SPECIFIC_IE_: update_bcn_vendor_spec_ie(padapter, oui); break; -- GitLab From ce3b84ab536a6f927506b998650ffb810b153705 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Thu, 29 Oct 2015 11:48:39 +0530 Subject: [PATCH 0111/2855] staging: rtl8188eu: Remove unused function Remove function that is declared but not called anywhere. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_xmit.c | 5 ----- drivers/staging/rtl8188eu/include/rtw_xmit.h | 1 - 2 files changed, 6 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_xmit.c b/drivers/staging/rtl8188eu/core/rtw_xmit.c index cabb810369bdf..11dbfc060b0d2 100644 --- a/drivers/staging/rtl8188eu/core/rtw_xmit.c +++ b/drivers/staging/rtl8188eu/core/rtw_xmit.c @@ -2186,11 +2186,6 @@ void rtw_sctx_done_err(struct submit_ctx **sctx, int status) } } -void rtw_sctx_done(struct submit_ctx **sctx) -{ - rtw_sctx_done_err(sctx, RTW_SCTX_DONE_SUCCESS); -} - int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms) { struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops; diff --git a/drivers/staging/rtl8188eu/include/rtw_xmit.h b/drivers/staging/rtl8188eu/include/rtw_xmit.h index 62f5db1695237..b7c20883d3551 100644 --- a/drivers/staging/rtl8188eu/include/rtw_xmit.h +++ b/drivers/staging/rtl8188eu/include/rtw_xmit.h @@ -197,7 +197,6 @@ enum { void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms); int rtw_sctx_wait(struct submit_ctx *sctx); void rtw_sctx_done_err(struct submit_ctx **sctx, int status); -void rtw_sctx_done(struct submit_ctx **sctx); struct xmit_buf { struct list_head list; -- GitLab From 03ea25f0c5f8929d27b2dcde26aa0b698fd12913 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Thu, 29 Oct 2015 11:52:35 +0530 Subject: [PATCH 0112/2855] staging: rtl8188eu: core: Remove wrapper function Remove wrapper function issue_probereq() that can be replaced by a single line of code and rename _issue_probereq() to issue_probereq(). This patch also fixes line over 80 characters checkpatch.pl warning. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_mlme_ext.c | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index d900546b672f0..687f0c2206cf6 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -609,7 +609,7 @@ static void issue_probersp(struct adapter *padapter, unsigned char *da) return; } -static int _issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, int wait_ack) +static int issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, int wait_ack) { int ret = _FAIL; struct xmit_frame *pmgntframe; @@ -702,12 +702,6 @@ exit: return ret; } -static inline void issue_probereq(struct adapter *padapter, - struct ndis_802_11_ssid *pssid, u8 *da) -{ - _issue_probereq(padapter, pssid, da, false); -} - static int issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, int try_cnt, int wait_ms) @@ -717,7 +711,7 @@ static int issue_probereq_ex(struct adapter *padapter, u32 start = jiffies; do { - ret = _issue_probereq(padapter, pssid, da, wait_ms > 0 ? true : false); + ret = issue_probereq(padapter, pssid, da, wait_ms > 0 ? true : false); i++; @@ -2029,24 +2023,28 @@ static void site_survey(struct adapter *padapter) for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) { /* todo: to issue two probe req??? */ - issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL); + issue_probereq(padapter, + &(pmlmeext->sitesurvey_res.ssid[i]), + NULL, false); /* msleep(SURVEY_TO>>1); */ - issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL); + issue_probereq(padapter, + &(pmlmeext->sitesurvey_res.ssid[i]), + NULL, false); } } if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) { /* todo: to issue two probe req??? */ - issue_probereq(padapter, NULL, NULL); + issue_probereq(padapter, NULL, NULL, false); /* msleep(SURVEY_TO>>1); */ - issue_probereq(padapter, NULL, NULL); + issue_probereq(padapter, NULL, NULL, false); } if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) { /* todo: to issue two probe req??? */ - issue_probereq(padapter, NULL, NULL); + issue_probereq(padapter, NULL, NULL, false); /* msleep(SURVEY_TO>>1); */ - issue_probereq(padapter, NULL, NULL); + issue_probereq(padapter, NULL, NULL, false); } } @@ -4820,9 +4818,18 @@ void linked_status_chk(struct adapter *padapter) } else { if (rx_chk != _SUCCESS) { if (pmlmeext->retry == 0) { - issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress); - issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress); - issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress); + issue_probereq(padapter, + &pmlmeinfo->network.Ssid, + pmlmeinfo->network.MacAddress, + false); + issue_probereq(padapter, + &pmlmeinfo->network.Ssid, + pmlmeinfo->network.MacAddress, + false); + issue_probereq(padapter, + &pmlmeinfo->network.Ssid, + pmlmeinfo->network.MacAddress, + false); } } -- GitLab From afcf9bc1bfe651a208e586ec68b35a1361af2fc9 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Thu, 29 Oct 2015 16:34:06 +0530 Subject: [PATCH 0113/2855] staging: rtl8188eu: core: Change function parameter to bool Change int wait_ack to bool wait_ack as it only takes true or false as its argument. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_mlme_ext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index 687f0c2206cf6..a9bff48868ef4 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -609,7 +609,7 @@ static void issue_probersp(struct adapter *padapter, unsigned char *da) return; } -static int issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, int wait_ack) +static int issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, bool wait_ack) { int ret = _FAIL; struct xmit_frame *pmgntframe; -- GitLab From bccb763d5fa25add4b374ac720052a01ba95cbca Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Thu, 29 Oct 2015 13:33:45 +0530 Subject: [PATCH 0114/2855] staging: rdma: amso1100: Remove unnecessary variable Drop unnecessary variable that can be replaced by single line of code. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/amso1100/c2_rnic.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/rdma/amso1100/c2_rnic.c b/drivers/staging/rdma/amso1100/c2_rnic.c index d3c0f77767d9a..5e65c6d07ca41 100644 --- a/drivers/staging/rdma/amso1100/c2_rnic.c +++ b/drivers/staging/rdma/amso1100/c2_rnic.c @@ -81,7 +81,6 @@ static int c2_adapter_init(struct c2_dev *c2dev) { struct c2wr_init_req wr; - int err; memset(&wr, 0, sizeof(wr)); c2_wr_set_id(&wr, CCWR_INIT); @@ -94,9 +93,7 @@ static int c2_adapter_init(struct c2_dev *c2dev) wr.q2_host_msg_pool = cpu_to_be64(c2dev->aeq.host_dma); /* Post the init message */ - err = vq_send_wr(c2dev, (union c2wr *) & wr); - - return err; + return vq_send_wr(c2dev, (union c2wr *) & wr); } /* -- GitLab From 463f8e7223ce10d12829e6d11204b1ef131d350d Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Thu, 29 Oct 2015 13:35:06 +0530 Subject: [PATCH 0115/2855] staging: rdma: hfi1: Remove unnecessary variable Drop unnecessary variable that can be replaced by a single line of code. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/qsfp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rdma/hfi1/qsfp.c b/drivers/staging/rdma/hfi1/qsfp.c index ffdb1d787a80b..6326a915d7fd3 100644 --- a/drivers/staging/rdma/hfi1/qsfp.c +++ b/drivers/staging/rdma/hfi1/qsfp.c @@ -475,7 +475,7 @@ int qsfp_dump(struct hfi1_pportdata *ppd, char *buf, int len) u8 *cache = &ppd->qsfp_info.cache[0]; u8 bin_buff[QSFP_DUMP_CHUNK]; char lenstr[6]; - int sofar, ret; + int sofar; int bidx = 0; u8 *atten = &cache[QSFP_ATTEN_OFFS]; u8 *vendor_oui = &cache[QSFP_VOUI_OFFS]; @@ -536,6 +536,5 @@ int qsfp_dump(struct hfi1_pportdata *ppd, char *buf, int len) bidx += QSFP_DUMP_CHUNK; } } - ret = sofar; - return ret; + return sofar; } -- GitLab From 99d19626b3b3c6e4f6c134359e7c690320776fd9 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Sun, 1 Nov 2015 01:45:13 +0530 Subject: [PATCH 0116/2855] staging: rdma: amso1100: Remove extern from function declarations Functions have the extern specifier by default, so this keyword can be removed. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/amso1100/c2.h | 80 +++++++++++++-------------- drivers/staging/rdma/amso1100/c2_mq.h | 14 ++--- drivers/staging/rdma/amso1100/c2_vq.h | 20 +++---- 3 files changed, 57 insertions(+), 57 deletions(-) diff --git a/drivers/staging/rdma/amso1100/c2.h b/drivers/staging/rdma/amso1100/c2.h index d619d735838bd..21b565a91fd62 100644 --- a/drivers/staging/rdma/amso1100/c2.h +++ b/drivers/staging/rdma/amso1100/c2.h @@ -476,72 +476,72 @@ static inline int c2_errno(void *reply) } /* Device */ -extern int c2_register_device(struct c2_dev *c2dev); -extern void c2_unregister_device(struct c2_dev *c2dev); -extern int c2_rnic_init(struct c2_dev *c2dev); -extern void c2_rnic_term(struct c2_dev *c2dev); -extern void c2_rnic_interrupt(struct c2_dev *c2dev); -extern int c2_del_addr(struct c2_dev *c2dev, __be32 inaddr, __be32 inmask); -extern int c2_add_addr(struct c2_dev *c2dev, __be32 inaddr, __be32 inmask); +int c2_register_device(struct c2_dev *c2dev); +void c2_unregister_device(struct c2_dev *c2dev); +int c2_rnic_init(struct c2_dev *c2dev); +void c2_rnic_term(struct c2_dev *c2dev); +void c2_rnic_interrupt(struct c2_dev *c2dev); +int c2_del_addr(struct c2_dev *c2dev, __be32 inaddr, __be32 inmask); +int c2_add_addr(struct c2_dev *c2dev, __be32 inaddr, __be32 inmask); /* QPs */ -extern int c2_alloc_qp(struct c2_dev *c2dev, struct c2_pd *pd, +int c2_alloc_qp(struct c2_dev *c2dev, struct c2_pd *pd, struct ib_qp_init_attr *qp_attrs, struct c2_qp *qp); -extern void c2_free_qp(struct c2_dev *c2dev, struct c2_qp *qp); -extern struct ib_qp *c2_get_qp(struct ib_device *device, int qpn); -extern int c2_qp_modify(struct c2_dev *c2dev, struct c2_qp *qp, +void c2_free_qp(struct c2_dev *c2dev, struct c2_qp *qp); +struct ib_qp *c2_get_qp(struct ib_device *device, int qpn); +int c2_qp_modify(struct c2_dev *c2dev, struct c2_qp *qp, struct ib_qp_attr *attr, int attr_mask); -extern int c2_qp_set_read_limits(struct c2_dev *c2dev, struct c2_qp *qp, +int c2_qp_set_read_limits(struct c2_dev *c2dev, struct c2_qp *qp, int ord, int ird); -extern int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, +int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, struct ib_send_wr **bad_wr); -extern int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, +int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, struct ib_recv_wr **bad_wr); -extern void c2_init_qp_table(struct c2_dev *c2dev); -extern void c2_cleanup_qp_table(struct c2_dev *c2dev); -extern void c2_set_qp_state(struct c2_qp *, int); -extern struct c2_qp *c2_find_qpn(struct c2_dev *c2dev, int qpn); +void c2_init_qp_table(struct c2_dev *c2dev); +void c2_cleanup_qp_table(struct c2_dev *c2dev); +void c2_set_qp_state(struct c2_qp *, int); +struct c2_qp *c2_find_qpn(struct c2_dev *c2dev, int qpn); /* PDs */ -extern int c2_pd_alloc(struct c2_dev *c2dev, int privileged, struct c2_pd *pd); -extern void c2_pd_free(struct c2_dev *c2dev, struct c2_pd *pd); -extern int c2_init_pd_table(struct c2_dev *c2dev); -extern void c2_cleanup_pd_table(struct c2_dev *c2dev); +int c2_pd_alloc(struct c2_dev *c2dev, int privileged, struct c2_pd *pd); +void c2_pd_free(struct c2_dev *c2dev, struct c2_pd *pd); +int c2_init_pd_table(struct c2_dev *c2dev); +void c2_cleanup_pd_table(struct c2_dev *c2dev); /* CQs */ -extern int c2_init_cq(struct c2_dev *c2dev, int entries, +int c2_init_cq(struct c2_dev *c2dev, int entries, struct c2_ucontext *ctx, struct c2_cq *cq); -extern void c2_free_cq(struct c2_dev *c2dev, struct c2_cq *cq); -extern void c2_cq_event(struct c2_dev *c2dev, u32 mq_index); -extern void c2_cq_clean(struct c2_dev *c2dev, struct c2_qp *qp, u32 mq_index); -extern int c2_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry); -extern int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags); +void c2_free_cq(struct c2_dev *c2dev, struct c2_cq *cq); +void c2_cq_event(struct c2_dev *c2dev, u32 mq_index); +void c2_cq_clean(struct c2_dev *c2dev, struct c2_qp *qp, u32 mq_index); +int c2_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry); +int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags); /* CM */ -extern int c2_llp_connect(struct iw_cm_id *cm_id, +int c2_llp_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param); -extern int c2_llp_accept(struct iw_cm_id *cm_id, +int c2_llp_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param); -extern int c2_llp_reject(struct iw_cm_id *cm_id, const void *pdata, +int c2_llp_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len); -extern int c2_llp_service_create(struct iw_cm_id *cm_id, int backlog); -extern int c2_llp_service_destroy(struct iw_cm_id *cm_id); +int c2_llp_service_create(struct iw_cm_id *cm_id, int backlog); +int c2_llp_service_destroy(struct iw_cm_id *cm_id); /* MM */ -extern int c2_nsmr_register_phys_kern(struct c2_dev *c2dev, u64 *addr_list, +int c2_nsmr_register_phys_kern(struct c2_dev *c2dev, u64 *addr_list, int page_size, int pbl_depth, u32 length, u32 off, u64 *va, enum c2_acf acf, struct c2_mr *mr); -extern int c2_stag_dealloc(struct c2_dev *c2dev, u32 stag_index); +int c2_stag_dealloc(struct c2_dev *c2dev, u32 stag_index); /* AE */ -extern void c2_ae_event(struct c2_dev *c2dev, u32 mq_index); +void c2_ae_event(struct c2_dev *c2dev, u32 mq_index); /* MQSP Allocator */ -extern int c2_init_mqsp_pool(struct c2_dev *c2dev, gfp_t gfp_mask, +int c2_init_mqsp_pool(struct c2_dev *c2dev, gfp_t gfp_mask, struct sp_chunk **root); -extern void c2_free_mqsp_pool(struct c2_dev *c2dev, struct sp_chunk *root); -extern __be16 *c2_alloc_mqsp(struct c2_dev *c2dev, struct sp_chunk *head, +void c2_free_mqsp_pool(struct c2_dev *c2dev, struct sp_chunk *root); +__be16 *c2_alloc_mqsp(struct c2_dev *c2dev, struct sp_chunk *head, dma_addr_t *dma_addr, gfp_t gfp_mask); -extern void c2_free_mqsp(__be16* mqsp); +void c2_free_mqsp(__be16* mqsp); #endif diff --git a/drivers/staging/rdma/amso1100/c2_mq.h b/drivers/staging/rdma/amso1100/c2_mq.h index fc1b9a7cec4b3..8e1b4d13409e4 100644 --- a/drivers/staging/rdma/amso1100/c2_mq.h +++ b/drivers/staging/rdma/amso1100/c2_mq.h @@ -93,14 +93,14 @@ static __inline__ int c2_mq_full(struct c2_mq *q) return q->priv == (be16_to_cpu(*q->shared) + q->q_size - 1) % q->q_size; } -extern void c2_mq_lconsume(struct c2_mq *q, u32 wqe_count); -extern void *c2_mq_alloc(struct c2_mq *q); -extern void c2_mq_produce(struct c2_mq *q); -extern void *c2_mq_consume(struct c2_mq *q); -extern void c2_mq_free(struct c2_mq *q); -extern void c2_mq_req_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size, +void c2_mq_lconsume(struct c2_mq *q, u32 wqe_count); +void *c2_mq_alloc(struct c2_mq *q); +void c2_mq_produce(struct c2_mq *q); +void *c2_mq_consume(struct c2_mq *q); +void c2_mq_free(struct c2_mq *q); +void c2_mq_req_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size, u8 __iomem *pool_start, u16 __iomem *peer, u32 type); -extern void c2_mq_rep_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size, +void c2_mq_rep_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size, u8 *pool_start, u16 __iomem *peer, u32 type); #endif /* _C2_MQ_H_ */ diff --git a/drivers/staging/rdma/amso1100/c2_vq.h b/drivers/staging/rdma/amso1100/c2_vq.h index 33805627a6074..c1f6cef60213d 100644 --- a/drivers/staging/rdma/amso1100/c2_vq.h +++ b/drivers/staging/rdma/amso1100/c2_vq.h @@ -47,17 +47,17 @@ struct c2_vq_req { struct c2_qp *qp; }; -extern int vq_init(struct c2_dev *c2dev); -extern void vq_term(struct c2_dev *c2dev); +int vq_init(struct c2_dev *c2dev); +void vq_term(struct c2_dev *c2dev); -extern struct c2_vq_req *vq_req_alloc(struct c2_dev *c2dev); -extern void vq_req_free(struct c2_dev *c2dev, struct c2_vq_req *req); -extern void vq_req_get(struct c2_dev *c2dev, struct c2_vq_req *req); -extern void vq_req_put(struct c2_dev *c2dev, struct c2_vq_req *req); -extern int vq_send_wr(struct c2_dev *c2dev, union c2wr * wr); +struct c2_vq_req *vq_req_alloc(struct c2_dev *c2dev); +void vq_req_free(struct c2_dev *c2dev, struct c2_vq_req *req); +void vq_req_get(struct c2_dev *c2dev, struct c2_vq_req *req); +void vq_req_put(struct c2_dev *c2dev, struct c2_vq_req *req); +int vq_send_wr(struct c2_dev *c2dev, union c2wr * wr); -extern void *vq_repbuf_alloc(struct c2_dev *c2dev); -extern void vq_repbuf_free(struct c2_dev *c2dev, void *reply); +void *vq_repbuf_alloc(struct c2_dev *c2dev); +void vq_repbuf_free(struct c2_dev *c2dev, void *reply); -extern int vq_wait_for_reply(struct c2_dev *c2dev, struct c2_vq_req *req); +int vq_wait_for_reply(struct c2_dev *c2dev, struct c2_vq_req *req); #endif /* _C2_VQ_H_ */ -- GitLab From 6e5b6131806d9fd05685ac6fddc297d91ea3b0ae Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Sun, 1 Nov 2015 16:14:32 +0530 Subject: [PATCH 0117/2855] staging: rdma: hfi1: Remove hfi1_nomsix() wrapper function This patch removes hfi1_nomsix() wrapper function that is used to wrap pci_disable_msix() and so substituted the wrapper function by a direct call to pci_disable_msix(). Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 2 +- drivers/staging/rdma/hfi1/hfi.h | 1 - drivers/staging/rdma/hfi1/pcie.c | 8 -------- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index e48981994b107..a6265277cfe5a 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -8785,7 +8785,7 @@ static void clean_up_interrupts(struct hfi1_devdata *dd) /* turn off interrupts */ if (dd->num_msix_entries) { /* MSI-X */ - hfi1_nomsix(dd); + pci_disable_msix(dd->pcidev); } else { /* INTx */ disable_intx(dd->pcidev); diff --git a/drivers/staging/rdma/hfi1/hfi.h b/drivers/staging/rdma/hfi1/hfi.h index 190f7a2f67731..73bd966f9e417 100644 --- a/drivers/staging/rdma/hfi1/hfi.h +++ b/drivers/staging/rdma/hfi1/hfi.h @@ -1612,7 +1612,6 @@ void hfi1_pcie_flr(struct hfi1_devdata *); int pcie_speeds(struct hfi1_devdata *); void request_msix(struct hfi1_devdata *, u32 *, struct hfi1_msix_entry *); void hfi1_enable_intx(struct pci_dev *); -void hfi1_nomsix(struct hfi1_devdata *); void restore_pci_variables(struct hfi1_devdata *dd); int do_pcie_gen3_transition(struct hfi1_devdata *dd); int parse_platform_config(struct hfi1_devdata *dd); diff --git a/drivers/staging/rdma/hfi1/pcie.c b/drivers/staging/rdma/hfi1/pcie.c index a956044459a2b..f531d0f6b212f 100644 --- a/drivers/staging/rdma/hfi1/pcie.c +++ b/drivers/staging/rdma/hfi1/pcie.c @@ -426,14 +426,6 @@ void request_msix(struct hfi1_devdata *dd, u32 *nent, tune_pcie_caps(dd); } -/* - * Disable MSI-X. - */ -void hfi1_nomsix(struct hfi1_devdata *dd) -{ - pci_disable_msix(dd->pcidev); -} - void hfi1_enable_intx(struct pci_dev *pdev) { /* first, turn on INTx */ -- GitLab From 8edf75020f60b2e1572291f93e0898351d478795 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Sun, 1 Nov 2015 16:16:40 +0530 Subject: [PATCH 0118/2855] staging: rdma: hfi1: sdma: Remove wrapper functions Drop wrapper functions sdma_start_err_halt_wait() and sdma_start_sw_clean_up() that can be replaced by a direct call to schedule_work() and tasklet_hi_schedule() respectively both of which are standard kernel functions. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/sdma.c | 40 +++++++++++--------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/drivers/staging/rdma/hfi1/sdma.c b/drivers/staging/rdma/hfi1/sdma.c index 2a1da21899003..f1855457fa329 100644 --- a/drivers/staging/rdma/hfi1/sdma.c +++ b/drivers/staging/rdma/hfi1/sdma.c @@ -236,7 +236,6 @@ static void sdma_hw_clean_up_task(unsigned long); static void sdma_put(struct sdma_state *); static void sdma_set_state(struct sdma_engine *, enum sdma_states); static void sdma_start_hw_clean_up(struct sdma_engine *); -static void sdma_start_sw_clean_up(struct sdma_engine *); static void sdma_sw_clean_up_task(unsigned long); static void sdma_sendctrl(struct sdma_engine *, unsigned); static void init_sdma_regs(struct sdma_engine *, u32, uint); @@ -470,12 +469,6 @@ static void sdma_err_halt_wait(struct work_struct *work) sdma_process_event(sde, sdma_event_e15_hw_halt_done); } -static void sdma_start_err_halt_wait(struct sdma_engine *sde) -{ - schedule_work(&sde->err_halt_worker); -} - - static void sdma_err_progress_check_schedule(struct sdma_engine *sde) { if (!is_bx(sde->dd) && HFI1_CAP_IS_KSET(SDMA_AHG)) { @@ -682,11 +675,6 @@ static void sdma_start_hw_clean_up(struct sdma_engine *sde) tasklet_hi_schedule(&sde->sdma_hw_clean_up_task); } -static void sdma_start_sw_clean_up(struct sdma_engine *sde) -{ - tasklet_hi_schedule(&sde->sdma_sw_clean_up_task); -} - static void sdma_set_state(struct sdma_engine *sde, enum sdma_states next_state) { @@ -2308,7 +2296,7 @@ static void __sdma_process_event(struct sdma_engine *sde, case sdma_event_e50_hw_cleaned: break; case sdma_event_e60_hw_halted: - sdma_start_err_halt_wait(sde); + schedule_work(&sde->err_halt_worker); break; case sdma_event_e70_go_idle: ss->go_s99_running = 0; @@ -2389,7 +2377,7 @@ static void __sdma_process_event(struct sdma_engine *sde, break; case sdma_event_e60_hw_halted: sdma_set_state(sde, sdma_state_s50_hw_halt_wait); - sdma_start_err_halt_wait(sde); + schedule_work(&sde->err_halt_worker); break; case sdma_event_e70_go_idle: break; @@ -2452,7 +2440,7 @@ static void __sdma_process_event(struct sdma_engine *sde, switch (event) { case sdma_event_e00_go_hw_down: sdma_set_state(sde, sdma_state_s00_hw_down); - sdma_start_sw_clean_up(sde); + tasklet_hi_schedule(&sde->sdma_sw_clean_up_task); break; case sdma_event_e10_go_hw_start: break; @@ -2494,13 +2482,13 @@ static void __sdma_process_event(struct sdma_engine *sde, switch (event) { case sdma_event_e00_go_hw_down: sdma_set_state(sde, sdma_state_s00_hw_down); - sdma_start_sw_clean_up(sde); + tasklet_hi_schedule(&sde->sdma_sw_clean_up_task); break; case sdma_event_e10_go_hw_start: break; case sdma_event_e15_hw_halt_done: sdma_set_state(sde, sdma_state_s30_sw_clean_up_wait); - sdma_start_sw_clean_up(sde); + tasklet_hi_schedule(&sde->sdma_sw_clean_up_task); break; case sdma_event_e25_hw_clean_up_done: break; @@ -2512,7 +2500,7 @@ static void __sdma_process_event(struct sdma_engine *sde, case sdma_event_e50_hw_cleaned: break; case sdma_event_e60_hw_halted: - sdma_start_err_halt_wait(sde); + schedule_work(&sde->err_halt_worker); break; case sdma_event_e70_go_idle: ss->go_s99_running = 0; @@ -2535,13 +2523,13 @@ static void __sdma_process_event(struct sdma_engine *sde, switch (event) { case sdma_event_e00_go_hw_down: sdma_set_state(sde, sdma_state_s00_hw_down); - sdma_start_sw_clean_up(sde); + tasklet_hi_schedule(&sde->sdma_sw_clean_up_task); break; case sdma_event_e10_go_hw_start: break; case sdma_event_e15_hw_halt_done: sdma_set_state(sde, sdma_state_s30_sw_clean_up_wait); - sdma_start_sw_clean_up(sde); + tasklet_hi_schedule(&sde->sdma_sw_clean_up_task); break; case sdma_event_e25_hw_clean_up_done: break; @@ -2553,7 +2541,7 @@ static void __sdma_process_event(struct sdma_engine *sde, case sdma_event_e50_hw_cleaned: break; case sdma_event_e60_hw_halted: - sdma_start_err_halt_wait(sde); + schedule_work(&sde->err_halt_worker); break; case sdma_event_e70_go_idle: ss->go_s99_running = 0; @@ -2575,7 +2563,7 @@ static void __sdma_process_event(struct sdma_engine *sde, switch (event) { case sdma_event_e00_go_hw_down: sdma_set_state(sde, sdma_state_s00_hw_down); - sdma_start_sw_clean_up(sde); + tasklet_hi_schedule(&sde->sdma_sw_clean_up_task); break; case sdma_event_e10_go_hw_start: break; @@ -2599,7 +2587,7 @@ static void __sdma_process_event(struct sdma_engine *sde, break; case sdma_event_e81_hw_frozen: sdma_set_state(sde, sdma_state_s82_freeze_sw_clean); - sdma_start_sw_clean_up(sde); + tasklet_hi_schedule(&sde->sdma_sw_clean_up_task); break; case sdma_event_e82_hw_unfreeze: break; @@ -2614,7 +2602,7 @@ static void __sdma_process_event(struct sdma_engine *sde, switch (event) { case sdma_event_e00_go_hw_down: sdma_set_state(sde, sdma_state_s00_hw_down); - sdma_start_sw_clean_up(sde); + tasklet_hi_schedule(&sde->sdma_sw_clean_up_task); break; case sdma_event_e10_go_hw_start: break; @@ -2658,7 +2646,7 @@ static void __sdma_process_event(struct sdma_engine *sde, switch (event) { case sdma_event_e00_go_hw_down: sdma_set_state(sde, sdma_state_s00_hw_down); - sdma_start_sw_clean_up(sde); + tasklet_hi_schedule(&sde->sdma_sw_clean_up_task); break; case sdma_event_e10_go_hw_start: break; @@ -2681,7 +2669,7 @@ static void __sdma_process_event(struct sdma_engine *sde, * progress check */ sdma_set_state(sde, sdma_state_s50_hw_halt_wait); - sdma_start_err_halt_wait(sde); + schedule_work(&sde->err_halt_worker); break; case sdma_event_e70_go_idle: sdma_set_state(sde, sdma_state_s60_idle_halt_wait); -- GitLab From 66c0933b30ae27ded1a48944381c9d05feff1979 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Sun, 1 Nov 2015 16:18:18 +0530 Subject: [PATCH 0119/2855] staging: rdma: hfi1: chip: Remove wrapper function Drop wrapper function remap_receive_available_interrupt() that wraps a call to remap_intr() with the only difference being the addition of macro IS_RCVAVAIL_START to the second argument of remap_intr(). Both the function names give the same information so the wrapper function can be dropped. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index a6265277cfe5a..4e22477c97394 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -8840,12 +8840,6 @@ static void remap_sdma_interrupts(struct hfi1_devdata *dd, msix_intr); } -static void remap_receive_available_interrupt(struct hfi1_devdata *dd, - int rx, int msix_intr) -{ - remap_intr(dd, IS_RCVAVAIL_START + rx, msix_intr); -} - static int request_intx_irq(struct hfi1_devdata *dd) { int ret; @@ -8983,7 +8977,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd) snprintf(me->name, sizeof(me->name), DRIVER_NAME"_%d kctxt%d", dd->unit, idx); err_info = "receive context"; - remap_receive_available_interrupt(dd, idx, i); + remap_intr(dd, IS_RCVAVAIL_START + idx, i); } else { /* not in our expected range - complain, then ignore it */ -- GitLab From 2592872f3b0b79b2247d6a40331a3761299041ac Mon Sep 17 00:00:00 2001 From: Burcin Akalin Date: Thu, 29 Oct 2015 18:54:06 +0300 Subject: [PATCH 0120/2855] staging: vt6656: Do not use multiple blank lines. Remove multiple blank lines. Problem found using checkpatch.pl "CHECK: Please don't use multiple blank lines" Signed-off-by: Burcin Akalin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/key.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index 181745d8e2500..1898fef1519cb 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -163,7 +163,6 @@ int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; } - if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { vnt_set_keymode(hw, mac_addr, key, VNT_KEY_PAIRWISE, key_dec_mode, true); -- GitLab From 165483c6337d25c00d9eb18271bc99f75f1dd8b6 Mon Sep 17 00:00:00 2001 From: Ksenija Stanojevic Date: Thu, 29 Oct 2015 13:42:38 -0700 Subject: [PATCH 0121/2855] Staging: rtl8723au: Remove unused EFUSE_Write1Byte function Function is defined but not used, so remove it. Signed-off-by: Ksenija Stanojevic Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_efuse.c | 42 ---------------------- 1 file changed, 42 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_efuse.c b/drivers/staging/rtl8723au/core/rtw_efuse.c index 906b5782d1658..5e8a1ba8a8b99 100644 --- a/drivers/staging/rtl8723au/core/rtw_efuse.c +++ b/drivers/staging/rtl8723au/core/rtw_efuse.c @@ -273,48 +273,6 @@ u8 EFUSE_Read1Byte23a(struct rtw_adapter *Adapter, u16 Address) return 0xFF; } -/* Copy from WMAC fot EFUSE write 1 byte. */ -void EFUSE_Write1Byte(struct rtw_adapter *Adapter, u16 Address, u8 Value) -{ - u8 Bytetemp = {0x00}; - u8 temp = {0x00}; - u32 k = 0; - u16 contentLen = 0; - - EFUSE_GetEfuseDefinition23a(Adapter, EFUSE_WIFI, - TYPE_EFUSE_REAL_CONTENT_LEN, - (void *)&contentLen); - - if (Address < contentLen) { /* E-fuse 512Byte */ - rtl8723au_write8(Adapter, EFUSE_CTRL, Value); - - /* Write E-fuse Register address bit0~7 */ - temp = Address & 0xFF; - rtl8723au_write8(Adapter, EFUSE_CTRL+1, temp); - Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+2); - - /* Write E-fuse Register address bit8~9 */ - temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC); - rtl8723au_write8(Adapter, EFUSE_CTRL+2, temp); - - /* Write 0x30[31]= 1 */ - Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3); - temp = Bytetemp | 0x80; - rtl8723au_write8(Adapter, EFUSE_CTRL+3, temp); - - /* Wait Write-ready (0x30[31]= 0) */ - Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3); - while (Bytetemp & 0x80) { - Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3); - k++; - if (k == 100) { - k = 0; - break; - } - } - } -} - /* Read one byte from real Efuse. */ int efuse_OneByteRead23a(struct rtw_adapter *pAdapter, u16 addr, u8 *data) { -- GitLab From 84295526a5797f7dfd75bba3d9438074f46ad7aa Mon Sep 17 00:00:00 2001 From: Ksenija Stanojevic Date: Thu, 29 Oct 2015 13:43:41 -0700 Subject: [PATCH 0122/2855] Staging: rtl8723au: Declare function static Declare function Efuse_ReadAllMap as static since it's defined and used only in this file. Signed-off-by: Ksenija Stanojevic Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_efuse.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723au/core/rtw_efuse.c b/drivers/staging/rtl8723au/core/rtw_efuse.c index 5e8a1ba8a8b99..f174b4d1a0184 100644 --- a/drivers/staging/rtl8723au/core/rtw_efuse.c +++ b/drivers/staging/rtl8723au/core/rtw_efuse.c @@ -459,7 +459,8 @@ int rtw_BT_efuse_map_read23a(struct rtw_adapter *padapter, } /* Read All Efuse content */ -void Efuse_ReadAllMap(struct rtw_adapter *pAdapter, u8 efuseType, u8 *Efuse) +static void Efuse_ReadAllMap(struct rtw_adapter *pAdapter, u8 efuseType, + u8 *Efuse) { u16 mapLen = 0; -- GitLab From d8340ed0446cd2195db92980beb4ff575e35e0a1 Mon Sep 17 00:00:00 2001 From: Burcin Akalin Date: Fri, 30 Oct 2015 03:29:08 +0300 Subject: [PATCH 0123/2855] staging: nvec:Misspelled the word Word error correction.Problem found using checkpatch.pl CHECK: 'Implemenation' may be misspelled - perhaps 'Implementation'? Signed-off-by: Burcin Akalin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/nvec/README b/drivers/staging/nvec/README index 9a320b7fdbe6c..0e2d5c4c875fb 100644 --- a/drivers/staging/nvec/README +++ b/drivers/staging/nvec/README @@ -1,4 +1,4 @@ -NVEC: An NVidia compliant Embedded Controller Protocol Implemenation +NVEC: An NVidia compliant Embedded Controller Protocol Implementation This is an implementation of the NVEC protocol used to communicate with an embedded controller (EC) via I2C bus. The EC is an I2C master while the host -- GitLab From a9548c223e08d5d022cb6e5daf64c3bb1ca41aa5 Mon Sep 17 00:00:00 2001 From: Burcin Akalin Date: Fri, 30 Oct 2015 03:04:03 +0300 Subject: [PATCH 0124/2855] staging: nvec: Add space around '>>' Add space around operator '>>'. Problem found using checkpatch.pl CHECK: spaces preferred around that '>>' (ctx:VxV) Signed-off-by: Burcin Akalin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 802c9597d4210..ba030ab22e9ba 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -740,7 +740,7 @@ static void tegra_init_i2c_slave(struct nvec_chip *nvec) writel(I2C_SL_NEWSL, nvec->base + I2C_SL_CNFG); writel(0x1E, nvec->base + I2C_SL_DELAY_COUNT); - writel(nvec->i2c_addr>>1, nvec->base + I2C_SL_ADDR1); + writel(nvec->i2c_addr >> 1, nvec->base + I2C_SL_ADDR1); writel(0, nvec->base + I2C_SL_ADDR2); enable_irq(nvec->irq); -- GitLab From b4129f2f53311804ee394fa80539710ab09a8401 Mon Sep 17 00:00:00 2001 From: Burcin Akalin Date: Fri, 30 Oct 2015 02:49:01 +0300 Subject: [PATCH 0125/2855] staging: nvec: Add space around '<<' Add space around operator '<<'. Problem found using checkpatch.pl CHECK: spaces preferred around that '<<' (ctx:VxV) Signed-off-by: Burcin Akalin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index ba030ab22e9ba..4ae44a5168f94 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -40,18 +40,18 @@ #include "nvec.h" #define I2C_CNFG 0x00 -#define I2C_CNFG_PACKET_MODE_EN (1<<10) -#define I2C_CNFG_NEW_MASTER_SFM (1<<11) +#define I2C_CNFG_PACKET_MODE_EN (1 << 10) +#define I2C_CNFG_NEW_MASTER_SFM (1 << 11) #define I2C_CNFG_DEBOUNCE_CNT_SHIFT 12 #define I2C_SL_CNFG 0x20 -#define I2C_SL_NEWSL (1<<2) -#define I2C_SL_NACK (1<<1) -#define I2C_SL_RESP (1<<0) -#define I2C_SL_IRQ (1<<3) -#define END_TRANS (1<<4) -#define RCVD (1<<2) -#define RNW (1<<1) +#define I2C_SL_NEWSL (1 << 2) +#define I2C_SL_NACK (1 << 1) +#define I2C_SL_RESP (1 << 0) +#define I2C_SL_IRQ (1 << 3) +#define END_TRANS (1 << 4) +#define RCVD (1 << 2) +#define RNW (1 << 1) #define I2C_SL_RCVD 0x24 #define I2C_SL_STATUS 0x28 -- GitLab From ca3fde19d47ef6edbee4c6ca7e824de0382abe67 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Fri, 30 Oct 2015 02:29:03 +0530 Subject: [PATCH 0126/2855] staging: gdm724x: Remove wrapper function Remove wrapper function that can be replaced by a single line of code. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm724x/gdm_lte.c | 2 +- drivers/staging/gdm724x/netlink_k.c | 5 ----- drivers/staging/gdm724x/netlink_k.h | 1 - 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c index 79de678807ccb..17d148f6e02cc 100644 --- a/drivers/staging/gdm724x/gdm_lte.c +++ b/drivers/staging/gdm724x/gdm_lte.c @@ -555,7 +555,7 @@ int gdm_lte_event_init(void) void gdm_lte_event_exit(void) { if (lte_event.sock && --lte_event.ref_cnt == 0) { - netlink_exit(lte_event.sock); + sock_release(lte_event.sock->sk_socket); lte_event.sock = NULL; } } diff --git a/drivers/staging/gdm724x/netlink_k.c b/drivers/staging/gdm724x/netlink_k.c index 92254fdaae1ee..9d8347769e888 100644 --- a/drivers/staging/gdm724x/netlink_k.c +++ b/drivers/staging/gdm724x/netlink_k.c @@ -107,11 +107,6 @@ struct sock *netlink_init(int unit, return sock; } -void netlink_exit(struct sock *sock) -{ - sock_release(sock->sk_socket); -} - int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len) { static u32 seq; diff --git a/drivers/staging/gdm724x/netlink_k.h b/drivers/staging/gdm724x/netlink_k.h index 589486d76714f..7cf979b3f826c 100644 --- a/drivers/staging/gdm724x/netlink_k.h +++ b/drivers/staging/gdm724x/netlink_k.h @@ -19,7 +19,6 @@ struct sock *netlink_init(int unit, void (*cb)(struct net_device *dev, u16 type, void *msg, int len)); -void netlink_exit(struct sock *sock); int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len); #endif /* _NETLINK_K_H_ */ -- GitLab From b0035ef7552e222e7b0d07644a3234350d8bba8e Mon Sep 17 00:00:00 2001 From: Burcin Akalin Date: Fri, 30 Oct 2015 04:01:01 +0300 Subject: [PATCH 0127/2855] staging: octeon: Add space around '+' Add space around operator '+'. Problem found using checkpatch.pl CHECK: spaces preferred around that '+' (ctx:VxV) Signed-off-by: Burcin Akalin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/octeon/ethernet-defines.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/octeon/ethernet-defines.h b/drivers/staging/octeon/ethernet-defines.h index 13e4cee1f86d0..07bd2b87f6a0f 100644 --- a/drivers/staging/octeon/ethernet-defines.h +++ b/drivers/staging/octeon/ethernet-defines.h @@ -40,6 +40,6 @@ #define FAU_TOTAL_TX_TO_CLEAN (CVMX_FAU_REG_END - sizeof(u32)) #define FAU_NUM_PACKET_BUFFERS_TO_FREE (FAU_TOTAL_TX_TO_CLEAN - sizeof(u32)) -#define TOTAL_NUMBER_OF_PORTS (CVMX_PIP_NUM_INPUT_PORTS+1) +#define TOTAL_NUMBER_OF_PORTS (CVMX_PIP_NUM_INPUT_PORTS + 1) #endif /* __ETHERNET_DEFINES_H__ */ -- GitLab From cdfeaae5b3034d630528d044f7bc72e209321517 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Fri, 30 Oct 2015 19:33:02 +0530 Subject: [PATCH 0128/2855] Staging: sm750fb: Remove unused modedb.h file The header file modedb.h is only included in sm750.c but the things defined by modedb.h are not used anywhere in sm750.c. Thus, drop the include in sm750.c and modedb.h can be dropped completely. Signed-off-by: Shraddha Barke Acked-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm750fb/modedb.h | 233 ------------------------------- drivers/staging/sm750fb/sm750.c | 2 - 2 files changed, 235 deletions(-) delete mode 100644 drivers/staging/sm750fb/modedb.h diff --git a/drivers/staging/sm750fb/modedb.h b/drivers/staging/sm750fb/modedb.h deleted file mode 100644 index 83cb2e2ae51a6..0000000000000 --- a/drivers/staging/sm750fb/modedb.h +++ /dev/null @@ -1,233 +0,0 @@ - -static const struct fb_videomode modedb2[] = { - { - /* 640x400 @ 70 Hz, 31.5 kHz hsync */ - NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2, - 0, FB_VMODE_NONINTERLACED - }, { - /* 640x480 @ 60 Hz, 31.5 kHz hsync */ - NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, - 0, FB_VMODE_NONINTERLACED - }, { - /* 800x600 @ 56 Hz, 35.15 kHz hsync */ - NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */ - NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8, - 0, FB_VMODE_INTERLACED - }, { - /* 640x400 @ 85 Hz, 37.86 kHz hsync */ - NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, { - /* 640x480 @ 72 Hz, 36.5 kHz hsync */ - NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3, - 0, FB_VMODE_NONINTERLACED - }, { - /* 640x480 @ 75 Hz, 37.50 kHz hsync */ - NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3, - 0, FB_VMODE_NONINTERLACED - }, { - /* 800x600 @ 60 Hz, 37.8 kHz hsync */ - NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED - }, { - /* 640x480 @ 85 Hz, 43.27 kHz hsync */ - NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */ - NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10, - 0, FB_VMODE_INTERLACED - }, { - /* 800x600 @ 72 Hz, 48.0 kHz hsync */ - NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED - }, { - /* 1024x768 @ 60 Hz, 48.4 kHz hsync */ - NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6, - 0, FB_VMODE_NONINTERLACED - }, { - /* 640x480 @ 100 Hz, 53.01 kHz hsync */ - NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1152x864 @ 60 Hz, 53.5 kHz hsync */ - NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8, - 0, FB_VMODE_NONINTERLACED - }, { - /* 800x600 @ 85 Hz, 55.84 kHz hsync */ - NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1024x768 @ 70 Hz, 56.5 kHz hsync */ - NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1280x960-60 VESA */ - NULL, 60, 1280, 960, 9259, 312, 96, 36, 1, 112, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA - }, { - /* 1280x1024-60 VESA */ - NULL, 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA - }, { - /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */ - NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12, - 0, FB_VMODE_INTERLACED - }, { - /* 800x600 @ 100 Hz, 64.02 kHz hsync */ - NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1024x768 @ 76 Hz, 62.5 kHz hsync */ - NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1152x864 @ 70 Hz, 62.4 kHz hsync */ - NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */ - NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1400x1050 @ 60Hz, 63.9 kHz hsync */ - NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/ - NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED - }, { - /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/ - NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED - }, { - /* 1024x768 @ 85 Hz, 70.24 kHz hsync */ - NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1152x864 @ 78 Hz, 70.8 kHz hsync */ - NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */ - NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1600x1200 @ 60Hz, 75.00 kHz hsync */ - NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED - }, { - /* 1152x864 @ 84 Hz, 76.0 kHz hsync */ - NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */ - NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1024x768 @ 100Hz, 80.21 kHz hsync */ - NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */ - NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */ - NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1152x864 @ 100 Hz, 89.62 kHz hsync */ - NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */ - NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED - }, { - /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */ - NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED - }, { - /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */ - NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED - }, { - /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */ - NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15, - 0, FB_VMODE_NONINTERLACED - }, { - /* 1800x1440 @ 64Hz, 96.15 kHz hsync */ - NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED - }, { - /* 1800x1440 @ 70Hz, 104.52 kHz hsync */ - NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED - }, { - /* 512x384 @ 78 Hz, 31.50 kHz hsync */ - NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3, - 0, FB_VMODE_NONINTERLACED - }, { - /* 512x384 @ 85 Hz, 34.38 kHz hsync */ - NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3, - 0, FB_VMODE_NONINTERLACED - }, { - /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */ - NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1, - 0, FB_VMODE_DOUBLE - }, { - /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */ - NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1, - 0, FB_VMODE_DOUBLE - }, { - /* 320x240 @ 72 Hz, 36.5 kHz hsync */ - NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2, - 0, FB_VMODE_DOUBLE - }, { - /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */ - NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1, - 0, FB_VMODE_DOUBLE - }, { - /* 400x300 @ 60 Hz, 37.8 kHz hsync */ - NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2, - 0, FB_VMODE_DOUBLE - }, { - /* 400x300 @ 72 Hz, 48.0 kHz hsync */ - NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3, - 0, FB_VMODE_DOUBLE - }, { - /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */ - NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1, - 0, FB_VMODE_DOUBLE - }, { - /* 480x300 @ 60 Hz, 37.8 kHz hsync */ - NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2, - 0, FB_VMODE_DOUBLE - }, { - /* 480x300 @ 63 Hz, 39.6 kHz hsync */ - NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2, - 0, FB_VMODE_DOUBLE - }, { - /* 480x300 @ 72 Hz, 48.0 kHz hsync */ - NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, - 0, FB_VMODE_DOUBLE - }, -}; -static const int nmodedb2 = sizeof(modedb2); diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index 860e1c288ad5e..c78421b5b0e7c 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c @@ -21,8 +21,6 @@ #include "sm750_accel.h" #include "sm750_cursor.h" -#include "modedb.h" - /* * #ifdef __BIG_ENDIAN * ssize_t lynxfb_ops_write(struct fb_info *info, const char __user *buf, -- GitLab From b4f286a953f0d9582fc5ec5d823afc6035470461 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Fri, 30 Oct 2015 19:33:03 +0530 Subject: [PATCH 0129/2855] Staging: dgnc: Remove unused #include header file Since the things defined by digi.h are not used in dgnc_utils.c, remove the header from this file. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_utils.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/dgnc/dgnc_utils.c b/drivers/staging/dgnc/dgnc_utils.c index f76de82908d3d..95272f4765fcf 100644 --- a/drivers/staging/dgnc/dgnc_utils.c +++ b/drivers/staging/dgnc/dgnc_utils.c @@ -1,7 +1,6 @@ #include #include #include "dgnc_utils.h" -#include "digi.h" /* * dgnc_ms_sleep() -- GitLab From 4e2cdf9324e93eef2e06f640d001979368f1e2b7 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Sat, 31 Oct 2015 15:51:04 +0530 Subject: [PATCH 0130/2855] staging: wlan-ng: Remove wrapper function Remove wrapper function that can be replaced by a single line of code. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/hfa384x_usb.c | 4 ++-- drivers/staging/wlan-ng/prism2mgmt.h | 1 - drivers/staging/wlan-ng/prism2sta.c | 21 --------------------- 3 files changed, 2 insertions(+), 24 deletions(-) diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index 444ebed7313a4..e3c9860fb2cb7 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -3504,7 +3504,7 @@ static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb) rxmeta->signal = usbin->rxfrm.desc.signal - hw->dbmadjust; rxmeta->noise = usbin->rxfrm.desc.silence - hw->dbmadjust; - prism2sta_ev_rx(wlandev, skb); + p80211netdev_rx(wlandev, skb); break; @@ -3628,7 +3628,7 @@ static void hfa384x_int_rxmonitor(wlandevice_t *wlandev, } /* pass it back up */ - prism2sta_ev_rx(wlandev, skb); + p80211netdev_rx(wlandev, skb); } /*---------------------------------------------------------------- diff --git a/drivers/staging/wlan-ng/prism2mgmt.h b/drivers/staging/wlan-ng/prism2mgmt.h index 16f1239591045..7a9f424607b75 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.h +++ b/drivers/staging/wlan-ng/prism2mgmt.h @@ -68,7 +68,6 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate); void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status); void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status); -void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb); void prism2sta_ev_alloc(wlandevice_t *wlandev); int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp); diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index c57f48a1d8df7..131223afd918e 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -1836,27 +1836,6 @@ void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status) wlandev->netdev->stats.tx_packets++; } -/* - * prism2sta_ev_rx - * - * Handles the Rx event. - * - * Arguments: - * wlandev wlan device structure - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - */ -void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb) -{ - p80211netdev_rx(wlandev, skb); -} - /* * prism2sta_ev_alloc * -- GitLab From 6ba714bb5f78d8d5647e8b8afbb739223c5a4620 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Sat, 31 Oct 2015 15:47:38 +0530 Subject: [PATCH 0131/2855] staging: wlan-ng: hfa384x_usb: Remove wrapper function Remove wrapper function that can be replaced by a single line of code. As a result of the change, there is an unused variable which has also been removed in this patch. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/hfa384x_usb.c | 30 +-------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index e3c9860fb2cb7..7551ac25d89d1 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -177,9 +177,6 @@ static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb); static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin); -static void -hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout); - static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin, int urb_status); @@ -3674,7 +3671,6 @@ static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin) static void hfa384x_usbout_callback(struct urb *urb) { wlandevice_t *wlandev = urb->context; - hfa384x_usbout_t *usbout = urb->transfer_buffer; #ifdef DEBUG_USB dbprint_urb(urb); @@ -3683,7 +3679,7 @@ static void hfa384x_usbout_callback(struct urb *urb) if (wlandev && wlandev->netdev) { switch (urb->status) { case 0: - hfa384x_usbout_tx(wlandev, usbout); + prism2sta_ev_alloc(wlandev); break; case -EPIPE: @@ -4037,30 +4033,6 @@ static int hfa384x_usbctlx_submit(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx) return 0; } -/*---------------------------------------------------------------- -* hfa384x_usbout_tx -* -* At this point we have finished a send of a frame. Mark the URB -* as available and call ev_alloc to notify higher layers we're -* ready for more. -* -* Arguments: -* wlandev wlan device -* usbout ptr to the usb transfer buffer -* -* Returns: -* nothing -* -* Side effects: -* -* Call context: -* interrupt -----------------------------------------------------------------*/ -static void hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout) -{ - prism2sta_ev_alloc(wlandev); -} - /*---------------------------------------------------------------- * hfa384x_isgood_pdrcore * -- GitLab From d4f8455b1267f40c090fc6fbf06335554d280be1 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Sat, 31 Oct 2015 15:49:29 +0530 Subject: [PATCH 0132/2855] staging: wlan-ng: prism2mib: Remove unnecessary variable Drop unnecessary variable that can be replaced by a single line of code. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/prism2mib.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c index b4a15ef3a405c..cdda07d1c2688 100644 --- a/drivers/staging/wlan-ng/prism2mib.c +++ b/drivers/staging/wlan-ng/prism2mib.c @@ -660,7 +660,6 @@ static int prism2mib_fragmentationthreshold(struct mibrec *mib, struct p80211msg_dot11req_mibset *msg, void *data) { - int result; u32 *uint32 = (u32 *) data; if (!isget) @@ -672,9 +671,7 @@ static int prism2mib_fragmentationthreshold(struct mibrec *mib, return 0; } - result = prism2mib_uint32(mib, isget, wlandev, hw, msg, data); - - return result; + return prism2mib_uint32(mib, isget, wlandev, hw, msg, data); } /*---------------------------------------------------------------- -- GitLab From 6fbbf260b00d4d79e87cd5b383906875237d4aa8 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Sat, 31 Oct 2015 21:53:03 +0530 Subject: [PATCH 0133/2855] Staging: wlan-ng: Remove unused function declaration Function p80211wext_event_associated has been declared but not used. Thus remove the declaration. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211netdev.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h index c547e1cb4c0df..810ee68aa18e2 100644 --- a/drivers/staging/wlan-ng/p80211netdev.h +++ b/drivers/staging/wlan-ng/p80211netdev.h @@ -141,7 +141,6 @@ typedef struct p80211_frmrx_t { struct iw_statistics *p80211wext_get_wireless_stats(netdevice_t *dev); /* wireless extensions' ioctls */ extern struct iw_handler_def p80211wext_handler_def; -int p80211wext_event_associated(struct wlandevice *wlandev, int assoc); /* WEP stuff */ #define NUM_WEPKEYS 4 -- GitLab From 925b65782c218cbc76bb975fb80ccf2072c735ee Mon Sep 17 00:00:00 2001 From: Amarjargal Gundjalam Date: Sat, 31 Oct 2015 01:56:37 -0700 Subject: [PATCH 0134/2855] staging: media: bcm2048: match alignments with open parenthesis This patch fixes the checkpatch issue: CHECK: Alignment should match open parenthesis Signed-off-by: Amarjargal Gundjalam Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/bcm2048/radio-bcm2048.c | 304 +++++++++--------- 1 file changed, 146 insertions(+), 158 deletions(-) diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index b10d6016b9939..3b012d37de498 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -348,7 +348,7 @@ static struct region_info region_configs[] = { * I2C Interface read / write */ static int bcm2048_send_command(struct bcm2048_device *bdev, unsigned int reg, - unsigned int value) + unsigned int value) { struct i2c_client *client = bdev->client; u8 data[2]; @@ -370,7 +370,7 @@ static int bcm2048_send_command(struct bcm2048_device *bdev, unsigned int reg, } static int bcm2048_recv_command(struct bcm2048_device *bdev, unsigned int reg, - u8 *value) + u8 *value) { struct i2c_client *client = bdev->client; @@ -385,7 +385,7 @@ static int bcm2048_recv_command(struct bcm2048_device *bdev, unsigned int reg, } static int bcm2048_recv_duples(struct bcm2048_device *bdev, unsigned int reg, - u8 *value, u8 duples) + u8 *value, u8 duples) { struct i2c_client *client = bdev->client; struct i2c_adapter *adap = client->adapter; @@ -436,7 +436,7 @@ static int bcm2048_set_power_state(struct bcm2048_device *bdev, u8 power) */ if (power) err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM, - bdev->cache_fm_rds_system); + bdev->cache_fm_rds_system); msleep(BCM2048_DEFAULT_POWERING_DELAY); if (!power) @@ -475,17 +475,17 @@ static int bcm2048_set_rds_no_lock(struct bcm2048_device *bdev, u8 rds_on) bdev->rds_state = BCM2048_RDS_ON; flags = BCM2048_RDS_FLAG_FIFO_WLINE; err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1, - flags); + flags); } else { flags = 0; bdev->rds_state = 0; err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1, - flags); + flags); memset(&bdev->rds_info, 0, sizeof(bdev->rds_info)); } err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM, - bdev->cache_fm_rds_system); + bdev->cache_fm_rds_system); return err; } @@ -545,14 +545,14 @@ static int bcm2048_set_fm_automatic_stereo_mono(struct bcm2048_device *bdev, bdev->cache_fm_ctrl |= BCM2048_STEREO_MONO_AUTO_SELECT; err = bcm2048_send_command(bdev, BCM2048_I2C_FM_CTRL, - bdev->cache_fm_ctrl); + bdev->cache_fm_ctrl); mutex_unlock(&bdev->mutex); return err; } static int bcm2048_set_fm_hi_lo_injection(struct bcm2048_device *bdev, - u8 hi_lo) + u8 hi_lo) { int err; @@ -564,7 +564,7 @@ static int bcm2048_set_fm_hi_lo_injection(struct bcm2048_device *bdev, bdev->cache_fm_ctrl |= BCM2048_HI_LO_INJECTION; err = bcm2048_send_command(bdev, BCM2048_I2C_FM_CTRL, - bdev->cache_fm_ctrl); + bdev->cache_fm_ctrl); mutex_unlock(&bdev->mutex); return err; @@ -592,7 +592,7 @@ static int bcm2048_set_fm_frequency(struct bcm2048_device *bdev, u32 frequency) int err; if (frequency < bdev->region_info.bottom_frequency || - frequency > bdev->region_info.top_frequency) + frequency > bdev->region_info.top_frequency) return -EDOM; frequency -= BCM2048_FREQUENCY_BASE; @@ -601,7 +601,7 @@ static int bcm2048_set_fm_frequency(struct bcm2048_device *bdev, u32 frequency) err = bcm2048_send_command(bdev, BCM2048_I2C_FM_FREQ0, lsb(frequency)); err |= bcm2048_send_command(bdev, BCM2048_I2C_FM_FREQ1, - msb(frequency)); + msb(frequency)); if (!err) bdev->frequency = frequency; @@ -632,12 +632,12 @@ static int bcm2048_get_fm_frequency(struct bcm2048_device *bdev) } static int bcm2048_set_fm_af_frequency(struct bcm2048_device *bdev, - u32 frequency) + u32 frequency) { int err; if (frequency < bdev->region_info.bottom_frequency || - frequency > bdev->region_info.top_frequency) + frequency > bdev->region_info.top_frequency) return -EDOM; frequency -= BCM2048_FREQUENCY_BASE; @@ -645,9 +645,9 @@ static int bcm2048_set_fm_af_frequency(struct bcm2048_device *bdev, mutex_lock(&bdev->mutex); err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AF_FREQ0, - lsb(frequency)); + lsb(frequency)); err |= bcm2048_send_command(bdev, BCM2048_I2C_FM_AF_FREQ1, - msb(frequency)); + msb(frequency)); if (!err) bdev->frequency = frequency; @@ -692,7 +692,7 @@ static int bcm2048_set_fm_deemphasis(struct bcm2048_device *bdev, int d) bdev->cache_fm_audio_ctrl0 |= deemphasis; err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0, - bdev->cache_fm_audio_ctrl0); + bdev->cache_fm_audio_ctrl0); if (!err) bdev->region_info.deemphasis = d; @@ -740,7 +740,7 @@ static int bcm2048_set_region(struct bcm2048_device *bdev, u8 region) bdev->cache_fm_ctrl &= ~BCM2048_BAND_SELECT; err = bcm2048_send_command(bdev, BCM2048_I2C_FM_CTRL, - bdev->cache_fm_ctrl); + bdev->cache_fm_ctrl); if (err) { mutex_unlock(&bdev->mutex); goto done; @@ -748,7 +748,7 @@ static int bcm2048_set_region(struct bcm2048_device *bdev, u8 region) mutex_unlock(&bdev->mutex); if (bdev->frequency < region_configs[region].bottom_frequency || - bdev->frequency > region_configs[region].top_frequency) + bdev->frequency > region_configs[region].top_frequency) new_frequency = region_configs[region].bottom_frequency; if (new_frequency > 0) { @@ -759,7 +759,7 @@ static int bcm2048_set_region(struct bcm2048_device *bdev, u8 region) } err = bcm2048_set_fm_deemphasis(bdev, - region_configs[region].deemphasis); + region_configs[region].deemphasis); done: return err; @@ -786,10 +786,10 @@ static int bcm2048_set_mute(struct bcm2048_device *bdev, u16 mute) if (mute) bdev->cache_fm_audio_ctrl0 |= (BCM2048_RF_MUTE | - BCM2048_MANUAL_MUTE); + BCM2048_MANUAL_MUTE); err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0, - bdev->cache_fm_audio_ctrl0); + bdev->cache_fm_audio_ctrl0); if (!err) bdev->mute_state = mute; @@ -807,7 +807,7 @@ static int bcm2048_get_mute(struct bcm2048_device *bdev) if (bdev->power_state) { err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0, - &value); + &value); if (!err) err = value & (BCM2048_RF_MUTE | BCM2048_MANUAL_MUTE); } else { @@ -826,11 +826,11 @@ static int bcm2048_set_audio_route(struct bcm2048_device *bdev, u8 route) route &= (BCM2048_AUDIO_ROUTE_DAC | BCM2048_AUDIO_ROUTE_I2S); bdev->cache_fm_audio_ctrl0 &= ~(BCM2048_AUDIO_ROUTE_DAC | - BCM2048_AUDIO_ROUTE_I2S); + BCM2048_AUDIO_ROUTE_I2S); bdev->cache_fm_audio_ctrl0 |= route; err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0, - bdev->cache_fm_audio_ctrl0); + bdev->cache_fm_audio_ctrl0); mutex_unlock(&bdev->mutex); return err; @@ -849,7 +849,7 @@ static int bcm2048_get_audio_route(struct bcm2048_device *bdev) if (!err) return value & (BCM2048_AUDIO_ROUTE_DAC | - BCM2048_AUDIO_ROUTE_I2S); + BCM2048_AUDIO_ROUTE_I2S); return err; } @@ -865,7 +865,7 @@ static int bcm2048_set_dac_output(struct bcm2048_device *bdev, u8 channels) bdev->cache_fm_audio_ctrl0 |= channels; err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0, - bdev->cache_fm_audio_ctrl0); + bdev->cache_fm_audio_ctrl0); mutex_unlock(&bdev->mutex); return err; @@ -884,13 +884,13 @@ static int bcm2048_get_dac_output(struct bcm2048_device *bdev) if (!err) return value & (BCM2048_DAC_OUTPUT_LEFT | - BCM2048_DAC_OUTPUT_RIGHT); + BCM2048_DAC_OUTPUT_RIGHT); return err; } static int bcm2048_set_fm_search_rssi_threshold(struct bcm2048_device *bdev, - u8 threshold) + u8 threshold) { int err; @@ -901,7 +901,7 @@ static int bcm2048_set_fm_search_rssi_threshold(struct bcm2048_device *bdev, bdev->cache_fm_search_ctrl0 |= threshold; err = bcm2048_send_command(bdev, BCM2048_I2C_FM_SEARCH_CTRL0, - bdev->cache_fm_search_ctrl0); + bdev->cache_fm_search_ctrl0); mutex_unlock(&bdev->mutex); return err; @@ -937,7 +937,7 @@ static int bcm2048_set_fm_search_mode_direction(struct bcm2048_device *bdev, bdev->cache_fm_search_ctrl0 |= BCM2048_SEARCH_DIRECTION; err = bcm2048_send_command(bdev, BCM2048_I2C_FM_SEARCH_CTRL0, - bdev->cache_fm_search_ctrl0); + bdev->cache_fm_search_ctrl0); mutex_unlock(&bdev->mutex); return err; @@ -961,7 +961,7 @@ static int bcm2048_get_fm_search_mode_direction(struct bcm2048_device *bdev) } static int bcm2048_set_fm_search_tune_mode(struct bcm2048_device *bdev, - u8 mode) + u8 mode) { int err, timeout, restart_rds = 0; u8 value, flags; @@ -1024,7 +1024,7 @@ static int bcm2048_get_fm_search_tune_mode(struct bcm2048_device *bdev) mutex_lock(&bdev->mutex); err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_SEARCH_TUNE_MODE, - &value); + &value); mutex_unlock(&bdev->mutex); @@ -1040,10 +1040,10 @@ static int bcm2048_set_rds_b_block_mask(struct bcm2048_device *bdev, u16 mask) mutex_lock(&bdev->mutex); - err = bcm2048_send_command(bdev, - BCM2048_I2C_RDS_BLKB_MASK0, lsb(mask)); - err |= bcm2048_send_command(bdev, - BCM2048_I2C_RDS_BLKB_MASK1, msb(mask)); + err = bcm2048_send_command(bdev, BCM2048_I2C_RDS_BLKB_MASK0, + lsb(mask)); + err |= bcm2048_send_command(bdev, BCM2048_I2C_RDS_BLKB_MASK1, + msb(mask)); mutex_unlock(&bdev->mutex); return err; @@ -1056,10 +1056,8 @@ static int bcm2048_get_rds_b_block_mask(struct bcm2048_device *bdev) mutex_lock(&bdev->mutex); - err = bcm2048_recv_command(bdev, - BCM2048_I2C_RDS_BLKB_MASK0, &lsb); - err |= bcm2048_recv_command(bdev, - BCM2048_I2C_RDS_BLKB_MASK1, &msb); + err = bcm2048_recv_command(bdev, BCM2048_I2C_RDS_BLKB_MASK0, &lsb); + err |= bcm2048_recv_command(bdev, BCM2048_I2C_RDS_BLKB_MASK1, &msb); mutex_unlock(&bdev->mutex); @@ -1070,16 +1068,16 @@ static int bcm2048_get_rds_b_block_mask(struct bcm2048_device *bdev) } static int bcm2048_set_rds_b_block_match(struct bcm2048_device *bdev, - u16 match) + u16 match) { int err; mutex_lock(&bdev->mutex); - err = bcm2048_send_command(bdev, - BCM2048_I2C_RDS_BLKB_MATCH0, lsb(match)); - err |= bcm2048_send_command(bdev, - BCM2048_I2C_RDS_BLKB_MATCH1, msb(match)); + err = bcm2048_send_command(bdev, BCM2048_I2C_RDS_BLKB_MATCH0, + lsb(match)); + err |= bcm2048_send_command(bdev, BCM2048_I2C_RDS_BLKB_MATCH1, + msb(match)); mutex_unlock(&bdev->mutex); return err; @@ -1092,10 +1090,8 @@ static int bcm2048_get_rds_b_block_match(struct bcm2048_device *bdev) mutex_lock(&bdev->mutex); - err = bcm2048_recv_command(bdev, - BCM2048_I2C_RDS_BLKB_MATCH0, &lsb); - err |= bcm2048_recv_command(bdev, - BCM2048_I2C_RDS_BLKB_MATCH1, &msb); + err = bcm2048_recv_command(bdev, BCM2048_I2C_RDS_BLKB_MATCH0, &lsb); + err |= bcm2048_recv_command(bdev, BCM2048_I2C_RDS_BLKB_MATCH1, &msb); mutex_unlock(&bdev->mutex); @@ -1111,10 +1107,8 @@ static int bcm2048_set_rds_pi_mask(struct bcm2048_device *bdev, u16 mask) mutex_lock(&bdev->mutex); - err = bcm2048_send_command(bdev, - BCM2048_I2C_RDS_PI_MASK0, lsb(mask)); - err |= bcm2048_send_command(bdev, - BCM2048_I2C_RDS_PI_MASK1, msb(mask)); + err = bcm2048_send_command(bdev, BCM2048_I2C_RDS_PI_MASK0, lsb(mask)); + err |= bcm2048_send_command(bdev, BCM2048_I2C_RDS_PI_MASK1, msb(mask)); mutex_unlock(&bdev->mutex); return err; @@ -1127,10 +1121,8 @@ static int bcm2048_get_rds_pi_mask(struct bcm2048_device *bdev) mutex_lock(&bdev->mutex); - err = bcm2048_recv_command(bdev, - BCM2048_I2C_RDS_PI_MASK0, &lsb); - err |= bcm2048_recv_command(bdev, - BCM2048_I2C_RDS_PI_MASK1, &msb); + err = bcm2048_recv_command(bdev, BCM2048_I2C_RDS_PI_MASK0, &lsb); + err |= bcm2048_recv_command(bdev, BCM2048_I2C_RDS_PI_MASK1, &msb); mutex_unlock(&bdev->mutex); @@ -1146,10 +1138,10 @@ static int bcm2048_set_rds_pi_match(struct bcm2048_device *bdev, u16 match) mutex_lock(&bdev->mutex); - err = bcm2048_send_command(bdev, - BCM2048_I2C_RDS_PI_MATCH0, lsb(match)); - err |= bcm2048_send_command(bdev, - BCM2048_I2C_RDS_PI_MATCH1, msb(match)); + err = bcm2048_send_command(bdev, BCM2048_I2C_RDS_PI_MATCH0, + lsb(match)); + err |= bcm2048_send_command(bdev, BCM2048_I2C_RDS_PI_MATCH1, + msb(match)); mutex_unlock(&bdev->mutex); return err; @@ -1162,10 +1154,8 @@ static int bcm2048_get_rds_pi_match(struct bcm2048_device *bdev) mutex_lock(&bdev->mutex); - err = bcm2048_recv_command(bdev, - BCM2048_I2C_RDS_PI_MATCH0, &lsb); - err |= bcm2048_recv_command(bdev, - BCM2048_I2C_RDS_PI_MATCH1, &msb); + err = bcm2048_recv_command(bdev, BCM2048_I2C_RDS_PI_MATCH0, &lsb); + err |= bcm2048_recv_command(bdev, BCM2048_I2C_RDS_PI_MATCH1, &msb); mutex_unlock(&bdev->mutex); @@ -1181,10 +1171,8 @@ static int bcm2048_set_fm_rds_mask(struct bcm2048_device *bdev, u16 mask) mutex_lock(&bdev->mutex); - err = bcm2048_send_command(bdev, - BCM2048_I2C_FM_RDS_MASK0, lsb(mask)); - err |= bcm2048_send_command(bdev, - BCM2048_I2C_FM_RDS_MASK1, msb(mask)); + err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK0, lsb(mask)); + err |= bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1, msb(mask)); mutex_unlock(&bdev->mutex); return err; @@ -1245,13 +1233,13 @@ static int bcm2048_set_fm_best_tune_mode(struct bcm2048_device *bdev, u8 mode) /* Perform read as the manual indicates */ err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_BEST_TUNE_MODE, - &value); + &value); value &= ~BCM2048_BEST_TUNE_MODE; if (mode) value |= BCM2048_BEST_TUNE_MODE; err |= bcm2048_send_command(bdev, BCM2048_I2C_FM_BEST_TUNE_MODE, - value); + value); mutex_unlock(&bdev->mutex); return err; @@ -1265,7 +1253,7 @@ static int bcm2048_get_fm_best_tune_mode(struct bcm2048_device *bdev) mutex_lock(&bdev->mutex); err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_BEST_TUNE_MODE, - &value); + &value); mutex_unlock(&bdev->mutex); @@ -1352,7 +1340,7 @@ static int bcm2048_checkrev(struct bcm2048_device *bdev) if (!err) { dev_info(&bdev->client->dev, "BCM2048 Version 0x%x\n", - version); + version); return version; } @@ -1478,7 +1466,7 @@ static int bcm2048_rds_block_crc(struct bcm2048_device *bdev, int i) } static void bcm2048_parse_rds_rt_block(struct bcm2048_device *bdev, int i, - int index, int crc) + int index, int crc) { /* Good data will overwrite poor data */ if (crc) { @@ -1505,7 +1493,7 @@ static int bcm2048_parse_rt_match_b(struct bcm2048_device *bdev, int i) return -EIO; if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) == - BCM2048_RDS_BLOCK_B) { + BCM2048_RDS_BLOCK_B) { rt_id = bdev->rds_info.radio_text[i+1] & BCM2048_RDS_BLOCK_MASK; @@ -1516,7 +1504,7 @@ static int bcm2048_parse_rt_match_b(struct bcm2048_device *bdev, int i) if (rt_group_b != bdev->rds_info.rds_rt_group_b) { memset(bdev->rds_info.rds_rt, 0, - sizeof(bdev->rds_info.rds_rt)); + sizeof(bdev->rds_info.rds_rt)); bdev->rds_info.rds_rt_group_b = rt_group_b; } @@ -1524,7 +1512,7 @@ static int bcm2048_parse_rt_match_b(struct bcm2048_device *bdev, int i) /* A to B or (vice versa), means: clear screen */ if (rt_ab != bdev->rds_info.rds_rt_ab) { memset(bdev->rds_info.rds_rt, 0, - sizeof(bdev->rds_info.rds_rt)); + sizeof(bdev->rds_info.rds_rt)); bdev->rds_info.rds_rt_ab = rt_ab; } @@ -1544,7 +1532,7 @@ static int bcm2048_parse_rt_match_b(struct bcm2048_device *bdev, int i) } static int bcm2048_parse_rt_match_c(struct bcm2048_device *bdev, int i, - int index) + int index) { int crc; @@ -1567,7 +1555,7 @@ static int bcm2048_parse_rt_match_c(struct bcm2048_device *bdev, int i, } static void bcm2048_parse_rt_match_d(struct bcm2048_device *bdev, int i, - int index) + int index) { int crc; @@ -1579,7 +1567,7 @@ static void bcm2048_parse_rt_match_d(struct bcm2048_device *bdev, int i, BUG_ON((index+4) >= BCM2048_MAX_RDS_RT); if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) == - BCM2048_RDS_BLOCK_D) + BCM2048_RDS_BLOCK_D) bcm2048_parse_rds_rt_block(bdev, i, index+2, crc); } @@ -1607,22 +1595,22 @@ static void bcm2048_parse_rds_rt(struct bcm2048_device *bdev) } /* Skip erroneous blocks due to messed up A block altogether */ - if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) - == BCM2048_RDS_BLOCK_A) { + if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) == + BCM2048_RDS_BLOCK_A) { crc = bcm2048_rds_block_crc(bdev, i); if (crc == BCM2048_RDS_CRC_UNRECOVARABLE) continue; /* Syncronize to a good RDS PI */ - if (((bdev->rds_info.radio_text[i+1] << 8) + - bdev->rds_info.radio_text[i+2]) == - bdev->rds_info.rds_pi) - match_b = 1; + if (((bdev->rds_info.radio_text[i + 1] << 8) + + bdev->rds_info.radio_text[i + 2]) == + bdev->rds_info.rds_pi) + match_b = 1; } } } static void bcm2048_parse_rds_ps_block(struct bcm2048_device *bdev, int i, - int index, int crc) + int index, int crc) { /* Good data will overwrite poor data */ if (crc) { @@ -1640,7 +1628,7 @@ static void bcm2048_parse_rds_ps_block(struct bcm2048_device *bdev, int i, } static int bcm2048_parse_ps_match_c(struct bcm2048_device *bdev, int i, - int index) + int index) { int crc; @@ -1650,14 +1638,14 @@ static int bcm2048_parse_ps_match_c(struct bcm2048_device *bdev, int i, return 0; if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) == - BCM2048_RDS_BLOCK_C) + BCM2048_RDS_BLOCK_C) return 1; return 0; } static void bcm2048_parse_ps_match_d(struct bcm2048_device *bdev, int i, - int index) + int index) { int crc; @@ -1667,7 +1655,7 @@ static void bcm2048_parse_ps_match_d(struct bcm2048_device *bdev, int i, return; if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) == - BCM2048_RDS_BLOCK_D) + BCM2048_RDS_BLOCK_D) bcm2048_parse_rds_ps_block(bdev, i, index, crc); } @@ -1682,7 +1670,7 @@ static int bcm2048_parse_ps_match_b(struct bcm2048_device *bdev, int i) /* Block B Radio PS match */ if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) == - BCM2048_RDS_BLOCK_B) { + BCM2048_RDS_BLOCK_B) { ps_id = bdev->rds_info.radio_text[i+1] & BCM2048_RDS_BLOCK_MASK; ps_group = bdev->rds_info.radio_text[i+1] & @@ -1743,16 +1731,16 @@ static void bcm2048_parse_rds_ps(struct bcm2048_device *bdev) } /* Skip erroneous blocks due to messed up A block altogether */ - if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) - == BCM2048_RDS_BLOCK_A) { + if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) == + BCM2048_RDS_BLOCK_A) { crc = bcm2048_rds_block_crc(bdev, i); if (crc == BCM2048_RDS_CRC_UNRECOVARABLE) continue; /* Syncronize to a good RDS PI */ - if (((bdev->rds_info.radio_text[i+1] << 8) + - bdev->rds_info.radio_text[i+2]) == - bdev->rds_info.rds_pi) - match_b = 1; + if (((bdev->rds_info.radio_text[i + 1] << 8) + + bdev->rds_info.radio_text[i + 2]) == + bdev->rds_info.rds_pi) + match_b = 1; } } } @@ -1764,7 +1752,7 @@ static void bcm2048_rds_fifo_receive(struct bcm2048_device *bdev) mutex_lock(&bdev->mutex); err = bcm2048_recv_duples(bdev, BCM2048_I2C_RDS_DATA, - bdev->rds_info.radio_text, bdev->fifo_size); + bdev->rds_info.radio_text, bdev->fifo_size); if (err != 2) { dev_err(&bdev->client->dev, "RDS Read problem\n"); mutex_unlock(&bdev->mutex); @@ -1802,7 +1790,7 @@ static int bcm2048_get_rds_data(struct bcm2048_device *bdev, char *data) for (i = 0; i < bdev->rds_info.text_len; i++) { p += sprintf(data_buffer+p, "%x ", - bdev->rds_info.radio_text[i]); + bdev->rds_info.radio_text[i]); } memcpy(data, data_buffer, p); @@ -1829,7 +1817,7 @@ static int bcm2048_init(struct bcm2048_device *bdev) goto exit; err = bcm2048_set_dac_output(bdev, BCM2048_DAC_OUTPUT_LEFT | - BCM2048_DAC_OUTPUT_RIGHT); + BCM2048_DAC_OUTPUT_RIGHT); exit: return err; @@ -1935,7 +1923,7 @@ static void bcm2048_work(struct work_struct *work) if (bdev->rds_state) { flags = BCM2048_RDS_FLAG_FIFO_WLINE; bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1, - flags); + flags); } bdev->rds_data_available = 1; bdev->rd_index = 0; /* new data, new start */ @@ -2084,70 +2072,70 @@ DEFINE_SYSFS_PROPERTY(region, unsigned, int, "%u", 0) static struct device_attribute attrs[] = { __ATTR(power_state, S_IRUGO | S_IWUSR, bcm2048_power_state_read, - bcm2048_power_state_write), + bcm2048_power_state_write), __ATTR(mute, S_IRUGO | S_IWUSR, bcm2048_mute_read, - bcm2048_mute_write), + bcm2048_mute_write), __ATTR(audio_route, S_IRUGO | S_IWUSR, bcm2048_audio_route_read, - bcm2048_audio_route_write), + bcm2048_audio_route_write), __ATTR(dac_output, S_IRUGO | S_IWUSR, bcm2048_dac_output_read, - bcm2048_dac_output_write), + bcm2048_dac_output_write), __ATTR(fm_hi_lo_injection, S_IRUGO | S_IWUSR, - bcm2048_fm_hi_lo_injection_read, - bcm2048_fm_hi_lo_injection_write), + bcm2048_fm_hi_lo_injection_read, + bcm2048_fm_hi_lo_injection_write), __ATTR(fm_frequency, S_IRUGO | S_IWUSR, bcm2048_fm_frequency_read, - bcm2048_fm_frequency_write), + bcm2048_fm_frequency_write), __ATTR(fm_af_frequency, S_IRUGO | S_IWUSR, - bcm2048_fm_af_frequency_read, - bcm2048_fm_af_frequency_write), + bcm2048_fm_af_frequency_read, + bcm2048_fm_af_frequency_write), __ATTR(fm_deemphasis, S_IRUGO | S_IWUSR, bcm2048_fm_deemphasis_read, - bcm2048_fm_deemphasis_write), + bcm2048_fm_deemphasis_write), __ATTR(fm_rds_mask, S_IRUGO | S_IWUSR, bcm2048_fm_rds_mask_read, - bcm2048_fm_rds_mask_write), + bcm2048_fm_rds_mask_write), __ATTR(fm_best_tune_mode, S_IRUGO | S_IWUSR, - bcm2048_fm_best_tune_mode_read, - bcm2048_fm_best_tune_mode_write), + bcm2048_fm_best_tune_mode_read, + bcm2048_fm_best_tune_mode_write), __ATTR(fm_search_rssi_threshold, S_IRUGO | S_IWUSR, - bcm2048_fm_search_rssi_threshold_read, - bcm2048_fm_search_rssi_threshold_write), + bcm2048_fm_search_rssi_threshold_read, + bcm2048_fm_search_rssi_threshold_write), __ATTR(fm_search_mode_direction, S_IRUGO | S_IWUSR, - bcm2048_fm_search_mode_direction_read, - bcm2048_fm_search_mode_direction_write), + bcm2048_fm_search_mode_direction_read, + bcm2048_fm_search_mode_direction_write), __ATTR(fm_search_tune_mode, S_IRUGO | S_IWUSR, - bcm2048_fm_search_tune_mode_read, - bcm2048_fm_search_tune_mode_write), + bcm2048_fm_search_tune_mode_read, + bcm2048_fm_search_tune_mode_write), __ATTR(rds, S_IRUGO | S_IWUSR, bcm2048_rds_read, - bcm2048_rds_write), + bcm2048_rds_write), __ATTR(rds_b_block_mask, S_IRUGO | S_IWUSR, - bcm2048_rds_b_block_mask_read, - bcm2048_rds_b_block_mask_write), + bcm2048_rds_b_block_mask_read, + bcm2048_rds_b_block_mask_write), __ATTR(rds_b_block_match, S_IRUGO | S_IWUSR, - bcm2048_rds_b_block_match_read, - bcm2048_rds_b_block_match_write), + bcm2048_rds_b_block_match_read, + bcm2048_rds_b_block_match_write), __ATTR(rds_pi_mask, S_IRUGO | S_IWUSR, bcm2048_rds_pi_mask_read, - bcm2048_rds_pi_mask_write), + bcm2048_rds_pi_mask_write), __ATTR(rds_pi_match, S_IRUGO | S_IWUSR, bcm2048_rds_pi_match_read, - bcm2048_rds_pi_match_write), + bcm2048_rds_pi_match_write), __ATTR(rds_wline, S_IRUGO | S_IWUSR, bcm2048_rds_wline_read, - bcm2048_rds_wline_write), + bcm2048_rds_wline_write), __ATTR(rds_pi, S_IRUGO, bcm2048_rds_pi_read, NULL), __ATTR(rds_rt, S_IRUGO, bcm2048_rds_rt_read, NULL), __ATTR(rds_ps, S_IRUGO, bcm2048_rds_ps_read, NULL), __ATTR(fm_rds_flags, S_IRUGO, bcm2048_fm_rds_flags_read, NULL), __ATTR(region_bottom_frequency, S_IRUGO, - bcm2048_region_bottom_frequency_read, NULL), + bcm2048_region_bottom_frequency_read, NULL), __ATTR(region_top_frequency, S_IRUGO, - bcm2048_region_top_frequency_read, NULL), + bcm2048_region_top_frequency_read, NULL), __ATTR(fm_carrier_error, S_IRUGO, - bcm2048_fm_carrier_error_read, NULL), + bcm2048_fm_carrier_error_read, NULL), __ATTR(fm_rssi, S_IRUGO, - bcm2048_fm_rssi_read, NULL), + bcm2048_fm_rssi_read, NULL), __ATTR(region, S_IRUGO | S_IWUSR, bcm2048_region_read, - bcm2048_region_write), + bcm2048_region_write), __ATTR(rds_data, S_IRUGO, bcm2048_rds_data_read, NULL), }; static int bcm2048_sysfs_unregister_properties(struct bcm2048_device *bdev, - int size) + int size) { int i; @@ -2165,7 +2153,7 @@ static int bcm2048_sysfs_register_properties(struct bcm2048_device *bdev) for (i = 0; i < ARRAY_SIZE(attrs); i++) { if (device_create_file(&bdev->client->dev, &attrs[i]) != 0) { dev_err(&bdev->client->dev, - "could not register sysfs entry\n"); + "could not register sysfs entry\n"); err = -EBUSY; bcm2048_sysfs_unregister_properties(bdev, i); break; @@ -2197,7 +2185,7 @@ static int bcm2048_fops_release(struct file *file) } static unsigned int bcm2048_fops_poll(struct file *file, - struct poll_table_struct *pts) + struct poll_table_struct *pts) { struct bcm2048_device *bdev = video_drvdata(file); int retval = 0; @@ -2211,7 +2199,7 @@ static unsigned int bcm2048_fops_poll(struct file *file, } static ssize_t bcm2048_fops_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { struct bcm2048_device *bdev = video_drvdata(file); int i; @@ -2229,7 +2217,7 @@ static ssize_t bcm2048_fops_read(struct file *file, char __user *buf, } /* interruptible_sleep_on(&bdev->read_queue); */ if (wait_event_interruptible(bdev->read_queue, - bdev->rds_data_available) < 0) { + bdev->rds_data_available) < 0) { retval = -EINTR; goto done; } @@ -2249,7 +2237,7 @@ static ssize_t bcm2048_fops_read(struct file *file, char __user *buf, tmpbuf[i+1] = bdev->rds_info.radio_text[bdev->rd_index+i+1]; tmpbuf[i+2] = (bdev->rds_info.radio_text[bdev->rd_index + i] & 0xf0) >> 4; if ((bdev->rds_info.radio_text[bdev->rd_index+i] & - BCM2048_RDS_CRC_MASK) == BCM2048_RDS_CRC_UNRECOVARABLE) + BCM2048_RDS_CRC_MASK) == BCM2048_RDS_CRC_UNRECOVARABLE) tmpbuf[i+2] |= 0x80; if (copy_to_user(buf+i, tmpbuf, 3)) { retval = -EFAULT; @@ -2319,7 +2307,7 @@ static struct v4l2_queryctrl bcm2048_v4l2_queryctrl[] = { }; static int bcm2048_vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *capability) + struct v4l2_capability *capability) { struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file)); @@ -2337,7 +2325,7 @@ static int bcm2048_vidioc_querycap(struct file *file, void *priv, } static int bcm2048_vidioc_g_input(struct file *filp, void *priv, - unsigned int *i) + unsigned int *i) { *i = 0; @@ -2345,7 +2333,7 @@ static int bcm2048_vidioc_g_input(struct file *filp, void *priv, } static int bcm2048_vidioc_s_input(struct file *filp, void *priv, - unsigned int i) + unsigned int i) { if (i) return -EINVAL; @@ -2354,7 +2342,7 @@ static int bcm2048_vidioc_s_input(struct file *filp, void *priv, } static int bcm2048_vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qc) + struct v4l2_queryctrl *qc) { int i; @@ -2369,7 +2357,7 @@ static int bcm2048_vidioc_queryctrl(struct file *file, void *priv, } static int bcm2048_vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) + struct v4l2_control *ctrl) { struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file)); int err = 0; @@ -2389,7 +2377,7 @@ static int bcm2048_vidioc_g_ctrl(struct file *file, void *priv, } static int bcm2048_vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) + struct v4l2_control *ctrl) { struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file)); int err = 0; @@ -2417,7 +2405,7 @@ static int bcm2048_vidioc_s_ctrl(struct file *file, void *priv, } static int bcm2048_vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *audio) + struct v4l2_audio *audio) { if (audio->index > 1) return -EINVAL; @@ -2429,7 +2417,7 @@ static int bcm2048_vidioc_g_audio(struct file *file, void *priv, } static int bcm2048_vidioc_s_audio(struct file *file, void *priv, - const struct v4l2_audio *audio) + const struct v4l2_audio *audio) { if (audio->index != 0) return -EINVAL; @@ -2438,7 +2426,7 @@ static int bcm2048_vidioc_s_audio(struct file *file, void *priv, } static int bcm2048_vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *tuner) + struct v4l2_tuner *tuner) { struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file)); s8 f_error; @@ -2493,7 +2481,7 @@ static int bcm2048_vidioc_g_tuner(struct file *file, void *priv, } static int bcm2048_vidioc_s_tuner(struct file *file, void *priv, - const struct v4l2_tuner *tuner) + const struct v4l2_tuner *tuner) { struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file)); @@ -2507,7 +2495,7 @@ static int bcm2048_vidioc_s_tuner(struct file *file, void *priv, } static int bcm2048_vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *freq) + struct v4l2_frequency *freq) { struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file)); int err = 0; @@ -2528,7 +2516,7 @@ static int bcm2048_vidioc_g_frequency(struct file *file, void *priv, } static int bcm2048_vidioc_s_frequency(struct file *file, void *priv, - const struct v4l2_frequency *freq) + const struct v4l2_frequency *freq) { struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file)); int err; @@ -2546,7 +2534,7 @@ static int bcm2048_vidioc_s_frequency(struct file *file, void *priv, } static int bcm2048_vidioc_s_hw_freq_seek(struct file *file, void *priv, - const struct v4l2_hw_freq_seek *seek) + const struct v4l2_hw_freq_seek *seek) { struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file)); int err; @@ -2559,7 +2547,7 @@ static int bcm2048_vidioc_s_hw_freq_seek(struct file *file, void *priv, err = bcm2048_set_fm_search_mode_direction(bdev, seek->seek_upward); err |= bcm2048_set_fm_search_tune_mode(bdev, - BCM2048_FM_AUTO_SEARCH_MODE); + BCM2048_FM_AUTO_SEARCH_MODE); return err; } @@ -2594,7 +2582,7 @@ static struct video_device bcm2048_viddev_template = { * I2C driver interface */ static int bcm2048_i2c_driver_probe(struct i2c_client *client, - const struct i2c_device_id *id) + const struct i2c_device_id *id) { struct bcm2048_device *bdev; int err; @@ -2613,8 +2601,8 @@ static int bcm2048_i2c_driver_probe(struct i2c_client *client, if (client->irq) { err = request_irq(client->irq, - bcm2048_handler, IRQF_TRIGGER_FALLING, - client->name, bdev); + bcm2048_handler, IRQF_TRIGGER_FALLING, + client->name, bdev); if (err < 0) { dev_err(&client->dev, "Could not request IRQ\n"); goto free_bdev; -- GitLab From 3ac086fb99fe689fb2183bdd5503912749b22e71 Mon Sep 17 00:00:00 2001 From: Amarjargal Gundjalam Date: Sat, 31 Oct 2015 01:56:38 -0700 Subject: [PATCH 0135/2855] staging: media: bcm2048: add space around operators This patch fixes the checkpatch issue: CHECK: spaces preferred around that ' ' Signed-off-by: Amarjargal Gundjalam Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/bcm2048/radio-bcm2048.c | 73 ++++++++++--------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index 3b012d37de498..9bb5ad9ec5931 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -1350,7 +1350,7 @@ static int bcm2048_checkrev(struct bcm2048_device *bdev) static int bcm2048_get_rds_rt(struct bcm2048_device *bdev, char *data) { int err = 0, i, j = 0, ce = 0, cr = 0; - char data_buffer[BCM2048_MAX_RDS_RT+1]; + char data_buffer[BCM2048_MAX_RDS_RT + 1]; mutex_lock(&bdev->mutex); @@ -1400,7 +1400,7 @@ unlock: static int bcm2048_get_rds_ps(struct bcm2048_device *bdev, char *data) { int err = 0, i, j = 0; - char data_buffer[BCM2048_MAX_RDS_PS+1]; + char data_buffer[BCM2048_MAX_RDS_PS + 1]; mutex_lock(&bdev->mutex); @@ -1440,8 +1440,8 @@ static void bcm2048_parse_rds_pi(struct bcm2048_device *bdev) /* Block A match, only data without crc errors taken */ if (bdev->rds_info.radio_text[i] == BCM2048_RDS_BLOCK_A) { - pi = (bdev->rds_info.radio_text[i+1] << 8) + - bdev->rds_info.radio_text[i+2]; + pi = (bdev->rds_info.radio_text[i + 1] << 8) + + bdev->rds_info.radio_text[i + 2]; if (!bdev->rds_info.rds_pi) { bdev->rds_info.rds_pi = pi; @@ -1472,14 +1472,15 @@ static void bcm2048_parse_rds_rt_block(struct bcm2048_device *bdev, int i, if (crc) { if (!bdev->rds_info.rds_rt[index]) bdev->rds_info.rds_rt[index] = - bdev->rds_info.radio_text[i+1]; - if (!bdev->rds_info.rds_rt[index+1]) - bdev->rds_info.rds_rt[index+1] = - bdev->rds_info.radio_text[i+2]; + bdev->rds_info.radio_text[i + 1]; + if (!bdev->rds_info.rds_rt[index + 1]) + bdev->rds_info.rds_rt[index + 1] = + bdev->rds_info.radio_text[i + 2]; } else { - bdev->rds_info.rds_rt[index] = bdev->rds_info.radio_text[i+1]; - bdev->rds_info.rds_rt[index+1] = - bdev->rds_info.radio_text[i+2]; + bdev->rds_info.rds_rt[index] = + bdev->rds_info.radio_text[i + 1]; + bdev->rds_info.rds_rt[index + 1] = + bdev->rds_info.radio_text[i + 2]; } } @@ -1495,11 +1496,11 @@ static int bcm2048_parse_rt_match_b(struct bcm2048_device *bdev, int i) if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) == BCM2048_RDS_BLOCK_B) { - rt_id = bdev->rds_info.radio_text[i+1] & + rt_id = bdev->rds_info.radio_text[i + 1] & BCM2048_RDS_BLOCK_MASK; - rt_group_b = bdev->rds_info.radio_text[i+1] & + rt_group_b = bdev->rds_info.radio_text[i + 1] & BCM2048_RDS_GROUP_AB_MASK; - rt_ab = bdev->rds_info.radio_text[i+2] & + rt_ab = bdev->rds_info.radio_text[i + 2] & BCM2048_RDS_RT_AB_MASK; if (rt_group_b != bdev->rds_info.rds_rt_group_b) { @@ -1516,7 +1517,7 @@ static int bcm2048_parse_rt_match_b(struct bcm2048_device *bdev, int i) bdev->rds_info.rds_rt_ab = rt_ab; } - index = bdev->rds_info.radio_text[i+2] & + index = bdev->rds_info.radio_text[i + 2] & BCM2048_RDS_RT_INDEX; if (bdev->rds_info.rds_rt_group_b) @@ -1568,7 +1569,7 @@ static void bcm2048_parse_rt_match_d(struct bcm2048_device *bdev, int i, if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) == BCM2048_RDS_BLOCK_D) - bcm2048_parse_rds_rt_block(bdev, i, index+2, crc); + bcm2048_parse_rds_rt_block(bdev, i, index + 2, crc); } static void bcm2048_parse_rds_rt(struct bcm2048_device *bdev) @@ -1616,14 +1617,15 @@ static void bcm2048_parse_rds_ps_block(struct bcm2048_device *bdev, int i, if (crc) { if (!bdev->rds_info.rds_ps[index]) bdev->rds_info.rds_ps[index] = - bdev->rds_info.radio_text[i+1]; - if (!bdev->rds_info.rds_ps[index+1]) - bdev->rds_info.rds_ps[index+1] = - bdev->rds_info.radio_text[i+2]; + bdev->rds_info.radio_text[i + 1]; + if (!bdev->rds_info.rds_ps[index + 1]) + bdev->rds_info.rds_ps[index + 1] = + bdev->rds_info.radio_text[i + 2]; } else { - bdev->rds_info.rds_ps[index] = bdev->rds_info.radio_text[i+1]; - bdev->rds_info.rds_ps[index+1] = - bdev->rds_info.radio_text[i+2]; + bdev->rds_info.rds_ps[index] = + bdev->rds_info.radio_text[i + 1]; + bdev->rds_info.rds_ps[index + 1] = + bdev->rds_info.radio_text[i + 2]; } } @@ -1671,9 +1673,9 @@ static int bcm2048_parse_ps_match_b(struct bcm2048_device *bdev, int i) /* Block B Radio PS match */ if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) == BCM2048_RDS_BLOCK_B) { - ps_id = bdev->rds_info.radio_text[i+1] & + ps_id = bdev->rds_info.radio_text[i + 1] & BCM2048_RDS_BLOCK_MASK; - ps_group = bdev->rds_info.radio_text[i+1] & + ps_group = bdev->rds_info.radio_text[i + 1] & BCM2048_RDS_GROUP_AB_MASK; /* @@ -1697,7 +1699,7 @@ static int bcm2048_parse_ps_match_b(struct bcm2048_device *bdev, int i) } if (ps_id == BCM2048_RDS_PS) { - index = bdev->rds_info.radio_text[i+2] & + index = bdev->rds_info.radio_text[i + 2] & BCM2048_RDS_PS_INDEX; index <<= 1; return index; @@ -1789,7 +1791,7 @@ static int bcm2048_get_rds_data(struct bcm2048_device *bdev, char *data) } for (i = 0; i < bdev->rds_info.text_len; i++) { - p += sprintf(data_buffer+p, "%x ", + p += sprintf(data_buffer + p, "%x ", bdev->rds_info.radio_text[i]); } @@ -2062,7 +2064,7 @@ property_str_read(rds_rt, (BCM2048_MAX_RDS_RT + 1)) property_str_read(rds_ps, (BCM2048_MAX_RDS_PS + 1)) property_read(fm_rds_flags, unsigned int, "%u") -property_str_read(rds_data, BCM2048_MAX_RDS_RADIO_TEXT*5) +property_str_read(rds_data, BCM2048_MAX_RDS_RADIO_TEXT * 5) property_read(region_bottom_frequency, unsigned int, "%u") property_read(region_top_frequency, unsigned int, "%u") @@ -2233,13 +2235,16 @@ static ssize_t bcm2048_fops_read(struct file *file, char __user *buf, while (i < count) { unsigned char tmpbuf[3]; - tmpbuf[i] = bdev->rds_info.radio_text[bdev->rd_index+i+2]; - tmpbuf[i+1] = bdev->rds_info.radio_text[bdev->rd_index+i+1]; - tmpbuf[i+2] = (bdev->rds_info.radio_text[bdev->rd_index + i] & 0xf0) >> 4; - if ((bdev->rds_info.radio_text[bdev->rd_index+i] & + tmpbuf[i] = bdev->rds_info.radio_text[bdev->rd_index + i + 2]; + tmpbuf[i + 1] = + bdev->rds_info.radio_text[bdev->rd_index + i + 1]; + tmpbuf[i + 2] = + (bdev->rds_info.radio_text[bdev->rd_index + i] & + 0xf0) >> 4; + if ((bdev->rds_info.radio_text[bdev->rd_index + i] & BCM2048_RDS_CRC_MASK) == BCM2048_RDS_CRC_UNRECOVARABLE) - tmpbuf[i+2] |= 0x80; - if (copy_to_user(buf+i, tmpbuf, 3)) { + tmpbuf[i + 2] |= 0x80; + if (copy_to_user(buf + i, tmpbuf, 3)) { retval = -EFAULT; break; } -- GitLab From 70fe32268366ebbcf7ce1adca2242ecdab89923e Mon Sep 17 00:00:00 2001 From: Amarjargal Gundjalam Date: Sat, 31 Oct 2015 01:56:39 -0700 Subject: [PATCH 0136/2855] staging: media: bcm2048: remove unnecessary blank lines This patch fixes the checkpatch issues: CHECK: Please don't use multiple blank lines CHECK: Blank lines aren't necessary after an open brace '{' Signed-off-by: Amarjargal Gundjalam Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/bcm2048/radio-bcm2048.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index 9bb5ad9ec5931..9a69d17c3eab4 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -179,7 +179,6 @@ #define BCM2048_DEFAULT_TIMEOUT 1500 #define BCM2048_AUTO_SEARCH_TIMEOUT 3000 - #define BCM2048_FREQDEV_UNIT 10000 #define BCM2048_FREQV4L2_MULTI 625 #define dev_to_v4l2(f) ((f * BCM2048_FREQDEV_UNIT) / BCM2048_FREQV4L2_MULTI) @@ -1436,10 +1435,8 @@ static void bcm2048_parse_rds_pi(struct bcm2048_device *bdev) u16 pi; for (i = 0; i < bdev->fifo_size; i += BCM2048_RDS_FIFO_DUPLE_SIZE) { - /* Block A match, only data without crc errors taken */ if (bdev->rds_info.radio_text[i] == BCM2048_RDS_BLOCK_A) { - pi = (bdev->rds_info.radio_text[i + 1] << 8) + bdev->rds_info.radio_text[i + 2]; @@ -1495,7 +1492,6 @@ static int bcm2048_parse_rt_match_b(struct bcm2048_device *bdev, int i) if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) == BCM2048_RDS_BLOCK_B) { - rt_id = bdev->rds_info.radio_text[i + 1] & BCM2048_RDS_BLOCK_MASK; rt_group_b = bdev->rds_info.radio_text[i + 1] & @@ -1577,7 +1573,6 @@ static void bcm2048_parse_rds_rt(struct bcm2048_device *bdev) int i, index = 0, crc, match_b = 0, match_c = 0, match_d = 0; for (i = 0; i < bdev->fifo_size; i += BCM2048_RDS_FIFO_DUPLE_SIZE) { - if (match_b) { match_b = 0; index = bcm2048_parse_rt_match_b(bdev, i); @@ -1714,7 +1709,6 @@ static void bcm2048_parse_rds_ps(struct bcm2048_device *bdev) int i, index = 0, crc, match_b = 0, match_c = 0, match_d = 0; for (i = 0; i < bdev->fifo_size; i += BCM2048_RDS_FIFO_DUPLE_SIZE) { - if (match_b) { match_b = 0; index = bcm2048_parse_ps_match_b(bdev, i); @@ -1911,7 +1905,6 @@ static void bcm2048_work(struct work_struct *work) if (flag_lsb & (BCM2048_FM_FLAG_SEARCH_TUNE_FINISHED | BCM2048_FM_FLAG_SEARCH_TUNE_FAIL)) { - if (flag_lsb & BCM2048_FM_FLAG_SEARCH_TUNE_FAIL) bdev->scan_state = BCM2048_SCAN_FAIL; else @@ -2165,7 +2158,6 @@ static int bcm2048_sysfs_register_properties(struct bcm2048_device *bdev) return err; } - static int bcm2048_fops_open(struct file *file) { struct bcm2048_device *bdev = video_drvdata(file); -- GitLab From cf2f34089f3e15959b12671c93cd7909e3b8cef0 Mon Sep 17 00:00:00 2001 From: Amarjargal Gundjalam Date: Sat, 31 Oct 2015 01:56:40 -0700 Subject: [PATCH 0137/2855] staging: media: bcm2048: remove unnecessary space after a cast This patch fixes the checkpatch issue: CHECK: No space is necessary after a cast Signed-off-by: Amarjargal Gundjalam Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/bcm2048/radio-bcm2048.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index 9a69d17c3eab4..82f4df40f166e 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -184,8 +184,8 @@ #define dev_to_v4l2(f) ((f * BCM2048_FREQDEV_UNIT) / BCM2048_FREQV4L2_MULTI) #define v4l2_to_dev(f) ((f * BCM2048_FREQV4L2_MULTI) / BCM2048_FREQDEV_UNIT) -#define msb(x) ((u8)((u16) x >> 8)) -#define lsb(x) ((u8)((u16) x & 0x00FF)) +#define msb(x) ((u8)((u16)x >> 8)) +#define lsb(x) ((u8)((u16)x & 0x00FF)) #define compose_u16(msb, lsb) (((u16)msb << 8) | lsb) #define BCM2048_DEFAULT_POWERING_DELAY 20 -- GitLab From 3066bc0587186dc8d14d72f04fc8aeeb7801787e Mon Sep 17 00:00:00 2001 From: Amarjargal Gundjalam Date: Sat, 31 Oct 2015 01:56:41 -0700 Subject: [PATCH 0138/2855] staging: media: bcm2048: fix mispelling This patch fixes the checkpatch issue: CHECK: 'Syncronize' may be misspelled - perhaps 'Synchronize'? Signed-off-by: Amarjargal Gundjalam Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/bcm2048/radio-bcm2048.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index 82f4df40f166e..19fcb1cb82314 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -1596,7 +1596,7 @@ static void bcm2048_parse_rds_rt(struct bcm2048_device *bdev) crc = bcm2048_rds_block_crc(bdev, i); if (crc == BCM2048_RDS_CRC_UNRECOVARABLE) continue; - /* Syncronize to a good RDS PI */ + /* Synchronize to a good RDS PI */ if (((bdev->rds_info.radio_text[i + 1] << 8) + bdev->rds_info.radio_text[i + 2]) == bdev->rds_info.rds_pi) @@ -1732,7 +1732,7 @@ static void bcm2048_parse_rds_ps(struct bcm2048_device *bdev) crc = bcm2048_rds_block_crc(bdev, i); if (crc == BCM2048_RDS_CRC_UNRECOVARABLE) continue; - /* Syncronize to a good RDS PI */ + /* Synchronize to a good RDS PI */ if (((bdev->rds_info.radio_text[i + 1] << 8) + bdev->rds_info.radio_text[i + 2]) == bdev->rds_info.rds_pi) -- GitLab From d48df5b37e8492adddd9d62000094f0f965a391a Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Sat, 31 Oct 2015 20:19:40 +0530 Subject: [PATCH 0139/2855] staging: rtl8712: rtl871x_mlme: Remove wrapper function Remove wrapper function free_network_nolock() that can be replaced by a single line of code. This patch renames _free_network_nolock() function to free_network_nolock(). Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_mlme.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index a4a002b551289..04f727fc95eae 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c @@ -123,7 +123,7 @@ static void _free_network(struct mlme_priv *pmlmepriv, spin_unlock_irqrestore(&free_queue->lock, irqL); } -static void _free_network_nolock(struct mlme_priv *pmlmepriv, +static void free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork) { struct __queue *free_queue = &pmlmepriv->free_bss_pool; @@ -234,12 +234,6 @@ static struct wlan_network *alloc_network(struct mlme_priv *pmlmepriv) return _r8712_alloc_network(pmlmepriv); } -static void free_network_nolock(struct mlme_priv *pmlmepriv, - struct wlan_network *pnetwork) -{ - _free_network_nolock(pmlmepriv, pnetwork); -} - void r8712_free_network_queue(struct _adapter *dev) { _free_network_queue(dev); -- GitLab From 10172144cc812f0f126587a919c328873e1594f2 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Sat, 31 Oct 2015 20:22:03 +0530 Subject: [PATCH 0140/2855] staging: rtl8192e: Remove unnecessary variable This patch removes unnecessary variable by using a single line of code instead. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c index 0b407feb54073..5e3bbe5c3ca49 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c @@ -90,13 +90,12 @@ void rtl92e_set_bb_reg(struct net_device *dev, u32 dwRegAddr, u32 dwBitMask, u32 rtl92e_get_bb_reg(struct net_device *dev, u32 dwRegAddr, u32 dwBitMask) { - u32 Ret = 0, OriginalValue, BitShift; + u32 OriginalValue, BitShift; OriginalValue = rtl92e_readl(dev, dwRegAddr); BitShift = _rtl92e_calculate_bit_shift(dwBitMask); - Ret = (OriginalValue & dwBitMask) >> BitShift; - return Ret; + return (OriginalValue & dwBitMask) >> BitShift; } static u32 _rtl92e_phy_rf_read(struct net_device *dev, -- GitLab From 8d831d451fd0654c8d20a91c4edec1ee57a93945 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Sun, 1 Nov 2015 11:34:40 +0530 Subject: [PATCH 0141/2855] Staging: fwserial: Remove unused fwtty_bind_console from header fwtty_bind_console is defined in header file but not used. Thus remove the definition. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fwserial/fwserial.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/staging/fwserial/fwserial.h b/drivers/staging/fwserial/fwserial.h index 787aa4f3a41b2..8d791ae79cd61 100644 --- a/drivers/staging/fwserial/fwserial.h +++ b/drivers/staging/fwserial/fwserial.h @@ -344,14 +344,6 @@ extern struct tty_driver *fwtty_driver; struct fwtty_port *fwtty_port_get(unsigned index); void fwtty_port_put(struct fwtty_port *port); -static inline void fwtty_bind_console(struct fwtty_port *port, - struct fwconsole_ops *fwcon_ops, - void *data) -{ - port->con_data = data; - port->fwcon_ops = fwcon_ops; -} - /* * Returns the max send async payload size in bytes based on the unit device * link speed. Self-limiting asynchronous bandwidth (via reducing the payload) -- GitLab From 375fb53ec1be6df6cfd0ac4932f14f0b7f57a761 Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Sun, 1 Nov 2015 16:38:20 +0200 Subject: [PATCH 0142/2855] staging: android: replace explicit NULL comparison This patch replaces explicit NULL comparison with ! operator in order to simplify the code Signed-off-by: Ioana Ciornei Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ion/compat_ion.c | 6 +++--- drivers/staging/android/sync.c | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/android/ion/compat_ion.c b/drivers/staging/android/ion/compat_ion.c index a402fdaf54ca3..9a978d21785ec 100644 --- a/drivers/staging/android/ion/compat_ion.c +++ b/drivers/staging/android/ion/compat_ion.c @@ -137,7 +137,7 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) data32 = compat_ptr(arg); data = compat_alloc_user_space(sizeof(*data)); - if (data == NULL) + if (!data) return -EFAULT; err = compat_get_ion_allocation_data(data32, data); @@ -156,7 +156,7 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) data32 = compat_ptr(arg); data = compat_alloc_user_space(sizeof(*data)); - if (data == NULL) + if (!data) return -EFAULT; err = compat_get_ion_handle_data(data32, data); @@ -173,7 +173,7 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) data32 = compat_ptr(arg); data = compat_alloc_user_space(sizeof(*data)); - if (data == NULL) + if (!data) return -EFAULT; err = compat_get_ion_custom_data(data32, data); diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index f83e00c780513..5413f28afe8e4 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -43,7 +43,7 @@ struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops, return NULL; obj = kzalloc(size, GFP_KERNEL); - if (obj == NULL) + if (!obj) return NULL; kref_init(&obj->kref); @@ -130,7 +130,7 @@ struct sync_pt *sync_pt_create(struct sync_timeline *obj, int size) return NULL; pt = kzalloc(size, GFP_KERNEL); - if (pt == NULL) + if (!pt) return NULL; spin_lock_irqsave(&obj->child_list_lock, flags); @@ -155,7 +155,7 @@ static struct sync_fence *sync_fence_alloc(int size, const char *name) struct sync_fence *fence; fence = kzalloc(size, GFP_KERNEL); - if (fence == NULL) + if (!fence) return NULL; fence->file = anon_inode_getfile("sync_fence", &sync_fence_fops, @@ -193,7 +193,7 @@ struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt) struct sync_fence *fence; fence = sync_fence_alloc(offsetof(struct sync_fence, cbs[1]), name); - if (fence == NULL) + if (!fence) return NULL; fence->num_fences = 1; @@ -215,7 +215,7 @@ struct sync_fence *sync_fence_fdget(int fd) { struct file *file = fget(fd); - if (file == NULL) + if (!file) return NULL; if (file->f_op != &sync_fence_fops) @@ -262,7 +262,7 @@ struct sync_fence *sync_fence_merge(const char *name, unsigned long size = offsetof(struct sync_fence, cbs[num_fences]); fence = sync_fence_alloc(size, name); - if (fence == NULL) + if (!fence) return NULL; atomic_set(&fence->status, num_fences); @@ -583,14 +583,14 @@ static long sync_fence_ioctl_merge(struct sync_fence *fence, unsigned long arg) } fence2 = sync_fence_fdget(data.fd2); - if (fence2 == NULL) { + if (!fence2) { err = -ENOENT; goto err_put_fd; } data.name[sizeof(data.name) - 1] = '\0'; fence3 = sync_fence_merge(data.name, fence, fence2); - if (fence3 == NULL) { + if (!fence3) { err = -ENOMEM; goto err_put_fence2; } @@ -666,7 +666,7 @@ static long sync_fence_ioctl_fence_info(struct sync_fence *fence, size = 4096; data = kzalloc(size, GFP_KERNEL); - if (data == NULL) + if (!data) return -ENOMEM; strlcpy(data->name, fence->name, sizeof(data->name)); -- GitLab From 36f16ff25c0290aa700dc0944f41dc14ff050432 Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Sun, 1 Nov 2015 16:38:21 +0200 Subject: [PATCH 0143/2855] staging: android: replace uint32_t with u32 This patch makes use of the preferred kernel types such as u16, u32. Signed-off-by: Ioana Ciornei Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/lowmemorykiller.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index e679d8432810b..de65db7d938f7 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -43,7 +43,7 @@ #include #include -static uint32_t lowmem_debug_level = 1; +static u32 lowmem_debug_level = 1; static short lowmem_adj[6] = { 0, 1, -- GitLab From f8b053e3da56cdfa798ce5d7014860798b04b7bc Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Sun, 1 Nov 2015 16:38:22 +0200 Subject: [PATCH 0144/2855] staging: android: properly align function arguments Fix alingment issues by properly indenting function arguments in accordance with the kernel coding style. Signed-off-by: Ioana Ciornei Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/lowmemorykiller.c | 4 ++-- drivers/staging/android/sync.c | 4 ++-- drivers/staging/android/timed_gpio.c | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index de65db7d938f7..8b5a4a82d8b87 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -105,8 +105,8 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) } lowmem_print(3, "lowmem_scan %lu, %x, ofree %d %d, ma %hd\n", - sc->nr_to_scan, sc->gfp_mask, other_free, - other_file, min_score_adj); + sc->nr_to_scan, sc->gfp_mask, other_free, + other_file, min_score_adj); if (min_score_adj == OOM_SCORE_ADJ_MAX + 1) { lowmem_print(5, "lowmem_scan %lu, %x, return 0\n", diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 5413f28afe8e4..e0c1acb2ba69c 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -313,7 +313,7 @@ struct sync_fence *sync_fence_merge(const char *name, EXPORT_SYMBOL(sync_fence_merge); int sync_fence_wake_up_wq(wait_queue_t *curr, unsigned mode, - int wake_flags, void *key) + int wake_flags, void *key) { struct sync_fence_waiter *wait; @@ -353,7 +353,7 @@ int sync_fence_wait_async(struct sync_fence *fence, EXPORT_SYMBOL(sync_fence_wait_async); int sync_fence_cancel_async(struct sync_fence *fence, - struct sync_fence_waiter *waiter) + struct sync_fence_waiter *waiter) { unsigned long flags; int ret = 0; diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c index ce11726f1a6c3..5246f42c12272 100644 --- a/drivers/staging/android/timed_gpio.c +++ b/drivers/staging/android/timed_gpio.c @@ -76,8 +76,8 @@ static void gpio_enable(struct timed_output_dev *dev, int value) value = data->max_timeout; hrtimer_start(&data->timer, - ktime_set(value / 1000, (value % 1000) * 1000000), - HRTIMER_MODE_REL); + ktime_set(value / 1000, (value % 1000) * 1000000), + HRTIMER_MODE_REL); } spin_unlock_irqrestore(&data->lock, flags); @@ -94,8 +94,8 @@ static int timed_gpio_probe(struct platform_device *pdev) return -EBUSY; gpio_data = devm_kzalloc(&pdev->dev, - sizeof(struct timed_gpio_data) * pdata->num_gpios, - GFP_KERNEL); + sizeof(*gpio_data) * pdata->num_gpios, + GFP_KERNEL); if (!gpio_data) return -ENOMEM; @@ -104,7 +104,7 @@ static int timed_gpio_probe(struct platform_device *pdev) gpio_dat = &gpio_data[i]; hrtimer_init(&gpio_dat->timer, CLOCK_MONOTONIC, - HRTIMER_MODE_REL); + HRTIMER_MODE_REL); gpio_dat->timer.function = gpio_timer_func; spin_lock_init(&gpio_dat->lock); -- GitLab From 49112c7fc2329a668d886f4410d9666328d8b2ef Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Sun, 1 Nov 2015 16:38:23 +0200 Subject: [PATCH 0145/2855] staging: android: remove multiple blank lines This patch removes multiple blank lines in order to follow the linux kernel coding style. Signed-off-by: Ioana Ciornei Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/timed_gpio.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c index 5246f42c12272..bcd9924d46312 100644 --- a/drivers/staging/android/timed_gpio.c +++ b/drivers/staging/android/timed_gpio.c @@ -25,7 +25,6 @@ #include "timed_output.h" #include "timed_gpio.h" - struct timed_gpio_data { struct timed_output_dev dev; struct hrtimer timer; -- GitLab From 5ec2136892cc01c802d10bb24c442951056e3af8 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Fri, 30 Oct 2015 12:18:56 +0530 Subject: [PATCH 0146/2855] staging: wilc1000: Remove inclusion of version.h version.h header inclusion is not necessary as detected by versioncheck. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 2a5b36fd8b480..034cfed653b02 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -23,7 +23,6 @@ #include #include -#include #include #ifdef WILC_SDIO -- GitLab From b60005a8ce169771fc7e7763c920cfe7f48eef93 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:24 +0900 Subject: [PATCH 0147/2855] staging: wilc1000: rename enuHostIFstate of struct host_if_drv This patch renames enuHostIFstate of struct host_if_drv to hif_state to avoid CamelCase naming convention. And, some comments modification that has been included name 'enuHostIFstate'. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 62 ++++++++++++----------- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index dbbe72c7e2557..4e01dbd492ed2 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -820,13 +820,15 @@ static s32 Handle_Scan(struct host_if_drv *hif_drv, u8 *pu8HdnNtwrksWidVal = NULL; PRINT_D(HOSTINF_DBG, "Setting SCAN params\n"); - PRINT_D(HOSTINF_DBG, "Scanning: In [%d] state\n", hif_drv->enuHostIFstate); + PRINT_D(HOSTINF_DBG, "Scanning: In [%d] state\n", hif_drv->hif_state); hif_drv->usr_scan_req.pfUserScanResult = pstrHostIFscanAttr->result; hif_drv->usr_scan_req.u32UserScanPvoid = pstrHostIFscanAttr->arg; - if ((hif_drv->enuHostIFstate >= HOST_IF_SCANNING) && (hif_drv->enuHostIFstate < HOST_IF_CONNECTED)) { - PRINT_D(GENERIC_DBG, "Don't scan we are already in [%d] state\n", hif_drv->enuHostIFstate); + if ((hif_drv->hif_state >= HOST_IF_SCANNING) && + (hif_drv->hif_state < HOST_IF_CONNECTED)) { + PRINT_D(GENERIC_DBG, "Don't scan already in [%d] state\n", + hif_drv->hif_state); PRINT_ER("Already scan\n"); result = -EBUSY; goto ERRORHANDLER; @@ -904,9 +906,9 @@ static s32 Handle_Scan(struct host_if_drv *hif_drv, strWIDList[u32WidsCount].val = (s8 *)&pstrHostIFscanAttr->src; u32WidsCount++; - if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED) + if (hif_drv->hif_state == HOST_IF_CONNECTED) scan_while_connected = true; - else if (hif_drv->enuHostIFstate == HOST_IF_IDLE) + else if (hif_drv->hif_state == HOST_IF_IDLE) scan_while_connected = false; result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount, @@ -1214,7 +1216,7 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv, goto ERRORHANDLER; } else { PRINT_D(GENERIC_DBG, "set HOST_IF_WAITING_CONN_RESP\n"); - hif_drv->enuHostIFstate = HOST_IF_WAITING_CONN_RESP; + hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP; } ERRORHANDLER: @@ -1244,7 +1246,7 @@ ERRORHANDLER: MAC_DISCONNECTED, NULL, pstrHostIFconnectAttr->arg); - hif_drv->enuHostIFstate = HOST_IF_IDLE; + hif_drv->hif_state = HOST_IF_IDLE; kfree(strConnectInfo.pu8ReqIEs); strConnectInfo.pu8ReqIEs = NULL; @@ -1325,7 +1327,7 @@ static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv) return result; } - hif_drv->enuHostIFstate = HOST_IF_IDLE; + hif_drv->hif_state = HOST_IF_IDLE; scan_while_connected = false; @@ -1491,11 +1493,11 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, PRINT_ER("Driver handler is NULL\n"); return -ENODEV; } - PRINT_D(GENERIC_DBG, "Current State = %d,Received state = %d\n", hif_drv->enuHostIFstate, - pstrRcvdGnrlAsyncInfo->buffer[7]); + PRINT_D(GENERIC_DBG, "Current State = %d,Received state = %d\n", + hif_drv->hif_state, pstrRcvdGnrlAsyncInfo->buffer[7]); - if ((hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) || - (hif_drv->enuHostIFstate == HOST_IF_CONNECTED) || + if ((hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) || + (hif_drv->hif_state == HOST_IF_CONNECTED) || hif_drv->usr_scan_req.pfUserScanResult) { if (!pstrRcvdGnrlAsyncInfo->buffer || !hif_drv->usr_conn_req.pfUserConnectResult) { @@ -1518,7 +1520,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, u8MacStatusReasonCode = pstrRcvdGnrlAsyncInfo->buffer[8]; u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->buffer[9]; PRINT_INFO(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Info = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo); - if (hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) { + if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) { u32 u32RcvdAssocRespInfoLen; tstrConnectRespInfo *pstrConnectRespInfo = NULL; @@ -1604,7 +1606,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, host_int_set_power_mgmt(hif_drv, 0, 0); PRINT_D(HOSTINF_DBG, "MAC status : CONNECTED and Connect Status : Successful\n"); - hif_drv->enuHostIFstate = HOST_IF_CONNECTED; + hif_drv->hif_state = HOST_IF_CONNECTED; PRINT_D(GENERIC_DBG, "Obtaining an IP, Disable Scan\n"); g_obtainingIP = true; @@ -1612,7 +1614,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, jiffies + msecs_to_jiffies(10000)); } else { PRINT_D(HOSTINF_DBG, "MAC status : %d and Connect Status : %d\n", u8MacStatus, strConnectInfo.u16ConnectStatus); - hif_drv->enuHostIFstate = HOST_IF_IDLE; + hif_drv->hif_state = HOST_IF_IDLE; scan_while_connected = false; } @@ -1627,7 +1629,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, hif_drv->usr_conn_req.ConnReqIEsLen = 0; kfree(hif_drv->usr_conn_req.pu8ConnReqIEs); } else if ((u8MacStatus == MAC_DISCONNECTED) && - (hif_drv->enuHostIFstate == HOST_IF_CONNECTED)) { + (hif_drv->hif_state == HOST_IF_CONNECTED)) { PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW\n"); memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo)); @@ -1673,7 +1675,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, info_element = NULL; } - hif_drv->enuHostIFstate = HOST_IF_IDLE; + hif_drv->hif_state = HOST_IF_IDLE; scan_while_connected = false; } else if ((u8MacStatus == MAC_DISCONNECTED) && @@ -1837,10 +1839,10 @@ static int Handle_Key(struct host_if_drv *hif_drv, goto _WPARxGtk_end_case_; } - if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED) + if (hif_drv->hif_state == HOST_IF_CONNECTED) memcpy(pu8keybuf, hif_drv->au8AssociatedBSSID, ETH_ALEN); else - PRINT_ER("Couldn't handle WPARxGtk while enuHostIFstate is not HOST_IF_CONNECTED\n"); + PRINT_ER("Couldn't handle WPARxGtk while state is not HOST_IF_CONNECTED\n"); memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8); memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1); @@ -2005,7 +2007,7 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) } if (hif_drv->usr_conn_req.pfUserConnectResult) { - if (hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) { + if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) { PRINT_D(HOSTINF_DBG, "Upper layer requested termination of connection\n"); del_timer(&hif_drv->hConnectTimer); } @@ -2018,7 +2020,7 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) scan_while_connected = false; - hif_drv->enuHostIFstate = HOST_IF_IDLE; + hif_drv->hif_state = HOST_IF_IDLE; eth_zero_addr(hif_drv->au8AssociatedBSSID); @@ -2046,7 +2048,8 @@ void resolve_disconnect_aberration(struct host_if_drv *hif_drv) { if (!hif_drv) return; - if ((hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) || (hif_drv->enuHostIFstate == HOST_IF_CONNECTING)) { + if ((hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) || + (hif_drv->hif_state == HOST_IF_CONNECTING)) { PRINT_D(HOSTINF_DBG, "\n\n<< correcting Supplicant state machine >>\n\n"); host_int_disconnect(hif_drv, 1); } @@ -2492,7 +2495,7 @@ static int Handle_RemainOnChan(struct host_if_drv *hif_drv, result = -EBUSY; goto ERRORHANDLER; } - if (hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) { + if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) { PRINT_INFO(GENERIC_DBG, "Required to remain on chan while connecting return\n"); result = -EBUSY; goto ERRORHANDLER; @@ -3497,10 +3500,11 @@ s32 host_int_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid, msg.body.con_info.ies = kmalloc(IEsLen, GFP_KERNEL); memcpy(msg.body.con_info.ies, pu8IEs, IEsLen); } - if (hif_drv->enuHostIFstate < HOST_IF_CONNECTING) - hif_drv->enuHostIFstate = HOST_IF_CONNECTING; + if (hif_drv->hif_state < HOST_IF_CONNECTING) + hif_drv->hif_state = HOST_IF_CONNECTING; else - PRINT_D(GENERIC_DBG, "Don't set state to 'connecting' as state is %d\n", hif_drv->enuHostIFstate); + PRINT_D(GENERIC_DBG, "Don't set state to 'connecting' : %d\n", + hif_drv->hif_state); result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) { @@ -4046,7 +4050,7 @@ static void GetPeriodicRSSI(unsigned long arg) return; } - if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED) { + if (hif_drv->hif_state == HOST_IF_CONNECTED) { s32 result = 0; struct host_if_msg msg; @@ -4142,7 +4146,7 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) sema_init(&hif_drv->gtOsCfgValuesSem, 1); down(&hif_drv->gtOsCfgValuesSem); - hif_drv->enuHostIFstate = HOST_IF_IDLE; + hif_drv->hif_state = HOST_IF_IDLE; hif_drv->strCfgValues.site_survey_enabled = SITE_SURVEY_OFF; hif_drv->strCfgValues.scan_source = DEFAULT_SCAN; hif_drv->strCfgValues.active_scan_time = ACTIVE_SCAN_TIME; @@ -4211,7 +4215,7 @@ s32 host_int_deinit(struct host_if_drv *hif_drv) hif_drv->usr_scan_req.pfUserScanResult = NULL; } - hif_drv->enuHostIFstate = HOST_IF_IDLE; + hif_drv->hif_state = HOST_IF_IDLE; scan_while_connected = false; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index b854db5ac932c..dcdb9c61b82c6 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -299,7 +299,7 @@ struct host_if_drv { u64 u64P2p_MgmtTimeout; u8 u8P2PConnect; - enum host_if_state enuHostIFstate; + enum host_if_state hif_state; u8 au8AssociatedBSSID[ETH_ALEN]; struct cfg_param_val strCfgValues; -- GitLab From 2a4eded9a827038dfdf322450f64ba4352a2b5ce Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:25 +0900 Subject: [PATCH 0148/2855] staging: wilc1000: rename au8AssociatedBSSID of struct host_if_drv This patch renames au8AssociatedBSSID of struct host_if_drv to assoc_bssid to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 8 ++++---- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 4e01dbd492ed2..7216d83bc3e19 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1581,7 +1581,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, if ((u8MacStatus == MAC_CONNECTED) && (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) { - memcpy(hif_drv->au8AssociatedBSSID, + memcpy(hif_drv->assoc_bssid, hif_drv->usr_conn_req.pu8bssid, ETH_ALEN); } } @@ -1657,7 +1657,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, PRINT_ER("Connect result callback function is NULL\n"); } - eth_zero_addr(hif_drv->au8AssociatedBSSID); + eth_zero_addr(hif_drv->assoc_bssid); hif_drv->usr_conn_req.ssidLen = 0; kfree(hif_drv->usr_conn_req.pu8ssid); @@ -1840,7 +1840,7 @@ static int Handle_Key(struct host_if_drv *hif_drv, } if (hif_drv->hif_state == HOST_IF_CONNECTED) - memcpy(pu8keybuf, hif_drv->au8AssociatedBSSID, ETH_ALEN); + memcpy(pu8keybuf, hif_drv->assoc_bssid, ETH_ALEN); else PRINT_ER("Couldn't handle WPARxGtk while state is not HOST_IF_CONNECTED\n"); @@ -2022,7 +2022,7 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) hif_drv->hif_state = HOST_IF_IDLE; - eth_zero_addr(hif_drv->au8AssociatedBSSID); + eth_zero_addr(hif_drv->assoc_bssid); hif_drv->usr_conn_req.ssidLen = 0; kfree(hif_drv->usr_conn_req.pu8ssid); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index dcdb9c61b82c6..fcfdd2151c9fc 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -301,7 +301,7 @@ struct host_if_drv { enum host_if_state hif_state; - u8 au8AssociatedBSSID[ETH_ALEN]; + u8 assoc_bssid[ETH_ALEN]; struct cfg_param_val strCfgValues; /* semaphores */ struct semaphore gtOsCfgValuesSem; -- GitLab From ace303f045939f7848acb3cb2f64509ab9d05a49 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:26 +0900 Subject: [PATCH 0149/2855] staging: wilc1000: rename strCfgValues of struct host_if_drv This patch renames strCfgValues of struct host_if_drv to cfg_values to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 91 ++++++++++++----------- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 47 insertions(+), 46 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 7216d83bc3e19..135d4b31d3e0e 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -535,7 +535,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.bss_type; strWIDList[u8WidCnt].type = WID_CHAR; strWIDList[u8WidCnt].size = sizeof(char); - hif_drv->strCfgValues.bss_type = (u8)strHostIFCfgParamAttr->cfg_attr_info.bss_type; + hif_drv->cfg_values.bss_type = (u8)strHostIFCfgParamAttr->cfg_attr_info.bss_type; } else { PRINT_ER("check value 6 over\n"); result = -EINVAL; @@ -549,7 +549,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.auth_type; strWIDList[u8WidCnt].type = WID_CHAR; strWIDList[u8WidCnt].size = sizeof(char); - hif_drv->strCfgValues.auth_type = (u8)strHostIFCfgParamAttr->cfg_attr_info.auth_type; + hif_drv->cfg_values.auth_type = (u8)strHostIFCfgParamAttr->cfg_attr_info.auth_type; } else { PRINT_ER("Impossible value \n"); result = -EINVAL; @@ -563,7 +563,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.auth_timeout; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->strCfgValues.auth_timeout = strHostIFCfgParamAttr->cfg_attr_info.auth_timeout; + hif_drv->cfg_values.auth_timeout = strHostIFCfgParamAttr->cfg_attr_info.auth_timeout; } else { PRINT_ER("Range(1 ~ 65535) over\n"); result = -EINVAL; @@ -577,7 +577,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.power_mgmt_mode; strWIDList[u8WidCnt].type = WID_CHAR; strWIDList[u8WidCnt].size = sizeof(char); - hif_drv->strCfgValues.power_mgmt_mode = (u8)strHostIFCfgParamAttr->cfg_attr_info.power_mgmt_mode; + hif_drv->cfg_values.power_mgmt_mode = (u8)strHostIFCfgParamAttr->cfg_attr_info.power_mgmt_mode; } else { PRINT_ER("Invalide power mode\n"); result = -EINVAL; @@ -591,7 +591,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->strCfgValues.short_retry_limit = strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit; + hif_drv->cfg_values.short_retry_limit = strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit; } else { PRINT_ER("Range(1~256) over\n"); result = -EINVAL; @@ -606,7 +606,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->strCfgValues.long_retry_limit = strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit; + hif_drv->cfg_values.long_retry_limit = strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit; } else { PRINT_ER("Range(1~256) over\n"); result = -EINVAL; @@ -620,7 +620,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.frag_threshold; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->strCfgValues.frag_threshold = strHostIFCfgParamAttr->cfg_attr_info.frag_threshold; + hif_drv->cfg_values.frag_threshold = strHostIFCfgParamAttr->cfg_attr_info.frag_threshold; } else { PRINT_ER("Threshold Range fail\n"); result = -EINVAL; @@ -634,7 +634,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.rts_threshold; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->strCfgValues.rts_threshold = strHostIFCfgParamAttr->cfg_attr_info.rts_threshold; + hif_drv->cfg_values.rts_threshold = strHostIFCfgParamAttr->cfg_attr_info.rts_threshold; } else { PRINT_ER("Threshold Range fail\n"); result = -EINVAL; @@ -648,7 +648,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.preamble_type; strWIDList[u8WidCnt].type = WID_CHAR; strWIDList[u8WidCnt].size = sizeof(char); - hif_drv->strCfgValues.preamble_type = strHostIFCfgParamAttr->cfg_attr_info.preamble_type; + hif_drv->cfg_values.preamble_type = strHostIFCfgParamAttr->cfg_attr_info.preamble_type; } else { PRINT_ER("Preamle Range(0~2) over\n"); result = -EINVAL; @@ -662,7 +662,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.short_slot_allowed; strWIDList[u8WidCnt].type = WID_CHAR; strWIDList[u8WidCnt].size = sizeof(char); - hif_drv->strCfgValues.short_slot_allowed = (u8)strHostIFCfgParamAttr->cfg_attr_info.short_slot_allowed; + hif_drv->cfg_values.short_slot_allowed = (u8)strHostIFCfgParamAttr->cfg_attr_info.short_slot_allowed; } else { PRINT_ER("Short slot(2) over\n"); result = -EINVAL; @@ -676,7 +676,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.txop_prot_disabled; strWIDList[u8WidCnt].type = WID_CHAR; strWIDList[u8WidCnt].size = sizeof(char); - hif_drv->strCfgValues.txop_prot_disabled = (u8)strHostIFCfgParamAttr->cfg_attr_info.txop_prot_disabled; + hif_drv->cfg_values.txop_prot_disabled = (u8)strHostIFCfgParamAttr->cfg_attr_info.txop_prot_disabled; } else { PRINT_ER("TXOP prot disable\n"); result = -EINVAL; @@ -690,7 +690,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.beacon_interval; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->strCfgValues.beacon_interval = strHostIFCfgParamAttr->cfg_attr_info.beacon_interval; + hif_drv->cfg_values.beacon_interval = strHostIFCfgParamAttr->cfg_attr_info.beacon_interval; } else { PRINT_ER("Beacon interval(1~65535) fail\n"); result = -EINVAL; @@ -704,7 +704,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.dtim_period; strWIDList[u8WidCnt].type = WID_CHAR; strWIDList[u8WidCnt].size = sizeof(char); - hif_drv->strCfgValues.dtim_period = strHostIFCfgParamAttr->cfg_attr_info.dtim_period; + hif_drv->cfg_values.dtim_period = strHostIFCfgParamAttr->cfg_attr_info.dtim_period; } else { PRINT_ER("DTIM range(1~255) fail\n"); result = -EINVAL; @@ -718,7 +718,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.site_survey_enabled; strWIDList[u8WidCnt].type = WID_CHAR; strWIDList[u8WidCnt].size = sizeof(char); - hif_drv->strCfgValues.site_survey_enabled = (u8)strHostIFCfgParamAttr->cfg_attr_info.site_survey_enabled; + hif_drv->cfg_values.site_survey_enabled = (u8)strHostIFCfgParamAttr->cfg_attr_info.site_survey_enabled; } else { PRINT_ER("Site survey disable\n"); result = -EINVAL; @@ -732,7 +732,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->strCfgValues.site_survey_scan_time = strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time; + hif_drv->cfg_values.site_survey_scan_time = strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time; } else { PRINT_ER("Site survey scan time(1~65535) over\n"); result = -EINVAL; @@ -746,7 +746,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.active_scan_time; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->strCfgValues.active_scan_time = strHostIFCfgParamAttr->cfg_attr_info.active_scan_time; + hif_drv->cfg_values.active_scan_time = strHostIFCfgParamAttr->cfg_attr_info.active_scan_time; } else { PRINT_ER("Active scan time(1~65535) over\n"); result = -EINVAL; @@ -760,7 +760,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->strCfgValues.passive_scan_time = strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time; + hif_drv->cfg_values.passive_scan_time = strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time; } else { PRINT_ER("Passive scan time(1~65535) over\n"); result = -EINVAL; @@ -781,7 +781,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, strWIDList[u8WidCnt].val = (s8 *)&curr_tx_rate; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->strCfgValues.curr_tx_rate = (u8)curr_tx_rate; + hif_drv->cfg_values.curr_tx_rate = (u8)curr_tx_rate; } else { PRINT_ER("out of TX rate\n"); result = -EINVAL; @@ -3961,75 +3961,75 @@ s32 hif_get_cfg(struct host_if_drv *hif_drv, u16 u16WID, u16 *pu16WID_Value) PRINT_D(HOSTINF_DBG, "Getting configuration parameters\n"); switch (u16WID) { case WID_BSS_TYPE: - *pu16WID_Value = (u16)hif_drv->strCfgValues.bss_type; + *pu16WID_Value = (u16)hif_drv->cfg_values.bss_type; break; case WID_AUTH_TYPE: - *pu16WID_Value = (u16)hif_drv->strCfgValues.auth_type; + *pu16WID_Value = (u16)hif_drv->cfg_values.auth_type; break; case WID_AUTH_TIMEOUT: - *pu16WID_Value = hif_drv->strCfgValues.auth_timeout; + *pu16WID_Value = hif_drv->cfg_values.auth_timeout; break; case WID_POWER_MANAGEMENT: - *pu16WID_Value = (u16)hif_drv->strCfgValues.power_mgmt_mode; + *pu16WID_Value = (u16)hif_drv->cfg_values.power_mgmt_mode; break; case WID_SHORT_RETRY_LIMIT: - *pu16WID_Value = hif_drv->strCfgValues.short_retry_limit; + *pu16WID_Value = hif_drv->cfg_values.short_retry_limit; break; case WID_LONG_RETRY_LIMIT: - *pu16WID_Value = hif_drv->strCfgValues.long_retry_limit; + *pu16WID_Value = hif_drv->cfg_values.long_retry_limit; break; case WID_FRAG_THRESHOLD: - *pu16WID_Value = hif_drv->strCfgValues.frag_threshold; + *pu16WID_Value = hif_drv->cfg_values.frag_threshold; break; case WID_RTS_THRESHOLD: - *pu16WID_Value = hif_drv->strCfgValues.rts_threshold; + *pu16WID_Value = hif_drv->cfg_values.rts_threshold; break; case WID_PREAMBLE: - *pu16WID_Value = (u16)hif_drv->strCfgValues.preamble_type; + *pu16WID_Value = (u16)hif_drv->cfg_values.preamble_type; break; case WID_SHORT_SLOT_ALLOWED: - *pu16WID_Value = (u16) hif_drv->strCfgValues.short_slot_allowed; + *pu16WID_Value = (u16)hif_drv->cfg_values.short_slot_allowed; break; case WID_11N_TXOP_PROT_DISABLE: - *pu16WID_Value = (u16)hif_drv->strCfgValues.txop_prot_disabled; + *pu16WID_Value = (u16)hif_drv->cfg_values.txop_prot_disabled; break; case WID_BEACON_INTERVAL: - *pu16WID_Value = hif_drv->strCfgValues.beacon_interval; + *pu16WID_Value = hif_drv->cfg_values.beacon_interval; break; case WID_DTIM_PERIOD: - *pu16WID_Value = (u16)hif_drv->strCfgValues.dtim_period; + *pu16WID_Value = (u16)hif_drv->cfg_values.dtim_period; break; case WID_SITE_SURVEY: - *pu16WID_Value = (u16)hif_drv->strCfgValues.site_survey_enabled; + *pu16WID_Value = (u16)hif_drv->cfg_values.site_survey_enabled; break; case WID_SITE_SURVEY_SCAN_TIME: - *pu16WID_Value = hif_drv->strCfgValues.site_survey_scan_time; + *pu16WID_Value = hif_drv->cfg_values.site_survey_scan_time; break; case WID_ACTIVE_SCAN_TIME: - *pu16WID_Value = hif_drv->strCfgValues.active_scan_time; + *pu16WID_Value = hif_drv->cfg_values.active_scan_time; break; case WID_PASSIVE_SCAN_TIME: - *pu16WID_Value = hif_drv->strCfgValues.passive_scan_time; + *pu16WID_Value = hif_drv->cfg_values.passive_scan_time; break; case WID_CURRENT_TX_RATE: - *pu16WID_Value = hif_drv->strCfgValues.curr_tx_rate; + *pu16WID_Value = hif_drv->cfg_values.curr_tx_rate; break; default: @@ -4147,19 +4147,20 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) down(&hif_drv->gtOsCfgValuesSem); hif_drv->hif_state = HOST_IF_IDLE; - hif_drv->strCfgValues.site_survey_enabled = SITE_SURVEY_OFF; - hif_drv->strCfgValues.scan_source = DEFAULT_SCAN; - hif_drv->strCfgValues.active_scan_time = ACTIVE_SCAN_TIME; - hif_drv->strCfgValues.passive_scan_time = PASSIVE_SCAN_TIME; - hif_drv->strCfgValues.curr_tx_rate = AUTORATE; + hif_drv->cfg_values.site_survey_enabled = SITE_SURVEY_OFF; + hif_drv->cfg_values.scan_source = DEFAULT_SCAN; + hif_drv->cfg_values.active_scan_time = ACTIVE_SCAN_TIME; + hif_drv->cfg_values.passive_scan_time = PASSIVE_SCAN_TIME; + hif_drv->cfg_values.curr_tx_rate = AUTORATE; hif_drv->u64P2p_MgmtTimeout = 0; PRINT_INFO(HOSTINF_DBG, "Initialization values, Site survey value: %d\n Scan source: %d\n Active scan time: %d\n Passive scan time: %d\nCurrent tx Rate = %d\n", - - hif_drv->strCfgValues.site_survey_enabled, hif_drv->strCfgValues.scan_source, - hif_drv->strCfgValues.active_scan_time, hif_drv->strCfgValues.passive_scan_time, - hif_drv->strCfgValues.curr_tx_rate); + hif_drv->cfg_values.site_survey_enabled, + hif_drv->cfg_values.scan_source, + hif_drv->cfg_values.active_scan_time, + hif_drv->cfg_values.passive_scan_time, + hif_drv->cfg_values.curr_tx_rate); up(&hif_drv->gtOsCfgValuesSem); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index fcfdd2151c9fc..90e2946b7c723 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -302,7 +302,7 @@ struct host_if_drv { enum host_if_state hif_state; u8 assoc_bssid[ETH_ALEN]; - struct cfg_param_val strCfgValues; + struct cfg_param_val cfg_values; /* semaphores */ struct semaphore gtOsCfgValuesSem; struct semaphore hSemTestKeyBlock; -- GitLab From 33110ad7d60506d215a57c13be5ed5607c5b155b Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:27 +0900 Subject: [PATCH 0150/2855] staging: wilc1000: rename gtOsCfgValuesSem of struct host_if_drv This patch renames gtOsCfgValuesSem of struct host_if_drv to sem_cfg_values to avoid CamelCase naming convention. And, remove the relation comment. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 18 +++++++++--------- drivers/staging/wilc1000/host_interface.h | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 135d4b31d3e0e..c6a08d2bfe317 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -525,7 +525,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, struct wid strWIDList[32]; u8 u8WidCnt = 0; - down(&hif_drv->gtOsCfgValuesSem); + down(&hif_drv->sem_cfg_values); PRINT_D(HOSTINF_DBG, "Setting CFG params\n"); @@ -797,7 +797,7 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, PRINT_ER("Error in setting CFG params\n"); ERRORHANDLER: - up(&hif_drv->gtOsCfgValuesSem); + up(&hif_drv->sem_cfg_values); return result; } @@ -3952,7 +3952,7 @@ s32 hif_get_cfg(struct host_if_drv *hif_drv, u16 u16WID, u16 *pu16WID_Value) { s32 result = 0; - down(&hif_drv->gtOsCfgValuesSem); + down(&hif_drv->sem_cfg_values); if (!hif_drv) { PRINT_ER("hif_drv NULL\n"); @@ -4036,7 +4036,7 @@ s32 hif_get_cfg(struct host_if_drv *hif_drv, u16 u16WID, u16 *pu16WID_Value) break; } - up(&hif_drv->gtOsCfgValuesSem); + up(&hif_drv->sem_cfg_values); return result; } @@ -4143,8 +4143,8 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) setup_timer(&hif_drv->hRemainOnChannel, ListenTimerCB, 0); - sema_init(&hif_drv->gtOsCfgValuesSem, 1); - down(&hif_drv->gtOsCfgValuesSem); + sema_init(&hif_drv->sem_cfg_values, 1); + down(&hif_drv->sem_cfg_values); hif_drv->hif_state = HOST_IF_IDLE; hif_drv->cfg_values.site_survey_enabled = SITE_SURVEY_OFF; @@ -4162,14 +4162,14 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) hif_drv->cfg_values.passive_scan_time, hif_drv->cfg_values.curr_tx_rate); - up(&hif_drv->gtOsCfgValuesSem); + up(&hif_drv->sem_cfg_values); clients_count++; return result; _fail_timer_2: - up(&hif_drv->gtOsCfgValuesSem); + up(&hif_drv->sem_cfg_values); del_timer_sync(&hif_drv->hConnectTimer); del_timer_sync(&hif_drv->hScanTimer); kthread_stop(hif_thread_handler); @@ -4238,7 +4238,7 @@ s32 host_int_deinit(struct host_if_drv *hif_drv) wilc_mq_destroy(&hif_msg_q); } - down(&hif_drv->gtOsCfgValuesSem); + down(&hif_drv->sem_cfg_values); ret = remove_handler_in_list(hif_drv); if (ret) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 90e2946b7c723..7b9930ebaa425 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -303,8 +303,8 @@ struct host_if_drv { u8 assoc_bssid[ETH_ALEN]; struct cfg_param_val cfg_values; -/* semaphores */ - struct semaphore gtOsCfgValuesSem; + + struct semaphore sem_cfg_values; struct semaphore hSemTestKeyBlock; struct semaphore hSemTestDisconnectBlock; -- GitLab From 9ea47133ecf0fa9622aa815835f791031566d229 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:28 +0900 Subject: [PATCH 0151/2855] staging: wilc1000: rename hSemTestKeyBlock of struct host_if_drv This patch renames hSemTestKeyBlock of struct host_if_drv to sem_test_key_block to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 24 +++++++++++------------ drivers/staging/wilc1000/host_interface.h | 3 +-- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index c6a08d2bfe317..99bf633b73dc3 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1792,7 +1792,7 @@ static int Handle_Key(struct host_if_drv *hif_drv, result = send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); } - up(&hif_drv->hSemTestKeyBlock); + up(&hif_drv->sem_test_key_block); break; case WPARxGtk: @@ -1826,7 +1826,7 @@ static int Handle_Key(struct host_if_drv *hif_drv, get_id_from_handler(hif_drv)); kfree(pu8keybuf); - up(&hif_drv->hSemTestKeyBlock); + up(&hif_drv->sem_test_key_block); } if (pstrHostIFkeyAttr->action & ADDKEY) { @@ -1859,7 +1859,7 @@ static int Handle_Key(struct host_if_drv *hif_drv, get_id_from_handler(hif_drv)); kfree(pu8keybuf); - up(&hif_drv->hSemTestKeyBlock); + up(&hif_drv->sem_test_key_block); } _WPARxGtk_end_case_: kfree(pstrHostIFkeyAttr->attr.wpa.key); @@ -1897,7 +1897,7 @@ _WPARxGtk_end_case_: result = send_config_pkt(SET_CFG, strWIDList, 2, get_id_from_handler(hif_drv)); kfree(pu8keybuf); - up(&hif_drv->hSemTestKeyBlock); + up(&hif_drv->sem_test_key_block); } if (pstrHostIFkeyAttr->action & ADDKEY) { pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL); @@ -1920,7 +1920,7 @@ _WPARxGtk_end_case_: result = send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); kfree(pu8keybuf); - up(&hif_drv->hSemTestKeyBlock); + up(&hif_drv->sem_test_key_block); } _WPAPtk_end_case_: @@ -3076,7 +3076,7 @@ int host_int_remove_wep_key(struct host_if_drv *hif_drv, u8 index) result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) PRINT_ER("Error in sending message queue : Request to remove WEP key\n"); - down(&hif_drv->hSemTestKeyBlock); + down(&hif_drv->sem_test_key_block); return result; } @@ -3103,7 +3103,7 @@ int host_int_set_wep_default_key(struct host_if_drv *hif_drv, u8 index) result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) PRINT_ER("Error in sending message queue : Default key index\n"); - down(&hif_drv->hSemTestKeyBlock); + down(&hif_drv->sem_test_key_block); return result; } @@ -3137,7 +3137,7 @@ int host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv, result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) PRINT_ER("Error in sending message queue :WEP Key\n"); - down(&hif_drv->hSemTestKeyBlock); + down(&hif_drv->sem_test_key_block); return result; } @@ -3181,7 +3181,7 @@ int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, if (result) PRINT_ER("Error in sending message queue :WEP Key\n"); - down(&hif_drv->hSemTestKeyBlock); + down(&hif_drv->sem_test_key_block); return result; } @@ -3246,7 +3246,7 @@ s32 host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk, if (result) PRINT_ER("Error in sending message queue: PTK Key\n"); - down(&hif_drv->hSemTestKeyBlock); + down(&hif_drv->sem_test_key_block); return result; } @@ -3308,7 +3308,7 @@ s32 host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk, if (result) PRINT_ER("Error in sending message queue: RX GTK\n"); - down(&hif_drv->hSemTestKeyBlock); + down(&hif_drv->sem_test_key_block); return result; } @@ -4107,7 +4107,7 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) sema_init(&hif_sema_deinit, 1); } - sema_init(&hif_drv->hSemTestKeyBlock, 0); + sema_init(&hif_drv->sem_test_key_block, 0); sema_init(&hif_drv->hSemTestDisconnectBlock, 0); sema_init(&hif_drv->hSemGetRSSI, 0); sema_init(&hif_drv->hSemGetLINKSPEED, 0); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 7b9930ebaa425..a8fd290f8eb33 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -305,8 +305,7 @@ struct host_if_drv { struct cfg_param_val cfg_values; struct semaphore sem_cfg_values; - struct semaphore hSemTestKeyBlock; - + struct semaphore sem_test_key_block; struct semaphore hSemTestDisconnectBlock; struct semaphore hSemGetRSSI; struct semaphore hSemGetLINKSPEED; -- GitLab From e55e49670b673d7ab9f7fb51d3530347f327fd40 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:29 +0900 Subject: [PATCH 0152/2855] staging: wilc1000: rename hSemTestDisconnectBlock of struct host_if_drv This patch renames hSemTestDisconnectBlock of struct host_if_drv to sem_test_disconn_block to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 +++--- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 99bf633b73dc3..4daef636ecbc3 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2041,7 +2041,7 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) } } - up(&hif_drv->hSemTestDisconnectBlock); + up(&hif_drv->sem_test_disconn_block); } void resolve_disconnect_aberration(struct host_if_drv *hif_drv) @@ -3563,7 +3563,7 @@ s32 host_int_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode) if (result) PRINT_ER("Failed to send message queue: disconnect\n"); - down(&hif_drv->hSemTestDisconnectBlock); + down(&hif_drv->sem_test_disconn_block); return result; } @@ -4108,7 +4108,7 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) } sema_init(&hif_drv->sem_test_key_block, 0); - sema_init(&hif_drv->hSemTestDisconnectBlock, 0); + sema_init(&hif_drv->sem_test_disconn_block, 0); sema_init(&hif_drv->hSemGetRSSI, 0); sema_init(&hif_drv->hSemGetLINKSPEED, 0); sema_init(&hif_drv->hSemGetCHNL, 0); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index a8fd290f8eb33..0c7a773896132 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -306,7 +306,7 @@ struct host_if_drv { struct semaphore sem_cfg_values; struct semaphore sem_test_key_block; - struct semaphore hSemTestDisconnectBlock; + struct semaphore sem_test_disconn_block; struct semaphore hSemGetRSSI; struct semaphore hSemGetLINKSPEED; struct semaphore hSemGetCHNL; -- GitLab From 7e111f9ea92386c7ec90efe7b62363da272beb1c Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:30 +0900 Subject: [PATCH 0153/2855] staging: wilc1000: rename hSemGetRSSI of struct host_if_drv This patch renames hSemGetRSSI of struct host_if_drv to sem_get_rssi to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 +++--- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 4daef636ecbc3..b40ce3bc46d3b 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2099,7 +2099,7 @@ static void Handle_GetRssi(struct host_if_drv *hif_drv) result = -EFAULT; } - up(&hif_drv->hSemGetRSSI); + up(&hif_drv->sem_get_rssi); } static void Handle_GetLinkspeed(struct host_if_drv *hif_drv) @@ -3815,7 +3815,7 @@ s32 host_int_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi) return -EFAULT; } - down(&hif_drv->hSemGetRSSI); + down(&hif_drv->sem_get_rssi); if (!ps8Rssi) { PRINT_ER("RSS pointer value is null"); @@ -4109,7 +4109,7 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) sema_init(&hif_drv->sem_test_key_block, 0); sema_init(&hif_drv->sem_test_disconn_block, 0); - sema_init(&hif_drv->hSemGetRSSI, 0); + sema_init(&hif_drv->sem_get_rssi, 0); sema_init(&hif_drv->hSemGetLINKSPEED, 0); sema_init(&hif_drv->hSemGetCHNL, 0); sema_init(&hif_drv->hSemInactiveTime, 0); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 0c7a773896132..dada9c57af4fa 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -307,7 +307,7 @@ struct host_if_drv { struct semaphore sem_cfg_values; struct semaphore sem_test_key_block; struct semaphore sem_test_disconn_block; - struct semaphore hSemGetRSSI; + struct semaphore sem_get_rssi; struct semaphore hSemGetLINKSPEED; struct semaphore hSemGetCHNL; struct semaphore hSemInactiveTime; -- GitLab From bc34da66057062636fb6c6d339ed8f0856c6d6c0 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:31 +0900 Subject: [PATCH 0154/2855] staging: wilc1000: rename hSemGetLINKSPEED of struct host_if_drv This patch renames hSemGetLINKSPEED of struct host_if_drv to sem_get_link_speed to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 +++--- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index b40ce3bc46d3b..7b654c5022b51 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2123,7 +2123,7 @@ static void Handle_GetLinkspeed(struct host_if_drv *hif_drv) result = -EFAULT; } - up(&hif_drv->hSemGetLINKSPEED); + up(&hif_drv->sem_get_link_speed); } s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics) @@ -3842,7 +3842,7 @@ s32 host_int_get_link_speed(struct host_if_drv *hif_drv, s8 *ps8lnkspd) return -EFAULT; } - down(&hif_drv->hSemGetLINKSPEED); + down(&hif_drv->sem_get_link_speed); if (!ps8lnkspd) { PRINT_ER("LINKSPEED pointer value is null"); @@ -4110,7 +4110,7 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) sema_init(&hif_drv->sem_test_key_block, 0); sema_init(&hif_drv->sem_test_disconn_block, 0); sema_init(&hif_drv->sem_get_rssi, 0); - sema_init(&hif_drv->hSemGetLINKSPEED, 0); + sema_init(&hif_drv->sem_get_link_speed, 0); sema_init(&hif_drv->hSemGetCHNL, 0); sema_init(&hif_drv->hSemInactiveTime, 0); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index dada9c57af4fa..a603e84ded597 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -308,7 +308,7 @@ struct host_if_drv { struct semaphore sem_test_key_block; struct semaphore sem_test_disconn_block; struct semaphore sem_get_rssi; - struct semaphore hSemGetLINKSPEED; + struct semaphore sem_get_link_speed; struct semaphore hSemGetCHNL; struct semaphore hSemInactiveTime; /* timer handlers */ -- GitLab From 4ea90008f60744b3d466f3c13c972e42a64c6aa2 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:32 +0900 Subject: [PATCH 0155/2855] staging: wilc1000: rename hSemGetCHNL of struct host_if_drv This patch renames hSemGetCHNL of struct host_if_drv to sem_get_chnl to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 +++--- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 7b654c5022b51..b59551a728dd4 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2075,7 +2075,7 @@ static s32 Handle_GetChnl(struct host_if_drv *hif_drv) result = -EFAULT; } - up(&hif_drv->hSemGetCHNL); + up(&hif_drv->sem_get_chnl); return result; } @@ -3737,7 +3737,7 @@ s32 host_int_get_host_chnl_num(struct host_if_drv *hif_drv, u8 *pu8ChNo) result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) PRINT_ER("wilc mq send fail\n"); - down(&hif_drv->hSemGetCHNL); + down(&hif_drv->sem_get_chnl); *pu8ChNo = ch_no; @@ -4111,7 +4111,7 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) sema_init(&hif_drv->sem_test_disconn_block, 0); sema_init(&hif_drv->sem_get_rssi, 0); sema_init(&hif_drv->sem_get_link_speed, 0); - sema_init(&hif_drv->hSemGetCHNL, 0); + sema_init(&hif_drv->sem_get_chnl, 0); sema_init(&hif_drv->hSemInactiveTime, 0); PRINT_D(HOSTINF_DBG, "INIT: CLIENT COUNT %d\n", clients_count); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index a603e84ded597..8d12099d584fc 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -309,7 +309,7 @@ struct host_if_drv { struct semaphore sem_test_disconn_block; struct semaphore sem_get_rssi; struct semaphore sem_get_link_speed; - struct semaphore hSemGetCHNL; + struct semaphore sem_get_chnl; struct semaphore hSemInactiveTime; /* timer handlers */ struct timer_list hScanTimer; -- GitLab From 569a3c670c1a4249db991afda0989d8efb73f91d Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:33 +0900 Subject: [PATCH 0156/2855] staging: wilc1000: rename hSemInactiveTime of struct host_if_drv This patch renames hSemInactiveTime of struct host_if_drv to sem_inactive_time to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 +++--- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index b59551a728dd4..f95d662cbdbb3 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2211,7 +2211,7 @@ static s32 Handle_Get_InActiveTime(struct host_if_drv *hif_drv, PRINT_D(CFG80211_DBG, "Getting inactive time : %d\n", inactive_time); - up(&hif_drv->hSemInactiveTime); + up(&hif_drv->sem_inactive_time); return result; } @@ -3765,7 +3765,7 @@ s32 host_int_get_inactive_time(struct host_if_drv *hif_drv, if (result) PRINT_ER("Failed to send get host channel param's message queue "); - down(&hif_drv->hSemInactiveTime); + down(&hif_drv->sem_inactive_time); *pu32InactiveTime = inactive_time; @@ -4112,7 +4112,7 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) sema_init(&hif_drv->sem_get_rssi, 0); sema_init(&hif_drv->sem_get_link_speed, 0); sema_init(&hif_drv->sem_get_chnl, 0); - sema_init(&hif_drv->hSemInactiveTime, 0); + sema_init(&hif_drv->sem_inactive_time, 0); PRINT_D(HOSTINF_DBG, "INIT: CLIENT COUNT %d\n", clients_count); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 8d12099d584fc..de3baaf4d2e46 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -310,7 +310,7 @@ struct host_if_drv { struct semaphore sem_get_rssi; struct semaphore sem_get_link_speed; struct semaphore sem_get_chnl; - struct semaphore hSemInactiveTime; + struct semaphore sem_inactive_time; /* timer handlers */ struct timer_list hScanTimer; struct timer_list hConnectTimer; -- GitLab From 13b313e45c6dbd20dc6bc174f423be5a372b992f Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:34 +0900 Subject: [PATCH 0157/2855] staging: wilc1000: rename hScanTimer of struct host_if_drv This patch renames hScanTimer of struct host_if_drv to scan_timer to avoid CamelCase naming convention. And, remove the relation comment. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 21 ++++++++++----------- drivers/staging/wilc1000/host_interface.h | 4 ++-- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index f95d662cbdbb3..8b13e67b2ddf6 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -921,7 +921,7 @@ static s32 Handle_Scan(struct host_if_drv *hif_drv, ERRORHANDLER: if (result) { - del_timer(&hif_drv->hScanTimer); + del_timer(&hif_drv->scan_timer); Handle_ScanDone(hif_drv, SCAN_EVENT_ABORTED); } @@ -1636,7 +1636,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, if (hif_drv->usr_scan_req.pfUserScanResult) { PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running OBSS Scan >>\n\n"); - del_timer(&hif_drv->hScanTimer); + del_timer(&hif_drv->scan_timer); Handle_ScanDone((void *)hif_drv, SCAN_EVENT_ABORTED); } @@ -1683,7 +1683,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW while scanning\n"); PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running Scan >>\n\n"); - del_timer(&hif_drv->hScanTimer); + del_timer(&hif_drv->scan_timer); if (hif_drv->usr_scan_req.pfUserScanResult) Handle_ScanDone(hif_drv, SCAN_EVENT_ABORTED); } @@ -1999,7 +1999,7 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) strDisconnectNotifInfo.ie_len = 0; if (hif_drv->usr_scan_req.pfUserScanResult) { - del_timer(&hif_drv->hScanTimer); + del_timer(&hif_drv->scan_timer); hif_drv->usr_scan_req.pfUserScanResult(SCAN_EVENT_ABORTED, NULL, hif_drv->usr_scan_req.u32UserScanPvoid, NULL); @@ -2881,7 +2881,7 @@ static int hostIFthread(void *pvArg) break; case HOST_IF_MSG_RCVD_SCAN_COMPLETE: - del_timer(&hif_drv->hScanTimer); + del_timer(&hif_drv->scan_timer); PRINT_D(HOSTINF_DBG, "scan completed successfully\n"); if (!linux_wlan_get_num_conn_ifcs()) @@ -3920,8 +3920,8 @@ s32 host_int_scan(struct host_if_drv *hif_drv, u8 u8ScanSource, } PRINT_D(HOSTINF_DBG, ">> Starting the SCAN timer\n"); - hif_drv->hScanTimer.data = (unsigned long)hif_drv; - mod_timer(&hif_drv->hScanTimer, + hif_drv->scan_timer.data = (unsigned long)hif_drv; + mod_timer(&hif_drv->scan_timer, jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT)); return result; @@ -4137,8 +4137,7 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000)); } - setup_timer(&hif_drv->hScanTimer, TimerCB_Scan, 0); - + setup_timer(&hif_drv->scan_timer, TimerCB_Scan, 0); setup_timer(&hif_drv->hConnectTimer, TimerCB_Connect, 0); setup_timer(&hif_drv->hRemainOnChannel, ListenTimerCB, 0); @@ -4171,7 +4170,7 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) _fail_timer_2: up(&hif_drv->sem_cfg_values); del_timer_sync(&hif_drv->hConnectTimer); - del_timer_sync(&hif_drv->hScanTimer); + del_timer_sync(&hif_drv->scan_timer); kthread_stop(hif_thread_handler); _fail_mq_: wilc_mq_destroy(&hif_msg_q); @@ -4195,7 +4194,7 @@ s32 host_int_deinit(struct host_if_drv *hif_drv) terminated_handle = hif_drv; PRINT_D(HOSTINF_DBG, "De-initializing host interface for client %d\n", clients_count); - if (del_timer_sync(&hif_drv->hScanTimer)) + if (del_timer_sync(&hif_drv->scan_timer)) PRINT_D(HOSTINF_DBG, ">> Scan timer is active\n"); if (del_timer_sync(&hif_drv->hConnectTimer)) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index de3baaf4d2e46..55afcae2977eb 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -311,8 +311,8 @@ struct host_if_drv { struct semaphore sem_get_link_speed; struct semaphore sem_get_chnl; struct semaphore sem_inactive_time; -/* timer handlers */ - struct timer_list hScanTimer; + + struct timer_list scan_timer; struct timer_list hConnectTimer; struct timer_list hRemainOnChannel; -- GitLab From 81a59506f2788cd1ed438e9e54714af5dd2f3df7 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:35 +0900 Subject: [PATCH 0158/2855] staging: wilc1000: rename hConnectTimer of struct host_if_drv This patch renames hConnectTimer of struct host_if_drv to connect_timer to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 17 ++++++++--------- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 8b13e67b2ddf6..6cde0bfab4365 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1223,7 +1223,7 @@ ERRORHANDLER: if (result) { tstrConnectInfo strConnectInfo; - del_timer(&hif_drv->hConnectTimer); + del_timer(&hif_drv->connect_timer); PRINT_D(HOSTINF_DBG, "could not start connecting to the required network\n"); @@ -1594,7 +1594,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, hif_drv->usr_conn_req.ConnReqIEsLen); } - del_timer(&hif_drv->hConnectTimer); + del_timer(&hif_drv->connect_timer); hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP, &strConnectInfo, u8MacStatus, @@ -2009,7 +2009,7 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) if (hif_drv->usr_conn_req.pfUserConnectResult) { if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) { PRINT_D(HOSTINF_DBG, "Upper layer requested termination of connection\n"); - del_timer(&hif_drv->hConnectTimer); + del_timer(&hif_drv->connect_timer); } hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL, @@ -3512,8 +3512,8 @@ s32 host_int_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid, return -EFAULT; } - hif_drv->hConnectTimer.data = (unsigned long)hif_drv; - mod_timer(&hif_drv->hConnectTimer, + hif_drv->connect_timer.data = (unsigned long)hif_drv; + mod_timer(&hif_drv->connect_timer, jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT)); return result; @@ -4138,8 +4138,7 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) } setup_timer(&hif_drv->scan_timer, TimerCB_Scan, 0); - setup_timer(&hif_drv->hConnectTimer, TimerCB_Connect, 0); - + setup_timer(&hif_drv->connect_timer, TimerCB_Connect, 0); setup_timer(&hif_drv->hRemainOnChannel, ListenTimerCB, 0); sema_init(&hif_drv->sem_cfg_values, 1); @@ -4169,7 +4168,7 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) _fail_timer_2: up(&hif_drv->sem_cfg_values); - del_timer_sync(&hif_drv->hConnectTimer); + del_timer_sync(&hif_drv->connect_timer); del_timer_sync(&hif_drv->scan_timer); kthread_stop(hif_thread_handler); _fail_mq_: @@ -4197,7 +4196,7 @@ s32 host_int_deinit(struct host_if_drv *hif_drv) if (del_timer_sync(&hif_drv->scan_timer)) PRINT_D(HOSTINF_DBG, ">> Scan timer is active\n"); - if (del_timer_sync(&hif_drv->hConnectTimer)) + if (del_timer_sync(&hif_drv->connect_timer)) PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n"); if (del_timer_sync(&periodic_rssi)) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 55afcae2977eb..d95011e73b012 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -313,7 +313,7 @@ struct host_if_drv { struct semaphore sem_inactive_time; struct timer_list scan_timer; - struct timer_list hConnectTimer; + struct timer_list connect_timer; struct timer_list hRemainOnChannel; bool IFC_UP; -- GitLab From cc2d7e9e86e279eb71c6be985b6e6dc81b05c251 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:36 +0900 Subject: [PATCH 0159/2855] staging: wilc1000: rename hRemainOnChannel of struct host_if_drv This patch renames hRemainOnChannel of struct host_if_drv to remain_on_ch_timer to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 12 ++++++------ drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 6cde0bfab4365..3cff865011aeb 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2530,8 +2530,8 @@ static int Handle_RemainOnChan(struct host_if_drv *hif_drv, ERRORHANDLER: { P2P_LISTEN_STATE = 1; - hif_drv->hRemainOnChannel.data = (unsigned long)hif_drv; - mod_timer(&hif_drv->hRemainOnChannel, + hif_drv->remain_on_ch_timer.data = (unsigned long)hif_drv; + mod_timer(&hif_drv->remain_on_ch_timer, jiffies + msecs_to_jiffies(pstrHostIfRemainOnChan->u32duration)); @@ -2628,7 +2628,7 @@ static void ListenTimerCB(unsigned long arg) struct host_if_msg msg; struct host_if_drv *hif_drv = (struct host_if_drv *)arg; - del_timer(&hif_drv->hRemainOnChannel); + del_timer(&hif_drv->remain_on_ch_timer); memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED; @@ -4139,7 +4139,7 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) setup_timer(&hif_drv->scan_timer, TimerCB_Scan, 0); setup_timer(&hif_drv->connect_timer, TimerCB_Connect, 0); - setup_timer(&hif_drv->hRemainOnChannel, ListenTimerCB, 0); + setup_timer(&hif_drv->remain_on_ch_timer, ListenTimerCB, 0); sema_init(&hif_drv->sem_cfg_values, 1); down(&hif_drv->sem_cfg_values); @@ -4202,7 +4202,7 @@ s32 host_int_deinit(struct host_if_drv *hif_drv) if (del_timer_sync(&periodic_rssi)) PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n"); - del_timer_sync(&hif_drv->hRemainOnChannel); + del_timer_sync(&hif_drv->remain_on_ch_timer); host_int_set_wfi_drv_handler(NULL); down(&hif_sema_driver); @@ -4391,7 +4391,7 @@ s32 host_int_ListenStateExpired(struct host_if_drv *hif_drv, u32 u32SessionID) return -EFAULT; } - del_timer(&hif_drv->hRemainOnChannel); + del_timer(&hif_drv->remain_on_ch_timer); memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index d95011e73b012..71788b1e80a81 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -314,7 +314,7 @@ struct host_if_drv { struct timer_list scan_timer; struct timer_list connect_timer; - struct timer_list hRemainOnChannel; + struct timer_list remain_on_ch_timer; bool IFC_UP; }; -- GitLab From e3e7e8acf5e6d87fc44d969abdf272c9bc10efa2 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:37 +0900 Subject: [PATCH 0160/2855] staging: wilc1000: host_interface.h : remove over-commenting There are over-commenting in the host_interface.h file and most of them are not helpful to explain what the code does and generate 80 ending line over warnings. So, all of comments are removed in this patch and the comments will later be added if necessary with the preferred Linux style. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.h | 740 +--------------------- 1 file changed, 4 insertions(+), 736 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 71788b1e80a81..37e5c7487c4a5 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -1,12 +1,3 @@ -/*! - * @file host_interface.h - * @brief File containg host interface APIs - * @author zsalah - * @sa host_interface.c - * @date 8 March 2012 - * @version 1.0 - */ - #ifndef HOST_INT_H #define HOST_INT_H @@ -173,31 +164,18 @@ enum KEY_TYPE { PMKSA, }; - -/*Scan callBack function definition*/ typedef void (*wilc_scan_result)(enum scan_event, tstrNetworkInfo *, void *, void *); -/*Connect callBack function definition*/ typedef void (*wilc_connect_result)(enum conn_event, tstrConnectInfo *, u8, tstrDisconnectNotifInfo *, void *); -typedef void (*wilc_remain_on_chan_expired)(void *, u32); /*Remain on channel expiration callback function*/ -typedef void (*wilc_remain_on_chan_ready)(void *); /*Remain on channel callback function*/ +typedef void (*wilc_remain_on_chan_expired)(void *, u32); +typedef void (*wilc_remain_on_chan_ready)(void *); -/*! - * @struct rcvd_net_info - * @brief Structure to hold Received Asynchronous Network info - * @details - * @todo - * @sa - * @author Mostafa Abu Bakr - * @date 25 March 2012 - * @version 1.0 - */ struct rcvd_net_info { u8 *buffer; u32 len; @@ -214,10 +192,7 @@ struct hidden_network { }; struct user_scan_req { - /* Scan user call back function */ wilc_scan_result pfUserScanResult; - - /* User specific parameter to be delivered through the Scan User Callback function */ void *u32UserScanPvoid; u32 u32RcvdChCount; @@ -232,10 +207,8 @@ struct user_conn_req { size_t ssidLen; u8 *pu8ConnReqIEs; size_t ConnReqIEsLen; - /* Connect user call back function */ wilc_connect_result pfUserConnectResult; bool IsHTCapable; - /* User specific parameter to be delivered through the Connect User Callback function */ void *u32UserConnectPvoid; }; @@ -331,335 +304,37 @@ struct add_sta_param { u16 u16HTExtParams; u32 u32TxBeamformingCap; u8 u8ASELCap; - u16 u16FlagsMask; /**/ - u16 u16FlagsSet; /* Date: Thu, 29 Oct 2015 11:58:38 +0900 Subject: [PATCH 0161/2855] staging: wilc1000: rename bReg of struct reg_frame This patch renames bReg of struct reg_frame to reg to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 8 +++++--- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 3cff865011aeb..41f226ff6c652 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2552,7 +2552,9 @@ static int Handle_RegisterFrame(struct host_if_drv *hif_drv, struct wid wid; u8 *pu8CurrByte; - PRINT_D(HOSTINF_DBG, "Handling frame register Flag : %d FrameType: %d\n", pstrHostIfRegisterFrame->bReg, pstrHostIfRegisterFrame->u16FrameType); + PRINT_D(HOSTINF_DBG, "Handling frame register : %d FrameType: %d\n", + pstrHostIfRegisterFrame->reg, + pstrHostIfRegisterFrame->u16FrameType); wid.id = (u16)WID_REGISTER_FRAME; wid.type = WID_STR; @@ -2562,7 +2564,7 @@ static int Handle_RegisterFrame(struct host_if_drv *hif_drv, pu8CurrByte = wid.val; - *pu8CurrByte++ = pstrHostIfRegisterFrame->bReg; + *pu8CurrByte++ = pstrHostIfRegisterFrame->reg; *pu8CurrByte++ = pstrHostIfRegisterFrame->u8Regid; memcpy(pu8CurrByte, &pstrHostIfRegisterFrame->u16FrameType, sizeof(u16)); @@ -4434,7 +4436,7 @@ s32 host_int_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool break; } msg.body.reg_frame.u16FrameType = u16FrameType; - msg.body.reg_frame.bReg = bReg; + msg.body.reg_frame.reg = bReg; msg.drv = hif_drv; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 37e5c7487c4a5..ad3071a0ac55b 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -245,7 +245,7 @@ struct remain_ch { }; struct reg_frame { - bool bReg; + bool reg; u16 u16FrameType; u8 u8Regid; }; -- GitLab From d5f654cabbf6c4133450326c16cd1d577ff175e2 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:39 +0900 Subject: [PATCH 0162/2855] staging: wilc1000: rename u16FrameType of struct reg_frame This patch renames u16FrameType of struct reg_frame to frame_type to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 7 +++---- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 41f226ff6c652..3c179123efad0 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2554,7 +2554,7 @@ static int Handle_RegisterFrame(struct host_if_drv *hif_drv, PRINT_D(HOSTINF_DBG, "Handling frame register : %d FrameType: %d\n", pstrHostIfRegisterFrame->reg, - pstrHostIfRegisterFrame->u16FrameType); + pstrHostIfRegisterFrame->frame_type); wid.id = (u16)WID_REGISTER_FRAME; wid.type = WID_STR; @@ -2566,8 +2566,7 @@ static int Handle_RegisterFrame(struct host_if_drv *hif_drv, *pu8CurrByte++ = pstrHostIfRegisterFrame->reg; *pu8CurrByte++ = pstrHostIfRegisterFrame->u8Regid; - memcpy(pu8CurrByte, &pstrHostIfRegisterFrame->u16FrameType, - sizeof(u16)); + memcpy(pu8CurrByte, &pstrHostIfRegisterFrame->frame_type, sizeof(u16)); wid.size = sizeof(u16) + 2; @@ -4435,7 +4434,7 @@ s32 host_int_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool PRINT_D(HOSTINF_DBG, "Not valid frame type\n"); break; } - msg.body.reg_frame.u16FrameType = u16FrameType; + msg.body.reg_frame.frame_type = u16FrameType; msg.body.reg_frame.reg = bReg; msg.drv = hif_drv; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index ad3071a0ac55b..f4239a782e0b9 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -246,7 +246,7 @@ struct remain_ch { struct reg_frame { bool reg; - u16 u16FrameType; + u16 frame_type; u8 u8Regid; }; -- GitLab From bcb410bbc971e585f56fec4f19cbeec54953ab71 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:40 +0900 Subject: [PATCH 0163/2855] staging: wilc1000: rename u8Regid of struct reg_frame This patch renames u8Regid of struct reg_frame to reg_id to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 +++--- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 3c179123efad0..12e0d210a3b10 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2565,7 +2565,7 @@ static int Handle_RegisterFrame(struct host_if_drv *hif_drv, pu8CurrByte = wid.val; *pu8CurrByte++ = pstrHostIfRegisterFrame->reg; - *pu8CurrByte++ = pstrHostIfRegisterFrame->u8Regid; + *pu8CurrByte++ = pstrHostIfRegisterFrame->reg_id; memcpy(pu8CurrByte, &pstrHostIfRegisterFrame->frame_type, sizeof(u16)); wid.size = sizeof(u16) + 2; @@ -4422,12 +4422,12 @@ s32 host_int_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool switch (u16FrameType) { case ACTION: PRINT_D(HOSTINF_DBG, "ACTION\n"); - msg.body.reg_frame.u8Regid = ACTION_FRM_IDX; + msg.body.reg_frame.reg_id = ACTION_FRM_IDX; break; case PROBE_REQ: PRINT_D(HOSTINF_DBG, "PROBE REQ\n"); - msg.body.reg_frame.u8Regid = PROBE_REQ_IDX; + msg.body.reg_frame.reg_id = PROBE_REQ_IDX; break; default: diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index f4239a782e0b9..6cca6e07d2ffa 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -247,7 +247,7 @@ struct remain_ch { struct reg_frame { bool reg; u16 frame_type; - u8 u8Regid; + u8 reg_id; }; -- GitLab From 839ab709b3c49b5dd4535502ec2d2a57f981704c Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:41 +0900 Subject: [PATCH 0164/2855] staging: wilc1000: rename u16Channel of struct remain_ch This patch renames u16Channel of struct remain_ch to ch to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 11 ++++++----- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 12e0d210a3b10..99958f4c4ba4f 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2483,10 +2483,10 @@ static int Handle_RemainOnChan(struct host_if_drv *hif_drv, hif_drv->remain_on_ch.pVoid = pstrHostIfRemainOnChan->pVoid; hif_drv->remain_on_ch.pRemainOnChanExpired = pstrHostIfRemainOnChan->pRemainOnChanExpired; hif_drv->remain_on_ch.pRemainOnChanReady = pstrHostIfRemainOnChan->pRemainOnChanReady; - hif_drv->remain_on_ch.u16Channel = pstrHostIfRemainOnChan->u16Channel; + hif_drv->remain_on_ch.ch = pstrHostIfRemainOnChan->ch; hif_drv->remain_on_ch.u32ListenSessionID = pstrHostIfRemainOnChan->u32ListenSessionID; } else { - pstrHostIfRemainOnChan->u16Channel = hif_drv->remain_on_ch.u16Channel; + pstrHostIfRemainOnChan->ch = hif_drv->remain_on_ch.ch; } if (hif_drv->usr_scan_req.pfUserScanResult) { @@ -2507,7 +2507,8 @@ static int Handle_RemainOnChan(struct host_if_drv *hif_drv, goto ERRORHANDLER; } - PRINT_D(HOSTINF_DBG, "Setting channel :%d\n", pstrHostIfRemainOnChan->u16Channel); + PRINT_D(HOSTINF_DBG, "Setting channel :%d\n", + pstrHostIfRemainOnChan->ch); u8remain_on_chan_flag = true; wid.id = (u16)WID_REMAIN_ON_CHAN; @@ -2520,7 +2521,7 @@ static int Handle_RemainOnChan(struct host_if_drv *hif_drv, } wid.val[0] = u8remain_on_chan_flag; - wid.val[1] = (s8)pstrHostIfRemainOnChan->u16Channel; + wid.val[1] = (s8)pstrHostIfRemainOnChan->ch; result = send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); @@ -4367,7 +4368,7 @@ s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID, memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_REMAIN_ON_CHAN; - msg.body.remain_on_ch.u16Channel = chan; + msg.body.remain_on_ch.ch = chan; msg.body.remain_on_ch.pRemainOnChanExpired = RemainOnChanExpired; msg.body.remain_on_ch.pRemainOnChanReady = RemainOnChanReady; msg.body.remain_on_ch.pVoid = pvUserArg; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 6cca6e07d2ffa..dc68711c67100 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -236,7 +236,7 @@ struct ba_session_info { }; struct remain_ch { - u16 u16Channel; + u16 ch; u32 u32duration; wilc_remain_on_chan_expired pRemainOnChanExpired; wilc_remain_on_chan_ready pRemainOnChanReady; -- GitLab From bfb62abc27789dfb4b30702c17795345a7f7fab3 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:42 +0900 Subject: [PATCH 0165/2855] staging: wilc1000: rename pRemainOnChanExpired of struct remain_ch This patch renames pRemainOnChanExpired of struct remain_ch to expired to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 10 +++++----- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 99958f4c4ba4f..e0ba7202b5843 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2481,7 +2481,7 @@ static int Handle_RemainOnChan(struct host_if_drv *hif_drv, if (!hif_drv->remain_on_ch_pending) { hif_drv->remain_on_ch.pVoid = pstrHostIfRemainOnChan->pVoid; - hif_drv->remain_on_ch.pRemainOnChanExpired = pstrHostIfRemainOnChan->pRemainOnChanExpired; + hif_drv->remain_on_ch.expired = pstrHostIfRemainOnChan->expired; hif_drv->remain_on_ch.pRemainOnChanReady = pstrHostIfRemainOnChan->pRemainOnChanReady; hif_drv->remain_on_ch.ch = pstrHostIfRemainOnChan->ch; hif_drv->remain_on_ch.u32ListenSessionID = pstrHostIfRemainOnChan->u32ListenSessionID; @@ -2610,9 +2610,9 @@ static u32 Handle_ListenStateExpired(struct host_if_drv *hif_drv, goto _done_; } - if (hif_drv->remain_on_ch.pRemainOnChanExpired) { - hif_drv->remain_on_ch.pRemainOnChanExpired(hif_drv->remain_on_ch.pVoid, - pstrHostIfRemainOnChan->u32ListenSessionID); + if (hif_drv->remain_on_ch.expired) { + hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.pVoid, + pstrHostIfRemainOnChan->u32ListenSessionID); } P2P_LISTEN_STATE = 0; } else { @@ -4369,7 +4369,7 @@ s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID, msg.id = HOST_IF_MSG_REMAIN_ON_CHAN; msg.body.remain_on_ch.ch = chan; - msg.body.remain_on_ch.pRemainOnChanExpired = RemainOnChanExpired; + msg.body.remain_on_ch.expired = RemainOnChanExpired; msg.body.remain_on_ch.pRemainOnChanReady = RemainOnChanReady; msg.body.remain_on_ch.pVoid = pvUserArg; msg.body.remain_on_ch.u32duration = u32duration; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index dc68711c67100..3a9f08cc156fc 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -238,7 +238,7 @@ struct ba_session_info { struct remain_ch { u16 ch; u32 u32duration; - wilc_remain_on_chan_expired pRemainOnChanExpired; + wilc_remain_on_chan_expired expired; wilc_remain_on_chan_ready pRemainOnChanReady; void *pVoid; u32 u32ListenSessionID; -- GitLab From 5e5f7916b37741de3219c8b84a162e2b7b949dd9 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:43 +0900 Subject: [PATCH 0166/2855] staging: wilc1000: rename pRemainOnChanReady of struct remain_ch This patch renames pRemainOnChanReady of struct remain_ch to ready to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 8 ++++---- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index e0ba7202b5843..c49bbbf1a1ed2 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2482,7 +2482,7 @@ static int Handle_RemainOnChan(struct host_if_drv *hif_drv, if (!hif_drv->remain_on_ch_pending) { hif_drv->remain_on_ch.pVoid = pstrHostIfRemainOnChan->pVoid; hif_drv->remain_on_ch.expired = pstrHostIfRemainOnChan->expired; - hif_drv->remain_on_ch.pRemainOnChanReady = pstrHostIfRemainOnChan->pRemainOnChanReady; + hif_drv->remain_on_ch.ready = pstrHostIfRemainOnChan->ready; hif_drv->remain_on_ch.ch = pstrHostIfRemainOnChan->ch; hif_drv->remain_on_ch.u32ListenSessionID = pstrHostIfRemainOnChan->u32ListenSessionID; } else { @@ -2536,8 +2536,8 @@ ERRORHANDLER: jiffies + msecs_to_jiffies(pstrHostIfRemainOnChan->u32duration)); - if (hif_drv->remain_on_ch.pRemainOnChanReady) - hif_drv->remain_on_ch.pRemainOnChanReady(hif_drv->remain_on_ch.pVoid); + if (hif_drv->remain_on_ch.ready) + hif_drv->remain_on_ch.ready(hif_drv->remain_on_ch.pVoid); if (hif_drv->remain_on_ch_pending) hif_drv->remain_on_ch_pending = 0; @@ -4370,7 +4370,7 @@ s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID, msg.id = HOST_IF_MSG_REMAIN_ON_CHAN; msg.body.remain_on_ch.ch = chan; msg.body.remain_on_ch.expired = RemainOnChanExpired; - msg.body.remain_on_ch.pRemainOnChanReady = RemainOnChanReady; + msg.body.remain_on_ch.ready = RemainOnChanReady; msg.body.remain_on_ch.pVoid = pvUserArg; msg.body.remain_on_ch.u32duration = u32duration; msg.body.remain_on_ch.u32ListenSessionID = u32SessionID; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 3a9f08cc156fc..d3dafc6086259 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -239,7 +239,7 @@ struct remain_ch { u16 ch; u32 u32duration; wilc_remain_on_chan_expired expired; - wilc_remain_on_chan_ready pRemainOnChanReady; + wilc_remain_on_chan_ready ready; void *pVoid; u32 u32ListenSessionID; }; -- GitLab From c5cc4b12641bf029286b24f418847409ed513259 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:44 +0900 Subject: [PATCH 0167/2855] staging: wilc1000: rename pVoid of struct remain_ch This patch renames pVoid of struct remain_ch to arg to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 8 ++++---- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index c49bbbf1a1ed2..1ccf45024c5e8 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2480,7 +2480,7 @@ static int Handle_RemainOnChan(struct host_if_drv *hif_drv, struct wid wid; if (!hif_drv->remain_on_ch_pending) { - hif_drv->remain_on_ch.pVoid = pstrHostIfRemainOnChan->pVoid; + hif_drv->remain_on_ch.arg = pstrHostIfRemainOnChan->arg; hif_drv->remain_on_ch.expired = pstrHostIfRemainOnChan->expired; hif_drv->remain_on_ch.ready = pstrHostIfRemainOnChan->ready; hif_drv->remain_on_ch.ch = pstrHostIfRemainOnChan->ch; @@ -2537,7 +2537,7 @@ ERRORHANDLER: msecs_to_jiffies(pstrHostIfRemainOnChan->u32duration)); if (hif_drv->remain_on_ch.ready) - hif_drv->remain_on_ch.ready(hif_drv->remain_on_ch.pVoid); + hif_drv->remain_on_ch.ready(hif_drv->remain_on_ch.arg); if (hif_drv->remain_on_ch_pending) hif_drv->remain_on_ch_pending = 0; @@ -2611,7 +2611,7 @@ static u32 Handle_ListenStateExpired(struct host_if_drv *hif_drv, } if (hif_drv->remain_on_ch.expired) { - hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.pVoid, + hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg, pstrHostIfRemainOnChan->u32ListenSessionID); } P2P_LISTEN_STATE = 0; @@ -4371,7 +4371,7 @@ s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID, msg.body.remain_on_ch.ch = chan; msg.body.remain_on_ch.expired = RemainOnChanExpired; msg.body.remain_on_ch.ready = RemainOnChanReady; - msg.body.remain_on_ch.pVoid = pvUserArg; + msg.body.remain_on_ch.arg = pvUserArg; msg.body.remain_on_ch.u32duration = u32duration; msg.body.remain_on_ch.u32ListenSessionID = u32SessionID; msg.drv = hif_drv; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index d3dafc6086259..a69be5574e6ee 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -240,7 +240,7 @@ struct remain_ch { u32 u32duration; wilc_remain_on_chan_expired expired; wilc_remain_on_chan_ready ready; - void *pVoid; + void *arg; u32 u32ListenSessionID; }; -- GitLab From 3fc4999e3d81546f4be2c11bce82adbfc7cb216e Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:45 +0900 Subject: [PATCH 0168/2855] staging: wilc1000: rename au8Bssid of struct ba_session_info This patch renames au8Bssid of struct ba_session_info to bssid to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 22 +++++++++++----------- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 1ccf45024c5e8..872f239c46761 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2715,9 +2715,9 @@ static s32 Handle_AddBASession(struct host_if_drv *hif_drv, char *ptr = NULL; PRINT_D(HOSTINF_DBG, "Opening Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\nBufferSize == %d\nSessionTimeOut = %d\n", - strHostIfBASessionInfo->au8Bssid[0], - strHostIfBASessionInfo->au8Bssid[1], - strHostIfBASessionInfo->au8Bssid[2], + strHostIfBASessionInfo->bssid[0], + strHostIfBASessionInfo->bssid[1], + strHostIfBASessionInfo->bssid[2], strHostIfBASessionInfo->u16BufferSize, strHostIfBASessionInfo->u16SessionTimeout, strHostIfBASessionInfo->u8Ted); @@ -2730,7 +2730,7 @@ static s32 Handle_AddBASession(struct host_if_drv *hif_drv, *ptr++ = 0x14; *ptr++ = 0x3; *ptr++ = 0x0; - memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + memcpy(ptr, strHostIfBASessionInfo->bssid, ETH_ALEN); ptr += ETH_ALEN; *ptr++ = strHostIfBASessionInfo->u8Ted; *ptr++ = 1; @@ -2755,7 +2755,7 @@ static s32 Handle_AddBASession(struct host_if_drv *hif_drv, *ptr++ = 15; *ptr++ = 7; *ptr++ = 0x2; - memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + memcpy(ptr, strHostIfBASessionInfo->bssid, ETH_ALEN); ptr += ETH_ALEN; *ptr++ = strHostIfBASessionInfo->u8Ted; *ptr++ = 8; @@ -2778,9 +2778,9 @@ static s32 Handle_DelAllRxBASessions(struct host_if_drv *hif_drv, char *ptr = NULL; PRINT_D(GENERIC_DBG, "Delete Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\n", - strHostIfBASessionInfo->au8Bssid[0], - strHostIfBASessionInfo->au8Bssid[1], - strHostIfBASessionInfo->au8Bssid[2], + strHostIfBASessionInfo->bssid[0], + strHostIfBASessionInfo->bssid[1], + strHostIfBASessionInfo->bssid[2], strHostIfBASessionInfo->u8Ted); wid.id = (u16)WID_DEL_ALL_RX_BA; @@ -2791,7 +2791,7 @@ static s32 Handle_DelAllRxBASessions(struct host_if_drv *hif_drv, *ptr++ = 0x14; *ptr++ = 0x3; *ptr++ = 0x2; - memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + memcpy(ptr, strHostIfBASessionInfo->bssid, ETH_ALEN); ptr += ETH_ALEN; *ptr++ = strHostIfBASessionInfo->u8Ted; *ptr++ = 0; @@ -4914,7 +4914,7 @@ s32 host_int_delBASession(struct host_if_drv *hif_drv, char *pBSSID, char TID) msg.id = HOST_IF_MSG_DEL_BA_SESSION; - memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN); + memcpy(pBASessionInfo->bssid, pBSSID, ETH_ALEN); pBASessionInfo->u8Ted = TID; msg.drv = hif_drv; @@ -4944,7 +4944,7 @@ s32 host_int_del_All_Rx_BASession(struct host_if_drv *hif_drv, msg.id = HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS; - memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN); + memcpy(pBASessionInfo->bssid, pBSSID, ETH_ALEN); pBASessionInfo->u8Ted = TID; msg.drv = hif_drv; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index a69be5574e6ee..29cab4eb0180e 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -229,7 +229,7 @@ struct get_mac_addr { }; struct ba_session_info { - u8 au8Bssid[ETH_ALEN]; + u8 bssid[ETH_ALEN]; u8 u8Ted; u16 u16BufferSize; u16 u16SessionTimeout; -- GitLab From 16c9b391425340e09be378e7becee0d4319dd295 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:46 +0900 Subject: [PATCH 0169/2855] staging: wilc1000: rename u8Ted of struct ba_session_info This patch renames u8Ted of struct ba_session_info to tid to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 14 +++++++------- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 872f239c46761..74d4c8f487447 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2720,7 +2720,7 @@ static s32 Handle_AddBASession(struct host_if_drv *hif_drv, strHostIfBASessionInfo->bssid[2], strHostIfBASessionInfo->u16BufferSize, strHostIfBASessionInfo->u16SessionTimeout, - strHostIfBASessionInfo->u8Ted); + strHostIfBASessionInfo->tid); wid.id = (u16)WID_11E_P_ACTION_REQ; wid.type = WID_STR; @@ -2732,7 +2732,7 @@ static s32 Handle_AddBASession(struct host_if_drv *hif_drv, *ptr++ = 0x0; memcpy(ptr, strHostIfBASessionInfo->bssid, ETH_ALEN); ptr += ETH_ALEN; - *ptr++ = strHostIfBASessionInfo->u8Ted; + *ptr++ = strHostIfBASessionInfo->tid; *ptr++ = 1; *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF); *ptr++ = ((strHostIfBASessionInfo->u16BufferSize >> 16) & 0xFF); @@ -2757,7 +2757,7 @@ static s32 Handle_AddBASession(struct host_if_drv *hif_drv, *ptr++ = 0x2; memcpy(ptr, strHostIfBASessionInfo->bssid, ETH_ALEN); ptr += ETH_ALEN; - *ptr++ = strHostIfBASessionInfo->u8Ted; + *ptr++ = strHostIfBASessionInfo->tid; *ptr++ = 8; *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF); *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF); @@ -2781,7 +2781,7 @@ static s32 Handle_DelAllRxBASessions(struct host_if_drv *hif_drv, strHostIfBASessionInfo->bssid[0], strHostIfBASessionInfo->bssid[1], strHostIfBASessionInfo->bssid[2], - strHostIfBASessionInfo->u8Ted); + strHostIfBASessionInfo->tid); wid.id = (u16)WID_DEL_ALL_RX_BA; wid.type = WID_STR; @@ -2793,7 +2793,7 @@ static s32 Handle_DelAllRxBASessions(struct host_if_drv *hif_drv, *ptr++ = 0x2; memcpy(ptr, strHostIfBASessionInfo->bssid, ETH_ALEN); ptr += ETH_ALEN; - *ptr++ = strHostIfBASessionInfo->u8Ted; + *ptr++ = strHostIfBASessionInfo->tid; *ptr++ = 0; *ptr++ = 32; @@ -4915,7 +4915,7 @@ s32 host_int_delBASession(struct host_if_drv *hif_drv, char *pBSSID, char TID) msg.id = HOST_IF_MSG_DEL_BA_SESSION; memcpy(pBASessionInfo->bssid, pBSSID, ETH_ALEN); - pBASessionInfo->u8Ted = TID; + pBASessionInfo->tid = TID; msg.drv = hif_drv; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -4945,7 +4945,7 @@ s32 host_int_del_All_Rx_BASession(struct host_if_drv *hif_drv, msg.id = HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS; memcpy(pBASessionInfo->bssid, pBSSID, ETH_ALEN); - pBASessionInfo->u8Ted = TID; + pBASessionInfo->tid = TID; msg.drv = hif_drv; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 29cab4eb0180e..9110e9ecf8cd0 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -230,7 +230,7 @@ struct get_mac_addr { struct ba_session_info { u8 bssid[ETH_ALEN]; - u8 u8Ted; + u8 tid; u16 u16BufferSize; u16 u16SessionTimeout; }; -- GitLab From 277c21308f1e8e135ca7d27bce9b6d496b3ad24f Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:47 +0900 Subject: [PATCH 0170/2855] staging: wilc1000: rename u16BufferSize of struct ba_session_info This patch renames u16BufferSize of struct ba_session_info to buf_size to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 8 ++++---- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 74d4c8f487447..75ad6d006944a 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2718,7 +2718,7 @@ static s32 Handle_AddBASession(struct host_if_drv *hif_drv, strHostIfBASessionInfo->bssid[0], strHostIfBASessionInfo->bssid[1], strHostIfBASessionInfo->bssid[2], - strHostIfBASessionInfo->u16BufferSize, + strHostIfBASessionInfo->buf_size, strHostIfBASessionInfo->u16SessionTimeout, strHostIfBASessionInfo->tid); @@ -2734,8 +2734,8 @@ static s32 Handle_AddBASession(struct host_if_drv *hif_drv, ptr += ETH_ALEN; *ptr++ = strHostIfBASessionInfo->tid; *ptr++ = 1; - *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF); - *ptr++ = ((strHostIfBASessionInfo->u16BufferSize >> 16) & 0xFF); + *ptr++ = (strHostIfBASessionInfo->buf_size & 0xFF); + *ptr++ = ((strHostIfBASessionInfo->buf_size >> 16) & 0xFF); *ptr++ = (strHostIfBASessionInfo->u16SessionTimeout & 0xFF); *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF); *ptr++ = (AddbaTimeout & 0xFF); @@ -2759,7 +2759,7 @@ static s32 Handle_AddBASession(struct host_if_drv *hif_drv, ptr += ETH_ALEN; *ptr++ = strHostIfBASessionInfo->tid; *ptr++ = 8; - *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF); + *ptr++ = (strHostIfBASessionInfo->buf_size & 0xFF); *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF); *ptr++ = 3; result = send_config_pkt(SET_CFG, &wid, 1, diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 9110e9ecf8cd0..e020a6d72d06c 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -231,7 +231,7 @@ struct get_mac_addr { struct ba_session_info { u8 bssid[ETH_ALEN]; u8 tid; - u16 u16BufferSize; + u16 buf_size; u16 u16SessionTimeout; }; -- GitLab From 23d0bfaa69648efaa91b247c7ac2fbdc21e0a90c Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:48 +0900 Subject: [PATCH 0171/2855] staging: wilc1000: rename u16SessionTimeout of struct ba_session_info This patch renames u16SessionTimeout of struct ba_session_info to time_out to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 8 ++++---- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 75ad6d006944a..5bc85dd275892 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2719,7 +2719,7 @@ static s32 Handle_AddBASession(struct host_if_drv *hif_drv, strHostIfBASessionInfo->bssid[1], strHostIfBASessionInfo->bssid[2], strHostIfBASessionInfo->buf_size, - strHostIfBASessionInfo->u16SessionTimeout, + strHostIfBASessionInfo->time_out, strHostIfBASessionInfo->tid); wid.id = (u16)WID_11E_P_ACTION_REQ; @@ -2736,8 +2736,8 @@ static s32 Handle_AddBASession(struct host_if_drv *hif_drv, *ptr++ = 1; *ptr++ = (strHostIfBASessionInfo->buf_size & 0xFF); *ptr++ = ((strHostIfBASessionInfo->buf_size >> 16) & 0xFF); - *ptr++ = (strHostIfBASessionInfo->u16SessionTimeout & 0xFF); - *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF); + *ptr++ = (strHostIfBASessionInfo->time_out & 0xFF); + *ptr++ = ((strHostIfBASessionInfo->time_out >> 16) & 0xFF); *ptr++ = (AddbaTimeout & 0xFF); *ptr++ = ((AddbaTimeout >> 16) & 0xFF); *ptr++ = 8; @@ -2760,7 +2760,7 @@ static s32 Handle_AddBASession(struct host_if_drv *hif_drv, *ptr++ = strHostIfBASessionInfo->tid; *ptr++ = 8; *ptr++ = (strHostIfBASessionInfo->buf_size & 0xFF); - *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF); + *ptr++ = ((strHostIfBASessionInfo->time_out >> 16) & 0xFF); *ptr++ = 3; result = send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index e020a6d72d06c..2050fbe45ced7 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -232,7 +232,7 @@ struct ba_session_info { u8 bssid[ETH_ALEN]; u8 tid; u16 buf_size; - u16 u16SessionTimeout; + u16 time_out; }; struct remain_ch { -- GitLab From 6bd77755b687f0b6f0b4a1ee1a8733fb5e4c0973 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:49 +0900 Subject: [PATCH 0172/2855] staging: wilc1000: remove warnings line over 80 characters This patch removes the warnings reported by checkpatch.pl for line over 80 characters. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.h | 116 ++++++++++++++-------- 1 file changed, 74 insertions(+), 42 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 2050fbe45ced7..486c647d6ea4e 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -316,82 +316,114 @@ int host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv, int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, const u8 *key, u8 len, u8 index, u8 mode, enum AUTHTYPE auth_type); -s32 host_int_add_ptk(struct host_if_drv *hWFIDrv, const u8 *pu8Ptk, u8 u8PtkKeylen, - const u8 *mac_addr, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode, u8 u8Idx); -s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, u32 *pu32InactiveTime); -s32 host_int_add_rx_gtk(struct host_if_drv *hWFIDrv, const u8 *pu8RxGtk, u8 u8GtkKeylen, - u8 u8KeyIdx, u32 u32KeyRSClen, const u8 *KeyRSC, - const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode); -s32 host_int_add_tx_gtk(struct host_if_drv *hWFIDrv, u8 u8KeyLen, u8 *pu8TxGtk, u8 u8KeyIdx); -s32 host_int_set_pmkid_info(struct host_if_drv *hWFIDrv, struct host_if_pmkid_attr *pu8PmkidInfoArray); +s32 host_int_add_ptk(struct host_if_drv *hWFIDrv, const u8 *pu8Ptk, + u8 u8PtkKeylen, const u8 *mac_addr, + const u8 *pu8RxMic, const u8 *pu8TxMic, + u8 mode, u8 u8Ciphermode, u8 u8Idx); +s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, + u32 *pu32InactiveTime); +s32 host_int_add_rx_gtk(struct host_if_drv *hWFIDrv, const u8 *pu8RxGtk, + u8 u8GtkKeylen, u8 u8KeyIdx, + u32 u32KeyRSClen, const u8 *KeyRSC, + const u8 *pu8RxMic, const u8 *pu8TxMic, + u8 mode, u8 u8Ciphermode); +s32 host_int_add_tx_gtk(struct host_if_drv *hWFIDrv, u8 u8KeyLen, + u8 *pu8TxGtk, u8 u8KeyIdx); +s32 host_int_set_pmkid_info(struct host_if_drv *hWFIDrv, + struct host_if_pmkid_attr *pu8PmkidInfoArray); s32 host_int_get_pmkid_info(struct host_if_drv *hWFIDrv, u8 *pu8PmkidInfoArray, - u32 u32PmkidInfoLen); -s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hWFIDrv, u8 *pu8PassPhrase, - u8 u8Psklength); + u32 u32PmkidInfoLen); +s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hWFIDrv, + u8 *pu8PassPhrase, + u8 u8Psklength); s32 host_int_get_RSNAConfigPSKPassPhrase(struct host_if_drv *hWFIDrv, - u8 *pu8PassPhrase, u8 u8Psklength); + u8 *pu8PassPhrase, u8 u8Psklength); s32 host_int_get_MacAddress(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); s32 host_int_set_MacAddress(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); int host_int_wait_msg_queue_idle(void); s32 host_int_set_start_scan_req(struct host_if_drv *hWFIDrv, u8 scanSource); s32 host_int_get_start_scan_req(struct host_if_drv *hWFIDrv, u8 *pu8ScanSource); s32 host_int_set_join_req(struct host_if_drv *hWFIDrv, u8 *pu8bssid, - const u8 *pu8ssid, size_t ssidLen, - const u8 *pu8IEs, size_t IEsLen, - wilc_connect_result pfConnectResult, void *pvUserArg, - u8 u8security, enum AUTHTYPE tenuAuth_type, - u8 u8channel, - void *pJoinParams); + const u8 *pu8ssid, size_t ssidLen, + const u8 *pu8IEs, size_t IEsLen, + wilc_connect_result pfConnectResult, void *pvUserArg, + u8 u8security, enum AUTHTYPE tenuAuth_type, + u8 u8channel, void *pJoinParams); s32 host_int_flush_join_req(struct host_if_drv *hWFIDrv); s32 host_int_disconnect(struct host_if_drv *hWFIDrv, u16 u16ReasonCode); s32 host_int_disconnect_station(struct host_if_drv *hWFIDrv, u8 assoc_id); -s32 host_int_get_assoc_req_info(struct host_if_drv *hWFIDrv, u8 *pu8AssocReqInfo, - u32 u32AssocReqInfoLen); -s32 host_int_get_assoc_res_info(struct host_if_drv *hWFIDrv, u8 *pu8AssocRespInfo, - u32 u32MaxAssocRespInfoLen, u32 *pu32RcvdAssocRespInfoLen); -s32 host_int_get_rx_power_level(struct host_if_drv *hWFIDrv, u8 *pu8RxPowerLevel, - u32 u32RxPowerLevelLen); +s32 host_int_get_assoc_req_info(struct host_if_drv *hWFIDrv, + u8 *pu8AssocReqInfo, + u32 u32AssocReqInfoLen); +s32 host_int_get_assoc_res_info(struct host_if_drv *hWFIDrv, + u8 *pu8AssocRespInfo, + u32 u32MaxAssocRespInfoLen, + u32 *pu32RcvdAssocRespInfoLen); +s32 host_int_get_rx_power_level(struct host_if_drv *hWFIDrv, + u8 *pu8RxPowerLevel, + u32 u32RxPowerLevelLen); int host_int_set_mac_chnl_num(struct host_if_drv *wfi_drv, u8 channel); s32 host_int_get_host_chnl_num(struct host_if_drv *hWFIDrv, u8 *pu8ChNo); s32 host_int_get_rssi(struct host_if_drv *hWFIDrv, s8 *ps8Rssi); s32 host_int_get_link_speed(struct host_if_drv *hWFIDrv, s8 *ps8lnkspd); s32 host_int_scan(struct host_if_drv *hWFIDrv, u8 u8ScanSource, - u8 u8ScanType, u8 *pu8ChnlFreqList, - u8 u8ChnlListLen, const u8 *pu8IEs, - size_t IEsLen, wilc_scan_result ScanResult, - void *pvUserArg, - struct hidden_network *pstrHiddenNetwork); -s32 hif_set_cfg(struct host_if_drv *hWFIDrv, struct cfg_param_val *pstrCfgParamVal); + u8 u8ScanType, u8 *pu8ChnlFreqList, + u8 u8ChnlListLen, const u8 *pu8IEs, + size_t IEsLen, wilc_scan_result ScanResult, + void *pvUserArg, struct hidden_network *pstrHiddenNetwork); +s32 hif_set_cfg(struct host_if_drv *hWFIDrv, + struct cfg_param_val *pstrCfgParamVal); s32 hif_get_cfg(struct host_if_drv *hWFIDrv, u16 u16WID, u16 *pu16WID_Value); s32 host_int_init(struct net_device *dev, struct host_if_drv **phWFIDrv); s32 host_int_deinit(struct host_if_drv *hWFIDrv); s32 host_int_add_beacon(struct host_if_drv *hWFIDrv, u32 u32Interval, - u32 u32DTIMPeriod, - u32 u32HeadLen, u8 *pu8Head, - u32 u32TailLen, u8 *pu8tail); + u32 u32DTIMPeriod, + u32 u32HeadLen, + u8 *pu8Head, + u32 u32TailLen, + u8 *pu8tail); s32 host_int_del_beacon(struct host_if_drv *hWFIDrv); s32 host_int_add_station(struct host_if_drv *hWFIDrv, struct add_sta_param *pstrStaParams); -s32 host_int_del_allstation(struct host_if_drv *hWFIDrv, u8 pu8MacAddr[][ETH_ALEN]); +s32 host_int_del_allstation(struct host_if_drv *hWFIDrv, + u8 pu8MacAddr[][ETH_ALEN]); s32 host_int_del_station(struct host_if_drv *hWFIDrv, const u8 *pu8MacAddr); s32 host_int_edit_station(struct host_if_drv *hWFIDrv, struct add_sta_param *pstrStaParams); -s32 host_int_set_power_mgmt(struct host_if_drv *hWFIDrv, bool bIsEnabled, u32 u32Timeout); -s32 host_int_setup_multicast_filter(struct host_if_drv *hWFIDrv, bool bIsEnabled, u32 u32count); -s32 host_int_setup_ipaddress(struct host_if_drv *hWFIDrv, u8 *pu8IPAddr, u8 idx); +s32 host_int_set_power_mgmt(struct host_if_drv *hWFIDrv, + bool bIsEnabled, + u32 u32Timeout); +s32 host_int_setup_multicast_filter(struct host_if_drv *hWFIDrv, + bool bIsEnabled, + u32 u32count); +s32 host_int_setup_ipaddress(struct host_if_drv *hWFIDrv, + u8 *pu8IPAddr, + u8 idx); s32 host_int_delBASession(struct host_if_drv *hWFIDrv, char *pBSSID, char TID); -s32 host_int_del_All_Rx_BASession(struct host_if_drv *hWFIDrv, char *pBSSID, char TID); +s32 host_int_del_All_Rx_BASession(struct host_if_drv *hWFIDrv, + char *pBSSID, + char TID); s32 host_int_get_ipaddress(struct host_if_drv *hWFIDrv, u8 *pu8IPAddr, u8 idx); -s32 host_int_remain_on_channel(struct host_if_drv *hWFIDrv, u32 u32SessionID, u32 u32duration, u16 chan, wilc_remain_on_chan_expired RemainOnChanExpired, wilc_remain_on_chan_ready RemainOnChanReady, void *pvUserArg); +s32 host_int_remain_on_channel(struct host_if_drv *hWFIDrv, + u32 u32SessionID, + u32 u32duration, + u16 chan, + wilc_remain_on_chan_expired RemainOnChanExpired, + wilc_remain_on_chan_ready RemainOnChanReady, + void *pvUserArg); s32 host_int_ListenStateExpired(struct host_if_drv *hWFIDrv, u32 u32SessionID); -s32 host_int_frame_register(struct host_if_drv *hWFIDrv, u16 u16FrameType, bool bReg); +s32 host_int_frame_register(struct host_if_drv *hWFIDrv, + u16 u16FrameType, + bool bReg); int host_int_set_wfi_drv_handler(struct host_if_drv *address); int host_int_set_operation_mode(struct host_if_drv *wfi_drv, u32 mode); -static s32 Handle_ScanDone(struct host_if_drv *drvHandler, enum scan_event enuEvent); +static s32 Handle_ScanDone(struct host_if_drv *drvHandler, + enum scan_event enuEvent); void host_int_freeJoinParams(void *pJoinParams); -s32 host_int_get_statistics(struct host_if_drv *hWFIDrv, struct rf_info *pstrStatistics); +s32 host_int_get_statistics(struct host_if_drv *hWFIDrv, + struct rf_info *pstrStatistics); #endif -- GitLab From bc80185546ad4c801485d94116cafeffa5da776f Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:50 +0900 Subject: [PATCH 0173/2855] staging: wilc1000: rename pfUserScanResult of struct user_scan_req This patch renames pfUserScanResult of struct user_scan_req to scan_result to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 56 +++++++++++------------ drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 5bc85dd275892..a1437e2df5fd1 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -822,7 +822,7 @@ static s32 Handle_Scan(struct host_if_drv *hif_drv, PRINT_D(HOSTINF_DBG, "Setting SCAN params\n"); PRINT_D(HOSTINF_DBG, "Scanning: In [%d] state\n", hif_drv->hif_state); - hif_drv->usr_scan_req.pfUserScanResult = pstrHostIFscanAttr->result; + hif_drv->usr_scan_req.scan_result = pstrHostIFscanAttr->result; hif_drv->usr_scan_req.u32UserScanPvoid = pstrHostIFscanAttr->arg; if ((hif_drv->hif_state >= HOST_IF_SCANNING) && @@ -969,10 +969,10 @@ static s32 Handle_ScanDone(struct host_if_drv *hif_drv, return result; } - if (hif_drv->usr_scan_req.pfUserScanResult) { - hif_drv->usr_scan_req.pfUserScanResult(enuEvent, NULL, - hif_drv->usr_scan_req.u32UserScanPvoid, NULL); - hif_drv->usr_scan_req.pfUserScanResult = NULL; + if (hif_drv->usr_scan_req.scan_result) { + hif_drv->usr_scan_req.scan_result(enuEvent, NULL, + hif_drv->usr_scan_req.u32UserScanPvoid, NULL); + hif_drv->usr_scan_req.scan_result = NULL; } return result; @@ -1404,11 +1404,11 @@ static s32 Handle_RcvdNtwrkInfo(struct host_if_drv *hif_drv, bNewNtwrkFound = true; PRINT_INFO(HOSTINF_DBG, "Handling received network info\n"); - if (hif_drv->usr_scan_req.pfUserScanResult) { + if (hif_drv->usr_scan_req.scan_result) { PRINT_D(HOSTINF_DBG, "State: Scanning, parsing network information received\n"); parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo); if ((!pstrNetworkInfo) || - (!hif_drv->usr_scan_req.pfUserScanResult)) { + (!hif_drv->usr_scan_req.scan_result)) { PRINT_ER("driver is null\n"); result = -EINVAL; goto done; @@ -1447,17 +1447,17 @@ static s32 Handle_RcvdNtwrkInfo(struct host_if_drv *hif_drv, pstrNetworkInfo->bNewNetwork = true; pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo); - hif_drv->usr_scan_req.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo, - hif_drv->usr_scan_req.u32UserScanPvoid, - pJoinParams); + hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo, + hif_drv->usr_scan_req.u32UserScanPvoid, + pJoinParams); } } else { PRINT_WRN(HOSTINF_DBG, "Discovered networks exceeded max. limit\n"); } } else { pstrNetworkInfo->bNewNetwork = false; - hif_drv->usr_scan_req.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo, - hif_drv->usr_scan_req.u32UserScanPvoid, NULL); + hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo, + hif_drv->usr_scan_req.u32UserScanPvoid, NULL); } } @@ -1498,7 +1498,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, if ((hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) || (hif_drv->hif_state == HOST_IF_CONNECTED) || - hif_drv->usr_scan_req.pfUserScanResult) { + hif_drv->usr_scan_req.scan_result) { if (!pstrRcvdGnrlAsyncInfo->buffer || !hif_drv->usr_conn_req.pfUserConnectResult) { PRINT_ER("driver is null\n"); @@ -1634,7 +1634,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo)); - if (hif_drv->usr_scan_req.pfUserScanResult) { + if (hif_drv->usr_scan_req.scan_result) { PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running OBSS Scan >>\n\n"); del_timer(&hif_drv->scan_timer); Handle_ScanDone((void *)hif_drv, SCAN_EVENT_ABORTED); @@ -1679,12 +1679,12 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, scan_while_connected = false; } else if ((u8MacStatus == MAC_DISCONNECTED) && - (hif_drv->usr_scan_req.pfUserScanResult)) { + (hif_drv->usr_scan_req.scan_result)) { PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW while scanning\n"); PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running Scan >>\n\n"); del_timer(&hif_drv->scan_timer); - if (hif_drv->usr_scan_req.pfUserScanResult) + if (hif_drv->usr_scan_req.scan_result) Handle_ScanDone(hif_drv, SCAN_EVENT_ABORTED); } } @@ -1998,12 +1998,11 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) strDisconnectNotifInfo.ie = NULL; strDisconnectNotifInfo.ie_len = 0; - if (hif_drv->usr_scan_req.pfUserScanResult) { + if (hif_drv->usr_scan_req.scan_result) { del_timer(&hif_drv->scan_timer); - hif_drv->usr_scan_req.pfUserScanResult(SCAN_EVENT_ABORTED, NULL, - hif_drv->usr_scan_req.u32UserScanPvoid, NULL); - - hif_drv->usr_scan_req.pfUserScanResult = NULL; + hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL, + hif_drv->usr_scan_req.u32UserScanPvoid, NULL); + hif_drv->usr_scan_req.scan_result = NULL; } if (hif_drv->usr_conn_req.pfUserConnectResult) { @@ -2489,7 +2488,7 @@ static int Handle_RemainOnChan(struct host_if_drv *hif_drv, pstrHostIfRemainOnChan->ch = hif_drv->remain_on_ch.ch; } - if (hif_drv->usr_scan_req.pfUserScanResult) { + if (hif_drv->usr_scan_req.scan_result) { PRINT_INFO(GENERIC_DBG, "Required to remain on chan while scanning return\n"); hif_drv->remain_on_ch_pending = 1; result = -EBUSY; @@ -2833,7 +2832,7 @@ static int hostIFthread(void *pvArg) } if (msg.id == HOST_IF_MSG_CONNECT && - hif_drv->usr_scan_req.pfUserScanResult) { + hif_drv->usr_scan_req.scan_result) { PRINT_D(HOSTINF_DBG, "Requeue connect request till scan done received\n"); wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); usleep_range(2 * 1000, 2 * 1000); @@ -4209,11 +4208,10 @@ s32 host_int_deinit(struct host_if_drv *hif_drv) host_int_set_wfi_drv_handler(NULL); down(&hif_sema_driver); - if (hif_drv->usr_scan_req.pfUserScanResult) { - hif_drv->usr_scan_req.pfUserScanResult(SCAN_EVENT_ABORTED, NULL, - hif_drv->usr_scan_req.u32UserScanPvoid, NULL); - - hif_drv->usr_scan_req.pfUserScanResult = NULL; + if (hif_drv->usr_scan_req.scan_result) { + hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL, + hif_drv->usr_scan_req.u32UserScanPvoid, NULL); + hif_drv->usr_scan_req.scan_result = NULL; } hif_drv->hif_state = HOST_IF_IDLE; @@ -4337,7 +4335,7 @@ void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length) if (!hif_drv || hif_drv == terminated_handle) return; - if (hif_drv->usr_scan_req.pfUserScanResult) { + if (hif_drv->usr_scan_req.scan_result) { memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 486c647d6ea4e..b90d9d2aba57e 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -192,7 +192,7 @@ struct hidden_network { }; struct user_scan_req { - wilc_scan_result pfUserScanResult; + wilc_scan_result scan_result; void *u32UserScanPvoid; u32 u32RcvdChCount; -- GitLab From 66eaea30867d9d85ab1f579f9d30a4d0e0a22346 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:51 +0900 Subject: [PATCH 0174/2855] staging: wilc1000: rename u32UserScanPvoid of struct user_scan_req This patch renames u32UserScanPvoid of struct user_scan_req to arg to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 12 ++++++------ drivers/staging/wilc1000/host_interface.h | 3 +-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index a1437e2df5fd1..3648e3cf642d9 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -823,7 +823,7 @@ static s32 Handle_Scan(struct host_if_drv *hif_drv, PRINT_D(HOSTINF_DBG, "Scanning: In [%d] state\n", hif_drv->hif_state); hif_drv->usr_scan_req.scan_result = pstrHostIFscanAttr->result; - hif_drv->usr_scan_req.u32UserScanPvoid = pstrHostIFscanAttr->arg; + hif_drv->usr_scan_req.arg = pstrHostIFscanAttr->arg; if ((hif_drv->hif_state >= HOST_IF_SCANNING) && (hif_drv->hif_state < HOST_IF_CONNECTED)) { @@ -971,7 +971,7 @@ static s32 Handle_ScanDone(struct host_if_drv *hif_drv, if (hif_drv->usr_scan_req.scan_result) { hif_drv->usr_scan_req.scan_result(enuEvent, NULL, - hif_drv->usr_scan_req.u32UserScanPvoid, NULL); + hif_drv->usr_scan_req.arg, NULL); hif_drv->usr_scan_req.scan_result = NULL; } @@ -1448,7 +1448,7 @@ static s32 Handle_RcvdNtwrkInfo(struct host_if_drv *hif_drv, pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo); hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo, - hif_drv->usr_scan_req.u32UserScanPvoid, + hif_drv->usr_scan_req.arg, pJoinParams); } } else { @@ -1457,7 +1457,7 @@ static s32 Handle_RcvdNtwrkInfo(struct host_if_drv *hif_drv, } else { pstrNetworkInfo->bNewNetwork = false; hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo, - hif_drv->usr_scan_req.u32UserScanPvoid, NULL); + hif_drv->usr_scan_req.arg, NULL); } } @@ -2001,7 +2001,7 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) if (hif_drv->usr_scan_req.scan_result) { del_timer(&hif_drv->scan_timer); hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL, - hif_drv->usr_scan_req.u32UserScanPvoid, NULL); + hif_drv->usr_scan_req.arg, NULL); hif_drv->usr_scan_req.scan_result = NULL; } @@ -4210,7 +4210,7 @@ s32 host_int_deinit(struct host_if_drv *hif_drv) if (hif_drv->usr_scan_req.scan_result) { hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL, - hif_drv->usr_scan_req.u32UserScanPvoid, NULL); + hif_drv->usr_scan_req.arg, NULL); hif_drv->usr_scan_req.scan_result = NULL; } diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index b90d9d2aba57e..058ea17379071 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -193,8 +193,7 @@ struct hidden_network { struct user_scan_req { wilc_scan_result scan_result; - void *u32UserScanPvoid; - + void *arg; u32 u32RcvdChCount; struct found_net_info astrFoundNetworkInfo[MAX_NUM_SCANNED_NETWORKS]; }; -- GitLab From af973f30a70aafbb775d9811fa89bee804a5e9d9 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:52 +0900 Subject: [PATCH 0175/2855] staging: wilc1000: rename astrFoundNetworkInfo of struct user_scan_req This patch renames astrFoundNetworkInfo of struct user_scan_req to net_info to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 14 +++++++------- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 3648e3cf642d9..35a1262e90983 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1415,15 +1415,15 @@ static s32 Handle_RcvdNtwrkInfo(struct host_if_drv *hif_drv, } for (i = 0; i < hif_drv->usr_scan_req.u32RcvdChCount; i++) { - if ((hif_drv->usr_scan_req.astrFoundNetworkInfo[i].au8bssid) && + if ((hif_drv->usr_scan_req.net_info[i].au8bssid) && (pstrNetworkInfo->au8bssid)) { - if (memcmp(hif_drv->usr_scan_req.astrFoundNetworkInfo[i].au8bssid, + if (memcmp(hif_drv->usr_scan_req.net_info[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) { - if (pstrNetworkInfo->s8rssi <= hif_drv->usr_scan_req.astrFoundNetworkInfo[i].s8rssi) { + if (pstrNetworkInfo->s8rssi <= hif_drv->usr_scan_req.net_info[i].s8rssi) { PRINT_D(HOSTINF_DBG, "Network previously discovered\n"); goto done; } else { - hif_drv->usr_scan_req.astrFoundNetworkInfo[i].s8rssi = pstrNetworkInfo->s8rssi; + hif_drv->usr_scan_req.net_info[i].s8rssi = pstrNetworkInfo->s8rssi; bNewNtwrkFound = false; break; } @@ -1435,11 +1435,11 @@ static s32 Handle_RcvdNtwrkInfo(struct host_if_drv *hif_drv, PRINT_D(HOSTINF_DBG, "New network found\n"); if (hif_drv->usr_scan_req.u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { - hif_drv->usr_scan_req.astrFoundNetworkInfo[hif_drv->usr_scan_req.u32RcvdChCount].s8rssi = pstrNetworkInfo->s8rssi; + hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.u32RcvdChCount].s8rssi = pstrNetworkInfo->s8rssi; - if (hif_drv->usr_scan_req.astrFoundNetworkInfo[hif_drv->usr_scan_req.u32RcvdChCount].au8bssid && + if (hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.u32RcvdChCount].au8bssid && pstrNetworkInfo->au8bssid) { - memcpy(hif_drv->usr_scan_req.astrFoundNetworkInfo[hif_drv->usr_scan_req.u32RcvdChCount].au8bssid, + memcpy(hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.u32RcvdChCount].au8bssid, pstrNetworkInfo->au8bssid, 6); hif_drv->usr_scan_req.u32RcvdChCount++; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 058ea17379071..dcb68eae24a0f 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -195,7 +195,7 @@ struct user_scan_req { wilc_scan_result scan_result; void *arg; u32 u32RcvdChCount; - struct found_net_info astrFoundNetworkInfo[MAX_NUM_SCANNED_NETWORKS]; + struct found_net_info net_info[MAX_NUM_SCANNED_NETWORKS]; }; struct user_conn_req { -- GitLab From 74ab5e45edf75a8476ee264c8250c35f9b143d4e Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:53 +0900 Subject: [PATCH 0176/2855] staging: wilc1000: rename ssidLen of struct user_conn_req This patch renames ssidLen of struct user_conn_req to ssid_len to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 10 +++++----- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 35a1262e90983..9f70a858f4036 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1010,7 +1010,7 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv, memcpy(hif_drv->usr_conn_req.pu8bssid, pstrHostIFconnectAttr->bssid, 6); } - hif_drv->usr_conn_req.ssidLen = pstrHostIFconnectAttr->ssid_len; + hif_drv->usr_conn_req.ssid_len = pstrHostIFconnectAttr->ssid_len; if (pstrHostIFconnectAttr->ssid) { hif_drv->usr_conn_req.pu8ssid = kmalloc(pstrHostIFconnectAttr->ssid_len + 1, GFP_KERNEL); memcpy(hif_drv->usr_conn_req.pu8ssid, @@ -1371,7 +1371,7 @@ static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv) if (result) PRINT_ER("Failed to send dissconect config packet\n"); - hif_drv->usr_conn_req.ssidLen = 0; + hif_drv->usr_conn_req.ssid_len = 0; kfree(hif_drv->usr_conn_req.pu8ssid); kfree(hif_drv->usr_conn_req.pu8bssid); hif_drv->usr_conn_req.ConnReqIEsLen = 0; @@ -1623,7 +1623,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, kfree(strConnectInfo.pu8ReqIEs); strConnectInfo.pu8ReqIEs = NULL; - hif_drv->usr_conn_req.ssidLen = 0; + hif_drv->usr_conn_req.ssid_len = 0; kfree(hif_drv->usr_conn_req.pu8ssid); kfree(hif_drv->usr_conn_req.pu8bssid); hif_drv->usr_conn_req.ConnReqIEsLen = 0; @@ -1659,7 +1659,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, eth_zero_addr(hif_drv->assoc_bssid); - hif_drv->usr_conn_req.ssidLen = 0; + hif_drv->usr_conn_req.ssid_len = 0; kfree(hif_drv->usr_conn_req.pu8ssid); kfree(hif_drv->usr_conn_req.pu8bssid); hif_drv->usr_conn_req.ConnReqIEsLen = 0; @@ -2023,7 +2023,7 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) eth_zero_addr(hif_drv->assoc_bssid); - hif_drv->usr_conn_req.ssidLen = 0; + hif_drv->usr_conn_req.ssid_len = 0; kfree(hif_drv->usr_conn_req.pu8ssid); kfree(hif_drv->usr_conn_req.pu8bssid); hif_drv->usr_conn_req.ConnReqIEsLen = 0; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index dcb68eae24a0f..69ce8f14fb2ec 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -203,7 +203,7 @@ struct user_conn_req { u8 *pu8ssid; u8 u8security; enum AUTHTYPE tenuAuth_type; - size_t ssidLen; + size_t ssid_len; u8 *pu8ConnReqIEs; size_t ConnReqIEsLen; wilc_connect_result pfUserConnectResult; -- GitLab From a3b2f4b91b3ddd814e853efea423a97dbe7d474b Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:54 +0900 Subject: [PATCH 0177/2855] staging: wilc1000: rename pu8ConnReqIEs of struct user_conn_req This patch renames pu8ConnReqIEs of struct user_conn_req to ies to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 24 +++++++++++------------ drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 9f70a858f4036..667bd2d892cf0 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1021,8 +1021,8 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv, hif_drv->usr_conn_req.ConnReqIEsLen = pstrHostIFconnectAttr->ies_len; if (pstrHostIFconnectAttr->ies) { - hif_drv->usr_conn_req.pu8ConnReqIEs = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL); - memcpy(hif_drv->usr_conn_req.pu8ConnReqIEs, + hif_drv->usr_conn_req.ies = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL); + memcpy(hif_drv->usr_conn_req.ies, pstrHostIFconnectAttr->ies, pstrHostIFconnectAttr->ies_len); } @@ -1053,14 +1053,14 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv, { strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE; strWIDList[u32WidsCount].type = WID_BIN_DATA; - strWIDList[u32WidsCount].val = hif_drv->usr_conn_req.pu8ConnReqIEs; + strWIDList[u32WidsCount].val = hif_drv->usr_conn_req.ies; strWIDList[u32WidsCount].size = hif_drv->usr_conn_req.ConnReqIEsLen; u32WidsCount++; if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) { info_element_size = hif_drv->usr_conn_req.ConnReqIEsLen; info_element = kmalloc(info_element_size, GFP_KERNEL); - memcpy(info_element, hif_drv->usr_conn_req.pu8ConnReqIEs, + memcpy(info_element, hif_drv->usr_conn_req.ies, info_element_size); } } @@ -1339,11 +1339,11 @@ static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv) hif_drv->usr_conn_req.pu8bssid, 6); } - if (hif_drv->usr_conn_req.pu8ConnReqIEs) { + if (hif_drv->usr_conn_req.ies) { strConnectInfo.ReqIEsLen = hif_drv->usr_conn_req.ConnReqIEsLen; strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->usr_conn_req.ConnReqIEsLen, GFP_KERNEL); memcpy(strConnectInfo.pu8ReqIEs, - hif_drv->usr_conn_req.pu8ConnReqIEs, + hif_drv->usr_conn_req.ies, hif_drv->usr_conn_req.ConnReqIEsLen); } @@ -1375,7 +1375,7 @@ static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv) kfree(hif_drv->usr_conn_req.pu8ssid); kfree(hif_drv->usr_conn_req.pu8bssid); hif_drv->usr_conn_req.ConnReqIEsLen = 0; - kfree(hif_drv->usr_conn_req.pu8ConnReqIEs); + kfree(hif_drv->usr_conn_req.ies); eth_zero_addr(u8ConnectedSSID); @@ -1586,11 +1586,11 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, } } - if (hif_drv->usr_conn_req.pu8ConnReqIEs) { + if (hif_drv->usr_conn_req.ies) { strConnectInfo.ReqIEsLen = hif_drv->usr_conn_req.ConnReqIEsLen; strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->usr_conn_req.ConnReqIEsLen, GFP_KERNEL); memcpy(strConnectInfo.pu8ReqIEs, - hif_drv->usr_conn_req.pu8ConnReqIEs, + hif_drv->usr_conn_req.ies, hif_drv->usr_conn_req.ConnReqIEsLen); } @@ -1627,7 +1627,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, kfree(hif_drv->usr_conn_req.pu8ssid); kfree(hif_drv->usr_conn_req.pu8bssid); hif_drv->usr_conn_req.ConnReqIEsLen = 0; - kfree(hif_drv->usr_conn_req.pu8ConnReqIEs); + kfree(hif_drv->usr_conn_req.ies); } else if ((u8MacStatus == MAC_DISCONNECTED) && (hif_drv->hif_state == HOST_IF_CONNECTED)) { PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW\n"); @@ -1663,7 +1663,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, kfree(hif_drv->usr_conn_req.pu8ssid); kfree(hif_drv->usr_conn_req.pu8bssid); hif_drv->usr_conn_req.ConnReqIEsLen = 0; - kfree(hif_drv->usr_conn_req.pu8ConnReqIEs); + kfree(hif_drv->usr_conn_req.ies); if (join_req && join_req_drv == hif_drv) { kfree(join_req); @@ -2027,7 +2027,7 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) kfree(hif_drv->usr_conn_req.pu8ssid); kfree(hif_drv->usr_conn_req.pu8bssid); hif_drv->usr_conn_req.ConnReqIEsLen = 0; - kfree(hif_drv->usr_conn_req.pu8ConnReqIEs); + kfree(hif_drv->usr_conn_req.ies); if (join_req && join_req_drv == hif_drv) { kfree(join_req); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 69ce8f14fb2ec..de4e7d94dfea2 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -204,7 +204,7 @@ struct user_conn_req { u8 u8security; enum AUTHTYPE tenuAuth_type; size_t ssid_len; - u8 *pu8ConnReqIEs; + u8 *ies; size_t ConnReqIEsLen; wilc_connect_result pfUserConnectResult; bool IsHTCapable; -- GitLab From 331ed08002ab1ea682a638e4ef97c88a61c3c090 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:55 +0900 Subject: [PATCH 0178/2855] staging: wilc1000: rename ConnReqIEsLen of struct user_conn_req This patch renames ConnReqIEsLen of struct user_conn_req to ies_len to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 26 +++++++++++------------ drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 667bd2d892cf0..bc899e8157523 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1019,7 +1019,7 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv, hif_drv->usr_conn_req.pu8ssid[pstrHostIFconnectAttr->ssid_len] = '\0'; } - hif_drv->usr_conn_req.ConnReqIEsLen = pstrHostIFconnectAttr->ies_len; + hif_drv->usr_conn_req.ies_len = pstrHostIFconnectAttr->ies_len; if (pstrHostIFconnectAttr->ies) { hif_drv->usr_conn_req.ies = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL); memcpy(hif_drv->usr_conn_req.ies, @@ -1054,11 +1054,11 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv, strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE; strWIDList[u32WidsCount].type = WID_BIN_DATA; strWIDList[u32WidsCount].val = hif_drv->usr_conn_req.ies; - strWIDList[u32WidsCount].size = hif_drv->usr_conn_req.ConnReqIEsLen; + strWIDList[u32WidsCount].size = hif_drv->usr_conn_req.ies_len; u32WidsCount++; if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) { - info_element_size = hif_drv->usr_conn_req.ConnReqIEsLen; + info_element_size = hif_drv->usr_conn_req.ies_len; info_element = kmalloc(info_element_size, GFP_KERNEL); memcpy(info_element, hif_drv->usr_conn_req.ies, info_element_size); @@ -1340,11 +1340,11 @@ static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv) } if (hif_drv->usr_conn_req.ies) { - strConnectInfo.ReqIEsLen = hif_drv->usr_conn_req.ConnReqIEsLen; - strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->usr_conn_req.ConnReqIEsLen, GFP_KERNEL); + strConnectInfo.ReqIEsLen = hif_drv->usr_conn_req.ies_len; + strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL); memcpy(strConnectInfo.pu8ReqIEs, hif_drv->usr_conn_req.ies, - hif_drv->usr_conn_req.ConnReqIEsLen); + hif_drv->usr_conn_req.ies_len); } hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP, @@ -1374,7 +1374,7 @@ static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv) hif_drv->usr_conn_req.ssid_len = 0; kfree(hif_drv->usr_conn_req.pu8ssid); kfree(hif_drv->usr_conn_req.pu8bssid); - hif_drv->usr_conn_req.ConnReqIEsLen = 0; + hif_drv->usr_conn_req.ies_len = 0; kfree(hif_drv->usr_conn_req.ies); eth_zero_addr(u8ConnectedSSID); @@ -1587,11 +1587,11 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, } if (hif_drv->usr_conn_req.ies) { - strConnectInfo.ReqIEsLen = hif_drv->usr_conn_req.ConnReqIEsLen; - strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->usr_conn_req.ConnReqIEsLen, GFP_KERNEL); + strConnectInfo.ReqIEsLen = hif_drv->usr_conn_req.ies_len; + strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL); memcpy(strConnectInfo.pu8ReqIEs, hif_drv->usr_conn_req.ies, - hif_drv->usr_conn_req.ConnReqIEsLen); + hif_drv->usr_conn_req.ies_len); } del_timer(&hif_drv->connect_timer); @@ -1626,7 +1626,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, hif_drv->usr_conn_req.ssid_len = 0; kfree(hif_drv->usr_conn_req.pu8ssid); kfree(hif_drv->usr_conn_req.pu8bssid); - hif_drv->usr_conn_req.ConnReqIEsLen = 0; + hif_drv->usr_conn_req.ies_len = 0; kfree(hif_drv->usr_conn_req.ies); } else if ((u8MacStatus == MAC_DISCONNECTED) && (hif_drv->hif_state == HOST_IF_CONNECTED)) { @@ -1662,7 +1662,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, hif_drv->usr_conn_req.ssid_len = 0; kfree(hif_drv->usr_conn_req.pu8ssid); kfree(hif_drv->usr_conn_req.pu8bssid); - hif_drv->usr_conn_req.ConnReqIEsLen = 0; + hif_drv->usr_conn_req.ies_len = 0; kfree(hif_drv->usr_conn_req.ies); if (join_req && join_req_drv == hif_drv) { @@ -2026,7 +2026,7 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) hif_drv->usr_conn_req.ssid_len = 0; kfree(hif_drv->usr_conn_req.pu8ssid); kfree(hif_drv->usr_conn_req.pu8bssid); - hif_drv->usr_conn_req.ConnReqIEsLen = 0; + hif_drv->usr_conn_req.ies_len = 0; kfree(hif_drv->usr_conn_req.ies); if (join_req && join_req_drv == hif_drv) { diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index de4e7d94dfea2..b2fe8f96855e4 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -205,7 +205,7 @@ struct user_conn_req { enum AUTHTYPE tenuAuth_type; size_t ssid_len; u8 *ies; - size_t ConnReqIEsLen; + size_t ies_len; wilc_connect_result pfUserConnectResult; bool IsHTCapable; void *u32UserConnectPvoid; -- GitLab From 33bfb198fff7f36f90c4b5cc753b8e233d1a32f6 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 11:58:56 +0900 Subject: [PATCH 0179/2855] staging: wilc1000: rename pfUserConnectResult of struct user_conn_req This patch renames pfUserConnectResult of struct user_conn_req to conn_result to avoid CamelCase naming convention. And, some comments modification that has been included name 'pfUserConnectResult'. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 57 ++++++++++++----------- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index bc899e8157523..dc94d00963959 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1029,7 +1029,7 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv, hif_drv->usr_conn_req.u8security = pstrHostIFconnectAttr->security; hif_drv->usr_conn_req.tenuAuth_type = pstrHostIFconnectAttr->auth_type; - hif_drv->usr_conn_req.pfUserConnectResult = pstrHostIFconnectAttr->result; + hif_drv->usr_conn_req.conn_result = pstrHostIFconnectAttr->result; hif_drv->usr_conn_req.u32UserConnectPvoid = pstrHostIFconnectAttr->arg; strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT; @@ -1333,7 +1333,7 @@ static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv) memset(&strConnectInfo, 0, sizeof(tstrConnectInfo)); - if (hif_drv->usr_conn_req.pfUserConnectResult) { + if (hif_drv->usr_conn_req.conn_result) { if (hif_drv->usr_conn_req.pu8bssid) { memcpy(strConnectInfo.au8bssid, hif_drv->usr_conn_req.pu8bssid, 6); @@ -1347,11 +1347,11 @@ static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv) hif_drv->usr_conn_req.ies_len); } - hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP, - &strConnectInfo, - MAC_DISCONNECTED, - NULL, - hif_drv->usr_conn_req.u32UserConnectPvoid); + hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP, + &strConnectInfo, + MAC_DISCONNECTED, + NULL, + hif_drv->usr_conn_req.u32UserConnectPvoid); kfree(strConnectInfo.pu8ReqIEs); strConnectInfo.pu8ReqIEs = NULL; @@ -1500,7 +1500,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, (hif_drv->hif_state == HOST_IF_CONNECTED) || hif_drv->usr_scan_req.scan_result) { if (!pstrRcvdGnrlAsyncInfo->buffer || - !hif_drv->usr_conn_req.pfUserConnectResult) { + !hif_drv->usr_conn_req.conn_result) { PRINT_ER("driver is null\n"); return -EINVAL; } @@ -1595,11 +1595,11 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, } del_timer(&hif_drv->connect_timer); - hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP, - &strConnectInfo, - u8MacStatus, - NULL, - hif_drv->usr_conn_req.u32UserConnectPvoid); + hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP, + &strConnectInfo, + u8MacStatus, + NULL, + hif_drv->usr_conn_req.u32UserConnectPvoid); if ((u8MacStatus == MAC_CONNECTED) && (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) { @@ -1644,15 +1644,15 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, strDisconnectNotifInfo.ie = NULL; strDisconnectNotifInfo.ie_len = 0; - if (hif_drv->usr_conn_req.pfUserConnectResult) { + if (hif_drv->usr_conn_req.conn_result) { g_obtainingIP = false; host_int_set_power_mgmt(hif_drv, 0, 0); - hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, - NULL, - 0, - &strDisconnectNotifInfo, - hif_drv->usr_conn_req.u32UserConnectPvoid); + hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, + NULL, + 0, + &strDisconnectNotifInfo, + hif_drv->usr_conn_req.u32UserConnectPvoid); } else { PRINT_ER("Connect result callback function is NULL\n"); } @@ -2000,21 +2000,26 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) if (hif_drv->usr_scan_req.scan_result) { del_timer(&hif_drv->scan_timer); - hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL, - hif_drv->usr_scan_req.arg, NULL); + hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, + NULL, + hif_drv->usr_scan_req.arg, + NULL); hif_drv->usr_scan_req.scan_result = NULL; } - if (hif_drv->usr_conn_req.pfUserConnectResult) { + if (hif_drv->usr_conn_req.conn_result) { if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) { PRINT_D(HOSTINF_DBG, "Upper layer requested termination of connection\n"); del_timer(&hif_drv->connect_timer); } - hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL, - 0, &strDisconnectNotifInfo, hif_drv->usr_conn_req.u32UserConnectPvoid); + hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, + NULL, + 0, + &strDisconnectNotifInfo, + hif_drv->usr_conn_req.u32UserConnectPvoid); } else { - PRINT_ER("usr_conn_req.pfUserConnectResult = NULL\n"); + PRINT_ER("usr_conn_req.conn_result = NULL\n"); } scan_while_connected = false; @@ -4298,7 +4303,7 @@ void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length) return; } - if (!hif_drv->usr_conn_req.pfUserConnectResult) { + if (!hif_drv->usr_conn_req.conn_result) { PRINT_ER("Received mac status is not needed when there is no current Connect Reques\n"); up(&hif_sema_deinit); return; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index b2fe8f96855e4..036306814d677 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -206,7 +206,7 @@ struct user_conn_req { size_t ssid_len; u8 *ies; size_t ies_len; - wilc_connect_result pfUserConnectResult; + wilc_connect_result conn_result; bool IsHTCapable; void *u32UserConnectPvoid; }; -- GitLab From ff06982c758a398c30e8eacd9479b873416367cd Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:26 +0900 Subject: [PATCH 0180/2855] staging: wilc1000: rename IsHTCapable of struct user_conn_req This patch renames IsHTCapable of struct user_conn_req to ht_capable to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 +- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index dc94d00963959..f1f1ef4b41570 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1143,7 +1143,7 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv, *(pu8CurrByte++) = ptstrJoinBssParam->uapsd_cap; *(pu8CurrByte++) = ptstrJoinBssParam->ht_capable; - hif_drv->usr_conn_req.IsHTCapable = ptstrJoinBssParam->ht_capable; + hif_drv->usr_conn_req.ht_capable = ptstrJoinBssParam->ht_capable; *(pu8CurrByte++) = ptstrJoinBssParam->rsn_found; PRINT_D(HOSTINF_DBG, "* rsn found %d*\n", *(pu8CurrByte - 1)); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 036306814d677..3afe4323072d4 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -207,7 +207,7 @@ struct user_conn_req { u8 *ies; size_t ies_len; wilc_connect_result conn_result; - bool IsHTCapable; + bool ht_capable; void *u32UserConnectPvoid; }; -- GitLab From 73abaa4906ae8d90d558e053a6af4ff5df03109d Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:27 +0900 Subject: [PATCH 0181/2855] staging: wilc1000: rename u32UserConnectPvoid of struct user_conn_req This patch renames u32UserConnectPvoid of struct user_conn_req to arg to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 10 +++++----- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index f1f1ef4b41570..3b24a27704e4a 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1030,7 +1030,7 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv, hif_drv->usr_conn_req.u8security = pstrHostIFconnectAttr->security; hif_drv->usr_conn_req.tenuAuth_type = pstrHostIFconnectAttr->auth_type; hif_drv->usr_conn_req.conn_result = pstrHostIFconnectAttr->result; - hif_drv->usr_conn_req.u32UserConnectPvoid = pstrHostIFconnectAttr->arg; + hif_drv->usr_conn_req.arg = pstrHostIFconnectAttr->arg; strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT; strWIDList[u32WidsCount].type = WID_INT; @@ -1351,7 +1351,7 @@ static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv) &strConnectInfo, MAC_DISCONNECTED, NULL, - hif_drv->usr_conn_req.u32UserConnectPvoid); + hif_drv->usr_conn_req.arg); kfree(strConnectInfo.pu8ReqIEs); strConnectInfo.pu8ReqIEs = NULL; @@ -1599,7 +1599,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, &strConnectInfo, u8MacStatus, NULL, - hif_drv->usr_conn_req.u32UserConnectPvoid); + hif_drv->usr_conn_req.arg); if ((u8MacStatus == MAC_CONNECTED) && (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) { @@ -1652,7 +1652,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, NULL, 0, &strDisconnectNotifInfo, - hif_drv->usr_conn_req.u32UserConnectPvoid); + hif_drv->usr_conn_req.arg); } else { PRINT_ER("Connect result callback function is NULL\n"); } @@ -2017,7 +2017,7 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) NULL, 0, &strDisconnectNotifInfo, - hif_drv->usr_conn_req.u32UserConnectPvoid); + hif_drv->usr_conn_req.arg); } else { PRINT_ER("usr_conn_req.conn_result = NULL\n"); } diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 3afe4323072d4..9595d488446bc 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -208,7 +208,7 @@ struct user_conn_req { size_t ies_len; wilc_connect_result conn_result; bool ht_capable; - void *u32UserConnectPvoid; + void *arg; }; struct drv_handler { -- GitLab From c81f7de85bddae4301b6e801c8175f38d212eaef Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:28 +0900 Subject: [PATCH 0182/2855] staging: wilc1000: host_interface.h: move local define variables This patch move local define variables to local define position. - ACTION - PROBE_REQ - PROBE_RESP - ACTION_FRM_IDX - PROBE_REQ_IDX Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.h | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 9595d488446bc..2dfd7f0d6b708 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -10,8 +10,12 @@ #define STATION_MODE 0x02 #define GO_MODE 0x03 #define CLIENT_MODE 0x04 +#define ACTION 0xD0 +#define PROBE_REQ 0x40 +#define PROBE_RESP 0x50 - +#define ACTION_FRM_IDX 0 +#define PROBE_REQ_IDX 1 #define MAX_NUM_STA 9 #define ACTIVE_SCAN_TIME 10 #define PASSIVE_SCAN_TIME 1200 @@ -249,14 +253,6 @@ struct reg_frame { u8 reg_id; }; - -#define ACTION 0xD0 -#define PROBE_REQ 0x40 -#define PROBE_RESP 0x50 -#define ACTION_FRM_IDX 0 -#define PROBE_REQ_IDX 1 - - enum p2p_listen_state { P2P_IDLE, P2P_LISTEN, -- GitLab From 5babeecb9f3e00ea4b2f15a6748b960fc38c189b Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:29 +0900 Subject: [PATCH 0183/2855] staging: wilc1000: rename u8LinkSpeed of struct rf_info This patch renames u8LinkSpeed of struct rf_info to link_speed to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 +- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 3b24a27704e4a..539911528a37e 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2138,7 +2138,7 @@ s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatis strWIDList[u32WidsCount].id = WID_LINKSPEED; strWIDList[u32WidsCount].type = WID_CHAR; strWIDList[u32WidsCount].size = sizeof(char); - strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u8LinkSpeed; + strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->link_speed; u32WidsCount++; strWIDList[u32WidsCount].id = WID_RSSI; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 2dfd7f0d6b708..cef952a1ef033 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -53,7 +53,7 @@ #define NUM_CONCURRENT_IFC 2 struct rf_info { - u8 u8LinkSpeed; + u8 link_speed; s8 s8RSSI; u32 u32TxCount; u32 u32RxCount; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 3e9501727812c..29b769f834fdf 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -1570,11 +1570,12 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, sinfo->rx_packets = strStatistics.u32RxCount; sinfo->tx_packets = strStatistics.u32TxCount + strStatistics.u32TxFailureCount; sinfo->tx_failed = strStatistics.u32TxFailureCount; - sinfo->txrate.legacy = strStatistics.u8LinkSpeed * 10; + sinfo->txrate.legacy = strStatistics.link_speed * 10; - if ((strStatistics.u8LinkSpeed > TCP_ACK_FILTER_LINK_SPEED_THRESH) && (strStatistics.u8LinkSpeed != DEFAULT_LINK_SPEED)) + if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) && + (strStatistics.link_speed != DEFAULT_LINK_SPEED)) Enable_TCP_ACK_Filter(true); - else if (strStatistics.u8LinkSpeed != DEFAULT_LINK_SPEED) + else if (strStatistics.link_speed != DEFAULT_LINK_SPEED) Enable_TCP_ACK_Filter(false); PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets, -- GitLab From 00c8dfcf98d8390165ba47ede6a34fc50452fa47 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:30 +0900 Subject: [PATCH 0184/2855] staging: wilc1000: rename s8RSSI of struct rf_info This patch renames s8RSSI of struct rf_info to rssi to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 +- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 539911528a37e..bee1f7f11d0c1 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2144,7 +2144,7 @@ s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatis strWIDList[u32WidsCount].id = WID_RSSI; strWIDList[u32WidsCount].type = WID_CHAR; strWIDList[u32WidsCount].size = sizeof(char); - strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->s8RSSI; + strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->rssi; u32WidsCount++; strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index cef952a1ef033..25f748fd5db0f 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -54,7 +54,7 @@ struct rf_info { u8 link_speed; - s8 s8RSSI; + s8 rssi; u32 u32TxCount; u32 u32RxCount; u32 u32TxFailureCount; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 29b769f834fdf..632daa802b799 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -1566,7 +1566,7 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, BIT(NL80211_STA_INFO_TX_FAILED) | BIT(NL80211_STA_INFO_TX_BITRATE); - sinfo->signal = strStatistics.s8RSSI; + sinfo->signal = strStatistics.rssi; sinfo->rx_packets = strStatistics.u32RxCount; sinfo->tx_packets = strStatistics.u32TxCount + strStatistics.u32TxFailureCount; sinfo->tx_failed = strStatistics.u32TxFailureCount; -- GitLab From 7e84ff4ec3cb8101d29f89fed1188121ab47f498 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:31 +0900 Subject: [PATCH 0185/2855] staging: wilc1000: rename u32TxCount of struct rf_info This patch renames u32TxCount of struct rf_info to tx_cnt to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 +- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index bee1f7f11d0c1..0d220a807caec 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2150,7 +2150,7 @@ s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatis strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT; strWIDList[u32WidsCount].type = WID_INT; strWIDList[u32WidsCount].size = sizeof(u32); - strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u32TxCount; + strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_cnt; u32WidsCount++; strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 25f748fd5db0f..9d31c4e873476 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -55,7 +55,7 @@ struct rf_info { u8 link_speed; s8 rssi; - u32 u32TxCount; + u32 tx_cnt; u32 u32RxCount; u32 u32TxFailureCount; }; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 632daa802b799..73cec4bb89f26 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -1568,7 +1568,7 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, sinfo->signal = strStatistics.rssi; sinfo->rx_packets = strStatistics.u32RxCount; - sinfo->tx_packets = strStatistics.u32TxCount + strStatistics.u32TxFailureCount; + sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.u32TxFailureCount; sinfo->tx_failed = strStatistics.u32TxFailureCount; sinfo->txrate.legacy = strStatistics.link_speed * 10; -- GitLab From 9b99274a72ac81d4f251d4d137fcfdee13580fc3 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:32 +0900 Subject: [PATCH 0186/2855] staging: wilc1000: rename u32RxCount of struct rf_info This patch renames u32RxCount of struct rf_info to rx_cnt to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 +- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 0d220a807caec..4f64ee78d3067 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2156,7 +2156,7 @@ s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatis strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT; strWIDList[u32WidsCount].type = WID_INT; strWIDList[u32WidsCount].size = sizeof(u32); - strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u32RxCount; + strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->rx_cnt; u32WidsCount++; strWIDList[u32WidsCount].id = WID_FAILED_COUNT; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 9d31c4e873476..d61b9b7089cb0 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -56,7 +56,7 @@ struct rf_info { u8 link_speed; s8 rssi; u32 tx_cnt; - u32 u32RxCount; + u32 rx_cnt; u32 u32TxFailureCount; }; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 73cec4bb89f26..9b7cac3cdbdda 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -1567,7 +1567,7 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, BIT(NL80211_STA_INFO_TX_BITRATE); sinfo->signal = strStatistics.rssi; - sinfo->rx_packets = strStatistics.u32RxCount; + sinfo->rx_packets = strStatistics.rx_cnt; sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.u32TxFailureCount; sinfo->tx_failed = strStatistics.u32TxFailureCount; sinfo->txrate.legacy = strStatistics.link_speed * 10; -- GitLab From 5416037670fd29045eb59b78beea2c7da4da611c Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:33 +0900 Subject: [PATCH 0187/2855] staging: wilc1000: rename u32TxFailureCount of struct rf_info This patch renames u32TxFailureCount of struct rf_info to tx_fail_cnt to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 +- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 4f64ee78d3067..590d8a423a2e2 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2162,7 +2162,7 @@ s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatis strWIDList[u32WidsCount].id = WID_FAILED_COUNT; strWIDList[u32WidsCount].type = WID_INT; strWIDList[u32WidsCount].size = sizeof(u32); - strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u32TxFailureCount; + strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_fail_cnt; u32WidsCount++; result = send_config_pkt(GET_CFG, strWIDList, u32WidsCount, diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index d61b9b7089cb0..59b1949a7ace8 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -57,7 +57,7 @@ struct rf_info { s8 rssi; u32 tx_cnt; u32 rx_cnt; - u32 u32TxFailureCount; + u32 tx_fail_cnt; }; enum host_if_state { diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 9b7cac3cdbdda..3060b8d3e149b 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -1568,8 +1568,8 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, sinfo->signal = strStatistics.rssi; sinfo->rx_packets = strStatistics.rx_cnt; - sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.u32TxFailureCount; - sinfo->tx_failed = strStatistics.u32TxFailureCount; + sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt; + sinfo->tx_failed = strStatistics.tx_fail_cnt; sinfo->txrate.legacy = strStatistics.link_speed * 10; if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) && -- GitLab From 5cd8f7ae74f5e13522ff8ea2f4079dba554a9423 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:34 +0900 Subject: [PATCH 0188/2855] staging: wilc1000: rename WPARxGtk of enum KEY_TYPE This patch renames WPARxGtk of enum KEY_TYPE to WPA_RX_GTK to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 590d8a423a2e2..ead99ab111ad9 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1795,7 +1795,7 @@ static int Handle_Key(struct host_if_drv *hif_drv, up(&hif_drv->sem_test_key_block); break; - case WPARxGtk: + case WPA_RX_GTK: if (pstrHostIFkeyAttr->action & ADDKEY_AP) { pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL); if (!pu8keybuf) { @@ -3285,7 +3285,7 @@ s32 host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk, } msg.id = HOST_IF_MSG_KEY; - msg.body.key_info.type = WPARxGtk; + msg.body.key_info.type = WPA_RX_GTK; msg.drv = hif_drv; if (mode == AP_MODE) { diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 59b1949a7ace8..b3e74d1ff8973 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -163,7 +163,7 @@ enum conn_event { enum KEY_TYPE { WEP, - WPARxGtk, + WPA_RX_GTK, WPAPtk, PMKSA, }; -- GitLab From 2141fe391ec6f21e52e3f37d642cfc157440cf85 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:35 +0900 Subject: [PATCH 0189/2855] staging: wilc1000: rename WPAPtk of enum KEY_TYPE This patch renames WPAPtk of enum KEY_TYPE to WPA_PTK to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index ead99ab111ad9..3e7c6e4119822 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1869,7 +1869,7 @@ _WPARxGtk_end_case_: break; - case WPAPtk: + case WPA_PTK: if (pstrHostIFkeyAttr->action & ADDKEY_AP) { pu8keybuf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL); if (!pu8keybuf) { @@ -3216,7 +3216,7 @@ s32 host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk, memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_KEY; - msg.body.key_info.type = WPAPtk; + msg.body.key_info.type = WPA_PTK; if (mode == AP_MODE) { msg.body.key_info.action = ADDKEY_AP; msg.body.key_info.attr.wpa.index = u8Idx; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index b3e74d1ff8973..f94bba69f15b0 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -164,7 +164,7 @@ enum conn_event { enum KEY_TYPE { WEP, WPA_RX_GTK, - WPAPtk, + WPA_PTK, PMKSA, }; -- GitLab From f79756eeb0c3af0b6672cae4912ae695f7c0c9d3 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:36 +0900 Subject: [PATCH 0190/2855] staging: wilc1000: rename u32RcvdChCount of struct user_scan_req This patch renames u32RcvdChCount of struct user_scan_req to rcvd_ch_cnt to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 14 +++++++------- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 3e7c6e4119822..f465233fa6095 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -843,7 +843,7 @@ static s32 Handle_Scan(struct host_if_drv *hif_drv, PRINT_D(HOSTINF_DBG, "Setting SCAN params\n"); - hif_drv->usr_scan_req.u32RcvdChCount = 0; + hif_drv->usr_scan_req.rcvd_ch_cnt = 0; strWIDList[u32WidsCount].id = (u16)WID_SSID_PROBE_REQ; strWIDList[u32WidsCount].type = WID_STR; @@ -1414,7 +1414,7 @@ static s32 Handle_RcvdNtwrkInfo(struct host_if_drv *hif_drv, goto done; } - for (i = 0; i < hif_drv->usr_scan_req.u32RcvdChCount; i++) { + for (i = 0; i < hif_drv->usr_scan_req.rcvd_ch_cnt; i++) { if ((hif_drv->usr_scan_req.net_info[i].au8bssid) && (pstrNetworkInfo->au8bssid)) { if (memcmp(hif_drv->usr_scan_req.net_info[i].au8bssid, @@ -1434,15 +1434,15 @@ static s32 Handle_RcvdNtwrkInfo(struct host_if_drv *hif_drv, if (bNewNtwrkFound) { PRINT_D(HOSTINF_DBG, "New network found\n"); - if (hif_drv->usr_scan_req.u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { - hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.u32RcvdChCount].s8rssi = pstrNetworkInfo->s8rssi; + if (hif_drv->usr_scan_req.rcvd_ch_cnt < MAX_NUM_SCANNED_NETWORKS) { + hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].s8rssi = pstrNetworkInfo->s8rssi; - if (hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.u32RcvdChCount].au8bssid && + if (hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].au8bssid && pstrNetworkInfo->au8bssid) { - memcpy(hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.u32RcvdChCount].au8bssid, + memcpy(hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].au8bssid, pstrNetworkInfo->au8bssid, 6); - hif_drv->usr_scan_req.u32RcvdChCount++; + hif_drv->usr_scan_req.rcvd_ch_cnt++; pstrNetworkInfo->bNewNetwork = true; pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index f94bba69f15b0..f824866c05a06 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -198,7 +198,7 @@ struct hidden_network { struct user_scan_req { wilc_scan_result scan_result; void *arg; - u32 u32RcvdChCount; + u32 rcvd_ch_cnt; struct found_net_info net_info[MAX_NUM_SCANNED_NETWORKS]; }; -- GitLab From 7d06972827829c6b7166314681548a57bb8e3586 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:37 +0900 Subject: [PATCH 0191/2855] staging: wilc1000: rename tenuAuth_type of struct user_conn_req This patch renames tenuAuth_type of struct user_conn_req to auth_type to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 9 +++++---- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index f465233fa6095..6c490916b2d8b 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1028,7 +1028,7 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv, } hif_drv->usr_conn_req.u8security = pstrHostIFconnectAttr->security; - hif_drv->usr_conn_req.tenuAuth_type = pstrHostIFconnectAttr->auth_type; + hif_drv->usr_conn_req.auth_type = pstrHostIFconnectAttr->auth_type; hif_drv->usr_conn_req.conn_result = pstrHostIFconnectAttr->result; hif_drv->usr_conn_req.arg = pstrHostIFconnectAttr->arg; @@ -1078,13 +1078,14 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv, strWIDList[u32WidsCount].id = (u16)WID_AUTH_TYPE; strWIDList[u32WidsCount].type = WID_CHAR; strWIDList[u32WidsCount].size = sizeof(char); - strWIDList[u32WidsCount].val = (s8 *)(&hif_drv->usr_conn_req.tenuAuth_type); + strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.auth_type; u32WidsCount++; if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) - auth_type = (u8)hif_drv->usr_conn_req.tenuAuth_type; + auth_type = (u8)hif_drv->usr_conn_req.auth_type; - PRINT_INFO(HOSTINF_DBG, "Authentication Type = %x\n", hif_drv->usr_conn_req.tenuAuth_type); + PRINT_INFO(HOSTINF_DBG, "Authentication Type = %x\n", + hif_drv->usr_conn_req.auth_type); PRINT_D(HOSTINF_DBG, "Connecting to network of SSID %s on channel %d\n", hif_drv->usr_conn_req.pu8ssid, pstrHostIFconnectAttr->ch); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index f824866c05a06..c338028b5171e 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -206,7 +206,7 @@ struct user_conn_req { u8 *pu8bssid; u8 *pu8ssid; u8 u8security; - enum AUTHTYPE tenuAuth_type; + enum AUTHTYPE auth_type; size_t ssid_len; u8 *ies; size_t ies_len; -- GitLab From 9d764e38d31389d7362a94361cccbc347878d1d3 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:38 +0900 Subject: [PATCH 0192/2855] staging: wilc1000: rename u32ListenSessionID of struct remain_ch This patch renames u32ListenSessionID of struct remain_ch to id to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 10 +++++----- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 6c490916b2d8b..294f90c245079 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2489,7 +2489,7 @@ static int Handle_RemainOnChan(struct host_if_drv *hif_drv, hif_drv->remain_on_ch.expired = pstrHostIfRemainOnChan->expired; hif_drv->remain_on_ch.ready = pstrHostIfRemainOnChan->ready; hif_drv->remain_on_ch.ch = pstrHostIfRemainOnChan->ch; - hif_drv->remain_on_ch.u32ListenSessionID = pstrHostIfRemainOnChan->u32ListenSessionID; + hif_drv->remain_on_ch.id = pstrHostIfRemainOnChan->id; } else { pstrHostIfRemainOnChan->ch = hif_drv->remain_on_ch.ch; } @@ -2617,7 +2617,7 @@ static u32 Handle_ListenStateExpired(struct host_if_drv *hif_drv, if (hif_drv->remain_on_ch.expired) { hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg, - pstrHostIfRemainOnChan->u32ListenSessionID); + pstrHostIfRemainOnChan->id); } P2P_LISTEN_STATE = 0; } else { @@ -2640,7 +2640,7 @@ static void ListenTimerCB(unsigned long arg) memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED; msg.drv = hif_drv; - msg.body.remain_on_ch.u32ListenSessionID = hif_drv->remain_on_ch.u32ListenSessionID; + msg.body.remain_on_ch.id = hif_drv->remain_on_ch.id; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) @@ -4377,7 +4377,7 @@ s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID, msg.body.remain_on_ch.ready = RemainOnChanReady; msg.body.remain_on_ch.arg = pvUserArg; msg.body.remain_on_ch.u32duration = u32duration; - msg.body.remain_on_ch.u32ListenSessionID = u32SessionID; + msg.body.remain_on_ch.id = u32SessionID; msg.drv = hif_drv; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -4402,7 +4402,7 @@ s32 host_int_ListenStateExpired(struct host_if_drv *hif_drv, u32 u32SessionID) memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED; msg.drv = hif_drv; - msg.body.remain_on_ch.u32ListenSessionID = u32SessionID; + msg.body.remain_on_ch.id = u32SessionID; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index c338028b5171e..8450e22acd7e8 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -244,7 +244,7 @@ struct remain_ch { wilc_remain_on_chan_expired expired; wilc_remain_on_chan_ready ready; void *arg; - u32 u32ListenSessionID; + u32 id; }; struct reg_frame { -- GitLab From 1229b1ab414c9bb6eebddbf457f324211bf79a79 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:39 +0900 Subject: [PATCH 0193/2855] staging: wilc1000: rename u64P2p_MgmtTimeout of struct host_if_drv This patch renames u64P2p_MgmtTimeout of struct host_if_drv to p2p_timeout to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 +- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 294f90c245079..00f271780b838 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -4158,7 +4158,7 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) hif_drv->cfg_values.passive_scan_time = PASSIVE_SCAN_TIME; hif_drv->cfg_values.curr_tx_rate = AUTORATE; - hif_drv->u64P2p_MgmtTimeout = 0; + hif_drv->p2p_timeout = 0; PRINT_INFO(HOSTINF_DBG, "Initialization values, Site survey value: %d\n Scan source: %d\n Active scan time: %d\n Passive scan time: %d\nCurrent tx Rate = %d\n", hif_drv->cfg_values.site_survey_enabled, diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 8450e22acd7e8..c9a4ce8dfc7ee 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -264,7 +264,7 @@ struct host_if_drv { struct user_conn_req usr_conn_req; struct remain_ch remain_on_ch; u8 remain_on_ch_pending; - u64 u64P2p_MgmtTimeout; + u64 p2p_timeout; u8 u8P2PConnect; enum host_if_state hif_state; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 3060b8d3e149b..116c37d2cda7b 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -1050,7 +1050,7 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_co u8P2Plocalrandom = 0x01; u8P2Precvrandom = 0x00; bWilc_ie = false; - pstrWFIDrv->u64P2p_MgmtTimeout = 0; + pstrWFIDrv->p2p_timeout = 0; s32Error = host_int_disconnect(priv->hWILCWFIDrv, reason_code); if (s32Error != 0) { @@ -1958,7 +1958,7 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) if (ieee80211_is_action(buff[FRAME_TYPE_ID])) { PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]); - if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->u64P2p_MgmtTimeout)) { + if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) { PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n"); return; } @@ -2331,10 +2331,10 @@ static int mgmt_tx(struct wiphy *wiphy, } PRINT_D(GENERIC_DBG, "TX: ACTION FRAME Type:%x : Chan:%d\n", buf[ACTION_SUBTYPE_ID], chan->hw_value); - pstrWFIDrv->u64P2p_MgmtTimeout = (jiffies + msecs_to_jiffies(wait)); - - PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n", jiffies, pstrWFIDrv->u64P2p_MgmtTimeout); + pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait)); + PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n", + jiffies, pstrWFIDrv->p2p_timeout); } wilc_wlan_txq_add_mgmt_pkt(mgmt_tx, mgmt_tx->buff, @@ -2358,7 +2358,7 @@ static int mgmt_tx_cancel_wait(struct wiphy *wiphy, PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies); - pstrWFIDrv->u64P2p_MgmtTimeout = jiffies; + pstrWFIDrv->p2p_timeout = jiffies; if (!priv->bInP2PlistenState) { cfg80211_remain_on_channel_expired(priv->wdev, -- GitLab From ab16ec0b813f9f52780e6e43549e7ae171e0b3a9 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:40 +0900 Subject: [PATCH 0194/2855] staging: wilc1000: rename u8P2PConnect of struct host_if_drv This patch renames u8P2PConnect of struct host_if_drv to p2p_connect to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.h | 2 +- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index c9a4ce8dfc7ee..60dcc364e7563 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -265,7 +265,7 @@ struct host_if_drv { struct remain_ch remain_on_ch; u8 remain_on_ch_pending; u64 p2p_timeout; - u8 u8P2PConnect; + u8 p2p_connect; enum host_if_state hif_state; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 116c37d2cda7b..4828deb24e681 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -564,7 +564,7 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, eth_zero_addr(u8ConnectedSSID); /*Invalidate u8WLANChannel value on wlan0 disconnect*/ - if (!pstrWFIDrv->u8P2PConnect) + if (!pstrWFIDrv->p2p_connect) u8WLANChannel = INVALID_CHANNEL; PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus); @@ -623,7 +623,7 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, eth_zero_addr(u8ConnectedSSID); /*Invalidate u8WLANChannel value on wlan0 disconnect*/ - if (!pstrWFIDrv->u8P2PConnect) + if (!pstrWFIDrv->p2p_connect) u8WLANChannel = INVALID_CHANNEL; /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change * virtual interface to station*/ @@ -804,9 +804,10 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, PRINT_D(CFG80211_DBG, "Connecting to SSID [%s] on netdev [%p] host if [%p]\n", sme->ssid, dev, priv->hWILCWFIDrv); if (!(strncmp(sme->ssid, "DIRECT-", 7))) { PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n"); - pstrWFIDrv->u8P2PConnect = 1; - } else - pstrWFIDrv->u8P2PConnect = 0; + pstrWFIDrv->p2p_connect = 1; + } else { + pstrWFIDrv->p2p_connect = 0; + } PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type); for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) { @@ -997,9 +998,8 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, curr_channel = pstrNetworkInfo->u8channel; - if (!pstrWFIDrv->u8P2PConnect) { + if (!pstrWFIDrv->p2p_connect) u8WLANChannel = pstrNetworkInfo->u8channel; - } linux_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid); @@ -1041,7 +1041,7 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_co /*Invalidate u8WLANChannel value on wlan0 disconnect*/ pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv; - if (!pstrWFIDrv->u8P2PConnect) + if (!pstrWFIDrv->p2p_connect) u8WLANChannel = INVALID_CHANNEL; linux_wlan_set_bssid(priv->dev, NullBssid); -- GitLab From 2353c388de7719f8b566fc68f8499018cb5b4a56 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:41 +0900 Subject: [PATCH 0195/2855] staging: wilc1000: rename au8BSSID of struct add_sta_param This patch renames au8BSSID of struct add_sta_param to bssid to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 +- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 10 ++++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 00f271780b838..2cf3ed5bd1cc6 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2308,7 +2308,7 @@ static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer, pu8CurrByte = pu8Buffer; PRINT_D(HOSTINF_DBG, "Packing STA params\n"); - memcpy(pu8CurrByte, pstrStationParam->au8BSSID, ETH_ALEN); + memcpy(pu8CurrByte, pstrStationParam->bssid, ETH_ALEN); pu8CurrByte += ETH_ALEN; *pu8CurrByte++ = pstrStationParam->u16AssocID & 0xFF; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 60dcc364e7563..58e4f920504af 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -288,7 +288,7 @@ struct host_if_drv { }; struct add_sta_param { - u8 au8BSSID[ETH_ALEN]; + u8 bssid[ETH_ALEN]; u16 u16AssocID; u8 u8NumRates; const u8 *pu8Rates; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 4828deb24e681..2ec85f037a7ad 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -2995,7 +2995,7 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, nic = netdev_priv(dev); if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) { - memcpy(strStaParams.au8BSSID, mac, ETH_ALEN); + memcpy(strStaParams.bssid, mac, ETH_ALEN); memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN); strStaParams.u16AssocID = params->aid; strStaParams.u8NumRates = params->supported_rates_len; @@ -3109,13 +3109,15 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, nic = netdev_priv(dev); if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) { - memcpy(strStaParams.au8BSSID, mac, ETH_ALEN); + memcpy(strStaParams.bssid, mac, ETH_ALEN); strStaParams.u16AssocID = params->aid; strStaParams.u8NumRates = params->supported_rates_len; strStaParams.pu8Rates = params->supported_rates; - PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n", strStaParams.au8BSSID[0], strStaParams.au8BSSID[1], strStaParams.au8BSSID[2], strStaParams.au8BSSID[3], strStaParams.au8BSSID[4], - strStaParams.au8BSSID[5]); + PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n", + strStaParams.bssid[0], strStaParams.bssid[1], + strStaParams.bssid[2], strStaParams.bssid[3], + strStaParams.bssid[4], strStaParams.bssid[5]); PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.u16AssocID); PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n", strStaParams.u8NumRates); -- GitLab From 4101eb8a0cd4ec53ead18d49314271e83f18bcab Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:42 +0900 Subject: [PATCH 0196/2855] staging: wilc1000: rename u16AssocID of struct add_sta_param This patch renames u16AssocID of struct add_sta_param to aid to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 2cf3ed5bd1cc6..512000e986a8e 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2311,8 +2311,8 @@ static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer, memcpy(pu8CurrByte, pstrStationParam->bssid, ETH_ALEN); pu8CurrByte += ETH_ALEN; - *pu8CurrByte++ = pstrStationParam->u16AssocID & 0xFF; - *pu8CurrByte++ = (pstrStationParam->u16AssocID >> 8) & 0xFF; + *pu8CurrByte++ = pstrStationParam->aid & 0xFF; + *pu8CurrByte++ = (pstrStationParam->aid >> 8) & 0xFF; *pu8CurrByte++ = pstrStationParam->u8NumRates; if (pstrStationParam->u8NumRates > 0) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 58e4f920504af..7d8a166307631 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -289,7 +289,7 @@ struct host_if_drv { struct add_sta_param { u8 bssid[ETH_ALEN]; - u16 u16AssocID; + u16 aid; u8 u8NumRates; const u8 *pu8Rates; bool bIsHTSupported; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 2ec85f037a7ad..00fa41133f034 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -2997,7 +2997,7 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) { memcpy(strStaParams.bssid, mac, ETH_ALEN); memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN); - strStaParams.u16AssocID = params->aid; + strStaParams.aid = params->aid; strStaParams.u8NumRates = params->supported_rates_len; strStaParams.pu8Rates = params->supported_rates; @@ -3005,7 +3005,7 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n", priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][0], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][1], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][2], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][3], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][4], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]); - PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.u16AssocID); + PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid); PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n", strStaParams.u8NumRates); if (params->ht_capa == NULL) { @@ -3110,7 +3110,7 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) { memcpy(strStaParams.bssid, mac, ETH_ALEN); - strStaParams.u16AssocID = params->aid; + strStaParams.aid = params->aid; strStaParams.u8NumRates = params->supported_rates_len; strStaParams.pu8Rates = params->supported_rates; @@ -3118,7 +3118,7 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.bssid[0], strStaParams.bssid[1], strStaParams.bssid[2], strStaParams.bssid[3], strStaParams.bssid[4], strStaParams.bssid[5]); - PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.u16AssocID); + PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid); PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n", strStaParams.u8NumRates); if (params->ht_capa == NULL) { -- GitLab From e734223cd8819bb07b671afa5a25e0ca6abaa3a9 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:43 +0900 Subject: [PATCH 0197/2855] staging: wilc1000: rename u8NumRates of struct add_sta_param This patch renames u8NumRates of struct add_sta_param to rates_len to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 27 ++++++++++--------- drivers/staging/wilc1000/host_interface.h | 2 +- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 10 ++++--- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 512000e986a8e..9b76acd6f011b 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2314,10 +2314,11 @@ static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer, *pu8CurrByte++ = pstrStationParam->aid & 0xFF; *pu8CurrByte++ = (pstrStationParam->aid >> 8) & 0xFF; - *pu8CurrByte++ = pstrStationParam->u8NumRates; - if (pstrStationParam->u8NumRates > 0) - memcpy(pu8CurrByte, pstrStationParam->pu8Rates, pstrStationParam->u8NumRates); - pu8CurrByte += pstrStationParam->u8NumRates; + *pu8CurrByte++ = pstrStationParam->rates_len; + if (pstrStationParam->rates_len > 0) + memcpy(pu8CurrByte, pstrStationParam->pu8Rates, + pstrStationParam->rates_len); + pu8CurrByte += pstrStationParam->rates_len; *pu8CurrByte++ = pstrStationParam->bIsHTSupported; *pu8CurrByte++ = pstrStationParam->u16HTCapInfo & 0xFF; @@ -2356,7 +2357,7 @@ static void Handle_AddStation(struct host_if_drv *hif_drv, PRINT_D(HOSTINF_DBG, "Handling add station\n"); wid.id = (u16)WID_ADD_STA; wid.type = WID_BIN; - wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates; + wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->rates_len; wid.val = kmalloc(wid.size, GFP_KERNEL); if (!wid.val) @@ -2457,7 +2458,7 @@ static void Handle_EditStation(struct host_if_drv *hif_drv, wid.id = (u16)WID_EDIT_STA; wid.type = WID_BIN; - wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates; + wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->rates_len; PRINT_D(HOSTINF_DBG, "Handling edit station\n"); wid.val = kmalloc(wid.size, GFP_KERNEL); @@ -4545,13 +4546,14 @@ s32 host_int_add_station(struct host_if_drv *hif_drv, msg.drv = hif_drv; memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param)); - if (pstrAddStationMsg->u8NumRates > 0) { - u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL); + if (pstrAddStationMsg->rates_len > 0) { + u8 *rates = kmalloc(pstrAddStationMsg->rates_len, GFP_KERNEL); if (!rates) return -ENOMEM; - memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates); + memcpy(rates, pstrStaParams->pu8Rates, + pstrAddStationMsg->rates_len); pstrAddStationMsg->pu8Rates = rates; } @@ -4661,13 +4663,14 @@ s32 host_int_edit_station(struct host_if_drv *hif_drv, msg.drv = hif_drv; memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param)); - if (pstrAddStationMsg->u8NumRates > 0) { - u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL); + if (pstrAddStationMsg->rates_len > 0) { + u8 *rates = kmalloc(pstrAddStationMsg->rates_len, GFP_KERNEL); if (!rates) return -ENOMEM; - memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates); + memcpy(rates, pstrStaParams->pu8Rates, + pstrAddStationMsg->rates_len); pstrAddStationMsg->pu8Rates = rates; } diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 7d8a166307631..b13c76ed7fe18 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -290,7 +290,7 @@ struct host_if_drv { struct add_sta_param { u8 bssid[ETH_ALEN]; u16 aid; - u8 u8NumRates; + u8 rates_len; const u8 *pu8Rates; bool bIsHTSupported; u16 u16HTCapInfo; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 00fa41133f034..715499aeebe62 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -2998,7 +2998,7 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, memcpy(strStaParams.bssid, mac, ETH_ALEN); memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN); strStaParams.aid = params->aid; - strStaParams.u8NumRates = params->supported_rates_len; + strStaParams.rates_len = params->supported_rates_len; strStaParams.pu8Rates = params->supported_rates; PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid); @@ -3006,7 +3006,8 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n", priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][0], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][1], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][2], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][3], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][4], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]); PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid); - PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n", strStaParams.u8NumRates); + PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n", + strStaParams.rates_len); if (params->ht_capa == NULL) { strStaParams.bIsHTSupported = false; @@ -3111,7 +3112,7 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) { memcpy(strStaParams.bssid, mac, ETH_ALEN); strStaParams.aid = params->aid; - strStaParams.u8NumRates = params->supported_rates_len; + strStaParams.rates_len = params->supported_rates_len; strStaParams.pu8Rates = params->supported_rates; PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n", @@ -3119,7 +3120,8 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.bssid[2], strStaParams.bssid[3], strStaParams.bssid[4], strStaParams.bssid[5]); PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid); - PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n", strStaParams.u8NumRates); + PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n", + strStaParams.rates_len); if (params->ht_capa == NULL) { strStaParams.bIsHTSupported = false; -- GitLab From a622e01645f650f217bbb0248b741fa83b3e5027 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:44 +0900 Subject: [PATCH 0198/2855] staging: wilc1000: rename pu8Rates of struct add_sta_param This patch renames pu8Rates of struct add_sta_param to rates to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 14 +++++++------- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 9b76acd6f011b..910462af0f381 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2316,7 +2316,7 @@ static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer, *pu8CurrByte++ = pstrStationParam->rates_len; if (pstrStationParam->rates_len > 0) - memcpy(pu8CurrByte, pstrStationParam->pu8Rates, + memcpy(pu8CurrByte, pstrStationParam->rates, pstrStationParam->rates_len); pu8CurrByte += pstrStationParam->rates_len; @@ -2372,7 +2372,7 @@ static void Handle_AddStation(struct host_if_drv *hif_drv, PRINT_ER("Failed to send add station config packet\n"); ERRORHANDLER: - kfree(pstrStationParam->pu8Rates); + kfree(pstrStationParam->rates); kfree(wid.val); } @@ -2474,7 +2474,7 @@ static void Handle_EditStation(struct host_if_drv *hif_drv, PRINT_ER("Failed to send edit station config packet\n"); ERRORHANDLER: - kfree(pstrStationParam->pu8Rates); + kfree(pstrStationParam->rates); kfree(wid.val); } @@ -4552,9 +4552,9 @@ s32 host_int_add_station(struct host_if_drv *hif_drv, if (!rates) return -ENOMEM; - memcpy(rates, pstrStaParams->pu8Rates, + memcpy(rates, pstrStaParams->rates, pstrAddStationMsg->rates_len); - pstrAddStationMsg->pu8Rates = rates; + pstrAddStationMsg->rates = rates; } result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -4669,9 +4669,9 @@ s32 host_int_edit_station(struct host_if_drv *hif_drv, if (!rates) return -ENOMEM; - memcpy(rates, pstrStaParams->pu8Rates, + memcpy(rates, pstrStaParams->rates, pstrAddStationMsg->rates_len); - pstrAddStationMsg->pu8Rates = rates; + pstrAddStationMsg->rates = rates; } result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index b13c76ed7fe18..5fba44f8f335d 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -291,7 +291,7 @@ struct add_sta_param { u8 bssid[ETH_ALEN]; u16 aid; u8 rates_len; - const u8 *pu8Rates; + const u8 *rates; bool bIsHTSupported; u16 u16HTCapInfo; u8 u8AmpduParams; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 715499aeebe62..019364a794a74 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -2999,7 +2999,7 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN); strStaParams.aid = params->aid; strStaParams.rates_len = params->supported_rates_len; - strStaParams.pu8Rates = params->supported_rates; + strStaParams.rates = params->supported_rates; PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid); @@ -3113,7 +3113,7 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, memcpy(strStaParams.bssid, mac, ETH_ALEN); strStaParams.aid = params->aid; strStaParams.rates_len = params->supported_rates_len; - strStaParams.pu8Rates = params->supported_rates; + strStaParams.rates = params->supported_rates; PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n", strStaParams.bssid[0], strStaParams.bssid[1], -- GitLab From 2252012081cf155e31c82bd901032b17f6705c90 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:45 +0900 Subject: [PATCH 0199/2855] staging: wilc1000: rename bIsHTSupported of struct add_sta_param This patch renames bIsHTSupported of struct add_sta_param to ht_supported to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 +- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 14 ++++++++------ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 910462af0f381..fbfaf12b37314 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2320,7 +2320,7 @@ static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer, pstrStationParam->rates_len); pu8CurrByte += pstrStationParam->rates_len; - *pu8CurrByte++ = pstrStationParam->bIsHTSupported; + *pu8CurrByte++ = pstrStationParam->ht_supported; *pu8CurrByte++ = pstrStationParam->u16HTCapInfo & 0xFF; *pu8CurrByte++ = (pstrStationParam->u16HTCapInfo >> 8) & 0xFF; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 5fba44f8f335d..2d9d8086bcd66 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -292,7 +292,7 @@ struct add_sta_param { u16 aid; u8 rates_len; const u8 *rates; - bool bIsHTSupported; + bool ht_supported; u16 u16HTCapInfo; u8 u8AmpduParams; u8 au8SuppMCsSet[16]; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 019364a794a74..d5b5158b5f7ea 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -3010,9 +3010,9 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.rates_len); if (params->ht_capa == NULL) { - strStaParams.bIsHTSupported = false; + strStaParams.ht_supported = false; } else { - strStaParams.bIsHTSupported = true; + strStaParams.ht_supported = true; strStaParams.u16HTCapInfo = params->ht_capa->cap_info; strStaParams.u8AmpduParams = params->ht_capa->ampdu_params_info; memcpy(strStaParams.au8SuppMCsSet, ¶ms->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE); @@ -3024,7 +3024,8 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.u16FlagsMask = params->sta_flags_mask; strStaParams.u16FlagsSet = params->sta_flags_set; - PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", strStaParams.bIsHTSupported); + PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", + strStaParams.ht_supported); PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n", strStaParams.u16HTCapInfo); PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", strStaParams.u8AmpduParams); PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.u16HTExtParams); @@ -3124,9 +3125,9 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.rates_len); if (params->ht_capa == NULL) { - strStaParams.bIsHTSupported = false; + strStaParams.ht_supported = false; } else { - strStaParams.bIsHTSupported = true; + strStaParams.ht_supported = true; strStaParams.u16HTCapInfo = params->ht_capa->cap_info; strStaParams.u8AmpduParams = params->ht_capa->ampdu_params_info; memcpy(strStaParams.au8SuppMCsSet, ¶ms->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE); @@ -3139,7 +3140,8 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.u16FlagsMask = params->sta_flags_mask; strStaParams.u16FlagsSet = params->sta_flags_set; - PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", strStaParams.bIsHTSupported); + PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", + strStaParams.ht_supported); PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n", strStaParams.u16HTCapInfo); PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", strStaParams.u8AmpduParams); PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.u16HTExtParams); -- GitLab From 0d073f69b1823e7f0f8252bcbfffe25fffdb6723 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:46 +0900 Subject: [PATCH 0200/2855] staging: wilc1000: rename u16HTCapInfo of struct add_sta_param This patch renames u16HTCapInfo of struct add_sta_param to ht_capa_info to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 10 ++++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index fbfaf12b37314..e6388ffae6d2c 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2321,8 +2321,8 @@ static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer, pu8CurrByte += pstrStationParam->rates_len; *pu8CurrByte++ = pstrStationParam->ht_supported; - *pu8CurrByte++ = pstrStationParam->u16HTCapInfo & 0xFF; - *pu8CurrByte++ = (pstrStationParam->u16HTCapInfo >> 8) & 0xFF; + *pu8CurrByte++ = pstrStationParam->ht_capa_info & 0xFF; + *pu8CurrByte++ = (pstrStationParam->ht_capa_info >> 8) & 0xFF; *pu8CurrByte++ = pstrStationParam->u8AmpduParams; memcpy(pu8CurrByte, pstrStationParam->au8SuppMCsSet, WILC_SUPP_MCS_SET_SIZE); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 2d9d8086bcd66..782088fadc0e9 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -293,7 +293,7 @@ struct add_sta_param { u8 rates_len; const u8 *rates; bool ht_supported; - u16 u16HTCapInfo; + u16 ht_capa_info; u8 u8AmpduParams; u8 au8SuppMCsSet[16]; u16 u16HTExtParams; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index d5b5158b5f7ea..0d465c1119bc8 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -3013,7 +3013,7 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_supported = false; } else { strStaParams.ht_supported = true; - strStaParams.u16HTCapInfo = params->ht_capa->cap_info; + strStaParams.ht_capa_info = params->ht_capa->cap_info; strStaParams.u8AmpduParams = params->ht_capa->ampdu_params_info; memcpy(strStaParams.au8SuppMCsSet, ¶ms->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE); strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info; @@ -3026,7 +3026,8 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", strStaParams.ht_supported); - PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n", strStaParams.u16HTCapInfo); + PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n", + strStaParams.ht_capa_info); PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", strStaParams.u8AmpduParams); PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.u16HTExtParams); PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.u32TxBeamformingCap); @@ -3128,7 +3129,7 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_supported = false; } else { strStaParams.ht_supported = true; - strStaParams.u16HTCapInfo = params->ht_capa->cap_info; + strStaParams.ht_capa_info = params->ht_capa->cap_info; strStaParams.u8AmpduParams = params->ht_capa->ampdu_params_info; memcpy(strStaParams.au8SuppMCsSet, ¶ms->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE); strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info; @@ -3142,7 +3143,8 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", strStaParams.ht_supported); - PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n", strStaParams.u16HTCapInfo); + PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n", + strStaParams.ht_capa_info); PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", strStaParams.u8AmpduParams); PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.u16HTExtParams); PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.u32TxBeamformingCap); -- GitLab From fba1f2d221b806b8e0e31939c595f05a87e3bf36 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:47 +0900 Subject: [PATCH 0201/2855] staging: wilc1000: rename u8AmpduParams of struct add_sta_param This patch renames u8AmpduParams of struct add_sta_param to ht_ampdu_params to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 +- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 10 ++++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index e6388ffae6d2c..8f7d3027ba1c2 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2324,7 +2324,7 @@ static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer, *pu8CurrByte++ = pstrStationParam->ht_capa_info & 0xFF; *pu8CurrByte++ = (pstrStationParam->ht_capa_info >> 8) & 0xFF; - *pu8CurrByte++ = pstrStationParam->u8AmpduParams; + *pu8CurrByte++ = pstrStationParam->ht_ampdu_params; memcpy(pu8CurrByte, pstrStationParam->au8SuppMCsSet, WILC_SUPP_MCS_SET_SIZE); pu8CurrByte += WILC_SUPP_MCS_SET_SIZE; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 782088fadc0e9..bb3bf077e9ced 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -294,7 +294,7 @@ struct add_sta_param { const u8 *rates; bool ht_supported; u16 ht_capa_info; - u8 u8AmpduParams; + u8 ht_ampdu_params; u8 au8SuppMCsSet[16]; u16 u16HTExtParams; u32 u32TxBeamformingCap; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 0d465c1119bc8..5ea7bd2ededba 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -3014,7 +3014,7 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, } else { strStaParams.ht_supported = true; strStaParams.ht_capa_info = params->ht_capa->cap_info; - strStaParams.u8AmpduParams = params->ht_capa->ampdu_params_info; + strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info; memcpy(strStaParams.au8SuppMCsSet, ¶ms->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE); strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info; strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info; @@ -3028,7 +3028,8 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_supported); PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n", strStaParams.ht_capa_info); - PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", strStaParams.u8AmpduParams); + PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", + strStaParams.ht_ampdu_params); PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.u16HTExtParams); PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.u32TxBeamformingCap); PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.u8ASELCap); @@ -3130,7 +3131,7 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, } else { strStaParams.ht_supported = true; strStaParams.ht_capa_info = params->ht_capa->cap_info; - strStaParams.u8AmpduParams = params->ht_capa->ampdu_params_info; + strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info; memcpy(strStaParams.au8SuppMCsSet, ¶ms->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE); strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info; strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info; @@ -3145,7 +3146,8 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_supported); PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n", strStaParams.ht_capa_info); - PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", strStaParams.u8AmpduParams); + PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", + strStaParams.ht_ampdu_params); PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.u16HTExtParams); PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.u32TxBeamformingCap); PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.u8ASELCap); -- GitLab From 5ebbf4f74888f8ef9ee07864de6251dd81d1a359 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:48 +0900 Subject: [PATCH 0202/2855] staging: wilc1000: rename au8SuppMCsSet of struct add_sta_param This patch renames au8SuppMCsSet of struct add_sta_param to ht_supp_mcs_set to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 3 ++- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 8 ++++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 8f7d3027ba1c2..d0a65c79ee887 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2325,7 +2325,8 @@ static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer, *pu8CurrByte++ = (pstrStationParam->ht_capa_info >> 8) & 0xFF; *pu8CurrByte++ = pstrStationParam->ht_ampdu_params; - memcpy(pu8CurrByte, pstrStationParam->au8SuppMCsSet, WILC_SUPP_MCS_SET_SIZE); + memcpy(pu8CurrByte, pstrStationParam->ht_supp_mcs_set, + WILC_SUPP_MCS_SET_SIZE); pu8CurrByte += WILC_SUPP_MCS_SET_SIZE; *pu8CurrByte++ = pstrStationParam->u16HTExtParams & 0xFF; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index bb3bf077e9ced..798adcf078dd5 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -295,7 +295,7 @@ struct add_sta_param { bool ht_supported; u16 ht_capa_info; u8 ht_ampdu_params; - u8 au8SuppMCsSet[16]; + u8 ht_supp_mcs_set[16]; u16 u16HTExtParams; u32 u32TxBeamformingCap; u8 u8ASELCap; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 5ea7bd2ededba..ef308da53b406 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -3015,7 +3015,9 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_supported = true; strStaParams.ht_capa_info = params->ht_capa->cap_info; strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info; - memcpy(strStaParams.au8SuppMCsSet, ¶ms->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE); + memcpy(strStaParams.ht_supp_mcs_set, + ¶ms->ht_capa->mcs, + WILC_SUPP_MCS_SET_SIZE); strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info; strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info; strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info; @@ -3132,7 +3134,9 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_supported = true; strStaParams.ht_capa_info = params->ht_capa->cap_info; strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info; - memcpy(strStaParams.au8SuppMCsSet, ¶ms->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE); + memcpy(strStaParams.ht_supp_mcs_set, + ¶ms->ht_capa->mcs, + WILC_SUPP_MCS_SET_SIZE); strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info; strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info; strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info; -- GitLab From 223741d71ee66e311a34176f154d979a62b32a70 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:49 +0900 Subject: [PATCH 0203/2855] staging: wilc1000: rename u16HTExtParams of struct add_sta_param This patch renames u16HTExtParams of struct add_sta_param to ht_ext_params to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 10 ++++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index d0a65c79ee887..be1fcbd37eec7 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2329,8 +2329,8 @@ static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer, WILC_SUPP_MCS_SET_SIZE); pu8CurrByte += WILC_SUPP_MCS_SET_SIZE; - *pu8CurrByte++ = pstrStationParam->u16HTExtParams & 0xFF; - *pu8CurrByte++ = (pstrStationParam->u16HTExtParams >> 8) & 0xFF; + *pu8CurrByte++ = pstrStationParam->ht_ext_params & 0xFF; + *pu8CurrByte++ = (pstrStationParam->ht_ext_params >> 8) & 0xFF; *pu8CurrByte++ = pstrStationParam->u32TxBeamformingCap & 0xFF; *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 8) & 0xFF; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 798adcf078dd5..c8e2d3fea6f80 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -296,7 +296,7 @@ struct add_sta_param { u16 ht_capa_info; u8 ht_ampdu_params; u8 ht_supp_mcs_set[16]; - u16 u16HTExtParams; + u16 ht_ext_params; u32 u32TxBeamformingCap; u8 u8ASELCap; u16 u16FlagsMask; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index ef308da53b406..e41778587e64b 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -3018,7 +3018,7 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, memcpy(strStaParams.ht_supp_mcs_set, ¶ms->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE); - strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info; + strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info; strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info; strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info; } @@ -3032,7 +3032,8 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_capa_info); PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", strStaParams.ht_ampdu_params); - PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.u16HTExtParams); + PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", + strStaParams.ht_ext_params); PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.u32TxBeamformingCap); PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.u8ASELCap); PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.u16FlagsMask); @@ -3137,7 +3138,7 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, memcpy(strStaParams.ht_supp_mcs_set, ¶ms->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE); - strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info; + strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info; strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info; strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info; @@ -3152,7 +3153,8 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_capa_info); PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", strStaParams.ht_ampdu_params); - PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.u16HTExtParams); + PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", + strStaParams.ht_ext_params); PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.u32TxBeamformingCap); PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.u8ASELCap); PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.u16FlagsMask); -- GitLab From 74fe73cf081f98b90aa7914fa3f879bf77e31f78 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:50 +0900 Subject: [PATCH 0204/2855] staging: wilc1000: rename u32TxBeamformingCap of struct add_sta_param This patch renames u32TxBeamformingCap of struct add_sta_param to ht_tx_bf_cap to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 8 ++++---- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 10 ++++++---- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index be1fcbd37eec7..41ccd80b3d84a 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2332,10 +2332,10 @@ static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer, *pu8CurrByte++ = pstrStationParam->ht_ext_params & 0xFF; *pu8CurrByte++ = (pstrStationParam->ht_ext_params >> 8) & 0xFF; - *pu8CurrByte++ = pstrStationParam->u32TxBeamformingCap & 0xFF; - *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 8) & 0xFF; - *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 16) & 0xFF; - *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 24) & 0xFF; + *pu8CurrByte++ = pstrStationParam->ht_tx_bf_cap & 0xFF; + *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 8) & 0xFF; + *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 16) & 0xFF; + *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 24) & 0xFF; *pu8CurrByte++ = pstrStationParam->u8ASELCap; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index c8e2d3fea6f80..3311d2faf59df 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -297,7 +297,7 @@ struct add_sta_param { u8 ht_ampdu_params; u8 ht_supp_mcs_set[16]; u16 ht_ext_params; - u32 u32TxBeamformingCap; + u32 ht_tx_bf_cap; u8 u8ASELCap; u16 u16FlagsMask; u16 u16FlagsSet; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index e41778587e64b..abd90963e5ad3 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -3019,7 +3019,7 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, ¶ms->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE); strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info; - strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info; + strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info; strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info; } @@ -3034,7 +3034,8 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_ampdu_params); PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.ht_ext_params); - PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.u32TxBeamformingCap); + PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", + strStaParams.ht_tx_bf_cap); PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.u8ASELCap); PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.u16FlagsMask); PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.u16FlagsSet); @@ -3139,7 +3140,7 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, ¶ms->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE); strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info; - strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info; + strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info; strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info; } @@ -3155,7 +3156,8 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_ampdu_params); PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.ht_ext_params); - PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.u32TxBeamformingCap); + PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", + strStaParams.ht_tx_bf_cap); PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.u8ASELCap); PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.u16FlagsMask); PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.u16FlagsSet); -- GitLab From a486baff710b4f761749ca16e3ff6b1cb0fe63dd Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:51 +0900 Subject: [PATCH 0205/2855] staging: wilc1000: rename u8ASELCap of struct add_sta_param This patch renames u8ASELCap of struct add_sta_param to ht_ante_sel to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 +- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 11 ++++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 41ccd80b3d84a..5a2e874d4d71e 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2337,7 +2337,7 @@ static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer, *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 16) & 0xFF; *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 24) & 0xFF; - *pu8CurrByte++ = pstrStationParam->u8ASELCap; + *pu8CurrByte++ = pstrStationParam->ht_ante_sel; *pu8CurrByte++ = pstrStationParam->u16FlagsMask & 0xFF; *pu8CurrByte++ = (pstrStationParam->u16FlagsMask >> 8) & 0xFF; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 3311d2faf59df..5ad0bfa84f00c 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -298,7 +298,7 @@ struct add_sta_param { u8 ht_supp_mcs_set[16]; u16 ht_ext_params; u32 ht_tx_bf_cap; - u8 u8ASELCap; + u8 ht_ante_sel; u16 u16FlagsMask; u16 u16FlagsSet; }; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index abd90963e5ad3..a2c08783f4051 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -3020,7 +3020,7 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, WILC_SUPP_MCS_SET_SIZE); strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info; strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info; - strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info; + strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info; } strStaParams.u16FlagsMask = params->sta_flags_mask; @@ -3036,7 +3036,8 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_ext_params); PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.ht_tx_bf_cap); - PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.u8ASELCap); + PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", + strStaParams.ht_ante_sel); PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.u16FlagsMask); PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.u16FlagsSet); @@ -3141,8 +3142,7 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, WILC_SUPP_MCS_SET_SIZE); strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info; strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info; - strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info; - + strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info; } strStaParams.u16FlagsMask = params->sta_flags_mask; @@ -3158,7 +3158,8 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_ext_params); PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.ht_tx_bf_cap); - PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.u8ASELCap); + PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", + strStaParams.ht_ante_sel); PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.u16FlagsMask); PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.u16FlagsSet); -- GitLab From f676e17a716d109b853a6237ffe6c9137c9e3b92 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:52 +0900 Subject: [PATCH 0206/2855] staging: wilc1000: rename u16FlagsMask of struct add_sta_param This patch renames u16FlagsMask of struct add_sta_param to flags_mask to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 10 ++++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 5a2e874d4d71e..258dabd24dd77 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2339,8 +2339,8 @@ static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer, *pu8CurrByte++ = pstrStationParam->ht_ante_sel; - *pu8CurrByte++ = pstrStationParam->u16FlagsMask & 0xFF; - *pu8CurrByte++ = (pstrStationParam->u16FlagsMask >> 8) & 0xFF; + *pu8CurrByte++ = pstrStationParam->flags_mask & 0xFF; + *pu8CurrByte++ = (pstrStationParam->flags_mask >> 8) & 0xFF; *pu8CurrByte++ = pstrStationParam->u16FlagsSet & 0xFF; *pu8CurrByte++ = (pstrStationParam->u16FlagsSet >> 8) & 0xFF; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 5ad0bfa84f00c..1422b90b31731 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -299,7 +299,7 @@ struct add_sta_param { u16 ht_ext_params; u32 ht_tx_bf_cap; u8 ht_ante_sel; - u16 u16FlagsMask; + u16 flags_mask; u16 u16FlagsSet; }; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index a2c08783f4051..0ae47c5c3a168 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -3023,7 +3023,7 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info; } - strStaParams.u16FlagsMask = params->sta_flags_mask; + strStaParams.flags_mask = params->sta_flags_mask; strStaParams.u16FlagsSet = params->sta_flags_set; PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", @@ -3038,7 +3038,8 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_tx_bf_cap); PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.ht_ante_sel); - PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.u16FlagsMask); + PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", + strStaParams.flags_mask); PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.u16FlagsSet); s32Error = host_int_add_station(priv->hWILCWFIDrv, &strStaParams); @@ -3145,7 +3146,7 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info; } - strStaParams.u16FlagsMask = params->sta_flags_mask; + strStaParams.flags_mask = params->sta_flags_mask; strStaParams.u16FlagsSet = params->sta_flags_set; PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", @@ -3160,7 +3161,8 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_tx_bf_cap); PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.ht_ante_sel); - PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.u16FlagsMask); + PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", + strStaParams.flags_mask); PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.u16FlagsSet); s32Error = host_int_edit_station(priv->hWILCWFIDrv, &strStaParams); -- GitLab From 67ab64e44c4658e99d11835913ec30fdb0dba634 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:53 +0900 Subject: [PATCH 0207/2855] staging: wilc1000: rename u16FlagsSet of struct add_sta_param This patch renames u16FlagsSet of struct add_sta_param to flags_set to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 10 ++++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 258dabd24dd77..34b345516a92c 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2342,8 +2342,8 @@ static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer, *pu8CurrByte++ = pstrStationParam->flags_mask & 0xFF; *pu8CurrByte++ = (pstrStationParam->flags_mask >> 8) & 0xFF; - *pu8CurrByte++ = pstrStationParam->u16FlagsSet & 0xFF; - *pu8CurrByte++ = (pstrStationParam->u16FlagsSet >> 8) & 0xFF; + *pu8CurrByte++ = pstrStationParam->flags_set & 0xFF; + *pu8CurrByte++ = (pstrStationParam->flags_set >> 8) & 0xFF; return pu8CurrByte - pu8Buffer; } diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 1422b90b31731..72c47974d2d82 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -300,7 +300,7 @@ struct add_sta_param { u32 ht_tx_bf_cap; u8 ht_ante_sel; u16 flags_mask; - u16 u16FlagsSet; + u16 flags_set; }; s32 host_int_remove_key(struct host_if_drv *hWFIDrv, const u8 *pu8StaAddress); diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 0ae47c5c3a168..4de27ef5b6e49 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -3024,7 +3024,7 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, } strStaParams.flags_mask = params->sta_flags_mask; - strStaParams.u16FlagsSet = params->sta_flags_set; + strStaParams.flags_set = params->sta_flags_set; PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", strStaParams.ht_supported); @@ -3040,7 +3040,8 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_ante_sel); PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.flags_mask); - PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.u16FlagsSet); + PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", + strStaParams.flags_set); s32Error = host_int_add_station(priv->hWILCWFIDrv, &strStaParams); if (s32Error) @@ -3147,7 +3148,7 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, } strStaParams.flags_mask = params->sta_flags_mask; - strStaParams.u16FlagsSet = params->sta_flags_set; + strStaParams.flags_set = params->sta_flags_set; PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", strStaParams.ht_supported); @@ -3163,7 +3164,8 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, strStaParams.ht_ante_sel); PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.flags_mask); - PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.u16FlagsSet); + PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", + strStaParams.flags_set); s32Error = host_int_edit_station(priv->hWILCWFIDrv, &strStaParams); if (s32Error) -- GitLab From 9cf7878c20f9fc7311cbf6f5a34599f769c70882 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:54 +0900 Subject: [PATCH 0208/2855] staging: wilc1000: rename pstrHostIFSetChan of fuction Handle_SetChannel This patch renames pstrHostIFSetChan of fuction Handle_SetChannel to hif_set_ch to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 34b345516a92c..819306b7e9b6f 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -325,14 +325,14 @@ static struct host_if_drv *get_handler_from_id(int id) } static s32 Handle_SetChannel(struct host_if_drv *hif_drv, - struct channel_attr *pstrHostIFSetChan) + struct channel_attr *hif_set_ch) { s32 result = 0; struct wid wid; wid.id = (u16)WID_CURRENT_CHANNEL; wid.type = WID_CHAR; - wid.val = (char *)&pstrHostIFSetChan->set_ch; + wid.val = (char *)&hif_set_ch->set_ch; wid.size = sizeof(char); PRINT_D(HOSTINF_DBG, "Setting channel\n"); -- GitLab From 6b73c7442597ceb664dc02514798c4d5184bd702 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:55 +0900 Subject: [PATCH 0209/2855] staging: wilc1000: rename pstrHostIfSetDrvHandler of fuction Handle_SetWfiDrvHandler This patch renames pstrHostIfSetDrvHandler of fuction Handle_SetWfiDrvHandler to hif_drv_handler to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 819306b7e9b6f..96c6d4a96024a 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -349,18 +349,17 @@ static s32 Handle_SetChannel(struct host_if_drv *hif_drv, } static s32 Handle_SetWfiDrvHandler(struct host_if_drv *hif_drv, - struct drv_handler *pstrHostIfSetDrvHandler) + struct drv_handler *hif_drv_handler) { s32 result = 0; struct wid wid; wid.id = (u16)WID_SET_DRV_HANDLER; wid.type = WID_INT; - wid.val = (s8 *)&pstrHostIfSetDrvHandler->handler; + wid.val = (s8 *)&hif_drv_handler->handler; wid.size = sizeof(u32); - result = send_config_pkt(SET_CFG, &wid, 1, - pstrHostIfSetDrvHandler->handler); + result = send_config_pkt(SET_CFG, &wid, 1, hif_drv_handler->handler); if (!hif_drv) up(&hif_sema_driver); -- GitLab From acff1d71f722f00ef1929df1d3b55bb65322f754 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 29 Oct 2015 12:05:56 +0900 Subject: [PATCH 0210/2855] staging: wilc1000: rename pstrHostIfSetOperationMode of fuction Handle_SetOperationMode This patch renames pstrHostIfSetOperationMode of fuction Handle_SetOperationMode to hif_op_mode to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 96c6d4a96024a..17826f3d4407d 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -373,20 +373,20 @@ static s32 Handle_SetWfiDrvHandler(struct host_if_drv *hif_drv, } static s32 Handle_SetOperationMode(struct host_if_drv *hif_drv, - struct op_mode *pstrHostIfSetOperationMode) + struct op_mode *hif_op_mode) { s32 result = 0; struct wid wid; wid.id = (u16)WID_SET_OPERATION_MODE; wid.type = WID_INT; - wid.val = (s8 *)&pstrHostIfSetOperationMode->mode; + wid.val = (s8 *)&hif_op_mode->mode; wid.size = sizeof(u32); result = send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); - if ((pstrHostIfSetOperationMode->mode) == IDLE_MODE) + if ((hif_op_mode->mode) == IDLE_MODE) up(&hif_sema_driver); if (result) { -- GitLab From 7af0522c99cf9b12f156267fa4185208e90cf4c6 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Thu, 29 Oct 2015 12:18:41 +0900 Subject: [PATCH 0211/2855] staging: wilc1000: wilc_wlan_txq_get_first: add argument struct wilc This patch adds new argument struct wilc and use it instead of g_linux_wlan. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index c026657477052..6c7cbd1125b5d 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -563,17 +563,17 @@ int wilc_wlan_txq_add_mgmt_pkt(void *priv, u8 *buffer, u32 buffer_size, wilc_tx_ return 1; } -static struct txq_entry_t *wilc_wlan_txq_get_first(void) +static struct txq_entry_t *wilc_wlan_txq_get_first(struct wilc *wilc) { wilc_wlan_dev_t *p = &g_wlan; struct txq_entry_t *tqe; unsigned long flags; - spin_lock_irqsave(&g_linux_wlan->txq_spinlock, flags); + spin_lock_irqsave(&wilc->txq_spinlock, flags); tqe = p->txq_head; - spin_unlock_irqrestore(&g_linux_wlan->txq_spinlock, flags); + spin_unlock_irqrestore(&wilc->txq_spinlock, flags); return tqe; @@ -855,7 +855,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) * build the vmm list **/ PRINT_D(TX_DBG, "Getting the head of the TxQ\n"); - tqe = wilc_wlan_txq_get_first(); + tqe = wilc_wlan_txq_get_first(wilc); i = 0; sum = 0; do { -- GitLab From ed760b67f283756cca401085519f0ff1a0996624 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Thu, 29 Oct 2015 12:18:42 +0900 Subject: [PATCH 0212/2855] staging: wilc1000: linux_wlan_firmware_download: change argument This patch changes argument p_nic with wilc and use it instead of g_linux_wlan. Pass argument dev to the function. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 034cfed653b02..79e59babc306c 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -597,12 +597,16 @@ static int linux_wlan_start_firmware(perInterface_wlan_t *nic) _fail_: return ret; } -static int linux_wlan_firmware_download(struct wilc *p_nic) +static int linux_wlan_firmware_download(struct net_device *dev) { - + perInterface_wlan_t *nic; + struct wilc *wilc; int ret = 0; - if (!g_linux_wlan->firmware) { + nic = netdev_priv(dev); + wilc = nic->wilc; + + if (!wilc->firmware) { PRINT_ER("Firmware buffer is NULL\n"); ret = -ENOBUFS; goto _FAIL_; @@ -611,15 +615,15 @@ static int linux_wlan_firmware_download(struct wilc *p_nic) * do the firmware download **/ PRINT_D(INIT_DBG, "Downloading Firmware ...\n"); - ret = wilc_wlan_firmware_download(g_linux_wlan->firmware->data, - g_linux_wlan->firmware->size); + ret = wilc_wlan_firmware_download(wilc->firmware->data, + wilc->firmware->size); if (ret < 0) goto _FAIL_; /* Freeing FW buffer */ PRINT_D(INIT_DBG, "Freeing FW buffer ...\n"); PRINT_D(INIT_DBG, "Releasing firmware\n"); - release_firmware(g_linux_wlan->firmware); + release_firmware(wilc->firmware); PRINT_D(INIT_DBG, "Download Succeeded\n"); @@ -1123,7 +1127,7 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) } /*Download firmware*/ - ret = linux_wlan_firmware_download(wl); + ret = linux_wlan_firmware_download(dev); if (ret < 0) { PRINT_ER("Failed to download firmware\n"); ret = -EIO; -- GitLab From 718fc2c9d4145ade7c97bbeb4f0a5c0e7e800cdd Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Thu, 29 Oct 2015 12:18:43 +0900 Subject: [PATCH 0213/2855] staging: wilc1000: wilc_wlan_txq_remove_from_head: add new argument dev Add new argument dev and use it instead of g_linux_wlan, and pass argument dev to the function as well. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 6c7cbd1125b5d..5dcc4d21fa313 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -159,13 +159,19 @@ static void wilc_wlan_txq_remove(struct txq_entry_t *tqe) } -static struct txq_entry_t *wilc_wlan_txq_remove_from_head(void) +static struct txq_entry_t * +wilc_wlan_txq_remove_from_head(struct net_device *dev) { struct txq_entry_t *tqe; wilc_wlan_dev_t *p = &g_wlan; unsigned long flags; + perInterface_wlan_t *nic; + struct wilc *wilc; - spin_lock_irqsave(&g_linux_wlan->txq_spinlock, flags); + nic = netdev_priv(dev); + wilc = nic->wilc; + + spin_lock_irqsave(&wilc->txq_spinlock, flags); if (p->txq_head) { tqe = p->txq_head; p->txq_head = tqe->next; @@ -180,7 +186,7 @@ static struct txq_entry_t *wilc_wlan_txq_remove_from_head(void) } else { tqe = NULL; } - spin_unlock_irqrestore(&g_linux_wlan->txq_spinlock, flags); + spin_unlock_irqrestore(&wilc->txq_spinlock, flags); return tqe; } @@ -1035,7 +1041,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) offset = 0; i = 0; do { - tqe = wilc_wlan_txq_remove_from_head(); + tqe = wilc_wlan_txq_remove_from_head(dev); if (tqe != NULL && (vmm_table[i] != 0)) { u32 header, buffer_offset; @@ -1668,7 +1674,7 @@ void wilc_wlan_cleanup(struct net_device *dev) p->quit = 1; do { - tqe = wilc_wlan_txq_remove_from_head(); + tqe = wilc_wlan_txq_remove_from_head(dev); if (tqe == NULL) break; if (tqe->tx_complete_func) -- GitLab From 829c477fd4811f7f1b90d8d4fa132d66e193689c Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Thu, 29 Oct 2015 12:18:44 +0900 Subject: [PATCH 0214/2855] staging: wilc1000: wilc_wlan_txq_add_mgmt_pkt: add new argument dev This patch adds new argument struct net_device *dev and pass argument struct net_device to the function. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_mon.c | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 4 ++-- drivers/staging/wilc1000/wilc_wlan.c | 3 ++- drivers/staging/wilc1000/wilc_wlan.h | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/linux_mon.c b/drivers/staging/wilc1000/linux_mon.c index 450af1b77f991..589a11fd977c3 100644 --- a/drivers/staging/wilc1000/linux_mon.c +++ b/drivers/staging/wilc1000/linux_mon.c @@ -195,7 +195,7 @@ static int mon_mgmt_tx(struct net_device *dev, const u8 *buf, size_t len) mgmt_tx->size = len; memcpy(mgmt_tx->buff, buf, len); - wilc_wlan_txq_add_mgmt_pkt(mgmt_tx, mgmt_tx->buff, mgmt_tx->size, + wilc_wlan_txq_add_mgmt_pkt(dev, mgmt_tx, mgmt_tx->buff, mgmt_tx->size, mgmt_tx_complete); netif_wake_queue(dev); diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 4de27ef5b6e49..cdcf134c314a3 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -2337,8 +2337,8 @@ static int mgmt_tx(struct wiphy *wiphy, jiffies, pstrWFIDrv->p2p_timeout); } - wilc_wlan_txq_add_mgmt_pkt(mgmt_tx, mgmt_tx->buff, - mgmt_tx->size, + wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx, + mgmt_tx->buff, mgmt_tx->size, WILC_WFI_mgmt_tx_complete); } else { PRINT_D(GENERIC_DBG, "This function transmits only management frames\n"); diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 5dcc4d21fa313..3dc0a80275ba5 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -543,7 +543,8 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, return p->txq_entries; } -int wilc_wlan_txq_add_mgmt_pkt(void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func) +int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, + u32 buffer_size, wilc_tx_complete_func_t func) { wilc_wlan_dev_t *p = &g_wlan; diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 57e1d51740502..2eb7e207b3abe 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -307,6 +307,6 @@ int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, int commit, u32 drvHandler); int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drvHandler); int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size); -int wilc_wlan_txq_add_mgmt_pkt(void *priv, u8 *buffer, u32 buffer_size, - wilc_tx_complete_func_t func); +int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, + u32 buffer_size, wilc_tx_complete_func_t func); #endif -- GitLab From 32f033287bdf1420b86fd459cbd19c060053037c Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Thu, 29 Oct 2015 12:18:45 +0900 Subject: [PATCH 0215/2855] staging: wilc1000: wilc_wlan_txq_add_to_tail: add argument net_device This patch adds new argument dev and use netdev private data member wilc instead of g_linux_wlan, pass the function dev also. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 3dc0a80275ba5..03593b7e50e23 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -190,11 +190,18 @@ wilc_wlan_txq_remove_from_head(struct net_device *dev) return tqe; } -static void wilc_wlan_txq_add_to_tail(struct txq_entry_t *tqe) +static void wilc_wlan_txq_add_to_tail(struct net_device *dev, + struct txq_entry_t *tqe) { wilc_wlan_dev_t *p = &g_wlan; unsigned long flags; - spin_lock_irqsave(&g_linux_wlan->txq_spinlock, flags); + perInterface_wlan_t *nic; + struct wilc *wilc; + + nic = netdev_priv(dev); + wilc = nic->wilc; + + spin_lock_irqsave(&wilc->txq_spinlock, flags); if (p->txq_head == NULL) { tqe->next = NULL; @@ -210,14 +217,14 @@ static void wilc_wlan_txq_add_to_tail(struct txq_entry_t *tqe) p->txq_entries += 1; PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", p->txq_entries); - spin_unlock_irqrestore(&g_linux_wlan->txq_spinlock, flags); + spin_unlock_irqrestore(&wilc->txq_spinlock, flags); /** * wake up TX queue **/ PRINT_D(TX_DBG, "Wake the txq_handling\n"); - up(&g_linux_wlan->txq_event); + up(&wilc->txq_event); } static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe) @@ -538,7 +545,7 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, if (is_TCP_ACK_Filter_Enabled()) tcp_process(dev, tqe); #endif - wilc_wlan_txq_add_to_tail(tqe); + wilc_wlan_txq_add_to_tail(dev, tqe); /*return number of itemes in the queue*/ return p->txq_entries; } @@ -566,7 +573,7 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, tqe->tcp_PendingAck_index = NOT_TCP_ACK; #endif PRINT_D(TX_DBG, "Adding Network packet at the Queue tail\n"); - wilc_wlan_txq_add_to_tail(tqe); + wilc_wlan_txq_add_to_tail(dev, tqe); return 1; } -- GitLab From 9bf3d7274516debe31e710a209e7d59ffc49d9c0 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Thu, 29 Oct 2015 12:18:46 +0900 Subject: [PATCH 0216/2855] staging: wilc1000: linux_wlan_start_firmware: change argument with dev This patch changes argument nic with dev and use netdev private data member wilc instead of g_linux_wlan, and pass dev to the function as well. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 79e59babc306c..c9a64c14188a8 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -569,10 +569,15 @@ _fail_: } -static int linux_wlan_start_firmware(perInterface_wlan_t *nic) +static int linux_wlan_start_firmware(struct net_device *dev) { - + perInterface_wlan_t *nic; + struct wilc *wilc; int ret = 0; + + nic = netdev_priv(dev); + wilc = nic->wilc; + /* start firmware */ PRINT_D(INIT_DBG, "Starting Firmware ...\n"); ret = wilc_wlan_start(); @@ -583,7 +588,7 @@ static int linux_wlan_start_firmware(perInterface_wlan_t *nic) /* wait for mac ready */ PRINT_D(INIT_DBG, "Waiting for Firmware to get ready ...\n"); - ret = linux_wlan_lock_timeout(&g_linux_wlan->sync_event, 5000); + ret = linux_wlan_lock_timeout(&wilc->sync_event, 5000); if (ret) { PRINT_D(INIT_DBG, "Firmware start timed out"); goto _fail_; @@ -1135,7 +1140,7 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) } /* Start firmware*/ - ret = linux_wlan_start_firmware(nic); + ret = linux_wlan_start_firmware(dev); if (ret < 0) { PRINT_ER("Failed to start firmware\n"); ret = -EIO; -- GitLab From 47a466f1d8569b7122bf782b19ee7ba35b2c8873 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Thu, 29 Oct 2015 12:18:47 +0900 Subject: [PATCH 0217/2855] staging: wilc1000: wilc_wlan_init: add argument struct net_device This patch adds an argument dev and pass dev to the function. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 2 +- drivers/staging/wilc1000/wilc_wlan.c | 2 +- drivers/staging/wilc1000/wilc_wlan_if.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index c9a64c14188a8..fee8c61385b2a 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1095,7 +1095,7 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) linux_to_wlan(&nwi, wl); - ret = wilc_wlan_init(&nwi); + ret = wilc_wlan_init(dev, &nwi); if (ret < 0) { PRINT_ER("Initializing WILC_Wlan FAILED\n"); ret = -EIO; diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 03593b7e50e23..5a480a123acd8 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1951,7 +1951,7 @@ _fail_: return chipid; } -int wilc_wlan_init(wilc_wlan_inp_t *inp) +int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) { int ret = 0; diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index be972afe6e620..139cc6d388945 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -937,7 +937,7 @@ typedef enum { WID_MAX = 0xFFFF } WID_T; -int wilc_wlan_init(wilc_wlan_inp_t *inp); +int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp); void wilc_bus_set_max_speed(void); void wilc_bus_set_default_speed(void); -- GitLab From ae6f772ddf715599d5d23d498f368e389735aac5 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Thu, 29 Oct 2015 12:18:48 +0900 Subject: [PATCH 0218/2855] staging: wilc1000: wilc_wlan_init: add argument net_device This patch adds new argument struct net_device and pass the function dev. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 5a480a123acd8..16224cefea791 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1870,7 +1870,7 @@ void wilc_bus_set_default_speed(void) /* Restore bus speed to default. */ g_wlan.hif_func.hif_set_default_bus_speed(); } -u32 init_chip(void) +u32 init_chip(struct net_device *dev) { u32 chipid; u32 reg, ret = 0; @@ -2028,7 +2028,7 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) } #endif - if (!init_chip()) { + if (!init_chip(dev)) { /* EIO 5 */ ret = -5; goto _fail_; -- GitLab From 65c8adcfd8740976eb471272741278989e4441fd Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Thu, 29 Oct 2015 12:18:49 +0900 Subject: [PATCH 0219/2855] staging: wilc1000: linux_wlan_get_firmware: change argument p_nic with dev This patch changes argument perInterface_wlan_t *p_nic with struct net_device *dev and use netdev private data nic and it's member wilc instead of g_linux_wlan. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 17 ++++++++++------- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 4 +--- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 1 + 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index fee8c61385b2a..2103e8c0d6f9c 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -517,14 +517,17 @@ void linux_wlan_rx_complete(void) PRINT_D(RX_DBG, "RX completed\n"); } -int linux_wlan_get_firmware(perInterface_wlan_t *p_nic) +int linux_wlan_get_firmware(struct net_device *dev) { - - perInterface_wlan_t *nic = p_nic; + perInterface_wlan_t *nic; + struct wilc *wilc; int ret = 0; const struct firmware *wilc_firmware; char *firmware; + nic = netdev_priv(dev); + wilc = nic->wilc; + if (nic->iftype == AP_MODE) firmware = AP_FIRMWARE; else if (nic->iftype == STATION_MODE) @@ -549,19 +552,19 @@ int linux_wlan_get_firmware(perInterface_wlan_t *p_nic) * root file system with the name specified above */ #ifdef WILC_SDIO - if (request_firmware(&wilc_firmware, firmware, &g_linux_wlan->wilc_sdio_func->dev) != 0) { + if (request_firmware(&wilc_firmware, firmware, &wilc->wilc_sdio_func->dev) != 0) { PRINT_ER("%s - firmare not available\n", firmware); ret = -1; goto _fail_; } #else - if (request_firmware(&wilc_firmware, firmware, &g_linux_wlan->wilc_spidev->dev) != 0) { + if (request_firmware(&wilc_firmware, firmware, &wilc->wilc_spidev->dev) != 0) { PRINT_ER("%s - firmare not available\n", firmware); ret = -1; goto _fail_; } #endif - g_linux_wlan->firmware = wilc_firmware; + wilc->firmware = wilc_firmware; _fail_: @@ -1125,7 +1128,7 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) } #endif - if (linux_wlan_get_firmware(nic)) { + if (linux_wlan_get_firmware(dev)) { PRINT_ER("Can't get firmware\n"); ret = -EIO; goto _fail_irq_enable_; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index cdcf134c314a3..32b93d3f806da 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -21,8 +21,6 @@ #define IS_MGMT_STATUS_SUCCES 0x040 #define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff) -extern int linux_wlan_get_firmware(perInterface_wlan_t *p_nic); - extern int mac_open(struct net_device *ndev); extern int mac_close(struct net_device *ndev); @@ -2737,7 +2735,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv); PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n"); - linux_wlan_get_firmware(nic); + linux_wlan_get_firmware(dev); /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/ if (wl->initialized) { nic->iftype = AP_MODE; diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 0bfe7626ad2d2..0435cb5712272 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -218,4 +218,5 @@ int wilc_netdev_init(struct wilc **wilc); void wilc1000_wlan_deinit(struct net_device *dev); void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size); u16 Set_machw_change_vir_if(struct net_device *dev, bool bValue); +int linux_wlan_get_firmware(struct net_device *dev); #endif -- GitLab From 90b984c8558ba6af99ca32931be5c1bb21c34271 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Thu, 29 Oct 2015 12:18:50 +0900 Subject: [PATCH 0220/2855] staging: wilc1000: wl_wlan_cleanup: add argument struct wilc This patch adds new argument struct wilc and use it instead of g_linux_wlan. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 28 +++++++++---------- drivers/staging/wilc1000/linux_wlan_sdio.c | 2 +- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 2103e8c0d6f9c..09ddba2fb53ac 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1651,39 +1651,39 @@ void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size) WILC_WFI_p2p_rx(wilc->vif[1].ndev, buff, size); } -void wl_wlan_cleanup(void) +void wl_wlan_cleanup(struct wilc *wilc) { int i = 0; perInterface_wlan_t *nic[NUM_CONCURRENT_IFC]; - if (g_linux_wlan && - (g_linux_wlan->vif[0].ndev || g_linux_wlan->vif[1].ndev)) { + if (wilc && + (wilc->vif[0].ndev || wilc->vif[1].ndev)) { unregister_inetaddr_notifier(&g_dev_notifier); for (i = 0; i < NUM_CONCURRENT_IFC; i++) - nic[i] = netdev_priv(g_linux_wlan->vif[i].ndev); + nic[i] = netdev_priv(wilc->vif[i].ndev); } - if (g_linux_wlan && g_linux_wlan->firmware) - release_firmware(g_linux_wlan->firmware); + if (wilc && wilc->firmware) + release_firmware(wilc->firmware); - if (g_linux_wlan && - (g_linux_wlan->vif[0].ndev || g_linux_wlan->vif[1].ndev)) { + if (wilc&& + (wilc->vif[0].ndev || wilc->vif[1].ndev)) { linux_wlan_lock_timeout(&close_exit_sync, 12 * 1000); for (i = 0; i < NUM_CONCURRENT_IFC; i++) - if (g_linux_wlan->vif[i].ndev) + if (wilc->vif[i].ndev) if (nic[i]->mac_opened) - mac_close(g_linux_wlan->vif[i].ndev); + mac_close(wilc->vif[i].ndev); for (i = 0; i < NUM_CONCURRENT_IFC; i++) { - unregister_netdev(g_linux_wlan->vif[i].ndev); - wilc_free_wiphy(g_linux_wlan->vif[i].ndev); - free_netdev(g_linux_wlan->vif[i].ndev); + unregister_netdev(wilc->vif[i].ndev); + wilc_free_wiphy(wilc->vif[i].ndev); + free_netdev(wilc->vif[i].ndev); } } - kfree(g_linux_wlan); + kfree(wilc); #if defined(WILC_DEBUGFS) wilc_debugfs_remove(); diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index 4aff953a88f16..bf05e227778c0 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -146,7 +146,7 @@ static void linux_sdio_remove(struct sdio_func *func) struct wilc_sdio *wl_sdio; wl_sdio = sdio_get_drvdata(func); - wl_wlan_cleanup(); + wl_wlan_cleanup(wl_sdio->wilc); kfree(wl_sdio); } diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 0435cb5712272..07917ea105b60 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -213,7 +213,7 @@ void linux_wlan_mac_indicate(struct wilc *wilc, int flag); void linux_wlan_rx_complete(void); void linux_wlan_dbg(u8 *buff); int linux_wlan_lock_timeout(void *vp, u32 timeout); -void wl_wlan_cleanup(void); +void wl_wlan_cleanup(struct wilc *wilc); int wilc_netdev_init(struct wilc **wilc); void wilc1000_wlan_deinit(struct net_device *dev); void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size); -- GitLab From 50327db7175a6109b8d35475c7735a30645751b0 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Tue, 3 Nov 2015 16:20:58 +0900 Subject: [PATCH 0221/2855] staging: wilc1000: change enum variable name with lower case This patch changes WID_TYPE with wid_type which is preferred style. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/coreconfigurator.h | 2 +- drivers/staging/wilc1000/wilc_wlan_if.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/coreconfigurator.h b/drivers/staging/wilc1000/coreconfigurator.h index 6294d929a800c..3253f6f1393ae 100644 --- a/drivers/staging/wilc1000/coreconfigurator.h +++ b/drivers/staging/wilc1000/coreconfigurator.h @@ -72,7 +72,7 @@ typedef enum { struct wid { u16 id; - enum WID_TYPE type; + enum wid_type type; s32 size; s8 *val; }; diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index 139cc6d388945..f11003d144861 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -315,7 +315,7 @@ typedef enum { SW_TRIGGER_ABORT, } TX_ABORT_OPTION_T; -enum WID_TYPE { +enum wid_type { WID_CHAR = 0, WID_SHORT = 1, WID_INT = 2, -- GitLab From 30cbaa7f17e5c55b4e28274c9896d6fb4fec3f90 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Tue, 3 Nov 2015 16:21:01 +0900 Subject: [PATCH 0222/2855] staging: wilc1000: send_config_pkt: remove unnecessary blank line This patch remove unnecessary blank line which is reported by checkpatch.pl Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/coreconfigurator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/wilc1000/coreconfigurator.c b/drivers/staging/wilc1000/coreconfigurator.c index e10c6ffa698a6..fd7240c9da3ee 100644 --- a/drivers/staging/wilc1000/coreconfigurator.c +++ b/drivers/staging/wilc1000/coreconfigurator.c @@ -609,7 +609,6 @@ s32 send_config_pkt(u8 mode, struct wid *wids, u32 count, u32 drv) wids[counter].id, wids[counter].val, wids[counter].size); - } } else if (mode == SET_CFG) { for (counter = 0; counter < count; counter++) { -- GitLab From a6527c3b36957d180f4ae2594bbae8ea3ef02bca Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:02 +0900 Subject: [PATCH 0223/2855] staging: wilc1000: rename pu8IPAddr of fuction Handle_set_IPAddress This patch renames pu8IPAddr of fuction Handle_set_IPAddress to ip_addr to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 17826f3d4407d..b1d8b17fc461a 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -397,22 +397,23 @@ static s32 Handle_SetOperationMode(struct host_if_drv *hif_drv, return result; } -s32 Handle_set_IPAddress(struct host_if_drv *hif_drv, u8 *pu8IPAddr, u8 idx) +s32 Handle_set_IPAddress(struct host_if_drv *hif_drv, u8 *ip_addr, u8 idx) { s32 result = 0; struct wid wid; char firmwareIPAddress[4] = {0}; - if (pu8IPAddr[0] < 192) - pu8IPAddr[0] = 0; + if (ip_addr[0] < 192) + ip_addr[0] = 0; - PRINT_INFO(HOSTINF_DBG, "Indx = %d, Handling set IP = %pI4\n", idx, pu8IPAddr); + PRINT_INFO(HOSTINF_DBG, "Indx = %d, Handling set IP = %pI4\n", + idx, ip_addr); - memcpy(set_ip[idx], pu8IPAddr, IP_ALEN); + memcpy(set_ip[idx], ip_addr, IP_ALEN); wid.id = (u16)WID_IP_ADDRESS; wid.type = WID_STR; - wid.val = (u8 *)pu8IPAddr; + wid.val = (u8 *)ip_addr; wid.size = IP_ALEN; result = send_config_pkt(SET_CFG, &wid, 1, -- GitLab From ebc57d194fc7aca973055b0b38a3b7f52df6ad78 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:03 +0900 Subject: [PATCH 0224/2855] staging: wilc1000: rename firmwareIPAddress of fuction Handle_set_IPAddress This patch renames firmwareIPAddress of fuction Handle_set_IPAddress to firmware_ip_addr to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index b1d8b17fc461a..4ad0dd0889225 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -401,7 +401,7 @@ s32 Handle_set_IPAddress(struct host_if_drv *hif_drv, u8 *ip_addr, u8 idx) { s32 result = 0; struct wid wid; - char firmwareIPAddress[4] = {0}; + char firmware_ip_addr[4] = {0}; if (ip_addr[0] < 192) ip_addr[0] = 0; @@ -419,7 +419,7 @@ s32 Handle_set_IPAddress(struct host_if_drv *hif_drv, u8 *ip_addr, u8 idx) result = send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); - host_int_get_ipaddress(hif_drv, firmwareIPAddress, idx); + host_int_get_ipaddress(hif_drv, firmware_ip_addr, idx); if (result) { PRINT_ER("Failed to set IP address\n"); -- GitLab From c033cdafb73286fdce714a69daace81ec5ff8558 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:04 +0900 Subject: [PATCH 0225/2855] staging: wilc1000: remove unused parameter of fuction Handle_get_IPAddress This patch removes parameter pu8IPAddr of fuction Handle_get_IPAddress because it is not used in the function. Remove argument in the function call also. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 4ad0dd0889225..463b86f4bfc69 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -431,7 +431,7 @@ s32 Handle_set_IPAddress(struct host_if_drv *hif_drv, u8 *ip_addr, u8 idx) return result; } -s32 Handle_get_IPAddress(struct host_if_drv *hif_drv, u8 *pu8IPAddr, u8 idx) +s32 Handle_get_IPAddress(struct host_if_drv *hif_drv, u8 idx) { s32 result = 0; struct wid wid; @@ -2974,7 +2974,7 @@ static int hostIFthread(void *pvArg) case HOST_IF_MSG_GET_IPADDRESS: PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n"); - Handle_get_IPAddress(msg.drv, msg.body.ip_info.ip_addr, msg.body.ip_info.idx); + Handle_get_IPAddress(msg.drv, msg.body.ip_info.idx); break; case HOST_IF_MSG_SET_MAC_ADDRESS: -- GitLab From 090dbb10149b17869b7a7740e59a0d5c4832348c Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:05 +0900 Subject: [PATCH 0226/2855] staging: wilc1000: rename pstrHostIfSetMacAddress of fuction Handle_SetMacAddress This patch renames pstrHostIfSetMacAddress of fuction Handle_SetMacAddress to set_mac_addr to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 463b86f4bfc69..35e94609e6cf0 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -466,7 +466,7 @@ s32 Handle_get_IPAddress(struct host_if_drv *hif_drv, u8 idx) } static s32 Handle_SetMacAddress(struct host_if_drv *hif_drv, - struct set_mac_addr *pstrHostIfSetMacAddress) + struct set_mac_addr *set_mac_addr) { s32 result = 0; struct wid wid; @@ -476,7 +476,7 @@ static s32 Handle_SetMacAddress(struct host_if_drv *hif_drv, PRINT_ER("No buffer to send mac address\n"); return -EFAULT; } - memcpy(mac_buf, pstrHostIfSetMacAddress->mac_addr, ETH_ALEN); + memcpy(mac_buf, set_mac_addr->mac_addr, ETH_ALEN); wid.id = (u16)WID_MAC_ADDR; wid.type = WID_STR; -- GitLab From 7f0ee9a69ef207ba0a0bd381620eb89bd92d9fe5 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:06 +0900 Subject: [PATCH 0227/2855] staging: wilc1000: rename pstrHostIfGetMacAddress of fuction Handle_GetMacAddress This patch renames pstrHostIfGetMacAddress of fuction Handle_GetMacAddress to get_mac_addr to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 35e94609e6cf0..06994fb91d155 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -496,14 +496,14 @@ static s32 Handle_SetMacAddress(struct host_if_drv *hif_drv, } static s32 Handle_GetMacAddress(struct host_if_drv *hif_drv, - struct get_mac_addr *pstrHostIfGetMacAddress) + struct get_mac_addr *get_mac_addr) { s32 result = 0; struct wid wid; wid.id = (u16)WID_MAC_ADDR; wid.type = WID_STR; - wid.val = pstrHostIfGetMacAddress->mac_addr; + wid.val = get_mac_addr->mac_addr; wid.size = ETH_ALEN; result = send_config_pkt(GET_CFG, &wid, 1, -- GitLab From 02ae2bdfe1400b00586f0dc439b318b17119027d Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:07 +0900 Subject: [PATCH 0228/2855] staging: wilc1000: rename strHostIFCfgParamAttr of fuction Handle_CfgParam This patch renames strHostIFCfgParamAttr of fuction Handle_CfgParam to cfg_param_attr to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 154 ++++++++++++---------- 1 file changed, 83 insertions(+), 71 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 06994fb91d155..9b986bb0f16c4 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -519,7 +519,7 @@ static s32 Handle_GetMacAddress(struct host_if_drv *hif_drv, } static s32 Handle_CfgParam(struct host_if_drv *hif_drv, - struct cfg_param_attr *strHostIFCfgParamAttr) + struct cfg_param_attr *cfg_param_attr) { s32 result = 0; struct wid strWIDList[32]; @@ -529,13 +529,13 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, PRINT_D(HOSTINF_DBG, "Setting CFG params\n"); - if (strHostIFCfgParamAttr->cfg_attr_info.flag & BSS_TYPE) { - if (strHostIFCfgParamAttr->cfg_attr_info.bss_type < 6) { + if (cfg_param_attr->cfg_attr_info.flag & BSS_TYPE) { + if (cfg_param_attr->cfg_attr_info.bss_type < 6) { strWIDList[u8WidCnt].id = WID_BSS_TYPE; - strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.bss_type; + strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.bss_type; strWIDList[u8WidCnt].type = WID_CHAR; strWIDList[u8WidCnt].size = sizeof(char); - hif_drv->cfg_values.bss_type = (u8)strHostIFCfgParamAttr->cfg_attr_info.bss_type; + hif_drv->cfg_values.bss_type = (u8)cfg_param_attr->cfg_attr_info.bss_type; } else { PRINT_ER("check value 6 over\n"); result = -EINVAL; @@ -543,13 +543,15 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, } u8WidCnt++; } - if (strHostIFCfgParamAttr->cfg_attr_info.flag & AUTH_TYPE) { - if ((strHostIFCfgParamAttr->cfg_attr_info.auth_type) == 1 || (strHostIFCfgParamAttr->cfg_attr_info.auth_type) == 2 || (strHostIFCfgParamAttr->cfg_attr_info.auth_type) == 5) { + if (cfg_param_attr->cfg_attr_info.flag & AUTH_TYPE) { + if (cfg_param_attr->cfg_attr_info.auth_type == 1 || + cfg_param_attr->cfg_attr_info.auth_type == 2 || + cfg_param_attr->cfg_attr_info.auth_type == 5) { strWIDList[u8WidCnt].id = WID_AUTH_TYPE; - strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.auth_type; + strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.auth_type; strWIDList[u8WidCnt].type = WID_CHAR; strWIDList[u8WidCnt].size = sizeof(char); - hif_drv->cfg_values.auth_type = (u8)strHostIFCfgParamAttr->cfg_attr_info.auth_type; + hif_drv->cfg_values.auth_type = (u8)cfg_param_attr->cfg_attr_info.auth_type; } else { PRINT_ER("Impossible value \n"); result = -EINVAL; @@ -557,13 +559,14 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, } u8WidCnt++; } - if (strHostIFCfgParamAttr->cfg_attr_info.flag & AUTHEN_TIMEOUT) { - if (strHostIFCfgParamAttr->cfg_attr_info.auth_timeout > 0 && strHostIFCfgParamAttr->cfg_attr_info.auth_timeout < 65536) { + if (cfg_param_attr->cfg_attr_info.flag & AUTHEN_TIMEOUT) { + if (cfg_param_attr->cfg_attr_info.auth_timeout > 0 && + cfg_param_attr->cfg_attr_info.auth_timeout < 65536) { strWIDList[u8WidCnt].id = WID_AUTH_TIMEOUT; - strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.auth_timeout; + strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.auth_timeout; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->cfg_values.auth_timeout = strHostIFCfgParamAttr->cfg_attr_info.auth_timeout; + hif_drv->cfg_values.auth_timeout = cfg_param_attr->cfg_attr_info.auth_timeout; } else { PRINT_ER("Range(1 ~ 65535) over\n"); result = -EINVAL; @@ -571,13 +574,13 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, } u8WidCnt++; } - if (strHostIFCfgParamAttr->cfg_attr_info.flag & POWER_MANAGEMENT) { - if (strHostIFCfgParamAttr->cfg_attr_info.power_mgmt_mode < 5) { + if (cfg_param_attr->cfg_attr_info.flag & POWER_MANAGEMENT) { + if (cfg_param_attr->cfg_attr_info.power_mgmt_mode < 5) { strWIDList[u8WidCnt].id = WID_POWER_MANAGEMENT; - strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.power_mgmt_mode; + strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.power_mgmt_mode; strWIDList[u8WidCnt].type = WID_CHAR; strWIDList[u8WidCnt].size = sizeof(char); - hif_drv->cfg_values.power_mgmt_mode = (u8)strHostIFCfgParamAttr->cfg_attr_info.power_mgmt_mode; + hif_drv->cfg_values.power_mgmt_mode = (u8)cfg_param_attr->cfg_attr_info.power_mgmt_mode; } else { PRINT_ER("Invalide power mode\n"); result = -EINVAL; @@ -585,13 +588,14 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, } u8WidCnt++; } - if (strHostIFCfgParamAttr->cfg_attr_info.flag & RETRY_SHORT) { - if ((strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit > 0) && (strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit < 256)) { + if (cfg_param_attr->cfg_attr_info.flag & RETRY_SHORT) { + if (cfg_param_attr->cfg_attr_info.short_retry_limit > 0 && + cfg_param_attr->cfg_attr_info.short_retry_limit < 256) { strWIDList[u8WidCnt].id = WID_SHORT_RETRY_LIMIT; - strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit; + strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.short_retry_limit; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->cfg_values.short_retry_limit = strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit; + hif_drv->cfg_values.short_retry_limit = cfg_param_attr->cfg_attr_info.short_retry_limit; } else { PRINT_ER("Range(1~256) over\n"); result = -EINVAL; @@ -599,14 +603,15 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, } u8WidCnt++; } - if (strHostIFCfgParamAttr->cfg_attr_info.flag & RETRY_LONG) { - if ((strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit > 0) && (strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit < 256)) { + if (cfg_param_attr->cfg_attr_info.flag & RETRY_LONG) { + if (cfg_param_attr->cfg_attr_info.long_retry_limit > 0 && + cfg_param_attr->cfg_attr_info.long_retry_limit < 256) { strWIDList[u8WidCnt].id = WID_LONG_RETRY_LIMIT; - strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit; + strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.long_retry_limit; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->cfg_values.long_retry_limit = strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit; + hif_drv->cfg_values.long_retry_limit = cfg_param_attr->cfg_attr_info.long_retry_limit; } else { PRINT_ER("Range(1~256) over\n"); result = -EINVAL; @@ -614,13 +619,14 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, } u8WidCnt++; } - if (strHostIFCfgParamAttr->cfg_attr_info.flag & FRAG_THRESHOLD) { - if (strHostIFCfgParamAttr->cfg_attr_info.frag_threshold > 255 && strHostIFCfgParamAttr->cfg_attr_info.frag_threshold < 7937) { + if (cfg_param_attr->cfg_attr_info.flag & FRAG_THRESHOLD) { + if (cfg_param_attr->cfg_attr_info.frag_threshold > 255 && + cfg_param_attr->cfg_attr_info.frag_threshold < 7937) { strWIDList[u8WidCnt].id = WID_FRAG_THRESHOLD; - strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.frag_threshold; + strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.frag_threshold; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->cfg_values.frag_threshold = strHostIFCfgParamAttr->cfg_attr_info.frag_threshold; + hif_drv->cfg_values.frag_threshold = cfg_param_attr->cfg_attr_info.frag_threshold; } else { PRINT_ER("Threshold Range fail\n"); result = -EINVAL; @@ -628,13 +634,14 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, } u8WidCnt++; } - if (strHostIFCfgParamAttr->cfg_attr_info.flag & RTS_THRESHOLD) { - if (strHostIFCfgParamAttr->cfg_attr_info.rts_threshold > 255 && strHostIFCfgParamAttr->cfg_attr_info.rts_threshold < 65536) { + if (cfg_param_attr->cfg_attr_info.flag & RTS_THRESHOLD) { + if (cfg_param_attr->cfg_attr_info.rts_threshold > 255 && + cfg_param_attr->cfg_attr_info.rts_threshold < 65536) { strWIDList[u8WidCnt].id = WID_RTS_THRESHOLD; - strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.rts_threshold; + strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.rts_threshold; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->cfg_values.rts_threshold = strHostIFCfgParamAttr->cfg_attr_info.rts_threshold; + hif_drv->cfg_values.rts_threshold = cfg_param_attr->cfg_attr_info.rts_threshold; } else { PRINT_ER("Threshold Range fail\n"); result = -EINVAL; @@ -642,13 +649,13 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, } u8WidCnt++; } - if (strHostIFCfgParamAttr->cfg_attr_info.flag & PREAMBLE) { - if (strHostIFCfgParamAttr->cfg_attr_info.preamble_type < 3) { + if (cfg_param_attr->cfg_attr_info.flag & PREAMBLE) { + if (cfg_param_attr->cfg_attr_info.preamble_type < 3) { strWIDList[u8WidCnt].id = WID_PREAMBLE; - strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.preamble_type; + strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.preamble_type; strWIDList[u8WidCnt].type = WID_CHAR; strWIDList[u8WidCnt].size = sizeof(char); - hif_drv->cfg_values.preamble_type = strHostIFCfgParamAttr->cfg_attr_info.preamble_type; + hif_drv->cfg_values.preamble_type = cfg_param_attr->cfg_attr_info.preamble_type; } else { PRINT_ER("Preamle Range(0~2) over\n"); result = -EINVAL; @@ -656,13 +663,13 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, } u8WidCnt++; } - if (strHostIFCfgParamAttr->cfg_attr_info.flag & SHORT_SLOT_ALLOWED) { - if (strHostIFCfgParamAttr->cfg_attr_info.short_slot_allowed < 2) { + if (cfg_param_attr->cfg_attr_info.flag & SHORT_SLOT_ALLOWED) { + if (cfg_param_attr->cfg_attr_info.short_slot_allowed < 2) { strWIDList[u8WidCnt].id = WID_SHORT_SLOT_ALLOWED; - strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.short_slot_allowed; + strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.short_slot_allowed; strWIDList[u8WidCnt].type = WID_CHAR; strWIDList[u8WidCnt].size = sizeof(char); - hif_drv->cfg_values.short_slot_allowed = (u8)strHostIFCfgParamAttr->cfg_attr_info.short_slot_allowed; + hif_drv->cfg_values.short_slot_allowed = (u8)cfg_param_attr->cfg_attr_info.short_slot_allowed; } else { PRINT_ER("Short slot(2) over\n"); result = -EINVAL; @@ -670,13 +677,13 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, } u8WidCnt++; } - if (strHostIFCfgParamAttr->cfg_attr_info.flag & TXOP_PROT_DISABLE) { - if (strHostIFCfgParamAttr->cfg_attr_info.txop_prot_disabled < 2) { + if (cfg_param_attr->cfg_attr_info.flag & TXOP_PROT_DISABLE) { + if (cfg_param_attr->cfg_attr_info.txop_prot_disabled < 2) { strWIDList[u8WidCnt].id = WID_11N_TXOP_PROT_DISABLE; - strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.txop_prot_disabled; + strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.txop_prot_disabled; strWIDList[u8WidCnt].type = WID_CHAR; strWIDList[u8WidCnt].size = sizeof(char); - hif_drv->cfg_values.txop_prot_disabled = (u8)strHostIFCfgParamAttr->cfg_attr_info.txop_prot_disabled; + hif_drv->cfg_values.txop_prot_disabled = (u8)cfg_param_attr->cfg_attr_info.txop_prot_disabled; } else { PRINT_ER("TXOP prot disable\n"); result = -EINVAL; @@ -684,13 +691,14 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, } u8WidCnt++; } - if (strHostIFCfgParamAttr->cfg_attr_info.flag & BEACON_INTERVAL) { - if (strHostIFCfgParamAttr->cfg_attr_info.beacon_interval > 0 && strHostIFCfgParamAttr->cfg_attr_info.beacon_interval < 65536) { + if (cfg_param_attr->cfg_attr_info.flag & BEACON_INTERVAL) { + if (cfg_param_attr->cfg_attr_info.beacon_interval > 0 && + cfg_param_attr->cfg_attr_info.beacon_interval < 65536) { strWIDList[u8WidCnt].id = WID_BEACON_INTERVAL; - strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.beacon_interval; + strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.beacon_interval; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->cfg_values.beacon_interval = strHostIFCfgParamAttr->cfg_attr_info.beacon_interval; + hif_drv->cfg_values.beacon_interval = cfg_param_attr->cfg_attr_info.beacon_interval; } else { PRINT_ER("Beacon interval(1~65535) fail\n"); result = -EINVAL; @@ -698,13 +706,14 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, } u8WidCnt++; } - if (strHostIFCfgParamAttr->cfg_attr_info.flag & DTIM_PERIOD) { - if (strHostIFCfgParamAttr->cfg_attr_info.dtim_period > 0 && strHostIFCfgParamAttr->cfg_attr_info.dtim_period < 256) { + if (cfg_param_attr->cfg_attr_info.flag & DTIM_PERIOD) { + if (cfg_param_attr->cfg_attr_info.dtim_period > 0 && + cfg_param_attr->cfg_attr_info.dtim_period < 256) { strWIDList[u8WidCnt].id = WID_DTIM_PERIOD; - strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.dtim_period; + strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.dtim_period; strWIDList[u8WidCnt].type = WID_CHAR; strWIDList[u8WidCnt].size = sizeof(char); - hif_drv->cfg_values.dtim_period = strHostIFCfgParamAttr->cfg_attr_info.dtim_period; + hif_drv->cfg_values.dtim_period = cfg_param_attr->cfg_attr_info.dtim_period; } else { PRINT_ER("DTIM range(1~255) fail\n"); result = -EINVAL; @@ -712,13 +721,13 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, } u8WidCnt++; } - if (strHostIFCfgParamAttr->cfg_attr_info.flag & SITE_SURVEY) { - if (strHostIFCfgParamAttr->cfg_attr_info.site_survey_enabled < 3) { + if (cfg_param_attr->cfg_attr_info.flag & SITE_SURVEY) { + if (cfg_param_attr->cfg_attr_info.site_survey_enabled < 3) { strWIDList[u8WidCnt].id = WID_SITE_SURVEY; - strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.site_survey_enabled; + strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.site_survey_enabled; strWIDList[u8WidCnt].type = WID_CHAR; strWIDList[u8WidCnt].size = sizeof(char); - hif_drv->cfg_values.site_survey_enabled = (u8)strHostIFCfgParamAttr->cfg_attr_info.site_survey_enabled; + hif_drv->cfg_values.site_survey_enabled = (u8)cfg_param_attr->cfg_attr_info.site_survey_enabled; } else { PRINT_ER("Site survey disable\n"); result = -EINVAL; @@ -726,13 +735,14 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, } u8WidCnt++; } - if (strHostIFCfgParamAttr->cfg_attr_info.flag & SITE_SURVEY_SCAN_TIME) { - if (strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time > 0 && strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time < 65536) { + if (cfg_param_attr->cfg_attr_info.flag & SITE_SURVEY_SCAN_TIME) { + if (cfg_param_attr->cfg_attr_info.site_survey_scan_time > 0 && + cfg_param_attr->cfg_attr_info.site_survey_scan_time < 65536) { strWIDList[u8WidCnt].id = WID_SITE_SURVEY_SCAN_TIME; - strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time; + strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.site_survey_scan_time; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->cfg_values.site_survey_scan_time = strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time; + hif_drv->cfg_values.site_survey_scan_time = cfg_param_attr->cfg_attr_info.site_survey_scan_time; } else { PRINT_ER("Site survey scan time(1~65535) over\n"); result = -EINVAL; @@ -740,13 +750,14 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, } u8WidCnt++; } - if (strHostIFCfgParamAttr->cfg_attr_info.flag & ACTIVE_SCANTIME) { - if (strHostIFCfgParamAttr->cfg_attr_info.active_scan_time > 0 && strHostIFCfgParamAttr->cfg_attr_info.active_scan_time < 65536) { + if (cfg_param_attr->cfg_attr_info.flag & ACTIVE_SCANTIME) { + if (cfg_param_attr->cfg_attr_info.active_scan_time > 0 && + cfg_param_attr->cfg_attr_info.active_scan_time < 65536) { strWIDList[u8WidCnt].id = WID_ACTIVE_SCAN_TIME; - strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.active_scan_time; + strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.active_scan_time; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->cfg_values.active_scan_time = strHostIFCfgParamAttr->cfg_attr_info.active_scan_time; + hif_drv->cfg_values.active_scan_time = cfg_param_attr->cfg_attr_info.active_scan_time; } else { PRINT_ER("Active scan time(1~65535) over\n"); result = -EINVAL; @@ -754,13 +765,14 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, } u8WidCnt++; } - if (strHostIFCfgParamAttr->cfg_attr_info.flag & PASSIVE_SCANTIME) { - if (strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time > 0 && strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time < 65536) { + if (cfg_param_attr->cfg_attr_info.flag & PASSIVE_SCANTIME) { + if (cfg_param_attr->cfg_attr_info.passive_scan_time > 0 && + cfg_param_attr->cfg_attr_info.passive_scan_time < 65536) { strWIDList[u8WidCnt].id = WID_PASSIVE_SCAN_TIME; - strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time; + strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.passive_scan_time; strWIDList[u8WidCnt].type = WID_SHORT; strWIDList[u8WidCnt].size = sizeof(u16); - hif_drv->cfg_values.passive_scan_time = strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time; + hif_drv->cfg_values.passive_scan_time = cfg_param_attr->cfg_attr_info.passive_scan_time; } else { PRINT_ER("Passive scan time(1~65535) over\n"); result = -EINVAL; @@ -768,8 +780,8 @@ static s32 Handle_CfgParam(struct host_if_drv *hif_drv, } u8WidCnt++; } - if (strHostIFCfgParamAttr->cfg_attr_info.flag & CURRENT_TX_RATE) { - enum CURRENT_TXRATE curr_tx_rate = strHostIFCfgParamAttr->cfg_attr_info.curr_tx_rate; + if (cfg_param_attr->cfg_attr_info.flag & CURRENT_TX_RATE) { + enum CURRENT_TXRATE curr_tx_rate = cfg_param_attr->cfg_attr_info.curr_tx_rate; if (curr_tx_rate == AUTORATE || curr_tx_rate == MBPS_1 || curr_tx_rate == MBPS_2 || curr_tx_rate == MBPS_5_5 -- GitLab From 3b840e494910df8150beea57d0c56a9720eb4eac Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:08 +0900 Subject: [PATCH 0229/2855] staging: wilc1000: remove return type of Handle_wait_msg_q_empty This patch changes return type of Handle_wait_msg_q_empty from s32 with void because return value is not used. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 9b986bb0f16c4..8494a032eb722 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -813,11 +813,10 @@ ERRORHANDLER: return result; } -static s32 Handle_wait_msg_q_empty(void) +static void Handle_wait_msg_q_empty(void) { g_wilc_initialized = 0; up(&hif_sema_wait_response); - return 0; } static s32 Handle_Scan(struct host_if_drv *hif_drv, -- GitLab From fb70e9f5bd4b9d00e6a3e3946a9ed46bb4babd8c Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:09 +0900 Subject: [PATCH 0230/2855] staging: wilc1000: rename gau8MulticastMacAddrList variable This patch renames gau8MulticastMacAddrList variable to multicast_mac_addr_list to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 5 +++-- drivers/staging/wilc1000/linux_wlan.c | 11 ++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 8494a032eb722..d0e4039e6ed1a 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -243,7 +243,7 @@ static struct semaphore hif_sema_wait_response; static struct semaphore hif_sema_deinit; static struct timer_list periodic_rssi; -u8 gau8MulticastMacAddrList[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; +u8 multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE]; @@ -2713,7 +2713,8 @@ static void Handle_SetMulticastFilter(struct host_if_drv *hif_drv, *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 24) & 0xFF); if ((strHostIfSetMulti->cnt) > 0) - memcpy(pu8CurrByte, gau8MulticastMacAddrList, ((strHostIfSetMulti->cnt) * ETH_ALEN)); + memcpy(pu8CurrByte, multicast_mac_addr_list, + ((strHostIfSetMulti->cnt) * ETH_ALEN)); result = send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 09ddba2fb53ac..1e14e97f6cba5 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -46,7 +46,7 @@ extern bool g_obtainingIP; extern void resolve_disconnect_aberration(void *drvHandler); -extern u8 gau8MulticastMacAddrList[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; +extern u8 multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; extern struct timer_list hDuringIpTimer; static int linux_wlan_device_power(int on_off) @@ -1343,9 +1343,14 @@ static void wilc_set_multicast_list(struct net_device *dev) /* Store all of the multicast addresses in the hardware filter */ netdev_for_each_mc_addr(ha, dev) { - memcpy(gau8MulticastMacAddrList[i], ha->addr, ETH_ALEN); + memcpy(multicast_mac_addr_list[i], ha->addr, ETH_ALEN); PRINT_D(INIT_DBG, "Entry[%d]: %x:%x:%x:%x:%x:%x\n", i, - gau8MulticastMacAddrList[i][0], gau8MulticastMacAddrList[i][1], gau8MulticastMacAddrList[i][2], gau8MulticastMacAddrList[i][3], gau8MulticastMacAddrList[i][4], gau8MulticastMacAddrList[i][5]); + multicast_mac_addr_list[i][0], + multicast_mac_addr_list[i][1], + multicast_mac_addr_list[i][2], + multicast_mac_addr_list[i][3], + multicast_mac_addr_list[i][4], + multicast_mac_addr_list[i][5]); i++; } -- GitLab From 3a147c07ca4c2048eb9861def7253cd21bf21d77 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:10 +0900 Subject: [PATCH 0231/2855] staging: wilc1000: replace explicit NULL comparisons with ! This patch replace explicit NULL comparison with ! or unmark operator to simplify code. Reported by checkpatch.pl for comparison to NULL could be written "!XXX" or "XXX". Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 45 ++++++++++++++------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 1e14e97f6cba5..d50f0d6a15cde 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -136,7 +136,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event u8 null_ip[4] = {0}; char wlan_dev_name[5] = "wlan0"; - if (dev_iface == NULL || dev_iface->ifa_dev == NULL || dev_iface->ifa_dev->dev == NULL) { + if (!dev_iface || !dev_iface->ifa_dev || !dev_iface->ifa_dev->dev) { PRINT_D(GENERIC_DBG, "dev_iface = NULL\n"); return NOTIFY_DONE; } @@ -147,18 +147,18 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event } dev = (struct net_device *)dev_iface->ifa_dev->dev; - if (dev->ieee80211_ptr == NULL || dev->ieee80211_ptr->wiphy == NULL) { + if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy) { PRINT_D(GENERIC_DBG, "No Wireless registerd\n"); return NOTIFY_DONE; } priv = wiphy_priv(dev->ieee80211_ptr->wiphy); - if (priv == NULL) { + if (!priv) { PRINT_D(GENERIC_DBG, "No Wireless Priv\n"); return NOTIFY_DONE; } pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv; nic = netdev_priv(dev); - if (nic == NULL || pstrWFIDrv == NULL) { + if (!nic || !pstrWFIDrv) { PRINT_D(GENERIC_DBG, "No Wireless Priv\n"); return NOTIFY_DONE; } @@ -339,7 +339,7 @@ int linux_wlan_lock_timeout(void *vp, u32 timeout) int error = -1; PRINT_D(LOCK_DBG, "Locking %p\n", vp); - if (vp != NULL) + if (vp) error = down_timeout((struct semaphore *)vp, msecs_to_jiffies(timeout)); else PRINT_ER("Failed, mutex is NULL\n"); @@ -538,12 +538,12 @@ int linux_wlan_get_firmware(struct net_device *dev) firmware = P2P_CONCURRENCY_FIRMWARE; } - if (nic == NULL) { + if (!nic) { PRINT_ER("NIC is NULL\n"); goto _fail_; } - if (&nic->wilc_netdev->dev == NULL) { + if (!(&nic->wilc_netdev->dev)) { PRINT_ER("&nic->wilc_netdev->dev is NULL\n"); goto _fail_; } @@ -925,7 +925,7 @@ void wilc1000_wlan_deinit(struct net_device *dev) disable_sdio_interrupt(); mutex_unlock(&wl->hif_cs); #endif - if (&wl->txq_event != NULL) + if (&wl->txq_event) up(&wl->txq_event); PRINT_D(INIT_DBG, "Deinitializing Threads\n"); @@ -998,10 +998,10 @@ static int wlan_deinit_locks(struct net_device *dev) PRINT_D(INIT_DBG, "De-Initializing Locks\n"); - if (&wilc->hif_cs != NULL) + if (&wilc->hif_cs) mutex_destroy(&wilc->hif_cs); - if (&wilc->rxq_cs != NULL) + if (&wilc->rxq_cs) mutex_destroy(&wilc->rxq_cs); return 0; @@ -1074,10 +1074,10 @@ static void wlan_deinitialize_threads(struct net_device *dev) wl->close = 1; PRINT_D(INIT_DBG, "Deinitializing Threads\n"); - if (&wl->txq_event != NULL) + if (&wl->txq_event) up(&wl->txq_event); - if (wl->txq_thread != NULL) { + if (wl->txq_thread) { kthread_stop(wl->txq_thread); wl->txq_thread = NULL; } @@ -1396,7 +1396,7 @@ int mac_xmit(struct sk_buff *skb, struct net_device *ndev) } tx_data = kmalloc(sizeof(struct tx_complete_data), GFP_ATOMIC); - if (tx_data == NULL) { + if (!tx_data) { PRINT_ER("Failed to allocate memory for tx_data structure\n"); dev_kfree_skb(skb); netif_wake_queue(ndev); @@ -1450,7 +1450,8 @@ int mac_close(struct net_device *ndev) nic = netdev_priv(ndev); - if ((nic == NULL) || (nic->wilc_netdev == NULL) || (nic->wilc_netdev->ieee80211_ptr == NULL) || (nic->wilc_netdev->ieee80211_ptr->wiphy == NULL)) { + if (!nic || !nic->wilc_netdev || !nic->wilc_netdev->ieee80211_ptr || + !nic->wilc_netdev->ieee80211_ptr->wiphy) { PRINT_ER("nic = NULL\n"); return 0; } @@ -1458,7 +1459,7 @@ int mac_close(struct net_device *ndev) priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy); wl = nic->wilc; - if (priv == NULL) { + if (!priv) { PRINT_ER("priv = NULL\n"); return 0; } @@ -1472,7 +1473,7 @@ int mac_close(struct net_device *ndev) return 0; } - if (pstrWFIDrv == NULL) { + if (!pstrWFIDrv) { PRINT_ER("pstrWFIDrv = NULL\n"); return 0; } @@ -1484,7 +1485,7 @@ int mac_close(struct net_device *ndev) return 0; } - if (nic->wilc_netdev != NULL) { + if (nic->wilc_netdev) { /* Stop the network interface queue */ netif_stop_queue(nic->wilc_netdev); @@ -1585,7 +1586,7 @@ void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset) perInterface_wlan_t *nic; wilc_netdev = GetIfHandler(wilc, buff); - if (wilc_netdev == NULL) + if (!wilc_netdev) return; buff += pkt_offset; @@ -1598,16 +1599,16 @@ void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset) /* Need to send the packet up to the host, allocate a skb buffer */ skb = dev_alloc_skb(frame_len); - if (skb == NULL) { + if (!skb) { PRINT_ER("Low memory - packet droped\n"); return; } - if (wilc == NULL || wilc_netdev == NULL) + if (!wilc || !wilc_netdev) PRINT_ER("wilc_netdev in wilc is NULL"); skb->dev = wilc_netdev; - if (skb->dev == NULL) + if (!skb->dev) PRINT_ER("skb->dev is NULL\n"); /* @@ -1754,7 +1755,7 @@ int wilc_netdev_init(struct wilc **wilc) SET_NETDEV_DEV(ndev, &local_sdio_func->dev); #endif - if (wdev == NULL) { + if (!wdev) { PRINT_ER("Can't register WILC Wiphy\n"); return -1; } -- GitLab From 682d7c95f8cff2f03839e0d0e66f93af3b621f67 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:11 +0900 Subject: [PATCH 0232/2855] staging: wilc1000: linux_wlan: remove unused define CUSTOMER_PLATFORM This patch remove unused define CUSTOMER_PLATFORM from linux_wlan.c. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index d50f0d6a15cde..a9052ed013399 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -31,18 +31,11 @@ #include "linux_wlan_spi.h" #endif -#if defined(CUSTOMER_PLATFORM) -/* - TODO : Write power control functions as customer platform. - */ -#else - #define _linux_wlan_device_power_on() {} #define _linux_wlan_device_power_off() {} #define _linux_wlan_device_detection() {} #define _linux_wlan_device_removal() {} -#endif extern bool g_obtainingIP; extern void resolve_disconnect_aberration(void *drvHandler); @@ -278,15 +271,7 @@ static int init_irq(struct net_device *dev) /*GPIO request*/ if ((gpio_request(GPIO_NUM, "WILC_INTR") == 0) && (gpio_direction_input(GPIO_NUM) == 0)) { -#if defined(CUSTOMER_PLATFORM) -/* - TODO : save the registerd irq number to the private wilc context in kernel. - * - * ex) nic->dev_irq_num = gpio_to_irq(GPIO_NUM); - */ -#else wl->dev_irq_num = gpio_to_irq(GPIO_NUM); -#endif } else { ret = -1; PRINT_ER("could not obtain gpio for WILC_INTR\n"); -- GitLab From f24374aa02bb9b4b38d5ca4db0ced3caf2982313 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:12 +0900 Subject: [PATCH 0233/2855] staging: wilc1000: rename pstrWFIDrv of function dev_state_ev_handler This patch renames pstrWFIDrv of function dev_state_ev_handler to hif_drv to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index a9052ed013399..88cf6999b0245 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -122,7 +122,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event { struct in_ifaddr *dev_iface = (struct in_ifaddr *)ptr; struct wilc_priv *priv; - struct host_if_drv *pstrWFIDrv; + struct host_if_drv *hif_drv; struct net_device *dev; u8 *pIP_Add_buff; perInterface_wlan_t *nic; @@ -149,9 +149,9 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event PRINT_D(GENERIC_DBG, "No Wireless Priv\n"); return NOTIFY_DONE; } - pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv; + hif_drv = (struct host_if_drv *)priv->hWILCWFIDrv; nic = netdev_priv(dev); - if (!nic || !pstrWFIDrv) { + if (!nic || !hif_drv) { PRINT_D(GENERIC_DBG, "No Wireless Priv\n"); return NOTIFY_DONE; } @@ -166,20 +166,20 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event /*If we are in station mode or client mode*/ if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) { - pstrWFIDrv->IFC_UP = 1; + hif_drv->IFC_UP = 1; g_obtainingIP = false; del_timer(&hDuringIpTimer); PRINT_D(GENERIC_DBG, "IP obtained , enable scan\n"); } if (bEnablePS) - host_int_set_power_mgmt(pstrWFIDrv, 1, 0); + host_int_set_power_mgmt(hif_drv, 1, 0); PRINT_D(GENERIC_DBG, "[%s] Up IP\n", dev_iface->ifa_label); pIP_Add_buff = (char *) (&(dev_iface->ifa_address)); PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n", pIP_Add_buff[0], pIP_Add_buff[1], pIP_Add_buff[2], pIP_Add_buff[3]); - host_int_setup_ipaddress(pstrWFIDrv, pIP_Add_buff, nic->u8IfIdx); + host_int_setup_ipaddress(hif_drv, pIP_Add_buff, nic->u8IfIdx); break; @@ -188,21 +188,21 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Released ===============\n\n"); if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) { - pstrWFIDrv->IFC_UP = 0; + hif_drv->IFC_UP = 0; g_obtainingIP = false; } if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0) - host_int_set_power_mgmt(pstrWFIDrv, 0, 0); + host_int_set_power_mgmt(hif_drv, 0, 0); - resolve_disconnect_aberration(pstrWFIDrv); + resolve_disconnect_aberration(hif_drv); PRINT_D(GENERIC_DBG, "[%s] Down IP\n", dev_iface->ifa_label); pIP_Add_buff = null_ip; PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n", pIP_Add_buff[0], pIP_Add_buff[1], pIP_Add_buff[2], pIP_Add_buff[3]); - host_int_setup_ipaddress(pstrWFIDrv, pIP_Add_buff, nic->u8IfIdx); + host_int_setup_ipaddress(hif_drv, pIP_Add_buff, nic->u8IfIdx); break; -- GitLab From 0fa66c7143a367964fd4afb0c3c58b8f76d76544 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:13 +0900 Subject: [PATCH 0234/2855] staging: wilc1000: rename pstrWFIDrv of function linux_wlan_init_test_config This patch renames pstrWFIDrv of function linux_wlan_init_test_config to hif_drv to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 88cf6999b0245..75edfa39d905b 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -632,14 +632,14 @@ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_ni unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xff}; struct wilc_priv *priv; - struct host_if_drv *pstrWFIDrv; + struct host_if_drv *hif_drv; PRINT_D(TX_DBG, "Start configuring Firmware\n"); get_random_bytes(&mac_add[5], 1); get_random_bytes(&mac_add[4], 1); priv = wiphy_priv(dev->ieee80211_ptr->wiphy); - pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv; - PRINT_D(INIT_DBG, "Host = %p\n", pstrWFIDrv); + hif_drv = (struct host_if_drv *)priv->hWILCWFIDrv; + PRINT_D(INIT_DBG, "Host = %p\n", hif_drv); PRINT_D(INIT_DBG, "MAC address is : %02x-%02x-%02x-%02x-%02x-%02x\n", mac_add[0], mac_add[1], mac_add[2], mac_add[3], mac_add[4], mac_add[5]); wilc_get_chipid(0); -- GitLab From ef7606c5c3b3563970ddd3780b44bbe0144f10f4 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:14 +0900 Subject: [PATCH 0235/2855] staging: wilc1000: rename pstrWFIDrv of function wilc_set_multicast_list This patch renames pstrWFIDrv of function wilc_set_multicast_list to hif_drv to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 75edfa39d905b..6250abbdb8d52 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1290,11 +1290,11 @@ static void wilc_set_multicast_list(struct net_device *dev) struct netdev_hw_addr *ha; struct wilc_priv *priv; - struct host_if_drv *pstrWFIDrv; + struct host_if_drv *hif_drv; int i = 0; priv = wiphy_priv(dev->ieee80211_ptr->wiphy); - pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv; + hif_drv = (struct host_if_drv *)priv->hWILCWFIDrv; if (!dev) return; @@ -1314,14 +1314,14 @@ static void wilc_set_multicast_list(struct net_device *dev) if ((dev->flags & IFF_ALLMULTI) || (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) { PRINT_D(INIT_DBG, "Disable multicast filter, retrive all multicast packets\n"); /* get all multicast packets */ - host_int_setup_multicast_filter(pstrWFIDrv, false, 0); + host_int_setup_multicast_filter(hif_drv, false, 0); return; } /* No multicast? Just get our own stuff */ if ((dev->mc.count) == 0) { PRINT_D(INIT_DBG, "Enable multicast filter, retrive directed packets only.\n"); - host_int_setup_multicast_filter(pstrWFIDrv, true, 0); + host_int_setup_multicast_filter(hif_drv, true, 0); return; } @@ -1339,7 +1339,7 @@ static void wilc_set_multicast_list(struct net_device *dev) i++; } - host_int_setup_multicast_filter(pstrWFIDrv, true, (dev->mc.count)); + host_int_setup_multicast_filter(hif_drv, true, (dev->mc.count)); return; -- GitLab From 2db2c8a71b9c121e8ec23809605d18e708b7af09 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:15 +0900 Subject: [PATCH 0236/2855] staging: wilc1000: rename pstrWFIDrv of function mac_close This patch renames pstrWFIDrv of function mac_close to hif_drv to avoid CamelCase naming convention. And, some debug print modification that has been included name 'pstrWFIDrv'. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 6250abbdb8d52..a8d9bcd9ddcda 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1430,7 +1430,7 @@ int mac_close(struct net_device *ndev) { struct wilc_priv *priv; perInterface_wlan_t *nic; - struct host_if_drv *pstrWFIDrv; + struct host_if_drv *hif_drv; struct wilc *wl; nic = netdev_priv(ndev); @@ -1449,7 +1449,7 @@ int mac_close(struct net_device *ndev) return 0; } - pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv; + hif_drv = (struct host_if_drv *)priv->hWILCWFIDrv; PRINT_D(GENERIC_DBG, "Mac close\n"); @@ -1458,8 +1458,8 @@ int mac_close(struct net_device *ndev) return 0; } - if (!pstrWFIDrv) { - PRINT_ER("pstrWFIDrv = NULL\n"); + if (!hif_drv) { + PRINT_ER("hif_drv = NULL\n"); return 0; } -- GitLab From eac3e8f6b86064da961f4874a052713ac0ab4824 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:16 +0900 Subject: [PATCH 0237/2855] staging: wilc1000: rename pIP_Add_buff of function dev_state_ev_handler This patch renames pIP_Add_buff of function dev_state_ev_handler to ip_addr_buf to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index a8d9bcd9ddcda..2900ea7e59ca1 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -124,7 +124,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event struct wilc_priv *priv; struct host_if_drv *hif_drv; struct net_device *dev; - u8 *pIP_Add_buff; + u8 *ip_addr_buf; perInterface_wlan_t *nic; u8 null_ip[4] = {0}; char wlan_dev_name[5] = "wlan0"; @@ -177,9 +177,11 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event PRINT_D(GENERIC_DBG, "[%s] Up IP\n", dev_iface->ifa_label); - pIP_Add_buff = (char *) (&(dev_iface->ifa_address)); - PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n", pIP_Add_buff[0], pIP_Add_buff[1], pIP_Add_buff[2], pIP_Add_buff[3]); - host_int_setup_ipaddress(hif_drv, pIP_Add_buff, nic->u8IfIdx); + ip_addr_buf = (char *)&dev_iface->ifa_address; + PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n", + ip_addr_buf[0], ip_addr_buf[1], + ip_addr_buf[2], ip_addr_buf[3]); + host_int_setup_ipaddress(hif_drv, ip_addr_buf, nic->u8IfIdx); break; @@ -199,10 +201,12 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event PRINT_D(GENERIC_DBG, "[%s] Down IP\n", dev_iface->ifa_label); - pIP_Add_buff = null_ip; - PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n", pIP_Add_buff[0], pIP_Add_buff[1], pIP_Add_buff[2], pIP_Add_buff[3]); + ip_addr_buf = null_ip; + PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n", + ip_addr_buf[0], ip_addr_buf[1], + ip_addr_buf[2], ip_addr_buf[3]); - host_int_setup_ipaddress(hif_drv, pIP_Add_buff, nic->u8IfIdx); + host_int_setup_ipaddress(hif_drv, ip_addr_buf, nic->u8IfIdx); break; -- GitLab From 20fa54e44326bbff3632a3a5800d3f10fdd1e760 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:17 +0900 Subject: [PATCH 0238/2855] staging: wilc1000: fixes blank lines aren't necessary brace This patch fixes the checks reported by checkpatch.pl for Blank lines aren't necessary after an open brace '{' and Blank lines aren't necessary before a close brace '}'. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 2900ea7e59ca1..4fbc344ac15ff 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -218,7 +218,6 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event } return NOTIFY_DONE; - } #if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO) @@ -284,11 +283,9 @@ static int init_irq(struct net_device *dev) if ((ret != -1) && (request_threaded_irq(wl->dev_irq_num, isr_uh_routine, isr_bh_routine, IRQF_TRIGGER_LOW | IRQF_ONESHOT, /*Without IRQF_ONESHOT the uh will remain kicked in and dont gave a chance to bh*/ "WILC_IRQ", dev)) < 0) { - PRINT_ER("Failed to request IRQ for GPIO: %d\n", GPIO_NUM); ret = -1; } else { - PRINT_D(INIT_DBG, "IRQ request succeeded IRQ-NUM= %d on GPIO: %d\n", wl->dev_irq_num, GPIO_NUM); } @@ -353,12 +350,9 @@ void linux_wlan_mac_indicate(struct wilc *wilc, int flag) if (wilc->mac_status == WILC_MAC_STATUS_CONNECT) { /* Connect */ } - } else if (flag == WILC_MAC_INDICATE_SCAN) { PRINT_D(GENERIC_DBG, "Scanning ...\n"); - } - } struct net_device *GetIfHandler(struct wilc *wilc, u8 *pMacHeader) @@ -445,7 +439,6 @@ static int linux_wlan_txq_task(void *vp) /* inform wilc1000_wlan_init that TXQ task is started. */ up(&wl->txq_thread_started); while (1) { - PRINT_D(TX_DBG, "txq_task Taking a nap :)\n"); down(&wl->txq_event); /* wait_for_completion(&pd->txq_event); */ @@ -558,7 +551,6 @@ int linux_wlan_get_firmware(struct net_device *dev) _fail_: return ret; - } static int linux_wlan_start_firmware(struct net_device *dev) @@ -631,7 +623,6 @@ _FAIL_: /* startup configuration - could be changed later using iconfig*/ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_nic) { - unsigned char c_val[64]; unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xff}; @@ -997,7 +988,6 @@ static int wlan_deinit_locks(struct net_device *dev) } void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic) { - PRINT_D(INIT_DBG, "Linux to Wlan services ...\n"); nwi->os_context.os_private = (void *)nic; @@ -1193,7 +1183,6 @@ _fail_locks_: int mac_init_fn(struct net_device *ndev) { - /*Why we do this !!!*/ netif_start_queue(ndev); /* ma */ netif_stop_queue(ndev); /* ma */ @@ -1291,7 +1280,6 @@ struct net_device_stats *mac_stats(struct net_device *dev) /* Setup the multicast filter */ static void wilc_set_multicast_list(struct net_device *dev) { - struct netdev_hw_addr *ha; struct wilc_priv *priv; struct host_if_drv *hif_drv; @@ -1346,12 +1334,10 @@ static void wilc_set_multicast_list(struct net_device *dev) host_int_setup_multicast_filter(hif_drv, true, (dev->mc.count)); return; - } static void linux_wlan_tx_complete(void *priv, int status) { - struct tx_complete_data *pv_data = (struct tx_complete_data *)priv; if (status == 1) @@ -1496,7 +1482,6 @@ int mac_close(struct net_device *ndev) int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) { - u8 *buff = NULL; s8 rssi; u32 size = 0, length = 0; @@ -1513,7 +1498,6 @@ int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) return 0; switch (cmd) { - /* ]] 2013-06-24 */ case SIOCSIWPRIV: { @@ -1522,7 +1506,6 @@ int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) size = wrq->u.data.length; if (size && wrq->u.data.pointer) { - buff = memdup_user(wrq->u.data.pointer, wrq->u.data.length); if (IS_ERR(buff)) return PTR_ERR(buff); @@ -1566,7 +1549,6 @@ done: void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset) { - unsigned int frame_len = 0; int stats; unsigned char *buff_to_send = NULL; @@ -1582,7 +1564,6 @@ void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset) nic = netdev_priv(wilc_netdev); if (size > 0) { - frame_len = size; buff_to_send = buff; @@ -1757,7 +1738,6 @@ int wilc_netdev_init(struct wilc **wilc) nic->netstats.tx_packets = 0; nic->netstats.rx_bytes = 0; nic->netstats.tx_bytes = 0; - } if (register_netdev(ndev)) { @@ -1767,7 +1747,6 @@ int wilc_netdev_init(struct wilc **wilc) nic->iftype = STATION_MODE; nic->mac_opened = 0; - } #ifndef WILC_SDIO -- GitLab From 98b8984794803a59587840d5261d5e5ec8e0d031 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:18 +0900 Subject: [PATCH 0239/2855] staging: wilc1000: linux_wlan.c: clean up comments There are over-commenting in the linux_wlan.c file and most of them are not helpful to explain what the code does and generate 80 ending line over warnings. So, all of comments and commented codes are removed in this patch. Comment will be added if necessary with the preferred Linux style. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 219 +++----------------------- 1 file changed, 26 insertions(+), 193 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 4fbc344ac15ff..105dbc809a5c0 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -78,12 +78,6 @@ static struct notifier_block g_dev_notifier = { #define IRQ_WAIT 1 #define IRQ_NO_WAIT 0 -/* - * to sync between mac_close and module exit. - * don't initialize or de-initialize from init/deinitlocks - * to be initialized from module wilc_netdev_init and - * deinitialized from mdoule_exit - */ static struct semaphore close_exit_sync; static int wlan_deinit_locks(struct net_device *dev); @@ -99,11 +93,6 @@ int mac_close(struct net_device *ndev); static struct net_device_stats *mac_stats(struct net_device *dev); static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd); static void wilc_set_multicast_list(struct net_device *dev); - -/* - * for now - in frmw_to_linux there should be private data to be passed to it - * and this data should be pointer to net device - */ struct wilc *g_linux_wlan; bool bEnablePS = true; @@ -156,15 +145,14 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event return NOTIFY_DONE; } - PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler +++\n"); /* tony */ + PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler +++\n"); switch (event) { case NETDEV_UP: - PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_UP %p\n", dev); /* tony */ + PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_UP %p\n", dev); PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Obtained ===============\n\n"); - /*If we are in station mode or client mode*/ if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) { hif_drv->IFC_UP = 1; g_obtainingIP = false; @@ -186,7 +174,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event break; case NETDEV_DOWN: - PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_DOWN %p\n", dev); /* tony */ + PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_DOWN %p\n", dev); PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Released ===============\n\n"); if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) { @@ -211,7 +199,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event break; default: - PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler event=default\n"); /* tony */ + PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler event=default\n"); PRINT_INFO(GENERIC_DBG, "[%s] unknown dev event: %lu\n", dev_iface->ifa_label, event); break; @@ -231,7 +219,6 @@ static irqreturn_t isr_uh_routine(int irq, void *user_data) wilc = nic->wilc; PRINT_D(INT_DBG, "Interrupt received UH\n"); - /*While mac is closing cacncel the handling of any interrupts received*/ if (wilc->close) { PRINT_ER("Driver is CLOSING: Can't handle UH interrupt\n"); return IRQ_HANDLED; @@ -248,7 +235,6 @@ irqreturn_t isr_bh_routine(int irq, void *userdata) nic = netdev_priv(userdata); wilc = nic->wilc; - /*While mac is closing cacncel the handling of any interrupts received*/ if (wilc->close) { PRINT_ER("Driver is CLOSING: Can't handle BH interrupt\n"); return IRQ_HANDLED; @@ -270,8 +256,6 @@ static int init_irq(struct net_device *dev) nic = netdev_priv(dev); wl = nic->wilc; - /*initialize GPIO and register IRQ num*/ - /*GPIO request*/ if ((gpio_request(GPIO_NUM, "WILC_INTR") == 0) && (gpio_direction_input(GPIO_NUM) == 0)) { wl->dev_irq_num = gpio_to_irq(GPIO_NUM); @@ -281,7 +265,7 @@ static int init_irq(struct net_device *dev) } if ((ret != -1) && (request_threaded_irq(wl->dev_irq_num, isr_uh_routine, isr_bh_routine, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, /*Without IRQF_ONESHOT the uh will remain kicked in and dont gave a chance to bh*/ + IRQF_TRIGGER_LOW | IRQF_ONESHOT, "WILC_IRQ", dev)) < 0) { PRINT_ER("Failed to request IRQ for GPIO: %d\n", GPIO_NUM); ret = -1; @@ -303,7 +287,6 @@ static void deinit_irq(struct net_device *dev) wilc = nic->wilc; #if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO) - /* Deintialize IRQ */ if (&wilc->dev_irq_num != 0) { free_irq(wilc->dev_irq_num, wilc); @@ -312,9 +295,6 @@ static void deinit_irq(struct net_device *dev) #endif } -/* - * OS functions - */ void linux_wlan_dbg(u8 *buff) { PRINT_D(INIT_DBG, "%d\n", *buff); @@ -334,9 +314,6 @@ int linux_wlan_lock_timeout(void *vp, u32 timeout) void linux_wlan_mac_indicate(struct wilc *wilc, int flag) { - /*I have to do it that way becuase there is no mean to encapsulate device pointer - * as a parameter - */ int status; if (flag == WILC_MAC_INDICATE_STATUS) { @@ -348,7 +325,7 @@ void linux_wlan_mac_indicate(struct wilc *wilc, int flag) wilc->mac_status = status; } - if (wilc->mac_status == WILC_MAC_STATUS_CONNECT) { /* Connect */ + if (wilc->mac_status == WILC_MAC_STATUS_CONNECT) { } } else if (flag == WILC_MAC_INDICATE_SCAN) { PRINT_D(GENERIC_DBG, "Scanning ...\n"); @@ -402,7 +379,6 @@ int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *pBSSID) return ret; } -/*Function to get number of connected interfaces*/ int linux_wlan_get_num_conn_ifcs(void) { u8 i = 0; @@ -436,16 +412,13 @@ static int linux_wlan_txq_task(void *vp) nic = netdev_priv(dev); wl = nic->wilc; - /* inform wilc1000_wlan_init that TXQ task is started. */ up(&wl->txq_thread_started); while (1) { PRINT_D(TX_DBG, "txq_task Taking a nap :)\n"); down(&wl->txq_event); - /* wait_for_completion(&pd->txq_event); */ PRINT_D(TX_DBG, "txq_task Who waked me up :$\n"); if (wl->close) { - /*Unlock the mutex in the mac_close function to indicate the exiting of the TX thread */ up(&wl->txq_thread_started); while (!kthread_should_stop()) @@ -460,23 +433,19 @@ static int linux_wlan_txq_task(void *vp) #else do { ret = wilc_wlan_handle_txq(dev, &txq_count); - if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD /* && netif_queue_stopped(pd->wilc_netdev)*/) { + if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD) { PRINT_D(TX_DBG, "Waking up queue\n"); - /* netif_wake_queue(pd->wilc_netdev); */ + if (netif_queue_stopped(wl->vif[0].ndev)) netif_wake_queue(wl->vif[0].ndev); if (netif_queue_stopped(wl->vif[1].ndev)) netif_wake_queue(wl->vif[1].ndev); } - if (ret == WILC_TX_ERR_NO_BUF) { /* failed to allocate buffers in chip. */ + if (ret == WILC_TX_ERR_NO_BUF) { do { - /* Back off from sending packets for some time. */ - /* schedule_timeout will allow RX task to run and free buffers.*/ - /* set_current_state(TASK_UNINTERRUPTIBLE); */ - /* timeout = schedule_timeout(timeout); */ msleep(TX_BACKOFF_WEIGHT_UNIT_MS << backoff_weight); - } while (/*timeout*/ 0); + } while (0); backoff_weight += TX_BACKOFF_WEIGHT_INCR_STEP; if (backoff_weight > TX_BACKOFF_WEIGHT_MAX) backoff_weight = TX_BACKOFF_WEIGHT_MAX; @@ -487,8 +456,7 @@ static int linux_wlan_txq_task(void *vp) backoff_weight = TX_BACKOFF_WEIGHT_MIN; } } - /*TODO: drop packets after a certain time/number of retry count. */ - } while (ret == WILC_TX_ERR_NO_BUF && !wl->close); /* retry sending packets if no more buffers in chip. */ + } while (ret == WILC_TX_ERR_NO_BUF && !wl->close); #endif } return 0; @@ -530,9 +498,6 @@ int linux_wlan_get_firmware(struct net_device *dev) goto _fail_; } - /* the firmare should be located in /lib/firmware in - * root file system with the name specified above */ - #ifdef WILC_SDIO if (request_firmware(&wilc_firmware, firmware, &wilc->wilc_sdio_func->dev) != 0) { PRINT_ER("%s - firmare not available\n", firmware); @@ -562,7 +527,6 @@ static int linux_wlan_start_firmware(struct net_device *dev) nic = netdev_priv(dev); wilc = nic->wilc; - /* start firmware */ PRINT_D(INIT_DBG, "Starting Firmware ...\n"); ret = wilc_wlan_start(); if (ret < 0) { @@ -570,17 +534,12 @@ static int linux_wlan_start_firmware(struct net_device *dev) goto _fail_; } - /* wait for mac ready */ PRINT_D(INIT_DBG, "Waiting for Firmware to get ready ...\n"); ret = linux_wlan_lock_timeout(&wilc->sync_event, 5000); if (ret) { PRINT_D(INIT_DBG, "Firmware start timed out"); goto _fail_; } - /* - * TODO: Driver shouoldn't wait forever for firmware to get started - - * in case of timeout this should be handled properly - */ PRINT_D(INIT_DBG, "Firmware successfully started\n"); _fail_: @@ -600,16 +559,12 @@ static int linux_wlan_firmware_download(struct net_device *dev) ret = -ENOBUFS; goto _FAIL_; } - /** - * do the firmware download - **/ PRINT_D(INIT_DBG, "Downloading Firmware ...\n"); ret = wilc_wlan_firmware_download(wilc->firmware->data, wilc->firmware->size); if (ret < 0) goto _FAIL_; - /* Freeing FW buffer */ PRINT_D(INIT_DBG, "Freeing FW buffer ...\n"); PRINT_D(INIT_DBG, "Releasing firmware\n"); release_firmware(wilc->firmware); @@ -620,7 +575,6 @@ _FAIL_: return ret; } -/* startup configuration - could be changed later using iconfig*/ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_nic) { unsigned char c_val[64]; @@ -644,7 +598,6 @@ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_ni if (!wilc_wlan_cfg_set(1, WID_SET_DRV_HANDLER, c_val, 4, 0, 0)) goto _fail_; - /*to tell fw that we are going to use PC test - WILC specific*/ c_val[0] = 0; if (!wilc_wlan_cfg_set(0, WID_PC_TEST_MODE, c_val, 1, 0, 0)) goto _fail_; @@ -653,7 +606,6 @@ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_ni if (!wilc_wlan_cfg_set(0, WID_BSS_TYPE, c_val, 1, 0, 0)) goto _fail_; - /* c_val[0] = RATE_AUTO; */ c_val[0] = RATE_AUTO; if (!wilc_wlan_cfg_set(0, WID_CURRENT_TX_RATE, c_val, 1, 0, 0)) goto _fail_; @@ -682,7 +634,7 @@ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_ni if (!wilc_wlan_cfg_set(0, WID_SITE_SURVEY, c_val, 1, 0, 0)) goto _fail_; - *((int *)c_val) = 0xffff; /* Never use RTS-CTS */ + *((int *)c_val) = 0xffff; if (!wilc_wlan_cfg_set(0, WID_RTS_THRESHOLD, c_val, 2, 0, 0)) goto _fail_; @@ -690,13 +642,6 @@ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_ni if (!wilc_wlan_cfg_set(0, WID_FRAG_THRESHOLD, c_val, 2, 0, 0)) goto _fail_; - /* SSID */ - /* -------------------------------------------------------------- */ - /* Configuration : String with length less than 32 bytes */ - /* Values to set : Any string with length less than 32 bytes */ - /* ( In BSS Station Set SSID to "" (null string) */ - /* to enable Broadcast SSID suppport ) */ - /* -------------------------------------------------------------- */ c_val[0] = 0; if (!wilc_wlan_cfg_set(0, WID_BCAST_SSID, c_val, 1, 0, 0)) goto _fail_; @@ -709,7 +654,7 @@ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_ni if (!wilc_wlan_cfg_set(0, WID_POWER_MANAGEMENT, c_val, 1, 0, 0)) goto _fail_; - c_val[0] = NO_ENCRYPT; /* NO_ENCRYPT, 0x79 */ + c_val[0] = NO_ENCRYPT; if (!wilc_wlan_cfg_set(0, WID_11I_MODE, c_val, 1, 0, 0)) goto _fail_; @@ -717,43 +662,18 @@ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_ni if (!wilc_wlan_cfg_set(0, WID_AUTH_TYPE, c_val, 1, 0, 0)) goto _fail_; - /* WEP/802 11I Configuration */ - /* ------------------------------------------------------------------ */ - /* Configuration : WEP Key */ - /* Values (0x) : 5 byte for WEP40 and 13 bytes for WEP104 */ - /* In case more than 5 bytes are passed on for WEP 40 */ - /* only first 5 bytes will be used as the key */ - /* ------------------------------------------------------------------ */ - strcpy(c_val, "123456790abcdef1234567890"); if (!wilc_wlan_cfg_set(0, WID_WEP_KEY_VALUE, c_val, (strlen(c_val) + 1), 0, 0)) goto _fail_; - /* WEP/802 11I Configuration */ - /* ------------------------------------------------------------------ */ - /* Configuration : AES/TKIP WPA/RSNA Pre-Shared Key */ - /* Values to set : Any string with length greater than equal to 8 bytes */ - /* and less than 64 bytes */ - /* ------------------------------------------------------------------ */ strcpy(c_val, "12345678"); if (!wilc_wlan_cfg_set(0, WID_11I_PSK, c_val, (strlen(c_val)), 0, 0)) goto _fail_; - /* IEEE802.1X Key Configuration */ - /* ------------------------------------------------------------------ */ - /* Configuration : Radius Server Access Secret Key */ - /* Values to set : Any string with length greater than equal to 8 bytes */ - /* and less than 65 bytes */ - /* ------------------------------------------------------------------ */ strcpy(c_val, "password"); if (!wilc_wlan_cfg_set(0, WID_1X_KEY, c_val, (strlen(c_val) + 1), 0, 0)) goto _fail_; - /* IEEE802.1X Server Address Configuration */ - /* ------------------------------------------------------------------ */ - /* Configuration : Radius Server IP Address */ - /* Values to set : Any valid IP Address */ - /* ------------------------------------------------------------------ */ c_val[0] = 192; c_val[1] = 168; c_val[2] = 1; @@ -785,12 +705,6 @@ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_ni if (!wilc_wlan_cfg_set(0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0, 0)) goto _fail_; - /* Beacon Interval */ - /* -------------------------------------------------------------------- */ - /* Configuration : Sets the beacon interval value */ - /* Values to set : Any 16-bit value */ - /* -------------------------------------------------------------------- */ - *((int *)c_val) = 100; if (!wilc_wlan_cfg_set(0, WID_BEACON_INTERVAL, c_val, 2, 0, 0)) goto _fail_; @@ -799,20 +713,10 @@ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_ni if (!wilc_wlan_cfg_set(0, WID_REKEY_POLICY, c_val, 1, 0, 0)) goto _fail_; - /* Rekey Time (s) (Used only when the Rekey policy is 2 or 4) */ - /* -------------------------------------------------------------------- */ - /* Configuration : Sets the Rekey Time (s) */ - /* Values to set : 32-bit value */ - /* -------------------------------------------------------------------- */ *((int *)c_val) = 84600; if (!wilc_wlan_cfg_set(0, WID_REKEY_PERIOD, c_val, 4, 0, 0)) goto _fail_; - /* Rekey Packet Count (in 1000s; used when Rekey Policy is 3) */ - /* -------------------------------------------------------------------- */ - /* Configuration : Sets Rekey Group Packet count */ - /* Values to set : 32-bit Value */ - /* -------------------------------------------------------------------- */ *((int *)c_val) = 500; if (!wilc_wlan_cfg_set(0, WID_REKEY_PACKET_COUNT, c_val, 4, 0, 0)) goto _fail_; @@ -825,7 +729,7 @@ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_ni if (!wilc_wlan_cfg_set(0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0, 0)) goto _fail_; - c_val[0] = 1; /* Enable N */ + c_val[0] = 1; if (!wilc_wlan_cfg_set(0, WID_11N_ENABLE, c_val, 1, 0, 0)) goto _fail_; @@ -833,7 +737,7 @@ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_ni if (!wilc_wlan_cfg_set(0, WID_11N_OPERATING_MODE, c_val, 1, 0, 0)) goto _fail_; - c_val[0] = 1; /* TXOP Prot disable in N mode: No RTS-CTS on TX A-MPDUs to save air-time. */ + c_val[0] = 1; if (!wilc_wlan_cfg_set(0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0, 0)) goto _fail_; @@ -842,9 +746,6 @@ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_ni if (!wilc_wlan_cfg_set(0, WID_MAC_ADDR, c_val, 6, 0, 0)) goto _fail_; - /** - * AP only - **/ c_val[0] = DETECT_PROTECT_REPORT; if (!wilc_wlan_cfg_set(0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1, 0, 0)) goto _fail_; @@ -865,7 +766,7 @@ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_ni if (!wilc_wlan_cfg_set(0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0, 0)) goto _fail_; - c_val[0] = 1; /* Enable N with immediate block ack. */ + c_val[0] = 1; if (!wilc_wlan_cfg_set(0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1, 1, 1)) goto _fail_; @@ -875,7 +776,6 @@ _fail_: return -1; } -/**************************/ void wilc1000_wlan_deinit(struct net_device *dev) { perInterface_wlan_t *nic; @@ -893,7 +793,6 @@ void wilc1000_wlan_deinit(struct net_device *dev) netdev_info(dev, "Deinitializing wilc1000...\n"); #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31) - /* johnny : remove */ PRINT_D(INIT_DBG, "skip wilc_bus_set_default_speed\n"); #else wilc_bus_set_default_speed(); @@ -928,11 +827,9 @@ void wilc1000_wlan_deinit(struct net_device *dev) #endif #endif - /*De-Initialize locks*/ PRINT_D(INIT_DBG, "Deinitializing Locks\n"); wlan_deinit_locks(dev); - /* announce that wilc1000 is not initialized */ wl->initialized = false; PRINT_D(INIT_DBG, "wilc1000 deinitialization Done\n"); @@ -1021,8 +918,6 @@ int wlan_initialize_threads(struct net_device *dev) wilc = nic->wilc; PRINT_D(INIT_DBG, "Initializing Threads ...\n"); - - /* create tx task */ PRINT_D(INIT_DBG, "Creating kthread for transmission\n"); wilc->txq_thread = kthread_run(linux_wlan_txq_task, (void *)dev, "K_TXQ_TASK"); @@ -1031,13 +926,11 @@ int wlan_initialize_threads(struct net_device *dev) ret = -ENOBUFS; goto _fail_2; } - /* wait for TXQ task to start. */ down(&wilc->txq_thread_started); return 0; _fail_2: - /*De-Initialize 2nd thread*/ wilc->close = 0; return ret; } @@ -1113,7 +1006,6 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) goto _fail_irq_enable_; } - /*Download firmware*/ ret = linux_wlan_firmware_download(dev); if (ret < 0) { PRINT_ER("Failed to download firmware\n"); @@ -1121,7 +1013,6 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) goto _fail_irq_enable_; } - /* Start firmware*/ ret = linux_wlan_start_firmware(dev); if (ret < 0) { PRINT_ER("Failed to start firmware\n"); @@ -1141,7 +1032,6 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) Firmware_ver[size] = '\0'; PRINT_D(INIT_DBG, "***** Firmware Ver = %s *******\n", Firmware_ver); } - /* Initialize firmware with default configuration */ ret = linux_wlan_init_test_config(dev, wl); if (ret < 0) { @@ -1151,7 +1041,7 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) } wl->initialized = true; - return 0; /*success*/ + return 0; _fail_fw_start_: wilc_wlan_stop(); @@ -1177,26 +1067,18 @@ _fail_locks_: return ret; } -/* - * - this function will be called automatically by OS when module inserted. - */ - int mac_init_fn(struct net_device *ndev) { - /*Why we do this !!!*/ - netif_start_queue(ndev); /* ma */ - netif_stop_queue(ndev); /* ma */ + netif_start_queue(ndev); + netif_stop_queue(ndev); return 0; } -/* This fn is called, when this device is setup using ifconfig */ int mac_open(struct net_device *ndev) { perInterface_wlan_t *nic; - /*No need for setting mac address here anymore,*/ - /*Just set it in init_test_config()*/ unsigned char mac_add[ETH_ALEN] = {0}; int ret = 0; int i = 0; @@ -1223,7 +1105,6 @@ int mac_open(struct net_device *ndev) return ret; } - /*initialize platform*/ PRINT_D(INIT_DBG, "*** re-init ***\n"); ret = wilc1000_wlan_init(ndev, nic); if (ret < 0) { @@ -1237,7 +1118,6 @@ int mac_open(struct net_device *ndev) host_int_get_MacAddress(priv->hWILCWFIDrv, mac_add); PRINT_D(INIT_DBG, "Mac address: %pM\n", mac_add); - /* loop through the NUM of supported devices and set the MAC address */ for (i = 0; i < wl->vif_num; i++) { if (ndev == wl->vif[i].ndev) { memcpy(wl->vif[i].src_addr, mac_add, ETH_ALEN); @@ -1246,7 +1126,6 @@ int mac_open(struct net_device *ndev) } } - /* TODO: get MAC address whenever the source is EPROM - hardcoded and copy it to ndev*/ memcpy(ndev->dev_addr, wl->vif[i].src_addr, ETH_ALEN); if (!is_valid_ether_addr(ndev->dev_addr)) { @@ -1277,7 +1156,6 @@ struct net_device_stats *mac_stats(struct net_device *dev) return &nic->netstats; } -/* Setup the multicast filter */ static void wilc_set_multicast_list(struct net_device *dev) { struct netdev_hw_addr *ha; @@ -1294,30 +1172,22 @@ static void wilc_set_multicast_list(struct net_device *dev) PRINT_D(INIT_DBG, "Setting Multicast List with count = %d.\n", dev->mc.count); if (dev->flags & IFF_PROMISC) { - /* Normally, we should configure the chip to retrive all packets - * but we don't wanna support this right now */ - /* TODO: add promiscuous mode support */ PRINT_D(INIT_DBG, "Set promiscuous mode ON, retrive all packets\n"); return; } - /* If there's more addresses than we handle, get all multicast - * packets and sort them out in software. */ if ((dev->flags & IFF_ALLMULTI) || (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) { PRINT_D(INIT_DBG, "Disable multicast filter, retrive all multicast packets\n"); - /* get all multicast packets */ host_int_setup_multicast_filter(hif_drv, false, 0); return; } - /* No multicast? Just get our own stuff */ if ((dev->mc.count) == 0) { PRINT_D(INIT_DBG, "Enable multicast filter, retrive directed packets only.\n"); host_int_setup_multicast_filter(hif_drv, true, 0); return; } - /* Store all of the multicast addresses in the hardware filter */ netdev_for_each_mc_addr(ha, dev) { memcpy(multicast_mac_addr_list[i], ha->addr, ETH_ALEN); @@ -1344,7 +1214,6 @@ static void linux_wlan_tx_complete(void *priv, int status) PRINT_D(TX_DBG, "Packet sent successfully - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb); else PRINT_D(TX_DBG, "Couldn't send packet - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb); - /* Free the SK Buffer, its work is done */ dev_kfree_skb(pv_data->skb); kfree(pv_data); } @@ -1364,7 +1233,6 @@ int mac_xmit(struct sk_buff *skb, struct net_device *ndev) PRINT_D(TX_DBG, "Sending packet just received from TCP/IP\n"); - /* Stop the network interface queue */ if (skb->dev != ndev) { PRINT_ER("Packet not destined to this device\n"); return 0; @@ -1386,7 +1254,6 @@ int mac_xmit(struct sk_buff *skb, struct net_device *ndev) if (eth_h->h_proto == 0x8e88) PRINT_D(INIT_DBG, "EAPOL transmitted\n"); - /*get source and dest ip addresses*/ ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr)); pu8UdpBuffer = (char *)ih + sizeof(struct iphdr); @@ -1394,12 +1261,6 @@ int mac_xmit(struct sk_buff *skb, struct net_device *ndev) PRINT_D(GENERIC_DBG, "DHCP Message transmitted, type:%x %x %x\n", pu8UdpBuffer[248], pu8UdpBuffer[249], pu8UdpBuffer[250]); PRINT_D(TX_DBG, "Sending packet - Size = %d - Address = %p - SKB = %p\n", tx_data->size, tx_data->buff, tx_data->skb); - - /* Send packet to MAC HW - for now the tx_complete function will be just status - * indicator. still not sure if I need to suspend host transmission till the tx_complete - * function called or not? - * allocated buffer will be freed in tx_complete function. - */ PRINT_D(TX_DBG, "Adding tx packet to TX Queue\n"); nic->netstats.tx_packets++; nic->netstats.tx_bytes += tx_data->size; @@ -1461,7 +1322,6 @@ int mac_close(struct net_device *ndev) } if (nic->wilc_netdev) { - /* Stop the network interface queue */ netif_stop_queue(nic->wilc_netdev); wilc_deinit_host_int(nic->wilc_netdev); @@ -1490,7 +1350,6 @@ int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) s32 s32Error = 0; struct wilc *wilc; - /* struct iwreq *wrq = (struct iwreq *) req; // tony moved to case SIOCSIWPRIV */ nic = netdev_priv(ndev); wilc = nic->wilc; @@ -1498,10 +1357,9 @@ int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) return 0; switch (cmd) { - /* ]] 2013-06-24 */ case SIOCSIWPRIV: { - struct iwreq *wrq = (struct iwreq *) req; /* added by tony */ + struct iwreq *wrq = (struct iwreq *) req; size = wrq->u.data.length; @@ -1517,7 +1375,6 @@ int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) PRINT_ER("Failed to send get rssi param's message queue "); PRINT_INFO(GENERIC_DBG, "RSSI :%d\n", rssi); - /*Rounding up the rssi negative value*/ rssi += 5; snprintf(buff, size, "rssi %d", rssi); @@ -1567,7 +1424,6 @@ void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset) frame_len = size; buff_to_send = buff; - /* Need to send the packet up to the host, allocate a skb buffer */ skb = dev_alloc_skb(frame_len); if (!skb) { PRINT_ER("Low memory - packet droped\n"); @@ -1581,23 +1437,9 @@ void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset) if (!skb->dev) PRINT_ER("skb->dev is NULL\n"); - /* - * for(i=0;i<40;i++) - * { - * if(iprotocol = eth_type_trans(skb, wilc_netdev); - /* Send the packet to the stack by giving it to the bridge */ nic->netstats.rx_packets++; nic->netstats.rx_bytes += frame_len; skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -1611,8 +1453,6 @@ void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size) int i = 0; perInterface_wlan_t *nic; - /*Pass the frame on the monitor interface, if any.*/ - /*Otherwise, pass it on p2p0 netdev, if registered on it*/ for (i = 0; i < wilc->vif_num; i++) { nic = netdev_priv(wilc->vif[i].ndev); if (nic->monitor_flag) { @@ -1621,7 +1461,7 @@ void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size) } } - nic = netdev_priv(wilc->vif[1].ndev); /* p2p0 */ + nic = netdev_priv(wilc->vif[1].ndev); if ((buff[0] == nic->g_struct_frame_reg[0].frame_type && nic->g_struct_frame_reg[0].reg) || (buff[0] == nic->g_struct_frame_reg[1].frame_type && nic->g_struct_frame_reg[1].reg)) WILC_WFI_p2p_rx(wilc->vif[1].ndev, buff, size); @@ -1676,7 +1516,6 @@ int wilc_netdev_init(struct wilc **wilc) sema_init(&close_exit_sync, 0); - /*create the common structure*/ g_linux_wlan = kzalloc(sizeof(*g_linux_wlan), GFP_KERNEL); if (!g_linux_wlan) return -ENOMEM; @@ -1686,7 +1525,6 @@ int wilc_netdev_init(struct wilc **wilc) register_inetaddr_notifier(&g_dev_notifier); for (i = 0; i < NUM_CONCURRENT_IFC; i++) { - /*allocate first ethernet device with perinterface_wlan_t as its private data*/ ndev = alloc_etherdev(sizeof(perInterface_wlan_t)); if (!ndev) { PRINT_ER("Failed to allocate ethernet dev\n"); @@ -1696,13 +1534,12 @@ int wilc_netdev_init(struct wilc **wilc) nic = netdev_priv(ndev); memset(nic, 0, sizeof(perInterface_wlan_t)); - /*Name the Devices*/ if (i == 0) { - #if defined(NM73131) /* tony, 2012-09-20 */ + #if defined(NM73131) strcpy(ndev->name, "wilc_eth%d"); - #elif defined(PLAT_CLM9722) /* rachel */ + #elif defined(PLAT_CLM9722) strcpy(ndev->name, "eth%d"); - #else /* PANDA_BOARD, PLAT_ALLWINNER_A10, PLAT_ALLWINNER_A20, PLAT_ALLWINNER_A31, PLAT_AML8726_M3 or PLAT_WMS8304 */ + #else strcpy(ndev->name, "wlan%d"); #endif } else @@ -1717,11 +1554,9 @@ int wilc_netdev_init(struct wilc **wilc) { struct wireless_dev *wdev; - /*Register WiFi*/ wdev = wilc_create_wiphy(ndev); #ifdef WILC_SDIO - /* set netdev, tony */ SET_NETDEV_DEV(ndev, &local_sdio_func->dev); #endif @@ -1730,7 +1565,6 @@ int wilc_netdev_init(struct wilc **wilc) return -1; } - /*linking the wireless_dev structure with the netdevice*/ nic->wilc_netdev->ieee80211_ptr = wdev; nic->wilc_netdev->ml_priv = nic; wdev->netdev = nic->wilc_netdev; @@ -1742,7 +1576,7 @@ int wilc_netdev_init(struct wilc **wilc) if (register_netdev(ndev)) { PRINT_ER("Device couldn't be registered - %s\n", ndev->name); - return -1; /* ERROR */ + return -1; } nic->iftype = STATION_MODE; @@ -1752,7 +1586,7 @@ int wilc_netdev_init(struct wilc **wilc) #ifndef WILC_SDIO if (!linux_spi_init(&g_linux_wlan->wilc_spidev)) { PRINT_ER("Can't initialize SPI\n"); - return -1; /* ERROR */ + return -1; } g_linux_wlan->wilc_spidev = wilc_spi_dev; #else @@ -1762,7 +1596,6 @@ int wilc_netdev_init(struct wilc **wilc) return 0; } -/*The 1st function called after module inserted*/ static int __init init_wilc_driver(void) { #ifdef WILC_SPI -- GitLab From 84d3b87e8b0d10088515da69829fc623833661c4 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:19 +0900 Subject: [PATCH 0240/2855] staging: wilc1000: linux_wlan: remove unused defines This patch removes unused defines from linux_wlan.c file. - NM73131 - PLAT_CLM9722 Two defines are support custom feature that don't used anymore. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 105dbc809a5c0..432f0be99cc0e 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1534,15 +1534,9 @@ int wilc_netdev_init(struct wilc **wilc) nic = netdev_priv(ndev); memset(nic, 0, sizeof(perInterface_wlan_t)); - if (i == 0) { - #if defined(NM73131) - strcpy(ndev->name, "wilc_eth%d"); - #elif defined(PLAT_CLM9722) - strcpy(ndev->name, "eth%d"); - #else + if (i == 0) strcpy(ndev->name, "wlan%d"); - #endif - } else + else strcpy(ndev->name, "p2p%d"); nic->u8IfIdx = g_linux_wlan->vif_num; -- GitLab From 7df00115f820d66d362820306438e73fcccf16d0 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:20 +0900 Subject: [PATCH 0241/2855] staging: wilc1000: remove extern function in c file and move it to header file. This patch removes extern resolve_disconnect_aberration in c file and move it to proper header file. Rename argument also to match with declaration. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/linux_wlan.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 72c47974d2d82..f73817a4d4353 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -420,5 +420,5 @@ void host_int_freeJoinParams(void *pJoinParams); s32 host_int_get_statistics(struct host_if_drv *hWFIDrv, struct rf_info *pstrStatistics); - +void resolve_disconnect_aberration(struct host_if_drv *hif_drv); #endif diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 432f0be99cc0e..3aedc288ade11 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -38,7 +38,6 @@ #define _linux_wlan_device_removal() {} extern bool g_obtainingIP; -extern void resolve_disconnect_aberration(void *drvHandler); extern u8 multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; extern struct timer_list hDuringIpTimer; -- GitLab From 582f8a2710f4fc78edfe2b33ebf6598fe02e9688 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:21 +0900 Subject: [PATCH 0242/2855] staging: wilc1000: remove warnings line over 80 characters This patch removes the warnings reported by checkpatch.pl for line over 80 characters. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 40 ++++++++++++++++++--------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 3aedc288ade11..4b2afa05d1760 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -122,7 +122,8 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event return NOTIFY_DONE; } - if ((memcmp(dev_iface->ifa_label, "wlan0", 5)) && (memcmp(dev_iface->ifa_label, "p2p0", 4))) { + if (memcmp(dev_iface->ifa_label, "wlan0", 5) && + memcmp(dev_iface->ifa_label, "p2p0", 4)) { PRINT_D(GENERIC_DBG, "Interface is neither WLAN0 nor P2P0\n"); return NOTIFY_DONE; } @@ -305,7 +306,8 @@ int linux_wlan_lock_timeout(void *vp, u32 timeout) PRINT_D(LOCK_DBG, "Locking %p\n", vp); if (vp) - error = down_timeout((struct semaphore *)vp, msecs_to_jiffies(timeout)); + error = down_timeout((struct semaphore *)vp, + msecs_to_jiffies(timeout)); else PRINT_ER("Failed, mutex is NULL\n"); return error; @@ -316,7 +318,8 @@ void linux_wlan_mac_indicate(struct wilc *wilc, int flag) int status; if (flag == WILC_MAC_INDICATE_STATUS) { - wilc_wlan_cfg_get_val(WID_STATUS, (unsigned char *)&status, 4); + wilc_wlan_cfg_get_val(WID_STATUS, + (unsigned char *)&status, 4); if (wilc->mac_status == WILC_MAC_STATUS_INIT) { wilc->mac_status = status; up(&wilc->sync_event); @@ -589,7 +592,9 @@ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_ni hif_drv = (struct host_if_drv *)priv->hWILCWFIDrv; PRINT_D(INIT_DBG, "Host = %p\n", hif_drv); - PRINT_D(INIT_DBG, "MAC address is : %02x-%02x-%02x-%02x-%02x-%02x\n", mac_add[0], mac_add[1], mac_add[2], mac_add[3], mac_add[4], mac_add[5]); + PRINT_D(INIT_DBG, "MAC address is : %02x-%02x-%02x-%02x-%02x-%02x\n", + mac_add[0], mac_add[1], mac_add[2], + mac_add[3], mac_add[4], mac_add[5]); wilc_get_chipid(0); *(int *)c_val = 1; @@ -1133,10 +1138,14 @@ int mac_open(struct net_device *ndev) goto _err_; } - wilc_mgmt_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, nic->wilc_netdev->ieee80211_ptr, - nic->g_struct_frame_reg[0].frame_type, nic->g_struct_frame_reg[0].reg); - wilc_mgmt_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, nic->wilc_netdev->ieee80211_ptr, - nic->g_struct_frame_reg[1].frame_type, nic->g_struct_frame_reg[1].reg); + wilc_mgmt_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, + nic->wilc_netdev->ieee80211_ptr, + nic->g_struct_frame_reg[0].frame_type, + nic->g_struct_frame_reg[0].reg); + wilc_mgmt_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, + nic->wilc_netdev->ieee80211_ptr, + nic->g_struct_frame_reg[1].frame_type, + nic->g_struct_frame_reg[1].reg); netif_wake_queue(ndev); wl->open_ifcs++; nic->mac_opened = 1; @@ -1168,14 +1177,16 @@ static void wilc_set_multicast_list(struct net_device *dev) if (!dev) return; - PRINT_D(INIT_DBG, "Setting Multicast List with count = %d.\n", dev->mc.count); + PRINT_D(INIT_DBG, "Setting Multicast List with count = %d.\n", + dev->mc.count); if (dev->flags & IFF_PROMISC) { PRINT_D(INIT_DBG, "Set promiscuous mode ON, retrive all packets\n"); return; } - if ((dev->flags & IFF_ALLMULTI) || (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) { + if ((dev->flags & IFF_ALLMULTI) || + (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) { PRINT_D(INIT_DBG, "Disable multicast filter, retrive all multicast packets\n"); host_int_setup_multicast_filter(hif_drv, false, 0); return; @@ -1256,7 +1267,8 @@ int mac_xmit(struct sk_buff *skb, struct net_device *ndev) ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr)); pu8UdpBuffer = (char *)ih + sizeof(struct iphdr); - if ((pu8UdpBuffer[1] == 68 && pu8UdpBuffer[3] == 67) || (pu8UdpBuffer[1] == 67 && pu8UdpBuffer[3] == 68)) + if ((pu8UdpBuffer[1] == 68 && pu8UdpBuffer[3] == 67) || + (pu8UdpBuffer[1] == 67 && pu8UdpBuffer[3] == 68)) PRINT_D(GENERIC_DBG, "DHCP Message transmitted, type:%x %x %x\n", pu8UdpBuffer[248], pu8UdpBuffer[249], pu8UdpBuffer[250]); PRINT_D(TX_DBG, "Sending packet - Size = %d - Address = %p - SKB = %p\n", tx_data->size, tx_data->buff, tx_data->skb); @@ -1363,7 +1375,8 @@ int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) size = wrq->u.data.length; if (size && wrq->u.data.pointer) { - buff = memdup_user(wrq->u.data.pointer, wrq->u.data.length); + buff = memdup_user(wrq->u.data.pointer, + wrq->u.data.length); if (IS_ERR(buff)) return PTR_ERR(buff); @@ -1568,7 +1581,8 @@ int wilc_netdev_init(struct wilc **wilc) } if (register_netdev(ndev)) { - PRINT_ER("Device couldn't be registered - %s\n", ndev->name); + PRINT_ER("Device couldn't be registered - %s\n", + ndev->name); return -1; } -- GitLab From 5191d771ca3c4e65b338e7d66a457b2341d76ed1 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:22 +0900 Subject: [PATCH 0243/2855] staging: wilc1000: fixes add spaces required around that '&&' This patch fixes add to spaces around that '&&' or '||'. Reported by checkpatch.pl for spaces required around that '&&' or '||' (ctx:VxE). Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 4b2afa05d1760..aecb89d2bc594 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1093,7 +1093,7 @@ int mac_open(struct net_device *ndev) wl = nic->wilc; #ifdef WILC_SPI - if (!wl|| !wl->wilc_spidev) { + if (!wl || !wl->wilc_spidev) { netdev_err(ndev, "wilc1000: SPI device not ready\n"); return -ENODEV; } @@ -1495,8 +1495,7 @@ void wl_wlan_cleanup(struct wilc *wilc) if (wilc && wilc->firmware) release_firmware(wilc->firmware); - if (wilc&& - (wilc->vif[0].ndev || wilc->vif[1].ndev)) { + if (wilc && (wilc->vif[0].ndev || wilc->vif[1].ndev)) { linux_wlan_lock_timeout(&close_exit_sync, 12 * 1000); for (i = 0; i < NUM_CONCURRENT_IFC; i++) -- GitLab From 3d6d8cd890afa9c2bcdc19e5b77e450717f1c7e7 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:23 +0900 Subject: [PATCH 0244/2855] staging: wilc1000: remove do-nothing if condition case. This patch removes do-nothing if condition case. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index aecb89d2bc594..94efb4a66240f 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -326,9 +326,6 @@ void linux_wlan_mac_indicate(struct wilc *wilc, int flag) } else { wilc->mac_status = status; } - - if (wilc->mac_status == WILC_MAC_STATUS_CONNECT) { - } } else if (flag == WILC_MAC_INDICATE_SCAN) { PRINT_D(GENERIC_DBG, "Scanning ...\n"); } -- GitLab From 7e725b474baf922c2c6fe6cdae7bbb81abe55a64 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:24 +0900 Subject: [PATCH 0245/2855] staging: wilc1000: rename function GetIfHandler This patch renames GetIfHandler function name to get_if_handler to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 94efb4a66240f..3da80cd54c4b9 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -331,7 +331,7 @@ void linux_wlan_mac_indicate(struct wilc *wilc, int flag) } } -struct net_device *GetIfHandler(struct wilc *wilc, u8 *pMacHeader) +struct net_device *get_if_handler(struct wilc *wilc, u8 *pMacHeader) { u8 *Bssid, *Bssid1; int i = 0; @@ -1422,7 +1422,7 @@ void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset) struct net_device *wilc_netdev; perInterface_wlan_t *nic; - wilc_netdev = GetIfHandler(wilc, buff); + wilc_netdev = get_if_handler(wilc, buff); if (!wilc_netdev) return; -- GitLab From 51456c2a6152130d093d81f1148383aae09cb355 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:25 +0900 Subject: [PATCH 0246/2855] staging: wilc1000: rename pMacHeader of function get_if_handler This patch renames pMacHeader of function get_if_handler to mac_header to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 3da80cd54c4b9..67e89286f13b7 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -331,13 +331,13 @@ void linux_wlan_mac_indicate(struct wilc *wilc, int flag) } } -struct net_device *get_if_handler(struct wilc *wilc, u8 *pMacHeader) +struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header) { u8 *Bssid, *Bssid1; int i = 0; - Bssid = pMacHeader + 10; - Bssid1 = pMacHeader + 4; + Bssid = mac_header + 10; + Bssid1 = mac_header + 4; for (i = 0; i < wilc->vif_num; i++) if (!memcmp(Bssid1, wilc->vif[i].bssid, ETH_ALEN) || @@ -346,9 +346,9 @@ struct net_device *get_if_handler(struct wilc *wilc, u8 *pMacHeader) PRINT_INFO(INIT_DBG, "Invalide handle\n"); for (i = 0; i < 25; i++) - PRINT_D(INIT_DBG, "%02x ", pMacHeader[i]); - Bssid = pMacHeader + 18; - Bssid1 = pMacHeader + 12; + PRINT_D(INIT_DBG, "%02x ", mac_header[i]); + Bssid = mac_header + 18; + Bssid1 = mac_header + 12; for (i = 0; i < wilc->vif_num; i++) if (!memcmp(Bssid1, wilc->vif[i].bssid, ETH_ALEN) || !memcmp(Bssid, wilc->vif[i].bssid, ETH_ALEN)) -- GitLab From d239222e82a209af611840b2a7cd72c26944eb12 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:26 +0900 Subject: [PATCH 0247/2855] staging: wilc1000: rename Bssid of function get_if_handler This patch renames Bssid of function get_if_handler to bssid to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 67e89286f13b7..64b7c4f340a83 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -333,25 +333,25 @@ void linux_wlan_mac_indicate(struct wilc *wilc, int flag) struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header) { - u8 *Bssid, *Bssid1; + u8 *bssid, *Bssid1; int i = 0; - Bssid = mac_header + 10; + bssid = mac_header + 10; Bssid1 = mac_header + 4; for (i = 0; i < wilc->vif_num; i++) if (!memcmp(Bssid1, wilc->vif[i].bssid, ETH_ALEN) || - !memcmp(Bssid, wilc->vif[i].bssid, ETH_ALEN)) + !memcmp(bssid, wilc->vif[i].bssid, ETH_ALEN)) return wilc->vif[i].ndev; PRINT_INFO(INIT_DBG, "Invalide handle\n"); for (i = 0; i < 25; i++) PRINT_D(INIT_DBG, "%02x ", mac_header[i]); - Bssid = mac_header + 18; + bssid = mac_header + 18; Bssid1 = mac_header + 12; for (i = 0; i < wilc->vif_num; i++) if (!memcmp(Bssid1, wilc->vif[i].bssid, ETH_ALEN) || - !memcmp(Bssid, wilc->vif[i].bssid, ETH_ALEN)) + !memcmp(bssid, wilc->vif[i].bssid, ETH_ALEN)) return wilc->vif[i].ndev; PRINT_INFO(INIT_DBG, "\n"); -- GitLab From 660786eae129346c31f79d73a6ff3c8d3f70fd45 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:27 +0900 Subject: [PATCH 0248/2855] staging: wilc1000: rename Bssid1 of function get_if_handler This patch renames Bssid1 of function get_if_handler to bssid1 to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 64b7c4f340a83..6758cbc04af92 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -333,14 +333,14 @@ void linux_wlan_mac_indicate(struct wilc *wilc, int flag) struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header) { - u8 *bssid, *Bssid1; + u8 *bssid, *bssid1; int i = 0; bssid = mac_header + 10; - Bssid1 = mac_header + 4; + bssid1 = mac_header + 4; for (i = 0; i < wilc->vif_num; i++) - if (!memcmp(Bssid1, wilc->vif[i].bssid, ETH_ALEN) || + if (!memcmp(bssid1, wilc->vif[i].bssid, ETH_ALEN) || !memcmp(bssid, wilc->vif[i].bssid, ETH_ALEN)) return wilc->vif[i].ndev; @@ -348,9 +348,9 @@ struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header) for (i = 0; i < 25; i++) PRINT_D(INIT_DBG, "%02x ", mac_header[i]); bssid = mac_header + 18; - Bssid1 = mac_header + 12; + bssid1 = mac_header + 12; for (i = 0; i < wilc->vif_num; i++) - if (!memcmp(Bssid1, wilc->vif[i].bssid, ETH_ALEN) || + if (!memcmp(bssid1, wilc->vif[i].bssid, ETH_ALEN) || !memcmp(bssid, wilc->vif[i].bssid, ETH_ALEN)) return wilc->vif[i].ndev; -- GitLab From f66dee7bfd5d378351c435ad8d49b7b8c2f1b665 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:28 +0900 Subject: [PATCH 0249/2855] staging: wilc1000: rename pBSSID of function linux_wlan_set_bssid This patch renames pBSSID of function linux_wlan_set_bssid to bssid to avoid CamelCase naming convention. Also, prototype linux_wlan_set_bssid in wilc_wfi_cfgoperations.c is moved to wilc_wfi_netdevice.h. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 4 ++-- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 2 -- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 6758cbc04af92..2fac99d059023 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -358,7 +358,7 @@ struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header) return NULL; } -int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *pBSSID) +int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid) { int i = 0; int ret = -1; @@ -370,7 +370,7 @@ int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *pBSSID) for (i = 0; i < wilc->vif_num; i++) if (wilc->vif[i].ndev == wilc_netdev) { - memcpy(wilc->vif[i].bssid, pBSSID, 6); + memcpy(wilc->vif[i].bssid, bssid, 6); ret = 0; break; } diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 32b93d3f806da..e8c82725d628b 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -505,8 +505,6 @@ int WILC_WFI_Set_PMKSA(u8 *bssid, struct wilc_priv *priv) } -int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *pBSSID); - /** * @brief CfgConnectResult diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 07917ea105b60..9b11b713b8c86 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -219,4 +219,5 @@ void wilc1000_wlan_deinit(struct net_device *dev); void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size); u16 Set_machw_change_vir_if(struct net_device *dev, bool bValue); int linux_wlan_get_firmware(struct net_device *dev); +int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid); #endif -- GitLab From 1b7a93ad9a5ebdef7968d2bf6c5ebd1db2c3e022 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:29 +0900 Subject: [PATCH 0250/2855] staging: wilc1000: fixes braces {} should be used on all arms of this statement This patch fixes the checks reported by checkpatch.pl for braces {} should be used on all arms of this statement. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 2fac99d059023..893c741794b8d 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -477,12 +477,11 @@ int linux_wlan_get_firmware(struct net_device *dev) nic = netdev_priv(dev); wilc = nic->wilc; - if (nic->iftype == AP_MODE) + if (nic->iftype == AP_MODE) { firmware = AP_FIRMWARE; - else if (nic->iftype == STATION_MODE) + } else if (nic->iftype == STATION_MODE) { firmware = STA_FIRMWARE; - - else { + } else { PRINT_D(INIT_DBG, "Get P2P_CONCURRENCY_FIRMWARE\n"); firmware = P2P_CONCURRENCY_FIRMWARE; } -- GitLab From 0aeea1ad2ab342153019b676a2d3cbbb45669c79 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:30 +0900 Subject: [PATCH 0251/2855] staging: wilc1000: remove goto from linux_wlan_start_firmware This patch remove goto feature from linux_wlan_start_firmware function. Goto feature is return result. So, remove goto functions and it was replaced with the return value directly. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 893c741794b8d..fcc8119093438 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -529,19 +529,18 @@ static int linux_wlan_start_firmware(struct net_device *dev) ret = wilc_wlan_start(); if (ret < 0) { PRINT_ER("Failed to start Firmware\n"); - goto _fail_; + return ret; } PRINT_D(INIT_DBG, "Waiting for Firmware to get ready ...\n"); ret = linux_wlan_lock_timeout(&wilc->sync_event, 5000); if (ret) { PRINT_D(INIT_DBG, "Firmware start timed out"); - goto _fail_; + return ret; } PRINT_D(INIT_DBG, "Firmware successfully started\n"); -_fail_: - return ret; + return 0; } static int linux_wlan_firmware_download(struct net_device *dev) { -- GitLab From 14b1821dd2ee72ac5ce360c8a420f4e87b0e923a Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:31 +0900 Subject: [PATCH 0252/2855] staging: wilc1000: remove goto from linux_wlan_firmware_download This patch remove goto feature from linux_wlan_firmware_download function. Goto feature is return result. So, remove goto functions and it was replaced with the return value directly. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index fcc8119093438..003165d57cfbc 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -553,14 +553,13 @@ static int linux_wlan_firmware_download(struct net_device *dev) if (!wilc->firmware) { PRINT_ER("Firmware buffer is NULL\n"); - ret = -ENOBUFS; - goto _FAIL_; + return -ENOBUFS; } PRINT_D(INIT_DBG, "Downloading Firmware ...\n"); ret = wilc_wlan_firmware_download(wilc->firmware->data, wilc->firmware->size); if (ret < 0) - goto _FAIL_; + return ret; PRINT_D(INIT_DBG, "Freeing FW buffer ...\n"); PRINT_D(INIT_DBG, "Releasing firmware\n"); @@ -568,8 +567,7 @@ static int linux_wlan_firmware_download(struct net_device *dev) PRINT_D(INIT_DBG, "Download Succeeded\n"); -_FAIL_: - return ret; + return 0; } static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_nic) -- GitLab From a40b22c544ce6bd70f14cf8c5fcb07ef5e64e5d5 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:32 +0900 Subject: [PATCH 0253/2855] staging: wilc1000: fixes missing a blank line after declarations This patch fixes the warnings reported by checkpatch.pl for Missing a blank line after declarations. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 003165d57cfbc..c529a15723551 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -542,6 +542,7 @@ static int linux_wlan_start_firmware(struct net_device *dev) return 0; } + static int linux_wlan_firmware_download(struct net_device *dev) { perInterface_wlan_t *nic; @@ -880,6 +881,7 @@ static int wlan_deinit_locks(struct net_device *dev) return 0; } + void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic) { PRINT_D(INIT_DBG, "Linux to Wlan services ...\n"); -- GitLab From 6bc72c5ac7996819961bf65d64693efd3135ea42 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:33 +0900 Subject: [PATCH 0254/2855] staging: wilc1000: remove goto from wlan_initialize_threads This patch remove goto feature from wlan_initialize_threads function. Goto feature is 'wilc->close=0' & return result. So, remove goto feature and it was replaced with the return value directly, as well as removed unused ret variable. Also, execute 'wilc->close=0' before return. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index c529a15723551..3c8155ec657c9 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -911,7 +911,6 @@ int wlan_initialize_threads(struct net_device *dev) { perInterface_wlan_t *nic; struct wilc *wilc; - int ret = 0; nic = netdev_priv(dev); wilc = nic->wilc; @@ -922,16 +921,12 @@ int wlan_initialize_threads(struct net_device *dev) "K_TXQ_TASK"); if (!wilc->txq_thread) { PRINT_ER("couldn't create TXQ thread\n"); - ret = -ENOBUFS; - goto _fail_2; + wilc->close = 0; + return -ENOBUFS; } down(&wilc->txq_thread_started); return 0; - -_fail_2: - wilc->close = 0; - return ret; } static void wlan_deinitialize_threads(struct net_device *dev) -- GitLab From 339d244a124da49ba1100189cf881448a30b8774 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:34 +0900 Subject: [PATCH 0255/2855] staging: wilc1000: remove goto from mac_open This patch removes goto from mac_open function. If address is invalid, goto handles deinit process and return result. So, just call deinit process and return the error value directly instead of goto statement. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 3c8155ec657c9..6492103f6bb19 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1124,8 +1124,9 @@ int mac_open(struct net_device *ndev) if (!is_valid_ether_addr(ndev->dev_addr)) { PRINT_ER("Error: Wrong MAC address\n"); - ret = -EINVAL; - goto _err_; + wilc_deinit_host_int(ndev); + wilc1000_wlan_deinit(ndev); + return -EINVAL; } wilc_mgmt_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, @@ -1140,11 +1141,6 @@ int mac_open(struct net_device *ndev) wl->open_ifcs++; nic->mac_opened = 1; return 0; - -_err_: - wilc_deinit_host_int(ndev); - wilc1000_wlan_deinit(ndev); - return ret; } struct net_device_stats *mac_stats(struct net_device *dev) -- GitLab From 2ad8c47d5c6c989cd7a1fd3eeb4e3c7c09dd327b Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:35 +0900 Subject: [PATCH 0256/2855] staging: wilc1000: rename Set_machw_change_vir_if function This patch rename Set_machw_change_vir_if function to set_machw_change_vir_if to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 2 +- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 6 +++--- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 2 +- drivers/staging/wilc1000/wilc_wlan.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 6492103f6bb19..79e755c108afa 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1107,7 +1107,7 @@ int mac_open(struct net_device *ndev) return ret; } - Set_machw_change_vir_if(ndev, false); + set_machw_change_vir_if(ndev, false); host_int_get_MacAddress(priv->hWILCWFIDrv, mac_add); PRINT_D(INIT_DBG, "Mac address: %pM\n", mac_add); diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index e8c82725d628b..5291868b70773 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -1408,7 +1408,7 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev, g_key_gtk_params.seq = NULL; /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/ - Set_machw_change_vir_if(netdev, false); + set_machw_change_vir_if(netdev, false); } if (key_index >= 0 && key_index <= 3) { @@ -2548,7 +2548,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n"); /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/ if (g_ptk_keys_saved && g_gtk_keys_saved) { - Set_machw_change_vir_if(dev, true); + set_machw_change_vir_if(dev, true); } switch (type) { @@ -2710,7 +2710,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, /*Refresh scan, to refresh the scan results to the wpa_supplicant. Set MachHw to false to enable further key installments*/ refresh_scan(priv, 1, true); - Set_machw_change_vir_if(dev, false); + set_machw_change_vir_if(dev, false); if (wl->initialized) { for (i = 0; i < num_reg_frame; i++) { diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 9b11b713b8c86..6f9da09f74c02 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -217,7 +217,7 @@ void wl_wlan_cleanup(struct wilc *wilc); int wilc_netdev_init(struct wilc **wilc); void wilc1000_wlan_deinit(struct net_device *dev); void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size); -u16 Set_machw_change_vir_if(struct net_device *dev, bool bValue); +u16 set_machw_change_vir_if(struct net_device *dev, bool bValue); int linux_wlan_get_firmware(struct net_device *dev); int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid); #endif diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 16224cefea791..0e5535e7c7044 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -2052,7 +2052,7 @@ _fail_: } -u16 Set_machw_change_vir_if(struct net_device *dev, bool bValue) +u16 set_machw_change_vir_if(struct net_device *dev, bool bValue) { u16 ret; u32 reg; -- GitLab From e5f352441b5eace23a402b3919e02852505cf6e7 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:36 +0900 Subject: [PATCH 0257/2855] staging: wilc1000: rename host_int_get_MacAddress function This patch rename host_int_get_MacAddress function to hif_get_mac_address to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 +- drivers/staging/wilc1000/host_interface.h | 2 +- drivers/staging/wilc1000/linux_wlan.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index d0e4039e6ed1a..84a2479600900 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3396,7 +3396,7 @@ s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv, return 0; } -s32 host_int_get_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress) +s32 hif_get_mac_address(struct host_if_drv *hif_drv, u8 *pu8MacAddress) { s32 result = 0; struct host_if_msg msg; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index f73817a4d4353..f70da7556a817 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -333,7 +333,7 @@ s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hWFIDrv, u8 u8Psklength); s32 host_int_get_RSNAConfigPSKPassPhrase(struct host_if_drv *hWFIDrv, u8 *pu8PassPhrase, u8 u8Psklength); -s32 host_int_get_MacAddress(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); +s32 hif_get_mac_address(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); s32 host_int_set_MacAddress(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); int host_int_wait_msg_queue_idle(void); s32 host_int_set_start_scan_req(struct host_if_drv *hWFIDrv, u8 scanSource); diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 79e755c108afa..f2de20ba2a299 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1109,7 +1109,7 @@ int mac_open(struct net_device *ndev) set_machw_change_vir_if(ndev, false); - host_int_get_MacAddress(priv->hWILCWFIDrv, mac_add); + hif_get_mac_address(priv->hWILCWFIDrv, mac_add); PRINT_D(INIT_DBG, "Mac address: %pM\n", mac_add); for (i = 0; i < wl->vif_num; i++) { -- GitLab From 9457b05ec50de47db5144c7747a4d0ca888bcb41 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:37 +0900 Subject: [PATCH 0258/2855] staging: wilc1000: rename s32Error of mac_ioctl function This patch rename s32Error variable of mac_ioctl function to ret to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index f2de20ba2a299..f1dcdfbe6d666 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1344,7 +1344,7 @@ int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) u32 size = 0, length = 0; perInterface_wlan_t *nic; struct wilc_priv *priv; - s32 s32Error = 0; + s32 ret = 0; struct wilc *wilc; nic = netdev_priv(ndev); @@ -1368,8 +1368,9 @@ int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) if (strncasecmp(buff, "RSSI", length) == 0) { priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy); - s32Error = host_int_get_rssi(priv->hWILCWFIDrv, &(rssi)); - if (s32Error) + ret = host_int_get_rssi(priv->hWILCWFIDrv, + &rssi); + if (ret) PRINT_ER("Failed to send get rssi param's message queue "); PRINT_INFO(GENERIC_DBG, "RSSI :%d\n", rssi); @@ -1379,7 +1380,7 @@ int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) if (copy_to_user(wrq->u.data.pointer, buff, size)) { PRINT_ER("%s: failed to copy data to user buffer\n", __func__); - s32Error = -EFAULT; + ret = -EFAULT; goto done; } } @@ -1390,7 +1391,7 @@ int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) default: { PRINT_INFO(GENERIC_DBG, "Command - %d - has been received\n", cmd); - s32Error = -EOPNOTSUPP; + ret = -EOPNOTSUPP; goto done; } } @@ -1399,7 +1400,7 @@ done: kfree(buff); - return s32Error; + return ret; } void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset) -- GitLab From 44ec3b75a68e071fbc4f30387a02f93ba1a3b358 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:38 +0900 Subject: [PATCH 0259/2855] staging: wilc1000: rename QueueCount of mac_xmit function This patch rename QueueCount variable of mac_xmit function to queue_count to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index f1dcdfbe6d666..7a07e431f7311 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1218,7 +1218,7 @@ int mac_xmit(struct sk_buff *skb, struct net_device *ndev) { perInterface_wlan_t *nic; struct tx_complete_data *tx_data = NULL; - int QueueCount; + int queue_count; char *pu8UdpBuffer; struct iphdr *ih; struct ethhdr *eth_h; @@ -1262,11 +1262,11 @@ int mac_xmit(struct sk_buff *skb, struct net_device *ndev) nic->netstats.tx_packets++; nic->netstats.tx_bytes += tx_data->size; tx_data->pBssid = wilc->vif[nic->u8IfIdx].bssid; - QueueCount = wilc_wlan_txq_add_net_pkt(ndev, (void *)tx_data, - tx_data->buff, tx_data->size, - linux_wlan_tx_complete); + queue_count = wilc_wlan_txq_add_net_pkt(ndev, (void *)tx_data, + tx_data->buff, tx_data->size, + linux_wlan_tx_complete); - if (QueueCount > FLOW_CONTROL_UPPER_THRESHOLD) { + if (queue_count > FLOW_CONTROL_UPPER_THRESHOLD) { netif_stop_queue(wilc->vif[0].ndev); netif_stop_queue(wilc->vif[1].ndev); } -- GitLab From fd8f03671b991031e4ed0f2840e36a3607aa57b2 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 5 Nov 2015 14:36:39 +0900 Subject: [PATCH 0260/2855] staging: wilc1000: rename pu8UdpBuffer of mac_xmit function This patch rename pu8UdpBuffer variable of mac_xmit function to udp_buf to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 7a07e431f7311..f82ecb99a7a52 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1219,7 +1219,7 @@ int mac_xmit(struct sk_buff *skb, struct net_device *ndev) perInterface_wlan_t *nic; struct tx_complete_data *tx_data = NULL; int queue_count; - char *pu8UdpBuffer; + char *udp_buf; struct iphdr *ih; struct ethhdr *eth_h; struct wilc *wilc; @@ -1252,10 +1252,11 @@ int mac_xmit(struct sk_buff *skb, struct net_device *ndev) ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr)); - pu8UdpBuffer = (char *)ih + sizeof(struct iphdr); - if ((pu8UdpBuffer[1] == 68 && pu8UdpBuffer[3] == 67) || - (pu8UdpBuffer[1] == 67 && pu8UdpBuffer[3] == 68)) - PRINT_D(GENERIC_DBG, "DHCP Message transmitted, type:%x %x %x\n", pu8UdpBuffer[248], pu8UdpBuffer[249], pu8UdpBuffer[250]); + udp_buf = (char *)ih + sizeof(struct iphdr); + if ((udp_buf[1] == 68 && udp_buf[3] == 67) || + (udp_buf[1] == 67 && udp_buf[3] == 68)) + PRINT_D(GENERIC_DBG, "DHCP Message transmitted, type:%x %x %x\n", + udp_buf[248], udp_buf[249], udp_buf[250]); PRINT_D(TX_DBG, "Sending packet - Size = %d - Address = %p - SKB = %p\n", tx_data->size, tx_data->buff, tx_data->skb); PRINT_D(TX_DBG, "Adding tx packet to TX Queue\n"); -- GitLab From b22fa80cdbf4ff1056ecddb4efdcc0ede5f5f422 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Thu, 5 Nov 2015 16:12:08 +0900 Subject: [PATCH 0261/2855] staging: wilc1000: fix kbuild test robot error This patch fixes build warning and error reported by kbuild test robot. It is fixed by including netdevice.h. >> drivers/staging/wilc1000/wilc_wlan_if.h:940:27: warning: 'struct net_device' declared inside parameter list int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp); >> drivers/staging/wilc1000/wilc_wlan_if.h:940:27: warning: its scope is only this definition or declaration, which is probably not what you want >> drivers/staging/wilc1000/wilc_wlan.c:1954:5: error: conflicting types for 'wilc_wlan_init' int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) Fixes: 30135ce ("staging: wilc1000: wilc_wlan_init: add argument struct net_device") Reported-by: kbuild test robot Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan_if.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index f11003d144861..12cbc4bcac90b 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -12,6 +12,7 @@ #include #include "linux_wlan_common.h" +#include /******************************************** * -- GitLab From 83231b7233bfc924e7059512f3c497c8e90f2c2b Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:22 +0900 Subject: [PATCH 0262/2855] staging: wilc1000: fixes alignment should match open parenthesis This patch fixes the checks reported by checkpatch.pl for alignment should match open parenthesis Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index f82ecb99a7a52..976964d575817 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -264,9 +264,11 @@ static int init_irq(struct net_device *dev) PRINT_ER("could not obtain gpio for WILC_INTR\n"); } - if ((ret != -1) && (request_threaded_irq(wl->dev_irq_num, isr_uh_routine, isr_bh_routine, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - "WILC_IRQ", dev)) < 0) { + if (ret != -1 && request_threaded_irq(wl->dev_irq_num, + isr_uh_routine, + isr_bh_routine, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "WILC_IRQ", dev) < 0) { PRINT_ER("Failed to request IRQ for GPIO: %d\n", GPIO_NUM); ret = -1; } else { @@ -1472,8 +1474,7 @@ void wl_wlan_cleanup(struct wilc *wilc) int i = 0; perInterface_wlan_t *nic[NUM_CONCURRENT_IFC]; - if (wilc && - (wilc->vif[0].ndev || wilc->vif[1].ndev)) { + if (wilc && (wilc->vif[0].ndev || wilc->vif[1].ndev)) { unregister_inetaddr_notifier(&g_dev_notifier); for (i = 0; i < NUM_CONCURRENT_IFC; i++) -- GitLab From b38e903090e12503a21183916ec8e5101b3ed610 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:23 +0900 Subject: [PATCH 0263/2855] staging: wilc1000: fixes a struct allocation to match coding standards This patch fixes the checks reported by checkpatch.pl for prefer kmalloc(sizeof(*tx_data)...) over kmalloc(sizeof(struct tx_complete_data)...) Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 976964d575817..947c9f9916004 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1236,7 +1236,7 @@ int mac_xmit(struct sk_buff *skb, struct net_device *ndev) return 0; } - tx_data = kmalloc(sizeof(struct tx_complete_data), GFP_ATOMIC); + tx_data = kmalloc(sizeof(*tx_data), GFP_ATOMIC); if (!tx_data) { PRINT_ER("Failed to allocate memory for tx_data structure\n"); dev_kfree_skb(skb); -- GitLab From c8537e6dbaaeb259e6e29259cf3fd224a7f480ba Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:24 +0900 Subject: [PATCH 0264/2855] staging: wilc1000: fixes that open brace { should be on the previous line This patch fixes the error reported by checkpatch.pl for that open brace { should be on the previous line. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 947c9f9916004..c94cb1362a55b 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1186,8 +1186,7 @@ static void wilc_set_multicast_list(struct net_device *dev) return; } - netdev_for_each_mc_addr(ha, dev) - { + netdev_for_each_mc_addr(ha, dev) { memcpy(multicast_mac_addr_list[i], ha->addr, ETH_ALEN); PRINT_D(INIT_DBG, "Entry[%d]: %x:%x:%x:%x:%x:%x\n", i, multicast_mac_addr_list[i][0], -- GitLab From ac087c82c4ec088c31a117e209a7367dc68ed854 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:25 +0900 Subject: [PATCH 0265/2855] staging: wilc1000: wilc_wlan.c: remove over-commenting There are over-commenting in the wilc_wlan.c file and most of them are not helpful to explain what the code does and generate 80 ending line over warnings. So, all of comments are removed in this patch and the comments will later be added if necessary with the preferred Linux style. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 330 +++------------------------ 1 file changed, 27 insertions(+), 303 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 0e5535e7c7044..7aaad0f3928a0 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1,21 +1,7 @@ -/* ////////////////////////////////////////////////////////////////////////// */ -/* */ -/* Copyright (c) Atmel Corporation. All rights reserved. */ -/* */ -/* Module Name: wilc_wlan.c */ -/* */ -/* */ -/* //////////////////////////////////////////////////////////////////////////// */ - #include "wilc_wlan_if.h" #include "wilc_wfi_netdevice.h" #include "wilc_wlan_cfg.h" -/******************************************** - * - * Global - * - ********************************************/ extern wilc_hif_func_t hif_sdio; extern wilc_hif_func_t hif_spi; u32 wilc_get_chipid(u8 update); @@ -24,42 +10,20 @@ u32 wilc_get_chipid(u8 update); typedef struct { int quit; - - /** - * input interface functions - **/ wilc_wlan_io_func_t io_func; - - /** - * host interface functions - **/ wilc_hif_func_t hif_func; - - /** - * configuration interface functions - **/ int cfg_frame_in_use; wilc_cfg_frame_t cfg_frame; u32 cfg_frame_offset; int cfg_seq_no; - /** - * RX buffer - **/ #ifdef MEMORY_STATIC u8 *rx_buffer; u32 rx_buffer_offset; #endif - /** - * TX buffer - **/ u8 *tx_buffer; u32 tx_buffer_offset; - /** - * TX queue - **/ - unsigned long txq_spinlock_flags; struct txq_entry_t *txq_head; @@ -67,9 +31,6 @@ typedef struct { int txq_entries; int txq_exit; - /** - * RX queue - **/ struct rxq_entry_t *rxq_head; struct rxq_entry_t *rxq_tail; int rxq_entries; @@ -82,12 +43,6 @@ static wilc_wlan_dev_t g_wlan; static inline void chip_allow_sleep(void); static inline void chip_wakeup(void); -/******************************************** - * - * Debug - * - ********************************************/ - static u32 dbgflag = N_INIT | N_ERR | N_INTR | N_TXQ | N_RXQ; static void wilc_debug(u32 flag, char *fmt, ...) @@ -106,9 +61,6 @@ static void wilc_debug(u32 flag, char *fmt, ...) static CHIP_PS_STATE_T genuChipPSstate = CHIP_WAKEDUP; -/*acquire_bus() and release_bus() are made static inline functions*/ -/*as a temporary workaround to fix a problem of receiving*/ -/*unknown interrupt from FW*/ static inline void acquire_bus(BUS_ACQUIRE_T acquire) { @@ -130,11 +82,6 @@ static inline void release_bus(BUS_RELEASE_T release) #endif mutex_unlock(&g_linux_wlan->hif_cs); } -/******************************************** - * - * Queue - * - ********************************************/ static void wilc_wlan_txq_remove(struct txq_entry_t *tqe) { @@ -219,9 +166,6 @@ static void wilc_wlan_txq_add_to_tail(struct net_device *dev, spin_unlock_irqrestore(&wilc->txq_spinlock, flags); - /** - * wake up TX queue - **/ PRINT_D(TX_DBG, "Wake the txq_handling\n"); up(&wilc->txq_event); @@ -253,11 +197,6 @@ static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe) spin_unlock_irqrestore(&g_linux_wlan->txq_spinlock, flags); up(&g_linux_wlan->txq_add_to_head_cs); - - - /** - * wake up TX queue - **/ up(&g_linux_wlan->txq_event); PRINT_D(TX_DBG, "Wake up the txq_handler\n"); @@ -281,7 +220,7 @@ typedef struct { u32 ack_num; u32 Session_index; struct txq_entry_t *txqe; -} Pending_Acks_info_t /*Ack_info_t*/; +} Pending_Acks_info_t; @@ -373,7 +312,7 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) eth_hdr_ptr = &buffer[0]; h_proto = ntohs(*((unsigned short *)ð_hdr_ptr[12])); - if (h_proto == 0x0800) { /* IP */ + if (h_proto == 0x0800) { u8 *ip_hdr_ptr; u8 protocol; @@ -389,7 +328,7 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) IHL = (ip_hdr_ptr[0] & 0xf) << 2; Total_Length = (((u32)ip_hdr_ptr[2]) << 8) + ((u32)ip_hdr_ptr[3]); Data_offset = (((u32)tcp_hdr_ptr[12] & 0xf0) >> 2); - if (Total_Length == (IHL + Data_offset)) { /*we want to recognize the clear Acks(packet only carry Ack infos not with data) so data size must be equal zero*/ + if (Total_Length == (IHL + Data_offset)) { u32 seq_no, Ack_no; seq_no = (((u32)tcp_hdr_ptr[4]) << 24) + (((u32)tcp_hdr_ptr[5]) << 16) + (((u32)tcp_hdr_ptr[6]) << 8) + ((u32)tcp_hdr_ptr[7]); @@ -443,7 +382,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) if (tqe) { wilc_wlan_txq_remove(tqe); Statisitcs_DroppedAcks++; - tqe->status = 1; /* mark the packet send */ + tqe->status = 1; if (tqe->tx_complete_func) tqe->tx_complete_func(tqe->priv, tqe->status); kfree(tqe); @@ -463,7 +402,6 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) spin_unlock_irqrestore(&wilc->txq_spinlock, p->txq_spinlock_flags); while (Dropped > 0) { - /*consume the semaphore count of the removed packet*/ linux_wlan_lock_timeout(&wilc->txq_event, 1); Dropped--; } @@ -510,9 +448,6 @@ static int wilc_wlan_txq_add_cfg_pkt(u8 *buffer, u32 buffer_size) #ifdef TCP_ACK_FILTER tqe->tcp_PendingAck_index = NOT_TCP_ACK; #endif - /** - * Configuration packet always at the front - **/ PRINT_D(TX_DBG, "Adding the config packet at the Queue tail\n"); if (wilc_wlan_txq_add_to_head(tqe)) @@ -546,7 +481,6 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, tcp_process(dev, tqe); #endif wilc_wlan_txq_add_to_tail(dev, tqe); - /*return number of itemes in the queue*/ return p->txq_entries; } @@ -651,22 +585,12 @@ static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc) return NULL; } - -/******************************************** - * - * Power Save handle functions - * - ********************************************/ - - - #ifdef WILC_OPTIMIZE_SLEEP_INT static inline void chip_allow_sleep(void) { u32 reg = 0; - /* Clear bit 1 */ g_wlan.hif_func.hif_read_reg(0xf0, ®); g_wlan.hif_func.hif_write_reg(0xf0, reg & ~BIT(0)); @@ -680,17 +604,11 @@ static inline void chip_wakeup(void) if ((g_wlan.io_func.io_type & 0x1) == HIF_SPI) { do { g_wlan.hif_func.hif_read_reg(1, ®); - /* Set bit 1 */ g_wlan.hif_func.hif_write_reg(1, reg | BIT(1)); - - /* Clear bit 1*/ g_wlan.hif_func.hif_write_reg(1, reg & ~BIT(1)); do { - /* Wait for the chip to stabilize*/ usleep_range(2 * 1000, 2 * 1000); - /* Make sure chip is awake. This is an extra step that can be removed */ - /* later to avoid the bus access overhead */ if ((wilc_get_chipid(true) == 0)) wilc_debug(N_ERR, "Couldn't read chip id. Wake up failed\n"); @@ -700,30 +618,19 @@ static inline void chip_wakeup(void) } else if ((g_wlan.io_func.io_type & 0x1) == HIF_SDIO) { g_wlan.hif_func.hif_read_reg(0xf0, ®); do { - /* Set bit 1 */ g_wlan.hif_func.hif_write_reg(0xf0, reg | BIT(0)); - - /* Check the clock status */ g_wlan.hif_func.hif_read_reg(0xf1, &clk_status_reg); - /* in case of clocks off, wait 2ms, and check it again. */ - /* if still off, wait for another 2ms, for a total wait of 6ms. */ - /* If still off, redo the wake up sequence */ while (((clk_status_reg & 0x1) == 0) && (((++trials) % 3) == 0)) { - /* Wait for the chip to stabilize*/ usleep_range(2 * 1000, 2 * 1000); - /* Make sure chip is awake. This is an extra step that can be removed */ - /* later to avoid the bus access overhead */ g_wlan.hif_func.hif_read_reg(0xf1, &clk_status_reg); if ((clk_status_reg & 0x1) == 0) wilc_debug(N_ERR, "clocks still OFF. Wake up failed\n"); } - /* in case of failure, Reset the wakeup bit to introduce a new edge on the next loop */ if ((clk_status_reg & 0x1) == 0) { - /* Reset bit 0 */ g_wlan.hif_func.hif_write_reg(0xf0, reg & (~BIT(0))); } @@ -737,7 +644,6 @@ static inline void chip_wakeup(void) g_wlan.hif_func.hif_write_reg(0x1C0C, reg); if (wilc_get_chipid(false) >= 0x1002b0) { - /* Enable PALDO back right after wakeup */ u32 val32; g_wlan.hif_func.hif_read_reg(0x1e1c, &val32); @@ -759,28 +665,19 @@ static inline void chip_wakeup(void) do { if ((g_wlan.io_func.io_type & 0x1) == HIF_SPI) { g_wlan.hif_func.hif_read_reg(1, ®); - /* Make sure bit 1 is 0 before we start. */ g_wlan.hif_func.hif_write_reg(1, reg & ~BIT(1)); - /* Set bit 1 */ g_wlan.hif_func.hif_write_reg(1, reg | BIT(1)); - /* Clear bit 1*/ g_wlan.hif_func.hif_write_reg(1, reg & ~BIT(1)); } else if ((g_wlan.io_func.io_type & 0x1) == HIF_SDIO) { - /* Make sure bit 0 is 0 before we start. */ g_wlan.hif_func.hif_read_reg(0xf0, ®); g_wlan.hif_func.hif_write_reg(0xf0, reg & ~BIT(0)); - /* Set bit 1 */ g_wlan.hif_func.hif_write_reg(0xf0, reg | BIT(0)); - /* Clear bit 1 */ g_wlan.hif_func.hif_write_reg(0xf0, reg & ~BIT(0)); } do { - /* Wait for the chip to stabilize*/ mdelay(3); - /* Make sure chip is awake. This is an extra step that can be removed */ - /* later to avoid the bus access overhead */ if ((wilc_get_chipid(true) == 0)) wilc_debug(N_ERR, "Couldn't read chip id. Wake up failed\n"); @@ -794,7 +691,6 @@ static inline void chip_wakeup(void) g_wlan.hif_func.hif_write_reg(0x1C0C, reg); if (wilc_get_chipid(false) >= 0x1002b0) { - /* Enable PALDO back right after wakeup */ u32 val32; g_wlan.hif_func.hif_read_reg(0x1e1c, &val32); @@ -811,17 +707,13 @@ static inline void chip_wakeup(void) #endif void chip_sleep_manually(u32 u32SleepTime) { - if (genuChipPSstate != CHIP_WAKEDUP) { - /* chip is already sleeping. Do nothing */ + if (genuChipPSstate != CHIP_WAKEDUP) return; - } acquire_bus(ACQUIRE_ONLY); #ifdef WILC_OPTIMIZE_SLEEP_INT chip_allow_sleep(); #endif - - /* Trigger the manual sleep interrupt */ g_wlan.hif_func.hif_write_reg(0x10a8, 1); genuChipPSstate = CHIP_SLEEPING_MANUAL; @@ -829,12 +721,6 @@ void chip_sleep_manually(u32 u32SleepTime) } - -/******************************************** - * - * Tx, Rx queue handle functions - * - ********************************************/ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) { wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; @@ -865,15 +751,12 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) #ifdef TCP_ACK_FILTER wilc_wlan_txq_filter_dup_tcp_ack(dev); #endif - /** - * build the vmm list - **/ PRINT_D(TX_DBG, "Getting the head of the TxQ\n"); tqe = wilc_wlan_txq_get_first(wilc); i = 0; sum = 0; do { - if ((tqe != NULL) && (i < (WILC_VMM_TBL_SIZE - 1)) /* reserve last entry to 0 */) { + if ((tqe != NULL) && (i < (WILC_VMM_TBL_SIZE - 1))) { if (tqe->type == WILC_CFG_PKT) vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET; @@ -886,14 +769,14 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) vmm_sz += tqe->buffer_size; PRINT_D(TX_DBG, "VMM Size before alignment = %d\n", vmm_sz); - if (vmm_sz & 0x3) { /* has to be word aligned */ + if (vmm_sz & 0x3) vmm_sz = (vmm_sz + 4) & ~0x3; - } + if ((sum + vmm_sz) > LINUX_TX_SIZE) break; PRINT_D(TX_DBG, "VMM Size AFTER alignment = %d\n", vmm_sz); - vmm_table[i] = vmm_sz / 4; /* table take the word size */ + vmm_table[i] = vmm_sz / 4; PRINT_D(TX_DBG, "VMMTable entry size = %d\n", vmm_table[i]); if (tqe->type == WILC_CFG_PKT) { @@ -913,12 +796,12 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) } } while (1); - if (i == 0) { /* nothing in the queue */ + if (i == 0) { PRINT_D(TX_DBG, "Nothing in TX-Q\n"); break; } else { PRINT_D(TX_DBG, "Mark the last entry in VMM table - number of previous entries = %d\n", i); - vmm_table[i] = 0x0; /* mark the last element to 0 */ + vmm_table[i] = 0x0; } acquire_bus(ACQUIRE_AND_WAKEUP); counter = 0; @@ -931,9 +814,6 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) } if ((reg & 0x1) == 0) { - /** - * write to vmm table - **/ PRINT_D(TX_DBG, "Writing VMM table ... with Size = %d\n", ((i + 1) * 4)); break; } else { @@ -944,9 +824,6 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) ret = p->hif_func.hif_write_reg(WILC_HOST_TX_CTRL, 0); break; } - /** - * wait for vmm table is ready - **/ PRINT_WRN(GENERIC_DBG, "[wilc txq]: warn, vmm table not clear yet, wait...\n"); release_bus(RELEASE_ALLOW_SLEEP); usleep_range(3000, 3000); @@ -959,30 +836,18 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) timeout = 200; do { - - /** - * write to vmm table - **/ ret = p->hif_func.hif_block_tx(WILC_VMM_TBL_RX_SHADOW_BASE, (u8 *)vmm_table, ((i + 1) * 4)); if (!ret) { wilc_debug(N_ERR, "ERR block TX of VMM table.\n"); break; } - - /** - * interrupt firmware - **/ ret = p->hif_func.hif_write_reg(WILC_HOST_VMM_CTL, 0x2); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't write reg host_vmm_ctl..\n"); break; } - /** - * wait for confirm... - **/ - do { ret = p->hif_func.hif_read_reg(WILC_HOST_VMM_CTL, ®); if (!ret) { @@ -990,9 +855,6 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) break; } if ((reg >> 2) & 0x1) { - /** - * Get the entries - **/ entries = ((reg >> 3) & 0x3f); break; } else { @@ -1013,7 +875,6 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) if (entries == 0) { PRINT_WRN(GENERIC_DBG, "[wilc txq]: no more buffer in the chip (reg: %08x), retry later [[ %d, %x ]]\n", reg, i, vmm_table[i - 1]); - /* undo the transaction. */ ret = p->hif_func.hif_read_reg(WILC_HOST_TX_CTRL, ®); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't read reg WILC_HOST_TX_CTRL..\n"); @@ -1039,13 +900,8 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) goto _end_; } - /* since copying data into txb takes some time, then - * allow the bus lock to be released let the RX task go. */ release_bus(RELEASE_ALLOW_SLEEP); - /** - * Copy data to the TX buffer - **/ offset = 0; i = 0; do { @@ -1056,7 +912,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) #ifdef BIG_ENDIAN vmm_table[i] = BYTE_SWAP(vmm_table[i]); #endif - vmm_sz = (vmm_table[i] & 0x3ff); /* in word unit */ + vmm_sz = (vmm_table[i] & 0x3ff); vmm_sz *= 4; header = (tqe->type << 31) | (tqe->buffer_size << 15) | vmm_sz; if (tqe->type == WILC_MGMT_PKT) @@ -1075,7 +931,6 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) char *pBSSID = ((struct tx_complete_data *)(tqe->priv))->pBssid; buffer_offset = ETH_ETHERNET_HDR_OFFSET; - /* copy the bssid at the sart of the buffer */ memcpy(&txb[offset + 4], pBSSID, 6); } else { @@ -1085,7 +940,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) memcpy(&txb[offset + buffer_offset], tqe->buffer, tqe->buffer_size); offset += vmm_sz; i++; - tqe->status = 1; /* mark the packet send */ + tqe->status = 1; if (tqe->tx_complete_func) tqe->tx_complete_func(tqe->priv, tqe->status); #ifdef TCP_ACK_FILTER @@ -1098,9 +953,6 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) } } while (--entries); - /** - * lock the bus - **/ acquire_bus(ACQUIRE_AND_WAKEUP); ret = p->hif_func.hif_clear_int_ext(ENABLE_TX_VMM); @@ -1109,9 +961,6 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) goto _end_; } - /** - * transfer - **/ ret = p->hif_func.hif_block_tx_ext(0, txb, offset); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't block tx ext...\n"); @@ -1128,7 +977,6 @@ _end_: p->txq_exit = 1; PRINT_D(TX_DBG, "THREAD: Exiting txq\n"); - /* return tx[]q count */ *pu32TxqCount = p->txq_entries; return ret; } @@ -1193,7 +1041,6 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) if (pkt_offset & IS_MANAGMEMENT) { - /* reset mgmt indicator bit, to use pkt_offeset in furthur calculations */ pkt_offset &= ~(IS_MANAGMEMENT | IS_MANAGMEMENT_CALLBACK | IS_MGMT_STATUS_SUCCES); WILC_WFI_mgmt_rx(wilc, &buffer[offset + HOST_HDR_OFFSET], pkt_len); @@ -1216,16 +1063,10 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) wilc_wlan_cfg_indicate_rx(&buffer[pkt_offset + offset], pkt_len, &rsp); if (rsp.type == WILC_CFG_RSP) { - /** - * wake up the waiting task... - **/ PRINT_D(RX_DBG, "p->cfg_seq_no = %d - rsp.seq_no = %d\n", p->cfg_seq_no, rsp.seq_no); if (p->cfg_seq_no == rsp.seq_no) up(&wilc->cfg_event); } else if (rsp.type == WILC_CFG_RSP_STATUS) { - /** - * Call back to indicate status... - **/ linux_wlan_mac_indicate(wilc, WILC_MAC_INDICATE_STATUS); } else if (rsp.type == WILC_CFG_RSP_SCAN) { @@ -1253,11 +1094,6 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) PRINT_D(RX_DBG, "THREAD: Exiting RX thread\n"); } -/******************************************** - * - * Fast DMA Isr - * - ********************************************/ static void wilc_unknown_isr_ext(void) { g_wlan.hif_func.hif_clear_int_ext(0); @@ -1269,10 +1105,8 @@ static void wilc_pllupdate_isr_ext(u32 int_stats) g_wlan.hif_func.hif_clear_int_ext(PLL_INT_CLR); - /* Waiting for PLL */ mdelay(WILC_PLL_TO); - /* poll till read a valid data */ while (!(ISWILC1000(wilc_get_chipid(true)) && --trials)) { PRINT_D(TX_DBG, "PLL update retrying\n"); mdelay(1); @@ -1299,17 +1133,11 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) int ret = 0; struct rxq_entry_t *rqe; - - /** - * Get the rx size - **/ - size = ((int_status & 0x7fff) << 2); while (!size && retries < 10) { u32 time = 0; - /*looping more secure*/ - /*zero size make a crashe because the dma will not happen and that will block the firmware*/ + wilc_debug(N_ERR, "RX Size equal zero ... Trying to read it again for %d time\n", time++); p->hif_func.hif_read_size(&size); size = ((size & 0x7fff) << 2); @@ -1337,16 +1165,7 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) goto _end_; } #endif - - /** - * clear the chip's interrupt after getting size some register getting corrupted after clear the interrupt - **/ p->hif_func.hif_clear_int_ext(DATA_INT_CLR | ENABLE_RX_VMM); - - - /** - * start transfer - **/ ret = p->hif_func.hif_block_rx_ext(0, buffer, size); if (!ret) { @@ -1361,9 +1180,6 @@ _end_: offset += size; p->rx_buffer_offset = offset; #endif - /** - * add to rx queue - **/ rqe = kmalloc(sizeof(struct rxq_entry_t), GFP_KERNEL); if (rqe != NULL) { rqe->buffer = buffer; @@ -1393,7 +1209,6 @@ void wilc_handle_isr(void *wilc) if (int_status & DATA_INT_EXT) { wilc_wlan_handle_isr_ext(wilc, int_status); #ifndef WILC_OPTIMIZE_SLEEP_INT - /* Chip is up and talking*/ genuChipPSstate = CHIP_WAKEDUP; #endif } @@ -1409,11 +1224,6 @@ void wilc_handle_isr(void *wilc) release_bus(RELEASE_ALLOW_SLEEP); } -/******************************************** - * - * Firmware download - * - ********************************************/ int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size) { wilc_wlan_dev_t *p = &g_wlan; @@ -1423,20 +1233,16 @@ int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size) int ret = 0; blksz = BIT(12); - /* Allocate a DMA coherent buffer. */ dma_buffer = kmalloc(blksz, GFP_KERNEL); if (dma_buffer == NULL) { - /*EIO 5*/ ret = -5; PRINT_ER("Can't allocate buffer for firmware download IO error\n "); goto _fail_1; } PRINT_D(INIT_DBG, "Downloading firmware size = %d ...\n", buffer_size); - /** - * load the firmware - **/ + offset = 0; do { memcpy(&addr, &buffer[offset], 4); @@ -1452,7 +1258,7 @@ int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size) size2 = size; else size2 = blksz; - /* Copy firmware into a DMA coherent buffer */ + memcpy(dma_buffer, &buffer[offset], size2); ret = p->hif_func.hif_block_tx(addr, dma_buffer, size2); if (!ret) @@ -1465,7 +1271,6 @@ int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size) release_bus(RELEASE_ONLY); if (!ret) { - /*EIO 5*/ ret = -5; PRINT_ER("Can't download firmware IO error\n "); goto _fail_; @@ -1482,11 +1287,6 @@ _fail_1: return (ret < 0) ? ret : 0; } -/******************************************** - * - * Common - * - ********************************************/ int wilc_wlan_start(void) { wilc_wlan_dev_t *p = &g_wlan; @@ -1494,12 +1294,9 @@ int wilc_wlan_start(void) int ret; u32 chipid; - /** - * Set the host interface - **/ if (p->io_func.io_type == HIF_SDIO) { reg = 0; - reg |= BIT(3); /* bug 4456 and 4557 */ + reg |= BIT(3); } else if (p->io_func.io_type == HIF_SPI) { reg = 1; } @@ -1508,7 +1305,6 @@ int wilc_wlan_start(void) if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail write reg vmm_core_cfg...\n"); release_bus(RELEASE_ONLY); - /* EIO 5*/ ret = -5; return ret; } @@ -1533,14 +1329,9 @@ int wilc_wlan_start(void) #endif reg |= WILC_HAVE_LEGACY_RF_SETTINGS; - - -/*Set oscillator frequency*/ #ifdef XTAL_24 reg |= WILC_HAVE_XTAL_24; #endif - -/*Enable/Disable GPIO configuration for FW logs*/ #ifdef DISABLE_WILC_UART reg |= WILC_HAVE_DISABLE_WILC_UART; #endif @@ -1549,30 +1340,20 @@ int wilc_wlan_start(void) if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail write WILC_GP_REG_1 ...\n"); release_bus(RELEASE_ONLY); - /* EIO 5*/ ret = -5; return ret; } - /** - * Bus related - **/ p->hif_func.hif_sync_ext(NUM_INT_EXT); ret = p->hif_func.hif_read_reg(0x1000, &chipid); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail read reg 0x1000 ...\n"); release_bus(RELEASE_ONLY); - /* EIO 5*/ ret = -5; return ret; } - /** - * Go... - **/ - - p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); if ((reg & BIT(10)) == BIT(10)) { reg &= ~BIT(10); @@ -1603,9 +1384,6 @@ int wilc_wlan_stop(void) u32 reg = 0; int ret; u8 timeout = 10; - /** - * TODO: stop the firmware, need a re-download - **/ acquire_bus(ACQUIRE_AND_WAKEUP); ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); @@ -1635,7 +1413,7 @@ int wilc_wlan_stop(void) return ret; } PRINT_D(GENERIC_DBG, "Read RESET Reg %x : Retry%d\n", reg, timeout); - /*Workaround to ensure that the chip is actually reset*/ + if ((reg & BIT(10))) { PRINT_D(GENERIC_DBG, "Bit 10 not reset : Retry %d\n", timeout); reg &= ~BIT(10); @@ -1700,10 +1478,6 @@ void wilc_wlan_cleanup(struct net_device *dev) kfree(rqe); } while (1); - /** - * clean up buffer - **/ - #ifdef MEMORY_STATIC kfree(p->rx_buffer); p->rx_buffer = NULL; @@ -1725,9 +1499,6 @@ void wilc_wlan_cleanup(struct net_device *dev) release_bus(RELEASE_ALLOW_SLEEP); } release_bus(RELEASE_ALLOW_SLEEP); - /** - * io clean up - **/ p->hif_func.hif_deinit(NULL); } @@ -1740,16 +1511,12 @@ static int wilc_wlan_cfg_commit(int type, u32 drvHandler) int seq_no = p->cfg_seq_no % 256; int driver_handler = (u32)drvHandler; - - /** - * Set up header - **/ - if (type == WILC_CFG_SET) { /* Set */ + if (type == WILC_CFG_SET) { cfg->wid_header[0] = 'W'; - } else { /* Query */ + } else { cfg->wid_header[0] = 'Q'; } - cfg->wid_header[1] = seq_no; /* sequence number */ + cfg->wid_header[1] = seq_no; cfg->wid_header[2] = (u8)total_len; cfg->wid_header[3] = (u8)(total_len >> 8); cfg->wid_header[4] = (u8)driver_handler; @@ -1758,10 +1525,6 @@ static int wilc_wlan_cfg_commit(int type, u32 drvHandler) cfg->wid_header[7] = (u8)(driver_handler >> 24); p->cfg_seq_no = seq_no; - /** - * Add to TX queue - **/ - if (!wilc_wlan_txq_add_cfg_pkt(&cfg->wid_header[0], total_len)) return -1; @@ -1859,15 +1622,11 @@ int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size) void wilc_bus_set_max_speed(void) { - - /* Increase bus speed to max possible. */ g_wlan.hif_func.hif_set_max_bus_speed(); } void wilc_bus_set_default_speed(void) { - - /* Restore bus speed to default. */ g_wlan.hif_func.hif_set_default_bus_speed(); } u32 init_chip(struct net_device *dev) @@ -1882,11 +1641,6 @@ u32 init_chip(struct net_device *dev) if ((chipid & 0xfff) != 0xa0) { - /** - * Avoid booting from boot ROM. Make sure that Drive IRQN [SDIO platform] - * or SD_DAT3 [SPI platform] to ?1? - **/ - /* Set cortus reset register to register control. */ ret = g_wlan.hif_func.hif_read_reg(0x1118, ®); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail read reg 0x1118 ...\n"); @@ -1898,10 +1652,6 @@ u32 init_chip(struct net_device *dev) wilc_debug(N_ERR, "[wilc start]: fail write reg 0x1118 ...\n"); return ret; } - /** - * Write branch intruction to IRAM (0x71 trap) at location 0xFFFF0000 - * (Cortus map) or C0000 (AHB map). - **/ ret = g_wlan.hif_func.hif_write_reg(0xc0000, 0x71); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail write reg 0xc0000 ...\n"); @@ -1918,8 +1668,6 @@ u32 init_chip(struct net_device *dev) u32 wilc_get_chipid(u8 update) { static u32 chipid; - /* SDIO can't read into global variables */ - /* Use this variable as a temp, then copy to the global */ u32 tempchipid = 0; u32 rfrevid; @@ -1931,15 +1679,15 @@ u32 wilc_get_chipid(u8 update) goto _fail_; } if (tempchipid == 0x1002a0) { - if (rfrevid == 0x1) { /* 1002A0 */ - } else { /* if (rfrevid == 0x2) */ /* 1002A1 */ + if (rfrevid == 0x1) { + } else { tempchipid = 0x1002a1; } } else if (tempchipid == 0x1002b0) { - if (rfrevid == 3) { /* 1002B0 */ - } else if (rfrevid == 4) { /* 1002B1 */ + if (rfrevid == 3) { + } else if (rfrevid == 4) { tempchipid = 0x1002b1; - } else { /* if(rfrevid == 5) */ /* 1002B2 */ + } else { tempchipid = 0x1002b2; } } else { @@ -1959,69 +1707,47 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) PRINT_D(INIT_DBG, "Initializing WILC_Wlan ...\n"); memset((void *)&g_wlan, 0, sizeof(wilc_wlan_dev_t)); - - /** - * store the input - **/ memcpy((void *)&g_wlan.io_func, (void *)&inp->io_func, sizeof(wilc_wlan_io_func_t)); - /*** - * host interface init - **/ + if ((inp->io_func.io_type & 0x1) == HIF_SDIO) { if (!hif_sdio.hif_init(inp, wilc_debug)) { - /* EIO 5 */ ret = -5; goto _fail_; } memcpy((void *)&g_wlan.hif_func, &hif_sdio, sizeof(wilc_hif_func_t)); } else { if ((inp->io_func.io_type & 0x1) == HIF_SPI) { - /** - * TODO: - **/ if (!hif_spi.hif_init(inp, wilc_debug)) { - /* EIO 5 */ ret = -5; goto _fail_; } memcpy((void *)&g_wlan.hif_func, &hif_spi, sizeof(wilc_hif_func_t)); } else { - /* EIO 5 */ ret = -5; goto _fail_; } } - /*** - * mac interface init - **/ if (!wilc_wlan_cfg_init(wilc_debug)) { - /* ENOBUFS 105 */ ret = -105; goto _fail_; } - /** - * alloc tx, rx buffer - **/ if (g_wlan.tx_buffer == NULL) g_wlan.tx_buffer = kmalloc(LINUX_TX_SIZE, GFP_KERNEL); PRINT_D(TX_DBG, "g_wlan.tx_buffer = %p\n", g_wlan.tx_buffer); if (g_wlan.tx_buffer == NULL) { - /* ENOBUFS 105 */ ret = -105; PRINT_ER("Can't allocate Tx Buffer"); goto _fail_; } -/* rx_buffer is not used unless we activate USE_MEM STATIC which is not applicable, allocating such memory is useless*/ #if defined (MEMORY_STATIC) if (g_wlan.rx_buffer == NULL) g_wlan.rx_buffer = kmalloc(LINUX_RX_SIZE, GFP_KERNEL); PRINT_D(TX_DBG, "g_wlan.rx_buffer =%p\n", g_wlan.rx_buffer); if (g_wlan.rx_buffer == NULL) { - /* ENOBUFS 105 */ ret = -105; PRINT_ER("Can't allocate Rx Buffer"); goto _fail_; @@ -2029,7 +1755,6 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) #endif if (!init_chip(dev)) { - /* EIO 5 */ ret = -5; goto _fail_; } @@ -2062,7 +1787,6 @@ u16 set_machw_change_vir_if(struct net_device *dev, bool bValue) nic = netdev_priv(dev); wilc = nic->wilc; - /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/ mutex_lock(&wilc->hif_cs); ret = (&g_wlan)->hif_func.hif_read_reg(WILC_CHANGING_VIR_IF, ®); if (!ret) -- GitLab From 85489fe17a341b9ab6ef18374b25f5a267bbf04e Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:26 +0900 Subject: [PATCH 0266/2855] staging: wilc1000: fixes please don't use multiple blank lines This patch fixes the checks reported by checkpatch.pl for Please don't use multiple blank lines. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 48 ---------------------------- 1 file changed, 48 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 7aaad0f3928a0..5db87c083b7ce 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -6,8 +6,6 @@ extern wilc_hif_func_t hif_sdio; extern wilc_hif_func_t hif_spi; u32 wilc_get_chipid(u8 update); - - typedef struct { int quit; wilc_wlan_io_func_t io_func; @@ -35,8 +33,6 @@ typedef struct { struct rxq_entry_t *rxq_tail; int rxq_entries; int rxq_exit; - - } wilc_wlan_dev_t; static wilc_wlan_dev_t g_wlan; @@ -92,8 +88,6 @@ static void wilc_wlan_txq_remove(struct txq_entry_t *tqe) p->txq_head = tqe->next; if (p->txq_head) p->txq_head->prev = NULL; - - } else if (tqe == p->txq_tail) { p->txq_tail = (tqe->prev); if (p->txq_tail) @@ -126,10 +120,6 @@ wilc_wlan_txq_remove_from_head(struct net_device *dev) p->txq_head->prev = NULL; p->txq_entries -= 1; - - - - } else { tqe = NULL; } @@ -222,9 +212,6 @@ typedef struct { struct txq_entry_t *txqe; } Pending_Acks_info_t; - - - struct Ack_session_info *Free_head; struct Ack_session_info *Alloc_head; @@ -239,8 +226,6 @@ u32 PendingAcks_arrBase; u32 Opened_TCP_session; u32 Pending_Acks; - - static inline int Init_TCP_tracking(void) { @@ -319,7 +304,6 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) ip_hdr_ptr = &buffer[ETHERNET_HDR_LEN]; protocol = ip_hdr_ptr[9]; - if (protocol == 0x06) { u8 *tcp_hdr_ptr; u32 IHL, Total_Length, Data_offset; @@ -335,7 +319,6 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) Ack_no = (((u32)tcp_hdr_ptr[8]) << 24) + (((u32)tcp_hdr_ptr[9]) << 16) + (((u32)tcp_hdr_ptr[10]) << 8) + ((u32)tcp_hdr_ptr[11]); - for (i = 0; i < Opened_TCP_session; i++) { if (Acks_keep_track_info[i].Ack_seq_num == seq_no) { Update_TCP_track_session(i, Ack_no); @@ -346,8 +329,6 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) add_TCP_track_session(0, 0, seq_no); add_TCP_Pending_Ack(Ack_no, i, tqe); - - } } else { @@ -360,7 +341,6 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) return ret; } - static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) { perInterface_wlan_t *nic; @@ -398,7 +378,6 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) else PendingAcks_arrBase = 0; - spin_unlock_irqrestore(&wilc->txq_spinlock, p->txq_spinlock_flags); while (Dropped > 0) { @@ -523,7 +502,6 @@ static struct txq_entry_t *wilc_wlan_txq_get_first(struct wilc *wilc) spin_unlock_irqrestore(&wilc->txq_spinlock, flags); - return tqe; } @@ -536,7 +514,6 @@ static struct txq_entry_t *wilc_wlan_txq_get_next(struct wilc *wilc, tqe = tqe->next; spin_unlock_irqrestore(&wilc->txq_spinlock, flags); - return tqe; } @@ -637,7 +614,6 @@ static inline void chip_wakeup(void) } while ((clk_status_reg & 0x1) == 0); } - if (genuChipPSstate == CHIP_SLEEPING_MANUAL) { g_wlan.hif_func.hif_read_reg(0x1C0C, ®); reg &= ~BIT(0); @@ -990,9 +966,6 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) p->rxq_exit = 0; - - - do { if (p->quit) { PRINT_D(RX_DBG, "exit 1st do-while due to Clean_UP function\n"); @@ -1009,8 +982,6 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) PRINT_D(RX_DBG, "rxQ entery Size = %d - Address = %p\n", size, buffer); offset = 0; - - do { u32 header; u32 pkt_len, pkt_offset, tp_len; @@ -1023,8 +994,6 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) #endif PRINT_D(RX_DBG, "Header = %04x - Offset = %d\n", header, offset); - - is_cfg_packet = (header >> 31) & 0x1; pkt_offset = (header >> 22) & 0x1ff; tp_len = (header >> 11) & 0x7ff; @@ -1039,7 +1008,6 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) #define IS_MANAGMEMENT_CALLBACK 0x080 #define IS_MGMT_STATUS_SUCCES 0x040 - if (pkt_offset & IS_MANAGMEMENT) { pkt_offset &= ~(IS_MANAGMEMENT | IS_MANAGMEMENT_CALLBACK | IS_MGMT_STATUS_SUCCES); @@ -1059,8 +1027,6 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) } else { wilc_cfg_rsp_t rsp; - - wilc_wlan_cfg_indicate_rx(&buffer[pkt_offset + offset], pkt_len, &rsp); if (rsp.type == WILC_CFG_RSP) { PRINT_D(RX_DBG, "p->cfg_seq_no = %d - rsp.seq_no = %d\n", p->cfg_seq_no, rsp.seq_no); @@ -1078,8 +1044,6 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) if (offset >= size) break; } while (1); - - #ifndef MEMORY_STATIC kfree(buffer); #endif @@ -1173,8 +1137,6 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) goto _end_; } _end_: - - if (ret) { #ifdef MEMORY_STATIC offset += size; @@ -1394,8 +1356,6 @@ int wilc_wlan_stop(void) } reg &= ~BIT(10); - - ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg); if (!ret) { PRINT_ER("Error while writing reg\n"); @@ -1403,8 +1363,6 @@ int wilc_wlan_stop(void) return ret; } - - do { ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); if (!ret) { @@ -1486,7 +1444,6 @@ void wilc_wlan_cleanup(struct net_device *dev) acquire_bus(ACQUIRE_AND_WAKEUP); - ret = p->hif_func.hif_read_reg(WILC_GP_REG_0, ®); if (!ret) { PRINT_ER("Error while reading reg\n"); @@ -1538,7 +1495,6 @@ int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, u32 offset; int ret_size; - if (p->cfg_frame_in_use) return 0; @@ -1578,7 +1534,6 @@ int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drvHandler) u32 offset; int ret_size; - if (p->cfg_frame_in_use) return 0; @@ -1596,7 +1551,6 @@ int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drvHandler) if (wilc_wlan_cfg_commit(WILC_CFG_QUERY, drvHandler)) ret_size = 0; - if (linux_wlan_lock_timeout(&g_linux_wlan->cfg_event, CFG_PKTS_TIMEOUT)) { PRINT_D(TX_DBG, "Get Timed Out\n"); @@ -1638,8 +1592,6 @@ u32 init_chip(struct net_device *dev) chipid = wilc_get_chipid(true); - - if ((chipid & 0xfff) != 0xa0) { ret = g_wlan.hif_func.hif_read_reg(0x1118, ®); if (!ret) { -- GitLab From 0edeea292b29efd1a898dc040a4e66c94c846c1a Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:27 +0900 Subject: [PATCH 0267/2855] staging: wilc1000: fixes blank lines aren't necessary brace This patch fixes the checks reported by checkpatch.pl for Blank lines aren't necessary after an open brace '{' and Blank lines aren't necessary before a close brace '}'. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 5db87c083b7ce..603541c90728e 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -59,7 +59,6 @@ static CHIP_PS_STATE_T genuChipPSstate = CHIP_WAKEDUP; static inline void acquire_bus(BUS_ACQUIRE_T acquire) { - mutex_lock(&g_linux_wlan->hif_cs); #ifndef WILC_OPTIMIZE_SLEEP_INT if (genuChipPSstate != CHIP_WAKEDUP) @@ -68,7 +67,6 @@ static inline void acquire_bus(BUS_ACQUIRE_T acquire) if (acquire == ACQUIRE_AND_WAKEUP) chip_wakeup(); } - } static inline void release_bus(BUS_RELEASE_T release) { @@ -81,10 +79,8 @@ static inline void release_bus(BUS_RELEASE_T release) static void wilc_wlan_txq_remove(struct txq_entry_t *tqe) { - wilc_wlan_dev_t *p = &g_wlan; if (tqe == p->txq_head) { - p->txq_head = tqe->next; if (p->txq_head) p->txq_head->prev = NULL; @@ -97,7 +93,6 @@ static void wilc_wlan_txq_remove(struct txq_entry_t *tqe) tqe->next->prev = tqe->prev; } p->txq_entries -= 1; - } static struct txq_entry_t * @@ -191,7 +186,6 @@ static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe) PRINT_D(TX_DBG, "Wake up the txq_handler\n"); return 0; - } u32 Statisitcs_totalAcks = 0, Statisitcs_DroppedAcks = 0; @@ -228,9 +222,7 @@ u32 Pending_Acks; static inline int Init_TCP_tracking(void) { - return 0; - } static inline int add_TCP_track_session(u32 src_prt, u32 dst_prt, u32 seq) { @@ -246,11 +238,9 @@ static inline int add_TCP_track_session(u32 src_prt, u32 dst_prt, u32 seq) static inline int Update_TCP_track_session(u32 index, u32 Ack) { - if (Ack > Acks_keep_track_info[index].Bigger_Ack_num) Acks_keep_track_info[index].Bigger_Ack_num = Ack; return 0; - } static inline int add_TCP_Pending_Ack(u32 Ack, u32 Session_index, struct txq_entry_t *txqe) { @@ -261,7 +251,6 @@ static inline int add_TCP_Pending_Ack(u32 Ack, u32 Session_index, struct txq_ent Pending_Acks_info[PendingAcks_arrBase + Pending_Acks].Session_index = Session_index; txqe->tcp_PendingAck_index = PendingAcks_arrBase + Pending_Acks; Pending_Acks++; - } else { } @@ -466,7 +455,6 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func) { - wilc_wlan_dev_t *p = &g_wlan; struct txq_entry_t *tqe; @@ -605,7 +593,6 @@ static inline void chip_wakeup(void) if ((clk_status_reg & 0x1) == 0) wilc_debug(N_ERR, "clocks still OFF. Wake up failed\n"); - } if ((clk_status_reg & 0x1) == 0) { g_wlan.hif_func.hif_write_reg(0xf0, reg & @@ -694,7 +681,6 @@ void chip_sleep_manually(u32 u32SleepTime) genuChipPSstate = CHIP_SLEEPING_MANUAL; release_bus(RELEASE_ONLY); - } int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) @@ -733,7 +719,6 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) sum = 0; do { if ((tqe != NULL) && (i < (WILC_VMM_TBL_SIZE - 1))) { - if (tqe->type == WILC_CFG_PKT) vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET; @@ -782,7 +767,6 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) acquire_bus(ACQUIRE_AND_WAKEUP); counter = 0; do { - ret = p->hif_func.hif_read_reg(WILC_HOST_TX_CTRL, ®); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't read reg vmm_tbl_entry..\n"); @@ -1015,7 +999,6 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) } else { - if (!is_cfg_packet) { if (pkt_len > 0) { frmw_to_linux(wilc, @@ -1064,7 +1047,6 @@ static void wilc_unknown_isr_ext(void) } static void wilc_pllupdate_isr_ext(u32 int_stats) { - int trials = 10; g_wlan.hif_func.hif_clear_int_ext(PLL_INT_CLR); @@ -1106,7 +1088,6 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) p->hif_func.hif_read_size(&size); size = ((size & 0x7fff) << 2); retries++; - } if (size > 0) { @@ -1457,7 +1438,6 @@ void wilc_wlan_cleanup(struct net_device *dev) } release_bus(RELEASE_ALLOW_SLEEP); p->hif_func.hif_deinit(NULL); - } static int wilc_wlan_cfg_commit(int type, u32 drvHandler) @@ -1523,7 +1503,6 @@ int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, p->cfg_frame_in_use = 0; p->cfg_frame_offset = 0; p->cfg_seq_no += 1; - } return ret_size; @@ -1614,7 +1593,6 @@ u32 init_chip(struct net_device *dev) release_bus(RELEASE_ONLY); return ret; - } u32 wilc_get_chipid(u8 update) @@ -1653,7 +1631,6 @@ _fail_: int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) { - int ret = 0; PRINT_D(INIT_DBG, "Initializing WILC_Wlan ...\n"); @@ -1726,7 +1703,6 @@ _fail_: g_wlan.tx_buffer = NULL; return ret; - } u16 set_machw_change_vir_if(struct net_device *dev, bool bValue) -- GitLab From 2d6973e6cd17a66d6904288993466a64ba0b9855 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:28 +0900 Subject: [PATCH 0268/2855] staging: wilc1000: fixes add blank line after function declaration This patch fixes the warnings reported by checkpatch.pl for please use a blank line after function/struct/union/enum declarations Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 603541c90728e..d3117f95bba3d 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -68,6 +68,7 @@ static inline void acquire_bus(BUS_ACQUIRE_T acquire) chip_wakeup(); } } + static inline void release_bus(BUS_RELEASE_T release) { #ifdef WILC_OPTIMIZE_SLEEP_INT @@ -224,6 +225,7 @@ static inline int Init_TCP_tracking(void) { return 0; } + static inline int add_TCP_track_session(u32 src_prt, u32 dst_prt, u32 seq) { Acks_keep_track_info[Opened_TCP_session].Ack_seq_num = seq; @@ -242,6 +244,7 @@ static inline int Update_TCP_track_session(u32 index, u32 Ack) Acks_keep_track_info[index].Bigger_Ack_num = Ack; return 0; } + static inline int add_TCP_Pending_Ack(u32 Ack, u32 Session_index, struct txq_entry_t *txqe) { Statisitcs_totalAcks++; @@ -1045,6 +1048,7 @@ static void wilc_unknown_isr_ext(void) { g_wlan.hif_func.hif_clear_int_ext(0); } + static void wilc_pllupdate_isr_ext(u32 int_stats) { int trials = 10; @@ -1507,6 +1511,7 @@ int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, return ret_size; } + int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drvHandler) { wilc_wlan_dev_t *p = &g_wlan; @@ -1562,6 +1567,7 @@ void wilc_bus_set_default_speed(void) { g_wlan.hif_func.hif_set_default_bus_speed(); } + u32 init_chip(struct net_device *dev) { u32 chipid; -- GitLab From 8739eeba4b8b2549170baf01fd70f15db3acc781 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:29 +0900 Subject: [PATCH 0269/2855] staging: wilc1000: fixes missing a blank line after declarations This patch fixes the warnings reported by checkpatch.pl for Missing a blank line after declarations. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index d3117f95bba3d..7ebfcaf8daf13 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -81,6 +81,7 @@ static inline void release_bus(BUS_RELEASE_T release) static void wilc_wlan_txq_remove(struct txq_entry_t *tqe) { wilc_wlan_dev_t *p = &g_wlan; + if (tqe == p->txq_head) { p->txq_head = tqe->next; if (p->txq_head) @@ -500,6 +501,7 @@ static struct txq_entry_t *wilc_wlan_txq_get_next(struct wilc *wilc, struct txq_entry_t *tqe) { unsigned long flags; + spin_lock_irqsave(&wilc->txq_spinlock, flags); tqe = tqe->next; -- GitLab From b7d1e18c278fe01f77a428b88bf750fc9ee6742e Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:30 +0900 Subject: [PATCH 0270/2855] staging: wilc1000: rename genuChipPSstate variable This patch rename genuChipPSstate variable to chip_ps_state to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 7ebfcaf8daf13..c393e529ce662 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -55,13 +55,13 @@ static void wilc_debug(u32 flag, char *fmt, ...) } } -static CHIP_PS_STATE_T genuChipPSstate = CHIP_WAKEDUP; +static CHIP_PS_STATE_T chip_ps_state = CHIP_WAKEDUP; static inline void acquire_bus(BUS_ACQUIRE_T acquire) { mutex_lock(&g_linux_wlan->hif_cs); #ifndef WILC_OPTIMIZE_SLEEP_INT - if (genuChipPSstate != CHIP_WAKEDUP) + if (chip_ps_state != CHIP_WAKEDUP) #endif { if (acquire == ACQUIRE_AND_WAKEUP) @@ -606,7 +606,7 @@ static inline void chip_wakeup(void) } while ((clk_status_reg & 0x1) == 0); } - if (genuChipPSstate == CHIP_SLEEPING_MANUAL) { + if (chip_ps_state == CHIP_SLEEPING_MANUAL) { g_wlan.hif_func.hif_read_reg(0x1C0C, ®); reg &= ~BIT(0); g_wlan.hif_func.hif_write_reg(0x1C0C, reg); @@ -623,7 +623,7 @@ static inline void chip_wakeup(void) g_wlan.hif_func.hif_write_reg(0x1e9c, val32); } } - genuChipPSstate = CHIP_WAKEDUP; + chip_ps_state = CHIP_WAKEDUP; } #else static inline void chip_wakeup(void) @@ -653,7 +653,7 @@ static inline void chip_wakeup(void) } while (wilc_get_chipid(true) == 0); - if (genuChipPSstate == CHIP_SLEEPING_MANUAL) { + if (chip_ps_state == CHIP_SLEEPING_MANUAL) { g_wlan.hif_func.hif_read_reg(0x1C0C, ®); reg &= ~BIT(0); g_wlan.hif_func.hif_write_reg(0x1C0C, reg); @@ -670,12 +670,12 @@ static inline void chip_wakeup(void) g_wlan.hif_func.hif_write_reg(0x1e9c, val32); } } - genuChipPSstate = CHIP_WAKEDUP; + chip_ps_state = CHIP_WAKEDUP; } #endif void chip_sleep_manually(u32 u32SleepTime) { - if (genuChipPSstate != CHIP_WAKEDUP) + if (chip_ps_state != CHIP_WAKEDUP) return; acquire_bus(ACQUIRE_ONLY); @@ -684,7 +684,7 @@ void chip_sleep_manually(u32 u32SleepTime) #endif g_wlan.hif_func.hif_write_reg(0x10a8, 1); - genuChipPSstate = CHIP_SLEEPING_MANUAL; + chip_ps_state = CHIP_SLEEPING_MANUAL; release_bus(RELEASE_ONLY); } @@ -1069,7 +1069,7 @@ static void wilc_sleeptimer_isr_ext(u32 int_stats1) { g_wlan.hif_func.hif_clear_int_ext(SLEEP_INT_CLR); #ifndef WILC_OPTIMIZE_SLEEP_INT - genuChipPSstate = CHIP_SLEEPING_AUTO; + chip_ps_state = CHIP_SLEEPING_AUTO; #endif } @@ -1158,7 +1158,7 @@ void wilc_handle_isr(void *wilc) if (int_status & DATA_INT_EXT) { wilc_wlan_handle_isr_ext(wilc, int_status); #ifndef WILC_OPTIMIZE_SLEEP_INT - genuChipPSstate = CHIP_WAKEDUP; + chip_ps_state = CHIP_WAKEDUP; #endif } if (int_status & SLEEP_INT_EXT) -- GitLab From a4b1719728652406913f13c99d725dd35515b372 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:31 +0900 Subject: [PATCH 0271/2855] staging: wilc1000: replace explicit NULL comparisons with ! This patch replace explicit NULL comparison with ! operator to simplify code. Reported by checkpatch.pl for Comparison to NULL could be written "!XXX" or "XXX". Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 36 ++++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index c393e529ce662..8ac0b1eb71aaa 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -137,7 +137,7 @@ static void wilc_wlan_txq_add_to_tail(struct net_device *dev, spin_lock_irqsave(&wilc->txq_spinlock, flags); - if (p->txq_head == NULL) { + if (!p->txq_head) { tqe->next = NULL; tqe->prev = NULL; p->txq_head = tqe; @@ -168,7 +168,7 @@ static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe) spin_lock_irqsave(&g_linux_wlan->txq_spinlock, flags); - if (p->txq_head == NULL) { + if (!p->txq_head) { tqe->next = NULL; tqe->prev = NULL; p->txq_head = tqe; @@ -407,7 +407,7 @@ static int wilc_wlan_txq_add_cfg_pkt(u8 *buffer, u32 buffer_size) } tqe = kmalloc(sizeof(struct txq_entry_t), GFP_ATOMIC); - if (tqe == NULL) { + if (!tqe) { PRINT_ER("Failed to allocate memory\n"); return 0; } @@ -438,7 +438,7 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, tqe = kmalloc(sizeof(struct txq_entry_t), GFP_ATOMIC); - if (tqe == NULL) + if (!tqe) return 0; tqe->type = WILC_NET_PKT; tqe->buffer = buffer; @@ -467,7 +467,7 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, tqe = kmalloc(sizeof(struct txq_entry_t), GFP_KERNEL); - if (tqe == NULL) + if (!tqe) return 0; tqe->type = WILC_MGMT_PKT; tqe->buffer = buffer; @@ -518,7 +518,7 @@ static int wilc_wlan_rxq_add(struct wilc *wilc, struct rxq_entry_t *rqe) return 0; mutex_lock(&wilc->rxq_cs); - if (p->rxq_head == NULL) { + if (!p->rxq_head) { PRINT_D(RX_DBG, "Add to Queue head\n"); rqe->next = NULL; p->rxq_head = rqe; @@ -723,7 +723,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) i = 0; sum = 0; do { - if ((tqe != NULL) && (i < (WILC_VMM_TBL_SIZE - 1))) { + if (tqe && (i < (WILC_VMM_TBL_SIZE - 1))) { if (tqe->type == WILC_CFG_PKT) vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET; @@ -871,7 +871,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) i = 0; do { tqe = wilc_wlan_txq_remove_from_head(dev); - if (tqe != NULL && (vmm_table[i] != 0)) { + if (tqe && (vmm_table[i] != 0)) { u32 header, buffer_offset; #ifdef BIG_ENDIAN @@ -962,7 +962,7 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) break; } rqe = wilc_wlan_rxq_remove(wilc); - if (rqe == NULL) { + if (!rqe) { PRINT_D(RX_DBG, "nothing in the queue - exit 1st do-while\n"); break; } @@ -1110,7 +1110,7 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) #else buffer = kmalloc(size, GFP_KERNEL); - if (buffer == NULL) { + if (!buffer) { wilc_debug(N_ERR, "[wilc isr]: fail alloc host memory...drop the packets (%d)\n", size); usleep_range(100 * 1000, 100 * 1000); goto _end_; @@ -1130,7 +1130,7 @@ _end_: p->rx_buffer_offset = offset; #endif rqe = kmalloc(sizeof(struct rxq_entry_t), GFP_KERNEL); - if (rqe != NULL) { + if (rqe) { rqe->buffer = buffer; rqe->buffer_size = size; PRINT_D(RX_DBG, "rxq entery Size= %d - Address = %p\n", rqe->buffer_size, rqe->buffer); @@ -1184,7 +1184,7 @@ int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size) blksz = BIT(12); dma_buffer = kmalloc(blksz, GFP_KERNEL); - if (dma_buffer == NULL) { + if (!dma_buffer) { ret = -5; PRINT_ER("Can't allocate buffer for firmware download IO error\n "); goto _fail_1; @@ -1406,7 +1406,7 @@ void wilc_wlan_cleanup(struct net_device *dev) p->quit = 1; do { tqe = wilc_wlan_txq_remove_from_head(dev); - if (tqe == NULL) + if (!tqe) break; if (tqe->tx_complete_func) tqe->tx_complete_func(tqe->priv, 0); @@ -1415,7 +1415,7 @@ void wilc_wlan_cleanup(struct net_device *dev) do { rqe = wilc_wlan_rxq_remove(wilc); - if (rqe == NULL) + if (!rqe) break; #ifndef MEMORY_STATIC kfree(rqe->buffer); @@ -1670,21 +1670,21 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) goto _fail_; } - if (g_wlan.tx_buffer == NULL) + if (!g_wlan.tx_buffer) g_wlan.tx_buffer = kmalloc(LINUX_TX_SIZE, GFP_KERNEL); PRINT_D(TX_DBG, "g_wlan.tx_buffer = %p\n", g_wlan.tx_buffer); - if (g_wlan.tx_buffer == NULL) { + if (!g_wlan.tx_buffer) { ret = -105; PRINT_ER("Can't allocate Tx Buffer"); goto _fail_; } #if defined (MEMORY_STATIC) - if (g_wlan.rx_buffer == NULL) + if (!g_wlan.rx_buffer) g_wlan.rx_buffer = kmalloc(LINUX_RX_SIZE, GFP_KERNEL); PRINT_D(TX_DBG, "g_wlan.rx_buffer =%p\n", g_wlan.rx_buffer); - if (g_wlan.rx_buffer == NULL) { + if (!g_wlan.rx_buffer) { ret = -105; PRINT_ER("Can't allocate Rx Buffer"); goto _fail_; -- GitLab From 821466d2fe8f6932c32ad86b8b36235aed644733 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:32 +0900 Subject: [PATCH 0272/2855] staging: wilc1000: rename Statisitcs_totalAcks variable This patch rename Statisitcs_totalAcks variable to total_acks to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 8ac0b1eb71aaa..8d6215b3b8f58 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -190,7 +190,7 @@ static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe) return 0; } -u32 Statisitcs_totalAcks = 0, Statisitcs_DroppedAcks = 0; +u32 total_acks = 0, Statisitcs_DroppedAcks = 0; #ifdef TCP_ACK_FILTER struct Ack_session_info; @@ -248,7 +248,7 @@ static inline int Update_TCP_track_session(u32 index, u32 Ack) static inline int add_TCP_Pending_Ack(u32 Ack, u32 Session_index, struct txq_entry_t *txqe) { - Statisitcs_totalAcks++; + total_acks++; if (Pending_Acks < MAX_PENDING_ACKS) { Pending_Acks_info[PendingAcks_arrBase + Pending_Acks].ack_num = Ack; Pending_Acks_info[PendingAcks_arrBase + Pending_Acks].txqe = txqe; -- GitLab From eb59da3be9054bf76cb159f7bcb90a8f74228dff Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:33 +0900 Subject: [PATCH 0273/2855] staging: wilc1000: rename Statisitcs_DroppedAcks variable This patch rename Statisitcs_DroppedAcks variable to dropped_acks to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 8d6215b3b8f58..9b1ca170c8dad 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -190,7 +190,7 @@ static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe) return 0; } -u32 total_acks = 0, Statisitcs_DroppedAcks = 0; +u32 total_acks = 0, dropped_acks = 0; #ifdef TCP_ACK_FILTER struct Ack_session_info; @@ -354,7 +354,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) tqe = Pending_Acks_info[i].txqe; if (tqe) { wilc_wlan_txq_remove(tqe); - Statisitcs_DroppedAcks++; + dropped_acks++; tqe->status = 1; if (tqe->tx_complete_func) tqe->tx_complete_func(tqe->priv, tqe->status); -- GitLab From 130a41f0c73bce3195dbf6e667cc1d8bfa6f7e54 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:34 +0900 Subject: [PATCH 0274/2855] staging: wilc1000: rename Ack_session_info struct variable This patch rename Ack_session_info struct variable to ack_session_info to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 9b1ca170c8dad..f3968fd3af42f 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -193,8 +193,8 @@ static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe) u32 total_acks = 0, dropped_acks = 0; #ifdef TCP_ACK_FILTER -struct Ack_session_info; -struct Ack_session_info { +struct ack_session_info; +struct ack_session_info { u32 Ack_seq_num; u32 Bigger_Ack_num; u16 src_port; @@ -208,14 +208,14 @@ typedef struct { struct txq_entry_t *txqe; } Pending_Acks_info_t; -struct Ack_session_info *Free_head; -struct Ack_session_info *Alloc_head; +struct ack_session_info *Free_head; +struct ack_session_info *Alloc_head; #define NOT_TCP_ACK (-1) #define MAX_TCP_SESSION 25 #define MAX_PENDING_ACKS 256 -struct Ack_session_info Acks_keep_track_info[2 * MAX_TCP_SESSION]; +struct ack_session_info Acks_keep_track_info[2 * MAX_TCP_SESSION]; Pending_Acks_info_t Pending_Acks_info[MAX_PENDING_ACKS]; u32 PendingAcks_arrBase; -- GitLab From d06b6cb2c06b641765ead77dca42513ce0c138a0 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:35 +0900 Subject: [PATCH 0275/2855] staging: wilc1000: rename Ack_seq_num of struct ack_session_info This patch rename Ack_seq_num of struct ack_session_info to seq_num to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index f3968fd3af42f..7162473b44429 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -195,7 +195,7 @@ u32 total_acks = 0, dropped_acks = 0; #ifdef TCP_ACK_FILTER struct ack_session_info; struct ack_session_info { - u32 Ack_seq_num; + u32 seq_num; u32 Bigger_Ack_num; u16 src_port; u16 dst_port; @@ -229,7 +229,7 @@ static inline int Init_TCP_tracking(void) static inline int add_TCP_track_session(u32 src_prt, u32 dst_prt, u32 seq) { - Acks_keep_track_info[Opened_TCP_session].Ack_seq_num = seq; + Acks_keep_track_info[Opened_TCP_session].seq_num = seq; Acks_keep_track_info[Opened_TCP_session].Bigger_Ack_num = 0; Acks_keep_track_info[Opened_TCP_session].src_port = src_prt; Acks_keep_track_info[Opened_TCP_session].dst_port = dst_prt; @@ -313,7 +313,7 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) Ack_no = (((u32)tcp_hdr_ptr[8]) << 24) + (((u32)tcp_hdr_ptr[9]) << 16) + (((u32)tcp_hdr_ptr[10]) << 8) + ((u32)tcp_hdr_ptr[11]); for (i = 0; i < Opened_TCP_session; i++) { - if (Acks_keep_track_info[i].Ack_seq_num == seq_no) { + if (Acks_keep_track_info[i].seq_num == seq_no) { Update_TCP_track_session(i, Ack_no); break; } -- GitLab From 9d54d3d5d51fa3d0633e70bf02d732ea86d60581 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:36 +0900 Subject: [PATCH 0276/2855] staging: wilc1000: rename Bigger_Ack_num of struct ack_session_info This patch rename Bigger_Ack_num of struct ack_session_info to bigger_ack_num to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 7162473b44429..4aec89222b087 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -196,7 +196,7 @@ u32 total_acks = 0, dropped_acks = 0; struct ack_session_info; struct ack_session_info { u32 seq_num; - u32 Bigger_Ack_num; + u32 bigger_ack_num; u16 src_port; u16 dst_port; u16 status; @@ -230,7 +230,7 @@ static inline int Init_TCP_tracking(void) static inline int add_TCP_track_session(u32 src_prt, u32 dst_prt, u32 seq) { Acks_keep_track_info[Opened_TCP_session].seq_num = seq; - Acks_keep_track_info[Opened_TCP_session].Bigger_Ack_num = 0; + Acks_keep_track_info[Opened_TCP_session].bigger_ack_num = 0; Acks_keep_track_info[Opened_TCP_session].src_port = src_prt; Acks_keep_track_info[Opened_TCP_session].dst_port = dst_prt; Opened_TCP_session++; @@ -241,8 +241,8 @@ static inline int add_TCP_track_session(u32 src_prt, u32 dst_prt, u32 seq) static inline int Update_TCP_track_session(u32 index, u32 Ack) { - if (Ack > Acks_keep_track_info[index].Bigger_Ack_num) - Acks_keep_track_info[index].Bigger_Ack_num = Ack; + if (Ack > Acks_keep_track_info[index].bigger_ack_num) + Acks_keep_track_info[index].bigger_ack_num = Ack; return 0; } @@ -347,7 +347,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) spin_lock_irqsave(&wilc->txq_spinlock, p->txq_spinlock_flags); for (i = PendingAcks_arrBase; i < (PendingAcks_arrBase + Pending_Acks); i++) { - if (Pending_Acks_info[i].ack_num < Acks_keep_track_info[Pending_Acks_info[i].Session_index].Bigger_Ack_num) { + if (Pending_Acks_info[i].ack_num < Acks_keep_track_info[Pending_Acks_info[i].Session_index].bigger_ack_num) { struct txq_entry_t *tqe; PRINT_D(TCP_ENH, "DROP ACK: %u\n", Pending_Acks_info[i].ack_num); -- GitLab From 08b90b106cc754206199e74b9512551bc426af15 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:37 +0900 Subject: [PATCH 0277/2855] staging: wilc1000: remove typedef of struct Pending_Acks_info_t This patch remove typedef of struct Pending_Acks_info_t. And, rename the Pending_Acks_info_t to pending_acks_info. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 4aec89222b087..fb0e63519b1f2 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -202,11 +202,11 @@ struct ack_session_info { u16 status; }; -typedef struct { +struct pending_acks_info { u32 ack_num; u32 Session_index; struct txq_entry_t *txqe; -} Pending_Acks_info_t; +}; struct ack_session_info *Free_head; struct ack_session_info *Alloc_head; @@ -216,7 +216,7 @@ struct ack_session_info *Alloc_head; #define MAX_TCP_SESSION 25 #define MAX_PENDING_ACKS 256 struct ack_session_info Acks_keep_track_info[2 * MAX_TCP_SESSION]; -Pending_Acks_info_t Pending_Acks_info[MAX_PENDING_ACKS]; +struct pending_acks_info Pending_Acks_info[MAX_PENDING_ACKS]; u32 PendingAcks_arrBase; u32 Opened_TCP_session; -- GitLab From 841369782d9a4b5105a80bc15baca8907fd35e53 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:38 +0900 Subject: [PATCH 0278/2855] staging: wilc1000: rename Session_index of struct pending_acks_info This patch rename Session_index of struct pending_acks_info to session_index to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index fb0e63519b1f2..af5a16ec227d1 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -204,7 +204,7 @@ struct ack_session_info { struct pending_acks_info { u32 ack_num; - u32 Session_index; + u32 session_index; struct txq_entry_t *txqe; }; @@ -252,7 +252,7 @@ static inline int add_TCP_Pending_Ack(u32 Ack, u32 Session_index, struct txq_ent if (Pending_Acks < MAX_PENDING_ACKS) { Pending_Acks_info[PendingAcks_arrBase + Pending_Acks].ack_num = Ack; Pending_Acks_info[PendingAcks_arrBase + Pending_Acks].txqe = txqe; - Pending_Acks_info[PendingAcks_arrBase + Pending_Acks].Session_index = Session_index; + Pending_Acks_info[PendingAcks_arrBase + Pending_Acks].session_index = Session_index; txqe->tcp_PendingAck_index = PendingAcks_arrBase + Pending_Acks; Pending_Acks++; } else { @@ -347,7 +347,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) spin_lock_irqsave(&wilc->txq_spinlock, p->txq_spinlock_flags); for (i = PendingAcks_arrBase; i < (PendingAcks_arrBase + Pending_Acks); i++) { - if (Pending_Acks_info[i].ack_num < Acks_keep_track_info[Pending_Acks_info[i].Session_index].bigger_ack_num) { + if (Pending_Acks_info[i].ack_num < Acks_keep_track_info[Pending_Acks_info[i].session_index].bigger_ack_num) { struct txq_entry_t *tqe; PRINT_D(TCP_ENH, "DROP ACK: %u\n", Pending_Acks_info[i].ack_num); -- GitLab From 32065054ceabfea7a65cb116e39221fac6e46d1e Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:39 +0900 Subject: [PATCH 0279/2855] staging: wilc1000: rename Acks_keep_track_info variable This patch rename the Acks_keep_track_info variable to ack_session_info to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index af5a16ec227d1..359df26c8625d 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -215,7 +215,7 @@ struct ack_session_info *Alloc_head; #define MAX_TCP_SESSION 25 #define MAX_PENDING_ACKS 256 -struct ack_session_info Acks_keep_track_info[2 * MAX_TCP_SESSION]; +struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION]; struct pending_acks_info Pending_Acks_info[MAX_PENDING_ACKS]; u32 PendingAcks_arrBase; @@ -229,10 +229,10 @@ static inline int Init_TCP_tracking(void) static inline int add_TCP_track_session(u32 src_prt, u32 dst_prt, u32 seq) { - Acks_keep_track_info[Opened_TCP_session].seq_num = seq; - Acks_keep_track_info[Opened_TCP_session].bigger_ack_num = 0; - Acks_keep_track_info[Opened_TCP_session].src_port = src_prt; - Acks_keep_track_info[Opened_TCP_session].dst_port = dst_prt; + ack_session_info[Opened_TCP_session].seq_num = seq; + ack_session_info[Opened_TCP_session].bigger_ack_num = 0; + ack_session_info[Opened_TCP_session].src_port = src_prt; + ack_session_info[Opened_TCP_session].dst_port = dst_prt; Opened_TCP_session++; PRINT_D(TCP_ENH, "TCP Session %d to Ack %d\n", Opened_TCP_session, seq); @@ -241,8 +241,8 @@ static inline int add_TCP_track_session(u32 src_prt, u32 dst_prt, u32 seq) static inline int Update_TCP_track_session(u32 index, u32 Ack) { - if (Ack > Acks_keep_track_info[index].bigger_ack_num) - Acks_keep_track_info[index].bigger_ack_num = Ack; + if (Ack > ack_session_info[index].bigger_ack_num) + ack_session_info[index].bigger_ack_num = Ack; return 0; } @@ -313,7 +313,7 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) Ack_no = (((u32)tcp_hdr_ptr[8]) << 24) + (((u32)tcp_hdr_ptr[9]) << 16) + (((u32)tcp_hdr_ptr[10]) << 8) + ((u32)tcp_hdr_ptr[11]); for (i = 0; i < Opened_TCP_session; i++) { - if (Acks_keep_track_info[i].seq_num == seq_no) { + if (ack_session_info[i].seq_num == seq_no) { Update_TCP_track_session(i, Ack_no); break; } @@ -347,7 +347,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) spin_lock_irqsave(&wilc->txq_spinlock, p->txq_spinlock_flags); for (i = PendingAcks_arrBase; i < (PendingAcks_arrBase + Pending_Acks); i++) { - if (Pending_Acks_info[i].ack_num < Acks_keep_track_info[Pending_Acks_info[i].session_index].bigger_ack_num) { + if (Pending_Acks_info[i].ack_num < ack_session_info[Pending_Acks_info[i].session_index].bigger_ack_num) { struct txq_entry_t *tqe; PRINT_D(TCP_ENH, "DROP ACK: %u\n", Pending_Acks_info[i].ack_num); -- GitLab From 2bb170876813491d74f09820424ee5d054f2b40b Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:40 +0900 Subject: [PATCH 0280/2855] staging: wilc1000: rename Pending_Acks_info variable This patch rename the Pending_Acks_info variable to pending_acks_info to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 359df26c8625d..7db42c0fd21f6 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -216,7 +216,7 @@ struct ack_session_info *Alloc_head; #define MAX_TCP_SESSION 25 #define MAX_PENDING_ACKS 256 struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION]; -struct pending_acks_info Pending_Acks_info[MAX_PENDING_ACKS]; +struct pending_acks_info pending_acks_info[MAX_PENDING_ACKS]; u32 PendingAcks_arrBase; u32 Opened_TCP_session; @@ -250,9 +250,9 @@ static inline int add_TCP_Pending_Ack(u32 Ack, u32 Session_index, struct txq_ent { total_acks++; if (Pending_Acks < MAX_PENDING_ACKS) { - Pending_Acks_info[PendingAcks_arrBase + Pending_Acks].ack_num = Ack; - Pending_Acks_info[PendingAcks_arrBase + Pending_Acks].txqe = txqe; - Pending_Acks_info[PendingAcks_arrBase + Pending_Acks].session_index = Session_index; + pending_acks_info[PendingAcks_arrBase + Pending_Acks].ack_num = Ack; + pending_acks_info[PendingAcks_arrBase + Pending_Acks].txqe = txqe; + pending_acks_info[PendingAcks_arrBase + Pending_Acks].session_index = Session_index; txqe->tcp_PendingAck_index = PendingAcks_arrBase + Pending_Acks; Pending_Acks++; } else { @@ -347,11 +347,12 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) spin_lock_irqsave(&wilc->txq_spinlock, p->txq_spinlock_flags); for (i = PendingAcks_arrBase; i < (PendingAcks_arrBase + Pending_Acks); i++) { - if (Pending_Acks_info[i].ack_num < ack_session_info[Pending_Acks_info[i].session_index].bigger_ack_num) { + if (pending_acks_info[i].ack_num < ack_session_info[pending_acks_info[i].session_index].bigger_ack_num) { struct txq_entry_t *tqe; - PRINT_D(TCP_ENH, "DROP ACK: %u\n", Pending_Acks_info[i].ack_num); - tqe = Pending_Acks_info[i].txqe; + PRINT_D(TCP_ENH, "DROP ACK: %u\n", + pending_acks_info[i].ack_num); + tqe = pending_acks_info[i].txqe; if (tqe) { wilc_wlan_txq_remove(tqe); dropped_acks++; @@ -910,7 +911,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) tqe->tx_complete_func(tqe->priv, tqe->status); #ifdef TCP_ACK_FILTER if (tqe->tcp_PendingAck_index != NOT_TCP_ACK) - Pending_Acks_info[tqe->tcp_PendingAck_index].txqe = NULL; + pending_acks_info[tqe->tcp_PendingAck_index].txqe = NULL; #endif kfree(tqe); } else { -- GitLab From 2ae91edb52caf62309b737d904d365a4d8fcfd19 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:41 +0900 Subject: [PATCH 0281/2855] staging: wilc1000: rename PendingAcks_arrBase variable This patch rename the PendingAcks_arrBase variable to pending_base to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 7db42c0fd21f6..a1b6067e12ed3 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -218,7 +218,7 @@ struct ack_session_info *Alloc_head; struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION]; struct pending_acks_info pending_acks_info[MAX_PENDING_ACKS]; -u32 PendingAcks_arrBase; +u32 pending_base; u32 Opened_TCP_session; u32 Pending_Acks; @@ -250,10 +250,10 @@ static inline int add_TCP_Pending_Ack(u32 Ack, u32 Session_index, struct txq_ent { total_acks++; if (Pending_Acks < MAX_PENDING_ACKS) { - pending_acks_info[PendingAcks_arrBase + Pending_Acks].ack_num = Ack; - pending_acks_info[PendingAcks_arrBase + Pending_Acks].txqe = txqe; - pending_acks_info[PendingAcks_arrBase + Pending_Acks].session_index = Session_index; - txqe->tcp_PendingAck_index = PendingAcks_arrBase + Pending_Acks; + pending_acks_info[pending_base + Pending_Acks].ack_num = Ack; + pending_acks_info[pending_base + Pending_Acks].txqe = txqe; + pending_acks_info[pending_base + Pending_Acks].session_index = Session_index; + txqe->tcp_PendingAck_index = pending_base + Pending_Acks; Pending_Acks++; } else { @@ -346,7 +346,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) wilc = nic->wilc; spin_lock_irqsave(&wilc->txq_spinlock, p->txq_spinlock_flags); - for (i = PendingAcks_arrBase; i < (PendingAcks_arrBase + Pending_Acks); i++) { + for (i = pending_base; i < (pending_base + Pending_Acks); i++) { if (pending_acks_info[i].ack_num < ack_session_info[pending_acks_info[i].session_index].bigger_ack_num) { struct txq_entry_t *tqe; @@ -367,10 +367,10 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) Pending_Acks = 0; Opened_TCP_session = 0; - if (PendingAcks_arrBase == 0) - PendingAcks_arrBase = MAX_TCP_SESSION; + if (pending_base == 0) + pending_base = MAX_TCP_SESSION; else - PendingAcks_arrBase = 0; + pending_base = 0; spin_unlock_irqrestore(&wilc->txq_spinlock, p->txq_spinlock_flags); -- GitLab From 3056ec39f864ee10be71433c5347338c1a281c27 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:42 +0900 Subject: [PATCH 0282/2855] staging: wilc1000: rename Opened_TCP_session variable This patch rename the Opened_TCP_session variable to tcp_session to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index a1b6067e12ed3..34e109753ea3e 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -219,7 +219,7 @@ struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION]; struct pending_acks_info pending_acks_info[MAX_PENDING_ACKS]; u32 pending_base; -u32 Opened_TCP_session; +u32 tcp_session; u32 Pending_Acks; static inline int Init_TCP_tracking(void) @@ -229,13 +229,13 @@ static inline int Init_TCP_tracking(void) static inline int add_TCP_track_session(u32 src_prt, u32 dst_prt, u32 seq) { - ack_session_info[Opened_TCP_session].seq_num = seq; - ack_session_info[Opened_TCP_session].bigger_ack_num = 0; - ack_session_info[Opened_TCP_session].src_port = src_prt; - ack_session_info[Opened_TCP_session].dst_port = dst_prt; - Opened_TCP_session++; + ack_session_info[tcp_session].seq_num = seq; + ack_session_info[tcp_session].bigger_ack_num = 0; + ack_session_info[tcp_session].src_port = src_prt; + ack_session_info[tcp_session].dst_port = dst_prt; + tcp_session++; - PRINT_D(TCP_ENH, "TCP Session %d to Ack %d\n", Opened_TCP_session, seq); + PRINT_D(TCP_ENH, "TCP Session %d to Ack %d\n", tcp_session, seq); return 0; } @@ -312,13 +312,13 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) Ack_no = (((u32)tcp_hdr_ptr[8]) << 24) + (((u32)tcp_hdr_ptr[9]) << 16) + (((u32)tcp_hdr_ptr[10]) << 8) + ((u32)tcp_hdr_ptr[11]); - for (i = 0; i < Opened_TCP_session; i++) { + for (i = 0; i < tcp_session; i++) { if (ack_session_info[i].seq_num == seq_no) { Update_TCP_track_session(i, Ack_no); break; } } - if (i == Opened_TCP_session) + if (i == tcp_session) add_TCP_track_session(0, 0, seq_no); add_TCP_Pending_Ack(Ack_no, i, tqe); @@ -365,7 +365,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) } } Pending_Acks = 0; - Opened_TCP_session = 0; + tcp_session = 0; if (pending_base == 0) pending_base = MAX_TCP_SESSION; -- GitLab From d12ac7e2b0c9bcdf9bee0a54424f4e9f270c19a0 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:43 +0900 Subject: [PATCH 0283/2855] staging: wilc1000: rename Pending_Acks variable This patch rename the Pending_Acks variable to pending_acks to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 34e109753ea3e..df20d4d9f48f1 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -220,7 +220,7 @@ struct pending_acks_info pending_acks_info[MAX_PENDING_ACKS]; u32 pending_base; u32 tcp_session; -u32 Pending_Acks; +u32 pending_acks; static inline int Init_TCP_tracking(void) { @@ -249,12 +249,12 @@ static inline int Update_TCP_track_session(u32 index, u32 Ack) static inline int add_TCP_Pending_Ack(u32 Ack, u32 Session_index, struct txq_entry_t *txqe) { total_acks++; - if (Pending_Acks < MAX_PENDING_ACKS) { - pending_acks_info[pending_base + Pending_Acks].ack_num = Ack; - pending_acks_info[pending_base + Pending_Acks].txqe = txqe; - pending_acks_info[pending_base + Pending_Acks].session_index = Session_index; - txqe->tcp_PendingAck_index = pending_base + Pending_Acks; - Pending_Acks++; + if (pending_acks < MAX_PENDING_ACKS) { + pending_acks_info[pending_base + pending_acks].ack_num = Ack; + pending_acks_info[pending_base + pending_acks].txqe = txqe; + pending_acks_info[pending_base + pending_acks].session_index = Session_index; + txqe->tcp_PendingAck_index = pending_base + pending_acks; + pending_acks++; } else { } @@ -346,7 +346,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) wilc = nic->wilc; spin_lock_irqsave(&wilc->txq_spinlock, p->txq_spinlock_flags); - for (i = pending_base; i < (pending_base + Pending_Acks); i++) { + for (i = pending_base; i < (pending_base + pending_acks); i++) { if (pending_acks_info[i].ack_num < ack_session_info[pending_acks_info[i].session_index].bigger_ack_num) { struct txq_entry_t *tqe; @@ -364,7 +364,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) } } } - Pending_Acks = 0; + pending_acks = 0; tcp_session = 0; if (pending_base == 0) -- GitLab From ef06b5f7330182604c348b7ee8fef6620bc5a44e Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:44 +0900 Subject: [PATCH 0284/2855] staging: wilc1000: rename Init_TCP_tracking function This patch rename the Init_TCP_tracking function to init_tcp_tracking to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index df20d4d9f48f1..df0f5ce5b2033 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -222,7 +222,7 @@ u32 pending_base; u32 tcp_session; u32 pending_acks; -static inline int Init_TCP_tracking(void) +static inline int init_tcp_tracking(void) { return 0; } @@ -1697,7 +1697,7 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) goto _fail_; } #ifdef TCP_ACK_FILTER - Init_TCP_tracking(); + init_tcp_tracking(); #endif return 1; -- GitLab From 67620788526cec1bcd5e5ff44b529d24f104172e Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:45 +0900 Subject: [PATCH 0285/2855] staging: wilc1000: rename add_TCP_track_session function This patch rename the add_TCP_track_session function to add_tcp_session to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index df0f5ce5b2033..75b35b8412c09 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -227,7 +227,7 @@ static inline int init_tcp_tracking(void) return 0; } -static inline int add_TCP_track_session(u32 src_prt, u32 dst_prt, u32 seq) +static inline int add_tcp_session(u32 src_prt, u32 dst_prt, u32 seq) { ack_session_info[tcp_session].seq_num = seq; ack_session_info[tcp_session].bigger_ack_num = 0; @@ -319,7 +319,7 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) } } if (i == tcp_session) - add_TCP_track_session(0, 0, seq_no); + add_tcp_session(0, 0, seq_no); add_TCP_Pending_Ack(Ack_no, i, tqe); } -- GitLab From bbf3dbd7dd5e4a798936cf1ce624d76f5ec37780 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:46 +0900 Subject: [PATCH 0286/2855] staging: wilc1000: rename Update_TCP_track_session function This patch rename the Update_TCP_track_session function to update_tcp_session to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 75b35b8412c09..c4312bb071bc5 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -239,7 +239,7 @@ static inline int add_tcp_session(u32 src_prt, u32 dst_prt, u32 seq) return 0; } -static inline int Update_TCP_track_session(u32 index, u32 Ack) +static inline int update_tcp_session(u32 index, u32 Ack) { if (Ack > ack_session_info[index].bigger_ack_num) ack_session_info[index].bigger_ack_num = Ack; @@ -314,7 +314,7 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) for (i = 0; i < tcp_session; i++) { if (ack_session_info[i].seq_num == seq_no) { - Update_TCP_track_session(i, Ack_no); + update_tcp_session(i, Ack_no); break; } } -- GitLab From bdc13ad502e3370dbdf285eea0d8f7fe4930fa89 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:47 +0900 Subject: [PATCH 0287/2855] staging: wilc1000: rename add_TCP_Pending_Ack function This patch rename the add_TCP_Pending_Ack function to add_tcp_pending_ack to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index c4312bb071bc5..3e62abd471534 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -246,7 +246,8 @@ static inline int update_tcp_session(u32 index, u32 Ack) return 0; } -static inline int add_TCP_Pending_Ack(u32 Ack, u32 Session_index, struct txq_entry_t *txqe) +static inline int add_tcp_pending_ack(u32 Ack, u32 Session_index, + struct txq_entry_t *txqe) { total_acks++; if (pending_acks < MAX_PENDING_ACKS) { @@ -321,7 +322,7 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) if (i == tcp_session) add_tcp_session(0, 0, seq_no); - add_TCP_Pending_Ack(Ack_no, i, tqe); + add_tcp_pending_ack(Ack_no, i, tqe); } } else { -- GitLab From b801a96c65b9d0fe64f2ce80bec2dd781127eb2f Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:48 +0900 Subject: [PATCH 0288/2855] staging: wilc1000: rename Ack member variable This patch rename the Ack member variable to ack to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 3e62abd471534..58043dc52413c 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -239,19 +239,19 @@ static inline int add_tcp_session(u32 src_prt, u32 dst_prt, u32 seq) return 0; } -static inline int update_tcp_session(u32 index, u32 Ack) +static inline int update_tcp_session(u32 index, u32 ack) { - if (Ack > ack_session_info[index].bigger_ack_num) - ack_session_info[index].bigger_ack_num = Ack; + if (ack > ack_session_info[index].bigger_ack_num) + ack_session_info[index].bigger_ack_num = ack; return 0; } -static inline int add_tcp_pending_ack(u32 Ack, u32 Session_index, +static inline int add_tcp_pending_ack(u32 ack, u32 Session_index, struct txq_entry_t *txqe) { total_acks++; if (pending_acks < MAX_PENDING_ACKS) { - pending_acks_info[pending_base + pending_acks].ack_num = Ack; + pending_acks_info[pending_base + pending_acks].ack_num = ack; pending_acks_info[pending_base + pending_acks].txqe = txqe; pending_acks_info[pending_base + pending_acks].session_index = Session_index; txqe->tcp_PendingAck_index = pending_base + pending_acks; -- GitLab From ea03f57b91dfcd23df11861b212949b1b967374c Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:49 +0900 Subject: [PATCH 0289/2855] staging: wilc1000: rename Session_index member variable This patch rename the Ack Session_index variable to session_index to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 58043dc52413c..ce9f45ca79851 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -246,14 +246,14 @@ static inline int update_tcp_session(u32 index, u32 ack) return 0; } -static inline int add_tcp_pending_ack(u32 ack, u32 Session_index, +static inline int add_tcp_pending_ack(u32 ack, u32 session_index, struct txq_entry_t *txqe) { total_acks++; if (pending_acks < MAX_PENDING_ACKS) { pending_acks_info[pending_base + pending_acks].ack_num = ack; pending_acks_info[pending_base + pending_acks].txqe = txqe; - pending_acks_info[pending_base + pending_acks].session_index = Session_index; + pending_acks_info[pending_base + pending_acks].session_index = session_index; txqe->tcp_PendingAck_index = pending_base + pending_acks; pending_acks++; } else { -- GitLab From 6ef3be9fb76c626541d80c273c13a56228b38731 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:50 +0900 Subject: [PATCH 0290/2855] staging: wilc1000: remove do-nothing else condition case. This patch removes do-nothing else condition case. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index ce9f45ca79851..b07d229eeedcb 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -256,8 +256,6 @@ static inline int add_tcp_pending_ack(u32 ack, u32 session_index, pending_acks_info[pending_base + pending_acks].session_index = session_index; txqe->tcp_PendingAck_index = pending_base + pending_acks; pending_acks++; - } else { - } return 0; } @@ -1630,7 +1628,6 @@ u32 wilc_get_chipid(u8 update) } else { tempchipid = 0x1002b2; } - } else { } chipid = tempchipid; -- GitLab From 24e2dac20c10576d7dac4ca2f93918c397801c57 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:51 +0900 Subject: [PATCH 0291/2855] staging: wilc1000: rename Total_Length variable This patch rename the Total_Length variable to total_length to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index b07d229eeedcb..34a8b47596f7b 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -298,13 +298,14 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) if (protocol == 0x06) { u8 *tcp_hdr_ptr; - u32 IHL, Total_Length, Data_offset; + u32 IHL, total_length, Data_offset; tcp_hdr_ptr = &ip_hdr_ptr[IP_HDR_LEN]; IHL = (ip_hdr_ptr[0] & 0xf) << 2; - Total_Length = (((u32)ip_hdr_ptr[2]) << 8) + ((u32)ip_hdr_ptr[3]); + total_length = ((u32)ip_hdr_ptr[2] << 8) + + (u32)ip_hdr_ptr[3]; Data_offset = (((u32)tcp_hdr_ptr[12] & 0xf0) >> 2); - if (Total_Length == (IHL + Data_offset)) { + if (total_length == (IHL + Data_offset)) { u32 seq_no, Ack_no; seq_no = (((u32)tcp_hdr_ptr[4]) << 24) + (((u32)tcp_hdr_ptr[5]) << 16) + (((u32)tcp_hdr_ptr[6]) << 8) + ((u32)tcp_hdr_ptr[7]); -- GitLab From 51bffa96338821d76aa4d61db1ed68c118cd36ed Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:52 +0900 Subject: [PATCH 0292/2855] staging: wilc1000: rename Data_offset variable This patch rename the Data_offset variable to data_offset to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 34a8b47596f7b..6d72e09b0479e 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -298,14 +298,14 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) if (protocol == 0x06) { u8 *tcp_hdr_ptr; - u32 IHL, total_length, Data_offset; + u32 IHL, total_length, data_offset; tcp_hdr_ptr = &ip_hdr_ptr[IP_HDR_LEN]; IHL = (ip_hdr_ptr[0] & 0xf) << 2; total_length = ((u32)ip_hdr_ptr[2] << 8) + (u32)ip_hdr_ptr[3]; - Data_offset = (((u32)tcp_hdr_ptr[12] & 0xf0) >> 2); - if (total_length == (IHL + Data_offset)) { + data_offset = ((u32)tcp_hdr_ptr[12] & 0xf0) >> 2; + if (total_length == (IHL + data_offset)) { u32 seq_no, Ack_no; seq_no = (((u32)tcp_hdr_ptr[4]) << 24) + (((u32)tcp_hdr_ptr[5]) << 16) + (((u32)tcp_hdr_ptr[6]) << 8) + ((u32)tcp_hdr_ptr[7]); -- GitLab From f91c5d77163f76ad8c6f2ea3dd84e0c03406b38b Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:53 +0900 Subject: [PATCH 0293/2855] staging: wilc1000: rename Ack_no variable This patch rename the Ack_no variable to ack_no to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 6d72e09b0479e..52351c6186572 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -306,22 +306,25 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) (u32)ip_hdr_ptr[3]; data_offset = ((u32)tcp_hdr_ptr[12] & 0xf0) >> 2; if (total_length == (IHL + data_offset)) { - u32 seq_no, Ack_no; + u32 seq_no, ack_no; seq_no = (((u32)tcp_hdr_ptr[4]) << 24) + (((u32)tcp_hdr_ptr[5]) << 16) + (((u32)tcp_hdr_ptr[6]) << 8) + ((u32)tcp_hdr_ptr[7]); - Ack_no = (((u32)tcp_hdr_ptr[8]) << 24) + (((u32)tcp_hdr_ptr[9]) << 16) + (((u32)tcp_hdr_ptr[10]) << 8) + ((u32)tcp_hdr_ptr[11]); + ack_no = ((u32)tcp_hdr_ptr[8] << 24) + + ((u32)tcp_hdr_ptr[9] << 16) + + ((u32)tcp_hdr_ptr[10] << 8) + + (u32)tcp_hdr_ptr[11]; for (i = 0; i < tcp_session; i++) { if (ack_session_info[i].seq_num == seq_no) { - update_tcp_session(i, Ack_no); + update_tcp_session(i, ack_no); break; } } if (i == tcp_session) add_tcp_session(0, 0, seq_no); - add_tcp_pending_ack(Ack_no, i, tqe); + add_tcp_pending_ack(ack_no, i, tqe); } } else { -- GitLab From 4478c62aa44c5caaaf6bb4d7917a3eacda214d2a Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:54 +0900 Subject: [PATCH 0294/2855] staging: wilc1000: remove warnings line over 80 characters This patch removes the warnings reported by checkpatch.pl for line over 80 characters. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 52351c6186572..66d7f1e86419e 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -308,7 +308,10 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) if (total_length == (IHL + data_offset)) { u32 seq_no, ack_no; - seq_no = (((u32)tcp_hdr_ptr[4]) << 24) + (((u32)tcp_hdr_ptr[5]) << 16) + (((u32)tcp_hdr_ptr[6]) << 8) + ((u32)tcp_hdr_ptr[7]); + seq_no = ((u32)tcp_hdr_ptr[4] << 24) + + ((u32)tcp_hdr_ptr[5] << 16) + + ((u32)tcp_hdr_ptr[6] << 8) + + (u32)tcp_hdr_ptr[7]; ack_no = ((u32)tcp_hdr_ptr[8] << 24) + ((u32)tcp_hdr_ptr[9] << 16) + -- GitLab From 442eda4ecb614caaec605a17a1c57fecbd7bd72f Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:55 +0900 Subject: [PATCH 0295/2855] staging: wilc1000: rename Dropped variable This patch rename the Dropped variable to dropped to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 66d7f1e86419e..283ab521ba18a 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -345,7 +345,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) perInterface_wlan_t *nic; struct wilc *wilc; u32 i = 0; - u32 Dropped = 0; + u32 dropped = 0; wilc_wlan_dev_t *p = &g_wlan; nic = netdev_priv(dev); @@ -366,7 +366,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) if (tqe->tx_complete_func) tqe->tx_complete_func(tqe->priv, tqe->status); kfree(tqe); - Dropped++; + dropped++; } } } @@ -380,9 +380,9 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) spin_unlock_irqrestore(&wilc->txq_spinlock, p->txq_spinlock_flags); - while (Dropped > 0) { + while (dropped > 0) { linux_wlan_lock_timeout(&wilc->txq_event, 1); - Dropped--; + dropped--; } return 1; -- GitLab From 7c4bafe9e0ec64dd76d6a87633fea1739ef236de Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:56 +0900 Subject: [PATCH 0296/2855] staging: wilc1000: rename EnableTCPAckFilter variable This patch rename the EnableTCPAckFilter variable to enabled to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 283ab521ba18a..0bfd1bd9aa2f1 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -389,16 +389,16 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) } #endif -bool EnableTCPAckFilter = false; +bool enabled = false; void Enable_TCP_ACK_Filter(bool value) { - EnableTCPAckFilter = value; + enabled = value; } bool is_TCP_ACK_Filter_Enabled(void) { - return EnableTCPAckFilter; + return enabled; } static int wilc_wlan_txq_add_cfg_pkt(u8 *buffer, u32 buffer_size) -- GitLab From b9e04aa648fccd5d82067a12bc11359ac8b8b8ee Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:57 +0900 Subject: [PATCH 0297/2855] staging: wilc1000: rename Enable_TCP_ACK_Filter function This patch rename the Enable_TCP_ACK_Filter function to enable_tcp_ack_filter to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 4 ++-- drivers/staging/wilc1000/wilc_wfi_cfgoperations.h | 2 +- drivers/staging/wilc1000/wilc_wlan.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 5291868b70773..6f405221030cb 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -1570,9 +1570,9 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) && (strStatistics.link_speed != DEFAULT_LINK_SPEED)) - Enable_TCP_ACK_Filter(true); + enable_tcp_ack_filter(true); else if (strStatistics.link_speed != DEFAULT_LINK_SPEED) - Enable_TCP_ACK_Filter(false); + enable_tcp_ack_filter(false); PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets, sinfo->tx_failed, sinfo->txrate.legacy); diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h index 39cd8e1b56756..d7bdca1f4c5ba 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h @@ -104,6 +104,6 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, #define TCP_ACK_FILTER_LINK_SPEED_THRESH 54 #define DEFAULT_LINK_SPEED 72 -void Enable_TCP_ACK_Filter(bool value); +void enable_tcp_ack_filter(bool value); #endif diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 0bfd1bd9aa2f1..53c5804dd1721 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -391,7 +391,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) bool enabled = false; -void Enable_TCP_ACK_Filter(bool value) +void enable_tcp_ack_filter(bool value) { enabled = value; } -- GitLab From 44c4417d1b2b3a05c9dd8f653915d2c3a6de4182 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:58 +0900 Subject: [PATCH 0298/2855] staging: wilc1000: rename is_TCP_ACK_Filter_Enabled function This patch rename the is_TCP_ACK_Filter_Enabled function to is_tcp_ack_filter_enabled to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 53c5804dd1721..78a43590e6452 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -396,7 +396,7 @@ void enable_tcp_ack_filter(bool value) enabled = value; } -bool is_TCP_ACK_Filter_Enabled(void) +bool is_tcp_ack_filter_enabled(void) { return enabled; } @@ -456,7 +456,7 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, PRINT_D(TX_DBG, "Adding mgmt packet at the Queue tail\n"); #ifdef TCP_ACK_FILTER tqe->tcp_PendingAck_index = NOT_TCP_ACK; - if (is_TCP_ACK_Filter_Enabled()) + if (is_tcp_ack_filter_enabled()) tcp_process(dev, tqe); #endif wilc_wlan_txq_add_to_tail(dev, tqe); -- GitLab From 1d401a4d66f6a3b1c70eec21288fe05d804d4bd8 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:12:59 +0900 Subject: [PATCH 0299/2855] staging: wilc1000: fixes a struct allocation to match coding standards This patch fixes the checks reported by checkpatch.pl for prefer kmalloc(sizeof(*tqe)...) over kmalloc(sizeof(struct txq_entry_t)...) Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 78a43590e6452..0c08a9ac38ae7 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -413,7 +413,7 @@ static int wilc_wlan_txq_add_cfg_pkt(u8 *buffer, u32 buffer_size) return 0; } - tqe = kmalloc(sizeof(struct txq_entry_t), GFP_ATOMIC); + tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC); if (!tqe) { PRINT_ER("Failed to allocate memory\n"); return 0; @@ -443,7 +443,7 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, if (p->quit) return 0; - tqe = kmalloc(sizeof(struct txq_entry_t), GFP_ATOMIC); + tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC); if (!tqe) return 0; @@ -472,7 +472,7 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, if (p->quit) return 0; - tqe = kmalloc(sizeof(struct txq_entry_t), GFP_KERNEL); + tqe = kmalloc(sizeof(*tqe), GFP_KERNEL); if (!tqe) return 0; -- GitLab From 1b721bf03164854da11be947ebf2e9e89994050f Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:13:00 +0900 Subject: [PATCH 0300/2855] staging: wilc1000: remove unused argument of chip_sleep_manually function This patch removes u32SleepTime that is second argument of chip_sleep_manually function because it is not used in this function. Remove argument in the function call also. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 3 +-- drivers/staging/wilc1000/wilc_wlan.c | 2 +- drivers/staging/wilc1000/wilc_wlan.h | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 84a2479600900..7014915e30d1e 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -271,7 +271,6 @@ static struct host_if_drv *join_req_drv; static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo); -extern void chip_sleep_manually(u32 u32SleepTime); extern int linux_wlan_get_num_conn_ifcs(void); static int add_handler_in_list(struct host_if_drv *handler) @@ -2906,7 +2905,7 @@ static int hostIFthread(void *pvArg) PRINT_D(HOSTINF_DBG, "scan completed successfully\n"); if (!linux_wlan_get_num_conn_ifcs()) - chip_sleep_manually(INFINITE_SLEEP_TIME); + chip_sleep_manually(); Handle_ScanDone(msg.drv, SCAN_EVENT_DONE); diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 0c08a9ac38ae7..66d5d42673273 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -680,7 +680,7 @@ static inline void chip_wakeup(void) chip_ps_state = CHIP_WAKEDUP; } #endif -void chip_sleep_manually(u32 u32SleepTime) +void chip_sleep_manually(void) { if (chip_ps_state != CHIP_WAKEDUP) return; diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 2eb7e207b3abe..de2fb7cdd1f4a 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -309,4 +309,5 @@ int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drvHandler); int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size); int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func); +void chip_sleep_manually(void); #endif -- GitLab From b1d19298aaca112c895b26df0488e9c3312a1bcf Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:13:01 +0900 Subject: [PATCH 0301/2855] staging: wilc1000: rename pu32TxqCount in wilc_wlan_handle_txq function This patch rename pu32TxqCount to txq_count that is second argument of wilc_wlan_handle_txq function to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- drivers/staging/wilc1000/wilc_wlan.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 66d5d42673273..cffd7205daeb9 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -695,7 +695,7 @@ void chip_sleep_manually(void) release_bus(RELEASE_ONLY); } -int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount) +int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) { wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; int i, entries = 0; @@ -949,7 +949,7 @@ _end_: p->txq_exit = 1; PRINT_D(TX_DBG, "THREAD: Exiting txq\n"); - *pu32TxqCount = p->txq_entries; + *txq_count = p->txq_entries; return ret; } diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index de2fb7cdd1f4a..1eaac9a9c43cf 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -300,7 +300,7 @@ int wilc_wlan_start(void); int wilc_wlan_stop(void); int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func); -int wilc_wlan_handle_txq(struct net_device *dev, u32 *pu32TxqCount); +int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count); void wilc_handle_isr(void *wilc); void wilc_wlan_cleanup(struct net_device *dev); int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, -- GitLab From 590c0a39650f0212a67141034156cd7452621619 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:13:02 +0900 Subject: [PATCH 0302/2855] staging: wilc1000: fixes else should follow close brace '}' This patch fixes the error reported by checkpatch.pl for else should follow close brace '}' Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index cffd7205daeb9..ec5fc1d3486d9 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -898,14 +898,12 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) memcpy(&txb[offset], &header, 4); if (tqe->type == WILC_CFG_PKT) { buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET; - } - else if (tqe->type == WILC_NET_PKT) { + } else if (tqe->type == WILC_NET_PKT) { char *pBSSID = ((struct tx_complete_data *)(tqe->priv))->pBssid; buffer_offset = ETH_ETHERNET_HDR_OFFSET; memcpy(&txb[offset + 4], pBSSID, 6); - } - else { + } else { buffer_offset = HOST_HDR_OFFSET; } @@ -1008,9 +1006,7 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) pkt_offset &= ~(IS_MANAGMEMENT | IS_MANAGMEMENT_CALLBACK | IS_MGMT_STATUS_SUCCES); WILC_WFI_mgmt_rx(wilc, &buffer[offset + HOST_HDR_OFFSET], pkt_len); - } - else - { + } else { if (!is_cfg_packet) { if (pkt_len > 0) { frmw_to_linux(wilc, -- GitLab From 2f7c31fd9c81a428c024cf5c18eeac6202bfabd7 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:13:03 +0900 Subject: [PATCH 0303/2855] staging: wilc1000: rename pBSSID variable This patch rename the pBSSID variable to bssid to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index ec5fc1d3486d9..f1bb8affec5b4 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -899,10 +899,10 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) if (tqe->type == WILC_CFG_PKT) { buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET; } else if (tqe->type == WILC_NET_PKT) { - char *pBSSID = ((struct tx_complete_data *)(tqe->priv))->pBssid; + char *bssid = ((struct tx_complete_data *)(tqe->priv))->pBssid; buffer_offset = ETH_ETHERNET_HDR_OFFSET; - memcpy(&txb[offset + 4], pBSSID, 6); + memcpy(&txb[offset + 4], bssid, 6); } else { buffer_offset = HOST_HDR_OFFSET; } -- GitLab From 13b01e4095476a19d035effa558f791013b07aca Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:13:04 +0900 Subject: [PATCH 0304/2855] staging: wilc1000: fixes a struct allocation to match coding standards This patch fixes the checks reported by checkpatch.pl for prefer kmalloc(sizeof(*rqe)...) over kmalloc(sizeof(struct rxq_entry_t)...) Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index f1bb8affec5b4..c4118fedfb700 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1132,7 +1132,7 @@ _end_: offset += size; p->rx_buffer_offset = offset; #endif - rqe = kmalloc(sizeof(struct rxq_entry_t), GFP_KERNEL); + rqe = kmalloc(sizeof(*rqe), GFP_KERNEL); if (rqe) { rqe->buffer = buffer; rqe->buffer_size = size; -- GitLab From aa313be3c596542872a1b4cef13a07036a72f422 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:13:05 +0900 Subject: [PATCH 0305/2855] staging: wilc1000: rename bValue in set_machw_change_vir_if function This patch rename bValue to value that is second argument of set_machw_change_vir_if function to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 2 +- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 6f9da09f74c02..54ed723367750 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -217,7 +217,7 @@ void wl_wlan_cleanup(struct wilc *wilc); int wilc_netdev_init(struct wilc **wilc); void wilc1000_wlan_deinit(struct net_device *dev); void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size); -u16 set_machw_change_vir_if(struct net_device *dev, bool bValue); +u16 set_machw_change_vir_if(struct net_device *dev, bool value); int linux_wlan_get_firmware(struct net_device *dev); int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid); #endif diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index c4118fedfb700..458eef2b4df91 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1715,7 +1715,7 @@ _fail_: return ret; } -u16 set_machw_change_vir_if(struct net_device *dev, bool bValue) +u16 set_machw_change_vir_if(struct net_device *dev, bool value) { u16 ret; u32 reg; @@ -1730,7 +1730,7 @@ u16 set_machw_change_vir_if(struct net_device *dev, bool bValue) if (!ret) PRINT_ER("Error while Reading reg WILC_CHANGING_VIR_IF\n"); - if (bValue) + if (value) reg |= BIT(31); else reg &= ~BIT(31); -- GitLab From 7eb17b8d4b49660d2e5c85b234194a0eb3b4e284 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:13:06 +0900 Subject: [PATCH 0306/2855] staging: wilc1000: fixes braces {} should be used on all arms of this statement This patch fixes the error reported by checkpatch.pl for braces {} should be used on all arms of this statement Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 458eef2b4df91..3b097c137fd38 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1104,9 +1104,9 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) if (LINUX_RX_SIZE - offset < size) offset = 0; - if (p->rx_buffer) + if (p->rx_buffer) { buffer = &p->rx_buffer[offset]; - else { + } else { wilc_debug(N_ERR, "[wilc isr]: fail Rx Buffer is NULL...drop the packets (%d)\n", size); goto _end_; } -- GitLab From 076ef657983d79221cb6f1c9628af2477ead6214 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:13:07 +0900 Subject: [PATCH 0307/2855] staging: wilc1000: fixes braces {} are not necessary for any arm of this statement This patch fixes the warning reported by checkpatch.pl for braces {} are not necessary for any arm of this statement Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 3b097c137fd38..d7834c5c31306 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1457,11 +1457,10 @@ static int wilc_wlan_cfg_commit(int type, u32 drvHandler) int seq_no = p->cfg_seq_no % 256; int driver_handler = (u32)drvHandler; - if (type == WILC_CFG_SET) { + if (type == WILC_CFG_SET) cfg->wid_header[0] = 'W'; - } else { + else cfg->wid_header[0] = 'Q'; - } cfg->wid_header[1] = seq_no; cfg->wid_header[2] = (u8)total_len; cfg->wid_header[3] = (u8)(total_len >> 8); -- GitLab From 486416798aa8ec2035492b2770104ba5d2a7da6d Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:13:08 +0900 Subject: [PATCH 0308/2855] staging: wilc1000: rename drvHandler in wilc_wlan_cfg_commit function This patch rename drvHandler to drv_handler that is third argument of wilc_wlan_cfg_commit function to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index d7834c5c31306..2e1d9b8796cde 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1449,13 +1449,13 @@ void wilc_wlan_cleanup(struct net_device *dev) p->hif_func.hif_deinit(NULL); } -static int wilc_wlan_cfg_commit(int type, u32 drvHandler) +static int wilc_wlan_cfg_commit(int type, u32 drv_handler) { wilc_wlan_dev_t *p = &g_wlan; wilc_cfg_frame_t *cfg = &p->cfg_frame; int total_len = p->cfg_frame_offset + 4 + DRIVER_HANDLER_SIZE; int seq_no = p->cfg_seq_no % 256; - int driver_handler = (u32)drvHandler; + int driver_handler = (u32)drv_handler; if (type == WILC_CFG_SET) cfg->wid_header[0] = 'W'; -- GitLab From 9cd034b8418a8774ef57875e682bf71c9f2afca0 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:13:09 +0900 Subject: [PATCH 0309/2855] staging: wilc1000: rename drvHandler in wilc_wlan_cfg_set function This patch rename drvHandler to drv_handler that is seventh argument of wilc_wlan_cfg_set function to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- drivers/staging/wilc1000/wilc_wlan.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 2e1d9b8796cde..f0a81318ab165 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1477,7 +1477,7 @@ static int wilc_wlan_cfg_commit(int type, u32 drv_handler) } int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, - int commit, u32 drvHandler) + int commit, u32 drv_handler) { wilc_wlan_dev_t *p = &g_wlan; u32 offset; @@ -1500,7 +1500,7 @@ int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, PRINT_D(RX_DBG, "Processing cfg_set()\n"); p->cfg_frame_in_use = 1; - if (wilc_wlan_cfg_commit(WILC_CFG_SET, drvHandler)) + if (wilc_wlan_cfg_commit(WILC_CFG_SET, drv_handler)) ret_size = 0; if (linux_wlan_lock_timeout(&g_linux_wlan->cfg_event, diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 1eaac9a9c43cf..03af19bfa37cc 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -304,7 +304,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count); void wilc_handle_isr(void *wilc); void wilc_wlan_cleanup(struct net_device *dev); int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, - int commit, u32 drvHandler); + int commit, u32 drv_handler); int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drvHandler); int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size); int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, -- GitLab From 4878bd6c8cea8c7986a450c8fc5dd0148d233cf4 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:13:10 +0900 Subject: [PATCH 0310/2855] staging: wilc1000: rename drvHandler in wilc_wlan_cfg_get function This patch rename drvHandler to drv_handler that is fifth argument of wilc_wlan_cfg_get function to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- drivers/staging/wilc1000/wilc_wlan.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index f0a81318ab165..09029b61be520 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1516,7 +1516,7 @@ int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, return ret_size; } -int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drvHandler) +int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drv_handler) { wilc_wlan_dev_t *p = &g_wlan; u32 offset; @@ -1536,7 +1536,7 @@ int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drvHandler) if (commit) { p->cfg_frame_in_use = 1; - if (wilc_wlan_cfg_commit(WILC_CFG_QUERY, drvHandler)) + if (wilc_wlan_cfg_commit(WILC_CFG_QUERY, drv_handler)) ret_size = 0; if (linux_wlan_lock_timeout(&g_linux_wlan->cfg_event, diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 03af19bfa37cc..55e4f19e29daa 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -305,7 +305,7 @@ void wilc_handle_isr(void *wilc); void wilc_wlan_cleanup(struct net_device *dev); int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, int commit, u32 drv_handler); -int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drvHandler); +int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drv_handler); int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size); int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func); -- GitLab From 9962b1a0401801ef27c8403c7dec597ea6467e0f Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:19:49 +0900 Subject: [PATCH 0311/2855] staging: wilc1000: wilc_wlan.c: remove unused pointer variables This patch removes unused two pointer variable. - Free_head - Alloc_head It's pointer variables unused inside code. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 09029b61be520..7e7e77facc5f7 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -208,9 +208,6 @@ struct pending_acks_info { struct txq_entry_t *txqe; }; -struct ack_session_info *Free_head; -struct ack_session_info *Alloc_head; - #define NOT_TCP_ACK (-1) #define MAX_TCP_SESSION 25 -- GitLab From 66a43a916263580a38f9882314f42ac864389ba2 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:19:50 +0900 Subject: [PATCH 0312/2855] staging: wilc1000: fixes alignment should match open parenthesis This patch fixes the checks reported by checkpatch.pl for alignment should match open parenthesis. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 7e7e77facc5f7..68158c94248fe 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -244,7 +244,7 @@ static inline int update_tcp_session(u32 index, u32 ack) } static inline int add_tcp_pending_ack(u32 ack, u32 session_index, - struct txq_entry_t *txqe) + struct txq_entry_t *txqe) { total_acks++; if (pending_acks < MAX_PENDING_ACKS) { -- GitLab From 8e55639d066f4ef402ba88fca08ed1be70e1c4da Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:19:51 +0900 Subject: [PATCH 0313/2855] staging: wilc1000: rename tcp_PendingAck_index of struct txq_entry_t This patch renames tcp_PendingAck_index of struct txq_entry_t to index to avoid CamelCase naming convention. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 12 ++++++------ drivers/staging/wilc1000/wilc_wlan.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 68158c94248fe..679ae7efa4312 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -251,7 +251,7 @@ static inline int add_tcp_pending_ack(u32 ack, u32 session_index, pending_acks_info[pending_base + pending_acks].ack_num = ack; pending_acks_info[pending_base + pending_acks].txqe = txqe; pending_acks_info[pending_base + pending_acks].session_index = session_index; - txqe->tcp_PendingAck_index = pending_base + pending_acks; + txqe->index = pending_base + pending_acks; pending_acks++; } return 0; @@ -422,7 +422,7 @@ static int wilc_wlan_txq_add_cfg_pkt(u8 *buffer, u32 buffer_size) tqe->tx_complete_func = NULL; tqe->priv = NULL; #ifdef TCP_ACK_FILTER - tqe->tcp_PendingAck_index = NOT_TCP_ACK; + tqe->index = NOT_TCP_ACK; #endif PRINT_D(TX_DBG, "Adding the config packet at the Queue tail\n"); @@ -452,7 +452,7 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, PRINT_D(TX_DBG, "Adding mgmt packet at the Queue tail\n"); #ifdef TCP_ACK_FILTER - tqe->tcp_PendingAck_index = NOT_TCP_ACK; + tqe->index = NOT_TCP_ACK; if (is_tcp_ack_filter_enabled()) tcp_process(dev, tqe); #endif @@ -479,7 +479,7 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, tqe->tx_complete_func = func; tqe->priv = priv; #ifdef TCP_ACK_FILTER - tqe->tcp_PendingAck_index = NOT_TCP_ACK; + tqe->index = NOT_TCP_ACK; #endif PRINT_D(TX_DBG, "Adding Network packet at the Queue tail\n"); wilc_wlan_txq_add_to_tail(dev, tqe); @@ -911,8 +911,8 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) if (tqe->tx_complete_func) tqe->tx_complete_func(tqe->priv, tqe->status); #ifdef TCP_ACK_FILTER - if (tqe->tcp_PendingAck_index != NOT_TCP_ACK) - pending_acks_info[tqe->tcp_PendingAck_index].txqe = NULL; + if (tqe->index != NOT_TCP_ACK) + pending_acks_info[tqe->index].txqe = NULL; #endif kfree(tqe); } else { diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 55e4f19e29daa..ff852b4c27634 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -231,7 +231,7 @@ struct txq_entry_t { struct txq_entry_t *next; struct txq_entry_t *prev; int type; - int tcp_PendingAck_index; + int index; u8 *buffer; int buffer_size; void *priv; -- GitLab From 706671db2f4714c1f5df65861d8b69a61ddd2da3 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:19:52 +0900 Subject: [PATCH 0314/2855] staging: wilc1000: fixes space prohibited between function name and open parenthesis This patch fixes the warning reported by checkpatch.pl for space prohibited between function name and open parenthesis '(' Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 679ae7efa4312..ba5060578c91a 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1678,7 +1678,7 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) goto _fail_; } -#if defined (MEMORY_STATIC) +#if defined(MEMORY_STATIC) if (!g_wlan.rx_buffer) g_wlan.rx_buffer = kmalloc(LINUX_RX_SIZE, GFP_KERNEL); PRINT_D(TX_DBG, "g_wlan.rx_buffer =%p\n", g_wlan.rx_buffer); -- GitLab From 7df0bb0db516095d8b719e8dd0daca22b1daa248 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:19:53 +0900 Subject: [PATCH 0315/2855] staging: wilc1000: fixes possible unnecessary 'out of memory' message This patch fixes the warning reported by checkpatch.pl for possible unnecessary 'out of memory' message Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index ba5060578c91a..70d794b717fdc 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1111,7 +1111,6 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) #else buffer = kmalloc(size, GFP_KERNEL); if (!buffer) { - wilc_debug(N_ERR, "[wilc isr]: fail alloc host memory...drop the packets (%d)\n", size); usleep_range(100 * 1000, 100 * 1000); goto _end_; } -- GitLab From ab12d8c773f86cbbd3773f65b355922fd13e5951 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:19:54 +0900 Subject: [PATCH 0316/2855] staging: wilc1000: remove warnings line over 80 characters This patch removes the warnings reported by checkpatch.pl for line over 80 characters. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 50 +++++++++++++++++++--------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 70d794b717fdc..ffe7baa9277d9 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -361,7 +361,8 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) dropped_acks++; tqe->status = 1; if (tqe->tx_complete_func) - tqe->tx_complete_func(tqe->priv, tqe->status); + tqe->tx_complete_func(tqe->priv, + tqe->status); kfree(tqe); dropped++; } @@ -747,7 +748,8 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) PRINT_D(TX_DBG, "VMM Size AFTER alignment = %d\n", vmm_sz); vmm_table[i] = vmm_sz / 4; - PRINT_D(TX_DBG, "VMMTable entry size = %d\n", vmm_table[i]); + PRINT_D(TX_DBG, "VMMTable entry size = %d\n", + vmm_table[i]); if (tqe->type == WILC_CFG_PKT) { vmm_table[i] |= BIT(10); @@ -883,7 +885,9 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) #endif vmm_sz = (vmm_table[i] & 0x3ff); vmm_sz *= 4; - header = (tqe->type << 31) | (tqe->buffer_size << 15) | vmm_sz; + header = (tqe->type << 31) | + (tqe->buffer_size << 15) | + vmm_sz; if (tqe->type == WILC_MGMT_PKT) header |= BIT(30); else @@ -904,12 +908,14 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) buffer_offset = HOST_HDR_OFFSET; } - memcpy(&txb[offset + buffer_offset], tqe->buffer, tqe->buffer_size); + memcpy(&txb[offset + buffer_offset], + tqe->buffer, tqe->buffer_size); offset += vmm_sz; i++; tqe->status = 1; if (tqe->tx_complete_func) - tqe->tx_complete_func(tqe->priv, tqe->status); + tqe->tx_complete_func(tqe->priv, + tqe->status); #ifdef TCP_ACK_FILTER if (tqe->index != NOT_TCP_ACK) pending_acks_info[tqe->index].txqe = NULL; @@ -970,7 +976,8 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) } buffer = rqe->buffer; size = rqe->buffer_size; - PRINT_D(RX_DBG, "rxQ entery Size = %d - Address = %p\n", size, buffer); + PRINT_D(RX_DBG, "rxQ entery Size = %d - Address = %p\n", + size, buffer); offset = 0; do { @@ -983,7 +990,8 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) #ifdef BIG_ENDIAN header = BYTE_SWAP(header); #endif - PRINT_D(RX_DBG, "Header = %04x - Offset = %d\n", header, offset); + PRINT_D(RX_DBG, "Header = %04x - Offset = %d\n", + header, offset); is_cfg_packet = (header >> 31) & 0x1; pkt_offset = (header >> 22) & 0x1ff; @@ -1000,7 +1008,9 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) #define IS_MGMT_STATUS_SUCCES 0x040 if (pkt_offset & IS_MANAGMEMENT) { - pkt_offset &= ~(IS_MANAGMEMENT | IS_MANAGMEMENT_CALLBACK | IS_MGMT_STATUS_SUCCES); + pkt_offset &= ~(IS_MANAGMEMENT | + IS_MANAGMEMENT_CALLBACK | + IS_MGMT_STATUS_SUCCES); WILC_WFI_mgmt_rx(wilc, &buffer[offset + HOST_HDR_OFFSET], pkt_len); } else { @@ -1356,22 +1366,26 @@ int wilc_wlan_stop(void) release_bus(RELEASE_ALLOW_SLEEP); return ret; } - PRINT_D(GENERIC_DBG, "Read RESET Reg %x : Retry%d\n", reg, timeout); + PRINT_D(GENERIC_DBG, "Read RESET Reg %x : Retry%d\n", + reg, timeout); if ((reg & BIT(10))) { - PRINT_D(GENERIC_DBG, "Bit 10 not reset : Retry %d\n", timeout); + PRINT_D(GENERIC_DBG, "Bit 10 not reset : Retry %d\n", + timeout); reg &= ~BIT(10); ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg); timeout--; } else { - PRINT_D(GENERIC_DBG, "Bit 10 reset after : Retry %d\n", timeout); + PRINT_D(GENERIC_DBG, "Bit 10 reset after : Retry %d\n", + timeout); ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); if (!ret) { PRINT_ER("Error while reading reg\n"); release_bus(RELEASE_ALLOW_SLEEP); return ret; } - PRINT_D(GENERIC_DBG, "Read RESET Reg %x : Retry%d\n", reg, timeout); + PRINT_D(GENERIC_DBG, "Read RESET Reg %x : Retry%d\n", + reg, timeout); break; } @@ -1492,7 +1506,8 @@ int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, p->cfg_frame_offset = offset; if (commit) { - PRINT_D(TX_DBG, "[WILC]PACKET Commit with sequence number %d\n", p->cfg_seq_no); + PRINT_D(TX_DBG, "[WILC]PACKET Commit with sequence number %d\n", + p->cfg_seq_no); PRINT_D(RX_DBG, "Processing cfg_set()\n"); p->cfg_frame_in_use = 1; @@ -1641,21 +1656,24 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) PRINT_D(INIT_DBG, "Initializing WILC_Wlan ...\n"); memset((void *)&g_wlan, 0, sizeof(wilc_wlan_dev_t)); - memcpy((void *)&g_wlan.io_func, (void *)&inp->io_func, sizeof(wilc_wlan_io_func_t)); + memcpy((void *)&g_wlan.io_func, (void *)&inp->io_func, + sizeof(wilc_wlan_io_func_t)); if ((inp->io_func.io_type & 0x1) == HIF_SDIO) { if (!hif_sdio.hif_init(inp, wilc_debug)) { ret = -5; goto _fail_; } - memcpy((void *)&g_wlan.hif_func, &hif_sdio, sizeof(wilc_hif_func_t)); + memcpy((void *)&g_wlan.hif_func, &hif_sdio, + sizeof(wilc_hif_func_t)); } else { if ((inp->io_func.io_type & 0x1) == HIF_SPI) { if (!hif_spi.hif_init(inp, wilc_debug)) { ret = -5; goto _fail_; } - memcpy((void *)&g_wlan.hif_func, &hif_spi, sizeof(wilc_hif_func_t)); + memcpy((void *)&g_wlan.hif_func, &hif_spi, + sizeof(wilc_hif_func_t)); } else { ret = -5; goto _fail_; -- GitLab From 92e7d188860277bf539c247c262d5a7ae098deb4 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:19:55 +0900 Subject: [PATCH 0317/2855] staging: wilc1000: replace numeric type to kernel error type This patch replaces numeric type to generic type by kernel style. -5 -> -EIO -105 -> -ENOBUFS Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index ffe7baa9277d9..283c506b4f214 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1194,7 +1194,7 @@ int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size) dma_buffer = kmalloc(blksz, GFP_KERNEL); if (!dma_buffer) { - ret = -5; + ret = -EIO; PRINT_ER("Can't allocate buffer for firmware download IO error\n "); goto _fail_1; } @@ -1229,7 +1229,7 @@ int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size) release_bus(RELEASE_ONLY); if (!ret) { - ret = -5; + ret = -EIO; PRINT_ER("Can't download firmware IO error\n "); goto _fail_; } @@ -1263,7 +1263,7 @@ int wilc_wlan_start(void) if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail write reg vmm_core_cfg...\n"); release_bus(RELEASE_ONLY); - ret = -5; + ret = -EIO; return ret; } reg = 0; @@ -1298,7 +1298,7 @@ int wilc_wlan_start(void) if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail write WILC_GP_REG_1 ...\n"); release_bus(RELEASE_ONLY); - ret = -5; + ret = -EIO; return ret; } @@ -1308,7 +1308,7 @@ int wilc_wlan_start(void) if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail read reg 0x1000 ...\n"); release_bus(RELEASE_ONLY); - ret = -5; + ret = -EIO; return ret; } @@ -1661,7 +1661,7 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) if ((inp->io_func.io_type & 0x1) == HIF_SDIO) { if (!hif_sdio.hif_init(inp, wilc_debug)) { - ret = -5; + ret = -EIO; goto _fail_; } memcpy((void *)&g_wlan.hif_func, &hif_sdio, @@ -1669,19 +1669,19 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) } else { if ((inp->io_func.io_type & 0x1) == HIF_SPI) { if (!hif_spi.hif_init(inp, wilc_debug)) { - ret = -5; + ret = -EIO; goto _fail_; } memcpy((void *)&g_wlan.hif_func, &hif_spi, sizeof(wilc_hif_func_t)); } else { - ret = -5; + ret = -EIO; goto _fail_; } } if (!wilc_wlan_cfg_init(wilc_debug)) { - ret = -105; + ret = -ENOBUFS; goto _fail_; } @@ -1690,7 +1690,7 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) PRINT_D(TX_DBG, "g_wlan.tx_buffer = %p\n", g_wlan.tx_buffer); if (!g_wlan.tx_buffer) { - ret = -105; + ret = -ENOBUFS; PRINT_ER("Can't allocate Tx Buffer"); goto _fail_; } @@ -1700,14 +1700,14 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) g_wlan.rx_buffer = kmalloc(LINUX_RX_SIZE, GFP_KERNEL); PRINT_D(TX_DBG, "g_wlan.rx_buffer =%p\n", g_wlan.rx_buffer); if (!g_wlan.rx_buffer) { - ret = -105; + ret = -ENOBUFS; PRINT_ER("Can't allocate Rx Buffer"); goto _fail_; } #endif if (!init_chip(dev)) { - ret = -5; + ret = -EIO; goto _fail_; } #ifdef TCP_ACK_FILTER -- GitLab From 7cf241a1cdb481b14e4d55e10d4b45f78aa41df4 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:19:56 +0900 Subject: [PATCH 0318/2855] staging: wilc1000: wilc_wlan.h: alignment defines This patch fixes alignment of defines. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.h | 292 ++++++++++++++------------- 1 file changed, 148 insertions(+), 144 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index ff852b4c27634..ba7063020417c 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -3,7 +3,7 @@ -#define ISWILC1000(id) (((id & 0xfffff000) == 0x100000) ? 1 : 0) +#define ISWILC1000(id) ((id & 0xfffff000) == 0x100000 ? 1 : 0) /******************************************** @@ -11,27 +11,30 @@ * Mac eth header length * ********************************************/ -#define DRIVER_HANDLER_SIZE 4 -#define MAX_MAC_HDR_LEN 26 /* QOS_MAC_HDR_LEN */ -#define SUB_MSDU_HEADER_LENGTH 14 -#define SNAP_HDR_LEN 8 -#define ETHERNET_HDR_LEN 14 -#define WORD_ALIGNMENT_PAD 0 - -#define ETH_ETHERNET_HDR_OFFSET (MAX_MAC_HDR_LEN + SUB_MSDU_HEADER_LENGTH + \ - SNAP_HDR_LEN - ETHERNET_HDR_LEN + WORD_ALIGNMENT_PAD) - -#define HOST_HDR_OFFSET 4 -#define ETHERNET_HDR_LEN 14 -#define IP_HDR_LEN 20 -#define IP_HDR_OFFSET ETHERNET_HDR_LEN -#define UDP_HDR_OFFSET (IP_HDR_LEN + IP_HDR_OFFSET) -#define UDP_HDR_LEN 8 -#define UDP_DATA_OFFSET (UDP_HDR_OFFSET + UDP_HDR_LEN) -#define ETH_CONFIG_PKT_HDR_LEN UDP_DATA_OFFSET - -#define ETH_CONFIG_PKT_HDR_OFFSET (ETH_ETHERNET_HDR_OFFSET + \ - ETH_CONFIG_PKT_HDR_LEN) +#define DRIVER_HANDLER_SIZE 4 +#define MAX_MAC_HDR_LEN 26 /* QOS_MAC_HDR_LEN */ +#define SUB_MSDU_HEADER_LENGTH 14 +#define SNAP_HDR_LEN 8 +#define ETHERNET_HDR_LEN 14 +#define WORD_ALIGNMENT_PAD 0 + +#define ETH_ETHERNET_HDR_OFFSET (MAX_MAC_HDR_LEN + \ + SUB_MSDU_HEADER_LENGTH + \ + SNAP_HDR_LEN - \ + ETHERNET_HDR_LEN + \ + WORD_ALIGNMENT_PAD) + +#define HOST_HDR_OFFSET 4 +#define ETHERNET_HDR_LEN 14 +#define IP_HDR_LEN 20 +#define IP_HDR_OFFSET ETHERNET_HDR_LEN +#define UDP_HDR_OFFSET (IP_HDR_LEN + IP_HDR_OFFSET) +#define UDP_HDR_LEN 8 +#define UDP_DATA_OFFSET (UDP_HDR_OFFSET + UDP_HDR_LEN) +#define ETH_CONFIG_PKT_HDR_LEN UDP_DATA_OFFSET + +#define ETH_CONFIG_PKT_HDR_OFFSET (ETH_ETHERNET_HDR_OFFSET + \ + ETH_CONFIG_PKT_HDR_LEN) /******************************************** * @@ -39,91 +42,92 @@ * ********************************************/ -#define BYTE_SWAP(val) ((((val) & 0x000000FF) << 24) + \ - (((val) & 0x0000FF00) << 8) + \ - (((val) & 0x00FF0000) >> 8) + \ - (((val) & 0xFF000000) >> 24)) +#define BYTE_SWAP(val) (((val & 0x000000FF) << 24) + \ + ((val & 0x0000FF00) << 8) + \ + ((val & 0x00FF0000) >> 8) + \ + ((val & 0xFF000000) >> 24)) /******************************************** * * Register Defines * ********************************************/ -#define WILC_PERIPH_REG_BASE 0x1000 -#define WILC_CHANGING_VIR_IF (0x108c) -#define WILC_CHIPID (WILC_PERIPH_REG_BASE) -#define WILC_GLB_RESET_0 (WILC_PERIPH_REG_BASE + 0x400) -#define WILC_PIN_MUX_0 (WILC_PERIPH_REG_BASE + 0x408) -#define WILC_HOST_TX_CTRL (WILC_PERIPH_REG_BASE + 0x6c) -#define WILC_HOST_RX_CTRL_0 (WILC_PERIPH_REG_BASE + 0x70) -#define WILC_HOST_RX_CTRL_1 (WILC_PERIPH_REG_BASE + 0x74) -#define WILC_HOST_VMM_CTL (WILC_PERIPH_REG_BASE + 0x78) -#define WILC_HOST_RX_CTRL (WILC_PERIPH_REG_BASE + 0x80) -#define WILC_HOST_RX_EXTRA_SIZE (WILC_PERIPH_REG_BASE + 0x84) -#define WILC_HOST_TX_CTRL_1 (WILC_PERIPH_REG_BASE + 0x88) -#define WILC_MISC (WILC_PERIPH_REG_BASE + 0x428) -#define WILC_INTR_REG_BASE (WILC_PERIPH_REG_BASE + 0xa00) -#define WILC_INTR_ENABLE (WILC_INTR_REG_BASE) -#define WILC_INTR2_ENABLE (WILC_INTR_REG_BASE + 4) - -#define WILC_INTR_POLARITY (WILC_INTR_REG_BASE + 0x10) -#define WILC_INTR_TYPE (WILC_INTR_REG_BASE + 0x20) -#define WILC_INTR_CLEAR (WILC_INTR_REG_BASE + 0x30) -#define WILC_INTR_STATUS (WILC_INTR_REG_BASE + 0x40) - -#define WILC_VMM_TBL_SIZE 64 -#define WILC_VMM_TX_TBL_BASE (0x150400) -#define WILC_VMM_RX_TBL_BASE (0x150500) - -#define WILC_VMM_BASE 0x150000 -#define WILC_VMM_CORE_CTL (WILC_VMM_BASE) -#define WILC_VMM_TBL_CTL (WILC_VMM_BASE + 0x4) -#define WILC_VMM_TBL_ENTRY (WILC_VMM_BASE + 0x8) -#define WILC_VMM_TBL0_SIZE (WILC_VMM_BASE + 0xc) -#define WILC_VMM_TO_HOST_SIZE (WILC_VMM_BASE + 0x10) -#define WILC_VMM_CORE_CFG (WILC_VMM_BASE + 0x14) -#define WILC_VMM_TBL_ACTIVE (WILC_VMM_BASE + 040) -#define WILC_VMM_TBL_STATUS (WILC_VMM_BASE + 0x44) - -#define WILC_SPI_REG_BASE 0xe800 -#define WILC_SPI_CTL (WILC_SPI_REG_BASE) -#define WILC_SPI_MASTER_DMA_ADDR (WILC_SPI_REG_BASE + 0x4) -#define WILC_SPI_MASTER_DMA_COUNT (WILC_SPI_REG_BASE + 0x8) -#define WILC_SPI_SLAVE_DMA_ADDR (WILC_SPI_REG_BASE + 0xc) -#define WILC_SPI_SLAVE_DMA_COUNT (WILC_SPI_REG_BASE + 0x10) -#define WILC_SPI_TX_MODE (WILC_SPI_REG_BASE + 0x20) -#define WILC_SPI_PROTOCOL_CONFIG (WILC_SPI_REG_BASE + 0x24) -#define WILC_SPI_INTR_CTL (WILC_SPI_REG_BASE + 0x2c) - -#define WILC_SPI_PROTOCOL_OFFSET (WILC_SPI_PROTOCOL_CONFIG - WILC_SPI_REG_BASE) - -#define WILC_AHB_DATA_MEM_BASE 0x30000 -#define WILC_AHB_SHARE_MEM_BASE 0xd0000 - -#define WILC_VMM_TBL_RX_SHADOW_BASE WILC_AHB_SHARE_MEM_BASE -#define WILC_VMM_TBL_RX_SHADOW_SIZE (256) - -#define WILC_GP_REG_0 0x149c -#define WILC_GP_REG_1 0x14a0 - -#define rHAVE_SDIO_IRQ_GPIO_BIT (0) -#define rHAVE_USE_PMU_BIT (1) -#define rHAVE_SLEEP_CLK_SRC_RTC_BIT (2) -#define rHAVE_SLEEP_CLK_SRC_XO_BIT (3) -#define rHAVE_EXT_PA_INV_TX_RX_BIT (4) -#define rHAVE_LEGACY_RF_SETTINGS_BIT (5) -#define rHAVE_XTAL_24_BIT (6) -#define rHAVE_DISABLE_WILC_UART_BIT (7) - - -#define WILC_HAVE_SDIO_IRQ_GPIO (1 << rHAVE_SDIO_IRQ_GPIO_BIT) -#define WILC_HAVE_USE_PMU (1 << rHAVE_USE_PMU_BIT) -#define WILC_HAVE_SLEEP_CLK_SRC_RTC (1 << rHAVE_SLEEP_CLK_SRC_RTC_BIT) -#define WILC_HAVE_SLEEP_CLK_SRC_XO (1 << rHAVE_SLEEP_CLK_SRC_XO_BIT) -#define WILC_HAVE_EXT_PA_INV_TX_RX (1 << rHAVE_EXT_PA_INV_TX_RX_BIT) -#define WILC_HAVE_LEGACY_RF_SETTINGS (1 << rHAVE_LEGACY_RF_SETTINGS_BIT) -#define WILC_HAVE_XTAL_24 (1 << rHAVE_XTAL_24_BIT) -#define WILC_HAVE_DISABLE_WILC_UART (1 << rHAVE_DISABLE_WILC_UART_BIT) +#define WILC_PERIPH_REG_BASE 0x1000 +#define WILC_CHANGING_VIR_IF 0x108c +#define WILC_CHIPID WILC_PERIPH_REG_BASE +#define WILC_GLB_RESET_0 (WILC_PERIPH_REG_BASE + 0x400) +#define WILC_PIN_MUX_0 (WILC_PERIPH_REG_BASE + 0x408) +#define WILC_HOST_TX_CTRL (WILC_PERIPH_REG_BASE + 0x6c) +#define WILC_HOST_RX_CTRL_0 (WILC_PERIPH_REG_BASE + 0x70) +#define WILC_HOST_RX_CTRL_1 (WILC_PERIPH_REG_BASE + 0x74) +#define WILC_HOST_VMM_CTL (WILC_PERIPH_REG_BASE + 0x78) +#define WILC_HOST_RX_CTRL (WILC_PERIPH_REG_BASE + 0x80) +#define WILC_HOST_RX_EXTRA_SIZE (WILC_PERIPH_REG_BASE + 0x84) +#define WILC_HOST_TX_CTRL_1 (WILC_PERIPH_REG_BASE + 0x88) +#define WILC_MISC (WILC_PERIPH_REG_BASE + 0x428) +#define WILC_INTR_REG_BASE (WILC_PERIPH_REG_BASE + 0xa00) +#define WILC_INTR_ENABLE WILC_INTR_REG_BASE +#define WILC_INTR2_ENABLE (WILC_INTR_REG_BASE + 4) + +#define WILC_INTR_POLARITY (WILC_INTR_REG_BASE + 0x10) +#define WILC_INTR_TYPE (WILC_INTR_REG_BASE + 0x20) +#define WILC_INTR_CLEAR (WILC_INTR_REG_BASE + 0x30) +#define WILC_INTR_STATUS (WILC_INTR_REG_BASE + 0x40) + +#define WILC_VMM_TBL_SIZE 64 +#define WILC_VMM_TX_TBL_BASE 0x150400 +#define WILC_VMM_RX_TBL_BASE 0x150500 + +#define WILC_VMM_BASE 0x150000 +#define WILC_VMM_CORE_CTL WILC_VMM_BASE +#define WILC_VMM_TBL_CTL (WILC_VMM_BASE + 0x4) +#define WILC_VMM_TBL_ENTRY (WILC_VMM_BASE + 0x8) +#define WILC_VMM_TBL0_SIZE (WILC_VMM_BASE + 0xc) +#define WILC_VMM_TO_HOST_SIZE (WILC_VMM_BASE + 0x10) +#define WILC_VMM_CORE_CFG (WILC_VMM_BASE + 0x14) +#define WILC_VMM_TBL_ACTIVE (WILC_VMM_BASE + 040) +#define WILC_VMM_TBL_STATUS (WILC_VMM_BASE + 0x44) + +#define WILC_SPI_REG_BASE 0xe800 +#define WILC_SPI_CTL WILC_SPI_REG_BASE +#define WILC_SPI_MASTER_DMA_ADDR (WILC_SPI_REG_BASE + 0x4) +#define WILC_SPI_MASTER_DMA_COUNT (WILC_SPI_REG_BASE + 0x8) +#define WILC_SPI_SLAVE_DMA_ADDR (WILC_SPI_REG_BASE + 0xc) +#define WILC_SPI_SLAVE_DMA_COUNT (WILC_SPI_REG_BASE + 0x10) +#define WILC_SPI_TX_MODE (WILC_SPI_REG_BASE + 0x20) +#define WILC_SPI_PROTOCOL_CONFIG (WILC_SPI_REG_BASE + 0x24) +#define WILC_SPI_INTR_CTL (WILC_SPI_REG_BASE + 0x2c) + +#define WILC_SPI_PROTOCOL_OFFSET (WILC_SPI_PROTOCOL_CONFIG - \ + WILC_SPI_REG_BASE) + +#define WILC_AHB_DATA_MEM_BASE 0x30000 +#define WILC_AHB_SHARE_MEM_BASE 0xd0000 + +#define WILC_VMM_TBL_RX_SHADOW_BASE WILC_AHB_SHARE_MEM_BASE +#define WILC_VMM_TBL_RX_SHADOW_SIZE 256 + +#define WILC_GP_REG_0 0x149c +#define WILC_GP_REG_1 0x14a0 + +#define rHAVE_SDIO_IRQ_GPIO_BIT 0 +#define rHAVE_USE_PMU_BIT 1 +#define rHAVE_SLEEP_CLK_SRC_RTC_BIT 2 +#define rHAVE_SLEEP_CLK_SRC_XO_BIT 3 +#define rHAVE_EXT_PA_INV_TX_RX_BIT 4 +#define rHAVE_LEGACY_RF_SETTINGS_BIT 5 +#define rHAVE_XTAL_24_BIT 6 +#define rHAVE_DISABLE_WILC_UART_BIT 7 + + +#define WILC_HAVE_SDIO_IRQ_GPIO (1 << rHAVE_SDIO_IRQ_GPIO_BIT) +#define WILC_HAVE_USE_PMU (1 << rHAVE_USE_PMU_BIT) +#define WILC_HAVE_SLEEP_CLK_SRC_RTC (1 << rHAVE_SLEEP_CLK_SRC_RTC_BIT) +#define WILC_HAVE_SLEEP_CLK_SRC_XO (1 << rHAVE_SLEEP_CLK_SRC_XO_BIT) +#define WILC_HAVE_EXT_PA_INV_TX_RX (1 << rHAVE_EXT_PA_INV_TX_RX_BIT) +#define WILC_HAVE_LEGACY_RF_SETTINGS (1 << rHAVE_LEGACY_RF_SETTINGS_BIT) +#define WILC_HAVE_XTAL_24 (1 << rHAVE_XTAL_24_BIT) +#define WILC_HAVE_DISABLE_WILC_UART (1 << rHAVE_DISABLE_WILC_UART_BIT) /******************************************** @@ -131,25 +135,25 @@ * Wlan Defines * ********************************************/ -#define WILC_CFG_PKT 1 -#define WILC_NET_PKT 0 -#define WILC_MGMT_PKT 2 +#define WILC_CFG_PKT 1 +#define WILC_NET_PKT 0 +#define WILC_MGMT_PKT 2 -#define WILC_CFG_SET 1 -#define WILC_CFG_QUERY 0 +#define WILC_CFG_SET 1 +#define WILC_CFG_QUERY 0 -#define WILC_CFG_RSP 1 -#define WILC_CFG_RSP_STATUS 2 -#define WILC_CFG_RSP_SCAN 3 +#define WILC_CFG_RSP 1 +#define WILC_CFG_RSP_STATUS 2 +#define WILC_CFG_RSP_SCAN 3 #ifdef WILC_SDIO -#define WILC_PLL_TO 4 +#define WILC_PLL_TO 4 #else -#define WILC_PLL_TO 2 +#define WILC_PLL_TO 2 #endif -#define ABORT_INT BIT(31) +#define ABORT_INT BIT(31) /*******************************************/ /* E0 and later Interrupt flags. */ @@ -165,15 +169,15 @@ /* 20: INT4 flag */ /* 21: INT5 flag */ /*******************************************/ -#define IRG_FLAGS_OFFSET 16 -#define IRQ_DMA_WD_CNT_MASK ((1ul << IRG_FLAGS_OFFSET) - 1) -#define INT_0 (1 << (IRG_FLAGS_OFFSET)) -#define INT_1 (1 << (IRG_FLAGS_OFFSET + 1)) -#define INT_2 (1 << (IRG_FLAGS_OFFSET + 2)) -#define INT_3 (1 << (IRG_FLAGS_OFFSET + 3)) -#define INT_4 (1 << (IRG_FLAGS_OFFSET + 4)) -#define INT_5 (1 << (IRG_FLAGS_OFFSET + 5)) -#define MAX_NUM_INT (6) +#define IRG_FLAGS_OFFSET 16 +#define IRQ_DMA_WD_CNT_MASK ((1ul << IRG_FLAGS_OFFSET) - 1) +#define INT_0 (1 << IRG_FLAGS_OFFSET) +#define INT_1 (1 << (IRG_FLAGS_OFFSET + 1)) +#define INT_2 (1 << (IRG_FLAGS_OFFSET + 2)) +#define INT_3 (1 << (IRG_FLAGS_OFFSET + 3)) +#define INT_4 (1 << (IRG_FLAGS_OFFSET + 4)) +#define INT_5 (1 << (IRG_FLAGS_OFFSET + 5)) +#define MAX_NUM_INT 6 /*******************************************/ /* E0 and later Interrupt flags. */ @@ -188,28 +192,28 @@ /* 7: Select VMM table 2 */ /* 8: Enable VMM */ /*******************************************/ -#define CLR_INT0 BIT(0) -#define CLR_INT1 BIT(1) -#define CLR_INT2 BIT(2) -#define CLR_INT3 BIT(3) -#define CLR_INT4 BIT(4) -#define CLR_INT5 BIT(5) -#define SEL_VMM_TBL0 BIT(6) -#define SEL_VMM_TBL1 BIT(7) -#define EN_VMM BIT(8) - -#define DATA_INT_EXT INT_0 -#define PLL_INT_EXT INT_1 -#define SLEEP_INT_EXT INT_2 -#define ALL_INT_EXT (DATA_INT_EXT | PLL_INT_EXT | SLEEP_INT_EXT) -#define NUM_INT_EXT (3) - -#define DATA_INT_CLR CLR_INT0 -#define PLL_INT_CLR CLR_INT1 -#define SLEEP_INT_CLR CLR_INT2 - -#define ENABLE_RX_VMM (SEL_VMM_TBL1 | EN_VMM) -#define ENABLE_TX_VMM (SEL_VMM_TBL0 | EN_VMM) +#define CLR_INT0 BIT(0) +#define CLR_INT1 BIT(1) +#define CLR_INT2 BIT(2) +#define CLR_INT3 BIT(3) +#define CLR_INT4 BIT(4) +#define CLR_INT5 BIT(5) +#define SEL_VMM_TBL0 BIT(6) +#define SEL_VMM_TBL1 BIT(7) +#define EN_VMM BIT(8) + +#define DATA_INT_EXT INT_0 +#define PLL_INT_EXT INT_1 +#define SLEEP_INT_EXT INT_2 +#define ALL_INT_EXT (DATA_INT_EXT | PLL_INT_EXT | SLEEP_INT_EXT) +#define NUM_INT_EXT 3 + +#define DATA_INT_CLR CLR_INT0 +#define PLL_INT_CLR CLR_INT1 +#define SLEEP_INT_CLR CLR_INT2 + +#define ENABLE_RX_VMM (SEL_VMM_TBL1 | EN_VMM) +#define ENABLE_TX_VMM (SEL_VMM_TBL0 | EN_VMM) /*time for expiring the semaphores of cfg packets*/ @@ -276,7 +280,7 @@ typedef struct { * ********************************************/ -#define MAX_CFG_FRAME_SIZE 1468 +#define MAX_CFG_FRAME_SIZE 1468 typedef struct { u8 ether_header[14]; -- GitLab From 97c14e8cd291b1dc60701a4c6b1b66c3271c26e0 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:19:57 +0900 Subject: [PATCH 0319/2855] staging: wilc1000: fixes prefer using the BIT macro This patch fixes the warning reported by checkpatch.pl for prefer using the BIT macro. And, removes unnecessary bit increase defines. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.h | 39 ++++++++++------------------ 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index ba7063020417c..6ca254435846f 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -110,25 +110,14 @@ #define WILC_GP_REG_0 0x149c #define WILC_GP_REG_1 0x14a0 -#define rHAVE_SDIO_IRQ_GPIO_BIT 0 -#define rHAVE_USE_PMU_BIT 1 -#define rHAVE_SLEEP_CLK_SRC_RTC_BIT 2 -#define rHAVE_SLEEP_CLK_SRC_XO_BIT 3 -#define rHAVE_EXT_PA_INV_TX_RX_BIT 4 -#define rHAVE_LEGACY_RF_SETTINGS_BIT 5 -#define rHAVE_XTAL_24_BIT 6 -#define rHAVE_DISABLE_WILC_UART_BIT 7 - - -#define WILC_HAVE_SDIO_IRQ_GPIO (1 << rHAVE_SDIO_IRQ_GPIO_BIT) -#define WILC_HAVE_USE_PMU (1 << rHAVE_USE_PMU_BIT) -#define WILC_HAVE_SLEEP_CLK_SRC_RTC (1 << rHAVE_SLEEP_CLK_SRC_RTC_BIT) -#define WILC_HAVE_SLEEP_CLK_SRC_XO (1 << rHAVE_SLEEP_CLK_SRC_XO_BIT) -#define WILC_HAVE_EXT_PA_INV_TX_RX (1 << rHAVE_EXT_PA_INV_TX_RX_BIT) -#define WILC_HAVE_LEGACY_RF_SETTINGS (1 << rHAVE_LEGACY_RF_SETTINGS_BIT) -#define WILC_HAVE_XTAL_24 (1 << rHAVE_XTAL_24_BIT) -#define WILC_HAVE_DISABLE_WILC_UART (1 << rHAVE_DISABLE_WILC_UART_BIT) - +#define WILC_HAVE_SDIO_IRQ_GPIO BIT(0) +#define WILC_HAVE_USE_PMU BIT(1) +#define WILC_HAVE_SLEEP_CLK_SRC_RTC BIT(2) +#define WILC_HAVE_SLEEP_CLK_SRC_XO BIT(3) +#define WILC_HAVE_EXT_PA_INV_TX_RX BIT(4) +#define WILC_HAVE_LEGACY_RF_SETTINGS BIT(5) +#define WILC_HAVE_XTAL_24 BIT(6) +#define WILC_HAVE_DISABLE_WILC_UART BIT(7) /******************************************** * @@ -171,12 +160,12 @@ /*******************************************/ #define IRG_FLAGS_OFFSET 16 #define IRQ_DMA_WD_CNT_MASK ((1ul << IRG_FLAGS_OFFSET) - 1) -#define INT_0 (1 << IRG_FLAGS_OFFSET) -#define INT_1 (1 << (IRG_FLAGS_OFFSET + 1)) -#define INT_2 (1 << (IRG_FLAGS_OFFSET + 2)) -#define INT_3 (1 << (IRG_FLAGS_OFFSET + 3)) -#define INT_4 (1 << (IRG_FLAGS_OFFSET + 4)) -#define INT_5 (1 << (IRG_FLAGS_OFFSET + 5)) +#define INT_0 BIT(IRG_FLAGS_OFFSET) +#define INT_1 BIT(IRG_FLAGS_OFFSET + 1) +#define INT_2 BIT(IRG_FLAGS_OFFSET + 2) +#define INT_3 BIT(IRG_FLAGS_OFFSET + 3) +#define INT_4 BIT(IRG_FLAGS_OFFSET + 4) +#define INT_5 BIT(IRG_FLAGS_OFFSET + 5) #define MAX_NUM_INT 6 /*******************************************/ -- GitLab From c222096361171782c5fb689b185d367d89396da9 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:19:58 +0900 Subject: [PATCH 0320/2855] staging: wilc1000: fixes please don't use multiple blank lines This patch fixes the checks reported by checkpatch.pl for Please don't use multiple blank lines. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 6ca254435846f..74f6210c12910 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -1,11 +1,7 @@ #ifndef WILC_WLAN_H #define WILC_WLAN_H - - #define ISWILC1000(id) ((id & 0xfffff000) == 0x100000 ? 1 : 0) - - /******************************************** * * Mac eth header length @@ -140,8 +136,6 @@ #else #define WILC_PLL_TO 2 #endif - - #define ABORT_INT BIT(31) /*******************************************/ @@ -203,8 +197,6 @@ #define ENABLE_RX_VMM (SEL_VMM_TBL1 | EN_VMM) #define ENABLE_TX_VMM (SEL_VMM_TBL0 | EN_VMM) - - /*time for expiring the semaphores of cfg packets*/ #define CFG_PKTS_TIMEOUT 2000 /******************************************** -- GitLab From 14cdc0a14bf681ffb1ef2b7ba6edb66933300600 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:19:59 +0900 Subject: [PATCH 0321/2855] staging: wilc1000: remove typedef from wilc_cfg_frame_t This patch removes typedef from the struct wilc_cfg_frame_t and renames it to wilc_cfg_frame. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- drivers/staging/wilc1000/wilc_wlan.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 283c506b4f214..c61048b5c54e5 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -11,7 +11,7 @@ typedef struct { wilc_wlan_io_func_t io_func; wilc_hif_func_t hif_func; int cfg_frame_in_use; - wilc_cfg_frame_t cfg_frame; + struct wilc_cfg_frame cfg_frame; u32 cfg_frame_offset; int cfg_seq_no; @@ -1462,7 +1462,7 @@ void wilc_wlan_cleanup(struct net_device *dev) static int wilc_wlan_cfg_commit(int type, u32 drv_handler) { wilc_wlan_dev_t *p = &g_wlan; - wilc_cfg_frame_t *cfg = &p->cfg_frame; + struct wilc_cfg_frame *cfg = &p->cfg_frame; int total_len = p->cfg_frame_offset + 4 + DRIVER_HANDLER_SIZE; int seq_no = p->cfg_seq_no % 256; int driver_handler = (u32)drv_handler; diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 74f6210c12910..d15c848d8a7bc 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -263,13 +263,13 @@ typedef struct { #define MAX_CFG_FRAME_SIZE 1468 -typedef struct { +struct wilc_cfg_frame { u8 ether_header[14]; u8 ip_header[20]; u8 udp_header[8]; u8 wid_header[8]; u8 frame[MAX_CFG_FRAME_SIZE]; -} wilc_cfg_frame_t; +}; typedef struct { int (*wlan_tx)(u8 *, u32, wilc_tx_complete_func_t); -- GitLab From 0e354a8e650de974e03eeaa9a1cb1bc379e89968 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:20:00 +0900 Subject: [PATCH 0322/2855] staging: wilc1000: remove unused typedef wilc_wlan_cfg_func_t This patch removes unused typedef wilc_wlan_cfg_func_t of wilc_wlan.h. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index d15c848d8a7bc..6c784fd591e6c 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -271,10 +271,6 @@ struct wilc_cfg_frame { u8 frame[MAX_CFG_FRAME_SIZE]; }; -typedef struct { - int (*wlan_tx)(u8 *, u32, wilc_tx_complete_func_t); -} wilc_wlan_cfg_func_t; - typedef struct { int type; u32 seq_no; -- GitLab From bcddd48b7f1485abaf3a127c5de4d4da4a677ed5 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:20:01 +0900 Subject: [PATCH 0323/2855] staging: wilc1000: remove typedef from wilc_cfg_rsp_t This patch removes typedef from the struct wilc_cfg_rsp_t and renames it to wilc_cfg_rsp. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 2 +- drivers/staging/wilc1000/wilc_wlan.h | 4 ++-- drivers/staging/wilc1000/wilc_wlan_cfg.c | 2 +- drivers/staging/wilc1000/wilc_wlan_cfg.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index c61048b5c54e5..7b8e70b391cd3 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1023,7 +1023,7 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) has_packet = 1; } } else { - wilc_cfg_rsp_t rsp; + struct wilc_cfg_rsp rsp; wilc_wlan_cfg_indicate_rx(&buffer[pkt_offset + offset], pkt_len, &rsp); if (rsp.type == WILC_CFG_RSP) { diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 6c784fd591e6c..368b7ff3c4957 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -271,10 +271,10 @@ struct wilc_cfg_frame { u8 frame[MAX_CFG_FRAME_SIZE]; }; -typedef struct { +struct wilc_cfg_rsp { int type; u32 seq_no; -} wilc_cfg_rsp_t; +}; int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size); int wilc_wlan_start(void); diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.c b/drivers/staging/wilc1000/wilc_wlan_cfg.c index a34a81cdeb5e1..e23796392e9c1 100644 --- a/drivers/staging/wilc1000/wilc_wlan_cfg.c +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.c @@ -505,7 +505,7 @@ int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size) return ret; } -int wilc_wlan_cfg_indicate_rx(u8 *frame, int size, wilc_cfg_rsp_t *rsp) +int wilc_wlan_cfg_indicate_rx(u8 *frame, int size, struct wilc_cfg_rsp *rsp) { int ret = 1; u8 msg_type; diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.h b/drivers/staging/wilc1000/wilc_wlan_cfg.h index 30e60ec4d29f7..443b2d5b6db85 100644 --- a/drivers/staging/wilc1000/wilc_wlan_cfg.h +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.h @@ -33,7 +33,7 @@ typedef struct { int wilc_wlan_cfg_set_wid(u8 *frame, u32 offset, u16 id, u8 *buf, int size); int wilc_wlan_cfg_get_wid(u8 *frame, u32 offset, u16 id); int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size); -int wilc_wlan_cfg_indicate_rx(u8 *frame, int size, wilc_cfg_rsp_t *rsp); +int wilc_wlan_cfg_indicate_rx(u8 *frame, int size, struct wilc_cfg_rsp *rsp); int wilc_wlan_cfg_init(wilc_debug_func func); #endif -- GitLab From 48d0aa97996c3653a2e3dd6db742fa89f3f3139a Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:20:02 +0900 Subject: [PATCH 0324/2855] staging: wilc1000: remove typedef from wilc_hif_func_t This patch removes typedef from the struct wilc_hif_func_t and renames it to wilc_hif_func. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_sdio.c | 2 +- drivers/staging/wilc1000/wilc_spi.c | 2 +- drivers/staging/wilc1000/wilc_wlan.c | 10 +++++----- drivers/staging/wilc1000/wilc_wlan.h | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index 300c571e4e2d1..cfa76b26bb53a 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -992,7 +992,7 @@ static int sdio_sync_ext(int nint /* how mant interrupts to enable. */) * ********************************************/ -wilc_hif_func_t hif_sdio = { +struct wilc_hif_func hif_sdio = { sdio_init, sdio_deinit, sdio_read_reg, diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 599508beabf8b..b09b3bde68c20 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -1256,7 +1256,7 @@ static int spi_sync_ext(int nint /* how mant interrupts to enable. */) * Global spi HIF function table * ********************************************/ -wilc_hif_func_t hif_spi = { +struct wilc_hif_func hif_spi = { spi_init, spi_deinit, spi_read_reg, diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 7b8e70b391cd3..b6d784bcf98ef 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -2,14 +2,14 @@ #include "wilc_wfi_netdevice.h" #include "wilc_wlan_cfg.h" -extern wilc_hif_func_t hif_sdio; -extern wilc_hif_func_t hif_spi; +extern struct wilc_hif_func hif_sdio; +extern struct wilc_hif_func hif_spi; u32 wilc_get_chipid(u8 update); typedef struct { int quit; wilc_wlan_io_func_t io_func; - wilc_hif_func_t hif_func; + struct wilc_hif_func hif_func; int cfg_frame_in_use; struct wilc_cfg_frame cfg_frame; u32 cfg_frame_offset; @@ -1665,7 +1665,7 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) goto _fail_; } memcpy((void *)&g_wlan.hif_func, &hif_sdio, - sizeof(wilc_hif_func_t)); + sizeof(struct wilc_hif_func)); } else { if ((inp->io_func.io_type & 0x1) == HIF_SPI) { if (!hif_spi.hif_init(inp, wilc_debug)) { @@ -1673,7 +1673,7 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) goto _fail_; } memcpy((void *)&g_wlan.hif_func, &hif_spi, - sizeof(wilc_hif_func_t)); + sizeof(struct wilc_hif_func)); } else { ret = -EIO; goto _fail_; diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 368b7ff3c4957..ff4872f1e675d 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -236,7 +236,7 @@ struct rxq_entry_t { * ********************************************/ -typedef struct { +struct wilc_hif_func { int (*hif_init)(wilc_wlan_inp_t *, wilc_debug_func); int (*hif_deinit)(void *); int (*hif_read_reg)(u32, u32 *); @@ -253,7 +253,7 @@ typedef struct { int (*hif_sync_ext)(int); void (*hif_set_max_bus_speed)(void); void (*hif_set_default_bus_speed)(void); -} wilc_hif_func_t; +}; /******************************************** * -- GitLab From 3eec50cf1a64f7239ee296d8be7e97eca754fc72 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:20:03 +0900 Subject: [PATCH 0325/2855] staging: wilc1000: rename Handle_SetChannel function This patch renames Handle_SetChannel function to handle_set_channel to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 7014915e30d1e..16396e5604c6a 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -323,7 +323,7 @@ static struct host_if_drv *get_handler_from_id(int id) return wfidrv_list[id]; } -static s32 Handle_SetChannel(struct host_if_drv *hif_drv, +static s32 handle_set_channel(struct host_if_drv *hif_drv, struct channel_attr *hif_set_ch) { s32 result = 0; @@ -2893,7 +2893,7 @@ static int hostIFthread(void *pvArg) break; case HOST_IF_MSG_SET_CHANNEL: - Handle_SetChannel(msg.drv, &msg.body.channel_info); + handle_set_channel(msg.drv, &msg.body.channel_info); break; case HOST_IF_MSG_DISCONNECT: -- GitLab From 23f2badd265a0065bde78aa9510f77be5cbea313 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:20:04 +0900 Subject: [PATCH 0326/2855] staging: wilc1000: rename Handle_SetWfiDrvHandler function This patch renames Handle_SetWfiDrvHandler function to handle_set_wfi_drv_handler to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 16396e5604c6a..dcaf0eb782ac6 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -347,8 +347,8 @@ static s32 handle_set_channel(struct host_if_drv *hif_drv, return result; } -static s32 Handle_SetWfiDrvHandler(struct host_if_drv *hif_drv, - struct drv_handler *hif_drv_handler) +static s32 handle_set_wfi_drv_handler(struct host_if_drv *hif_drv, + struct drv_handler *hif_drv_handler) { s32 result = 0; struct wid wid; @@ -2970,8 +2970,7 @@ static int hostIFthread(void *pvArg) break; case HOST_IF_MSG_SET_WFIDRV_HANDLER: - Handle_SetWfiDrvHandler(msg.drv, - &msg.body.drv); + handle_set_wfi_drv_handler(msg.drv, &msg.body.drv); break; case HOST_IF_MSG_SET_OPERATION_MODE: -- GitLab From 97b5c59134328f197d86087b08671384c6ecd6ca Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:20:05 +0900 Subject: [PATCH 0327/2855] staging: wilc1000: rename Handle_SetOperationMode function This patch renames Handle_SetOperationMode function to handle_set_operation_mode to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index dcaf0eb782ac6..504763e07456d 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -371,8 +371,8 @@ static s32 handle_set_wfi_drv_handler(struct host_if_drv *hif_drv, return result; } -static s32 Handle_SetOperationMode(struct host_if_drv *hif_drv, - struct op_mode *hif_op_mode) +static s32 handle_set_operation_mode(struct host_if_drv *hif_drv, + struct op_mode *hif_op_mode) { s32 result = 0; struct wid wid; @@ -2974,7 +2974,7 @@ static int hostIFthread(void *pvArg) break; case HOST_IF_MSG_SET_OPERATION_MODE: - Handle_SetOperationMode(msg.drv, &msg.body.mode); + handle_set_operation_mode(msg.drv, &msg.body.mode); break; case HOST_IF_MSG_SET_IPADDRESS: -- GitLab From a6e6d48b888b9bba10e05d7bd457c518718b1e99 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:20:06 +0900 Subject: [PATCH 0328/2855] staging: wilc1000: rename Handle_set_IPAddress function This patch renames Handle_set_IPAddress function to handle_set_ip_address to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 504763e07456d..461272337dc92 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -396,7 +396,7 @@ static s32 handle_set_operation_mode(struct host_if_drv *hif_drv, return result; } -s32 Handle_set_IPAddress(struct host_if_drv *hif_drv, u8 *ip_addr, u8 idx) +s32 handle_set_ip_address(struct host_if_drv *hif_drv, u8 *ip_addr, u8 idx) { s32 result = 0; struct wid wid; @@ -2979,7 +2979,9 @@ static int hostIFthread(void *pvArg) case HOST_IF_MSG_SET_IPADDRESS: PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n"); - Handle_set_IPAddress(msg.drv, msg.body.ip_info.ip_addr, msg.body.ip_info.idx); + handle_set_ip_address(msg.drv, + msg.body.ip_info.ip_addr, + msg.body.ip_info.idx); break; case HOST_IF_MSG_GET_IPADDRESS: -- GitLab From d4516952e0ac5121db2c3d0a0633356031d186d9 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:20:07 +0900 Subject: [PATCH 0329/2855] staging: wilc1000: rename Handle_get_IPAddress function This patch renames Handle_get_IPAddress function to handle_get_ip_address to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 drivers/staging/wilc1000/host_interface.c diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c old mode 100644 new mode 100755 index 461272337dc92..9c4c0b2b899be --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -430,7 +430,7 @@ s32 handle_set_ip_address(struct host_if_drv *hif_drv, u8 *ip_addr, u8 idx) return result; } -s32 Handle_get_IPAddress(struct host_if_drv *hif_drv, u8 idx) +s32 handle_get_ip_address(struct host_if_drv *hif_drv, u8 idx) { s32 result = 0; struct wid wid; @@ -2986,7 +2986,7 @@ static int hostIFthread(void *pvArg) case HOST_IF_MSG_GET_IPADDRESS: PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n"); - Handle_get_IPAddress(msg.drv, msg.body.ip_info.idx); + handle_get_ip_address(msg.drv, msg.body.ip_info.idx); break; case HOST_IF_MSG_SET_MAC_ADDRESS: -- GitLab From a82674216547605540b77f9545ae83c6ff00146c Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:20:08 +0900 Subject: [PATCH 0330/2855] staging: wilc1000: rename Handle_SetMacAddress function This patch renames Handle_SetMacAddress function to handle_set_mac_address to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) mode change 100755 => 100644 drivers/staging/wilc1000/host_interface.c diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c old mode 100755 new mode 100644 index 9c4c0b2b899be..2388e2d1be8f3 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -464,8 +464,8 @@ s32 handle_get_ip_address(struct host_if_drv *hif_drv, u8 idx) return result; } -static s32 Handle_SetMacAddress(struct host_if_drv *hif_drv, - struct set_mac_addr *set_mac_addr) +static s32 handle_set_mac_address(struct host_if_drv *hif_drv, + struct set_mac_addr *set_mac_addr) { s32 result = 0; struct wid wid; @@ -2990,7 +2990,8 @@ static int hostIFthread(void *pvArg) break; case HOST_IF_MSG_SET_MAC_ADDRESS: - Handle_SetMacAddress(msg.drv, &msg.body.set_mac_info); + handle_set_mac_address(msg.drv, + &msg.body.set_mac_info); break; case HOST_IF_MSG_GET_MAC_ADDRESS: -- GitLab From b3bf8fd98494642871954e8c89a35c8959686236 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:20:09 +0900 Subject: [PATCH 0331/2855] staging: wilc1000: rename Handle_GetMacAddress function This patch renames Handle_GetMacAddress function to handle_get_mac_address to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) mode change 100644 => 100755 drivers/staging/wilc1000/host_interface.c diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c old mode 100644 new mode 100755 index 2388e2d1be8f3..cbc53bc9e98c8 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -494,8 +494,8 @@ static s32 handle_set_mac_address(struct host_if_drv *hif_drv, return result; } -static s32 Handle_GetMacAddress(struct host_if_drv *hif_drv, - struct get_mac_addr *get_mac_addr) +static s32 handle_get_mac_address(struct host_if_drv *hif_drv, + struct get_mac_addr *get_mac_addr) { s32 result = 0; struct wid wid; @@ -2995,7 +2995,8 @@ static int hostIFthread(void *pvArg) break; case HOST_IF_MSG_GET_MAC_ADDRESS: - Handle_GetMacAddress(msg.drv, &msg.body.get_mac_info); + handle_get_mac_address(msg.drv, + &msg.body.get_mac_info); break; case HOST_IF_MSG_REMAIN_ON_CHAN: -- GitLab From dc27666477e539881f49dc07bece967c0dff772d Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:20:10 +0900 Subject: [PATCH 0332/2855] staging: wilc1000: rename Handle_CfgParam function This patch renames Handle_CfgParam function to handle_cfg_param to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) mode change 100755 => 100644 drivers/staging/wilc1000/host_interface.c diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c old mode 100755 new mode 100644 index cbc53bc9e98c8..4c91ae26fa745 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -517,8 +517,8 @@ static s32 handle_get_mac_address(struct host_if_drv *hif_drv, return result; } -static s32 Handle_CfgParam(struct host_if_drv *hif_drv, - struct cfg_param_attr *cfg_param_attr) +static s32 handle_cfg_param(struct host_if_drv *hif_drv, + struct cfg_param_attr *cfg_param_attr) { s32 result = 0; struct wid strWIDList[32]; @@ -2888,8 +2888,7 @@ static int hostIFthread(void *pvArg) break; case HOST_IF_MSG_CFG_PARAMS: - - Handle_CfgParam(msg.drv, &msg.body.cfg_info); + handle_cfg_param(msg.drv, &msg.body.cfg_info); break; case HOST_IF_MSG_SET_CHANNEL: -- GitLab From 13ca52ad77dfba19a52a681391c276c9213668b9 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:20:11 +0900 Subject: [PATCH 0333/2855] staging: wilc1000: rename strWIDList of handle_cfg_param function This patch renames strWIDList variable of handle_cfg_param function to wid_list to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 149 +++++++++++----------- 1 file changed, 74 insertions(+), 75 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 4c91ae26fa745..588a027e44d83 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -521,7 +521,7 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, struct cfg_param_attr *cfg_param_attr) { s32 result = 0; - struct wid strWIDList[32]; + struct wid wid_list[32]; u8 u8WidCnt = 0; down(&hif_drv->sem_cfg_values); @@ -530,10 +530,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, if (cfg_param_attr->cfg_attr_info.flag & BSS_TYPE) { if (cfg_param_attr->cfg_attr_info.bss_type < 6) { - strWIDList[u8WidCnt].id = WID_BSS_TYPE; - strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.bss_type; - strWIDList[u8WidCnt].type = WID_CHAR; - strWIDList[u8WidCnt].size = sizeof(char); + wid_list[u8WidCnt].id = WID_BSS_TYPE; + wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.bss_type; + wid_list[u8WidCnt].type = WID_CHAR; + wid_list[u8WidCnt].size = sizeof(char); hif_drv->cfg_values.bss_type = (u8)cfg_param_attr->cfg_attr_info.bss_type; } else { PRINT_ER("check value 6 over\n"); @@ -546,10 +546,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, if (cfg_param_attr->cfg_attr_info.auth_type == 1 || cfg_param_attr->cfg_attr_info.auth_type == 2 || cfg_param_attr->cfg_attr_info.auth_type == 5) { - strWIDList[u8WidCnt].id = WID_AUTH_TYPE; - strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.auth_type; - strWIDList[u8WidCnt].type = WID_CHAR; - strWIDList[u8WidCnt].size = sizeof(char); + wid_list[u8WidCnt].id = WID_AUTH_TYPE; + wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.auth_type; + wid_list[u8WidCnt].type = WID_CHAR; + wid_list[u8WidCnt].size = sizeof(char); hif_drv->cfg_values.auth_type = (u8)cfg_param_attr->cfg_attr_info.auth_type; } else { PRINT_ER("Impossible value \n"); @@ -561,10 +561,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, if (cfg_param_attr->cfg_attr_info.flag & AUTHEN_TIMEOUT) { if (cfg_param_attr->cfg_attr_info.auth_timeout > 0 && cfg_param_attr->cfg_attr_info.auth_timeout < 65536) { - strWIDList[u8WidCnt].id = WID_AUTH_TIMEOUT; - strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.auth_timeout; - strWIDList[u8WidCnt].type = WID_SHORT; - strWIDList[u8WidCnt].size = sizeof(u16); + wid_list[u8WidCnt].id = WID_AUTH_TIMEOUT; + wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.auth_timeout; + wid_list[u8WidCnt].type = WID_SHORT; + wid_list[u8WidCnt].size = sizeof(u16); hif_drv->cfg_values.auth_timeout = cfg_param_attr->cfg_attr_info.auth_timeout; } else { PRINT_ER("Range(1 ~ 65535) over\n"); @@ -575,10 +575,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, } if (cfg_param_attr->cfg_attr_info.flag & POWER_MANAGEMENT) { if (cfg_param_attr->cfg_attr_info.power_mgmt_mode < 5) { - strWIDList[u8WidCnt].id = WID_POWER_MANAGEMENT; - strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.power_mgmt_mode; - strWIDList[u8WidCnt].type = WID_CHAR; - strWIDList[u8WidCnt].size = sizeof(char); + wid_list[u8WidCnt].id = WID_POWER_MANAGEMENT; + wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.power_mgmt_mode; + wid_list[u8WidCnt].type = WID_CHAR; + wid_list[u8WidCnt].size = sizeof(char); hif_drv->cfg_values.power_mgmt_mode = (u8)cfg_param_attr->cfg_attr_info.power_mgmt_mode; } else { PRINT_ER("Invalide power mode\n"); @@ -590,10 +590,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, if (cfg_param_attr->cfg_attr_info.flag & RETRY_SHORT) { if (cfg_param_attr->cfg_attr_info.short_retry_limit > 0 && cfg_param_attr->cfg_attr_info.short_retry_limit < 256) { - strWIDList[u8WidCnt].id = WID_SHORT_RETRY_LIMIT; - strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.short_retry_limit; - strWIDList[u8WidCnt].type = WID_SHORT; - strWIDList[u8WidCnt].size = sizeof(u16); + wid_list[u8WidCnt].id = WID_SHORT_RETRY_LIMIT; + wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.short_retry_limit; + wid_list[u8WidCnt].type = WID_SHORT; + wid_list[u8WidCnt].size = sizeof(u16); hif_drv->cfg_values.short_retry_limit = cfg_param_attr->cfg_attr_info.short_retry_limit; } else { PRINT_ER("Range(1~256) over\n"); @@ -605,11 +605,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, if (cfg_param_attr->cfg_attr_info.flag & RETRY_LONG) { if (cfg_param_attr->cfg_attr_info.long_retry_limit > 0 && cfg_param_attr->cfg_attr_info.long_retry_limit < 256) { - strWIDList[u8WidCnt].id = WID_LONG_RETRY_LIMIT; - strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.long_retry_limit; - - strWIDList[u8WidCnt].type = WID_SHORT; - strWIDList[u8WidCnt].size = sizeof(u16); + wid_list[u8WidCnt].id = WID_LONG_RETRY_LIMIT; + wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.long_retry_limit; + wid_list[u8WidCnt].type = WID_SHORT; + wid_list[u8WidCnt].size = sizeof(u16); hif_drv->cfg_values.long_retry_limit = cfg_param_attr->cfg_attr_info.long_retry_limit; } else { PRINT_ER("Range(1~256) over\n"); @@ -621,10 +620,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, if (cfg_param_attr->cfg_attr_info.flag & FRAG_THRESHOLD) { if (cfg_param_attr->cfg_attr_info.frag_threshold > 255 && cfg_param_attr->cfg_attr_info.frag_threshold < 7937) { - strWIDList[u8WidCnt].id = WID_FRAG_THRESHOLD; - strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.frag_threshold; - strWIDList[u8WidCnt].type = WID_SHORT; - strWIDList[u8WidCnt].size = sizeof(u16); + wid_list[u8WidCnt].id = WID_FRAG_THRESHOLD; + wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.frag_threshold; + wid_list[u8WidCnt].type = WID_SHORT; + wid_list[u8WidCnt].size = sizeof(u16); hif_drv->cfg_values.frag_threshold = cfg_param_attr->cfg_attr_info.frag_threshold; } else { PRINT_ER("Threshold Range fail\n"); @@ -636,10 +635,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, if (cfg_param_attr->cfg_attr_info.flag & RTS_THRESHOLD) { if (cfg_param_attr->cfg_attr_info.rts_threshold > 255 && cfg_param_attr->cfg_attr_info.rts_threshold < 65536) { - strWIDList[u8WidCnt].id = WID_RTS_THRESHOLD; - strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.rts_threshold; - strWIDList[u8WidCnt].type = WID_SHORT; - strWIDList[u8WidCnt].size = sizeof(u16); + wid_list[u8WidCnt].id = WID_RTS_THRESHOLD; + wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.rts_threshold; + wid_list[u8WidCnt].type = WID_SHORT; + wid_list[u8WidCnt].size = sizeof(u16); hif_drv->cfg_values.rts_threshold = cfg_param_attr->cfg_attr_info.rts_threshold; } else { PRINT_ER("Threshold Range fail\n"); @@ -650,10 +649,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, } if (cfg_param_attr->cfg_attr_info.flag & PREAMBLE) { if (cfg_param_attr->cfg_attr_info.preamble_type < 3) { - strWIDList[u8WidCnt].id = WID_PREAMBLE; - strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.preamble_type; - strWIDList[u8WidCnt].type = WID_CHAR; - strWIDList[u8WidCnt].size = sizeof(char); + wid_list[u8WidCnt].id = WID_PREAMBLE; + wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.preamble_type; + wid_list[u8WidCnt].type = WID_CHAR; + wid_list[u8WidCnt].size = sizeof(char); hif_drv->cfg_values.preamble_type = cfg_param_attr->cfg_attr_info.preamble_type; } else { PRINT_ER("Preamle Range(0~2) over\n"); @@ -664,10 +663,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, } if (cfg_param_attr->cfg_attr_info.flag & SHORT_SLOT_ALLOWED) { if (cfg_param_attr->cfg_attr_info.short_slot_allowed < 2) { - strWIDList[u8WidCnt].id = WID_SHORT_SLOT_ALLOWED; - strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.short_slot_allowed; - strWIDList[u8WidCnt].type = WID_CHAR; - strWIDList[u8WidCnt].size = sizeof(char); + wid_list[u8WidCnt].id = WID_SHORT_SLOT_ALLOWED; + wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.short_slot_allowed; + wid_list[u8WidCnt].type = WID_CHAR; + wid_list[u8WidCnt].size = sizeof(char); hif_drv->cfg_values.short_slot_allowed = (u8)cfg_param_attr->cfg_attr_info.short_slot_allowed; } else { PRINT_ER("Short slot(2) over\n"); @@ -678,10 +677,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, } if (cfg_param_attr->cfg_attr_info.flag & TXOP_PROT_DISABLE) { if (cfg_param_attr->cfg_attr_info.txop_prot_disabled < 2) { - strWIDList[u8WidCnt].id = WID_11N_TXOP_PROT_DISABLE; - strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.txop_prot_disabled; - strWIDList[u8WidCnt].type = WID_CHAR; - strWIDList[u8WidCnt].size = sizeof(char); + wid_list[u8WidCnt].id = WID_11N_TXOP_PROT_DISABLE; + wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.txop_prot_disabled; + wid_list[u8WidCnt].type = WID_CHAR; + wid_list[u8WidCnt].size = sizeof(char); hif_drv->cfg_values.txop_prot_disabled = (u8)cfg_param_attr->cfg_attr_info.txop_prot_disabled; } else { PRINT_ER("TXOP prot disable\n"); @@ -693,10 +692,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, if (cfg_param_attr->cfg_attr_info.flag & BEACON_INTERVAL) { if (cfg_param_attr->cfg_attr_info.beacon_interval > 0 && cfg_param_attr->cfg_attr_info.beacon_interval < 65536) { - strWIDList[u8WidCnt].id = WID_BEACON_INTERVAL; - strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.beacon_interval; - strWIDList[u8WidCnt].type = WID_SHORT; - strWIDList[u8WidCnt].size = sizeof(u16); + wid_list[u8WidCnt].id = WID_BEACON_INTERVAL; + wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.beacon_interval; + wid_list[u8WidCnt].type = WID_SHORT; + wid_list[u8WidCnt].size = sizeof(u16); hif_drv->cfg_values.beacon_interval = cfg_param_attr->cfg_attr_info.beacon_interval; } else { PRINT_ER("Beacon interval(1~65535) fail\n"); @@ -708,10 +707,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, if (cfg_param_attr->cfg_attr_info.flag & DTIM_PERIOD) { if (cfg_param_attr->cfg_attr_info.dtim_period > 0 && cfg_param_attr->cfg_attr_info.dtim_period < 256) { - strWIDList[u8WidCnt].id = WID_DTIM_PERIOD; - strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.dtim_period; - strWIDList[u8WidCnt].type = WID_CHAR; - strWIDList[u8WidCnt].size = sizeof(char); + wid_list[u8WidCnt].id = WID_DTIM_PERIOD; + wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.dtim_period; + wid_list[u8WidCnt].type = WID_CHAR; + wid_list[u8WidCnt].size = sizeof(char); hif_drv->cfg_values.dtim_period = cfg_param_attr->cfg_attr_info.dtim_period; } else { PRINT_ER("DTIM range(1~255) fail\n"); @@ -722,10 +721,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, } if (cfg_param_attr->cfg_attr_info.flag & SITE_SURVEY) { if (cfg_param_attr->cfg_attr_info.site_survey_enabled < 3) { - strWIDList[u8WidCnt].id = WID_SITE_SURVEY; - strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.site_survey_enabled; - strWIDList[u8WidCnt].type = WID_CHAR; - strWIDList[u8WidCnt].size = sizeof(char); + wid_list[u8WidCnt].id = WID_SITE_SURVEY; + wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.site_survey_enabled; + wid_list[u8WidCnt].type = WID_CHAR; + wid_list[u8WidCnt].size = sizeof(char); hif_drv->cfg_values.site_survey_enabled = (u8)cfg_param_attr->cfg_attr_info.site_survey_enabled; } else { PRINT_ER("Site survey disable\n"); @@ -737,10 +736,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, if (cfg_param_attr->cfg_attr_info.flag & SITE_SURVEY_SCAN_TIME) { if (cfg_param_attr->cfg_attr_info.site_survey_scan_time > 0 && cfg_param_attr->cfg_attr_info.site_survey_scan_time < 65536) { - strWIDList[u8WidCnt].id = WID_SITE_SURVEY_SCAN_TIME; - strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.site_survey_scan_time; - strWIDList[u8WidCnt].type = WID_SHORT; - strWIDList[u8WidCnt].size = sizeof(u16); + wid_list[u8WidCnt].id = WID_SITE_SURVEY_SCAN_TIME; + wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.site_survey_scan_time; + wid_list[u8WidCnt].type = WID_SHORT; + wid_list[u8WidCnt].size = sizeof(u16); hif_drv->cfg_values.site_survey_scan_time = cfg_param_attr->cfg_attr_info.site_survey_scan_time; } else { PRINT_ER("Site survey scan time(1~65535) over\n"); @@ -752,10 +751,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, if (cfg_param_attr->cfg_attr_info.flag & ACTIVE_SCANTIME) { if (cfg_param_attr->cfg_attr_info.active_scan_time > 0 && cfg_param_attr->cfg_attr_info.active_scan_time < 65536) { - strWIDList[u8WidCnt].id = WID_ACTIVE_SCAN_TIME; - strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.active_scan_time; - strWIDList[u8WidCnt].type = WID_SHORT; - strWIDList[u8WidCnt].size = sizeof(u16); + wid_list[u8WidCnt].id = WID_ACTIVE_SCAN_TIME; + wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.active_scan_time; + wid_list[u8WidCnt].type = WID_SHORT; + wid_list[u8WidCnt].size = sizeof(u16); hif_drv->cfg_values.active_scan_time = cfg_param_attr->cfg_attr_info.active_scan_time; } else { PRINT_ER("Active scan time(1~65535) over\n"); @@ -767,10 +766,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, if (cfg_param_attr->cfg_attr_info.flag & PASSIVE_SCANTIME) { if (cfg_param_attr->cfg_attr_info.passive_scan_time > 0 && cfg_param_attr->cfg_attr_info.passive_scan_time < 65536) { - strWIDList[u8WidCnt].id = WID_PASSIVE_SCAN_TIME; - strWIDList[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.passive_scan_time; - strWIDList[u8WidCnt].type = WID_SHORT; - strWIDList[u8WidCnt].size = sizeof(u16); + wid_list[u8WidCnt].id = WID_PASSIVE_SCAN_TIME; + wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.passive_scan_time; + wid_list[u8WidCnt].type = WID_SHORT; + wid_list[u8WidCnt].size = sizeof(u16); hif_drv->cfg_values.passive_scan_time = cfg_param_attr->cfg_attr_info.passive_scan_time; } else { PRINT_ER("Passive scan time(1~65535) over\n"); @@ -788,10 +787,10 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, || curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12 || curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24 || curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 || curr_tx_rate == MBPS_54) { - strWIDList[u8WidCnt].id = WID_CURRENT_TX_RATE; - strWIDList[u8WidCnt].val = (s8 *)&curr_tx_rate; - strWIDList[u8WidCnt].type = WID_SHORT; - strWIDList[u8WidCnt].size = sizeof(u16); + wid_list[u8WidCnt].id = WID_CURRENT_TX_RATE; + wid_list[u8WidCnt].val = (s8 *)&curr_tx_rate; + wid_list[u8WidCnt].type = WID_SHORT; + wid_list[u8WidCnt].size = sizeof(u16); hif_drv->cfg_values.curr_tx_rate = (u8)curr_tx_rate; } else { PRINT_ER("out of TX rate\n"); @@ -801,7 +800,7 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, u8WidCnt++; } - result = send_config_pkt(SET_CFG, strWIDList, u8WidCnt, + result = send_config_pkt(SET_CFG, wid_list, u8WidCnt, get_id_from_handler(hif_drv)); if (result) -- GitLab From 540c3e88ba5d06f64246e22f5b791d5ff5b97086 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 6 Nov 2015 11:20:12 +0900 Subject: [PATCH 0334/2855] staging: wilc1000: rename u8WidCnt of handle_cfg_param function This patch renames u8WidCnt variable of handle_cfg_param function to wid_cnt to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 184 +++++++++++----------- 1 file changed, 92 insertions(+), 92 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 588a027e44d83..1a334aec0eb71 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -522,7 +522,7 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, { s32 result = 0; struct wid wid_list[32]; - u8 u8WidCnt = 0; + u8 wid_cnt = 0; down(&hif_drv->sem_cfg_values); @@ -530,253 +530,253 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, if (cfg_param_attr->cfg_attr_info.flag & BSS_TYPE) { if (cfg_param_attr->cfg_attr_info.bss_type < 6) { - wid_list[u8WidCnt].id = WID_BSS_TYPE; - wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.bss_type; - wid_list[u8WidCnt].type = WID_CHAR; - wid_list[u8WidCnt].size = sizeof(char); + wid_list[wid_cnt].id = WID_BSS_TYPE; + wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.bss_type; + wid_list[wid_cnt].type = WID_CHAR; + wid_list[wid_cnt].size = sizeof(char); hif_drv->cfg_values.bss_type = (u8)cfg_param_attr->cfg_attr_info.bss_type; } else { PRINT_ER("check value 6 over\n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } if (cfg_param_attr->cfg_attr_info.flag & AUTH_TYPE) { if (cfg_param_attr->cfg_attr_info.auth_type == 1 || cfg_param_attr->cfg_attr_info.auth_type == 2 || cfg_param_attr->cfg_attr_info.auth_type == 5) { - wid_list[u8WidCnt].id = WID_AUTH_TYPE; - wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.auth_type; - wid_list[u8WidCnt].type = WID_CHAR; - wid_list[u8WidCnt].size = sizeof(char); + wid_list[wid_cnt].id = WID_AUTH_TYPE; + wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.auth_type; + wid_list[wid_cnt].type = WID_CHAR; + wid_list[wid_cnt].size = sizeof(char); hif_drv->cfg_values.auth_type = (u8)cfg_param_attr->cfg_attr_info.auth_type; } else { PRINT_ER("Impossible value \n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } if (cfg_param_attr->cfg_attr_info.flag & AUTHEN_TIMEOUT) { if (cfg_param_attr->cfg_attr_info.auth_timeout > 0 && cfg_param_attr->cfg_attr_info.auth_timeout < 65536) { - wid_list[u8WidCnt].id = WID_AUTH_TIMEOUT; - wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.auth_timeout; - wid_list[u8WidCnt].type = WID_SHORT; - wid_list[u8WidCnt].size = sizeof(u16); + wid_list[wid_cnt].id = WID_AUTH_TIMEOUT; + wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.auth_timeout; + wid_list[wid_cnt].type = WID_SHORT; + wid_list[wid_cnt].size = sizeof(u16); hif_drv->cfg_values.auth_timeout = cfg_param_attr->cfg_attr_info.auth_timeout; } else { PRINT_ER("Range(1 ~ 65535) over\n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } if (cfg_param_attr->cfg_attr_info.flag & POWER_MANAGEMENT) { if (cfg_param_attr->cfg_attr_info.power_mgmt_mode < 5) { - wid_list[u8WidCnt].id = WID_POWER_MANAGEMENT; - wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.power_mgmt_mode; - wid_list[u8WidCnt].type = WID_CHAR; - wid_list[u8WidCnt].size = sizeof(char); + wid_list[wid_cnt].id = WID_POWER_MANAGEMENT; + wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.power_mgmt_mode; + wid_list[wid_cnt].type = WID_CHAR; + wid_list[wid_cnt].size = sizeof(char); hif_drv->cfg_values.power_mgmt_mode = (u8)cfg_param_attr->cfg_attr_info.power_mgmt_mode; } else { PRINT_ER("Invalide power mode\n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } if (cfg_param_attr->cfg_attr_info.flag & RETRY_SHORT) { if (cfg_param_attr->cfg_attr_info.short_retry_limit > 0 && cfg_param_attr->cfg_attr_info.short_retry_limit < 256) { - wid_list[u8WidCnt].id = WID_SHORT_RETRY_LIMIT; - wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.short_retry_limit; - wid_list[u8WidCnt].type = WID_SHORT; - wid_list[u8WidCnt].size = sizeof(u16); + wid_list[wid_cnt].id = WID_SHORT_RETRY_LIMIT; + wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.short_retry_limit; + wid_list[wid_cnt].type = WID_SHORT; + wid_list[wid_cnt].size = sizeof(u16); hif_drv->cfg_values.short_retry_limit = cfg_param_attr->cfg_attr_info.short_retry_limit; } else { PRINT_ER("Range(1~256) over\n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } if (cfg_param_attr->cfg_attr_info.flag & RETRY_LONG) { if (cfg_param_attr->cfg_attr_info.long_retry_limit > 0 && cfg_param_attr->cfg_attr_info.long_retry_limit < 256) { - wid_list[u8WidCnt].id = WID_LONG_RETRY_LIMIT; - wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.long_retry_limit; - wid_list[u8WidCnt].type = WID_SHORT; - wid_list[u8WidCnt].size = sizeof(u16); + wid_list[wid_cnt].id = WID_LONG_RETRY_LIMIT; + wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.long_retry_limit; + wid_list[wid_cnt].type = WID_SHORT; + wid_list[wid_cnt].size = sizeof(u16); hif_drv->cfg_values.long_retry_limit = cfg_param_attr->cfg_attr_info.long_retry_limit; } else { PRINT_ER("Range(1~256) over\n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } if (cfg_param_attr->cfg_attr_info.flag & FRAG_THRESHOLD) { if (cfg_param_attr->cfg_attr_info.frag_threshold > 255 && cfg_param_attr->cfg_attr_info.frag_threshold < 7937) { - wid_list[u8WidCnt].id = WID_FRAG_THRESHOLD; - wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.frag_threshold; - wid_list[u8WidCnt].type = WID_SHORT; - wid_list[u8WidCnt].size = sizeof(u16); + wid_list[wid_cnt].id = WID_FRAG_THRESHOLD; + wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.frag_threshold; + wid_list[wid_cnt].type = WID_SHORT; + wid_list[wid_cnt].size = sizeof(u16); hif_drv->cfg_values.frag_threshold = cfg_param_attr->cfg_attr_info.frag_threshold; } else { PRINT_ER("Threshold Range fail\n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } if (cfg_param_attr->cfg_attr_info.flag & RTS_THRESHOLD) { if (cfg_param_attr->cfg_attr_info.rts_threshold > 255 && cfg_param_attr->cfg_attr_info.rts_threshold < 65536) { - wid_list[u8WidCnt].id = WID_RTS_THRESHOLD; - wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.rts_threshold; - wid_list[u8WidCnt].type = WID_SHORT; - wid_list[u8WidCnt].size = sizeof(u16); + wid_list[wid_cnt].id = WID_RTS_THRESHOLD; + wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.rts_threshold; + wid_list[wid_cnt].type = WID_SHORT; + wid_list[wid_cnt].size = sizeof(u16); hif_drv->cfg_values.rts_threshold = cfg_param_attr->cfg_attr_info.rts_threshold; } else { PRINT_ER("Threshold Range fail\n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } if (cfg_param_attr->cfg_attr_info.flag & PREAMBLE) { if (cfg_param_attr->cfg_attr_info.preamble_type < 3) { - wid_list[u8WidCnt].id = WID_PREAMBLE; - wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.preamble_type; - wid_list[u8WidCnt].type = WID_CHAR; - wid_list[u8WidCnt].size = sizeof(char); + wid_list[wid_cnt].id = WID_PREAMBLE; + wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.preamble_type; + wid_list[wid_cnt].type = WID_CHAR; + wid_list[wid_cnt].size = sizeof(char); hif_drv->cfg_values.preamble_type = cfg_param_attr->cfg_attr_info.preamble_type; } else { PRINT_ER("Preamle Range(0~2) over\n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } if (cfg_param_attr->cfg_attr_info.flag & SHORT_SLOT_ALLOWED) { if (cfg_param_attr->cfg_attr_info.short_slot_allowed < 2) { - wid_list[u8WidCnt].id = WID_SHORT_SLOT_ALLOWED; - wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.short_slot_allowed; - wid_list[u8WidCnt].type = WID_CHAR; - wid_list[u8WidCnt].size = sizeof(char); + wid_list[wid_cnt].id = WID_SHORT_SLOT_ALLOWED; + wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.short_slot_allowed; + wid_list[wid_cnt].type = WID_CHAR; + wid_list[wid_cnt].size = sizeof(char); hif_drv->cfg_values.short_slot_allowed = (u8)cfg_param_attr->cfg_attr_info.short_slot_allowed; } else { PRINT_ER("Short slot(2) over\n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } if (cfg_param_attr->cfg_attr_info.flag & TXOP_PROT_DISABLE) { if (cfg_param_attr->cfg_attr_info.txop_prot_disabled < 2) { - wid_list[u8WidCnt].id = WID_11N_TXOP_PROT_DISABLE; - wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.txop_prot_disabled; - wid_list[u8WidCnt].type = WID_CHAR; - wid_list[u8WidCnt].size = sizeof(char); + wid_list[wid_cnt].id = WID_11N_TXOP_PROT_DISABLE; + wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.txop_prot_disabled; + wid_list[wid_cnt].type = WID_CHAR; + wid_list[wid_cnt].size = sizeof(char); hif_drv->cfg_values.txop_prot_disabled = (u8)cfg_param_attr->cfg_attr_info.txop_prot_disabled; } else { PRINT_ER("TXOP prot disable\n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } if (cfg_param_attr->cfg_attr_info.flag & BEACON_INTERVAL) { if (cfg_param_attr->cfg_attr_info.beacon_interval > 0 && cfg_param_attr->cfg_attr_info.beacon_interval < 65536) { - wid_list[u8WidCnt].id = WID_BEACON_INTERVAL; - wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.beacon_interval; - wid_list[u8WidCnt].type = WID_SHORT; - wid_list[u8WidCnt].size = sizeof(u16); + wid_list[wid_cnt].id = WID_BEACON_INTERVAL; + wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.beacon_interval; + wid_list[wid_cnt].type = WID_SHORT; + wid_list[wid_cnt].size = sizeof(u16); hif_drv->cfg_values.beacon_interval = cfg_param_attr->cfg_attr_info.beacon_interval; } else { PRINT_ER("Beacon interval(1~65535) fail\n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } if (cfg_param_attr->cfg_attr_info.flag & DTIM_PERIOD) { if (cfg_param_attr->cfg_attr_info.dtim_period > 0 && cfg_param_attr->cfg_attr_info.dtim_period < 256) { - wid_list[u8WidCnt].id = WID_DTIM_PERIOD; - wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.dtim_period; - wid_list[u8WidCnt].type = WID_CHAR; - wid_list[u8WidCnt].size = sizeof(char); + wid_list[wid_cnt].id = WID_DTIM_PERIOD; + wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.dtim_period; + wid_list[wid_cnt].type = WID_CHAR; + wid_list[wid_cnt].size = sizeof(char); hif_drv->cfg_values.dtim_period = cfg_param_attr->cfg_attr_info.dtim_period; } else { PRINT_ER("DTIM range(1~255) fail\n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } if (cfg_param_attr->cfg_attr_info.flag & SITE_SURVEY) { if (cfg_param_attr->cfg_attr_info.site_survey_enabled < 3) { - wid_list[u8WidCnt].id = WID_SITE_SURVEY; - wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.site_survey_enabled; - wid_list[u8WidCnt].type = WID_CHAR; - wid_list[u8WidCnt].size = sizeof(char); + wid_list[wid_cnt].id = WID_SITE_SURVEY; + wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.site_survey_enabled; + wid_list[wid_cnt].type = WID_CHAR; + wid_list[wid_cnt].size = sizeof(char); hif_drv->cfg_values.site_survey_enabled = (u8)cfg_param_attr->cfg_attr_info.site_survey_enabled; } else { PRINT_ER("Site survey disable\n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } if (cfg_param_attr->cfg_attr_info.flag & SITE_SURVEY_SCAN_TIME) { if (cfg_param_attr->cfg_attr_info.site_survey_scan_time > 0 && cfg_param_attr->cfg_attr_info.site_survey_scan_time < 65536) { - wid_list[u8WidCnt].id = WID_SITE_SURVEY_SCAN_TIME; - wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.site_survey_scan_time; - wid_list[u8WidCnt].type = WID_SHORT; - wid_list[u8WidCnt].size = sizeof(u16); + wid_list[wid_cnt].id = WID_SITE_SURVEY_SCAN_TIME; + wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.site_survey_scan_time; + wid_list[wid_cnt].type = WID_SHORT; + wid_list[wid_cnt].size = sizeof(u16); hif_drv->cfg_values.site_survey_scan_time = cfg_param_attr->cfg_attr_info.site_survey_scan_time; } else { PRINT_ER("Site survey scan time(1~65535) over\n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } if (cfg_param_attr->cfg_attr_info.flag & ACTIVE_SCANTIME) { if (cfg_param_attr->cfg_attr_info.active_scan_time > 0 && cfg_param_attr->cfg_attr_info.active_scan_time < 65536) { - wid_list[u8WidCnt].id = WID_ACTIVE_SCAN_TIME; - wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.active_scan_time; - wid_list[u8WidCnt].type = WID_SHORT; - wid_list[u8WidCnt].size = sizeof(u16); + wid_list[wid_cnt].id = WID_ACTIVE_SCAN_TIME; + wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.active_scan_time; + wid_list[wid_cnt].type = WID_SHORT; + wid_list[wid_cnt].size = sizeof(u16); hif_drv->cfg_values.active_scan_time = cfg_param_attr->cfg_attr_info.active_scan_time; } else { PRINT_ER("Active scan time(1~65535) over\n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } if (cfg_param_attr->cfg_attr_info.flag & PASSIVE_SCANTIME) { if (cfg_param_attr->cfg_attr_info.passive_scan_time > 0 && cfg_param_attr->cfg_attr_info.passive_scan_time < 65536) { - wid_list[u8WidCnt].id = WID_PASSIVE_SCAN_TIME; - wid_list[u8WidCnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.passive_scan_time; - wid_list[u8WidCnt].type = WID_SHORT; - wid_list[u8WidCnt].size = sizeof(u16); + wid_list[wid_cnt].id = WID_PASSIVE_SCAN_TIME; + wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.passive_scan_time; + wid_list[wid_cnt].type = WID_SHORT; + wid_list[wid_cnt].size = sizeof(u16); hif_drv->cfg_values.passive_scan_time = cfg_param_attr->cfg_attr_info.passive_scan_time; } else { PRINT_ER("Passive scan time(1~65535) over\n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } if (cfg_param_attr->cfg_attr_info.flag & CURRENT_TX_RATE) { enum CURRENT_TXRATE curr_tx_rate = cfg_param_attr->cfg_attr_info.curr_tx_rate; @@ -787,20 +787,20 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, || curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12 || curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24 || curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 || curr_tx_rate == MBPS_54) { - wid_list[u8WidCnt].id = WID_CURRENT_TX_RATE; - wid_list[u8WidCnt].val = (s8 *)&curr_tx_rate; - wid_list[u8WidCnt].type = WID_SHORT; - wid_list[u8WidCnt].size = sizeof(u16); + wid_list[wid_cnt].id = WID_CURRENT_TX_RATE; + wid_list[wid_cnt].val = (s8 *)&curr_tx_rate; + wid_list[wid_cnt].type = WID_SHORT; + wid_list[wid_cnt].size = sizeof(u16); hif_drv->cfg_values.curr_tx_rate = (u8)curr_tx_rate; } else { PRINT_ER("out of TX rate\n"); result = -EINVAL; goto ERRORHANDLER; } - u8WidCnt++; + wid_cnt++; } - result = send_config_pkt(SET_CFG, wid_list, u8WidCnt, + result = send_config_pkt(SET_CFG, wid_list, wid_cnt, get_id_from_handler(hif_drv)); if (result) -- GitLab From cdb99231c4cb9ab3de2a0090a335d73b4ece0ea4 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:39:58 +0900 Subject: [PATCH 0335/2855] staging: wilc1000: separate hif_sdio and hif_spi into different module hif_sdio and hif_spi objects are compiled all the time even though one of SPI or SDIO is selected. This patch separates hif_sdio and hif_spi into different modules using ifdef define. After rework SPI and SDIO modules with only one hif interface, the define WILC_SDIO will be removed. This is first path of this series. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/Makefile | 6 ++--- drivers/staging/wilc1000/wilc_wlan.c | 36 +++++++++++++--------------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile index 64c2f1b83dfbe..650123df0b4c1 100644 --- a/drivers/staging/wilc1000/Makefile +++ b/drivers/staging/wilc1000/Makefile @@ -21,8 +21,8 @@ ccflags-$(CONFIG_WILC1000_DYNAMICALLY_ALLOCATE_MEMROY) += -DWILC_NORMAL_ALLOC wilc1000-objs := wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \ wilc_msgqueue.o \ coreconfigurator.o host_interface.o \ - wilc_sdio.o wilc_spi.o wilc_wlan_cfg.o wilc_debugfs.o \ + wilc_wlan_cfg.o wilc_debugfs.o \ wilc_wlan.o -wilc1000-$(CONFIG_WILC1000_SDIO) += linux_wlan_sdio.o -wilc1000-$(CONFIG_WILC1000_SPI) += linux_wlan_spi.o +wilc1000-$(CONFIG_WILC1000_SDIO) += linux_wlan_sdio.o wilc_sdio.o +wilc1000-$(CONFIG_WILC1000_SPI) += linux_wlan_spi.o wilc_spi.o diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index b6d784bcf98ef..2ce58702d705a 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -2,8 +2,11 @@ #include "wilc_wfi_netdevice.h" #include "wilc_wlan_cfg.h" +#ifdef WILC_SDIO extern struct wilc_hif_func hif_sdio; +#else extern struct wilc_hif_func hif_spi; +#endif u32 wilc_get_chipid(u8 update); typedef struct { @@ -1659,26 +1662,21 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) memcpy((void *)&g_wlan.io_func, (void *)&inp->io_func, sizeof(wilc_wlan_io_func_t)); - if ((inp->io_func.io_type & 0x1) == HIF_SDIO) { - if (!hif_sdio.hif_init(inp, wilc_debug)) { - ret = -EIO; - goto _fail_; - } - memcpy((void *)&g_wlan.hif_func, &hif_sdio, - sizeof(struct wilc_hif_func)); - } else { - if ((inp->io_func.io_type & 0x1) == HIF_SPI) { - if (!hif_spi.hif_init(inp, wilc_debug)) { - ret = -EIO; - goto _fail_; - } - memcpy((void *)&g_wlan.hif_func, &hif_spi, - sizeof(struct wilc_hif_func)); - } else { - ret = -EIO; - goto _fail_; - } +#ifdef WILC_SDIO + if (!hif_sdio.hif_init(inp, wilc_debug)) { + ret = -EIO; + goto _fail_; } + memcpy((void *)&g_wlan.hif_func, &hif_sdio, + sizeof(struct wilc_hif_func)); +#else + if (!hif_spi.hif_init(inp, wilc_debug)) { + ret = -EIO; + goto _fail_; + } + memcpy((void *)&g_wlan.hif_func, &hif_spi, + sizeof(struct wilc_hif_func)); +#endif if (!wilc_wlan_cfg_init(wilc_debug)) { ret = -ENOBUFS; -- GitLab From 3ff2ac2c042bf23a6ad520fb483c5d3f89c3e1d0 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:39:59 +0900 Subject: [PATCH 0336/2855] staging: wilc1000: remove function pointer sdio_cmd52 This patch removes function pointer sdio_cmd52 of wilc_sdio_t and just call the function directly. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_sdio.c | 53 ++++++++++++++-------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index cfa76b26bb53a..a2d631882fde1 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -10,13 +10,13 @@ #include #include "wilc_wlan_if.h" #include "wilc_wlan.h" +#include "linux_wlan_sdio.h" #define WILC_SDIO_BLOCK_SIZE 512 typedef struct { void *os_context; u32 block_size; - int (*sdio_cmd52)(sdio_cmd52_t *); int (*sdio_cmd53)(sdio_cmd53_t *); int (*sdio_set_max_speed)(void); int (*sdio_set_default_speed)(void); @@ -51,21 +51,21 @@ static int sdio_set_func0_csa_address(u32 adr) cmd.raw = 0; cmd.address = 0x10c; cmd.data = (u8)adr; - if (!g_sdio.sdio_cmd52(&cmd)) { + if (!linux_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10c data...\n"); goto _fail_; } cmd.address = 0x10d; cmd.data = (u8)(adr >> 8); - if (!g_sdio.sdio_cmd52(&cmd)) { + if (!linux_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10d data...\n"); goto _fail_; } cmd.address = 0x10e; cmd.data = (u8)(adr >> 16); - if (!g_sdio.sdio_cmd52(&cmd)) { + if (!linux_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10e data...\n"); goto _fail_; } @@ -84,14 +84,14 @@ static int sdio_set_func0_block_size(u32 block_size) cmd.raw = 0; cmd.address = 0x10; cmd.data = (u8)block_size; - if (!g_sdio.sdio_cmd52(&cmd)) { + if (!linux_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10 data...\n"); goto _fail_; } cmd.address = 0x11; cmd.data = (u8)(block_size >> 8); - if (!g_sdio.sdio_cmd52(&cmd)) { + if (!linux_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x11 data...\n"); goto _fail_; } @@ -116,13 +116,13 @@ static int sdio_set_func1_block_size(u32 block_size) cmd.raw = 0; cmd.address = 0x110; cmd.data = (u8)block_size; - if (!g_sdio.sdio_cmd52(&cmd)) { + if (!linux_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x110 data...\n"); goto _fail_; } cmd.address = 0x111; cmd.data = (u8)(block_size >> 8); - if (!g_sdio.sdio_cmd52(&cmd)) { + if (!linux_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x111 data...\n"); goto _fail_; } @@ -143,7 +143,7 @@ static int sdio_clear_int(void) cmd.raw = 0; cmd.address = 0x4; cmd.data = 0; - g_sdio.sdio_cmd52(&cmd); + linux_sdio_cmd52(&cmd); return cmd.data; #else @@ -170,7 +170,7 @@ u32 sdio_xfer_cnt(void) cmd.raw = 0; cmd.address = 0x1C; cmd.data = 0; - g_sdio.sdio_cmd52(&cmd); + linux_sdio_cmd52(&cmd); cnt = cmd.data; cmd.read_write = 0; @@ -178,7 +178,7 @@ u32 sdio_xfer_cnt(void) cmd.raw = 0; cmd.address = 0x1D; cmd.data = 0; - g_sdio.sdio_cmd52(&cmd); + linux_sdio_cmd52(&cmd); cnt |= (cmd.data << 8); cmd.read_write = 0; @@ -186,7 +186,7 @@ u32 sdio_xfer_cnt(void) cmd.raw = 0; cmd.address = 0x1E; cmd.data = 0; - g_sdio.sdio_cmd52(&cmd); + linux_sdio_cmd52(&cmd); cnt |= (cmd.data << 16); return cnt; @@ -209,7 +209,7 @@ int sdio_check_bs(void) cmd.raw = 0; cmd.address = 0xc; cmd.data = 0; - if (!g_sdio.sdio_cmd52(&cmd)) { + if (!linux_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get BS register...\n"); goto _fail_; } @@ -235,7 +235,7 @@ static int sdio_write_reg(u32 addr, u32 data) cmd.raw = 0; cmd.address = addr; cmd.data = data; - if (!g_sdio.sdio_cmd52(&cmd)) { + if (!linux_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr); goto _fail_; } @@ -363,7 +363,7 @@ static int sdio_read_reg(u32 addr, u32 *data) cmd.function = 0; cmd.raw = 0; cmd.address = addr; - if (!g_sdio.sdio_cmd52(&cmd)) { + if (!linux_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr); goto _fail_; } @@ -574,7 +574,6 @@ static int sdio_init(wilc_wlan_inp_t *inp, wilc_debug_func func) return 0; } - g_sdio.sdio_cmd52 = inp->io_func.u.sdio.sdio_cmd52; g_sdio.sdio_cmd53 = inp->io_func.u.sdio.sdio_cmd53; g_sdio.sdio_set_max_speed = inp->io_func.u.sdio.sdio_set_max_speed; g_sdio.sdio_set_default_speed = inp->io_func.u.sdio.sdio_set_default_speed; @@ -587,7 +586,7 @@ static int sdio_init(wilc_wlan_inp_t *inp, wilc_debug_func func) cmd.raw = 1; cmd.address = 0x100; cmd.data = 0x80; - if (!g_sdio.sdio_cmd52(&cmd)) { + if (!linux_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, enable csa...\n"); goto _fail_; } @@ -609,7 +608,7 @@ static int sdio_init(wilc_wlan_inp_t *inp, wilc_debug_func func) cmd.raw = 1; cmd.address = 0x2; cmd.data = 0x2; - if (!g_sdio.sdio_cmd52(&cmd)) { + if (!linux_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio] Fail cmd 52, set IOE register...\n"); goto _fail_; } @@ -624,7 +623,7 @@ static int sdio_init(wilc_wlan_inp_t *inp, wilc_debug_func func) loop = 3; do { cmd.data = 0; - if (!g_sdio.sdio_cmd52(&cmd)) { + if (!linux_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get IOR register...\n"); goto _fail_; } @@ -653,7 +652,7 @@ static int sdio_init(wilc_wlan_inp_t *inp, wilc_debug_func func) cmd.raw = 1; cmd.address = 0x4; cmd.data = 0x3; - if (!g_sdio.sdio_cmd52(&cmd)) { + if (!linux_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set IEN register...\n"); goto _fail_; } @@ -703,7 +702,7 @@ static int sdio_read_size(u32 *size) cmd.raw = 0; cmd.address = 0xf2; cmd.data = 0; - g_sdio.sdio_cmd52(&cmd); + linux_sdio_cmd52(&cmd); tmp = cmd.data; /* cmd.read_write = 0; */ @@ -711,7 +710,7 @@ static int sdio_read_size(u32 *size) /* cmd.raw = 0; */ cmd.address = 0xf3; cmd.data = 0; - g_sdio.sdio_cmd52(&cmd); + linux_sdio_cmd52(&cmd); tmp |= (cmd.data << 8); *size = tmp; @@ -733,7 +732,7 @@ static int sdio_read_int(u32 *int_status) cmd.function = 1; cmd.address = 0x04; cmd.data = 0; - g_sdio.sdio_cmd52(&cmd); + linux_sdio_cmd52(&cmd); if (cmd.data & BIT(0)) tmp |= INT_0; @@ -766,7 +765,7 @@ static int sdio_read_int(u32 *int_status) cmd.raw = 0; cmd.address = 0xf7; cmd.data = 0; - g_sdio.sdio_cmd52(&cmd); + linux_sdio_cmd52(&cmd); irq_flags = cmd.data & 0x1f; tmp |= ((irq_flags >> 0) << IRG_FLAGS_OFFSET); } @@ -813,7 +812,7 @@ static int sdio_clear_int_ext(u32 val) cmd.address = 0xf8; cmd.data = reg; - ret = g_sdio.sdio_cmd52(&cmd); + ret = linux_sdio_cmd52(&cmd); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__); goto _fail_; @@ -842,7 +841,7 @@ static int sdio_clear_int_ext(u32 val) cmd.address = 0xf8; cmd.data = BIT(i); - ret = g_sdio.sdio_cmd52(&cmd); + ret = linux_sdio_cmd52(&cmd); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__); goto _fail_; @@ -886,7 +885,7 @@ static int sdio_clear_int_ext(u32 val) cmd.raw = 0; cmd.address = 0xf6; cmd.data = vmm_ctl; - ret = g_sdio.sdio_cmd52(&cmd); + ret = linux_sdio_cmd52(&cmd); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf6 data (%d) ...\n", __LINE__); goto _fail_; -- GitLab From b2882ab32bd33280739b7c294a7567f45523e95d Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:00 +0900 Subject: [PATCH 0337/2855] staging: wilc1000: remove sdio_cmd52 of wilc_wlan_io_func_t This patch removes sdio_cmd52 of wilc_wlan_io_func_t which is not used. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 1 - drivers/staging/wilc1000/wilc_wlan_if.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index c94cb1362a55b..ce5463e44e61f 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -894,7 +894,6 @@ void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic) nwi->io_func.io_type = HIF_SDIO; nwi->io_func.io_init = linux_sdio_init; nwi->io_func.io_deinit = linux_sdio_deinit; - nwi->io_func.u.sdio.sdio_cmd52 = linux_sdio_cmd52; nwi->io_func.u.sdio.sdio_cmd53 = linux_sdio_cmd53; nwi->io_func.u.sdio.sdio_set_max_speed = linux_sdio_set_max_speed; nwi->io_func.u.sdio.sdio_set_default_speed = linux_sdio_set_default_speed; diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index 12cbc4bcac90b..cd83098314dc9 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -78,7 +78,6 @@ typedef struct { void (*io_deinit)(void *); union { struct { - int (*sdio_cmd52)(sdio_cmd52_t *); int (*sdio_cmd53)(sdio_cmd53_t *); int (*sdio_set_max_speed)(void); int (*sdio_set_default_speed)(void); -- GitLab From a960936efb4401df773f667e482d2c483ebda826 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:01 +0900 Subject: [PATCH 0338/2855] staging: wilc1000: remove function pointer sdio_cmd53 This patch removes function pointer sdio_cmd53 of wilc_sdio_t and just call the function directly. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_sdio.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index a2d631882fde1..1176946d07d66 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -17,7 +17,6 @@ typedef struct { void *os_context; u32 block_size; - int (*sdio_cmd53)(sdio_cmd53_t *); int (*sdio_set_max_speed)(void); int (*sdio_set_default_speed)(void); wilc_debug_func dPrint; @@ -257,7 +256,7 @@ static int sdio_write_reg(u32 addr, u32 data) cmd.buffer = (u8 *)&data; cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */ - if (!g_sdio.sdio_cmd53(&cmd)) { + if (!linux_sdio_cmd53(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, write reg (%08x)...\n", addr); goto _fail_; } @@ -320,7 +319,7 @@ static int sdio_write(u32 addr, u8 *buf, u32 size) if (!sdio_set_func0_csa_address(addr)) goto _fail_; } - if (!g_sdio.sdio_cmd53(&cmd)) { + if (!linux_sdio_cmd53(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block send...\n", addr); goto _fail_; } @@ -341,7 +340,7 @@ static int sdio_write(u32 addr, u8 *buf, u32 size) if (!sdio_set_func0_csa_address(addr)) goto _fail_; } - if (!g_sdio.sdio_cmd53(&cmd)) { + if (!linux_sdio_cmd53(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes send...\n", addr); goto _fail_; } @@ -384,7 +383,7 @@ static int sdio_read_reg(u32 addr, u32 *data) cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */ - if (!g_sdio.sdio_cmd53(&cmd)) { + if (!linux_sdio_cmd53(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, read reg (%08x)...\n", addr); goto _fail_; } @@ -451,7 +450,7 @@ static int sdio_read(u32 addr, u8 *buf, u32 size) if (!sdio_set_func0_csa_address(addr)) goto _fail_; } - if (!g_sdio.sdio_cmd53(&cmd)) { + if (!linux_sdio_cmd53(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block read...\n", addr); goto _fail_; } @@ -472,7 +471,7 @@ static int sdio_read(u32 addr, u8 *buf, u32 size) if (!sdio_set_func0_csa_address(addr)) goto _fail_; } - if (!g_sdio.sdio_cmd53(&cmd)) { + if (!linux_sdio_cmd53(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes read...\n", addr); goto _fail_; } @@ -574,7 +573,6 @@ static int sdio_init(wilc_wlan_inp_t *inp, wilc_debug_func func) return 0; } - g_sdio.sdio_cmd53 = inp->io_func.u.sdio.sdio_cmd53; g_sdio.sdio_set_max_speed = inp->io_func.u.sdio.sdio_set_max_speed; g_sdio.sdio_set_default_speed = inp->io_func.u.sdio.sdio_set_default_speed; -- GitLab From 2d6151782d6cc41b25fbec6607e23daaa34ce24b Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:02 +0900 Subject: [PATCH 0339/2855] staging: wilc1000: remove sdio_cmd53 of wilc_wlan_io_func_t This patch removes sdio_cmd53 of wilc_wlan_io_func_t which is not used. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 1 - drivers/staging/wilc1000/wilc_wlan_if.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index ce5463e44e61f..725831395395c 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -894,7 +894,6 @@ void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic) nwi->io_func.io_type = HIF_SDIO; nwi->io_func.io_init = linux_sdio_init; nwi->io_func.io_deinit = linux_sdio_deinit; - nwi->io_func.u.sdio.sdio_cmd53 = linux_sdio_cmd53; nwi->io_func.u.sdio.sdio_set_max_speed = linux_sdio_set_max_speed; nwi->io_func.u.sdio.sdio_set_default_speed = linux_sdio_set_default_speed; #else diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index cd83098314dc9..92cee45766126 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -78,7 +78,6 @@ typedef struct { void (*io_deinit)(void *); union { struct { - int (*sdio_cmd53)(sdio_cmd53_t *); int (*sdio_set_max_speed)(void); int (*sdio_set_default_speed)(void); } sdio; -- GitLab From 78d2f1a4b50c6460e9b82179ec301773b5757acb Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:03 +0900 Subject: [PATCH 0340/2855] staging: wilc1000: remove function pointer sdio_set_max_speed This patch removes function pointer sdio_set_max_speed of wilc_sdio_t and call the function directly. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_sdio.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index 1176946d07d66..0ce2eccb36182 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -17,7 +17,6 @@ typedef struct { void *os_context; u32 block_size; - int (*sdio_set_max_speed)(void); int (*sdio_set_default_speed)(void); wilc_debug_func dPrint; int nint; @@ -573,7 +572,6 @@ static int sdio_init(wilc_wlan_inp_t *inp, wilc_debug_func func) return 0; } - g_sdio.sdio_set_max_speed = inp->io_func.u.sdio.sdio_set_max_speed; g_sdio.sdio_set_default_speed = inp->io_func.u.sdio.sdio_set_default_speed; /** @@ -678,7 +676,7 @@ _fail_: static void sdio_set_max_speed(void) { - g_sdio.sdio_set_max_speed(); + linux_sdio_set_max_speed(); } static void sdio_set_default_speed(void) -- GitLab From f15179eb1f77b1b991273d5229b676ac630be1c0 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:04 +0900 Subject: [PATCH 0341/2855] staging: wilc1000: remove sdio_set_max_speed This patch removes sdio_set_max_speed of wilc_wlan_io_func_t which is not used any more. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 1 - drivers/staging/wilc1000/wilc_wlan_if.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 725831395395c..9ecf307758524 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -894,7 +894,6 @@ void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic) nwi->io_func.io_type = HIF_SDIO; nwi->io_func.io_init = linux_sdio_init; nwi->io_func.io_deinit = linux_sdio_deinit; - nwi->io_func.u.sdio.sdio_set_max_speed = linux_sdio_set_max_speed; nwi->io_func.u.sdio.sdio_set_default_speed = linux_sdio_set_default_speed; #else nwi->io_func.io_type = HIF_SPI; diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index 92cee45766126..2caad2883b193 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -78,7 +78,6 @@ typedef struct { void (*io_deinit)(void *); union { struct { - int (*sdio_set_max_speed)(void); int (*sdio_set_default_speed)(void); } sdio; struct { -- GitLab From 544827f3807f8165f2736d4b3fbe89a33754b05e Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:05 +0900 Subject: [PATCH 0342/2855] staging: wilc1000: remove function pointer sdio_set_default_speed This patch removes function pointer sdio_set_default_speed of wilc_sdio_t and call linux_sdio_set_default_speed() directly. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_sdio.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index 0ce2eccb36182..6f488395e1b3f 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -17,7 +17,6 @@ typedef struct { void *os_context; u32 block_size; - int (*sdio_set_default_speed)(void); wilc_debug_func dPrint; int nint; #define MAX_NUN_INT_THRPT_ENH2 (5) /* Max num interrupts allowed in registers 0xf7, 0xf8 */ @@ -572,8 +571,6 @@ static int sdio_init(wilc_wlan_inp_t *inp, wilc_debug_func func) return 0; } - g_sdio.sdio_set_default_speed = inp->io_func.u.sdio.sdio_set_default_speed; - /** * function 0 csa enable **/ @@ -681,7 +678,7 @@ static void sdio_set_max_speed(void) static void sdio_set_default_speed(void) { - g_sdio.sdio_set_default_speed(); + linux_sdio_set_default_speed(); } static int sdio_read_size(u32 *size) -- GitLab From 1c2cf24ce5fde01316bfaa0b03711651ab1a71bf Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:06 +0900 Subject: [PATCH 0343/2855] staging: wilc1000: remove varialbe sdio_set_default_speed This patch removes sdio_set_default_speed of wilc_wlan_io_func_t which is not used anymore and also remove struct sdio since it is empty. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 1 - drivers/staging/wilc1000/wilc_wlan_if.h | 3 --- 2 files changed, 4 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 9ecf307758524..b37ef4d029436 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -894,7 +894,6 @@ void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic) nwi->io_func.io_type = HIF_SDIO; nwi->io_func.io_init = linux_sdio_init; nwi->io_func.io_deinit = linux_sdio_deinit; - nwi->io_func.u.sdio.sdio_set_default_speed = linux_sdio_set_default_speed; #else nwi->io_func.io_type = HIF_SPI; nwi->io_func.io_init = linux_spi_init; diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index 2caad2883b193..4568457d98200 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -77,9 +77,6 @@ typedef struct { int (*io_init)(void *); void (*io_deinit)(void *); union { - struct { - int (*sdio_set_default_speed)(void); - } sdio; struct { int (*spi_max_speed)(void); int (*spi_tx)(u8 *, u32); -- GitLab From de11ee8b214e26aebe07729629246ef893d056cb Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:07 +0900 Subject: [PATCH 0344/2855] staging: wilc1000: call linux_sdio_init instead of io_init Just call linux_sdio_init instead of io_init function pointer. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_sdio.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index 6f488395e1b3f..0d88b6e46a023 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -562,11 +562,9 @@ static int sdio_init(wilc_wlan_inp_t *inp, wilc_debug_func func) g_sdio.dPrint = func; g_sdio.os_context = inp->os_context.os_private; - if (inp->io_func.io_init) { - if (!inp->io_func.io_init(g_sdio.os_context)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed io init bus...\n"); - return 0; - } + if (!linux_sdio_init(g_sdio.os_context)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed io init bus...\n"); + return 0; } else { return 0; } -- GitLab From d4a7344b77c96748ca91368355f138de4e370879 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:08 +0900 Subject: [PATCH 0345/2855] staging: wilc1000: wilc_spi.c: add prefix wilc in all function name This patch add prefix wilc for all functions name because the function name such as spi_write, spi_read and spi_sync are same as linux spi function. Hence, this should be done before restructuring wilc_spi.c and linux_wlan_spi.c later. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_spi.c | 108 ++++++++++++++-------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index b09b3bde68c20..946bda77827f1 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -25,8 +25,8 @@ typedef struct { static wilc_spi_t g_spi; -static int spi_read(u32, u8 *, u32); -static int spi_write(u32, u8 *, u32); +static int wilc_spi_read(u32, u8 *, u32); +static int wilc_spi_write(u32, u8 *, u32); /******************************************** * @@ -790,7 +790,7 @@ static int spi_internal_read(u32 adr, u32 *data) * ********************************************/ -static int spi_write_reg(u32 addr, u32 data) +static int wilc_spi_write_reg(u32 addr, u32 data) { int result = N_OK; u8 cmd = CMD_SINGLE_WRITE; @@ -813,7 +813,7 @@ static int spi_write_reg(u32 addr, u32 data) return result; } -static int spi_write(u32 addr, u8 *buf, u32 size) +static int wilc_spi_write(u32 addr, u8 *buf, u32 size) { int result; u8 cmd = CMD_DMA_EXT_WRITE; @@ -841,7 +841,7 @@ static int spi_write(u32 addr, u8 *buf, u32 size) return 1; } -static int spi_read_reg(u32 addr, u32 *data) +static int wilc_spi_read_reg(u32 addr, u32 *data) { int result = N_OK; u8 cmd = CMD_SINGLE_READ; @@ -867,7 +867,7 @@ static int spi_read_reg(u32 addr, u32 *data) return 1; } -static int spi_read(u32 addr, u8 *buf, u32 size) +static int wilc_spi_read(u32 addr, u8 *buf, u32 size) { u8 cmd = CMD_DMA_EXT_READ; int result; @@ -890,20 +890,20 @@ static int spi_read(u32 addr, u8 *buf, u32 size) * ********************************************/ -static int spi_clear_int(void) +static int wilc_spi_clear_int(void) { u32 reg; - if (!spi_read_reg(WILC_HOST_RX_CTRL_0, ®)) { + if (!wilc_spi_read_reg(WILC_HOST_RX_CTRL_0, ®)) { PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0); return 0; } reg &= ~0x1; - spi_write_reg(WILC_HOST_RX_CTRL_0, reg); + wilc_spi_write_reg(WILC_HOST_RX_CTRL_0, reg); return 1; } -static int spi_deinit(void *pv) +static int wilc_spi_deinit(void *pv) { /** * TODO: @@ -911,7 +911,7 @@ static int spi_deinit(void *pv) return 1; } -static int spi_sync(void) +static int wilc_spi_sync(void) { u32 reg; int ret; @@ -919,13 +919,13 @@ static int spi_sync(void) /** * interrupt pin mux select **/ - ret = spi_read_reg(WILC_PIN_MUX_0, ®); + ret = wilc_spi_read_reg(WILC_PIN_MUX_0, ®); if (!ret) { PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); return 0; } reg |= BIT(8); - ret = spi_write_reg(WILC_PIN_MUX_0, reg); + ret = wilc_spi_write_reg(WILC_PIN_MUX_0, reg); if (!ret) { PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); return 0; @@ -934,13 +934,13 @@ static int spi_sync(void) /** * interrupt enable **/ - ret = spi_read_reg(WILC_INTR_ENABLE, ®); + ret = wilc_spi_read_reg(WILC_INTR_ENABLE, ®); if (!ret) { PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); return 0; } reg |= BIT(16); - ret = spi_write_reg(WILC_INTR_ENABLE, reg); + ret = wilc_spi_write_reg(WILC_INTR_ENABLE, reg); if (!ret) { PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); return 0; @@ -949,7 +949,7 @@ static int spi_sync(void) return 1; } -static int spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func) +static int wilc_spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func) { u32 reg; u32 chipid; @@ -958,7 +958,7 @@ static int spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func) if (isinit) { - if (!spi_read_reg(0x1000, &chipid)) { + if (!wilc_spi_read_reg(0x1000, &chipid)) { PRINT_ER("[wilc spi]: Fail cmd read chip id...\n"); return 0; } @@ -1015,7 +1015,7 @@ static int spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func) /** * make sure can read back chip id correctly **/ - if (!spi_read_reg(0x1000, &chipid)) { + if (!wilc_spi_read_reg(0x1000, &chipid)) { PRINT_ER("[wilc spi]: Fail cmd read chip id...\n"); return 0; } @@ -1028,16 +1028,16 @@ static int spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func) return 1; } -static void spi_max_bus_speed(void) +static void wilc_spi_max_bus_speed(void) { g_spi.spi_max_speed(); } -static void spi_default_bus_speed(void) +static void wilc_spi_default_bus_speed(void) { } -static int spi_read_size(u32 *size) +static int wilc_spi_read_size(u32 *size) { int ret; @@ -1048,7 +1048,7 @@ static int spi_read_size(u32 *size) u32 tmp; u32 byte_cnt; - ret = spi_read_reg(WILC_VMM_TO_HOST_SIZE, &byte_cnt); + ret = wilc_spi_read_reg(WILC_VMM_TO_HOST_SIZE, &byte_cnt); if (!ret) { PRINT_ER("[wilc spi]: Failed read WILC_VMM_TO_HOST_SIZE ...\n"); goto _fail_; @@ -1065,7 +1065,7 @@ _fail_: -static int spi_read_int(u32 *int_status) +static int wilc_spi_read_int(u32 *int_status) { int ret; @@ -1075,7 +1075,7 @@ static int spi_read_int(u32 *int_status) u32 tmp; u32 byte_cnt; - ret = spi_read_reg(WILC_VMM_TO_HOST_SIZE, &byte_cnt); + ret = wilc_spi_read_reg(WILC_VMM_TO_HOST_SIZE, &byte_cnt); if (!ret) { PRINT_ER("[wilc spi]: Failed read WILC_VMM_TO_HOST_SIZE ...\n"); goto _fail_; @@ -1091,11 +1091,11 @@ static int spi_read_int(u32 *int_status) happended = 0; - spi_read_reg(0x1a90, &irq_flags); + wilc_spi_read_reg(0x1a90, &irq_flags); tmp |= ((irq_flags >> 27) << IRG_FLAGS_OFFSET); if (g_spi.nint > 5) { - spi_read_reg(0x1a94, &irq_flags); + wilc_spi_read_reg(0x1a94, &irq_flags); tmp |= (((irq_flags >> 0) & 0x7) << (IRG_FLAGS_OFFSET + 5)); } @@ -1121,7 +1121,7 @@ _fail_: return ret; } -static int spi_clear_int_ext(u32 val) +static int wilc_spi_clear_int_ext(u32 val) { int ret; @@ -1138,13 +1138,13 @@ static int spi_clear_int_ext(u32 val) for (i = 0; i < g_spi.nint; i++) { /* No matter what you write 1 or 0, it will clear interrupt. */ if (flags & 1) - ret = spi_write_reg(0x10c8 + i * 4, 1); + ret = wilc_spi_write_reg(0x10c8 + i * 4, 1); if (!ret) break; flags >>= 1; } if (!ret) { - PRINT_ER("[wilc spi]: Failed spi_write_reg, set reg %x ...\n", 0x10c8 + i * 4); + PRINT_ER("[wilc spi]: Failed wilc_spi_write_reg, set reg %x ...\n", 0x10c8 + i * 4); goto _fail_; } for (i = g_spi.nint; i < MAX_NUM_INT; i++) { @@ -1165,7 +1165,7 @@ static int spi_clear_int_ext(u32 val) if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1) tbl_ctl |= BIT(1); - ret = spi_write_reg(WILC_VMM_TBL_CTL, tbl_ctl); + ret = wilc_spi_write_reg(WILC_VMM_TBL_CTL, tbl_ctl); if (!ret) { PRINT_ER("[wilc spi]: fail write reg vmm_tbl_ctl...\n"); goto _fail_; @@ -1175,7 +1175,7 @@ static int spi_clear_int_ext(u32 val) /** * enable vmm transfer. **/ - ret = spi_write_reg(WILC_VMM_CORE_CTL, 1); + ret = wilc_spi_write_reg(WILC_VMM_CORE_CTL, 1); if (!ret) { PRINT_ER("[wilc spi]: fail write reg vmm_core_ctl...\n"); goto _fail_; @@ -1187,7 +1187,7 @@ _fail_: return ret; } -static int spi_sync_ext(int nint /* how mant interrupts to enable. */) +static int wilc_spi_sync_ext(int nint /* how mant interrupts to enable. */) { u32 reg; int ret, i; @@ -1202,13 +1202,13 @@ static int spi_sync_ext(int nint /* how mant interrupts to enable. */) /** * interrupt pin mux select **/ - ret = spi_read_reg(WILC_PIN_MUX_0, ®); + ret = wilc_spi_read_reg(WILC_PIN_MUX_0, ®); if (!ret) { PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); return 0; } reg |= BIT(8); - ret = spi_write_reg(WILC_PIN_MUX_0, reg); + ret = wilc_spi_write_reg(WILC_PIN_MUX_0, reg); if (!ret) { PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); return 0; @@ -1217,7 +1217,7 @@ static int spi_sync_ext(int nint /* how mant interrupts to enable. */) /** * interrupt enable **/ - ret = spi_read_reg(WILC_INTR_ENABLE, ®); + ret = wilc_spi_read_reg(WILC_INTR_ENABLE, ®); if (!ret) { PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); return 0; @@ -1226,13 +1226,13 @@ static int spi_sync_ext(int nint /* how mant interrupts to enable. */) for (i = 0; (i < 5) && (nint > 0); i++, nint--) { reg |= (BIT((27 + i))); } - ret = spi_write_reg(WILC_INTR_ENABLE, reg); + ret = wilc_spi_write_reg(WILC_INTR_ENABLE, reg); if (!ret) { PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); return 0; } if (nint) { - ret = spi_read_reg(WILC_INTR2_ENABLE, ®); + ret = wilc_spi_read_reg(WILC_INTR2_ENABLE, ®); if (!ret) { PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR2_ENABLE); return 0; @@ -1242,7 +1242,7 @@ static int spi_sync_ext(int nint /* how mant interrupts to enable. */) reg |= BIT(i); } - ret = spi_read_reg(WILC_INTR2_ENABLE, ®); + ret = wilc_spi_read_reg(WILC_INTR2_ENABLE, ®); if (!ret) { PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR2_ENABLE); return 0; @@ -1257,20 +1257,20 @@ static int spi_sync_ext(int nint /* how mant interrupts to enable. */) * ********************************************/ struct wilc_hif_func hif_spi = { - spi_init, - spi_deinit, - spi_read_reg, - spi_write_reg, - spi_read, - spi_write, - spi_sync, - spi_clear_int, - spi_read_int, - spi_clear_int_ext, - spi_read_size, - spi_write, - spi_read, - spi_sync_ext, - spi_max_bus_speed, - spi_default_bus_speed, + wilc_spi_init, + wilc_spi_deinit, + wilc_spi_read_reg, + wilc_spi_write_reg, + wilc_spi_read, + wilc_spi_write, + wilc_spi_sync, + wilc_spi_clear_int, + wilc_spi_read_int, + wilc_spi_clear_int_ext, + wilc_spi_read_size, + wilc_spi_write, + wilc_spi_read, + wilc_spi_sync_ext, + wilc_spi_max_bus_speed, + wilc_spi_default_bus_speed, }; -- GitLab From 5334bad035d8caa6d8c88401293234d450beefe1 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:09 +0900 Subject: [PATCH 0346/2855] staging: wilc1000: remove function pointer spi_tx of wilc_spi_t This patch removes function pointer spi_tx of wilc_spi_t and call linux_spi_write directly. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_spi.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 946bda77827f1..fd0d762b99313 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -10,10 +10,10 @@ #include #include "wilc_wlan_if.h" #include "wilc_wlan.h" +#include "linux_wlan_spi.h" typedef struct { void *os_context; - int (*spi_tx)(u8 *, u32); int (*spi_rx)(u8 *, u32); int (*spi_trx)(u8 *, u8 *, u32); int (*spi_max_speed)(void); @@ -211,7 +211,7 @@ static int spi_cmd(u8 cmd, u32 adr, u32 data, u32 sz, u8 clockless) else len -= 1; - if (!g_spi.spi_tx(bc, len)) { + if (!linux_spi_write(bc, len)) { PRINT_ER("[wilc spi]: Failed cmd write, bus error...\n"); result = N_FAIL; } @@ -709,7 +709,7 @@ static int spi_data_write(u8 *b, u32 sz) order = 0x2; } cmd |= order; - if (!g_spi.spi_tx(&cmd, 1)) { + if (!linux_spi_write(&cmd, 1)) { PRINT_ER("[wilc spi]: Failed data block cmd write, bus error...\n"); result = N_FAIL; break; @@ -718,7 +718,7 @@ static int spi_data_write(u8 *b, u32 sz) /** * Write data **/ - if (!g_spi.spi_tx(&b[ix], nbytes)) { + if (!linux_spi_write(&b[ix], nbytes)) { PRINT_ER("[wilc spi]: Failed data block write, bus error...\n"); result = N_FAIL; break; @@ -728,7 +728,7 @@ static int spi_data_write(u8 *b, u32 sz) * Write Crc **/ if (!g_spi.crc_off) { - if (!g_spi.spi_tx(crc, 2)) { + if (!linux_spi_write(crc, 2)) { PRINT_ER("[wilc spi]: Failed data block crc write, bus error...\n"); result = N_FAIL; break; @@ -977,7 +977,6 @@ static int wilc_spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func) } else { return 0; } - g_spi.spi_tx = inp->io_func.u.spi.spi_tx; g_spi.spi_rx = inp->io_func.u.spi.spi_rx; g_spi.spi_trx = inp->io_func.u.spi.spi_trx; g_spi.spi_max_speed = inp->io_func.u.spi.spi_max_speed; -- GitLab From 6cad576a89a99b41ff8b40a618a756f8ea54cb45 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:10 +0900 Subject: [PATCH 0347/2855] staging: wilc1000: remove function pointer spi_tx of wilc_wlan_io_function_t This patch removes function pointer spi_tx of wilc_wlan_io_func_t because it is not used anymore. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 1 - drivers/staging/wilc1000/wilc_wlan_if.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index b37ef4d029436..fb2fea574bf7b 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -898,7 +898,6 @@ void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic) nwi->io_func.io_type = HIF_SPI; nwi->io_func.io_init = linux_spi_init; nwi->io_func.io_deinit = linux_spi_deinit; - nwi->io_func.u.spi.spi_tx = linux_spi_write; nwi->io_func.u.spi.spi_rx = linux_spi_read; nwi->io_func.u.spi.spi_trx = linux_spi_write_read; nwi->io_func.u.spi.spi_max_speed = linux_spi_set_max_speed; diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index 4568457d98200..4c05a46a722bb 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -79,7 +79,6 @@ typedef struct { union { struct { int (*spi_max_speed)(void); - int (*spi_tx)(u8 *, u32); int (*spi_rx)(u8 *, u32); int (*spi_trx)(u8 *, u8 *, u32); } spi; -- GitLab From d3d02320b4ea420e1c833a64a8fe3195eedb6fd3 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:11 +0900 Subject: [PATCH 0348/2855] staging: wilc1000: remove function pointer spi_rx of wilc_spi_t This patch removes function pointer spi_rx of wilc_spi_t and just call linux_spi_read instead. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_spi.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index fd0d762b99313..f584d7e6cc08e 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -14,7 +14,6 @@ typedef struct { void *os_context; - int (*spi_rx)(u8 *, u32); int (*spi_trx)(u8 *, u8 *, u32); int (*spi_max_speed)(void); wilc_debug_func dPrint; @@ -231,13 +230,13 @@ static int spi_cmd_rsp(u8 cmd) if ((cmd == CMD_RESET) || (cmd == CMD_TERMINATE) || (cmd == CMD_REPEAT)) { - if (!g_spi.spi_rx(&rsp, 1)) { + if (!linux_spi_read(&rsp, 1)) { result = N_FAIL; goto _fail_; } } - if (!g_spi.spi_rx(&rsp, 1)) { + if (!linux_spi_read(&rsp, 1)) { PRINT_ER("[wilc spi]: Failed cmd response read, bus error...\n"); result = N_FAIL; goto _fail_; @@ -252,7 +251,7 @@ static int spi_cmd_rsp(u8 cmd) /** * State response **/ - if (!g_spi.spi_rx(&rsp, 1)) { + if (!linux_spi_read(&rsp, 1)) { PRINT_ER("[wilc spi]: Failed cmd state read, bus error...\n"); result = N_FAIL; goto _fail_; @@ -524,7 +523,7 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless) /** * Read bytes **/ - if (!g_spi.spi_rx(&b[ix], nbytes)) { + if (!linux_spi_read(&b[ix], nbytes)) { PRINT_ER("[wilc spi]: Failed data block read, bus error...\n"); result = N_FAIL; goto _error_; @@ -534,7 +533,7 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless) * Read Crc **/ if (!g_spi.crc_off) { - if (!g_spi.spi_rx(crc, 2)) { + if (!linux_spi_read(crc, 2)) { PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n"); result = N_FAIL; goto _error_; @@ -565,7 +564,7 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless) **/ retry = 10; do { - if (!g_spi.spi_rx(&rsp, 1)) { + if (!linux_spi_read(&rsp, 1)) { PRINT_ER("[wilc spi]: Failed data response read, bus error...\n"); result = N_FAIL; break; @@ -581,7 +580,7 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless) /** * Read bytes **/ - if (!g_spi.spi_rx(&b[ix], nbytes)) { + if (!linux_spi_read(&b[ix], nbytes)) { PRINT_ER("[wilc spi]: Failed data block read, bus error...\n"); result = N_FAIL; break; @@ -591,7 +590,7 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless) * Read Crc **/ if (!g_spi.crc_off) { - if (!g_spi.spi_rx(crc, 2)) { + if (!linux_spi_read(crc, 2)) { PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n"); result = N_FAIL; break; @@ -629,7 +628,7 @@ static int spi_data_read(u8 *b, u32 sz) **/ retry = 10; do { - if (!g_spi.spi_rx(&rsp, 1)) { + if (!linux_spi_read(&rsp, 1)) { PRINT_ER("[wilc spi]: Failed data response read, bus error...\n"); result = N_FAIL; break; @@ -650,7 +649,7 @@ static int spi_data_read(u8 *b, u32 sz) /** * Read bytes **/ - if (!g_spi.spi_rx(&b[ix], nbytes)) { + if (!linux_spi_read(&b[ix], nbytes)) { PRINT_ER("[wilc spi]: Failed data block read, bus error...\n"); result = N_FAIL; break; @@ -660,7 +659,7 @@ static int spi_data_read(u8 *b, u32 sz) * Read Crc **/ if (!g_spi.crc_off) { - if (!g_spi.spi_rx(crc, 2)) { + if (!linux_spi_read(crc, 2)) { PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n"); result = N_FAIL; break; @@ -977,7 +976,6 @@ static int wilc_spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func) } else { return 0; } - g_spi.spi_rx = inp->io_func.u.spi.spi_rx; g_spi.spi_trx = inp->io_func.u.spi.spi_trx; g_spi.spi_max_speed = inp->io_func.u.spi.spi_max_speed; -- GitLab From b4b87a0b1278c872b0873ce285b25e60ca5bbe42 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:12 +0900 Subject: [PATCH 0349/2855] staging: wilc1000: remove function pointer spi_rx of wilc_wlan_io_func_t This patch removes spi_rx of wilc_wlan_io_func_t and it's related codes since it is not used anymore. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 1 - drivers/staging/wilc1000/wilc_wlan_if.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index fb2fea574bf7b..7a207658b98c2 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -898,7 +898,6 @@ void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic) nwi->io_func.io_type = HIF_SPI; nwi->io_func.io_init = linux_spi_init; nwi->io_func.io_deinit = linux_spi_deinit; - nwi->io_func.u.spi.spi_rx = linux_spi_read; nwi->io_func.u.spi.spi_trx = linux_spi_write_read; nwi->io_func.u.spi.spi_max_speed = linux_spi_set_max_speed; #endif diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index 4c05a46a722bb..b820a113ad514 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -79,7 +79,6 @@ typedef struct { union { struct { int (*spi_max_speed)(void); - int (*spi_rx)(u8 *, u32); int (*spi_trx)(u8 *, u8 *, u32); } spi; } u; -- GitLab From fd9bf7bd4fac7ccb7a967918fe2c88e0e9f4a37d Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:13 +0900 Subject: [PATCH 0350/2855] staging: wilc1000: remove function pointer spi_trx This patch removes function pointer spi_trx and call linux_spi_write_read directly. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_spi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index f584d7e6cc08e..789635b8c2300 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -14,7 +14,6 @@ typedef struct { void *os_context; - int (*spi_trx)(u8 *, u8 *, u32); int (*spi_max_speed)(void); wilc_debug_func dPrint; int crc_off; @@ -408,7 +407,7 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless) } rix = len; - if (!g_spi.spi_trx(wb, rb, len2)) { + if (!linux_spi_write_read(wb, rb, len2)) { PRINT_ER("[wilc spi]: Failed cmd write, bus error...\n"); result = N_FAIL; return result; @@ -976,7 +975,6 @@ static int wilc_spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func) } else { return 0; } - g_spi.spi_trx = inp->io_func.u.spi.spi_trx; g_spi.spi_max_speed = inp->io_func.u.spi.spi_max_speed; /** -- GitLab From 6f617f22cfdc8c9e19c763c22bfde6f9eef27308 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:14 +0900 Subject: [PATCH 0351/2855] staging: wilc1000: remove spi_trx of wilc_wlan_io_func_t This patch removes spi_trx of wilc_wlan_io_func_t which is not used anymore. Delete it's related codes also. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 1 - drivers/staging/wilc1000/wilc_wlan_if.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 7a207658b98c2..935314c548512 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -898,7 +898,6 @@ void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic) nwi->io_func.io_type = HIF_SPI; nwi->io_func.io_init = linux_spi_init; nwi->io_func.io_deinit = linux_spi_deinit; - nwi->io_func.u.spi.spi_trx = linux_spi_write_read; nwi->io_func.u.spi.spi_max_speed = linux_spi_set_max_speed; #endif } diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index b820a113ad514..be73b02e107fe 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -79,7 +79,6 @@ typedef struct { union { struct { int (*spi_max_speed)(void); - int (*spi_trx)(u8 *, u8 *, u32); } spi; } u; } wilc_wlan_io_func_t; -- GitLab From fae26065d2d62404add16e26818e2506bd864ae4 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:15 +0900 Subject: [PATCH 0352/2855] staging: wilc1000: remove function pointer spi_max_speed This patch removes function pointer spi_max_speed of wilc_spi_t and just call the function linux_spi_set_max_speed directly. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_spi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 789635b8c2300..bda7b10a52a0a 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -14,7 +14,6 @@ typedef struct { void *os_context; - int (*spi_max_speed)(void); wilc_debug_func dPrint; int crc_off; int nint; @@ -975,7 +974,6 @@ static int wilc_spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func) } else { return 0; } - g_spi.spi_max_speed = inp->io_func.u.spi.spi_max_speed; /** * configure protocol @@ -1025,7 +1023,7 @@ static int wilc_spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func) static void wilc_spi_max_bus_speed(void) { - g_spi.spi_max_speed(); + linux_spi_set_max_speed(); } static void wilc_spi_default_bus_speed(void) -- GitLab From d8dd29dd3f9bca34c1a79c5ba3da1a0e48dfbdc9 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:16 +0900 Subject: [PATCH 0353/2855] staging: wilc1000: remove spi_max_speed of wilc_wlan_io_func_t This patch removes spi_max_speed of wilc_wlan_io_func_t which is not used anymore and removes union u and struct spi, which does not have members in it. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 1 - drivers/staging/wilc1000/wilc_wlan_if.h | 5 ----- 2 files changed, 6 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 935314c548512..3aa636aba66fb 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -898,7 +898,6 @@ void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic) nwi->io_func.io_type = HIF_SPI; nwi->io_func.io_init = linux_spi_init; nwi->io_func.io_deinit = linux_spi_deinit; - nwi->io_func.u.spi.spi_max_speed = linux_spi_set_max_speed; #endif } diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index be73b02e107fe..0f15795c95ec9 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -76,11 +76,6 @@ typedef struct { int io_type; int (*io_init)(void *); void (*io_deinit)(void *); - union { - struct { - int (*spi_max_speed)(void); - } spi; - } u; } wilc_wlan_io_func_t; #define WILC_MAC_INDICATE_STATUS 0x1 -- GitLab From 62342c7af7dd5c0f9c3a8c2c57d9afdf53d92507 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:17 +0900 Subject: [PATCH 0354/2855] staging: wilc1000: remove function pointer io_init This patch removes function pointer io_init of wilc_wlan_io_func_t and it's related codes, and call the function linux_spi_init directly. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 2 -- drivers/staging/wilc1000/wilc_spi.c | 8 +++----- drivers/staging/wilc1000/wilc_wlan_if.h | 1 - 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 3aa636aba66fb..119f55d8b756d 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -892,11 +892,9 @@ void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic) #ifdef WILC_SDIO nwi->io_func.io_type = HIF_SDIO; - nwi->io_func.io_init = linux_sdio_init; nwi->io_func.io_deinit = linux_sdio_deinit; #else nwi->io_func.io_type = HIF_SPI; - nwi->io_func.io_init = linux_spi_init; nwi->io_func.io_deinit = linux_spi_deinit; #endif } diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index bda7b10a52a0a..30b1744f98f1d 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -966,11 +966,9 @@ static int wilc_spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func) g_spi.dPrint = func; g_spi.os_context = inp->os_context.os_private; - if (inp->io_func.io_init) { - if (!inp->io_func.io_init(g_spi.os_context)) { - PRINT_ER("[wilc spi]: Failed io init bus...\n"); - return 0; - } + if (!linux_spi_init(g_spi.os_context)) { + PRINT_ER("[wilc spi]: Failed io init bus...\n"); + return 0; } else { return 0; } diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index 0f15795c95ec9..d0b5bc3161e08 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -74,7 +74,6 @@ typedef struct { typedef struct { int io_type; - int (*io_init)(void *); void (*io_deinit)(void *); } wilc_wlan_io_func_t; -- GitLab From 060a8a23f51c4ccc0ec70619e8f70d93870ef081 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:18 +0900 Subject: [PATCH 0355/2855] staging: wilc1000: remove unused function pointer io_deinit This patch removes function pointer io_deinit which is never used, and delete it's related codes also. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 2 -- drivers/staging/wilc1000/wilc_wlan_if.h | 1 - 2 files changed, 3 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 119f55d8b756d..00bc890f16625 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -892,10 +892,8 @@ void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic) #ifdef WILC_SDIO nwi->io_func.io_type = HIF_SDIO; - nwi->io_func.io_deinit = linux_sdio_deinit; #else nwi->io_func.io_type = HIF_SPI; - nwi->io_func.io_deinit = linux_spi_deinit; #endif } diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index d0b5bc3161e08..b43e439651b33 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -74,7 +74,6 @@ typedef struct { typedef struct { int io_type; - void (*io_deinit)(void *); } wilc_wlan_io_func_t; #define WILC_MAC_INDICATE_STATUS 0x1 -- GitLab From 4bffadb0446cdc46153f9a3055da5cf2288833da Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:19 +0900 Subject: [PATCH 0356/2855] staging: wilc1000: linux_sdio_init: remove parameter pv This patch removes function parameter pv which is not used and modify it's related codes. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_sdio.c | 2 +- drivers/staging/wilc1000/linux_wlan_sdio.h | 2 +- drivers/staging/wilc1000/wilc_sdio.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index bf05e227778c0..e854d376878fe 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -214,7 +214,7 @@ static int linux_sdio_get_speed(void) return local_sdio_func->card->host->ios.clock; } -int linux_sdio_init(void *pv) +int linux_sdio_init(void) { /** diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.h b/drivers/staging/wilc1000/linux_wlan_sdio.h index 4b515f5108e7f..6f42bc75b5076 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.h +++ b/drivers/staging/wilc1000/linux_wlan_sdio.h @@ -3,7 +3,7 @@ extern struct sdio_driver wilc_bus; #include -int linux_sdio_init(void *); +int linux_sdio_init(void); void linux_sdio_deinit(void *); int linux_sdio_cmd52(sdio_cmd52_t *cmd); int linux_sdio_cmd53(sdio_cmd53_t *cmd); diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index 0d88b6e46a023..01a8e5b71c801 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -562,7 +562,7 @@ static int sdio_init(wilc_wlan_inp_t *inp, wilc_debug_func func) g_sdio.dPrint = func; g_sdio.os_context = inp->os_context.os_private; - if (!linux_sdio_init(g_sdio.os_context)) { + if (!linux_sdio_init()) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed io init bus...\n"); return 0; } else { -- GitLab From 3f644285a8bd19916e580e892685881522916bab Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:20 +0900 Subject: [PATCH 0357/2855] staging: wilc1000: linux_spi_init: remove parameter vp This patch removes function parameter vp which is not used and modify it's related codes. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 2 +- drivers/staging/wilc1000/linux_wlan_spi.c | 2 +- drivers/staging/wilc1000/linux_wlan_spi.h | 2 +- drivers/staging/wilc1000/wilc_spi.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 00bc890f16625..fcc669c7a10f6 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1566,7 +1566,7 @@ int wilc_netdev_init(struct wilc **wilc) } #ifndef WILC_SDIO - if (!linux_spi_init(&g_linux_wlan->wilc_spidev)) { + if (!linux_spi_init()) { PRINT_ER("Can't initialize SPI\n"); return -1; } diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index 039d06192d6b1..73c788f602c02 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -93,7 +93,7 @@ void linux_spi_deinit(void *vp) -int linux_spi_init(void *vp) +int linux_spi_init(void) { int ret = 1; static int called; diff --git a/drivers/staging/wilc1000/linux_wlan_spi.h b/drivers/staging/wilc1000/linux_wlan_spi.h index 7356785296f9f..b9561003ecf0a 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.h +++ b/drivers/staging/wilc1000/linux_wlan_spi.h @@ -5,7 +5,7 @@ extern struct spi_device *wilc_spi_dev; extern struct spi_driver wilc_bus; -int linux_spi_init(void *vp); +int linux_spi_init(void); void linux_spi_deinit(void *vp); int linux_spi_write(u8 *b, u32 len); int linux_spi_read(u8 *rb, u32 rlen); diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 30b1744f98f1d..fe16d705e841d 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -966,7 +966,7 @@ static int wilc_spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func) g_spi.dPrint = func; g_spi.os_context = inp->os_context.os_private; - if (!linux_spi_init(g_spi.os_context)) { + if (!linux_spi_init()) { PRINT_ER("[wilc spi]: Failed io init bus...\n"); return 0; } else { -- GitLab From 64ae414fe2bcdc86a347056e20d377376fa45b4f Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:21 +0900 Subject: [PATCH 0358/2855] staging: wilc1000: remove os_context This patch removes variable os_context of wilc_sdio_t and wilc_spi_t because os_context is not used, and delete it's related code. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_sdio.c | 2 -- drivers/staging/wilc1000/wilc_spi.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index 01a8e5b71c801..a5307a7602c57 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -15,7 +15,6 @@ #define WILC_SDIO_BLOCK_SIZE 512 typedef struct { - void *os_context; u32 block_size; wilc_debug_func dPrint; int nint; @@ -560,7 +559,6 @@ static int sdio_init(wilc_wlan_inp_t *inp, wilc_debug_func func) memset(&g_sdio, 0, sizeof(wilc_sdio_t)); g_sdio.dPrint = func; - g_sdio.os_context = inp->os_context.os_private; if (!linux_sdio_init()) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed io init bus...\n"); diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index fe16d705e841d..5a6bbfd4f5da8 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -13,7 +13,6 @@ #include "linux_wlan_spi.h" typedef struct { - void *os_context; wilc_debug_func dPrint; int crc_off; int nint; @@ -965,7 +964,6 @@ static int wilc_spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func) memset(&g_spi, 0, sizeof(wilc_spi_t)); g_spi.dPrint = func; - g_spi.os_context = inp->os_context.os_private; if (!linux_spi_init()) { PRINT_ER("[wilc spi]: Failed io init bus...\n"); return 0; -- GitLab From 9c800322a56610bbdd80e6a859c412e65c5fc6eb Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:22 +0900 Subject: [PATCH 0359/2855] staging: wilc1000: change parameter type of hif_init This patch changes parameter type wilc_wlan_inp_t with struct wilc and modify it's related code. Pass wilc to the functions as well. wilc will be used in later patch. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_sdio.c | 3 ++- drivers/staging/wilc1000/wilc_spi.c | 3 ++- drivers/staging/wilc1000/wilc_wlan.c | 8 ++++++-- drivers/staging/wilc1000/wilc_wlan.h | 4 ++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index a5307a7602c57..8aacf55e5eb80 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -11,6 +11,7 @@ #include "wilc_wlan_if.h" #include "wilc_wlan.h" #include "linux_wlan_sdio.h" +#include "wilc_wfi_netdevice.h" #define WILC_SDIO_BLOCK_SIZE 512 @@ -550,7 +551,7 @@ static int sdio_sync(void) return 1; } -static int sdio_init(wilc_wlan_inp_t *inp, wilc_debug_func func) +static int sdio_init(struct wilc *wilc, wilc_debug_func func) { sdio_cmd52_t cmd; int loop; diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 5a6bbfd4f5da8..3741836dad419 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -11,6 +11,7 @@ #include "wilc_wlan_if.h" #include "wilc_wlan.h" #include "linux_wlan_spi.h" +#include "wilc_wfi_netdevice.h" typedef struct { wilc_debug_func dPrint; @@ -945,7 +946,7 @@ static int wilc_spi_sync(void) return 1; } -static int wilc_spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func) +static int wilc_spi_init(struct wilc *wilc, wilc_debug_func func) { u32 reg; u32 chipid; diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 2ce58702d705a..9d257b06c8537 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1655,6 +1655,10 @@ _fail_: int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) { int ret = 0; + perInterface_wlan_t *nic = netdev_priv(dev); + struct wilc *wilc; + + wilc = nic->wilc; PRINT_D(INIT_DBG, "Initializing WILC_Wlan ...\n"); @@ -1663,14 +1667,14 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) sizeof(wilc_wlan_io_func_t)); #ifdef WILC_SDIO - if (!hif_sdio.hif_init(inp, wilc_debug)) { + if (!hif_sdio.hif_init(wilc, wilc_debug)) { ret = -EIO; goto _fail_; } memcpy((void *)&g_wlan.hif_func, &hif_sdio, sizeof(struct wilc_hif_func)); #else - if (!hif_spi.hif_init(inp, wilc_debug)) { + if (!hif_spi.hif_init(wilc, wilc_debug)) { ret = -EIO; goto _fail_; } diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index ff4872f1e675d..64fd019595cec 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -235,9 +235,9 @@ struct rxq_entry_t { * Host IF Structure * ********************************************/ - +struct wilc; struct wilc_hif_func { - int (*hif_init)(wilc_wlan_inp_t *, wilc_debug_func); + int (*hif_init)(struct wilc *, wilc_debug_func); int (*hif_deinit)(void *); int (*hif_read_reg)(u32, u32 *); int (*hif_write_reg)(u32, u32); -- GitLab From f7a34d9ceb78ffa84eb71c4859193f022b87b5bf Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 6 Nov 2015 18:40:23 +0900 Subject: [PATCH 0360/2855] staging: wilc1000: remove os_private This patch removes unused variable os_private and delete struct wilc_wlan_os_context_t since there is no members in it. Remove it's related code also. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 2 -- drivers/staging/wilc1000/wilc_wlan_if.h | 5 ----- 2 files changed, 7 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index fcc669c7a10f6..086f1dbfb157d 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -888,8 +888,6 @@ void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic) { PRINT_D(INIT_DBG, "Linux to Wlan services ...\n"); - nwi->os_context.os_private = (void *)nic; - #ifdef WILC_SDIO nwi->io_func.io_type = HIF_SDIO; #else diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index b43e439651b33..5980ece49daa1 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -84,11 +84,6 @@ typedef struct { #define WILC_MAC_INDICATE_SCAN 0x2 typedef struct { - void *os_private; -} wilc_wlan_os_context_t; - -typedef struct { - wilc_wlan_os_context_t os_context; wilc_wlan_io_func_t io_func; } wilc_wlan_inp_t; -- GitLab From 0a5298cbf316df263664b94e7afdeaccb7451216 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Fri, 6 Nov 2015 19:11:10 +0900 Subject: [PATCH 0361/2855] staging: wilc1000: fix return type of host_int_del_beacon This patch changes return type of host_int_del_beacon from s32 to int. The result variable gets return value from wilc_mq_send that has return type of int. It should be changed return type of this function as well as data type of result variable. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 1a334aec0eb71..08384b0954cce 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -4518,9 +4518,9 @@ ERRORHANDLER: return result; } -s32 host_int_del_beacon(struct host_if_drv *hif_drv) +int host_int_del_beacon(struct host_if_drv *hif_drv) { - s32 result = 0; + int result = 0; struct host_if_msg msg; if (!hif_drv) { diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index f70da7556a817..4457f9c07afb8 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -377,7 +377,7 @@ s32 host_int_add_beacon(struct host_if_drv *hWFIDrv, u32 u32Interval, u8 *pu8Head, u32 u32TailLen, u8 *pu8tail); -s32 host_int_del_beacon(struct host_if_drv *hWFIDrv); +int host_int_del_beacon(struct host_if_drv *hWFIDrv); s32 host_int_add_station(struct host_if_drv *hWFIDrv, struct add_sta_param *pstrStaParams); s32 host_int_del_allstation(struct host_if_drv *hWFIDrv, -- GitLab From b6694df6756e3784c38b9f8f0a9bcdb6f934e13c Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Fri, 6 Nov 2015 19:11:11 +0900 Subject: [PATCH 0362/2855] staging: wilc1000: fix parameter name of host_int_del_beacon This patch changes struct host_if_drv of host_int_del_beacon function declaration from hWFIDrv to hif_drv. With this change, first parameter name of this function declaration and definition has same name as hif_drv. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 4457f9c07afb8..1a27b88facab7 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -377,7 +377,7 @@ s32 host_int_add_beacon(struct host_if_drv *hWFIDrv, u32 u32Interval, u8 *pu8Head, u32 u32TailLen, u8 *pu8tail); -int host_int_del_beacon(struct host_if_drv *hWFIDrv); +int host_int_del_beacon(struct host_if_drv *hif_drv); s32 host_int_add_station(struct host_if_drv *hWFIDrv, struct add_sta_param *pstrStaParams); s32 host_int_del_allstation(struct host_if_drv *hWFIDrv, -- GitLab From 79a0c0a8c4db5809854ce9419486f2cfd01212e5 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Fri, 6 Nov 2015 19:11:12 +0900 Subject: [PATCH 0363/2855] staging: wilc1000: fix return type of host_int_del_station This patch changes return type of host_int_del_station from s32 to int. The result variable gets return value from wilc_mq_send that has return type of int. It should be changed return type of this function as well as data type of result variable. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 08384b0954cce..0729811dfeb25 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -4576,9 +4576,9 @@ s32 host_int_add_station(struct host_if_drv *hif_drv, return result; } -s32 host_int_del_station(struct host_if_drv *hif_drv, const u8 *pu8MacAddr) +int host_int_del_station(struct host_if_drv *hif_drv, const u8 *pu8MacAddr) { - s32 result = 0; + int result = 0; struct host_if_msg msg; struct del_sta *pstrDelStationMsg = &msg.body.del_sta_info; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 1a27b88facab7..76e7c2f015660 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -382,7 +382,7 @@ s32 host_int_add_station(struct host_if_drv *hWFIDrv, struct add_sta_param *pstrStaParams); s32 host_int_del_allstation(struct host_if_drv *hWFIDrv, u8 pu8MacAddr[][ETH_ALEN]); -s32 host_int_del_station(struct host_if_drv *hWFIDrv, const u8 *pu8MacAddr); +int host_int_del_station(struct host_if_drv *hWFIDrv, const u8 *pu8MacAddr); s32 host_int_edit_station(struct host_if_drv *hWFIDrv, struct add_sta_param *pstrStaParams); s32 host_int_set_power_mgmt(struct host_if_drv *hWFIDrv, -- GitLab From 994e7dc9134ee418eda48cf744e44ab19d3de4f8 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Fri, 6 Nov 2015 19:11:13 +0900 Subject: [PATCH 0364/2855] staging: wilc1000: fix parameter name of host_int_del_station This patch changes struct host_if_drv of host_int_del_station function declaration from hWFIDrv to hif_drv. With this change, first parameter name of this function declaration and definition has same name as hif_drv. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 76e7c2f015660..9d747469aae2d 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -382,7 +382,7 @@ s32 host_int_add_station(struct host_if_drv *hWFIDrv, struct add_sta_param *pstrStaParams); s32 host_int_del_allstation(struct host_if_drv *hWFIDrv, u8 pu8MacAddr[][ETH_ALEN]); -int host_int_del_station(struct host_if_drv *hWFIDrv, const u8 *pu8MacAddr); +int host_int_del_station(struct host_if_drv *hif_drv, const u8 *pu8MacAddr); s32 host_int_edit_station(struct host_if_drv *hWFIDrv, struct add_sta_param *pstrStaParams); s32 host_int_set_power_mgmt(struct host_if_drv *hWFIDrv, -- GitLab From c9c4eb415d9541e3c48fc3103462e668c15c4870 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Fri, 6 Nov 2015 19:11:14 +0900 Subject: [PATCH 0365/2855] staging: wilc1000: rename pu8MacAddr in host_int_del_station This patch changes pu8MacAddr to mac_addr that is second argument of this function to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 +++--- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 0729811dfeb25..0e7d3db86a2ab 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -4576,7 +4576,7 @@ s32 host_int_add_station(struct host_if_drv *hif_drv, return result; } -int host_int_del_station(struct host_if_drv *hif_drv, const u8 *pu8MacAddr) +int host_int_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr) { int result = 0; struct host_if_msg msg; @@ -4594,10 +4594,10 @@ int host_int_del_station(struct host_if_drv *hif_drv, const u8 *pu8MacAddr) msg.id = HOST_IF_MSG_DEL_STATION; msg.drv = hif_drv; - if (!pu8MacAddr) + if (!mac_addr) eth_broadcast_addr(pstrDelStationMsg->mac_addr); else - memcpy(pstrDelStationMsg->mac_addr, pu8MacAddr, ETH_ALEN); + memcpy(pstrDelStationMsg->mac_addr, mac_addr, ETH_ALEN); result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 9d747469aae2d..80562b5e57fba 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -382,7 +382,7 @@ s32 host_int_add_station(struct host_if_drv *hWFIDrv, struct add_sta_param *pstrStaParams); s32 host_int_del_allstation(struct host_if_drv *hWFIDrv, u8 pu8MacAddr[][ETH_ALEN]); -int host_int_del_station(struct host_if_drv *hif_drv, const u8 *pu8MacAddr); +int host_int_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr); s32 host_int_edit_station(struct host_if_drv *hWFIDrv, struct add_sta_param *pstrStaParams); s32 host_int_set_power_mgmt(struct host_if_drv *hWFIDrv, -- GitLab From c87fbede0fc852753c74e554206023b5d98b7cd7 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Fri, 6 Nov 2015 19:11:15 +0900 Subject: [PATCH 0366/2855] staging: wilc1000: rename pstrDelStationMsg in host_int_del_station This patch renames pstrDelStationMsg to del_sta_info to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 0e7d3db86a2ab..047bb373f72d9 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -4580,7 +4580,7 @@ int host_int_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr) { int result = 0; struct host_if_msg msg; - struct del_sta *pstrDelStationMsg = &msg.body.del_sta_info; + struct del_sta *del_sta_info = &msg.body.del_sta_info; if (!hif_drv) { PRINT_ER("driver is null\n"); @@ -4595,9 +4595,9 @@ int host_int_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr) msg.drv = hif_drv; if (!mac_addr) - eth_broadcast_addr(pstrDelStationMsg->mac_addr); + eth_broadcast_addr(del_sta_info->mac_addr); else - memcpy(pstrDelStationMsg->mac_addr, mac_addr, ETH_ALEN); + memcpy(del_sta_info->mac_addr, mac_addr, ETH_ALEN); result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) -- GitLab From 18cfbd334e83e4716cabc7b278eb6aa52f0f97c0 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Fri, 6 Nov 2015 19:11:16 +0900 Subject: [PATCH 0367/2855] staging: wilc1000: fix return type of host_int_add_station This patch changes return type of host_int_add_station from s32 to int. The result variable gets return value from wilc_mq_send that has return type of int. It should be changed return type of this function as well as data type of result variable. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 047bb373f72d9..10e394acd6355 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -4539,10 +4539,10 @@ int host_int_del_beacon(struct host_if_drv *hif_drv) return result; } -s32 host_int_add_station(struct host_if_drv *hif_drv, +int host_int_add_station(struct host_if_drv *hif_drv, struct add_sta_param *pstrStaParams) { - s32 result = 0; + int result = 0; struct host_if_msg msg; struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 80562b5e57fba..81ebfcf5bfd95 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -378,7 +378,7 @@ s32 host_int_add_beacon(struct host_if_drv *hWFIDrv, u32 u32Interval, u32 u32TailLen, u8 *pu8tail); int host_int_del_beacon(struct host_if_drv *hif_drv); -s32 host_int_add_station(struct host_if_drv *hWFIDrv, +int host_int_add_station(struct host_if_drv *hWFIDrv, struct add_sta_param *pstrStaParams); s32 host_int_del_allstation(struct host_if_drv *hWFIDrv, u8 pu8MacAddr[][ETH_ALEN]); -- GitLab From 261de713b9e4c55057d7053a08fe148519ee710c Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Fri, 6 Nov 2015 19:11:17 +0900 Subject: [PATCH 0368/2855] staging: wilc1000: fix parameter name of host_int_add_station This patch changes struct host_if_drv of host_int_add_station function declaration from hWFIDrv to hif_drv. With this change, first parameter of this function declaration and definition has same name as hif_drv. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 81ebfcf5bfd95..adb201be7af34 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -378,7 +378,7 @@ s32 host_int_add_beacon(struct host_if_drv *hWFIDrv, u32 u32Interval, u32 u32TailLen, u8 *pu8tail); int host_int_del_beacon(struct host_if_drv *hif_drv); -int host_int_add_station(struct host_if_drv *hWFIDrv, +int host_int_add_station(struct host_if_drv *hif_drv, struct add_sta_param *pstrStaParams); s32 host_int_del_allstation(struct host_if_drv *hWFIDrv, u8 pu8MacAddr[][ETH_ALEN]); -- GitLab From e33785470d26fdae12f453426cc5bb68771a69c3 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Fri, 6 Nov 2015 19:11:18 +0900 Subject: [PATCH 0369/2855] staging: wilc1000: rename pstrStaParams in host_int_add_station This patch renames pstrStaParams to sta_param to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 +++--- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 10e394acd6355..cce95177b515a 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -4540,7 +4540,7 @@ int host_int_del_beacon(struct host_if_drv *hif_drv) } int host_int_add_station(struct host_if_drv *hif_drv, - struct add_sta_param *pstrStaParams) + struct add_sta_param *sta_param) { int result = 0; struct host_if_msg msg; @@ -4558,14 +4558,14 @@ int host_int_add_station(struct host_if_drv *hif_drv, msg.id = HOST_IF_MSG_ADD_STATION; msg.drv = hif_drv; - memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param)); + memcpy(pstrAddStationMsg, sta_param, sizeof(struct add_sta_param)); if (pstrAddStationMsg->rates_len > 0) { u8 *rates = kmalloc(pstrAddStationMsg->rates_len, GFP_KERNEL); if (!rates) return -ENOMEM; - memcpy(rates, pstrStaParams->rates, + memcpy(rates, sta_param->rates, pstrAddStationMsg->rates_len); pstrAddStationMsg->rates = rates; } diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index adb201be7af34..57e1d424afdc4 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -379,7 +379,7 @@ s32 host_int_add_beacon(struct host_if_drv *hWFIDrv, u32 u32Interval, u8 *pu8tail); int host_int_del_beacon(struct host_if_drv *hif_drv); int host_int_add_station(struct host_if_drv *hif_drv, - struct add_sta_param *pstrStaParams); + struct add_sta_param *sta_param); s32 host_int_del_allstation(struct host_if_drv *hWFIDrv, u8 pu8MacAddr[][ETH_ALEN]); int host_int_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr); -- GitLab From 773e02e696b1926d85627a901375453d46d12262 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Fri, 6 Nov 2015 19:11:19 +0900 Subject: [PATCH 0370/2855] staging: wilc1000: rename pstrAddStationMsg in host_int_add_station This patch renames pstrAddStationMsg to add_sta_info to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index cce95177b515a..b870809037b11 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -4544,7 +4544,7 @@ int host_int_add_station(struct host_if_drv *hif_drv, { int result = 0; struct host_if_msg msg; - struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info; + struct add_sta_param *add_sta_info = &msg.body.add_sta_info; if (!hif_drv) { PRINT_ER("driver is null\n"); @@ -4558,16 +4558,16 @@ int host_int_add_station(struct host_if_drv *hif_drv, msg.id = HOST_IF_MSG_ADD_STATION; msg.drv = hif_drv; - memcpy(pstrAddStationMsg, sta_param, sizeof(struct add_sta_param)); - if (pstrAddStationMsg->rates_len > 0) { - u8 *rates = kmalloc(pstrAddStationMsg->rates_len, GFP_KERNEL); + memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param)); + if (add_sta_info->rates_len > 0) { + u8 *rates = kmalloc(add_sta_info->rates_len, GFP_KERNEL); if (!rates) return -ENOMEM; memcpy(rates, sta_param->rates, - pstrAddStationMsg->rates_len); - pstrAddStationMsg->rates = rates; + add_sta_info->rates_len); + add_sta_info->rates = rates; } result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); -- GitLab From 7897bd00f6b5e69443ceffc7900faaafc23455b0 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Fri, 6 Nov 2015 19:11:20 +0900 Subject: [PATCH 0371/2855] staging: wilc1000: use kmemdup in host_int_add_station This patch replaces kmalloc followed by memcpy with kmemdup. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index b870809037b11..db7060f2ba12d 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -4560,13 +4560,11 @@ int host_int_add_station(struct host_if_drv *hif_drv, memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param)); if (add_sta_info->rates_len > 0) { - u8 *rates = kmalloc(add_sta_info->rates_len, GFP_KERNEL); - + u8 *rates = kmemdup(sta_param->rates, + add_sta_info->rates_len, + GFP_KERNEL); if (!rates) return -ENOMEM; - - memcpy(rates, sta_param->rates, - add_sta_info->rates_len); add_sta_info->rates = rates; } -- GitLab From 9062305b902d9daadf1ca34d32df40858d82a2c9 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Fri, 6 Nov 2015 19:11:21 +0900 Subject: [PATCH 0372/2855] staging: wilc1000: remove rates variable in host_int_add_station Instead of using rates variable, it is used as add_sta_info->rates directly. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index db7060f2ba12d..d5b7725ec2bf5 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -4560,12 +4560,11 @@ int host_int_add_station(struct host_if_drv *hif_drv, memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param)); if (add_sta_info->rates_len > 0) { - u8 *rates = kmemdup(sta_param->rates, - add_sta_info->rates_len, - GFP_KERNEL); - if (!rates) + add_sta_info->rates = kmemdup(sta_param->rates, + add_sta_info->rates_len, + GFP_KERNEL); + if (!add_sta_info->rates) return -ENOMEM; - add_sta_info->rates = rates; } result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); -- GitLab From 9e10af4787ac5164345c89ba5118686b4463857d Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Fri, 30 Oct 2015 18:58:40 -0400 Subject: [PATCH 0373/2855] staging/rdma/hfi1: Remove file pointer macros Remove the following macros in favor of explicit use of struct hfi1_filedata and various sub structures. ctxt_fp subctxt_fp tidcursor_fp user_sdma_pkt_fp user_sdma_comp_fp Reviewed-by: Mitko Haralanov Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/file_ops.c | 124 ++++++++++++++------------ drivers/staging/rdma/hfi1/hfi.h | 12 --- drivers/staging/rdma/hfi1/user_sdma.c | 34 +++---- 3 files changed, 84 insertions(+), 86 deletions(-) diff --git a/drivers/staging/rdma/hfi1/file_ops.c b/drivers/staging/rdma/hfi1/file_ops.c index aae9826ec62be..f78bcf673252c 100644 --- a/drivers/staging/rdma/hfi1/file_ops.c +++ b/drivers/staging/rdma/hfi1/file_ops.c @@ -204,7 +204,8 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data, size_t count, loff_t *offset) { const struct hfi1_cmd __user *ucmd; - struct hfi1_ctxtdata *uctxt = ctxt_fp(fp); + struct hfi1_filedata *fd = fp->private_data; + struct hfi1_ctxtdata *uctxt = fd->uctxt; struct hfi1_cmd cmd; struct hfi1_user_info uinfo; struct hfi1_tid_info tinfo; @@ -338,17 +339,17 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data, ret = exp_tid_free(fp, &tinfo); break; case HFI1_CMD_RECV_CTRL: - ret = manage_rcvq(uctxt, subctxt_fp(fp), (int)user_val); + ret = manage_rcvq(uctxt, fd->subctxt, (int)user_val); break; case HFI1_CMD_POLL_TYPE: uctxt->poll_type = (typeof(uctxt->poll_type))user_val; break; case HFI1_CMD_ACK_EVENT: - ret = user_event_ack(uctxt, subctxt_fp(fp), user_val); + ret = user_event_ack(uctxt, fd->subctxt, user_val); break; case HFI1_CMD_SET_PKEY: if (HFI1_CAP_IS_USET(PKEY_CHECK)) - ret = set_ctxt_pkey(uctxt, subctxt_fp(fp), user_val); + ret = set_ctxt_pkey(uctxt, fd->subctxt, user_val); else ret = -EPERM; break; @@ -431,13 +432,13 @@ bail: static ssize_t hfi1_write_iter(struct kiocb *kiocb, struct iov_iter *from) { - struct hfi1_user_sdma_pkt_q *pq; - struct hfi1_user_sdma_comp_q *cq; + struct hfi1_filedata *fd = kiocb->ki_filp->private_data; + struct hfi1_user_sdma_pkt_q *pq = fd->pq; + struct hfi1_user_sdma_comp_q *cq = fd->cq; int ret = 0, done = 0, reqs = 0; unsigned long dim = from->nr_segs; - if (!user_sdma_comp_fp(kiocb->ki_filp) || - !user_sdma_pkt_fp(kiocb->ki_filp)) { + if (!cq || !pq) { ret = -EIO; goto done; } @@ -448,10 +449,7 @@ static ssize_t hfi1_write_iter(struct kiocb *kiocb, struct iov_iter *from) } hfi1_cdbg(SDMA, "SDMA request from %u:%u (%lu)", - ctxt_fp(kiocb->ki_filp)->ctxt, subctxt_fp(kiocb->ki_filp), - dim); - pq = user_sdma_pkt_fp(kiocb->ki_filp); - cq = user_sdma_comp_fp(kiocb->ki_filp); + fd->uctxt->ctxt, fd->subctxt, dim); if (atomic_read(&pq->n_reqs) == pq->n_max_reqs) { ret = -ENOSPC; @@ -476,7 +474,8 @@ done: static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) { - struct hfi1_ctxtdata *uctxt; + struct hfi1_filedata *fd = fp->private_data; + struct hfi1_ctxtdata *uctxt = fd->uctxt; struct hfi1_devdata *dd; unsigned long flags, pfn; u64 token = vma->vm_pgoff << PAGE_SHIFT, @@ -486,7 +485,6 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) int ret = 0; u16 ctxt; - uctxt = ctxt_fp(fp); if (!is_valid_mmap(token) || !uctxt || !(vma->vm_flags & VM_SHARED)) { ret = -EINVAL; @@ -496,7 +494,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) ctxt = HFI1_MMAP_TOKEN_GET(CTXT, token); subctxt = HFI1_MMAP_TOKEN_GET(SUBCTXT, token); type = HFI1_MMAP_TOKEN_GET(TYPE, token); - if (ctxt != uctxt->ctxt || subctxt != subctxt_fp(fp)) { + if (ctxt != uctxt->ctxt || subctxt != fd->subctxt) { ret = -EINVAL; goto done; } @@ -660,13 +658,12 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) vmf = 1; break; case SDMA_COMP: { - struct hfi1_user_sdma_comp_q *cq; + struct hfi1_user_sdma_comp_q *cq = fd->cq; - if (!user_sdma_comp_fp(fp)) { + if (!cq) { ret = -EFAULT; goto done; } - cq = user_sdma_comp_fp(fp); memaddr = (u64)cq->comps; memlen = ALIGN(sizeof(*cq->comps) * cq->nentries, PAGE_SIZE); flags |= VM_IO | VM_DONTEXPAND; @@ -680,7 +677,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) if ((vma->vm_end - vma->vm_start) != memlen) { hfi1_cdbg(PROC, "%u:%u Memory size mismatch %lu:%lu", - uctxt->ctxt, subctxt_fp(fp), + uctxt->ctxt, fd->subctxt, (vma->vm_end - vma->vm_start), memlen); ret = -EINVAL; goto done; @@ -730,7 +727,7 @@ static unsigned int hfi1_poll(struct file *fp, struct poll_table_struct *pt) struct hfi1_ctxtdata *uctxt; unsigned pollflag; - uctxt = ctxt_fp(fp); + uctxt = ((struct hfi1_filedata *)fp->private_data)->uctxt; if (!uctxt) pollflag = POLLERR; else if (uctxt->poll_type == HFI1_POLL_TYPE_URGENT) @@ -930,6 +927,7 @@ static int find_shared_ctxt(struct file *fp, { int devmax, ndev, i; int ret = 0; + struct hfi1_filedata *fd = fp->private_data; devmax = hfi1_count_units(NULL, NULL); @@ -959,10 +957,10 @@ static int find_shared_ctxt(struct file *fp, ret = -EINVAL; goto done; } - ctxt_fp(fp) = uctxt; - subctxt_fp(fp) = uctxt->cnt++; - uctxt->subpid[subctxt_fp(fp)] = current->pid; - uctxt->active_slaves |= 1 << subctxt_fp(fp); + fd->uctxt = uctxt; + fd->subctxt = uctxt->cnt++; + uctxt->subpid[fd->subctxt] = current->pid; + uctxt->active_slaves |= 1 << fd->subctxt; ret = 1; goto done; } @@ -975,6 +973,7 @@ done: static int allocate_ctxt(struct file *fp, struct hfi1_devdata *dd, struct hfi1_user_info *uinfo) { + struct hfi1_filedata *fd = fp->private_data; struct hfi1_ctxtdata *uctxt; unsigned ctxt; int ret; @@ -1022,7 +1021,7 @@ static int allocate_ctxt(struct file *fp, struct hfi1_devdata *dd, * This has to be done here so the rest of the sub-contexts find the * proper master. */ - if (uinfo->subctxt_cnt && !subctxt_fp(fp)) { + if (uinfo->subctxt_cnt && !fd->subctxt) { ret = init_subctxts(uctxt, uinfo); /* * On error, we don't need to disable and de-allocate the @@ -1042,7 +1041,7 @@ static int allocate_ctxt(struct file *fp, struct hfi1_devdata *dd, spin_lock_init(&uctxt->sdma_qlock); hfi1_stats.sps_ctxts++; dd->freectxts--; - ctxt_fp(fp) = uctxt; + fd->uctxt = uctxt; return 0; } @@ -1106,7 +1105,8 @@ static int user_init(struct file *fp) { int ret; unsigned int rcvctrl_ops = 0; - struct hfi1_ctxtdata *uctxt = ctxt_fp(fp); + struct hfi1_filedata *fd = fp->private_data; + struct hfi1_ctxtdata *uctxt = fd->uctxt; /* make sure that the context has already been setup */ if (!test_bit(HFI1_CTXT_SETUP_DONE, &uctxt->event_flags)) { @@ -1118,7 +1118,7 @@ static int user_init(struct file *fp) * Subctxts don't need to initialize anything since master * has done it. */ - if (subctxt_fp(fp)) { + if (fd->subctxt) { ret = wait_event_interruptible(uctxt->wait, !test_bit(HFI1_CTXT_MASTER_UNINIT, &uctxt->event_flags)); @@ -1178,8 +1178,8 @@ done: static int get_ctxt_info(struct file *fp, void __user *ubase, __u32 len) { struct hfi1_ctxt_info cinfo; - struct hfi1_ctxtdata *uctxt = ctxt_fp(fp); struct hfi1_filedata *fd = fp->private_data; + struct hfi1_ctxtdata *uctxt = fd->uctxt; int ret = 0; memset(&cinfo, 0, sizeof(cinfo)); @@ -1189,7 +1189,7 @@ static int get_ctxt_info(struct file *fp, void __user *ubase, __u32 len) cinfo.num_active = hfi1_count_active_units(); cinfo.unit = uctxt->dd->unit; cinfo.ctxt = uctxt->ctxt; - cinfo.subctxt = subctxt_fp(fp); + cinfo.subctxt = fd->subctxt; cinfo.rcvtids = roundup(uctxt->egrbufs.alloced, uctxt->dd->rcv_entries.group_size) + uctxt->expected_count; @@ -1201,10 +1201,10 @@ static int get_ctxt_info(struct file *fp, void __user *ubase, __u32 len) cinfo.egrtids = uctxt->egrbufs.alloced; cinfo.rcvhdrq_cnt = uctxt->rcvhdrq_cnt; cinfo.rcvhdrq_entsize = uctxt->rcvhdrqentsize << 2; - cinfo.sdma_ring_size = user_sdma_comp_fp(fp)->nentries; + cinfo.sdma_ring_size = fd->cq->nentries; cinfo.rcvegr_size = uctxt->egrbufs.rcvtid_size; - trace_hfi1_ctxt_info(uctxt->dd, uctxt->ctxt, subctxt_fp(fp), cinfo); + trace_hfi1_ctxt_info(uctxt->dd, uctxt->ctxt, fd->subctxt, cinfo); if (copy_to_user(ubase, &cinfo, sizeof(cinfo))) ret = -EFAULT; done: @@ -1213,7 +1213,8 @@ done: static int setup_ctxt(struct file *fp) { - struct hfi1_ctxtdata *uctxt = ctxt_fp(fp); + struct hfi1_filedata *fd = fp->private_data; + struct hfi1_ctxtdata *uctxt = fd->uctxt; struct hfi1_devdata *dd = uctxt->dd; int ret = 0; @@ -1222,7 +1223,7 @@ static int setup_ctxt(struct file *fp) * programming of eager buffers. This is done if context sharing * is not requested or by the master process. */ - if (!uctxt->subctxt_cnt || !subctxt_fp(fp)) { + if (!uctxt->subctxt_cnt || !fd->subctxt) { ret = hfi1_init_ctxt(uctxt->sc); if (ret) goto done; @@ -1234,7 +1235,7 @@ static int setup_ctxt(struct file *fp) ret = hfi1_setup_eagerbufs(uctxt); if (ret) goto done; - if (uctxt->subctxt_cnt && !subctxt_fp(fp)) { + if (uctxt->subctxt_cnt && !fd->subctxt) { ret = setup_subctxt(uctxt); if (ret) goto done; @@ -1277,7 +1278,7 @@ static int setup_ctxt(struct file *fp) uctxt->tidusemap[uctxt->tidmapcnt - 1] = ~((1ULL << (uctxt->numtidgroups % BITS_PER_LONG)) - 1); - trace_hfi1_exp_tid_map(uctxt->ctxt, subctxt_fp(fp), 0, + trace_hfi1_exp_tid_map(uctxt->ctxt, fd->subctxt, 0, uctxt->tidusemap, uctxt->tidmapcnt); } ret = hfi1_user_sdma_alloc_queues(uctxt, fp); @@ -1292,7 +1293,8 @@ done: static int get_base_info(struct file *fp, void __user *ubase, __u32 len) { struct hfi1_base_info binfo; - struct hfi1_ctxtdata *uctxt = ctxt_fp(fp); + struct hfi1_filedata *fd = fp->private_data; + struct hfi1_ctxtdata *uctxt = fd->uctxt; struct hfi1_devdata *dd = uctxt->dd; ssize_t sz; unsigned offset; @@ -1314,50 +1316,50 @@ static int get_base_info(struct file *fp, void __user *ubase, __u32 len) offset = ((u64)uctxt->sc->hw_free - (u64)dd->cr_base[uctxt->numa_id].va) % PAGE_SIZE; binfo.sc_credits_addr = HFI1_MMAP_TOKEN(PIO_CRED, uctxt->ctxt, - subctxt_fp(fp), offset); + fd->subctxt, offset); binfo.pio_bufbase = HFI1_MMAP_TOKEN(PIO_BUFS, uctxt->ctxt, - subctxt_fp(fp), + fd->subctxt, uctxt->sc->base_addr); binfo.pio_bufbase_sop = HFI1_MMAP_TOKEN(PIO_BUFS_SOP, uctxt->ctxt, - subctxt_fp(fp), + fd->subctxt, uctxt->sc->base_addr); binfo.rcvhdr_bufbase = HFI1_MMAP_TOKEN(RCV_HDRQ, uctxt->ctxt, - subctxt_fp(fp), + fd->subctxt, uctxt->rcvhdrq); binfo.rcvegr_bufbase = HFI1_MMAP_TOKEN(RCV_EGRBUF, uctxt->ctxt, - subctxt_fp(fp), + fd->subctxt, uctxt->egrbufs.rcvtids[0].phys); binfo.sdma_comp_bufbase = HFI1_MMAP_TOKEN(SDMA_COMP, uctxt->ctxt, - subctxt_fp(fp), 0); + fd->subctxt, 0); /* * user regs are at * (RXE_PER_CONTEXT_USER + (ctxt * RXE_PER_CONTEXT_SIZE)) */ binfo.user_regbase = HFI1_MMAP_TOKEN(UREGS, uctxt->ctxt, - subctxt_fp(fp), 0); + fd->subctxt, 0); offset = offset_in_page((((uctxt->ctxt - dd->first_user_ctxt) * - HFI1_MAX_SHARED_CTXTS) + subctxt_fp(fp)) * + HFI1_MAX_SHARED_CTXTS) + fd->subctxt) * sizeof(*dd->events)); binfo.events_bufbase = HFI1_MMAP_TOKEN(EVENTS, uctxt->ctxt, - subctxt_fp(fp), + fd->subctxt, offset); binfo.status_bufbase = HFI1_MMAP_TOKEN(STATUS, uctxt->ctxt, - subctxt_fp(fp), + fd->subctxt, dd->status); if (HFI1_CAP_IS_USET(DMA_RTAIL)) binfo.rcvhdrtail_base = HFI1_MMAP_TOKEN(RTAIL, uctxt->ctxt, - subctxt_fp(fp), 0); + fd->subctxt, 0); if (uctxt->subctxt_cnt) { binfo.subctxt_uregbase = HFI1_MMAP_TOKEN(SUBCTXT_UREGS, uctxt->ctxt, - subctxt_fp(fp), 0); + fd->subctxt, 0); binfo.subctxt_rcvhdrbuf = HFI1_MMAP_TOKEN(SUBCTXT_RCV_HDRQ, uctxt->ctxt, - subctxt_fp(fp), 0); + fd->subctxt, 0); binfo.subctxt_rcvegrbuf = HFI1_MMAP_TOKEN(SUBCTXT_EGRBUF, uctxt->ctxt, - subctxt_fp(fp), 0); + fd->subctxt, 0); } sz = (len < sizeof(binfo)) ? len : sizeof(binfo); if (copy_to_user(ubase, &binfo, sz)) @@ -1368,7 +1370,8 @@ static int get_base_info(struct file *fp, void __user *ubase, __u32 len) static unsigned int poll_urgent(struct file *fp, struct poll_table_struct *pt) { - struct hfi1_ctxtdata *uctxt = ctxt_fp(fp); + struct hfi1_filedata *fd = fp->private_data; + struct hfi1_ctxtdata *uctxt = fd->uctxt; struct hfi1_devdata *dd = uctxt->dd; unsigned pollflag; @@ -1390,7 +1393,8 @@ static unsigned int poll_urgent(struct file *fp, static unsigned int poll_next(struct file *fp, struct poll_table_struct *pt) { - struct hfi1_ctxtdata *uctxt = ctxt_fp(fp); + struct hfi1_filedata *fd = fp->private_data; + struct hfi1_ctxtdata *uctxt = fd->uctxt; struct hfi1_devdata *dd = uctxt->dd; unsigned pollflag; @@ -1562,7 +1566,8 @@ static inline unsigned num_free_groups(unsigned long map, u16 *start) static int exp_tid_setup(struct file *fp, struct hfi1_tid_info *tinfo) { int ret = 0; - struct hfi1_ctxtdata *uctxt = ctxt_fp(fp); + struct hfi1_filedata *fd = fp->private_data; + struct hfi1_ctxtdata *uctxt = fd->uctxt; struct hfi1_devdata *dd = uctxt->dd; unsigned tid, mapped = 0, npages, ngroups, exp_groups, tidpairs = uctxt->expected_count / 2; @@ -1718,7 +1723,7 @@ static int exp_tid_setup(struct file *fp, struct hfi1_tid_info *tinfo) pages[pmapped], 0, tidsize, PCI_DMA_FROMDEVICE); trace_hfi1_exp_rcv_set(uctxt->ctxt, - subctxt_fp(fp), + fd->subctxt, tid, vaddr, phys[pmapped], pages[pmapped]); @@ -1763,7 +1768,7 @@ static int exp_tid_setup(struct file *fp, struct hfi1_tid_info *tinfo) (((useidx & 0xffffff) << 16) | ((bitidx + bits_used) & 0xffffff))); } - trace_hfi1_exp_tid_map(uctxt->ctxt, subctxt_fp(fp), 0, uctxt->tidusemap, + trace_hfi1_exp_tid_map(uctxt->ctxt, fd->subctxt, 0, uctxt->tidusemap, uctxt->tidmapcnt); done: @@ -1792,7 +1797,8 @@ bail: static int exp_tid_free(struct file *fp, struct hfi1_tid_info *tinfo) { - struct hfi1_ctxtdata *uctxt = ctxt_fp(fp); + struct hfi1_filedata *fd = fp->private_data; + struct hfi1_ctxtdata *uctxt = fd->uctxt; struct hfi1_devdata *dd = uctxt->dd; unsigned long tidmap[uctxt->tidmapcnt]; struct page **pages; @@ -1828,7 +1834,7 @@ static int exp_tid_free(struct file *fp, struct hfi1_tid_info *tinfo) hfi1_put_tid(dd, tid, PT_INVALID, 0, 0); trace_hfi1_exp_rcv_free(uctxt->ctxt, - subctxt_fp(fp), + fd->subctxt, tid, phys[i], pages[i]); pci_unmap_page(dd->pcidev, phys[i], @@ -1845,7 +1851,7 @@ static int exp_tid_free(struct file *fp, struct hfi1_tid_info *tinfo) map &= ~(1ULL<ctxt, subctxt_fp(fp), 1, uctxt->tidusemap, + trace_hfi1_exp_tid_map(uctxt->ctxt, fd->subctxt, 1, uctxt->tidusemap, uctxt->tidmapcnt); done: return ret; diff --git a/drivers/staging/rdma/hfi1/hfi.h b/drivers/staging/rdma/hfi1/hfi.h index 73bd966f9e417..31c11852d4c02 100644 --- a/drivers/staging/rdma/hfi1/hfi.h +++ b/drivers/staging/rdma/hfi1/hfi.h @@ -1423,18 +1423,6 @@ int snoop_send_pio_handler(struct hfi1_qp *qp, struct ahg_ib_header *ibhdr, void snoop_inline_pio_send(struct hfi1_devdata *dd, struct pio_buf *pbuf, u64 pbc, const void *from, size_t count); -/* for use in system calls, where we want to know device type, etc. */ -#define ctxt_fp(fp) \ - (((struct hfi1_filedata *)(fp)->private_data)->uctxt) -#define subctxt_fp(fp) \ - (((struct hfi1_filedata *)(fp)->private_data)->subctxt) -#define tidcursor_fp(fp) \ - (((struct hfi1_filedata *)(fp)->private_data)->tidcursor) -#define user_sdma_pkt_fp(fp) \ - (((struct hfi1_filedata *)(fp)->private_data)->pq) -#define user_sdma_comp_fp(fp) \ - (((struct hfi1_filedata *)(fp)->private_data)->cq) - static inline struct hfi1_devdata *dd_from_ppd(struct hfi1_pportdata *ppd) { return ppd->dd; diff --git a/drivers/staging/rdma/hfi1/user_sdma.c b/drivers/staging/rdma/hfi1/user_sdma.c index 36c838dcf0235..be7a4e53335fe 100644 --- a/drivers/staging/rdma/hfi1/user_sdma.c +++ b/drivers/staging/rdma/hfi1/user_sdma.c @@ -352,6 +352,7 @@ static void sdma_kmem_cache_ctor(void *obj) int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, struct file *fp) { + struct hfi1_filedata *fd; int ret = 0; unsigned memsize; char buf[64]; @@ -365,6 +366,8 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, struct file *fp) goto done; } + fd = fp->private_data; + if (!hfi1_sdma_comp_ring_size) { ret = -EINVAL; goto done; @@ -384,7 +387,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, struct file *fp) INIT_LIST_HEAD(&pq->list); pq->dd = dd; pq->ctxt = uctxt->ctxt; - pq->subctxt = subctxt_fp(fp); + pq->subctxt = fd->subctxt; pq->n_max_reqs = hfi1_sdma_comp_ring_size; pq->state = SDMA_PKT_Q_INACTIVE; atomic_set(&pq->n_reqs, 0); @@ -393,7 +396,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, struct file *fp) activate_packet_queue); pq->reqidx = 0; snprintf(buf, 64, "txreq-kmem-cache-%u-%u-%u", dd->unit, uctxt->ctxt, - subctxt_fp(fp)); + fd->subctxt); pq->txreq_cache = kmem_cache_create(buf, sizeof(struct user_sdma_txreq), L1_CACHE_BYTES, @@ -404,7 +407,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, struct file *fp) uctxt->ctxt); goto pq_txreq_nomem; } - user_sdma_pkt_fp(fp) = pq; + fd->pq = pq; cq = kzalloc(sizeof(*cq), GFP_KERNEL); if (!cq) goto cq_nomem; @@ -416,7 +419,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, struct file *fp) goto cq_comps_nomem; cq->nentries = hfi1_sdma_comp_ring_size; - user_sdma_comp_fp(fp) = cq; + fd->cq = cq; spin_lock_irqsave(&uctxt->sdma_qlock, flags); list_add(&pq->list, &uctxt->sdma_queues); @@ -431,7 +434,7 @@ pq_txreq_nomem: kfree(pq->reqs); pq_reqs_nomem: kfree(pq); - user_sdma_pkt_fp(fp) = NULL; + fd->pq = NULL; pq_nomem: ret = -ENOMEM; done: @@ -485,9 +488,10 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, unsigned long dim, unsigned long *count) { int ret = 0, i = 0, sent; - struct hfi1_ctxtdata *uctxt = ctxt_fp(fp); - struct hfi1_user_sdma_pkt_q *pq = user_sdma_pkt_fp(fp); - struct hfi1_user_sdma_comp_q *cq = user_sdma_comp_fp(fp); + struct hfi1_filedata *fd = fp->private_data; + struct hfi1_ctxtdata *uctxt = fd->uctxt; + struct hfi1_user_sdma_pkt_q *pq = fd->pq; + struct hfi1_user_sdma_comp_q *cq = fd->cq; struct hfi1_devdata *dd = pq->dd; unsigned long idx = 0; u8 pcount = initial_pkt_count; @@ -499,7 +503,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, hfi1_cdbg( SDMA, "[%u:%u:%u] First vector not big enough for header %lu/%lu", - dd->unit, uctxt->ctxt, subctxt_fp(fp), + dd->unit, uctxt->ctxt, fd->subctxt, iovec[idx].iov_len, sizeof(info) + sizeof(req->hdr)); ret = -EINVAL; goto done; @@ -507,15 +511,15 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, ret = copy_from_user(&info, iovec[idx].iov_base, sizeof(info)); if (ret) { hfi1_cdbg(SDMA, "[%u:%u:%u] Failed to copy info QW (%d)", - dd->unit, uctxt->ctxt, subctxt_fp(fp), ret); + dd->unit, uctxt->ctxt, fd->subctxt, ret); ret = -EFAULT; goto done; } - trace_hfi1_sdma_user_reqinfo(dd, uctxt->ctxt, subctxt_fp(fp), + trace_hfi1_sdma_user_reqinfo(dd, uctxt->ctxt, fd->subctxt, (u16 *)&info); if (cq->comps[info.comp_idx].status == QUEUED) { hfi1_cdbg(SDMA, "[%u:%u:%u] Entry %u is in QUEUED state", - dd->unit, uctxt->ctxt, subctxt_fp(fp), + dd->unit, uctxt->ctxt, fd->subctxt, info.comp_idx); ret = -EBADSLT; goto done; @@ -523,7 +527,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, if (!info.fragsize) { hfi1_cdbg(SDMA, "[%u:%u:%u:%u] Request does not specify fragsize", - dd->unit, uctxt->ctxt, subctxt_fp(fp), info.comp_idx); + dd->unit, uctxt->ctxt, fd->subctxt, info.comp_idx); ret = -EINVAL; goto done; } @@ -532,7 +536,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, * "allocate" the request entry. */ hfi1_cdbg(SDMA, "[%u:%u:%u] Using req/comp entry %u\n", dd->unit, - uctxt->ctxt, subctxt_fp(fp), info.comp_idx); + uctxt->ctxt, fd->subctxt, info.comp_idx); req = pq->reqs + info.comp_idx; memset(req, 0, sizeof(*req)); /* Mark the request as IN_USE before we start filling it in. */ @@ -659,7 +663,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, /* Have to select the engine */ req->sde = sdma_select_engine_vl(dd, - (u32)(uctxt->ctxt + subctxt_fp(fp)), + (u32)(uctxt->ctxt + fd->subctxt), vl); if (!req->sde || !sdma_running(req->sde)) { ret = -ECOMM; -- GitLab From 3bd4dce1366fefe6575b841816e595f54e8e9752 Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Fri, 30 Oct 2015 18:58:41 -0400 Subject: [PATCH 0374/2855] staging/rdma/hfi1: Clean up macro indentation In preparation for implementing Expected TID caching we do some simple clean up of header file macros. Signed-off-by: Mitko Haralanov Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/common.h | 15 ++++++++------- include/uapi/rdma/hfi/hfi1_user.h | 26 +++++++++++++------------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/drivers/staging/rdma/hfi1/common.h b/drivers/staging/rdma/hfi1/common.h index 5e203239c5b04..5dd92720faae2 100644 --- a/drivers/staging/rdma/hfi1/common.h +++ b/drivers/staging/rdma/hfi1/common.h @@ -132,13 +132,14 @@ * HFI1_CAP_RESERVED_MASK bits. */ #define HFI1_CAP_WRITABLE_MASK (HFI1_CAP_SDMA_AHG | \ - HFI1_CAP_HDRSUPP | \ - HFI1_CAP_MULTI_PKT_EGR | \ - HFI1_CAP_NODROP_RHQ_FULL | \ - HFI1_CAP_NODROP_EGR_FULL | \ - HFI1_CAP_ALLOW_PERM_JKEY | \ - HFI1_CAP_STATIC_RATE_CTRL | \ - HFI1_CAP_PRINT_UNIMPL) + HFI1_CAP_HDRSUPP | \ + HFI1_CAP_MULTI_PKT_EGR | \ + HFI1_CAP_NODROP_RHQ_FULL | \ + HFI1_CAP_NODROP_EGR_FULL | \ + HFI1_CAP_ALLOW_PERM_JKEY | \ + HFI1_CAP_STATIC_RATE_CTRL | \ + HFI1_CAP_PRINT_UNIMPL | \ + HFI1_CAP_TID_UNMAP) /* * A set of capability bits that are "global" and are not allowed to be * set in the user bitmask. diff --git a/include/uapi/rdma/hfi/hfi1_user.h b/include/uapi/rdma/hfi/hfi1_user.h index 599562fe5d574..a2fc6cbfe4141 100644 --- a/include/uapi/rdma/hfi/hfi1_user.h +++ b/include/uapi/rdma/hfi/hfi1_user.h @@ -127,13 +127,13 @@ #define HFI1_CMD_TID_UPDATE 4 /* update expected TID entries */ #define HFI1_CMD_TID_FREE 5 /* free expected TID entries */ #define HFI1_CMD_CREDIT_UPD 6 /* force an update of PIO credit */ -#define HFI1_CMD_SDMA_STATUS_UPD 7 /* force update of SDMA status ring */ +#define HFI1_CMD_SDMA_STATUS_UPD 7 /* force update of SDMA status ring */ #define HFI1_CMD_RECV_CTRL 8 /* control receipt of packets */ #define HFI1_CMD_POLL_TYPE 9 /* set the kind of polling we want */ #define HFI1_CMD_ACK_EVENT 10 /* ack & clear user status bits */ -#define HFI1_CMD_SET_PKEY 11 /* set context's pkey */ -#define HFI1_CMD_CTXT_RESET 12 /* reset context's HW send context */ +#define HFI1_CMD_SET_PKEY 11 /* set context's pkey */ +#define HFI1_CMD_CTXT_RESET 12 /* reset context's HW send context */ /* separate EPROM commands from normal PSM commands */ #define HFI1_CMD_EP_INFO 64 /* read EPROM device ID */ #define HFI1_CMD_EP_ERASE_CHIP 65 /* erase whole EPROM */ @@ -144,18 +144,18 @@ #define HFI1_CMD_EP_WRITE_P0 70 /* write EPROM partition 0 */ #define HFI1_CMD_EP_WRITE_P1 71 /* write EPROM partition 1 */ -#define _HFI1_EVENT_FROZEN_BIT 0 -#define _HFI1_EVENT_LINKDOWN_BIT 1 -#define _HFI1_EVENT_LID_CHANGE_BIT 2 -#define _HFI1_EVENT_LMC_CHANGE_BIT 3 -#define _HFI1_EVENT_SL2VL_CHANGE_BIT 4 +#define _HFI1_EVENT_FROZEN_BIT 0 +#define _HFI1_EVENT_LINKDOWN_BIT 1 +#define _HFI1_EVENT_LID_CHANGE_BIT 2 +#define _HFI1_EVENT_LMC_CHANGE_BIT 3 +#define _HFI1_EVENT_SL2VL_CHANGE_BIT 4 #define _HFI1_MAX_EVENT_BIT _HFI1_EVENT_SL2VL_CHANGE_BIT -#define HFI1_EVENT_FROZEN (1UL << _HFI1_EVENT_FROZEN_BIT) -#define HFI1_EVENT_LINKDOWN_BIT (1UL << _HFI1_EVENT_LINKDOWN_BIT) -#define HFI1_EVENT_LID_CHANGE_BIT (1UL << _HFI1_EVENT_LID_CHANGE_BIT) -#define HFI1_EVENT_LMC_CHANGE_BIT (1UL << _HFI1_EVENT_LMC_CHANGE_BIT) -#define HFI1_EVENT_SL2VL_CHANGE_BIT (1UL << _HFI1_EVENT_SL2VL_CHANGE_BIT) +#define HFI1_EVENT_FROZEN (1UL << _HFI1_EVENT_FROZEN_BIT) +#define HFI1_EVENT_LINKDOWN (1UL << _HFI1_EVENT_LINKDOWN_BIT) +#define HFI1_EVENT_LID_CHANGE (1UL << _HFI1_EVENT_LID_CHANGE_BIT) +#define HFI1_EVENT_LMC_CHANGE (1UL << _HFI1_EVENT_LMC_CHANGE_BIT) +#define HFI1_EVENT_SL2VL_CHANGE (1UL << _HFI1_EVENT_SL2VL_CHANGE_BIT) /* * These are the status bits readable (in ASCII form, 64bit value) -- GitLab From 49efd866193253f8b0322b73791b473e8e4eb688 Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Fri, 30 Oct 2015 18:58:42 -0400 Subject: [PATCH 0375/2855] staging/rdma/hfi1: Remove unnecessary include files These includes were not used in file_ops.c Signed-off-by: Mitko Haralanov Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/file_ops.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/staging/rdma/hfi1/file_ops.c b/drivers/staging/rdma/hfi1/file_ops.c index f78bcf673252c..b8aeef0e0d392 100644 --- a/drivers/staging/rdma/hfi1/file_ops.c +++ b/drivers/staging/rdma/hfi1/file_ops.c @@ -47,20 +47,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ -#include #include #include -#include #include -#include #include -#include -#include -#include -#include -#include -#include -#include #include "hfi.h" #include "pio.h" -- GitLab From 701e441d82689c21afd699b229d338783f3463b1 Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Fri, 30 Oct 2015 18:58:43 -0400 Subject: [PATCH 0376/2855] staging/rdma/hfi1: Move macros to a common header In preparation of implementing TID caching move EXP_TID macros to a common header user_exp_rcv.h Signed-off-by: Mitko Haralanov Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/file_ops.c | 13 +---- drivers/staging/rdma/hfi1/user_exp_rcv.h | 74 ++++++++++++++++++++++++ drivers/staging/rdma/hfi1/user_sdma.h | 10 +--- 3 files changed, 76 insertions(+), 21 deletions(-) create mode 100644 drivers/staging/rdma/hfi1/user_exp_rcv.h diff --git a/drivers/staging/rdma/hfi1/file_ops.c b/drivers/staging/rdma/hfi1/file_ops.c index b8aeef0e0d392..3b15eb4d5bf9c 100644 --- a/drivers/staging/rdma/hfi1/file_ops.c +++ b/drivers/staging/rdma/hfi1/file_ops.c @@ -58,6 +58,7 @@ #include "common.h" #include "trace.h" #include "user_sdma.h" +#include "user_exp_rcv.h" #include "eprom.h" #undef pr_fmt @@ -160,18 +161,6 @@ enum mmap_types { HFI1_MMAP_TOKEN_SET(SUBCTXT, subctxt) | \ HFI1_MMAP_TOKEN_SET(OFFSET, (offset_in_page(addr)))) -#define EXP_TID_SET(field, value) \ - (((value) & EXP_TID_TID##field##_MASK) << \ - EXP_TID_TID##field##_SHIFT) -#define EXP_TID_CLEAR(tid, field) { \ - (tid) &= ~(EXP_TID_TID##field##_MASK << \ - EXP_TID_TID##field##_SHIFT); \ - } -#define EXP_TID_RESET(tid, field, value) do { \ - EXP_TID_CLEAR(tid, field); \ - (tid) |= EXP_TID_SET(field, value); \ - } while (0) - #define dbg(fmt, ...) \ pr_info(fmt, ##__VA_ARGS__) diff --git a/drivers/staging/rdma/hfi1/user_exp_rcv.h b/drivers/staging/rdma/hfi1/user_exp_rcv.h new file mode 100644 index 0000000000000..4f4876e1d3537 --- /dev/null +++ b/drivers/staging/rdma/hfi1/user_exp_rcv.h @@ -0,0 +1,74 @@ +#ifndef _HFI1_USER_EXP_RCV_H +#define _HFI1_USER_EXP_RCV_H +/* + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2015 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * BSD LICENSE + * + * Copyright(c) 2015 Intel Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#define EXP_TID_TIDLEN_MASK 0x7FFULL +#define EXP_TID_TIDLEN_SHIFT 0 +#define EXP_TID_TIDCTRL_MASK 0x3ULL +#define EXP_TID_TIDCTRL_SHIFT 20 +#define EXP_TID_TIDIDX_MASK 0x3FFULL +#define EXP_TID_TIDIDX_SHIFT 22 +#define EXP_TID_GET(tid, field) \ + (((tid) >> EXP_TID_TID##field##_SHIFT) & EXP_TID_TID##field##_MASK) + +#define EXP_TID_SET(field, value) \ + (((value) & EXP_TID_TID##field##_MASK) << \ + EXP_TID_TID##field##_SHIFT) +#define EXP_TID_CLEAR(tid, field) ({ \ + (tid) &= ~(EXP_TID_TID##field##_MASK << \ + EXP_TID_TID##field##_SHIFT); \ + }) +#define EXP_TID_RESET(tid, field, value) do { \ + EXP_TID_CLEAR(tid, field); \ + (tid) |= EXP_TID_SET(field, (value)); \ + } while (0) + +#endif /* _HFI1_USER_EXP_RCV_H */ diff --git a/drivers/staging/rdma/hfi1/user_sdma.h b/drivers/staging/rdma/hfi1/user_sdma.h index fa4422553e23c..0046ffa774fef 100644 --- a/drivers/staging/rdma/hfi1/user_sdma.h +++ b/drivers/staging/rdma/hfi1/user_sdma.h @@ -52,15 +52,7 @@ #include "common.h" #include "iowait.h" - -#define EXP_TID_TIDLEN_MASK 0x7FFULL -#define EXP_TID_TIDLEN_SHIFT 0 -#define EXP_TID_TIDCTRL_MASK 0x3ULL -#define EXP_TID_TIDCTRL_SHIFT 20 -#define EXP_TID_TIDIDX_MASK 0x7FFULL -#define EXP_TID_TIDIDX_SHIFT 22 -#define EXP_TID_GET(tid, field) \ - (((tid) >> EXP_TID_TID##field##_SHIFT) & EXP_TID_TID##field##_MASK) +#include "user_exp_rcv.h" extern uint extended_psn; -- GitLab From 3e7ccca08dbe46665ca432d09a5472d80aaadb6f Mon Sep 17 00:00:00 2001 From: Arthur Kepner Date: Wed, 4 Nov 2015 21:10:09 -0500 Subject: [PATCH 0377/2855] staging/rdma/hfi1: don't cache "prescan head" When HFI1_CAP_DMA_RTAIL is toggled off the "prescan head" can get out of sync with the receive context's "head". This happens when, after prescan_rxq() newly arrived packets are then received, and processed by an RX interrupt handler. This is an unavoidable race, and to avoid getting out of sync we always start prescanning at the current "rcd->head" entry. Reviewed-by: Mike Marciniszyn Reviewed-by: Dennis Dalessandro Signed-off-by: Arthur Kepner Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/driver.c | 13 +++---------- drivers/staging/rdma/hfi1/hfi.h | 13 ------------- 2 files changed, 3 insertions(+), 23 deletions(-) diff --git a/drivers/staging/rdma/hfi1/driver.c b/drivers/staging/rdma/hfi1/driver.c index ce69141b56cb0..cfcbe417fde98 100644 --- a/drivers/staging/rdma/hfi1/driver.c +++ b/drivers/staging/rdma/hfi1/driver.c @@ -509,14 +509,10 @@ static inline void init_ps_mdata(struct ps_mdata *mdata, mdata->rsize = packet->rsize; mdata->maxcnt = packet->maxcnt; - if (rcd->ps_state.initialized == 0) { - mdata->ps_head = packet->rhqoff; - rcd->ps_state.initialized++; - } else - mdata->ps_head = rcd->ps_state.ps_head; + mdata->ps_head = packet->rhqoff; if (HFI1_CAP_IS_KSET(DMA_RTAIL)) { - mdata->ps_tail = packet->hdrqtail; + mdata->ps_tail = get_rcvhdrtail(rcd); mdata->ps_seq = 0; /* not used with DMA_RTAIL */ } else { mdata->ps_tail = 0; /* used only with DMA_RTAIL*/ @@ -533,12 +529,9 @@ static inline int ps_done(struct ps_mdata *mdata, u64 rhf) static inline void update_ps_mdata(struct ps_mdata *mdata) { - struct hfi1_ctxtdata *rcd = mdata->rcd; - mdata->ps_head += mdata->rsize; - if (mdata->ps_head > mdata->maxcnt) + if (mdata->ps_head >= mdata->maxcnt) mdata->ps_head = 0; - rcd->ps_state.ps_head = mdata->ps_head; if (!HFI1_CAP_IS_KSET(DMA_RTAIL)) { if (++mdata->ps_seq > 13) mdata->ps_seq = 1; diff --git a/drivers/staging/rdma/hfi1/hfi.h b/drivers/staging/rdma/hfi1/hfi.h index 31c11852d4c02..70891fbf89b05 100644 --- a/drivers/staging/rdma/hfi1/hfi.h +++ b/drivers/staging/rdma/hfi1/hfi.h @@ -139,15 +139,6 @@ extern const struct pci_error_handlers hfi1_pci_err_handler; struct hfi1_opcode_stats_perctx; #endif -/* - * struct ps_state keeps state associated with RX queue "prescanning" - * (prescanning for FECNs, and BECNs), if prescanning is in use. - */ -struct ps_state { - u32 ps_head; - int initialized; -}; - struct ctxt_eager_bufs { ssize_t size; /* total size of eager buffers */ u32 count; /* size of buffers array */ @@ -302,10 +293,6 @@ struct hfi1_ctxtdata { struct list_head sdma_queues; spinlock_t sdma_qlock; -#ifdef CONFIG_PRESCAN_RXQ - struct ps_state ps_state; -#endif /* CONFIG_PRESCAN_RXQ */ - /* * The interrupt handler for a particular receive context can vary * throughout it's lifetime. This is not a lock protected data member so -- GitLab From 977940b85e3c3b6b5b8ffbc1235b23e35284382f Mon Sep 17 00:00:00 2001 From: Arthur Kepner Date: Wed, 4 Nov 2015 21:10:10 -0500 Subject: [PATCH 0378/2855] staging/rdma/hfi1: optionally prescan rx queue for {B, F}ECNs - UC, RC To more rapidly respond to Explicit Congestion Notifications, prescan the receive queue, and process FECNs, and BECNs first. When a UC, or RC packet containing a FECN, or BECN is found, immediately react to the ECN (either by returning a CNP, or adjusting the injection rate). Afterward, the packet will be processed normally. Reviewed-by: Mike Marciniszyn Reviewed-by: Dennis Dalessandro Signed-off-by: Arthur Kepner Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/driver.c | 64 +++++++++++++++--------------- drivers/staging/rdma/hfi1/rc.c | 10 ++--- drivers/staging/rdma/hfi1/uc.c | 15 ++++--- drivers/staging/rdma/hfi1/verbs.c | 41 ++++++++++++++++--- 4 files changed, 81 insertions(+), 49 deletions(-) diff --git a/drivers/staging/rdma/hfi1/driver.c b/drivers/staging/rdma/hfi1/driver.c index cfcbe417fde98..9a4ec09af0201 100644 --- a/drivers/staging/rdma/hfi1/driver.c +++ b/drivers/staging/rdma/hfi1/driver.c @@ -436,59 +436,58 @@ static inline void init_packet(struct hfi1_ctxtdata *rcd, #ifndef CONFIG_PRESCAN_RXQ static void prescan_rxq(struct hfi1_packet *packet) {} -#else /* CONFIG_PRESCAN_RXQ */ +#else /* !CONFIG_PRESCAN_RXQ */ static int prescan_receive_queue; static void process_ecn(struct hfi1_qp *qp, struct hfi1_ib_header *hdr, struct hfi1_other_headers *ohdr, - u64 rhf, struct ib_grh *grh) + u64 rhf, u32 bth1, struct ib_grh *grh) { struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); - u32 bth1; + u32 rqpn = 0; + u16 rlid; u8 sc5, svc_type; - int is_fecn, is_becn; switch (qp->ibqp.qp_type) { + case IB_QPT_SMI: + case IB_QPT_GSI: case IB_QPT_UD: + rlid = be16_to_cpu(hdr->lrh[3]); + rqpn = be32_to_cpu(ohdr->u.ud.deth[1]) & HFI1_QPN_MASK; svc_type = IB_CC_SVCTYPE_UD; break; - case IB_QPT_UC: /* LATER */ - case IB_QPT_RC: /* LATER */ + case IB_QPT_UC: + rlid = qp->remote_ah_attr.dlid; + rqpn = qp->remote_qpn; + svc_type = IB_CC_SVCTYPE_UC; + break; + case IB_QPT_RC: + rlid = qp->remote_ah_attr.dlid; + rqpn = qp->remote_qpn; + svc_type = IB_CC_SVCTYPE_RC; + break; default: return; } - is_fecn = (be32_to_cpu(ohdr->bth[1]) >> HFI1_FECN_SHIFT) & - HFI1_FECN_MASK; - is_becn = (be32_to_cpu(ohdr->bth[1]) >> HFI1_BECN_SHIFT) & - HFI1_BECN_MASK; - sc5 = (be16_to_cpu(hdr->lrh[0]) >> 12) & 0xf; if (rhf_dc_info(rhf)) sc5 |= 0x10; - if (is_fecn) { - u32 src_qpn = be32_to_cpu(ohdr->u.ud.deth[1]) & HFI1_QPN_MASK; + if (bth1 & HFI1_FECN_SMASK) { u16 pkey = (u16)be32_to_cpu(ohdr->bth[0]); u16 dlid = be16_to_cpu(hdr->lrh[1]); - u16 slid = be16_to_cpu(hdr->lrh[3]); - return_cnp(ibp, qp, src_qpn, pkey, dlid, slid, sc5, grh); + return_cnp(ibp, qp, rqpn, pkey, dlid, rlid, sc5, grh); } - if (is_becn) { + if (bth1 & HFI1_BECN_SMASK) { struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); - u32 lqpn = be32_to_cpu(ohdr->bth[1]) & HFI1_QPN_MASK; + u32 lqpn = bth1 & HFI1_QPN_MASK; u8 sl = ibp->sc_to_sl[sc5]; - process_becn(ppd, sl, 0, lqpn, 0, svc_type); + process_becn(ppd, sl, rlid, lqpn, rqpn, svc_type); } - - /* turn off BECN, or FECN */ - bth1 = be32_to_cpu(ohdr->bth[1]); - bth1 &= ~(HFI1_FECN_MASK << HFI1_FECN_SHIFT); - bth1 &= ~(HFI1_BECN_MASK << HFI1_BECN_SHIFT); - ohdr->bth[1] = cpu_to_be32(bth1); } struct ps_mdata { @@ -508,7 +507,6 @@ static inline void init_ps_mdata(struct ps_mdata *mdata, mdata->rcd = rcd; mdata->rsize = packet->rsize; mdata->maxcnt = packet->maxcnt; - mdata->ps_head = packet->rhqoff; if (HFI1_CAP_IS_KSET(DMA_RTAIL)) { @@ -564,7 +562,7 @@ static void prescan_rxq(struct hfi1_packet *packet) struct hfi1_other_headers *ohdr; struct ib_grh *grh = NULL; u64 rhf = rhf_to_cpu(rhf_addr); - u32 etype = rhf_rcv_type(rhf), qpn; + u32 etype = rhf_rcv_type(rhf), qpn, bth1; int is_ecn = 0; u8 lnh; @@ -586,15 +584,13 @@ static void prescan_rxq(struct hfi1_packet *packet) } else goto next; /* just in case */ - is_ecn |= be32_to_cpu(ohdr->bth[1]) & - (HFI1_FECN_MASK << HFI1_FECN_SHIFT); - is_ecn |= be32_to_cpu(ohdr->bth[1]) & - (HFI1_BECN_MASK << HFI1_BECN_SHIFT); + bth1 = be32_to_cpu(ohdr->bth[1]); + is_ecn = !!(bth1 & (HFI1_FECN_SMASK | HFI1_BECN_SMASK)); if (!is_ecn) goto next; - qpn = be32_to_cpu(ohdr->bth[1]) & HFI1_QPN_MASK; + qpn = bth1 & HFI1_QPN_MASK; rcu_read_lock(); qp = hfi1_lookup_qpn(ibp, qpn); @@ -603,8 +599,12 @@ static void prescan_rxq(struct hfi1_packet *packet) goto next; } - process_ecn(qp, hdr, ohdr, rhf, grh); + process_ecn(qp, hdr, ohdr, rhf, bth1, grh); rcu_read_unlock(); + + /* turn off BECN, FECN */ + bth1 &= ~(HFI1_FECN_SMASK | HFI1_BECN_SMASK); + ohdr->bth[1] = cpu_to_be32(bth1); next: update_ps_mdata(&mdata); } diff --git a/drivers/staging/rdma/hfi1/rc.c b/drivers/staging/rdma/hfi1/rc.c index 5fc93bb312f1b..fd23907f18fed 100644 --- a/drivers/staging/rdma/hfi1/rc.c +++ b/drivers/staging/rdma/hfi1/rc.c @@ -1978,7 +1978,7 @@ void hfi1_rc_rcv(struct hfi1_packet *packet) } psn = be32_to_cpu(ohdr->bth[2]); - opcode = bth0 >> 24; + opcode = (bth0 >> 24) & 0xff; /* * Process responses (ACKs) before anything else. Note that the @@ -2391,19 +2391,19 @@ void hfi1_rc_hdrerr( struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); int diff; u32 opcode; - u32 psn; + u32 psn, bth0; /* Check for GRH */ ohdr = &hdr->u.oth; if (has_grh) ohdr = &hdr->u.l.oth; - opcode = be32_to_cpu(ohdr->bth[0]); - if (hfi1_ruc_check_hdr(ibp, hdr, has_grh, qp, opcode)) + bth0 = be32_to_cpu(ohdr->bth[0]); + if (hfi1_ruc_check_hdr(ibp, hdr, has_grh, qp, bth0)) return; psn = be32_to_cpu(ohdr->bth[2]); - opcode >>= 24; + opcode = (bth0 >> 24) & 0xff; /* Only deal with RDMA Writes for now */ if (opcode < IB_OPCODE_RC_RDMA_READ_RESPONSE_FIRST) { diff --git a/drivers/staging/rdma/hfi1/uc.c b/drivers/staging/rdma/hfi1/uc.c index 6095039c4485a..4f2a7889a8528 100644 --- a/drivers/staging/rdma/hfi1/uc.c +++ b/drivers/staging/rdma/hfi1/uc.c @@ -268,7 +268,7 @@ void hfi1_uc_rcv(struct hfi1_packet *packet) u32 tlen = packet->tlen; struct hfi1_qp *qp = packet->qp; struct hfi1_other_headers *ohdr = packet->ohdr; - u32 opcode; + u32 bth0, opcode; u32 hdrsize = packet->hlen; u32 psn; u32 pad; @@ -278,10 +278,9 @@ void hfi1_uc_rcv(struct hfi1_packet *packet) int has_grh = rcv_flags & HFI1_HAS_GRH; int ret; u32 bth1; - struct ib_grh *grh = NULL; - opcode = be32_to_cpu(ohdr->bth[0]); - if (hfi1_ruc_check_hdr(ibp, hdr, has_grh, qp, opcode)) + bth0 = be32_to_cpu(ohdr->bth[0]); + if (hfi1_ruc_check_hdr(ibp, hdr, has_grh, qp, bth0)) return; bth1 = be32_to_cpu(ohdr->bth[1]); @@ -303,6 +302,7 @@ void hfi1_uc_rcv(struct hfi1_packet *packet) } if (bth1 & HFI1_FECN_SMASK) { + struct ib_grh *grh = NULL; u16 pkey = (u16)be32_to_cpu(ohdr->bth[0]); u16 slid = be16_to_cpu(hdr->lrh[3]); u16 dlid = be16_to_cpu(hdr->lrh[1]); @@ -310,13 +310,16 @@ void hfi1_uc_rcv(struct hfi1_packet *packet) u8 sc5; sc5 = ibp->sl_to_sc[qp->remote_ah_attr.sl]; + if (has_grh) + grh = &hdr->u.l.grh; - return_cnp(ibp, qp, src_qp, pkey, dlid, slid, sc5, grh); + return_cnp(ibp, qp, src_qp, pkey, dlid, slid, sc5, + grh); } } psn = be32_to_cpu(ohdr->bth[2]); - opcode >>= 24; + opcode = (bth0 >> 24) & 0xff; /* Compare the PSN verses the expected PSN. */ if (unlikely(cmp_psn(psn, qp->r_psn) != 0)) { diff --git a/drivers/staging/rdma/hfi1/verbs.c b/drivers/staging/rdma/hfi1/verbs.c index 9beb0aa876f07..ea1d9e6303e2c 100644 --- a/drivers/staging/rdma/hfi1/verbs.c +++ b/drivers/staging/rdma/hfi1/verbs.c @@ -2152,11 +2152,40 @@ void hfi1_schedule_send(struct hfi1_qp *qp) void hfi1_cnp_rcv(struct hfi1_packet *packet) { struct hfi1_ibport *ibp = &packet->rcd->ppd->ibport_data; - - if (packet->qp->ibqp.qp_type == IB_QPT_UC) - hfi1_uc_rcv(packet); - else if (packet->qp->ibqp.qp_type == IB_QPT_UD) - hfi1_ud_rcv(packet); - else + struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); + struct hfi1_ib_header *hdr = packet->hdr; + struct hfi1_qp *qp = packet->qp; + u32 lqpn, rqpn = 0; + u16 rlid = 0; + u8 sl, sc5, sc4_bit, svc_type; + bool sc4_set = has_sc4_bit(packet); + + switch (packet->qp->ibqp.qp_type) { + case IB_QPT_UC: + rlid = qp->remote_ah_attr.dlid; + rqpn = qp->remote_qpn; + svc_type = IB_CC_SVCTYPE_UC; + break; + case IB_QPT_RC: + rlid = qp->remote_ah_attr.dlid; + rqpn = qp->remote_qpn; + svc_type = IB_CC_SVCTYPE_RC; + break; + case IB_QPT_SMI: + case IB_QPT_GSI: + case IB_QPT_UD: + svc_type = IB_CC_SVCTYPE_UD; + break; + default: ibp->n_pkt_drops++; + return; + } + + sc4_bit = sc4_set << 4; + sc5 = (be16_to_cpu(hdr->lrh[0]) >> 12) & 0xf; + sc5 |= sc4_bit; + sl = ibp->sc_to_sl[sc5]; + lqpn = qp->ibqp.qp_num; + + process_becn(ppd, sl, rlid, lqpn, rqpn, svc_type); } -- GitLab From e3a45e4063601336f5759734d65fcee1b73d001f Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Thu, 5 Nov 2015 02:25:58 +0530 Subject: [PATCH 0379/2855] staging: rdma: amso1100: c2: Remove wrapper function This patch removes the c2_print_macaddr() wrapper function which calls the pr_debug standard kernel function only. c2_print_macaddr() has been replaced by directly calling pr_debug(). Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/amso1100/c2.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/staging/rdma/amso1100/c2.c b/drivers/staging/rdma/amso1100/c2.c index 35ac536b2d45d..af043f023c7d0 100644 --- a/drivers/staging/rdma/amso1100/c2.c +++ b/drivers/staging/rdma/amso1100/c2.c @@ -87,11 +87,6 @@ static struct pci_device_id c2_pci_table[] = { MODULE_DEVICE_TABLE(pci, c2_pci_table); -static void c2_print_macaddr(struct net_device *netdev) -{ - pr_debug("%s: MAC %pM, IRQ %u\n", netdev->name, netdev->dev_addr, netdev->irq); -} - static void c2_set_rxbufsize(struct c2_port *c2_port) { struct net_device *netdev = c2_port->netdev; @@ -908,7 +903,8 @@ static struct net_device *c2_devinit(struct c2_dev *c2dev, /* Validate the MAC address */ if (!is_valid_ether_addr(netdev->dev_addr)) { pr_debug("Invalid MAC Address\n"); - c2_print_macaddr(netdev); + pr_debug("%s: MAC %pM, IRQ %u\n", netdev->name, + netdev->dev_addr, netdev->irq); free_netdev(netdev); return NULL; } @@ -1142,7 +1138,8 @@ static int c2_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) } /* Print out the MAC address */ - c2_print_macaddr(netdev); + pr_debug("%s: MAC %pM, IRQ %u\n", netdev->name, netdev->dev_addr, + netdev->irq); ret = c2_rnic_init(c2dev); if (ret) { -- GitLab From cb32649d087d513bb6e0f90dda0a686a6662b519 Mon Sep 17 00:00:00 2001 From: Sunny Kumar Date: Fri, 6 Nov 2015 10:06:43 +0530 Subject: [PATCH 0380/2855] staging: rdma: hfi1 : Prefer using the BIT macro This patch replaces bit shifting on 1 with the BIT(x) macro Signed-off-by: Sunny Kumar Acked-by: Mike Marciniszyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/user_sdma.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rdma/hfi1/user_sdma.c b/drivers/staging/rdma/hfi1/user_sdma.c index be7a4e53335fe..41408f82afe87 100644 --- a/drivers/staging/rdma/hfi1/user_sdma.c +++ b/drivers/staging/rdma/hfi1/user_sdma.c @@ -146,8 +146,8 @@ MODULE_PARM_DESC(sdma_comp_size, "Size of User SDMA completion ring. Default: 12 #define KDETH_OM_MAX_SIZE (1 << ((KDETH_OM_LARGE / KDETH_OM_SMALL) + 1)) /* Last packet in the request */ -#define TXREQ_FLAGS_REQ_LAST_PKT (1 << 0) -#define TXREQ_FLAGS_IOVEC_LAST_PKT (1 << 0) +#define TXREQ_FLAGS_REQ_LAST_PKT BIT(0) +#define TXREQ_FLAGS_IOVEC_LAST_PKT BIT(0) #define SDMA_REQ_IN_USE 0 #define SDMA_REQ_FOR_THREAD 1 @@ -156,9 +156,9 @@ MODULE_PARM_DESC(sdma_comp_size, "Size of User SDMA completion ring. Default: 12 #define SDMA_REQ_HAS_ERROR 4 #define SDMA_REQ_DONE_ERROR 5 -#define SDMA_PKT_Q_INACTIVE (1 << 0) -#define SDMA_PKT_Q_ACTIVE (1 << 1) -#define SDMA_PKT_Q_DEFERRED (1 << 2) +#define SDMA_PKT_Q_INACTIVE BIT(0) +#define SDMA_PKT_Q_ACTIVE BIT(1) +#define SDMA_PKT_Q_DEFERRED BIT(2) /* * Maximum retry attempts to submit a TX request -- GitLab From 5f4179e04b31441b0b7995d14320a457aafba01b Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Thu, 29 Oct 2015 02:54:09 +0200 Subject: [PATCH 0381/2855] staging: lustre: ldlm_extent.c: replace IS_PO2 by is_power_of_2 Replaces IS_PO2 by is_power_of_2. It is more accurate to use is_power_of_2 since it returns 1 for numbers that are powers of 2 only whereas IS_PO2 returns 1 for 0 and numbers that are powers of 2. Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ldlm/ldlm_extent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c b/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c index c787888eb8af4..9c70f31ea56e7 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c @@ -149,7 +149,7 @@ static inline int lock_mode_to_index(ldlm_mode_t mode) int index; LASSERT(mode != 0); - LASSERT(IS_PO2(mode)); + LASSERT(is_power_of_2(mode)); for (index = -1; mode; index++) mode >>= 1; LASSERT(index < LCK_MODE_NUM); -- GitLab From 57b573d14b0fb9f83575a2cf155862d251c8f0d1 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Thu, 29 Oct 2015 02:57:33 +0200 Subject: [PATCH 0382/2855] staging: lustre: workitem.c: replace IS_PO2 by is_power_of_2 Replaces IS_PO2 by is_power_of_2. It is more accurate to use is_power_of_2 since it returns 1 for numbers that are powers of 2 only whereas IS_PO2 returns 1 for 0 and numbers that are powers of 2. Reviewed-by: Andreas Dilger Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/workitem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/libcfs/workitem.c b/drivers/staging/lustre/lustre/libcfs/workitem.c index e1143a566ac4a..268dd6851af4b 100644 --- a/drivers/staging/lustre/lustre/libcfs/workitem.c +++ b/drivers/staging/lustre/lustre/libcfs/workitem.c @@ -325,7 +325,7 @@ cfs_wi_sched_destroy(struct cfs_wi_sched *sched) spin_lock(&cfs_wi_data.wi_glock); while (sched->ws_nthreads > 0) { - CDEBUG(IS_PO2(++i) ? D_WARNING : D_NET, + CDEBUG(is_power_of_2(++i) ? D_WARNING : D_NET, "waiting for %d threads of WI sched[%s] to terminate\n", sched->ws_nthreads, sched->ws_name); -- GitLab From b3367164f4ff8ff2c1aa8bd79c7548f113b62b83 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Thu, 29 Oct 2015 02:59:27 +0200 Subject: [PATCH 0383/2855] staging: lustre: selftest.h: replace IS_PO2 by is_power_of_2 Replaces IS_PO2 by is_power_of_2. It is more accurate to use is_power_of_2 since it returns 1 for numbers that are powers of 2 only whereas IS_PO2 returns 1 for 0 and numbers that are powers of 2. Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/selftest.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/selftest/selftest.h b/drivers/staging/lustre/lnet/selftest/selftest.h index 0c0f177debc88..870498339538b 100644 --- a/drivers/staging/lustre/lnet/selftest/selftest.h +++ b/drivers/staging/lustre/lnet/selftest/selftest.h @@ -585,7 +585,7 @@ swi_state2str (int state) do { \ int __I = 2; \ while (!(cond)) { \ - CDEBUG(IS_PO2(++__I) ? D_WARNING : D_NET, \ + CDEBUG(is_power_of_2(++__I) ? D_WARNING : D_NET, \ fmt, ## __VA_ARGS__); \ spin_unlock(&(lock)); \ \ -- GitLab From a4be078d7818e8712cb5d78b95542877a6f75071 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 4 Nov 2015 01:16:16 +0300 Subject: [PATCH 0384/2855] staging: lustre: remove unused variable The "->lr_lvb_data" struct member is never used. Delete it. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/lustre_dlm.h | 2 -- drivers/staging/lustre/lustre/ldlm/ldlm_resource.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h index 0e75a15fe0d42..138479a9edc1f 100644 --- a/drivers/staging/lustre/lustre/include/lustre_dlm.h +++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h @@ -872,8 +872,6 @@ struct ldlm_resource { */ struct mutex lr_lvb_mutex; int lr_lvb_len; - /** protected by lr_lock */ - void *lr_lvb_data; /** When the resource was considered as contended. */ unsigned long lr_contention_time; diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c index c0a54bf406ca5..b55a4f0eb1d5a 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c @@ -1154,8 +1154,6 @@ ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent, CERROR("%s: lvbo_init failed for resource %#llx:%#llx: rc = %d\n", ns->ns_obd->obd_name, name->name[0], name->name[1], rc); - kfree(res->lr_lvb_data); - res->lr_lvb_data = NULL; res->lr_lvb_len = rc; mutex_unlock(&res->lr_lvb_mutex); ldlm_resource_putref(res); -- GitLab From cf02dfef8a3de0e45e4907a374dbc53890cc9ee5 Mon Sep 17 00:00:00 2001 From: Liang Zhen Date: Wed, 4 Nov 2015 13:39:57 -0500 Subject: [PATCH 0385/2855] staging: lustre: wrong parameter to cfs_hash_keycpy cfs_hash_rehash_key() passed wrong parameter to cfs_hash_keycpy, hnode should be the second parameter not the third one. Signed-off-by: Liang Zhen Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4362 Reviewed-on: http://review.whamcloud.com/8509 Reviewed-by: Bobi Jam Reviewed-by: Johann Lombardi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/libcfs/hash.c b/drivers/staging/lustre/lustre/libcfs/hash.c index 98c19b6cd1744..8800d64780bfc 100644 --- a/drivers/staging/lustre/lustre/libcfs/hash.c +++ b/drivers/staging/lustre/lustre/libcfs/hash.c @@ -2005,7 +2005,7 @@ void cfs_hash_rehash_key(struct cfs_hash *hs, const void *old_key, } /* overwrite key inside locks, otherwise may screw up with * other operations, i.e: rehash */ - cfs_hash_keycpy(hs, new_key, hnode); + cfs_hash_keycpy(hs, hnode, new_key); cfs_hash_multi_bd_unlock(hs, bds, 3, 1); cfs_hash_unlock(hs, 0); -- GitLab From 5b26f052fb31561717f889fff09604907be62080 Mon Sep 17 00:00:00 2001 From: frank zago Date: Wed, 4 Nov 2015 13:39:58 -0500 Subject: [PATCH 0386/2855] staging: lustre: remove unnecessary EXPORT_SYMBOL in libcfs A lot of symbols don't need to be exported at all because they are only used in the module they belong to. Signed-off-by: frank zago Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5829 Reviewed-on: http://review.whamcloud.com/13319 Reviewed-by: James Simmons Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/debug.c | 10 ---------- drivers/staging/lustre/lustre/libcfs/hash.c | 10 ---------- drivers/staging/lustre/lustre/libcfs/libcfs_mem.c | 2 -- .../staging/lustre/lustre/libcfs/linux/linux-debug.c | 1 - 4 files changed, 23 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/debug.c b/drivers/staging/lustre/lustre/libcfs/debug.c index 1d1c67164418f..4272a7c959d78 100644 --- a/drivers/staging/lustre/lustre/libcfs/debug.c +++ b/drivers/staging/lustre/lustre/libcfs/debug.c @@ -94,17 +94,14 @@ static struct kernel_param_ops param_ops_debugmb = { static unsigned int libcfs_debug_mb; module_param(libcfs_debug_mb, debugmb, 0644); MODULE_PARM_DESC(libcfs_debug_mb, "Total debug buffer size."); -EXPORT_SYMBOL(libcfs_debug_mb); unsigned int libcfs_printk = D_CANTMASK; module_param(libcfs_printk, uint, 0644); MODULE_PARM_DESC(libcfs_printk, "Lustre kernel debug console mask"); -EXPORT_SYMBOL(libcfs_printk); unsigned int libcfs_console_ratelimit = 1; module_param(libcfs_console_ratelimit, uint, 0644); MODULE_PARM_DESC(libcfs_console_ratelimit, "Lustre kernel debug console ratelimit (0 to disable)"); -EXPORT_SYMBOL(libcfs_console_ratelimit); static int param_set_delay_minmax(const char *val, const struct kernel_param *kp, @@ -135,9 +132,7 @@ static int param_get_delay(char *buffer, const struct kernel_param *kp) } unsigned int libcfs_console_max_delay; -EXPORT_SYMBOL(libcfs_console_max_delay); unsigned int libcfs_console_min_delay; -EXPORT_SYMBOL(libcfs_console_min_delay); static int param_set_console_max_delay(const char *val, const struct kernel_param *kp) @@ -207,10 +202,8 @@ static struct kernel_param_ops param_ops_uintpos = { unsigned int libcfs_console_backoff = CDEBUG_DEFAULT_BACKOFF; module_param(libcfs_console_backoff, uintpos, 0644); MODULE_PARM_DESC(libcfs_console_backoff, "Lustre kernel debug console backoff factor"); -EXPORT_SYMBOL(libcfs_console_backoff); unsigned int libcfs_debug_binary = 1; -EXPORT_SYMBOL(libcfs_debug_binary); unsigned int libcfs_stack = 3 * THREAD_SIZE / 4; EXPORT_SYMBOL(libcfs_stack); @@ -221,7 +214,6 @@ EXPORT_SYMBOL(libcfs_catastrophe); unsigned int libcfs_panic_on_lbug = 1; module_param(libcfs_panic_on_lbug, uint, 0644); MODULE_PARM_DESC(libcfs_panic_on_lbug, "Lustre kernel panic on LBUG"); -EXPORT_SYMBOL(libcfs_panic_on_lbug); static wait_queue_head_t debug_ctlwq; @@ -572,5 +564,3 @@ void libcfs_debug_set_level(unsigned int debug_level) debug_level); libcfs_debug = debug_level; } - -EXPORT_SYMBOL(libcfs_debug_set_level); diff --git a/drivers/staging/lustre/lustre/libcfs/hash.c b/drivers/staging/lustre/lustre/libcfs/hash.c index 8800d64780bfc..f23a11ddc9794 100644 --- a/drivers/staging/lustre/lustre/libcfs/hash.c +++ b/drivers/staging/lustre/lustre/libcfs/hash.c @@ -593,7 +593,6 @@ cfs_hash_bd_move_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd_old, if (unlikely(nbkt->hsb_version == 0)) nbkt->hsb_version++; } -EXPORT_SYMBOL(cfs_hash_bd_move_locked); enum { /** always set, for sanity (avoid ZERO intent) */ @@ -830,21 +829,18 @@ cfs_hash_dual_bd_get(struct cfs_hash *hs, const void *key, cfs_hash_bd_order(&bds[0], &bds[1]); } -EXPORT_SYMBOL(cfs_hash_dual_bd_get); void cfs_hash_dual_bd_lock(struct cfs_hash *hs, struct cfs_hash_bd *bds, int excl) { cfs_hash_multi_bd_lock(hs, bds, 2, excl); } -EXPORT_SYMBOL(cfs_hash_dual_bd_lock); void cfs_hash_dual_bd_unlock(struct cfs_hash *hs, struct cfs_hash_bd *bds, int excl) { cfs_hash_multi_bd_unlock(hs, bds, 2, excl); } -EXPORT_SYMBOL(cfs_hash_dual_bd_unlock); struct hlist_node * cfs_hash_dual_bd_lookup_locked(struct cfs_hash *hs, struct cfs_hash_bd *bds, @@ -852,7 +848,6 @@ cfs_hash_dual_bd_lookup_locked(struct cfs_hash *hs, struct cfs_hash_bd *bds, { return cfs_hash_multi_bd_lookup_locked(hs, bds, 2, key); } -EXPORT_SYMBOL(cfs_hash_dual_bd_lookup_locked); struct hlist_node * cfs_hash_dual_bd_findadd_locked(struct cfs_hash *hs, struct cfs_hash_bd *bds, @@ -862,7 +857,6 @@ cfs_hash_dual_bd_findadd_locked(struct cfs_hash *hs, struct cfs_hash_bd *bds, return cfs_hash_multi_bd_findadd_locked(hs, bds, 2, key, hnode, noref); } -EXPORT_SYMBOL(cfs_hash_dual_bd_findadd_locked); struct hlist_node * cfs_hash_dual_bd_finddel_locked(struct cfs_hash *hs, struct cfs_hash_bd *bds, @@ -870,7 +864,6 @@ cfs_hash_dual_bd_finddel_locked(struct cfs_hash *hs, struct cfs_hash_bd *bds, { return cfs_hash_multi_bd_finddel_locked(hs, bds, 2, key, hnode); } -EXPORT_SYMBOL(cfs_hash_dual_bd_finddel_locked); static void cfs_hash_buckets_free(struct cfs_hash_bucket **buckets, @@ -1792,7 +1785,6 @@ cfs_hash_rehash_cancel_locked(struct cfs_hash *hs) cfs_hash_lock(hs, 1); } } -EXPORT_SYMBOL(cfs_hash_rehash_cancel_locked); void cfs_hash_rehash_cancel(struct cfs_hash *hs) @@ -1801,7 +1793,6 @@ cfs_hash_rehash_cancel(struct cfs_hash *hs) cfs_hash_rehash_cancel_locked(hs); cfs_hash_unlock(hs, 1); } -EXPORT_SYMBOL(cfs_hash_rehash_cancel); int cfs_hash_rehash(struct cfs_hash *hs, int do_rehash) @@ -1831,7 +1822,6 @@ cfs_hash_rehash(struct cfs_hash *hs, int do_rehash) return cfs_hash_rehash_worker(&hs->hs_rehash_wi); } -EXPORT_SYMBOL(cfs_hash_rehash); static int cfs_hash_rehash_bd(struct cfs_hash *hs, struct cfs_hash_bd *old) diff --git a/drivers/staging/lustre/lustre/libcfs/libcfs_mem.c b/drivers/staging/lustre/lustre/libcfs/libcfs_mem.c index f4e08daba4d9b..27cf86106363e 100644 --- a/drivers/staging/lustre/lustre/libcfs/libcfs_mem.c +++ b/drivers/staging/lustre/lustre/libcfs/libcfs_mem.c @@ -134,7 +134,6 @@ cfs_percpt_current(void *vars) return arr->va_ptrs[cpt]; } -EXPORT_SYMBOL(cfs_percpt_current); void * cfs_percpt_index(void *vars, int idx) @@ -146,7 +145,6 @@ cfs_percpt_index(void *vars, int idx) LASSERT(idx >= 0 && idx < arr->va_count); return arr->va_ptrs[idx]; } -EXPORT_SYMBOL(cfs_percpt_index); /* * free variable array, see more detail in cfs_array_alloc diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c index 8689ea757c993..59c7bf3cbc1ff 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c @@ -195,6 +195,5 @@ void libcfs_unregister_panic_notifier(void) atomic_notifier_chain_unregister(&panic_notifier_list, &libcfs_panic_notifier); } -EXPORT_SYMBOL(libcfs_run_upcall); EXPORT_SYMBOL(libcfs_run_lbug_upcall); EXPORT_SYMBOL(lbug_with_loc); -- GitLab From 30a0a431e043b378bbf75e0f88d700812d24ef80 Mon Sep 17 00:00:00 2001 From: frank zago Date: Wed, 4 Nov 2015 13:39:59 -0500 Subject: [PATCH 0387/2855] staging: lustre: remove libcfs_debug_set_level prototype from libcfs_private.h The function libcfs_debug_set_level is used only internally so no reason to expose it in libcfs_private.h. This is broken out from LU-5829 patch http://review.whamcloud.com/13319. Signed-off-by: frank zago Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs_private.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h index f0b0423a716bd..d6273e143324e 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h @@ -185,8 +185,6 @@ int libcfs_debug_cleanup(void); int libcfs_debug_clear_buffer(void); int libcfs_debug_mark_buffer(const char *text); -void libcfs_debug_set_level(unsigned int debug_level); - /* * allocate per-cpu-partition data, returned value is an array of pointers, * variable can be indexed by CPU ID. -- GitLab From 9563fe8a2de9db5eb087fe0e48ec335ee66f8f41 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin Date: Wed, 4 Nov 2015 13:40:00 -0500 Subject: [PATCH 0388/2855] staging: lustre: fix buffer overflow of string buffer Buffer overflow of string buffer due to non null terminated string. Use strlcpy() when it's justifiable. Use sizeof(var) instead of constants. Signed-off-by: Dmitry Eremin Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4629 Reviewed-on: http://review.whamcloud.com/9389 Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 9 +++++---- drivers/staging/lustre/lnet/lnet/config.c | 14 ++++++++------ drivers/staging/lustre/lnet/selftest/conrpc.c | 4 ++-- drivers/staging/lustre/lnet/selftest/console.c | 6 ++++-- .../staging/lustre/lustre/include/lustre_disk.h | 1 + drivers/staging/lustre/lustre/libcfs/debug.c | 6 +++--- drivers/staging/lustre/lustre/libcfs/hash.c | 3 +-- drivers/staging/lustre/lustre/libcfs/workitem.c | 4 ++-- drivers/staging/lustre/lustre/llite/dir.c | 2 +- drivers/staging/lustre/lustre/lov/lov_pool.c | 3 +-- drivers/staging/lustre/lustre/obdclass/obd_mount.c | 10 +++++++--- drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c | 1 + drivers/staging/lustre/lustre/ptlrpc/sec_config.c | 3 +-- 13 files changed, 37 insertions(+), 29 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index ecfe733023503..46a24b4ead097 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -2621,8 +2621,8 @@ ksocknal_enumerate_interfaces(ksock_net_t *net) net->ksnn_interfaces[j].ksni_ipaddr = ip; net->ksnn_interfaces[j].ksni_netmask = mask; - strncpy(&net->ksnn_interfaces[j].ksni_name[0], - names[i], IFNAMSIZ); + strlcpy(net->ksnn_interfaces[j].ksni_name, + names[i], sizeof(net->ksnn_interfaces[j].ksni_name)); j++; } @@ -2805,8 +2805,9 @@ ksocknal_startup(lnet_ni_t *ni) goto fail_1; } - strncpy(&net->ksnn_interfaces[i].ksni_name[0], - ni->ni_interfaces[i], IFNAMSIZ); + strlcpy(net->ksnn_interfaces[i].ksni_name, + ni->ni_interfaces[i], + sizeof(net->ksnn_interfaces[i].ksni_name)); } net->ksnn_ninterfaces = i; } diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 4e8b54b86c7d1..5390ee9963ab4 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -650,8 +650,8 @@ lnet_parse_route(char *str, int *im_a_router) INIT_LIST_HEAD(&nets); /* save a copy of the string for error messages */ - strncpy(cmd, str, sizeof(cmd) - 1); - cmd[sizeof(cmd) - 1] = 0; + strncpy(cmd, str, sizeof(cmd)); + cmd[sizeof(cmd) - 1] = '\0'; sep = str; for (;;) { @@ -972,11 +972,13 @@ lnet_splitnets(char *source, struct list_head *nets) return 0; offset += (int)(sep - tb->ltb_text); - tb2 = lnet_new_text_buf(strlen(sep)); + len = strlen(sep); + tb2 = lnet_new_text_buf(len); if (tb2 == NULL) return -ENOMEM; - strcpy(tb2->ltb_text, sep); + strncpy(tb2->ltb_text, sep, len); + tb2->ltb_text[len] = '\0'; list_add_tail(&tb2->ltb_list, nets); tb = tb2; @@ -1021,8 +1023,8 @@ lnet_match_networks(char **networksp, char *ip2nets, __u32 *ipaddrs, int nip) tb = list_entry(raw_entries.next, struct lnet_text_buf_t, ltb_list); - strncpy(source, tb->ltb_text, sizeof(source)-1); - source[sizeof(source)-1] = 0; + strncpy(source, tb->ltb_text, sizeof(source)); + source[sizeof(source)-1] = '\0'; /* replace ltb_text with the network(s) add on match */ rc = lnet_match_network_tokens(tb->ltb_text, ipaddrs, nip); diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c index 64a0335934f3d..1066c70434b11 100644 --- a/drivers/staging/lustre/lnet/selftest/conrpc.c +++ b/drivers/staging/lustre/lnet/selftest/conrpc.c @@ -612,8 +612,8 @@ lstcon_sesrpc_prep(lstcon_node_t *nd, int transop, msrq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.mksn_reqst; msrq->mksn_sid = console_session.ses_id; msrq->mksn_force = console_session.ses_force; - strncpy(msrq->mksn_name, console_session.ses_name, - strlen(console_session.ses_name)); + strlcpy(msrq->mksn_name, console_session.ses_name, + sizeof(msrq->mksn_name)); break; case LST_TRANS_SESEND: diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c index 6862c9a15556e..5619fc430e8d2 100644 --- a/drivers/staging/lustre/lnet/selftest/console.c +++ b/drivers/staging/lustre/lnet/selftest/console.c @@ -1731,7 +1731,8 @@ lstcon_session_new(char *name, int key, unsigned feats, console_session.ses_feats_updated = 0; console_session.ses_timeout = (timeout <= 0) ? LST_CONSOLE_TIMEOUT : timeout; - strcpy(console_session.ses_name, name); + strlcpy(console_session.ses_name, name, + sizeof(console_session.ses_name)); rc = lstcon_batch_add(LST_DEFAULT_BATCH); if (rc != 0) @@ -1951,7 +1952,8 @@ lstcon_acceptor_handle(struct srpc_server_rpc *rpc) if (grp->grp_userland == 0) grp->grp_userland = 1; - strcpy(jrep->join_session, console_session.ses_name); + strlcpy(jrep->join_session, console_session.ses_name, + sizeof(jrep->join_session)); jrep->join_timeout = console_session.ses_timeout; jrep->join_status = 0; diff --git a/drivers/staging/lustre/lustre/include/lustre_disk.h b/drivers/staging/lustre/lustre/include/lustre_disk.h index 5e1ac129a681e..7c6933ffc9c17 100644 --- a/drivers/staging/lustre/lustre/include/lustre_disk.h +++ b/drivers/staging/lustre/lustre/include/lustre_disk.h @@ -68,6 +68,7 @@ everything as string options */ #define LMD_MAGIC 0xbdacbd03 +#define LMD_PARAMS_MAXLEN 4096 /* gleaned from the mount command - no persistent info here */ struct lustre_mount_data { diff --git a/drivers/staging/lustre/lustre/libcfs/debug.c b/drivers/staging/lustre/lustre/libcfs/debug.c index 4272a7c959d78..e56785a482425 100644 --- a/drivers/staging/lustre/lustre/libcfs/debug.c +++ b/drivers/staging/lustre/lustre/libcfs/debug.c @@ -504,9 +504,9 @@ int libcfs_debug_init(unsigned long bufsize) } if (libcfs_debug_file_path != NULL) { - strncpy(libcfs_debug_file_path_arr, - libcfs_debug_file_path, PATH_MAX-1); - libcfs_debug_file_path_arr[PATH_MAX - 1] = '\0'; + strlcpy(libcfs_debug_file_path_arr, + libcfs_debug_file_path, + sizeof(libcfs_debug_file_path_arr)); } /* If libcfs_debug_mb is set to an invalid value or uninitialized diff --git a/drivers/staging/lustre/lustre/libcfs/hash.c b/drivers/staging/lustre/lustre/libcfs/hash.c index f23a11ddc9794..d285117af3ada 100644 --- a/drivers/staging/lustre/lustre/libcfs/hash.c +++ b/drivers/staging/lustre/lustre/libcfs/hash.c @@ -1037,8 +1037,7 @@ cfs_hash_create(char *name, unsigned cur_bits, unsigned max_bits, if (hs == NULL) return NULL; - strncpy(hs->hs_name, name, len); - hs->hs_name[len - 1] = '\0'; + strlcpy(hs->hs_name, name, len); hs->hs_flags = flags; atomic_set(&hs->hs_refcount, 1); diff --git a/drivers/staging/lustre/lustre/libcfs/workitem.c b/drivers/staging/lustre/lustre/libcfs/workitem.c index 268dd6851af4b..6d988084dbb65 100644 --- a/drivers/staging/lustre/lustre/libcfs/workitem.c +++ b/drivers/staging/lustre/lustre/libcfs/workitem.c @@ -360,8 +360,8 @@ cfs_wi_sched_create(char *name, struct cfs_cpt_table *cptab, if (sched == NULL) return -ENOMEM; - strncpy(sched->ws_name, name, CFS_WS_NAME_LEN); - sched->ws_name[CFS_WS_NAME_LEN - 1] = '\0'; + strlcpy(sched->ws_name, name, CFS_WS_NAME_LEN); + sched->ws_cptab = cptab; sched->ws_cpt = cpt; diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index 5c9502b5b3582..951259a983233 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -641,7 +641,7 @@ static int ll_send_mgc_param(struct obd_export *mgc, char *string) if (!msp) return -ENOMEM; - strncpy(msp->mgs_param, string, MGS_PARAM_MAXLEN); + strlcpy(msp->mgs_param, string, sizeof(msp->mgs_param)); rc = obd_set_info_async(NULL, mgc, sizeof(KEY_SET_INFO), KEY_SET_INFO, sizeof(struct mgs_send_param), msp, NULL); if (rc) diff --git a/drivers/staging/lustre/lustre/lov/lov_pool.c b/drivers/staging/lustre/lustre/lov/lov_pool.c index b03827ef65145..b43ce6cd64c2a 100644 --- a/drivers/staging/lustre/lustre/lov/lov_pool.c +++ b/drivers/staging/lustre/lustre/lov/lov_pool.c @@ -412,8 +412,7 @@ int lov_pool_new(struct obd_device *obd, char *poolname) if (!new_pool) return -ENOMEM; - strncpy(new_pool->pool_name, poolname, LOV_MAXPOOLNAME); - new_pool->pool_name[LOV_MAXPOOLNAME] = '\0'; + strlcpy(new_pool->pool_name, poolname, sizeof(new_pool->pool_name)); new_pool->pool_lobd = obd; /* ref count init to 1 because when created a pool is always used * up to deletion diff --git a/drivers/staging/lustre/lustre/obdclass/obd_mount.c b/drivers/staging/lustre/lustre/obdclass/obd_mount.c index 48003d5325e32..7617c57d16e0c 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_mount.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_mount.c @@ -892,7 +892,7 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd) } lmd->lmd_magic = LMD_MAGIC; - lmd->lmd_params = kzalloc(4096, GFP_NOFS); + lmd->lmd_params = kzalloc(LMD_PARAMS_MAXLEN, GFP_NOFS); if (!lmd->lmd_params) return -ENOMEM; lmd->lmd_params[0] = '\0'; @@ -978,7 +978,7 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd) goto invalid; clear++; } else if (strncmp(s1, "param=", 6) == 0) { - int length; + size_t length, params_length; char *tail = strchr(s1 + 6, ','); if (tail == NULL) @@ -986,8 +986,12 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd) else length = tail - s1; length -= 6; + params_length = strlen(lmd->lmd_params); + if (params_length + length + 1 >= LMD_PARAMS_MAXLEN) + return -E2BIG; strncat(lmd->lmd_params, s1 + 6, length); - strcat(lmd->lmd_params, " "); + lmd->lmd_params[params_length + length] = '\0'; + strlcat(lmd->lmd_params, " ", LMD_PARAMS_MAXLEN); clear++; } else if (strncmp(s1, "osd=", 4) == 0) { rc = lmd_parse_string(&lmd->lmd_osd_type, s1 + 4); diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c index ce036a1ac4663..ac87aa12bd7e7 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c @@ -422,6 +422,7 @@ static int ptlrpcd(void *arg) complete(&pc->pc_starting); /* + * This mainloop strongly resembles ptlrpc_set_wait() except that our * set never completes. ptlrpcd_check() calls ptlrpc_check_set() when * there are requests in the set. New requests come in on the set's diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_config.c b/drivers/staging/lustre/lustre/ptlrpc/sec_config.c index 7ff948fe14247..7a206705865b7 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_config.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_config.c @@ -83,8 +83,7 @@ int sptlrpc_parse_flavor(const char *str, struct sptlrpc_flavor *flvr) return 0; } - strncpy(buf, str, sizeof(buf)); - buf[sizeof(buf) - 1] = '\0'; + strlcpy(buf, str, sizeof(buf)); bulk = strchr(buf, '-'); if (bulk) -- GitLab From b00917be6e90149286b3680f5e626787bcc75c55 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin Date: Wed, 4 Nov 2015 13:40:01 -0500 Subject: [PATCH 0389/2855] staging: lustre: Fix possible NULL pointer dereference in lprocfs_status.c The imp->imp_connection really could be NULL, we better check for it before dereferencing it in taht call to libcfs_nid2str_r. Signed-off-by: Dmitry Eremin Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6507 Reviewed-on: http://review.whamcloud.com/14808 Reviewed-by: Bob Glossman Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/obdclass/lprocfs_status.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c index 2de3c1b6fa49f..dda5ad105f2e3 100644 --- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c +++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c @@ -665,15 +665,18 @@ int lprocfs_rd_import(struct seq_file *m, void *data) seq_printf(m, "%s%s", j ? ", " : "", nidstr); j++; } - libcfs_nid2str_r(imp->imp_connection->c_peer.nid, - nidstr, sizeof(nidstr)); + if (imp->imp_connection != NULL) + libcfs_nid2str_r(imp->imp_connection->c_peer.nid, + nidstr, sizeof(nidstr)); + else + strncpy(nidstr, "", sizeof(nidstr)); seq_printf(m, "]\n" " current_connection: %s\n" " connection_attempts: %u\n" " generation: %u\n" " in-progress_invalidations: %u\n", - imp->imp_connection == NULL ? "" : nidstr, + nidstr, imp->imp_conn_cnt, imp->imp_generation, atomic_read(&imp->imp_inval_count)); -- GitLab From a0455471582117d31659618c02146804df527ff4 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Wed, 4 Nov 2015 13:40:02 -0500 Subject: [PATCH 0390/2855] staging: lustre: Update module author to OpenSFS The modinfo data has gone stale for the author information. This patch changes all the MODULE_AUTHOR to OpenSFS. Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6204 Reviewed-on: http://review.whamcloud.com/16132 Reviewed-by: Frank Zago Reviewed-by: Andreas Dilger Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 +- drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c | 2 +- drivers/staging/lustre/lnet/lnet/module.c | 2 +- drivers/staging/lustre/lustre/fid/fid_request.c | 2 +- drivers/staging/lustre/lustre/fld/fld_request.c | 2 +- drivers/staging/lustre/lustre/libcfs/module.c | 2 +- drivers/staging/lustre/lustre/llite/lloop.c | 2 +- drivers/staging/lustre/lustre/llite/super25.c | 2 +- drivers/staging/lustre/lustre/lmv/lmv_obd.c | 2 +- drivers/staging/lustre/lustre/lov/lov_obd.c | 2 +- drivers/staging/lustre/lustre/mdc/mdc_request.c | 2 +- drivers/staging/lustre/lustre/mgc/mgc_request.c | 2 +- drivers/staging/lustre/lustre/obdclass/class_obd.c | 2 +- drivers/staging/lustre/lustre/obdecho/echo_client.c | 2 +- drivers/staging/lustre/lustre/osc/osc_request.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 7c730e3f7453e..de0f85f8a2f97 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -2865,7 +2865,7 @@ static int __init kiblnd_module_init(void) return 0; } -MODULE_AUTHOR("Sun Microsystems, Inc. "); +MODULE_AUTHOR("OpenSFS, Inc. "); MODULE_DESCRIPTION("Kernel OpenIB gen2 LND v2.00"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 46a24b4ead097..ebde0369edc81 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -2869,7 +2869,7 @@ ksocknal_module_init(void) return 0; } -MODULE_AUTHOR("Sun Microsystems, Inc. "); +MODULE_AUTHOR("OpenSFS, Inc. "); MODULE_DESCRIPTION("Kernel TCP Socket LND v3.0.0"); MODULE_LICENSE("GPL"); MODULE_VERSION("3.0.0"); diff --git a/drivers/staging/lustre/lnet/lnet/module.c b/drivers/staging/lustre/lnet/lnet/module.c index 576201a8390cd..ac2fdf05a5fd9 100644 --- a/drivers/staging/lustre/lnet/lnet/module.c +++ b/drivers/staging/lustre/lnet/lnet/module.c @@ -146,7 +146,7 @@ fini_lnet(void) lnet_fini(); } -MODULE_AUTHOR("Peter J. Braam "); +MODULE_AUTHOR("OpenSFS, Inc. "); MODULE_DESCRIPTION("LNet v3.1"); MODULE_LICENSE("GPL"); MODULE_VERSION("1.0.0"); diff --git a/drivers/staging/lustre/lustre/fid/fid_request.c b/drivers/staging/lustre/lustre/fid/fid_request.c index e8176288452c6..fe7c39afd1d9e 100644 --- a/drivers/staging/lustre/lustre/fid/fid_request.c +++ b/drivers/staging/lustre/lustre/fid/fid_request.c @@ -462,7 +462,7 @@ static void __exit fid_mod_exit(void) ldebugfs_remove(&seq_debugfs_dir); } -MODULE_AUTHOR("Sun Microsystems, Inc. "); +MODULE_AUTHOR("OpenSFS, Inc. "); MODULE_DESCRIPTION("Lustre FID Module"); MODULE_LICENSE("GPL"); MODULE_VERSION("0.1.0"); diff --git a/drivers/staging/lustre/lustre/fld/fld_request.c b/drivers/staging/lustre/lustre/fld/fld_request.c index 3fd91bc77da5d..469df685f392d 100644 --- a/drivers/staging/lustre/lustre/fld/fld_request.c +++ b/drivers/staging/lustre/lustre/fld/fld_request.c @@ -501,7 +501,7 @@ static void __exit fld_mod_exit(void) ldebugfs_remove(&fld_debugfs_dir); } -MODULE_AUTHOR("Sun Microsystems, Inc. "); +MODULE_AUTHOR("OpenSFS, Inc. "); MODULE_DESCRIPTION("Lustre FLD"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/lustre/lustre/libcfs/module.c b/drivers/staging/lustre/lustre/libcfs/module.c index 07a68594c2791..d781b417fd389 100644 --- a/drivers/staging/lustre/lustre/libcfs/module.c +++ b/drivers/staging/lustre/lustre/libcfs/module.c @@ -62,7 +62,7 @@ #include "../../include/linux/lnet/lnet.h" #include "tracefile.h" -MODULE_AUTHOR("Peter J. Braam "); +MODULE_AUTHOR("OpenSFS, Inc. "); MODULE_DESCRIPTION("Portals v3.1"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/lustre/lustre/llite/lloop.c b/drivers/staging/lustre/lustre/llite/lloop.c index fed50d538a414..420d39123877b 100644 --- a/drivers/staging/lustre/lustre/llite/lloop.c +++ b/drivers/staging/lustre/lustre/llite/lloop.c @@ -877,6 +877,6 @@ module_exit(lloop_exit); module_param(max_loop, int, 0444); MODULE_PARM_DESC(max_loop, "maximum of lloop_device"); -MODULE_AUTHOR("Sun Microsystems, Inc. "); +MODULE_AUTHOR("OpenSFS, Inc. "); MODULE_DESCRIPTION("Lustre virtual block device"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/lustre/lustre/llite/super25.c b/drivers/staging/lustre/lustre/llite/super25.c index 0131368606644..7a9fafc676935 100644 --- a/drivers/staging/lustre/lustre/llite/super25.c +++ b/drivers/staging/lustre/lustre/llite/super25.c @@ -205,7 +205,7 @@ static void __exit exit_lustre_lite(void) kmem_cache_destroy(ll_file_data_slab); } -MODULE_AUTHOR("Sun Microsystems, Inc. "); +MODULE_AUTHOR("OpenSFS, Inc. "); MODULE_DESCRIPTION("Lustre Lite Client File System"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c index 55f801ba98266..a4de9a3fd847c 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c @@ -2812,7 +2812,7 @@ static void lmv_exit(void) class_unregister_type(LUSTRE_LMV_NAME); } -MODULE_AUTHOR("Sun Microsystems, Inc. "); +MODULE_AUTHOR("OpenSFS, Inc. "); MODULE_DESCRIPTION("Lustre Logical Metadata Volume OBD driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c index 6bd4ac051274f..b52609aead4cf 100644 --- a/drivers/staging/lustre/lustre/lov/lov_obd.c +++ b/drivers/staging/lustre/lustre/lov/lov_obd.c @@ -2352,7 +2352,7 @@ static void /*__exit*/ lov_exit(void) lu_kmem_fini(lov_caches); } -MODULE_AUTHOR("Sun Microsystems, Inc. "); +MODULE_AUTHOR("OpenSFS, Inc. "); MODULE_DESCRIPTION("Lustre Logical Object Volume OBD driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(LUSTRE_VERSION_STRING); diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 3dd0d01856f10..294c05084b976 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -2532,7 +2532,7 @@ static void /*__exit*/ mdc_exit(void) class_unregister_type(LUSTRE_MDC_NAME); } -MODULE_AUTHOR("Sun Microsystems, Inc. "); +MODULE_AUTHOR("OpenSFS, Inc. "); MODULE_DESCRIPTION("Lustre Metadata Client"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c index b73f8f21b6c52..2c48847276260 100644 --- a/drivers/staging/lustre/lustre/mgc/mgc_request.c +++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c @@ -1725,7 +1725,7 @@ static void /*__exit*/ mgc_exit(void) class_unregister_type(LUSTRE_MGC_NAME); } -MODULE_AUTHOR("Sun Microsystems, Inc. "); +MODULE_AUTHOR("OpenSFS, Inc. "); MODULE_DESCRIPTION("Lustre Management Client"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c index 3e9c246846907..beb59f009cbe8 100644 --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c @@ -576,7 +576,7 @@ static void cleanup_obdclass(void) obd_zombie_impexp_stop(); } -MODULE_AUTHOR("Sun Microsystems, Inc. "); +MODULE_AUTHOR("OpenSFS, Inc. "); MODULE_DESCRIPTION("Lustre Class Driver Build Version: " BUILD_VERSION); MODULE_LICENSE("GPL"); MODULE_VERSION(LUSTRE_VERSION_STRING); diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c index f49564f6bb894..14ac56bb0d77c 100644 --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c @@ -2170,7 +2170,7 @@ static void /*__exit*/ obdecho_exit(void) } -MODULE_AUTHOR("Sun Microsystems, Inc. "); +MODULE_AUTHOR("OpenSFS, Inc. "); MODULE_DESCRIPTION("Lustre Testing Echo OBD driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(LUSTRE_VERSION_STRING); diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index cfb3ce2111f8b..d6c1447f6bd95 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -3358,7 +3358,7 @@ static void /*__exit*/ osc_exit(void) ptlrpc_free_rq_pool(osc_rq_pool); } -MODULE_AUTHOR("Sun Microsystems, Inc. "); +MODULE_AUTHOR("OpenSFS, Inc. "); MODULE_DESCRIPTION("Lustre Object Storage Client (OSC)"); MODULE_LICENSE("GPL"); MODULE_VERSION(LUSTRE_VERSION_STRING); diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c index 9deeb244166fa..c4f1d0f5deb21 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c @@ -160,7 +160,7 @@ static void __exit ptlrpc_exit(void) ptlrpc_connection_fini(); } -MODULE_AUTHOR("Sun Microsystems, Inc. "); +MODULE_AUTHOR("OpenSFS, Inc. "); MODULE_DESCRIPTION("Lustre Request Processor and Lock Management"); MODULE_LICENSE("GPL"); MODULE_VERSION("1.0.0"); -- GitLab From 78368d578e9eab8dc9d42b9e9a2be78a98f4e9d9 Mon Sep 17 00:00:00 2001 From: Fan Yong Date: Wed, 4 Nov 2015 13:40:04 -0500 Subject: [PATCH 0391/2855] staging: lustre: race condition for check/use cfs_fail_val There are some race conditions when check/use cfs_fail_val. For example: when inject failure stub for LFSCK test as following: 764 if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_DELAY2) && 765 cfs_fail_val > 0) { 766 struct l_wait_info lwi; 767 768 lwi = LWI_TIMEOUT(cfs_time_seconds(cfs_fail_val), 769 NULL, NULL); 770 l_wait_event(thread->t_ctl_waitq, 771 !thread_is_running(thread), 772 &lwi); 773 774 if (unlikely(!thread_is_running(thread))) { 775 CDEBUG(D_LFSCK, "%s: scan dir exit for engine " 776 "stop, parent "DFID", cookie "LPX64"n", 777 lfsck_lfsck2name(lfsck), 778 PFID(lfsck_dto2fid(dir)), 779 lfsck->li_cookie_dir); 780 RETURN(0); 781 } 782 } The "cfs_fail_val" may be changed as zero by others after the check at the line 765 but before using it at the line 768. Then the LFSCK engine will fall into "wait" until someone run "lfsck_stop". Signed-off-by: Fan Yong Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6146 Reviewed-on: http://review.whamcloud.com/13481 Reviewed-by: Lai Siyao Reviewed-by: Andreas Dilger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/fail.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/libcfs/fail.c b/drivers/staging/lustre/lustre/libcfs/fail.c index d39fecebd12d0..ea059b012a669 100644 --- a/drivers/staging/lustre/lustre/libcfs/fail.c +++ b/drivers/staging/lustre/lustre/libcfs/fail.c @@ -126,7 +126,7 @@ int __cfs_fail_timeout_set(__u32 id, __u32 value, int ms, int set) int ret; ret = __cfs_fail_check_set(id, value, set); - if (ret) { + if (ret && likely(ms > 0)) { CERROR("cfs_fail_timeout id %x sleeping for %dms\n", id, ms); set_current_state(TASK_UNINTERRUPTIBLE); -- GitLab From 9d3e85326f4c3c65a7e97c5406611a17142bd70f Mon Sep 17 00:00:00 2001 From: Liang Zhen Date: Wed, 4 Nov 2015 13:40:05 -0500 Subject: [PATCH 0392/2855] staging: lustre: remove page_collection::pc_lock in libcfs page_collection::pc_lock is supposed to protect race between functions called by smp_call_function(), however we don't have this use-case for ages and page_collection only lives in stack of thread, so it is safe to remove it. Signed-off-by: Liang Zhen Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3055 Reviewed-on: http://review.whamcloud.com/7660 Reviewed-by: Bobi Jam Reviewed-by: Sebastien Buisson Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/tracefile.c | 14 -------------- drivers/staging/lustre/lustre/libcfs/tracefile.h | 8 -------- 2 files changed, 22 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.c b/drivers/staging/lustre/lustre/libcfs/tracefile.c index f99d30f799e0c..c27e3207e9325 100644 --- a/drivers/staging/lustre/lustre/libcfs/tracefile.c +++ b/drivers/staging/lustre/lustre/libcfs/tracefile.c @@ -199,7 +199,6 @@ static void cfs_tcd_shrink(struct cfs_trace_cpu_data *tcd) pgcount + 1, tcd->tcd_cur_pages); INIT_LIST_HEAD(&pc.pc_pages); - spin_lock_init(&pc.pc_lock); list_for_each_entry_safe(tage, tmp, &tcd->tcd_pages, linkage) { if (pgcount-- == 0) @@ -522,7 +521,6 @@ static void collect_pages_on_all_cpus(struct page_collection *pc) struct cfs_trace_cpu_data *tcd; int i, cpu; - spin_lock(&pc->pc_lock); for_each_possible_cpu(cpu) { cfs_tcd_for_each_type_lock(tcd, i, cpu) { list_splice_init(&tcd->tcd_pages, &pc->pc_pages); @@ -534,7 +532,6 @@ static void collect_pages_on_all_cpus(struct page_collection *pc) } } } - spin_unlock(&pc->pc_lock); } static void collect_pages(struct page_collection *pc) @@ -555,7 +552,6 @@ static void put_pages_back_on_all_cpus(struct page_collection *pc) struct cfs_trace_page *tmp; int i, cpu; - spin_lock(&pc->pc_lock); for_each_possible_cpu(cpu) { cfs_tcd_for_each_type_lock(tcd, i, cpu) { cur_head = tcd->tcd_pages.next; @@ -573,7 +569,6 @@ static void put_pages_back_on_all_cpus(struct page_collection *pc) } } } - spin_unlock(&pc->pc_lock); } static void put_pages_back(struct page_collection *pc) @@ -592,7 +587,6 @@ static void put_pages_on_tcd_daemon_list(struct page_collection *pc, struct cfs_trace_page *tage; struct cfs_trace_page *tmp; - spin_lock(&pc->pc_lock); list_for_each_entry_safe(tage, tmp, &pc->pc_pages, linkage) { __LASSERT_TAGE_INVARIANT(tage); @@ -616,7 +610,6 @@ static void put_pages_on_tcd_daemon_list(struct page_collection *pc, tcd->tcd_cur_daemon_pages--; } } - spin_unlock(&pc->pc_lock); } static void put_pages_on_daemon_list(struct page_collection *pc) @@ -636,8 +629,6 @@ void cfs_trace_debug_print(void) struct cfs_trace_page *tage; struct cfs_trace_page *tmp; - spin_lock_init(&pc.pc_lock); - pc.pc_want_daemon_pages = 1; collect_pages(&pc); list_for_each_entry_safe(tage, tmp, &pc.pc_pages, linkage) { @@ -692,7 +683,6 @@ int cfs_tracefile_dump_all_pages(char *filename) goto out; } - spin_lock_init(&pc.pc_lock); pc.pc_want_daemon_pages = 1; collect_pages(&pc); if (list_empty(&pc.pc_pages)) { @@ -739,8 +729,6 @@ void cfs_trace_flush_pages(void) struct cfs_trace_page *tage; struct cfs_trace_page *tmp; - spin_lock_init(&pc.pc_lock); - pc.pc_want_daemon_pages = 1; collect_pages(&pc); list_for_each_entry_safe(tage, tmp, &pc.pc_pages, linkage) { @@ -970,7 +958,6 @@ static int tracefiled(void *arg) /* we're started late enough that we pick up init's fs context */ /* this is so broken in uml? what on earth is going on? */ - spin_lock_init(&pc.pc_lock); complete(&tctl->tctl_start); while (1) { @@ -1170,7 +1157,6 @@ static void cfs_trace_cleanup(void) struct page_collection pc; INIT_LIST_HEAD(&pc.pc_pages); - spin_lock_init(&pc.pc_lock); trace_cleanup_on_all_cpus(); diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.h b/drivers/staging/lustre/lustre/libcfs/tracefile.h index 73d60e0569226..e5fbeecf3567d 100644 --- a/drivers/staging/lustre/lustre/libcfs/tracefile.h +++ b/drivers/staging/lustre/lustre/libcfs/tracefile.h @@ -195,14 +195,6 @@ extern union cfs_trace_data_union (*cfs_trace_data[TCD_MAX_TYPES])[NR_CPUS]; * be moved there */ struct page_collection { struct list_head pc_pages; - /* - * spin-lock protecting ->pc_pages. It is taken by smp_call_function() - * call-back functions. XXX nikita: Which is horrible: all processors - * receive NMI at the same time only to be serialized by this - * lock. Probably ->pc_pages should be replaced with an array of - * NR_CPUS elements accessed locklessly. - */ - spinlock_t pc_lock; /* * if this flag is set, collect_pages() will spill both * ->tcd_daemon_pages and ->tcd_pages to the ->pc_pages. Otherwise, -- GitLab From 5bfd446e7bd94ee6f9c17d07b5d47342b96b387a Mon Sep 17 00:00:00 2001 From: Sebastien Buisson Date: Wed, 4 Nov 2015 13:40:06 -0500 Subject: [PATCH 0393/2855] staging: lustre: fix 'error handling' issues for libcfs workitem.c Fix 'error handling' issues found by Coverity version 6.5.1: Unchecked return value (CHECKED_RETURN) Calling function without checking return value. Signed-off-by: Sebastien Buisson Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3427 Reviewed-on: http://review.whamcloud.com/7103 Reviewed-by: Bobbie Lind Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/workitem.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/libcfs/workitem.c b/drivers/staging/lustre/lustre/libcfs/workitem.c index 6d988084dbb65..b57acbfb061b1 100644 --- a/drivers/staging/lustre/lustre/libcfs/workitem.c +++ b/drivers/staging/lustre/lustre/libcfs/workitem.c @@ -225,7 +225,9 @@ cfs_wi_scheduler (void *arg) /* CPT affinity scheduler? */ if (sched->ws_cptab != NULL) - cfs_cpt_bind(sched->ws_cptab, sched->ws_cpt); + if (cfs_cpt_bind(sched->ws_cptab, sched->ws_cpt) != 0) + CWARN("Failed to bind %s on CPT %d\n", + sched->ws_name, sched->ws_cpt); spin_lock(&cfs_wi_data.wi_glock); -- GitLab From 14e384ce758d613cf9da0b3fb4c2e66d58917ac0 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 5 Nov 2015 10:55:16 +0100 Subject: [PATCH 0394/2855] staging: lustre: Delete an unnecessary variable initialisation in class_register_type() The variable "rc" will be eventually set to an error return code in the class_register_type() function. Thus let us omit the explicit initialisation at the beginning. Signed-off-by: Markus Elfring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/obdclass/genops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c index 08966562d7fef..26f54f9503508 100644 --- a/drivers/staging/lustre/lustre/obdclass/genops.c +++ b/drivers/staging/lustre/lustre/obdclass/genops.c @@ -155,7 +155,7 @@ int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops, struct lu_device_type *ldt) { struct obd_type *type; - int rc = 0; + int rc; /* sanity check */ LASSERT(strnlen(name, CLASS_MAX_NAME) < CLASS_MAX_NAME); -- GitLab From ee98e44249a95832f24469d8caa8a693b88f854a Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Fri, 6 Nov 2015 20:26:52 +0530 Subject: [PATCH 0395/2855] staging: lustre: lnet: klnds: socklnd: Move extern declarations to header This patch moves extern declarations in socklnd_lib.c to the respective header file, 'socklnd.h'. This patch also removes extern keyword from function declarations since functions have the extern specifier by default. Signed-off-by: Amitoj Kaur Chawla Acked-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h | 3 +++ drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h index b349847f9cf96..f4fa72550657c 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h @@ -679,6 +679,9 @@ int ksocknal_lib_recv_kiov(ksock_conn_t *conn); int ksocknal_lib_get_conn_tunables(ksock_conn_t *conn, int *txmem, int *rxmem, int *nagle); +void ksocknal_read_callback(ksock_conn_t *conn); +void ksocknal_write_callback(ksock_conn_t *conn); + int ksocknal_tunables_init(void); void ksocknal_lib_csum_tx(ksock_tx_t *tx); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c index 679785b0209cf..04a4653c549ae 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c @@ -580,8 +580,6 @@ ksocknal_lib_push_conn(ksock_conn_t *conn) ksocknal_connsock_decref(conn); } -extern void ksocknal_read_callback(ksock_conn_t *conn); -extern void ksocknal_write_callback(ksock_conn_t *conn); /* * socket call back in Linux */ -- GitLab From c6ef5b91f3df7d22c058a135871d5827add94498 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Fri, 6 Nov 2015 22:25:29 +0530 Subject: [PATCH 0396/2855] Staging: lustre: dir: Remove wrapper function Remove the function ll_check_page() and replace all its calls with the function it wrapped. Signed-off-by: Shivani Bhardwaj Acked-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/dir.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index 951259a983233..5c2ef92809e64 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -239,12 +239,6 @@ static int ll_dir_filler(void *_hash, struct page *page0) return rc; } -static void ll_check_page(struct inode *dir, struct page *page) -{ - /* XXX: check page format later */ - SetPageChecked(page); -} - void ll_release_page(struct page *page, int remove) { kunmap(page); @@ -432,7 +426,8 @@ struct page *ll_get_dir_page(struct inode *dir, __u64 hash, goto fail; } if (!PageChecked(page)) - ll_check_page(dir, page); + /* XXX: check page format later */ + SetPageChecked(page); if (PageError(page)) { CERROR("page error: "DFID" at %llu: rc %d\n", PFID(ll_inode2fid(dir)), hash, -5); -- GitLab From e4ce7f7779313ff23f958049b91cc7ac1b24d8e8 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Fri, 6 Nov 2015 22:48:29 +0530 Subject: [PATCH 0397/2855] Staging: lustre: module: Replace function calls Replace the calls of function cfs_trace_free_string_buffer() with kfree() as the former function is not required. Signed-off-by: Shivani Bhardwaj Acked-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/module.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/module.c b/drivers/staging/lustre/lustre/libcfs/module.c index d781b417fd389..96d9d4651a51b 100644 --- a/drivers/staging/lustre/lustre/libcfs/module.c +++ b/drivers/staging/lustre/lustre/libcfs/module.c @@ -392,7 +392,7 @@ static int __proc_dobitmasks(void *data, int write, } else { rc = cfs_trace_copyin_string(tmpstr, tmpstrlen, buffer, nob); if (rc < 0) { - cfs_trace_free_string_buffer(tmpstr, tmpstrlen); + kfree(tmpstr); return rc; } @@ -402,7 +402,7 @@ static int __proc_dobitmasks(void *data, int write, *mask |= D_EMERG; } - cfs_trace_free_string_buffer(tmpstr, tmpstrlen); + kfree(tmpstr); return rc; } -- GitLab From 7cbf673d8b4a68916fe362fe9a9c3a55a604700e Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Fri, 6 Nov 2015 22:49:07 +0530 Subject: [PATCH 0398/2855] Staging: lustre: tracefile: Remove wrapper function Remove the function cfs_trace_free_string_buffer() as it can be replaced with the standard function kfree(). Signed-off-by: Shivani Bhardwaj Acked-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/tracefile.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.c b/drivers/staging/lustre/lustre/libcfs/tracefile.c index c27e3207e9325..65c4f1ab0de8a 100644 --- a/drivers/staging/lustre/lustre/libcfs/tracefile.c +++ b/drivers/staging/lustre/lustre/libcfs/tracefile.c @@ -805,11 +805,6 @@ int cfs_trace_allocate_string_buffer(char **str, int nob) return 0; } -void cfs_trace_free_string_buffer(char *str, int nob) -{ - kfree(str); -} - int cfs_trace_dump_debug_buffer_usrstr(void __user *usr_str, int usr_str_nob) { char *str; @@ -830,7 +825,7 @@ int cfs_trace_dump_debug_buffer_usrstr(void __user *usr_str, int usr_str_nob) } rc = cfs_tracefile_dump_all_pages(str); out: - cfs_trace_free_string_buffer(str, usr_str_nob + 1); + kfree(str); return rc; } @@ -886,7 +881,7 @@ int cfs_trace_daemon_command_usrstr(void __user *usr_str, int usr_str_nob) if (rc == 0) rc = cfs_trace_daemon_command(str); - cfs_trace_free_string_buffer(str, usr_str_nob + 1); + kfree(str); return rc; } -- GitLab From 7fb6f46b14d01a185dfe563a8ba20cda514d4f9a Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Fri, 6 Nov 2015 22:49:43 +0530 Subject: [PATCH 0399/2855] Staging: lustre: tracefile: Remove function prototype Remove the prototype of function cfs_trace_free_string_buffer() as it is no longer needed. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/tracefile.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.h b/drivers/staging/lustre/lustre/libcfs/tracefile.h index e5fbeecf3567d..6b37798336f23 100644 --- a/drivers/staging/lustre/lustre/libcfs/tracefile.h +++ b/drivers/staging/lustre/lustre/libcfs/tracefile.h @@ -70,7 +70,6 @@ int cfs_trace_copyin_string(char *knl_buffer, int knl_buffer_nob, int cfs_trace_copyout_string(char __user *usr_buffer, int usr_buffer_nob, const char *knl_str, char *append); int cfs_trace_allocate_string_buffer(char **str, int nob); -void cfs_trace_free_string_buffer(char *str, int nob); int cfs_trace_dump_debug_buffer_usrstr(void __user *usr_str, int usr_str_nob); int cfs_trace_daemon_command(char *str); int cfs_trace_daemon_command_usrstr(void __user *usr_str, int usr_str_nob); -- GitLab From 7c37abe0e1e970a7793a05c0953b44ac078f0a11 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Fri, 6 Nov 2015 23:13:19 +0530 Subject: [PATCH 0400/2855] Staging: lustre: ldlm_pool: Remove unneeded wrapper function Remove the function ldlm_pl2ns() and replace its calls with the function it wrapped. Signed-off-by: Shivani Bhardwaj Acked-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/ldlm/ldlm_pool.c | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c index 1a4eef64658f9..2beb36b081a35 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c @@ -176,11 +176,6 @@ enum { LDLM_POOL_LAST_STAT }; -static inline struct ldlm_namespace *ldlm_pl2ns(struct ldlm_pool *pl) -{ - return container_of(pl, struct ldlm_namespace, ns_pool); -} - /** * Calculates suggested grant_step in % of available locks for passed * \a period. This is later used in grant_plan calculations. @@ -254,7 +249,8 @@ static void ldlm_pool_recalc_stats(struct ldlm_pool *pl) } /** - * Sets SLV and Limit from ldlm_pl2ns(pl)->ns_obd tp passed \a pl. + * Sets SLV and Limit from container_of(pl, struct ldlm_namespace, + * ns_pool)->ns_obd tp passed \a pl. */ static void ldlm_cli_pool_pop_slv(struct ldlm_pool *pl) { @@ -264,7 +260,8 @@ static void ldlm_cli_pool_pop_slv(struct ldlm_pool *pl) * Get new SLV and Limit from obd which is updated with coming * RPCs. */ - obd = ldlm_pl2ns(pl)->ns_obd; + obd = container_of(pl, struct ldlm_namespace, + ns_pool)->ns_obd; LASSERT(obd != NULL); read_lock(&obd->obd_pool_lock); pl->pl_server_lock_volume = obd->obd_pool_slv; @@ -304,7 +301,8 @@ static int ldlm_cli_pool_recalc(struct ldlm_pool *pl) /* * Do not cancel locks in case lru resize is disabled for this ns. */ - if (!ns_connect_lru_resize(ldlm_pl2ns(pl))) { + if (!ns_connect_lru_resize(container_of(pl, struct ldlm_namespace, + ns_pool))) { ret = 0; goto out; } @@ -315,7 +313,8 @@ static int ldlm_cli_pool_recalc(struct ldlm_pool *pl) * It may be called when SLV has changed much, this is why we do not * take into account pl->pl_recalc_time here. */ - ret = ldlm_cancel_lru(ldlm_pl2ns(pl), 0, LCF_ASYNC, LDLM_CANCEL_LRUR); + ret = ldlm_cancel_lru(container_of(pl, struct ldlm_namespace, ns_pool), + 0, LCF_ASYNC, LDLM_CANCEL_LRUR); out: spin_lock(&pl->pl_lock); @@ -341,7 +340,7 @@ static int ldlm_cli_pool_shrink(struct ldlm_pool *pl, struct ldlm_namespace *ns; int unused; - ns = ldlm_pl2ns(pl); + ns = container_of(pl, struct ldlm_namespace, ns_pool); /* * Do not cancel locks in case lru resize is disabled for this ns. @@ -558,7 +557,8 @@ static struct kobj_type ldlm_pl_ktype = { static int ldlm_pool_sysfs_init(struct ldlm_pool *pl) { - struct ldlm_namespace *ns = ldlm_pl2ns(pl); + struct ldlm_namespace *ns = container_of(pl, struct ldlm_namespace, + ns_pool); int err; init_completion(&pl->pl_kobj_unregister); @@ -570,7 +570,8 @@ static int ldlm_pool_sysfs_init(struct ldlm_pool *pl) static int ldlm_pool_debugfs_init(struct ldlm_pool *pl) { - struct ldlm_namespace *ns = ldlm_pl2ns(pl); + struct ldlm_namespace *ns = container_of(pl, struct ldlm_namespace, + ns_pool); struct dentry *debugfs_ns_parent; struct lprocfs_vars pool_vars[2]; char *var_name = NULL; -- GitLab From 946d6f9577438f5d344aa8545fba2b7885118b5f Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Fri, 6 Nov 2015 23:13:56 +0530 Subject: [PATCH 0401/2855] Staging: lustre: ldlm_pool: Drop wrapper function Remove the function ldlm_pool_get_limit() and replace its calls with the function it wrapped. Signed-off-by: Shivani Bhardwaj Acked-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ldlm/ldlm_pool.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c index 2beb36b081a35..20cf38931ea75 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c @@ -207,14 +207,6 @@ static inline int ldlm_pool_t2gsp(unsigned int t) (t >> LDLM_POOL_GSP_STEP_SHIFT)); } -/** - * Returns current \a pl limit. - */ -static __u32 ldlm_pool_get_limit(struct ldlm_pool *pl) -{ - return atomic_read(&pl->pl_limit); -} - /** * Sets passed \a limit to \a pl. */ @@ -452,7 +444,7 @@ static int lprocfs_pool_state_seq_show(struct seq_file *m, void *unused) spin_lock(&pl->pl_lock); slv = pl->pl_server_lock_volume; clv = pl->pl_client_lock_volume; - limit = ldlm_pool_get_limit(pl); + limit = atomic_read(&pl->pl_limit); granted = atomic_read(&pl->pl_granted); grant_rate = atomic_read(&pl->pl_grant_rate); cancel_rate = atomic_read(&pl->pl_cancel_rate); -- GitLab From f7ec22b5fa0423d1bd7c5cf3f811c539307a595d Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Fri, 6 Nov 2015 23:14:32 +0530 Subject: [PATCH 0402/2855] Staging: lustre: ldlm_pool: Drop unneeded wrapper function Remove the function ldlm_pool_set_limit() and replace its calls with the function it wrapped. Signed-off-by: Shivani Bhardwaj Acked-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ldlm/ldlm_pool.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c index 20cf38931ea75..e59b2864180fd 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c @@ -207,14 +207,6 @@ static inline int ldlm_pool_t2gsp(unsigned int t) (t >> LDLM_POOL_GSP_STEP_SHIFT)); } -/** - * Sets passed \a limit to \a pl. - */ -static void ldlm_pool_set_limit(struct ldlm_pool *pl, __u32 limit) -{ - atomic_set(&pl->pl_limit, limit); -} - /** * Recalculates next stats on passed \a pl. * @@ -257,7 +249,7 @@ static void ldlm_cli_pool_pop_slv(struct ldlm_pool *pl) LASSERT(obd != NULL); read_lock(&obd->obd_pool_lock); pl->pl_server_lock_volume = obd->obd_pool_slv; - ldlm_pool_set_limit(pl, obd->obd_pool_limit); + atomic_set(&pl->pl_limit, obd->obd_pool_limit); read_unlock(&obd->obd_pool_lock); } @@ -678,7 +670,7 @@ int ldlm_pool_init(struct ldlm_pool *pl, struct ldlm_namespace *ns, snprintf(pl->pl_name, sizeof(pl->pl_name), "ldlm-pool-%s-%d", ldlm_ns_name(ns), idx); - ldlm_pool_set_limit(pl, 1); + atomic_set(&pl->pl_limit, 1); pl->pl_server_lock_volume = 0; pl->pl_ops = &ldlm_cli_pool_ops; pl->pl_recalc_period = LDLM_POOL_CLI_DEF_RECALC_PERIOD; -- GitLab From ed73749426deb2810d4b66a25d6441c5fe8de2b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Oudompheng?= Date: Mon, 2 Nov 2015 11:39:22 +0100 Subject: [PATCH 0403/2855] staging: rtl8188eu: jiffies are unsigned long MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove rtw_get_passing_time_ms function and adjust type of relevant variables. Signed-off-by: Rémy Oudompheng Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_efuse.c | 4 +- drivers/staging/rtl8188eu/core/rtw_mlme.c | 13 +++--- drivers/staging/rtl8188eu/core/rtw_mlme_ext.c | 43 ++++++++++++------- drivers/staging/rtl8188eu/core/rtw_pwrctrl.c | 14 +++--- .../staging/rtl8188eu/hal/rtl8188e_hal_init.c | 4 +- drivers/staging/rtl8188eu/hal/usb_halinit.c | 10 +++-- .../staging/rtl8188eu/include/osdep_service.h | 2 - drivers/staging/rtl8188eu/os_dep/os_intfs.c | 10 +++-- .../staging/rtl8188eu/os_dep/osdep_service.c | 6 --- drivers/staging/rtl8188eu/os_dep/usb_intf.c | 8 ++-- 10 files changed, 62 insertions(+), 52 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c index eb894233a7858..2320fb11af24d 100644 --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c @@ -224,7 +224,7 @@ static void efuse_read_phymap_from_txpktbuf( ) { u16 dbg_addr = 0; - u32 start = 0, passing_time = 0; + unsigned long start = 0; u8 reg_0x143 = 0; u32 lo32 = 0, hi32 = 0; u16 len = 0, count = 0; @@ -248,7 +248,7 @@ static void efuse_read_phymap_from_txpktbuf( usb_write8(adapter, REG_TXPKTBUF_DBG, 0); start = jiffies; while (!(reg_0x143 = usb_read8(adapter, REG_TXPKTBUF_DBG)) && - (passing_time = rtw_get_passing_time_ms(start)) < 1000) { + jiffies_to_msecs(jiffies - start) < 1000) { DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, usb_read8(adapter, 0x106)); usleep_range(1000, 2000); } diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c index c1b82f71b682b..1bf5c48198972 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c @@ -163,7 +163,8 @@ exit: static void _rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 isfreeall) { - u32 curr_time, delta_time; + unsigned long curr_time; + u32 delta_time; u32 lifetime = SCANQUEUE_LIFETIME; struct __queue *free_queue = &(pmlmepriv->free_bss_pool); @@ -272,7 +273,7 @@ int rtw_if_up(struct adapter *padapter) void rtw_generate_random_ibss(u8 *pibss) { - u32 curtime = jiffies; + unsigned long curtime = jiffies; pibss[0] = 0x02; /* in ad-hoc mode bit1 must set to 1 */ pibss[1] = 0x11; @@ -878,14 +879,14 @@ inline void rtw_indicate_scan_done(struct adapter *padapter, bool aborted) void rtw_scan_abort(struct adapter *adapter) { - u32 start; + unsigned long start; struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv); start = jiffies; pmlmeext->scan_abort = true; while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) && - rtw_get_passing_time_ms(start) <= 200) { + jiffies_to_msecs(jiffies - start) <= 200) { if (adapter->bDriverStopped || adapter->bSurpriseRemoved) break; DBG_88E(FUNC_NDEV_FMT"fw_state=_FW_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter->pnetdev)); @@ -1474,6 +1475,7 @@ static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv , struct wlan_network **candidate, struct wlan_network *competitor) { int updated = false; + unsigned long since_scan; struct adapter *adapter = container_of(pmlmepriv, struct adapter, mlmepriv); @@ -1494,7 +1496,8 @@ static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv goto exit; if (pmlmepriv->to_roaming) { - if (rtw_get_passing_time_ms((u32)competitor->last_scanned) >= RTW_SCAN_RESULT_EXPIRE || + since_scan = jiffies - competitor->last_scanned; + if (jiffies_to_msecs(since_scan) >= RTW_SCAN_RESULT_EXPIRE || is_same_ess(&competitor->network, &pmlmepriv->cur_network.network) == false) goto exit; } diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index a9bff48868ef4..3eca6874b6df9 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -708,7 +708,7 @@ static int issue_probereq_ex(struct adapter *padapter, { int ret; int i = 0; - u32 start = jiffies; + unsigned long start = jiffies; do { ret = issue_probereq(padapter, pssid, da, wait_ms > 0 ? true : false); @@ -732,11 +732,13 @@ static int issue_probereq_ex(struct adapter *padapter, if (da) DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n", FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter), - ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); + ret == _SUCCESS ? ", acked" : "", i, try_cnt, + jiffies_to_msecs(jiffies - start)); else DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter), - ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); + ret == _SUCCESS ? ", acked" : "", i, try_cnt, + jiffies_to_msecs(jiffies - start)); } exit: return ret; @@ -1293,7 +1295,7 @@ int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int pow { int ret; int i = 0; - u32 start = jiffies; + unsigned long start = jiffies; struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network); @@ -1323,11 +1325,13 @@ int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int pow if (da) DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n", FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter), - ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); + ret == _SUCCESS ? ", acked" : "", i, try_cnt, + jiffies_to_msecs(jiffies - start)); else DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter), - ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); + ret == _SUCCESS ? ", acked" : "", i, try_cnt, + jiffies_to_msecs(jiffies - start)); } exit: return ret; @@ -1418,7 +1422,7 @@ int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int { int ret; int i = 0; - u32 start = jiffies; + unsigned long start = jiffies; struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network); @@ -1448,11 +1452,13 @@ int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int if (da) DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n", FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter), - ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); + ret == _SUCCESS ? ", acked" : "", i, try_cnt, + jiffies_to_msecs(jiffies - start)); else DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter), - ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); + ret == _SUCCESS ? ", acked" : "", i, try_cnt, + jiffies_to_msecs(jiffies - start)); } exit: return ret; @@ -1530,7 +1536,7 @@ static int issue_deauth_ex(struct adapter *padapter, u8 *da, { int ret; int i = 0; - u32 start = jiffies; + unsigned long start = jiffies; do { ret = _issue_deauth(padapter, da, reason, wait_ms > 0 ? true : false); @@ -1553,11 +1559,13 @@ static int issue_deauth_ex(struct adapter *padapter, u8 *da, if (da) DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n", FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter), - ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); + ret == _SUCCESS ? ", acked" : "", i, try_cnt, + jiffies_to_msecs(jiffies - start)); else DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter), - ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); + ret == _SUCCESS ? ", acked" : "", i, try_cnt, + jiffies_to_msecs(jiffies - start)); } exit: return ret; @@ -1959,7 +1967,7 @@ unsigned int send_beacon(struct adapter *padapter) int issue = 0; int poll = 0; - u32 start = jiffies; + unsigned long start = jiffies; rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL); do { @@ -1975,13 +1983,16 @@ unsigned int send_beacon(struct adapter *padapter) if (padapter->bSurpriseRemoved || padapter->bDriverStopped) return _FAIL; if (!bxmitok) { - DBG_88E("%s fail! %u ms\n", __func__, rtw_get_passing_time_ms(start)); + DBG_88E("%s fail! %u ms\n", __func__, + jiffies_to_msecs(jiffies - start)); return _FAIL; } else { - u32 passing_time = rtw_get_passing_time_ms(start); + u32 passing_time = jiffies_to_msecs(jiffies - start); if (passing_time > 100 || issue > 3) - DBG_88E("%s success, issue:%d, poll:%d, %u ms\n", __func__, issue, poll, rtw_get_passing_time_ms(start)); + DBG_88E("%s success, issue:%d, poll:%d, %u ms\n", + __func__, issue, poll, + jiffies_to_msecs(jiffies - start)); return _SUCCESS; } } diff --git a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c index 9765946466ab6..5e1ef9fdcf475 100644 --- a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c @@ -348,7 +348,7 @@ void rtw_set_rpwm(struct adapter *padapter, u8 pslv) static u8 PS_RDY_CHECK(struct adapter *padapter) { - u32 curr_time, delta_time; + unsigned long curr_time, delta_time; struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); @@ -418,7 +418,7 @@ void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_a */ s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms) { - u32 start_time; + unsigned long start_time; u8 bAwake = false; s32 err = 0; @@ -435,7 +435,7 @@ s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms) break; } - if (rtw_get_passing_time_ms(start_time) > delay_ms) { + if (jiffies_to_msecs(jiffies - start_time) > delay_ms) { err = -1; DBG_88E("%s: Wait for FW LPS leave more than %u ms!!!\n", __func__, delay_ms); break; @@ -561,24 +561,24 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; unsigned long expires; + unsigned long start; int ret = _SUCCESS; expires = jiffies + msecs_to_jiffies(ips_deffer_ms); if (time_before(pwrpriv->ips_deny_time, expires)) pwrpriv->ips_deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms); -{ - u32 start = jiffies; + start = jiffies; if (pwrpriv->ps_processing) { DBG_88E("%s wait ps_processing...\n", __func__); - while (pwrpriv->ps_processing && rtw_get_passing_time_ms(start) <= 3000) + while (pwrpriv->ps_processing && + jiffies_to_msecs(jiffies - start) <= 3000) usleep_range(1000, 3000); if (pwrpriv->ps_processing) DBG_88E("%s wait ps_processing timeout\n", __func__); else DBG_88E("%s wait ps_processing done\n", __func__); } -} /* System suspend is not allowed to wakeup */ if ((!pwrpriv->bInternalAutoSuspend) && (pwrpriv->bInSuspend)) { diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c index e3e5d6f5d4f9b..03cf84c4bb061 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c @@ -53,7 +53,7 @@ s32 iol_execute(struct adapter *padapter, u8 control) { s32 status = _FAIL; u8 reg_0x88 = 0; - u32 start = 0, passing_time = 0; + unsigned long start = 0; control = control&0x0f; reg_0x88 = usb_read8(padapter, REG_HMEBOX_E0); @@ -61,7 +61,7 @@ s32 iol_execute(struct adapter *padapter, u8 control) start = jiffies; while ((reg_0x88 = usb_read8(padapter, REG_HMEBOX_E0)) & control && - (passing_time = rtw_get_passing_time_ms(start)) < 1000) { + jiffies_to_msecs(jiffies - start) < 1000) { ; } diff --git a/drivers/staging/rtl8188eu/hal/usb_halinit.c b/drivers/staging/rtl8188eu/hal/usb_halinit.c index 7e72259f0e400..5789e1e23f0a2 100644 --- a/drivers/staging/rtl8188eu/hal/usb_halinit.c +++ b/drivers/staging/rtl8188eu/hal/usb_halinit.c @@ -684,7 +684,7 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter) struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv; struct registry_priv *pregistrypriv = &Adapter->registrypriv; - u32 init_start_time = jiffies; + unsigned long init_start_time = jiffies; #define HAL_INIT_PROFILE_TAG(stage) do {} while (0) @@ -903,7 +903,8 @@ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_LCK); exit: HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END); - DBG_88E("%s in %dms\n", __func__, rtw_get_passing_time_ms(init_start_time)); + DBG_88E("%s in %dms\n", __func__, + jiffies_to_msecs(jiffies - init_start_time)); return status; @@ -1149,14 +1150,15 @@ static void _ReadRFType(struct adapter *Adapter) static void _ReadAdapterInfo8188EU(struct adapter *Adapter) { - u32 start = jiffies; + unsigned long start = jiffies; MSG_88E("====> %s\n", __func__); _ReadRFType(Adapter);/* rf_chip -> _InitRFType() */ _ReadPROMContent(Adapter); - MSG_88E("<==== %s in %d ms\n", __func__, rtw_get_passing_time_ms(start)); + MSG_88E("<==== %s in %d ms\n", __func__, + jiffies_to_msecs(jiffies - start)); } #define GPIO_DEBUG_PORT_NUM 0 diff --git a/drivers/staging/rtl8188eu/include/osdep_service.h b/drivers/staging/rtl8188eu/include/osdep_service.h index e24fe8cc3d0b7..22de53d6539ae 100644 --- a/drivers/staging/rtl8188eu/include/osdep_service.h +++ b/drivers/staging/rtl8188eu/include/osdep_service.h @@ -87,8 +87,6 @@ u32 _rtw_down_sema(struct semaphore *sema); void _rtw_init_queue(struct __queue *pqueue); -s32 rtw_get_passing_time_ms(u32 start); - struct rtw_netdev_priv_indicator { void *priv; u32 sizeof_priv; diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c index d063d02db7f09..9201b94d017c2 100644 --- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c +++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c @@ -1100,7 +1100,7 @@ netdev_open_error: int rtw_ips_pwr_up(struct adapter *padapter) { int result; - u32 start_time = jiffies; + unsigned long start_time = jiffies; DBG_88E("===> rtw_ips_pwr_up..............\n"); rtw_reset_drv_sw(padapter); @@ -1109,13 +1109,14 @@ int rtw_ips_pwr_up(struct adapter *padapter) rtw_led_control(padapter, LED_CTL_NO_LINK); - DBG_88E("<=== rtw_ips_pwr_up.............. in %dms\n", rtw_get_passing_time_ms(start_time)); + DBG_88E("<=== rtw_ips_pwr_up.............. in %dms\n", + jiffies_to_msecs(jiffies - start_time)); return result; } void rtw_ips_pwr_down(struct adapter *padapter) { - u32 start_time = jiffies; + unsigned long start_time = jiffies; DBG_88E("===> rtw_ips_pwr_down...................\n"); @@ -1124,7 +1125,8 @@ void rtw_ips_pwr_down(struct adapter *padapter) rtw_led_control(padapter, LED_CTL_POWER_OFF); rtw_ips_dev_unload(padapter); - DBG_88E("<=== rtw_ips_pwr_down..................... in %dms\n", rtw_get_passing_time_ms(start_time)); + DBG_88E("<=== rtw_ips_pwr_down..................... in %dms\n", + jiffies_to_msecs(jiffies - start_time)); } void rtw_ips_dev_unload(struct adapter *padapter) diff --git a/drivers/staging/rtl8188eu/os_dep/osdep_service.c b/drivers/staging/rtl8188eu/os_dep/osdep_service.c index 466cd76fc1c4f..d87b54711c0d5 100644 --- a/drivers/staging/rtl8188eu/os_dep/osdep_service.c +++ b/drivers/staging/rtl8188eu/os_dep/osdep_service.c @@ -77,12 +77,6 @@ void _rtw_init_queue(struct __queue *pqueue) spin_lock_init(&(pqueue->lock)); } -/* the input parameter start must be in jiffies */ -inline s32 rtw_get_passing_time_ms(u32 start) -{ - return jiffies_to_msecs(jiffies-start); -} - struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv) { diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index 82a7c27c517ff..01d50f7c1667e 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c @@ -227,7 +227,7 @@ static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message) struct net_device *pnetdev = padapter->pnetdev; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; - u32 start_time = jiffies; + unsigned long start_time = jiffies; pr_debug("==> %s (%s:%d)\n", __func__, current->comm, current->pid); @@ -282,7 +282,7 @@ static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message) exit: pr_debug("<=== %s .............. in %dms\n", __func__, - rtw_get_passing_time_ms(start_time)); + jiffies_to_msecs(jiffies - start_time)); return 0; } @@ -292,7 +292,7 @@ static int rtw_resume_process(struct adapter *padapter) struct net_device *pnetdev; struct pwrctrl_priv *pwrpriv = NULL; int ret = -1; - u32 start_time = jiffies; + unsigned long start_time = jiffies; pr_debug("==> %s (%s:%d)\n", __func__, current->comm, current->pid); @@ -323,7 +323,7 @@ exit: if (pwrpriv) pwrpriv->bInSuspend = false; pr_debug("<=== %s return %d.............. in %dms\n", __func__, - ret, rtw_get_passing_time_ms(start_time)); + ret, jiffies_to_msecs(jiffies - start_time)); return ret; } -- GitLab From 3913c19ae7a3ede2fa4f1787630fa71c55ff8d23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Oudompheng?= Date: Mon, 2 Nov 2015 11:43:09 +0100 Subject: [PATCH 0404/2855] staging: rtl8188eu: add missing delay in polling loops. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously the code could exit with failure too early. Signed-off-by: Rémy Oudompheng Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c index 03cf84c4bb061..2592bc298f848 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c @@ -62,7 +62,7 @@ s32 iol_execute(struct adapter *padapter, u8 control) start = jiffies; while ((reg_0x88 = usb_read8(padapter, REG_HMEBOX_E0)) & control && jiffies_to_msecs(jiffies - start) < 1000) { - ; + udelay(5); } reg_0x88 = usb_read8(padapter, REG_HMEBOX_E0); @@ -242,6 +242,7 @@ static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data) status = _FAIL; break; } + udelay(5); } while (count++); return status; -- GitLab From 2b5a10a923e6541f20581b0557785a55e0039436 Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 3 Nov 2015 00:16:09 +0700 Subject: [PATCH 0405/2855] staging: rtl8188eu: do .. while (0) loop replaced by while (...) loop It is a simple and clear representation of this loop. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_cmd.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index 9b7026e7d55b6..f0ac66de34d67 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c @@ -242,15 +242,11 @@ post_process: pcmdpriv->cmdthd_running = false; /* free all cmd_obj resources */ - do { - pcmd = rtw_dequeue_cmd(&pcmdpriv->cmd_queue); - if (pcmd == NULL) - break; - + while ((pcmd = rtw_dequeue_cmd(&pcmdpriv->cmd_queue))) { /* DBG_88E("%s: leaving... drop cmdcode:%u\n", __func__, pcmd->cmdcode); */ rtw_free_cmd_obj(pcmd); - } while (1); + } up(&pcmdpriv->terminate_cmdthread_sema); -- GitLab From 72fb6c5a9dbc8cff8308d42b9de4f7c49bbcdcb4 Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 3 Nov 2015 00:16:28 +0700 Subject: [PATCH 0406/2855] staging: rtl8188eu: while loop replaced by for loop Here is more suitable for loop. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_mlme.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c index 1bf5c48198972..abab854e68898 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c @@ -366,20 +366,13 @@ struct wlan_network *rtw_get_oldest_wlan_network(struct __queue *scanned_queue) phead = get_list_head(scanned_queue); - plist = phead->next; - - while (1) { - if (phead == plist) - break; - + for (plist = phead->next; plist != phead; plist = plist->next) { pwlan = container_of(plist, struct wlan_network, list); if (!pwlan->fixed) { if (oldest == NULL || time_after(oldest->last_scanned, pwlan->last_scanned)) oldest = pwlan; } - - plist = plist->next; } return oldest; } -- GitLab From 37efd082311371ad387d9067128e5924eebd5790 Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 3 Nov 2015 00:16:53 +0700 Subject: [PATCH 0407/2855] staging: rtl8188eu: 'infinite' loop removed The body of this loop is executed only once, so it can be removed. In this loop no keyword 'continue', only 'break' at the end. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8188eu/hal/rtl8188eu_xmit.c | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c index 7c5086ecff170..e04303ce80af8 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c @@ -463,30 +463,26 @@ s32 rtl8188eu_xmitframe_complete(struct adapter *adapt, struct xmit_priv *pxmitp } /* 3 1. pick up first frame */ - do { - rtw_free_xmitframe(pxmitpriv, pxmitframe); - - pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); - if (pxmitframe == NULL) { - /* no more xmit frame, release xmit buffer */ - rtw_free_xmitbuf(pxmitpriv, pxmitbuf); - return false; - } + rtw_free_xmitframe(pxmitpriv, pxmitframe); - pxmitframe->pxmitbuf = pxmitbuf; - pxmitframe->buf_addr = pxmitbuf->pbuf; - pxmitbuf->priv_data = pxmitframe; + pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); + if (pxmitframe == NULL) { + /* no more xmit frame, release xmit buffer */ + rtw_free_xmitbuf(pxmitpriv, pxmitbuf); + return false; + } - pxmitframe->agg_num = 1; /* alloc xmitframe should assign to 1. */ - pxmitframe->pkt_offset = 1; /* first frame of aggregation, reserve offset */ + pxmitframe->pxmitbuf = pxmitbuf; + pxmitframe->buf_addr = pxmitbuf->pbuf; + pxmitbuf->priv_data = pxmitframe; - rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe); + pxmitframe->agg_num = 1; /* alloc xmitframe should assign to 1. */ + pxmitframe->pkt_offset = 1; /* first frame of aggregation, reserve offset */ - /* always return ndis_packet after rtw_xmitframe_coalesce */ - rtw_os_xmit_complete(adapt, pxmitframe); + rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe); - break; - } while (1); + /* always return ndis_packet after rtw_xmitframe_coalesce */ + rtw_os_xmit_complete(adapt, pxmitframe); /* 3 2. aggregate same priority and same DA(AP or STA) frames */ pfirstframe = pxmitframe; -- GitLab From 6d9b0f00ecf3f991ae8d4124211cad7c5122cbbc Mon Sep 17 00:00:00 2001 From: Abdul Hussain Date: Tue, 3 Nov 2015 05:30:56 +0000 Subject: [PATCH 0408/2855] Staging: rtl8188eu: fix space prohibited before that ',' This patch fixes the following checkpatch.pl error: fix space prohibited before that ',' Signed-off-by: Abdul Hussain Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_xmit.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_xmit.c b/drivers/staging/rtl8188eu/core/rtw_xmit.c index 11dbfc060b0d2..e778132b73dca 100644 --- a/drivers/staging/rtl8188eu/core/rtw_xmit.c +++ b/drivers/staging/rtl8188eu/core/rtw_xmit.c @@ -641,7 +641,7 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr if (pattrib->psta) stainfo = pattrib->psta; else - stainfo = rtw_get_stainfo(&padapter->stapriv , &pattrib->ra[0]); + stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]); hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ); @@ -1702,12 +1702,12 @@ u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe) return addr; } -static void do_queue_select(struct adapter *padapter, struct pkt_attrib *pattrib) +static void do_queue_select(struct adapter *padapter, struct pkt_attrib *pattrib) { u8 qsel; qsel = pattrib->priority; - RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("### do_queue_select priority=%d , qsel = %d\n", pattrib->priority , qsel)); + RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("### do_queue_select priority=%d , qsel = %d\n", pattrib->priority, qsel)); pattrib->qsel = qsel; } -- GitLab From 52863d83f3112b009aec82403c63f8fcf1c6c4cb Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 3 Nov 2015 16:43:53 +0700 Subject: [PATCH 0409/2855] staging: rtl8188eu: *(ptr + i) replaced by ptr[i] in _rtl88e_fw_block_write It is better to read. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/fw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index 23aa6d37acac7..af93697a6ab9c 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -68,7 +68,7 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, for (i = 0; i < blk_cnt; i++) { offset = i * blk_sz; usb_write32(adapt, (FW_8192C_START_ADDRESS + offset), - *(pu4BytePtr + i)); + pu4BytePtr[i]); } if (remain) { @@ -76,7 +76,7 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, buf_ptr += offset; for (i = 0; i < remain; i++) { usb_write8(adapt, (FW_8192C_START_ADDRESS + - offset + i), *(buf_ptr + i)); + offset + i), buf_ptr[i]); } } } -- GitLab From d44f58f7c5c737c6f95f3adf4af00a4a19746d9f Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 3 Nov 2015 16:45:00 +0700 Subject: [PATCH 0410/2855] staging: rtl8188eu: assigning a value to the variable is replaced by the increment It is made to the initial value could be placed in the offset variable. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/fw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index af93697a6ab9c..70825e05fae9b 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -65,10 +65,12 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, blk_cnt = size / blk_sz; remain = size % blk_sz; + offset = 0; + for (i = 0; i < blk_cnt; i++) { - offset = i * blk_sz; usb_write32(adapt, (FW_8192C_START_ADDRESS + offset), pu4BytePtr[i]); + offset += blk_sz; } if (remain) { -- GitLab From 1c48deffc7fa48a341ccc4bcef41f8ce2eab645f Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 3 Nov 2015 16:46:08 +0700 Subject: [PATCH 0411/2855] staging: rtl8188eu: initial value placed in the variable Line become shorter. After the loop offset variable points to the location following insertion. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/fw.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index 70825e05fae9b..99dd1f03afec5 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -65,11 +65,10 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, blk_cnt = size / blk_sz; remain = size % blk_sz; - offset = 0; + offset = FW_8192C_START_ADDRESS; for (i = 0; i < blk_cnt; i++) { - usb_write32(adapt, (FW_8192C_START_ADDRESS + offset), - pu4BytePtr[i]); + usb_write32(adapt, offset, pu4BytePtr[i]); offset += blk_sz; } -- GitLab From 37d5579095b380f3328a5106354c0999eeca60f2 Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 3 Nov 2015 16:46:53 +0700 Subject: [PATCH 0412/2855] staging: rtl8188eu: offset variable replaced by its value It is now possible to get rid of re-initializing the offset variable. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/fw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index 99dd1f03afec5..9673686bdc47f 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -74,7 +74,7 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, if (remain) { offset = blk_cnt * blk_sz; - buf_ptr += offset; + buf_ptr += blk_cnt * blk_sz; for (i = 0; i < remain; i++) { usb_write8(adapt, (FW_8192C_START_ADDRESS + offset + i), buf_ptr[i]); -- GitLab From 8107b147d78ba5f04ed5e809041b17273c1f5a02 Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 3 Nov 2015 16:47:32 +0700 Subject: [PATCH 0413/2855] staging: rtl8188eu: unnecessary variable override removed Variable value calculated in the previous loop. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/fw.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index 9673686bdc47f..39c5a055fc1b8 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -73,11 +73,9 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, } if (remain) { - offset = blk_cnt * blk_sz; buf_ptr += blk_cnt * blk_sz; for (i = 0; i < remain; i++) { - usb_write8(adapt, (FW_8192C_START_ADDRESS + - offset + i), buf_ptr[i]); + usb_write8(adapt, offset + i, buf_ptr[i]); } } } -- GitLab From f464b3a08cefe3febcd30068d0a7ecd28f085b2d Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 3 Nov 2015 16:48:22 +0700 Subject: [PATCH 0414/2855] staging: rtl8188eu: unnecessary branching removed If the 'remain' is zero, the loop is not executed at all. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/fw.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index 39c5a055fc1b8..44e807803a363 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -72,11 +72,9 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, offset += blk_sz; } - if (remain) { - buf_ptr += blk_cnt * blk_sz; - for (i = 0; i < remain; i++) { - usb_write8(adapt, offset + i, buf_ptr[i]); - } + buf_ptr += blk_cnt * blk_sz; + for (i = 0; i < remain; i++) { + usb_write8(adapt, offset + i, buf_ptr[i]); } } -- GitLab From ec60e037c7e3e6b38b5c153d009d4f9161dd9e16 Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 3 Nov 2015 16:49:13 +0700 Subject: [PATCH 0415/2855] staging: rtl8188eu: offset increment placed into for loop header It makes the code little easier. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/fw.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index 44e807803a363..3cfd2b2bc8681 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -67,14 +67,13 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, offset = FW_8192C_START_ADDRESS; - for (i = 0; i < blk_cnt; i++) { + for (i = 0; i < blk_cnt; i++, offset += blk_sz) { usb_write32(adapt, offset, pu4BytePtr[i]); - offset += blk_sz; } buf_ptr += blk_cnt * blk_sz; - for (i = 0; i < remain; i++) { - usb_write8(adapt, offset + i, buf_ptr[i]); + for (i = 0; i < remain; i++, offset++) { + usb_write8(adapt, offset, buf_ptr[i]); } } -- GitLab From 1e7e93ee6da0ee4c9054a9cb70748f1c34fe15bf Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 3 Nov 2015 16:51:11 +0700 Subject: [PATCH 0416/2855] staging: rtl8188eu: buf_ptr variable completely defined in a single line It is simpler. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/fw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index 3cfd2b2bc8681..4f1c3a2997b8c 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -71,7 +71,7 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, usb_write32(adapt, offset, pu4BytePtr[i]); } - buf_ptr += blk_cnt * blk_sz; + buf_ptr = buffer + blk_cnt * blk_sz; for (i = 0; i < remain; i++, offset++) { usb_write8(adapt, offset, buf_ptr[i]); } -- GitLab From 645d2a8f463c70f27fef2507952b71fdae71cf41 Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 3 Nov 2015 16:51:47 +0700 Subject: [PATCH 0417/2855] staging: rtl8188eu: types of local variables conformed with types of function arguments The array should not change in any case. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/fw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index 4f1c3a2997b8c..8eafd7e34f4a7 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -58,8 +58,8 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, const u8 *buffer, u32 size) { u32 blk_sz = sizeof(u32); - u8 *buf_ptr = (u8 *)buffer; - u32 *pu4BytePtr = (u32 *)buffer; + const u8 *buf_ptr = (u8 *)buffer; + const u32 *pu4BytePtr = (u32 *)buffer; u32 i, offset, blk_cnt, remain; blk_cnt = size / blk_sz; -- GitLab From 429078e1f1ddf549ff9e282ed4a485b607b945cb Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 3 Nov 2015 16:52:23 +0700 Subject: [PATCH 0418/2855] staging: rtl8188eu: unnecessary initialization removed It is superfluous. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/fw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index 8eafd7e34f4a7..b48f4447dc40f 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -58,7 +58,7 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, const u8 *buffer, u32 size) { u32 blk_sz = sizeof(u32); - const u8 *buf_ptr = (u8 *)buffer; + const u8 *buf_ptr; const u32 *pu4BytePtr = (u32 *)buffer; u32 i, offset, blk_cnt, remain; -- GitLab From 6e84aa6c8251f9d5cb086cb9ba8d1a59a59e5cd9 Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 3 Nov 2015 16:53:43 +0700 Subject: [PATCH 0419/2855] staging: rtl8188eu: unnessesary braces for single statement block removed checkpatch fix: WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/fw.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index b48f4447dc40f..04ae5836d1219 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -67,14 +67,12 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, offset = FW_8192C_START_ADDRESS; - for (i = 0; i < blk_cnt; i++, offset += blk_sz) { + for (i = 0; i < blk_cnt; i++, offset += blk_sz) usb_write32(adapt, offset, pu4BytePtr[i]); - } buf_ptr = buffer + blk_cnt * blk_sz; - for (i = 0; i < remain; i++, offset++) { + for (i = 0; i < remain; i++, offset++) usb_write8(adapt, offset, buf_ptr[i]); - } } static void _rtl88e_fill_dummy(u8 *pfwbuf, u32 *pfwlen) -- GitLab From 988c5146885f0f16e9124b4ae8e840229c4dc6d6 Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 3 Nov 2015 16:54:10 +0700 Subject: [PATCH 0420/2855] staging: rtl8188eu: buf_ptr renamed to byte_buffer This name is better suited for this variable. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/fw.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index 04ae5836d1219..f8f212f1e0afa 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -58,7 +58,7 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, const u8 *buffer, u32 size) { u32 blk_sz = sizeof(u32); - const u8 *buf_ptr; + const u8 *byte_buffer; const u32 *pu4BytePtr = (u32 *)buffer; u32 i, offset, blk_cnt, remain; @@ -70,9 +70,9 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, for (i = 0; i < blk_cnt; i++, offset += blk_sz) usb_write32(adapt, offset, pu4BytePtr[i]); - buf_ptr = buffer + blk_cnt * blk_sz; + byte_buffer = buffer + blk_cnt * blk_sz; for (i = 0; i < remain; i++, offset++) - usb_write8(adapt, offset, buf_ptr[i]); + usb_write8(adapt, offset, byte_buffer[i]); } static void _rtl88e_fill_dummy(u8 *pfwbuf, u32 *pfwlen) -- GitLab From 7e91b28a015e1b478fe5e872dc8e46fc867c418f Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 3 Nov 2015 16:54:28 +0700 Subject: [PATCH 0421/2855] staging: rtl8188eu: pu4BytePtr renamed to dword_buffer This name is better suited for this variable. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/fw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index f8f212f1e0afa..059e7ee761ca1 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -59,7 +59,7 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, { u32 blk_sz = sizeof(u32); const u8 *byte_buffer; - const u32 *pu4BytePtr = (u32 *)buffer; + const u32 *dword_buffer = (u32 *)buffer; u32 i, offset, blk_cnt, remain; blk_cnt = size / blk_sz; @@ -68,7 +68,7 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, offset = FW_8192C_START_ADDRESS; for (i = 0; i < blk_cnt; i++, offset += blk_sz) - usb_write32(adapt, offset, pu4BytePtr[i]); + usb_write32(adapt, offset, dword_buffer[i]); byte_buffer = buffer + blk_cnt * blk_sz; for (i = 0; i < remain; i++, offset++) -- GitLab From 13cab3d422e89ccdcc78377e76299a2fdb4df90b Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 3 Nov 2015 16:54:45 +0700 Subject: [PATCH 0422/2855] staging: rtl8188eu: offset renamed to write_address This name is better suited for this variable. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/fw.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index 059e7ee761ca1..8c0230125d00d 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -60,19 +60,19 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, u32 blk_sz = sizeof(u32); const u8 *byte_buffer; const u32 *dword_buffer = (u32 *)buffer; - u32 i, offset, blk_cnt, remain; + u32 i, write_address, blk_cnt, remain; blk_cnt = size / blk_sz; remain = size % blk_sz; - offset = FW_8192C_START_ADDRESS; + write_address = FW_8192C_START_ADDRESS; - for (i = 0; i < blk_cnt; i++, offset += blk_sz) - usb_write32(adapt, offset, dword_buffer[i]); + for (i = 0; i < blk_cnt; i++, write_address += blk_sz) + usb_write32(adapt, write_address, dword_buffer[i]); byte_buffer = buffer + blk_cnt * blk_sz; - for (i = 0; i < remain; i++, offset++) - usb_write8(adapt, offset, byte_buffer[i]); + for (i = 0; i < remain; i++, write_address++) + usb_write8(adapt, write_address, byte_buffer[i]); } static void _rtl88e_fill_dummy(u8 *pfwbuf, u32 *pfwlen) -- GitLab From 08ecab13e1677396edcd57459e47d25272f9179b Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Wed, 4 Nov 2015 18:58:41 +0700 Subject: [PATCH 0423/2855] staging: rtl8188eu: for loop instead of while loop used The range of elements to fill with zeros is determined by using a roundup macro Signed-off-by: Ivan Safonov Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/fw.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index 8c0230125d00d..4d72537644b3a 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -77,18 +77,12 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, static void _rtl88e_fill_dummy(u8 *pfwbuf, u32 *pfwlen) { - u32 fwlen = *pfwlen; - u8 remain = (u8)(fwlen % 4); + u32 i; - remain = (remain == 0) ? 0 : (4 - remain); + for (i = *pfwlen; i < roundup(*pfwlen, 4); i++) + pfwbuf[i] = 0; - while (remain > 0) { - pfwbuf[fwlen] = 0; - fwlen++; - remain--; - } - - *pfwlen = fwlen; + *pfwlen = i; } static void _rtl88e_fw_page_write(struct adapter *adapt, -- GitLab From 940f90eae69b6f548c9c03c416bccb5331e6bfac Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Thu, 5 Nov 2015 16:56:38 +0700 Subject: [PATCH 0424/2855] staging: rtl8188eu: rarely used macros replaced by their definitions IS_* macros (except one) occur only once. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/hal_com.c | 14 +++++++------- drivers/staging/rtl8188eu/hal/rtl8188e_dm.c | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/hal_com.c b/drivers/staging/rtl8188eu/hal/hal_com.c index 38e9fdc312d33..3871cda2eec2e 100644 --- a/drivers/staging/rtl8188eu/hal/hal_com.c +++ b/drivers/staging/rtl8188eu/hal/hal_com.c @@ -32,19 +32,19 @@ void dump_chip_info(struct HAL_VERSION chip_vers) char buf[128]; cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8188E_"); - cnt += sprintf((buf+cnt), "%s_", IS_NORMAL_CHIP(chip_vers) ? + cnt += sprintf((buf+cnt), "%s_", chip_vers.ChipType == NORMAL_CHIP ? "Normal_Chip" : "Test_Chip"); - cnt += sprintf((buf+cnt), "%s_", IS_CHIP_VENDOR_TSMC(chip_vers) ? + cnt += sprintf((buf+cnt), "%s_", chip_vers.VendorType == CHIP_VENDOR_TSMC ? "TSMC" : "UMC"); - if (IS_A_CUT(chip_vers)) + if (chip_vers.CUTVersion == A_CUT_VERSION) cnt += sprintf((buf+cnt), "A_CUT_"); - else if (IS_B_CUT(chip_vers)) + else if (chip_vers.CUTVersion == B_CUT_VERSION) cnt += sprintf((buf+cnt), "B_CUT_"); - else if (IS_C_CUT(chip_vers)) + else if (chip_vers.CUTVersion == C_CUT_VERSION) cnt += sprintf((buf+cnt), "C_CUT_"); - else if (IS_D_CUT(chip_vers)) + else if (chip_vers.CUTVersion == D_CUT_VERSION) cnt += sprintf((buf+cnt), "D_CUT_"); - else if (IS_E_CUT(chip_vers)) + else if (chip_vers.CUTVersion == E_CUT_VERSION) cnt += sprintf((buf+cnt), "E_CUT_"); else cnt += sprintf((buf+cnt), "UNKNOWN_CUT(%d)_", diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c b/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c index fca590949409c..199a77acd7a9c 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c @@ -67,7 +67,7 @@ static void Init_ODM_ComInfo_88E(struct adapter *Adapter) ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_FAB_VER, fab_ver); ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_CUT_VER, cut_ver); - ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_MP_TEST_CHIP, IS_NORMAL_CHIP(hal_data->VersionID)); + ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_MP_TEST_CHIP, hal_data->VersionID.ChipType == NORMAL_CHIP ? true : false); ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_PATCH_ID, hal_data->CustomerID); ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_BWIFI_TEST, Adapter->registrypriv.wifi_spec); -- GitLab From d14c07f6ff63d43c536c312c1b14837d44dbe020 Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Thu, 5 Nov 2015 16:58:56 +0700 Subject: [PATCH 0425/2855] staging: rtl8188eu: unused macros removed IS_* and GET_CVID_* macros have not been used. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8188eu/core/rtw_ioctl_set.c | 7 ---- drivers/staging/rtl8188eu/include/HalVerDef.h | 33 ------------------- 2 files changed, 40 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c index 22f5b45f5f7fc..cf60717a6c19f 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c @@ -27,13 +27,6 @@ extern void indicate_wx_scan_complete_event(struct adapter *padapter); -#define IS_MAC_ADDRESS_BROADCAST(addr) \ -(\ - ((addr[0] == 0xff) && (addr[1] == 0xff) && \ - (addr[2] == 0xff) && (addr[3] == 0xff) && \ - (addr[4] == 0xff) && (addr[5] == 0xff)) ? true : false \ -) - u8 rtw_do_join(struct adapter *padapter) { struct list_head *plist, *phead; diff --git a/drivers/staging/rtl8188eu/include/HalVerDef.h b/drivers/staging/rtl8188eu/include/HalVerDef.h index 56b4ff08e509c..6f2b2a436b04a 100644 --- a/drivers/staging/rtl8188eu/include/HalVerDef.h +++ b/drivers/staging/rtl8188eu/include/HalVerDef.h @@ -47,37 +47,4 @@ struct HAL_VERSION { enum HAL_VENDOR VendorType; }; -/* Get element */ -#define GET_CVID_CHIP_TYPE(version) (((version).ChipType)) -#define GET_CVID_MANUFACTUER(version) (((version).VendorType)) -#define GET_CVID_CUT_VERSION(version) (((version).CUTVersion)) - -/* Common Macro. -- */ -/* HAL_VERSION VersionID */ - -/* HAL_CHIP_TYPE_E */ -#define IS_TEST_CHIP(version) \ - ((GET_CVID_CHIP_TYPE(version) == TEST_CHIP) ? true : false) -#define IS_NORMAL_CHIP(version) \ - ((GET_CVID_CHIP_TYPE(version) == NORMAL_CHIP) ? true : false) - -/* HAL_CUT_VERSION_E */ -#define IS_A_CUT(version) \ - ((GET_CVID_CUT_VERSION(version) == A_CUT_VERSION) ? true : false) -#define IS_B_CUT(version) \ - ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? true : false) -#define IS_C_CUT(version) \ - ((GET_CVID_CUT_VERSION(version) == C_CUT_VERSION) ? true : false) -#define IS_D_CUT(version) \ - ((GET_CVID_CUT_VERSION(version) == D_CUT_VERSION) ? true : false) -#define IS_E_CUT(version) \ - ((GET_CVID_CUT_VERSION(version) == E_CUT_VERSION) ? true : false) - - -/* HAL_VENDOR_E */ -#define IS_CHIP_VENDOR_TSMC(version) \ - ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_TSMC) ? true : false) -#define IS_CHIP_VENDOR_UMC(version) \ - ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_UMC) ? true : false) - #endif -- GitLab From 4a3bda22fdf0b9ccc674675cbe87d781207c799e Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Fri, 6 Nov 2015 22:17:29 +0700 Subject: [PATCH 0426/2855] staging: rtl8188eu: goto replaced by 'else' branch goto is not needed here. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_cmd.c | 25 +++++++++++------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index f0ac66de34d67..f90a2bfbb8199 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c @@ -201,23 +201,20 @@ _next: if (rtw_cmd_filter(pcmdpriv, pcmd) == _FAIL) { pcmd->res = H2C_DROPPED; - goto post_process; - } - - if (pcmd->cmdcode < ARRAY_SIZE(wlancmds)) { - cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns; - - if (cmd_hdl) { - ret = cmd_hdl(pcmd->padapter, pcmd->parmbuf); - pcmd->res = ret; - } } else { - pcmd->res = H2C_PARAMETERS_ERROR; - } + if (pcmd->cmdcode < ARRAY_SIZE(wlancmds)) { + cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns; - cmd_hdl = NULL; + if (cmd_hdl) { + ret = cmd_hdl(pcmd->padapter, pcmd->parmbuf); + pcmd->res = ret; + } + } else { + pcmd->res = H2C_PARAMETERS_ERROR; + } -post_process: + cmd_hdl = NULL; + } /* call callback function for post-processed */ if (pcmd->cmdcode < ARRAY_SIZE(rtw_cmd_callback)) { -- GitLab From 25e168a4a367eca8bdab3456ac73758290e8aab5 Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Fri, 6 Nov 2015 22:20:17 +0700 Subject: [PATCH 0427/2855] staging: rtl8188eu: goto removed malloc error handling moved into one place. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_cmd.c | 67 +++++------------------- 1 file changed, 13 insertions(+), 54 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index f90a2bfbb8199..433b926ceae76 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c @@ -563,31 +563,19 @@ u8 rtw_setopmode_cmd(struct adapter *padapter, enum ndis_802_11_network_infra n struct setopmode_parm *psetop; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - u8 res = _SUCCESS; - ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); - if (ph2c == NULL) { - res = false; - goto exit; - } psetop = kzalloc(sizeof(struct setopmode_parm), GFP_KERNEL); - - if (psetop == NULL) { + if (!ph2c || !psetop) { kfree(ph2c); - res = false; - goto exit; + kfree(psetop); + return false; } init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_); psetop->mode = (u8)networktype; - res = rtw_enqueue_cmd(pcmdpriv, ph2c); - -exit: - - - return res; + return rtw_enqueue_cmd(pcmdpriv, ph2c); } u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key) @@ -600,28 +588,16 @@ u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key) struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; struct sta_info *sta = (struct sta_info *)psta; - u8 res = _SUCCESS; - ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); - if (ph2c == NULL) { - res = _FAIL; - goto exit; - } - psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL); - if (psetstakey_para == NULL) { - kfree(ph2c); - res = _FAIL; - goto exit; - } - psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp), GFP_KERNEL); - if (psetstakey_rsp == NULL) { + + if (!ph2c || !psetstakey_para || !psetstakey_rsp) { kfree(ph2c); kfree(psetstakey_para); - res = _FAIL; - goto exit; + kfree(psetstakey_rsp); + return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); @@ -643,12 +619,7 @@ u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key) /* jeff: set this because at least sw key is ready */ padapter->securitypriv.busetkipkey = true; - res = rtw_enqueue_cmd(pcmdpriv, ph2c); - -exit: - - - return res; + return rtw_enqueue_cmd(pcmdpriv, ph2c); } u8 rtw_clearstakey_cmd(struct adapter *padapter, u8 *psta, u8 entry, u8 enqueue) @@ -1079,31 +1050,19 @@ u8 rtw_ps_cmd(struct adapter *padapter) struct drvextra_cmd_parm *pdrvextra_cmd_parm; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - u8 res = _SUCCESS; - ppscmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); - if (ppscmd == NULL) { - res = _FAIL; - goto exit; - } - pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); - if (pdrvextra_cmd_parm == NULL) { + if (!ppscmd || !pdrvextra_cmd_parm) { kfree(ppscmd); - res = _FAIL; - goto exit; + kfree(pdrvextra_cmd_parm); + return _FAIL; } pdrvextra_cmd_parm->ec_id = POWER_SAVING_CTRL_WK_CID; pdrvextra_cmd_parm->pbuf = NULL; init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); - res = rtw_enqueue_cmd(pcmdpriv, ppscmd); - -exit: - - - return res; + return rtw_enqueue_cmd(pcmdpriv, ppscmd); } #ifdef CONFIG_88EU_AP_MODE -- GitLab From fabb93f18fdbb1b9eebb799fd7b69610799f25a9 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Thu, 29 Oct 2015 16:44:08 +0900 Subject: [PATCH 0428/2855] staging: most: remove multiple blank lines This patch removes multiple blank lines found by checkpatch. CHECK: Please don't use multiple blank lines Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/aim-network/networking.h | 2 -- drivers/staging/most/hdm-dim2/dim2_errors.h | 2 -- drivers/staging/most/hdm-dim2/dim2_hal.h | 3 --- drivers/staging/most/hdm-dim2/dim2_reg.h | 3 --- drivers/staging/most/hdm-dim2/dim2_sysfs.h | 3 --- drivers/staging/most/mostcore/mostcore.h | 2 -- 6 files changed, 15 deletions(-) diff --git a/drivers/staging/most/aim-network/networking.h b/drivers/staging/most/aim-network/networking.h index 1b8b434fabb0c..6f346d410525e 100644 --- a/drivers/staging/most/aim-network/networking.h +++ b/drivers/staging/most/aim-network/networking.h @@ -15,9 +15,7 @@ #include "mostcore.h" - void most_deliver_netinfo(struct most_interface *iface, unsigned char link_stat, unsigned char *mac_addr); - #endif diff --git a/drivers/staging/most/hdm-dim2/dim2_errors.h b/drivers/staging/most/hdm-dim2/dim2_errors.h index 314f7de2be73d..5a713df1d1d4d 100644 --- a/drivers/staging/most/hdm-dim2/dim2_errors.h +++ b/drivers/staging/most/hdm-dim2/dim2_errors.h @@ -19,7 +19,6 @@ extern "C" { #endif - /** * MOST DIM errors. */ @@ -59,7 +58,6 @@ enum dim_errors_t { DIM_ERR_OVERFLOW, }; - #ifdef __cplusplus } #endif diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index ebb7d87a45fcf..94ea6c7827f1c 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -17,7 +17,6 @@ #include - #ifdef __cplusplus extern "C" { #endif @@ -66,7 +65,6 @@ struct dim_channel { u16 done_sw_buffers_number; /*< Done software buffers number. */ }; - u8 DIM_Startup(void *dim_base_address, u32 mlb_clock); void DIM_Shutdown(void); @@ -111,7 +109,6 @@ void DIMCB_IoWrite(u32 *ptr32, u32 value); void DIMCB_OnError(u8 error_id, const char *error_message); - #ifdef __cplusplus } #endif diff --git a/drivers/staging/most/hdm-dim2/dim2_reg.h b/drivers/staging/most/hdm-dim2/dim2_reg.h index 476f66f4c5662..0795aae05f1cd 100644 --- a/drivers/staging/most/hdm-dim2/dim2_reg.h +++ b/drivers/staging/most/hdm-dim2/dim2_reg.h @@ -21,7 +21,6 @@ extern "C" { #endif - struct dim2_regs { /* 0x00 */ u32 MLBC0; /* 0x01 */ u32 rsvd0[1]; @@ -67,7 +66,6 @@ struct dim2_regs { /* 0xF7 */ u32 ACMR1; }; - #define DIM2_MASK(n) (~((~(u32)0)<<(n))) enum { @@ -168,7 +166,6 @@ enum { CAT_CL_MASK = DIM2_MASK(6) }; - #ifdef __cplusplus } #endif diff --git a/drivers/staging/most/hdm-dim2/dim2_sysfs.h b/drivers/staging/most/hdm-dim2/dim2_sysfs.h index e719691035b08..b71dd027ebc76 100644 --- a/drivers/staging/most/hdm-dim2/dim2_sysfs.h +++ b/drivers/staging/most/hdm-dim2/dim2_sysfs.h @@ -16,10 +16,8 @@ #ifndef DIM2_SYSFS_H #define DIM2_SYSFS_H - #include - struct medialb_bus { struct kobject kobj_group; }; @@ -35,5 +33,4 @@ void dim2_sysfs_destroy(struct medialb_bus *bus); */ bool dim2_sysfs_get_state_cb(void); - #endif /* DIM2_SYSFS_H */ diff --git a/drivers/staging/most/mostcore/mostcore.h b/drivers/staging/most/mostcore/mostcore.h index e148b324331a4..bda3850d54358 100644 --- a/drivers/staging/most/mostcore/mostcore.h +++ b/drivers/staging/most/mostcore/mostcore.h @@ -60,7 +60,6 @@ enum most_channel_data_type { MOST_CH_SYNC = 1 << 5, }; - enum mbo_status_flags { /* MBO was processed successfully (data was send or received )*/ MBO_SUCCESS = 0, @@ -317,5 +316,4 @@ int most_start_channel(struct most_interface *iface, int channel_idx, int most_stop_channel(struct most_interface *iface, int channel_idx, struct most_aim *); - #endif /* MOST_CORE_H_ */ -- GitLab From 23242684c150835602a7f8cf10d530761f8d96ab Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Thu, 29 Oct 2015 16:44:09 +0900 Subject: [PATCH 0429/2855] staging: most: remove blank line after an open brace This patch removes blank line after an open brace found by checkpatch. CHECK: Blank lines aren't necessary after an open brace '{' Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hdm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index b6fe346f73b00..9ab092a3ccfee 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -371,7 +371,6 @@ static void service_done_flag(struct dim2_hdm *dev, int ch_idx) if (hdm_ch->data_type == MOST_CH_ASYNC && hdm_ch->direction == MOST_CH_RX && PACKET_IS_NET_INFO(data)) { - retrieve_netinfo(dev, mbo); spin_lock_irqsave(&dim_lock, flags); @@ -380,7 +379,6 @@ static void service_done_flag(struct dim2_hdm *dev, int ch_idx) } else { if (hdm_ch->data_type == MOST_CH_CONTROL || hdm_ch->data_type == MOST_CH_ASYNC) { - u32 const data_size = (u32)data[0] * 256 + data[1] + 2; -- GitLab From 3c70754250e42cf7aacf9c4d3ea7ea61beb4d3fa Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Thu, 29 Oct 2015 16:44:10 +0900 Subject: [PATCH 0430/2855] staging: most: add spaces preferred around that '<<' This patch adds space around '<<' found by checkpatch. CHECK: spaces preferred around that '<<' (ctx:VxV) FILE: drivers/staging/most/hdm-dim2/dim2_reg.h:69: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_reg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_reg.h b/drivers/staging/most/hdm-dim2/dim2_reg.h index 0795aae05f1cd..bcf6a79f6744d 100644 --- a/drivers/staging/most/hdm-dim2/dim2_reg.h +++ b/drivers/staging/most/hdm-dim2/dim2_reg.h @@ -66,7 +66,7 @@ struct dim2_regs { /* 0xF7 */ u32 ACMR1; }; -#define DIM2_MASK(n) (~((~(u32)0)<<(n))) +#define DIM2_MASK(n) (~((~(u32)0) << (n))) enum { MLBC0_MLBLK_BIT = 7, -- GitLab From 6417267f17c72f3d4224be3e76399475748e1e17 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Thu, 29 Oct 2015 16:44:11 +0900 Subject: [PATCH 0431/2855] staging: most: rename DIM_Startup to dim_startup This patch renames DIM_Startup to dim_startup to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:653: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 2 +- drivers/staging/most/hdm-dim2/dim2_hal.h | 2 +- drivers/staging/most/hdm-dim2/dim2_hdm.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index c915c44f025e5..583506dac323c 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -650,7 +650,7 @@ static bool channel_detach_buffers(struct dim_channel *ch, u16 buffers_number) /* -------------------------------------------------------------------------- */ /* API */ -u8 DIM_Startup(void *dim_base_address, u32 mlb_clock) +u8 dim_startup(void *dim_base_address, u32 mlb_clock) { g.dim_is_initialized = false; diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index 94ea6c7827f1c..6e1392a0e6044 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -65,7 +65,7 @@ struct dim_channel { u16 done_sw_buffers_number; /*< Done software buffers number. */ }; -u8 DIM_Startup(void *dim_base_address, u32 mlb_clock); +u8 dim_startup(void *dim_base_address, u32 mlb_clock); void DIM_Shutdown(void); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 9ab092a3ccfee..89e43e412c4e3 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -212,9 +212,9 @@ static int startup_dim(struct platform_device *pdev) return ret; } - hal_ret = DIM_Startup(dev->io_base, dev->clk_speed); + hal_ret = dim_startup(dev->io_base, dev->clk_speed); if (hal_ret != DIM_NO_ERROR) { - pr_err("DIM_Startup failed: %d\n", hal_ret); + pr_err("dim_startup failed: %d\n", hal_ret); if (pdata && pdata->destroy) pdata->destroy(pdata); return -ENODEV; -- GitLab From 50a45b170c044a27075535b36beea7b18ada98ce Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Thu, 29 Oct 2015 16:44:12 +0900 Subject: [PATCH 0432/2855] staging: most: rename DIM_Shutdown to dim_shutdown This patch renames DIM_Shutdown to dim_shutdown to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:676: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 2 +- drivers/staging/most/hdm-dim2/dim2_hal.h | 2 +- drivers/staging/most/hdm-dim2/dim2_hdm.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index 583506dac323c..e296adb64a1d0 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -673,7 +673,7 @@ u8 dim_startup(void *dim_base_address, u32 mlb_clock) return DIM_NO_ERROR; } -void DIM_Shutdown(void) +void dim_shutdown(void) { g.dim_is_initialized = false; dim2_cleanup(); diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index 6e1392a0e6044..8b18f74c08373 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -67,7 +67,7 @@ struct dim_channel { u8 dim_startup(void *dim_base_address, u32 mlb_clock); -void DIM_Shutdown(void); +void dim_shutdown(void); bool DIM_GetLockState(void); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 89e43e412c4e3..9c99f65d5ed5a 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -883,7 +883,7 @@ static int dim2_remove(struct platform_device *pdev) unsigned long flags; spin_lock_irqsave(&dim_lock, flags); - DIM_Shutdown(); + dim_shutdown(); spin_unlock_irqrestore(&dim_lock, flags); if (pdata && pdata->destroy) -- GitLab From 38c385449048ef4372ec7973c179bf1012cb284e Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Thu, 29 Oct 2015 16:44:13 +0900 Subject: [PATCH 0433/2855] staging: most: rename DIM_DetachBuffers to dim_detach_buffers This patch renames DIM_DetachBuffers to dim_detach_buffers to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:886: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 2 +- drivers/staging/most/hdm-dim2/dim2_hal.h | 2 +- drivers/staging/most/hdm-dim2/dim2_hdm.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index e296adb64a1d0..9bf952d57cc7b 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -883,7 +883,7 @@ bool DIM_EnqueueBuffer(struct dim_channel *ch, u32 buffer_addr, u16 buffer_size) return channel_start(ch, buffer_addr, buffer_size); } -bool DIM_DetachBuffers(struct dim_channel *ch, u16 buffers_number) +bool dim_detach_buffers(struct dim_channel *ch, u16 buffers_number) { if (!ch) return dim_on_error(DIM_ERR_DRIVER_NOT_INITIALIZED, diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index 8b18f74c08373..54dbfc4953eb9 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -101,7 +101,7 @@ struct dim_ch_state_t *DIM_GetChannelState(struct dim_channel *ch, bool DIM_EnqueueBuffer(struct dim_channel *ch, u32 buffer_addr, u16 buffer_size); -bool DIM_DetachBuffers(struct dim_channel *ch, u16 buffers_number); +bool dim_detach_buffers(struct dim_channel *ch, u16 buffers_number); u32 DIMCB_IoRead(u32 *ptr32); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 9c99f65d5ed5a..3f36aa6548aff 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -346,7 +346,7 @@ static void service_done_flag(struct dim2_hdm *dev, int ch_idx) return; } - if (!DIM_DetachBuffers(&hdm_ch->ch, done_buffers)) { + if (!dim_detach_buffers(&hdm_ch->ch, done_buffers)) { spin_unlock_irqrestore(&dim_lock, flags); return; } -- GitLab From b724207b4122ac8253c76834b24696a9dc68384a Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 2 Nov 2015 22:59:01 +0900 Subject: [PATCH 0434/2855] staging: most: rename DIM_GetLockState to dim_get_lock_state This patch renames DIM_GetLockState to dim_get_lock_state to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hdm.c:131: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 2 +- drivers/staging/most/hdm-dim2/dim2_hal.h | 2 +- drivers/staging/most/hdm-dim2/dim2_hdm.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index 9bf952d57cc7b..2610ad2030c1e 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -679,7 +679,7 @@ void dim_shutdown(void) dim2_cleanup(); } -bool DIM_GetLockState(void) +bool dim_get_lock_state(void) { return dim2_is_mlb_locked(); } diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index 54dbfc4953eb9..323ac2d052a23 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -69,7 +69,7 @@ u8 dim_startup(void *dim_base_address, u32 mlb_clock); void dim_shutdown(void); -bool DIM_GetLockState(void); +bool dim_get_lock_state(void); u16 DIM_NormCtrlAsyncBufferSize(u16 buf_size); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 3f36aa6548aff..fdaf9d2a6a729 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -128,7 +128,7 @@ bool dim2_sysfs_get_state_cb(void) unsigned long flags; spin_lock_irqsave(&dim_lock, flags); - state = DIM_GetLockState(); + state = dim_get_lock_state(); spin_unlock_irqrestore(&dim_lock, flags); return state; -- GitLab From de6687313df421296533de085dee76ec779d7332 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 2 Nov 2015 22:59:02 +0900 Subject: [PATCH 0435/2855] staging: most: rename DIMCB_OnError to dimcb_on_error This patch renames DIMCB_OnError to dimcb_on_error to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:77: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 2 +- drivers/staging/most/hdm-dim2/dim2_hal.h | 2 +- drivers/staging/most/hdm-dim2/dim2_hdm.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index 2610ad2030c1e..d77566a1a59f7 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -74,7 +74,7 @@ static inline u32 bit_mask(u8 position) static inline bool dim_on_error(u8 error_id, const char *error_message) { - DIMCB_OnError(error_id, error_message); + dimcb_on_error(error_id, error_message); return false; } diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index 323ac2d052a23..9e65e815eee19 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -107,7 +107,7 @@ u32 DIMCB_IoRead(u32 *ptr32); void DIMCB_IoWrite(u32 *ptr32, u32 value); -void DIMCB_OnError(u8 error_id, const char *error_message); +void dimcb_on_error(u8 error_id, const char *error_message); #ifdef __cplusplus } diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index fdaf9d2a6a729..ffe4bad5d7dd5 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -154,14 +154,14 @@ void DIMCB_IoWrite(u32 *ptr32, u32 value) } /** - * DIMCB_OnError - callback from HAL to report miscommunication between + * dimcb_on_error - callback from HAL to report miscommunication between * HDM and HAL * @error_id: Error ID * @error_message: Error message. Some text in a free format */ -void DIMCB_OnError(u8 error_id, const char *error_message) +void dimcb_on_error(u8 error_id, const char *error_message) { - pr_err("DIMCB_OnError: error_id - %d, error_message - %s\n", error_id, + pr_err("dimcb_on_error: error_id - %d, error_message - %s\n", error_id, error_message); } -- GitLab From 1efc4564624070561c1a562f2001ca357895cc99 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 2 Nov 2015 22:59:03 +0900 Subject: [PATCH 0436/2855] staging: most: rename DIMCB_IoWrite to dimcb_io_write This patch renames DIMCB_IoWrite to dimcb_io_write to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:154: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 76 ++++++++++++------------ drivers/staging/most/hdm-dim2/dim2_hal.h | 2 +- drivers/staging/most/hdm-dim2/dim2_hdm.c | 4 +- 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index d77566a1a59f7..2df126c64b2c9 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -151,13 +151,13 @@ static void free_dbr(int offs, int size) static u32 dim2_read_ctr(u32 ctr_addr, u16 mdat_idx) { - DIMCB_IoWrite(&g.dim2->MADR, ctr_addr); + dimcb_io_write(&g.dim2->MADR, ctr_addr); /* wait till transfer is completed */ while ((DIMCB_IoRead(&g.dim2->MCTL) & 1) != 1) continue; - DIMCB_IoWrite(&g.dim2->MCTL, 0); /* clear transfer complete */ + dimcb_io_write(&g.dim2->MCTL, 0); /* clear transfer complete */ return DIMCB_IoRead((&g.dim2->MDAT0) + mdat_idx); } @@ -166,29 +166,29 @@ static void dim2_write_ctr_mask(u32 ctr_addr, const u32 *mask, const u32 *value) { enum { MADR_WNR_BIT = 31 }; - DIMCB_IoWrite(&g.dim2->MCTL, 0); /* clear transfer complete */ + dimcb_io_write(&g.dim2->MCTL, 0); /* clear transfer complete */ if (mask[0] != 0) - DIMCB_IoWrite(&g.dim2->MDAT0, value[0]); + dimcb_io_write(&g.dim2->MDAT0, value[0]); if (mask[1] != 0) - DIMCB_IoWrite(&g.dim2->MDAT1, value[1]); + dimcb_io_write(&g.dim2->MDAT1, value[1]); if (mask[2] != 0) - DIMCB_IoWrite(&g.dim2->MDAT2, value[2]); + dimcb_io_write(&g.dim2->MDAT2, value[2]); if (mask[3] != 0) - DIMCB_IoWrite(&g.dim2->MDAT3, value[3]); + dimcb_io_write(&g.dim2->MDAT3, value[3]); - DIMCB_IoWrite(&g.dim2->MDWE0, mask[0]); - DIMCB_IoWrite(&g.dim2->MDWE1, mask[1]); - DIMCB_IoWrite(&g.dim2->MDWE2, mask[2]); - DIMCB_IoWrite(&g.dim2->MDWE3, mask[3]); + dimcb_io_write(&g.dim2->MDWE0, mask[0]); + dimcb_io_write(&g.dim2->MDWE1, mask[1]); + dimcb_io_write(&g.dim2->MDWE2, mask[2]); + dimcb_io_write(&g.dim2->MDWE3, mask[3]); - DIMCB_IoWrite(&g.dim2->MADR, bit_mask(MADR_WNR_BIT) | ctr_addr); + dimcb_io_write(&g.dim2->MADR, bit_mask(MADR_WNR_BIT) | ctr_addr); /* wait till transfer is completed */ while ((DIMCB_IoRead(&g.dim2->MCTL) & 1) != 1) continue; - DIMCB_IoWrite(&g.dim2->MCTL, 0); /* clear transfer complete */ + dimcb_io_write(&g.dim2->MCTL, 0); /* clear transfer complete */ } static inline void dim2_write_ctr(u32 ctr_addr, const u32 *value) @@ -341,15 +341,15 @@ static void dim2_configure_channel( dim2_configure_cat(AHB_CAT, ch_addr, type, is_tx ? 0 : 1, sync_mfe); /* unmask interrupt for used channel, enable mlb_sys_int[0] interrupt */ - DIMCB_IoWrite(&g.dim2->ACMR0, - DIMCB_IoRead(&g.dim2->ACMR0) | bit_mask(ch_addr)); + dimcb_io_write(&g.dim2->ACMR0, + DIMCB_IoRead(&g.dim2->ACMR0) | bit_mask(ch_addr)); } static void dim2_clear_channel(u8 ch_addr) { /* mask interrupt for used channel, disable mlb_sys_int[0] interrupt */ - DIMCB_IoWrite(&g.dim2->ACMR0, - DIMCB_IoRead(&g.dim2->ACMR0) & ~bit_mask(ch_addr)); + dimcb_io_write(&g.dim2->ACMR0, + DIMCB_IoRead(&g.dim2->ACMR0) & ~bit_mask(ch_addr)); dim2_clear_cat(AHB_CAT, ch_addr); dim2_clear_adt(ch_addr); @@ -455,20 +455,20 @@ static inline u16 norm_sync_buffer_size(u16 buf_size, u16 bytes_per_frame) static void dim2_cleanup(void) { /* disable MediaLB */ - DIMCB_IoWrite(&g.dim2->MLBC0, false << MLBC0_MLBEN_BIT); + dimcb_io_write(&g.dim2->MLBC0, false << MLBC0_MLBEN_BIT); dim2_clear_ctram(); /* disable mlb_int interrupt */ - DIMCB_IoWrite(&g.dim2->MIEN, 0); + dimcb_io_write(&g.dim2->MIEN, 0); /* clear status for all dma channels */ - DIMCB_IoWrite(&g.dim2->ACSR0, 0xFFFFFFFF); - DIMCB_IoWrite(&g.dim2->ACSR1, 0xFFFFFFFF); + dimcb_io_write(&g.dim2->ACSR0, 0xFFFFFFFF); + dimcb_io_write(&g.dim2->ACSR1, 0xFFFFFFFF); /* mask interrupts for all channels */ - DIMCB_IoWrite(&g.dim2->ACMR0, 0); - DIMCB_IoWrite(&g.dim2->ACMR1, 0); + dimcb_io_write(&g.dim2->ACMR0, 0); + dimcb_io_write(&g.dim2->ACMR1, 0); } static void dim2_initialize(bool enable_6pin, u8 mlb_clock) @@ -476,23 +476,23 @@ static void dim2_initialize(bool enable_6pin, u8 mlb_clock) dim2_cleanup(); /* configure and enable MediaLB */ - DIMCB_IoWrite(&g.dim2->MLBC0, - enable_6pin << MLBC0_MLBPEN_BIT | - mlb_clock << MLBC0_MLBCLK_SHIFT | - MLBC0_FCNT_VAL(FRAMES_PER_SUBBUFF) << MLBC0_FCNT_SHIFT | - true << MLBC0_MLBEN_BIT); + dimcb_io_write(&g.dim2->MLBC0, + enable_6pin << MLBC0_MLBPEN_BIT | + mlb_clock << MLBC0_MLBCLK_SHIFT | + MLBC0_FCNT_VAL(FRAMES_PER_SUBBUFF) << MLBC0_FCNT_SHIFT | + true << MLBC0_MLBEN_BIT); /* activate all HBI channels */ - DIMCB_IoWrite(&g.dim2->HCMR0, 0xFFFFFFFF); - DIMCB_IoWrite(&g.dim2->HCMR1, 0xFFFFFFFF); + dimcb_io_write(&g.dim2->HCMR0, 0xFFFFFFFF); + dimcb_io_write(&g.dim2->HCMR1, 0xFFFFFFFF); /* enable HBI */ - DIMCB_IoWrite(&g.dim2->HCTL, bit_mask(HCTL_EN_BIT)); + dimcb_io_write(&g.dim2->HCTL, bit_mask(HCTL_EN_BIT)); /* configure DMA */ - DIMCB_IoWrite(&g.dim2->ACTL, - ACTL_DMA_MODE_VAL_DMA_MODE_1 << ACTL_DMA_MODE_BIT | - true << ACTL_SCE_BIT); + dimcb_io_write(&g.dim2->ACTL, + ACTL_DMA_MODE_VAL_DMA_MODE_1 << ACTL_DMA_MODE_BIT | + true << ACTL_SCE_BIT); } static bool dim2_is_mlb_locked(void) @@ -503,7 +503,7 @@ static bool dim2_is_mlb_locked(void) u32 const c1 = DIMCB_IoRead(&g.dim2->MLBC1); u32 const nda_mask = (u32)MLBC1_NDA_MASK << MLBC1_NDA_SHIFT; - DIMCB_IoWrite(&g.dim2->MLBC1, c1 & nda_mask); + dimcb_io_write(&g.dim2->MLBC1, c1 & nda_mask); return (DIMCB_IoRead(&g.dim2->MLBC1) & mask1) == 0 && (DIMCB_IoRead(&g.dim2->MLBC0) & mask0) != 0; } @@ -531,7 +531,7 @@ static inline bool service_channel(u8 ch_addr, u8 idx) } /* clear channel status bit */ - DIMCB_IoWrite(&g.dim2->ACSR0, bit_mask(ch_addr)); + dimcb_io_write(&g.dim2->ACSR0, bit_mask(ch_addr)); return true; } @@ -850,8 +850,8 @@ void DIM_ServiceIrq(struct dim_channel *const *channels) } while (state_changed); /* clear pending Interrupts */ - DIMCB_IoWrite(&g.dim2->MS0, 0); - DIMCB_IoWrite(&g.dim2->MS1, 0); + dimcb_io_write(&g.dim2->MS0, 0); + dimcb_io_write(&g.dim2->MS1, 0); } u8 DIM_ServiceChannel(struct dim_channel *ch) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index 9e65e815eee19..7dc290896c12b 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -105,7 +105,7 @@ bool dim_detach_buffers(struct dim_channel *ch, u16 buffers_number); u32 DIMCB_IoRead(u32 *ptr32); -void DIMCB_IoWrite(u32 *ptr32, u32 value); +void dimcb_io_write(u32 *ptr32, u32 value); void dimcb_on_error(u8 error_id, const char *error_message); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index ffe4bad5d7dd5..d8a0790979bf0 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -144,11 +144,11 @@ u32 DIMCB_IoRead(u32 *ptr32) } /** - * DIMCB_IoWrite - callback from HAL to write value to an I/O register + * dimcb_io_write - callback from HAL to write value to an I/O register * @ptr32: register address * @value: value to write */ -void DIMCB_IoWrite(u32 *ptr32, u32 value) +void dimcb_io_write(u32 *ptr32, u32 value) { __raw_writel(value, ptr32); } -- GitLab From 58889788fc806e8b63e7f159db659937decf61e8 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 2 Nov 2015 22:59:04 +0900 Subject: [PATCH 0437/2855] staging: most: rename DIMCB_IoRead to dimcb_io_read This patch renames DIMCB_IoRead to dimcb_io_read to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:157: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 16 ++++++++-------- drivers/staging/most/hdm-dim2/dim2_hal.h | 2 +- drivers/staging/most/hdm-dim2/dim2_hdm.c | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index 2df126c64b2c9..a470900ccf4cf 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -154,12 +154,12 @@ static u32 dim2_read_ctr(u32 ctr_addr, u16 mdat_idx) dimcb_io_write(&g.dim2->MADR, ctr_addr); /* wait till transfer is completed */ - while ((DIMCB_IoRead(&g.dim2->MCTL) & 1) != 1) + while ((dimcb_io_read(&g.dim2->MCTL) & 1) != 1) continue; dimcb_io_write(&g.dim2->MCTL, 0); /* clear transfer complete */ - return DIMCB_IoRead((&g.dim2->MDAT0) + mdat_idx); + return dimcb_io_read((&g.dim2->MDAT0) + mdat_idx); } static void dim2_write_ctr_mask(u32 ctr_addr, const u32 *mask, const u32 *value) @@ -185,7 +185,7 @@ static void dim2_write_ctr_mask(u32 ctr_addr, const u32 *mask, const u32 *value) dimcb_io_write(&g.dim2->MADR, bit_mask(MADR_WNR_BIT) | ctr_addr); /* wait till transfer is completed */ - while ((DIMCB_IoRead(&g.dim2->MCTL) & 1) != 1) + while ((dimcb_io_read(&g.dim2->MCTL) & 1) != 1) continue; dimcb_io_write(&g.dim2->MCTL, 0); /* clear transfer complete */ @@ -342,14 +342,14 @@ static void dim2_configure_channel( /* unmask interrupt for used channel, enable mlb_sys_int[0] interrupt */ dimcb_io_write(&g.dim2->ACMR0, - DIMCB_IoRead(&g.dim2->ACMR0) | bit_mask(ch_addr)); + dimcb_io_read(&g.dim2->ACMR0) | bit_mask(ch_addr)); } static void dim2_clear_channel(u8 ch_addr) { /* mask interrupt for used channel, disable mlb_sys_int[0] interrupt */ dimcb_io_write(&g.dim2->ACMR0, - DIMCB_IoRead(&g.dim2->ACMR0) & ~bit_mask(ch_addr)); + dimcb_io_read(&g.dim2->ACMR0) & ~bit_mask(ch_addr)); dim2_clear_cat(AHB_CAT, ch_addr); dim2_clear_adt(ch_addr); @@ -500,12 +500,12 @@ static bool dim2_is_mlb_locked(void) u32 const mask0 = bit_mask(MLBC0_MLBLK_BIT); u32 const mask1 = bit_mask(MLBC1_CLKMERR_BIT) | bit_mask(MLBC1_LOCKERR_BIT); - u32 const c1 = DIMCB_IoRead(&g.dim2->MLBC1); + u32 const c1 = dimcb_io_read(&g.dim2->MLBC1); u32 const nda_mask = (u32)MLBC1_NDA_MASK << MLBC1_NDA_SHIFT; dimcb_io_write(&g.dim2->MLBC1, c1 & nda_mask); - return (DIMCB_IoRead(&g.dim2->MLBC1) & mask1) == 0 && - (DIMCB_IoRead(&g.dim2->MLBC0) & mask0) != 0; + return (dimcb_io_read(&g.dim2->MLBC1) & mask1) == 0 && + (dimcb_io_read(&g.dim2->MLBC0) & mask0) != 0; } /* -------------------------------------------------------------------------- */ diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index 7dc290896c12b..5a866da2a1286 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -103,7 +103,7 @@ bool DIM_EnqueueBuffer(struct dim_channel *ch, u32 buffer_addr, bool dim_detach_buffers(struct dim_channel *ch, u16 buffers_number); -u32 DIMCB_IoRead(u32 *ptr32); +u32 dimcb_io_read(u32 *ptr32); void dimcb_io_write(u32 *ptr32, u32 value); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index d8a0790979bf0..1b792f1861c22 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -135,10 +135,10 @@ bool dim2_sysfs_get_state_cb(void) } /** - * DIMCB_IoRead - callback from HAL to read an I/O register + * dimcb_io_read - callback from HAL to read an I/O register * @ptr32: register address */ -u32 DIMCB_IoRead(u32 *ptr32) +u32 dimcb_io_read(u32 *ptr32) { return __raw_readl(ptr32); } -- GitLab From c64c6073e8fe1c80cc991c48450136c619c051ee Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 2 Nov 2015 22:59:05 +0900 Subject: [PATCH 0438/2855] staging: most: rename DIM_NormCtrlAsyncBufferSize to dim_norm_ctrl_async_buffer_size This patch renames DIM_NormCtrlAsyncBufferSize to dim_norm_ctrl_async_buffer_size to avoid camelcase found by checkpatch CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:709: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 2 +- drivers/staging/most/hdm-dim2/dim2_hal.h | 2 +- drivers/staging/most/hdm-dim2/dim2_hdm.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index a470900ccf4cf..8cca18e9f38f5 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -706,7 +706,7 @@ static u8 init_ctrl_async(struct dim_channel *ch, u8 type, u8 is_tx, return DIM_NO_ERROR; } -u16 DIM_NormCtrlAsyncBufferSize(u16 buf_size) +u16 dim_norm_ctrl_async_buffer_size(u16 buf_size) { return norm_ctrl_async_buffer_size(buf_size); } diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index 5a866da2a1286..f5640485c5baa 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -71,7 +71,7 @@ void dim_shutdown(void); bool dim_get_lock_state(void); -u16 DIM_NormCtrlAsyncBufferSize(u16 buf_size); +u16 dim_norm_ctrl_async_buffer_size(u16 buf_size); u16 DIM_NormIsocBufferSize(u16 buf_size, u16 packet_length); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 1b792f1861c22..6e583d46181f2 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -534,7 +534,7 @@ static int configure_channel(struct most_interface *most_iface, int ch_idx, switch (ccfg->data_type) { case MOST_CH_CONTROL: - new_size = DIM_NormCtrlAsyncBufferSize(buf_size); + new_size = dim_norm_ctrl_async_buffer_size(buf_size); if (new_size == 0) { pr_err("%s: too small buffer size\n", hdm_ch->name); return -EINVAL; @@ -548,7 +548,7 @@ static int configure_channel(struct most_interface *most_iface, int ch_idx, buf_size); break; case MOST_CH_ASYNC: - new_size = DIM_NormCtrlAsyncBufferSize(buf_size); + new_size = dim_norm_ctrl_async_buffer_size(buf_size); if (new_size == 0) { pr_err("%s: too small buffer size\n", hdm_ch->name); return -EINVAL; -- GitLab From e302ca47b59f024e90c26367fca6448af5198dc7 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 2 Nov 2015 22:59:06 +0900 Subject: [PATCH 0439/2855] staging: most: rename DIM_NormIsocBufferSize to dim_norm_isoc_buffer_size This patch renames DIM_NormIsocBufferSize to dim_norm_isoc_buffer_size to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:720: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 2 +- drivers/staging/most/hdm-dim2/dim2_hal.h | 2 +- drivers/staging/most/hdm-dim2/dim2_hdm.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index 8cca18e9f38f5..01fa2e535737e 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -717,7 +717,7 @@ u16 dim_norm_ctrl_async_buffer_size(u16 buf_size) * * Returns non-zero correct buffer size or zero by error. */ -u16 DIM_NormIsocBufferSize(u16 buf_size, u16 packet_length) +u16 dim_norm_isoc_buffer_size(u16 buf_size, u16 packet_length) { if (!check_packet_length(packet_length)) return 0; diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index f5640485c5baa..c2e3fcc377cce 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -73,7 +73,7 @@ bool dim_get_lock_state(void); u16 dim_norm_ctrl_async_buffer_size(u16 buf_size); -u16 DIM_NormIsocBufferSize(u16 buf_size, u16 packet_length); +u16 dim_norm_isoc_buffer_size(u16 buf_size, u16 packet_length); u16 DIM_NormSyncBufferSize(u16 buf_size, u16 bytes_per_frame); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 6e583d46181f2..6e457c138151d 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -561,7 +561,7 @@ static int configure_channel(struct most_interface *most_iface, int ch_idx, hal_ret = DIM_InitAsync(&hdm_ch->ch, is_tx, ch_addr, buf_size); break; case MOST_CH_ISOC_AVP: - new_size = DIM_NormIsocBufferSize(buf_size, sub_size); + new_size = dim_norm_isoc_buffer_size(buf_size, sub_size); if (new_size == 0) { pr_err("%s: invalid sub-buffer size or too small buffer size\n", hdm_ch->name); -- GitLab From aff1924508e8808a3e9d6b41ce30ad4cbb4be582 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 2 Nov 2015 22:59:07 +0900 Subject: [PATCH 0440/2855] staging: most: rename DIM_NormSyncBufferSize to dim_norm_sync_buffer_size This patch renames DIM_NormSyncBufferSize to dim_norm_sync_buffer_size to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:734: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 2 +- drivers/staging/most/hdm-dim2/dim2_hal.h | 2 +- drivers/staging/most/hdm-dim2/dim2_hdm.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index 01fa2e535737e..e6f35cb0fc014 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -731,7 +731,7 @@ u16 dim_norm_isoc_buffer_size(u16 buf_size, u16 packet_length) * * Returns non-zero correct buffer size or zero by error. */ -u16 DIM_NormSyncBufferSize(u16 buf_size, u16 bytes_per_frame) +u16 dim_norm_sync_buffer_size(u16 buf_size, u16 bytes_per_frame) { if (!check_bytes_per_frame(bytes_per_frame)) return 0; diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index c2e3fcc377cce..cbed686cbafe9 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -75,7 +75,7 @@ u16 dim_norm_ctrl_async_buffer_size(u16 buf_size); u16 dim_norm_isoc_buffer_size(u16 buf_size, u16 packet_length); -u16 DIM_NormSyncBufferSize(u16 buf_size, u16 bytes_per_frame); +u16 dim_norm_sync_buffer_size(u16 buf_size, u16 bytes_per_frame); u8 DIM_InitControl(struct dim_channel *ch, u8 is_tx, u16 ch_address, u16 max_buffer_size); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 6e457c138151d..1e9037f862f56 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -575,7 +575,7 @@ static int configure_channel(struct most_interface *most_iface, int ch_idx, hal_ret = DIM_InitIsoc(&hdm_ch->ch, is_tx, ch_addr, sub_size); break; case MOST_CH_SYNC: - new_size = DIM_NormSyncBufferSize(buf_size, sub_size); + new_size = dim_norm_sync_buffer_size(buf_size, sub_size); if (new_size == 0) { pr_err("%s: invalid sub-buffer size or too small buffer size\n", hdm_ch->name); -- GitLab From a3f3e9211947101b00d3c6d6c0864905a1bde0a9 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 2 Nov 2015 22:59:08 +0900 Subject: [PATCH 0441/2855] staging: most: rename DIM_InitControl to dim_init_control This patch renames DIM_InitControl to dim_init_control to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:742: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 4 ++-- drivers/staging/most/hdm-dim2/dim2_hal.h | 4 ++-- drivers/staging/most/hdm-dim2/dim2_hdm.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index e6f35cb0fc014..6edabbdd0eedc 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -739,8 +739,8 @@ u16 dim_norm_sync_buffer_size(u16 buf_size, u16 bytes_per_frame) return norm_sync_buffer_size(buf_size, bytes_per_frame); } -u8 DIM_InitControl(struct dim_channel *ch, u8 is_tx, u16 ch_address, - u16 max_buffer_size) +u8 dim_init_control(struct dim_channel *ch, u8 is_tx, u16 ch_address, + u16 max_buffer_size) { return init_ctrl_async(ch, CAT_CT_VAL_CONTROL, is_tx, ch_address, max_buffer_size); diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index cbed686cbafe9..7ab57c96c43dc 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -77,8 +77,8 @@ u16 dim_norm_isoc_buffer_size(u16 buf_size, u16 packet_length); u16 dim_norm_sync_buffer_size(u16 buf_size, u16 bytes_per_frame); -u8 DIM_InitControl(struct dim_channel *ch, u8 is_tx, u16 ch_address, - u16 max_buffer_size); +u8 dim_init_control(struct dim_channel *ch, u8 is_tx, u16 ch_address, + u16 max_buffer_size); u8 DIM_InitAsync(struct dim_channel *ch, u8 is_tx, u16 ch_address, u16 max_buffer_size); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 1e9037f862f56..02cd10b881a76 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -544,8 +544,8 @@ static int configure_channel(struct most_interface *most_iface, int ch_idx, pr_warn("%s: fixed buffer size (%d -> %d)\n", hdm_ch->name, buf_size, new_size); spin_lock_irqsave(&dim_lock, flags); - hal_ret = DIM_InitControl(&hdm_ch->ch, is_tx, ch_addr, - buf_size); + hal_ret = dim_init_control(&hdm_ch->ch, is_tx, ch_addr, + buf_size); break; case MOST_CH_ASYNC: new_size = dim_norm_ctrl_async_buffer_size(buf_size); -- GitLab From 26303150c3fe9fce81cc1baa60a32aed6ff203ee Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 2 Nov 2015 22:59:09 +0900 Subject: [PATCH 0442/2855] staging: most: rename DIM_InitAsync to dim_init_async This patch renames DIM_InitAsync to dim_init_async to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:749: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 4 ++-- drivers/staging/most/hdm-dim2/dim2_hal.h | 4 ++-- drivers/staging/most/hdm-dim2/dim2_hdm.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index 6edabbdd0eedc..a59bb50451a2b 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -746,8 +746,8 @@ u8 dim_init_control(struct dim_channel *ch, u8 is_tx, u16 ch_address, max_buffer_size); } -u8 DIM_InitAsync(struct dim_channel *ch, u8 is_tx, u16 ch_address, - u16 max_buffer_size) +u8 dim_init_async(struct dim_channel *ch, u8 is_tx, u16 ch_address, + u16 max_buffer_size) { return init_ctrl_async(ch, CAT_CT_VAL_ASYNC, is_tx, ch_address, max_buffer_size); diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index 7ab57c96c43dc..8c60f7eab6926 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -80,8 +80,8 @@ u16 dim_norm_sync_buffer_size(u16 buf_size, u16 bytes_per_frame); u8 dim_init_control(struct dim_channel *ch, u8 is_tx, u16 ch_address, u16 max_buffer_size); -u8 DIM_InitAsync(struct dim_channel *ch, u8 is_tx, u16 ch_address, - u16 max_buffer_size); +u8 dim_init_async(struct dim_channel *ch, u8 is_tx, u16 ch_address, + u16 max_buffer_size); u8 DIM_InitIsoc(struct dim_channel *ch, u8 is_tx, u16 ch_address, u16 packet_length); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 02cd10b881a76..4bc6c8e8b89a8 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -558,7 +558,7 @@ static int configure_channel(struct most_interface *most_iface, int ch_idx, pr_warn("%s: fixed buffer size (%d -> %d)\n", hdm_ch->name, buf_size, new_size); spin_lock_irqsave(&dim_lock, flags); - hal_ret = DIM_InitAsync(&hdm_ch->ch, is_tx, ch_addr, buf_size); + hal_ret = dim_init_async(&hdm_ch->ch, is_tx, ch_addr, buf_size); break; case MOST_CH_ISOC_AVP: new_size = dim_norm_isoc_buffer_size(buf_size, sub_size); -- GitLab From f1383176c928016e6b7c85bb8c646fe829600db0 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 2 Nov 2015 22:59:10 +0900 Subject: [PATCH 0443/2855] staging: most: rename DIM_InitIsoc to dim_init_isoc This patch renames DIM_InitIsoc to dim_init_isoc to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:756: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 4 ++-- drivers/staging/most/hdm-dim2/dim2_hal.h | 4 ++-- drivers/staging/most/hdm-dim2/dim2_hdm.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index a59bb50451a2b..3c9ea4cd3c11e 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -753,8 +753,8 @@ u8 dim_init_async(struct dim_channel *ch, u8 is_tx, u16 ch_address, max_buffer_size); } -u8 DIM_InitIsoc(struct dim_channel *ch, u8 is_tx, u16 ch_address, - u16 packet_length) +u8 dim_init_isoc(struct dim_channel *ch, u8 is_tx, u16 ch_address, + u16 packet_length) { if (!g.dim_is_initialized || !ch) return DIM_ERR_DRIVER_NOT_INITIALIZED; diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index 8c60f7eab6926..43e79c97851fa 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -83,8 +83,8 @@ u8 dim_init_control(struct dim_channel *ch, u8 is_tx, u16 ch_address, u8 dim_init_async(struct dim_channel *ch, u8 is_tx, u16 ch_address, u16 max_buffer_size); -u8 DIM_InitIsoc(struct dim_channel *ch, u8 is_tx, u16 ch_address, - u16 packet_length); +u8 dim_init_isoc(struct dim_channel *ch, u8 is_tx, u16 ch_address, + u16 packet_length); u8 DIM_InitSync(struct dim_channel *ch, u8 is_tx, u16 ch_address, u16 bytes_per_frame); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 4bc6c8e8b89a8..43a9c2b281481 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -572,7 +572,7 @@ static int configure_channel(struct most_interface *most_iface, int ch_idx, pr_warn("%s: fixed buffer size (%d -> %d)\n", hdm_ch->name, buf_size, new_size); spin_lock_irqsave(&dim_lock, flags); - hal_ret = DIM_InitIsoc(&hdm_ch->ch, is_tx, ch_addr, sub_size); + hal_ret = dim_init_isoc(&hdm_ch->ch, is_tx, ch_addr, sub_size); break; case MOST_CH_SYNC: new_size = dim_norm_sync_buffer_size(buf_size, sub_size); -- GitLab From 10e5efb7b51f30b696a2cde366b783d8ecd0f465 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 2 Nov 2015 22:59:11 +0900 Subject: [PATCH 0444/2855] staging: most: rename DIM_InitSync to dim_init_sync This patch renames DIM_InitSync to dim_init_sync to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:781: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 4 ++-- drivers/staging/most/hdm-dim2/dim2_hal.h | 4 ++-- drivers/staging/most/hdm-dim2/dim2_hdm.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index 3c9ea4cd3c11e..a57816ae861e9 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -778,8 +778,8 @@ u8 dim_init_isoc(struct dim_channel *ch, u8 is_tx, u16 ch_address, return DIM_NO_ERROR; } -u8 DIM_InitSync(struct dim_channel *ch, u8 is_tx, u16 ch_address, - u16 bytes_per_frame) +u8 dim_init_sync(struct dim_channel *ch, u8 is_tx, u16 ch_address, + u16 bytes_per_frame) { if (!g.dim_is_initialized || !ch) return DIM_ERR_DRIVER_NOT_INITIALIZED; diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index 43e79c97851fa..8692bb7dd68f7 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -86,8 +86,8 @@ u8 dim_init_async(struct dim_channel *ch, u8 is_tx, u16 ch_address, u8 dim_init_isoc(struct dim_channel *ch, u8 is_tx, u16 ch_address, u16 packet_length); -u8 DIM_InitSync(struct dim_channel *ch, u8 is_tx, u16 ch_address, - u16 bytes_per_frame); +u8 dim_init_sync(struct dim_channel *ch, u8 is_tx, u16 ch_address, + u16 bytes_per_frame); u8 DIM_DestroyChannel(struct dim_channel *ch); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 43a9c2b281481..63219852d1126 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -586,7 +586,7 @@ static int configure_channel(struct most_interface *most_iface, int ch_idx, pr_warn("%s: fixed buffer size (%d -> %d)\n", hdm_ch->name, buf_size, new_size); spin_lock_irqsave(&dim_lock, flags); - hal_ret = DIM_InitSync(&hdm_ch->ch, is_tx, ch_addr, sub_size); + hal_ret = dim_init_sync(&hdm_ch->ch, is_tx, ch_addr, sub_size); break; default: pr_err("%s: configure failed, bad channel type: %d\n", -- GitLab From a5e4d891a3968ded645a1c556f021097b2faa514 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 2 Nov 2015 22:59:12 +0900 Subject: [PATCH 0445/2855] staging: most: rename DIM_DestroyChannel to dim_destroy_channel This patch renames DIM_DestroyChannel to dim_destroy_channel to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:806: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 2 +- drivers/staging/most/hdm-dim2/dim2_hal.h | 2 +- drivers/staging/most/hdm-dim2/dim2_hdm.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index a57816ae861e9..cb92461fa36cf 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -803,7 +803,7 @@ u8 dim_init_sync(struct dim_channel *ch, u8 is_tx, u16 ch_address, return DIM_NO_ERROR; } -u8 DIM_DestroyChannel(struct dim_channel *ch) +u8 dim_destroy_channel(struct dim_channel *ch) { if (!g.dim_is_initialized || !ch) return DIM_ERR_DRIVER_NOT_INITIALIZED; diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index 8692bb7dd68f7..bdde159671a85 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -89,7 +89,7 @@ u8 dim_init_isoc(struct dim_channel *ch, u8 is_tx, u16 ch_address, u8 dim_init_sync(struct dim_channel *ch, u8 is_tx, u16 ch_address, u16 bytes_per_frame); -u8 DIM_DestroyChannel(struct dim_channel *ch); +u8 dim_destroy_channel(struct dim_channel *ch); void DIM_ServiceIrq(struct dim_channel *const *channels); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 63219852d1126..6cd6c788e6f7e 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -706,7 +706,7 @@ static int poison_channel(struct most_interface *most_iface, int ch_idx) return -EPERM; spin_lock_irqsave(&dim_lock, flags); - hal_ret = DIM_DestroyChannel(&hdm_ch->ch); + hal_ret = dim_destroy_channel(&hdm_ch->ch); hdm_ch->is_initialized = false; if (ch_idx == dev->atx_idx) dev->atx_idx = -1; -- GitLab From e5baa9e99cc3f5bbca84d8894aed4b39692c41e6 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 2 Nov 2015 22:59:13 +0900 Subject: [PATCH 0446/2855] staging: most: rename DIM_ServiceIrq to dim_service_irq This patch renames DIM_ServiceIrq to dim_service_irq to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:819: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 2 +- drivers/staging/most/hdm-dim2/dim2_hal.h | 2 +- drivers/staging/most/hdm-dim2/dim2_hdm.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index cb92461fa36cf..4a7d7fb11bfc6 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -816,7 +816,7 @@ u8 dim_destroy_channel(struct dim_channel *ch) return DIM_NO_ERROR; } -void DIM_ServiceIrq(struct dim_channel *const *channels) +void dim_service_irq(struct dim_channel *const *channels) { bool state_changed; diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index bdde159671a85..6eb8da16160f4 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -91,7 +91,7 @@ u8 dim_init_sync(struct dim_channel *ch, u8 is_tx, u16 ch_address, u8 dim_destroy_channel(struct dim_channel *ch); -void DIM_ServiceIrq(struct dim_channel *const *channels); +void dim_service_irq(struct dim_channel *const *channels); u8 DIM_ServiceChannel(struct dim_channel *ch); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 6cd6c788e6f7e..7767cdcda6fd9 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -452,7 +452,7 @@ static irqreturn_t dim2_ahb_isr(int irq, void *_dev) unsigned long flags; spin_lock_irqsave(&dim_lock, flags); - DIM_ServiceIrq(get_active_channels(dev, buffer)); + dim_service_irq(get_active_channels(dev, buffer)); spin_unlock_irqrestore(&dim_lock, flags); #if !defined(ENABLE_HDM_TEST) -- GitLab From 0d08d54f8da9f54bd861f694a81208a8a0625b95 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 2 Nov 2015 22:59:14 +0900 Subject: [PATCH 0447/2855] staging: most: rename DIM_ServiceChannel to dim_service_channel This patch renames DIM_ServiceChannel to dim_service_channel to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:857: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 2 +- drivers/staging/most/hdm-dim2/dim2_hal.h | 2 +- drivers/staging/most/hdm-dim2/dim2_hdm.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index 4a7d7fb11bfc6..a96457c60f6d0 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -854,7 +854,7 @@ void dim_service_irq(struct dim_channel *const *channels) dimcb_io_write(&g.dim2->MS1, 0); } -u8 DIM_ServiceChannel(struct dim_channel *ch) +u8 dim_service_channel(struct dim_channel *ch) { if (!g.dim_is_initialized || !ch) return DIM_ERR_DRIVER_NOT_INITIALIZED; diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index 6eb8da16160f4..f333f0adbcd23 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -93,7 +93,7 @@ u8 dim_destroy_channel(struct dim_channel *ch); void dim_service_irq(struct dim_channel *const *channels); -u8 DIM_ServiceChannel(struct dim_channel *ch); +u8 dim_service_channel(struct dim_channel *ch); struct dim_ch_state_t *DIM_GetChannelState(struct dim_channel *ch, struct dim_ch_state_t *dim_ch_state_ptr); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 7767cdcda6fd9..4b5df0b06008b 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -428,7 +428,7 @@ static void dim2_tasklet_fn(unsigned long data) continue; spin_lock_irqsave(&dim_lock, flags); - DIM_ServiceChannel(&dev->hch[ch_idx].ch); + dim_service_channel(&dev->hch[ch_idx].ch); spin_unlock_irqrestore(&dim_lock, flags); service_done_flag(dev, ch_idx); -- GitLab From e38092531282db8bdf8c8f3e9607e551b2f1a906 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 2 Nov 2015 22:59:15 +0900 Subject: [PATCH 0448/2855] staging: most: fix argument name of DIM_GetChannelState The second argument name of DIM_GetChannelState declaration changes from dim_ch_state_ptr to state_ptr. The DIM_GetChannelState declaration and definition has same argument name as state_ptr. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index f333f0adbcd23..76e4a62f2f204 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -96,7 +96,7 @@ void dim_service_irq(struct dim_channel *const *channels); u8 dim_service_channel(struct dim_channel *ch); struct dim_ch_state_t *DIM_GetChannelState(struct dim_channel *ch, - struct dim_ch_state_t *dim_ch_state_ptr); + struct dim_ch_state_t *state_ptr); bool DIM_EnqueueBuffer(struct dim_channel *ch, u32 buffer_addr, u16 buffer_size); -- GitLab From 60d5f66ce5e1a569fe0230bc1b23bfb5295f383d Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 2 Nov 2015 22:59:16 +0900 Subject: [PATCH 0449/2855] staging: most: rename DIM_GetChannelState to dim_get_channel_state This patch renames DIM_GetChannelState to dim_get_channel_state to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:865: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 4 ++-- drivers/staging/most/hdm-dim2/dim2_hal.h | 4 ++-- drivers/staging/most/hdm-dim2/dim2_hdm.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index a96457c60f6d0..e80a12ec0db4a 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -862,8 +862,8 @@ u8 dim_service_channel(struct dim_channel *ch) return channel_service(ch); } -struct dim_ch_state_t *DIM_GetChannelState(struct dim_channel *ch, - struct dim_ch_state_t *state_ptr) +struct dim_ch_state_t *dim_get_channel_state(struct dim_channel *ch, + struct dim_ch_state_t *state_ptr) { if (!ch || !state_ptr) return NULL; diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index 76e4a62f2f204..1ca7a1a2e0c58 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -95,8 +95,8 @@ void dim_service_irq(struct dim_channel *const *channels); u8 dim_service_channel(struct dim_channel *ch); -struct dim_ch_state_t *DIM_GetChannelState(struct dim_channel *ch, - struct dim_ch_state_t *state_ptr); +struct dim_ch_state_t *dim_get_channel_state(struct dim_channel *ch, + struct dim_ch_state_t *state_ptr); bool DIM_EnqueueBuffer(struct dim_channel *ch, u32 buffer_addr, u16 buffer_size); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 4b5df0b06008b..6524c3ce96856 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -246,7 +246,7 @@ static int try_start_dim_transfer(struct hdm_channel *hdm_ch) return -EAGAIN; } - if (!DIM_GetChannelState(&hdm_ch->ch, &st)->ready) { + if (!dim_get_channel_state(&hdm_ch->ch, &st)->ready) { spin_unlock_irqrestore(&dim_lock, flags); return -EAGAIN; } @@ -340,7 +340,7 @@ static void service_done_flag(struct dim2_hdm *dev, int ch_idx) spin_lock_irqsave(&dim_lock, flags); - done_buffers = DIM_GetChannelState(&hdm_ch->ch, &st)->done_buffers; + done_buffers = dim_get_channel_state(&hdm_ch->ch, &st)->done_buffers; if (!done_buffers) { spin_unlock_irqrestore(&dim_lock, flags); return; -- GitLab From c904ffdaf3e3ab679e43b9a87df02ff502dbd70c Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 2 Nov 2015 22:59:17 +0900 Subject: [PATCH 0450/2855] staging: most: rename DIM_EnqueueBuffer to dim_enqueue_buffer This patch renames DIM_EnqueueBuffer to dim_enqueue_buffer to avoid camelcase found by checkpatch. CHECK: Avoid CamelCase: FILE: drivers/staging/most/hdm-dim2/dim2_hal.c:877: Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.c | 3 ++- drivers/staging/most/hdm-dim2/dim2_hal.h | 4 ++-- drivers/staging/most/hdm-dim2/dim2_hdm.c | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index e80a12ec0db4a..172257596f1fa 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -874,7 +874,8 @@ struct dim_ch_state_t *dim_get_channel_state(struct dim_channel *ch, return state_ptr; } -bool DIM_EnqueueBuffer(struct dim_channel *ch, u32 buffer_addr, u16 buffer_size) +bool dim_enqueue_buffer(struct dim_channel *ch, u32 buffer_addr, + u16 buffer_size) { if (!ch) return dim_on_error(DIM_ERR_DRIVER_NOT_INITIALIZED, diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index 1ca7a1a2e0c58..48cdd9c8cde17 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -98,8 +98,8 @@ u8 dim_service_channel(struct dim_channel *ch); struct dim_ch_state_t *dim_get_channel_state(struct dim_channel *ch, struct dim_ch_state_t *state_ptr); -bool DIM_EnqueueBuffer(struct dim_channel *ch, u32 buffer_addr, - u16 buffer_size); +bool dim_enqueue_buffer(struct dim_channel *ch, u32 buffer_addr, + u16 buffer_size); bool dim_detach_buffers(struct dim_channel *ch, u16 buffers_number); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 6524c3ce96856..327d738c71942 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -73,8 +73,8 @@ struct hdm_channel { char name[sizeof "caNNN"]; bool is_initialized; struct dim_channel ch; - struct list_head pending_list; /* before DIM_EnqueueBuffer() */ - struct list_head started_list; /* after DIM_EnqueueBuffer() */ + struct list_head pending_list; /* before dim_enqueue_buffer() */ + struct list_head started_list; /* after dim_enqueue_buffer() */ enum most_channel_direction direction; enum most_channel_data_type data_type; }; @@ -255,7 +255,7 @@ static int try_start_dim_transfer(struct hdm_channel *hdm_ch) buf_size = mbo->buffer_length; BUG_ON(mbo->bus_address == 0); - if (!DIM_EnqueueBuffer(&hdm_ch->ch, mbo->bus_address, buf_size)) { + if (!dim_enqueue_buffer(&hdm_ch->ch, mbo->bus_address, buf_size)) { list_del(head->next); spin_unlock_irqrestore(&dim_lock, flags); mbo->processed_length = 0; -- GitLab From e23afff94803e9735d4f0edda0c77efad8d408a4 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 5 Nov 2015 14:34:43 +0100 Subject: [PATCH 0451/2855] staging: most: Delete an unnecessary check before the function call "module_put" The module_put() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/mostcore/core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/most/mostcore/core.c b/drivers/staging/most/mostcore/core.c index 19852ca7e59c3..ed1ed25b6d1d2 100644 --- a/drivers/staging/most/mostcore/core.c +++ b/drivers/staging/most/mostcore/core.c @@ -1587,8 +1587,7 @@ out: return 0; error: - if (iface->mod) - module_put(iface->mod); + module_put(iface->mod); modref--; mutex_unlock(&c->start_mutex); return ret; -- GitLab From 6c63e4238acad0bb5394e0fd50d993edd23c0dc7 Mon Sep 17 00:00:00 2001 From: Sebastian Sanchez Date: Fri, 6 Nov 2015 20:06:56 -0500 Subject: [PATCH 0452/2855] staging/rdma/hfi1: Convert dd_dev_info() to hfi1_cdbg() in process startup Replacing dd_dev_info() for hfi1_cdbg() to avoid generating syslog output for every context that is open by PSM. Reviewed-by: Mitko Haralanov Signed-off-by: Sebastian Sanchez Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/file_ops.c | 10 ++++----- drivers/staging/rdma/hfi1/init.c | 31 ++++++++++++++++------------ drivers/staging/rdma/hfi1/pio.c | 19 +++++++++-------- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/drivers/staging/rdma/hfi1/file_ops.c b/drivers/staging/rdma/hfi1/file_ops.c index 3b15eb4d5bf9c..97ca9ec8fd3fb 100644 --- a/drivers/staging/rdma/hfi1/file_ops.c +++ b/drivers/staging/rdma/hfi1/file_ops.c @@ -663,9 +663,9 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) } vma->vm_flags = flags; - dd_dev_info(dd, - "%s: %u:%u type:%u io/vf:%d/%d, addr:0x%llx, len:%lu(%lu), flags:0x%lx\n", - __func__, ctxt, subctxt, type, mapio, vmf, memaddr, memlen, + hfi1_cdbg(PROC, + "%u:%u type:%u io/vf:%d/%d, addr:0x%llx, len:%lu(%lu), flags:0x%lx\n", + ctxt, subctxt, type, mapio, vmf, memaddr, memlen, vma->vm_end - vma->vm_start, vma->vm_flags); pfn = (unsigned long)(memaddr >> PAGE_SHIFT); if (vmf) { @@ -989,8 +989,8 @@ static int allocate_ctxt(struct file *fp, struct hfi1_devdata *dd, if (!uctxt->sc) return -ENOMEM; - dbg("allocated send context %u(%u)\n", uctxt->sc->sw_index, - uctxt->sc->hw_context); + hfi1_cdbg(PROC, "allocated send context %u(%u)\n", uctxt->sc->sw_index, + uctxt->sc->hw_context); ret = sc_enable(uctxt->sc); if (ret) return ret; diff --git a/drivers/staging/rdma/hfi1/init.c b/drivers/staging/rdma/hfi1/init.c index 8666f3ad24e99..4a79744421547 100644 --- a/drivers/staging/rdma/hfi1/init.c +++ b/drivers/staging/rdma/hfi1/init.c @@ -60,6 +60,7 @@ #include "hfi.h" #include "device.h" #include "common.h" +#include "trace.h" #include "mad.h" #include "sdma.h" #include "debugfs.h" @@ -208,7 +209,7 @@ struct hfi1_ctxtdata *hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, u32 ctxt) if (rcd) { u32 rcvtids, max_entries; - dd_dev_info(dd, "%s: setting up context %u\n", __func__, ctxt); + hfi1_cdbg(PROC, "setting up context %u\n", ctxt); INIT_LIST_HEAD(&rcd->qp_wait_list); rcd->ppd = ppd; @@ -279,8 +280,9 @@ struct hfi1_ctxtdata *hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, u32 ctxt) rcd->ctxt); rcd->egrbufs.count = MAX_EAGER_ENTRIES; } - dd_dev_info(dd, "ctxt%u: max Eager buffer RcvArray entries: %u\n", - rcd->ctxt, rcd->egrbufs.count); + hfi1_cdbg(PROC, + "ctxt%u: max Eager buffer RcvArray entries: %u\n", + rcd->ctxt, rcd->egrbufs.count); /* * Allocate array that will hold the eager buffer accounting @@ -308,8 +310,8 @@ struct hfi1_ctxtdata *hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, u32 ctxt) */ if (rcd->egrbufs.size < hfi1_max_mtu) { rcd->egrbufs.size = __roundup_pow_of_two(hfi1_max_mtu); - dd_dev_info(dd, - "ctxt%u: eager bufs size too small. Adjusting to %zu\n", + hfi1_cdbg(PROC, + "ctxt%u: eager bufs size too small. Adjusting to %zu\n", rcd->ctxt, rcd->egrbufs.size); } rcd->egrbufs.rcvtid_size = HFI1_MAX_EAGER_BUFFER_SIZE; @@ -1660,9 +1662,11 @@ int hfi1_setup_eagerbufs(struct hfi1_ctxtdata *rcd) rcd->egrbufs.numbufs = idx; rcd->egrbufs.size = alloced_bytes; - dd_dev_info(dd, "ctxt%u: Alloced %u rcv tid entries @ %uKB, total %zuKB\n", - rcd->ctxt, rcd->egrbufs.alloced, rcd->egrbufs.rcvtid_size, - rcd->egrbufs.size); + hfi1_cdbg(PROC, + "ctxt%u: Alloced %u rcv tid entries @ %uKB, total %zuKB\n", + rcd->ctxt, rcd->egrbufs.alloced, rcd->egrbufs.rcvtid_size, + rcd->egrbufs.size); + /* * Set the contexts rcv array head update threshold to the closest @@ -1683,13 +1687,14 @@ int hfi1_setup_eagerbufs(struct hfi1_ctxtdata *rcd) rcd->expected_count = MAX_TID_PAIR_ENTRIES * 2; rcd->expected_base = rcd->eager_base + egrtop; - dd_dev_info(dd, "ctxt%u: eager:%u, exp:%u, egrbase:%u, expbase:%u\n", - rcd->ctxt, rcd->egrbufs.alloced, rcd->expected_count, - rcd->eager_base, rcd->expected_base); + hfi1_cdbg(PROC, "ctxt%u: eager:%u, exp:%u, egrbase:%u, expbase:%u\n", + rcd->ctxt, rcd->egrbufs.alloced, rcd->expected_count, + rcd->eager_base, rcd->expected_base); if (!hfi1_rcvbuf_validate(rcd->egrbufs.rcvtid_size, PT_EAGER, &order)) { - dd_dev_err(dd, "ctxt%u: current Eager buffer size is invalid %u\n", - rcd->ctxt, rcd->egrbufs.rcvtid_size); + hfi1_cdbg(PROC, + "ctxt%u: current Eager buffer size is invalid %u\n", + rcd->ctxt, rcd->egrbufs.rcvtid_size); ret = -EINVAL; goto bail; } diff --git a/drivers/staging/rdma/hfi1/pio.c b/drivers/staging/rdma/hfi1/pio.c index e5c32db4bc67c..eab58c12d9159 100644 --- a/drivers/staging/rdma/hfi1/pio.c +++ b/drivers/staging/rdma/hfi1/pio.c @@ -815,15 +815,16 @@ struct send_context *sc_alloc(struct hfi1_devdata *dd, int type, } } - dd_dev_info(dd, - "Send context %u(%u) %s group %u credits %u credit_ctrl 0x%llx threshold %u\n", - sw_index, - hw_context, - sc_type_name(type), - sc->group, - sc->credits, - sc->credit_ctrl, - thresh); + hfi1_cdbg(PIO, + "Send context %u(%u) %s group %u credits %u credit_ctrl 0x%llx threshold %u\n", + sw_index, + hw_context, + sc_type_name(type), + sc->group, + sc->credits, + sc->credit_ctrl, + thresh); + return sc; } -- GitLab From 72a67ba2fa69737757c637ac541a4f0271efb41d Mon Sep 17 00:00:00 2001 From: Easwar Hariharan Date: Fri, 6 Nov 2015 20:06:57 -0500 Subject: [PATCH 0453/2855] staging/rdma/hfi1: Clear the QSFP reset that is asserted on FLR The FLR on driver load asserts the QSFP reset pin and the driver does not deassert it after. This patch allows the external QSFP cable to exit reset by writing 1 to all the QSFP pins. Reviewed-by: Dean Luick Signed-off-by: Easwar Hariharan Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index 4e22477c97394..dd2ba2516a66d 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -9923,19 +9923,16 @@ static void init_chip(struct hfi1_devdata *dd) setextled(dd, 0); /* * Clear the QSFP reset. - * A0 leaves the out lines floating on power on, then on an FLR - * enforces a 0 on all out pins. The driver does not touch + * An FLR enforces a 0 on all out pins. The driver does not touch * ASIC_QSFPn_OUT otherwise. This leaves RESET_N low and - * anything plugged constantly in reset, if it pays attention + * anything plugged constantly in reset, if it pays attention * to RESET_N. - * A prime example of this is SiPh. For now, set all pins high. + * Prime examples of this are optical cables. Set all pins high. * I2CCLK and I2CDAT will change per direction, and INT_N and * MODPRS_N are input only and their value is ignored. */ - if (is_a0(dd)) { - write_csr(dd, ASIC_QSFP1_OUT, 0x1f); - write_csr(dd, ASIC_QSFP2_OUT, 0x1f); - } + write_csr(dd, ASIC_QSFP1_OUT, 0x1f); + write_csr(dd, ASIC_QSFP2_OUT, 0x1f); } static void init_early_variables(struct hfi1_devdata *dd) -- GitLab From bf70a77577361c334367a2a2add9d92b716a2481 Mon Sep 17 00:00:00 2001 From: Vennila Megavannan Date: Fri, 6 Nov 2015 20:06:58 -0500 Subject: [PATCH 0454/2855] staging/rdma/hfi1: Enable WFR PCIe extended tags from the driver Some BIOS implementations turn off extended tags in DevCtl (a RW field) even though it was originally set and is advertised in DevCap Fix is to set it in the driver Reviewed-by: Dean Luick Reviewed-by: Mike Marciniszyn Reviewed-by: Ashutosh Dixit Signed-off-by: Vennila Megavannan Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/pcie.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rdma/hfi1/pcie.c b/drivers/staging/rdma/hfi1/pcie.c index f531d0f6b212f..7fcf0896b65ab 100644 --- a/drivers/staging/rdma/hfi1/pcie.c +++ b/drivers/staging/rdma/hfi1/pcie.c @@ -467,8 +467,18 @@ static void tune_pcie_caps(struct hfi1_devdata *dd) { struct pci_dev *parent; u16 rc_mpss, rc_mps, ep_mpss, ep_mps; - u16 rc_mrrs, ep_mrrs, max_mrrs; + u16 rc_mrrs, ep_mrrs, max_mrrs, ectl; + /* + * Turn on extended tags in DevCtl in case the BIOS has turned it off + * to improve WFR SDMA bandwidth + */ + pcie_capability_read_word(dd->pcidev, PCI_EXP_DEVCTL, &ectl); + if (!(ectl & PCI_EXP_DEVCTL_EXT_TAG)) { + dd_dev_info(dd, "Enabling PCIe extended tags\n"); + ectl |= PCI_EXP_DEVCTL_EXT_TAG; + pcie_capability_write_word(dd->pcidev, PCI_EXP_DEVCTL, ectl); + } /* Find out supported and configured values for parent (root) */ parent = dd->pcidev->bus->self; if (!pci_is_root_bus(parent->bus)) { -- GitLab From 65fcf5576441eb23cd1f2c9f271cbf27e3455581 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Fri, 6 Nov 2015 20:06:59 -0500 Subject: [PATCH 0455/2855] staging/rdma/hfi1: Always download SBus firmware B0 dual port parts require the SBus firmware to always be downloaded. Remove reset of the SBus Master spico. It is not necessary since the SBus firmware download already does that. Reviewed-by: Dennis Dalessandro Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/firmware.c | 2 +- drivers/staging/rdma/hfi1/pcie.c | 12 +----------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/staging/rdma/hfi1/firmware.c b/drivers/staging/rdma/hfi1/firmware.c index b4bdcf341aacf..f3112821cf475 100644 --- a/drivers/staging/rdma/hfi1/firmware.c +++ b/drivers/staging/rdma/hfi1/firmware.c @@ -1568,7 +1568,7 @@ int load_pcie_firmware(struct hfi1_devdata *dd) /* both firmware loads below use the SBus */ set_sbus_fast_mode(dd); - if (fw_sbus_load && (dd->flags & HFI1_DO_INIT_ASIC)) { + if (fw_sbus_load) { turn_off_spicos(dd, SPICO_SBUS); ret = load_sbus_firmware(dd, &fw_sbus); if (ret) diff --git a/drivers/staging/rdma/hfi1/pcie.c b/drivers/staging/rdma/hfi1/pcie.c index 7fcf0896b65ab..0b7eafb0fc705 100644 --- a/drivers/staging/rdma/hfi1/pcie.c +++ b/drivers/staging/rdma/hfi1/pcie.c @@ -949,17 +949,7 @@ int do_pcie_gen3_transition(struct hfi1_devdata *dd) } retry: - - if (therm) { - /* - * toggle SPICO_ENABLE to get back to the state - * just after the firmware load - */ - sbus_request(dd, SBUS_MASTER_BROADCAST, 0x01, - WRITE_SBUS_RECEIVER, 0x00000040); - sbus_request(dd, SBUS_MASTER_BROADCAST, 0x01, - WRITE_SBUS_RECEIVER, 0x00000140); - } + /* the SBus download will reset the spico for thermal */ /* step 3: download SBus Master firmware */ /* step 4: download PCIe Gen3 SerDes firmware */ -- GitLab From 4ef98989cb08af8c7c9c955cd69327bb67dcd027 Mon Sep 17 00:00:00 2001 From: Jareer Abdel-Qader Date: Fri, 6 Nov 2015 20:07:00 -0500 Subject: [PATCH 0456/2855] staging/rdma/hfi1: Disable thermal polling before sensor initialization During driver load the thermal sensor needs to be reset prior to initialization of the sensor. This prevents a possible sensor lock up which can cause the wrong temperature value to be reported. This fix leads to remove disabling thermal polling from reset_asic_csrs() function. Reviewed by: Dennis Dalessandro Reviewed by: Easwar Hariharan Signed-off-by: Jareer Abdel-Qader Signed-off-by: Ira Weiny Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index dd2ba2516a66d..e842aee00535c 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -9449,7 +9449,7 @@ static void reset_asic_csrs(struct hfi1_devdata *dd) /* We might want to retain this state across FLR if we ever use it */ write_csr(dd, ASIC_CFG_DRV_STR, 0); - write_csr(dd, ASIC_CFG_THERM_POLL_EN, 0); + /* ASIC_CFG_THERM_POLL_EN leave alone */ /* ASIC_STS_THERM read-only */ /* ASIC_CFG_RESET leave alone */ @@ -10794,7 +10794,9 @@ static int thermal_init(struct hfi1_devdata *dd) acquire_hw_mutex(dd); dd_dev_info(dd, "Initializing thermal sensor\n"); - + /* Disable polling of thermal readings */ + write_csr(dd, ASIC_CFG_THERM_POLL_EN, 0x0); + msleep(100); /* Thermal Sensor Initialization */ /* Step 1: Reset the Thermal SBus Receiver */ ret = sbus_request_slow(dd, SBUS_THERMAL, 0x0, -- GitLab From 702249732580f8f9b392552806b55206642ff401 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Fri, 6 Nov 2015 20:07:01 -0500 Subject: [PATCH 0457/2855] staging/rdma/hfi1: Select only devices with active links When looking for or validating a user device, only use devices that are currently active. Reviewed-by: Mitko Haralanov Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/file_ops.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rdma/hfi1/file_ops.c b/drivers/staging/rdma/hfi1/file_ops.c index 97ca9ec8fd3fb..22037ce984c83 100644 --- a/drivers/staging/rdma/hfi1/file_ops.c +++ b/drivers/staging/rdma/hfi1/file_ops.c @@ -850,6 +850,14 @@ done: return ret; } +/* return true if the device available for general use */ +static int usable_device(struct hfi1_devdata *dd) +{ + struct hfi1_pportdata *ppd = dd->pport; + + return driver_lstate(ppd) == IB_PORT_ACTIVE; +} + static int get_user_context(struct file *fp, struct hfi1_user_info *uinfo, int devno, unsigned alg) { @@ -879,7 +887,11 @@ static int get_user_context(struct file *fp, struct hfi1_user_info *uinfo, for (dev = 0; dev < devmax; dev++) { pdd = hfi1_lookup(dev); - if (pdd && pdd->freectxts && + if (!pdd) + continue; + if (!usable_device(pdd)) + continue; + if (pdd->freectxts && pdd->freectxts > free) { dd = pdd; free = pdd->freectxts; @@ -888,7 +900,11 @@ static int get_user_context(struct file *fp, struct hfi1_user_info *uinfo, } else { for (dev = 0; dev < devmax; dev++) { pdd = hfi1_lookup(dev); - if (pdd && pdd->freectxts) { + if (!pdd) + continue; + if (!usable_device(pdd)) + continue; + if (pdd->freectxts) { dd = pdd; break; } @@ -913,7 +929,6 @@ static int find_shared_ctxt(struct file *fp, for (ndev = 0; ndev < devmax; ndev++) { struct hfi1_devdata *dd = hfi1_lookup(ndev); - /* device portion of usable() */ if (!(dd && (dd->flags & HFI1_PRESENT) && dd->kregbase)) continue; for (i = dd->first_user_ctxt; i < dd->num_rcv_contexts; i++) { -- GitLab From 801cfd6d8a24051a34d3cd4429e1ddc172b5aad6 Mon Sep 17 00:00:00 2001 From: Sebastian Sanchez Date: Fri, 6 Nov 2015 20:07:02 -0500 Subject: [PATCH 0458/2855] staging/rdma/hfi1: Fix for opaportconfig ledon by not checking for portNum opaportconfig ledon fails with error message due to port number being checked in the attr modifier. This change removes the check for the port number in AttrMod, so the P field is ignored. Reviewed-by: Easwar Hariharan Signed-off-by: Sebastian Sanchez Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/mad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rdma/hfi1/mad.c b/drivers/staging/rdma/hfi1/mad.c index 32f7037361853..a1225651005c1 100644 --- a/drivers/staging/rdma/hfi1/mad.c +++ b/drivers/staging/rdma/hfi1/mad.c @@ -3458,7 +3458,7 @@ static int __subn_get_opa_led_info(struct opa_smp *smp, u32 am, u8 *data, u32 nport = OPA_AM_NPORT(am); u64 reg; - if (nport != 1 || OPA_AM_PORTNUM(am)) { + if (nport != 1) { smp->status |= IB_SMP_INVALID_FIELD; return reply((struct ib_mad_hdr *)smp); } @@ -3483,7 +3483,7 @@ static int __subn_set_opa_led_info(struct opa_smp *smp, u32 am, u8 *data, u32 nport = OPA_AM_NPORT(am); int on = !!(be32_to_cpu(p->rsvd_led_mask) & OPA_LED_MASK); - if (nport != 1 || OPA_AM_PORTNUM(am)) { + if (nport != 1) { smp->status |= IB_SMP_INVALID_FIELD; return reply((struct ib_mad_hdr *)smp); } -- GitLab From a03a03e956c2cb8d0c69d33edb149c6a64584a48 Mon Sep 17 00:00:00 2001 From: Ignacio Hernandez Date: Fri, 6 Nov 2015 20:07:03 -0500 Subject: [PATCH 0459/2855] staging/rdma/hfi1: Remove spurious error messages Changed the order in which diagnostics messages are printed, taking into account the cases where the errors are handled in rcv_hdrerr() and no further message is needed to report. Reviewed-by: Mark Debbage Reviewed-by: Arthur Kepner Reviewed-by: Mike Marciniszyn Signed-off-by: Ignacio Hernandez Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/driver.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/rdma/hfi1/driver.c b/drivers/staging/rdma/hfi1/driver.c index 9a4ec09af0201..72ab5e145f495 100644 --- a/drivers/staging/rdma/hfi1/driver.c +++ b/drivers/staging/rdma/hfi1/driver.c @@ -1156,20 +1156,20 @@ void handle_eflags(struct hfi1_packet *packet) struct hfi1_ctxtdata *rcd = packet->rcd; u32 rte = rhf_rcv_type_err(packet->rhf); - dd_dev_err(rcd->dd, - "receive context %d: rhf 0x%016llx, errs [ %s%s%s%s%s%s%s%s] rte 0x%x\n", - rcd->ctxt, packet->rhf, - packet->rhf & RHF_K_HDR_LEN_ERR ? "k_hdr_len " : "", - packet->rhf & RHF_DC_UNC_ERR ? "dc_unc " : "", - packet->rhf & RHF_DC_ERR ? "dc " : "", - packet->rhf & RHF_TID_ERR ? "tid " : "", - packet->rhf & RHF_LEN_ERR ? "len " : "", - packet->rhf & RHF_ECC_ERR ? "ecc " : "", - packet->rhf & RHF_VCRC_ERR ? "vcrc " : "", - packet->rhf & RHF_ICRC_ERR ? "icrc " : "", - rte); - rcv_hdrerr(rcd, rcd->ppd, packet); + if (rhf_err_flags(packet->rhf)) + dd_dev_err(rcd->dd, + "receive context %d: rhf 0x%016llx, errs [ %s%s%s%s%s%s%s%s] rte 0x%x\n", + rcd->ctxt, packet->rhf, + packet->rhf & RHF_K_HDR_LEN_ERR ? "k_hdr_len " : "", + packet->rhf & RHF_DC_UNC_ERR ? "dc_unc " : "", + packet->rhf & RHF_DC_ERR ? "dc " : "", + packet->rhf & RHF_TID_ERR ? "tid " : "", + packet->rhf & RHF_LEN_ERR ? "len " : "", + packet->rhf & RHF_ECC_ERR ? "ecc " : "", + packet->rhf & RHF_VCRC_ERR ? "vcrc " : "", + packet->rhf & RHF_ICRC_ERR ? "icrc " : "", + rte); } /* -- GitLab From 3bf40d65dcbfd7335680ffbc59e83a3671682472 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Fri, 6 Nov 2015 20:07:04 -0500 Subject: [PATCH 0460/2855] staging/rdma/hfi1: use one-shot LCB write Use the one-shot LCB write implemented in the 8051 firmware. This speeds up 8051 LCB writes by 2x. Use old method for older firmwares. Reviewed-by: Dennis Dalessandro Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 42 ++++++++++++++++++++++++++++---- drivers/staging/rdma/hfi1/chip.h | 1 + 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index e842aee00535c..d858f36042b5a 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -4774,13 +4774,25 @@ int read_lcb_csr(struct hfi1_devdata *dd, u32 addr, u64 *data) */ static int write_lcb_via_8051(struct hfi1_devdata *dd, u32 addr, u64 data) { + u32 regno; + int ret; - if (acquire_lcb_access(dd, 0) == 0) { - write_csr(dd, addr, data); - release_lcb_access(dd, 0); - return 0; + if (dd->icode == ICODE_FUNCTIONAL_SIMULATOR || + (dd->dc8051_ver < dc8051_ver(0, 20))) { + if (acquire_lcb_access(dd, 0) == 0) { + write_csr(dd, addr, data); + release_lcb_access(dd, 0); + return 0; + } + return -EBUSY; } - return -EBUSY; + + /* register is an index of LCB registers: (offset - base) / 8 */ + regno = (addr - DC_LCB_CFG_RUN) >> 3; + ret = do_8051_command(dd, HCMD_WRITE_LCB_CSR, regno, &data); + if (ret != HCMD_SUCCESS) + return -EBUSY; + return 0; } /* @@ -4861,6 +4873,26 @@ static int do_8051_command( * waiting for a command. */ + /* + * When writing a LCB CSR, out_data contains the full value to + * to be written, while in_data contains the relative LCB + * address in 7:0. Do the work here, rather than the caller, + * of distrubting the write data to where it needs to go: + * + * Write data + * 39:00 -> in_data[47:8] + * 47:40 -> DC8051_CFG_EXT_DEV_0.RETURN_CODE + * 63:48 -> DC8051_CFG_EXT_DEV_0.RSP_DATA + */ + if (type == HCMD_WRITE_LCB_CSR) { + in_data |= ((*out_data) & 0xffffffffffull) << 8; + reg = ((((*out_data) >> 40) & 0xff) << + DC_DC8051_CFG_EXT_DEV_0_RETURN_CODE_SHIFT) + | ((((*out_data) >> 48) & 0xffff) << + DC_DC8051_CFG_EXT_DEV_0_RSP_DATA_SHIFT); + write_csr(dd, DC_DC8051_CFG_EXT_DEV_0, reg); + } + /* * Do two writes: the first to stabilize the type and req_data, the * second to activate. diff --git a/drivers/staging/rdma/hfi1/chip.h b/drivers/staging/rdma/hfi1/chip.h index ebf9041a1c5ea..d74aed8ccc18d 100644 --- a/drivers/staging/rdma/hfi1/chip.h +++ b/drivers/staging/rdma/hfi1/chip.h @@ -235,6 +235,7 @@ #define HCMD_MISC 0x05 #define HCMD_READ_LCB_IDLE_MSG 0x06 #define HCMD_READ_LCB_CSR 0x07 +#define HCMD_WRITE_LCB_CSR 0x08 #define HCMD_INTERFACE_TEST 0xff /* DC_DC8051_CFG_HOST_CMD_1.RETURN_CODE - 8051 host command return */ -- GitLab From be1d6cb3e657907731a9aeb3cafd190c94634753 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Thu, 5 Nov 2015 19:35:36 +0530 Subject: [PATCH 0461/2855] Staging: fwserial: Declare fwtty_port_put as static Declare the function fwtty_port_put as static since it is used only in this particular file. Also remove the corresponding declaration from header file. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fwserial/fwserial.c | 3 +-- drivers/staging/fwserial/fwserial.h | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index b3ea4bb54e2c7..b676c486cb189 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -893,11 +893,10 @@ static void fwserial_destroy(struct kref *kref) kfree(serial); } -void fwtty_port_put(struct fwtty_port *port) +static void fwtty_port_put(struct fwtty_port *port) { kref_put(&port->serial->kref, fwserial_destroy); } -EXPORT_SYMBOL(fwtty_port_put); static void fwtty_port_dtr_rts(struct tty_port *tty_port, int on) { diff --git a/drivers/staging/fwserial/fwserial.h b/drivers/staging/fwserial/fwserial.h index 8d791ae79cd61..e13fe33a68974 100644 --- a/drivers/staging/fwserial/fwserial.h +++ b/drivers/staging/fwserial/fwserial.h @@ -342,8 +342,6 @@ static const char loop_dev_name[] = "fwloop"; extern struct tty_driver *fwtty_driver; struct fwtty_port *fwtty_port_get(unsigned index); -void fwtty_port_put(struct fwtty_port *port); - /* * Returns the max send async payload size in bytes based on the unit device * link speed. Self-limiting asynchronous bandwidth (via reducing the payload) -- GitLab From 4811789503d16510a8a6610fb6c4097e1efa6312 Mon Sep 17 00:00:00 2001 From: Gavin O'Leary Date: Mon, 9 Nov 2015 20:12:00 -0800 Subject: [PATCH 0462/2855] staging: unisys: visorbus: visorbus_main.c: made checkpatch warning-free Made visorbus_main.c checkpatch warning-free by fixing the comment style issues. Signed-off-by: Gavin O'Leary Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorbus_main.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index a272b48bab282..eac97d22278a1 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -1078,7 +1078,8 @@ away: } /* Write the contents of to the struct - * spar_vbus_channel_protocol.chp_info. */ + * spar_vbus_channel_protocol.chp_info. + */ static int write_vbus_chp_info(struct visorchannel *chan, @@ -1096,7 +1097,8 @@ write_vbus_chp_info(struct visorchannel *chan, } /* Write the contents of to the struct - * spar_vbus_channel_protocol.bus_info. */ + * spar_vbus_channel_protocol.bus_info. + */ static int write_vbus_bus_info(struct visorchannel *chan, @@ -1370,7 +1372,8 @@ pause_state_change_complete(struct visor_device *dev, int status) /* Notify the chipset driver that the pause is complete, which * will presumably want to send some sort of response to the - * initiator. */ + * initiator. + */ (*chipset_responders.device_pause) (dev, status); } @@ -1390,7 +1393,8 @@ resume_state_change_complete(struct visor_device *dev, int status) /* Notify the chipset driver that the resume is complete, * which will presumably want to send some sort of response to - * the initiator. */ + * the initiator. + */ (*chipset_responders.device_resume) (dev, status); } @@ -1437,7 +1441,8 @@ initiate_chipset_device_pause_resume(struct visor_device *dev, bool is_pause) * existing problem prevents us from ever getting a bus * resume... This hack would fail to work should we * ever have a bus that contains NO devices, since we - * would never even get here in that case. */ + * would never even get here in that case. + */ fix_vbus_dev_info(dev); if (!drv->resume) goto away; -- GitLab From d2a2e729a666972d1938e63e804ee5bb6ea13549 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Wed, 4 Nov 2015 11:12:14 -0600 Subject: [PATCH 0463/2855] regulator: tps65086: Add regulator driver for the TPS65086 PMIC Add support for TPS65086 PMIC regulators. The regulators set consists of 3 Step-down Controllers, 3 Step-down Converters, 3 LDOs, 3 Load Switches, and a Sink and Source LDO. The output voltages are configurable and are meant to supply power to a SoC and/or other components. Signed-off-by: Andrew F. Davis Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 7 + drivers/regulator/Makefile | 1 + drivers/regulator/tps65086-regulator.c | 250 +++++++++++++++++++++++++ 3 files changed, 258 insertions(+) create mode 100644 drivers/regulator/tps65086-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 8df0b0e62976d..b45fc6023bef1 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -680,6 +680,13 @@ config REGULATOR_TPS6507X three step-down converters and two general-purpose LDO voltage regulators. It supports TI's software based Class-2 SmartReflex implementation. +config REGULATOR_TPS65086 + tristate "TI TPS65086 Power regulators" + depends on MFD_TPS65086 + help + This driver provides support for the voltage regulators on + TI TPS65086 PMICs. + config REGULATOR_TPS65090 tristate "TI TPS65090 Power regulator" depends on MFD_TPS65090 diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 0f8174913c17b..945d8ec5ea8ff 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -85,6 +85,7 @@ obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o +obj-$(CONFIG_REGULATOR_TPS65086) += tps65086-regulator.o obj-$(CONFIG_REGULATOR_TPS65090) += tps65090-regulator.o obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o obj-$(CONFIG_REGULATOR_TPS65218) += tps65218-regulator.o diff --git a/drivers/regulator/tps65086-regulator.c b/drivers/regulator/tps65086-regulator.c new file mode 100644 index 0000000000000..c26fc7e88ebaf --- /dev/null +++ b/drivers/regulator/tps65086-regulator.c @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ + * + * Author: Andrew F. Davis + * + * 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. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether expressed or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License version 2 for more details. + * + * Based on the TPS65912 driver + */ + +#include +#include +#include +#include +#include + +#include + +enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1, + LDOA2, LDOA3, SWA1, SWB1, SWB2, VTT }; + +#define TPS65086_REGULATOR(_name, _of, _id, _nv, _vr, _vm, _er, _em, _lr, _dr, _dm) \ + [_id] = { \ + .desc = { \ + .name = _name, \ + .of_match = of_match_ptr(_of), \ + .of_parse_cb = tps65086_of_parse_cb, \ + .id = _id, \ + .ops = ®_ops, \ + .n_voltages = _nv, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .vsel_reg = _vr, \ + .vsel_mask = _vm, \ + .enable_reg = _er, \ + .enable_mask = _em, \ + .volt_table = NULL, \ + .linear_ranges = _lr, \ + .n_linear_ranges = ARRAY_SIZE(_lr), \ + }, \ + .decay_reg = _dr, \ + .decay_mask = _dm, \ + } + +#define TPS65086_SWITCH(_name, _of, _id, _er, _em) \ + [_id] = { \ + .desc = { \ + .name = _name, \ + .of_match = of_match_ptr(_of), \ + .of_parse_cb = tps65086_of_parse_cb, \ + .id = _id, \ + .ops = &switch_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .enable_reg = _er, \ + .enable_mask = _em, \ + }, \ + } + +struct tps65086_regulator { + struct regulator_desc desc; + unsigned int decay_reg; + unsigned int decay_mask; +}; + +static const struct regulator_linear_range tps65086_buck126_10mv_ranges[] = { + REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0), + REGULATOR_LINEAR_RANGE(410000, 0x1, 0x7F, 10000), +}; + +static const struct regulator_linear_range tps65086_buck126_25mv_ranges[] = { + REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0), + REGULATOR_LINEAR_RANGE(1000000, 0x1, 0x18, 0), + REGULATOR_LINEAR_RANGE(1025000, 0x19, 0x7F, 25000), +}; + +static const struct regulator_linear_range tps65086_buck345_ranges[] = { + REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0), + REGULATOR_LINEAR_RANGE(425000, 0x1, 0x7F, 25000), +}; + +static const struct regulator_linear_range tps65086_ldoa1_ranges[] = { + REGULATOR_LINEAR_RANGE(1350000, 0x0, 0x0, 0), + REGULATOR_LINEAR_RANGE(1500000, 0x1, 0x7, 100000), + REGULATOR_LINEAR_RANGE(2300000, 0x8, 0xA, 100000), + REGULATOR_LINEAR_RANGE(2700000, 0xB, 0xD, 150000), + REGULATOR_LINEAR_RANGE(3300000, 0xE, 0xE, 0), +}; + +static const struct regulator_linear_range tps65086_ldoa23_ranges[] = { + REGULATOR_LINEAR_RANGE(700000, 0x0, 0xD, 50000), + REGULATOR_LINEAR_RANGE(1400000, 0xE, 0xF, 100000), +}; + +/* Operations permitted on regulators */ +static struct regulator_ops reg_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .map_voltage = regulator_map_voltage_linear_range, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear_range, +}; + +/* Operations permitted on load switches */ +static struct regulator_ops switch_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, +}; + +static int tps65086_of_parse_cb(struct device_node *dev, + const struct regulator_desc *desc, + struct regulator_config *config); + +static struct tps65086_regulator regulators[] = { + TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL, + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0), + tps65086_buck126_10mv_ranges, TPS65086_BUCK1CTRL, + BIT(0)), + TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL, + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1), + tps65086_buck126_10mv_ranges, TPS65086_BUCK2CTRL, + BIT(0)), + TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID, + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2), + tps65086_buck345_ranges, TPS65086_BUCK3DECAY, + BIT(0)), + TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID, + BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0), + tps65086_buck345_ranges, TPS65086_BUCK4VID, + BIT(0)), + TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID, + BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0), + tps65086_buck345_ranges, TPS65086_BUCK5CTRL, + BIT(0)), + TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID, + BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0), + tps65086_buck126_10mv_ranges, TPS65086_BUCK6CTRL, + BIT(0)), + TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL, + VDOA1_VID_MASK, TPS65086_LDOA1CTRL, BIT(0), + tps65086_ldoa1_ranges, 0, 0), + TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID, + VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0), + tps65086_ldoa23_ranges, 0, 0), + TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID, + VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0), + tps65086_ldoa23_ranges, 0, 0), + TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)), + TPS65086_SWITCH("SWB1", "swa2", SWB1, TPS65086_SWVTT_EN, BIT(6)), + TPS65086_SWITCH("SWB2", "swa3", SWB2, TPS65086_SWVTT_EN, BIT(7)), + TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)), +}; + +static inline bool has_25mv_mode(int id) +{ + switch (id) { + case BUCK1: + case BUCK2: + case BUCK6: + return true; + default: + return false; + } +} + +static int tps65086_of_parse_cb(struct device_node *dev, + const struct regulator_desc *desc, + struct regulator_config *config) +{ + int ret; + + /* Check for 25mV step mode */ + if (has_25mv_mode(desc->id) && + of_property_read_bool(config->of_node, "ti,regulator-step-size-25mv")) { + regulators[desc->id].desc.linear_ranges = + tps65086_buck126_25mv_ranges; + regulators[desc->id].desc.n_linear_ranges = + ARRAY_SIZE(tps65086_buck126_25mv_ranges); + } + + /* Check for decay mode */ + if (desc->id <= BUCK6 && of_property_read_bool(config->of_node, "ti,regulator-decay")) { + ret = regmap_write_bits(config->regmap, + regulators[desc->id].decay_reg, + regulators[desc->id].decay_mask, + regulators[desc->id].decay_mask); + if (ret) { + dev_err(config->dev, "Error setting decay\n"); + return ret; + } + } + + return 0; +} + +static int tps65086_regulator_probe(struct platform_device *pdev) +{ + struct tps65086 *tps = dev_get_drvdata(pdev->dev.parent); + struct regulator_config config = { }; + struct regulator_dev *rdev; + int i; + + platform_set_drvdata(pdev, tps); + + config.dev = &pdev->dev; + config.driver_data = tps; + config.of_node = pdev->dev.of_node; + config.regmap = tps->regmap; + + for (i = 0; i < ARRAY_SIZE(regulators); i++) { + rdev = devm_regulator_register(&pdev->dev, ®ulators[i].desc, + &config); + if (IS_ERR(rdev)) { + dev_err(tps->dev, "failed to register %s regulator\n", + pdev->name); + return PTR_ERR(rdev); + } + } + + return 0; +} + +static const struct platform_device_id tps65086_regulator_id_table[] = { + { "tps65086-regulator", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, tps65086_regulator_id_table); + +static struct platform_driver tps65086_regulator_driver = { + .driver = { + .name = "tps65086-regulator", + }, + .probe = tps65086_regulator_probe, + .id_table = tps65086_regulator_id_table, +}; +module_platform_driver(tps65086_regulator_driver); + +MODULE_AUTHOR("Andrew F. Davis "); +MODULE_DESCRIPTION("TPS65086 Regulator driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From ebfb319bb601e501f77809a83b0b69b529c22a8d Mon Sep 17 00:00:00 2001 From: Konstantin Shkolnyy Date: Wed, 28 Oct 2015 16:02:03 -0500 Subject: [PATCH 0464/2855] USB: cp210x: flush device queues at close Flush all device queues at close in order to work around a cp2108 Tx queue bug. Occasionally, writing data and immediately closing the port makes cp2108 stop responding. The device has to be unplugged to clear the error. The failure is induced by shutting down the device while its Tx queue still has unsent data. This condition is avoided by issuing PURGE command from the close() callback. This change is applied to all cp210x devices. Clearing internal queues on close is generally good. Signed-off-by: Konstantin Shkolnyy [johan: amend commit message ] Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index eac7ccaa3c859..8ba1005f6a53b 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -300,6 +300,14 @@ static struct usb_serial_driver * const serial_drivers[] = { #define CONTROL_WRITE_DTR 0x0100 #define CONTROL_WRITE_RTS 0x0200 +/* + * CP210X_PURGE - 16 bits passed in wValue of USB request. + * SiLabs app note AN571 gives a strange description of the 4 bits: + * bit 0 or bit 2 clears the transmit queue and 1 or 3 receive. + * writing 1 to all, however, purges cp2108 well enough to avoid the hang. + */ +#define PURGE_ALL 0x000f + /* * cp210x_get_config * Reads from the CP210x configuration registers @@ -475,7 +483,14 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) static void cp210x_close(struct usb_serial_port *port) { + unsigned int purge_ctl; + usb_serial_generic_close(port); + + /* Clear both queues; cp2108 needs this to avoid an occasional hang */ + purge_ctl = PURGE_ALL; + cp210x_set_config(port, CP210X_PURGE, &purge_ctl, 2); + cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_DISABLE); } -- GitLab From e2ae67a3b55188b0342522d8139acf013feb2a69 Mon Sep 17 00:00:00 2001 From: Konstantin Shkolnyy Date: Wed, 28 Oct 2015 16:02:34 -0500 Subject: [PATCH 0465/2855] USB: cp210x: relocate private data from USB interface to port This change is preparation for implementing a cp2108 bug workaround. The workaround requires storing some private data. Right now the data is attached to the USB interface and allocated in the attach() callback. The bug detection requires USB I/O which is done easier from port_probe() callback rather than attach(). Since the USB access functions take port as a parameter, and since the private data is used exclusively by these functions, it can be allocated in port_probe(). Also, all cp210x devices have exactly 1 port per USB iterface, so moving private data from the USB interface to port is trivial. Signed-off-by: Konstantin Shkolnyy Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 43 ++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 8ba1005f6a53b..352fe63fb056d 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -43,8 +43,8 @@ static int cp210x_tiocmset(struct tty_struct *, unsigned int, unsigned int); static int cp210x_tiocmset_port(struct usb_serial_port *port, unsigned int, unsigned int); static void cp210x_break_ctl(struct tty_struct *, int); -static int cp210x_startup(struct usb_serial *); -static void cp210x_release(struct usb_serial *); +static int cp210x_port_probe(struct usb_serial_port *); +static int cp210x_port_remove(struct usb_serial_port *); static void cp210x_dtr_rts(struct usb_serial_port *p, int on); static const struct usb_device_id id_table[] = { @@ -197,7 +197,7 @@ static const struct usb_device_id id_table[] = { MODULE_DEVICE_TABLE(usb, id_table); -struct cp210x_serial_private { +struct cp210x_port_private { __u8 bInterfaceNumber; }; @@ -216,8 +216,8 @@ static struct usb_serial_driver cp210x_device = { .set_termios = cp210x_set_termios, .tiocmget = cp210x_tiocmget, .tiocmset = cp210x_tiocmset, - .attach = cp210x_startup, - .release = cp210x_release, + .port_probe = cp210x_port_probe, + .port_remove = cp210x_port_remove, .dtr_rts = cp210x_dtr_rts }; @@ -319,7 +319,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, unsigned int *data, int size) { struct usb_serial *serial = port->serial; - struct cp210x_serial_private *spriv = usb_get_serial_data(serial); + struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); __le32 *buf; int result, i, length; @@ -333,7 +333,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, /* Issue the request, attempting to read 'size' bytes */ result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), request, REQTYPE_INTERFACE_TO_HOST, 0x0000, - spriv->bInterfaceNumber, buf, size, + port_priv->bInterfaceNumber, buf, size, USB_CTRL_GET_TIMEOUT); /* Convert data into an array of integers */ @@ -364,7 +364,7 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, unsigned int *data, int size) { struct usb_serial *serial = port->serial; - struct cp210x_serial_private *spriv = usb_get_serial_data(serial); + struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); __le32 *buf; int result, i, length; @@ -383,13 +383,13 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_INTERFACE, 0x0000, - spriv->bInterfaceNumber, buf, size, + port_priv->bInterfaceNumber, buf, size, USB_CTRL_SET_TIMEOUT); } else { result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_INTERFACE, data[0], - spriv->bInterfaceNumber, NULL, 0, + port_priv->bInterfaceNumber, NULL, 0, USB_CTRL_SET_TIMEOUT); } @@ -878,29 +878,32 @@ static void cp210x_break_ctl(struct tty_struct *tty, int break_state) cp210x_set_config(port, CP210X_SET_BREAK, &state, 2); } -static int cp210x_startup(struct usb_serial *serial) +static int cp210x_port_probe(struct usb_serial_port *port) { + struct usb_serial *serial = port->serial; struct usb_host_interface *cur_altsetting; - struct cp210x_serial_private *spriv; + struct cp210x_port_private *port_priv; - spriv = kzalloc(sizeof(*spriv), GFP_KERNEL); - if (!spriv) + port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); + if (!port_priv) return -ENOMEM; cur_altsetting = serial->interface->cur_altsetting; - spriv->bInterfaceNumber = cur_altsetting->desc.bInterfaceNumber; + port_priv->bInterfaceNumber = cur_altsetting->desc.bInterfaceNumber; - usb_set_serial_data(serial, spriv); + usb_set_serial_port_data(port, port_priv); return 0; } -static void cp210x_release(struct usb_serial *serial) +static int cp210x_port_remove(struct usb_serial_port *port) { - struct cp210x_serial_private *spriv; + struct cp210x_port_private *port_priv; + + port_priv = usb_get_serial_port_data(port); + kfree(port_priv); - spriv = usb_get_serial_data(serial); - kfree(spriv); + return 0; } module_usb_serial_driver(serial_drivers, id_table); -- GitLab From d0bf1ff0ae322aca59b00b9a2ad121d35a77e78f Mon Sep 17 00:00:00 2001 From: Konstantin Shkolnyy Date: Wed, 28 Oct 2015 16:02:54 -0500 Subject: [PATCH 0466/2855] USB: cp210x: work around cp2108 GET_LINE_CTL bug Add helper to access line-control register in order to work around a cp2108 GET_LINE_CTL bug. cp2108 GET_LINE_CTL returns the 16-bit value with the 2 bytes swapped. However, SET_LINE_CTL functions properly. When the driver tries to modify the register, it reads it, modifies some bits and writes back. Because the read bytes were swapped, this often results in an invalid value to be written. In turn, this causes cp2108 respond with a stall. The stall sometimes doesn't clear properly and cp2108 starts responding to following valid commands also with stalls, effectively failing. Signed-off-by: Konstantin Shkolnyy [johan: amend commit message, modify probe error handling ] Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 70 ++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 352fe63fb056d..9e5d5b016633a 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -199,6 +199,7 @@ MODULE_DEVICE_TABLE(usb, id_table); struct cp210x_port_private { __u8 bInterfaceNumber; + bool has_swapped_line_ctl; }; static struct usb_serial_driver cp210x_device = { @@ -418,6 +419,60 @@ static inline int cp210x_set_config_single(struct usb_serial_port *port, return cp210x_set_config(port, request, &data, 2); } +/* + * Detect CP2108 GET_LINE_CTL bug and activate workaround. + * Write a known good value 0x800, read it back. + * If it comes back swapped the bug is detected. + * Preserve the original register value. + */ +static int cp210x_detect_swapped_line_ctl(struct usb_serial_port *port) +{ + struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); + unsigned int line_ctl_save; + unsigned int line_ctl_test; + int err; + + err = cp210x_get_config(port, CP210X_GET_LINE_CTL, &line_ctl_save, 2); + if (err) + return err; + + line_ctl_test = 0x800; + err = cp210x_set_config(port, CP210X_SET_LINE_CTL, &line_ctl_test, 2); + if (err) + return err; + + err = cp210x_get_config(port, CP210X_GET_LINE_CTL, &line_ctl_test, 2); + if (err) + return err; + + if (line_ctl_test == 8) { + port_priv->has_swapped_line_ctl = true; + line_ctl_save = swab16((u16)line_ctl_save); + } + + return cp210x_set_config(port, CP210X_SET_LINE_CTL, &line_ctl_save, 2); +} + +/* + * Must always be called instead of cp210x_get_config(CP210X_GET_LINE_CTL) + * to workaround cp2108 bug and get correct value. + */ +static int cp210x_get_line_ctl(struct usb_serial_port *port, unsigned int *ctl) +{ + struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); + int err; + + err = cp210x_get_config(port, CP210X_GET_LINE_CTL, ctl, 2); + if (err) + return err; + + /* Workaround swapped bytes in 16-bit value from CP210X_GET_LINE_CTL */ + if (port_priv->has_swapped_line_ctl) + *ctl = swab16((u16)(*ctl)); + + return 0; +} + /* * cp210x_quantise_baudrate * Quantises the baud rate as per AN205 Table 1 @@ -535,7 +590,7 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, cflag = *cflagp; - cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); + cp210x_get_line_ctl(port, &bits); cflag &= ~CSIZE; switch (bits & BITS_DATA_MASK) { case BITS_DATA_5: @@ -703,7 +758,7 @@ static void cp210x_set_termios(struct tty_struct *tty, /* If the number of data bits is to be updated */ if ((cflag & CSIZE) != (old_cflag & CSIZE)) { - cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); + cp210x_get_line_ctl(port, &bits); bits &= ~BITS_DATA_MASK; switch (cflag & CSIZE) { case CS5: @@ -737,7 +792,7 @@ static void cp210x_set_termios(struct tty_struct *tty, if ((cflag & (PARENB|PARODD|CMSPAR)) != (old_cflag & (PARENB|PARODD|CMSPAR))) { - cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); + cp210x_get_line_ctl(port, &bits); bits &= ~BITS_PARITY_MASK; if (cflag & PARENB) { if (cflag & CMSPAR) { @@ -763,7 +818,7 @@ static void cp210x_set_termios(struct tty_struct *tty, } if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { - cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); + cp210x_get_line_ctl(port, &bits); bits &= ~BITS_STOP_MASK; if (cflag & CSTOPB) { bits |= BITS_STOP_2; @@ -883,6 +938,7 @@ static int cp210x_port_probe(struct usb_serial_port *port) struct usb_serial *serial = port->serial; struct usb_host_interface *cur_altsetting; struct cp210x_port_private *port_priv; + int ret; port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); if (!port_priv) @@ -893,6 +949,12 @@ static int cp210x_port_probe(struct usb_serial_port *port) usb_set_serial_port_data(port, port_priv); + ret = cp210x_detect_swapped_line_ctl(port); + if (ret) { + kfree(port_priv); + return ret; + } + return 0; } -- GitLab From 4dde99bd32fc3f61f7c2b602a78f1627a118e450 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 9 Nov 2015 10:28:50 +0100 Subject: [PATCH 0467/2855] spi/bcm63xx: Move default clock configuration to kill compiler warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/spi/spi-bcm63xx.c: In function ‘bcm63xx_spi_setup_transfer’: drivers/spi/spi-bcm63xx.c:207: warning: ‘clk_cfg’ may be used uninitialized in this function While this is a false positive, it can easily be avoided by selecting the default clock configuration first. Signed-off-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 06858e04ec59a..cc8e1513d1673 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -207,6 +207,9 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi, u8 clk_cfg, reg; int i; + /* Default to lowest clock configuration */ + clk_cfg = SPI_CLK_0_391MHZ; + /* Find the closest clock configuration */ for (i = 0; i < SPI_CLK_MASK; i++) { if (t->speed_hz >= bcm63xx_spi_freq_table[i][0]) { @@ -215,10 +218,6 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi, } } - /* No matching configuration found, default to lowest */ - if (i == SPI_CLK_MASK) - clk_cfg = SPI_CLK_0_391MHZ; - /* clear existing clock configuration bits of the register */ reg = bcm_spi_readb(bs, SPI_CLK_CFG); reg &= ~SPI_CLK_MASK; -- GitLab From c7f00c29aa846b00c70bc99ddb6b1cc7e17c47d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ezequiel=20Garc=C3=ADa?= Date: Wed, 4 Nov 2015 13:13:41 -0300 Subject: [PATCH 0468/2855] mtd: pxa3xx_nand: Increase the initial chunk size The chunk size represents the size of the data chunks, which is used by the controllers that allow to split transfered data. However, the initial chunk size is used in a non-splitted way, during device identification. Therefore, it must be large enough for all the NAND commands issued during device identification. This includes NAND_CMD_PARAM which was recently changed to transfer up to 2048 bytes (for the redundant parameter pages). Thus, the initial chunk size should be 2048 as well. On Armada 370/XP platforms (NFCv2) booted without the keep-config devicetree property, this commit fixes a timeout on the NAND_CMD_PARAM command: [..] pxa3xx-nand f10d0000.nand: This platform can't do DMA on this device pxa3xx-nand f10d0000.nand: Wait time out!!! nand: device found, Manufacturer ID: 0x2c, Chip ID: 0x38 nand: Micron MT29F8G08ABABAWP nand: 1024 MiB, SLC, erase size: 512 KiB, page size: 4096, OOB size: 224 Signed-off-by: Ezequiel Garcia Acked-by: Robert Jarzmik Signed-off-by: Brian Norris --- drivers/mtd/nand/pxa3xx_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 37df51df422e9..d3da5ef5faa4c 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -1592,7 +1592,7 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) goto KEEP_CONFIG; /* Set a default chunk size */ - info->chunk_size = 512; + info->chunk_size = PAGE_CHUNK_SIZE; ret = pxa3xx_nand_config_flash(info); if (ret) -- GitLab From 66e8e47eae658dc884e65695a597fdda7a109448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ezequiel=20Garc=C3=ADa?= Date: Wed, 4 Nov 2015 13:13:42 -0300 Subject: [PATCH 0469/2855] mtd: pxa3xx_nand: Fix initial controller configuration The Data Flash Control Register (NDCR) contains two types of parameters: those that are needed for device identification, and those that can only be set after device identification. Therefore, the driver can't set them all at once and instead needs to configure the first group before nand_scan_ident() and the second group later. Let's split pxa3xx_nand_config in two halves, and set the parameters that depend on the device geometry once this is known. Signed-off-by: Ezequiel Garcia Signed-off-by: Brian Norris --- drivers/mtd/nand/pxa3xx_nand.c | 35 +++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index d3da5ef5faa4c..54512ce254432 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -1387,34 +1387,43 @@ static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) return NAND_STATUS_READY; } -static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info) +static int pxa3xx_nand_config_ident(struct pxa3xx_nand_info *info) { struct platform_device *pdev = info->pdev; struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct pxa3xx_nand_host *host = info->host[info->cs]; - struct mtd_info *mtd = host->mtd; - struct nand_chip *chip = mtd->priv; - /* configure default flash values */ + /* Configure default flash values */ + info->chunk_size = PAGE_CHUNK_SIZE; info->reg_ndcr = 0x0; /* enable all interrupts */ info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; info->reg_ndcr |= NDCR_RD_ID_CNT(READ_ID_BYTES); - info->reg_ndcr |= NDCR_SPARE_EN; /* enable spare by default */ + info->reg_ndcr |= NDCR_SPARE_EN; + + return 0; +} + +static void pxa3xx_nand_config_tail(struct pxa3xx_nand_info *info) +{ + struct pxa3xx_nand_host *host = info->host[info->cs]; + struct mtd_info *mtd = host->mtd; + struct nand_chip *chip = mtd->priv; + info->reg_ndcr |= (host->col_addr_cycles == 2) ? NDCR_RA_START : 0; info->reg_ndcr |= (chip->page_shift == 6) ? NDCR_PG_PER_BLK : 0; info->reg_ndcr |= (mtd->writesize == 2048) ? NDCR_PAGE_SZ : 0; - - return 0; } static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) { + struct platform_device *pdev = info->pdev; + struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); uint32_t ndcr = nand_readl(info, NDCR); /* Set an initial chunk size */ info->chunk_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512; info->reg_ndcr = ndcr & ~(NDCR_INT_MASK | NDCR_ND_ARB_EN | NFCV1_NDCR_ARB_CNTL); + info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; info->ndtr0cs0 = nand_readl(info, NDTR0CS0); info->ndtr1cs0 = nand_readl(info, NDTR1CS0); return 0; @@ -1591,10 +1600,7 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) if (pdata->keep_config && !pxa3xx_nand_detect_config(info)) goto KEEP_CONFIG; - /* Set a default chunk size */ - info->chunk_size = PAGE_CHUNK_SIZE; - - ret = pxa3xx_nand_config_flash(info); + ret = pxa3xx_nand_config_ident(info); if (ret) return ret; @@ -1607,7 +1613,6 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) } KEEP_CONFIG: - info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; if (info->reg_ndcr & NDCR_DWIDTH_M) chip->options |= NAND_BUSWIDTH_16; @@ -1692,6 +1697,10 @@ KEEP_CONFIG: host->row_addr_cycles = 3; else host->row_addr_cycles = 2; + + if (!pdata->keep_config) + pxa3xx_nand_config_tail(info); + return nand_scan_tail(mtd); } -- GitLab From 154f50fbde539c20bbf74854461d932ebdace4d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ezequiel=20Garc=C3=ADa?= Date: Wed, 4 Nov 2015 13:13:43 -0300 Subject: [PATCH 0470/2855] mtd: pxa3xx_nand: Simplify pxa3xx_nand_scan This commit simplifies the initial configuration performed by pxa3xx_nand_scan. No functionality change is intended. Signed-off-by: Ezequiel Garcia Acked-by: Robert Jarzmik Signed-off-by: Brian Norris --- drivers/mtd/nand/pxa3xx_nand.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 54512ce254432..002f1cc75543a 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -1413,7 +1413,7 @@ static void pxa3xx_nand_config_tail(struct pxa3xx_nand_info *info) info->reg_ndcr |= (mtd->writesize == 2048) ? NDCR_PAGE_SZ : 0; } -static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) +static void pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) { struct platform_device *pdev = info->pdev; struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); @@ -1426,7 +1426,6 @@ static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; info->ndtr0cs0 = nand_readl(info, NDTR0CS0); info->ndtr1cs0 = nand_readl(info, NDTR1CS0); - return 0; } static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info) @@ -1597,22 +1596,21 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) int ret; uint16_t ecc_strength, ecc_step; - if (pdata->keep_config && !pxa3xx_nand_detect_config(info)) - goto KEEP_CONFIG; - - ret = pxa3xx_nand_config_ident(info); - if (ret) - return ret; - - ret = pxa3xx_nand_sensing(host); - if (ret) { - dev_info(&info->pdev->dev, "There is no chip on cs %d!\n", - info->cs); - - return ret; + if (pdata->keep_config) { + pxa3xx_nand_detect_config(info); + } else { + ret = pxa3xx_nand_config_ident(info); + if (ret) + return ret; + ret = pxa3xx_nand_sensing(host); + if (ret) { + dev_info(&info->pdev->dev, + "There is no chip on cs %d!\n", + info->cs); + return ret; + } } -KEEP_CONFIG: if (info->reg_ndcr & NDCR_DWIDTH_M) chip->options |= NAND_BUSWIDTH_16; -- GitLab From b1e485779c06d3e43a1818f1065874dd2504b5ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ezequiel=20Garc=C3=ADa?= Date: Wed, 4 Nov 2015 13:13:44 -0300 Subject: [PATCH 0471/2855] mtd: pxa3xx_nand: Remove redundant NAND sensing Currently, the driver is trying to detect the presence of a chip by issuing a RESET command before nand_scan_ident. This seems completely redundant, and is also a layering violation as nand_scan_ident is in charge of device detection. This commit removes the RESET command use, and moves the initial timing configuration to pxa3xx_nand_config_ident. Signed-off-by: Ezequiel Garcia Signed-off-by: Brian Norris --- drivers/mtd/nand/pxa3xx_nand.c | 41 +++++++--------------------------- 1 file changed, 8 insertions(+), 33 deletions(-) diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 002f1cc75543a..bf1b2ac0e425f 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -1389,8 +1389,10 @@ static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) static int pxa3xx_nand_config_ident(struct pxa3xx_nand_info *info) { + struct pxa3xx_nand_host *host = info->host[info->cs]; struct platform_device *pdev = info->pdev; struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); + const struct nand_sdr_timings *timings; /* Configure default flash values */ info->chunk_size = PAGE_CHUNK_SIZE; @@ -1399,6 +1401,12 @@ static int pxa3xx_nand_config_ident(struct pxa3xx_nand_info *info) info->reg_ndcr |= NDCR_RD_ID_CNT(READ_ID_BYTES); info->reg_ndcr |= NDCR_SPARE_EN; + /* use the common timing to make a try */ + timings = onfi_async_timing_mode_to_sdr_timings(0); + if (IS_ERR(timings)) + return PTR_ERR(timings); + + pxa3xx_nand_set_sdr_timing(host, timings); return 0; } @@ -1491,32 +1499,6 @@ static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info) kfree(info->data_buff); } -static int pxa3xx_nand_sensing(struct pxa3xx_nand_host *host) -{ - struct pxa3xx_nand_info *info = host->info_data; - struct mtd_info *mtd; - struct nand_chip *chip; - const struct nand_sdr_timings *timings; - int ret; - - mtd = info->host[info->cs]->mtd; - chip = mtd->priv; - - /* use the common timing to make a try */ - timings = onfi_async_timing_mode_to_sdr_timings(0); - if (IS_ERR(timings)) - return PTR_ERR(timings); - - pxa3xx_nand_set_sdr_timing(host, timings); - - chip->cmdfunc(mtd, NAND_CMD_RESET, 0, 0); - ret = chip->waitfunc(mtd, chip); - if (ret & NAND_STATUS_FAIL) - return -ENODEV; - - return 0; -} - static int pxa_ecc_init(struct pxa3xx_nand_info *info, struct nand_ecc_ctrl *ecc, int strength, int ecc_stepsize, int page_size) @@ -1602,13 +1584,6 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) ret = pxa3xx_nand_config_ident(info); if (ret) return ret; - ret = pxa3xx_nand_sensing(host); - if (ret) { - dev_info(&info->pdev->dev, - "There is no chip on cs %d!\n", - info->cs); - return ret; - } } if (info->reg_ndcr & NDCR_DWIDTH_M) -- GitLab From f3028c840867d2235886a6a5c97865fc9d91bafd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ezequiel=20Garc=C3=ADa?= Date: Wed, 4 Nov 2015 13:13:45 -0300 Subject: [PATCH 0472/2855] mtd: pxa3xx_nand: Remove dead code This macro is not used anymore, so it's just dead code. Remove it. Signed-off-by: Ezequiel Garcia Acked-by: Robert Jarzmik Signed-off-by: Brian Norris --- drivers/mtd/nand/pxa3xx_nand.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index bf1b2ac0e425f..2f337eaef155c 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -30,11 +30,6 @@ #include #include #include - -#if defined(CONFIG_ARM) && (defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP)) -#define ARCH_HAS_DMA -#endif - #include #define CHIP_DELAY_TIMEOUT msecs_to_jiffies(200) -- GitLab From d55d31a6b8f65bb13e1912043a66295cc928967c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ezequiel=20Garc=C3=ADa?= Date: Wed, 4 Nov 2015 13:13:46 -0300 Subject: [PATCH 0473/2855] mtd: pxa3xx_nand: Gate/ungate the NAND clock in suspend/resume paths The NAND clock can be disabled on suspend and enabled on resume. Signed-off-by: Ezequiel Garcia Acked-by: Robert Jarzmik Signed-off-by: Brian Norris --- drivers/mtd/nand/pxa3xx_nand.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 2f337eaef155c..2bb9732a42f8f 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -1936,12 +1936,18 @@ static int pxa3xx_nand_suspend(struct device *dev) return -EAGAIN; } + clk_disable(info->clk); return 0; } static int pxa3xx_nand_resume(struct device *dev) { struct pxa3xx_nand_info *info = dev_get_drvdata(dev); + int ret; + + ret = clk_enable(info->clk); + if (ret < 0) + return ret; /* We don't want to handle interrupt without calling mtd routine */ disable_int(info, NDCR_INT_MASK); -- GitLab From 2b2462d5928379b8f43ffe19d72d069bfb89d316 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 4 Nov 2015 15:21:21 -0500 Subject: [PATCH 0474/2855] mtd: sm_ftl: fix wrong do_div() usage do_div() is meant to be used with an unsigned dividend. Signed-off-by: Nicolas Pitre Signed-off-by: Brian Norris --- drivers/mtd/sm_ftl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c index c23184a47fc4e..b096f8bb05bae 100644 --- a/drivers/mtd/sm_ftl.c +++ b/drivers/mtd/sm_ftl.c @@ -206,9 +206,10 @@ static loff_t sm_mkoffset(struct sm_ftl *ftl, int zone, int block, int boffset) } /* Breaks offset into parts */ -static void sm_break_offset(struct sm_ftl *ftl, loff_t offset, +static void sm_break_offset(struct sm_ftl *ftl, loff_t loffset, int *zone, int *block, int *boffset) { + u64 offset = loffset; *boffset = do_div(offset, ftl->block_size); *block = do_div(offset, ftl->max_lba); *zone = offset >= ftl->zone_count ? -1 : offset; -- GitLab From 20625dfe0384676e3ee244091c4f09544d080798 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 30 Oct 2015 12:56:22 -0700 Subject: [PATCH 0475/2855] mtd: spi-nor: remove unnecessary leading space from dbg print As Cyrille noted [1], this line is wrong. [1] http://lists.infradead.org/pipermail/linux-mtd/2015-September/061725.html Signed-off-by: Brian Norris Cc: Cyrille Pitchen --- drivers/mtd/spi-nor/spi-nor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 12041e181630c..16c9f5522b8f9 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -856,7 +856,7 @@ static const struct flash_info *spi_nor_read_id(struct spi_nor *nor) tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN); if (tmp < 0) { - dev_dbg(nor->dev, " error %d reading JEDEC ID\n", tmp); + dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp); return ERR_PTR(tmp); } -- GitLab From aab3c3f34cc2dd8230052770712606d65de6538f Mon Sep 17 00:00:00 2001 From: Henry Chen Date: Tue, 17 Nov 2015 16:36:49 +0800 Subject: [PATCH 0476/2855] regulator: mt6311: MT6311_REGULATOR needs to select REGMAP_I2C This patch fix the below build error: drivers/regulator/mt6311-regulator.c:111: undefined reference to `__devm_regmap_init_i2c' Signed-off-by: Henry Chen Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/regulator/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 8df0b0e62976d..00676208080e6 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -446,6 +446,7 @@ config REGULATOR_MC13892 config REGULATOR_MT6311 tristate "MediaTek MT6311 PMIC" depends on I2C + select REGMAP_I2C help Say y here to select this option to enable the power regulator of MediaTek MT6311 PMIC. -- GitLab From 1b15b1f5a01019524815a9ce5c575f3b2068e7f8 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 17 Nov 2015 13:58:50 -0200 Subject: [PATCH 0477/2855] mtd: mxc_nand: Remove bit-or operation with zero Doing a bit-or operation with zero is pointless. Remove this unneeded bit-or. Signed-off-by: Fabio Estevam Signed-off-by: Brian Norris --- drivers/mtd/nand/mxc_nand.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 7922d318ebb8e..f507d361b1a6a 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -1067,8 +1067,7 @@ static void preset_v3(struct mtd_info *mtd) /* Blocks to be unlocked */ for (i = 0; i < NAND_MAX_CHIPS; i++) - writel(0x0 | (0xffff << 16), - NFC_V3_WRPROT_UNLOCK_BLK_ADD0 + (i << 2)); + writel(0xffff << 16, NFC_V3_WRPROT_UNLOCK_BLK_ADD0 + (i << 2)); writel(0, NFC_V3_IPC); -- GitLab From 3ff3f518a135fa4592fe2817e9ac2cce1fa23dc2 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 9 Nov 2015 22:20:37 -0800 Subject: [PATCH 0478/2855] regulator: Make bulk API support optional supplies Make it possible to use the bulk API with optional supplies, by allowing the consumer to marking supplies as optional in the regulator_bulk_data. Signed-off-by: Bjorn Andersson Signed-off-by: Mark Brown --- drivers/regulator/core.c | 6 ++++-- drivers/regulator/devres.c | 7 +++++-- include/linux/regulator/consumer.h | 3 +++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 73b7683355cd0..4cf1390784e54 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -3451,8 +3451,10 @@ int regulator_bulk_get(struct device *dev, int num_consumers, consumers[i].consumer = NULL; for (i = 0; i < num_consumers; i++) { - consumers[i].consumer = regulator_get(dev, - consumers[i].supply); + consumers[i].consumer = _regulator_get(dev, + consumers[i].supply, + false, + !consumers[i].optional); if (IS_ERR(consumers[i].consumer)) { ret = PTR_ERR(consumers[i].consumer); dev_err(dev, "Failed to get supply '%s': %d\n", diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c index 6ec1d400adae7..6ad8ab4c578d6 100644 --- a/drivers/regulator/devres.c +++ b/drivers/regulator/devres.c @@ -164,8 +164,11 @@ int devm_regulator_bulk_get(struct device *dev, int num_consumers, consumers[i].consumer = NULL; for (i = 0; i < num_consumers; i++) { - consumers[i].consumer = devm_regulator_get(dev, - consumers[i].supply); + consumers[i].consumer = _devm_regulator_get(dev, + consumers[i].supply, + consumers[i].optional ? + OPTIONAL_GET : + NORMAL_GET); if (IS_ERR(consumers[i].consumer)) { ret = PTR_ERR(consumers[i].consumer); dev_err(dev, "Failed to get supply '%s': %d\n", diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 9e0e76992be08..48603506f8de3 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -140,6 +140,8 @@ struct regulator; * * @supply: The name of the supply. Initialised by the user before * using the bulk regulator APIs. + * @optional: The supply should be considered optional. Initialised by the user + * before using the bulk regulator APIs. * @consumer: The regulator consumer for the supply. This will be managed * by the bulk API. * @@ -149,6 +151,7 @@ struct regulator; */ struct regulator_bulk_data { const char *supply; + bool optional; struct regulator *consumer; /* private: Internal use */ -- GitLab From 559b7d2444790415b8818d3154afba7e74f5925f Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Mon, 16 Nov 2015 20:16:45 +0530 Subject: [PATCH 0479/2855] staging: unisys: remove unused variable The variables op, sd and zmotion were never being used. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorhba/visorhba_main.c | 4 ---- drivers/staging/unisys/visorinput/visorinput.c | 4 +--- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c index c119f20dfd44b..593a48627b09d 100644 --- a/drivers/staging/unisys/visorhba/visorhba_main.c +++ b/drivers/staging/unisys/visorhba/visorhba_main.c @@ -453,7 +453,6 @@ visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, struct uiscmdrsp *cmdrsp; struct scsi_device *scsidev = scsicmd->device; int insert_location; - unsigned char op; unsigned char *cdb = scsicmd->cmnd; struct Scsi_Host *scsihost = scsidev->host; unsigned int i; @@ -511,7 +510,6 @@ visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, } cmdrsp->scsi.guest_phys_entries = scsi_sg_count(scsicmd); - op = cdb[0]; if (!visorchannel_signalinsert(devdata->dev->visorchannel, IOCHAN_TO_IOPART, cmdrsp)) { @@ -759,11 +757,9 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) struct visorhba_devdata *devdata; struct visordisk_info *vdisk; struct scsi_device *scsidev; - struct sense_data *sd; scsidev = scsicmd->device; memcpy(scsicmd->sense_buffer, cmdrsp->scsi.sensebuf, MAX_SENSE_SIZE); - sd = (struct sense_data *)scsicmd->sense_buffer; /* Do not log errors for disk-not-present inquiries */ if ((cmdrsp->scsi.cmnd[0] == INQUIRY) && diff --git a/drivers/staging/unisys/visorinput/visorinput.c b/drivers/staging/unisys/visorinput/visorinput.c index 5c16f66343688..38d4d5b884dfb 100644 --- a/drivers/staging/unisys/visorinput/visorinput.c +++ b/drivers/staging/unisys/visorinput/visorinput.c @@ -523,7 +523,7 @@ visorinput_channel_interrupt(struct visor_device *dev) struct ultra_inputreport r; int scancode, keycode; struct input_dev *visorinput_dev; - int xmotion, ymotion, zmotion, button; + int xmotion, ymotion, button; int i; struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device); @@ -604,12 +604,10 @@ visorinput_channel_interrupt(struct visor_device *dev) } break; case inputaction_wheel_rotate_away: - zmotion = r.activity.arg1; input_report_rel(visorinput_dev, REL_WHEEL, 1); input_sync(visorinput_dev); break; case inputaction_wheel_rotate_toward: - zmotion = r.activity.arg1; input_report_rel(visorinput_dev, REL_WHEEL, -1); input_sync(visorinput_dev); break; -- GitLab From 34d96c0dedbfbba50349dcc76546a86ad59a0789 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Mon, 16 Nov 2015 20:16:46 +0530 Subject: [PATCH 0480/2855] staging: unisys: return error value directly In case of error we are jumping to err_del_scsipending_ent and always returning SCSI_MLQUEUE_DEVICE_BUSY from error path. We donot need a variable to return a fixed error value, it can be returned directly. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorhba/visorhba_main.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c index 593a48627b09d..d5178b44ba8c9 100644 --- a/drivers/staging/unisys/visorhba/visorhba_main.c +++ b/drivers/staging/unisys/visorhba/visorhba_main.c @@ -460,7 +460,6 @@ visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, (struct visorhba_devdata *)scsihost->hostdata; struct scatterlist *sg = NULL; struct scatterlist *sglist = NULL; - int err = 0; if (devdata->serverdown || devdata->serverchangingstate) return SCSI_MLQUEUE_DEVICE_BUSY; @@ -495,10 +494,8 @@ visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, if (cmdrsp->scsi.bufflen > devdata->max_buff_len) devdata->max_buff_len = cmdrsp->scsi.bufflen; - if (scsi_sg_count(scsicmd) > MAX_PHYS_INFO) { - err = SCSI_MLQUEUE_DEVICE_BUSY; + if (scsi_sg_count(scsicmd) > MAX_PHYS_INFO) goto err_del_scsipending_ent; - } /* convert buffer to phys information */ /* buffer is scatterlist - copy it out */ @@ -512,16 +509,15 @@ visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, if (!visorchannel_signalinsert(devdata->dev->visorchannel, IOCHAN_TO_IOPART, - cmdrsp)) { + cmdrsp)) /* queue must be full and we aren't going to wait */ - err = SCSI_MLQUEUE_DEVICE_BUSY; goto err_del_scsipending_ent; - } + return 0; err_del_scsipending_ent: del_scsipending_ent(devdata, insert_location); - return err; + return SCSI_MLQUEUE_DEVICE_BUSY; } /** -- GitLab From 79c07e9c1f3948757c30fa630c66903da2a247ec Mon Sep 17 00:00:00 2001 From: Erik Arfvidson Date: Tue, 17 Nov 2015 13:34:48 -0500 Subject: [PATCH 0481/2855] staging: unisys: iochannel fix block comments This patch fixes warning messages from checkpatch.pl specifically: WARNING: Block comments use a trailing */ on a separate lines Signed-off-by: Erik Arfvidson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/iochannel.h | 137 +++++++++------------ 1 file changed, 59 insertions(+), 78 deletions(-) diff --git a/drivers/staging/unisys/include/iochannel.h b/drivers/staging/unisys/include/iochannel.h index 14e656ff73ecd..457fe3d464789 100644 --- a/drivers/staging/unisys/include/iochannel.h +++ b/drivers/staging/unisys/include/iochannel.h @@ -6,7 +6,8 @@ /* * Everything needed for IOPart-GuestPart communication is define in * this file. Note: Everything is OS-independent because this file is - * used by Windows, Linux and possible EFI drivers. */ + * used by Windows, Linux and possible EFI drivers. + */ /* * Communication flow between the IOPart and GuestPart uses the channel headers @@ -66,21 +67,15 @@ * IO Partition is defined below. */ -/* - * Defines and enums. - */ - +/* Defines and enums. */ #define MINNUM(a, b) (((a) < (b)) ? (a) : (b)) #define MAXNUM(a, b) (((a) > (b)) ? (a) : (b)) -/* these define the two queues per data channel between iopart and - * ioguestparts - */ -#define IOCHAN_TO_IOPART 0 /* used by ioguestpart to 'insert' signals to - * iopart */ - -#define IOCHAN_FROM_IOPART 1 /* used by ioguestpart to 'remove' signals from - * iopart - same queue as previous queue */ +/* define the two queues per data channel between iopart and ioguestparts */ +/* used by ioguestpart to 'insert' signals to iopart */ +#define IOCHAN_TO_IOPART 0 +/* used by ioguestpart to 'remove' signals from iopart, same previous queue */ +#define IOCHAN_FROM_IOPART 1 /* size of cdb - i.e., scsi cmnd */ #define MAX_CMND_SIZE 16 @@ -92,26 +87,29 @@ /* various types of network packets that can be sent in cmdrsp */ enum net_types { NET_RCV_POST = 0, /* submit buffer to hold receiving - * incoming packet */ + * incoming packet + */ /* virtnic -> uisnic */ NET_RCV, /* incoming packet received */ /* uisnic -> virtpci */ - NET_XMIT, /* for outgoing net packets */ + NET_XMIT, /* for outgoing net packets */ /* virtnic -> uisnic */ NET_XMIT_DONE, /* outgoing packet xmitted */ /* uisnic -> virtpci */ NET_RCV_ENBDIS, /* enable/disable packet reception */ /* virtnic -> uisnic */ - NET_RCV_ENBDIS_ACK, /* acknowledge enable/disable packet - * reception */ + NET_RCV_ENBDIS_ACK, /* acknowledge enable/disable packet */ + /* reception */ /* uisnic -> virtnic */ NET_RCV_PROMISC, /* enable/disable promiscuous mode */ /* virtnic -> uisnic */ NET_CONNECT_STATUS, /* indicate the loss or restoration of a network - * connection */ + * connection + */ /* uisnic -> virtnic */ NET_MACADDR, /* indicates the client has requested to update - * its MAC addr */ + * its MAC addr + */ NET_MACADDR_ACK, /* MAC address */ }; @@ -170,51 +168,43 @@ struct vhba_wwnn { } __packed; /* WARNING: Values stired in this structure must contain maximum counts (not - * maximum values). */ -struct vhba_config_max { /* 20 bytes */ - u32 max_channel; /* maximum channel for devices attached to this - * bus */ - u32 max_id; /* maximum SCSI ID for devices attached to this - * bus */ - u32 max_lun; /* maximum SCSI LUN for devices attached to this - * bus */ - u32 cmd_per_lun; /* maximum number of outstanding commands per - * lun that are allowed at one time */ - u32 max_io_size; /* maximum io size for devices attached to this - * bus */ + * maximum values). + */ +struct vhba_config_max {/* 20 bytes */ + u32 max_channel;/* maximum channel for devices attached to this bus */ + u32 max_id; /* maximum SCSI ID for devices attached to bus */ + u32 max_lun; /* maximum SCSI LUN for devices attached to bus */ + u32 cmd_per_lun;/* maximum number of outstanding commands per LUN */ + u32 max_io_size;/* maximum io size for devices attached to this bus */ /* max io size is often determined by the resource of the hba. e.g */ /* max scatter gather list length * page size / sector size */ } __packed; struct uiscmdrsp_scsi { - u64 handle; /* the handle to the cmd that was received - - * send it back as is in the rsp packet. */ + u64 handle; /* the handle to the cmd that was received */ + /* send it back as is in the rsp packet. */ u8 cmnd[MAX_CMND_SIZE]; /* the cdb for the command */ u32 bufflen; /* length of data to be transferred out or in */ - u16 guest_phys_entries; /* Number of entries in scatter-gather (sg) - * list */ + u16 guest_phys_entries; /* Number of entries in scatter-gather list */ struct guest_phys_info gpi_list[MAX_PHYS_INFO]; /* physical address * information for each - * fragment */ + * fragment + */ enum dma_data_direction data_dir; /* direction of the data, if any */ - struct uisscsi_dest vdest; /* identifies the virtual hba, id, - * channel, lun to which cmd was sent */ + struct uisscsi_dest vdest; /* identifies the virtual hba, id, */ + /* channel, lun to which cmd was sent */ - /* the following fields are needed to queue the rsp back to cmd - * originator */ - int linuxstat; /* the original Linux status - for use by linux - * vdisk code */ + /* Needed to queue the rsp back to cmd originator */ + int linuxstat; /* original Linux status used by linux vdisk */ u8 scsistat; /* the scsi status */ - u8 addlstat; /* non-scsi status - covers cases like timeout - * needed by windows guests */ + u8 addlstat; /* non-scsi status */ #define ADDL_SEL_TIMEOUT 4 /* the following fields are need to determine the result of command */ u8 sensebuf[MAX_SENSE_SIZE]; /* sense info in case cmd failed; */ /* it holds the sense_data struct; */ /* see that struct for details. */ - void *vdisk; /* contains pointer to the vdisk so that we can clean up - * when the IO completes. */ + void *vdisk; /* pointer to the vdisk to clean up when IO completes. */ int no_disk_result; /* used to return no disk inquiry result * when no_disk_result is set to 1, @@ -258,15 +248,15 @@ struct uiscmdrsp_scsi { */ #define NO_DISK_INQUIRY_RESULT_LEN 36 -#define MIN_INQUIRY_RESULT_LEN 5 /* we need at least 5 bytes minimum for inquiry - * result */ +#define MIN_INQUIRY_RESULT_LEN 5 /* 5 bytes minimum for inquiry result */ /* SCSI device version for no disk inquiry result */ #define SCSI_SPC2_VER 4 /* indicates SCSI SPC2 (SPC3 is 5) */ /* Windows and Linux want different things for a non-existent lun. So, we'll let * caller pass in the peripheral qualifier and type. - * NOTE:[4] SCSI returns (n-4); so we return length-1-4 or length-5. */ + * NOTE:[4] SCSI returns (n-4); so we return length-1-4 or length-5. + */ #define SET_NO_DISK_INQUIRY_RESULT(buf, len, lun, lun0notpresent, notpresent) \ do { \ @@ -305,9 +295,7 @@ struct uiscmdrsp_scsi { } \ } while (0) -/* - * Struct & Defines to support sense information. - */ +/* Struct & Defines to support sense information. */ /* The following struct is returned in sensebuf field in uiscmdrsp_scsi. It is * initialized in exactly the manner that is recommended in Windows (hence the @@ -342,13 +330,11 @@ struct sense_data { struct net_pkt_xmt { int len; /* full length of data in the packet */ int num_frags; /* number of fragments in frags containing data */ - struct phys_info frags[MAX_PHYS_INFO]; /* physical page information for - * each fragment */ + struct phys_info frags[MAX_PHYS_INFO]; /* physical page information */ char ethhdr[ETH_HEADER_SIZE]; /* the ethernet header */ struct { - /* these are needed for csum at uisnic end */ - u8 valid; /* 1 = rest of this struct is valid - else - * ignore */ + /* these are needed for csum at uisnic end */ + u8 valid; /* 1 = struct is valid - else ignore */ u8 hrawoffv; /* 1 = hwrafoff is valid */ u8 nhrawoffv; /* 1 = nhwrafoff is valid */ u16 protocol; /* specifies packet protocol */ @@ -385,11 +371,12 @@ struct net_pkt_xmtdone { struct net_pkt_rcvpost { /* rcv buf size must be large enough to include ethernet data len + * ethernet header len - we are choosing 2K because it is guaranteed - * to be describable */ - struct phys_info frag; /* physical page information for the - * single fragment 2K rcv buf */ - u64 unique_num; /* This is used to make sure that - * receive posts are returned to */ + * to be describable + */ + struct phys_info frag; /* physical page information for the */ + /* single fragment 2K rcv buf */ + u64 unique_num; + /* unique_num ensure that receive posts are returned to */ /* the Adapter which we sent them originally. */ } __packed; @@ -399,8 +386,7 @@ struct net_pkt_rcv { u32 rcv_done_len; /* length of received data */ u8 numrcvbufs; /* number of receive buffers that contain the */ /* incoming data; guest end MUST chain these together. */ - void *rcvbuf[MAX_NET_RCV_CHAIN]; /* the list of receive buffers - * that must be chained; */ + void *rcvbuf[MAX_NET_RCV_CHAIN]; /* list of chained rcvbufs */ /* each entry is a receive buffer provided by NET_RCV_POST. */ /* NOTE: first rcvbuf in the chain will also be provided in net.buf. */ u64 unique_num; @@ -469,18 +455,17 @@ struct uiscmdrsp_scsitaskmgmt { #define TASK_MGMT_FAILED 0 } __packed; -/* The following is used by uissd to send disk add/remove notifications to - * Guest */ +/* Used by uissd to send disk add/remove notifications to Guest */ /* Note that the vHba pointer is not used by the Client/Guest side. */ struct uiscmdrsp_disknotify { u8 add; /* 0-remove, 1-add */ - void *v_hba; /* Pointer to vhba_info for channel info to - * route msg */ + void *v_hba; /* channel info to route msg */ u32 channel, id, lun; /* SCSI Path of Disk to added or removed */ } __packed; /* The following is used by virthba/vSCSI to send the Acquire/Release commands - * to the IOVM. */ + * to the IOVM. + */ struct uiscmdrsp_vdiskmgmt { enum vdisk_mgmt_types vdisktype; @@ -533,8 +518,8 @@ struct uiscmdrsp { struct uiscmdrsp_disknotify disknotify; struct uiscmdrsp_vdiskmgmt vdiskmgmt; }; - void *private_data; /* used to send the response when the cmd is - * done (scsi & scsittaskmgmt). */ + void *private_data; /* send the response when the cmd is */ + /* done (scsi & scsittaskmgmt). */ struct uiscmdrsp *next; /* General Purpose Queue Link */ struct uiscmdrsp *activeQ_next; /* Used to track active commands */ struct uiscmdrsp *activeQ_prev; /* Used to track active commands */ @@ -564,15 +549,11 @@ struct spar_io_channel_protocol { } __packed; #define MAX_CLIENTSTRING_LEN 1024 - u8 client_string[MAX_CLIENTSTRING_LEN];/* NULL terminated - so holds - * max - 1 bytes */ + /* client_string is NULL termimated so holds max -1 bytes */ + u8 client_string[MAX_CLIENTSTRING_LEN]; } __packed; - -/* - * INLINE functions for initializing and accessing I/O data channels - */ - +/* INLINE functions for initializing and accessing I/O data channels */ #define SIZEOF_PROTOCOL (COVER(sizeof(struct spar_io_channel_protocol), 64)) #define SIZEOF_CMDRSP (COVER(sizeof(struct uiscmdrsp), 64)) -- GitLab From 71c3c5a8ef37ab21397516caca778238874dc3dd Mon Sep 17 00:00:00 2001 From: Erik Arfvidson Date: Tue, 17 Nov 2015 13:34:49 -0500 Subject: [PATCH 0482/2855] staging: unisys: iochannel.h remove redundant comments iochannel cleanup redudant comments in function declarations. Signed-off-by: Erik Arfvidson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/iochannel.h | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/staging/unisys/include/iochannel.h b/drivers/staging/unisys/include/iochannel.h index 457fe3d464789..ec04576fe20c3 100644 --- a/drivers/staging/unisys/include/iochannel.h +++ b/drivers/staging/unisys/include/iochannel.h @@ -575,18 +575,8 @@ struct spar_io_channel_protocol { * room) */ static inline u16 -add_physinfo_entries(u32 inp_pfn, /* input - specifies the pfn to be used - * to add entries */ - u16 inp_off, /* input - specifies the off to be used - * to add entries */ - u32 inp_len, /* input - specifies the len to be used - * to add entries */ - u16 index, /* input - index in array at which new - * entries are added */ - u16 max_pi_arr_entries, /* input - specifies the maximum - * entries pi_arr can hold */ - struct phys_info pi_arr[]) /* input & output - array to - * which entries are added */ +add_physinfo_entries(u32 inp_pfn, u16 inp_off, u32 inp_len, u16 index, + u16 max_pi_arr_entries, struct phys_info pi_arr[]) { u32 len; u16 i, firstlen; -- GitLab From c06a278344ad5024e44d962ce9aa2ed945f0d1cf Mon Sep 17 00:00:00 2001 From: Erik Arfvidson Date: Tue, 17 Nov 2015 13:34:50 -0500 Subject: [PATCH 0483/2855] staging: unisys: iochannel fix spacing around operators This patch fixes check warning from checkpatch.pl in the macro definition CHECK: spaces preferred around that '+' (ctx:VxV) Signed-off-by: Erik Arfvidson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/iochannel.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/unisys/include/iochannel.h b/drivers/staging/unisys/include/iochannel.h index ec04576fe20c3..36664ccc08df2 100644 --- a/drivers/staging/unisys/include/iochannel.h +++ b/drivers/staging/unisys/include/iochannel.h @@ -366,7 +366,8 @@ struct net_pkt_xmtdone { */ #define RCVPOST_BUF_SIZE 4032 #define MAX_NET_RCV_CHAIN \ - ((ETH_MAX_MTU+ETH_HEADER_SIZE + RCVPOST_BUF_SIZE-1) / RCVPOST_BUF_SIZE) + ((ETH_MAX_MTU + ETH_HEADER_SIZE + RCVPOST_BUF_SIZE - 1) \ + / RCVPOST_BUF_SIZE) struct net_pkt_rcvpost { /* rcv buf size must be large enough to include ethernet data len + -- GitLab From 0678eb1e4e0de2eaf40a28243bb9f227ae4ff49e Mon Sep 17 00:00:00 2001 From: Erik Arfvidson Date: Tue, 17 Nov 2015 13:34:51 -0500 Subject: [PATCH 0484/2855] staging: unisys: iochannel fix trailing */ Fixed last warning message from checkpatch.pl by removing the wordiness of the comment Signed-off-by: Erik Arfvidson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/iochannel.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/unisys/include/iochannel.h b/drivers/staging/unisys/include/iochannel.h index 36664ccc08df2..162ca187a66be 100644 --- a/drivers/staging/unisys/include/iochannel.h +++ b/drivers/staging/unisys/include/iochannel.h @@ -566,8 +566,7 @@ struct spar_io_channel_protocol { * pfn-off-size entires. */ -/* we deal with 4K page sizes when we it comes to passing page information - * between */ +/* use 4K page sizes when we it comes to passing page information between */ /* Guest and IOPartition. */ #define PI_PAGE_SIZE 0x1000 #define PI_PAGE_MASK 0x0FFF -- GitLab From b0bc5da143f654d39a4899c766757a22606428c0 Mon Sep 17 00:00:00 2001 From: Erik Arfvidson Date: Tue, 17 Nov 2015 13:34:52 -0500 Subject: [PATCH 0485/2855] staging: unisys: visorbus.h fix block comment This fixes last checkpatch warning: WARNING: Block comments use a trailing */ on a separate line Signed-off-by: Erik Arfvidson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/visorbus.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h index 9235536fa75f7..2a64a9ce0208f 100644 --- a/drivers/staging/unisys/include/visorbus.h +++ b/drivers/staging/unisys/include/visorbus.h @@ -140,8 +140,8 @@ struct visor_device { struct { int major, minor; void *attr; /* private use by devmajorminor_attr.c you can - * change this constant to whatever you - * want; */ + * change this constant to whatever you want + */ } devnodes[5]; /* the code will detect and behave appropriately) */ struct semaphore visordriver_callback_lock; -- GitLab From 25236bc98f955007c8174a69522c5e26e2d4f804 Mon Sep 17 00:00:00 2001 From: Erik Arfvidson Date: Tue, 17 Nov 2015 13:34:53 -0500 Subject: [PATCH 0486/2855] staging: unisys: vbushelper.h fix Block comment This patch fixes last checkpatch warning for vbushelper.h WARNING: Block comments use a trailing */ on a separate line Signed-off-by: Erik Arfvidson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/vbushelper.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/unisys/include/vbushelper.h b/drivers/staging/unisys/include/vbushelper.h index f272975b2920b..f1b6aacb79d7d 100644 --- a/drivers/staging/unisys/include/vbushelper.h +++ b/drivers/staging/unisys/include/vbushelper.h @@ -19,7 +19,8 @@ #define __VBUSHELPER_H__ /* TARGET_HOSTNAME specified as -DTARGET_HOSTNAME=\"thename\" on the - * command line */ + * command line + */ #define TARGET_HOSTNAME "linuxguest" -- GitLab From 6504e649289f24257c782aadfc419926a06b9584 Mon Sep 17 00:00:00 2001 From: Erik Arfvidson Date: Tue, 17 Nov 2015 13:34:55 -0500 Subject: [PATCH 0487/2855] staging: unisys: Fix visorchannel.c block comments This patch fixes the last checkpatch warning about: Block comments use a trailing */ on a separate line Signed-off-by: Erik Arfvidson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorchannel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/visorbus/visorchannel.c b/drivers/staging/unisys/visorbus/visorchannel.c index a4e117f101cfe..891b8db7c5ec9 100644 --- a/drivers/staging/unisys/visorbus/visorchannel.c +++ b/drivers/staging/unisys/visorbus/visorchannel.c @@ -41,8 +41,8 @@ struct visorchannel { struct channel_header chan_hdr; uuid_le guid; ulong size; - bool needs_lock; /* channel creator knows if more than one - * thread will be inserting or removing */ + bool needs_lock; /* channel creator knows if more than one */ + /* thread will be inserting or removing */ spinlock_t insert_lock; /* protect head writes in chan_hdr */ spinlock_t remove_lock; /* protect tail writes in chan_hdr */ -- GitLab From 195b57875f1563fef51be7d204ddb1dbc9e1538e Mon Sep 17 00:00:00 2001 From: Erik Arfvidson Date: Tue, 17 Nov 2015 13:34:56 -0500 Subject: [PATCH 0488/2855] staging: unisys: Fix vmcallerinterface.h block comments This patch fixes all the checkpatch Block comments use a trailing */ while keeping comments clean. Signed-off-by: Erik Arfvidson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/visorbus/vmcallinterface.h | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/drivers/staging/unisys/visorbus/vmcallinterface.h b/drivers/staging/unisys/visorbus/vmcallinterface.h index c8d8483bd4df7..c043fa41cedaf 100644 --- a/drivers/staging/unisys/visorbus/vmcallinterface.h +++ b/drivers/staging/unisys/visorbus/vmcallinterface.h @@ -43,20 +43,15 @@ enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples */ * - the 0x01 identifies it as the 1st instance of a VMCALL_VIRTPART * type of VMCALL */ - - VMCALL_IO_CONTROLVM_ADDR = 0x0501, /* used by all Guests, not just - * IO */ - VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET = 0x0708, /* Allow caller to - * query virtual time - * offset */ - VMCALL_POST_CODE_LOGEVENT = 0x070B, /* LOGEVENT Post Code (RDX) with - * specified subsystem mask (RCX - * - monitor_subsystems.h) and - * severity (RDX) */ - VMCALL_UPDATE_PHYSICAL_TIME = 0x0a02 /* Allow - * ULTRA_SERVICE_CAPABILITY_TIME - * capable guest to make - * VMCALL */ + /* used by all Guests, not just IO */ + VMCALL_IO_CONTROLVM_ADDR = 0x0501, + /* Allow caller to query virtual time offset */ + VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET = 0x0708, + /* LOGEVENT Post Code (RDX) with specified subsystem mask */ + /* (RCX - monitor_subsystems.h) and severity (RDX) */ + VMCALL_POST_CODE_LOGEVENT = 0x070B, + /* Allow ULTRA_SERVICE_CAPABILITY_TIME capable guest to make VMCALL */ + VMCALL_UPDATE_PHYSICAL_TIME = 0x0a02 }; #define VMCALL_SUCCESS 0 @@ -74,7 +69,8 @@ enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples */ unisys_extended_vmcall(method, param1, param2, param3) /* The following uses VMCALL_POST_CODE_LOGEVENT interface but is currently - * not used much */ + * not used much + */ #define ISSUE_IO_VMCALL_POSTCODE_SEVERITY(postcode, severity) \ ISSUE_IO_EXTENDED_VMCALL(VMCALL_POST_CODE_LOGEVENT, severity, \ MDS_APPOS, postcode) @@ -84,11 +80,11 @@ enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples */ /* Parameters to VMCALL_IO_CONTROLVM_ADDR interface */ struct vmcall_io_controlvm_addr_params { - /* The Guest-relative physical address of the ControlVm channel. - * This VMCall fills this in with the appropriate address. */ + /* The Guest-relative physical address of the ControlVm channel. */ + /* This VMCall fills this in with the appropriate address. */ u64 address; /* contents provided by this VMCALL (OUT) */ - /* the size of the ControlVm channel in bytes This VMCall fills this - * in with the appropriate address. */ + /* the size of the ControlVm channel in bytes This VMCall fills this */ + /* in with the appropriate address. */ u32 channel_bytes; /* contents provided by this VMCALL (OUT) */ u8 unused[4]; /* Unused Bytes in the 64-Bit Aligned Struct */ } __packed; -- GitLab From 180e2767eb3f4d608ea5a954c8052956431593cf Mon Sep 17 00:00:00 2001 From: Erik Arfvidson Date: Tue, 17 Nov 2015 13:34:57 -0500 Subject: [PATCH 0489/2855] staging: unisys: Fix channel.h Block comments This patch fixes all the checkpatch.pl block commments that use a trailing */ in channel.h Signed-off-by: Erik Arfvidson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/channel.h | 114 +++++++++++++---------- 1 file changed, 67 insertions(+), 47 deletions(-) diff --git a/drivers/staging/unisys/include/channel.h b/drivers/staging/unisys/include/channel.h index c6c24423a7f0a..5af59a5fce618 100644 --- a/drivers/staging/unisys/include/channel.h +++ b/drivers/staging/unisys/include/channel.h @@ -60,15 +60,19 @@ enum channel_clientstate { CHANNELCLI_DISABLED = 1, /* client can see channel but is NOT * allowed to use it unless given TBD * explicit request (should actually be - * < DETACHED) */ + * < DETACHED) + */ CHANNELCLI_ATTACHING = 2, /* legacy EFI client request - * for EFI server to attach */ + * for EFI server to attach + */ CHANNELCLI_ATTACHED = 3, /* idle, but client may want - * to use channel any time */ + * to use channel any time + */ CHANNELCLI_BUSY = 4, /* client either wants to use or is - * using channel */ - CHANNELCLI_OWNED = 5 /* "no worries" state - client can - * access channel anytime */ + * using channel + */ + CHANNELCLI_OWNED = 5 /* "no worries" state - client can */ + /* access channel anytime */ }; static inline const u8 * @@ -116,11 +120,13 @@ ULTRA_CHANNELCLI_STRING(u32 v) /* Values for ULTRA_CHANNEL_PROTOCOL.CliErrorBoot: */ /* throttling invalid boot channel statetransition error due to client - * disabled */ + * disabled + */ #define ULTRA_CLIERRORBOOT_THROTTLEMSG_DISABLED 0x01 /* throttling invalid boot channel statetransition error due to client - * not attached */ + * not attached + */ #define ULTRA_CLIERRORBOOT_THROTTLEMSG_NOTATTACHED 0x02 /* throttling invalid boot channel statetransition error due to busy channel */ @@ -128,24 +134,28 @@ ULTRA_CHANNELCLI_STRING(u32 v) /* Values for ULTRA_CHANNEL_PROTOCOL.CliErrorOS: */ /* throttling invalid guest OS channel statetransition error due to - * client disabled */ + * client disabled + */ #define ULTRA_CLIERROROS_THROTTLEMSG_DISABLED 0x01 /* throttling invalid guest OS channel statetransition error due to - * client not attached */ + * client not attached + */ #define ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED 0x02 /* throttling invalid guest OS channel statetransition error due to - * busy channel */ + * busy channel + */ #define ULTRA_CLIERROROS_THROTTLEMSG_BUSY 0x04 /* Values for ULTRA_CHANNEL_PROTOCOL.Features: This define exists so -* that windows guest can look at the FeatureFlags in the io channel, -* and configure the windows driver to use interrupts or not based on -* this setting. This flag is set in uislib after the -* ULTRA_VHBA_init_channel is called. All feature bits for all -* channels should be defined here. The io channel feature bits are -* defined right here */ + * that windows guest can look at the FeatureFlags in the io channel, + * and configure the windows driver to use interrupts or not based on + * this setting. This flag is set in uislib after the + * ULTRA_VHBA_init_channel is called. All feature bits for all + * channels should be defined here. The io channel feature bits are + * defined right here + */ #define ULTRA_IO_DRIVER_ENABLES_INTS (0x1ULL << 1) #define ULTRA_IO_CHANNEL_IS_POLLING (0x1ULL << 3) #define ULTRA_IO_IOVM_IS_OK_WITH_DRIVER_DISABLING_INTS (0x1ULL << 4) @@ -156,7 +166,7 @@ ULTRA_CHANNELCLI_STRING(u32 v) struct channel_header { u64 signature; /* Signature */ u32 legacy_state; /* DEPRECATED - being replaced by */ - /* / SrvState, CliStateBoot, and CliStateOS below */ + /* SrvState, CliStateBoot, and CliStateOS below */ u32 header_size; /* sizeof(struct channel_header) */ u64 size; /* Total size of this channel in bytes */ u64 features; /* Flags to modify behavior */ @@ -169,25 +179,32 @@ struct channel_header { uuid_le zone_uuid; /* Guid of Channel's zone */ u32 cli_str_offset; /* offset from channel header to * nul-terminated ClientString (0 if - * ClientString not present) */ + * ClientString not present) + */ u32 cli_state_boot; /* CHANNEL_CLIENTSTATE of pre-boot - * EFI client of this channel */ + * EFI client of this channel + */ u32 cmd_state_cli; /* CHANNEL_COMMANDSTATE (overloaded in * Windows drivers, see ServerStateUp, - * ServerStateDown, etc) */ + * ServerStateDown, etc) + */ u32 cli_state_os; /* CHANNEL_CLIENTSTATE of Guest OS - * client of this channel */ + * client of this channel + */ u32 ch_characteristic; /* CHANNEL_CHARACTERISTIC_ */ u32 cmd_state_srv; /* CHANNEL_COMMANDSTATE (overloaded in * Windows drivers, see ServerStateUp, - * ServerStateDown, etc) */ + * ServerStateDown, etc) + */ u32 srv_state; /* CHANNEL_SERVERSTATE */ u8 cli_error_boot; /* bits to indicate err states for * boot clients, so err messages can - * be throttled */ + * be throttled + */ u8 cli_error_os; /* bits to indicate err states for OS * clients, so err messages can be - * throttled */ + * throttled + */ u8 filler[1]; /* Pad out to 128 byte cacheline */ /* Please add all new single-byte values below here */ u8 recover_channel; @@ -205,29 +222,33 @@ struct signal_queue_header { u64 features; /* Flags to modify behavior */ u64 num_sent; /* Total # of signals placed in this queue */ u64 num_overflows; /* Total # of inserts failed due to - * full queue */ + * full queue + */ u32 signal_size; /* Total size of a signal for this queue */ u32 max_slots; /* Max # of slots in queue, 1 slot is - * always empty */ + * always empty + */ u32 max_signals; /* Max # of signals in queue - * (MaxSignalSlots-1) */ + * (MaxSignalSlots-1) + */ u32 head; /* Queue head signal # */ /* 2nd cache line */ u64 num_received; /* Total # of signals removed from this queue */ - u32 tail; /* Queue tail signal # (on separate - * cache line) */ + u32 tail; /* Queue tail signal */ u32 reserved1; /* Reserved field */ u64 reserved2; /* Reserved field */ u64 client_queue; u64 num_irq_received; /* Total # of Interrupts received. This - * is incremented by the ISR in the - * guest windows driver */ + * is incremented by the ISR in the + * guest windows driver + */ u64 num_empty; /* Number of times that visor_signal_remove - * is called and returned Empty - * Status. */ + * is called and returned Empty Status. + */ u32 errorflags; /* Error bits set during SignalReinit * to denote trouble with client's - * fields */ + * fields + */ u8 filler[12]; /* Pad out to 64 byte cacheline */ } __packed; @@ -272,8 +293,7 @@ spar_check_channel_client(void __iomem *ch, return 0; } } - if (expected_min_bytes > 0) { /* caller wants us to verify - * channel size */ + if (expected_min_bytes > 0) { /* verify channel size */ unsigned long long bytes = readq(&((struct channel_header __iomem *) (ch))->size); @@ -284,8 +304,7 @@ spar_check_channel_client(void __iomem *ch, return 0; } } - if (expected_version > 0) { /* caller wants us to verify - * channel version */ + if (expected_version > 0) { /* verify channel version */ unsigned long ver = readl(&((struct channel_header __iomem *) (ch))->version_id); if (ver != expected_version) { @@ -295,8 +314,7 @@ spar_check_channel_client(void __iomem *ch, return 0; } } - if (expected_signature > 0) { /* caller wants us to verify - * channel signature */ + if (expected_signature > 0) { /* verify channel signature */ unsigned long long sig = readq(&((struct channel_header __iomem *) (ch))->signature); @@ -319,8 +337,7 @@ static inline int spar_check_channel_server(uuid_le typeuuid, char *name, u64 expected_min_bytes, u64 actual_bytes) { - if (expected_min_bytes > 0) /* caller wants us to verify - * channel size */ + if (expected_min_bytes > 0) /* verify channel size */ if (actual_bytes < expected_min_bytes) { pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8llx actual=0x%-8.8llx\n", name, &typeuuid, expected_min_bytes, @@ -354,7 +371,8 @@ pathname_last_n_nodes(u8 *s, unsigned int n) if (p == s) break; /* should never happen, unless someone * is changing the string while we are - * looking at it!! */ + * looking at it!! + */ if ((*p == '/') || (*p == '\\')) n--; } @@ -395,7 +413,8 @@ spar_channel_client_acquire_os(void __iomem *ch, u8 *id) if (readl(&hdr->cli_state_os) == CHANNELCLI_OWNED) { if (readb(&hdr->cli_error_os) != 0) { /* we are in an error msg throttling state; - * come out of it */ + * come out of it + */ pr_info("%s Channel OS client acquire now successful\n", id); writeb(0, &hdr->cli_error_os); @@ -404,8 +423,9 @@ spar_channel_client_acquire_os(void __iomem *ch, u8 *id) } /* We have to do it the "hard way". We transition to BUSY, - * and can use the channel iff our competitor has not also - * transitioned to BUSY. */ + * and can use the channel iff our competitor has not also + * transitioned to BUSY. + */ if (readl(&hdr->cli_state_os) != CHANNELCLI_ATTACHED) { if ((readb(&hdr->cli_error_os) & ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED) == 0) { -- GitLab From 3d05734fff784835ce8b83b029b6affbabc6faa4 Mon Sep 17 00:00:00 2001 From: Erik Arfvidson Date: Tue, 17 Nov 2015 13:34:58 -0500 Subject: [PATCH 0490/2855] staging: unisys: Fix periodic_work.c parenthesis alignment This patch fixes checkpatch.pl message: CHECK: Alignment should match open parenthesis Signed-off-by: Erik Arfvidson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/periodic_work.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/visorbus/periodic_work.c b/drivers/staging/unisys/visorbus/periodic_work.c index 115b7aa9560a8..00b152764f84c 100644 --- a/drivers/staging/unisys/visorbus/periodic_work.c +++ b/drivers/staging/unisys/visorbus/periodic_work.c @@ -43,11 +43,12 @@ static void periodic_work_func(struct work_struct *work) (*pw->workfunc)(pw->workfuncarg); } -struct periodic_work *visor_periodic_work_create(ulong jiffy_interval, - struct workqueue_struct *workqueue, - void (*workfunc)(void *), - void *workfuncarg, - const char *devnam) +struct periodic_work +*visor_periodic_work_create(ulong jiffy_interval, + struct workqueue_struct *workqueue, + void (*workfunc)(void *), + void *workfuncarg, + const char *devnam) { struct periodic_work *pw; -- GitLab From 1c192718fbafbfd8fcc9af924861a311820d5078 Mon Sep 17 00:00:00 2001 From: Erik Arfvidson Date: Tue, 17 Nov 2015 13:34:59 -0500 Subject: [PATCH 0491/2855] staging: unisys: controlvmcompletionstatus.h fix block comments This patch fixes the checkpatch warning messages in controlvmcompletionstatus.h. All the warning messages in this file are caused by "Block comments use atrailing */ on a separate line" Signed-off-by: Erik Arfvidson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../visorbus/controlvmcompletionstatus.h | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/staging/unisys/visorbus/controlvmcompletionstatus.h b/drivers/staging/unisys/visorbus/controlvmcompletionstatus.h index 3c97ebac4f322..23ad0ea6c9fc1 100644 --- a/drivers/staging/unisys/visorbus/controlvmcompletionstatus.h +++ b/drivers/staging/unisys/visorbus/controlvmcompletionstatus.h @@ -39,7 +39,8 @@ #define CONTROLVM_RESP_ERROR_MAX_DEVICES 202 /* DEVICE_CREATE */ /* Payload and Parameter Related------------------------------------[400-499] */ #define CONTROLVM_RESP_ERROR_PAYLOAD_INVALID 400 /* SWITCH_ATTACHEXTPORT, - * DEVICE_CONFIGURE */ + * DEVICE_CONFIGURE + */ #define CONTROLVM_RESP_ERROR_INITIATOR_PARAMETER_INVALID 401 /* Multiple */ #define CONTROLVM_RESP_ERROR_TARGET_PARAMETER_INVALID 402 /* DEVICE_CONFIGURE */ #define CONTROLVM_RESP_ERROR_CLIENT_PARAMETER_INVALID 403 /* DEVICE_CONFIGURE */ @@ -48,36 +49,43 @@ * BUS_CONFIGURE, * DEVICE_CREATE, * DEVICE_CONFIG - * DEVICE_DESTROY */ + * DEVICE_DESTROY + */ #define CONTROLVM_RESP_ERROR_DEVICE_INVALID 501 /* SWITCH_ATTACHINTPORT */ /* DEVICE_CREATE, * DEVICE_CONFIGURE, - * DEVICE_DESTROY */ + * DEVICE_DESTROY + */ #define CONTROLVM_RESP_ERROR_CHANNEL_INVALID 502 /* DEVICE_CREATE, - * DEVICE_CONFIGURE */ + * DEVICE_CONFIGURE + */ /* Partition Driver Callback Interface----------------------[600-699] */ #define CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE 604 /* BUS_CREATE, * BUS_DESTROY, * DEVICE_CREATE, - * DEVICE_DESTROY */ + * DEVICE_DESTROY + */ /* Unable to invoke VIRTPCI callback */ #define CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR 605 /* BUS_CREATE, * BUS_DESTROY, * DEVICE_CREATE, - * DEVICE_DESTROY */ + * DEVICE_DESTROY + */ /* VIRTPCI Callback returned error */ #define CONTROLVM_RESP_ERROR_GENERIC_DRIVER_CALLBACK_ERROR 606 /* SWITCH_ATTACHEXTPORT, * SWITCH_DETACHEXTPORT - * DEVICE_CONFIGURE */ + * DEVICE_CONFIGURE + */ /* generic device callback returned error */ /* Bus Related------------------------------------------------------[700-799] */ #define CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED 700 /* BUS_DESTROY */ /* Channel Related--------------------------------------------------[800-899] */ #define CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN 800 /* GET_CHANNELINFO, - * DEVICE_DESTROY */ + * DEVICE_DESTROY + */ #define CONTROLVM_RESP_ERROR_CHANNEL_SIZE_TOO_SMALL 801 /* DEVICE_CREATE */ /* Chipset Shutdown Related---------------------------------------[1000-1099] */ #define CONTROLVM_RESP_ERROR_CHIPSET_SHUTDOWN_FAILED 1000 -- GitLab From e3f8f77c41ceaf899351e2085b039610038ac2b9 Mon Sep 17 00:00:00 2001 From: Erik Arfvidson Date: Tue, 17 Nov 2015 13:35:00 -0500 Subject: [PATCH 0492/2855] staging: unisys: fix vbuschannel.h comments Fixes trailling */ from vbuschannel.h and alignment issue on the same comment block Signed-off-by: Erik Arfvidson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/vbuschannel.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/staging/unisys/visorbus/vbuschannel.h b/drivers/staging/unisys/visorbus/vbuschannel.h index 80e64477e547e..90fa12e62f26c 100644 --- a/drivers/staging/unisys/visorbus/vbuschannel.h +++ b/drivers/staging/unisys/visorbus/vbuschannel.h @@ -36,10 +36,11 @@ static const uuid_le spar_vbus_channel_protocol_uuid = #define SPAR_VBUS_CHANNEL_PROTOCOL_SIGNATURE ULTRA_CHANNEL_PROTOCOL_SIGNATURE /* Must increment this whenever you insert or delete fields within this channel -* struct. Also increment whenever you change the meaning of fields within this -* channel struct so as to break pre-existing software. Note that you can -* usually add fields to the END of the channel struct withOUT needing to -* increment this. */ + * struct. Also increment whenever you change the meaning of fields within this + * channel struct so as to break pre-existing software. Note that you can + * usually add fields to the END of the channel struct withOUT needing to + * increment this. + */ #define SPAR_VBUS_CHANNEL_PROTOCOL_VERSIONID 1 #define SPAR_VBUS_CHANNEL_OK_CLIENT(ch) \ -- GitLab From fc5adbebac6ffab461492f7a415648b29b1a3b31 Mon Sep 17 00:00:00 2001 From: Wang YanQing Date: Fri, 30 Oct 2015 00:36:33 +0800 Subject: [PATCH 0493/2855] Documentation: mtd: improve nand_ecc.txt for readability and correctness This patch correct some representation errors, add a little clarification in some places, and fix indentation problems for pseudo code. It also delete one more white space for one place. Signed-off-by: Wang YanQing [Brian: a few tweaks] Signed-off-by: Brian Norris --- Documentation/mtd/nand_ecc.txt | 58 +++++++++++++++++----------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/Documentation/mtd/nand_ecc.txt b/Documentation/mtd/nand_ecc.txt index e129b2479ea8d..f8c3284bf6a7f 100644 --- a/Documentation/mtd/nand_ecc.txt +++ b/Documentation/mtd/nand_ecc.txt @@ -107,7 +107,7 @@ for (i = 0; i < 256; i++) if (i & 0x01) rp1 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp1; else - rp0 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp1; + rp0 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp0; if (i & 0x02) rp3 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp3; else @@ -127,7 +127,7 @@ for (i = 0; i < 256; i++) if (i & 0x20) rp11 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp11; else - rp10 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp10; + rp10 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp10; if (i & 0x40) rp13 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp13; else @@ -158,7 +158,7 @@ the values in any order. So instead of calculating all the bits individually, let us try to rearrange things. For the column parity this is easy. We can just xor the bytes and in the end filter out the relevant bits. This is pretty nice as it will bring -all cp calculation out of the if loop. +all cp calculation out of the for loop. Similarly we can first xor the bytes for the various rows. This leads to: @@ -271,11 +271,11 @@ to write our code in such a way that we process data in 32 bit chunks. Of course this means some modification as the row parity is byte by byte. A quick analysis: for the column parity we use the par variable. When extending to 32 bits -we can in the end easily calculate p0 and p1 from it. +we can in the end easily calculate rp0 and rp1 from it. (because par now consists of 4 bytes, contributing to rp1, rp0, rp1, rp0 -respectively) +respectively, from MSB to LSB) also rp2 and rp3 can be easily retrieved from par as rp3 covers the -first two bytes and rp2 the last two bytes. +first two MSBs and rp2 covers the last two LSBs. Note that of course now the loop is executed only 64 times (256/4). And note that care must taken wrt byte ordering. The way bytes are @@ -387,11 +387,11 @@ Analysis 2 The code (of course) works, and hurray: we are a little bit faster than the linux driver code (about 15%). But wait, don't cheer too quickly. -THere is more to be gained. +There is more to be gained. If we look at e.g. rp14 and rp15 we see that we either xor our data with rp14 or with rp15. However we also have par which goes over all data. This means there is no need to calculate rp14 as it can be calculated from -rp15 through rp14 = par ^ rp15; +rp15 through rp14 = par ^ rp15, because par = rp14 ^ rp15; (or if desired we can avoid calculating rp15 and calculate it from rp14). That is why some places refer to inverse parity. Of course the same thing holds for rp4/5, rp6/7, rp8/9, rp10/11 and rp12/13. @@ -419,12 +419,12 @@ with if (i & 0x20) rp15 ^= cur; and outside the loop added: - rp4 = par ^ rp5; - rp6 = par ^ rp7; - rp8 = par ^ rp9; - rp10 = par ^ rp11; - rp12 = par ^ rp13; - rp14 = par ^ rp15; + rp4 = par ^ rp5; + rp6 = par ^ rp7; + rp8 = par ^ rp9; + rp10 = par ^ rp11; + rp12 = par ^ rp13; + rp14 = par ^ rp15; And after that the code takes about 30% more time, although the number of statements is reduced. This is also reflected in the assembly code. @@ -524,12 +524,12 @@ THe code within the for loop was changed to: cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp6 ^= cur; cur = *bp++; tmppar ^= cur; rp6 ^= cur; - cur = *bp++; tmppar ^= cur; rp4 ^= cur; - cur = *bp++; tmppar ^= cur; rp10 ^= tmppar; + cur = *bp++; tmppar ^= cur; rp4 ^= cur; + cur = *bp++; tmppar ^= cur; rp10 ^= tmppar; - cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp6 ^= cur; rp8 ^= cur; + cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp6 ^= cur; rp8 ^= cur; cur = *bp++; tmppar ^= cur; rp6 ^= cur; rp8 ^= cur; - cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp8 ^= cur; + cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp8 ^= cur; cur = *bp++; tmppar ^= cur; rp8 ^= cur; cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp6 ^= cur; @@ -537,7 +537,7 @@ THe code within the for loop was changed to: cur = *bp++; tmppar ^= cur; rp4 ^= cur; cur = *bp++; tmppar ^= cur; - par ^= tmppar; + par ^= tmppar; if ((i & 0x1) == 0) rp12 ^= tmppar; if ((i & 0x2) == 0) rp14 ^= tmppar; } @@ -548,8 +548,8 @@ to rp12 and rp14. While making the changes I also found that I could exploit that tmppar contains the running parity for this iteration. So instead of having: -rp4 ^= cur; rp6 = cur; -I removed the rp6 = cur; statement and did rp6 ^= tmppar; on next +rp4 ^= cur; rp6 ^= cur; +I removed the rp6 ^= cur; statement and did rp6 ^= tmppar; on next statement. A similar change was done for rp8 and rp10 @@ -593,22 +593,22 @@ The new code now looks like: cur = *bp++; tmppar ^= cur; rp4_6 ^= cur; cur = *bp++; tmppar ^= cur; rp6 ^= cur; - cur = *bp++; tmppar ^= cur; rp4 ^= cur; - cur = *bp++; tmppar ^= cur; rp10 ^= tmppar; + cur = *bp++; tmppar ^= cur; rp4 ^= cur; + cur = *bp++; tmppar ^= cur; rp10 ^= tmppar; - notrp8 = tmppar; - cur = *bp++; tmppar ^= cur; rp4_6 ^= cur; + notrp8 = tmppar; + cur = *bp++; tmppar ^= cur; rp4_6 ^= cur; cur = *bp++; tmppar ^= cur; rp6 ^= cur; - cur = *bp++; tmppar ^= cur; rp4 ^= cur; + cur = *bp++; tmppar ^= cur; rp4 ^= cur; cur = *bp++; tmppar ^= cur; - rp8 = rp8 ^ tmppar ^ notrp8; + rp8 = rp8 ^ tmppar ^ notrp8; cur = *bp++; tmppar ^= cur; rp4_6 ^= cur; cur = *bp++; tmppar ^= cur; rp6 ^= cur; cur = *bp++; tmppar ^= cur; rp4 ^= cur; cur = *bp++; tmppar ^= cur; - par ^= tmppar; + par ^= tmppar; if ((i & 0x1) == 0) rp12 ^= tmppar; if ((i & 0x2) == 0) rp14 ^= tmppar; } @@ -700,7 +700,7 @@ Conclusion The gain when calculating the ecc is tremendous. Om my development hardware a speedup of a factor of 18 for ecc calculation was achieved. On a test on an embedded system with a MIPS core a factor 7 was obtained. -On a test with a Linksys NSLU2 (ARMv5TE processor) the speedup was a factor +On a test with a Linksys NSLU2 (ARMv5TE processor) the speedup was a factor 5 (big endian mode, gcc 4.1.2, -O3) For correction not much gain could be obtained (as bitflips are rare). Then again there are also much less cycles spent there. -- GitLab From fad2ba681c74f785d56a2401bb9db615843a465a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 18 Nov 2015 16:22:52 +0800 Subject: [PATCH 0494/2855] regulator: tps6105x: Convert to use regmap helper functions Since commit 7e5071199355 ("mfd: tps6105x: Use i2c regmap to access registers"), we can use regmap helper functions instead of open coded. Signed-off-by: Axel Lin Tested-by: Denis Grigoryev Signed-off-by: Mark Brown --- drivers/regulator/tps6105x-regulator.c | 95 ++++---------------------- 1 file changed, 12 insertions(+), 83 deletions(-) diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c index ddc4f10e268a0..584ef3dedca65 100644 --- a/drivers/regulator/tps6105x-regulator.c +++ b/drivers/regulator/tps6105x-regulator.c @@ -27,90 +27,12 @@ static const unsigned int tps6105x_voltages[] = { 5000000, /* There is an additional 5V */ }; -static int tps6105x_regulator_enable(struct regulator_dev *rdev) -{ - struct tps6105x *tps6105x = rdev_get_drvdata(rdev); - int ret; - - /* Activate voltage mode */ - ret = regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0, - TPS6105X_REG0_MODE_MASK, - TPS6105X_REG0_MODE_VOLTAGE << TPS6105X_REG0_MODE_SHIFT); - if (ret) - return ret; - - return 0; -} - -static int tps6105x_regulator_disable(struct regulator_dev *rdev) -{ - struct tps6105x *tps6105x = rdev_get_drvdata(rdev); - int ret; - - /* Set into shutdown mode */ - ret = regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0, - TPS6105X_REG0_MODE_MASK, - TPS6105X_REG0_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT); - if (ret) - return ret; - - return 0; -} - -static int tps6105x_regulator_is_enabled(struct regulator_dev *rdev) -{ - struct tps6105x *tps6105x = rdev_get_drvdata(rdev); - unsigned int regval; - int ret; - - ret = regmap_read(tps6105x->regmap, TPS6105X_REG_0, ®val); - if (ret) - return ret; - regval &= TPS6105X_REG0_MODE_MASK; - regval >>= TPS6105X_REG0_MODE_SHIFT; - - if (regval == TPS6105X_REG0_MODE_VOLTAGE) - return 1; - - return 0; -} - -static int tps6105x_regulator_get_voltage_sel(struct regulator_dev *rdev) -{ - struct tps6105x *tps6105x = rdev_get_drvdata(rdev); - unsigned int regval; - int ret; - - ret = regmap_read(tps6105x->regmap, TPS6105X_REG_0, ®val); - if (ret) - return ret; - - regval &= TPS6105X_REG0_VOLTAGE_MASK; - regval >>= TPS6105X_REG0_VOLTAGE_SHIFT; - return (int) regval; -} - -static int tps6105x_regulator_set_voltage_sel(struct regulator_dev *rdev, - unsigned selector) -{ - struct tps6105x *tps6105x = rdev_get_drvdata(rdev); - int ret; - - ret = regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0, - TPS6105X_REG0_VOLTAGE_MASK, - selector << TPS6105X_REG0_VOLTAGE_SHIFT); - if (ret) - return ret; - - return 0; -} - static struct regulator_ops tps6105x_regulator_ops = { - .enable = tps6105x_regulator_enable, - .disable = tps6105x_regulator_disable, - .is_enabled = tps6105x_regulator_is_enabled, - .get_voltage_sel = tps6105x_regulator_get_voltage_sel, - .set_voltage_sel = tps6105x_regulator_set_voltage_sel, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, .list_voltage = regulator_list_voltage_table, }; @@ -122,6 +44,12 @@ static const struct regulator_desc tps6105x_regulator_desc = { .owner = THIS_MODULE, .n_voltages = ARRAY_SIZE(tps6105x_voltages), .volt_table = tps6105x_voltages, + .vsel_reg = TPS6105X_REG_0, + .vsel_mask = TPS6105X_REG0_VOLTAGE_MASK, + .enable_reg = TPS6105X_REG_0, + .enable_mask = TPS6105X_REG0_MODE_MASK, + .enable_val = TPS6105X_REG0_MODE_VOLTAGE << + TPS6105X_REG0_MODE_SHIFT, }; /* @@ -144,6 +72,7 @@ static int tps6105x_regulator_probe(struct platform_device *pdev) config.dev = &tps6105x->client->dev; config.init_data = pdata->regulator_data; config.driver_data = tps6105x; + config.regmap = tps6105x->regmap; /* Register regulator with framework */ tps6105x->regulator = devm_regulator_register(&pdev->dev, -- GitLab From e747cad203f2956aad460325510f0c339fac10c4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 15 Nov 2015 12:48:33 +0100 Subject: [PATCH 0495/2855] st: Remove obsolete scsi_tape.max_pfn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Its last user was removed 10 years ago, in commit 8b05b773b6030de5 ("[SCSI] convert st to use scsi_execute_async"). Signed-off-by: Geert Uytterhoeven Reviewed-by: Ewan D. Milne Acked-by: Kai Mäkisara Signed-off-by: Martin K. Petersen --- drivers/scsi/st.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index b6486b5d86811..8c732c8de0153 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h @@ -148,8 +148,6 @@ struct scsi_tape { int tape_type; int long_timeout; /* timeout for commands known to take long time */ - unsigned long max_pfn; /* the maximum page number reachable by the HBA */ - /* Mode characteristics */ struct st_modedef modes[ST_NBR_MODES]; int current_mode; -- GitLab From 940a7f09ad645b6be7ff85b034499fcffdfe0ebc Mon Sep 17 00:00:00 2001 From: Himanshu Madhani Date: Tue, 17 Nov 2015 15:44:48 -0500 Subject: [PATCH 0496/2855] qla2xxx: Remove unavailable firmware files Remove firmware binary names for the ISPs, which are not submitted to linux-firmware. Signed-off-by: Himanshu Madhani Signed-off-by: Giridhar Malavali Reviewed-by: Julian Calaby Reviewed-by: Xose Vazquez Perez Cc: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/Kconfig | 3 --- drivers/scsi/qla2xxx/qla_os.c | 3 --- 2 files changed, 6 deletions(-) diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig index a0f732b138e4b..10aa18ba05fdc 100644 --- a/drivers/scsi/qla2xxx/Kconfig +++ b/drivers/scsi/qla2xxx/Kconfig @@ -18,9 +18,6 @@ config SCSI_QLA_FC 2322, 6322 ql2322_fw.bin 24xx, 54xx ql2400_fw.bin 25xx ql2500_fw.bin - 2031 ql2600_fw.bin - 8031 ql8300_fw.bin - 27xx ql2700_fw.bin Upon request, the driver caches the firmware image until the driver is unloaded. diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index bfa9a64c316b6..6be32fdab365b 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -5843,6 +5843,3 @@ MODULE_FIRMWARE(FW_FILE_ISP2300); MODULE_FIRMWARE(FW_FILE_ISP2322); MODULE_FIRMWARE(FW_FILE_ISP24XX); MODULE_FIRMWARE(FW_FILE_ISP25XX); -MODULE_FIRMWARE(FW_FILE_ISP2031); -MODULE_FIRMWARE(FW_FILE_ISP8031); -MODULE_FIRMWARE(FW_FILE_ISP27XX); -- GitLab From a0067db36a2f9733a2e956a44ef8145e6a809bdb Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 18 Nov 2015 15:21:32 +0100 Subject: [PATCH 0497/2855] spi: s3c64xx: pass DMA arguments in platform data The s3c64xx platform data already contains a pointer to the DMA filter function, but not to the associated data. This simplifies the code and makes it more generic by passing the data along with the filter function like we do for other drivers. Signed-off-by: Arnd Bergmann Signed-off-by: Mark Brown --- arch/arm/plat-samsung/devs.c | 19 ++++++++-------- drivers/spi/spi-s3c64xx.c | 27 ++++++----------------- include/linux/platform_data/spi-s3c64xx.h | 2 ++ 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index 82074625de5ce..4c64ece1a3081 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -1100,9 +1100,7 @@ struct platform_device s3c_device_wdt = { #ifdef CONFIG_S3C64XX_DEV_SPI0 static struct resource s3c64xx_spi0_resource[] = { [0] = DEFINE_RES_MEM(S3C_PA_SPI0, SZ_256), - [1] = DEFINE_RES_DMA(DMACH_SPI0_TX), - [2] = DEFINE_RES_DMA(DMACH_SPI0_RX), - [3] = DEFINE_RES_IRQ(IRQ_SPI0), + [1] = DEFINE_RES_IRQ(IRQ_SPI0), }; struct platform_device s3c64xx_device_spi0 = { @@ -1130,6 +1128,8 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, pd.num_cs = num_cs; pd.src_clk_nr = src_clk_nr; pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio; + pd.dma_tx = (void *)DMACH_SPI0_TX; + pd.dma_rx = (void *)DMACH_SPI0_RX; #if defined(CONFIG_PL330_DMA) pd.filter = pl330_filter; #elif defined(CONFIG_S3C64XX_PL080) @@ -1145,9 +1145,7 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, #ifdef CONFIG_S3C64XX_DEV_SPI1 static struct resource s3c64xx_spi1_resource[] = { [0] = DEFINE_RES_MEM(S3C_PA_SPI1, SZ_256), - [1] = DEFINE_RES_DMA(DMACH_SPI1_TX), - [2] = DEFINE_RES_DMA(DMACH_SPI1_RX), - [3] = DEFINE_RES_IRQ(IRQ_SPI1), + [1] = DEFINE_RES_IRQ(IRQ_SPI1), }; struct platform_device s3c64xx_device_spi1 = { @@ -1175,12 +1173,15 @@ void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, pd.num_cs = num_cs; pd.src_clk_nr = src_clk_nr; pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio; + pd.dma_tx = (void *)DMACH_SPI1_TX; + pd.dma_rx = (void *)DMACH_SPI1_RX; #if defined(CONFIG_PL330_DMA) pd.filter = pl330_filter; #elif defined(CONFIG_S3C64XX_PL080) pd.filter = pl08x_filter_id; #endif + s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1); } #endif /* CONFIG_S3C64XX_DEV_SPI1 */ @@ -1188,9 +1189,7 @@ void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, #ifdef CONFIG_S3C64XX_DEV_SPI2 static struct resource s3c64xx_spi2_resource[] = { [0] = DEFINE_RES_MEM(S3C_PA_SPI2, SZ_256), - [1] = DEFINE_RES_DMA(DMACH_SPI2_TX), - [2] = DEFINE_RES_DMA(DMACH_SPI2_RX), - [3] = DEFINE_RES_IRQ(IRQ_SPI2), + [1] = DEFINE_RES_IRQ(IRQ_SPI2), }; struct platform_device s3c64xx_device_spi2 = { @@ -1218,6 +1217,8 @@ void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, pd.num_cs = num_cs; pd.src_clk_nr = src_clk_nr; pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio; + pd.dma_tx = (void *)DMACH_SPI2_TX; + pd.dma_rx = (void *)DMACH_SPI2_RX; #if defined(CONFIG_PL330_DMA) pd.filter = pl330_filter; #elif defined(CONFIG_S3C64XX_PL080) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 8e86e7f6663a1..b954c5444cca5 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -133,7 +133,6 @@ struct s3c64xx_spi_dma_data { struct dma_chan *ch; enum dma_transfer_direction direction; - unsigned int dmach; }; /** @@ -325,7 +324,7 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) /* Acquire DMA channels */ sdd->rx_dma.ch = dma_request_slave_channel_compat(mask, filter, - (void *)(long)sdd->rx_dma.dmach, dev, "rx"); + sdd->cntrlr_info->dma_rx, dev, "rx"); if (!sdd->rx_dma.ch) { dev_err(dev, "Failed to get RX DMA channel\n"); ret = -EBUSY; @@ -334,7 +333,7 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) spi->dma_rx = sdd->rx_dma.ch; sdd->tx_dma.ch = dma_request_slave_channel_compat(mask, filter, - (void *)(long)sdd->tx_dma.dmach, dev, "tx"); + sdd->cntrlr_info->dma_tx, dev, "tx"); if (!sdd->tx_dma.ch) { dev_err(dev, "Failed to get TX DMA channel\n"); ret = -EBUSY; @@ -1028,7 +1027,6 @@ static inline struct s3c64xx_spi_port_config *s3c64xx_spi_get_port_config( static int s3c64xx_spi_probe(struct platform_device *pdev) { struct resource *mem_res; - struct resource *res; struct s3c64xx_spi_driver_data *sdd; struct s3c64xx_spi_info *sci = dev_get_platdata(&pdev->dev); struct spi_master *master; @@ -1087,20 +1085,9 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) sdd->cur_bpw = 8; - if (!sdd->pdev->dev.of_node) { - res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!res) { - dev_warn(&pdev->dev, "Unable to get SPI tx dma resource. Switching to poll mode\n"); - sdd->port_conf->quirks = S3C64XX_SPI_QUIRK_POLL; - } else - sdd->tx_dma.dmach = res->start; - - res = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (!res) { - dev_warn(&pdev->dev, "Unable to get SPI rx dma resource. Switching to poll mode\n"); - sdd->port_conf->quirks = S3C64XX_SPI_QUIRK_POLL; - } else - sdd->rx_dma.dmach = res->start; + if (!sdd->pdev->dev.of_node && (!sci->dma_tx || !sci->dma_rx)) { + dev_warn(&pdev->dev, "Unable to get SPI tx/rx DMA data. Switching to poll mode\n"); + sdd->port_conf->quirks = S3C64XX_SPI_QUIRK_POLL; } sdd->tx_dma.direction = DMA_MEM_TO_DEV; @@ -1197,9 +1184,9 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d with %d Slaves attached\n", sdd->port_id, master->num_chipselect); - dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tFIFO %dbytes\tDMA=[Rx-%d, Tx-%d]\n", + dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tFIFO %dbytes\tDMA=[Rx-%p, Tx-%p]\n", mem_res, (FIFO_LVL_MASK(sdd) >> 1) + 1, - sdd->rx_dma.dmach, sdd->tx_dma.dmach); + sci->dma_rx, sci->dma_tx); pm_runtime_mark_last_busy(&pdev->dev); pm_runtime_put_autosuspend(&pdev->dev); diff --git a/include/linux/platform_data/spi-s3c64xx.h b/include/linux/platform_data/spi-s3c64xx.h index d3889b98a1a12..fb5625bcca9a5 100644 --- a/include/linux/platform_data/spi-s3c64xx.h +++ b/include/linux/platform_data/spi-s3c64xx.h @@ -40,6 +40,8 @@ struct s3c64xx_spi_info { int num_cs; int (*cfg_gpio)(void); dma_filter_fn filter; + void *dma_tx; + void *dma_rx; }; /** -- GitLab From c98f71d1c05601cff0f302889933798020e08869 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 16 Nov 2015 10:45:30 -0800 Subject: [PATCH 0498/2855] mtd: fsl-quadspi: possible NULL dereference It is theoretically possible to probe this driver without a matching device tree, so let's guard against this. Also, use the of_device_get_match_data() helper to make this a bit simpler. Coverity complained about this one. Signed-off-by: Brian Norris Acked-by: Han xu --- drivers/mtd/spi-nor/fsl-quadspi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c index 9e7f657af6a56..54640f1eb3a13 100644 --- a/drivers/mtd/spi-nor/fsl-quadspi.c +++ b/drivers/mtd/spi-nor/fsl-quadspi.c @@ -269,7 +269,7 @@ struct fsl_qspi { struct clk *clk, *clk_en; struct device *dev; struct completion c; - struct fsl_qspi_devtype_data *devtype_data; + const struct fsl_qspi_devtype_data *devtype_data; u32 nor_size; u32 nor_num; u32 clk_rate; @@ -933,8 +933,6 @@ static int fsl_qspi_probe(struct platform_device *pdev) struct spi_nor *nor; struct mtd_info *mtd; int ret, i = 0; - const struct of_device_id *of_id = - of_match_device(fsl_qspi_dt_ids, &pdev->dev); q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL); if (!q) @@ -945,7 +943,9 @@ static int fsl_qspi_probe(struct platform_device *pdev) return -ENODEV; q->dev = dev; - q->devtype_data = (struct fsl_qspi_devtype_data *)of_id->data; + q->devtype_data = of_device_get_match_data(dev); + if (!q->devtype_data) + return -ENODEV; platform_set_drvdata(pdev, q); /* find the resources */ -- GitLab From 47284e3e0f3c427c93f8583549b6c938e8a18015 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Sun, 8 Nov 2015 12:03:23 +0100 Subject: [PATCH 0499/2855] spi: sun4i: allow transfers to set transmission speed Allow transfers to set the transmission speed rather than using the device max_speed_hz value. The SPI core makes sure that the speed_hz value is always set on the transfer. Signed-off-by: Marcus Weseloh Signed-off-by: Mark Brown --- drivers/spi/spi-sun4i.c | 8 ++++---- drivers/spi/spi-sun6i.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c index fbb0a4d74e91c..f60a6d634d61a 100644 --- a/drivers/spi/spi-sun4i.c +++ b/drivers/spi/spi-sun4i.c @@ -229,8 +229,8 @@ static int sun4i_spi_transfer_one(struct spi_master *master, /* Ensure that we have a parent clock fast enough */ mclk_rate = clk_get_rate(sspi->mclk); - if (mclk_rate < (2 * spi->max_speed_hz)) { - clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz); + if (mclk_rate < (2 * tfr->speed_hz)) { + clk_set_rate(sspi->mclk, 2 * tfr->speed_hz); mclk_rate = clk_get_rate(sspi->mclk); } @@ -248,14 +248,14 @@ static int sun4i_spi_transfer_one(struct spi_master *master, * First try CDR2, and if we can't reach the expected * frequency, fall back to CDR1. */ - div = mclk_rate / (2 * spi->max_speed_hz); + div = mclk_rate / (2 * tfr->speed_hz); if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) { if (div > 0) div--; reg = SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS; } else { - div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz); + div = ilog2(mclk_rate) - ilog2(tfr->speed_hz); reg = SUN4I_CLK_CTL_CDR1(div); } diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c index ac48f59705a87..42e2c4bd690a2 100644 --- a/drivers/spi/spi-sun6i.c +++ b/drivers/spi/spi-sun6i.c @@ -217,8 +217,8 @@ static int sun6i_spi_transfer_one(struct spi_master *master, /* Ensure that we have a parent clock fast enough */ mclk_rate = clk_get_rate(sspi->mclk); - if (mclk_rate < (2 * spi->max_speed_hz)) { - clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz); + if (mclk_rate < (2 * tfr->speed_hz)) { + clk_set_rate(sspi->mclk, 2 * tfr->speed_hz); mclk_rate = clk_get_rate(sspi->mclk); } @@ -236,14 +236,14 @@ static int sun6i_spi_transfer_one(struct spi_master *master, * First try CDR2, and if we can't reach the expected * frequency, fall back to CDR1. */ - div = mclk_rate / (2 * spi->max_speed_hz); + div = mclk_rate / (2 * tfr->speed_hz); if (div <= (SUN6I_CLK_CTL_CDR2_MASK + 1)) { if (div > 0) div--; reg = SUN6I_CLK_CTL_CDR2(div) | SUN6I_CLK_CTL_DRS; } else { - div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz); + div = ilog2(mclk_rate) - ilog2(tfr->speed_hz); reg = SUN6I_CLK_CTL_CDR1(div); } -- GitLab From 52555a5d1058eec96c6bac2928bc965b0077c60e Mon Sep 17 00:00:00 2001 From: Dragos Bogdan Date: Wed, 18 Nov 2015 12:35:34 +0200 Subject: [PATCH 0500/2855] staging:iio:ad7780: Switch to the gpio descriptor interface Use the gpiod interface for the powerdown_gpio instead of the deprecated old non-descriptor interface. The powerdown pin can be tied high, so the gpio is optional. Remove the gpio_pdrst platform_data member since the new interface is used. Signed-off-by: Dragos Bogdan Acked-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7780.c | 27 +++++++++++---------------- drivers/staging/iio/adc/ad7780.h | 1 - 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index 618b41faa289a..98b5fc492eff2 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include @@ -42,7 +42,7 @@ struct ad7780_chip_info { struct ad7780_state { const struct ad7780_chip_info *chip_info; struct regulator *reg; - int powerdown_gpio; + struct gpio_desc *powerdown_gpio; unsigned int gain; u16 int_vref_mv; @@ -77,8 +77,7 @@ static int ad7780_set_mode(struct ad_sigma_delta *sigma_delta, break; } - if (gpio_is_valid(st->powerdown_gpio)) - gpio_set_value(st->powerdown_gpio, val); + gpiod_set_value(st->powerdown_gpio, val); return 0; } @@ -205,18 +204,14 @@ static int ad7780_probe(struct spi_device *spi) indio_dev->num_channels = 1; indio_dev->info = &ad7780_info; - if (pdata && gpio_is_valid(pdata->gpio_pdrst)) { - ret = devm_gpio_request_one(&spi->dev, - pdata->gpio_pdrst, - GPIOF_OUT_INIT_LOW, - "AD7780 /PDRST"); - if (ret) { - dev_err(&spi->dev, "failed to request GPIO PDRST\n"); - goto error_disable_reg; - } - st->powerdown_gpio = pdata->gpio_pdrst; - } else { - st->powerdown_gpio = -1; + st->powerdown_gpio = devm_gpiod_get_optional(&spi->dev, + "powerdown", + GPIOD_OUT_LOW); + if (IS_ERR(st->powerdown_gpio)) { + ret = PTR_ERR(st->powerdown_gpio); + dev_err(&spi->dev, "Failed to request powerdown GPIO: %d\n", + ret); + goto error_disable_reg; } ret = ad_sd_setup_buffer_and_trigger(indio_dev); diff --git a/drivers/staging/iio/adc/ad7780.h b/drivers/staging/iio/adc/ad7780.h index 67e511c3d6f04..46f61c9e798e6 100644 --- a/drivers/staging/iio/adc/ad7780.h +++ b/drivers/staging/iio/adc/ad7780.h @@ -24,7 +24,6 @@ struct ad7780_platform_data { u16 vref_mv; - int gpio_pdrst; }; #endif /* IIO_ADC_AD7780_H_ */ -- GitLab From cef7e12585e61e2a03aea1c99331865213982f3a Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 15 Nov 2015 21:00:02 +0100 Subject: [PATCH 0501/2855] iio: adc: xilinx: constify iio_buffer_setup_ops structure The iio_buffer_setup_ops structures are never modified, so declare this one as const, like the others. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Acked-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/adc/xilinx-xadc-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c index 0370624a35db7..c2b5f10958482 100644 --- a/drivers/iio/adc/xilinx-xadc-core.c +++ b/drivers/iio/adc/xilinx-xadc-core.c @@ -803,7 +803,7 @@ err: return ret; } -static struct iio_buffer_setup_ops xadc_buffer_ops = { +static const struct iio_buffer_setup_ops xadc_buffer_ops = { .preenable = &xadc_preenable, .postenable = &iio_triggered_buffer_postenable, .predisable = &iio_triggered_buffer_predisable, -- GitLab From d618baf94c62eb63b5b7f6159fb6aee5550a2e10 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 16 Nov 2015 16:56:13 -0800 Subject: [PATCH 0502/2855] mtd: brcmnand: clean up flash cache for parameter pages The read_byte() handling for accessing the flash cache has some awkward swapping being done in the read_byte() function. Let's just make this a byte array, and do the swapping with the word-level macros during the initial buffer copy. This is just a refactoring patch, with no (intended) functional change. Signed-off-by: Brian Norris Cc: Clay McClure Cc: Ray Jui Cc: Scott Branden Cc: Tested-by: Clay McClure --- drivers/mtd/nand/brcmnand/brcmnand.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index 2a437c7ed1759..0f43bc95ece41 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -134,7 +134,7 @@ struct brcmnand_controller { dma_addr_t dma_pa; /* in-memory cache of the FLASH_CACHE, used only for some commands */ - u32 flash_cache[FC_WORDS]; + u8 flash_cache[FC_BYTES]; /* Controller revision details */ const u16 *reg_offsets; @@ -1188,6 +1188,8 @@ static void brcmnand_cmdfunc(struct mtd_info *mtd, unsigned command, if (native_cmd == CMD_PARAMETER_READ || native_cmd == CMD_PARAMETER_CHANGE_COL) { + /* Copy flash cache word-wise */ + u32 *flash_cache = (u32 *)ctrl->flash_cache; int i; brcmnand_soc_data_bus_prepare(ctrl->soc); @@ -1197,7 +1199,11 @@ static void brcmnand_cmdfunc(struct mtd_info *mtd, unsigned command, * SECTOR_SIZE_1K may invalidate it */ for (i = 0; i < FC_WORDS; i++) - ctrl->flash_cache[i] = brcmnand_read_fc(ctrl, i); + /* + * Flash cache is big endian for parameter pages, at + * least on STB SoCs + */ + flash_cache[i] = be32_to_cpu(brcmnand_read_fc(ctrl, i)); brcmnand_soc_data_bus_unprepare(ctrl->soc); @@ -1250,8 +1256,7 @@ static uint8_t brcmnand_read_byte(struct mtd_info *mtd) if (host->last_byte > 0 && offs == 0) chip->cmdfunc(mtd, NAND_CMD_RNDOUT, addr, -1); - ret = ctrl->flash_cache[offs >> 2] >> - (24 - ((offs & 0x03) << 3)); + ret = ctrl->flash_cache[offs]; break; case NAND_CMD_GET_FEATURES: if (host->last_byte >= ONFI_SUBFEATURE_PARAM_LEN) { -- GitLab From 064f462632c2294f9b7fb51a7697392fedeea12e Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 16 Nov 2015 17:04:08 -0800 Subject: [PATCH 0503/2855] mtd: brcmnand: drop unused subpage_read() support AFAIR this driver was never tested with subpage read support, and this code is currently unused because we don't set the NAND_SUBPAGE_READ flag. It can be resurrected if someone tests it properly. Signed-off-by: Brian Norris Tested-by: Ray Jui --- drivers/mtd/nand/brcmnand/brcmnand.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index 0f43bc95ece41..626a80eb76a1d 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -1551,16 +1551,6 @@ static int brcmnand_read_oob_raw(struct mtd_info *mtd, struct nand_chip *chip, return 0; } -static int brcmnand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, - uint32_t data_offs, uint32_t readlen, - uint8_t *bufpoi, int page) -{ - struct brcmnand_host *host = chip->priv; - - return brcmnand_read(mtd, chip, host->last_addr + data_offs, - readlen >> FC_SHIFT, (u32 *)bufpoi, NULL); -} - static int brcmnand_write(struct mtd_info *mtd, struct nand_chip *chip, u64 addr, const u32 *buf, u8 *oob) { @@ -1949,7 +1939,6 @@ static int brcmnand_init_cs(struct brcmnand_host *host) chip->ecc.mode = NAND_ECC_HW; chip->ecc.read_page = brcmnand_read_page; - chip->ecc.read_subpage = brcmnand_read_subpage; chip->ecc.write_page = brcmnand_write_page; chip->ecc.read_page_raw = brcmnand_read_page_raw; chip->ecc.write_page_raw = brcmnand_write_page_raw; -- GitLab From d8aaccda7144df1c3d35251313197aed4cbea7bc Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Wed, 11 Nov 2015 09:49:37 -0500 Subject: [PATCH 0504/2855] HID: sony: Refactor the output report sending functions Refactor the output report sending functions to allow for the sending of output reports without enqueuing a work item. Output reports for any device can now be sent via the send_output_report function pointer in the sony_sc struct which points to the appropriate output function. The individual state worker functions have been replaced with a universal sony_state_worker function which uses this function pointer. Signed-off-by: Frank Praznik Signed-off-by: Jiri Kosina --- drivers/hid/hid-sony.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 774cd22105665..4ba904b02bc26 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -1028,6 +1028,7 @@ struct sony_sc { struct led_classdev *leds[MAX_LEDS]; unsigned long quirks; struct work_struct state_worker; + void(*send_output_report)(struct sony_sc*); struct power_supply *battery; struct power_supply_desc battery_desc; int device_id; @@ -1789,7 +1790,7 @@ error_leds: return ret; } -static void sixaxis_state_worker(struct work_struct *work) +static void sixaxis_send_output_report(struct sony_sc *sc) { static const union sixaxis_output_report_01 default_report = { .buf = { @@ -1803,7 +1804,6 @@ static void sixaxis_state_worker(struct work_struct *work) 0x00, 0x00, 0x00, 0x00, 0x00 } }; - struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); struct sixaxis_output_report *report = (struct sixaxis_output_report *)sc->output_report_dmabuf; int n; @@ -1846,9 +1846,8 @@ static void sixaxis_state_worker(struct work_struct *work) HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); } -static void dualshock4_state_worker(struct work_struct *work) +static void dualshock4_send_output_report(struct sony_sc *sc) { - struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); struct hid_device *hdev = sc->hdev; __u8 *buf = sc->output_report_dmabuf; int offset; @@ -1893,9 +1892,8 @@ static void dualshock4_state_worker(struct work_struct *work) HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); } -static void motion_state_worker(struct work_struct *work) +static void motion_send_output_report(struct sony_sc *sc) { - struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); struct hid_device *hdev = sc->hdev; struct motion_output_report_02 *report = (struct motion_output_report_02 *)sc->output_report_dmabuf; @@ -1914,6 +1912,12 @@ static void motion_state_worker(struct work_struct *work) hid_hw_output_report(hdev, (__u8 *)report, MOTION_REPORT_0x02_SIZE); } +static void sony_state_worker(struct work_struct *work) +{ + struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); + sc->send_output_report(sc); +} + static int sony_allocate_output_report(struct sony_sc *sc) { if ((sc->quirks & SIXAXIS_CONTROLLER) || @@ -2241,11 +2245,13 @@ static void sony_release_device_id(struct sony_sc *sc) } } -static inline void sony_init_work(struct sony_sc *sc, - void (*worker)(struct work_struct *)) +static inline void sony_init_output_report(struct sony_sc *sc, + void(*send_output_report)(struct sony_sc*)) { + sc->send_output_report = send_output_report; + if (!sc->worker_initialized) - INIT_WORK(&sc->state_worker, worker); + INIT_WORK(&sc->state_worker, sony_state_worker); sc->worker_initialized = 1; } @@ -2319,7 +2325,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID; ret = sixaxis_set_operational_usb(hdev); - sony_init_work(sc, sixaxis_state_worker); + sony_init_output_report(sc, sixaxis_send_output_report); } else if ((sc->quirks & SIXAXIS_CONTROLLER_BT) || (sc->quirks & NAVIGATION_CONTROLLER_BT)) { /* @@ -2328,7 +2334,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) */ hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; ret = sixaxis_set_operational_bt(hdev); - sony_init_work(sc, sixaxis_state_worker); + sony_init_output_report(sc, sixaxis_send_output_report); } else if (sc->quirks & DUALSHOCK4_CONTROLLER) { if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) { /* @@ -2343,9 +2349,9 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) } } - sony_init_work(sc, dualshock4_state_worker); + sony_init_output_report(sc, dualshock4_send_output_report); } else if (sc->quirks & MOTION_CONTROLLER) { - sony_init_work(sc, motion_state_worker); + sony_init_output_report(sc, motion_send_output_report); } else { ret = 0; } -- GitLab From decd946c99f6b3826bda0bfd5d1b2ddd56ef6b54 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Wed, 11 Nov 2015 09:49:38 -0500 Subject: [PATCH 0505/2855] HID: sony: Save and restore the controller state on suspend and resume On hardware which provides standby power for charging devices the state of the LEDs and force-feedback on controllers can persist even when the system is in standby. Additionally, the state of the controllers on resume may be different from the state they were in at the time when they were suspended (ie. LEDs are cleared on resume). This implements the suspend and resume callbacks which saves and clears the state of the LEDs on suspend and restores them on resume. Force-feedback is stopped on suspend but not automatically restored on resume until a new event is received to avoid potentially damaging hardware. USB Sixaxis and navigation controllers must be reinitialized when the hardware is reset on resume or they won't send any input reports. Signed-off-by: Frank Praznik Signed-off-by: Jiri Kosina --- drivers/hid/hid-sony.c | 65 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 4ba904b02bc26..1041c44765e17 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -1045,6 +1045,7 @@ struct sony_sc { __u8 battery_charging; __u8 battery_capacity; __u8 led_state[MAX_LEDS]; + __u8 resume_led_state[MAX_LEDS]; __u8 led_delay_on[MAX_LEDS]; __u8 led_delay_off[MAX_LEDS]; __u8 led_count; @@ -1912,6 +1913,12 @@ static void motion_send_output_report(struct sony_sc *sc) hid_hw_output_report(hdev, (__u8 *)report, MOTION_REPORT_0x02_SIZE); } +static inline void sony_send_output_report(struct sony_sc *sc) +{ + if (sc->send_output_report) + sc->send_output_report(sc); +} + static void sony_state_worker(struct work_struct *work) { struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); @@ -2427,6 +2434,56 @@ static void sony_remove(struct hid_device *hdev) hid_hw_stop(hdev); } +#ifdef CONFIG_PM + +static int sony_suspend(struct hid_device *hdev, pm_message_t message) +{ + /* + * On suspend save the current LED state, + * stop running force-feedback and blank the LEDS. + */ + if (SONY_LED_SUPPORT || SONY_FF_SUPPORT) { + struct sony_sc *sc = hid_get_drvdata(hdev); + +#ifdef CONFIG_SONY_FF + sc->left = sc->right = 0; +#endif + + memcpy(sc->resume_led_state, sc->led_state, + sizeof(sc->resume_led_state)); + memset(sc->led_state, 0, sizeof(sc->led_state)); + + sony_send_output_report(sc); + } + + return 0; +} + +static int sony_resume(struct hid_device *hdev) +{ + /* Restore the state of controller LEDs on resume */ + if (SONY_LED_SUPPORT) { + struct sony_sc *sc = hid_get_drvdata(hdev); + + memcpy(sc->led_state, sc->resume_led_state, + sizeof(sc->led_state)); + + /* + * The Sixaxis and navigation controllers on USB need to be + * reinitialized on resume or they won't behave properly. + */ + if ((sc->quirks & SIXAXIS_CONTROLLER_USB) || + (sc->quirks & NAVIGATION_CONTROLLER_USB)) + sixaxis_set_operational_usb(sc->hdev); + + sony_set_leds(sc); + } + + return 0; +} + +#endif + static const struct hid_device_id sony_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), .driver_data = SIXAXIS_CONTROLLER_USB }, @@ -2476,7 +2533,13 @@ static struct hid_driver sony_driver = { .probe = sony_probe, .remove = sony_remove, .report_fixup = sony_report_fixup, - .raw_event = sony_raw_event + .raw_event = sony_raw_event, + +#ifdef CONFIG_PM + .suspend = sony_suspend, + .resume = sony_resume, + .reset_resume = sony_resume, +#endif }; static int __init sony_init(void) -- GitLab From b71b5578a84d297954e4812ba0ca2d466e61cf42 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Fri, 6 Nov 2015 15:35:53 -0500 Subject: [PATCH 0506/2855] HID: sony: Remove the size check for the Dualshock 4 HID Descriptor Sony has modified the HID descriptor in new revisions of the Dualshock 4 which causes the size check in the descriptor replacement function to fail. Remove it so that new revisions of the controller will work correctly. The module is completely replacing the descriptor instead of patching it, so the size check isn't really necessary anyways. Signed-off-by: Frank Praznik Signed-off-by: Jiri Kosina --- drivers/hid/hid-sony.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 1041c44765e17..876ea2b853555 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -1139,11 +1139,11 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, * the gyroscope values to corresponding axes so we need a * modified one. */ - if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && *rsize == 467) { + if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n"); rdesc = dualshock4_usb_rdesc; *rsize = sizeof(dualshock4_usb_rdesc); - } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && *rsize == 357) { + } else if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) { hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n"); rdesc = dualshock4_bt_rdesc; *rsize = sizeof(dualshock4_bt_rdesc); -- GitLab From 6cf2e31bea1445ae50644d4d359786f43eb10afc Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 19 Nov 2015 12:58:14 +0900 Subject: [PATCH 0507/2855] HID: Drop owner assignment from i2c_driver i2c_driver does not need to set an owner because i2c_register_driver() will set it. Signed-off-by: Krzysztof Kozlowski Acked-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/i2c-hid/i2c-hid.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 10bd8e6e4c9c8..55d8f9d256965 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -1184,7 +1184,6 @@ MODULE_DEVICE_TABLE(i2c, i2c_hid_id_table); static struct i2c_driver i2c_hid_driver = { .driver = { .name = "i2c_hid", - .owner = THIS_MODULE, .pm = &i2c_hid_pm, .acpi_match_table = ACPI_PTR(i2c_hid_acpi_match), .of_match_table = of_match_ptr(i2c_hid_of_match), -- GitLab From 27ba1d56e1e150294802f0dca8368abc51a664fb Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 6 Nov 2015 18:00:30 +0100 Subject: [PATCH 0508/2855] HID: wacom: Delete an unnecessary check before kobject_put() The kobject_put() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Jiri Kosina --- drivers/hid/wacom_sys.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index e06af5b9f59e8..c7a3b79d563e3 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1353,8 +1353,7 @@ static void wacom_clean_inputs(struct wacom *wacom) else input_free_device(wacom->wacom_wac.pad_input); } - if (wacom->remote_dir) - kobject_put(wacom->remote_dir); + kobject_put(wacom->remote_dir); wacom->wacom_wac.pen_input = NULL; wacom->wacom_wac.touch_input = NULL; wacom->wacom_wac.pad_input = NULL; -- GitLab From beca365565d8f8912dce67567f54ad4c71734843 Mon Sep 17 00:00:00 2001 From: Pascal Huerst Date: Thu, 19 Nov 2015 16:18:28 +0100 Subject: [PATCH 0509/2855] spi: omap2-mcspi: Add calls for pinctrl state select This adds calls to pinctrl subsystem in order to switch pin states on suspend/resume if you provide a "sleep" state in DT. If no "sleep" state is provided in DT, these calls turn to NOPs. Signed-off-by: Pascal Huerst Signed-off-by: Mark Brown --- drivers/spi/spi-omap2-mcspi.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 1f8903d356e55..02aa1d0607b3f 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -1536,14 +1537,23 @@ static int omap2_mcspi_resume(struct device *dev) } pm_runtime_mark_last_busy(mcspi->dev); pm_runtime_put_autosuspend(mcspi->dev); - return 0; + + return pinctrl_pm_select_default_state(dev); +} + +static int omap2_mcspi_suspend(struct device *dev) +{ + return pinctrl_pm_select_sleep_state(dev); } + #else +#define omap2_mcspi_suspend NULL #define omap2_mcspi_resume NULL #endif static const struct dev_pm_ops omap2_mcspi_pm_ops = { .resume = omap2_mcspi_resume, + .suspend = omap2_mcspi_suspend, .runtime_resume = omap_mcspi_runtime_resume, }; -- GitLab From 1d8d8b5c852b6c7ae860ddc647ebb3ed3493c9a8 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 16 Nov 2015 14:37:34 +0100 Subject: [PATCH 0510/2855] mtd: nand: fix drivers abusing mtd->priv The ->priv field of the mtd_info object attached to a nand_chip device should point to the nand_chip device. The pxa and cafe drivers are assigning this field their own private structure, which works fine as long as the nand_chip field is the first one in the driver private struct but seems a bit fragile. Fix that by setting mtd->priv to point the nand_chip field and assigning chip->priv to the private structure head. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/cafe_nand.c | 34 ++++++++++++++++++++++------------ drivers/mtd/nand/pxa3xx_nand.c | 30 +++++++++++++++++++----------- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 9de78d2a2eb18..cce3ac4939b6d 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c @@ -101,7 +101,8 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; static int cafe_device_ready(struct mtd_info *mtd) { - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; int result = !!(cafe_readl(cafe, NAND_STATUS) & 0x40000000); uint32_t irqs = cafe_readl(cafe, NAND_IRQ); @@ -117,7 +118,8 @@ static int cafe_device_ready(struct mtd_info *mtd) static void cafe_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; if (usedma) memcpy(cafe->dmabuf + cafe->datalen, buf, len); @@ -132,7 +134,8 @@ static void cafe_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) static void cafe_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; if (usedma) memcpy(buf, cafe->dmabuf + cafe->datalen, len); @@ -146,7 +149,8 @@ static void cafe_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static uint8_t cafe_read_byte(struct mtd_info *mtd) { - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; uint8_t d; cafe_read_buf(mtd, &d, 1); @@ -158,7 +162,8 @@ static uint8_t cafe_read_byte(struct mtd_info *mtd) static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command, int column, int page_addr) { - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; int adrbytes = 0; uint32_t ctl1; uint32_t doneint = 0x80000000; @@ -313,7 +318,8 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command, static void cafe_select_chip(struct mtd_info *mtd, int chipnr) { - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr); @@ -328,7 +334,8 @@ static void cafe_select_chip(struct mtd_info *mtd, int chipnr) static irqreturn_t cafe_nand_interrupt(int irq, void *id) { struct mtd_info *mtd = id; - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; uint32_t irqs = cafe_readl(cafe, NAND_IRQ); cafe_writel(cafe, irqs & ~0x90000000, NAND_IRQ); if (!irqs) @@ -377,7 +384,7 @@ static int cafe_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - struct cafe_priv *cafe = mtd->priv; + struct cafe_priv *cafe = chip->priv; unsigned int max_bitflips = 0; cafe_dev_dbg(&cafe->pdev->dev, "ECC result %08x SYN1,2 %08x\n", @@ -519,7 +526,7 @@ static int cafe_nand_write_page_lowlevel(struct mtd_info *mtd, const uint8_t *buf, int oob_required, int page) { - struct cafe_priv *cafe = mtd->priv; + struct cafe_priv *cafe = chip->priv; chip->write_buf(mtd, buf, mtd->writesize); chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); @@ -604,7 +611,8 @@ static int cafe_nand_probe(struct pci_dev *pdev, cafe = (void *)(&mtd[1]); mtd->dev.parent = &pdev->dev; - mtd->priv = cafe; + mtd->priv = &cafe->nand; + cafe->nand.priv = cafe; cafe->pdev = pdev; cafe->mmio = pci_iomap(pdev, 0, 0); @@ -792,7 +800,8 @@ static int cafe_nand_probe(struct pci_dev *pdev, static void cafe_nand_remove(struct pci_dev *pdev) { struct mtd_info *mtd = pci_get_drvdata(pdev); - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; /* Disable NAND IRQ in global IRQ mask register */ cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK); @@ -819,7 +828,8 @@ static int cafe_nand_resume(struct pci_dev *pdev) { uint32_t ctrl; struct mtd_info *mtd = pci_get_drvdata(pdev); - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; /* Start off by resetting the NAND controller completely */ cafe_writel(cafe, 1, NAND_RESET); diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 2bb9732a42f8f..bdbc2c231ceb2 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -1113,7 +1113,8 @@ static int prepare_set_command(struct pxa3xx_nand_info *info, int command, static void nand_cmdfunc(struct mtd_info *mtd, unsigned command, int column, int page_addr) { - struct pxa3xx_nand_host *host = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct pxa3xx_nand_host *host = chip->priv; struct pxa3xx_nand_info *info = host->info_data; int exec_cmd; @@ -1161,7 +1162,8 @@ static void nand_cmdfunc_extended(struct mtd_info *mtd, const unsigned command, int column, int page_addr) { - struct pxa3xx_nand_host *host = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct pxa3xx_nand_host *host = chip->priv; struct pxa3xx_nand_info *info = host->info_data; int exec_cmd, ext_cmd_type; @@ -1281,7 +1283,7 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - struct pxa3xx_nand_host *host = mtd->priv; + struct pxa3xx_nand_host *host = chip->priv; struct pxa3xx_nand_info *info = host->info_data; chip->read_buf(mtd, buf, mtd->writesize); @@ -1307,7 +1309,8 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) { - struct pxa3xx_nand_host *host = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct pxa3xx_nand_host *host = chip->priv; struct pxa3xx_nand_info *info = host->info_data; char retval = 0xFF; @@ -1320,7 +1323,8 @@ static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) static u16 pxa3xx_nand_read_word(struct mtd_info *mtd) { - struct pxa3xx_nand_host *host = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct pxa3xx_nand_host *host = chip->priv; struct pxa3xx_nand_info *info = host->info_data; u16 retval = 0xFFFF; @@ -1333,7 +1337,8 @@ static u16 pxa3xx_nand_read_word(struct mtd_info *mtd) static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { - struct pxa3xx_nand_host *host = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct pxa3xx_nand_host *host = chip->priv; struct pxa3xx_nand_info *info = host->info_data; int real_len = min_t(size_t, len, info->buf_count - info->buf_start); @@ -1344,7 +1349,8 @@ static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static void pxa3xx_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct pxa3xx_nand_host *host = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct pxa3xx_nand_host *host = chip->priv; struct pxa3xx_nand_info *info = host->info_data; int real_len = min_t(size_t, len, info->buf_count - info->buf_start); @@ -1359,7 +1365,8 @@ static void pxa3xx_nand_select_chip(struct mtd_info *mtd, int chip) static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) { - struct pxa3xx_nand_host *host = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct pxa3xx_nand_host *host = chip->priv; struct pxa3xx_nand_info *info = host->info_data; if (info->need_wait) { @@ -1565,11 +1572,11 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info, static int pxa3xx_nand_scan(struct mtd_info *mtd) { - struct pxa3xx_nand_host *host = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct pxa3xx_nand_host *host = chip->priv; struct pxa3xx_nand_info *info = host->info_data; struct platform_device *pdev = info->pdev; struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct nand_chip *chip = mtd->priv; int ret; uint16_t ecc_strength, ecc_step; @@ -1701,11 +1708,12 @@ static int alloc_nand_resource(struct platform_device *pdev) host->mtd = mtd; host->cs = cs; host->info_data = info; - mtd->priv = host; + mtd->priv = chip; mtd->dev.parent = &pdev->dev; /* FIXME: all chips use the same device tree partitions */ nand_set_flash_node(chip, np); + chip->priv = host; chip->ecc.read_page = pxa3xx_nand_read_page_hwecc; chip->ecc.write_page = pxa3xx_nand_write_page_hwecc; chip->controller = &info->controller; -- GitLab From 9eba47ddd8fee8a21f45e6e1d707103f040d90c7 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 16 Nov 2015 14:37:35 +0100 Subject: [PATCH 0511/2855] mtd: nand: add an mtd_to_nand() helper Some drivers are retrieving the nand_chip pointer using the container_of macro on a struct wrapping both the nand_chip and the mtd_info struct while the standard way of retrieving this pointer is through mtd->priv. Provide an helper to do that. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 5a9d1d4c2487f..a4839b3f27da0 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -719,6 +719,11 @@ struct nand_chip { void *priv; }; +static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd) +{ + return mtd->priv; +} + /* * NAND Flash Manufacturer ID Codes */ -- GitLab From 1e6460abf739310fe695bafac30c2be39d18c8f9 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 16 Nov 2015 14:37:36 +0100 Subject: [PATCH 0512/2855] doc: mtd: nand: update examples to use mtd_to_nand() mtd_to_nand() has been introduced to hide accesses to mtd->priv. All NAND controller drivers should use it instead of directly accessing the ->priv field. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- Documentation/DocBook/mtdnand.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl index 7da8f0402af50..403a7abfc2bca 100644 --- a/Documentation/DocBook/mtdnand.tmpl +++ b/Documentation/DocBook/mtdnand.tmpl @@ -235,7 +235,7 @@ static void board_hwcontrol(struct mtd_info *mtd, int cmd) static void board_hwcontrol(struct mtd_info *mtd, int cmd) { - struct nand_chip *this = (struct nand_chip *) mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); switch(cmd){ case NAND_CTL_SETCLE: this->IO_ADDR_W |= CLE_ADRR_BIT; break; case NAND_CTL_CLRCLE: this->IO_ADDR_W &= ~CLE_ADRR_BIT; break; @@ -399,7 +399,7 @@ static void board_select_chip (struct mtd_info *mtd, int chip) static void board_select_chip (struct mtd_info *mtd, int chip) { - struct nand_chip *this = (struct nand_chip *) mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); /* Deselect all chips */ this->IO_ADDR_R &= ~BOARD_NAND_ADDR_MASK; -- GitLab From c67cbb839da9cc2757eabfa128556db6a2baf160 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 10 Nov 2015 12:15:27 -0800 Subject: [PATCH 0513/2855] mtd: spi-nor: provide default erase_sector implementation Some spi-nor drivers perform sector erase by duplicating their write_reg() command. Let's not require that the driver fill this out, and provide a default instead. Tested on m25p80.c and Medatek's MT8173 SPI NOR flash driver. Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/spi-nor.c | 37 +++++++++++++++++++++++++++++++---- include/linux/mtd/spi-nor.h | 3 ++- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 16c9f5522b8f9..a38ec01a1e06d 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -38,6 +38,7 @@ #define CHIP_ERASE_2MB_READY_WAIT_JIFFIES (40UL * HZ) #define SPI_NOR_MAX_ID_LEN 6 +#define SPI_NOR_MAX_ADDR_WIDTH 4 struct flash_info { char *name; @@ -312,6 +313,29 @@ static void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops) mutex_unlock(&nor->lock); } +/* + * Initiate the erasure of a single sector + */ +static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr) +{ + u8 buf[SPI_NOR_MAX_ADDR_WIDTH]; + int i; + + if (nor->erase) + return nor->erase(nor, addr); + + /* + * Default implementation, if driver doesn't have a specialized HW + * control + */ + for (i = nor->addr_width - 1; i >= 0; i--) { + buf[i] = addr & 0xff; + addr >>= 8; + } + + return nor->write_reg(nor, nor->erase_opcode, buf, nor->addr_width); +} + /* * Erase an address range on the nor chip. The address range may extend * one or more erase sectors. Return an error is there is a problem erasing. @@ -371,10 +395,9 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) while (len) { write_enable(nor); - if (nor->erase(nor, addr)) { - ret = -EIO; + ret = spi_nor_erase_sector(nor, addr); + if (ret) goto erase_err; - } addr += mtd->erasesize; len -= mtd->erasesize; @@ -1138,7 +1161,7 @@ static int set_quad_mode(struct spi_nor *nor, const struct flash_info *info) static int spi_nor_check(struct spi_nor *nor) { if (!nor->dev || !nor->read || !nor->write || - !nor->read_reg || !nor->write_reg || !nor->erase) { + !nor->read_reg || !nor->write_reg) { pr_err("spi-nor: please fill all the necessary fields!\n"); return -EINVAL; } @@ -1340,6 +1363,12 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) nor->addr_width = 3; } + if (nor->addr_width > SPI_NOR_MAX_ADDR_WIDTH) { + dev_err(dev, "address width is too large: %u\n", + nor->addr_width); + return -EINVAL; + } + nor->read_dummy = spi_nor_read_dummy_cycles(nor); dev_info(dev, "%s (%lld Kbytes)\n", info->name, diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 955f268d159a1..7bed97471e537 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -143,7 +143,8 @@ struct mtd_info; * @read: [DRIVER-SPECIFIC] read data from the SPI NOR * @write: [DRIVER-SPECIFIC] write data to the SPI NOR * @erase: [DRIVER-SPECIFIC] erase a sector of the SPI NOR - * at the offset @offs + * at the offset @offs; if not provided by the driver, + * spi-nor will send the erase opcode via write_reg() * @flash_lock: [FLASH-SPECIFIC] lock a region of the SPI NOR * @flash_unlock: [FLASH-SPECIFIC] unlock a region of the SPI NOR * @flash_is_locked: [FLASH-SPECIFIC] check if a region of the SPI NOR is -- GitLab From cd78ea02dc82eb26be8c2fc1cf05adbf94ea8727 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 10 Nov 2015 12:15:28 -0800 Subject: [PATCH 0514/2855] mtd: m25p80: drop erase() callback Just use the spi-nor default instead. Signed-off-by: Brian Norris --- drivers/mtd/devices/m25p80.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index f002a8f753744..6077c4aa89856 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -152,22 +152,6 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len, return 0; } -static int m25p80_erase(struct spi_nor *nor, loff_t offset) -{ - struct m25p *flash = nor->priv; - - dev_dbg(nor->dev, "%dKiB at 0x%08x\n", - flash->spi_nor.mtd.erasesize / 1024, (u32)offset); - - /* Set up command buffer. */ - flash->command[0] = nor->erase_opcode; - m25p_addr2cmd(nor, offset, flash->command); - - spi_write(flash->spi, flash->command, m25p_cmdsz(nor)); - - return 0; -} - /* * board specific setup should have ensured the SPI clock used here * matches what the READ command supports, at least until this driver @@ -193,7 +177,6 @@ static int m25p_probe(struct spi_device *spi) /* install the hooks */ nor->read = m25p80_read; nor->write = m25p80_write; - nor->erase = m25p80_erase; nor->write_reg = m25p80_write_reg; nor->read_reg = m25p80_read_reg; -- GitLab From 0501f2e5ff28a02295e42fc9e7164a20ef4c30d5 Mon Sep 17 00:00:00 2001 From: Andreas Fenkart Date: Thu, 5 Nov 2015 10:04:23 +0100 Subject: [PATCH 0515/2855] mtd: spi-nor: mx25l3205d/mx25l6405d: append SECT_4K according datasheet both chips can erase 4kByte sectors individually Signed-off-by: Andreas Fenkart Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/spi-nor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index a38ec01a1e06d..b7c038c75684b 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -738,9 +738,9 @@ static const struct flash_info spi_nor_ids[] = { { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, - { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) }, + { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) }, { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) }, - { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) }, + { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) }, { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) }, { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, -- GitLab From 54f32fd5dff96a903f838de1efcdfb9831c5b207 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 19 Nov 2015 08:19:31 -0800 Subject: [PATCH 0516/2855] HID: Make report_descriptor available for all devices Currently the sysfs report_descriptor attribute is only available if the device is claimed. We have the descriptor before we even create the device node, so just instantiate report_descriptor statically. Signed-off-by: Andy Lutomirski Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index c6f7a694f67a1..d5ddb75736919 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1691,11 +1691,6 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) hid_warn(hdev, "can't create sysfs country code attribute err: %d\n", ret); - ret = device_create_bin_file(&hdev->dev, &dev_bin_attr_report_desc); - if (ret) - hid_warn(hdev, - "can't create sysfs report descriptor attribute err: %d\n", ret); - hid_info(hdev, "%s: %s HID v%x.%02x %s [%s] on %s\n", buf, bus, hdev->version >> 8, hdev->version & 0xff, type, hdev->name, hdev->phys); @@ -1707,7 +1702,6 @@ EXPORT_SYMBOL_GPL(hid_connect); void hid_disconnect(struct hid_device *hdev) { device_remove_file(&hdev->dev, &dev_attr_country); - device_remove_bin_file(&hdev->dev, &dev_bin_attr_report_desc); if (hdev->claimed & HID_CLAIMED_INPUT) hidinput_disconnect(hdev); if (hdev->claimed & HID_CLAIMED_HIDDEV) @@ -2236,7 +2230,15 @@ static struct attribute *hid_dev_attrs[] = { &dev_attr_modalias.attr, NULL, }; -ATTRIBUTE_GROUPS(hid_dev); +static struct bin_attribute *hid_dev_bin_attrs[] = { + &dev_bin_attr_report_desc, + NULL +}; +static const struct attribute_group hid_dev_group = { + .attrs = hid_dev_attrs, + .bin_attrs = hid_dev_bin_attrs, +}; +__ATTRIBUTE_GROUPS(hid_dev); static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) { -- GitLab From de57732da86288cae9a84bd6ce7cf1d1e21f8329 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 16 Nov 2015 14:34:50 -0800 Subject: [PATCH 0517/2855] mtd: m25p80: fix module autoloading for "jedec, spi-nor" and "spi-nor" Commit 43163022927b ("mtd: m25p80: allow arbitrary OF matching for "jedec,spi-nor"") moved the "jedec,spi-nor" handling from the spi_device_id table to the of_match_table, to better handle matching complex device tree compatible strings. With that patch, device tree support works as expected when m25p80.c is built into the kernel. However, that commit ignored the fact that: (1) (non-DT) platform devices might want to use the "spi-nor" string for matching with this driver, rather than picking an arbitrary one like "m25p80" (2) the core SPI uevent/modalias code doesn't yet support kernel module autoloading via of_match_table strings; so for DT-based devices, it will only report (part of) the first compatible string used Problem (1) has been reported previously, and I forgot to patch it up afterward. Problem (2) was noticed recently here: http://lists.infradead.org/pipermail/linux-mtd/2015-October/062369.html https://lkml.org/lkml/2015/11/12/574 Specifically, this patch fixes m25p80.ko module autoloading for cases like this: flash@xxx { compatible = "jedec,spi-nor"; ... }; because modalias of "spi:spi-nor" (the only module loading info provided by the SPI core for this device) will now be listed as an alias in m25p80.ko. Notably, it does *not* help cases like this: flash@xxx { compatible = "vendor,shiny-new-device", "jedec,spi-nor"; ... }; unless we also list "shiny-new-device" in m25p_ids[]. There has been discussion on future work for this issue here: https://lkml.org/lkml/2015/11/12/574 Cc: Heiner Kallweit Signed-off-by: Brian Norris Reviewed-by: Javier Martinez Canillas --- drivers/mtd/devices/m25p80.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 6077c4aa89856..1275357c99b90 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -163,7 +163,7 @@ static int m25p_probe(struct spi_device *spi) struct m25p *flash; struct spi_nor *nor; enum read_mode mode = SPI_NOR_NORMAL; - char *flash_name = NULL; + char *flash_name; int ret; data = dev_get_platdata(&spi->dev); @@ -202,6 +202,8 @@ static int m25p_probe(struct spi_device *spi) */ if (data && data->type) flash_name = data->type; + else if (!strcmp(spi->modalias, "spi-nor")) + flash_name = NULL; /* auto-detect */ else flash_name = spi->modalias; @@ -235,6 +237,13 @@ static int m25p_remove(struct spi_device *spi) * keep them available as module aliases for existing platforms. */ static const struct spi_device_id m25p_ids[] = { + /* + * Allow non-DT platform devices to bind to the "spi-nor" modalias, and + * hack around the fact that the SPI core does not provide uevent + * matching for .of_match_table + */ + {"spi-nor"}, + /* * Entries not used in DTs that should be safe to drop after replacing * them with "nor-jedec" in platform data. -- GitLab From c1711b297f6e2270c1cb17de512985ef500e0de9 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 16 Nov 2015 14:34:51 -0800 Subject: [PATCH 0518/2855] mtd: m25p80: replace leftover "nor-jedec" with "spi-nor" in comments I overlooked a few comments in commit 8947e396a829 ("Documentation: dt: mtd: replace "nor-jedec" binding with "jedec, spi-nor""). Fix these up now. Suggested-by: Javier Martinez Canillas Signed-off-by: Brian Norris Reviewed-by: Javier Martinez Canillas --- drivers/mtd/devices/m25p80.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 1275357c99b90..c9c3b7fa30511 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -246,13 +246,13 @@ static const struct spi_device_id m25p_ids[] = { /* * Entries not used in DTs that should be safe to drop after replacing - * them with "nor-jedec" in platform data. + * them with "spi-nor" in platform data. */ {"s25sl064a"}, {"w25x16"}, {"m25p10"}, {"m25px64"}, /* - * Entries that were used in DTs without "nor-jedec" fallback and should - * be kept for backward compatibility. + * Entries that were used in DTs without "jedec,spi-nor" fallback and + * should be kept for backward compatibility. */ {"at25df321a"}, {"at25df641"}, {"at26df081a"}, {"mr25h256"}, -- GitLab From 1d158315c13b6989f7ddb1d8d334965d14d958d8 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 16 Nov 2015 14:34:52 -0800 Subject: [PATCH 0519/2855] doc: dt: mtd: stop referring to driver code for spi-nor IDs Pull the supported chip names from drivers/mtd/devices/m25p80.c and stop pointing readers to Linux code. Also (although I see this habit repeated throughout the Documentation/devicetree/bindings/ tree), stop using the title "driver" in this file, when we're trying explicitly to describe hardware, not software. Signed-off-by: Brian Norris Cc: Acked-by: Rob Herring Reviewed-by: Javier Martinez Canillas --- .../devicetree/bindings/mtd/jedec,spi-nor.txt | 56 +++++++++++++++++-- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt index 2bee68103b011..2c91c03e7eb02 100644 --- a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt +++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt @@ -1,15 +1,61 @@ -* MTD SPI driver for ST M25Pxx (and similar) serial flash chips +* SPI NOR flash: ST M25Pxx (and similar) serial flash chips Required properties: - #address-cells, #size-cells : Must be present if the device has sub-nodes representing partitions. - compatible : May include a device-specific string consisting of the - manufacturer and name of the chip. Bear in mind the DT binding - is not Linux-only, but in case of Linux, see the "m25p_ids" - table in drivers/mtd/devices/m25p80.c for the list of supported - chips. + manufacturer and name of the chip. A list of supported chip + names follows. Must also include "jedec,spi-nor" for any SPI NOR flash that can be identified by the JEDEC READ ID opcode (0x9F). + + Supported chip names: + at25df321a + at25df641 + at26df081a + mr25h256 + mx25l4005a + mx25l1606e + mx25l6405d + mx25l12805d + mx25l25635e + n25q064 + n25q128a11 + n25q128a13 + n25q512a + s25fl256s1 + s25fl512s + s25sl12801 + s25fl008k + s25fl064k + sst25vf040b + m25p40 + m25p80 + m25p16 + m25p32 + m25p64 + m25p128 + w25x80 + w25x32 + w25q32 + w25q32dw + w25q80bl + w25q128 + w25q256 + + The following chip names have been used historically to + designate quirky versions of flash chips that do not support the + JEDEC READ ID opcode (0x9F): + m25p05-nonjedec + m25p10-nonjedec + m25p20-nonjedec + m25p40-nonjedec + m25p80-nonjedec + m25p16-nonjedec + m25p32-nonjedec + m25p64-nonjedec + m25p128-nonjedec + - reg : Chip-Select number - spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at -- GitLab From a85994d5467a8fbcecc4ae4a42f9d4c1a0a54886 Mon Sep 17 00:00:00 2001 From: Othmar Pasteka Date: Mon, 16 Nov 2015 23:29:44 +0100 Subject: [PATCH 0520/2855] staging: vt6656: remove address from GPL text Cleanup errors from checkpatch.pl. Signed-off-by: Othmar Pasteka Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/baseband.c | 4 ---- drivers/staging/vt6656/baseband.h | 4 ---- drivers/staging/vt6656/card.c | 3 --- drivers/staging/vt6656/card.h | 3 --- drivers/staging/vt6656/channel.c | 4 ---- drivers/staging/vt6656/channel.h | 4 ---- drivers/staging/vt6656/desc.h | 3 --- drivers/staging/vt6656/device.h | 3 --- drivers/staging/vt6656/dpc.c | 3 --- drivers/staging/vt6656/dpc.h | 3 --- drivers/staging/vt6656/firmware.c | 4 ---- drivers/staging/vt6656/firmware.h | 4 ---- drivers/staging/vt6656/int.c | 4 ---- drivers/staging/vt6656/int.h | 4 ---- drivers/staging/vt6656/key.c | 4 ---- drivers/staging/vt6656/key.h | 4 ---- drivers/staging/vt6656/mac.c | 4 ---- drivers/staging/vt6656/mac.h | 4 ---- drivers/staging/vt6656/main_usb.c | 3 --- drivers/staging/vt6656/power.c | 4 ---- drivers/staging/vt6656/power.h | 3 --- drivers/staging/vt6656/rf.c | 4 ---- drivers/staging/vt6656/rf.h | 4 ---- drivers/staging/vt6656/rxtx.c | 3 --- drivers/staging/vt6656/rxtx.h | 3 --- drivers/staging/vt6656/usbpipe.c | 4 ---- drivers/staging/vt6656/usbpipe.h | 4 ---- drivers/staging/vt6656/wcmd.c | 3 --- drivers/staging/vt6656/wcmd.h | 3 --- 29 files changed, 104 deletions(-) diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c index e5be261f2e69c..9417c935fc303 100644 --- a/drivers/staging/vt6656/baseband.c +++ b/drivers/staging/vt6656/baseband.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * * File: baseband.c * diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h index 771ea40541742..807a5809b5d90 100644 --- a/drivers/staging/vt6656/baseband.h +++ b/drivers/staging/vt6656/baseband.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * * File: baseband.h * diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c index 927243ebcb564..a382fc6aa9d3a 100644 --- a/drivers/staging/vt6656/card.c +++ b/drivers/staging/vt6656/card.c @@ -12,9 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * File: card.c * Purpose: Provide functions to setup NIC operation mode diff --git a/drivers/staging/vt6656/card.h b/drivers/staging/vt6656/card.h index 03fc1678896bd..c2cde7e92c8f9 100644 --- a/drivers/staging/vt6656/card.h +++ b/drivers/staging/vt6656/card.h @@ -12,9 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * File: card.h * diff --git a/drivers/staging/vt6656/channel.c b/drivers/staging/vt6656/channel.c index 8412d0532fb26..a0fe288c13228 100644 --- a/drivers/staging/vt6656/channel.c +++ b/drivers/staging/vt6656/channel.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * * File: channel.c * diff --git a/drivers/staging/vt6656/channel.h b/drivers/staging/vt6656/channel.h index 21c080803714b..fcea6995fe261 100644 --- a/drivers/staging/vt6656/channel.h +++ b/drivers/staging/vt6656/channel.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * * File: channel.h * diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h index f79af8513ff29..59e3071021bde 100644 --- a/drivers/staging/vt6656/desc.h +++ b/drivers/staging/vt6656/desc.h @@ -12,9 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * File: desc.h * diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index dec36f296f3d0..76b5f4127f959 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -12,9 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * File: device.h * diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index e6367ed3b0bb8..6019aac8bdd59 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -12,9 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * File: dpc.c * diff --git a/drivers/staging/vt6656/dpc.h b/drivers/staging/vt6656/dpc.h index 95e0e83a487e6..5a92bd86cee2f 100644 --- a/drivers/staging/vt6656/dpc.h +++ b/drivers/staging/vt6656/dpc.h @@ -12,9 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * File: dpc.h * diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c index d440f284bf189..1b48f9c86f63b 100644 --- a/drivers/staging/vt6656/firmware.c +++ b/drivers/staging/vt6656/firmware.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * * File: baseband.c * diff --git a/drivers/staging/vt6656/firmware.h b/drivers/staging/vt6656/firmware.h index d594dbe1c1474..e2b54acb8fdb0 100644 --- a/drivers/staging/vt6656/firmware.h +++ b/drivers/staging/vt6656/firmware.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * * File: firmware.h * diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c index 14b8ebc6508d6..8d05acbc0e238 100644 --- a/drivers/staging/vt6656/int.c +++ b/drivers/staging/vt6656/int.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * * File: int.c * diff --git a/drivers/staging/vt6656/int.h b/drivers/staging/vt6656/int.h index 154605c639478..97e55bacbb7cb 100644 --- a/drivers/staging/vt6656/int.h +++ b/drivers/staging/vt6656/int.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * * File: int.h * diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index 1898fef1519cb..0246a8fc47fe5 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * * File: key.c * diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index 3cb1291055ed4..7861faf5138f6 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * * File: key.h * diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c index 5dfac05b9cf17..eeed16e9124ed 100644 --- a/drivers/staging/vt6656/mac.c +++ b/drivers/staging/vt6656/mac.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * * File: mac.c * diff --git a/drivers/staging/vt6656/mac.h b/drivers/staging/vt6656/mac.h index d53fcef87b4aa..4c6e610f1bc1f 100644 --- a/drivers/staging/vt6656/mac.h +++ b/drivers/staging/vt6656/mac.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * * File: mac.h * diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 01e642db311e5..ee8d1e1a24c25 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -12,9 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * File: main_usb.c * diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index 13afce27951c9..c025dab0f62ce 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * * File: power.c * diff --git a/drivers/staging/vt6656/power.h b/drivers/staging/vt6656/power.h index 7696b714850c9..9d1ebb695f9d2 100644 --- a/drivers/staging/vt6656/power.h +++ b/drivers/staging/vt6656/power.h @@ -12,9 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * File: power.h * diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index c4286ccac3203..816206c92f572 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * * File: rf.c * diff --git a/drivers/staging/vt6656/rf.h b/drivers/staging/vt6656/rf.h index 3acdc65b1e56a..c3d4f06d65f44 100644 --- a/drivers/staging/vt6656/rf.h +++ b/drivers/staging/vt6656/rf.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * * File: rf.h * diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index efb54f53b4f9e..a0c69b697901d 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -12,9 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * File: rxtx.c * diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h index 90b34ab2f6ce0..4a79c404275b2 100644 --- a/drivers/staging/vt6656/rxtx.h +++ b/drivers/staging/vt6656/rxtx.h @@ -12,9 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * File: rxtx.h * diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index c975c3b870938..351a99f3d6841 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * * File: usbpipe.c * diff --git a/drivers/staging/vt6656/usbpipe.h b/drivers/staging/vt6656/usbpipe.h index e74aa08099283..8bafd9aee1fad 100644 --- a/drivers/staging/vt6656/usbpipe.h +++ b/drivers/staging/vt6656/usbpipe.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * * File: usbpipe.h * diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index 3cbf4791bac17..4846a898d39bc 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -12,9 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * File: wcmd.c * diff --git a/drivers/staging/vt6656/wcmd.h b/drivers/staging/vt6656/wcmd.h index 2b0ee285eb0b5..764c09ccd42df 100644 --- a/drivers/staging/vt6656/wcmd.h +++ b/drivers/staging/vt6656/wcmd.h @@ -12,9 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * File: wcmd.h * -- GitLab From b629a6f63d5d7a8aab1b57223e4353427824c6d7 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Sun, 8 Nov 2015 01:42:03 +0530 Subject: [PATCH 0521/2855] staging: rdma: amso1100: Remove unnecessary variables Remove unnecessary variable 'err' from functions c2_reject() and c2_service_destroy() since it can be replaced by a single line of code instead. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/amso1100/c2_provider.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/staging/rdma/amso1100/c2_provider.c b/drivers/staging/rdma/amso1100/c2_provider.c index c707e45887c25..a092ac743c723 100644 --- a/drivers/staging/rdma/amso1100/c2_provider.c +++ b/drivers/staging/rdma/amso1100/c2_provider.c @@ -620,12 +620,9 @@ static int c2_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param) static int c2_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len) { - int err; - pr_debug("%s:%u\n", __func__, __LINE__); - err = c2_llp_reject(cm_id, pdata, pdata_len); - return err; + return c2_llp_reject(cm_id, pdata, pdata_len); } static int c2_service_create(struct iw_cm_id *cm_id, int backlog) @@ -642,12 +639,9 @@ static int c2_service_create(struct iw_cm_id *cm_id, int backlog) static int c2_service_destroy(struct iw_cm_id *cm_id) { - int err; pr_debug("%s:%u\n", __func__, __LINE__); - err = c2_llp_service_destroy(cm_id); - - return err; + return c2_llp_service_destroy(cm_id); } static int c2_pseudo_up(struct net_device *netdev) -- GitLab From 8b3e676b0cb9444f8de18b54dee1ccb51f152460 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Sun, 8 Nov 2015 22:17:52 +0800 Subject: [PATCH 0522/2855] staging: rdma: use kmalloc_array instead of kmalloc Use kmalloc_array instead of kmalloc to allocate memory for an array. Signed-off-by: Geliang Tang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/amso1100/c2.c | 6 ++++-- drivers/staging/rdma/ipath/ipath_file_ops.c | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rdma/amso1100/c2.c b/drivers/staging/rdma/amso1100/c2.c index af043f023c7d0..b46ebd1ae15a7 100644 --- a/drivers/staging/rdma/amso1100/c2.c +++ b/drivers/staging/rdma/amso1100/c2.c @@ -111,7 +111,8 @@ static int c2_tx_ring_alloc(struct c2_ring *tx_ring, void *vaddr, struct c2_element *elem; int i; - tx_ring->start = kmalloc(sizeof(*elem) * tx_ring->count, GFP_KERNEL); + tx_ring->start = kmalloc_array(tx_ring->count, sizeof(*elem), + GFP_KERNEL); if (!tx_ring->start) return -ENOMEM; @@ -160,7 +161,8 @@ static int c2_rx_ring_alloc(struct c2_ring *rx_ring, void *vaddr, struct c2_element *elem; int i; - rx_ring->start = kmalloc(sizeof(*elem) * rx_ring->count, GFP_KERNEL); + rx_ring->start = kmalloc_array(rx_ring->count, sizeof(*elem), + GFP_KERNEL); if (!rx_ring->start) return -ENOMEM; diff --git a/drivers/staging/rdma/ipath/ipath_file_ops.c b/drivers/staging/rdma/ipath/ipath_file_ops.c index 13c3cd11ab92a..6187b848b3ca5 100644 --- a/drivers/staging/rdma/ipath/ipath_file_ops.c +++ b/drivers/staging/rdma/ipath/ipath_file_ops.c @@ -917,15 +917,15 @@ static int ipath_create_user_egr(struct ipath_portdata *pd) chunk = pd->port_rcvegrbuf_chunks; egrperchunk = pd->port_rcvegrbufs_perchunk; size = pd->port_rcvegrbuf_size; - pd->port_rcvegrbuf = kmalloc(chunk * sizeof(pd->port_rcvegrbuf[0]), - GFP_KERNEL); + pd->port_rcvegrbuf = kmalloc_array(chunk, sizeof(pd->port_rcvegrbuf[0]), + GFP_KERNEL); if (!pd->port_rcvegrbuf) { ret = -ENOMEM; goto bail; } pd->port_rcvegrbuf_phys = - kmalloc(chunk * sizeof(pd->port_rcvegrbuf_phys[0]), - GFP_KERNEL); + kmalloc_array(chunk, sizeof(pd->port_rcvegrbuf_phys[0]), + GFP_KERNEL); if (!pd->port_rcvegrbuf_phys) { ret = -ENOMEM; goto bail_rcvegrbuf; -- GitLab From c2f3ffb08593d8cf587ee0e4c40197b5eb68bd38 Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Mon, 9 Nov 2015 19:13:57 -0500 Subject: [PATCH 0523/2855] staging/rdma/hfi1: move hfi1_migrate_qp Move hfi1_migrate_qp from ruc.c to qp.[hc] in prep for modifying the QP workqueue. Signed-off-by: Mike Marciniszyn Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/qp.c | 20 ++++++++++++++++++++ drivers/staging/rdma/hfi1/qp.h | 2 ++ drivers/staging/rdma/hfi1/ruc.c | 20 -------------------- drivers/staging/rdma/hfi1/verbs.h | 2 -- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/staging/rdma/hfi1/qp.c b/drivers/staging/rdma/hfi1/qp.c index f8c36166962f3..a2bbf0b8316c7 100644 --- a/drivers/staging/rdma/hfi1/qp.c +++ b/drivers/staging/rdma/hfi1/qp.c @@ -1685,3 +1685,23 @@ void qp_comm_est(struct hfi1_qp *qp) qp->ibqp.event_handler(&ev, qp->ibqp.qp_context); } } + +/* + * Switch to alternate path. + * The QP s_lock should be held and interrupts disabled. + */ +void hfi1_migrate_qp(struct hfi1_qp *qp) +{ + struct ib_event ev; + + qp->s_mig_state = IB_MIG_MIGRATED; + qp->remote_ah_attr = qp->alt_ah_attr; + qp->port_num = qp->alt_ah_attr.port_num; + qp->s_pkey_index = qp->s_alt_pkey_index; + qp->s_flags |= HFI1_S_AHG_CLEAR; + + ev.device = qp->ibqp.device; + ev.element.qp = &qp->ibqp; + ev.event = IB_EVENT_PATH_MIG; + qp->ibqp.event_handler(&ev, qp->ibqp.qp_context); +} diff --git a/drivers/staging/rdma/hfi1/qp.h b/drivers/staging/rdma/hfi1/qp.h index b9c1575990aa3..bacfa9c5e8a89 100644 --- a/drivers/staging/rdma/hfi1/qp.h +++ b/drivers/staging/rdma/hfi1/qp.h @@ -247,4 +247,6 @@ void qp_iter_print(struct seq_file *s, struct qp_iter *iter); */ void qp_comm_est(struct hfi1_qp *qp); +void hfi1_migrate_qp(struct hfi1_qp *qp); + #endif /* _QP_H */ diff --git a/drivers/staging/rdma/hfi1/ruc.c b/drivers/staging/rdma/hfi1/ruc.c index 49bc9fd7a51ae..cf8ac617552fd 100644 --- a/drivers/staging/rdma/hfi1/ruc.c +++ b/drivers/staging/rdma/hfi1/ruc.c @@ -241,26 +241,6 @@ bail: return ret; } -/* - * Switch to alternate path. - * The QP s_lock should be held and interrupts disabled. - */ -void hfi1_migrate_qp(struct hfi1_qp *qp) -{ - struct ib_event ev; - - qp->s_mig_state = IB_MIG_MIGRATED; - qp->remote_ah_attr = qp->alt_ah_attr; - qp->port_num = qp->alt_ah_attr.port_num; - qp->s_pkey_index = qp->s_alt_pkey_index; - qp->s_flags |= HFI1_S_AHG_CLEAR; - - ev.device = qp->ibqp.device; - ev.element.qp = &qp->ibqp; - ev.event = IB_EVENT_PATH_MIG; - qp->ibqp.event_handler(&ev, qp->ibqp.qp_context); -} - static __be64 get_sguid(struct hfi1_ibport *ibp, unsigned index) { if (!index) { diff --git a/drivers/staging/rdma/hfi1/verbs.h b/drivers/staging/rdma/hfi1/verbs.h index 041ad07ee699a..fa938fba8786c 100644 --- a/drivers/staging/rdma/hfi1/verbs.h +++ b/drivers/staging/rdma/hfi1/verbs.h @@ -1069,8 +1069,6 @@ int hfi1_mmap(struct ib_ucontext *context, struct vm_area_struct *vma); int hfi1_get_rwqe(struct hfi1_qp *qp, int wr_id_only); -void hfi1_migrate_qp(struct hfi1_qp *qp); - int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct hfi1_ib_header *hdr, int has_grh, struct hfi1_qp *qp, u32 bth0); -- GitLab From 0a226edd203f1209e4ee6e07a6b41a9cfd8beeb8 Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Mon, 9 Nov 2015 19:13:58 -0500 Subject: [PATCH 0524/2855] staging/rdma/hfi1: Use parallel workqueue for SDMA engines The workqueue is currently single threaded per port which for a small number of SDMA engines is ok. For hfi1, the there are up to 16 SDMA engines that can be fed descriptors in parallel. Use alloc_workqueue with a workqueue limit of the number of sdma engines and with WQ_CPU_INTENSIVE and WQ_HIGHPRI specified. Then change send to use the new scheduler which no longer needs to get the s_lock Reviewed-by: Dennis Dalessandro Signed-off-by: Mike Marciniszyn Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 1 + drivers/staging/rdma/hfi1/init.c | 13 +++++------ drivers/staging/rdma/hfi1/iowait.h | 6 +++-- drivers/staging/rdma/hfi1/qp.h | 35 ++++++++++++++++++++++++++++++ drivers/staging/rdma/hfi1/sdma.c | 8 ++++--- drivers/staging/rdma/hfi1/sdma.h | 8 ++++--- drivers/staging/rdma/hfi1/verbs.c | 20 ++++------------- drivers/staging/rdma/hfi1/verbs.h | 1 - 8 files changed, 60 insertions(+), 32 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index d858f36042b5a..0b07b364f6662 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -9044,6 +9044,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd) if (handler == sdma_interrupt) { dd_dev_info(dd, "sdma engine %d cpu %d\n", sde->this_idx, sdma_cpu); + sde->cpu = sdma_cpu; cpumask_set_cpu(sdma_cpu, dd->msix_entries[i].mask); sdma_cpu = cpumask_next(sdma_cpu, def); if (sdma_cpu >= nr_cpu_ids) diff --git a/drivers/staging/rdma/hfi1/init.c b/drivers/staging/rdma/hfi1/init.c index 4a79744421547..6359967424801 100644 --- a/drivers/staging/rdma/hfi1/init.c +++ b/drivers/staging/rdma/hfi1/init.c @@ -603,20 +603,19 @@ static int create_workqueues(struct hfi1_devdata *dd) for (pidx = 0; pidx < dd->num_pports; ++pidx) { ppd = dd->pport + pidx; if (!ppd->hfi1_wq) { - char wq_name[8]; /* 3 + 2 + 1 + 1 + 1 */ - - snprintf(wq_name, sizeof(wq_name), "hfi%d_%d", - dd->unit, pidx); ppd->hfi1_wq = - create_singlethread_workqueue(wq_name); + alloc_workqueue( + "hfi%d_%d", + WQ_SYSFS | WQ_HIGHPRI | WQ_CPU_INTENSIVE, + dd->num_sdma, + dd->unit, pidx); if (!ppd->hfi1_wq) goto wq_error; } } return 0; wq_error: - pr_err("create_singlethread_workqueue failed for port %d\n", - pidx + 1); + pr_err("alloc_workqueue failed for port %d\n", pidx + 1); for (pidx = 0; pidx < dd->num_pports; ++pidx) { ppd = dd->pport + pidx; if (ppd->hfi1_wq) { diff --git a/drivers/staging/rdma/hfi1/iowait.h b/drivers/staging/rdma/hfi1/iowait.h index fa361b4058514..e8ba5606d08d1 100644 --- a/drivers/staging/rdma/hfi1/iowait.h +++ b/drivers/staging/rdma/hfi1/iowait.h @@ -150,12 +150,14 @@ static inline void iowait_init( * iowait_schedule() - initialize wait structure * @wait: wait struct to schedule * @wq: workqueue for schedule + * @cpu: cpu */ static inline void iowait_schedule( struct iowait *wait, - struct workqueue_struct *wq) + struct workqueue_struct *wq, + int cpu) { - queue_work(wq, &wait->iowork); + queue_work_on(cpu, wq, &wait->iowork); } /** diff --git a/drivers/staging/rdma/hfi1/qp.h b/drivers/staging/rdma/hfi1/qp.h index bacfa9c5e8a89..e49cfa6e59e08 100644 --- a/drivers/staging/rdma/hfi1/qp.h +++ b/drivers/staging/rdma/hfi1/qp.h @@ -247,6 +247,41 @@ void qp_iter_print(struct seq_file *s, struct qp_iter *iter); */ void qp_comm_est(struct hfi1_qp *qp); +/** + * _hfi1_schedule_send - schedule progress + * @qp: the QP + * + * This schedules qp progress w/o regard to the s_flags. + * + * It is only used in the post send, which doesn't hold + * the s_lock. + */ +static inline void _hfi1_schedule_send(struct hfi1_qp *qp) +{ + struct hfi1_ibport *ibp = + to_iport(qp->ibqp.device, qp->port_num); + struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); + struct hfi1_devdata *dd = dd_from_ibdev(qp->ibqp.device); + + iowait_schedule(&qp->s_iowait, ppd->hfi1_wq, + qp->s_sde ? + qp->s_sde->cpu : + cpumask_first(cpumask_of_node(dd->assigned_node_id))); +} + +/** + * hfi1_schedule_send - schedule progress + * @qp: the QP + * + * This schedules qp progress and caller should hold + * the s_lock. + */ +static inline void hfi1_schedule_send(struct hfi1_qp *qp) +{ + if (hfi1_send_ok(qp)) + _hfi1_schedule_send(qp); +} + void hfi1_migrate_qp(struct hfi1_qp *qp); #endif /* _QP_H */ diff --git a/drivers/staging/rdma/hfi1/sdma.c b/drivers/staging/rdma/hfi1/sdma.c index f1855457fa329..90b7072a99698 100644 --- a/drivers/staging/rdma/hfi1/sdma.c +++ b/drivers/staging/rdma/hfi1/sdma.c @@ -766,18 +766,19 @@ struct sdma_engine *sdma_select_engine_vl( struct sdma_engine *rval; if (WARN_ON(vl > 8)) - return NULL; + return &dd->per_sdma[0]; rcu_read_lock(); m = rcu_dereference(dd->sdma_map); if (unlikely(!m)) { rcu_read_unlock(); - return NULL; + return &dd->per_sdma[0]; } e = m->map[vl & m->mask]; rval = e->sde[selector & e->mask]; rcu_read_unlock(); + rval = !rval ? &dd->per_sdma[0] : rval; trace_hfi1_sdma_engine_select(dd, selector, vl, rval->this_idx); return rval; } @@ -1862,7 +1863,7 @@ static void dump_sdma_state(struct sdma_engine *sde) } #define SDE_FMT \ - "SDE %u STE %s C 0x%llx S 0x%016llx E 0x%llx T(HW) 0x%llx T(SW) 0x%x H(HW) 0x%llx H(SW) 0x%x H(D) 0x%llx DM 0x%llx GL 0x%llx R 0x%llx LIS 0x%llx AHGI 0x%llx TXT %u TXH %u DT %u DH %u FLNE %d DQF %u SLC 0x%llx\n" + "SDE %u CPU %d STE %s C 0x%llx S 0x%016llx E 0x%llx T(HW) 0x%llx T(SW) 0x%x H(HW) 0x%llx H(SW) 0x%x H(D) 0x%llx DM 0x%llx GL 0x%llx R 0x%llx LIS 0x%llx AHGI 0x%llx TXT %u TXH %u DT %u DH %u FLNE %d DQF %u SLC 0x%llx\n" /** * sdma_seqfile_dump_sde() - debugfs dump of sde * @s: seq file @@ -1882,6 +1883,7 @@ void sdma_seqfile_dump_sde(struct seq_file *s, struct sdma_engine *sde) head = sde->descq_head & sde->sdma_mask; tail = ACCESS_ONCE(sde->descq_tail) & sde->sdma_mask; seq_printf(s, SDE_FMT, sde->this_idx, + sde->cpu, sdma_state_name(sde->state.current_state), (unsigned long long)read_sde_csr(sde, SD(CTRL)), (unsigned long long)read_sde_csr(sde, SD(STATUS)), diff --git a/drivers/staging/rdma/hfi1/sdma.h b/drivers/staging/rdma/hfi1/sdma.h index cc22d2ee2054f..85701eed15858 100644 --- a/drivers/staging/rdma/hfi1/sdma.h +++ b/drivers/staging/rdma/hfi1/sdma.h @@ -410,8 +410,6 @@ struct sdma_engine { u64 idle_mask; u64 progress_mask; /* private: */ - struct workqueue_struct *wq; - /* private: */ volatile __le64 *head_dma; /* DMA'ed by chip */ /* private: */ dma_addr_t head_phys; @@ -426,6 +424,8 @@ struct sdma_engine { u32 sdma_mask; /* private */ struct sdma_state state; + /* private */ + int cpu; /* private: */ u8 sdma_shift; /* private: */ @@ -990,7 +990,9 @@ static inline void sdma_iowait_schedule( struct sdma_engine *sde, struct iowait *wait) { - iowait_schedule(wait, sde->wq); + struct hfi1_pportdata *ppd = sde->dd->pport; + + iowait_schedule(wait, ppd->hfi1_wq, sde->cpu); } /* for use by interrupt handling */ diff --git a/drivers/staging/rdma/hfi1/verbs.c b/drivers/staging/rdma/hfi1/verbs.c index ea1d9e6303e2c..38d2cd33a46f8 100644 --- a/drivers/staging/rdma/hfi1/verbs.c +++ b/drivers/staging/rdma/hfi1/verbs.c @@ -162,6 +162,8 @@ static inline struct hfi1_ucontext *to_iucontext(struct ib_ucontext return container_of(ibucontext, struct hfi1_ucontext, ibucontext); } +static inline void _hfi1_schedule_send(struct hfi1_qp *qp); + /* * Translate ib_wr_opcode into ib_wc_opcode. */ @@ -509,9 +511,9 @@ static int post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, nreq++; } bail: - if (nreq && !call_send) - hfi1_schedule_send(qp); spin_unlock_irqrestore(&qp->s_lock, flags); + if (nreq && !call_send) + _hfi1_schedule_send(qp); if (nreq && call_send) hfi1_do_send(&qp->s_iowait.iowork); return err; @@ -2135,20 +2137,6 @@ void hfi1_unregister_ib_device(struct hfi1_devdata *dd) vfree(dev->lk_table.table); } -/* - * This must be called with s_lock held. - */ -void hfi1_schedule_send(struct hfi1_qp *qp) -{ - if (hfi1_send_ok(qp)) { - struct hfi1_ibport *ibp = - to_iport(qp->ibqp.device, qp->port_num); - struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); - - iowait_schedule(&qp->s_iowait, ppd->hfi1_wq); - } -} - void hfi1_cnp_rcv(struct hfi1_packet *packet) { struct hfi1_ibport *ibp = &packet->rcd->ppd->ibport_data; diff --git a/drivers/staging/rdma/hfi1/verbs.h b/drivers/staging/rdma/hfi1/verbs.h index fa938fba8786c..b5013f88ea3cc 100644 --- a/drivers/staging/rdma/hfi1/verbs.h +++ b/drivers/staging/rdma/hfi1/verbs.h @@ -846,7 +846,6 @@ static inline int hfi1_send_ok(struct hfi1_qp *qp) /* * This must be called with s_lock held. */ -void hfi1_schedule_send(struct hfi1_qp *qp); void hfi1_bad_pqkey(struct hfi1_ibport *ibp, __be16 trap_num, u32 key, u32 sl, u32 qp1, u32 qp2, __be16 lid1, __be16 lid2); void hfi1_cap_mask_chg(struct hfi1_ibport *ibp); -- GitLab From d7b8ba5121e874fddd09e2e953f09646594a24a8 Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Mon, 9 Nov 2015 19:13:59 -0500 Subject: [PATCH 0525/2855] staging/rdma/hfi1: pre-compute sc and sde for RC/UC QPs Now that we have a multi-threaded work queue we precomputed and store the SC and SDE on RC and UC QPs for faster access. Reviewed-by: Dennis Dalessandro Signed-off-by: Mike Marciniszyn Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/qp.c | 27 +++++++++++++++++++++------ drivers/staging/rdma/hfi1/qp.h | 1 - drivers/staging/rdma/hfi1/ruc.c | 10 ++-------- drivers/staging/rdma/hfi1/ud.c | 1 + drivers/staging/rdma/hfi1/verbs.c | 14 +++----------- drivers/staging/rdma/hfi1/verbs.h | 3 ++- 6 files changed, 29 insertions(+), 27 deletions(-) diff --git a/drivers/staging/rdma/hfi1/qp.c b/drivers/staging/rdma/hfi1/qp.c index a2bbf0b8316c7..d37c4a77d1d87 100644 --- a/drivers/staging/rdma/hfi1/qp.c +++ b/drivers/staging/rdma/hfi1/qp.c @@ -617,7 +617,7 @@ int hfi1_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int mig = 0; int ret; u32 pmtu = 0; /* for gcc warning only */ - struct hfi1_devdata *dd; + struct hfi1_devdata *dd = dd_from_dev(dev); spin_lock_irq(&qp->r_lock); spin_lock(&qp->s_lock); @@ -631,23 +631,35 @@ int hfi1_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, goto inval; if (attr_mask & IB_QP_AV) { + u8 sc; + if (attr->ah_attr.dlid >= HFI1_MULTICAST_LID_BASE) goto inval; if (hfi1_check_ah(qp->ibqp.device, &attr->ah_attr)) goto inval; + sc = ah_to_sc(ibqp->device, &attr->ah_attr); + if (!qp_to_sdma_engine(qp, sc) && + dd->flags & HFI1_HAS_SEND_DMA) + goto inval; } if (attr_mask & IB_QP_ALT_PATH) { + u8 sc; + if (attr->alt_ah_attr.dlid >= HFI1_MULTICAST_LID_BASE) goto inval; if (hfi1_check_ah(qp->ibqp.device, &attr->alt_ah_attr)) goto inval; - if (attr->alt_pkey_index >= hfi1_get_npkeys(dd_from_dev(dev))) + if (attr->alt_pkey_index >= hfi1_get_npkeys(dd)) + goto inval; + sc = ah_to_sc(ibqp->device, &attr->alt_ah_attr); + if (!qp_to_sdma_engine(qp, sc) && + dd->flags & HFI1_HAS_SEND_DMA) goto inval; } if (attr_mask & IB_QP_PKEY_INDEX) - if (attr->pkey_index >= hfi1_get_npkeys(dd_from_dev(dev))) + if (attr->pkey_index >= hfi1_get_npkeys(dd)) goto inval; if (attr_mask & IB_QP_MIN_RNR_TIMER) @@ -792,6 +804,8 @@ int hfi1_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, qp->remote_ah_attr = attr->ah_attr; qp->s_srate = attr->ah_attr.static_rate; qp->srate_mbps = ib_rate_to_mbps(qp->s_srate); + qp->s_sc = ah_to_sc(ibqp->device, &qp->remote_ah_attr); + qp->s_sde = qp_to_sdma_engine(qp, qp->s_sc); } if (attr_mask & IB_QP_ALT_PATH) { @@ -806,6 +820,8 @@ int hfi1_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, qp->port_num = qp->alt_ah_attr.port_num; qp->s_pkey_index = qp->s_alt_pkey_index; qp->s_flags |= HFI1_S_AHG_CLEAR; + qp->s_sc = ah_to_sc(ibqp->device, &qp->remote_ah_attr); + qp->s_sde = qp_to_sdma_engine(qp, qp->s_sc); } } @@ -1528,9 +1544,6 @@ struct sdma_engine *qp_to_sdma_engine(struct hfi1_qp *qp, u8 sc5) if (!(dd->flags & HFI1_HAS_SEND_DMA)) return NULL; switch (qp->ibqp.qp_type) { - case IB_QPT_UC: - case IB_QPT_RC: - break; case IB_QPT_SMI: return NULL; default: @@ -1699,6 +1712,8 @@ void hfi1_migrate_qp(struct hfi1_qp *qp) qp->port_num = qp->alt_ah_attr.port_num; qp->s_pkey_index = qp->s_alt_pkey_index; qp->s_flags |= HFI1_S_AHG_CLEAR; + qp->s_sc = ah_to_sc(qp->ibqp.device, &qp->remote_ah_attr); + qp->s_sde = qp_to_sdma_engine(qp, qp->s_sc); ev.device = qp->ibqp.device; ev.element.qp = &qp->ibqp; diff --git a/drivers/staging/rdma/hfi1/qp.h b/drivers/staging/rdma/hfi1/qp.h index e49cfa6e59e08..94fd748a00a61 100644 --- a/drivers/staging/rdma/hfi1/qp.h +++ b/drivers/staging/rdma/hfi1/qp.h @@ -128,7 +128,6 @@ static inline void clear_ahg(struct hfi1_qp *qp) if (qp->s_sde && qp->s_ahgidx >= 0) sdma_ahg_free(qp->s_sde, qp->s_ahgidx); qp->s_ahgidx = -1; - qp->s_sde = NULL; } /** diff --git a/drivers/staging/rdma/hfi1/ruc.c b/drivers/staging/rdma/hfi1/ruc.c index cf8ac617552fd..863092bb06847 100644 --- a/drivers/staging/rdma/hfi1/ruc.c +++ b/drivers/staging/rdma/hfi1/ruc.c @@ -694,11 +694,8 @@ static inline void build_ahg(struct hfi1_qp *qp, u32 npsn) clear_ahg(qp); if (!(qp->s_flags & HFI1_S_AHG_VALID)) { /* first middle that needs copy */ - if (qp->s_ahgidx < 0) { - if (!qp->s_sde) - qp->s_sde = qp_to_sdma_engine(qp, qp->s_sc); + if (qp->s_ahgidx < 0) qp->s_ahgidx = sdma_ahg_alloc(qp->s_sde); - } if (qp->s_ahgidx >= 0) { qp->s_ahgpsn = npsn; qp->s_hdr->tx_flags |= SDMA_TXREQ_F_AHG_COPY; @@ -741,7 +738,6 @@ void hfi1_make_ruc_header(struct hfi1_qp *qp, struct hfi1_other_headers *ohdr, u16 lrh0; u32 nwords; u32 extra_bytes; - u8 sc5; u32 bth1; /* Construct the header. */ @@ -755,9 +751,7 @@ void hfi1_make_ruc_header(struct hfi1_qp *qp, struct hfi1_other_headers *ohdr, lrh0 = HFI1_LRH_GRH; middle = 0; } - sc5 = ibp->sl_to_sc[qp->remote_ah_attr.sl]; - lrh0 |= (sc5 & 0xf) << 12 | (qp->remote_ah_attr.sl & 0xf) << 4; - qp->s_sc = sc5; + lrh0 |= (qp->s_sc & 0xf) << 12 | (qp->remote_ah_attr.sl & 0xf) << 4; /* * reset s_hdr/AHG fields * diff --git a/drivers/staging/rdma/hfi1/ud.c b/drivers/staging/rdma/hfi1/ud.c index 5a9c784bec04c..54ff1f5416d49 100644 --- a/drivers/staging/rdma/hfi1/ud.c +++ b/drivers/staging/rdma/hfi1/ud.c @@ -383,6 +383,7 @@ int hfi1_make_ud_req(struct hfi1_qp *qp) lrh0 |= (sc5 & 0xf) << 12; qp->s_sc = sc5; } + qp->s_sde = qp_to_sdma_engine(qp, qp->s_sc); qp->s_hdr->ibh.lrh[0] = cpu_to_be16(lrh0); qp->s_hdr->ibh.lrh[1] = cpu_to_be16(ah_attr->dlid); /* DEST LID */ qp->s_hdr->ibh.lrh[2] = diff --git a/drivers/staging/rdma/hfi1/verbs.c b/drivers/staging/rdma/hfi1/verbs.c index 38d2cd33a46f8..296b7cbf39a99 100644 --- a/drivers/staging/rdma/hfi1/verbs.c +++ b/drivers/staging/rdma/hfi1/verbs.c @@ -1011,7 +1011,6 @@ int hfi1_verbs_send_dma(struct hfi1_qp *qp, struct ahg_ib_header *ahdr, struct verbs_txreq *tx; struct sdma_txreq *stx; u64 pbc_flags = 0; - struct sdma_engine *sde; u8 sc5 = qp->s_sc; int ret; @@ -1032,12 +1031,7 @@ int hfi1_verbs_send_dma(struct hfi1_qp *qp, struct ahg_ib_header *ahdr, if (IS_ERR(tx)) goto bail_tx; - if (!qp->s_hdr->sde) { - tx->sde = sde = qp_to_sdma_engine(qp, sc5); - if (!sde) - goto bail_no_sde; - } else - tx->sde = sde = qp->s_hdr->sde; + tx->sde = qp->s_sde; if (likely(pbc == 0)) { u32 vl = sc_to_vlt(dd_from_ibdev(qp->ibqp.device), sc5); @@ -1052,17 +1046,15 @@ int hfi1_verbs_send_dma(struct hfi1_qp *qp, struct ahg_ib_header *ahdr, if (qp->s_rdma_mr) qp->s_rdma_mr = NULL; tx->hdr_dwords = hdrwords + 2; - ret = build_verbs_tx_desc(sde, ss, len, tx, ahdr, pbc); + ret = build_verbs_tx_desc(tx->sde, ss, len, tx, ahdr, pbc); if (unlikely(ret)) goto bail_build; trace_output_ibhdr(dd_from_ibdev(qp->ibqp.device), &ahdr->ibh); - ret = sdma_send_txreq(sde, &qp->s_iowait, &tx->txreq); + ret = sdma_send_txreq(tx->sde, &qp->s_iowait, &tx->txreq); if (unlikely(ret == -ECOMM)) goto bail_ecomm; return ret; -bail_no_sde: - hfi1_put_txreq(tx); bail_ecomm: /* The current one got "sent" */ return 0; diff --git a/drivers/staging/rdma/hfi1/verbs.h b/drivers/staging/rdma/hfi1/verbs.h index b5013f88ea3cc..fdbe0f9d5f312 100644 --- a/drivers/staging/rdma/hfi1/verbs.h +++ b/drivers/staging/rdma/hfi1/verbs.h @@ -441,7 +441,8 @@ struct hfi1_qp { struct hfi1_swqe *s_wq; /* send work queue */ struct hfi1_mmap_info *ip; struct ahg_ib_header *s_hdr; /* next packet header to send */ - u8 s_sc; /* SC[0..4] for next packet */ + /* sc for UC/RC QPs - based on ah for UD */ + u8 s_sc; unsigned long timeout_jiffies; /* computed from timeout */ enum ib_mtu path_mtu; -- GitLab From 46b010d3eeb8eb29c740c4ef09c666485f5c07e6 Mon Sep 17 00:00:00 2001 From: "Mark F. Brown" Date: Mon, 9 Nov 2015 19:18:20 -0500 Subject: [PATCH 0526/2855] staging/rdma/hfi1: Workaround to prevent corruption during packet delivery Disabling one receive context when RX_DMA is receiving a packet can cause incorrect packet delivery for a subsequent packet on another receive context. This is resolved by doing the following: 1. Programming dummy tail address for every receive context before enabling it 2. While deallocating receive context resetting tail address to dummy address 3. Leaving the dummy address in when disabling tail update 4. When disabling receive context leaving tail update enabled Reviewed-by: Dennis Dalessandro Reviewed-by: Mike Marciniszyn Reviewed-by: Mitko Haralanov Signed-off-by: Mark F. Brown Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 18 +++++++++++++++--- drivers/staging/rdma/hfi1/hfi.h | 4 ++++ drivers/staging/rdma/hfi1/init.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index 0b07b364f6662..456704e9629a1 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -7785,6 +7785,17 @@ void hfi1_rcvctrl(struct hfi1_devdata *dd, unsigned int op, int ctxt) } if (op & HFI1_RCVCTRL_CTXT_DIS) { write_csr(dd, RCV_VL15, 0); + /* + * When receive context is being disabled turn on tail + * update with a dummy tail address and then disable + * receive context. + */ + if (dd->rcvhdrtail_dummy_physaddr) { + write_kctxt_csr(dd, ctxt, RCV_HDR_TAIL_ADDR, + dd->rcvhdrtail_dummy_physaddr); + rcvctrl |= RCV_CTXT_CTRL_TAIL_UPD_SMASK; + } + rcvctrl &= ~RCV_CTXT_CTRL_ENABLE_SMASK; } if (op & HFI1_RCVCTRL_INTRAVAIL_ENB) @@ -7854,10 +7865,11 @@ void hfi1_rcvctrl(struct hfi1_devdata *dd, unsigned int op, int ctxt) if (op & (HFI1_RCVCTRL_TAILUPD_DIS | HFI1_RCVCTRL_CTXT_DIS)) /* * If the context has been disabled and the Tail Update has - * been cleared, clear the RCV_HDR_TAIL_ADDR CSR so - * it doesn't contain an address that is invalid. + * been cleared, set the RCV_HDR_TAIL_ADDR CSR to dummy address + * so it doesn't contain an address that is invalid. */ - write_kctxt_csr(dd, ctxt, RCV_HDR_TAIL_ADDR, 0); + write_kctxt_csr(dd, ctxt, RCV_HDR_TAIL_ADDR, + dd->rcvhdrtail_dummy_physaddr); } u32 hfi1_read_cntrs(struct hfi1_devdata *dd, loff_t pos, char **namep, diff --git a/drivers/staging/rdma/hfi1/hfi.h b/drivers/staging/rdma/hfi1/hfi.h index 70891fbf89b05..1fd12411463c0 100644 --- a/drivers/staging/rdma/hfi1/hfi.h +++ b/drivers/staging/rdma/hfi1/hfi.h @@ -1071,6 +1071,10 @@ struct hfi1_devdata { /* Save the enabled LCB error bits */ u64 lcb_err_en; u8 dc_shutdown; + + /* receive context tail dummy address */ + __le64 *rcvhdrtail_dummy_kvaddr; + dma_addr_t rcvhdrtail_dummy_physaddr; }; /* 8051 firmware version helper */ diff --git a/drivers/staging/rdma/hfi1/init.c b/drivers/staging/rdma/hfi1/init.c index 6359967424801..c17cef6938fb3 100644 --- a/drivers/staging/rdma/hfi1/init.c +++ b/drivers/staging/rdma/hfi1/init.c @@ -692,6 +692,18 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit) if (ret) goto done; + /* allocate dummy tail memory for all receive contexts */ + dd->rcvhdrtail_dummy_kvaddr = dma_zalloc_coherent( + &dd->pcidev->dev, sizeof(u64), + &dd->rcvhdrtail_dummy_physaddr, + GFP_KERNEL); + + if (!dd->rcvhdrtail_dummy_kvaddr) { + dd_dev_err(dd, "cannot allocate dummy tail memory\n"); + ret = -ENOMEM; + goto done; + } + /* dd->rcd can be NULL if early initialization failed */ for (i = 0; dd->rcd && i < dd->first_user_ctxt; ++i) { /* @@ -1267,6 +1279,14 @@ static void cleanup_device_data(struct hfi1_devdata *dd) tmp = dd->rcd; dd->rcd = NULL; spin_unlock_irqrestore(&dd->uctxt_lock, flags); + + if (dd->rcvhdrtail_dummy_kvaddr) { + dma_free_coherent(&dd->pcidev->dev, sizeof(u64), + (void *)dd->rcvhdrtail_dummy_kvaddr, + dd->rcvhdrtail_dummy_physaddr); + dd->rcvhdrtail_dummy_kvaddr = NULL; + } + for (ctxt = 0; tmp && ctxt < dd->num_rcv_contexts; ctxt++) { struct hfi1_ctxtdata *rcd = tmp[ctxt]; @@ -1522,6 +1542,14 @@ int hfi1_create_rcvhdrq(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd) reg = (dd->rcvhdrsize & RCV_HDR_SIZE_HDR_SIZE_MASK) << RCV_HDR_SIZE_HDR_SIZE_SHIFT; write_kctxt_csr(dd, rcd->ctxt, RCV_HDR_SIZE, reg); + + /* + * Program dummy tail address for every receive context + * before enabling any receive context + */ + write_kctxt_csr(dd, rcd->ctxt, RCV_HDR_TAIL_ADDR, + dd->rcvhdrtail_dummy_physaddr); + return 0; bail_free: -- GitLab From 2fd36865b570667bf3deb0ad3e1f7739ce85c063 Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Tue, 10 Nov 2015 09:13:55 -0500 Subject: [PATCH 0527/2855] staging/rdma/hfi1: add common routine for queuing acks This patch is a prelimary patch required to coalesce acks. The routine to "schedule" a QP for sending a NAK is now centralized in rc_defer_ack(). The flag is changed for clarity since the all acks will potentially use the deferral mechanism. Reviewed-by: Dennis Dalessandro Signed-off-by: Mike Marciniszyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/driver.c | 4 +-- drivers/staging/rdma/hfi1/rc.c | 42 +++++++++++------------------- drivers/staging/rdma/hfi1/verbs.h | 12 +++++---- 3 files changed, 24 insertions(+), 34 deletions(-) diff --git a/drivers/staging/rdma/hfi1/driver.c b/drivers/staging/rdma/hfi1/driver.c index 72ab5e145f495..487d58778d700 100644 --- a/drivers/staging/rdma/hfi1/driver.c +++ b/drivers/staging/rdma/hfi1/driver.c @@ -714,8 +714,8 @@ static inline void process_rcv_qp_work(struct hfi1_packet *packet) */ list_for_each_entry_safe(qp, nqp, &rcd->qp_wait_list, rspwait) { list_del_init(&qp->rspwait); - if (qp->r_flags & HFI1_R_RSP_NAK) { - qp->r_flags &= ~HFI1_R_RSP_NAK; + if (qp->r_flags & HFI1_R_RSP_DEFERED_ACK) { + qp->r_flags &= ~HFI1_R_RSP_DEFERED_ACK; hfi1_send_rc_ack(rcd, qp, 0); } if (qp->r_flags & HFI1_R_RSP_SEND) { diff --git a/drivers/staging/rdma/hfi1/rc.c b/drivers/staging/rdma/hfi1/rc.c index fd23907f18fed..0c10012cc397f 100644 --- a/drivers/staging/rdma/hfi1/rc.c +++ b/drivers/staging/rdma/hfi1/rc.c @@ -1608,6 +1608,16 @@ bail: return; } +static inline void rc_defered_ack(struct hfi1_ctxtdata *rcd, + struct hfi1_qp *qp) +{ + if (list_empty(&qp->rspwait)) { + qp->r_flags |= HFI1_R_RSP_DEFERED_ACK; + atomic_inc(&qp->refcount); + list_add_tail(&qp->rspwait, &rcd->qp_wait_list); + } +} + /** * rc_rcv_error - process an incoming duplicate or error RC packet * @ohdr: the other headers for this packet @@ -1650,11 +1660,7 @@ static noinline int rc_rcv_error(struct hfi1_other_headers *ohdr, void *data, * in the receive queue have been processed. * Otherwise, we end up propagating congestion. */ - if (list_empty(&qp->rspwait)) { - qp->r_flags |= HFI1_R_RSP_NAK; - atomic_inc(&qp->refcount); - list_add_tail(&qp->rspwait, &rcd->qp_wait_list); - } + rc_defered_ack(rcd, qp); } goto done; } @@ -2337,11 +2343,7 @@ rnr_nak: qp->r_nak_state = IB_RNR_NAK | qp->r_min_rnr_timer; qp->r_ack_psn = qp->r_psn; /* Queue RNR NAK for later */ - if (list_empty(&qp->rspwait)) { - qp->r_flags |= HFI1_R_RSP_NAK; - atomic_inc(&qp->refcount); - list_add_tail(&qp->rspwait, &rcd->qp_wait_list); - } + rc_defered_ack(rcd, qp); return; nack_op_err: @@ -2349,11 +2351,7 @@ nack_op_err: qp->r_nak_state = IB_NAK_REMOTE_OPERATIONAL_ERROR; qp->r_ack_psn = qp->r_psn; /* Queue NAK for later */ - if (list_empty(&qp->rspwait)) { - qp->r_flags |= HFI1_R_RSP_NAK; - atomic_inc(&qp->refcount); - list_add_tail(&qp->rspwait, &rcd->qp_wait_list); - } + rc_defered_ack(rcd, qp); return; nack_inv_unlck: @@ -2363,11 +2361,7 @@ nack_inv: qp->r_nak_state = IB_NAK_INVALID_REQUEST; qp->r_ack_psn = qp->r_psn; /* Queue NAK for later */ - if (list_empty(&qp->rspwait)) { - qp->r_flags |= HFI1_R_RSP_NAK; - atomic_inc(&qp->refcount); - list_add_tail(&qp->rspwait, &rcd->qp_wait_list); - } + rc_defered_ack(rcd, qp); return; nack_acc_unlck: @@ -2421,13 +2415,7 @@ void hfi1_rc_hdrerr( * Otherwise, we end up * propagating congestion. */ - if (list_empty(&qp->rspwait)) { - qp->r_flags |= HFI1_R_RSP_NAK; - atomic_inc(&qp->refcount); - list_add_tail( - &qp->rspwait, - &rcd->qp_wait_list); - } + rc_defered_ack(rcd, qp); } /* Out of sequence NAK */ } /* QP Request NAKs */ } diff --git a/drivers/staging/rdma/hfi1/verbs.h b/drivers/staging/rdma/hfi1/verbs.h index fdbe0f9d5f312..6a49a3ca96b45 100644 --- a/drivers/staging/rdma/hfi1/verbs.h +++ b/drivers/staging/rdma/hfi1/verbs.h @@ -553,11 +553,13 @@ struct hfi1_qp { /* * Bit definitions for r_flags. */ -#define HFI1_R_REUSE_SGE 0x01 -#define HFI1_R_RDMAR_SEQ 0x02 -#define HFI1_R_RSP_NAK 0x04 -#define HFI1_R_RSP_SEND 0x08 -#define HFI1_R_COMM_EST 0x10 +#define HFI1_R_REUSE_SGE 0x01 +#define HFI1_R_RDMAR_SEQ 0x02 +/* defer ack until end of interrupt session */ +#define HFI1_R_RSP_DEFERED_ACK 0x04 +/* relay ack to send engine */ +#define HFI1_R_RSP_SEND 0x08 +#define HFI1_R_COMM_EST 0x10 /* * Bit definitions for s_flags. -- GitLab From 7c091e5c0685c463dc58e5115781f7ac0a1448d6 Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Tue, 10 Nov 2015 09:14:01 -0500 Subject: [PATCH 0528/2855] staging/rdma/hfi1: add ACK coalescing logic Implement ACK coalesing logic using a 8 bit counter. The algorithm is send pio ack when: - fecn present - this is the first packet in an interrupt session - counter is >= HFI1_PSN_CREDIT Otherwise the ack is defered. Reviewed-by: Dennis Dalessandro Signed-off-by: Mike Marciniszyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/qp.c | 1 + drivers/staging/rdma/hfi1/rc.c | 29 +++++++++++++++++++++++++++-- drivers/staging/rdma/hfi1/verbs.h | 7 ++++--- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rdma/hfi1/qp.c b/drivers/staging/rdma/hfi1/qp.c index d37c4a77d1d87..ce036810d5761 100644 --- a/drivers/staging/rdma/hfi1/qp.c +++ b/drivers/staging/rdma/hfi1/qp.c @@ -378,6 +378,7 @@ static void reset_qp(struct hfi1_qp *qp, enum ib_qp_type type) } qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE; qp->r_nak_state = 0; + qp->r_adefered = 0; qp->r_aflags = 0; qp->r_flags = 0; qp->s_head = 0; diff --git a/drivers/staging/rdma/hfi1/rc.c b/drivers/staging/rdma/hfi1/rc.c index 0c10012cc397f..6f4a155f79319 100644 --- a/drivers/staging/rdma/hfi1/rc.c +++ b/drivers/staging/rdma/hfi1/rc.c @@ -1618,6 +1618,17 @@ static inline void rc_defered_ack(struct hfi1_ctxtdata *rcd, } } +static inline void rc_cancel_ack(struct hfi1_qp *qp) +{ + qp->r_adefered = 0; + if (list_empty(&qp->rspwait)) + return; + list_del_init(&qp->rspwait); + qp->r_flags &= ~HFI1_R_RSP_DEFERED_ACK; + if (atomic_dec_and_test(&qp->refcount)) + wake_up(&qp->wait); +} + /** * rc_rcv_error - process an incoming duplicate or error RC packet * @ohdr: the other headers for this packet @@ -2335,8 +2346,22 @@ send_last: qp->r_ack_psn = psn; qp->r_nak_state = 0; /* Send an ACK if requested or required. */ - if (psn & (1 << 31)) - goto send_ack; + if (psn & IB_BTH_REQ_ACK) { + if (packet->numpkt == 0) { + rc_cancel_ack(qp); + goto send_ack; + } + if (qp->r_adefered >= HFI1_PSN_CREDIT) { + rc_cancel_ack(qp); + goto send_ack; + } + if (unlikely(is_fecn)) { + rc_cancel_ack(qp); + goto send_ack; + } + qp->r_adefered++; + rc_defered_ack(rcd, qp); + } return; rnr_nak: diff --git a/drivers/staging/rdma/hfi1/verbs.h b/drivers/staging/rdma/hfi1/verbs.h index 6a49a3ca96b45..cdc844f56c6b1 100644 --- a/drivers/staging/rdma/hfi1/verbs.h +++ b/drivers/staging/rdma/hfi1/verbs.h @@ -120,9 +120,9 @@ struct hfi1_packet; #define HFI1_VENDOR_IPG cpu_to_be16(0xFFA0) -#define IB_BTH_REQ_ACK (1 << 31) -#define IB_BTH_SOLICITED (1 << 23) -#define IB_BTH_MIG_REQ (1 << 22) +#define IB_BTH_REQ_ACK BIT(31) +#define IB_BTH_SOLICITED BIT(23) +#define IB_BTH_MIG_REQ BIT(22) #define IB_GRH_VERSION 6 #define IB_GRH_VERSION_MASK 0xF @@ -490,6 +490,7 @@ struct hfi1_qp { u32 r_psn; /* expected rcv packet sequence number */ u32 r_msn; /* message sequence number */ + u8 r_adefered; /* number of acks defered */ u8 r_state; /* opcode of last packet received */ u8 r_flags; u8 r_head_ack_queue; /* index into s_ack_queue[] */ -- GitLab From d46e51448a9a79817b85e9af04506d453ef5e279 Mon Sep 17 00:00:00 2001 From: Dennis Dalessandro Date: Wed, 11 Nov 2015 00:34:37 -0500 Subject: [PATCH 0529/2855] staging/rdma/hfi1: Reduce number of parameters passed to send handlers The current send function handlers are passed a bunch of parameters that are already part of the data structure that is passed in first (qp). This patch removes all of this and just passes the QP. Reviewed-by: Mike Marciniszyn Signed-off-by: Dennis Dalessandro Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/diag.c | 27 +++++++-------- drivers/staging/rdma/hfi1/hfi.h | 20 +++++------ drivers/staging/rdma/hfi1/ruc.c | 15 +++++---- drivers/staging/rdma/hfi1/verbs.c | 55 ++++++++++++++----------------- drivers/staging/rdma/hfi1/verbs.h | 23 ++++++++----- 5 files changed, 71 insertions(+), 69 deletions(-) diff --git a/drivers/staging/rdma/hfi1/diag.c b/drivers/staging/rdma/hfi1/diag.c index 88414d720469f..0aaad7412842b 100644 --- a/drivers/staging/rdma/hfi1/diag.c +++ b/drivers/staging/rdma/hfi1/diag.c @@ -1618,14 +1618,12 @@ int snoop_recv_handler(struct hfi1_packet *packet) /* * Handle snooping and capturing packets when sdma is being used. */ -int snoop_send_dma_handler(struct hfi1_qp *qp, struct ahg_ib_header *ibhdr, - u32 hdrwords, struct hfi1_sge_state *ss, u32 len, - u32 plen, u32 dwords, u64 pbc) +int snoop_send_dma_handler(struct hfi1_qp *qp, struct hfi1_pkt_state *ps, + u64 pbc) { - pr_alert("Snooping/Capture of Send DMA Packets Is Not Supported!\n"); + pr_alert("Snooping/Capture of Send DMA Packets Is Not Supported!\n"); snoop_dbg("Unsupported Operation"); - return hfi1_verbs_send_dma(qp, ibhdr, hdrwords, ss, len, plen, dwords, - 0); + return hfi1_verbs_send_dma(qp, ps, 0); } /* @@ -1633,12 +1631,16 @@ int snoop_send_dma_handler(struct hfi1_qp *qp, struct ahg_ib_header *ibhdr, * bypass packets. The only way to send a bypass packet currently is to use the * diagpkt interface. When that interface is enable snoop/capture is not. */ -int snoop_send_pio_handler(struct hfi1_qp *qp, struct ahg_ib_header *ahdr, - u32 hdrwords, struct hfi1_sge_state *ss, u32 len, - u32 plen, u32 dwords, u64 pbc) +int snoop_send_pio_handler(struct hfi1_qp *qp, struct hfi1_pkt_state *ps, + u64 pbc) { - struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); - struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); + struct ahg_ib_header *ahdr = qp->s_hdr; + u32 hdrwords = qp->s_hdrwords; + struct hfi1_sge_state *ss = qp->s_cur_sge; + u32 len = qp->s_cur_size; + u32 dwords = (len + 3) >> 2; + u32 plen = hdrwords + dwords + 2; /* includes pbc */ + struct hfi1_pportdata *ppd = ps->ppd; struct snoop_packet *s_packet = NULL; u32 *hdr = (u32 *)&ahdr->ibh; u32 length = 0; @@ -1783,8 +1785,7 @@ int snoop_send_pio_handler(struct hfi1_qp *qp, struct ahg_ib_header *ahdr, break; } out: - return hfi1_verbs_send_pio(qp, ahdr, hdrwords, ss, len, plen, dwords, - md.u.pbc); + return hfi1_verbs_send_pio(qp, ps, md.u.pbc); } /* diff --git a/drivers/staging/rdma/hfi1/hfi.h b/drivers/staging/rdma/hfi1/hfi.h index 1fd12411463c0..b048cf6960d9a 100644 --- a/drivers/staging/rdma/hfi1/hfi.h +++ b/drivers/staging/rdma/hfi1/hfi.h @@ -1048,12 +1048,10 @@ struct hfi1_devdata { * Handlers for outgoing data so that snoop/capture does not * have to have its hooks in the send path */ - int (*process_pio_send)(struct hfi1_qp *qp, struct ahg_ib_header *ibhdr, - u32 hdrwords, struct hfi1_sge_state *ss, - u32 len, u32 plen, u32 dwords, u64 pbc); - int (*process_dma_send)(struct hfi1_qp *qp, struct ahg_ib_header *ibhdr, - u32 hdrwords, struct hfi1_sge_state *ss, - u32 len, u32 plen, u32 dwords, u64 pbc); + int (*process_pio_send)(struct hfi1_qp *qp, struct hfi1_pkt_state *ps, + u64 pbc); + int (*process_dma_send)(struct hfi1_qp *qp, struct hfi1_pkt_state *ps, + u64 pbc); void (*pio_inline_send)(struct hfi1_devdata *dd, struct pio_buf *pbuf, u64 pbc, const void *from, size_t count); @@ -1405,12 +1403,10 @@ void reset_link_credits(struct hfi1_devdata *dd); void assign_remote_cm_au_table(struct hfi1_devdata *dd, u8 vcu); int snoop_recv_handler(struct hfi1_packet *packet); -int snoop_send_dma_handler(struct hfi1_qp *qp, struct ahg_ib_header *ibhdr, - u32 hdrwords, struct hfi1_sge_state *ss, u32 len, - u32 plen, u32 dwords, u64 pbc); -int snoop_send_pio_handler(struct hfi1_qp *qp, struct ahg_ib_header *ibhdr, - u32 hdrwords, struct hfi1_sge_state *ss, u32 len, - u32 plen, u32 dwords, u64 pbc); +int snoop_send_dma_handler(struct hfi1_qp *qp, struct hfi1_pkt_state *ps, + u64 pbc); +int snoop_send_pio_handler(struct hfi1_qp *qp, struct hfi1_pkt_state *ps, + u64 pbc); void snoop_inline_pio_send(struct hfi1_devdata *dd, struct pio_buf *pbuf, u64 pbc, const void *from, size_t count); diff --git a/drivers/staging/rdma/hfi1/ruc.c b/drivers/staging/rdma/hfi1/ruc.c index 863092bb06847..317bf6ff46a86 100644 --- a/drivers/staging/rdma/hfi1/ruc.c +++ b/drivers/staging/rdma/hfi1/ruc.c @@ -809,16 +809,20 @@ void hfi1_do_send(struct work_struct *work) { struct iowait *wait = container_of(work, struct iowait, iowork); struct hfi1_qp *qp = container_of(wait, struct hfi1_qp, s_iowait); - struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); - struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); + struct hfi1_pkt_state ps; int (*make_req)(struct hfi1_qp *qp); unsigned long flags; unsigned long timeout; + ps.dev = to_idev(qp->ibqp.device); + ps.ibp = to_iport(qp->ibqp.device, qp->port_num); + ps.ppd = ppd_from_ibp(ps.ibp); + if ((qp->ibqp.qp_type == IB_QPT_RC || qp->ibqp.qp_type == IB_QPT_UC) && !loopback && - (qp->remote_ah_attr.dlid & ~((1 << ppd->lmc) - 1)) == ppd->lid) { + (qp->remote_ah_attr.dlid & ~((1 << ps.ppd->lmc) - 1)) == + ps.ppd->lid) { ruc_loopback(qp); return; } @@ -850,8 +854,7 @@ void hfi1_do_send(struct work_struct *work) * If the packet cannot be sent now, return and * the send tasklet will be woken up later. */ - if (hfi1_verbs_send(qp, qp->s_hdr, qp->s_hdrwords, - qp->s_cur_sge, qp->s_cur_size)) + if (hfi1_verbs_send(qp, &ps)) break; /* Record that s_hdr is empty. */ qp->s_hdrwords = 0; @@ -860,7 +863,7 @@ void hfi1_do_send(struct work_struct *work) /* allow other tasks to run */ if (unlikely(time_after(jiffies, timeout))) { cond_resched(); - ppd->dd->verbs_dev.n_send_schedule++; + ps.ppd->dd->verbs_dev.n_send_schedule++; timeout = jiffies + SEND_RESCHED_TIMEOUT; } } while (make_req(qp)); diff --git a/drivers/staging/rdma/hfi1/verbs.c b/drivers/staging/rdma/hfi1/verbs.c index 296b7cbf39a99..ef0feaa684a48 100644 --- a/drivers/staging/rdma/hfi1/verbs.c +++ b/drivers/staging/rdma/hfi1/verbs.c @@ -1001,13 +1001,16 @@ bail_txadd: return ret; } -int hfi1_verbs_send_dma(struct hfi1_qp *qp, struct ahg_ib_header *ahdr, - u32 hdrwords, struct hfi1_sge_state *ss, u32 len, - u32 plen, u32 dwords, u64 pbc) +int hfi1_verbs_send_dma(struct hfi1_qp *qp, struct hfi1_pkt_state *ps, + u64 pbc) { - struct hfi1_ibdev *dev = to_idev(qp->ibqp.device); - struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); - struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); + struct ahg_ib_header *ahdr = qp->s_hdr; + u32 hdrwords = qp->s_hdrwords; + struct hfi1_sge_state *ss = qp->s_cur_sge; + u32 len = qp->s_cur_size; + u32 plen = hdrwords + ((len + 3) >> 2) + 2; /* includes pbc */ + struct hfi1_ibdev *dev = ps->dev; + struct hfi1_pportdata *ppd = ps->ppd; struct verbs_txreq *tx; struct sdma_txreq *stx; u64 pbc_flags = 0; @@ -1120,12 +1123,16 @@ struct send_context *qp_to_send_context(struct hfi1_qp *qp, u8 sc5) return dd->vld[vl].sc; } -int hfi1_verbs_send_pio(struct hfi1_qp *qp, struct ahg_ib_header *ahdr, - u32 hdrwords, struct hfi1_sge_state *ss, u32 len, - u32 plen, u32 dwords, u64 pbc) +int hfi1_verbs_send_pio(struct hfi1_qp *qp, struct hfi1_pkt_state *ps, + u64 pbc) { - struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); - struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); + struct ahg_ib_header *ahdr = qp->s_hdr; + u32 hdrwords = qp->s_hdrwords; + struct hfi1_sge_state *ss = qp->s_cur_sge; + u32 len = qp->s_cur_size; + u32 dwords = (len + 3) >> 2; + u32 plen = hdrwords + dwords + 2; /* includes pbc */ + struct hfi1_pportdata *ppd = ps->ppd; u32 *hdr = (u32 *)&ahdr->ibh; u64 pbc_flags = 0; u32 sc5; @@ -1297,23 +1304,18 @@ bad: /** * hfi1_verbs_send - send a packet * @qp: the QP to send on - * @ahdr: the packet header - * @hdrwords: the number of 32-bit words in the header - * @ss: the SGE to send - * @len: the length of the packet in bytes + * @ps: the state of the packet to send * * Return zero if packet is sent or queued OK. * Return non-zero and clear qp->s_flags HFI1_S_BUSY otherwise. */ -int hfi1_verbs_send(struct hfi1_qp *qp, struct ahg_ib_header *ahdr, - u32 hdrwords, struct hfi1_sge_state *ss, u32 len) +int hfi1_verbs_send(struct hfi1_qp *qp, struct hfi1_pkt_state *ps) { struct hfi1_devdata *dd = dd_from_ibdev(qp->ibqp.device); - u32 plen; + struct ahg_ib_header *ahdr = qp->s_hdr; int ret; int pio = 0; unsigned long flags = 0; - u32 dwords = (len + 3) >> 2; /* * VL15 packets (IB_QPT_SMI) will always use PIO, so we @@ -1344,23 +1346,16 @@ int hfi1_verbs_send(struct hfi1_qp *qp, struct ahg_ib_header *ahdr, return -EINVAL; } - /* - * Calculate the send buffer trigger address. - * The +2 counts for the pbc control qword - */ - plen = hdrwords + dwords + 2; - if (pio) { - ret = dd->process_pio_send( - qp, ahdr, hdrwords, ss, len, plen, dwords, 0); + ret = dd->process_pio_send(qp, ps, 0); } else { #ifdef CONFIG_SDMA_VERBOSITY dd_dev_err(dd, "CONFIG SDMA %s:%d %s()\n", slashstrip(__FILE__), __LINE__, __func__); - dd_dev_err(dd, "SDMA hdrwords = %u, len = %u\n", hdrwords, len); + dd_dev_err(dd, "SDMA hdrwords = %u, len = %u\n", qp->s_hdrwords, + qp->s_cur_size); #endif - ret = dd->process_dma_send( - qp, ahdr, hdrwords, ss, len, plen, dwords, 0); + ret = dd->process_dma_send(qp, ps, 0); } return ret; diff --git a/drivers/staging/rdma/hfi1/verbs.h b/drivers/staging/rdma/hfi1/verbs.h index cdc844f56c6b1..7e27531c430a3 100644 --- a/drivers/staging/rdma/hfi1/verbs.h +++ b/drivers/staging/rdma/hfi1/verbs.h @@ -545,6 +545,16 @@ struct hfi1_qp { ____cacheline_aligned_in_smp; }; +/* + * This structure is used to hold commonly lookedup and computed values during + * the send engine progress. + */ +struct hfi1_pkt_state { + struct hfi1_ibdev *dev; + struct hfi1_ibport *ibp; + struct hfi1_pportdata *ppd; +}; + /* * Atomic bit definitions for r_aflags. */ @@ -930,8 +940,7 @@ int hfi1_mcast_tree_empty(struct hfi1_ibport *ibp); struct verbs_txreq; void hfi1_put_txreq(struct verbs_txreq *tx); -int hfi1_verbs_send(struct hfi1_qp *qp, struct ahg_ib_header *ahdr, - u32 hdrwords, struct hfi1_sge_state *ss, u32 len); +int hfi1_verbs_send(struct hfi1_qp *qp, struct hfi1_pkt_state *ps); void hfi1_copy_sge(struct hfi1_sge_state *ss, void *data, u32 length, int release); @@ -1102,13 +1111,11 @@ void hfi1_ib_rcv(struct hfi1_packet *packet); unsigned hfi1_get_npkeys(struct hfi1_devdata *); -int hfi1_verbs_send_dma(struct hfi1_qp *qp, struct ahg_ib_header *hdr, - u32 hdrwords, struct hfi1_sge_state *ss, u32 len, - u32 plen, u32 dwords, u64 pbc); +int hfi1_verbs_send_dma(struct hfi1_qp *qp, struct hfi1_pkt_state *ps, + u64 pbc); -int hfi1_verbs_send_pio(struct hfi1_qp *qp, struct ahg_ib_header *hdr, - u32 hdrwords, struct hfi1_sge_state *ss, u32 len, - u32 plen, u32 dwords, u64 pbc); +int hfi1_verbs_send_pio(struct hfi1_qp *qp, struct hfi1_pkt_state *ps, + u64 pbc); struct send_context *qp_to_send_context(struct hfi1_qp *qp, u8 sc5); -- GitLab From 82c2611daaf010500720a569ca733d216d81968e Mon Sep 17 00:00:00 2001 From: Niranjana Vishwanathapura Date: Wed, 11 Nov 2015 00:35:19 -0500 Subject: [PATCH 0530/2855] staging/rdma/hfi1: Handle packets with invalid RHF on context 0 Context 0 (which handles the error packets) can potentially receive an invalid rhf. Hence, it can not depend on RHF sequence number and can only use DMA_RTAIL mechanism. Detect such packets with invalid rhf using rhf sequence counting mechanism and drop them. As DMA_RTAIL mechanism has performance penalties, do not use context 0 for performance critical verbs path. Use context 0 for VL15 (MAD), multicast and error packets. Reviewed-by: Arthur Kepner Reviewed-by: Mike Marciniszyn Reviewed-by: Dennis Dalessandro Reviewed-by: Dean Luick Reviewed-by: Mitko Haralanov Signed-off-by: Niranjana Vishwanathapura Signed-off-by: Mike Marciniszyn Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 74 ++++++++++---------- drivers/staging/rdma/hfi1/driver.c | 108 +++++++++++++++++++++++++---- drivers/staging/rdma/hfi1/hfi.h | 8 ++- drivers/staging/rdma/hfi1/init.c | 9 ++- 4 files changed, 146 insertions(+), 53 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index 456704e9629a1..dc6915947c78d 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -121,8 +121,8 @@ struct flag_table { #define SEC_SC_HALTED 0x4 /* per-context only */ #define SEC_SPC_FREEZE 0x8 /* per-HFI only */ -#define VL15CTXT 1 #define MIN_KERNEL_KCTXTS 2 +#define FIRST_KERNEL_KCTXT 1 #define NUM_MAP_REGS 32 /* Bit offset into the GUID which carries HFI id information */ @@ -7780,8 +7780,8 @@ void hfi1_rcvctrl(struct hfi1_devdata *dd, unsigned int op, int ctxt) & RCV_TID_CTRL_TID_BASE_INDEX_MASK) << RCV_TID_CTRL_TID_BASE_INDEX_SHIFT); write_kctxt_csr(dd, ctxt, RCV_TID_CTRL, reg); - if (ctxt == VL15CTXT) - write_csr(dd, RCV_VL15, VL15CTXT); + if (ctxt == HFI1_CTRL_CTXT) + write_csr(dd, RCV_VL15, HFI1_CTRL_CTXT); } if (op & HFI1_RCVCTRL_CTXT_DIS) { write_csr(dd, RCV_VL15, 0); @@ -8908,7 +8908,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd) int first_general, last_general; int first_sdma, last_sdma; int first_rx, last_rx; - int first_cpu, restart_cpu, curr_cpu; + int first_cpu, curr_cpu; int rcv_cpu, sdma_cpu; int i, ret = 0, possible; int ht; @@ -8947,22 +8947,19 @@ static int request_msix_irqs(struct hfi1_devdata *dd) topology_sibling_cpumask(cpumask_first(local_mask))); for (i = possible/ht; i < possible; i++) cpumask_clear_cpu(i, def); - /* reset possible */ - possible = cpumask_weight(def); /* def now has full cores on chosen node*/ first_cpu = cpumask_first(def); if (nr_cpu_ids >= first_cpu) first_cpu++; - restart_cpu = first_cpu; - curr_cpu = restart_cpu; + curr_cpu = first_cpu; - for (i = first_cpu; i < dd->n_krcv_queues + first_cpu; i++) { + /* One context is reserved as control context */ + for (i = first_cpu; i < dd->n_krcv_queues + first_cpu - 1; i++) { cpumask_clear_cpu(curr_cpu, def); cpumask_set_cpu(curr_cpu, rcv); - if (curr_cpu >= possible) - curr_cpu = restart_cpu; - else - curr_cpu++; + curr_cpu = cpumask_next(curr_cpu, def); + if (curr_cpu >= nr_cpu_ids) + break; } /* def mask has non-rcv, rcv has recv mask */ rcv_cpu = cpumask_first(rcv); @@ -9062,12 +9059,20 @@ static int request_msix_irqs(struct hfi1_devdata *dd) if (sdma_cpu >= nr_cpu_ids) sdma_cpu = cpumask_first(def); } else if (handler == receive_context_interrupt) { - dd_dev_info(dd, "rcv ctxt %d cpu %d\n", - rcd->ctxt, rcv_cpu); - cpumask_set_cpu(rcv_cpu, dd->msix_entries[i].mask); - rcv_cpu = cpumask_next(rcv_cpu, rcv); - if (rcv_cpu >= nr_cpu_ids) - rcv_cpu = cpumask_first(rcv); + dd_dev_info(dd, "rcv ctxt %d cpu %d\n", rcd->ctxt, + (rcd->ctxt == HFI1_CTRL_CTXT) ? + cpumask_first(def) : rcv_cpu); + if (rcd->ctxt == HFI1_CTRL_CTXT) { + /* map to first default */ + cpumask_set_cpu(cpumask_first(def), + dd->msix_entries[i].mask); + } else { + cpumask_set_cpu(rcv_cpu, + dd->msix_entries[i].mask); + rcv_cpu = cpumask_next(rcv_cpu, rcv); + if (rcv_cpu >= nr_cpu_ids) + rcv_cpu = cpumask_first(rcv); + } } else { /* otherwise first def */ dd_dev_info(dd, "%s cpu %d\n", @@ -9200,11 +9205,18 @@ static int set_up_context_variables(struct hfi1_devdata *dd) /* * Kernel contexts: (to be fixed later): * - min or 2 or 1 context/numa - * - Context 0 - default/errors - * - Context 1 - VL15 + * - Context 0 - control context (VL15/multicast/error) + * - Context 1 - default context */ if (n_krcvqs) - num_kernel_contexts = n_krcvqs + MIN_KERNEL_KCTXTS; + /* + * Don't count context 0 in n_krcvqs since + * is isn't used for normal verbs traffic. + * + * krcvqs will reflect number of kernel + * receive contexts above 0. + */ + num_kernel_contexts = n_krcvqs + MIN_KERNEL_KCTXTS - 1; else num_kernel_contexts = num_online_nodes(); num_kernel_contexts = @@ -10053,12 +10065,6 @@ static void init_qpmap_table(struct hfi1_devdata *dd, u64 ctxt = first_ctxt; for (i = 0; i < 256;) { - if (ctxt == VL15CTXT) { - ctxt++; - if (ctxt > last_ctxt) - ctxt = first_ctxt; - continue; - } reg |= ctxt << (8 * (i % 8)); i++; ctxt++; @@ -10171,19 +10177,13 @@ static void init_qos(struct hfi1_devdata *dd, u32 first_ctxt) /* Enable RSM */ add_rcvctrl(dd, RCV_CTRL_RCV_RSM_ENABLE_SMASK); kfree(rsmmap); - /* map everything else (non-VL15) to context 0 */ - init_qpmap_table( - dd, - 0, - 0); + /* map everything else to first context */ + init_qpmap_table(dd, FIRST_KERNEL_KCTXT, MIN_KERNEL_KCTXTS - 1); dd->qos_shift = n + 1; return; bail: dd->qos_shift = 1; - init_qpmap_table( - dd, - dd->n_krcv_queues > MIN_KERNEL_KCTXTS ? MIN_KERNEL_KCTXTS : 0, - dd->n_krcv_queues - 1); + init_qpmap_table(dd, FIRST_KERNEL_KCTXT, dd->n_krcv_queues - 1); } static void init_rxe(struct hfi1_devdata *dd) diff --git a/drivers/staging/rdma/hfi1/driver.c b/drivers/staging/rdma/hfi1/driver.c index 487d58778d700..4c52e785de68e 100644 --- a/drivers/staging/rdma/hfi1/driver.c +++ b/drivers/staging/rdma/hfi1/driver.c @@ -509,28 +509,49 @@ static inline void init_ps_mdata(struct ps_mdata *mdata, mdata->maxcnt = packet->maxcnt; mdata->ps_head = packet->rhqoff; - if (HFI1_CAP_IS_KSET(DMA_RTAIL)) { + if (HFI1_CAP_KGET_MASK(rcd->flags, DMA_RTAIL)) { mdata->ps_tail = get_rcvhdrtail(rcd); - mdata->ps_seq = 0; /* not used with DMA_RTAIL */ + if (rcd->ctxt == HFI1_CTRL_CTXT) + mdata->ps_seq = rcd->seq_cnt; + else + mdata->ps_seq = 0; /* not used with DMA_RTAIL */ } else { mdata->ps_tail = 0; /* used only with DMA_RTAIL*/ mdata->ps_seq = rcd->seq_cnt; } } -static inline int ps_done(struct ps_mdata *mdata, u64 rhf) +static inline int ps_done(struct ps_mdata *mdata, u64 rhf, + struct hfi1_ctxtdata *rcd) { - if (HFI1_CAP_IS_KSET(DMA_RTAIL)) + if (HFI1_CAP_KGET_MASK(rcd->flags, DMA_RTAIL)) return mdata->ps_head == mdata->ps_tail; return mdata->ps_seq != rhf_rcv_seq(rhf); } -static inline void update_ps_mdata(struct ps_mdata *mdata) +static inline int ps_skip(struct ps_mdata *mdata, u64 rhf, + struct hfi1_ctxtdata *rcd) +{ + /* + * Control context can potentially receive an invalid rhf. + * Drop such packets. + */ + if ((rcd->ctxt == HFI1_CTRL_CTXT) && (mdata->ps_head != mdata->ps_tail)) + return mdata->ps_seq != rhf_rcv_seq(rhf); + + return 0; +} + +static inline void update_ps_mdata(struct ps_mdata *mdata, + struct hfi1_ctxtdata *rcd) { mdata->ps_head += mdata->rsize; if (mdata->ps_head >= mdata->maxcnt) mdata->ps_head = 0; - if (!HFI1_CAP_IS_KSET(DMA_RTAIL)) { + + /* Control context must do seq counting */ + if (!HFI1_CAP_KGET_MASK(rcd->flags, DMA_RTAIL) || + (rcd->ctxt == HFI1_CTRL_CTXT)) { if (++mdata->ps_seq > 13) mdata->ps_seq = 1; } @@ -566,9 +587,12 @@ static void prescan_rxq(struct hfi1_packet *packet) int is_ecn = 0; u8 lnh; - if (ps_done(&mdata, rhf)) + if (ps_done(&mdata, rhf, rcd)) break; + if (ps_skip(&mdata, rhf, rcd)) + goto next; + if (etype != RHF_RCV_TYPE_IB) goto next; @@ -606,8 +630,34 @@ static void prescan_rxq(struct hfi1_packet *packet) bth1 &= ~(HFI1_FECN_SMASK | HFI1_BECN_SMASK); ohdr->bth[1] = cpu_to_be32(bth1); next: - update_ps_mdata(&mdata); + update_ps_mdata(&mdata, rcd); + } +} + +static inline int skip_rcv_packet(struct hfi1_packet *packet, int thread) +{ + int ret = RCV_PKT_OK; + + /* Set up for the next packet */ + packet->rhqoff += packet->rsize; + if (packet->rhqoff >= packet->maxcnt) + packet->rhqoff = 0; + + packet->numpkt++; + if (unlikely((packet->numpkt & (MAX_PKT_RECV - 1)) == 0)) { + if (thread) { + cond_resched(); + } else { + ret = RCV_PKT_LIMIT; + this_cpu_inc(*packet->rcd->dd->rcv_limit); + } } + + packet->rhf_addr = (__le32 *)packet->rcd->rcvhdrq + packet->rhqoff + + packet->rcd->dd->rhf_offset; + packet->rhf = rhf_to_cpu(packet->rhf_addr); + + return ret; } #endif /* CONFIG_PRESCAN_RXQ */ @@ -784,7 +834,6 @@ int handle_receive_interrupt_dma_rtail(struct hfi1_ctxtdata *rcd, int thread) while (last == RCV_PKT_OK) { last = process_rcv_packet(&packet, thread); - hdrqtail = get_rcvhdrtail(rcd); if (packet.rhqoff == hdrqtail) last = RCV_PKT_DONE; process_rcv_update(last, &packet); @@ -799,7 +848,7 @@ static inline void set_all_nodma_rtail(struct hfi1_devdata *dd) { int i; - for (i = 0; i < dd->first_user_ctxt; i++) + for (i = HFI1_CTRL_CTXT + 1; i < dd->first_user_ctxt; i++) dd->rcd[i]->do_interrupt = &handle_receive_interrupt_nodma_rtail; } @@ -808,7 +857,7 @@ static inline void set_all_dma_rtail(struct hfi1_devdata *dd) { int i; - for (i = 0; i < dd->first_user_ctxt; i++) + for (i = HFI1_CTRL_CTXT + 1; i < dd->first_user_ctxt; i++) dd->rcd[i]->do_interrupt = &handle_receive_interrupt_dma_rtail; } @@ -824,12 +873,16 @@ int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread) { struct hfi1_devdata *dd = rcd->dd; u32 hdrqtail; - int last = RCV_PKT_OK, needset = 1; + int needset, last = RCV_PKT_OK; struct hfi1_packet packet; + int skip_pkt = 0; + + /* Control context will always use the slow path interrupt handler */ + needset = (rcd->ctxt == HFI1_CTRL_CTXT) ? 0 : 1; init_packet(rcd, &packet); - if (!HFI1_CAP_IS_KSET(DMA_RTAIL)) { + if (!HFI1_CAP_KGET_MASK(rcd->flags, DMA_RTAIL)) { u32 seq = rhf_rcv_seq(packet.rhf); if (seq != rcd->seq_cnt) { @@ -844,6 +897,17 @@ int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread) goto bail; } smp_rmb(); /* prevent speculative reads of dma'ed hdrq */ + + /* + * Control context can potentially receive an invalid + * rhf. Drop such packets. + */ + if (rcd->ctxt == HFI1_CTRL_CTXT) { + u32 seq = rhf_rcv_seq(packet.rhf); + + if (seq != rcd->seq_cnt) + skip_pkt = 1; + } } prescan_rxq(&packet); @@ -861,11 +925,14 @@ int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread) dd->rhf_offset; packet.rhf = rhf_to_cpu(packet.rhf_addr); + } else if (skip_pkt) { + last = skip_rcv_packet(&packet, thread); + skip_pkt = 0; } else { last = process_rcv_packet(&packet, thread); } - if (!HFI1_CAP_IS_KSET(DMA_RTAIL)) { + if (!HFI1_CAP_KGET_MASK(rcd->flags, DMA_RTAIL)) { u32 seq = rhf_rcv_seq(packet.rhf); if (++rcd->seq_cnt > 13) @@ -881,6 +948,19 @@ int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread) } else { if (packet.rhqoff == hdrqtail) last = RCV_PKT_DONE; + /* + * Control context can potentially receive an invalid + * rhf. Drop such packets. + */ + if (rcd->ctxt == HFI1_CTRL_CTXT) { + u32 seq = rhf_rcv_seq(packet.rhf); + + if (++rcd->seq_cnt > 13) + rcd->seq_cnt = 1; + if (!last && (seq != rcd->seq_cnt)) + skip_pkt = 1; + } + if (needset) { dd_dev_info(dd, "Switching to DMA_RTAIL\n"); diff --git a/drivers/staging/rdma/hfi1/hfi.h b/drivers/staging/rdma/hfi1/hfi.h index b048cf6960d9a..54ed6b36c1a78 100644 --- a/drivers/staging/rdma/hfi1/hfi.h +++ b/drivers/staging/rdma/hfi1/hfi.h @@ -99,6 +99,12 @@ extern unsigned long hfi1_cap_mask; #define HFI1_MISC_GET() ((hfi1_cap_mask >> HFI1_CAP_MISC_SHIFT) & \ HFI1_CAP_MISC_MASK) +/* + * Control context is always 0 and handles the error packets. + * It also handles the VL15 and multicast packets. + */ +#define HFI1_CTRL_CTXT 0 + /* * per driver stats, either not device nor port-specific, or * summed over all of the devices and ports. @@ -234,7 +240,7 @@ struct hfi1_ctxtdata { /* chip offset of PIO buffers for this ctxt */ u32 piobufs; /* per-context configuration flags */ - u16 flags; + u32 flags; /* per-context event flags for fileops/intr communication */ unsigned long event_flags; /* WAIT_RCV that timed out, no interrupt */ diff --git a/drivers/staging/rdma/hfi1/init.c b/drivers/staging/rdma/hfi1/init.c index c17cef6938fb3..1c8286f4c00ca 100644 --- a/drivers/staging/rdma/hfi1/init.c +++ b/drivers/staging/rdma/hfi1/init.c @@ -90,7 +90,7 @@ MODULE_PARM_DESC( u8 krcvqs[RXE_NUM_DATA_VL]; int krcvqsset; module_param_array(krcvqs, byte, &krcvqsset, S_IRUGO); -MODULE_PARM_DESC(krcvqs, "Array of the number of kernel receive queues by VL"); +MODULE_PARM_DESC(krcvqs, "Array of the number of non-control kernel receive queues by VL"); /* computed based on above array */ unsigned n_krcvqs; @@ -130,6 +130,9 @@ int hfi1_create_ctxts(struct hfi1_devdata *dd) int ret; int local_node_id = pcibus_to_node(dd->pcidev->bus); + /* Control context has to be always 0 */ + BUILD_BUG_ON(HFI1_CTRL_CTXT != 0); + if (local_node_id < 0) local_node_id = numa_node_id(); dd->assigned_node_id = local_node_id; @@ -159,6 +162,10 @@ int hfi1_create_ctxts(struct hfi1_devdata *dd) HFI1_CAP_KGET(NODROP_RHQ_FULL) | HFI1_CAP_KGET(NODROP_EGR_FULL) | HFI1_CAP_KGET(DMA_RTAIL); + + /* Control context must use DMA_RTAIL */ + if (rcd->ctxt == HFI1_CTRL_CTXT) + rcd->flags |= HFI1_CAP_DMA_RTAIL; rcd->seq_cnt = 1; rcd->sc = sc_alloc(dd, SC_ACK, rcd->rcvhdrqentsize, dd->node); -- GitLab From b26baffbc91693c9a3b81704a4870a474f169871 Mon Sep 17 00:00:00 2001 From: Anjali Menon Date: Mon, 16 Nov 2015 22:49:19 +0530 Subject: [PATCH 0531/2855] staging: rdma: ehca: Added a blank line Added a blank line after declarations to remove the coding style error detected by the checkpatch.pl. WARNING: Missing a blank line after declarations Signed-off-by: Anjali Menon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/ehca/ehca_av.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/rdma/ehca/ehca_av.c b/drivers/staging/rdma/ehca/ehca_av.c index 465926319f3dc..fd7b6d044ec10 100644 --- a/drivers/staging/rdma/ehca/ehca_av.c +++ b/drivers/staging/rdma/ehca/ehca_av.c @@ -105,6 +105,7 @@ struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) if (ehca_static_rate < 0) { u32 ipd; + if (ehca_calc_ipd(shca, ah_attr->port_num, ah_attr->static_rate, &ipd)) { ret = -EINVAL; @@ -128,6 +129,7 @@ struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) int rc; struct ib_port_attr port_attr; union ib_gid gid; + memset(&port_attr, 0, sizeof(port_attr)); rc = ehca_query_port(pd->device, ah_attr->port_num, &port_attr); @@ -192,6 +194,7 @@ int ehca_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr) int rc; struct ib_port_attr port_attr; union ib_gid gid; + memset(&port_attr, 0, sizeof(port_attr)); rc = ehca_query_port(ah->device, ah_attr->port_num, &port_attr); -- GitLab From 2e87b7a8bef7901ab56f121f0d7c085aacee86fc Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 Nov 2015 15:45:35 +0000 Subject: [PATCH 0532/2855] extcon: arizona: Add device binding to enable ADC mode micdet Add a simple boolean binding to turn on and off the use of ADC microphone detection mode to determine 3/4 pole jack. Signed-off-by: Charles Keepax Acked-by: Chanwoo Choi Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-arizona.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index e4890dd4fefd6..af3afeeb6673f 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -1236,6 +1236,9 @@ static int arizona_extcon_device_get_pdata(struct arizona *arizona) pdata->micd_force_micbias = device_property_read_bool(arizona->dev, "wlf,micd-force-micbias"); + pdata->micd_software_compare = device_property_read_bool(arizona->dev, + "wlf,micd-software-compare"); + return 0; } -- GitLab From 99374227cfb9f410965022063baf447ae3c41b9f Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 Nov 2015 15:45:36 +0000 Subject: [PATCH 0533/2855] extcon: arizona: Add device binding for the general purpose switch The switch is generally used in conjunction with the MICDET clamp to suppress pops and clicks associated with jack insertion. This patch adds a binding that allows the user to select the mode of operation for this switch. Signed-off-by: Charles Keepax Acked-by: Chanwoo Choi Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-arizona.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index af3afeeb6673f..493da5bc99897 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -1239,6 +1239,8 @@ static int arizona_extcon_device_get_pdata(struct arizona *arizona) pdata->micd_software_compare = device_property_read_bool(arizona->dev, "wlf,micd-software-compare"); + device_property_read_u32(arizona->dev, "wlf,gpsw", &pdata->gpsw); + return 0; } -- GitLab From 3d7a872fa359e13b6903c7fb45bb15c0078d4a84 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 Nov 2015 15:45:37 +0000 Subject: [PATCH 0534/2855] extcon: arizona: Add device binding for jack detect polarity inversion By default the driver expects the jackdet pin to be pulled low when a jack is inserted. This patch adds a device binding that allows the user to specify that the jackdet pin will be pulled high when a jack is inserted. Signed-off-by: Charles Keepax Acked-by: Chanwoo Choi Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-arizona.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index 493da5bc99897..27ddf9cccca51 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -1239,6 +1239,9 @@ static int arizona_extcon_device_get_pdata(struct arizona *arizona) pdata->micd_software_compare = device_property_read_bool(arizona->dev, "wlf,micd-software-compare"); + pdata->jd_invert = device_property_read_bool(arizona->dev, + "wlf,jd-invert"); + device_property_read_u32(arizona->dev, "wlf,gpsw", &pdata->gpsw); return 0; -- GitLab From 35247c136a47a05d7747c9c7f0bc0d948d1fdda5 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 Nov 2015 15:45:38 +0000 Subject: [PATCH 0535/2855] extcon: arizona: Add device binding for second jack detect pin on GPIO5 Some Arizona devices have the option to use the GPIO5 pin as a second jack detection pin. This patch adds device bindings to specify to the driver that it should use this pin. Note that the second jack detection pin is hard wired in the chip so can only be enabled through the binding, rather than a pin being specified. Signed-off-by: Charles Keepax Acked-by: Chanwoo Choi Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-arizona.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index 27ddf9cccca51..7c9598db318dc 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -1244,6 +1244,11 @@ static int arizona_extcon_device_get_pdata(struct arizona *arizona) device_property_read_u32(arizona->dev, "wlf,gpsw", &pdata->gpsw); + pdata->jd_gpio5 = device_property_read_bool(arizona->dev, + "wlf,use-jd-gpio"); + pdata->jd_gpio5_nopull = device_property_read_bool(arizona->dev, + "wlf,use-jd-gpio-nopull"); + return 0; } -- GitLab From afe330098d255e698088e010be3cb4fa57e9ff86 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 Nov 2015 15:45:39 +0000 Subject: [PATCH 0536/2855] extcon: arizona: Update DT binding documentation for mic detection Add additional bindings to allow configuration of the system specific microphone detection settings. Signed-off-by: Charles Keepax Signed-off-by: Chanwoo Choi --- .../bindings/extcon/extcon-arizona.txt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Documentation/devicetree/bindings/extcon/extcon-arizona.txt b/Documentation/devicetree/bindings/extcon/extcon-arizona.txt index e1705fae63a86..d6618119a9a85 100644 --- a/Documentation/devicetree/bindings/extcon/extcon-arizona.txt +++ b/Documentation/devicetree/bindings/extcon/extcon-arizona.txt @@ -13,3 +13,23 @@ Optional properties: ARIZONA_ACCDET_MODE_HPR or 2 - Headphone detect mode is set to HPDETR If this node is not mentioned or if the value is unknown, then headphone detection mode is set to HPDETL. + + - wlf,micd-software-compare : Use a software comparison to determine mic + presence + - wlf,micd-detect-debounce : Additional software microphone detection + debounce specified in milliseconds. + - wlf,micd-pol-gpio : GPIO specifier for the GPIO controlling the headset + polarity if one exists. + - wlf,micd-bias-start-time : Time allowed for MICBIAS to startup prior to + performing microphone detection, specified as per the ARIZONA_MICD_TIME_XXX + defines. + - wlf,micd-rate : Delay between successive microphone detection measurements, + specified as per the ARIZONA_MICD_TIME_XXX defines. + - wlf,micd-dbtime : Microphone detection hardware debounces specified as the + number of measurements to take, valid values being 2 and 4. + - wlf,micd-timeout : Timeout for microphone detection, specified in + milliseconds. + - wlf,micd-force-micbias : Force MICBIAS continuously on during microphone + detection. + + - wlf,gpsw : Settings for the general purpose switch -- GitLab From 36a86872964609f2596d22f323070b60b17e08ef Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 Nov 2015 15:45:40 +0000 Subject: [PATCH 0537/2855] extcon: arizona: Update DT binding documentation for jack detection Add additional bindings for both inverting the polarity of the jack detection pins and allowing the use of a second jack detection pin. Note that the second jack detection pin is hard wired in the chip so can only be enabled through the binding, rather than a pin being specified. Signed-off-by: Charles Keepax Reviewed-by: Chanwoo Choi Signed-off-by: Chanwoo Choi --- Documentation/devicetree/bindings/extcon/extcon-arizona.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/extcon/extcon-arizona.txt b/Documentation/devicetree/bindings/extcon/extcon-arizona.txt index d6618119a9a85..7640a3502c67f 100644 --- a/Documentation/devicetree/bindings/extcon/extcon-arizona.txt +++ b/Documentation/devicetree/bindings/extcon/extcon-arizona.txt @@ -14,6 +14,12 @@ Optional properties: If this node is not mentioned or if the value is unknown, then headphone detection mode is set to HPDETL. + - wlf,use-jd-gpio : Use GPIO input along with JD1 for dual pin jack + detection. + - wlf,use-jd-gpio-nopull : Internal pull on GPIO is disabled when used for + jack detection. + - wlf,jd-invert : Invert the polarity of the jack detection switch + - wlf,micd-software-compare : Use a software comparison to determine mic presence - wlf,micd-detect-debounce : Additional software microphone detection -- GitLab From b9eab01125bf3cb6f5fbab1811402d16c9fcf4ec Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 11 Nov 2015 19:13:29 -0800 Subject: [PATCH 0538/2855] mtd: partitions: add module_mtd_part_parser() helper This can help eliminate some boilerplate by generating the module_init() and module_exit() functions, and by automatically assigning the module owner. Signed-off-by: Brian Norris --- drivers/mtd/mtdpart.c | 8 ++++++-- include/linux/mtd/partitions.h | 14 +++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 46dfbf5629c31..1fa3ca95d9c10 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -703,13 +703,17 @@ static struct mtd_part_parser *get_partition_parser(const char *name) #define put_partition_parser(p) do { module_put((p)->owner); } while (0) -void register_mtd_parser(struct mtd_part_parser *p) +int __register_mtd_parser(struct mtd_part_parser *p, struct module *owner) { + p->owner = owner; + spin_lock(&part_parser_lock); list_add(&p->list, &part_parsers); spin_unlock(&part_parser_lock); + + return 0; } -EXPORT_SYMBOL_GPL(register_mtd_parser); +EXPORT_SYMBOL_GPL(__register_mtd_parser); void deregister_mtd_parser(struct mtd_part_parser *p) { diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index 8421520c10eb2..d002d9b5d7977 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -73,9 +73,21 @@ struct mtd_part_parser { struct mtd_part_parser_data *); }; -extern void register_mtd_parser(struct mtd_part_parser *parser); +extern int __register_mtd_parser(struct mtd_part_parser *parser, + struct module *owner); +#define register_mtd_parser(parser) __register_mtd_parser(parser, THIS_MODULE) + extern void deregister_mtd_parser(struct mtd_part_parser *parser); +/* + * module_mtd_part_parser() - Helper macro for MTD partition parsers that don't + * do anything special in module init/exit. Each driver may only use this macro + * once, and calling it replaces module_init() and module_exit(). + */ +#define module_mtd_part_parser(__mtd_part_parser) \ + module_driver(__mtd_part_parser, register_mtd_parser, \ + deregister_mtd_parser) + int mtd_is_partition(const struct mtd_info *mtd); int mtd_add_partition(struct mtd_info *master, const char *name, long long offset, long long length); -- GitLab From b8f70badb8cd7c928f7e076b6143aeb66fe13c8b Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 11 Nov 2015 19:13:30 -0800 Subject: [PATCH 0539/2855] mtd: kill off MTD partition parser boilerplate Most parsers can be handled with our new boilerplate-reducing macro. There are a few that can't be (cmdlineparts and ofpart). Also kill off the owner assignments, since register_mtd_parser() now takes care of that. Signed-off-by: Brian Norris --- drivers/mtd/afs.c | 17 +---------------- drivers/mtd/ar7part.c | 16 +--------------- drivers/mtd/bcm47xxpart.c | 16 +--------------- drivers/mtd/bcm63xxpart.c | 16 +--------------- drivers/mtd/cmdlinepart.c | 1 - drivers/mtd/ofpart.c | 2 -- drivers/mtd/redboot.c | 17 +---------------- 7 files changed, 5 insertions(+), 80 deletions(-) diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c index a1eea50ce1800..e02dae3b739bd 100644 --- a/drivers/mtd/afs.c +++ b/drivers/mtd/afs.c @@ -256,25 +256,10 @@ static int parse_afs_partitions(struct mtd_info *mtd, } static struct mtd_part_parser afs_parser = { - .owner = THIS_MODULE, .parse_fn = parse_afs_partitions, .name = "afs", }; - -static int __init afs_parser_init(void) -{ - register_mtd_parser(&afs_parser); - return 0; -} - -static void __exit afs_parser_exit(void) -{ - deregister_mtd_parser(&afs_parser); -} - -module_init(afs_parser_init); -module_exit(afs_parser_exit); - +module_mtd_part_parser(afs_parser); MODULE_AUTHOR("ARM Ltd"); MODULE_DESCRIPTION("ARM Firmware Suite partition parser"); diff --git a/drivers/mtd/ar7part.c b/drivers/mtd/ar7part.c index 7c9172ad26210..9203b96fd7892 100644 --- a/drivers/mtd/ar7part.c +++ b/drivers/mtd/ar7part.c @@ -132,24 +132,10 @@ static int create_mtd_partitions(struct mtd_info *master, } static struct mtd_part_parser ar7_parser = { - .owner = THIS_MODULE, .parse_fn = create_mtd_partitions, .name = "ar7part", }; - -static int __init ar7_parser_init(void) -{ - register_mtd_parser(&ar7_parser); - return 0; -} - -static void __exit ar7_parser_exit(void) -{ - deregister_mtd_parser(&ar7_parser); -} - -module_init(ar7_parser_init); -module_exit(ar7_parser_exit); +module_mtd_part_parser(ar7_parser); MODULE_LICENSE("GPL"); MODULE_AUTHOR( "Felix Fietkau , " diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index c0720c1ee4c96..92a6dd18198be 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c @@ -313,24 +313,10 @@ static int bcm47xxpart_parse(struct mtd_info *master, }; static struct mtd_part_parser bcm47xxpart_mtd_parser = { - .owner = THIS_MODULE, .parse_fn = bcm47xxpart_parse, .name = "bcm47xxpart", }; - -static int __init bcm47xxpart_init(void) -{ - register_mtd_parser(&bcm47xxpart_mtd_parser); - return 0; -} - -static void __exit bcm47xxpart_exit(void) -{ - deregister_mtd_parser(&bcm47xxpart_mtd_parser); -} - -module_init(bcm47xxpart_init); -module_exit(bcm47xxpart_exit); +module_mtd_part_parser(bcm47xxpart_mtd_parser); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MTD partitioning for BCM47XX flash memories"); diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index b2443f7031c9a..cf02135320bce 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c @@ -214,24 +214,10 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, }; static struct mtd_part_parser bcm63xx_cfe_parser = { - .owner = THIS_MODULE, .parse_fn = bcm63xx_parse_cfe_partitions, .name = "bcm63xxpart", }; - -static int __init bcm63xx_cfe_parser_init(void) -{ - register_mtd_parser(&bcm63xx_cfe_parser); - return 0; -} - -static void __exit bcm63xx_cfe_parser_exit(void) -{ - deregister_mtd_parser(&bcm63xx_cfe_parser); -} - -module_init(bcm63xx_cfe_parser_init); -module_exit(bcm63xx_cfe_parser_exit); +module_mtd_part_parser(bcm63xx_cfe_parser); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Daniel Dickinson "); diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index 08f62987cc37c..420489864bc2d 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c @@ -382,7 +382,6 @@ static int __init mtdpart_setup(char *s) __setup("mtdparts=", mtdpart_setup); static struct mtd_part_parser cmdline_parser = { - .owner = THIS_MODULE, .parse_fn = parse_cmdline_partitions, .name = "cmdlinepart", }; diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index f78d2aea5545e..478538100ddd9 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c @@ -131,7 +131,6 @@ ofpart_none: } static struct mtd_part_parser ofpart_parser = { - .owner = THIS_MODULE, .parse_fn = parse_ofpart_partitions, .name = "ofpart", }; @@ -191,7 +190,6 @@ static int parse_ofoldpart_partitions(struct mtd_info *master, } static struct mtd_part_parser ofoldpart_parser = { - .owner = THIS_MODULE, .parse_fn = parse_ofoldpart_partitions, .name = "ofoldpart", }; diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c index 5da911ebdf495..11c3447eb8ff7 100644 --- a/drivers/mtd/redboot.c +++ b/drivers/mtd/redboot.c @@ -290,28 +290,13 @@ static int parse_redboot_partitions(struct mtd_info *master, } static struct mtd_part_parser redboot_parser = { - .owner = THIS_MODULE, .parse_fn = parse_redboot_partitions, .name = "RedBoot", }; +module_mtd_part_parser(redboot_parser); /* mtd parsers will request the module by parser name */ MODULE_ALIAS("RedBoot"); - -static int __init redboot_parser_init(void) -{ - register_mtd_parser(&redboot_parser); - return 0; -} - -static void __exit redboot_parser_exit(void) -{ - deregister_mtd_parser(&redboot_parser); -} - -module_init(redboot_parser_init); -module_exit(redboot_parser_exit); - MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Woodhouse "); MODULE_DESCRIPTION("Parsing code for RedBoot Flash Image System (FIS) tables"); -- GitLab From 406df15344cc54be9f6852917b19394c375c7b59 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Fri, 20 Nov 2015 10:16:06 +0100 Subject: [PATCH 0540/2855] HID: add Benjamin Tissoires as designated reviewer / co-maintainer Benjamin has been helping a lot over time with reviewing patches flowing into HID subsystem. Let's make it official. Acked-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index b16bffabe70a8..ca8cff5c2a9ea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4981,6 +4981,7 @@ F: arch/*/include/asm/suspend*.h HID CORE LAYER M: Jiri Kosina +R: Benjamin Tissoires L: linux-input@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git S: Maintained @@ -11081,6 +11082,7 @@ F: include/linux/usb/gadget* USB HID/HIDBP DRIVERS (USB KEYBOARDS, MICE, REMOTE CONTROLS, ...) M: Jiri Kosina +R: Benjamin Tissoires L: linux-usb@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git S: Maintained -- GitLab From 27b9d5a254dcbc6095404c1bab7c335419601eb8 Mon Sep 17 00:00:00 2001 From: Simon Wood Date: Thu, 19 Nov 2015 16:42:10 -0700 Subject: [PATCH 0541/2855] INPUT: xpad: switch Logitech G920 Wheel into HID mode When plugged in the Logitech G920 wheel starts with USBID 046d:c261 and behaviors as a vendor specific class. If a 'magic' byte sequence is sent the wheel will detach and reconnect as a HID device with the USBID 046d:c262. Signed-off-by: Simon Wood Acked-by: Dmitry Torokhov Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/input/joystick/xpad.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index f8850f9cb3310..af83f7ef83e4d 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -93,6 +93,7 @@ #define MAP_STICKS_TO_NULL (1 << 2) #define DANCEPAD_MAP_CONFIG (MAP_DPAD_TO_BUTTONS | \ MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL) +#define SWITCH_G920_TO_HID_MODE (1 << 3) #define XTYPE_XBOX 0 #define XTYPE_XBOX360 1 @@ -133,6 +134,7 @@ static const struct xpad_device { { 0x046d, 0xc21e, "Logitech Gamepad F510", 0, XTYPE_XBOX360 }, { 0x046d, 0xc21f, "Logitech Gamepad F710", 0, XTYPE_XBOX360 }, { 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 }, + { 0x046d, 0xc261, "Logitech G920 Driving Force Racing Wheel", SWITCH_G920_TO_HID_MODE, XTYPE_XBOXONE }, { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX }, { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX }, { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", 0, XTYPE_XBOX }, @@ -299,6 +301,7 @@ static struct usb_device_id xpad_table[] = { XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */ XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ + XPAD_XBOXONE_VENDOR(0x046d), /* Logitech X-Box One style controllers */ XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */ @@ -1021,6 +1024,19 @@ static int xpad_open(struct input_dev *dev) if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) return -EIO; + /* Logitect G920 wheel starts in XBOX mode, but is reconfigured to be HID */ + /* device with USBID of 046D:C262. Wheel will detach when 'magic' is sent. */ + if (xpad->mapping & SWITCH_G920_TO_HID_MODE) { + xpad->odata[0] = 0x0F; + xpad->odata[1] = 0x00; + xpad->odata[2] = 0x01; + xpad->odata[3] = 0x01; + xpad->odata[4] = 0x42; + xpad->irq_out->transfer_buffer_length = 5; + + return usb_submit_urb(xpad->irq_out, GFP_KERNEL); + } + if (xpad->xtype == XTYPE_XBOXONE) { /* Xbox one controller needs to be initialized. */ xpad->odata[0] = 0x05; -- GitLab From a5ce8f5b12966d34623d6c20278b5b4da7a53675 Mon Sep 17 00:00:00 2001 From: Simon Wood Date: Thu, 19 Nov 2015 16:42:11 -0700 Subject: [PATCH 0542/2855] HID: hid-logitech-hidpp: Add support for very long packets Patch add support for the 'very long' HID++ packets, which are 64 bytes in length. Signed-off-by: Simon Wood Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-hidpp.c | 59 ++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 5fd97860aec4d..0f53dc8c79b17 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -40,9 +40,11 @@ MODULE_PARM_DESC(disable_tap_to_click, #define REPORT_ID_HIDPP_SHORT 0x10 #define REPORT_ID_HIDPP_LONG 0x11 +#define REPORT_ID_HIDPP_VERY_LONG 0x12 #define HIDPP_REPORT_SHORT_LENGTH 7 #define HIDPP_REPORT_LONG_LENGTH 20 +#define HIDPP_REPORT_VERY_LONG_LENGTH 64 #define HIDPP_QUIRK_CLASS_WTP BIT(0) #define HIDPP_QUIRK_CLASS_M560 BIT(1) @@ -81,13 +83,13 @@ MODULE_PARM_DESC(disable_tap_to_click, struct fap { u8 feature_index; u8 funcindex_clientid; - u8 params[HIDPP_REPORT_LONG_LENGTH - 4U]; + u8 params[HIDPP_REPORT_VERY_LONG_LENGTH - 4U]; }; struct rap { u8 sub_id; u8 reg_address; - u8 params[HIDPP_REPORT_LONG_LENGTH - 4U]; + u8 params[HIDPP_REPORT_VERY_LONG_LENGTH - 4U]; }; struct hidpp_report { @@ -153,6 +155,9 @@ static int __hidpp_send_report(struct hid_device *hdev, case REPORT_ID_HIDPP_LONG: fields_count = HIDPP_REPORT_LONG_LENGTH; break; + case REPORT_ID_HIDPP_VERY_LONG: + fields_count = HIDPP_REPORT_VERY_LONG_LENGTH; + break; default: return -ENODEV; } @@ -217,8 +222,9 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp, goto exit; } - if (response->report_id == REPORT_ID_HIDPP_LONG && - response->fap.feature_index == HIDPP20_ERROR) { + if ((response->report_id == REPORT_ID_HIDPP_LONG || + response->report_id == REPORT_ID_HIDPP_VERY_LONG) && + response->fap.feature_index == HIDPP20_ERROR) { ret = response->fap.params[1]; dbg_hid("%s:got hidpp 2.0 error %02X\n", __func__, ret); goto exit; @@ -243,7 +249,11 @@ static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp, message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL); if (!message) return -ENOMEM; - message->report_id = REPORT_ID_HIDPP_LONG; + + if (param_count > (HIDPP_REPORT_LONG_LENGTH - 4)) + message->report_id = REPORT_ID_HIDPP_VERY_LONG; + else + message->report_id = REPORT_ID_HIDPP_LONG; message->fap.feature_index = feat_index; message->fap.funcindex_clientid = funcindex_clientid; memcpy(&message->fap.params, params, param_count); @@ -258,13 +268,23 @@ static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev, struct hidpp_report *response) { struct hidpp_report *message; - int ret; + int ret, max_count; - if ((report_id != REPORT_ID_HIDPP_SHORT) && - (report_id != REPORT_ID_HIDPP_LONG)) + switch (report_id) { + case REPORT_ID_HIDPP_SHORT: + max_count = HIDPP_REPORT_SHORT_LENGTH - 4; + break; + case REPORT_ID_HIDPP_LONG: + max_count = HIDPP_REPORT_LONG_LENGTH - 4; + break; + case REPORT_ID_HIDPP_VERY_LONG: + max_count = HIDPP_REPORT_VERY_LONG_LENGTH - 4; + break; + default: return -EINVAL; + } - if (param_count > sizeof(message->rap.params)) + if (param_count > max_count) return -EINVAL; message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL); @@ -508,10 +528,19 @@ static int hidpp_devicenametype_get_device_name(struct hidpp_device *hidpp, if (ret) return ret; - if (response.report_id == REPORT_ID_HIDPP_LONG) + switch (response.report_id) { + case REPORT_ID_HIDPP_VERY_LONG: + count = HIDPP_REPORT_VERY_LONG_LENGTH - 4; + break; + case REPORT_ID_HIDPP_LONG: count = HIDPP_REPORT_LONG_LENGTH - 4; - else + break; + case REPORT_ID_HIDPP_SHORT: count = HIDPP_REPORT_SHORT_LENGTH - 4; + break; + default: + return -EPROTO; + } if (len_buf < count) count = len_buf; @@ -1347,6 +1376,14 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report, /* Generic HID++ processing. */ switch (data[0]) { + case REPORT_ID_HIDPP_VERY_LONG: + if (size != HIDPP_REPORT_VERY_LONG_LENGTH) { + hid_err(hdev, "received hid++ report of bad size (%d)", + size); + return 1; + } + ret = hidpp_raw_hidpp_event(hidpp, data, size); + break; case REPORT_ID_HIDPP_LONG: if (size != HIDPP_REPORT_LONG_LENGTH) { hid_err(hdev, "received hid++ report of bad size (%d)", -- GitLab From 7bfd2927adcacac2930a2709a9bcc1231e5bba1c Mon Sep 17 00:00:00 2001 From: Simon Wood Date: Thu, 19 Nov 2015 16:42:12 -0700 Subject: [PATCH 0543/2855] HID: hid-logitech-hidpp: Add basic support for Logitech G920 This patch adds basic support for the Logitech G920 wheel when in HID mode. This wheel 'speaks' the HID++ protocol, and therefor is driven with hid-logitech-hidpp. At this stage the driver only shows that it can communicate with the wheel by outputting the name discovered over HID++. The normal HID functions work to give input functionality using joystick/event interface. Note: in 'hidpp_probe()' we have to start the hardware to get packets flowing, the same might apply in future for other devices which don't use the unifying protocol. Signed-off-by: Simon Wood Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 1 + drivers/hid/hid-logitech-hidpp.c | 71 +++++++++++++++++++++++++------- 3 files changed, 57 insertions(+), 16 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index c6f7a694f67a1..190260c52adc7 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1902,6 +1902,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index ac1feea51be36..269e758d450d3 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -619,6 +619,7 @@ #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2 0xc219 #define USB_DEVICE_ID_LOGITECH_G29_WHEEL 0xc24f +#define USB_DEVICE_ID_LOGITECH_G920_WHEEL 0xc262 #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286 #define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940 0xc287 diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 0f53dc8c79b17..98b8f096d7ee5 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -49,11 +49,13 @@ MODULE_PARM_DESC(disable_tap_to_click, #define HIDPP_QUIRK_CLASS_WTP BIT(0) #define HIDPP_QUIRK_CLASS_M560 BIT(1) #define HIDPP_QUIRK_CLASS_K400 BIT(2) +#define HIDPP_QUIRK_CLASS_G920 BIT(3) /* bits 2..20 are reserved for classes */ #define HIDPP_QUIRK_CONNECT_EVENTS BIT(21) #define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22) #define HIDPP_QUIRK_NO_HIDINPUT BIT(23) +#define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24) #define HIDPP_QUIRK_DELAYED_INIT (HIDPP_QUIRK_NO_HIDINPUT | \ HIDPP_QUIRK_CONNECT_EVENTS) @@ -146,8 +148,11 @@ static void hidpp_connect_event(struct hidpp_device *hidpp_dev); static int __hidpp_send_report(struct hid_device *hdev, struct hidpp_report *hidpp_report) { + struct hidpp_device *hidpp = hid_get_drvdata(hdev); int fields_count, ret; + hidpp = hid_get_drvdata(hdev); + switch (hidpp_report->report_id) { case REPORT_ID_HIDPP_SHORT: fields_count = HIDPP_REPORT_SHORT_LENGTH; @@ -168,9 +173,13 @@ static int __hidpp_send_report(struct hid_device *hdev, */ hidpp_report->device_index = 0xff; - ret = hid_hw_raw_request(hdev, hidpp_report->report_id, - (u8 *)hidpp_report, fields_count, HID_OUTPUT_REPORT, - HID_REQ_SET_REPORT); + if (hidpp->quirks & HIDPP_QUIRK_FORCE_OUTPUT_REPORTS) { + ret = hid_hw_output_report(hdev, (u8 *)hidpp_report, fields_count); + } else { + ret = hid_hw_raw_request(hdev, hidpp_report->report_id, + (u8 *)hidpp_report, fields_count, HID_OUTPUT_REPORT, + HID_REQ_SET_REPORT); + } return ret == fields_count ? 0 : -1; } @@ -1430,10 +1439,12 @@ static void hidpp_overwrite_name(struct hid_device *hdev, bool use_unifying) else name = hidpp_get_device_name(hidpp); - if (!name) + if (!name) { hid_err(hdev, "unable to retrieve the name of the device"); - else + } else { + dbg_hid("HID++: Got name: %s\n", name); snprintf(hdev->name, sizeof(hdev->name), "%s", name); + } kfree(name); } @@ -1596,6 +1607,25 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) goto hid_parse_fail; } + if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) + connect_mask &= ~HID_CONNECT_HIDINPUT; + + if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { + ret = hid_hw_start(hdev, connect_mask); + if (ret) { + hid_err(hdev, "hw start failed\n"); + goto hid_hw_start_fail; + } + ret = hid_hw_open(hdev); + if (ret < 0) { + dev_err(&hdev->dev, "%s:hid_hw_open returned error:%d\n", + __func__, ret); + hid_hw_stop(hdev); + goto hid_hw_start_fail; + } + } + + /* Allow incoming packets */ hid_device_io_start(hdev); @@ -1604,8 +1634,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) if (!connected) { ret = -ENODEV; hid_err(hdev, "Device not connected"); - hid_device_io_stop(hdev); - goto hid_parse_fail; + goto hid_hw_open_failed; } hid_info(hdev, "HID++ %u.%u device connected.\n", @@ -1618,19 +1647,18 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) { ret = wtp_get_config(hidpp); if (ret) - goto hid_parse_fail; + goto hid_hw_open_failed; } /* Block incoming packets */ hid_device_io_stop(hdev); - if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) - connect_mask &= ~HID_CONNECT_HIDINPUT; - - ret = hid_hw_start(hdev, connect_mask); - if (ret) { - hid_err(hdev, "%s:hid_hw_start returned error\n", __func__); - goto hid_hw_start_fail; + if (!(hidpp->quirks & HIDPP_QUIRK_CLASS_G920)) { + ret = hid_hw_start(hdev, connect_mask); + if (ret) { + hid_err(hdev, "%s:hid_hw_start returned error\n", __func__); + goto hid_hw_start_fail; + } } if (hidpp->quirks & HIDPP_QUIRK_CONNECT_EVENTS) { @@ -1642,6 +1670,12 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) return ret; +hid_hw_open_failed: + hid_device_io_stop(hdev); + if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { + hid_hw_close(hdev); + hid_hw_stop(hdev); + } hid_hw_start_fail: hid_parse_fail: cancel_work_sync(&hidpp->work); @@ -1655,9 +1689,11 @@ static void hidpp_remove(struct hid_device *hdev) { struct hidpp_device *hidpp = hid_get_drvdata(hdev); + if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) + hid_hw_close(hdev); + hid_hw_stop(hdev); cancel_work_sync(&hidpp->work); mutex_destroy(&hidpp->send_mutex); - hid_hw_stop(hdev); } static const struct hid_device_id hidpp_devices[] = { @@ -1685,6 +1721,9 @@ static const struct hid_device_id hidpp_devices[] = { { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, USB_VENDOR_ID_LOGITECH, HID_ANY_ID)}, + + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL), + .driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS}, {} }; -- GitLab From 7f4b49fef6ffb5021c01a915c21b3221fd521e81 Mon Sep 17 00:00:00 2001 From: Simon Wood Date: Thu, 19 Nov 2015 16:42:13 -0700 Subject: [PATCH 0544/2855] HID: hid-logitech-hidpp: Add range sysfs for Logitech G920 The G920 can adjust the amount of 'turn' it permits, this patch adds a sysfs file 'range' to control this. Signed-off-by: Simon Wood Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-hidpp.c | 140 ++++++++++++++++++++++++++++++- 1 file changed, 139 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 98b8f096d7ee5..fc553e3f948da 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -1295,6 +1295,133 @@ static int k400_connect(struct hid_device *hdev, bool connected) return k400_disable_tap_to_click(hidpp); } +/* ------------------------------------------------------------------------- */ +/* Logitech G920 Driving Force Racing Wheel for Xbox One */ +/* ------------------------------------------------------------------------- */ + +#define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123 + +/* Using session ID = 1 */ +#define CMD_G920_FORCE_GET_APERTURE 0x51 +#define CMD_G920_FORCE_SET_APERTURE 0x61 + +struct g920_private_data { + u8 force_feature; + u16 range; +}; + +#define to_hid_device(pdev) container_of(pdev, struct hid_device, dev) + +static ssize_t g920_range_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct hid_device *hid = to_hid_device(dev); + struct hidpp_device *hidpp = hid_get_drvdata(hid); + struct g920_private_data *pdata; + + pdata = hidpp->private_data; + if (!pdata) { + hid_err(hid, "Private driver data not found!\n"); + return -EINVAL; + } + + return scnprintf(buf, PAGE_SIZE, "%u\n", pdata->range); +} + +static ssize_t g920_range_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct hid_device *hid = to_hid_device(dev); + struct hidpp_device *hidpp = hid_get_drvdata(hid); + struct g920_private_data *pdata; + struct hidpp_report response; + u8 params[2]; + int ret; + u16 range = simple_strtoul(buf, NULL, 10); + + pdata = hidpp->private_data; + if (!pdata) { + hid_err(hid, "Private driver data not found!\n"); + return -EINVAL; + } + + if (range < 180) + range = 180; + else if (range > 900) + range = 900; + + params[0] = range >> 8; + params[1] = range & 0x00FF; + + ret = hidpp_send_fap_command_sync(hidpp, pdata->force_feature, + CMD_G920_FORCE_SET_APERTURE, params, 2, &response); + if (ret) + return ret; + + pdata->range = range; + return count; +} + +static DEVICE_ATTR(range, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, g920_range_show, g920_range_store); + +static int g920_allocate(struct hid_device *hdev) +{ + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + struct g920_private_data *pdata; + + pdata = devm_kzalloc(&hdev->dev, sizeof(struct g920_private_data), + GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + hidpp->private_data = pdata; + + return 0; +} + +static int g920_get_config(struct hidpp_device *hidpp) +{ + struct g920_private_data *pdata = hidpp->private_data; + struct hidpp_report response; + u8 feature_type; + u8 feature_index; + int ret; + + pdata = hidpp->private_data; + if (!pdata) { + hid_err(hidpp->hid_dev, "Private driver data not found!\n"); + return -EINVAL; + } + + /* Find feature and store for later use */ + ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK, + &feature_index, &feature_type); + if (ret) + return ret; + + pdata->force_feature = feature_index; + + /* Read current Range */ + ret = hidpp_send_fap_command_sync(hidpp, feature_index, + CMD_G920_FORCE_GET_APERTURE, NULL, 0, &response); + if (ret > 0) { + hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", + __func__, ret); + return -EPROTO; + } + if (ret) + return ret; + + pdata->range = get_unaligned_be16(&response.fap.params[0]); + + /* Create sysfs interface */ + ret = device_create_file(&(hidpp->hid_dev->dev), &dev_attr_range); + if (ret) + hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d\n", ret); + + return 0; +} + /* -------------------------------------------------------------------------- */ /* Generic HID++ devices */ /* -------------------------------------------------------------------------- */ @@ -1595,6 +1722,10 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = k400_allocate(hdev); if (ret) goto allocate_fail; + } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { + ret = g920_allocate(hdev); + if (ret) + goto allocate_fail; } INIT_WORK(&hidpp->work, delayed_work_cb); @@ -1648,6 +1779,10 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = wtp_get_config(hidpp); if (ret) goto hid_hw_open_failed; + } else if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_G920)) { + ret = g920_get_config(hidpp); + if (ret) + goto hid_hw_open_failed; } /* Block incoming packets */ @@ -1673,6 +1808,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) hid_hw_open_failed: hid_device_io_stop(hdev); if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { + device_remove_file(&hdev->dev, &dev_attr_range); hid_hw_close(hdev); hid_hw_stop(hdev); } @@ -1689,8 +1825,10 @@ static void hidpp_remove(struct hid_device *hdev) { struct hidpp_device *hidpp = hid_get_drvdata(hdev); - if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) + if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { + device_remove_file(&hdev->dev, &dev_attr_range); hid_hw_close(hdev); + } hid_hw_stop(hdev); cancel_work_sync(&hidpp->work); mutex_destroy(&hidpp->send_mutex); -- GitLab From b466c1dd73d5303a313fb0c962e4eb5879bc1336 Mon Sep 17 00:00:00 2001 From: Simon Wood Date: Thu, 19 Nov 2015 16:42:14 -0700 Subject: [PATCH 0545/2855] HID: Add vendor specific usage pages for Logitech G920 The Logitech G920 uses a couple of vendor specific usage pages, which results in incorrect number of axis/buttons being detected. This patch adds these pages to the 'ignore' list. Reported-by: Elias Vanderstuyft Signed-off-by: Simon Wood Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 4 ++++ include/linux/hid.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 2ba6bf69b7d0c..f4eeb6bcb9acb 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -960,6 +960,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel goto ignore; case HID_UP_LOGIVENDOR: + /* intentional fallback */ + case HID_UP_LOGIVENDOR2: + /* intentional fallback */ + case HID_UP_LOGIVENDOR3: goto ignore; case HID_UP_PID: diff --git a/include/linux/hid.h b/include/linux/hid.h index 251a1d382e232..a6d7a3fc2cb30 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -168,6 +168,8 @@ struct hid_item { #define HID_UP_MSVENDOR 0xff000000 #define HID_UP_CUSTOM 0x00ff0000 #define HID_UP_LOGIVENDOR 0xffbc0000 +#define HID_UP_LOGIVENDOR2 0xff090000 +#define HID_UP_LOGIVENDOR3 0xff430000 #define HID_UP_LNVENDOR 0xffa00000 #define HID_UP_SENSOR 0x00200000 -- GitLab From 0b1804e3d6ee820303cd07fd5b9579db6110840b Mon Sep 17 00:00:00 2001 From: Simon Wood Date: Thu, 19 Nov 2015 16:42:15 -0700 Subject: [PATCH 0546/2855] HID: hid-logitech-hidpp: G920 remove deadzones Ensure that the G920 is not given the default deadzones. Signed-off-by: Simon Wood Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-hidpp.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index fc553e3f948da..f2a481125522e 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -1441,6 +1441,25 @@ static int hidpp_input_mapping(struct hid_device *hdev, struct hid_input *hi, return 0; } +static int hidpp_input_mapped(struct hid_device *hdev, struct hid_input *hi, + struct hid_field *field, struct hid_usage *usage, + unsigned long **bit, int *max) +{ + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + + /* Ensure that Logitech G920 is not given a default fuzz/flat value */ + if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { + if (usage->type == EV_ABS && (usage->code == ABS_X || + usage->code == ABS_Y || usage->code == ABS_Z || + usage->code == ABS_RZ)) { + field->application = HID_GD_MULTIAXIS; + } + } + + return 0; +} + + static void hidpp_populate_input(struct hidpp_device *hidpp, struct input_dev *input, bool origin_is_hid_core) { @@ -1875,6 +1894,7 @@ static struct hid_driver hidpp_driver = { .raw_event = hidpp_raw_event, .input_configured = hidpp_input_configured, .input_mapping = hidpp_input_mapping, + .input_mapped = hidpp_input_mapped, }; module_hid_driver(hidpp_driver); -- GitLab From dfa0c5faf1b8964fa508373232b4cb597a5c226b Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Sat, 14 Nov 2015 22:08:08 +0100 Subject: [PATCH 0547/2855] HID: core: use scnprintf in modalias_show() scnprintf() exists to provide these semantics, so we might as well use it. Signed-off-by: Rasmus Villemoes Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index d5ddb75736919..3c1cfc6d99641 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2217,12 +2217,9 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a, char *buf) { struct hid_device *hdev = container_of(dev, struct hid_device, dev); - int len; - - len = snprintf(buf, PAGE_SIZE, "hid:b%04Xg%04Xv%08Xp%08X\n", - hdev->bus, hdev->group, hdev->vendor, hdev->product); - return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; + return scnprintf(buf, PAGE_SIZE, "hid:b%04Xg%04Xv%08Xp%08X\n", + hdev->bus, hdev->group, hdev->vendor, hdev->product); } static DEVICE_ATTR_RO(modalias); -- GitLab From d282e2b383e3f41a7758e8cbf3076091ef9d9447 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 19 Nov 2015 15:33:41 +0100 Subject: [PATCH 0548/2855] SCSI: initio: remove duplicate module device table The initio driver has for many years had two copies of the same module device table. One of them is also used for registering the other driver, the other one is entirely useless after the large scale cleanup that Alan Cox did back in 2007. The compiler warns about this whenever the driver is built-in: drivers/scsi/initio.c:131:29: warning: 'i91u_pci_devices' defined but not used [-Wunused-variable] This removes the extraneous table and the warning. Signed-off-by: Arnd Bergmann Fixes: 72d39fea901 ("[SCSI] initio: Convert into a real Linux driver and update to modern style") Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/initio.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index 6a926bae76b26..7a91cf3ff1732 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c @@ -110,11 +110,6 @@ #define i91u_MAXQUEUE 2 #define i91u_REVID "Initio INI-9X00U/UW SCSI device driver; Revision: 1.04a" -#define I950_DEVICE_ID 0x9500 /* Initio's inic-950 product ID */ -#define I940_DEVICE_ID 0x9400 /* Initio's inic-940 product ID */ -#define I935_DEVICE_ID 0x9401 /* Initio's inic-935 product ID */ -#define I920_DEVICE_ID 0x0002 /* Initio's other product ID */ - #ifdef DEBUG_i91u static unsigned int i91u_debug = DEBUG_DEFAULT; #endif @@ -127,17 +122,6 @@ static int setup_debug = 0; static void i91uSCBPost(u8 * pHcb, u8 * pScb); -/* PCI Devices supported by this driver */ -static struct pci_device_id i91u_pci_devices[] = { - { PCI_VENDOR_ID_INIT, I950_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_INIT, I940_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_INIT, I935_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_INIT, I920_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_DOMEX, I920_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { } -}; -MODULE_DEVICE_TABLE(pci, i91u_pci_devices); - #define DEBUG_INTERRUPT 0 #define DEBUG_QUEUE 0 #define DEBUG_STATE 0 -- GitLab From 72eaec21b0cf106dbb284cc855aef3df2dcc9cf6 Mon Sep 17 00:00:00 2001 From: LABBE Corentin Date: Fri, 20 Nov 2015 08:45:16 +0100 Subject: [PATCH 0549/2855] mtd: nand: atmel_nand: constify atmel_nand_caps structures All atmel_nand_caps are never modified, consitify them. Signed-off-by: LABBE Corentin Acked-by: Josh Wu Signed-off-by: Brian Norris --- drivers/mtd/nand/atmel_nand.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 6ecc1c1ab4375..f4e1f915c6963 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -128,7 +128,7 @@ struct atmel_nand_host { struct atmel_nfc *nfc; - struct atmel_nand_caps *caps; + const struct atmel_nand_caps *caps; bool has_pmecc; u8 pmecc_corr_cap; u16 pmecc_sector_size; @@ -2303,11 +2303,11 @@ static int atmel_nand_remove(struct platform_device *pdev) return 0; } -static struct atmel_nand_caps at91rm9200_caps = { +static const struct atmel_nand_caps at91rm9200_caps = { .pmecc_correct_erase_page = false, }; -static struct atmel_nand_caps sama5d4_caps = { +static const struct atmel_nand_caps sama5d4_caps = { .pmecc_correct_erase_page = true, }; -- GitLab From fa731ac7ea04a7d3a5c6d2f568132478c02a83b3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 20 Nov 2015 15:24:39 +0100 Subject: [PATCH 0550/2855] regulator: core: avoid unused variable warning The second argument of the mutex_lock_nested() helper is only evaluated if CONFIG_DEBUG_LOCK_ALLOC is set. Otherwise we get this build warning for the new regulator_lock_supply function: drivers/regulator/core.c: In function 'regulator_lock_supply': drivers/regulator/core.c:142:6: warning: unused variable 'i' [-Wunused-variable] To avoid the warning, this restructures the code to make it both simpler and to move the 'i++' outside of the mutex_lock_nested call, where it is now always used and the variable is not flagged as unused. We had some discussion about changing mutex_lock_nested to an inline function, which would make the code do the right thing here, but in the end decided against it, in order to guarantee that mutex_lock_nested() does not introduced overhead without CONFIG_DEBUG_LOCK_ALLOC. Signed-off-by: Arnd Bergmann Fixes: 9f01cd4a915 ("regulator: core: introduce function to lock regulators and its supplies") Link: http://permalink.gmane.org/gmane.linux.kernel/2068900 Signed-off-by: Mark Brown --- drivers/regulator/core.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 73b7683355cd0..c70017d5f74bb 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -138,18 +138,10 @@ static bool have_full_constraints(void) */ static void regulator_lock_supply(struct regulator_dev *rdev) { - struct regulator *supply; - int i = 0; - - while (1) { - mutex_lock_nested(&rdev->mutex, i++); - supply = rdev->supply; - - if (!rdev->supply) - return; + int i; - rdev = supply->rdev; - } + for (i = 0; rdev->supply; rdev = rdev->supply->rdev, i++) + mutex_lock_nested(&rdev->mutex, i); } /** -- GitLab From f307a7e9b7af401d459d26f98497c9cec766a41f Mon Sep 17 00:00:00 2001 From: James Ban Date: Thu, 19 Nov 2015 09:59:15 +0900 Subject: [PATCH 0551/2855] regulator: pv88060: new regulator driver This is the driver for the Powerventure PV88060 BUCKs and LDOs regulator. It communicates via an I2C bus to the device. Signed-off-by: James Ban Signed-off-by: Mark Brown --- .../devicetree/bindings/regulator/pv88060.txt | 124 +++++ drivers/regulator/Kconfig | 8 + drivers/regulator/Makefile | 1 + drivers/regulator/pv88060-regulator.c | 437 ++++++++++++++++++ drivers/regulator/pv88060-regulator.h | 69 +++ 5 files changed, 639 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/pv88060.txt create mode 100644 drivers/regulator/pv88060-regulator.c create mode 100644 drivers/regulator/pv88060-regulator.h diff --git a/Documentation/devicetree/bindings/regulator/pv88060.txt b/Documentation/devicetree/bindings/regulator/pv88060.txt new file mode 100644 index 0000000000000..10a6dadc008eb --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/pv88060.txt @@ -0,0 +1,124 @@ +* Powerventure Semiconductor PV88060 Voltage Regulator + +Required properties: +- compatible: "pvs,pv88060". +- reg: I2C slave address, usually 0x49. +- interrupts: the interrupt outputs of the controller +- regulators: A node that houses a sub-node for each regulator within the + device. Each sub-node is identified using the node's name, with valid + values listed below. The content of each sub-node is defined by the + standard binding for regulators; see regulator.txt. + BUCK1, LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7, SW1, SW2, SW3, SW4, + SW5, and SW6. + +Optional properties: +- Any optional property defined in regulator.txt + +Example + + pmic: pv88060@49 { + compatible = "pvs,pv88060"; + reg = <0x49>; + interrupt-parent = <&gpio>; + interrupts = <24 24>; + + regulators { + BUCK1 { + regulator-name = "buck1"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <4387500>; + regulator-min-microamp = <1496000>; + regulator-max-microamp = <4189000>; + regulator-boot-on; + }; + + LDO1 { + regulator-name = "ldo1"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3350000>; + regulator-boot-on; + }; + + LDO2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3350000>; + regulator-boot-on; + }; + + LDO3 { + regulator-name = "ldo3"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3350000>; + regulator-boot-on; + }; + + LDO4 { + regulator-name = "ldo4"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3350000>; + regulator-boot-on; + }; + + LDO5 { + regulator-name = "ldo5"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3350000>; + regulator-boot-on; + }; + + LDO6 { + regulator-name = "ldo6"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3350000>; + regulator-boot-on; + }; + + LDO7 { + regulator-name = "ldo7"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3350000>; + regulator-boot-on; + }; + + SW1 { + regulator-name = "sw1"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + SW2 { + regulator-name = "sw2"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + }; + + SW3 { + regulator-name = "sw3"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + }; + + SW4 { + regulator-name = "sw4"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + }; + + SW5 { + regulator-name = "sw5"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + }; + + SW6 { + regulator-name = "sw6"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + }; + }; \ No newline at end of file diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 8df0b0e62976d..c61f72ff1dfde 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -504,6 +504,14 @@ config REGULATOR_PFUZE100 Say y here to support the regulators found on the Freescale PFUZE100/PFUZE200 PMIC. +config REGULATOR_PV88060 + tristate "Powerventure Semiconductor PV88060 regulator" + depends on I2C + select REGMAP_I2C + help + Say y here to support the voltage regulators and convertors + PV88060 + config REGULATOR_PWM tristate "PWM voltage regulator" depends on PWM diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 0f8174913c17b..b11c8a4f873ad 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -66,6 +66,7 @@ obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o +obj-$(CONFIG_REGULATOR_PV88060) += pv88060-regulator.o obj-$(CONFIG_REGULATOR_PWM) += pwm-regulator.o obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o diff --git a/drivers/regulator/pv88060-regulator.c b/drivers/regulator/pv88060-regulator.c new file mode 100644 index 0000000000000..60b16d835df72 --- /dev/null +++ b/drivers/regulator/pv88060-regulator.c @@ -0,0 +1,437 @@ +/* + * pv88060-regulator.c - Regulator device driver for PV88060 + * Copyright (C) 2015 Powerventure Semiconductor Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pv88060-regulator.h" + +#define PV88060_MAX_REGULATORS 14 + +/* PV88060 REGULATOR IDs */ +enum { + /* BUCKs */ + PV88060_ID_BUCK1, + + /* LDOs */ + PV88060_ID_LDO1, + PV88060_ID_LDO2, + PV88060_ID_LDO3, + PV88060_ID_LDO4, + PV88060_ID_LDO5, + PV88060_ID_LDO6, + PV88060_ID_LDO7, + + /* SWTs */ + PV88060_ID_SW1, + PV88060_ID_SW2, + PV88060_ID_SW3, + PV88060_ID_SW4, + PV88060_ID_SW5, + PV88060_ID_SW6, +}; + +struct pv88060_regulator { + struct regulator_desc desc; + /* Current limiting */ + unsigned n_current_limits; + const int *current_limits; + unsigned int limit_mask; + unsigned int conf; /* buck configuration register */ +}; + +struct pv88060 { + struct device *dev; + struct regmap *regmap; + struct regulator_dev *rdev[PV88060_MAX_REGULATORS]; +}; + +static const struct regmap_config pv88060_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + +/* Current limits array (in uA) for BUCK1 + * Entry indexes corresponds to register values. + */ + +static const int pv88060_buck1_limits[] = { + 1496000, 2393000, 3291000, 4189000 +}; + +static unsigned int pv88060_buck_get_mode(struct regulator_dev *rdev) +{ + struct pv88060_regulator *info = rdev_get_drvdata(rdev); + unsigned int data; + int ret, mode = 0; + + ret = regmap_read(rdev->regmap, info->conf, &data); + if (ret < 0) + return ret; + + switch (data & PV88060_BUCK_MODE_MASK) { + case PV88060_BUCK_MODE_SYNC: + mode = REGULATOR_MODE_FAST; + break; + case PV88060_BUCK_MODE_AUTO: + mode = REGULATOR_MODE_NORMAL; + break; + case PV88060_BUCK_MODE_SLEEP: + mode = REGULATOR_MODE_STANDBY; + break; + } + + return mode; +} + +static int pv88060_buck_set_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + struct pv88060_regulator *info = rdev_get_drvdata(rdev); + int val = 0; + + switch (mode) { + case REGULATOR_MODE_FAST: + val = PV88060_BUCK_MODE_SYNC; + break; + case REGULATOR_MODE_NORMAL: + val = PV88060_BUCK_MODE_AUTO; + break; + case REGULATOR_MODE_STANDBY: + val = PV88060_BUCK_MODE_SLEEP; + break; + default: + return -EINVAL; + } + + return regmap_update_bits(rdev->regmap, info->conf, + PV88060_BUCK_MODE_MASK, val); +} + +static int pv88060_set_current_limit(struct regulator_dev *rdev, int min, + int max) +{ + struct pv88060_regulator *info = rdev_get_drvdata(rdev); + int i; + + /* search for closest to maximum */ + for (i = info->n_current_limits; i >= 0; i--) { + if (min <= info->current_limits[i] + && max >= info->current_limits[i]) { + return regmap_update_bits(rdev->regmap, + info->conf, + info->limit_mask, + i << PV88060_BUCK_ILIM_SHIFT); + } + } + + return -EINVAL; +} + +static int pv88060_get_current_limit(struct regulator_dev *rdev) +{ + struct pv88060_regulator *info = rdev_get_drvdata(rdev); + unsigned int data; + int ret; + + ret = regmap_read(rdev->regmap, info->conf, &data); + if (ret < 0) + return ret; + + data = (data & info->limit_mask) >> PV88060_BUCK_ILIM_SHIFT; + return info->current_limits[data]; +} + +static struct regulator_ops pv88060_buck_ops = { + .get_mode = pv88060_buck_get_mode, + .set_mode = pv88060_buck_set_mode, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, + .set_current_limit = pv88060_set_current_limit, + .get_current_limit = pv88060_get_current_limit, +}; + +static struct regulator_ops pv88060_ldo_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, +}; + +#define PV88060_BUCK(chip, regl_name, min, step, max, limits_array) \ +{\ + .desc = {\ + .id = chip##_ID_##regl_name,\ + .name = __stringify(chip##_##regl_name),\ + .of_match = of_match_ptr(#regl_name),\ + .regulators_node = of_match_ptr("regulators"),\ + .type = REGULATOR_VOLTAGE,\ + .owner = THIS_MODULE,\ + .ops = &pv88060_buck_ops,\ + .min_uV = min,\ + .uV_step = step,\ + .n_voltages = ((max) - (min))/(step) + 1,\ + .enable_reg = PV88060_REG_##regl_name##_CONF0,\ + .enable_mask = PV88060_BUCK_EN, \ + .vsel_reg = PV88060_REG_##regl_name##_CONF0,\ + .vsel_mask = PV88060_VBUCK_MASK,\ + },\ + .current_limits = limits_array,\ + .n_current_limits = ARRAY_SIZE(limits_array),\ + .limit_mask = PV88060_BUCK_ILIM_MASK, \ + .conf = PV88060_REG_##regl_name##_CONF1,\ +} + +#define PV88060_LDO(chip, regl_name, min, step, max) \ +{\ + .desc = {\ + .id = chip##_ID_##regl_name,\ + .name = __stringify(chip##_##regl_name),\ + .of_match = of_match_ptr(#regl_name),\ + .regulators_node = of_match_ptr("regulators"),\ + .type = REGULATOR_VOLTAGE,\ + .owner = THIS_MODULE,\ + .ops = &pv88060_ldo_ops,\ + .min_uV = min, \ + .uV_step = step, \ + .n_voltages = (step) ? ((max - min) / step + 1) : 1, \ + .enable_reg = PV88060_REG_##regl_name##_CONF, \ + .enable_mask = PV88060_LDO_EN, \ + .vsel_reg = PV88060_REG_##regl_name##_CONF, \ + .vsel_mask = PV88060_VLDO_MASK, \ + },\ +} + +#define PV88060_SW(chip, regl_name, max) \ +{\ + .desc = {\ + .id = chip##_ID_##regl_name,\ + .name = __stringify(chip##_##regl_name),\ + .of_match = of_match_ptr(#regl_name),\ + .regulators_node = of_match_ptr("regulators"),\ + .type = REGULATOR_VOLTAGE,\ + .owner = THIS_MODULE,\ + .ops = &pv88060_ldo_ops,\ + .min_uV = max,\ + .uV_step = 0,\ + .n_voltages = 1,\ + .enable_reg = PV88060_REG_##regl_name##_CONF,\ + .enable_mask = PV88060_SW_EN,\ + },\ +} + +static const struct pv88060_regulator pv88060_regulator_info[] = { + PV88060_BUCK(PV88060, BUCK1, 2800000, 12500, 4387500, + pv88060_buck1_limits), + PV88060_LDO(PV88060, LDO1, 1200000, 50000, 3350000), + PV88060_LDO(PV88060, LDO2, 1200000, 50000, 3350000), + PV88060_LDO(PV88060, LDO3, 1200000, 50000, 3350000), + PV88060_LDO(PV88060, LDO4, 1200000, 50000, 3350000), + PV88060_LDO(PV88060, LDO5, 1200000, 50000, 3350000), + PV88060_LDO(PV88060, LDO6, 1200000, 50000, 3350000), + PV88060_LDO(PV88060, LDO7, 1200000, 50000, 3350000), + PV88060_SW(PV88060, SW1, 5000000), + PV88060_SW(PV88060, SW2, 5000000), + PV88060_SW(PV88060, SW3, 5000000), + PV88060_SW(PV88060, SW4, 5000000), + PV88060_SW(PV88060, SW5, 5000000), + PV88060_SW(PV88060, SW6, 5000000), +}; + +static irqreturn_t pv88060_irq_handler(int irq, void *data) +{ + struct pv88060 *chip = data; + int i, reg_val, err, ret = IRQ_NONE; + + err = regmap_read(chip->regmap, PV88060_REG_EVENT_A, ®_val); + if (err < 0) + goto error_i2c; + + if (reg_val & PV88060_E_VDD_FLT) { + for (i = 0; i < PV88060_MAX_REGULATORS; i++) { + if (chip->rdev[i] != NULL) { + regulator_notifier_call_chain(chip->rdev[i], + REGULATOR_EVENT_UNDER_VOLTAGE, + NULL); + } + } + + err = regmap_update_bits(chip->regmap, PV88060_REG_EVENT_A, + PV88060_E_VDD_FLT, PV88060_E_VDD_FLT); + if (err < 0) + goto error_i2c; + + ret = IRQ_HANDLED; + } + + if (reg_val & PV88060_E_OVER_TEMP) { + for (i = 0; i < PV88060_MAX_REGULATORS; i++) { + if (chip->rdev[i] != NULL) { + regulator_notifier_call_chain(chip->rdev[i], + REGULATOR_EVENT_OVER_TEMP, + NULL); + } + } + + err = regmap_update_bits(chip->regmap, PV88060_REG_EVENT_A, + PV88060_E_OVER_TEMP, PV88060_E_OVER_TEMP); + if (err < 0) + goto error_i2c; + + ret = IRQ_HANDLED; + } + + return ret; + +error_i2c: + dev_err(chip->dev, "I2C error : %d\n", err); + return IRQ_NONE; +} + +/* + * I2C driver interface functions + */ +static int pv88060_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev); + struct pv88060 *chip; + struct regulator_config config = { }; + int error, i, ret = 0; + + chip = devm_kzalloc(&i2c->dev, sizeof(struct pv88060), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->dev = &i2c->dev; + chip->regmap = devm_regmap_init_i2c(i2c, &pv88060_regmap_config); + if (IS_ERR(chip->regmap)) { + error = PTR_ERR(chip->regmap); + dev_err(chip->dev, "Failed to allocate register map: %d\n", + error); + return error; + } + + i2c_set_clientdata(i2c, chip); + + if (i2c->irq != 0) { + ret = regmap_write(chip->regmap, PV88060_REG_MASK_A, 0xFF); + if (ret < 0) { + dev_err(chip->dev, + "Failed to mask A reg: %d\n", ret); + return ret; + } + + regmap_write(chip->regmap, PV88060_REG_MASK_B, 0xFF); + if (ret < 0) { + dev_err(chip->dev, + "Failed to mask B reg: %d\n", ret); + return ret; + } + + regmap_write(chip->regmap, PV88060_REG_MASK_C, 0xFF); + if (ret < 0) { + dev_err(chip->dev, + "Failed to mask C reg: %d\n", ret); + return ret; + } + + ret = request_threaded_irq(i2c->irq, NULL, + pv88060_irq_handler, + IRQF_TRIGGER_LOW|IRQF_ONESHOT, + "pv88060", chip); + if (ret != 0) { + dev_err(chip->dev, "Failed to request IRQ: %d\n", + i2c->irq); + return ret; + } + + ret = regmap_update_bits(chip->regmap, PV88060_REG_MASK_A, + PV88060_M_VDD_FLT | PV88060_M_OVER_TEMP, 0); + if (ret < 0) { + dev_err(chip->dev, + "Failed to update mask reg: %d\n", ret); + return ret; + } + + } else { + dev_warn(chip->dev, "No IRQ configured\n"); + } + + config.dev = chip->dev; + config.regmap = chip->regmap; + + for (i = 0; i < PV88060_MAX_REGULATORS; i++) { + if (init_data) + config.init_data = &init_data[i]; + + config.driver_data = (void *)&pv88060_regulator_info[i]; + chip->rdev[i] = devm_regulator_register(chip->dev, + &pv88060_regulator_info[i].desc, &config); + if (IS_ERR(chip->rdev[i])) { + dev_err(chip->dev, + "Failed to register PV88060 regulator\n"); + return PTR_ERR(chip->rdev[i]); + } + } + + return 0; +} + +static const struct i2c_device_id pv88060_i2c_id[] = { + {"pv88060", 0}, + {}, +}; +MODULE_DEVICE_TABLE(i2c, pv88060_i2c_id); + +#ifdef CONFIG_OF +static const struct of_device_id pv88060_dt_ids[] = { + { .compatible = "pvs,pv88060", .data = &pv88060_i2c_id[0] }, + {}, +}; +MODULE_DEVICE_TABLE(of, pv88060_dt_ids); +#endif + +static struct i2c_driver pv88060_regulator_driver = { + .driver = { + .name = "pv88060", + .of_match_table = of_match_ptr(pv88060_dt_ids), + }, + .probe = pv88060_i2c_probe, + .id_table = pv88060_i2c_id, +}; + +module_i2c_driver(pv88060_regulator_driver); + +MODULE_AUTHOR("James Ban "); +MODULE_DESCRIPTION("Regulator device driver for Powerventure PV88060"); +MODULE_LICENSE("GPL"); diff --git a/drivers/regulator/pv88060-regulator.h b/drivers/regulator/pv88060-regulator.h new file mode 100644 index 0000000000000..02ca9203a172a --- /dev/null +++ b/drivers/regulator/pv88060-regulator.h @@ -0,0 +1,69 @@ +/* + * pv88060-regulator.h - Regulator definitions for PV88060 + * Copyright (C) 2015 Powerventure Semiconductor Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __PV88060_REGISTERS_H__ +#define __PV88060_REGISTERS_H__ + +/* System Control and Event Registers */ +#define PV88060_REG_EVENT_A 0x04 +#define PV88060_REG_MASK_A 0x08 +#define PV88060_REG_MASK_B 0x09 +#define PV88060_REG_MASK_C 0x0A + +/* Regulator Registers */ +#define PV88060_REG_BUCK1_CONF0 0x1B +#define PV88060_REG_BUCK1_CONF1 0x1C +#define PV88060_REG_LDO1_CONF 0x1D +#define PV88060_REG_LDO2_CONF 0x1E +#define PV88060_REG_LDO3_CONF 0x1F +#define PV88060_REG_LDO4_CONF 0x20 +#define PV88060_REG_LDO5_CONF 0x21 +#define PV88060_REG_LDO6_CONF 0x22 +#define PV88060_REG_LDO7_CONF 0x23 + +#define PV88060_REG_SW1_CONF 0x3B +#define PV88060_REG_SW2_CONF 0x3C +#define PV88060_REG_SW3_CONF 0x3D +#define PV88060_REG_SW4_CONF 0x3E +#define PV88060_REG_SW5_CONF 0x3F +#define PV88060_REG_SW6_CONF 0x40 + +/* PV88060_REG_EVENT_A (addr=0x04) */ +#define PV88060_E_VDD_FLT 0x01 +#define PV88060_E_OVER_TEMP 0x02 + +/* PV88060_REG_MASK_A (addr=0x08) */ +#define PV88060_M_VDD_FLT 0x01 +#define PV88060_M_OVER_TEMP 0x02 + +/* PV88060_REG_BUCK1_CONF0 (addr=0x1B) */ +#define PV88060_BUCK_EN 0x80 +#define PV88060_VBUCK_MASK 0x7F +/* PV88060_REG_LDO1/2/3/4/5/6/7_CONT */ +#define PV88060_LDO_EN 0x40 +#define PV88060_VLDO_MASK 0x3F +/* PV88060_REG_SW1/2/3/4/5_CONF */ +#define PV88060_SW_EN 0x80 + +/* PV88060_REG_BUCK1_CONF1 (addr=0x1C) */ +#define PV88060_BUCK_ILIM_SHIFT 2 +#define PV88060_BUCK_ILIM_MASK 0x0C +#define PV88060_BUCK_MODE_SHIFT 0 +#define PV88060_BUCK_MODE_MASK 0x03 +#define PV88060_BUCK_MODE_SLEEP 0x00 +#define PV88060_BUCK_MODE_AUTO 0x01 +#define PV88060_BUCK_MODE_SYNC 0x02 + +#endif /* __PV88060_REGISTERS_H__ */ -- GitLab From d599af65fda384b5e91780485f243c9f2d3e757d Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Fri, 20 Nov 2015 13:55:21 +0200 Subject: [PATCH 0552/2855] spi: pxa2xx: Remove redundant call to lpss_ssp_setup() in probe Commit 8b136baa5892 ("spi: pxa2xx: Detect number of enabled Intel LPSS SPI chip select signals") added a block where lpss_ssp_setup() gets called again for Intel LPSS SPI host controllers before checking number of chip selects from the capabilities register. There is no point in calling the function twice in probe so remove the first call. Reported-by: Aaron Lu Signed-off-by: Mika Westerberg Acked-by: Jarkko Nikula Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index b25dc71b0ea91..ab9914ad8365a 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1567,9 +1567,6 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) if (!is_quark_x1000_ssp(drv_data)) pxa2xx_spi_write(drv_data, SSPSP, 0); - if (is_lpss_ssp(drv_data)) - lpss_ssp_setup(drv_data); - if (is_lpss_ssp(drv_data)) { lpss_ssp_setup(drv_data); config = lpss_get_config(drv_data); -- GitLab From 3ce351b5354a206e92ccd2d7f30df9c8b7ae5ed1 Mon Sep 17 00:00:00 2001 From: Bayi Cheng Date: Wed, 18 Nov 2015 11:30:02 +0800 Subject: [PATCH 0553/2855] mtd: mtk-nor: new Mediatek serial flash controller driver Add spi nor flash driver for mediatek controller Signed-off-by: Bayi Cheng Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/Kconfig | 7 + drivers/mtd/spi-nor/Makefile | 1 + drivers/mtd/spi-nor/mtk-quadspi.c | 486 ++++++++++++++++++++++++++++++ 3 files changed, 494 insertions(+) create mode 100644 drivers/mtd/spi-nor/mtk-quadspi.c diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig index 2fe2a7e90fa9f..0dc927540b3d1 100644 --- a/drivers/mtd/spi-nor/Kconfig +++ b/drivers/mtd/spi-nor/Kconfig @@ -7,6 +7,13 @@ menuconfig MTD_SPI_NOR if MTD_SPI_NOR +config MTD_MT81xx_NOR + tristate "Mediatek MT81xx SPI NOR flash controller" + help + This enables access to SPI NOR flash, using MT81xx SPI NOR flash + controller. This controller does not support generic SPI BUS, it only + supports SPI NOR Flash. + config MTD_SPI_NOR_USE_4K_SECTORS bool "Use small 4096 B erase sectors" default y diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index e53333ef85820..0bf3a7f816755 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o +obj-$(CONFIG_MTD_MT81xx_NOR) += mtk-quadspi.o obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o diff --git a/drivers/mtd/spi-nor/mtk-quadspi.c b/drivers/mtd/spi-nor/mtk-quadspi.c new file mode 100644 index 0000000000000..dd269650cd164 --- /dev/null +++ b/drivers/mtd/spi-nor/mtk-quadspi.c @@ -0,0 +1,486 @@ +/* + * Copyright (c) 2015 MediaTek Inc. + * Author: Bayi Cheng + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MTK_NOR_CMD_REG 0x00 +#define MTK_NOR_CNT_REG 0x04 +#define MTK_NOR_RDSR_REG 0x08 +#define MTK_NOR_RDATA_REG 0x0c +#define MTK_NOR_RADR0_REG 0x10 +#define MTK_NOR_RADR1_REG 0x14 +#define MTK_NOR_RADR2_REG 0x18 +#define MTK_NOR_WDATA_REG 0x1c +#define MTK_NOR_PRGDATA0_REG 0x20 +#define MTK_NOR_PRGDATA1_REG 0x24 +#define MTK_NOR_PRGDATA2_REG 0x28 +#define MTK_NOR_PRGDATA3_REG 0x2c +#define MTK_NOR_PRGDATA4_REG 0x30 +#define MTK_NOR_PRGDATA5_REG 0x34 +#define MTK_NOR_SHREG0_REG 0x38 +#define MTK_NOR_SHREG1_REG 0x3c +#define MTK_NOR_SHREG2_REG 0x40 +#define MTK_NOR_SHREG3_REG 0x44 +#define MTK_NOR_SHREG4_REG 0x48 +#define MTK_NOR_SHREG5_REG 0x4c +#define MTK_NOR_SHREG6_REG 0x50 +#define MTK_NOR_SHREG7_REG 0x54 +#define MTK_NOR_SHREG8_REG 0x58 +#define MTK_NOR_SHREG9_REG 0x5c +#define MTK_NOR_CFG1_REG 0x60 +#define MTK_NOR_CFG2_REG 0x64 +#define MTK_NOR_CFG3_REG 0x68 +#define MTK_NOR_STATUS0_REG 0x70 +#define MTK_NOR_STATUS1_REG 0x74 +#define MTK_NOR_STATUS2_REG 0x78 +#define MTK_NOR_STATUS3_REG 0x7c +#define MTK_NOR_FLHCFG_REG 0x84 +#define MTK_NOR_TIME_REG 0x94 +#define MTK_NOR_PP_DATA_REG 0x98 +#define MTK_NOR_PREBUF_STUS_REG 0x9c +#define MTK_NOR_DELSEL0_REG 0xa0 +#define MTK_NOR_DELSEL1_REG 0xa4 +#define MTK_NOR_INTRSTUS_REG 0xa8 +#define MTK_NOR_INTREN_REG 0xac +#define MTK_NOR_CHKSUM_CTL_REG 0xb8 +#define MTK_NOR_CHKSUM_REG 0xbc +#define MTK_NOR_CMD2_REG 0xc0 +#define MTK_NOR_WRPROT_REG 0xc4 +#define MTK_NOR_RADR3_REG 0xc8 +#define MTK_NOR_DUAL_REG 0xcc +#define MTK_NOR_DELSEL2_REG 0xd0 +#define MTK_NOR_DELSEL3_REG 0xd4 +#define MTK_NOR_DELSEL4_REG 0xd8 + +/* commands for mtk nor controller */ +#define MTK_NOR_READ_CMD 0x0 +#define MTK_NOR_RDSR_CMD 0x2 +#define MTK_NOR_PRG_CMD 0x4 +#define MTK_NOR_WR_CMD 0x10 +#define MTK_NOR_PIO_WR_CMD 0x90 +#define MTK_NOR_WRSR_CMD 0x20 +#define MTK_NOR_PIO_READ_CMD 0x81 +#define MTK_NOR_WR_BUF_ENABLE 0x1 +#define MTK_NOR_WR_BUF_DISABLE 0x0 +#define MTK_NOR_ENABLE_SF_CMD 0x30 +#define MTK_NOR_DUAD_ADDR_EN 0x8 +#define MTK_NOR_QUAD_READ_EN 0x4 +#define MTK_NOR_DUAL_ADDR_EN 0x2 +#define MTK_NOR_DUAL_READ_EN 0x1 +#define MTK_NOR_DUAL_DISABLE 0x0 +#define MTK_NOR_FAST_READ 0x1 + +#define SFLASH_WRBUF_SIZE 128 + +/* Can shift up to 48 bits (6 bytes) of TX/RX */ +#define MTK_NOR_MAX_RX_TX_SHIFT 6 +/* can shift up to 56 bits (7 bytes) transfer by MTK_NOR_PRG_CMD */ +#define MTK_NOR_MAX_SHIFT 7 + +/* Helpers for accessing the program data / shift data registers */ +#define MTK_NOR_PRG_REG(n) (MTK_NOR_PRGDATA0_REG + 4 * (n)) +#define MTK_NOR_SHREG(n) (MTK_NOR_SHREG0_REG + 4 * (n)) + +struct mt8173_nor { + struct spi_nor nor; + struct device *dev; + void __iomem *base; /* nor flash base address */ + struct clk *spi_clk; + struct clk *nor_clk; +}; + +static void mt8173_nor_set_read_mode(struct mt8173_nor *mt8173_nor) +{ + struct spi_nor *nor = &mt8173_nor->nor; + + switch (nor->flash_read) { + case SPI_NOR_FAST: + writeb(nor->read_opcode, mt8173_nor->base + + MTK_NOR_PRGDATA3_REG); + writeb(MTK_NOR_FAST_READ, mt8173_nor->base + + MTK_NOR_CFG1_REG); + break; + case SPI_NOR_DUAL: + writeb(nor->read_opcode, mt8173_nor->base + + MTK_NOR_PRGDATA3_REG); + writeb(MTK_NOR_DUAL_READ_EN, mt8173_nor->base + + MTK_NOR_DUAL_REG); + break; + case SPI_NOR_QUAD: + writeb(nor->read_opcode, mt8173_nor->base + + MTK_NOR_PRGDATA4_REG); + writeb(MTK_NOR_QUAD_READ_EN, mt8173_nor->base + + MTK_NOR_DUAL_REG); + break; + default: + writeb(MTK_NOR_DUAL_DISABLE, mt8173_nor->base + + MTK_NOR_DUAL_REG); + break; + } +} + +static int mt8173_nor_execute_cmd(struct mt8173_nor *mt8173_nor, u8 cmdval) +{ + int reg; + u8 val = cmdval & 0x1f; + + writeb(cmdval, mt8173_nor->base + MTK_NOR_CMD_REG); + return readl_poll_timeout(mt8173_nor->base + MTK_NOR_CMD_REG, reg, + !(reg & val), 100, 10000); +} + +static int mt8173_nor_do_tx_rx(struct mt8173_nor *mt8173_nor, u8 op, + u8 *tx, int txlen, u8 *rx, int rxlen) +{ + int len = 1 + txlen + rxlen; + int i, ret, idx; + + if (len > MTK_NOR_MAX_SHIFT) + return -EINVAL; + + writeb(len * 8, mt8173_nor->base + MTK_NOR_CNT_REG); + + /* start at PRGDATA5, go down to PRGDATA0 */ + idx = MTK_NOR_MAX_RX_TX_SHIFT - 1; + + /* opcode */ + writeb(op, mt8173_nor->base + MTK_NOR_PRG_REG(idx)); + idx--; + + /* program TX data */ + for (i = 0; i < txlen; i++, idx--) + writeb(tx[i], mt8173_nor->base + MTK_NOR_PRG_REG(idx)); + + /* clear out rest of TX registers */ + while (idx >= 0) { + writeb(0, mt8173_nor->base + MTK_NOR_PRG_REG(idx)); + idx--; + } + + ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PRG_CMD); + if (ret) + return ret; + + /* restart at first RX byte */ + idx = rxlen - 1; + + /* read out RX data */ + for (i = 0; i < rxlen; i++, idx--) + rx[i] = readb(mt8173_nor->base + MTK_NOR_SHREG(idx)); + + return 0; +} + +/* Do a WRSR (Write Status Register) command */ +static int mt8173_nor_wr_sr(struct mt8173_nor *mt8173_nor, u8 sr) +{ + writeb(sr, mt8173_nor->base + MTK_NOR_PRGDATA5_REG); + writeb(8, mt8173_nor->base + MTK_NOR_CNT_REG); + return mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_WRSR_CMD); +} + +static int mt8173_nor_write_buffer_enable(struct mt8173_nor *mt8173_nor) +{ + u8 reg; + + /* the bit0 of MTK_NOR_CFG2_REG is pre-fetch buffer + * 0: pre-fetch buffer use for read + * 1: pre-fetch buffer use for page program + */ + writel(MTK_NOR_WR_BUF_ENABLE, mt8173_nor->base + MTK_NOR_CFG2_REG); + return readb_poll_timeout(mt8173_nor->base + MTK_NOR_CFG2_REG, reg, + 0x01 == (reg & 0x01), 100, 10000); +} + +static int mt8173_nor_write_buffer_disable(struct mt8173_nor *mt8173_nor) +{ + u8 reg; + + writel(MTK_NOR_WR_BUF_DISABLE, mt8173_nor->base + MTK_NOR_CFG2_REG); + return readb_poll_timeout(mt8173_nor->base + MTK_NOR_CFG2_REG, reg, + MTK_NOR_WR_BUF_DISABLE == (reg & 0x1), 100, + 10000); +} + +static void mt8173_nor_set_addr(struct mt8173_nor *mt8173_nor, u32 addr) +{ + int i; + + for (i = 0; i < 3; i++) { + writeb(addr & 0xff, mt8173_nor->base + MTK_NOR_RADR0_REG + i * 4); + addr >>= 8; + } + /* Last register is non-contiguous */ + writeb(addr & 0xff, mt8173_nor->base + MTK_NOR_RADR3_REG); +} + +static int mt8173_nor_read(struct spi_nor *nor, loff_t from, size_t length, + size_t *retlen, u_char *buffer) +{ + int i, ret; + int addr = (int)from; + u8 *buf = (u8 *)buffer; + struct mt8173_nor *mt8173_nor = nor->priv; + + /* set mode for fast read mode ,dual mode or quad mode */ + mt8173_nor_set_read_mode(mt8173_nor); + mt8173_nor_set_addr(mt8173_nor, addr); + + for (i = 0; i < length; i++, (*retlen)++) { + ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PIO_READ_CMD); + if (ret < 0) + return ret; + buf[i] = readb(mt8173_nor->base + MTK_NOR_RDATA_REG); + } + return 0; +} + +static int mt8173_nor_write_single_byte(struct mt8173_nor *mt8173_nor, + int addr, int length, u8 *data) +{ + int i, ret; + + mt8173_nor_set_addr(mt8173_nor, addr); + + for (i = 0; i < length; i++) { + ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PIO_WR_CMD); + if (ret < 0) + return ret; + writeb(*data++, mt8173_nor->base + MTK_NOR_WDATA_REG); + } + return 0; +} + +static int mt8173_nor_write_buffer(struct mt8173_nor *mt8173_nor, int addr, + const u8 *buf) +{ + int i, bufidx, data; + + mt8173_nor_set_addr(mt8173_nor, addr); + + bufidx = 0; + for (i = 0; i < SFLASH_WRBUF_SIZE; i += 4) { + data = buf[bufidx + 3]<<24 | buf[bufidx + 2]<<16 | + buf[bufidx + 1]<<8 | buf[bufidx]; + bufidx += 4; + writel(data, mt8173_nor->base + MTK_NOR_PP_DATA_REG); + } + return mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_WR_CMD); +} + +static void mt8173_nor_write(struct spi_nor *nor, loff_t to, size_t len, + size_t *retlen, const u_char *buf) +{ + int ret; + struct mt8173_nor *mt8173_nor = nor->priv; + + ret = mt8173_nor_write_buffer_enable(mt8173_nor); + if (ret < 0) + dev_warn(mt8173_nor->dev, "write buffer enable failed!\n"); + + while (len >= SFLASH_WRBUF_SIZE) { + ret = mt8173_nor_write_buffer(mt8173_nor, to, buf); + if (ret < 0) + dev_err(mt8173_nor->dev, "write buffer failed!\n"); + len -= SFLASH_WRBUF_SIZE; + to += SFLASH_WRBUF_SIZE; + buf += SFLASH_WRBUF_SIZE; + (*retlen) += SFLASH_WRBUF_SIZE; + } + ret = mt8173_nor_write_buffer_disable(mt8173_nor); + if (ret < 0) + dev_warn(mt8173_nor->dev, "write buffer disable failed!\n"); + + if (len) { + ret = mt8173_nor_write_single_byte(mt8173_nor, to, (int)len, + (u8 *)buf); + if (ret < 0) + dev_err(mt8173_nor->dev, "write single byte failed!\n"); + (*retlen) += len; + } +} + +static int mt8173_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len) +{ + int ret; + struct mt8173_nor *mt8173_nor = nor->priv; + + switch (opcode) { + case SPINOR_OP_RDSR: + ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_RDSR_CMD); + if (ret < 0) + return ret; + if (len == 1) + *buf = readb(mt8173_nor->base + MTK_NOR_RDSR_REG); + else + dev_err(mt8173_nor->dev, "len should be 1 for read status!\n"); + break; + default: + ret = mt8173_nor_do_tx_rx(mt8173_nor, opcode, NULL, 0, buf, len); + break; + } + return ret; +} + +static int mt8173_nor_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, + int len) +{ + int ret; + struct mt8173_nor *mt8173_nor = nor->priv; + + switch (opcode) { + case SPINOR_OP_WRSR: + /* We only handle 1 byte */ + ret = mt8173_nor_wr_sr(mt8173_nor, *buf); + break; + default: + ret = mt8173_nor_do_tx_rx(mt8173_nor, opcode, buf, len, NULL, 0); + if (ret) + dev_warn(mt8173_nor->dev, "write reg failure!\n"); + break; + } + return ret; +} + +static int __init mtk_nor_init(struct mt8173_nor *mt8173_nor, + struct device_node *flash_node) +{ + int ret; + struct spi_nor *nor; + + /* initialize controller to accept commands */ + writel(MTK_NOR_ENABLE_SF_CMD, mt8173_nor->base + MTK_NOR_WRPROT_REG); + + nor = &mt8173_nor->nor; + nor->dev = mt8173_nor->dev; + nor->priv = mt8173_nor; + spi_nor_set_flash_node(nor, flash_node); + + /* fill the hooks to spi nor */ + nor->read = mt8173_nor_read; + nor->read_reg = mt8173_nor_read_reg; + nor->write = mt8173_nor_write; + nor->write_reg = mt8173_nor_write_reg; + nor->mtd.owner = THIS_MODULE; + nor->mtd.name = "mtk_nor"; + /* initialized with NULL */ + ret = spi_nor_scan(nor, NULL, SPI_NOR_DUAL); + if (ret) + return ret; + + return mtd_device_register(&nor->mtd, NULL, 0); +} + +static int mtk_nor_drv_probe(struct platform_device *pdev) +{ + struct device_node *flash_np; + struct resource *res; + int ret; + struct mt8173_nor *mt8173_nor; + + if (!pdev->dev.of_node) { + dev_err(&pdev->dev, "No DT found\n"); + return -EINVAL; + } + + mt8173_nor = devm_kzalloc(&pdev->dev, sizeof(*mt8173_nor), GFP_KERNEL); + if (!mt8173_nor) + return -ENOMEM; + platform_set_drvdata(pdev, mt8173_nor); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + mt8173_nor->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(mt8173_nor->base)) + return PTR_ERR(mt8173_nor->base); + + mt8173_nor->spi_clk = devm_clk_get(&pdev->dev, "spi"); + if (IS_ERR(mt8173_nor->spi_clk)) + return PTR_ERR(mt8173_nor->spi_clk); + + mt8173_nor->nor_clk = devm_clk_get(&pdev->dev, "sf"); + if (IS_ERR(mt8173_nor->nor_clk)) + return PTR_ERR(mt8173_nor->nor_clk); + + mt8173_nor->dev = &pdev->dev; + ret = clk_prepare_enable(mt8173_nor->spi_clk); + if (ret) + return ret; + + ret = clk_prepare_enable(mt8173_nor->nor_clk); + if (ret) { + clk_disable_unprepare(mt8173_nor->spi_clk); + return ret; + } + /* only support one attached flash */ + flash_np = of_get_next_available_child(pdev->dev.of_node, NULL); + if (!flash_np) { + dev_err(&pdev->dev, "no SPI flash device to configure\n"); + ret = -ENODEV; + goto nor_free; + } + ret = mtk_nor_init(mt8173_nor, flash_np); + +nor_free: + if (ret) { + clk_disable_unprepare(mt8173_nor->spi_clk); + clk_disable_unprepare(mt8173_nor->nor_clk); + } + return ret; +} + +static int mtk_nor_drv_remove(struct platform_device *pdev) +{ + struct mt8173_nor *mt8173_nor = platform_get_drvdata(pdev); + + clk_disable_unprepare(mt8173_nor->spi_clk); + clk_disable_unprepare(mt8173_nor->nor_clk); + return 0; +} + +static const struct of_device_id mtk_nor_of_ids[] = { + { .compatible = "mediatek,mt8173-nor"}, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, mtk_nor_of_ids); + +static struct platform_driver mtk_nor_driver = { + .probe = mtk_nor_drv_probe, + .remove = mtk_nor_drv_remove, + .driver = { + .name = "mtk-nor", + .of_match_table = mtk_nor_of_ids, + }, +}; + +module_platform_driver(mtk_nor_driver); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("MediaTek SPI NOR Flash Driver"); -- GitLab From fbdb5d78ce7085966eb958ce8e003b1f8c2aaad4 Mon Sep 17 00:00:00 2001 From: "leilk.liu@mediatek.com" Date: Fri, 20 Nov 2015 10:21:16 +0800 Subject: [PATCH 0554/2855] spi: mediatek: update document devicetree bindings to fix syntax error This patch updates document devicetree bindings to fix syntax error. Signed-off-by: Leilk Liu Acked-by: Rob Herring Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/spi-mt65xx.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt index ce363c923f446..fba8334bfd179 100644 --- a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt +++ b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt @@ -32,7 +32,7 @@ Optional properties: -cs-gpios: see spi-bus.txt, only required for MT8173. - mediatek,pad-select: specify which pins group(ck/mi/mo/cs) spi - controller used. This is a array, the element value should be 0~3, + controller used. This is an array, the element value should be 0~3, only required for MT8173. 0: specify GPIO69,70,71,72 for spi pins. 1: specify GPIO102,103,104,105 for spi pins. -- GitLab From 6e6a9cd461073256977bc8c91aba3c847e80fbd2 Mon Sep 17 00:00:00 2001 From: "leilk.liu@mediatek.com" Date: Fri, 20 Nov 2015 10:21:17 +0800 Subject: [PATCH 0555/2855] spi: mediatek: remove unrequired description cs-gpios isn't required with patch "spi: mediatek: single device does not require cs_gpios", so modify the description. Signed-off-by: Leilk Liu Acked-by: Rob Herring Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/spi-mt65xx.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt index fba8334bfd179..60a183c16e6e8 100644 --- a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt +++ b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt @@ -29,7 +29,7 @@ Required properties: muxes clock, and "spi-clk" for the clock gate. Optional properties: --cs-gpios: see spi-bus.txt, only required for MT8173. +-cs-gpios: see spi-bus.txt. - mediatek,pad-select: specify which pins group(ck/mi/mo/cs) spi controller used. This is an array, the element value should be 0~3, -- GitLab From 4c3dbd35d4369ddb0f0e26dd329a6aab870703e2 Mon Sep 17 00:00:00 2001 From: "leilk.liu@mediatek.com" Date: Fri, 20 Nov 2015 10:21:18 +0800 Subject: [PATCH 0556/2855] spi: mediatek: remove needless pair of writel()/readl() It's not need to re-read and re-write SPI_CMD_REG, so remove it. Signed-off-by: Leilk Liu Reviewed-by: Matthias Brugger Signed-off-by: Mark Brown --- drivers/spi/spi-mt65xx.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index 563954a614242..2b3fcb8ca3251 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c @@ -154,9 +154,6 @@ static int mtk_spi_prepare_message(struct spi_master *master, reg_val |= SPI_CMD_CPOL; else reg_val &= ~SPI_CMD_CPOL; - writel(reg_val, mdata->base + SPI_CMD_REG); - - reg_val = readl(mdata->base + SPI_CMD_REG); /* set the mlsbx and mlsbtx */ if (chip_config->tx_mlsb) -- GitLab From 403c5c0650816375527a6feecfb255d9b494dda3 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 8 Oct 2015 09:11:48 +0200 Subject: [PATCH 0557/2855] HSI: Remove struct hsi_client private fields from kernel-doc The kernel-doc how to says that structure fields that are inside a "private:" area shouldn't be listed in the generated documentation but the private fields for struct hsi_client private are listed. This also fixes the following make htmldocs warnings: .//include/linux/hsi/hsi.h:150: warning: Excess struct/union/enum/typedef member 'e_handler' description in 'hsi_client' .//include/linux/hsi/hsi.h:150: warning: Excess struct/union/enum/typedef member 'pclaimed' description in 'hsi_client' .//include/linux/hsi/hsi.h:150: warning: Excess struct/union/enum/typedef member 'nb' description in 'hsi_client' Signed-off-by: Javier Martinez Canillas Signed-off-by: Sebastian Reichel --- include/linux/hsi/hsi.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/linux/hsi/hsi.h b/include/linux/hsi/hsi.h index 5dd60c2e120f9..2790591c77cf6 100644 --- a/include/linux/hsi/hsi.h +++ b/include/linux/hsi/hsi.h @@ -135,9 +135,6 @@ static inline int hsi_register_board_info(struct hsi_board_info const *info, * @device: Driver model representation of the device * @tx_cfg: HSI TX configuration * @rx_cfg: HSI RX configuration - * @e_handler: Callback for handling port events (RX Wake High/Low) - * @pclaimed: Keeps tracks if the clients claimed its associated HSI port - * @nb: Notifier block for port events */ struct hsi_client { struct device device; -- GitLab From 8ffedc1b128af336ab650cef4883015d1c49269d Mon Sep 17 00:00:00 2001 From: Dragos Bogdan Date: Wed, 18 Nov 2015 16:16:34 +0200 Subject: [PATCH 0558/2855] staging:iio:ad7780: Remove the ad7780_platform_data The ad7780_platform_data contains just the reference voltage information. Since the preferred way of specifying this information is using the Linux regulator framework and the ad7780 platform_data is not used by other users, it can be completely removed. Signed-off-by: Dragos Bogdan Acked-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7780.c | 9 ++------- drivers/staging/iio/adc/ad7780.h | 29 ----------------------------- 2 files changed, 2 insertions(+), 36 deletions(-) delete mode 100644 drivers/staging/iio/adc/ad7780.h diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index 98b5fc492eff2..498e86b71ae75 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c @@ -22,8 +22,6 @@ #include #include -#include "ad7780.h" - #define AD7780_RDY BIT(7) #define AD7780_FILTER BIT(6) #define AD7780_ERR BIT(5) @@ -162,7 +160,6 @@ static const struct iio_info ad7780_info = { static int ad7780_probe(struct spi_device *spi) { - struct ad7780_platform_data *pdata = spi->dev.platform_data; struct ad7780_state *st; struct iio_dev *indio_dev; int ret, voltage_uv = 0; @@ -188,12 +185,10 @@ static int ad7780_probe(struct spi_device *spi) st->chip_info = &ad7780_chip_info_tbl[spi_get_device_id(spi)->driver_data]; - if (pdata && pdata->vref_mv) - st->int_vref_mv = pdata->vref_mv; - else if (voltage_uv) + if (voltage_uv) st->int_vref_mv = voltage_uv / 1000; else - dev_warn(&spi->dev, "reference voltage unspecified\n"); + dev_warn(&spi->dev, "Reference voltage unspecified\n"); spi_set_drvdata(spi, indio_dev); diff --git a/drivers/staging/iio/adc/ad7780.h b/drivers/staging/iio/adc/ad7780.h deleted file mode 100644 index 46f61c9e798e6..0000000000000 --- a/drivers/staging/iio/adc/ad7780.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * AD7780/AD7781 SPI ADC driver - * - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ -#ifndef IIO_ADC_AD7780_H_ -#define IIO_ADC_AD7780_H_ - -/* - * TODO: struct ad7780_platform_data needs to go into include/linux/iio - */ - -/* NOTE: - * The AD7780 doesn't feature a dedicated SPI chip select, in addition it - * features a dual use data out ready DOUT/RDY output. - * In order to avoid contentions on the SPI bus, it's therefore necessary - * to use spi bus locking combined with a dedicated GPIO to control the - * power down reset signal of the AD7780. - * - * The DOUT/RDY output must also be wired to an interrupt capable GPIO. - */ - -struct ad7780_platform_data { - u16 vref_mv; -}; - -#endif /* IIO_ADC_AD7780_H_ */ -- GitLab From 438f13a283e776957779e9beb0503100801ea84f Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 21 Nov 2015 18:20:06 +0000 Subject: [PATCH 0559/2855] staging:iio: Delete some commented out lines in Kconfig and Makefile. These should have been removed with the driver move out of staging but instead were commented out. This was missed in reviews at the time so fixing it up now. Signed-off-by: Jonathan Cameron --- drivers/staging/iio/Kconfig | 28 ---------------------------- drivers/staging/iio/Makefile | 7 ------- 2 files changed, 35 deletions(-) diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index 85de1985df8e1..0e044cb0def8a 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -17,32 +17,4 @@ source "drivers/staging/iio/meter/Kconfig" source "drivers/staging/iio/resolver/Kconfig" source "drivers/staging/iio/trigger/Kconfig" -#config IIO_DUMMY_EVGEN -# tristate -# -#config IIO_SIMPLE_DUMMY -# tristate "An example driver with no hardware requirements" -# help -# Driver intended mainly as documentation for how to write -# a driver. May also be useful for testing userspace code -# without hardware. - -#if IIO_SIMPLE_DUMMY - -#config IIO_SIMPLE_DUMMY_EVENTS -# bool "Event generation support" -# select IIO_DUMMY_EVGEN -# help -# Add some dummy events to the simple dummy driver. - -#config IIO_SIMPLE_DUMMY_BUFFER -# bool "Buffered capture support" -# select IIO_BUFFER -# select IIO_TRIGGER -# select IIO_KFIFO_BUF -# help -# Add buffered data capture to the simple dummy driver. - -#endif # IIO_SIMPLE_DUMMY - endmenu diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index 355824ab733be..3e616b4437f54 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -2,13 +2,6 @@ # Makefile for the industrial I/O core. # -#obj-$(CONFIG_IIO_SIMPLE_DUMMY) += iio_dummy.o -#iio_dummy-y := iio_simple_dummy.o -#iio_dummy-$(CONFIG_IIO_SIMPLE_DUMMY_EVENTS) += iio_simple_dummy_events.o -#iio_dummy-$(CONFIG_IIO_SIMPLE_DUMMY_BUFFER) += iio_simple_dummy_buffer.o - -#obj-$(CONFIG_IIO_DUMMY_EVGEN) += iio_dummy_evgen.o - obj-y += accel/ obj-y += adc/ obj-y += addac/ -- GitLab From 3fba9b5ff837ed57a993e98245378c30911ab4ee Mon Sep 17 00:00:00 2001 From: Nizam Haider Date: Mon, 16 Nov 2015 05:35:57 +0530 Subject: [PATCH 0560/2855] IIO: adc: at91_adc.c Prefer kmalloc_array over kmalloc with multiply So this patch swaps that use out for kmalloc_array instead. Signed-off-by Nizam Haider Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91_adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 7b40925dd4ff2..f284cd6a93d64 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -742,7 +742,7 @@ static int at91_adc_of_get_resolution(struct at91_adc_state *st, return count; } - resolutions = kmalloc(count * sizeof(*resolutions), GFP_KERNEL); + resolutions = kmalloc_array(count, sizeof(*resolutions), GFP_KERNEL); if (!resolutions) return -ENOMEM; -- GitLab From 4ac4e086fd8c59e6b69089e6f7605500b63a6d17 Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Sun, 15 Nov 2015 17:20:05 -0800 Subject: [PATCH 0561/2855] iio: pulsedlight-lidar-lite: add runtime PM Add runtime PM support for the lidar-lite module to enable low power mode when last device requested reading is over a second. Signed-off-by: Matt Ranostay Signed-off-by: Jonathan Cameron --- .../iio/proximity/pulsedlight-lidar-lite-v2.c | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c index 961f9f990faff..be8ccef735f8b 100644 --- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c +++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c @@ -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 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -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" @@ -90,6 +92,12 @@ static inline int lidar_write_control(struct lidar_data *data, int val) 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; @@ -116,6 +124,8 @@ static int lidar_get_measurement(struct lidar_data *data, u16 *reg) 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) { @@ -144,6 +154,8 @@ static int lidar_get_measurement(struct lidar_data *data, u16 *reg) } ret = -EIO; } + pm_runtime_mark_last_busy(&client->dev); + pm_runtime_put_autosuspend(&client->dev); return ret; } @@ -243,6 +255,17 @@ static int lidar_probe(struct i2c_client *client, 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: @@ -258,6 +281,9 @@ static int lidar_remove(struct i2c_client *client) iio_device_unregister(indio_dev); iio_triggered_buffer_cleanup(indio_dev); + pm_runtime_disable(&client->dev); + pm_runtime_set_suspended(&client->dev); + return 0; } @@ -273,10 +299,38 @@ static const struct of_device_id lidar_dt_ids[] = { }; 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, -- GitLab From 9e4808d2c6a6660d5d2cd572e689570df14a8472 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Fri, 20 Nov 2015 16:07:51 +0530 Subject: [PATCH 0562/2855] mfd: sec: Add support for S2MPS15 PMIC Add support for S2MPS15 PMIC which is similar to S2MPS11 PMIC. The S2MPS15 PMIC supports 27 LDO regulators, 10 buck regulators, RTC, three 32.768KHz clock outputs and battery charger. This patch adds initial support for LDO and buck regulators of S2MPS15 device. Signed-off-by: Thomas Abraham Signed-off-by: Alim Akhtar Reviewed-by: Krzysztof Kozlowski [Alim: Added s2mps15_devs like rtc and clk and related changes] Signed-off-by: Lee Jones --- drivers/mfd/sec-core.c | 31 ++++++ drivers/mfd/sec-irq.c | 8 ++ include/linux/mfd/samsung/core.h | 1 + include/linux/mfd/samsung/s2mps15.h | 158 ++++++++++++++++++++++++++++ 4 files changed, 198 insertions(+) create mode 100644 include/linux/mfd/samsung/s2mps15.h diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index 989076d6cb834..7c4e7be17f1e2 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -96,6 +97,17 @@ static const struct mfd_cell s2mps14_devs[] = { } }; +static const struct mfd_cell s2mps15_devs[] = { + { + .name = "s2mps15-regulator", + }, { + .name = "s2mps15-rtc", + }, { + .name = "s2mps13-clk", + .of_compatible = "samsung,s2mps13-clk", + }, +}; + static const struct mfd_cell s2mpa01_devs[] = { { .name = "s2mpa01-pmic", @@ -121,6 +133,9 @@ static const struct of_device_id sec_dt_match[] = { }, { .compatible = "samsung,s2mps14-pmic", .data = (void *)S2MPS14X, + }, { + .compatible = "samsung,s2mps15-pmic", + .data = (void *)S2MPS15X, }, { .compatible = "samsung,s2mpa01-pmic", .data = (void *)S2MPA01, @@ -223,6 +238,15 @@ static const struct regmap_config s2mps14_regmap_config = { .cache_type = REGCACHE_FLAT, }; +static const struct regmap_config s2mps15_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = S2MPS15_REG_LDODSCH4, + .volatile_reg = s2mps11_volatile, + .cache_type = REGCACHE_FLAT, +}; + static const struct regmap_config s2mpu02_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -384,6 +408,9 @@ static int sec_pmic_probe(struct i2c_client *i2c, case S2MPS14X: regmap = &s2mps14_regmap_config; break; + case S2MPS15X: + regmap = &s2mps15_regmap_config; + break; case S5M8763X: regmap = &s5m8763_regmap_config; break; @@ -442,6 +469,10 @@ static int sec_pmic_probe(struct i2c_client *i2c, sec_devs = s2mps14_devs; num_sec_devs = ARRAY_SIZE(s2mps14_devs); break; + case S2MPS15X: + sec_devs = s2mps15_devs; + num_sec_devs = ARRAY_SIZE(s2mps15_devs); + break; case S2MPU02: sec_devs = s2mpu02_devs; num_sec_devs = ARRAY_SIZE(s2mpu02_devs); diff --git a/drivers/mfd/sec-irq.c b/drivers/mfd/sec-irq.c index 806fa8dbb22d8..d77de431cc506 100644 --- a/drivers/mfd/sec-irq.c +++ b/drivers/mfd/sec-irq.c @@ -407,6 +407,11 @@ static const struct regmap_irq_chip s2mps14_irq_chip = { S2MPS1X_IRQ_CHIP_COMMON_DATA, }; +static const struct regmap_irq_chip s2mps15_irq_chip = { + .name = "s2mps15", + S2MPS1X_IRQ_CHIP_COMMON_DATA, +}; + static const struct regmap_irq_chip s2mpu02_irq_chip = { .name = "s2mpu02", .irqs = s2mpu02_irqs, @@ -466,6 +471,9 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic) case S2MPS14X: sec_irq_chip = &s2mps14_irq_chip; break; + case S2MPS15X: + sec_irq_chip = &s2mps15_irq_chip; + break; case S2MPU02: sec_irq_chip = &s2mpu02_irq_chip; break; diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h index a060986393991..6bc4bcd488acb 100644 --- a/include/linux/mfd/samsung/core.h +++ b/include/linux/mfd/samsung/core.h @@ -44,6 +44,7 @@ enum sec_device_type { S2MPS11X, S2MPS13X, S2MPS14X, + S2MPS15X, S2MPU02, }; diff --git a/include/linux/mfd/samsung/s2mps15.h b/include/linux/mfd/samsung/s2mps15.h new file mode 100644 index 0000000000000..36d35287c3c06 --- /dev/null +++ b/include/linux/mfd/samsung/s2mps15.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __LINUX_MFD_S2MPS15_H +#define __LINUX_MFD_S2MPS15_H + +/* S2MPS15 registers */ +enum s2mps15_reg { + S2MPS15_REG_ID, + S2MPS15_REG_INT1, + S2MPS15_REG_INT2, + S2MPS15_REG_INT3, + S2MPS15_REG_INT1M, + S2MPS15_REG_INT2M, + S2MPS15_REG_INT3M, + S2MPS15_REG_ST1, + S2MPS15_REG_ST2, + S2MPS15_REG_PWRONSRC, + S2MPS15_REG_OFFSRC, + S2MPS15_REG_BU_CHG, + S2MPS15_REG_RTC_BUF, + S2MPS15_REG_CTRL1, + S2MPS15_REG_CTRL2, + S2MPS15_REG_RSVD1, + S2MPS15_REG_RSVD2, + S2MPS15_REG_RSVD3, + S2MPS15_REG_RSVD4, + S2MPS15_REG_RSVD5, + S2MPS15_REG_RSVD6, + S2MPS15_REG_CTRL3, + S2MPS15_REG_RSVD7, + S2MPS15_REG_RSVD8, + S2MPS15_REG_RSVD9, + S2MPS15_REG_B1CTRL1, + S2MPS15_REG_B1CTRL2, + S2MPS15_REG_B2CTRL1, + S2MPS15_REG_B2CTRL2, + S2MPS15_REG_B3CTRL1, + S2MPS15_REG_B3CTRL2, + S2MPS15_REG_B4CTRL1, + S2MPS15_REG_B4CTRL2, + S2MPS15_REG_B5CTRL1, + S2MPS15_REG_B5CTRL2, + S2MPS15_REG_B6CTRL1, + S2MPS15_REG_B6CTRL2, + S2MPS15_REG_B7CTRL1, + S2MPS15_REG_B7CTRL2, + S2MPS15_REG_B8CTRL1, + S2MPS15_REG_B8CTRL2, + S2MPS15_REG_B9CTRL1, + S2MPS15_REG_B9CTRL2, + S2MPS15_REG_B10CTRL1, + S2MPS15_REG_B10CTRL2, + S2MPS15_REG_BBCTRL1, + S2MPS15_REG_BBCTRL2, + S2MPS15_REG_BRAMP, + S2MPS15_REG_LDODVS1, + S2MPS15_REG_LDODVS2, + S2MPS15_REG_LDODVS3, + S2MPS15_REG_LDODVS4, + S2MPS15_REG_L1CTRL, + S2MPS15_REG_L2CTRL, + S2MPS15_REG_L3CTRL, + S2MPS15_REG_L4CTRL, + S2MPS15_REG_L5CTRL, + S2MPS15_REG_L6CTRL, + S2MPS15_REG_L7CTRL, + S2MPS15_REG_L8CTRL, + S2MPS15_REG_L9CTRL, + S2MPS15_REG_L10CTRL, + S2MPS15_REG_L11CTRL, + S2MPS15_REG_L12CTRL, + S2MPS15_REG_L13CTRL, + S2MPS15_REG_L14CTRL, + S2MPS15_REG_L15CTRL, + S2MPS15_REG_L16CTRL, + S2MPS15_REG_L17CTRL, + S2MPS15_REG_L18CTRL, + S2MPS15_REG_L19CTRL, + S2MPS15_REG_L20CTRL, + S2MPS15_REG_L21CTRL, + S2MPS15_REG_L22CTRL, + S2MPS15_REG_L23CTRL, + S2MPS15_REG_L24CTRL, + S2MPS15_REG_L25CTRL, + S2MPS15_REG_L26CTRL, + S2MPS15_REG_L27CTRL, + S2MPS15_REG_LDODSCH1, + S2MPS15_REG_LDODSCH2, + S2MPS15_REG_LDODSCH3, + S2MPS15_REG_LDODSCH4, +}; + +/* S2MPS15 regulator ids */ +enum s2mps15_regulators { + S2MPS15_LDO1, + S2MPS15_LDO2, + S2MPS15_LDO3, + S2MPS15_LDO4, + S2MPS15_LDO5, + S2MPS15_LDO6, + S2MPS15_LDO7, + S2MPS15_LDO8, + S2MPS15_LDO9, + S2MPS15_LDO10, + S2MPS15_LDO11, + S2MPS15_LDO12, + S2MPS15_LDO13, + S2MPS15_LDO14, + S2MPS15_LDO15, + S2MPS15_LDO16, + S2MPS15_LDO17, + S2MPS15_LDO18, + S2MPS15_LDO19, + S2MPS15_LDO20, + S2MPS15_LDO21, + S2MPS15_LDO22, + S2MPS15_LDO23, + S2MPS15_LDO24, + S2MPS15_LDO25, + S2MPS15_LDO26, + S2MPS15_LDO27, + S2MPS15_BUCK1, + S2MPS15_BUCK2, + S2MPS15_BUCK3, + S2MPS15_BUCK4, + S2MPS15_BUCK5, + S2MPS15_BUCK6, + S2MPS15_BUCK7, + S2MPS15_BUCK8, + S2MPS15_BUCK9, + S2MPS15_BUCK10, + S2MPS15_BUCK11, + S2MPS15_REGULATOR_MAX, +}; + +#define S2MPS15_LDO_VSEL_MASK (0x3F) +#define S2MPS15_BUCK_VSEL_MASK (0xFF) + +#define S2MPS15_ENABLE_SHIFT (0x06) +#define S2MPS15_ENABLE_MASK (0x03 << S2MPS15_ENABLE_SHIFT) + +#define S2MPS15_LDO_N_VOLTAGES (S2MPS15_LDO_VSEL_MASK + 1) +#define S2MPS15_BUCK_N_VOLTAGES (S2MPS15_BUCK_VSEL_MASK + 1) + +#endif /* __LINUX_MFD_S2MPS15_H */ -- GitLab From 51af20675800ffbd97bd48363a06e00f83de44c4 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Fri, 20 Nov 2015 16:07:52 +0530 Subject: [PATCH 0563/2855] regulator: s2mps11: Add support for S2MPS15 regulators The S2MPS15 PMIC is similar in functionality to S2MPS11/14 PMIC. It contains 27 LDO and 10 Buck regulators and allows programming these regulators via a I2C interface. This patch adds initial support for LDO/Buck regulators of S2MPS15 PMIC. Signed-off-by: Thomas Abraham Signed-off-by: Alim Akhtar Reviewed-by: Krzysztof Kozlowski Acked-by: Mark Brown Signed-off-by: Lee Jones --- drivers/regulator/Kconfig | 4 +- drivers/regulator/s2mps11.c | 135 +++++++++++++++++++++++++++++++++++- 2 files changed, 136 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 8df0b0e62976d..2805b014ae311 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -588,10 +588,10 @@ config REGULATOR_S2MPA01 via I2C bus. S2MPA01 has 10 Bucks and 26 LDO outputs. config REGULATOR_S2MPS11 - tristate "Samsung S2MPS11/S2MPS13/S2MPS14/S2MPU02 voltage regulator" + tristate "Samsung S2MPS11/13/14/15/S2MPU02 voltage regulator" depends on MFD_SEC_CORE help - This driver supports a Samsung S2MPS11/S2MPS13/S2MPS14/S2MPU02 voltage + This driver supports a Samsung S2MPS11/13/14/15/S2MPU02 voltage output regulator via I2C bus. The chip is comprised of high efficient Buck converters including Dual-Phase Buck converter, Buck-Boost converter, various LDOs. diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index 72fc3c32db498..b2f3a28e720ce 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -32,6 +32,7 @@ #include #include #include +#include #include /* The highest number of possible regulators for supported devices. */ @@ -661,6 +662,133 @@ static const struct regulator_desc s2mps14_regulators[] = { S2MPS14_BUCK1235_START_SEL), }; +static struct regulator_ops s2mps15_reg_ldo_ops = { + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, +}; + +static struct regulator_ops s2mps15_reg_buck_ops = { + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage_time_sel = regulator_set_voltage_time_sel, +}; + +#define regulator_desc_s2mps15_ldo(num, range) { \ + .name = "LDO"#num, \ + .id = S2MPS15_LDO##num, \ + .ops = &s2mps15_reg_ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .linear_ranges = range, \ + .n_linear_ranges = ARRAY_SIZE(range), \ + .n_voltages = S2MPS15_LDO_N_VOLTAGES, \ + .vsel_reg = S2MPS15_REG_L1CTRL + num - 1, \ + .vsel_mask = S2MPS15_LDO_VSEL_MASK, \ + .enable_reg = S2MPS15_REG_L1CTRL + num - 1, \ + .enable_mask = S2MPS15_ENABLE_MASK \ +} + +#define regulator_desc_s2mps15_buck(num, range) { \ + .name = "BUCK"#num, \ + .id = S2MPS15_BUCK##num, \ + .ops = &s2mps15_reg_buck_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .linear_ranges = range, \ + .n_linear_ranges = ARRAY_SIZE(range), \ + .ramp_delay = 12500, \ + .n_voltages = S2MPS15_BUCK_N_VOLTAGES, \ + .vsel_reg = S2MPS15_REG_B1CTRL2 + ((num - 1) * 2), \ + .vsel_mask = S2MPS15_BUCK_VSEL_MASK, \ + .enable_reg = S2MPS15_REG_B1CTRL1 + ((num - 1) * 2), \ + .enable_mask = S2MPS15_ENABLE_MASK \ +} + +/* voltage range for s2mps15 LDO 3, 5, 15, 16, 18, 20, 23 and 27 */ +static const struct regulator_linear_range s2mps15_ldo_voltage_ranges1[] = { + REGULATOR_LINEAR_RANGE(1000000, 0xc, 0x38, 25000), +}; + +/* voltage range for s2mps15 LDO 2, 6, 14, 17, 19, 21, 24 and 25 */ +static const struct regulator_linear_range s2mps15_ldo_voltage_ranges2[] = { + REGULATOR_LINEAR_RANGE(1800000, 0x0, 0x3f, 25000), +}; + +/* voltage range for s2mps15 LDO 4, 11, 12, 13, 22 and 26 */ +static const struct regulator_linear_range s2mps15_ldo_voltage_ranges3[] = { + REGULATOR_LINEAR_RANGE(700000, 0x0, 0x34, 12500), +}; + +/* voltage range for s2mps15 LDO 7, 8, 9 and 10 */ +static const struct regulator_linear_range s2mps15_ldo_voltage_ranges4[] = { + REGULATOR_LINEAR_RANGE(700000, 0xc, 0x18, 25000), +}; + +/* voltage range for s2mps15 LDO 1 */ +static const struct regulator_linear_range s2mps15_ldo_voltage_ranges5[] = { + REGULATOR_LINEAR_RANGE(500000, 0x0, 0x20, 12500), +}; + +/* voltage range for s2mps15 BUCK 1, 2, 3, 4, 5, 6 and 7 */ +static const struct regulator_linear_range s2mps15_buck_voltage_ranges1[] = { + REGULATOR_LINEAR_RANGE(500000, 0x20, 0xb0, 6250), +}; + +/* voltage range for s2mps15 BUCK 8, 9 and 10 */ +static const struct regulator_linear_range s2mps15_buck_voltage_ranges2[] = { + REGULATOR_LINEAR_RANGE(1000000, 0x20, 0xc0, 12500), +}; + +static const struct regulator_desc s2mps15_regulators[] = { + regulator_desc_s2mps15_ldo(1, s2mps15_ldo_voltage_ranges5), + regulator_desc_s2mps15_ldo(2, s2mps15_ldo_voltage_ranges2), + regulator_desc_s2mps15_ldo(3, s2mps15_ldo_voltage_ranges1), + regulator_desc_s2mps15_ldo(4, s2mps15_ldo_voltage_ranges3), + regulator_desc_s2mps15_ldo(5, s2mps15_ldo_voltage_ranges1), + regulator_desc_s2mps15_ldo(6, s2mps15_ldo_voltage_ranges2), + regulator_desc_s2mps15_ldo(7, s2mps15_ldo_voltage_ranges4), + regulator_desc_s2mps15_ldo(8, s2mps15_ldo_voltage_ranges4), + regulator_desc_s2mps15_ldo(9, s2mps15_ldo_voltage_ranges4), + regulator_desc_s2mps15_ldo(10, s2mps15_ldo_voltage_ranges4), + regulator_desc_s2mps15_ldo(11, s2mps15_ldo_voltage_ranges3), + regulator_desc_s2mps15_ldo(12, s2mps15_ldo_voltage_ranges3), + regulator_desc_s2mps15_ldo(13, s2mps15_ldo_voltage_ranges3), + regulator_desc_s2mps15_ldo(14, s2mps15_ldo_voltage_ranges2), + regulator_desc_s2mps15_ldo(15, s2mps15_ldo_voltage_ranges1), + regulator_desc_s2mps15_ldo(16, s2mps15_ldo_voltage_ranges1), + regulator_desc_s2mps15_ldo(17, s2mps15_ldo_voltage_ranges2), + regulator_desc_s2mps15_ldo(18, s2mps15_ldo_voltage_ranges1), + regulator_desc_s2mps15_ldo(19, s2mps15_ldo_voltage_ranges2), + regulator_desc_s2mps15_ldo(20, s2mps15_ldo_voltage_ranges1), + regulator_desc_s2mps15_ldo(21, s2mps15_ldo_voltage_ranges2), + regulator_desc_s2mps15_ldo(22, s2mps15_ldo_voltage_ranges3), + regulator_desc_s2mps15_ldo(23, s2mps15_ldo_voltage_ranges1), + regulator_desc_s2mps15_ldo(24, s2mps15_ldo_voltage_ranges2), + regulator_desc_s2mps15_ldo(25, s2mps15_ldo_voltage_ranges2), + regulator_desc_s2mps15_ldo(26, s2mps15_ldo_voltage_ranges3), + regulator_desc_s2mps15_ldo(27, s2mps15_ldo_voltage_ranges1), + regulator_desc_s2mps15_buck(1, s2mps15_buck_voltage_ranges1), + regulator_desc_s2mps15_buck(2, s2mps15_buck_voltage_ranges1), + regulator_desc_s2mps15_buck(3, s2mps15_buck_voltage_ranges1), + regulator_desc_s2mps15_buck(4, s2mps15_buck_voltage_ranges1), + regulator_desc_s2mps15_buck(5, s2mps15_buck_voltage_ranges1), + regulator_desc_s2mps15_buck(6, s2mps15_buck_voltage_ranges1), + regulator_desc_s2mps15_buck(7, s2mps15_buck_voltage_ranges1), + regulator_desc_s2mps15_buck(8, s2mps15_buck_voltage_ranges2), + regulator_desc_s2mps15_buck(9, s2mps15_buck_voltage_ranges2), + regulator_desc_s2mps15_buck(10, s2mps15_buck_voltage_ranges2), +}; + static int s2mps14_pmic_enable_ext_control(struct s2mps11_info *s2mps11, struct regulator_dev *rdev) { @@ -974,6 +1102,10 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) regulators = s2mps14_regulators; BUILD_BUG_ON(S2MPS_REGULATOR_MAX < s2mps11->rdev_num); break; + case S2MPS15X: + s2mps11->rdev_num = ARRAY_SIZE(s2mps15_regulators); + regulators = s2mps15_regulators; + break; case S2MPU02: s2mps11->rdev_num = ARRAY_SIZE(s2mpu02_regulators); regulators = s2mpu02_regulators; @@ -1070,6 +1202,7 @@ static const struct platform_device_id s2mps11_pmic_id[] = { { "s2mps11-pmic", S2MPS11X}, { "s2mps13-pmic", S2MPS13X}, { "s2mps14-pmic", S2MPS14X}, + { "s2mps15-regulator", S2MPS15X}, { "s2mpu02-pmic", S2MPU02}, { }, }; @@ -1097,5 +1230,5 @@ module_exit(s2mps11_pmic_exit); /* Module information */ MODULE_AUTHOR("Sangbeom Kim "); -MODULE_DESCRIPTION("SAMSUNG S2MPS11/S2MPS14/S2MPU02 Regulator Driver"); +MODULE_DESCRIPTION("SAMSUNG S2MPS11/S2MPS14/S2MPS15/S2MPU02 Regulator Driver"); MODULE_LICENSE("GPL"); -- GitLab From a65e5efa7c5faa8c320fe56cc351d47fcd006749 Mon Sep 17 00:00:00 2001 From: Alim Akhtar Date: Fri, 20 Nov 2015 16:07:53 +0530 Subject: [PATCH 0564/2855] rtc: s5m.c: Add support for S2MPS15 RTC RTC found in s2mps15 is almost same as one found on s2mps13 with few differences in RTC_UPDATE register fields, like: 1> Bit[4] and Bit[1] are reversed - On s2mps13 WUDR -> bit[4], AUDR -> bit[1] - On s2mps15 WUDR -> bit[1], AUDR -> bit[4] 2> In case of s2mps13, for alarm register, need to set both WDUR and ADUR high, whereas for s2mps15 only set AUDR to high. 3> On s2mps15, WUDR, RUDR and AUDR functions should never be used at the same time. This patch add required changes to enable s2mps15 rtc timer. Signed-off-by: Alim Akhtar Reviewed-by: Krzysztof Kozlowski Acked-by: Alexandre Belloni Signed-off-by: Lee Jones --- drivers/rtc/rtc-s5m.c | 37 +++++++++++++++++++++++++++++---- include/linux/mfd/samsung/rtc.h | 2 ++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index f2504b4eef345..0d68a85dd4298 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -188,6 +188,7 @@ static inline int s5m_check_peding_alarm_interrupt(struct s5m_rtc_info *info, ret = regmap_read(info->regmap, S5M_RTC_STATUS, &val); val &= S5M_ALARM0_STATUS; break; + case S2MPS15X: case S2MPS14X: case S2MPS13X: ret = regmap_read(info->s5m87xx->regmap_pmic, S2MPS14_REG_ST2, @@ -219,9 +220,22 @@ static inline int s5m8767_rtc_set_time_reg(struct s5m_rtc_info *info) return ret; } - data |= info->regs->rtc_udr_mask; - if (info->device_type == S5M8763X || info->device_type == S5M8767X) - data |= S5M_RTC_TIME_EN_MASK; + switch (info->device_type) { + case S5M8763X: + case S5M8767X: + data |= info->regs->rtc_udr_mask | S5M_RTC_TIME_EN_MASK; + case S2MPS15X: + /* As per UM, for write time register, set WUDR bit to high */ + data |= S2MPS15_RTC_WUDR_MASK; + break; + case S2MPS14X: + case S2MPS13X: + data |= info->regs->rtc_udr_mask; + break; + default: + return -EINVAL; + } + ret = regmap_write(info->regmap, info->regs->rtc_udr_update, data); if (ret < 0) { @@ -252,6 +266,11 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info) case S5M8767X: data &= ~S5M_RTC_TIME_EN_MASK; break; + case S2MPS15X: + /* As per UM, for write alarm, set A_UDR(bit[4]) to high + * rtc_udr_mask above sets bit[4] + */ + break; case S2MPS14X: data |= S2MPS_RTC_RUDR_MASK; break; @@ -317,7 +336,8 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm) u8 data[info->regs->regs_count]; int ret; - if (info->device_type == S2MPS14X || info->device_type == S2MPS13X) { + if (info->device_type == S2MPS15X || info->device_type == S2MPS14X || + info->device_type == S2MPS13X) { ret = regmap_update_bits(info->regmap, info->regs->rtc_udr_update, S2MPS_RTC_RUDR_MASK, S2MPS_RTC_RUDR_MASK); @@ -339,6 +359,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm) break; case S5M8767X: + case S2MPS15X: case S2MPS14X: case S2MPS13X: s5m8767_data_to_tm(data, tm, info->rtc_24hr_mode); @@ -366,6 +387,7 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm) s5m8763_tm_to_data(tm, data); break; case S5M8767X: + case S2MPS15X: case S2MPS14X: case S2MPS13X: ret = s5m8767_tm_to_data(tm, data); @@ -414,6 +436,7 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) break; case S5M8767X: + case S2MPS15X: case S2MPS14X: case S2MPS13X: s5m8767_data_to_tm(data, &alrm->time, info->rtc_24hr_mode); @@ -463,6 +486,7 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info) break; case S5M8767X: + case S2MPS15X: case S2MPS14X: case S2MPS13X: for (i = 0; i < info->regs->regs_count; i++) @@ -508,6 +532,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info) break; case S5M8767X: + case S2MPS15X: case S2MPS14X: case S2MPS13X: data[RTC_SEC] |= ALARM_ENABLE_MASK; @@ -548,6 +573,7 @@ static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) break; case S5M8767X: + case S2MPS15X: case S2MPS14X: case S2MPS13X: s5m8767_tm_to_data(&alrm->time, data); @@ -631,6 +657,7 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info) ret = regmap_raw_write(info->regmap, S5M_ALARM0_CONF, data, 2); break; + case S2MPS15X: case S2MPS14X: case S2MPS13X: data[0] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); @@ -679,6 +706,7 @@ static int s5m_rtc_probe(struct platform_device *pdev) return -ENOMEM; switch (platform_get_device_id(pdev)->driver_data) { + case S2MPS15X: case S2MPS14X: case S2MPS13X: regmap_cfg = &s2mps14_rtc_regmap_config; @@ -805,6 +833,7 @@ static const struct platform_device_id s5m_rtc_id[] = { { "s5m-rtc", S5M8767X }, { "s2mps13-rtc", S2MPS13X }, { "s2mps14-rtc", S2MPS14X }, + { "s2mps15-rtc", S2MPS15X }, { }, }; MODULE_DEVICE_TABLE(platform, s5m_rtc_id); diff --git a/include/linux/mfd/samsung/rtc.h b/include/linux/mfd/samsung/rtc.h index 29c30ac36020a..a65e4655d470b 100644 --- a/include/linux/mfd/samsung/rtc.h +++ b/include/linux/mfd/samsung/rtc.h @@ -107,6 +107,8 @@ enum s2mps_rtc_reg { #define S2MPS_RTC_WUDR_MASK (1 << S2MPS_RTC_WUDR_SHIFT) #define S2MPS13_RTC_AUDR_SHIFT 1 #define S2MPS13_RTC_AUDR_MASK (1 << S2MPS13_RTC_AUDR_SHIFT) +#define S2MPS15_RTC_WUDR_SHIFT 1 +#define S2MPS15_RTC_WUDR_MASK (1 << S2MPS15_RTC_WUDR_SHIFT) #define S2MPS_RTC_RUDR_SHIFT 0 #define S2MPS_RTC_RUDR_MASK (1 << S2MPS_RTC_RUDR_SHIFT) #define RTC_TCON_SHIFT 1 -- GitLab From cc8a9d79222c6b259ea9eceef21b94a5610616f0 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 5 Nov 2015 12:55:27 +0100 Subject: [PATCH 0565/2855] HID: usbhid: discarded events don't abort idleness If an event is discarded the device stays idle. Just reverse the order of check and marking busy. Found by code inspection. Signed-off-by: Oliver Neukum Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 36712e9f56c26..19a4364c90856 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -274,10 +274,10 @@ static void hid_irq_in(struct urb *urb) switch (urb->status) { case 0: /* success */ - usbhid_mark_busy(usbhid); usbhid->retry_delay = 0; if ((hid->quirks & HID_QUIRK_ALWAYS_POLL) && !hid->open) break; + usbhid_mark_busy(usbhid); if (!test_bit(HID_RESUME_RUNNING, &usbhid->iofl)) { hid_input_report(urb->context, HID_INPUT_REPORT, urb->transfer_buffer, -- GitLab From 5eca4d843f9f0c3140a8657ba2f8217ee6c08c11 Mon Sep 17 00:00:00 2001 From: Joshua Clayton Date: Wed, 18 Nov 2015 14:30:37 -0800 Subject: [PATCH 0566/2855] spi: Move spi code from Documentation to tools Jon Corbet requested this code moved with the last changeset, https://lkml.org/lkml/2015/3/1/144, but the patch was not applied because it missed the Makefile. Moved spidev_test, spidev_fdx and their Makefile infrastructure. Signed-off-by: Joshua Clayton Signed-off-by: Mark Brown --- Documentation/Makefile | 2 +- Documentation/spi/Makefile | 8 -------- tools/Makefile | 7 ++++--- tools/spi/Makefile | 4 ++++ {Documentation => tools}/spi/spidev_fdx.c | 0 {Documentation => tools}/spi/spidev_test.c | 0 6 files changed, 9 insertions(+), 12 deletions(-) delete mode 100644 Documentation/spi/Makefile create mode 100644 tools/spi/Makefile rename {Documentation => tools}/spi/spidev_fdx.c (100%) rename {Documentation => tools}/spi/spidev_test.c (100%) diff --git a/Documentation/Makefile b/Documentation/Makefile index bc0548201755e..1207d79076500 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -1,4 +1,4 @@ subdir-y := accounting auxdisplay blackfin connector \ filesystems filesystems ia64 laptops mic misc-devices \ - networking pcmcia prctl ptp spi timers vDSO video4linux \ + networking pcmcia prctl ptp timers vDSO video4linux \ watchdog diff --git a/Documentation/spi/Makefile b/Documentation/spi/Makefile deleted file mode 100644 index efa255813e9d3..0000000000000 --- a/Documentation/spi/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# List of programs to build -hostprogs-y := spidev_test spidev_fdx - -# Tell kbuild to always build the programs -always := $(hostprogs-y) - -HOSTCFLAGS_spidev_test.o += -I$(objtree)/usr/include -HOSTCFLAGS_spidev_fdx.o += -I$(objtree)/usr/include diff --git a/tools/Makefile b/tools/Makefile index d6f307dfb1a3c..0528aa13ccb42 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -17,6 +17,7 @@ help: @echo ' lguest - a minimal 32-bit x86 hypervisor' @echo ' perf - Linux performance measurement and analysis tool' @echo ' selftests - various kernel selftests' + @echo ' spi - spi tools' @echo ' turbostat - Intel CPU idle stats and freq reporting tool' @echo ' usb - USB testing tools' @echo ' virtio - vhost test module' @@ -48,7 +49,7 @@ acpi: FORCE cpupower: FORCE $(call descend,power/$@) -cgroup firewire hv guest usb virtio vm net iio: FORCE +cgroup firewire hv guest spi usb virtio vm net iio: FORCE $(call descend,$@) liblockdep: FORCE @@ -109,7 +110,7 @@ acpi_clean: cpupower_clean: $(call descend,power/cpupower,clean) -cgroup_clean hv_clean firewire_clean lguest_clean usb_clean virtio_clean vm_clean net_clean iio_clean: +cgroup_clean hv_clean firewire_clean lguest_clean spi_clean usb_clean virtio_clean vm_clean net_clean iio_clean: $(call descend,$(@:_clean=),clean) liblockdep_clean: @@ -134,7 +135,7 @@ freefall_clean: $(call descend,laptop/freefall,clean) clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean lguest_clean \ - perf_clean selftests_clean turbostat_clean usb_clean virtio_clean \ + perf_clean selftests_clean turbostat_clean spi_clean usb_clean virtio_clean \ vm_clean net_clean iio_clean x86_energy_perf_policy_clean tmon_clean \ freefall_clean diff --git a/tools/spi/Makefile b/tools/spi/Makefile new file mode 100644 index 0000000000000..cd0db62e4d9d6 --- /dev/null +++ b/tools/spi/Makefile @@ -0,0 +1,4 @@ +all: spidev_test spidev_fdx + +clean: + $(RM) spidev_test spidev_fdx diff --git a/Documentation/spi/spidev_fdx.c b/tools/spi/spidev_fdx.c similarity index 100% rename from Documentation/spi/spidev_fdx.c rename to tools/spi/spidev_fdx.c diff --git a/Documentation/spi/spidev_test.c b/tools/spi/spidev_test.c similarity index 100% rename from Documentation/spi/spidev_test.c rename to tools/spi/spidev_test.c -- GitLab From 5c437a401b824399b6fa7342c66b675ebb7af43e Mon Sep 17 00:00:00 2001 From: Joshua Clayton Date: Wed, 18 Nov 2015 14:30:38 -0800 Subject: [PATCH 0567/2855] spi: spidev_test: transfer_escaped_string function Move the input_tx code into its own small function. This cleans up some variables from main() that are used only here. While we are at it, check malloc calls instead of assuming they succeed. Signed-off-by: Joshua Clayton Signed-off-by: Mark Brown --- tools/spi/spidev_test.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/tools/spi/spidev_test.c b/tools/spi/spidev_test.c index 135b3f592b83d..f9d2957e538b0 100644 --- a/tools/spi/spidev_test.c +++ b/tools/spi/spidev_test.c @@ -249,13 +249,30 @@ static void parse_opts(int argc, char *argv[]) } } +static void transfer_escaped_string(int fd, char *str) +{ + size_t size = strlen(str + 1); + uint8_t *tx; + uint8_t *rx; + + tx = malloc(size); + if (!tx) + pabort("can't allocate tx buffer"); + + rx = malloc(size); + if (!rx) + pabort("can't allocate rx buffer"); + + size = unescape((char *)tx, str, size); + transfer(fd, tx, rx, size); + free(rx); + free(tx); +} + int main(int argc, char *argv[]) { int ret = 0; int fd; - uint8_t *tx; - uint8_t *rx; - int size; parse_opts(argc, argv); @@ -300,17 +317,10 @@ int main(int argc, char *argv[]) printf("bits per word: %d\n", bits); printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); - if (input_tx) { - size = strlen(input_tx+1); - tx = malloc(size); - rx = malloc(size); - size = unescape((char *)tx, input_tx, size); - transfer(fd, tx, rx, size); - free(rx); - free(tx); - } else { + if (input_tx) + transfer_escaped_string(fd, input_tx); + else transfer(fd, default_tx, default_rx, sizeof(default_tx)); - } close(fd); -- GitLab From 7af475a5b55e8e47327818e8133fe22204c1fc4d Mon Sep 17 00:00:00 2001 From: Joshua Clayton Date: Wed, 18 Nov 2015 14:30:39 -0800 Subject: [PATCH 0568/2855] spi: spidev_test: accept input from a file Add input file support to facilitate testing larger data. Signed-off-by: Joshua Clayton Signed-off-by: Mark Brown --- tools/spi/spidev_test.c | 48 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/tools/spi/spidev_test.c b/tools/spi/spidev_test.c index f9d2957e538b0..71a45a4d7d497 100644 --- a/tools/spi/spidev_test.c +++ b/tools/spi/spidev_test.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -33,6 +34,7 @@ static void pabort(const char *s) static const char *device = "/dev/spidev1.1"; static uint32_t mode; static uint8_t bits = 8; +static char *input_file; static uint32_t speed = 500000; static uint16_t delay; static int verbose; @@ -144,6 +146,7 @@ static void print_usage(const char *prog) " -s --speed max speed (Hz)\n" " -d --delay delay (usec)\n" " -b --bpw bits per word \n" + " -i --input input data from a file (e.g. \"test.bin\")\n" " -l --loop loopback\n" " -H --cpha clock phase\n" " -O --cpol clock polarity\n" @@ -167,6 +170,7 @@ static void parse_opts(int argc, char *argv[]) { "speed", 1, 0, 's' }, { "delay", 1, 0, 'd' }, { "bpw", 1, 0, 'b' }, + { "input", 1, 0, 'i' }, { "loop", 0, 0, 'l' }, { "cpha", 0, 0, 'H' }, { "cpol", 0, 0, 'O' }, @@ -182,7 +186,8 @@ static void parse_opts(int argc, char *argv[]) }; int c; - c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR24p:v", lopts, NULL); + c = getopt_long(argc, argv, "D:s:d:b:i:lHOLC3NR24p:v", + lopts, NULL); if (c == -1) break; @@ -200,6 +205,9 @@ static void parse_opts(int argc, char *argv[]) case 'b': bits = atoi(optarg); break; + case 'i': + input_file = optarg; + break; case 'l': mode |= SPI_LOOP; break; @@ -269,6 +277,39 @@ static void transfer_escaped_string(int fd, char *str) free(tx); } +static void transfer_file(int fd, char *filename) +{ + ssize_t bytes; + struct stat sb; + int tx_fd; + uint8_t *tx; + uint8_t *rx; + + if (stat(filename, &sb) == -1) + pabort("can't stat input file"); + + tx_fd = open(filename, O_RDONLY); + if (fd < 0) + pabort("can't open input file"); + + tx = malloc(sb.st_size); + if (!tx) + pabort("can't allocate tx buffer"); + + rx = malloc(sb.st_size); + if (!rx) + pabort("can't allocate rx buffer"); + + bytes = read(tx_fd, tx, sb.st_size); + if (bytes != sb.st_size) + pabort("failed to read input file"); + + transfer(fd, tx, rx, sb.st_size); + free(rx); + free(tx); + close(tx_fd); +} + int main(int argc, char *argv[]) { int ret = 0; @@ -317,8 +358,13 @@ int main(int argc, char *argv[]) printf("bits per word: %d\n", bits); printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); + if (input_tx && input_file) + pabort("only one of -p and --input may be selected"); + if (input_tx) transfer_escaped_string(fd, input_tx); + else if (input_file) + transfer_file(fd, input_file); else transfer(fd, default_tx, default_rx, sizeof(default_tx)); -- GitLab From 983b27886a3c7f6eff4e987ddba932da74703f4e Mon Sep 17 00:00:00 2001 From: Joshua Clayton Date: Wed, 18 Nov 2015 14:30:40 -0800 Subject: [PATCH 0569/2855] spi: spidev_test: output to a file For testing of larger data transfers, output unmodified data directly to a file. Signed-off-by: Joshua Clayton Signed-off-by: Mark Brown --- tools/spi/spidev_test.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/tools/spi/spidev_test.c b/tools/spi/spidev_test.c index 71a45a4d7d497..02fc3a44901b5 100644 --- a/tools/spi/spidev_test.c +++ b/tools/spi/spidev_test.c @@ -35,6 +35,7 @@ static const char *device = "/dev/spidev1.1"; static uint32_t mode; static uint8_t bits = 8; static char *input_file; +static char *output_file; static uint32_t speed = 500000; static uint16_t delay; static int verbose; @@ -105,7 +106,7 @@ static int unescape(char *_dst, char *_src, size_t len) static void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len) { int ret; - + int out_fd; struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)tx, .rx_buf = (unsigned long)rx, @@ -136,7 +137,21 @@ static void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len) if (verbose) hex_dump(tx, len, 32, "TX"); - hex_dump(rx, len, 32, "RX"); + + if (output_file) { + out_fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (out_fd < 0) + pabort("could not open output file"); + + ret = write(out_fd, rx, len); + if (ret != len) + pabort("not all bytes written to utput file"); + + close(out_fd); + } + + if (verbose || !output_file) + hex_dump(rx, len, 32, "RX"); } static void print_usage(const char *prog) @@ -147,6 +162,7 @@ static void print_usage(const char *prog) " -d --delay delay (usec)\n" " -b --bpw bits per word \n" " -i --input input data from a file (e.g. \"test.bin\")\n" + " -o --output output data to a file (e.g. \"results.bin\")\n" " -l --loop loopback\n" " -H --cpha clock phase\n" " -O --cpol clock polarity\n" @@ -171,6 +187,7 @@ static void parse_opts(int argc, char *argv[]) { "delay", 1, 0, 'd' }, { "bpw", 1, 0, 'b' }, { "input", 1, 0, 'i' }, + { "output", 1, 0, 'o' }, { "loop", 0, 0, 'l' }, { "cpha", 0, 0, 'H' }, { "cpol", 0, 0, 'O' }, @@ -186,7 +203,7 @@ static void parse_opts(int argc, char *argv[]) }; int c; - c = getopt_long(argc, argv, "D:s:d:b:i:lHOLC3NR24p:v", + c = getopt_long(argc, argv, "D:s:d:b:i:o:lHOLC3NR24p:v", lopts, NULL); if (c == -1) @@ -208,6 +225,9 @@ static void parse_opts(int argc, char *argv[]) case 'i': input_file = optarg; break; + case 'o': + output_file = optarg; + break; case 'l': mode |= SPI_LOOP; break; -- GitLab From a20874f78be633b9e3a505d5f191735188b110a5 Mon Sep 17 00:00:00 2001 From: Joshua Clayton Date: Wed, 18 Nov 2015 14:30:41 -0800 Subject: [PATCH 0570/2855] spi: spidev_test: check error Check the result of sscanf to verify a result was found. report and error and abort if pattern was not found. Signed-off-by: Joshua Clayton Signed-off-by: Mark Brown --- tools/spi/spidev_test.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/spi/spidev_test.c b/tools/spi/spidev_test.c index 02fc3a44901b5..322370dbc7702 100644 --- a/tools/spi/spidev_test.c +++ b/tools/spi/spidev_test.c @@ -86,13 +86,17 @@ static void hex_dump(const void *src, size_t length, size_t line_size, char *pre static int unescape(char *_dst, char *_src, size_t len) { int ret = 0; + int match; char *src = _src; char *dst = _dst; unsigned int ch; while (*src) { if (*src == '\\' && *(src+1) == 'x') { - sscanf(src + 2, "%2x", &ch); + match = sscanf(src + 2, "%2x", &ch); + if (!match) + pabort("malformed input string"); + src += 4; *dst++ = (unsigned char)ch; } else { -- GitLab From b2cfc90428f1c24ce4920f06b584bd05c62741e6 Mon Sep 17 00:00:00 2001 From: Joshua Clayton Date: Wed, 18 Nov 2015 14:30:42 -0800 Subject: [PATCH 0571/2855] spi: spidev_test: fix whitespace Signed-off-by: Joshua Clayton Signed-off-by: Mark Brown --- tools/spi/spidev_test.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/spi/spidev_test.c b/tools/spi/spidev_test.c index 322370dbc7702..eddfc336a960f 100644 --- a/tools/spi/spidev_test.c +++ b/tools/spi/spidev_test.c @@ -52,7 +52,8 @@ uint8_t default_tx[] = { uint8_t default_rx[ARRAY_SIZE(default_tx)] = {0, }; char *input_tx; -static void hex_dump(const void *src, size_t length, size_t line_size, char *prefix) +static void hex_dump(const void *src, size_t length, size_t line_size, + char *prefix) { int i = 0; const unsigned char *address = src; @@ -164,7 +165,7 @@ static void print_usage(const char *prog) puts(" -D --device device to use (default /dev/spidev1.1)\n" " -s --speed max speed (Hz)\n" " -d --delay delay (usec)\n" - " -b --bpw bits per word \n" + " -b --bpw bits per word\n" " -i --input input data from a file (e.g. \"test.bin\")\n" " -o --output output data to a file (e.g. \"results.bin\")\n" " -l --loop loopback\n" -- GitLab From 6f18dc893981e4daab29221d6a9771f3ce2dd8c5 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 12 Nov 2015 09:44:33 -0500 Subject: [PATCH 0572/2855] svcrdma: Do not send XDR roundup bytes for a write chunk Minor optimization: when dealing with write chunk XDR roundup, do not post a Write WR for the zero bytes in the pad. Simply update the write segment in the RPC-over-RDMA header to reflect the extra pad bytes. The Reply chunk is also a write chunk, but the server does not use send_write_chunks() to send the Reply chunk. That's OK in this case: the server Upper Layer typically marshals the Reply chunk contents in a single contiguous buffer, without a separate tail for the XDR pad. The comments and the variable naming refer to "chunks" but what is really meant is "segments." The existing code sends only one xdr_write_chunk per RPC reply. The fix assumes this as well. When the XDR pad in the first write chunk is reached, the assumption is the Write list is complete and send_write_chunks() returns. That will remain a valid assumption until the server Upper Layer can support multiple bulk payload results per RPC. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields --- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index 969a1ab75fc3c..bad5eaa9f812b 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -342,6 +342,13 @@ static int send_write_chunks(struct svcxprt_rdma *xprt, arg_ch->rs_handle, arg_ch->rs_offset, write_len); + + /* Do not send XDR pad bytes */ + if (chunk_no && write_len < 4) { + chunk_no++; + break; + } + chunk_off = 0; while (write_len) { ret = send_write(xprt, rqstp, -- GitLab From 7c582e4faaf2593116068fc9ec8f5d81f720c02b Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 22 Nov 2015 08:22:10 +0100 Subject: [PATCH 0573/2855] nfsd: recover: constify nfsd4_client_tracking_ops structures The nfsd4_client_tracking_ops structures are never modified, so declare them as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Reviewed-by: Jeff Layton Signed-off-by: J. Bruce Fields --- fs/nfsd/netns.h | 2 +- fs/nfsd/nfs4recover.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h index d8b16c2568f30..5fbf3bbd00d04 100644 --- a/fs/nfsd/netns.h +++ b/fs/nfsd/netns.h @@ -92,7 +92,7 @@ struct nfsd_net { struct file *rec_file; bool in_grace; - struct nfsd4_client_tracking_ops *client_tracking_ops; + const struct nfsd4_client_tracking_ops *client_tracking_ops; time_t nfsd4_lease; time_t nfsd4_grace; diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index e3d47091b191d..79f0307a5ec83 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -631,7 +631,7 @@ nfsd4_check_legacy_client(struct nfs4_client *clp) return -ENOENT; } -static struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = { +static const struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = { .init = nfsd4_legacy_tracking_init, .exit = nfsd4_legacy_tracking_exit, .create = nfsd4_create_clid_dir, @@ -1050,7 +1050,7 @@ out_err: printk(KERN_ERR "NFSD: Unable to end grace period: %d\n", ret); } -static struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops = { +static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops = { .init = nfsd4_init_cld_pipe, .exit = nfsd4_remove_cld_pipe, .create = nfsd4_cld_create, @@ -1394,7 +1394,7 @@ nfsd4_umh_cltrack_grace_done(struct nfsd_net *nn) kfree(legacy); } -static struct nfsd4_client_tracking_ops nfsd4_umh_tracking_ops = { +static const struct nfsd4_client_tracking_ops nfsd4_umh_tracking_ops = { .init = nfsd4_umh_cltrack_init, .exit = NULL, .create = nfsd4_umh_cltrack_create, -- GitLab From c4cb897462c93ba09543d912344c29a26c92eb31 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 21 Nov 2015 22:57:39 +0100 Subject: [PATCH 0574/2855] nfsd: constify nfsd4_callback_ops structure The nfsd4_callback_ops structure is never modified, so declare it as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Reviewed-by: Christoph Hellwig Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4callback.c | 2 +- fs/nfsd/nfs4layouts.c | 4 ++-- fs/nfsd/nfs4state.c | 4 ++-- fs/nfsd/state.h | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index e7f50c4081d60..081709c3fa4fd 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -1143,7 +1143,7 @@ nfsd4_run_cb_work(struct work_struct *work) } void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp, - struct nfsd4_callback_ops *ops, enum nfsd4_cb_op op) + const struct nfsd4_callback_ops *ops, enum nfsd4_cb_op op) { cb->cb_clp = clp; cb->cb_msg.rpc_proc = &nfs4_cb_procedures[op]; diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c index 9ffef06b30d51..fec49febb75b2 100644 --- a/fs/nfsd/nfs4layouts.c +++ b/fs/nfsd/nfs4layouts.c @@ -22,7 +22,7 @@ struct nfs4_layout { static struct kmem_cache *nfs4_layout_cache; static struct kmem_cache *nfs4_layout_stateid_cache; -static struct nfsd4_callback_ops nfsd4_cb_layout_ops; +static const struct nfsd4_callback_ops nfsd4_cb_layout_ops; static const struct lock_manager_operations nfsd4_layouts_lm_ops; const struct nfsd4_layout_ops *nfsd4_layout_ops[LAYOUT_TYPE_MAX] = { @@ -665,7 +665,7 @@ nfsd4_cb_layout_release(struct nfsd4_callback *cb) nfs4_put_stid(&ls->ls_stid); } -static struct nfsd4_callback_ops nfsd4_cb_layout_ops = { +static const struct nfsd4_callback_ops nfsd4_cb_layout_ops = { .prepare = nfsd4_cb_layout_prepare, .done = nfsd4_cb_layout_done, .release = nfsd4_cb_layout_release, diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 6b800b5b8fedb..0d30a36bbae61 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -98,7 +98,7 @@ static struct kmem_cache *odstate_slab; static void free_session(struct nfsd4_session *); -static struct nfsd4_callback_ops nfsd4_cb_recall_ops; +static const struct nfsd4_callback_ops nfsd4_cb_recall_ops; static bool is_session_dead(struct nfsd4_session *ses) { @@ -3648,7 +3648,7 @@ static void nfsd4_cb_recall_release(struct nfsd4_callback *cb) nfs4_put_stid(&dp->dl_stid); } -static struct nfsd4_callback_ops nfsd4_cb_recall_ops = { +static const struct nfsd4_callback_ops nfsd4_cb_recall_ops = { .prepare = nfsd4_cb_recall_prepare, .done = nfsd4_cb_recall_done, .release = nfsd4_cb_recall_release, diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 77fdf4de91baa..5e2ba19fe3cb4 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -65,7 +65,7 @@ struct nfsd4_callback { struct nfs4_client *cb_clp; u32 cb_minorversion; struct rpc_message cb_msg; - struct nfsd4_callback_ops *cb_ops; + const struct nfsd4_callback_ops *cb_ops; struct work_struct cb_work; int cb_seq_status; int cb_status; @@ -599,7 +599,7 @@ extern void nfsd4_probe_callback(struct nfs4_client *clp); extern void nfsd4_probe_callback_sync(struct nfs4_client *clp); extern void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *); extern void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp, - struct nfsd4_callback_ops *ops, enum nfsd4_cb_op op); + const struct nfsd4_callback_ops *ops, enum nfsd4_cb_op op); extern void nfsd4_run_cb(struct nfsd4_callback *cb); extern int nfsd4_create_callback_queue(void); extern void nfsd4_destroy_callback_queue(void); -- GitLab From d3f03403a8735cebfcc16db4edfbf07c5c7421f5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 21 Nov 2015 13:28:50 +0300 Subject: [PATCH 0575/2855] nfsd: fix a warning message The WARN() macro takes a condition and a format string. The condition was accidentally left out here so it just prints the function name instead of the message. Signed-off-by: Dan Carpenter Reviewed-by: Jeff Layton Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4state.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 0d30a36bbae61..9f6beb8e99187 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -2240,7 +2240,8 @@ nfsd4_store_cache_entry(struct nfsd4_compoundres *resp) base = resp->cstate.data_offset; slot->sl_datalen = buf->len - base; if (read_bytes_from_xdr_buf(buf, base, slot->sl_data, slot->sl_datalen)) - WARN("%s: sessions DRC could not cache compound\n", __func__); + WARN(1, "%s: sessions DRC could not cache compound\n", + __func__); return; } -- GitLab From 832df9e8ecabec271a0c418bdbb94da826dc5b6d Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Fri, 20 Nov 2015 17:53:59 +0900 Subject: [PATCH 0576/2855] extcon: arizona: Update naming for second jack detection DT binding Update the name for the second jack detection pin binding to be a little less confusing. Signed-off-by: Charles Keepax Acked-by: Rob Herring Signed-off-by: Chanwoo Choi --- Documentation/devicetree/bindings/extcon/extcon-arizona.txt | 4 ++-- drivers/extcon/extcon-arizona.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/extcon/extcon-arizona.txt b/Documentation/devicetree/bindings/extcon/extcon-arizona.txt index 7640a3502c67f..8aa0bd430f7b7 100644 --- a/Documentation/devicetree/bindings/extcon/extcon-arizona.txt +++ b/Documentation/devicetree/bindings/extcon/extcon-arizona.txt @@ -14,9 +14,9 @@ Optional properties: If this node is not mentioned or if the value is unknown, then headphone detection mode is set to HPDETL. - - wlf,use-jd-gpio : Use GPIO input along with JD1 for dual pin jack + - wlf,use-jd2 : Use the additional JD input along with JD1 for dual pin jack detection. - - wlf,use-jd-gpio-nopull : Internal pull on GPIO is disabled when used for + - wlf,use-jd2-nopull : Internal pull on JD2 is disabled when used for jack detection. - wlf,jd-invert : Invert the polarity of the jack detection switch diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index 7c9598db318dc..c377030807c45 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -1245,9 +1245,9 @@ static int arizona_extcon_device_get_pdata(struct arizona *arizona) device_property_read_u32(arizona->dev, "wlf,gpsw", &pdata->gpsw); pdata->jd_gpio5 = device_property_read_bool(arizona->dev, - "wlf,use-jd-gpio"); + "wlf,use-jd2"); pdata->jd_gpio5_nopull = device_property_read_bool(arizona->dev, - "wlf,use-jd-gpio-nopull"); + "wlf,use-jd2-nopull"); return 0; } -- GitLab From 7a7ef0f2a4b359d0206772bf291781157d07f7dc Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 23 Nov 2015 14:51:30 +0000 Subject: [PATCH 0577/2855] extcon: arizona: Update naming for micd-timeout DT to include units Add time units of -ms (milliseconds) to wlf,micd-timeout. Signed-off-by: Charles Keepax Signed-off-by: Chanwoo Choi --- Documentation/devicetree/bindings/extcon/extcon-arizona.txt | 2 +- drivers/extcon/extcon-arizona.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/extcon/extcon-arizona.txt b/Documentation/devicetree/bindings/extcon/extcon-arizona.txt index 8aa0bd430f7b7..238e10e86a204 100644 --- a/Documentation/devicetree/bindings/extcon/extcon-arizona.txt +++ b/Documentation/devicetree/bindings/extcon/extcon-arizona.txt @@ -33,7 +33,7 @@ Optional properties: specified as per the ARIZONA_MICD_TIME_XXX defines. - wlf,micd-dbtime : Microphone detection hardware debounces specified as the number of measurements to take, valid values being 2 and 4. - - wlf,micd-timeout : Timeout for microphone detection, specified in + - wlf,micd-timeout-ms : Timeout for microphone detection, specified in milliseconds. - wlf,micd-force-micbias : Force MICBIAS continuously on during microphone detection. diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index c377030807c45..86475338e51ee 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -1230,7 +1230,7 @@ static int arizona_extcon_device_get_pdata(struct arizona *arizona) device_property_read_u32(arizona->dev, "wlf,micd-dbtime", &pdata->micd_dbtime); - device_property_read_u32(arizona->dev, "wlf,micd-timeout", + device_property_read_u32(arizona->dev, "wlf,micd-timeout-ms", &pdata->micd_timeout); pdata->micd_force_micbias = device_property_read_bool(arizona->dev, -- GitLab From 1b5df59e50874b9034c0fa389cd52b65f1f93292 Mon Sep 17 00:00:00 2001 From: Vaibhav Jain Date: Mon, 16 Nov 2015 09:33:45 +0530 Subject: [PATCH 0578/2855] cxl: Fix possible idr warning when contexts are released An idr warning is reported when a context is release after the capi card is unbound from the cxl driver via sysfs. Below are the steps to reproduce: 1. Create multiple afu contexts in an user-space application using libcxl. 2. Unbind capi card from cxl using command of form echo > /sys/bus/pci/drivers/cxl-pci/unbind 3. Exit/kill the application owning afu contexts. After above steps a warning message is usually seen in the kernel logs of the form "idr_remove called for id= which is not allocated." This is caused by the function cxl_release_afu which destroys the contexts_idr table. So when a context is release no entry for context pe is found in the contexts_idr table and idr code prints this warning. This patch fixes this issue by increasing & decreasing the ref-count on the afu device when a context is initialized or when its freed respectively. This prevents the afu from being released until all the afu contexts have been released. The patch introduces two new functions namely cxl_afu_get/put that manage the ref-count on the afu device. Also the patch removes code inside cxl_dev_context_init that increases ref on the afu device as its guaranteed to be alive during this function. Reported-by: Ian Munsie Signed-off-by: Vaibhav Jain Acked-by: Ian Munsie Signed-off-by: Michael Ellerman --- drivers/misc/cxl/api.c | 4 ---- drivers/misc/cxl/context.c | 9 +++++++++ drivers/misc/cxl/cxl.h | 12 ++++++++++++ drivers/misc/cxl/file.c | 19 +++++++++++-------- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c index 103baf0e0c5bf..a6543aefa299d 100644 --- a/drivers/misc/cxl/api.c +++ b/drivers/misc/cxl/api.c @@ -25,7 +25,6 @@ struct cxl_context *cxl_dev_context_init(struct pci_dev *dev) afu = cxl_pci_to_afu(dev); - get_device(&afu->dev); ctx = cxl_context_alloc(); if (IS_ERR(ctx)) { rc = PTR_ERR(ctx); @@ -61,7 +60,6 @@ err_mapping: err_ctx: kfree(ctx); err_dev: - put_device(&afu->dev); return ERR_PTR(rc); } EXPORT_SYMBOL_GPL(cxl_dev_context_init); @@ -87,8 +85,6 @@ int cxl_release_context(struct cxl_context *ctx) if (ctx->status >= STARTED) return -EBUSY; - put_device(&ctx->afu->dev); - cxl_context_free(ctx); return 0; diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c index 2faa1270d085b..6dde7a9d6a7e2 100644 --- a/drivers/misc/cxl/context.c +++ b/drivers/misc/cxl/context.c @@ -97,6 +97,12 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master, ctx->pe = i; ctx->elem = &ctx->afu->spa[i]; ctx->pe_inserted = false; + + /* + * take a ref on the afu so that it stays alive at-least till + * this context is reclaimed inside reclaim_ctx. + */ + cxl_afu_get(afu); return 0; } @@ -278,6 +284,9 @@ static void reclaim_ctx(struct rcu_head *rcu) if (ctx->irq_bitmap) kfree(ctx->irq_bitmap); + /* Drop ref to the afu device taken during cxl_context_init */ + cxl_afu_put(ctx->afu); + kfree(ctx); } diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index 0cfb9c129f273..25ae57fa79b0f 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -403,6 +403,18 @@ struct cxl_afu { bool enabled; }; +/* AFU refcount management */ +static inline struct cxl_afu *cxl_afu_get(struct cxl_afu *afu) +{ + + return (get_device(&afu->dev) == NULL) ? NULL : afu; +} + +static inline void cxl_afu_put(struct cxl_afu *afu) +{ + put_device(&afu->dev); +} + struct cxl_irq_name { struct list_head list; diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c index 7ccd2998be92b..5cc14599837d1 100644 --- a/drivers/misc/cxl/file.c +++ b/drivers/misc/cxl/file.c @@ -67,7 +67,13 @@ static int __afu_open(struct inode *inode, struct file *file, bool master) spin_unlock(&adapter->afu_list_lock); goto err_put_adapter; } - get_device(&afu->dev); + + /* + * taking a ref to the afu so that it doesn't go away + * for rest of the function. This ref is released before + * we return. + */ + cxl_afu_get(afu); spin_unlock(&adapter->afu_list_lock); if (!afu->current_mode) @@ -90,13 +96,12 @@ static int __afu_open(struct inode *inode, struct file *file, bool master) file->private_data = ctx; cxl_ctx_get(); - /* Our ref on the AFU will now hold the adapter */ - put_device(&adapter->dev); - - return 0; + /* indicate success */ + rc = 0; err_put_afu: - put_device(&afu->dev); + /* release the ref taken earlier */ + cxl_afu_put(afu); err_put_adapter: put_device(&adapter->dev); return rc; @@ -131,8 +136,6 @@ int afu_release(struct inode *inode, struct file *file) mutex_unlock(&ctx->mapping_lock); } - put_device(&ctx->afu->dev); - /* * At this this point all bottom halfs have finished and we should be * getting no more IRQs from the hardware for this context. Once it's -- GitLab From 48f0f6b717e314a30be121b67e1d044f6d311d66 Mon Sep 17 00:00:00 2001 From: Andrew Donnellan Date: Wed, 4 Nov 2015 13:24:09 +1100 Subject: [PATCH 0579/2855] cxl: use correct operator when writing pcie config space values When writing a value to config space, cxl_pcie_write_config() calls cxl_pcie_config_info() to obtain a mask and shift value, shifts the new value accordingly, then uses the mask to combine the shifted value with the existing value at the address as part of a read-modify-write pattern. Currently, we use a logical OR operator rather than a bitwise OR operator, which means any use of this function results in an incorrect value being written. Replace the logical OR operator with a bitwise OR operator so the value is written correctly. Reported-by: Michael Ellerman Cc: stable@vger.kernel.org Fixes: 6f7f0b3df6d4 ("cxl: Add AFU virtual PHB and kernel API") Signed-off-by: Andrew Donnellan Acked-by: Ian Munsie Signed-off-by: Michael Ellerman --- drivers/misc/cxl/vphb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c index c241e15cacb1f..cbd4331fb45cb 100644 --- a/drivers/misc/cxl/vphb.c +++ b/drivers/misc/cxl/vphb.c @@ -203,7 +203,7 @@ static int cxl_pcie_write_config(struct pci_bus *bus, unsigned int devfn, mask <<= shift; val <<= shift; - v = (in_le32(ioaddr) & ~mask) || (val & mask); + v = (in_le32(ioaddr) & ~mask) | (val & mask); out_le32(ioaddr, v); return PCIBIOS_SUCCESSFUL; -- GitLab From 87630eb1d5ab76fc39e785294d1930bebcecabcf Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 19 Nov 2015 13:00:39 +0900 Subject: [PATCH 0580/2855] powerpc/powernv: Drop owner assignment from platform_driver platform_driver does not need to set an owner because platform_driver_register() will set it. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/opal-prd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/opal-prd.c b/arch/powerpc/platforms/powernv/opal-prd.c index 4ece8e40dd541..e315e704cca71 100644 --- a/arch/powerpc/platforms/powernv/opal-prd.c +++ b/arch/powerpc/platforms/powernv/opal-prd.c @@ -434,7 +434,6 @@ static const struct of_device_id opal_prd_match[] = { static struct platform_driver opal_prd_driver = { .driver = { .name = "opal-prd", - .owner = THIS_MODULE, .of_match_table = opal_prd_match, }, .probe = opal_prd_probe, -- GitLab From 6223a30935852369fd797f44eeafac445e422ac4 Mon Sep 17 00:00:00 2001 From: Alexandra Yates Date: Fri, 6 Nov 2015 15:19:48 -0800 Subject: [PATCH 0581/2855] mfd: lpc_ich: Intel device IDs for PCH Adding Intel codename Lewisburg platform device IDs for PCH. Signed-off-by: Alexandra Yates Reviewed-by: Andy Shevchenko Signed-off-by: Lee Jones --- drivers/mfd/lpc_ich.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c index b514f3cf140d1..bd3aa45783460 100644 --- a/drivers/mfd/lpc_ich.c +++ b/drivers/mfd/lpc_ich.c @@ -55,6 +55,7 @@ * document number TBD : Coleto Creek * document number TBD : Wildcat Point-LP * document number TBD : 9 Series + * document number TBD : Lewisburg */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -213,6 +214,7 @@ enum lpc_chipsets { LPC_COLETO, /* Coleto Creek */ LPC_WPT_LP, /* Wildcat Point-LP */ LPC_BRASWELL, /* Braswell SoC */ + LPC_LEWISBURG, /* Lewisburg */ LPC_9S, /* 9 Series */ }; @@ -521,6 +523,10 @@ static struct lpc_ich_info lpc_chipset_info[] = { .name = "Braswell SoC", .iTCO_version = 3, }, + [LPC_LEWISBURG] = { + .name = "Lewisburg", + .iTCO_version = 2, + }, [LPC_9S] = { .name = "9 Series", .iTCO_version = 2, @@ -757,6 +763,15 @@ static const struct pci_device_id lpc_ich_ids[] = { { PCI_VDEVICE(INTEL, 0x9cc6), LPC_WPT_LP}, { PCI_VDEVICE(INTEL, 0x9cc7), LPC_WPT_LP}, { PCI_VDEVICE(INTEL, 0x9cc9), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0xa1c1), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c2), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c3), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c4), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c5), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c6), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c7), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa242), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa243), LPC_LEWISBURG}, { 0, }, /* End of list */ }; MODULE_DEVICE_TABLE(pci, lpc_ich_ids); -- GitLab From 2fadbbf02d81c825b1627f673499d0e0b9d132b6 Mon Sep 17 00:00:00 2001 From: Alim Akhtar Date: Fri, 20 Nov 2015 16:18:26 +0530 Subject: [PATCH 0582/2855] mfd: sec-core: Rename MFD and regulator names differently Currently S2MPSXX multifunction device is named as *-pmic, and these MFDs also supports regulator as a one of its MFD cell which has the same name, because current name is confusing and we want to sort it out. We did discussed different approaches about how the MFD and it cells need to be named here [1]. Based in the discussion this patch rename MFD regulator name as *-regulator instead of current *-pmic. This patch also changes the corresponding entries in the regulator driver to keep git-bisect happy. [1]-> https://lkml.org/lkml/2015/10/28/417 Suggested-by: Lee Jones Signed-off-by: Alim Akhtar Reviewed-by: Krzysztof Kozlowski Acked-by: Mark Brown Signed-off-by: Lee Jones --- drivers/mfd/sec-core.c | 8 ++++---- drivers/regulator/s2mps11.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index 7c4e7be17f1e2..c9802ba9be721 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -68,7 +68,7 @@ static const struct mfd_cell s5m8767_devs[] = { static const struct mfd_cell s2mps11_devs[] = { { - .name = "s2mps11-pmic", + .name = "s2mps11-regulator", }, { .name = "s2mps14-rtc", }, { @@ -78,7 +78,7 @@ static const struct mfd_cell s2mps11_devs[] = { }; static const struct mfd_cell s2mps13_devs[] = { - { .name = "s2mps13-pmic", }, + { .name = "s2mps13-regulator", }, { .name = "s2mps13-rtc", }, { .name = "s2mps13-clk", @@ -88,7 +88,7 @@ static const struct mfd_cell s2mps13_devs[] = { static const struct mfd_cell s2mps14_devs[] = { { - .name = "s2mps14-pmic", + .name = "s2mps14-regulator", }, { .name = "s2mps14-rtc", }, { @@ -116,7 +116,7 @@ static const struct mfd_cell s2mpa01_devs[] = { static const struct mfd_cell s2mpu02_devs[] = { { - .name = "s2mpu02-pmic", + .name = "s2mpu02-regulator", }, }; diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index b2f3a28e720ce..3242ffc0cb25a 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -1199,11 +1199,11 @@ out: } static const struct platform_device_id s2mps11_pmic_id[] = { - { "s2mps11-pmic", S2MPS11X}, - { "s2mps13-pmic", S2MPS13X}, - { "s2mps14-pmic", S2MPS14X}, + { "s2mps11-regulator", S2MPS11X}, + { "s2mps13-regulator", S2MPS13X}, + { "s2mps14-regulator", S2MPS14X}, { "s2mps15-regulator", S2MPS15X}, - { "s2mpu02-pmic", S2MPU02}, + { "s2mpu02-regulator", S2MPU02}, { }, }; MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id); -- GitLab From 51669f89931d7e07c297fa11028cd1e3a4cef09c Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Mon, 21 Sep 2015 11:25:40 -0500 Subject: [PATCH 0583/2855] Documentation: dt-bindings: Fix interrupt documentation file path Fix the incorrect interrupt documentation file path in binding docs. Signed-off-by: Andrew F. Davis Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt | 2 +- Documentation/devicetree/bindings/mfd/arizona.txt | 2 +- Documentation/devicetree/bindings/mfd/palmas.txt | 2 +- Documentation/devicetree/bindings/sound/wm8994.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt index dd5d2c0394b13..4d6c8cdc85860 100644 --- a/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt +++ b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt @@ -24,7 +24,7 @@ controller. - #interrupt-cells : Specifies the number of cells needed to encode an interrupt. Shall be set to 2. The first cell defines the interrupt number, the second encodes the triger flags encoded as described in - Documentation/devicetree/bindings/interrupts.txt + Documentation/devicetree/bindings/interrupt-controller/interrupts.txt - interrupt-parent : The parent interrupt controller. - interrupts : The interrupt to the parent controller raised when GPIOs generate the interrupts. diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt b/Documentation/devicetree/bindings/mfd/arizona.txt index 18be0cbfb456c..2c5d0387fe98c 100644 --- a/Documentation/devicetree/bindings/mfd/arizona.txt +++ b/Documentation/devicetree/bindings/mfd/arizona.txt @@ -24,7 +24,7 @@ Required properties: - #interrupt-cells: the number of cells to describe an IRQ, this should be 2. The first cell is the IRQ number. The second cell is the flags, encoded as the trigger masks from - Documentation/devicetree/bindings/interrupts.txt + Documentation/devicetree/bindings/interrupt-controller/interrupts.txt - gpio-controller : Indicates this device is a GPIO controller. - #gpio-cells : Must be 2. The first cell is the pin number and the diff --git a/Documentation/devicetree/bindings/mfd/palmas.txt b/Documentation/devicetree/bindings/mfd/palmas.txt index eda898978d333..8ae1a32bfb7eb 100644 --- a/Documentation/devicetree/bindings/mfd/palmas.txt +++ b/Documentation/devicetree/bindings/mfd/palmas.txt @@ -24,7 +24,7 @@ and also the generic series names - #interrupt-cells : should be set to 2 for IRQ number and flags The first cell is the IRQ number. The second cell is the flags, encoded as the trigger masks from - Documentation/devicetree/bindings/interrupts.txt + Documentation/devicetree/bindings/interrupt-controller/interrupts.txt - interrupt-parent : The parent interrupt controller. Optional properties: diff --git a/Documentation/devicetree/bindings/sound/wm8994.txt b/Documentation/devicetree/bindings/sound/wm8994.txt index e045e90a0924b..68c4e8d96bed6 100644 --- a/Documentation/devicetree/bindings/sound/wm8994.txt +++ b/Documentation/devicetree/bindings/sound/wm8994.txt @@ -30,7 +30,7 @@ Optional properties: - #interrupt-cells: the number of cells to describe an IRQ, this should be 2. The first cell is the IRQ number. The second cell is the flags, encoded as the trigger masks from - Documentation/devicetree/bindings/interrupts.txt + Documentation/devicetree/bindings/interrupt-controller/interrupts.txt - clocks : A list of up to two phandle and clock specifier pairs - clock-names : A list of clock names sorted in the same order as clocks. -- GitLab From cc509d5ba2b74fea8d0598cc941f4b5e4052740a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 Nov 2015 16:46:14 +0000 Subject: [PATCH 0584/2855] mfd: wm8994: Ensure that the whole MFD is built into a single module The MFD part of wm8994 consists of three files wm8994-core.c, wm8994-irq.c and wm8994-regmap.c only wm8994-core.c has a MODULE_DESCRIPTION / LICENSE. These were clearly intended to be built as a single module, but currently are not. This will lead to a tainted kernel when loading modules for wm8894-irq.c and wm8994-regmap.c because are missing a license. This patch fixes this issue by grouping the three files together into a single module. Reported-by: Peter Robinson Signed-off-by: Charles Keepax Signed-off-by: Lee Jones --- drivers/mfd/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index a8b76b81b4679..99f93ab26348b 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -61,7 +61,8 @@ wm8350-objs := wm8350-core.o wm8350-regmap.o wm8350-gpio.o wm8350-objs += wm8350-irq.o obj-$(CONFIG_MFD_WM8350) += wm8350.o obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o -obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o wm8994-regmap.o +wm8994-objs := wm8994-core.o wm8994-irq.o wm8994-regmap.o +obj-$(CONFIG_MFD_WM8994) += wm8994.o obj-$(CONFIG_TPS6105X) += tps6105x.o obj-$(CONFIG_TPS65010) += tps65010.o -- GitLab From 6496500cf15f29ac8afc565e2e4b6f92a1324860 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Fri, 20 Nov 2015 15:45:35 -0500 Subject: [PATCH 0585/2855] svcrpc: move some initialization to common code Minor cleanup, no change in behavior. Signed-off-by: J. Bruce Fields --- net/sunrpc/svcauth.c | 2 ++ net/sunrpc/svcauth_unix.c | 8 -------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c index 79c0f3459b5c3..69841db1f5335 100644 --- a/net/sunrpc/svcauth.c +++ b/net/sunrpc/svcauth.c @@ -55,6 +55,7 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp) spin_unlock(&authtab_lock); rqstp->rq_auth_slack = 0; + init_svc_cred(&rqstp->rq_cred); rqstp->rq_authop = aops; return aops->accept(rqstp, authp); @@ -63,6 +64,7 @@ EXPORT_SYMBOL_GPL(svc_authenticate); int svc_set_client(struct svc_rqst *rqstp) { + rqstp->rq_client = NULL; return rqstp->rq_authop->set_client(rqstp); } EXPORT_SYMBOL_GPL(svc_set_client); diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 621ca7b4a1552..dfacdc95b3f52 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c @@ -728,10 +728,6 @@ svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp) struct kvec *resv = &rqstp->rq_res.head[0]; struct svc_cred *cred = &rqstp->rq_cred; - cred->cr_group_info = NULL; - cred->cr_principal = NULL; - rqstp->rq_client = NULL; - if (argv->iov_len < 3*4) return SVC_GARBAGE; @@ -794,10 +790,6 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) u32 slen, i; int len = argv->iov_len; - cred->cr_group_info = NULL; - cred->cr_principal = NULL; - rqstp->rq_client = NULL; - if ((len -= 3*4) < 0) return SVC_GARBAGE; -- GitLab From 50043859325b377e728676d31aad7affaf91b2ce Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Fri, 20 Nov 2015 15:58:37 -0500 Subject: [PATCH 0586/2855] nfsd: helper for dup of possibly NULL string Technically the initialization in the NULL case isn't even needed as the only caller already has target zeroed out, but it seems safer to keep copy_cred generic. Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4state.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 9f6beb8e99187..641604a221bc6 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1857,15 +1857,24 @@ static void copy_clid(struct nfs4_client *target, struct nfs4_client *source) target->cl_clientid.cl_id = source->cl_clientid.cl_id; } -static int copy_cred(struct svc_cred *target, struct svc_cred *source) +int strdup_if_nonnull(char **target, char *source) { - if (source->cr_principal) { - target->cr_principal = - kstrdup(source->cr_principal, GFP_KERNEL); - if (target->cr_principal == NULL) + if (source) { + *target = kstrdup(source, GFP_KERNEL); + if (!*target) return -ENOMEM; } else - target->cr_principal = NULL; + *target = NULL; + return 0; +} + +static int copy_cred(struct svc_cred *target, struct svc_cred *source) +{ + int ret; + + ret = strdup_if_nonnull(&target->cr_principal, source->cr_principal); + if (ret) + return ret; target->cr_flavor = source->cr_flavor; target->cr_uid = source->cr_uid; target->cr_gid = source->cr_gid; -- GitLab From 50c7b948adbd1f8f0475fa0c92abb51c8a49f847 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Mon, 23 Nov 2015 15:39:12 -0700 Subject: [PATCH 0587/2855] nfsd: minor consolidation of mach_cred handling code Minor cleanup, no change in functionality. Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4state.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 641604a221bc6..efa3d4c09dabf 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -2375,10 +2375,17 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, if (exid->flags & ~EXCHGID4_FLAG_MASK_A) return nfserr_inval; + new = create_client(exid->clname, rqstp, &verf); + if (new == NULL) + return nfserr_jukebox; + switch (exid->spa_how) { case SP4_MACH_CRED: - if (!svc_rqst_integrity_protected(rqstp)) - return nfserr_inval; + if (!svc_rqst_integrity_protected(rqstp)) { + status = nfserr_inval; + goto out_nolock; + } + new->cl_mach_cred = true; case SP4_NONE: break; default: /* checked by xdr code */ @@ -2387,10 +2394,6 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, return nfserr_encr_alg_unsupp; } - new = create_client(exid->clname, rqstp, &verf); - if (new == NULL) - return nfserr_jukebox; - /* Cases below refer to rfc 5661 section 18.35.4: */ spin_lock(&nn->client_lock); conf = find_confirmed_client_by_name(&exid->clname, nn); @@ -2452,7 +2455,6 @@ out_new: goto out; } new->cl_minorversion = cstate->minorversion; - new->cl_mach_cred = (exid->spa_how == SP4_MACH_CRED); gen_clid(new, nn); add_to_unconfirmed(new); @@ -2470,6 +2472,7 @@ out_copy: out: spin_unlock(&nn->client_lock); +out_nolock: if (new) expire_client(new); if (unconf) -- GitLab From 920dd9bb7d7cf9ae339e15240326a28a22f08a74 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Fri, 20 Nov 2015 16:42:40 -0500 Subject: [PATCH 0588/2855] nfsd: fix unlikely NULL deref in mach_creds_match We really shouldn't allow a client to be created with cl_mach_cred set unless it also has a principal name. This also allows us to fail such cases immediately on EXCHANGE_ID as opposed to waiting and incorrectly returning WRONG_CRED on the following CREATE_SESSION. Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4state.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index efa3d4c09dabf..ed58ced6fa8b9 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -2385,6 +2385,15 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, status = nfserr_inval; goto out_nolock; } + /* + * Sometimes userspace doesn't give us a principal. + * Which is a bug, really. Anyway, we can't enforce + * MACH_CRED in that case, better to give up now: + */ + if (!new->cl_cred.cr_principal) { + status = nfserr_serverfault; + goto out_nolock; + } new->cl_mach_cred = true; case SP4_NONE: break; -- GitLab From 414ca017a54d26c3a58ed1504884e51448d22ae1 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Fri, 20 Nov 2015 10:48:02 -0500 Subject: [PATCH 0589/2855] nfsd4: fix gss-proxy 4.1 mounts for some AD principals The principal name on a gss cred is used to setup the NFSv4.0 callback, which has to have a client principal name to authenticate to. That code wants the name to be in the form servicetype@hostname. rpc.svcgssd passes down such names (and passes down no principal name at all in the case the principal isn't a service principal). gss-proxy always passes down the principal name, and passes it down in the form servicetype/hostname@REALM. So we've been munging the name gss-proxy passes down into the format the NFSv4.0 callback code expects, or throwing away the name if we can't. Since the introduction of the MACH_CRED enforcement in NFSv4.1, we've also been using the principal name to verify that certain operations are done as the same principal as was used on the original EXCHANGE_ID call. For that application, the original name passed down by gss-proxy is also useful. Lack of that name in some cases was causing some kerberized NFSv4.1 mount failures in an Active Directory environment. This fix only works in the gss-proxy case. The fix for legacy rpc.svcgssd would be more involved, and rpc.svcgssd already has other problems in the AD case. Reported-and-tested-by: James Ralston Acked-by: Simo Sorce Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4state.c | 10 +++++++++- include/linux/sunrpc/svcauth.h | 9 ++++++++- net/sunrpc/auth_gss/gss_rpc_upcall.c | 3 +++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index ed58ced6fa8b9..113ecbfac25ce 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1873,6 +1873,10 @@ static int copy_cred(struct svc_cred *target, struct svc_cred *source) int ret; ret = strdup_if_nonnull(&target->cr_principal, source->cr_principal); + if (ret) + return ret; + ret = strdup_if_nonnull(&target->cr_raw_principal, + source->cr_raw_principal); if (ret) return ret; target->cr_flavor = source->cr_flavor; @@ -1978,6 +1982,9 @@ static bool mach_creds_match(struct nfs4_client *cl, struct svc_rqst *rqstp) return false; if (!svc_rqst_integrity_protected(rqstp)) return false; + if (cl->cl_cred.cr_raw_principal) + return 0 == strcmp(cl->cl_cred.cr_raw_principal, + cr->cr_raw_principal); if (!cr->cr_principal) return false; return 0 == strcmp(cl->cl_cred.cr_principal, cr->cr_principal); @@ -2390,7 +2397,8 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, * Which is a bug, really. Anyway, we can't enforce * MACH_CRED in that case, better to give up now: */ - if (!new->cl_cred.cr_principal) { + if (!new->cl_cred.cr_principal && + !new->cl_cred.cr_raw_principal) { status = nfserr_serverfault; goto out_nolock; } diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h index 8d71d6577459c..c00f53a4ccdd7 100644 --- a/include/linux/sunrpc/svcauth.h +++ b/include/linux/sunrpc/svcauth.h @@ -23,13 +23,19 @@ struct svc_cred { kgid_t cr_gid; struct group_info *cr_group_info; u32 cr_flavor; /* pseudoflavor */ - char *cr_principal; /* for gss */ + /* name of form servicetype/hostname@REALM, passed down by + * gss-proxy: */ + char *cr_raw_principal; + /* name of form servicetype@hostname, passed down by + * rpc.svcgssd, or computed from the above: */ + char *cr_principal; struct gss_api_mech *cr_gss_mech; }; static inline void init_svc_cred(struct svc_cred *cred) { cred->cr_group_info = NULL; + cred->cr_raw_principal = NULL; cred->cr_principal = NULL; cred->cr_gss_mech = NULL; } @@ -38,6 +44,7 @@ static inline void free_svc_cred(struct svc_cred *cred) { if (cred->cr_group_info) put_group_info(cred->cr_group_info); + kfree(cred->cr_raw_principal); kfree(cred->cr_principal); gss_mech_put(cred->cr_gss_mech); init_svc_cred(cred); diff --git a/net/sunrpc/auth_gss/gss_rpc_upcall.c b/net/sunrpc/auth_gss/gss_rpc_upcall.c index 59eeed43eda2d..f0c6a8c78a567 100644 --- a/net/sunrpc/auth_gss/gss_rpc_upcall.c +++ b/net/sunrpc/auth_gss/gss_rpc_upcall.c @@ -326,6 +326,9 @@ int gssp_accept_sec_context_upcall(struct net *net, if (data->found_creds && client_name.data != NULL) { char *c; + data->creds.cr_raw_principal = kstrndup(client_name.data, + client_name.len, GFP_KERNEL); + data->creds.cr_principal = kstrndup(client_name.data, client_name.len, GFP_KERNEL); if (data->creds.cr_principal) { -- GitLab From 24e394b08e11be8fdc7a769f757a775367a36b7d Mon Sep 17 00:00:00 2001 From: Egor Uleyskiy Date: Sun, 22 Nov 2015 11:27:52 +0200 Subject: [PATCH 0590/2855] drivers: staging: vme: Fixed indention Signed-off-by: Egor Uleyskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_pio2_cntr.c | 2 +- drivers/staging/vme/devices/vme_pio2_core.c | 16 +++++++------- drivers/staging/vme/devices/vme_pio2_gpio.c | 24 ++++++++++----------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/staging/vme/devices/vme_pio2_cntr.c b/drivers/staging/vme/devices/vme_pio2_cntr.c index 6335471faa368..486c30c4956f8 100644 --- a/drivers/staging/vme/devices/vme_pio2_cntr.c +++ b/drivers/staging/vme/devices/vme_pio2_cntr.c @@ -61,7 +61,7 @@ int pio2_cntr_reset(struct pio2_card *card) /* Ensure all counter interrupts are cleared */ do { retval = vme_master_read(card->window, ®, 1, - PIO2_REGS_INT_STAT_CNTR); + PIO2_REGS_INT_STAT_CNTR); if (retval < 0) return retval; } while (reg != 0); diff --git a/drivers/staging/vme/devices/vme_pio2_core.c b/drivers/staging/vme/devices/vme_pio2_core.c index 35c6ce5047de7..f3b878b441ee7 100644 --- a/drivers/staging/vme/devices/vme_pio2_core.c +++ b/drivers/staging/vme/devices/vme_pio2_core.c @@ -90,7 +90,7 @@ static void pio2_int(int level, int vector, void *ptr) case 4: /* Channels 0 to 7 */ retval = vme_master_read(card->window, ®, 1, - PIO2_REGS_INT_STAT[vec - 1]); + PIO2_REGS_INT_STAT[vec - 1]); if (retval < 0) { dev_err(&card->vdev->dev, "Unable to read IRQ status register\n"); @@ -100,8 +100,8 @@ static void pio2_int(int level, int vector, void *ptr) channel = ((vec - 1) * 8) + i; if (reg & PIO2_CHANNEL_BIT[channel]) dev_info(&card->vdev->dev, - "Interrupt on I/O channel %d\n", - channel); + "Interrupt on I/O channel %d\n", + channel); } break; case 5: @@ -289,7 +289,7 @@ static int pio2_probe(struct vme_dev *vdev) } retval = vme_master_set(card->window, 1, card->base, 0x10000, VME_A24, - (VME_SCT | VME_USER | VME_DATA), VME_D16); + (VME_SCT | VME_USER | VME_DATA), VME_D16); if (retval) { dev_err(&card->vdev->dev, "Unable to configure VME master resource\n"); @@ -335,7 +335,7 @@ static int pio2_probe(struct vme_dev *vdev) /* Set VME vector */ retval = vme_master_write(card->window, &card->irq_vector, 1, - PIO2_REGS_VME_VECTOR); + PIO2_REGS_VME_VECTOR); if (retval < 0) return retval; @@ -343,7 +343,7 @@ static int pio2_probe(struct vme_dev *vdev) vec = card->irq_vector | PIO2_VME_VECTOR_SPUR; retval = vme_irq_request(vdev, card->irq_level, vec, - &pio2_int, (void *)card); + &pio2_int, (void *)card); if (retval < 0) { dev_err(&card->vdev->dev, "Unable to attach VME interrupt vector0x%x, level 0x%x\n", @@ -356,7 +356,7 @@ static int pio2_probe(struct vme_dev *vdev) vec = card->irq_vector | PIO2_VECTOR_BANK[i]; retval = vme_irq_request(vdev, card->irq_level, vec, - &pio2_int, (void *)card); + &pio2_int, (void *)card); if (retval < 0) { dev_err(&card->vdev->dev, "Unable to attach VME interrupt vector0x%x, level 0x%x\n", @@ -397,7 +397,7 @@ static int pio2_probe(struct vme_dev *vdev) dev_set_drvdata(&card->vdev->dev, card); dev_info(&card->vdev->dev, - "PIO2 (variant %s) configured at 0x%lx\n", card->variant, + "PIO2 (variant %s) configured at 0x%lx\n", card->variant, card->base); return 0; diff --git a/drivers/staging/vme/devices/vme_pio2_gpio.c b/drivers/staging/vme/devices/vme_pio2_gpio.c index 77901b345a716..0b72dac16d56c 100644 --- a/drivers/staging/vme/devices/vme_pio2_gpio.c +++ b/drivers/staging/vme/devices/vme_pio2_gpio.c @@ -37,14 +37,14 @@ static int pio2_gpio_get(struct gpio_chip *chip, unsigned int offset) struct pio2_card *card = gpio_to_pio2_card(chip); if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == OUTPUT) | - (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) { + (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) { dev_err(&card->vdev->dev, "Channel not available as input\n"); return 0; } retval = vme_master_read(card->window, ®, 1, - PIO2_REGS_DATA[PIO2_CHANNEL_BANK[offset]]); + PIO2_REGS_DATA[PIO2_CHANNEL_BANK[offset]]); if (retval < 0) { dev_err(&card->vdev->dev, "Unable to read from GPIO\n"); return 0; @@ -67,15 +67,15 @@ static int pio2_gpio_get(struct gpio_chip *chip, unsigned int offset) return 0; } -static void pio2_gpio_set(struct gpio_chip *chip, unsigned int offset, - int value) +static void pio2_gpio_set(struct gpio_chip *chip, + unsigned int offset, int value) { u8 reg; int retval; struct pio2_card *card = gpio_to_pio2_card(chip); if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) | - (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) { + (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) { dev_err(&card->vdev->dev, "Channel not available as output\n"); return; @@ -89,7 +89,7 @@ static void pio2_gpio_set(struct gpio_chip *chip, unsigned int offset, ~PIO2_CHANNEL_BIT[offset]; retval = vme_master_write(card->window, ®, 1, - PIO2_REGS_DATA[PIO2_CHANNEL_BANK[offset]]); + PIO2_REGS_DATA[PIO2_CHANNEL_BANK[offset]]); if (retval < 0) { dev_err(&card->vdev->dev, "Unable to write to GPIO\n"); return; @@ -105,7 +105,7 @@ static int pio2_gpio_dir_in(struct gpio_chip *chip, unsigned offset) struct pio2_card *card = gpio_to_pio2_card(chip); if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == OUTPUT) | - (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) { + (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) { dev_err(&card->vdev->dev, "Channel directionality not configurable at runtime\n"); @@ -124,7 +124,7 @@ static int pio2_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value) struct pio2_card *card = gpio_to_pio2_card(chip); if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) | - (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) { + (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) { dev_err(&card->vdev->dev, "Channel directionality not configurable at runtime\n"); @@ -150,7 +150,7 @@ int pio2_gpio_reset(struct pio2_card *card) /* Zero output registers */ for (i = 0; i < 4; i++) { retval = vme_master_write(card->window, &data, 1, - PIO2_REGS_DATA[i]); + PIO2_REGS_DATA[i]); if (retval < 0) return retval; card->bank[i].value = 0; @@ -159,12 +159,12 @@ int pio2_gpio_reset(struct pio2_card *card) /* Set input interrupt masks */ for (i = 0; i < 4; i++) { retval = vme_master_write(card->window, &data, 1, - PIO2_REGS_INT_MASK[i * 2]); + PIO2_REGS_INT_MASK[i * 2]); if (retval < 0) return retval; retval = vme_master_write(card->window, &data, 1, - PIO2_REGS_INT_MASK[(i * 2) + 1]); + PIO2_REGS_INT_MASK[(i * 2) + 1]); if (retval < 0) return retval; @@ -176,7 +176,7 @@ int pio2_gpio_reset(struct pio2_card *card) for (i = 0; i < 4; i++) { do { retval = vme_master_read(card->window, &data, 1, - PIO2_REGS_INT_STAT[i]); + PIO2_REGS_INT_STAT[i]); if (retval < 0) return retval; } while (data != 0); -- GitLab From cad5636db7a28693dbed3268cb1ee4fe7ddaf6b4 Mon Sep 17 00:00:00 2001 From: Egor Uleyskiy Date: Sun, 22 Nov 2015 11:27:53 +0200 Subject: [PATCH 0591/2855] drivers: staging: vme: Deleted extra empty lines Signed-off-by: Egor Uleyskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_pio2_gpio.c | 2 -- drivers/staging/vme/devices/vme_user.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/staging/vme/devices/vme_pio2_gpio.c b/drivers/staging/vme/devices/vme_pio2_gpio.c index 0b72dac16d56c..e09f6bb881b6f 100644 --- a/drivers/staging/vme/devices/vme_pio2_gpio.c +++ b/drivers/staging/vme/devices/vme_pio2_gpio.c @@ -38,7 +38,6 @@ static int pio2_gpio_get(struct gpio_chip *chip, unsigned int offset) if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == OUTPUT) | (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) { - dev_err(&card->vdev->dev, "Channel not available as input\n"); return 0; } @@ -76,7 +75,6 @@ static void pio2_gpio_set(struct gpio_chip *chip, if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) | (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) { - dev_err(&card->vdev->dev, "Channel not available as output\n"); return; } diff --git a/drivers/staging/vme/devices/vme_user.h b/drivers/staging/vme/devices/vme_user.h index b8cc7bc78a739..a6cb75686fa4c 100644 --- a/drivers/staging/vme/devices/vme_user.h +++ b/drivers/staging/vme/devices/vme_user.h @@ -20,7 +20,6 @@ struct vme_master { #endif } __packed; - /* * IOCTL Commands and structures */ @@ -28,7 +27,6 @@ struct vme_master { /* Magic number for use in ioctls */ #define VME_IOC_MAGIC 0xAE - /* VMEbus Slave Window Configuration Structure */ struct vme_slave { __u32 enable; /* State of Window */ -- GitLab From 93a28666a9fadc56fa700e496bb549faf490f3a4 Mon Sep 17 00:00:00 2001 From: Egor Uleyskiy Date: Sun, 22 Nov 2015 11:27:54 +0200 Subject: [PATCH 0592/2855] drivers: staging: vme: Fixed the using of sizeof Constructions that looks like card = kzalloc(sizeof(struct pio2_card), GFP_KERNEL); are changed to card = kzalloc(sizeof(*card), GFP_KERNEL); Signed-off-by: Egor Uleyskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_pio2_core.c | 2 +- drivers/staging/vme/devices/vme_user.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/vme/devices/vme_pio2_core.c b/drivers/staging/vme/devices/vme_pio2_core.c index f3b878b441ee7..a30282a57b6bc 100644 --- a/drivers/staging/vme/devices/vme_pio2_core.c +++ b/drivers/staging/vme/devices/vme_pio2_core.c @@ -215,7 +215,7 @@ static int pio2_probe(struct vme_dev *vdev) u8 reg; int vec; - card = kzalloc(sizeof(struct pio2_card), GFP_KERNEL); + card = kzalloc(sizeof(*card), GFP_KERNEL); if (!card) { retval = -ENOMEM; goto err_struct; diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 8e61a3b3e7e47..a05a065686de8 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -308,7 +308,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, switch (cmd) { case VME_IRQ_GEN: copied = copy_from_user(&irq_req, argp, - sizeof(struct vme_irq_id)); + sizeof(irq_req)); if (copied != 0) { pr_warn("Partial copy from userspace\n"); return -EFAULT; @@ -322,7 +322,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, case MASTER_MINOR: switch (cmd) { case VME_GET_MASTER: - memset(&master, 0, sizeof(struct vme_master)); + memset(&master, 0, sizeof(master)); /* XXX We do not want to push aspace, cycle and width * to userspace as they are @@ -334,7 +334,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, &master.cycle, &master.dwidth); copied = copy_to_user(argp, &master, - sizeof(struct vme_master)); + sizeof(master)); if (copied != 0) { pr_warn("Partial copy to userspace\n"); return -EFAULT; @@ -368,7 +368,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, case SLAVE_MINOR: switch (cmd) { case VME_GET_SLAVE: - memset(&slave, 0, sizeof(struct vme_slave)); + memset(&slave, 0, sizeof(slave)); /* XXX We do not want to push aspace, cycle and width * to userspace as they are @@ -379,7 +379,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, &slave.aspace, &slave.cycle); copied = copy_to_user(argp, &slave, - sizeof(struct vme_slave)); + sizeof(slave)); if (copied != 0) { pr_warn("Partial copy to userspace\n"); return -EFAULT; -- GitLab From 48a42206dd343f490f40ddaf44e8f0f9fb3aed37 Mon Sep 17 00:00:00 2001 From: Egor Uleyskiy Date: Sun, 22 Nov 2015 11:27:55 +0200 Subject: [PATCH 0593/2855] drivers: staging: vme: Deleted extra bracking * Deleted extra bracking of VME_* constants * Deleted extra bracking of address operator Signed-off-by: Egor Uleyskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_pio2_core.c | 2 +- drivers/staging/vme/devices/vme_pio2_gpio.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/vme/devices/vme_pio2_core.c b/drivers/staging/vme/devices/vme_pio2_core.c index a30282a57b6bc..296551f9499b5 100644 --- a/drivers/staging/vme/devices/vme_pio2_core.c +++ b/drivers/staging/vme/devices/vme_pio2_core.c @@ -289,7 +289,7 @@ static int pio2_probe(struct vme_dev *vdev) } retval = vme_master_set(card->window, 1, card->base, 0x10000, VME_A24, - (VME_SCT | VME_USER | VME_DATA), VME_D16); + VME_SCT | VME_USER | VME_DATA, VME_D16); if (retval) { dev_err(&card->vdev->dev, "Unable to configure VME master resource\n"); diff --git a/drivers/staging/vme/devices/vme_pio2_gpio.c b/drivers/staging/vme/devices/vme_pio2_gpio.c index e09f6bb881b6f..65fdb562e9034 100644 --- a/drivers/staging/vme/devices/vme_pio2_gpio.c +++ b/drivers/staging/vme/devices/vme_pio2_gpio.c @@ -205,7 +205,7 @@ int pio2_gpio_init(struct pio2_card *card) card->gc.set = pio2_gpio_set; /* This function adds a memory mapped GPIO chip */ - retval = gpiochip_add(&(card->gc)); + retval = gpiochip_add(&card->gc); if (retval) { dev_err(&card->vdev->dev, "Unable to register GPIO\n"); kfree(card->gc.label); @@ -218,7 +218,7 @@ void pio2_gpio_exit(struct pio2_card *card) { const char *label = card->gc.label; - gpiochip_remove(&(card->gc)); + gpiochip_remove(&card->gc); kfree(label); } -- GitLab From 59a04f11350bcf5653aee760fb3d5e06a651b640 Mon Sep 17 00:00:00 2001 From: Egor Uleyskiy Date: Sun, 22 Nov 2015 11:27:56 +0200 Subject: [PATCH 0594/2855] drivers: staging: vme: Fixed checking NULL and 0 code style Signed-off-by: Egor Uleyskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_pio2_core.c | 2 +- drivers/staging/vme/devices/vme_pio2_gpio.c | 2 +- drivers/staging/vme/devices/vme_user.c | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/vme/devices/vme_pio2_core.c b/drivers/staging/vme/devices/vme_pio2_core.c index 296551f9499b5..30712daf54fe2 100644 --- a/drivers/staging/vme/devices/vme_pio2_core.c +++ b/drivers/staging/vme/devices/vme_pio2_core.c @@ -230,7 +230,7 @@ static int pio2_probe(struct vme_dev *vdev) card->vdev = vdev; for (i = 0; i < PIO2_VARIANT_LENGTH; i++) { - if (isdigit(card->variant[i]) == 0) { + if (!isdigit(card->variant[i])) { dev_err(&card->vdev->dev, "Variant invalid\n"); retval = -EINVAL; goto err_variant; diff --git a/drivers/staging/vme/devices/vme_pio2_gpio.c b/drivers/staging/vme/devices/vme_pio2_gpio.c index 65fdb562e9034..df992c3cb5ce0 100644 --- a/drivers/staging/vme/devices/vme_pio2_gpio.c +++ b/drivers/staging/vme/devices/vme_pio2_gpio.c @@ -190,7 +190,7 @@ int pio2_gpio_init(struct pio2_card *card) label = kasprintf(GFP_KERNEL, "%s@%s", driver_name, dev_name(&card->vdev->dev)); - if (label == NULL) + if (!label) return -ENOMEM; card->gc.label = label; diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index a05a065686de8..b95883bc68fea 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -309,7 +309,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, case VME_IRQ_GEN: copied = copy_from_user(&irq_req, argp, sizeof(irq_req)); - if (copied != 0) { + if (copied) { pr_warn("Partial copy from userspace\n"); return -EFAULT; } @@ -335,7 +335,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, copied = copy_to_user(argp, &master, sizeof(master)); - if (copied != 0) { + if (copied) { pr_warn("Partial copy to userspace\n"); return -EFAULT; } @@ -350,7 +350,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, } copied = copy_from_user(&master, argp, sizeof(master)); - if (copied != 0) { + if (copied) { pr_warn("Partial copy from userspace\n"); return -EFAULT; } @@ -380,7 +380,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, copied = copy_to_user(argp, &slave, sizeof(slave)); - if (copied != 0) { + if (copied) { pr_warn("Partial copy to userspace\n"); return -EFAULT; } @@ -390,7 +390,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, case VME_SET_SLAVE: copied = copy_from_user(&slave, argp, sizeof(slave)); - if (copied != 0) { + if (copied) { pr_warn("Partial copy from userspace\n"); return -EFAULT; } @@ -757,7 +757,7 @@ static int __init vme_user_init(void) * we just change the code in vme_user_match(). */ retval = vme_register_driver(&vme_user_driver, VME_MAX_SLOTS); - if (retval != 0) + if (retval) goto err_reg; return retval; -- GitLab From 6e23ec4a1118e8dbabee8e62ec20ef78e9aa804d Mon Sep 17 00:00:00 2001 From: Egor Uleyskiy Date: Sun, 22 Nov 2015 11:27:57 +0200 Subject: [PATCH 0595/2855] drivers: staging: vme: Deleted casting to (void *) Signed-off-by: Egor Uleyskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_pio2_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/vme/devices/vme_pio2_core.c b/drivers/staging/vme/devices/vme_pio2_core.c index 30712daf54fe2..4f3cdbcedb3e3 100644 --- a/drivers/staging/vme/devices/vme_pio2_core.c +++ b/drivers/staging/vme/devices/vme_pio2_core.c @@ -343,7 +343,7 @@ static int pio2_probe(struct vme_dev *vdev) vec = card->irq_vector | PIO2_VME_VECTOR_SPUR; retval = vme_irq_request(vdev, card->irq_level, vec, - &pio2_int, (void *)card); + &pio2_int, card); if (retval < 0) { dev_err(&card->vdev->dev, "Unable to attach VME interrupt vector0x%x, level 0x%x\n", @@ -356,7 +356,7 @@ static int pio2_probe(struct vme_dev *vdev) vec = card->irq_vector | PIO2_VECTOR_BANK[i]; retval = vme_irq_request(vdev, card->irq_level, vec, - &pio2_int, (void *)card); + &pio2_int, card); if (retval < 0) { dev_err(&card->vdev->dev, "Unable to attach VME interrupt vector0x%x, level 0x%x\n", @@ -370,7 +370,7 @@ static int pio2_probe(struct vme_dev *vdev) vec = card->irq_vector | PIO2_VECTOR_CNTR[i]; retval = vme_irq_request(vdev, card->irq_level, vec, - &pio2_int, (void *)card); + &pio2_int, card); if (retval < 0) { dev_err(&card->vdev->dev, "Unable to attach VME interrupt vector0x%x, level 0x%x\n", -- GitLab From e38da37fa8f410e61f2a6c03b3d14fec11b00259 Mon Sep 17 00:00:00 2001 From: Leilk Liu Date: Wed, 25 Nov 2015 17:50:38 +0800 Subject: [PATCH 0596/2855] spi: mediatek: revise mtk_spi_probe() failure flow mtk_spi_probe() calls pm_runtime_enable(), after pm_runtime_enable() is called, it should call pm_runtime_disable() in the failure flow. Signed-off-by: Leilk Liu Signed-off-by: Mark Brown --- drivers/spi/spi-mt65xx.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index 6c1a96eb49ee7..00a36dacfe2fa 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c @@ -607,7 +607,8 @@ static int mtk_spi_probe(struct platform_device *pdev) ret = clk_set_parent(mdata->sel_clk, mdata->parent_clk); if (ret < 0) { dev_err(&pdev->dev, "failed to clk_set_parent (%d)\n", ret); - goto err_disable_clk; + clk_disable_unprepare(mdata->spi_clk); + goto err_put_master; } clk_disable_unprepare(mdata->spi_clk); @@ -617,7 +618,7 @@ static int mtk_spi_probe(struct platform_device *pdev) ret = devm_spi_register_master(&pdev->dev, master); if (ret) { dev_err(&pdev->dev, "failed to register master (%d)\n", ret); - goto err_put_master; + goto err_disable_runtime_pm; } if (mdata->dev_comp->need_pad_sel) { @@ -626,14 +627,14 @@ static int mtk_spi_probe(struct platform_device *pdev) "pad_num does not match num_chipselect(%d != %d)\n", mdata->pad_num, master->num_chipselect); ret = -EINVAL; - goto err_put_master; + goto err_disable_runtime_pm; } if (!master->cs_gpios && master->num_chipselect > 1) { dev_err(&pdev->dev, "cs_gpios not specified and num_chipselect > 1\n"); ret = -EINVAL; - goto err_put_master; + goto err_disable_runtime_pm; } if (master->cs_gpios) { @@ -644,7 +645,7 @@ static int mtk_spi_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "can't get CS GPIO %i\n", i); - goto err_put_master; + goto err_disable_runtime_pm; } } } @@ -652,8 +653,8 @@ static int mtk_spi_probe(struct platform_device *pdev) return 0; -err_disable_clk: - clk_disable_unprepare(mdata->spi_clk); +err_disable_runtime_pm: + pm_runtime_disable(&pdev->dev); err_put_master: spi_master_put(master); -- GitLab From 88467943b35d2c94c00c130166705ee18b775bbe Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 25 Nov 2015 12:34:07 +0800 Subject: [PATCH 0597/2855] regulator: pv88060: Fix irq leak Use devm_request_threaded_irq to ensure the irq is freed when unload the module. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/pv88060-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/pv88060-regulator.c b/drivers/regulator/pv88060-regulator.c index 60b16d835df72..69893f28122a6 100644 --- a/drivers/regulator/pv88060-regulator.c +++ b/drivers/regulator/pv88060-regulator.c @@ -365,7 +365,7 @@ static int pv88060_i2c_probe(struct i2c_client *i2c, return ret; } - ret = request_threaded_irq(i2c->irq, NULL, + ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL, pv88060_irq_handler, IRQF_TRIGGER_LOW|IRQF_ONESHOT, "pv88060", chip); -- GitLab From c0ea88b890d67cff2667188f14189d8346e89a0f Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 25 Nov 2015 13:59:04 +0200 Subject: [PATCH 0598/2855] regulator: tps65218: add support for LS3 current regulator Add support for TPS65218 LS3 current regulator, which is capable of 4 current input limit modes: 100, 200, 500, and 1000 uA. Signed-off-by: Nikita Kiryanov Signed-off-by: Mark Brown --- drivers/regulator/tps65218-regulator.c | 137 +++++++++++++++++++------ include/linux/mfd/tps65218.h | 7 +- include/linux/regulator/driver.h | 2 + 3 files changed, 115 insertions(+), 31 deletions(-) diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index a02c1b9610396..a5e5634eeb9e4 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -27,19 +27,22 @@ #include #include -enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 }; +enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, + DCDC5, DCDC6, LDO1, LS3 }; -#define TPS65218_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _er, _em, \ - _lr, _nlr, _delay, _fuv) \ +#define TPS65218_REGULATOR(_name, _id, _type, _ops, _n, _vr, _vm, _er, _em, \ + _cr, _cm, _lr, _nlr, _delay, _fuv) \ { \ .name = _name, \ .id = _id, \ .ops = &_ops, \ .n_voltages = _n, \ - .type = REGULATOR_VOLTAGE, \ + .type = _type, \ .owner = THIS_MODULE, \ .vsel_reg = _vr, \ .vsel_mask = _vm, \ + .csel_reg = _cr, \ + .csel_mask = _cm, \ .enable_reg = _er, \ .enable_mask = _em, \ .volt_table = NULL, \ @@ -80,6 +83,7 @@ static struct tps_info tps65218_pmic_regs[] = { TPS65218_INFO(DCDC5, "DCDC5", 1000000, 1000000), TPS65218_INFO(DCDC6, "DCDC6", 1800000, 1800000), TPS65218_INFO(LDO1, "LDO1", 900000, 3400000), + TPS65218_INFO(LS3, "LS3", -1, -1), }; #define TPS65218_OF_MATCH(comp, label) \ @@ -96,6 +100,7 @@ static const struct of_device_id tps65218_of_match[] = { TPS65218_OF_MATCH("ti,tps65218-dcdc5", tps65218_pmic_regs[DCDC5]), TPS65218_OF_MATCH("ti,tps65218-dcdc6", tps65218_pmic_regs[DCDC6]), TPS65218_OF_MATCH("ti,tps65218-ldo1", tps65218_pmic_regs[LDO1]), + TPS65218_OF_MATCH("ti,tps65218-ls3", tps65218_pmic_regs[LS3]), { } }; MODULE_DEVICE_TABLE(of, tps65218_of_match); @@ -175,6 +180,68 @@ static struct regulator_ops tps65218_ldo1_dcdc34_ops = { .map_voltage = regulator_map_voltage_linear_range, }; +static const int ls3_currents[] = { 100, 200, 500, 1000 }; + +static int tps65218_pmic_set_input_current_lim(struct regulator_dev *dev, + int lim_uA) +{ + unsigned int index = 0; + unsigned int num_currents = ARRAY_SIZE(ls3_currents); + struct tps65218 *tps = rdev_get_drvdata(dev); + + while (index < num_currents && ls3_currents[index] != lim_uA) + index++; + + if (index == num_currents) + return -EINVAL; + + return tps65218_set_bits(tps, dev->desc->csel_reg, dev->desc->csel_mask, + index << 2, TPS65218_PROTECT_L1); +} + +static int tps65218_pmic_set_current_limit(struct regulator_dev *dev, + int min_uA, int max_uA) +{ + int index = 0; + unsigned int num_currents = ARRAY_SIZE(ls3_currents); + struct tps65218 *tps = rdev_get_drvdata(dev); + + while (index < num_currents && ls3_currents[index] < max_uA) + index++; + + index--; + + if (index < 0 || ls3_currents[index] < min_uA) + return -EINVAL; + + return tps65218_set_bits(tps, dev->desc->csel_reg, dev->desc->csel_mask, + index << 2, TPS65218_PROTECT_L1); +} + +static int tps65218_pmic_get_current_limit(struct regulator_dev *dev) +{ + int retval; + unsigned int index; + struct tps65218 *tps = rdev_get_drvdata(dev); + + retval = tps65218_reg_read(tps, dev->desc->csel_reg, &index); + if (retval < 0) + return retval; + + index = (index & dev->desc->csel_mask) >> 2; + + return ls3_currents[index]; +} + +static struct regulator_ops tps65218_ls3_ops = { + .is_enabled = regulator_is_enabled_regmap, + .enable = tps65218_pmic_enable, + .disable = tps65218_pmic_disable, + .set_input_current_limit = tps65218_pmic_set_input_current_lim, + .set_current_limit = tps65218_pmic_set_current_limit, + .get_current_limit = tps65218_pmic_get_current_limit, +}; + /* Operations permitted on DCDC5, DCDC6 */ static struct regulator_ops tps65218_dcdc56_pmic_ops = { .is_enabled = regulator_is_enabled_regmap, @@ -183,36 +250,46 @@ static struct regulator_ops tps65218_dcdc56_pmic_ops = { }; static const struct regulator_desc regulators[] = { - TPS65218_REGULATOR("DCDC1", TPS65218_DCDC_1, tps65218_dcdc12_ops, 64, - TPS65218_REG_CONTROL_DCDC1, - TPS65218_CONTROL_DCDC1_MASK, - TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN, - dcdc1_dcdc2_ranges, 2, 4000, 0), - TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, tps65218_dcdc12_ops, 64, - TPS65218_REG_CONTROL_DCDC2, - TPS65218_CONTROL_DCDC2_MASK, - TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN, - dcdc1_dcdc2_ranges, 2, 4000, 0), - TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, tps65218_ldo1_dcdc34_ops, - 64, TPS65218_REG_CONTROL_DCDC3, + TPS65218_REGULATOR("DCDC1", TPS65218_DCDC_1, REGULATOR_VOLTAGE, + tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC1, + TPS65218_CONTROL_DCDC1_MASK, TPS65218_REG_ENABLE1, + TPS65218_ENABLE1_DC1_EN, 0, 0, dcdc1_dcdc2_ranges, + 2, 4000, 0), + TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, REGULATOR_VOLTAGE, + tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC2, + TPS65218_CONTROL_DCDC2_MASK, TPS65218_REG_ENABLE1, + TPS65218_ENABLE1_DC2_EN, 0, 0, dcdc1_dcdc2_ranges, + 2, 4000, 0), + TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, REGULATOR_VOLTAGE, + tps65218_ldo1_dcdc34_ops, 64, + TPS65218_REG_CONTROL_DCDC3, TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1, - TPS65218_ENABLE1_DC3_EN, ldo1_dcdc3_ranges, 2, 0, 0), - TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, tps65218_ldo1_dcdc34_ops, - 53, TPS65218_REG_CONTROL_DCDC4, - TPS65218_CONTROL_DCDC4_MASK, - TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN, - dcdc4_ranges, 2, 0, 0), - TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, tps65218_dcdc56_pmic_ops, - 1, -1, -1, TPS65218_REG_ENABLE1, - TPS65218_ENABLE1_DC5_EN, NULL, 0, 0, 1000000), - TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, tps65218_dcdc56_pmic_ops, - 1, -1, -1, TPS65218_REG_ENABLE1, - TPS65218_ENABLE1_DC6_EN, NULL, 0, 0, 1800000), - TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, tps65218_ldo1_dcdc34_ops, 64, + TPS65218_ENABLE1_DC3_EN, 0, 0, ldo1_dcdc3_ranges, 2, + 0, 0), + TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, REGULATOR_VOLTAGE, + tps65218_ldo1_dcdc34_ops, 53, + TPS65218_REG_CONTROL_DCDC4, + TPS65218_CONTROL_DCDC4_MASK, TPS65218_REG_ENABLE1, + TPS65218_ENABLE1_DC4_EN, 0, 0, dcdc4_ranges, 2, + 0, 0), + TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, REGULATOR_VOLTAGE, + tps65218_dcdc56_pmic_ops, 1, -1, -1, + TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC5_EN, 0, 0, + NULL, 0, 0, 1000000), + TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, REGULATOR_VOLTAGE, + tps65218_dcdc56_pmic_ops, 1, -1, -1, + TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, 0, 0, + NULL, 0, 0, 1800000), + TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, REGULATOR_VOLTAGE, + tps65218_ldo1_dcdc34_ops, 64, TPS65218_REG_CONTROL_LDO1, TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, - TPS65218_ENABLE2_LDO1_EN, ldo1_dcdc3_ranges, + TPS65218_ENABLE2_LDO1_EN, 0, 0, ldo1_dcdc3_ranges, 2, 0, 0), + TPS65218_REGULATOR("LS3", TPS65218_LS_3, REGULATOR_CURRENT, + tps65218_ls3_ops, 0, 0, 0, TPS65218_REG_ENABLE2, + TPS65218_ENABLE2_LS3_EN, TPS65218_REG_CONFIG2, + TPS65218_CONFIG2_LS3ILIM_MASK, NULL, 0, 0, 0), }; static int tps65218_regulator_probe(struct platform_device *pdev) diff --git a/include/linux/mfd/tps65218.h b/include/linux/mfd/tps65218.h index 2f9b593246ee6..d58f3b5f585a4 100644 --- a/include/linux/mfd/tps65218.h +++ b/include/linux/mfd/tps65218.h @@ -200,6 +200,8 @@ enum tps65218_regulator_id { TPS65218_DCDC_4, TPS65218_DCDC_5, TPS65218_DCDC_6, + /* LS's */ + TPS65218_LS_3, /* LDOs */ TPS65218_LDO_1, }; @@ -210,8 +212,11 @@ enum tps65218_regulator_id { #define TPS65218_NUM_DCDC 6 /* Number of LDO voltage regulators available */ #define TPS65218_NUM_LDO 1 +/* Number of total LS current regulators available */ +#define TPS65218_NUM_LS 1 /* Number of total regulators available */ -#define TPS65218_NUM_REGULATOR (TPS65218_NUM_DCDC + TPS65218_NUM_LDO) +#define TPS65218_NUM_REGULATOR (TPS65218_NUM_DCDC + TPS65218_NUM_LDO \ + + TPS65218_NUM_LS) /* Define the TPS65218 IRQ numbers */ enum tps65218_irqs { diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 9c2903e58adbd..16ac9e1088064 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -302,6 +302,8 @@ struct regulator_desc { unsigned int vsel_reg; unsigned int vsel_mask; + unsigned int csel_reg; + unsigned int csel_mask; unsigned int apply_reg; unsigned int apply_bit; unsigned int enable_reg; -- GitLab From f2fd578f16c49256ae493d4bf192e361be9224fe Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Sat, 7 Nov 2015 11:16:39 +0530 Subject: [PATCH 0599/2855] Staging: lustre: obd_cksum.h: Remove unused cksum_types_supported_server cksum_types_supported_server is defined in header file but not used anywhere. Hence remove it. Signed-off-by: Shraddha Barke Acked-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/include/obd_cksum.h | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/obd_cksum.h b/drivers/staging/lustre/lustre/include/obd_cksum.h index a0099d71773a7..01db604053939 100644 --- a/drivers/staging/lustre/lustre/include/obd_cksum.h +++ b/drivers/staging/lustre/lustre/include/obd_cksum.h @@ -133,29 +133,6 @@ static inline cksum_type_t cksum_types_supported_client(void) return ret; } -/* Server uses algos that perform at 50% or better of the Adler */ -static inline cksum_type_t cksum_types_supported_server(void) -{ - int base_speed; - cksum_type_t ret = OBD_CKSUM_ADLER; - - CDEBUG(D_INFO, "Crypto hash speed: crc %d, crc32c %d, adler %d\n", - cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32)), - cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C)), - cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_ADLER))); - - base_speed = cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_ADLER)) / 2; - - if (cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C)) >= - base_speed) - ret |= OBD_CKSUM_CRC32C; - if (cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32)) >= - base_speed) - ret |= OBD_CKSUM_CRC32; - - return ret; -} - /* Select the best checksum algorithm among those supplied in the cksum_types * input. * -- GitLab From 24069d287cba5bc0279eac83b34eae8f59fd10ef Mon Sep 17 00:00:00 2001 From: Anjali Menon Date: Fri, 20 Nov 2015 18:34:37 +0530 Subject: [PATCH 0600/2855] staging: unisys: visornic: Removed the blank line Removed the blank line before the close brace to remove the check detected by the checkpatch.pl CHECK: Blank lines aren't necessary before a close brace '}' Signed-off-by: Anjali Menon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visornic/visornic_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c index 296b11cea247f..05194707278a3 100644 --- a/drivers/staging/unisys/visornic/visornic_main.c +++ b/drivers/staging/unisys/visornic/visornic_main.c @@ -1742,7 +1742,6 @@ poll_for_irq(unsigned long v) atomic_set(&devdata->interrupt_rcvd, 0); mod_timer(&devdata->irq_poll_timer, msecs_to_jiffies(2)); - } /** -- GitLab From f84a187019ccfce97fbf38fa9f3a8261fef91d8e Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Tue, 24 Nov 2015 09:53:29 -0500 Subject: [PATCH 0601/2855] staging: unisys: better config switch comments We should provide more information in the Kconfig help for visorbus and visorinput. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/Kconfig | 7 ++++++- drivers/staging/unisys/visorinput/Kconfig | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/visorbus/Kconfig b/drivers/staging/unisys/visorbus/Kconfig index 9b299ac86015e..511388075ffaa 100644 --- a/drivers/staging/unisys/visorbus/Kconfig +++ b/drivers/staging/unisys/visorbus/Kconfig @@ -6,4 +6,9 @@ config UNISYS_VISORBUS tristate "Unisys visorbus driver" depends on UNISYSSPAR ---help--- - If you say Y here, you will enable the Unisys visorbus driver. + The visorbus driver is a virtualized bus for the Unisys s-Par firmware. + Virtualized devices allow Linux guests on a system to share disks and + network cards that do not have SR-IOV support, and to be accessed using + the partition desktop application. The visorbus driver is required to + discover devices on an s-Par guest, and must be present for any other + s-Par guest driver to function correctly. diff --git a/drivers/staging/unisys/visorinput/Kconfig b/drivers/staging/unisys/visorinput/Kconfig index d83deb4137e83..3476d419d32c3 100644 --- a/drivers/staging/unisys/visorinput/Kconfig +++ b/drivers/staging/unisys/visorinput/Kconfig @@ -6,5 +6,10 @@ config UNISYS_VISORINPUT tristate "Unisys visorinput driver" depends on UNISYSSPAR && UNISYS_VISORBUS && FB ---help--- - If you say Y here, you will enable the Unisys visorinput driver. + The Unisys s-Par visorinput driver provides a virtualized system + console (keyboard and mouse) that is accessible through the + s-Par firmware's user interface. s-Par provides video using the EFI + GOP protocol, so If this driver is not present, the Linux guest should + still boot with visible output in the partition desktop, but keyboard + and mouse interaction will not be available. -- GitLab From c43cd036e531ca54b885dee535f535ab58bf8a0f Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:37 +0100 Subject: [PATCH 0602/2855] atp870u: Remove workport Remove workport temporary variable to simplify the code. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 59 ++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 05301bc752eee..3db9d0cdc625d 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -51,7 +51,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) unsigned char i, j, c, target_id, lun,cmdp; unsigned char *prd; struct scsi_cmnd *workreq; - unsigned int workport, tmport, tmport1; + unsigned int tmport, tmport1; unsigned long adrcnt, k; #ifdef ED_DBGP unsigned long l; @@ -76,10 +76,9 @@ ch_sel: #endif dev->in_int[c] = 1; cmdp = inb(dev->ioport[c] + 0x10); - workport = dev->ioport[c]; if (dev->working[c] != 0) { if (dev->dev_id == ATP885_DEVID) { - tmport1 = workport + 0x16; + tmport1 = dev->ioport[c] + 0x16; if ((inb(tmport1) & 0x80) == 0) outb((inb(tmport1) | 0x80), tmport1); } @@ -160,7 +159,7 @@ stop_dma: * Flip wide */ if (dev->wide_id[c] != 0) { - tmport = workport + 0x1b; + tmport = dev->ioport[c] + 0x1b; outb(0x01, tmport); while ((inb(tmport) & 0x01) != 0x01) { outb(0x01, tmport); @@ -276,9 +275,9 @@ stop_dma: if (dev->dev_id == ATP885_DEVID) { j = inb(dev->baseport + 0x29) & 0xfe; outb(j, dev->baseport + 0x29); - tmport = workport + 0x16; + tmport = dev->ioport[c] + 0x16; } else { - tmport = workport + 0x10; + tmport = dev->ioport[c] + 0x10; outb(0x45, tmport); tmport += 0x06; } @@ -293,7 +292,7 @@ stop_dma: target_id &= 0x07; } if (dev->dev_id == ATP885_DEVID) { - tmport = workport + 0x10; + tmport = dev->ioport[c] + 0x10; outb(0x45, tmport); } workreq = dev->id[c][target_id].curr_req; @@ -304,7 +303,7 @@ stop_dma: printk("\n"); #endif - tmport = workport + 0x0f; + tmport = dev->ioport[c] + 0x0f; outb(lun, tmport); tmport += 0x02; outb(dev->id[c][target_id].devsp, tmport++); @@ -338,21 +337,21 @@ stop_dma: outb(i,tmpcip); } else if ((dev->dev_id == ATP880_DEVID1) || (dev->dev_id == ATP880_DEVID2) ) { - tmport = workport - 0x05; + tmport = dev->ioport[c] - 0x05; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport); } else { outb((unsigned char) (inb(tmport) & 0x3f), tmport); } } else { - tmport = workport + 0x3a; + tmport = dev->ioport[c] + 0x3a; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { outb((unsigned char) ((inb(tmport) & 0xf3) | 0x08), tmport); } else { outb((unsigned char) (inb(tmport) & 0xf3), tmport); } } - tmport = workport + 0x1b; + tmport = dev->ioport[c] + 0x1b; j = 0; id = 1; id = id << target_id; @@ -367,7 +366,7 @@ stop_dma: outb(j,tmport); } if (dev->id[c][target_id].last_len == 0) { - tmport = workport + 0x18; + tmport = dev->ioport[c] + 0x18; outb(0x08, tmport); dev->in_int[c] = 0; #ifdef ED_DBGP @@ -414,7 +413,7 @@ stop_dma: outb(0x00, tmpcip); tmpcip -= 0x02; } - tmport = workport + 0x18; + tmport = dev->ioport[c] + 0x18; /* * Check transfer direction */ @@ -488,7 +487,7 @@ go_42: * Take it back wide */ if (dev->wide_id[c] != 0) { - tmport = workport + 0x1b; + tmport = dev->ioport[c] + 0x1b; outb(0x01, tmport); while ((inb(tmport) & 0x01) != 0x01) { outb(0x01, tmport); @@ -523,7 +522,7 @@ go_42: outb(0x06, tmpcip); outb(0x00, tmpcip); tmpcip = tmpcip - 2; - tmport = workport + 0x10; + tmport = dev->ioport[c] + 0x10; outb(0x41, tmport); if (dev->dev_id == ATP885_DEVID) { tmport += 2; @@ -549,7 +548,7 @@ go_42: outb(0x06, tmpcip); outb(0x00, tmpcip); tmpcip = tmpcip - 2; - tmport = workport + 0x10; + tmport = dev->ioport[c] + 0x10; outb(0x41, tmport); if (dev->dev_id == ATP885_DEVID) { tmport += 2; @@ -584,7 +583,7 @@ go_42: dev->in_int[c] = 0; goto handled; } else { -// tmport = workport + 0x17; +// tmport = dev->ioport[c] + 0x17; // inb(tmport); // dev->working[c] = 0; dev->in_int[c] = 0; @@ -713,7 +712,6 @@ static void send_s870(struct atp_unit *dev,unsigned char c) unsigned char *prd; unsigned short int tmpcip, w; unsigned long l, bttl = 0; - unsigned int workport; unsigned long sg_count; if (dev->in_snd[c] != 0) { @@ -759,12 +757,11 @@ static void send_s870(struct atp_unit *dev,unsigned char c) dev->in_snd[c] = 0; return; cmd_subp: - workport = dev->ioport[c]; - tmport = workport + 0x1f; + tmport = dev->ioport[c] + 0x1f; if ((inb(tmport) & 0xb0) != 0) { goto abortsnd; } - tmport = workport + 0x1c; + tmport = dev->ioport[c] + 0x1c; if (inb(tmport) == 0) { goto oktosend; } @@ -800,7 +797,7 @@ oktosend: l = 0; } - tmport = workport + 0x1b; + tmport = dev->ioport[c] + 0x1b; j = 0; target_id = scmd_id(workreq); @@ -823,7 +820,7 @@ oktosend: * Write the command */ - tmport = workport; + tmport = dev->ioport[c]; outb(workreq->cmd_len, tmport++); outb(0x2c, tmport++); if (dev->dev_id == ATP885_DEVID) { @@ -834,7 +831,7 @@ oktosend: for (i = 0; i < workreq->cmd_len; i++) { outb(workreq->cmnd[i], tmport++); } - tmport = workport + 0x0f; + tmport = dev->ioport[c] + 0x0f; outb(workreq->device->lun, tmport); tmport += 0x02; /* @@ -874,11 +871,11 @@ oktosend: } outb((unsigned char) (inb(tmport) | 0x80), tmport); outb(0x80, tmport); - tmport = workport + 0x1c; + tmport = dev->ioport[c] + 0x1c; dev->id[c][target_id].dirct = 0; if (l == 0) { if (inb(tmport) == 0) { - tmport = workport + 0x18; + tmport = dev->ioport[c] + 0x18; #ifdef ED_DBGP printk("change SCSI_CMD_REG 0x08\n"); #endif @@ -947,7 +944,7 @@ oktosend: } else if ((dev->dev_id == ATP880_DEVID1) || (dev->dev_id == ATP880_DEVID2)) { tmpcip =tmpcip -2; - tmport = workport - 0x05; + tmport = dev->ioport[c] - 0x05; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport); } else { @@ -955,19 +952,19 @@ oktosend: } } else { tmpcip =tmpcip -2; - tmport = workport + 0x3a; + tmport = dev->ioport[c] + 0x3a; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { outb((inb(tmport) & 0xf3) | 0x08, tmport); } else { outb(inb(tmport) & 0xf3, tmport); } } - tmport = workport + 0x1c; + tmport = dev->ioport[c] + 0x1c; if(workreq->sc_data_direction == DMA_TO_DEVICE) { dev->id[c][target_id].dirct = 0x20; if (inb(tmport) == 0) { - tmport = workport + 0x18; + tmport = dev->ioport[c] + 0x18; outb(0x08, tmport); outb(0x01, tmpcip); #ifdef ED_DBGP @@ -980,7 +977,7 @@ oktosend: return; } if (inb(tmport) == 0) { - tmport = workport + 0x18; + tmport = dev->ioport[c] + 0x18; outb(0x08, tmport); outb(0x09, tmpcip); #ifdef ED_DBGP -- GitLab From b4263b3ce9bac236ee9317153a735ffeb635c0d9 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:38 +0100 Subject: [PATCH 0603/2855] atp870u: Remove tmport1 Remove tmport1 temporary variable to simplify the code. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 3db9d0cdc625d..aac7d4733a6ef 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -51,7 +51,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) unsigned char i, j, c, target_id, lun,cmdp; unsigned char *prd; struct scsi_cmnd *workreq; - unsigned int tmport, tmport1; + unsigned int tmport; unsigned long adrcnt, k; #ifdef ED_DBGP unsigned long l; @@ -78,9 +78,8 @@ ch_sel: cmdp = inb(dev->ioport[c] + 0x10); if (dev->working[c] != 0) { if (dev->dev_id == ATP885_DEVID) { - tmport1 = dev->ioport[c] + 0x16; - if ((inb(tmport1) & 0x80) == 0) - outb((inb(tmport1) | 0x80), tmport1); + if ((inb(dev->ioport[c] + 0x16) & 0x80) == 0) + outb((inb(dev->ioport[c] + 0x16) | 0x80), dev->ioport[c] + 0x16); } tmpcip = dev->pciport[c]; if ((inb(tmpcip) & 0x08) != 0) -- GitLab From 3a38e53ee6c6542410a32374a3bd5ae6c8fc9f09 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:39 +0100 Subject: [PATCH 0604/2855] atp870u: Untangle tmport Untangle the tmport crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 186 ++++++++++++++++------------------------- 1 file changed, 71 insertions(+), 115 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index aac7d4733a6ef..a25a300efde86 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -51,7 +51,6 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) unsigned char i, j, c, target_id, lun,cmdp; unsigned char *prd; struct scsi_cmnd *workreq; - unsigned int tmport; unsigned long adrcnt, k; #ifdef ED_DBGP unsigned long l; @@ -61,8 +60,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) struct atp_unit *dev = (struct atp_unit *)&host->hostdata; for (c = 0; c < 2; c++) { - tmport = dev->ioport[c] + 0x1f; - j = inb(tmport); + j = inb(dev->ioport[c] + 0x1f); if ((j & 0x80) != 0) { goto ch_sel; @@ -97,9 +95,8 @@ ch_sel: stop_dma: tmpcip = dev->pciport[c]; outb(0x00, tmpcip); - tmport -= 0x08; - i = inb(tmport); + i = inb(dev->ioport[c] + 0x17); if (dev->dev_id == ATP885_DEVID) { tmpcip += 2; @@ -107,9 +104,7 @@ stop_dma: tmpcip -= 2; } - tmport -= 0x02; - target_id = inb(tmport); - tmport += 0x02; + target_id = inb(dev->ioport[c] + 0x15); /* * Remap wide devices onto id numbers @@ -137,11 +132,10 @@ stop_dma: dev->last_cmd[c] = 0xff; } if (dev->dev_id == ATP885_DEVID) { - tmport -= 0x05; adrcnt = 0; - ((unsigned char *) &adrcnt)[2] = inb(tmport++); - ((unsigned char *) &adrcnt)[1] = inb(tmport++); - ((unsigned char *) &adrcnt)[0] = inb(tmport); + ((unsigned char *) &adrcnt)[2] = inb(dev->ioport[c] + 0x12); + ((unsigned char *) &adrcnt)[1] = inb(dev->ioport[c] + 0x13); + ((unsigned char *) &adrcnt)[0] = inb(dev->ioport[c] + 0x14); if (dev->id[c][target_id].last_len != adrcnt) { k = dev->id[c][target_id].last_len; @@ -150,7 +144,7 @@ stop_dma: dev->id[c][target_id].last_len = adrcnt; } #ifdef ED_DBGP - printk("tmport = %x dev->id[c][target_id].last_len = %d dev->id[c][target_id].tran_len = %d\n",tmport,dev->id[c][target_id].last_len,dev->id[c][target_id].tran_len); + printk("dev->id[c][target_id].last_len = %d dev->id[c][target_id].tran_len = %d\n",dev->id[c][target_id].last_len,dev->id[c][target_id].tran_len); #endif } @@ -158,10 +152,9 @@ stop_dma: * Flip wide */ if (dev->wide_id[c] != 0) { - tmport = dev->ioport[c] + 0x1b; - outb(0x01, tmport); - while ((inb(tmport) & 0x01) != 0x01) { - outb(0x01, tmport); + outb(0x01, dev->ioport[c] + 0x1b); + while ((inb(dev->ioport[c] + 0x1b) & 0x01) != 0x01) { + outb(0x01, dev->ioport[c] + 0x1b); } } /* @@ -196,19 +189,16 @@ stop_dma: if ((dev->last_cmd[c] & 0xf0) != 0x40) { dev->last_cmd[c] = 0xff; } - tmport -= 0x05; adrcnt = 0; - ((unsigned char *) &adrcnt)[2] = inb(tmport++); - ((unsigned char *) &adrcnt)[1] = inb(tmport++); - ((unsigned char *) &adrcnt)[0] = inb(tmport); + ((unsigned char *) &adrcnt)[2] = inb(dev->ioport[c] + 0x12); + ((unsigned char *) &adrcnt)[1] = inb(dev->ioport[c] + 0x13); + ((unsigned char *) &adrcnt)[0] = inb(dev->ioport[c] + 0x14); k = dev->id[c][target_id].last_len; k -= adrcnt; dev->id[c][target_id].tran_len = k; dev->id[c][target_id].last_len = adrcnt; - tmport -= 0x04; - outb(0x41, tmport); - tmport += 0x08; - outb(0x08, tmport); + outb(0x41, dev->ioport[c] + 0x10); + outb(0x08, dev->ioport[c] + 0x18); dev->in_int[c] = 0; goto handled; } @@ -227,10 +217,8 @@ stop_dma: printk(KERN_DEBUG "Device reselect\n"); #endif lun = 0; - tmport -= 0x07; if (cmdp == 0x44 || i==0x80) { - tmport += 0x0d; - lun = inb(tmport) & 0x07; + lun = inb(dev->ioport[c] + 0x1d) & 0x07; } else { if ((dev->last_cmd[c] & 0xf0) != 0x40) { dev->last_cmd[c] = 0xff; @@ -239,31 +227,27 @@ stop_dma: #ifdef ED_DBGP printk("cmdp = 0x41\n"); #endif - tmport += 0x02; adrcnt = 0; - ((unsigned char *) &adrcnt)[2] = inb(tmport++); - ((unsigned char *) &adrcnt)[1] = inb(tmport++); - ((unsigned char *) &adrcnt)[0] = inb(tmport); + ((unsigned char *) &adrcnt)[2] = inb(dev->ioport[c] + 0x12); + ((unsigned char *) &adrcnt)[1] = inb(dev->ioport[c] + 0x13); + ((unsigned char *) &adrcnt)[0] = inb(dev->ioport[c] + 0x14); k = dev->id[c][target_id].last_len; k -= adrcnt; dev->id[c][target_id].tran_len = k; dev->id[c][target_id].last_len = adrcnt; - tmport += 0x04; - outb(0x08, tmport); + outb(0x08, dev->ioport[c] + 0x18); dev->in_int[c] = 0; goto handled; } else { #ifdef ED_DBGP printk("cmdp != 0x41\n"); #endif - outb(0x46, tmport); + outb(0x46, dev->ioport[c] + 0x10); dev->id[c][target_id].dirct = 0x00; - tmport += 0x02; - outb(0x00, tmport++); - outb(0x00, tmport++); - outb(0x00, tmport++); - tmport += 0x03; - outb(0x08, tmport); + outb(0x00, dev->ioport[c] + 0x12); + outb(0x00, dev->ioport[c] + 0x13); + outb(0x00, dev->ioport[c] + 0x14); + outb(0x08, dev->ioport[c] + 0x18); dev->in_int[c] = 0; goto handled; } @@ -274,14 +258,10 @@ stop_dma: if (dev->dev_id == ATP885_DEVID) { j = inb(dev->baseport + 0x29) & 0xfe; outb(j, dev->baseport + 0x29); - tmport = dev->ioport[c] + 0x16; - } else { - tmport = dev->ioport[c] + 0x10; - outb(0x45, tmport); - tmport += 0x06; - } - - target_id = inb(tmport); + } else + outb(0x45, dev->ioport[c] + 0x10); + + target_id = inb(dev->ioport[c] + 0x16); /* * Remap wide identifiers */ @@ -290,10 +270,8 @@ stop_dma: } else { target_id &= 0x07; } - if (dev->dev_id == ATP885_DEVID) { - tmport = dev->ioport[c] + 0x10; - outb(0x45, tmport); - } + if (dev->dev_id == ATP885_DEVID) + outb(0x45, dev->ioport[c] + 0x10); workreq = dev->id[c][target_id].curr_req; #ifdef ED_DBGP scmd_printk(KERN_DEBUG, workreq, "CDB"); @@ -302,18 +280,16 @@ stop_dma: printk("\n"); #endif - tmport = dev->ioport[c] + 0x0f; - outb(lun, tmport); - tmport += 0x02; - outb(dev->id[c][target_id].devsp, tmport++); + outb(lun, dev->ioport[c] + 0x0f); + outb(dev->id[c][target_id].devsp, dev->ioport[c] + 0x11); adrcnt = dev->id[c][target_id].tran_len; k = dev->id[c][target_id].last_len; - outb(((unsigned char *) &k)[2], tmport++); - outb(((unsigned char *) &k)[1], tmport++); - outb(((unsigned char *) &k)[0], tmport++); + outb(((unsigned char *) &k)[2], dev->ioport[c] + 0x12); + outb(((unsigned char *) &k)[1], dev->ioport[c] + 0x13); + outb(((unsigned char *) &k)[0], dev->ioport[c] + 0x14); #ifdef ED_DBGP - printk("k %x, k[0] 0x%x k[1] 0x%x k[2] 0x%x\n", k, inb(tmport-1), inb(tmport-2), inb(tmport-3)); + printk("k %x, k[0] 0x%x k[1] 0x%x k[2] 0x%x\n", k, inb(dev->ioport[c] + 0x14), inb(dev->ioport[c] + 0x13), inb(dev->ioport[c] + 0x12)); #endif /* Remap wide */ j = target_id; @@ -322,8 +298,8 @@ stop_dma: } /* Add direction */ j |= dev->id[c][target_id].dirct; - outb(j, tmport++); - outb(0x80,tmport); + outb(j, dev->ioport[c] + 0x15); + outb(0x80, dev->ioport[c] + 0x16); /* enable 32 bit fifo transfer */ if (dev->dev_id == ATP885_DEVID) { @@ -336,21 +312,18 @@ stop_dma: outb(i,tmpcip); } else if ((dev->dev_id == ATP880_DEVID1) || (dev->dev_id == ATP880_DEVID2) ) { - tmport = dev->ioport[c] - 0x05; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { - outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport); + outb((unsigned char) ((inb(dev->ioport[c] - 0x05) & 0x3f) | 0xc0), dev->ioport[c] - 0x05);///minus 0x05??? } else { - outb((unsigned char) (inb(tmport) & 0x3f), tmport); + outb((unsigned char) (inb(dev->ioport[c] - 0x05) & 0x3f), dev->ioport[c] - 0x05);///minus 0x05??? } } else { - tmport = dev->ioport[c] + 0x3a; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { - outb((unsigned char) ((inb(tmport) & 0xf3) | 0x08), tmport); + outb((unsigned char) ((inb(dev->ioport[c] + 0x3a) & 0xf3) | 0x08), dev->ioport[c] + 0x3a); } else { - outb((unsigned char) (inb(tmport) & 0xf3), tmport); + outb((unsigned char) (inb(dev->ioport[c] + 0x3a) & 0xf3), dev->ioport[c] + 0x3a); } } - tmport = dev->ioport[c] + 0x1b; j = 0; id = 1; id = id << target_id; @@ -360,13 +333,12 @@ stop_dma: if ((id & dev->wide_id[c]) != 0) { j |= 0x01; } - outb(j, tmport); - while ((inb(tmport) & 0x01) != j) { - outb(j,tmport); + outb(j, dev->ioport[c] + 0x1b); + while ((inb(dev->ioport[c] + 0x1b) & 0x01) != j) { + outb(j,dev->ioport[c] + 0x1b); } if (dev->id[c][target_id].last_len == 0) { - tmport = dev->ioport[c] + 0x18; - outb(0x08, tmport); + outb(0x08, dev->ioport[c] + 0x18); dev->in_int[c] = 0; #ifdef ED_DBGP printk("dev->id[c][target_id].last_len = 0\n"); @@ -412,12 +384,11 @@ stop_dma: outb(0x00, tmpcip); tmpcip -= 0x02; } - tmport = dev->ioport[c] + 0x18; /* * Check transfer direction */ if (dev->id[c][target_id].dirct != 0) { - outb(0x08, tmport); + outb(0x08, dev->ioport[c] + 0x18); outb(0x01, tmpcip); dev->in_int[c] = 0; #ifdef ED_DBGP @@ -425,7 +396,7 @@ stop_dma: #endif goto handled; } - outb(0x08, tmport); + outb(0x08, dev->ioport[c] + 0x18); outb(0x09, tmpcip); dev->in_int[c] = 0; #ifdef ED_DBGP @@ -454,8 +425,7 @@ stop_dma: dev->last_cmd[c] = 0xff; } errstus = 0; - tmport -= 0x08; - errstus = inb(tmport); + errstus = inb(dev->ioport[c] + 0x0f); if (((dev->r1f[c][target_id] & 0x10) != 0)&&(dev->dev_id==ATP885_DEVID)) { printk(KERN_WARNING "AEC67162 CRC ERROR !\n"); errstus = 0x02; @@ -486,10 +456,9 @@ go_42: * Take it back wide */ if (dev->wide_id[c] != 0) { - tmport = dev->ioport[c] + 0x1b; - outb(0x01, tmport); - while ((inb(tmport) & 0x01) != 0x01) { - outb(0x01, tmport); + outb(0x01, dev->ioport[c] + 0x1b); + while ((inb(dev->ioport[c] + 0x1b) & 0x01) != 0x01) { + outb(0x01, dev->ioport[c] + 0x1b); } } /* @@ -521,21 +490,17 @@ go_42: outb(0x06, tmpcip); outb(0x00, tmpcip); tmpcip = tmpcip - 2; - tmport = dev->ioport[c] + 0x10; - outb(0x41, tmport); + outb(0x41, dev->ioport[c] + 0x10); if (dev->dev_id == ATP885_DEVID) { - tmport += 2; k = dev->id[c][target_id].last_len; - outb((unsigned char) (((unsigned char *) (&k))[2]), tmport++); - outb((unsigned char) (((unsigned char *) (&k))[1]), tmport++); - outb((unsigned char) (((unsigned char *) (&k))[0]), tmport); + outb((unsigned char) (((unsigned char *) (&k))[2]), dev->ioport[c] + 0x12); + outb((unsigned char) (((unsigned char *) (&k))[1]), dev->ioport[c] + 0x13); + outb((unsigned char) (((unsigned char *) (&k))[0]), dev->ioport[c] + 0x14); dev->id[c][target_id].dirct = 0x00; - tmport += 0x04; } else { dev->id[c][target_id].dirct = 0x00; - tmport += 0x08; } - outb(0x08, tmport); + outb(0x08, dev->ioport[c] + 0x18); outb(0x09, tmpcip); dev->in_int[c] = 0; goto handled; @@ -547,43 +512,34 @@ go_42: outb(0x06, tmpcip); outb(0x00, tmpcip); tmpcip = tmpcip - 2; - tmport = dev->ioport[c] + 0x10; - outb(0x41, tmport); + outb(0x41, dev->ioport[c] + 0x10); if (dev->dev_id == ATP885_DEVID) { - tmport += 2; k = dev->id[c][target_id].last_len; - outb((unsigned char) (((unsigned char *) (&k))[2]), tmport++); - outb((unsigned char) (((unsigned char *) (&k))[1]), tmport++); - outb((unsigned char) (((unsigned char *) (&k))[0]), tmport++); - } else { - tmport += 5; + outb((unsigned char) (((unsigned char *) (&k))[2]), dev->ioport[c] + 0x12); + outb((unsigned char) (((unsigned char *) (&k))[1]), dev->ioport[c] + 0x13); + outb((unsigned char) (((unsigned char *) (&k))[0]), dev->ioport[c] + 0x14); } - outb((unsigned char) (inb(tmport) | 0x20), tmport); + outb((unsigned char) (inb(dev->ioport[c] + 0x15) | 0x20), dev->ioport[c] + 0x15); dev->id[c][target_id].dirct = 0x20; - tmport += 0x03; - outb(0x08, tmport); + outb(0x08, dev->ioport[c] + 0x18); outb(0x01, tmpcip); dev->in_int[c] = 0; goto handled; } - tmport -= 0x07; if (i == 0x0a) { - outb(0x30, tmport); + outb(0x30, dev->ioport[c] + 0x10); } else { - outb(0x46, tmport); + outb(0x46, dev->ioport[c] + 0x10); } dev->id[c][target_id].dirct = 0x00; - tmport += 0x02; - outb(0x00, tmport++); - outb(0x00, tmport++); - outb(0x00, tmport++); - tmport += 0x03; - outb(0x08, tmport); + outb(0x00, dev->ioport[c] + 0x12); + outb(0x00, dev->ioport[c] + 0x13); + outb(0x00, dev->ioport[c] + 0x14); + outb(0x08, dev->ioport[c] + 0x18); dev->in_int[c] = 0; goto handled; } else { -// tmport = dev->ioport[c] + 0x17; -// inb(tmport); +// inb(dev->ioport[c] + 0x17); // dev->working[c] = 0; dev->in_int[c] = 0; goto handled; -- GitLab From 3b836464809aff2795c22ba2a97f3b148e70282e Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:40 +0100 Subject: [PATCH 0605/2855] atp870u: Untangle tmport #2 Untangle the tmport crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 79 +++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 47 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index a25a300efde86..71123372e52bd 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -562,7 +562,7 @@ static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p, void (*done) (struct scsi_cmnd *)) { unsigned char c; - unsigned int tmport,m; + unsigned int m; struct atp_unit *dev; struct Scsi_Host *host; @@ -631,11 +631,10 @@ static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p, return 0; } dev->quereq[c][dev->quend[c]] = req_p; - tmport = dev->ioport[c] + 0x1c; #ifdef ED_DBGP - printk("dev->ioport[c] = %x inb(tmport) = %x dev->in_int[%d] = %d dev->in_snd[%d] = %d\n",dev->ioport[c],inb(tmport),c,dev->in_int[c],c,dev->in_snd[c]); + printk("dev->ioport[c] = %x inb(dev->ioport[c] + 0x1c) = %x dev->in_int[%d] = %d dev->in_snd[%d] = %d\n",dev->ioport[c],inb(dev->ioport[c] + 0x1c),c,dev->in_int[c],c,dev->in_snd[c]); #endif - if ((inb(tmport) == 0) && (dev->in_int[c] == 0) && (dev->in_snd[c] == 0)) { + if ((inb(dev->ioport[c] + 0x1c) == 0) && (dev->in_int[c] == 0) && (dev->in_snd[c] == 0)) { #ifdef ED_DBGP printk("Call sent_s870(atp870u_queuecommand)\n"); #endif @@ -660,7 +659,6 @@ static DEF_SCSI_QCMD(atp870u_queuecommand) */ static void send_s870(struct atp_unit *dev,unsigned char c) { - unsigned int tmport; struct scsi_cmnd *workreq; unsigned int i;//,k; unsigned char j, target_id; @@ -712,12 +710,10 @@ static void send_s870(struct atp_unit *dev,unsigned char c) dev->in_snd[c] = 0; return; cmd_subp: - tmport = dev->ioport[c] + 0x1f; - if ((inb(tmport) & 0xb0) != 0) { + if ((inb(dev->ioport[c] + 0x1f) & 0xb0) != 0) { goto abortsnd; } - tmport = dev->ioport[c] + 0x1c; - if (inb(tmport) == 0) { + if (inb(dev->ioport[c] + 0x1c) == 0) { goto oktosend; } abortsnd: @@ -752,7 +748,6 @@ oktosend: l = 0; } - tmport = dev->ioport[c] + 0x1b; j = 0; target_id = scmd_id(workreq); @@ -764,9 +759,9 @@ oktosend: if ((w & dev->wide_id[c]) != 0) { j |= 0x01; } - outb(j, tmport); - while ((inb(tmport) & 0x01) != j) { - outb(j,tmport); + outb(j, dev->ioport[c] + 0x1b); + while ((inb(dev->ioport[c] + 0x1b) & 0x01) != j) { + outb(j,dev->ioport[c] + 0x1b); #ifdef ED_DBGP printk("send_s870 while loop 1\n"); #endif @@ -775,24 +770,21 @@ oktosend: * Write the command */ - tmport = dev->ioport[c]; - outb(workreq->cmd_len, tmport++); - outb(0x2c, tmport++); + outb(workreq->cmd_len, dev->ioport[c] + 0x00); + outb(0x2c, dev->ioport[c] + 0x01); if (dev->dev_id == ATP885_DEVID) { - outb(0x7f, tmport++); + outb(0x7f, dev->ioport[c] + 0x02); } else { - outb(0xcf, tmport++); + outb(0xcf, dev->ioport[c] + 0x02); } for (i = 0; i < workreq->cmd_len; i++) { - outb(workreq->cmnd[i], tmport++); + outb(workreq->cmnd[i], dev->ioport[c] + 0x03 + i); } - tmport = dev->ioport[c] + 0x0f; - outb(workreq->device->lun, tmport); - tmport += 0x02; + outb(workreq->device->lun, dev->ioport[c] + 0x0f); /* * Write the target */ - outb(dev->id[c][target_id].devsp, tmport++); + outb(dev->id[c][target_id].devsp, dev->ioport[c] + 0x11); #ifdef ED_DBGP printk("dev->id[%d][%d].devsp = %2x\n",c,target_id,dev->id[c][target_id].devsp); #endif @@ -801,9 +793,9 @@ oktosend: /* * Write transfer size */ - outb((unsigned char) (((unsigned char *) (&l))[2]), tmport++); - outb((unsigned char) (((unsigned char *) (&l))[1]), tmport++); - outb((unsigned char) (((unsigned char *) (&l))[0]), tmport++); + outb((unsigned char) (((unsigned char *) (&l))[2]), dev->ioport[c] + 0x12); + outb((unsigned char) (((unsigned char *) (&l))[1]), dev->ioport[c] + 0x13); + outb((unsigned char) (((unsigned char *) (&l))[0]), dev->ioport[c] + 0x14); j = target_id; dev->id[c][j].last_len = l; dev->id[c][j].tran_len = 0; @@ -820,21 +812,19 @@ oktosend: * Check transfer direction */ if (workreq->sc_data_direction == DMA_TO_DEVICE) { - outb((unsigned char) (j | 0x20), tmport++); + outb((unsigned char) (j | 0x20), dev->ioport[c] + 0x15); } else { - outb(j, tmport++); + outb(j, dev->ioport[c] + 0x15); } - outb((unsigned char) (inb(tmport) | 0x80), tmport); - outb(0x80, tmport); - tmport = dev->ioport[c] + 0x1c; + outb((unsigned char) (inb(dev->ioport[c] + 0x16) | 0x80), dev->ioport[c] + 0x16); + outb(0x80, dev->ioport[c] + 0x16); dev->id[c][target_id].dirct = 0; if (l == 0) { - if (inb(tmport) == 0) { - tmport = dev->ioport[c] + 0x18; + if (inb(dev->ioport[c] + 0x1c) == 0) { #ifdef ED_DBGP printk("change SCSI_CMD_REG 0x08\n"); #endif - outb(0x08, tmport); + outb(0x08, dev->ioport[c] + 0x18); } else { dev->last_cmd[c] |= 0x40; } @@ -899,28 +889,24 @@ oktosend: } else if ((dev->dev_id == ATP880_DEVID1) || (dev->dev_id == ATP880_DEVID2)) { tmpcip =tmpcip -2; - tmport = dev->ioport[c] - 0x05; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { - outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport); + outb((unsigned char) ((inb(dev->ioport[c] - 0x05) & 0x3f) | 0xc0), dev->ioport[c] - 0x05); } else { - outb((unsigned char) (inb(tmport) & 0x3f), tmport); + outb((unsigned char) (inb(dev->ioport[c] - 0x05) & 0x3f), dev->ioport[c] - 0x05); } } else { tmpcip =tmpcip -2; - tmport = dev->ioport[c] + 0x3a; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { - outb((inb(tmport) & 0xf3) | 0x08, tmport); + outb((inb(dev->ioport[c] + 0x3a) & 0xf3) | 0x08, dev->ioport[c] + 0x3a); } else { - outb(inb(tmport) & 0xf3, tmport); + outb(inb(dev->ioport[c] + 0x3a) & 0xf3, dev->ioport[c] + 0x3a); } } - tmport = dev->ioport[c] + 0x1c; if(workreq->sc_data_direction == DMA_TO_DEVICE) { dev->id[c][target_id].dirct = 0x20; - if (inb(tmport) == 0) { - tmport = dev->ioport[c] + 0x18; - outb(0x08, tmport); + if (inb(dev->ioport[c] + 0x1c) == 0) { + outb(0x08, dev->ioport[c] + 0x18); outb(0x01, tmpcip); #ifdef ED_DBGP printk( "start DMA(to target)\n"); @@ -931,9 +917,8 @@ oktosend: dev->in_snd[c] = 0; return; } - if (inb(tmport) == 0) { - tmport = dev->ioport[c] + 0x18; - outb(0x08, tmport); + if (inb(dev->ioport[c] + 0x1c) == 0) { + outb(0x08, dev->ioport[c] + 0x18); outb(0x09, tmpcip); #ifdef ED_DBGP printk( "start DMA(to host)\n"); -- GitLab From 1940ed62f9ca6d0b1f4c10afef3960f4f8a7d327 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:41 +0100 Subject: [PATCH 0606/2855] atp870u: Untangle tmport #3 Untangle the tmport crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 118 +++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 69 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 71123372e52bd..a23f38717d90b 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -933,38 +933,36 @@ oktosend: static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val) { - unsigned int tmport; unsigned short int i, k; unsigned char j; - tmport = dev->ioport[0] + 0x1c; - outw(*val, tmport); + outw(*val, dev->ioport[0] + 0x1c); FUN_D7: for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ - k = inw(tmport); + k = inw(dev->ioport[0] + 0x1c); j = (unsigned char) (k >> 8); if ((k & 0x8000) != 0) { /* DB7 all release? */ goto FUN_D7; } } *val |= 0x4000; /* assert DB6 */ - outw(*val, tmport); + outw(*val, dev->ioport[0] + 0x1c); *val &= 0xdfff; /* assert DB5 */ - outw(*val, tmport); + outw(*val, dev->ioport[0] + 0x1c); FUN_D5: for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ - if ((inw(tmport) & 0x2000) != 0) { /* DB5 all release? */ + if ((inw(dev->ioport[0] + 0x1c) & 0x2000) != 0) { /* DB5 all release? */ goto FUN_D5; } } *val |= 0x8000; /* no DB4-0, assert DB7 */ *val &= 0xe0ff; - outw(*val, tmport); + outw(*val, dev->ioport[0] + 0x1c); *val &= 0xbfff; /* release DB6 */ - outw(*val, tmport); + outw(*val, dev->ioport[0] + 0x1c); FUN_D6: for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ - if ((inw(tmport) & 0x4000) != 0) { /* DB6 all release? */ + if ((inw(dev->ioport[0] + 0x1c) & 0x4000) != 0) { /* DB6 all release? */ goto FUN_D6; } } @@ -975,7 +973,6 @@ FUN_D6: static void tscam(struct Scsi_Host *host) { - unsigned int tmport; unsigned char i, j, k; unsigned long n; unsigned short int m, assignid_map, val; @@ -992,11 +989,9 @@ static void tscam(struct Scsi_Host *host) } */ - tmport = dev->ioport[0] + 1; - outb(0x08, tmport++); - outb(0x7f, tmport); - tmport = dev->ioport[0] + 0x11; - outb(0x20, tmport); + outb(0x08, dev->ioport[0] + 1); + outb(0x7f, dev->ioport[0] + 2); + outb(0x20, dev->ioport[0] + 0x11); if ((dev->scam_on & 0x40) == 0) { return; @@ -1009,14 +1004,13 @@ static void tscam(struct Scsi_Host *host) j = 8; } assignid_map = m; - tmport = dev->ioport[0] + 0x02; - outb(0x02, tmport++); /* 2*2=4ms,3EH 2/32*3E=3.9ms */ - outb(0, tmport++); - outb(0, tmport++); - outb(0, tmport++); - outb(0, tmport++); - outb(0, tmport++); - outb(0, tmport++); + outb(0x02, dev->ioport[0] + 0x02); /* 2*2=4ms,3EH 2/32*3E=3.9ms */ + outb(0, dev->ioport[0] + 0x03); + outb(0, dev->ioport[0] + 0x04); + outb(0, dev->ioport[0] + 0x05); + outb(0, dev->ioport[0] + 0x06); + outb(0, dev->ioport[0] + 0x07); + outb(0, dev->ioport[0] + 0x08); for (i = 0; i < j; i++) { m = 1; @@ -1024,79 +1018,69 @@ static void tscam(struct Scsi_Host *host) if ((m & assignid_map) != 0) { continue; } - tmport = dev->ioport[0] + 0x0f; - outb(0, tmport++); - tmport += 0x02; - outb(0, tmport++); - outb(0, tmport++); - outb(0, tmport++); + outb(0, dev->ioport[0] + 0x0f); + outb(0, dev->ioport[0] + 0x12); + outb(0, dev->ioport[0] + 0x13); + outb(0, dev->ioport[0] + 0x14); if (i > 7) { k = (i & 0x07) | 0x40; } else { k = i; } - outb(k, tmport++); - tmport = dev->ioport[0] + 0x1b; + outb(k, dev->ioport[0] + 0x15); if (dev->chip_ver == 4) { - outb(0x01, tmport); + outb(0x01, dev->ioport[0] + 0x1b); } else { - outb(0x00, tmport); + outb(0x00, dev->ioport[0] + 0x1b); } wait_rdyok: - tmport = dev->ioport[0] + 0x18; - outb(0x09, tmport); - tmport += 0x07; + outb(0x09, dev->ioport[0] + 0x18); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(dev->ioport[0] + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - k = inb(tmport); + k = inb(dev->ioport[0] + 0x17); if (k != 0x16) { if ((k == 0x85) || (k == 0x42)) { continue; } - tmport = dev->ioport[0] + 0x10; - outb(0x41, tmport); + outb(0x41, dev->ioport[0] + 0x10); goto wait_rdyok; } assignid_map |= m; } - tmport = dev->ioport[0] + 0x02; - outb(0x7f, tmport); - tmport = dev->ioport[0] + 0x1b; - outb(0x02, tmport); + outb(0x7f, dev->ioport[0] + 0x02); + outb(0x02, dev->ioport[0] + 0x1b); outb(0, 0x80); val = 0x0080; /* bsy */ - tmport = dev->ioport[0] + 0x1c; - outw(val, tmport); + outw(val, dev->ioport[0] + 0x1c); val |= 0x0040; /* sel */ - outw(val, tmport); + outw(val, dev->ioport[0] + 0x1c); val |= 0x0004; /* msg */ - outw(val, tmport); + outw(val, dev->ioport[0] + 0x1c); inb(0x80); /* 2 deskew delay(45ns*2=90ns) */ val &= 0x007f; /* no bsy */ - outw(val, tmport); + outw(val, dev->ioport[0] + 0x1c); mdelay(128); val &= 0x00fb; /* after 1ms no msg */ - outw(val, tmport); + outw(val, dev->ioport[0] + 0x1c); wait_nomsg: - if ((inb(tmport) & 0x04) != 0) { + if ((inb(dev->ioport[0] + 0x1c) & 0x04) != 0) { goto wait_nomsg; } outb(1, 0x80); udelay(100); for (n = 0; n < 0x30000; n++) { - if ((inb(tmport) & 0x80) != 0) { /* bsy ? */ + if ((inb(dev->ioport[0] + 0x1c) & 0x80) != 0) { /* bsy ? */ goto wait_io; } } goto TCM_SYNC; wait_io: for (n = 0; n < 0x30000; n++) { - if ((inb(tmport) & 0x81) == 0x0081) { + if ((inb(dev->ioport[0] + 0x1c) & 0x81) == 0x0081) { goto wait_io1; } } @@ -1104,10 +1088,10 @@ wait_io: wait_io1: inb(0x80); val |= 0x8003; /* io,cd,db7 */ - outw(val, tmport); + outw(val, dev->ioport[0] + 0x1c); inb(0x80); val &= 0x00bf; /* no sel */ - outw(val, tmport); + outw(val, dev->ioport[0] + 0x1c); outb(2, 0x80); TCM_SYNC: /* @@ -1120,18 +1104,14 @@ TCM_SYNC: */ mdelay(2); udelay(48); - if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */ - outw(0, tmport--); - outb(0, tmport); - tmport = dev->ioport[0] + 0x15; - outb(0, tmport); - tmport += 0x03; - outb(0x09, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0) + if ((inb(dev->ioport[0] + 0x1c) & 0x80) == 0x00) { /* bsy ? */ + outw(0, dev->ioport[0] + 0x1c); + outb(0, dev->ioport[0] + 0x1b); + outb(0, dev->ioport[0] + 0x15); + outb(0x09, dev->ioport[0] + 0x18); + while ((inb(dev->ioport[0] + 0x1f) & 0x80) == 0) cpu_relax(); - tmport -= 0x08; - inb(tmport); + inb(dev->ioport[0] + 0x17); return; } val &= 0x00ff; /* synchronization */ @@ -1145,7 +1125,7 @@ TCM_SYNC: i = 8; j = 0; TCM_ID: - if ((inw(tmport) & 0x2000) == 0) { + if ((inw(dev->ioport[0] + 0x1c) & 0x2000) == 0) { goto TCM_ID; } outb(5, 0x80); -- GitLab From ea41ed600b261fec87820c1aa2455942dcfa1ce7 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:42 +0100 Subject: [PATCH 0607/2855] atp870u: Untangle tmport #4 Untangle the tmport crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 370 +++++++++++++++-------------------------- 1 file changed, 138 insertions(+), 232 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index a23f38717d90b..3e3a68b2738d3 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1207,7 +1207,6 @@ G2Q_QUIN: /* k=binID#, */ static void is870(struct atp_unit *dev, unsigned int wkport) { - unsigned int tmport; unsigned char i, j, k, rmb, n; unsigned short int m; static unsigned char mbuf[512]; @@ -1218,8 +1217,7 @@ static void is870(struct atp_unit *dev, unsigned int wkport) static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 }; static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; - tmport = wkport + 0x3a; - outb((unsigned char) (inb(tmport) | 0x10), tmport); + outb((unsigned char) (inb(wkport + 0x3a) | 0x10), wkport + 0x3a); for (i = 0; i < 16; i++) { if ((dev->chip_ver != 4) && (i > 7)) { @@ -1234,135 +1232,105 @@ static void is870(struct atp_unit *dev, unsigned int wkport) printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[0]); continue; } - tmport = wkport + 0x1b; if (dev->chip_ver == 4) { - outb(0x01, tmport); + outb(0x01, wkport + 0x1b); } else { - outb(0x00, tmport); - } - tmport = wkport + 1; - outb(0x08, tmport++); - outb(0x7f, tmport++); - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); + outb(0x00, wkport + 0x1b); + } + outb(0x08, wkport + 1); + outb(0x7f, wkport + 2); + outb(satn[0], wkport + 3); + outb(satn[1], wkport + 4); + outb(satn[2], wkport + 5); + outb(satn[3], wkport + 6); + outb(satn[4], wkport + 7); + outb(satn[5], wkport + 8); + outb(0, wkport + 0x0f); + outb(dev->id[0][i].devsp, wkport + 0x11); + outb(0, wkport + 0x12); + outb(satn[6], wkport + 0x13); + outb(satn[7], wkport + 0x14); j = i; if ((j & 0x08) != 0) { j = (j & 0x07) | 0x40; } - outb(j, tmport); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; + outb(j, wkport + 0x15); + outb(satn[8], wkport + 0x18); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) + if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e) continue; - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); dev->active_id[0] |= m; - tmport = wkport + 0x10; - outb(0x30, tmport); - tmport = wkport + 0x04; - outb(0x00, tmport); + outb(0x30, wkport + 0x10); + outb(0x00, wkport + 0x04); phase_cmd: - tmport = wkport + 0x18; - outb(0x08, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) + outb(0x08, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j != 0x16) { - tmport = wkport + 0x10; - outb(0x41, tmport); + outb(0x41, wkport + 0x10); goto phase_cmd; } sel_ok: - tmport = wkport + 3; - outb(inqd[0], tmport++); - outb(inqd[1], tmport++); - outb(inqd[2], tmport++); - outb(inqd[3], tmport++); - outb(inqd[4], tmport++); - outb(inqd[5], tmport); - tmport += 0x07; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(inqd[6], tmport++); - outb(inqd[7], tmport++); - tmport += 0x03; - outb(inqd[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(inqd[0], wkport + 3); + outb(inqd[1], wkport + 4); + outb(inqd[2], wkport + 5); + outb(inqd[3], wkport + 6); + outb(inqd[4], wkport + 7); + outb(inqd[5], wkport + 8); + outb(0, wkport + 0x0f); + outb(dev->id[0][i].devsp, wkport + 0x11); + outb(0, wkport + 0x12); + outb(inqd[6], wkport + 0x13); + outb(inqd[7], wkport + 0x14); + outb(inqd[8], wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) + if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e) continue; - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); - tmport = wkport + 0x1b; if (dev->chip_ver == 4) - outb(0x00, tmport); + outb(0x00, wkport + 0x1b); - tmport = wkport + 0x18; - outb(0x08, tmport); - tmport += 0x07; + outb(0x08, wkport + 0x18); j = 0; rd_inq_data: - k = inb(tmport); + k = inb(wkport + 0x1f); if ((k & 0x01) != 0) { - tmport -= 0x06; - mbuf[j++] = inb(tmport); - tmport += 0x06; + mbuf[j++] = inb(wkport + 0x19); goto rd_inq_data; } if ((k & 0x80) == 0) { goto rd_inq_data; } - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j == 0x16) { goto inq_ok; } - tmport = wkport + 0x10; - outb(0x46, tmport); - tmport += 0x02; - outb(0, tmport++); - outb(0, tmport++); - outb(0, tmport++); - tmport += 0x03; - outb(0x08, tmport); - tmport += 0x07; + outb(0x46, wkport + 0x10); + outb(0, wkport + 0x12); + outb(0, wkport + 0x13); + outb(0, wkport + 0x14); + outb(0x08, wkport + 0x18); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x16) { + if (inb(wkport + 0x17) != 0x16) { goto sel_ok; } inq_ok: @@ -1380,57 +1348,43 @@ inq_ok: if ((dev->global_map[0] & 0x20) == 0) { goto not_wide; } - tmport = wkport + 0x1b; - outb(0x01, tmport); - tmport = wkport + 3; - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(0x01, wkport + 0x1b); + outb(satn[0], wkport + 3); + outb(satn[1], wkport + 4); + outb(satn[2], wkport + 5); + outb(satn[3], wkport + 6); + outb(satn[4], wkport + 7); + outb(satn[5], wkport + 8); + outb(0, wkport + 0x0f); + outb(dev->id[0][i].devsp, wkport + 0x11); + outb(0, wkport + 0x12); + outb(satn[6], wkport + 0x13); + outb(satn[7], wkport + 0x14); + outb(satn[8], wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) + if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e) continue; - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); try_wide: j = 0; - tmport = wkport + 0x14; - outb(0x05, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x05, wkport + 0x14); + outb(0x20, wkport + 0x18); - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(wide[j++], tmport); - tmport += 0x06; - } + while ((inb(wkport + 0x1f) & 0x80) == 0) { + if ((inb(wkport + 0x1f) & 0x01) != 0) + outb(wide[j++], wkport + 0x19); } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1442,18 +1396,12 @@ try_wide: } continue; widep_out: - tmport = wkport + 0x18; - outb(0x20, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(0, tmport); - tmport += 0x06; - } + outb(0x20, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0) { + if ((inb(wkport + 0x1f) & 0x01) != 0) + outb(0, wkport + 0x19); } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1465,25 +1413,19 @@ widep_out: } continue; widep_in: - tmport = wkport + 0x14; - outb(0xff, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0xff, wkport + 0x14); + outb(0x20, wkport + 0x18); k = 0; widep_in1: - j = inb(tmport); + j = inb(wkport + 0x1f); if ((j & 0x01) != 0) { - tmport -= 0x06; - mbuf[k++] = inb(tmport); - tmport += 0x06; + mbuf[k++] = inb(wkport + 0x19); goto widep_in1; } if ((j & 0x80) == 0x00) { goto widep_in1; } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1495,19 +1437,14 @@ widep_in1: } continue; widep_cmd: - tmport = wkport + 0x10; - outb(0x30, tmport); - tmport = wkport + 0x14; - outb(0x00, tmport); - tmport += 0x04; - outb(0x08, tmport); - tmport += 0x07; + outb(0x30, wkport + 0x10); + outb(0x00, wkport + 0x14); + outb(0x08, wkport + 0x18); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j != 0x16) { if (j == 0x4e) { goto widep_out; @@ -1535,69 +1472,56 @@ not_wide: } continue; set_sync: - tmport = wkport + 0x1b; j = 0; if ((m & dev->wide_id[0]) != 0) { j |= 0x01; } - outb(j, tmport); - tmport = wkport + 3; - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(j, wkport + 0x1b); + outb(satn[0], wkport + 3); + outb(satn[1], wkport + 4); + outb(satn[2], wkport + 5); + outb(satn[3], wkport + 6); + outb(satn[4], wkport + 7); + outb(satn[5], wkport + 8); + outb(0, wkport + 0x0f); + outb(dev->id[0][i].devsp, wkport + 0x11); + outb(0, wkport + 0x12); + outb(satn[6], wkport + 0x13); + outb(satn[7], wkport + 0x14); + outb(satn[8], wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) + if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e) continue; - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); try_sync: j = 0; - tmport = wkport + 0x14; - outb(0x06, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x06, wkport + 0x14); + outb(0x20, wkport + 0x18); - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; + while ((inb(wkport + 0x1f) & 0x80) == 0) { + if ((inb(wkport + 0x1f) & 0x01) != 0) { if ((m & dev->wide_id[0]) != 0) { - outb(synw[j++], tmport); + outb(synw[j++], wkport + 0x19); } else { if ((m & dev->ultra_map[0]) != 0) { - outb(synu[j++], tmport); + outb(synu[j++], wkport + 0x19); } else { - outb(synn[j++], tmport); + outb(synn[j++], wkport + 0x19); } } - tmport += 0x06; } } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; } @@ -1609,18 +1533,12 @@ try_sync: } continue; phase_outs: - tmport = wkport + 0x18; - outb(0x20, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) { - if ((inb(tmport) & 0x01) != 0x00) { - tmport -= 0x06; - outb(0x00, tmport); - tmport += 0x06; - } + outb(0x20, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00) { + if ((inb(wkport + 0x1f) & 0x01) != 0x00) + outb(0x00, wkport + 0x19); } - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j == 0x85) { goto tar_dcons; } @@ -1636,29 +1554,23 @@ phase_outs: } continue; phase_ins: - tmport = wkport + 0x14; - outb(0xff, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0xff, wkport + 0x14); + outb(0x20, wkport + 0x18); k = 0; phase_ins1: - j = inb(tmport); + j = inb(wkport + 0x1f); if ((j & 0x01) != 0x00) { - tmport -= 0x06; - mbuf[k++] = inb(tmport); - tmport += 0x06; + mbuf[k++] = inb(wkport + 0x19); goto phase_ins1; } if ((j & 0x80) == 0x00) { goto phase_ins1; } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport); + j = inb(wkport + 0x17); if (j == 0x85) { goto tar_dcons; } @@ -1674,20 +1586,15 @@ phase_ins1: } continue; phase_cmds: - tmport = wkport + 0x10; - outb(0x30, tmport); + outb(0x30, wkport + 0x10); tar_dcons: - tmport = wkport + 0x14; - outb(0x00, tmport); - tmport += 0x04; - outb(0x08, tmport); - tmport += 0x07; + outb(0x00, wkport + 0x14); + outb(0x08, wkport + 0x18); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j != 0x16) { continue; } @@ -1727,8 +1634,7 @@ tar_dcons: set_syn_ok: dev->id[0][i].devsp = (dev->id[0][i].devsp & 0x0f) | j; } - tmport = wkport + 0x3a; - outb((unsigned char) (inb(tmport) & 0xef), tmport); + outb((unsigned char) (inb(wkport + 0x3a) & 0xef), wkport + 0x3a); } static void is880(struct atp_unit *dev, unsigned int wkport) -- GitLab From 3b30acf6a8989dc1a98f959d3c7743790eab00df Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:43 +0100 Subject: [PATCH 0608/2855] atp870u: Untangle tmport #5 Untangle the tmport crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 470 +++++++++++++++-------------------------- 1 file changed, 173 insertions(+), 297 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 3e3a68b2738d3..3bf01fcb4b49a 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1639,7 +1639,6 @@ set_syn_ok: static void is880(struct atp_unit *dev, unsigned int wkport) { - unsigned int tmport; unsigned char i, j, k, rmb, n, lvdmode; unsigned short int m; static unsigned char mbuf[512]; @@ -1664,130 +1663,100 @@ static void is880(struct atp_unit *dev, unsigned int wkport) printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[0]); continue; } - tmport = wkport + 0x5b; - outb(0x01, tmport); - tmport = wkport + 0x41; - outb(0x08, tmport++); - outb(0x7f, tmport++); - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); + outb(0x01, wkport + 0x5b); + outb(0x08, wkport + 0x41); + outb(0x7f, wkport + 0x42); + outb(satn[0], wkport + 0x43); + outb(satn[1], wkport + 0x44); + outb(satn[2], wkport + 0x45); + outb(satn[3], wkport + 0x46); + outb(satn[4], wkport + 0x47); + outb(satn[5], wkport + 0x48); + outb(0, wkport + 0x4f); + outb(dev->id[0][i].devsp, wkport + 0x51); + outb(0, wkport + 0x52); + outb(satn[6], wkport + 0x53); + outb(satn[7], wkport + 0x54); j = i; if ((j & 0x08) != 0) { j = (j & 0x07) | 0x40; } - outb(j, tmport); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; + outb(j, wkport + 0x55); + outb(satn[8], wkport + 0x58); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) + if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e) continue; - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x57) != 0x8e) cpu_relax(); dev->active_id[0] |= m; - tmport = wkport + 0x50; - outb(0x30, tmport); - tmport = wkport + 0x54; - outb(0x00, tmport); + outb(0x30, wkport + 0x50); + outb(0x00, wkport + 0x54); phase_cmd: - tmport = wkport + 0x58; - outb(0x08, tmport); - tmport += 0x07; + outb(0x08, wkport + 0x58); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x57); if (j != 0x16) { - tmport = wkport + 0x50; - outb(0x41, tmport); + outb(0x41, wkport + 0x50); goto phase_cmd; } sel_ok: - tmport = wkport + 0x43; - outb(inqd[0], tmport++); - outb(inqd[1], tmport++); - outb(inqd[2], tmport++); - outb(inqd[3], tmport++); - outb(inqd[4], tmport++); - outb(inqd[5], tmport); - tmport += 0x07; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(inqd[6], tmport++); - outb(inqd[7], tmport++); - tmport += 0x03; - outb(inqd[8], tmport); - tmport += 0x07; + outb(inqd[0], wkport + 0x43); + outb(inqd[1], wkport + 0x44); + outb(inqd[2], wkport + 0x45); + outb(inqd[3], wkport + 0x46); + outb(inqd[4], wkport + 0x47); + outb(inqd[5], wkport + 0x48); + outb(0, wkport + 0x4f); + outb(dev->id[0][i].devsp, wkport + 0x51); + outb(0, wkport + 0x52); + outb(inqd[6], wkport + 0x53); + outb(inqd[7], wkport + 0x54); + outb(inqd[8], wkport + 0x58); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) + if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e) continue; - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x57) != 0x8e) cpu_relax(); - tmport = wkport + 0x5b; - outb(0x00, tmport); - tmport = wkport + 0x58; - outb(0x08, tmport); - tmport += 0x07; + outb(0x00, wkport + 0x5b); + outb(0x08, wkport + 0x58); j = 0; rd_inq_data: - k = inb(tmport); + k = inb(wkport + 0x5f); if ((k & 0x01) != 0) { - tmport -= 0x06; - mbuf[j++] = inb(tmport); - tmport += 0x06; + mbuf[j++] = inb(wkport + 0x59); goto rd_inq_data; } if ((k & 0x80) == 0) { goto rd_inq_data; } - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x57); if (j == 0x16) { goto inq_ok; } - tmport = wkport + 0x50; - outb(0x46, tmport); - tmport += 0x02; - outb(0, tmport++); - outb(0, tmport++); - outb(0, tmport++); - tmport += 0x03; - outb(0x08, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) + outb(0x46, wkport + 0x50); + outb(0, wkport + 0x52); + outb(0, wkport + 0x53); + outb(0, wkport + 0x54); + outb(0x08, wkport + 0x58); + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x16) + if (inb(wkport + 0x57) != 0x16) goto sel_ok; inq_ok: @@ -1810,58 +1779,43 @@ inq_ok: goto chg_wide; } - tmport = wkport + 0x5b; - outb(0x01, tmport); - tmport = wkport + 0x43; - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(0x01, wkport + 0x5b); + outb(satn[0], wkport + 0x43); + outb(satn[1], wkport + 0x44); + outb(satn[2], wkport + 0x45); + outb(satn[3], wkport + 0x46); + outb(satn[4], wkport + 0x47); + outb(satn[5], wkport + 0x48); + outb(0, wkport + 0x4f); + outb(dev->id[0][i].devsp, wkport + 0x51); + outb(0, wkport + 0x52); + outb(satn[6], wkport + 0x53); + outb(satn[7], wkport + 0x54); + outb(satn[8], wkport + 0x58); + + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - - if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) + if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e) continue; - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x57) != 0x8e) cpu_relax(); try_u3: j = 0; - tmport = wkport + 0x54; - outb(0x09, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x09, wkport + 0x54); + outb(0x20, wkport + 0x58); - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(u3[j++], tmport); - tmport += 0x06; - } + while ((inb(wkport + 0x5f) & 0x80) == 0) { + if ((inb(wkport + 0x5f) & 0x01) != 0) + outb(u3[j++], wkport + 0x59); } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x57) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x57) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1873,18 +1827,12 @@ try_u3: } continue; u3p_out: - tmport = wkport + 0x58; - outb(0x20, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(0, tmport); - tmport += 0x06; - } + outb(0x20, wkport + 0x58); + while ((inb(wkport + 0x5f) & 0x80) == 0) { + if ((inb(wkport + 0x5f) & 0x01) != 0) + outb(0, wkport + 0x59); } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x57) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1896,25 +1844,19 @@ u3p_out: } continue; u3p_in: - tmport = wkport + 0x54; - outb(0x09, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x09, wkport + 0x54); + outb(0x20, wkport + 0x58); k = 0; u3p_in1: - j = inb(tmport); + j = inb(wkport + 0x5f); if ((j & 0x01) != 0) { - tmport -= 0x06; - mbuf[k++] = inb(tmport); - tmport += 0x06; + mbuf[k++] = inb(wkport + 0x59); goto u3p_in1; } if ((j & 0x80) == 0x00) { goto u3p_in1; } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x57) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1926,19 +1868,14 @@ u3p_in1: } continue; u3p_cmd: - tmport = wkport + 0x50; - outb(0x30, tmport); - tmport = wkport + 0x54; - outb(0x00, tmport); - tmport += 0x04; - outb(0x08, tmport); - tmport += 0x07; + outb(0x30, wkport + 0x50); + outb(0x00, wkport + 0x54); + outb(0x08, wkport + 0x58); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x57); if (j != 0x16) { if (j == 0x4e) { goto u3p_out; @@ -1962,56 +1899,42 @@ u3p_cmd: continue; } chg_wide: - tmport = wkport + 0x5b; - outb(0x01, tmport); - tmport = wkport + 0x43; - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(0x01, wkport + 0x5b); + outb(satn[0], wkport + 0x43); + outb(satn[1], wkport + 0x44); + outb(satn[2], wkport + 0x45); + outb(satn[3], wkport + 0x46); + outb(satn[4], wkport + 0x47); + outb(satn[5], wkport + 0x48); + outb(0, wkport + 0x4f); + outb(dev->id[0][i].devsp, wkport + 0x51); + outb(0, wkport + 0x52); + outb(satn[6], wkport + 0x53); + outb(satn[7], wkport + 0x54); + outb(satn[8], wkport + 0x58); + + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) + if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e) continue; - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x57) != 0x8e) cpu_relax(); try_wide: j = 0; - tmport = wkport + 0x54; - outb(0x05, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x05, wkport + 0x54); + outb(0x20, wkport + 0x58); - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(wide[j++], tmport); - tmport += 0x06; - } + while ((inb(wkport + 0x5f) & 0x80) == 0) { + if ((inb(wkport + 0x5f) & 0x01) != 0) + outb(wide[j++], wkport + 0x59); } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x57) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x57) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -2023,18 +1946,12 @@ try_wide: } continue; widep_out: - tmport = wkport + 0x58; - outb(0x20, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(0, tmport); - tmport += 0x06; - } + outb(0x20, wkport + 0x58); + while ((inb(wkport + 0x5f) & 0x80) == 0) { + if ((inb(wkport + 0x5f) & 0x01) != 0) + outb(0, wkport + 0x59); } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x57) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -2046,25 +1963,19 @@ widep_out: } continue; widep_in: - tmport = wkport + 0x54; - outb(0xff, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0xff, wkport + 0x54); + outb(0x20, wkport + 0x58); k = 0; widep_in1: - j = inb(tmport); + j = inb(wkport + 0x5f); if ((j & 0x01) != 0) { - tmport -= 0x06; - mbuf[k++] = inb(tmport); - tmport += 0x06; + mbuf[k++] = inb(wkport + 0x59); goto widep_in1; } if ((j & 0x80) == 0x00) { goto widep_in1; } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x57) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -2076,19 +1987,14 @@ widep_in1: } continue; widep_cmd: - tmport = wkport + 0x50; - outb(0x30, tmport); - tmport = wkport + 0x54; - outb(0x00, tmport); - tmport += 0x04; - outb(0x08, tmport); - tmport += 0x07; + outb(0x30, wkport + 0x50); + outb(0x00, wkport + 0x54); + outb(0x08, wkport + 0x58); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x57); if (j != 0x16) { if (j == 0x4e) { goto widep_out; @@ -2129,73 +2035,60 @@ set_sync: synuw[4] = 0x0a; } } - tmport = wkport + 0x5b; j = 0; if ((m & dev->wide_id[0]) != 0) { j |= 0x01; } - outb(j, tmport); - tmport = wkport + 0x43; - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(j, wkport + 0x5b); + outb(satn[0], wkport + 0x43); + outb(satn[1], wkport + 0x44); + outb(satn[2], wkport + 0x45); + outb(satn[3], wkport + 0x46); + outb(satn[4], wkport + 0x47); + outb(satn[5], wkport + 0x48); + outb(0, wkport + 0x4f); + outb(dev->id[0][i].devsp, wkport + 0x51); + outb(0, wkport + 0x52); + outb(satn[6], wkport + 0x53); + outb(satn[7], wkport + 0x54); + outb(satn[8], wkport + 0x58); + + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { + if ((inb(wkport + 0x57) != 0x11) && (inb(wkport + 0x57) != 0x8e)) { continue; } - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x57) != 0x8e) cpu_relax(); try_sync: j = 0; - tmport = wkport + 0x54; - outb(0x06, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x06, wkport + 0x54); + outb(0x20, wkport + 0x58); - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; + while ((inb(wkport + 0x5f) & 0x80) == 0) { + if ((inb(wkport + 0x5f) & 0x01) != 0) { if ((m & dev->wide_id[0]) != 0) { if ((m & dev->ultra_map[0]) != 0) { - outb(synuw[j++], tmport); + outb(synuw[j++], wkport + 0x59); } else { - outb(synw[j++], tmport); + outb(synw[j++], wkport + 0x59); } } else { if ((m & dev->ultra_map[0]) != 0) { - outb(synu[j++], tmport); + outb(synu[j++], wkport + 0x59); } else { - outb(synn[j++], tmport); + outb(synn[j++], wkport + 0x59); } } - tmport += 0x06; } } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x57) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x57) & 0x0f; if (j == 0x0f) { goto phase_ins; } @@ -2207,18 +2100,12 @@ try_sync: } continue; phase_outs: - tmport = wkport + 0x58; - outb(0x20, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) { - if ((inb(tmport) & 0x01) != 0x00) { - tmport -= 0x06; - outb(0x00, tmport); - tmport += 0x06; - } + outb(0x20, wkport + 0x58); + while ((inb(wkport + 0x5f) & 0x80) == 0x00) { + if ((inb(wkport + 0x5f) & 0x01) != 0x00) + outb(0x00, wkport + 0x59); } - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x57); if (j == 0x85) { goto tar_dcons; } @@ -2234,29 +2121,23 @@ phase_outs: } continue; phase_ins: - tmport = wkport + 0x54; - outb(0x06, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x06, wkport + 0x54); + outb(0x20, wkport + 0x58); k = 0; phase_ins1: - j = inb(tmport); + j = inb(wkport + 0x5f); if ((j & 0x01) != 0x00) { - tmport -= 0x06; - mbuf[k++] = inb(tmport); - tmport += 0x06; + mbuf[k++] = inb(wkport + 0x59); goto phase_ins1; } if ((j & 0x80) == 0x00) { goto phase_ins1; } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x57) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport); + j = inb(wkport + 0x57); if (j == 0x85) { goto tar_dcons; } @@ -2272,20 +2153,15 @@ phase_ins1: } continue; phase_cmds: - tmport = wkport + 0x50; - outb(0x30, tmport); + outb(0x30, wkport + 0x50); tar_dcons: - tmport = wkport + 0x54; - outb(0x00, tmport); - tmport += 0x04; - outb(0x08, tmport); - tmport += 0x07; + outb(0x00, wkport + 0x54); + outb(0x08, wkport + 0x58); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x57); if (j != 0x16) { continue; } -- GitLab From 493c5201933f39711569602dc938ac7054391b53 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:44 +0100 Subject: [PATCH 0609/2855] atp870u: Untangle tmport #6 Untangle the tmport crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 136 +++++++++++++++-------------------------- 1 file changed, 49 insertions(+), 87 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 3bf01fcb4b49a..e398ea5ea8f1f 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -2264,7 +2264,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { unsigned char k, m, c; unsigned long flags; - unsigned int base_io, tmport, error,n; + unsigned int base_io, error,n; unsigned char host_id; struct Scsi_Host *shpnt = NULL; struct atp_unit *atpdev, *p; @@ -2322,12 +2322,9 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) atpdev->dev_id = ent->device; atpdev->host_id[0] = host_id; - tmport = base_io + 0x22; - atpdev->scam_on = inb(tmport); - tmport += 0x13; - atpdev->global_map[0] = inb(tmport); - tmport += 0x07; - atpdev->ultra_map[0] = inw(tmport); + atpdev->scam_on = inb(base_io + 0x22); + atpdev->global_map[0] = inb(base_io + 0x35); + atpdev->ultra_map[0] = inw(base_io + 0x3c); n = 0x3f09; next_fblk_880: @@ -2402,37 +2399,26 @@ flash_ok_880: } spin_lock_irqsave(shpnt->host_lock, flags); - tmport = base_io + 0x38; - k = inb(tmport) & 0x80; - outb(k, tmport); - tmport += 0x03; - outb(0x20, tmport); + k = inb(base_io + 0x38) & 0x80; + outb(k, base_io + 0x38); + outb(0x20, base_io + 0x3b); mdelay(32); - outb(0, tmport); + outb(0, base_io + 0x3b); mdelay(32); - tmport = base_io + 0x5b; - inb(tmport); - tmport -= 0x04; - inb(tmport); - tmport = base_io + 0x40; - outb((host_id | 0x08), tmport); - tmport += 0x18; - outb(0, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0) + inb(base_io + 0x5b); + inb(base_io + 0x57); + outb((host_id | 0x08), base_io + 0x40); + outb(0, base_io + 0x58); + while ((inb(base_io + 0x5f) & 0x80) == 0) mdelay(1); - tmport -= 0x08; - inb(tmport); - tmport = base_io + 0x41; - outb(8, tmport++); - outb(0x7f, tmport); - tmport = base_io + 0x51; - outb(0x20, tmport); + inb(base_io + 0x57); + outb(8, base_io + 0x41); + outb(0x7f, base_io + 0x42); + outb(0x20, base_io + 0x51); tscam(shpnt); is880(p, base_io); - tmport = base_io + 0x38; - outb(0xb0, tmport); + outb(0xb0, base_io + 0x38); shpnt->max_id = 16; shpnt->this_id = host_id; shpnt->unique_id = base_io; @@ -2546,47 +2532,35 @@ flash_ok_885: inb(base_io + 0x97); inb(base_io + 0xdb); inb(base_io + 0xd7); - tmport = base_io + 0x80; k=p->host_id[0]; if (k > 7) k = (k & 0x07) | 0x40; k |= 0x08; - outb(k, tmport); - tmport += 0x18; - outb(0, tmport); - tmport += 0x07; + outb(k, base_io + 0x80); + outb(0, base_io + 0x98); - while ((inb(tmport) & 0x80) == 0) + while ((inb(base_io + 0x9f) & 0x80) == 0) cpu_relax(); - tmport -= 0x08; - inb(tmport); - tmport = base_io + 0x81; - outb(8, tmport++); - outb(0x7f, tmport); - tmport = base_io + 0x91; - outb(0x20, tmport); + inb(base_io + 0x97); + outb(8, base_io + 0x81); + outb(0x7f, base_io + 0x82); + outb(0x20, base_io + 0x91); - tmport = base_io + 0xc0; k=p->host_id[1]; if (k > 7) k = (k & 0x07) | 0x40; k |= 0x08; - outb(k, tmport); - tmport += 0x18; - outb(0, tmport); - tmport += 0x07; + outb(k, base_io + 0xc0); + outb(0, base_io + 0xd8); - while ((inb(tmport) & 0x80) == 0) + while ((inb(base_io + 0xdf) & 0x80) == 0) cpu_relax(); - tmport -= 0x08; - inb(tmport); - tmport = base_io + 0xc1; - outb(8, tmport++); - outb(0x7f, tmport); - tmport = base_io + 0xd1; - outb(0x20, tmport); + inb(base_io + 0xd7); + outb(8, base_io + 0xc1); + outb(0x7f, base_io + 0xc2); + outb(0x20, base_io + 0xd1); tscam_885(); printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); @@ -2624,11 +2598,9 @@ flash_ok_885: atpdev->dev_id = ent->device; host_id &= 0x07; atpdev->host_id[0] = host_id; - tmport = base_io + 0x22; - atpdev->scam_on = inb(tmport); - tmport += 0x0b; - atpdev->global_map[0] = inb(tmport++); - atpdev->ultra_map[0] = inw(tmport); + atpdev->scam_on = inb(base_io + 0x22); + atpdev->global_map[0] = inb(base_io + 0x2d); + atpdev->ultra_map[0] = inw(base_io + 0x2e); if (atpdev->ultra_map[0] == 0) { atpdev->scam_on = 0x00; @@ -2656,39 +2628,29 @@ flash_ok_885: spin_lock_irqsave(shpnt->host_lock, flags); if (atpdev->chip_ver > 0x07) { /* check if atp876 chip then enable terminator */ - tmport = base_io + 0x3e; - outb(0x00, tmport); + outb(0x00, base_io + 0x3e); } - tmport = base_io + 0x3a; - k = (inb(tmport) & 0xf3) | 0x10; - outb(k, tmport); - outb((k & 0xdf), tmport); + k = (inb(base_io + 0x3a) & 0xf3) | 0x10; + outb(k, base_io + 0x3a); + outb((k & 0xdf), base_io + 0x3a); mdelay(32); - outb(k, tmport); + outb(k, base_io + 0x3a); mdelay(32); - tmport = base_io; - outb((host_id | 0x08), tmport); - tmport += 0x18; - outb(0, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0) + outb((host_id | 0x08), base_io + 0); + outb(0, base_io + 0x18); + while ((inb(base_io + 0x1f) & 0x80) == 0) mdelay(1); - tmport -= 0x08; - inb(tmport); - tmport = base_io + 1; - outb(8, tmport++); - outb(0x7f, tmport); - tmport = base_io + 0x11; - outb(0x20, tmport); + inb(base_io + 0x17); + outb(8, base_io + 1); + outb(0x7f, base_io + 2); + outb(0x20, base_io + 0x11); tscam(shpnt); is870(p, base_io); - tmport = base_io + 0x3a; - outb((inb(tmport) & 0xef), tmport); - tmport++; - outb((inb(tmport) | 0x20), tmport); + outb((inb(base_io + 0x3a) & 0xef), base_io + 0x3a); + outb((inb(base_io + 0x3b) | 0x20), base_io + 0x3b); if (atpdev->chip_ver == 4) shpnt->max_id = 16; else -- GitLab From 2eabdf22ad667742258ef7c55a965e56366bf74d Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:45 +0100 Subject: [PATCH 0610/2855] atp870u: Untangle tmport #7 Untangle the tmport crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index e398ea5ea8f1f..f5a11f49bfad8 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -2716,7 +2716,6 @@ static int atp870u_abort(struct scsi_cmnd * SCpnt) { unsigned char j, k, c; struct scsi_cmnd *workrequ; - unsigned int tmport; struct atp_unit *dev; struct Scsi_Host *host; host = SCpnt->device->host; @@ -2726,18 +2725,13 @@ static int atp870u_abort(struct scsi_cmnd * SCpnt) printk(" atp870u: abort Channel = %x \n", c); printk("working=%x last_cmd=%x ", dev->working[c], dev->last_cmd[c]); printk(" quhdu=%x quendu=%x ", dev->quhd[c], dev->quend[c]); - tmport = dev->ioport[c]; for (j = 0; j < 0x18; j++) { - printk(" r%2x=%2x", j, inb(tmport++)); + printk(" r%2x=%2x", j, inb(dev->ioport[c] + j)); } - tmport += 0x04; - printk(" r1c=%2x", inb(tmport)); - tmport += 0x03; - printk(" r1f=%2x in_snd=%2x ", inb(tmport), dev->in_snd[c]); - tmport= dev->pciport[c]; - printk(" d00=%2x", inb(tmport)); - tmport += 0x02; - printk(" d02=%2x", inb(tmport)); + printk(" r1c=%2x", inb(dev->ioport[c] + 0x1c)); + printk(" r1f=%2x in_snd=%2x ", inb(dev->ioport[c] + 0x1f), dev->in_snd[c]); + printk(" d00=%2x", inb(dev->pciport[c])); + printk(" d02=%2x", inb(dev->pciport[c] + 0x02)); for(j=0;j<16;j++) { if (dev->id[c][j].curr_req != NULL) { workrequ = dev->id[c][j].curr_req; -- GitLab From e2c22b45cb8feb00f2b8296e277d98485882ed92 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:46 +0100 Subject: [PATCH 0611/2855] atp870u: Untangle tmport #8 Untangle the tmport crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 478 +++++++++++++++-------------------------- 1 file changed, 177 insertions(+), 301 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index f5a11f49bfad8..993442d65a0ea 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -2870,7 +2870,6 @@ static void tscam_885(void) static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c) { - unsigned int tmport; unsigned char i, j, k, rmb, n, lvdmode; unsigned short int m; static unsigned char mbuf[512]; @@ -2895,123 +2894,93 @@ static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c) printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); continue; } - tmport = wkport + 0x1b; - outb(0x01, tmport); - tmport = wkport + 0x01; - outb(0x08, tmport++); - outb(0x7f, tmport++); - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[c][i].devsp, tmport++); + outb(0x01, wkport + 0x1b); + outb(0x08, wkport + 0x01); + outb(0x7f, wkport + 0x02); + outb(satn[0], wkport + 0x03); + outb(satn[1], wkport + 0x04); + outb(satn[2], wkport + 0x05); + outb(satn[3], wkport + 0x06); + outb(satn[4], wkport + 0x07); + outb(satn[5], wkport + 0x08); + outb(0, wkport + 0x0f); + outb(dev->id[c][i].devsp, wkport + 0x11); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); + outb(0, wkport + 0x12); + outb(satn[6], wkport + 0x13); + outb(satn[7], wkport + 0x14); j = i; if ((j & 0x08) != 0) { j = (j & 0x07) | 0x40; } - outb(j, tmport); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; + outb(j, wkport + 0x15); + outb(satn[8], wkport + 0x18); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { + if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { continue; } - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); dev->active_id[c] |= m; - tmport = wkport + 0x10; - outb(0x30, tmport); - tmport = wkport + 0x14; - outb(0x00, tmport); + outb(0x30, wkport + 0x10); + outb(0x00, wkport + 0x14); phase_cmd: - tmport = wkport + 0x18; - outb(0x08, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) + outb(0x08, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j != 0x16) { - tmport = wkport + 0x10; - outb(0x41, tmport); + outb(0x41, wkport + 0x10); goto phase_cmd; } sel_ok: - tmport = wkport + 0x03; - outb(inqd[0], tmport++); - outb(inqd[1], tmport++); - outb(inqd[2], tmport++); - outb(inqd[3], tmport++); - outb(inqd[4], tmport++); - outb(inqd[5], tmport); - tmport += 0x07; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[c][i].devsp, tmport++); - outb(0, tmport++); - outb(inqd[6], tmport++); - outb(inqd[7], tmport++); - tmport += 0x03; - outb(inqd[8], tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) + outb(inqd[0], wkport + 0x03); + outb(inqd[1], wkport + 0x04); + outb(inqd[2], wkport + 0x05); + outb(inqd[3], wkport + 0x06); + outb(inqd[4], wkport + 0x07); + outb(inqd[5], wkport + 0x08); + outb(0, wkport + 0x0f); + outb(dev->id[c][i].devsp, wkport + 0x11); + outb(0, wkport + 0x12); + outb(inqd[6], wkport + 0x13); + outb(inqd[7], wkport + 0x14); + outb(inqd[8], wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { + if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { continue; } - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); - tmport = wkport + 0x1b; - outb(0x00, tmport); - tmport = wkport + 0x18; - outb(0x08, tmport); - tmport += 0x07; + outb(0x00, wkport + 0x1b); + outb(0x08, wkport + 0x18); j = 0; rd_inq_data: - k = inb(tmport); + k = inb(wkport + 0x1f); if ((k & 0x01) != 0) { - tmport -= 0x06; - mbuf[j++] = inb(tmport); - tmport += 0x06; + mbuf[j++] = inb(wkport + 0x19); goto rd_inq_data; } if ((k & 0x80) == 0) { goto rd_inq_data; } - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j == 0x16) { goto inq_ok; } - tmport = wkport + 0x10; - outb(0x46, tmport); - tmport += 0x02; - outb(0, tmport++); - outb(0, tmport++); - outb(0, tmport++); - tmport += 0x03; - outb(0x08, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) + outb(0x46, wkport + 0x10); + outb(0, wkport + 0x12); + outb(0, wkport + 0x13); + outb(0, wkport + 0x14); + outb(0x08, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x16) { + if (inb(wkport + 0x17) != 0x16) { goto sel_ok; } inq_ok: @@ -3033,54 +3002,40 @@ inq_ok: goto chg_wide; } - tmport = wkport + 0x1b; - outb(0x01, tmport); - tmport = wkport + 0x03; - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[c][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(0x01, wkport + 0x1b); + outb(satn[0], wkport + 0x03); + outb(satn[1], wkport + 0x04); + outb(satn[2], wkport + 0x05); + outb(satn[3], wkport + 0x06); + outb(satn[4], wkport + 0x07); + outb(satn[5], wkport + 0x08); + outb(0, wkport + 0x0f); + outb(dev->id[c][i].devsp, wkport + 0x11); + outb(0, wkport + 0x12); + outb(satn[6], wkport + 0x13); + outb(satn[7], wkport + 0x14); + outb(satn[8], wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { + if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { continue; } - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); try_u3: j = 0; - tmport = wkport + 0x14; - outb(0x09, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(u3[j++], tmport); - tmport += 0x06; - } + outb(0x09, wkport + 0x14); + outb(0x20, wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0) { + if ((inb(wkport + 0x1f) & 0x01) != 0) + outb(u3[j++], wkport + 0x19); cpu_relax(); } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -3092,19 +3047,13 @@ try_u3: } continue; u3p_out: - tmport = wkport + 0x18; - outb(0x20, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(0, tmport); - tmport += 0x06; - } + outb(0x20, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0) { + if ((inb(wkport + 0x1f) & 0x01) != 0) + outb(0, wkport + 0x19); cpu_relax(); } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -3116,25 +3065,19 @@ u3p_out: } continue; u3p_in: - tmport = wkport + 0x14; - outb(0x09, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x09, wkport + 0x14); + outb(0x20, wkport + 0x18); k = 0; u3p_in1: - j = inb(tmport); + j = inb(wkport + 0x1f); if ((j & 0x01) != 0) { - tmport -= 0x06; - mbuf[k++] = inb(tmport); - tmport += 0x06; + mbuf[k++] = inb(wkport + 0x19); goto u3p_in1; } if ((j & 0x80) == 0x00) { goto u3p_in1; } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -3146,16 +3089,11 @@ u3p_in1: } continue; u3p_cmd: - tmport = wkport + 0x10; - outb(0x30, tmport); - tmport = wkport + 0x14; - outb(0x00, tmport); - tmport += 0x04; - outb(0x08, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00); - tmport -= 0x08; - j = inb(tmport); + outb(0x30, wkport + 0x10); + outb(0x00, wkport + 0x14); + outb(0x08, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00); + j = inb(wkport + 0x17); if (j != 0x16) { if (j == 0x4e) { goto u3p_out; @@ -3182,54 +3120,40 @@ u3p_cmd: continue; } chg_wide: - tmport = wkport + 0x1b; - outb(0x01, tmport); - tmport = wkport + 0x03; - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[c][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(0x01, wkport + 0x1b); + outb(satn[0], wkport + 0x03); + outb(satn[1], wkport + 0x04); + outb(satn[2], wkport + 0x05); + outb(satn[3], wkport + 0x06); + outb(satn[4], wkport + 0x07); + outb(satn[5], wkport + 0x08); + outb(0, wkport + 0x0f); + outb(dev->id[c][i].devsp, wkport + 0x11); + outb(0, wkport + 0x12); + outb(satn[6], wkport + 0x13); + outb(satn[7], wkport + 0x14); + outb(satn[8], wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { + if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { continue; } - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); try_wide: j = 0; - tmport = wkport + 0x14; - outb(0x05, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(wide[j++], tmport); - tmport += 0x06; - } + outb(0x05, wkport + 0x14); + outb(0x20, wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0) { + if ((inb(wkport + 0x1f) & 0x01) != 0) + outb(wide[j++], wkport + 0x19); cpu_relax(); } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -3241,19 +3165,13 @@ try_wide: } continue; widep_out: - tmport = wkport + 0x18; - outb(0x20, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(0, tmport); - tmport += 0x06; - } + outb(0x20, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0) { + if ((inb(wkport + 0x1f) & 0x01) != 0) + outb(0, wkport + 0x19); cpu_relax(); } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -3265,25 +3183,19 @@ widep_out: } continue; widep_in: - tmport = wkport + 0x14; - outb(0xff, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0xff, wkport + 0x14); + outb(0x20, wkport + 0x18); k = 0; widep_in1: - j = inb(tmport); + j = inb(wkport + 0x1f); if ((j & 0x01) != 0) { - tmport -= 0x06; - mbuf[k++] = inb(tmport); - tmport += 0x06; + mbuf[k++] = inb(wkport + 0x19); goto widep_in1; } if ((j & 0x80) == 0x00) { goto widep_in1; } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -3295,17 +3207,12 @@ widep_in1: } continue; widep_cmd: - tmport = wkport + 0x10; - outb(0x30, tmport); - tmport = wkport + 0x14; - outb(0x00, tmport); - tmport += 0x04; - outb(0x08, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) + outb(0x30, wkport + 0x10); + outb(0x00, wkport + 0x14); + outb(0x08, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j != 0x16) { if (j == 0x4e) { goto widep_out; @@ -3347,69 +3254,56 @@ set_sync: synuw[4]=0x0a; } } - tmport = wkport + 0x1b; j = 0; if ((m & dev->wide_id[c]) != 0) { j |= 0x01; } - outb(j, tmport); - tmport = wkport + 0x03; - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[c][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(j, wkport + 0x1b); + outb(satn[0], wkport + 0x03); + outb(satn[1], wkport + 0x04); + outb(satn[2], wkport + 0x05); + outb(satn[3], wkport + 0x06); + outb(satn[4], wkport + 0x07); + outb(satn[5], wkport + 0x08); + outb(0, wkport + 0x0f); + outb(dev->id[c][i].devsp, wkport + 0x11); + outb(0, wkport + 0x12); + outb(satn[6], wkport + 0x13); + outb(satn[7], wkport + 0x14); + outb(satn[8], wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { + if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { continue; } - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); try_sync: j = 0; - tmport = wkport + 0x14; - outb(0x06, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; + outb(0x06, wkport + 0x14); + outb(0x20, wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0) { + if ((inb(wkport + 0x1f) & 0x01) != 0) { if ((m & dev->wide_id[c]) != 0) { if ((m & dev->ultra_map[c]) != 0) { - outb(synuw[j++], tmport); + outb(synuw[j++], wkport + 0x19); } else { - outb(synw[j++], tmport); + outb(synw[j++], wkport + 0x19); } } else { if ((m & dev->ultra_map[c]) != 0) { - outb(synu[j++], tmport); + outb(synu[j++], wkport + 0x19); } else { - outb(synn[j++], tmport); + outb(synn[j++], wkport + 0x19); } } - tmport += 0x06; } } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; } @@ -3421,19 +3315,13 @@ try_sync: } continue; phase_outs: - tmport = wkport + 0x18; - outb(0x20, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) { - if ((inb(tmport) & 0x01) != 0x00) { - tmport -= 0x06; - outb(0x00, tmport); - tmport += 0x06; - } + outb(0x20, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00) { + if ((inb(wkport + 0x1f) & 0x01) != 0x00) + outb(0x00, wkport + 0x19); cpu_relax(); } - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j == 0x85) { goto tar_dcons; } @@ -3449,26 +3337,20 @@ phase_outs: } continue; phase_ins: - tmport = wkport + 0x14; - outb(0x06, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x06, wkport + 0x14); + outb(0x20, wkport + 0x18); k = 0; phase_ins1: - j = inb(tmport); + j = inb(wkport + 0x1f); if ((j & 0x01) != 0x00) { - tmport -= 0x06; - mbuf[k++] = inb(tmport); - tmport += 0x06; + mbuf[k++] = inb(wkport + 0x19); goto phase_ins1; } if ((j & 0x80) == 0x00) { goto phase_ins1; } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00); - j = inb(tmport); + while ((inb(wkport + 0x17) & 0x80) == 0x00); + j = inb(wkport + 0x17); if (j == 0x85) { goto tar_dcons; } @@ -3484,18 +3366,13 @@ phase_ins1: } continue; phase_cmds: - tmport = wkport + 0x10; - outb(0x30, tmport); + outb(0x30, wkport + 0x10); tar_dcons: - tmport = wkport + 0x14; - outb(0x00, tmport); - tmport += 0x04; - outb(0x08, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) + outb(0x00, wkport + 0x14); + outb(0x08, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j != 0x16) { continue; } @@ -3542,8 +3419,7 @@ tar_dcons: printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp); #endif } - tmport = wkport + 0x16; - outb(0x80, tmport); + outb(0x80, wkport + 0x16); } module_init(atp870u_init); -- GitLab From bc0fe4c91cdc7e211ca7dafd9039d3bf40a41e3b Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:47 +0100 Subject: [PATCH 0612/2855] atp870u: Untangle tmpcip Untangle the tmpcip crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 64 +++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 41 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 993442d65a0ea..32544bb5c88d2 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -47,7 +47,7 @@ static void tscam_885(void); static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) { unsigned long flags; - unsigned short int tmpcip, id; + unsigned short int id; unsigned char i, j, c, target_id, lun,cmdp; unsigned char *prd; struct scsi_cmnd *workreq; @@ -79,30 +79,24 @@ ch_sel: if ((inb(dev->ioport[c] + 0x16) & 0x80) == 0) outb((inb(dev->ioport[c] + 0x16) | 0x80), dev->ioport[c] + 0x16); } - tmpcip = dev->pciport[c]; - if ((inb(tmpcip) & 0x08) != 0) + if ((inb(dev->pciport[c]) & 0x08) != 0) { - tmpcip += 0x2; for (k=0; k < 1000; k++) { - if ((inb(tmpcip) & 0x08) == 0) { + if ((inb(dev->pciport[c] + 2) & 0x08) == 0) { goto stop_dma; } - if ((inb(tmpcip) & 0x01) == 0) { + if ((inb(dev->pciport[c] + 2) & 0x01) == 0) { goto stop_dma; } } } stop_dma: - tmpcip = dev->pciport[c]; - outb(0x00, tmpcip); + outb(0x00, dev->pciport[c]); i = inb(dev->ioport[c] + 0x17); - if (dev->dev_id == ATP885_DEVID) { - tmpcip += 2; - outb(0x06, tmpcip); - tmpcip -= 2; - } + if (dev->dev_id == ATP885_DEVID) + outb(0x06, dev->pciport[c] + 2); target_id = inb(dev->ioport[c] + 0x15); @@ -303,13 +297,12 @@ stop_dma: /* enable 32 bit fifo transfer */ if (dev->dev_id == ATP885_DEVID) { - tmpcip = dev->pciport[c] + 1; - i=inb(tmpcip) & 0xf3; + i=inb(dev->pciport[c] + 1) & 0xf3; //j=workreq->cmnd[0]; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { i |= 0x0c; } - outb(i,tmpcip); + outb(i, dev->pciport[c] + 1); } else if ((dev->dev_id == ATP880_DEVID1) || (dev->dev_id == ATP880_DEVID2) ) { if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { @@ -371,25 +364,20 @@ stop_dma: } } } - tmpcip = dev->pciport[c] + 0x04; - outl(dev->id[c][target_id].prdaddr, tmpcip); + outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 0x04); #ifdef ED_DBGP printk("dev->id[%d][%d].prdaddr 0x%8x\n", c, target_id, dev->id[c][target_id].prdaddr); #endif - if (dev->dev_id == ATP885_DEVID) { - tmpcip -= 0x04; - } else { - tmpcip -= 0x02; - outb(0x06, tmpcip); - outb(0x00, tmpcip); - tmpcip -= 0x02; + if (dev->dev_id != ATP885_DEVID) { + outb(0x06, dev->pciport[c] + 2); + outb(0x00, dev->pciport[c] + 2); } /* * Check transfer direction */ if (dev->id[c][target_id].dirct != 0) { outb(0x08, dev->ioport[c] + 0x18); - outb(0x01, tmpcip); + outb(0x01, dev->pciport[c]); dev->in_int[c] = 0; #ifdef ED_DBGP printk("status 0x80 return dirct != 0\n"); @@ -397,7 +385,7 @@ stop_dma: goto handled; } outb(0x08, dev->ioport[c] + 0x18); - outb(0x09, tmpcip); + outb(0x09, dev->pciport[c]); dev->in_int[c] = 0; #ifdef ED_DBGP printk("status 0x80 return dirct = 0\n"); @@ -484,12 +472,9 @@ go_42: } i &= 0x0f; if (i == 0x09) { - tmpcip += 4; - outl(dev->id[c][target_id].prdaddr, tmpcip); - tmpcip = tmpcip - 2; - outb(0x06, tmpcip); - outb(0x00, tmpcip); - tmpcip = tmpcip - 2; + outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 4); + outb(0x06, dev->pciport[c] + 2); + outb(0x00, dev->pciport[c] + 2); outb(0x41, dev->ioport[c] + 0x10); if (dev->dev_id == ATP885_DEVID) { k = dev->id[c][target_id].last_len; @@ -501,17 +486,14 @@ go_42: dev->id[c][target_id].dirct = 0x00; } outb(0x08, dev->ioport[c] + 0x18); - outb(0x09, tmpcip); + outb(0x09, dev->pciport[c]); dev->in_int[c] = 0; goto handled; } if (i == 0x08) { - tmpcip += 4; - outl(dev->id[c][target_id].prdaddr, tmpcip); - tmpcip = tmpcip - 2; - outb(0x06, tmpcip); - outb(0x00, tmpcip); - tmpcip = tmpcip - 2; + outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 4); + outb(0x06, dev->pciport[c] + 2); + outb(0x00, dev->pciport[c] + 2); outb(0x41, dev->ioport[c] + 0x10); if (dev->dev_id == ATP885_DEVID) { k = dev->id[c][target_id].last_len; @@ -522,7 +504,7 @@ go_42: outb((unsigned char) (inb(dev->ioport[c] + 0x15) | 0x20), dev->ioport[c] + 0x15); dev->id[c][target_id].dirct = 0x20; outb(0x08, dev->ioport[c] + 0x18); - outb(0x01, tmpcip); + outb(0x01, dev->pciport[c]); dev->in_int[c] = 0; goto handled; } -- GitLab From c2bab4031b528b4a5a665a499fd87c2440758b00 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:48 +0100 Subject: [PATCH 0613/2855] atp870u: Untangle tmpcip #2 Untangle the tmpcip crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 32544bb5c88d2..4d840a59afa33 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -645,7 +645,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c) unsigned int i;//,k; unsigned char j, target_id; unsigned char *prd; - unsigned short int tmpcip, w; + unsigned short int w; unsigned long l, bttl = 0; unsigned long sg_count; @@ -813,7 +813,6 @@ oktosend: dev->in_snd[c] = 0; return; } - tmpcip = dev->pciport[c]; prd = dev->id[c][target_id].prd_table; dev->id[c][target_id].prd_pos = prd; @@ -850,34 +849,28 @@ oktosend: printk("2. bttl %x, l %x\n",bttl, l); #endif } - tmpcip += 4; #ifdef ED_DBGP - printk("send_s870: prdaddr_2 0x%8x tmpcip %x target_id %d\n", dev->id[c][target_id].prdaddr,tmpcip,target_id); + printk("send_s870: prdaddr_2 0x%8x target_id %d\n", dev->id[c][target_id].prdaddr,target_id); #endif dev->id[c][target_id].prdaddr = dev->id[c][target_id].prd_bus; - outl(dev->id[c][target_id].prdaddr, tmpcip); - tmpcip = tmpcip - 2; - outb(0x06, tmpcip); - outb(0x00, tmpcip); + outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 4); + outb(0x06, dev->pciport[c] + 2); + outb(0x00, dev->pciport[c] + 2); if (dev->dev_id == ATP885_DEVID) { - tmpcip--; - j=inb(tmpcip) & 0xf3; + j = inb(dev->pciport[c] + 1) & 0xf3; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { j |= 0x0c; } - outb(j,tmpcip); - tmpcip--; + outb(j, dev->pciport[c] + 1); } else if ((dev->dev_id == ATP880_DEVID1) || (dev->dev_id == ATP880_DEVID2)) { - tmpcip =tmpcip -2; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { outb((unsigned char) ((inb(dev->ioport[c] - 0x05) & 0x3f) | 0xc0), dev->ioport[c] - 0x05); } else { outb((unsigned char) (inb(dev->ioport[c] - 0x05) & 0x3f), dev->ioport[c] - 0x05); } } else { - tmpcip =tmpcip -2; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { outb((inb(dev->ioport[c] + 0x3a) & 0xf3) | 0x08, dev->ioport[c] + 0x3a); } else { @@ -889,7 +882,7 @@ oktosend: dev->id[c][target_id].dirct = 0x20; if (inb(dev->ioport[c] + 0x1c) == 0) { outb(0x08, dev->ioport[c] + 0x18); - outb(0x01, tmpcip); + outb(0x01, dev->pciport[c]); #ifdef ED_DBGP printk( "start DMA(to target)\n"); #endif @@ -901,7 +894,7 @@ oktosend: } if (inb(dev->ioport[c] + 0x1c) == 0) { outb(0x08, dev->ioport[c] + 0x18); - outb(0x09, tmpcip); + outb(0x09, dev->pciport[c]); #ifdef ED_DBGP printk( "start DMA(to host)\n"); #endif -- GitLab From 78614ecdda717ac4afa2764bec622b50400a1dc3 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:49 +0100 Subject: [PATCH 0614/2855] atp870u: Remove ugly gotos Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 84 +++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 54 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 4d840a59afa33..886e54ba97ffb 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -55,20 +55,17 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) #ifdef ED_DBGP unsigned long l; #endif - int errstus; struct Scsi_Host *host = dev_id; struct atp_unit *dev = (struct atp_unit *)&host->hostdata; for (c = 0; c < 2; c++) { j = inb(dev->ioport[c] + 0x1f); if ((j & 0x80) != 0) - { - goto ch_sel; - } + break; dev->in_int[c] = 0; } - return IRQ_NONE; -ch_sel: + if ((j & 0x80) == 0) + return IRQ_NONE; #ifdef ED_DBGP printk("atp870u_intr_handle enter\n"); #endif @@ -82,15 +79,12 @@ ch_sel: if ((inb(dev->pciport[c]) & 0x08) != 0) { for (k=0; k < 1000; k++) { - if ((inb(dev->pciport[c] + 2) & 0x08) == 0) { - goto stop_dma; - } - if ((inb(dev->pciport[c] + 2) & 0x01) == 0) { - goto stop_dma; - } + if ((inb(dev->pciport[c] + 2) & 0x08) == 0) + break; + if ((inb(dev->pciport[c] + 2) & 0x01) == 0) + break; } } -stop_dma: outb(0x00, dev->pciport[c]); i = inb(dev->ioport[c] + 0x17); @@ -170,13 +164,13 @@ stop_dma: #ifdef ED_DBGP printk("Status 0x85 return\n"); #endif - goto handled; + return IRQ_HANDLED; } if (i == 0x40) { dev->last_cmd[c] |= 0x40; dev->in_int[c] = 0; - goto handled; + return IRQ_HANDLED; } if (i == 0x21) { @@ -194,7 +188,7 @@ stop_dma: outb(0x41, dev->ioport[c] + 0x10); outb(0x08, dev->ioport[c] + 0x18); dev->in_int[c] = 0; - goto handled; + return IRQ_HANDLED; } if (dev->dev_id == ATP885_DEVID) { @@ -231,7 +225,7 @@ stop_dma: dev->id[c][target_id].last_len = adrcnt; outb(0x08, dev->ioport[c] + 0x18); dev->in_int[c] = 0; - goto handled; + return IRQ_HANDLED; } else { #ifdef ED_DBGP printk("cmdp != 0x41\n"); @@ -243,7 +237,7 @@ stop_dma: outb(0x00, dev->ioport[c] + 0x14); outb(0x08, dev->ioport[c] + 0x18); dev->in_int[c] = 0; - goto handled; + return IRQ_HANDLED; } } if (dev->last_cmd[c] != 0xff) { @@ -336,7 +330,7 @@ stop_dma: #ifdef ED_DBGP printk("dev->id[c][target_id].last_len = 0\n"); #endif - goto handled; + return IRQ_HANDLED; } #ifdef ED_DBGP printk("target_id = %d adrcnt = %d\n",target_id,adrcnt); @@ -382,7 +376,7 @@ stop_dma: #ifdef ED_DBGP printk("status 0x80 return dirct != 0\n"); #endif - goto handled; + return IRQ_HANDLED; } outb(0x08, dev->ioport[c] + 0x18); outb(0x09, dev->pciport[c]); @@ -390,7 +384,7 @@ stop_dma: #ifdef ED_DBGP printk("status 0x80 return dirct = 0\n"); #endif - goto handled; + return IRQ_HANDLED; } /* @@ -399,27 +393,19 @@ stop_dma: workreq = dev->id[c][target_id].curr_req; - if (i == 0x42) { - if ((dev->last_cmd[c] & 0xf0) != 0x40) - { - dev->last_cmd[c] = 0xff; - } - errstus = 0x02; - workreq->result = errstus; - goto go_42; - } - if (i == 0x16) { + if (i == 0x42 || i == 0x16) { if ((dev->last_cmd[c] & 0xf0) != 0x40) { dev->last_cmd[c] = 0xff; } - errstus = 0; - errstus = inb(dev->ioport[c] + 0x0f); - if (((dev->r1f[c][target_id] & 0x10) != 0)&&(dev->dev_id==ATP885_DEVID)) { - printk(KERN_WARNING "AEC67162 CRC ERROR !\n"); - errstus = 0x02; - } - workreq->result = errstus; -go_42: + if (i == 0x16) { + workreq->result = inb(dev->ioport[c] + 0x0f); + if (((dev->r1f[c][target_id] & 0x10) != 0)&&(dev->dev_id==ATP885_DEVID)) { + printk(KERN_WARNING "AEC67162 CRC ERROR !\n"); + workreq->result = 0x02; + } + } else + workreq->result = 0x02; + if (dev->dev_id == ATP885_DEVID) { j = inb(dev->baseport + 0x29) | 0x01; outb(j, dev->baseport + 0x29); @@ -462,7 +448,7 @@ go_42: } spin_unlock_irqrestore(dev->host->host_lock, flags); dev->in_int[c] = 0; - goto handled; + return IRQ_HANDLED; } if ((dev->last_cmd[c] & 0xf0) != 0x40) { dev->last_cmd[c] = 0xff; @@ -488,7 +474,7 @@ go_42: outb(0x08, dev->ioport[c] + 0x18); outb(0x09, dev->pciport[c]); dev->in_int[c] = 0; - goto handled; + return IRQ_HANDLED; } if (i == 0x08) { outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 4); @@ -506,7 +492,7 @@ go_42: outb(0x08, dev->ioport[c] + 0x18); outb(0x01, dev->pciport[c]); dev->in_int[c] = 0; - goto handled; + return IRQ_HANDLED; } if (i == 0x0a) { outb(0x30, dev->ioport[c] + 0x10); @@ -518,19 +504,9 @@ go_42: outb(0x00, dev->ioport[c] + 0x13); outb(0x00, dev->ioport[c] + 0x14); outb(0x08, dev->ioport[c] + 0x18); - dev->in_int[c] = 0; - goto handled; - } else { -// inb(dev->ioport[c] + 0x17); -// dev->working[c] = 0; - dev->in_int[c] = 0; - goto handled; } - -handled: -#ifdef ED_DBGP - printk("atp870u_intr_handle exit\n"); -#endif + dev->in_int[c] = 0; + return IRQ_HANDLED; } /** -- GitLab From 468b8968157466996b70c610c080c41ae517c61c Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:50 +0100 Subject: [PATCH 0615/2855] atp870u: Remove ugly gotos #2 Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 68 +++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 38 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 886e54ba97ffb..999bf74c3a861 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -617,7 +617,7 @@ static DEF_SCSI_QCMD(atp870u_queuecommand) */ static void send_s870(struct atp_unit *dev,unsigned char c) { - struct scsi_cmnd *workreq; + struct scsi_cmnd *workreq = NULL; unsigned int i;//,k; unsigned char j, target_id; unsigned char *prd; @@ -638,50 +638,42 @@ static void send_s870(struct atp_unit *dev,unsigned char c) if ((dev->last_cmd[c] != 0xff) && ((dev->last_cmd[c] & 0x40) != 0)) { dev->last_cmd[c] &= 0x0f; workreq = dev->id[c][dev->last_cmd[c]].curr_req; - if (workreq != NULL) { /* check NULL pointer */ - goto cmd_subp; - } - dev->last_cmd[c] = 0xff; - if (dev->quhd[c] == dev->quend[c]) { - dev->in_snd[c] = 0; - return ; + if (!workreq) { + dev->last_cmd[c] = 0xff; + if (dev->quhd[c] == dev->quend[c]) { + dev->in_snd[c] = 0; + return; + } } } - if ((dev->last_cmd[c] != 0xff) && (dev->working[c] != 0)) { - dev->in_snd[c] = 0; - return ; - } - dev->working[c]++; - j = dev->quhd[c]; - dev->quhd[c]++; - if (dev->quhd[c] >= qcnt) { - dev->quhd[c] = 0; - } - workreq = dev->quereq[c][dev->quhd[c]]; - if (dev->id[c][scmd_id(workreq)].curr_req == NULL) { + if (!workreq) { + if ((dev->last_cmd[c] != 0xff) && (dev->working[c] != 0)) { + dev->in_snd[c] = 0; + return; + } + dev->working[c]++; + j = dev->quhd[c]; + dev->quhd[c]++; + if (dev->quhd[c] >= qcnt) + dev->quhd[c] = 0; + workreq = dev->quereq[c][dev->quhd[c]]; + if (dev->id[c][scmd_id(workreq)].curr_req != NULL) { + dev->quhd[c] = j; + dev->working[c]--; + dev->in_snd[c] = 0; + return; + } dev->id[c][scmd_id(workreq)].curr_req = workreq; dev->last_cmd[c] = scmd_id(workreq); - goto cmd_subp; - } - dev->quhd[c] = j; - dev->working[c]--; - dev->in_snd[c] = 0; - return; -cmd_subp: - if ((inb(dev->ioport[c] + 0x1f) & 0xb0) != 0) { - goto abortsnd; - } - if (inb(dev->ioport[c] + 0x1c) == 0) { - goto oktosend; } -abortsnd: + if ((inb(dev->ioport[c] + 0x1f) & 0xb0) != 0 || inb(dev->ioport[c] + 0x1c) != 0) { #ifdef ED_DBGP - printk("Abort to Send\n"); + printk("Abort to Send\n"); #endif - dev->last_cmd[c] |= 0x40; - dev->in_snd[c] = 0; - return; -oktosend: + dev->last_cmd[c] |= 0x40; + dev->in_snd[c] = 0; + return; + } #ifdef ED_DBGP printk("OK to Send\n"); scmd_printk(KERN_DEBUG, workreq, "CDB"); -- GitLab From 832e9ac6de16ea07045ab3a18d7a64bc3fb1231c Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:51 +0100 Subject: [PATCH 0616/2855] atp870u: Remove ugly gotos #3 Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 999bf74c3a861..b3d4e9db3c101 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -880,34 +880,28 @@ static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val) unsigned char j; outw(*val, dev->ioport[0] + 0x1c); -FUN_D7: for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ k = inw(dev->ioport[0] + 0x1c); j = (unsigned char) (k >> 8); - if ((k & 0x8000) != 0) { /* DB7 all release? */ - goto FUN_D7; - } + if ((k & 0x8000) != 0) /* DB7 all release? */ + i = 0; } *val |= 0x4000; /* assert DB6 */ outw(*val, dev->ioport[0] + 0x1c); *val &= 0xdfff; /* assert DB5 */ outw(*val, dev->ioport[0] + 0x1c); -FUN_D5: for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ - if ((inw(dev->ioport[0] + 0x1c) & 0x2000) != 0) { /* DB5 all release? */ - goto FUN_D5; - } + if ((inw(dev->ioport[0] + 0x1c) & 0x2000) != 0) /* DB5 all release? */ + i = 0; } *val |= 0x8000; /* no DB4-0, assert DB7 */ *val &= 0xe0ff; outw(*val, dev->ioport[0] + 0x1c); *val &= 0xbfff; /* release DB6 */ outw(*val, dev->ioport[0] + 0x1c); -FUN_D6: for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ - if ((inw(dev->ioport[0] + 0x1c) & 0x4000) != 0) { /* DB6 all release? */ - goto FUN_D6; - } + if ((inw(dev->ioport[0] + 0x1c) & 0x4000) != 0) /* DB6 all release? */ + i = 0; } return j; -- GitLab From 58c4d046b4d1d5b84875eb73115f3ef092abccce Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:52 +0100 Subject: [PATCH 0617/2855] atp870u: Remove ugly gotos #4 Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index b3d4e9db3c101..68afe11251660 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -970,19 +970,19 @@ static void tscam(struct Scsi_Host *host) } else { outb(0x00, dev->ioport[0] + 0x1b); } -wait_rdyok: - outb(0x09, dev->ioport[0] + 0x18); - - while ((inb(dev->ioport[0] + 0x1f) & 0x80) == 0x00) - cpu_relax(); - k = inb(dev->ioport[0] + 0x17); - if (k != 0x16) { - if ((k == 0x85) || (k == 0x42)) { - continue; - } - outb(0x41, dev->ioport[0] + 0x10); - goto wait_rdyok; - } + do { + outb(0x09, dev->ioport[0] + 0x18); + + while ((inb(dev->ioport[0] + 0x1f) & 0x80) == 0x00) + cpu_relax(); + k = inb(dev->ioport[0] + 0x17); + if ((k == 0x85) || (k == 0x42)) + break; + if (k != 0x16) + outb(0x41, dev->ioport[0] + 0x10); + } while (k != 0x16); + if ((k == 0x85) || (k == 0x42)) + continue; assignid_map |= m; } @@ -1003,10 +1003,8 @@ wait_rdyok: mdelay(128); val &= 0x00fb; /* after 1ms no msg */ outw(val, dev->ioport[0] + 0x1c); -wait_nomsg: - if ((inb(dev->ioport[0] + 0x1c) & 0x04) != 0) { - goto wait_nomsg; - } + while ((inb(dev->ioport[0] + 0x1c) & 0x04) != 0) + ; outb(1, 0x80); udelay(100); for (n = 0; n < 0x30000; n++) { -- GitLab From c7fcc089b0e49dce9208277871f69e42d8fb1db0 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:53 +0100 Subject: [PATCH 0618/2855] atp870u: Remove ugly gotos #5 Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 134 +++++++++++++++++++---------------------- 1 file changed, 62 insertions(+), 72 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 68afe11251660..fd2bb6f035dac 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1007,28 +1007,22 @@ static void tscam(struct Scsi_Host *host) ; outb(1, 0x80); udelay(100); - for (n = 0; n < 0x30000; n++) { - if ((inb(dev->ioport[0] + 0x1c) & 0x80) != 0) { /* bsy ? */ - goto wait_io; - } - } - goto TCM_SYNC; -wait_io: - for (n = 0; n < 0x30000; n++) { - if ((inb(dev->ioport[0] + 0x1c) & 0x81) == 0x0081) { - goto wait_io1; - } - } - goto TCM_SYNC; -wait_io1: - inb(0x80); - val |= 0x8003; /* io,cd,db7 */ - outw(val, dev->ioport[0] + 0x1c); - inb(0x80); - val &= 0x00bf; /* no sel */ - outw(val, dev->ioport[0] + 0x1c); - outb(2, 0x80); -TCM_SYNC: + for (n = 0; n < 0x30000; n++) + if ((inb(dev->ioport[0] + 0x1c) & 0x80) != 0) /* bsy ? */ + break; + if (n < 0x30000) + for (n = 0; n < 0x30000; n++) + if ((inb(dev->ioport[0] + 0x1c) & 0x81) == 0x0081) { + inb(0x80); + val |= 0x8003; /* io,cd,db7 */ + outw(val, dev->ioport[0] + 0x1c); + inb(0x80); + val &= 0x00bf; /* no sel */ + outw(val, dev->ioport[0] + 0x1c); + outb(2, 0x80); + break; + } + while (1) { /* * The funny division into multiple delays is to accomodate * arches like ARM where udelay() multiplies its argument by @@ -1059,31 +1053,28 @@ TCM_SYNC: outb(4, 0x80); i = 8; j = 0; -TCM_ID: - if ((inw(dev->ioport[0] + 0x1c) & 0x2000) == 0) { - goto TCM_ID; - } - outb(5, 0x80); - val &= 0x00ff; /* get ID_STRING */ - val |= 0x2000; - k = fun_scam(dev, &val); - if ((k & 0x03) == 0) { - goto TCM_5; - } - mbuf[j] <<= 0x01; - mbuf[j] &= 0xfe; - if ((k & 0x02) != 0) { - mbuf[j] |= 0x01; - } - i--; - if (i > 0) { - goto TCM_ID; + + while (1) { + if ((inw(dev->ioport[0] + 0x1c) & 0x2000) == 0) + continue; + outb(5, 0x80); + val &= 0x00ff; /* get ID_STRING */ + val |= 0x2000; + k = fun_scam(dev, &val); + if ((k & 0x03) == 0) + break; + mbuf[j] <<= 0x01; + mbuf[j] &= 0xfe; + if ((k & 0x02) != 0) + mbuf[j] |= 0x01; + i--; + if (i > 0) + continue; + j++; + i = 8; } - j++; - i = 8; - goto TCM_ID; -TCM_5: /* isolation complete.. */ + /* isolation complete.. */ /* mbuf[32]=0; printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */ i = 15; @@ -1091,33 +1082,33 @@ TCM_5: /* isolation complete.. */ if ((j & 0x20) != 0) { /* bit5=1:ID up to 7 */ i = 7; } - if ((j & 0x06) == 0) { /* IDvalid? */ - goto G2Q5; - } - k = mbuf[1]; -small_id: - m = 1; - m <<= k; - if ((m & assignid_map) == 0) { - goto G2Q_QUIN; - } - if (k > 0) { - k--; - goto small_id; - } -G2Q5: /* srch from max acceptable ID# */ - k = i; /* max acceptable ID# */ -G2Q_LP: - m = 1; - m <<= k; - if ((m & assignid_map) == 0) { - goto G2Q_QUIN; + if ((j & 0x06) != 0) { /* IDvalid? */ + k = mbuf[1]; + while (1) { + m = 1; + m <<= k; + if ((m & assignid_map) == 0) + break; + if (k > 0) + k--; + else + break; + } } - if (k > 0) { - k--; - goto G2Q_LP; + if ((m & assignid_map) != 0) { /* srch from max acceptable ID# */ + k = i; /* max acceptable ID# */ + while (1) { + m = 1; + m <<= k; + if ((m & assignid_map) == 0) + break; + if (k > 0) + k--; + else + break; + } } -G2Q_QUIN: /* k=binID#, */ + /* k=binID#, */ assignid_map |= m; if (k < 8) { quintet[0] = 0x38; /* 1st dft ID<8 */ @@ -1136,8 +1127,7 @@ G2Q_QUIN: /* k=binID#, */ val |= m; fun_scam(dev, &val); - goto TCM_SYNC; - + } } static void is870(struct atp_unit *dev, unsigned int wkport) -- GitLab From 6a3cebb682190f878dcab60450cfdb2eddeceb69 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:54 +0100 Subject: [PATCH 0619/2855] atp870u: Introduce HW access wrappers Introduce *_read? and *_write? wrappers to improve code readability. Also make sure that baseport is always initialized, not only for ATP880. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 472 ++++++++++++++++++++++------------------- 1 file changed, 252 insertions(+), 220 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index fd2bb6f035dac..07b50acf6b921 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -44,6 +44,51 @@ static void send_s870(struct atp_unit *dev,unsigned char c); static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c); static void tscam_885(void); +static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val) +{ + outb(val, atp->baseport + reg); +} + +static inline void atp_writeb_io(struct atp_unit *atp, u8 channel, u8 reg, u8 val) +{ + outb(val, atp->ioport[channel] + reg); +} + +static inline void atp_writew_io(struct atp_unit *atp, u8 channel, u8 reg, u16 val) +{ + outw(val, atp->ioport[channel] + reg); +} + +static inline void atp_writeb_pci(struct atp_unit *atp, u8 channel, u8 reg, u8 val) +{ + outb(val, atp->pciport[channel] + reg); +} + +static inline void atp_writel_pci(struct atp_unit *atp, u8 channel, u8 reg, u32 val) +{ + outl(val, atp->pciport[channel] + reg); +} + +static inline u8 atp_readb_base(struct atp_unit *atp, u8 reg) +{ + return inb(atp->baseport + reg); +} + +static inline u8 atp_readb_io(struct atp_unit *atp, u8 channel, u8 reg) +{ + return inb(atp->ioport[channel] + reg); +} + +static inline u16 atp_readw_io(struct atp_unit *atp, u8 channel, u8 reg) +{ + return inw(atp->ioport[channel] + reg); +} + +static inline u8 atp_readb_pci(struct atp_unit *atp, u8 channel, u8 reg) +{ + return inb(atp->pciport[channel] + reg); +} + static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) { unsigned long flags; @@ -59,7 +104,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) struct atp_unit *dev = (struct atp_unit *)&host->hostdata; for (c = 0; c < 2; c++) { - j = inb(dev->ioport[c] + 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x80) != 0) break; dev->in_int[c] = 0; @@ -70,29 +115,29 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) printk("atp870u_intr_handle enter\n"); #endif dev->in_int[c] = 1; - cmdp = inb(dev->ioport[c] + 0x10); + cmdp = atp_readb_io(dev, c, 0x10); if (dev->working[c] != 0) { if (dev->dev_id == ATP885_DEVID) { - if ((inb(dev->ioport[c] + 0x16) & 0x80) == 0) - outb((inb(dev->ioport[c] + 0x16) | 0x80), dev->ioport[c] + 0x16); + if ((atp_readb_io(dev, c, 0x16) & 0x80) == 0) + atp_writeb_io(dev, c, 0x16, (atp_readb_io(dev, c, 0x16) | 0x80)); } - if ((inb(dev->pciport[c]) & 0x08) != 0) + if ((atp_readb_pci(dev, c, 0x00) & 0x08) != 0) { for (k=0; k < 1000; k++) { - if ((inb(dev->pciport[c] + 2) & 0x08) == 0) + if ((atp_readb_pci(dev, c, 2) & 0x08) == 0) break; - if ((inb(dev->pciport[c] + 2) & 0x01) == 0) + if ((atp_readb_pci(dev, c, 2) & 0x01) == 0) break; } } - outb(0x00, dev->pciport[c]); + atp_writeb_pci(dev, c, 0, 0x00); - i = inb(dev->ioport[c] + 0x17); + i = atp_readb_io(dev, c, 0x17); if (dev->dev_id == ATP885_DEVID) - outb(0x06, dev->pciport[c] + 2); + atp_writeb_pci(dev, c, 2, 0x06); - target_id = inb(dev->ioport[c] + 0x15); + target_id = atp_readb_io(dev, c, 0x15); /* * Remap wide devices onto id numbers @@ -121,9 +166,9 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) } if (dev->dev_id == ATP885_DEVID) { adrcnt = 0; - ((unsigned char *) &adrcnt)[2] = inb(dev->ioport[c] + 0x12); - ((unsigned char *) &adrcnt)[1] = inb(dev->ioport[c] + 0x13); - ((unsigned char *) &adrcnt)[0] = inb(dev->ioport[c] + 0x14); + ((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12); + ((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13); + ((unsigned char *) &adrcnt)[0] = atp_readb_io(dev, c, 0x14); if (dev->id[c][target_id].last_len != adrcnt) { k = dev->id[c][target_id].last_len; @@ -140,10 +185,9 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) * Flip wide */ if (dev->wide_id[c] != 0) { - outb(0x01, dev->ioport[c] + 0x1b); - while ((inb(dev->ioport[c] + 0x1b) & 0x01) != 0x01) { - outb(0x01, dev->ioport[c] + 0x1b); - } + atp_writeb_io(dev, c, 0x1b, 0x01); + while ((atp_readb_io(dev, c, 0x1b) & 0x01) != 0x01) + atp_writeb_io(dev, c, 0x1b, 0x01); } /* * Issue more commands @@ -178,15 +222,15 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) dev->last_cmd[c] = 0xff; } adrcnt = 0; - ((unsigned char *) &adrcnt)[2] = inb(dev->ioport[c] + 0x12); - ((unsigned char *) &adrcnt)[1] = inb(dev->ioport[c] + 0x13); - ((unsigned char *) &adrcnt)[0] = inb(dev->ioport[c] + 0x14); + ((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12); + ((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13); + ((unsigned char *) &adrcnt)[0] = atp_readb_io(dev, c, 0x14); k = dev->id[c][target_id].last_len; k -= adrcnt; dev->id[c][target_id].tran_len = k; dev->id[c][target_id].last_len = adrcnt; - outb(0x41, dev->ioport[c] + 0x10); - outb(0x08, dev->ioport[c] + 0x18); + atp_writeb_io(dev, c, 0x10, 0x41); + atp_writeb_io(dev, c, 0x18, 0x08); dev->in_int[c] = 0; return IRQ_HANDLED; } @@ -205,9 +249,9 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) printk(KERN_DEBUG "Device reselect\n"); #endif lun = 0; - if (cmdp == 0x44 || i==0x80) { - lun = inb(dev->ioport[c] + 0x1d) & 0x07; - } else { + if (cmdp == 0x44 || i == 0x80) + lun = atp_readb_io(dev, c, 0x1d) & 0x07; + else { if ((dev->last_cmd[c] & 0xf0) != 0x40) { dev->last_cmd[c] = 0xff; } @@ -216,26 +260,26 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) printk("cmdp = 0x41\n"); #endif adrcnt = 0; - ((unsigned char *) &adrcnt)[2] = inb(dev->ioport[c] + 0x12); - ((unsigned char *) &adrcnt)[1] = inb(dev->ioport[c] + 0x13); - ((unsigned char *) &adrcnt)[0] = inb(dev->ioport[c] + 0x14); + ((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12); + ((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13); + ((unsigned char *) &adrcnt)[0] = atp_readb_io(dev, c, 0x14); k = dev->id[c][target_id].last_len; k -= adrcnt; dev->id[c][target_id].tran_len = k; dev->id[c][target_id].last_len = adrcnt; - outb(0x08, dev->ioport[c] + 0x18); + atp_writeb_io(dev, c, 0x18, 0x08); dev->in_int[c] = 0; return IRQ_HANDLED; } else { #ifdef ED_DBGP printk("cmdp != 0x41\n"); #endif - outb(0x46, dev->ioport[c] + 0x10); + atp_writeb_io(dev, c, 0x10, 0x46); dev->id[c][target_id].dirct = 0x00; - outb(0x00, dev->ioport[c] + 0x12); - outb(0x00, dev->ioport[c] + 0x13); - outb(0x00, dev->ioport[c] + 0x14); - outb(0x08, dev->ioport[c] + 0x18); + atp_writeb_io(dev, c, 0x12, 0x00); + atp_writeb_io(dev, c, 0x13, 0x00); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); dev->in_int[c] = 0; return IRQ_HANDLED; } @@ -244,12 +288,12 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) dev->last_cmd[c] |= 0x40; } if (dev->dev_id == ATP885_DEVID) { - j = inb(dev->baseport + 0x29) & 0xfe; - outb(j, dev->baseport + 0x29); + j = atp_readb_base(dev, 0x29) & 0xfe; + atp_writeb_base(dev, 0x29, j); } else - outb(0x45, dev->ioport[c] + 0x10); + atp_writeb_io(dev, c, 0x10, 0x45); - target_id = inb(dev->ioport[c] + 0x16); + target_id = atp_readb_io(dev, c, 0x16); /* * Remap wide identifiers */ @@ -259,7 +303,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) target_id &= 0x07; } if (dev->dev_id == ATP885_DEVID) - outb(0x45, dev->ioport[c] + 0x10); + atp_writeb_io(dev, c, 0x10, 0x45); workreq = dev->id[c][target_id].curr_req; #ifdef ED_DBGP scmd_printk(KERN_DEBUG, workreq, "CDB"); @@ -268,16 +312,16 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) printk("\n"); #endif - outb(lun, dev->ioport[c] + 0x0f); - outb(dev->id[c][target_id].devsp, dev->ioport[c] + 0x11); + atp_writeb_io(dev, c, 0x0f, lun); + atp_writeb_io(dev, c, 0x11, dev->id[c][target_id].devsp); adrcnt = dev->id[c][target_id].tran_len; k = dev->id[c][target_id].last_len; - outb(((unsigned char *) &k)[2], dev->ioport[c] + 0x12); - outb(((unsigned char *) &k)[1], dev->ioport[c] + 0x13); - outb(((unsigned char *) &k)[0], dev->ioport[c] + 0x14); + atp_writeb_io(dev, c, 0x12, ((unsigned char *) &k)[2]); + atp_writeb_io(dev, c, 0x13, ((unsigned char *) &k)[1]); + atp_writeb_io(dev, c, 0x14, ((unsigned char *) &k)[0]); #ifdef ED_DBGP - printk("k %x, k[0] 0x%x k[1] 0x%x k[2] 0x%x\n", k, inb(dev->ioport[c] + 0x14), inb(dev->ioport[c] + 0x13), inb(dev->ioport[c] + 0x12)); + printk("k %x, k[0] 0x%x k[1] 0x%x k[2] 0x%x\n", k, atp_readb_io(dev, c, 0x14), atp_readb_io(dev, c, 0x13), atp_readb_io(dev, c, 0x12)); #endif /* Remap wide */ j = target_id; @@ -286,30 +330,28 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) } /* Add direction */ j |= dev->id[c][target_id].dirct; - outb(j, dev->ioport[c] + 0x15); - outb(0x80, dev->ioport[c] + 0x16); + atp_writeb_io(dev, c, 0x15, j); + atp_writeb_io(dev, c, 0x16, 0x80); /* enable 32 bit fifo transfer */ if (dev->dev_id == ATP885_DEVID) { - i=inb(dev->pciport[c] + 1) & 0xf3; + i = atp_readb_pci(dev, c, 1) & 0xf3; //j=workreq->cmnd[0]; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { i |= 0x0c; } - outb(i, dev->pciport[c] + 1); + atp_writeb_pci(dev, c, 1, i); } else if ((dev->dev_id == ATP880_DEVID1) || (dev->dev_id == ATP880_DEVID2) ) { - if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { - outb((unsigned char) ((inb(dev->ioport[c] - 0x05) & 0x3f) | 0xc0), dev->ioport[c] - 0x05);///minus 0x05??? - } else { - outb((unsigned char) (inb(dev->ioport[c] - 0x05) & 0x3f), dev->ioport[c] - 0x05);///minus 0x05??? - } + if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) + atp_writeb_base(dev, 0x3b, (atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0); + else + atp_writeb_base(dev, 0x3b, atp_readb_base(dev, 0x3b) & 0x3f); } else { - if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { - outb((unsigned char) ((inb(dev->ioport[c] + 0x3a) & 0xf3) | 0x08), dev->ioport[c] + 0x3a); - } else { - outb((unsigned char) (inb(dev->ioport[c] + 0x3a) & 0xf3), dev->ioport[c] + 0x3a); - } + if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) + atp_writeb_io(dev, c, 0x3a, (atp_readb_io(dev, c, 0x3a) & 0xf3) | 0x08); + else + atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xf3); } j = 0; id = 1; @@ -320,12 +362,11 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) if ((id & dev->wide_id[c]) != 0) { j |= 0x01; } - outb(j, dev->ioport[c] + 0x1b); - while ((inb(dev->ioport[c] + 0x1b) & 0x01) != j) { - outb(j,dev->ioport[c] + 0x1b); - } + atp_writeb_io(dev, c, 0x1b, j); + while ((atp_readb_io(dev, c, 0x1b) & 0x01) != j) + atp_writeb_io(dev, c, 0x1b, j); if (dev->id[c][target_id].last_len == 0) { - outb(0x08, dev->ioport[c] + 0x18); + atp_writeb_io(dev, c, 0x18, 0x08); dev->in_int[c] = 0; #ifdef ED_DBGP printk("dev->id[c][target_id].last_len = 0\n"); @@ -358,28 +399,28 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) } } } - outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 0x04); + atp_writel_pci(dev, c, 0x04, dev->id[c][target_id].prdaddr); #ifdef ED_DBGP printk("dev->id[%d][%d].prdaddr 0x%8x\n", c, target_id, dev->id[c][target_id].prdaddr); #endif if (dev->dev_id != ATP885_DEVID) { - outb(0x06, dev->pciport[c] + 2); - outb(0x00, dev->pciport[c] + 2); + atp_writeb_pci(dev, c, 2, 0x06); + atp_writeb_pci(dev, c, 2, 0x00); } /* * Check transfer direction */ if (dev->id[c][target_id].dirct != 0) { - outb(0x08, dev->ioport[c] + 0x18); - outb(0x01, dev->pciport[c]); + atp_writeb_io(dev, c, 0x18, 0x08); + atp_writeb_pci(dev, c, 0, 0x01); dev->in_int[c] = 0; #ifdef ED_DBGP printk("status 0x80 return dirct != 0\n"); #endif return IRQ_HANDLED; } - outb(0x08, dev->ioport[c] + 0x18); - outb(0x09, dev->pciport[c]); + atp_writeb_io(dev, c, 0x18, 0x08); + atp_writeb_pci(dev, c, 0, 0x09); dev->in_int[c] = 0; #ifdef ED_DBGP printk("status 0x80 return dirct = 0\n"); @@ -398,7 +439,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) dev->last_cmd[c] = 0xff; } if (i == 0x16) { - workreq->result = inb(dev->ioport[c] + 0x0f); + workreq->result = atp_readb_io(dev, c, 0x0f); if (((dev->r1f[c][target_id] & 0x10) != 0)&&(dev->dev_id==ATP885_DEVID)) { printk(KERN_WARNING "AEC67162 CRC ERROR !\n"); workreq->result = 0x02; @@ -407,8 +448,8 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) workreq->result = 0x02; if (dev->dev_id == ATP885_DEVID) { - j = inb(dev->baseport + 0x29) | 0x01; - outb(j, dev->baseport + 0x29); + j = atp_readb_base(dev, 0x29) | 0x01; + atp_writeb_base(dev, 0x29, j); } /* * Complete the command @@ -430,10 +471,9 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) * Take it back wide */ if (dev->wide_id[c] != 0) { - outb(0x01, dev->ioport[c] + 0x1b); - while ((inb(dev->ioport[c] + 0x1b) & 0x01) != 0x01) { - outb(0x01, dev->ioport[c] + 0x1b); - } + atp_writeb_io(dev, c, 0x1b, 0x01); + while ((atp_readb_io(dev, c, 0x1b) & 0x01) != 0x01) + atp_writeb_io(dev, c, 0x1b, 0x01); } /* * If there is stuff to send and nothing going then send it @@ -458,52 +498,51 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) } i &= 0x0f; if (i == 0x09) { - outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 4); - outb(0x06, dev->pciport[c] + 2); - outb(0x00, dev->pciport[c] + 2); - outb(0x41, dev->ioport[c] + 0x10); + atp_writel_pci(dev, c, 4, dev->id[c][target_id].prdaddr); + atp_writeb_pci(dev, c, 2, 0x06); + atp_writeb_pci(dev, c, 2, 0x00); + atp_writeb_io(dev, c, 0x10, 0x41); if (dev->dev_id == ATP885_DEVID) { k = dev->id[c][target_id].last_len; - outb((unsigned char) (((unsigned char *) (&k))[2]), dev->ioport[c] + 0x12); - outb((unsigned char) (((unsigned char *) (&k))[1]), dev->ioport[c] + 0x13); - outb((unsigned char) (((unsigned char *) (&k))[0]), dev->ioport[c] + 0x14); + atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&k))[2]); + atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&k))[1]); + atp_writeb_io(dev, c, 0x14, ((unsigned char *) (&k))[0]); dev->id[c][target_id].dirct = 0x00; } else { dev->id[c][target_id].dirct = 0x00; } - outb(0x08, dev->ioport[c] + 0x18); - outb(0x09, dev->pciport[c]); + atp_writeb_io(dev, c, 0x18, 0x08); + atp_writeb_pci(dev, c, 0, 0x09); dev->in_int[c] = 0; return IRQ_HANDLED; } if (i == 0x08) { - outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 4); - outb(0x06, dev->pciport[c] + 2); - outb(0x00, dev->pciport[c] + 2); - outb(0x41, dev->ioport[c] + 0x10); + atp_writel_pci(dev, c, 4, dev->id[c][target_id].prdaddr); + atp_writeb_pci(dev, c, 2, 0x06); + atp_writeb_pci(dev, c, 2, 0x00); + atp_writeb_io(dev, c, 0x10, 0x41); if (dev->dev_id == ATP885_DEVID) { k = dev->id[c][target_id].last_len; - outb((unsigned char) (((unsigned char *) (&k))[2]), dev->ioport[c] + 0x12); - outb((unsigned char) (((unsigned char *) (&k))[1]), dev->ioport[c] + 0x13); - outb((unsigned char) (((unsigned char *) (&k))[0]), dev->ioport[c] + 0x14); + atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&k))[2]); + atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&k))[1]); + atp_writeb_io(dev, c, 0x14, ((unsigned char *) (&k))[0]); } - outb((unsigned char) (inb(dev->ioport[c] + 0x15) | 0x20), dev->ioport[c] + 0x15); + atp_writeb_io(dev, c, 0x15, atp_readb_io(dev, c, 0x15) | 0x20); dev->id[c][target_id].dirct = 0x20; - outb(0x08, dev->ioport[c] + 0x18); - outb(0x01, dev->pciport[c]); + atp_writeb_io(dev, c, 0x18, 0x08); + atp_writeb_pci(dev, c, 0, 0x01); dev->in_int[c] = 0; return IRQ_HANDLED; } - if (i == 0x0a) { - outb(0x30, dev->ioport[c] + 0x10); - } else { - outb(0x46, dev->ioport[c] + 0x10); - } + if (i == 0x0a) + atp_writeb_io(dev, c, 0x10, 0x30); + else + atp_writeb_io(dev, c, 0x10, 0x46); dev->id[c][target_id].dirct = 0x00; - outb(0x00, dev->ioport[c] + 0x12); - outb(0x00, dev->ioport[c] + 0x13); - outb(0x00, dev->ioport[c] + 0x14); - outb(0x08, dev->ioport[c] + 0x18); + atp_writeb_io(dev, c, 0x12, 0x00); + atp_writeb_io(dev, c, 0x13, 0x00); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); } dev->in_int[c] = 0; @@ -590,9 +629,9 @@ static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p, } dev->quereq[c][dev->quend[c]] = req_p; #ifdef ED_DBGP - printk("dev->ioport[c] = %x inb(dev->ioport[c] + 0x1c) = %x dev->in_int[%d] = %d dev->in_snd[%d] = %d\n",dev->ioport[c],inb(dev->ioport[c] + 0x1c),c,dev->in_int[c],c,dev->in_snd[c]); + printk("dev->ioport[c] = %x atp_readb_io(dev, c, 0x1c) = %x dev->in_int[%d] = %d dev->in_snd[%d] = %d\n",dev->ioport[c],atp_readb_io(dev, c, 0x1c),c,dev->in_int[c],c,dev->in_snd[c]); #endif - if ((inb(dev->ioport[c] + 0x1c) == 0) && (dev->in_int[c] == 0) && (dev->in_snd[c] == 0)) { + if ((atp_readb_io(dev, c, 0x1c) == 0) && (dev->in_int[c] == 0) && (dev->in_snd[c] == 0)) { #ifdef ED_DBGP printk("Call sent_s870(atp870u_queuecommand)\n"); #endif @@ -666,7 +705,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c) dev->id[c][scmd_id(workreq)].curr_req = workreq; dev->last_cmd[c] = scmd_id(workreq); } - if ((inb(dev->ioport[c] + 0x1f) & 0xb0) != 0 || inb(dev->ioport[c] + 0x1c) != 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0xb0) != 0 || atp_readb_io(dev, c, 0x1c) != 0) { #ifdef ED_DBGP printk("Abort to Send\n"); #endif @@ -685,8 +724,8 @@ static void send_s870(struct atp_unit *dev,unsigned char c) l = scsi_bufflen(workreq); if (dev->dev_id == ATP885_DEVID) { - j = inb(dev->baseport + 0x29) & 0xfe; - outb(j, dev->baseport + 0x29); + j = atp_readb_base(dev, 0x29) & 0xfe; + atp_writeb_base(dev, 0x29, j); dev->r1f[c][scmd_id(workreq)] = 0; } @@ -709,9 +748,9 @@ static void send_s870(struct atp_unit *dev,unsigned char c) if ((w & dev->wide_id[c]) != 0) { j |= 0x01; } - outb(j, dev->ioport[c] + 0x1b); - while ((inb(dev->ioport[c] + 0x1b) & 0x01) != j) { - outb(j,dev->ioport[c] + 0x1b); + atp_writeb_io(dev, c, 0x1b, j); + while ((atp_readb_io(dev, c, 0x1b) & 0x01) != j) { + atp_writeb_pci(dev, c, 0x1b, j); #ifdef ED_DBGP printk("send_s870 while loop 1\n"); #endif @@ -720,21 +759,19 @@ static void send_s870(struct atp_unit *dev,unsigned char c) * Write the command */ - outb(workreq->cmd_len, dev->ioport[c] + 0x00); - outb(0x2c, dev->ioport[c] + 0x01); - if (dev->dev_id == ATP885_DEVID) { - outb(0x7f, dev->ioport[c] + 0x02); - } else { - outb(0xcf, dev->ioport[c] + 0x02); - } - for (i = 0; i < workreq->cmd_len; i++) { - outb(workreq->cmnd[i], dev->ioport[c] + 0x03 + i); - } - outb(workreq->device->lun, dev->ioport[c] + 0x0f); + atp_writeb_io(dev, c, 0x00, workreq->cmd_len); + atp_writeb_io(dev, c, 0x01, 0x2c); + if (dev->dev_id == ATP885_DEVID) + atp_writeb_io(dev, c, 0x02, 0x7f); + else + atp_writeb_io(dev, c, 0x02, 0xcf); + for (i = 0; i < workreq->cmd_len; i++) + atp_writeb_io(dev, c, 0x03 + i, workreq->cmnd[i]); + atp_writeb_io(dev, c, 0x0f, workreq->device->lun); /* * Write the target */ - outb(dev->id[c][target_id].devsp, dev->ioport[c] + 0x11); + atp_writeb_io(dev, c, 0x11, dev->id[c][target_id].devsp); #ifdef ED_DBGP printk("dev->id[%d][%d].devsp = %2x\n",c,target_id,dev->id[c][target_id].devsp); #endif @@ -743,9 +780,9 @@ static void send_s870(struct atp_unit *dev,unsigned char c) /* * Write transfer size */ - outb((unsigned char) (((unsigned char *) (&l))[2]), dev->ioport[c] + 0x12); - outb((unsigned char) (((unsigned char *) (&l))[1]), dev->ioport[c] + 0x13); - outb((unsigned char) (((unsigned char *) (&l))[0]), dev->ioport[c] + 0x14); + atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&l))[2]); + atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&l))[1]); + atp_writeb_io(dev, c, 0x14, ((unsigned char *) (&l))[0]); j = target_id; dev->id[c][j].last_len = l; dev->id[c][j].tran_len = 0; @@ -761,23 +798,21 @@ static void send_s870(struct atp_unit *dev,unsigned char c) /* * Check transfer direction */ - if (workreq->sc_data_direction == DMA_TO_DEVICE) { - outb((unsigned char) (j | 0x20), dev->ioport[c] + 0x15); - } else { - outb(j, dev->ioport[c] + 0x15); - } - outb((unsigned char) (inb(dev->ioport[c] + 0x16) | 0x80), dev->ioport[c] + 0x16); - outb(0x80, dev->ioport[c] + 0x16); + if (workreq->sc_data_direction == DMA_TO_DEVICE) + atp_writeb_io(dev, c, 0x15, j | 0x20); + else + atp_writeb_io(dev, c, 0x15, j); + atp_writeb_io(dev, c, 0x16, atp_readb_io(dev, c, 0x16) | 0x80); + atp_writeb_io(dev, c, 0x16, 0x80); dev->id[c][target_id].dirct = 0; if (l == 0) { - if (inb(dev->ioport[c] + 0x1c) == 0) { + if (atp_readb_io(dev, c, 0x1c) == 0) { #ifdef ED_DBGP printk("change SCSI_CMD_REG 0x08\n"); #endif - outb(0x08, dev->ioport[c] + 0x18); - } else { + atp_writeb_io(dev, c, 0x18, 0x08); + } else dev->last_cmd[c] |= 0x40; - } dev->in_snd[c] = 0; return; } @@ -821,36 +856,34 @@ static void send_s870(struct atp_unit *dev,unsigned char c) printk("send_s870: prdaddr_2 0x%8x target_id %d\n", dev->id[c][target_id].prdaddr,target_id); #endif dev->id[c][target_id].prdaddr = dev->id[c][target_id].prd_bus; - outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 4); - outb(0x06, dev->pciport[c] + 2); - outb(0x00, dev->pciport[c] + 2); + atp_writel_pci(dev, c, 4, dev->id[c][target_id].prdaddr); + atp_writeb_pci(dev, c, 2, 0x06); + atp_writeb_pci(dev, c, 2, 0x00); if (dev->dev_id == ATP885_DEVID) { - j = inb(dev->pciport[c] + 1) & 0xf3; + j = atp_readb_pci(dev, c, 1) & 0xf3; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { j |= 0x0c; } - outb(j, dev->pciport[c] + 1); + atp_writeb_pci(dev, c, 1, j); } else if ((dev->dev_id == ATP880_DEVID1) || (dev->dev_id == ATP880_DEVID2)) { - if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { - outb((unsigned char) ((inb(dev->ioport[c] - 0x05) & 0x3f) | 0xc0), dev->ioport[c] - 0x05); - } else { - outb((unsigned char) (inb(dev->ioport[c] - 0x05) & 0x3f), dev->ioport[c] - 0x05); - } + if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) + atp_writeb_base(dev, 0x3b, (atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0); + else + atp_writeb_base(dev, 0x3b, atp_readb_base(dev, 0x3b) & 0x3f); } else { - if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { - outb((inb(dev->ioport[c] + 0x3a) & 0xf3) | 0x08, dev->ioport[c] + 0x3a); - } else { - outb(inb(dev->ioport[c] + 0x3a) & 0xf3, dev->ioport[c] + 0x3a); - } + if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) + atp_writeb_io(dev, c, 0x3a, (atp_readb_io(dev, c, 0x3a) & 0xf3) | 0x08); + else + atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xf3); } if(workreq->sc_data_direction == DMA_TO_DEVICE) { dev->id[c][target_id].dirct = 0x20; - if (inb(dev->ioport[c] + 0x1c) == 0) { - outb(0x08, dev->ioport[c] + 0x18); - outb(0x01, dev->pciport[c]); + if (atp_readb_io(dev, c, 0x1c) == 0) { + atp_writeb_io(dev, c, 0x18, 0x08); + atp_writeb_pci(dev, c, 0, 0x01); #ifdef ED_DBGP printk( "start DMA(to target)\n"); #endif @@ -860,9 +893,9 @@ static void send_s870(struct atp_unit *dev,unsigned char c) dev->in_snd[c] = 0; return; } - if (inb(dev->ioport[c] + 0x1c) == 0) { - outb(0x08, dev->ioport[c] + 0x18); - outb(0x09, dev->pciport[c]); + if (atp_readb_io(dev, c, 0x1c) == 0) { + atp_writeb_io(dev, c, 0x18, 0x08); + atp_writeb_pci(dev, c, 0, 0x09); #ifdef ED_DBGP printk( "start DMA(to host)\n"); #endif @@ -879,28 +912,28 @@ static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val) unsigned short int i, k; unsigned char j; - outw(*val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, *val); for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ - k = inw(dev->ioport[0] + 0x1c); + k = atp_readw_io(dev, 0, 0x1c); j = (unsigned char) (k >> 8); if ((k & 0x8000) != 0) /* DB7 all release? */ i = 0; } *val |= 0x4000; /* assert DB6 */ - outw(*val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, *val); *val &= 0xdfff; /* assert DB5 */ - outw(*val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, *val); for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ - if ((inw(dev->ioport[0] + 0x1c) & 0x2000) != 0) /* DB5 all release? */ + if ((atp_readw_io(dev, 0, 0x1c) & 0x2000) != 0) /* DB5 all release? */ i = 0; } *val |= 0x8000; /* no DB4-0, assert DB7 */ *val &= 0xe0ff; - outw(*val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, *val); *val &= 0xbfff; /* release DB6 */ - outw(*val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, *val); for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ - if ((inw(dev->ioport[0] + 0x1c) & 0x4000) != 0) /* DB6 all release? */ + if ((atp_readw_io(dev, 0, 0x1c) & 0x4000) != 0) /* DB6 all release? */ i = 0; } @@ -926,9 +959,9 @@ static void tscam(struct Scsi_Host *host) } */ - outb(0x08, dev->ioport[0] + 1); - outb(0x7f, dev->ioport[0] + 2); - outb(0x20, dev->ioport[0] + 0x11); + atp_writeb_io(dev, 0, 1, 0x08); + atp_writeb_io(dev, 0, 2, 0x7f); + atp_writeb_io(dev, 0, 0x11, 0x20); if ((dev->scam_on & 0x40) == 0) { return; @@ -941,13 +974,13 @@ static void tscam(struct Scsi_Host *host) j = 8; } assignid_map = m; - outb(0x02, dev->ioport[0] + 0x02); /* 2*2=4ms,3EH 2/32*3E=3.9ms */ - outb(0, dev->ioport[0] + 0x03); - outb(0, dev->ioport[0] + 0x04); - outb(0, dev->ioport[0] + 0x05); - outb(0, dev->ioport[0] + 0x06); - outb(0, dev->ioport[0] + 0x07); - outb(0, dev->ioport[0] + 0x08); + atp_writeb_io(dev, 0, 0x02, 0x02); /* 2*2=4ms,3EH 2/32*3E=3.9ms */ + atp_writeb_io(dev, 0, 0x03, 0); + atp_writeb_io(dev, 0, 0x04, 0); + atp_writeb_io(dev, 0, 0x05, 0); + atp_writeb_io(dev, 0, 0x06, 0); + atp_writeb_io(dev, 0, 0x07, 0); + atp_writeb_io(dev, 0, 0x08, 0); for (i = 0; i < j; i++) { m = 1; @@ -955,70 +988,69 @@ static void tscam(struct Scsi_Host *host) if ((m & assignid_map) != 0) { continue; } - outb(0, dev->ioport[0] + 0x0f); - outb(0, dev->ioport[0] + 0x12); - outb(0, dev->ioport[0] + 0x13); - outb(0, dev->ioport[0] + 0x14); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, 0); + atp_writeb_io(dev, 0, 0x14, 0); if (i > 7) { k = (i & 0x07) | 0x40; } else { k = i; } - outb(k, dev->ioport[0] + 0x15); - if (dev->chip_ver == 4) { - outb(0x01, dev->ioport[0] + 0x1b); - } else { - outb(0x00, dev->ioport[0] + 0x1b); - } + atp_writeb_io(dev, 0, 0x15, k); + if (dev->chip_ver == 4) + atp_writeb_io(dev, 0, 0x1b, 0x01); + else + atp_writeb_io(dev, 0, 0x1b, 0x00); do { - outb(0x09, dev->ioport[0] + 0x18); + atp_writeb_io(dev, 0, 0x18, 0x09); - while ((inb(dev->ioport[0] + 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - k = inb(dev->ioport[0] + 0x17); + k = atp_readb_io(dev, 0, 0x17); if ((k == 0x85) || (k == 0x42)) break; if (k != 0x16) - outb(0x41, dev->ioport[0] + 0x10); + atp_writeb_io(dev, 0, 0x10, 0x41); } while (k != 0x16); if ((k == 0x85) || (k == 0x42)) continue; assignid_map |= m; } - outb(0x7f, dev->ioport[0] + 0x02); - outb(0x02, dev->ioport[0] + 0x1b); + atp_writeb_io(dev, 0, 0x02, 0x7f); + atp_writeb_io(dev, 0, 0x1b, 0x02); outb(0, 0x80); val = 0x0080; /* bsy */ - outw(val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, val); val |= 0x0040; /* sel */ - outw(val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, val); val |= 0x0004; /* msg */ - outw(val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, val); inb(0x80); /* 2 deskew delay(45ns*2=90ns) */ val &= 0x007f; /* no bsy */ - outw(val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, val); mdelay(128); val &= 0x00fb; /* after 1ms no msg */ - outw(val, dev->ioport[0] + 0x1c); - while ((inb(dev->ioport[0] + 0x1c) & 0x04) != 0) + atp_writew_io(dev, 0, 0x1c, val); + while ((atp_readb_io(dev, 0, 0x1c) & 0x04) != 0) ; outb(1, 0x80); udelay(100); for (n = 0; n < 0x30000; n++) - if ((inb(dev->ioport[0] + 0x1c) & 0x80) != 0) /* bsy ? */ + if ((atp_readb_io(dev, 0, 0x1c) & 0x80) != 0) /* bsy ? */ break; if (n < 0x30000) for (n = 0; n < 0x30000; n++) - if ((inb(dev->ioport[0] + 0x1c) & 0x81) == 0x0081) { + if ((atp_readb_io(dev, 0, 0x1c) & 0x81) == 0x0081) { inb(0x80); val |= 0x8003; /* io,cd,db7 */ - outw(val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, val); inb(0x80); val &= 0x00bf; /* no sel */ - outw(val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, val); outb(2, 0x80); break; } @@ -1033,14 +1065,14 @@ static void tscam(struct Scsi_Host *host) */ mdelay(2); udelay(48); - if ((inb(dev->ioport[0] + 0x1c) & 0x80) == 0x00) { /* bsy ? */ - outw(0, dev->ioport[0] + 0x1c); - outb(0, dev->ioport[0] + 0x1b); - outb(0, dev->ioport[0] + 0x15); - outb(0x09, dev->ioport[0] + 0x18); - while ((inb(dev->ioport[0] + 0x1f) & 0x80) == 0) + if ((atp_readb_io(dev, 0, 0x1c) & 0x80) == 0x00) { /* bsy ? */ + atp_writew_io(dev, 0, 0x1c, 0); + atp_writeb_io(dev, 0, 0x1b, 0); + atp_writeb_io(dev, 0, 0x15, 0); + atp_writeb_io(dev, 0, 0x18, 0x09); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) cpu_relax(); - inb(dev->ioport[0] + 0x17); + atp_readb_io(dev, 0, 0x17); return; } val &= 0x00ff; /* synchronization */ @@ -1055,7 +1087,7 @@ static void tscam(struct Scsi_Host *host) j = 0; while (1) { - if ((inw(dev->ioport[0] + 0x1c) & 0x2000) == 0) + if ((atp_readw_io(dev, 0, 0x1c) & 0x2000) == 0) continue; outb(5, 0x80); val &= 0x00ff; /* get ID_STRING */ @@ -2232,6 +2264,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } base_io = pci_resource_start(pdev, 0); base_io &= 0xfffffff8; + atpdev->baseport = base_io; if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { atpdev->chip_ver = pdev->revision; @@ -2356,7 +2389,6 @@ flash_ok_880: atpdev->pdev = pdev; atpdev->dev_id = ent->device; - atpdev->baseport = base_io; atpdev->ioport[0] = base_io + 0x80; atpdev->ioport[1] = base_io + 0xc0; atpdev->pciport[0] = base_io + 0x40; @@ -2651,12 +2683,12 @@ static int atp870u_abort(struct scsi_cmnd * SCpnt) printk("working=%x last_cmd=%x ", dev->working[c], dev->last_cmd[c]); printk(" quhdu=%x quendu=%x ", dev->quhd[c], dev->quend[c]); for (j = 0; j < 0x18; j++) { - printk(" r%2x=%2x", j, inb(dev->ioport[c] + j)); + printk(" r%2x=%2x", j, atp_readb_io(dev, c, j)); } - printk(" r1c=%2x", inb(dev->ioport[c] + 0x1c)); - printk(" r1f=%2x in_snd=%2x ", inb(dev->ioport[c] + 0x1f), dev->in_snd[c]); - printk(" d00=%2x", inb(dev->pciport[c])); - printk(" d02=%2x", inb(dev->pciport[c] + 0x02)); + printk(" r1c=%2x", atp_readb_io(dev, c, 0x1c)); + printk(" r1f=%2x in_snd=%2x ", atp_readb_io(dev, c, 0x1f), dev->in_snd[c]); + printk(" d00=%2x", atp_readb_pci(dev, c, 0x00)); + printk(" d02=%2x", atp_readb_pci(dev, c, 0x02)); for(j=0;j<16;j++) { if (dev->id[c][j].curr_req != NULL) { workrequ = dev->id[c][j].curr_req; -- GitLab From 152c3ac5e18057dbec396db83c76fccfa44aa258 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:55 +0100 Subject: [PATCH 0620/2855] atp870u: Convert is870() to use wrappers Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 276 ++++++++++++++++++++--------------------- 1 file changed, 138 insertions(+), 138 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 07b50acf6b921..305eda807e115 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1162,7 +1162,7 @@ static void tscam(struct Scsi_Host *host) } } -static void is870(struct atp_unit *dev, unsigned int wkport) +static void is870(struct atp_unit *dev) { unsigned char i, j, k, rmb, n; unsigned short int m; @@ -1174,7 +1174,7 @@ static void is870(struct atp_unit *dev, unsigned int wkport) static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 }; static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; - outb((unsigned char) (inb(wkport + 0x3a) | 0x10), wkport + 0x3a); + atp_writeb_io(dev, 0, 0x3a, atp_readb_io(dev, 0, 0x3a) | 0x10); for (i = 0; i < 16; i++) { if ((dev->chip_ver != 4) && (i > 7)) { @@ -1190,104 +1190,104 @@ static void is870(struct atp_unit *dev, unsigned int wkport) continue; } if (dev->chip_ver == 4) { - outb(0x01, wkport + 0x1b); + atp_writeb_io(dev, 0, 0x1b, 0x01); } else { - outb(0x00, wkport + 0x1b); - } - outb(0x08, wkport + 1); - outb(0x7f, wkport + 2); - outb(satn[0], wkport + 3); - outb(satn[1], wkport + 4); - outb(satn[2], wkport + 5); - outb(satn[3], wkport + 6); - outb(satn[4], wkport + 7); - outb(satn[5], wkport + 8); - outb(0, wkport + 0x0f); - outb(dev->id[0][i].devsp, wkport + 0x11); - outb(0, wkport + 0x12); - outb(satn[6], wkport + 0x13); - outb(satn[7], wkport + 0x14); + atp_writeb_io(dev, 0, 0x1b, 0x00); + } + atp_writeb_io(dev, 0, 1, 0x08); + atp_writeb_io(dev, 0, 2, 0x7f); + atp_writeb_io(dev, 0, 3, satn[0]); + atp_writeb_io(dev, 0, 4, satn[1]); + atp_writeb_io(dev, 0, 5, satn[2]); + atp_writeb_io(dev, 0, 6, satn[3]); + atp_writeb_io(dev, 0, 7, satn[4]); + atp_writeb_io(dev, 0, 8, satn[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, satn[6]); + atp_writeb_io(dev, 0, 0x14, satn[7]); j = i; if ((j & 0x08) != 0) { j = (j & 0x07) | 0x40; } - outb(j, wkport + 0x15); - outb(satn[8], wkport + 0x18); + atp_writeb_io(dev, 0, 0x15, j); + atp_writeb_io(dev, 0, 0x18, satn[8]); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e) + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); dev->active_id[0] |= m; - outb(0x30, wkport + 0x10); - outb(0x00, wkport + 0x04); + atp_writeb_io(dev, 0, 0x10, 0x30); + atp_writeb_io(dev, 0, 0x04, 0x00); phase_cmd: - outb(0x08, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, 0, 0x18, 0x08); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17); + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { - outb(0x41, wkport + 0x10); + atp_writeb_io(dev, 0, 0x10, 0x41); goto phase_cmd; } sel_ok: - outb(inqd[0], wkport + 3); - outb(inqd[1], wkport + 4); - outb(inqd[2], wkport + 5); - outb(inqd[3], wkport + 6); - outb(inqd[4], wkport + 7); - outb(inqd[5], wkport + 8); - outb(0, wkport + 0x0f); - outb(dev->id[0][i].devsp, wkport + 0x11); - outb(0, wkport + 0x12); - outb(inqd[6], wkport + 0x13); - outb(inqd[7], wkport + 0x14); - outb(inqd[8], wkport + 0x18); + atp_writeb_io(dev, 0, 3, inqd[0]); + atp_writeb_io(dev, 0, 4, inqd[1]); + atp_writeb_io(dev, 0, 5, inqd[2]); + atp_writeb_io(dev, 0, 6, inqd[3]); + atp_writeb_io(dev, 0, 7, inqd[4]); + atp_writeb_io(dev, 0, 8, inqd[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, inqd[6]); + atp_writeb_io(dev, 0, 0x14, inqd[7]); + atp_writeb_io(dev, 0, 0x18, inqd[8]); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e) + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); if (dev->chip_ver == 4) - outb(0x00, wkport + 0x1b); + atp_writeb_io(dev, 0, 0x1b, 0x00); - outb(0x08, wkport + 0x18); + atp_writeb_io(dev, 0, 0x18, 0x08); j = 0; rd_inq_data: - k = inb(wkport + 0x1f); + k = atp_readb_io(dev, 0, 0x1f); if ((k & 0x01) != 0) { - mbuf[j++] = inb(wkport + 0x19); + mbuf[j++] = atp_readb_io(dev, 0, 0x19); goto rd_inq_data; } if ((k & 0x80) == 0) { goto rd_inq_data; } - j = inb(wkport + 0x17); + j = atp_readb_io(dev, 0, 0x17); if (j == 0x16) { goto inq_ok; } - outb(0x46, wkport + 0x10); - outb(0, wkport + 0x12); - outb(0, wkport + 0x13); - outb(0, wkport + 0x14); - outb(0x08, wkport + 0x18); + atp_writeb_io(dev, 0, 0x10, 0x46); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, 0); + atp_writeb_io(dev, 0, 0x14, 0); + atp_writeb_io(dev, 0, 0x18, 0x08); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x17) != 0x16) { + if (atp_readb_io(dev, 0, 0x17) != 0x16) { goto sel_ok; } inq_ok: @@ -1305,43 +1305,43 @@ inq_ok: if ((dev->global_map[0] & 0x20) == 0) { goto not_wide; } - outb(0x01, wkport + 0x1b); - outb(satn[0], wkport + 3); - outb(satn[1], wkport + 4); - outb(satn[2], wkport + 5); - outb(satn[3], wkport + 6); - outb(satn[4], wkport + 7); - outb(satn[5], wkport + 8); - outb(0, wkport + 0x0f); - outb(dev->id[0][i].devsp, wkport + 0x11); - outb(0, wkport + 0x12); - outb(satn[6], wkport + 0x13); - outb(satn[7], wkport + 0x14); - outb(satn[8], wkport + 0x18); + atp_writeb_io(dev, 0, 0x1b, 0x01); + atp_writeb_io(dev, 0, 3, satn[0]); + atp_writeb_io(dev, 0, 4, satn[1]); + atp_writeb_io(dev, 0, 5, satn[2]); + atp_writeb_io(dev, 0, 6, satn[3]); + atp_writeb_io(dev, 0, 7, satn[4]); + atp_writeb_io(dev, 0, 8, satn[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, satn[6]); + atp_writeb_io(dev, 0, 0x14, satn[7]); + atp_writeb_io(dev, 0, 0x18, satn[8]); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e) + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); try_wide: j = 0; - outb(0x05, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, 0, 0x14, 0x05); + atp_writeb_io(dev, 0, 0x18, 0x20); - while ((inb(wkport + 0x1f) & 0x80) == 0) { - if ((inb(wkport + 0x1f) & 0x01) != 0) - outb(wide[j++], wkport + 0x19); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, 0, 0x19, wide[j++]); } - while ((inb(wkport + 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1353,12 +1353,12 @@ try_wide: } continue; widep_out: - outb(0x20, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0) { - if ((inb(wkport + 0x1f) & 0x01) != 0) - outb(0, wkport + 0x19); + atp_writeb_io(dev, 0, 0x18, 0x20); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, 0, 0x19, 0); } - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1370,19 +1370,19 @@ widep_out: } continue; widep_in: - outb(0xff, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, 0, 0x14, 0xff); + atp_writeb_io(dev, 0, 0x18, 0x20); k = 0; widep_in1: - j = inb(wkport + 0x1f); + j = atp_readb_io(dev, 0, 0x1f); if ((j & 0x01) != 0) { - mbuf[k++] = inb(wkport + 0x19); + mbuf[k++] = atp_readb_io(dev, 0, 0x19); goto widep_in1; } if ((j & 0x80) == 0x00) { goto widep_in1; } - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1394,14 +1394,14 @@ widep_in1: } continue; widep_cmd: - outb(0x30, wkport + 0x10); - outb(0x00, wkport + 0x14); - outb(0x08, wkport + 0x18); - - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, 0, 0x10, 0x30); + atp_writeb_io(dev, 0, 0x14, 0x00); + atp_writeb_io(dev, 0, 0x18, 0x08); + + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17); + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { if (j == 0x4e) { goto widep_out; @@ -1433,52 +1433,52 @@ set_sync: if ((m & dev->wide_id[0]) != 0) { j |= 0x01; } - outb(j, wkport + 0x1b); - outb(satn[0], wkport + 3); - outb(satn[1], wkport + 4); - outb(satn[2], wkport + 5); - outb(satn[3], wkport + 6); - outb(satn[4], wkport + 7); - outb(satn[5], wkport + 8); - outb(0, wkport + 0x0f); - outb(dev->id[0][i].devsp, wkport + 0x11); - outb(0, wkport + 0x12); - outb(satn[6], wkport + 0x13); - outb(satn[7], wkport + 0x14); - outb(satn[8], wkport + 0x18); + atp_writeb_io(dev, 0, 0x1b, j); + atp_writeb_io(dev, 0, 3, satn[0]); + atp_writeb_io(dev, 0, 4, satn[1]); + atp_writeb_io(dev, 0, 5, satn[2]); + atp_writeb_io(dev, 0, 6, satn[3]); + atp_writeb_io(dev, 0, 7, satn[4]); + atp_writeb_io(dev, 0, 8, satn[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, satn[6]); + atp_writeb_io(dev, 0, 0x14, satn[7]); + atp_writeb_io(dev, 0, 0x18, satn[8]); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e) + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); try_sync: j = 0; - outb(0x06, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, 0, 0x14, 0x06); + atp_writeb_io(dev, 0, 0x18, 0x20); - while ((inb(wkport + 0x1f) & 0x80) == 0) { - if ((inb(wkport + 0x1f) & 0x01) != 0) { + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) { if ((m & dev->wide_id[0]) != 0) { - outb(synw[j++], wkport + 0x19); + atp_writeb_io(dev, 0, 0x19, synw[j++]); } else { if ((m & dev->ultra_map[0]) != 0) { - outb(synu[j++], wkport + 0x19); + atp_writeb_io(dev, 0, 0x19, synu[j++]); } else { - outb(synn[j++], wkport + 0x19); + atp_writeb_io(dev, 0, 0x19, synn[j++]); } } } } - while ((inb(wkport + 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; } @@ -1490,12 +1490,12 @@ try_sync: } continue; phase_outs: - outb(0x20, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) { - if ((inb(wkport + 0x1f) & 0x01) != 0x00) - outb(0x00, wkport + 0x19); + atp_writeb_io(dev, 0, 0x18, 0x20); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0x00) + atp_writeb_io(dev, 0, 0x19, 0x00); } - j = inb(wkport + 0x17); + j = atp_readb_io(dev, 0, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -1511,23 +1511,23 @@ phase_outs: } continue; phase_ins: - outb(0xff, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, 0, 0x14, 0xff); + atp_writeb_io(dev, 0, 0x18, 0x20); k = 0; phase_ins1: - j = inb(wkport + 0x1f); + j = atp_readb_io(dev, 0, 0x1f); if ((j & 0x01) != 0x00) { - mbuf[k++] = inb(wkport + 0x19); + mbuf[k++] = atp_readb_io(dev, 0, 0x19); goto phase_ins1; } if ((j & 0x80) == 0x00) { goto phase_ins1; } - while ((inb(wkport + 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17); + j = atp_readb_io(dev, 0, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -1543,15 +1543,15 @@ phase_ins1: } continue; phase_cmds: - outb(0x30, wkport + 0x10); + atp_writeb_io(dev, 0, 0x10, 0x30); tar_dcons: - outb(0x00, wkport + 0x14); - outb(0x08, wkport + 0x18); + atp_writeb_io(dev, 0, 0x14, 0x00); + atp_writeb_io(dev, 0, 0x18, 0x08); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17); + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { continue; } @@ -1591,7 +1591,7 @@ tar_dcons: set_syn_ok: dev->id[0][i].devsp = (dev->id[0][i].devsp & 0x0f) | j; } - outb((unsigned char) (inb(wkport + 0x3a) & 0xef), wkport + 0x3a); + atp_writeb_io(dev, 0, 0x3a, atp_readb_io(dev, 0, 0x3a) & 0xef); } static void is880(struct atp_unit *dev, unsigned int wkport) @@ -2605,7 +2605,7 @@ flash_ok_885: outb(0x20, base_io + 0x11); tscam(shpnt); - is870(p, base_io); + is870(p); outb((inb(base_io + 0x3a) & 0xef), base_io + 0x3a); outb((inb(base_io + 0x3b) | 0x20), base_io + 0x3b); if (atpdev->chip_ver == 4) -- GitLab From 485025606b5bbd1024c9b2781fb8909afbd1a64d Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:56 +0100 Subject: [PATCH 0621/2855] atp870u: Convert is880() to use wrappers Subtract 0x40 to use _io access wrappers. Now it's obvious that is870() and is880() are very similar. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 352 ++++++++++++++++++++--------------------- 1 file changed, 176 insertions(+), 176 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 305eda807e115..1b9276f618508 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1594,7 +1594,7 @@ set_syn_ok: atp_writeb_io(dev, 0, 0x3a, atp_readb_io(dev, 0, 0x3a) & 0xef); } -static void is880(struct atp_unit *dev, unsigned int wkport) +static void is880(struct atp_unit *dev) { unsigned char i, j, k, rmb, n, lvdmode; unsigned short int m; @@ -1608,7 +1608,7 @@ static void is880(struct atp_unit *dev, unsigned int wkport) static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 }; - lvdmode = inb(wkport + 0x3f) & 0x40; + lvdmode = atp_readb_base(dev, 0x3f) & 0x40; for (i = 0; i < 16; i++) { m = 1; @@ -1620,100 +1620,100 @@ static void is880(struct atp_unit *dev, unsigned int wkport) printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[0]); continue; } - outb(0x01, wkport + 0x5b); - outb(0x08, wkport + 0x41); - outb(0x7f, wkport + 0x42); - outb(satn[0], wkport + 0x43); - outb(satn[1], wkport + 0x44); - outb(satn[2], wkport + 0x45); - outb(satn[3], wkport + 0x46); - outb(satn[4], wkport + 0x47); - outb(satn[5], wkport + 0x48); - outb(0, wkport + 0x4f); - outb(dev->id[0][i].devsp, wkport + 0x51); - outb(0, wkport + 0x52); - outb(satn[6], wkport + 0x53); - outb(satn[7], wkport + 0x54); + atp_writeb_io(dev, 0, 0x1b, 0x01); + atp_writeb_io(dev, 0, 1, 0x08); + atp_writeb_io(dev, 0, 2, 0x7f); + atp_writeb_io(dev, 0, 3, satn[0]); + atp_writeb_io(dev, 0, 4, satn[1]); + atp_writeb_io(dev, 0, 5, satn[2]); + atp_writeb_io(dev, 0, 6, satn[3]); + atp_writeb_io(dev, 0, 7, satn[4]); + atp_writeb_io(dev, 0, 8, satn[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, satn[6]); + atp_writeb_io(dev, 0, 0x14, satn[7]); j = i; if ((j & 0x08) != 0) { j = (j & 0x07) | 0x40; } - outb(j, wkport + 0x55); - outb(satn[8], wkport + 0x58); + atp_writeb_io(dev, 0, 0x15, j); + atp_writeb_io(dev, 0, 0x18, satn[8]); - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e) + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - while (inb(wkport + 0x57) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); dev->active_id[0] |= m; - outb(0x30, wkport + 0x50); - outb(0x00, wkport + 0x54); + atp_writeb_io(dev, 0, 0x10, 0x30); + atp_writeb_io(dev, 0, 0x14, 0x00); phase_cmd: - outb(0x08, wkport + 0x58); + atp_writeb_io(dev, 0, 0x18, 0x08); - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x57); + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { - outb(0x41, wkport + 0x50); + atp_writeb_io(dev, 0, 0x10, 0x41); goto phase_cmd; } sel_ok: - outb(inqd[0], wkport + 0x43); - outb(inqd[1], wkport + 0x44); - outb(inqd[2], wkport + 0x45); - outb(inqd[3], wkport + 0x46); - outb(inqd[4], wkport + 0x47); - outb(inqd[5], wkport + 0x48); - outb(0, wkport + 0x4f); - outb(dev->id[0][i].devsp, wkport + 0x51); - outb(0, wkport + 0x52); - outb(inqd[6], wkport + 0x53); - outb(inqd[7], wkport + 0x54); - outb(inqd[8], wkport + 0x58); + atp_writeb_io(dev, 0, 3, inqd[0]); + atp_writeb_io(dev, 0, 4, inqd[1]); + atp_writeb_io(dev, 0, 5, inqd[2]); + atp_writeb_io(dev, 0, 6, inqd[3]); + atp_writeb_io(dev, 0, 7, inqd[4]); + atp_writeb_io(dev, 0, 8, inqd[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, inqd[6]); + atp_writeb_io(dev, 0, 0x14, inqd[7]); + atp_writeb_io(dev, 0, 0x18, inqd[8]); - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e) + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - while (inb(wkport + 0x57) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); - outb(0x00, wkport + 0x5b); - outb(0x08, wkport + 0x58); + atp_writeb_io(dev, 0, 0x1b, 0x00); + atp_writeb_io(dev, 0, 0x18, 0x08); j = 0; rd_inq_data: - k = inb(wkport + 0x5f); + k = atp_readb_io(dev, 0, 0x1f); if ((k & 0x01) != 0) { - mbuf[j++] = inb(wkport + 0x59); + mbuf[j++] = atp_readb_io(dev, 0, 0x19); goto rd_inq_data; } if ((k & 0x80) == 0) { goto rd_inq_data; } - j = inb(wkport + 0x57); + j = atp_readb_io(dev, 0, 0x17); if (j == 0x16) { goto inq_ok; } - outb(0x46, wkport + 0x50); - outb(0, wkport + 0x52); - outb(0, wkport + 0x53); - outb(0, wkport + 0x54); - outb(0x08, wkport + 0x58); - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + atp_writeb_io(dev, 0, 0x10, 0x46); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, 0); + atp_writeb_io(dev, 0, 0x14, 0); + atp_writeb_io(dev, 0, 0x18, 0x08); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x57) != 0x16) + if (atp_readb_io(dev, 0, 0x17) != 0x16) goto sel_ok; inq_ok: @@ -1736,43 +1736,43 @@ inq_ok: goto chg_wide; } - outb(0x01, wkport + 0x5b); - outb(satn[0], wkport + 0x43); - outb(satn[1], wkport + 0x44); - outb(satn[2], wkport + 0x45); - outb(satn[3], wkport + 0x46); - outb(satn[4], wkport + 0x47); - outb(satn[5], wkport + 0x48); - outb(0, wkport + 0x4f); - outb(dev->id[0][i].devsp, wkport + 0x51); - outb(0, wkport + 0x52); - outb(satn[6], wkport + 0x53); - outb(satn[7], wkport + 0x54); - outb(satn[8], wkport + 0x58); - - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + atp_writeb_io(dev, 0, 0x1b, 0x01); + atp_writeb_io(dev, 0, 3, satn[0]); + atp_writeb_io(dev, 0, 4, satn[1]); + atp_writeb_io(dev, 0, 5, satn[2]); + atp_writeb_io(dev, 0, 6, satn[3]); + atp_writeb_io(dev, 0, 7, satn[4]); + atp_writeb_io(dev, 0, 8, satn[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, satn[6]); + atp_writeb_io(dev, 0, 0x14, satn[7]); + atp_writeb_io(dev, 0, 0x18, satn[8]); + + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e) + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - while (inb(wkport + 0x57) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); try_u3: j = 0; - outb(0x09, wkport + 0x54); - outb(0x20, wkport + 0x58); + atp_writeb_io(dev, 0, 0x14, 0x09); + atp_writeb_io(dev, 0, 0x18, 0x20); - while ((inb(wkport + 0x5f) & 0x80) == 0) { - if ((inb(wkport + 0x5f) & 0x01) != 0) - outb(u3[j++], wkport + 0x59); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, 0, 0x19, u3[j++]); } - while ((inb(wkport + 0x57) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x57) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1784,12 +1784,12 @@ try_u3: } continue; u3p_out: - outb(0x20, wkport + 0x58); - while ((inb(wkport + 0x5f) & 0x80) == 0) { - if ((inb(wkport + 0x5f) & 0x01) != 0) - outb(0, wkport + 0x59); + atp_writeb_io(dev, 0, 0x18, 0x20); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, 0, 0x19, 0); } - j = inb(wkport + 0x57) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1801,19 +1801,19 @@ u3p_out: } continue; u3p_in: - outb(0x09, wkport + 0x54); - outb(0x20, wkport + 0x58); + atp_writeb_io(dev, 0, 0x14, 0x09); + atp_writeb_io(dev, 0, 0x18, 0x20); k = 0; u3p_in1: - j = inb(wkport + 0x5f); + j = atp_readb_io(dev, 0, 0x1f); if ((j & 0x01) != 0) { - mbuf[k++] = inb(wkport + 0x59); + mbuf[k++] = atp_readb_io(dev, 0, 0x19); goto u3p_in1; } if ((j & 0x80) == 0x00) { goto u3p_in1; } - j = inb(wkport + 0x57) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1825,14 +1825,14 @@ u3p_in1: } continue; u3p_cmd: - outb(0x30, wkport + 0x50); - outb(0x00, wkport + 0x54); - outb(0x08, wkport + 0x58); + atp_writeb_io(dev, 0, 0x10, 0x30); + atp_writeb_io(dev, 0, 0x14, 0x00); + atp_writeb_io(dev, 0, 0x18, 0x08); - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x57); + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { if (j == 0x4e) { goto u3p_out; @@ -1856,42 +1856,42 @@ u3p_cmd: continue; } chg_wide: - outb(0x01, wkport + 0x5b); - outb(satn[0], wkport + 0x43); - outb(satn[1], wkport + 0x44); - outb(satn[2], wkport + 0x45); - outb(satn[3], wkport + 0x46); - outb(satn[4], wkport + 0x47); - outb(satn[5], wkport + 0x48); - outb(0, wkport + 0x4f); - outb(dev->id[0][i].devsp, wkport + 0x51); - outb(0, wkport + 0x52); - outb(satn[6], wkport + 0x53); - outb(satn[7], wkport + 0x54); - outb(satn[8], wkport + 0x58); - - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + atp_writeb_io(dev, 0, 0x1b, 0x01); + atp_writeb_io(dev, 0, 3, satn[0]); + atp_writeb_io(dev, 0, 4, satn[1]); + atp_writeb_io(dev, 0, 5, satn[2]); + atp_writeb_io(dev, 0, 6, satn[3]); + atp_writeb_io(dev, 0, 7, satn[4]); + atp_writeb_io(dev, 0, 8, satn[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, satn[6]); + atp_writeb_io(dev, 0, 0x14, satn[7]); + atp_writeb_io(dev, 0, 0x18, satn[8]); + + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e) + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - while (inb(wkport + 0x57) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); try_wide: j = 0; - outb(0x05, wkport + 0x54); - outb(0x20, wkport + 0x58); + atp_writeb_io(dev, 0, 0x14, 0x05); + atp_writeb_io(dev, 0, 0x18, 0x20); - while ((inb(wkport + 0x5f) & 0x80) == 0) { - if ((inb(wkport + 0x5f) & 0x01) != 0) - outb(wide[j++], wkport + 0x59); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, 0, 0x19, wide[j++]); } - while ((inb(wkport + 0x57) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x57) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1903,12 +1903,12 @@ try_wide: } continue; widep_out: - outb(0x20, wkport + 0x58); - while ((inb(wkport + 0x5f) & 0x80) == 0) { - if ((inb(wkport + 0x5f) & 0x01) != 0) - outb(0, wkport + 0x59); + atp_writeb_io(dev, 0, 0x18, 0x20); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, 0, 0x19, 0); } - j = inb(wkport + 0x57) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1920,19 +1920,19 @@ widep_out: } continue; widep_in: - outb(0xff, wkport + 0x54); - outb(0x20, wkport + 0x58); + atp_writeb_io(dev, 0, 0x14, 0xff); + atp_writeb_io(dev, 0, 0x18, 0x20); k = 0; widep_in1: - j = inb(wkport + 0x5f); + j = atp_readb_io(dev, 0, 0x1f); if ((j & 0x01) != 0) { - mbuf[k++] = inb(wkport + 0x59); + mbuf[k++] = atp_readb_io(dev, 0, 0x19); goto widep_in1; } if ((j & 0x80) == 0x00) { goto widep_in1; } - j = inb(wkport + 0x57) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1944,14 +1944,14 @@ widep_in1: } continue; widep_cmd: - outb(0x30, wkport + 0x50); - outb(0x00, wkport + 0x54); - outb(0x08, wkport + 0x58); + atp_writeb_io(dev, 0, 0x10, 0x30); + atp_writeb_io(dev, 0, 0x14, 0x00); + atp_writeb_io(dev, 0, 0x18, 0x08); - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x57); + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { if (j == 0x4e) { goto widep_out; @@ -1996,56 +1996,56 @@ set_sync: if ((m & dev->wide_id[0]) != 0) { j |= 0x01; } - outb(j, wkport + 0x5b); - outb(satn[0], wkport + 0x43); - outb(satn[1], wkport + 0x44); - outb(satn[2], wkport + 0x45); - outb(satn[3], wkport + 0x46); - outb(satn[4], wkport + 0x47); - outb(satn[5], wkport + 0x48); - outb(0, wkport + 0x4f); - outb(dev->id[0][i].devsp, wkport + 0x51); - outb(0, wkport + 0x52); - outb(satn[6], wkport + 0x53); - outb(satn[7], wkport + 0x54); - outb(satn[8], wkport + 0x58); - - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + atp_writeb_io(dev, 0, 0x1b, j); + atp_writeb_io(dev, 0, 3, satn[0]); + atp_writeb_io(dev, 0, 4, satn[1]); + atp_writeb_io(dev, 0, 5, satn[2]); + atp_writeb_io(dev, 0, 6, satn[3]); + atp_writeb_io(dev, 0, 7, satn[4]); + atp_writeb_io(dev, 0, 8, satn[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, satn[6]); + atp_writeb_io(dev, 0, 0x14, satn[7]); + atp_writeb_io(dev, 0, 0x18, satn[8]); + + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((inb(wkport + 0x57) != 0x11) && (inb(wkport + 0x57) != 0x8e)) { + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) { continue; } - while (inb(wkport + 0x57) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); try_sync: j = 0; - outb(0x06, wkport + 0x54); - outb(0x20, wkport + 0x58); + atp_writeb_io(dev, 0, 0x14, 0x06); + atp_writeb_io(dev, 0, 0x18, 0x20); - while ((inb(wkport + 0x5f) & 0x80) == 0) { - if ((inb(wkport + 0x5f) & 0x01) != 0) { + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) { if ((m & dev->wide_id[0]) != 0) { if ((m & dev->ultra_map[0]) != 0) { - outb(synuw[j++], wkport + 0x59); + atp_writeb_io(dev, 0, 0x19, synuw[j++]); } else { - outb(synw[j++], wkport + 0x59); + atp_writeb_io(dev, 0, 0x19, synw[j++]); } } else { if ((m & dev->ultra_map[0]) != 0) { - outb(synu[j++], wkport + 0x59); + atp_writeb_io(dev, 0, 0x19, synu[j++]); } else { - outb(synn[j++], wkport + 0x59); + atp_writeb_io(dev, 0, 0x19, synn[j++]); } } } } - while ((inb(wkport + 0x57) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x57) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; } @@ -2057,12 +2057,12 @@ try_sync: } continue; phase_outs: - outb(0x20, wkport + 0x58); - while ((inb(wkport + 0x5f) & 0x80) == 0x00) { - if ((inb(wkport + 0x5f) & 0x01) != 0x00) - outb(0x00, wkport + 0x59); + atp_writeb_io(dev, 0, 0x18, 0x20); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0x00) + atp_writeb_io(dev, 0, 0x19, 0x00); } - j = inb(wkport + 0x57); + j = atp_readb_io(dev, 0, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -2078,23 +2078,23 @@ phase_outs: } continue; phase_ins: - outb(0x06, wkport + 0x54); - outb(0x20, wkport + 0x58); + atp_writeb_io(dev, 0, 0x14, 0x06); + atp_writeb_io(dev, 0, 0x18, 0x20); k = 0; phase_ins1: - j = inb(wkport + 0x5f); + j = atp_readb_io(dev, 0, 0x1f); if ((j & 0x01) != 0x00) { - mbuf[k++] = inb(wkport + 0x59); + mbuf[k++] = atp_readb_io(dev, 0, 0x19); goto phase_ins1; } if ((j & 0x80) == 0x00) { goto phase_ins1; } - while ((inb(wkport + 0x57) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x57); + j = atp_readb_io(dev, 0, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -2110,15 +2110,15 @@ phase_ins1: } continue; phase_cmds: - outb(0x30, wkport + 0x50); + atp_writeb_io(dev, 0, 0x10, 0x30); tar_dcons: - outb(0x00, wkport + 0x54); - outb(0x08, wkport + 0x58); + atp_writeb_io(dev, 0, 0x14, 0x00); + atp_writeb_io(dev, 0, 0x18, 0x08); - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x57); + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { continue; } @@ -2375,7 +2375,7 @@ flash_ok_880: outb(0x20, base_io + 0x51); tscam(shpnt); - is880(p, base_io); + is880(p); outb(0xb0, base_io + 0x38); shpnt->max_id = 16; shpnt->this_id = host_id; -- GitLab From 5d2a5a4f86616587a37e0c50dbef359d3078d9f5 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:57 +0100 Subject: [PATCH 0622/2855] atp870u: Convert is885() to use wrappers Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 358 ++++++++++++++++++++--------------------- 1 file changed, 179 insertions(+), 179 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 1b9276f618508..ad7af547fc90a 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -41,7 +41,7 @@ static struct scsi_host_template atp870u_template; static void send_s870(struct atp_unit *dev,unsigned char c); -static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c); +static void is885(struct atp_unit *dev, unsigned char c); static void tscam_885(void); static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val) @@ -2521,9 +2521,9 @@ flash_ok_885: tscam_885(); printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); - is885(p, base_io + 0x80, 0); + is885(p, 0); printk(KERN_INFO " Scanning Channel B SCSI Device ...\n"); - is885(p, base_io + 0xc0, 1); + is885(p, 1); k = inb(base_io + 0x28) & 0xcf; k |= 0xc0; @@ -2825,7 +2825,7 @@ static void tscam_885(void) -static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c) +static void is885(struct atp_unit *dev, unsigned char c) { unsigned char i, j, k, rmb, n, lvdmode; unsigned short int m; @@ -2839,7 +2839,7 @@ static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c) static unsigned char wide[6] = {0x80, 1, 2, 3, 1, 0}; static unsigned char u3[9] = { 0x80,1,6,4,0x09,00,0x0e,0x01,0x02 }; - lvdmode=inb(wkport + 0x1b) >> 7; + lvdmode=atp_readb_io(dev, c, 0x1b) >> 7; for (i = 0; i < 16; i++) { m = 1; @@ -2851,93 +2851,93 @@ static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c) printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); continue; } - outb(0x01, wkport + 0x1b); - outb(0x08, wkport + 0x01); - outb(0x7f, wkport + 0x02); - outb(satn[0], wkport + 0x03); - outb(satn[1], wkport + 0x04); - outb(satn[2], wkport + 0x05); - outb(satn[3], wkport + 0x06); - outb(satn[4], wkport + 0x07); - outb(satn[5], wkport + 0x08); - outb(0, wkport + 0x0f); - outb(dev->id[c][i].devsp, wkport + 0x11); + atp_writeb_io(dev, c, 0x1b, 0x01); + atp_writeb_io(dev, c, 1, 0x08); + atp_writeb_io(dev, c, 2, 0x7f); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - outb(0, wkport + 0x12); - outb(satn[6], wkport + 0x13); - outb(satn[7], wkport + 0x14); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); j = i; if ((j & 0x08) != 0) { j = (j & 0x07) | 0x40; } - outb(j, wkport + 0x15); - outb(satn[8], wkport + 0x18); + atp_writeb_io(dev, c, 0x15, j); + atp_writeb_io(dev, c, 0x18, satn[8]); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { + if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { continue; } - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); dev->active_id[c] |= m; - outb(0x30, wkport + 0x10); - outb(0x00, wkport + 0x14); + atp_writeb_io(dev, c, 0x10, 0x30); + atp_writeb_io(dev, c, 0x14, 0x00); phase_cmd: - outb(0x08, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { - outb(0x41, wkport + 0x10); + atp_writeb_io(dev, c, 0x10, 0x41); goto phase_cmd; } sel_ok: - outb(inqd[0], wkport + 0x03); - outb(inqd[1], wkport + 0x04); - outb(inqd[2], wkport + 0x05); - outb(inqd[3], wkport + 0x06); - outb(inqd[4], wkport + 0x07); - outb(inqd[5], wkport + 0x08); - outb(0, wkport + 0x0f); - outb(dev->id[c][i].devsp, wkport + 0x11); - outb(0, wkport + 0x12); - outb(inqd[6], wkport + 0x13); - outb(inqd[7], wkport + 0x14); - outb(inqd[8], wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, c, 3, inqd[0]); + atp_writeb_io(dev, c, 4, inqd[1]); + atp_writeb_io(dev, c, 5, inqd[2]); + atp_writeb_io(dev, c, 6, inqd[3]); + atp_writeb_io(dev, c, 7, inqd[4]); + atp_writeb_io(dev, c, 8, inqd[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, inqd[6]); + atp_writeb_io(dev, c, 0x14, inqd[7]); + atp_writeb_io(dev, c, 0x18, inqd[8]); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { + if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { continue; } - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); - outb(0x00, wkport + 0x1b); - outb(0x08, wkport + 0x18); + atp_writeb_io(dev, c, 0x1b, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); j = 0; rd_inq_data: - k = inb(wkport + 0x1f); + k = atp_readb_io(dev, c, 0x1f); if ((k & 0x01) != 0) { - mbuf[j++] = inb(wkport + 0x19); + mbuf[j++] = atp_readb_io(dev, c, 0x19); goto rd_inq_data; } if ((k & 0x80) == 0) { goto rd_inq_data; } - j = inb(wkport + 0x17); + j = atp_readb_io(dev, c, 0x17); if (j == 0x16) { goto inq_ok; } - outb(0x46, wkport + 0x10); - outb(0, wkport + 0x12); - outb(0, wkport + 0x13); - outb(0, wkport + 0x14); - outb(0x08, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, c, 0x10, 0x46); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, 0); + atp_writeb_io(dev, c, 0x14, 0); + atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x17) != 0x16) { + if (atp_readb_io(dev, c, 0x17) != 0x16) { goto sel_ok; } inq_ok: @@ -2959,40 +2959,40 @@ inq_ok: goto chg_wide; } - outb(0x01, wkport + 0x1b); - outb(satn[0], wkport + 0x03); - outb(satn[1], wkport + 0x04); - outb(satn[2], wkport + 0x05); - outb(satn[3], wkport + 0x06); - outb(satn[4], wkport + 0x07); - outb(satn[5], wkport + 0x08); - outb(0, wkport + 0x0f); - outb(dev->id[c][i].devsp, wkport + 0x11); - outb(0, wkport + 0x12); - outb(satn[6], wkport + 0x13); - outb(satn[7], wkport + 0x14); - outb(satn[8], wkport + 0x18); - - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, c, 0x1b, 0x01); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x18, satn[8]); + + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { + if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { continue; } - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); try_u3: j = 0; - outb(0x09, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, c, 0x14, 0x09); + atp_writeb_io(dev, c, 0x18, 0x20); - while ((inb(wkport + 0x1f) & 0x80) == 0) { - if ((inb(wkport + 0x1f) & 0x01) != 0) - outb(u3[j++], wkport + 0x19); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, u3[j++]); cpu_relax(); } - while ((inb(wkport + 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -3004,13 +3004,13 @@ try_u3: } continue; u3p_out: - outb(0x20, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0) { - if ((inb(wkport + 0x1f) & 0x01) != 0) - outb(0, wkport + 0x19); + atp_writeb_io(dev, c, 0x18, 0x20); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, 0); cpu_relax(); } - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -3022,19 +3022,19 @@ u3p_out: } continue; u3p_in: - outb(0x09, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, c, 0x14, 0x09); + atp_writeb_io(dev, c, 0x18, 0x20); k = 0; u3p_in1: - j = inb(wkport + 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x01) != 0) { - mbuf[k++] = inb(wkport + 0x19); + mbuf[k++] = atp_readb_io(dev, c, 0x19); goto u3p_in1; } if ((j & 0x80) == 0x00) { goto u3p_in1; } - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -3046,11 +3046,11 @@ u3p_in1: } continue; u3p_cmd: - outb(0x30, wkport + 0x10); - outb(0x00, wkport + 0x14); - outb(0x08, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00); - j = inb(wkport + 0x17); + atp_writeb_io(dev, c, 0x10, 0x30); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { if (j == 0x4e) { goto u3p_out; @@ -3077,40 +3077,40 @@ u3p_cmd: continue; } chg_wide: - outb(0x01, wkport + 0x1b); - outb(satn[0], wkport + 0x03); - outb(satn[1], wkport + 0x04); - outb(satn[2], wkport + 0x05); - outb(satn[3], wkport + 0x06); - outb(satn[4], wkport + 0x07); - outb(satn[5], wkport + 0x08); - outb(0, wkport + 0x0f); - outb(dev->id[c][i].devsp, wkport + 0x11); - outb(0, wkport + 0x12); - outb(satn[6], wkport + 0x13); - outb(satn[7], wkport + 0x14); - outb(satn[8], wkport + 0x18); - - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, c, 0x1b, 0x01); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x18, satn[8]); + + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { + if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { continue; } - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); try_wide: j = 0; - outb(0x05, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, c, 0x14, 0x05); + atp_writeb_io(dev, c, 0x18, 0x20); - while ((inb(wkport + 0x1f) & 0x80) == 0) { - if ((inb(wkport + 0x1f) & 0x01) != 0) - outb(wide[j++], wkport + 0x19); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, wide[j++]); cpu_relax(); } - while ((inb(wkport + 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -3122,13 +3122,13 @@ try_wide: } continue; widep_out: - outb(0x20, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0) { - if ((inb(wkport + 0x1f) & 0x01) != 0) - outb(0, wkport + 0x19); + atp_writeb_io(dev, c, 0x18, 0x20); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, 0); cpu_relax(); } - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -3140,19 +3140,19 @@ widep_out: } continue; widep_in: - outb(0xff, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, c, 0x14, 0xff); + atp_writeb_io(dev, c, 0x18, 0x20); k = 0; widep_in1: - j = inb(wkport + 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x01) != 0) { - mbuf[k++] = inb(wkport + 0x19); + mbuf[k++] = atp_readb_io(dev, c, 0x19); goto widep_in1; } if ((j & 0x80) == 0x00) { goto widep_in1; } - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -3164,12 +3164,12 @@ widep_in1: } continue; widep_cmd: - outb(0x30, wkport + 0x10); - outb(0x00, wkport + 0x14); - outb(0x08, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, c, 0x10, 0x30); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { if (j == 0x4e) { goto widep_out; @@ -3215,52 +3215,52 @@ set_sync: if ((m & dev->wide_id[c]) != 0) { j |= 0x01; } - outb(j, wkport + 0x1b); - outb(satn[0], wkport + 0x03); - outb(satn[1], wkport + 0x04); - outb(satn[2], wkport + 0x05); - outb(satn[3], wkport + 0x06); - outb(satn[4], wkport + 0x07); - outb(satn[5], wkport + 0x08); - outb(0, wkport + 0x0f); - outb(dev->id[c][i].devsp, wkport + 0x11); - outb(0, wkport + 0x12); - outb(satn[6], wkport + 0x13); - outb(satn[7], wkport + 0x14); - outb(satn[8], wkport + 0x18); - - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, c, 0x1b, j); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x18, satn[8]); + + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { + if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { continue; } - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); try_sync: j = 0; - outb(0x06, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, c, 0x14, 0x06); + atp_writeb_io(dev, c, 0x18, 0x20); - while ((inb(wkport + 0x1f) & 0x80) == 0) { - if ((inb(wkport + 0x1f) & 0x01) != 0) { + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) { if ((m & dev->wide_id[c]) != 0) { if ((m & dev->ultra_map[c]) != 0) { - outb(synuw[j++], wkport + 0x19); + atp_writeb_io(dev, c, 0x19, synuw[j++]); } else { - outb(synw[j++], wkport + 0x19); + atp_writeb_io(dev, c, 0x19, synw[j++]); } } else { if ((m & dev->ultra_map[c]) != 0) { - outb(synu[j++], wkport + 0x19); + atp_writeb_io(dev, c, 0x19, synu[j++]); } else { - outb(synn[j++], wkport + 0x19); + atp_writeb_io(dev, c, 0x19, synn[j++]); } } } } - while ((inb(wkport + 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; } @@ -3272,13 +3272,13 @@ try_sync: } continue; phase_outs: - outb(0x20, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) { - if ((inb(wkport + 0x1f) & 0x01) != 0x00) - outb(0x00, wkport + 0x19); + atp_writeb_io(dev, c, 0x18, 0x20); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0x00) + atp_writeb_io(dev, c, 0x19, 0x00); cpu_relax(); } - j = inb(wkport + 0x17); + j = atp_readb_io(dev, c, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -3294,20 +3294,20 @@ phase_outs: } continue; phase_ins: - outb(0x06, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, c, 0x14, 0x06); + atp_writeb_io(dev, c, 0x18, 0x20); k = 0; phase_ins1: - j = inb(wkport + 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x01) != 0x00) { - mbuf[k++] = inb(wkport + 0x19); + mbuf[k++] = atp_readb_io(dev, c, 0x19); goto phase_ins1; } if ((j & 0x80) == 0x00) { goto phase_ins1; } - while ((inb(wkport + 0x17) & 0x80) == 0x00); - j = inb(wkport + 0x17); + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00); + j = atp_readb_io(dev, c, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -3323,13 +3323,13 @@ phase_ins1: } continue; phase_cmds: - outb(0x30, wkport + 0x10); + atp_writeb_io(dev, c, 0x10, 0x30); tar_dcons: - outb(0x00, wkport + 0x14); - outb(0x08, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { continue; } @@ -3376,7 +3376,7 @@ tar_dcons: printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp); #endif } - outb(0x80, wkport + 0x16); + atp_writeb_io(dev, c, 0x16, 0x80); } module_init(atp870u_init); -- GitLab From 80b52a7f8d2d432e21ba1bd47212bc1aa93b3647 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:58 +0100 Subject: [PATCH 0623/2855] atp870u: Unify code format in is870(), is880() and is885() Unify code formatting in is870(), is880() and is885() functions to simplify comparing them. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 170 ++++++++++++++++++++++++----------------- 1 file changed, 101 insertions(+), 69 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index ad7af547fc90a..595c5c54af990 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1173,7 +1173,7 @@ static void is870(struct atp_unit *dev) static unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0c, 0x0e }; static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 }; static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; - + atp_writeb_io(dev, 0, 0x3a, atp_readb_io(dev, 0, 0x3a) | 0x10); for (i = 0; i < 16; i++) { @@ -1230,8 +1230,10 @@ static void is870(struct atp_unit *dev) phase_cmd: atp_writeb_io(dev, 0, 0x18, 0x08); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { atp_writeb_io(dev, 0, 0x10, 0x41); @@ -1253,13 +1255,13 @@ sel_ok: while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); - + if (dev->chip_ver == 4) atp_writeb_io(dev, 0, 0x1b, 0x00); @@ -1286,10 +1288,10 @@ rd_inq_data: while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - - if (atp_readb_io(dev, 0, 0x17) != 0x16) { + + if (atp_readb_io(dev, 0, 0x17) != 0x16) goto sel_ok; - } + inq_ok: mbuf[36] = 0; printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]); @@ -1321,13 +1323,13 @@ inq_ok: while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); - + try_wide: j = 0; atp_writeb_io(dev, 0, 0x14, 0x05); @@ -1337,10 +1339,10 @@ try_wide: if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) atp_writeb_io(dev, 0, 0x19, wide[j++]); } - + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; @@ -1449,13 +1451,13 @@ set_sync: while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); - + try_sync: j = 0; atp_writeb_io(dev, 0, 0x14, 0x06); @@ -1474,10 +1476,10 @@ try_sync: } } } - + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; @@ -1526,7 +1528,7 @@ phase_ins1: while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - + j = atp_readb_io(dev, 0, 0x17); if (j == 0x85) { goto tar_dcons; @@ -1547,10 +1549,10 @@ phase_cmds: tar_dcons: atp_writeb_io(dev, 0, 0x14, 0x00); atp_writeb_io(dev, 0, 0x18, 0x08); - + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { continue; @@ -1649,7 +1651,7 @@ static void is880(struct atp_unit *dev) while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); - + dev->active_id[0] |= m; atp_writeb_io(dev, 0, 0x10, 0x30); @@ -1657,7 +1659,7 @@ static void is880(struct atp_unit *dev) phase_cmd: atp_writeb_io(dev, 0, 0x18, 0x08); - + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); @@ -1679,16 +1681,16 @@ sel_ok: atp_writeb_io(dev, 0, 0x13, inqd[6]); atp_writeb_io(dev, 0, 0x14, inqd[7]); atp_writeb_io(dev, 0, 0x18, inqd[8]); - + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); - + atp_writeb_io(dev, 0, 0x1b, 0x00); atp_writeb_io(dev, 0, 0x18, 0x08); j = 0; @@ -1710,9 +1712,10 @@ rd_inq_data: atp_writeb_io(dev, 0, 0x13, 0); atp_writeb_io(dev, 0, 0x14, 0); atp_writeb_io(dev, 0, 0x18, 0x08); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - + if (atp_readb_io(dev, 0, 0x17) != 0x16) goto sel_ok; @@ -1771,7 +1774,7 @@ try_u3: while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; @@ -1828,10 +1831,10 @@ u3p_cmd: atp_writeb_io(dev, 0, 0x10, 0x30); atp_writeb_io(dev, 0, 0x14, 0x00); atp_writeb_io(dev, 0, 0x18, 0x08); - + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { if (j == 0x4e) { @@ -1872,13 +1875,13 @@ chg_wide: while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); - + try_wide: j = 0; atp_writeb_io(dev, 0, 0x14, 0x05); @@ -1888,9 +1891,10 @@ try_wide: if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) atp_writeb_io(dev, 0, 0x19, wide[j++]); } + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; @@ -2013,9 +2017,9 @@ set_sync: while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) { + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - } + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); @@ -2830,16 +2834,16 @@ static void is885(struct atp_unit *dev, unsigned char c) unsigned char i, j, k, rmb, n, lvdmode; unsigned short int m; static unsigned char mbuf[512]; - static unsigned char satn[9] = {0, 0, 0, 0, 0, 0, 0, 6, 6}; - static unsigned char inqd[9] = {0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6}; - static unsigned char synn[6] = {0x80, 1, 3, 1, 0x19, 0x0e}; - unsigned char synu[6] = {0x80, 1, 3, 1, 0x0a, 0x0e}; - static unsigned char synw[6] = {0x80, 1, 3, 1, 0x19, 0x0e}; - unsigned char synuw[6] = {0x80, 1, 3, 1, 0x0a, 0x0e}; - static unsigned char wide[6] = {0x80, 1, 2, 3, 1, 0}; - static unsigned char u3[9] = { 0x80,1,6,4,0x09,00,0x0e,0x01,0x02 }; + static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 }; + static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 }; + static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e }; + unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e }; + static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x19, 0x0e }; + unsigned char synuw[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e }; + static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; + static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 }; - lvdmode=atp_readb_io(dev, c, 0x1b) >> 7; + lvdmode = atp_readb_io(dev, c, 0x1b) >> 7; for (i = 0; i < 16; i++) { m = 1; @@ -2862,7 +2866,6 @@ static void is885(struct atp_unit *dev, unsigned char c) atp_writeb_io(dev, c, 8, satn[5]); atp_writeb_io(dev, c, 0x0f, 0); atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); atp_writeb_io(dev, c, 0x13, satn[6]); atp_writeb_io(dev, c, 0x14, satn[7]); @@ -2875,11 +2878,13 @@ static void is885(struct atp_unit *dev, unsigned char c) while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { + + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - } + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); + dev->active_id[c] |= m; atp_writeb_io(dev, c, 0x10, 0x30); @@ -2887,8 +2892,10 @@ static void is885(struct atp_unit *dev, unsigned char c) phase_cmd: atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { atp_writeb_io(dev, c, 0x10, 0x41); @@ -2907,13 +2914,16 @@ sel_ok: atp_writeb_io(dev, c, 0x13, inqd[6]); atp_writeb_io(dev, c, 0x14, inqd[7]); atp_writeb_io(dev, c, 0x18, inqd[8]); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { + + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - } + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); + atp_writeb_io(dev, c, 0x1b, 0x00); atp_writeb_io(dev, c, 0x18, 0x08); j = 0; @@ -2935,14 +2945,16 @@ rd_inq_data: atp_writeb_io(dev, c, 0x13, 0); atp_writeb_io(dev, c, 0x14, 0); atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, c, 0x17) != 0x16) { + + if (atp_readb_io(dev, c, 0x17) != 0x16) goto sel_ok; - } + inq_ok: mbuf[36] = 0; - printk( KERN_INFO" ID: %2d %s\n", i, &mbuf[8]); + printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]); dev->id[c][i].devtype = mbuf[0]; rmb = mbuf[1]; n = mbuf[7]; @@ -2953,10 +2965,11 @@ inq_ok: goto not_wide; } if (lvdmode == 0) { - goto chg_wide; + goto chg_wide; } - if (dev->sp[c][i] != 0x04) { // force u2 - goto chg_wide; + if (dev->sp[c][i] != 0x04) // force u2 + { + goto chg_wide; } atp_writeb_io(dev, c, 0x1b, 0x01); @@ -2975,11 +2988,13 @@ inq_ok: while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { + + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - } + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); + try_u3: j = 0; atp_writeb_io(dev, c, 0x14, 0x09); @@ -2990,8 +3005,10 @@ try_u3: atp_writeb_io(dev, c, 0x19, u3[j++]); cpu_relax(); } + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; @@ -3049,7 +3066,9 @@ u3p_cmd: atp_writeb_io(dev, c, 0x10, 0x30); atp_writeb_io(dev, c, 0x14, 0x00); atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { if (j == 0x4e) { @@ -3093,11 +3112,13 @@ chg_wide: while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { + + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - } + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); + try_wide: j = 0; atp_writeb_io(dev, c, 0x14, 0x05); @@ -3108,8 +3129,10 @@ try_wide: atp_writeb_io(dev, c, 0x19, wide[j++]); cpu_relax(); } + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; @@ -3167,8 +3190,10 @@ widep_cmd: atp_writeb_io(dev, c, 0x10, 0x30); atp_writeb_io(dev, c, 0x14, 0x00); atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { if (j == 0x4e) { @@ -3192,24 +3217,23 @@ widep_cmd: m = m << i; dev->wide_id[c] |= m; not_wide: - if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) || - ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) { + if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) || ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) { m = 1; m = m << i; if ((dev->async[c] & m) != 0) { - goto set_sync; + goto set_sync; } } continue; set_sync: if (dev->sp[c][i] == 0x02) { - synu[4]=0x0c; - synuw[4]=0x0c; + synu[4] = 0x0c; + synuw[4] = 0x0c; } else { - if (dev->sp[c][i] >= 0x03) { - synu[4]=0x0a; - synuw[4]=0x0a; - } + if (dev->sp[c][i] >= 0x03) { + synu[4] = 0x0a; + synuw[4] = 0x0a; + } } j = 0; if ((m & dev->wide_id[c]) != 0) { @@ -3231,11 +3255,13 @@ set_sync: while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { + + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - } + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); + try_sync: j = 0; atp_writeb_io(dev, c, 0x14, 0x06); @@ -3258,8 +3284,10 @@ try_sync: } } } + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; @@ -3306,7 +3334,9 @@ phase_ins1: if ((j & 0x80) == 0x00) { goto phase_ins1; } + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00); + j = atp_readb_io(dev, c, 0x17); if (j == 0x85) { goto tar_dcons; @@ -3327,8 +3357,10 @@ phase_cmds: tar_dcons: atp_writeb_io(dev, c, 0x14, 0x00); atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { continue; @@ -3349,7 +3381,7 @@ tar_dcons: mbuf[4] = 0x0e; } dev->id[c][i].devsp = mbuf[4]; - if (mbuf[3] < 0x0c){ + if (mbuf[3] < 0x0c) { j = 0xb0; goto set_syn_ok; } @@ -3370,9 +3402,9 @@ tar_dcons: goto set_syn_ok; } j = 0x60; - set_syn_ok: +set_syn_ok: dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j; -#ifdef ED_DBGP +#ifdef ED_DBGP printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp); #endif } -- GitLab From bdf8b62dc3fb2ef5df22d36d1d2ec1d38e081290 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:59 +0100 Subject: [PATCH 0624/2855] atp870u: Add channel parameter to is870() and is880() Add channel parameter to is870() and is880() functions to simplify comparing them with is885(). Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 684 ++++++++++++++++++++--------------------- 1 file changed, 342 insertions(+), 342 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 595c5c54af990..ec619022aa6eb 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1162,7 +1162,7 @@ static void tscam(struct Scsi_Host *host) } } -static void is870(struct atp_unit *dev) +static void is870(struct atp_unit *dev, unsigned char c) { unsigned char i, j, k, rmb, n; unsigned short int m; @@ -1174,7 +1174,7 @@ static void is870(struct atp_unit *dev) static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 }; static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; - atp_writeb_io(dev, 0, 0x3a, atp_readb_io(dev, 0, 0x3a) | 0x10); + atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) | 0x10); for (i = 0; i < 16; i++) { if ((dev->chip_ver != 4) && (i > 7)) { @@ -1182,120 +1182,120 @@ static void is870(struct atp_unit *dev) } m = 1; m = m << i; - if ((m & dev->active_id[0]) != 0) { + if ((m & dev->active_id[c]) != 0) { continue; } - if (i == dev->host_id[0]) { - printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[0]); + if (i == dev->host_id[c]) { + printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); continue; } if (dev->chip_ver == 4) { - atp_writeb_io(dev, 0, 0x1b, 0x01); + atp_writeb_io(dev, c, 0x1b, 0x01); } else { - atp_writeb_io(dev, 0, 0x1b, 0x00); + atp_writeb_io(dev, c, 0x1b, 0x00); } - atp_writeb_io(dev, 0, 1, 0x08); - atp_writeb_io(dev, 0, 2, 0x7f); - atp_writeb_io(dev, 0, 3, satn[0]); - atp_writeb_io(dev, 0, 4, satn[1]); - atp_writeb_io(dev, 0, 5, satn[2]); - atp_writeb_io(dev, 0, 6, satn[3]); - atp_writeb_io(dev, 0, 7, satn[4]); - atp_writeb_io(dev, 0, 8, satn[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, satn[6]); - atp_writeb_io(dev, 0, 0x14, satn[7]); + atp_writeb_io(dev, c, 1, 0x08); + atp_writeb_io(dev, c, 2, 0x7f); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); j = i; if ((j & 0x08) != 0) { j = (j & 0x07) | 0x40; } - atp_writeb_io(dev, 0, 0x15, j); - atp_writeb_io(dev, 0, 0x18, satn[8]); + atp_writeb_io(dev, c, 0x15, j); + atp_writeb_io(dev, c, 0x18, satn[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); - dev->active_id[0] |= m; + dev->active_id[c] |= m; - atp_writeb_io(dev, 0, 0x10, 0x30); - atp_writeb_io(dev, 0, 0x04, 0x00); + atp_writeb_io(dev, c, 0x10, 0x30); + atp_writeb_io(dev, c, 0x04, 0x00); phase_cmd: - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { - atp_writeb_io(dev, 0, 0x10, 0x41); + atp_writeb_io(dev, c, 0x10, 0x41); goto phase_cmd; } sel_ok: - atp_writeb_io(dev, 0, 3, inqd[0]); - atp_writeb_io(dev, 0, 4, inqd[1]); - atp_writeb_io(dev, 0, 5, inqd[2]); - atp_writeb_io(dev, 0, 6, inqd[3]); - atp_writeb_io(dev, 0, 7, inqd[4]); - atp_writeb_io(dev, 0, 8, inqd[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, inqd[6]); - atp_writeb_io(dev, 0, 0x14, inqd[7]); - atp_writeb_io(dev, 0, 0x18, inqd[8]); + atp_writeb_io(dev, c, 3, inqd[0]); + atp_writeb_io(dev, c, 4, inqd[1]); + atp_writeb_io(dev, c, 5, inqd[2]); + atp_writeb_io(dev, c, 6, inqd[3]); + atp_writeb_io(dev, c, 7, inqd[4]); + atp_writeb_io(dev, c, 8, inqd[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, inqd[6]); + atp_writeb_io(dev, c, 0x14, inqd[7]); + atp_writeb_io(dev, c, 0x18, inqd[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); if (dev->chip_ver == 4) - atp_writeb_io(dev, 0, 0x1b, 0x00); + atp_writeb_io(dev, c, 0x1b, 0x00); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x18, 0x08); j = 0; rd_inq_data: - k = atp_readb_io(dev, 0, 0x1f); + k = atp_readb_io(dev, c, 0x1f); if ((k & 0x01) != 0) { - mbuf[j++] = atp_readb_io(dev, 0, 0x19); + mbuf[j++] = atp_readb_io(dev, c, 0x19); goto rd_inq_data; } if ((k & 0x80) == 0) { goto rd_inq_data; } - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j == 0x16) { goto inq_ok; } - atp_writeb_io(dev, 0, 0x10, 0x46); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, 0); - atp_writeb_io(dev, 0, 0x14, 0); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x10, 0x46); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, 0); + atp_writeb_io(dev, c, 0x14, 0); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x16) + if (atp_readb_io(dev, c, 0x17) != 0x16) goto sel_ok; inq_ok: mbuf[36] = 0; printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]); - dev->id[0][i].devtype = mbuf[0]; + dev->id[c][i].devtype = mbuf[0]; rmb = mbuf[1]; n = mbuf[7]; if (dev->chip_ver != 4) { @@ -1304,46 +1304,46 @@ inq_ok: if ((mbuf[7] & 0x60) == 0) { goto not_wide; } - if ((dev->global_map[0] & 0x20) == 0) { + if ((dev->global_map[c] & 0x20) == 0) { goto not_wide; } - atp_writeb_io(dev, 0, 0x1b, 0x01); - atp_writeb_io(dev, 0, 3, satn[0]); - atp_writeb_io(dev, 0, 4, satn[1]); - atp_writeb_io(dev, 0, 5, satn[2]); - atp_writeb_io(dev, 0, 6, satn[3]); - atp_writeb_io(dev, 0, 7, satn[4]); - atp_writeb_io(dev, 0, 8, satn[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, satn[6]); - atp_writeb_io(dev, 0, 0x14, satn[7]); - atp_writeb_io(dev, 0, 0x18, satn[8]); + atp_writeb_io(dev, c, 0x1b, 0x01); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x18, satn[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); try_wide: j = 0; - atp_writeb_io(dev, 0, 0x14, 0x05); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0x05); + atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, 0, 0x19, wide[j++]); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, wide[j++]); } - while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1355,12 +1355,12 @@ try_wide: } continue; widep_out: - atp_writeb_io(dev, 0, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, 0, 0x19, 0); + atp_writeb_io(dev, c, 0x18, 0x20); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, 0); } - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1372,19 +1372,19 @@ widep_out: } continue; widep_in: - atp_writeb_io(dev, 0, 0x14, 0xff); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0xff); + atp_writeb_io(dev, c, 0x18, 0x20); k = 0; widep_in1: - j = atp_readb_io(dev, 0, 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x01) != 0) { - mbuf[k++] = atp_readb_io(dev, 0, 0x19); + mbuf[k++] = atp_readb_io(dev, c, 0x19); goto widep_in1; } if ((j & 0x80) == 0x00) { goto widep_in1; } - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1396,14 +1396,14 @@ widep_in1: } continue; widep_cmd: - atp_writeb_io(dev, 0, 0x10, 0x30); - atp_writeb_io(dev, 0, 0x14, 0x00); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x10, 0x30); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { if (j == 0x4e) { goto widep_out; @@ -1424,63 +1424,63 @@ widep_cmd: } m = 1; m = m << i; - dev->wide_id[0] |= m; + dev->wide_id[c] |= m; not_wide: - if ((dev->id[0][i].devtype == 0x00) || (dev->id[0][i].devtype == 0x07) || ((dev->id[0][i].devtype == 0x05) && ((n & 0x10) != 0))) { + if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) || ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) { goto set_sync; } continue; set_sync: j = 0; - if ((m & dev->wide_id[0]) != 0) { + if ((m & dev->wide_id[c]) != 0) { j |= 0x01; } - atp_writeb_io(dev, 0, 0x1b, j); - atp_writeb_io(dev, 0, 3, satn[0]); - atp_writeb_io(dev, 0, 4, satn[1]); - atp_writeb_io(dev, 0, 5, satn[2]); - atp_writeb_io(dev, 0, 6, satn[3]); - atp_writeb_io(dev, 0, 7, satn[4]); - atp_writeb_io(dev, 0, 8, satn[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, satn[6]); - atp_writeb_io(dev, 0, 0x14, satn[7]); - atp_writeb_io(dev, 0, 0x18, satn[8]); + atp_writeb_io(dev, c, 0x1b, j); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x18, satn[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); try_sync: j = 0; - atp_writeb_io(dev, 0, 0x14, 0x06); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0x06); + atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) { - if ((m & dev->wide_id[0]) != 0) { - atp_writeb_io(dev, 0, 0x19, synw[j++]); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) { + if ((m & dev->wide_id[c]) != 0) { + atp_writeb_io(dev, c, 0x19, synw[j++]); } else { - if ((m & dev->ultra_map[0]) != 0) { - atp_writeb_io(dev, 0, 0x19, synu[j++]); + if ((m & dev->ultra_map[c]) != 0) { + atp_writeb_io(dev, c, 0x19, synu[j++]); } else { - atp_writeb_io(dev, 0, 0x19, synn[j++]); + atp_writeb_io(dev, c, 0x19, synn[j++]); } } } } - while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; } @@ -1492,12 +1492,12 @@ try_sync: } continue; phase_outs: - atp_writeb_io(dev, 0, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0x00) - atp_writeb_io(dev, 0, 0x19, 0x00); + atp_writeb_io(dev, c, 0x18, 0x20); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0x00) + atp_writeb_io(dev, c, 0x19, 0x00); } - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -1513,23 +1513,23 @@ phase_outs: } continue; phase_ins: - atp_writeb_io(dev, 0, 0x14, 0xff); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0xff); + atp_writeb_io(dev, c, 0x18, 0x20); k = 0; phase_ins1: - j = atp_readb_io(dev, 0, 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x01) != 0x00) { - mbuf[k++] = atp_readb_io(dev, 0, 0x19); + mbuf[k++] = atp_readb_io(dev, c, 0x19); goto phase_ins1; } if ((j & 0x80) == 0x00) { goto phase_ins1; } - while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -1545,15 +1545,15 @@ phase_ins1: } continue; phase_cmds: - atp_writeb_io(dev, 0, 0x10, 0x30); + atp_writeb_io(dev, c, 0x10, 0x30); tar_dcons: - atp_writeb_io(dev, 0, 0x14, 0x00); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { continue; } @@ -1572,7 +1572,7 @@ tar_dcons: if (mbuf[4] > 0x0c) { mbuf[4] = 0x0c; } - dev->id[0][i].devsp = mbuf[4]; + dev->id[c][i].devsp = mbuf[4]; if ((mbuf[3] < 0x0d) && (rmb == 0)) { j = 0xa0; goto set_syn_ok; @@ -1591,12 +1591,12 @@ tar_dcons: } j = 0x60; set_syn_ok: - dev->id[0][i].devsp = (dev->id[0][i].devsp & 0x0f) | j; + dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j; } - atp_writeb_io(dev, 0, 0x3a, atp_readb_io(dev, 0, 0x3a) & 0xef); + atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xef); } -static void is880(struct atp_unit *dev) +static void is880(struct atp_unit *dev, unsigned char c) { unsigned char i, j, k, rmb, n, lvdmode; unsigned short int m; @@ -1615,167 +1615,167 @@ static void is880(struct atp_unit *dev) for (i = 0; i < 16; i++) { m = 1; m = m << i; - if ((m & dev->active_id[0]) != 0) { + if ((m & dev->active_id[c]) != 0) { continue; } - if (i == dev->host_id[0]) { - printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[0]); + if (i == dev->host_id[c]) { + printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); continue; } - atp_writeb_io(dev, 0, 0x1b, 0x01); - atp_writeb_io(dev, 0, 1, 0x08); - atp_writeb_io(dev, 0, 2, 0x7f); - atp_writeb_io(dev, 0, 3, satn[0]); - atp_writeb_io(dev, 0, 4, satn[1]); - atp_writeb_io(dev, 0, 5, satn[2]); - atp_writeb_io(dev, 0, 6, satn[3]); - atp_writeb_io(dev, 0, 7, satn[4]); - atp_writeb_io(dev, 0, 8, satn[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, satn[6]); - atp_writeb_io(dev, 0, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x1b, 0x01); + atp_writeb_io(dev, c, 1, 0x08); + atp_writeb_io(dev, c, 2, 0x7f); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); j = i; if ((j & 0x08) != 0) { j = (j & 0x07) | 0x40; } - atp_writeb_io(dev, 0, 0x15, j); - atp_writeb_io(dev, 0, 0x18, satn[8]); + atp_writeb_io(dev, c, 0x15, j); + atp_writeb_io(dev, c, 0x18, satn[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); - dev->active_id[0] |= m; + dev->active_id[c] |= m; - atp_writeb_io(dev, 0, 0x10, 0x30); - atp_writeb_io(dev, 0, 0x14, 0x00); + atp_writeb_io(dev, c, 0x10, 0x30); + atp_writeb_io(dev, c, 0x14, 0x00); phase_cmd: - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { - atp_writeb_io(dev, 0, 0x10, 0x41); + atp_writeb_io(dev, c, 0x10, 0x41); goto phase_cmd; } sel_ok: - atp_writeb_io(dev, 0, 3, inqd[0]); - atp_writeb_io(dev, 0, 4, inqd[1]); - atp_writeb_io(dev, 0, 5, inqd[2]); - atp_writeb_io(dev, 0, 6, inqd[3]); - atp_writeb_io(dev, 0, 7, inqd[4]); - atp_writeb_io(dev, 0, 8, inqd[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, inqd[6]); - atp_writeb_io(dev, 0, 0x14, inqd[7]); - atp_writeb_io(dev, 0, 0x18, inqd[8]); + atp_writeb_io(dev, c, 3, inqd[0]); + atp_writeb_io(dev, c, 4, inqd[1]); + atp_writeb_io(dev, c, 5, inqd[2]); + atp_writeb_io(dev, c, 6, inqd[3]); + atp_writeb_io(dev, c, 7, inqd[4]); + atp_writeb_io(dev, c, 8, inqd[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, inqd[6]); + atp_writeb_io(dev, c, 0x14, inqd[7]); + atp_writeb_io(dev, c, 0x18, inqd[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); - atp_writeb_io(dev, 0, 0x1b, 0x00); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x1b, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); j = 0; rd_inq_data: - k = atp_readb_io(dev, 0, 0x1f); + k = atp_readb_io(dev, c, 0x1f); if ((k & 0x01) != 0) { - mbuf[j++] = atp_readb_io(dev, 0, 0x19); + mbuf[j++] = atp_readb_io(dev, c, 0x19); goto rd_inq_data; } if ((k & 0x80) == 0) { goto rd_inq_data; } - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j == 0x16) { goto inq_ok; } - atp_writeb_io(dev, 0, 0x10, 0x46); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, 0); - atp_writeb_io(dev, 0, 0x14, 0); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x10, 0x46); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, 0); + atp_writeb_io(dev, c, 0x14, 0); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x16) + if (atp_readb_io(dev, c, 0x17) != 0x16) goto sel_ok; inq_ok: mbuf[36] = 0; printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]); - dev->id[0][i].devtype = mbuf[0]; + dev->id[c][i].devtype = mbuf[0]; rmb = mbuf[1]; n = mbuf[7]; if ((mbuf[7] & 0x60) == 0) { goto not_wide; } - if ((i < 8) && ((dev->global_map[0] & 0x20) == 0)) { + if ((i < 8) && ((dev->global_map[c] & 0x20) == 0)) { goto not_wide; } if (lvdmode == 0) { goto chg_wide; } - if (dev->sp[0][i] != 0x04) // force u2 + if (dev->sp[c][i] != 0x04) // force u2 { goto chg_wide; } - atp_writeb_io(dev, 0, 0x1b, 0x01); - atp_writeb_io(dev, 0, 3, satn[0]); - atp_writeb_io(dev, 0, 4, satn[1]); - atp_writeb_io(dev, 0, 5, satn[2]); - atp_writeb_io(dev, 0, 6, satn[3]); - atp_writeb_io(dev, 0, 7, satn[4]); - atp_writeb_io(dev, 0, 8, satn[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, satn[6]); - atp_writeb_io(dev, 0, 0x14, satn[7]); - atp_writeb_io(dev, 0, 0x18, satn[8]); + atp_writeb_io(dev, c, 0x1b, 0x01); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x18, satn[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); try_u3: j = 0; - atp_writeb_io(dev, 0, 0x14, 0x09); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0x09); + atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, 0, 0x19, u3[j++]); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, u3[j++]); } - while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1787,12 +1787,12 @@ try_u3: } continue; u3p_out: - atp_writeb_io(dev, 0, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, 0, 0x19, 0); + atp_writeb_io(dev, c, 0x18, 0x20); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, 0); } - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1804,19 +1804,19 @@ u3p_out: } continue; u3p_in: - atp_writeb_io(dev, 0, 0x14, 0x09); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0x09); + atp_writeb_io(dev, c, 0x18, 0x20); k = 0; u3p_in1: - j = atp_readb_io(dev, 0, 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x01) != 0) { - mbuf[k++] = atp_readb_io(dev, 0, 0x19); + mbuf[k++] = atp_readb_io(dev, c, 0x19); goto u3p_in1; } if ((j & 0x80) == 0x00) { goto u3p_in1; } - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1828,14 +1828,14 @@ u3p_in1: } continue; u3p_cmd: - atp_writeb_io(dev, 0, 0x10, 0x30); - atp_writeb_io(dev, 0, 0x14, 0x00); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x10, 0x30); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { if (j == 0x4e) { goto u3p_out; @@ -1854,48 +1854,48 @@ u3p_cmd: if (mbuf[3] == 0x09) { m = 1; m = m << i; - dev->wide_id[0] |= m; - dev->id[0][i].devsp = 0xce; + dev->wide_id[c] |= m; + dev->id[c][i].devsp = 0xce; continue; } chg_wide: - atp_writeb_io(dev, 0, 0x1b, 0x01); - atp_writeb_io(dev, 0, 3, satn[0]); - atp_writeb_io(dev, 0, 4, satn[1]); - atp_writeb_io(dev, 0, 5, satn[2]); - atp_writeb_io(dev, 0, 6, satn[3]); - atp_writeb_io(dev, 0, 7, satn[4]); - atp_writeb_io(dev, 0, 8, satn[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, satn[6]); - atp_writeb_io(dev, 0, 0x14, satn[7]); - atp_writeb_io(dev, 0, 0x18, satn[8]); + atp_writeb_io(dev, c, 0x1b, 0x01); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x18, satn[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); try_wide: j = 0; - atp_writeb_io(dev, 0, 0x14, 0x05); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0x05); + atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, 0, 0x19, wide[j++]); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, wide[j++]); } - while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1907,12 +1907,12 @@ try_wide: } continue; widep_out: - atp_writeb_io(dev, 0, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, 0, 0x19, 0); + atp_writeb_io(dev, c, 0x18, 0x20); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, 0); } - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1924,19 +1924,19 @@ widep_out: } continue; widep_in: - atp_writeb_io(dev, 0, 0x14, 0xff); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0xff); + atp_writeb_io(dev, c, 0x18, 0x20); k = 0; widep_in1: - j = atp_readb_io(dev, 0, 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x01) != 0) { - mbuf[k++] = atp_readb_io(dev, 0, 0x19); + mbuf[k++] = atp_readb_io(dev, c, 0x19); goto widep_in1; } if ((j & 0x80) == 0x00) { goto widep_in1; } - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1948,14 +1948,14 @@ widep_in1: } continue; widep_cmd: - atp_writeb_io(dev, 0, 0x10, 0x30); - atp_writeb_io(dev, 0, 0x14, 0x00); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x10, 0x30); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { if (j == 0x4e) { goto widep_out; @@ -1976,80 +1976,80 @@ widep_cmd: } m = 1; m = m << i; - dev->wide_id[0] |= m; + dev->wide_id[c] |= m; not_wide: - if ((dev->id[0][i].devtype == 0x00) || (dev->id[0][i].devtype == 0x07) || ((dev->id[0][i].devtype == 0x05) && ((n & 0x10) != 0))) { + if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) || ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) { m = 1; m = m << i; - if ((dev->async[0] & m) != 0) { + if ((dev->async[c] & m) != 0) { goto set_sync; } } continue; set_sync: - if (dev->sp[0][i] == 0x02) { + if (dev->sp[c][i] == 0x02) { synu[4] = 0x0c; synuw[4] = 0x0c; } else { - if (dev->sp[0][i] >= 0x03) { + if (dev->sp[c][i] >= 0x03) { synu[4] = 0x0a; synuw[4] = 0x0a; } } j = 0; - if ((m & dev->wide_id[0]) != 0) { + if ((m & dev->wide_id[c]) != 0) { j |= 0x01; } - atp_writeb_io(dev, 0, 0x1b, j); - atp_writeb_io(dev, 0, 3, satn[0]); - atp_writeb_io(dev, 0, 4, satn[1]); - atp_writeb_io(dev, 0, 5, satn[2]); - atp_writeb_io(dev, 0, 6, satn[3]); - atp_writeb_io(dev, 0, 7, satn[4]); - atp_writeb_io(dev, 0, 8, satn[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, satn[6]); - atp_writeb_io(dev, 0, 0x14, satn[7]); - atp_writeb_io(dev, 0, 0x18, satn[8]); + atp_writeb_io(dev, c, 0x1b, j); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x18, satn[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); try_sync: j = 0; - atp_writeb_io(dev, 0, 0x14, 0x06); - atp_writeb_io(dev, 0, 0x18, 0x20); - - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) { - if ((m & dev->wide_id[0]) != 0) { - if ((m & dev->ultra_map[0]) != 0) { - atp_writeb_io(dev, 0, 0x19, synuw[j++]); + atp_writeb_io(dev, c, 0x14, 0x06); + atp_writeb_io(dev, c, 0x18, 0x20); + + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) { + if ((m & dev->wide_id[c]) != 0) { + if ((m & dev->ultra_map[c]) != 0) { + atp_writeb_io(dev, c, 0x19, synuw[j++]); } else { - atp_writeb_io(dev, 0, 0x19, synw[j++]); + atp_writeb_io(dev, c, 0x19, synw[j++]); } } else { - if ((m & dev->ultra_map[0]) != 0) { - atp_writeb_io(dev, 0, 0x19, synu[j++]); + if ((m & dev->ultra_map[c]) != 0) { + atp_writeb_io(dev, c, 0x19, synu[j++]); } else { - atp_writeb_io(dev, 0, 0x19, synn[j++]); + atp_writeb_io(dev, c, 0x19, synn[j++]); } } } } - while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; } @@ -2061,12 +2061,12 @@ try_sync: } continue; phase_outs: - atp_writeb_io(dev, 0, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0x00) - atp_writeb_io(dev, 0, 0x19, 0x00); + atp_writeb_io(dev, c, 0x18, 0x20); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0x00) + atp_writeb_io(dev, c, 0x19, 0x00); } - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -2082,23 +2082,23 @@ phase_outs: } continue; phase_ins: - atp_writeb_io(dev, 0, 0x14, 0x06); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0x06); + atp_writeb_io(dev, c, 0x18, 0x20); k = 0; phase_ins1: - j = atp_readb_io(dev, 0, 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x01) != 0x00) { - mbuf[k++] = atp_readb_io(dev, 0, 0x19); + mbuf[k++] = atp_readb_io(dev, c, 0x19); goto phase_ins1; } if ((j & 0x80) == 0x00) { goto phase_ins1; } - while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -2114,15 +2114,15 @@ phase_ins1: } continue; phase_cmds: - atp_writeb_io(dev, 0, 0x10, 0x30); + atp_writeb_io(dev, c, 0x10, 0x30); tar_dcons: - atp_writeb_io(dev, 0, 0x14, 0x00); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { continue; } @@ -2141,7 +2141,7 @@ tar_dcons: if (mbuf[4] > 0x0e) { mbuf[4] = 0x0e; } - dev->id[0][i].devsp = mbuf[4]; + dev->id[c][i].devsp = mbuf[4]; if (mbuf[3] < 0x0c) { j = 0xb0; goto set_syn_ok; @@ -2164,7 +2164,7 @@ tar_dcons: } j = 0x60; set_syn_ok: - dev->id[0][i].devsp = (dev->id[0][i].devsp & 0x0f) | j; + dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j; } } @@ -2379,7 +2379,7 @@ flash_ok_880: outb(0x20, base_io + 0x51); tscam(shpnt); - is880(p); + is880(p, 0); outb(0xb0, base_io + 0x38); shpnt->max_id = 16; shpnt->this_id = host_id; @@ -2609,7 +2609,7 @@ flash_ok_885: outb(0x20, base_io + 0x11); tscam(shpnt); - is870(p); + is870(p, 0); outb((inb(base_io + 0x3a) & 0xef), base_io + 0x3a); outb((inb(base_io + 0x3b) | 0x20), base_io + 0x3b); if (atpdev->chip_ver == 4) -- GitLab From fa50b30842d8cea02903d55caf64fe22c0c4c8e2 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:00 +0100 Subject: [PATCH 0625/2855] atp870u: Move chip-specific lines out of is880() and is885() Move few chip-specifis lines out of is880() and is885() so they become almost identical. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index ec619022aa6eb..1c4b1f9f62b99 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -41,7 +41,7 @@ static struct scsi_host_template atp870u_template; static void send_s870(struct atp_unit *dev,unsigned char c); -static void is885(struct atp_unit *dev, unsigned char c); +static void is885(struct atp_unit *dev, unsigned char c, unsigned char lvdmode); static void tscam_885(void); static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val) @@ -1596,9 +1596,9 @@ set_syn_ok: atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xef); } -static void is880(struct atp_unit *dev, unsigned char c) +static void is880(struct atp_unit *dev, unsigned char c, unsigned char lvdmode) { - unsigned char i, j, k, rmb, n, lvdmode; + unsigned char i, j, k, rmb, n; unsigned short int m; static unsigned char mbuf[512]; static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 }; @@ -1610,8 +1610,6 @@ static void is880(struct atp_unit *dev, unsigned char c) static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 }; - lvdmode = atp_readb_base(dev, 0x3f) & 0x40; - for (i = 0; i < 16; i++) { m = 1; m = m << i; @@ -2379,7 +2377,7 @@ flash_ok_880: outb(0x20, base_io + 0x51); tscam(shpnt); - is880(p, 0); + is880(p, 0, atp_readb_base(p, 0x3f) & 0x40); outb(0xb0, base_io + 0x38); shpnt->max_id = 16; shpnt->this_id = host_id; @@ -2525,10 +2523,11 @@ flash_ok_885: tscam_885(); printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); - is885(p, 0); + is885(p, 0, atp_readb_io(p, 0, 0x1b) >> 7); + atp_writeb_io(p, 0, 0x16, 0x80); printk(KERN_INFO " Scanning Channel B SCSI Device ...\n"); - is885(p, 1); - + is885(p, 1, atp_readb_io(p, 1, 0x1b) >> 7); + atp_writeb_io(p, 1, 0x16, 0x80); k = inb(base_io + 0x28) & 0xcf; k |= 0xc0; outb(k, base_io + 0x28); @@ -2829,9 +2828,9 @@ static void tscam_885(void) -static void is885(struct atp_unit *dev, unsigned char c) +static void is885(struct atp_unit *dev, unsigned char c, unsigned char lvdmode) { - unsigned char i, j, k, rmb, n, lvdmode; + unsigned char i, j, k, rmb, n; unsigned short int m; static unsigned char mbuf[512]; static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 }; @@ -2843,8 +2842,6 @@ static void is885(struct atp_unit *dev, unsigned char c) static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 }; - lvdmode = atp_readb_io(dev, c, 0x1b) >> 7; - for (i = 0; i < 16; i++) { m = 1; m = m << i; @@ -3408,7 +3405,6 @@ set_syn_ok: printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp); #endif } - atp_writeb_io(dev, c, 0x16, 0x80); } module_init(atp870u_init); -- GitLab From e7d6d140328cb8c92ad749ab8a614c9299269975 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:01 +0100 Subject: [PATCH 0626/2855] atp870u: Remove is880() Now that is880() and is885() are almost identical (except for some cpu_relax() calls and debug printks), remove is880() and use is885() instead. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 572 +---------------------------------------- 1 file changed, 1 insertion(+), 571 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 1c4b1f9f62b99..d10026a734d7d 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1596,576 +1596,6 @@ set_syn_ok: atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xef); } -static void is880(struct atp_unit *dev, unsigned char c, unsigned char lvdmode) -{ - unsigned char i, j, k, rmb, n; - unsigned short int m; - static unsigned char mbuf[512]; - static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 }; - static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 }; - static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e }; - unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e }; - static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x19, 0x0e }; - unsigned char synuw[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e }; - static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; - static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 }; - - for (i = 0; i < 16; i++) { - m = 1; - m = m << i; - if ((m & dev->active_id[c]) != 0) { - continue; - } - if (i == dev->host_id[c]) { - printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); - continue; - } - atp_writeb_io(dev, c, 0x1b, 0x01); - atp_writeb_io(dev, c, 1, 0x08); - atp_writeb_io(dev, c, 2, 0x7f); - atp_writeb_io(dev, c, 3, satn[0]); - atp_writeb_io(dev, c, 4, satn[1]); - atp_writeb_io(dev, c, 5, satn[2]); - atp_writeb_io(dev, c, 6, satn[3]); - atp_writeb_io(dev, c, 7, satn[4]); - atp_writeb_io(dev, c, 8, satn[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, satn[6]); - atp_writeb_io(dev, c, 0x14, satn[7]); - j = i; - if ((j & 0x08) != 0) { - j = (j & 0x07) | 0x40; - } - atp_writeb_io(dev, c, 0x15, j); - atp_writeb_io(dev, c, 0x18, satn[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - - dev->active_id[c] |= m; - - atp_writeb_io(dev, c, 0x10, 0x30); - atp_writeb_io(dev, c, 0x14, 0x00); - -phase_cmd: - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j != 0x16) { - atp_writeb_io(dev, c, 0x10, 0x41); - goto phase_cmd; - } -sel_ok: - atp_writeb_io(dev, c, 3, inqd[0]); - atp_writeb_io(dev, c, 4, inqd[1]); - atp_writeb_io(dev, c, 5, inqd[2]); - atp_writeb_io(dev, c, 6, inqd[3]); - atp_writeb_io(dev, c, 7, inqd[4]); - atp_writeb_io(dev, c, 8, inqd[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, inqd[6]); - atp_writeb_io(dev, c, 0x14, inqd[7]); - atp_writeb_io(dev, c, 0x18, inqd[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - - atp_writeb_io(dev, c, 0x1b, 0x00); - atp_writeb_io(dev, c, 0x18, 0x08); - j = 0; -rd_inq_data: - k = atp_readb_io(dev, c, 0x1f); - if ((k & 0x01) != 0) { - mbuf[j++] = atp_readb_io(dev, c, 0x19); - goto rd_inq_data; - } - if ((k & 0x80) == 0) { - goto rd_inq_data; - } - j = atp_readb_io(dev, c, 0x17); - if (j == 0x16) { - goto inq_ok; - } - atp_writeb_io(dev, c, 0x10, 0x46); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, 0); - atp_writeb_io(dev, c, 0x14, 0); - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x16) - goto sel_ok; - -inq_ok: - mbuf[36] = 0; - printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]); - dev->id[c][i].devtype = mbuf[0]; - rmb = mbuf[1]; - n = mbuf[7]; - if ((mbuf[7] & 0x60) == 0) { - goto not_wide; - } - if ((i < 8) && ((dev->global_map[c] & 0x20) == 0)) { - goto not_wide; - } - if (lvdmode == 0) { - goto chg_wide; - } - if (dev->sp[c][i] != 0x04) // force u2 - { - goto chg_wide; - } - - atp_writeb_io(dev, c, 0x1b, 0x01); - atp_writeb_io(dev, c, 3, satn[0]); - atp_writeb_io(dev, c, 4, satn[1]); - atp_writeb_io(dev, c, 5, satn[2]); - atp_writeb_io(dev, c, 6, satn[3]); - atp_writeb_io(dev, c, 7, satn[4]); - atp_writeb_io(dev, c, 8, satn[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, satn[6]); - atp_writeb_io(dev, c, 0x14, satn[7]); - atp_writeb_io(dev, c, 0x18, satn[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - -try_u3: - j = 0; - atp_writeb_io(dev, c, 0x14, 0x09); - atp_writeb_io(dev, c, 0x18, 0x20); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, c, 0x19, u3[j++]); - } - - while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto u3p_in; - } - if (j == 0x0a) { - goto u3p_cmd; - } - if (j == 0x0e) { - goto try_u3; - } - continue; -u3p_out: - atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, c, 0x19, 0); - } - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto u3p_in; - } - if (j == 0x0a) { - goto u3p_cmd; - } - if (j == 0x0e) { - goto u3p_out; - } - continue; -u3p_in: - atp_writeb_io(dev, c, 0x14, 0x09); - atp_writeb_io(dev, c, 0x18, 0x20); - k = 0; -u3p_in1: - j = atp_readb_io(dev, c, 0x1f); - if ((j & 0x01) != 0) { - mbuf[k++] = atp_readb_io(dev, c, 0x19); - goto u3p_in1; - } - if ((j & 0x80) == 0x00) { - goto u3p_in1; - } - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto u3p_in; - } - if (j == 0x0a) { - goto u3p_cmd; - } - if (j == 0x0e) { - goto u3p_out; - } - continue; -u3p_cmd: - atp_writeb_io(dev, c, 0x10, 0x30); - atp_writeb_io(dev, c, 0x14, 0x00); - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j != 0x16) { - if (j == 0x4e) { - goto u3p_out; - } - continue; - } - if (mbuf[0] != 0x01) { - goto chg_wide; - } - if (mbuf[1] != 0x06) { - goto chg_wide; - } - if (mbuf[2] != 0x04) { - goto chg_wide; - } - if (mbuf[3] == 0x09) { - m = 1; - m = m << i; - dev->wide_id[c] |= m; - dev->id[c][i].devsp = 0xce; - continue; - } -chg_wide: - atp_writeb_io(dev, c, 0x1b, 0x01); - atp_writeb_io(dev, c, 3, satn[0]); - atp_writeb_io(dev, c, 4, satn[1]); - atp_writeb_io(dev, c, 5, satn[2]); - atp_writeb_io(dev, c, 6, satn[3]); - atp_writeb_io(dev, c, 7, satn[4]); - atp_writeb_io(dev, c, 8, satn[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, satn[6]); - atp_writeb_io(dev, c, 0x14, satn[7]); - atp_writeb_io(dev, c, 0x18, satn[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - -try_wide: - j = 0; - atp_writeb_io(dev, c, 0x14, 0x05); - atp_writeb_io(dev, c, 0x18, 0x20); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, c, 0x19, wide[j++]); - } - - while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto widep_in; - } - if (j == 0x0a) { - goto widep_cmd; - } - if (j == 0x0e) { - goto try_wide; - } - continue; -widep_out: - atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, c, 0x19, 0); - } - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto widep_in; - } - if (j == 0x0a) { - goto widep_cmd; - } - if (j == 0x0e) { - goto widep_out; - } - continue; -widep_in: - atp_writeb_io(dev, c, 0x14, 0xff); - atp_writeb_io(dev, c, 0x18, 0x20); - k = 0; -widep_in1: - j = atp_readb_io(dev, c, 0x1f); - if ((j & 0x01) != 0) { - mbuf[k++] = atp_readb_io(dev, c, 0x19); - goto widep_in1; - } - if ((j & 0x80) == 0x00) { - goto widep_in1; - } - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto widep_in; - } - if (j == 0x0a) { - goto widep_cmd; - } - if (j == 0x0e) { - goto widep_out; - } - continue; -widep_cmd: - atp_writeb_io(dev, c, 0x10, 0x30); - atp_writeb_io(dev, c, 0x14, 0x00); - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j != 0x16) { - if (j == 0x4e) { - goto widep_out; - } - continue; - } - if (mbuf[0] != 0x01) { - goto not_wide; - } - if (mbuf[1] != 0x02) { - goto not_wide; - } - if (mbuf[2] != 0x03) { - goto not_wide; - } - if (mbuf[3] != 0x01) { - goto not_wide; - } - m = 1; - m = m << i; - dev->wide_id[c] |= m; -not_wide: - if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) || ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) { - m = 1; - m = m << i; - if ((dev->async[c] & m) != 0) { - goto set_sync; - } - } - continue; -set_sync: - if (dev->sp[c][i] == 0x02) { - synu[4] = 0x0c; - synuw[4] = 0x0c; - } else { - if (dev->sp[c][i] >= 0x03) { - synu[4] = 0x0a; - synuw[4] = 0x0a; - } - } - j = 0; - if ((m & dev->wide_id[c]) != 0) { - j |= 0x01; - } - atp_writeb_io(dev, c, 0x1b, j); - atp_writeb_io(dev, c, 3, satn[0]); - atp_writeb_io(dev, c, 4, satn[1]); - atp_writeb_io(dev, c, 5, satn[2]); - atp_writeb_io(dev, c, 6, satn[3]); - atp_writeb_io(dev, c, 7, satn[4]); - atp_writeb_io(dev, c, 8, satn[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, satn[6]); - atp_writeb_io(dev, c, 0x14, satn[7]); - atp_writeb_io(dev, c, 0x18, satn[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - -try_sync: - j = 0; - atp_writeb_io(dev, c, 0x14, 0x06); - atp_writeb_io(dev, c, 0x18, 0x20); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) { - if ((m & dev->wide_id[c]) != 0) { - if ((m & dev->ultra_map[c]) != 0) { - atp_writeb_io(dev, c, 0x19, synuw[j++]); - } else { - atp_writeb_io(dev, c, 0x19, synw[j++]); - } - } else { - if ((m & dev->ultra_map[c]) != 0) { - atp_writeb_io(dev, c, 0x19, synu[j++]); - } else { - atp_writeb_io(dev, c, 0x19, synn[j++]); - } - } - } - } - - while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto phase_ins; - } - if (j == 0x0a) { - goto phase_cmds; - } - if (j == 0x0e) { - goto try_sync; - } - continue; -phase_outs: - atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0x00) - atp_writeb_io(dev, c, 0x19, 0x00); - } - j = atp_readb_io(dev, c, 0x17); - if (j == 0x85) { - goto tar_dcons; - } - j &= 0x0f; - if (j == 0x0f) { - goto phase_ins; - } - if (j == 0x0a) { - goto phase_cmds; - } - if (j == 0x0e) { - goto phase_outs; - } - continue; -phase_ins: - atp_writeb_io(dev, c, 0x14, 0x06); - atp_writeb_io(dev, c, 0x18, 0x20); - k = 0; -phase_ins1: - j = atp_readb_io(dev, c, 0x1f); - if ((j & 0x01) != 0x00) { - mbuf[k++] = atp_readb_io(dev, c, 0x19); - goto phase_ins1; - } - if ((j & 0x80) == 0x00) { - goto phase_ins1; - } - - while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j == 0x85) { - goto tar_dcons; - } - j &= 0x0f; - if (j == 0x0f) { - goto phase_ins; - } - if (j == 0x0a) { - goto phase_cmds; - } - if (j == 0x0e) { - goto phase_outs; - } - continue; -phase_cmds: - atp_writeb_io(dev, c, 0x10, 0x30); -tar_dcons: - atp_writeb_io(dev, c, 0x14, 0x00); - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j != 0x16) { - continue; - } - if (mbuf[0] != 0x01) { - continue; - } - if (mbuf[1] != 0x03) { - continue; - } - if (mbuf[4] == 0x00) { - continue; - } - if (mbuf[3] > 0x64) { - continue; - } - if (mbuf[4] > 0x0e) { - mbuf[4] = 0x0e; - } - dev->id[c][i].devsp = mbuf[4]; - if (mbuf[3] < 0x0c) { - j = 0xb0; - goto set_syn_ok; - } - if ((mbuf[3] < 0x0d) && (rmb == 0)) { - j = 0xa0; - goto set_syn_ok; - } - if (mbuf[3] < 0x1a) { - j = 0x20; - goto set_syn_ok; - } - if (mbuf[3] < 0x33) { - j = 0x40; - goto set_syn_ok; - } - if (mbuf[3] < 0x4c) { - j = 0x50; - goto set_syn_ok; - } - j = 0x60; -set_syn_ok: - dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j; - } -} - static void atp870u_free_tables(struct Scsi_Host *host) { struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata; @@ -2377,7 +1807,7 @@ flash_ok_880: outb(0x20, base_io + 0x51); tscam(shpnt); - is880(p, 0, atp_readb_base(p, 0x3f) & 0x40); + is885(p, 0, atp_readb_base(p, 0x3f) & 0x40); outb(0xb0, base_io + 0x38); shpnt->max_id = 16; shpnt->this_id = host_id; -- GitLab From 197fb8d85707d07eab68ac17d20e95c7104f1d5e Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:02 +0100 Subject: [PATCH 0627/2855] atp870u: Add wide_chip parameter to is870() and is885() Don't check chip_ver in is870() but add wide_chip parameter for that. Then add the non-wide support to is885(). Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 46 +++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index d10026a734d7d..0548d07509866 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -41,7 +41,7 @@ static struct scsi_host_template atp870u_template; static void send_s870(struct atp_unit *dev,unsigned char c); -static void is885(struct atp_unit *dev, unsigned char c, unsigned char lvdmode); +static void is885(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode); static void tscam_885(void); static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val) @@ -1162,7 +1162,7 @@ static void tscam(struct Scsi_Host *host) } } -static void is870(struct atp_unit *dev, unsigned char c) +static void is870(struct atp_unit *dev, unsigned char c, bool wide_chip) { unsigned char i, j, k, rmb, n; unsigned short int m; @@ -1177,9 +1177,8 @@ static void is870(struct atp_unit *dev, unsigned char c) atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) | 0x10); for (i = 0; i < 16; i++) { - if ((dev->chip_ver != 4) && (i > 7)) { + if (!wide_chip && (i > 7)) break; - } m = 1; m = m << i; if ((m & dev->active_id[c]) != 0) { @@ -1189,11 +1188,7 @@ static void is870(struct atp_unit *dev, unsigned char c) printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); continue; } - if (dev->chip_ver == 4) { - atp_writeb_io(dev, c, 0x1b, 0x01); - } else { - atp_writeb_io(dev, c, 0x1b, 0x00); - } + atp_writeb_io(dev, c, 0x1b, wide_chip ? 0x01 : 0x00); atp_writeb_io(dev, c, 1, 0x08); atp_writeb_io(dev, c, 2, 0x7f); atp_writeb_io(dev, c, 3, satn[0]); @@ -1262,7 +1257,7 @@ sel_ok: while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); - if (dev->chip_ver == 4) + if (wide_chip) atp_writeb_io(dev, c, 0x1b, 0x00); atp_writeb_io(dev, c, 0x18, 0x08); @@ -1298,9 +1293,8 @@ inq_ok: dev->id[c][i].devtype = mbuf[0]; rmb = mbuf[1]; n = mbuf[7]; - if (dev->chip_ver != 4) { + if (!wide_chip) goto not_wide; - } if ((mbuf[7] & 0x60) == 0) { goto not_wide; } @@ -1807,7 +1801,7 @@ flash_ok_880: outb(0x20, base_io + 0x51); tscam(shpnt); - is885(p, 0, atp_readb_base(p, 0x3f) & 0x40); + is885(p, 0, true, atp_readb_base(p, 0x3f) & 0x40); outb(0xb0, base_io + 0x38); shpnt->max_id = 16; shpnt->this_id = host_id; @@ -1953,10 +1947,10 @@ flash_ok_885: tscam_885(); printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); - is885(p, 0, atp_readb_io(p, 0, 0x1b) >> 7); + is885(p, 0, true, atp_readb_io(p, 0, 0x1b) >> 7); atp_writeb_io(p, 0, 0x16, 0x80); printk(KERN_INFO " Scanning Channel B SCSI Device ...\n"); - is885(p, 1, atp_readb_io(p, 1, 0x1b) >> 7); + is885(p, 1, true, atp_readb_io(p, 1, 0x1b) >> 7); atp_writeb_io(p, 1, 0x16, 0x80); k = inb(base_io + 0x28) & 0xcf; k |= 0xc0; @@ -2038,7 +2032,7 @@ flash_ok_885: outb(0x20, base_io + 0x11); tscam(shpnt); - is870(p, 0); + is870(p, 0, p->chip_ver == 4); outb((inb(base_io + 0x3a) & 0xef), base_io + 0x3a); outb((inb(base_io + 0x3b) | 0x20), base_io + 0x3b); if (atpdev->chip_ver == 4) @@ -2258,7 +2252,7 @@ static void tscam_885(void) -static void is885(struct atp_unit *dev, unsigned char c, unsigned char lvdmode) +static void is885(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode) { unsigned char i, j, k, rmb, n; unsigned short int m; @@ -2273,6 +2267,8 @@ static void is885(struct atp_unit *dev, unsigned char c, unsigned char lvdmode) static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 }; for (i = 0; i < 16; i++) { + if (!wide_chip && (i > 7)) + break; m = 1; m = m << i; if ((m & dev->active_id[c]) != 0) { @@ -2282,7 +2278,7 @@ static void is885(struct atp_unit *dev, unsigned char c, unsigned char lvdmode) printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); continue; } - atp_writeb_io(dev, c, 0x1b, 0x01); + atp_writeb_io(dev, c, 0x1b, wide_chip ? 0x01 : 0x00); atp_writeb_io(dev, c, 1, 0x08); atp_writeb_io(dev, c, 2, 0x7f); atp_writeb_io(dev, c, 3, satn[0]); @@ -2351,7 +2347,9 @@ sel_ok: while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); - atp_writeb_io(dev, c, 0x1b, 0x00); + if (wide_chip) + atp_writeb_io(dev, c, 0x1b, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); j = 0; rd_inq_data: @@ -2385,11 +2383,17 @@ inq_ok: dev->id[c][i].devtype = mbuf[0]; rmb = mbuf[1]; n = mbuf[7]; + if (!wide_chip) + goto not_wide; if ((mbuf[7] & 0x60) == 0) { goto not_wide; } - if ((i < 8) && ((dev->global_map[c] & 0x20) == 0)) { - goto not_wide; + if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) { + if ((i < 8) && ((dev->global_map[c] & 0x20) == 0)) + goto not_wide; + } else { /* result of is870() merge - is this a bug? */ + if ((dev->global_map[c] & 0x20) == 0) + goto not_wide; } if (lvdmode == 0) { goto chg_wide; -- GitLab From 460da918d46b075dcc9fdcf77281f8ebde169bd4 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:03 +0100 Subject: [PATCH 0628/2855] atp870u: Add remaining 870 support to is885() Add remaining 870 support to is885(): - different synw, no synuw - synu[4] = 0x0c - atp_writeb_io(dev, c, 0x04, 0x00); instead of atp_writeb_io(dev, c, 0x14, 0x00); (isn't that a bug?) - atp_writeb_io(dev, c, 0x14, 0xff); instead of atp_writeb_io(dev, c, 0x14, 0x06); - different mbuf[3] and mbuf[4] checks Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 45 +++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 0548d07509866..d76d3869a06d8 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -2262,6 +2262,7 @@ static void is885(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigne static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e }; unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e }; static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x19, 0x0e }; + static unsigned char synw_870[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 }; unsigned char synuw[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e }; static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 }; @@ -2311,7 +2312,10 @@ static void is885(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigne dev->active_id[c] |= m; atp_writeb_io(dev, c, 0x10, 0x30); - atp_writeb_io(dev, c, 0x14, 0x00); + if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) + atp_writeb_io(dev, c, 0x14, 0x00); + else /* result of is870() merge - is this a bug? */ + atp_writeb_io(dev, c, 0x04, 0x00); phase_cmd: atp_writeb_io(dev, c, 0x18, 0x08); @@ -2657,7 +2661,7 @@ not_wide: } continue; set_sync: - if (dev->sp[c][i] == 0x02) { + if ((dev->dev_id != ATP885_DEVID && dev->dev_id != ATP880_DEVID1 && dev->dev_id != ATP880_DEVID2) || (dev->sp[c][i] == 0x02)) { synu[4] = 0x0c; synuw[4] = 0x0c; } else { @@ -2701,11 +2705,14 @@ try_sync: while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) { if ((m & dev->wide_id[c]) != 0) { - if ((m & dev->ultra_map[c]) != 0) { - atp_writeb_io(dev, c, 0x19, synuw[j++]); - } else { - atp_writeb_io(dev, c, 0x19, synw[j++]); - } + if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) { + if ((m & dev->ultra_map[c]) != 0) { + atp_writeb_io(dev, c, 0x19, synuw[j++]); + } else { + atp_writeb_io(dev, c, 0x19, synw[j++]); + } + } else + atp_writeb_io(dev, c, 0x19, synw_870[j++]); } else { if ((m & dev->ultra_map[c]) != 0) { atp_writeb_io(dev, c, 0x19, synu[j++]); @@ -2753,7 +2760,10 @@ phase_outs: } continue; phase_ins: - atp_writeb_io(dev, c, 0x14, 0x06); + if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) + atp_writeb_io(dev, c, 0x14, 0x06); + else + atp_writeb_io(dev, c, 0x14, 0xff); atp_writeb_io(dev, c, 0x18, 0x20); k = 0; phase_ins1: @@ -2808,14 +2818,21 @@ tar_dcons: if (mbuf[3] > 0x64) { continue; } - if (mbuf[4] > 0x0e) { - mbuf[4] = 0x0e; + if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) { + if (mbuf[4] > 0x0e) { + mbuf[4] = 0x0e; + } + } else { + if (mbuf[4] > 0x0c) { + mbuf[4] = 0x0c; + } } dev->id[c][i].devsp = mbuf[4]; - if (mbuf[3] < 0x0c) { - j = 0xb0; - goto set_syn_ok; - } + if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) + if (mbuf[3] < 0x0c) { + j = 0xb0; + goto set_syn_ok; + } if ((mbuf[3] < 0x0d) && (rmb == 0)) { j = 0xa0; goto set_syn_ok; -- GitLab From 95c1def50dd6b1de4ceb0d6950e37e74c301d9d2 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:04 +0100 Subject: [PATCH 0629/2855] atp870u: Move 870-specific code out of is870() Move few remaining 870-specific code lines out of is870() Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index d76d3869a06d8..6427f8737b7df 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1174,8 +1174,6 @@ static void is870(struct atp_unit *dev, unsigned char c, bool wide_chip) static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 }; static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; - atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) | 0x10); - for (i = 0; i < 16; i++) { if (!wide_chip && (i > 7)) break; @@ -1587,7 +1585,6 @@ tar_dcons: set_syn_ok: dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j; } - atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xef); } static void atp870u_free_tables(struct Scsi_Host *host) @@ -2032,7 +2029,9 @@ flash_ok_885: outb(0x20, base_io + 0x11); tscam(shpnt); + atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) | 0x10); is870(p, 0, p->chip_ver == 4); + atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) & 0xef); outb((inb(base_io + 0x3a) & 0xef), base_io + 0x3a); outb((inb(base_io + 0x3b) | 0x20), base_io + 0x3b); if (atpdev->chip_ver == 4) -- GitLab From 851eb6618e6a27004e33c0422fdcf05b5b45c025 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:05 +0100 Subject: [PATCH 0630/2855] atp870u: Remove is870() Now that is885() supports everything from is870() and the rest of the code is almost identical, remove is870() and use is885() instead. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 427 +---------------------------------------- 1 file changed, 1 insertion(+), 426 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 6427f8737b7df..918875bc92feb 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1162,431 +1162,6 @@ static void tscam(struct Scsi_Host *host) } } -static void is870(struct atp_unit *dev, unsigned char c, bool wide_chip) -{ - unsigned char i, j, k, rmb, n; - unsigned short int m; - static unsigned char mbuf[512]; - static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 }; - static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 }; - static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e }; - static unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0c, 0x0e }; - static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 }; - static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; - - for (i = 0; i < 16; i++) { - if (!wide_chip && (i > 7)) - break; - m = 1; - m = m << i; - if ((m & dev->active_id[c]) != 0) { - continue; - } - if (i == dev->host_id[c]) { - printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); - continue; - } - atp_writeb_io(dev, c, 0x1b, wide_chip ? 0x01 : 0x00); - atp_writeb_io(dev, c, 1, 0x08); - atp_writeb_io(dev, c, 2, 0x7f); - atp_writeb_io(dev, c, 3, satn[0]); - atp_writeb_io(dev, c, 4, satn[1]); - atp_writeb_io(dev, c, 5, satn[2]); - atp_writeb_io(dev, c, 6, satn[3]); - atp_writeb_io(dev, c, 7, satn[4]); - atp_writeb_io(dev, c, 8, satn[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, satn[6]); - atp_writeb_io(dev, c, 0x14, satn[7]); - j = i; - if ((j & 0x08) != 0) { - j = (j & 0x07) | 0x40; - } - atp_writeb_io(dev, c, 0x15, j); - atp_writeb_io(dev, c, 0x18, satn[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - - dev->active_id[c] |= m; - - atp_writeb_io(dev, c, 0x10, 0x30); - atp_writeb_io(dev, c, 0x04, 0x00); - -phase_cmd: - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j != 0x16) { - atp_writeb_io(dev, c, 0x10, 0x41); - goto phase_cmd; - } -sel_ok: - atp_writeb_io(dev, c, 3, inqd[0]); - atp_writeb_io(dev, c, 4, inqd[1]); - atp_writeb_io(dev, c, 5, inqd[2]); - atp_writeb_io(dev, c, 6, inqd[3]); - atp_writeb_io(dev, c, 7, inqd[4]); - atp_writeb_io(dev, c, 8, inqd[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, inqd[6]); - atp_writeb_io(dev, c, 0x14, inqd[7]); - atp_writeb_io(dev, c, 0x18, inqd[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - - if (wide_chip) - atp_writeb_io(dev, c, 0x1b, 0x00); - - atp_writeb_io(dev, c, 0x18, 0x08); - j = 0; -rd_inq_data: - k = atp_readb_io(dev, c, 0x1f); - if ((k & 0x01) != 0) { - mbuf[j++] = atp_readb_io(dev, c, 0x19); - goto rd_inq_data; - } - if ((k & 0x80) == 0) { - goto rd_inq_data; - } - j = atp_readb_io(dev, c, 0x17); - if (j == 0x16) { - goto inq_ok; - } - atp_writeb_io(dev, c, 0x10, 0x46); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, 0); - atp_writeb_io(dev, c, 0x14, 0); - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x16) - goto sel_ok; - -inq_ok: - mbuf[36] = 0; - printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]); - dev->id[c][i].devtype = mbuf[0]; - rmb = mbuf[1]; - n = mbuf[7]; - if (!wide_chip) - goto not_wide; - if ((mbuf[7] & 0x60) == 0) { - goto not_wide; - } - if ((dev->global_map[c] & 0x20) == 0) { - goto not_wide; - } - atp_writeb_io(dev, c, 0x1b, 0x01); - atp_writeb_io(dev, c, 3, satn[0]); - atp_writeb_io(dev, c, 4, satn[1]); - atp_writeb_io(dev, c, 5, satn[2]); - atp_writeb_io(dev, c, 6, satn[3]); - atp_writeb_io(dev, c, 7, satn[4]); - atp_writeb_io(dev, c, 8, satn[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, satn[6]); - atp_writeb_io(dev, c, 0x14, satn[7]); - atp_writeb_io(dev, c, 0x18, satn[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - -try_wide: - j = 0; - atp_writeb_io(dev, c, 0x14, 0x05); - atp_writeb_io(dev, c, 0x18, 0x20); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, c, 0x19, wide[j++]); - } - - while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto widep_in; - } - if (j == 0x0a) { - goto widep_cmd; - } - if (j == 0x0e) { - goto try_wide; - } - continue; -widep_out: - atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, c, 0x19, 0); - } - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto widep_in; - } - if (j == 0x0a) { - goto widep_cmd; - } - if (j == 0x0e) { - goto widep_out; - } - continue; -widep_in: - atp_writeb_io(dev, c, 0x14, 0xff); - atp_writeb_io(dev, c, 0x18, 0x20); - k = 0; -widep_in1: - j = atp_readb_io(dev, c, 0x1f); - if ((j & 0x01) != 0) { - mbuf[k++] = atp_readb_io(dev, c, 0x19); - goto widep_in1; - } - if ((j & 0x80) == 0x00) { - goto widep_in1; - } - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto widep_in; - } - if (j == 0x0a) { - goto widep_cmd; - } - if (j == 0x0e) { - goto widep_out; - } - continue; -widep_cmd: - atp_writeb_io(dev, c, 0x10, 0x30); - atp_writeb_io(dev, c, 0x14, 0x00); - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j != 0x16) { - if (j == 0x4e) { - goto widep_out; - } - continue; - } - if (mbuf[0] != 0x01) { - goto not_wide; - } - if (mbuf[1] != 0x02) { - goto not_wide; - } - if (mbuf[2] != 0x03) { - goto not_wide; - } - if (mbuf[3] != 0x01) { - goto not_wide; - } - m = 1; - m = m << i; - dev->wide_id[c] |= m; -not_wide: - if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) || ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) { - goto set_sync; - } - continue; -set_sync: - j = 0; - if ((m & dev->wide_id[c]) != 0) { - j |= 0x01; - } - atp_writeb_io(dev, c, 0x1b, j); - atp_writeb_io(dev, c, 3, satn[0]); - atp_writeb_io(dev, c, 4, satn[1]); - atp_writeb_io(dev, c, 5, satn[2]); - atp_writeb_io(dev, c, 6, satn[3]); - atp_writeb_io(dev, c, 7, satn[4]); - atp_writeb_io(dev, c, 8, satn[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, satn[6]); - atp_writeb_io(dev, c, 0x14, satn[7]); - atp_writeb_io(dev, c, 0x18, satn[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - -try_sync: - j = 0; - atp_writeb_io(dev, c, 0x14, 0x06); - atp_writeb_io(dev, c, 0x18, 0x20); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) { - if ((m & dev->wide_id[c]) != 0) { - atp_writeb_io(dev, c, 0x19, synw[j++]); - } else { - if ((m & dev->ultra_map[c]) != 0) { - atp_writeb_io(dev, c, 0x19, synu[j++]); - } else { - atp_writeb_io(dev, c, 0x19, synn[j++]); - } - } - } - } - - while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto phase_ins; - } - if (j == 0x0a) { - goto phase_cmds; - } - if (j == 0x0e) { - goto try_sync; - } - continue; -phase_outs: - atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0x00) - atp_writeb_io(dev, c, 0x19, 0x00); - } - j = atp_readb_io(dev, c, 0x17); - if (j == 0x85) { - goto tar_dcons; - } - j &= 0x0f; - if (j == 0x0f) { - goto phase_ins; - } - if (j == 0x0a) { - goto phase_cmds; - } - if (j == 0x0e) { - goto phase_outs; - } - continue; -phase_ins: - atp_writeb_io(dev, c, 0x14, 0xff); - atp_writeb_io(dev, c, 0x18, 0x20); - k = 0; -phase_ins1: - j = atp_readb_io(dev, c, 0x1f); - if ((j & 0x01) != 0x00) { - mbuf[k++] = atp_readb_io(dev, c, 0x19); - goto phase_ins1; - } - if ((j & 0x80) == 0x00) { - goto phase_ins1; - } - - while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j == 0x85) { - goto tar_dcons; - } - j &= 0x0f; - if (j == 0x0f) { - goto phase_ins; - } - if (j == 0x0a) { - goto phase_cmds; - } - if (j == 0x0e) { - goto phase_outs; - } - continue; -phase_cmds: - atp_writeb_io(dev, c, 0x10, 0x30); -tar_dcons: - atp_writeb_io(dev, c, 0x14, 0x00); - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j != 0x16) { - continue; - } - if (mbuf[0] != 0x01) { - continue; - } - if (mbuf[1] != 0x03) { - continue; - } - if (mbuf[4] == 0x00) { - continue; - } - if (mbuf[3] > 0x64) { - continue; - } - if (mbuf[4] > 0x0c) { - mbuf[4] = 0x0c; - } - dev->id[c][i].devsp = mbuf[4]; - if ((mbuf[3] < 0x0d) && (rmb == 0)) { - j = 0xa0; - goto set_syn_ok; - } - if (mbuf[3] < 0x1a) { - j = 0x20; - goto set_syn_ok; - } - if (mbuf[3] < 0x33) { - j = 0x40; - goto set_syn_ok; - } - if (mbuf[3] < 0x4c) { - j = 0x50; - goto set_syn_ok; - } - j = 0x60; -set_syn_ok: - dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j; - } -} - static void atp870u_free_tables(struct Scsi_Host *host) { struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata; @@ -2030,7 +1605,7 @@ flash_ok_885: tscam(shpnt); atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) | 0x10); - is870(p, 0, p->chip_ver == 4); + is885(p, 0, p->chip_ver == 4, 0); atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) & 0xef); outb((inb(base_io + 0x3a) & 0xef), base_io + 0x3a); outb((inb(base_io + 0x3b) | 0x20), base_io + 0x3b); -- GitLab From 4192a40f49f0ab3028019deaba5cdc3b9db789dd Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:06 +0100 Subject: [PATCH 0631/2855] atp870u: Rename is885() to atp_is() Now that all the is* functions except is885() are gone, rename is885() to atp_is() to avoid confusion. Don't know what "is" means, though... Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 918875bc92feb..0b7d3bd854087 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -41,7 +41,7 @@ static struct scsi_host_template atp870u_template; static void send_s870(struct atp_unit *dev,unsigned char c); -static void is885(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode); +static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode); static void tscam_885(void); static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val) @@ -1373,7 +1373,7 @@ flash_ok_880: outb(0x20, base_io + 0x51); tscam(shpnt); - is885(p, 0, true, atp_readb_base(p, 0x3f) & 0x40); + atp_is(p, 0, true, atp_readb_base(p, 0x3f) & 0x40); outb(0xb0, base_io + 0x38); shpnt->max_id = 16; shpnt->this_id = host_id; @@ -1519,10 +1519,10 @@ flash_ok_885: tscam_885(); printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); - is885(p, 0, true, atp_readb_io(p, 0, 0x1b) >> 7); + atp_is(p, 0, true, atp_readb_io(p, 0, 0x1b) >> 7); atp_writeb_io(p, 0, 0x16, 0x80); printk(KERN_INFO " Scanning Channel B SCSI Device ...\n"); - is885(p, 1, true, atp_readb_io(p, 1, 0x1b) >> 7); + atp_is(p, 1, true, atp_readb_io(p, 1, 0x1b) >> 7); atp_writeb_io(p, 1, 0x16, 0x80); k = inb(base_io + 0x28) & 0xcf; k |= 0xc0; @@ -1605,7 +1605,7 @@ flash_ok_885: tscam(shpnt); atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) | 0x10); - is885(p, 0, p->chip_ver == 4, 0); + atp_is(p, 0, p->chip_ver == 4, 0); atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) & 0xef); outb((inb(base_io + 0x3a) & 0xef), base_io + 0x3a); outb((inb(base_io + 0x3b) | 0x20), base_io + 0x3b); @@ -1826,7 +1826,7 @@ static void tscam_885(void) -static void is885(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode) +static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode) { unsigned char i, j, k, rmb, n; unsigned short int m; -- GitLab From d804bb255ce85b1fd7dfe447da5415952ba341c5 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:07 +0100 Subject: [PATCH 0632/2855] atp870u: Convert remaining in[bwl] and out[bwl] to wrappers Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 222 ++++++++++++++++++++++------------------- 1 file changed, 118 insertions(+), 104 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 0b7d3bd854087..bccf872903e5c 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -49,6 +49,11 @@ static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val) outb(val, atp->baseport + reg); } +static inline void atp_writew_base(struct atp_unit *atp, u8 reg, u16 val) +{ + outw(val, atp->baseport + reg); +} + static inline void atp_writeb_io(struct atp_unit *atp, u8 channel, u8 reg, u8 val) { outb(val, atp->ioport[channel] + reg); @@ -74,6 +79,16 @@ static inline u8 atp_readb_base(struct atp_unit *atp, u8 reg) return inb(atp->baseport + reg); } +static inline u16 atp_readw_base(struct atp_unit *atp, u8 reg) +{ + return inw(atp->baseport + reg); +} + +static inline u32 atp_readl_base(struct atp_unit *atp, u8 reg) +{ + return inl(atp->baseport + reg); +} + static inline u8 atp_readb_io(struct atp_unit *atp, u8 channel, u8 reg) { return inb(atp->ioport[channel] + reg); @@ -1268,19 +1283,20 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) atpdev->chip_ver = pdev->revision; pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 - host_id = inb(base_io + 0x39); + atpdev->ioport[0] = base_io + 0x40; + atpdev->pciport[0] = base_io + 0x28; + + host_id = atp_readb_base(atpdev, 0x39); host_id >>= 0x04; printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d" " IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); - atpdev->ioport[0] = base_io + 0x40; - atpdev->pciport[0] = base_io + 0x28; atpdev->dev_id = ent->device; atpdev->host_id[0] = host_id; - atpdev->scam_on = inb(base_io + 0x22); - atpdev->global_map[0] = inb(base_io + 0x35); - atpdev->ultra_map[0] = inw(base_io + 0x3c); + atpdev->scam_on = atp_readb_base(atpdev, 0x22); + atpdev->global_map[0] = atp_readb_base(atpdev, 0x35); + atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x3c); n = 0x3f09; next_fblk_880: @@ -1288,37 +1304,37 @@ next_fblk_880: goto flash_ok_880; m = 0; - outw(n, base_io + 0x34); + atp_writew_base(atpdev, 0x34, n); n += 0x0002; - if (inb(base_io + 0x30) == 0xff) + if (atp_readb_base(atpdev, 0x30) == 0xff) goto flash_ok_880; - atpdev->sp[0][m++] = inb(base_io + 0x30); - atpdev->sp[0][m++] = inb(base_io + 0x31); - atpdev->sp[0][m++] = inb(base_io + 0x32); - atpdev->sp[0][m++] = inb(base_io + 0x33); - outw(n, base_io + 0x34); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); + atp_writew_base(atpdev, 0x34, n); n += 0x0002; - atpdev->sp[0][m++] = inb(base_io + 0x30); - atpdev->sp[0][m++] = inb(base_io + 0x31); - atpdev->sp[0][m++] = inb(base_io + 0x32); - atpdev->sp[0][m++] = inb(base_io + 0x33); - outw(n, base_io + 0x34); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); + atp_writew_base(atpdev, 0x34, n); n += 0x0002; - atpdev->sp[0][m++] = inb(base_io + 0x30); - atpdev->sp[0][m++] = inb(base_io + 0x31); - atpdev->sp[0][m++] = inb(base_io + 0x32); - atpdev->sp[0][m++] = inb(base_io + 0x33); - outw(n, base_io + 0x34); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); + atp_writew_base(atpdev, 0x34, n); n += 0x0002; - atpdev->sp[0][m++] = inb(base_io + 0x30); - atpdev->sp[0][m++] = inb(base_io + 0x31); - atpdev->sp[0][m++] = inb(base_io + 0x32); - atpdev->sp[0][m++] = inb(base_io + 0x33); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); n += 0x0018; goto next_fblk_880; flash_ok_880: - outw(0, base_io + 0x34); + atp_writew_base(atpdev, 0x34, 0); atpdev->ultra_map[0] = 0; atpdev->async[0] = 0; for (k = 0; k < 16; k++) { @@ -1332,7 +1348,7 @@ flash_ok_880: } } atpdev->async[0] = ~(atpdev->async[0]); - outb(atpdev->global_map[0], base_io + 0x35); + atp_writeb_base(atpdev, 0x35, atpdev->global_map[0]); shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); if (!shpnt) @@ -1355,26 +1371,26 @@ flash_ok_880: } spin_lock_irqsave(shpnt->host_lock, flags); - k = inb(base_io + 0x38) & 0x80; - outb(k, base_io + 0x38); - outb(0x20, base_io + 0x3b); + k = atp_readb_base(p, 0x38) & 0x80; + atp_writeb_base(p, 0x38, k); + atp_writeb_base(p, 0x3b, 0x20); mdelay(32); - outb(0, base_io + 0x3b); + atp_writeb_base(p, 0x3b, 0); mdelay(32); - inb(base_io + 0x5b); - inb(base_io + 0x57); - outb((host_id | 0x08), base_io + 0x40); - outb(0, base_io + 0x58); - while ((inb(base_io + 0x5f) & 0x80) == 0) + atp_readb_io(p, 0, 0x1b); + atp_readb_io(p, 0, 0x17); + atp_writeb_io(p, 0, 0, host_id | 0x08); + atp_writeb_io(p, 0, 0x18, 0); + while ((atp_readb_io(p, 0, 0x1f) & 0x80) == 0) mdelay(1); - inb(base_io + 0x57); - outb(8, base_io + 0x41); - outb(0x7f, base_io + 0x42); - outb(0x20, base_io + 0x51); + atp_readb_io(p, 0, 0x17); + atp_writeb_io(p, 0, 1, 8); + atp_writeb_io(p, 0, 2, 0x7f); + atp_writeb_io(p, 0, 0x11, 0x20); tscam(shpnt); atp_is(p, 0, true, atp_readb_base(p, 0x3f) & 0x40); - outb(0xb0, base_io + 0x38); + atp_writeb_base(p, 0x38, 0xb0); shpnt->max_id = 16; shpnt->this_id = host_id; shpnt->unique_id = base_io; @@ -1415,27 +1431,27 @@ flash_ok_880: spin_lock_irqsave(shpnt->host_lock, flags); - c=inb(base_io + 0x29); - outb((c | 0x04),base_io + 0x29); + c = atp_readb_base(p, 0x29); + atp_writeb_base(p, 0x29, c | 0x04); n=0x1f80; next_fblk_885: if (n >= 0x2000) { goto flash_ok_885; } - outw(n,base_io + 0x3c); - if (inl(base_io + 0x38) == 0xffffffff) { + atp_writew_base(p, 0x3c, n); + if (atp_readl_base(p, 0x38) == 0xffffffff) { goto flash_ok_885; } for (m=0; m < 2; m++) { p->global_map[m]= 0; for (k=0; k < 4; k++) { - outw(n++,base_io + 0x3c); - ((unsigned long *)&setupdata[m][0])[k]=inl(base_io + 0x38); + atp_writew_base(p, 0x3c, n++); + ((unsigned long *)&setupdata[m][0])[k] = atp_readl_base(p, 0x38); } for (k=0; k < 4; k++) { - outw(n++,base_io + 0x3c); - ((unsigned long *)&p->sp[m][0])[k]=inl(base_io + 0x38); + atp_writew_base(p, 0x3c, n++); + ((unsigned long *)&p->sp[m][0])[k] = atp_readl_base(p, 0x38); } n += 8; } @@ -1444,8 +1460,8 @@ flash_ok_885: #ifdef ED_DBGP printk( "Flash Read OK\n"); #endif - c=inb(base_io + 0x29); - outb((c & 0xfb),base_io + 0x29); + c = atp_readb_base(p, 0x29); + atp_writeb_base(p, 0x29, c & 0xfb); for (c=0;c < 2;c++) { p->ultra_map[c]=0; p->async[c] = 0; @@ -1474,48 +1490,48 @@ flash_ok_885: } } - k = inb(base_io + 0x28) & 0x8f; + k = atp_readb_base(p, 0x28) & 0x8f; k |= 0x10; - outb(k, base_io + 0x28); - outb(0x80, base_io + 0x41); - outb(0x80, base_io + 0x51); + atp_writeb_base(p, 0x28, k); + atp_writeb_pci(p, 0, 1, 0x80); + atp_writeb_pci(p, 1, 1, 0x80); mdelay(100); - outb(0, base_io + 0x41); - outb(0, base_io + 0x51); + atp_writeb_pci(p, 0, 1, 0); + atp_writeb_pci(p, 1, 1, 0); mdelay(1000); - inb(base_io + 0x9b); - inb(base_io + 0x97); - inb(base_io + 0xdb); - inb(base_io + 0xd7); + atp_readb_io(p, 0, 0x1b); + atp_readb_io(p, 0, 0x17); + atp_readb_io(p, 1, 0x1b); + atp_readb_io(p, 1, 0x17); k=p->host_id[0]; if (k > 7) k = (k & 0x07) | 0x40; k |= 0x08; - outb(k, base_io + 0x80); - outb(0, base_io + 0x98); + atp_writeb_io(p, 0, 0, k); + atp_writeb_io(p, 0, 0x18, 0); - while ((inb(base_io + 0x9f) & 0x80) == 0) + while ((atp_readb_io(p, 0, 0x1f) & 0x80) == 0) cpu_relax(); - inb(base_io + 0x97); - outb(8, base_io + 0x81); - outb(0x7f, base_io + 0x82); - outb(0x20, base_io + 0x91); + atp_readb_io(p, 0, 0x17); + atp_writeb_io(p, 0, 1, 8); + atp_writeb_io(p, 0, 2, 0x7f); + atp_writeb_io(p, 0, 0x11, 0x20); k=p->host_id[1]; if (k > 7) k = (k & 0x07) | 0x40; k |= 0x08; - outb(k, base_io + 0xc0); - outb(0, base_io + 0xd8); + atp_writeb_io(p, 1, 0, k); + atp_writeb_io(p, 1, 0x18, 0); - while ((inb(base_io + 0xdf) & 0x80) == 0) + while ((atp_readb_io(p, 1, 0x1f) & 0x80) == 0) cpu_relax(); - inb(base_io + 0xd7); - outb(8, base_io + 0xc1); - outb(0x7f, base_io + 0xc2); - outb(0x20, base_io + 0xd1); + atp_readb_io(p, 1, 0x17); + atp_writeb_io(p, 1, 1, 8); + atp_writeb_io(p, 1, 2, 0x7f); + atp_writeb_io(p, 1, 0x11, 0x20); tscam_885(); printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); @@ -1524,13 +1540,13 @@ flash_ok_885: printk(KERN_INFO " Scanning Channel B SCSI Device ...\n"); atp_is(p, 1, true, atp_readb_io(p, 1, 0x1b) >> 7); atp_writeb_io(p, 1, 0x16, 0x80); - k = inb(base_io + 0x28) & 0xcf; + k = atp_readb_base(p, 0x28) & 0xcf; k |= 0xc0; - outb(k, base_io + 0x28); - k = inb(base_io + 0x1f) | 0x80; - outb(k, base_io + 0x1f); - k = inb(base_io + 0x29) | 0x01; - outb(k, base_io + 0x29); + atp_writeb_base(p, 0x28, k); + k = atp_readb_base(p, 0x1f) | 0x80; + atp_writeb_base(p, 0x1f, k); + k = atp_readb_base(p, 0x29) | 0x01; + atp_writeb_base(p, 0x29, k); #ifdef ED_DBGP //printk("atp885: atp_host[0] 0x%p\n", atp_host[0]); #endif @@ -1554,9 +1570,9 @@ flash_ok_885: atpdev->dev_id = ent->device; host_id &= 0x07; atpdev->host_id[0] = host_id; - atpdev->scam_on = inb(base_io + 0x22); - atpdev->global_map[0] = inb(base_io + 0x2d); - atpdev->ultra_map[0] = inw(base_io + 0x2e); + atpdev->scam_on = atp_readb_pci(atpdev, 0, 2); + atpdev->global_map[0] = atp_readb_base(atpdev, 0x2d); + atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x2e); if (atpdev->ultra_map[0] == 0) { atpdev->scam_on = 0x00; @@ -1583,32 +1599,30 @@ flash_ok_885: } spin_lock_irqsave(shpnt->host_lock, flags); - if (atpdev->chip_ver > 0x07) { /* check if atp876 chip then enable terminator */ - outb(0x00, base_io + 0x3e); - } + if (atpdev->chip_ver > 0x07) /* check if atp876 chip then enable terminator */ + atp_writeb_base(p, 0x3e, 0x00); - k = (inb(base_io + 0x3a) & 0xf3) | 0x10; - outb(k, base_io + 0x3a); - outb((k & 0xdf), base_io + 0x3a); + k = (atp_readb_base(p, 0x3a) & 0xf3) | 0x10; + atp_writeb_base(p, 0x3a, k); + atp_writeb_base(p, 0x3a, k & 0xdf); mdelay(32); - outb(k, base_io + 0x3a); + atp_writeb_base(p, 0x3a, k); mdelay(32); - outb((host_id | 0x08), base_io + 0); - outb(0, base_io + 0x18); - while ((inb(base_io + 0x1f) & 0x80) == 0) + atp_writeb_io(p, 0, 0, host_id | 0x08); + atp_writeb_io(p, 0, 0x18, 0); + while ((atp_readb_io(p, 0, 0x1f) & 0x80) == 0) mdelay(1); - inb(base_io + 0x17); - outb(8, base_io + 1); - outb(0x7f, base_io + 2); - outb(0x20, base_io + 0x11); + atp_readb_io(p, 0, 0x17); + atp_writeb_io(p, 0, 1, 8); + atp_writeb_io(p, 0, 2, 0x7f); + atp_writeb_io(p, 0, 0x11, 0x20); tscam(shpnt); - atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) | 0x10); + atp_writeb_base(p, 0x3a, atp_readb_base(p, 0x3a) | 0x10); atp_is(p, 0, p->chip_ver == 4, 0); - atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) & 0xef); - outb((inb(base_io + 0x3a) & 0xef), base_io + 0x3a); - outb((inb(base_io + 0x3b) | 0x20), base_io + 0x3b); + atp_writeb_base(p, 0x3a, atp_readb_base(p, 0x3a) & 0xef); + atp_writeb_base(p, 0x3b, atp_readb_base(p, 0x3b) | 0x20); if (atpdev->chip_ver == 4) shpnt->max_id = 16; else -- GitLab From 2bbbac4571de7983f142ed22add59e5217674169 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:08 +0100 Subject: [PATCH 0633/2855] atp870u: Replace port 0x80 delay by udelay tscam() is using port 0x80 access for delays but that's x86-only. Use udelay(2) instead. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index bccf872903e5c..c4a59cc0821bd 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1036,7 +1036,7 @@ static void tscam(struct Scsi_Host *host) atp_writeb_io(dev, 0, 0x02, 0x7f); atp_writeb_io(dev, 0, 0x1b, 0x02); - outb(0, 0x80); + udelay(2); val = 0x0080; /* bsy */ atp_writew_io(dev, 0, 0x1c, val); @@ -1044,7 +1044,7 @@ static void tscam(struct Scsi_Host *host) atp_writew_io(dev, 0, 0x1c, val); val |= 0x0004; /* msg */ atp_writew_io(dev, 0, 0x1c, val); - inb(0x80); /* 2 deskew delay(45ns*2=90ns) */ + udelay(2); /* 2 deskew delay(45ns*2=90ns) */ val &= 0x007f; /* no bsy */ atp_writew_io(dev, 0, 0x1c, val); mdelay(128); @@ -1052,7 +1052,7 @@ static void tscam(struct Scsi_Host *host) atp_writew_io(dev, 0, 0x1c, val); while ((atp_readb_io(dev, 0, 0x1c) & 0x04) != 0) ; - outb(1, 0x80); + udelay(2); udelay(100); for (n = 0; n < 0x30000; n++) if ((atp_readb_io(dev, 0, 0x1c) & 0x80) != 0) /* bsy ? */ @@ -1060,13 +1060,13 @@ static void tscam(struct Scsi_Host *host) if (n < 0x30000) for (n = 0; n < 0x30000; n++) if ((atp_readb_io(dev, 0, 0x1c) & 0x81) == 0x0081) { - inb(0x80); + udelay(2); val |= 0x8003; /* io,cd,db7 */ atp_writew_io(dev, 0, 0x1c, val); - inb(0x80); + udelay(2); val &= 0x00bf; /* no sel */ atp_writew_io(dev, 0, 0x1c, val); - outb(2, 0x80); + udelay(2); break; } while (1) { @@ -1093,18 +1093,18 @@ static void tscam(struct Scsi_Host *host) val &= 0x00ff; /* synchronization */ val |= 0x3f00; fun_scam(dev, &val); - outb(3, 0x80); + udelay(2); val &= 0x00ff; /* isolation */ val |= 0x2000; fun_scam(dev, &val); - outb(4, 0x80); + udelay(2); i = 8; j = 0; while (1) { if ((atp_readw_io(dev, 0, 0x1c) & 0x2000) == 0) continue; - outb(5, 0x80); + udelay(2); val &= 0x00ff; /* get ID_STRING */ val |= 0x2000; k = fun_scam(dev, &val); -- GitLab From c751d9f1fce4187bf1c0848d7d3a5bf7644d7f9c Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:09 +0100 Subject: [PATCH 0634/2855] atp870u: Fix incorrect writeb_io access to register 0x3a The ioport region is 0x20 bytes long so accessing 0x3a register using writeb_io is incorrect. Use writeb_base instead. There's no change in behavior as 870 chips have ioport = baseport. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index c4a59cc0821bd..04b29d3e65d65 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -364,9 +364,9 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) atp_writeb_base(dev, 0x3b, atp_readb_base(dev, 0x3b) & 0x3f); } else { if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) - atp_writeb_io(dev, c, 0x3a, (atp_readb_io(dev, c, 0x3a) & 0xf3) | 0x08); + atp_writeb_base(dev, 0x3a, (atp_readb_base(dev, 0x3a) & 0xf3) | 0x08); else - atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xf3); + atp_writeb_base(dev, 0x3a, atp_readb_base(dev, 0x3a) & 0xf3); } j = 0; id = 1; @@ -889,9 +889,9 @@ static void send_s870(struct atp_unit *dev,unsigned char c) atp_writeb_base(dev, 0x3b, atp_readb_base(dev, 0x3b) & 0x3f); } else { if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) - atp_writeb_io(dev, c, 0x3a, (atp_readb_io(dev, c, 0x3a) & 0xf3) | 0x08); + atp_writeb_base(dev, 0x3a, (atp_readb_base(dev, 0x3a) & 0xf3) | 0x08); else - atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xf3); + atp_writeb_base(dev, 0x3a, atp_readb_base(dev, 0x3a) & 0xf3); } if(workreq->sc_data_direction == DMA_TO_DEVICE) { -- GitLab From 6a1961bc9c8916fc40423cc71e44fd8c59fef360 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:10 +0100 Subject: [PATCH 0635/2855] atp870u: Introduce atp_set_host_id The code for setting host adapter ID is the same for all chips. Move it to a common function. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 57 +++++++++++++----------------------------- 1 file changed, 18 insertions(+), 39 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 04b29d3e65d65..96214035b6d66 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1229,6 +1229,18 @@ static int atp870u_init_tables(struct Scsi_Host *host) return 0; } +static void atp_set_host_id(struct atp_unit *atp, u8 c, u8 host_id) +{ + atp_writeb_io(atp, c, 0, host_id | 0x08); + atp_writeb_io(atp, c, 0x18, 0); + while ((atp_readb_io(atp, c, 0x1f) & 0x80) == 0) + mdelay(1); + atp_readb_io(atp, c, 0x17); + atp_writeb_io(atp, c, 1, 8); + atp_writeb_io(atp, c, 2, 0x7f); + atp_writeb_io(atp, c, 0x11, 0x20); +} + /* return non-zero on detection */ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1379,14 +1391,8 @@ flash_ok_880: mdelay(32); atp_readb_io(p, 0, 0x1b); atp_readb_io(p, 0, 0x17); - atp_writeb_io(p, 0, 0, host_id | 0x08); - atp_writeb_io(p, 0, 0x18, 0); - while ((atp_readb_io(p, 0, 0x1f) & 0x80) == 0) - mdelay(1); - atp_readb_io(p, 0, 0x17); - atp_writeb_io(p, 0, 1, 8); - atp_writeb_io(p, 0, 2, 0x7f); - atp_writeb_io(p, 0, 0x11, 0x20); + + atp_set_host_id(p, 0, host_id); tscam(shpnt); atp_is(p, 0, true, atp_readb_base(p, 0x3f) & 0x40); @@ -1503,35 +1509,16 @@ flash_ok_885: atp_readb_io(p, 0, 0x17); atp_readb_io(p, 1, 0x1b); atp_readb_io(p, 1, 0x17); + k=p->host_id[0]; if (k > 7) k = (k & 0x07) | 0x40; - k |= 0x08; - atp_writeb_io(p, 0, 0, k); - atp_writeb_io(p, 0, 0x18, 0); - - while ((atp_readb_io(p, 0, 0x1f) & 0x80) == 0) - cpu_relax(); - - atp_readb_io(p, 0, 0x17); - atp_writeb_io(p, 0, 1, 8); - atp_writeb_io(p, 0, 2, 0x7f); - atp_writeb_io(p, 0, 0x11, 0x20); + atp_set_host_id(p, 0, k); k=p->host_id[1]; if (k > 7) k = (k & 0x07) | 0x40; - k |= 0x08; - atp_writeb_io(p, 1, 0, k); - atp_writeb_io(p, 1, 0x18, 0); - - while ((atp_readb_io(p, 1, 0x1f) & 0x80) == 0) - cpu_relax(); - - atp_readb_io(p, 1, 0x17); - atp_writeb_io(p, 1, 1, 8); - atp_writeb_io(p, 1, 2, 0x7f); - atp_writeb_io(p, 1, 0x11, 0x20); + atp_set_host_id(p, 1, k); tscam_885(); printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); @@ -1608,15 +1595,7 @@ flash_ok_885: mdelay(32); atp_writeb_base(p, 0x3a, k); mdelay(32); - atp_writeb_io(p, 0, 0, host_id | 0x08); - atp_writeb_io(p, 0, 0x18, 0); - while ((atp_readb_io(p, 0, 0x1f) & 0x80) == 0) - mdelay(1); - - atp_readb_io(p, 0, 0x17); - atp_writeb_io(p, 0, 1, 8); - atp_writeb_io(p, 0, 2, 0x7f); - atp_writeb_io(p, 0, 0x11, 0x20); + atp_set_host_id(p, 0, host_id); tscam(shpnt); atp_writeb_base(p, 0x3a, atp_readb_base(p, 0x3a) | 0x10); -- GitLab From 34a2c35d29a160b326bc63dfbff64ae38fe0a994 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:11 +0100 Subject: [PATCH 0636/2855] atp870u: Reduce log spam on module load/unload Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 96214035b6d66..b662e395b5ea0 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1260,9 +1260,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (pci_enable_device(pdev)) goto err_eio; - if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { - printk(KERN_INFO "atp870u: use 32bit DMA mask.\n"); - } else { + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { printk(KERN_ERR "atp870u: DMA mask required but not available.\n"); goto err_eio; } @@ -1742,12 +1740,9 @@ static void atp870u_remove (struct pci_dev *pdev) scsi_remove_host(pshost); - printk(KERN_INFO "free_irq : %d\n",pshost->irq); free_irq(pshost->irq, pshost); release_region(pshost->io_port, pshost->n_io_port); - printk(KERN_INFO "atp870u_free_tables : %p\n",pshost); atp870u_free_tables(pshost); - printk(KERN_INFO "scsi_host_put : %p\n",pshost); scsi_host_put(pshost); } MODULE_LICENSE("GPL"); -- GitLab From c4ad92bce06bf73946ea4bd5771b987685221e8a Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:12 +0100 Subject: [PATCH 0637/2855] atp870u: Remove empty tscam_885() tscam_885() is empty (except a delay) so remove it. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index b662e395b5ea0..2570919af0e00 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -42,7 +42,6 @@ static struct scsi_host_template atp870u_template; static void send_s870(struct atp_unit *dev,unsigned char c); static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode); -static void tscam_885(void); static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val) { @@ -1518,7 +1517,7 @@ flash_ok_885: k = (k & 0x07) | 0x40; atp_set_host_id(p, 1, k); - tscam_885(); + mdelay(600); /* this delay used to be called tscam_885() */ printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); atp_is(p, 0, true, atp_readb_io(p, 0, 0x1b) >> 7); atp_writeb_io(p, 0, 0x16, 0x80); @@ -1802,18 +1801,6 @@ static void __exit atp870u_exit(void) pci_unregister_driver(&atp870u_driver); } -static void tscam_885(void) -{ - unsigned char i; - - for (i = 0; i < 0x2; i++) { - mdelay(300); - } - return; -} - - - static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode) { unsigned char i, j, k, rmb, n; -- GitLab From 1ccd7d68fc3004e3ed111753e62385176fa28f40 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:13 +0100 Subject: [PATCH 0638/2855] atp870u: Use module_pci_driver Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 2570919af0e00..7f53a50a0ab4a 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1785,21 +1785,7 @@ static struct pci_driver atp870u_driver = { .remove = atp870u_remove, }; -static int __init atp870u_init(void) -{ -#ifdef ED_DBGP - printk("atp870u_init: Entry\n"); -#endif - return pci_register_driver(&atp870u_driver); -} - -static void __exit atp870u_exit(void) -{ -#ifdef ED_DBGP - printk("atp870u_exit: Entry\n"); -#endif - pci_unregister_driver(&atp870u_driver); -} +module_pci_driver(atp870u_driver); static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode) { @@ -2406,7 +2392,3 @@ set_syn_ok: #endif } } - -module_init(atp870u_init); -module_exit(atp870u_exit); - -- GitLab From 30ebc7efcf5cf653ec2f5567d9fce2b4e1247ab7 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:14 +0100 Subject: [PATCH 0639/2855] atp870u: Use n_io_port in request_region and release_region Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 7f53a50a0ab4a..a06a0a4db71cb 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1610,16 +1610,8 @@ flash_ok_885: shpnt->irq = pdev->irq; } spin_unlock_irqrestore(shpnt->host_lock, flags); - if(ent->device==ATP885_DEVID) { - if(!request_region(base_io, 0xff, "atp870u")) /* Register the IO ports that we use */ - goto request_io_fail; - } else if((ent->device==ATP880_DEVID1)||(ent->device==ATP880_DEVID2)) { - if(!request_region(base_io, 0x60, "atp870u")) /* Register the IO ports that we use */ - goto request_io_fail; - } else { - if(!request_region(base_io, 0x40, "atp870u")) /* Register the IO ports that we use */ - goto request_io_fail; - } + if (!request_region(base_io, shpnt->n_io_port, "atp870u")) + goto request_io_fail; count++; if (scsi_add_host(shpnt, &pdev->dev)) goto scsi_add_fail; @@ -1631,13 +1623,7 @@ flash_ok_885: scsi_add_fail: printk("atp870u_prob:scsi_add_fail\n"); - if(ent->device==ATP885_DEVID) { - release_region(base_io, 0xff); - } else if((ent->device==ATP880_DEVID1)||(ent->device==ATP880_DEVID2)) { - release_region(base_io, 0x60); - } else { - release_region(base_io, 0x40); - } + release_region(base_io, shpnt->n_io_port); request_io_fail: printk("atp870u_prob:request_io_fail\n"); free_irq(pdev->irq, shpnt); -- GitLab From c48442d1277a9b9e20ad38c29ca68485b921d4e9 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:15 +0100 Subject: [PATCH 0640/2855] atp870u: Remove useless and broken card counting Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index a06a0a4db71cb..0b349bc4e6e62 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1250,7 +1250,6 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct Scsi_Host *shpnt = NULL; struct atp_unit *atpdev, *p; unsigned char setupdata[2][16]; - int count = 0; atpdev = kzalloc(sizeof(*atpdev), GFP_KERNEL); if (!atpdev) @@ -1298,8 +1297,8 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) host_id = atp_readb_base(atpdev, 0x39); host_id >>= 0x04; - printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d" - " IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); + printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter:" + " IO:%x, IRQ:%d.\n", base_io, pdev->irq); atpdev->dev_id = ent->device; atpdev->host_id[0] = host_id; @@ -1546,8 +1545,8 @@ flash_ok_885: } else { error = pci_read_config_byte(pdev, 0x49, &host_id); - printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: %d " - "IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); + printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: " + "IO:%x, IRQ:%d.\n", base_io, pdev->irq); atpdev->ioport[0] = base_io; atpdev->pciport[0] = base_io + 0x20; @@ -1612,7 +1611,6 @@ flash_ok_885: spin_unlock_irqrestore(shpnt->host_lock, flags); if (!request_region(base_io, shpnt->n_io_port, "atp870u")) goto request_io_fail; - count++; if (scsi_add_host(shpnt, &pdev->dev)) goto scsi_add_fail; scsi_scan_host(shpnt); -- GitLab From e1e9a70642309020571a07b2918eca84cec6287a Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:16 +0100 Subject: [PATCH 0641/2855] atp870u: Remove unused irq from struct atp_unit Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h index 5cf62566ad428..c3c6c13685d41 100644 --- a/drivers/scsi/atp870u.h +++ b/drivers/scsi/atp870u.h @@ -26,7 +26,6 @@ struct atp_unit unsigned long baseport; unsigned long ioport[2]; unsigned long pciport[2]; - unsigned long irq; unsigned char last_cmd[2]; unsigned char in_snd[2]; unsigned char in_int[2]; -- GitLab From bdd5ac4065dbc2bb1478ae0c9205a651487c7432 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:17 +0100 Subject: [PATCH 0642/2855] atp870u: Improve _probe() Move scsi_host_alloc() to the top of _probe() to remove code duplication, *p and unneeded atpdev (de)allocation and copying. While at it, fix the error paths to return real error codes and also add missing pci_disble_device() call. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 236 ++++++++++++++++++++--------------------- 1 file changed, 113 insertions(+), 123 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 0b349bc4e6e62..d0119f1731950 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1248,29 +1248,41 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) unsigned int base_io, error,n; unsigned char host_id; struct Scsi_Host *shpnt = NULL; - struct atp_unit *atpdev, *p; + struct atp_unit *atpdev; unsigned char setupdata[2][16]; + int err; - atpdev = kzalloc(sizeof(*atpdev), GFP_KERNEL); - if (!atpdev) - return -ENOMEM; - - if (pci_enable_device(pdev)) - goto err_eio; + err = pci_enable_device(pdev); + if (err) + goto fail; if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { printk(KERN_ERR "atp870u: DMA mask required but not available.\n"); - goto err_eio; + err = -EIO; + goto disable_device; } + err = -ENOMEM; + shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); + if (!shpnt) + goto disable_device; + + atpdev = shost_priv(shpnt); + + atpdev->host = shpnt; + atpdev->pdev = pdev; + pci_set_drvdata(pdev, atpdev); + /* * It's probably easier to weed out some revisions like * this than via the PCI device table */ if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) { atpdev->chip_ver = pdev->revision; - if (atpdev->chip_ver < 2) - goto err_eio; + if (atpdev->chip_ver < 2) { + err = -ENODEV; + goto unregister; + } } switch (ent->device) { @@ -1358,41 +1370,33 @@ flash_ok_880: atpdev->async[0] = ~(atpdev->async[0]); atp_writeb_base(atpdev, 0x35, atpdev->global_map[0]); - shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); - if (!shpnt) - goto err_nomem; - - p = (struct atp_unit *)&shpnt->hostdata; - - atpdev->host = shpnt; - atpdev->pdev = pdev; - pci_set_drvdata(pdev, p); - memcpy(p, atpdev, sizeof(*atpdev)); if (atp870u_init_tables(shpnt) < 0) { printk(KERN_ERR "Unable to allocate tables for Acard controller\n"); + err = -ENOMEM; goto unregister; } - if (request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp880i", shpnt)) { + err = request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp880i", shpnt); + if (err) { printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq); goto free_tables; } spin_lock_irqsave(shpnt->host_lock, flags); - k = atp_readb_base(p, 0x38) & 0x80; - atp_writeb_base(p, 0x38, k); - atp_writeb_base(p, 0x3b, 0x20); + k = atp_readb_base(atpdev, 0x38) & 0x80; + atp_writeb_base(atpdev, 0x38, k); + atp_writeb_base(atpdev, 0x3b, 0x20); mdelay(32); - atp_writeb_base(p, 0x3b, 0); + atp_writeb_base(atpdev, 0x3b, 0); mdelay(32); - atp_readb_io(p, 0, 0x1b); - atp_readb_io(p, 0, 0x17); + atp_readb_io(atpdev, 0, 0x1b); + atp_readb_io(atpdev, 0, 0x17); - atp_set_host_id(p, 0, host_id); + atp_set_host_id(atpdev, 0, host_id); tscam(shpnt); - atp_is(p, 0, true, atp_readb_base(p, 0x3f) & 0x40); - atp_writeb_base(p, 0x38, 0xb0); + atp_is(atpdev, 0, true, atp_readb_base(atpdev, 0x3f) & 0x40); + atp_writeb_base(atpdev, 0x38, 0xb0); shpnt->max_id = 16; shpnt->this_id = host_id; shpnt->unique_id = base_io; @@ -1410,50 +1414,43 @@ flash_ok_880: atpdev->pciport[0] = base_io + 0x40; atpdev->pciport[1] = base_io + 0x50; - shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); - if (!shpnt) - goto err_nomem; - - p = (struct atp_unit *)&shpnt->hostdata; - - atpdev->host = shpnt; - atpdev->pdev = pdev; - pci_set_drvdata(pdev, p); - memcpy(p, atpdev, sizeof(struct atp_unit)); - if (atp870u_init_tables(shpnt) < 0) + if (atp870u_init_tables(shpnt) < 0) { + err = -ENOMEM; goto unregister; + } #ifdef ED_DBGP - printk("request_irq() shpnt %p hostdata %p\n", shpnt, p); + printk("request_irq() shpnt %p hostdata %p\n", shpnt, atpdev); #endif - if (request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt)) { + err = request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt); + if (err) { printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n"); goto free_tables; } spin_lock_irqsave(shpnt->host_lock, flags); - c = atp_readb_base(p, 0x29); - atp_writeb_base(p, 0x29, c | 0x04); + c = atp_readb_base(atpdev, 0x29); + atp_writeb_base(atpdev, 0x29, c | 0x04); n=0x1f80; next_fblk_885: if (n >= 0x2000) { goto flash_ok_885; } - atp_writew_base(p, 0x3c, n); - if (atp_readl_base(p, 0x38) == 0xffffffff) { + atp_writew_base(atpdev, 0x3c, n); + if (atp_readl_base(atpdev, 0x38) == 0xffffffff) { goto flash_ok_885; } for (m=0; m < 2; m++) { - p->global_map[m]= 0; + atpdev->global_map[m]= 0; for (k=0; k < 4; k++) { - atp_writew_base(p, 0x3c, n++); - ((unsigned long *)&setupdata[m][0])[k] = atp_readl_base(p, 0x38); + atp_writew_base(atpdev, 0x3c, n++); + ((unsigned long *)&setupdata[m][0])[k] = atp_readl_base(atpdev, 0x38); } for (k=0; k < 4; k++) { - atp_writew_base(p, 0x3c, n++); - ((unsigned long *)&p->sp[m][0])[k] = atp_readl_base(p, 0x38); + atp_writew_base(atpdev, 0x3c, n++); + ((unsigned long *)&atpdev->sp[m][0])[k] = atp_readl_base(atpdev, 0x38); } n += 8; } @@ -1462,81 +1459,81 @@ flash_ok_885: #ifdef ED_DBGP printk( "Flash Read OK\n"); #endif - c = atp_readb_base(p, 0x29); - atp_writeb_base(p, 0x29, c & 0xfb); + c = atp_readb_base(atpdev, 0x29); + atp_writeb_base(atpdev, 0x29, c & 0xfb); for (c=0;c < 2;c++) { - p->ultra_map[c]=0; - p->async[c] = 0; + atpdev->ultra_map[c]=0; + atpdev->async[c] = 0; for (k=0; k < 16; k++) { n=1; n = n << k; - if (p->sp[c][k] > 1) { - p->ultra_map[c] |= n; + if (atpdev->sp[c][k] > 1) { + atpdev->ultra_map[c] |= n; } else { - if (p->sp[c][k] == 0) { - p->async[c] |= n; + if (atpdev->sp[c][k] == 0) { + atpdev->async[c] |= n; } } } - p->async[c] = ~(p->async[c]); + atpdev->async[c] = ~(atpdev->async[c]); - if (p->global_map[c] == 0) { + if (atpdev->global_map[c] == 0) { k=setupdata[c][1]; if ((k & 0x40) != 0) - p->global_map[c] |= 0x20; + atpdev->global_map[c] |= 0x20; k &= 0x07; - p->global_map[c] |= k; + atpdev->global_map[c] |= k; if ((setupdata[c][2] & 0x04) != 0) - p->global_map[c] |= 0x08; - p->host_id[c] = setupdata[c][0] & 0x07; + atpdev->global_map[c] |= 0x08; + atpdev->host_id[c] = setupdata[c][0] & 0x07; } } - k = atp_readb_base(p, 0x28) & 0x8f; + k = atp_readb_base(atpdev, 0x28) & 0x8f; k |= 0x10; - atp_writeb_base(p, 0x28, k); - atp_writeb_pci(p, 0, 1, 0x80); - atp_writeb_pci(p, 1, 1, 0x80); + atp_writeb_base(atpdev, 0x28, k); + atp_writeb_pci(atpdev, 0, 1, 0x80); + atp_writeb_pci(atpdev, 1, 1, 0x80); mdelay(100); - atp_writeb_pci(p, 0, 1, 0); - atp_writeb_pci(p, 1, 1, 0); + atp_writeb_pci(atpdev, 0, 1, 0); + atp_writeb_pci(atpdev, 1, 1, 0); mdelay(1000); - atp_readb_io(p, 0, 0x1b); - atp_readb_io(p, 0, 0x17); - atp_readb_io(p, 1, 0x1b); - atp_readb_io(p, 1, 0x17); + atp_readb_io(atpdev, 0, 0x1b); + atp_readb_io(atpdev, 0, 0x17); + atp_readb_io(atpdev, 1, 0x1b); + atp_readb_io(atpdev, 1, 0x17); - k=p->host_id[0]; + k=atpdev->host_id[0]; if (k > 7) k = (k & 0x07) | 0x40; - atp_set_host_id(p, 0, k); + atp_set_host_id(atpdev, 0, k); - k=p->host_id[1]; + k=atpdev->host_id[1]; if (k > 7) k = (k & 0x07) | 0x40; - atp_set_host_id(p, 1, k); + atp_set_host_id(atpdev, 1, k); mdelay(600); /* this delay used to be called tscam_885() */ printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); - atp_is(p, 0, true, atp_readb_io(p, 0, 0x1b) >> 7); - atp_writeb_io(p, 0, 0x16, 0x80); + atp_is(atpdev, 0, true, atp_readb_io(atpdev, 0, 0x1b) >> 7); + atp_writeb_io(atpdev, 0, 0x16, 0x80); printk(KERN_INFO " Scanning Channel B SCSI Device ...\n"); - atp_is(p, 1, true, atp_readb_io(p, 1, 0x1b) >> 7); - atp_writeb_io(p, 1, 0x16, 0x80); - k = atp_readb_base(p, 0x28) & 0xcf; + atp_is(atpdev, 1, true, atp_readb_io(atpdev, 1, 0x1b) >> 7); + atp_writeb_io(atpdev, 1, 0x16, 0x80); + k = atp_readb_base(atpdev, 0x28) & 0xcf; k |= 0xc0; - atp_writeb_base(p, 0x28, k); - k = atp_readb_base(p, 0x1f) | 0x80; - atp_writeb_base(p, 0x1f, k); - k = atp_readb_base(p, 0x29) | 0x01; - atp_writeb_base(p, 0x29, k); + atp_writeb_base(atpdev, 0x28, k); + k = atp_readb_base(atpdev, 0x1f) | 0x80; + atp_writeb_base(atpdev, 0x1f, k); + k = atp_readb_base(atpdev, 0x29) | 0x01; + atp_writeb_base(atpdev, 0x29, k); #ifdef ED_DBGP //printk("atp885: atp_host[0] 0x%p\n", atp_host[0]); #endif shpnt->max_id = 16; - shpnt->max_lun = (p->global_map[0] & 0x07) + 1; + shpnt->max_lun = (atpdev->global_map[0] & 0x07) + 1; shpnt->max_channel = 1; - shpnt->this_id = p->host_id[0]; + shpnt->this_id = atpdev->host_id[0]; shpnt->unique_id = base_io; shpnt->io_port = base_io; shpnt->n_io_port = 0xff; /* Number of bytes of I/O space used */ @@ -1563,41 +1560,35 @@ flash_ok_885: atpdev->ultra_map[0] = 0xffff; } - shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); - if (!shpnt) - goto err_nomem; - p = (struct atp_unit *)&shpnt->hostdata; - - atpdev->host = shpnt; - atpdev->pdev = pdev; - pci_set_drvdata(pdev, p); - memcpy(p, atpdev, sizeof(*atpdev)); - if (atp870u_init_tables(shpnt) < 0) + if (atp870u_init_tables(shpnt) < 0) { + err = -ENOMEM; goto unregister; + } - if (request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp870i", shpnt)) { + err = request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp870i", shpnt); + if (err) { printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq); goto free_tables; } spin_lock_irqsave(shpnt->host_lock, flags); if (atpdev->chip_ver > 0x07) /* check if atp876 chip then enable terminator */ - atp_writeb_base(p, 0x3e, 0x00); + atp_writeb_base(atpdev, 0x3e, 0x00); - k = (atp_readb_base(p, 0x3a) & 0xf3) | 0x10; - atp_writeb_base(p, 0x3a, k); - atp_writeb_base(p, 0x3a, k & 0xdf); + k = (atp_readb_base(atpdev, 0x3a) & 0xf3) | 0x10; + atp_writeb_base(atpdev, 0x3a, k); + atp_writeb_base(atpdev, 0x3a, k & 0xdf); mdelay(32); - atp_writeb_base(p, 0x3a, k); + atp_writeb_base(atpdev, 0x3a, k); mdelay(32); - atp_set_host_id(p, 0, host_id); + atp_set_host_id(atpdev, 0, host_id); tscam(shpnt); - atp_writeb_base(p, 0x3a, atp_readb_base(p, 0x3a) | 0x10); - atp_is(p, 0, p->chip_ver == 4, 0); - atp_writeb_base(p, 0x3a, atp_readb_base(p, 0x3a) & 0xef); - atp_writeb_base(p, 0x3b, atp_readb_base(p, 0x3b) | 0x20); + atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) | 0x10); + atp_is(atpdev, 0, atpdev->chip_ver == 4, 0); + atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) & 0xef); + atp_writeb_base(atpdev, 0x3b, atp_readb_base(atpdev, 0x3b) | 0x20); if (atpdev->chip_ver == 4) shpnt->max_id = 16; else @@ -1609,9 +1600,12 @@ flash_ok_885: shpnt->irq = pdev->irq; } spin_unlock_irqrestore(shpnt->host_lock, flags); - if (!request_region(base_io, shpnt->n_io_port, "atp870u")) + if (!request_region(base_io, shpnt->n_io_port, "atp870u")) { + err = -EBUSY; goto request_io_fail; - if (scsi_add_host(shpnt, &pdev->dev)) + } + err = scsi_add_host(shpnt, &pdev->dev); + if (err) goto scsi_add_fail; scsi_scan_host(shpnt); #ifdef ED_DBGP @@ -1629,15 +1623,11 @@ free_tables: printk("atp870u_prob:free_table\n"); atp870u_free_tables(shpnt); unregister: - printk("atp870u_prob:unregister\n"); scsi_host_put(shpnt); - return -1; -err_eio: - kfree(atpdev); - return -EIO; -err_nomem: - kfree(atpdev); - return -ENOMEM; +disable_device: + pci_disable_device(pdev); +fail: + return err; } /* The abort command does not leave the device in a clean state where -- GitLab From b1e850630b746e347f80cb3f70bdaa791c10b4f6 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:18 +0100 Subject: [PATCH 0643/2855] atp870u: Improve unsupported chip detection Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index d0119f1731950..128613e88dfbe 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1252,6 +1252,11 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) unsigned char setupdata[2][16]; int err; + if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610 && pdev->revision < 2) { + dev_err(&pdev->dev, "ATP850S chips (AEC6710L/F cards) are not supported.\n"); + return -ENODEV; + } + err = pci_enable_device(pdev); if (err) goto fail; @@ -1273,19 +1278,10 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) atpdev->pdev = pdev; pci_set_drvdata(pdev, atpdev); - /* - * It's probably easier to weed out some revisions like - * this than via the PCI device table - */ - if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) { - atpdev->chip_ver = pdev->revision; - if (atpdev->chip_ver < 2) { - err = -ENODEV; - goto unregister; - } - } - switch (ent->device) { + case PCI_DEVICE_ID_ARTOP_AEC7610: + atpdev->chip_ver = pdev->revision; + break; case PCI_DEVICE_ID_ARTOP_AEC7612UW: case PCI_DEVICE_ID_ARTOP_AEC7612SUW: case ATP880_DEVID1: -- GitLab From dd5a5f7951e253b81ac480a63dfd8b826a9ef61e Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:19 +0100 Subject: [PATCH 0644/2855] atp870u: Remove chip_ver from struct atp_unit chip_ver is used for wide chip detection only. Remove it and use a local variable instead (for 870; 880 and 885 are always wide). Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 39 ++++++++++++++------------------------- drivers/scsi/atp870u.h | 1 - 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 128613e88dfbe..f92eb008cb8c6 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -954,7 +954,7 @@ static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val) return j; } -static void tscam(struct Scsi_Host *host) +static void tscam(struct Scsi_Host *host, bool wide_chip) { unsigned char i, j, k; @@ -983,7 +983,7 @@ static void tscam(struct Scsi_Host *host) m = 1; m <<= dev->host_id[0]; j = 16; - if (dev->chip_ver < 4) { + if (!wide_chip) { m |= 0xff00; j = 8; } @@ -1012,7 +1012,7 @@ static void tscam(struct Scsi_Host *host) k = i; } atp_writeb_io(dev, 0, 0x15, k); - if (dev->chip_ver == 4) + if (wide_chip) atp_writeb_io(dev, 0, 0x1b, 0x01); else atp_writeb_io(dev, 0, 0x1b, 0x00); @@ -1278,25 +1278,11 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) atpdev->pdev = pdev; pci_set_drvdata(pdev, atpdev); - switch (ent->device) { - case PCI_DEVICE_ID_ARTOP_AEC7610: - atpdev->chip_ver = pdev->revision; - break; - case PCI_DEVICE_ID_ARTOP_AEC7612UW: - case PCI_DEVICE_ID_ARTOP_AEC7612SUW: - case ATP880_DEVID1: - case ATP880_DEVID2: - case ATP885_DEVID: - atpdev->chip_ver = 0x04; - default: - break; - } base_io = pci_resource_start(pdev, 0); base_io &= 0xfffffff8; atpdev->baseport = base_io; if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { - atpdev->chip_ver = pdev->revision; pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 atpdev->ioport[0] = base_io + 0x40; @@ -1390,7 +1376,7 @@ flash_ok_880: atp_set_host_id(atpdev, 0, host_id); - tscam(shpnt); + tscam(shpnt, true); atp_is(atpdev, 0, true, atp_readb_base(atpdev, 0x3f) & 0x40); atp_writeb_base(atpdev, 0x38, 0xb0); shpnt->max_id = 16; @@ -1536,6 +1522,11 @@ flash_ok_885: shpnt->irq = pdev->irq; } else { + bool wide_chip = + (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610 && + pdev->revision == 4) || + (ent->device == PCI_DEVICE_ID_ARTOP_AEC7612UW) || + (ent->device == PCI_DEVICE_ID_ARTOP_AEC7612SUW); error = pci_read_config_byte(pdev, 0x49, &host_id); printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: " @@ -1569,7 +1560,7 @@ flash_ok_885: } spin_lock_irqsave(shpnt->host_lock, flags); - if (atpdev->chip_ver > 0x07) /* check if atp876 chip then enable terminator */ + if (pdev->revision > 0x07) /* check if atp876 chip then enable terminator */ atp_writeb_base(atpdev, 0x3e, 0x00); k = (atp_readb_base(atpdev, 0x3a) & 0xf3) | 0x10; @@ -1580,15 +1571,13 @@ flash_ok_885: mdelay(32); atp_set_host_id(atpdev, 0, host_id); - tscam(shpnt); + + tscam(shpnt, wide_chip); atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) | 0x10); - atp_is(atpdev, 0, atpdev->chip_ver == 4, 0); + atp_is(atpdev, 0, wide_chip, 0); atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) & 0xef); atp_writeb_base(atpdev, 0x3b, atp_readb_base(atpdev, 0x3b) | 0x20); - if (atpdev->chip_ver == 4) - shpnt->max_id = 16; - else - shpnt->max_id = 8; + shpnt->max_id = wide_chip ? 16 : 8; shpnt->this_id = host_id; shpnt->unique_id = base_io; shpnt->io_port = base_io; diff --git a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h index c3c6c13685d41..8c47c53aee7f5 100644 --- a/drivers/scsi/atp870u.h +++ b/drivers/scsi/atp870u.h @@ -32,7 +32,6 @@ struct atp_unit unsigned char quhd[2]; unsigned char quend[2]; unsigned char global_map[2]; - unsigned char chip_ver; unsigned char scam_on; unsigned char host_id[2]; unsigned int working[2]; -- GitLab From 6c9b9c554b2a369d2b46558975ef2eaa3a84c1c3 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:20 +0100 Subject: [PATCH 0645/2855] atp870u: Simplify _probe() Move shpnt common code to the top, remove base_io, use pci_resource_len. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 65 ++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 37 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index f92eb008cb8c6..8af51a97185af 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1245,7 +1245,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { unsigned char k, m, c; unsigned long flags; - unsigned int base_io, error,n; + unsigned int error,n; unsigned char host_id; struct Scsi_Host *shpnt = NULL; struct atp_unit *atpdev; @@ -1278,21 +1278,24 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) atpdev->pdev = pdev; pci_set_drvdata(pdev, atpdev); - base_io = pci_resource_start(pdev, 0); - base_io &= 0xfffffff8; - atpdev->baseport = base_io; + shpnt->io_port = pci_resource_start(pdev, 0); + shpnt->io_port &= 0xfffffff8; + shpnt->n_io_port = pci_resource_len(pdev, 0); + atpdev->baseport = shpnt->io_port; + shpnt->unique_id = shpnt->io_port; + shpnt->irq = pdev->irq; if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 - atpdev->ioport[0] = base_io + 0x40; - atpdev->pciport[0] = base_io + 0x28; + atpdev->ioport[0] = shpnt->io_port + 0x40; + atpdev->pciport[0] = shpnt->io_port + 0x28; host_id = atp_readb_base(atpdev, 0x39); host_id >>= 0x04; printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter:" - " IO:%x, IRQ:%d.\n", base_io, pdev->irq); + " IO:%lx, IRQ:%d.\n", shpnt->io_port, shpnt->irq); atpdev->dev_id = ent->device; atpdev->host_id[0] = host_id; @@ -1358,9 +1361,9 @@ flash_ok_880: goto unregister; } - err = request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp880i", shpnt); + err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp880i", shpnt); if (err) { - printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq); + printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", shpnt->irq); goto free_tables; } @@ -1381,20 +1384,16 @@ flash_ok_880: atp_writeb_base(atpdev, 0x38, 0xb0); shpnt->max_id = 16; shpnt->this_id = host_id; - shpnt->unique_id = base_io; - shpnt->io_port = base_io; - shpnt->n_io_port = 0x60; /* Number of bytes of I/O space used */ - shpnt->irq = pdev->irq; } else if (ent->device == ATP885_DEVID) { - printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%x, IRQ:%d.\n" - , base_io, pdev->irq); + printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%lx, IRQ:%d.\n" + , shpnt->io_port, shpnt->irq); atpdev->pdev = pdev; atpdev->dev_id = ent->device; - atpdev->ioport[0] = base_io + 0x80; - atpdev->ioport[1] = base_io + 0xc0; - atpdev->pciport[0] = base_io + 0x40; - atpdev->pciport[1] = base_io + 0x50; + atpdev->ioport[0] = shpnt->io_port + 0x80; + atpdev->ioport[1] = shpnt->io_port + 0xc0; + atpdev->pciport[0] = shpnt->io_port + 0x40; + atpdev->pciport[1] = shpnt->io_port + 0x50; if (atp870u_init_tables(shpnt) < 0) { err = -ENOMEM; @@ -1404,7 +1403,7 @@ flash_ok_880: #ifdef ED_DBGP printk("request_irq() shpnt %p hostdata %p\n", shpnt, atpdev); #endif - err = request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt); + err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt); if (err) { printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n"); goto free_tables; @@ -1516,11 +1515,6 @@ flash_ok_885: shpnt->max_lun = (atpdev->global_map[0] & 0x07) + 1; shpnt->max_channel = 1; shpnt->this_id = atpdev->host_id[0]; - shpnt->unique_id = base_io; - shpnt->io_port = base_io; - shpnt->n_io_port = 0xff; /* Number of bytes of I/O space used */ - shpnt->irq = pdev->irq; - } else { bool wide_chip = (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610 && @@ -1530,10 +1524,10 @@ flash_ok_885: error = pci_read_config_byte(pdev, 0x49, &host_id); printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: " - "IO:%x, IRQ:%d.\n", base_io, pdev->irq); + "IO:%lx, IRQ:%d.\n", shpnt->io_port, shpnt->irq); - atpdev->ioport[0] = base_io; - atpdev->pciport[0] = base_io + 0x20; + atpdev->ioport[0] = shpnt->io_port; + atpdev->pciport[0] = shpnt->io_port + 0x20; atpdev->dev_id = ent->device; host_id &= 0x07; atpdev->host_id[0] = host_id; @@ -1553,9 +1547,9 @@ flash_ok_885: goto unregister; } - err = request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp870i", shpnt); + err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp870i", shpnt); if (err) { - printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq); + printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", shpnt->irq); goto free_tables; } @@ -1579,13 +1573,10 @@ flash_ok_885: atp_writeb_base(atpdev, 0x3b, atp_readb_base(atpdev, 0x3b) | 0x20); shpnt->max_id = wide_chip ? 16 : 8; shpnt->this_id = host_id; - shpnt->unique_id = base_io; - shpnt->io_port = base_io; - shpnt->n_io_port = 0x40; /* Number of bytes of I/O space used */ - shpnt->irq = pdev->irq; + } spin_unlock_irqrestore(shpnt->host_lock, flags); - if (!request_region(base_io, shpnt->n_io_port, "atp870u")) { + if (!request_region(shpnt->io_port, shpnt->n_io_port, "atp870u")) { err = -EBUSY; goto request_io_fail; } @@ -1600,10 +1591,10 @@ flash_ok_885: scsi_add_fail: printk("atp870u_prob:scsi_add_fail\n"); - release_region(base_io, shpnt->n_io_port); + release_region(shpnt->io_port, shpnt->n_io_port); request_io_fail: printk("atp870u_prob:request_io_fail\n"); - free_irq(pdev->irq, shpnt); + free_irq(shpnt->irq, shpnt); free_tables: printk("atp870u_prob:free_table\n"); atp870u_free_tables(shpnt); -- GitLab From b922a44995a6e94560aa3eae0602bf92a4e7b084 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:21 +0100 Subject: [PATCH 0646/2855] atp870u: Introduce is880(), is885() and remove dev_id Introduce chip type inline functions to simplify code, allowing to delete dev_id from struct atp_unit. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 70 +++++++++++++++++++++++------------------- drivers/scsi/atp870u.h | 1 - 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 8af51a97185af..4bb0f4fcd9dfb 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -103,6 +103,17 @@ static inline u8 atp_readb_pci(struct atp_unit *atp, u8 channel, u8 reg) return inb(atp->pciport[channel] + reg); } +static inline bool is880(struct atp_unit *atp) +{ + return atp->pdev->device == ATP880_DEVID1 || + atp->pdev->device == ATP880_DEVID2; +} + +static inline bool is885(struct atp_unit *atp) +{ + return atp->pdev->device == ATP885_DEVID; +} + static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) { unsigned long flags; @@ -131,7 +142,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) dev->in_int[c] = 1; cmdp = atp_readb_io(dev, c, 0x10); if (dev->working[c] != 0) { - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { if ((atp_readb_io(dev, c, 0x16) & 0x80) == 0) atp_writeb_io(dev, c, 0x16, (atp_readb_io(dev, c, 0x16) | 0x80)); } @@ -148,7 +159,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) i = atp_readb_io(dev, c, 0x17); - if (dev->dev_id == ATP885_DEVID) + if (is885(dev)) atp_writeb_pci(dev, c, 2, 0x06); target_id = atp_readb_io(dev, c, 0x15); @@ -169,7 +180,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) } dev->last_cmd[c] |= 0x40; } - if (dev->dev_id == ATP885_DEVID) + if (is885(dev)) dev->r1f[c][target_id] |= j; #ifdef ED_DBGP printk("atp870u_intr_handle status = %x\n",i); @@ -178,7 +189,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) if ((dev->last_cmd[c] & 0xf0) != 0x40) { dev->last_cmd[c] = 0xff; } - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { adrcnt = 0; ((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12); ((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13); @@ -249,7 +260,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) return IRQ_HANDLED; } - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { if ((i == 0x4c) || (i == 0x4d) || (i == 0x8c) || (i == 0x8d)) { if ((i == 0x4c) || (i == 0x8c)) i=0x48; @@ -301,7 +312,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) if (dev->last_cmd[c] != 0xff) { dev->last_cmd[c] |= 0x40; } - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { j = atp_readb_base(dev, 0x29) & 0xfe; atp_writeb_base(dev, 0x29, j); } else @@ -316,7 +327,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) } else { target_id &= 0x07; } - if (dev->dev_id == ATP885_DEVID) + if (is885(dev)) atp_writeb_io(dev, c, 0x10, 0x45); workreq = dev->id[c][target_id].curr_req; #ifdef ED_DBGP @@ -348,15 +359,14 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) atp_writeb_io(dev, c, 0x16, 0x80); /* enable 32 bit fifo transfer */ - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { i = atp_readb_pci(dev, c, 1) & 0xf3; //j=workreq->cmnd[0]; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { i |= 0x0c; } atp_writeb_pci(dev, c, 1, i); - } else if ((dev->dev_id == ATP880_DEVID1) || - (dev->dev_id == ATP880_DEVID2) ) { + } else if (is880(dev)) { if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) atp_writeb_base(dev, 0x3b, (atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0); else @@ -417,7 +427,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) #ifdef ED_DBGP printk("dev->id[%d][%d].prdaddr 0x%8x\n", c, target_id, dev->id[c][target_id].prdaddr); #endif - if (dev->dev_id != ATP885_DEVID) { + if (!is885(dev)) { atp_writeb_pci(dev, c, 2, 0x06); atp_writeb_pci(dev, c, 2, 0x00); } @@ -454,14 +464,14 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) } if (i == 0x16) { workreq->result = atp_readb_io(dev, c, 0x0f); - if (((dev->r1f[c][target_id] & 0x10) != 0)&&(dev->dev_id==ATP885_DEVID)) { + if (((dev->r1f[c][target_id] & 0x10) != 0) && is885(dev)) { printk(KERN_WARNING "AEC67162 CRC ERROR !\n"); workreq->result = 0x02; } } else workreq->result = 0x02; - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { j = atp_readb_base(dev, 0x29) | 0x01; atp_writeb_base(dev, 0x29, j); } @@ -516,7 +526,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) atp_writeb_pci(dev, c, 2, 0x06); atp_writeb_pci(dev, c, 2, 0x00); atp_writeb_io(dev, c, 0x10, 0x41); - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { k = dev->id[c][target_id].last_len; atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&k))[2]); atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&k))[1]); @@ -535,7 +545,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) atp_writeb_pci(dev, c, 2, 0x06); atp_writeb_pci(dev, c, 2, 0x00); atp_writeb_io(dev, c, 0x10, 0x41); - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { k = dev->id[c][target_id].last_len; atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&k))[2]); atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&k))[1]); @@ -737,7 +747,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c) #endif l = scsi_bufflen(workreq); - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { j = atp_readb_base(dev, 0x29) & 0xfe; atp_writeb_base(dev, 0x29, j); dev->r1f[c][scmd_id(workreq)] = 0; @@ -775,7 +785,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c) atp_writeb_io(dev, c, 0x00, workreq->cmd_len); atp_writeb_io(dev, c, 0x01, 0x2c); - if (dev->dev_id == ATP885_DEVID) + if (is885(dev)) atp_writeb_io(dev, c, 0x02, 0x7f); else atp_writeb_io(dev, c, 0x02, 0xcf); @@ -873,15 +883,14 @@ static void send_s870(struct atp_unit *dev,unsigned char c) atp_writel_pci(dev, c, 4, dev->id[c][target_id].prdaddr); atp_writeb_pci(dev, c, 2, 0x06); atp_writeb_pci(dev, c, 2, 0x00); - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { j = atp_readb_pci(dev, c, 1) & 0xf3; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { j |= 0x0c; } atp_writeb_pci(dev, c, 1, j); - } else if ((dev->dev_id == ATP880_DEVID1) || - (dev->dev_id == ATP880_DEVID2)) { + } else if (is880(dev)) { if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) atp_writeb_base(dev, 0x3b, (atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0); else @@ -1285,7 +1294,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) shpnt->unique_id = shpnt->io_port; shpnt->irq = pdev->irq; - if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { + if (is880(atpdev)) { pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 atpdev->ioport[0] = shpnt->io_port + 0x40; @@ -1296,7 +1305,6 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter:" " IO:%lx, IRQ:%d.\n", shpnt->io_port, shpnt->irq); - atpdev->dev_id = ent->device; atpdev->host_id[0] = host_id; atpdev->scam_on = atp_readb_base(atpdev, 0x22); @@ -1384,12 +1392,11 @@ flash_ok_880: atp_writeb_base(atpdev, 0x38, 0xb0); shpnt->max_id = 16; shpnt->this_id = host_id; - } else if (ent->device == ATP885_DEVID) { + } else if (is885(atpdev)) { printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%lx, IRQ:%d.\n" , shpnt->io_port, shpnt->irq); atpdev->pdev = pdev; - atpdev->dev_id = ent->device; atpdev->ioport[0] = shpnt->io_port + 0x80; atpdev->ioport[1] = shpnt->io_port + 0xc0; atpdev->pciport[0] = shpnt->io_port + 0x40; @@ -1528,7 +1535,6 @@ flash_ok_885: atpdev->ioport[0] = shpnt->io_port; atpdev->pciport[0] = shpnt->io_port + 0x20; - atpdev->dev_id = ent->device; host_id &= 0x07; atpdev->host_id[0] = host_id; atpdev->scam_on = atp_readb_pci(atpdev, 0, 2); @@ -1797,7 +1803,7 @@ static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsign dev->active_id[c] |= m; atp_writeb_io(dev, c, 0x10, 0x30); - if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) + if (is885(dev) || is880(dev)) atp_writeb_io(dev, c, 0x14, 0x00); else /* result of is870() merge - is this a bug? */ atp_writeb_io(dev, c, 0x04, 0x00); @@ -1877,7 +1883,7 @@ inq_ok: if ((mbuf[7] & 0x60) == 0) { goto not_wide; } - if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) { + if (is885(dev) || is880(dev)) { if ((i < 8) && ((dev->global_map[c] & 0x20) == 0)) goto not_wide; } else { /* result of is870() merge - is this a bug? */ @@ -2146,7 +2152,7 @@ not_wide: } continue; set_sync: - if ((dev->dev_id != ATP885_DEVID && dev->dev_id != ATP880_DEVID1 && dev->dev_id != ATP880_DEVID2) || (dev->sp[c][i] == 0x02)) { + if ((!is885(dev) && !is880(dev)) || (dev->sp[c][i] == 0x02)) { synu[4] = 0x0c; synuw[4] = 0x0c; } else { @@ -2190,7 +2196,7 @@ try_sync: while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) { if ((m & dev->wide_id[c]) != 0) { - if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) { + if (is885(dev) || is880(dev)) { if ((m & dev->ultra_map[c]) != 0) { atp_writeb_io(dev, c, 0x19, synuw[j++]); } else { @@ -2245,7 +2251,7 @@ phase_outs: } continue; phase_ins: - if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) + if (is885(dev) || is880(dev)) atp_writeb_io(dev, c, 0x14, 0x06); else atp_writeb_io(dev, c, 0x14, 0xff); @@ -2303,7 +2309,7 @@ tar_dcons: if (mbuf[3] > 0x64) { continue; } - if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) { + if (is885(dev) || is880(dev)) { if (mbuf[4] > 0x0e) { mbuf[4] = 0x0e; } @@ -2313,7 +2319,7 @@ tar_dcons: } } dev->id[c][i].devsp = mbuf[4]; - if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) + if (is885(dev) || is880(dev)) if (mbuf[3] < 0x0c) { j = 0xb0; goto set_syn_ok; diff --git a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h index 8c47c53aee7f5..f9d62a2170898 100644 --- a/drivers/scsi/atp870u.h +++ b/drivers/scsi/atp870u.h @@ -39,7 +39,6 @@ struct atp_unit unsigned short active_id[2]; unsigned short ultra_map[2]; unsigned short async[2]; - unsigned short dev_id; unsigned char sp[2][16]; unsigned char r1f[2][16]; struct scsi_cmnd *quereq[2][qcnt]; -- GitLab From 11ec131804e75b73f07ac04f94888efc65c5d4c4 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:22 +0100 Subject: [PATCH 0647/2855] atp870u: Use pci_request_regions Use pci_request_regions and do it before accessing the I/O ports. Also add missing pci_disable_device() call to atp870u_remove(). Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 4bb0f4fcd9dfb..87dd8867106c8 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1276,10 +1276,15 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto disable_device; } + err = pci_request_regions(pdev, "atp870u"); + if (err) + goto disable_device; + pci_set_master(pdev); + err = -ENOMEM; shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); if (!shpnt) - goto disable_device; + goto release_region; atpdev = shost_priv(shpnt); @@ -1582,10 +1587,6 @@ flash_ok_885: } spin_unlock_irqrestore(shpnt->host_lock, flags); - if (!request_region(shpnt->io_port, shpnt->n_io_port, "atp870u")) { - err = -EBUSY; - goto request_io_fail; - } err = scsi_add_host(shpnt, &pdev->dev); if (err) goto scsi_add_fail; @@ -1596,16 +1597,13 @@ flash_ok_885: return 0; scsi_add_fail: - printk("atp870u_prob:scsi_add_fail\n"); - release_region(shpnt->io_port, shpnt->n_io_port); -request_io_fail: - printk("atp870u_prob:request_io_fail\n"); free_irq(shpnt->irq, shpnt); free_tables: - printk("atp870u_prob:free_table\n"); atp870u_free_tables(shpnt); unregister: scsi_host_put(shpnt); +release_region: + pci_release_regions(pdev); disable_device: pci_disable_device(pdev); fail: @@ -1696,7 +1694,8 @@ static void atp870u_remove (struct pci_dev *pdev) scsi_remove_host(pshost); free_irq(pshost->irq, pshost); - release_region(pshost->io_port, pshost->n_io_port); + pci_release_regions(pdev); + pci_disable_device(pdev); atp870u_free_tables(pshost); scsi_host_put(pshost); } -- GitLab From 1729c0d22bddfa949551c38301af3ce52d40c3b9 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:23 +0100 Subject: [PATCH 0648/2855] atp870u: Request IRQ later, remove weird locking Allocate IRQ later during probe to avoid code duplication and also remove the need for weird locking in _probe. (It was probably there to prevent race with the IRQ handler?) Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 47 +++++++++++------------------------------- 1 file changed, 12 insertions(+), 35 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 87dd8867106c8..4719df4a2a062 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1253,7 +1253,6 @@ static void atp_set_host_id(struct atp_unit *atp, u8 c, u8 host_id) static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { unsigned char k, m, c; - unsigned long flags; unsigned int error,n; unsigned char host_id; struct Scsi_Host *shpnt = NULL; @@ -1374,13 +1373,6 @@ flash_ok_880: goto unregister; } - err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp880i", shpnt); - if (err) { - printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", shpnt->irq); - goto free_tables; - } - - spin_lock_irqsave(shpnt->host_lock, flags); k = atp_readb_base(atpdev, 0x38) & 0x80; atp_writeb_base(atpdev, 0x38, k); atp_writeb_base(atpdev, 0x3b, 0x20); @@ -1412,17 +1404,6 @@ flash_ok_880: goto unregister; } -#ifdef ED_DBGP - printk("request_irq() shpnt %p hostdata %p\n", shpnt, atpdev); -#endif - err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt); - if (err) { - printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n"); - goto free_tables; - } - - spin_lock_irqsave(shpnt->host_lock, flags); - c = atp_readb_base(atpdev, 0x29); atp_writeb_base(atpdev, 0x29, c | 0x04); @@ -1558,13 +1539,6 @@ flash_ok_885: goto unregister; } - err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp870i", shpnt); - if (err) { - printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", shpnt->irq); - goto free_tables; - } - - spin_lock_irqsave(shpnt->host_lock, flags); if (pdev->revision > 0x07) /* check if atp876 chip then enable terminator */ atp_writeb_base(atpdev, 0x3e, 0x00); @@ -1586,15 +1560,18 @@ flash_ok_885: shpnt->this_id = host_id; } - spin_unlock_irqrestore(shpnt->host_lock, flags); - err = scsi_add_host(shpnt, &pdev->dev); - if (err) - goto scsi_add_fail; - scsi_scan_host(shpnt); -#ifdef ED_DBGP - printk("atp870u_prob : exit\n"); -#endif - return 0; + err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt); + if (err) { + dev_err(&pdev->dev, "Unable to allocate IRQ %d.\n", shpnt->irq); + goto free_tables; + } + + err = scsi_add_host(shpnt, &pdev->dev); + if (err) + goto scsi_add_fail; + scsi_scan_host(shpnt); + + return 0; scsi_add_fail: free_irq(shpnt->irq, shpnt); -- GitLab From 8177c507523e053011861cce08cb73a77d5896e3 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:24 +0100 Subject: [PATCH 0649/2855] atp870u: Remove scam_on from struct atp_unit scam_on is used only during probe, no need to keep it later. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 14 +++++++------- drivers/scsi/atp870u.h | 1 - 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 4719df4a2a062..dd0b520f7dd48 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -963,7 +963,7 @@ static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val) return j; } -static void tscam(struct Scsi_Host *host, bool wide_chip) +static void tscam(struct Scsi_Host *host, bool wide_chip, u8 scam_on) { unsigned char i, j, k; @@ -986,7 +986,7 @@ static void tscam(struct Scsi_Host *host, bool wide_chip) atp_writeb_io(dev, 0, 2, 0x7f); atp_writeb_io(dev, 0, 0x11, 0x20); - if ((dev->scam_on & 0x40) == 0) { + if ((scam_on & 0x40) == 0) { return; } m = 1; @@ -1311,7 +1311,6 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) " IO:%lx, IRQ:%d.\n", shpnt->io_port, shpnt->irq); atpdev->host_id[0] = host_id; - atpdev->scam_on = atp_readb_base(atpdev, 0x22); atpdev->global_map[0] = atp_readb_base(atpdev, 0x35); atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x3c); @@ -1384,7 +1383,7 @@ flash_ok_880: atp_set_host_id(atpdev, 0, host_id); - tscam(shpnt, true); + tscam(shpnt, true, atp_readb_base(atpdev, 0x22)); atp_is(atpdev, 0, true, atp_readb_base(atpdev, 0x3f) & 0x40); atp_writeb_base(atpdev, 0x38, 0xb0); shpnt->max_id = 16; @@ -1509,6 +1508,7 @@ flash_ok_885: shpnt->max_channel = 1; shpnt->this_id = atpdev->host_id[0]; } else { + u8 scam_on; bool wide_chip = (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610 && pdev->revision == 4) || @@ -1523,12 +1523,12 @@ flash_ok_885: atpdev->pciport[0] = shpnt->io_port + 0x20; host_id &= 0x07; atpdev->host_id[0] = host_id; - atpdev->scam_on = atp_readb_pci(atpdev, 0, 2); + scam_on = atp_readb_pci(atpdev, 0, 2); atpdev->global_map[0] = atp_readb_base(atpdev, 0x2d); atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x2e); if (atpdev->ultra_map[0] == 0) { - atpdev->scam_on = 0x00; + scam_on = 0x00; atpdev->global_map[0] = 0x20; atpdev->ultra_map[0] = 0xffff; } @@ -1551,7 +1551,7 @@ flash_ok_885: atp_set_host_id(atpdev, 0, host_id); - tscam(shpnt, wide_chip); + tscam(shpnt, wide_chip, scam_on); atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) | 0x10); atp_is(atpdev, 0, wide_chip, 0); atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) & 0xef); diff --git a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h index f9d62a2170898..9b839b1e895a1 100644 --- a/drivers/scsi/atp870u.h +++ b/drivers/scsi/atp870u.h @@ -32,7 +32,6 @@ struct atp_unit unsigned char quhd[2]; unsigned char quend[2]; unsigned char global_map[2]; - unsigned char scam_on; unsigned char host_id[2]; unsigned int working[2]; unsigned short wide_id[2]; -- GitLab From f5f53a38c2f8671f9fc249c711411ba44d76a618 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:25 +0100 Subject: [PATCH 0650/2855] atp870u: Initialize tables earlier Call _init_tables before chip-specific initialization. This avoids code duplication and fixes a bug(?) in 880 init where the values read from flash into atpdev->sp are then overwritten by calling init_tables. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index dd0b520f7dd48..3c66539e57816 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1298,6 +1298,12 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) shpnt->unique_id = shpnt->io_port; shpnt->irq = pdev->irq; + err = atp870u_init_tables(shpnt); + if (err) { + dev_err(&pdev->dev, "Unable to allocate tables for Acard controller\n"); + goto unregister; + } + if (is880(atpdev)) { pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 @@ -1366,11 +1372,6 @@ flash_ok_880: atpdev->async[0] = ~(atpdev->async[0]); atp_writeb_base(atpdev, 0x35, atpdev->global_map[0]); - if (atp870u_init_tables(shpnt) < 0) { - printk(KERN_ERR "Unable to allocate tables for Acard controller\n"); - err = -ENOMEM; - goto unregister; - } k = atp_readb_base(atpdev, 0x38) & 0x80; atp_writeb_base(atpdev, 0x38, k); @@ -1398,11 +1399,6 @@ flash_ok_880: atpdev->pciport[0] = shpnt->io_port + 0x40; atpdev->pciport[1] = shpnt->io_port + 0x50; - if (atp870u_init_tables(shpnt) < 0) { - err = -ENOMEM; - goto unregister; - } - c = atp_readb_base(atpdev, 0x29); atp_writeb_base(atpdev, 0x29, c | 0x04); @@ -1533,12 +1529,6 @@ flash_ok_885: atpdev->ultra_map[0] = 0xffff; } - - if (atp870u_init_tables(shpnt) < 0) { - err = -ENOMEM; - goto unregister; - } - if (pdev->revision > 0x07) /* check if atp876 chip then enable terminator */ atp_writeb_base(atpdev, 0x3e, 0x00); -- GitLab From c7e6a0298d56694d79189cd9127ac8ec1c2275ca Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:26 +0100 Subject: [PATCH 0651/2855] atp870u: Introduce atp880_init() Move 880-specific init code to a separate function atp880_init() Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 174 +++++++++++++++++++++-------------------- 1 file changed, 88 insertions(+), 86 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 3c66539e57816..c1fd9fb8d40fd 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1249,6 +1249,91 @@ static void atp_set_host_id(struct atp_unit *atp, u8 c, u8 host_id) atp_writeb_io(atp, c, 0x11, 0x20); } +static void atp880_init(struct Scsi_Host *shpnt) +{ + struct atp_unit *atpdev = shost_priv(shpnt); + struct pci_dev *pdev = atpdev->pdev; + unsigned char k, m, host_id; + unsigned int n; + + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80); + + atpdev->ioport[0] = shpnt->io_port + 0x40; + atpdev->pciport[0] = shpnt->io_port + 0x28; + + host_id = atp_readb_base(atpdev, 0x39) >> 4; + + dev_info(&pdev->dev, "ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: IO:%lx, IRQ:%d.\n", + shpnt->io_port, shpnt->irq); + atpdev->host_id[0] = host_id; + + atpdev->global_map[0] = atp_readb_base(atpdev, 0x35); + atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x3c); + + n = 0x3f09; + while (n < 0x4000) { + m = 0; + atp_writew_base(atpdev, 0x34, n); + n += 0x0002; + if (atp_readb_base(atpdev, 0x30) == 0xff) + break; + + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); + atp_writew_base(atpdev, 0x34, n); + n += 0x0002; + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); + atp_writew_base(atpdev, 0x34, n); + n += 0x0002; + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); + atp_writew_base(atpdev, 0x34, n); + n += 0x0002; + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); + n += 0x0018; + } + atp_writew_base(atpdev, 0x34, 0); + atpdev->ultra_map[0] = 0; + atpdev->async[0] = 0; + for (k = 0; k < 16; k++) { + n = 1 << k; + if (atpdev->sp[0][k] > 1) + atpdev->ultra_map[0] |= n; + else + if (atpdev->sp[0][k] == 0) + atpdev->async[0] |= n; + } + atpdev->async[0] = ~(atpdev->async[0]); + atp_writeb_base(atpdev, 0x35, atpdev->global_map[0]); + + k = atp_readb_base(atpdev, 0x38) & 0x80; + atp_writeb_base(atpdev, 0x38, k); + atp_writeb_base(atpdev, 0x3b, 0x20); + mdelay(32); + atp_writeb_base(atpdev, 0x3b, 0); + mdelay(32); + atp_readb_io(atpdev, 0, 0x1b); + atp_readb_io(atpdev, 0, 0x17); + + atp_set_host_id(atpdev, 0, host_id); + + tscam(shpnt, true, atp_readb_base(atpdev, 0x22)); + atp_is(atpdev, 0, true, atp_readb_base(atpdev, 0x3f) & 0x40); + atp_writeb_base(atpdev, 0x38, 0xb0); + shpnt->max_id = 16; + shpnt->this_id = host_id; +} + /* return non-zero on detection */ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1304,92 +1389,9 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto unregister; } - if (is880(atpdev)) { - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 - - atpdev->ioport[0] = shpnt->io_port + 0x40; - atpdev->pciport[0] = shpnt->io_port + 0x28; - - host_id = atp_readb_base(atpdev, 0x39); - host_id >>= 0x04; - - printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter:" - " IO:%lx, IRQ:%d.\n", shpnt->io_port, shpnt->irq); - atpdev->host_id[0] = host_id; - - atpdev->global_map[0] = atp_readb_base(atpdev, 0x35); - atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x3c); - - n = 0x3f09; -next_fblk_880: - if (n >= 0x4000) - goto flash_ok_880; - - m = 0; - atp_writew_base(atpdev, 0x34, n); - n += 0x0002; - if (atp_readb_base(atpdev, 0x30) == 0xff) - goto flash_ok_880; - - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); - atp_writew_base(atpdev, 0x34, n); - n += 0x0002; - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); - atp_writew_base(atpdev, 0x34, n); - n += 0x0002; - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); - atp_writew_base(atpdev, 0x34, n); - n += 0x0002; - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); - n += 0x0018; - goto next_fblk_880; -flash_ok_880: - atp_writew_base(atpdev, 0x34, 0); - atpdev->ultra_map[0] = 0; - atpdev->async[0] = 0; - for (k = 0; k < 16; k++) { - n = 1; - n = n << k; - if (atpdev->sp[0][k] > 1) { - atpdev->ultra_map[0] |= n; - } else { - if (atpdev->sp[0][k] == 0) - atpdev->async[0] |= n; - } - } - atpdev->async[0] = ~(atpdev->async[0]); - atp_writeb_base(atpdev, 0x35, atpdev->global_map[0]); - - - k = atp_readb_base(atpdev, 0x38) & 0x80; - atp_writeb_base(atpdev, 0x38, k); - atp_writeb_base(atpdev, 0x3b, 0x20); - mdelay(32); - atp_writeb_base(atpdev, 0x3b, 0); - mdelay(32); - atp_readb_io(atpdev, 0, 0x1b); - atp_readb_io(atpdev, 0, 0x17); - - atp_set_host_id(atpdev, 0, host_id); - - tscam(shpnt, true, atp_readb_base(atpdev, 0x22)); - atp_is(atpdev, 0, true, atp_readb_base(atpdev, 0x3f) & 0x40); - atp_writeb_base(atpdev, 0x38, 0xb0); - shpnt->max_id = 16; - shpnt->this_id = host_id; - } else if (is885(atpdev)) { + if (is880(atpdev)) + atp880_init(shpnt); + else if (is885(atpdev)) { printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%lx, IRQ:%d.\n" , shpnt->io_port, shpnt->irq); -- GitLab From ecc6ff95d1a84f0a025112e071be40dd905a5168 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:27 +0100 Subject: [PATCH 0652/2855] atp870u: Introduce atp885_init() Move 885-specific init code to a separate function atp885_init() Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 231 ++++++++++++++++++++--------------------- 1 file changed, 113 insertions(+), 118 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index c1fd9fb8d40fd..584b90f462128 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1334,15 +1334,122 @@ static void atp880_init(struct Scsi_Host *shpnt) shpnt->this_id = host_id; } +static void atp885_init(struct Scsi_Host *shpnt) +{ + struct atp_unit *atpdev = shost_priv(shpnt); + struct pci_dev *pdev = atpdev->pdev; + unsigned char k, m, c; + unsigned int n; + unsigned char setupdata[2][16]; + + dev_info(&pdev->dev, "ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%lx, IRQ:%d.\n", + shpnt->io_port, shpnt->irq); + + atpdev->ioport[0] = shpnt->io_port + 0x80; + atpdev->ioport[1] = shpnt->io_port + 0xc0; + atpdev->pciport[0] = shpnt->io_port + 0x40; + atpdev->pciport[1] = shpnt->io_port + 0x50; + + c = atp_readb_base(atpdev, 0x29); + atp_writeb_base(atpdev, 0x29, c | 0x04); + + n = 0x1f80; + while (n < 0x2000) { + atp_writew_base(atpdev, 0x3c, n); + if (atp_readl_base(atpdev, 0x38) == 0xffffffff) + break; + for (m = 0; m < 2; m++) { + atpdev->global_map[m] = 0; + for (k = 0; k < 4; k++) { + atp_writew_base(atpdev, 0x3c, n++); + ((unsigned long *)&setupdata[m][0])[k] = atp_readl_base(atpdev, 0x38); + } + for (k = 0; k < 4; k++) { + atp_writew_base(atpdev, 0x3c, n++); + ((unsigned long *)&atpdev->sp[m][0])[k] = atp_readl_base(atpdev, 0x38); + } + n += 8; + } + } + c = atp_readb_base(atpdev, 0x29); + atp_writeb_base(atpdev, 0x29, c & 0xfb); + for (c = 0; c < 2; c++) { + atpdev->ultra_map[c] = 0; + atpdev->async[c] = 0; + for (k = 0; k < 16; k++) { + n = 1 << k; + if (atpdev->sp[c][k] > 1) + atpdev->ultra_map[c] |= n; + else + if (atpdev->sp[c][k] == 0) + atpdev->async[c] |= n; + } + atpdev->async[c] = ~(atpdev->async[c]); + + if (atpdev->global_map[c] == 0) { + k = setupdata[c][1]; + if ((k & 0x40) != 0) + atpdev->global_map[c] |= 0x20; + k &= 0x07; + atpdev->global_map[c] |= k; + if ((setupdata[c][2] & 0x04) != 0) + atpdev->global_map[c] |= 0x08; + atpdev->host_id[c] = setupdata[c][0] & 0x07; + } + } + + k = atp_readb_base(atpdev, 0x28) & 0x8f; + k |= 0x10; + atp_writeb_base(atpdev, 0x28, k); + atp_writeb_pci(atpdev, 0, 1, 0x80); + atp_writeb_pci(atpdev, 1, 1, 0x80); + mdelay(100); + atp_writeb_pci(atpdev, 0, 1, 0); + atp_writeb_pci(atpdev, 1, 1, 0); + mdelay(1000); + atp_readb_io(atpdev, 0, 0x1b); + atp_readb_io(atpdev, 0, 0x17); + atp_readb_io(atpdev, 1, 0x1b); + atp_readb_io(atpdev, 1, 0x17); + + k = atpdev->host_id[0]; + if (k > 7) + k = (k & 0x07) | 0x40; + atp_set_host_id(atpdev, 0, k); + + k = atpdev->host_id[1]; + if (k > 7) + k = (k & 0x07) | 0x40; + atp_set_host_id(atpdev, 1, k); + + mdelay(600); /* this delay used to be called tscam_885() */ + dev_info(&pdev->dev, "Scanning Channel A SCSI Device ...\n"); + atp_is(atpdev, 0, true, atp_readb_io(atpdev, 0, 0x1b) >> 7); + atp_writeb_io(atpdev, 0, 0x16, 0x80); + dev_info(&pdev->dev, "Scanning Channel B SCSI Device ...\n"); + atp_is(atpdev, 1, true, atp_readb_io(atpdev, 1, 0x1b) >> 7); + atp_writeb_io(atpdev, 1, 0x16, 0x80); + k = atp_readb_base(atpdev, 0x28) & 0xcf; + k |= 0xc0; + atp_writeb_base(atpdev, 0x28, k); + k = atp_readb_base(atpdev, 0x1f) | 0x80; + atp_writeb_base(atpdev, 0x1f, k); + k = atp_readb_base(atpdev, 0x29) | 0x01; + atp_writeb_base(atpdev, 0x29, k); + shpnt->max_id = 16; + shpnt->max_lun = (atpdev->global_map[0] & 0x07) + 1; + shpnt->max_channel = 1; + shpnt->this_id = atpdev->host_id[0]; +} + /* return non-zero on detection */ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - unsigned char k, m, c; - unsigned int error,n; + unsigned char k; + unsigned int error; unsigned char host_id; struct Scsi_Host *shpnt = NULL; struct atp_unit *atpdev; - unsigned char setupdata[2][16]; int err; if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610 && pdev->revision < 2) { @@ -1391,121 +1498,9 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (is880(atpdev)) atp880_init(shpnt); - else if (is885(atpdev)) { - printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%lx, IRQ:%d.\n" - , shpnt->io_port, shpnt->irq); - - atpdev->pdev = pdev; - atpdev->ioport[0] = shpnt->io_port + 0x80; - atpdev->ioport[1] = shpnt->io_port + 0xc0; - atpdev->pciport[0] = shpnt->io_port + 0x40; - atpdev->pciport[1] = shpnt->io_port + 0x50; - - c = atp_readb_base(atpdev, 0x29); - atp_writeb_base(atpdev, 0x29, c | 0x04); - - n=0x1f80; -next_fblk_885: - if (n >= 0x2000) { - goto flash_ok_885; - } - atp_writew_base(atpdev, 0x3c, n); - if (atp_readl_base(atpdev, 0x38) == 0xffffffff) { - goto flash_ok_885; - } - for (m=0; m < 2; m++) { - atpdev->global_map[m]= 0; - for (k=0; k < 4; k++) { - atp_writew_base(atpdev, 0x3c, n++); - ((unsigned long *)&setupdata[m][0])[k] = atp_readl_base(atpdev, 0x38); - } - for (k=0; k < 4; k++) { - atp_writew_base(atpdev, 0x3c, n++); - ((unsigned long *)&atpdev->sp[m][0])[k] = atp_readl_base(atpdev, 0x38); - } - n += 8; - } - goto next_fblk_885; -flash_ok_885: -#ifdef ED_DBGP - printk( "Flash Read OK\n"); -#endif - c = atp_readb_base(atpdev, 0x29); - atp_writeb_base(atpdev, 0x29, c & 0xfb); - for (c=0;c < 2;c++) { - atpdev->ultra_map[c]=0; - atpdev->async[c] = 0; - for (k=0; k < 16; k++) { - n=1; - n = n << k; - if (atpdev->sp[c][k] > 1) { - atpdev->ultra_map[c] |= n; - } else { - if (atpdev->sp[c][k] == 0) { - atpdev->async[c] |= n; - } - } - } - atpdev->async[c] = ~(atpdev->async[c]); - - if (atpdev->global_map[c] == 0) { - k=setupdata[c][1]; - if ((k & 0x40) != 0) - atpdev->global_map[c] |= 0x20; - k &= 0x07; - atpdev->global_map[c] |= k; - if ((setupdata[c][2] & 0x04) != 0) - atpdev->global_map[c] |= 0x08; - atpdev->host_id[c] = setupdata[c][0] & 0x07; - } - } - - k = atp_readb_base(atpdev, 0x28) & 0x8f; - k |= 0x10; - atp_writeb_base(atpdev, 0x28, k); - atp_writeb_pci(atpdev, 0, 1, 0x80); - atp_writeb_pci(atpdev, 1, 1, 0x80); - mdelay(100); - atp_writeb_pci(atpdev, 0, 1, 0); - atp_writeb_pci(atpdev, 1, 1, 0); - mdelay(1000); - atp_readb_io(atpdev, 0, 0x1b); - atp_readb_io(atpdev, 0, 0x17); - atp_readb_io(atpdev, 1, 0x1b); - atp_readb_io(atpdev, 1, 0x17); - - k=atpdev->host_id[0]; - if (k > 7) - k = (k & 0x07) | 0x40; - atp_set_host_id(atpdev, 0, k); - - k=atpdev->host_id[1]; - if (k > 7) - k = (k & 0x07) | 0x40; - atp_set_host_id(atpdev, 1, k); - - mdelay(600); /* this delay used to be called tscam_885() */ - printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); - atp_is(atpdev, 0, true, atp_readb_io(atpdev, 0, 0x1b) >> 7); - atp_writeb_io(atpdev, 0, 0x16, 0x80); - printk(KERN_INFO " Scanning Channel B SCSI Device ...\n"); - atp_is(atpdev, 1, true, atp_readb_io(atpdev, 1, 0x1b) >> 7); - atp_writeb_io(atpdev, 1, 0x16, 0x80); - k = atp_readb_base(atpdev, 0x28) & 0xcf; - k |= 0xc0; - atp_writeb_base(atpdev, 0x28, k); - k = atp_readb_base(atpdev, 0x1f) | 0x80; - atp_writeb_base(atpdev, 0x1f, k); - k = atp_readb_base(atpdev, 0x29) | 0x01; - atp_writeb_base(atpdev, 0x29, k); -#ifdef ED_DBGP - //printk("atp885: atp_host[0] 0x%p\n", atp_host[0]); -#endif - shpnt->max_id = 16; - shpnt->max_lun = (atpdev->global_map[0] & 0x07) + 1; - shpnt->max_channel = 1; - shpnt->this_id = atpdev->host_id[0]; - } else { + else if (is885(atpdev)) + atp885_init(shpnt); + else { u8 scam_on; bool wide_chip = (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610 && -- GitLab From 4190230edbbe8864f04610900249db3738e2f51c Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:28 +0100 Subject: [PATCH 0653/2855] atp870u: Introduce atp870_init() Move 870-specific init code to a separate function atp870_init() Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 104 +++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 584b90f462128..8b52a9dbb9cf5 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1249,6 +1249,57 @@ static void atp_set_host_id(struct atp_unit *atp, u8 c, u8 host_id) atp_writeb_io(atp, c, 0x11, 0x20); } +static void atp870_init(struct Scsi_Host *shpnt) +{ + struct atp_unit *atpdev = shost_priv(shpnt); + struct pci_dev *pdev = atpdev->pdev; + unsigned char k, host_id; + u8 scam_on; + bool wide_chip = + (pdev->device == PCI_DEVICE_ID_ARTOP_AEC7610 && + pdev->revision == 4) || + (pdev->device == PCI_DEVICE_ID_ARTOP_AEC7612UW) || + (pdev->device == PCI_DEVICE_ID_ARTOP_AEC7612SUW); + + pci_read_config_byte(pdev, 0x49, &host_id); + + dev_info(&pdev->dev, "ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: IO:%lx, IRQ:%d.\n", + shpnt->io_port, shpnt->irq); + + atpdev->ioport[0] = shpnt->io_port; + atpdev->pciport[0] = shpnt->io_port + 0x20; + host_id &= 0x07; + atpdev->host_id[0] = host_id; + scam_on = atp_readb_pci(atpdev, 0, 2); + atpdev->global_map[0] = atp_readb_base(atpdev, 0x2d); + atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x2e); + + if (atpdev->ultra_map[0] == 0) { + scam_on = 0x00; + atpdev->global_map[0] = 0x20; + atpdev->ultra_map[0] = 0xffff; + } + + if (pdev->revision > 0x07) /* check if atp876 chip */ + atp_writeb_base(atpdev, 0x3e, 0x00); /* enable terminator */ + + k = (atp_readb_base(atpdev, 0x3a) & 0xf3) | 0x10; + atp_writeb_base(atpdev, 0x3a, k); + atp_writeb_base(atpdev, 0x3a, k & 0xdf); + mdelay(32); + atp_writeb_base(atpdev, 0x3a, k); + mdelay(32); + atp_set_host_id(atpdev, 0, host_id); + + tscam(shpnt, wide_chip, scam_on); + atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) | 0x10); + atp_is(atpdev, 0, wide_chip, 0); + atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) & 0xef); + atp_writeb_base(atpdev, 0x3b, atp_readb_base(atpdev, 0x3b) | 0x20); + shpnt->max_id = wide_chip ? 16 : 8; + shpnt->this_id = host_id; +} + static void atp880_init(struct Scsi_Host *shpnt) { struct atp_unit *atpdev = shost_priv(shpnt); @@ -1445,9 +1496,6 @@ static void atp885_init(struct Scsi_Host *shpnt) /* return non-zero on detection */ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - unsigned char k; - unsigned int error; - unsigned char host_id; struct Scsi_Host *shpnt = NULL; struct atp_unit *atpdev; int err; @@ -1500,53 +1548,9 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) atp880_init(shpnt); else if (is885(atpdev)) atp885_init(shpnt); - else { - u8 scam_on; - bool wide_chip = - (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610 && - pdev->revision == 4) || - (ent->device == PCI_DEVICE_ID_ARTOP_AEC7612UW) || - (ent->device == PCI_DEVICE_ID_ARTOP_AEC7612SUW); - error = pci_read_config_byte(pdev, 0x49, &host_id); - - printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: " - "IO:%lx, IRQ:%d.\n", shpnt->io_port, shpnt->irq); - - atpdev->ioport[0] = shpnt->io_port; - atpdev->pciport[0] = shpnt->io_port + 0x20; - host_id &= 0x07; - atpdev->host_id[0] = host_id; - scam_on = atp_readb_pci(atpdev, 0, 2); - atpdev->global_map[0] = atp_readb_base(atpdev, 0x2d); - atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x2e); - - if (atpdev->ultra_map[0] == 0) { - scam_on = 0x00; - atpdev->global_map[0] = 0x20; - atpdev->ultra_map[0] = 0xffff; - } - - if (pdev->revision > 0x07) /* check if atp876 chip then enable terminator */ - atp_writeb_base(atpdev, 0x3e, 0x00); - - k = (atp_readb_base(atpdev, 0x3a) & 0xf3) | 0x10; - atp_writeb_base(atpdev, 0x3a, k); - atp_writeb_base(atpdev, 0x3a, k & 0xdf); - mdelay(32); - atp_writeb_base(atpdev, 0x3a, k); - mdelay(32); - atp_set_host_id(atpdev, 0, host_id); - - - tscam(shpnt, wide_chip, scam_on); - atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) | 0x10); - atp_is(atpdev, 0, wide_chip, 0); - atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) & 0xef); - atp_writeb_base(atpdev, 0x3b, atp_readb_base(atpdev, 0x3b) | 0x20); - shpnt->max_id = wide_chip ? 16 : 8; - shpnt->this_id = host_id; - - } + else + atp870_init(shpnt); + err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt); if (err) { dev_err(&pdev->dev, "Unable to allocate IRQ %d.\n", shpnt->irq); -- GitLab From c15d75bec6d0a937f7a15b81052ed99d310e9767 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:28 +0800 Subject: [PATCH 0654/2855] scsi: Centralise ssp frame information units The xfer_rdy, command, and task frame's iu structures are not available in , but only aic94xx driver folder. Add them to include/scsi/sas.h Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/aic94xx/aic94xx_sas.h | 49 +++----------------- include/scsi/sas.h | 74 ++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 43 deletions(-) diff --git a/drivers/scsi/aic94xx/aic94xx_sas.h b/drivers/scsi/aic94xx/aic94xx_sas.h index 912e6b755f749..101072cab70fc 100644 --- a/drivers/scsi/aic94xx/aic94xx_sas.h +++ b/drivers/scsi/aic94xx/aic94xx_sas.h @@ -327,46 +327,9 @@ struct scb_header { #define LUN_SIZE 8 -/* See SAS spec, task IU - */ -struct ssp_task_iu { - u8 lun[LUN_SIZE]; /* BE */ - u16 _r_a; - u8 tmf; - u8 _r_b; - __be16 tag; /* BE */ - u8 _r_c[14]; -} __attribute__ ((packed)); - -/* See SAS spec, command IU - */ -struct ssp_command_iu { - u8 lun[LUN_SIZE]; - u8 _r_a; - u8 efb_prio_attr; /* enable first burst, task prio & attr */ -#define EFB_MASK 0x80 -#define TASK_PRIO_MASK 0x78 -#define TASK_ATTR_MASK 0x07 - - u8 _r_b; - u8 add_cdb_len; /* in dwords, since bit 0,1 are reserved */ - union { - u8 cdb[16]; - struct { - __le64 long_cdb_addr; /* bus address, LE */ - __le32 long_cdb_size; /* LE */ - u8 _r_c[3]; - u8 eol_ds; /* eol:6,6, ds:5,4 */ - } long_cdb; /* sequencer extension */ - }; -} __attribute__ ((packed)); - -struct xfer_rdy_iu { - __be32 requested_offset; /* BE */ - __be32 write_data_len; /* BE */ - __be32 _r_a; -} __attribute__ ((packed)); - +#define EFB_MASK 0x80 +#define TASK_PRIO_MASK 0x78 +#define TASK_ATTR_MASK 0x07 /* ---------- SCB tasks ---------- */ /* This is both ssp_task and long_ssp_task @@ -511,7 +474,7 @@ struct abort_task { u8 proto_conn_rate; __le32 _r_a; struct ssp_frame_hdr ssp_frame; - struct ssp_task_iu ssp_task; + struct ssp_tmf_iu ssp_task; __le16 sister_scb; __le16 conn_handle; u8 flags; /* ovrd_itnl_timer:3,3, suspend_data_trans:2,2 */ @@ -549,7 +512,7 @@ struct clear_nexus { u8 _r_b[3]; u8 conn_mask; u8 _r_c[19]; - struct ssp_task_iu ssp_task; /* LUN and TAG */ + struct ssp_tmf_iu ssp_task; /* LUN and TAG */ __le16 _r_d; __le16 conn_handle; __le64 _r_e; @@ -562,7 +525,7 @@ struct initiate_ssp_tmf { u8 proto_conn_rate; __le32 _r_a; struct ssp_frame_hdr ssp_frame; - struct ssp_task_iu ssp_task; + struct ssp_tmf_iu ssp_task; __le16 sister_scb; __le16 conn_handle; u8 flags; /* itnl override and suspend data tx */ diff --git a/include/scsi/sas.h b/include/scsi/sas.h index 0d2607d123875..42a84ef42683a 100644 --- a/include/scsi/sas.h +++ b/include/scsi/sas.h @@ -344,6 +344,43 @@ struct ssp_response_iu { u8 sense_data[0]; } __attribute__ ((packed)); +struct ssp_command_iu { + u8 lun[8]; + u8 _r_a; + + union { + struct { + u8 attr:3; + u8 prio:4; + u8 efb:1; + }; + u8 efb_prio_attr; + }; + + u8 _r_b; + + u8 _r_c:2; + u8 add_cdb_len:6; + + u8 cdb[16]; + u8 add_cdb[0]; +} __attribute__ ((packed)); + +struct xfer_rdy_iu { + __be32 requested_offset; + __be32 write_data_len; + __be32 _r_a; +} __attribute__ ((packed)); + +struct ssp_tmf_iu { + u8 lun[8]; + u16 _r_a; + u8 tmf; + u8 _r_b; + __be16 tag; + u8 _r_c[14]; +} __attribute__ ((packed)); + /* ---------- SMP ---------- */ struct report_general_resp { @@ -538,6 +575,43 @@ struct ssp_response_iu { u8 sense_data[0]; } __attribute__ ((packed)); +struct ssp_command_iu { + u8 lun[8]; + u8 _r_a; + + union { + struct { + u8 efb:1; + u8 prio:4; + u8 attr:3; + }; + u8 efb_prio_attr; + }; + + u8 _r_b; + + u8 add_cdb_len:6; + u8 _r_c:2; + + u8 cdb[16]; + u8 add_cdb[0]; +} __attribute__ ((packed)); + +struct xfer_rdy_iu { + __be32 requested_offset; + __be32 write_data_len; + __be32 _r_a; +} __attribute__ ((packed)); + +struct ssp_tmf_iu { + u8 lun[8]; + u16 _r_a; + u8 tmf; + u8 _r_b; + __be16 tag; + u8 _r_c[14]; +} __attribute__ ((packed)); + /* ---------- SMP ---------- */ struct report_general_resp { -- GitLab From 47caad1577cd7a39e2048c5e4edbce4b863dc12b Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:29 +0800 Subject: [PATCH 0655/2855] devicetree: bindings: scsi: HiSi SAS Add devicetree bindings for HiSilicon SAS driver. Signed-off-by: John Garry Signed-off-by: Zhangfei Gao Acked-by: Rob Herring Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- .../bindings/scsi/hisilicon-sas.txt | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 Documentation/devicetree/bindings/scsi/hisilicon-sas.txt diff --git a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt new file mode 100644 index 0000000000000..f67e761bcc18e --- /dev/null +++ b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt @@ -0,0 +1,69 @@ +* HiSilicon SAS controller + +The HiSilicon SAS controller supports SAS/SATA. + +Main node required properties: + - compatible : value should be as follows: + (a) "hisilicon,hip05-sas-v1" for v1 hw in hip05 chipset + - sas-addr : array of 8 bytes for host SAS address + - reg : Address and length of the SAS register + - hisilicon,sas-syscon: phandle of syscon used for sas control + - ctrl-reset-reg : offset to controller reset register in ctrl reg + - ctrl-reset-sts-reg : offset to controller reset status register in ctrl reg + - ctrl-clock-ena-reg : offset to controller clock enable register in ctrl reg + - queue-count : number of delivery and completion queues in the controller + - phy-count : number of phys accessible by the controller + - interrupts : Interrupts for phys, completion queues, and fatal + sources; the interrupts are ordered in 3 groups, as follows: + - Phy interrupts + - Completion queue interrupts + - Fatal interrupts + Phy interrupts : Each phy has 3 interrupt sources: + - broadcast + - phyup + - abnormal + The phy interrupts are ordered into groups of 3 per phy + (broadcast, phyup, and abnormal) in increasing order. + Completion queue interrupts : each completion queue has 1 + interrupt source. + The interrupts are ordered in increasing order. + Fatal interrupts : the fatal interrupts are ordered as follows: + - ECC + - AXI bus + +Example: + sas0: sas@c1000000 { + compatible = "hisilicon,hip05-sas-v1"; + sas-addr = [50 01 88 20 16 00 00 0a]; + reg = <0x0 0xc1000000 0x0 0x10000>; + hisilicon,sas-syscon = <&pcie_sas>; + ctrl-reset-reg = <0xa60>; + ctrl-reset-sts-reg = <0x5a30>; + ctrl-clock-ena-reg = <0x338>; + queue-count = <32>; + phy-count = <8>; + dma-coherent; + interrupt-parent = <&mbigen_dsa>; + interrupts = <259 4>,<263 4>,<264 4>,/* phy0 */ + <269 4>,<273 4>,<274 4>,/* phy1 */ + <279 4>,<283 4>,<284 4>,/* phy2 */ + <289 4>,<293 4>,<294 4>,/* phy3 */ + <299 4>,<303 4>,<304 4>,/* phy4 */ + <309 4>,<313 4>,<314 4>,/* phy5 */ + <319 4>,<323 4>,<324 4>,/* phy6 */ + <329 4>,<333 4>,<334 4>,/* phy7 */ + <336 1>,<337 1>,<338 1>,/* cq0-2 */ + <339 1>,<340 1>,<341 1>,/* cq3-5 */ + <342 1>,<343 1>,<344 1>,/* cq6-8 */ + <345 1>,<346 1>,<347 1>,/* cq9-11 */ + <348 1>,<349 1>,<350 1>,/* cq12-14 */ + <351 1>,<352 1>,<353 1>,/* cq15-17 */ + <354 1>,<355 1>,<356 1>,/* cq18-20 */ + <357 1>,<358 1>,<359 1>,/* cq21-23 */ + <360 1>,<361 1>,<362 1>,/* cq24-26 */ + <363 1>,<364 1>,<365 1>,/* cq27-29 */ + <366 1>,<367 1>/* cq30-31 */ + <376 4>,/* fatal ecc */ + <381 4>;/* fatal axi */ + status = "disabled"; + }; -- GitLab From e8899fad9672ca8b414db36e16ce4d21818802dc Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:30 +0800 Subject: [PATCH 0656/2855] hisi_sas: Add initial bare main driver This patch adds the initial bare main driver for the HiSilicon SAS HBA. This only introduces the changes to build and load the main driver module. The complete driver consists of the core main module and also a module platform driver for driving the hw. The HBA is a platform device. Signed-off-by: John Garry Signed-off-by: Zhangfei Gao Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/Kconfig | 1 + drivers/scsi/Makefile | 1 + drivers/scsi/hisi_sas/Kconfig | 6 ++++ drivers/scsi/hisi_sas/Makefile | 1 + drivers/scsi/hisi_sas/hisi_sas.h | 26 ++++++++++++++++ drivers/scsi/hisi_sas/hisi_sas_main.c | 43 +++++++++++++++++++++++++++ 6 files changed, 78 insertions(+) create mode 100644 drivers/scsi/hisi_sas/Kconfig create mode 100644 drivers/scsi/hisi_sas/Makefile create mode 100644 drivers/scsi/hisi_sas/hisi_sas.h create mode 100644 drivers/scsi/hisi_sas/hisi_sas_main.c diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 5f692ae407495..37dce2380a527 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -473,6 +473,7 @@ config SCSI_AACRAID source "drivers/scsi/aic7xxx/Kconfig.aic7xxx" source "drivers/scsi/aic7xxx/Kconfig.aic79xx" source "drivers/scsi/aic94xx/Kconfig" +source "drivers/scsi/hisi_sas/Kconfig" source "drivers/scsi/mvsas/Kconfig" config SCSI_MVUMI diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index c14bca4a9675c..862ab4efad61e 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -157,6 +157,7 @@ obj-$(CONFIG_CHR_DEV_SCH) += ch.o obj-$(CONFIG_SCSI_ENCLOSURE) += ses.o obj-$(CONFIG_SCSI_OSD_INITIATOR) += osd/ +obj-$(CONFIG_SCSI_HISI_SAS) += hisi_sas/ # This goes last, so that "real" scsi devices probe earlier obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o diff --git a/drivers/scsi/hisi_sas/Kconfig b/drivers/scsi/hisi_sas/Kconfig new file mode 100644 index 0000000000000..37a0c71560879 --- /dev/null +++ b/drivers/scsi/hisi_sas/Kconfig @@ -0,0 +1,6 @@ +config SCSI_HISI_SAS + tristate "HiSilicon SAS" + select SCSI_SAS_LIBSAS + select BLK_DEV_INTEGRITY + help + This driver supports HiSilicon's SAS HBA diff --git a/drivers/scsi/hisi_sas/Makefile b/drivers/scsi/hisi_sas/Makefile new file mode 100644 index 0000000000000..d86b05e262e96 --- /dev/null +++ b/drivers/scsi/hisi_sas/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_SCSI_HISI_SAS) += hisi_sas_main.o diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h new file mode 100644 index 0000000000000..a5cec225eb253 --- /dev/null +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2015 Linaro Ltd. + * Copyright (c) 2015 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#ifndef _HISI_SAS_H_ +#define _HISI_SAS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_VERSION "v1.0" + +#endif diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c new file mode 100644 index 0000000000000..7201363c45b59 --- /dev/null +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015 Linaro Ltd. + * Copyright (c) 2015 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include "hisi_sas.h" +#define DRV_NAME "hisi_sas" + +static struct scsi_transport_template *hisi_sas_stt; + +static struct sas_domain_function_template hisi_sas_transport_ops = { +}; + +static __init int hisi_sas_init(void) +{ + pr_info("hisi_sas: driver version %s\n", DRV_VERSION); + + hisi_sas_stt = sas_domain_attach_transport(&hisi_sas_transport_ops); + if (!hisi_sas_stt) + return -ENOMEM; + + return 0; +} + +static __exit void hisi_sas_exit(void) +{ + sas_release_transport(hisi_sas_stt); +} + +module_init(hisi_sas_init); +module_exit(hisi_sas_exit); + +MODULE_VERSION(DRV_VERSION); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("John Garry "); +MODULE_DESCRIPTION("HISILICON SAS controller driver"); +MODULE_ALIAS("platform:" DRV_NAME); -- GitLab From 7eb7869f1307cc86fca9afd1425bba023c35414f Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:31 +0800 Subject: [PATCH 0657/2855] hisi_sas: Add scsi host registration Add functionality to register device as a scsi host. The SAS domain transport ops are empty at this point. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 34 ++++++++ drivers/scsi/hisi_sas/hisi_sas_main.c | 116 ++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index a5cec225eb253..6f57fd16e9375 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -23,4 +23,38 @@ #define DRV_VERSION "v1.0" +#define HISI_SAS_MAX_PHYS 9 +#define HISI_SAS_MAX_ITCT_ENTRIES 4096 +#define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES +#define HISI_SAS_COMMAND_ENTRIES 8192 + +struct hisi_sas_phy { + struct asd_sas_phy sas_phy; +}; + +struct hisi_sas_port { + struct asd_sas_port sas_port; +}; + +struct hisi_sas_hw { +}; + +struct hisi_hba { + /* This must be the first element, used by SHOST_TO_SAS_HA */ + struct sas_ha_struct *p; + + struct platform_device *pdev; + u8 sas_addr[SAS_ADDR_SIZE]; + + int n_phy; + + /* SCSI/SAS glue */ + struct sas_ha_struct sha; + struct Scsi_Host *shost; + struct hisi_sas_phy phy[HISI_SAS_MAX_PHYS]; + struct hisi_sas_port port[HISI_SAS_MAX_PHYS]; + const struct hisi_sas_hw *hw; /* Low level hw interface */ +}; + +#define HISI_SAS_SGE_PAGE_CNT SCSI_MAX_SG_SEGMENTS #endif diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 7201363c45b59..4fd000e565c26 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -14,9 +14,125 @@ static struct scsi_transport_template *hisi_sas_stt; +static struct scsi_host_template hisi_sas_sht = { + .module = THIS_MODULE, + .name = DRV_NAME, + .queuecommand = sas_queuecommand, + .target_alloc = sas_target_alloc, + .slave_configure = sas_slave_configure, + .change_queue_depth = sas_change_queue_depth, + .bios_param = sas_bios_param, + .can_queue = 1, + .this_id = -1, + .sg_tablesize = SG_ALL, + .max_sectors = SCSI_DEFAULT_MAX_SECTORS, + .use_clustering = ENABLE_CLUSTERING, + .eh_device_reset_handler = sas_eh_device_reset_handler, + .eh_bus_reset_handler = sas_eh_bus_reset_handler, + .target_destroy = sas_target_destroy, + .ioctl = sas_ioctl, +}; + static struct sas_domain_function_template hisi_sas_transport_ops = { }; +static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, + const struct hisi_sas_hw *hw) +{ + struct Scsi_Host *shost; + struct hisi_hba *hisi_hba; + struct device *dev = &pdev->dev; + + shost = scsi_host_alloc(&hisi_sas_sht, sizeof(*hisi_hba)); + if (!shost) + goto err_out; + hisi_hba = shost_priv(shost); + + hisi_hba->hw = hw; + hisi_hba->pdev = pdev; + hisi_hba->shost = shost; + SHOST_TO_SAS_HA(shost) = &hisi_hba->sha; + + return shost; +err_out: + dev_err(dev, "shost alloc failed\n"); + return NULL; +} + +int hisi_sas_probe(struct platform_device *pdev, + const struct hisi_sas_hw *hw) +{ + struct Scsi_Host *shost; + struct hisi_hba *hisi_hba; + struct device *dev = &pdev->dev; + struct asd_sas_phy **arr_phy; + struct asd_sas_port **arr_port; + struct sas_ha_struct *sha; + int rc, phy_nr, port_nr, i; + + shost = hisi_sas_shost_alloc(pdev, hw); + if (!shost) { + rc = -ENOMEM; + goto err_out_ha; + } + + sha = SHOST_TO_SAS_HA(shost); + hisi_hba = shost_priv(shost); + platform_set_drvdata(pdev, sha); + hisi_hba->n_phy = HISI_SAS_MAX_PHYS; + phy_nr = port_nr = hisi_hba->n_phy; + + arr_phy = devm_kcalloc(dev, phy_nr, sizeof(void *), GFP_KERNEL); + arr_port = devm_kcalloc(dev, port_nr, sizeof(void *), GFP_KERNEL); + if (!arr_phy || !arr_port) + return -ENOMEM; + + sha->sas_phy = arr_phy; + sha->sas_port = arr_port; + sha->core.shost = shost; + sha->lldd_ha = hisi_hba; + + shost->transportt = hisi_sas_stt; + shost->max_id = HISI_SAS_MAX_DEVICES; + shost->max_lun = ~0; + shost->max_channel = 1; + shost->max_cmd_len = 16; + shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT); + shost->can_queue = HISI_SAS_COMMAND_ENTRIES; + shost->cmd_per_lun = HISI_SAS_COMMAND_ENTRIES; + + sha->sas_ha_name = DRV_NAME; + sha->dev = &hisi_hba->pdev->dev; + sha->lldd_module = THIS_MODULE; + sha->sas_addr = &hisi_hba->sas_addr[0]; + sha->num_phys = hisi_hba->n_phy; + sha->core.shost = hisi_hba->shost; + + for (i = 0; i < hisi_hba->n_phy; i++) { + sha->sas_phy[i] = &hisi_hba->phy[i].sas_phy; + sha->sas_port[i] = &hisi_hba->port[i].sas_port; + } + + rc = scsi_add_host(shost, &pdev->dev); + if (rc) + goto err_out_ha; + + rc = sas_register_ha(sha); + if (rc) + goto err_out_register_ha; + + scsi_scan_host(shost); + + return 0; + +err_out_register_ha: + scsi_remove_host(shost); +err_out_ha: + kfree(shost); + return rc; +} +EXPORT_SYMBOL_GPL(hisi_sas_probe); + static __init int hisi_sas_init(void) { pr_info("hisi_sas: driver version %s\n", DRV_VERSION); -- GitLab From e26b2f405a6a65c0ce0ea168aef7d4607ec7ad80 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:32 +0800 Subject: [PATCH 0658/2855] hisi_sas: Scan device tree Scan the device tree for all properties. Also do this: - do ioremap for SAS registers - allocate memory for interrupt names Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 10 ++++++ drivers/scsi/hisi_sas/hisi_sas_main.c | 45 ++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 6f57fd16e9375..87f4b61028ebf 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -28,6 +28,8 @@ #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES #define HISI_SAS_COMMAND_ENTRIES 8192 +#define HISI_SAS_NAME_LEN 32 + struct hisi_sas_phy { struct asd_sas_phy sas_phy; }; @@ -44,6 +46,11 @@ struct hisi_hba { struct sas_ha_struct *p; struct platform_device *pdev; + void __iomem *regs; + struct regmap *ctrl; + u32 ctrl_reset_reg; + u32 ctrl_reset_sts_reg; + u32 ctrl_clock_ena_reg; u8 sas_addr[SAS_ADDR_SIZE]; int n_phy; @@ -53,6 +60,9 @@ struct hisi_hba { struct Scsi_Host *shost; struct hisi_sas_phy phy[HISI_SAS_MAX_PHYS]; struct hisi_sas_port port[HISI_SAS_MAX_PHYS]; + + int queue_count; + char *int_names; const struct hisi_sas_hw *hw; /* Low level hw interface */ }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 4fd000e565c26..4fc5a6c6d0ce5 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -39,9 +39,13 @@ static struct sas_domain_function_template hisi_sas_transport_ops = { static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, const struct hisi_sas_hw *hw) { + struct resource *res; struct Scsi_Host *shost; struct hisi_hba *hisi_hba; struct device *dev = &pdev->dev; + struct device_node *np = pdev->dev.of_node; + struct property *sas_addr_prop; + int num; shost = scsi_host_alloc(&hisi_sas_sht, sizeof(*hisi_hba)); if (!shost) @@ -53,6 +57,46 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, hisi_hba->shost = shost; SHOST_TO_SAS_HA(shost) = &hisi_hba->sha; + sas_addr_prop = of_find_property(np, "sas-addr", NULL); + if (!sas_addr_prop || (sas_addr_prop->length != SAS_ADDR_SIZE)) + goto err_out; + memcpy(hisi_hba->sas_addr, sas_addr_prop->value, SAS_ADDR_SIZE); + + if (of_property_read_u32(np, "ctrl-reset-reg", + &hisi_hba->ctrl_reset_reg)) + goto err_out; + + if (of_property_read_u32(np, "ctrl-reset-sts-reg", + &hisi_hba->ctrl_reset_sts_reg)) + goto err_out; + + if (of_property_read_u32(np, "ctrl-clock-ena-reg", + &hisi_hba->ctrl_clock_ena_reg)) + goto err_out; + + if (of_property_read_u32(np, "phy-count", &hisi_hba->n_phy)) + goto err_out; + + if (of_property_read_u32(np, "queue-count", &hisi_hba->queue_count)) + goto err_out; + + num = of_irq_count(np); + hisi_hba->int_names = devm_kcalloc(dev, num, + HISI_SAS_NAME_LEN, + GFP_KERNEL); + if (!hisi_hba->int_names) + goto err_out; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + hisi_hba->regs = devm_ioremap_resource(dev, res); + if (IS_ERR(hisi_hba->regs)) + goto err_out; + + hisi_hba->ctrl = syscon_regmap_lookup_by_phandle( + np, "hisilicon,sas-syscon"); + if (IS_ERR(hisi_hba->ctrl)) + goto err_out; + return shost; err_out: dev_err(dev, "shost alloc failed\n"); @@ -79,7 +123,6 @@ int hisi_sas_probe(struct platform_device *pdev, sha = SHOST_TO_SAS_HA(shost); hisi_hba = shost_priv(shost); platform_set_drvdata(pdev, sha); - hisi_hba->n_phy = HISI_SAS_MAX_PHYS; phy_nr = port_nr = hisi_hba->n_phy; arr_phy = devm_kcalloc(dev, phy_nr, sizeof(void *), GFP_KERNEL); -- GitLab From c799d6bd8fe4a82333fd11f8699f621e10af2f4b Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:33 +0800 Subject: [PATCH 0659/2855] hisi_sas: Add HW DMA structures Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 131 +++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 87f4b61028ebf..19d40b76508fd 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -66,5 +66,136 @@ struct hisi_hba { const struct hisi_sas_hw *hw; /* Low level hw interface */ }; +/* Generic HW DMA host memory structures */ +/* Delivery queue header */ +struct hisi_sas_cmd_hdr { + /* dw0 */ + __le32 dw0; + + /* dw1 */ + __le32 dw1; + + /* dw2 */ + __le32 dw2; + + /* dw3 */ + __le32 transfer_tags; + + /* dw4 */ + __le32 data_transfer_len; + + /* dw5 */ + __le32 first_burst_num; + + /* dw6 */ + __le32 sg_len; + + /* dw7 */ + __le32 dw7; + + /* dw8-9 */ + __le64 cmd_table_addr; + + /* dw10-11 */ + __le64 sts_buffer_addr; + + /* dw12-13 */ + __le64 prd_table_addr; + + /* dw14-15 */ + __le64 dif_prd_table_addr; +}; + +struct hisi_sas_itct { + __le64 qw0; + __le64 sas_addr; + __le64 qw2; + __le64 qw3; + __le64 qw4; + __le64 qw_sata_ncq0_3; + __le64 qw_sata_ncq7_4; + __le64 qw_sata_ncq11_8; + __le64 qw_sata_ncq15_12; + __le64 qw_sata_ncq19_16; + __le64 qw_sata_ncq23_20; + __le64 qw_sata_ncq27_24; + __le64 qw_sata_ncq31_28; + __le64 qw_non_ncq_iptt; + __le64 qw_rsvd0; + __le64 qw_rsvd1; +}; + +struct hisi_sas_iost { + __le64 qw0; + __le64 qw1; + __le64 qw2; + __le64 qw3; +}; + +struct hisi_sas_err_record { + /* dw0 */ + __le32 dma_err_type; + + /* dw1 */ + __le32 trans_tx_fail_type; + + /* dw2 */ + __le32 trans_rx_fail_type; + + /* dw3 */ + u32 rsvd; +}; + +struct hisi_sas_initial_fis { + struct hisi_sas_err_record err_record; + struct dev_to_host_fis fis; + u32 rsvd[3]; +}; + +struct hisi_sas_breakpoint { + u8 data[128]; /*io128 byte*/ +}; + +struct hisi_sas_sge { + __le64 addr; + __le32 page_ctrl_0; + __le32 page_ctrl_1; + __le32 data_len; + __le32 data_off; +}; + +struct hisi_sas_command_table_smp { + u8 bytes[44]; +}; + +struct hisi_sas_command_table_stp { + struct host_to_dev_fis command_fis; + u8 dummy[12]; + u8 atapi_cdb[ATAPI_CDB_LEN]; +}; + #define HISI_SAS_SGE_PAGE_CNT SCSI_MAX_SG_SEGMENTS +struct hisi_sas_sge_page { + struct hisi_sas_sge sge[HISI_SAS_SGE_PAGE_CNT]; +}; + +struct hisi_sas_command_table_ssp { + struct ssp_frame_hdr hdr; + union { + struct { + struct ssp_command_iu task; + u32 prot[6]; + }; + struct ssp_tmf_iu ssp_task; + struct xfer_rdy_iu xfer_rdy; + struct ssp_response_iu ssp_res; + } u; +}; + +union hisi_sas_command_table { + struct hisi_sas_command_table_ssp ssp; + struct hisi_sas_command_table_smp smp; + struct hisi_sas_command_table_stp stp; +}; + #endif -- GitLab From 6be6de18891d5533451b2c00424f6a557dc901ec Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:34 +0800 Subject: [PATCH 0660/2855] hisi_sas: Allocate memories and create pools Allocate DMA and non-DMA memories for the controller. Also create DMA pools. These include: - Delivery queues - Completion queues - Command status buffer - Command table - ITCT (For device context) - Host slot info - IO status - Breakpoint - host slot indexing - SG data - FIS - interrupts names Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 30 +++++++++ drivers/scsi/hisi_sas/hisi_sas_main.c | 94 +++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 19d40b76508fd..6d1b7d88cb385 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -24,10 +24,17 @@ #define DRV_VERSION "v1.0" #define HISI_SAS_MAX_PHYS 9 +#define HISI_SAS_MAX_QUEUES 32 +#define HISI_SAS_QUEUE_SLOTS 512 #define HISI_SAS_MAX_ITCT_ENTRIES 4096 #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES #define HISI_SAS_COMMAND_ENTRIES 8192 +#define HISI_SAS_STATUS_BUF_SZ \ + (sizeof(struct hisi_sas_err_record) + 1024) +#define HISI_SAS_COMMAND_TABLE_SZ \ + (((sizeof(union hisi_sas_command_table)+3)/4)*4) + #define HISI_SAS_NAME_LEN 32 struct hisi_sas_phy { @@ -38,7 +45,11 @@ struct hisi_sas_port { struct asd_sas_port sas_port; }; +struct hisi_sas_slot { +}; + struct hisi_sas_hw { + int complete_hdr_size; }; struct hisi_hba { @@ -63,6 +74,25 @@ struct hisi_hba { int queue_count; char *int_names; + + struct dma_pool *sge_page_pool; + struct dma_pool *command_table_pool; + struct dma_pool *status_buffer_pool; + struct hisi_sas_cmd_hdr *cmd_hdr[HISI_SAS_MAX_QUEUES]; + dma_addr_t cmd_hdr_dma[HISI_SAS_MAX_QUEUES]; + void *complete_hdr[HISI_SAS_MAX_QUEUES]; + dma_addr_t complete_hdr_dma[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_initial_fis *initial_fis; + dma_addr_t initial_fis_dma; + struct hisi_sas_itct *itct; + dma_addr_t itct_dma; + struct hisi_sas_iost *iost; + dma_addr_t iost_dma; + struct hisi_sas_breakpoint *breakpoint; + dma_addr_t breakpoint_dma; + struct hisi_sas_breakpoint *sata_breakpoint; + dma_addr_t sata_breakpoint_dma; + struct hisi_sas_slot *slot_info; const struct hisi_sas_hw *hw; /* Low level hw interface */ }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 4fc5a6c6d0ce5..97f53682b475c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -36,6 +36,97 @@ static struct scsi_host_template hisi_sas_sht = { static struct sas_domain_function_template hisi_sas_transport_ops = { }; +static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) +{ + int i, s; + struct platform_device *pdev = hisi_hba->pdev; + struct device *dev = &pdev->dev; + + for (i = 0; i < hisi_hba->queue_count; i++) { + /* Delivery queue */ + s = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; + hisi_hba->cmd_hdr[i] = dma_alloc_coherent(dev, s, + &hisi_hba->cmd_hdr_dma[i], GFP_KERNEL); + if (!hisi_hba->cmd_hdr[i]) + goto err_out; + memset(hisi_hba->cmd_hdr[i], 0, s); + + /* Completion queue */ + s = hisi_hba->hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; + hisi_hba->complete_hdr[i] = dma_alloc_coherent(dev, s, + &hisi_hba->complete_hdr_dma[i], GFP_KERNEL); + if (!hisi_hba->complete_hdr[i]) + goto err_out; + memset(hisi_hba->complete_hdr[i], 0, s); + } + + s = HISI_SAS_STATUS_BUF_SZ; + hisi_hba->status_buffer_pool = dma_pool_create("status_buffer", + dev, s, 16, 0); + if (!hisi_hba->status_buffer_pool) + goto err_out; + + s = HISI_SAS_COMMAND_TABLE_SZ; + hisi_hba->command_table_pool = dma_pool_create("command_table", + dev, s, 16, 0); + if (!hisi_hba->command_table_pool) + goto err_out; + + s = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct); + hisi_hba->itct = dma_alloc_coherent(dev, s, &hisi_hba->itct_dma, + GFP_KERNEL); + if (!hisi_hba->itct) + goto err_out; + + memset(hisi_hba->itct, 0, s); + + hisi_hba->slot_info = devm_kcalloc(dev, HISI_SAS_COMMAND_ENTRIES, + sizeof(struct hisi_sas_slot), + GFP_KERNEL); + if (!hisi_hba->slot_info) + goto err_out; + + s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_iost); + hisi_hba->iost = dma_alloc_coherent(dev, s, &hisi_hba->iost_dma, + GFP_KERNEL); + if (!hisi_hba->iost) + goto err_out; + + memset(hisi_hba->iost, 0, s); + + s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_breakpoint); + hisi_hba->breakpoint = dma_alloc_coherent(dev, s, + &hisi_hba->breakpoint_dma, GFP_KERNEL); + if (!hisi_hba->breakpoint) + goto err_out; + + memset(hisi_hba->breakpoint, 0, s); + + hisi_hba->sge_page_pool = dma_pool_create("status_sge", dev, + sizeof(struct hisi_sas_sge_page), 16, 0); + if (!hisi_hba->sge_page_pool) + goto err_out; + + s = sizeof(struct hisi_sas_initial_fis) * HISI_SAS_MAX_PHYS; + hisi_hba->initial_fis = dma_alloc_coherent(dev, s, + &hisi_hba->initial_fis_dma, GFP_KERNEL); + if (!hisi_hba->initial_fis) + goto err_out; + memset(hisi_hba->initial_fis, 0, s); + + s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_breakpoint) * 2; + hisi_hba->sata_breakpoint = dma_alloc_coherent(dev, s, + &hisi_hba->sata_breakpoint_dma, GFP_KERNEL); + if (!hisi_hba->sata_breakpoint) + goto err_out; + memset(hisi_hba->sata_breakpoint, 0, s); + + return 0; +err_out: + return -ENOMEM; +} + + static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, const struct hisi_sas_hw *hw) { @@ -97,6 +188,9 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, if (IS_ERR(hisi_hba->ctrl)) goto err_out; + if (hisi_sas_alloc(hisi_hba, shost)) + goto err_out; + return shost; err_out: dev_err(dev, "shost alloc failed\n"); -- GitLab From 89d533223de0fe30e3b30900d1fc9c98020c2215 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:35 +0800 Subject: [PATCH 0661/2855] hisi_sas: Add hisi_sas_remove This patch also includes relevant memory/pool freeing and sas/scsi host removal. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 71 ++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 97f53682b475c..b96a2ab1c4c9e 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -126,6 +126,59 @@ err_out: return -ENOMEM; } +static void hisi_sas_free(struct hisi_hba *hisi_hba) +{ + struct device *dev = &hisi_hba->pdev->dev; + int i, s; + + for (i = 0; i < hisi_hba->queue_count; i++) { + s = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; + if (hisi_hba->cmd_hdr[i]) + dma_free_coherent(dev, s, + hisi_hba->cmd_hdr[i], + hisi_hba->cmd_hdr_dma[i]); + + s = hisi_hba->hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; + if (hisi_hba->complete_hdr[i]) + dma_free_coherent(dev, s, + hisi_hba->complete_hdr[i], + hisi_hba->complete_hdr_dma[i]); + } + + dma_pool_destroy(hisi_hba->status_buffer_pool); + dma_pool_destroy(hisi_hba->command_table_pool); + dma_pool_destroy(hisi_hba->sge_page_pool); + + s = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct); + if (hisi_hba->itct) + dma_free_coherent(dev, s, + hisi_hba->itct, hisi_hba->itct_dma); + + s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_iost); + if (hisi_hba->iost) + dma_free_coherent(dev, s, + hisi_hba->iost, hisi_hba->iost_dma); + + s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_breakpoint); + if (hisi_hba->breakpoint) + dma_free_coherent(dev, s, + hisi_hba->breakpoint, + hisi_hba->breakpoint_dma); + + + s = sizeof(struct hisi_sas_initial_fis) * HISI_SAS_MAX_PHYS; + if (hisi_hba->initial_fis) + dma_free_coherent(dev, s, + hisi_hba->initial_fis, + hisi_hba->initial_fis_dma); + + s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_breakpoint) * 2; + if (hisi_hba->sata_breakpoint) + dma_free_coherent(dev, s, + hisi_hba->sata_breakpoint, + hisi_hba->sata_breakpoint_dma); + +} static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, const struct hisi_sas_hw *hw) @@ -188,8 +241,10 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, if (IS_ERR(hisi_hba->ctrl)) goto err_out; - if (hisi_sas_alloc(hisi_hba, shost)) + if (hisi_sas_alloc(hisi_hba, shost)) { + hisi_sas_free(hisi_hba); goto err_out; + } return shost; err_out: @@ -270,6 +325,20 @@ err_out_ha: } EXPORT_SYMBOL_GPL(hisi_sas_probe); +int hisi_sas_remove(struct platform_device *pdev) +{ + struct sas_ha_struct *sha = platform_get_drvdata(pdev); + struct hisi_hba *hisi_hba = sha->lldd_ha; + + scsi_remove_host(sha->core.shost); + sas_unregister_ha(sha); + sas_remove_host(sha->core.shost); + + hisi_sas_free(hisi_hba); + return 0; +} +EXPORT_SYMBOL_GPL(hisi_sas_remove); + static __init int hisi_sas_init(void) { pr_info("hisi_sas: driver version %s\n", DRV_VERSION); -- GitLab From 257efd1f69dd1789b1db0f12425e31d6c05118db Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:36 +0800 Subject: [PATCH 0662/2855] hisi_sas: Add slot init code Add functionality to init slot indexing. Slot indexing is for the host to track which slots (or tags) are free and which are used. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 4 ++++ drivers/scsi/hisi_sas/hisi_sas_main.c | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 6d1b7d88cb385..2cd677170db5e 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -66,6 +66,10 @@ struct hisi_hba { int n_phy; + + int slot_index_count; + unsigned long *slot_index_tags; + /* SCSI/SAS glue */ struct sas_ha_struct sha; struct Scsi_Host *shost; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index b96a2ab1c4c9e..d7e5b66e60779 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -12,6 +12,21 @@ #include "hisi_sas.h" #define DRV_NAME "hisi_sas" +static void hisi_sas_slot_index_clear(struct hisi_hba *hisi_hba, int slot_idx) +{ + void *bitmap = hisi_hba->slot_index_tags; + + clear_bit(slot_idx, bitmap); +} + +static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba) +{ + int i; + + for (i = 0; i < hisi_hba->slot_index_count; ++i) + hisi_sas_slot_index_clear(hisi_hba, i); +} + static struct scsi_transport_template *hisi_sas_stt; static struct scsi_host_template hisi_sas_sht = { @@ -102,6 +117,12 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) memset(hisi_hba->breakpoint, 0, s); + hisi_hba->slot_index_count = HISI_SAS_COMMAND_ENTRIES; + s = hisi_hba->slot_index_count / sizeof(unsigned long); + hisi_hba->slot_index_tags = devm_kzalloc(dev, s, GFP_KERNEL); + if (!hisi_hba->slot_index_tags) + goto err_out; + hisi_hba->sge_page_pool = dma_pool_create("status_sge", dev, sizeof(struct hisi_sas_sge_page), 16, 0); if (!hisi_hba->sge_page_pool) @@ -121,6 +142,8 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) goto err_out; memset(hisi_hba->sata_breakpoint, 0, s); + hisi_sas_slot_index_init(hisi_hba); + return 0; err_out: return -ENOMEM; -- GitLab From 9101a0792d2ad49a0bf293d346f391c198d72843 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:37 +0800 Subject: [PATCH 0663/2855] hisi_sas: Add cq structure initialization Each completion queue has a structure. This is mainly for passing to irq handler so we know which queue the irq occured on. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 7 +++++++ drivers/scsi/hisi_sas/hisi_sas_main.c | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 2cd677170db5e..315fe4640d889 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -45,6 +45,11 @@ struct hisi_sas_port { struct asd_sas_port sas_port; }; +struct hisi_sas_cq { + struct hisi_hba *hisi_hba; + int id; +}; + struct hisi_sas_slot { }; @@ -73,6 +78,8 @@ struct hisi_hba { /* SCSI/SAS glue */ struct sas_ha_struct sha; struct Scsi_Host *shost; + + struct hisi_sas_cq cq[HISI_SAS_MAX_QUEUES]; struct hisi_sas_phy phy[HISI_SAS_MAX_PHYS]; struct hisi_sas_port port[HISI_SAS_MAX_PHYS]; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index d7e5b66e60779..d10bf24ecebd1 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -58,6 +58,12 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) struct device *dev = &pdev->dev; for (i = 0; i < hisi_hba->queue_count; i++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[i]; + + /* Completion queue structure */ + cq->id = i; + cq->hisi_hba = hisi_hba; + /* Delivery queue */ s = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; hisi_hba->cmd_hdr[i] = dma_alloc_coherent(dev, s, -- GitLab From 5d74242e37feb5d06aecb3118d642ff621d08b75 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:38 +0800 Subject: [PATCH 0664/2855] hisi_sas: Add phy SAS ADDR initialization The SAS address for the HBA comes from the device tree. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 1 + drivers/scsi/hisi_sas/hisi_sas_main.c | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 315fe4640d889..c50384f60be69 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -39,6 +39,7 @@ struct hisi_sas_phy { struct asd_sas_phy sas_phy; + u64 dev_sas_addr; }; struct hisi_sas_port { diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index d10bf24ecebd1..8cd1b551abb6a 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -281,6 +281,16 @@ err_out: return NULL; } +static void hisi_sas_init_add(struct hisi_hba *hisi_hba) +{ + int i; + + for (i = 0; i < hisi_hba->n_phy; i++) + memcpy(&hisi_hba->phy[i].dev_sas_addr, + hisi_hba->sas_addr, + SAS_ADDR_SIZE); +} + int hisi_sas_probe(struct platform_device *pdev, const struct hisi_sas_hw *hw) { @@ -334,6 +344,8 @@ int hisi_sas_probe(struct platform_device *pdev, sha->sas_port[i] = &hisi_hba->port[i].sas_port; } + hisi_sas_init_add(hisi_hba); + rc = scsi_add_host(shost, &pdev->dev); if (rc) goto err_out_ha; -- GitLab From 50cb916f4361e9202866d388eaddbe1d3f0ee0f7 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:39 +0800 Subject: [PATCH 0665/2855] hisi_sas: Set dev DMA mask Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 8cd1b551abb6a..d7d9516385a7f 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -311,6 +311,14 @@ int hisi_sas_probe(struct platform_device *pdev, sha = SHOST_TO_SAS_HA(shost); hisi_hba = shost_priv(shost); platform_set_drvdata(pdev, sha); + + if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)) && + dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) { + dev_err(dev, "No usable DMA addressing method\n"); + rc = -EIO; + goto err_out_ha; + } + phy_nr = port_nr = hisi_hba->n_phy; arr_phy = devm_kcalloc(dev, phy_nr, sizeof(void *), GFP_KERNEL); -- GitLab From 7e9080e1c68dba3324ba307395b8dcb80bec308c Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:40 +0800 Subject: [PATCH 0666/2855] hisi_sas: Add hisi_hba workqueue Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 1 + drivers/scsi/hisi_sas/hisi_sas_main.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index c50384f60be69..62bc6f32b7344 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -72,6 +72,7 @@ struct hisi_hba { int n_phy; + struct workqueue_struct *wq; int slot_index_count; unsigned long *slot_index_tags; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index d7d9516385a7f..7f32c6b76d055 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -150,6 +150,12 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) hisi_sas_slot_index_init(hisi_hba); + hisi_hba->wq = create_singlethread_workqueue(dev_name(dev)); + if (!hisi_hba->wq) { + dev_err(dev, "sas_alloc: failed to create workqueue\n"); + goto err_out; + } + return 0; err_out: return -ENOMEM; @@ -207,6 +213,8 @@ static void hisi_sas_free(struct hisi_hba *hisi_hba) hisi_hba->sata_breakpoint, hisi_hba->sata_breakpoint_dma); + if (hisi_hba->wq) + destroy_workqueue(hisi_hba->wq); } static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, -- GitLab From af740dbe659f1eee07a18801f89d9b2e2f9b5329 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:41 +0800 Subject: [PATCH 0667/2855] hisi_sas: Add hisi sas device type Include initialisation. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 12 ++++++++++++ drivers/scsi/hisi_sas/hisi_sas_main.c | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 62bc6f32b7344..5ac5a82edfec8 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -37,6 +37,11 @@ #define HISI_SAS_NAME_LEN 32 + +enum dev_status { + HISI_SAS_DEV_NORMAL, + HISI_SAS_DEV_EH, +}; struct hisi_sas_phy { struct asd_sas_phy sas_phy; u64 dev_sas_addr; @@ -51,6 +56,12 @@ struct hisi_sas_cq { int id; }; +struct hisi_sas_device { + enum sas_device_type dev_type; + u64 device_id; + u8 dev_status; +}; + struct hisi_sas_slot { }; @@ -89,6 +100,7 @@ struct hisi_hba { char *int_names; struct dma_pool *sge_page_pool; + struct hisi_sas_device devices[HISI_SAS_MAX_DEVICES]; struct dma_pool *command_table_pool; struct dma_pool *status_buffer_pool; struct hisi_sas_cmd_hdr *cmd_hdr[HISI_SAS_MAX_QUEUES]; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 7f32c6b76d055..21111d4b854f2 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -57,6 +57,12 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) struct platform_device *pdev = hisi_hba->pdev; struct device *dev = &pdev->dev; + for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) { + hisi_hba->devices[i].dev_type = SAS_PHY_UNUSED; + hisi_hba->devices[i].device_id = i; + hisi_hba->devices[i].dev_status = HISI_SAS_DEV_NORMAL; + } + for (i = 0; i < hisi_hba->queue_count; i++) { struct hisi_sas_cq *cq = &hisi_hba->cq[i]; -- GitLab From 976867e6ed0384b9c0598d692e3858d7c1ec349f Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:42 +0800 Subject: [PATCH 0668/2855] hisi_sas: Add phy and port init Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 15 +++++++++++++ drivers/scsi/hisi_sas/hisi_sas_main.c | 31 +++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 5ac5a82edfec8..3a2400e8bb959 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -43,12 +43,27 @@ enum dev_status { HISI_SAS_DEV_EH, }; struct hisi_sas_phy { + struct hisi_hba *hisi_hba; + struct hisi_sas_port *port; struct asd_sas_phy sas_phy; + struct sas_identify identify; + struct timer_list timer; + u64 port_id; /* from hw */ u64 dev_sas_addr; + u64 phy_type; + u64 frame_rcvd_size; + u8 frame_rcvd[32]; + u8 phy_attached; + u8 reserved[3]; + enum sas_linkrate minimum_linkrate; + enum sas_linkrate maximum_linkrate; }; struct hisi_sas_port { struct asd_sas_port sas_port; + u8 port_attached; + u8 id; /* from hw */ + struct list_head list; }; struct hisi_sas_cq { diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 21111d4b854f2..bc41ce478c3dd 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -27,6 +27,30 @@ static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba) hisi_sas_slot_index_clear(hisi_hba, i); } + +static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) +{ + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + + phy->hisi_hba = hisi_hba; + phy->port = NULL; + init_timer(&phy->timer); + sas_phy->enabled = (phy_no < hisi_hba->n_phy) ? 1 : 0; + sas_phy->class = SAS; + sas_phy->iproto = SAS_PROTOCOL_ALL; + sas_phy->tproto = 0; + sas_phy->type = PHY_TYPE_PHYSICAL; + sas_phy->role = PHY_ROLE_INITIATOR; + sas_phy->oob_mode = OOB_NOT_CONNECTED; + sas_phy->linkrate = SAS_LINK_RATE_UNKNOWN; + sas_phy->id = phy_no; + sas_phy->sas_addr = &hisi_hba->sas_addr[0]; + sas_phy->frame_rcvd = &phy->frame_rcvd[0]; + sas_phy->ha = (struct sas_ha_struct *)hisi_hba->shost->hostdata; + sas_phy->lldd_phy = phy; +} + static struct scsi_transport_template *hisi_sas_stt; static struct scsi_host_template hisi_sas_sht = { @@ -57,6 +81,13 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) struct platform_device *pdev = hisi_hba->pdev; struct device *dev = &pdev->dev; + for (i = 0; i < hisi_hba->n_phy; i++) { + hisi_sas_phy_init(hisi_hba, i); + hisi_hba->port[i].port_attached = 0; + hisi_hba->port[i].id = -1; + INIT_LIST_HEAD(&hisi_hba->port[i].list); + } + for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) { hisi_hba->devices[i].dev_type = SAS_PHY_UNUSED; hisi_hba->devices[i].device_id = i; -- GitLab From fa42d80dc3c5196b0359fab9a212cc4ede257502 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:43 +0800 Subject: [PATCH 0669/2855] hisi_sas: Add timer and spinlock init Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 2 ++ drivers/scsi/hisi_sas/hisi_sas_main.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 3a2400e8bb959..3749c46bc6d0e 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -97,7 +97,9 @@ struct hisi_hba { u8 sas_addr[SAS_ADDR_SIZE]; int n_phy; + spinlock_t lock; + struct timer_list timer; struct workqueue_struct *wq; int slot_index_count; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index bc41ce478c3dd..06b863c401247 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -81,6 +81,7 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) struct platform_device *pdev = hisi_hba->pdev; struct device *dev = &pdev->dev; + spin_lock_init(&hisi_hba->lock); for (i = 0; i < hisi_hba->n_phy; i++) { hisi_sas_phy_init(hisi_hba, i); hisi_hba->port[i].port_attached = 0; @@ -275,6 +276,8 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, hisi_hba->shost = shost; SHOST_TO_SAS_HA(shost) = &hisi_hba->sha; + init_timer(&hisi_hba->timer); + sas_addr_prop = of_find_property(np, "sas-addr", NULL); if (!sas_addr_prop || (sas_addr_prop->length != SAS_ADDR_SIZE)) goto err_out; -- GitLab From 9fb10b54861f481de4c484a67a60d981e54fe9a1 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:44 +0800 Subject: [PATCH 0670/2855] hisi_sas: Add v1 hw module init Add module init code for v1 hw. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/Makefile | 1 + drivers/scsi/hisi_sas/hisi_sas.h | 3 ++ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 53 ++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 drivers/scsi/hisi_sas/hisi_sas_v1_hw.c diff --git a/drivers/scsi/hisi_sas/Makefile b/drivers/scsi/hisi_sas/Makefile index d86b05e262e96..3e70eae81343a 100644 --- a/drivers/scsi/hisi_sas/Makefile +++ b/drivers/scsi/hisi_sas/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_SCSI_HISI_SAS) += hisi_sas_main.o +obj-$(CONFIG_SCSI_HISI_SAS) += hisi_sas_v1_hw.o diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 3749c46bc6d0e..72533cae320d8 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -269,5 +269,8 @@ union hisi_sas_command_table { struct hisi_sas_command_table_smp smp; struct hisi_sas_command_table_stp stp; }; +extern int hisi_sas_probe(struct platform_device *pdev, + const struct hisi_sas_hw *ops); +extern int hisi_sas_remove(struct platform_device *pdev); #endif diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c new file mode 100644 index 0000000000000..e9aebcec7aac2 --- /dev/null +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015 Linaro Ltd. + * Copyright (c) 2015 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include "hisi_sas.h" +#define DRV_NAME "hisi_sas_v1_hw" + + +struct hisi_sas_complete_v1_hdr { + __le32 data; +}; +static const struct hisi_sas_hw hisi_sas_v1_hw = { + .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr), +}; + +static int hisi_sas_v1_probe(struct platform_device *pdev) +{ + return hisi_sas_probe(pdev, &hisi_sas_v1_hw); +} + +static int hisi_sas_v1_remove(struct platform_device *pdev) +{ + return hisi_sas_remove(pdev); +} + +static const struct of_device_id sas_v1_of_match[] = { + { .compatible = "hisilicon,hip05-sas-v1",}, + {}, +}; +MODULE_DEVICE_TABLE(of, sas_v1_of_match); + +static struct platform_driver hisi_sas_v1_driver = { + .probe = hisi_sas_v1_probe, + .remove = hisi_sas_v1_remove, + .driver = { + .name = DRV_NAME, + .of_match_table = sas_v1_of_match, + }, +}; + +module_platform_driver(hisi_sas_v1_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("John Garry "); +MODULE_DESCRIPTION("HISILICON SAS controller v1 hw driver"); +MODULE_ALIAS("platform:" DRV_NAME); -- GitLab From 50af155b6cabd398bc2dca5aa32ddb879bb9331e Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:45 +0800 Subject: [PATCH 0671/2855] hisi_sas: Add v1 hardware register definitions Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 389 +++++++++++++++++++++++++ 1 file changed, 389 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index e9aebcec7aac2..9fe89bb847793 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -12,10 +12,399 @@ #include "hisi_sas.h" #define DRV_NAME "hisi_sas_v1_hw" +/* global registers need init*/ +#define DLVRY_QUEUE_ENABLE 0x0 +#define IOST_BASE_ADDR_LO 0x8 +#define IOST_BASE_ADDR_HI 0xc +#define ITCT_BASE_ADDR_LO 0x10 +#define ITCT_BASE_ADDR_HI 0x14 +#define BROKEN_MSG_ADDR_LO 0x18 +#define BROKEN_MSG_ADDR_HI 0x1c +#define PHY_CONTEXT 0x20 +#define PHY_STATE 0x24 +#define PHY_PORT_NUM_MA 0x28 +#define PORT_STATE 0x2c +#define PHY_CONN_RATE 0x30 +#define HGC_TRANS_TASK_CNT_LIMIT 0x38 +#define AXI_AHB_CLK_CFG 0x3c +#define HGC_SAS_TXFAIL_RETRY_CTRL 0x84 +#define HGC_GET_ITV_TIME 0x90 +#define DEVICE_MSG_WORK_MODE 0x94 +#define I_T_NEXUS_LOSS_TIME 0xa0 +#define BUS_INACTIVE_LIMIT_TIME 0xa8 +#define REJECT_TO_OPEN_LIMIT_TIME 0xac +#define CFG_AGING_TIME 0xbc +#define CFG_AGING_TIME_ITCT_REL_OFF 0 +#define CFG_AGING_TIME_ITCT_REL_MSK (0x1 << CFG_AGING_TIME_ITCT_REL_OFF) +#define HGC_DFX_CFG2 0xc0 +#define FIS_LIST_BADDR_L 0xc4 +#define CFG_1US_TIMER_TRSH 0xcc +#define CFG_SAS_CONFIG 0xd4 +#define HGC_IOST_ECC_ADDR 0x140 +#define HGC_IOST_ECC_ADDR_BAD_OFF 16 +#define HGC_IOST_ECC_ADDR_BAD_MSK (0x3ff << HGC_IOST_ECC_ADDR_BAD_OFF) +#define HGC_DQ_ECC_ADDR 0x144 +#define HGC_DQ_ECC_ADDR_BAD_OFF 16 +#define HGC_DQ_ECC_ADDR_BAD_MSK (0xfff << HGC_DQ_ECC_ADDR_BAD_OFF) +#define HGC_INVLD_DQE_INFO 0x148 +#define HGC_INVLD_DQE_INFO_DQ_OFF 0 +#define HGC_INVLD_DQE_INFO_DQ_MSK (0xffff << HGC_INVLD_DQE_INFO_DQ_OFF) +#define HGC_INVLD_DQE_INFO_TYPE_OFF 16 +#define HGC_INVLD_DQE_INFO_TYPE_MSK (0x1 << HGC_INVLD_DQE_INFO_TYPE_OFF) +#define HGC_INVLD_DQE_INFO_FORCE_OFF 17 +#define HGC_INVLD_DQE_INFO_FORCE_MSK (0x1 << HGC_INVLD_DQE_INFO_FORCE_OFF) +#define HGC_INVLD_DQE_INFO_PHY_OFF 18 +#define HGC_INVLD_DQE_INFO_PHY_MSK (0x1 << HGC_INVLD_DQE_INFO_PHY_OFF) +#define HGC_INVLD_DQE_INFO_ABORT_OFF 19 +#define HGC_INVLD_DQE_INFO_ABORT_MSK (0x1 << HGC_INVLD_DQE_INFO_ABORT_OFF) +#define HGC_INVLD_DQE_INFO_IPTT_OF_OFF 20 +#define HGC_INVLD_DQE_INFO_IPTT_OF_MSK (0x1 << HGC_INVLD_DQE_INFO_IPTT_OF_OFF) +#define HGC_INVLD_DQE_INFO_SSP_ERR_OFF 21 +#define HGC_INVLD_DQE_INFO_SSP_ERR_MSK (0x1 << HGC_INVLD_DQE_INFO_SSP_ERR_OFF) +#define HGC_INVLD_DQE_INFO_OFL_OFF 22 +#define HGC_INVLD_DQE_INFO_OFL_MSK (0x1 << HGC_INVLD_DQE_INFO_OFL_OFF) +#define HGC_ITCT_ECC_ADDR 0x150 +#define HGC_ITCT_ECC_ADDR_BAD_OFF 16 +#define HGC_ITCT_ECC_ADDR_BAD_MSK (0x3ff << HGC_ITCT_ECC_ADDR_BAD_OFF) +#define HGC_AXI_FIFO_ERR_INFO 0x154 +#define INT_COAL_EN 0x1bc +#define OQ_INT_COAL_TIME 0x1c0 +#define OQ_INT_COAL_CNT 0x1c4 +#define ENT_INT_COAL_TIME 0x1c8 +#define ENT_INT_COAL_CNT 0x1cc +#define OQ_INT_SRC 0x1d0 +#define OQ_INT_SRC_MSK 0x1d4 +#define ENT_INT_SRC1 0x1d8 +#define ENT_INT_SRC2 0x1dc +#define ENT_INT_SRC2_DQ_CFG_ERR_OFF 25 +#define ENT_INT_SRC2_DQ_CFG_ERR_MSK (0x1 << ENT_INT_SRC2_DQ_CFG_ERR_OFF) +#define ENT_INT_SRC2_CQ_CFG_ERR_OFF 27 +#define ENT_INT_SRC2_CQ_CFG_ERR_MSK (0x1 << ENT_INT_SRC2_CQ_CFG_ERR_OFF) +#define ENT_INT_SRC2_AXI_WRONG_INT_OFF 28 +#define ENT_INT_SRC2_AXI_WRONG_INT_MSK (0x1 << ENT_INT_SRC2_AXI_WRONG_INT_OFF) +#define ENT_INT_SRC2_AXI_OVERLF_INT_OFF 29 +#define ENT_INT_SRC2_AXI_OVERLF_INT_MSK (0x1 << ENT_INT_SRC2_AXI_OVERLF_INT_OFF) +#define ENT_INT_SRC_MSK1 0x1e0 +#define ENT_INT_SRC_MSK2 0x1e4 +#define SAS_ECC_INTR 0x1e8 +#define SAS_ECC_INTR_DQ_ECC1B_OFF 0 +#define SAS_ECC_INTR_DQ_ECC1B_MSK (0x1 << SAS_ECC_INTR_DQ_ECC1B_OFF) +#define SAS_ECC_INTR_DQ_ECCBAD_OFF 1 +#define SAS_ECC_INTR_DQ_ECCBAD_MSK (0x1 << SAS_ECC_INTR_DQ_ECCBAD_OFF) +#define SAS_ECC_INTR_IOST_ECC1B_OFF 2 +#define SAS_ECC_INTR_IOST_ECC1B_MSK (0x1 << SAS_ECC_INTR_IOST_ECC1B_OFF) +#define SAS_ECC_INTR_IOST_ECCBAD_OFF 3 +#define SAS_ECC_INTR_IOST_ECCBAD_MSK (0x1 << SAS_ECC_INTR_IOST_ECCBAD_OFF) +#define SAS_ECC_INTR_ITCT_ECC1B_OFF 4 +#define SAS_ECC_INTR_ITCT_ECC1B_MSK (0x1 << SAS_ECC_INTR_ITCT_ECC1B_OFF) +#define SAS_ECC_INTR_ITCT_ECCBAD_OFF 5 +#define SAS_ECC_INTR_ITCT_ECCBAD_MSK (0x1 << SAS_ECC_INTR_ITCT_ECCBAD_OFF) +#define SAS_ECC_INTR_MSK 0x1ec +#define HGC_ERR_STAT_EN 0x238 +#define DLVRY_Q_0_BASE_ADDR_LO 0x260 +#define DLVRY_Q_0_BASE_ADDR_HI 0x264 +#define DLVRY_Q_0_DEPTH 0x268 +#define DLVRY_Q_0_WR_PTR 0x26c +#define DLVRY_Q_0_RD_PTR 0x270 +#define COMPL_Q_0_BASE_ADDR_LO 0x4e0 +#define COMPL_Q_0_BASE_ADDR_HI 0x4e4 +#define COMPL_Q_0_DEPTH 0x4e8 +#define COMPL_Q_0_WR_PTR 0x4ec +#define COMPL_Q_0_RD_PTR 0x4f0 +#define HGC_ECC_ERR 0x7d0 + +/* phy registers need init */ +#define PORT_BASE (0x800) + +#define PHY_CFG (PORT_BASE + 0x0) +#define PHY_CFG_ENA_OFF 0 +#define PHY_CFG_ENA_MSK (0x1 << PHY_CFG_ENA_OFF) +#define PHY_CFG_DC_OPT_OFF 2 +#define PHY_CFG_DC_OPT_MSK (0x1 << PHY_CFG_DC_OPT_OFF) +#define PROG_PHY_LINK_RATE (PORT_BASE + 0xc) +#define PROG_PHY_LINK_RATE_MAX_OFF 0 +#define PROG_PHY_LINK_RATE_MAX_MSK (0xf << PROG_PHY_LINK_RATE_MAX_OFF) +#define PROG_PHY_LINK_RATE_MIN_OFF 4 +#define PROG_PHY_LINK_RATE_MIN_MSK (0xf << PROG_PHY_LINK_RATE_MIN_OFF) +#define PROG_PHY_LINK_RATE_OOB_OFF 8 +#define PROG_PHY_LINK_RATE_OOB_MSK (0xf << PROG_PHY_LINK_RATE_OOB_OFF) +#define PHY_CTRL (PORT_BASE + 0x14) +#define PHY_CTRL_RESET_OFF 0 +#define PHY_CTRL_RESET_MSK (0x1 << PHY_CTRL_RESET_OFF) +#define PHY_RATE_NEGO (PORT_BASE + 0x30) +#define PHY_PCN (PORT_BASE + 0x44) +#define SL_TOUT_CFG (PORT_BASE + 0x8c) +#define SL_CONTROL (PORT_BASE + 0x94) +#define SL_CONTROL_NOTIFY_EN_OFF 0 +#define SL_CONTROL_NOTIFY_EN_MSK (0x1 << SL_CONTROL_NOTIFY_EN_OFF) +#define TX_ID_DWORD0 (PORT_BASE + 0x9c) +#define TX_ID_DWORD1 (PORT_BASE + 0xa0) +#define TX_ID_DWORD2 (PORT_BASE + 0xa4) +#define TX_ID_DWORD3 (PORT_BASE + 0xa8) +#define TX_ID_DWORD4 (PORT_BASE + 0xaC) +#define TX_ID_DWORD5 (PORT_BASE + 0xb0) +#define TX_ID_DWORD6 (PORT_BASE + 0xb4) +#define RX_IDAF_DWORD0 (PORT_BASE + 0xc4) +#define RX_IDAF_DWORD1 (PORT_BASE + 0xc8) +#define RX_IDAF_DWORD2 (PORT_BASE + 0xcc) +#define RX_IDAF_DWORD3 (PORT_BASE + 0xd0) +#define RX_IDAF_DWORD4 (PORT_BASE + 0xd4) +#define RX_IDAF_DWORD5 (PORT_BASE + 0xd8) +#define RX_IDAF_DWORD6 (PORT_BASE + 0xdc) +#define RXOP_CHECK_CFG_H (PORT_BASE + 0xfc) +#define DONE_RECEIVED_TIME (PORT_BASE + 0x12c) +#define CON_CFG_DRIVER (PORT_BASE + 0x130) +#define PHY_CONFIG2 (PORT_BASE + 0x1a8) +#define PHY_CONFIG2_FORCE_TXDEEMPH_OFF 3 +#define PHY_CONFIG2_FORCE_TXDEEMPH_MSK (0x1 << PHY_CONFIG2_FORCE_TXDEEMPH_OFF) +#define PHY_CONFIG2_TX_TRAIN_COMP_OFF 24 +#define PHY_CONFIG2_TX_TRAIN_COMP_MSK (0x1 << PHY_CONFIG2_TX_TRAIN_COMP_OFF) +#define CHL_INT0 (PORT_BASE + 0x1b0) +#define CHL_INT0_PHYCTRL_NOTRDY_OFF 0 +#define CHL_INT0_PHYCTRL_NOTRDY_MSK (0x1 << CHL_INT0_PHYCTRL_NOTRDY_OFF) +#define CHL_INT0_SN_FAIL_NGR_OFF 2 +#define CHL_INT0_SN_FAIL_NGR_MSK (0x1 << CHL_INT0_SN_FAIL_NGR_OFF) +#define CHL_INT0_DWS_LOST_OFF 4 +#define CHL_INT0_DWS_LOST_MSK (0x1 << CHL_INT0_DWS_LOST_OFF) +#define CHL_INT0_SL_IDAF_FAIL_OFF 10 +#define CHL_INT0_SL_IDAF_FAIL_MSK (0x1 << CHL_INT0_SL_IDAF_FAIL_OFF) +#define CHL_INT0_ID_TIMEOUT_OFF 11 +#define CHL_INT0_ID_TIMEOUT_MSK (0x1 << CHL_INT0_ID_TIMEOUT_OFF) +#define CHL_INT0_SL_OPAF_FAIL_OFF 12 +#define CHL_INT0_SL_OPAF_FAIL_MSK (0x1 << CHL_INT0_SL_OPAF_FAIL_OFF) +#define CHL_INT0_SL_PS_FAIL_OFF 21 +#define CHL_INT0_SL_PS_FAIL_MSK (0x1 << CHL_INT0_SL_PS_FAIL_OFF) +#define CHL_INT1 (PORT_BASE + 0x1b4) +#define CHL_INT2 (PORT_BASE + 0x1b8) +#define CHL_INT2_SL_RX_BC_ACK_OFF 2 +#define CHL_INT2_SL_RX_BC_ACK_MSK (0x1 << CHL_INT2_SL_RX_BC_ACK_OFF) +#define CHL_INT2_SL_PHY_ENA_OFF 6 +#define CHL_INT2_SL_PHY_ENA_MSK (0x1 << CHL_INT2_SL_PHY_ENA_OFF) +#define CHL_INT0_MSK (PORT_BASE + 0x1bc) +#define CHL_INT0_MSK_PHYCTRL_NOTRDY_OFF 0 +#define CHL_INT0_MSK_PHYCTRL_NOTRDY_MSK (0x1 << CHL_INT0_MSK_PHYCTRL_NOTRDY_OFF) +#define CHL_INT1_MSK (PORT_BASE + 0x1c0) +#define CHL_INT2_MSK (PORT_BASE + 0x1c4) +#define CHL_INT_COAL_EN (PORT_BASE + 0x1d0) +#define DMA_TX_STATUS (PORT_BASE + 0x2d0) +#define DMA_TX_STATUS_BUSY_OFF 0 +#define DMA_TX_STATUS_BUSY_MSK (0x1 << DMA_TX_STATUS_BUSY_OFF) +#define DMA_RX_STATUS (PORT_BASE + 0x2e8) +#define DMA_RX_STATUS_BUSY_OFF 0 +#define DMA_RX_STATUS_BUSY_MSK (0x1 << DMA_RX_STATUS_BUSY_OFF) + +#define AXI_CFG 0x5100 +#define RESET_VALUE 0x7ffff + +/* HW dma structures */ +/* Delivery queue header */ +/* dw0 */ +#define CMD_HDR_RESP_REPORT_OFF 5 +#define CMD_HDR_RESP_REPORT_MSK 0x20 +#define CMD_HDR_TLR_CTRL_OFF 6 +#define CMD_HDR_TLR_CTRL_MSK 0xc0 +#define CMD_HDR_PORT_OFF 17 +#define CMD_HDR_PORT_MSK 0xe0000 +#define CMD_HDR_PRIORITY_OFF 27 +#define CMD_HDR_PRIORITY_MSK 0x8000000 +#define CMD_HDR_MODE_OFF 28 +#define CMD_HDR_MODE_MSK 0x10000000 +#define CMD_HDR_CMD_OFF 29 +#define CMD_HDR_CMD_MSK 0xe0000000 +/* dw1 */ +#define CMD_HDR_VERIFY_DTL_OFF 10 +#define CMD_HDR_VERIFY_DTL_MSK 0x400 +#define CMD_HDR_SSP_FRAME_TYPE_OFF 13 +#define CMD_HDR_SSP_FRAME_TYPE_MSK 0xe000 +#define CMD_HDR_DEVICE_ID_OFF 16 +#define CMD_HDR_DEVICE_ID_MSK 0xffff0000 +/* dw2 */ +#define CMD_HDR_CFL_OFF 0 +#define CMD_HDR_CFL_MSK 0x1ff +#define CMD_HDR_MRFL_OFF 15 +#define CMD_HDR_MRFL_MSK 0xff8000 +#define CMD_HDR_FIRST_BURST_OFF 25 +#define CMD_HDR_FIRST_BURST_MSK 0x2000000 +/* dw3 */ +#define CMD_HDR_IPTT_OFF 0 +#define CMD_HDR_IPTT_MSK 0xffff +/* dw6 */ +#define CMD_HDR_DATA_SGL_LEN_OFF 16 +#define CMD_HDR_DATA_SGL_LEN_MSK 0xffff0000 + +/* Completion header */ +#define CMPLT_HDR_IPTT_OFF 0 +#define CMPLT_HDR_IPTT_MSK (0xffff << CMPLT_HDR_IPTT_OFF) +#define CMPLT_HDR_CMD_CMPLT_OFF 17 +#define CMPLT_HDR_CMD_CMPLT_MSK (0x1 << CMPLT_HDR_CMD_CMPLT_OFF) +#define CMPLT_HDR_ERR_RCRD_XFRD_OFF 18 +#define CMPLT_HDR_ERR_RCRD_XFRD_MSK (0x1 << CMPLT_HDR_ERR_RCRD_XFRD_OFF) +#define CMPLT_HDR_RSPNS_XFRD_OFF 19 +#define CMPLT_HDR_RSPNS_XFRD_MSK (0x1 << CMPLT_HDR_RSPNS_XFRD_OFF) +#define CMPLT_HDR_IO_CFG_ERR_OFF 27 +#define CMPLT_HDR_IO_CFG_ERR_MSK (0x1 << CMPLT_HDR_IO_CFG_ERR_OFF) + +/* ITCT header */ +/* qw0 */ +#define ITCT_HDR_DEV_TYPE_OFF 0 +#define ITCT_HDR_DEV_TYPE_MSK (0x3 << ITCT_HDR_DEV_TYPE_OFF) +#define ITCT_HDR_VALID_OFF 2 +#define ITCT_HDR_VALID_MSK (0x1 << ITCT_HDR_VALID_OFF) +#define ITCT_HDR_BREAK_REPLY_ENA_OFF 3 +#define ITCT_HDR_BREAK_REPLY_ENA_MSK (0x1 << ITCT_HDR_BREAK_REPLY_ENA_OFF) +#define ITCT_HDR_AWT_CONTROL_OFF 4 +#define ITCT_HDR_AWT_CONTROL_MSK (0x1 << ITCT_HDR_AWT_CONTROL_OFF) +#define ITCT_HDR_MAX_CONN_RATE_OFF 5 +#define ITCT_HDR_MAX_CONN_RATE_MSK (0xf << ITCT_HDR_MAX_CONN_RATE_OFF) +#define ITCT_HDR_VALID_LINK_NUM_OFF 9 +#define ITCT_HDR_VALID_LINK_NUM_MSK (0xf << ITCT_HDR_VALID_LINK_NUM_OFF) +#define ITCT_HDR_PORT_ID_OFF 13 +#define ITCT_HDR_PORT_ID_MSK (0x7 << ITCT_HDR_PORT_ID_OFF) +#define ITCT_HDR_SMP_TIMEOUT_OFF 16 +#define ITCT_HDR_SMP_TIMEOUT_MSK (0xffff << ITCT_HDR_SMP_TIMEOUT_OFF) +#define ITCT_HDR_MAX_BURST_BYTES_OFF 16 +#define ITCT_HDR_MAX_BURST_BYTES_MSK (0xffffffff << \ + ITCT_MAX_BURST_BYTES_OFF) +/* qw1 */ +#define ITCT_HDR_MAX_SAS_ADDR_OFF 0 +#define ITCT_HDR_MAX_SAS_ADDR_MSK (0xffffffffffffffff << \ + ITCT_HDR_MAX_SAS_ADDR_OFF) +/* qw2 */ +#define ITCT_HDR_IT_NEXUS_LOSS_TL_OFF 0 +#define ITCT_HDR_IT_NEXUS_LOSS_TL_MSK (0xffff << \ + ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) +#define ITCT_HDR_BUS_INACTIVE_TL_OFF 16 +#define ITCT_HDR_BUS_INACTIVE_TL_MSK (0xffff << \ + ITCT_HDR_BUS_INACTIVE_TL_OFF) +#define ITCT_HDR_MAX_CONN_TL_OFF 32 +#define ITCT_HDR_MAX_CONN_TL_MSK (0xffff << \ + ITCT_HDR_MAX_CONN_TL_OFF) +#define ITCT_HDR_REJ_OPEN_TL_OFF 48 +#define ITCT_HDR_REJ_OPEN_TL_MSK (0xffff << \ + ITCT_REJ_OPEN_TL_OFF) + +/* Err record header */ +#define ERR_HDR_DMA_TX_ERR_TYPE_OFF 0 +#define ERR_HDR_DMA_TX_ERR_TYPE_MSK (0xffff << ERR_HDR_DMA_TX_ERR_TYPE_OFF) +#define ERR_HDR_DMA_RX_ERR_TYPE_OFF 16 +#define ERR_HDR_DMA_RX_ERR_TYPE_MSK (0xffff << ERR_HDR_DMA_RX_ERR_TYPE_OFF) struct hisi_sas_complete_v1_hdr { __le32 data; }; + +enum { + HISI_SAS_PHY_BCAST_ACK = 0, + HISI_SAS_PHY_SL_PHY_ENABLED, + HISI_SAS_PHY_INT_ABNORMAL, + HISI_SAS_PHY_INT_NR +}; + +enum { + DMA_TX_ERR_BASE = 0x0, + DMA_RX_ERR_BASE = 0x100, + TRANS_TX_FAIL_BASE = 0x200, + TRANS_RX_FAIL_BASE = 0x300, + + /* dma tx */ + DMA_TX_DIF_CRC_ERR = DMA_TX_ERR_BASE, /* 0x0 */ + DMA_TX_DIF_APP_ERR, /* 0x1 */ + DMA_TX_DIF_RPP_ERR, /* 0x2 */ + DMA_TX_AXI_BUS_ERR, /* 0x3 */ + DMA_TX_DATA_SGL_OVERFLOW_ERR, /* 0x4 */ + DMA_TX_DIF_SGL_OVERFLOW_ERR, /* 0x5 */ + DMA_TX_UNEXP_XFER_RDY_ERR, /* 0x6 */ + DMA_TX_XFER_RDY_OFFSET_ERR, /* 0x7 */ + DMA_TX_DATA_UNDERFLOW_ERR, /* 0x8 */ + DMA_TX_XFER_RDY_LENGTH_OVERFLOW_ERR, /* 0x9 */ + + /* dma rx */ + DMA_RX_BUFFER_ECC_ERR = DMA_RX_ERR_BASE, /* 0x100 */ + DMA_RX_DIF_CRC_ERR, /* 0x101 */ + DMA_RX_DIF_APP_ERR, /* 0x102 */ + DMA_RX_DIF_RPP_ERR, /* 0x103 */ + DMA_RX_RESP_BUFFER_OVERFLOW_ERR, /* 0x104 */ + DMA_RX_AXI_BUS_ERR, /* 0x105 */ + DMA_RX_DATA_SGL_OVERFLOW_ERR, /* 0x106 */ + DMA_RX_DIF_SGL_OVERFLOW_ERR, /* 0x107 */ + DMA_RX_DATA_OFFSET_ERR, /* 0x108 */ + DMA_RX_UNEXP_RX_DATA_ERR, /* 0x109 */ + DMA_RX_DATA_OVERFLOW_ERR, /* 0x10a */ + DMA_RX_DATA_UNDERFLOW_ERR, /* 0x10b */ + DMA_RX_UNEXP_RETRANS_RESP_ERR, /* 0x10c */ + + /* trans tx */ + TRANS_TX_RSVD0_ERR = TRANS_TX_FAIL_BASE, /* 0x200 */ + TRANS_TX_PHY_NOT_ENABLE_ERR, /* 0x201 */ + TRANS_TX_OPEN_REJCT_WRONG_DEST_ERR, /* 0x202 */ + TRANS_TX_OPEN_REJCT_ZONE_VIOLATION_ERR, /* 0x203 */ + TRANS_TX_OPEN_REJCT_BY_OTHER_ERR, /* 0x204 */ + TRANS_TX_RSVD1_ERR, /* 0x205 */ + TRANS_TX_OPEN_REJCT_AIP_TIMEOUT_ERR, /* 0x206 */ + TRANS_TX_OPEN_REJCT_STP_BUSY_ERR, /* 0x207 */ + TRANS_TX_OPEN_REJCT_PROTOCOL_NOT_SUPPORT_ERR, /* 0x208 */ + TRANS_TX_OPEN_REJCT_RATE_NOT_SUPPORT_ERR, /* 0x209 */ + TRANS_TX_OPEN_REJCT_BAD_DEST_ERR, /* 0x20a */ + TRANS_TX_OPEN_BREAK_RECEIVE_ERR, /* 0x20b */ + TRANS_TX_LOW_PHY_POWER_ERR, /* 0x20c */ + TRANS_TX_OPEN_REJCT_PATHWAY_BLOCKED_ERR, /* 0x20d */ + TRANS_TX_OPEN_TIMEOUT_ERR, /* 0x20e */ + TRANS_TX_OPEN_REJCT_NO_DEST_ERR, /* 0x20f */ + TRANS_TX_OPEN_RETRY_ERR, /* 0x210 */ + TRANS_TX_RSVD2_ERR, /* 0x211 */ + TRANS_TX_BREAK_TIMEOUT_ERR, /* 0x212 */ + TRANS_TX_BREAK_REQUEST_ERR, /* 0x213 */ + TRANS_TX_BREAK_RECEIVE_ERR, /* 0x214 */ + TRANS_TX_CLOSE_TIMEOUT_ERR, /* 0x215 */ + TRANS_TX_CLOSE_NORMAL_ERR, /* 0x216 */ + TRANS_TX_CLOSE_PHYRESET_ERR, /* 0x217 */ + TRANS_TX_WITH_CLOSE_DWS_TIMEOUT_ERR, /* 0x218 */ + TRANS_TX_WITH_CLOSE_COMINIT_ERR, /* 0x219 */ + TRANS_TX_NAK_RECEIVE_ERR, /* 0x21a */ + TRANS_TX_ACK_NAK_TIMEOUT_ERR, /* 0x21b */ + TRANS_TX_CREDIT_TIMEOUT_ERR, /* 0x21c */ + TRANS_TX_IPTT_CONFLICT_ERR, /* 0x21d */ + TRANS_TX_TXFRM_TYPE_ERR, /* 0x21e */ + TRANS_TX_TXSMP_LENGTH_ERR, /* 0x21f */ + + /* trans rx */ + TRANS_RX_FRAME_CRC_ERR = TRANS_RX_FAIL_BASE, /* 0x300 */ + TRANS_RX_FRAME_DONE_ERR, /* 0x301 */ + TRANS_RX_FRAME_ERRPRM_ERR, /* 0x302 */ + TRANS_RX_FRAME_NO_CREDIT_ERR, /* 0x303 */ + TRANS_RX_RSVD0_ERR, /* 0x304 */ + TRANS_RX_FRAME_OVERRUN_ERR, /* 0x305 */ + TRANS_RX_FRAME_NO_EOF_ERR, /* 0x306 */ + TRANS_RX_LINK_BUF_OVERRUN_ERR, /* 0x307 */ + TRANS_RX_BREAK_TIMEOUT_ERR, /* 0x308 */ + TRANS_RX_BREAK_REQUEST_ERR, /* 0x309 */ + TRANS_RX_BREAK_RECEIVE_ERR, /* 0x30a */ + TRANS_RX_CLOSE_TIMEOUT_ERR, /* 0x30b */ + TRANS_RX_CLOSE_NORMAL_ERR, /* 0x30c */ + TRANS_RX_CLOSE_PHYRESET_ERR, /* 0x30d */ + TRANS_RX_WITH_CLOSE_DWS_TIMEOUT_ERR, /* 0x30e */ + TRANS_RX_WITH_CLOSE_COMINIT_ERR, /* 0x30f */ + TRANS_RX_DATA_LENGTH0_ERR, /* 0x310 */ + TRANS_RX_BAD_HASH_ERR, /* 0x311 */ + TRANS_RX_XRDY_ZERO_ERR, /* 0x312 */ + TRANS_RX_SSP_FRAME_LEN_ERR, /* 0x313 */ + TRANS_RX_TRANS_RX_RSVD1_ERR, /* 0x314 */ + TRANS_RX_NO_BALANCE_ERR, /* 0x315 */ + TRANS_RX_TRANS_RX_RSVD2_ERR, /* 0x316 */ + TRANS_RX_TRANS_RX_RSVD3_ERR, /* 0x317 */ + TRANS_RX_BAD_FRAME_TYPE_ERR, /* 0x318 */ + TRANS_RX_SMP_FRAME_LEN_ERR, /* 0x319 */ + TRANS_RX_SMP_RESP_TIMEOUT_ERR, /* 0x31a */ +}; + +#define HISI_SAS_PHY_MAX_INT_NR (HISI_SAS_PHY_INT_NR * HISI_SAS_MAX_PHYS) +#define HISI_SAS_CQ_MAX_INT_NR (HISI_SAS_MAX_QUEUES) +#define HISI_SAS_FATAL_INT_NR (2) + +#define HISI_SAS_MAX_INT_NR \ + (HISI_SAS_PHY_MAX_INT_NR + HISI_SAS_CQ_MAX_INT_NR +\ + HISI_SAS_FATAL_INT_NR) + static const struct hisi_sas_hw hisi_sas_v1_hw = { .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr), }; -- GitLab From 8ff1d5718e9d42e3d0d2331492b5cb49b5c5442b Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:46 +0800 Subject: [PATCH 0672/2855] hisi_sas: Add v1 hardware initialisation code Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 1 + drivers/scsi/hisi_sas/hisi_sas_main.c | 4 + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 337 +++++++++++++++++++++++++ 3 files changed, 342 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 72533cae320d8..ba3bf5eed7455 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -81,6 +81,7 @@ struct hisi_sas_slot { }; struct hisi_sas_hw { + int (*hw_init)(struct hisi_hba *hisi_hba); int complete_hdr_size; }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 06b863c401247..6c13547f23d2b 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -402,6 +402,10 @@ int hisi_sas_probe(struct platform_device *pdev, hisi_sas_init_add(hisi_hba); + rc = hisi_hba->hw->hw_init(hisi_hba); + if (rc) + goto err_out_ha; + rc = scsi_add_host(shost, &pdev->dev); if (rc) goto err_out_ha; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 9fe89bb847793..9bfe1aaad971e 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -405,7 +405,344 @@ enum { (HISI_SAS_PHY_MAX_INT_NR + HISI_SAS_CQ_MAX_INT_NR +\ HISI_SAS_FATAL_INT_NR) +static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off) +{ + void __iomem *regs = hisi_hba->regs + off; + + return readl(regs); +} + +static void hisi_sas_write32(struct hisi_hba *hisi_hba, + u32 off, u32 val) +{ + void __iomem *regs = hisi_hba->regs + off; + + writel(val, regs); +} + +static void hisi_sas_phy_write32(struct hisi_hba *hisi_hba, + int phy_no, u32 off, u32 val) +{ + void __iomem *regs = hisi_hba->regs + (0x400 * phy_no) + off; + + writel(val, regs); +} + +static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba, + int phy_no, u32 off) +{ + void __iomem *regs = hisi_hba->regs + (0x400 * phy_no) + off; + + return readl(regs); +} + +static void config_phy_opt_mode_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG); + + cfg &= ~PHY_CFG_DC_OPT_MSK; + cfg |= 1 << PHY_CFG_DC_OPT_OFF; + hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); +} + +static void config_tx_tfe_autoneg_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CONFIG2); + + cfg &= ~PHY_CONFIG2_FORCE_TXDEEMPH_MSK; + hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CONFIG2, cfg); +} + +static void config_id_frame_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + struct sas_identify_frame identify_frame; + u32 *identify_buffer; + + memset(&identify_frame, 0, sizeof(identify_frame)); + identify_frame.dev_type = SAS_END_DEVICE; + identify_frame.frame_type = 0; + identify_frame._un1 = 1; + identify_frame.initiator_bits = SAS_PROTOCOL_ALL; + identify_frame.target_bits = SAS_PROTOCOL_NONE; + memcpy(&identify_frame._un4_11[0], hisi_hba->sas_addr, SAS_ADDR_SIZE); + memcpy(&identify_frame.sas_addr[0], hisi_hba->sas_addr, SAS_ADDR_SIZE); + identify_frame.phy_id = phy_no; + identify_buffer = (u32 *)(&identify_frame); + + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD0, + __swab32(identify_buffer[0])); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD1, + identify_buffer[2]); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD2, + identify_buffer[1]); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD3, + identify_buffer[4]); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD4, + identify_buffer[3]); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD5, + __swab32(identify_buffer[5])); +} + +static void init_id_frame_v1_hw(struct hisi_hba *hisi_hba) +{ + int i; + + for (i = 0; i < hisi_hba->n_phy; i++) + config_id_frame_v1_hw(hisi_hba, i); +} + +static int reset_hw_v1_hw(struct hisi_hba *hisi_hba) +{ + int i; + unsigned long end_time; + u32 val; + struct device *dev = &hisi_hba->pdev->dev; + + for (i = 0; i < hisi_hba->n_phy; i++) { + u32 phy_ctrl = hisi_sas_phy_read32(hisi_hba, i, PHY_CTRL); + + phy_ctrl |= PHY_CTRL_RESET_MSK; + hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL, phy_ctrl); + } + msleep(1); /* It is safe to wait for 50us */ + + /* Ensure DMA tx & rx idle */ + for (i = 0; i < hisi_hba->n_phy; i++) { + u32 dma_tx_status, dma_rx_status; + + end_time = jiffies + msecs_to_jiffies(1000); + + while (1) { + dma_tx_status = hisi_sas_phy_read32(hisi_hba, i, + DMA_TX_STATUS); + dma_rx_status = hisi_sas_phy_read32(hisi_hba, i, + DMA_RX_STATUS); + + if (!(dma_tx_status & DMA_TX_STATUS_BUSY_MSK) && + !(dma_rx_status & DMA_RX_STATUS_BUSY_MSK)) + break; + + msleep(20); + if (time_after(jiffies, end_time)) + return -EIO; + } + } + + /* Ensure axi bus idle */ + end_time = jiffies + msecs_to_jiffies(1000); + while (1) { + u32 axi_status = + hisi_sas_read32(hisi_hba, AXI_CFG); + + if (axi_status == 0) + break; + + msleep(20); + if (time_after(jiffies, end_time)) + return -EIO; + } + + /* Apply reset and disable clock */ + /* clk disable reg is offset by +4 bytes from clk enable reg */ + regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_reset_reg, + RESET_VALUE); + regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_clock_ena_reg + 4, + RESET_VALUE); + msleep(1); + regmap_read(hisi_hba->ctrl, hisi_hba->ctrl_reset_sts_reg, &val); + if (RESET_VALUE != (val & RESET_VALUE)) { + dev_err(dev, "Reset failed\n"); + return -EIO; + } + + /* De-reset and enable clock */ + /* deassert rst reg is offset by +4 bytes from assert reg */ + regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_reset_reg + 4, + RESET_VALUE); + regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_clock_ena_reg, + RESET_VALUE); + msleep(1); + regmap_read(hisi_hba->ctrl, hisi_hba->ctrl_reset_sts_reg, &val); + if (val & RESET_VALUE) { + dev_err(dev, "De-reset failed\n"); + return -EIO; + } + + return 0; +} + +static void init_reg_v1_hw(struct hisi_hba *hisi_hba) +{ + int i; + + /* Global registers init*/ + hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, + (u32)((1ULL << hisi_hba->queue_count) - 1)); + hisi_sas_write32(hisi_hba, HGC_TRANS_TASK_CNT_LIMIT, 0x11); + hisi_sas_write32(hisi_hba, DEVICE_MSG_WORK_MODE, 0x1); + hisi_sas_write32(hisi_hba, HGC_SAS_TXFAIL_RETRY_CTRL, 0x1ff); + hisi_sas_write32(hisi_hba, HGC_ERR_STAT_EN, 0x401); + hisi_sas_write32(hisi_hba, CFG_1US_TIMER_TRSH, 0x64); + hisi_sas_write32(hisi_hba, HGC_GET_ITV_TIME, 0x1); + hisi_sas_write32(hisi_hba, I_T_NEXUS_LOSS_TIME, 0x64); + hisi_sas_write32(hisi_hba, BUS_INACTIVE_LIMIT_TIME, 0x2710); + hisi_sas_write32(hisi_hba, REJECT_TO_OPEN_LIMIT_TIME, 0x1); + hisi_sas_write32(hisi_hba, CFG_AGING_TIME, 0x7a12); + hisi_sas_write32(hisi_hba, HGC_DFX_CFG2, 0x9c40); + hisi_sas_write32(hisi_hba, FIS_LIST_BADDR_L, 0x2); + hisi_sas_write32(hisi_hba, INT_COAL_EN, 0xc); + hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x186a0); + hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 1); + hisi_sas_write32(hisi_hba, ENT_INT_COAL_TIME, 0x1); + hisi_sas_write32(hisi_hba, ENT_INT_COAL_CNT, 0x1); + hisi_sas_write32(hisi_hba, OQ_INT_SRC, 0xffffffff); + hisi_sas_write32(hisi_hba, OQ_INT_SRC_MSK, 0); + hisi_sas_write32(hisi_hba, ENT_INT_SRC1, 0xffffffff); + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0); + hisi_sas_write32(hisi_hba, ENT_INT_SRC2, 0xffffffff); + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0); + hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0); + hisi_sas_write32(hisi_hba, AXI_AHB_CLK_CFG, 0x2); + hisi_sas_write32(hisi_hba, CFG_SAS_CONFIG, 0x22000000); + + for (i = 0; i < hisi_hba->n_phy; i++) { + hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE, 0x88a); + hisi_sas_phy_write32(hisi_hba, i, PHY_CONFIG2, 0x7c080); + hisi_sas_phy_write32(hisi_hba, i, PHY_RATE_NEGO, 0x415ee00); + hisi_sas_phy_write32(hisi_hba, i, PHY_PCN, 0x80a80000); + hisi_sas_phy_write32(hisi_hba, i, SL_TOUT_CFG, 0x7d7d7d7d); + hisi_sas_phy_write32(hisi_hba, i, DONE_RECEIVED_TIME, 0x0); + hisi_sas_phy_write32(hisi_hba, i, RXOP_CHECK_CFG_H, 0x1000); + hisi_sas_phy_write32(hisi_hba, i, DONE_RECEIVED_TIME, 0); + hisi_sas_phy_write32(hisi_hba, i, CON_CFG_DRIVER, 0x13f0a); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT_COAL_EN, 3); + hisi_sas_phy_write32(hisi_hba, i, DONE_RECEIVED_TIME, 8); + } + + for (i = 0; i < hisi_hba->queue_count; i++) { + /* Delivery queue */ + hisi_sas_write32(hisi_hba, + DLVRY_Q_0_BASE_ADDR_HI + (i * 0x14), + upper_32_bits(hisi_hba->cmd_hdr_dma[i])); + + hisi_sas_write32(hisi_hba, + DLVRY_Q_0_BASE_ADDR_LO + (i * 0x14), + lower_32_bits(hisi_hba->cmd_hdr_dma[i])); + + hisi_sas_write32(hisi_hba, + DLVRY_Q_0_DEPTH + (i * 0x14), + HISI_SAS_QUEUE_SLOTS); + + /* Completion queue */ + hisi_sas_write32(hisi_hba, + COMPL_Q_0_BASE_ADDR_HI + (i * 0x14), + upper_32_bits(hisi_hba->complete_hdr_dma[i])); + + hisi_sas_write32(hisi_hba, + COMPL_Q_0_BASE_ADDR_LO + (i * 0x14), + lower_32_bits(hisi_hba->complete_hdr_dma[i])); + + hisi_sas_write32(hisi_hba, COMPL_Q_0_DEPTH + (i * 0x14), + HISI_SAS_QUEUE_SLOTS); + } + + /* itct */ + hisi_sas_write32(hisi_hba, ITCT_BASE_ADDR_LO, + lower_32_bits(hisi_hba->itct_dma)); + + hisi_sas_write32(hisi_hba, ITCT_BASE_ADDR_HI, + upper_32_bits(hisi_hba->itct_dma)); + + /* iost */ + hisi_sas_write32(hisi_hba, IOST_BASE_ADDR_LO, + lower_32_bits(hisi_hba->iost_dma)); + + hisi_sas_write32(hisi_hba, IOST_BASE_ADDR_HI, + upper_32_bits(hisi_hba->iost_dma)); + + /* breakpoint */ + hisi_sas_write32(hisi_hba, BROKEN_MSG_ADDR_LO, + lower_32_bits(hisi_hba->breakpoint_dma)); + + hisi_sas_write32(hisi_hba, BROKEN_MSG_ADDR_HI, + upper_32_bits(hisi_hba->breakpoint_dma)); +} + +static int hw_init_v1_hw(struct hisi_hba *hisi_hba) +{ + struct device *dev = &hisi_hba->pdev->dev; + int rc; + + rc = reset_hw_v1_hw(hisi_hba); + if (rc) { + dev_err(dev, "hisi_sas_reset_hw failed, rc=%d", rc); + return rc; + } + + msleep(100); + init_reg_v1_hw(hisi_hba); + + init_id_frame_v1_hw(hisi_hba); + + return 0; +} + +static void enable_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG); + + cfg |= PHY_CFG_ENA_MSK; + hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); +} + +static void start_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + config_id_frame_v1_hw(hisi_hba, phy_no); + config_phy_opt_mode_v1_hw(hisi_hba, phy_no); + config_tx_tfe_autoneg_v1_hw(hisi_hba, phy_no); + enable_phy_v1_hw(hisi_hba, phy_no); +} + +static void start_phys_v1_hw(unsigned long data) +{ + struct hisi_hba *hisi_hba = (struct hisi_hba *)data; + int i; + + for (i = 0; i < hisi_hba->n_phy; i++) { + hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x12a); + start_phy_v1_hw(hisi_hba, i); + } +} + +static void phys_init_v1_hw(struct hisi_hba *hisi_hba) +{ + int i; + struct timer_list *timer = &hisi_hba->timer; + + for (i = 0; i < hisi_hba->n_phy; i++) { + hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x6a); + hisi_sas_phy_read32(hisi_hba, i, CHL_INT2_MSK); + } + + setup_timer(timer, start_phys_v1_hw, (unsigned long)hisi_hba); + mod_timer(timer, jiffies + HZ); +} + +static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) +{ + int rc; + + rc = hw_init_v1_hw(hisi_hba); + if (rc) + return rc; + + phys_init_v1_hw(hisi_hba); + + return 0; +} + static const struct hisi_sas_hw hisi_sas_v1_hw = { + .hw_init = hisi_sas_v1_init, .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr), }; -- GitLab From 07d785923fa5353eabb451976defeedd407936ac Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:47 +0800 Subject: [PATCH 0673/2855] hisi_sas: Add v1 hardware interrupt init Add code to interrupts, so now we can get a phy up interrupt when a disk is connected. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 5 + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 161 +++++++++++++++++++++++++ 2 files changed, 166 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index ba3bf5eed7455..938fa755300b1 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -38,6 +38,11 @@ #define HISI_SAS_NAME_LEN 32 +enum { + PORT_TYPE_SAS = (1U << 1), + PORT_TYPE_SATA = (1U << 0), +}; + enum dev_status { HISI_SAS_DEV_NORMAL, HISI_SAS_DEV_EH, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 9bfe1aaad971e..3ea666f54d489 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -728,6 +728,159 @@ static void phys_init_v1_hw(struct hisi_hba *hisi_hba) mod_timer(timer, jiffies + HZ); } +/* Interrupts */ +static irqreturn_t int_phyup_v1_hw(int irq_no, void *p) +{ + struct hisi_sas_phy *phy = p; + struct hisi_hba *hisi_hba = phy->hisi_hba; + struct device *dev = &hisi_hba->pdev->dev; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + int i, phy_no = sas_phy->id; + u32 irq_value, context, port_id, link_rate; + u32 *frame_rcvd = (u32 *)sas_phy->frame_rcvd; + struct sas_identify_frame *id = (struct sas_identify_frame *)frame_rcvd; + irqreturn_t res = IRQ_HANDLED; + + irq_value = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2); + if (!(irq_value & CHL_INT2_SL_PHY_ENA_MSK)) { + dev_dbg(dev, "phyup: irq_value = %x not set enable bit\n", + irq_value); + res = IRQ_NONE; + goto end; + } + + context = hisi_sas_read32(hisi_hba, PHY_CONTEXT); + if (context & 1 << phy_no) { + dev_err(dev, "phyup: phy%d SATA attached equipment\n", + phy_no); + goto end; + } + + port_id = (hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA) >> (4 * phy_no)) + & 0xf; + if (port_id == 0xf) { + dev_err(dev, "phyup: phy%d invalid portid\n", phy_no); + res = IRQ_NONE; + goto end; + } + + for (i = 0; i < 6; i++) { + u32 idaf = hisi_sas_phy_read32(hisi_hba, phy_no, + RX_IDAF_DWORD0 + (i * 4)); + frame_rcvd[i] = __swab32(idaf); + } + + /* Get the linkrate */ + link_rate = hisi_sas_read32(hisi_hba, PHY_CONN_RATE); + link_rate = (link_rate >> (phy_no * 4)) & 0xf; + sas_phy->linkrate = link_rate; + sas_phy->oob_mode = SAS_OOB_MODE; + memcpy(sas_phy->attached_sas_addr, + &id->sas_addr, SAS_ADDR_SIZE); + dev_info(dev, "phyup: phy%d link_rate=%d\n", + phy_no, link_rate); + phy->port_id = port_id; + phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA); + phy->phy_type |= PORT_TYPE_SAS; + phy->phy_attached = 1; + phy->identify.device_type = id->dev_type; + phy->frame_rcvd_size = sizeof(struct sas_identify_frame); + if (phy->identify.device_type == SAS_END_DEVICE) + phy->identify.target_port_protocols = + SAS_PROTOCOL_SSP; + else if (phy->identify.device_type != SAS_PHY_UNUSED) + phy->identify.target_port_protocols = + SAS_PROTOCOL_SMP; + +end: + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, + CHL_INT2_SL_PHY_ENA_MSK); + + if (irq_value & CHL_INT2_SL_PHY_ENA_MSK) { + u32 chl_int0 = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT0); + + chl_int0 &= ~CHL_INT0_PHYCTRL_NOTRDY_MSK; + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, chl_int0); + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0_MSK, 0x3ce3ee); + } + + return res; +} +static const char phy_int_names[HISI_SAS_PHY_INT_NR][32] = { + {"Phy Up"}, +}; +static irq_handler_t phy_interrupts[HISI_SAS_PHY_INT_NR] = { + int_phyup_v1_hw, +}; + +static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) +{ + struct device *dev = &hisi_hba->pdev->dev; + struct device_node *np = dev->of_node; + char *int_names = hisi_hba->int_names; + int i, j, irq, rc, idx; + + if (!np) + return -ENOENT; + + for (i = 0; i < hisi_hba->n_phy; i++) { + struct hisi_sas_phy *phy = &hisi_hba->phy[i]; + + idx = i * HISI_SAS_PHY_INT_NR; + for (j = 0; j < HISI_SAS_PHY_INT_NR; j++, idx++) { + irq = irq_of_parse_and_map(np, idx); + if (!irq) { + dev_err(dev, + "irq init: fail map phy interrupt %d\n", + idx); + return -ENOENT; + } + + (void)snprintf(&int_names[idx * HISI_SAS_NAME_LEN], + HISI_SAS_NAME_LEN, + "%s %s:%d", dev_name(dev), + phy_int_names[j], i); + rc = devm_request_irq(dev, irq, phy_interrupts[j], 0, + &int_names[idx * HISI_SAS_NAME_LEN], + phy); + if (rc) { + dev_err(dev, "irq init: could not request " + "phy interrupt %d, rc=%d\n", + irq, rc); + return -ENOENT; + } + } + } + return 0; +} + +static int interrupt_openall_v1_hw(struct hisi_hba *hisi_hba) +{ + int i; + u32 val; + + for (i = 0; i < hisi_hba->n_phy; i++) { + /* Clear interrupt status */ + val = hisi_sas_phy_read32(hisi_hba, i, CHL_INT0); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT0, val); + val = hisi_sas_phy_read32(hisi_hba, i, CHL_INT1); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, val); + val = hisi_sas_phy_read32(hisi_hba, i, CHL_INT2); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, val); + + /* Unmask interrupt */ + hisi_sas_phy_write32(hisi_hba, i, CHL_INT0_MSK, 0x3ce3ee); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0x17fff); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x8000012a); + + /* bypass chip bug mask abnormal intr */ + hisi_sas_phy_write32(hisi_hba, i, CHL_INT0_MSK, + 0x3fffff & ~CHL_INT0_MSK_PHYCTRL_NOTRDY_MSK); + } + + return 0; +} + static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) { int rc; @@ -736,6 +889,14 @@ static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) if (rc) return rc; + rc = interrupt_init_v1_hw(hisi_hba); + if (rc) + return rc; + + rc = interrupt_openall_v1_hw(hisi_hba); + if (rc) + return rc; + phys_init_v1_hw(hisi_hba); return 0; -- GitLab From 66139921973db60c2fc93a4d467c3c574d9657a0 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:48 +0800 Subject: [PATCH 0674/2855] hisi_sas: Add path from phyup irq to SAS framework Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 2 ++ drivers/scsi/hisi_sas/hisi_sas_main.c | 49 ++++++++++++++++++++++++++ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 15 ++++++++ 3 files changed, 66 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 938fa755300b1..837d13976e6f4 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -53,6 +53,7 @@ struct hisi_sas_phy { struct asd_sas_phy sas_phy; struct sas_identify identify; struct timer_list timer; + struct work_struct phyup_ws; u64 port_id; /* from hw */ u64 dev_sas_addr; u64 phy_type; @@ -87,6 +88,7 @@ struct hisi_sas_slot { struct hisi_sas_hw { int (*hw_init)(struct hisi_hba *hisi_hba); + void (*sl_notify)(struct hisi_hba *hisi_hba, int phy_no); int complete_hdr_size; }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 6c13547f23d2b..7bf6d2f5df0af 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -27,6 +27,53 @@ static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba) hisi_sas_slot_index_clear(hisi_hba, i); } +static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no) +{ + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + struct sas_ha_struct *sas_ha; + + if (!phy->phy_attached) + return; + + sas_ha = &hisi_hba->sha; + sas_ha->notify_phy_event(sas_phy, PHYE_OOB_DONE); + + if (sas_phy->phy) { + struct sas_phy *sphy = sas_phy->phy; + + sphy->negotiated_linkrate = sas_phy->linkrate; + sphy->minimum_linkrate = phy->minimum_linkrate; + sphy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS; + sphy->maximum_linkrate = phy->maximum_linkrate; + } + + if (phy->phy_type & PORT_TYPE_SAS) { + struct sas_identify_frame *id; + + id = (struct sas_identify_frame *)phy->frame_rcvd; + id->dev_type = phy->identify.device_type; + id->initiator_bits = SAS_PROTOCOL_ALL; + id->target_bits = phy->identify.target_port_protocols; + } else if (phy->phy_type & PORT_TYPE_SATA) { + /*Nothing*/ + } + + sas_phy->frame_rcvd_size = phy->frame_rcvd_size; + sas_ha->notify_port_event(sas_phy, PORTE_BYTES_DMAED); +} + +static void hisi_sas_phyup_work(struct work_struct *work) +{ + struct hisi_sas_phy *phy = + container_of(work, struct hisi_sas_phy, phyup_ws); + struct hisi_hba *hisi_hba = phy->hisi_hba; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + int phy_no = sas_phy->id; + + hisi_hba->hw->sl_notify(hisi_hba, phy_no); /* This requires a sleep */ + hisi_sas_bytes_dmaed(hisi_hba, phy_no); +} static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) { @@ -49,6 +96,8 @@ static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) sas_phy->frame_rcvd = &phy->frame_rcvd[0]; sas_phy->ha = (struct sas_ha_struct *)hisi_hba->shost->hostdata; sas_phy->lldd_phy = phy; + + INIT_WORK(&phy->phyup_ws, hisi_sas_phyup_work); } static struct scsi_transport_template *hisi_sas_stt; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 3ea666f54d489..43642798b89c1 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -728,6 +728,19 @@ static void phys_init_v1_hw(struct hisi_hba *hisi_hba) mod_timer(timer, jiffies + HZ); } +static void sl_notify_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + u32 sl_control; + + sl_control = hisi_sas_phy_read32(hisi_hba, phy_no, SL_CONTROL); + sl_control |= SL_CONTROL_NOTIFY_EN_MSK; + hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL, sl_control); + msleep(1); + sl_control = hisi_sas_phy_read32(hisi_hba, phy_no, SL_CONTROL); + sl_control &= ~SL_CONTROL_NOTIFY_EN_MSK; + hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL, sl_control); +} + /* Interrupts */ static irqreturn_t int_phyup_v1_hw(int irq_no, void *p) { @@ -791,6 +804,7 @@ static irqreturn_t int_phyup_v1_hw(int irq_no, void *p) else if (phy->identify.device_type != SAS_PHY_UNUSED) phy->identify.target_port_protocols = SAS_PROTOCOL_SMP; + queue_work(hisi_hba->wq, &phy->phyup_ws); end: hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, @@ -904,6 +918,7 @@ static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) static const struct hisi_sas_hw hisi_sas_v1_hw = { .hw_init = hisi_sas_v1_init, + .sl_notify = sl_notify_v1_hw, .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr), }; -- GitLab From 42e7a69368a5855b36cbaff130e58e2cc9976ff3 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:49 +0800 Subject: [PATCH 0675/2855] hisi_sas: Add ssp command function Add path to send ssp command to HW. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 30 ++++ drivers/scsi/hisi_sas/hisi_sas_main.c | 234 +++++++++++++++++++++++++ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 194 ++++++++++++++++++++ 3 files changed, 458 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 837d13976e6f4..72657eb770f69 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -35,6 +35,8 @@ #define HISI_SAS_COMMAND_TABLE_SZ \ (((sizeof(union hisi_sas_command_table)+3)/4)*4) +#define HISI_SAS_MAX_SSP_RESP_SZ (sizeof(struct ssp_frame_hdr) + 1024) + #define HISI_SAS_NAME_LEN 32 @@ -80,15 +82,41 @@ struct hisi_sas_cq { struct hisi_sas_device { enum sas_device_type dev_type; u64 device_id; + u64 running_req; u8 dev_status; }; struct hisi_sas_slot { + struct list_head entry; + struct sas_task *task; + struct hisi_sas_port *port; + u64 n_elem; + int dlvry_queue; + int dlvry_queue_slot; + int idx; + void *cmd_hdr; + dma_addr_t cmd_hdr_dma; + void *status_buffer; + dma_addr_t status_buffer_dma; + void *command_table; + dma_addr_t command_table_dma; + struct hisi_sas_sge_page *sge_page; + dma_addr_t sge_page_dma; +}; + +struct hisi_sas_tmf_task { + u8 tmf; + u16 tag_of_task_to_be_managed; }; struct hisi_sas_hw { int (*hw_init)(struct hisi_hba *hisi_hba); void (*sl_notify)(struct hisi_hba *hisi_hba, int phy_no); + int (*get_free_slot)(struct hisi_hba *hisi_hba, int *q, int *s); + void (*start_delivery)(struct hisi_hba *hisi_hba); + int (*prep_ssp)(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot, int is_tmf, + struct hisi_sas_tmf_task *tmf); int complete_hdr_size; }; @@ -122,7 +150,9 @@ struct hisi_hba { struct hisi_sas_port port[HISI_SAS_MAX_PHYS]; int queue_count; + int queue; char *int_names; + struct hisi_sas_slot *slot_prep; struct dma_pool *sge_page_pool; struct hisi_sas_device devices[HISI_SAS_MAX_DEVICES]; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 7bf6d2f5df0af..660ef6cac3ab9 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -12,6 +12,15 @@ #include "hisi_sas.h" #define DRV_NAME "hisi_sas" + +#define DEV_IS_GONE(dev) \ + ((!dev) || (dev->dev_type == SAS_PHY_UNUSED)) + +static struct hisi_hba *dev_to_hisi_hba(struct domain_device *device) +{ + return device->port->ha->lldd_ha; +} + static void hisi_sas_slot_index_clear(struct hisi_hba *hisi_hba, int slot_idx) { void *bitmap = hisi_hba->slot_index_tags; @@ -19,6 +28,31 @@ static void hisi_sas_slot_index_clear(struct hisi_hba *hisi_hba, int slot_idx) clear_bit(slot_idx, bitmap); } +static void hisi_sas_slot_index_free(struct hisi_hba *hisi_hba, int slot_idx) +{ + hisi_sas_slot_index_clear(hisi_hba, slot_idx); +} + +static void hisi_sas_slot_index_set(struct hisi_hba *hisi_hba, int slot_idx) +{ + void *bitmap = hisi_hba->slot_index_tags; + + set_bit(slot_idx, bitmap); +} + +static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba, int *slot_idx) +{ + unsigned int index; + void *bitmap = hisi_hba->slot_index_tags; + + index = find_first_zero_bit(bitmap, hisi_hba->slot_index_count); + if (index >= hisi_hba->slot_index_count) + return -SAS_QUEUE_FULL; + hisi_sas_slot_index_set(hisi_hba, index); + *slot_idx = index; + return 0; +} + static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba) { int i; @@ -26,6 +60,199 @@ static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba) for (i = 0; i < hisi_hba->slot_index_count; ++i) hisi_sas_slot_index_clear(hisi_hba, i); } +static int hisi_sas_task_prep_ssp(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot, int is_tmf, + struct hisi_sas_tmf_task *tmf) +{ + return hisi_hba->hw->prep_ssp(hisi_hba, slot, is_tmf, tmf); +} + +static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba, + int is_tmf, struct hisi_sas_tmf_task *tmf, + int *pass) +{ + struct domain_device *device = task->dev; + struct hisi_sas_device *sas_dev = device->lldd_dev; + struct hisi_sas_port *port; + struct hisi_sas_slot *slot; + struct hisi_sas_cmd_hdr *cmd_hdr_base; + struct device *dev = &hisi_hba->pdev->dev; + int dlvry_queue_slot, dlvry_queue, n_elem = 0, rc, slot_idx; + + if (!device->port) { + struct task_status_struct *ts = &task->task_status; + + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_PHY_DOWN; + /* + * libsas will use dev->port, should + * not call task_done for sata + */ + if (device->dev_type != SAS_SATA_DEV) + task->task_done(task); + return 0; + } + + if (DEV_IS_GONE(sas_dev)) { + if (sas_dev) + dev_info(dev, "task prep: device %llu not ready\n", + sas_dev->device_id); + else + dev_info(dev, "task prep: device %016llx not ready\n", + SAS_ADDR(device->sas_addr)); + + rc = SAS_PHY_DOWN; + return rc; + } + port = device->port->lldd_port; + if (port && !port->port_attached && !tmf) { + if (sas_protocol_ata(task->task_proto)) { + struct task_status_struct *ts = &task->task_status; + + dev_info(dev, + "task prep: SATA/STP port%d not attach device\n", + device->port->id); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_PHY_DOWN; + task->task_done(task); + } else { + struct task_status_struct *ts = &task->task_status; + + dev_info(dev, + "task prep: SAS port%d does not attach device\n", + device->port->id); + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_PHY_DOWN; + task->task_done(task); + } + return 0; + } + + if (!sas_protocol_ata(task->task_proto)) { + if (task->num_scatter) { + n_elem = dma_map_sg(dev, task->scatter, + task->num_scatter, task->data_dir); + if (!n_elem) { + rc = -ENOMEM; + goto prep_out; + } + } + } else + n_elem = task->num_scatter; + + rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx); + if (rc) + goto err_out; + rc = hisi_hba->hw->get_free_slot(hisi_hba, &dlvry_queue, + &dlvry_queue_slot); + if (rc) + goto err_out_tag; + + slot = &hisi_hba->slot_info[slot_idx]; + memset(slot, 0, sizeof(struct hisi_sas_slot)); + + slot->idx = slot_idx; + slot->n_elem = n_elem; + slot->dlvry_queue = dlvry_queue; + slot->dlvry_queue_slot = dlvry_queue_slot; + cmd_hdr_base = hisi_hba->cmd_hdr[dlvry_queue]; + slot->cmd_hdr = &cmd_hdr_base[dlvry_queue_slot]; + slot->task = task; + slot->port = port; + task->lldd_task = slot; + + slot->status_buffer = dma_pool_alloc(hisi_hba->status_buffer_pool, + GFP_ATOMIC, + &slot->status_buffer_dma); + if (!slot->status_buffer) + goto err_out_slot_buf; + memset(slot->status_buffer, 0, HISI_SAS_STATUS_BUF_SZ); + + slot->command_table = dma_pool_alloc(hisi_hba->command_table_pool, + GFP_ATOMIC, + &slot->command_table_dma); + if (!slot->command_table) + goto err_out_status_buf; + memset(slot->command_table, 0, HISI_SAS_COMMAND_TABLE_SZ); + memset(slot->cmd_hdr, 0, sizeof(struct hisi_sas_cmd_hdr)); + + switch (task->task_proto) { + case SAS_PROTOCOL_SSP: + rc = hisi_sas_task_prep_ssp(hisi_hba, slot, is_tmf, tmf); + break; + case SAS_PROTOCOL_SATA: + case SAS_PROTOCOL_STP: + case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: + default: + dev_err(dev, "task prep: unknown/unsupported proto (0x%x)\n", + task->task_proto); + rc = -EINVAL; + break; + } + + if (rc) { + dev_err(dev, "task prep: rc = 0x%x\n", rc); + if (slot->sge_page) + goto err_out_sge; + goto err_out_command_table; + } + + list_add_tail(&slot->entry, &port->list); + spin_lock(&task->task_state_lock); + task->task_state_flags |= SAS_TASK_AT_INITIATOR; + spin_unlock(&task->task_state_lock); + + hisi_hba->slot_prep = slot; + + sas_dev->running_req++; + ++(*pass); + + return rc; + +err_out_sge: + dma_pool_free(hisi_hba->sge_page_pool, slot->sge_page, + slot->sge_page_dma); +err_out_command_table: + dma_pool_free(hisi_hba->command_table_pool, slot->command_table, + slot->command_table_dma); +err_out_status_buf: + dma_pool_free(hisi_hba->status_buffer_pool, slot->status_buffer, + slot->status_buffer_dma); +err_out_slot_buf: + /* Nothing to be done */ +err_out_tag: + hisi_sas_slot_index_free(hisi_hba, slot_idx); +err_out: + dev_err(dev, "task prep: failed[%d]!\n", rc); + if (!sas_protocol_ata(task->task_proto)) + if (n_elem) + dma_unmap_sg(dev, task->scatter, n_elem, + task->data_dir); +prep_out: + return rc; +} + +static int hisi_sas_task_exec(struct sas_task *task, gfp_t gfp_flags, + int is_tmf, struct hisi_sas_tmf_task *tmf) +{ + u32 rc; + u32 pass = 0; + unsigned long flags; + struct hisi_hba *hisi_hba = dev_to_hisi_hba(task->dev); + struct device *dev = &hisi_hba->pdev->dev; + + /* protect task_prep and start_delivery sequence */ + spin_lock_irqsave(&hisi_hba->lock, flags); + rc = hisi_sas_task_prep(task, hisi_hba, is_tmf, tmf, &pass); + if (rc) + dev_err(dev, "task exec: failed[%d]!\n", rc); + + if (likely(pass)) + hisi_hba->hw->start_delivery(hisi_hba); + spin_unlock_irqrestore(&hisi_hba->lock, flags); + + return rc; +} static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no) { @@ -100,6 +327,12 @@ static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) INIT_WORK(&phy->phyup_ws, hisi_sas_phyup_work); } + +static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags) +{ + return hisi_sas_task_exec(task, gfp_flags, 0, NULL); +} + static struct scsi_transport_template *hisi_sas_stt; static struct scsi_host_template hisi_sas_sht = { @@ -122,6 +355,7 @@ static struct scsi_host_template hisi_sas_sht = { }; static struct sas_domain_function_template hisi_sas_transport_ops = { + .lldd_execute_task = hisi_sas_queue_command, }; static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 43642798b89c1..07b9750d9af6c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -412,6 +412,13 @@ static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off) return readl(regs); } +static u32 hisi_sas_read32_relaxed(struct hisi_hba *hisi_hba, u32 off) +{ + void __iomem *regs = hisi_hba->regs + off; + + return readl_relaxed(regs); +} + static void hisi_sas_write32(struct hisi_hba *hisi_hba, u32 off, u32 val) { @@ -741,6 +748,190 @@ static void sl_notify_v1_hw(struct hisi_hba *hisi_hba, int phy_no) hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL, sl_control); } +/** + * This function allocates across all queues to load balance. + * Slots are allocated from queues in a round-robin fashion. + * + * The callpath to this function and upto writing the write + * queue pointer should be safe from interruption. + */ +static int get_free_slot_v1_hw(struct hisi_hba *hisi_hba, int *q, int *s) +{ + struct device *dev = &hisi_hba->pdev->dev; + u32 r, w; + int queue = hisi_hba->queue; + + while (1) { + w = hisi_sas_read32_relaxed(hisi_hba, + DLVRY_Q_0_WR_PTR + (queue * 0x14)); + r = hisi_sas_read32_relaxed(hisi_hba, + DLVRY_Q_0_RD_PTR + (queue * 0x14)); + if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) { + queue = (queue + 1) % hisi_hba->queue_count; + if (queue == hisi_hba->queue) { + dev_warn(dev, "could not find free slot\n"); + return -EAGAIN; + } + continue; + } + break; + } + hisi_hba->queue = (queue + 1) % hisi_hba->queue_count; + *q = queue; + *s = w; + return 0; +} + +static void start_delivery_v1_hw(struct hisi_hba *hisi_hba) +{ + int dlvry_queue = hisi_hba->slot_prep->dlvry_queue; + int dlvry_queue_slot = hisi_hba->slot_prep->dlvry_queue_slot; + + hisi_sas_write32(hisi_hba, + DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14), + ++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS); +} + +static int prep_prd_sge_v1_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot, + struct hisi_sas_cmd_hdr *hdr, + struct scatterlist *scatter, + int n_elem) +{ + struct device *dev = &hisi_hba->pdev->dev; + struct scatterlist *sg; + int i; + + if (n_elem > HISI_SAS_SGE_PAGE_CNT) { + dev_err(dev, "prd err: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT", + n_elem); + return -EINVAL; + } + + slot->sge_page = dma_pool_alloc(hisi_hba->sge_page_pool, GFP_ATOMIC, + &slot->sge_page_dma); + if (!slot->sge_page) + return -ENOMEM; + + for_each_sg(scatter, sg, n_elem, i) { + struct hisi_sas_sge *entry = &slot->sge_page->sge[i]; + + entry->addr = cpu_to_le64(sg_dma_address(sg)); + entry->page_ctrl_0 = entry->page_ctrl_1 = 0; + entry->data_len = cpu_to_le32(sg_dma_len(sg)); + entry->data_off = 0; + } + + hdr->prd_table_addr = cpu_to_le64(slot->sge_page_dma); + + hdr->sg_len = cpu_to_le32(n_elem << CMD_HDR_DATA_SGL_LEN_OFF); + + return 0; +} + + +static int prep_ssp_v1_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot, int is_tmf, + struct hisi_sas_tmf_task *tmf) +{ + struct sas_task *task = slot->task; + struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr; + struct domain_device *device = task->dev; + struct hisi_sas_device *sas_dev = device->lldd_dev; + struct hisi_sas_port *port = slot->port; + struct sas_ssp_task *ssp_task = &task->ssp_task; + struct scsi_cmnd *scsi_cmnd = ssp_task->cmd; + int has_data = 0, rc, priority = is_tmf; + u8 *buf_cmd, fburst = 0; + u32 dw1, dw2; + + /* create header */ + hdr->dw0 = cpu_to_le32((1 << CMD_HDR_RESP_REPORT_OFF) | + (0x2 << CMD_HDR_TLR_CTRL_OFF) | + (port->id << CMD_HDR_PORT_OFF) | + (priority << CMD_HDR_PRIORITY_OFF) | + (1 << CMD_HDR_MODE_OFF) | /* ini mode */ + (1 << CMD_HDR_CMD_OFF)); /* ssp */ + + dw1 = 1 << CMD_HDR_VERIFY_DTL_OFF; + + if (is_tmf) { + dw1 |= 3 << CMD_HDR_SSP_FRAME_TYPE_OFF; + } else { + switch (scsi_cmnd->sc_data_direction) { + case DMA_TO_DEVICE: + dw1 |= 2 << CMD_HDR_SSP_FRAME_TYPE_OFF; + has_data = 1; + break; + case DMA_FROM_DEVICE: + dw1 |= 1 << CMD_HDR_SSP_FRAME_TYPE_OFF; + has_data = 1; + break; + default: + dw1 |= 0 << CMD_HDR_SSP_FRAME_TYPE_OFF; + } + } + + /* map itct entry */ + dw1 |= sas_dev->device_id << CMD_HDR_DEVICE_ID_OFF; + hdr->dw1 = cpu_to_le32(dw1); + + if (is_tmf) { + dw2 = ((sizeof(struct ssp_tmf_iu) + + sizeof(struct ssp_frame_hdr)+3)/4) << + CMD_HDR_CFL_OFF; + } else { + dw2 = ((sizeof(struct ssp_command_iu) + + sizeof(struct ssp_frame_hdr)+3)/4) << + CMD_HDR_CFL_OFF; + } + + dw2 |= (HISI_SAS_MAX_SSP_RESP_SZ/4) << CMD_HDR_MRFL_OFF; + + hdr->transfer_tags = cpu_to_le32(slot->idx << CMD_HDR_IPTT_OFF); + + if (has_data) { + rc = prep_prd_sge_v1_hw(hisi_hba, slot, hdr, task->scatter, + slot->n_elem); + if (rc) + return rc; + } + + hdr->data_transfer_len = cpu_to_le32(task->total_xfer_len); + hdr->cmd_table_addr = cpu_to_le64(slot->command_table_dma); + hdr->sts_buffer_addr = cpu_to_le64(slot->status_buffer_dma); + + buf_cmd = slot->command_table + sizeof(struct ssp_frame_hdr); + if (task->ssp_task.enable_first_burst) { + fburst = (1 << 7); + dw2 |= 1 << CMD_HDR_FIRST_BURST_OFF; + } + hdr->dw2 = cpu_to_le32(dw2); + + memcpy(buf_cmd, &task->ssp_task.LUN, 8); + if (!is_tmf) { + buf_cmd[9] = fburst | task->ssp_task.task_attr | + (task->ssp_task.task_prio << 3); + memcpy(buf_cmd + 12, task->ssp_task.cmd->cmnd, + task->ssp_task.cmd->cmd_len); + } else { + buf_cmd[10] = tmf->tmf; + switch (tmf->tmf) { + case TMF_ABORT_TASK: + case TMF_QUERY_TASK: + buf_cmd[12] = + (tmf->tag_of_task_to_be_managed >> 8) & 0xff; + buf_cmd[13] = + tmf->tag_of_task_to_be_managed & 0xff; + break; + default: + break; + } + } + + return 0; +} + /* Interrupts */ static irqreturn_t int_phyup_v1_hw(int irq_no, void *p) { @@ -919,6 +1110,9 @@ static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) static const struct hisi_sas_hw hisi_sas_v1_hw = { .hw_init = hisi_sas_v1_init, .sl_notify = sl_notify_v1_hw, + .prep_ssp = prep_ssp_v1_hw, + .get_free_slot = get_free_slot_v1_hw, + .start_delivery = start_delivery_v1_hw, .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr), }; -- GitLab From 27a3f2292ea2508d2d1ddd85846910a69ed95a3f Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:50 +0800 Subject: [PATCH 0676/2855] hisi_sas: Add cq interrupt handler Add cq interrupt handler and also slot error handler function. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 9 + drivers/scsi/hisi_sas/hisi_sas_main.c | 35 +++ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 345 +++++++++++++++++++++++++ 3 files changed, 389 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 72657eb770f69..fe4055be325a8 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -93,6 +93,8 @@ struct hisi_sas_slot { u64 n_elem; int dlvry_queue; int dlvry_queue_slot; + int cmplt_queue; + int cmplt_queue_slot; int idx; void *cmd_hdr; dma_addr_t cmd_hdr_dma; @@ -117,6 +119,10 @@ struct hisi_sas_hw { int (*prep_ssp)(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot, int is_tmf, struct hisi_sas_tmf_task *tmf); + int (*slot_complete)(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot, int abort); + void (*free_device)(struct hisi_hba *hisi_hba, + struct hisi_sas_device *dev); int complete_hdr_size; }; @@ -311,4 +317,7 @@ extern int hisi_sas_probe(struct platform_device *pdev, const struct hisi_sas_hw *ops); extern int hisi_sas_remove(struct platform_device *pdev); +extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, + struct sas_task *task, + struct hisi_sas_slot *slot); #endif diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 660ef6cac3ab9..ddbd2b711cf3d 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -60,6 +60,41 @@ static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba) for (i = 0; i < hisi_hba->slot_index_count; ++i) hisi_sas_slot_index_clear(hisi_hba, i); } + +void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, + struct hisi_sas_slot *slot) +{ + struct device *dev = &hisi_hba->pdev->dev; + + if (!slot->task) + return; + + if (!sas_protocol_ata(task->task_proto)) + if (slot->n_elem) + dma_unmap_sg(dev, task->scatter, slot->n_elem, + task->data_dir); + + if (slot->command_table) + dma_pool_free(hisi_hba->command_table_pool, + slot->command_table, slot->command_table_dma); + + if (slot->status_buffer) + dma_pool_free(hisi_hba->status_buffer_pool, + slot->status_buffer, slot->status_buffer_dma); + + if (slot->sge_page) + dma_pool_free(hisi_hba->sge_page_pool, slot->sge_page, + slot->sge_page_dma); + + list_del_init(&slot->entry); + task->lldd_task = NULL; + slot->task = NULL; + slot->port = NULL; + hisi_sas_slot_index_free(hisi_hba, slot->idx); + memset(slot, 0, sizeof(*slot)); +} +EXPORT_SYMBOL_GPL(hisi_sas_slot_task_free); + static int hisi_sas_task_prep_ssp(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot, int is_tmf, struct hisi_sas_tmf_task *tmf) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 07b9750d9af6c..6711c0ae66b71 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -498,6 +498,28 @@ static void init_id_frame_v1_hw(struct hisi_hba *hisi_hba) config_id_frame_v1_hw(hisi_hba, i); } + +static void free_device_v1_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_device *sas_dev) +{ + u64 dev_id = sas_dev->device_id; + struct hisi_sas_itct *itct = &hisi_hba->itct[dev_id]; + u32 qw0, reg_val = hisi_sas_read32(hisi_hba, CFG_AGING_TIME); + + reg_val |= CFG_AGING_TIME_ITCT_REL_MSK; + hisi_sas_write32(hisi_hba, CFG_AGING_TIME, reg_val); + + /* free itct */ + udelay(1); + reg_val = hisi_sas_read32(hisi_hba, CFG_AGING_TIME); + reg_val &= ~CFG_AGING_TIME_ITCT_REL_MSK; + hisi_sas_write32(hisi_hba, CFG_AGING_TIME, reg_val); + + qw0 = cpu_to_le64(itct->qw0); + qw0 &= ~ITCT_HDR_VALID_MSK; + itct->qw0 = cpu_to_le64(qw0); +} + static int reset_hw_v1_hw(struct hisi_hba *hisi_hba) { int i; @@ -932,6 +954,253 @@ static int prep_ssp_v1_hw(struct hisi_hba *hisi_hba, return 0; } +/* by default, task resp is complete */ +static void slot_err_v1_hw(struct hisi_hba *hisi_hba, + struct sas_task *task, + struct hisi_sas_slot *slot) +{ + struct task_status_struct *ts = &task->task_status; + struct hisi_sas_err_record *err_record = slot->status_buffer; + struct device *dev = &hisi_hba->pdev->dev; + + switch (task->task_proto) { + case SAS_PROTOCOL_SSP: + { + int error = -1; + u32 dma_err_type = cpu_to_le32(err_record->dma_err_type); + u32 dma_tx_err_type = ((dma_err_type & + ERR_HDR_DMA_TX_ERR_TYPE_MSK)) >> + ERR_HDR_DMA_TX_ERR_TYPE_OFF; + u32 dma_rx_err_type = ((dma_err_type & + ERR_HDR_DMA_RX_ERR_TYPE_MSK)) >> + ERR_HDR_DMA_RX_ERR_TYPE_OFF; + u32 trans_tx_fail_type = + cpu_to_le32(err_record->trans_tx_fail_type); + u32 trans_rx_fail_type = + cpu_to_le32(err_record->trans_rx_fail_type); + + if (dma_tx_err_type) { + /* dma tx err */ + error = ffs(dma_tx_err_type) + - 1 + DMA_TX_ERR_BASE; + } else if (dma_rx_err_type) { + /* dma rx err */ + error = ffs(dma_rx_err_type) + - 1 + DMA_RX_ERR_BASE; + } else if (trans_tx_fail_type) { + /* trans tx err */ + error = ffs(trans_tx_fail_type) + - 1 + TRANS_TX_FAIL_BASE; + } else if (trans_rx_fail_type) { + /* trans rx err */ + error = ffs(trans_rx_fail_type) + - 1 + TRANS_RX_FAIL_BASE; + } + + switch (error) { + case DMA_TX_DATA_UNDERFLOW_ERR: + case DMA_RX_DATA_UNDERFLOW_ERR: + { + ts->residual = 0; + ts->stat = SAS_DATA_UNDERRUN; + break; + } + case DMA_TX_DATA_SGL_OVERFLOW_ERR: + case DMA_TX_DIF_SGL_OVERFLOW_ERR: + case DMA_TX_XFER_RDY_LENGTH_OVERFLOW_ERR: + case DMA_RX_DATA_OVERFLOW_ERR: + case TRANS_RX_FRAME_OVERRUN_ERR: + case TRANS_RX_LINK_BUF_OVERRUN_ERR: + { + ts->stat = SAS_DATA_OVERRUN; + ts->residual = 0; + break; + } + case TRANS_TX_PHY_NOT_ENABLE_ERR: + { + ts->stat = SAS_PHY_DOWN; + break; + } + case TRANS_TX_OPEN_REJCT_WRONG_DEST_ERR: + case TRANS_TX_OPEN_REJCT_ZONE_VIOLATION_ERR: + case TRANS_TX_OPEN_REJCT_BY_OTHER_ERR: + case TRANS_TX_OPEN_REJCT_AIP_TIMEOUT_ERR: + case TRANS_TX_OPEN_REJCT_STP_BUSY_ERR: + case TRANS_TX_OPEN_REJCT_PROTOCOL_NOT_SUPPORT_ERR: + case TRANS_TX_OPEN_REJCT_RATE_NOT_SUPPORT_ERR: + case TRANS_TX_OPEN_REJCT_BAD_DEST_ERR: + case TRANS_TX_OPEN_BREAK_RECEIVE_ERR: + case TRANS_TX_OPEN_REJCT_PATHWAY_BLOCKED_ERR: + case TRANS_TX_OPEN_REJCT_NO_DEST_ERR: + case TRANS_TX_OPEN_RETRY_ERR: + { + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; + break; + } + case TRANS_TX_OPEN_TIMEOUT_ERR: + { + ts->stat = SAS_OPEN_TO; + break; + } + case TRANS_TX_NAK_RECEIVE_ERR: + case TRANS_TX_ACK_NAK_TIMEOUT_ERR: + { + ts->stat = SAS_NAK_R_ERR; + break; + } + default: + { + ts->stat = SAM_STAT_CHECK_CONDITION; + break; + } + } + } + break; + case SAS_PROTOCOL_SMP: + ts->stat = SAM_STAT_CHECK_CONDITION; + break; + + case SAS_PROTOCOL_SATA: + case SAS_PROTOCOL_STP: + case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: + { + dev_err(dev, "slot err: SATA/STP not supported"); + } + break; + default: + break; + } + +} + +static int slot_complete_v1_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot, int abort) +{ + struct sas_task *task = slot->task; + struct hisi_sas_device *sas_dev; + struct device *dev = &hisi_hba->pdev->dev; + struct task_status_struct *ts; + struct domain_device *device; + enum exec_status sts; + struct hisi_sas_complete_v1_hdr *complete_queue = + (struct hisi_sas_complete_v1_hdr *) + hisi_hba->complete_hdr[slot->cmplt_queue]; + struct hisi_sas_complete_v1_hdr *complete_hdr; + u32 cmplt_hdr_data; + + complete_hdr = &complete_queue[slot->cmplt_queue_slot]; + cmplt_hdr_data = le32_to_cpu(complete_hdr->data); + + if (unlikely(!task || !task->lldd_task || !task->dev)) + return -EINVAL; + + ts = &task->task_status; + device = task->dev; + sas_dev = device->lldd_dev; + + task->task_state_flags &= + ~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR); + task->task_state_flags |= SAS_TASK_STATE_DONE; + + memset(ts, 0, sizeof(*ts)); + ts->resp = SAS_TASK_COMPLETE; + + if (unlikely(!sas_dev || abort)) { + if (!sas_dev) + dev_dbg(dev, "slot complete: port has not device\n"); + ts->stat = SAS_PHY_DOWN; + goto out; + } + + if (cmplt_hdr_data & CMPLT_HDR_IO_CFG_ERR_MSK) { + u32 info_reg = hisi_sas_read32(hisi_hba, HGC_INVLD_DQE_INFO); + + if (info_reg & HGC_INVLD_DQE_INFO_DQ_MSK) + dev_err(dev, "slot complete: [%d:%d] has dq IPTT err", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_TYPE_MSK) + dev_err(dev, "slot complete: [%d:%d] has dq type err", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_FORCE_MSK) + dev_err(dev, "slot complete: [%d:%d] has dq force phy err", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_PHY_MSK) + dev_err(dev, "slot complete: [%d:%d] has dq phy id err", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_ABORT_MSK) + dev_err(dev, "slot complete: [%d:%d] has dq abort flag err", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_IPTT_OF_MSK) + dev_err(dev, "slot complete: [%d:%d] has dq IPTT or ICT err", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_SSP_ERR_MSK) + dev_err(dev, "slot complete: [%d:%d] has dq SSP frame type err", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_OFL_MSK) + dev_err(dev, "slot complete: [%d:%d] has dq order frame len err", + slot->cmplt_queue, slot->cmplt_queue_slot); + + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; + goto out; + } + + if (cmplt_hdr_data & CMPLT_HDR_ERR_RCRD_XFRD_MSK) { + if (!(cmplt_hdr_data & CMPLT_HDR_CMD_CMPLT_MSK) || + !(cmplt_hdr_data & CMPLT_HDR_RSPNS_XFRD_MSK)) + ts->stat = SAS_DATA_OVERRUN; + else + slot_err_v1_hw(hisi_hba, task, slot); + + goto out; + } + + switch (task->task_proto) { + case SAS_PROTOCOL_SSP: + { + struct ssp_response_iu *iu = slot->status_buffer + + sizeof(struct hisi_sas_err_record); + sas_ssp_task_response(dev, task, iu); + break; + } + case SAS_PROTOCOL_SATA: + case SAS_PROTOCOL_STP: + case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: + dev_err(dev, "slot complete: SATA/STP not supported"); + break; + + default: + ts->stat = SAM_STAT_CHECK_CONDITION; + break; + } + + if (!slot->port->port_attached) { + dev_err(dev, "slot complete: port %d has removed\n", + slot->port->sas_port.id); + ts->stat = SAS_PHY_DOWN; + } + +out: + if (sas_dev && sas_dev->running_req) + sas_dev->running_req--; + + hisi_sas_slot_task_free(hisi_hba, task, slot); + sts = ts->stat; + + if (task->task_done) + task->task_done(task); + + return sts; +} + /* Interrupts */ static irqreturn_t int_phyup_v1_hw(int irq_no, void *p) { @@ -1011,9 +1280,61 @@ end: return res; } + +static irqreturn_t cq_interrupt_v1_hw(int irq, void *p) +{ + struct hisi_sas_cq *cq = p; + struct hisi_hba *hisi_hba = cq->hisi_hba; + struct hisi_sas_slot *slot; + int queue = cq->id; + struct hisi_sas_complete_v1_hdr *complete_queue = + (struct hisi_sas_complete_v1_hdr *) + hisi_hba->complete_hdr[queue]; + u32 irq_value, rd_point, wr_point; + + irq_value = hisi_sas_read32(hisi_hba, OQ_INT_SRC); + + hisi_sas_write32(hisi_hba, OQ_INT_SRC, 1 << queue); + + rd_point = hisi_sas_read32(hisi_hba, + COMPL_Q_0_RD_PTR + (0x14 * queue)); + wr_point = hisi_sas_read32(hisi_hba, + COMPL_Q_0_WR_PTR + (0x14 * queue)); + + while (rd_point != wr_point) { + struct hisi_sas_complete_v1_hdr *complete_hdr; + int idx; + u32 cmplt_hdr_data; + + complete_hdr = &complete_queue[rd_point]; + cmplt_hdr_data = cpu_to_le32(complete_hdr->data); + idx = (cmplt_hdr_data & CMPLT_HDR_IPTT_MSK) >> + CMPLT_HDR_IPTT_OFF; + slot = &hisi_hba->slot_info[idx]; + + /* The completion queue and queue slot index are not + * necessarily the same as the delivery queue and + * queue slot index. + */ + slot->cmplt_queue_slot = rd_point; + slot->cmplt_queue = queue; + slot_complete_v1_hw(hisi_hba, slot, 0); + + if (++rd_point >= HISI_SAS_QUEUE_SLOTS) + rd_point = 0; + } + + /* update rd_point */ + hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point); + + return IRQ_HANDLED; +} + static const char phy_int_names[HISI_SAS_PHY_INT_NR][32] = { {"Phy Up"}, }; + +static const char cq_int_name[32] = "cq"; static irq_handler_t phy_interrupts[HISI_SAS_PHY_INT_NR] = { int_phyup_v1_hw, }; @@ -1056,6 +1377,28 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) } } } + + idx = hisi_hba->n_phy * HISI_SAS_PHY_INT_NR; + for (i = 0; i < hisi_hba->queue_count; i++, idx++) { + irq = irq_of_parse_and_map(np, idx); + if (!irq) { + dev_err(dev, "irq init: could not map cq interrupt %d\n", + idx); + return -ENOENT; + } + (void)snprintf(&int_names[idx * HISI_SAS_NAME_LEN], + HISI_SAS_NAME_LEN, + "%s %s:%d", dev_name(dev), cq_int_name, i); + rc = devm_request_irq(dev, irq, cq_interrupt_v1_hw, 0, + &int_names[idx * HISI_SAS_NAME_LEN], + &hisi_hba->cq[i]); + if (rc) { + dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n", + irq, rc); + return -ENOENT; + } + } + return 0; } @@ -1110,9 +1453,11 @@ static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) static const struct hisi_sas_hw hisi_sas_v1_hw = { .hw_init = hisi_sas_v1_init, .sl_notify = sl_notify_v1_hw, + .free_device = free_device_v1_hw, .prep_ssp = prep_ssp_v1_hw, .get_free_slot = get_free_slot_v1_hw, .start_delivery = start_delivery_v1_hw, + .slot_complete = slot_complete_v1_hw, .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr), }; -- GitLab From abda97c2fe874cd8826fe25a77f66c75bcc7b5cd Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:51 +0800 Subject: [PATCH 0677/2855] hisi_sas: Add dev_found and dev_gone Add functions to deal with lldd_dev_found and lldd_dev_gone. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 13 ++++ drivers/scsi/hisi_sas/hisi_sas_main.c | 88 ++++++++++++++++++++++++++ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 41 ++++++++++++ 3 files changed, 142 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index fe4055be325a8..999f31955bee2 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -39,6 +39,7 @@ #define HISI_SAS_NAME_LEN 32 +struct hisi_hba; enum { PORT_TYPE_SAS = (1U << 1), @@ -49,6 +50,13 @@ enum dev_status { HISI_SAS_DEV_NORMAL, HISI_SAS_DEV_EH, }; + +enum hisi_sas_dev_type { + HISI_SAS_DEV_TYPE_STP = 0, + HISI_SAS_DEV_TYPE_SSP, + HISI_SAS_DEV_TYPE_SATA, +}; + struct hisi_sas_phy { struct hisi_hba *hisi_hba; struct hisi_sas_port *port; @@ -81,6 +89,9 @@ struct hisi_sas_cq { struct hisi_sas_device { enum sas_device_type dev_type; + struct hisi_hba *hisi_hba; + struct domain_device *sas_device; + u64 attached_phy; u64 device_id; u64 running_req; u8 dev_status; @@ -113,6 +124,8 @@ struct hisi_sas_tmf_task { struct hisi_sas_hw { int (*hw_init)(struct hisi_hba *hisi_hba); + void (*setup_itct)(struct hisi_hba *hisi_hba, + struct hisi_sas_device *device); void (*sl_notify)(struct hisi_hba *hisi_hba, int phy_no); int (*get_free_slot)(struct hisi_hba *hisi_hba, int *q, int *s); void (*start_delivery)(struct hisi_hba *hisi_hba); diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index ddbd2b711cf3d..d8af4c64cd51f 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -12,6 +12,9 @@ #include "hisi_sas.h" #define DRV_NAME "hisi_sas" +#define DEV_IS_EXPANDER(type) \ + ((type == SAS_EDGE_EXPANDER_DEVICE) || \ + (type == SAS_FANOUT_EXPANDER_DEVICE)) #define DEV_IS_GONE(dev) \ ((!dev) || (dev->dev_type == SAS_PHY_UNUSED)) @@ -325,6 +328,72 @@ static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no) sas_ha->notify_port_event(sas_phy, PORTE_BYTES_DMAED); } +static struct hisi_sas_device *hisi_sas_alloc_dev(struct domain_device *device) +{ + struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); + struct hisi_sas_device *sas_dev = NULL; + int i; + + spin_lock(&hisi_hba->lock); + for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) { + if (hisi_hba->devices[i].dev_type == SAS_PHY_UNUSED) { + hisi_hba->devices[i].device_id = i; + sas_dev = &hisi_hba->devices[i]; + sas_dev->dev_status = HISI_SAS_DEV_NORMAL; + sas_dev->dev_type = device->dev_type; + sas_dev->hisi_hba = hisi_hba; + sas_dev->sas_device = device; + break; + } + } + spin_unlock(&hisi_hba->lock); + + return sas_dev; +} + +static int hisi_sas_dev_found(struct domain_device *device) +{ + struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); + struct domain_device *parent_dev = device->parent; + struct hisi_sas_device *sas_dev; + struct device *dev = &hisi_hba->pdev->dev; + + sas_dev = hisi_sas_alloc_dev(device); + if (!sas_dev) { + dev_err(dev, "fail alloc dev: max support %d devices\n", + HISI_SAS_MAX_DEVICES); + return -EINVAL; + } + + device->lldd_dev = sas_dev; + hisi_hba->hw->setup_itct(hisi_hba, sas_dev); + + if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) { + int phy_no; + u8 phy_num = parent_dev->ex_dev.num_phys; + struct ex_phy *phy; + + for (phy_no = 0; phy_no < phy_num; phy_no++) { + phy = &parent_dev->ex_dev.ex_phy[phy_no]; + if (SAS_ADDR(phy->attached_sas_addr) == + SAS_ADDR(device->sas_addr)) { + sas_dev->attached_phy = phy_no; + break; + } + } + + if (phy_no == phy_num) { + dev_info(dev, "dev found: no attached " + "dev:%016llx at ex:%016llx\n", + SAS_ADDR(device->sas_addr), + SAS_ADDR(parent_dev->sas_addr)); + return -EINVAL; + } + } + + return 0; +} + static void hisi_sas_phyup_work(struct work_struct *work) { struct hisi_sas_phy *phy = @@ -362,6 +431,23 @@ static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) INIT_WORK(&phy->phyup_ws, hisi_sas_phyup_work); } +static void hisi_sas_dev_gone(struct domain_device *device) +{ + struct hisi_sas_device *sas_dev = device->lldd_dev; + struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); + struct device *dev = &hisi_hba->pdev->dev; + u64 dev_id = sas_dev->device_id; + + dev_info(dev, "found dev[%lld:%x] is gone\n", + sas_dev->device_id, sas_dev->dev_type); + + hisi_hba->hw->free_device(hisi_hba, sas_dev); + device->lldd_dev = NULL; + memset(sas_dev, 0, sizeof(*sas_dev)); + sas_dev->device_id = dev_id; + sas_dev->dev_type = SAS_PHY_UNUSED; + sas_dev->dev_status = HISI_SAS_DEV_NORMAL; +} static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags) { @@ -390,6 +476,8 @@ static struct scsi_host_template hisi_sas_sht = { }; static struct sas_domain_function_template hisi_sas_transport_ops = { + .lldd_dev_found = hisi_sas_dev_found, + .lldd_dev_gone = hisi_sas_dev_gone, .lldd_execute_task = hisi_sas_queue_command, }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 6711c0ae66b71..530e77152bc69 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -498,6 +498,46 @@ static void init_id_frame_v1_hw(struct hisi_hba *hisi_hba) config_id_frame_v1_hw(hisi_hba, i); } +static void setup_itct_v1_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_device *sas_dev) +{ + struct domain_device *device = sas_dev->sas_device; + struct device *dev = &hisi_hba->pdev->dev; + u64 qw0, device_id = sas_dev->device_id; + struct hisi_sas_itct *itct = &hisi_hba->itct[device_id]; + + memset(itct, 0, sizeof(*itct)); + + /* qw0 */ + qw0 = 0; + switch (sas_dev->dev_type) { + case SAS_END_DEVICE: + case SAS_EDGE_EXPANDER_DEVICE: + case SAS_FANOUT_EXPANDER_DEVICE: + qw0 = HISI_SAS_DEV_TYPE_SSP << ITCT_HDR_DEV_TYPE_OFF; + break; + default: + dev_warn(dev, "setup itct: unsupported dev type (%d)\n", + sas_dev->dev_type); + } + + qw0 |= ((1 << ITCT_HDR_VALID_OFF) | + (1 << ITCT_HDR_AWT_CONTROL_OFF) | + (device->max_linkrate << ITCT_HDR_MAX_CONN_RATE_OFF) | + (1 << ITCT_HDR_VALID_LINK_NUM_OFF) | + (device->port->id << ITCT_HDR_PORT_ID_OFF)); + itct->qw0 = cpu_to_le64(qw0); + + /* qw1 */ + memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE); + itct->sas_addr = __swab64(itct->sas_addr); + + /* qw2 */ + itct->qw2 = cpu_to_le64((500 < ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) | + (0xff00 < ITCT_HDR_BUS_INACTIVE_TL_OFF) | + (0xff00 < ITCT_HDR_MAX_CONN_TL_OFF) | + (0xff00 < ITCT_HDR_REJ_OPEN_TL_OFF)); +} static void free_device_v1_hw(struct hisi_hba *hisi_hba, struct hisi_sas_device *sas_dev) @@ -1452,6 +1492,7 @@ static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) static const struct hisi_sas_hw hisi_sas_v1_hw = { .hw_init = hisi_sas_v1_init, + .setup_itct = setup_itct_v1_hw, .sl_notify = sl_notify_v1_hw, .free_device = free_device_v1_hw, .prep_ssp = prep_ssp_v1_hw, -- GitLab From 184a4635340be6e0e804240ff889c3c82d6e4745 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:52 +0800 Subject: [PATCH 0678/2855] hisi_sas: Add abnormal irq handler Add abnormal irq handler. This handler is concerned with phy down event. Also add port formed and port deformed handlers. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 2 + drivers/scsi/hisi_sas/hisi_sas_main.c | 118 +++++++++++++++++++++++++ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 70 +++++++++++++++ 3 files changed, 190 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 999f31955bee2..e5ee3c90f7b5f 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -136,6 +136,7 @@ struct hisi_sas_hw { struct hisi_sas_slot *slot, int abort); void (*free_device)(struct hisi_hba *hisi_hba, struct hisi_sas_device *dev); + int (*get_wideport_bitmap)(struct hisi_hba *hisi_hba, int port_id); int complete_hdr_size; }; @@ -330,6 +331,7 @@ extern int hisi_sas_probe(struct platform_device *pdev, const struct hisi_sas_hw *ops); extern int hisi_sas_remove(struct platform_device *pdev); +extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy); extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, struct hisi_sas_slot *slot); diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index d8af4c64cd51f..17978510c4f29 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -431,6 +431,72 @@ static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) INIT_WORK(&phy->phyup_ws, hisi_sas_phyup_work); } +static void hisi_sas_port_notify_formed(struct asd_sas_phy *sas_phy) +{ + struct sas_ha_struct *sas_ha = sas_phy->ha; + struct hisi_hba *hisi_hba = sas_ha->lldd_ha; + struct hisi_sas_phy *phy = sas_phy->lldd_phy; + struct asd_sas_port *sas_port = sas_phy->port; + struct hisi_sas_port *port = &hisi_hba->port[sas_phy->id]; + unsigned long flags; + + if (!sas_port) + return; + + spin_lock_irqsave(&hisi_hba->lock, flags); + port->port_attached = 1; + port->id = phy->port_id; + phy->port = port; + sas_port->lldd_port = port; + spin_unlock_irqrestore(&hisi_hba->lock, flags); +} + +static void hisi_sas_do_release_task(struct hisi_hba *hisi_hba, int phy_no, + struct domain_device *device) +{ + struct hisi_sas_phy *phy; + struct hisi_sas_port *port; + struct hisi_sas_slot *slot, *slot2; + struct device *dev = &hisi_hba->pdev->dev; + + phy = &hisi_hba->phy[phy_no]; + port = phy->port; + if (!port) + return; + + list_for_each_entry_safe(slot, slot2, &port->list, entry) { + struct sas_task *task; + + task = slot->task; + if (device && task->dev != device) + continue; + + dev_info(dev, "Release slot [%d:%d], task [%p]:\n", + slot->dlvry_queue, slot->dlvry_queue_slot, task); + hisi_hba->hw->slot_complete(hisi_hba, slot, 1); + } +} + +static void hisi_sas_port_notify_deformed(struct asd_sas_phy *sas_phy) +{ + struct domain_device *device; + struct hisi_sas_phy *phy = sas_phy->lldd_phy; + struct asd_sas_port *sas_port = sas_phy->port; + + list_for_each_entry(device, &sas_port->dev_list, dev_list_node) + hisi_sas_do_release_task(phy->hisi_hba, sas_phy->id, device); +} + +static void hisi_sas_release_task(struct hisi_hba *hisi_hba, + struct domain_device *device) +{ + struct asd_sas_port *port = device->port; + struct asd_sas_phy *sas_phy; + + list_for_each_entry(sas_phy, &port->phy_list, port_phy_el) + hisi_sas_do_release_task(hisi_hba, sas_phy->id, device); +} + static void hisi_sas_dev_gone(struct domain_device *device) { struct hisi_sas_device *sas_dev = device->lldd_dev; @@ -454,6 +520,56 @@ static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags) return hisi_sas_task_exec(task, gfp_flags, 0, NULL); } + +static void hisi_sas_port_formed(struct asd_sas_phy *sas_phy) +{ + hisi_sas_port_notify_formed(sas_phy); +} + +static void hisi_sas_port_deformed(struct asd_sas_phy *sas_phy) +{ + hisi_sas_port_notify_deformed(sas_phy); +} + +static void hisi_sas_phy_disconnected(struct hisi_sas_phy *phy) +{ + phy->phy_attached = 0; + phy->phy_type = 0; + phy->port = NULL; +} + +void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy) +{ + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + struct sas_ha_struct *sas_ha = &hisi_hba->sha; + + if (rdy) { + /* Phy down but ready */ + hisi_sas_bytes_dmaed(hisi_hba, phy_no); + hisi_sas_port_notify_formed(sas_phy); + } else { + struct hisi_sas_port *port = phy->port; + + /* Phy down and not ready */ + sas_ha->notify_phy_event(sas_phy, PHYE_LOSS_OF_SIGNAL); + sas_phy_disconnected(sas_phy); + + if (port) { + if (phy->phy_type & PORT_TYPE_SAS) { + int port_id = port->id; + + if (!hisi_hba->hw->get_wideport_bitmap(hisi_hba, + port_id)) + port->port_attached = 0; + } else if (phy->phy_type & PORT_TYPE_SATA) + port->port_attached = 0; + } + hisi_sas_phy_disconnected(phy); + } +} +EXPORT_SYMBOL_GPL(hisi_sas_phy_down); + static struct scsi_transport_template *hisi_sas_stt; static struct scsi_host_template hisi_sas_sht = { @@ -479,6 +595,8 @@ static struct sas_domain_function_template hisi_sas_transport_ops = { .lldd_dev_found = hisi_sas_dev_found, .lldd_dev_gone = hisi_sas_dev_gone, .lldd_execute_task = hisi_sas_queue_command, + .lldd_port_formed = hisi_sas_port_formed, + .lldd_port_deformed = hisi_sas_port_deformed, }; static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 530e77152bc69..1723dd453e06e 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -810,6 +810,18 @@ static void sl_notify_v1_hw(struct hisi_hba *hisi_hba, int phy_no) hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL, sl_control); } +static int get_wideport_bitmap_v1_hw(struct hisi_hba *hisi_hba, int port_id) +{ + int i, bitmap = 0; + u32 phy_port_num_ma = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA); + + for (i = 0; i < hisi_hba->n_phy; i++) + if (((phy_port_num_ma >> (i * 4)) & 0xf) == port_id) + bitmap |= 1 << i; + + return bitmap; +} + /** * This function allocates across all queues to load balance. * Slots are allocated from queues in a round-robin fashion. @@ -1321,6 +1333,61 @@ end: return res; } +static irqreturn_t int_abnormal_v1_hw(int irq, void *p) +{ + struct hisi_sas_phy *phy = p; + struct hisi_hba *hisi_hba = phy->hisi_hba; + struct device *dev = &hisi_hba->pdev->dev; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + u32 irq_value, irq_mask_old; + int phy_no = sas_phy->id; + + /* mask_int0 */ + irq_mask_old = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT0_MSK); + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0_MSK, 0x3fffff); + + /* read int0 */ + irq_value = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT0); + + if (irq_value & CHL_INT0_PHYCTRL_NOTRDY_MSK) { + u32 phy_state = hisi_sas_read32(hisi_hba, PHY_STATE); + + hisi_sas_phy_down(hisi_hba, phy_no, + (phy_state & 1 << phy_no) ? 1 : 0); + } + + if (irq_value & CHL_INT0_ID_TIMEOUT_MSK) + dev_dbg(dev, "abnormal: ID_TIMEOUT phy%d identify timeout\n", + phy_no); + + if (irq_value & CHL_INT0_DWS_LOST_MSK) + dev_dbg(dev, "abnormal: DWS_LOST phy%d dws lost\n", phy_no); + + if (irq_value & CHL_INT0_SN_FAIL_NGR_MSK) + dev_dbg(dev, "abnormal: SN_FAIL_NGR phy%d sn fail ngr\n", + phy_no); + + if (irq_value & CHL_INT0_SL_IDAF_FAIL_MSK || + irq_value & CHL_INT0_SL_OPAF_FAIL_MSK) + dev_dbg(dev, "abnormal: SL_ID/OPAF_FAIL phy%d check adr frm err\n", + phy_no); + + if (irq_value & CHL_INT0_SL_PS_FAIL_OFF) + dev_dbg(dev, "abnormal: SL_PS_FAIL phy%d fail\n", phy_no); + + /* write to zero */ + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, irq_value); + + if (irq_value & CHL_INT0_PHYCTRL_NOTRDY_MSK) + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0_MSK, + 0x3fffff & ~CHL_INT0_MSK_PHYCTRL_NOTRDY_MSK); + else + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0_MSK, + irq_mask_old); + + return IRQ_HANDLED; +} + static irqreturn_t cq_interrupt_v1_hw(int irq, void *p) { struct hisi_sas_cq *cq = p; @@ -1372,11 +1439,13 @@ static irqreturn_t cq_interrupt_v1_hw(int irq, void *p) static const char phy_int_names[HISI_SAS_PHY_INT_NR][32] = { {"Phy Up"}, + {"Abnormal"}, }; static const char cq_int_name[32] = "cq"; static irq_handler_t phy_interrupts[HISI_SAS_PHY_INT_NR] = { int_phyup_v1_hw, + int_abnormal_v1_hw }; static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) @@ -1499,6 +1568,7 @@ static const struct hisi_sas_hw hisi_sas_v1_hw = { .get_free_slot = get_free_slot_v1_hw, .start_delivery = start_delivery_v1_hw, .slot_complete = slot_complete_v1_hw, + .get_wideport_bitmap = get_wideport_bitmap_v1_hw, .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr), }; -- GitLab From dc5da4cf8e4c29f82e4ead8cf4d4dad61c78fab9 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:53 +0800 Subject: [PATCH 0679/2855] hisi_sas: Add bcast interrupt handler This is for expander broadcast event. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 31 ++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 1723dd453e06e..ad50aed5a1cfb 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1333,6 +1333,35 @@ end: return res; } +static irqreturn_t int_bcast_v1_hw(int irq, void *p) +{ + struct hisi_sas_phy *phy = p; + struct hisi_hba *hisi_hba = phy->hisi_hba; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + struct sas_ha_struct *sha = &hisi_hba->sha; + struct device *dev = &hisi_hba->pdev->dev; + int phy_no = sas_phy->id; + u32 irq_value; + irqreturn_t res = IRQ_HANDLED; + + irq_value = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2); + + if (!(irq_value & CHL_INT2_SL_RX_BC_ACK_MSK)) { + dev_err(dev, "bcast: irq_value = %x not set enable bit", + irq_value); + res = IRQ_NONE; + goto end; + } + + sha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + +end: + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, + CHL_INT2_SL_RX_BC_ACK_MSK); + + return res; +} + static irqreturn_t int_abnormal_v1_hw(int irq, void *p) { struct hisi_sas_phy *phy = p; @@ -1438,12 +1467,14 @@ static irqreturn_t cq_interrupt_v1_hw(int irq, void *p) } static const char phy_int_names[HISI_SAS_PHY_INT_NR][32] = { + {"Bcast"}, {"Phy Up"}, {"Abnormal"}, }; static const char cq_int_name[32] = "cq"; static irq_handler_t phy_interrupts[HISI_SAS_PHY_INT_NR] = { + int_bcast_v1_hw, int_phyup_v1_hw, int_abnormal_v1_hw }; -- GitLab From 66ee999b4e43e15182beb458689ec61b5715d568 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:54 +0800 Subject: [PATCH 0680/2855] hisi_sas: Add smp protocol support Add support for smp function, which allows devices attached by expander to be controlled. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 3 + drivers/scsi/hisi_sas/hisi_sas_main.c | 9 +++ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 88 ++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index e5ee3c90f7b5f..f34f73b3d64c7 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -36,6 +36,7 @@ (((sizeof(union hisi_sas_command_table)+3)/4)*4) #define HISI_SAS_MAX_SSP_RESP_SZ (sizeof(struct ssp_frame_hdr) + 1024) +#define HISI_SAS_MAX_SMP_RESP_SZ 1028 #define HISI_SAS_NAME_LEN 32 @@ -132,6 +133,8 @@ struct hisi_sas_hw { int (*prep_ssp)(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot, int is_tmf, struct hisi_sas_tmf_task *tmf); + int (*prep_smp)(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot); int (*slot_complete)(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot, int abort); void (*free_device)(struct hisi_hba *hisi_hba, diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 17978510c4f29..406ffa08fc1aa 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -98,6 +98,12 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, } EXPORT_SYMBOL_GPL(hisi_sas_slot_task_free); +static int hisi_sas_task_prep_smp(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot) +{ + return hisi_hba->hw->prep_smp(hisi_hba, slot); +} + static int hisi_sas_task_prep_ssp(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot, int is_tmf, struct hisi_sas_tmf_task *tmf) @@ -215,6 +221,9 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba, memset(slot->cmd_hdr, 0, sizeof(struct hisi_sas_cmd_hdr)); switch (task->task_proto) { + case SAS_PROTOCOL_SMP: + rc = hisi_sas_task_prep_smp(hisi_hba, slot); + break; case SAS_PROTOCOL_SSP: rc = hisi_sas_task_prep_ssp(hisi_hba, slot, is_tmf, tmf); break; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index ad50aed5a1cfb..64b17a183090f 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -903,6 +903,74 @@ static int prep_prd_sge_v1_hw(struct hisi_hba *hisi_hba, return 0; } +static int prep_smp_v1_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot) +{ + struct sas_task *task = slot->task; + struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr; + struct domain_device *device = task->dev; + struct device *dev = &hisi_hba->pdev->dev; + struct hisi_sas_port *port = slot->port; + struct scatterlist *sg_req, *sg_resp; + struct hisi_sas_device *sas_dev = device->lldd_dev; + dma_addr_t req_dma_addr; + unsigned int req_len, resp_len; + int elem, rc; + + /* + * DMA-map SMP request, response buffers + */ + /* req */ + sg_req = &task->smp_task.smp_req; + elem = dma_map_sg(dev, sg_req, 1, DMA_TO_DEVICE); + if (!elem) + return -ENOMEM; + req_len = sg_dma_len(sg_req); + req_dma_addr = sg_dma_address(sg_req); + + /* resp */ + sg_resp = &task->smp_task.smp_resp; + elem = dma_map_sg(dev, sg_resp, 1, DMA_FROM_DEVICE); + if (!elem) { + rc = -ENOMEM; + goto err_out_req; + } + resp_len = sg_dma_len(sg_resp); + if ((req_len & 0x3) || (resp_len & 0x3)) { + rc = -EINVAL; + goto err_out_resp; + } + + /* create header */ + /* dw0 */ + hdr->dw0 = cpu_to_le32((port->id << CMD_HDR_PORT_OFF) | + (1 << CMD_HDR_PRIORITY_OFF) | /* high pri */ + (1 << CMD_HDR_MODE_OFF) | /* ini mode */ + (2 << CMD_HDR_CMD_OFF)); /* smp */ + + /* map itct entry */ + hdr->dw1 = cpu_to_le32(sas_dev->device_id << CMD_HDR_DEVICE_ID_OFF); + + /* dw2 */ + hdr->dw2 = cpu_to_le32((((req_len-4)/4) << CMD_HDR_CFL_OFF) | + (HISI_SAS_MAX_SMP_RESP_SZ/4 << + CMD_HDR_MRFL_OFF)); + + hdr->transfer_tags = cpu_to_le32(slot->idx << CMD_HDR_IPTT_OFF); + + hdr->cmd_table_addr = cpu_to_le64(req_dma_addr); + hdr->sts_buffer_addr = cpu_to_le64(slot->status_buffer_dma); + + return 0; + +err_out_resp: + dma_unmap_sg(dev, &slot->task->smp_task.smp_resp, 1, + DMA_FROM_DEVICE); +err_out_req: + dma_unmap_sg(dev, &slot->task->smp_task.smp_req, 1, + DMA_TO_DEVICE); + return rc; +} static int prep_ssp_v1_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot, int is_tmf, @@ -1223,6 +1291,25 @@ static int slot_complete_v1_hw(struct hisi_hba *hisi_hba, sas_ssp_task_response(dev, task, iu); break; } + case SAS_PROTOCOL_SMP: + { + void *to; + struct scatterlist *sg_resp = &task->smp_task.smp_resp; + + ts->stat = SAM_STAT_GOOD; + to = kmap_atomic(sg_page(sg_resp)); + + dma_unmap_sg(dev, &task->smp_task.smp_resp, 1, + DMA_FROM_DEVICE); + dma_unmap_sg(dev, &task->smp_task.smp_req, 1, + DMA_TO_DEVICE); + memcpy(to + sg_resp->offset, + slot->status_buffer + + sizeof(struct hisi_sas_err_record), + sg_dma_len(sg_resp)); + kunmap_atomic(to); + break; + } case SAS_PROTOCOL_SATA: case SAS_PROTOCOL_STP: case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: @@ -1595,6 +1682,7 @@ static const struct hisi_sas_hw hisi_sas_v1_hw = { .setup_itct = setup_itct_v1_hw, .sl_notify = sl_notify_v1_hw, .free_device = free_device_v1_hw, + .prep_smp = prep_smp_v1_hw, .prep_ssp = prep_ssp_v1_hw, .get_free_slot = get_free_slot_v1_hw, .start_delivery = start_delivery_v1_hw, -- GitLab From 701f75ecd95130ab8a283fe5f44ba963a737d5f7 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:55 +0800 Subject: [PATCH 0681/2855] hisi_sas: Add scan finished and start Add functions for scsi host template scan_finished and scan_start methods. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 1 + drivers/scsi/hisi_sas/hisi_sas_main.c | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index f34f73b3d64c7..15adeca5ddc97 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -156,6 +156,7 @@ struct hisi_hba { u8 sas_addr[SAS_ADDR_SIZE]; int n_phy; + int scan_finished; spinlock_t lock; struct timer_list timer; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 406ffa08fc1aa..63ebaf3a9263c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -403,6 +403,29 @@ static int hisi_sas_dev_found(struct domain_device *device) return 0; } +static void hisi_sas_scan_start(struct Scsi_Host *shost) +{ + struct hisi_hba *hisi_hba = shost_priv(shost); + int i; + + for (i = 0; i < hisi_hba->n_phy; ++i) + hisi_sas_bytes_dmaed(hisi_hba, i); + + hisi_hba->scan_finished = 1; +} + +static int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time) +{ + struct hisi_hba *hisi_hba = shost_priv(shost); + struct sas_ha_struct *sha = &hisi_hba->sha; + + if (hisi_hba->scan_finished == 0) + return 0; + + sas_drain_work(sha); + return 1; +} + static void hisi_sas_phyup_work(struct work_struct *work) { struct hisi_sas_phy *phy = @@ -587,6 +610,8 @@ static struct scsi_host_template hisi_sas_sht = { .queuecommand = sas_queuecommand, .target_alloc = sas_target_alloc, .slave_configure = sas_slave_configure, + .scan_finished = hisi_sas_scan_finished, + .scan_start = hisi_sas_scan_start, .change_queue_depth = sas_change_queue_depth, .bios_param = sas_bios_param, .can_queue = 1, -- GitLab From 0efff300c72df76476d5d48d13a069ee04974ab3 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:56 +0800 Subject: [PATCH 0682/2855] hisi_sas: Add tmf methods Add function methods for tmf's. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 309 ++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 63ebaf3a9263c..4ee90eb55a0f6 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -553,6 +553,309 @@ static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags) } +static void hisi_sas_task_done(struct sas_task *task) +{ + if (!del_timer(&task->slow_task->timer)) + return; + complete(&task->slow_task->completion); +} + +static void hisi_sas_tmf_timedout(unsigned long data) +{ + struct sas_task *task = (struct sas_task *)data; + + task->task_state_flags |= SAS_TASK_STATE_ABORTED; + complete(&task->slow_task->completion); +} + +#define TASK_TIMEOUT 20 +#define TASK_RETRY 3 +static int hisi_sas_exec_internal_tmf_task(struct domain_device *device, + void *parameter, u32 para_len, + struct hisi_sas_tmf_task *tmf) +{ + struct hisi_sas_device *sas_dev = device->lldd_dev; + struct hisi_hba *hisi_hba = sas_dev->hisi_hba; + struct device *dev = &hisi_hba->pdev->dev; + struct sas_task *task; + int res, retry; + + for (retry = 0; retry < TASK_RETRY; retry++) { + task = sas_alloc_slow_task(GFP_KERNEL); + if (!task) + return -ENOMEM; + + task->dev = device; + task->task_proto = device->tproto; + + memcpy(&task->ssp_task, parameter, para_len); + task->task_done = hisi_sas_task_done; + + task->slow_task->timer.data = (unsigned long) task; + task->slow_task->timer.function = hisi_sas_tmf_timedout; + task->slow_task->timer.expires = jiffies + TASK_TIMEOUT*HZ; + add_timer(&task->slow_task->timer); + + res = hisi_sas_task_exec(task, GFP_KERNEL, 1, tmf); + + if (res) { + del_timer(&task->slow_task->timer); + dev_err(dev, "abort tmf: executing internal task failed: %d\n", + res); + goto ex_err; + } + + wait_for_completion(&task->slow_task->completion); + res = TMF_RESP_FUNC_FAILED; + /* Even TMF timed out, return direct. */ + if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { + if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { + dev_err(dev, "abort tmf: TMF task[%d] timeout\n", + tmf->tag_of_task_to_be_managed); + if (task->lldd_task) { + struct hisi_sas_slot *slot = + task->lldd_task; + + hisi_sas_slot_task_free(hisi_hba, + task, slot); + } + + goto ex_err; + } + } + + if (task->task_status.resp == SAS_TASK_COMPLETE && + task->task_status.stat == SAM_STAT_GOOD) { + res = TMF_RESP_FUNC_COMPLETE; + break; + } + + if (task->task_status.resp == SAS_TASK_COMPLETE && + task->task_status.stat == SAS_DATA_UNDERRUN) { + /* no error, but return the number of bytes of + * underrun + */ + dev_warn(dev, "abort tmf: task to dev %016llx " + "resp: 0x%x sts 0x%x underrun\n", + SAS_ADDR(device->sas_addr), + task->task_status.resp, + task->task_status.stat); + res = task->task_status.residual; + break; + } + + if (task->task_status.resp == SAS_TASK_COMPLETE && + task->task_status.stat == SAS_DATA_OVERRUN) { + dev_warn(dev, "abort tmf: blocked task error\n"); + res = -EMSGSIZE; + break; + } + + dev_warn(dev, "abort tmf: task to dev " + "%016llx resp: 0x%x status 0x%x\n", + SAS_ADDR(device->sas_addr), task->task_status.resp, + task->task_status.stat); + sas_free_task(task); + task = NULL; + } +ex_err: + WARN_ON(retry == TASK_RETRY); + sas_free_task(task); + return res; +} + +static int hisi_sas_debug_issue_ssp_tmf(struct domain_device *device, + u8 *lun, struct hisi_sas_tmf_task *tmf) +{ + struct sas_ssp_task ssp_task; + + if (!(device->tproto & SAS_PROTOCOL_SSP)) + return TMF_RESP_FUNC_ESUPP; + + memcpy(ssp_task.LUN, lun, 8); + + return hisi_sas_exec_internal_tmf_task(device, &ssp_task, + sizeof(ssp_task), tmf); +} + +static int hisi_sas_abort_task(struct sas_task *task) +{ + struct scsi_lun lun; + struct hisi_sas_tmf_task tmf_task; + struct domain_device *device = task->dev; + struct hisi_sas_device *sas_dev = device->lldd_dev; + struct hisi_hba *hisi_hba = dev_to_hisi_hba(task->dev); + struct device *dev = &hisi_hba->pdev->dev; + int rc = TMF_RESP_FUNC_FAILED; + unsigned long flags; + + if (!sas_dev) { + dev_warn(dev, "Device has been removed\n"); + return TMF_RESP_FUNC_FAILED; + } + + spin_lock_irqsave(&task->task_state_lock, flags); + if (task->task_state_flags & SAS_TASK_STATE_DONE) { + spin_unlock_irqrestore(&task->task_state_lock, flags); + rc = TMF_RESP_FUNC_COMPLETE; + goto out; + } + + spin_unlock_irqrestore(&task->task_state_lock, flags); + sas_dev->dev_status = HISI_SAS_DEV_EH; + if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) { + struct scsi_cmnd *cmnd = task->uldd_task; + struct hisi_sas_slot *slot = task->lldd_task; + u32 tag = slot->idx; + + int_to_scsilun(cmnd->device->lun, &lun); + tmf_task.tmf = TMF_ABORT_TASK; + tmf_task.tag_of_task_to_be_managed = cpu_to_le16(tag); + + rc = hisi_sas_debug_issue_ssp_tmf(task->dev, lun.scsi_lun, + &tmf_task); + + /* if successful, clear the task and callback forwards.*/ + if (rc == TMF_RESP_FUNC_COMPLETE) { + if (task->lldd_task) { + struct hisi_sas_slot *slot; + + slot = &hisi_hba->slot_info + [tmf_task.tag_of_task_to_be_managed]; + spin_lock_irqsave(&hisi_hba->lock, flags); + hisi_hba->hw->slot_complete(hisi_hba, slot, 1); + spin_unlock_irqrestore(&hisi_hba->lock, flags); + } + } + + } else if (task->task_proto & SAS_PROTOCOL_SATA || + task->task_proto & SAS_PROTOCOL_STP) { + if (task->dev->dev_type == SAS_SATA_DEV) { + struct hisi_slot_info *slot = task->lldd_task; + + dev_notice(dev, "abort task: hba=%p task=%p slot=%p\n", + hisi_hba, task, slot); + task->task_state_flags |= SAS_TASK_STATE_ABORTED; + rc = TMF_RESP_FUNC_COMPLETE; + goto out; + } + + } + +out: + if (rc != TMF_RESP_FUNC_COMPLETE) + dev_notice(dev, "abort task: rc=%d\n", rc); + return rc; +} + +static int hisi_sas_abort_task_set(struct domain_device *device, u8 *lun) +{ + struct hisi_sas_tmf_task tmf_task; + int rc = TMF_RESP_FUNC_FAILED; + + tmf_task.tmf = TMF_ABORT_TASK_SET; + rc = hisi_sas_debug_issue_ssp_tmf(device, lun, &tmf_task); + + return rc; +} + +static int hisi_sas_clear_aca(struct domain_device *device, u8 *lun) +{ + int rc = TMF_RESP_FUNC_FAILED; + struct hisi_sas_tmf_task tmf_task; + + tmf_task.tmf = TMF_CLEAR_ACA; + rc = hisi_sas_debug_issue_ssp_tmf(device, lun, &tmf_task); + + return rc; +} + +static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) +{ + struct sas_phy *phy = sas_get_local_phy(device); + int rc, reset_type = (device->dev_type == SAS_SATA_DEV || + (device->tproto & SAS_PROTOCOL_STP)) ? 0 : 1; + rc = sas_phy_reset(phy, reset_type); + sas_put_local_phy(phy); + msleep(2000); + return rc; +} + +static int hisi_sas_I_T_nexus_reset(struct domain_device *device) +{ + struct hisi_sas_device *sas_dev = device->lldd_dev; + struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); + unsigned long flags; + int rc = TMF_RESP_FUNC_FAILED; + + if (sas_dev->dev_status != HISI_SAS_DEV_EH) + return TMF_RESP_FUNC_FAILED; + sas_dev->dev_status = HISI_SAS_DEV_NORMAL; + + rc = hisi_sas_debug_I_T_nexus_reset(device); + + spin_lock_irqsave(&hisi_hba->lock, flags); + hisi_sas_release_task(hisi_hba, device); + spin_unlock_irqrestore(&hisi_hba->lock, flags); + + return 0; +} + +static int hisi_sas_lu_reset(struct domain_device *device, u8 *lun) +{ + struct hisi_sas_tmf_task tmf_task; + struct hisi_sas_device *sas_dev = device->lldd_dev; + struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); + struct device *dev = &hisi_hba->pdev->dev; + unsigned long flags; + int rc = TMF_RESP_FUNC_FAILED; + + tmf_task.tmf = TMF_LU_RESET; + sas_dev->dev_status = HISI_SAS_DEV_EH; + rc = hisi_sas_debug_issue_ssp_tmf(device, lun, &tmf_task); + if (rc == TMF_RESP_FUNC_COMPLETE) { + spin_lock_irqsave(&hisi_hba->lock, flags); + hisi_sas_release_task(hisi_hba, device); + spin_unlock_irqrestore(&hisi_hba->lock, flags); + } + + /* If failed, fall-through I_T_Nexus reset */ + dev_err(dev, "lu_reset: for device[%llx]:rc= %d\n", + sas_dev->device_id, rc); + return rc; +} + +static int hisi_sas_query_task(struct sas_task *task) +{ + struct scsi_lun lun; + struct hisi_sas_tmf_task tmf_task; + int rc = TMF_RESP_FUNC_FAILED; + + if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) { + struct scsi_cmnd *cmnd = task->uldd_task; + struct domain_device *device = task->dev; + struct hisi_sas_slot *slot = task->lldd_task; + u32 tag = slot->idx; + + int_to_scsilun(cmnd->device->lun, &lun); + tmf_task.tmf = TMF_QUERY_TASK; + tmf_task.tag_of_task_to_be_managed = cpu_to_le16(tag); + + rc = hisi_sas_debug_issue_ssp_tmf(device, + lun.scsi_lun, + &tmf_task); + switch (rc) { + /* The task is still in Lun, release it then */ + case TMF_RESP_FUNC_SUCC: + /* The task is not in Lun or failed, reset the phy */ + case TMF_RESP_FUNC_FAILED: + case TMF_RESP_FUNC_COMPLETE: + break; + } + } + return rc; +} + static void hisi_sas_port_formed(struct asd_sas_phy *sas_phy) { hisi_sas_port_notify_formed(sas_phy); @@ -629,6 +932,12 @@ static struct sas_domain_function_template hisi_sas_transport_ops = { .lldd_dev_found = hisi_sas_dev_found, .lldd_dev_gone = hisi_sas_dev_gone, .lldd_execute_task = hisi_sas_queue_command, + .lldd_abort_task = hisi_sas_abort_task, + .lldd_abort_task_set = hisi_sas_abort_task_set, + .lldd_clear_aca = hisi_sas_clear_aca, + .lldd_I_T_nexus_reset = hisi_sas_I_T_nexus_reset, + .lldd_lu_reset = hisi_sas_lu_reset, + .lldd_query_task = hisi_sas_query_task, .lldd_port_formed = hisi_sas_port_formed, .lldd_port_deformed = hisi_sas_port_deformed, }; -- GitLab From e4189d539f78f335f57266d2c3a848cadbd3a00f Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:57 +0800 Subject: [PATCH 0683/2855] hisi_sas: Add control phy handler Add method for lldd_control_phy. Currently link rate control and spinup hold is unsupported. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 3 +++ drivers/scsi/hisi_sas/hisi_sas_main.c | 29 ++++++++++++++++++++++++++ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 23 ++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 15adeca5ddc97..5b790c9438d65 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -137,6 +137,9 @@ struct hisi_sas_hw { struct hisi_sas_slot *slot); int (*slot_complete)(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot, int abort); + void (*phy_enable)(struct hisi_hba *hisi_hba, int phy_no); + void (*phy_disable)(struct hisi_hba *hisi_hba, int phy_no); + void (*phy_hard_reset)(struct hisi_hba *hisi_hba, int phy_no); void (*free_device)(struct hisi_hba *hisi_hba, struct hisi_sas_device *dev); int (*get_wideport_bitmap)(struct hisi_hba *hisi_hba, int port_id); diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 4ee90eb55a0f6..137762515aa93 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -552,6 +552,34 @@ static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags) return hisi_sas_task_exec(task, gfp_flags, 0, NULL); } +static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, + void *funcdata) +{ + struct sas_ha_struct *sas_ha = sas_phy->ha; + struct hisi_hba *hisi_hba = sas_ha->lldd_ha; + int phy_no = sas_phy->id; + + switch (func) { + case PHY_FUNC_HARD_RESET: + hisi_hba->hw->phy_hard_reset(hisi_hba, phy_no); + break; + + case PHY_FUNC_LINK_RESET: + hisi_hba->hw->phy_enable(hisi_hba, phy_no); + hisi_hba->hw->phy_hard_reset(hisi_hba, phy_no); + break; + + case PHY_FUNC_DISABLE: + hisi_hba->hw->phy_disable(hisi_hba, phy_no); + break; + + case PHY_FUNC_SET_LINK_RATE: + case PHY_FUNC_RELEASE_SPINUP_HOLD: + default: + return -EOPNOTSUPP; + } + return 0; +} static void hisi_sas_task_done(struct sas_task *task) { @@ -932,6 +960,7 @@ static struct sas_domain_function_template hisi_sas_transport_ops = { .lldd_dev_found = hisi_sas_dev_found, .lldd_dev_gone = hisi_sas_dev_gone, .lldd_execute_task = hisi_sas_queue_command, + .lldd_control_phy = hisi_sas_control_phy, .lldd_abort_task = hisi_sas_abort_task, .lldd_abort_task_set = hisi_sas_abort_task_set, .lldd_clear_aca = hisi_sas_clear_aca, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 64b17a183090f..a95259cdc2bf7 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -764,6 +764,14 @@ static void enable_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); } +static void disable_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG); + + cfg &= ~PHY_CFG_ENA_MSK; + hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); +} + static void start_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) { config_id_frame_v1_hw(hisi_hba, phy_no); @@ -772,6 +780,18 @@ static void start_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) enable_phy_v1_hw(hisi_hba, phy_no); } +static void stop_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + disable_phy_v1_hw(hisi_hba, phy_no); +} + +static void phy_hard_reset_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + stop_phy_v1_hw(hisi_hba, phy_no); + msleep(100); + start_phy_v1_hw(hisi_hba, phy_no); +} + static void start_phys_v1_hw(unsigned long data) { struct hisi_hba *hisi_hba = (struct hisi_hba *)data; @@ -1687,6 +1707,9 @@ static const struct hisi_sas_hw hisi_sas_v1_hw = { .get_free_slot = get_free_slot_v1_hw, .start_delivery = start_delivery_v1_hw, .slot_complete = slot_complete_v1_hw, + .phy_enable = enable_phy_v1_hw, + .phy_disable = disable_phy_v1_hw, + .phy_hard_reset = phy_hard_reset_v1_hw, .get_wideport_bitmap = get_wideport_bitmap_v1_hw, .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr), }; -- GitLab From ff165289f9121c7f5ac2f9273aef5f47e84625da Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:58 +0800 Subject: [PATCH 0684/2855] hisi_sas: Add fatal irq handler Add handlers for fatal interrupts. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 119 +++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index a95259cdc2bf7..e29b7c7aa7bcf 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1573,6 +1573,93 @@ static irqreturn_t cq_interrupt_v1_hw(int irq, void *p) return IRQ_HANDLED; } +static irqreturn_t fatal_ecc_int_v1_hw(int irq, void *p) +{ + struct hisi_hba *hisi_hba = p; + struct device *dev = &hisi_hba->pdev->dev; + u32 ecc_int = hisi_sas_read32(hisi_hba, SAS_ECC_INTR); + + if (ecc_int & SAS_ECC_INTR_DQ_ECC1B_MSK) { + u32 ecc_err = hisi_sas_read32(hisi_hba, HGC_ECC_ERR); + + panic("%s: Fatal DQ 1b ECC interrupt (0x%x)\n", + dev_name(dev), ecc_err); + } + + if (ecc_int & SAS_ECC_INTR_DQ_ECCBAD_MSK) { + u32 addr = (hisi_sas_read32(hisi_hba, HGC_DQ_ECC_ADDR) & + HGC_DQ_ECC_ADDR_BAD_MSK) >> + HGC_DQ_ECC_ADDR_BAD_OFF; + + panic("%s: Fatal DQ RAM ECC interrupt @ 0x%08x\n", + dev_name(dev), addr); + } + + if (ecc_int & SAS_ECC_INTR_IOST_ECC1B_MSK) { + u32 ecc_err = hisi_sas_read32(hisi_hba, HGC_ECC_ERR); + + panic("%s: Fatal IOST 1b ECC interrupt (0x%x)\n", + dev_name(dev), ecc_err); + } + + if (ecc_int & SAS_ECC_INTR_IOST_ECCBAD_MSK) { + u32 addr = (hisi_sas_read32(hisi_hba, HGC_IOST_ECC_ADDR) & + HGC_IOST_ECC_ADDR_BAD_MSK) >> + HGC_IOST_ECC_ADDR_BAD_OFF; + + panic("%s: Fatal IOST RAM ECC interrupt @ 0x%08x\n", + dev_name(dev), addr); + } + + if (ecc_int & SAS_ECC_INTR_ITCT_ECCBAD_MSK) { + u32 addr = (hisi_sas_read32(hisi_hba, HGC_ITCT_ECC_ADDR) & + HGC_ITCT_ECC_ADDR_BAD_MSK) >> + HGC_ITCT_ECC_ADDR_BAD_OFF; + + panic("%s: Fatal TCT RAM ECC interrupt @ 0x%08x\n", + dev_name(dev), addr); + } + + if (ecc_int & SAS_ECC_INTR_ITCT_ECC1B_MSK) { + u32 ecc_err = hisi_sas_read32(hisi_hba, HGC_ECC_ERR); + + panic("%s: Fatal ITCT 1b ECC interrupt (0x%x)\n", + dev_name(dev), ecc_err); + } + + hisi_sas_write32(hisi_hba, SAS_ECC_INTR, ecc_int | 0x3f); + + return IRQ_HANDLED; +} + +static irqreturn_t fatal_axi_int_v1_hw(int irq, void *p) +{ + struct hisi_hba *hisi_hba = p; + struct device *dev = &hisi_hba->pdev->dev; + u32 axi_int = hisi_sas_read32(hisi_hba, ENT_INT_SRC2); + u32 axi_info = hisi_sas_read32(hisi_hba, HGC_AXI_FIFO_ERR_INFO); + + if (axi_int & ENT_INT_SRC2_DQ_CFG_ERR_MSK) + panic("%s: Fatal DQ_CFG_ERR interrupt (0x%x)\n", + dev_name(dev), axi_info); + + if (axi_int & ENT_INT_SRC2_CQ_CFG_ERR_MSK) + panic("%s: Fatal CQ_CFG_ERR interrupt (0x%x)\n", + dev_name(dev), axi_info); + + if (axi_int & ENT_INT_SRC2_AXI_WRONG_INT_MSK) + panic("%s: Fatal AXI_WRONG_INT interrupt (0x%x)\n", + dev_name(dev), axi_info); + + if (axi_int & ENT_INT_SRC2_AXI_OVERLF_INT_MSK) + panic("%s: Fatal AXI_OVERLF_INT incorrect interrupt (0x%x)\n", + dev_name(dev), axi_info); + + hisi_sas_write32(hisi_hba, ENT_INT_SRC2, axi_int | 0x30000000); + + return IRQ_HANDLED; +} + static const char phy_int_names[HISI_SAS_PHY_INT_NR][32] = { {"Bcast"}, {"Phy Up"}, @@ -1580,12 +1667,22 @@ static const char phy_int_names[HISI_SAS_PHY_INT_NR][32] = { }; static const char cq_int_name[32] = "cq"; +static const char fatal_int_name[HISI_SAS_FATAL_INT_NR][32] = { + "fatal ecc", + "fatal axi" +}; + static irq_handler_t phy_interrupts[HISI_SAS_PHY_INT_NR] = { int_bcast_v1_hw, int_phyup_v1_hw, int_abnormal_v1_hw }; +static irq_handler_t fatal_interrupts[HISI_SAS_MAX_QUEUES] = { + fatal_ecc_int_v1_hw, + fatal_axi_int_v1_hw +}; + static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) { struct device *dev = &hisi_hba->pdev->dev; @@ -1646,6 +1743,28 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) } } + idx = (hisi_hba->n_phy * HISI_SAS_PHY_INT_NR) + hisi_hba->queue_count; + for (i = 0; i < HISI_SAS_FATAL_INT_NR; i++, idx++) { + irq = irq_of_parse_and_map(np, idx); + if (!irq) { + dev_err(dev, "irq init: could not map fatal interrupt %d\n", + idx); + return -ENOENT; + } + (void)snprintf(&int_names[idx * HISI_SAS_NAME_LEN], + HISI_SAS_NAME_LEN, + "%s %s:%d", dev_name(dev), fatal_int_name[i], i); + rc = devm_request_irq(dev, irq, fatal_interrupts[i], 0, + &int_names[idx * HISI_SAS_NAME_LEN], + hisi_hba); + if (rc) { + dev_err(dev, + "irq init: could not request fatal interrupt %d, rc=%d\n", + irq, rc); + return -ENOENT; + } + } + return 0; } -- GitLab From 16c6c252f0ac8256e38d36a3de7c59d5d27efdc3 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:59 +0800 Subject: [PATCH 0685/2855] MAINTAINERS: Add maintainer for HiSi SAS driver Add maintainer for HiSilicon SAS driver. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index ea1751283b496..d2f94e21fe577 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5035,6 +5035,13 @@ F: include/uapi/linux/if_hippi.h F: net/802/hippi.c F: drivers/net/hippi/ +HISILICON SAS Controller +M: John Garry +W: http://www.hisilicon.com +S: Supported +F: drivers/scsi/hisi_sas/ +F: Documentation/devicetree/bindings/scsi/hisilicon-sas.txt + HOST AP DRIVER M: Jouni Malinen L: hostap@shmoo.com (subscribers-only) -- GitLab From 8c77dca011125b795bfa1c86f85a80132feee578 Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 19 Nov 2015 20:23:59 +0800 Subject: [PATCH 0686/2855] hisi_sas: Remove dependency on of_irq_count Originally the driver would use of_irq_count to calculate how much memory is required for storing the interrupt names, since the number of interrupt sources for the controller is variable. Since of_irq_count cannot be used by the driver, use fixed names. Signed-off-by: John Garry Signed-off-by: Zhangfei Gao Acked-by: Rob Herring Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 3 --- drivers/scsi/hisi_sas/hisi_sas_main.c | 8 ------ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 34 ++++---------------------- 3 files changed, 5 insertions(+), 40 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 5b790c9438d65..30a9ab94cd291 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -38,8 +38,6 @@ #define HISI_SAS_MAX_SSP_RESP_SZ (sizeof(struct ssp_frame_hdr) + 1024) #define HISI_SAS_MAX_SMP_RESP_SZ 1028 -#define HISI_SAS_NAME_LEN 32 - struct hisi_hba; enum { @@ -178,7 +176,6 @@ struct hisi_hba { int queue_count; int queue; - char *int_names; struct hisi_sas_slot *slot_prep; struct dma_pool *sge_page_pool; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 137762515aa93..29290181b1319 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1160,7 +1160,6 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, struct device *dev = &pdev->dev; struct device_node *np = pdev->dev.of_node; struct property *sas_addr_prop; - int num; shost = scsi_host_alloc(&hisi_sas_sht, sizeof(*hisi_hba)); if (!shost) @@ -1197,13 +1196,6 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, if (of_property_read_u32(np, "queue-count", &hisi_hba->queue_count)) goto err_out; - num = of_irq_count(np); - hisi_hba->int_names = devm_kcalloc(dev, num, - HISI_SAS_NAME_LEN, - GFP_KERNEL); - if (!hisi_hba->int_names) - goto err_out; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hisi_hba->regs = devm_ioremap_resource(dev, res); if (IS_ERR(hisi_hba->regs)) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index e29b7c7aa7bcf..0ed2f92c8959d 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1660,18 +1660,6 @@ static irqreturn_t fatal_axi_int_v1_hw(int irq, void *p) return IRQ_HANDLED; } -static const char phy_int_names[HISI_SAS_PHY_INT_NR][32] = { - {"Bcast"}, - {"Phy Up"}, - {"Abnormal"}, -}; - -static const char cq_int_name[32] = "cq"; -static const char fatal_int_name[HISI_SAS_FATAL_INT_NR][32] = { - "fatal ecc", - "fatal axi" -}; - static irq_handler_t phy_interrupts[HISI_SAS_PHY_INT_NR] = { int_bcast_v1_hw, int_phyup_v1_hw, @@ -1687,7 +1675,6 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) { struct device *dev = &hisi_hba->pdev->dev; struct device_node *np = dev->of_node; - char *int_names = hisi_hba->int_names; int i, j, irq, rc, idx; if (!np) @@ -1706,13 +1693,8 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) return -ENOENT; } - (void)snprintf(&int_names[idx * HISI_SAS_NAME_LEN], - HISI_SAS_NAME_LEN, - "%s %s:%d", dev_name(dev), - phy_int_names[j], i); rc = devm_request_irq(dev, irq, phy_interrupts[j], 0, - &int_names[idx * HISI_SAS_NAME_LEN], - phy); + DRV_NAME " phy", phy); if (rc) { dev_err(dev, "irq init: could not request " "phy interrupt %d, rc=%d\n", @@ -1730,12 +1712,9 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx); return -ENOENT; } - (void)snprintf(&int_names[idx * HISI_SAS_NAME_LEN], - HISI_SAS_NAME_LEN, - "%s %s:%d", dev_name(dev), cq_int_name, i); + rc = devm_request_irq(dev, irq, cq_interrupt_v1_hw, 0, - &int_names[idx * HISI_SAS_NAME_LEN], - &hisi_hba->cq[i]); + DRV_NAME " cq", &hisi_hba->cq[i]); if (rc) { dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n", irq, rc); @@ -1751,12 +1730,9 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx); return -ENOENT; } - (void)snprintf(&int_names[idx * HISI_SAS_NAME_LEN], - HISI_SAS_NAME_LEN, - "%s %s:%d", dev_name(dev), fatal_int_name[i], i); + rc = devm_request_irq(dev, irq, fatal_interrupts[i], 0, - &int_names[idx * HISI_SAS_NAME_LEN], - hisi_hba); + DRV_NAME " fatal", hisi_hba); if (rc) { dev_err(dev, "irq init: could not request fatal interrupt %d, rc=%d\n", -- GitLab From 494131124f04252bb3f91c0801bfe796d49971ef Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 20 Nov 2015 17:38:28 +0100 Subject: [PATCH 0687/2855] scsi: use sector_div instead of do_div do_div is the wrong way to divide a sector_t, as it is less efficient when sector_t is 32-bit wide. With the upcoming do_div optimizations, the kernel starts warning about this: drivers/scsi/scsi_debug.c: In function 'dif_store': include/asm-generic/div64.h:207:28: warning: comparison of distinct pointer types lacks a cast This changes the code to use sector_div instead, which always produces optimal code. Signed-off-by: Arnd Bergmann Reviewed-by: Hannes Reinicke Reviewed-by: Sagi Grimberg Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index dfcc45bb03b1f..ec622ba9864ac 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -678,7 +678,7 @@ static void *fake_store(unsigned long long lba) static struct sd_dif_tuple *dif_store(sector_t sector) { - sector = do_div(sector, sdebug_store_sectors); + sector = sector_div(sector, sdebug_store_sectors); return dif_storep + sector; } @@ -2780,7 +2780,7 @@ static unsigned long lba_to_map_index(sector_t lba) lba += scsi_debug_unmap_granularity - scsi_debug_unmap_alignment; } - do_div(lba, scsi_debug_unmap_granularity); + sector_div(lba, scsi_debug_unmap_granularity); return lba; } -- GitLab From fe0798c5e150be8f06959250076d3864477e74c2 Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Tue, 10 Nov 2015 13:59:06 +0800 Subject: [PATCH 0688/2855] aacraid: aac_release_resources() can be static Signed-off-by: Fengguang Wu Reviewed-by: Johannes Thumshirn Reviewed-by: Mahesh Rajashekhara Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/linit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 3b6e5c67e853d..76eaa38ffd6e5 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1318,7 +1318,7 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) } #if (defined(CONFIG_PM)) -void aac_release_resources(struct aac_dev *aac) +static void aac_release_resources(struct aac_dev *aac) { int i; -- GitLab From 6f923a0134d9868a71db19cca1fae551a27b46f5 Mon Sep 17 00:00:00 2001 From: Konstantin Shkolnyy Date: Tue, 24 Nov 2015 16:28:41 -0600 Subject: [PATCH 0689/2855] USB: cp210x: add tx_empty() Added tx_empty callback needed for generic wait-until-sent support. Without this function, when the port is closed usbserial can't know that there are still data in the chip's transmit FIFO. The chip gets disabled and untransmitted data lost. When the actual byte count is reported by tx-empty the close can be delayed until all data are sent. Signed-off-by: Konstantin Shkolnyy [johan: modify tx_empty error handling ] Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 58 +++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 9e5d5b016633a..084033a568c21 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -38,6 +38,7 @@ static void cp210x_change_speed(struct tty_struct *, struct usb_serial_port *, struct ktermios *); static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *, struct ktermios*); +static bool cp210x_tx_empty(struct usb_serial_port *port); static int cp210x_tiocmget(struct tty_struct *); static int cp210x_tiocmset(struct tty_struct *, unsigned int, unsigned int); static int cp210x_tiocmset_port(struct usb_serial_port *port, @@ -215,6 +216,7 @@ static struct usb_serial_driver cp210x_device = { .close = cp210x_close, .break_ctl = cp210x_break_ctl, .set_termios = cp210x_set_termios, + .tx_empty = cp210x_tx_empty, .tiocmget = cp210x_tiocmget, .tiocmset = cp210x_tiocmset, .port_probe = cp210x_port_probe, @@ -301,6 +303,17 @@ static struct usb_serial_driver * const serial_drivers[] = { #define CONTROL_WRITE_DTR 0x0100 #define CONTROL_WRITE_RTS 0x0200 +/* CP210X_GET_COMM_STATUS returns these 0x13 bytes */ +struct cp210x_comm_status { + __le32 ulErrors; + __le32 ulHoldReasons; + __le32 ulAmountInInQueue; + __le32 ulAmountInOutQueue; + u8 bEofReceived; + u8 bWaitForImmediate; + u8 bReserved; +} __packed; + /* * CP210X_PURGE - 16 bits passed in wValue of USB request. * SiLabs app note AN571 gives a strange description of the 4 bits: @@ -549,6 +562,51 @@ static void cp210x_close(struct usb_serial_port *port) cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_DISABLE); } +/* + * Read how many bytes are waiting in the TX queue. + */ +static int cp210x_get_tx_queue_byte_count(struct usb_serial_port *port, + u32 *count) +{ + struct usb_serial *serial = port->serial; + struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); + struct cp210x_comm_status *sts; + int result; + + sts = kmalloc(sizeof(*sts), GFP_KERNEL); + if (!sts) + return -ENOMEM; + + result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), + CP210X_GET_COMM_STATUS, REQTYPE_INTERFACE_TO_HOST, + 0, port_priv->bInterfaceNumber, sts, sizeof(*sts), + USB_CTRL_GET_TIMEOUT); + if (result == sizeof(*sts)) { + *count = le32_to_cpu(sts->ulAmountInOutQueue); + result = 0; + } else { + dev_err(&port->dev, "failed to get comm status: %d\n", result); + if (result >= 0) + result = -EPROTO; + } + + kfree(sts); + + return result; +} + +static bool cp210x_tx_empty(struct usb_serial_port *port) +{ + int err; + u32 count; + + err = cp210x_get_tx_queue_byte_count(port, &count); + if (err) + return true; + + return !count; +} + /* * cp210x_get_termios * Reads the baud rate, data bits, parity, stop bits and flow control mode -- GitLab From 57f889471c0fb55cbb0db98b30483040e2065bd9 Mon Sep 17 00:00:00 2001 From: John Ogness Date: Wed, 11 Nov 2015 14:48:50 +0100 Subject: [PATCH 0690/2855] powerpc/powermac: set IRQF_NO_THREAD for xmon/cascade handlers The xmon and cascade irq handlers must not run as threads. pmac_pic_lock is already a raw_spinlock, but the irq flag IRQF_NO_THREAD needs to be set as well. Signed-off-by: John Ogness Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powermac/pic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 6f4f8b060def5..9815463450331 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -258,13 +258,14 @@ static unsigned int pmac_pic_get_irq(void) #ifdef CONFIG_XMON static struct irqaction xmon_action = { .handler = xmon_irq, - .flags = 0, + .flags = IRQF_NO_THREAD, .name = "NMI - XMON" }; #endif static struct irqaction gatwick_cascade_action = { .handler = gatwick_action, + .flags = IRQF_NO_THREAD, .name = "cascade", }; -- GitLab From 6c3082151e13846fd872cc216e8cbb5a59cd0b12 Mon Sep 17 00:00:00 2001 From: John Ogness Date: Wed, 11 Nov 2015 15:15:03 +0100 Subject: [PATCH 0691/2855] powerpc/powermac: IRQF_NO_SUSPEND not IRQF_TIMER for non-timer Since gpio1 is not a timer, it also should not use IRQF_TIMER. Similar to commit ba461f094bab ("powerpc: Use IRQF_NO_SUSPEND not IRQF_TIMER for non-timer interrupts"). Signed-off-by: John Ogness Signed-off-by: Michael Ellerman --- drivers/macintosh/via-pmu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index f9512bfa6c3c7..01ee736fe0efc 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -425,8 +425,9 @@ static int __init via_pmu_start(void) gpio_irq = irq_of_parse_and_map(gpio_node, 0); if (gpio_irq != NO_IRQ) { - if (request_irq(gpio_irq, gpio1_interrupt, IRQF_TIMER, - "GPIO1 ADB", (void *)0)) + if (request_irq(gpio_irq, gpio1_interrupt, + IRQF_NO_SUSPEND, "GPIO1 ADB", + (void *)0)) printk(KERN_ERR "pmu: can't get irq %d" " (GPIO1)\n", gpio_irq); else -- GitLab From 58531b0c800fd514f04ae42b6cf5ab15abdf0651 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Thu, 5 Nov 2015 12:31:34 +0100 Subject: [PATCH 0692/2855] powerpc/boot: allow wrapper to work on non-english system if the language is not english objdump output is not parsed correctly and format is "". Later, "ld -m $format" fails. This patch adds "LANG=C" to force english output for objdump. Signed-off-by: Laurent Vivier Signed-off-by: Michael Ellerman --- arch/powerpc/boot/wrapper | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index ceaa75d5a6843..6a19fcef5596f 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -154,7 +154,7 @@ if [ -z "$kernel" ]; then kernel=vmlinux fi -elfformat="`${CROSS}objdump -p "$kernel" | grep 'file format' | awk '{print $4}'`" +LANG=C elfformat="`${CROSS}objdump -p "$kernel" | grep 'file format' | awk '{print $4}'`" case "$elfformat" in elf64-powerpcle) format=elf64lppc ;; elf64-powerpc) format=elf32ppc ;; -- GitLab From cdfc8ed6904d7b0c0ca23d619b387b32070703b1 Mon Sep 17 00:00:00 2001 From: Rashmica Gupta Date: Thu, 19 Nov 2015 14:26:28 +1100 Subject: [PATCH 0693/2855] powerpc: Remove unused function trace_syscall() This function has been unused since commit 14cf11af6cf6 ("powerpc: Merge enough to start building in arch/powerpc."), so remove it. Signed-off-by: Rashmica Gupta Reviewed-by: Andrew Donnellan Reviewed-by: Anshuman Khandual Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/traps.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 37de90f8a845c..b6becc795bb55 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1313,13 +1313,6 @@ void nonrecoverable_exception(struct pt_regs *regs) die("nonrecoverable exception", regs, SIGKILL); } -void trace_syscall(struct pt_regs *regs) -{ - printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n", - current, task_pid_nr(current), regs->nip, regs->link, regs->gpr[0], - regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted()); -} - void kernel_fp_unavailable_exception(struct pt_regs *regs) { enum ctx_state prev_state = exception_enter(); -- GitLab From f43194e45852b0455d2a3e3730f70daa76958423 Mon Sep 17 00:00:00 2001 From: Rashmica Gupta Date: Thu, 19 Nov 2015 17:04:53 +1100 Subject: [PATCH 0694/2855] powerpc: Standardise on NR_syscalls rather than __NR_syscalls. Most architectures use NR_syscalls as the #define for the number of syscalls. We use __NR_syscalls, and then define NR_syscalls as __NR_syscalls. __NR_syscalls is not used outside arch code, whereas NR_syscalls is. So as NR_syscalls must be defined and __NR_syscalls does not, replace __NR_syscalls with NR_syscalls. Signed-off-by: Rashmica Gupta Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/unistd.h | 3 +-- arch/powerpc/include/asm/vdso_datapage.h | 2 +- arch/powerpc/kernel/systbl_chk.c | 2 +- arch/powerpc/kernel/systbl_chk.sh | 2 +- arch/powerpc/kernel/vdso.c | 2 +- arch/powerpc/kernel/vdso32/datapage.S | 2 +- arch/powerpc/kernel/vdso64/datapage.S | 2 +- arch/powerpc/platforms/cell/spufs/run.c | 2 +- 8 files changed, 8 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index 4b6b8ace18e08..6a5ace5fa0c8a 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h @@ -12,10 +12,9 @@ #include -#define __NR_syscalls 379 +#define NR_syscalls 379 #define __NR__exit __NR_exit -#define NR_syscalls __NR_syscalls #ifndef __ASSEMBLY__ diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h index b73a8199f161c..1afe90ade595e 100644 --- a/arch/powerpc/include/asm/vdso_datapage.h +++ b/arch/powerpc/include/asm/vdso_datapage.h @@ -41,7 +41,7 @@ #include #include -#define SYSCALL_MAP_SIZE ((__NR_syscalls + 31) / 32) +#define SYSCALL_MAP_SIZE ((NR_syscalls + 31) / 32) /* * So here is the ppc64 backward compatible version diff --git a/arch/powerpc/kernel/systbl_chk.c b/arch/powerpc/kernel/systbl_chk.c index 2384129f58930..55323a620cfe2 100644 --- a/arch/powerpc/kernel/systbl_chk.c +++ b/arch/powerpc/kernel/systbl_chk.c @@ -57,4 +57,4 @@ START_TABLE #include -END_TABLE __NR_syscalls +END_TABLE NR_syscalls diff --git a/arch/powerpc/kernel/systbl_chk.sh b/arch/powerpc/kernel/systbl_chk.sh index 19415e7674a50..31b6e7c358ca9 100644 --- a/arch/powerpc/kernel/systbl_chk.sh +++ b/arch/powerpc/kernel/systbl_chk.sh @@ -16,7 +16,7 @@ awk 'BEGIN { num = -1; } # Ignore the beginning of the file /^START_TABLE/ { num = 0; next; } /^END_TABLE/ { if (num != $2) { - printf "__NR_syscalls (%s) is not one more than the last syscall (%s)\n", + printf "NR_syscalls (%s) is not one more than the last syscall (%s)\n", $2, num - 1; exit(1); } diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index b457bfa284360..def1b8b5e6c14 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -671,7 +671,7 @@ static void __init vdso_setup_syscall_map(void) extern unsigned long sys_ni_syscall; - for (i = 0; i < __NR_syscalls; i++) { + for (i = 0; i < NR_syscalls; i++) { #ifdef CONFIG_PPC64 if (sys_call_table[i*2] != sys_ni_syscall) vdso_data->syscall_map_64[i >> 5] |= diff --git a/arch/powerpc/kernel/vdso32/datapage.S b/arch/powerpc/kernel/vdso32/datapage.S index 59cf5f452879b..3745113fcc652 100644 --- a/arch/powerpc/kernel/vdso32/datapage.S +++ b/arch/powerpc/kernel/vdso32/datapage.S @@ -61,7 +61,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map) addi r3,r3,CFG_SYSCALL_MAP32 cmpli cr0,r4,0 beqlr - li r0,__NR_syscalls + li r0,NR_syscalls stw r0,0(r4) crclr cr0*4+so blr diff --git a/arch/powerpc/kernel/vdso64/datapage.S b/arch/powerpc/kernel/vdso64/datapage.S index 2f01c4a0d8a03..184a6ba7f2831 100644 --- a/arch/powerpc/kernel/vdso64/datapage.S +++ b/arch/powerpc/kernel/vdso64/datapage.S @@ -62,7 +62,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map) cmpli cr0,r4,0 crclr cr0*4+so beqlr - li r0,__NR_syscalls + li r0,NR_syscalls stw r0,0(r4) blr .cfi_endproc diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index 4ddf769a64e58..9f79004e6d6f6 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -326,7 +326,7 @@ static int spu_process_callback(struct spu_context *ctx) spu_ret = -ENOSYS; npc += 4; - if (s.nr_ret < __NR_syscalls) { + if (s.nr_ret < NR_syscalls) { spu_release(ctx); /* do actual system call from here */ spu_ret = spu_sys_callback(&s); -- GitLab From 343c3327c12b13655192983007de94bd44fd7941 Mon Sep 17 00:00:00 2001 From: Rashmica Gupta Date: Sat, 21 Nov 2015 17:08:16 +1100 Subject: [PATCH 0695/2855] powerpc: Add rN aliases to the pt_regs_offset table. It is common practice with powerpc to use 'rN' to refer to register 'N'. However when using the pt_regs_offset table we have to use 'gprN'. So add aliases such that both 'rN' and 'gprN' can be used. For example, we can currently do: $ su - $ cd /sys/kernel/debug/tracing $ echo "p:probe/sys_fchownat sys_fchownat %gpr3:s32 +0(%gpr4):string %gpr5:s32 %gpr6:s32 %gpr7:s32" > kprobe_events $ echo 1 > events/probe/sys_fchownat/enable $ touch /tmp/foo $ chown root /tmp/foo $ echo 0 > events/enable $ cat trace chown-2925 [014] d... 76.160657: sys_fchownat: (SyS_fchownat+0x8/0x1a0) arg1=-100 arg2="/tmp/foo" arg3=0 arg4=-1 arg5=0 Instead we'd like to be able to use: $ echo "p:probe/sys_fchownat sys_fchownat %r3:s32 +0(%r4):string %r5:s32 %r6:s32 %r7:s32" > kprobe_events Signed-off-by: Rashmica Gupta Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/ptrace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 737c0d0b53ac4..30a03c03fe734 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -60,6 +60,7 @@ struct pt_regs_offset { #define STR(s) #s /* convert to string */ #define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)} #define GPR_OFFSET_NAME(num) \ + {.name = STR(r##num), .offset = offsetof(struct pt_regs, gpr[num])}, \ {.name = STR(gpr##num), .offset = offsetof(struct pt_regs, gpr[num])} #define REG_OFFSET_END {.name = NULL, .offset = 0} -- GitLab From 6735b2e985b78e0ecb05e8818c22f46b904f3599 Mon Sep 17 00:00:00 2001 From: Luis de Bethencourt Date: Tue, 20 Oct 2015 16:13:53 +0100 Subject: [PATCH 0696/2855] powerpc/rackmeter: Fix module autoload for OF platform driver This platform driver has a OF device ID table but the OF module alias information is not created so module autoloading won't work. Signed-off-by: Luis de Bethencourt Signed-off-by: Michael Ellerman --- drivers/macintosh/rack-meter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index 048901a1111a3..caaec654d7ea0 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c @@ -582,6 +582,7 @@ static struct of_device_id rackmeter_match[] = { { .name = "i2s" }, { } }; +MODULE_DEVICE_TABLE(of, rackmeter_match); static struct macio_driver rackmeter_driver = { .driver = { -- GitLab From b4f8144559e172f792f7fa926e4f342fbdbaf6ee Mon Sep 17 00:00:00 2001 From: Luis de Bethencourt Date: Tue, 20 Oct 2015 16:04:13 +0100 Subject: [PATCH 0697/2855] powerpc/axonram: Fix module autoload for OF platform driver This platform driver has a OF device ID table but the OF module alias information is not created so module autoloading won't work. Signed-off-by: Luis de Bethencourt Signed-off-by: Michael Ellerman --- arch/powerpc/sysdev/axonram.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index 7a399b4d60a03..c713b349d9679 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c @@ -313,6 +313,7 @@ static const struct of_device_id axon_ram_device_id[] = { }, {} }; +MODULE_DEVICE_TABLE(of, axon_ram_device_id); static struct platform_driver axon_ram_driver = { .probe = axon_ram_probe, -- GitLab From 25a84db15b3f3a24d3ea7d2baf90693bcff34b0c Mon Sep 17 00:00:00 2001 From: Allen Hung Date: Fri, 20 Nov 2015 18:21:06 +0800 Subject: [PATCH 0698/2855] HID: multitouch: enable palm rejection if device implements confidence usage The usage Confidence is mandary to Windows Precision Touchpad devices. The appearance of this usage is checked in hidinput_connect but the quirk MT_QUIRK_VALID_IS_CONFIDENCE is not applied to device accordingly. Apply this quirk and also remove quirk MT_QUIRK_ALWAYS_VALID to enable palm rejection for the WIN 8 touchpad devices which have implemented usage Confidence in its input reports. Tested on Dell XPS 13 laptop. Signed-off-by: Allen Hung Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 3d664d01305e5..351ddd297792c 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -486,6 +486,11 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, mt_store_field(usage, td, hi); return 1; case HID_DG_CONFIDENCE: + if (cls->name == MT_CLS_WIN_8 && + field->application == HID_DG_TOUCHPAD) { + cls->quirks &= ~MT_QUIRK_ALWAYS_VALID; + cls->quirks |= MT_QUIRK_VALID_IS_CONFIDENCE; + } mt_store_field(usage, td, hi); return 1; case HID_DG_TIPSWITCH: -- GitLab From 92529623d242cea4440958d7bcebdf291f4ab15e Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 24 Nov 2015 13:33:47 +0100 Subject: [PATCH 0699/2855] HID: debug: improve hid_debug_event() The code in hid_debug_event() causes horrible code generation. First, we do a strlen() call for every byte we copy (we're doing a store to global memory, so gcc has no way of proving that strlen(buf) doesn't change). Second, since both i, list->tail and HID_DEBUG_BUFSIZE have signed type, the modulo computation has to take into account the possibility that list->tail+i is negative, so it's not just a simple and. Fix the former by simply not doing strlen() at all (we have to load buf[i] anyway, so testing it is almost free) and the latter by changing i to unsigned. This cuts 29% (69 bytes) of the size of the function. Signed-off-by: Rasmus Villemoes Signed-off-by: Jiri Kosina --- drivers/hid/hid-debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index 2886b645ced73..acfb522a432ae 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -659,13 +659,13 @@ EXPORT_SYMBOL_GPL(hid_dump_device); /* enqueue string to 'events' ring buffer */ void hid_debug_event(struct hid_device *hdev, char *buf) { - int i; + unsigned i; struct hid_debug_list *list; unsigned long flags; spin_lock_irqsave(&hdev->debug_list_lock, flags); list_for_each_entry(list, &hdev->debug_list, node) { - for (i = 0; i < strlen(buf); i++) + for (i = 0; buf[i]; i++) list->hid_debug_buf[(list->tail + i) % HID_DEBUG_BUFSIZE] = buf[i]; list->tail = (list->tail + i) % HID_DEBUG_BUFSIZE; -- GitLab From 5f01e6bc3336c27b9553494214f05ac439dbeb37 Mon Sep 17 00:00:00 2001 From: Saurabh Sengar Date: Wed, 25 Nov 2015 23:31:11 +0530 Subject: [PATCH 0700/2855] extcon: rt8973: Add IRQF_ONESHOT to interrupt flags This patch adds IRQF_ONESHOT if no primary handler is provided for request threaded irq. Signed-off-by: Saurabh Sengar Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-rt8973a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/extcon/extcon-rt8973a.c b/drivers/extcon/extcon-rt8973a.c index 36bf1d63791c6..e1bb82809bef5 100644 --- a/drivers/extcon/extcon-rt8973a.c +++ b/drivers/extcon/extcon-rt8973a.c @@ -603,7 +603,7 @@ static int rt8973a_muic_i2c_probe(struct i2c_client *i2c, ret = devm_request_threaded_irq(info->dev, virq, NULL, rt8973a_muic_irq_handler, - IRQF_NO_SUSPEND, + IRQF_NO_SUSPEND | IRQF_ONESHOT, muic_irq->name, info); if (ret) { dev_err(info->dev, -- GitLab From 4c5b03b60762bbe6b129b648e845f7faa5933f61 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 9 Oct 2015 13:36:40 +0200 Subject: [PATCH 0701/2855] s390/zcore: remove invalid kfree in init_cpu_info The extended save area for the boot CPU has been allocated by smp_save_dump_cpus() with memblock_alloc() and may not be freed with kfree(). Signed-off-by: Martin Schwidefsky --- drivers/s390/char/zcore.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 823f41fc4bbd6..c839a1593b8fe 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -160,7 +160,6 @@ static int __init init_cpu_info(enum arch_id arch) if (memcpy_hsa_kernel(&sa_ext->sa, sys_info.sa_base, sys_info.sa_size) < 0) { TRACE("could not copy from HSA\n"); - kfree(sa_ext); return -EIO; } if (MACHINE_HAS_VX) -- GitLab From bbfed511c262db4d046a35f0389d98645124814f Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 15 Oct 2015 11:14:19 +0200 Subject: [PATCH 0702/2855] s390/zcore: copy vector registers into the image data The /sys/kernel/debug/zcore/mem interface delivers the memory of the old system with the CPU registers stored to the assigned locations in each prefix page. For the vector registers the prefix page of each CPU has an address of a 1024 byte save area at 0x11b0. But the /sys/kernel/debug/zcore/mem interface fails copy the vector registers saved at boot of the zfcpdump kernel into the dump image. Copy the saved vector registers of a CPU to the outout buffer if the memory area that is read via /sys/kernel/debug/zcore/mem intersects with the vector register save area of this CPU. Acked-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/lowcore.h | 1 + drivers/s390/char/zcore.c | 70 +++++++++++++++++++++++++-------- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index afe1cfebf1a4a..bc618067e725b 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h @@ -35,6 +35,7 @@ struct save_area { struct save_area_ext { struct save_area sa; __vector128 vx_regs[32]; + u64 vx_sa_addr; }; struct _lowcore { diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index c839a1593b8fe..e0c87a83eb34b 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "sclp.h" @@ -151,6 +152,9 @@ static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) static int __init init_cpu_info(enum arch_id arch) { struct save_area_ext *sa_ext; + struct _lowcore *lc; + void *ptr; + int i; /* get info for boot cpu from lowcore, stored in the HSA */ @@ -162,8 +166,18 @@ static int __init init_cpu_info(enum arch_id arch) TRACE("could not copy from HSA\n"); return -EIO; } - if (MACHINE_HAS_VX) - save_vx_regs_safe(sa_ext->vx_regs); + if (!MACHINE_HAS_VX) + return 0; + + save_vx_regs_safe(sa_ext->vx_regs); + /* Get address of the vector register save area for each CPU */ + for (i = 0; i < dump_save_areas.count; i++) { + sa_ext = dump_save_areas.areas[i]; + lc = (struct _lowcore *)(unsigned long) sa_ext->sa.pref_reg; + ptr = &lc->vector_save_area_addr; + copy_from_oldmem(&sa_ext->vx_sa_addr, ptr, + sizeof(sa_ext->vx_sa_addr)); + } return 0; } @@ -245,6 +259,8 @@ static int copy_lc(void __user *buf, void *sa, int sa_off, int len) */ static int zcore_add_lc(char __user *buf, unsigned long start, size_t count) { + struct save_area_ext *sa_ext; + struct save_area *sa; unsigned long end; int i; @@ -255,26 +271,48 @@ static int zcore_add_lc(char __user *buf, unsigned long start, size_t count) for (i = 0; i < dump_save_areas.count; i++) { unsigned long cp_start, cp_end; /* copy range */ unsigned long sa_start, sa_end; /* save area range */ - unsigned long prefix; unsigned long sa_off, len, buf_off; - struct save_area *save_area = &dump_save_areas.areas[i]->sa; - prefix = save_area->pref_reg; - sa_start = prefix + sys_info.sa_base; - sa_end = prefix + sys_info.sa_base + sys_info.sa_size; + sa_ext = dump_save_areas.areas[i]; + sa = &sa_ext->sa; + + /* Copy the 512 bytes lowcore save area 0x1200 - 0x1400 */ + sa_start = sa->pref_reg + sys_info.sa_base; + sa_end = sa_start + sys_info.sa_size; + + if (end >= sa_start && start < sa_end) { + cp_start = max(start, sa_start); + cp_end = min(end, sa_end); + buf_off = cp_start - start; + sa_off = cp_start - sa_start; + len = cp_end - cp_start; - if ((end < sa_start) || (start > sa_end)) + TRACE("copy_lc: %lx-%lx\n", cp_start, cp_end); + if (copy_lc(buf + buf_off, sa, sa_off, len)) + return -EFAULT; + } + + if (!MACHINE_HAS_VX) continue; - cp_start = max(start, sa_start); - cp_end = min(end, sa_end); - buf_off = cp_start - start; - sa_off = cp_start - sa_start; - len = cp_end - cp_start; + /* Copy the 512 bytes vector save area */ + sa_start = sa_ext->vx_sa_addr & -1024UL; + sa_end = sa_start + 512; - TRACE("copy_lc for: %lx\n", start); - if (copy_lc(buf + buf_off, save_area, sa_off, len)) - return -EFAULT; + if (end >= sa_start && start < sa_end) { + cp_start = max(start, sa_start); + cp_end = min(end, sa_end); + + buf_off = cp_start - start; + sa_off = cp_start - sa_start; + len = cp_end - cp_start; + + TRACE("copy vxrs: %lx-%lx\n", cp_start, cp_end); + if (copy_to_user(buf + buf_off, + (void *) &sa_ext->vx_regs + sa_off, + len)) + return -EFAULT; + } } return 0; } -- GitLab From ffa52d02c50ea31420dc70869c0b6b439e7cb5ef Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Wed, 28 Oct 2015 09:47:58 +0100 Subject: [PATCH 0703/2855] s390/zcore: remove /sys/kernel/debug/zcore/mem New versions of the SCSI dumper use the /dev/vmcore interface instead of zcore mem. Remove the outdated interface. Acked-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- Documentation/s390/zfcpdump.txt | 22 +- arch/s390/include/asm/lowcore.h | 1 - drivers/s390/char/Makefile | 4 +- drivers/s390/char/zcore.c | 394 +------------------------------- 4 files changed, 18 insertions(+), 403 deletions(-) diff --git a/Documentation/s390/zfcpdump.txt b/Documentation/s390/zfcpdump.txt index dc929be960161..b064aa59714db 100644 --- a/Documentation/s390/zfcpdump.txt +++ b/Documentation/s390/zfcpdump.txt @@ -15,19 +15,15 @@ the s390-tools package) to make the device bootable. The operator of a Linux system can then trigger a SCSI dump by booting the SCSI disk, where zfcpdump resides on. -The kernel part of zfcpdump is implemented as a debugfs file under "zcore/mem", -which exports memory and registers of the crashed Linux in an s390 -standalone dump format. It can be used in the same way as e.g. /dev/mem. The -dump format defines a 4K header followed by plain uncompressed memory. The -register sets are stored in the prefix pages of the respective CPUs. To build a -dump enabled kernel with the zcore driver, the kernel config option -CONFIG_CRASH_DUMP has to be set. When reading from "zcore/mem", the part of -memory, which has been saved by hardware is read by the driver via the SCLP -hardware interface. The second part is just copied from the non overwritten real -memory. - -Since kernel version 3.12 also the /proc/vmcore file can also be used to access -the dump. +The user space dump tool accesses the memory of the crashed system by means +of the /proc/vmcore interface. This interface exports the crashed system's +memory and registers in ELF core dump format. To access the memory which has +been saved by the hardware SCLP requests will be created at the time the data +is needed by /proc/vmcore. The tail part of the crashed systems memory which +has not been stashed by hardware can just be copied from real memory. + +To build a dump enabled kernel the kernel config option CONFIG_CRASH_DUMP +has to be set. To get a valid zfcpdump kernel configuration use "make zfcpdump_defconfig". diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index bc618067e725b..afe1cfebf1a4a 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h @@ -35,7 +35,6 @@ struct save_area { struct save_area_ext { struct save_area sa; __vector128 vx_regs[32]; - u64 vx_sa_addr; }; struct _lowcore { diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile index 6fa9364d1c079..8a2632ba88dc3 100644 --- a/drivers/s390/char/Makefile +++ b/drivers/s390/char/Makefile @@ -30,9 +30,7 @@ obj-$(CONFIG_S390_TAPE_3590) += tape_3590.o obj-$(CONFIG_MONREADER) += monreader.o obj-$(CONFIG_MONWRITER) += monwriter.o obj-$(CONFIG_S390_VMUR) += vmur.o - -zcore_mod-objs := sclp_sdias.o zcore.o -obj-$(CONFIG_CRASH_DUMP) += zcore_mod.o +obj-$(CONFIG_CRASH_DUMP) += sclp_sdias.o zcore.o hmcdrv-objs := hmcdrv_mod.o hmcdrv_dev.o hmcdrv_ftp.o hmcdrv_cache.o diag_ftp.o sclp_ftp.o obj-$(CONFIG_HMC_DRV) += hmcdrv.o diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index e0c87a83eb34b..3ad3d538e4327 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -43,27 +43,14 @@ enum arch_id { ARCH_S390X = 1, }; -/* dump system info */ - -struct sys_info { - enum arch_id arch; - unsigned long sa_base; - u32 sa_size; - int cpu_map[NR_CPUS]; - unsigned long mem_size; - struct save_area lc_mask; -}; - struct ipib_info { unsigned long ipib; u32 checksum; } __attribute__((packed)); -static struct sys_info sys_info; static struct debug_info *zcore_dbf; static int hsa_available; static struct dentry *zcore_dir; -static struct dentry *zcore_file; static struct dentry *zcore_memmap_file; static struct dentry *zcore_reipl_file; static struct dentry *zcore_hsa_file; @@ -149,171 +136,22 @@ static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) return memcpy_hsa(dest, src, count, TO_KERNEL); } -static int __init init_cpu_info(enum arch_id arch) +static int __init init_cpu_info(void) { struct save_area_ext *sa_ext; - struct _lowcore *lc; - void *ptr; - int i; /* get info for boot cpu from lowcore, stored in the HSA */ sa_ext = dump_save_areas.areas[0]; if (!sa_ext) return -ENOMEM; - if (memcpy_hsa_kernel(&sa_ext->sa, sys_info.sa_base, - sys_info.sa_size) < 0) { + if (memcpy_hsa_kernel(&sa_ext->sa, SAVE_AREA_BASE, + sizeof(struct save_area)) < 0) { TRACE("could not copy from HSA\n"); return -EIO; } - if (!MACHINE_HAS_VX) - return 0; - - save_vx_regs_safe(sa_ext->vx_regs); - /* Get address of the vector register save area for each CPU */ - for (i = 0; i < dump_save_areas.count; i++) { - sa_ext = dump_save_areas.areas[i]; - lc = (struct _lowcore *)(unsigned long) sa_ext->sa.pref_reg; - ptr = &lc->vector_save_area_addr; - copy_from_oldmem(&sa_ext->vx_sa_addr, ptr, - sizeof(sa_ext->vx_sa_addr)); - } - return 0; -} - -static DEFINE_MUTEX(zcore_mutex); - -#define DUMP_VERSION 0x5 -#define DUMP_MAGIC 0xa8190173618f23fdULL -#define DUMP_ARCH_S390X 2 -#define DUMP_ARCH_S390 1 -#define HEADER_SIZE 4096 - -/* dump header dumped according to s390 crash dump format */ - -struct zcore_header { - u64 magic; - u32 version; - u32 header_size; - u32 dump_level; - u32 page_size; - u64 mem_size; - u64 mem_start; - u64 mem_end; - u32 num_pages; - u32 pad1; - u64 tod; - struct cpuid cpu_id; - u32 arch_id; - u32 volnr; - u32 build_arch; - u64 rmem_size; - u8 mvdump; - u16 cpu_cnt; - u16 real_cpu_cnt; - u8 end_pad1[0x200-0x061]; - u64 mvdump_sign; - u64 mvdump_zipl_time; - u8 end_pad2[0x800-0x210]; - u32 lc_vec[512]; -} __attribute__((packed,__aligned__(16))); - -static struct zcore_header zcore_header = { - .magic = DUMP_MAGIC, - .version = DUMP_VERSION, - .header_size = 4096, - .dump_level = 0, - .page_size = PAGE_SIZE, - .mem_start = 0, - .build_arch = DUMP_ARCH_S390X, -}; - -/* - * Copy lowcore info to buffer. Use map in order to copy only register parts. - * - * @buf: User buffer - * @sa: Pointer to save area - * @sa_off: Offset in save area to copy - * @len: Number of bytes to copy - */ -static int copy_lc(void __user *buf, void *sa, int sa_off, int len) -{ - int i; - char *lc_mask = (char*)&sys_info.lc_mask; - - for (i = 0; i < len; i++) { - if (!lc_mask[i + sa_off]) - continue; - if (copy_to_user(buf + i, sa + sa_off + i, 1)) - return -EFAULT; - } - return 0; -} - -/* - * Copy lowcores info to memory, if necessary - * - * @buf: User buffer - * @addr: Start address of buffer in dump memory - * @count: Size of buffer - */ -static int zcore_add_lc(char __user *buf, unsigned long start, size_t count) -{ - struct save_area_ext *sa_ext; - struct save_area *sa; - unsigned long end; - int i; - - if (count == 0) - return 0; - - end = start + count; - for (i = 0; i < dump_save_areas.count; i++) { - unsigned long cp_start, cp_end; /* copy range */ - unsigned long sa_start, sa_end; /* save area range */ - unsigned long sa_off, len, buf_off; - - sa_ext = dump_save_areas.areas[i]; - sa = &sa_ext->sa; - - /* Copy the 512 bytes lowcore save area 0x1200 - 0x1400 */ - sa_start = sa->pref_reg + sys_info.sa_base; - sa_end = sa_start + sys_info.sa_size; - - if (end >= sa_start && start < sa_end) { - cp_start = max(start, sa_start); - cp_end = min(end, sa_end); - buf_off = cp_start - start; - sa_off = cp_start - sa_start; - len = cp_end - cp_start; - - TRACE("copy_lc: %lx-%lx\n", cp_start, cp_end); - if (copy_lc(buf + buf_off, sa, sa_off, len)) - return -EFAULT; - } - - if (!MACHINE_HAS_VX) - continue; - - /* Copy the 512 bytes vector save area */ - sa_start = sa_ext->vx_sa_addr & -1024UL; - sa_end = sa_start + 512; - - if (end >= sa_start && start < sa_end) { - cp_start = max(start, sa_start); - cp_end = min(end, sa_end); - - buf_off = cp_start - start; - sa_off = cp_start - sa_start; - len = cp_end - cp_start; - - TRACE("copy vxrs: %lx-%lx\n", cp_start, cp_end); - if (copy_to_user(buf + buf_off, - (void *) &sa_ext->vx_regs + sa_off, - len)) - return -EFAULT; - } - } + if (MACHINE_HAS_VX) + save_vx_regs_safe(sa_ext->vx_regs); return 0; } @@ -326,126 +164,6 @@ static void release_hsa(void) hsa_available = 0; } -/* - * Read routine for zcore character device - * First 4K are dump header - * Next 32MB are HSA Memory - * Rest is read from absolute Memory - */ -static ssize_t zcore_read(struct file *file, char __user *buf, size_t count, - loff_t *ppos) -{ - unsigned long mem_start; /* Start address in memory */ - size_t mem_offs; /* Offset in dump memory */ - size_t hdr_count; /* Size of header part of output buffer */ - size_t size; - int rc; - - mutex_lock(&zcore_mutex); - - if (*ppos > (sys_info.mem_size + HEADER_SIZE)) { - rc = -EINVAL; - goto fail; - } - - count = min(count, (size_t) (sys_info.mem_size + HEADER_SIZE - *ppos)); - - /* Copy dump header */ - if (*ppos < HEADER_SIZE) { - size = min(count, (size_t) (HEADER_SIZE - *ppos)); - if (copy_to_user(buf, &zcore_header + *ppos, size)) { - rc = -EFAULT; - goto fail; - } - hdr_count = size; - mem_start = 0; - } else { - hdr_count = 0; - mem_start = *ppos - HEADER_SIZE; - } - - mem_offs = 0; - - /* Copy from HSA data */ - if (*ppos < sclp.hsa_size + HEADER_SIZE) { - size = min((count - hdr_count), - (size_t) (sclp.hsa_size - mem_start)); - rc = memcpy_hsa_user(buf + hdr_count, mem_start, size); - if (rc) - goto fail; - - mem_offs += size; - } - - /* Copy from real mem */ - size = count - mem_offs - hdr_count; - rc = copy_to_user_real(buf + hdr_count + mem_offs, - (void *) mem_start + mem_offs, size); - if (rc) - goto fail; - - /* - * Since s390 dump analysis tools like lcrash or crash - * expect register sets in the prefix pages of the cpus, - * we copy them into the read buffer, if necessary. - * buf + hdr_count: Start of memory part of output buffer - * mem_start: Start memory address to copy from - * count - hdr_count: Size of memory area to copy - */ - if (zcore_add_lc(buf + hdr_count, mem_start, count - hdr_count)) { - rc = -EFAULT; - goto fail; - } - *ppos += count; -fail: - mutex_unlock(&zcore_mutex); - return (rc < 0) ? rc : count; -} - -static int zcore_open(struct inode *inode, struct file *filp) -{ - if (!hsa_available) - return -ENODATA; - else - return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; -} - -static int zcore_release(struct inode *inode, struct file *filep) -{ - if (hsa_available) - release_hsa(); - return 0; -} - -static loff_t zcore_lseek(struct file *file, loff_t offset, int orig) -{ - loff_t rc; - - mutex_lock(&zcore_mutex); - switch (orig) { - case 0: - file->f_pos = offset; - rc = file->f_pos; - break; - case 1: - file->f_pos += offset; - rc = file->f_pos; - break; - default: - rc = -EINVAL; - } - mutex_unlock(&zcore_mutex); - return rc; -} - -static const struct file_operations zcore_fops = { - .owner = THIS_MODULE, - .llseek = zcore_lseek, - .read = zcore_read, - .open = zcore_open, - .release = zcore_release, -}; - static ssize_t zcore_memmap_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { @@ -549,50 +267,6 @@ static const struct file_operations zcore_hsa_fops = { .llseek = no_llseek, }; -static void __init set_lc_mask(struct save_area *map) -{ - memset(&map->fp_regs, 0xff, sizeof(map->fp_regs)); - memset(&map->gp_regs, 0xff, sizeof(map->gp_regs)); - memset(&map->psw, 0xff, sizeof(map->psw)); - memset(&map->pref_reg, 0xff, sizeof(map->pref_reg)); - memset(&map->fp_ctrl_reg, 0xff, sizeof(map->fp_ctrl_reg)); - memset(&map->tod_reg, 0xff, sizeof(map->tod_reg)); - memset(&map->timer, 0xff, sizeof(map->timer)); - memset(&map->clk_cmp, 0xff, sizeof(map->clk_cmp)); - memset(&map->acc_regs, 0xff, sizeof(map->acc_regs)); - memset(&map->ctrl_regs, 0xff, sizeof(map->ctrl_regs)); -} - -/* - * Initialize dump globals for a given architecture - */ -static int __init sys_info_init(enum arch_id arch, unsigned long mem_end) -{ - int rc; - - switch (arch) { - case ARCH_S390X: - pr_alert("DETECTED 'S390X (64 bit) OS'\n"); - break; - case ARCH_S390: - pr_alert("DETECTED 'S390 (32 bit) OS'\n"); - break; - default: - pr_alert("0x%x is an unknown architecture.\n",arch); - return -EINVAL; - } - sys_info.sa_base = SAVE_AREA_BASE; - sys_info.sa_size = sizeof(struct save_area); - sys_info.arch = arch; - set_lc_mask(&sys_info.lc_mask); - rc = init_cpu_info(arch); - if (rc) - return rc; - sys_info.mem_size = mem_end; - - return 0; -} - static int __init check_sdias(void) { if (!sclp.hsa_size) { @@ -602,43 +276,6 @@ static int __init check_sdias(void) return 0; } -static int __init get_mem_info(unsigned long *mem, unsigned long *end) -{ - struct memblock_region *reg; - - for_each_memblock(memory, reg) { - *mem += reg->size; - *end = max_t(unsigned long, *end, reg->base + reg->size); - } - return 0; -} - -static void __init zcore_header_init(int arch, struct zcore_header *hdr, - unsigned long mem_size) -{ - u32 prefix; - int i; - - if (arch == ARCH_S390X) - hdr->arch_id = DUMP_ARCH_S390X; - else - hdr->arch_id = DUMP_ARCH_S390; - hdr->mem_size = mem_size; - hdr->rmem_size = mem_size; - hdr->mem_end = sys_info.mem_size; - hdr->num_pages = mem_size / PAGE_SIZE; - hdr->tod = get_tod_clock(); - get_cpu_id(&hdr->cpu_id); - for (i = 0; i < dump_save_areas.count; i++) { - prefix = dump_save_areas.areas[i]->sa.pref_reg; - hdr->real_cpu_cnt++; - if (!prefix) - continue; - hdr->lc_vec[hdr->cpu_cnt] = prefix; - hdr->cpu_cnt++; - } -} - /* * Provide IPL parameter information block from either HSA or memory * for future reipl @@ -671,11 +308,9 @@ static int __init zcore_reipl_init(void) static int __init zcore_init(void) { - unsigned long mem_size, mem_end; unsigned char arch; int rc; - mem_size = mem_end = 0; if (ipl_info.type != IPL_TYPE_FCP_DUMP) return -ENODATA; if (OLDMEM_BASE) @@ -709,15 +344,11 @@ static int __init zcore_init(void) goto fail; } - rc = get_mem_info(&mem_size, &mem_end); + pr_alert("DETECTED 'S390X (64 bit) OS'\n"); + rc = init_cpu_info(); if (rc) goto fail; - rc = sys_info_init(arch, mem_end); - if (rc) - goto fail; - zcore_header_init(arch, &zcore_header, mem_size); - rc = zcore_reipl_init(); if (rc) goto fail; @@ -727,17 +358,11 @@ static int __init zcore_init(void) rc = -ENOMEM; goto fail; } - zcore_file = debugfs_create_file("mem", S_IRUSR, zcore_dir, NULL, - &zcore_fops); - if (!zcore_file) { - rc = -ENOMEM; - goto fail_dir; - } zcore_memmap_file = debugfs_create_file("memmap", S_IRUSR, zcore_dir, NULL, &zcore_memmap_fops); if (!zcore_memmap_file) { rc = -ENOMEM; - goto fail_file; + goto fail_dir; } zcore_reipl_file = debugfs_create_file("reipl", S_IRUSR, zcore_dir, NULL, &zcore_reipl_fops); @@ -757,8 +382,6 @@ fail_reipl_file: debugfs_remove(zcore_reipl_file); fail_memmap_file: debugfs_remove(zcore_memmap_file); -fail_file: - debugfs_remove(zcore_file); fail_dir: debugfs_remove(zcore_dir); fail: @@ -774,7 +397,6 @@ static void __exit zcore_exit(void) debugfs_remove(zcore_hsa_file); debugfs_remove(zcore_reipl_file); debugfs_remove(zcore_memmap_file); - debugfs_remove(zcore_file); debugfs_remove(zcore_dir); diag308(DIAG308_REL_HSA, NULL); } -- GitLab From 8a07dd02d7615d91d65d6235f7232e3f9b5d347f Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Wed, 14 Oct 2015 15:53:06 +0200 Subject: [PATCH 0704/2855] s390/kdump: remove code to create ELF notes in the crashed system The s390 architecture can store the CPU registers of the crashed system after the kdump kernel has been started and this is the preferred way. Remove the remaining code fragments that deal with storing CPU registers while the crashed system is still active. Acked-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/elf.h | 2 -- arch/s390/kernel/crash_dump.c | 24 +++--------------- arch/s390/kernel/machine_kexec.c | 42 ++++++++++++++------------------ arch/s390/kernel/setup.c | 15 ++++-------- arch/s390/kernel/smp.c | 8 ++---- 5 files changed, 28 insertions(+), 63 deletions(-) diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index bab6739a1154e..7730e5b9e7e23 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h @@ -229,6 +229,4 @@ struct linux_binprm; #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 int arch_setup_additional_pages(struct linux_binprm *, int); -void *fill_cpu_elf_notes(void *ptr, struct save_area *sa, __vector128 *vxrs); - #endif diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index 171e09bb8ea2a..07d75b969f591 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -72,11 +72,6 @@ static int copy_from_realmem(void *dest, void *src, size_t count) return 0; } -/* - * Pointer to ELF header in new kernel - */ -static void *elfcorehdr_newmem; - /* * Copy one page from zfcpdump "oldmem" * @@ -390,7 +385,8 @@ static void *nt_s390_vx_low(void *ptr, __vector128 *vx_regs) /* * Fill ELF notes for one CPU with save area registers */ -void *fill_cpu_elf_notes(void *ptr, struct save_area *sa, __vector128 *vx_regs) +static void *fill_cpu_elf_notes(void *ptr, struct save_area *sa, + __vector128 *vx_regs) { ptr = nt_prstatus(ptr, sa); ptr = nt_fpregset(ptr, sa); @@ -573,9 +569,6 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size) /* If we are not in kdump or zfcpdump mode return */ if (!OLDMEM_BASE && ipl_info.type != IPL_TYPE_FCP_DUMP) return 0; - /* If elfcorehdr= has been passed via cmdline, we use that one */ - if (elfcorehdr_addr != ELFCORE_ADDR_MAX) - return 0; /* If we cannot get HSA size for zfcpdump return error */ if (ipl_info.type == IPL_TYPE_FCP_DUMP && !sclp.hsa_size) return -ENODEV; @@ -606,7 +599,6 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size) hdr_off = PTR_DIFF(ptr, hdr); loads_init(phdr_loads, hdr_off); *addr = (unsigned long long) hdr; - elfcorehdr_newmem = hdr; *size = (unsigned long long) hdr_off; BUG_ON(elfcorehdr_size > alloc_size); return 0; @@ -617,8 +609,6 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size) */ void elfcorehdr_free(unsigned long long addr) { - if (!elfcorehdr_newmem) - return; kfree((void *)(unsigned long)addr); } @@ -629,7 +619,6 @@ ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos) { void *src = (void *)(unsigned long)*ppos; - src = elfcorehdr_newmem ? src : src - OLDMEM_BASE; memcpy(buf, src, count); *ppos += count; return count; @@ -641,15 +630,8 @@ ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos) ssize_t elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos) { void *src = (void *)(unsigned long)*ppos; - int rc; - if (elfcorehdr_newmem) { - memcpy(buf, src, count); - } else { - rc = copy_from_oldmem(buf, src, count); - if (rc) - return rc; - } + memcpy(buf, src, count); *ppos += count; return count; } diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index fb0901ec4306b..991b16819b974 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c @@ -34,44 +34,38 @@ extern const unsigned long long relocate_kernel_len; #ifdef CONFIG_CRASH_DUMP -/* - * Create ELF notes for one CPU - */ -static void add_elf_notes(int cpu) -{ - struct save_area *sa = (void *) 4608 + store_prefix(); - void *ptr; - - memcpy((void *) (4608UL + sa->pref_reg), sa, sizeof(*sa)); - ptr = (u64 *) per_cpu_ptr(crash_notes, cpu); - ptr = fill_cpu_elf_notes(ptr, sa, NULL); - memset(ptr, 0, sizeof(struct elf_note)); -} - /* * Initialize CPU ELF notes */ static void setup_regs(void) { - unsigned long sa = S390_lowcore.prefixreg_save_area + SAVE_AREA_BASE; - struct _lowcore *lc; + struct save_area *sa, *sa_0; + unsigned long prefix; int cpu, this_cpu; - /* Get lowcore pointer from store status of this CPU (absolute zero) */ - lc = (struct _lowcore *)(unsigned long)S390_lowcore.prefixreg_save_area; + /* setup_regs is called with the prefix register = 0 */ + sa_0 = (struct save_area *) SAVE_AREA_BASE; + + /* Get status of this CPU out of absolute zero */ + prefix = (unsigned long) S390_lowcore.prefixreg_save_area; + sa = (struct save_area *)(prefix + SAVE_AREA_BASE); + memcpy(sa, sa_0, sizeof(struct save_area)); + if (MACHINE_HAS_VX) { + struct _lowcore *lc = (struct _lowcore *) prefix; + save_vx_regs_safe((void *) lc->vector_save_area_addr); + } + + /* Get status of the other CPUs */ this_cpu = smp_find_processor_id(stap()); - add_elf_notes(this_cpu); for_each_online_cpu(cpu) { if (cpu == this_cpu) continue; if (smp_store_status(cpu)) continue; - add_elf_notes(cpu); + prefix = (unsigned long) S390_lowcore.prefixreg_save_area; + sa = (struct save_area *)(prefix + SAVE_AREA_BASE); + memcpy(sa, sa_0, sizeof(struct save_area)); } - if (MACHINE_HAS_VX) - save_vx_regs_safe((void *) lc->vector_save_area_addr); - /* Copy dump CPU store status info to absolute zero */ - memcpy((void *) SAVE_AREA_BASE, (void *) sa, sizeof(struct save_area)); } /* diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index c837bcacf2188..8f5107d6ebb37 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -661,15 +661,6 @@ static void __init reserve_kernel(void) #endif } -static void __init reserve_elfcorehdr(void) -{ -#ifdef CONFIG_CRASH_DUMP - if (is_kdump_kernel()) - memblock_reserve(elfcorehdr_addr - OLDMEM_BASE, - PAGE_ALIGN(elfcorehdr_size)); -#endif -} - static void __init setup_memory(void) { struct memblock_region *reg; @@ -841,6 +832,11 @@ void __init setup_arch(char **cmdline_p) init_mm.brk = (unsigned long) &_end; parse_early_param(); +#ifdef CONFIG_CRASH_DUMP + /* Deactivate elfcorehdr= kernel parameter */ + elfcorehdr_addr = ELFCORE_ADDR_MAX; +#endif + os_info_init(); setup_ipl(); @@ -849,7 +845,6 @@ void __init setup_arch(char **cmdline_p) reserve_oldmem(); reserve_kernel(); reserve_initrd(); - reserve_elfcorehdr(); memblock_allow_resize(); /* Get information about *all* installed memory */ diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 9062df575afe1..7ad070e984f27 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -608,9 +608,8 @@ int smp_store_status(int cpu) * stored the registers of the boot CPU in the memory of the old system. * 4) kdump and the old kernel stored the CPU state * condition: OLDMEM_BASE != NULL && is_kdump_kernel() - * The state of all CPUs is stored in ELF sections in the memory of the - * old system. The ELF sections are picked up by the crash_dump code - * via elfcorehdr_addr. + * This case does not exist for s390 anymore, setup_arch explicitly + * deactivates the elfcorehdr= kernel parameter */ void __init smp_save_dump_cpus(void) { @@ -619,9 +618,6 @@ void __init smp_save_dump_cpus(void) struct save_area_ext *sa_ext; bool is_boot_cpu; - if (is_kdump_kernel()) - /* Previous system stored the CPU states. Nothing to do. */ - return; if (!(OLDMEM_BASE || ipl_info.type == IPL_TYPE_FCP_DUMP)) /* No previous system present, normal boot. */ return; -- GitLab From df9694c7975ff9976368eb381388c61f65352aef Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 12 Oct 2015 10:43:37 +0200 Subject: [PATCH 0705/2855] s390/dump: streamline oldmem copy functions Introduce two copy functions for the memory of the dumped system, copy_oldmem_kernel() to copy to the virtual kernel address space and copy_oldmem_user() to copy to user space. Acked-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/os_info.h | 2 +- arch/s390/include/asm/sclp.h | 3 +- arch/s390/kernel/crash_dump.c | 171 +++++++++++++++----------------- arch/s390/kernel/os_info.c | 7 +- arch/s390/kernel/smp.c | 4 +- drivers/s390/char/zcore.c | 20 +++- 6 files changed, 105 insertions(+), 102 deletions(-) diff --git a/arch/s390/include/asm/os_info.h b/arch/s390/include/asm/os_info.h index 295f2c4f1c96a..943475382d515 100644 --- a/arch/s390/include/asm/os_info.h +++ b/arch/s390/include/asm/os_info.h @@ -38,7 +38,7 @@ u32 os_info_csum(struct os_info *os_info); #ifdef CONFIG_CRASH_DUMP void *os_info_old_entry(int nr, unsigned long *size); -int copy_from_oldmem(void *dest, void *src, size_t count); +int copy_oldmem_kernel(void *dst, void *src, size_t count); #else static inline void *os_info_old_entry(int nr, unsigned long *size) { diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index 821dde5f425d0..2ca9c7bc50db6 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h @@ -77,7 +77,8 @@ int sclp_chp_read_info(struct sclp_chp_info *info); void sclp_get_ipl_info(struct sclp_ipl_info *info); int sclp_pci_configure(u32 fid); int sclp_pci_deconfigure(u32 fid); -int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode); +int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count); +int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count); void sclp_early_detect(void); int _sclp_print_early(const char *); diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index 07d75b969f591..0d59c0705c4fb 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -51,74 +51,85 @@ static inline void *load_real_addr(void *addr) } /* - * Copy real to virtual or real memory + * Copy memory of the old, dumped system to a kernel space virtual address */ -static int copy_from_realmem(void *dest, void *src, size_t count) -{ - unsigned long size; - - if (!count) - return 0; - if (!is_vmalloc_or_module_addr(dest)) - return memcpy_real(dest, src, count); - do { - size = min(count, PAGE_SIZE - (__pa(dest) & ~PAGE_MASK)); - if (memcpy_real(load_real_addr(dest), src, size)) - return -EFAULT; - count -= size; - dest += size; - src += size; - } while (count); - return 0; -} - -/* - * Copy one page from zfcpdump "oldmem" - * - * For pages below HSA size memory from the HSA is copied. Otherwise - * real memory copy is used. - */ -static ssize_t copy_oldmem_page_zfcpdump(char *buf, size_t csize, - unsigned long src, int userbuf) +int copy_oldmem_kernel(void *dst, void *src, size_t count) { + unsigned long from, len; + void *ra; int rc; - if (src < sclp.hsa_size) { - rc = memcpy_hsa(buf, src, csize, userbuf); - } else { - if (userbuf) - rc = copy_to_user_real((void __force __user *) buf, - (void *) src, csize); - else - rc = memcpy_real(buf, (void *) src, csize); + while (count) { + from = __pa(src); + if (!OLDMEM_BASE && from < sclp.hsa_size) { + /* Copy from zfcpdump HSA area */ + len = min(count, sclp.hsa_size - from); + rc = memcpy_hsa_kernel(dst, from, len); + if (rc) + return rc; + } else { + /* Check for swapped kdump oldmem areas */ + if (OLDMEM_BASE && from - OLDMEM_BASE < OLDMEM_SIZE) { + from -= OLDMEM_BASE; + len = min(count, OLDMEM_SIZE - from); + } else if (OLDMEM_BASE && from < OLDMEM_SIZE) { + len = min(count, OLDMEM_SIZE - from); + from += OLDMEM_BASE; + } else { + len = count; + } + if (is_vmalloc_or_module_addr(dst)) { + ra = load_real_addr(dst); + len = min(PAGE_SIZE - offset_in_page(ra), len); + } else { + ra = dst; + } + if (memcpy_real(ra, (void *) from, len)) + return -EFAULT; + } + dst += len; + src += len; + count -= len; } - return rc ? rc : csize; + return 0; } /* - * Copy one page from kdump "oldmem" - * - * For the kdump reserved memory this functions performs a swap operation: - * - [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE] is mapped to [0 - OLDMEM_SIZE]. - * - [0 - OLDMEM_SIZE] is mapped to [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE] + * Copy memory of the old, dumped system to a user space virtual address */ -static ssize_t copy_oldmem_page_kdump(char *buf, size_t csize, - unsigned long src, int userbuf) - +int copy_oldmem_user(void __user *dst, void *src, size_t count) { + unsigned long from, len; int rc; - if (src < OLDMEM_SIZE) - src += OLDMEM_BASE; - else if (src > OLDMEM_BASE && - src < OLDMEM_BASE + OLDMEM_SIZE) - src -= OLDMEM_BASE; - if (userbuf) - rc = copy_to_user_real((void __force __user *) buf, - (void *) src, csize); - else - rc = copy_from_realmem(buf, (void *) src, csize); - return (rc == 0) ? rc : csize; + while (count) { + from = __pa(src); + if (!OLDMEM_BASE && from < sclp.hsa_size) { + /* Copy from zfcpdump HSA area */ + len = min(count, sclp.hsa_size - from); + rc = memcpy_hsa_user(dst, from, len); + if (rc) + return rc; + } else { + /* Check for swapped kdump oldmem areas */ + if (OLDMEM_BASE && from - OLDMEM_BASE < OLDMEM_SIZE) { + from -= OLDMEM_BASE; + len = min(count, OLDMEM_SIZE - from); + } else if (OLDMEM_BASE && from < OLDMEM_SIZE) { + len = min(count, OLDMEM_SIZE - from); + from += OLDMEM_BASE; + } else { + len = count; + } + rc = copy_to_user_real(dst, (void *) from, count); + if (rc) + return rc; + } + dst += len; + src += len; + count -= len; + } + return 0; } /* @@ -127,15 +138,17 @@ static ssize_t copy_oldmem_page_kdump(char *buf, size_t csize, ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize, unsigned long offset, int userbuf) { - unsigned long src; + void *src; + int rc; if (!csize) return 0; - src = (pfn << PAGE_SHIFT) + offset; - if (OLDMEM_BASE) - return copy_oldmem_page_kdump(buf, csize, src, userbuf); + src = (void *) (pfn << PAGE_SHIFT) + offset; + if (userbuf) + rc = copy_oldmem_user((void __force __user *) buf, src, csize); else - return copy_oldmem_page_zfcpdump(buf, csize, src, userbuf); + rc = copy_oldmem_kernel((void *) buf, src, csize); + return rc; } /* @@ -203,33 +216,6 @@ int remap_oldmem_pfn_range(struct vm_area_struct *vma, unsigned long from, prot); } -/* - * Copy memory from old kernel - */ -int copy_from_oldmem(void *dest, void *src, size_t count) -{ - unsigned long copied = 0; - int rc; - - if (OLDMEM_BASE) { - if ((unsigned long) src < OLDMEM_SIZE) { - copied = min(count, OLDMEM_SIZE - (unsigned long) src); - rc = copy_from_realmem(dest, src + OLDMEM_BASE, copied); - if (rc) - return rc; - } - } else { - unsigned long hsa_end = sclp.hsa_size; - if ((unsigned long) src < hsa_end) { - copied = min(count, hsa_end - (unsigned long) src); - rc = memcpy_hsa(dest, (unsigned long) src, copied, 0); - if (rc) - return rc; - } - } - return copy_from_realmem(dest + copied, src + copied, count - copied); -} - /* * Alloc memory and panic in case of ENOMEM */ @@ -425,17 +411,18 @@ static void *get_vmcoreinfo_old(unsigned long *size) Elf64_Nhdr note; void *addr; - if (copy_from_oldmem(&addr, &S390_lowcore.vmcore_info, sizeof(addr))) + if (copy_oldmem_kernel(&addr, &S390_lowcore.vmcore_info, sizeof(addr))) return NULL; memset(nt_name, 0, sizeof(nt_name)); - if (copy_from_oldmem(¬e, addr, sizeof(note))) + if (copy_oldmem_kernel(¬e, addr, sizeof(note))) return NULL; - if (copy_from_oldmem(nt_name, addr + sizeof(note), sizeof(nt_name) - 1)) + if (copy_oldmem_kernel(nt_name, addr + sizeof(note), + sizeof(nt_name) - 1)) return NULL; if (strcmp(nt_name, "VMCOREINFO") != 0) return NULL; vmcoreinfo = kzalloc_panic(note.n_descsz); - if (copy_from_oldmem(vmcoreinfo, addr + 24, note.n_descsz)) + if (copy_oldmem_kernel(vmcoreinfo, addr + 24, note.n_descsz)) return NULL; *size = note.n_descsz; return vmcoreinfo; diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c index d112fc66f993e..87f05e475ae86 100644 --- a/arch/s390/kernel/os_info.c +++ b/arch/s390/kernel/os_info.c @@ -89,7 +89,7 @@ static void os_info_old_alloc(int nr, int align) goto fail; } buf_align = PTR_ALIGN(buf, align); - if (copy_from_oldmem(buf_align, (void *) addr, size)) { + if (copy_oldmem_kernel(buf_align, (void *) addr, size)) { msg = "copy failed"; goto fail_free; } @@ -122,14 +122,15 @@ static void os_info_old_init(void) return; if (!OLDMEM_BASE) goto fail; - if (copy_from_oldmem(&addr, &S390_lowcore.os_info, sizeof(addr))) + if (copy_oldmem_kernel(&addr, &S390_lowcore.os_info, sizeof(addr))) goto fail; if (addr == 0 || addr % PAGE_SIZE) goto fail; os_info_old = kzalloc(sizeof(*os_info_old), GFP_KERNEL); if (!os_info_old) goto fail; - if (copy_from_oldmem(os_info_old, (void *) addr, sizeof(*os_info_old))) + if (copy_oldmem_kernel(os_info_old, (void *) addr, + sizeof(*os_info_old))) goto fail_free; if (os_info_old->magic != OS_INFO_MAGIC) goto fail_free; diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 7ad070e984f27..5e04acdc62904 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -546,8 +546,8 @@ static void __init __smp_store_cpu_state(struct save_area_ext *sa_ext, if (is_boot_cpu) { /* Copy the registers of the boot CPU. */ - copy_oldmem_page(1, (void *) &sa_ext->sa, sizeof(sa_ext->sa), - SAVE_AREA_BASE - PAGE_SIZE, 0); + copy_oldmem_kernel(&sa_ext->sa, (void *) SAVE_AREA_BASE, + sizeof(sa_ext->sa)); if (MACHINE_HAS_VX) save_vx_regs_safe(sa_ext->vx_regs); return; diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 3ad3d538e4327..4fa455787a775 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -64,7 +64,7 @@ static struct ipl_parameter_block *ipl_block; * @count: Size of buffer, which should be copied * @mode: Either TO_KERNEL or TO_USER */ -int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode) +static int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode) { int offs, blk_num; static char buf[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); @@ -126,12 +126,26 @@ out: return 0; } -static int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count) +/* + * Copy memory from HSA to user memory (not reentrant): + * + * @dest: Kernel or user buffer where memory should be copied to + * @src: Start address within HSA where data should be copied + * @count: Size of buffer, which should be copied + */ +int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count) { return memcpy_hsa((void __force *) dest, src, count, TO_USER); } -static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) +/* + * Copy memory from HSA to kernel memory (not reentrant): + * + * @dest: Kernel or user buffer where memory should be copied to + * @src: Start address within HSA where data should be copied + * @count: Size of buffer, which should be copied + */ +int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) { return memcpy_hsa(dest, src, count, TO_KERNEL); } -- GitLab From 019d6bec6d2842729c477f433b2330e9f52c0f1a Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 12 Oct 2015 10:51:54 +0200 Subject: [PATCH 0706/2855] s390/zcore: simplify memcpy_hsa Replace the three part copy logic int memcpy_hsa with a single loop around sclp_sdias_copy with appropriate offset and size calculations, and inline memcpy_hsa into memcpy_hsa_user and memcpy_hsa_kernel. Acked-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- drivers/s390/char/zcore.c | 101 +++++++++++++------------------------- 1 file changed, 33 insertions(+), 68 deletions(-) diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 4fa455787a775..7d94c696c38be 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -34,8 +34,6 @@ #define TRACE(x...) debug_sprintf_event(zcore_dbf, 1, x) -#define TO_USER 1 -#define TO_KERNEL 0 #define CHUNK_INFO_SIZE 34 /* 2 16-byte char, each followed by blank */ enum arch_id { @@ -56,88 +54,38 @@ static struct dentry *zcore_reipl_file; static struct dentry *zcore_hsa_file; static struct ipl_parameter_block *ipl_block; +static char hsa_buf[PAGE_SIZE] __aligned(PAGE_SIZE); + /* - * Copy memory from HSA to kernel or user memory (not reentrant): + * Copy memory from HSA to user memory (not reentrant): * - * @dest: Kernel or user buffer where memory should be copied to + * @dest: User buffer where memory should be copied to * @src: Start address within HSA where data should be copied * @count: Size of buffer, which should be copied - * @mode: Either TO_KERNEL or TO_USER */ -static int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode) +int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count) { - int offs, blk_num; - static char buf[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); + unsigned long offset, bytes; if (!hsa_available) return -ENODATA; - if (count == 0) - return 0; - - /* copy first block */ - offs = 0; - if ((src % PAGE_SIZE) != 0) { - blk_num = src / PAGE_SIZE + 2; - if (sclp_sdias_copy(buf, blk_num, 1)) { - TRACE("sclp_sdias_copy() failed\n"); - return -EIO; - } - offs = min((PAGE_SIZE - (src % PAGE_SIZE)), count); - if (mode == TO_USER) { - if (copy_to_user((__force __user void*) dest, - buf + (src % PAGE_SIZE), offs)) - return -EFAULT; - } else - memcpy(dest, buf + (src % PAGE_SIZE), offs); - } - if (offs == count) - goto out; - /* copy middle */ - for (; (offs + PAGE_SIZE) <= count; offs += PAGE_SIZE) { - blk_num = (src + offs) / PAGE_SIZE + 2; - if (sclp_sdias_copy(buf, blk_num, 1)) { + while (count) { + if (sclp_sdias_copy(hsa_buf, src / PAGE_SIZE + 2, 1)) { TRACE("sclp_sdias_copy() failed\n"); return -EIO; } - if (mode == TO_USER) { - if (copy_to_user((__force __user void*) dest + offs, - buf, PAGE_SIZE)) - return -EFAULT; - } else - memcpy(dest + offs, buf, PAGE_SIZE); - } - if (offs == count) - goto out; - - /* copy last block */ - blk_num = (src + offs) / PAGE_SIZE + 2; - if (sclp_sdias_copy(buf, blk_num, 1)) { - TRACE("sclp_sdias_copy() failed\n"); - return -EIO; - } - if (mode == TO_USER) { - if (copy_to_user((__force __user void*) dest + offs, buf, - count - offs)) + offset = src % PAGE_SIZE; + bytes = min(PAGE_SIZE - offset, count); + if (copy_to_user(dest, hsa_buf + offset, bytes)) return -EFAULT; - } else - memcpy(dest + offs, buf, count - offs); -out: + src += bytes; + dest += bytes; + count -= bytes; + } return 0; } -/* - * Copy memory from HSA to user memory (not reentrant): - * - * @dest: Kernel or user buffer where memory should be copied to - * @src: Start address within HSA where data should be copied - * @count: Size of buffer, which should be copied - */ -int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count) -{ - return memcpy_hsa((void __force *) dest, src, count, TO_USER); -} - /* * Copy memory from HSA to kernel memory (not reentrant): * @@ -147,7 +95,24 @@ int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count) */ int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) { - return memcpy_hsa(dest, src, count, TO_KERNEL); + unsigned long offset, bytes; + + if (!hsa_available) + return -ENODATA; + + while (count) { + if (sclp_sdias_copy(hsa_buf, src / PAGE_SIZE + 2, 1)) { + TRACE("sclp_sdias_copy() failed\n"); + return -EIO; + } + offset = src % PAGE_SIZE; + bytes = min(PAGE_SIZE - offset, count); + memcpy(dest, hsa_buf + offset, bytes); + src += bytes; + dest += bytes; + count -= bytes; + } + return 0; } static int __init init_cpu_info(void) -- GitLab From d9a3a09af54d01ab8b0c320580f4f95328d4a7ac Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 23 Oct 2015 09:02:32 +0200 Subject: [PATCH 0707/2855] s390/kvm: remove dependency on struct save_area definition Replace the offsets based on the struct area_area with the offset constants from asm-offsets.c based on the struct _lowcore. Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/asm-offsets.c | 1 + arch/s390/kvm/kvm-s390.c | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index 9cd248f637c7a..dc6c9c6045430 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -181,6 +181,7 @@ int main(void) OFFSET(__LC_PSW_SAVE_AREA, _lowcore, psw_save_area); OFFSET(__LC_PREFIX_SAVE_AREA, _lowcore, prefixreg_save_area); OFFSET(__LC_FP_CREG_SAVE_AREA, _lowcore, fpt_creg_save_area); + OFFSET(__LC_TOD_PROGREG_SAVE_AREA, _lowcore, tod_progreg_save_area); OFFSET(__LC_CPU_TIMER_SAVE_AREA, _lowcore, cpu_timer_save_area); OFFSET(__LC_CLOCK_COMP_SAVE_AREA, _lowcore, clock_comp_save_area); OFFSET(__LC_AREGS_SAVE_AREA, _lowcore, access_regs_save_area); diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 846589281b046..713a91a0622bd 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -2270,37 +2270,37 @@ int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa) u64 clkcomp; int rc; + px = kvm_s390_get_prefix(vcpu); if (gpa == KVM_S390_STORE_STATUS_NOADDR) { if (write_guest_abs(vcpu, 163, &archmode, 1)) return -EFAULT; - gpa = SAVE_AREA_BASE; + gpa = 0; } else if (gpa == KVM_S390_STORE_STATUS_PREFIXED) { if (write_guest_real(vcpu, 163, &archmode, 1)) return -EFAULT; - gpa = kvm_s390_real_to_abs(vcpu, SAVE_AREA_BASE); - } - rc = write_guest_abs(vcpu, gpa + offsetof(struct save_area, fp_regs), + gpa = px; + } else + gpa -= __LC_FPREGS_SAVE_AREA; + rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA, vcpu->arch.guest_fpregs.fprs, 128); - rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, gp_regs), + rc |= write_guest_abs(vcpu, gpa + __LC_GPREGS_SAVE_AREA, vcpu->run->s.regs.gprs, 128); - rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, psw), + rc |= write_guest_abs(vcpu, gpa + __LC_PSW_SAVE_AREA, &vcpu->arch.sie_block->gpsw, 16); - px = kvm_s390_get_prefix(vcpu); - rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, pref_reg), + rc |= write_guest_abs(vcpu, gpa + __LC_PREFIX_SAVE_AREA, &px, 4); - rc |= write_guest_abs(vcpu, - gpa + offsetof(struct save_area, fp_ctrl_reg), + rc |= write_guest_abs(vcpu, gpa + __LC_FP_CREG_SAVE_AREA, &vcpu->arch.guest_fpregs.fpc, 4); - rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, tod_reg), + rc |= write_guest_abs(vcpu, gpa + __LC_TOD_PROGREG_SAVE_AREA, &vcpu->arch.sie_block->todpr, 4); - rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, timer), + rc |= write_guest_abs(vcpu, gpa + __LC_CPU_TIMER_SAVE_AREA, &vcpu->arch.sie_block->cputm, 8); clkcomp = vcpu->arch.sie_block->ckc >> 8; - rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, clk_cmp), + rc |= write_guest_abs(vcpu, gpa + __LC_CLOCK_COMP_SAVE_AREA, &clkcomp, 8); - rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, acc_regs), + rc |= write_guest_abs(vcpu, gpa + __LC_AREGS_SAVE_AREA, &vcpu->run->s.regs.acrs, 64); - rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, ctrl_regs), + rc |= write_guest_abs(vcpu, gpa + __LC_CREGS_SAVE_AREA, &vcpu->arch.sie_block->gcr, 128); return rc ? -EFAULT : 0; } -- GitLab From f08b8414632c9f256e33f0a18104d8d5e103d204 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 23 Oct 2015 09:05:38 +0200 Subject: [PATCH 0708/2855] s390/dump: remove SAVE_AREA_BASE Replace the SAVE_AREA_BASE offset calculations in reipl.S with the assembler constant for the location of each register status area. Use __LC_FPREGS_SAVE_AREA instead of SAVE_AREA_BASE in the three remaining code locations and remove the definition of SAVE_AREA_BASE. Acked-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/asm-offsets.c | 1 - arch/s390/kernel/machine_kexec.c | 6 +-- arch/s390/kernel/reipl.S | 65 ++++++++++++++++++-------------- arch/s390/kernel/smp.c | 4 +- drivers/s390/char/zcore.c | 2 +- 5 files changed, 42 insertions(+), 36 deletions(-) diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index dc6c9c6045430..ae7b565b6c4c7 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -175,7 +175,6 @@ int main(void) /* hardware defined lowcore locations 0x1000 - 0x18ff */ OFFSET(__LC_VX_SAVE_AREA_ADDR, _lowcore, vector_save_area_addr); OFFSET(__LC_EXT_PARAMS2, _lowcore, ext_params2); - OFFSET(SAVE_AREA_BASE, _lowcore, floating_pt_save_area); OFFSET(__LC_FPREGS_SAVE_AREA, _lowcore, floating_pt_save_area); OFFSET(__LC_GPREGS_SAVE_AREA, _lowcore, gpregs_save_area); OFFSET(__LC_PSW_SAVE_AREA, _lowcore, psw_save_area); diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index 991b16819b974..bf2cd699556f3 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c @@ -44,11 +44,11 @@ static void setup_regs(void) int cpu, this_cpu; /* setup_regs is called with the prefix register = 0 */ - sa_0 = (struct save_area *) SAVE_AREA_BASE; + sa_0 = (struct save_area *) __LC_FPREGS_SAVE_AREA; /* Get status of this CPU out of absolute zero */ prefix = (unsigned long) S390_lowcore.prefixreg_save_area; - sa = (struct save_area *)(prefix + SAVE_AREA_BASE); + sa = (struct save_area *)(prefix + __LC_FPREGS_SAVE_AREA); memcpy(sa, sa_0, sizeof(struct save_area)); if (MACHINE_HAS_VX) { struct _lowcore *lc = (struct _lowcore *) prefix; @@ -63,7 +63,7 @@ static void setup_regs(void) if (smp_store_status(cpu)) continue; prefix = (unsigned long) S390_lowcore.prefixreg_save_area; - sa = (struct save_area *)(prefix + SAVE_AREA_BASE); + sa = (struct save_area *)(prefix + __LC_FPREGS_SAVE_AREA); memcpy(sa, sa_0, sizeof(struct save_area)); } } diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S index 52aab0bd84f89..b75a521e4fabd 100644 --- a/arch/s390/kernel/reipl.S +++ b/arch/s390/kernel/reipl.S @@ -19,49 +19,56 @@ ENTRY(store_status) /* Save register one and load save area base */ stg %r1,__LC_SAVE_AREA_RESTART - lghi %r1,SAVE_AREA_BASE /* General purpose registers */ - stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - lg %r2,__LC_SAVE_AREA_RESTART - stg %r2,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE+8(%r1) + lghi %r1,__LC_GPREGS_SAVE_AREA + stmg %r0,%r15,0(%r1) + mvc 8(8,%r1),__LC_SAVE_AREA_RESTART /* Control registers */ - stctg %c0,%c15,__LC_CREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + lghi %r1,__LC_CREGS_SAVE_AREA + stctg %c0,%c15,0(%r1) /* Access registers */ - stam %a0,%a15,__LC_AREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + lghi %r1,__LC_AREGS_SAVE_AREA + stam %a0,%a15,0(%r1) /* Floating point registers */ - std %f0, 0x00 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f1, 0x08 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f2, 0x10 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f3, 0x18 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f4, 0x20 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f5, 0x28 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f6, 0x30 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f7, 0x38 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f8, 0x40 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f9, 0x48 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f10,0x50 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f11,0x58 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f12,0x60 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f13,0x68 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f14,0x70 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f15,0x78 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + lghi %r1,__LC_FPREGS_SAVE_AREA + std %f0, 0x00(%r1) + std %f1, 0x08(%r1) + std %f2, 0x10(%r1) + std %f3, 0x18(%r1) + std %f4, 0x20(%r1) + std %f5, 0x28(%r1) + std %f6, 0x30(%r1) + std %f7, 0x38(%r1) + std %f8, 0x40(%r1) + std %f9, 0x48(%r1) + std %f10,0x50(%r1) + std %f11,0x58(%r1) + std %f12,0x60(%r1) + std %f13,0x68(%r1) + std %f14,0x70(%r1) + std %f15,0x78(%r1) /* Floating point control register */ - stfpc __LC_FP_CREG_SAVE_AREA-SAVE_AREA_BASE(%r1) + lghi %r1,__LC_FP_CREG_SAVE_AREA + stfpc 0(%r1) /* CPU timer */ - stpt __LC_CPU_TIMER_SAVE_AREA-SAVE_AREA_BASE(%r1) + lghi %r1,__LC_CPU_TIMER_SAVE_AREA + stpt 0(%r1) /* Saved prefix register */ + lghi %r1,__LC_PREFIX_SAVE_AREA larl %r2,dump_prefix_page - mvc __LC_PREFIX_SAVE_AREA-SAVE_AREA_BASE(4,%r1),0(%r2) + mvc 0(4,%r1),0(%r2) /* Clock comparator - seven bytes */ + lghi %r1,__LC_CLOCK_COMP_SAVE_AREA larl %r2,.Lclkcmp stckc 0(%r2) - mvc __LC_CLOCK_COMP_SAVE_AREA-SAVE_AREA_BASE + 1(7,%r1),1(%r2) + mvc 1(7,%r1),1(%r2) /* Program status word */ + lghi %r1,__LC_PSW_SAVE_AREA epsw %r2,%r3 - st %r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 0(%r1) - st %r3,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 4(%r1) + st %r2,0(%r1) + st %r3,4(%r1) larl %r2,store_status - stg %r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 8(%r1) + stg %r2,8(%r1) br %r14 .section .bss diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 5e04acdc62904..d49a8cb404c25 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -546,7 +546,7 @@ static void __init __smp_store_cpu_state(struct save_area_ext *sa_ext, if (is_boot_cpu) { /* Copy the registers of the boot CPU. */ - copy_oldmem_kernel(&sa_ext->sa, (void *) SAVE_AREA_BASE, + copy_oldmem_kernel(&sa_ext->sa, (void *) __LC_FPREGS_SAVE_AREA, sizeof(sa_ext->sa)); if (MACHINE_HAS_VX) save_vx_regs_safe(sa_ext->vx_regs); @@ -554,7 +554,7 @@ static void __init __smp_store_cpu_state(struct save_area_ext *sa_ext, } /* Get the registers of a non-boot cpu. */ __pcpu_sigp_relax(address, SIGP_STOP_AND_STORE_STATUS, 0, NULL); - memcpy_real(&sa_ext->sa, lc + SAVE_AREA_BASE, sizeof(sa_ext->sa)); + memcpy_real(&sa_ext->sa, lc + __LC_FPREGS_SAVE_AREA, sizeof(sa_ext->sa)); if (!MACHINE_HAS_VX) return; /* Get the VX registers */ diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 7d94c696c38be..087da775c359e 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -124,7 +124,7 @@ static int __init init_cpu_info(void) sa_ext = dump_save_areas.areas[0]; if (!sa_ext) return -ENOMEM; - if (memcpy_hsa_kernel(&sa_ext->sa, SAVE_AREA_BASE, + if (memcpy_hsa_kernel(&sa_ext->sa, __LC_FPREGS_SAVE_AREA, sizeof(struct save_area)) < 0) { TRACE("could not copy from HSA\n"); return -EIO; -- GitLab From 1a36a39e225d3558fb3776a3d3d7736cf1ec9f60 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 29 Oct 2015 10:28:26 +0100 Subject: [PATCH 0709/2855] s390/dump: rework CPU register dump code To collect the CPU registers of the crashed system allocated a single page with memblock_alloc_base and use it as a copy buffer. Replace the stop-and-store-status sigp with a store-status-at-address sigp in smp_save_dump_cpus() and smp_store_status(). In both cases the target CPU is already stopped and store-status-at-address avoids the detour via the absolute zero page. For kexec simplify s390_reset_system and call store_status() before the prefix register of the boot CPU has been set to zero. Use STPX to store the prefix register and remove dump_prefix_page. Acked-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/fpu/internal.h | 10 +-- arch/s390/include/asm/ipl.h | 3 +- arch/s390/include/asm/reset.h | 3 +- arch/s390/include/asm/smp.h | 2 +- arch/s390/kernel/early.c | 9 +++ arch/s390/kernel/ipl.c | 17 +--- arch/s390/kernel/machine_kexec.c | 104 +++++++++++++++---------- arch/s390/kernel/reipl.S | 37 ++++----- arch/s390/kernel/setup.c | 2 + arch/s390/kernel/smp.c | 112 +++++++++++++++------------ drivers/s390/char/zcore.c | 2 - drivers/s390/cio/cio.c | 2 +- 12 files changed, 158 insertions(+), 145 deletions(-) diff --git a/arch/s390/include/asm/fpu/internal.h b/arch/s390/include/asm/fpu/internal.h index 2559b16da525e..ea91ddfe54ebb 100644 --- a/arch/s390/include/asm/fpu/internal.h +++ b/arch/s390/include/asm/fpu/internal.h @@ -12,21 +12,13 @@ #include #include -static inline void save_vx_regs_safe(__vector128 *vxrs) +static inline void save_vx_regs(__vector128 *vxrs) { - unsigned long cr0, flags; - - flags = arch_local_irq_save(); - __ctl_store(cr0, 0, 0); - __ctl_set_bit(0, 17); - __ctl_set_bit(0, 18); asm volatile( " la 1,%0\n" " .word 0xe70f,0x1000,0x003e\n" /* vstm 0,15,0(1) */ " .word 0xe70f,0x1100,0x0c3e\n" /* vstm 16,31,256(1) */ : "=Q" (*(struct vx_array *) vxrs) : : "1"); - __ctl_load(cr0, 0, 0); - arch_local_irq_restore(flags); } static inline void convert_vx_to_fp(freg_t *fprs, __vector128 *vxrs) diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index 86634e71b69f4..1dc55db8cd819 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h @@ -87,7 +87,6 @@ struct ipl_parameter_block { * IPL validity flags */ extern u32 ipl_flags; -extern u32 dump_prefix_page; struct dump_save_areas { struct save_area_ext **areas; @@ -176,7 +175,7 @@ enum diag308_rc { extern int diag308(unsigned long subcode, void *addr); extern void diag308_reset(void); -extern void store_status(void); +extern void store_status(void (*fn)(void *), void *data); extern void lgr_info_log(void); #endif /* _ASM_S390_IPL_H */ diff --git a/arch/s390/include/asm/reset.h b/arch/s390/include/asm/reset.h index 72786067b3005..fe11fa88a0e02 100644 --- a/arch/s390/include/asm/reset.h +++ b/arch/s390/include/asm/reset.h @@ -15,6 +15,5 @@ struct reset_call { extern void register_reset_call(struct reset_call *reset); extern void unregister_reset_call(struct reset_call *reset); -extern void s390_reset_system(void (*fn_pre)(void), - void (*fn_post)(void *), void *data); +extern void s390_reset_system(void); #endif /* _ASM_S390_RESET_H */ diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index 5df26b11cf47c..0cc383b9be7fc 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h @@ -18,6 +18,7 @@ extern struct mutex smp_cpu_state_mutex; extern unsigned int smp_cpu_mt_shift; extern unsigned int smp_cpu_mtid; +extern __vector128 __initdata boot_cpu_vector_save_area[__NUM_VXRS]; extern int __cpu_up(unsigned int cpu, struct task_struct *tidle); @@ -55,7 +56,6 @@ static inline int smp_store_status(int cpu) { return 0; } static inline int smp_vcpu_scheduled(int cpu) { return 1; } static inline void smp_yield_cpu(int cpu) { } static inline void smp_fill_possible_mask(void) { } -static inline void smp_save_dump_cpus(void) { } #endif /* CONFIG_SMP */ diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 3c31609df959a..20a5caf6d981d 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -335,6 +335,14 @@ static __init void detect_machine_facilities(void) } } +static inline void save_vector_registers(void) +{ +#ifdef CONFIG_CRASH_DUMP + if (test_facility(129)) + save_vx_regs(boot_cpu_vector_save_area); +#endif +} + static int __init disable_vector_extension(char *str) { S390_lowcore.machine_flags &= ~MACHINE_FLAG_VX; @@ -451,6 +459,7 @@ void __init startup_init(void) detect_diag9c(); detect_diag44(); detect_machine_facilities(); + save_vector_registers(); setup_topology(); sclp_early_detect(); lockdep_on(); diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index b1f0a90f933bb..26d58cf725738 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -2039,10 +2039,7 @@ static void do_reset_calls(void) reset->fn(); } -u32 dump_prefix_page; - -void s390_reset_system(void (*fn_pre)(void), - void (*fn_post)(void *), void *data) +void s390_reset_system(void) { struct _lowcore *lc; @@ -2051,9 +2048,6 @@ void s390_reset_system(void (*fn_pre)(void), /* Stack for interrupt/machine check handler */ lc->panic_stack = S390_lowcore.panic_stack; - /* Save prefix page address for dump case */ - dump_prefix_page = (u32)(unsigned long) lc; - /* Disable prefixing */ set_prefix(0); @@ -2077,14 +2071,5 @@ void s390_reset_system(void (*fn_pre)(void), S390_lowcore.subchannel_id = 0; S390_lowcore.subchannel_nr = 0; - /* Store status at absolute zero */ - store_status(); - - /* Call function before reset */ - if (fn_pre) - fn_pre(); do_reset_calls(); - /* Call function after reset */ - if (fn_post) - fn_post(data); } diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index bf2cd699556f3..2f1b7217c25cf 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c @@ -34,40 +34,6 @@ extern const unsigned long long relocate_kernel_len; #ifdef CONFIG_CRASH_DUMP -/* - * Initialize CPU ELF notes - */ -static void setup_regs(void) -{ - struct save_area *sa, *sa_0; - unsigned long prefix; - int cpu, this_cpu; - - /* setup_regs is called with the prefix register = 0 */ - sa_0 = (struct save_area *) __LC_FPREGS_SAVE_AREA; - - /* Get status of this CPU out of absolute zero */ - prefix = (unsigned long) S390_lowcore.prefixreg_save_area; - sa = (struct save_area *)(prefix + __LC_FPREGS_SAVE_AREA); - memcpy(sa, sa_0, sizeof(struct save_area)); - if (MACHINE_HAS_VX) { - struct _lowcore *lc = (struct _lowcore *) prefix; - save_vx_regs_safe((void *) lc->vector_save_area_addr); - } - - /* Get status of the other CPUs */ - this_cpu = smp_find_processor_id(stap()); - for_each_online_cpu(cpu) { - if (cpu == this_cpu) - continue; - if (smp_store_status(cpu)) - continue; - prefix = (unsigned long) S390_lowcore.prefixreg_save_area; - sa = (struct save_area *)(prefix + __LC_FPREGS_SAVE_AREA); - memcpy(sa, sa_0, sizeof(struct save_area)); - } -} - /* * PM notifier callback for kdump */ @@ -99,14 +65,66 @@ static int __init machine_kdump_pm_init(void) arch_initcall(machine_kdump_pm_init); /* - * Start kdump: We expect here that a store status has been done on our CPU + * Reset the system, copy boot CPU registers to absolute zero, + * and jump to the kdump image */ static void __do_machine_kdump(void *image) { - int (*start_kdump)(int) = (void *)((struct kimage *) image)->start; + int (*start_kdump)(int); + unsigned long prefix; + + /* store_status() saved the prefix register to lowcore */ + prefix = (unsigned long) S390_lowcore.prefixreg_save_area; + + /* Now do the reset */ + s390_reset_system(); + + /* + * Copy dump CPU store status info to absolute zero. + * This need to be done *after* s390_reset_system set the + * prefix register of this CPU to zero + */ + memcpy((void *) __LC_FPREGS_SAVE_AREA, + (void *)(prefix + __LC_FPREGS_SAVE_AREA), 512); __load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA); + start_kdump = (void *)((struct kimage *) image)->start; start_kdump(1); + + /* Die if start_kdump returns */ + disabled_wait((unsigned long) __builtin_return_address(0)); +} + +/* + * Start kdump: create a LGR log entry, store status of all CPUs and + * branch to __do_machine_kdump. + */ +static noinline void __machine_kdump(void *image) +{ + int this_cpu, cpu; + + lgr_info_log(); + /* Get status of the other CPUs */ + this_cpu = smp_find_processor_id(stap()); + for_each_online_cpu(cpu) { + if (cpu == this_cpu) + continue; + if (smp_store_status(cpu)) + continue; + } + /* Store status of the boot CPU */ + if (MACHINE_HAS_VX) + save_vx_regs((void *) &S390_lowcore.vector_save_area); + /* + * To create a good backchain for this CPU in the dump store_status + * is passed the address of a function. The address is saved into + * the PSW save area of the boot CPU and the function is invoked as + * a tail call of store_status. The backchain in the dump will look + * like this: + * restart_int_handler -> __machine_kexec -> __do_machine_kdump + * The call to store_status() will not return. + */ + store_status(__do_machine_kdump, image); } #endif @@ -229,10 +247,14 @@ static void __do_machine_kexec(void *data) relocate_kernel_t data_mover; struct kimage *image = data; + s390_reset_system(); data_mover = (relocate_kernel_t) page_to_phys(image->control_code_page); /* Call the moving routine */ (*data_mover)(&image->head, image->start); + + /* Die if kexec returns */ + disabled_wait((unsigned long) __builtin_return_address(0)); } /* @@ -245,14 +267,10 @@ static void __machine_kexec(void *data) tracing_off(); debug_locks_off(); #ifdef CONFIG_CRASH_DUMP - if (((struct kimage *) data)->type == KEXEC_TYPE_CRASH) { - - lgr_info_log(); - s390_reset_system(setup_regs, __do_machine_kdump, data); - } else + if (((struct kimage *) data)->type == KEXEC_TYPE_CRASH) + __machine_kdump(data); #endif - s390_reset_system(NULL, __do_machine_kexec, data); - disabled_wait((unsigned long) __builtin_return_address(0)); + __do_machine_kexec(data); } /* diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S index b75a521e4fabd..89ea8c213d823 100644 --- a/arch/s390/kernel/reipl.S +++ b/arch/s390/kernel/reipl.S @@ -9,12 +9,11 @@ #include # -# store_status +# Issue "store status" for the current CPU to its prefix page +# and call passed function afterwards # -# Prerequisites to run this function: -# - Prefix register is set to zero -# - Original prefix register is stored in "dump_prefix_page" -# - Lowcore protection is off +# r2 = Function to be called after store status +# r3 = Parameter for function # ENTRY(store_status) /* Save register one and load save area base */ @@ -53,23 +52,23 @@ ENTRY(store_status) /* CPU timer */ lghi %r1,__LC_CPU_TIMER_SAVE_AREA stpt 0(%r1) - /* Saved prefix register */ + /* Store prefix register */ lghi %r1,__LC_PREFIX_SAVE_AREA - larl %r2,dump_prefix_page - mvc 0(4,%r1),0(%r2) + stpx 0(%r1) /* Clock comparator - seven bytes */ lghi %r1,__LC_CLOCK_COMP_SAVE_AREA - larl %r2,.Lclkcmp - stckc 0(%r2) - mvc 1(7,%r1),1(%r2) + larl %r4,.Lclkcmp + stckc 0(%r4) + mvc 1(7,%r1),1(%r4) /* Program status word */ lghi %r1,__LC_PSW_SAVE_AREA - epsw %r2,%r3 - st %r2,0(%r1) - st %r3,4(%r1) - larl %r2,store_status + epsw %r4,%r5 + st %r4,0(%r1) + st %r5,4(%r1) stg %r2,8(%r1) - br %r14 + lgr %r1,%r2 + lgr %r2,%r3 + br %r1 .section .bss .align 8 @@ -84,9 +83,11 @@ ENTRY(store_status) ENTRY(do_reipl_asm) basr %r13,0 .Lpg0: lpswe .Lnewpsw-.Lpg0(%r13) -.Lpg1: brasl %r14,store_status +.Lpg1: lgr %r3,%r2 + larl %r2,.Lstatus + brasl %r14,store_status - lctlg %c6,%c6,.Lall-.Lpg0(%r13) +.Lstatus: lctlg %c6,%c6,.Lall-.Lpg0(%r13) lgr %r1,%r2 mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13) stsch .Lschib-.Lpg0(%r13) diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 8f5107d6ebb37..22756bb0819e6 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -865,11 +865,13 @@ void __init setup_arch(char **cmdline_p) check_initrd(); reserve_crashkernel(); +#ifdef CONFIG_CRASH_DUMP /* * Be aware that smp_save_dump_cpus() triggers a system reset. * Therefore CPU and device initialization should be done afterwards. */ smp_save_dump_cpus(); +#endif setup_resources(); setup_vmcoreinfo(); diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index d49a8cb404c25..2a69077d482cb 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -80,6 +80,10 @@ EXPORT_SYMBOL(smp_cpu_mt_shift); unsigned int smp_cpu_mtid; EXPORT_SYMBOL(smp_cpu_mtid); +#ifdef CONFIG_CRASH_DUMP +__vector128 __initdata boot_cpu_vector_save_area[__NUM_VXRS]; +#endif + static unsigned int smp_max_threads __initdata = -1U; static int __init early_nosmt(char *s) @@ -105,8 +109,7 @@ DEFINE_MUTEX(smp_cpu_state_mutex); /* * Signal processor helper functions. */ -static inline int __pcpu_sigp_relax(u16 addr, u8 order, unsigned long parm, - u32 *status) +static inline int __pcpu_sigp_relax(u16 addr, u8 order, unsigned long parm) { int cc; @@ -538,53 +541,24 @@ EXPORT_SYMBOL(smp_ctl_clear_bit); #ifdef CONFIG_CRASH_DUMP -static void __init __smp_store_cpu_state(struct save_area_ext *sa_ext, - u16 address, int is_boot_cpu) -{ - void *lc = (void *)(unsigned long) store_prefix(); - unsigned long vx_sa; - - if (is_boot_cpu) { - /* Copy the registers of the boot CPU. */ - copy_oldmem_kernel(&sa_ext->sa, (void *) __LC_FPREGS_SAVE_AREA, - sizeof(sa_ext->sa)); - if (MACHINE_HAS_VX) - save_vx_regs_safe(sa_ext->vx_regs); - return; - } - /* Get the registers of a non-boot cpu. */ - __pcpu_sigp_relax(address, SIGP_STOP_AND_STORE_STATUS, 0, NULL); - memcpy_real(&sa_ext->sa, lc + __LC_FPREGS_SAVE_AREA, sizeof(sa_ext->sa)); - if (!MACHINE_HAS_VX) - return; - /* Get the VX registers */ - vx_sa = memblock_alloc(PAGE_SIZE, PAGE_SIZE); - if (!vx_sa) - panic("could not allocate memory for VX save area\n"); - __pcpu_sigp_relax(address, SIGP_STORE_ADDITIONAL_STATUS, vx_sa, NULL); - memcpy(sa_ext->vx_regs, (void *) vx_sa, sizeof(sa_ext->vx_regs)); - memblock_free(vx_sa, PAGE_SIZE); -} - int smp_store_status(int cpu) { - unsigned long vx_sa; - struct pcpu *pcpu; + struct pcpu *pcpu = pcpu_devices + cpu; + unsigned long pa; - pcpu = pcpu_devices + cpu; - if (__pcpu_sigp_relax(pcpu->address, SIGP_STOP_AND_STORE_STATUS, - 0, NULL) != SIGP_CC_ORDER_CODE_ACCEPTED) + pa = __pa(&pcpu->lowcore->floating_pt_save_area); + if (__pcpu_sigp_relax(pcpu->address, SIGP_STORE_STATUS_AT_ADDRESS, + pa) != SIGP_CC_ORDER_CODE_ACCEPTED) return -EIO; if (!MACHINE_HAS_VX) return 0; - vx_sa = __pa(pcpu->lowcore->vector_save_area_addr); - __pcpu_sigp_relax(pcpu->address, SIGP_STORE_ADDITIONAL_STATUS, - vx_sa, NULL); + pa = __pa(pcpu->lowcore->vector_save_area_addr); + if (__pcpu_sigp_relax(pcpu->address, SIGP_STORE_ADDITIONAL_STATUS, + pa) != SIGP_CC_ORDER_CODE_ACCEPTED) + return -EIO; return 0; } -#endif /* CONFIG_CRASH_DUMP */ - /* * Collect CPU state of the previous, crashed system. * There are four cases: @@ -593,7 +567,7 @@ int smp_store_status(int cpu) * The state for all CPUs except the boot CPU needs to be collected * with sigp stop-and-store-status. The boot CPU state is located in * the absolute lowcore of the memory stored in the HSA. The zcore code - * will allocate the save area and copy the boot CPU state from the HSA. + * will copy the boot CPU state from the HSA. * 2) stand-alone kdump for SCSI (zfcp dump with swapped memory) * condition: OLDMEM_BASE != NULL && ipl_info.type == IPL_TYPE_FCP_DUMP * The state for all CPUs except the boot CPU needs to be collected @@ -611,21 +585,49 @@ int smp_store_status(int cpu) * This case does not exist for s390 anymore, setup_arch explicitly * deactivates the elfcorehdr= kernel parameter */ +static __init void smp_save_cpu_vxrs(struct save_area_ext *sa_ext, u16 addr, + bool is_boot_cpu, unsigned long page) +{ + __vector128 *vxrs = (__vector128 *) page; + + if (is_boot_cpu) + vxrs = boot_cpu_vector_save_area; + else + __pcpu_sigp_relax(addr, SIGP_STORE_ADDITIONAL_STATUS, page); + memcpy(&sa_ext->vx_regs, vxrs, sizeof(sa_ext->vx_regs)); +} + +static __init void smp_save_cpu_regs(struct save_area_ext *sa_ext, u16 addr, + bool is_boot_cpu, unsigned long page) +{ + void *regs = (void *) page; + + if (is_boot_cpu) + copy_oldmem_kernel(regs, (void *) __LC_FPREGS_SAVE_AREA, 512); + else + __pcpu_sigp_relax(addr, SIGP_STORE_STATUS_AT_ADDRESS, page); + memcpy(&sa_ext->sa, regs, sizeof(sa_ext->sa)); +} + void __init smp_save_dump_cpus(void) { -#ifdef CONFIG_CRASH_DUMP int addr, cpu, boot_cpu_addr, max_cpu_addr; struct save_area_ext *sa_ext; + unsigned long page; bool is_boot_cpu; if (!(OLDMEM_BASE || ipl_info.type == IPL_TYPE_FCP_DUMP)) /* No previous system present, normal boot. */ return; + /* Allocate a page as dumping area for the store status sigps */ + page = memblock_alloc_base(PAGE_SIZE, PAGE_SIZE, 1UL << 31); + if (!page) + panic("could not allocate memory for save area\n"); /* Set multi-threading state to the previous system. */ pcpu_set_smt(sclp.mtid_prev); max_cpu_addr = SCLP_MAX_CORES << sclp.mtid_prev; for (cpu = 0, addr = 0; addr <= max_cpu_addr; addr++) { - if (__pcpu_sigp_relax(addr, SIGP_SENSE, 0, NULL) == + if (__pcpu_sigp_relax(addr, SIGP_SENSE, 0) == SIGP_CC_NOT_OPERATIONAL) continue; cpu += 1; @@ -634,7 +636,7 @@ void __init smp_save_dump_cpus(void) dump_save_areas.count = cpu; boot_cpu_addr = stap(); for (cpu = 0, addr = 0; addr <= max_cpu_addr; addr++) { - if (__pcpu_sigp_relax(addr, SIGP_SENSE, 0, NULL) == + if (__pcpu_sigp_relax(addr, SIGP_SENSE, 0) == SIGP_CC_NOT_OPERATIONAL) continue; sa_ext = (void *) memblock_alloc(sizeof(*sa_ext), 8); @@ -643,16 +645,24 @@ void __init smp_save_dump_cpus(void) panic("could not allocate memory for save area\n"); is_boot_cpu = (addr == boot_cpu_addr); cpu += 1; - if (is_boot_cpu && !OLDMEM_BASE) - /* Skip boot CPU for standard zfcp dump. */ - continue; - /* Get state for this CPU. */ - __smp_store_cpu_state(sa_ext, addr, is_boot_cpu); + if (MACHINE_HAS_VX) + /* Get the vector registers */ + smp_save_cpu_vxrs(sa_ext, addr, is_boot_cpu, page); + /* + * For a zfcp dump OLDMEM_BASE == NULL and the registers + * of the boot CPU are stored in the HSA. To retrieve + * these registers an SCLP request is required which is + * done by drivers/s390/char/zcore.c:init_cpu_info() + */ + if (!is_boot_cpu || OLDMEM_BASE) + /* Get the CPU registers */ + smp_save_cpu_regs(sa_ext, addr, is_boot_cpu, page); } + memblock_free(page, PAGE_SIZE); diag308_reset(); pcpu_set_smt(0); -#endif /* CONFIG_CRASH_DUMP */ } +#endif /* CONFIG_CRASH_DUMP */ void smp_cpu_set_polarization(int cpu, int val) { @@ -676,7 +686,7 @@ static struct sclp_core_info *smp_get_core_info(void) for (address = 0; address < (SCLP_MAX_CORES << smp_cpu_mt_shift); address += (1U << smp_cpu_mt_shift)) { - if (__pcpu_sigp_relax(address, SIGP_SENSE, 0, NULL) == + if (__pcpu_sigp_relax(address, SIGP_SENSE, 0) == SIGP_CC_NOT_OPERATIONAL) continue; info->core[info->configured].core_id = diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 087da775c359e..bed191a39c5ba 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -129,8 +129,6 @@ static int __init init_cpu_info(void) TRACE("could not copy from HSA\n"); return -EIO; } - if (MACHINE_HAS_VX) - save_vx_regs_safe(sa_ext->vx_regs); return 0; } diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 690b8547e828d..e0d02952a7f48 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -917,7 +917,7 @@ void reipl_ccw_dev(struct ccw_dev_id *devid) { struct subchannel_id uninitialized_var(schid); - s390_reset_system(NULL, NULL, NULL); + s390_reset_system(); if (reipl_find_schid(devid, &schid) != 0) panic("IPL Device not found\n"); do_reipl_asm(*((__u32*)&schid)); -- GitLab From 1a2c5840acf9f657c9b580d4ee12a4c9db3429cb Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 29 Oct 2015 10:59:15 +0100 Subject: [PATCH 0710/2855] s390/dump: cleanup CPU save area handling Introduce save_area_alloc(), save_area_boot_cpu(), save_area_add_regs() and save_area_add_vxrs to deal with storing the CPU state in case of a system dump. Remove struct save_area and save_area_ext, and create a new struct save_area as a local definition to arch/s390/kernel/crash_dump.c. Copy each individual field from the hardware status area to the save area, storing the minimum of required data. Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/ipl.h | 11 +- arch/s390/include/asm/lowcore.h | 21 --- arch/s390/kernel/crash_dump.c | 263 +++++++++++++++----------------- arch/s390/kernel/smp.c | 37 ++--- drivers/s390/char/zcore.c | 11 +- 5 files changed, 145 insertions(+), 198 deletions(-) diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index 1dc55db8cd819..6fc44dca193ef 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h @@ -88,12 +88,11 @@ struct ipl_parameter_block { */ extern u32 ipl_flags; -struct dump_save_areas { - struct save_area_ext **areas; - int count; -}; - -extern struct dump_save_areas dump_save_areas; +struct save_area; +struct save_area * __init save_area_alloc(bool is_boot_cpu); +struct save_area * __init save_area_boot_cpu(void); +void __init save_area_add_regs(struct save_area *, void *regs); +void __init save_area_add_vxrs(struct save_area *, __vector128 *vxrs); extern void do_reipl(void); extern void do_halt(void); diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index afe1cfebf1a4a..5dbbf199ba2ed 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h @@ -16,27 +16,6 @@ #define LC_ORDER 1 #define LC_PAGES 2 -struct save_area { - u64 fp_regs[16]; - u64 gp_regs[16]; - u8 psw[16]; - u8 pad1[8]; - u32 pref_reg; - u32 fp_ctrl_reg; - u8 pad2[4]; - u32 tod_reg; - u64 timer; - u64 clk_cmp; - u8 pad3[8]; - u32 acc_regs[16]; - u64 ctrl_regs[16]; -} __packed; - -struct save_area_ext { - struct save_area sa; - __vector128 vx_regs[32]; -}; - struct _lowcore { __u8 pad_0x0000[0x0014-0x0000]; /* 0x0000 */ __u32 ipl_parmblock_ptr; /* 0x0014 */ diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index 0d59c0705c4fb..823ed6ab53c84 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -32,7 +33,84 @@ static struct memblock_type oldmem_type = { .regions = &oldmem_region, }; -struct dump_save_areas dump_save_areas; +struct save_area { + struct list_head list; + u64 psw[2]; + u64 ctrs[16]; + u64 gprs[16]; + u32 acrs[16]; + u64 fprs[16]; + u32 fpc; + u32 prefix; + u64 todpreg; + u64 timer; + u64 todcmp; + u64 vxrs_low[16]; + __vector128 vxrs_high[16]; +}; + +static LIST_HEAD(dump_save_areas); + +/* + * Allocate a save area + */ +struct save_area * __init save_area_alloc(bool is_boot_cpu) +{ + struct save_area *sa; + + sa = (void *) memblock_alloc(sizeof(*sa), 8); + if (!sa) + return NULL; + if (is_boot_cpu) + list_add(&sa->list, &dump_save_areas); + else + list_add_tail(&sa->list, &dump_save_areas); + return sa; +} + +/* + * Return the address of the save area for the boot CPU + */ +struct save_area * __init save_area_boot_cpu(void) +{ + if (list_empty(&dump_save_areas)) + return NULL; + return list_first_entry(&dump_save_areas, struct save_area, list); +} + +/* + * Copy CPU registers into the save area + */ +void __init save_area_add_regs(struct save_area *sa, void *regs) +{ + struct _lowcore *lc; + + lc = (struct _lowcore *)(regs - __LC_FPREGS_SAVE_AREA); + memcpy(&sa->psw, &lc->psw_save_area, sizeof(sa->psw)); + memcpy(&sa->ctrs, &lc->cregs_save_area, sizeof(sa->ctrs)); + memcpy(&sa->gprs, &lc->gpregs_save_area, sizeof(sa->gprs)); + memcpy(&sa->acrs, &lc->access_regs_save_area, sizeof(sa->acrs)); + memcpy(&sa->fprs, &lc->floating_pt_save_area, sizeof(sa->fprs)); + memcpy(&sa->fpc, &lc->fpt_creg_save_area, sizeof(sa->fpc)); + memcpy(&sa->prefix, &lc->prefixreg_save_area, sizeof(sa->prefix)); + memcpy(&sa->todpreg, &lc->tod_progreg_save_area, sizeof(sa->todpreg)); + memcpy(&sa->timer, &lc->cpu_timer_save_area, sizeof(sa->timer)); + memcpy(&sa->todcmp, &lc->clock_comp_save_area, sizeof(sa->todcmp)); +} + +/* + * Copy vector registers into the save area + */ +void __init save_area_add_vxrs(struct save_area *sa, __vector128 *vxrs) +{ + int i; + + /* Copy lower halves of vector registers 0-15 */ + for (i = 0; i < 16; i++) + memcpy(&sa->vxrs_low[i], &vxrs[i].u[2], 8); + /* Copy vector registers 16-31 */ + memcpy(sa->vxrs_high, vxrs + 16, 16 * sizeof(__vector128)); +} /* * Return physical address for virtual address @@ -232,8 +310,8 @@ static void *kzalloc_panic(int len) /* * Initialize ELF note */ -static void *nt_init(void *buf, Elf64_Word type, void *desc, int d_len, - const char *name) +static void *nt_init_name(void *buf, Elf64_Word type, void *desc, int d_len, + const char *name) { Elf64_Nhdr *note; u64 len; @@ -253,137 +331,42 @@ static void *nt_init(void *buf, Elf64_Word type, void *desc, int d_len, return PTR_ADD(buf, len); } -/* - * Initialize prstatus note - */ -static void *nt_prstatus(void *ptr, struct save_area *sa) +static inline void *nt_init(void *buf, Elf64_Word type, void *desc, int d_len) { - struct elf_prstatus nt_prstatus; - static int cpu_nr = 1; - - memset(&nt_prstatus, 0, sizeof(nt_prstatus)); - memcpy(&nt_prstatus.pr_reg.gprs, sa->gp_regs, sizeof(sa->gp_regs)); - memcpy(&nt_prstatus.pr_reg.psw, sa->psw, sizeof(sa->psw)); - memcpy(&nt_prstatus.pr_reg.acrs, sa->acc_regs, sizeof(sa->acc_regs)); - nt_prstatus.pr_pid = cpu_nr; - cpu_nr++; - - return nt_init(ptr, NT_PRSTATUS, &nt_prstatus, sizeof(nt_prstatus), - "CORE"); + return nt_init_name(buf, type, desc, d_len, KEXEC_CORE_NOTE_NAME); } /* - * Initialize fpregset (floating point) note + * Fill ELF notes for one CPU with save area registers */ -static void *nt_fpregset(void *ptr, struct save_area *sa) +static void *fill_cpu_elf_notes(void *ptr, int cpu, struct save_area *sa) { + struct elf_prstatus nt_prstatus; elf_fpregset_t nt_fpregset; + /* Prepare prstatus note */ + memset(&nt_prstatus, 0, sizeof(nt_prstatus)); + memcpy(&nt_prstatus.pr_reg.gprs, sa->gprs, sizeof(sa->gprs)); + memcpy(&nt_prstatus.pr_reg.psw, sa->psw, sizeof(sa->psw)); + memcpy(&nt_prstatus.pr_reg.acrs, sa->acrs, sizeof(sa->acrs)); + nt_prstatus.pr_pid = cpu; + /* Prepare fpregset (floating point) note */ memset(&nt_fpregset, 0, sizeof(nt_fpregset)); - memcpy(&nt_fpregset.fpc, &sa->fp_ctrl_reg, sizeof(sa->fp_ctrl_reg)); - memcpy(&nt_fpregset.fprs, &sa->fp_regs, sizeof(sa->fp_regs)); - - return nt_init(ptr, NT_PRFPREG, &nt_fpregset, sizeof(nt_fpregset), - "CORE"); -} - -/* - * Initialize timer note - */ -static void *nt_s390_timer(void *ptr, struct save_area *sa) -{ - return nt_init(ptr, NT_S390_TIMER, &sa->timer, sizeof(sa->timer), - KEXEC_CORE_NOTE_NAME); -} - -/* - * Initialize TOD clock comparator note - */ -static void *nt_s390_tod_cmp(void *ptr, struct save_area *sa) -{ - return nt_init(ptr, NT_S390_TODCMP, &sa->clk_cmp, - sizeof(sa->clk_cmp), KEXEC_CORE_NOTE_NAME); -} - -/* - * Initialize TOD programmable register note - */ -static void *nt_s390_tod_preg(void *ptr, struct save_area *sa) -{ - return nt_init(ptr, NT_S390_TODPREG, &sa->tod_reg, - sizeof(sa->tod_reg), KEXEC_CORE_NOTE_NAME); -} - -/* - * Initialize control register note - */ -static void *nt_s390_ctrs(void *ptr, struct save_area *sa) -{ - return nt_init(ptr, NT_S390_CTRS, &sa->ctrl_regs, - sizeof(sa->ctrl_regs), KEXEC_CORE_NOTE_NAME); -} - -/* - * Initialize prefix register note - */ -static void *nt_s390_prefix(void *ptr, struct save_area *sa) -{ - return nt_init(ptr, NT_S390_PREFIX, &sa->pref_reg, - sizeof(sa->pref_reg), KEXEC_CORE_NOTE_NAME); -} - -/* - * Initialize vxrs high note (full 128 bit VX registers 16-31) - */ -static void *nt_s390_vx_high(void *ptr, __vector128 *vx_regs) -{ - return nt_init(ptr, NT_S390_VXRS_HIGH, &vx_regs[16], - 16 * sizeof(__vector128), KEXEC_CORE_NOTE_NAME); -} - -/* - * Initialize vxrs low note (lower halves of VX registers 0-15) - */ -static void *nt_s390_vx_low(void *ptr, __vector128 *vx_regs) -{ - Elf64_Nhdr *note; - u64 len; - int i; - - note = (Elf64_Nhdr *)ptr; - note->n_namesz = strlen(KEXEC_CORE_NOTE_NAME) + 1; - note->n_descsz = 16 * 8; - note->n_type = NT_S390_VXRS_LOW; - len = sizeof(Elf64_Nhdr); - - memcpy(ptr + len, KEXEC_CORE_NOTE_NAME, note->n_namesz); - len = roundup(len + note->n_namesz, 4); - - ptr += len; - /* Copy lower halves of SIMD registers 0-15 */ - for (i = 0; i < 16; i++) { - memcpy(ptr, &vx_regs[i].u[2], 8); - ptr += 8; - } - return ptr; -} - -/* - * Fill ELF notes for one CPU with save area registers - */ -static void *fill_cpu_elf_notes(void *ptr, struct save_area *sa, - __vector128 *vx_regs) -{ - ptr = nt_prstatus(ptr, sa); - ptr = nt_fpregset(ptr, sa); - ptr = nt_s390_timer(ptr, sa); - ptr = nt_s390_tod_cmp(ptr, sa); - ptr = nt_s390_tod_preg(ptr, sa); - ptr = nt_s390_ctrs(ptr, sa); - ptr = nt_s390_prefix(ptr, sa); - if (MACHINE_HAS_VX && vx_regs) { - ptr = nt_s390_vx_low(ptr, vx_regs); - ptr = nt_s390_vx_high(ptr, vx_regs); + memcpy(&nt_fpregset.fpc, &sa->fpc, sizeof(sa->fpc)); + memcpy(&nt_fpregset.fprs, &sa->fprs, sizeof(sa->fprs)); + /* Create ELF notes for the CPU */ + ptr = nt_init(ptr, NT_PRSTATUS, &nt_prstatus, sizeof(nt_prstatus)); + ptr = nt_init(ptr, NT_PRFPREG, &nt_fpregset, sizeof(nt_fpregset)); + ptr = nt_init(ptr, NT_S390_TIMER, &sa->timer, sizeof(sa->timer)); + ptr = nt_init(ptr, NT_S390_TODCMP, &sa->todcmp, sizeof(sa->todcmp)); + ptr = nt_init(ptr, NT_S390_TODPREG, &sa->todpreg, sizeof(sa->todpreg)); + ptr = nt_init(ptr, NT_S390_CTRS, &sa->ctrs, sizeof(sa->ctrs)); + ptr = nt_init(ptr, NT_S390_PREFIX, &sa->prefix, sizeof(sa->prefix)); + if (MACHINE_HAS_VX) { + ptr = nt_init(ptr, NT_S390_VXRS_HIGH, + &sa->vxrs_high, sizeof(sa->vxrs_high)); + ptr = nt_init(ptr, NT_S390_VXRS_LOW, + &sa->vxrs_low, sizeof(sa->vxrs_low)); } return ptr; } @@ -398,8 +381,7 @@ static void *nt_prpsinfo(void *ptr) memset(&prpsinfo, 0, sizeof(prpsinfo)); prpsinfo.pr_sname = 'R'; strcpy(prpsinfo.pr_fname, "vmlinux"); - return nt_init(ptr, NT_PRPSINFO, &prpsinfo, sizeof(prpsinfo), - KEXEC_CORE_NOTE_NAME); + return nt_init(ptr, NT_PRPSINFO, &prpsinfo, sizeof(prpsinfo)); } /* @@ -441,7 +423,7 @@ static void *nt_vmcoreinfo(void *ptr) vmcoreinfo = get_vmcoreinfo_old(&size); if (!vmcoreinfo) return ptr; - return nt_init(ptr, 0, vmcoreinfo, size, "VMCOREINFO"); + return nt_init_name(ptr, 0, vmcoreinfo, size, "VMCOREINFO"); } /* @@ -470,13 +452,12 @@ static void *ehdr_init(Elf64_Ehdr *ehdr, int mem_chunk_cnt) */ static int get_cpu_cnt(void) { - int i, cpus = 0; + struct save_area *sa; + int cpus = 0; - for (i = 0; i < dump_save_areas.count; i++) { - if (dump_save_areas.areas[i]->sa.pref_reg == 0) - continue; - cpus++; - } + list_for_each_entry(sa, &dump_save_areas, list) + if (sa->prefix != 0) + cpus++; return cpus; } @@ -521,18 +502,16 @@ static void loads_init(Elf64_Phdr *phdr, u64 loads_offset) */ static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset) { - struct save_area_ext *sa_ext; + struct save_area *sa; void *ptr_start = ptr; - int i; + int cpu; ptr = nt_prpsinfo(ptr); - for (i = 0; i < dump_save_areas.count; i++) { - sa_ext = dump_save_areas.areas[i]; - if (sa_ext->sa.pref_reg == 0) - continue; - ptr = fill_cpu_elf_notes(ptr, &sa_ext->sa, sa_ext->vx_regs); - } + cpu = 1; + list_for_each_entry(sa, &dump_save_areas, list) + if (sa->prefix != 0) + ptr = fill_cpu_elf_notes(ptr, cpu++, sa); ptr = nt_vmcoreinfo(ptr); memset(phdr, 0, sizeof(*phdr)); phdr->p_type = PT_NOTE; diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 2a69077d482cb..9da95d8dfc62c 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -585,7 +585,7 @@ int smp_store_status(int cpu) * This case does not exist for s390 anymore, setup_arch explicitly * deactivates the elfcorehdr= kernel parameter */ -static __init void smp_save_cpu_vxrs(struct save_area_ext *sa_ext, u16 addr, +static __init void smp_save_cpu_vxrs(struct save_area *sa, u16 addr, bool is_boot_cpu, unsigned long page) { __vector128 *vxrs = (__vector128 *) page; @@ -594,10 +594,10 @@ static __init void smp_save_cpu_vxrs(struct save_area_ext *sa_ext, u16 addr, vxrs = boot_cpu_vector_save_area; else __pcpu_sigp_relax(addr, SIGP_STORE_ADDITIONAL_STATUS, page); - memcpy(&sa_ext->vx_regs, vxrs, sizeof(sa_ext->vx_regs)); + save_area_add_vxrs(sa, vxrs); } -static __init void smp_save_cpu_regs(struct save_area_ext *sa_ext, u16 addr, +static __init void smp_save_cpu_regs(struct save_area *sa, u16 addr, bool is_boot_cpu, unsigned long page) { void *regs = (void *) page; @@ -606,13 +606,13 @@ static __init void smp_save_cpu_regs(struct save_area_ext *sa_ext, u16 addr, copy_oldmem_kernel(regs, (void *) __LC_FPREGS_SAVE_AREA, 512); else __pcpu_sigp_relax(addr, SIGP_STORE_STATUS_AT_ADDRESS, page); - memcpy(&sa_ext->sa, regs, sizeof(sa_ext->sa)); + save_area_add_regs(sa, regs); } void __init smp_save_dump_cpus(void) { - int addr, cpu, boot_cpu_addr, max_cpu_addr; - struct save_area_ext *sa_ext; + int addr, boot_cpu_addr, max_cpu_addr; + struct save_area *sa; unsigned long page; bool is_boot_cpu; @@ -625,29 +625,20 @@ void __init smp_save_dump_cpus(void) panic("could not allocate memory for save area\n"); /* Set multi-threading state to the previous system. */ pcpu_set_smt(sclp.mtid_prev); - max_cpu_addr = SCLP_MAX_CORES << sclp.mtid_prev; - for (cpu = 0, addr = 0; addr <= max_cpu_addr; addr++) { - if (__pcpu_sigp_relax(addr, SIGP_SENSE, 0) == - SIGP_CC_NOT_OPERATIONAL) - continue; - cpu += 1; - } - dump_save_areas.areas = (void *)memblock_alloc(sizeof(void *) * cpu, 8); - dump_save_areas.count = cpu; boot_cpu_addr = stap(); - for (cpu = 0, addr = 0; addr <= max_cpu_addr; addr++) { + max_cpu_addr = SCLP_MAX_CORES << sclp.mtid_prev; + for (addr = 0; addr <= max_cpu_addr; addr++) { if (__pcpu_sigp_relax(addr, SIGP_SENSE, 0) == SIGP_CC_NOT_OPERATIONAL) continue; - sa_ext = (void *) memblock_alloc(sizeof(*sa_ext), 8); - dump_save_areas.areas[cpu] = sa_ext; - if (!sa_ext) - panic("could not allocate memory for save area\n"); is_boot_cpu = (addr == boot_cpu_addr); - cpu += 1; + /* Allocate save area */ + sa = save_area_alloc(is_boot_cpu); + if (!sa) + panic("could not allocate memory for save area\n"); if (MACHINE_HAS_VX) /* Get the vector registers */ - smp_save_cpu_vxrs(sa_ext, addr, is_boot_cpu, page); + smp_save_cpu_vxrs(sa, addr, is_boot_cpu, page); /* * For a zfcp dump OLDMEM_BASE == NULL and the registers * of the boot CPU are stored in the HSA. To retrieve @@ -656,7 +647,7 @@ void __init smp_save_dump_cpus(void) */ if (!is_boot_cpu || OLDMEM_BASE) /* Get the CPU registers */ - smp_save_cpu_regs(sa_ext, addr, is_boot_cpu, page); + smp_save_cpu_regs(sa, addr, is_boot_cpu, page); } memblock_free(page, PAGE_SIZE); diag308_reset(); diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index bed191a39c5ba..5043ecfa1fbcf 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -117,18 +117,17 @@ int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) static int __init init_cpu_info(void) { - struct save_area_ext *sa_ext; + struct save_area *sa; /* get info for boot cpu from lowcore, stored in the HSA */ - - sa_ext = dump_save_areas.areas[0]; - if (!sa_ext) + sa = save_area_boot_cpu(); + if (!sa) return -ENOMEM; - if (memcpy_hsa_kernel(&sa_ext->sa, __LC_FPREGS_SAVE_AREA, - sizeof(struct save_area)) < 0) { + if (memcpy_hsa_kernel(hsa_buf, __LC_FPREGS_SAVE_AREA, 512) < 0) { TRACE("could not copy from HSA\n"); return -EIO; } + save_area_add_regs(sa, hsa_buf); /* vx registers are saved in smp.c */ return 0; } -- GitLab From db1c45154a82195ad0b4d45d0e330ebac6883b70 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 12 Nov 2015 12:51:17 +0100 Subject: [PATCH 0711/2855] s390/spinlock: avoid diagnose loop The spinlock implementation calls the diagnose 0x9c / 0x44 immediately if the SIGP sense running reported the target CPU as not running. The diagnose 0x9c is a hint to the hypervisor to schedule the target CPU in preference to the source CPU that issued the diagnose. It can happen that on return from the diagnose the target CPU has not been scheduled yet, e.g. if the target logical CPU is on another physical CPU and the hypervisor did not want to migrate the logical CPU. Avoid the immediate repeat of the diagnose instruction, instead do the retry loop before the next invocation of diagnose 0x9c. Reviewed-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/lib/spinlock.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index 427aa44b35051..0a68fe04a9e16 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c @@ -41,8 +41,9 @@ void arch_spin_lock_wait(arch_spinlock_t *lp) { unsigned int cpu = SPINLOCK_LOCKVAL; unsigned int owner; - int count; + int count, first_diag; + first_diag = 1; while (1) { owner = ACCESS_ONCE(lp->lock); /* Try to get the lock if it is free. */ @@ -51,9 +52,10 @@ void arch_spin_lock_wait(arch_spinlock_t *lp) return; continue; } - /* Check if the lock owner is running. */ - if (!smp_vcpu_scheduled(~owner)) { + /* First iteration: check if the lock owner is running. */ + if (first_diag && !smp_vcpu_scheduled(~owner)) { smp_yield_cpu(~owner); + first_diag = 0; continue; } /* Loop for a while on the lock value. */ @@ -67,10 +69,13 @@ void arch_spin_lock_wait(arch_spinlock_t *lp) continue; /* * For multiple layers of hypervisors, e.g. z/VM + LPAR - * yield the CPU if the lock is still unavailable. + * yield the CPU unconditionally. For LPAR rely on the + * sense running status. */ - if (!MACHINE_IS_LPAR) + if (!MACHINE_IS_LPAR || !smp_vcpu_scheduled(~owner)) { smp_yield_cpu(~owner); + first_diag = 0; + } } } EXPORT_SYMBOL(arch_spin_lock_wait); @@ -79,9 +84,10 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) { unsigned int cpu = SPINLOCK_LOCKVAL; unsigned int owner; - int count; + int count, first_diag; local_irq_restore(flags); + first_diag = 1; while (1) { owner = ACCESS_ONCE(lp->lock); /* Try to get the lock if it is free. */ @@ -92,8 +98,9 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) local_irq_restore(flags); } /* Check if the lock owner is running. */ - if (!smp_vcpu_scheduled(~owner)) { + if (first_diag && !smp_vcpu_scheduled(~owner)) { smp_yield_cpu(~owner); + first_diag = 0; continue; } /* Loop for a while on the lock value. */ @@ -107,10 +114,13 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) continue; /* * For multiple layers of hypervisors, e.g. z/VM + LPAR - * yield the CPU if the lock is still unavailable. + * yield the CPU unconditionally. For LPAR rely on the + * sense running status. */ - if (!MACHINE_IS_LPAR) + if (!MACHINE_IS_LPAR || !smp_vcpu_scheduled(~owner)) { smp_yield_cpu(~owner); + first_diag = 0; + } } } EXPORT_SYMBOL(arch_spin_lock_wait_flags); -- GitLab From 406123517b5b3cd5855774f80d685cf393c950f6 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Thu, 15 Oct 2015 10:47:18 +0200 Subject: [PATCH 0712/2855] s390: get_user_pages_fast() might sleep Let's annotate it correctly, so we directly get a warning if we ever were to use it in atomic/preempt_disable/spinlock environment. Acked-by: Heiko Carstens Signed-off-by: David Hildenbrand Signed-off-by: Martin Schwidefsky --- arch/s390/mm/gup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 12bbf0e8478f8..21c74a71e2ab2 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c @@ -233,6 +233,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, struct mm_struct *mm = current->mm; int nr, ret; + might_sleep(); start &= PAGE_MASK; nr = __get_user_pages_fast(start, nr_pages, write, pages); if (nr == nr_pages) -- GitLab From 69eea95c48857c9dfcac120d6acea43027627b28 Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Mon, 16 Nov 2015 14:35:48 +0100 Subject: [PATCH 0713/2855] s390/pci_dma: fix DMA table corruption with > 4 TB main memory DMA addresses returned from map_page() are calculated by using an iommu bitmap plus a start_dma offset. The size of this bitmap is based on the main memory size. If we have more than (4 TB - start_dma) main memory, the DMA address calculation will also produce addresses > 4 TB. Such addresses cannot be inserted in the 3-level DMA page table, instead the entries modulo 4 TB will be overwritten. Fix this by restricting the iommu bitmap size to (4 TB - start_dma). Also set zdev->end_dma to the actual end address of the usable range, instead of the theoretical maximum as reported by the hardware, which fixes a sanity check in dma_map() and also the IOMMU API domain geometry aperture calculation. Signed-off-by: Gerald Schaefer Reviewed-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/pci_dma.h | 2 ++ arch/s390/pci/pci.c | 3 +-- arch/s390/pci/pci_dma.c | 19 ++++++++++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/arch/s390/include/asm/pci_dma.h b/arch/s390/include/asm/pci_dma.h index 1aac41e83ea19..92df3eb8d14ef 100644 --- a/arch/s390/include/asm/pci_dma.h +++ b/arch/s390/include/asm/pci_dma.h @@ -23,6 +23,8 @@ enum zpci_ioat_dtype { #define ZPCI_IOTA_FS_2G 2 #define ZPCI_KEY (PAGE_DEFAULT_KEY << 5) +#define ZPCI_TABLE_SIZE_RT (1UL << 42) + #define ZPCI_IOTA_STO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_ST) #define ZPCI_IOTA_RTTO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RT) #define ZPCI_IOTA_RSTO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RS) diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 7ef12a3ace3ae..11d4f277e9f69 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -701,8 +701,7 @@ static int zpci_restore(struct device *dev) goto out; zpci_map_resources(pdev); - zpci_register_ioat(zdev, 0, zdev->start_dma + PAGE_OFFSET, - zdev->start_dma + zdev->iommu_size - 1, + zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma, (u64) zdev->dma_table); out: diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index d348f2c09a1ee..3a40f718baefd 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c @@ -458,7 +458,19 @@ int zpci_dma_init_device(struct zpci_dev *zdev) goto out_clean; } - zdev->iommu_size = (unsigned long) high_memory - PAGE_OFFSET; + /* + * Restrict the iommu bitmap size to the minimum of the following: + * - main memory size + * - 3-level pagetable address limit minus start_dma offset + * - DMA address range allowed by the hardware (clp query pci fn) + * + * Also set zdev->end_dma to the actual end address of the usable + * range, instead of the theoretical maximum as reported by hardware. + */ + zdev->iommu_size = min3((u64) high_memory, + ZPCI_TABLE_SIZE_RT - zdev->start_dma, + zdev->end_dma - zdev->start_dma + 1); + zdev->end_dma = zdev->start_dma + zdev->iommu_size - 1; zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT; zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8); if (!zdev->iommu_bitmap) { @@ -466,10 +478,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev) goto out_reg; } - rc = zpci_register_ioat(zdev, - 0, - zdev->start_dma + PAGE_OFFSET, - zdev->start_dma + zdev->iommu_size - 1, + rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma, (u64) zdev->dma_table); if (rc) goto out_reg; -- GitLab From a6e975c5f8fd8652fc5ab754236ec155a228d452 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 16 Nov 2015 14:45:40 +0100 Subject: [PATCH 0714/2855] s390: Delete unnecessary checks before the function call "debug_unregister" The debug_unregister() function performs also input parameter validation. Thus the test around the calls is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/chsc_sch.c | 3 +-- drivers/s390/cio/cio.c | 9 +++------ drivers/s390/cio/qdio_debug.c | 6 ++---- drivers/s390/crypto/zcrypt_api.c | 6 ++---- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 213159dec89e0..378c57178bb8d 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c @@ -185,8 +185,7 @@ static int __init chsc_init_dbfs(void) debug_set_level(chsc_debug_log_id, 2); return 0; out: - if (chsc_debug_msg_id) - debug_unregister(chsc_debug_msg_id); + debug_unregister(chsc_debug_msg_id); return -ENOMEM; } diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index e0d02952a7f48..2d18205526b66 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -76,12 +76,9 @@ static int __init cio_debug_init(void) return 0; out_unregister: - if (cio_debug_msg_id) - debug_unregister(cio_debug_msg_id); - if (cio_debug_trace_id) - debug_unregister(cio_debug_trace_id); - if (cio_debug_crw_id) - debug_unregister(cio_debug_crw_id); + debug_unregister(cio_debug_msg_id); + debug_unregister(cio_debug_trace_id); + debug_unregister(cio_debug_crw_id); return -1; } diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c index f1f3baa8e6e4d..b6fc147f83d86 100644 --- a/drivers/s390/cio/qdio_debug.c +++ b/drivers/s390/cio/qdio_debug.c @@ -366,8 +366,6 @@ void qdio_debug_exit(void) { qdio_clear_dbf_list(); debugfs_remove(debugfs_root); - if (qdio_dbf_setup) - debug_unregister(qdio_dbf_setup); - if (qdio_dbf_error) - debug_unregister(qdio_dbf_error); + debug_unregister(qdio_dbf_setup); + debug_unregister(qdio_dbf_error); } diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 9f8fa42c062c2..5d3d04c040c2b 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -1428,10 +1428,8 @@ int __init zcrypt_debug_init(void) void zcrypt_debug_exit(void) { debugfs_remove(debugfs_root); - if (zcrypt_dbf_common) - debug_unregister(zcrypt_dbf_common); - if (zcrypt_dbf_devices) - debug_unregister(zcrypt_dbf_devices); + debug_unregister(zcrypt_dbf_common); + debug_unregister(zcrypt_dbf_devices); } /** -- GitLab From 155eeb66d2d1e58c8d4d58d47d8f8b02263d508d Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Wed, 4 Nov 2015 09:01:34 +0100 Subject: [PATCH 0715/2855] s390/sclp_cpi: remove sclp_cpi module in favor of sysfs interface Since commit c05ffc4f2b20 ("[S390] sclp: sysfs interface for SCLP cpi"), which was made 2008 the user can specify a system and sysplex name through the /sys/firmware/cpi interface. In addition to sysplex and system name, the user can also override the system type and system version. Because the syfs interface is easier to use and allows the settings to be updated, the sclp_cpi module becomes obsolete and can be removed. Signed-off-by: Hendrik Brueckner Acked-by: Christian Borntraeger Acked-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/char/Kconfig | 13 ------------ drivers/s390/char/Makefile | 1 - drivers/s390/char/sclp_cpi.c | 40 ------------------------------------ 3 files changed, 54 deletions(-) delete mode 100644 drivers/s390/char/sclp_cpi.c diff --git a/drivers/s390/char/Kconfig b/drivers/s390/char/Kconfig index eaca3e0063019..1f9078fdaf8c0 100644 --- a/drivers/s390/char/Kconfig +++ b/drivers/s390/char/Kconfig @@ -78,19 +78,6 @@ config SCLP_VT220_CONSOLE Include support for using an IBM SCLP VT220-compatible terminal as a Linux system console. -config SCLP_CPI - def_tristate m - prompt "Control-Program Identification" - depends on S390 - help - This option enables the hardware console interface for system - identification. This is commonly used for workload management and - gives you a nice name for the system on the service element. - Please select this option as a module since built-in operation is - completely untested. - You should only select this option if you know what you are doing, - need this feature and intend to run your kernel in LPAR. - config SCLP_ASYNC def_tristate m prompt "Support for Call Home via Asynchronous SCLP Records" diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile index 8a2632ba88dc3..dd2f7c832e5e3 100644 --- a/drivers/s390/char/Makefile +++ b/drivers/s390/char/Makefile @@ -16,7 +16,6 @@ obj-$(CONFIG_TN3215) += con3215.o obj-$(CONFIG_SCLP_TTY) += sclp_tty.o obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o -obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o obj-$(CONFIG_SCLP_ASYNC) += sclp_async.o obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o diff --git a/drivers/s390/char/sclp_cpi.c b/drivers/s390/char/sclp_cpi.c deleted file mode 100644 index d70d8c20229c1..0000000000000 --- a/drivers/s390/char/sclp_cpi.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * SCLP control programm identification - * - * Copyright IBM Corp. 2001, 2007 - * Author(s): Martin Peschke - * Michael Ernst - */ - -#include -#include -#include -#include -#include "sclp_cpi_sys.h" - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Identify this operating system instance " - "to the System z hardware"); -MODULE_AUTHOR("Martin Peschke , " - "Michael Ernst "); - -static char *system_name = ""; -static char *sysplex_name = ""; - -module_param(system_name, charp, 0); -MODULE_PARM_DESC(system_name, "e.g. hostname - max. 8 characters"); -module_param(sysplex_name, charp, 0); -MODULE_PARM_DESC(sysplex_name, "if applicable - max. 8 characters"); - -static int __init cpi_module_init(void) -{ - return sclp_cpi_set_data(system_name, sysplex_name, "LINUX", - LINUX_VERSION_CODE); -} - -static void __exit cpi_module_exit(void) -{ -} - -module_init(cpi_module_init); -module_exit(cpi_module_exit); -- GitLab From 561e103002696a17907ac5bbccec551e32de3b7f Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Wed, 18 Nov 2015 17:00:10 +0100 Subject: [PATCH 0716/2855] s390/dis: Fix printing of the register numbers Since commit b006f19b055f ("lib/vsprintf.c: handle invalid format specifiers more robustly") I get errors like [...] Krnl Code: 00000000004e2410: c00400000000 brcl 0,4e2410 Please remove unsupported %r in format string [ 8.179483] ------------[ cut here ]------------ [ 8.179484] WARNING: at lib/vsprintf.c:1781 Turns out that our disassembler relied on %r not being used as format string. Let's do the proper escaping of our decode buffers. Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/dis.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c index 8140d10c67850..8cb9bfdd3ea8a 100644 --- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c @@ -2015,7 +2015,7 @@ void show_code(struct pt_regs *regs) *ptr++ = '\t'; ptr += print_insn(ptr, code + start, addr); start += opsize; - printk(buffer); + printk("%s", buffer); ptr = buffer; ptr += sprintf(ptr, "\n "); hops++; @@ -2042,7 +2042,7 @@ void print_fn_code(unsigned char *code, unsigned long len) ptr += print_insn(ptr, code, (unsigned long) code); *ptr++ = '\n'; *ptr++ = 0; - printk(buffer); + printk("%s", buffer); code += opsize; len -= opsize; } -- GitLab From 3f975df69dba78834471b7133dcb8c8ddf7f986a Mon Sep 17 00:00:00 2001 From: Sascha Silbe Date: Tue, 24 Nov 2015 16:28:55 +0100 Subject: [PATCH 0717/2855] s390/sclp: Add VT220 support to early sclp console When running under qemu with the default configuration (-nographic), there is only a VT220 SCLP console, no line-mode SCLP console. Add VT220 support to the early SCLP console so the user has a chance to see critical error messages during early boot. None of the existing users of _sclp_print_early() check the return code. Instead of trying to come up with return code semantics when printing to multiple consoles (any or all of which may fail), we just drop the return code entirely. Tested on z/VM (line mode console) and LPAR (VT220 and line mode console). Tested on qemu/KVM with VT220 console and / or line mode console. Signed-off-by: Sascha Silbe Reviewed-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/sclp.h | 2 +- arch/s390/kernel/sclp.c | 65 +++++++++++++++++++++++++++--------- 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index 2ca9c7bc50db6..cb691602f295e 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h @@ -80,6 +80,6 @@ int sclp_pci_deconfigure(u32 fid); int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count); int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count); void sclp_early_detect(void); -int _sclp_print_early(const char *); +void _sclp_print_early(const char *); #endif /* _ASM_S390_SCLP_H */ diff --git a/arch/s390/kernel/sclp.c b/arch/s390/kernel/sclp.c index 9fe7781a45cdd..d88db40bdf159 100644 --- a/arch/s390/kernel/sclp.c +++ b/arch/s390/kernel/sclp.c @@ -9,7 +9,11 @@ #include #include +#define EVTYP_VT220MSG_MASK 0x00000040 +#define EVTYP_MSG_MASK 0x40000000 + static char _sclp_work_area[4096] __aligned(PAGE_SIZE); +static bool have_vt220, have_linemode; static void _sclp_wait_int(void) { @@ -68,7 +72,7 @@ static int _sclp_setup(int disable) 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; unsigned int *masks; @@ -82,13 +86,13 @@ static int _sclp_setup(int disable) rc = _sclp_servc(0x00780005, _sclp_work_area); if (rc) return rc; - if ((masks[0] & masks[3]) != masks[0] || - (masks[1] & masks[2]) != masks[1]) - return -EIO; + have_vt220 = masks[2] & EVTYP_VT220MSG_MASK; + have_linemode = masks[2] & EVTYP_MSG_MASK; return 0; } -static int _sclp_print(const char *str) +/* Output multi-line text using SCLP Message interface. */ +static void _sclp_print_lm(const char *str) { static unsigned char write_head[] = { /* sccb header */ @@ -143,18 +147,49 @@ static int _sclp_print(const char *str) } while (ch != 0); /* SCLP write data */ - return _sclp_servc(0x00760005, _sclp_work_area); + _sclp_servc(0x00760005, _sclp_work_area); } -int _sclp_print_early(const char *str) +/* Output multi-line text (plus a newline) using SCLP VT220 + * interface. + */ +static void _sclp_print_vt220(const char *str) { - int rc; + static unsigned char const write_head[] = { + /* sccb header */ + 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* evbuf header */ + 0x00, 0x06, + 0x1a, 0x00, 0x00, 0x00, + }; + size_t len = strlen(str); - rc = _sclp_setup(0); - if (rc) - return rc; - rc = _sclp_print(str); - if (rc) - return rc; - return _sclp_setup(1); + if (sizeof(write_head) + len >= sizeof(_sclp_work_area)) + len = sizeof(_sclp_work_area) - sizeof(write_head) - 1; + + memcpy(_sclp_work_area, write_head, sizeof(write_head)); + memcpy(_sclp_work_area + sizeof(write_head), str, len); + _sclp_work_area[sizeof(write_head) + len] = '\n'; + + /* Update length fields in evbuf and sccb headers */ + *(unsigned short *)(_sclp_work_area + 8) += len + 1; + *(unsigned short *)(_sclp_work_area + 0) += len + 1; + + /* SCLP write data */ + (void)_sclp_servc(0x00760005, _sclp_work_area); +} + +/* Output one or more lines of text on the SCLP console (VT220 and / + * or line-mode). All lines get terminated; no need for a trailing LF. + */ +void _sclp_print_early(const char *str) +{ + if (_sclp_setup(0) != 0) + return; + if (have_linemode) + _sclp_print_lm(str); + if (have_vt220) + _sclp_print_vt220(str); + _sclp_setup(1); } -- GitLab From b8eecf36a47bc5e9569f513a3888d03d82985fbb Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Wed, 25 Nov 2015 11:54:36 +0100 Subject: [PATCH 0718/2855] s390: add 'install' target to 'make help' Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/s390/Makefile b/arch/s390/Makefile index e8d4423e4f858..647bd14b223e0 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -129,4 +129,8 @@ archclean: define archhelp echo '* image - Kernel image for IPL ($(boot)/image)' echo '* bzImage - Compressed kernel image for IPL ($(boot)/bzImage)' + echo ' install - Install kernel using' + echo ' (your) ~/bin/$(INSTALLKERNEL) or' + echo ' (distribution) /sbin/$(INSTALLKERNEL) or' + echo ' install to $$(INSTALL_PATH)' endef -- GitLab From 9eb31be33cf84266abd61de0f6d3d1fe609587cf Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 26 Nov 2015 09:25:35 +0100 Subject: [PATCH 0719/2855] s390: remove is_32bit_task() helper is_32bit_task() used to be helpful when we still had CONFIG_32BIT. Since that is gone, it is nowadays identical to is_compat_task(). So remove it. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/compat.h | 2 +- arch/s390/include/asm/elf.h | 9 +++++---- arch/s390/include/asm/thread_info.h | 2 -- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index d350ed9d0fbb2..352f7bdaf11fc 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h @@ -284,7 +284,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) static inline int is_compat_task(void) { - return is_32bit_task(); + return test_thread_flag(TIF_31BIT); } static inline void __user *arch_compat_alloc_user_space(long len) diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index 7730e5b9e7e23..fabebe1e45d93 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h @@ -126,6 +126,7 @@ typedef s390_regs elf_gregset_t; typedef s390_fp_regs compat_elf_fpregset_t; typedef s390_compat_regs compat_elf_gregset_t; +#include #include /* for task_struct */ #include @@ -159,7 +160,7 @@ extern unsigned int vdso_enabled; the loader. We need to make sure that it is out of the way of the program that it will "exec", and that there is sufficient room for the brk. 64-bit tasks are aligned to 4GB. */ -#define ELF_ET_DYN_BASE (is_32bit_task() ? \ +#define ELF_ET_DYN_BASE (is_compat_task() ? \ (STACK_TOP / 3 * 2) : \ (STACK_TOP / 3 * 2) & ~((1UL << 32) - 1)) @@ -212,9 +213,9 @@ do { \ * of up to 1GB. For 31-bit processes the virtual address space is limited, * use no alignment and limit the randomization to 8MB. */ -#define BRK_RND_MASK (is_32bit_task() ? 0x7ffUL : 0x3ffffUL) -#define MMAP_RND_MASK (is_32bit_task() ? 0x7ffUL : 0x3ff80UL) -#define MMAP_ALIGN_MASK (is_32bit_task() ? 0 : 0x7fUL) +#define BRK_RND_MASK (is_compat_task() ? 0x7ffUL : 0x3ffffUL) +#define MMAP_RND_MASK (is_compat_task() ? 0x7ffUL : 0x3ff80UL) +#define MMAP_ALIGN_MASK (is_compat_task() ? 0 : 0x7fUL) #define STACK_RND_MASK MMAP_RND_MASK #define ARCH_DLINFO \ diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index 692b9247c0192..2fffc2c27581a 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h @@ -96,6 +96,4 @@ void arch_release_task_struct(struct task_struct *tsk); #define _TIF_31BIT _BITUL(TIF_31BIT) #define _TIF_SINGLE_STEP _BITUL(TIF_SINGLE_STEP) -#define is_32bit_task() (test_thread_flag(TIF_31BIT)) - #endif /* _ASM_THREAD_INFO_H */ -- GitLab From c6f70d3b8a32fdec60d3f78cb59423f056f16688 Mon Sep 17 00:00:00 2001 From: Jochen Schweflinghaus Date: Thu, 26 Nov 2015 19:13:01 +0100 Subject: [PATCH 0720/2855] s390/sclp: add open for business support Provide a user space interface and an enhancement to the sclp device driver which allows to send an 'Open for Business' event from the operating system to the Support Element. The 'Open for Business' event is used to signal the Support Element that the operating system (or an application running on top of it) is up and running. Signed-off-by: Jochen Schweflinghaus Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/char/Kconfig | 8 +++ drivers/s390/char/sclp_config.c | 102 +++++++++++++++++++++++++++++++- 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/drivers/s390/char/Kconfig b/drivers/s390/char/Kconfig index 1f9078fdaf8c0..b3f1c458905ff 100644 --- a/drivers/s390/char/Kconfig +++ b/drivers/s390/char/Kconfig @@ -112,6 +112,14 @@ config HMC_DRV transfer cache size from it's default value 0.5MB to N bytes. If N is zero, then no caching is performed. +config SCLP_OFB + def_bool n + prompt "Support for Open-for-Business SCLP Event" + depends on S390 + help + This option enables the Open-for-Business interface to the s390 + Service Element. + config S390_TAPE def_tristate m prompt "S/390 tape device support" diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c index 9441562074774..2ced50ccca63e 100644 --- a/drivers/s390/char/sclp_config.c +++ b/drivers/s390/char/sclp_config.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include "sclp.h" @@ -20,8 +22,22 @@ struct conf_mgm_data { u8 ev_qualifier; } __attribute__((packed)); +#define OFB_DATA_MAX 64 + +struct sclp_ofb_evbuf { + struct evbuf_header header; + struct conf_mgm_data cm_data; + char ev_data[OFB_DATA_MAX]; +} __packed; + +struct sclp_ofb_sccb { + struct sccb_header header; + struct sclp_ofb_evbuf ofb_evbuf; +} __packed; + #define EV_QUAL_CPU_CHANGE 1 #define EV_QUAL_CAP_CHANGE 3 +#define EV_QUAL_OPEN4BUSINESS 5 static struct work_struct sclp_cpu_capability_work; static struct work_struct sclp_cpu_change_work; @@ -63,15 +79,99 @@ static void sclp_conf_receiver_fn(struct evbuf_header *evbuf) static struct sclp_register sclp_conf_register = { +#ifdef CONFIG_SCLP_OFB + .send_mask = EVTYP_CONFMGMDATA_MASK, +#endif .receive_mask = EVTYP_CONFMGMDATA_MASK, .receiver_fn = sclp_conf_receiver_fn, }; +#ifdef CONFIG_SCLP_OFB +static int sclp_ofb_send_req(char *ev_data, size_t len) +{ + static DEFINE_MUTEX(send_mutex); + struct sclp_ofb_sccb *sccb; + int rc, response; + + if (len > OFB_DATA_MAX) + return -EINVAL; + sccb = (struct sclp_ofb_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!sccb) + return -ENOMEM; + /* Setup SCCB for Control-Program Identification */ + sccb->header.length = sizeof(struct sclp_ofb_sccb); + sccb->ofb_evbuf.header.length = sizeof(struct sclp_ofb_evbuf); + sccb->ofb_evbuf.header.type = EVTYP_CONFMGMDATA; + sccb->ofb_evbuf.cm_data.ev_qualifier = EV_QUAL_OPEN4BUSINESS; + memcpy(sccb->ofb_evbuf.ev_data, ev_data, len); + + if (!(sclp_conf_register.sclp_receive_mask & EVTYP_CONFMGMDATA_MASK)) + pr_warn("SCLP receiver did not register to receive " + "Configuration Management Data Events.\n"); + + mutex_lock(&send_mutex); + rc = sclp_sync_request(SCLP_CMDW_WRITE_EVENT_DATA, sccb); + mutex_unlock(&send_mutex); + if (rc) + goto out; + response = sccb->header.response_code; + if (response != 0x0020) { + pr_err("Open for Business request failed with response code " + "0x%04x\n", response); + rc = -EIO; + } +out: + free_page((unsigned long)sccb); + return rc; +} + +static ssize_t sysfs_ofb_data_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + int rc; + + rc = sclp_ofb_send_req(buf, count); + return rc ?: count; +} + +static struct bin_attribute ofb_bin_attr = { + .attr = { + .name = "event_data", + .mode = S_IWUSR, + }, + .write = sysfs_ofb_data_write, +}; +#endif + +static int __init sclp_ofb_setup(void) +{ +#ifdef CONFIG_SCLP_OFB + struct kset *ofb_kset; + int rc; + + ofb_kset = kset_create_and_add("ofb", NULL, firmware_kobj); + if (!ofb_kset) + return -ENOMEM; + rc = sysfs_create_bin_file(&ofb_kset->kobj, &ofb_bin_attr); + if (rc) { + kset_unregister(ofb_kset); + return rc; + } +#endif + return 0; +} + static int __init sclp_conf_init(void) { + int rc; + INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify); INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify); - return sclp_register(&sclp_conf_register); + rc = sclp_register(&sclp_conf_register); + if (rc) + return rc; + return sclp_ofb_setup(); } __initcall(sclp_conf_init); -- GitLab From 419123f900dac58fb27ce5285b21074f5300095a Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 19 Nov 2015 11:09:45 +0100 Subject: [PATCH 0721/2855] s390/spinlock: do not yield to a CPU in udelay/mdelay It does not make sense to try to relinquish the time slice with diag 0x9c to a CPU in a state that does not allow to schedule the CPU. The scenario where this can happen is a CPU waiting in udelay/mdelay while holding a spin-lock. Add a CIF bit to tag a CPU in enabled wait and use it to detect that the yield of a CPU will not be successful and skip the diagnose call. Reviewed-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/processor.h | 12 ++++++++++++ arch/s390/kernel/entry.S | 2 ++ arch/s390/lib/spinlock.c | 25 +++++++++++++++++-------- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index b16c3d0a1b9fc..5592c94ebe310 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -18,12 +18,14 @@ #define CIF_NOHZ_DELAY 2 /* delay HZ disable for a tick */ #define CIF_FPU 3 /* restore FPU registers */ #define CIF_IGNORE_IRQ 4 /* ignore interrupt (for udelay) */ +#define CIF_ENABLED_WAIT 5 /* in enabled wait state */ #define _CIF_MCCK_PENDING _BITUL(CIF_MCCK_PENDING) #define _CIF_ASCE _BITUL(CIF_ASCE) #define _CIF_NOHZ_DELAY _BITUL(CIF_NOHZ_DELAY) #define _CIF_FPU _BITUL(CIF_FPU) #define _CIF_IGNORE_IRQ _BITUL(CIF_IGNORE_IRQ) +#define _CIF_ENABLED_WAIT _BITUL(CIF_ENABLED_WAIT) #ifndef __ASSEMBLY__ @@ -52,6 +54,16 @@ static inline int test_cpu_flag(int flag) return !!(S390_lowcore.cpu_flags & (1UL << flag)); } +/* + * Test CIF flag of another CPU. The caller needs to ensure that + * CPU hotplug can not happen, e.g. by disabling preemption. + */ +static inline int test_cpu_flag_of(int flag, int cpu) +{ + struct _lowcore *lc = lowcore_ptr[cpu]; + return !!(lc->cpu_flags & (1UL << flag)); +} + #define arch_needs_cpu() test_cpu_flag(CIF_NOHZ_DELAY) /* diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 857b6526d2983..cd5a191381b94 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -764,6 +764,7 @@ ENTRY(psw_idle) .insn rsy,0xeb0000000017,%r1,5,__SF_EMPTY+16(%r15) .Lpsw_idle_stcctm: #endif + oi __LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT STCK __CLOCK_IDLE_ENTER(%r2) stpt __TIMER_IDLE_ENTER(%r2) .Lpsw_idle_lpsw: @@ -1146,6 +1147,7 @@ cleanup_critical: .quad .Lio_done - 4 .Lcleanup_idle: + ni __LC_CPU_FLAGS+7,255-_CIF_ENABLED_WAIT # copy interrupt clock & cpu timer mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK mvc __TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index 0a68fe04a9e16..d4549c9645892 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c @@ -37,6 +37,15 @@ static inline void _raw_compare_and_delay(unsigned int *lock, unsigned int old) asm(".insn rsy,0xeb0000000022,%0,0,%1" : : "d" (old), "Q" (*lock)); } +static inline int cpu_is_preempted(int cpu) +{ + if (test_cpu_flag_of(CIF_ENABLED_WAIT, cpu)) + return 0; + if (smp_vcpu_scheduled(cpu)) + return 0; + return 1; +} + void arch_spin_lock_wait(arch_spinlock_t *lp) { unsigned int cpu = SPINLOCK_LOCKVAL; @@ -53,7 +62,7 @@ void arch_spin_lock_wait(arch_spinlock_t *lp) continue; } /* First iteration: check if the lock owner is running. */ - if (first_diag && !smp_vcpu_scheduled(~owner)) { + if (first_diag && cpu_is_preempted(~owner)) { smp_yield_cpu(~owner); first_diag = 0; continue; @@ -72,7 +81,7 @@ void arch_spin_lock_wait(arch_spinlock_t *lp) * yield the CPU unconditionally. For LPAR rely on the * sense running status. */ - if (!MACHINE_IS_LPAR || !smp_vcpu_scheduled(~owner)) { + if (!MACHINE_IS_LPAR || cpu_is_preempted(~owner)) { smp_yield_cpu(~owner); first_diag = 0; } @@ -98,7 +107,7 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) local_irq_restore(flags); } /* Check if the lock owner is running. */ - if (first_diag && !smp_vcpu_scheduled(~owner)) { + if (first_diag && cpu_is_preempted(~owner)) { smp_yield_cpu(~owner); first_diag = 0; continue; @@ -117,7 +126,7 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) * yield the CPU unconditionally. For LPAR rely on the * sense running status. */ - if (!MACHINE_IS_LPAR || !smp_vcpu_scheduled(~owner)) { + if (!MACHINE_IS_LPAR || cpu_is_preempted(~owner)) { smp_yield_cpu(~owner); first_diag = 0; } @@ -155,7 +164,7 @@ void _raw_read_lock_wait(arch_rwlock_t *rw) owner = 0; while (1) { if (count-- <= 0) { - if (owner && !smp_vcpu_scheduled(~owner)) + if (owner && cpu_is_preempted(~owner)) smp_yield_cpu(~owner); count = spin_retry; } @@ -201,7 +210,7 @@ void _raw_write_lock_wait(arch_rwlock_t *rw, unsigned int prev) owner = 0; while (1) { if (count-- <= 0) { - if (owner && !smp_vcpu_scheduled(~owner)) + if (owner && cpu_is_preempted(~owner)) smp_yield_cpu(~owner); count = spin_retry; } @@ -231,7 +240,7 @@ void _raw_write_lock_wait(arch_rwlock_t *rw) owner = 0; while (1) { if (count-- <= 0) { - if (owner && !smp_vcpu_scheduled(~owner)) + if (owner && cpu_is_preempted(~owner)) smp_yield_cpu(~owner); count = spin_retry; } @@ -275,7 +284,7 @@ void arch_lock_relax(unsigned int cpu) { if (!cpu) return; - if (MACHINE_IS_LPAR && smp_vcpu_scheduled(~cpu)) + if (MACHINE_IS_LPAR && !cpu_is_preempted(~cpu)) return; smp_yield_cpu(~cpu); } -- GitLab From 3a8d1a73a037e1bf099dbbd477e017607bc3dc20 Mon Sep 17 00:00:00 2001 From: Milo Kim Date: Thu, 26 Nov 2015 15:57:05 +0900 Subject: [PATCH 0722/2855] regulator: add LM363X driver LM363X regulator driver supports LM3631 and LM3632. LM3631 has 5 regulators. LM3632 provides 3 regulators. One boost output and LDOs are used for the display module. Boost voltage is configurable but always on. Supported operations for LDOs are enabled/disabled and voltage change. Two LDOs of LM3632 can be controlled by external pins. Those are configured through the DT properties. Signed-off-by: Milo Kim Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 9 + drivers/regulator/Makefile | 1 + drivers/regulator/lm363x-regulator.c | 309 +++++++++++++++++++++++++++ 3 files changed, 319 insertions(+) create mode 100644 drivers/regulator/lm363x-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 8df0b0e62976d..ca8f46579f010 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -274,6 +274,15 @@ config REGULATOR_ISL6271A help This driver supports ISL6271A voltage regulator chip. +config REGULATOR_LM363X + tristate "TI LM363X voltage regulators" + depends on MFD_TI_LMU + help + This driver supports LM3631 and LM3632 voltage regulators for + the LCD bias. + One boost output voltage is configurable and always on. + Other LDOs are used for the display module. + config REGULATOR_LP3971 tristate "National Semiconductors LP3971 PMIC regulator driver" depends on I2C diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 0f8174913c17b..0ea87cdd389ca 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o obj-$(CONFIG_REGULATOR_HI6421) += hi6421-regulator.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_ISL9305) += isl9305.o +obj-$(CONFIG_REGULATOR_LM363X) += lm363x-regulator.o obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o obj-$(CONFIG_REGULATOR_LP872X) += lp872x.o diff --git a/drivers/regulator/lm363x-regulator.c b/drivers/regulator/lm363x-regulator.c new file mode 100644 index 0000000000000..e1b683e02561b --- /dev/null +++ b/drivers/regulator/lm363x-regulator.c @@ -0,0 +1,309 @@ +/* + * TI LM363X Regulator Driver + * + * Copyright 2015 Texas Instruments + * + * Author: Milo Kim + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* LM3631 */ +#define LM3631_BOOST_VSEL_MAX 0x25 +#define LM3631_LDO_VSEL_MAX 0x28 +#define LM3631_CONT_VSEL_MAX 0x03 +#define LM3631_VBOOST_MIN 4500000 +#define LM3631_VCONT_MIN 1800000 +#define LM3631_VLDO_MIN 4000000 +#define ENABLE_TIME_USEC 1000 + +/* LM3632 */ +#define LM3632_BOOST_VSEL_MAX 0x26 +#define LM3632_LDO_VSEL_MAX 0x29 +#define LM3632_VBOOST_MIN 4500000 +#define LM3632_VLDO_MIN 4000000 + +/* Common */ +#define LM363X_STEP_50mV 50000 +#define LM363X_STEP_500mV 500000 + +struct lm363x_regulator { + struct regmap *regmap; + struct regulator_dev *regulator; +}; + +const int ldo_cont_enable_time[] = { + 0, 2000, 5000, 10000, 20000, 50000, 100000, 200000, +}; + +static int lm363x_regulator_enable_time(struct regulator_dev *rdev) +{ + struct lm363x_regulator *lm363x_regulator = rdev_get_drvdata(rdev); + enum lm363x_regulator_id id = rdev_get_id(rdev); + u8 val, addr, mask; + + switch (id) { + case LM3631_LDO_CONT: + addr = LM3631_REG_ENTIME_VCONT; + mask = LM3631_ENTIME_CONT_MASK; + break; + case LM3631_LDO_OREF: + addr = LM3631_REG_ENTIME_VOREF; + mask = LM3631_ENTIME_MASK; + break; + case LM3631_LDO_POS: + addr = LM3631_REG_ENTIME_VPOS; + mask = LM3631_ENTIME_MASK; + break; + case LM3631_LDO_NEG: + addr = LM3631_REG_ENTIME_VNEG; + mask = LM3631_ENTIME_MASK; + break; + default: + return 0; + } + + if (regmap_read(lm363x_regulator->regmap, addr, (unsigned int *)&val)) + return -EINVAL; + + val = (val & mask) >> LM3631_ENTIME_SHIFT; + + if (id == LM3631_LDO_CONT) + return ldo_cont_enable_time[val]; + else + return ENABLE_TIME_USEC * val; +} + +static struct regulator_ops lm363x_boost_voltage_table_ops = { + .list_voltage = regulator_list_voltage_linear, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, +}; + +static struct regulator_ops lm363x_regulator_voltage_table_ops = { + .list_voltage = regulator_list_voltage_linear, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .enable_time = lm363x_regulator_enable_time, +}; + +static const struct regulator_desc lm363x_regulator_desc[] = { + /* LM3631 */ + { + .name = "vboost", + .of_match = "vboost", + .id = LM3631_BOOST, + .ops = &lm363x_boost_voltage_table_ops, + .n_voltages = LM3631_BOOST_VSEL_MAX + 1, + .min_uV = LM3631_VBOOST_MIN, + .uV_step = LM363X_STEP_50mV, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LM3631_REG_VOUT_BOOST, + .vsel_mask = LM3631_VOUT_MASK, + }, + { + .name = "ldo_cont", + .of_match = "vcont", + .id = LM3631_LDO_CONT, + .ops = &lm363x_regulator_voltage_table_ops, + .n_voltages = LM3631_CONT_VSEL_MAX + 1, + .min_uV = LM3631_VCONT_MIN, + .uV_step = LM363X_STEP_500mV, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LM3631_REG_VOUT_CONT, + .vsel_mask = LM3631_VOUT_CONT_MASK, + .enable_reg = LM3631_REG_LDO_CTRL2, + .enable_mask = LM3631_EN_CONT_MASK, + }, + { + .name = "ldo_oref", + .of_match = "voref", + .id = LM3631_LDO_OREF, + .ops = &lm363x_regulator_voltage_table_ops, + .n_voltages = LM3631_LDO_VSEL_MAX + 1, + .min_uV = LM3631_VLDO_MIN, + .uV_step = LM363X_STEP_50mV, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LM3631_REG_VOUT_OREF, + .vsel_mask = LM3631_VOUT_MASK, + .enable_reg = LM3631_REG_LDO_CTRL1, + .enable_mask = LM3631_EN_OREF_MASK, + }, + { + .name = "ldo_vpos", + .of_match = "vpos", + .id = LM3631_LDO_POS, + .ops = &lm363x_regulator_voltage_table_ops, + .n_voltages = LM3631_LDO_VSEL_MAX + 1, + .min_uV = LM3631_VLDO_MIN, + .uV_step = LM363X_STEP_50mV, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LM3631_REG_VOUT_POS, + .vsel_mask = LM3631_VOUT_MASK, + .enable_reg = LM3631_REG_LDO_CTRL1, + .enable_mask = LM3631_EN_VPOS_MASK, + }, + { + .name = "ldo_vneg", + .of_match = "vneg", + .id = LM3631_LDO_NEG, + .ops = &lm363x_regulator_voltage_table_ops, + .n_voltages = LM3631_LDO_VSEL_MAX + 1, + .min_uV = LM3631_VLDO_MIN, + .uV_step = LM363X_STEP_50mV, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LM3631_REG_VOUT_NEG, + .vsel_mask = LM3631_VOUT_MASK, + .enable_reg = LM3631_REG_LDO_CTRL1, + .enable_mask = LM3631_EN_VNEG_MASK, + }, + /* LM3632 */ + { + .name = "vboost", + .of_match = "vboost", + .id = LM3632_BOOST, + .ops = &lm363x_boost_voltage_table_ops, + .n_voltages = LM3632_BOOST_VSEL_MAX + 1, + .min_uV = LM3632_VBOOST_MIN, + .uV_step = LM363X_STEP_50mV, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LM3632_REG_VOUT_BOOST, + .vsel_mask = LM3632_VOUT_MASK, + }, + { + .name = "ldo_vpos", + .of_match = "vpos", + .id = LM3632_LDO_POS, + .ops = &lm363x_regulator_voltage_table_ops, + .n_voltages = LM3632_LDO_VSEL_MAX + 1, + .min_uV = LM3632_VLDO_MIN, + .uV_step = LM363X_STEP_50mV, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LM3632_REG_VOUT_POS, + .vsel_mask = LM3632_VOUT_MASK, + .enable_reg = LM3632_REG_BIAS_CONFIG, + .enable_mask = LM3632_EN_VPOS_MASK, + }, + { + .name = "ldo_vneg", + .of_match = "vneg", + .id = LM3632_LDO_NEG, + .ops = &lm363x_regulator_voltage_table_ops, + .n_voltages = LM3632_LDO_VSEL_MAX + 1, + .min_uV = LM3632_VLDO_MIN, + .uV_step = LM363X_STEP_50mV, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LM3632_REG_VOUT_NEG, + .vsel_mask = LM3632_VOUT_MASK, + .enable_reg = LM3632_REG_BIAS_CONFIG, + .enable_mask = LM3632_EN_VNEG_MASK, + }, +}; + +static int lm363x_regulator_of_get_enable_gpio(struct device_node *np, int id) +{ + /* + * Check LCM_EN1/2_GPIO is configured. + * Those pins are used for enabling VPOS/VNEG LDOs. + */ + switch (id) { + case LM3632_LDO_POS: + return of_get_named_gpio(np, "ti,lcm-en1-gpio", 0); + case LM3632_LDO_NEG: + return of_get_named_gpio(np, "ti,lcm-en2-gpio", 0); + default: + return -EINVAL; + } +} + +static int lm363x_regulator_probe(struct platform_device *pdev) +{ + struct ti_lmu *lmu = dev_get_drvdata(pdev->dev.parent); + struct lm363x_regulator *lm363x_regulator; + struct regmap *regmap = lmu->regmap; + struct regulator_config cfg = { }; + struct regulator_dev *rdev; + struct device *dev = &pdev->dev; + int id = pdev->id; + int ret, ena_gpio; + + lm363x_regulator = devm_kzalloc(dev, sizeof(*lm363x_regulator), + GFP_KERNEL); + if (!lm363x_regulator) + return -ENOMEM; + + lm363x_regulator->regmap = regmap; + + cfg.dev = dev; + cfg.driver_data = lm363x_regulator; + cfg.regmap = regmap; + + /* + * LM3632 LDOs can be controlled by external pin. + * Register update is required if the pin is used. + */ + ena_gpio = lm363x_regulator_of_get_enable_gpio(dev->of_node, id); + if (gpio_is_valid(ena_gpio)) { + cfg.ena_gpio = ena_gpio; + cfg.ena_gpio_flags = GPIOF_OUT_INIT_LOW; + + ret = regmap_update_bits(regmap, LM3632_REG_BIAS_CONFIG, + LM3632_EXT_EN_MASK, + LM3632_EXT_EN_MASK); + if (ret) { + dev_err(dev, "External pin err: %d\n", ret); + return ret; + } + } + + rdev = devm_regulator_register(dev, &lm363x_regulator_desc[id], &cfg); + if (IS_ERR(rdev)) { + ret = PTR_ERR(rdev); + dev_err(dev, "[%d] regulator register err: %d\n", id, ret); + return ret; + } + + lm363x_regulator->regulator = rdev; + platform_set_drvdata(pdev, lm363x_regulator); + + return 0; +} + +static struct platform_driver lm363x_regulator_driver = { + .probe = lm363x_regulator_probe, + .driver = { + .name = "lm363x-regulator", + }, +}; + +module_platform_driver(lm363x_regulator_driver); + +MODULE_DESCRIPTION("TI LM363X Regulator Driver"); +MODULE_AUTHOR("Milo Kim"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:lm363x-regulator"); -- GitLab From eaea7d27129b9b493c3029608486c157827a92ce Mon Sep 17 00:00:00 2001 From: Milo Kim Date: Thu, 26 Nov 2015 15:57:00 +0900 Subject: [PATCH 0723/2855] regulator: lm363x: add LM363x regulator binding information This binding describes LM3631 and LM3632 regulator properties. Signed-off-by: Milo Kim Signed-off-by: Mark Brown --- .../bindings/regulator/lm363x-regulator.txt | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/lm363x-regulator.txt diff --git a/Documentation/devicetree/bindings/regulator/lm363x-regulator.txt b/Documentation/devicetree/bindings/regulator/lm363x-regulator.txt new file mode 100644 index 0000000000000..8f14df9d12055 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/lm363x-regulator.txt @@ -0,0 +1,34 @@ +TI LMU LM363x regulator device tree bindings + +LM363x regulator driver supports LM3631 and LM3632. +LM3631 has five regulators and LM3632 supports three regulators. + +Required property: + - compatible: "ti,lm363x-regulator" + +Optional properties: + LM3632 has external enable pins for two LDOs. + - ti,lcm-en1-gpio: A GPIO specifier for Vpos control pin. + - ti,lcm-en2-gpio: A GPIO specifier for Vneg control pin. + +Child nodes: + LM3631 + - vboost + - vcont + - voref + - vpos + - vneg + + LM3632 + - vboost + - vpos + - vneg + + Optional properties of a child node: + Each sub-node should contain the constraints and initialization. + Please refer to [1]. + +Examples: Please refer to ti-lmu dt-bindings [2]. + +[1] ../regulator/regulator.txt +[2] ../mfd/ti-lmu.txt -- GitLab From bb41897e38c53458a88b271f2fbcd905ee1f9584 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 27 Nov 2015 14:46:41 +0100 Subject: [PATCH 0724/2855] regulator: core: fix regulator_lock_supply regression As noticed by Geert Uytterhoeven, my patch to avoid a harmless build warning in regulator_lock_supply() was total crap and introduced a real bug: > [ BUG: bad unlock balance detected! ] > kworker/u4:0/6 is trying to release lock (&rdev->mutex) at: > [] regulator_set_voltage+0x38/0x50 we still lock the regulator supplies, but not the actual regulators, so we are missing a lock, and the unlock is unbalanced. This rectifies it by first locking the regulator device itself before using the same loop as before to lock its supplies. Reported-by: Geert Uytterhoeven Signed-off-by: Arnd Bergmann Fixes: 716fec9d1965 ("[SUBMITTED] regulator: core: avoid unused variable warning") Signed-off-by: Mark Brown --- drivers/regulator/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index c70017d5f74bb..daffff83ced2a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -140,7 +140,8 @@ static void regulator_lock_supply(struct regulator_dev *rdev) { int i; - for (i = 0; rdev->supply; rdev = rdev->supply->rdev, i++) + mutex_lock(&rdev->mutex); + for (i = 1; rdev->supply; rdev = rdev->supply->rdev, i++) mutex_lock_nested(&rdev->mutex, i); } -- GitLab From 2adb2743b1c66766aac1c7f70f5101a72b229f93 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 30 Oct 2015 10:00:38 +0200 Subject: [PATCH 0725/2855] dmaengine: ti-dma-crossbar: dra7: Support for eDMA with new bindings Allow the crossbar driver to be used with the eDMA node with non legacy binding. Signed-off-by: Peter Ujfalusi Signed-off-by: Vinod Koul --- drivers/dma/ti-dma-crossbar.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/dma/ti-dma-crossbar.c b/drivers/dma/ti-dma-crossbar.c index a415edbe61b1c..fccf65f890759 100644 --- a/drivers/dma/ti-dma-crossbar.c +++ b/drivers/dma/ti-dma-crossbar.c @@ -278,6 +278,10 @@ static const struct of_device_id ti_dra7_master_match[] = { .compatible = "ti,edma3", .data = (void *)TI_XBAR_EDMA_OFFSET, }, + { + .compatible = "ti,edma3-tpcc", + .data = (void *)TI_XBAR_EDMA_OFFSET, + }, {}, }; -- GitLab From ec9bfa1e1a796ef7acc2e55917c9b8be5a79e70e Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 30 Oct 2015 10:00:36 +0200 Subject: [PATCH 0726/2855] dmaengine: ti-dma-crossbar: dra7: Use bitops instead of idr The use of idr was nice, but it was a bit heavy and we did not need the features it provides. Using simple bitmap to track allocated DMA channels is adequate here and it will be easier to add support for reserving channels later on. Signed-off-by: Peter Ujfalusi Signed-off-by: Vinod Koul --- drivers/dma/ti-dma-crossbar.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/dma/ti-dma-crossbar.c b/drivers/dma/ti-dma-crossbar.c index fccf65f890759..7b1e3ea874bfd 100644 --- a/drivers/dma/ti-dma-crossbar.c +++ b/drivers/dma/ti-dma-crossbar.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -198,7 +197,8 @@ struct ti_dra7_xbar_data { void __iomem *iomem; struct dma_router dmarouter; - struct idr map_idr; + struct mutex mutex; + unsigned long *dma_inuse; u16 safe_val; /* Value to rest the crossbar lines */ u32 xbar_requests; /* number of DMA requests connected to XBAR */ @@ -225,7 +225,9 @@ static void ti_dra7_xbar_free(struct device *dev, void *route_data) map->xbar_in, map->xbar_out); ti_dra7_xbar_write(xbar->iomem, map->xbar_out, xbar->safe_val); - idr_remove(&xbar->map_idr, map->xbar_out); + mutex_lock(&xbar->mutex); + clear_bit(map->xbar_out, xbar->dma_inuse); + mutex_unlock(&xbar->mutex); kfree(map); } @@ -255,8 +257,17 @@ static void *ti_dra7_xbar_route_allocate(struct of_phandle_args *dma_spec, return ERR_PTR(-ENOMEM); } - map->xbar_out = idr_alloc(&xbar->map_idr, NULL, 0, xbar->dma_requests, - GFP_KERNEL); + mutex_lock(&xbar->mutex); + map->xbar_out = find_first_zero_bit(xbar->dma_inuse, + xbar->dma_requests); + mutex_unlock(&xbar->mutex); + if (map->xbar_out == xbar->dma_requests) { + dev_err(&pdev->dev, "Run out of free DMA requests\n"); + kfree(map); + return ERR_PTR(-ENOMEM); + } + set_bit(map->xbar_out, xbar->dma_inuse); + map->xbar_in = (u16)dma_spec->args[0]; dma_spec->args[0] = map->xbar_out + xbar->dma_offset; @@ -303,8 +314,6 @@ static int ti_dra7_xbar_probe(struct platform_device *pdev) if (!xbar) return -ENOMEM; - idr_init(&xbar->map_idr); - dma_node = of_parse_phandle(node, "dma-masters", 0); if (!dma_node) { dev_err(&pdev->dev, "Can't get DMA master node\n"); @@ -326,6 +335,12 @@ static int ti_dra7_xbar_probe(struct platform_device *pdev) } of_node_put(dma_node); + xbar->dma_inuse = devm_kcalloc(&pdev->dev, + BITS_TO_LONGS(xbar->dma_requests), + sizeof(unsigned long), GFP_KERNEL); + if (!xbar->dma_inuse) + return -ENOMEM; + if (of_property_read_u32(node, "dma-requests", &xbar->xbar_requests)) { dev_info(&pdev->dev, "Missing XBAR input information, using %u.\n", @@ -347,6 +362,7 @@ static int ti_dra7_xbar_probe(struct platform_device *pdev) xbar->dmarouter.route_free = ti_dra7_xbar_free; xbar->dma_offset = (u32)match->data; + mutex_init(&xbar->mutex); platform_set_drvdata(pdev, xbar); /* Reset the crossbar */ -- GitLab From 0f73f3e85757091f40019b71077b41a717182b29 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 30 Oct 2015 10:00:37 +0200 Subject: [PATCH 0727/2855] dmaengine: ti-dma-crossbar: dra7: Support for reserving DMA event ranges In eDMA the events are directly mapped to a DMA channel (for example DMA event 14 can only be handled by DMA channel 14). If the memcpy is enabled on the eDMA, there is a possibility that the crossbar driver would assign DMA event number already allocated in eDMA for memcpy. Furthermore the eDMA can be shared with DSP in which case the crossbar driver should also avoid mapping xbar events to DSP used event numbers (or channels). Signed-off-by: Peter Ujfalusi Signed-off-by: Vinod Koul --- .../bindings/dma/ti-dma-crossbar.txt | 6 +++ drivers/dma/ti-dma-crossbar.c | 47 +++++++++++++++++-- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt b/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt index b152a75dceaeb..aead5869a28d9 100644 --- a/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt +++ b/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt @@ -14,6 +14,10 @@ The DMA controller node need to have the following poroperties: Optional properties: - ti,dma-safe-map: Safe routing value for unused request lines +- ti,reserved-dma-request-ranges: DMA request ranges which should not be used + when mapping xbar input to DMA request, they are either + allocated to be used by for example the DSP or they are used as + memcpy channels in eDMA. Notes: When requesting channel via ti,dra7-dma-crossbar, the DMA clinet must request @@ -46,6 +50,8 @@ sdma_xbar: dma-router@4a002b78 { #dma-cells = <1>; dma-requests = <205>; ti,dma-safe-map = <0>; + /* Protect the sDMA request ranges: 10-14 and 100-126 */ + ti,reserved-dma-request-ranges = <10 5>, <100 27>; dma-masters = <&sdma>; }; diff --git a/drivers/dma/ti-dma-crossbar.c b/drivers/dma/ti-dma-crossbar.c index 7b1e3ea874bfd..e107779b1a2e8 100644 --- a/drivers/dma/ti-dma-crossbar.c +++ b/drivers/dma/ti-dma-crossbar.c @@ -296,14 +296,22 @@ static const struct of_device_id ti_dra7_master_match[] = { {}, }; +static inline void ti_dra7_xbar_reserve(int offset, int len, unsigned long *p) +{ + for (; len > 0; len--) + clear_bit(offset + (len - 1), p); +} + static int ti_dra7_xbar_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; const struct of_device_id *match; struct device_node *dma_node; struct ti_dra7_xbar_data *xbar; + struct property *prop; struct resource *res; u32 safe_val; + size_t sz; void __iomem *iomem; int i, ret; @@ -351,6 +359,33 @@ static int ti_dra7_xbar_probe(struct platform_device *pdev) if (!of_property_read_u32(node, "ti,dma-safe-map", &safe_val)) xbar->safe_val = (u16)safe_val; + + prop = of_find_property(node, "ti,reserved-dma-request-ranges", &sz); + if (prop) { + const char pname[] = "ti,reserved-dma-request-ranges"; + u32 (*rsv_events)[2]; + size_t nelm = sz / sizeof(*rsv_events); + int i; + + if (!nelm) + return -EINVAL; + + rsv_events = kcalloc(nelm, sizeof(*rsv_events), GFP_KERNEL); + if (!rsv_events) + return -ENOMEM; + + ret = of_property_read_u32_array(node, pname, (u32 *)rsv_events, + nelm * 2); + if (ret) + return ret; + + for (i = 0; i < nelm; i++) { + ti_dra7_xbar_reserve(rsv_events[i][0], rsv_events[i][1], + xbar->dma_inuse); + } + kfree(rsv_events); + } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); iomem = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(iomem)) @@ -366,15 +401,19 @@ static int ti_dra7_xbar_probe(struct platform_device *pdev) platform_set_drvdata(pdev, xbar); /* Reset the crossbar */ - for (i = 0; i < xbar->dma_requests; i++) - ti_dra7_xbar_write(xbar->iomem, i, xbar->safe_val); + for (i = 0; i < xbar->dma_requests; i++) { + if (!test_bit(i, xbar->dma_inuse)) + ti_dra7_xbar_write(xbar->iomem, i, xbar->safe_val); + } ret = of_dma_router_register(node, ti_dra7_xbar_route_allocate, &xbar->dmarouter); if (ret) { /* Restore the defaults for the crossbar */ - for (i = 0; i < xbar->dma_requests; i++) - ti_dra7_xbar_write(xbar->iomem, i, i); + for (i = 0; i < xbar->dma_requests; i++) { + if (!test_bit(i, xbar->dma_inuse)) + ti_dra7_xbar_write(xbar->iomem, i, i); + } } return ret; -- GitLab From a8bc6ca0707c71fe7085543dc6d76b077e0ae89e Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 29 Nov 2015 14:58:54 +0800 Subject: [PATCH 0728/2855] regulator: lm363x: Remove struct lm363x_regulator which is not necessary Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/lm363x-regulator.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/drivers/regulator/lm363x-regulator.c b/drivers/regulator/lm363x-regulator.c index e1b683e02561b..38587359cd2d4 100644 --- a/drivers/regulator/lm363x-regulator.c +++ b/drivers/regulator/lm363x-regulator.c @@ -41,18 +41,12 @@ #define LM363X_STEP_50mV 50000 #define LM363X_STEP_500mV 500000 -struct lm363x_regulator { - struct regmap *regmap; - struct regulator_dev *regulator; -}; - const int ldo_cont_enable_time[] = { 0, 2000, 5000, 10000, 20000, 50000, 100000, 200000, }; static int lm363x_regulator_enable_time(struct regulator_dev *rdev) { - struct lm363x_regulator *lm363x_regulator = rdev_get_drvdata(rdev); enum lm363x_regulator_id id = rdev_get_id(rdev); u8 val, addr, mask; @@ -77,7 +71,7 @@ static int lm363x_regulator_enable_time(struct regulator_dev *rdev) return 0; } - if (regmap_read(lm363x_regulator->regmap, addr, (unsigned int *)&val)) + if (regmap_read(rdev->regmap, addr, (unsigned int *)&val)) return -EINVAL; val = (val & mask) >> LM3631_ENTIME_SHIFT; @@ -244,7 +238,6 @@ static int lm363x_regulator_of_get_enable_gpio(struct device_node *np, int id) static int lm363x_regulator_probe(struct platform_device *pdev) { struct ti_lmu *lmu = dev_get_drvdata(pdev->dev.parent); - struct lm363x_regulator *lm363x_regulator; struct regmap *regmap = lmu->regmap; struct regulator_config cfg = { }; struct regulator_dev *rdev; @@ -252,15 +245,7 @@ static int lm363x_regulator_probe(struct platform_device *pdev) int id = pdev->id; int ret, ena_gpio; - lm363x_regulator = devm_kzalloc(dev, sizeof(*lm363x_regulator), - GFP_KERNEL); - if (!lm363x_regulator) - return -ENOMEM; - - lm363x_regulator->regmap = regmap; - cfg.dev = dev; - cfg.driver_data = lm363x_regulator; cfg.regmap = regmap; /* @@ -288,9 +273,6 @@ static int lm363x_regulator_probe(struct platform_device *pdev) return ret; } - lm363x_regulator->regulator = rdev; - platform_set_drvdata(pdev, lm363x_regulator); - return 0; } -- GitLab From faa5cf3af39faa9ed1d3fbe14be9c1cf80acbf91 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 29 Nov 2015 15:02:21 +0800 Subject: [PATCH 0729/2855] regulator: lm363x: Staticise ldo_cont_enable_time Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/lm363x-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/lm363x-regulator.c b/drivers/regulator/lm363x-regulator.c index 38587359cd2d4..f53e63301a205 100644 --- a/drivers/regulator/lm363x-regulator.c +++ b/drivers/regulator/lm363x-regulator.c @@ -41,7 +41,7 @@ #define LM363X_STEP_50mV 50000 #define LM363X_STEP_500mV 500000 -const int ldo_cont_enable_time[] = { +static const int ldo_cont_enable_time[] = { 0, 2000, 5000, 10000, 20000, 50000, 100000, 200000, }; -- GitLab From 4fe338c94986df105c3966a39b5a0af608762891 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 28 Nov 2015 15:09:38 +0100 Subject: [PATCH 0730/2855] spi: dw-mid: constify dw_spi_dma_ops structure The dw_spi_dma_ops structure is never modified, so declare it as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Acked-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-dw-mid.c | 2 +- drivers/spi/spi-dw.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index bb1052e748f28..9185f6c084598 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -283,7 +283,7 @@ static void mid_spi_dma_stop(struct dw_spi *dws) } } -static struct dw_spi_dma_ops mid_dma_ops = { +static const struct dw_spi_dma_ops mid_dma_ops = { .dma_init = mid_spi_dma_init, .dma_exit = mid_spi_dma_exit, .dma_setup = mid_spi_dma_setup, diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 35589a270468d..61bc3cbab38d5 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -130,7 +130,7 @@ struct dw_spi { struct dma_chan *rxchan; unsigned long dma_chan_busy; dma_addr_t dma_addr; /* phy address of the Data register */ - struct dw_spi_dma_ops *dma_ops; + const struct dw_spi_dma_ops *dma_ops; void *dma_tx; void *dma_rx; -- GitLab From de2c6e58554c7df3db70c68e52f982e558895ecf Mon Sep 17 00:00:00 2001 From: Joshua Clayton Date: Sat, 28 Nov 2015 13:28:18 -0800 Subject: [PATCH 0731/2855] spi: tools: move spidev_test metadata Now that spidev_test and spidev_fdx have been moved, remove them from the Documentation index and move their .gitignore file. Signed-off-by: Joshua Clayton Signed-off-by: Mark Brown --- Documentation/spi/00-INDEX | 4 ---- {Documentation => tools}/spi/.gitignore | 0 2 files changed, 4 deletions(-) rename {Documentation => tools}/spi/.gitignore (100%) diff --git a/Documentation/spi/00-INDEX b/Documentation/spi/00-INDEX index a128fa8355129..4644bf0d9832e 100644 --- a/Documentation/spi/00-INDEX +++ b/Documentation/spi/00-INDEX @@ -10,13 +10,9 @@ pxa2xx - PXA2xx SPI master controller build by spi_message fifo wq spidev - Intro to the userspace API for spi devices -spidev_fdx.c - - spidev example file spi-lm70llp - Connecting an LM70-LLP sensor to the kernel via the SPI subsys. spi-sc18is602 - NXP SC18IS602/603 I2C-bus to SPI bridge spi-summary - (Linux) SPI overview. If unsure about SPI or SPI in Linux, start here. -spidev_test.c - - SPI testing utility. diff --git a/Documentation/spi/.gitignore b/tools/spi/.gitignore similarity index 100% rename from Documentation/spi/.gitignore rename to tools/spi/.gitignore -- GitLab From e43e0df13f8528ca55ed79f469c4b2af897fa796 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 19 Nov 2015 16:56:41 +0100 Subject: [PATCH 0732/2855] i2c: rcar: make sure clocks are on when doing clock calculation When calculating the bus speed, the clock should be on, of course. Most bootloaders left them on, so this went unnoticed so far. Move the ioremapping out of this clock-enabled-block and prepare for adding hw initialization there, too. Reported-by: Kuninori Morimoto Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index b0ae560b38c30..dac0f5d194534 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -650,19 +650,23 @@ static int rcar_i2c_probe(struct platform_device *pdev) return PTR_ERR(priv->clk); } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->io = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->io)) + return PTR_ERR(priv->io); + bus_speed = 100000; /* default 100 kHz */ of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed); priv->devtype = (enum rcar_i2c_type)of_match_device(rcar_i2c_dt_ids, dev)->data; + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); ret = rcar_i2c_clock_calculate(priv, bus_speed, dev); if (ret < 0) - return ret; + goto out_pm_put; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->io = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->io)) - return PTR_ERR(priv->io); + pm_runtime_put(dev); irq = platform_get_irq(pdev, 0); init_waitqueue_head(&priv->wait); @@ -682,22 +686,26 @@ static int rcar_i2c_probe(struct platform_device *pdev) dev_name(dev), priv); if (ret < 0) { dev_err(dev, "cannot get irq %d\n", irq); - return ret; + goto out_pm_disable; } - pm_runtime_enable(dev); platform_set_drvdata(pdev, priv); ret = i2c_add_numbered_adapter(adap); if (ret < 0) { dev_err(dev, "reg adap failed: %d\n", ret); - pm_runtime_disable(dev); - return ret; + goto out_pm_disable; } dev_info(dev, "probed\n"); return 0; + + out_pm_put: + pm_runtime_put(dev); + out_pm_disable: + pm_runtime_disable(dev); + return ret; } static int rcar_i2c_remove(struct platform_device *pdev) -- GitLab From 2c78cdc1c06308a59d6ed4145cdba73fdeff8c0d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 19 Nov 2015 16:56:42 +0100 Subject: [PATCH 0733/2855] i2c: rcar: rework hw init We don't need to init HW before every transfer since we know the HW state then. HW init at probe time is enough. While here, add setting the clock register which belongs to init HW. Also, set MDBS bit since not setting it is prohibited according to the manual. Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index dac0f5d194534..efc8de6cc8a2f 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -144,9 +144,10 @@ static void rcar_i2c_init(struct rcar_i2c_priv *priv) { /* reset master mode */ rcar_i2c_write(priv, ICMIER, 0); - rcar_i2c_write(priv, ICMCR, 0); + rcar_i2c_write(priv, ICMCR, MDBS); rcar_i2c_write(priv, ICMSR, 0); - rcar_i2c_write(priv, ICMAR, 0); + /* start clock */ + rcar_i2c_write(priv, ICCCR, priv->icccr); } static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv) @@ -496,16 +497,6 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, pm_runtime_get_sync(dev); - /*-------------- spin lock -----------------*/ - spin_lock_irqsave(&priv->lock, flags); - - rcar_i2c_init(priv); - /* start clock */ - rcar_i2c_write(priv, ICCCR, priv->icccr); - - spin_unlock_irqrestore(&priv->lock, flags); - /*-------------- spin unlock -----------------*/ - ret = rcar_i2c_bus_barrier(priv); if (ret < 0) goto out; @@ -666,6 +657,7 @@ static int rcar_i2c_probe(struct platform_device *pdev) if (ret < 0) goto out_pm_put; + rcar_i2c_init(priv); pm_runtime_put(dev); irq = platform_get_irq(pdev, 0); -- GitLab From 90f779e565bdc18dd4f79d81cf11f43a7266010b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 19 Nov 2015 16:56:43 +0100 Subject: [PATCH 0734/2855] i2c: rcar: remove unused IOERROR state Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index efc8de6cc8a2f..746406923a582 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -94,7 +94,6 @@ #define RCAR_IRQ_ACK_RECV (~(MAT | MDR) & 0xFF) #define ID_LAST_MSG (1 << 0) -#define ID_IOERROR (1 << 1) #define ID_DONE (1 << 2) #define ID_ARBLOST (1 << 3) #define ID_NACK (1 << 4) @@ -541,11 +540,6 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, break; } - if (rcar_i2c_flags_has(priv, ID_IOERROR)) { - ret = -EIO; - break; - } - ret = i + 1; /* The number of transfer */ } out: -- GitLab From ff2316b87a336bff940939cd9fc56287ed48e578 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 19 Nov 2015 16:56:44 +0100 Subject: [PATCH 0735/2855] i2c: rcar: remove spinlock After making sure to reinit the HW and clear interrupts in the timeout case, we know that interrupts are always disabled in the sections protected by the spinlock. Thus, we can simply remove it which is a preparation for further refactoring. While here, rename the timeout variable to time_left which is way more readable. Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index 746406923a582..0f2dc74ab8bcc 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -33,7 +33,6 @@ #include #include #include -#include /* register offsets */ #define ICSCR 0x00 /* slave ctrl */ @@ -110,7 +109,6 @@ struct rcar_i2c_priv { struct i2c_msg *msg; struct clk *clk; - spinlock_t lock; wait_queue_head_t wait; int pos; @@ -429,9 +427,6 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) irqreturn_t result = IRQ_HANDLED; u32 msr; - /*-------------- spin lock -----------------*/ - spin_lock(&priv->lock); - if (rcar_i2c_slave_irq(priv)) goto exit; @@ -478,9 +473,6 @@ out: } exit: - spin_unlock(&priv->lock); - /*-------------- spin unlock -----------------*/ - return result; } @@ -490,9 +482,8 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, { struct rcar_i2c_priv *priv = i2c_get_adapdata(adap); struct device *dev = rcar_i2c_priv_to_dev(priv); - unsigned long flags; int i, ret; - long timeout; + long time_left; pm_runtime_get_sync(dev); @@ -507,9 +498,6 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, break; } - /*-------------- spin lock -----------------*/ - spin_lock_irqsave(&priv->lock, flags); - /* init each data */ priv->msg = &msgs[i]; priv->pos = 0; @@ -519,13 +507,11 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, rcar_i2c_prepare_msg(priv); - spin_unlock_irqrestore(&priv->lock, flags); - /*-------------- spin unlock -----------------*/ - - timeout = wait_event_timeout(priv->wait, + time_left = wait_event_timeout(priv->wait, rcar_i2c_flags_has(priv, ID_DONE), adap->timeout); - if (!timeout) { + if (!time_left) { + rcar_i2c_init(priv); ret = -ETIMEDOUT; break; } @@ -656,7 +642,6 @@ static int rcar_i2c_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); init_waitqueue_head(&priv->wait); - spin_lock_init(&priv->lock); adap = &priv->adap; adap->nr = pdev->id; -- GitLab From b9d0684c79c4b9d30ce0d47d3270493dd0e76e59 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 19 Nov 2015 16:56:45 +0100 Subject: [PATCH 0736/2855] i2c: rcar: refactor setup of a msg We want to reuse this function later. Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index 0f2dc74ab8bcc..4bd3099865b48 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -106,7 +106,8 @@ enum rcar_i2c_type { struct rcar_i2c_priv { void __iomem *io; struct i2c_adapter adap; - struct i2c_msg *msg; + struct i2c_msg *msg; + int msgs_left; struct clk *clk; wait_queue_head_t wait; @@ -255,6 +256,11 @@ static void rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv) { int read = !!rcar_i2c_is_recv(priv); + priv->pos = 0; + priv->flags = 0; + if (priv->msgs_left == 1) + rcar_i2c_flags_set(priv, ID_LAST_MSG); + rcar_i2c_write(priv, ICMAR, (priv->msg->addr << 1) | read); rcar_i2c_write(priv, ICMSR, 0); rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START); @@ -499,11 +505,8 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, } /* init each data */ - priv->msg = &msgs[i]; - priv->pos = 0; - priv->flags = 0; - if (i == num - 1) - rcar_i2c_flags_set(priv, ID_LAST_MSG); + priv->msg = &msgs[i]; + priv->msgs_left = num - i; rcar_i2c_prepare_msg(priv); -- GitLab From cc21d0b4b62e41e5013d763adade5ea4462c33a4 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 19 Nov 2015 16:56:46 +0100 Subject: [PATCH 0737/2855] i2c: rcar: init new messages in irq Setting up new messages was done in process context while handling a message was in interrupt context. Because of the HW design, this IP core is sensitive to timing, so the context switches were too expensive. Move this setup to interrupt context as well. In my test setup, this fixed the occasional 'data byte sent twice' issue which a number of people have seen. It also fixes to send REP_START after a read message which was wrongly send as a STOP + START sequence before. Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 90 +++++++++++++++++------------------ 1 file changed, 43 insertions(+), 47 deletions(-) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index 4bd3099865b48..d91acc1163155 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -267,10 +267,17 @@ static void rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv) rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND); } +static void rcar_i2c_next_msg(struct rcar_i2c_priv *priv) +{ + priv->msg++; + priv->msgs_left--; + rcar_i2c_prepare_msg(priv); +} + /* * interrupt functions */ -static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr) +static void rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr) { struct i2c_msg *msg = priv->msg; @@ -280,7 +287,7 @@ static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr) * Do nothing */ if (!(msr & MDE)) - return 0; + return; /* * If address transfer phase finished, @@ -309,29 +316,23 @@ static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr) * [ICRXTX] -> [SHIFT] -> [I2C bus] */ - if (priv->flags & ID_LAST_MSG) + if (priv->flags & ID_LAST_MSG) { /* * If current msg is the _LAST_ msg, * prepare stop condition here. * ID_DONE will be set on STOP irq. */ rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP); - else - /* - * If current msg is _NOT_ last msg, - * it doesn't call stop phase. - * thus, there is no STOP irq. - * return ID_DONE here. - */ - return ID_DONE; + } else { + rcar_i2c_next_msg(priv); + return; + } } rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_SEND); - - return 0; } -static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) +static void rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) { struct i2c_msg *msg = priv->msg; @@ -341,7 +342,7 @@ static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) * Do nothing */ if (!(msr & MDR)) - return 0; + return; if (msr & MAT) { /* @@ -367,9 +368,10 @@ static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) else rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); - rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_RECV); - - return 0; + if (priv->pos == msg->len && !(priv->flags & ID_LAST_MSG)) + rcar_i2c_next_msg(priv); + else + rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_RECV); } static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv) @@ -462,14 +464,15 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) /* Stop */ if (msr & MST) { + priv->msgs_left--; /* The last message also made it */ rcar_i2c_flags_set(priv, ID_DONE); goto out; } if (rcar_i2c_is_recv(priv)) - rcar_i2c_flags_set(priv, rcar_i2c_irq_recv(priv, msr)); + rcar_i2c_irq_recv(priv, msr); else - rcar_i2c_flags_set(priv, rcar_i2c_irq_send(priv, msr)); + rcar_i2c_irq_send(priv, msr); out: if (rcar_i2c_flags_has(priv, ID_DONE)) { @@ -501,35 +504,28 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, /* This HW can't send STOP after address phase */ if (msgs[i].len == 0) { ret = -EOPNOTSUPP; - break; - } - - /* init each data */ - priv->msg = &msgs[i]; - priv->msgs_left = num - i; - - rcar_i2c_prepare_msg(priv); - - time_left = wait_event_timeout(priv->wait, - rcar_i2c_flags_has(priv, ID_DONE), - adap->timeout); - if (!time_left) { - rcar_i2c_init(priv); - ret = -ETIMEDOUT; - break; - } - - if (rcar_i2c_flags_has(priv, ID_NACK)) { - ret = -ENXIO; - break; - } - - if (rcar_i2c_flags_has(priv, ID_ARBLOST)) { - ret = -EAGAIN; - break; + goto out; } + } - ret = i + 1; /* The number of transfer */ + /* init data */ + priv->msg = msgs; + priv->msgs_left = num; + + rcar_i2c_prepare_msg(priv); + + time_left = wait_event_timeout(priv->wait, + rcar_i2c_flags_has(priv, ID_DONE), + num * adap->timeout); + if (!time_left) { + rcar_i2c_init(priv); + ret = -ETIMEDOUT; + } else if (rcar_i2c_flags_has(priv, ID_NACK)) { + ret = -ENXIO; + } else if (rcar_i2c_flags_has(priv, ID_ARBLOST)) { + ret = -EAGAIN; + } else { + ret = num - priv->msgs_left; /* The number of transfer */ } out: pm_runtime_put(dev); -- GitLab From d89667b14f9d13b684287f6189ca209af5feee43 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 19 Nov 2015 16:56:47 +0100 Subject: [PATCH 0738/2855] i2c: rcar: don't issue stop when HW does it automatically The manual says (55.4.8.6) that HW does automatically send STOP after NACK was received. My measuerments confirm that. Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index d91acc1163155..87fccf20fc4c3 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -455,8 +455,8 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) /* Nack */ if (msr & MNR) { - /* go to stop phase */ - rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP); + /* HW automatically sends STOP after received NACK */ + rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); rcar_i2c_write(priv, ICMIER, RCAR_IRQ_STOP); rcar_i2c_flags_set(priv, ID_NACK); goto out; -- GitLab From c3be0af15959e11fa535d5332ab3d7cf34abd09b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 19 Nov 2015 16:56:48 +0100 Subject: [PATCH 0739/2855] i2c: rcar: check master irqs before slave irqs Due to the HW design, master IRQs are timing critical, so give them precedence over slave IRQ. Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index 87fccf20fc4c3..f237b4fc5b5e5 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -432,19 +432,17 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv) static irqreturn_t rcar_i2c_irq(int irq, void *ptr) { struct rcar_i2c_priv *priv = ptr; - irqreturn_t result = IRQ_HANDLED; u32 msr; - if (rcar_i2c_slave_irq(priv)) - goto exit; - msr = rcar_i2c_read(priv, ICMSR); /* Only handle interrupts that are currently enabled */ msr &= rcar_i2c_read(priv, ICMIER); if (!msr) { - result = IRQ_NONE; - goto exit; + if (rcar_i2c_slave_irq(priv)) + return IRQ_HANDLED; + + return IRQ_NONE; } /* Arbitration lost */ @@ -481,8 +479,7 @@ out: wake_up(&priv->wait); } -exit: - return result; + return IRQ_HANDLED; } static int rcar_i2c_master_xfer(struct i2c_adapter *adap, -- GitLab From 52df445f29b79006d8b2dcd129152987c0d3bd64 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 19 Nov 2015 16:56:49 +0100 Subject: [PATCH 0740/2855] i2c: rcar: revoke START request early If we don't clear START generation as soon as possible, it may cause another message to be generated, e.g. when receiving NACK in address phase. To keep the race window as small as possible, we clear it right at the beginning of the interrupt. We don't need any checks since we always want to stop START and STOP generation on the next occasion after we started it. This patch improves the situation but sadly does not completely fix it. It is still to be researched if we can do better given this HW design. Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index f237b4fc5b5e5..4097913020093 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -83,6 +83,7 @@ #define RCAR_BUS_PHASE_START (MDBS | MIE | ESG) #define RCAR_BUS_PHASE_DATA (MDBS | MIE) +#define RCAR_BUS_MASK_DATA (~(ESG | FSB) & 0xFF) #define RCAR_BUS_PHASE_STOP (MDBS | MIE | FSB) #define RCAR_IRQ_SEND (MNR | MAL | MST | MAT | MDE) @@ -289,13 +290,6 @@ static void rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr) if (!(msr & MDE)) return; - /* - * If address transfer phase finished, - * goto data phase. - */ - if (msr & MAT) - rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); - if (priv->pos < msg->len) { /* * Prepare next data to ICRXTX register. @@ -345,11 +339,7 @@ static void rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) return; if (msr & MAT) { - /* - * Address transfer phase finished, - * but, there is no data at this point. - * Do nothing. - */ + /* Address transfer phase finished, but no data at this point. */ } else if (priv->pos < msg->len) { /* * get received data @@ -365,8 +355,6 @@ static void rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) */ if (priv->pos + 1 >= msg->len) rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP); - else - rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); if (priv->pos == msg->len && !(priv->flags & ID_LAST_MSG)) rcar_i2c_next_msg(priv); @@ -432,7 +420,11 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv) static irqreturn_t rcar_i2c_irq(int irq, void *ptr) { struct rcar_i2c_priv *priv = ptr; - u32 msr; + u32 msr, val; + + /* Clear START or STOP as soon as we can */ + val = rcar_i2c_read(priv, ICMCR); + rcar_i2c_write(priv, ICMCR, val & RCAR_BUS_MASK_DATA); msr = rcar_i2c_read(priv, ICMSR); @@ -454,7 +446,6 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) /* Nack */ if (msr & MNR) { /* HW automatically sends STOP after received NACK */ - rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); rcar_i2c_write(priv, ICMIER, RCAR_IRQ_STOP); rcar_i2c_flags_set(priv, ID_NACK); goto out; -- GitLab From 3c2b1ff3e5b37a710f7766f8dce6d9f732e3f902 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 19 Nov 2015 16:56:50 +0100 Subject: [PATCH 0741/2855] i2c: rcar: clean up after refactoring Update the comments to match current behaviour. Shorten some comments. Update copyrights. Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index 4097913020093..e71fd4090247a 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -1,7 +1,8 @@ /* * Driver for the Renesas RCar I2C unit * - * Copyright (C) 2014 Wolfram Sang + * Copyright (C) 2014-15 Wolfram Sang + * Copyright (C) 2011-2015 Renesas Electronics Corporation * * Copyright (C) 2012-14 Renesas Solutions Corp. * Kuninori Morimoto @@ -9,9 +10,6 @@ * This file is based on the drivers/i2c/busses/i2c-sh7760.c * (c) 2005-2008 MSC Vertriebsges.m.b.H, Manuel Lauss * - * This file used out-of-tree driver i2c-rcar.c - * Copyright (C) 2011-2012 Renesas Electronics Corporation - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. @@ -245,9 +243,7 @@ scgd_find: dev_dbg(dev, "clk %d/%d(%lu), round %u, CDF:0x%x, SCGD: 0x%x\n", scl, bus_speed, clk_get_rate(priv->clk), round, cdf, scgd); - /* - * keep icccr value - */ + /* keep icccr value */ priv->icccr = scgd << cdf_width | cdf; return 0; @@ -282,11 +278,7 @@ static void rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr) { struct i2c_msg *msg = priv->msg; - /* - * FIXME - * sometimes, unknown interrupt happened. - * Do nothing - */ + /* FIXME: sometimes, unknown interrupt happened. Do nothing */ if (!(msr & MDE)) return; @@ -330,28 +322,22 @@ static void rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) { struct i2c_msg *msg = priv->msg; - /* - * FIXME - * sometimes, unknown interrupt happened. - * Do nothing - */ + /* FIXME: sometimes, unknown interrupt happened. Do nothing */ if (!(msr & MDR)) return; if (msr & MAT) { /* Address transfer phase finished, but no data at this point. */ } else if (priv->pos < msg->len) { - /* - * get received data - */ + /* get received data */ msg->buf[priv->pos] = rcar_i2c_read(priv, ICRXTX); priv->pos++; } /* - * If next received data is the _LAST_, - * go to STOP phase, - * otherwise, go to DATA phase. + * If next received data is the _LAST_, go to STOP phase. Might be + * overwritten by REP START when setting up a new msg. Not elegant + * but the only stable sequence for REP START I have found so far. */ if (priv->pos + 1 >= msg->len) rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP); -- GitLab From e49865d10ad563fda56bfe3c385948f88b41b1af Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 19 Nov 2015 16:56:51 +0100 Subject: [PATCH 0742/2855] i2c: rcar: handle difference in setting up non-first message Signed-off-by: Ryo Kataoka Signed-off-by: Hiromitsu Yamasaki Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index e71fd4090247a..3ed1f0aa5eeb1 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -92,6 +92,7 @@ #define RCAR_IRQ_ACK_RECV (~(MAT | MDR) & 0xFF) #define ID_LAST_MSG (1 << 0) +#define ID_FIRST_MSG (1 << 1) #define ID_DONE (1 << 2) #define ID_ARBLOST (1 << 3) #define ID_NACK (1 << 4) @@ -254,13 +255,22 @@ static void rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv) int read = !!rcar_i2c_is_recv(priv); priv->pos = 0; - priv->flags = 0; if (priv->msgs_left == 1) rcar_i2c_flags_set(priv, ID_LAST_MSG); rcar_i2c_write(priv, ICMAR, (priv->msg->addr << 1) | read); - rcar_i2c_write(priv, ICMSR, 0); - rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START); + /* + * We don't have a testcase but the HW engineers say that the write order + * of ICMSR and ICMCR depends on whether we issue START or REP_START. Since + * it didn't cause a drawback for me, let's rather be safe than sorry. + */ + if (rcar_i2c_flags_has(priv, ID_FIRST_MSG)) { + rcar_i2c_write(priv, ICMSR, 0); + rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START); + } else { + rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START); + rcar_i2c_write(priv, ICMSR, 0); + } rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND); } @@ -268,6 +278,7 @@ static void rcar_i2c_next_msg(struct rcar_i2c_priv *priv) { priv->msg++; priv->msgs_left--; + priv->flags = 0; rcar_i2c_prepare_msg(priv); } @@ -482,10 +493,10 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, } } - /* init data */ + /* init first message */ priv->msg = msgs; priv->msgs_left = num; - + priv->flags = ID_FIRST_MSG; rcar_i2c_prepare_msg(priv); time_left = wait_event_timeout(priv->wait, -- GitLab From ca2061e1283b787b49e3f6817645b9f0a2151671 Mon Sep 17 00:00:00 2001 From: Christian Fetzer Date: Thu, 19 Nov 2015 20:13:47 +0100 Subject: [PATCH 0743/2855] i2c: piix4: Convert piix4_main_adapter to array The SB800 chipset supports a multiplexed main SMBus controller with four ports. Therefore the static variable piix4_main_adapter is converted into a piix4_main_adapters array that can hold one i2c_adapter for each multiplexed port. The auxiliary adapter remains unchanged since it represents the second (not multiplexed) SMBus controller on the SB800 chipset. Signed-off-by: Christian Fetzer Reviewed-by: Mika Westerberg Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-piix4.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 630bce68bf381..9c32eb124b728 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -75,6 +75,9 @@ #define PIIX4_WORD_DATA 0x0C #define PIIX4_BLOCK_DATA 0x14 +/* Multi-port constants */ +#define PIIX4_MAX_ADAPTERS 4 + /* insmod parameters */ /* If force is set to anything different from 0, we forcibly enable the @@ -561,7 +564,7 @@ static const struct pci_device_id piix4_ids[] = { MODULE_DEVICE_TABLE (pci, piix4_ids); -static struct i2c_adapter *piix4_main_adapter; +static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS]; static struct i2c_adapter *piix4_aux_adapter; static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, @@ -629,7 +632,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) return retval; /* Try to register main SMBus adapter, give up if we can't */ - retval = piix4_add_adapter(dev, retval, &piix4_main_adapter); + retval = piix4_add_adapter(dev, retval, &piix4_main_adapters[0]); if (retval < 0) return retval; @@ -674,9 +677,13 @@ static void piix4_adap_remove(struct i2c_adapter *adap) static void piix4_remove(struct pci_dev *dev) { - if (piix4_main_adapter) { - piix4_adap_remove(piix4_main_adapter); - piix4_main_adapter = NULL; + int port = PIIX4_MAX_ADAPTERS; + + while (--port >= 0) { + if (piix4_main_adapters[port]) { + piix4_adap_remove(piix4_main_adapters[port]); + piix4_main_adapters[port] = NULL; + } } if (piix4_aux_adapter) { -- GitLab From 2fee61d22e606fc99ade9079fda15fdee83ec33e Mon Sep 17 00:00:00 2001 From: Christian Fetzer Date: Thu, 19 Nov 2015 20:13:48 +0100 Subject: [PATCH 0744/2855] i2c: piix4: Add support for multiplexed main adapter in SB800 The SB800 chipset supports a multiplexed main SMBus controller with four ports. The multiplexed ports share the same SMBus address and register set. The port is selected by bits 2:1 of the smb_en register (0x2C). Only one port can be active at any point in time therefore a mutex is needed in order to synchronize access. Additionally, the commit avoids requesting and releasing the SMBus base address index region on every multiplexed transfer by moving the request_region call into piix4_probe. Tested on HP ProLiant MicroServer G7 N54L (where this patch adds support to access sensor data from the w83795adg). Cc: Thomas Brandon Cc: Eddi De Pieri Signed-off-by: Christian Fetzer Reviewed-by: Mika Westerberg Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-piix4.c | 169 ++++++++++++++++++++++++++++----- 1 file changed, 147 insertions(+), 22 deletions(-) diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 9c32eb124b728..6b4231d406d5c 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -23,6 +23,9 @@ Note: we assume there can only be one device, with one or more SMBus interfaces. + The device can register multiple i2c_adapters (up to PIIX4_MAX_ADAPTERS). + For devices supporting multiple ports the i2c_adapter should provide + an i2c_algorithm to access them. */ #include @@ -37,6 +40,7 @@ #include #include #include +#include /* PIIX4 SMBus address offsets */ @@ -78,6 +82,13 @@ /* Multi-port constants */ #define PIIX4_MAX_ADAPTERS 4 +/* SB800 constants */ +#define SB800_PIIX4_SMB_IDX 0xcd6 + +/* SB800 port is selected by bits 2:1 of the smb_en register (0x2c) */ +#define SB800_PIIX4_PORT_IDX 0x2c +#define SB800_PIIX4_PORT_IDX_MASK 0x06 + /* insmod parameters */ /* If force is set to anything different from 0, we forcibly enable the @@ -127,6 +138,11 @@ static const struct dmi_system_id piix4_dmi_ibm[] = { struct i2c_piix4_adapdata { unsigned short smba; + + /* SB800 */ + bool sb800_main; + unsigned short port; + struct mutex *mutex; }; static int piix4_setup(struct pci_dev *PIIX4_dev, @@ -232,7 +248,6 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, const struct pci_device_id *id, u8 aux) { unsigned short piix4_smba; - unsigned short smba_idx = 0xcd6; u8 smba_en_lo, smba_en_hi, smb_en, smb_en_status; u8 i2ccfg, i2ccfg_offset = 0x10; @@ -254,16 +269,10 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, else smb_en = (aux) ? 0x28 : 0x2c; - if (!request_region(smba_idx, 2, "smba_idx")) { - dev_err(&PIIX4_dev->dev, "SMBus base address index region " - "0x%x already in use!\n", smba_idx); - return -EBUSY; - } - outb_p(smb_en, smba_idx); - smba_en_lo = inb_p(smba_idx + 1); - outb_p(smb_en + 1, smba_idx); - smba_en_hi = inb_p(smba_idx + 1); - release_region(smba_idx, 2); + outb_p(smb_en, SB800_PIIX4_SMB_IDX); + smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); + outb_p(smb_en + 1, SB800_PIIX4_SMB_IDX); + smba_en_hi = inb_p(SB800_PIIX4_SMB_IDX + 1); if (!smb_en) { smb_en_status = smba_en_lo & 0x10; @@ -527,6 +536,43 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr, return 0; } +/* + * Handles access to multiple SMBus ports on the SB800. + * The port is selected by bits 2:1 of the smb_en register (0x2c). + * Returns negative errno on error. + * + * Note: The selected port must be returned to the initial selection to avoid + * problems on certain systems. + */ +static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, union i2c_smbus_data *data) +{ + struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(adap); + u8 smba_en_lo; + u8 port; + int retval; + + mutex_lock(adapdata->mutex); + + outb_p(SB800_PIIX4_PORT_IDX, SB800_PIIX4_SMB_IDX); + smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); + + port = adapdata->port; + if ((smba_en_lo & SB800_PIIX4_PORT_IDX_MASK) != (port << 1)) + outb_p((smba_en_lo & ~SB800_PIIX4_PORT_IDX_MASK) | (port << 1), + SB800_PIIX4_SMB_IDX + 1); + + retval = piix4_access(adap, addr, flags, read_write, + command, size, data); + + outb_p(smba_en_lo, SB800_PIIX4_SMB_IDX + 1); + + mutex_unlock(adapdata->mutex); + + return retval; +} + static u32 piix4_func(struct i2c_adapter *adapter) { return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | @@ -539,6 +585,11 @@ static const struct i2c_algorithm smbus_algorithm = { .functionality = piix4_func, }; +static const struct i2c_algorithm piix4_smbus_algorithm_sb800 = { + .smbus_xfer = piix4_access_sb800, + .functionality = piix4_func, +}; + static const struct pci_device_id piix4_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3) }, @@ -614,6 +665,53 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, return 0; } +static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba) +{ + struct mutex *mutex; + struct i2c_piix4_adapdata *adapdata; + int port; + int retval; + + mutex = kzalloc(sizeof(*mutex), GFP_KERNEL); + if (mutex == NULL) + return -ENOMEM; + + mutex_init(mutex); + + for (port = 0; port < PIIX4_MAX_ADAPTERS; port++) { + retval = piix4_add_adapter(dev, smba, + &piix4_main_adapters[port]); + if (retval < 0) + goto error; + + piix4_main_adapters[port]->algo = &piix4_smbus_algorithm_sb800; + + adapdata = i2c_get_adapdata(piix4_main_adapters[port]); + adapdata->sb800_main = true; + adapdata->port = port; + adapdata->mutex = mutex; + } + + return retval; + +error: + dev_err(&dev->dev, + "Error setting up SB800 adapters. Unregistering!\n"); + while (--port >= 0) { + adapdata = i2c_get_adapdata(piix4_main_adapters[port]); + if (adapdata->smba) { + i2c_del_adapter(piix4_main_adapters[port]); + kfree(adapdata); + kfree(piix4_main_adapters[port]); + piix4_main_adapters[port] = NULL; + } + } + + kfree(mutex); + + return retval; +} + static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) { int retval; @@ -621,20 +719,41 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) if ((dev->vendor == PCI_VENDOR_ID_ATI && dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && dev->revision >= 0x40) || - dev->vendor == PCI_VENDOR_ID_AMD) + dev->vendor == PCI_VENDOR_ID_AMD) { + if (!request_region(SB800_PIIX4_SMB_IDX, 2, "smba_idx")) { + dev_err(&dev->dev, + "SMBus base address index region 0x%x already in use!\n", + SB800_PIIX4_SMB_IDX); + return -EBUSY; + } + /* base address location etc changed in SB800 */ retval = piix4_setup_sb800(dev, id, 0); - else - retval = piix4_setup(dev, id); + if (retval < 0) { + release_region(SB800_PIIX4_SMB_IDX, 2); + return retval; + } - /* If no main SMBus found, give up */ - if (retval < 0) - return retval; + /* + * Try to register multiplexed main SMBus adapter, + * give up if we can't + */ + retval = piix4_add_adapters_sb800(dev, retval); + if (retval < 0) { + release_region(SB800_PIIX4_SMB_IDX, 2); + return retval; + } + } else { + retval = piix4_setup(dev, id); + if (retval < 0) + return retval; - /* Try to register main SMBus adapter, give up if we can't */ - retval = piix4_add_adapter(dev, retval, &piix4_main_adapters[0]); - if (retval < 0) - return retval; + /* Try to register main SMBus adapter, give up if we can't */ + retval = piix4_add_adapter(dev, retval, + &piix4_main_adapters[0]); + if (retval < 0) + return retval; + } /* Check for auxiliary SMBus on some AMD chipsets */ retval = -ENODEV; @@ -669,7 +788,13 @@ static void piix4_adap_remove(struct i2c_adapter *adap) if (adapdata->smba) { i2c_del_adapter(adap); - release_region(adapdata->smba, SMBIOSIZE); + if (adapdata->port == 0) { + release_region(adapdata->smba, SMBIOSIZE); + if (adapdata->sb800_main) { + kfree(adapdata->mutex); + release_region(SB800_PIIX4_SMB_IDX, 2); + } + } kfree(adapdata); kfree(adap); } -- GitLab From 725d2e3facfb51f8925da3cadce5380b5ea85d09 Mon Sep 17 00:00:00 2001 From: Christian Fetzer Date: Thu, 19 Nov 2015 20:13:49 +0100 Subject: [PATCH 0745/2855] i2c: piix4: Add adapter port name support for SB800 chipset This patch adds support for port names for the SB800 chipset. Since the chipset supports a multiplexed main SMBus controller, adding the channel name to the adapter name is necessary to differentiate the ports better (for example in sensors output). Signed-off-by: Christian Fetzer Reviewed-by: Mika Westerberg Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-piix4.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 6b4231d406d5c..af4e606f8886b 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -136,6 +136,12 @@ static const struct dmi_system_id piix4_dmi_ibm[] = { { }, }; +/* SB800 globals */ +static const char *piix4_main_port_names_sb800[PIIX4_MAX_ADAPTERS] = { + "SDA0", "SDA2", "SDA3", "SDA4" +}; +static const char *piix4_aux_port_name_sb800 = "SDA1"; + struct i2c_piix4_adapdata { unsigned short smba; @@ -619,7 +625,7 @@ static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS]; static struct i2c_adapter *piix4_aux_adapter; static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, - struct i2c_adapter **padap) + const char *name, struct i2c_adapter **padap) { struct i2c_adapter *adap; struct i2c_piix4_adapdata *adapdata; @@ -648,7 +654,7 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, adap->dev.parent = &dev->dev; snprintf(adap->name, sizeof(adap->name), - "SMBus PIIX4 adapter at %04x", smba); + "SMBus PIIX4 adapter %s at %04x", name, smba); i2c_set_adapdata(adap, adapdata); @@ -680,6 +686,7 @@ static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba) for (port = 0; port < PIIX4_MAX_ADAPTERS; port++) { retval = piix4_add_adapter(dev, smba, + piix4_main_port_names_sb800[port], &piix4_main_adapters[port]); if (retval < 0) goto error; @@ -749,7 +756,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) return retval; /* Try to register main SMBus adapter, give up if we can't */ - retval = piix4_add_adapter(dev, retval, + retval = piix4_add_adapter(dev, retval, "main", &piix4_main_adapters[0]); if (retval < 0) return retval; @@ -776,7 +783,8 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) if (retval > 0) { /* Try to add the aux adapter if it exists, * piix4_add_adapter will clean up if this fails */ - piix4_add_adapter(dev, retval, &piix4_aux_adapter); + piix4_add_adapter(dev, retval, piix4_aux_port_name_sb800, + &piix4_aux_adapter); } return 0; -- GitLab From ec7f9eb4bea26b627cb5f15ebbfb5b06f969511d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 30 Nov 2015 15:14:00 +0100 Subject: [PATCH 0746/2855] spi: sh-msiof: Add support for SH-Mobile AG5 MSIOF in SH-Mobile AG5 (sh73a0) is handled fine by the existing driver. Signed-off-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/sh-msiof.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/spi/sh-msiof.txt b/Documentation/devicetree/bindings/spi/sh-msiof.txt index 705075da2f101..aa005c1d10d95 100644 --- a/Documentation/devicetree/bindings/spi/sh-msiof.txt +++ b/Documentation/devicetree/bindings/spi/sh-msiof.txt @@ -10,6 +10,7 @@ Required properties: "renesas,msiof-r8a7792" (R-Car V2H) "renesas,msiof-r8a7793" (R-Car M2-N) "renesas,msiof-r8a7794" (R-Car E2) + "renesas,msiof-sh73a0" (SH-Mobile AG5) - reg : A list of offsets and lengths of the register sets for the device. If only one register set is present, it is to be used -- GitLab From f15c58410ad90bd1208305771689877ffffe3a88 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 30 Nov 2015 15:19:06 +0100 Subject: [PATCH 0747/2855] spi: spidev: Use "%u" to format __u32 On 64-bit with CONFIG_SPI_DEBUG=y and #define VERBOSE: drivers/spi/spidev.c:287:3: warning: format '%zd' expects argument of type 'signed size_t', but argument 4 has type '__u32' [-Wformat=] Signed-off-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- drivers/spi/spidev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 91a0fcd724230..9a8e47c452f40 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -284,7 +284,7 @@ static int spidev_message(struct spidev_data *spidev, k_tmp->speed_hz = spidev->speed_hz; #ifdef VERBOSE dev_dbg(&spidev->spi->dev, - " xfer len %zd %s%s%s%dbits %u usec %uHz\n", + " xfer len %u %s%s%s%dbits %u usec %uHz\n", u_tmp->len, u_tmp->rx_buf ? "rx " : "", u_tmp->tx_buf ? "tx " : "", -- GitLab From bfbcfa770b1c316396162f9354872dc00cd572fe Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 29 Nov 2015 13:50:02 +0100 Subject: [PATCH 0748/2855] mailbox: constify mbox_chan_ops structure This mbox_chan_ops structure is never modified, so declare it as const, like all the other mbox_chan_ops structures. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Jassi Brar --- drivers/mailbox/mailbox-sti.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mailbox/mailbox-sti.c b/drivers/mailbox/mailbox-sti.c index 4835817c53651..2394cfe892b68 100644 --- a/drivers/mailbox/mailbox-sti.c +++ b/drivers/mailbox/mailbox-sti.c @@ -384,7 +384,7 @@ static struct mbox_chan *sti_mbox_xlate(struct mbox_controller *mbox, return chan; } -static struct mbox_chan_ops sti_mbox_ops = { +static const struct mbox_chan_ops sti_mbox_ops = { .startup = sti_mbox_startup_chan, .shutdown = sti_mbox_shutdown_chan, .send_data = sti_mbox_send_data, -- GitLab From 09e2b0b14690fb13ccfc04af49f156df3e25b152 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 9 Nov 2015 13:24:28 +0100 Subject: [PATCH 0749/2855] scsi: rescan VPD attributes The VPD page information might change, so we need to be able to update it. This patch implements a VPD page rescan whenever the 'rescan' sysfs attribute is triggered. Signed-off-by: Hannes Reinecke Reviewed-by: Johannes Thumshirn Reviewed-by: Shane Seymour Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi.c | 20 +++++++++++++++++--- drivers/scsi/scsi_scan.c | 4 ++++ drivers/scsi/scsi_sysfs.c | 8 ++++++-- drivers/scsi/ses.c | 12 +++++++++--- include/scsi/scsi_device.h | 5 +++-- 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index d07fb653f5dc3..b1bf42b93fccb 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -782,7 +782,7 @@ void scsi_attach_vpd(struct scsi_device *sdev) int vpd_len = SCSI_VPD_PG_LEN; int pg80_supported = 0; int pg83_supported = 0; - unsigned char *vpd_buf; + unsigned char __rcu *vpd_buf, *orig_vpd_buf = NULL; if (sdev->skip_vpd_pages) return; @@ -828,8 +828,16 @@ retry_pg80: kfree(vpd_buf); goto retry_pg80; } + mutex_lock(&sdev->inquiry_mutex); + orig_vpd_buf = sdev->vpd_pg80; sdev->vpd_pg80_len = result; - sdev->vpd_pg80 = vpd_buf; + rcu_assign_pointer(sdev->vpd_pg80, vpd_buf); + mutex_unlock(&sdev->inquiry_mutex); + synchronize_rcu(); + if (orig_vpd_buf) { + kfree(orig_vpd_buf); + orig_vpd_buf = NULL; + } vpd_len = SCSI_VPD_PG_LEN; } @@ -849,8 +857,14 @@ retry_pg83: kfree(vpd_buf); goto retry_pg83; } + mutex_lock(&sdev->inquiry_mutex); + orig_vpd_buf = sdev->vpd_pg83; sdev->vpd_pg83_len = result; - sdev->vpd_pg83 = vpd_buf; + rcu_assign_pointer(sdev->vpd_pg83, vpd_buf); + mutex_unlock(&sdev->inquiry_mutex); + synchronize_rcu(); + if (orig_vpd_buf) + kfree(orig_vpd_buf); } } diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 83245391e956b..a1c195d71fd1c 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -236,6 +236,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, INIT_LIST_HEAD(&sdev->starved_entry); INIT_LIST_HEAD(&sdev->event_list); spin_lock_init(&sdev->list_lock); + mutex_init(&sdev->inquiry_mutex); INIT_WORK(&sdev->event_work, scsi_evt_thread); INIT_WORK(&sdev->requeue_work, scsi_requeue_run_queue); @@ -1516,6 +1517,9 @@ EXPORT_SYMBOL(scsi_add_device); void scsi_rescan_device(struct device *dev) { device_lock(dev); + + scsi_attach_vpd(to_scsi_device(dev)); + if (dev->driver && try_module_get(dev->driver->owner)) { struct scsi_driver *drv = to_scsi_driver(dev->driver); diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 8d2312239ae0c..158f1b553acff 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -760,11 +760,15 @@ show_vpd_##_page(struct file *filp, struct kobject *kobj, \ { \ struct device *dev = container_of(kobj, struct device, kobj); \ struct scsi_device *sdev = to_scsi_device(dev); \ + int ret; \ if (!sdev->vpd_##_page) \ return -EINVAL; \ - return memory_read_from_buffer(buf, count, &off, \ - sdev->vpd_##_page, \ + rcu_read_lock(); \ + ret = memory_read_from_buffer(buf, count, &off, \ + rcu_dereference(sdev->vpd_##_page), \ sdev->vpd_##_page##_len); \ + rcu_read_unlock(); \ + return ret; \ } \ static struct bin_attribute dev_attr_vpd_##_page = { \ .attr = {.name = __stringify(vpd_##_page), .mode = S_IRUGO }, \ diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index dcb0d76d73128..e234da78ce6e5 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -554,17 +554,22 @@ static void ses_match_to_enclosure(struct enclosure_device *edev, struct scsi_device *sdev) { unsigned char *desc; + unsigned char __rcu *vpd_pg83; struct efd efd = { .addr = 0, }; ses_enclosure_data_process(edev, to_scsi_device(edev->edev.parent), 0); - if (!sdev->vpd_pg83_len) + rcu_read_lock(); + vpd_pg83 = rcu_dereference(sdev->vpd_pg83); + if (!vpd_pg83) { + rcu_read_unlock(); return; + } - desc = sdev->vpd_pg83 + 4; - while (desc < sdev->vpd_pg83 + sdev->vpd_pg83_len) { + desc = vpd_pg83 + 4; + while (desc < vpd_pg83 + sdev->vpd_pg83_len) { enum scsi_protocol proto = desc[0] >> 4; u8 code_set = desc[0] & 0x0f; u8 piv = desc[1] & 0x80; @@ -578,6 +583,7 @@ static void ses_match_to_enclosure(struct enclosure_device *edev, desc += len + 4; } + rcu_read_unlock(); if (efd.addr) { efd.dev = &sdev->sdev_gendev; diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index fe89d7cd67b9d..bde4077f2864a 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -109,6 +109,7 @@ struct scsi_device { char type; char scsi_level; char inq_periph_qual; /* PQ from INQUIRY data */ + struct mutex inquiry_mutex; unsigned char inquiry_len; /* valid bytes in 'inquiry' */ unsigned char * inquiry; /* INQUIRY response data */ const char * vendor; /* [back_compat] point into 'inquiry' ... */ @@ -117,9 +118,9 @@ struct scsi_device { #define SCSI_VPD_PG_LEN 255 int vpd_pg83_len; - unsigned char *vpd_pg83; + unsigned char __rcu *vpd_pg83; int vpd_pg80_len; - unsigned char *vpd_pg80; + unsigned char __rcu *vpd_pg80; unsigned char current_tag; /* current tag */ struct scsi_target *sdev_target; /* used only for single_lun */ -- GitLab From f05ca854b3df79bf6596de5102eb99ca10d6089f Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Mon, 30 Nov 2015 16:21:42 +0000 Subject: [PATCH 0750/2855] spi: topcliff-pch: allow build for MIPS platforms Allow the topcliff-pch driver to be built for MIPS platforms, in preparation for use on the MIPS Boston board. Signed-off-by: Paul Burton Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 8b9c2a38d1ccd..7c78d52591af6 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -585,7 +585,7 @@ config SPI_TEGRA20_SLINK config SPI_TOPCLIFF_PCH tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) SPI" - depends on PCI && (X86_32 || COMPILE_TEST) + depends on PCI && (X86_32 || MIPS || COMPILE_TEST) help SPI driver for the Topcliff PCH (Platform Controller Hub) SPI bus used in some x86 embedded processors. -- GitLab From fa785f0a984d863a24d2f288b68757188a50261b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 26 Nov 2015 20:22:50 +0200 Subject: [PATCH 0751/2855] scsi_debug: check for bigger value first Even for signed types we have to check for bigger positive value first. Otherwise it will be never happened. Signed-off-by: Andy Shevchenko Acked-by: Douglas Gilbert Reviewed-by: Johannes Thumshirn Reviewed-by: Ewan Milne Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_debug.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index ec622ba9864ac..1bea1adc16a8f 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -4846,10 +4846,10 @@ static int __init scsi_debug_init(void) /* play around with geometry, don't waste too much on track 0 */ sdebug_heads = 8; sdebug_sectors_per = 32; - if (scsi_debug_dev_size_mb >= 16) - sdebug_heads = 32; - else if (scsi_debug_dev_size_mb >= 256) + if (scsi_debug_dev_size_mb >= 256) sdebug_heads = 64; + else if (scsi_debug_dev_size_mb >= 16) + sdebug_heads = 32; sdebug_cylinders_per = (unsigned long)sdebug_capacity / (sdebug_sectors_per * sdebug_heads); if (sdebug_cylinders_per >= 1024) { -- GitLab From c4c696fa1b0623031544da8b10f9d4e1401a49db Mon Sep 17 00:00:00 2001 From: LABBE Corentin Date: Tue, 24 Nov 2015 08:43:27 +0100 Subject: [PATCH 0752/2855] i2c: taos-evm: replace simple_strtoul by kstrtou8 The simple_strtoul function is marked as obsolete. This patch replace it by kstrtou8. Reviewed-by: Jean Delvare Tested-by: Jean Delvare Signed-off-by: LABBE Corentin Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-taos-evm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-taos-evm.c b/drivers/i2c/busses/i2c-taos-evm.c index 4c7fc2d47014f..210ca82f8aa05 100644 --- a/drivers/i2c/busses/i2c-taos-evm.c +++ b/drivers/i2c/busses/i2c-taos-evm.c @@ -130,7 +130,13 @@ static int taos_smbus_xfer(struct i2c_adapter *adapter, u16 addr, return 0; } else { if (p[0] == 'x') { - data->byte = simple_strtol(p + 1, NULL, 16); + /* + * Voluntarily dropping error code of kstrtou8 since all + * error code that it could return are invalid according + * to Documentation/i2c/fault-codes. + */ + if (kstrtou8(p + 1, 16, &data->byte)) + return -EPROTO; return 0; } } -- GitLab From 77c680196791e7b13c90b4d475a3d6c96778755c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 16 Nov 2015 14:42:05 +0100 Subject: [PATCH 0753/2855] i2c: xiic: Replace spinlock with mutex All protected sections are only called from sleep-able context, so there is no need to use a spinlock. Signed-off-by: Lars-Peter Clausen Reviewed-by: Shubhrajyoti Datta Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-xiic.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index 0b20449e48cfe..6efd20095d5db 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -70,7 +70,7 @@ struct xiic_i2c { wait_queue_head_t wait; struct i2c_adapter adap; struct i2c_msg *tx_msg; - spinlock_t lock; + struct mutex lock; unsigned int tx_pos; unsigned int nmsgs; enum xilinx_i2c_state state; @@ -369,7 +369,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id) * To find which interrupts are pending; AND interrupts pending with * interrupts masked. */ - spin_lock(&i2c->lock); + mutex_lock(&i2c->lock); isr = xiic_getreg32(i2c, XIIC_IISR_OFFSET); ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET); pend = isr & ier; @@ -497,7 +497,7 @@ out: dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr); xiic_setreg32(i2c, XIIC_IISR_OFFSET, clr); - spin_unlock(&i2c->lock); + mutex_unlock(&i2c->lock); return IRQ_HANDLED; } @@ -662,10 +662,10 @@ static void __xiic_start_xfer(struct xiic_i2c *i2c) static void xiic_start_xfer(struct xiic_i2c *i2c) { - spin_lock(&i2c->lock); + mutex_lock(&i2c->lock); xiic_reinit(i2c); __xiic_start_xfer(i2c); - spin_unlock(&i2c->lock); + mutex_unlock(&i2c->lock); } static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) @@ -745,7 +745,7 @@ static int xiic_i2c_probe(struct platform_device *pdev) i2c->adap.dev.parent = &pdev->dev; i2c->adap.dev.of_node = pdev->dev.of_node; - spin_lock_init(&i2c->lock); + mutex_init(&i2c->lock); init_waitqueue_head(&i2c->wait); ret = devm_request_threaded_irq(&pdev->dev, irq, xiic_isr, -- GitLab From 749de3dac5e4d65cbed3b58f89c56883e31d1a5a Mon Sep 17 00:00:00 2001 From: Nicola Corna Date: Thu, 29 Oct 2015 12:34:23 +0100 Subject: [PATCH 0754/2855] i2c: add i2c quirk flag for unsupported clock stretching Add I2C_AQ_NO_CLK_STRETCH quirk flag, to be used when clock stretching is not supported. Signed-off-by: Nicola Corna Signed-off-by: Wolfram Sang --- include/linux/i2c.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 768063baafbf5..96970024883ff 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -493,6 +493,8 @@ struct i2c_adapter_quirks { /* convenience macro for typical write-then read case */ #define I2C_AQ_COMB_WRITE_THEN_READ (I2C_AQ_COMB | I2C_AQ_COMB_WRITE_FIRST | \ I2C_AQ_COMB_READ_SECOND | I2C_AQ_COMB_SAME_ADDR) +/* clock stretching is not supported */ +#define I2C_AQ_NO_CLK_STRETCH BIT(4) /* * i2c_adapter is the structure used to identify a physical i2c bus along -- GitLab From a94d306b71a5202cb928a7a1328dedab4fe0e968 Mon Sep 17 00:00:00 2001 From: Nicola Corna Date: Thu, 29 Oct 2015 12:34:24 +0100 Subject: [PATCH 0755/2855] i2c: algo-bit: add I2C_AQ_NO_CLK_STRETCH Add I2C_AQ_NO_CLK_STRETCH to drivers/i2c/algos/i2c-algo-bit.c when getscl is not available. Signed-off-by: Nicola Corna Signed-off-by: Wolfram Sang --- drivers/i2c/algos/i2c-algo-bit.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index 899bede81b31b..9d233bbde5e19 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -617,6 +617,10 @@ const struct i2c_algorithm i2c_bit_algo = { }; EXPORT_SYMBOL(i2c_bit_algo); +const struct i2c_adapter_quirks i2c_bit_quirk_no_clk_stretch = { + .flags = I2C_AQ_NO_CLK_STRETCH, +}; + /* * registering functions to load algorithms at runtime */ @@ -635,6 +639,8 @@ static int __i2c_bit_add_bus(struct i2c_adapter *adap, /* register new adapter to i2c module... */ adap->algo = &i2c_bit_algo; adap->retries = 3; + if (bit_adap->getscl == NULL) + adap->quirks = &i2c_bit_quirk_no_clk_stretch; ret = add_adapter(adap); if (ret < 0) -- GitLab From 4dbfb5f4401f845903679afbfeb4b97b47bb2331 Mon Sep 17 00:00:00 2001 From: Nicola Corna Date: Thu, 29 Oct 2015 12:34:25 +0100 Subject: [PATCH 0756/2855] i2c: bcm2835: add I2C_AQ_NO_CLK_STRETCH As reported in the links given below. the BCM2835 has a hardware bug in its i2c module which prevents a correct clock stretching. This patch adds the I2C_AQ_NO_CLK_STRETCH quirk flag to i2c-bcm2835. Signed-off-by: Nicola Corna [wsa: put the links into the code as comments] Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-bcm2835.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c index 3032b89ac60b5..818b051d25e6d 100644 --- a/drivers/i2c/busses/i2c-bcm2835.c +++ b/drivers/i2c/busses/i2c-bcm2835.c @@ -222,6 +222,15 @@ static const struct i2c_algorithm bcm2835_i2c_algo = { .functionality = bcm2835_i2c_func, }; +/* + * This HW was reported to have problems with clock stretching: + * http://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html + * https://www.raspberrypi.org/forums/viewtopic.php?p=146272 + */ +static const struct i2c_adapter_quirks bcm2835_i2c_quirks = { + .flags = I2C_AQ_NO_CLK_STRETCH, +}; + static int bcm2835_i2c_probe(struct platform_device *pdev) { struct bcm2835_i2c_dev *i2c_dev; @@ -293,6 +302,7 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) adap->algo = &bcm2835_i2c_algo; adap->dev.parent = &pdev->dev; adap->dev.of_node = pdev->dev.of_node; + adap->quirks = &bcm2835_i2c_quirks; bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, 0); -- GitLab From cfa576db834cacc1bb01bc41b2f61a8b578e67c5 Mon Sep 17 00:00:00 2001 From: Nicola Corna Date: Thu, 29 Oct 2015 12:34:26 +0100 Subject: [PATCH 0757/2855] i2c: add i2c_check_quirks helper function This patch adds a i2c_check_quirks helper function to check the quirk flags of an i2c adapter, in a similar way to i2c_check_functionality. Signed-off-by: Nicola Corna Signed-off-by: Wolfram Sang --- include/linux/i2c.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 96970024883ff..51028f351d13e 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -617,6 +617,20 @@ static inline int i2c_check_functionality(struct i2c_adapter *adap, u32 func) return (func & i2c_get_functionality(adap)) == func; } +/** + * i2c_check_quirks() - Function for checking the quirk flags in an i2c adapter + * @adap: i2c adapter + * @quirks: quirk flags + * + * Return: true if the adapter has all the specified quirk flags, false if not + */ +static inline bool i2c_check_quirks(struct i2c_adapter *adap, u64 quirks) +{ + if (!adap->quirks) + return false; + return (adap->quirks->flags & quirks) == quirks; +} + /* Return the adapter number for a specific adapter */ static inline int i2c_adapter_id(struct i2c_adapter *adap) { -- GitLab From 2c81de771f38e54324ede3f24118f4852570b384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 26 Nov 2015 09:05:04 +0100 Subject: [PATCH 0758/2855] mtd: spi-nor: include mtd.h header for struct mtd_info definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So far struct spi_nor was using just a pointer to struct mtd_info so it wasn't needed to have it fully defined there. After recent change we embed whole struct so we need to include a proper header. Fixes: 1976367173a4 ("mtd: spi-nor: embed struct mtd_info within struct spi_nor") Signed-off-by: Rafał Miłecki Signed-off-by: Brian Norris --- include/linux/mtd/spi-nor.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 7bed97471e537..fac3f6f53981a 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -12,6 +12,7 @@ #include #include +#include /* * Manufacturer IDs @@ -117,8 +118,6 @@ enum spi_nor_option_flags { SNOR_F_USE_FSR = BIT(0), }; -struct mtd_info; - /** * struct spi_nor - Structure for defining a the SPI NOR layer * @mtd: point to a mtd_info structure -- GitLab From 7fa32329ca03148fb2c07b4ef3247b8fc0488d6a Mon Sep 17 00:00:00 2001 From: Shubhrajyoti Datta Date: Tue, 24 Nov 2015 13:01:56 +0530 Subject: [PATCH 0759/2855] i2c: cadence: Move to sensible power management Currently the clocks are enabled at probe and disabled at remove. Which keeps the clocks enabled even if no transaction is going on. This patch enables the clocks at the start of transfer and disables after it. Also adapts to runtime pm. converts dev pm to const to silence a checkpatch warning. Signed-off-by: Shubhrajyoti Datta Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-cadence.c | 66 ++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index 84deed6571bdf..d54ad46afa2b3 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c @@ -18,6 +18,7 @@ #include #include #include +#include /* Register offsets for the I2C device. */ #define CDNS_I2C_CR_OFFSET 0x00 /* Control Register, RW */ @@ -96,6 +97,8 @@ CDNS_I2C_IXR_COMP) #define CDNS_I2C_TIMEOUT msecs_to_jiffies(1000) +/* timeout for pm runtime autosuspend */ +#define CNDS_I2C_PM_TIMEOUT 1000 /* ms */ #define CDNS_I2C_FIFO_DEPTH 16 /* FIFO depth at which the DATA interrupt occurs */ @@ -141,6 +144,7 @@ * @quirks: flag for broken hold bit usage in r1p10 */ struct cdns_i2c { + struct device *dev; void __iomem *membase; struct i2c_adapter adap; struct i2c_msg *p_msg; @@ -569,9 +573,14 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, struct cdns_i2c *id = adap->algo_data; bool hold_quirk; + ret = pm_runtime_get_sync(id->dev); + if (ret < 0) + return ret; /* Check if the bus is free */ - if (cdns_i2c_readreg(CDNS_I2C_SR_OFFSET) & CDNS_I2C_SR_BA) - return -EAGAIN; + if (cdns_i2c_readreg(CDNS_I2C_SR_OFFSET) & CDNS_I2C_SR_BA) { + ret = -EAGAIN; + goto out; + } hold_quirk = !!(id->quirks & CDNS_I2C_BROKEN_HOLD_BIT); /* @@ -590,7 +599,8 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, if (msgs[count].flags & I2C_M_RD) { dev_warn(adap->dev.parent, "Can't do repeated start after a receive message\n"); - return -EOPNOTSUPP; + ret = -EOPNOTSUPP; + goto out; } } id->bus_hold_flag = 1; @@ -608,20 +618,26 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, ret = cdns_i2c_process_msg(id, msgs, adap); if (ret) - return ret; + goto out; /* Report the other error interrupts to application */ if (id->err_status) { cdns_i2c_master_reset(adap); - if (id->err_status & CDNS_I2C_IXR_NACK) - return -ENXIO; - - return -EIO; + if (id->err_status & CDNS_I2C_IXR_NACK) { + ret = -ENXIO; + goto out; + } + ret = -EIO; + goto out; } } - return num; + ret = num; +out: + pm_runtime_mark_last_busy(id->dev); + pm_runtime_put_autosuspend(id->dev); + return ret; } /** @@ -808,10 +824,9 @@ static int cdns_i2c_clk_notifier_cb(struct notifier_block *nb, unsigned long * * Return: 0 always */ -static int __maybe_unused cdns_i2c_suspend(struct device *_dev) +static int __maybe_unused cdns_i2c_runtime_suspend(struct device *dev) { - struct platform_device *pdev = container_of(_dev, - struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); struct cdns_i2c *xi2c = platform_get_drvdata(pdev); clk_disable(xi2c->clk); @@ -828,16 +843,15 @@ static int __maybe_unused cdns_i2c_suspend(struct device *_dev) * * Return: 0 on success and error value on error */ -static int __maybe_unused cdns_i2c_resume(struct device *_dev) +static int __maybe_unused cdns_i2c_runtime_resume(struct device *dev) { - struct platform_device *pdev = container_of(_dev, - struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); struct cdns_i2c *xi2c = platform_get_drvdata(pdev); int ret; ret = clk_enable(xi2c->clk); if (ret) { - dev_err(_dev, "Cannot enable clock.\n"); + dev_err(dev, "Cannot enable clock.\n"); return ret; } @@ -846,8 +860,10 @@ static int __maybe_unused cdns_i2c_resume(struct device *_dev) return 0; } -static SIMPLE_DEV_PM_OPS(cdns_i2c_dev_pm_ops, cdns_i2c_suspend, - cdns_i2c_resume); +static const struct dev_pm_ops cdns_i2c_dev_pm_ops = { + SET_RUNTIME_PM_OPS(cdns_i2c_runtime_suspend, + cdns_i2c_runtime_resume, NULL) +}; static const struct cdns_platform_data r1p10_i2c_def = { .quirks = CDNS_I2C_BROKEN_HOLD_BIT, @@ -881,6 +897,7 @@ static int cdns_i2c_probe(struct platform_device *pdev) if (!id) return -ENOMEM; + id->dev = &pdev->dev; platform_set_drvdata(pdev, id); match = of_match_node(cdns_i2c_of_match, pdev->dev.of_node); @@ -913,10 +930,14 @@ static int cdns_i2c_probe(struct platform_device *pdev) return PTR_ERR(id->clk); } ret = clk_prepare_enable(id->clk); - if (ret) { + if (ret) dev_err(&pdev->dev, "Unable to enable clock.\n"); - return ret; - } + + pm_runtime_enable(id->dev); + pm_runtime_set_autosuspend_delay(id->dev, CNDS_I2C_PM_TIMEOUT); + pm_runtime_use_autosuspend(id->dev); + pm_runtime_set_active(id->dev); + id->clk_rate_change_nb.notifier_call = cdns_i2c_clk_notifier_cb; if (clk_notifier_register(id->clk, &id->clk_rate_change_nb)) dev_warn(&pdev->dev, "Unable to register clock notifier.\n"); @@ -966,6 +987,8 @@ static int cdns_i2c_probe(struct platform_device *pdev) err_clk_dis: clk_disable_unprepare(id->clk); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_disable(&pdev->dev); return ret; } @@ -984,6 +1007,7 @@ static int cdns_i2c_remove(struct platform_device *pdev) i2c_del_adapter(&id->adap); clk_notifier_unregister(id->clk, &id->clk_rate_change_nb); clk_disable_unprepare(id->clk); + pm_runtime_disable(&pdev->dev); return 0; } -- GitLab From 948c58a03a4c63edc1007c222c340003fdba6d98 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti Datta Date: Tue, 24 Nov 2015 13:01:57 +0530 Subject: [PATCH 0760/2855] i2c: cadence: Remove the suspended flag The suspended flag is a flag holding the device's PM status. The runtime framework does that for us. Use pm_runtime_suspended call instead. Signed-off-by: Shubhrajyoti Datta Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-cadence.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index d54ad46afa2b3..6b08d1607b7a1 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c @@ -131,7 +131,6 @@ * @xfer_done: Transfer complete status * @p_send_buf: Pointer to transmit buffer * @p_recv_buf: Pointer to receive buffer - * @suspended: Flag holding the device's PM status * @send_count: Number of bytes still expected to send * @recv_count: Number of bytes still expected to receive * @curr_recv_count: Number of bytes to be received in current transfer @@ -152,7 +151,6 @@ struct cdns_i2c { struct completion xfer_done; unsigned char *p_send_buf; unsigned char *p_recv_buf; - u8 suspended; unsigned int send_count; unsigned int recv_count; unsigned int curr_recv_count; @@ -776,7 +774,7 @@ static int cdns_i2c_clk_notifier_cb(struct notifier_block *nb, unsigned long struct clk_notifier_data *ndata = data; struct cdns_i2c *id = to_cdns_i2c(nb); - if (id->suspended) + if (pm_runtime_suspended(id->dev)) return NOTIFY_OK; switch (event) { @@ -830,7 +828,6 @@ static int __maybe_unused cdns_i2c_runtime_suspend(struct device *dev) struct cdns_i2c *xi2c = platform_get_drvdata(pdev); clk_disable(xi2c->clk); - xi2c->suspended = 1; return 0; } @@ -855,8 +852,6 @@ static int __maybe_unused cdns_i2c_runtime_resume(struct device *dev) return ret; } - xi2c->suspended = 0; - return 0; } -- GitLab From f5f92b36fbbb8ac7d70ff5fa39ec2637cce3094c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 23 Nov 2015 14:39:33 +0100 Subject: [PATCH 0761/2855] mtd: cfi: enforce valid geometry configuration MTD allows compile-time configuration of the possible CFI geometry settings that are allowed by the kernel, but that includes a couple of invalid configurations, where no bank width or no interleave setting is allowed. These are then caught with a compile-time warning: include/linux/mtd/cfi.h:76:2: warning: #warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work. include/linux/mtd/map.h:145:2: warning: #warning "No CONFIG_MTD_MAP_BANK_WIDTH_xx selected. No NOR chip support can work" This is a bit annoying for randconfig tests, and can be avoided if we change the Kconfig logic to always select the simplest configuration when no other one is enabled. Signed-off-by: Arnd Bergmann Signed-off-by: Brian Norris --- drivers/mtd/chips/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig index 54479c481a7a8..3b3dabce58de9 100644 --- a/drivers/mtd/chips/Kconfig +++ b/drivers/mtd/chips/Kconfig @@ -67,6 +67,10 @@ endchoice config MTD_CFI_GEOMETRY bool "Specific CFI Flash geometry selection" depends on MTD_CFI_ADV_OPTIONS + select MTD_MAP_BANK_WIDTH_1 if !(MTD_MAP_BANK_WIDTH_2 || \ + MTD_MAP_BANK_WIDTH_4 || MTD_MAP_BANK_WIDTH_8 || \ + MTD_MAP_BANK_WIDTH_16 || MTD_MAP_BANK_WIDTH_32) + select MTD_CFI_I1 if !(MTD_CFI_I2 || MTD_CFI_I4 || MTD_CFI_I8) help This option does not affect the code directly, but will enable some other configuration options which would allow you to reduce -- GitLab From fe7579d6122f2869d00b55842bca9e2a9be51607 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 24 Nov 2015 23:09:02 +0100 Subject: [PATCH 0762/2855] mtd: cfi: don't warn about broken geometry for !CONFIG_MTD The linux/mtd/map.h header file is included by a couple of platform specific files that are built even when CONFIG_MTD is disabled, and we always get warning "No CONFIG_MTD_MAP_BANK_WIDTH_xx selected. No NOR chip support can work" in that case. This adds an #ifdef around the pointless warning, as everything is really fine when we don't build the drivers anyway. Signed-off-by: Arnd Bergmann Signed-off-by: Brian Norris --- include/linux/mtd/map.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h index 366cf77953b55..58f3ba709adec 100644 --- a/include/linux/mtd/map.h +++ b/include/linux/mtd/map.h @@ -142,7 +142,9 @@ #endif #ifndef map_bankwidth +#ifdef CONFIG_MTD #warning "No CONFIG_MTD_MAP_BANK_WIDTH_xx selected. No NOR chip support can work" +#endif static inline int map_bankwidth(void *map) { BUG(); -- GitLab From 4cd38e388d547807e89b4bc51a57bdd5fc5ef7df Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 20 Nov 2015 13:33:04 -0800 Subject: [PATCH 0763/2855] scsi_transport_fc: Introduce scsi_host_{get,put}() Use scsi_host_{get,put}() instead of open-coding these functions. Compile-tested only. [mkp: Dropped CC:stable and fixed James Smart's email address] Signed-off-by: Bart Van Assche Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Cc: Christoph Hellwig Cc: Hannes Reinecke Cc: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_transport_fc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 24eaaf66af710..8a8822641b266 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -2586,7 +2586,7 @@ fc_rport_final_delete(struct work_struct *work) transport_remove_device(dev); device_del(dev); transport_destroy_device(dev); - put_device(&shost->shost_gendev); /* for fc_host->rport list */ + scsi_host_put(shost); /* for fc_host->rport list */ put_device(dev); /* for self-reference */ } @@ -2650,7 +2650,7 @@ fc_rport_create(struct Scsi_Host *shost, int channel, else rport->scsi_target_id = -1; list_add_tail(&rport->peers, &fc_host->rports); - get_device(&shost->shost_gendev); /* for fc_host->rport list */ + scsi_host_get(shost); /* for fc_host->rport list */ spin_unlock_irqrestore(shost->host_lock, flags); @@ -2685,7 +2685,7 @@ delete_rport: transport_destroy_device(dev); spin_lock_irqsave(shost->host_lock, flags); list_del(&rport->peers); - put_device(&shost->shost_gendev); /* for fc_host->rport list */ + scsi_host_put(shost); /* for fc_host->rport list */ spin_unlock_irqrestore(shost->host_lock, flags); put_device(dev->parent); kfree(rport); @@ -3383,7 +3383,7 @@ fc_vport_setup(struct Scsi_Host *shost, int channel, struct device *pdev, fc_host->npiv_vports_inuse++; vport->number = fc_host->next_vport_number++; list_add_tail(&vport->peers, &fc_host->vports); - get_device(&shost->shost_gendev); /* for fc_host->vport list */ + scsi_host_get(shost); /* for fc_host->vport list */ spin_unlock_irqrestore(shost->host_lock, flags); @@ -3441,7 +3441,7 @@ delete_vport: transport_destroy_device(dev); spin_lock_irqsave(shost->host_lock, flags); list_del(&vport->peers); - put_device(&shost->shost_gendev); /* for fc_host->vport list */ + scsi_host_put(shost); /* for fc_host->vport list */ fc_host->npiv_vports_inuse--; spin_unlock_irqrestore(shost->host_lock, flags); put_device(dev->parent); @@ -3504,7 +3504,7 @@ fc_vport_terminate(struct fc_vport *vport) vport->flags |= FC_VPORT_DELETED; list_del(&vport->peers); fc_host->npiv_vports_inuse--; - put_device(&shost->shost_gendev); /* for fc_host->vport list */ + scsi_host_put(shost); /* for fc_host->vport list */ } spin_unlock_irqrestore(shost->host_lock, flags); -- GitLab From 251e2d25bfb72b69edd414abfa42a41191d9657a Mon Sep 17 00:00:00 2001 From: Ching Huang Date: Wed, 25 Nov 2015 19:36:02 +0800 Subject: [PATCH 0764/2855] arcmsr: fixed getting wrong configuration data Fixed getting wrong configuration data of adapter type B and type D. Signed-off-by: Ching Huang Reviewed-by: Hannes Reinicke Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/arcmsr/arcmsr_hba.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 333db5953607e..397cdd52fbfed 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -2694,15 +2694,15 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) acb->firm_model, acb->firm_version); - acb->signature = readl(®->message_rwbuffer[1]); + acb->signature = readl(®->message_rwbuffer[0]); /*firm_signature,1,00-03*/ - acb->firm_request_len = readl(®->message_rwbuffer[2]); + acb->firm_request_len = readl(®->message_rwbuffer[1]); /*firm_request_len,1,04-07*/ - acb->firm_numbers_queue = readl(®->message_rwbuffer[3]); + acb->firm_numbers_queue = readl(®->message_rwbuffer[2]); /*firm_numbers_queue,2,08-11*/ - acb->firm_sdram_size = readl(®->message_rwbuffer[4]); + acb->firm_sdram_size = readl(®->message_rwbuffer[3]); /*firm_sdram_size,3,12-15*/ - acb->firm_hd_channels = readl(®->message_rwbuffer[5]); + acb->firm_hd_channels = readl(®->message_rwbuffer[4]); /*firm_ide_channels,4,16-19*/ acb->firm_cfg_version = readl(®->message_rwbuffer[25]); /*firm_cfg_version,25,100-103*/ /*firm_ide_channels,4,16-19*/ @@ -2880,15 +2880,15 @@ static bool arcmsr_hbaD_get_config(struct AdapterControlBlock *acb) iop_device_map++; count--; } - acb->signature = readl(®->msgcode_rwbuffer[1]); + acb->signature = readl(®->msgcode_rwbuffer[0]); /*firm_signature,1,00-03*/ - acb->firm_request_len = readl(®->msgcode_rwbuffer[2]); + acb->firm_request_len = readl(®->msgcode_rwbuffer[1]); /*firm_request_len,1,04-07*/ - acb->firm_numbers_queue = readl(®->msgcode_rwbuffer[3]); + acb->firm_numbers_queue = readl(®->msgcode_rwbuffer[2]); /*firm_numbers_queue,2,08-11*/ - acb->firm_sdram_size = readl(®->msgcode_rwbuffer[4]); + acb->firm_sdram_size = readl(®->msgcode_rwbuffer[3]); /*firm_sdram_size,3,12-15*/ - acb->firm_hd_channels = readl(®->msgcode_rwbuffer[5]); + acb->firm_hd_channels = readl(®->msgcode_rwbuffer[4]); /*firm_hd_channels,4,16-19*/ acb->firm_cfg_version = readl(®->msgcode_rwbuffer[25]); pr_notice("Areca RAID Controller%d: Model %s, F/W %s\n", -- GitLab From 98f90debc2b64a40a416dd9794ac2d8de6b43af2 Mon Sep 17 00:00:00 2001 From: Ching Huang Date: Wed, 25 Nov 2015 19:41:23 +0800 Subject: [PATCH 0765/2855] arcmsr: fixes not release allocated resource Releasing allocated resource if get configuration data failed. Signed-off-by: Ching Huang Reviewed-by: Johannes Thumshirn Reviewed-by: Hannes Reinicke Reviewed-by: Tomas Henzl Signed-off-by: Martin K. Petersen --- drivers/scsi/arcmsr/arcmsr_hba.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 397cdd52fbfed..41f9a00e4f74f 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -2664,7 +2664,7 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) if (!arcmsr_hbaB_wait_msgint_ready(acb)) { printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ miscellaneous data' timeout \n", acb->host->host_no); - return false; + goto err_free_dma; } count = 8; while (count){ @@ -2707,6 +2707,10 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) acb->firm_cfg_version = readl(®->message_rwbuffer[25]); /*firm_cfg_version,25,100-103*/ /*firm_ide_channels,4,16-19*/ return true; +err_free_dma: + dma_free_coherent(&acb->pdev->dev, acb->roundup_ccbsize, + acb->dma_coherent2, acb->dma_coherent_handle2); + return false; } static bool arcmsr_hbaC_get_config(struct AdapterControlBlock *pACB) -- GitLab From d662ad246256e33eb9b25c8e801f4487527f2bfe Mon Sep 17 00:00:00 2001 From: Ching Huang Date: Wed, 25 Nov 2015 19:45:16 +0800 Subject: [PATCH 0766/2855] arcmsr: make code more readable [mkp: Fixed checkpatch whitespace warning] Signed-off-by: Ching Huang Reviewed-by: Johannes Thumshirn Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen --- drivers/scsi/arcmsr/arcmsr.h | 3 +++ drivers/scsi/arcmsr/arcmsr_hba.c | 14 +++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 3bcaaac0ae4bb..48931bd9bcef3 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -288,6 +288,9 @@ struct FIRMWARE_INFO #define ARCMSR_MESSAGE_RBUFFER 0x0000ff00 /* iop message_rwbuffer for message command */ #define ARCMSR_MESSAGE_RWBUFFER 0x0000fa00 + +#define MEM_BASE0(x) (u32 __iomem *)((unsigned long)acb->mem_base0 + x) +#define MEM_BASE1(x) (u32 __iomem *)((unsigned long)acb->mem_base1 + x) /* ************************************************************************ ** SPEC. for Areca HBC adapter diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 41f9a00e4f74f..077c3ecff7eed 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -2649,13 +2649,13 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) acb->dma_coherent2 = dma_coherent; reg = (struct MessageUnit_B *)dma_coherent; acb->pmuB = reg; - reg->drv2iop_doorbell= (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL); - reg->drv2iop_doorbell_mask = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL_MASK); - reg->iop2drv_doorbell = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL); - reg->iop2drv_doorbell_mask = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL_MASK); - reg->message_wbuffer = (uint32_t __iomem *)((unsigned long)acb->mem_base1 + ARCMSR_MESSAGE_WBUFFER); - reg->message_rbuffer = (uint32_t __iomem *)((unsigned long)acb->mem_base1 + ARCMSR_MESSAGE_RBUFFER); - reg->message_rwbuffer = (uint32_t __iomem *)((unsigned long)acb->mem_base1 + ARCMSR_MESSAGE_RWBUFFER); + reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL); + reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK); + reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL); + reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK); + reg->message_wbuffer = MEM_BASE1(ARCMSR_MESSAGE_WBUFFER); + reg->message_rbuffer = MEM_BASE1(ARCMSR_MESSAGE_RBUFFER); + reg->message_rwbuffer = MEM_BASE1(ARCMSR_MESSAGE_RWBUFFER); iop_firm_model = (char __iomem *)(®->message_rwbuffer[15]); /*firm_model,15,60-67*/ iop_firm_version = (char __iomem *)(®->message_rwbuffer[17]); /*firm_version,17,68-83*/ iop_device_map = (char __iomem *)(®->message_rwbuffer[21]); /*firm_version,21,84-99*/ -- GitLab From 7e315ffd49b906fc545b8e0312eedeed738796c9 Mon Sep 17 00:00:00 2001 From: Ching Huang Date: Wed, 25 Nov 2015 19:49:33 +0800 Subject: [PATCH 0767/2855] arcmsr: adds code to support new Areca adapter ARC1203 Support Areca's new PCIe to SATA RAID adapter ARC1203. Signed-off-by: Ching Huang Reviewed-by: Johannes Thumshirn Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen --- drivers/scsi/arcmsr/arcmsr.h | 9 +++++++++ drivers/scsi/arcmsr/arcmsr_hba.c | 27 ++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 48931bd9bcef3..9c5a2a89a69d8 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -74,6 +74,9 @@ struct device_attribute; #ifndef PCI_DEVICE_ID_ARECA_1214 #define PCI_DEVICE_ID_ARECA_1214 0x1214 #endif +#ifndef PCI_DEVICE_ID_ARECA_1203 + #define PCI_DEVICE_ID_ARECA_1203 0x1203 +#endif /* ********************************************************************************** ** @@ -245,6 +248,12 @@ struct FIRMWARE_INFO /* window of "instruction flags" from iop to driver */ #define ARCMSR_IOP2DRV_DOORBELL 0x00020408 #define ARCMSR_IOP2DRV_DOORBELL_MASK 0x0002040C +/* window of "instruction flags" from iop to driver */ +#define ARCMSR_IOP2DRV_DOORBELL_1203 0x00021870 +#define ARCMSR_IOP2DRV_DOORBELL_MASK_1203 0x00021874 +/* window of "instruction flags" from driver to iop */ +#define ARCMSR_DRV2IOP_DOORBELL_1203 0x00021878 +#define ARCMSR_DRV2IOP_DOORBELL_MASK_1203 0x0002187C /* ARECA FLAG LANGUAGE */ /* ioctl transfer */ #define ARCMSR_IOP2DRV_DATA_WRITE_OK 0x00000001 diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 077c3ecff7eed..881be34afd8b1 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -114,6 +114,7 @@ static void arcmsr_hardware_reset(struct AdapterControlBlock *acb); static const char *arcmsr_info(struct Scsi_Host *); static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb); static void arcmsr_free_irq(struct pci_dev *, struct AdapterControlBlock *); +static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb); static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth) { if (queue_depth > ARCMSR_MAX_CMD_PERLUN) @@ -157,6 +158,8 @@ static struct pci_device_id arcmsr_device_id_table[] = { .driver_data = ACB_ADAPTER_TYPE_B}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1202), .driver_data = ACB_ADAPTER_TYPE_B}, + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1203), + .driver_data = ACB_ADAPTER_TYPE_B}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1210), .driver_data = ACB_ADAPTER_TYPE_A}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1214), @@ -2621,7 +2624,7 @@ static bool arcmsr_hbaA_get_config(struct AdapterControlBlock *acb) } static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) { - struct MessageUnit_B *reg = acb->pmuB; + struct MessageUnit_B *reg; struct pci_dev *pdev = acb->pdev; void *dma_coherent; dma_addr_t dma_coherent_handle; @@ -2649,10 +2652,17 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) acb->dma_coherent2 = dma_coherent; reg = (struct MessageUnit_B *)dma_coherent; acb->pmuB = reg; - reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL); - reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK); - reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL); - reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK); + if (acb->pdev->device == PCI_DEVICE_ID_ARECA_1203) { + reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_1203); + reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK_1203); + reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_1203); + reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK_1203); + } else { + reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL); + reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK); + reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL); + reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK); + } reg->message_wbuffer = MEM_BASE1(ARCMSR_MESSAGE_WBUFFER); reg->message_rbuffer = MEM_BASE1(ARCMSR_MESSAGE_RBUFFER); reg->message_rwbuffer = MEM_BASE1(ARCMSR_MESSAGE_RWBUFFER); @@ -2660,6 +2670,12 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) iop_firm_version = (char __iomem *)(®->message_rwbuffer[17]); /*firm_version,17,68-83*/ iop_device_map = (char __iomem *)(®->message_rwbuffer[21]); /*firm_version,21,84-99*/ + arcmsr_wait_firmware_ready(acb); + writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell); + if (!arcmsr_hbaB_wait_msgint_ready(acb)) { + printk(KERN_ERR "arcmsr%d: can't set driver mode.\n", acb->host->host_no); + goto err_free_dma; + } writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell); if (!arcmsr_hbaB_wait_msgint_ready(acb)) { printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ @@ -4002,6 +4018,7 @@ static const char *arcmsr_info(struct Scsi_Host *host) case PCI_DEVICE_ID_ARECA_1160: case PCI_DEVICE_ID_ARECA_1170: case PCI_DEVICE_ID_ARECA_1201: + case PCI_DEVICE_ID_ARECA_1203: case PCI_DEVICE_ID_ARECA_1220: case PCI_DEVICE_ID_ARECA_1230: case PCI_DEVICE_ID_ARECA_1260: -- GitLab From d15dd55d049ccae9a1061e08ad377f9c799b8a3a Mon Sep 17 00:00:00 2001 From: Ching Huang Date: Wed, 25 Nov 2015 19:52:15 +0800 Subject: [PATCH 0768/2855] arcmsr: changes driver version number Changes driver version number. Signed-off-by: Ching Huang Reviewed-by: Johannes Thumshirn Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen --- drivers/scsi/arcmsr/arcmsr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 9c5a2a89a69d8..23567779029bd 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -52,7 +52,7 @@ struct device_attribute; #define ARCMSR_MAX_FREECCB_NUM 320 #define ARCMSR_MAX_OUTSTANDING_CMD 255 #endif -#define ARCMSR_DRIVER_VERSION "v1.30.00.04-20140919" +#define ARCMSR_DRIVER_VERSION "v1.30.00.21-20151019" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS 512 #define ARCMSR_MAX_XFER_SECTORS_B 4096 -- GitLab From f75ab39a4be08b996ca19002bd7b54df8fdb8d10 Mon Sep 17 00:00:00 2001 From: Ching Huang Date: Thu, 26 Nov 2015 19:33:56 +0800 Subject: [PATCH 0769/2855] arcmsr: more readability improvements Signed-off-by: Ching Huang Reviewed-by: Tomas Henzl Signed-off-by: Martin K. Petersen --- drivers/scsi/arcmsr/arcmsr_hba.c | 73 ++++++++++++-------------------- 1 file changed, 26 insertions(+), 47 deletions(-) diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 881be34afd8b1..a0c98bf508966 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -2814,53 +2814,32 @@ static bool arcmsr_hbaD_get_config(struct AdapterControlBlock *acb) acb->dma_coherent2 = dma_coherent2; reg = (struct MessageUnit_D *)dma_coherent2; acb->pmuD = reg; - reg->chip_id = acb->mem_base0 + ARCMSR_ARC1214_CHIP_ID; - reg->cpu_mem_config = acb->mem_base0 + - ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION; - reg->i2o_host_interrupt_mask = acb->mem_base0 + - ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK; - reg->sample_at_reset = acb->mem_base0 + ARCMSR_ARC1214_SAMPLE_RESET; - reg->reset_request = acb->mem_base0 + ARCMSR_ARC1214_RESET_REQUEST; - reg->host_int_status = acb->mem_base0 + - ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS; - reg->pcief0_int_enable = acb->mem_base0 + - ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE; - reg->inbound_msgaddr0 = acb->mem_base0 + - ARCMSR_ARC1214_INBOUND_MESSAGE0; - reg->inbound_msgaddr1 = acb->mem_base0 + - ARCMSR_ARC1214_INBOUND_MESSAGE1; - reg->outbound_msgaddr0 = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_MESSAGE0; - reg->outbound_msgaddr1 = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_MESSAGE1; - reg->inbound_doorbell = acb->mem_base0 + - ARCMSR_ARC1214_INBOUND_DOORBELL; - reg->outbound_doorbell = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_DOORBELL; - reg->outbound_doorbell_enable = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE; - reg->inboundlist_base_low = acb->mem_base0 + - ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW; - reg->inboundlist_base_high = acb->mem_base0 + - ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH; - reg->inboundlist_write_pointer = acb->mem_base0 + - ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER; - reg->outboundlist_base_low = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW; - reg->outboundlist_base_high = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH; - reg->outboundlist_copy_pointer = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER; - reg->outboundlist_read_pointer = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER; - reg->outboundlist_interrupt_cause = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE; - reg->outboundlist_interrupt_enable = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE; - reg->message_wbuffer = acb->mem_base0 + ARCMSR_ARC1214_MESSAGE_WBUFFER; - reg->message_rbuffer = acb->mem_base0 + ARCMSR_ARC1214_MESSAGE_RBUFFER; - reg->msgcode_rwbuffer = acb->mem_base0 + - ARCMSR_ARC1214_MESSAGE_RWBUFFER; + reg->chip_id = MEM_BASE0(ARCMSR_ARC1214_CHIP_ID); + reg->cpu_mem_config = MEM_BASE0(ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION); + reg->i2o_host_interrupt_mask = MEM_BASE0(ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK); + reg->sample_at_reset = MEM_BASE0(ARCMSR_ARC1214_SAMPLE_RESET); + reg->reset_request = MEM_BASE0(ARCMSR_ARC1214_RESET_REQUEST); + reg->host_int_status = MEM_BASE0(ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS); + reg->pcief0_int_enable = MEM_BASE0(ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE); + reg->inbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE0); + reg->inbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE1); + reg->outbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE0); + reg->outbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE1); + reg->inbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_INBOUND_DOORBELL); + reg->outbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL); + reg->outbound_doorbell_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE); + reg->inboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW); + reg->inboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH); + reg->inboundlist_write_pointer = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER); + reg->outboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW); + reg->outboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH); + reg->outboundlist_copy_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER); + reg->outboundlist_read_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER); + reg->outboundlist_interrupt_cause = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE); + reg->outboundlist_interrupt_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE); + reg->message_wbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_WBUFFER); + reg->message_rbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RBUFFER); + reg->msgcode_rwbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RWBUFFER); iop_firm_model = (char __iomem *)(®->msgcode_rwbuffer[15]); iop_firm_version = (char __iomem *)(®->msgcode_rwbuffer[17]); iop_device_map = (char __iomem *)(®->msgcode_rwbuffer[21]); -- GitLab From 02040670aaa0f125259ad8f9f5f30e4d138a65ae Mon Sep 17 00:00:00 2001 From: Ching Huang Date: Thu, 26 Nov 2015 19:41:15 +0800 Subject: [PATCH 0770/2855] arcmsr: Split dma resource allocation to a new function Split dma resource allocation and io register assignment from get_config to a new function arcmsr_alloc_io_queue. Signed-off-by: Ching Huang Reviewed-by: Tomas Henzl Signed-off-by: Martin K. Petersen --- drivers/scsi/arcmsr/arcmsr_hba.c | 175 ++++++++++++++++--------------- 1 file changed, 93 insertions(+), 82 deletions(-) diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index a0c98bf508966..7640498964a5b 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -498,6 +498,91 @@ static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb) } } +static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb) +{ + bool rtn = true; + void *dma_coherent; + dma_addr_t dma_coherent_handle; + struct pci_dev *pdev = acb->pdev; + + switch (acb->adapter_type) { + case ACB_ADAPTER_TYPE_B: { + struct MessageUnit_B *reg; + acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_B), 32); + dma_coherent = dma_zalloc_coherent(&pdev->dev, acb->roundup_ccbsize, + &dma_coherent_handle, GFP_KERNEL); + if (!dma_coherent) { + pr_notice("arcmsr%d: DMA allocation failed\n", acb->host->host_no); + return false; + } + acb->dma_coherent_handle2 = dma_coherent_handle; + acb->dma_coherent2 = dma_coherent; + reg = (struct MessageUnit_B *)dma_coherent; + acb->pmuB = reg; + if (acb->pdev->device == PCI_DEVICE_ID_ARECA_1203) { + reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_1203); + reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK_1203); + reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_1203); + reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK_1203); + } else { + reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL); + reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK); + reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL); + reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK); + } + reg->message_wbuffer = MEM_BASE1(ARCMSR_MESSAGE_WBUFFER); + reg->message_rbuffer = MEM_BASE1(ARCMSR_MESSAGE_RBUFFER); + reg->message_rwbuffer = MEM_BASE1(ARCMSR_MESSAGE_RWBUFFER); + } + break; + case ACB_ADAPTER_TYPE_D: { + struct MessageUnit_D *reg; + + acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_D), 32); + dma_coherent = dma_zalloc_coherent(&pdev->dev, acb->roundup_ccbsize, + &dma_coherent_handle, GFP_KERNEL); + if (!dma_coherent) { + pr_notice("arcmsr%d: DMA allocation failed\n", acb->host->host_no); + return false; + } + acb->dma_coherent_handle2 = dma_coherent_handle; + acb->dma_coherent2 = dma_coherent; + reg = (struct MessageUnit_D *)dma_coherent; + acb->pmuD = reg; + reg->chip_id = MEM_BASE0(ARCMSR_ARC1214_CHIP_ID); + reg->cpu_mem_config = MEM_BASE0(ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION); + reg->i2o_host_interrupt_mask = MEM_BASE0(ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK); + reg->sample_at_reset = MEM_BASE0(ARCMSR_ARC1214_SAMPLE_RESET); + reg->reset_request = MEM_BASE0(ARCMSR_ARC1214_RESET_REQUEST); + reg->host_int_status = MEM_BASE0(ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS); + reg->pcief0_int_enable = MEM_BASE0(ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE); + reg->inbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE0); + reg->inbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE1); + reg->outbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE0); + reg->outbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE1); + reg->inbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_INBOUND_DOORBELL); + reg->outbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL); + reg->outbound_doorbell_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE); + reg->inboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW); + reg->inboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH); + reg->inboundlist_write_pointer = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER); + reg->outboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW); + reg->outboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH); + reg->outboundlist_copy_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER); + reg->outboundlist_read_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER); + reg->outboundlist_interrupt_cause = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE); + reg->outboundlist_interrupt_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE); + reg->message_wbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_WBUFFER); + reg->message_rbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RBUFFER); + reg->msgcode_rwbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RWBUFFER); + } + break; + default: + break; + } + return rtn; +} + static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) { struct pci_dev *pdev = acb->pdev; @@ -742,9 +827,12 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id) if(!error){ goto pci_release_regs; } + error = arcmsr_alloc_io_queue(acb); + if (!error) + goto unmap_pci_region; error = arcmsr_get_firmware_spec(acb); if(!error){ - goto unmap_pci_region; + goto free_hbb_mu; } error = arcmsr_alloc_ccb_pool(acb); if(error){ @@ -2624,10 +2712,7 @@ static bool arcmsr_hbaA_get_config(struct AdapterControlBlock *acb) } static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) { - struct MessageUnit_B *reg; - struct pci_dev *pdev = acb->pdev; - void *dma_coherent; - dma_addr_t dma_coherent_handle; + struct MessageUnit_B *reg = acb->pmuB; char *acb_firm_model = acb->firm_model; char *acb_firm_version = acb->firm_version; char *acb_device_map = acb->device_map; @@ -2639,33 +2724,6 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) /*firm_version,21,84-99*/ int count; - acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_B), 32); - dma_coherent = dma_alloc_coherent(&pdev->dev, acb->roundup_ccbsize, - &dma_coherent_handle, GFP_KERNEL); - if (!dma_coherent){ - printk(KERN_NOTICE - "arcmsr%d: dma_alloc_coherent got error for hbb mu\n", - acb->host->host_no); - return false; - } - acb->dma_coherent_handle2 = dma_coherent_handle; - acb->dma_coherent2 = dma_coherent; - reg = (struct MessageUnit_B *)dma_coherent; - acb->pmuB = reg; - if (acb->pdev->device == PCI_DEVICE_ID_ARECA_1203) { - reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_1203); - reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK_1203); - reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_1203); - reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK_1203); - } else { - reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL); - reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK); - reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL); - reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK); - } - reg->message_wbuffer = MEM_BASE1(ARCMSR_MESSAGE_WBUFFER); - reg->message_rbuffer = MEM_BASE1(ARCMSR_MESSAGE_RBUFFER); - reg->message_rwbuffer = MEM_BASE1(ARCMSR_MESSAGE_RWBUFFER); iop_firm_model = (char __iomem *)(®->message_rwbuffer[15]); /*firm_model,15,60-67*/ iop_firm_version = (char __iomem *)(®->message_rwbuffer[17]); /*firm_version,17,68-83*/ iop_device_map = (char __iomem *)(®->message_rwbuffer[21]); /*firm_version,21,84-99*/ @@ -2674,13 +2732,13 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell); if (!arcmsr_hbaB_wait_msgint_ready(acb)) { printk(KERN_ERR "arcmsr%d: can't set driver mode.\n", acb->host->host_no); - goto err_free_dma; + return false; } writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell); if (!arcmsr_hbaB_wait_msgint_ready(acb)) { printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ miscellaneous data' timeout \n", acb->host->host_no); - goto err_free_dma; + return false; } count = 8; while (count){ @@ -2723,10 +2781,6 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) acb->firm_cfg_version = readl(®->message_rwbuffer[25]); /*firm_cfg_version,25,100-103*/ /*firm_ide_channels,4,16-19*/ return true; -err_free_dma: - dma_free_coherent(&acb->pdev->dev, acb->roundup_ccbsize, - acb->dma_coherent2, acb->dma_coherent_handle2); - return false; } static bool arcmsr_hbaC_get_config(struct AdapterControlBlock *pACB) @@ -2797,49 +2851,8 @@ static bool arcmsr_hbaD_get_config(struct AdapterControlBlock *acb) char __iomem *iop_firm_version; char __iomem *iop_device_map; u32 count; - struct MessageUnit_D *reg; - void *dma_coherent2; - dma_addr_t dma_coherent_handle2; - struct pci_dev *pdev = acb->pdev; + struct MessageUnit_D *reg = acb->pmuD; - acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_D), 32); - dma_coherent2 = dma_alloc_coherent(&pdev->dev, acb->roundup_ccbsize, - &dma_coherent_handle2, GFP_KERNEL); - if (!dma_coherent2) { - pr_notice("DMA allocation failed...\n"); - return false; - } - memset(dma_coherent2, 0, acb->roundup_ccbsize); - acb->dma_coherent_handle2 = dma_coherent_handle2; - acb->dma_coherent2 = dma_coherent2; - reg = (struct MessageUnit_D *)dma_coherent2; - acb->pmuD = reg; - reg->chip_id = MEM_BASE0(ARCMSR_ARC1214_CHIP_ID); - reg->cpu_mem_config = MEM_BASE0(ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION); - reg->i2o_host_interrupt_mask = MEM_BASE0(ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK); - reg->sample_at_reset = MEM_BASE0(ARCMSR_ARC1214_SAMPLE_RESET); - reg->reset_request = MEM_BASE0(ARCMSR_ARC1214_RESET_REQUEST); - reg->host_int_status = MEM_BASE0(ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS); - reg->pcief0_int_enable = MEM_BASE0(ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE); - reg->inbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE0); - reg->inbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE1); - reg->outbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE0); - reg->outbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE1); - reg->inbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_INBOUND_DOORBELL); - reg->outbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL); - reg->outbound_doorbell_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE); - reg->inboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW); - reg->inboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH); - reg->inboundlist_write_pointer = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER); - reg->outboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW); - reg->outboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH); - reg->outboundlist_copy_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER); - reg->outboundlist_read_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER); - reg->outboundlist_interrupt_cause = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE); - reg->outboundlist_interrupt_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE); - reg->message_wbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_WBUFFER); - reg->message_rbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RBUFFER); - reg->msgcode_rwbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RWBUFFER); iop_firm_model = (char __iomem *)(®->msgcode_rwbuffer[15]); iop_firm_version = (char __iomem *)(®->msgcode_rwbuffer[17]); iop_device_map = (char __iomem *)(®->msgcode_rwbuffer[21]); @@ -2854,8 +2867,6 @@ static bool arcmsr_hbaD_get_config(struct AdapterControlBlock *acb) if (!arcmsr_hbaD_wait_msgint_ready(acb)) { pr_notice("arcmsr%d: wait get adapter firmware " "miscellaneous data timeout\n", acb->host->host_no); - dma_free_coherent(&acb->pdev->dev, acb->roundup_ccbsize, - acb->dma_coherent2, acb->dma_coherent_handle2); return false; } count = 8; -- GitLab From 15d2639704b828db0506a416eda010178e1fd816 Mon Sep 17 00:00:00 2001 From: Ching Huang Date: Thu, 26 Nov 2015 19:44:55 +0800 Subject: [PATCH 0771/2855] arcmsr: change driver version to v1.30.00.22-20151126 Change driver version to v1.30.00.22-20151126 Signed-off-by: Ching Huang Reviewed-by: Tomas Henzl Signed-off-by: Martin K. Petersen --- drivers/scsi/arcmsr/arcmsr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 23567779029bd..cf99f8cf4cdd8 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -52,7 +52,7 @@ struct device_attribute; #define ARCMSR_MAX_FREECCB_NUM 320 #define ARCMSR_MAX_OUTSTANDING_CMD 255 #endif -#define ARCMSR_DRIVER_VERSION "v1.30.00.21-20151019" +#define ARCMSR_DRIVER_VERSION "v1.30.00.22-20151126" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS 512 #define ARCMSR_MAX_XFER_SECTORS_B 4096 -- GitLab From 173b77e8d8fe18e2792fa5dadebd2350f213abbe Mon Sep 17 00:00:00 2001 From: Liguo Zhang Date: Mon, 9 Nov 2015 13:43:58 +0800 Subject: [PATCH 0772/2855] i2c: mediatek: add i2c first write then read optimization For platform with auto restart support, between every transfer, i2c controller will trigger an interrupt and SW need to handle it to start new transfer. When doing write-then-read transfer, instead of restart mechanism, using WRRD mode to have controller send both transfer in one request to reduce latency. Signed-off-by: Liguo Zhang Reviewed-by: Eddie Huang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mt65xx.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 9b867169142fd..dc4aac64ac2e9 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -132,6 +132,7 @@ struct mtk_i2c_compatible { unsigned char pmic_i2c: 1; unsigned char dcm: 1; unsigned char auto_restart: 1; + unsigned char aux_len_reg: 1; }; struct mtk_i2c { @@ -153,6 +154,7 @@ struct mtk_i2c { enum mtk_trans_op op; u16 timing_reg; u16 high_speed_reg; + unsigned char auto_restart; const struct mtk_i2c_compatible *dev_comp; }; @@ -178,6 +180,7 @@ static const struct mtk_i2c_compatible mt6577_compat = { .pmic_i2c = 0, .dcm = 1, .auto_restart = 0, + .aux_len_reg = 0, }; static const struct mtk_i2c_compatible mt6589_compat = { @@ -185,6 +188,7 @@ static const struct mtk_i2c_compatible mt6589_compat = { .pmic_i2c = 1, .dcm = 0, .auto_restart = 0, + .aux_len_reg = 0, }; static const struct mtk_i2c_compatible mt8173_compat = { @@ -192,6 +196,7 @@ static const struct mtk_i2c_compatible mt8173_compat = { .pmic_i2c = 0, .dcm = 1, .auto_restart = 1, + .aux_len_reg = 1, }; static const struct of_device_id mtk_i2c_of_match[] = { @@ -373,7 +378,7 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs, i2c->irq_stat = 0; - if (i2c->dev_comp->auto_restart) + if (i2c->auto_restart) restart_flag = I2C_RS_TRANSFER; reinit_completion(&i2c->msg_complete); @@ -411,8 +416,14 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs, /* Set transfer and transaction len */ if (i2c->op == I2C_MASTER_WRRD) { - writew(msgs->len | ((msgs + 1)->len) << 8, - i2c->base + OFFSET_TRANSFER_LEN); + if (i2c->dev_comp->aux_len_reg) { + writew(msgs->len, i2c->base + OFFSET_TRANSFER_LEN); + writew((msgs + 1)->len, i2c->base + + OFFSET_TRANSFER_LEN_AUX); + } else { + writew(msgs->len | ((msgs + 1)->len) << 8, + i2c->base + OFFSET_TRANSFER_LEN); + } writew(I2C_WRRD_TRANAC_VALUE, i2c->base + OFFSET_TRANSAC_LEN); } else { writew(msgs->len, i2c->base + OFFSET_TRANSFER_LEN); @@ -461,7 +472,7 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs, writel(I2C_DMA_START_EN, i2c->pdmabase + OFFSET_EN); - if (!i2c->dev_comp->auto_restart) { + if (!i2c->auto_restart) { start_reg = I2C_TRANSAC_START; } else { start_reg = I2C_TRANSAC_START | I2C_RS_MUL_TRIG; @@ -518,6 +529,16 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, if (ret) return ret; + i2c->auto_restart = i2c->dev_comp->auto_restart; + + /* checking if we can skip restart and optimize using WRRD mode */ + if (i2c->auto_restart && num == 2) { + if (!(msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD) && + msgs[0].addr == msgs[1].addr) { + i2c->auto_restart = 0; + } + } + while (left_num--) { if (!msgs->buf) { dev_dbg(i2c->dev, "data buffer is NULL.\n"); @@ -530,7 +551,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, else i2c->op = I2C_MASTER_WR; - if (!i2c->dev_comp->auto_restart) { + if (!i2c->auto_restart) { if (num > 1) { /* combined two messages into one transaction */ i2c->op = I2C_MASTER_WRRD; @@ -559,7 +580,7 @@ static irqreturn_t mtk_i2c_irq(int irqno, void *dev_id) u16 restart_flag = 0; u16 intr_stat; - if (i2c->dev_comp->auto_restart) + if (i2c->auto_restart) restart_flag = I2C_RS_TRANSFER; intr_stat = readw(i2c->base + OFFSET_INTR_STAT); -- GitLab From 0401669797488feb055521cade69b1d0e81669db Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Mon, 16 Nov 2015 22:05:39 +0000 Subject: [PATCH 0773/2855] brcmnand: Clear EXT_ADDR error registers in PIO mode If an error occurs in flash above 4GB in PIO mode then the EXT_ADDR registers will be set to the location of the error and never cleared. Reset them to 0 before reading. Signed-off-by: Simon Arlott Signed-off-by: Brian Norris --- drivers/mtd/nand/brcmnand/brcmnand.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index 626a80eb76a1d..8feee1e489cbc 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -1405,6 +1405,8 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip, /* Clear error addresses */ brcmnand_write_reg(ctrl, BRCMNAND_UNCORR_ADDR, 0); brcmnand_write_reg(ctrl, BRCMNAND_CORR_ADDR, 0); + brcmnand_write_reg(ctrl, BRCMNAND_UNCORR_EXT_ADDR, 0); + brcmnand_write_reg(ctrl, BRCMNAND_CORR_EXT_ADDR, 0); brcmnand_write_reg(ctrl, BRCMNAND_CMD_EXT_ADDRESS, (host->cs << 16) | ((addr >> 32) & 0xffff)); -- GitLab From bad9764cfaaa15bc4263824b33956f15267442c6 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sat, 28 Nov 2015 16:33:56 +0000 Subject: [PATCH 0774/2855] scsi: ufs: fix spelling mistake in error message Minor issue, fix spelling mistake, Intialization -> Initialization Signed-off-by: Colin Ian King Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd-pltfrm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 9714f2a8b3297..d2a7b127b05c1 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -333,7 +333,7 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, err = ufshcd_init(hba, mmio_base, irq); if (err) { - dev_err(dev, "Intialization failed\n"); + dev_err(dev, "Initialization failed\n"); goto out_disable_rpm; } -- GitLab From 7789cd39274c51bf475411fe22a8ee7255082809 Mon Sep 17 00:00:00 2001 From: Luis de Bethencourt Date: Mon, 30 Nov 2015 14:32:17 +0000 Subject: [PATCH 0775/2855] mvsas: fix misleading indentation Fix a smatch warning: drivers/scsi/mvsas/mv_sas.c:740 mvs_task_prep() warn: curly braces intended? The code is correct, the indention is misleading. When the device is not ready we want to return SAS_PHY_DOWN. But current indentation makes it look like we only do so in the else branch of if (mvi_dev). Signed-off-by: Luis de Bethencourt Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/mvsas/mv_sas.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index 9c780740fb829..e712fe7459556 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c @@ -737,8 +737,8 @@ static int mvs_task_prep(struct sas_task *task, struct mvs_info *mvi, int is_tmf mv_dprintk("device %016llx not ready.\n", SAS_ADDR(dev->sas_addr)); - rc = SAS_PHY_DOWN; - return rc; + rc = SAS_PHY_DOWN; + return rc; } tei.port = dev->port->lldd_port; if (tei.port && !tei.port->port_attached && !tmf) { -- GitLab From 081976bcc0cbc84f5164fb7aa0e5cf597df6de9e Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 19 Nov 2015 22:32:15 +0100 Subject: [PATCH 0776/2855] mtd: brcmnand: improve memory management This patch addresses two related memory management issues in the probe function: 1. for_each_available_child_of_node performs an of_node_get on each iteration, so a break out of the loop requires an of_node_put. A simplified version of the semantic patch that fixes this problem is as follows (http://coccinelle.lip6.fr): // @@ expression root,e; local idexpression child; @@ for_each_available_child_of_node(root, child) { ... when != of_node_put(child) when != e = child ( return child; | + of_node_put(child); ? return ...; ) ... } // 2. The devm_kzalloc'd data is not used if brcmnand_init_cs fails. Free it immediately, using devm_kfree in this case, instead of waiting for the remove function. Signed-off-by: Julia Lawall Signed-off-by: Brian Norris --- drivers/mtd/nand/brcmnand/brcmnand.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index 8feee1e489cbc..ad756f626f4be 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -2233,15 +2233,19 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) struct brcmnand_host *host; host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); - if (!host) + if (!host) { + of_node_put(child); return -ENOMEM; + } host->pdev = pdev; host->ctrl = ctrl; host->of_node = child; ret = brcmnand_init_cs(host); - if (ret) + if (ret) { + devm_kfree(dev, host); continue; /* Try all chip-selects */ + } list_add_tail(&host->node, &ctrl->host_list); } -- GitLab From a81c0f07b4a7559eecebf77bcc1956d9d777b006 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 18 Nov 2015 23:04:12 +0100 Subject: [PATCH 0777/2855] mtd: nand: sunxi: add missing of_node_put for_each_child_of_node performs an of_node_get on each iteration, so a break out of the loop requires an of_node_put. A simplified version of the semantic patch that fixes this problem is as follows (http://coccinelle.lip6.fr): // @@ expression root,e; local idexpression child; @@ for_each_child_of_node(root, child) { ... when != of_node_put(child) when != e = child ( return child; | + of_node_put(child); ? return ...; ) ... } // Signed-off-by: Julia Lawall Acked-by: Chen-Yu Tsai Acked-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/sunxi_nand.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index 2ed52e466ea64..1bbcc0c2aab51 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c @@ -1391,8 +1391,10 @@ static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc) for_each_child_of_node(np, nand_np) { ret = sunxi_nand_chip_init(dev, nfc, nand_np); - if (ret) + if (ret) { + of_node_put(nand_np); return ret; + } } return 0; -- GitLab From 31a40e2b052c0f2b80df7b56928f9d5ff9c96933 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 12 Nov 2015 16:44:42 +1100 Subject: [PATCH 0778/2855] powerpc/64: Include KVM guest test in all interrupt vectors Currently, if HV KVM is configured but PR KVM isn't, we don't include a test to see whether we were interrupted in KVM guest context for the set of interrupts which get delivered directly to the guest by hardware if they occur in the guest. This includes things like program interrupts. However, the recent bug where userspace could set the MSR for a VCPU to have an illegal value in the TS field, and thus cause a TM Bad Thing type of program interrupt on the hrfid that enters the guest, showed that we can never be completely sure that these interrupts can never occur in the guest entry/exit code. If one of these interrupts does happen and we have HV KVM configured but not PR KVM, then we end up trying to run the handler in the host with the MMU set to the guest MMU context, which generally ends badly. Thus, for robustness it is better to have the test in every interrupt vector, so that if some way is found to trigger some interrupt in the guest entry/exit path, we can handle it without immediately crashing the host. This means that the distinction between KVMTEST and KVMTEST_PR goes away. Thus we delete KVMTEST_PR and associated macros and use KVMTEST everywhere that we previously used either KVMTEST_PR or KVMTEST. It also means that SOFTEN_TEST_HV_201 becomes the same as SOFTEN_TEST_PR, so we deleted SOFTEN_TEST_HV_201 and use SOFTEN_TEST_PR instead. Signed-off-by: Paul Mackerras Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 21 +++------------ arch/powerpc/kernel/exceptions-64s.S | 34 ++++++++++++------------ 2 files changed, 20 insertions(+), 35 deletions(-) diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 77f52b26dad6c..9ee10781121fc 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -263,17 +263,6 @@ do_kvm_##n: \ #define KVM_HANDLER_SKIP(area, h, n) #endif -#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE -#define KVMTEST_PR(n) __KVMTEST(n) -#define KVM_HANDLER_PR(area, h, n) __KVM_HANDLER(area, h, n) -#define KVM_HANDLER_PR_SKIP(area, h, n) __KVM_HANDLER_SKIP(area, h, n) - -#else -#define KVMTEST_PR(n) -#define KVM_HANDLER_PR(area, h, n) -#define KVM_HANDLER_PR_SKIP(area, h, n) -#endif - #define NOTEST(n) /* @@ -360,13 +349,13 @@ label##_pSeries: \ HMT_MEDIUM_PPR_DISCARD; \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ - EXC_STD, KVMTEST_PR, vec) + EXC_STD, KVMTEST, vec) /* Version of above for when we have to branch out-of-line */ #define STD_EXCEPTION_PSERIES_OOL(vec, label) \ .globl label##_pSeries; \ label##_pSeries: \ - EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, vec); \ + EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST, vec); \ EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_STD) #define STD_EXCEPTION_HV(loc, vec, label) \ @@ -436,17 +425,13 @@ label##_relon_hv: \ #define _SOFTEN_TEST(h, vec) __SOFTEN_TEST(h, vec) #define SOFTEN_TEST_PR(vec) \ - KVMTEST_PR(vec); \ + KVMTEST(vec); \ _SOFTEN_TEST(EXC_STD, vec) #define SOFTEN_TEST_HV(vec) \ KVMTEST(vec); \ _SOFTEN_TEST(EXC_HV, vec) -#define SOFTEN_TEST_HV_201(vec) \ - KVMTEST(vec); \ - _SOFTEN_TEST(EXC_STD, vec) - #define SOFTEN_NOTEST_PR(vec) _SOFTEN_TEST(EXC_STD, vec) #define SOFTEN_NOTEST_HV(vec) _SOFTEN_TEST(EXC_HV, vec) diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 0a0399c2af119..1a03142a69fd1 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -242,7 +242,7 @@ instruction_access_slb_pSeries: HMT_MEDIUM_PPR_DISCARD SET_SCRATCH0(r13) EXCEPTION_PROLOG_0(PACA_EXSLB) - EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x480) + EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x480) std r3,PACA_EXSLB+EX_R3(r13) mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ #ifdef __DISABLED__ @@ -276,18 +276,18 @@ hardware_interrupt_hv: KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x502) FTR_SECTION_ELSE _MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt, - EXC_STD, SOFTEN_TEST_HV_201) + EXC_STD, SOFTEN_TEST_PR) KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x500) ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) STD_EXCEPTION_PSERIES(0x600, 0x600, alignment) - KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x600) + KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x600) STD_EXCEPTION_PSERIES(0x700, 0x700, program_check) - KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x700) + KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x700) STD_EXCEPTION_PSERIES(0x800, 0x800, fp_unavailable) - KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x800) + KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x800) . = 0x900 .globl decrementer_pSeries @@ -297,10 +297,10 @@ decrementer_pSeries: STD_EXCEPTION_HV(0x980, 0x982, hdecrementer) MASKABLE_EXCEPTION_PSERIES(0xa00, 0xa00, doorbell_super) - KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xa00) + KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xa00) STD_EXCEPTION_PSERIES(0xb00, 0xb00, trap_0b) - KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xb00) + KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xb00) . = 0xc00 .globl system_call_pSeries @@ -332,7 +332,7 @@ system_call_pSeries: KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xc00) STD_EXCEPTION_PSERIES(0xd00, 0xd00, single_step) - KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xd00) + KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xd00) /* At 0xe??? we have a bunch of hypervisor exceptions, we branch * out of line to handle them @@ -408,7 +408,7 @@ hv_facility_unavailable_trampoline: #endif /* CONFIG_CBE_RAS */ STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint) - KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_STD, 0x1300) + KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x1300) . = 0x1500 .global denorm_exception_hv @@ -436,7 +436,7 @@ denorm_exception_hv: #endif /* CONFIG_CBE_RAS */ STD_EXCEPTION_PSERIES(0x1700, 0x1700, altivec_assist) - KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x1700) + KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x1700) #ifdef CONFIG_CBE_RAS STD_EXCEPTION_HV(0x1800, 0x1802, cbe_thermal) @@ -536,9 +536,9 @@ machine_check_pSeries_0: KVM_HANDLER_SKIP(PACA_EXMC, EXC_STD, 0x200) KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300) KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380) - KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x400) - KVM_HANDLER_PR(PACA_EXSLB, EXC_STD, 0x480) - KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x900) + KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x400) + KVM_HANDLER(PACA_EXSLB, EXC_STD, 0x480) + KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x900) KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x982) #ifdef CONFIG_PPC_DENORMALISATION @@ -621,13 +621,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) /* moved from 0xf00 */ STD_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor) - KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf00) + KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xf00) STD_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable) - KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf20) + KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xf20) STD_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable) - KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf40) + KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xf40) STD_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable) - KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf60) + KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xf60) STD_EXCEPTION_HV_OOL(0xf82, facility_unavailable) KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xf82) -- GitLab From 07e45c120c9c61b792be62182b0a8f706ee2ab24 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:43:53 +1100 Subject: [PATCH 0779/2855] powerpc: Don't disable kernel FP/VMX/VSX MSR bits on context switch Writing the MSR is slow, so we want to avoid it whenever possible. A subsequent patch will add a debug option that strictly manages the FP/VMX/VSX unavailable bits. For now just remove it, matching what we do in other areas of the kernel (eg enable_kernel_altivec()). A context switch microbenchmark using yield(): http://ozlabs.org/~anton/junkcode/context_switch2.c ./context_switch2 --test=yield --fp 0 0 shows an improvement of almost 3% on POWER8. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/entry_64.S | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index a94f155db78e8..93bb284fddf94 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -453,26 +453,13 @@ _GLOBAL(_switch) SAVE_8GPRS(14, r1) SAVE_10GPRS(22, r1) mflr r20 /* Return to switch caller */ - mfmsr r22 - li r0, MSR_FP -#ifdef CONFIG_VSX -BEGIN_FTR_SECTION - oris r0,r0,MSR_VSX@h /* Disable VSX */ -END_FTR_SECTION_IFSET(CPU_FTR_VSX) -#endif /* CONFIG_VSX */ #ifdef CONFIG_ALTIVEC BEGIN_FTR_SECTION - oris r0,r0,MSR_VEC@h /* Disable altivec */ mfspr r24,SPRN_VRSAVE /* save vrsave register value */ std r24,THREAD_VRSAVE(r3) END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif /* CONFIG_ALTIVEC */ - and. r0,r0,r22 - beq+ 1f - andc r22,r22,r0 - MTMSRD(r22) - isync -1: std r20,_NIP(r1) + std r20,_NIP(r1) mfcr r23 std r23,_CCR(r1) std r1,KSP(r3) /* Set old stack pointer */ -- GitLab From af72ab646a6bee724f190820e8f56497a5b635f0 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:43:54 +1100 Subject: [PATCH 0780/2855] powerpc: Don't disable MSR bits in do_load_up_transact_*() functions Similar to the non TM load_up_*() functions, don't disable the MSR bits on the way out. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/fpu.S | 4 ---- arch/powerpc/kernel/vector.S | 4 ---- 2 files changed, 8 deletions(-) diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 9ad236e5d2c9d..38eb79b8a0349 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S @@ -73,10 +73,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) MTFSF_L(fr0) REST_32FPVSRS(0, R4, R7) - /* FP/VSX off again */ - MTMSRD(r6) - SYNC - blr #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S index f5c80d567d8d1..1c5425966204f 100644 --- a/arch/powerpc/kernel/vector.S +++ b/arch/powerpc/kernel/vector.S @@ -29,10 +29,6 @@ _GLOBAL(do_load_up_transact_altivec) addi r10,r3,THREAD_TRANSACT_VRSTATE REST_32VRS(0,r4,r10) - /* Disable VEC again. */ - MTMSRD(r6) - isync - blr #endif -- GitLab From 152d523e6307c7152f9986a542f873b5c5863937 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:43:55 +1100 Subject: [PATCH 0781/2855] powerpc: Create context switch helpers save_sprs() and restore_sprs() Move all our context switch SPR save and restore code into two helpers. We do a few optimisations: - Group all mfsprs and all mtsprs. In many cases an mtspr sets a scoreboarding bit that an mfspr waits on, so the current practise of mfspr A; mtspr A; mfpsr B; mtspr B is the worst scheduling we can do. - SPR writes are slow, so check that the value is changing before writing it. A context switch microbenchmark using yield(): http://ozlabs.org/~anton/junkcode/context_switch2.c ./context_switch2 --test=yield 0 0 shows an improvement of almost 10% on POWER8. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/processor.h | 1 + arch/powerpc/include/asm/switch_to.h | 11 ---- arch/powerpc/kernel/entry_64.S | 60 +----------------- arch/powerpc/kernel/process.c | 92 ++++++++++++++++++++++++---- 4 files changed, 82 insertions(+), 82 deletions(-) diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 5afea361beaae..c273f3e0ba842 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -294,6 +294,7 @@ struct thread_struct { #endif #ifdef CONFIG_PPC64 unsigned long dscr; + unsigned long fscr; /* * This member element dscr_inherit indicates that the process * has explicitly attempted and changed the DSCR register value diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 15cca17cba4b9..33a071d24ba80 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -15,17 +15,6 @@ extern struct task_struct *__switch_to(struct task_struct *, struct thread_struct; extern struct task_struct *_switch(struct thread_struct *prev, struct thread_struct *next); -#ifdef CONFIG_PPC_BOOK3S_64 -static inline void save_early_sprs(struct thread_struct *prev) -{ - if (cpu_has_feature(CPU_FTR_ARCH_207S)) - prev->tar = mfspr(SPRN_TAR); - if (cpu_has_feature(CPU_FTR_DSCR)) - prev->dscr = mfspr(SPRN_DSCR); -} -#else -static inline void save_early_sprs(struct thread_struct *prev) {} -#endif extern void enable_kernel_fp(void); extern void enable_kernel_altivec(void); diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 93bb284fddf94..e84e5bc7fe345 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -453,29 +453,12 @@ _GLOBAL(_switch) SAVE_8GPRS(14, r1) SAVE_10GPRS(22, r1) mflr r20 /* Return to switch caller */ -#ifdef CONFIG_ALTIVEC -BEGIN_FTR_SECTION - mfspr r24,SPRN_VRSAVE /* save vrsave register value */ - std r24,THREAD_VRSAVE(r3) -END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) -#endif /* CONFIG_ALTIVEC */ + std r20,_NIP(r1) mfcr r23 std r23,_CCR(r1) std r1,KSP(r3) /* Set old stack pointer */ -#ifdef CONFIG_PPC_BOOK3S_64 -BEGIN_FTR_SECTION - /* Event based branch registers */ - mfspr r0, SPRN_BESCR - std r0, THREAD_BESCR(r3) - mfspr r0, SPRN_EBBHR - std r0, THREAD_EBBHR(r3) - mfspr r0, SPRN_EBBRR - std r0, THREAD_EBBRR(r3) -END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) -#endif - #ifdef CONFIG_SMP /* We need a sync somewhere here to make sure that if the * previous task gets rescheduled on another CPU, it sees all @@ -563,47 +546,6 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) mr r1,r8 /* start using new stack pointer */ std r7,PACAKSAVE(r13) -#ifdef CONFIG_PPC_BOOK3S_64 -BEGIN_FTR_SECTION - /* Event based branch registers */ - ld r0, THREAD_BESCR(r4) - mtspr SPRN_BESCR, r0 - ld r0, THREAD_EBBHR(r4) - mtspr SPRN_EBBHR, r0 - ld r0, THREAD_EBBRR(r4) - mtspr SPRN_EBBRR, r0 - - ld r0,THREAD_TAR(r4) - mtspr SPRN_TAR,r0 -END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) -#endif - -#ifdef CONFIG_ALTIVEC -BEGIN_FTR_SECTION - ld r0,THREAD_VRSAVE(r4) - mtspr SPRN_VRSAVE,r0 /* if G4, restore VRSAVE reg */ -END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) -#endif /* CONFIG_ALTIVEC */ -#ifdef CONFIG_PPC64 -BEGIN_FTR_SECTION - lwz r6,THREAD_DSCR_INHERIT(r4) - ld r0,THREAD_DSCR(r4) - cmpwi r6,0 - bne 1f - ld r0,PACA_DSCR_DEFAULT(r13) -1: -BEGIN_FTR_SECTION_NESTED(70) - mfspr r8, SPRN_FSCR - rldimi r8, r6, FSCR_DSCR_LG, (63 - FSCR_DSCR_LG) - mtspr SPRN_FSCR, r8 -END_FTR_SECTION_NESTED(CPU_FTR_ARCH_207S, CPU_FTR_ARCH_207S, 70) - cmpd r0,r25 - beq 2f - mtspr SPRN_DSCR,r0 -2: -END_FTR_SECTION_IFSET(CPU_FTR_DSCR) -#endif - ld r6,_CCR(r1) mtcrf 0xFF,r6 diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 75b6676c1a0b9..3aabed4a60a99 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -742,6 +742,73 @@ void restore_tm_state(struct pt_regs *regs) #define __switch_to_tm(prev) #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ +static inline void save_sprs(struct thread_struct *t) +{ +#ifdef CONFIG_ALTIVEC + if (cpu_has_feature(cpu_has_feature(CPU_FTR_ALTIVEC))) + t->vrsave = mfspr(SPRN_VRSAVE); +#endif +#ifdef CONFIG_PPC_BOOK3S_64 + if (cpu_has_feature(CPU_FTR_DSCR)) + t->dscr = mfspr(SPRN_DSCR); + + if (cpu_has_feature(CPU_FTR_ARCH_207S)) { + t->bescr = mfspr(SPRN_BESCR); + t->ebbhr = mfspr(SPRN_EBBHR); + t->ebbrr = mfspr(SPRN_EBBRR); + + t->fscr = mfspr(SPRN_FSCR); + + /* + * Note that the TAR is not available for use in the kernel. + * (To provide this, the TAR should be backed up/restored on + * exception entry/exit instead, and be in pt_regs. FIXME, + * this should be in pt_regs anyway (for debug).) + */ + t->tar = mfspr(SPRN_TAR); + } +#endif +} + +static inline void restore_sprs(struct thread_struct *old_thread, + struct thread_struct *new_thread) +{ +#ifdef CONFIG_ALTIVEC + if (cpu_has_feature(CPU_FTR_ALTIVEC) && + old_thread->vrsave != new_thread->vrsave) + mtspr(SPRN_VRSAVE, new_thread->vrsave); +#endif +#ifdef CONFIG_PPC_BOOK3S_64 + if (cpu_has_feature(CPU_FTR_DSCR)) { + u64 dscr = get_paca()->dscr_default; + u64 fscr = old_thread->fscr & ~FSCR_DSCR; + + if (new_thread->dscr_inherit) { + dscr = new_thread->dscr; + fscr |= FSCR_DSCR; + } + + if (old_thread->dscr != dscr) + mtspr(SPRN_DSCR, dscr); + + if (old_thread->fscr != fscr) + mtspr(SPRN_FSCR, fscr); + } + + if (cpu_has_feature(CPU_FTR_ARCH_207S)) { + if (old_thread->bescr != new_thread->bescr) + mtspr(SPRN_BESCR, new_thread->bescr); + if (old_thread->ebbhr != new_thread->ebbhr) + mtspr(SPRN_EBBHR, new_thread->ebbhr); + if (old_thread->ebbrr != new_thread->ebbrr) + mtspr(SPRN_EBBRR, new_thread->ebbrr); + + if (old_thread->tar != new_thread->tar) + mtspr(SPRN_TAR, new_thread->tar); + } +#endif +} + struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *new) { @@ -751,17 +818,16 @@ struct task_struct *__switch_to(struct task_struct *prev, struct ppc64_tlb_batch *batch; #endif + new_thread = &new->thread; + old_thread = ¤t->thread; + WARN_ON(!irqs_disabled()); - /* Back up the TAR and DSCR across context switches. - * Note that the TAR is not available for use in the kernel. (To - * provide this, the TAR should be backed up/restored on exception - * entry/exit instead, and be in pt_regs. FIXME, this should be in - * pt_regs anyway (for debug).) - * Save the TAR and DSCR here before we do treclaim/trecheckpoint as - * these will change them. + /* + * We need to save SPRs before treclaim/trecheckpoint as these will + * change a number of them. */ - save_early_sprs(&prev->thread); + save_sprs(&prev->thread); __switch_to_tm(prev); @@ -844,10 +910,6 @@ struct task_struct *__switch_to(struct task_struct *prev, #endif /* CONFIG_HAVE_HW_BREAKPOINT */ #endif - - new_thread = &new->thread; - old_thread = ¤t->thread; - #ifdef CONFIG_PPC64 /* * Collect processor utilization data per process @@ -883,6 +945,10 @@ struct task_struct *__switch_to(struct task_struct *prev, last = _switch(old_thread, new_thread); + /* Need to recalculate these after calling _switch() */ + old_thread = &last->thread; + new_thread = ¤t->thread; + #ifdef CONFIG_PPC_BOOK3S_64 if (current_thread_info()->local_flags & _TLF_LAZY_MMU) { current_thread_info()->local_flags &= ~_TLF_LAZY_MMU; @@ -891,6 +957,8 @@ struct task_struct *__switch_to(struct task_struct *prev, } #endif /* CONFIG_PPC_BOOK3S_64 */ + restore_sprs(old_thread, new_thread); + return last; } -- GitLab From 68bfa962bff5783ad65de9dc7f3b9e16ea466766 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:43:56 +1100 Subject: [PATCH 0782/2855] powerpc: Remove redundant mflr in _switch No need to execute mflr twice. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/entry_64.S | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index e84e5bc7fe345..c8b4225a0095a 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -452,9 +452,7 @@ _GLOBAL(_switch) /* r3-r13 are caller saved -- Cort */ SAVE_8GPRS(14, r1) SAVE_10GPRS(22, r1) - mflr r20 /* Return to switch caller */ - - std r20,_NIP(r1) + std r0,_NIP(r1) /* Return to switch caller */ mfcr r23 std r23,_CCR(r1) std r1,KSP(r3) /* Set old stack pointer */ -- GitLab From af1bbc3dd3d501d27da72e1764afe5f5b0d3882d Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:43:57 +1100 Subject: [PATCH 0783/2855] powerpc: Remove UP only lazy floating point and vector optimisations The UP only lazy floating point and vector optimisations were written back when SMP was not common, and neither glibc nor gcc used vector instructions. Now SMP is very common, glibc aggressively uses vector instructions and gcc autovectorises. We want to add new optimisations that apply to both UP and SMP, but in preparation for that remove these UP only optimisations. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/processor.h | 6 -- arch/powerpc/include/asm/switch_to.h | 8 -- arch/powerpc/kernel/fpu.S | 35 --------- arch/powerpc/kernel/head_fsl_booke.S | 32 -------- arch/powerpc/kernel/idle_power7.S | 7 -- arch/powerpc/kernel/process.c | 113 +-------------------------- arch/powerpc/kernel/signal_32.c | 18 ----- arch/powerpc/kernel/signal_64.c | 18 ----- arch/powerpc/kernel/vector.S | 68 ---------------- 9 files changed, 1 insertion(+), 304 deletions(-) diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index c273f3e0ba842..a2e8918408064 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -88,12 +88,6 @@ struct task_struct; void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp); void release_thread(struct task_struct *); -/* Lazy FPU handling on uni-processor */ -extern struct task_struct *last_task_used_math; -extern struct task_struct *last_task_used_altivec; -extern struct task_struct *last_task_used_vsx; -extern struct task_struct *last_task_used_spe; - #ifdef CONFIG_PPC32 #if CONFIG_TASK_SIZE > CONFIG_KERNEL_START diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 33a071d24ba80..bd1d93318350d 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -27,14 +27,6 @@ extern void giveup_spe(struct task_struct *); extern void load_up_spe(struct task_struct *); extern void switch_booke_debug_regs(struct debug_reg *new_debug); -#ifndef CONFIG_SMP -extern void discard_lazy_cpu_state(void); -#else -static inline void discard_lazy_cpu_state(void) -{ -} -#endif - #ifdef CONFIG_PPC_FPU extern void flush_fp_to_thread(struct task_struct *); extern void giveup_fpu(struct task_struct *); diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 38eb79b8a0349..50d2352f2cf45 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S @@ -132,31 +132,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) SYNC MTMSRD(r5) /* enable use of fpu now */ isync -/* - * For SMP, we don't do lazy FPU switching because it just gets too - * horrendously complex, especially when a task switches from one CPU - * to another. Instead we call giveup_fpu in switch_to. - */ -#ifndef CONFIG_SMP - LOAD_REG_ADDRBASE(r3, last_task_used_math) - toreal(r3) - PPC_LL r4,ADDROFF(last_task_used_math)(r3) - PPC_LCMPI 0,r4,0 - beq 1f - toreal(r4) - addi r4,r4,THREAD /* want last_task_used_math->thread */ - addi r10,r4,THREAD_FPSTATE - SAVE_32FPVSRS(0, R5, R10) - mffs fr0 - stfd fr0,FPSTATE_FPSCR(r10) - PPC_LL r5,PT_REGS(r4) - toreal(r5) - PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) - li r10,MSR_FP|MSR_FE0|MSR_FE1 - andc r4,r4,r10 /* disable FP for previous task */ - PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: -#endif /* CONFIG_SMP */ /* enable use of FP after return */ #ifdef CONFIG_PPC32 mfspr r5,SPRN_SPRG_THREAD /* current task's THREAD (phys) */ @@ -175,11 +150,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) lfd fr0,FPSTATE_FPSCR(r10) MTFSF_L(fr0) REST_32FPVSRS(0, R4, R10) -#ifndef CONFIG_SMP - subi r4,r5,THREAD - fromreal(r4) - PPC_STL r4,ADDROFF(last_task_used_math)(r3) -#endif /* CONFIG_SMP */ /* restore registers and return */ /* we haven't used ctr or xer or lr */ blr @@ -226,11 +196,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) andc r4,r4,r3 /* disable FP for previous task */ PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) 1: -#ifndef CONFIG_SMP - li r5,0 - LOAD_REG_ADDRBASE(r4,last_task_used_math) - PPC_STL r5,ADDROFF(last_task_used_math)(r4) -#endif /* CONFIG_SMP */ blr /* diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index fffd1f96bb1d0..ec936abbcadcc 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -857,29 +857,6 @@ _GLOBAL(load_up_spe) oris r5,r5,MSR_SPE@h mtmsr r5 /* enable use of SPE now */ isync -/* - * For SMP, we don't do lazy SPE switching because it just gets too - * horrendously complex, especially when a task switches from one CPU - * to another. Instead we call giveup_spe in switch_to. - */ -#ifndef CONFIG_SMP - lis r3,last_task_used_spe@ha - lwz r4,last_task_used_spe@l(r3) - cmpi 0,r4,0 - beq 1f - addi r4,r4,THREAD /* want THREAD of last_task_used_spe */ - SAVE_32EVRS(0,r10,r4,THREAD_EVR0) - evxor evr10, evr10, evr10 /* clear out evr10 */ - evmwumiaa evr10, evr10, evr10 /* evr10 <- ACC = 0 * 0 + ACC */ - li r5,THREAD_ACC - evstddx evr10, r4, r5 /* save off accumulator */ - lwz r5,PT_REGS(r4) - lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) - lis r10,MSR_SPE@h - andc r4,r4,r10 /* disable SPE for previous task */ - stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: -#endif /* !CONFIG_SMP */ /* enable use of SPE after return */ oris r9,r9,MSR_SPE@h mfspr r5,SPRN_SPRG_THREAD /* current task's THREAD (phys) */ @@ -889,10 +866,6 @@ _GLOBAL(load_up_spe) evlddx evr4,r10,r5 evmra evr4,evr4 REST_32EVRS(0,r10,r5,THREAD_EVR0) -#ifndef CONFIG_SMP - subi r4,r5,THREAD - stw r4,last_task_used_spe@l(r3) -#endif /* !CONFIG_SMP */ blr /* @@ -1035,11 +1008,6 @@ _GLOBAL(giveup_spe) andc r4,r4,r3 /* disable SPE for previous task */ stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) 1: -#ifndef CONFIG_SMP - li r5,0 - lis r4,last_task_used_spe@ha - stw r5,last_task_used_spe@l(r4) -#endif /* !CONFIG_SMP */ blr #endif /* CONFIG_SPE */ diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S index 112ccf4975620..cf4fb5429cf12 100644 --- a/arch/powerpc/kernel/idle_power7.S +++ b/arch/powerpc/kernel/idle_power7.S @@ -89,13 +89,6 @@ _GLOBAL(power7_powersave_common) std r0,_LINK(r1) std r0,_NIP(r1) -#ifndef CONFIG_SMP - /* Make sure FPU, VSX etc... are flushed as we may lose - * state when going to nap mode - */ - bl discard_lazy_cpu_state -#endif /* CONFIG_SMP */ - /* Hard disable interrupts */ mfmsr r9 rldicl r9,r9,48,1 diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 3aabed4a60a99..e098f43156434 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -67,13 +67,6 @@ extern unsigned long _get_SP(void); -#ifndef CONFIG_SMP -struct task_struct *last_task_used_math = NULL; -struct task_struct *last_task_used_altivec = NULL; -struct task_struct *last_task_used_vsx = NULL; -struct task_struct *last_task_used_spe = NULL; -#endif - #ifdef CONFIG_PPC_TRANSACTIONAL_MEM void giveup_fpu_maybe_transactional(struct task_struct *tsk) { @@ -134,16 +127,14 @@ void flush_fp_to_thread(struct task_struct *tsk) */ preempt_disable(); if (tsk->thread.regs->msr & MSR_FP) { -#ifdef CONFIG_SMP /* * This should only ever be called for current or * for a stopped child process. Since we save away - * the FP register state on context switch on SMP, + * the FP register state on context switch, * there is something wrong if a stopped child appears * to still have its FP state in the CPU registers. */ BUG_ON(tsk != current); -#endif giveup_fpu_maybe_transactional(tsk); } preempt_enable(); @@ -156,14 +147,10 @@ void enable_kernel_fp(void) { WARN_ON(preemptible()); -#ifdef CONFIG_SMP if (current->thread.regs && (current->thread.regs->msr & MSR_FP)) giveup_fpu_maybe_transactional(current); else giveup_fpu(NULL); /* just enables FP for kernel */ -#else - giveup_fpu_maybe_transactional(last_task_used_math); -#endif /* CONFIG_SMP */ } EXPORT_SYMBOL(enable_kernel_fp); @@ -172,14 +159,10 @@ void enable_kernel_altivec(void) { WARN_ON(preemptible()); -#ifdef CONFIG_SMP if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) giveup_altivec_maybe_transactional(current); else giveup_altivec_notask(); -#else - giveup_altivec_maybe_transactional(last_task_used_altivec); -#endif /* CONFIG_SMP */ } EXPORT_SYMBOL(enable_kernel_altivec); @@ -192,9 +175,7 @@ void flush_altivec_to_thread(struct task_struct *tsk) if (tsk->thread.regs) { preempt_disable(); if (tsk->thread.regs->msr & MSR_VEC) { -#ifdef CONFIG_SMP BUG_ON(tsk != current); -#endif giveup_altivec_maybe_transactional(tsk); } preempt_enable(); @@ -208,14 +189,10 @@ void enable_kernel_vsx(void) { WARN_ON(preemptible()); -#ifdef CONFIG_SMP if (current->thread.regs && (current->thread.regs->msr & MSR_VSX)) giveup_vsx(current); else giveup_vsx(NULL); /* just enable vsx for kernel - force */ -#else - giveup_vsx(last_task_used_vsx); -#endif /* CONFIG_SMP */ } EXPORT_SYMBOL(enable_kernel_vsx); @@ -232,9 +209,7 @@ void flush_vsx_to_thread(struct task_struct *tsk) if (tsk->thread.regs) { preempt_disable(); if (tsk->thread.regs->msr & MSR_VSX) { -#ifdef CONFIG_SMP BUG_ON(tsk != current); -#endif giveup_vsx(tsk); } preempt_enable(); @@ -249,14 +224,10 @@ void enable_kernel_spe(void) { WARN_ON(preemptible()); -#ifdef CONFIG_SMP if (current->thread.regs && (current->thread.regs->msr & MSR_SPE)) giveup_spe(current); else giveup_spe(NULL); /* just enable SPE for kernel - force */ -#else - giveup_spe(last_task_used_spe); -#endif /* __SMP __ */ } EXPORT_SYMBOL(enable_kernel_spe); @@ -265,9 +236,7 @@ void flush_spe_to_thread(struct task_struct *tsk) if (tsk->thread.regs) { preempt_disable(); if (tsk->thread.regs->msr & MSR_SPE) { -#ifdef CONFIG_SMP BUG_ON(tsk != current); -#endif tsk->thread.spefscr = mfspr(SPRN_SPEFSCR); giveup_spe(tsk); } @@ -276,32 +245,6 @@ void flush_spe_to_thread(struct task_struct *tsk) } #endif /* CONFIG_SPE */ -#ifndef CONFIG_SMP -/* - * If we are doing lazy switching of CPU state (FP, altivec or SPE), - * and the current task has some state, discard it. - */ -void discard_lazy_cpu_state(void) -{ - preempt_disable(); - if (last_task_used_math == current) - last_task_used_math = NULL; -#ifdef CONFIG_ALTIVEC - if (last_task_used_altivec == current) - last_task_used_altivec = NULL; -#endif /* CONFIG_ALTIVEC */ -#ifdef CONFIG_VSX - if (last_task_used_vsx == current) - last_task_used_vsx = NULL; -#endif /* CONFIG_VSX */ -#ifdef CONFIG_SPE - if (last_task_used_spe == current) - last_task_used_spe = NULL; -#endif - preempt_enable(); -} -#endif /* CONFIG_SMP */ - #ifdef CONFIG_PPC_ADV_DEBUG_REGS void do_send_trap(struct pt_regs *regs, unsigned long address, unsigned long error_code, int signal_code, int breakpt) @@ -831,30 +774,9 @@ struct task_struct *__switch_to(struct task_struct *prev, __switch_to_tm(prev); -#ifdef CONFIG_SMP - /* avoid complexity of lazy save/restore of fpu - * by just saving it every time we switch out if - * this task used the fpu during the last quantum. - * - * If it tries to use the fpu again, it'll trap and - * reload its fp regs. So we don't have to do a restore - * every switch, just a save. - * -- Cort - */ if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP)) giveup_fpu(prev); #ifdef CONFIG_ALTIVEC - /* - * If the previous thread used altivec in the last quantum - * (thus changing altivec regs) then save them. - * We used to check the VRSAVE register but not all apps - * set it, so we don't rely on it now (and in fact we need - * to save & restore VSCR even if VRSAVE == 0). -- paulus - * - * On SMP we always save/restore altivec regs just to avoid the - * complexity of changing processors. - * -- Cort - */ if (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) giveup_altivec(prev); #endif /* CONFIG_ALTIVEC */ @@ -864,39 +786,10 @@ struct task_struct *__switch_to(struct task_struct *prev, __giveup_vsx(prev); #endif /* CONFIG_VSX */ #ifdef CONFIG_SPE - /* - * If the previous thread used spe in the last quantum - * (thus changing spe regs) then save them. - * - * On SMP we always save/restore spe regs just to avoid the - * complexity of changing processors. - */ if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE))) giveup_spe(prev); #endif /* CONFIG_SPE */ -#else /* CONFIG_SMP */ -#ifdef CONFIG_ALTIVEC - /* Avoid the trap. On smp this this never happens since - * we don't set last_task_used_altivec -- Cort - */ - if (new->thread.regs && last_task_used_altivec == new) - new->thread.regs->msr |= MSR_VEC; -#endif /* CONFIG_ALTIVEC */ -#ifdef CONFIG_VSX - if (new->thread.regs && last_task_used_vsx == new) - new->thread.regs->msr |= MSR_VSX; -#endif /* CONFIG_VSX */ -#ifdef CONFIG_SPE - /* Avoid the trap. On smp this this never happens since - * we don't set last_task_used_spe - */ - if (new->thread.regs && last_task_used_spe == new) - new->thread.regs->msr |= MSR_SPE; -#endif /* CONFIG_SPE */ - -#endif /* CONFIG_SMP */ - #ifdef CONFIG_PPC_ADV_DEBUG_REGS switch_booke_debug_regs(&new->thread.debug); #else @@ -1111,13 +1004,10 @@ void show_regs(struct pt_regs * regs) void exit_thread(void) { - discard_lazy_cpu_state(); } void flush_thread(void) { - discard_lazy_cpu_state(); - #ifdef CONFIG_HAVE_HW_BREAKPOINT flush_ptrace_hw_breakpoint(current); #else /* CONFIG_HAVE_HW_BREAKPOINT */ @@ -1355,7 +1245,6 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) regs->msr = MSR_USER32; } #endif - discard_lazy_cpu_state(); #ifdef CONFIG_VSX current->thread.used_vsr = 0; #endif diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 0dbee465af7a7..3cd7a32c8ff4f 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -687,15 +687,6 @@ static long restore_user_regs(struct pt_regs *regs, if (sig) regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE); - /* - * Do this before updating the thread state in - * current->thread.fpr/vr/evr. That way, if we get preempted - * and another task grabs the FPU/Altivec/SPE, it won't be - * tempted to save the current CPU state into the thread_struct - * and corrupt what we are writing there. - */ - discard_lazy_cpu_state(); - #ifdef CONFIG_ALTIVEC /* * Force the process to reload the altivec registers from @@ -798,15 +789,6 @@ static long restore_tm_user_regs(struct pt_regs *regs, /* Restore the previous little-endian mode */ regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE); - /* - * Do this before updating the thread state in - * current->thread.fpr/vr/evr. That way, if we get preempted - * and another task grabs the FPU/Altivec/SPE, it won't be - * tempted to save the current CPU state into the thread_struct - * and corrupt what we are writing there. - */ - discard_lazy_cpu_state(); - #ifdef CONFIG_ALTIVEC regs->msr &= ~MSR_VEC; if (msr & MSR_VEC) { diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 20756dfb9f346..6f2b555516e6c 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -349,15 +349,6 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, if (set != NULL) err |= __get_user(set->sig[0], &sc->oldmask); - /* - * Do this before updating the thread state in - * current->thread.fpr/vr. That way, if we get preempted - * and another task grabs the FPU/Altivec, it won't be - * tempted to save the current CPU state into the thread_struct - * and corrupt what we are writing there. - */ - discard_lazy_cpu_state(); - /* * Force reload of FP/VEC. * This has to be done before copying stuff into current->thread.fpr/vr @@ -464,15 +455,6 @@ static long restore_tm_sigcontexts(struct pt_regs *regs, err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]); err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]); - /* - * Do this before updating the thread state in - * current->thread.fpr/vr. That way, if we get preempted - * and another task grabs the FPU/Altivec, it won't be - * tempted to save the current CPU state into the thread_struct - * and corrupt what we are writing there. - */ - discard_lazy_cpu_state(); - /* * Force reload of FP/VEC. * This has to be done before copying stuff into current->thread.fpr/vr diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S index 1c5425966204f..1757c0c936c17 100644 --- a/arch/powerpc/kernel/vector.S +++ b/arch/powerpc/kernel/vector.S @@ -80,39 +80,6 @@ _GLOBAL(load_up_altivec) MTMSRD(r5) /* enable use of AltiVec now */ isync -/* - * For SMP, we don't do lazy VMX switching because it just gets too - * horrendously complex, especially when a task switches from one CPU - * to another. Instead we call giveup_altvec in switch_to. - * VRSAVE isn't dealt with here, that is done in the normal context - * switch code. Note that we could rely on vrsave value to eventually - * avoid saving all of the VREGs here... - */ -#ifndef CONFIG_SMP - LOAD_REG_ADDRBASE(r3, last_task_used_altivec) - toreal(r3) - PPC_LL r4,ADDROFF(last_task_used_altivec)(r3) - PPC_LCMPI 0,r4,0 - beq 1f - - /* Save VMX state to last_task_used_altivec's THREAD struct */ - toreal(r4) - addi r4,r4,THREAD - addi r6,r4,THREAD_VRSTATE - SAVE_32VRS(0,r5,r6) - mfvscr v0 - li r10,VRSTATE_VSCR - stvx v0,r10,r6 - /* Disable VMX for last_task_used_altivec */ - PPC_LL r5,PT_REGS(r4) - toreal(r5) - PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) - lis r10,MSR_VEC@h - andc r4,r4,r10 - PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: -#endif /* CONFIG_SMP */ - /* Hack: if we get an altivec unavailable trap with VRSAVE * set to all zeros, we assume this is a broken application * that fails to set it properly, and thus we switch it to @@ -141,12 +108,6 @@ _GLOBAL(load_up_altivec) lvx v0,r10,r6 mtvscr v0 REST_32VRS(0,r4,r6) -#ifndef CONFIG_SMP - /* Update last_task_used_altivec to 'current' */ - subi r4,r5,THREAD /* Back to 'current' */ - fromreal(r4) - PPC_STL r4,ADDROFF(last_task_used_altivec)(r3) -#endif /* CONFIG_SMP */ /* restore registers and return */ blr @@ -199,11 +160,6 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX) andc r4,r4,r3 /* disable FP for previous task */ PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) 1: -#ifndef CONFIG_SMP - li r5,0 - LOAD_REG_ADDRBASE(r4,last_task_used_altivec) - PPC_STL r5,ADDROFF(last_task_used_altivec)(r4) -#endif /* CONFIG_SMP */ blr #ifdef CONFIG_VSX @@ -226,20 +182,6 @@ _GLOBAL(load_up_vsx) andis. r5,r12,MSR_VEC@h beql+ load_up_altivec /* skip if already loaded */ -#ifndef CONFIG_SMP - ld r3,last_task_used_vsx@got(r2) - ld r4,0(r3) - cmpdi 0,r4,0 - beq 1f - /* Disable VSX for last_task_used_vsx */ - addi r4,r4,THREAD - ld r5,PT_REGS(r4) - ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) - lis r6,MSR_VSX@h - andc r6,r4,r6 - std r6,_MSR-STACK_FRAME_OVERHEAD(r5) -1: -#endif /* CONFIG_SMP */ ld r4,PACACURRENT(r13) addi r4,r4,THREAD /* Get THREAD */ li r6,1 @@ -247,11 +189,6 @@ _GLOBAL(load_up_vsx) /* enable use of VSX after return */ oris r12,r12,MSR_VSX@h std r12,_MSR(r1) -#ifndef CONFIG_SMP - /* Update last_task_used_vsx to 'current' */ - ld r4,PACACURRENT(r13) - std r4,0(r3) -#endif /* CONFIG_SMP */ b fast_exception_return /* @@ -277,11 +214,6 @@ _GLOBAL(__giveup_vsx) andc r4,r4,r3 /* disable VSX for previous task */ std r4,_MSR-STACK_FRAME_OVERHEAD(r5) 1: -#ifndef CONFIG_SMP - li r5,0 - ld r4,last_task_used_vsx@got(r2) - std r5,0(r4) -#endif /* CONFIG_SMP */ blr #endif /* CONFIG_VSX */ -- GitLab From b86fd2bd03021ce906bfa0c1456ec38329e31b30 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:43:58 +1100 Subject: [PATCH 0784/2855] powerpc: Simplify TM restore checks Instead of having multiple giveup_*_maybe_transactional() functions, separate out the TM check into a new function called check_if_tm_restore_required(). This will make it easier to optimise the giveup_*() functions in a subsequent patch. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/process.c | 53 +++++++++++++---------------------- 1 file changed, 19 insertions(+), 34 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index e098f43156434..ef64219548d53 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -68,7 +68,7 @@ extern unsigned long _get_SP(void); #ifdef CONFIG_PPC_TRANSACTIONAL_MEM -void giveup_fpu_maybe_transactional(struct task_struct *tsk) +static void check_if_tm_restore_required(struct task_struct *tsk) { /* * If we are saving the current thread's registers, and the @@ -82,31 +82,9 @@ void giveup_fpu_maybe_transactional(struct task_struct *tsk) tsk->thread.ckpt_regs.msr = tsk->thread.regs->msr; set_thread_flag(TIF_RESTORE_TM); } - - giveup_fpu(tsk); -} - -void giveup_altivec_maybe_transactional(struct task_struct *tsk) -{ - /* - * If we are saving the current thread's registers, and the - * thread is in a transactional state, set the TIF_RESTORE_TM - * bit so that we know to restore the registers before - * returning to userspace. - */ - if (tsk == current && tsk->thread.regs && - MSR_TM_ACTIVE(tsk->thread.regs->msr) && - !test_thread_flag(TIF_RESTORE_TM)) { - tsk->thread.ckpt_regs.msr = tsk->thread.regs->msr; - set_thread_flag(TIF_RESTORE_TM); - } - - giveup_altivec(tsk); } - #else -#define giveup_fpu_maybe_transactional(tsk) giveup_fpu(tsk) -#define giveup_altivec_maybe_transactional(tsk) giveup_altivec(tsk) +static inline void check_if_tm_restore_required(struct task_struct *tsk) { } #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ #ifdef CONFIG_PPC_FPU @@ -135,7 +113,8 @@ void flush_fp_to_thread(struct task_struct *tsk) * to still have its FP state in the CPU registers. */ BUG_ON(tsk != current); - giveup_fpu_maybe_transactional(tsk); + check_if_tm_restore_required(tsk); + giveup_fpu(tsk); } preempt_enable(); } @@ -147,10 +126,12 @@ void enable_kernel_fp(void) { WARN_ON(preemptible()); - if (current->thread.regs && (current->thread.regs->msr & MSR_FP)) - giveup_fpu_maybe_transactional(current); - else + if (current->thread.regs && (current->thread.regs->msr & MSR_FP)) { + check_if_tm_restore_required(current); + giveup_fpu(current); + } else { giveup_fpu(NULL); /* just enables FP for kernel */ + } } EXPORT_SYMBOL(enable_kernel_fp); @@ -159,10 +140,12 @@ void enable_kernel_altivec(void) { WARN_ON(preemptible()); - if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) - giveup_altivec_maybe_transactional(current); - else + if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) { + check_if_tm_restore_required(current); + giveup_altivec(current); + } else { giveup_altivec_notask(); + } } EXPORT_SYMBOL(enable_kernel_altivec); @@ -176,7 +159,8 @@ void flush_altivec_to_thread(struct task_struct *tsk) preempt_disable(); if (tsk->thread.regs->msr & MSR_VEC) { BUG_ON(tsk != current); - giveup_altivec_maybe_transactional(tsk); + check_if_tm_restore_required(tsk); + giveup_altivec(tsk); } preempt_enable(); } @@ -198,8 +182,9 @@ EXPORT_SYMBOL(enable_kernel_vsx); void giveup_vsx(struct task_struct *tsk) { - giveup_fpu_maybe_transactional(tsk); - giveup_altivec_maybe_transactional(tsk); + check_if_tm_restore_required(tsk); + giveup_fpu(tsk); + giveup_altivec(tsk); __giveup_vsx(tsk); } EXPORT_SYMBOL(giveup_vsx); -- GitLab From 611b0e5c19963374175b39f42117b03ee7573228 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:43:59 +1100 Subject: [PATCH 0785/2855] powerpc: Create mtmsrd_isync() mtmsrd_isync() will do an mtmsrd followed by an isync on older processors. On newer processors we avoid the isync via a feature fixup. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/reg.h | 8 ++++++++ arch/powerpc/kernel/process.c | 30 ++++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index a908ada8e0a53..987dac090244f 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -1193,12 +1193,20 @@ #define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \ : : "r" (v) : "memory") #define mtmsr(v) __mtmsrd((v), 0) +#define __MTMSR "mtmsrd" #else #define mtmsr(v) asm volatile("mtmsr %0" : \ : "r" ((unsigned long)(v)) \ : "memory") +#define __MTMSR "mtmsr" #endif +static inline void mtmsr_isync(unsigned long val) +{ + asm volatile(__MTMSR " %0; " ASM_FTR_IFCLR("isync", "nop", %1) : : + "r" (val), "i" (CPU_FTR_ARCH_206) : "memory"); +} + #define mfspr(rn) ({unsigned long rval; \ asm volatile("mfspr %0," __stringify(rn) \ : "=r" (rval)); rval;}) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index ef64219548d53..5bf8ec2597d42 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -130,7 +130,10 @@ void enable_kernel_fp(void) check_if_tm_restore_required(current); giveup_fpu(current); } else { - giveup_fpu(NULL); /* just enables FP for kernel */ + u64 oldmsr = mfmsr(); + + if (!(oldmsr & MSR_FP)) + mtmsr_isync(oldmsr | MSR_FP); } } EXPORT_SYMBOL(enable_kernel_fp); @@ -144,7 +147,10 @@ void enable_kernel_altivec(void) check_if_tm_restore_required(current); giveup_altivec(current); } else { - giveup_altivec_notask(); + u64 oldmsr = mfmsr(); + + if (!(oldmsr & MSR_VEC)) + mtmsr_isync(oldmsr | MSR_VEC); } } EXPORT_SYMBOL(enable_kernel_altivec); @@ -173,10 +179,14 @@ void enable_kernel_vsx(void) { WARN_ON(preemptible()); - if (current->thread.regs && (current->thread.regs->msr & MSR_VSX)) + if (current->thread.regs && (current->thread.regs->msr & MSR_VSX)) { giveup_vsx(current); - else - giveup_vsx(NULL); /* just enable vsx for kernel - force */ + } else { + u64 oldmsr = mfmsr(); + + if (!(oldmsr & MSR_VSX)) + mtmsr_isync(oldmsr | MSR_VSX); + } } EXPORT_SYMBOL(enable_kernel_vsx); @@ -209,10 +219,14 @@ void enable_kernel_spe(void) { WARN_ON(preemptible()); - if (current->thread.regs && (current->thread.regs->msr & MSR_SPE)) + if (current->thread.regs && (current->thread.regs->msr & MSR_SPE)) { giveup_spe(current); - else - giveup_spe(NULL); /* just enable SPE for kernel - force */ + } else { + u64 oldmsr = mfmsr(); + + if (!(oldmsr & MSR_SPE)) + mtmsr_isync(oldmsr | MSR_SPE); + } } EXPORT_SYMBOL(enable_kernel_spe); -- GitLab From b51b1153d0e78a70767441273331d2de066bb929 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:44:00 +1100 Subject: [PATCH 0786/2855] powerpc: Remove NULL task struct pointer checks in FP and vector code We used to allow giveup_*() to be called with a NULL task struct pointer. Now those cases are handled in the caller we can remove the checks. We can also remove giveup_altivec_notask() which is also unused. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/switch_to.h | 1 - arch/powerpc/kernel/fpu.S | 2 -- arch/powerpc/kernel/head_fsl_booke.S | 2 -- arch/powerpc/kernel/vector.S | 14 -------------- 4 files changed, 19 deletions(-) diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index bd1d93318350d..042aaf05a7870 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -38,7 +38,6 @@ static inline void giveup_fpu(struct task_struct *t) { } #ifdef CONFIG_ALTIVEC extern void flush_altivec_to_thread(struct task_struct *); extern void giveup_altivec(struct task_struct *); -extern void giveup_altivec_notask(void); #else static inline void flush_altivec_to_thread(struct task_struct *t) { diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 50d2352f2cf45..71bdce284ad93 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S @@ -173,8 +173,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) MTMSRD(r5) /* enable use of fpu now */ SYNC_601 isync - PPC_LCMPI 0,r3,0 - beqlr- /* if no previous owner, done */ addi r3,r3,THREAD /* want THREAD of task */ PPC_LL r6,THREAD_FPSAVEAREA(r3) PPC_LL r5,PT_REGS(r3) diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index ec936abbcadcc..d6980bbae9544 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -992,8 +992,6 @@ _GLOBAL(giveup_spe) oris r5,r5,MSR_SPE@h mtmsr r5 /* enable use of SPE now */ isync - cmpi 0,r3,0 - beqlr- /* if no previous owner, done */ addi r3,r3,THREAD /* want THREAD of task */ lwz r5,PT_REGS(r3) cmpi 0,r5,0 diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S index 1757c0c936c17..b31528c302537 100644 --- a/arch/powerpc/kernel/vector.S +++ b/arch/powerpc/kernel/vector.S @@ -111,16 +111,6 @@ _GLOBAL(load_up_altivec) /* restore registers and return */ blr -_GLOBAL(giveup_altivec_notask) - mfmsr r3 - andis. r4,r3,MSR_VEC@h - bnelr /* Already enabled? */ - oris r3,r3,MSR_VEC@h - SYNC - MTMSRD(r3) /* enable use of VMX now */ - isync - blr - /* * giveup_altivec(tsk) * Disable VMX for the task given as the argument, @@ -133,8 +123,6 @@ _GLOBAL(giveup_altivec) SYNC MTMSRD(r5) /* enable use of VMX now */ isync - PPC_LCMPI 0,r3,0 - beqlr /* if no previous owner, done */ addi r3,r3,THREAD /* want THREAD of task */ PPC_LL r7,THREAD_VRSAVEAREA(r3) PPC_LL r5,PT_REGS(r3) @@ -203,8 +191,6 @@ _GLOBAL(__giveup_vsx) mtmsrd r5 /* enable use of VSX now */ isync - cmpdi 0,r3,0 - beqlr- /* if no previous owner, done */ addi r3,r3,THREAD /* want THREAD of task */ ld r5,PT_REGS(r3) cmpdi 0,r5,0 -- GitLab From 98da581e0846f6d932a4bc46a55458140e20478a Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:44:01 +1100 Subject: [PATCH 0787/2855] powerpc: Move part of giveup_fpu,altivec,spe into c Move the MSR modification into new c functions. Removing it from the low level functions will allow us to avoid costly MSR writes by batching them up. Move the check_if_tm_restore_required() check into these new functions. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/switch_to.h | 21 +++++------ arch/powerpc/kernel/fpu.S | 16 ++------- arch/powerpc/kernel/head_fsl_booke.S | 8 ++--- arch/powerpc/kernel/ppc_ksyms.c | 6 ---- arch/powerpc/kernel/process.c | 52 +++++++++++++++++++++++++--- arch/powerpc/kernel/vector.S | 10 ++---- 6 files changed, 65 insertions(+), 48 deletions(-) diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 042aaf05a7870..c2678b93bcbac 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -23,28 +23,27 @@ extern int emulate_altivec(struct pt_regs *); extern void __giveup_vsx(struct task_struct *); extern void giveup_vsx(struct task_struct *); extern void enable_kernel_spe(void); -extern void giveup_spe(struct task_struct *); extern void load_up_spe(struct task_struct *); extern void switch_booke_debug_regs(struct debug_reg *new_debug); #ifdef CONFIG_PPC_FPU extern void flush_fp_to_thread(struct task_struct *); extern void giveup_fpu(struct task_struct *); +extern void __giveup_fpu(struct task_struct *); #else static inline void flush_fp_to_thread(struct task_struct *t) { } static inline void giveup_fpu(struct task_struct *t) { } +static inline void __giveup_fpu(struct task_struct *t) { } #endif #ifdef CONFIG_ALTIVEC extern void flush_altivec_to_thread(struct task_struct *); extern void giveup_altivec(struct task_struct *); +extern void __giveup_altivec(struct task_struct *); #else -static inline void flush_altivec_to_thread(struct task_struct *t) -{ -} -static inline void giveup_altivec(struct task_struct *t) -{ -} +static inline void flush_altivec_to_thread(struct task_struct *t) { } +static inline void giveup_altivec(struct task_struct *t) { } +static inline void __giveup_altivec(struct task_struct *t) { } #endif #ifdef CONFIG_VSX @@ -57,10 +56,12 @@ static inline void flush_vsx_to_thread(struct task_struct *t) #ifdef CONFIG_SPE extern void flush_spe_to_thread(struct task_struct *); +extern void giveup_spe(struct task_struct *); +extern void __giveup_spe(struct task_struct *); #else -static inline void flush_spe_to_thread(struct task_struct *t) -{ -} +static inline void flush_spe_to_thread(struct task_struct *t) { } +static inline void giveup_spe(struct task_struct *t) { } +static inline void __giveup_spe(struct task_struct *t) { } #endif static inline void clear_task_ebb(struct task_struct *t) diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 71bdce284ad93..431ab571ed1b1 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S @@ -155,24 +155,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) blr /* - * giveup_fpu(tsk) + * __giveup_fpu(tsk) * Disable FP for the task given as the argument, * and save the floating-point registers in its thread_struct. * Enables the FPU for use in the kernel on return. */ -_GLOBAL(giveup_fpu) - mfmsr r5 - ori r5,r5,MSR_FP -#ifdef CONFIG_VSX -BEGIN_FTR_SECTION - oris r5,r5,MSR_VSX@h -END_FTR_SECTION_IFSET(CPU_FTR_VSX) -#endif - SYNC_601 - ISYNC_601 - MTMSRD(r5) /* enable use of fpu now */ - SYNC_601 - isync +_GLOBAL(__giveup_fpu) addi r3,r3,THREAD /* want THREAD of task */ PPC_LL r6,THREAD_FPSAVEAREA(r3) PPC_LL r5,PT_REGS(r3) diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index d6980bbae9544..f705171b924b9 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -984,14 +984,10 @@ _GLOBAL(__setup_ehv_ivors) #ifdef CONFIG_SPE /* - * extern void giveup_spe(struct task_struct *prev) + * extern void __giveup_spe(struct task_struct *prev) * */ -_GLOBAL(giveup_spe) - mfmsr r5 - oris r5,r5,MSR_SPE@h - mtmsr r5 /* enable use of SPE now */ - isync +_GLOBAL(__giveup_spe) addi r3,r3,THREAD /* want THREAD of task */ lwz r5,PT_REGS(r3) cmpi 0,r5,0 diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 202963ee013a8..41e1607e800ca 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -19,13 +19,11 @@ EXPORT_SYMBOL(_mcount); #endif #ifdef CONFIG_PPC_FPU -EXPORT_SYMBOL(giveup_fpu); EXPORT_SYMBOL(load_fp_state); EXPORT_SYMBOL(store_fp_state); #endif #ifdef CONFIG_ALTIVEC -EXPORT_SYMBOL(giveup_altivec); EXPORT_SYMBOL(load_vr_state); EXPORT_SYMBOL(store_vr_state); #endif @@ -34,10 +32,6 @@ EXPORT_SYMBOL(store_vr_state); EXPORT_SYMBOL_GPL(__giveup_vsx); #endif -#ifdef CONFIG_SPE -EXPORT_SYMBOL(giveup_spe); -#endif - #ifdef CONFIG_EPAPR_PARAVIRT EXPORT_SYMBOL(epapr_hypercall_start); #endif diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 5bf8ec2597d42..6bcf82bed6107 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -88,6 +88,25 @@ static inline void check_if_tm_restore_required(struct task_struct *tsk) { } #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ #ifdef CONFIG_PPC_FPU +void giveup_fpu(struct task_struct *tsk) +{ + u64 oldmsr = mfmsr(); + u64 newmsr; + + check_if_tm_restore_required(tsk); + + newmsr = oldmsr | MSR_FP; +#ifdef CONFIG_VSX + if (cpu_has_feature(CPU_FTR_VSX)) + newmsr |= MSR_VSX; +#endif + if (oldmsr != newmsr) + mtmsr_isync(newmsr); + + __giveup_fpu(tsk); +} +EXPORT_SYMBOL(giveup_fpu); + /* * Make sure the floating-point register state in the * the thread_struct is up to date for task tsk. @@ -113,7 +132,6 @@ void flush_fp_to_thread(struct task_struct *tsk) * to still have its FP state in the CPU registers. */ BUG_ON(tsk != current); - check_if_tm_restore_required(tsk); giveup_fpu(tsk); } preempt_enable(); @@ -127,7 +145,6 @@ void enable_kernel_fp(void) WARN_ON(preemptible()); if (current->thread.regs && (current->thread.regs->msr & MSR_FP)) { - check_if_tm_restore_required(current); giveup_fpu(current); } else { u64 oldmsr = mfmsr(); @@ -139,12 +156,26 @@ void enable_kernel_fp(void) EXPORT_SYMBOL(enable_kernel_fp); #ifdef CONFIG_ALTIVEC +void giveup_altivec(struct task_struct *tsk) +{ + u64 oldmsr = mfmsr(); + u64 newmsr; + + check_if_tm_restore_required(tsk); + + newmsr = oldmsr | MSR_VEC; + if (oldmsr != newmsr) + mtmsr_isync(newmsr); + + __giveup_altivec(tsk); +} +EXPORT_SYMBOL(giveup_altivec); + void enable_kernel_altivec(void) { WARN_ON(preemptible()); if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) { - check_if_tm_restore_required(current); giveup_altivec(current); } else { u64 oldmsr = mfmsr(); @@ -165,7 +196,6 @@ void flush_altivec_to_thread(struct task_struct *tsk) preempt_disable(); if (tsk->thread.regs->msr & MSR_VEC) { BUG_ON(tsk != current); - check_if_tm_restore_required(tsk); giveup_altivec(tsk); } preempt_enable(); @@ -214,6 +244,20 @@ EXPORT_SYMBOL_GPL(flush_vsx_to_thread); #endif /* CONFIG_VSX */ #ifdef CONFIG_SPE +void giveup_spe(struct task_struct *tsk) +{ + u64 oldmsr = mfmsr(); + u64 newmsr; + + check_if_tm_restore_required(tsk); + + newmsr = oldmsr | MSR_SPE; + if (oldmsr != newmsr) + mtmsr_isync(newmsr); + + __giveup_spe(tsk); +} +EXPORT_SYMBOL(giveup_spe); void enable_kernel_spe(void) { diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S index b31528c302537..6e925b40a484e 100644 --- a/arch/powerpc/kernel/vector.S +++ b/arch/powerpc/kernel/vector.S @@ -112,17 +112,11 @@ _GLOBAL(load_up_altivec) blr /* - * giveup_altivec(tsk) + * __giveup_altivec(tsk) * Disable VMX for the task given as the argument, * and save the vector registers in its thread_struct. - * Enables the VMX for use in the kernel on return. */ -_GLOBAL(giveup_altivec) - mfmsr r5 - oris r5,r5,MSR_VEC@h - SYNC - MTMSRD(r5) /* enable use of VMX now */ - isync +_GLOBAL(__giveup_altivec) addi r3,r3,THREAD /* want THREAD of task */ PPC_LL r7,THREAD_VRSAVEAREA(r3) PPC_LL r5,PT_REGS(r3) -- GitLab From a7d623d4d053ccb0cdfad210bced2ec25ddf69a2 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:44:02 +1100 Subject: [PATCH 0788/2855] powerpc: Move part of giveup_vsx into c Move the MSR modification into c. Removing it from the assembly function will allow us to avoid costly MSR writes by batching them up. Check the FP and VMX bits before calling the relevant giveup_*() function. This makes giveup_vsx() and flush_vsx_to_thread() perform more like their sister functions, and allows us to use flush_vsx_to_thread() in the signal code. Move the check_if_tm_restore_required() check in. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/process.c | 28 +++++++++++++++++++--------- arch/powerpc/kernel/signal_32.c | 4 ++-- arch/powerpc/kernel/signal_64.c | 4 ++-- arch/powerpc/kernel/vector.S | 6 ------ 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 6bcf82bed6107..0cb627662ded1 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -205,6 +205,25 @@ EXPORT_SYMBOL_GPL(flush_altivec_to_thread); #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_VSX +void giveup_vsx(struct task_struct *tsk) +{ + u64 oldmsr = mfmsr(); + u64 newmsr; + + check_if_tm_restore_required(tsk); + + newmsr = oldmsr | (MSR_FP|MSR_VEC|MSR_VSX); + if (oldmsr != newmsr) + mtmsr_isync(newmsr); + + if (tsk->thread.regs->msr & MSR_FP) + __giveup_fpu(tsk); + if (tsk->thread.regs->msr & MSR_VEC) + __giveup_altivec(tsk); + __giveup_vsx(tsk); +} +EXPORT_SYMBOL(giveup_vsx); + void enable_kernel_vsx(void) { WARN_ON(preemptible()); @@ -220,15 +239,6 @@ void enable_kernel_vsx(void) } EXPORT_SYMBOL(enable_kernel_vsx); -void giveup_vsx(struct task_struct *tsk) -{ - check_if_tm_restore_required(tsk); - giveup_fpu(tsk); - giveup_altivec(tsk); - __giveup_vsx(tsk); -} -EXPORT_SYMBOL(giveup_vsx); - void flush_vsx_to_thread(struct task_struct *tsk) { if (tsk->thread.regs) { diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 3cd7a32c8ff4f..4022cbb7e2d6c 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -458,7 +458,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, * contains valid data */ if (current->thread.used_vsr && ctx_has_vsx_region) { - __giveup_vsx(current); + flush_vsx_to_thread(current); if (copy_vsx_to_user(&frame->mc_vsregs, current)) return 1; msr |= MSR_VSX; @@ -606,7 +606,7 @@ static int save_tm_user_regs(struct pt_regs *regs, * contains valid data */ if (current->thread.used_vsr) { - __giveup_vsx(current); + flush_vsx_to_thread(current); if (copy_vsx_to_user(&frame->mc_vsregs, current)) return 1; if (msr & MSR_VSX) { diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 6f2b555516e6c..3b23399129116 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -147,7 +147,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, * VMX data. */ if (current->thread.used_vsr && ctx_has_vsx_region) { - __giveup_vsx(current); + flush_vsx_to_thread(current); v_regs += ELF_NVRREG; err |= copy_vsx_to_user(v_regs, current); /* set MSR_VSX in the MSR value in the frame to @@ -270,7 +270,7 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc, * VMX data. */ if (current->thread.used_vsr) { - __giveup_vsx(current); + flush_vsx_to_thread(current); v_regs += ELF_NVRREG; tm_v_regs += ELF_NVRREG; diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S index 6e925b40a484e..98675b08efe2b 100644 --- a/arch/powerpc/kernel/vector.S +++ b/arch/powerpc/kernel/vector.S @@ -177,14 +177,8 @@ _GLOBAL(load_up_vsx) * __giveup_vsx(tsk) * Disable VSX for the task given as the argument. * Does NOT save vsx registers. - * Enables the VSX for use in the kernel on return. */ _GLOBAL(__giveup_vsx) - mfmsr r5 - oris r5,r5,MSR_VSX@h - mtmsrd r5 /* enable use of VSX now */ - isync - addi r3,r3,THREAD /* want THREAD of task */ ld r5,PT_REGS(r3) cmpdi 0,r5,0 -- GitLab From 1552cd703cf5a07caeb17ccd82f80e20a23b1707 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:44:03 +1100 Subject: [PATCH 0789/2855] crypto: vmx: Only call enable_kernel_vsx() With the recent change to enable_kernel_vsx(), we no longer need to call enable_kernel_fp() and enable_kernel_altivec(). Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- drivers/crypto/vmx/aes.c | 3 --- drivers/crypto/vmx/aes_cbc.c | 3 --- drivers/crypto/vmx/aes_ctr.c | 3 --- drivers/crypto/vmx/ghash.c | 8 -------- 4 files changed, 17 deletions(-) diff --git a/drivers/crypto/vmx/aes.c b/drivers/crypto/vmx/aes.c index 263af709e5360..20539fb7e975d 100644 --- a/drivers/crypto/vmx/aes.c +++ b/drivers/crypto/vmx/aes.c @@ -83,7 +83,6 @@ static int p8_aes_setkey(struct crypto_tfm *tfm, const u8 *key, preempt_disable(); pagefault_disable(); - enable_kernel_altivec(); enable_kernel_vsx(); ret = aes_p8_set_encrypt_key(key, keylen * 8, &ctx->enc_key); ret += aes_p8_set_decrypt_key(key, keylen * 8, &ctx->dec_key); @@ -103,7 +102,6 @@ static void p8_aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) } else { preempt_disable(); pagefault_disable(); - enable_kernel_altivec(); enable_kernel_vsx(); aes_p8_encrypt(src, dst, &ctx->enc_key); pagefault_enable(); @@ -120,7 +118,6 @@ static void p8_aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) } else { preempt_disable(); pagefault_disable(); - enable_kernel_altivec(); enable_kernel_vsx(); aes_p8_decrypt(src, dst, &ctx->dec_key); pagefault_enable(); diff --git a/drivers/crypto/vmx/aes_cbc.c b/drivers/crypto/vmx/aes_cbc.c index 0b8fe2ec5315f..8847b92e9ff07 100644 --- a/drivers/crypto/vmx/aes_cbc.c +++ b/drivers/crypto/vmx/aes_cbc.c @@ -84,7 +84,6 @@ static int p8_aes_cbc_setkey(struct crypto_tfm *tfm, const u8 *key, preempt_disable(); pagefault_disable(); - enable_kernel_altivec(); enable_kernel_vsx(); ret = aes_p8_set_encrypt_key(key, keylen * 8, &ctx->enc_key); ret += aes_p8_set_decrypt_key(key, keylen * 8, &ctx->dec_key); @@ -115,7 +114,6 @@ static int p8_aes_cbc_encrypt(struct blkcipher_desc *desc, } else { preempt_disable(); pagefault_disable(); - enable_kernel_altivec(); enable_kernel_vsx(); blkcipher_walk_init(&walk, dst, src, nbytes); @@ -156,7 +154,6 @@ static int p8_aes_cbc_decrypt(struct blkcipher_desc *desc, } else { preempt_disable(); pagefault_disable(); - enable_kernel_altivec(); enable_kernel_vsx(); blkcipher_walk_init(&walk, dst, src, nbytes); diff --git a/drivers/crypto/vmx/aes_ctr.c b/drivers/crypto/vmx/aes_ctr.c index ee1306cd8f59b..80958660c31ad 100644 --- a/drivers/crypto/vmx/aes_ctr.c +++ b/drivers/crypto/vmx/aes_ctr.c @@ -81,7 +81,6 @@ static int p8_aes_ctr_setkey(struct crypto_tfm *tfm, const u8 *key, struct p8_aes_ctr_ctx *ctx = crypto_tfm_ctx(tfm); pagefault_disable(); - enable_kernel_altivec(); enable_kernel_vsx(); ret = aes_p8_set_encrypt_key(key, keylen * 8, &ctx->enc_key); pagefault_enable(); @@ -100,7 +99,6 @@ static void p8_aes_ctr_final(struct p8_aes_ctr_ctx *ctx, unsigned int nbytes = walk->nbytes; pagefault_disable(); - enable_kernel_altivec(); enable_kernel_vsx(); aes_p8_encrypt(ctrblk, keystream, &ctx->enc_key); pagefault_enable(); @@ -133,7 +131,6 @@ static int p8_aes_ctr_crypt(struct blkcipher_desc *desc, ret = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE); while ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE) { pagefault_disable(); - enable_kernel_altivec(); enable_kernel_vsx(); aes_p8_ctr32_encrypt_blocks(walk.src.virt.addr, walk.dst.virt.addr, diff --git a/drivers/crypto/vmx/ghash.c b/drivers/crypto/vmx/ghash.c index 2183a2e77641e..1f4586c2fd255 100644 --- a/drivers/crypto/vmx/ghash.c +++ b/drivers/crypto/vmx/ghash.c @@ -118,9 +118,7 @@ static int p8_ghash_setkey(struct crypto_shash *tfm, const u8 *key, preempt_disable(); pagefault_disable(); - enable_kernel_altivec(); enable_kernel_vsx(); - enable_kernel_fp(); gcm_init_p8(ctx->htable, (const u64 *) key); pagefault_enable(); preempt_enable(); @@ -149,9 +147,7 @@ static int p8_ghash_update(struct shash_desc *desc, GHASH_DIGEST_SIZE - dctx->bytes); preempt_disable(); pagefault_disable(); - enable_kernel_altivec(); enable_kernel_vsx(); - enable_kernel_fp(); gcm_ghash_p8(dctx->shash, ctx->htable, dctx->buffer, GHASH_DIGEST_SIZE); pagefault_enable(); @@ -164,9 +160,7 @@ static int p8_ghash_update(struct shash_desc *desc, if (len) { preempt_disable(); pagefault_disable(); - enable_kernel_altivec(); enable_kernel_vsx(); - enable_kernel_fp(); gcm_ghash_p8(dctx->shash, ctx->htable, src, len); pagefault_enable(); preempt_enable(); @@ -195,9 +189,7 @@ static int p8_ghash_final(struct shash_desc *desc, u8 *out) dctx->buffer[i] = 0; preempt_disable(); pagefault_disable(); - enable_kernel_altivec(); enable_kernel_vsx(); - enable_kernel_fp(); gcm_ghash_p8(dctx->shash, ctx->htable, dctx->buffer, GHASH_DIGEST_SIZE); pagefault_enable(); -- GitLab From a0e72cf12b1a1f159b6822ed2e1e41893d996fc7 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:44:04 +1100 Subject: [PATCH 0790/2855] powerpc: Create msr_check_and_{set,clear}() Create helper functions to set and clear MSR bits after first checking if they are already set. Grouping them will make it easy to avoid the MSR writes in a subsequent optimisation. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/process.c | 107 +++++++++++++++++----------------- 1 file changed, 52 insertions(+), 55 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 0cb627662ded1..5cdd35c0b0264 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -87,23 +87,46 @@ static void check_if_tm_restore_required(struct task_struct *tsk) static inline void check_if_tm_restore_required(struct task_struct *tsk) { } #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ -#ifdef CONFIG_PPC_FPU -void giveup_fpu(struct task_struct *tsk) +static void msr_check_and_set(unsigned long bits) { - u64 oldmsr = mfmsr(); - u64 newmsr; + unsigned long oldmsr = mfmsr(); + unsigned long newmsr; - check_if_tm_restore_required(tsk); + newmsr = oldmsr | bits; - newmsr = oldmsr | MSR_FP; #ifdef CONFIG_VSX - if (cpu_has_feature(CPU_FTR_VSX)) + if (cpu_has_feature(CPU_FTR_VSX) && (bits & MSR_FP)) newmsr |= MSR_VSX; #endif + if (oldmsr != newmsr) mtmsr_isync(newmsr); +} + +static void msr_check_and_clear(unsigned long bits) +{ + unsigned long oldmsr = mfmsr(); + unsigned long newmsr; + + newmsr = oldmsr & ~bits; + +#ifdef CONFIG_VSX + if (cpu_has_feature(CPU_FTR_VSX) && (bits & MSR_FP)) + newmsr &= ~MSR_VSX; +#endif + if (oldmsr != newmsr) + mtmsr_isync(newmsr); +} + +#ifdef CONFIG_PPC_FPU +void giveup_fpu(struct task_struct *tsk) +{ + check_if_tm_restore_required(tsk); + + msr_check_and_set(MSR_FP); __giveup_fpu(tsk); + msr_check_and_clear(MSR_FP); } EXPORT_SYMBOL(giveup_fpu); @@ -144,30 +167,21 @@ void enable_kernel_fp(void) { WARN_ON(preemptible()); - if (current->thread.regs && (current->thread.regs->msr & MSR_FP)) { - giveup_fpu(current); - } else { - u64 oldmsr = mfmsr(); + msr_check_and_set(MSR_FP); - if (!(oldmsr & MSR_FP)) - mtmsr_isync(oldmsr | MSR_FP); - } + if (current->thread.regs && (current->thread.regs->msr & MSR_FP)) + __giveup_fpu(current); } EXPORT_SYMBOL(enable_kernel_fp); #ifdef CONFIG_ALTIVEC void giveup_altivec(struct task_struct *tsk) { - u64 oldmsr = mfmsr(); - u64 newmsr; - check_if_tm_restore_required(tsk); - newmsr = oldmsr | MSR_VEC; - if (oldmsr != newmsr) - mtmsr_isync(newmsr); - + msr_check_and_set(MSR_VEC); __giveup_altivec(tsk); + msr_check_and_clear(MSR_VEC); } EXPORT_SYMBOL(giveup_altivec); @@ -175,14 +189,10 @@ void enable_kernel_altivec(void) { WARN_ON(preemptible()); - if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) { - giveup_altivec(current); - } else { - u64 oldmsr = mfmsr(); + msr_check_and_set(MSR_VEC); - if (!(oldmsr & MSR_VEC)) - mtmsr_isync(oldmsr | MSR_VEC); - } + if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) + __giveup_altivec(current); } EXPORT_SYMBOL(enable_kernel_altivec); @@ -207,20 +217,15 @@ EXPORT_SYMBOL_GPL(flush_altivec_to_thread); #ifdef CONFIG_VSX void giveup_vsx(struct task_struct *tsk) { - u64 oldmsr = mfmsr(); - u64 newmsr; - check_if_tm_restore_required(tsk); - newmsr = oldmsr | (MSR_FP|MSR_VEC|MSR_VSX); - if (oldmsr != newmsr) - mtmsr_isync(newmsr); - + msr_check_and_set(MSR_FP|MSR_VEC|MSR_VSX); if (tsk->thread.regs->msr & MSR_FP) __giveup_fpu(tsk); if (tsk->thread.regs->msr & MSR_VEC) __giveup_altivec(tsk); __giveup_vsx(tsk); + msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX); } EXPORT_SYMBOL(giveup_vsx); @@ -228,13 +233,14 @@ void enable_kernel_vsx(void) { WARN_ON(preemptible()); - if (current->thread.regs && (current->thread.regs->msr & MSR_VSX)) { - giveup_vsx(current); - } else { - u64 oldmsr = mfmsr(); + msr_check_and_set(MSR_FP|MSR_VEC|MSR_VSX); - if (!(oldmsr & MSR_VSX)) - mtmsr_isync(oldmsr | MSR_VSX); + if (current->thread.regs && (current->thread.regs->msr & MSR_VSX)) { + if (current->thread.regs->msr & MSR_FP) + __giveup_fpu(current); + if (current->thread.regs->msr & MSR_VEC) + __giveup_altivec(current); + __giveup_vsx(current); } } EXPORT_SYMBOL(enable_kernel_vsx); @@ -256,16 +262,11 @@ EXPORT_SYMBOL_GPL(flush_vsx_to_thread); #ifdef CONFIG_SPE void giveup_spe(struct task_struct *tsk) { - u64 oldmsr = mfmsr(); - u64 newmsr; - check_if_tm_restore_required(tsk); - newmsr = oldmsr | MSR_SPE; - if (oldmsr != newmsr) - mtmsr_isync(newmsr); - + msr_check_and_set(MSR_SPE); __giveup_spe(tsk); + msr_check_and_clear(MSR_SPE); } EXPORT_SYMBOL(giveup_spe); @@ -273,14 +274,10 @@ void enable_kernel_spe(void) { WARN_ON(preemptible()); - if (current->thread.regs && (current->thread.regs->msr & MSR_SPE)) { - giveup_spe(current); - } else { - u64 oldmsr = mfmsr(); + msr_check_and_set(MSR_SPE); - if (!(oldmsr & MSR_SPE)) - mtmsr_isync(oldmsr | MSR_SPE); - } + if (current->thread.regs && (current->thread.regs->msr & MSR_SPE)) + __giveup_spe(current); } EXPORT_SYMBOL(enable_kernel_spe); -- GitLab From dc4fbba11e4661a6a77a1f89ba32f9082e6395ff Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:44:05 +1100 Subject: [PATCH 0791/2855] powerpc: Create disable_kernel_{fp,altivec,vsx,spe}() The enable_kernel_*() functions leave the relevant MSR bits enabled until we exit the kernel sometime later. Create disable versions that wrap the kernel use of FP, Altivec VSX or SPE. While we don't want to disable it normally for performance reasons (MSR writes are slow), it will be used for a debug boot option that does this and catches bad uses in other areas of the kernel. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/crypto/aes-spe-glue.c | 1 + arch/powerpc/crypto/sha1-spe-glue.c | 1 + arch/powerpc/crypto/sha256-spe-glue.c | 1 + arch/powerpc/include/asm/switch_to.h | 5 +++++ arch/powerpc/kernel/align.c | 2 ++ arch/powerpc/kvm/book3s_paired_singles.c | 1 + arch/powerpc/kvm/book3s_pr.c | 4 ++++ arch/powerpc/kvm/booke.c | 4 ++++ arch/powerpc/lib/vmx-helper.c | 2 ++ arch/powerpc/lib/xor_vmx.c | 4 ++++ drivers/crypto/vmx/aes.c | 3 +++ drivers/crypto/vmx/aes_cbc.c | 3 +++ drivers/crypto/vmx/aes_ctr.c | 3 +++ drivers/crypto/vmx/ghash.c | 4 ++++ lib/raid6/altivec.uc | 1 + 15 files changed, 39 insertions(+) diff --git a/arch/powerpc/crypto/aes-spe-glue.c b/arch/powerpc/crypto/aes-spe-glue.c index bd5e63f72ad40..93ee046d12cde 100644 --- a/arch/powerpc/crypto/aes-spe-glue.c +++ b/arch/powerpc/crypto/aes-spe-glue.c @@ -85,6 +85,7 @@ static void spe_begin(void) static void spe_end(void) { + disable_kernel_spe(); /* reenable preemption */ preempt_enable(); } diff --git a/arch/powerpc/crypto/sha1-spe-glue.c b/arch/powerpc/crypto/sha1-spe-glue.c index 3e1d222125218..f9ebc38d3fe79 100644 --- a/arch/powerpc/crypto/sha1-spe-glue.c +++ b/arch/powerpc/crypto/sha1-spe-glue.c @@ -46,6 +46,7 @@ static void spe_begin(void) static void spe_end(void) { + disable_kernel_spe(); /* reenable preemption */ preempt_enable(); } diff --git a/arch/powerpc/crypto/sha256-spe-glue.c b/arch/powerpc/crypto/sha256-spe-glue.c index f4a616fe1a822..718a079dcdbfb 100644 --- a/arch/powerpc/crypto/sha256-spe-glue.c +++ b/arch/powerpc/crypto/sha256-spe-glue.c @@ -47,6 +47,7 @@ static void spe_begin(void) static void spe_end(void) { + disable_kernel_spe(); /* reenable preemption */ preempt_enable(); } diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index c2678b93bcbac..438502f59550f 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -26,6 +26,11 @@ extern void enable_kernel_spe(void); extern void load_up_spe(struct task_struct *); extern void switch_booke_debug_regs(struct debug_reg *new_debug); +static inline void disable_kernel_fp(void) { } +static inline void disable_kernel_altivec(void) { } +static inline void disable_kernel_spe(void) { } +static inline void disable_kernel_vsx(void) { } + #ifdef CONFIG_PPC_FPU extern void flush_fp_to_thread(struct task_struct *); extern void giveup_fpu(struct task_struct *); diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index 86150fbb42c39..8e7cb8e2b21ac 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -960,6 +960,7 @@ int fix_alignment(struct pt_regs *regs) preempt_disable(); enable_kernel_fp(); cvt_df(&data.dd, (float *)&data.x32.low32); + disable_kernel_fp(); preempt_enable(); #else return 0; @@ -1000,6 +1001,7 @@ int fix_alignment(struct pt_regs *regs) preempt_disable(); enable_kernel_fp(); cvt_fd((float *)&data.x32.low32, &data.dd); + disable_kernel_fp(); preempt_enable(); #else return 0; diff --git a/arch/powerpc/kvm/book3s_paired_singles.c b/arch/powerpc/kvm/book3s_paired_singles.c index a759d9adb0b6f..eab96cfe82fa0 100644 --- a/arch/powerpc/kvm/book3s_paired_singles.c +++ b/arch/powerpc/kvm/book3s_paired_singles.c @@ -1265,6 +1265,7 @@ int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu) if (rcomp) kvmppc_set_cr(vcpu, cr); + disable_kernel_fp(); preempt_enable(); return emulated; diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 64891b081ad54..49f5dad1bd458 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c @@ -751,6 +751,7 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, preempt_disable(); enable_kernel_fp(); load_fp_state(&vcpu->arch.fp); + disable_kernel_fp(); t->fp_save_area = &vcpu->arch.fp; preempt_enable(); } @@ -760,6 +761,7 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, preempt_disable(); enable_kernel_altivec(); load_vr_state(&vcpu->arch.vr); + disable_kernel_altivec(); t->vr_save_area = &vcpu->arch.vr; preempt_enable(); #endif @@ -788,6 +790,7 @@ static void kvmppc_handle_lost_ext(struct kvm_vcpu *vcpu) preempt_disable(); enable_kernel_fp(); load_fp_state(&vcpu->arch.fp); + disable_kernel_fp(); preempt_enable(); } #ifdef CONFIG_ALTIVEC @@ -795,6 +798,7 @@ static void kvmppc_handle_lost_ext(struct kvm_vcpu *vcpu) preempt_disable(); enable_kernel_altivec(); load_vr_state(&vcpu->arch.vr); + disable_kernel_altivec(); preempt_enable(); } #endif diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index fd5875179e5c0..778ef86e187ec 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -98,6 +98,7 @@ void kvmppc_vcpu_disable_spe(struct kvm_vcpu *vcpu) preempt_disable(); enable_kernel_spe(); kvmppc_save_guest_spe(vcpu); + disable_kernel_spe(); vcpu->arch.shadow_msr &= ~MSR_SPE; preempt_enable(); } @@ -107,6 +108,7 @@ static void kvmppc_vcpu_enable_spe(struct kvm_vcpu *vcpu) preempt_disable(); enable_kernel_spe(); kvmppc_load_guest_spe(vcpu); + disable_kernel_spe(); vcpu->arch.shadow_msr |= MSR_SPE; preempt_enable(); } @@ -141,6 +143,7 @@ static inline void kvmppc_load_guest_fp(struct kvm_vcpu *vcpu) if (!(current->thread.regs->msr & MSR_FP)) { enable_kernel_fp(); load_fp_state(&vcpu->arch.fp); + disable_kernel_fp(); current->thread.fp_save_area = &vcpu->arch.fp; current->thread.regs->msr |= MSR_FP; } @@ -182,6 +185,7 @@ static inline void kvmppc_load_guest_altivec(struct kvm_vcpu *vcpu) if (!(current->thread.regs->msr & MSR_VEC)) { enable_kernel_altivec(); load_vr_state(&vcpu->arch.vr); + disable_kernel_altivec(); current->thread.vr_save_area = &vcpu->arch.vr; current->thread.regs->msr |= MSR_VEC; } diff --git a/arch/powerpc/lib/vmx-helper.c b/arch/powerpc/lib/vmx-helper.c index ac93a3bd27300..b27e030fc9f86 100644 --- a/arch/powerpc/lib/vmx-helper.c +++ b/arch/powerpc/lib/vmx-helper.c @@ -46,6 +46,7 @@ int enter_vmx_usercopy(void) */ int exit_vmx_usercopy(void) { + disable_kernel_altivec(); pagefault_enable(); preempt_enable(); return 0; @@ -70,6 +71,7 @@ int enter_vmx_copy(void) */ void *exit_vmx_copy(void *dest) { + disable_kernel_altivec(); preempt_enable(); return dest; } diff --git a/arch/powerpc/lib/xor_vmx.c b/arch/powerpc/lib/xor_vmx.c index e905f7c2ea7bf..07f49f1568e5e 100644 --- a/arch/powerpc/lib/xor_vmx.c +++ b/arch/powerpc/lib/xor_vmx.c @@ -74,6 +74,7 @@ void xor_altivec_2(unsigned long bytes, unsigned long *v1_in, v2 += 4; } while (--lines > 0); + disable_kernel_altivec(); preempt_enable(); } EXPORT_SYMBOL(xor_altivec_2); @@ -102,6 +103,7 @@ void xor_altivec_3(unsigned long bytes, unsigned long *v1_in, v3 += 4; } while (--lines > 0); + disable_kernel_altivec(); preempt_enable(); } EXPORT_SYMBOL(xor_altivec_3); @@ -135,6 +137,7 @@ void xor_altivec_4(unsigned long bytes, unsigned long *v1_in, v4 += 4; } while (--lines > 0); + disable_kernel_altivec(); preempt_enable(); } EXPORT_SYMBOL(xor_altivec_4); @@ -172,6 +175,7 @@ void xor_altivec_5(unsigned long bytes, unsigned long *v1_in, v5 += 4; } while (--lines > 0); + disable_kernel_altivec(); preempt_enable(); } EXPORT_SYMBOL(xor_altivec_5); diff --git a/drivers/crypto/vmx/aes.c b/drivers/crypto/vmx/aes.c index 20539fb7e975d..022c7ab7351a0 100644 --- a/drivers/crypto/vmx/aes.c +++ b/drivers/crypto/vmx/aes.c @@ -86,6 +86,7 @@ static int p8_aes_setkey(struct crypto_tfm *tfm, const u8 *key, enable_kernel_vsx(); ret = aes_p8_set_encrypt_key(key, keylen * 8, &ctx->enc_key); ret += aes_p8_set_decrypt_key(key, keylen * 8, &ctx->dec_key); + disable_kernel_vsx(); pagefault_enable(); preempt_enable(); @@ -104,6 +105,7 @@ static void p8_aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) pagefault_disable(); enable_kernel_vsx(); aes_p8_encrypt(src, dst, &ctx->enc_key); + disable_kernel_vsx(); pagefault_enable(); preempt_enable(); } @@ -120,6 +122,7 @@ static void p8_aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) pagefault_disable(); enable_kernel_vsx(); aes_p8_decrypt(src, dst, &ctx->dec_key); + disable_kernel_vsx(); pagefault_enable(); preempt_enable(); } diff --git a/drivers/crypto/vmx/aes_cbc.c b/drivers/crypto/vmx/aes_cbc.c index 8847b92e9ff07..1881b3f413fac 100644 --- a/drivers/crypto/vmx/aes_cbc.c +++ b/drivers/crypto/vmx/aes_cbc.c @@ -87,6 +87,7 @@ static int p8_aes_cbc_setkey(struct crypto_tfm *tfm, const u8 *key, enable_kernel_vsx(); ret = aes_p8_set_encrypt_key(key, keylen * 8, &ctx->enc_key); ret += aes_p8_set_decrypt_key(key, keylen * 8, &ctx->dec_key); + disable_kernel_vsx(); pagefault_enable(); preempt_enable(); @@ -127,6 +128,7 @@ static int p8_aes_cbc_encrypt(struct blkcipher_desc *desc, ret = blkcipher_walk_done(desc, &walk, nbytes); } + disable_kernel_vsx(); pagefault_enable(); preempt_enable(); } @@ -167,6 +169,7 @@ static int p8_aes_cbc_decrypt(struct blkcipher_desc *desc, ret = blkcipher_walk_done(desc, &walk, nbytes); } + disable_kernel_vsx(); pagefault_enable(); preempt_enable(); } diff --git a/drivers/crypto/vmx/aes_ctr.c b/drivers/crypto/vmx/aes_ctr.c index 80958660c31ad..2d58b18acc10a 100644 --- a/drivers/crypto/vmx/aes_ctr.c +++ b/drivers/crypto/vmx/aes_ctr.c @@ -83,6 +83,7 @@ static int p8_aes_ctr_setkey(struct crypto_tfm *tfm, const u8 *key, pagefault_disable(); enable_kernel_vsx(); ret = aes_p8_set_encrypt_key(key, keylen * 8, &ctx->enc_key); + disable_kernel_vsx(); pagefault_enable(); ret += crypto_blkcipher_setkey(ctx->fallback, key, keylen); @@ -101,6 +102,7 @@ static void p8_aes_ctr_final(struct p8_aes_ctr_ctx *ctx, pagefault_disable(); enable_kernel_vsx(); aes_p8_encrypt(ctrblk, keystream, &ctx->enc_key); + disable_kernel_vsx(); pagefault_enable(); crypto_xor(keystream, src, nbytes); @@ -139,6 +141,7 @@ static int p8_aes_ctr_crypt(struct blkcipher_desc *desc, AES_BLOCK_SIZE, &ctx->enc_key, walk.iv); + disable_kernel_vsx(); pagefault_enable(); /* We need to update IV mostly for last bytes/round */ diff --git a/drivers/crypto/vmx/ghash.c b/drivers/crypto/vmx/ghash.c index 1f4586c2fd255..6c999cb01b804 100644 --- a/drivers/crypto/vmx/ghash.c +++ b/drivers/crypto/vmx/ghash.c @@ -120,6 +120,7 @@ static int p8_ghash_setkey(struct crypto_shash *tfm, const u8 *key, pagefault_disable(); enable_kernel_vsx(); gcm_init_p8(ctx->htable, (const u64 *) key); + disable_kernel_vsx(); pagefault_enable(); preempt_enable(); return crypto_shash_setkey(ctx->fallback, key, keylen); @@ -150,6 +151,7 @@ static int p8_ghash_update(struct shash_desc *desc, enable_kernel_vsx(); gcm_ghash_p8(dctx->shash, ctx->htable, dctx->buffer, GHASH_DIGEST_SIZE); + disable_kernel_vsx(); pagefault_enable(); preempt_enable(); src += GHASH_DIGEST_SIZE - dctx->bytes; @@ -162,6 +164,7 @@ static int p8_ghash_update(struct shash_desc *desc, pagefault_disable(); enable_kernel_vsx(); gcm_ghash_p8(dctx->shash, ctx->htable, src, len); + disable_kernel_vsx(); pagefault_enable(); preempt_enable(); src += len; @@ -192,6 +195,7 @@ static int p8_ghash_final(struct shash_desc *desc, u8 *out) enable_kernel_vsx(); gcm_ghash_p8(dctx->shash, ctx->htable, dctx->buffer, GHASH_DIGEST_SIZE); + disable_kernel_vsx(); pagefault_enable(); preempt_enable(); dctx->bytes = 0; diff --git a/lib/raid6/altivec.uc b/lib/raid6/altivec.uc index bec27fce75017..682aae8a1fef2 100644 --- a/lib/raid6/altivec.uc +++ b/lib/raid6/altivec.uc @@ -101,6 +101,7 @@ static void raid6_altivec$#_gen_syndrome(int disks, size_t bytes, void **ptrs) raid6_altivec$#_gen_syndrome_real(disks, bytes, ptrs); + disable_kernel_altivec(); preempt_enable(); } -- GitLab From 3eb5d5888dc68c9b187998ca4249b8b9fa481eeb Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:44:06 +1100 Subject: [PATCH 0792/2855] powerpc: Add ppc_strict_facility_enable boot option Add a boot option that strictly manages the MSR unavailable bits. This catches kernel uses of FP/Altivec/SPE that would otherwise corrupt user state. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- Documentation/kernel-parameters.txt | 6 ++++++ arch/powerpc/include/asm/reg.h | 9 +++++++++ arch/powerpc/include/asm/switch_to.h | 24 +++++++++++++++++++----- arch/powerpc/kernel/process.c | 17 +++++++++++++++-- 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 742f69d18fc89..8978c26cacdd7 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2978,6 +2978,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. may be specified. Format: ,.... + ppc_strict_facility_enable + [PPC] This option catches any kernel floating point, + Altivec, VSX and SPE outside of regions specifically + allowed (eg kernel_enable_fpu()/kernel_disable_fpu()). + There is some performance impact when enabling this. + print-fatal-signals= [KNL] debug: print fatal signals diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 987dac090244f..eb2986e60c50f 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -1214,6 +1214,15 @@ static inline void mtmsr_isync(unsigned long val) : "r" ((unsigned long)(v)) \ : "memory") +extern void msr_check_and_set(unsigned long bits); +extern bool strict_msr_control; +extern void __msr_check_and_clear(unsigned long bits); +static inline void msr_check_and_clear(unsigned long bits) +{ + if (strict_msr_control) + __msr_check_and_clear(bits); +} + static inline unsigned long mfvtb (void) { #ifdef CONFIG_PPC_BOOK3S_64 diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 438502f59550f..9414dcb180d6d 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -4,6 +4,8 @@ #ifndef _ASM_POWERPC_SWITCH_TO_H #define _ASM_POWERPC_SWITCH_TO_H +#include + struct thread_struct; struct task_struct; struct pt_regs; @@ -26,15 +28,15 @@ extern void enable_kernel_spe(void); extern void load_up_spe(struct task_struct *); extern void switch_booke_debug_regs(struct debug_reg *new_debug); -static inline void disable_kernel_fp(void) { } -static inline void disable_kernel_altivec(void) { } -static inline void disable_kernel_spe(void) { } -static inline void disable_kernel_vsx(void) { } - #ifdef CONFIG_PPC_FPU extern void flush_fp_to_thread(struct task_struct *); extern void giveup_fpu(struct task_struct *); extern void __giveup_fpu(struct task_struct *); +static inline void disable_kernel_fp(void) +{ + msr_check_and_clear(MSR_FP); +} + #else static inline void flush_fp_to_thread(struct task_struct *t) { } static inline void giveup_fpu(struct task_struct *t) { } @@ -45,6 +47,10 @@ static inline void __giveup_fpu(struct task_struct *t) { } extern void flush_altivec_to_thread(struct task_struct *); extern void giveup_altivec(struct task_struct *); extern void __giveup_altivec(struct task_struct *); +static inline void disable_kernel_altivec(void) +{ + msr_check_and_clear(MSR_VEC); +} #else static inline void flush_altivec_to_thread(struct task_struct *t) { } static inline void giveup_altivec(struct task_struct *t) { } @@ -53,6 +59,10 @@ static inline void __giveup_altivec(struct task_struct *t) { } #ifdef CONFIG_VSX extern void flush_vsx_to_thread(struct task_struct *); +static inline void disable_kernel_vsx(void) +{ + msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX); +} #else static inline void flush_vsx_to_thread(struct task_struct *t) { @@ -63,6 +73,10 @@ static inline void flush_vsx_to_thread(struct task_struct *t) extern void flush_spe_to_thread(struct task_struct *); extern void giveup_spe(struct task_struct *); extern void __giveup_spe(struct task_struct *); +static inline void disable_kernel_spe(void) +{ + msr_check_and_clear(MSR_SPE); +} #else static inline void flush_spe_to_thread(struct task_struct *t) { } static inline void giveup_spe(struct task_struct *t) { } diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 5cdd35c0b0264..1eafceefeac9b 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -87,7 +87,19 @@ static void check_if_tm_restore_required(struct task_struct *tsk) static inline void check_if_tm_restore_required(struct task_struct *tsk) { } #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ -static void msr_check_and_set(unsigned long bits) +bool strict_msr_control; +EXPORT_SYMBOL(strict_msr_control); + +static int __init enable_strict_msr_control(char *str) +{ + strict_msr_control = true; + pr_info("Enabling strict facility control\n"); + + return 0; +} +early_param("ppc_strict_facility_enable", enable_strict_msr_control); + +void msr_check_and_set(unsigned long bits) { unsigned long oldmsr = mfmsr(); unsigned long newmsr; @@ -103,7 +115,7 @@ static void msr_check_and_set(unsigned long bits) mtmsr_isync(newmsr); } -static void msr_check_and_clear(unsigned long bits) +void __msr_check_and_clear(unsigned long bits) { unsigned long oldmsr = mfmsr(); unsigned long newmsr; @@ -118,6 +130,7 @@ static void msr_check_and_clear(unsigned long bits) if (oldmsr != newmsr) mtmsr_isync(newmsr); } +EXPORT_SYMBOL(__msr_check_and_clear); #ifdef CONFIG_PPC_FPU void giveup_fpu(struct task_struct *tsk) -- GitLab From 1f2e25b2d552cade43eacb2edc4e7f01c1cfecb3 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:44:07 +1100 Subject: [PATCH 0793/2855] powerpc: Remove fp_enable() and vec_enable(), use msr_check_and_{set, clear}() More consolidation of our MSR available bit handling. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/processor.h | 2 -- arch/powerpc/kernel/fpu.S | 16 ---------------- arch/powerpc/kernel/process.c | 6 ++++-- arch/powerpc/kernel/vector.S | 10 ---------- 4 files changed, 4 insertions(+), 30 deletions(-) diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index a2e8918408064..ac2330820b9ae 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -380,8 +380,6 @@ extern int set_endian(struct task_struct *tsk, unsigned int val); extern int get_unalign_ctl(struct task_struct *tsk, unsigned long adr); extern int set_unalign_ctl(struct task_struct *tsk, unsigned int val); -extern void fp_enable(void); -extern void vec_enable(void); extern void load_fp_state(struct thread_fp_state *fp); extern void store_fp_state(struct thread_fp_state *fp); extern void load_vr_state(struct thread_vr_state *vr); diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 431ab571ed1b1..2117eaca3d288 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S @@ -76,22 +76,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) blr #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ -/* - * Enable use of the FPU, and VSX if possible, for the caller. - */ -_GLOBAL(fp_enable) - mfmsr r3 - ori r3,r3,MSR_FP -#ifdef CONFIG_VSX -BEGIN_FTR_SECTION - oris r3,r3,MSR_VSX@h -END_FTR_SECTION_IFSET(CPU_FTR_VSX) -#endif - SYNC - MTMSRD(r3) - isync /* (not necessary for arch 2.02 and later) */ - blr - /* * Load state from memory into FP registers including FPSCR. * Assumes the caller has enabled FP in the MSR. diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 1eafceefeac9b..9f8444b84ddee 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -732,13 +732,15 @@ void restore_tm_state(struct pt_regs *regs) msr_diff = current->thread.ckpt_regs.msr & ~regs->msr; msr_diff &= MSR_FP | MSR_VEC | MSR_VSX; if (msr_diff & MSR_FP) { - fp_enable(); + msr_check_and_set(MSR_FP); load_fp_state(¤t->thread.fp_state); + msr_check_and_clear(MSR_FP); regs->msr |= current->thread.fpexc_mode; } if (msr_diff & MSR_VEC) { - vec_enable(); + msr_check_and_set(MSR_VEC); load_vr_state(¤t->thread.vr_state); + msr_check_and_clear(MSR_VEC); } regs->msr |= msr_diff; } diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S index 98675b08efe2b..162d0f7149419 100644 --- a/arch/powerpc/kernel/vector.S +++ b/arch/powerpc/kernel/vector.S @@ -32,16 +32,6 @@ _GLOBAL(do_load_up_transact_altivec) blr #endif -/* - * Enable use of VMX/Altivec for the caller. - */ -_GLOBAL(vec_enable) - mfmsr r3 - oris r3,r3,MSR_VEC@h - MTMSRD(r3) - isync - blr - /* * Load state from memory into VMX registers including VSCR. * Assumes the caller has enabled VMX in the MSR. -- GitLab From 3c0a2f64bcc14402cfdeca633e4210f33affa7a5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 1 Dec 2015 11:29:12 +0300 Subject: [PATCH 0794/2855] regulator: pv88060: fix error handling in probe There were some missing "ret = " assignments here. Signed-off-by: Dan Carpenter Signed-off-by: Mark Brown --- drivers/regulator/pv88060-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/pv88060-regulator.c b/drivers/regulator/pv88060-regulator.c index 69893f28122a6..094376c8de4bd 100644 --- a/drivers/regulator/pv88060-regulator.c +++ b/drivers/regulator/pv88060-regulator.c @@ -351,14 +351,14 @@ static int pv88060_i2c_probe(struct i2c_client *i2c, return ret; } - regmap_write(chip->regmap, PV88060_REG_MASK_B, 0xFF); + ret = regmap_write(chip->regmap, PV88060_REG_MASK_B, 0xFF); if (ret < 0) { dev_err(chip->dev, "Failed to mask B reg: %d\n", ret); return ret; } - regmap_write(chip->regmap, PV88060_REG_MASK_C, 0xFF); + ret = regmap_write(chip->regmap, PV88060_REG_MASK_C, 0xFF); if (ret < 0) { dev_err(chip->dev, "Failed to mask C reg: %d\n", ret); -- GitLab From e470127e9606b1fa151c4184243e61296d1e0c0f Mon Sep 17 00:00:00 2001 From: Ioan-Adrian Ratiu Date: Fri, 20 Nov 2015 22:19:02 +0200 Subject: [PATCH 0795/2855] HID: usbhid: fix recursive deadlock The critical section protected by usbhid->lock in hid_ctrl() is too big and because of this it causes a recursive deadlock. "Too big" means the case statement and the call to hid_input_report() do not need to be protected by the spinlock (no URB operations are done inside them). The deadlock happens because in certain rare cases drivers try to grab the lock while handling the ctrl irq which grabs the lock before them as described above. For example newer wacom tablets like 056a:033c try to reschedule proximity reads from wacom_intuos_schedule_prox_event() calling hid_hw_request() -> usbhid_request() -> usbhid_submit_report() which tries to grab the usbhid lock already held by hid_ctrl(). There are two ways to get out of this deadlock: 1. Make the drivers work "around" the ctrl critical region, in the wacom case for ex. by delaying the scheduling of the proximity read request itself to a workqueue. 2. Shrink the critical region so the usbhid lock protects only the instructions which modify usbhid state, calling hid_input_report() with the spinlock unlocked, allowing the device driver to grab the lock first, finish and then grab the lock afterwards in hid_ctrl(). This patch implements the 2nd solution. Signed-off-by: Ioan-Adrian Ratiu Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 19a4364c90856..ad71160b9ea43 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -477,8 +477,6 @@ static void hid_ctrl(struct urb *urb) struct usbhid_device *usbhid = hid->driver_data; int unplug = 0, status = urb->status; - spin_lock(&usbhid->lock); - switch (status) { case 0: /* success */ if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN) @@ -498,6 +496,8 @@ static void hid_ctrl(struct urb *urb) hid_warn(urb->dev, "ctrl urb status %d received\n", status); } + spin_lock(&usbhid->lock); + if (unplug) { usbhid->ctrltail = usbhid->ctrlhead; } else { -- GitLab From 2f538c017e1a8620d19553931199c6d6a6d31bb2 Mon Sep 17 00:00:00 2001 From: Michael Welling Date: Mon, 30 Nov 2015 09:02:39 -0600 Subject: [PATCH 0796/2855] spi: omap2-mcspi: Prevent duplicate gpio_request Occasionally the setup function will be called multiple times. Only request the gpio the first time otherwise -EBUSY will occur on subsequent calls to setup. Reported-by: Joseph Bell Signed-off-by: Michael Welling Signed-off-by: Mark Brown --- drivers/spi/spi-omap2-mcspi.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 02aa1d0607b3f..7273820275e90 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -1025,6 +1025,16 @@ static int omap2_mcspi_setup(struct spi_device *spi) spi->controller_state = cs; /* Link this to context save list */ list_add_tail(&cs->node, &ctx->cs); + + if (gpio_is_valid(spi->cs_gpio)) { + ret = gpio_request(spi->cs_gpio, dev_name(&spi->dev)); + if (ret) { + dev_err(&spi->dev, "failed to request gpio\n"); + return ret; + } + gpio_direction_output(spi->cs_gpio, + !(spi->mode & SPI_CS_HIGH)); + } } if (!mcspi_dma->dma_rx || !mcspi_dma->dma_tx) { @@ -1033,15 +1043,6 @@ static int omap2_mcspi_setup(struct spi_device *spi) return ret; } - if (gpio_is_valid(spi->cs_gpio)) { - ret = gpio_request(spi->cs_gpio, dev_name(&spi->dev)); - if (ret) { - dev_err(&spi->dev, "failed to request gpio\n"); - return ret; - } - gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); - } - ret = pm_runtime_get_sync(mcspi->dev); if (ret < 0) return ret; -- GitLab From 9b9f1033da9166617c4a5cadfc12b23b465fb596 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Mon, 30 Nov 2015 20:41:17 +0100 Subject: [PATCH 0797/2855] mtd: spi-nor: Fix error message with unrecognized JEDEC The error message was: m25p80 spi32766.0: unrecognized JEDEC id bytes: 00, 0, 0 The new error message: m25p80 spi32766.0: unrecognized JEDEC id bytes: 00, 00, 00 Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/spi-nor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index b7c038c75684b..f8a9b77aac768 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -890,7 +890,7 @@ static const struct flash_info *spi_nor_read_id(struct spi_nor *nor) return &spi_nor_ids[tmp]; } } - dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %2x, %2x\n", + dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n", id[0], id[1], id[2]); return ERR_PTR(-ENODEV); } -- GitLab From 0290cc9f044a4d24d9a64e81761ac84498dc9d73 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 20 Nov 2015 13:53:22 -0500 Subject: [PATCH 0798/2855] USB: limit usbfs snooping of URB contents The usbfs_snoop facility can be very useful for debugging problems involving usbfs. However, it always prints out the entire contents of every URB. When dealing with large quantities of data, this can be less than helpful. This patch ameliorates the situation by adding a module parameter to usbcore for controlling the maximum number of bytes to print when snooping an URB. This makes debugging much easier. For backward compatibility, the default value is set unreasonably high. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- Documentation/kernel-parameters.txt | 4 ++++ drivers/usb/core/devio.c | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 742f69d18fc89..e6b6e056cc115 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -3874,6 +3874,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. usbcore.usbfs_snoop= [USB] Set to log all usbfs traffic (default 0 = off). + usbcore.usbfs_snoop_max= + [USB] Maximum number of bytes to snoop in each URB + (default = 65536). + usbcore.blinkenlights= [USB] Set to cycle leds on hubs (default 0 = off). diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 38ae877c46e31..3d41faf6e6073 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -100,6 +100,11 @@ static bool usbfs_snoop; module_param(usbfs_snoop, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(usbfs_snoop, "true to log all usbfs traffic"); +static unsigned usbfs_snoop_max = 65536; +module_param(usbfs_snoop_max, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(usbfs_snoop_max, + "maximum number of bytes to print while snooping"); + #define snoop(dev, format, arg...) \ do { \ if (usbfs_snoop) \ @@ -392,6 +397,7 @@ static void snoop_urb(struct usb_device *udev, ep, t, d, length, timeout_or_status); } + data_len = min(data_len, usbfs_snoop_max); if (data && data_len > 0) { print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE, 32, 1, data, data_len, 1); @@ -402,7 +408,8 @@ static void snoop_urb_data(struct urb *urb, unsigned len) { int i, size; - if (!usbfs_snoop) + len = min(len, usbfs_snoop_max); + if (!usbfs_snoop || len == 0) return; if (urb->num_sgs == 0) { -- GitLab From a016a816bb96088ce4cd0ec890e256e4a63dfb47 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 20 Nov 2015 13:53:35 -0500 Subject: [PATCH 0799/2855] USB: add usbfs snooping for REAP and DISCARD This patch improves the usbfs_snoop debugging facility by adding messages for a couple of significant events which, up to now, have not been logged. The events are reaping and discarding (i.e., cancelling) an URB. The debugging messages include the userspace address of the URB being reaped or discarded. The reaping messages have to be added in four places, in order to handle blocking and non-blocking reaps in both normal and 32-bit compatibility mode. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 3d41faf6e6073..e9f0de3e06db1 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1716,8 +1716,12 @@ static struct async *reap_as(struct usb_dev_state *ps) static int proc_reapurb(struct usb_dev_state *ps, void __user *arg) { struct async *as = reap_as(ps); + if (as) { - int retval = processcompl(as, (void __user * __user *)arg); + int retval; + + snoop(&ps->dev->dev, "reap %p\n", as->userurb); + retval = processcompl(as, (void __user * __user *)arg); free_async(as); return retval; } @@ -1733,6 +1737,7 @@ static int proc_reapurbnonblock(struct usb_dev_state *ps, void __user *arg) as = async_getcompleted(ps); if (as) { + snoop(&ps->dev->dev, "reap %p\n", as->userurb); retval = processcompl(as, (void __user * __user *)arg); free_async(as); } else { @@ -1859,8 +1864,12 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) static int proc_reapurb_compat(struct usb_dev_state *ps, void __user *arg) { struct async *as = reap_as(ps); + if (as) { - int retval = processcompl_compat(as, (void __user * __user *)arg); + int retval; + + snoop(&ps->dev->dev, "reap %p\n", as->userurb); + retval = processcompl_compat(as, (void __user * __user *)arg); free_async(as); return retval; } @@ -1876,6 +1885,7 @@ static int proc_reapurbnonblock_compat(struct usb_dev_state *ps, void __user *ar as = async_getcompleted(ps); if (as) { + snoop(&ps->dev->dev, "reap %p\n", as->userurb); retval = processcompl_compat(as, (void __user * __user *)arg); free_async(as); } else { @@ -2280,7 +2290,7 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, #endif case USBDEVFS_DISCARDURB: - snoop(&dev->dev, "%s: DISCARDURB\n", __func__); + snoop(&dev->dev, "%s: DISCARDURB %p\n", __func__, p); ret = proc_unlinkurb(ps, p); break; -- GitLab From 8ee10d6292cab0e425f93dbfa1f0e805c449dfc2 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 20 Nov 2015 13:53:45 -0500 Subject: [PATCH 0800/2855] USB: EHCI: enhance "async" debugfs output This patch enhances the "async" debugfs file in ehci-hcd by printing out several additional fields in the hardware-accessible data structures. These fields are important for determining the hardware's view of the async schedule, in particular, the addresses of the current and next qTDs for each QH along with the start address of each qTD's data buffer. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-dbg.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index b26b96e25a131..b7d623f1523c5 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -436,7 +436,8 @@ static void qh_lines ( scratch = hc32_to_cpup(ehci, &hw->hw_info1); hw_curr = (mark == '*') ? hc32_to_cpup(ehci, &hw->hw_current) : 0; temp = scnprintf (next, size, - "qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)", + "qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)" + " [cur %08x next %08x buf[0] %08x]", qh, scratch & 0x007f, speed_char (scratch), (scratch >> 8) & 0x000f, @@ -444,7 +445,10 @@ static void qh_lines ( hc32_to_cpup(ehci, &hw->hw_token), mark, (cpu_to_hc32(ehci, QTD_TOGGLE) & hw->hw_token) ? "data1" : "data0", - (hc32_to_cpup(ehci, &hw->hw_alt_next) >> 1) & 0x0f); + (hc32_to_cpup(ehci, &hw->hw_alt_next) >> 1) & 0x0f, + hc32_to_cpup(ehci, &hw->hw_current), + hc32_to_cpup(ehci, &hw->hw_qtd_next), + hc32_to_cpup(ehci, &hw->hw_buf[0])); size -= temp; next += temp; @@ -464,7 +468,8 @@ static void qh_lines ( mark = '/'; } temp = snprintf (next, size, - "\n\t%p%c%s len=%d %08x urb %p", + "\n\t%p%c%s len=%d %08x urb %p" + " [td %08x buf[0] %08x]", td, mark, ({ char *tmp; switch ((scratch>>8)&0x03) { case 0: tmp = "out"; break; @@ -474,7 +479,9 @@ static void qh_lines ( } tmp;}), (scratch >> 16) & 0x7fff, scratch, - td->urb); + td->urb, + (u32) td->qtd_dma, + hc32_to_cpup(ehci, &td->hw_buf[0])); if (size < temp) temp = size; size -= temp; -- GitLab From fc0855f2747a0e21d86b7e63c50bf234fa766184 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 20 Nov 2015 13:53:58 -0500 Subject: [PATCH 0801/2855] USB: EHCI: warn on unexpectedly active QH This patch adds a new warning message to ehci-hcd. The warning is triggered whenever the driver finds that the hardware has set the Active bit in a QH at a time when the driver expects the QH to be completely idle. Such bugs have been observed by users in the past, and since they can lead to serious problems (such as inability to unlink an URB that never completes), it would be good to know about them when they occur. This won't fix these bugs; that's a bigger job for a later patch. But success isn't guaranteed, since this depends on aspects of the hardware which are not documented in the EHCI spec or for which the spec's recommendations are clearly unworkable. It therefore seems worthwhile to check for these bugs proactively. Signed-off-by: Alan Stern Reported-by: Michael Reutman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-q.c | 9 +++++++-- drivers/usb/host/ehci.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 54f5332f814dd..aad0777240d3b 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -132,10 +132,14 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh) * qtd is updated in qh_completions(). Update the QH * overlay here. */ - if (qh->hw->hw_token & ACTIVE_BIT(ehci)) + if (qh->hw->hw_token & ACTIVE_BIT(ehci)) { qh->hw->hw_qtd_next = qtd->hw_next; - else + if (qh->should_be_inactive) + ehci_warn(ehci, "qh %p should be inactive!\n", qh); + } else { qh_update(ehci, qh, qtd); + } + qh->should_be_inactive = 0; } /*-------------------------------------------------------------------------*/ @@ -438,6 +442,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) (hw->hw_token & ACTIVE_BIT(ehci))) { token = hc32_to_cpu(ehci, hw->hw_token); hw->hw_token &= ~ACTIVE_BIT(ehci); + qh->should_be_inactive = 1; /* An unlink may leave an incomplete * async transaction in the TT buffer. diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 46f62e41bcde9..ec61aedb00673 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -439,6 +439,7 @@ struct ehci_qh { unsigned dequeue_during_giveback:1; unsigned exception:1; /* got a fault, or an unlink was requested */ + unsigned should_be_inactive:1; }; /*-------------------------------------------------------------------------*/ -- GitLab From 5e6389fda02d6a22800bacfb2850366bfa18291b Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Tue, 24 Nov 2015 13:09:46 +0200 Subject: [PATCH 0802/2855] xhci: use the correct define to indicate port status suspend change. use the variables defined for populating the port status and port chage bits retuend by GetPortStatus request intead of the hub class feature selectors. The defines for hub class feature selectors are used for other purposes, they work as port status and feature selectors are in the same order, and set the same bits, but it makes the code very hard to follow Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 0230965fb78cf..0863d8a61f816 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -820,7 +820,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd, xhci_hub_report_usb2_link_state(&status, raw_port_status); } if (bus_state->port_c_suspend & (1 << wIndex)) - status |= 1 << USB_PORT_FEAT_C_SUSPEND; + status |= USB_PORT_STAT_C_SUSPEND << 16; return status; } -- GitLab From 32479d4b929714b7891efea3783ac4d378e30c59 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 24 Nov 2015 13:09:47 +0200 Subject: [PATCH 0803/2855] usb: host: xhci: cleanup hcd private size This patch cleanups the hcd private size to suitable size. The previous code has "sizeof(struct xhci_hcd *)" in xhci_hc_driver as hcd_priv_size and sizeof(struct xhci_hcd) in xhci_plat_overrides or xhci_pci_overrides as extra_priv_size. However, the xhci driver uses a "sizeof(struct xhcd_hcd)" memory space in each hcd (main_hcd and shared_hcd) actually. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 1 - drivers/usb/host/xhci-plat.c | 1 - drivers/usb/host/xhci.c | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 17f6897acde2a..b51ac631c2402 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -53,7 +53,6 @@ static struct hc_driver __read_mostly xhci_pci_hc_driver; static int xhci_pci_setup(struct usb_hcd *hcd); static const struct xhci_driver_overrides xhci_pci_overrides __initconst = { - .extra_priv_size = sizeof(struct xhci_hcd), .reset = xhci_pci_setup, }; diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 05647e6753cd8..4699c1e223d50 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -31,7 +31,6 @@ static int xhci_plat_setup(struct usb_hcd *hcd); static int xhci_plat_start(struct usb_hcd *hcd); static const struct xhci_driver_overrides xhci_plat_overrides __initconst = { - .extra_priv_size = sizeof(struct xhci_hcd), .reset = xhci_plat_setup, .start = xhci_plat_start, }; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index dfa44d3e8eee4..ac25e9037e88b 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -4952,7 +4952,7 @@ EXPORT_SYMBOL_GPL(xhci_gen_setup); static const struct hc_driver xhci_hc_driver = { .description = "xhci-hcd", .product_desc = "xHCI Host Controller", - .hcd_priv_size = sizeof(struct xhci_hcd *), + .hcd_priv_size = sizeof(struct xhci_hcd), /* * generic hardware linkage -- GitLab From 79a17ddf89173cf3749656e5d3f87d33c196492b Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 24 Nov 2015 13:09:48 +0200 Subject: [PATCH 0804/2855] usb: host: xhci: add a platform-private field This patch adds an xhci->priv field for private use by XHCI platform drivers. Until now none of the platform drivers has used this private space. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 0b9451250e33f..8b46296503283 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1656,6 +1656,9 @@ struct xhci_hcd { u32 port_status_u0; /* Compliance Mode Timer Triggered every 2 seconds */ #define COMP_MODE_RCVRY_MSECS 2000 + + /* platform-specific data -- must come last */ + unsigned long priv[0] __aligned(sizeof(s64)); }; /* Platform specific overrides to generic XHCI hc_driver ops */ -- GitLab From 4efb2f69411456d35051e9047c15157c9a5ba217 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 24 Nov 2015 13:09:49 +0200 Subject: [PATCH 0805/2855] usb: host: xhci-plat: add struct xhci_plat_priv This patch adds struct xhci_plat_priv to simplify the code to match platform specific variables. For now, this patch adds a member "type" in the structure. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-plat.c | 73 ++++++++++++++++++++++++------------ drivers/usb/host/xhci-plat.h | 37 ++++++++++++++++++ 2 files changed, 85 insertions(+), 25 deletions(-) create mode 100644 drivers/usb/host/xhci-plat.h diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 4699c1e223d50..083e77bc80ae4 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -22,6 +22,7 @@ #include #include "xhci.h" +#include "xhci-plat.h" #include "xhci-mvebu.h" #include "xhci-rcar.h" @@ -31,6 +32,7 @@ static int xhci_plat_setup(struct usb_hcd *hcd); static int xhci_plat_start(struct usb_hcd *hcd); static const struct xhci_driver_overrides xhci_plat_overrides __initconst = { + .extra_priv_size = sizeof(struct xhci_plat_priv), .reset = xhci_plat_setup, .start = xhci_plat_start, }; @@ -48,11 +50,9 @@ static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci) /* called during probe() after chip reset completes */ static int xhci_plat_setup(struct usb_hcd *hcd) { - struct device_node *of_node = hcd->self.controller->of_node; int ret; - if (of_device_is_compatible(of_node, "renesas,xhci-r8a7790") || - of_device_is_compatible(of_node, "renesas,xhci-r8a7791")) { + if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2)) { ret = xhci_rcar_init_quirk(hcd); if (ret) return ret; @@ -63,19 +63,49 @@ static int xhci_plat_setup(struct usb_hcd *hcd) static int xhci_plat_start(struct usb_hcd *hcd) { - struct device_node *of_node = hcd->self.controller->of_node; - - if (of_device_is_compatible(of_node, "renesas,xhci-r8a7790") || - of_device_is_compatible(of_node, "renesas,xhci-r8a7791")) + if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2)) xhci_rcar_start(hcd); return xhci_run(hcd); } +#ifdef CONFIG_OF +static const struct xhci_plat_priv xhci_plat_marvell_armada = { + .type = XHCI_PLAT_TYPE_MARVELL_ARMADA, +}; + +static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen2 = { + .type = XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2, +}; + +static const struct of_device_id usb_xhci_of_match[] = { + { + .compatible = "generic-xhci", + }, { + .compatible = "xhci-platform", + }, { + .compatible = "marvell,armada-375-xhci", + .data = &xhci_plat_marvell_armada, + }, { + .compatible = "marvell,armada-380-xhci", + .data = &xhci_plat_marvell_armada, + }, { + .compatible = "renesas,xhci-r8a7790", + .data = &xhci_plat_renesas_rcar_gen2, + }, { + .compatible = "renesas,xhci-r8a7791", + .data = &xhci_plat_renesas_rcar_gen2, + }, { + }, +}; +MODULE_DEVICE_TABLE(of, usb_xhci_of_match); +#endif + static int xhci_plat_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; struct usb_xhci_pdata *pdata = dev_get_platdata(&pdev->dev); + const struct of_device_id *match; const struct hc_driver *driver; struct xhci_hcd *xhci; struct resource *res; @@ -133,10 +163,17 @@ static int xhci_plat_probe(struct platform_device *pdev) goto put_hcd; } - if (of_device_is_compatible(pdev->dev.of_node, - "marvell,armada-375-xhci") || - of_device_is_compatible(pdev->dev.of_node, - "marvell,armada-380-xhci")) { + xhci = hcd_to_xhci(hcd); + match = of_match_node(usb_xhci_of_match, node); + if (match) { + const struct xhci_plat_priv *priv_match = match->data; + struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); + + /* Just copy data for now */ + *priv = *priv_match; + } + + if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_MARVELL_ARMADA)) { ret = xhci_mvebu_mbus_init_quirk(pdev); if (ret) goto disable_clk; @@ -144,7 +181,6 @@ static int xhci_plat_probe(struct platform_device *pdev) device_wakeup_enable(hcd->self.controller); - xhci = hcd_to_xhci(hcd); xhci->clk = clk; xhci->main_hcd = hcd; xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev, @@ -255,19 +291,6 @@ static const struct dev_pm_ops xhci_plat_pm_ops = { #define DEV_PM_OPS NULL #endif /* CONFIG_PM */ -#ifdef CONFIG_OF -static const struct of_device_id usb_xhci_of_match[] = { - { .compatible = "generic-xhci" }, - { .compatible = "xhci-platform" }, - { .compatible = "marvell,armada-375-xhci"}, - { .compatible = "marvell,armada-380-xhci"}, - { .compatible = "renesas,xhci-r8a7790"}, - { .compatible = "renesas,xhci-r8a7791"}, - { }, -}; -MODULE_DEVICE_TABLE(of, usb_xhci_of_match); -#endif - static const struct acpi_device_id usb_xhci_acpi_match[] = { /* XHCI-compliant USB Controller */ { "PNP0D10", }, diff --git a/drivers/usb/host/xhci-plat.h b/drivers/usb/host/xhci-plat.h new file mode 100644 index 0000000000000..4479869bd0069 --- /dev/null +++ b/drivers/usb/host/xhci-plat.h @@ -0,0 +1,37 @@ +/* + * xhci-plat.h - xHCI host controller driver platform Bus Glue. + * + * Copyright (C) 2015 Renesas Electronics Corporation + * + * 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. + */ + +#ifndef _XHCI_PLAT_H +#define _XHCI_PLAT_H + +#include "xhci.h" /* for hcd_to_xhci() */ + +enum xhci_plat_type { + XHCI_PLAT_TYPE_MARVELL_ARMADA, + XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2, +}; + +struct xhci_plat_priv { + enum xhci_plat_type type; +}; + +#define hcd_to_xhci_priv(h) ((struct xhci_plat_priv *)hcd_to_xhci(h)->priv) + +static inline bool xhci_plat_type_is(struct usb_hcd *hcd, + enum xhci_plat_type type) +{ + struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); + + if (priv && priv->type == type) + return true; + else + return false; +} +#endif /* _XHCI_PLAT_H */ -- GitLab From e93272fe3c1b7a03865e567f64403c6b578486cf Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 24 Nov 2015 13:09:50 +0200 Subject: [PATCH 0806/2855] usb: host: xhci-plat: add firmware_name in xhci_plat_priv This patch adds a member "firmware_name" in struct xhci_plat_priv to simplify the code to match specific firmware name. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-plat.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/host/xhci-plat.h b/drivers/usb/host/xhci-plat.h index 4479869bd0069..20b32a749398b 100644 --- a/drivers/usb/host/xhci-plat.h +++ b/drivers/usb/host/xhci-plat.h @@ -20,6 +20,7 @@ enum xhci_plat_type { struct xhci_plat_priv { enum xhci_plat_type type; + const char *firmware_name; }; #define hcd_to_xhci_priv(h) ((struct xhci_plat_priv *)hcd_to_xhci(h)->priv) -- GitLab From 9bf9d9d6008c7541a5c0bcfe61a0e0504c6f2bb9 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 24 Nov 2015 13:09:51 +0200 Subject: [PATCH 0807/2855] usb: host: xhci-rcar: Change code for new SoCs This patch changes code to ease the addition of next generation SoCs. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-plat.c | 1 + drivers/usb/host/xhci-rcar.c | 37 ++++++++++++++++++++++-------------- drivers/usb/host/xhci-rcar.h | 2 ++ 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 083e77bc80ae4..a471f12ffa468 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -76,6 +76,7 @@ static const struct xhci_plat_priv xhci_plat_marvell_armada = { static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen2 = { .type = XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2, + .firmware_name = XHCI_RCAR_FIRMWARE_NAME_V1, }; static const struct of_device_id usb_xhci_of_match[] = { diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c index ff0d1b44ea586..010a24fdaa591 100644 --- a/drivers/usb/host/xhci-rcar.c +++ b/drivers/usb/host/xhci-rcar.c @@ -14,10 +14,10 @@ #include #include "xhci.h" +#include "xhci-plat.h" #include "xhci-rcar.h" -#define FIRMWARE_NAME "r8a779x_usb3_v1.dlmem" -MODULE_FIRMWARE(FIRMWARE_NAME); +MODULE_FIRMWARE(XHCI_RCAR_FIRMWARE_NAME_V1); /*** Register Offset ***/ #define RCAR_USB3_INT_ENA 0x224 /* Interrupt Enable */ @@ -56,6 +56,19 @@ MODULE_FIRMWARE(FIRMWARE_NAME); #define RCAR_USB3_RX_POL_VAL BIT(21) #define RCAR_USB3_TX_POL_VAL BIT(4) +static void xhci_rcar_start_gen2(struct usb_hcd *hcd) +{ + /* LCLK Select */ + writel(RCAR_USB3_LCLK_ENA_VAL, hcd->regs + RCAR_USB3_LCLK); + /* USB3.0 Configuration */ + writel(RCAR_USB3_CONF1_VAL, hcd->regs + RCAR_USB3_CONF1); + writel(RCAR_USB3_CONF2_VAL, hcd->regs + RCAR_USB3_CONF2); + writel(RCAR_USB3_CONF3_VAL, hcd->regs + RCAR_USB3_CONF3); + /* USB3.0 Polarity */ + writel(RCAR_USB3_RX_POL_VAL, hcd->regs + RCAR_USB3_RX_POL); + writel(RCAR_USB3_TX_POL_VAL, hcd->regs + RCAR_USB3_TX_POL); +} + void xhci_rcar_start(struct usb_hcd *hcd) { u32 temp; @@ -65,27 +78,23 @@ void xhci_rcar_start(struct usb_hcd *hcd) temp = readl(hcd->regs + RCAR_USB3_INT_ENA); temp |= RCAR_USB3_INT_ENA_VAL; writel(temp, hcd->regs + RCAR_USB3_INT_ENA); - /* LCLK Select */ - writel(RCAR_USB3_LCLK_ENA_VAL, hcd->regs + RCAR_USB3_LCLK); - /* USB3.0 Configuration */ - writel(RCAR_USB3_CONF1_VAL, hcd->regs + RCAR_USB3_CONF1); - writel(RCAR_USB3_CONF2_VAL, hcd->regs + RCAR_USB3_CONF2); - writel(RCAR_USB3_CONF3_VAL, hcd->regs + RCAR_USB3_CONF3); - /* USB3.0 Polarity */ - writel(RCAR_USB3_RX_POL_VAL, hcd->regs + RCAR_USB3_RX_POL); - writel(RCAR_USB3_TX_POL_VAL, hcd->regs + RCAR_USB3_TX_POL); + if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2)) + xhci_rcar_start_gen2(hcd); } } -static int xhci_rcar_download_firmware(struct device *dev, void __iomem *regs) +static int xhci_rcar_download_firmware(struct usb_hcd *hcd) { + struct device *dev = hcd->self.controller; + void __iomem *regs = hcd->regs; + struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); const struct firmware *fw; int retval, index, j, time; int timeout = 10000; u32 data, val, temp; /* request R-Car USB3.0 firmware */ - retval = request_firmware(&fw, FIRMWARE_NAME, dev); + retval = request_firmware(&fw, priv->firmware_name, dev); if (retval) return retval; @@ -144,5 +153,5 @@ int xhci_rcar_init_quirk(struct usb_hcd *hcd) if (!hcd->regs) return 0; - return xhci_rcar_download_firmware(hcd->self.controller, hcd->regs); + return xhci_rcar_download_firmware(hcd); } diff --git a/drivers/usb/host/xhci-rcar.h b/drivers/usb/host/xhci-rcar.h index 58501256715d5..ba3ad31e702ac 100644 --- a/drivers/usb/host/xhci-rcar.h +++ b/drivers/usb/host/xhci-rcar.h @@ -11,6 +11,8 @@ #ifndef _XHCI_RCAR_H #define _XHCI_RCAR_H +#define XHCI_RCAR_FIRMWARE_NAME_V1 "r8a779x_usb3_v1.dlmem" + #if IS_ENABLED(CONFIG_USB_XHCI_RCAR) void xhci_rcar_start(struct usb_hcd *hcd); int xhci_rcar_init_quirk(struct usb_hcd *hcd); -- GitLab From 82487b714858d99feff600a096177675481a4935 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 24 Nov 2015 13:09:52 +0200 Subject: [PATCH 0808/2855] usb: host: xhci-plat: add support for the R-Car M2-N xHCI controller This patch adds support for R-Car M2-N (r8a7793) xHCI controller. This SoC is compatible with R-Car H2 (r8a7790) and R-Car M2-W (r8a7791). Signed-off-by: Yoshihiro Shimoda Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/usb-xhci.txt | 4 ++-- drivers/usb/host/xhci-plat.c | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt index 86f67f0886bc4..106299ad38076 100644 --- a/Documentation/devicetree/bindings/usb/usb-xhci.txt +++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt @@ -3,8 +3,8 @@ USB xHCI controllers Required properties: - compatible: should be one of "generic-xhci", "marvell,armada-375-xhci", "marvell,armada-380-xhci", - "renesas,xhci-r8a7790", "renesas,xhci-r8a7791" (deprecated: - "xhci-platform"). + "renesas,xhci-r8a7790", "renesas,xhci-r8a7791", "renesas,xhci-r8a7793" + (deprecated: "xhci-platform"). - reg: should contain address and length of the standard XHCI register set for the device. - interrupts: one XHCI interrupt should be described here. diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index a471f12ffa468..0113e79c74cb3 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -96,6 +96,9 @@ static const struct of_device_id usb_xhci_of_match[] = { }, { .compatible = "renesas,xhci-r8a7791", .data = &xhci_plat_renesas_rcar_gen2, + }, { + .compatible = "renesas,xhci-r8a7793", + .data = &xhci_plat_renesas_rcar_gen2, }, { }, }; -- GitLab From 526a240f6145fa54658a4d56327f3e053ac73c48 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 24 Nov 2015 13:09:53 +0200 Subject: [PATCH 0809/2855] usb: host: xhci-plat: add support for the R-Car H3 xHCI controllers The R-Car H3 has two xHCI controllers. This SoC is compatible with R-Car Gen2 SoCs, however this SoC doesn't need some specific registers setting, and need a new firmware. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/usb-xhci.txt | 4 ++-- drivers/usb/host/xhci-plat.c | 14 ++++++++++++-- drivers/usb/host/xhci-plat.h | 1 + drivers/usb/host/xhci-rcar.c | 7 +++++++ drivers/usb/host/xhci-rcar.h | 1 + 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt index 106299ad38076..082573289f1e5 100644 --- a/Documentation/devicetree/bindings/usb/usb-xhci.txt +++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt @@ -3,8 +3,8 @@ USB xHCI controllers Required properties: - compatible: should be one of "generic-xhci", "marvell,armada-375-xhci", "marvell,armada-380-xhci", - "renesas,xhci-r8a7790", "renesas,xhci-r8a7791", "renesas,xhci-r8a7793" - (deprecated: "xhci-platform"). + "renesas,xhci-r8a7790", "renesas,xhci-r8a7791", "renesas,xhci-r8a7793", + "renesas,xhci-r8a7795" (deprecated: "xhci-platform"). - reg: should contain address and length of the standard XHCI register set for the device. - interrupts: one XHCI interrupt should be described here. diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 0113e79c74cb3..770b6b0887979 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -52,7 +52,8 @@ static int xhci_plat_setup(struct usb_hcd *hcd) { int ret; - if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2)) { + if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2) || + xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN3)) { ret = xhci_rcar_init_quirk(hcd); if (ret) return ret; @@ -63,7 +64,8 @@ static int xhci_plat_setup(struct usb_hcd *hcd) static int xhci_plat_start(struct usb_hcd *hcd) { - if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2)) + if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2) || + xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN3)) xhci_rcar_start(hcd); return xhci_run(hcd); @@ -79,6 +81,11 @@ static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen2 = { .firmware_name = XHCI_RCAR_FIRMWARE_NAME_V1, }; +static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen3 = { + .type = XHCI_PLAT_TYPE_RENESAS_RCAR_GEN3, + .firmware_name = XHCI_RCAR_FIRMWARE_NAME_V2, +}; + static const struct of_device_id usb_xhci_of_match[] = { { .compatible = "generic-xhci", @@ -99,6 +106,9 @@ static const struct of_device_id usb_xhci_of_match[] = { }, { .compatible = "renesas,xhci-r8a7793", .data = &xhci_plat_renesas_rcar_gen2, + }, { + .compatible = "renesas,xhci-r8a7795", + .data = &xhci_plat_renesas_rcar_gen3, }, { }, }; diff --git a/drivers/usb/host/xhci-plat.h b/drivers/usb/host/xhci-plat.h index 20b32a749398b..5a2e2e3936c4c 100644 --- a/drivers/usb/host/xhci-plat.h +++ b/drivers/usb/host/xhci-plat.h @@ -16,6 +16,7 @@ enum xhci_plat_type { XHCI_PLAT_TYPE_MARVELL_ARMADA, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2, + XHCI_PLAT_TYPE_RENESAS_RCAR_GEN3, }; struct xhci_plat_priv { diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c index 010a24fdaa591..623100e9385ea 100644 --- a/drivers/usb/host/xhci-rcar.c +++ b/drivers/usb/host/xhci-rcar.c @@ -17,7 +17,14 @@ #include "xhci-plat.h" #include "xhci-rcar.h" +/* +* - The V2 firmware is possible to use on R-Car Gen2. However, the V2 causes +* performance degradation. So, this driver continues to use the V1 if R-Car +* Gen2. +* - The V1 firmware is impossible to use on R-Car Gen3. +*/ MODULE_FIRMWARE(XHCI_RCAR_FIRMWARE_NAME_V1); +MODULE_FIRMWARE(XHCI_RCAR_FIRMWARE_NAME_V2); /*** Register Offset ***/ #define RCAR_USB3_INT_ENA 0x224 /* Interrupt Enable */ diff --git a/drivers/usb/host/xhci-rcar.h b/drivers/usb/host/xhci-rcar.h index ba3ad31e702ac..2941a25cfe989 100644 --- a/drivers/usb/host/xhci-rcar.h +++ b/drivers/usb/host/xhci-rcar.h @@ -12,6 +12,7 @@ #define _XHCI_RCAR_H #define XHCI_RCAR_FIRMWARE_NAME_V1 "r8a779x_usb3_v1.dlmem" +#define XHCI_RCAR_FIRMWARE_NAME_V2 "r8a779x_usb3_v2.dlmem" #if IS_ENABLED(CONFIG_USB_XHCI_RCAR) void xhci_rcar_start(struct usb_hcd *hcd); -- GitLab From c74732e3c5f02b09ad839238622a8bd4fad75f84 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Tue, 24 Nov 2015 13:09:54 +0200 Subject: [PATCH 0810/2855] dt-bindings: Add a binding for Mediatek xHCI host controller add a DT binding documentation of xHCI host controller for the MT8173 SoC from Mediatek. Signed-off-by: Chunfeng Yun Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/mt8173-xhci.txt | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/mt8173-xhci.txt diff --git a/Documentation/devicetree/bindings/usb/mt8173-xhci.txt b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt new file mode 100644 index 0000000000000..b3a7ffa48852f --- /dev/null +++ b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt @@ -0,0 +1,51 @@ +MT8173 xHCI + +The device node for Mediatek SOC USB3.0 host controller + +Required properties: + - compatible : should contain "mediatek,mt8173-xhci" + - reg : specifies physical base address and size of the registers, + the first one for MAC, the second for IPPC + - interrupts : interrupt used by the controller + - power-domains : a phandle to USB power domain node to control USB's + mtcmos + - vusb33-supply : regulator of USB avdd3.3v + + - clocks : a list of phandle + clock-specifier pairs, one for each + entry in clock-names + - clock-names : must contain + "sys_ck": for clock of xHCI MAC + "wakeup_deb_p0": for USB wakeup debounce clock of port0 + "wakeup_deb_p1": for USB wakeup debounce clock of port1 + + - phys : a list of phandle + phy specifier pairs + +Optional properties: + - mediatek,wakeup-src : 1: ip sleep wakeup mode; 2: line state wakeup + mode; + - mediatek,syscon-wakeup : phandle to syscon used to access USB wakeup + control register, it depends on "mediatek,wakeup-src". + - vbus-supply : reference to the VBUS regulator; + - usb3-lpm-capable : supports USB3.0 LPM + +Example: +usb30: usb@11270000 { + compatible = "mediatek,mt8173-xhci"; + reg = <0 0x11270000 0 0x1000>, + <0 0x11280700 0 0x0100>; + interrupts = ; + power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>; + clocks = <&topckgen CLK_TOP_USB30_SEL>, + <&pericfg CLK_PERI_USB0>, + <&pericfg CLK_PERI_USB1>; + clock-names = "sys_ck", + "wakeup_deb_p0", + "wakeup_deb_p1"; + phys = <&phy_port0 PHY_TYPE_USB3>, + <&phy_port1 PHY_TYPE_USB2>; + vusb33-supply = <&mt6397_vusb_reg>; + vbus-supply = <&usb_p1_vbus>; + usb3-lpm-capable; + mediatek,syscon-wakeup = <&pericfg>; + mediatek,wakeup-src = <1>; +}; -- GitLab From 0cbd4b34cda9dfd36b6c26b692dee181e0100b67 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Tue, 24 Nov 2015 13:09:55 +0200 Subject: [PATCH 0811/2855] xhci: mediatek: support MTK xHCI host controller There some vendor quirks for MTK xhci host controller: 1. It defines some extra SW scheduling parameters for HW to minimize the scheduling effort for synchronous and interrupt endpoints. The parameters are put into reseved DWs of slot context and endpoint context. 2. Its IMODI unit for Interrupter Moderation register is 8 times as much as that defined in xHCI spec. 3. Its TDS in Normal TRB defines a number of packets that remains to be transferred for a TD after processing all Max packets in all previous TRBs. Signed-off-by: Chunfeng Yun Tested-by: Daniel Thompson Reviewed-by: Daniel Thompson Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 9 + drivers/usb/host/Makefile | 4 + drivers/usb/host/xhci-mtk-sch.c | 415 +++++++++++++++++ drivers/usb/host/xhci-mtk.c | 763 ++++++++++++++++++++++++++++++++ drivers/usb/host/xhci-mtk.h | 162 +++++++ drivers/usb/host/xhci-ring.c | 16 +- drivers/usb/host/xhci.c | 19 +- drivers/usb/host/xhci.h | 1 + 8 files changed, 1383 insertions(+), 6 deletions(-) create mode 100644 drivers/usb/host/xhci-mtk-sch.c create mode 100644 drivers/usb/host/xhci-mtk.c create mode 100644 drivers/usb/host/xhci-mtk.h diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 3bb08870148f4..daa563ff1fa05 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -41,6 +41,15 @@ config USB_XHCI_PLATFORM If unsure, say N. +config USB_XHCI_MTK + tristate "xHCI support for Mediatek MT65xx" + select MFD_SYSCON + depends on ARCH_MEDIATEK || COMPILE_TEST + ---help--- + Say 'Y' to enable the support for the xHCI host controller + found in Mediatek MT65xx SoCs. + If unsure, say N. + config USB_XHCI_MVEBU tristate "xHCI support for Marvell Armada 375/38x" select USB_XHCI_PLATFORM diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index e7558abc994d7..65a06b4382bfa 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -13,6 +13,9 @@ fhci-$(CONFIG_FHCI_DEBUG) += fhci-dbg.o xhci-hcd-y := xhci.o xhci-mem.o xhci-hcd-y += xhci-ring.o xhci-hub.o xhci-dbg.o xhci-hcd-y += xhci-trace.o +ifneq ($(CONFIG_USB_XHCI_MTK), ) + xhci-hcd-y += xhci-mtk-sch.o +endif xhci-plat-hcd-y := xhci-plat.o ifneq ($(CONFIG_USB_XHCI_MVEBU), ) @@ -64,6 +67,7 @@ obj-$(CONFIG_USB_FHCI_HCD) += fhci.o obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o +obj-$(CONFIG_USB_XHCI_MTK) += xhci-mtk.o obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c new file mode 100644 index 0000000000000..c30de7c39f440 --- /dev/null +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2015 MediaTek Inc. + * Author: + * Zhigang.Wei + * Chunfeng.Yun + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include + +#include "xhci.h" +#include "xhci-mtk.h" + +#define SS_BW_BOUNDARY 51000 +/* table 5-5. High-speed Isoc Transaction Limits in usb_20 spec */ +#define HS_BW_BOUNDARY 6144 +/* usb2 spec section11.18.1: at most 188 FS bytes per microframe */ +#define FS_PAYLOAD_MAX 188 + +/* mtk scheduler bitmasks */ +#define EP_BPKTS(p) ((p) & 0x3f) +#define EP_BCSCOUNT(p) (((p) & 0x7) << 8) +#define EP_BBM(p) ((p) << 11) +#define EP_BOFFSET(p) ((p) & 0x3fff) +#define EP_BREPEAT(p) (((p) & 0x7fff) << 16) + +static int is_fs_or_ls(enum usb_device_speed speed) +{ + return speed == USB_SPEED_FULL || speed == USB_SPEED_LOW; +} + +/* +* get the index of bandwidth domains array which @ep belongs to. +* +* the bandwidth domain array is saved to @sch_array of struct xhci_hcd_mtk, +* each HS root port is treated as a single bandwidth domain, +* but each SS root port is treated as two bandwidth domains, one for IN eps, +* one for OUT eps. +* @real_port value is defined as follow according to xHCI spec: +* 1 for SSport0, ..., N+1 for SSportN, N+2 for HSport0, N+3 for HSport1, etc +* so the bandwidth domain array is organized as follow for simplification: +* SSport0-OUT, SSport0-IN, ..., SSportX-OUT, SSportX-IN, HSport0, ..., HSportY +*/ +static int get_bw_index(struct xhci_hcd *xhci, struct usb_device *udev, + struct usb_host_endpoint *ep) +{ + struct xhci_virt_device *virt_dev; + int bw_index; + + virt_dev = xhci->devs[udev->slot_id]; + + if (udev->speed == USB_SPEED_SUPER) { + if (usb_endpoint_dir_out(&ep->desc)) + bw_index = (virt_dev->real_port - 1) * 2; + else + bw_index = (virt_dev->real_port - 1) * 2 + 1; + } else { + /* add one more for each SS port */ + bw_index = virt_dev->real_port + xhci->num_usb3_ports - 1; + } + + return bw_index; +} + +static void setup_sch_info(struct usb_device *udev, + struct xhci_ep_ctx *ep_ctx, struct mu3h_sch_ep_info *sch_ep) +{ + u32 ep_type; + u32 ep_interval; + u32 max_packet_size; + u32 max_burst; + u32 mult; + u32 esit_pkts; + + ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2)); + ep_interval = CTX_TO_EP_INTERVAL(le32_to_cpu(ep_ctx->ep_info)); + max_packet_size = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2)); + max_burst = CTX_TO_MAX_BURST(le32_to_cpu(ep_ctx->ep_info2)); + mult = CTX_TO_EP_MULT(le32_to_cpu(ep_ctx->ep_info)); + + sch_ep->esit = 1 << ep_interval; + sch_ep->offset = 0; + sch_ep->burst_mode = 0; + + if (udev->speed == USB_SPEED_HIGH) { + sch_ep->cs_count = 0; + + /* + * usb_20 spec section5.9 + * a single microframe is enough for HS synchromous endpoints + * in a interval + */ + sch_ep->num_budget_microframes = 1; + sch_ep->repeat = 0; + + /* + * xHCI spec section6.2.3.4 + * @max_burst is the number of additional transactions + * opportunities per microframe + */ + sch_ep->pkts = max_burst + 1; + sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts; + } else if (udev->speed == USB_SPEED_SUPER) { + /* usb3_r1 spec section4.4.7 & 4.4.8 */ + sch_ep->cs_count = 0; + esit_pkts = (mult + 1) * (max_burst + 1); + if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) { + sch_ep->pkts = esit_pkts; + sch_ep->num_budget_microframes = 1; + sch_ep->repeat = 0; + } + + if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) { + if (esit_pkts <= sch_ep->esit) + sch_ep->pkts = 1; + else + sch_ep->pkts = roundup_pow_of_two(esit_pkts) + / sch_ep->esit; + + sch_ep->num_budget_microframes = + DIV_ROUND_UP(esit_pkts, sch_ep->pkts); + + if (sch_ep->num_budget_microframes > 1) + sch_ep->repeat = 1; + else + sch_ep->repeat = 0; + } + sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts; + } else if (is_fs_or_ls(udev->speed)) { + + /* + * usb_20 spec section11.18.4 + * assume worst cases + */ + sch_ep->repeat = 0; + sch_ep->pkts = 1; /* at most one packet for each microframe */ + if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) { + sch_ep->cs_count = 3; /* at most need 3 CS*/ + /* one for SS and one for budgeted transaction */ + sch_ep->num_budget_microframes = sch_ep->cs_count + 2; + sch_ep->bw_cost_per_microframe = max_packet_size; + } + if (ep_type == ISOC_OUT_EP) { + + /* + * the best case FS budget assumes that 188 FS bytes + * occur in each microframe + */ + sch_ep->num_budget_microframes = DIV_ROUND_UP( + max_packet_size, FS_PAYLOAD_MAX); + sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX; + sch_ep->cs_count = sch_ep->num_budget_microframes; + } + if (ep_type == ISOC_IN_EP) { + /* at most need additional two CS. */ + sch_ep->cs_count = DIV_ROUND_UP( + max_packet_size, FS_PAYLOAD_MAX) + 2; + sch_ep->num_budget_microframes = sch_ep->cs_count + 2; + sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX; + } + } +} + +/* Get maximum bandwidth when we schedule at offset slot. */ +static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw, + struct mu3h_sch_ep_info *sch_ep, u32 offset) +{ + u32 num_esit; + u32 max_bw = 0; + int i; + int j; + + num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; + for (i = 0; i < num_esit; i++) { + u32 base = offset + i * sch_ep->esit; + + for (j = 0; j < sch_ep->num_budget_microframes; j++) { + if (sch_bw->bus_bw[base + j] > max_bw) + max_bw = sch_bw->bus_bw[base + j]; + } + } + return max_bw; +} + +static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw, + struct mu3h_sch_ep_info *sch_ep, int bw_cost) +{ + u32 num_esit; + u32 base; + int i; + int j; + + num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; + for (i = 0; i < num_esit; i++) { + base = sch_ep->offset + i * sch_ep->esit; + for (j = 0; j < sch_ep->num_budget_microframes; j++) + sch_bw->bus_bw[base + j] += bw_cost; + } +} + +static int check_sch_bw(struct usb_device *udev, + struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep) +{ + u32 offset; + u32 esit; + u32 num_budget_microframes; + u32 min_bw; + u32 min_index; + u32 worst_bw; + u32 bw_boundary; + + if (sch_ep->esit > XHCI_MTK_MAX_ESIT) + sch_ep->esit = XHCI_MTK_MAX_ESIT; + + esit = sch_ep->esit; + num_budget_microframes = sch_ep->num_budget_microframes; + + /* + * Search through all possible schedule microframes. + * and find a microframe where its worst bandwidth is minimum. + */ + min_bw = ~0; + min_index = 0; + for (offset = 0; offset < esit; offset++) { + if ((offset + num_budget_microframes) > sch_ep->esit) + break; + + /* + * usb_20 spec section11.18: + * must never schedule Start-Split in Y6 + */ + if (is_fs_or_ls(udev->speed) && (offset % 8 == 6)) + continue; + + worst_bw = get_max_bw(sch_bw, sch_ep, offset); + if (min_bw > worst_bw) { + min_bw = worst_bw; + min_index = offset; + } + if (min_bw == 0) + break; + } + sch_ep->offset = min_index; + + bw_boundary = (udev->speed == USB_SPEED_SUPER) + ? SS_BW_BOUNDARY : HS_BW_BOUNDARY; + + /* check bandwidth */ + if (min_bw + sch_ep->bw_cost_per_microframe > bw_boundary) + return -ERANGE; + + /* update bus bandwidth info */ + update_bus_bw(sch_bw, sch_ep, sch_ep->bw_cost_per_microframe); + + return 0; +} + +static bool need_bw_sch(struct usb_host_endpoint *ep, + enum usb_device_speed speed, int has_tt) +{ + /* only for periodic endpoints */ + if (usb_endpoint_xfer_control(&ep->desc) + || usb_endpoint_xfer_bulk(&ep->desc)) + return false; + + /* + * for LS & FS periodic endpoints which its device don't attach + * to TT are also ignored, root-hub will schedule them directly + */ + if (is_fs_or_ls(speed) && !has_tt) + return false; + + return true; +} + +int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk) +{ + struct mu3h_sch_bw_info *sch_array; + int num_usb_bus; + int i; + + /* ss IN and OUT are separated */ + num_usb_bus = mtk->num_u3_ports * 2 + mtk->num_u2_ports; + + sch_array = kcalloc(num_usb_bus, sizeof(*sch_array), GFP_KERNEL); + if (sch_array == NULL) + return -ENOMEM; + + for (i = 0; i < num_usb_bus; i++) + INIT_LIST_HEAD(&sch_array[i].bw_ep_list); + + mtk->sch_array = sch_array; + + return 0; +} +EXPORT_SYMBOL_GPL(xhci_mtk_sch_init); + +void xhci_mtk_sch_exit(struct xhci_hcd_mtk *mtk) +{ + kfree(mtk->sch_array); +} +EXPORT_SYMBOL_GPL(xhci_mtk_sch_exit); + +int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, + struct usb_host_endpoint *ep) +{ + struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); + struct xhci_hcd *xhci; + struct xhci_ep_ctx *ep_ctx; + struct xhci_slot_ctx *slot_ctx; + struct xhci_virt_device *virt_dev; + struct mu3h_sch_bw_info *sch_bw; + struct mu3h_sch_ep_info *sch_ep; + struct mu3h_sch_bw_info *sch_array; + unsigned int ep_index; + int bw_index; + int ret = 0; + + xhci = hcd_to_xhci(hcd); + virt_dev = xhci->devs[udev->slot_id]; + ep_index = xhci_get_endpoint_index(&ep->desc); + slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); + ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); + sch_array = mtk->sch_array; + + xhci_dbg(xhci, "%s() type:%d, speed:%d, mpkt:%d, dir:%d, ep:%p\n", + __func__, usb_endpoint_type(&ep->desc), udev->speed, + GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)), + usb_endpoint_dir_in(&ep->desc), ep); + + if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT)) + return 0; + + bw_index = get_bw_index(xhci, udev, ep); + sch_bw = &sch_array[bw_index]; + + sch_ep = kzalloc(sizeof(struct mu3h_sch_ep_info), GFP_NOIO); + if (!sch_ep) + return -ENOMEM; + + setup_sch_info(udev, ep_ctx, sch_ep); + + ret = check_sch_bw(udev, sch_bw, sch_ep); + if (ret) { + xhci_err(xhci, "Not enough bandwidth!\n"); + kfree(sch_ep); + return -ENOSPC; + } + + list_add_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list); + sch_ep->ep = ep; + + ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts) + | EP_BCSCOUNT(sch_ep->cs_count) | EP_BBM(sch_ep->burst_mode)); + ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset) + | EP_BREPEAT(sch_ep->repeat)); + + xhci_dbg(xhci, " PKTS:%x, CSCOUNT:%x, BM:%x, OFFSET:%x, REPEAT:%x\n", + sch_ep->pkts, sch_ep->cs_count, sch_ep->burst_mode, + sch_ep->offset, sch_ep->repeat); + + return 0; +} +EXPORT_SYMBOL_GPL(xhci_mtk_add_ep_quirk); + +void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, + struct usb_host_endpoint *ep) +{ + struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); + struct xhci_hcd *xhci; + struct xhci_slot_ctx *slot_ctx; + struct xhci_virt_device *virt_dev; + struct mu3h_sch_bw_info *sch_array; + struct mu3h_sch_bw_info *sch_bw; + struct mu3h_sch_ep_info *sch_ep; + int bw_index; + + xhci = hcd_to_xhci(hcd); + virt_dev = xhci->devs[udev->slot_id]; + slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); + sch_array = mtk->sch_array; + + xhci_dbg(xhci, "%s() type:%d, speed:%d, mpks:%d, dir:%d, ep:%p\n", + __func__, usb_endpoint_type(&ep->desc), udev->speed, + GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)), + usb_endpoint_dir_in(&ep->desc), ep); + + if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT)) + return; + + bw_index = get_bw_index(xhci, udev, ep); + sch_bw = &sch_array[bw_index]; + + list_for_each_entry(sch_ep, &sch_bw->bw_ep_list, endpoint) { + if (sch_ep->ep == ep) { + update_bus_bw(sch_bw, sch_ep, + -sch_ep->bw_cost_per_microframe); + list_del(&sch_ep->endpoint); + kfree(sch_ep); + break; + } + } +} +EXPORT_SYMBOL_GPL(xhci_mtk_drop_ep_quirk); diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c new file mode 100644 index 0000000000000..c9ab6a44c34ae --- /dev/null +++ b/drivers/usb/host/xhci-mtk.c @@ -0,0 +1,763 @@ +/* + * MediaTek xHCI Host Controller Driver + * + * Copyright (c) 2015 MediaTek Inc. + * Author: + * Chunfeng Yun + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xhci.h" +#include "xhci-mtk.h" + +/* ip_pw_ctrl0 register */ +#define CTRL0_IP_SW_RST BIT(0) + +/* ip_pw_ctrl1 register */ +#define CTRL1_IP_HOST_PDN BIT(0) + +/* ip_pw_ctrl2 register */ +#define CTRL2_IP_DEV_PDN BIT(0) + +/* ip_pw_sts1 register */ +#define STS1_IP_SLEEP_STS BIT(30) +#define STS1_XHCI_RST BIT(11) +#define STS1_SYS125_RST BIT(10) +#define STS1_REF_RST BIT(8) +#define STS1_SYSPLL_STABLE BIT(0) + +/* ip_xhci_cap register */ +#define CAP_U3_PORT_NUM(p) ((p) & 0xff) +#define CAP_U2_PORT_NUM(p) (((p) >> 8) & 0xff) + +/* u3_ctrl_p register */ +#define CTRL_U3_PORT_HOST_SEL BIT(2) +#define CTRL_U3_PORT_PDN BIT(1) +#define CTRL_U3_PORT_DIS BIT(0) + +/* u2_ctrl_p register */ +#define CTRL_U2_PORT_HOST_SEL BIT(2) +#define CTRL_U2_PORT_PDN BIT(1) +#define CTRL_U2_PORT_DIS BIT(0) + +/* u2_phy_pll register */ +#define CTRL_U2_FORCE_PLL_STB BIT(28) + +#define PERI_WK_CTRL0 0x400 +#define UWK_CTR0_0P_LS_PE BIT(8) /* posedge */ +#define UWK_CTR0_0P_LS_NE BIT(7) /* negedge for 0p linestate*/ +#define UWK_CTL1_1P_LS_C(x) (((x) & 0xf) << 1) +#define UWK_CTL1_1P_LS_E BIT(0) + +#define PERI_WK_CTRL1 0x404 +#define UWK_CTL1_IS_C(x) (((x) & 0xf) << 26) +#define UWK_CTL1_IS_E BIT(25) +#define UWK_CTL1_0P_LS_C(x) (((x) & 0xf) << 21) +#define UWK_CTL1_0P_LS_E BIT(20) +#define UWK_CTL1_IDDIG_C(x) (((x) & 0xf) << 11) /* cycle debounce */ +#define UWK_CTL1_IDDIG_E BIT(10) /* enable debounce */ +#define UWK_CTL1_IDDIG_P BIT(9) /* polarity */ +#define UWK_CTL1_0P_LS_P BIT(7) +#define UWK_CTL1_IS_P BIT(6) /* polarity for ip sleep */ + +enum ssusb_wakeup_src { + SSUSB_WK_IP_SLEEP = 1, + SSUSB_WK_LINE_STATE = 2, +}; + +static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk) +{ + struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs; + u32 value, check_val; + int ret; + int i; + + /* power on host ip */ + value = readl(&ippc->ip_pw_ctr1); + value &= ~CTRL1_IP_HOST_PDN; + writel(value, &ippc->ip_pw_ctr1); + + /* power on and enable all u3 ports */ + for (i = 0; i < mtk->num_u3_ports; i++) { + value = readl(&ippc->u3_ctrl_p[i]); + value &= ~(CTRL_U3_PORT_PDN | CTRL_U3_PORT_DIS); + value |= CTRL_U3_PORT_HOST_SEL; + writel(value, &ippc->u3_ctrl_p[i]); + } + + /* power on and enable all u2 ports */ + for (i = 0; i < mtk->num_u2_ports; i++) { + value = readl(&ippc->u2_ctrl_p[i]); + value &= ~(CTRL_U2_PORT_PDN | CTRL_U2_PORT_DIS); + value |= CTRL_U2_PORT_HOST_SEL; + writel(value, &ippc->u2_ctrl_p[i]); + } + + /* + * wait for clocks to be stable, and clock domains reset to + * be inactive after power on and enable ports + */ + check_val = STS1_SYSPLL_STABLE | STS1_REF_RST | + STS1_SYS125_RST | STS1_XHCI_RST; + + ret = readl_poll_timeout(&ippc->ip_pw_sts1, value, + (check_val == (value & check_val)), 100, 20000); + if (ret) { + dev_err(mtk->dev, "clocks are not stable (0x%x)\n", value); + return ret; + } + + return 0; +} + +static int xhci_mtk_host_disable(struct xhci_hcd_mtk *mtk) +{ + struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs; + u32 value; + int ret; + int i; + + /* power down all u3 ports */ + for (i = 0; i < mtk->num_u3_ports; i++) { + value = readl(&ippc->u3_ctrl_p[i]); + value |= CTRL_U3_PORT_PDN; + writel(value, &ippc->u3_ctrl_p[i]); + } + + /* power down all u2 ports */ + for (i = 0; i < mtk->num_u2_ports; i++) { + value = readl(&ippc->u2_ctrl_p[i]); + value |= CTRL_U2_PORT_PDN; + writel(value, &ippc->u2_ctrl_p[i]); + } + + /* power down host ip */ + value = readl(&ippc->ip_pw_ctr1); + value |= CTRL1_IP_HOST_PDN; + writel(value, &ippc->ip_pw_ctr1); + + /* wait for host ip to sleep */ + ret = readl_poll_timeout(&ippc->ip_pw_sts1, value, + (value & STS1_IP_SLEEP_STS), 100, 100000); + if (ret) { + dev_err(mtk->dev, "ip sleep failed!!!\n"); + return ret; + } + return 0; +} + +static int xhci_mtk_ssusb_config(struct xhci_hcd_mtk *mtk) +{ + struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs; + u32 value; + + /* reset whole ip */ + value = readl(&ippc->ip_pw_ctr0); + value |= CTRL0_IP_SW_RST; + writel(value, &ippc->ip_pw_ctr0); + udelay(1); + value = readl(&ippc->ip_pw_ctr0); + value &= ~CTRL0_IP_SW_RST; + writel(value, &ippc->ip_pw_ctr0); + + /* + * device ip is default power-on in fact + * power down device ip, otherwise ip-sleep will fail + */ + value = readl(&ippc->ip_pw_ctr2); + value |= CTRL2_IP_DEV_PDN; + writel(value, &ippc->ip_pw_ctr2); + + value = readl(&ippc->ip_xhci_cap); + mtk->num_u3_ports = CAP_U3_PORT_NUM(value); + mtk->num_u2_ports = CAP_U2_PORT_NUM(value); + dev_dbg(mtk->dev, "%s u2p:%d, u3p:%d\n", __func__, + mtk->num_u2_ports, mtk->num_u3_ports); + + return xhci_mtk_host_enable(mtk); +} + +static int xhci_mtk_clks_enable(struct xhci_hcd_mtk *mtk) +{ + int ret; + + ret = clk_prepare_enable(mtk->sys_clk); + if (ret) { + dev_err(mtk->dev, "failed to enable sys_clk\n"); + goto sys_clk_err; + } + + if (mtk->wakeup_src) { + ret = clk_prepare_enable(mtk->wk_deb_p0); + if (ret) { + dev_err(mtk->dev, "failed to enable wk_deb_p0\n"); + goto usb_p0_err; + } + + ret = clk_prepare_enable(mtk->wk_deb_p1); + if (ret) { + dev_err(mtk->dev, "failed to enable wk_deb_p1\n"); + goto usb_p1_err; + } + } + return 0; + +usb_p1_err: + clk_disable_unprepare(mtk->wk_deb_p0); +usb_p0_err: + clk_disable_unprepare(mtk->sys_clk); +sys_clk_err: + return -EINVAL; +} + +static void xhci_mtk_clks_disable(struct xhci_hcd_mtk *mtk) +{ + if (mtk->wakeup_src) { + clk_disable_unprepare(mtk->wk_deb_p1); + clk_disable_unprepare(mtk->wk_deb_p0); + } + clk_disable_unprepare(mtk->sys_clk); +} + +/* only clocks can be turn off for ip-sleep wakeup mode */ +static void usb_wakeup_ip_sleep_en(struct xhci_hcd_mtk *mtk) +{ + u32 tmp; + struct regmap *pericfg = mtk->pericfg; + + regmap_read(pericfg, PERI_WK_CTRL1, &tmp); + tmp &= ~UWK_CTL1_IS_P; + tmp &= ~(UWK_CTL1_IS_C(0xf)); + tmp |= UWK_CTL1_IS_C(0x8); + regmap_write(pericfg, PERI_WK_CTRL1, tmp); + regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_IS_E); + + regmap_read(pericfg, PERI_WK_CTRL1, &tmp); + dev_dbg(mtk->dev, "%s(): WK_CTRL1[P6,E25,C26:29]=%#x\n", + __func__, tmp); +} + +static void usb_wakeup_ip_sleep_dis(struct xhci_hcd_mtk *mtk) +{ + u32 tmp; + + regmap_read(mtk->pericfg, PERI_WK_CTRL1, &tmp); + tmp &= ~UWK_CTL1_IS_E; + regmap_write(mtk->pericfg, PERI_WK_CTRL1, tmp); +} + +/* +* for line-state wakeup mode, phy's power should not power-down +* and only support cable plug in/out +*/ +static void usb_wakeup_line_state_en(struct xhci_hcd_mtk *mtk) +{ + u32 tmp; + struct regmap *pericfg = mtk->pericfg; + + /* line-state of u2-port0 */ + regmap_read(pericfg, PERI_WK_CTRL1, &tmp); + tmp &= ~UWK_CTL1_0P_LS_P; + tmp &= ~(UWK_CTL1_0P_LS_C(0xf)); + tmp |= UWK_CTL1_0P_LS_C(0x8); + regmap_write(pericfg, PERI_WK_CTRL1, tmp); + regmap_read(pericfg, PERI_WK_CTRL1, &tmp); + regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_0P_LS_E); + + /* line-state of u2-port1 */ + regmap_read(pericfg, PERI_WK_CTRL0, &tmp); + tmp &= ~(UWK_CTL1_1P_LS_C(0xf)); + tmp |= UWK_CTL1_1P_LS_C(0x8); + regmap_write(pericfg, PERI_WK_CTRL0, tmp); + regmap_write(pericfg, PERI_WK_CTRL0, tmp | UWK_CTL1_1P_LS_E); +} + +static void usb_wakeup_line_state_dis(struct xhci_hcd_mtk *mtk) +{ + u32 tmp; + struct regmap *pericfg = mtk->pericfg; + + /* line-state of u2-port0 */ + regmap_read(pericfg, PERI_WK_CTRL1, &tmp); + tmp &= ~UWK_CTL1_0P_LS_E; + regmap_write(pericfg, PERI_WK_CTRL1, tmp); + + /* line-state of u2-port1 */ + regmap_read(pericfg, PERI_WK_CTRL0, &tmp); + tmp &= ~UWK_CTL1_1P_LS_E; + regmap_write(pericfg, PERI_WK_CTRL0, tmp); +} + +static void usb_wakeup_enable(struct xhci_hcd_mtk *mtk) +{ + if (mtk->wakeup_src == SSUSB_WK_IP_SLEEP) + usb_wakeup_ip_sleep_en(mtk); + else if (mtk->wakeup_src == SSUSB_WK_LINE_STATE) + usb_wakeup_line_state_en(mtk); +} + +static void usb_wakeup_disable(struct xhci_hcd_mtk *mtk) +{ + if (mtk->wakeup_src == SSUSB_WK_IP_SLEEP) + usb_wakeup_ip_sleep_dis(mtk); + else if (mtk->wakeup_src == SSUSB_WK_LINE_STATE) + usb_wakeup_line_state_dis(mtk); +} + +static int usb_wakeup_of_property_parse(struct xhci_hcd_mtk *mtk, + struct device_node *dn) +{ + struct device *dev = mtk->dev; + + /* + * wakeup function is optional, so it is not an error if this property + * does not exist, and in such case, no need to get relative + * properties anymore. + */ + of_property_read_u32(dn, "mediatek,wakeup-src", &mtk->wakeup_src); + if (!mtk->wakeup_src) + return 0; + + mtk->wk_deb_p0 = devm_clk_get(dev, "wakeup_deb_p0"); + if (IS_ERR(mtk->wk_deb_p0)) { + dev_err(dev, "fail to get wakeup_deb_p0\n"); + return PTR_ERR(mtk->wk_deb_p0); + } + + mtk->wk_deb_p1 = devm_clk_get(dev, "wakeup_deb_p1"); + if (IS_ERR(mtk->wk_deb_p1)) { + dev_err(dev, "fail to get wakeup_deb_p1\n"); + return PTR_ERR(mtk->wk_deb_p1); + } + + mtk->pericfg = syscon_regmap_lookup_by_phandle(dn, + "mediatek,syscon-wakeup"); + if (IS_ERR(mtk->pericfg)) { + dev_err(dev, "fail to get pericfg regs\n"); + return PTR_ERR(mtk->pericfg); + } + + return 0; +} + +static int xhci_mtk_setup(struct usb_hcd *hcd); +static const struct xhci_driver_overrides xhci_mtk_overrides __initconst = { + .extra_priv_size = sizeof(struct xhci_hcd), + .reset = xhci_mtk_setup, +}; + +static struct hc_driver __read_mostly xhci_mtk_hc_driver; + +static int xhci_mtk_phy_init(struct xhci_hcd_mtk *mtk) +{ + int i; + int ret; + + for (i = 0; i < mtk->num_phys; i++) { + ret = phy_init(mtk->phys[i]); + if (ret) + goto exit_phy; + } + return 0; + +exit_phy: + for (; i > 0; i--) + phy_exit(mtk->phys[i - 1]); + + return ret; +} + +static int xhci_mtk_phy_exit(struct xhci_hcd_mtk *mtk) +{ + int i; + + for (i = 0; i < mtk->num_phys; i++) + phy_exit(mtk->phys[i]); + + return 0; +} + +static int xhci_mtk_phy_power_on(struct xhci_hcd_mtk *mtk) +{ + int i; + int ret; + + for (i = 0; i < mtk->num_phys; i++) { + ret = phy_power_on(mtk->phys[i]); + if (ret) + goto power_off_phy; + } + return 0; + +power_off_phy: + for (; i > 0; i--) + phy_power_off(mtk->phys[i - 1]); + + return ret; +} + +static void xhci_mtk_phy_power_off(struct xhci_hcd_mtk *mtk) +{ + unsigned int i; + + for (i = 0; i < mtk->num_phys; i++) + phy_power_off(mtk->phys[i]); +} + +static int xhci_mtk_ldos_enable(struct xhci_hcd_mtk *mtk) +{ + int ret; + + ret = regulator_enable(mtk->vbus); + if (ret) { + dev_err(mtk->dev, "failed to enable vbus\n"); + return ret; + } + + ret = regulator_enable(mtk->vusb33); + if (ret) { + dev_err(mtk->dev, "failed to enable vusb33\n"); + regulator_disable(mtk->vbus); + return ret; + } + return 0; +} + +static void xhci_mtk_ldos_disable(struct xhci_hcd_mtk *mtk) +{ + regulator_disable(mtk->vbus); + regulator_disable(mtk->vusb33); +} + +static void xhci_mtk_quirks(struct device *dev, struct xhci_hcd *xhci) +{ + struct usb_hcd *hcd = xhci_to_hcd(xhci); + struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); + + /* + * As of now platform drivers don't provide MSI support so we ensure + * here that the generic code does not try to make a pci_dev from our + * dev struct in order to setup MSI + */ + xhci->quirks |= XHCI_PLAT; + xhci->quirks |= XHCI_MTK_HOST; + /* + * MTK host controller gives a spurious successful event after a + * short transfer. Ignore it. + */ + xhci->quirks |= XHCI_SPURIOUS_SUCCESS; + if (mtk->lpm_support) + xhci->quirks |= XHCI_LPM_SUPPORT; +} + +/* called during probe() after chip reset completes */ +static int xhci_mtk_setup(struct usb_hcd *hcd) +{ + struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); + int ret; + + if (usb_hcd_is_primary_hcd(hcd)) { + ret = xhci_mtk_ssusb_config(mtk); + if (ret) + return ret; + ret = xhci_mtk_sch_init(mtk); + if (ret) + return ret; + } + + return xhci_gen_setup(hcd, xhci_mtk_quirks); +} + +static int xhci_mtk_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct xhci_hcd_mtk *mtk; + const struct hc_driver *driver; + struct xhci_hcd *xhci; + struct resource *res; + struct usb_hcd *hcd; + struct phy *phy; + int phy_num; + int ret = -ENODEV; + int irq; + + if (usb_disabled()) + return -ENODEV; + + driver = &xhci_mtk_hc_driver; + mtk = devm_kzalloc(dev, sizeof(*mtk), GFP_KERNEL); + if (!mtk) + return -ENOMEM; + + mtk->dev = dev; + mtk->vbus = devm_regulator_get(dev, "vbus"); + if (IS_ERR(mtk->vbus)) { + dev_err(dev, "fail to get vbus\n"); + return PTR_ERR(mtk->vbus); + } + + mtk->vusb33 = devm_regulator_get(dev, "vusb33"); + if (IS_ERR(mtk->vusb33)) { + dev_err(dev, "fail to get vusb33\n"); + return PTR_ERR(mtk->vusb33); + } + + mtk->sys_clk = devm_clk_get(dev, "sys_ck"); + if (IS_ERR(mtk->sys_clk)) { + dev_err(dev, "fail to get sys_ck\n"); + return PTR_ERR(mtk->sys_clk); + } + + mtk->lpm_support = of_property_read_bool(node, "usb3-lpm-capable"); + + ret = usb_wakeup_of_property_parse(mtk, node); + if (ret) + return ret; + + mtk->num_phys = of_count_phandle_with_args(node, + "phys", "#phy-cells"); + if (mtk->num_phys > 0) { + mtk->phys = devm_kcalloc(dev, mtk->num_phys, + sizeof(*mtk->phys), GFP_KERNEL); + if (!mtk->phys) + return -ENOMEM; + } else { + mtk->num_phys = 0; + } + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); + device_enable_async_suspend(dev); + + ret = xhci_mtk_ldos_enable(mtk); + if (ret) + goto disable_pm; + + ret = xhci_mtk_clks_enable(mtk); + if (ret) + goto disable_ldos; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + goto disable_clk; + + /* Initialize dma_mask and coherent_dma_mask to 32-bits */ + ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); + if (ret) + goto disable_clk; + + if (!dev->dma_mask) + dev->dma_mask = &dev->coherent_dma_mask; + else + dma_set_mask(dev, DMA_BIT_MASK(32)); + + hcd = usb_create_hcd(driver, dev, dev_name(dev)); + if (!hcd) { + ret = -ENOMEM; + goto disable_clk; + } + + /* + * USB 2.0 roothub is stored in the platform_device. + * Swap it with mtk HCD. + */ + mtk->hcd = platform_get_drvdata(pdev); + platform_set_drvdata(pdev, mtk); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + hcd->regs = devm_ioremap_resource(dev, res); + if (IS_ERR(hcd->regs)) { + ret = PTR_ERR(hcd->regs); + goto put_usb2_hcd; + } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + mtk->ippc_regs = devm_ioremap_resource(dev, res); + if (IS_ERR(mtk->ippc_regs)) { + ret = PTR_ERR(mtk->ippc_regs); + goto put_usb2_hcd; + } + + for (phy_num = 0; phy_num < mtk->num_phys; phy_num++) { + phy = devm_of_phy_get_by_index(dev, node, phy_num); + if (IS_ERR(phy)) { + ret = PTR_ERR(phy); + goto put_usb2_hcd; + } + mtk->phys[phy_num] = phy; + } + + ret = xhci_mtk_phy_init(mtk); + if (ret) + goto put_usb2_hcd; + + ret = xhci_mtk_phy_power_on(mtk); + if (ret) + goto exit_phys; + + device_init_wakeup(dev, true); + + xhci = hcd_to_xhci(hcd); + xhci->main_hcd = hcd; + xhci->shared_hcd = usb_create_shared_hcd(driver, dev, + dev_name(dev), hcd); + if (!xhci->shared_hcd) { + ret = -ENOMEM; + goto power_off_phys; + } + + if (HCC_MAX_PSA(xhci->hcc_params) >= 4) + xhci->shared_hcd->can_do_streams = 1; + + ret = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (ret) + goto put_usb3_hcd; + + ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); + if (ret) + goto dealloc_usb2_hcd; + + return 0; + +dealloc_usb2_hcd: + usb_remove_hcd(hcd); + +put_usb3_hcd: + xhci_mtk_sch_exit(mtk); + usb_put_hcd(xhci->shared_hcd); + +power_off_phys: + xhci_mtk_phy_power_off(mtk); + device_init_wakeup(dev, false); + +exit_phys: + xhci_mtk_phy_exit(mtk); + +put_usb2_hcd: + usb_put_hcd(hcd); + +disable_clk: + xhci_mtk_clks_disable(mtk); + +disable_ldos: + xhci_mtk_ldos_disable(mtk); + +disable_pm: + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); + return ret; +} + +static int xhci_mtk_remove(struct platform_device *dev) +{ + struct xhci_hcd_mtk *mtk = platform_get_drvdata(dev); + struct usb_hcd *hcd = mtk->hcd; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + usb_remove_hcd(xhci->shared_hcd); + xhci_mtk_phy_power_off(mtk); + xhci_mtk_phy_exit(mtk); + device_init_wakeup(&dev->dev, false); + + usb_remove_hcd(hcd); + usb_put_hcd(xhci->shared_hcd); + usb_put_hcd(hcd); + xhci_mtk_sch_exit(mtk); + xhci_mtk_clks_disable(mtk); + xhci_mtk_ldos_disable(mtk); + pm_runtime_put_sync(&dev->dev); + pm_runtime_disable(&dev->dev); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int xhci_mtk_suspend(struct device *dev) +{ + struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); + + xhci_mtk_host_disable(mtk); + xhci_mtk_phy_power_off(mtk); + xhci_mtk_clks_disable(mtk); + usb_wakeup_enable(mtk); + return 0; +} + +static int xhci_mtk_resume(struct device *dev) +{ + struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); + + usb_wakeup_disable(mtk); + xhci_mtk_clks_enable(mtk); + xhci_mtk_phy_power_on(mtk); + xhci_mtk_host_enable(mtk); + return 0; +} + +static const struct dev_pm_ops xhci_mtk_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(xhci_mtk_suspend, xhci_mtk_resume) +}; +#define DEV_PM_OPS (&xhci_mtk_pm_ops) +#else +#define DEV_PM_OPS NULL +#endif /* CONFIG_PM */ + +#ifdef CONFIG_OF +static const struct of_device_id mtk_xhci_of_match[] = { + { .compatible = "mediatek,mt8173-xhci"}, + { }, +}; +MODULE_DEVICE_TABLE(of, mtk_xhci_of_match); +#endif + +static struct platform_driver mtk_xhci_driver = { + .probe = xhci_mtk_probe, + .remove = xhci_mtk_remove, + .driver = { + .name = "xhci-mtk", + .pm = DEV_PM_OPS, + .of_match_table = of_match_ptr(mtk_xhci_of_match), + }, +}; +MODULE_ALIAS("platform:xhci-mtk"); + +static int __init xhci_mtk_init(void) +{ + xhci_init_driver(&xhci_mtk_hc_driver, &xhci_mtk_overrides); + return platform_driver_register(&mtk_xhci_driver); +} +module_init(xhci_mtk_init); + +static void __exit xhci_mtk_exit(void) +{ + platform_driver_unregister(&mtk_xhci_driver); +} +module_exit(xhci_mtk_exit); + +MODULE_AUTHOR("Chunfeng Yun "); +MODULE_DESCRIPTION("MediaTek xHCI Host Controller Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h new file mode 100644 index 0000000000000..7da677c79ea85 --- /dev/null +++ b/drivers/usb/host/xhci-mtk.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2015 MediaTek Inc. + * Author: + * Zhigang.Wei + * Chunfeng.Yun + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _XHCI_MTK_H_ +#define _XHCI_MTK_H_ + +#include "xhci.h" + +/** + * To simplify scheduler algorithm, set a upper limit for ESIT, + * if a synchromous ep's ESIT is larger than @XHCI_MTK_MAX_ESIT, + * round down to the limit value, that means allocating more + * bandwidth to it. + */ +#define XHCI_MTK_MAX_ESIT 64 + +/** + * struct mu3h_sch_bw_info: schedule information for bandwidth domain + * + * @bus_bw: array to keep track of bandwidth already used at each uframes + * @bw_ep_list: eps in the bandwidth domain + * + * treat a HS root port as a bandwidth domain, but treat a SS root port as + * two bandwidth domains, one for IN eps and another for OUT eps. + */ +struct mu3h_sch_bw_info { + u32 bus_bw[XHCI_MTK_MAX_ESIT]; + struct list_head bw_ep_list; +}; + +/** + * struct mu3h_sch_ep_info: schedule information for endpoint + * + * @esit: unit is 125us, equal to 2 << Interval field in ep-context + * @num_budget_microframes: number of continuous uframes + * (@repeat==1) scheduled within the interval + * @bw_cost_per_microframe: bandwidth cost per microframe + * @endpoint: linked into bandwidth domain which it belongs to + * @ep: address of usb_host_endpoint struct + * @offset: which uframe of the interval that transfer should be + * scheduled first time within the interval + * @repeat: the time gap between two uframes that transfers are + * scheduled within a interval. in the simple algorithm, only + * assign 0 or 1 to it; 0 means using only one uframe in a + * interval, and 1 means using @num_budget_microframes + * continuous uframes + * @pkts: number of packets to be transferred in the scheduled uframes + * @cs_count: number of CS that host will trigger + * @burst_mode: burst mode for scheduling. 0: normal burst mode, + * distribute the bMaxBurst+1 packets for a single burst + * according to @pkts and @repeat, repeate the burst multiple + * times; 1: distribute the (bMaxBurst+1)*(Mult+1) packets + * according to @pkts and @repeat. normal mode is used by + * default + */ +struct mu3h_sch_ep_info { + u32 esit; + u32 num_budget_microframes; + u32 bw_cost_per_microframe; + struct list_head endpoint; + void *ep; + /* + * mtk xHCI scheduling information put into reserved DWs + * in ep context + */ + u32 offset; + u32 repeat; + u32 pkts; + u32 cs_count; + u32 burst_mode; +}; + +#define MU3C_U3_PORT_MAX 4 +#define MU3C_U2_PORT_MAX 5 + +/** + * struct mu3c_ippc_regs: MTK ssusb ip port control registers + * @ip_pw_ctr0~3: ip power and clock control registers + * @ip_pw_sts1~2: ip power and clock status registers + * @ip_xhci_cap: ip xHCI capability register + * @u3_ctrl_p[x]: ip usb3 port x control register, only low 4bytes are used + * @u2_ctrl_p[x]: ip usb2 port x control register, only low 4bytes are used + * @u2_phy_pll: usb2 phy pll control register + */ +struct mu3c_ippc_regs { + __le32 ip_pw_ctr0; + __le32 ip_pw_ctr1; + __le32 ip_pw_ctr2; + __le32 ip_pw_ctr3; + __le32 ip_pw_sts1; + __le32 ip_pw_sts2; + __le32 reserved0[3]; + __le32 ip_xhci_cap; + __le32 reserved1[2]; + __le64 u3_ctrl_p[MU3C_U3_PORT_MAX]; + __le64 u2_ctrl_p[MU3C_U2_PORT_MAX]; + __le32 reserved2; + __le32 u2_phy_pll; + __le32 reserved3[33]; /* 0x80 ~ 0xff */ +}; + +struct xhci_hcd_mtk { + struct device *dev; + struct usb_hcd *hcd; + struct mu3h_sch_bw_info *sch_array; + struct mu3c_ippc_regs __iomem *ippc_regs; + int num_u2_ports; + int num_u3_ports; + struct regulator *vusb33; + struct regulator *vbus; + struct clk *sys_clk; /* sys and mac clock */ + struct clk *wk_deb_p0; /* port0's wakeup debounce clock */ + struct clk *wk_deb_p1; + struct regmap *pericfg; + struct phy **phys; + int num_phys; + int wakeup_src; + bool lpm_support; +}; + +static inline struct xhci_hcd_mtk *hcd_to_mtk(struct usb_hcd *hcd) +{ + return dev_get_drvdata(hcd->self.controller); +} + +#if IS_ENABLED(CONFIG_USB_XHCI_MTK) +int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk); +void xhci_mtk_sch_exit(struct xhci_hcd_mtk *mtk); +int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, + struct usb_host_endpoint *ep); +void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, + struct usb_host_endpoint *ep); + +#else +static inline int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, + struct usb_device *udev, struct usb_host_endpoint *ep) +{ + return 0; +} + +static inline void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, + struct usb_device *udev, struct usb_host_endpoint *ep) +{ +} + +#endif + +#endif /* _XHCI_MTK_H_ */ diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 6c5e8133cf87c..8fab75863f1a6 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -68,6 +68,7 @@ #include #include "xhci.h" #include "xhci-trace.h" +#include "xhci-mtk.h" /* * Returns zero if the TRB isn't in this segment, otherwise it returns the DMA @@ -3074,17 +3075,22 @@ static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred, { u32 maxp, total_packet_count; - if (xhci->hci_version < 0x100) + /* MTK xHCI is mostly 0.97 but contains some features from 1.0 */ + if (xhci->hci_version < 0x100 && !(xhci->quirks & XHCI_MTK_HOST)) return ((td_total_len - transferred) >> 10); - maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc)); - total_packet_count = DIV_ROUND_UP(td_total_len, maxp); - /* One TRB with a zero-length data packet. */ if (num_trbs_left == 0 || (transferred == 0 && trb_buff_len == 0) || trb_buff_len == td_total_len) return 0; + /* for MTK xHCI, TD size doesn't include this TRB */ + if (xhci->quirks & XHCI_MTK_HOST) + trb_buff_len = 0; + + maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc)); + total_packet_count = DIV_ROUND_UP(td_total_len, maxp); + /* Queueing functions don't count the current TRB into transferred */ return (total_packet_count - ((transferred + trb_buff_len) / maxp)); } @@ -3472,7 +3478,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, field |= 0x1; /* xHCI 1.0/1.1 6.4.1.2.1: Transfer Type field */ - if (xhci->hci_version >= 0x100) { + if ((xhci->hci_version >= 0x100) || (xhci->quirks & XHCI_MTK_HOST)) { if (urb->transfer_buffer_length > 0) { if (setup->bRequestType & USB_DIR_IN) field |= TRB_TX_TYPE(TRB_DATA_IN); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ac25e9037e88b..887f308376f60 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -31,6 +31,7 @@ #include "xhci.h" #include "xhci-trace.h" +#include "xhci-mtk.h" #define DRIVER_AUTHOR "Sarah Sharp" #define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver" @@ -634,7 +635,11 @@ int xhci_run(struct usb_hcd *hcd) "// Set the interrupt modulation register"); temp = readl(&xhci->ir_set->irq_control); temp &= ~ER_IRQ_INTERVAL_MASK; - temp |= (u32) 160; + /* + * the increment interval is 8 times as much as that defined + * in xHCI spec on MTK's controller + */ + temp |= (u32) ((xhci->quirks & XHCI_MTK_HOST) ? 20 : 160); writel(temp, &xhci->ir_set->irq_control); /* Set the HCD state before we enable the irqs */ @@ -1698,6 +1703,9 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep); + if (xhci->quirks & XHCI_MTK_HOST) + xhci_mtk_drop_ep_quirk(hcd, udev, ep); + xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x\n", (unsigned int) ep->desc.bEndpointAddress, udev->slot_id, @@ -1793,6 +1801,15 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, return -ENOMEM; } + if (xhci->quirks & XHCI_MTK_HOST) { + ret = xhci_mtk_add_ep_quirk(hcd, udev, ep); + if (ret < 0) { + xhci_free_or_cache_endpoint_ring(xhci, + virt_dev, ep_index); + return ret; + } + } + ctrl_ctx->add_flags |= cpu_to_le32(added_ctxs); new_add_flags = le32_to_cpu(ctrl_ctx->add_flags); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 8b46296503283..9be7348872baa 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1630,6 +1630,7 @@ struct xhci_hcd { /* For controllers with a broken beyond repair streams implementation */ #define XHCI_BROKEN_STREAMS (1 << 19) #define XHCI_PME_STUCK_QUIRK (1 << 20) +#define XHCI_MTK_HOST (1 << 21) unsigned int num_active_eps; unsigned int limit_active_eps; /* There are two roothubs to keep track of bus suspend info for */ -- GitLab From bfcce47af567983a35f9689f392b68ae40229aea Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Tue, 24 Nov 2015 13:09:56 +0200 Subject: [PATCH 0812/2855] arm64: dts: mediatek: add xHCI & usb phy for mt8173 add xHCI and phy drivers for MT8173-EVB Signed-off-by: Chunfeng Yun Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 16 ++++++++ arch/arm64/boot/dts/mediatek/mt8173.dtsi | 42 +++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts index 811cb760ba49d..9b1482a1d0073 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts +++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts @@ -13,6 +13,7 @@ */ /dts-v1/; +#include #include "mt8173.dtsi" / { @@ -32,6 +33,15 @@ }; chosen { }; + + usb_p1_vbus: regulator@0 { + compatible = "regulator-fixed"; + regulator-name = "usb_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&pio 130 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; }; &i2c1 { @@ -408,3 +418,9 @@ &uart0 { status = "okay"; }; + +&usb30 { + vusb33-supply = <&mt6397_vusb_reg>; + vbus-supply = <&usb_p1_vbus>; + mediatek,wakeup-src = <1>; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index 4dd5f93d0303f..c1fd2757f8e44 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include "mt8173-pinfunc.h" @@ -510,6 +511,47 @@ status = "disabled"; }; + usb30: usb@11270000 { + compatible = "mediatek,mt8173-xhci"; + reg = <0 0x11270000 0 0x1000>, + <0 0x11280700 0 0x0100>; + interrupts = ; + power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>; + clocks = <&topckgen CLK_TOP_USB30_SEL>, + <&pericfg CLK_PERI_USB0>, + <&pericfg CLK_PERI_USB1>; + clock-names = "sys_ck", + "wakeup_deb_p0", + "wakeup_deb_p1"; + phys = <&phy_port0 PHY_TYPE_USB3>, + <&phy_port1 PHY_TYPE_USB2>; + mediatek,syscon-wakeup = <&pericfg>; + status = "okay"; + }; + + u3phy: usb-phy@11290000 { + compatible = "mediatek,mt8173-u3phy"; + reg = <0 0x11290000 0 0x800>; + clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>; + clock-names = "u3phya_ref"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + status = "okay"; + + phy_port0: port@11290800 { + reg = <0 0x11290800 0 0x800>; + #phy-cells = <1>; + status = "okay"; + }; + + phy_port1: port@11291000 { + reg = <0 0x11291000 0 0x800>; + #phy-cells = <1>; + status = "okay"; + }; + }; + mmsys: clock-controller@14000000 { compatible = "mediatek,mt8173-mmsys", "syscon"; reg = <0 0x14000000 0 0x1000>; -- GitLab From a5da9568c58023dff5e79a5eb52b164e69890707 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Tue, 24 Nov 2015 13:09:57 +0200 Subject: [PATCH 0813/2855] xhci: use debug level when printing out interval rounding messages Don't use dev_warn() for intened behaviour, use dev_dbg() Rounding down the interval to the nearest power of 2 is required by xhci specs. Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index c48cbe7313565..536d00f21eed3 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1245,7 +1245,7 @@ static unsigned int xhci_microframes_to_exponent(struct usb_device *udev, interval = fls(desc_interval) - 1; interval = clamp_val(interval, min_exponent, max_exponent); if ((1 << interval) != desc_interval) - dev_warn(&udev->dev, + dev_dbg(&udev->dev, "ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n", ep->desc.bEndpointAddress, 1 << interval, -- GitLab From d5ddcdf4d672fddeb947ab144eb355c917b431c3 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Tue, 24 Nov 2015 13:09:58 +0200 Subject: [PATCH 0814/2855] xhci: rework xhci extended capability list parsing functions Replace the existing two extended capability parsing helper functions with one called xhci_find_next_ext_cap(). The extended capabilities are read both in pci-quirks before xhci driver is loaded, and inside the xhci driver when adding ports. The existing helpers did not suit well for these cases and a lot of custom parsing code was needed. The new helper function simplifies these two cases a lot. The motivation for this rework was that code to support xhci debug capability needed to parse extended capabilities, and it included yet another capability parsing helper specific for its needs. With this solution it debug capability code can use this new helper as well Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/pci-quirks.c | 25 ++++------ drivers/usb/host/xhci-ext-caps.h | 83 +++++++++++--------------------- drivers/usb/host/xhci-mem.c | 73 +++++++++++----------------- 3 files changed, 64 insertions(+), 117 deletions(-) diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index f9400564cb721..26cb8c861e6ed 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -984,24 +984,17 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev) * Find the Legacy Support Capability register - * this is optional for xHCI host controllers. */ - ext_cap_offset = xhci_find_next_cap_offset(base, XHCI_HCC_PARAMS_OFFSET); - do { - if ((ext_cap_offset + sizeof(val)) > len) { - /* We're reading garbage from the controller */ - dev_warn(&pdev->dev, - "xHCI controller failing to respond"); - return; - } + ext_cap_offset = xhci_find_next_ext_cap(base, 0, XHCI_EXT_CAPS_LEGACY); - if (!ext_cap_offset) - /* We've reached the end of the extended capabilities */ - goto hc_init; + if (!ext_cap_offset) + goto hc_init; - val = readl(base + ext_cap_offset); - if (XHCI_EXT_CAPS_ID(val) == XHCI_EXT_CAPS_LEGACY) - break; - ext_cap_offset = xhci_find_next_cap_offset(base, ext_cap_offset); - } while (1); + if ((ext_cap_offset + sizeof(val)) > len) { + /* We're reading garbage from the controller */ + dev_warn(&pdev->dev, "xHCI controller failing to respond"); + return; + } + val = readl(base + ext_cap_offset); /* If the BIOS owns the HC, signal that the OS wants it, and wait */ if (val & XHCI_HC_BIOS_OWNED) { diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h index 9fe3225e6c614..04ce6b156b350 100644 --- a/drivers/usb/host/xhci-ext-caps.h +++ b/drivers/usb/host/xhci-ext-caps.h @@ -90,67 +90,40 @@ #include -/** - * Return the next extended capability pointer register. - * - * @base PCI register base address. - * - * @ext_offset Offset of the 32-bit register that contains the extended - * capabilites pointer. If searching for the first extended capability, pass - * in XHCI_HCC_PARAMS_OFFSET. If searching for the next extended capability, - * pass in the offset of the current extended capability register. - * - * Returns 0 if there is no next extended capability register or returns the register offset - * from the PCI registers base address. - */ -static inline int xhci_find_next_cap_offset(void __iomem *base, int ext_offset) -{ - u32 next; - - next = readl(base + ext_offset); - - if (ext_offset == XHCI_HCC_PARAMS_OFFSET) { - /* Find the first extended capability */ - next = XHCI_HCC_EXT_CAPS(next); - ext_offset = 0; - } else { - /* Find the next extended capability */ - next = XHCI_EXT_CAPS_NEXT(next); - } - - if (!next) - return 0; - /* - * Address calculation from offset of extended capabilities - * (or HCCPARAMS) register - see section 5.3.6 and section 7. - */ - return ext_offset + (next << 2); -} - /** * Find the offset of the extended capabilities with capability ID id. * - * @base PCI MMIO registers base address. - * @ext_offset Offset from base of the first extended capability to look at, - * or the address of HCCPARAMS. - * @id Extended capability ID to search for. + * @base PCI MMIO registers base address. + * @start address at which to start looking, (0 or HCC_PARAMS to start at + * beginning of list) + * @id Extended capability ID to search for. * - * This uses an arbitrary limit of XHCI_MAX_EXT_CAPS extended capabilities - * to make sure that the list doesn't contain a loop. + * Returns the offset of the next matching extended capability structure. + * Some capabilities can occur several times, e.g., the XHCI_EXT_CAPS_PROTOCOL, + * and this provides a way to find them all. */ -static inline int xhci_find_ext_cap_by_id(void __iomem *base, int ext_offset, int id) + +static inline int xhci_find_next_ext_cap(void __iomem *base, u32 start, int id) { u32 val; - int limit = XHCI_MAX_EXT_CAPS; - - while (ext_offset && limit > 0) { - val = readl(base + ext_offset); - if (XHCI_EXT_CAPS_ID(val) == id) - break; - ext_offset = xhci_find_next_cap_offset(base, ext_offset); - limit--; - } - if (limit > 0) - return ext_offset; + u32 next; + u32 offset; + + offset = start; + if (!start || start == XHCI_HCC_PARAMS_OFFSET) { + val = readl(base + XHCI_HCC_PARAMS_OFFSET); + offset = XHCI_HCC_EXT_CAPS(val) << 2; + if (!offset) + return 0; + }; + do { + val = readl(base + offset); + if (XHCI_EXT_CAPS_ID(val) == id && offset != start) + return offset; + + next = XHCI_EXT_CAPS_NEXT(val); + offset += next << 2; + } while (next); + return 0; } diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 536d00f21eed3..dc7f915d9a131 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -2064,17 +2064,19 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci) } static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, - __le32 __iomem *addr, u8 major_revision, int max_caps) + __le32 __iomem *addr, int max_caps) { u32 temp, port_offset, port_count; int i; + u8 major_revision; struct xhci_hub *rhub; temp = readl(addr); + major_revision = XHCI_EXT_PORT_MAJOR(temp); - if (XHCI_EXT_PORT_MAJOR(temp) == 0x03) { + if (major_revision == 0x03) { rhub = &xhci->usb3_rhub; - } else if (XHCI_EXT_PORT_MAJOR(temp) <= 0x02) { + } else if (major_revision <= 0x02) { rhub = &xhci->usb2_rhub; } else { xhci_warn(xhci, "Ignoring unknown port speed, " @@ -2190,19 +2192,12 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, */ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) { - __le32 __iomem *addr, *tmp_addr; - u32 offset, tmp_offset; + void __iomem *base; + u32 offset; unsigned int num_ports; int i, j, port_index; int cap_count = 0; - - addr = &xhci->cap_regs->hcc_params; - offset = XHCI_HCC_EXT_CAPS(readl(addr)); - if (offset == 0) { - xhci_err(xhci, "No Extended Capability registers, " - "unable to set up roothub.\n"); - return -ENODEV; - } + u32 cap_start; num_ports = HCS_MAX_PORTS(xhci->hcs_params1); xhci->port_array = kzalloc(sizeof(*xhci->port_array)*num_ports, flags); @@ -2220,48 +2215,34 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) for (j = 0; j < XHCI_MAX_INTERVAL; j++) INIT_LIST_HEAD(&bw_table->interval_bw[j].endpoints); } + base = &xhci->cap_regs->hc_capbase; - /* - * For whatever reason, the first capability offset is from the - * capability register base, not from the HCCPARAMS register. - * See section 5.3.6 for offset calculation. - */ - addr = &xhci->cap_regs->hc_capbase + offset; - - tmp_addr = addr; - tmp_offset = offset; + cap_start = xhci_find_next_ext_cap(base, 0, XHCI_EXT_CAPS_PROTOCOL); + if (!cap_start) { + xhci_err(xhci, "No Extended Capability registers, unable to set up roothub\n"); + return -ENODEV; + } + offset = cap_start; /* count extended protocol capability entries for later caching */ - do { - u32 cap_id; - cap_id = readl(tmp_addr); - if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL) - cap_count++; - tmp_offset = XHCI_EXT_CAPS_NEXT(cap_id); - tmp_addr += tmp_offset; - } while (tmp_offset); + while (offset) { + cap_count++; + offset = xhci_find_next_ext_cap(base, offset, + XHCI_EXT_CAPS_PROTOCOL); + } xhci->ext_caps = kzalloc(sizeof(*xhci->ext_caps) * cap_count, flags); if (!xhci->ext_caps) return -ENOMEM; - while (1) { - u32 cap_id; - - cap_id = readl(addr); - if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL) - xhci_add_in_port(xhci, num_ports, addr, - (u8) XHCI_EXT_PORT_MAJOR(cap_id), - cap_count); - offset = XHCI_EXT_CAPS_NEXT(cap_id); - if (!offset || (xhci->num_usb2_ports + xhci->num_usb3_ports) - == num_ports) + offset = cap_start; + + while (offset) { + xhci_add_in_port(xhci, num_ports, base + offset, cap_count); + if (xhci->num_usb2_ports + xhci->num_usb3_ports == num_ports) break; - /* - * Once you're into the Extended Capabilities, the offset is - * always relative to the register holding the offset. - */ - addr += offset; + offset = xhci_find_next_ext_cap(base, offset, + XHCI_EXT_CAPS_PROTOCOL); } if (xhci->num_usb2_ports == 0 && xhci->num_usb3_ports == 0) { -- GitLab From 3b1884c24c98dada51fc4b05735773f0078711d2 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 30 Nov 2015 15:28:06 +0100 Subject: [PATCH 0815/2855] spi: Uninline spi_unregister_device() Uninline spi_unregister_device() in preparation of adding more code to it. Add kerneldoc documentation while we're at it. Signed-off-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- drivers/spi/spi.c | 14 ++++++++++++++ include/linux/spi/spi.h | 7 +------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index e2415be209d5a..3f135cc9a70ea 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -604,6 +604,20 @@ struct spi_device *spi_new_device(struct spi_master *master, } EXPORT_SYMBOL_GPL(spi_new_device); +/** + * spi_unregister_device - unregister a single SPI device + * @spi: spi_device to unregister + * + * Start making the passed SPI device vanish. Normally this would be handled + * by spi_unregister_master(). + */ +void spi_unregister_device(struct spi_device *spi) +{ + if (spi) + device_unregister(&spi->dev); +} +EXPORT_SYMBOL_GPL(spi_unregister_device); + static void spi_match_master_to_boardinfo(struct spi_master *master, struct spi_board_info *bi) { diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index cce80e6dc7d11..075bede665210 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -1115,12 +1115,7 @@ spi_add_device(struct spi_device *spi); extern struct spi_device * spi_new_device(struct spi_master *, struct spi_board_info *); -static inline void -spi_unregister_device(struct spi_device *spi) -{ - if (spi) - device_unregister(&spi->dev); -} +extern void spi_unregister_device(struct spi_device *spi); extern const struct spi_device_id * spi_get_device_id(const struct spi_device *sdev); -- GitLab From bd6c1644a2f6f46cdf89388e81168a70711fce3a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 30 Nov 2015 15:28:07 +0100 Subject: [PATCH 0816/2855] spi: Mark instantiated device nodes with OF_POPULATE Mark (and unmark) device nodes with the POPULATE flag as appropriate. This is required to avoid multi probing when enabling and populating SPI buses in DT overlays. Based on commit 4f001fd30145a6a8 ("i2c: Mark instantiated device nodes with OF_POPULATE"). Suggested-by: Mark Brown Signed-off-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- drivers/spi/spi.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 3f135cc9a70ea..c7486a373af1b 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -613,8 +613,12 @@ EXPORT_SYMBOL_GPL(spi_new_device); */ void spi_unregister_device(struct spi_device *spi) { - if (spi) - device_unregister(&spi->dev); + if (!spi) + return; + + if (spi->dev.of_node) + of_node_clear_flag(spi->dev.of_node, OF_POPULATED); + device_unregister(&spi->dev); } EXPORT_SYMBOL_GPL(spi_unregister_device); @@ -1561,6 +1565,8 @@ static void of_register_spi_devices(struct spi_master *master) return; for_each_available_child_of_node(master->dev.of_node, nc) { + if (of_node_test_and_set_flag(nc, OF_POPULATED)) + continue; spi = of_register_spi_device(master, nc); if (IS_ERR(spi)) dev_warn(&master->dev, "Failed to create SPI device for %s\n", @@ -2645,6 +2651,11 @@ static int of_spi_notify(struct notifier_block *nb, unsigned long action, if (master == NULL) return NOTIFY_OK; /* not for us */ + if (of_node_test_and_set_flag(rd->dn, OF_POPULATED)) { + put_device(&master->dev); + return NOTIFY_OK; + } + spi = of_register_spi_device(master, rd->dn); put_device(&master->dev); @@ -2656,6 +2667,10 @@ static int of_spi_notify(struct notifier_block *nb, unsigned long action, break; case OF_RECONFIG_CHANGE_REMOVE: + /* already depopulated? */ + if (!of_node_check_flag(rd->dn, OF_POPULATED)) + return NOTIFY_OK; + /* find our device by node */ spi = of_find_spi_device_by_node(rd->dn); if (spi == NULL) -- GitLab From de64aa9ec129ba627634088f662a4d09e356ddb6 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 23 Nov 2015 11:23:07 +0100 Subject: [PATCH 0817/2855] mtd: nand: fix ONFI parameter page layout src_ssync_features field is only 1 byte large, and the 4th reserved area is actually 8 bytes large. Fixes: d1e1f4e42b5 ("mtd: nand: add support for reading ONFI parameters from NAND device") Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 056d1650eb89f..eaf48b5a95dd1 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -276,7 +276,7 @@ struct nand_onfi_params { __le16 t_r; __le16 t_ccs; __le16 src_sync_timing_mode; - __le16 src_ssync_features; + u8 src_ssync_features; __le16 clk_pin_capacitance_typ; __le16 io_pin_capacitance_typ; __le16 input_pin_capacitance_typ; @@ -284,7 +284,7 @@ struct nand_onfi_params { u8 driver_strength_support; __le16 t_int_r; __le16 t_ald; - u8 reserved4[7]; + u8 reserved4[8]; /* vendor */ __le16 vendor_revision; -- GitLab From 74e98be45fe069fcdb00f35eccbb179309ab65cd Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 1 Dec 2015 11:08:32 -0800 Subject: [PATCH 0818/2855] mtd: nand: fix typo (t_ald -> t_adl) It's "ADL" ("ALE to data loading" time) not "ALD". Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- include/linux/mtd/nand.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index eaf48b5a95dd1..fad634ea16857 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -283,7 +283,7 @@ struct nand_onfi_params { u8 input_pin_capacitance_max; u8 driver_strength_support; __le16 t_int_r; - __le16 t_ald; + __le16 t_adl; u8 reserved4[8]; /* vendor */ @@ -407,7 +407,7 @@ struct nand_jedec_params { __le16 input_pin_capacitance_typ; __le16 clk_pin_capacitance_typ; u8 driver_strength_support; - __le16 t_ald; + __le16 t_adl; u8 reserved4[36]; /* ECC and endurance block */ -- GitLab From d121b66d25adfa8b631dc59511ebc1d600ad5111 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 30 Nov 2015 18:01:27 -0800 Subject: [PATCH 0819/2855] mtd: brcmnand: drop brcmnand_host::of_node field We don't actually need to stash a copy of this device_node indefinitely; we only need it in brcmnand_init_cs(). Signed-off-by: Brian Norris Cc: Cc: Kamal Dasu Acked-by: Scott Branden Signed-off-by: Brian Norris --- drivers/mtd/nand/brcmnand/brcmnand.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index ad756f626f4be..35d78f739d91d 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -176,7 +176,6 @@ struct brcmnand_cfg { struct brcmnand_host { struct list_head node; - struct device_node *of_node; struct nand_chip chip; struct mtd_info mtd; @@ -1902,10 +1901,9 @@ static int brcmnand_setup_dev(struct brcmnand_host *host) return 0; } -static int brcmnand_init_cs(struct brcmnand_host *host) +static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn) { struct brcmnand_controller *ctrl = host->ctrl; - struct device_node *dn = host->of_node; struct platform_device *pdev = host->pdev; struct mtd_info *mtd; struct nand_chip *chip; @@ -2239,9 +2237,8 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) } host->pdev = pdev; host->ctrl = ctrl; - host->of_node = child; - ret = brcmnand_init_cs(host); + ret = brcmnand_init_cs(host, child); if (ret) { devm_kfree(dev, host); continue; /* Try all chip-selects */ -- GitLab From 7f9354f26e3f84d349615e17888111ae204557a0 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Tue, 1 Dec 2015 12:44:03 -0600 Subject: [PATCH 0820/2855] regulator: tps65086: Update regulator driver for the TPS65086 PMIC Make changes to allow this driver to work with the updated TPS65086 core driver and bindings. Signed-off-by: Andrew F. Davis Signed-off-by: Mark Brown --- drivers/regulator/tps65086-regulator.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/tps65086-regulator.c b/drivers/regulator/tps65086-regulator.c index c26fc7e88ebaf..33f389d583ef1 100644 --- a/drivers/regulator/tps65086-regulator.c +++ b/drivers/regulator/tps65086-regulator.c @@ -16,10 +16,9 @@ */ #include -#include +#include #include #include -#include #include @@ -31,6 +30,7 @@ enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1, .desc = { \ .name = _name, \ .of_match = of_match_ptr(_of), \ + .regulators_node = "regulators", \ .of_parse_cb = tps65086_of_parse_cb, \ .id = _id, \ .ops = ®_ops, \ @@ -54,6 +54,7 @@ enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1, .desc = { \ .name = _name, \ .of_match = of_match_ptr(_of), \ + .regulators_node = "regulators", \ .of_parse_cb = tps65086_of_parse_cb, \ .id = _id, \ .ops = &switch_ops, \ @@ -213,8 +214,8 @@ static int tps65086_regulator_probe(struct platform_device *pdev) platform_set_drvdata(pdev, tps); config.dev = &pdev->dev; + config.dev->of_node = tps->dev->of_node; config.driver_data = tps; - config.of_node = pdev->dev.of_node; config.regmap = tps->regmap; for (i = 0; i < ARRAY_SIZE(regulators); i++) { -- GitLab From ced08b020e6ce0fa693e4d1d8c6088dbc0a36c64 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Mon, 26 Oct 2015 04:06:29 +0100 Subject: [PATCH 0821/2855] uwb: uwbd() is not freezable kthread uwbd() calls try_to_freeze(), but the thread doesn't mark itself freezable through set_freezable(), so the try_to_freeze() call is useless. Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/uwb/uwbd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/uwb/uwbd.c b/drivers/uwb/uwbd.c index bdcb13cc1d541..01c20a260a8b3 100644 --- a/drivers/uwb/uwbd.c +++ b/drivers/uwb/uwbd.c @@ -279,7 +279,6 @@ static int uwbd(void *param) HZ); if (should_stop) break; - try_to_freeze(); spin_lock_irqsave(&rc->uwbd.event_list_lock, flags); if (!list_empty(&rc->uwbd.event_list)) { -- GitLab From 84c1eeb02353ffcafe039e892410cad835334ba9 Mon Sep 17 00:00:00 2001 From: Saurabh Sengar Date: Wed, 28 Oct 2015 12:44:35 +0530 Subject: [PATCH 0822/2855] usb : replace dma_pool_alloc and memset with dma_pool_zalloc replace dma_pool_alloc and memset with a single call to dma_pool_zalloc Signed-off-by: Saurabh Sengar Acked-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/udc.c | 3 +-- drivers/usb/gadget/udc/gr_udc.c | 3 +-- drivers/usb/host/uhci-q.c | 3 +-- drivers/usb/host/whci/qset.c | 3 +-- drivers/usb/host/xhci-mem.c | 6 ++---- 5 files changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 391a1225b0ba3..b292b454c77ba 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -349,14 +349,13 @@ static int add_td_to_list(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq, if (node == NULL) return -ENOMEM; - node->ptr = dma_pool_alloc(hwep->td_pool, GFP_ATOMIC, + node->ptr = dma_pool_zalloc(hwep->td_pool, GFP_ATOMIC, &node->dma); if (node->ptr == NULL) { kfree(node); return -ENOMEM; } - memset(node->ptr, 0, sizeof(struct ci_hw_td)); node->ptr->token = cpu_to_le32(length << __ffs(TD_TOTAL_BYTES)); node->ptr->token &= cpu_to_le32(TD_TOTAL_BYTES); node->ptr->token |= cpu_to_le32(TD_STATUS_ACTIVE); diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c index b9429bc425116..39b7136d31d9c 100644 --- a/drivers/usb/gadget/udc/gr_udc.c +++ b/drivers/usb/gadget/udc/gr_udc.c @@ -253,13 +253,12 @@ static struct gr_dma_desc *gr_alloc_dma_desc(struct gr_ep *ep, gfp_t gfp_flags) dma_addr_t paddr; struct gr_dma_desc *dma_desc; - dma_desc = dma_pool_alloc(ep->dev->desc_pool, gfp_flags, &paddr); + dma_desc = dma_pool_zalloc(ep->dev->desc_pool, gfp_flags, &paddr); if (!dma_desc) { dev_err(ep->dev->dev, "Could not allocate from DMA pool\n"); return NULL; } - memset(dma_desc, 0, sizeof(*dma_desc)); dma_desc->paddr = paddr; return dma_desc; diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index da6f56d996ce5..c17ea1589b833 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -248,11 +248,10 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, dma_addr_t dma_handle; struct uhci_qh *qh; - qh = dma_pool_alloc(uhci->qh_pool, GFP_ATOMIC, &dma_handle); + qh = dma_pool_zalloc(uhci->qh_pool, GFP_ATOMIC, &dma_handle); if (!qh) return NULL; - memset(qh, 0, sizeof(*qh)); qh->dma_handle = dma_handle; qh->element = UHCI_PTR_TERM(uhci); diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c index dc31c425ce017..329747398f9ac 100644 --- a/drivers/usb/host/whci/qset.c +++ b/drivers/usb/host/whci/qset.c @@ -30,10 +30,9 @@ struct whc_qset *qset_alloc(struct whc *whc, gfp_t mem_flags) struct whc_qset *qset; dma_addr_t dma; - qset = dma_pool_alloc(whc->qset_pool, mem_flags, &dma); + qset = dma_pool_zalloc(whc->qset_pool, mem_flags, &dma); if (qset == NULL) return NULL; - memset(qset, 0, sizeof(struct whc_qset)); qset->qset_dma = dma; qset->whc = whc; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index dc7f915d9a131..5cd080e0a685e 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -47,13 +47,12 @@ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci, if (!seg) return NULL; - seg->trbs = dma_pool_alloc(xhci->segment_pool, flags, &dma); + seg->trbs = dma_pool_zalloc(xhci->segment_pool, flags, &dma); if (!seg->trbs) { kfree(seg); return NULL; } - memset(seg->trbs, 0, TRB_SEGMENT_SIZE); /* If the cycle state is 0, set the cycle bit to 1 for all the TRBs */ if (cycle_state == 0) { for (i = 0; i < TRBS_PER_SEGMENT; i++) @@ -517,12 +516,11 @@ static struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci if (type == XHCI_CTX_TYPE_INPUT) ctx->size += CTX_SIZE(xhci->hcc_params); - ctx->bytes = dma_pool_alloc(xhci->device_pool, flags, &ctx->dma); + ctx->bytes = dma_pool_zalloc(xhci->device_pool, flags, &ctx->dma); if (!ctx->bytes) { kfree(ctx); return NULL; } - memset(ctx->bytes, 0, ctx->size); return ctx; } -- GitLab From a7a19d7ab6f7b683e08ef25fd0fd673d5b09776e Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 16 Nov 2015 19:01:44 +0100 Subject: [PATCH 0823/2855] USB-EHCI: Delete unnecessary checks before the function call "dma_pool_destroy" The dma_pool_destroy() function tests whether its argument is NULL and then returns immediately. Thus the test around the calls is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-mem.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index b6205fac35677..4de43011df23a 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c @@ -128,21 +128,13 @@ static void ehci_mem_cleanup (struct ehci_hcd *ehci) ehci->dummy = NULL; /* DMA consistent memory and pools */ - if (ehci->qtd_pool) - dma_pool_destroy (ehci->qtd_pool); + dma_pool_destroy(ehci->qtd_pool); ehci->qtd_pool = NULL; - - if (ehci->qh_pool) { - dma_pool_destroy (ehci->qh_pool); - ehci->qh_pool = NULL; - } - - if (ehci->itd_pool) - dma_pool_destroy (ehci->itd_pool); + dma_pool_destroy(ehci->qh_pool); + ehci->qh_pool = NULL; + dma_pool_destroy(ehci->itd_pool); ehci->itd_pool = NULL; - - if (ehci->sitd_pool) - dma_pool_destroy (ehci->sitd_pool); + dma_pool_destroy(ehci->sitd_pool); ehci->sitd_pool = NULL; if (ehci->periodic) -- GitLab From 764331940bed55a18132ac46bca5a4216090a06b Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 5 Nov 2015 16:20:36 +0100 Subject: [PATCH 0824/2855] uas: use the BIT() macro Use this macro to make the driver more readable. Signed-off-by: Oliver Neukum Reviewed-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index e691516644360..e0947e3f1ea5a 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -49,18 +49,18 @@ struct uas_dev_info { }; enum { - SUBMIT_STATUS_URB = (1 << 1), - ALLOC_DATA_IN_URB = (1 << 2), - SUBMIT_DATA_IN_URB = (1 << 3), - ALLOC_DATA_OUT_URB = (1 << 4), - SUBMIT_DATA_OUT_URB = (1 << 5), - ALLOC_CMD_URB = (1 << 6), - SUBMIT_CMD_URB = (1 << 7), - COMMAND_INFLIGHT = (1 << 8), - DATA_IN_URB_INFLIGHT = (1 << 9), - DATA_OUT_URB_INFLIGHT = (1 << 10), - COMMAND_ABORTED = (1 << 11), - IS_IN_WORK_LIST = (1 << 12), + SUBMIT_STATUS_URB = BIT(1), + ALLOC_DATA_IN_URB = BIT(2), + SUBMIT_DATA_IN_URB = BIT(3), + ALLOC_DATA_OUT_URB = BIT(4), + SUBMIT_DATA_OUT_URB = BIT(5), + ALLOC_CMD_URB = BIT(6), + SUBMIT_CMD_URB = BIT(7), + COMMAND_INFLIGHT = BIT(8), + DATA_IN_URB_INFLIGHT = BIT(9), + DATA_OUT_URB_INFLIGHT = BIT(10), + COMMAND_ABORTED = BIT(11), + IS_IN_WORK_LIST = BIT(12), }; /* Overrides scsi_pointer */ -- GitLab From b36d83913ae55c7619ac80185fb707bc30fd41c5 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 3 Nov 2015 16:43:17 +0100 Subject: [PATCH 0825/2855] uas: no gfp argument to uas_submit_urbs() This function must be called with a spinlock held. Memory can be allocated only with GFP_ATOMIC. Passing a gfp_t argument is a waste. Signed-off-by: Oliver Neukum Reviewed-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index e0947e3f1ea5a..60a1bfc80434c 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -74,7 +74,7 @@ struct uas_cmd_info { /* I hate forward declarations, but I actually have a loop */ static int uas_submit_urbs(struct scsi_cmnd *cmnd, - struct uas_dev_info *devinfo, gfp_t gfp); + struct uas_dev_info *devinfo); static void uas_do_work(struct work_struct *work); static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller); static void uas_free_streams(struct uas_dev_info *devinfo); @@ -105,7 +105,7 @@ static void uas_do_work(struct work_struct *work) if (!(cmdinfo->state & IS_IN_WORK_LIST)) continue; - err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); + err = uas_submit_urbs(cmnd, cmnd->device->hostdata); if (!err) cmdinfo->state &= ~IS_IN_WORK_LIST; else @@ -240,7 +240,7 @@ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, int err; cmdinfo->state |= direction | SUBMIT_STATUS_URB; - err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); + err = uas_submit_urbs(cmnd, cmnd->device->hostdata); if (err) { uas_add_work(cmdinfo); } @@ -512,7 +512,7 @@ static struct urb *uas_submit_sense_urb(struct scsi_cmnd *cmnd, gfp_t gfp) } static int uas_submit_urbs(struct scsi_cmnd *cmnd, - struct uas_dev_info *devinfo, gfp_t gfp) + struct uas_dev_info *devinfo) { struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; struct urb *urb; @@ -520,14 +520,14 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, lockdep_assert_held(&devinfo->lock); if (cmdinfo->state & SUBMIT_STATUS_URB) { - urb = uas_submit_sense_urb(cmnd, gfp); + urb = uas_submit_sense_urb(cmnd, GFP_ATOMIC); if (!urb) return SCSI_MLQUEUE_DEVICE_BUSY; cmdinfo->state &= ~SUBMIT_STATUS_URB; } if (cmdinfo->state & ALLOC_DATA_IN_URB) { - cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, gfp, + cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, GFP_ATOMIC, cmnd, DMA_FROM_DEVICE); if (!cmdinfo->data_in_urb) return SCSI_MLQUEUE_DEVICE_BUSY; @@ -536,7 +536,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, if (cmdinfo->state & SUBMIT_DATA_IN_URB) { usb_anchor_urb(cmdinfo->data_in_urb, &devinfo->data_urbs); - err = usb_submit_urb(cmdinfo->data_in_urb, gfp); + err = usb_submit_urb(cmdinfo->data_in_urb, GFP_ATOMIC); if (err) { usb_unanchor_urb(cmdinfo->data_in_urb); uas_log_cmd_state(cmnd, "data in submit err", err); @@ -547,7 +547,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, } if (cmdinfo->state & ALLOC_DATA_OUT_URB) { - cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, gfp, + cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, GFP_ATOMIC, cmnd, DMA_TO_DEVICE); if (!cmdinfo->data_out_urb) return SCSI_MLQUEUE_DEVICE_BUSY; @@ -556,7 +556,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, if (cmdinfo->state & SUBMIT_DATA_OUT_URB) { usb_anchor_urb(cmdinfo->data_out_urb, &devinfo->data_urbs); - err = usb_submit_urb(cmdinfo->data_out_urb, gfp); + err = usb_submit_urb(cmdinfo->data_out_urb, GFP_ATOMIC); if (err) { usb_unanchor_urb(cmdinfo->data_out_urb); uas_log_cmd_state(cmnd, "data out submit err", err); @@ -567,7 +567,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, } if (cmdinfo->state & ALLOC_CMD_URB) { - cmdinfo->cmd_urb = uas_alloc_cmd_urb(devinfo, gfp, cmnd); + cmdinfo->cmd_urb = uas_alloc_cmd_urb(devinfo, GFP_ATOMIC, cmnd); if (!cmdinfo->cmd_urb) return SCSI_MLQUEUE_DEVICE_BUSY; cmdinfo->state &= ~ALLOC_CMD_URB; @@ -575,7 +575,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, if (cmdinfo->state & SUBMIT_CMD_URB) { usb_anchor_urb(cmdinfo->cmd_urb, &devinfo->cmd_urbs); - err = usb_submit_urb(cmdinfo->cmd_urb, gfp); + err = usb_submit_urb(cmdinfo->cmd_urb, GFP_ATOMIC); if (err) { usb_unanchor_urb(cmdinfo->cmd_urb); uas_log_cmd_state(cmnd, "cmd submit err", err); @@ -653,7 +653,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, if (!devinfo->use_streams) cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB); - err = uas_submit_urbs(cmnd, devinfo, GFP_ATOMIC); + err = uas_submit_urbs(cmnd, devinfo); if (err) { /* If we did nothing, give up now */ if (cmdinfo->state & SUBMIT_STATUS_URB) { -- GitLab From 144e38c6bebe41da8dc0e611f70fee53ce22604f Mon Sep 17 00:00:00 2001 From: Saurabh Sengar Date: Mon, 16 Nov 2015 18:18:33 +0530 Subject: [PATCH 0826/2855] usb: host: ohci-pxa27x: use of_property_read_bool() for checking if a property is present or not, of_property_read_bool is more appropriate than of_get_property() Signed-off-by: Saurabh Sengar Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-pxa27x.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index ba1bec7db026d..e8c006e7a9608 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -365,19 +365,19 @@ static int ohci_pxa_of_init(struct platform_device *pdev) if (!pdata) return -ENOMEM; - if (of_get_property(np, "marvell,enable-port1", NULL)) + if (of_property_read_bool(np, "marvell,enable-port1")) pdata->flags |= ENABLE_PORT1; - if (of_get_property(np, "marvell,enable-port2", NULL)) + if (of_property_read_bool(np, "marvell,enable-port2")) pdata->flags |= ENABLE_PORT2; - if (of_get_property(np, "marvell,enable-port3", NULL)) + if (of_property_read_bool(np, "marvell,enable-port3")) pdata->flags |= ENABLE_PORT3; - if (of_get_property(np, "marvell,port-sense-low", NULL)) + if (of_property_read_bool(np, "marvell,port-sense-low")) pdata->flags |= POWER_SENSE_LOW; - if (of_get_property(np, "marvell,power-control-low", NULL)) + if (of_property_read_bool(np, "marvell,power-control-low")) pdata->flags |= POWER_CONTROL_LOW; - if (of_get_property(np, "marvell,no-oc-protection", NULL)) + if (of_property_read_bool(np, "marvell,no-oc-protection")) pdata->flags |= NO_OC_PROTECTION; - if (of_get_property(np, "marvell,oc-mode-perport", NULL)) + if (of_property_read_bool(np, "marvell,oc-mode-perport")) pdata->flags |= OC_MODE_PERPORT; if (!of_property_read_u32(np, "marvell,power-on-delay", &tmp)) pdata->power_on_delay = tmp; -- GitLab From c7c7806700e15ca9c48d880f8c65071f041cd890 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 18 Nov 2015 17:40:23 +0800 Subject: [PATCH 0827/2855] usb: misc: usbtest: improve the description for error message Now the function of complicated_callback is not only used for iso transfer, improve the error message to reflect it. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usbtest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 637f3f7cfce8b..c1bd1eb548bb9 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -1849,7 +1849,7 @@ static void complicated_callback(struct urb *urb) goto done; default: dev_err(&ctx->dev->intf->dev, - "iso resubmit err %d\n", + "resubmit err %d\n", status); /* FALLTHROUGH */ case -ENODEV: /* disconnected */ @@ -1863,7 +1863,7 @@ static void complicated_callback(struct urb *urb) if (ctx->pending == 0) { if (ctx->errors) dev_err(&ctx->dev->intf->dev, - "iso test, %lu errors out of %lu\n", + "during the test, %lu errors out of %lu\n", ctx->errors, ctx->packet_count); complete(&ctx->done); } -- GitLab From 6fb8ac81cb3125aafc7136f2ef0145da792bab94 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 28 Nov 2015 16:07:10 +0100 Subject: [PATCH 0828/2855] USB: constify usb_mon_operations structure The usb_mon_operations structure is never modified, so declare it as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 4 ++-- drivers/usb/mon/mon_main.c | 2 +- include/linux/usb/hcd.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 1c102d60cd9f4..df0e3b92533a7 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -3000,7 +3000,7 @@ EXPORT_SYMBOL_GPL(usb_hcd_platform_shutdown); #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) -struct usb_mon_operations *mon_ops; +const struct usb_mon_operations *mon_ops; /* * The registration is unlocked. @@ -3010,7 +3010,7 @@ struct usb_mon_operations *mon_ops; * symbols from usbcore, usbcore gets referenced and cannot be unloaded first. */ -int usb_mon_register (struct usb_mon_operations *ops) +int usb_mon_register(const struct usb_mon_operations *ops) { if (mon_ops) diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index f7c292f4891ee..fec3f1128fdca 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c @@ -241,7 +241,7 @@ static struct notifier_block mon_nb = { /* * Ops */ -static struct usb_mon_operations mon_ops_0 = { +static const struct usb_mon_operations mon_ops_0 = { .urb_submit = mon_submit, .urb_submit_error = mon_submit_error, .urb_complete = mon_complete, diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index f89c24bd53a4c..4dcf8446dbcda 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -660,7 +660,7 @@ struct usb_mon_operations { /* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */ }; -extern struct usb_mon_operations *mon_ops; +extern const struct usb_mon_operations *mon_ops; static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb) { @@ -682,7 +682,7 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb, (*mon_ops->urb_complete)(bus, urb, status); } -int usb_mon_register(struct usb_mon_operations *ops); +int usb_mon_register(const struct usb_mon_operations *ops); void usb_mon_deregister(void); #else -- GitLab From 9faae5a37b266afca6914163316856c5ed4ec366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 1 Nov 2015 10:04:41 +0100 Subject: [PATCH 0829/2855] USB: bcma: switch to GPIO descriptor for power control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So far we were using simple (legacy) GPIO functions & some poor logic to control power. It got many drawbacks: we were ignoring OF flags (GPIO_ACTIVE_LOW), we were not setting direction to output and we were assuming gpio_request success all the time. Fix it by switching to gpiod functions and adding appropriate checks. Signed-off-by: Rafał Miłecki Acked-by: Hauke Mehrtens Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/bcma-hcd.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c index 5398e3d42822c..291aaa2baed83 100644 --- a/drivers/usb/host/bcma-hcd.c +++ b/drivers/usb/host/bcma-hcd.c @@ -21,6 +21,7 @@ */ #include #include +#include #include #include #include @@ -36,6 +37,7 @@ MODULE_LICENSE("GPL"); struct bcma_hcd_device { struct platform_device *ehci_dev; struct platform_device *ohci_dev; + struct gpio_desc *gpio_desc; }; /* Wait for bitmask in a register to get set or cleared. @@ -228,19 +230,12 @@ static void bcma_hcd_init_chip_arm(struct bcma_device *dev) static void bcma_hci_platform_power_gpio(struct bcma_device *dev, bool val) { - int gpio; + struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev); - gpio = of_get_named_gpio(dev->dev.of_node, "vcc-gpio", 0); - if (!gpio_is_valid(gpio)) + if (IS_ERR_OR_NULL(usb_dev->gpio_desc)) return; - if (val) { - gpio_request(gpio, "bcma-hcd-gpio"); - gpio_set_value(gpio, 1); - } else { - gpio_set_value(gpio, 0); - gpio_free(gpio); - } + gpiod_set_value(usb_dev->gpio_desc, val); } static const struct usb_ehci_pdata ehci_pdata = { @@ -314,7 +309,11 @@ static int bcma_hcd_probe(struct bcma_device *dev) if (!usb_dev) return -ENOMEM; - bcma_hci_platform_power_gpio(dev, true); + if (dev->dev.of_node) + usb_dev->gpio_desc = devm_get_gpiod_from_child(&dev->dev, "vcc", + &dev->dev.of_node->fwnode); + if (!IS_ERR_OR_NULL(usb_dev->gpio_desc)) + gpiod_direction_output(usb_dev->gpio_desc, 1); switch (dev->id.id) { case BCMA_CORE_NS_USB20: -- GitLab From ec4dca8bdfb650fd698401e26f586683ec69a942 Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Thu, 29 Oct 2015 22:58:28 -0700 Subject: [PATCH 0830/2855] USB: usbmon: Remove timeval usage for timestamp struct timeval' uses 32-bits for its seconds field and will overflow in the year 2038 and beyond. This patch replaces the usage of 'struct timeval' in mon_get_timestamp() with timespec64 which uses a 64-bit seconds field and is y2038-safe. mon_get_timestamp() truncates the timestamp at 4096 seconds, so the correctness of the code is not affected. This patch is part of a larger attempt to remove instances of struct timeval and other 32-bit timekeeping (time_t, struct timespec) from the kernel. Signed-off-by: Tina Ruchandani Suggested-by: Arnd Bergmann Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/usb/mon/mon_text.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index ad408251d9557..98e4f63e6823a 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -176,12 +177,12 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, static inline unsigned int mon_get_timestamp(void) { - struct timeval tval; + struct timespec64 now; unsigned int stamp; - do_gettimeofday(&tval); - stamp = tval.tv_sec & 0xFFF; /* 2^32 = 4294967296. Limit to 4096s. */ - stamp = stamp * 1000000 + tval.tv_usec; + ktime_get_ts64(&now); + stamp = now.tv_sec & 0xFFF; /* 2^32 = 4294967296. Limit to 4096s. */ + stamp = stamp * USEC_PER_SEC + now.tv_nsec / NSEC_PER_USEC; return stamp; } -- GitLab From 18fc4ebdc7057478497682047db5acfb25b35c49 Mon Sep 17 00:00:00 2001 From: Deepa Dinamani Date: Wed, 4 Nov 2015 15:29:11 -0800 Subject: [PATCH 0831/2855] usb: misc: usbtest: Remove timeval usage timeval is deprecated and not y2038 safe. Its size also changes according to 32 bit/ 64 bit compilation. Replace it with 32 and 64 bit versions of its individual fields, giving two ioctls with different code values. The two ioctls are necessary to maintain the 32 bit and 64 bit userspace compatibility with a 64/32 bit kernel. Change unsigned to __u32 types for a definitive userspace interface. This is in accordance with the psABI that the unsigned type is always 32 bits. Also use motonic timer instead of real time to ensure positive delta values. Refactor usbtest_ioctl for readability to isolate the handling of the testing timing measurement. The official testusb userspace tool can be changed in a separate patch to reflect the __u32 changes as well. It can use the usbtest_param_32 struct, since 32 bit seconds is long enough for test durations. Signed-off-by: Deepa Dinamani Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usbtest.c | 229 ++++++++++++++++++++++++------------- 1 file changed, 147 insertions(+), 82 deletions(-) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index c1bd1eb548bb9..92fdb6e9faff4 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -22,18 +22,42 @@ static void complicated_callback(struct urb *urb); /*-------------------------------------------------------------------------*/ /* FIXME make these public somewhere; usbdevfs.h? */ -struct usbtest_param { + +/* Parameter for usbtest driver. */ +struct usbtest_param_32 { /* inputs */ - unsigned test_num; /* 0..(TEST_CASES-1) */ - unsigned iterations; - unsigned length; - unsigned vary; - unsigned sglen; + __u32 test_num; /* 0..(TEST_CASES-1) */ + __u32 iterations; + __u32 length; + __u32 vary; + __u32 sglen; /* outputs */ - struct timeval duration; + __s32 duration_sec; + __s32 duration_usec; }; -#define USBTEST_REQUEST _IOWR('U', 100, struct usbtest_param) + +/* + * Compat parameter to the usbtest driver. + * This supports older user space binaries compiled with 64 bit compiler. + */ +struct usbtest_param_64 { + /* inputs */ + __u32 test_num; /* 0..(TEST_CASES-1) */ + __u32 iterations; + __u32 length; + __u32 vary; + __u32 sglen; + + /* outputs */ + __s64 duration_sec; + __s64 duration_usec; +}; + +/* IOCTL interface to the driver. */ +#define USBTEST_REQUEST_32 _IOWR('U', 100, struct usbtest_param_32) +/* COMPAT IOCTL interface to the driver. */ +#define USBTEST_REQUEST_64 _IOWR('U', 100, struct usbtest_param_64) /*-------------------------------------------------------------------------*/ @@ -1030,7 +1054,7 @@ struct ctrl_ctx { unsigned pending; int status; struct urb **urb; - struct usbtest_param *param; + struct usbtest_param_32 *param; int last; }; @@ -1155,7 +1179,7 @@ error: } static int -test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param) +test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param) { struct usb_device *udev = testdev_to_usbdev(dev); struct urb **urb; @@ -1930,7 +1954,7 @@ static struct urb *iso_alloc_urb( } static int -test_queue(struct usbtest_dev *dev, struct usbtest_param *param, +test_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param, int pipe, struct usb_endpoint_descriptor *desc, unsigned offset) { struct transfer_context context; @@ -2049,81 +2073,20 @@ static int test_unaligned_bulk( return retval; } -/*-------------------------------------------------------------------------*/ - -/* We only have this one interface to user space, through usbfs. - * User mode code can scan usbfs to find N different devices (maybe on - * different busses) to use when testing, and allocate one thread per - * test. So discovery is simplified, and we have no device naming issues. - * - * Don't use these only as stress/load tests. Use them along with with - * other USB bus activity: plugging, unplugging, mousing, mp3 playback, - * video capture, and so on. Run different tests at different times, in - * different sequences. Nothing here should interact with other devices, - * except indirectly by consuming USB bandwidth and CPU resources for test - * threads and request completion. But the only way to know that for sure - * is to test when HC queues are in use by many devices. - * - * WARNING: Because usbfs grabs udev->dev.sem before calling this ioctl(), - * it locks out usbcore in certain code paths. Notably, if you disconnect - * the device-under-test, hub_wq will wait block forever waiting for the - * ioctl to complete ... so that usb_disconnect() can abort the pending - * urbs and then call usbtest_disconnect(). To abort a test, you're best - * off just killing the userspace task and waiting for it to exit. - */ - +/* Run tests. */ static int -usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) +usbtest_do_ioctl(struct usb_interface *intf, struct usbtest_param_32 *param) { struct usbtest_dev *dev = usb_get_intfdata(intf); struct usb_device *udev = testdev_to_usbdev(dev); - struct usbtest_param *param = buf; - int retval = -EOPNOTSUPP; struct urb *urb; struct scatterlist *sg; struct usb_sg_request req; - struct timeval start; unsigned i; - - /* FIXME USBDEVFS_CONNECTINFO doesn't say how fast the device is. */ - - pattern = mod_pattern; - - if (code != USBTEST_REQUEST) - return -EOPNOTSUPP; + int retval = -EOPNOTSUPP; if (param->iterations <= 0) return -EINVAL; - - if (param->sglen > MAX_SGLEN) - return -EINVAL; - - if (mutex_lock_interruptible(&dev->lock)) - return -ERESTARTSYS; - - /* FIXME: What if a system sleep starts while a test is running? */ - - /* some devices, like ez-usb default devices, need a non-default - * altsetting to have any active endpoints. some tests change - * altsettings; force a default so most tests don't need to check. - */ - if (dev->info->alt >= 0) { - int res; - - if (intf->altsetting->desc.bInterfaceNumber) { - mutex_unlock(&dev->lock); - return -ENODEV; - } - res = set_altsetting(dev, dev->info->alt); - if (res) { - dev_err(&intf->dev, - "set altsetting to %d failed, %d\n", - dev->info->alt, res); - mutex_unlock(&dev->lock); - return res; - } - } - /* * Just a bunch of test cases that every HCD is expected to handle. * @@ -2133,7 +2096,6 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) * FIXME add more tests! cancel requests, verify the data, control * queueing, concurrent read+write threads, and so on. */ - do_gettimeofday(&start); switch (param->test_num) { case 0: @@ -2548,13 +2510,116 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) dev->in_pipe, NULL, 0); break; } - do_gettimeofday(¶m->duration); - param->duration.tv_sec -= start.tv_sec; - param->duration.tv_usec -= start.tv_usec; - if (param->duration.tv_usec < 0) { - param->duration.tv_usec += 1000 * 1000; - param->duration.tv_sec -= 1; + return retval; +} + +/*-------------------------------------------------------------------------*/ + +/* We only have this one interface to user space, through usbfs. + * User mode code can scan usbfs to find N different devices (maybe on + * different busses) to use when testing, and allocate one thread per + * test. So discovery is simplified, and we have no device naming issues. + * + * Don't use these only as stress/load tests. Use them along with with + * other USB bus activity: plugging, unplugging, mousing, mp3 playback, + * video capture, and so on. Run different tests at different times, in + * different sequences. Nothing here should interact with other devices, + * except indirectly by consuming USB bandwidth and CPU resources for test + * threads and request completion. But the only way to know that for sure + * is to test when HC queues are in use by many devices. + * + * WARNING: Because usbfs grabs udev->dev.sem before calling this ioctl(), + * it locks out usbcore in certain code paths. Notably, if you disconnect + * the device-under-test, hub_wq will wait block forever waiting for the + * ioctl to complete ... so that usb_disconnect() can abort the pending + * urbs and then call usbtest_disconnect(). To abort a test, you're best + * off just killing the userspace task and waiting for it to exit. + */ + +static int +usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) +{ + + struct usbtest_dev *dev = usb_get_intfdata(intf); + struct usbtest_param_64 *param_64 = buf; + struct usbtest_param_32 temp; + struct usbtest_param_32 *param_32 = buf; + struct timespec64 start; + struct timespec64 end; + struct timespec64 duration; + int retval = -EOPNOTSUPP; + + /* FIXME USBDEVFS_CONNECTINFO doesn't say how fast the device is. */ + + pattern = mod_pattern; + + if (mutex_lock_interruptible(&dev->lock)) + return -ERESTARTSYS; + + /* FIXME: What if a system sleep starts while a test is running? */ + + /* some devices, like ez-usb default devices, need a non-default + * altsetting to have any active endpoints. some tests change + * altsettings; force a default so most tests don't need to check. + */ + if (dev->info->alt >= 0) { + if (intf->altsetting->desc.bInterfaceNumber) { + retval = -ENODEV; + goto free_mutex; + } + retval = set_altsetting(dev, dev->info->alt); + if (retval) { + dev_err(&intf->dev, + "set altsetting to %d failed, %d\n", + dev->info->alt, retval); + goto free_mutex; + } + } + + switch (code) { + case USBTEST_REQUEST_64: + temp.test_num = param_64->test_num; + temp.iterations = param_64->iterations; + temp.length = param_64->length; + temp.sglen = param_64->sglen; + temp.vary = param_64->vary; + param_32 = &temp; + break; + + case USBTEST_REQUEST_32: + break; + + default: + retval = -EOPNOTSUPP; + goto free_mutex; + } + + ktime_get_ts64(&start); + + retval = usbtest_do_ioctl(intf, param_32); + if (retval) + goto free_mutex; + + ktime_get_ts64(&end); + + duration = timespec64_sub(end, start); + + temp.duration_sec = duration.tv_sec; + temp.duration_usec = duration.tv_nsec/NSEC_PER_USEC; + + switch (code) { + case USBTEST_REQUEST_32: + param_32->duration_sec = temp.duration_sec; + param_32->duration_usec = temp.duration_usec; + break; + + case USBTEST_REQUEST_64: + param_64->duration_sec = temp.duration_sec; + param_64->duration_usec = temp.duration_usec; + break; } + +free_mutex: mutex_unlock(&dev->lock); return retval; } -- GitLab From 8ab0f723af247af8dd92196c152c8f1da0254b2f Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Thu, 29 Oct 2015 22:44:31 -0700 Subject: [PATCH 0832/2855] USB: usbmon: Use 64bit timestamp for mon_bin_hdr struct mon_bin_hdr allows for a 64-bit seconds timestamp. The code currently uses 'struct timeval' to populate the timestamp in mon_bin_hdr, which has a 32-bit seconds field and will overflow in year 2038 and beyond. This patch replaces 'struct timeval' with 'struct timespec64' which is y2038 safe. This patch is part of a larger attempt to remove instances of struct timeval and other 32-bit timekeeping (time_t, struct timespec) from the kernel. Signed-off-by: Tina Ruchandani Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/usb/mon/mon_bin.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index 3598f1a626737..1a874a1f3890e 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -92,8 +93,8 @@ struct mon_bin_hdr { unsigned short busnum; /* Bus number */ char flag_setup; char flag_data; - s64 ts_sec; /* gettimeofday */ - s32 ts_usec; /* gettimeofday */ + s64 ts_sec; /* getnstimeofday64 */ + s32 ts_usec; /* getnstimeofday64 */ int status; unsigned int len_urb; /* Length of data (submitted or actual) */ unsigned int len_cap; /* Delivered length */ @@ -483,7 +484,7 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, char ev_type, int status) { const struct usb_endpoint_descriptor *epd = &urb->ep->desc; - struct timeval ts; + struct timespec64 ts; unsigned long flags; unsigned int urb_length; unsigned int offset; @@ -494,7 +495,7 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, struct mon_bin_hdr *ep; char data_tag = 0; - do_gettimeofday(&ts); + getnstimeofday64(&ts); spin_lock_irqsave(&rp->b_lock, flags); @@ -568,7 +569,7 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, ep->busnum = urb->dev->bus->busnum; ep->id = (unsigned long) urb; ep->ts_sec = ts.tv_sec; - ep->ts_usec = ts.tv_usec; + ep->ts_usec = ts.tv_nsec / NSEC_PER_USEC; ep->status = status; ep->len_urb = urb_length; ep->len_cap = length + lendesc; @@ -629,12 +630,12 @@ static void mon_bin_complete(void *data, struct urb *urb, int status) static void mon_bin_error(void *data, struct urb *urb, int error) { struct mon_reader_bin *rp = data; - struct timeval ts; + struct timespec64 ts; unsigned long flags; unsigned int offset; struct mon_bin_hdr *ep; - do_gettimeofday(&ts); + getnstimeofday64(&ts); spin_lock_irqsave(&rp->b_lock, flags); @@ -656,7 +657,7 @@ static void mon_bin_error(void *data, struct urb *urb, int error) ep->busnum = urb->dev->bus->busnum; ep->id = (unsigned long) urb; ep->ts_sec = ts.tv_sec; - ep->ts_usec = ts.tv_usec; + ep->ts_usec = ts.tv_nsec / NSEC_PER_USEC; ep->status = error; ep->flag_setup = '-'; -- GitLab From 5ce7d27d5c4dd40d7b147f7a4c2f7308508208a7 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Fri, 6 Nov 2015 00:04:06 -0600 Subject: [PATCH 0833/2855] usb: chipidea: msm: Use posted data writes on AHB This patch sets the AHBMODE to allow for posted data writes. This results in higher performance. Signed-off-by: Andy Gross Acked-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/ci_hdrc_msm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c index d79ecc08a1be7..3889809fd0c49 100644 --- a/drivers/usb/chipidea/ci_hdrc_msm.c +++ b/drivers/usb/chipidea/ci_hdrc_msm.c @@ -25,7 +25,8 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event) case CI_HDRC_CONTROLLER_RESET_EVENT: dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n"); writel(0, USB_AHBBURST); - writel(0, USB_AHBMODE); + /* use AHB transactor, allow posted data writes */ + writel(0x8, USB_AHBMODE); usb_phy_init(ci->usb_phy); break; case CI_HDRC_CONTROLLER_STOPPED_EVENT: -- GitLab From c56a2b2bc661fe089fde9beffeadcb0ecb5e934b Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Fri, 6 Nov 2015 00:04:07 -0600 Subject: [PATCH 0834/2855] usb: host: ehci-msm: Use posted data writes on AHB This patch sets the AHBMODE to allow for posted data writes. This results in higher performance. Signed-off-by: Andy Gross Tested-by: Georgi Djakov Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-msm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index c4f84c81de019..c23e2858c815b 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -57,8 +57,8 @@ static int ehci_msm_reset(struct usb_hcd *hcd) /* bursts of unspecified length. */ writel(0, USB_AHBBURST); - /* Use the AHB transactor */ - writel(0, USB_AHBMODE); + /* Use the AHB transactor, allow posted data writes */ + writel(0x8, USB_AHBMODE); /* Disable streaming mode and select host mode */ writel(0x13, USB_USBMODE); -- GitLab From bf5ce5bf3cc7136fd7fe5e8999a580bc93a9c8f6 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Sat, 14 Nov 2015 16:26:32 +0800 Subject: [PATCH 0835/2855] usb: core: lpm: fix usb3_hardware_lpm sysfs node Commit 655fe4effe0f ("usbcore: add sysfs support to xHCI usb3 hardware LPM") introduced usb3_hardware_lpm sysfs node. This doesn't show the correct status of USB3 U1 and U2 LPM status. This patch fixes this by replacing usb3_hardware_lpm with two nodes, usb3_hardware_lpm_u1 (for U1) and usb3_hardware_lpm_u2 (for U2), and recording the U1/U2 LPM status in right places. This patch should be back-ported to kernels as old as 4.3, that contains Commit 655fe4effe0f ("usbcore: add sysfs support to xHCI usb3 hardware LPM"). Cc: stable@vger.kernel.org Signed-off-by: Lu Baolu Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-bus-usb | 16 +++++----- Documentation/usb/power-management.txt | 11 +++---- drivers/usb/core/hub.c | 39 +++++++++++++++++++------ drivers/usb/core/sysfs.c | 31 ++++++++++++++++---- include/linux/usb.h | 4 +++ 5 files changed, 75 insertions(+), 26 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index 3a4abfc44f5e0..136ba17d2da05 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -134,19 +134,21 @@ Description: enabled for the device. Developer can write y/Y/1 or n/N/0 to the file to enable/disable the feature. -What: /sys/bus/usb/devices/.../power/usb3_hardware_lpm -Date: June 2015 +What: /sys/bus/usb/devices/.../power/usb3_hardware_lpm_u1 + /sys/bus/usb/devices/.../power/usb3_hardware_lpm_u2 +Date: November 2015 Contact: Kevin Strasser + Lu Baolu Description: If CONFIG_PM is set and a USB 3.0 lpm-capable device is plugged in to a xHCI host which supports link PM, it will check if U1 and U2 exit latencies have been set in the BOS descriptor; if - the check is is passed and the host supports USB3 hardware LPM, + the check is passed and the host supports USB3 hardware LPM, USB3 hardware LPM will be enabled for the device and the USB - device directory will contain a file named - power/usb3_hardware_lpm. The file holds a string value (enable - or disable) indicating whether or not USB3 hardware LPM is - enabled for the device. + device directory will contain two files named + power/usb3_hardware_lpm_u1 and power/usb3_hardware_lpm_u2. These + files hold a string value (enable or disable) indicating whether + or not USB3 hardware LPM U1 or U2 is enabled for the device. What: /sys/bus/usb/devices/.../removable Date: February 2012 diff --git a/Documentation/usb/power-management.txt b/Documentation/usb/power-management.txt index 4a15c90bc11d9..0a94ffe17ab6f 100644 --- a/Documentation/usb/power-management.txt +++ b/Documentation/usb/power-management.txt @@ -537,17 +537,18 @@ relevant attribute files are usb2_hardware_lpm and usb3_hardware_lpm. can write y/Y/1 or n/N/0 to the file to enable/disable USB2 hardware LPM manually. This is for test purpose mainly. - power/usb3_hardware_lpm + power/usb3_hardware_lpm_u1 + power/usb3_hardware_lpm_u2 When a USB 3.0 lpm-capable device is plugged in to a xHCI host which supports link PM, it will check if U1 and U2 exit latencies have been set in the BOS descriptor; if the check is is passed and the host supports USB3 hardware LPM, USB3 hardware LPM will be - enabled for the device and this file will be created. - The file holds a string value (enable or disable) - indicating whether or not USB3 hardware LPM is - enabled for the device. + enabled for the device and these files will be created. + The files hold a string value (enable or disable) + indicating whether or not USB3 hardware LPM U1 or U2 + is enabled for the device. USB Port Power Control ---------------------- diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index bdeadc112d29f..59f998e600309 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3875,17 +3875,30 @@ static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, return; } - if (usb_set_lpm_timeout(udev, state, timeout)) + if (usb_set_lpm_timeout(udev, state, timeout)) { /* If we can't set the parent hub U1/U2 timeout, * device-initiated LPM won't be allowed either, so let the xHCI * host know that this link state won't be enabled. */ hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); + } else { + /* Only a configured device will accept the Set Feature + * U1/U2_ENABLE + */ + if (udev->actconfig) + usb_set_device_initiated_lpm(udev, state, true); - /* Only a configured device will accept the Set Feature U1/U2_ENABLE */ - else if (udev->actconfig) - usb_set_device_initiated_lpm(udev, state, true); - + /* As soon as usb_set_lpm_timeout(timeout) returns 0, the + * hub-initiated LPM is enabled. Thus, LPM is enabled no + * matter the result of usb_set_device_initiated_lpm(). + * The only difference is whether device is able to initiate + * LPM. + */ + if (state == USB3_LPM_U1) + udev->usb3_lpm_u1_enabled = 1; + else if (state == USB3_LPM_U2) + udev->usb3_lpm_u2_enabled = 1; + } } /* @@ -3925,6 +3938,18 @@ static int usb_disable_link_state(struct usb_hcd *hcd, struct usb_device *udev, dev_warn(&udev->dev, "Could not disable xHCI %s timeout, " "bus schedule bandwidth may be impacted.\n", usb3_lpm_names[state]); + + /* As soon as usb_set_lpm_timeout(0) return 0, hub initiated LPM + * is disabled. Hub will disallows link to enter U1/U2 as well, + * even device is initiating LPM. Hence LPM is disabled if hub LPM + * timeout set to 0, no matter device-initiated LPM is disabled or + * not. + */ + if (state == USB3_LPM_U1) + udev->usb3_lpm_u1_enabled = 0; + else if (state == USB3_LPM_U2) + udev->usb3_lpm_u2_enabled = 0; + return 0; } @@ -3959,8 +3984,6 @@ int usb_disable_lpm(struct usb_device *udev) if (usb_disable_link_state(hcd, udev, USB3_LPM_U2)) goto enable_lpm; - udev->usb3_lpm_enabled = 0; - return 0; enable_lpm: @@ -4018,8 +4041,6 @@ void usb_enable_lpm(struct usb_device *udev) usb_enable_link_state(hcd, udev, USB3_LPM_U1); usb_enable_link_state(hcd, udev, USB3_LPM_U2); - - udev->usb3_lpm_enabled = 1; } EXPORT_SYMBOL_GPL(usb_enable_lpm); diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index d9ec2de6c4cf8..65b6e6b840431 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -531,7 +531,7 @@ static ssize_t usb2_lpm_besl_store(struct device *dev, } static DEVICE_ATTR_RW(usb2_lpm_besl); -static ssize_t usb3_hardware_lpm_show(struct device *dev, +static ssize_t usb3_hardware_lpm_u1_show(struct device *dev, struct device_attribute *attr, char *buf) { struct usb_device *udev = to_usb_device(dev); @@ -539,7 +539,7 @@ static ssize_t usb3_hardware_lpm_show(struct device *dev, usb_lock_device(udev); - if (udev->usb3_lpm_enabled) + if (udev->usb3_lpm_u1_enabled) p = "enabled"; else p = "disabled"; @@ -548,7 +548,26 @@ static ssize_t usb3_hardware_lpm_show(struct device *dev, return sprintf(buf, "%s\n", p); } -static DEVICE_ATTR_RO(usb3_hardware_lpm); +static DEVICE_ATTR_RO(usb3_hardware_lpm_u1); + +static ssize_t usb3_hardware_lpm_u2_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_device *udev = to_usb_device(dev); + const char *p; + + usb_lock_device(udev); + + if (udev->usb3_lpm_u2_enabled) + p = "enabled"; + else + p = "disabled"; + + usb_unlock_device(udev); + + return sprintf(buf, "%s\n", p); +} +static DEVICE_ATTR_RO(usb3_hardware_lpm_u2); static struct attribute *usb2_hardware_lpm_attr[] = { &dev_attr_usb2_hardware_lpm.attr, @@ -562,7 +581,8 @@ static struct attribute_group usb2_hardware_lpm_attr_group = { }; static struct attribute *usb3_hardware_lpm_attr[] = { - &dev_attr_usb3_hardware_lpm.attr, + &dev_attr_usb3_hardware_lpm_u1.attr, + &dev_attr_usb3_hardware_lpm_u2.attr, NULL, }; static struct attribute_group usb3_hardware_lpm_attr_group = { @@ -592,7 +612,8 @@ static int add_power_attributes(struct device *dev) if (udev->usb2_hw_lpm_capable == 1) rc = sysfs_merge_group(&dev->kobj, &usb2_hardware_lpm_attr_group); - if (udev->lpm_capable == 1) + if (udev->speed == USB_SPEED_SUPER && + udev->lpm_capable == 1) rc = sysfs_merge_group(&dev->kobj, &usb3_hardware_lpm_attr_group); } diff --git a/include/linux/usb.h b/include/linux/usb.h index b9a28074210f2..b79925dd2b411 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -511,6 +511,8 @@ struct usb3_lpm_parameters { * @usb2_hw_lpm_enabled: USB2 hardware LPM is enabled * @usb2_hw_lpm_allowed: Userspace allows USB 2.0 LPM to be enabled * @usb3_lpm_enabled: USB3 hardware LPM enabled + * @usb3_lpm_u1_enabled: USB3 hardware U1 LPM enabled + * @usb3_lpm_u2_enabled: USB3 hardware U2 LPM enabled * @string_langid: language ID for strings * @product: iProduct string, if present (static) * @manufacturer: iManufacturer string, if present (static) @@ -584,6 +586,8 @@ struct usb_device { unsigned usb2_hw_lpm_enabled:1; unsigned usb2_hw_lpm_allowed:1; unsigned usb3_lpm_enabled:1; + unsigned usb3_lpm_u1_enabled:1; + unsigned usb3_lpm_u2_enabled:1; int string_langid; /* static strings from the device */ -- GitLab From 513072d90a8dfe4bf83e1f81810de605eb5d7c3b Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Sat, 14 Nov 2015 16:26:33 +0800 Subject: [PATCH 0836/2855] usb: core: lpm: add sysfs node for usb3 lpm permit USB3 LPM is default on in Linux kernel if both xHCI host controller and the USB devices declare to be LPM-capable. Unfortunately, some devices are known to work well with LPM disabled, but to be broken if LPM is enabled, although it declares the LPM capability. Users won't be able to use this kind of devices, until someone puts them in the kernel blacklist and gets the kernel upgraded. This patch adds a sysfs node to permit or forbit USB3 LPM U1 or U2 entry for a port. The settings apply to both before and after device enumeration. Supported values are "0" - neither u1 nor u2 permitted, "u1" - only u1 is permitted, "u2" - only u2 is permitted, "u1_u2" - both u1 and u2 are permitted. With this interface, users can use an LPM-unfriendly USB device on a released Linux kernel. Signed-off-by: Lu Baolu Signed-off-by: Zhuang Jin Can Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-bus-usb | 11 +++ drivers/usb/core/hub.c | 15 ++++- drivers/usb/core/hub.h | 5 +- drivers/usb/core/port.c | 89 ++++++++++++++++++++++++- 4 files changed, 116 insertions(+), 4 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index 136ba17d2da05..0bd731cbb50cc 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -189,6 +189,17 @@ Description: The file will read "hotplug", "wired" and "not used" if the information is available, and "unknown" otherwise. +What: /sys/bus/usb/devices/.../(hub interface)/portX/usb3_lpm_permit +Date: November 2015 +Contact: Lu Baolu +Description: + Some USB3.0 devices are not friendly to USB3 LPM. usb3_lpm_permit + attribute allows enabling/disabling usb3 lpm of a port. It takes + effect both before and after a usb device is enumerated. Supported + values are "0" if both u1 and u2 are NOT permitted, "u1" if only u1 + is permitted, "u2" if only u2 is permitted, "u1_u2" if both u1 and + u2 are permitted. + What: /sys/bus/usb/devices/.../power/usb2_lpm_l1_timeout Date: May 2013 Contact: Mathias Nyman diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 59f998e600309..db7683e2d34c6 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -4020,6 +4020,8 @@ EXPORT_SYMBOL_GPL(usb_unlocked_disable_lpm); void usb_enable_lpm(struct usb_device *udev) { struct usb_hcd *hcd; + struct usb_hub *hub; + struct usb_port *port_dev; if (!udev || !udev->parent || udev->speed != USB_SPEED_SUPER || @@ -4039,8 +4041,17 @@ void usb_enable_lpm(struct usb_device *udev) if (udev->lpm_disable_count > 0) return; - usb_enable_link_state(hcd, udev, USB3_LPM_U1); - usb_enable_link_state(hcd, udev, USB3_LPM_U2); + hub = usb_hub_to_struct_hub(udev->parent); + if (!hub) + return; + + port_dev = hub->ports[udev->portnum - 1]; + + if (port_dev->usb3_lpm_u1_permit) + usb_enable_link_state(hcd, udev, USB3_LPM_U1); + + if (port_dev->usb3_lpm_u2_permit) + usb_enable_link_state(hcd, udev, USB3_LPM_U2); } EXPORT_SYMBOL_GPL(usb_enable_lpm); diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index 688817fb3246c..45d070dd1d031 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h @@ -92,6 +92,8 @@ struct usb_hub { * @status_lock: synchronize port_event() vs usb_port_{suspend|resume} * @portnum: port index num based one * @is_superspeed cache super-speed status + * @usb3_lpm_u1_permit: whether USB3 U1 LPM is permitted. + * @usb3_lpm_u2_permit: whether USB3 U2 LPM is permitted. */ struct usb_port { struct usb_device *child; @@ -104,6 +106,8 @@ struct usb_port { struct mutex status_lock; u8 portnum; unsigned int is_superspeed:1; + unsigned int usb3_lpm_u1_permit:1; + unsigned int usb3_lpm_u2_permit:1; }; #define to_usb_port(_dev) \ @@ -155,4 +159,3 @@ static inline int hub_port_debounce_be_stable(struct usb_hub *hub, { return hub_port_debounce(hub, port1, false); } - diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index 210618319f10a..cb18ce0d91775 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c @@ -50,6 +50,72 @@ static ssize_t connect_type_show(struct device *dev, } static DEVICE_ATTR_RO(connect_type); +static ssize_t usb3_lpm_permit_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_port *port_dev = to_usb_port(dev); + const char *p; + + if (port_dev->usb3_lpm_u1_permit) { + if (port_dev->usb3_lpm_u2_permit) + p = "u1_u2"; + else + p = "u1"; + } else { + if (port_dev->usb3_lpm_u2_permit) + p = "u2"; + else + p = "0"; + } + + return sprintf(buf, "%s\n", p); +} + +static ssize_t usb3_lpm_permit_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct usb_port *port_dev = to_usb_port(dev); + struct usb_device *udev = port_dev->child; + struct usb_hcd *hcd; + + if (!strncmp(buf, "u1_u2", 5)) { + port_dev->usb3_lpm_u1_permit = 1; + port_dev->usb3_lpm_u2_permit = 1; + + } else if (!strncmp(buf, "u1", 2)) { + port_dev->usb3_lpm_u1_permit = 1; + port_dev->usb3_lpm_u2_permit = 0; + + } else if (!strncmp(buf, "u2", 2)) { + port_dev->usb3_lpm_u1_permit = 0; + port_dev->usb3_lpm_u2_permit = 1; + + } else if (!strncmp(buf, "0", 1)) { + port_dev->usb3_lpm_u1_permit = 0; + port_dev->usb3_lpm_u2_permit = 0; + } else + return -EINVAL; + + /* If device is connected to the port, disable or enable lpm + * to make new u1 u2 setting take effect immediately. + */ + if (udev) { + hcd = bus_to_hcd(udev->bus); + if (!hcd) + return -EINVAL; + usb_lock_device(udev); + mutex_lock(hcd->bandwidth_mutex); + if (!usb_disable_lpm(udev)) + usb_enable_lpm(udev); + mutex_unlock(hcd->bandwidth_mutex); + usb_unlock_device(udev); + } + + return count; +} +static DEVICE_ATTR_RW(usb3_lpm_permit); + static struct attribute *port_dev_attrs[] = { &dev_attr_connect_type.attr, NULL, @@ -64,6 +130,21 @@ static const struct attribute_group *port_dev_group[] = { NULL, }; +static struct attribute *port_dev_usb3_attrs[] = { + &dev_attr_usb3_lpm_permit.attr, + NULL, +}; + +static struct attribute_group port_dev_usb3_attr_grp = { + .attrs = port_dev_usb3_attrs, +}; + +static const struct attribute_group *port_dev_usb3_group[] = { + &port_dev_attr_grp, + &port_dev_usb3_attr_grp, + NULL, +}; + static void usb_port_device_release(struct device *dev) { struct usb_port *port_dev = to_usb_port(dev); @@ -401,6 +482,7 @@ static void find_and_link_peer(struct usb_hub *hub, int port1) int usb_hub_create_port_device(struct usb_hub *hub, int port1) { struct usb_port *port_dev; + struct usb_device *hdev = hub->hdev; int retval; port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL); @@ -417,7 +499,12 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1) port_dev->portnum = port1; set_bit(port1, hub->power_bits); port_dev->dev.parent = hub->intfdev; - port_dev->dev.groups = port_dev_group; + if (hub_is_superspeed(hdev)) { + port_dev->usb3_lpm_u1_permit = 1; + port_dev->usb3_lpm_u2_permit = 1; + port_dev->dev.groups = port_dev_usb3_group; + } else + port_dev->dev.groups = port_dev_group; port_dev->dev.type = &usb_port_device_type; port_dev->dev.driver = &usb_port_driver; if (hub_is_superspeed(hub->hdev)) -- GitLab From 498378d9d2c12d97318028f1a648d98ee7568430 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Sat, 14 Nov 2015 16:26:34 +0800 Subject: [PATCH 0837/2855] usb: core: lpm: remove usb3_lpm_enabled in usb_device Commit 8306095fd2c1 ("USB: Disable USB 3.0 LPM in critical sections.") adds usb3_lpm_enabled member to struct usb_device. There is no reference to this member now. Hence, it could be removed. Signed-off-by: Lu Baolu Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/linux/usb.h b/include/linux/usb.h index b79925dd2b411..89533ba38691a 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -510,7 +510,6 @@ struct usb3_lpm_parameters { * @usb2_hw_lpm_besl_capable: device can perform USB2 hardware BESL LPM * @usb2_hw_lpm_enabled: USB2 hardware LPM is enabled * @usb2_hw_lpm_allowed: Userspace allows USB 2.0 LPM to be enabled - * @usb3_lpm_enabled: USB3 hardware LPM enabled * @usb3_lpm_u1_enabled: USB3 hardware U1 LPM enabled * @usb3_lpm_u2_enabled: USB3 hardware U2 LPM enabled * @string_langid: language ID for strings @@ -585,7 +584,6 @@ struct usb_device { unsigned usb2_hw_lpm_besl_capable:1; unsigned usb2_hw_lpm_enabled:1; unsigned usb2_hw_lpm_allowed:1; - unsigned usb3_lpm_enabled:1; unsigned usb3_lpm_u1_enabled:1; unsigned usb3_lpm_u2_enabled:1; int string_langid; -- GitLab From c208505900b232ecdc81dee54cb3a032e75d88d6 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:44:08 +1100 Subject: [PATCH 0838/2855] powerpc: create giveup_all() Create a single function that gives everything up (FP, VMX, VSX, SPE). Doing this all at once means we only do one MSR write. A context switch microbenchmark using yield(): http://ozlabs.org/~anton/junkcode/context_switch2.c ./context_switch2 --test=yield --fp --altivec --vector 0 0 shows an improvement of 3% on POWER8. Signed-off-by: Anton Blanchard [mpe: giveup_all() needs to be EXPORT_SYMBOL'ed] Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/switch_to.h | 1 + arch/powerpc/kernel/process.c | 76 ++++++++++++++++++++++------ arch/powerpc/kvm/book3s_pr.c | 17 +------ 3 files changed, 64 insertions(+), 30 deletions(-) diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 9414dcb180d6d..8f856788a7cf1 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -26,6 +26,7 @@ extern void __giveup_vsx(struct task_struct *); extern void giveup_vsx(struct task_struct *); extern void enable_kernel_spe(void); extern void load_up_spe(struct task_struct *); +extern void giveup_all(struct task_struct *); extern void switch_booke_debug_regs(struct debug_reg *new_debug); #ifdef CONFIG_PPC_FPU diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 9f8444b84ddee..4c087b9ed2d64 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -308,6 +308,65 @@ void flush_spe_to_thread(struct task_struct *tsk) } #endif /* CONFIG_SPE */ +static unsigned long msr_all_available; + +static int __init init_msr_all_available(void) +{ +#ifdef CONFIG_PPC_FPU + msr_all_available |= MSR_FP; +#endif +#ifdef CONFIG_ALTIVEC + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + msr_all_available |= MSR_VEC; +#endif +#ifdef CONFIG_VSX + if (cpu_has_feature(CPU_FTR_VSX)) + msr_all_available |= MSR_VSX; +#endif +#ifdef CONFIG_SPE + if (cpu_has_feature(CPU_FTR_SPE)) + msr_all_available |= MSR_SPE; +#endif + + return 0; +} +early_initcall(init_msr_all_available); + +void giveup_all(struct task_struct *tsk) +{ + unsigned long usermsr; + + if (!tsk->thread.regs) + return; + + usermsr = tsk->thread.regs->msr; + + if ((usermsr & msr_all_available) == 0) + return; + + msr_check_and_set(msr_all_available); + +#ifdef CONFIG_PPC_FPU + if (usermsr & MSR_FP) + __giveup_fpu(tsk); +#endif +#ifdef CONFIG_ALTIVEC + if (usermsr & MSR_VEC) + __giveup_altivec(tsk); +#endif +#ifdef CONFIG_VSX + if (usermsr & MSR_VSX) + __giveup_vsx(tsk); +#endif +#ifdef CONFIG_SPE + if (usermsr & MSR_SPE) + __giveup_spe(tsk); +#endif + + msr_check_and_clear(msr_all_available); +} +EXPORT_SYMBOL(giveup_all); + #ifdef CONFIG_PPC_ADV_DEBUG_REGS void do_send_trap(struct pt_regs *regs, unsigned long address, unsigned long error_code, int signal_code, int breakpt) @@ -839,21 +898,8 @@ struct task_struct *__switch_to(struct task_struct *prev, __switch_to_tm(prev); - if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP)) - giveup_fpu(prev); -#ifdef CONFIG_ALTIVEC - if (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) - giveup_altivec(prev); -#endif /* CONFIG_ALTIVEC */ -#ifdef CONFIG_VSX - if (prev->thread.regs && (prev->thread.regs->msr & MSR_VSX)) - /* VMX and FPU registers are already save here */ - __giveup_vsx(prev); -#endif /* CONFIG_VSX */ -#ifdef CONFIG_SPE - if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE))) - giveup_spe(prev); -#endif /* CONFIG_SPE */ + /* Save FPU, Altivec, VSX and SPE state */ + giveup_all(prev); #ifdef CONFIG_PPC_ADV_DEBUG_REGS switch_booke_debug_regs(&new->thread.debug); diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 49f5dad1bd458..a78e0e6bd9326 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c @@ -1490,21 +1490,8 @@ static int kvmppc_vcpu_run_pr(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) goto out; /* interrupts now hard-disabled */ - /* Save FPU state in thread_struct */ - if (current->thread.regs->msr & MSR_FP) - giveup_fpu(current); - -#ifdef CONFIG_ALTIVEC - /* Save Altivec state in thread_struct */ - if (current->thread.regs->msr & MSR_VEC) - giveup_altivec(current); -#endif - -#ifdef CONFIG_VSX - /* Save VSX state in thread_struct */ - if (current->thread.regs->msr & MSR_VSX) - __giveup_vsx(current); -#endif + /* Save FPU, Altivec and VSX state */ + giveup_all(current); /* Preload FPU if it's enabled */ if (kvmppc_get_msr(vcpu) & MSR_FP) -- GitLab From 579e633e764e6e5f7784b74e7df3e81fe11f40de Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:44:09 +1100 Subject: [PATCH 0839/2855] powerpc: create flush_all_to_thread() Create a single function that flushes everything (FP, VMX, VSX, SPE). Doing this all at once means we only do one MSR write. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/switch_to.h | 1 + arch/powerpc/kernel/process.c | 22 ++++++++++++++++++---- arch/powerpc/kernel/swsusp.c | 4 +--- arch/powerpc/kvm/book3s_hv.c | 5 ++--- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 8f856788a7cf1..81d46a433c03e 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -27,6 +27,7 @@ extern void giveup_vsx(struct task_struct *); extern void enable_kernel_spe(void); extern void load_up_spe(struct task_struct *); extern void giveup_all(struct task_struct *); +extern void flush_all_to_thread(struct task_struct *); extern void switch_booke_debug_regs(struct debug_reg *new_debug); #ifdef CONFIG_PPC_FPU diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 4c087b9ed2d64..7f437e7b273e1 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -367,6 +367,23 @@ void giveup_all(struct task_struct *tsk) } EXPORT_SYMBOL(giveup_all); +void flush_all_to_thread(struct task_struct *tsk) +{ + if (tsk->thread.regs) { + preempt_disable(); + BUG_ON(tsk != current); + giveup_all(tsk); + +#ifdef CONFIG_SPE + if (tsk->thread.regs->msr & MSR_SPE) + tsk->thread.spefscr = mfspr(SPRN_SPEFSCR); +#endif + + preempt_enable(); + } +} +EXPORT_SYMBOL(flush_all_to_thread); + #ifdef CONFIG_PPC_ADV_DEBUG_REGS void do_send_trap(struct pt_regs *regs, unsigned long address, unsigned long error_code, int signal_code, int breakpt) @@ -1137,10 +1154,7 @@ release_thread(struct task_struct *t) */ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) { - flush_fp_to_thread(src); - flush_altivec_to_thread(src); - flush_vsx_to_thread(src); - flush_spe_to_thread(src); + flush_all_to_thread(src); /* * Flush TM state out so we can copy it. __switch_to_tm() does this * flush but it removes the checkpointed state from the current CPU and diff --git a/arch/powerpc/kernel/swsusp.c b/arch/powerpc/kernel/swsusp.c index eae33e10b65fb..6669b17525129 100644 --- a/arch/powerpc/kernel/swsusp.c +++ b/arch/powerpc/kernel/swsusp.c @@ -20,9 +20,7 @@ void save_processor_state(void) * flush out all the special registers so we don't need * to save them in the snapshot */ - flush_fp_to_thread(current); - flush_altivec_to_thread(current); - flush_spe_to_thread(current); + flush_all_to_thread(current); #ifdef CONFIG_PPC64 hard_irq_disable(); diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 54b45b73195f9..8e694707bc565 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -2700,9 +2700,8 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu) goto out; } - flush_fp_to_thread(current); - flush_altivec_to_thread(current); - flush_vsx_to_thread(current); + flush_all_to_thread(current); + vcpu->arch.wqp = &vcpu->arch.vcore->wq; vcpu->arch.pgdir = current->mm->pgd; vcpu->arch.state = KVMPPC_VCPU_BUSY_IN_HOST; -- GitLab From f3d885ccba8539f62e8be3ba29ecf91687120252 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:44:10 +1100 Subject: [PATCH 0840/2855] powerpc: Rearrange __switch_to() Most of __switch_to() is housekeeping, TLB batching, timekeeping etc. Move these away from the more complex and critical context switching code. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/process.c | 52 +++++++++++++++++------------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 7f437e7b273e1..49424dc1168d9 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -907,30 +907,6 @@ struct task_struct *__switch_to(struct task_struct *prev, WARN_ON(!irqs_disabled()); - /* - * We need to save SPRs before treclaim/trecheckpoint as these will - * change a number of them. - */ - save_sprs(&prev->thread); - - __switch_to_tm(prev); - - /* Save FPU, Altivec, VSX and SPE state */ - giveup_all(prev); - -#ifdef CONFIG_PPC_ADV_DEBUG_REGS - switch_booke_debug_regs(&new->thread.debug); -#else -/* - * For PPC_BOOK3S_64, we use the hw-breakpoint interfaces that would - * schedule DABR - */ -#ifndef CONFIG_HAVE_HW_BREAKPOINT - if (unlikely(!hw_brk_match(this_cpu_ptr(¤t_brk), &new->thread.hw_brk))) - __set_breakpoint(&new->thread.hw_brk); -#endif /* CONFIG_HAVE_HW_BREAKPOINT */ -#endif - #ifdef CONFIG_PPC64 /* * Collect processor utilization data per process @@ -955,6 +931,30 @@ struct task_struct *__switch_to(struct task_struct *prev, } #endif /* CONFIG_PPC_BOOK3S_64 */ +#ifdef CONFIG_PPC_ADV_DEBUG_REGS + switch_booke_debug_regs(&new->thread.debug); +#else +/* + * For PPC_BOOK3S_64, we use the hw-breakpoint interfaces that would + * schedule DABR + */ +#ifndef CONFIG_HAVE_HW_BREAKPOINT + if (unlikely(!hw_brk_match(this_cpu_ptr(¤t_brk), &new->thread.hw_brk))) + __set_breakpoint(&new->thread.hw_brk); +#endif /* CONFIG_HAVE_HW_BREAKPOINT */ +#endif + + /* + * We need to save SPRs before treclaim/trecheckpoint as these will + * change a number of them. + */ + save_sprs(&prev->thread); + + __switch_to_tm(prev); + + /* Save FPU, Altivec, VSX and SPE state */ + giveup_all(prev); + /* * We can't take a PMU exception inside _switch() since there is a * window where the kernel stack SLB and the kernel stack are out @@ -970,6 +970,8 @@ struct task_struct *__switch_to(struct task_struct *prev, old_thread = &last->thread; new_thread = ¤t->thread; + restore_sprs(old_thread, new_thread); + #ifdef CONFIG_PPC_BOOK3S_64 if (current_thread_info()->local_flags & _TLF_LAZY_MMU) { current_thread_info()->local_flags &= ~_TLF_LAZY_MMU; @@ -978,8 +980,6 @@ struct task_struct *__switch_to(struct task_struct *prev, } #endif /* CONFIG_PPC_BOOK3S_64 */ - restore_sprs(old_thread, new_thread); - return last; } -- GitLab From d1e1cf2e38def301fde42c1a33f896f974941d7b Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 29 Oct 2015 11:44:11 +1100 Subject: [PATCH 0841/2855] powerpc: clean up asm/switch_to.h Remove a bunch of unnecessary fallback functions and group things in a more logical way. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/switch_to.h | 35 ++++++++-------------------- arch/powerpc/kernel/process.c | 2 +- 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 81d46a433c03e..5b268b6be74c7 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -14,23 +14,18 @@ extern struct task_struct *__switch_to(struct task_struct *, struct task_struct *); #define switch_to(prev, next, last) ((last) = __switch_to((prev), (next))) -struct thread_struct; extern struct task_struct *_switch(struct thread_struct *prev, struct thread_struct *next); -extern void enable_kernel_fp(void); -extern void enable_kernel_altivec(void); -extern void enable_kernel_vsx(void); +extern void switch_booke_debug_regs(struct debug_reg *new_debug); + extern int emulate_altivec(struct pt_regs *); -extern void __giveup_vsx(struct task_struct *); -extern void giveup_vsx(struct task_struct *); -extern void enable_kernel_spe(void); -extern void load_up_spe(struct task_struct *); -extern void giveup_all(struct task_struct *); + extern void flush_all_to_thread(struct task_struct *); -extern void switch_booke_debug_regs(struct debug_reg *new_debug); +extern void giveup_all(struct task_struct *); #ifdef CONFIG_PPC_FPU +extern void enable_kernel_fp(void); extern void flush_fp_to_thread(struct task_struct *); extern void giveup_fpu(struct task_struct *); extern void __giveup_fpu(struct task_struct *); @@ -38,14 +33,12 @@ static inline void disable_kernel_fp(void) { msr_check_and_clear(MSR_FP); } - #else static inline void flush_fp_to_thread(struct task_struct *t) { } -static inline void giveup_fpu(struct task_struct *t) { } -static inline void __giveup_fpu(struct task_struct *t) { } #endif #ifdef CONFIG_ALTIVEC +extern void enable_kernel_altivec(void); extern void flush_altivec_to_thread(struct task_struct *); extern void giveup_altivec(struct task_struct *); extern void __giveup_altivec(struct task_struct *); @@ -53,25 +46,21 @@ static inline void disable_kernel_altivec(void) { msr_check_and_clear(MSR_VEC); } -#else -static inline void flush_altivec_to_thread(struct task_struct *t) { } -static inline void giveup_altivec(struct task_struct *t) { } -static inline void __giveup_altivec(struct task_struct *t) { } #endif #ifdef CONFIG_VSX +extern void enable_kernel_vsx(void); extern void flush_vsx_to_thread(struct task_struct *); +extern void giveup_vsx(struct task_struct *); +extern void __giveup_vsx(struct task_struct *); static inline void disable_kernel_vsx(void) { msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX); } -#else -static inline void flush_vsx_to_thread(struct task_struct *t) -{ -} #endif #ifdef CONFIG_SPE +extern void enable_kernel_spe(void); extern void flush_spe_to_thread(struct task_struct *); extern void giveup_spe(struct task_struct *); extern void __giveup_spe(struct task_struct *); @@ -79,10 +68,6 @@ static inline void disable_kernel_spe(void) { msr_check_and_clear(MSR_SPE); } -#else -static inline void flush_spe_to_thread(struct task_struct *t) { } -static inline void giveup_spe(struct task_struct *t) { } -static inline void __giveup_spe(struct task_struct *t) { } #endif static inline void clear_task_ebb(struct task_struct *t) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 49424dc1168d9..58194c3f421ea 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -174,7 +174,6 @@ void flush_fp_to_thread(struct task_struct *tsk) } } EXPORT_SYMBOL_GPL(flush_fp_to_thread); -#endif /* CONFIG_PPC_FPU */ void enable_kernel_fp(void) { @@ -186,6 +185,7 @@ void enable_kernel_fp(void) __giveup_fpu(current); } EXPORT_SYMBOL(enable_kernel_fp); +#endif /* CONFIG_PPC_FPU */ #ifdef CONFIG_ALTIVEC void giveup_altivec(struct task_struct *tsk) -- GitLab From 73e7d63efb4d774883a338997943bfa59e127085 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 1 Dec 2015 12:41:38 +0100 Subject: [PATCH 0842/2855] HID: multitouch: fix input mode switching on some Elan panels as reported by https://bugzilla.kernel.org/show_bug.cgi?id=108481 This bug reports mentions 6d4f5440 ("HID: multitouch: Fetch feature reports on demand for Win8 devices") as the origin of the problem but this commit actually masked 2 firmware bugs that are annihilating each other: The report descriptor declares two features in reports 3 and 5: 0x05, 0x0d, // Usage Page (Digitizers) 318 0x09, 0x0e, // Usage (Device Configuration) 320 0xa1, 0x01, // Collection (Application) 322 0x85, 0x03, // Report ID (3) 324 0x09, 0x22, // Usage (Finger) 326 0xa1, 0x00, // Collection (Physical) 328 0x09, 0x52, // Usage (Inputmode) 330 0x15, 0x00, // Logical Minimum (0) 332 0x25, 0x0a, // Logical Maximum (10) 334 0x75, 0x08, // Report Size (8) 336 0x95, 0x02, // Report Count (2) 338 0xb1, 0x02, // Feature (Data,Var,Abs) 340 0xc0, // End Collection 342 0x09, 0x22, // Usage (Finger) 343 0xa1, 0x00, // Collection (Physical) 345 0x85, 0x05, // Report ID (5) 347 0x09, 0x57, // Usage (Surface Switch) 349 0x09, 0x58, // Usage (Button Switch) 351 0x15, 0x00, // Logical Minimum (0) 353 0x75, 0x01, // Report Size (1) 355 0x95, 0x02, // Report Count (2) 357 0x25, 0x03, // Logical Maximum (3) 359 0xb1, 0x02, // Feature (Data,Var,Abs) 361 0x95, 0x0e, // Report Count (14) 363 0xb1, 0x03, // Feature (Cnst,Var,Abs) 365 0xc0, // End Collection 367 The report ID 3 presents 2 input mode features, while only the first one is handled by the device. Given that we did not checked if one was previously assigned, we were dealing with the ignored featured and we should never have been able to switch this panel into the multitouch mode. However, the firmware presents an other bugs which allowed 6d4f5440 to counteract the faulty report descriptor. When we request the values of the feature 5, the firmware answers "03 03 00". The fields are correct but the report id is wrong. Before 6d4f5440, we retrieved all the features and injected them in the system. So when we called report 5, we injected in the system the report 3 with the values "03 00". Setting the second input mode to 03 in this report changed it to "03 03" and the touchpad switched to the mt mode. We could have set anything in the second field because the actual value (the first 03 in this report) was given by the query of report ID 5. To sum up: 2 bugs in the firmware were hiding that we were accessing the wrong feature. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 351ddd297792c..4ee771642090d 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -357,8 +357,19 @@ static void mt_feature_mapping(struct hid_device *hdev, break; } - td->inputmode = field->report->id; - td->inputmode_index = usage->usage_index; + if (td->inputmode < 0) { + td->inputmode = field->report->id; + td->inputmode_index = usage->usage_index; + } else { + /* + * Some elan panels wrongly declare 2 input mode + * features, and silently ignore when we set the + * value in the second field. Skip the second feature + * and hope for the best. + */ + dev_info(&hdev->dev, + "Ignoring the extra HID_DG_INPUTMODE\n"); + } break; case HID_DG_CONTACTMAX: -- GitLab From 49a6bb7a1c0963f260e4b0dcc2c0e56ec65a28b2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 1 Dec 2015 15:51:52 +0000 Subject: [PATCH 0843/2855] regulator: core: Ensure we lock all regulators The latest workaround for the lockdep interface's not using the second argument of mutex_lock_nested() changed the loop missed locking the last regulator due to a thinko with the loop termination condition exiting one regulator too soon. Reported-by: Tyler Baker Signed-off-by: Mark Brown --- drivers/regulator/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index daffff83ced2a..f71db02fcb713 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -141,7 +141,7 @@ static void regulator_lock_supply(struct regulator_dev *rdev) int i; mutex_lock(&rdev->mutex); - for (i = 1; rdev->supply; rdev = rdev->supply->rdev, i++) + for (i = 1; rdev; rdev = rdev->supply->rdev, i++) mutex_lock_nested(&rdev->mutex, i); } -- GitLab From 70a7fb80e85ae7f78f8e90cec3fbd862ea6a4d4b Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 2 Dec 2015 16:54:50 +0100 Subject: [PATCH 0844/2855] regulator: core: Fix nested locking of supplies Commit fa731ac7ea04 ("regulator: core: avoid unused variable warning") introduced a subtle change in how supplies are locked. Where previously code was always locking the regulator of the current iteration, the new implementation only locks the regulator if it has a supply. For any given power tree that means that the root will never get locked. On the other hand the regulator_unlock_supply() will still release all the locks, which in turn causes the lock debugging code to warn about a mutex being unlocked which wasn't locked. Cc: Mark Brown Cc: Arnd Bergmann Fixes: Fixes: fa731ac7ea04 ("regulator: core: avoid unused variable warning") Signed-off-by: Thierry Reding Signed-off-by: Mark Brown --- drivers/regulator/core.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index f71db02fcb713..732ac71b82cdd 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -132,6 +132,14 @@ static bool have_full_constraints(void) return has_full_constraints || of_have_populated_dt(); } +static inline struct regulator_dev *rdev_get_supply(struct regulator_dev *rdev) +{ + if (rdev && rdev->supply) + return rdev->supply->rdev; + + return NULL; +} + /** * regulator_lock_supply - lock a regulator and its supplies * @rdev: regulator source @@ -140,8 +148,7 @@ static void regulator_lock_supply(struct regulator_dev *rdev) { int i; - mutex_lock(&rdev->mutex); - for (i = 1; rdev; rdev = rdev->supply->rdev, i++) + for (i = 0; rdev; rdev = rdev_get_supply(rdev), i++) mutex_lock_nested(&rdev->mutex, i); } -- GitLab From d352c0e1f32e168e20d14d666a73f3712fbdc1f5 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 2 Dec 2015 09:28:03 -0800 Subject: [PATCH 0845/2855] Input: sparcspkr - use platform_register/unregister_drivers() These new helpers simplify implementing multi-driver modules and properly handle failure to register one driver by unregistering all previously registered drivers. Signed-off-by: Thierry Reding Signed-off-by: Dmitry Torokhov --- drivers/input/misc/sparcspkr.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index 6f997aa49183a..4a5afc7fe96ea 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c @@ -345,23 +345,19 @@ static struct platform_driver grover_beep_driver = { .shutdown = sparcspkr_shutdown, }; +static struct platform_driver * const drivers[] = { + &bbc_beep_driver, + &grover_beep_driver, +}; + static int __init sparcspkr_init(void) { - int err = platform_driver_register(&bbc_beep_driver); - - if (!err) { - err = platform_driver_register(&grover_beep_driver); - if (err) - platform_driver_unregister(&bbc_beep_driver); - } - - return err; + return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); } static void __exit sparcspkr_exit(void) { - platform_driver_unregister(&bbc_beep_driver); - platform_driver_unregister(&grover_beep_driver); + platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); } module_init(sparcspkr_init); -- GitLab From 78f16dbda5eee2f9379a6313cd01792160e2ec70 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 27 Nov 2015 14:52:51 +0100 Subject: [PATCH 0846/2855] iio: adc: mcp3422: Add mcp3421 support The mcp3421 is the single channel variant of the mcp342x family. Support is straight forward, only the channels array has to be added for this chip. Signed-off-by: Sascha Hauer Signed-off-by: Jonathan Cameron --- drivers/iio/adc/mcp3422.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/iio/adc/mcp3422.c b/drivers/iio/adc/mcp3422.c index 3555122008b44..6eca7aea8a374 100644 --- a/drivers/iio/adc/mcp3422.c +++ b/drivers/iio/adc/mcp3422.c @@ -305,6 +305,10 @@ static const struct attribute_group mcp3422_attribute_group = { .attrs = mcp3422_attributes, }; +static const struct iio_chan_spec mcp3421_channels[] = { + MCP3422_CHAN(0), +}; + static const struct iio_chan_spec mcp3422_channels[] = { MCP3422_CHAN(0), MCP3422_CHAN(1), @@ -352,6 +356,10 @@ static int mcp3422_probe(struct i2c_client *client, indio_dev->info = &mcp3422_info; switch (adc->id) { + case 1: + indio_dev->channels = mcp3421_channels; + indio_dev->num_channels = ARRAY_SIZE(mcp3421_channels); + break; case 2: case 3: case 6: @@ -383,6 +391,7 @@ static int mcp3422_probe(struct i2c_client *client, } static const struct i2c_device_id mcp3422_id[] = { + { "mcp3421", 1 }, { "mcp3422", 2 }, { "mcp3423", 3 }, { "mcp3424", 4 }, -- GitLab From 930cc0f39b07a830e6939c5634f9a310f306c4b1 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 27 Nov 2015 14:52:52 +0100 Subject: [PATCH 0847/2855] dt-bindings: iio: adc: Update mcp342x binding for the mcp3421 The mcp3421 is the single channel variant of the mcp342x family and can be supported by the mcp342x driver. Signed-off-by: Sascha Hauer Cc: devicetree@vger.kernel.org Acked-by: Rob Herring Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/adc/mcp3422.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/iio/adc/mcp3422.txt b/Documentation/devicetree/bindings/iio/adc/mcp3422.txt index 333139cc0bfb3..dcae4ccfcc528 100644 --- a/Documentation/devicetree/bindings/iio/adc/mcp3422.txt +++ b/Documentation/devicetree/bindings/iio/adc/mcp3422.txt @@ -1,7 +1,8 @@ -* Microchip mcp3422/3/4/6/7/8 chip family (ADC) +* Microchip mcp3421/2/3/4/6/7/8 chip family (ADC) Required properties: - compatible: Should be + "microchip,mcp3421" or "microchip,mcp3422" or "microchip,mcp3423" or "microchip,mcp3424" or -- GitLab From c3304c212326cfcabb1faf6a0035d0c631778d5b Mon Sep 17 00:00:00 2001 From: Adriana Reus Date: Tue, 24 Nov 2015 12:59:48 +0200 Subject: [PATCH 0848/2855] iio: light: us5182d: Add property for choosing default power mode This chip supports two power modes. 1. "one-shot" mode - the chip activates and executes one complete conversion loop and then shuts itself down. This is the default mode chosen for raw reads. 2. "continuous" mode - the chip takes continuous measurements. Continuous mode is more expensive power-wise but may be more reliable. Add a property so that if preferred, the default power mode for raw reads can be set to continuous. Separate one-shot enabling in a separate function that will be used depending on the chosen power mode. Also create a function for powering the chip on and off. Signed-off-by: Adriana Reus Signed-off-by: Jonathan Cameron --- drivers/iio/light/us5182d.c | 90 ++++++++++++++++++++++++++++++++----- 1 file changed, 78 insertions(+), 12 deletions(-) diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c index 49dab3cb3e239..855f183ba216b 100644 --- a/drivers/iio/light/us5182d.c +++ b/drivers/iio/light/us5182d.c @@ -99,6 +99,11 @@ enum mode { US5182D_PX_ONLY }; +enum pmode { + US5182D_CONTINUOUS, + US5182D_ONESHOT +}; + struct us5182d_data { struct i2c_client *client; struct mutex lock; @@ -112,6 +117,9 @@ struct us5182d_data { u16 *us5182d_dark_ths; u8 opmode; + u8 power_mode; + + bool default_continuous; }; static IIO_CONST_ATTR(in_illuminance_scale_available, @@ -130,13 +138,11 @@ static const struct { u8 reg; u8 val; } us5182d_regvals[] = { - {US5182D_REG_CFG0, (US5182D_CFG0_SHUTDOWN_EN | - US5182D_CFG0_WORD_ENABLE)}, + {US5182D_REG_CFG0, US5182D_CFG0_WORD_ENABLE}, {US5182D_REG_CFG1, US5182D_CFG1_ALS_RES16}, {US5182D_REG_CFG2, (US5182D_CFG2_PX_RES16 | US5182D_CFG2_PXGAIN_DEFAULT)}, {US5182D_REG_CFG3, US5182D_CFG3_LED_CURRENT100}, - {US5182D_REG_MODE_STORE, US5182D_STORE_MODE}, {US5182D_REG_CFG4, 0x00}, }; @@ -169,7 +175,7 @@ static int us5182d_get_als(struct us5182d_data *data) return result; } -static int us5182d_set_opmode(struct us5182d_data *data, u8 mode) +static int us5182d_oneshot_en(struct us5182d_data *data) { int ret; @@ -183,6 +189,20 @@ static int us5182d_set_opmode(struct us5182d_data *data, u8 mode) */ ret = ret | US5182D_CFG0_ONESHOT_EN; + return i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret); +} + +static int us5182d_set_opmode(struct us5182d_data *data, u8 mode) +{ + int ret; + + if (mode == data->opmode) + return 0; + + ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0); + if (ret < 0) + return ret; + /* update mode */ ret = ret & ~US5182D_OPMODE_MASK; ret = ret | (mode << US5182D_OPMODE_SHIFT); @@ -196,9 +216,6 @@ static int us5182d_set_opmode(struct us5182d_data *data, u8 mode) if (ret < 0) return ret; - if (mode == data->opmode) - return 0; - ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_MODE_STORE, US5182D_STORE_MODE); if (ret < 0) @@ -210,6 +227,23 @@ static int us5182d_set_opmode(struct us5182d_data *data, u8 mode) return 0; } +static int us5182d_shutdown_en(struct us5182d_data *data, u8 state) +{ + int ret; + + if (data->power_mode == US5182D_ONESHOT) + return 0; + + ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0); + if (ret < 0) + return ret; + + ret = ret & ~US5182D_CFG0_SHUTDOWN_EN; + ret = ret | state; + + return i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret); +} + static int us5182d_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -222,6 +256,11 @@ static int us5182d_read_raw(struct iio_dev *indio_dev, switch (chan->type) { case IIO_LIGHT: mutex_lock(&data->lock); + if (data->power_mode == US5182D_ONESHOT) { + ret = us5182d_oneshot_en(data); + if (ret < 0) + goto out_err; + } ret = us5182d_set_opmode(data, US5182D_OPMODE_ALS); if (ret < 0) goto out_err; @@ -234,6 +273,11 @@ static int us5182d_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT; case IIO_PROXIMITY: mutex_lock(&data->lock); + if (data->power_mode == US5182D_ONESHOT) { + ret = us5182d_oneshot_en(data); + if (ret < 0) + goto out_err; + } ret = us5182d_set_opmode(data, US5182D_OPMODE_PX); if (ret < 0) goto out_err; @@ -368,6 +412,7 @@ static int us5182d_init(struct iio_dev *indio_dev) return ret; data->opmode = 0; + data->power_mode = US5182D_CONTINUOUS; for (i = 0; i < ARRAY_SIZE(us5182d_regvals); i++) { ret = i2c_smbus_write_byte_data(data->client, us5182d_regvals[i].reg, @@ -376,7 +421,15 @@ static int us5182d_init(struct iio_dev *indio_dev) return ret; } - return 0; + if (!data->default_continuous) { + ret = us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN); + if (ret < 0) + return ret; + data->power_mode = US5182D_ONESHOT; + } + + + return ret; } static void us5182d_get_platform_data(struct iio_dev *indio_dev) @@ -399,6 +452,8 @@ static void us5182d_get_platform_data(struct iio_dev *indio_dev) "upisemi,lower-dark-gain", &data->lower_dark_gain)) data->lower_dark_gain = US5182D_REG_AUTO_LDARK_GAIN_DEFAULT; + data->default_continuous = device_property_read_bool(&data->client->dev, + "upisemi,continuous"); } static int us5182d_dark_gain_config(struct iio_dev *indio_dev) @@ -464,16 +519,27 @@ static int us5182d_probe(struct i2c_client *client, ret = us5182d_dark_gain_config(indio_dev); if (ret < 0) - return ret; + goto out_err; + + ret = iio_device_register(indio_dev); + if (ret < 0) + goto out_err; + + return 0; + +out_err: + us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN); + return ret; - return iio_device_register(indio_dev); } static int us5182d_remove(struct i2c_client *client) { + struct us5182d_data *data = iio_priv(i2c_get_clientdata(client)); + iio_device_unregister(i2c_get_clientdata(client)); - return i2c_smbus_write_byte_data(client, US5182D_REG_CFG0, - US5182D_CFG0_SHUTDOWN_EN); + + return us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN); } static const struct acpi_device_id us5182d_acpi_match[] = { -- GitLab From 023e30fb0d3a3b9d6b8dc9e47590aa544d58a22f Mon Sep 17 00:00:00 2001 From: Adriana Reus Date: Tue, 24 Nov 2015 12:59:49 +0200 Subject: [PATCH 0849/2855] Documentation: devicetree: Add property for controlling power saving mode for the us5182 als sensor Add a property to allow changing the default power-saving mode. By default, at read raw the chip will activate and provide one measurent, then it will shut itself down. However, the chip can also work in "continuous" mode which may be more reliable but is also more power consuming. Signed-off-by: Adriana Reus Acked-by: Rob Herring Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/light/us5182d.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/light/us5182d.txt b/Documentation/devicetree/bindings/iio/light/us5182d.txt index 6f0a530144fde..a61979997f373 100644 --- a/Documentation/devicetree/bindings/iio/light/us5182d.txt +++ b/Documentation/devicetree/bindings/iio/light/us5182d.txt @@ -7,13 +7,24 @@ Required properties: Optional properties: - upisemi,glass-coef: glass attenuation factor - compensation factor of resolution 1000 for material transmittance. + - upisemi,dark-ths: array of 8 elements containing 16-bit thresholds (adc counts) corresponding to every scale. + - upisemi,upper-dark-gain: 8-bit dark gain compensation factor(4 int and 4 fractional bits - Q4.4) applied when light > threshold + - upisemi,lower-dark-gain: 8-bit dark gain compensation factor(4 int and 4 fractional bits - Q4.4) applied when light < threshold +- upisemi,continuous: This chip has two power modes: one-shot (chip takes one + measurement and then shuts itself down) and continuous ( + chip takes continuous measurements). The one-shot mode is + more power-friendly but the continuous mode may be more + reliable. If this property is specified the continuous + mode will be used instead of the default one-shot one for + raw reads. + If the optional properties are not specified these factors will default to the values in the below example. The glass-coef defaults to no compensation for the covering material. -- GitLab From a22a3c5c40deb31f03c2810a46e669bedbf476c5 Mon Sep 17 00:00:00 2001 From: Adriana Reus Date: Tue, 24 Nov 2015 12:59:50 +0200 Subject: [PATCH 0850/2855] iio: light: us5182d: Add functions for selectively enabling als and proximity Keep track of the als and px enabled/disabled status in order to enable them selectively. Signed-off-by: Adriana Reus Signed-off-by: Jonathan Cameron --- drivers/iio/light/us5182d.c | 66 ++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c index 855f183ba216b..e67956c1f2966 100644 --- a/drivers/iio/light/us5182d.c +++ b/drivers/iio/light/us5182d.c @@ -119,6 +119,9 @@ struct us5182d_data { u8 opmode; u8 power_mode; + bool als_enabled; + bool px_enabled; + bool default_continuous; }; @@ -227,6 +230,50 @@ static int us5182d_set_opmode(struct us5182d_data *data, u8 mode) return 0; } +static int us5182d_als_enable(struct us5182d_data *data) +{ + int ret; + u8 mode; + + if (data->power_mode == US5182D_ONESHOT) + return us5182d_set_opmode(data, US5182D_ALS_ONLY); + + if (data->als_enabled) + return 0; + + mode = data->px_enabled ? US5182D_ALS_PX : US5182D_ALS_ONLY; + + ret = us5182d_set_opmode(data, mode); + if (ret < 0) + return ret; + + data->als_enabled = true; + + return 0; +} + +static int us5182d_px_enable(struct us5182d_data *data) +{ + int ret; + u8 mode; + + if (data->power_mode == US5182D_ONESHOT) + return us5182d_set_opmode(data, US5182D_PX_ONLY); + + if (data->px_enabled) + return 0; + + mode = data->als_enabled ? US5182D_ALS_PX : US5182D_PX_ONLY; + + ret = us5182d_set_opmode(data, mode); + if (ret < 0) + return ret; + + data->px_enabled = true; + + return 0; +} + static int us5182d_shutdown_en(struct us5182d_data *data, u8 state) { int ret; @@ -241,7 +288,16 @@ static int us5182d_shutdown_en(struct us5182d_data *data, u8 state) ret = ret & ~US5182D_CFG0_SHUTDOWN_EN; ret = ret | state; - return i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret); + ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret); + if (ret < 0) + return ret; + + if (state & US5182D_CFG0_SHUTDOWN_EN) { + data->als_enabled = false; + data->px_enabled = false; + } + + return ret; } static int us5182d_read_raw(struct iio_dev *indio_dev, @@ -261,7 +317,7 @@ static int us5182d_read_raw(struct iio_dev *indio_dev, if (ret < 0) goto out_err; } - ret = us5182d_set_opmode(data, US5182D_OPMODE_ALS); + ret = us5182d_als_enable(data); if (ret < 0) goto out_err; @@ -278,7 +334,7 @@ static int us5182d_read_raw(struct iio_dev *indio_dev, if (ret < 0) goto out_err; } - ret = us5182d_set_opmode(data, US5182D_OPMODE_PX); + ret = us5182d_px_enable(data); if (ret < 0) goto out_err; @@ -421,6 +477,9 @@ static int us5182d_init(struct iio_dev *indio_dev) return ret; } + data->als_enabled = true; + data->px_enabled = true; + if (!data->default_continuous) { ret = us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN); if (ret < 0) @@ -428,7 +487,6 @@ static int us5182d_init(struct iio_dev *indio_dev) data->power_mode = US5182D_ONESHOT; } - return ret; } -- GitLab From f0e5f57d3ac25aa2afb25dc94d2b42a8defa8a19 Mon Sep 17 00:00:00 2001 From: Adriana Reus Date: Tue, 24 Nov 2015 12:59:51 +0200 Subject: [PATCH 0851/2855] iio: light: us8152d: Add power management support Add power management for sleep as well as runtime pm. Signed-off-by: Adriana Reus Signed-off-by: Jonathan Cameron --- drivers/iio/light/us5182d.c | 95 ++++++++++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 7 deletions(-) diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c index e67956c1f2966..256c4bc12d219 100644 --- a/drivers/iio/light/us5182d.c +++ b/drivers/iio/light/us5182d.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #define US5182D_REG_CFG0 0x00 #define US5182D_CFG0_ONESHOT_EN BIT(6) @@ -81,6 +83,7 @@ #define US5182D_READ_BYTE 1 #define US5182D_READ_WORD 2 #define US5182D_OPSTORE_SLEEP_TIME 20 /* ms */ +#define US5182D_SLEEP_MS 3000 /* ms */ /* Available ranges: [12354, 7065, 3998, 2202, 1285, 498, 256, 138] lux */ static const int us5182d_scales[] = {188500, 107800, 61000, 33600, 19600, 7600, @@ -300,6 +303,26 @@ static int us5182d_shutdown_en(struct us5182d_data *data, u8 state) return ret; } + +static int us5182d_set_power_state(struct us5182d_data *data, bool on) +{ + int ret; + + if (data->power_mode == US5182D_ONESHOT) + return 0; + + if (on) { + ret = pm_runtime_get_sync(&data->client->dev); + if (ret < 0) + pm_runtime_put_noidle(&data->client->dev); + } else { + pm_runtime_mark_last_busy(&data->client->dev); + ret = pm_runtime_put_autosuspend(&data->client->dev); + } + + return ret; +} + static int us5182d_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -317,15 +340,20 @@ static int us5182d_read_raw(struct iio_dev *indio_dev, if (ret < 0) goto out_err; } - ret = us5182d_als_enable(data); + ret = us5182d_set_power_state(data, true); if (ret < 0) goto out_err; - + ret = us5182d_als_enable(data); + if (ret < 0) + goto out_poweroff; ret = us5182d_get_als(data); + if (ret < 0) + goto out_poweroff; + *val = ret; + ret = us5182d_set_power_state(data, false); if (ret < 0) goto out_err; mutex_unlock(&data->lock); - *val = ret; return IIO_VAL_INT; case IIO_PROXIMITY: mutex_lock(&data->lock); @@ -334,17 +362,22 @@ static int us5182d_read_raw(struct iio_dev *indio_dev, if (ret < 0) goto out_err; } - ret = us5182d_px_enable(data); + ret = us5182d_set_power_state(data, true); if (ret < 0) goto out_err; - + ret = us5182d_px_enable(data); + if (ret < 0) + goto out_poweroff; ret = i2c_smbus_read_word_data(data->client, US5182D_REG_PDL); + if (ret < 0) + goto out_poweroff; + *val = ret; + ret = us5182d_set_power_state(data, false); if (ret < 0) goto out_err; mutex_unlock(&data->lock); - *val = ret; - return IIO_VAL_INT; + return IIO_VAL_INT; default: return -EINVAL; } @@ -363,6 +396,9 @@ static int us5182d_read_raw(struct iio_dev *indio_dev, } return -EINVAL; + +out_poweroff: + us5182d_set_power_state(data, false); out_err: mutex_unlock(&data->lock); return ret; @@ -579,6 +615,17 @@ static int us5182d_probe(struct i2c_client *client, if (ret < 0) goto out_err; + if (data->default_continuous) { + pm_runtime_set_active(&client->dev); + if (ret < 0) + goto out_err; + } + + pm_runtime_enable(&client->dev); + pm_runtime_set_autosuspend_delay(&client->dev, + US5182D_SLEEP_MS); + pm_runtime_use_autosuspend(&client->dev); + ret = iio_device_register(indio_dev); if (ret < 0) goto out_err; @@ -597,9 +644,42 @@ static int us5182d_remove(struct i2c_client *client) iio_device_unregister(i2c_get_clientdata(client)); + pm_runtime_disable(&client->dev); + pm_runtime_set_suspended(&client->dev); + return us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN); } +#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM) +static int us5182d_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + struct us5182d_data *data = iio_priv(indio_dev); + + if (data->power_mode == US5182D_CONTINUOUS) + return us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN); + + return 0; +} + +static int us5182d_resume(struct device *dev) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + struct us5182d_data *data = iio_priv(indio_dev); + + if (data->power_mode == US5182D_CONTINUOUS) + return us5182d_shutdown_en(data, + ~US5182D_CFG0_SHUTDOWN_EN & 0xff); + + return 0; +} +#endif + +static const struct dev_pm_ops us5182d_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(us5182d_suspend, us5182d_resume) + SET_RUNTIME_PM_OPS(us5182d_suspend, us5182d_resume, NULL) +}; + static const struct acpi_device_id us5182d_acpi_match[] = { { "USD5182", 0}, {} @@ -617,6 +697,7 @@ MODULE_DEVICE_TABLE(i2c, us5182d_id); static struct i2c_driver us5182d_driver = { .driver = { .name = US5182D_DRV_NAME, + .pm = &us5182d_pm_ops, .acpi_match_table = ACPI_PTR(us5182d_acpi_match), }, .probe = us5182d_probe, -- GitLab From 22b19ab3e2d6da666be816e649af67bf721b8561 Mon Sep 17 00:00:00 2001 From: Nizam Haider Date: Mon, 23 Nov 2015 23:03:07 +0530 Subject: [PATCH 0852/2855] Staging: iio: adc: use dev_get_platdata() Use the wrapper function for retrieving the platform data instead of accessing dev->platform_data directly. Signed-off-by: Nizam Haider Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7192.c | 2 +- drivers/staging/iio/adc/ad7280a.c | 2 +- drivers/staging/iio/adc/ad7816.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index bb40f37287426..92211039ffa94 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -609,7 +609,7 @@ static const struct iio_chan_spec ad7192_channels[] = { static int ad7192_probe(struct spi_device *spi) { - const struct ad7192_platform_data *pdata = spi->dev.platform_data; + const struct ad7192_platform_data *pdata = dev_get_platdata(&spi->dev); struct ad7192_state *st; struct iio_dev *indio_dev; int ret, voltage_uv = 0; diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c index 35acb1a4669b3..f45ebedb7a056 100644 --- a/drivers/staging/iio/adc/ad7280a.c +++ b/drivers/staging/iio/adc/ad7280a.c @@ -833,7 +833,7 @@ static const struct ad7280_platform_data ad7793_default_pdata = { static int ad7280_probe(struct spi_device *spi) { - const struct ad7280_platform_data *pdata = spi->dev.platform_data; + const struct ad7280_platform_data *pdata = dev_get_platdata(&spi->dev); struct ad7280_state *st; int ret; const unsigned short tACQ_ns[4] = {465, 1010, 1460, 1890}; diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c index c8e1566465285..22260512cf01e 100644 --- a/drivers/staging/iio/adc/ad7816.c +++ b/drivers/staging/iio/adc/ad7816.c @@ -345,7 +345,7 @@ static int ad7816_probe(struct spi_device *spi_dev) { struct ad7816_chip_info *chip; struct iio_dev *indio_dev; - unsigned short *pins = spi_dev->dev.platform_data; + unsigned short *pins = dev_get_platdata(&spi_dev->dev); int ret = 0; int i; -- GitLab From a260527f83dfebe7c49bd6582ed6aa1be29f355a Mon Sep 17 00:00:00 2001 From: Nizam Haider Date: Mon, 23 Nov 2015 23:18:50 +0530 Subject: [PATCH 0853/2855] Staging: iio: light: tsl2x7x_core: use dev_get_platdata() Use the wrapper function for retrieving the platform data instead of accessing dev->platform_data directly. Signed-off-by: Nizam Haider Signed-off-by: Jonathan Cameron --- drivers/staging/iio/light/tsl2x7x_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index 9dfd04855a1b0..5b1c1650a0e4a 100644 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -1898,7 +1898,7 @@ static int tsl2x7x_probe(struct i2c_client *clientp, mutex_init(&chip->prox_mutex); chip->tsl2x7x_chip_status = TSL2X7X_CHIP_UNKNOWN; - chip->pdata = clientp->dev.platform_data; + chip->pdata = dev_get_platdata(&clientp->dev); chip->id = id->driver_data; chip->chip_info = &tsl2x7x_chip_info_tbl[device_channel_config[id->driver_data]]; -- GitLab From 7221819ac48195ea9f1e179c3f812939319d9e7b Mon Sep 17 00:00:00 2001 From: Nizam Haider Date: Mon, 23 Nov 2015 23:37:16 +0530 Subject: [PATCH 0854/2855] Staging: iio: frequency: use dev_get_platdata() Use the wrapper function for retrieving the platform data instead of accessing dev->platform_data directly. Signed-off-by: Nizam Haider Signed-off-by: Jonathan Cameron --- drivers/staging/iio/frequency/ad9832.c | 2 +- drivers/staging/iio/frequency/ad9834.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c index 2b65faa6296a8..18b27a1984b2b 100644 --- a/drivers/staging/iio/frequency/ad9832.c +++ b/drivers/staging/iio/frequency/ad9832.c @@ -201,7 +201,7 @@ static const struct iio_info ad9832_info = { static int ad9832_probe(struct spi_device *spi) { - struct ad9832_platform_data *pdata = spi->dev.platform_data; + struct ad9832_platform_data *pdata = dev_get_platdata(&spi->dev); struct iio_dev *indio_dev; struct ad9832_state *st; struct regulator *reg; diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c index 6464f2cbe94b5..6366216e4f378 100644 --- a/drivers/staging/iio/frequency/ad9834.c +++ b/drivers/staging/iio/frequency/ad9834.c @@ -318,7 +318,7 @@ static const struct iio_info ad9833_info = { static int ad9834_probe(struct spi_device *spi) { - struct ad9834_platform_data *pdata = spi->dev.platform_data; + struct ad9834_platform_data *pdata = dev_get_platdata(&spi->dev); struct ad9834_state *st; struct iio_dev *indio_dev; struct regulator *reg; -- GitLab From 7629cef11200bccb63ce5a629a4d0602e7f85555 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 2 Dec 2015 17:32:51 +0100 Subject: [PATCH 0855/2855] regulator: lp8788-ldo: Use platform_register/unregister_drivers() These new helpers simplify implementing multi-driver modules and properly handle failure to register one driver by unregistering all previously registered drivers. Signed-off-by: Thierry Reding Signed-off-by: Mark Brown --- drivers/regulator/lp8788-ldo.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/regulator/lp8788-ldo.c b/drivers/regulator/lp8788-ldo.c index 9f22d079c8cce..30e28b1311260 100644 --- a/drivers/regulator/lp8788-ldo.c +++ b/drivers/regulator/lp8788-ldo.c @@ -613,22 +613,20 @@ static struct platform_driver lp8788_aldo_driver = { }, }; +static struct platform_driver * const drivers[] = { + &lp8788_dldo_driver, + &lp8788_aldo_driver, +}; + static int __init lp8788_ldo_init(void) { - int ret; - - ret = platform_driver_register(&lp8788_dldo_driver); - if (ret) - return ret; - - return platform_driver_register(&lp8788_aldo_driver); + return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); } subsys_initcall(lp8788_ldo_init); static void __exit lp8788_ldo_exit(void) { - platform_driver_unregister(&lp8788_aldo_driver); - platform_driver_unregister(&lp8788_dldo_driver); + platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); } module_exit(lp8788_ldo_exit); -- GitLab From 55e03e9c2d6909fd449cdcec9e933f6907f4820e Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 2 Dec 2015 17:32:52 +0100 Subject: [PATCH 0856/2855] regulator: wm831x-dcdc: Use platform_register/unregister_drivers() These new helpers simplify implementing multi-driver modules and properly handle failure to register one driver by unregistering all previously registered drivers. Signed-off-by: Thierry Reding Signed-off-by: Mark Brown --- drivers/regulator/wm831x-dcdc.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 8cbb82ceec405..05f69d1ede19a 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -884,35 +884,22 @@ static struct platform_driver wm831x_epe_driver = { }, }; +static struct platform_driver * const drivers[] = { + &wm831x_buckv_driver, + &wm831x_buckp_driver, + &wm831x_boostp_driver, + &wm831x_epe_driver, +}; + static int __init wm831x_dcdc_init(void) { - int ret; - ret = platform_driver_register(&wm831x_buckv_driver); - if (ret != 0) - pr_err("Failed to register WM831x BUCKV driver: %d\n", ret); - - ret = platform_driver_register(&wm831x_buckp_driver); - if (ret != 0) - pr_err("Failed to register WM831x BUCKP driver: %d\n", ret); - - ret = platform_driver_register(&wm831x_boostp_driver); - if (ret != 0) - pr_err("Failed to register WM831x BOOST driver: %d\n", ret); - - ret = platform_driver_register(&wm831x_epe_driver); - if (ret != 0) - pr_err("Failed to register WM831x EPE driver: %d\n", ret); - - return 0; + return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); } subsys_initcall(wm831x_dcdc_init); static void __exit wm831x_dcdc_exit(void) { - platform_driver_unregister(&wm831x_epe_driver); - platform_driver_unregister(&wm831x_boostp_driver); - platform_driver_unregister(&wm831x_buckp_driver); - platform_driver_unregister(&wm831x_buckv_driver); + platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); } module_exit(wm831x_dcdc_exit); -- GitLab From 92a513b79f942dd86f906512352e2c6d7eca1d8b Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 2 Dec 2015 17:32:53 +0100 Subject: [PATCH 0857/2855] regulator: wm831x-ldo: Use platform_register/unregister_drivers() These new helpers simplify implementing multi-driver modules and properly handle failure to register one driver by unregistering all previously registered drivers. Signed-off-by: Thierry Reding Signed-off-by: Mark Brown --- drivers/regulator/wm831x-ldo.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index 5a7b65e8a529c..9ad2a29617e27 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -653,32 +653,21 @@ static struct platform_driver wm831x_alive_ldo_driver = { }, }; +static struct platform_driver * const drivers[] = { + &wm831x_gp_ldo_driver, + &wm831x_aldo_driver, + &wm831x_alive_ldo_driver, +}; + static int __init wm831x_ldo_init(void) { - int ret; - - ret = platform_driver_register(&wm831x_gp_ldo_driver); - if (ret != 0) - pr_err("Failed to register WM831x GP LDO driver: %d\n", ret); - - ret = platform_driver_register(&wm831x_aldo_driver); - if (ret != 0) - pr_err("Failed to register WM831x ALDO driver: %d\n", ret); - - ret = platform_driver_register(&wm831x_alive_ldo_driver); - if (ret != 0) - pr_err("Failed to register WM831x alive LDO driver: %d\n", - ret); - - return 0; + return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); } subsys_initcall(wm831x_ldo_init); static void __exit wm831x_ldo_exit(void) { - platform_driver_unregister(&wm831x_alive_ldo_driver); - platform_driver_unregister(&wm831x_aldo_driver); - platform_driver_unregister(&wm831x_gp_ldo_driver); + platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); } module_exit(wm831x_ldo_exit); -- GitLab From 1bfa91e9255065e8f5b8aef869eee57b8badf61e Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 2 Dec 2015 19:17:48 +0530 Subject: [PATCH 0858/2855] spi: butterfly: remove multiple blank lines checkpatch complains about multiple blank lines. Signed-off-by: Sudip Mukherjee Signed-off-by: Mark Brown --- drivers/spi/spi-butterfly.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/spi/spi-butterfly.c b/drivers/spi/spi-butterfly.c index 9a95862986c83..f520eaa193c53 100644 --- a/drivers/spi/spi-butterfly.c +++ b/drivers/spi/spi-butterfly.c @@ -27,7 +27,6 @@ #include - /* * This uses SPI to talk with an "AVR Butterfly", which is a $US20 card * with a battery powered AVR microcontroller and lots of goodies. You @@ -37,7 +36,6 @@ * and use this custom parallel port cable. */ - /* DATA output bits (pins 2..9 == D0..D7) */ #define butterfly_nreset (1 << 1) /* pin 3 */ @@ -52,14 +50,11 @@ /* CONTROL output bits */ #define spi_cs_bit PARPORT_CONTROL_SELECT /* pin 17 */ - - static inline struct butterfly *spidev_to_pp(struct spi_device *spi) { return spi->controller_data; } - struct butterfly { /* REVISIT ... for now, this must be first */ struct spi_bitbang bitbang; @@ -140,7 +135,6 @@ static void butterfly_chipselect(struct spi_device *spi, int value) parport_frob_control(pp->port, spi_cs_bit, value ? spi_cs_bit : 0); } - /* we only needed to implement one mode here, and choose SPI_MODE_0 */ #define spidelay(X) do { } while (0) @@ -186,7 +180,6 @@ static struct flash_platform_data flash = { .nr_parts = ARRAY_SIZE(partitions), }; - /* REVISIT remove this ugly global and its "only one" limitation */ static struct butterfly *butterfly; @@ -262,7 +255,6 @@ static void butterfly_attach(struct parport *p) parport_write_data(pp->port, pp->lastbyte); msleep(100); - /* * Start SPI ... for now, hide that we're two physical busses. */ @@ -334,7 +326,6 @@ static struct parport_driver butterfly_driver = { .detach = butterfly_detach, }; - static int __init butterfly_init(void) { return parport_register_driver(&butterfly_driver); -- GitLab From b12fe7250cf013622d064a280b87b19448d26d00 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 2 Dec 2015 19:17:49 +0530 Subject: [PATCH 0859/2855] spi: butterfly: remove cast to void checkpatch was complaining about space after cast. But the cast to void is not required at that place. Signed-off-by: Sudip Mukherjee Signed-off-by: Mark Brown --- drivers/spi/spi-butterfly.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-butterfly.c b/drivers/spi/spi-butterfly.c index f520eaa193c53..8fc284d0d7c39 100644 --- a/drivers/spi/spi-butterfly.c +++ b/drivers/spi/spi-butterfly.c @@ -289,7 +289,7 @@ clean2: clean1: parport_unregister_device(pd); clean0: - (void) spi_master_put(pp->bitbang.master); + spi_master_put(pp->bitbang.master); done: pr_debug("%s: butterfly probe, fail %d\n", p->name, status); } @@ -317,7 +317,7 @@ static void butterfly_detach(struct parport *p) parport_release(pp->pd); parport_unregister_device(pp->pd); - (void) spi_master_put(pp->bitbang.master); + spi_master_put(pp->bitbang.master); } static struct parport_driver butterfly_driver = { -- GitLab From e71fec7352c83af889ea36e164f1f6f895b0aaaf Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 2 Dec 2015 19:17:50 +0530 Subject: [PATCH 0860/2855] spi: butterfly: correct alignment checkpatch complains about the allignment with open parenthesis. Signed-off-by: Sudip Mukherjee Signed-off-by: Mark Brown --- drivers/spi/spi-butterfly.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-butterfly.c b/drivers/spi/spi-butterfly.c index 8fc284d0d7c39..f16ef7fb10f1a 100644 --- a/drivers/spi/spi-butterfly.c +++ b/drivers/spi/spi-butterfly.c @@ -143,9 +143,8 @@ static void butterfly_chipselect(struct spi_device *spi, int value) #include "spi-bitbang-txrx.h" static u32 -butterfly_txrx_word_mode0(struct spi_device *spi, - unsigned nsecs, - u32 word, u8 bits) +butterfly_txrx_word_mode0(struct spi_device *spi, unsigned nsecs, u32 word, + u8 bits) { return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits); } @@ -223,8 +222,8 @@ static void butterfly_attach(struct parport *p) */ pp->port = p; pd = parport_register_device(p, "spi_butterfly", - NULL, NULL, NULL, - 0 /* FLAGS */, pp); + NULL, NULL, NULL, + 0 /* FLAGS */, pp); if (!pd) { status = -ENOMEM; goto clean0; @@ -275,7 +274,7 @@ static void butterfly_attach(struct parport *p) pp->dataflash = spi_new_device(pp->bitbang.master, &pp->info[0]); if (pp->dataflash) pr_debug("%s: dataflash at %s\n", p->name, - dev_name(&pp->dataflash->dev)); + dev_name(&pp->dataflash->dev)); pr_info("%s: AVR Butterfly\n", p->name); butterfly = pp; -- GitLab From 1d3029cc5f17081afdc2d6b7b50f9d0366cdbae1 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 2 Dec 2015 19:17:51 +0530 Subject: [PATCH 0861/2855] spi: butterfly: use new parport device model Modify spi-butterfly driver to use the new parallel port device model. Signed-off-by: Sudip Mukherjee Signed-off-by: Mark Brown --- drivers/spi/spi-butterfly.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-butterfly.c b/drivers/spi/spi-butterfly.c index f16ef7fb10f1a..22a31e4a1a11b 100644 --- a/drivers/spi/spi-butterfly.c +++ b/drivers/spi/spi-butterfly.c @@ -189,6 +189,7 @@ static void butterfly_attach(struct parport *p) struct butterfly *pp; struct spi_master *master; struct device *dev = p->physport->dev; + struct pardev_cb butterfly_cb; if (butterfly || !dev) return; @@ -221,9 +222,9 @@ static void butterfly_attach(struct parport *p) * parport hookup */ pp->port = p; - pd = parport_register_device(p, "spi_butterfly", - NULL, NULL, NULL, - 0 /* FLAGS */, pp); + memset(&butterfly_cb, 0, sizeof(butterfly_cb)); + butterfly_cb.private = pp; + pd = parport_register_dev_model(p, "spi_butterfly", &butterfly_cb, 0); if (!pd) { status = -ENOMEM; goto clean0; @@ -321,8 +322,9 @@ static void butterfly_detach(struct parport *p) static struct parport_driver butterfly_driver = { .name = "spi_butterfly", - .attach = butterfly_attach, + .match_port = butterfly_attach, .detach = butterfly_detach, + .devmodel = true, }; static int __init butterfly_init(void) -- GitLab From fb013a01d48d71a68cd14ea30181754f93acae21 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 30 Nov 2015 17:13:46 -0800 Subject: [PATCH 0862/2855] HID: wacom: Move Intuos pad handling code into dedicated function Begin slimming down the body of 'wacom_intuos_irq' by moving out its largest block of code to a dedicated 'wacom_intuos_pad' function. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 482 ++++++++++++++++++++-------------------- 1 file changed, 247 insertions(+), 235 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 8b29949507d16..c611ea5b83c82 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -446,6 +446,249 @@ static void wacom_intuos_schedule_prox_event(struct wacom_wac *wacom_wac) } } +static int wacom_intuos_pad(struct wacom_wac *wacom) +{ + struct wacom_features *features = &wacom->features; + unsigned char *data = wacom->data; + struct input_dev *input = wacom->pad_input; + + /* pad packets. Works as a second tool and is always in prox */ + if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD || + data[0] == WACOM_REPORT_CINTIQPAD)) + return 0; + + if (features->type >= INTUOS4S && features->type <= INTUOS4L) { + input_report_key(input, BTN_0, (data[2] & 0x01)); + input_report_key(input, BTN_1, (data[3] & 0x01)); + input_report_key(input, BTN_2, (data[3] & 0x02)); + input_report_key(input, BTN_3, (data[3] & 0x04)); + input_report_key(input, BTN_4, (data[3] & 0x08)); + input_report_key(input, BTN_5, (data[3] & 0x10)); + input_report_key(input, BTN_6, (data[3] & 0x20)); + if (data[1] & 0x80) { + input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f)); + } else { + /* Out of proximity, clear wheel value. */ + input_report_abs(input, ABS_WHEEL, 0); + } + if (features->type != INTUOS4S) { + input_report_key(input, BTN_7, (data[3] & 0x40)); + input_report_key(input, BTN_8, (data[3] & 0x80)); + } + if (data[1] | (data[2] & 0x01) | data[3]) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + } else if (features->type == DTK) { + input_report_key(input, BTN_0, (data[6] & 0x01)); + input_report_key(input, BTN_1, (data[6] & 0x02)); + input_report_key(input, BTN_2, (data[6] & 0x04)); + input_report_key(input, BTN_3, (data[6] & 0x08)); + input_report_key(input, BTN_4, (data[6] & 0x10)); + input_report_key(input, BTN_5, (data[6] & 0x20)); + if (data[6] & 0x3f) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + } else if (features->type == WACOM_13HD) { + input_report_key(input, BTN_0, (data[3] & 0x01)); + input_report_key(input, BTN_1, (data[4] & 0x01)); + input_report_key(input, BTN_2, (data[4] & 0x02)); + input_report_key(input, BTN_3, (data[4] & 0x04)); + input_report_key(input, BTN_4, (data[4] & 0x08)); + input_report_key(input, BTN_5, (data[4] & 0x10)); + input_report_key(input, BTN_6, (data[4] & 0x20)); + input_report_key(input, BTN_7, (data[4] & 0x40)); + input_report_key(input, BTN_8, (data[4] & 0x80)); + if ((data[3] & 0x01) | data[4]) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + } else if (features->type == WACOM_24HD) { + input_report_key(input, BTN_0, (data[6] & 0x01)); + input_report_key(input, BTN_1, (data[6] & 0x02)); + input_report_key(input, BTN_2, (data[6] & 0x04)); + input_report_key(input, BTN_3, (data[6] & 0x08)); + input_report_key(input, BTN_4, (data[6] & 0x10)); + input_report_key(input, BTN_5, (data[6] & 0x20)); + input_report_key(input, BTN_6, (data[6] & 0x40)); + input_report_key(input, BTN_7, (data[6] & 0x80)); + input_report_key(input, BTN_8, (data[8] & 0x01)); + input_report_key(input, BTN_9, (data[8] & 0x02)); + input_report_key(input, BTN_A, (data[8] & 0x04)); + input_report_key(input, BTN_B, (data[8] & 0x08)); + input_report_key(input, BTN_C, (data[8] & 0x10)); + input_report_key(input, BTN_X, (data[8] & 0x20)); + input_report_key(input, BTN_Y, (data[8] & 0x40)); + input_report_key(input, BTN_Z, (data[8] & 0x80)); + + /* + * Three "buttons" are available on the 24HD which are + * physically implemented as a touchstrip. Each button + * is approximately 3 bits wide with a 2 bit spacing. + * The raw touchstrip bits are stored at: + * ((data[3] & 0x1f) << 8) | data[4]) + */ + input_report_key(input, KEY_PROG1, data[4] & 0x07); + input_report_key(input, KEY_PROG2, data[4] & 0xE0); + input_report_key(input, KEY_PROG3, data[3] & 0x1C); + + if (data[1] & 0x80) { + input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f)); + } else { + /* Out of proximity, clear wheel value. */ + input_report_abs(input, ABS_WHEEL, 0); + } + + if (data[2] & 0x80) { + input_report_abs(input, ABS_THROTTLE, (data[2] & 0x7f)); + } else { + /* Out of proximity, clear second wheel value. */ + input_report_abs(input, ABS_THROTTLE, 0); + } + + if (data[1] | data[2] | (data[3] & 0x1f) | data[4] | data[6] | data[8]) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + } else if (features->type == WACOM_27QHD) { + input_report_key(input, KEY_PROG1, data[2] & 0x01); + input_report_key(input, KEY_PROG2, data[2] & 0x02); + input_report_key(input, KEY_PROG3, data[2] & 0x04); + + input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4])); + input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6])); + input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8])); + if ((data[2] & 0x07) | data[4] | data[5] | data[6] | data[7] | data[8] | data[9]) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + } else if (features->type == CINTIQ_HYBRID) { + /* + * Do not send hardware buttons under Android. They + * are already sent to the system through GPIO (and + * have different meaning). + */ + input_report_key(input, BTN_1, (data[4] & 0x01)); + input_report_key(input, BTN_2, (data[4] & 0x02)); + input_report_key(input, BTN_3, (data[4] & 0x04)); + input_report_key(input, BTN_4, (data[4] & 0x08)); + + input_report_key(input, BTN_5, (data[4] & 0x10)); /* Right */ + input_report_key(input, BTN_6, (data[4] & 0x20)); /* Up */ + input_report_key(input, BTN_7, (data[4] & 0x40)); /* Left */ + input_report_key(input, BTN_8, (data[4] & 0x80)); /* Down */ + input_report_key(input, BTN_0, (data[3] & 0x01)); /* Center */ + + if (data[4] | (data[3] & 0x01)) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + + } else if (features->type == CINTIQ_COMPANION_2) { + input_report_key(input, BTN_1, (data[1] & 0x02)); + input_report_key(input, BTN_2, (data[2] & 0x01)); + input_report_key(input, BTN_3, (data[2] & 0x02)); + input_report_key(input, BTN_4, (data[2] & 0x04)); + input_report_key(input, BTN_5, (data[2] & 0x08)); + input_report_key(input, BTN_6, (data[1] & 0x04)); + + input_report_key(input, BTN_7, (data[2] & 0x10)); /* Right */ + input_report_key(input, BTN_8, (data[2] & 0x20)); /* Up */ + input_report_key(input, BTN_9, (data[2] & 0x40)); /* Left */ + input_report_key(input, BTN_A, (data[2] & 0x80)); /* Down */ + input_report_key(input, BTN_0, (data[1] & 0x01)); /* Center */ + + if (data[2] | (data[1] & 0x07)) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + + } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { + int i; + + /* Touch ring mode switch has no capacitive sensor */ + input_report_key(input, BTN_0, (data[3] & 0x01)); + + /* + * ExpressKeys on Intuos5/Intuos Pro have a capacitive sensor in + * addition to the mechanical switch. Switch data is + * stored in data[4], capacitive data in data[5]. + */ + for (i = 0; i < 8; i++) + input_report_key(input, BTN_1 + i, data[4] & (1 << i)); + + if (data[2] & 0x80) { + input_report_abs(input, ABS_WHEEL, (data[2] & 0x7f)); + } else { + /* Out of proximity, clear wheel value. */ + input_report_abs(input, ABS_WHEEL, 0); + } + + if (data[2] | (data[3] & 0x01) | data[4] | data[5]) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + } else { + if (features->type == WACOM_21UX2 || features->type == WACOM_22HD) { + input_report_key(input, BTN_0, (data[5] & 0x01)); + input_report_key(input, BTN_1, (data[6] & 0x01)); + input_report_key(input, BTN_2, (data[6] & 0x02)); + input_report_key(input, BTN_3, (data[6] & 0x04)); + input_report_key(input, BTN_4, (data[6] & 0x08)); + input_report_key(input, BTN_5, (data[6] & 0x10)); + input_report_key(input, BTN_6, (data[6] & 0x20)); + input_report_key(input, BTN_7, (data[6] & 0x40)); + input_report_key(input, BTN_8, (data[6] & 0x80)); + input_report_key(input, BTN_9, (data[7] & 0x01)); + input_report_key(input, BTN_A, (data[8] & 0x01)); + input_report_key(input, BTN_B, (data[8] & 0x02)); + input_report_key(input, BTN_C, (data[8] & 0x04)); + input_report_key(input, BTN_X, (data[8] & 0x08)); + input_report_key(input, BTN_Y, (data[8] & 0x10)); + input_report_key(input, BTN_Z, (data[8] & 0x20)); + input_report_key(input, BTN_BASE, (data[8] & 0x40)); + input_report_key(input, BTN_BASE2, (data[8] & 0x80)); + + if (features->type == WACOM_22HD) { + input_report_key(input, KEY_PROG1, data[9] & 0x01); + input_report_key(input, KEY_PROG2, data[9] & 0x02); + input_report_key(input, KEY_PROG3, data[9] & 0x04); + } + } else { + input_report_key(input, BTN_0, (data[5] & 0x01)); + input_report_key(input, BTN_1, (data[5] & 0x02)); + input_report_key(input, BTN_2, (data[5] & 0x04)); + input_report_key(input, BTN_3, (data[5] & 0x08)); + input_report_key(input, BTN_4, (data[6] & 0x01)); + input_report_key(input, BTN_5, (data[6] & 0x02)); + input_report_key(input, BTN_6, (data[6] & 0x04)); + input_report_key(input, BTN_7, (data[6] & 0x08)); + input_report_key(input, BTN_8, (data[5] & 0x10)); + input_report_key(input, BTN_9, (data[6] & 0x10)); + } + input_report_abs(input, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); + input_report_abs(input, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); + + if ((data[5] & 0x1f) | data[6] | (data[1] & 0x1f) | + data[2] | (data[3] & 0x1f) | data[4] | data[8] | + (data[7] & 0x01)) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + } + return 1; +} + static int wacom_intuos_inout(struct wacom_wac *wacom) { struct wacom_features *features = &wacom->features; @@ -814,241 +1057,10 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) if (features->type == INTUOS) idx = data[1] & 0x01; - /* pad packets. Works as a second tool and is always in prox */ - if (data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD || - data[0] == WACOM_REPORT_CINTIQPAD) { - input = wacom->pad_input; - if (features->type >= INTUOS4S && features->type <= INTUOS4L) { - input_report_key(input, BTN_0, (data[2] & 0x01)); - input_report_key(input, BTN_1, (data[3] & 0x01)); - input_report_key(input, BTN_2, (data[3] & 0x02)); - input_report_key(input, BTN_3, (data[3] & 0x04)); - input_report_key(input, BTN_4, (data[3] & 0x08)); - input_report_key(input, BTN_5, (data[3] & 0x10)); - input_report_key(input, BTN_6, (data[3] & 0x20)); - if (data[1] & 0x80) { - input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f)); - } else { - /* Out of proximity, clear wheel value. */ - input_report_abs(input, ABS_WHEEL, 0); - } - if (features->type != INTUOS4S) { - input_report_key(input, BTN_7, (data[3] & 0x40)); - input_report_key(input, BTN_8, (data[3] & 0x80)); - } - if (data[1] | (data[2] & 0x01) | data[3]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - } else if (features->type == DTK) { - input_report_key(input, BTN_0, (data[6] & 0x01)); - input_report_key(input, BTN_1, (data[6] & 0x02)); - input_report_key(input, BTN_2, (data[6] & 0x04)); - input_report_key(input, BTN_3, (data[6] & 0x08)); - input_report_key(input, BTN_4, (data[6] & 0x10)); - input_report_key(input, BTN_5, (data[6] & 0x20)); - if (data[6] & 0x3f) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - } else if (features->type == WACOM_13HD) { - input_report_key(input, BTN_0, (data[3] & 0x01)); - input_report_key(input, BTN_1, (data[4] & 0x01)); - input_report_key(input, BTN_2, (data[4] & 0x02)); - input_report_key(input, BTN_3, (data[4] & 0x04)); - input_report_key(input, BTN_4, (data[4] & 0x08)); - input_report_key(input, BTN_5, (data[4] & 0x10)); - input_report_key(input, BTN_6, (data[4] & 0x20)); - input_report_key(input, BTN_7, (data[4] & 0x40)); - input_report_key(input, BTN_8, (data[4] & 0x80)); - if ((data[3] & 0x01) | data[4]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - } else if (features->type == WACOM_24HD) { - input_report_key(input, BTN_0, (data[6] & 0x01)); - input_report_key(input, BTN_1, (data[6] & 0x02)); - input_report_key(input, BTN_2, (data[6] & 0x04)); - input_report_key(input, BTN_3, (data[6] & 0x08)); - input_report_key(input, BTN_4, (data[6] & 0x10)); - input_report_key(input, BTN_5, (data[6] & 0x20)); - input_report_key(input, BTN_6, (data[6] & 0x40)); - input_report_key(input, BTN_7, (data[6] & 0x80)); - input_report_key(input, BTN_8, (data[8] & 0x01)); - input_report_key(input, BTN_9, (data[8] & 0x02)); - input_report_key(input, BTN_A, (data[8] & 0x04)); - input_report_key(input, BTN_B, (data[8] & 0x08)); - input_report_key(input, BTN_C, (data[8] & 0x10)); - input_report_key(input, BTN_X, (data[8] & 0x20)); - input_report_key(input, BTN_Y, (data[8] & 0x40)); - input_report_key(input, BTN_Z, (data[8] & 0x80)); - - /* - * Three "buttons" are available on the 24HD which are - * physically implemented as a touchstrip. Each button - * is approximately 3 bits wide with a 2 bit spacing. - * The raw touchstrip bits are stored at: - * ((data[3] & 0x1f) << 8) | data[4]) - */ - input_report_key(input, KEY_PROG1, data[4] & 0x07); - input_report_key(input, KEY_PROG2, data[4] & 0xE0); - input_report_key(input, KEY_PROG3, data[3] & 0x1C); - - if (data[1] & 0x80) { - input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f)); - } else { - /* Out of proximity, clear wheel value. */ - input_report_abs(input, ABS_WHEEL, 0); - } - - if (data[2] & 0x80) { - input_report_abs(input, ABS_THROTTLE, (data[2] & 0x7f)); - } else { - /* Out of proximity, clear second wheel value. */ - input_report_abs(input, ABS_THROTTLE, 0); - } - - if (data[1] | data[2] | (data[3] & 0x1f) | data[4] | data[6] | data[8]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - } else if (features->type == WACOM_27QHD) { - input_report_key(input, KEY_PROG1, data[2] & 0x01); - input_report_key(input, KEY_PROG2, data[2] & 0x02); - input_report_key(input, KEY_PROG3, data[2] & 0x04); - - input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4])); - input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6])); - input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8])); - if ((data[2] & 0x07) | data[4] | data[5] | data[6] | data[7] | data[8] | data[9]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - } else if (features->type == CINTIQ_HYBRID) { - /* - * Do not send hardware buttons under Android. They - * are already sent to the system through GPIO (and - * have different meaning). - */ - input_report_key(input, BTN_1, (data[4] & 0x01)); - input_report_key(input, BTN_2, (data[4] & 0x02)); - input_report_key(input, BTN_3, (data[4] & 0x04)); - input_report_key(input, BTN_4, (data[4] & 0x08)); - - input_report_key(input, BTN_5, (data[4] & 0x10)); /* Right */ - input_report_key(input, BTN_6, (data[4] & 0x20)); /* Up */ - input_report_key(input, BTN_7, (data[4] & 0x40)); /* Left */ - input_report_key(input, BTN_8, (data[4] & 0x80)); /* Down */ - input_report_key(input, BTN_0, (data[3] & 0x01)); /* Center */ - - if (data[4] | (data[3] & 0x01)) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - - } else if (features->type == CINTIQ_COMPANION_2) { - input_report_key(input, BTN_1, (data[1] & 0x02)); - input_report_key(input, BTN_2, (data[2] & 0x01)); - input_report_key(input, BTN_3, (data[2] & 0x02)); - input_report_key(input, BTN_4, (data[2] & 0x04)); - input_report_key(input, BTN_5, (data[2] & 0x08)); - input_report_key(input, BTN_6, (data[1] & 0x04)); - - input_report_key(input, BTN_7, (data[2] & 0x10)); /* Right */ - input_report_key(input, BTN_8, (data[2] & 0x20)); /* Up */ - input_report_key(input, BTN_9, (data[2] & 0x40)); /* Left */ - input_report_key(input, BTN_A, (data[2] & 0x80)); /* Down */ - input_report_key(input, BTN_0, (data[1] & 0x01)); /* Center */ - - if (data[2] | (data[1] & 0x07)) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - - } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { - int i; - - /* Touch ring mode switch has no capacitive sensor */ - input_report_key(input, BTN_0, (data[3] & 0x01)); - - /* - * ExpressKeys on Intuos5/Intuos Pro have a capacitive sensor in - * addition to the mechanical switch. Switch data is - * stored in data[4], capacitive data in data[5]. - */ - for (i = 0; i < 8; i++) - input_report_key(input, BTN_1 + i, data[4] & (1 << i)); - - if (data[2] & 0x80) { - input_report_abs(input, ABS_WHEEL, (data[2] & 0x7f)); - } else { - /* Out of proximity, clear wheel value. */ - input_report_abs(input, ABS_WHEEL, 0); - } - - if (data[2] | (data[3] & 0x01) | data[4] | data[5]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - } else { - if (features->type == WACOM_21UX2 || features->type == WACOM_22HD) { - input_report_key(input, BTN_0, (data[5] & 0x01)); - input_report_key(input, BTN_1, (data[6] & 0x01)); - input_report_key(input, BTN_2, (data[6] & 0x02)); - input_report_key(input, BTN_3, (data[6] & 0x04)); - input_report_key(input, BTN_4, (data[6] & 0x08)); - input_report_key(input, BTN_5, (data[6] & 0x10)); - input_report_key(input, BTN_6, (data[6] & 0x20)); - input_report_key(input, BTN_7, (data[6] & 0x40)); - input_report_key(input, BTN_8, (data[6] & 0x80)); - input_report_key(input, BTN_9, (data[7] & 0x01)); - input_report_key(input, BTN_A, (data[8] & 0x01)); - input_report_key(input, BTN_B, (data[8] & 0x02)); - input_report_key(input, BTN_C, (data[8] & 0x04)); - input_report_key(input, BTN_X, (data[8] & 0x08)); - input_report_key(input, BTN_Y, (data[8] & 0x10)); - input_report_key(input, BTN_Z, (data[8] & 0x20)); - input_report_key(input, BTN_BASE, (data[8] & 0x40)); - input_report_key(input, BTN_BASE2, (data[8] & 0x80)); - - if (features->type == WACOM_22HD) { - input_report_key(input, KEY_PROG1, data[9] & 0x01); - input_report_key(input, KEY_PROG2, data[9] & 0x02); - input_report_key(input, KEY_PROG3, data[9] & 0x04); - } - } else { - input_report_key(input, BTN_0, (data[5] & 0x01)); - input_report_key(input, BTN_1, (data[5] & 0x02)); - input_report_key(input, BTN_2, (data[5] & 0x04)); - input_report_key(input, BTN_3, (data[5] & 0x08)); - input_report_key(input, BTN_4, (data[6] & 0x01)); - input_report_key(input, BTN_5, (data[6] & 0x02)); - input_report_key(input, BTN_6, (data[6] & 0x04)); - input_report_key(input, BTN_7, (data[6] & 0x08)); - input_report_key(input, BTN_8, (data[5] & 0x10)); - input_report_key(input, BTN_9, (data[6] & 0x10)); - } - input_report_abs(input, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); - input_report_abs(input, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); - - if ((data[5] & 0x1f) | data[6] | (data[1] & 0x1f) | - data[2] | (data[3] & 0x1f) | data[4] | data[8] | - (data[7] & 0x01)) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - } - return 1; - } + /* process pad events */ + result = wacom_intuos_pad(wacom); + if (result) + return result; /* process in/out prox events */ result = wacom_intuos_inout(wacom); -- GitLab From c7f0522a1ad1c2a1a23872c96955d60890f453e4 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 30 Nov 2015 17:13:47 -0800 Subject: [PATCH 0863/2855] HID: wacom: Slim down wacom_intuos_pad processing Seperate the function into two halves: first gather data from the packet, next report all gathered data. The input subsystem should automatically mute any events that aren't actually declared for the tablet at hand. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 277 +++++++++++++--------------------------- 1 file changed, 86 insertions(+), 191 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index c611ea5b83c82..ec1e13e55ae90 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -34,6 +34,9 @@ */ #define WACOM_CONTACT_AREA_SCALE 2607 +static void wacom_report_numbered_buttons(struct input_dev *input_dev, + int button_count, int mask); + /* * Percent of battery capacity for Graphire. * 8th value means AC online and show 100% capacity. @@ -451,6 +454,12 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) struct wacom_features *features = &wacom->features; unsigned char *data = wacom->data; struct input_dev *input = wacom->pad_input; + int i; + int buttons = 0, nbuttons = features->numbered_buttons; + int keys = 0, nkeys = 0; + int ring1 = 0, ring2 = 0; + int strip1 = 0, strip2 = 0; + bool prox = false; /* pad packets. Works as a second tool and is always in prox */ if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD || @@ -458,72 +467,16 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) return 0; if (features->type >= INTUOS4S && features->type <= INTUOS4L) { - input_report_key(input, BTN_0, (data[2] & 0x01)); - input_report_key(input, BTN_1, (data[3] & 0x01)); - input_report_key(input, BTN_2, (data[3] & 0x02)); - input_report_key(input, BTN_3, (data[3] & 0x04)); - input_report_key(input, BTN_4, (data[3] & 0x08)); - input_report_key(input, BTN_5, (data[3] & 0x10)); - input_report_key(input, BTN_6, (data[3] & 0x20)); - if (data[1] & 0x80) { - input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f)); - } else { - /* Out of proximity, clear wheel value. */ - input_report_abs(input, ABS_WHEEL, 0); - } - if (features->type != INTUOS4S) { - input_report_key(input, BTN_7, (data[3] & 0x40)); - input_report_key(input, BTN_8, (data[3] & 0x80)); - } - if (data[1] | (data[2] & 0x01) | data[3]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } + buttons = (data[3] << 1) | (data[2] & 0x01); + ring1 = data[1]; } else if (features->type == DTK) { - input_report_key(input, BTN_0, (data[6] & 0x01)); - input_report_key(input, BTN_1, (data[6] & 0x02)); - input_report_key(input, BTN_2, (data[6] & 0x04)); - input_report_key(input, BTN_3, (data[6] & 0x08)); - input_report_key(input, BTN_4, (data[6] & 0x10)); - input_report_key(input, BTN_5, (data[6] & 0x20)); - if (data[6] & 0x3f) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } + buttons = data[6]; } else if (features->type == WACOM_13HD) { - input_report_key(input, BTN_0, (data[3] & 0x01)); - input_report_key(input, BTN_1, (data[4] & 0x01)); - input_report_key(input, BTN_2, (data[4] & 0x02)); - input_report_key(input, BTN_3, (data[4] & 0x04)); - input_report_key(input, BTN_4, (data[4] & 0x08)); - input_report_key(input, BTN_5, (data[4] & 0x10)); - input_report_key(input, BTN_6, (data[4] & 0x20)); - input_report_key(input, BTN_7, (data[4] & 0x40)); - input_report_key(input, BTN_8, (data[4] & 0x80)); - if ((data[3] & 0x01) | data[4]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } + buttons = (data[4] << 1) | (data[3] & 0x01); } else if (features->type == WACOM_24HD) { - input_report_key(input, BTN_0, (data[6] & 0x01)); - input_report_key(input, BTN_1, (data[6] & 0x02)); - input_report_key(input, BTN_2, (data[6] & 0x04)); - input_report_key(input, BTN_3, (data[6] & 0x08)); - input_report_key(input, BTN_4, (data[6] & 0x10)); - input_report_key(input, BTN_5, (data[6] & 0x20)); - input_report_key(input, BTN_6, (data[6] & 0x40)); - input_report_key(input, BTN_7, (data[6] & 0x80)); - input_report_key(input, BTN_8, (data[8] & 0x01)); - input_report_key(input, BTN_9, (data[8] & 0x02)); - input_report_key(input, BTN_A, (data[8] & 0x04)); - input_report_key(input, BTN_B, (data[8] & 0x08)); - input_report_key(input, BTN_C, (data[8] & 0x10)); - input_report_key(input, BTN_X, (data[8] & 0x20)); - input_report_key(input, BTN_Y, (data[8] & 0x40)); - input_report_key(input, BTN_Z, (data[8] & 0x80)); + buttons = (data[8] << 8) | data[6]; + ring1 = data[1]; + ring2 = data[2]; /* * Three "buttons" are available on the 24HD which are @@ -532,160 +485,89 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) * The raw touchstrip bits are stored at: * ((data[3] & 0x1f) << 8) | data[4]) */ - input_report_key(input, KEY_PROG1, data[4] & 0x07); - input_report_key(input, KEY_PROG2, data[4] & 0xE0); - input_report_key(input, KEY_PROG3, data[3] & 0x1C); - - if (data[1] & 0x80) { - input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f)); - } else { - /* Out of proximity, clear wheel value. */ - input_report_abs(input, ABS_WHEEL, 0); - } - - if (data[2] & 0x80) { - input_report_abs(input, ABS_THROTTLE, (data[2] & 0x7f)); - } else { - /* Out of proximity, clear second wheel value. */ - input_report_abs(input, ABS_THROTTLE, 0); - } - - if (data[1] | data[2] | (data[3] & 0x1f) | data[4] | data[6] | data[8]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } + nkeys = 3; + keys = ((data[3] & 0x1C) ? 1<<2 : 0) | + ((data[4] & 0xE0) ? 1<<1 : 0) | + ((data[4] & 0x07) ? 1<<0 : 0); } else if (features->type == WACOM_27QHD) { - input_report_key(input, KEY_PROG1, data[2] & 0x01); - input_report_key(input, KEY_PROG2, data[2] & 0x02); - input_report_key(input, KEY_PROG3, data[2] & 0x04); + nkeys = 3; + keys = data[2] & 0x07; input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4])); input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6])); input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8])); - if ((data[2] & 0x07) | data[4] | data[5] | data[6] | data[7] | data[8] | data[9]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } } else if (features->type == CINTIQ_HYBRID) { /* * Do not send hardware buttons under Android. They * are already sent to the system through GPIO (and * have different meaning). + * + * d-pad right -> data[4] & 0x10 + * d-pad up -> data[4] & 0x20 + * d-pad left -> data[4] & 0x40 + * d-pad down -> data[4] & 0x80 + * d-pad center -> data[3] & 0x01 */ - input_report_key(input, BTN_1, (data[4] & 0x01)); - input_report_key(input, BTN_2, (data[4] & 0x02)); - input_report_key(input, BTN_3, (data[4] & 0x04)); - input_report_key(input, BTN_4, (data[4] & 0x08)); - - input_report_key(input, BTN_5, (data[4] & 0x10)); /* Right */ - input_report_key(input, BTN_6, (data[4] & 0x20)); /* Up */ - input_report_key(input, BTN_7, (data[4] & 0x40)); /* Left */ - input_report_key(input, BTN_8, (data[4] & 0x80)); /* Down */ - input_report_key(input, BTN_0, (data[3] & 0x01)); /* Center */ - - if (data[4] | (data[3] & 0x01)) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - + buttons = (data[4] << 1) | (data[3] & 0x01); } else if (features->type == CINTIQ_COMPANION_2) { - input_report_key(input, BTN_1, (data[1] & 0x02)); - input_report_key(input, BTN_2, (data[2] & 0x01)); - input_report_key(input, BTN_3, (data[2] & 0x02)); - input_report_key(input, BTN_4, (data[2] & 0x04)); - input_report_key(input, BTN_5, (data[2] & 0x08)); - input_report_key(input, BTN_6, (data[1] & 0x04)); - - input_report_key(input, BTN_7, (data[2] & 0x10)); /* Right */ - input_report_key(input, BTN_8, (data[2] & 0x20)); /* Up */ - input_report_key(input, BTN_9, (data[2] & 0x40)); /* Left */ - input_report_key(input, BTN_A, (data[2] & 0x80)); /* Down */ - input_report_key(input, BTN_0, (data[1] & 0x01)); /* Center */ - - if (data[2] | (data[1] & 0x07)) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - + /* d-pad right -> data[4] & 0x10 + * d-pad up -> data[4] & 0x20 + * d-pad left -> data[4] & 0x40 + * d-pad down -> data[4] & 0x80 + * d-pad center -> data[3] & 0x01 + */ + buttons = ((data[2] & 0xF0) << 7) | + ((data[1] & 0x04) << 6) | + ((data[2] & 0x0F) << 2) | + (data[1] & 0x03); } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { - int i; - - /* Touch ring mode switch has no capacitive sensor */ - input_report_key(input, BTN_0, (data[3] & 0x01)); - /* * ExpressKeys on Intuos5/Intuos Pro have a capacitive sensor in * addition to the mechanical switch. Switch data is * stored in data[4], capacitive data in data[5]. + * + * Touch ring mode switch (data[3]) has no capacitive sensor */ - for (i = 0; i < 8; i++) - input_report_key(input, BTN_1 + i, data[4] & (1 << i)); - - if (data[2] & 0x80) { - input_report_abs(input, ABS_WHEEL, (data[2] & 0x7f)); - } else { - /* Out of proximity, clear wheel value. */ - input_report_abs(input, ABS_WHEEL, 0); - } - - if (data[2] | (data[3] & 0x01) | data[4] | data[5]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } + buttons = (data[4] << 1) | (data[3] & 0x01); + ring1 = data[2]; } else { if (features->type == WACOM_21UX2 || features->type == WACOM_22HD) { - input_report_key(input, BTN_0, (data[5] & 0x01)); - input_report_key(input, BTN_1, (data[6] & 0x01)); - input_report_key(input, BTN_2, (data[6] & 0x02)); - input_report_key(input, BTN_3, (data[6] & 0x04)); - input_report_key(input, BTN_4, (data[6] & 0x08)); - input_report_key(input, BTN_5, (data[6] & 0x10)); - input_report_key(input, BTN_6, (data[6] & 0x20)); - input_report_key(input, BTN_7, (data[6] & 0x40)); - input_report_key(input, BTN_8, (data[6] & 0x80)); - input_report_key(input, BTN_9, (data[7] & 0x01)); - input_report_key(input, BTN_A, (data[8] & 0x01)); - input_report_key(input, BTN_B, (data[8] & 0x02)); - input_report_key(input, BTN_C, (data[8] & 0x04)); - input_report_key(input, BTN_X, (data[8] & 0x08)); - input_report_key(input, BTN_Y, (data[8] & 0x10)); - input_report_key(input, BTN_Z, (data[8] & 0x20)); - input_report_key(input, BTN_BASE, (data[8] & 0x40)); - input_report_key(input, BTN_BASE2, (data[8] & 0x80)); + buttons = (data[8] << 10) | ((data[7] & 0x01) << 9) | + (data[6] << 1) | (data[5] & 0x01); if (features->type == WACOM_22HD) { - input_report_key(input, KEY_PROG1, data[9] & 0x01); - input_report_key(input, KEY_PROG2, data[9] & 0x02); - input_report_key(input, KEY_PROG3, data[9] & 0x04); + nkeys = 3; + keys = data[9] & 0x07; } } else { - input_report_key(input, BTN_0, (data[5] & 0x01)); - input_report_key(input, BTN_1, (data[5] & 0x02)); - input_report_key(input, BTN_2, (data[5] & 0x04)); - input_report_key(input, BTN_3, (data[5] & 0x08)); - input_report_key(input, BTN_4, (data[6] & 0x01)); - input_report_key(input, BTN_5, (data[6] & 0x02)); - input_report_key(input, BTN_6, (data[6] & 0x04)); - input_report_key(input, BTN_7, (data[6] & 0x08)); - input_report_key(input, BTN_8, (data[5] & 0x10)); - input_report_key(input, BTN_9, (data[6] & 0x10)); - } - input_report_abs(input, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); - input_report_abs(input, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); - - if ((data[5] & 0x1f) | data[6] | (data[1] & 0x1f) | - data[2] | (data[3] & 0x1f) | data[4] | data[8] | - (data[7] & 0x01)) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); + buttons = ((data[6] & 0x10) << 10) | + ((data[5] & 0x10) << 9) | + ((data[6] & 0x0F) << 4) | + (data[5] & 0x0F); } + strip1 = (data[1] << 8) || data[2]; + strip2 = (data[3] << 8) || data[4]; } + + prox = (buttons & ~(~0 << nbuttons)) || (keys & ~(~0 << nkeys)) || + (ring1 & 0x80) || (ring2 & 0x80) || strip1 || strip2; + + wacom_report_numbered_buttons(input, nbuttons, buttons); + + for (i = 0; i < nkeys; i++) + input_report_key(input, KEY_PROG1 + i, keys & (1 << i)); + + input_report_abs(input, ABS_RX, strip1); + input_report_abs(input, ABS_RX, strip2); + + input_report_abs(input, ABS_WHEEL, ring1 & 0x7f ? ring1 : 0); + input_report_abs(input, ABS_THROTTLE, ring2 & 0x07 ? ring2 : 0); + + input_report_key(input, wacom->tool[1], prox ? 1 : 0); + input_report_abs(input, ABS_MISC, prox ? PAD_DEVICE_ID : 0); + + input_event(input, EV_MSC, MSC_SERIAL, 0xffffffff); + return 1; } @@ -2818,6 +2700,19 @@ static void wacom_setup_numbered_buttons(struct input_dev *input_dev, __set_bit(BTN_BASE + (i-16), input_dev->keybit); } +static void wacom_report_numbered_buttons(struct input_dev *input_dev, + int button_count, int mask) +{ + int i; + + for (i = 0; i < button_count && i < 10; i++) + input_report_key(input_dev, BTN_0 + i, mask & (1 << i)); + for (i = 10; i < button_count && i < 16; i++) + input_report_key(input_dev, BTN_A + (i-10), mask & (1 << i)); + for (i = 16; i < button_count && i < 18; i++) + input_report_key(input_dev, BTN_BASE + (i-16), mask & (1 << i)); +} + int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { -- GitLab From 16e0a6a0d27f01c47e3685a2a5e6dd2a5b0a525f Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 30 Nov 2015 17:13:48 -0800 Subject: [PATCH 0864/2855] HID: wacom: Centralize Intuos pen packet decoding Continue to slim down 'wacom_intuos_irq' by moving all decoding and reporting of pen packet data into the 'wacom_intuos_general' function. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 105 +++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 51 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index ec1e13e55ae90..e39568837b584 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -880,13 +880,28 @@ static int wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len) return 0; } -static void wacom_intuos_general(struct wacom_wac *wacom) +static int wacom_intuos_general(struct wacom_wac *wacom) { struct wacom_features *features = &wacom->features; unsigned char *data = wacom->data; struct input_dev *input = wacom->pen_input; + int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0; unsigned int t; + if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_CINTIQ && + data[0] != WACOM_REPORT_INTUOS_PEN) + return 0; + + if (features->type >= INTUOS3S) { + input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); + input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); + input_report_abs(input, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); + } else { + input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[2])); + input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[4])); + input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); + } + /* general pen packet */ if ((data[1] & 0xb8) == 0xa0) { t = (data[6] << 2) | ((data[7] >> 6) & 3); @@ -912,55 +927,6 @@ static void wacom_intuos_general(struct wacom_wac *wacom) (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); } -} - -static int wacom_intuos_irq(struct wacom_wac *wacom) -{ - struct wacom_features *features = &wacom->features; - unsigned char *data = wacom->data; - struct input_dev *input = wacom->pen_input; - unsigned int t; - int idx = 0, result; - - if (data[0] != WACOM_REPORT_PENABLED && - data[0] != WACOM_REPORT_INTUOSREAD && - data[0] != WACOM_REPORT_INTUOSWRITE && - data[0] != WACOM_REPORT_INTUOSPAD && - data[0] != WACOM_REPORT_INTUOS_PEN && - data[0] != WACOM_REPORT_CINTIQ && - data[0] != WACOM_REPORT_CINTIQPAD && - data[0] != WACOM_REPORT_INTUOS5PAD) { - dev_dbg(input->dev.parent, - "%s: received unknown report #%d\n", __func__, data[0]); - return 0; - } - - /* tool number */ - if (features->type == INTUOS) - idx = data[1] & 0x01; - - /* process pad events */ - result = wacom_intuos_pad(wacom); - if (result) - return result; - - /* process in/out prox events */ - result = wacom_intuos_inout(wacom); - if (result) - return result - 1; - - if (features->type >= INTUOS3S) { - input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); - input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); - input_report_abs(input, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); - } else { - input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[2])); - input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[4])); - input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); - } - - /* process general packets */ - wacom_intuos_general(wacom); /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) { @@ -1036,7 +1002,44 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) input_report_key(input, wacom->tool[idx], 1); input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]); wacom->reporting_data = true; - return 1; + return 2; +} + +static int wacom_intuos_irq(struct wacom_wac *wacom) +{ + unsigned char *data = wacom->data; + struct input_dev *input = wacom->pen_input; + int result; + + if (data[0] != WACOM_REPORT_PENABLED && + data[0] != WACOM_REPORT_INTUOSREAD && + data[0] != WACOM_REPORT_INTUOSWRITE && + data[0] != WACOM_REPORT_INTUOSPAD && + data[0] != WACOM_REPORT_INTUOS_PEN && + data[0] != WACOM_REPORT_CINTIQ && + data[0] != WACOM_REPORT_CINTIQPAD && + data[0] != WACOM_REPORT_INTUOS5PAD) { + dev_dbg(input->dev.parent, + "%s: received unknown report #%d\n", __func__, data[0]); + return 0; + } + + /* process pad events */ + result = wacom_intuos_pad(wacom); + if (result) + return result; + + /* process in/out prox events */ + result = wacom_intuos_inout(wacom); + if (result) + return result - 1; + + /* process general packets */ + result = wacom_intuos_general(wacom); + if (result) + return result - 1; + + return 0; } static int int_dist(int x1, int y1, int x2, int y2) -- GitLab From a8a09c8597bd301437c30ce0a4b2f511349a90aa Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 30 Nov 2015 17:13:49 -0800 Subject: [PATCH 0865/2855] HID: wacom: Replace magic masks and comparisons with switch cases Reasoning through the conditions under which a particular block of code in 'wacom_intuos_general' will be reached is not at all easy due to the sheer number of magic masks and comparisons. Remove these and replace them with a switch statement over the various 'types' of packets that will be encountered. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 79 +++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 30 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index e39568837b584..a426cb2a1834b 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -886,6 +886,7 @@ static int wacom_intuos_general(struct wacom_wac *wacom) unsigned char *data = wacom->data; struct input_dev *input = wacom->pen_input; int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0; + unsigned char type = (data[1] >> 1) & 0x0F; unsigned int t; if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_CINTIQ && @@ -902,8 +903,12 @@ static int wacom_intuos_general(struct wacom_wac *wacom) input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); } - /* general pen packet */ - if ((data[1] & 0xb8) == 0xa0) { + switch (type) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + /* general pen packet */ t = (data[6] << 2) | ((data[7] >> 6) & 3); if (features->pressure_max == 2047) { t = (t << 1) | (data[1] & 1); @@ -917,36 +922,40 @@ static int wacom_intuos_general(struct wacom_wac *wacom) input_report_key(input, BTN_STYLUS, data[1] & 2); input_report_key(input, BTN_STYLUS2, data[1] & 4); input_report_key(input, BTN_TOUCH, t > 10); - } + break; - /* airbrush second packet */ - if ((data[1] & 0xbc) == 0xb4) { + case 0x0a: + case 0x0b: + /* airbrush second packet */ input_report_abs(input, ABS_WHEEL, (data[6] << 2) | ((data[7] >> 6) & 3)); input_report_abs(input, ABS_TILT_X, (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); - } + break; - /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ - if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) { - - if (data[1] & 0x02) { - /* Rotation packet */ - if (features->type >= INTUOS3S) { - /* I3 marker pen rotation */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : - ((t-1) / 2 + 450)) : (450 - t / 2) ; - input_report_abs(input, ABS_Z, t); - } else { - /* 4D mouse rotation packet */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - input_report_abs(input, ABS_RZ, (data[7] & 0x20) ? - ((t - 1) / 2) : -t / 2); - } + case 0x05: + case 0x07: + /* Rotation packet */ + if (features->type >= INTUOS3S) { + /* I3 marker pen rotation */ + t = (data[6] << 3) | ((data[7] >> 5) & 7); + t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : + ((t-1) / 2 + 450)) : (450 - t / 2) ; + input_report_abs(input, ABS_Z, t); + } else { + /* 4D mouse rotation packet */ + t = (data[6] << 3) | ((data[7] >> 5) & 7); + input_report_abs(input, ABS_RZ, (data[7] & 0x20) ? + ((t - 1) / 2) : -t / 2); + } + break; - } else if (!(data[1] & 0x10) && features->type < INTUOS3S) { + /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ + case 0x04: + case 0x06: + case 0x08: + if (features->type < INTUOS3S && type != 0x08) { /* 4D mouse packet */ input_report_key(input, BTN_LEFT, data[8] & 0x01); input_report_key(input, BTN_MIDDLE, data[8] & 0x02); @@ -956,8 +965,8 @@ static int wacom_intuos_general(struct wacom_wac *wacom) input_report_key(input, BTN_EXTRA, data[8] & 0x10); t = (data[6] << 2) | ((data[7] >> 6) & 3); input_report_abs(input, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); - - } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { + } + else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { /* I4 mouse */ if (features->type >= INTUOS4S && features->type <= INTUOSPL) { input_report_key(input, BTN_LEFT, data[6] & 0x01); @@ -985,10 +994,11 @@ static int wacom_intuos_general(struct wacom_wac *wacom) input_report_key(input, BTN_EXTRA, data[8] & 0x20); } } - } else if ((features->type < INTUOS3S || features->type == INTUOS3L || - features->type == INTUOS4L || features->type == INTUOS5L || - features->type == INTUOSPL) && - wacom->tool[idx] == BTN_TOOL_LENS) { + } + else if ((features->type < INTUOS3S || features->type == INTUOS3L || + features->type == INTUOS4L || features->type == INTUOS5L || + features->type == INTUOSPL) && + wacom->tool[idx] == BTN_TOOL_LENS) { /* Lens cursor packets */ input_report_key(input, BTN_LEFT, data[8] & 0x01); input_report_key(input, BTN_MIDDLE, data[8] & 0x02); @@ -996,6 +1006,15 @@ static int wacom_intuos_general(struct wacom_wac *wacom) input_report_key(input, BTN_SIDE, data[8] & 0x10); input_report_key(input, BTN_EXTRA, data[8] & 0x08); } + break; + + case 0x09: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + /* unhandled */ + break; } input_report_abs(input, ABS_MISC, wacom->id[idx]); /* report tool id */ -- GitLab From 571f572f9acf7e03fd0e8eb1449e75447295d457 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 30 Nov 2015 17:13:50 -0800 Subject: [PATCH 0866/2855] HID: wacom: Further clean up wacom_intuos_general packet decoder Continue re-organizing and trimming cases to make it easier to wrap the brain around. A number of changes were made after consulting the protocol spec and so don't necessarily follow from the code itself. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 87 +++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 46 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index a426cb2a1834b..ce3afab806cc5 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -925,7 +925,6 @@ static int wacom_intuos_general(struct wacom_wac *wacom) break; case 0x0a: - case 0x0b: /* airbrush second packet */ input_report_abs(input, ABS_WHEEL, (data[6] << 2) | ((data[7] >> 6) & 3)); @@ -935,7 +934,6 @@ static int wacom_intuos_general(struct wacom_wac *wacom) break; case 0x05: - case 0x07: /* Rotation packet */ if (features->type >= INTUOS3S) { /* I3 marker pen rotation */ @@ -944,61 +942,56 @@ static int wacom_intuos_general(struct wacom_wac *wacom) ((t-1) / 2 + 450)) : (450 - t / 2) ; input_report_abs(input, ABS_Z, t); } else { - /* 4D mouse rotation packet */ + /* 4D mouse 2nd packet */ t = (data[6] << 3) | ((data[7] >> 5) & 7); input_report_abs(input, ABS_RZ, (data[7] & 0x20) ? ((t - 1) / 2) : -t / 2); } break; - /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ case 0x04: + /* 4D mouse 1st packet */ + input_report_key(input, BTN_LEFT, data[8] & 0x01); + input_report_key(input, BTN_MIDDLE, data[8] & 0x02); + input_report_key(input, BTN_RIGHT, data[8] & 0x04); + + input_report_key(input, BTN_SIDE, data[8] & 0x20); + input_report_key(input, BTN_EXTRA, data[8] & 0x10); + t = (data[6] << 2) | ((data[7] >> 6) & 3); + input_report_abs(input, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); + break; + case 0x06: - case 0x08: - if (features->type < INTUOS3S && type != 0x08) { - /* 4D mouse packet */ - input_report_key(input, BTN_LEFT, data[8] & 0x01); - input_report_key(input, BTN_MIDDLE, data[8] & 0x02); - input_report_key(input, BTN_RIGHT, data[8] & 0x04); + /* I4 mouse */ + input_report_key(input, BTN_LEFT, data[6] & 0x01); + input_report_key(input, BTN_MIDDLE, data[6] & 0x02); + input_report_key(input, BTN_RIGHT, data[6] & 0x04); + input_report_rel(input, REL_WHEEL, ((data[7] & 0x80) >> 7) + - ((data[7] & 0x40) >> 6)); + input_report_key(input, BTN_SIDE, data[6] & 0x08); + input_report_key(input, BTN_EXTRA, data[6] & 0x10); - input_report_key(input, BTN_SIDE, data[8] & 0x20); - input_report_key(input, BTN_EXTRA, data[8] & 0x10); - t = (data[6] << 2) | ((data[7] >> 6) & 3); - input_report_abs(input, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); - } - else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { - /* I4 mouse */ - if (features->type >= INTUOS4S && features->type <= INTUOSPL) { - input_report_key(input, BTN_LEFT, data[6] & 0x01); - input_report_key(input, BTN_MIDDLE, data[6] & 0x02); - input_report_key(input, BTN_RIGHT, data[6] & 0x04); - input_report_rel(input, REL_WHEEL, ((data[7] & 0x80) >> 7) - - ((data[7] & 0x40) >> 6)); - input_report_key(input, BTN_SIDE, data[6] & 0x08); - input_report_key(input, BTN_EXTRA, data[6] & 0x10); - - input_report_abs(input, ABS_TILT_X, - (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); - input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); - } else { - /* 2D mouse packet */ - input_report_key(input, BTN_LEFT, data[8] & 0x04); - input_report_key(input, BTN_MIDDLE, data[8] & 0x08); - input_report_key(input, BTN_RIGHT, data[8] & 0x10); - input_report_rel(input, REL_WHEEL, (data[8] & 0x01) - - ((data[8] & 0x02) >> 1)); - - /* I3 2D mouse side buttons */ - if (features->type >= INTUOS3S && features->type <= INTUOS3L) { - input_report_key(input, BTN_SIDE, data[8] & 0x40); - input_report_key(input, BTN_EXTRA, data[8] & 0x20); - } + input_report_abs(input, ABS_TILT_X, + (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); + input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); + break; + + case 0x08: + if (wacom->tool[idx] == BTN_TOOL_MOUSE) { + /* 2D mouse packet */ + input_report_key(input, BTN_LEFT, data[8] & 0x04); + input_report_key(input, BTN_MIDDLE, data[8] & 0x08); + input_report_key(input, BTN_RIGHT, data[8] & 0x10); + input_report_rel(input, REL_WHEEL, (data[8] & 0x01) + - ((data[8] & 0x02) >> 1)); + + /* I3 2D mouse side buttons */ + if (features->type >= INTUOS3S && features->type <= INTUOS3L) { + input_report_key(input, BTN_SIDE, data[8] & 0x40); + input_report_key(input, BTN_EXTRA, data[8] & 0x20); } } - else if ((features->type < INTUOS3S || features->type == INTUOS3L || - features->type == INTUOS4L || features->type == INTUOS5L || - features->type == INTUOSPL) && - wacom->tool[idx] == BTN_TOOL_LENS) { + else if (wacom->tool[idx] == BTN_TOOL_LENS) { /* Lens cursor packets */ input_report_key(input, BTN_LEFT, data[8] & 0x01); input_report_key(input, BTN_MIDDLE, data[8] & 0x02); @@ -1008,7 +1001,9 @@ static int wacom_intuos_general(struct wacom_wac *wacom) } break; + case 0x07: case 0x09: + case 0x0b: case 0x0c: case 0x0d: case 0x0e: -- GitLab From 5f33f430efe3ce2dfe4e9c5eeabb89ea5df145b6 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 30 Nov 2015 17:13:51 -0800 Subject: [PATCH 0867/2855] HID: wacom: Clean up value reading Make the logic for reading X, Y, distance, and pressure a bit more clear. An additional bit was stuffed into the packet format many models back, and /most/ devices in use will use it. If we happen to be dealing with a particularly old tablet, just shift it off the end to pretend we never read it. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index ce3afab806cc5..0008650e3bdb5 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -887,21 +887,23 @@ static int wacom_intuos_general(struct wacom_wac *wacom) struct input_dev *input = wacom->pen_input; int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0; unsigned char type = (data[1] >> 1) & 0x0F; - unsigned int t; + unsigned int x, y, distance, t; if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_CINTIQ && data[0] != WACOM_REPORT_INTUOS_PEN) return 0; - if (features->type >= INTUOS3S) { - input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); - input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); - input_report_abs(input, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); - } else { - input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[2])); - input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[4])); - input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); + x = (be16_to_cpup((__be16 *)&data[2]) << 1) | ((data[9] >> 1) & 1); + y = (be16_to_cpup((__be16 *)&data[4]) << 1) | (data[9] & 1); + distance = data[9] >> 2; + if (features->type < INTUOS3S) { + x >>= 1; + y >>= 1; + distance >>= 1; } + input_report_abs(input, ABS_X, x); + input_report_abs(input, ABS_Y, y); + input_report_abs(input, ABS_DISTANCE, distance); switch (type) { case 0x00: @@ -909,10 +911,9 @@ static int wacom_intuos_general(struct wacom_wac *wacom) case 0x02: case 0x03: /* general pen packet */ - t = (data[6] << 2) | ((data[7] >> 6) & 3); - if (features->pressure_max == 2047) { - t = (t << 1) | (data[1] & 1); - } + t = (data[6] << 3) | ((data[7] & 0xC0) >> 5) | (data[1] & 1); + if (features->pressure_max < 2047) + t >>= 1; input_report_abs(input, ABS_PRESSURE, t); if (features->type != INTUOSHT2) { input_report_abs(input, ABS_TILT_X, -- GitLab From 061099936a724cdd8dd0d69deea5b064b4f7122b Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 30 Nov 2015 17:13:52 -0800 Subject: [PATCH 0868/2855] HID: wacom: Rename wacom ID report ID macros "INTUOSREAD" and "INTUOSWRITE" are poorly named. These are report IDs for pen ID (proximity) packets. It should be noted that the latter is only used on Intuos/Intuos2 for a second stylus when DualTrack is in use. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 6 +++--- drivers/hid/wacom_wac.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 0008650e3bdb5..3953416ff753b 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -443,7 +443,7 @@ static void wacom_intuos_schedule_prox_event(struct wacom_wac *wacom_wac) struct hid_report_enum *re; re = &(wacom->hdev->report_enum[HID_FEATURE_REPORT]); - r = re->report_id_hash[WACOM_REPORT_INTUOSREAD]; + r = re->report_id_hash[WACOM_REPORT_INTUOS_ID1]; if (r) { hid_hw_request(wacom->hdev, r, HID_REQ_GET_REPORT); } @@ -1027,8 +1027,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) int result; if (data[0] != WACOM_REPORT_PENABLED && - data[0] != WACOM_REPORT_INTUOSREAD && - data[0] != WACOM_REPORT_INTUOSWRITE && + data[0] != WACOM_REPORT_INTUOS_ID1 && + data[0] != WACOM_REPORT_INTUOS_ID2 && data[0] != WACOM_REPORT_INTUOSPAD && data[0] != WACOM_REPORT_INTUOS_PEN && data[0] != WACOM_REPORT_CINTIQ && diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 877c24a5df94a..3f60192e92726 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -47,8 +47,8 @@ /* wacom data packet report IDs */ #define WACOM_REPORT_PENABLED 2 #define WACOM_REPORT_PENABLED_BT 3 -#define WACOM_REPORT_INTUOSREAD 5 -#define WACOM_REPORT_INTUOSWRITE 6 +#define WACOM_REPORT_INTUOS_ID1 5 +#define WACOM_REPORT_INTUOS_ID2 6 #define WACOM_REPORT_INTUOSPAD 12 #define WACOM_REPORT_INTUOS5PAD 3 #define WACOM_REPORT_DTUSPAD 21 -- GitLab From 41f95dd2efd80a611c8566888fcdcb5d399ea474 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:41 +0100 Subject: [PATCH 0869/2855] scsi_dh: move 'dh_state' sysfs attribute to generic code As scsi_dh.c is now always compiled in we should be moving the 'dh_state' attribute to the generic code. Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Signed-off-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_dh.c | 72 +-------------------------------------- drivers/scsi/scsi_priv.h | 3 +- drivers/scsi/scsi_sysfs.c | 58 +++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 73 deletions(-) diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c index e7649ed3f6677..54d446c9f56e0 100644 --- a/drivers/scsi/scsi_dh.c +++ b/drivers/scsi/scsi_dh.c @@ -153,76 +153,11 @@ static void scsi_dh_handler_detach(struct scsi_device *sdev) module_put(sdev->handler->module); } -/* - * Functions for sysfs attribute 'dh_state' - */ -static ssize_t -store_dh_state(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct scsi_device *sdev = to_scsi_device(dev); - struct scsi_device_handler *scsi_dh; - int err = -EINVAL; - - if (sdev->sdev_state == SDEV_CANCEL || - sdev->sdev_state == SDEV_DEL) - return -ENODEV; - - if (!sdev->handler) { - /* - * Attach to a device handler - */ - scsi_dh = scsi_dh_lookup(buf); - if (!scsi_dh) - return err; - err = scsi_dh_handler_attach(sdev, scsi_dh); - } else { - if (!strncmp(buf, "detach", 6)) { - /* - * Detach from a device handler - */ - sdev_printk(KERN_WARNING, sdev, - "can't detach handler %s.\n", - sdev->handler->name); - err = -EINVAL; - } else if (!strncmp(buf, "activate", 8)) { - /* - * Activate a device handler - */ - if (sdev->handler->activate) - err = sdev->handler->activate(sdev, NULL, NULL); - else - err = 0; - } - } - - return err<0?err:count; -} - -static ssize_t -show_dh_state(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct scsi_device *sdev = to_scsi_device(dev); - - if (!sdev->handler) - return snprintf(buf, 20, "detached\n"); - - return snprintf(buf, 20, "%s\n", sdev->handler->name); -} - -static struct device_attribute scsi_dh_state_attr = - __ATTR(dh_state, S_IRUGO | S_IWUSR, show_dh_state, - store_dh_state); - int scsi_dh_add_device(struct scsi_device *sdev) { struct scsi_device_handler *devinfo = NULL; const char *drv; - int err; - - err = device_create_file(&sdev->sdev_gendev, &scsi_dh_state_attr); - if (err) - return err; + int err = 0; drv = scsi_dh_find_driver(sdev); if (drv) @@ -238,11 +173,6 @@ void scsi_dh_release_device(struct scsi_device *sdev) scsi_dh_handler_detach(sdev); } -void scsi_dh_remove_device(struct scsi_device *sdev) -{ - device_remove_file(&sdev->sdev_gendev, &scsi_dh_state_attr); -} - /* * scsi_register_device_handler - register a device handler personality * module. diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 4d01cdb1b3483..27b4d0a6a01db 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -174,12 +174,11 @@ extern struct async_domain scsi_sd_probe_domain; #ifdef CONFIG_SCSI_DH int scsi_dh_add_device(struct scsi_device *sdev); void scsi_dh_release_device(struct scsi_device *sdev); -void scsi_dh_remove_device(struct scsi_device *sdev); #else static inline int scsi_dh_add_device(struct scsi_device *sdev) { return 0; } static inline void scsi_dh_release_device(struct scsi_device *sdev) { } -static inline void scsi_dh_remove_device(struct scsi_device *sdev) { } #endif +static inline void scsi_dh_remove_device(struct scsi_device *sdev) { } /* * internal scsi timeout functions: for use by mid-layer and transport diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 158f1b553acff..fc3cd26560595 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -904,6 +905,60 @@ sdev_show_function(queue_depth, "%d\n"); static DEVICE_ATTR(queue_depth, S_IRUGO | S_IWUSR, sdev_show_queue_depth, sdev_store_queue_depth); +#ifdef CONFIG_SCSI_DH +static ssize_t +sdev_show_dh_state(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scsi_device *sdev = to_scsi_device(dev); + + if (!sdev->handler) + return snprintf(buf, 20, "detached\n"); + + return snprintf(buf, 20, "%s\n", sdev->handler->name); +} + +static ssize_t +sdev_store_dh_state(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + int err = -EINVAL; + + if (sdev->sdev_state == SDEV_CANCEL || + sdev->sdev_state == SDEV_DEL) + return -ENODEV; + + if (!sdev->handler) { + /* + * Attach to a device handler + */ + err = scsi_dh_attach(sdev->request_queue, buf); + } else if (!strncmp(buf, "activate", 8)) { + /* + * Activate a device handler + */ + if (sdev->handler->activate) + err = sdev->handler->activate(sdev, NULL, NULL); + else + err = 0; + } else if (!strncmp(buf, "detach", 6)) { + /* + * Detach from a device handler + */ + sdev_printk(KERN_WARNING, sdev, + "can't detach handler %s.\n", + sdev->handler->name); + err = -EINVAL; + } + + return err < 0 ? err : count; +} + +static DEVICE_ATTR(dh_state, S_IRUGO | S_IWUSR, sdev_show_dh_state, + sdev_store_dh_state); +#endif + static ssize_t sdev_show_queue_ramp_up_period(struct device *dev, struct device_attribute *attr, @@ -973,6 +1028,9 @@ static struct attribute *scsi_sdev_attrs[] = { &dev_attr_modalias.attr, &dev_attr_queue_depth.attr, &dev_attr_queue_type.attr, +#ifdef CONFIG_SCSI_DH + &dev_attr_dh_state.attr, +#endif &dev_attr_queue_ramp_up_period.attr, REF_EVT(media_change), REF_EVT(inquiry_change_reported), -- GitLab From 221255aee67ec1c752001080aafec0c4e9390d95 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:42 +0100 Subject: [PATCH 0870/2855] scsi: ignore errors from scsi_dh_add_device() device handler initialisation might fail due to a number of reasons. But as device_handlers are optional this shouldn't cause us to disable the device entirely. So just ignore errors from scsi_dh_add_device(). Reviewed-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_sysfs.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index fc3cd26560595..d015374f8ea92 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1120,11 +1120,12 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) } error = scsi_dh_add_device(sdev); - if (error) { + if (error) + /* + * device_handler is optional, so any error can be ignored + */ sdev_printk(KERN_INFO, sdev, "failed to add device handler: %d\n", error); - return error; - } device_enable_async_suspend(&sdev->sdev_dev); error = device_add(&sdev->sdev_dev); -- GitLab From db5a6a601ba93c69dd320a0625ce492543c37748 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:43 +0100 Subject: [PATCH 0871/2855] scsi_dh_alua: Disable ALUA handling for non-disk devices Non-disk devices might support ALUA, but the firmware implementation is untested and frequently broken. As we're don't actually need it disable ALUA support for non-disk device for now. Signed-off-by: Hannes Reinecke Reviewed-by: Bart Van Assche Reviewed-by: Christoph Hellwig Reviewed-by: Martin K. Petersen Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/device_handler/scsi_dh_alua.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index cc2773b5de68f..7d01ef0b66cc5 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -320,6 +320,18 @@ static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h) { int err = SCSI_DH_OK; + /* + * ALUA support for non-disk devices is fraught with + * difficulties, so disable it for now. + */ + if (sdev->type != TYPE_DISK) { + h->tpgs = TPGS_MODE_NONE; + sdev_printk(KERN_INFO, sdev, + "%s: disable for non-disk devices\n", + ALUA_DH_NAME); + return SCSI_DH_DEV_UNSUPP; + } + h->tpgs = scsi_device_tpgs(sdev); switch (h->tpgs) { case TPGS_MODE_EXPLICIT|TPGS_MODE_IMPLICIT: -- GitLab From 9b80dcec411e8937d94d7ca09da08ed6ca95e6ba Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:44 +0100 Subject: [PATCH 0872/2855] scsi_dh_alua: Use vpd_pg83 information The SCSI device now has the VPD page 0x83 information attached, so there is no need to query it again. [mkp: Fixed a checkpatch warning] Signed-off-by: Hannes Reinecke Reviewed-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/device_handler/scsi_dh_alua.c | 87 +++++----------------- 1 file changed, 18 insertions(+), 69 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 7d01ef0b66cc5..87c5ba86aff2a 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -130,43 +130,6 @@ static struct request *get_alua_req(struct scsi_device *sdev, return rq; } -/* - * submit_vpd_inquiry - Issue an INQUIRY VPD page 0x83 command - * @sdev: sdev the command should be sent to - */ -static int submit_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) -{ - struct request *rq; - int err = SCSI_DH_RES_TEMP_UNAVAIL; - - rq = get_alua_req(sdev, h->buff, h->bufflen, READ); - if (!rq) - goto done; - - /* Prepare the command. */ - rq->cmd[0] = INQUIRY; - rq->cmd[1] = 1; - rq->cmd[2] = 0x83; - rq->cmd[4] = h->bufflen; - rq->cmd_len = COMMAND_SIZE(INQUIRY); - - rq->sense = h->sense; - memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); - rq->sense_len = h->senselen = 0; - - err = blk_execute_rq(rq->q, NULL, rq, 1); - if (err == -EIO) { - sdev_printk(KERN_INFO, sdev, - "%s: evpd inquiry failed with %x\n", - ALUA_DH_NAME, rq->errors); - h->senselen = rq->sense_len; - err = SCSI_DH_IO; - } - blk_put_request(rq); -done: - return err; -} - /* * submit_rtpg - Issue a REPORT TARGET GROUP STATES command * @sdev: sdev the command should be sent to @@ -359,43 +322,29 @@ static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h) } /* - * alua_vpd_inquiry - Evaluate INQUIRY vpd page 0x83 + * alua_check_vpd - Evaluate INQUIRY vpd page 0x83 * @sdev: device to be checked * * Extract the relative target port and the target port group * descriptor from the list of identificators. */ -static int alua_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) +static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h) { - int len; - unsigned err; unsigned char *d; + unsigned char __rcu *vpd_pg83; - retry: - err = submit_vpd_inquiry(sdev, h); - - if (err != SCSI_DH_OK) - return err; - - /* Check if vpd page exceeds initial buffer */ - len = (h->buff[2] << 8) + h->buff[3] + 4; - if (len > h->bufflen) { - /* Resubmit with the correct length */ - if (realloc_buffer(h, len)) { - sdev_printk(KERN_WARNING, sdev, - "%s: kmalloc buffer failed\n", - ALUA_DH_NAME); - /* Temporary failure, bypass */ - return SCSI_DH_DEV_TEMP_BUSY; - } - goto retry; + rcu_read_lock(); + if (!rcu_dereference(sdev->vpd_pg83)) { + rcu_read_unlock(); + return SCSI_DH_DEV_UNSUPP; } /* - * Now look for the correct descriptor. + * Look for the correct descriptor. */ - d = h->buff + 4; - while (d < h->buff + len) { + vpd_pg83 = rcu_dereference(sdev->vpd_pg83); + d = vpd_pg83 + 4; + while (d < vpd_pg83 + sdev->vpd_pg83_len) { switch (d[1] & 0xf) { case 0x4: /* Relative target port */ @@ -410,6 +359,7 @@ static int alua_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) } d += d[3] + 4; } + rcu_read_unlock(); if (h->group_id == -1) { /* @@ -422,14 +372,13 @@ static int alua_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) ALUA_DH_NAME); h->state = TPGS_STATE_OPTIMIZED; h->tpgs = TPGS_MODE_NONE; - err = SCSI_DH_DEV_UNSUPP; - } else { - sdev_printk(KERN_INFO, sdev, - "%s: port group %02x rel port %02x\n", - ALUA_DH_NAME, h->group_id, h->rel_port); + return SCSI_DH_DEV_UNSUPP; } + sdev_printk(KERN_INFO, sdev, + "%s: port group %02x rel port %02x\n", + ALUA_DH_NAME, h->group_id, h->rel_port); - return err; + return 0; } static char print_alua_state(int state) @@ -692,7 +641,7 @@ static int alua_initialize(struct scsi_device *sdev, struct alua_dh_data *h) if (err != SCSI_DH_OK) goto out; - err = alua_vpd_inquiry(sdev, h); + err = alua_check_vpd(sdev, h); if (err != SCSI_DH_OK) goto out; -- GitLab From 6cc05d451cfa876014ef607516f730623e317987 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:45 +0100 Subject: [PATCH 0873/2855] scsi_dh_alua: improved logging Issue different logging messages if ALUA is not supported or the TPGS setting is invalid. Signed-off-by: Hannes Reinecke Reviewed-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/device_handler/scsi_dh_alua.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 87c5ba86aff2a..31a971f35d831 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -310,12 +310,18 @@ static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h) sdev_printk(KERN_INFO, sdev, "%s: supports implicit TPGS\n", ALUA_DH_NAME); break; - default: - h->tpgs = TPGS_MODE_NONE; + case TPGS_MODE_NONE: sdev_printk(KERN_INFO, sdev, "%s: not supported\n", ALUA_DH_NAME); err = SCSI_DH_DEV_UNSUPP; break; + default: + sdev_printk(KERN_INFO, sdev, + "%s: unsupported TPGS setting %d\n", + ALUA_DH_NAME, h->tpgs); + h->tpgs = TPGS_MODE_NONE; + err = SCSI_DH_DEV_UNSUPP; + break; } return err; -- GitLab From d3692a3d13e8ee2e371907d67d585d42297b4d66 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:46 +0100 Subject: [PATCH 0874/2855] scsi_dh_alua: sanitze sense code handling The only check for a valid sense code is calling scsi_normalize_sense() and check the return value. So drop the pointless checks and rely on scsi_normalize_sense() to figure out if the sense code is valid. With that we can also remove the 'senselen' field. Signed-off-by: Hannes Reinecke Reviewed-by: Johannes Thumshirn Reviewed-by: Bart van Assche Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/device_handler/scsi_dh_alua.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 31a971f35d831..0bbde139d94d5 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -73,7 +73,6 @@ struct alua_dh_data { int bufflen; unsigned char transition_tmo; unsigned char sense[SCSI_SENSE_BUFFERSIZE]; - int senselen; struct scsi_device *sdev; activate_complete callback_fn; void *callback_data; @@ -158,14 +157,13 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, rq->sense = h->sense; memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); - rq->sense_len = h->senselen = 0; + rq->sense_len = 0; err = blk_execute_rq(rq->q, NULL, rq, 1); if (err == -EIO) { sdev_printk(KERN_INFO, sdev, "%s: rtpg failed with %x\n", ALUA_DH_NAME, rq->errors); - h->senselen = rq->sense_len; err = SCSI_DH_IO; } blk_put_request(rq); @@ -194,9 +192,8 @@ static void stpg_endio(struct request *req, int error) goto done; } - if (req->sense_len > 0) { - err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, - &sense_hdr); + if (scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, + &sense_hdr)) { if (!err) { err = SCSI_DH_IO; goto done; @@ -265,7 +262,7 @@ static unsigned submit_stpg(struct alua_dh_data *h) rq->sense = h->sense; memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); - rq->sense_len = h->senselen = 0; + rq->sense_len = 0; rq->end_io_data = h; blk_execute_rq_nowait(rq->q, NULL, rq, 1, stpg_endio); @@ -514,10 +511,9 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ retry: err = submit_rtpg(sdev, h, rtpg_ext_hdr_req); - if (err == SCSI_DH_IO && h->senselen > 0) { - err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, - &sense_hdr); - if (!err) + if (err == SCSI_DH_IO) { + if (!scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, + &sense_hdr)) return SCSI_DH_IO; /* -- GitLab From 80bd68d6bf06bc8851db4b93ee6cb067115098c0 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:47 +0100 Subject: [PATCH 0875/2855] scsi_dh_alua: use standard logging functions Use standard logging functions instead of hand-crafted ones. Signed-off-by: Hannes Reinecke Reviewed-by: Ewan Milne Reviewed-by: Bart Van Assche Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/device_handler/scsi_dh_alua.c | 27 +++++++++++----------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 0bbde139d94d5..63824992532ec 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -194,19 +195,14 @@ static void stpg_endio(struct request *req, int error) if (scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, &sense_hdr)) { - if (!err) { - err = SCSI_DH_IO; - goto done; - } err = alua_check_sense(h->sdev, &sense_hdr); if (err == ADD_TO_MLQUEUE) { err = SCSI_DH_RETRY; goto done; } - sdev_printk(KERN_INFO, h->sdev, - "%s: stpg sense code: %02x/%02x/%02x\n", - ALUA_DH_NAME, sense_hdr.sense_key, - sense_hdr.asc, sense_hdr.ascq); + sdev_printk(KERN_INFO, h->sdev, "%s: stpg failed\n", + ALUA_DH_NAME); + scsi_print_sense_hdr(h->sdev, ALUA_DH_NAME, &sense_hdr); err = SCSI_DH_IO; } else if (error) err = SCSI_DH_IO; @@ -532,13 +528,16 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ } err = alua_check_sense(sdev, &sense_hdr); - if (err == ADD_TO_MLQUEUE && time_before(jiffies, expiry)) + if (err == ADD_TO_MLQUEUE && time_before(jiffies, expiry)) { + sdev_printk(KERN_ERR, sdev, "%s: rtpg retry\n", + ALUA_DH_NAME); + scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr); goto retry; - sdev_printk(KERN_INFO, sdev, - "%s: rtpg sense code %02x/%02x/%02x\n", - ALUA_DH_NAME, sense_hdr.sense_key, - sense_hdr.asc, sense_hdr.ascq); - err = SCSI_DH_IO; + } + sdev_printk(KERN_ERR, sdev, "%s: rtpg failed\n", + ALUA_DH_NAME); + scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr); + return SCSI_DH_IO; } if (err != SCSI_DH_OK) return err; -- GitLab From 5597cafc7aabc6ba1d218a334090988cb37c016a Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:48 +0100 Subject: [PATCH 0876/2855] scsi_dh_alua: return standard SCSI return codes in submit_rtpg Fixup submit_rtpg() to always return a standard SCSI return code. Signed-off-by: Hannes Reinecke Reviewed-by: Ewan Milne Reviewed-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/device_handler/scsi_dh_alua.c | 33 +++++++++++----------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 63824992532ec..e28abf05293b8 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -138,11 +138,13 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, bool rtpg_ext_hdr_req) { struct request *rq; - int err = SCSI_DH_RES_TEMP_UNAVAIL; + int err = 0; rq = get_alua_req(sdev, h->buff, h->bufflen, READ); - if (!rq) + if (!rq) { + err = DRIVER_BUSY << 24; goto done; + } /* Prepare the command. */ rq->cmd[0] = MAINTENANCE_IN; @@ -160,13 +162,9 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); rq->sense_len = 0; - err = blk_execute_rq(rq->q, NULL, rq, 1); - if (err == -EIO) { - sdev_printk(KERN_INFO, sdev, - "%s: rtpg failed with %x\n", - ALUA_DH_NAME, rq->errors); - err = SCSI_DH_IO; - } + blk_execute_rq(rq->q, NULL, rq, 1); + if (rq->errors) + err = rq->errors; blk_put_request(rq); done: return err; @@ -493,7 +491,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ struct scsi_sense_hdr sense_hdr; int len, k, off, valid_states = 0; unsigned char *ucp; - unsigned err; + unsigned err, retval; bool rtpg_ext_hdr_req = 1; unsigned long expiry, interval = 0; unsigned int tpg_desc_tbl_off; @@ -505,12 +503,17 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ expiry = round_jiffies_up(jiffies + h->transition_tmo * HZ); retry: - err = submit_rtpg(sdev, h, rtpg_ext_hdr_req); - - if (err == SCSI_DH_IO) { + retval = submit_rtpg(sdev, h, rtpg_ext_hdr_req); + if (retval) { if (!scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, - &sense_hdr)) + &sense_hdr)) { + sdev_printk(KERN_INFO, sdev, + "%s: rtpg failed, result %d\n", + ALUA_DH_NAME, retval); + if (driver_byte(retval) == DRIVER_BUSY) + return SCSI_DH_DEV_TEMP_BUSY; return SCSI_DH_IO; + } /* * submit_rtpg() has failed on existing arrays @@ -539,8 +542,6 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr); return SCSI_DH_IO; } - if (err != SCSI_DH_OK) - return err; len = (h->buff[0] << 24) + (h->buff[1] << 16) + (h->buff[2] << 8) + h->buff[3] + 4; -- GitLab From dac173ee7e16cb51fc033a2ec9aae38576684735 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:49 +0100 Subject: [PATCH 0877/2855] scsi_dh_alua: fixup description of stpg_endio() Fixup copy-and-paste error in the description of stpg_endio(). Signed-off-by: Hannes Reinecke Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Reviewed-by: Martin K. Petersen Signed-off-by: Martin K. Petersen --- drivers/scsi/device_handler/scsi_dh_alua.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index e28abf05293b8..fdf6557f68bfc 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -171,13 +171,11 @@ done: } /* - * alua_stpg - Evaluate SET TARGET GROUP STATES + * stpg_endio - Evaluate SET TARGET GROUP STATES * @sdev: the device to be evaluated * @state: the new target group state * - * Send a SET TARGET GROUP STATES command to the device. - * We only have to test here if we should resubmit the command; - * any other error is assumed as a failure. + * Evaluate a SET TARGET GROUP STATES command response. */ static void stpg_endio(struct request *req, int error) { -- GitLab From 095077ad37043574ce7a3978e92c89f535a6612c Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:50 +0100 Subject: [PATCH 0878/2855] scsi: remove scsi_show_sense_hdr() Last caller is gone, so remove it. Signed-off-by: Hannes Reinecke Reviewed-by: Bart Van Assche Reviewed-by: Christoph Hellwig Reviewed-by: Martin K. Petersen Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- include/scsi/scsi_dbg.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h index f8170e90b49d2..56710e03101c6 100644 --- a/include/scsi/scsi_dbg.h +++ b/include/scsi/scsi_dbg.h @@ -12,8 +12,6 @@ extern size_t __scsi_format_command(char *, size_t, const unsigned char *, size_t); extern void scsi_show_extd_sense(const struct scsi_device *, const char *, unsigned char, unsigned char); -extern void scsi_show_sense_hdr(const struct scsi_device *, const char *, - const struct scsi_sense_hdr *); extern void scsi_print_sense_hdr(const struct scsi_device *, const char *, const struct scsi_sense_hdr *); extern void scsi_print_sense(const struct scsi_cmnd *); -- GitLab From 6c4fc04491754834d5b5be189ee8f49a1d92b433 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:51 +0100 Subject: [PATCH 0879/2855] scsi_dh_alua: use flag for RTPG extended header We should be using a flag when RTPG extended header is not supported, that saves us sending RTPG twice for older arrays. Signed-off-by: Hannes Reinecke Reviewed-by: Bart Van Assche Reviewed-by: Christoph Hellwig Reviewed-by: Martin K. Petersen Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/device_handler/scsi_dh_alua.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index fdf6557f68bfc..d99fc14370cca 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -59,8 +59,9 @@ #define ALUA_FAILOVER_TIMEOUT 60 #define ALUA_FAILOVER_RETRIES 5 -/* flags passed from user level */ +/* device handler flags */ #define ALUA_OPTIMIZE_STPG 1 +#define ALUA_RTPG_EXT_HDR_UNSUPP 2 struct alua_dh_data { int group_id; @@ -134,8 +135,7 @@ static struct request *get_alua_req(struct scsi_device *sdev, * submit_rtpg - Issue a REPORT TARGET GROUP STATES command * @sdev: sdev the command should be sent to */ -static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, - bool rtpg_ext_hdr_req) +static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) { struct request *rq; int err = 0; @@ -148,7 +148,7 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, /* Prepare the command. */ rq->cmd[0] = MAINTENANCE_IN; - if (rtpg_ext_hdr_req) + if (!(h->flags & ALUA_RTPG_EXT_HDR_UNSUPP)) rq->cmd[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT; else rq->cmd[1] = MI_REPORT_TARGET_PGS; @@ -490,7 +490,6 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ int len, k, off, valid_states = 0; unsigned char *ucp; unsigned err, retval; - bool rtpg_ext_hdr_req = 1; unsigned long expiry, interval = 0; unsigned int tpg_desc_tbl_off; unsigned char orig_transition_tmo; @@ -501,7 +500,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ expiry = round_jiffies_up(jiffies + h->transition_tmo * HZ); retry: - retval = submit_rtpg(sdev, h, rtpg_ext_hdr_req); + retval = submit_rtpg(sdev, h); if (retval) { if (!scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, &sense_hdr)) { @@ -521,10 +520,10 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ * The retry without rtpg_ext_hdr_req set * handles this. */ - if (rtpg_ext_hdr_req == 1 && + if (!(h->flags & ALUA_RTPG_EXT_HDR_UNSUPP) && sense_hdr.sense_key == ILLEGAL_REQUEST && sense_hdr.asc == 0x24 && sense_hdr.ascq == 0) { - rtpg_ext_hdr_req = 0; + h->flags |= ALUA_RTPG_EXT_HDR_UNSUPP; goto retry; } -- GitLab From a7089770b95902854f48b3bc7bec026dc8403286 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:52 +0100 Subject: [PATCH 0880/2855] scsi_dh_alua: use unaligned access macros Use 'get_unaligned_XX' and 'put_unaligned_XX' instead of open-coding it. Signed-off-by: Hannes Reinecke Reviewed-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/device_handler/scsi_dh_alua.c | 23 ++++++++-------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index d99fc14370cca..1c8e538d4a2e9 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -152,10 +153,7 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) rq->cmd[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT; else rq->cmd[1] = MI_REPORT_TARGET_PGS; - rq->cmd[6] = (h->bufflen >> 24) & 0xff; - rq->cmd[7] = (h->bufflen >> 16) & 0xff; - rq->cmd[8] = (h->bufflen >> 8) & 0xff; - rq->cmd[9] = h->bufflen & 0xff; + put_unaligned_be32(h->bufflen, &rq->cmd[6]); rq->cmd_len = COMMAND_SIZE(MAINTENANCE_IN); rq->sense = h->sense; @@ -236,8 +234,7 @@ static unsigned submit_stpg(struct alua_dh_data *h) /* Prepare the data buffer */ memset(h->buff, 0, stpg_len); h->buff[4] = TPGS_STATE_OPTIMIZED & 0x0f; - h->buff[6] = (h->group_id >> 8) & 0xff; - h->buff[7] = h->group_id & 0xff; + put_unaligned_be16(h->group_id, &h->buff[6]); rq = get_alua_req(sdev, h->buff, stpg_len, WRITE); if (!rq) @@ -246,10 +243,7 @@ static unsigned submit_stpg(struct alua_dh_data *h) /* Prepare the command. */ rq->cmd[0] = MAINTENANCE_OUT; rq->cmd[1] = MO_SET_TARGET_PGS; - rq->cmd[6] = (stpg_len >> 24) & 0xff; - rq->cmd[7] = (stpg_len >> 16) & 0xff; - rq->cmd[8] = (stpg_len >> 8) & 0xff; - rq->cmd[9] = stpg_len & 0xff; + put_unaligned_be32(stpg_len, &rq->cmd[6]); rq->cmd_len = COMMAND_SIZE(MAINTENANCE_OUT); rq->sense = h->sense; @@ -343,11 +337,11 @@ static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h) switch (d[1] & 0xf) { case 0x4: /* Relative target port */ - h->rel_port = (d[6] << 8) + d[7]; + h->rel_port = get_unaligned_be16(&d[6]); break; case 0x5: /* Target port group */ - h->group_id = (d[6] << 8) + d[7]; + h->group_id = get_unaligned_be16(&d[6]); break; default: break; @@ -540,8 +534,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ return SCSI_DH_IO; } - len = (h->buff[0] << 24) + (h->buff[1] << 16) + - (h->buff[2] << 8) + h->buff[3] + 4; + len = get_unaligned_be32(&h->buff[0]) + 4; if (len > h->bufflen) { /* Resubmit with the correct length */ @@ -576,7 +569,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ k < len; k += off, ucp += off) { - if (h->group_id == (ucp[2] << 8) + ucp[3]) { + if (h->group_id == get_unaligned_be16(&ucp[2])) { h->state = ucp[0] & 0x0f; h->pref = ucp[0] >> 7; valid_states = ucp[1]; -- GitLab From ad0ea64c53f5808e29784812fbb0c300f3a89d39 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:53 +0100 Subject: [PATCH 0881/2855] scsi_dh_alua: rework alua_check_tpgs() to return the tpgs mode Instead of returning an error code in alua_check_tpgs() we should rather return the tpgs mode directly and have a cleaner syntax. Signed-off-by: Hannes Reinecke Reviewed-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/device_handler/scsi_dh_alua.c | 25 ++++++++++------------ 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 1c8e538d4a2e9..7a34ffb41382b 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -262,24 +262,23 @@ static unsigned submit_stpg(struct alua_dh_data *h) * Examine the TPGS setting of the sdev to find out if ALUA * is supported. */ -static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h) +static int alua_check_tpgs(struct scsi_device *sdev) { - int err = SCSI_DH_OK; + int tpgs = TPGS_MODE_NONE; /* * ALUA support for non-disk devices is fraught with * difficulties, so disable it for now. */ if (sdev->type != TYPE_DISK) { - h->tpgs = TPGS_MODE_NONE; sdev_printk(KERN_INFO, sdev, "%s: disable for non-disk devices\n", ALUA_DH_NAME); - return SCSI_DH_DEV_UNSUPP; + return tpgs; } - h->tpgs = scsi_device_tpgs(sdev); - switch (h->tpgs) { + tpgs = scsi_device_tpgs(sdev); + switch (tpgs) { case TPGS_MODE_EXPLICIT|TPGS_MODE_IMPLICIT: sdev_printk(KERN_INFO, sdev, "%s: supports implicit and explicit TPGS\n", @@ -296,18 +295,16 @@ static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h) case TPGS_MODE_NONE: sdev_printk(KERN_INFO, sdev, "%s: not supported\n", ALUA_DH_NAME); - err = SCSI_DH_DEV_UNSUPP; break; default: sdev_printk(KERN_INFO, sdev, "%s: unsupported TPGS setting %d\n", - ALUA_DH_NAME, h->tpgs); - h->tpgs = TPGS_MODE_NONE; - err = SCSI_DH_DEV_UNSUPP; + ALUA_DH_NAME, tpgs); + tpgs = TPGS_MODE_NONE; break; } - return err; + return tpgs; } /* @@ -627,10 +624,10 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ */ static int alua_initialize(struct scsi_device *sdev, struct alua_dh_data *h) { - int err; + int err = SCSI_DH_DEV_UNSUPP; - err = alua_check_tpgs(sdev, h); - if (err != SCSI_DH_OK) + h->tpgs = alua_check_tpgs(sdev); + if (h->tpgs == TPGS_MODE_NONE) goto out; err = alua_check_vpd(sdev, h); -- GitLab From e2d817db32027c25a1702f667fbf0bf6a73fc68c Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:54 +0100 Subject: [PATCH 0882/2855] scsi_dh_alua: simplify sense code handling Most sense code is already handled in the generic code, so we shouldn't be adding special cases here. However, when doing so we need to check for unit attention whenever we're sending an internal command. Signed-off-by: Hannes Reinecke Reviewed-by: Ewan Milne Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/device_handler/scsi_dh_alua.c | 45 ++++++++-------------- 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 7a34ffb41382b..39654b1703b34 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -85,7 +85,6 @@ struct alua_dh_data { #define ALUA_POLICY_SWITCH_ALL 1 static char print_alua_state(int); -static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *); static int realloc_buffer(struct alua_dh_data *h, unsigned len) { @@ -189,8 +188,13 @@ static void stpg_endio(struct request *req, int error) if (scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, &sense_hdr)) { - err = alua_check_sense(h->sdev, &sense_hdr); - if (err == ADD_TO_MLQUEUE) { + if (sense_hdr.sense_key == NOT_READY && + sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a) { + /* ALUA state transition already in progress */ + err = SCSI_DH_OK; + goto done; + } + if (sense_hdr.sense_key == UNIT_ATTENTION) { err = SCSI_DH_RETRY; goto done; } @@ -399,28 +403,6 @@ static int alua_check_sense(struct scsi_device *sdev, * LUN Not Accessible - ALUA state transition */ return ADD_TO_MLQUEUE; - if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0b) - /* - * LUN Not Accessible -- Target port in standby state - */ - return SUCCESS; - if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0c) - /* - * LUN Not Accessible -- Target port in unavailable state - */ - return SUCCESS; - if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x12) - /* - * LUN Not Ready -- Offline - */ - return SUCCESS; - if (sdev->allow_restart && - sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x02) - /* - * if the device is not started, we need to wake - * the error handler to start the motor - */ - return FAILED; break; case UNIT_ATTENTION: if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00) @@ -517,9 +499,16 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ h->flags |= ALUA_RTPG_EXT_HDR_UNSUPP; goto retry; } - - err = alua_check_sense(sdev, &sense_hdr); - if (err == ADD_TO_MLQUEUE && time_before(jiffies, expiry)) { + /* + * Retry on ALUA state transition or if any + * UNIT ATTENTION occurred. + */ + if (sense_hdr.sense_key == NOT_READY && + sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a) + err = SCSI_DH_RETRY; + else if (sense_hdr.sense_key == UNIT_ATTENTION) + err = SCSI_DH_RETRY; + if (err == SCSI_DH_RETRY && time_before(jiffies, expiry)) { sdev_printk(KERN_ERR, sdev, "%s: rtpg retry\n", ALUA_DH_NAME); scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr); -- GitLab From 9983bed3907c379d1d30b7509bb0a871ed655f9d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:55 +0100 Subject: [PATCH 0883/2855] scsi: Add scsi_vpd_lun_id() Add a function scsi_vpd_lun_id() to return a unique device identifcation based on the designation descriptors of VPD page 0x83. As devices might implement several descriptors the order of preference is: - NAA IEE Registered Extended - EUI-64 based 16-byte - EUI-64 based 12-byte - NAA IEEE Registered - NAA IEEE Extended A SCSI name string descriptor is preferred to all of them if the identification is longer than 16 bytes. The returned unique device identification will be formatted as a SCSI Name string to avoid clashes between different designator types. [mkp: Fixed up kernel doc comment from Johannes] Signed-off-by: Hannes Reinecke Reviewed-by: Ewan Milne Reviewed-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_lib.c | 140 +++++++++++++++++++++++++++++++++++++ include/scsi/scsi_device.h | 1 + 2 files changed, 141 insertions(+) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index dd8ad2a44510c..e352c2b7deaf1 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -3154,3 +3154,143 @@ void sdev_enable_disk_events(struct scsi_device *sdev) atomic_dec(&sdev->disk_events_disable_depth); } EXPORT_SYMBOL(sdev_enable_disk_events); + +/** + * scsi_vpd_lun_id - return a unique device identification + * @sdev: SCSI device + * @id: buffer for the identification + * @id_len: length of the buffer + * + * Copies a unique device identification into @id based + * on the information in the VPD page 0x83 of the device. + * The string will be formatted as a SCSI name string. + * + * Returns the length of the identification or error on failure. + * If the identifier is longer than the supplied buffer the actual + * identifier length is returned and the buffer is not zero-padded. + */ +int scsi_vpd_lun_id(struct scsi_device *sdev, char *id, size_t id_len) +{ + u8 cur_id_type = 0xff; + u8 cur_id_size = 0; + unsigned char *d, *cur_id_str; + unsigned char __rcu *vpd_pg83; + int id_size = -EINVAL; + + rcu_read_lock(); + vpd_pg83 = rcu_dereference(sdev->vpd_pg83); + if (!vpd_pg83) { + rcu_read_unlock(); + return -ENXIO; + } + + /* + * Look for the correct descriptor. + * Order of preference for lun descriptor: + * - SCSI name string + * - NAA IEEE Registered Extended + * - EUI-64 based 16-byte + * - EUI-64 based 12-byte + * - NAA IEEE Registered + * - NAA IEEE Extended + * as longer descriptors reduce the likelyhood + * of identification clashes. + */ + + /* The id string must be at least 20 bytes + terminating NULL byte */ + if (id_len < 21) { + rcu_read_unlock(); + return -EINVAL; + } + + memset(id, 0, id_len); + d = vpd_pg83 + 4; + while (d < vpd_pg83 + sdev->vpd_pg83_len) { + /* Skip designators not referring to the LUN */ + if ((d[1] & 0x30) != 0x00) + goto next_desig; + + switch (d[1] & 0xf) { + case 0x2: + /* EUI-64 */ + if (cur_id_size > d[3]) + break; + /* Prefer NAA IEEE Registered Extended */ + if (cur_id_type == 0x3 && + cur_id_size == d[3]) + break; + cur_id_size = d[3]; + cur_id_str = d + 4; + cur_id_type = d[1] & 0xf; + switch (cur_id_size) { + case 8: + id_size = snprintf(id, id_len, + "eui.%8phN", + cur_id_str); + break; + case 12: + id_size = snprintf(id, id_len, + "eui.%12phN", + cur_id_str); + break; + case 16: + id_size = snprintf(id, id_len, + "eui.%16phN", + cur_id_str); + break; + default: + cur_id_size = 0; + break; + } + break; + case 0x3: + /* NAA */ + if (cur_id_size > d[3]) + break; + cur_id_size = d[3]; + cur_id_str = d + 4; + cur_id_type = d[1] & 0xf; + switch (cur_id_size) { + case 8: + id_size = snprintf(id, id_len, + "naa.%8phN", + cur_id_str); + break; + case 16: + id_size = snprintf(id, id_len, + "naa.%16phN", + cur_id_str); + break; + default: + cur_id_size = 0; + break; + } + break; + case 0x8: + /* SCSI name string */ + if (cur_id_size + 4 > d[3]) + break; + /* Prefer others for truncated descriptor */ + if (cur_id_size && d[3] > id_len) + break; + cur_id_size = id_size = d[3]; + cur_id_str = d + 4; + cur_id_type = d[1] & 0xf; + if (cur_id_size >= id_len) + cur_id_size = id_len - 1; + memcpy(id, cur_id_str, cur_id_size); + /* Decrease priority for truncated descriptor */ + if (cur_id_size != id_size) + cur_id_size = 6; + break; + default: + break; + } +next_desig: + d += d[3] + 4; + } + rcu_read_unlock(); + + return id_size; +} +EXPORT_SYMBOL(scsi_vpd_lun_id); diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index bde4077f2864a..4c49cfa25cac5 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -415,6 +415,7 @@ static inline int scsi_execute_req(struct scsi_device *sdev, } extern void sdev_disable_disk_events(struct scsi_device *sdev); extern void sdev_enable_disk_events(struct scsi_device *sdev); +extern int scsi_vpd_lun_id(struct scsi_device *, char *, size_t); #ifdef CONFIG_PM extern int scsi_autopm_get_device(struct scsi_device *); -- GitLab From 248d4fe95f232010846bc648ce92e40b07544c5d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:56 +0100 Subject: [PATCH 0884/2855] scsi: export 'wwid' to sysfs Use scsi_vpd_lun_id() to export the world-wide unique id (wwid) to sysfs. Note that this is the 'best' wwid according to the rules in scsi_vpd_lun_id(), not every possible wwid presented by the drive. Signed-off-by: Hannes Reinecke Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_sysfs.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index d015374f8ea92..ef360533790d2 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -905,6 +905,22 @@ sdev_show_function(queue_depth, "%d\n"); static DEVICE_ATTR(queue_depth, S_IRUGO | S_IWUSR, sdev_show_queue_depth, sdev_store_queue_depth); +static ssize_t +sdev_show_wwid(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scsi_device *sdev = to_scsi_device(dev); + ssize_t count; + + count = scsi_vpd_lun_id(sdev, buf, PAGE_SIZE); + if (count > 0) { + buf[count] = '\n'; + count++; + } + return count; +} +static DEVICE_ATTR(wwid, S_IRUGO, sdev_show_wwid, NULL); + #ifdef CONFIG_SCSI_DH static ssize_t sdev_show_dh_state(struct device *dev, struct device_attribute *attr, @@ -1028,6 +1044,7 @@ static struct attribute *scsi_sdev_attrs[] = { &dev_attr_modalias.attr, &dev_attr_queue_depth.attr, &dev_attr_queue_type.attr, + &dev_attr_wwid.attr, #ifdef CONFIG_SCSI_DH &dev_attr_dh_state.attr, #endif -- GitLab From a8aa3978588a4fa2d9edabc151adedd97bbed091 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:57 +0100 Subject: [PATCH 0885/2855] scsi: Add scsi_vpd_tpg_id() Implement scsi_vpd_tpg_id() to extract the target port group id and the relative port id from SCSI VPD page 0x83. Reviewed-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_lib.c | 48 ++++++++++++++++++++++++++++++++++++++ include/scsi/scsi_device.h | 1 + 2 files changed, 49 insertions(+) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index e352c2b7deaf1..fa6b2c4eb7a2b 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -3294,3 +3295,50 @@ next_desig: return id_size; } EXPORT_SYMBOL(scsi_vpd_lun_id); + +/* + * scsi_vpd_tpg_id - return a target port group identifier + * @sdev: SCSI device + * + * Returns the Target Port Group identifier from the information + * froom VPD page 0x83 of the device. + * + * Returns the identifier or error on failure. + */ +int scsi_vpd_tpg_id(struct scsi_device *sdev, int *rel_id) +{ + unsigned char *d; + unsigned char __rcu *vpd_pg83; + int group_id = -EAGAIN, rel_port = -1; + + rcu_read_lock(); + vpd_pg83 = rcu_dereference(sdev->vpd_pg83); + if (!vpd_pg83) { + rcu_read_unlock(); + return -ENXIO; + } + + d = sdev->vpd_pg83 + 4; + while (d < sdev->vpd_pg83 + sdev->vpd_pg83_len) { + switch (d[1] & 0xf) { + case 0x4: + /* Relative target port */ + rel_port = get_unaligned_be16(&d[6]); + break; + case 0x5: + /* Target port group */ + group_id = get_unaligned_be16(&d[6]); + break; + default: + break; + } + d += d[3] + 4; + } + rcu_read_unlock(); + + if (group_id >= 0 && rel_id && rel_port != -1) + *rel_id = rel_port; + + return group_id; +} +EXPORT_SYMBOL(scsi_vpd_tpg_id); diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 4c49cfa25cac5..f63a16760ae90 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -416,6 +416,7 @@ static inline int scsi_execute_req(struct scsi_device *sdev, extern void sdev_disable_disk_events(struct scsi_device *sdev); extern void sdev_enable_disk_events(struct scsi_device *sdev); extern int scsi_vpd_lun_id(struct scsi_device *, char *, size_t); +extern int scsi_vpd_tpg_id(struct scsi_device *, int *); #ifdef CONFIG_PM extern int scsi_autopm_get_device(struct scsi_device *); -- GitLab From 83ea0e5e3501decac0afdff25bba2ca1e78f79cc Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:58 +0100 Subject: [PATCH 0886/2855] scsi_dh_alua: use scsi_vpd_tpg_id() Use the common function 'scsi_vpd_tpg_id()' instead of open-coding it in scsi_dh_alua. [mkp: Applied by hand] Signed-off-by: Hannes Reinecke Reviewed-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/device_handler/scsi_dh_alua.c | 37 ++++------------------ 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 39654b1703b34..f100cbb7d2e19 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -322,36 +322,10 @@ static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h) { unsigned char *d; unsigned char __rcu *vpd_pg83; + int rel_port = -1, group_id; - rcu_read_lock(); - if (!rcu_dereference(sdev->vpd_pg83)) { - rcu_read_unlock(); - return SCSI_DH_DEV_UNSUPP; - } - - /* - * Look for the correct descriptor. - */ - vpd_pg83 = rcu_dereference(sdev->vpd_pg83); - d = vpd_pg83 + 4; - while (d < vpd_pg83 + sdev->vpd_pg83_len) { - switch (d[1] & 0xf) { - case 0x4: - /* Relative target port */ - h->rel_port = get_unaligned_be16(&d[6]); - break; - case 0x5: - /* Target port group */ - h->group_id = get_unaligned_be16(&d[6]); - break; - default: - break; - } - d += d[3] + 4; - } - rcu_read_unlock(); - - if (h->group_id == -1) { + group_id = scsi_vpd_tpg_id(sdev, &rel_port); + if (group_id < 0) { /* * Internal error; TPGS supported but required * VPD identification descriptors not present. @@ -360,10 +334,11 @@ static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h) sdev_printk(KERN_INFO, sdev, "%s: No target port descriptors found\n", ALUA_DH_NAME); - h->state = TPGS_STATE_OPTIMIZED; - h->tpgs = TPGS_MODE_NONE; return SCSI_DH_DEV_UNSUPP; } + h->state = TPGS_STATE_OPTIMIZED; + h->group_id = group_id; + sdev_printk(KERN_INFO, sdev, "%s: port group %02x rel port %02x\n", ALUA_DH_NAME, h->group_id, h->rel_port); -- GitLab From 889d0d42667c998a099028f845c0be074acb4b90 Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Thu, 26 Nov 2015 03:54:45 -0500 Subject: [PATCH 0887/2855] bfa: Update copyright messages Signed-off-by: Sudarsana Kalluru Signed-off-by: Anil Gurumurthy Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/bfa/bfa.h | 5 +++-- drivers/scsi/bfa/bfa_core.c | 5 +++-- drivers/scsi/bfa/bfa_cs.h | 5 +++-- drivers/scsi/bfa/bfa_defs.h | 5 +++-- drivers/scsi/bfa/bfa_defs_fcs.h | 5 +++-- drivers/scsi/bfa/bfa_defs_svc.h | 5 +++-- drivers/scsi/bfa/bfa_fc.h | 5 +++-- drivers/scsi/bfa/bfa_fcbuild.c | 5 +++-- drivers/scsi/bfa/bfa_fcbuild.h | 5 +++-- drivers/scsi/bfa/bfa_fcpim.c | 5 +++-- drivers/scsi/bfa/bfa_fcpim.h | 5 +++-- drivers/scsi/bfa/bfa_fcs.c | 5 +++-- drivers/scsi/bfa/bfa_fcs.h | 5 +++-- drivers/scsi/bfa/bfa_fcs_fcpim.c | 5 +++-- drivers/scsi/bfa/bfa_fcs_lport.c | 5 +++-- drivers/scsi/bfa/bfa_fcs_rport.c | 5 +++-- drivers/scsi/bfa/bfa_hw_cb.c | 5 +++-- drivers/scsi/bfa/bfa_hw_ct.c | 5 +++-- drivers/scsi/bfa/bfa_ioc.c | 5 +++-- drivers/scsi/bfa/bfa_ioc.h | 5 +++-- drivers/scsi/bfa/bfa_ioc_cb.c | 5 +++-- drivers/scsi/bfa/bfa_ioc_ct.c | 5 +++-- drivers/scsi/bfa/bfa_modules.h | 5 +++-- drivers/scsi/bfa/bfa_plog.h | 5 +++-- drivers/scsi/bfa/bfa_port.c | 5 +++-- drivers/scsi/bfa/bfa_port.h | 5 +++-- drivers/scsi/bfa/bfa_svc.c | 5 +++-- drivers/scsi/bfa/bfa_svc.h | 5 +++-- drivers/scsi/bfa/bfad.c | 5 +++-- drivers/scsi/bfa/bfad_attr.c | 5 +++-- drivers/scsi/bfa/bfad_bsg.c | 5 +++-- drivers/scsi/bfa/bfad_bsg.h | 5 +++-- drivers/scsi/bfa/bfad_debugfs.c | 5 +++-- drivers/scsi/bfa/bfad_drv.h | 5 +++-- drivers/scsi/bfa/bfad_im.c | 5 +++-- drivers/scsi/bfa/bfad_im.h | 5 +++-- drivers/scsi/bfa/bfi.h | 5 +++-- drivers/scsi/bfa/bfi_ms.h | 5 +++-- drivers/scsi/bfa/bfi_reg.h | 5 +++-- 39 files changed, 117 insertions(+), 78 deletions(-) diff --git a/drivers/scsi/bfa/bfa.h b/drivers/scsi/bfa/bfa.h index 4ad7e368bbc25..7d0337ba5e1b3 100644 --- a/drivers/scsi/bfa/bfa.h +++ b/drivers/scsi/bfa/bfa.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c index e3f67b097a5ca..f157a37150d7d 100644 --- a/drivers/scsi/bfa/bfa_core.c +++ b/drivers/scsi/bfa/bfa_core.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_cs.h b/drivers/scsi/bfa/bfa_cs.h index 91a8aa394db51..c8bb20aebd89c 100644 --- a/drivers/scsi/bfa/bfa_cs.h +++ b/drivers/scsi/bfa/bfa_cs.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h index 877b86dd2837d..da4f705494621 100644 --- a/drivers/scsi/bfa/bfa_defs.h +++ b/drivers/scsi/bfa/bfa_defs.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_defs_fcs.h b/drivers/scsi/bfa/bfa_defs_fcs.h index 06f0a163ca35b..5185ae33e8439 100644 --- a/drivers/scsi/bfa/bfa_defs_fcs.h +++ b/drivers/scsi/bfa/bfa_defs_fcs.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h index 638f441ffc388..fd2fa249df2ae 100644 --- a/drivers/scsi/bfa/bfa_defs_svc.h +++ b/drivers/scsi/bfa/bfa_defs_svc.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fc.h b/drivers/scsi/bfa/bfa_fc.h index 64069a0a3d0d1..7142309fd8916 100644 --- a/drivers/scsi/bfa/bfa_fc.h +++ b/drivers/scsi/bfa/bfa_fc.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcbuild.c b/drivers/scsi/bfa/bfa_fcbuild.c index dce787f6cca2e..6f670d3362aff 100644 --- a/drivers/scsi/bfa/bfa_fcbuild.c +++ b/drivers/scsi/bfa/bfa_fcbuild.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcbuild.h b/drivers/scsi/bfa/bfa_fcbuild.h index 03c753d1e5489..85e3c58a306bb 100644 --- a/drivers/scsi/bfa/bfa_fcbuild.h +++ b/drivers/scsi/bfa/bfa_fcbuild.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c index d7385d1d9c5ae..3881a729c2a05 100644 --- a/drivers/scsi/bfa/bfa_fcpim.c +++ b/drivers/scsi/bfa/bfa_fcpim.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcpim.h b/drivers/scsi/bfa/bfa_fcpim.h index e693af6e59300..0c370624ff085 100644 --- a/drivers/scsi/bfa/bfa_fcpim.h +++ b/drivers/scsi/bfa/bfa_fcpim.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index 0f19455951ec3..043d3c0680dce 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h index 42bcb970445a8..30b4555e2c4a6 100644 --- a/drivers/scsi/bfa/bfa_fcs.h +++ b/drivers/scsi/bfa/bfa_fcs.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcs_fcpim.c b/drivers/scsi/bfa/bfa_fcs_fcpim.c index 6dc7926a3edd4..4fd20d92877e5 100644 --- a/drivers/scsi/bfa/bfa_fcs_fcpim.c +++ b/drivers/scsi/bfa/bfa_fcs_fcpim.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index ff75ef8917551..d82379216926d 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c index 2035b0d643518..5559faaf458b1 100644 --- a/drivers/scsi/bfa/bfa_fcs_rport.c +++ b/drivers/scsi/bfa/bfa_fcs_rport.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c index ea24d4c6e67af..e3648d9272a37 100644 --- a/drivers/scsi/bfa/bfa_hw_cb.c +++ b/drivers/scsi/bfa/bfa_hw_cb.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c index 637527f48b400..f19bc446a70ae 100644 --- a/drivers/scsi/bfa/bfa_hw_ct.c +++ b/drivers/scsi/bfa/bfa_hw_ct.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 98f7e8cca52df..e9a7c64d5dcf2 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h index a38aafa030b35..0d6e16581f37c 100644 --- a/drivers/scsi/bfa/bfa_ioc.h +++ b/drivers/scsi/bfa/bfa_ioc.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c index 453c2f5b55611..10a0042d54336 100644 --- a/drivers/scsi/bfa/bfa_ioc_cb.c +++ b/drivers/scsi/bfa/bfa_ioc_cb.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c index bd53150e4ee00..1e5fa6126e4cb 100644 --- a/drivers/scsi/bfa/bfa_ioc_ct.c +++ b/drivers/scsi/bfa/bfa_ioc_ct.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_modules.h b/drivers/scsi/bfa/bfa_modules.h index a14c784ff3fc2..5b024158a54c8 100644 --- a/drivers/scsi/bfa/bfa_modules.h +++ b/drivers/scsi/bfa/bfa_modules.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_plog.h b/drivers/scsi/bfa/bfa_plog.h index 1c9baa68339b4..4fdba6f70d4fc 100644 --- a/drivers/scsi/bfa/bfa_plog.h +++ b/drivers/scsi/bfa/bfa_plog.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_port.c b/drivers/scsi/bfa/bfa_port.c index 8ea7697deb9bd..314548aa3d7d2 100644 --- a/drivers/scsi/bfa/bfa_port.c +++ b/drivers/scsi/bfa/bfa_port.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_port.h b/drivers/scsi/bfa/bfa_port.h index 2fcab6bc62807..ba715ceff1bf9 100644 --- a/drivers/scsi/bfa/bfa_port.h +++ b/drivers/scsi/bfa/bfa_port.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index 625225f31081a..93e588fa5712e 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h index ef07365991e75..efb04976aca54 100644 --- a/drivers/scsi/bfa/bfa_svc.h +++ b/drivers/scsi/bfa/bfa_svc.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index cc3b9d3d6d409..f298b2e8d5c37 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index 40be670a1cbc8..66cca48d8ab84 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index 023b9d42ad9a2..b9d1460efe322 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h index 90abef6915850..59aca80e16223 100644 --- a/drivers/scsi/bfa/bfad_bsg.h +++ b/drivers/scsi/bfa/bfad_bsg.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfad_debugfs.c b/drivers/scsi/bfa/bfad_debugfs.c index 74a307c0a2407..62b11d4b2fd2e 100644 --- a/drivers/scsi/bfa/bfad_debugfs.c +++ b/drivers/scsi/bfa/bfad_debugfs.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 8b97877d42cf6..58fee34b2d477 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 299c6f80d4605..efcb2470f40aa 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h index f6c1023e502a1..31434dfb3a40b 100644 --- a/drivers/scsi/bfa/bfad_im.h +++ b/drivers/scsi/bfa/bfad_im.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h index 9ef91f907decb..54c93ef439ace 100644 --- a/drivers/scsi/bfa/bfi.h +++ b/drivers/scsi/bfa/bfi.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfi_ms.h b/drivers/scsi/bfa/bfi_ms.h index 1a3fe5ad58fa7..8699be47dbc59 100644 --- a/drivers/scsi/bfa/bfi_ms.h +++ b/drivers/scsi/bfa/bfi_ms.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfi_reg.h b/drivers/scsi/bfa/bfi_reg.h index 99133bcf53f99..7d071a4db0da6 100644 --- a/drivers/scsi/bfa/bfi_reg.h +++ b/drivers/scsi/bfa/bfi_reg.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * -- GitLab From f89c2b39ce676cb08b6ed8848cde76dcb21cc672 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 2 Dec 2015 18:24:45 +0000 Subject: [PATCH 0888/2855] staging:iio:mxs-lradc Fix large integer implicitly truncated to unsigned warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The change to using BIT(20) for one of the bit shifts resulted in a constant becoming unsigned. When combined with the existing signed constants in a couple of places, this caused possible trouble, hence the warnings: drivers/staging/iio/adc/mxs-lradc.c: In function ‘mxs_lradc_complete_touch_event’: drivers/staging/iio/adc/mxs-lradc.c:325:5: warning: large integer implicitly truncated to unsigned type [-Woverflow] (((x) << LRADC_DELAY_TRIGGER_LRADCS_OFFSET) & \ ^ drivers/staging/iio/adc/mxs-lradc.c:734:7: note: in expansion of macro ‘LRADC_DELAY_TRIGGER’ LRADC_DELAY_TRIGGER(1 << TOUCHSCREEN_VCHANNEL1) | ^ LD [M] drivers/staging/iio/accel/adis16201.o drivers/staging/iio/adc/mxs-lradc.c: In function ‘mxs_lradc_buffer_preenable’: drivers/staging/iio/adc/mxs-lradc.c:322:42: warning: large integer implicitly truncated to unsigned type [-Woverflow] #define LRADC_DELAY_TRIGGER_LRADCS_MASK (0xff << 24) ^ drivers/staging/iio/adc/mxs-lradc.c:1308:29: note: in expansion of macro ‘LRADC_DELAY_TRIGGER_LRADCS_MASK’ mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK | ^ drivers/staging/iio/adc/mxs-lradc.c: In function ‘mxs_lradc_buffer_postdisable’: drivers/staging/iio/adc/mxs-lradc.c:322:42: warning: large integer implicitly truncated to unsigned type [-Woverflow] #define LRADC_DELAY_TRIGGER_LRADCS_MASK (0xff << 24) ^ drivers/staging/iio/adc/mxs-lradc.c:1327:29: note: in expansion of macro ‘LRADC_DELAY_TRIGGER_LRADCS_MASK’ mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK | The simplest fix is to force LRADC_DELAY_TRIGGER_LRADCS_MASK to be a shift of an unsigned 0xff rather than a signed one. This is ugly considering it is the only constant in the driver which is so forced, but it does deal with the issue. Fixes: e0c961bdaf27 (iio: adc: mxs-lradc: Prefer using the BIT macro) Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/mxs-lradc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index 5f1375c465e61..bb1f15224ac85 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -319,7 +319,7 @@ struct mxs_lradc { #define LRADC_CH_VALUE_OFFSET 0 #define LRADC_DELAY(n) (0xd0 + (0x10 * (n))) -#define LRADC_DELAY_TRIGGER_LRADCS_MASK (0xff << 24) +#define LRADC_DELAY_TRIGGER_LRADCS_MASK (0xffUL << 24) #define LRADC_DELAY_TRIGGER_LRADCS_OFFSET 24 #define LRADC_DELAY_TRIGGER(x) \ (((x) << LRADC_DELAY_TRIGGER_LRADCS_OFFSET) & \ -- GitLab From 3c3da12d3174891f61f0f2c672da095562f19b92 Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Thu, 26 Nov 2015 03:54:00 -0500 Subject: [PATCH 0889/2855] bfa: Fix for crash when bfa_itnim is NULL Fix a very corner case when the port gets disconnected and the BFA and FCS layers clean up references to the IT nexus. During this window if a task management command is issued by the SCSI-ML and ends up referencing a NULL itnim, it could lead to a crash. Signed-off-by: Sudarsana Kalluru Signed-off-by: Anil Gurumurthy Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/bfa/bfad_im.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index efcb2470f40aa..2c0cf8a46a47b 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -272,6 +272,19 @@ bfad_im_target_reset_send(struct bfad_s *bfad, struct scsi_cmnd *cmnd, cmnd->host_scribble = NULL; cmnd->SCp.Status = 0; bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim); + /* + * bfa_itnim can be NULL if the port gets disconnected and the bfa + * and fcs layers have cleaned up their nexus with the targets and + * the same has not been cleaned up by the shim + */ + if (bfa_itnim == NULL) { + bfa_tskim_free(tskim); + BFA_LOG(KERN_ERR, bfad, bfa_log_level, + "target reset, bfa_itnim is NULL\n"); + rc = BFA_STATUS_FAILED; + goto out; + } + memset(&scsilun, 0, sizeof(scsilun)); bfa_tskim_start(tskim, bfa_itnim, scsilun, FCP_TM_TARGET_RESET, BFAD_TARGET_RESET_TMO); @@ -327,6 +340,19 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd) cmnd->SCp.ptr = (char *)&wq; cmnd->SCp.Status = 0; bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim); + /* + * bfa_itnim can be NULL if the port gets disconnected and the bfa + * and fcs layers have cleaned up their nexus with the targets and + * the same has not been cleaned up by the shim + */ + if (bfa_itnim == NULL) { + bfa_tskim_free(tskim); + BFA_LOG(KERN_ERR, bfad, bfa_log_level, + "lun reset, bfa_itnim is NULL\n"); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + rc = FAILED; + goto out; + } int_to_scsilun(cmnd->device->lun, &scsilun); bfa_tskim_start(tskim, bfa_itnim, scsilun, FCP_TM_LUN_RESET, BFAD_LUN_RESET_TMO); -- GitLab From 31e1d5695724829759c4b5d63cd643c9f01769cc Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Thu, 26 Nov 2015 03:54:46 -0500 Subject: [PATCH 0890/2855] bfa: File header and user visible string changes Signed-off-by: Sudarsana Kalluru Signed-off-by: Anil Gurumurthy Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/bfa/bfa.h | 2 +- drivers/scsi/bfa/bfa_core.c | 2 +- drivers/scsi/bfa/bfa_cs.h | 2 +- drivers/scsi/bfa/bfa_defs.h | 2 +- drivers/scsi/bfa/bfa_defs_fcs.h | 2 +- drivers/scsi/bfa/bfa_defs_svc.h | 2 +- drivers/scsi/bfa/bfa_fc.h | 2 +- drivers/scsi/bfa/bfa_fcbuild.c | 2 +- drivers/scsi/bfa/bfa_fcbuild.h | 2 +- drivers/scsi/bfa/bfa_fcpim.c | 2 +- drivers/scsi/bfa/bfa_fcpim.h | 2 +- drivers/scsi/bfa/bfa_fcs.c | 2 +- drivers/scsi/bfa/bfa_fcs.h | 4 +- drivers/scsi/bfa/bfa_fcs_fcpim.c | 2 +- drivers/scsi/bfa/bfa_fcs_lport.c | 4 +- drivers/scsi/bfa/bfa_fcs_rport.c | 2 +- drivers/scsi/bfa/bfa_hw_cb.c | 2 +- drivers/scsi/bfa/bfa_hw_ct.c | 2 +- drivers/scsi/bfa/bfa_ioc.c | 4 +- drivers/scsi/bfa/bfa_ioc.h | 2 +- drivers/scsi/bfa/bfa_ioc_cb.c | 2 +- drivers/scsi/bfa/bfa_ioc_ct.c | 2 +- drivers/scsi/bfa/bfa_modules.h | 2 +- drivers/scsi/bfa/bfa_plog.h | 2 +- drivers/scsi/bfa/bfa_port.c | 2 +- drivers/scsi/bfa/bfa_port.h | 2 +- drivers/scsi/bfa/bfa_svc.c | 2 +- drivers/scsi/bfa/bfa_svc.h | 2 +- drivers/scsi/bfa/bfad.c | 19 ++++----- drivers/scsi/bfa/bfad_attr.c | 70 ++++++++++++++++---------------- drivers/scsi/bfa/bfad_bsg.c | 2 +- drivers/scsi/bfa/bfad_bsg.h | 2 +- drivers/scsi/bfa/bfad_debugfs.c | 2 +- drivers/scsi/bfa/bfad_drv.h | 2 +- drivers/scsi/bfa/bfad_im.c | 4 +- drivers/scsi/bfa/bfad_im.h | 2 +- drivers/scsi/bfa/bfi.h | 2 +- drivers/scsi/bfa/bfi_ms.h | 2 +- drivers/scsi/bfa/bfi_reg.h | 4 +- 39 files changed, 84 insertions(+), 89 deletions(-) diff --git a/drivers/scsi/bfa/bfa.h b/drivers/scsi/bfa/bfa.h index 7d0337ba5e1b3..0e119d838e1b6 100644 --- a/drivers/scsi/bfa/bfa.h +++ b/drivers/scsi/bfa/bfa.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c index f157a37150d7d..2ea0db4b62a73 100644 --- a/drivers/scsi/bfa/bfa_core.c +++ b/drivers/scsi/bfa/bfa_core.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_cs.h b/drivers/scsi/bfa/bfa_cs.h index c8bb20aebd89c..da9cf655be260 100644 --- a/drivers/scsi/bfa/bfa_cs.h +++ b/drivers/scsi/bfa/bfa_cs.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h index da4f705494621..5dc3782d615b6 100644 --- a/drivers/scsi/bfa/bfa_defs.h +++ b/drivers/scsi/bfa/bfa_defs.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_defs_fcs.h b/drivers/scsi/bfa/bfa_defs_fcs.h index 5185ae33e8439..5815a904574d9 100644 --- a/drivers/scsi/bfa/bfa_defs_fcs.h +++ b/drivers/scsi/bfa/bfa_defs_fcs.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h index fd2fa249df2ae..e81707f938cb0 100644 --- a/drivers/scsi/bfa/bfa_defs_svc.h +++ b/drivers/scsi/bfa/bfa_defs_svc.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_fc.h b/drivers/scsi/bfa/bfa_fc.h index 7142309fd8916..18b7304d6b0bc 100644 --- a/drivers/scsi/bfa/bfa_fc.h +++ b/drivers/scsi/bfa/bfa_fc.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_fcbuild.c b/drivers/scsi/bfa/bfa_fcbuild.c index 6f670d3362aff..b8dadc9cc9935 100644 --- a/drivers/scsi/bfa/bfa_fcbuild.c +++ b/drivers/scsi/bfa/bfa_fcbuild.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_fcbuild.h b/drivers/scsi/bfa/bfa_fcbuild.h index 85e3c58a306bb..b109a8813401a 100644 --- a/drivers/scsi/bfa/bfa_fcbuild.h +++ b/drivers/scsi/bfa/bfa_fcbuild.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c index 3881a729c2a05..20982e7cdd818 100644 --- a/drivers/scsi/bfa/bfa_fcpim.c +++ b/drivers/scsi/bfa/bfa_fcpim.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_fcpim.h b/drivers/scsi/bfa/bfa_fcpim.h index 0c370624ff085..e93921dec3478 100644 --- a/drivers/scsi/bfa/bfa_fcpim.h +++ b/drivers/scsi/bfa/bfa_fcpim.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index 043d3c0680dce..1e7e139d71eab 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h index 30b4555e2c4a6..06dc215ea0503 100644 --- a/drivers/scsi/bfa/bfa_fcs.h +++ b/drivers/scsi/bfa/bfa_fcs.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as @@ -634,7 +634,7 @@ void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, /* * HBA Attribute Block : BFA internal representation. Note : Some variable - * sizes have been trimmed to suit BFA For Ex : Model will be "Brocade". Based + * sizes have been trimmed to suit BFA For Ex : Model will be "QLogic ". Based * on this the size has been reduced to 16 bytes from the standard's 64 bytes. */ struct bfa_fcs_fdmi_hba_attr_s { diff --git a/drivers/scsi/bfa/bfa_fcs_fcpim.c b/drivers/scsi/bfa/bfa_fcs_fcpim.c index 4fd20d92877e5..4f089d76afb1a 100644 --- a/drivers/scsi/bfa/bfa_fcs_fcpim.c +++ b/drivers/scsi/bfa/bfa_fcs_fcpim.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index d82379216926d..7733ad5305d41 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as @@ -2654,7 +2654,7 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, strncpy(hba_attr->node_sym_name.symname, port->port_cfg.node_sym_name.symname, BFA_SYMNAME_MAXLEN); - strcpy(hba_attr->vendor_info, "BROCADE"); + strcpy(hba_attr->vendor_info, "QLogic"); hba_attr->num_ports = cpu_to_be32(bfa_ioc_get_nports(&port->fcs->bfa->ioc)); hba_attr->fabric_name = port->fabric->lps->pr_nwwn; diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c index 5559faaf458b1..de50349a39ce2 100644 --- a/drivers/scsi/bfa/bfa_fcs_rport.c +++ b/drivers/scsi/bfa/bfa_fcs_rport.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c index e3648d9272a37..c4a0c0eb88a57 100644 --- a/drivers/scsi/bfa/bfa_hw_cb.c +++ b/drivers/scsi/bfa/bfa_hw_cb.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c index f19bc446a70ae..b0ff378dece2c 100644 --- a/drivers/scsi/bfa/bfa_hw_ct.c +++ b/drivers/scsi/bfa/bfa_hw_ct.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index e9a7c64d5dcf2..251e2ff8ff5f7 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as @@ -2698,7 +2698,7 @@ bfa_ioc_reset_fwstate(struct bfa_ioc_s *ioc) bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_UNINIT); } -#define BFA_MFG_NAME "Brocade" +#define BFA_MFG_NAME "QLogic" void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, struct bfa_adapter_attr_s *ad_attr) diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h index 0d6e16581f37c..713745da44c6a 100644 --- a/drivers/scsi/bfa/bfa_ioc.h +++ b/drivers/scsi/bfa/bfa_ioc.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c index 10a0042d54336..f1b80da298c8d 100644 --- a/drivers/scsi/bfa/bfa_ioc_cb.c +++ b/drivers/scsi/bfa/bfa_ioc_cb.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c index 1e5fa6126e4cb..651a8fb930377 100644 --- a/drivers/scsi/bfa/bfa_ioc_ct.c +++ b/drivers/scsi/bfa/bfa_ioc_ct.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_modules.h b/drivers/scsi/bfa/bfa_modules.h index 5b024158a54c8..53135f21fa0e4 100644 --- a/drivers/scsi/bfa/bfa_modules.h +++ b/drivers/scsi/bfa/bfa_modules.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_plog.h b/drivers/scsi/bfa/bfa_plog.h index 4fdba6f70d4fc..da570c0b8275e 100644 --- a/drivers/scsi/bfa/bfa_plog.h +++ b/drivers/scsi/bfa/bfa_plog.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_port.c b/drivers/scsi/bfa/bfa_port.c index 314548aa3d7d2..da1721e0d1673 100644 --- a/drivers/scsi/bfa/bfa_port.c +++ b/drivers/scsi/bfa/bfa_port.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_port.h b/drivers/scsi/bfa/bfa_port.h index ba715ceff1bf9..26dc1bf14c85e 100644 --- a/drivers/scsi/bfa/bfa_port.h +++ b/drivers/scsi/bfa/bfa_port.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index 93e588fa5712e..12de292175ef6 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h index efb04976aca54..ea2278bc78a8d 100644 --- a/drivers/scsi/bfa/bfa_svc.h +++ b/drivers/scsi/bfa/bfa_svc.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index f298b2e8d5c37..9d253cb83ee76 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as @@ -131,13 +131,9 @@ MODULE_PARM_DESC(bfa_linkup_delay, "Link up delay, default=30 secs for " "boot port. Otherwise 10 secs in RHEL4 & 0 for " "[RHEL5, SLES10, ESX40] Range[>0]"); module_param(msix_disable_cb, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(msix_disable_cb, "Disable Message Signaled Interrupts " - "for Brocade-415/425/815/825 cards, default=0, " - " Range[false:0|true:1]"); +MODULE_PARM_DESC(msix_disable_cb, "Disable Message Signaled Interrupts for QLogic-415/425/815/825 cards, default=0 Range[false:0|true:1]"); module_param(msix_disable_ct, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(msix_disable_ct, "Disable Message Signaled Interrupts " - "if possible for Brocade-1010/1020/804/1007/902/1741 " - "cards, default=0, Range[false:0|true:1]"); +MODULE_PARM_DESC(msix_disable_ct, "Disable Message Signaled Interrupts if possible for QLogic-1010/1020/804/1007/902/1741 cards, default=0, Range[false:0|true:1]"); module_param(fdmi_enable, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(fdmi_enable, "Enables fdmi registration, default=1, " "Range[false:0|true:1]"); @@ -839,8 +835,7 @@ bfad_drv_init(struct bfad_s *bfad) printk(KERN_WARNING "bfad%d bfad_hal_mem_alloc failure\n", bfad->inst_no); printk(KERN_WARNING - "Not enough memory to attach all Brocade HBA ports, %s", - "System may need more memory.\n"); + "Not enough memory to attach all QLogic BR-series HBA ports. System may need more memory.\n"); return BFA_STATUS_FAILED; } @@ -1711,7 +1706,7 @@ bfad_init(void) { int error = 0; - printk(KERN_INFO "Brocade BFA FC/FCOE SCSI driver - version: %s\n", + pr_info("QLogic BR-series BFA FC/FCOE SCSI driver - version: %s\n", BFAD_DRIVER_VERSION); if (num_sgpgs > 0) @@ -1818,6 +1813,6 @@ bfad_free_fwimg(void) module_init(bfad_init); module_exit(bfad_exit); MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Brocade Fibre Channel HBA Driver" BFAD_PROTO_NAME); -MODULE_AUTHOR("Brocade Communications Systems, Inc."); +MODULE_DESCRIPTION("QLogic BR-series Fibre Channel HBA Driver" BFAD_PROTO_NAME); +MODULE_AUTHOR("QLogic Corporation"); MODULE_VERSION(BFAD_DRIVER_VERSION); diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index 66cca48d8ab84..13db3b7bc8737 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as @@ -751,65 +751,65 @@ bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr, bfa_get_adapter_model(&bfad->bfa, model); nports = bfa_get_nports(&bfad->bfa); - if (!strcmp(model, "Brocade-425")) + if (!strcmp(model, "QLogic-425")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 4Gbps PCIe dual port FC HBA"); - else if (!strcmp(model, "Brocade-825")) + "QLogic BR-series 4Gbps PCIe dual port FC HBA"); + else if (!strcmp(model, "QLogic-825")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 8Gbps PCIe dual port FC HBA"); - else if (!strcmp(model, "Brocade-42B")) + "QLogic BR-series 8Gbps PCIe dual port FC HBA"); + else if (!strcmp(model, "QLogic-42B")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 4Gbps PCIe dual port FC HBA for HP"); - else if (!strcmp(model, "Brocade-82B")) + "QLogic BR-series 4Gbps PCIe dual port FC HBA for HP"); + else if (!strcmp(model, "QLogic-82B")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 8Gbps PCIe dual port FC HBA for HP"); - else if (!strcmp(model, "Brocade-1010")) + "QLogic BR-series 8Gbps PCIe dual port FC HBA for HP"); + else if (!strcmp(model, "QLogic-1010")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 10Gbps single port CNA"); - else if (!strcmp(model, "Brocade-1020")) + "QLogic BR-series 10Gbps single port CNA"); + else if (!strcmp(model, "QLogic-1020")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 10Gbps dual port CNA"); - else if (!strcmp(model, "Brocade-1007")) + "QLogic BR-series 10Gbps dual port CNA"); + else if (!strcmp(model, "QLogic-1007")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 10Gbps CNA for IBM Blade Center"); - else if (!strcmp(model, "Brocade-415")) + "QLogic BR-series 10Gbps CNA for IBM Blade Center"); + else if (!strcmp(model, "QLogic-415")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 4Gbps PCIe single port FC HBA"); - else if (!strcmp(model, "Brocade-815")) + "QLogic BR-series 4Gbps PCIe single port FC HBA"); + else if (!strcmp(model, "QLogic-815")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 8Gbps PCIe single port FC HBA"); - else if (!strcmp(model, "Brocade-41B")) + "QLogic BR-series 8Gbps PCIe single port FC HBA"); + else if (!strcmp(model, "QLogic-41B")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 4Gbps PCIe single port FC HBA for HP"); - else if (!strcmp(model, "Brocade-81B")) + "QLogic BR-series 4Gbps PCIe single port FC HBA for HP"); + else if (!strcmp(model, "QLogic-81B")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 8Gbps PCIe single port FC HBA for HP"); - else if (!strcmp(model, "Brocade-804")) + "QLogic BR-series 8Gbps PCIe single port FC HBA for HP"); + else if (!strcmp(model, "QLogic-804")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 8Gbps FC HBA for HP Bladesystem C-class"); - else if (!strcmp(model, "Brocade-1741")) + "QLogic BR-series 8Gbps FC HBA for HP Bladesystem C-class"); + else if (!strcmp(model, "QLogic-1741")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 10Gbps CNA for Dell M-Series Blade Servers"); - else if (strstr(model, "Brocade-1860")) { + "QLogic BR-series 10Gbps CNA for Dell M-Series Blade Servers"); + else if (strstr(model, "QLogic-1860")) { if (nports == 1 && bfa_ioc_is_cna(&bfad->bfa.ioc)) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 10Gbps single port CNA"); + "QLogic BR-series 10Gbps single port CNA"); else if (nports == 1 && !bfa_ioc_is_cna(&bfad->bfa.ioc)) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 16Gbps PCIe single port FC HBA"); + "QLogic BR-series 16Gbps PCIe single port FC HBA"); else if (nports == 2 && bfa_ioc_is_cna(&bfad->bfa.ioc)) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 10Gbps dual port CNA"); + "QLogic BR-series 10Gbps dual port CNA"); else if (nports == 2 && !bfa_ioc_is_cna(&bfad->bfa.ioc)) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 16Gbps PCIe dual port FC HBA"); - } else if (!strcmp(model, "Brocade-1867")) { + "QLogic BR-series 16Gbps PCIe dual port FC HBA"); + } else if (!strcmp(model, "QLogic-1867")) { if (nports == 1 && !bfa_ioc_is_cna(&bfad->bfa.ioc)) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 16Gbps PCIe single port FC HBA for IBM"); + "QLogic BR-series 16Gbps PCIe single port FC HBA for IBM"); else if (nports == 2 && !bfa_ioc_is_cna(&bfad->bfa.ioc)) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 16Gbps PCIe dual port FC HBA for IBM"); + "QLogic BR-series 16Gbps PCIe dual port FC HBA for IBM"); } else snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, "Invalid Model"); diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index b9d1460efe322..d1ad0208dfe75 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h index 59aca80e16223..917e140dfbcce 100644 --- a/drivers/scsi/bfa/bfad_bsg.h +++ b/drivers/scsi/bfa/bfad_bsg.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfad_debugfs.c b/drivers/scsi/bfa/bfad_debugfs.c index 62b11d4b2fd2e..8dcd8c70c7ee0 100644 --- a/drivers/scsi/bfa/bfad_debugfs.c +++ b/drivers/scsi/bfa/bfad_debugfs.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 58fee34b2d477..800145966ef8c 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 2c0cf8a46a47b..6c805e13f8dd8 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as @@ -186,7 +186,7 @@ bfad_im_info(struct Scsi_Host *shost) memset(bfa_buf, 0, sizeof(bfa_buf)); snprintf(bfa_buf, sizeof(bfa_buf), - "Brocade FC/FCOE Adapter, " "hwpath: %s driver: %s", + "QLogic BR-series FC/FCOE Adapter, hwpath: %s driver: %s", bfad->pci_name, BFAD_DRIVER_VERSION); return bfa_buf; diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h index 31434dfb3a40b..836fdc221edd3 100644 --- a/drivers/scsi/bfa/bfad_im.h +++ b/drivers/scsi/bfa/bfad_im.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h index 54c93ef439ace..97600dcec6491 100644 --- a/drivers/scsi/bfa/bfi.h +++ b/drivers/scsi/bfa/bfi.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfi_ms.h b/drivers/scsi/bfa/bfi_ms.h index 8699be47dbc59..ae5bfe039fcc0 100644 --- a/drivers/scsi/bfa/bfi_ms.h +++ b/drivers/scsi/bfa/bfi_ms.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfi_reg.h b/drivers/scsi/bfa/bfi_reg.h index 7d071a4db0da6..fd5b87616e8b1 100644 --- a/drivers/scsi/bfa/bfi_reg.h +++ b/drivers/scsi/bfa/bfi_reg.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as @@ -17,7 +17,7 @@ */ /* - * bfi_reg.h ASIC register defines for all Brocade adapter ASICs + * bfi_reg.h ASIC register defines for all QLogic BR-series adapter ASICs */ #ifndef __BFI_REG_H__ -- GitLab From 08c2315015561d2292cddcbad8967deab86af4d5 Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Thu, 26 Nov 2015 03:54:47 -0500 Subject: [PATCH 0891/2855] bfa: Update driver version to 3.2.25.0 Signed-off-by: Sudarsana Kalluru Signed-off-by: Anil Gurumurthy Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/bfa/bfad_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 800145966ef8c..f9e862093a259 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h @@ -58,7 +58,7 @@ #ifdef BFA_DRIVER_VERSION #define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION #else -#define BFAD_DRIVER_VERSION "3.2.23.0" +#define BFAD_DRIVER_VERSION "3.2.25.0" #endif #define BFAD_PROTO_NAME FCPI_NAME -- GitLab From 64bebefcf3195baed3d15dc377e15d1e7121036a Mon Sep 17 00:00:00 2001 From: "Fu, Zhonghui" Date: Thu, 24 Sep 2015 14:06:31 +0800 Subject: [PATCH 0892/2855] HID: enable hid device to suspend/resume asynchronously Now, PM core supports asynchronous suspend/resume mode for devices during system suspend/resume, and the power state transition of one device may be completed in separate kernel thread. PM core ensures all power state transition timing dependency between devices. This patch enables hid devices to suspend/resume asynchronously. This will take advantage of multicore and improve system suspend/resume speed. Signed-off-by: Zhonghui Fu Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index c6f7a694f67a1..e9ef0dd4fd893 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2660,6 +2660,7 @@ struct hid_device *hid_allocate_device(void) device_initialize(&hdev->dev); hdev->dev.release = hid_device_release; hdev->dev.bus = &hid_bus_type; + device_enable_async_suspend(&hdev->dev); hid_close_report(hdev); -- GitLab From 8261d961d1f397925d7a470864c14663d01ed714 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Mon, 9 Nov 2015 09:13:59 +0200 Subject: [PATCH 0893/2855] iio: core: Introduce IIO configfs support This patch creates the IIO configfs root group. The group will appear under /iio/, usually /config/iio. We introduce configfs support in IIO in order to be able to easily create IIO objects from userspace. The first supported IIO objects are triggers introduced with next patches. Signed-off-by: Daniel Baluta Tested-by: Matt Ranostay Signed-off-by: Jonathan Cameron --- drivers/iio/Kconfig | 8 +++++ drivers/iio/Makefile | 1 + drivers/iio/industrialio-configfs.c | 50 +++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 drivers/iio/industrialio-configfs.c diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 6b8c77c97d40d..9509b8a4c5518 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -22,6 +22,14 @@ if IIO_BUFFER source "drivers/iio/buffer/Kconfig" endif # IIO_BUFFER +config IIO_CONFIGFS + tristate "Enable IIO configuration via configfs" + select CONFIGFS_FS + help + This allows configuring various IIO bits through configfs + (e.g. software triggers). For more info see + Documentation/iio/iio_configfs.txt. + config IIO_TRIGGER bool "Enable triggered sampling support" help diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index 6769f2f43e868..39d119f18f2e5 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -7,6 +7,7 @@ industrialio-y := industrialio-core.o industrialio-event.o inkern.o industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o +obj-$(CONFIG_IIO_CONFIGFS) += industrialio-configfs.o obj-$(CONFIG_IIO_TRIGGERED_EVENT) += industrialio-triggered-event.o obj-y += accel/ diff --git a/drivers/iio/industrialio-configfs.c b/drivers/iio/industrialio-configfs.c new file mode 100644 index 0000000000000..83563dd7fcf4b --- /dev/null +++ b/drivers/iio/industrialio-configfs.c @@ -0,0 +1,50 @@ +/* + * Industrial I/O configfs bits + * + * Copyright (c) 2015 Intel Corporation + * + * 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. + */ + +#include +#include +#include +#include +#include + +#include + +static struct config_item_type iio_root_group_type = { + .ct_owner = THIS_MODULE, +}; + +struct configfs_subsystem iio_configfs_subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "iio", + .ci_type = &iio_root_group_type, + }, + }, + .su_mutex = __MUTEX_INITIALIZER(iio_configfs_subsys.su_mutex), +}; +EXPORT_SYMBOL(iio_configfs_subsys); + +static int __init iio_configfs_init(void) +{ + config_group_init(&iio_configfs_subsys.su_group); + + return configfs_register_subsystem(&iio_configfs_subsys); +} +module_init(iio_configfs_init); + +static void __exit iio_configfs_exit(void) +{ + configfs_unregister_subsystem(&iio_configfs_subsys); +} +module_exit(iio_configfs_exit); + +MODULE_AUTHOR("Daniel Baluta "); +MODULE_DESCRIPTION("Industrial I/O configfs support"); +MODULE_LICENSE("GPL v2"); -- GitLab From b662f809d41009749a9ee6f9a4db3d9af579e171 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Mon, 9 Nov 2015 09:14:00 +0200 Subject: [PATCH 0894/2855] iio: core: Introduce IIO software triggers A software trigger associates an IIO device trigger with a software interrupt source (e.g: timer, sysfs). This patch adds the generic infrastructure for handling software triggers. Software interrupts sources are kept in a iio_trigger_types_list and registered separately when the associated kernel module is loaded. Software triggers can be created directly from drivers or from user space via configfs interface. To sum up, this dynamically creates "triggers" group to be found under /config/iio/triggers and offers the possibility of dynamically creating trigger types groups. The first supported trigger type is "hrtimer" found under /config/iio/triggers/hrtimer. Signed-off-by: Daniel Baluta Signed-off-by: Jonathan Cameron --- drivers/iio/Kconfig | 8 ++ drivers/iio/Makefile | 1 + drivers/iio/industrialio-sw-trigger.c | 183 ++++++++++++++++++++++++++ include/linux/iio/sw_trigger.h | 71 ++++++++++ 4 files changed, 263 insertions(+) create mode 100644 drivers/iio/industrialio-sw-trigger.c create mode 100644 include/linux/iio/sw_trigger.h diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 9509b8a4c5518..ac8715e56ba18 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -46,6 +46,14 @@ config IIO_CONSUMERS_PER_TRIGGER This value controls the maximum number of consumers that a given trigger may handle. Default is 2. +config IIO_SW_TRIGGER + tristate "Enable software triggers support" + select IIO_CONFIGFS + help + Provides IIO core support for software triggers. A software + trigger can be created via configfs or directly by a driver + using the API provided. + config IIO_TRIGGERED_EVENT tristate select IIO_TRIGGER diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index 39d119f18f2e5..f670b82298aae 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -8,6 +8,7 @@ industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o obj-$(CONFIG_IIO_CONFIGFS) += industrialio-configfs.o +obj-$(CONFIG_IIO_SW_TRIGGER) += industrialio-sw-trigger.o obj-$(CONFIG_IIO_TRIGGERED_EVENT) += industrialio-triggered-event.o obj-y += accel/ diff --git a/drivers/iio/industrialio-sw-trigger.c b/drivers/iio/industrialio-sw-trigger.c new file mode 100644 index 0000000000000..4825cfd9c4ea4 --- /dev/null +++ b/drivers/iio/industrialio-sw-trigger.c @@ -0,0 +1,183 @@ +/* + * The Industrial I/O core, software trigger functions + * + * Copyright (c) 2015 Intel Corporation + * + * 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. + */ + +#include +#include +#include +#include +#include + +#include +#include + +static struct config_group *iio_triggers_group; +static struct config_item_type iio_trigger_type_group_type; + +static struct config_item_type iio_triggers_group_type = { + .ct_owner = THIS_MODULE, +}; + +static LIST_HEAD(iio_trigger_types_list); +static DEFINE_MUTEX(iio_trigger_types_lock); + +static +struct iio_sw_trigger_type *__iio_find_sw_trigger_type(const char *name, + unsigned len) +{ + struct iio_sw_trigger_type *t = NULL, *iter; + + list_for_each_entry(iter, &iio_trigger_types_list, list) + if (!strcmp(iter->name, name)) { + t = iter; + break; + } + + return t; +} + +int iio_register_sw_trigger_type(struct iio_sw_trigger_type *t) +{ + struct iio_sw_trigger_type *iter; + int ret = 0; + + mutex_lock(&iio_trigger_types_lock); + iter = __iio_find_sw_trigger_type(t->name, strlen(t->name)); + if (iter) + ret = -EBUSY; + else + list_add_tail(&t->list, &iio_trigger_types_list); + mutex_unlock(&iio_trigger_types_lock); + + if (ret) + return ret; + + t->group = configfs_register_default_group(iio_triggers_group, t->name, + &iio_trigger_type_group_type); + if (IS_ERR(t->group)) + ret = PTR_ERR(t->group); + + return ret; +} +EXPORT_SYMBOL(iio_register_sw_trigger_type); + +void iio_unregister_sw_trigger_type(struct iio_sw_trigger_type *t) +{ + struct iio_sw_trigger_type *iter; + + mutex_lock(&iio_trigger_types_lock); + iter = __iio_find_sw_trigger_type(t->name, strlen(t->name)); + if (iter) + list_del(&t->list); + mutex_unlock(&iio_trigger_types_lock); + + configfs_unregister_default_group(t->group); +} +EXPORT_SYMBOL(iio_unregister_sw_trigger_type); + +static +struct iio_sw_trigger_type *iio_get_sw_trigger_type(const char *name) +{ + struct iio_sw_trigger_type *t; + + mutex_lock(&iio_trigger_types_lock); + t = __iio_find_sw_trigger_type(name, strlen(name)); + if (t && !try_module_get(t->owner)) + t = NULL; + mutex_unlock(&iio_trigger_types_lock); + + return t; +} + +struct iio_sw_trigger *iio_sw_trigger_create(const char *type, const char *name) +{ + struct iio_sw_trigger *t; + struct iio_sw_trigger_type *tt; + + tt = iio_get_sw_trigger_type(type); + if (!tt) { + pr_err("Invalid trigger type: %s\n", type); + return ERR_PTR(-EINVAL); + } + t = tt->ops->probe(name); + if (IS_ERR(t)) + goto out_module_put; + + t->trigger_type = tt; + + return t; +out_module_put: + module_put(tt->owner); + return t; +} +EXPORT_SYMBOL(iio_sw_trigger_create); + +void iio_sw_trigger_destroy(struct iio_sw_trigger *t) +{ + struct iio_sw_trigger_type *tt = t->trigger_type; + + tt->ops->remove(t); + module_put(tt->owner); +} +EXPORT_SYMBOL(iio_sw_trigger_destroy); + +static struct config_group *trigger_make_group(struct config_group *group, + const char *name) +{ + struct iio_sw_trigger *t; + + t = iio_sw_trigger_create(group->cg_item.ci_name, name); + if (IS_ERR(t)) + return ERR_CAST(t); + + config_item_set_name(&t->group.cg_item, "%s", name); + + return &t->group; +} + +static void trigger_drop_group(struct config_group *group, + struct config_item *item) +{ + struct iio_sw_trigger *t = to_iio_sw_trigger(item); + + iio_sw_trigger_destroy(t); + config_item_put(item); +} + +static struct configfs_group_operations trigger_ops = { + .make_group = &trigger_make_group, + .drop_item = &trigger_drop_group, +}; + +static struct config_item_type iio_trigger_type_group_type = { + .ct_group_ops = &trigger_ops, + .ct_owner = THIS_MODULE, +}; + +static int __init iio_sw_trigger_init(void) +{ + iio_triggers_group = + configfs_register_default_group(&iio_configfs_subsys.su_group, + "triggers", + &iio_triggers_group_type); + if (IS_ERR(iio_triggers_group)) + return PTR_ERR(iio_triggers_group); + return 0; +} +module_init(iio_sw_trigger_init); + +static void __exit iio_sw_trigger_exit(void) +{ + configfs_unregister_default_group(iio_triggers_group); +} +module_exit(iio_sw_trigger_exit); + +MODULE_AUTHOR("Daniel Baluta "); +MODULE_DESCRIPTION("Industrial I/O software triggers support"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/iio/sw_trigger.h b/include/linux/iio/sw_trigger.h new file mode 100644 index 0000000000000..c2f33b2b35a5e --- /dev/null +++ b/include/linux/iio/sw_trigger.h @@ -0,0 +1,71 @@ +/* + * Industrial I/O software trigger interface + * + * Copyright (c) 2015 Intel Corporation + * + * 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. + */ + +#ifndef __IIO_SW_TRIGGER +#define __IIO_SW_TRIGGER + +#include +#include +#include +#include + +#define module_iio_sw_trigger_driver(__iio_sw_trigger_type) \ + module_driver(__iio_sw_trigger_type, iio_register_sw_trigger_type, \ + iio_unregister_sw_trigger_type) + +extern struct configfs_subsystem iio_configfs_subsys; +struct iio_sw_trigger_ops; + +struct iio_sw_trigger_type { + const char *name; + struct module *owner; + const struct iio_sw_trigger_ops *ops; + struct list_head list; + struct config_group *group; +}; + +struct iio_sw_trigger { + struct iio_trigger *trigger; + struct iio_sw_trigger_type *trigger_type; + struct config_group group; +}; + +struct iio_sw_trigger_ops { + struct iio_sw_trigger* (*probe)(const char *); + int (*remove)(struct iio_sw_trigger *); +}; + +static inline +struct iio_sw_trigger *to_iio_sw_trigger(struct config_item *item) +{ + return container_of(to_config_group(item), struct iio_sw_trigger, + group); +} + +int iio_register_sw_trigger_type(struct iio_sw_trigger_type *tt); +void iio_unregister_sw_trigger_type(struct iio_sw_trigger_type *tt); + +struct iio_sw_trigger *iio_sw_trigger_create(const char *, const char *); +void iio_sw_trigger_destroy(struct iio_sw_trigger *); + +int iio_sw_trigger_type_configfs_register(struct iio_sw_trigger_type *tt); +void iio_sw_trigger_type_configfs_unregister(struct iio_sw_trigger_type *tt); + +static inline +void iio_swt_group_init_type_name(struct iio_sw_trigger *t, + const char *name, + struct config_item_type *type) +{ +#ifdef CONFIG_CONFIGFS_FS + config_group_init_type_name(&t->group, name, type); +#endif +} + +#endif /* __IIO_SW_TRIGGER */ -- GitLab From ac5006a2a558a2441a840c7be1e0e717839d5e07 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Mon, 9 Nov 2015 09:14:01 +0200 Subject: [PATCH 0895/2855] iio: trigger: Introduce IIO hrtimer based trigger This patch registers a new IIO software trigger interrupt source based on high resolution timers. Notice that if configfs is enabled we create sampling_frequency attribute allowing users to change hrtimer period (1/sampling_frequency). The IIO hrtimer trigger has a long history, this patch is based on an older version from Marten and Lars-Peter. Signed-off-by: Marten Svanfeldt Signed-off-by: Lars-Peter Clausen Signed-off-by: Daniel Baluta Signed-off-by: Jonathan Cameron --- drivers/iio/trigger/Kconfig | 10 ++ drivers/iio/trigger/Makefile | 2 + drivers/iio/trigger/iio-trig-hrtimer.c | 193 +++++++++++++++++++++++++ 3 files changed, 205 insertions(+) create mode 100644 drivers/iio/trigger/iio-trig-hrtimer.c diff --git a/drivers/iio/trigger/Kconfig b/drivers/iio/trigger/Kconfig index 79996123a71b9..519e6772f6f57 100644 --- a/drivers/iio/trigger/Kconfig +++ b/drivers/iio/trigger/Kconfig @@ -5,6 +5,16 @@ menu "Triggers - standalone" +config IIO_HRTIMER_TRIGGER + tristate "High resolution timer trigger" + depends on IIO_SW_TRIGGER + help + Provides a frequency based IIO trigger using high resolution + timers as interrupt source. + + To compile this driver as a module, choose M here: the + module will be called iio-trig-hrtimer. + config IIO_INTERRUPT_TRIGGER tristate "Generic interrupt trigger" help diff --git a/drivers/iio/trigger/Makefile b/drivers/iio/trigger/Makefile index 0694daecaf228..fe06eb564367e 100644 --- a/drivers/iio/trigger/Makefile +++ b/drivers/iio/trigger/Makefile @@ -3,5 +3,7 @@ # # When adding new entries keep the list in alphabetical order + +obj-$(CONFIG_IIO_HRTIMER_TRIGGER) += iio-trig-hrtimer.o obj-$(CONFIG_IIO_INTERRUPT_TRIGGER) += iio-trig-interrupt.o obj-$(CONFIG_IIO_SYSFS_TRIGGER) += iio-trig-sysfs.o diff --git a/drivers/iio/trigger/iio-trig-hrtimer.c b/drivers/iio/trigger/iio-trig-hrtimer.c new file mode 100644 index 0000000000000..5e6d451febebd --- /dev/null +++ b/drivers/iio/trigger/iio-trig-hrtimer.c @@ -0,0 +1,193 @@ +/** + * The industrial I/O periodic hrtimer trigger driver + * + * Copyright (C) Intuitive Aerial AB + * Written by Marten Svanfeldt, marten@intuitiveaerial.com + * Copyright (C) 2012, Analog Device Inc. + * Author: Lars-Peter Clausen + * Copyright (C) 2015, Intel Corporation + * + * 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. + * + */ +#include +#include +#include + +#include +#include +#include + +/* default sampling frequency - 100Hz */ +#define HRTIMER_DEFAULT_SAMPLING_FREQUENCY 100 + +struct iio_hrtimer_info { + struct iio_sw_trigger swt; + struct hrtimer timer; + unsigned long sampling_frequency; + ktime_t period; +}; + +static struct config_item_type iio_hrtimer_type = { + .ct_owner = THIS_MODULE, +}; + +static +ssize_t iio_hrtimer_show_sampling_frequency(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_trigger *trig = to_iio_trigger(dev); + struct iio_hrtimer_info *info = iio_trigger_get_drvdata(trig); + + return snprintf(buf, PAGE_SIZE, "%lu\n", info->sampling_frequency); +} + +static +ssize_t iio_hrtimer_store_sampling_frequency(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_trigger *trig = to_iio_trigger(dev); + struct iio_hrtimer_info *info = iio_trigger_get_drvdata(trig); + unsigned long val; + int ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + return ret; + + if (!val || val > NSEC_PER_SEC) + return -EINVAL; + + info->sampling_frequency = val; + info->period = ktime_set(0, NSEC_PER_SEC / val); + + return len; +} + +static DEVICE_ATTR(sampling_frequency, S_IRUGO | S_IWUSR, + iio_hrtimer_show_sampling_frequency, + iio_hrtimer_store_sampling_frequency); + +static struct attribute *iio_hrtimer_attrs[] = { + &dev_attr_sampling_frequency.attr, + NULL +}; + +static const struct attribute_group iio_hrtimer_attr_group = { + .attrs = iio_hrtimer_attrs, +}; + +static const struct attribute_group *iio_hrtimer_attr_groups[] = { + &iio_hrtimer_attr_group, + NULL +}; + +static enum hrtimer_restart iio_hrtimer_trig_handler(struct hrtimer *timer) +{ + struct iio_hrtimer_info *info; + + info = container_of(timer, struct iio_hrtimer_info, timer); + + hrtimer_forward_now(timer, info->period); + iio_trigger_poll(info->swt.trigger); + + return HRTIMER_RESTART; +} + +static int iio_trig_hrtimer_set_state(struct iio_trigger *trig, bool state) +{ + struct iio_hrtimer_info *trig_info; + + trig_info = iio_trigger_get_drvdata(trig); + + if (state) + hrtimer_start(&trig_info->timer, trig_info->period, + HRTIMER_MODE_REL); + else + hrtimer_cancel(&trig_info->timer); + + return 0; +} + +static const struct iio_trigger_ops iio_hrtimer_trigger_ops = { + .owner = THIS_MODULE, + .set_trigger_state = iio_trig_hrtimer_set_state, +}; + +static struct iio_sw_trigger *iio_trig_hrtimer_probe(const char *name) +{ + struct iio_hrtimer_info *trig_info; + int ret; + + trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL); + if (!trig_info) + return ERR_PTR(-ENOMEM); + + trig_info->swt.trigger = iio_trigger_alloc("%s", name); + if (!trig_info->swt.trigger) { + ret = -ENOMEM; + goto err_free_trig_info; + } + + iio_trigger_set_drvdata(trig_info->swt.trigger, trig_info); + trig_info->swt.trigger->ops = &iio_hrtimer_trigger_ops; + trig_info->swt.trigger->dev.groups = iio_hrtimer_attr_groups; + + hrtimer_init(&trig_info->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + trig_info->timer.function = iio_hrtimer_trig_handler; + + trig_info->sampling_frequency = HRTIMER_DEFAULT_SAMPLING_FREQUENCY; + trig_info->period = ktime_set(0, NSEC_PER_SEC / + trig_info->sampling_frequency); + + ret = iio_trigger_register(trig_info->swt.trigger); + if (ret) + goto err_free_trigger; + + iio_swt_group_init_type_name(&trig_info->swt, name, &iio_hrtimer_type); + return &trig_info->swt; +err_free_trigger: + iio_trigger_free(trig_info->swt.trigger); +err_free_trig_info: + kfree(trig_info); + + return ERR_PTR(ret); +} + +static int iio_trig_hrtimer_remove(struct iio_sw_trigger *swt) +{ + struct iio_hrtimer_info *trig_info; + + trig_info = iio_trigger_get_drvdata(swt->trigger); + + iio_trigger_unregister(swt->trigger); + + /* cancel the timer after unreg to make sure no one rearms it */ + hrtimer_cancel(&trig_info->timer); + iio_trigger_free(swt->trigger); + kfree(trig_info); + + return 0; +} + +static const struct iio_sw_trigger_ops iio_trig_hrtimer_ops = { + .probe = iio_trig_hrtimer_probe, + .remove = iio_trig_hrtimer_remove, +}; + +static struct iio_sw_trigger_type iio_trig_hrtimer = { + .name = "hrtimer", + .owner = THIS_MODULE, + .ops = &iio_trig_hrtimer_ops, +}; + +module_iio_sw_trigger_driver(iio_trig_hrtimer); + +MODULE_AUTHOR("Marten Svanfeldt "); +MODULE_AUTHOR("Daniel Baluta "); +MODULE_DESCRIPTION("Periodic hrtimer trigger for the IIO subsystem"); +MODULE_LICENSE("GPL v2"); -- GitLab From 4c3e2a4036054deca4819758f59ff65f27938388 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Mon, 9 Nov 2015 09:14:02 +0200 Subject: [PATCH 0896/2855] iio: Documentation: Add IIO configfs documentation Signed-off-by: Daniel Baluta Acked-by: Crt Mori Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/configfs-iio | 21 ++++++ Documentation/iio/iio_configfs.txt | 93 ++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 Documentation/ABI/testing/configfs-iio create mode 100644 Documentation/iio/iio_configfs.txt diff --git a/Documentation/ABI/testing/configfs-iio b/Documentation/ABI/testing/configfs-iio new file mode 100644 index 0000000000000..2483756fccf58 --- /dev/null +++ b/Documentation/ABI/testing/configfs-iio @@ -0,0 +1,21 @@ +What: /config/iio +Date: October 2015 +KernelVersion: 4.4 +Contact: linux-iio@vger.kernel.org +Description: + This represents Industrial IO configuration entry point + directory. It contains sub-groups corresponding to IIO + objects. + +What: /config/iio/triggers +Date: October 2015 +KernelVersion: 4.4 +Description: + Industrial IO software triggers directory. + +What: /config/iio/triggers/hrtimers +Date: October 2015 +KernelVersion: 4.4 +Description: + High resolution timers directory. Creating a directory here + will result in creating a hrtimer trigger in the IIO subsystem. diff --git a/Documentation/iio/iio_configfs.txt b/Documentation/iio/iio_configfs.txt new file mode 100644 index 0000000000000..f0add35cd52ed --- /dev/null +++ b/Documentation/iio/iio_configfs.txt @@ -0,0 +1,93 @@ +Industrial IIO configfs support + +1. Overview + +Configfs is a filesystem-based manager of kernel objects. IIO uses some +objects that could be easily configured using configfs (e.g.: devices, +triggers). + +See Documentation/filesystems/configfs/configfs.txt for more information +about how configfs works. + +2. Usage + +In order to use configfs support in IIO we need to select it at compile +time via CONFIG_IIO_CONFIGFS config option. + +Then, mount the configfs filesystem (usually under /config directory): + +$ mkdir /config +$ mount -t configfs none /config + +At this point, all default IIO groups will be created and can be accessed +under /config/iio. Next chapters will describe available IIO configuration +objects. + +3. Software triggers + +One of the IIO default configfs groups is the "triggers" group. It is +automagically accessible when the configfs is mounted and can be found +under /config/iio/triggers. + +IIO software triggers implementation offers support for creating multiple +trigger types. A new trigger type is usually implemented as a separate +kernel module following the interface in include/linux/iio/sw_trigger.h: + +/* + * drivers/iio/trigger/iio-trig-sample.c + * sample kernel module implementing a new trigger type + */ +#include + + +static struct iio_sw_trigger *iio_trig_sample_probe(const char *name) +{ + /* + * This allocates and registers an IIO trigger plus other + * trigger type specific initialization. + */ +} + +static int iio_trig_hrtimer_remove(struct iio_sw_trigger *swt) +{ + /* + * This undoes the actions in iio_trig_sample_probe + */ +} + +static const struct iio_sw_trigger_ops iio_trig_sample_ops = { + .probe = iio_trig_sample_probe, + .remove = iio_trig_sample_remove, +}; + +static struct iio_sw_trigger_type iio_trig_sample = { + .name = "trig-sample", + .owner = THIS_MODULE, + .ops = &iio_trig_sample_ops, +}; + +module_iio_sw_trigger_driver(iio_trig_sample); + +Each trigger type has its own directory under /config/iio/triggers. Loading +iio-trig-sample module will create 'trig-sample' trigger type directory +/config/iio/triggers/trig-sample. + +We support the following interrupt sources (trigger types): + * hrtimer, uses high resolution timers as interrupt source + +3.1 Hrtimer triggers creation and destruction + +Loading iio-trig-hrtimer module will register hrtimer trigger types allowing +users to create hrtimer triggers under /config/iio/triggers/hrtimer. + +e.g: + +$ mkdir /config/triggers/hrtimer/instance1 +$ rmdir /config/triggers/hrtimer/instance1 + +Each trigger can have one or more attributes specific to the trigger type. + +3.2 "hrtimer" trigger types attributes + +"hrtimer" trigger type doesn't have any configurable attribute from /config dir. +It does introduce the sampling_frequency attribute to trigger directory. -- GitLab From 93e87d73cc46685902bffb0928c2514eaf209b44 Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Tue, 1 Dec 2015 21:47:20 -0800 Subject: [PATCH 0897/2855] iio: chemical: vz89x: rework i2c transfer reading Add an optimized i2c transfer reading function, and fallback to racey smbus transfers if client->adapter doesn't support this. Signed-off-by: Matt Ranostay Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/vz89x.c | 66 ++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/drivers/iio/chemical/vz89x.c b/drivers/iio/chemical/vz89x.c index 11e59a5a51121..b8b8049232301 100644 --- a/drivers/iio/chemical/vz89x.c +++ b/drivers/iio/chemical/vz89x.c @@ -34,8 +34,9 @@ struct vz89x_data { struct i2c_client *client; struct mutex lock; - unsigned long last_update; + int (*xfer)(struct vz89x_data *data, u8 cmd); + unsigned long last_update; u8 buffer[VZ89X_REG_MEASUREMENT_SIZE]; }; @@ -100,27 +101,60 @@ static int vz89x_measurement_is_valid(struct vz89x_data *data) return !!(data->buffer[VZ89X_REG_MEASUREMENT_SIZE - 1] > 0); } -static int vz89x_get_measurement(struct vz89x_data *data) +static int vz89x_i2c_xfer(struct vz89x_data *data, u8 cmd) { + struct i2c_client *client = data->client; + struct i2c_msg msg[2]; int ret; - int i; + u8 buf[3] = { cmd, 0, 0}; - /* sensor can only be polled once a second max per datasheet */ - if (!time_after(jiffies, data->last_update + HZ)) - return 0; + msg[0].addr = client->addr; + msg[0].flags = client->flags; + msg[0].len = 3; + msg[0].buf = (char *) &buf; + + msg[1].addr = client->addr; + msg[1].flags = client->flags | I2C_M_RD; + msg[1].len = VZ89X_REG_MEASUREMENT_SIZE; + msg[1].buf = (char *) &data->buffer; + + ret = i2c_transfer(client->adapter, msg, 2); - ret = i2c_smbus_write_word_data(data->client, - VZ89X_REG_MEASUREMENT, 0); + return (ret == 2) ? 0 : ret; +} + +static int vz89x_smbus_xfer(struct vz89x_data *data, u8 cmd) +{ + struct i2c_client *client = data->client; + int ret; + int i; + + ret = i2c_smbus_write_word_data(client, cmd, 0); if (ret < 0) return ret; for (i = 0; i < VZ89X_REG_MEASUREMENT_SIZE; i++) { - ret = i2c_smbus_read_byte(data->client); + ret = i2c_smbus_read_byte(client); if (ret < 0) return ret; data->buffer[i] = ret; } + return 0; +} + +static int vz89x_get_measurement(struct vz89x_data *data) +{ + int ret; + + /* sensor can only be polled once a second max per datasheet */ + if (!time_after(jiffies, data->last_update + HZ)) + return 0; + + ret = data->xfer(data, VZ89X_REG_MEASUREMENT); + if (ret < 0) + return ret; + ret = vz89x_measurement_is_valid(data); if (ret) return -EAGAIN; @@ -204,15 +238,19 @@ static int vz89x_probe(struct i2c_client *client, struct iio_dev *indio_dev; struct vz89x_data *data; - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_BYTE)) - return -ENODEV; - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); if (!indio_dev) return -ENOMEM; - data = iio_priv(indio_dev); + + if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + data->xfer = vz89x_i2c_xfer; + else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BYTE)) + data->xfer = vz89x_smbus_xfer; + else + return -ENOTSUPP; + i2c_set_clientdata(client, indio_dev); data->client = client; data->last_update = jiffies - HZ; -- GitLab From d7a4c7633629c983a226ea3e32824360521c09b3 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 30 Nov 2015 14:43:09 +0100 Subject: [PATCH 0898/2855] i2c: piix4: remove unneeded assignments smatch rightfully says: drivers/i2c/busses/i2c-piix4.c:504 piix4_access warn: unused return: i = inb_p() drivers/i2c/busses/i2c-piix4.c:537 piix4_access warn: unused return: i = inb_p() Signed-off-by: Wolfram Sang Tested-by: Christian Fetzer --- drivers/i2c/busses/i2c-piix4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index af4e606f8886b..e045985950737 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -501,7 +501,7 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr, if (len == 0 || len > I2C_SMBUS_BLOCK_MAX) return -EINVAL; outb_p(len, SMBHSTDAT0); - i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ + inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ for (i = 1; i <= len; i++) outb_p(data->block[i], SMBBLKDAT); } @@ -534,7 +534,7 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr, data->block[0] = inb_p(SMBHSTDAT0); if (data->block[0] == 0 || data->block[0] > I2C_SMBUS_BLOCK_MAX) return -EPROTO; - i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ + inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ for (i = 1; i <= data->block[0]; i++) data->block[i] = inb_p(SMBBLKDAT); break; -- GitLab From cc018e3612e4a8244790521e88f9b1b7eb60dab0 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Thu, 3 Dec 2015 10:53:50 +0100 Subject: [PATCH 0899/2855] i2c: at91: add support for the HOLD field The hold field allows to configure the data hold time which can be set with the help of the generic binding 'i2c-sda-hold-time-ns'. This feature has been introduced with SAMA5D4 SoC family. Signed-off-by: Ludovic Desroches Acked-by: Nicolas Ferre Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- .../devicetree/bindings/i2c/i2c-at91.txt | 5 +- drivers/i2c/busses/i2c-at91.c | 53 +++++++++++++++++-- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c-at91.txt b/Documentation/devicetree/bindings/i2c/i2c-at91.txt index 6e81dc153f3b9..ef973a0343c7b 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-at91.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-at91.txt @@ -3,7 +3,7 @@ I2C for Atmel platforms Required properties : - compatible : Must be "atmel,at91rm9200-i2c", "atmel,at91sam9261-i2c", "atmel,at91sam9260-i2c", "atmel,at91sam9g20-i2c", "atmel,at91sam9g10-i2c", - "atmel,at91sam9x5-i2c" or "atmel,sama5d2-i2c" + "atmel,at91sam9x5-i2c", "atmel,sama5d4-i2c" or "atmel,sama5d2-i2c" - reg: physical base address of the controller and length of memory mapped region. - interrupts: interrupt number to the cpu. @@ -17,6 +17,8 @@ Optional properties: - dma-names: should contain "tx" and "rx". - atmel,fifo-size: maximum number of data the RX and TX FIFOs can store for FIFO capable I2C controllers. +- i2c-sda-hold-time-ns: TWD hold time, only available for "atmel,sama5d4-i2c" + and "atmel,sama5d2-i2c". - Child nodes conforming to i2c bus binding Examples : @@ -52,6 +54,7 @@ i2c0: i2c@f8034600 { #size-cells = <0>; clocks = <&flx0>; atmel,fifo-size = <16>; + i2c-sda-hold-time-ns = <336>; wm8731: wm8731@1a { compatible = "wm8731"; diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index 10835d1f559ba..921d32bfcda8e 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -64,6 +64,8 @@ #define AT91_TWI_IADR 0x000c /* Internal Address Register */ #define AT91_TWI_CWGR 0x0010 /* Clock Waveform Generator Reg */ +#define AT91_TWI_CWGR_HOLD_MAX 0x1f +#define AT91_TWI_CWGR_HOLD(x) (((x) & AT91_TWI_CWGR_HOLD_MAX) << 24) #define AT91_TWI_SR 0x0020 /* Status Register */ #define AT91_TWI_TXCOMP BIT(0) /* Transmission Complete */ @@ -110,6 +112,7 @@ struct at91_twi_pdata { unsigned clk_offset; bool has_unre_flag; bool has_alt_cmd; + bool has_hold_field; struct at_dma_slave dma_slave; }; @@ -187,10 +190,11 @@ static void at91_init_twi_bus(struct at91_twi_dev *dev) */ static void at91_calc_twi_clock(struct at91_twi_dev *dev, int twi_clk) { - int ckdiv, cdiv, div; + int ckdiv, cdiv, div, hold = 0; struct at91_twi_pdata *pdata = dev->pdata; int offset = pdata->clk_offset; int max_ckdiv = pdata->clk_max_div; + u32 twd_hold_time_ns = 0; div = max(0, (int)DIV_ROUND_UP(clk_get_rate(dev->clk), 2 * twi_clk) - offset); @@ -204,8 +208,33 @@ static void at91_calc_twi_clock(struct at91_twi_dev *dev, int twi_clk) cdiv = 255; } - dev->twi_cwgr_reg = (ckdiv << 16) | (cdiv << 8) | cdiv; - dev_dbg(dev->dev, "cdiv %d ckdiv %d\n", cdiv, ckdiv); + if (pdata->has_hold_field) { + of_property_read_u32(dev->dev->of_node, "i2c-sda-hold-time-ns", + &twd_hold_time_ns); + + /* + * hold time = HOLD + 3 x T_peripheral_clock + * Use clk rate in kHz to prevent overflows when computing + * hold. + */ + hold = DIV_ROUND_UP(twd_hold_time_ns + * (clk_get_rate(dev->clk) / 1000), 1000000); + hold -= 3; + if (hold < 0) + hold = 0; + if (hold > AT91_TWI_CWGR_HOLD_MAX) { + dev_warn(dev->dev, + "HOLD field set to its maximum value (%d instead of %d)\n", + AT91_TWI_CWGR_HOLD_MAX, hold); + hold = AT91_TWI_CWGR_HOLD_MAX; + } + } + + dev->twi_cwgr_reg = (ckdiv << 16) | (cdiv << 8) | cdiv + | AT91_TWI_CWGR_HOLD(hold); + + dev_dbg(dev->dev, "cdiv %d ckdiv %d hold %d (%d ns)\n", + cdiv, ckdiv, hold, twd_hold_time_ns); } static void at91_twi_dma_cleanup(struct at91_twi_dev *dev) @@ -797,6 +826,7 @@ static struct at91_twi_pdata at91rm9200_config = { .clk_offset = 3, .has_unre_flag = true, .has_alt_cmd = false, + .has_hold_field = false, }; static struct at91_twi_pdata at91sam9261_config = { @@ -804,6 +834,7 @@ static struct at91_twi_pdata at91sam9261_config = { .clk_offset = 4, .has_unre_flag = false, .has_alt_cmd = false, + .has_hold_field = false, }; static struct at91_twi_pdata at91sam9260_config = { @@ -811,6 +842,7 @@ static struct at91_twi_pdata at91sam9260_config = { .clk_offset = 4, .has_unre_flag = false, .has_alt_cmd = false, + .has_hold_field = false, }; static struct at91_twi_pdata at91sam9g20_config = { @@ -818,6 +850,7 @@ static struct at91_twi_pdata at91sam9g20_config = { .clk_offset = 4, .has_unre_flag = false, .has_alt_cmd = false, + .has_hold_field = false, }; static struct at91_twi_pdata at91sam9g10_config = { @@ -825,6 +858,7 @@ static struct at91_twi_pdata at91sam9g10_config = { .clk_offset = 4, .has_unre_flag = false, .has_alt_cmd = false, + .has_hold_field = false, }; static const struct platform_device_id at91_twi_devtypes[] = { @@ -854,6 +888,15 @@ static struct at91_twi_pdata at91sam9x5_config = { .clk_offset = 4, .has_unre_flag = false, .has_alt_cmd = false, + .has_hold_field = false, +}; + +static struct at91_twi_pdata sama5d4_config = { + .clk_max_div = 7, + .clk_offset = 4, + .has_unre_flag = false, + .has_alt_cmd = false, + .has_hold_field = true, }; static struct at91_twi_pdata sama5d2_config = { @@ -861,6 +904,7 @@ static struct at91_twi_pdata sama5d2_config = { .clk_offset = 4, .has_unre_flag = true, .has_alt_cmd = true, + .has_hold_field = true, }; static const struct of_device_id atmel_twi_dt_ids[] = { @@ -882,6 +926,9 @@ static const struct of_device_id atmel_twi_dt_ids[] = { }, { .compatible = "atmel,at91sam9x5-i2c", .data = &at91sam9x5_config, + }, { + .compatible = "atmel,sama5d4-i2c", + .data = &sama5d4_config, }, { .compatible = "atmel,sama5d2-i2c", .data = &sama5d2_config, -- GitLab From a613d9d48573d3d2f9bba7ed7719c5cc26d3a755 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Mon, 30 Nov 2015 16:21:40 +0000 Subject: [PATCH 0900/2855] i2c: eg20t: set i2c_adapter->dev.of_node Set the I2C adapter devices of_node to that of the PCI device, such that I2C clients may be instantiated via device tree. Signed-off-by: Paul Burton Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-eg20t.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index 76e699f9ed973..137125b5eae77 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c @@ -795,6 +795,7 @@ static int pch_i2c_probe(struct pci_dev *pdev, /* base_addr + offset; */ adap_info->pch_data[i].pch_base_address = base_addr + 0x100 * i; + pch_adap->dev.of_node = pdev->dev.of_node; pch_adap->dev.parent = &pdev->dev; pch_i2c_init(&adap_info->pch_data[i]); -- GitLab From 7a852b02d420c8c82e547e49377552e70976a083 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Mon, 30 Nov 2015 16:21:39 +0000 Subject: [PATCH 0901/2855] i2c: eg20t: allow build on MIPS platforms Allow the eg20t I2C driver to be built for MIPS platforms, in preparation for use on the MIPS Boston board. Signed-off-by: Paul Burton Signed-off-by: Wolfram Sang --- drivers/i2c/busses/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 7b0aa82ea38b2..69c46fe137771 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -516,7 +516,7 @@ config I2C_EFM32 config I2C_EG20T tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) I2C" - depends on PCI && (X86_32 || COMPILE_TEST) + depends on PCI && (X86_32 || MIPS || COMPILE_TEST) help This driver is for PCH(Platform controller Hub) I2C of EG20T which is an IOH(Input/Output Hub) for x86 embedded processor. -- GitLab From b2b018ef48675a9a524fa9791ea7d67fdac405f7 Mon Sep 17 00:00:00 2001 From: Chris J Arges Date: Tue, 1 Dec 2015 20:40:54 -0600 Subject: [PATCH 0902/2855] livepatch: add old_sympos as disambiguator field to klp_func Currently, patching objects with duplicate symbol names fail because the creation of the sysfs function directory collides with the previous attempt. Appending old_addr to the function name is problematic as it reveals the address of the function being patch to a normal user. Using the symbol's occurrence in kallsyms to postfix the function name in the sysfs directory solves the issue of having consistent unique names and ensuring that the address is not exposed to a normal user. In addition, using the symbol position as the user's method to disambiguate symbols instead of addr allows for disambiguating symbols in modules as well for both function addresses and for relocs. This also simplifies much of the code. Special handling for kASLR is no longer needed and can be removed. The klp_find_verify_func_addr function can be replaced by klp_find_object_symbol, and klp_verify_vmlinux_symbol and its callback can be removed completely. In cases of duplicate symbols, old_sympos will be used to disambiguate instead of old_addr. By default old_sympos will be 0, and patching will only succeed if the symbol is unique. Specifying a positive value will ensure that occurrence of the symbol in kallsyms for the patched object will be used for patching if it is valid. In addition, make old_addr an internal structure field not to be specified by the user. Finally, remove klp_find_verify_func_addr as it can be replaced by klp_find_object_symbol directly. Support for symbol position disambiguation for relocations is added in the next patch in this series. Signed-off-by: Chris J Arges Reviewed-by: Petr Mladek Acked-by: Josh Poimboeuf Signed-off-by: Jiri Kosina --- include/linux/livepatch.h | 19 ++++++----- kernel/livepatch/core.c | 72 +++++++++++++++++---------------------- 2 files changed, 41 insertions(+), 50 deletions(-) diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h index 31db7a05dd369..b60e8abab0ab5 100644 --- a/include/linux/livepatch.h +++ b/include/linux/livepatch.h @@ -37,8 +37,9 @@ enum klp_state { * struct klp_func - function structure for live patching * @old_name: name of the function to be patched * @new_func: pointer to the patched function code - * @old_addr: a hint conveying at what address the old function - * can be found (optional, vmlinux patches only) + * @old_sympos: a hint indicating which symbol position the old function + * can be found (optional) + * @old_addr: the address of the function being patched * @kobj: kobject for sysfs resources * @state: tracks function-level patch application state * @stack_node: list node for klp_ops func_stack list @@ -48,16 +49,16 @@ struct klp_func { const char *old_name; void *new_func; /* - * The old_addr field is optional and can be used to resolve - * duplicate symbol names in the vmlinux object. If this - * information is not present, the symbol is located by name - * with kallsyms. If the name is not unique and old_addr is - * not provided, the patch application fails as there is no - * way to resolve the ambiguity. + * The old_sympos field is optional and can be used to resolve + * duplicate symbol names in livepatch objects. If this field is zero, + * it is expected the symbol is unique, otherwise patching fails. If + * this value is greater than zero then that occurrence of the symbol + * in kallsyms for the given object is used. */ - unsigned long old_addr; + unsigned long old_sympos; /* internal */ + unsigned long old_addr; struct kobject kobj; enum klp_state state; struct list_head stack_node; diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index db545cbcdb893..e416f96e938df 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -135,13 +135,8 @@ struct klp_find_arg { const char *objname; const char *name; unsigned long addr; - /* - * If count == 0, the symbol was not found. If count == 1, a unique - * match was found and addr is set. If count > 1, there is - * unresolvable ambiguity among "count" number of symbols with the same - * name in the same object. - */ unsigned long count; + unsigned long pos; }; static int klp_find_callback(void *data, const char *name, @@ -158,37 +153,48 @@ static int klp_find_callback(void *data, const char *name, if (args->objname && strcmp(args->objname, mod->name)) return 0; - /* - * args->addr might be overwritten if another match is found - * but klp_find_object_symbol() handles this and only returns the - * addr if count == 1. - */ args->addr = addr; args->count++; + /* + * Finish the search when the symbol is found for the desired position + * or the position is not defined for a non-unique symbol. + */ + if ((args->pos && (args->count == args->pos)) || + (!args->pos && (args->count > 1))) + return 1; + return 0; } static int klp_find_object_symbol(const char *objname, const char *name, - unsigned long *addr) + unsigned long sympos, unsigned long *addr) { struct klp_find_arg args = { .objname = objname, .name = name, .addr = 0, - .count = 0 + .count = 0, + .pos = sympos, }; mutex_lock(&module_mutex); kallsyms_on_each_symbol(klp_find_callback, &args); mutex_unlock(&module_mutex); - if (args.count == 0) + /* + * Ensure an address was found. If sympos is 0, ensure symbol is unique; + * otherwise ensure the symbol position count matches sympos. + */ + if (args.addr == 0) pr_err("symbol '%s' not found in symbol table\n", name); - else if (args.count > 1) + else if (args.count > 1 && sympos == 0) { pr_err("unresolvable ambiguity (%lu matches) on symbol '%s' in object '%s'\n", args.count, name, objname); - else { + } else if (sympos != args.count && sympos > 0) { + pr_err("symbol position %lu for symbol '%s' in object '%s' not found\n", + sympos, name, objname ? objname : "vmlinux"); + } else { *addr = args.addr; return 0; } @@ -236,27 +242,6 @@ static int klp_verify_vmlinux_symbol(const char *name, unsigned long addr) return 0; } -static int klp_find_verify_func_addr(struct klp_object *obj, - struct klp_func *func) -{ - int ret; - -#if defined(CONFIG_RANDOMIZE_BASE) - /* If KASLR has been enabled, adjust old_addr accordingly */ - if (kaslr_enabled() && func->old_addr) - func->old_addr += kaslr_offset(); -#endif - - if (!func->old_addr || klp_is_module(obj)) - ret = klp_find_object_symbol(obj->name, func->old_name, - &func->old_addr); - else - ret = klp_verify_vmlinux_symbol(func->old_name, - func->old_addr); - - return ret; -} - /* * external symbols are located outside the parent object (where the parent * object is either vmlinux or the kmod being patched). @@ -276,8 +261,11 @@ static int klp_find_external_symbol(struct module *pmod, const char *name, } preempt_enable(); - /* otherwise check if it's in another .o within the patch module */ - return klp_find_object_symbol(pmod->name, name, addr); + /* + * Check if it's in another .o within the patch module. This also + * checks that the external symbol is unique. + */ + return klp_find_object_symbol(pmod->name, name, 0, addr); } static int klp_write_object_relocations(struct module *pmod, @@ -313,7 +301,7 @@ static int klp_write_object_relocations(struct module *pmod, else ret = klp_find_object_symbol(obj->mod->name, reloc->name, - &reloc->val); + 0, &reloc->val); if (ret) return ret; } @@ -756,7 +744,9 @@ static int klp_init_object_loaded(struct klp_patch *patch, } klp_for_each_func(obj, func) { - ret = klp_find_verify_func_addr(obj, func); + ret = klp_find_object_symbol(obj->name, func->old_name, + func->old_sympos, + &func->old_addr); if (ret) return ret; } -- GitLab From 064c89df6247cd829a7880cc8a87b7ed2cdfccd8 Mon Sep 17 00:00:00 2001 From: Chris J Arges Date: Tue, 1 Dec 2015 20:40:55 -0600 Subject: [PATCH 0903/2855] livepatch: add sympos as disambiguator field to klp_reloc In cases of duplicate symbols, sympos will be used to disambiguate instead of val. By default sympos will be 0, and patching will only succeed if the symbol is unique. Specifying a positive value will ensure that occurrence of the symbol in kallsyms for the patched object will be used for patching if it is valid. For external relocations sympos is not supported. Remove klp_verify_callback, klp_verify_args and klp_verify_vmlinux_symbol as they are no longer used. From the klp_reloc structure remove val, as it can be refactored as a local variable in klp_write_object_relocations. Signed-off-by: Chris J Arges Reviewed-by: Petr Mladek Acked-by: Josh Poimboeuf Signed-off-by: Jiri Kosina --- include/linux/livepatch.h | 5 +-- kernel/livepatch/core.c | 84 +++++++++------------------------------ 2 files changed, 21 insertions(+), 68 deletions(-) diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h index b60e8abab0ab5..a8828652f7942 100644 --- a/include/linux/livepatch.h +++ b/include/linux/livepatch.h @@ -67,8 +67,7 @@ struct klp_func { /** * struct klp_reloc - relocation structure for live patching * @loc: address where the relocation will be written - * @val: address of the referenced symbol (optional, - * vmlinux patches only) + * @sympos: position in kallsyms to disambiguate symbols (optional) * @type: ELF relocation type * @name: name of the referenced symbol (for lookup/verification) * @addend: offset from the referenced symbol @@ -76,7 +75,7 @@ struct klp_func { */ struct klp_reloc { unsigned long loc; - unsigned long val; + unsigned long sympos; unsigned long type; const char *name; int addend; diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index e416f96e938df..e842534d34935 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -203,45 +203,6 @@ static int klp_find_object_symbol(const char *objname, const char *name, return -EINVAL; } -struct klp_verify_args { - const char *name; - const unsigned long addr; -}; - -static int klp_verify_callback(void *data, const char *name, - struct module *mod, unsigned long addr) -{ - struct klp_verify_args *args = data; - - if (!mod && - !strcmp(args->name, name) && - args->addr == addr) - return 1; - - return 0; -} - -static int klp_verify_vmlinux_symbol(const char *name, unsigned long addr) -{ - struct klp_verify_args args = { - .name = name, - .addr = addr, - }; - int ret; - - mutex_lock(&module_mutex); - ret = kallsyms_on_each_symbol(klp_verify_callback, &args); - mutex_unlock(&module_mutex); - - if (!ret) { - pr_err("symbol '%s' not found at specified address 0x%016lx, kernel mismatch?\n", - name, addr); - return -EINVAL; - } - - return 0; -} - /* * external symbols are located outside the parent object (where the parent * object is either vmlinux or the kmod being patched). @@ -272,6 +233,7 @@ static int klp_write_object_relocations(struct module *pmod, struct klp_object *obj) { int ret; + unsigned long val; struct klp_reloc *reloc; if (WARN_ON(!klp_is_object_loaded(obj))) @@ -281,35 +243,27 @@ static int klp_write_object_relocations(struct module *pmod, return -EINVAL; for (reloc = obj->relocs; reloc->name; reloc++) { - if (!klp_is_module(obj)) { - -#if defined(CONFIG_RANDOMIZE_BASE) - /* If KASLR has been enabled, adjust old value accordingly */ - if (kaslr_enabled()) - reloc->val += kaslr_offset(); -#endif - ret = klp_verify_vmlinux_symbol(reloc->name, - reloc->val); - if (ret) - return ret; - } else { - /* module, reloc->val needs to be discovered */ - if (reloc->external) - ret = klp_find_external_symbol(pmod, - reloc->name, - &reloc->val); - else - ret = klp_find_object_symbol(obj->mod->name, - reloc->name, - 0, &reloc->val); - if (ret) - return ret; - } + /* discover the address of the referenced symbol */ + if (reloc->external) { + if (reloc->sympos > 0) { + pr_err("non-zero sympos for external reloc symbol '%s' is not supported\n", + reloc->name); + return -EINVAL; + } + ret = klp_find_external_symbol(pmod, reloc->name, &val); + } else + ret = klp_find_object_symbol(obj->name, + reloc->name, + reloc->sympos, + &val); + if (ret) + return ret; + ret = klp_write_module_reloc(pmod, reloc->type, reloc->loc, - reloc->val + reloc->addend); + val + reloc->addend); if (ret) { pr_err("relocation failed for symbol '%s' at 0x%016lx (%d)\n", - reloc->name, reloc->val, ret); + reloc->name, val, ret); return ret; } } -- GitLab From 444f9e99a840c4050c0530cfef81801a21a59f4c Mon Sep 17 00:00:00 2001 From: Chris J Arges Date: Tue, 1 Dec 2015 20:40:56 -0600 Subject: [PATCH 0904/2855] livepatch: function,sympos scheme in livepatch sysfs directory The following directory structure will allow for cases when the same function name exists in a single object. /sys/kernel/livepatch/// The sympos number corresponds to the nth occurrence of the symbol name in kallsyms for the patched object. An example of patching multiple symbols can be found here: https://github.com/dynup/kpatch/issues/493 Signed-off-by: Chris J Arges Reviewed-by: Petr Mladek Acked-by: Josh Poimboeuf Signed-off-by: Jiri Kosina --- Documentation/ABI/testing/sysfs-kernel-livepatch | 6 +++++- kernel/livepatch/core.c | 10 ++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-kernel-livepatch b/Documentation/ABI/testing/sysfs-kernel-livepatch index 5bf42a840b220..da87f43aec584 100644 --- a/Documentation/ABI/testing/sysfs-kernel-livepatch +++ b/Documentation/ABI/testing/sysfs-kernel-livepatch @@ -33,7 +33,7 @@ Description: The object directory contains subdirectories for each function that is patched within the object. -What: /sys/kernel/livepatch/// +What: /sys/kernel/livepatch/// Date: Nov 2014 KernelVersion: 3.19.0 Contact: live-patching@vger.kernel.org @@ -41,4 +41,8 @@ Description: The function directory contains attributes regarding the properties and state of the patched function. + The directory name contains the patched function name and a + sympos number corresponding to the nth occurrence of the symbol + name in kallsyms for the patched object. + There are currently no such attributes. diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index e842534d34935..94893e844e445 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -535,7 +535,7 @@ EXPORT_SYMBOL_GPL(klp_enable_patch); * /sys/kernel/livepatch/ * /sys/kernel/livepatch//enabled * /sys/kernel/livepatch// - * /sys/kernel/livepatch/// + * /sys/kernel/livepatch/// */ static ssize_t enabled_store(struct kobject *kobj, struct kobj_attribute *attr, @@ -680,8 +680,14 @@ static int klp_init_func(struct klp_object *obj, struct klp_func *func) INIT_LIST_HEAD(&func->stack_node); func->state = KLP_DISABLED; + /* The format for the sysfs directory is where sympos + * is the nth occurrence of this symbol in kallsyms for the patched + * object. If the user selects 0 for old_sympos, then 1 will be used + * since a unique symbol will be the first occurrence. + */ return kobject_init_and_add(&func->kobj, &klp_ktype_func, - &obj->kobj, "%s", func->old_name); + &obj->kobj, "%s,%lu", func->old_name, + func->old_sympos ? func->old_sympos : 1); } /* parts of the initialization that is done only when the object is loaded */ -- GitLab From 86c03f46b9a40b251e4d97f461a13f8b1f18ae17 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 1 Dec 2015 13:31:06 -0800 Subject: [PATCH 0905/2855] Input: wacom_w8001 - use __set_bit for evbits Signed-off-by: Peter Hutterer Acked-by: Benjamin Tissoires Reviewed-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wacom_w8001.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index 2792ca397dd08..d194d57c21b63 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c @@ -393,7 +393,8 @@ static int w8001_setup(struct w8001 *w8001) msleep(250); /* wait 250ms before querying the device */ - dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + __set_bit(EV_KEY, dev->evbit); + __set_bit(EV_ABS, dev->evbit); strlcat(w8001->name, "Wacom Serial", sizeof(w8001->name)); __set_bit(INPUT_PROP_DIRECT, dev->propbit); -- GitLab From ec9acda7360de7ee70cc0db36f41c1fd819a3310 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 1 Dec 2015 13:31:28 -0800 Subject: [PATCH 0906/2855] Input: wacom_w8001 - set BTN_TOOL_DOUBLETAP if we have 2fg support Signed-off-by: Peter Hutterer Acked-by: Benjamin Tissoires Reviewed-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wacom_w8001.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index d194d57c21b63..222006ee23fa5 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c @@ -471,6 +471,7 @@ static int w8001_setup(struct w8001 *w8001) case 5: w8001->pktlen = W8001_PKTLEN_TOUCH2FG; + __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); input_mt_init_slots(dev, 2, 0); input_set_abs_params(dev, ABS_MT_POSITION_X, 0, touch.x, 0, 0); -- GitLab From e171735410ae5a0ebf90d6bc6a8a97fc28bfc041 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 3 Dec 2015 12:24:26 -0800 Subject: [PATCH 0907/2855] Input: wacom_w8001 - handle touch error case correctly If a device failed at the pen setup and gets a zero reply from the touch device, we need to return an error. Otherwise we have a device with nothing but a name and the EV_KEY and EV_ABS bits. Signed-off-by: Peter Hutterer Acked-by: Benjamin Tissoires Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wacom_w8001.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index 222006ee23fa5..9ea5f8226a312 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c @@ -385,7 +385,7 @@ static int w8001_setup(struct w8001 *w8001) struct input_dev *dev = w8001->dev; struct w8001_coord coord; struct w8001_touch_query touch; - int error; + int error, err_pen, err_touch; error = w8001_command(w8001, W8001_CMD_STOP, false); if (error) @@ -400,8 +400,8 @@ static int w8001_setup(struct w8001 *w8001) __set_bit(INPUT_PROP_DIRECT, dev->propbit); /* penabled? */ - error = w8001_command(w8001, W8001_CMD_QUERY, true); - if (!error) { + err_pen = w8001_command(w8001, W8001_CMD_QUERY, true); + if (!err_pen) { __set_bit(BTN_TOUCH, dev->keybit); __set_bit(BTN_TOOL_PEN, dev->keybit); __set_bit(BTN_TOOL_RUBBER, dev->keybit); @@ -426,13 +426,12 @@ static int w8001_setup(struct w8001 *w8001) } /* Touch enabled? */ - error = w8001_command(w8001, W8001_CMD_TOUCHQUERY, true); + err_touch = w8001_command(w8001, W8001_CMD_TOUCHQUERY, true); - /* - * Some non-touch devices may reply to the touch query. But their - * second byte is empty, which indicates touch is not supported. - */ - if (!error && w8001->response[1]) { + if (!err_touch && !w8001->response[1]) + err_touch = -ENXIO; + + if (!err_touch) { __set_bit(BTN_TOUCH, dev->keybit); __set_bit(BTN_TOOL_FINGER, dev->keybit); @@ -491,7 +490,7 @@ static int w8001_setup(struct w8001 *w8001) strlcat(w8001->name, " Touchscreen", sizeof(w8001->name)); - return 0; + return !err_pen || !err_touch ? 0 : -ENXIO; } /* -- GitLab From 5d0a4fe2a9347b05bc5db2963cb7cd6cf014a9ed Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 3 Dec 2015 12:25:09 -0800 Subject: [PATCH 0908/2855] Input: wacom_w8001 - split pen and touch initialization up This is preparation work for splitting it up for two event nodes. Signed-off-by: Peter Hutterer Acked-by: Benjamin Tissoires Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wacom_w8001.c | 194 ++++++++++++++---------- 1 file changed, 111 insertions(+), 83 deletions(-) diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index 9ea5f8226a312..de8f0e47fc3d5 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c @@ -380,12 +380,10 @@ static void w8001_close(struct input_dev *dev) w8001_command(w8001, W8001_CMD_STOP, false); } -static int w8001_setup(struct w8001 *w8001) +static int w8001_detect(struct w8001 *w8001) { struct input_dev *dev = w8001->dev; - struct w8001_coord coord; - struct w8001_touch_query touch; - int error, err_pen, err_touch; + int error; error = w8001_command(w8001, W8001_CMD_STOP, false); if (error) @@ -399,98 +397,121 @@ static int w8001_setup(struct w8001 *w8001) __set_bit(INPUT_PROP_DIRECT, dev->propbit); + return 0; +} + +static int w8001_setup_pen(struct w8001 *w8001) +{ + struct input_dev *dev = w8001->dev; + struct w8001_coord coord; + int error; + /* penabled? */ - err_pen = w8001_command(w8001, W8001_CMD_QUERY, true); - if (!err_pen) { - __set_bit(BTN_TOUCH, dev->keybit); - __set_bit(BTN_TOOL_PEN, dev->keybit); - __set_bit(BTN_TOOL_RUBBER, dev->keybit); - __set_bit(BTN_STYLUS, dev->keybit); - __set_bit(BTN_STYLUS2, dev->keybit); - - parse_pen_data(w8001->response, &coord); - w8001->max_pen_x = coord.x; - w8001->max_pen_y = coord.y; - - input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); - input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); - input_abs_set_res(dev, ABS_X, W8001_PEN_RESOLUTION); - input_abs_set_res(dev, ABS_Y, W8001_PEN_RESOLUTION); - input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0); - if (coord.tilt_x && coord.tilt_y) { - input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); - input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0); - } - w8001->id = 0x90; - strlcat(w8001->name, " Penabled", sizeof(w8001->name)); + error = w8001_command(w8001, W8001_CMD_QUERY, true); + if (error) + return error; + + __set_bit(BTN_TOUCH, dev->keybit); + __set_bit(BTN_TOOL_PEN, dev->keybit); + __set_bit(BTN_TOOL_RUBBER, dev->keybit); + __set_bit(BTN_STYLUS, dev->keybit); + __set_bit(BTN_STYLUS2, dev->keybit); + + parse_pen_data(w8001->response, &coord); + w8001->max_pen_x = coord.x; + w8001->max_pen_y = coord.y; + + input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); + input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); + input_abs_set_res(dev, ABS_X, W8001_PEN_RESOLUTION); + input_abs_set_res(dev, ABS_Y, W8001_PEN_RESOLUTION); + input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0); + if (coord.tilt_x && coord.tilt_y) { + input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); + input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0); } + w8001->id = 0x90; + strlcat(w8001->name, " Penabled", sizeof(w8001->name)); + + return 0; +} + +static int w8001_setup_touch(struct w8001 *w8001) +{ + struct input_dev *dev = w8001->dev; + struct w8001_touch_query touch; + int error; + /* Touch enabled? */ - err_touch = w8001_command(w8001, W8001_CMD_TOUCHQUERY, true); + error = w8001_command(w8001, W8001_CMD_TOUCHQUERY, true); + if (error) + return error; + /* + * Some non-touch devices may reply to the touch query. But their + * second byte is empty, which indicates touch is not supported. + */ + if (!w8001->response[1]) + return -ENXIO; - if (!err_touch && !w8001->response[1]) - err_touch = -ENXIO; + __set_bit(BTN_TOUCH, dev->keybit); + __set_bit(BTN_TOOL_FINGER, dev->keybit); - if (!err_touch) { - __set_bit(BTN_TOUCH, dev->keybit); - __set_bit(BTN_TOOL_FINGER, dev->keybit); + parse_touchquery(w8001->response, &touch); + w8001->max_touch_x = touch.x; + w8001->max_touch_y = touch.y; - parse_touchquery(w8001->response, &touch); - w8001->max_touch_x = touch.x; - w8001->max_touch_y = touch.y; + if (w8001->max_pen_x && w8001->max_pen_y) { + /* if pen is supported scale to pen maximum */ + touch.x = w8001->max_pen_x; + touch.y = w8001->max_pen_y; + touch.panel_res = W8001_PEN_RESOLUTION; + } - if (w8001->max_pen_x && w8001->max_pen_y) { - /* if pen is supported scale to pen maximum */ - touch.x = w8001->max_pen_x; - touch.y = w8001->max_pen_y; - touch.panel_res = W8001_PEN_RESOLUTION; - } + input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0); + input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0); + input_abs_set_res(dev, ABS_X, touch.panel_res); + input_abs_set_res(dev, ABS_Y, touch.panel_res); - input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0); - input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0); - input_abs_set_res(dev, ABS_X, touch.panel_res); - input_abs_set_res(dev, ABS_Y, touch.panel_res); - - switch (touch.sensor_id) { - case 0: - case 2: - w8001->pktlen = W8001_PKTLEN_TOUCH93; - w8001->id = 0x93; - strlcat(w8001->name, " 1FG", sizeof(w8001->name)); - break; + switch (touch.sensor_id) { + case 0: + case 2: + w8001->pktlen = W8001_PKTLEN_TOUCH93; + w8001->id = 0x93; + strlcat(w8001->name, " 1FG", sizeof(w8001->name)); + break; - case 1: - case 3: - case 4: - w8001->pktlen = W8001_PKTLEN_TOUCH9A; - strlcat(w8001->name, " 1FG", sizeof(w8001->name)); - w8001->id = 0x9a; - break; + case 1: + case 3: + case 4: + w8001->pktlen = W8001_PKTLEN_TOUCH9A; + strlcat(w8001->name, " 1FG", sizeof(w8001->name)); + w8001->id = 0x9a; + break; - case 5: - w8001->pktlen = W8001_PKTLEN_TOUCH2FG; - - __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); - input_mt_init_slots(dev, 2, 0); - input_set_abs_params(dev, ABS_MT_POSITION_X, - 0, touch.x, 0, 0); - input_set_abs_params(dev, ABS_MT_POSITION_Y, - 0, touch.y, 0, 0); - input_set_abs_params(dev, ABS_MT_TOOL_TYPE, - 0, MT_TOOL_MAX, 0, 0); - - strlcat(w8001->name, " 2FG", sizeof(w8001->name)); - if (w8001->max_pen_x && w8001->max_pen_y) - w8001->id = 0xE3; - else - w8001->id = 0xE2; - break; - } + case 5: + w8001->pktlen = W8001_PKTLEN_TOUCH2FG; + + __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); + input_mt_init_slots(dev, 2, 0); + input_set_abs_params(dev, ABS_MT_POSITION_X, + 0, touch.x, 0, 0); + input_set_abs_params(dev, ABS_MT_POSITION_Y, + 0, touch.y, 0, 0); + input_set_abs_params(dev, ABS_MT_TOOL_TYPE, + 0, MT_TOOL_MAX, 0, 0); + + strlcat(w8001->name, " 2FG", sizeof(w8001->name)); + if (w8001->max_pen_x && w8001->max_pen_y) + w8001->id = 0xE3; + else + w8001->id = 0xE2; + break; } strlcat(w8001->name, " Touchscreen", sizeof(w8001->name)); - return !err_pen || !err_touch ? 0 : -ENXIO; + return 0; } /* @@ -519,7 +540,7 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) { struct w8001 *w8001; struct input_dev *input_dev; - int err; + int err, err_pen, err_touch; w8001 = kzalloc(sizeof(struct w8001), GFP_KERNEL); input_dev = input_allocate_device(); @@ -538,10 +559,17 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) if (err) goto fail2; - err = w8001_setup(w8001); + err = w8001_detect(w8001); if (err) goto fail3; + err_pen = w8001_setup_pen(w8001); + err_touch = w8001_setup_touch(w8001); + if (err_pen && err_touch) { + err = -ENXIO; + goto fail3; + } + input_dev->name = w8001->name; input_dev->phys = w8001->phys; input_dev->id.product = w8001->id; -- GitLab From e0361b70175f0cd6199dd9ed6679632de73973d4 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 3 Dec 2015 12:26:19 -0800 Subject: [PATCH 0909/2855] Input: wacom_w8001 - split the touch and pen devices into two devices These devices have a pen device and a touch device through the same serial protocol, split it up into two separate devices like we do for USB Wacom tablets too. Userspace already matches on the device name so we can't drop it completely. Compose the same basename based on capabilities and append the tool type, leading to a name like "Wacom Serial Penabled 2FG Touchscreen Pen". Note that this drops BTN_TOOL_FINGER, it is not needed once the tools are split out (and a touch device with BTN_TOOL_FINGER is interpreted as touchpad by most of userspace). Signed-off-by: Peter Hutterer Acked-by: Benjamin Tissoires Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wacom_w8001.c | 167 ++++++++++++++++-------- 1 file changed, 116 insertions(+), 51 deletions(-) diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index de8f0e47fc3d5..fe983e781bca5 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c @@ -80,7 +80,8 @@ struct w8001_touch_query { */ struct w8001 { - struct input_dev *dev; + struct input_dev *pen_dev; + struct input_dev *touch_dev; struct serio *serio; struct completion cmd_done; int id; @@ -95,7 +96,10 @@ struct w8001 { u16 max_touch_y; u16 max_pen_x; u16 max_pen_y; - char name[64]; + char pen_name[64]; + char touch_name[64]; + int open_count; + struct mutex mutex; }; static void parse_pen_data(u8 *data, struct w8001_coord *coord) @@ -141,7 +145,7 @@ static void scale_touch_coordinates(struct w8001 *w8001, static void parse_multi_touch(struct w8001 *w8001) { - struct input_dev *dev = w8001->dev; + struct input_dev *dev = w8001->touch_dev; unsigned char *data = w8001->data; unsigned int x, y; int i; @@ -207,7 +211,7 @@ static void parse_touchquery(u8 *data, struct w8001_touch_query *query) static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord) { - struct input_dev *dev = w8001->dev; + struct input_dev *dev = w8001->pen_dev; /* * We have 1 bit for proximity (rdy) and 3 bits for tip, side, @@ -233,11 +237,6 @@ static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord) break; case BTN_TOOL_FINGER: - input_report_key(dev, BTN_TOUCH, 0); - input_report_key(dev, BTN_TOOL_FINGER, 0); - input_sync(dev); - /* fall through */ - case KEY_RESERVED: w8001->type = coord->f2 ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; break; @@ -261,7 +260,7 @@ static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord) static void report_single_touch(struct w8001 *w8001, struct w8001_coord *coord) { - struct input_dev *dev = w8001->dev; + struct input_dev *dev = w8001->touch_dev; unsigned int x = coord->x; unsigned int y = coord->y; @@ -271,7 +270,6 @@ static void report_single_touch(struct w8001 *w8001, struct w8001_coord *coord) input_report_abs(dev, ABS_X, x); input_report_abs(dev, ABS_Y, y); input_report_key(dev, BTN_TOUCH, coord->tsw); - input_report_key(dev, BTN_TOOL_FINGER, coord->tsw); input_sync(dev); @@ -369,20 +367,36 @@ static int w8001_command(struct w8001 *w8001, unsigned char command, static int w8001_open(struct input_dev *dev) { struct w8001 *w8001 = input_get_drvdata(dev); + int err; + + err = mutex_lock_interruptible(&w8001->mutex); + if (err) + return err; + + if (w8001->open_count++ == 0) { + err = w8001_command(w8001, W8001_CMD_START, false); + if (err) + w8001->open_count--; + } - return w8001_command(w8001, W8001_CMD_START, false); + mutex_unlock(&w8001->mutex); + return err; } static void w8001_close(struct input_dev *dev) { struct w8001 *w8001 = input_get_drvdata(dev); - w8001_command(w8001, W8001_CMD_STOP, false); + mutex_lock(&w8001->mutex); + + if (--w8001->open_count == 0) + w8001_command(w8001, W8001_CMD_STOP, false); + + mutex_unlock(&w8001->mutex); } static int w8001_detect(struct w8001 *w8001) { - struct input_dev *dev = w8001->dev; int error; error = w8001_command(w8001, W8001_CMD_STOP, false); @@ -391,18 +405,13 @@ static int w8001_detect(struct w8001 *w8001) msleep(250); /* wait 250ms before querying the device */ - __set_bit(EV_KEY, dev->evbit); - __set_bit(EV_ABS, dev->evbit); - strlcat(w8001->name, "Wacom Serial", sizeof(w8001->name)); - - __set_bit(INPUT_PROP_DIRECT, dev->propbit); - return 0; } -static int w8001_setup_pen(struct w8001 *w8001) +static int w8001_setup_pen(struct w8001 *w8001, char *basename, + size_t basename_sz) { - struct input_dev *dev = w8001->dev; + struct input_dev *dev = w8001->pen_dev; struct w8001_coord coord; int error; @@ -411,11 +420,14 @@ static int w8001_setup_pen(struct w8001 *w8001) if (error) return error; + __set_bit(EV_KEY, dev->evbit); + __set_bit(EV_ABS, dev->evbit); __set_bit(BTN_TOUCH, dev->keybit); __set_bit(BTN_TOOL_PEN, dev->keybit); __set_bit(BTN_TOOL_RUBBER, dev->keybit); __set_bit(BTN_STYLUS, dev->keybit); __set_bit(BTN_STYLUS2, dev->keybit); + __set_bit(INPUT_PROP_DIRECT, dev->propbit); parse_pen_data(w8001->response, &coord); w8001->max_pen_x = coord.x; @@ -432,17 +444,19 @@ static int w8001_setup_pen(struct w8001 *w8001) } w8001->id = 0x90; - strlcat(w8001->name, " Penabled", sizeof(w8001->name)); + strlcat(basename, " Penabled", basename_sz); return 0; } -static int w8001_setup_touch(struct w8001 *w8001) +static int w8001_setup_touch(struct w8001 *w8001, char *basename, + size_t basename_sz) { - struct input_dev *dev = w8001->dev; + struct input_dev *dev = w8001->touch_dev; struct w8001_touch_query touch; int error; + /* Touch enabled? */ error = w8001_command(w8001, W8001_CMD_TOUCHQUERY, true); if (error) @@ -454,8 +468,10 @@ static int w8001_setup_touch(struct w8001 *w8001) if (!w8001->response[1]) return -ENXIO; + __set_bit(EV_KEY, dev->evbit); + __set_bit(EV_ABS, dev->evbit); __set_bit(BTN_TOUCH, dev->keybit); - __set_bit(BTN_TOOL_FINGER, dev->keybit); + __set_bit(INPUT_PROP_DIRECT, dev->propbit); parse_touchquery(w8001->response, &touch); w8001->max_touch_x = touch.x; @@ -478,14 +494,14 @@ static int w8001_setup_touch(struct w8001 *w8001) case 2: w8001->pktlen = W8001_PKTLEN_TOUCH93; w8001->id = 0x93; - strlcat(w8001->name, " 1FG", sizeof(w8001->name)); + strlcat(basename, " 1FG", basename_sz); break; case 1: case 3: case 4: w8001->pktlen = W8001_PKTLEN_TOUCH9A; - strlcat(w8001->name, " 1FG", sizeof(w8001->name)); + strlcat(basename, " 1FG", basename_sz); w8001->id = 0x9a; break; @@ -501,7 +517,7 @@ static int w8001_setup_touch(struct w8001 *w8001) input_set_abs_params(dev, ABS_MT_TOOL_TYPE, 0, MT_TOOL_MAX, 0, 0); - strlcat(w8001->name, " 2FG", sizeof(w8001->name)); + strlcat(basename, " 2FG", basename_sz); if (w8001->max_pen_x && w8001->max_pen_y) w8001->id = 0xE3; else @@ -509,11 +525,27 @@ static int w8001_setup_touch(struct w8001 *w8001) break; } - strlcat(w8001->name, " Touchscreen", sizeof(w8001->name)); + strlcat(basename, " Touchscreen", basename_sz); return 0; } +static void w8001_set_devdata(struct input_dev *dev, struct w8001 *w8001, + struct serio *serio) +{ + dev->phys = w8001->phys; + dev->id.bustype = BUS_RS232; + dev->id.product = w8001->id; + dev->id.vendor = 0x056a; + dev->id.version = 0x0100; + dev->open = w8001_open; + dev->close = w8001_close; + + dev->dev.parent = &serio->dev; + + input_set_drvdata(dev, w8001); +} + /* * w8001_disconnect() is the opposite of w8001_connect() */ @@ -524,7 +556,10 @@ static void w8001_disconnect(struct serio *serio) serio_close(serio); - input_unregister_device(w8001->dev); + if (w8001->pen_dev) + input_unregister_device(w8001->pen_dev); + if (w8001->touch_dev) + input_unregister_device(w8001->touch_dev); kfree(w8001); serio_set_drvdata(serio, NULL); @@ -539,18 +574,23 @@ static void w8001_disconnect(struct serio *serio) static int w8001_connect(struct serio *serio, struct serio_driver *drv) { struct w8001 *w8001; - struct input_dev *input_dev; + struct input_dev *input_dev_pen; + struct input_dev *input_dev_touch; + char basename[64]; int err, err_pen, err_touch; w8001 = kzalloc(sizeof(struct w8001), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!w8001 || !input_dev) { + input_dev_pen = input_allocate_device(); + input_dev_touch = input_allocate_device(); + if (!w8001 || !input_dev_pen || !input_dev_touch) { err = -ENOMEM; goto fail1; } w8001->serio = serio; - w8001->dev = input_dev; + w8001->pen_dev = input_dev_pen; + w8001->touch_dev = input_dev_touch; + mutex_init(&w8001->mutex); init_completion(&w8001->cmd_done); snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); @@ -563,38 +603,63 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) if (err) goto fail3; - err_pen = w8001_setup_pen(w8001); - err_touch = w8001_setup_touch(w8001); + /* For backwards-compatibility we compose the basename based on + * capabilities and then just append the tool type + */ + strlcpy(basename, "Wacom Serial", sizeof(basename)); + + err_pen = w8001_setup_pen(w8001, basename, sizeof(basename)); + err_touch = w8001_setup_touch(w8001, basename, sizeof(basename)); if (err_pen && err_touch) { err = -ENXIO; goto fail3; } - input_dev->name = w8001->name; - input_dev->phys = w8001->phys; - input_dev->id.product = w8001->id; - input_dev->id.bustype = BUS_RS232; - input_dev->id.vendor = 0x056a; - input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; + if (!err_pen) { + strlcpy(w8001->pen_name, basename, sizeof(w8001->pen_name)); + strlcat(w8001->pen_name, " Pen", sizeof(w8001->pen_name)); + input_dev_pen->name = w8001->pen_name; - input_dev->open = w8001_open; - input_dev->close = w8001_close; + w8001_set_devdata(input_dev_pen, w8001, serio); - input_set_drvdata(input_dev, w8001); + err = input_register_device(w8001->pen_dev); + if (err) + goto fail3; + } else { + input_free_device(input_dev_pen); + input_dev_pen = NULL; + w8001->pen_dev = NULL; + } - err = input_register_device(w8001->dev); - if (err) - goto fail3; + if (!err_touch) { + strlcpy(w8001->touch_name, basename, sizeof(w8001->touch_name)); + strlcat(w8001->touch_name, " Finger", + sizeof(w8001->touch_name)); + input_dev_touch->name = w8001->touch_name; + + w8001_set_devdata(input_dev_touch, w8001, serio); + + err = input_register_device(w8001->touch_dev); + if (err) + goto fail4; + } else { + input_free_device(input_dev_touch); + input_dev_touch = NULL; + w8001->touch_dev = NULL; + } return 0; +fail4: + if (w8001->pen_dev) + input_unregister_device(w8001->pen_dev); fail3: serio_close(serio); fail2: serio_set_drvdata(serio, NULL); fail1: - input_free_device(input_dev); + input_free_device(input_dev_pen); + input_free_device(input_dev_touch); kfree(w8001); return err; } -- GitLab From 35deff7eb212b661b32177b6043f674fde6314d7 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Fri, 20 Nov 2015 10:51:00 +0000 Subject: [PATCH 0910/2855] mfd: as3722: Handle interrupts on suspend The as3722 device is registered as an irqchip and the as3722-rtc interrupt is one of it's interrupt sources. When using the as3722-rtc as a wake-up device from suspend, the following is seen: PM: Syncing filesystems ... done. Freezing user space processes ... (elapsed 0.001 seconds) done. Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done. Suspending console(s) (use no_console_suspend to debug) PM: suspend of devices complete after 161.119 msecs PM: late suspend of devices complete after 1.048 msecs PM: noirq suspend of devices complete after 0.756 msecs Disabling non-boot CPUs ... CPU1: shutdown CPU2: shutdown CPU3: shutdown Entering suspend state LP1 Enabling non-boot CPUs ... CPU1 is up CPU2 is up CPU3 is up PM: noirq resume of devices complete after 0.487 msecs as3722 4-0040: Failed to read IRQ status: -16 as3722 4-0040: Failed to read IRQ status: -16 as3722 4-0040: Failed to read IRQ status: -16 as3722 4-0040: Failed to read IRQ status: -16 ... The reason why the as3722 interrupt status cannot be read is because the as3722 interrupt is not masked during suspend and when the as3722-rtc interrupt occurs, to wake-up the device, the interrupt is seen before the i2c controller has been resumed in order to read the as3722 interrupt status. The as3722-rtc driver sets it's interrupt as a wake-up source during suspend, which gets propagated to the parent as3722 interrupt. However, the as3722-rtc driver cannot disable it's interrupt during suspend otherwise we would never be woken up and so the as3722 must disable it's interrupt instead. Fix this by disabling the as3722 interrupt during suspend. To ensure that a wake-up event from the as3722 is not missing, enable the as3722 interrupt as a wake-up source before disabling the interrupt on entering suspend. Signed-off-by: Jon Hunter Signed-off-by: Lee Jones --- drivers/mfd/as3722.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/mfd/as3722.c b/drivers/mfd/as3722.c index 924ea90494ae5..3b21eb4bc480e 100644 --- a/drivers/mfd/as3722.c +++ b/drivers/mfd/as3722.c @@ -405,6 +405,8 @@ static int as3722_i2c_probe(struct i2c_client *i2c, goto scrub; } + device_init_wakeup(as3722->dev, true); + dev_dbg(as3722->dev, "AS3722 core driver initialized successfully\n"); return 0; @@ -422,6 +424,29 @@ static int as3722_i2c_remove(struct i2c_client *i2c) return 0; } +static int as3722_i2c_suspend(struct device *dev) +{ + struct as3722 *as3722 = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + enable_irq_wake(as3722->chip_irq); + disable_irq(as3722->chip_irq); + + return 0; +} + +static int as3722_i2c_resume(struct device *dev) +{ + struct as3722 *as3722 = dev_get_drvdata(dev); + + enable_irq(as3722->chip_irq); + + if (device_may_wakeup(dev)) + disable_irq_wake(as3722->chip_irq); + + return 0; +} + static const struct of_device_id as3722_of_match[] = { { .compatible = "ams,as3722", }, {}, @@ -434,10 +459,15 @@ static const struct i2c_device_id as3722_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, as3722_i2c_id); +static const struct dev_pm_ops as3722_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(as3722_i2c_suspend, as3722_i2c_resume) +}; + static struct i2c_driver as3722_i2c_driver = { .driver = { .name = "as3722", .of_match_table = as3722_of_match, + .pm = &as3722_pm_ops, }, .probe = as3722_i2c_probe, .remove = as3722_i2c_remove, -- GitLab From 505b9e573ce1384f1729acb3226f6d83b651dee1 Mon Sep 17 00:00:00 2001 From: Saurabh Sengar Date: Mon, 16 Nov 2015 14:43:17 +0530 Subject: [PATCH 0911/2855] mfd: mc13xxx-core: Use of_property_read_bool() For checking if a property is present or not, use of_property_read_bool instead of of_get_property() Signed-off-by: Saurabh Sengar Signed-off-by: Lee Jones --- drivers/mfd/mc13xxx-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index 3f9f4c874d2aa..d7f54e492aa61 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c @@ -383,16 +383,16 @@ static int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx) if (!np) return -ENODEV; - if (of_get_property(np, "fsl,mc13xxx-uses-adc", NULL)) + if (of_property_read_bool(np, "fsl,mc13xxx-uses-adc")) mc13xxx->flags |= MC13XXX_USE_ADC; - if (of_get_property(np, "fsl,mc13xxx-uses-codec", NULL)) + if (of_property_read_bool(np, "fsl,mc13xxx-uses-codec")) mc13xxx->flags |= MC13XXX_USE_CODEC; - if (of_get_property(np, "fsl,mc13xxx-uses-rtc", NULL)) + if (of_property_read_bool(np, "fsl,mc13xxx-uses-rtc")) mc13xxx->flags |= MC13XXX_USE_RTC; - if (of_get_property(np, "fsl,mc13xxx-uses-touch", NULL)) + if (of_property_read_bool(np, "fsl,mc13xxx-uses-touch")) mc13xxx->flags |= MC13XXX_USE_TOUCHSCREEN; return 0; -- GitLab From f83e7d814084d9e982a8e24311a402e811d0ee90 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 13 Nov 2015 17:03:51 +0100 Subject: [PATCH 0912/2855] mfd: da903x: Constify da903x_chip_ops structure The da903x_chip_ops structure is never modified, so declare it as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Lee Jones --- drivers/mfd/da903x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c index 37e4426ef0610..f6a045900b167 100644 --- a/drivers/mfd/da903x.c +++ b/drivers/mfd/da903x.c @@ -60,7 +60,7 @@ struct da903x_chip_ops { struct da903x_chip { struct i2c_client *client; struct device *dev; - struct da903x_chip_ops *ops; + const struct da903x_chip_ops *ops; int type; uint32_t events_mask; @@ -424,7 +424,7 @@ static irqreturn_t da903x_irq_handler(int irq, void *data) return IRQ_HANDLED; } -static struct da903x_chip_ops da903x_ops[] = { +static const struct da903x_chip_ops da903x_ops[] = { [0] = { .init_chip = da9030_init_chip, .unmask_events = da9030_unmask_events, -- GitLab From bdd5dcf513847b306621a2059e2ebee910208d8a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 12 Nov 2015 10:51:10 +0100 Subject: [PATCH 0913/2855] mfd: ab8500: Delete static IRQ resources The platforms that use the AB8500 define all IRQ resources in the device tree and they are automatically populated by matching the .of_compatible string. These static resources are just surplus baggage these days. Signed-off-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/ab8500-core.c | 482 -------------------------------------- 1 file changed, 482 deletions(-) diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index fefbe4cfa61dd..582d3587f56aa 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -609,442 +609,28 @@ int ab8500_suspend(struct ab8500 *ab8500) return 0; } -static struct resource ab8500_gpadc_resources[] = { - { - .name = "HW_CONV_END", - .start = AB8500_INT_GP_HW_ADC_CONV_END, - .end = AB8500_INT_GP_HW_ADC_CONV_END, - .flags = IORESOURCE_IRQ, - }, - { - .name = "SW_CONV_END", - .start = AB8500_INT_GP_SW_ADC_CONV_END, - .end = AB8500_INT_GP_SW_ADC_CONV_END, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource ab8505_gpadc_resources[] = { - { - .name = "SW_CONV_END", - .start = AB8500_INT_GP_SW_ADC_CONV_END, - .end = AB8500_INT_GP_SW_ADC_CONV_END, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource ab8500_rtc_resources[] = { - { - .name = "60S", - .start = AB8500_INT_RTC_60S, - .end = AB8500_INT_RTC_60S, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ALARM", - .start = AB8500_INT_RTC_ALARM, - .end = AB8500_INT_RTC_ALARM, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource ab8540_rtc_resources[] = { - { - .name = "1S", - .start = AB8540_INT_RTC_1S, - .end = AB8540_INT_RTC_1S, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ALARM", - .start = AB8500_INT_RTC_ALARM, - .end = AB8500_INT_RTC_ALARM, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource ab8500_poweronkey_db_resources[] = { - { - .name = "ONKEY_DBF", - .start = AB8500_INT_PON_KEY1DB_F, - .end = AB8500_INT_PON_KEY1DB_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ONKEY_DBR", - .start = AB8500_INT_PON_KEY1DB_R, - .end = AB8500_INT_PON_KEY1DB_R, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource ab8500_av_acc_detect_resources[] = { - { - .name = "ACC_DETECT_1DB_F", - .start = AB8500_INT_ACC_DETECT_1DB_F, - .end = AB8500_INT_ACC_DETECT_1DB_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ACC_DETECT_1DB_R", - .start = AB8500_INT_ACC_DETECT_1DB_R, - .end = AB8500_INT_ACC_DETECT_1DB_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ACC_DETECT_21DB_F", - .start = AB8500_INT_ACC_DETECT_21DB_F, - .end = AB8500_INT_ACC_DETECT_21DB_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ACC_DETECT_21DB_R", - .start = AB8500_INT_ACC_DETECT_21DB_R, - .end = AB8500_INT_ACC_DETECT_21DB_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ACC_DETECT_22DB_F", - .start = AB8500_INT_ACC_DETECT_22DB_F, - .end = AB8500_INT_ACC_DETECT_22DB_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ACC_DETECT_22DB_R", - .start = AB8500_INT_ACC_DETECT_22DB_R, - .end = AB8500_INT_ACC_DETECT_22DB_R, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource ab8500_charger_resources[] = { - { - .name = "MAIN_CH_UNPLUG_DET", - .start = AB8500_INT_MAIN_CH_UNPLUG_DET, - .end = AB8500_INT_MAIN_CH_UNPLUG_DET, - .flags = IORESOURCE_IRQ, - }, - { - .name = "MAIN_CHARGE_PLUG_DET", - .start = AB8500_INT_MAIN_CH_PLUG_DET, - .end = AB8500_INT_MAIN_CH_PLUG_DET, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_DET_R", - .start = AB8500_INT_VBUS_DET_R, - .end = AB8500_INT_VBUS_DET_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_DET_F", - .start = AB8500_INT_VBUS_DET_F, - .end = AB8500_INT_VBUS_DET_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_LINK_STATUS", - .start = AB8500_INT_USB_LINK_STATUS, - .end = AB8500_INT_USB_LINK_STATUS, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_OVV", - .start = AB8500_INT_VBUS_OVV, - .end = AB8500_INT_VBUS_OVV, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_CH_TH_PROT_R", - .start = AB8500_INT_USB_CH_TH_PROT_R, - .end = AB8500_INT_USB_CH_TH_PROT_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_CH_TH_PROT_F", - .start = AB8500_INT_USB_CH_TH_PROT_F, - .end = AB8500_INT_USB_CH_TH_PROT_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "MAIN_EXT_CH_NOT_OK", - .start = AB8500_INT_MAIN_EXT_CH_NOT_OK, - .end = AB8500_INT_MAIN_EXT_CH_NOT_OK, - .flags = IORESOURCE_IRQ, - }, - { - .name = "MAIN_CH_TH_PROT_R", - .start = AB8500_INT_MAIN_CH_TH_PROT_R, - .end = AB8500_INT_MAIN_CH_TH_PROT_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "MAIN_CH_TH_PROT_F", - .start = AB8500_INT_MAIN_CH_TH_PROT_F, - .end = AB8500_INT_MAIN_CH_TH_PROT_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_CHARGER_NOT_OKR", - .start = AB8500_INT_USB_CHARGER_NOT_OKR, - .end = AB8500_INT_USB_CHARGER_NOT_OKR, - .flags = IORESOURCE_IRQ, - }, - { - .name = "CH_WD_EXP", - .start = AB8500_INT_CH_WD_EXP, - .end = AB8500_INT_CH_WD_EXP, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_CH_DROP_END", - .start = AB8500_INT_VBUS_CH_DROP_END, - .end = AB8500_INT_VBUS_CH_DROP_END, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource ab8500_btemp_resources[] = { - { - .name = "BAT_CTRL_INDB", - .start = AB8500_INT_BAT_CTRL_INDB, - .end = AB8500_INT_BAT_CTRL_INDB, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BTEMP_LOW", - .start = AB8500_INT_BTEMP_LOW, - .end = AB8500_INT_BTEMP_LOW, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BTEMP_HIGH", - .start = AB8500_INT_BTEMP_HIGH, - .end = AB8500_INT_BTEMP_HIGH, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BTEMP_LOW_MEDIUM", - .start = AB8500_INT_BTEMP_LOW_MEDIUM, - .end = AB8500_INT_BTEMP_LOW_MEDIUM, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BTEMP_MEDIUM_HIGH", - .start = AB8500_INT_BTEMP_MEDIUM_HIGH, - .end = AB8500_INT_BTEMP_MEDIUM_HIGH, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource ab8500_fg_resources[] = { - { - .name = "NCONV_ACCU", - .start = AB8500_INT_CCN_CONV_ACC, - .end = AB8500_INT_CCN_CONV_ACC, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BATT_OVV", - .start = AB8500_INT_BATT_OVV, - .end = AB8500_INT_BATT_OVV, - .flags = IORESOURCE_IRQ, - }, - { - .name = "LOW_BAT_F", - .start = AB8500_INT_LOW_BAT_F, - .end = AB8500_INT_LOW_BAT_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "LOW_BAT_R", - .start = AB8500_INT_LOW_BAT_R, - .end = AB8500_INT_LOW_BAT_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "CC_INT_CALIB", - .start = AB8500_INT_CC_INT_CALIB, - .end = AB8500_INT_CC_INT_CALIB, - .flags = IORESOURCE_IRQ, - }, - { - .name = "CCEOC", - .start = AB8500_INT_CCEOC, - .end = AB8500_INT_CCEOC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource ab8500_chargalg_resources[] = {}; - -#ifdef CONFIG_DEBUG_FS -static struct resource ab8500_debug_resources[] = { - { - .name = "IRQ_AB8500", - /* - * Number will be filled in. NOTE: this is deliberately - * not flagged as an IRQ in ordet to avoid remapping using - * the irqdomain in the MFD core, so that this IRQ passes - * unremapped to the debug code. - */ - }, - { - .name = "IRQ_FIRST", - .start = AB8500_INT_MAIN_EXT_CH_NOT_OK, - .end = AB8500_INT_MAIN_EXT_CH_NOT_OK, - .flags = IORESOURCE_IRQ, - }, - { - .name = "IRQ_LAST", - .start = AB8500_INT_XTAL32K_KO, - .end = AB8500_INT_XTAL32K_KO, - .flags = IORESOURCE_IRQ, - }, -}; -#endif - -static struct resource ab8500_usb_resources[] = { - { - .name = "ID_WAKEUP_R", - .start = AB8500_INT_ID_WAKEUP_R, - .end = AB8500_INT_ID_WAKEUP_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ID_WAKEUP_F", - .start = AB8500_INT_ID_WAKEUP_F, - .end = AB8500_INT_ID_WAKEUP_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_DET_F", - .start = AB8500_INT_VBUS_DET_F, - .end = AB8500_INT_VBUS_DET_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_DET_R", - .start = AB8500_INT_VBUS_DET_R, - .end = AB8500_INT_VBUS_DET_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_LINK_STATUS", - .start = AB8500_INT_USB_LINK_STATUS, - .end = AB8500_INT_USB_LINK_STATUS, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_ADP_PROBE_PLUG", - .start = AB8500_INT_ADP_PROBE_PLUG, - .end = AB8500_INT_ADP_PROBE_PLUG, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_ADP_PROBE_UNPLUG", - .start = AB8500_INT_ADP_PROBE_UNPLUG, - .end = AB8500_INT_ADP_PROBE_UNPLUG, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource ab8505_iddet_resources[] = { - { - .name = "KeyDeglitch", - .start = AB8505_INT_KEYDEGLITCH, - .end = AB8505_INT_KEYDEGLITCH, - .flags = IORESOURCE_IRQ, - }, - { - .name = "KP", - .start = AB8505_INT_KP, - .end = AB8505_INT_KP, - .flags = IORESOURCE_IRQ, - }, - { - .name = "IKP", - .start = AB8505_INT_IKP, - .end = AB8505_INT_IKP, - .flags = IORESOURCE_IRQ, - }, - { - .name = "IKR", - .start = AB8505_INT_IKR, - .end = AB8505_INT_IKR, - .flags = IORESOURCE_IRQ, - }, - { - .name = "KeyStuck", - .start = AB8505_INT_KEYSTUCK, - .end = AB8505_INT_KEYSTUCK, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_DET_R", - .start = AB8500_INT_VBUS_DET_R, - .end = AB8500_INT_VBUS_DET_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_DET_F", - .start = AB8500_INT_VBUS_DET_F, - .end = AB8500_INT_VBUS_DET_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ID_DET_PLUGR", - .start = AB8500_INT_ID_DET_PLUGR, - .end = AB8500_INT_ID_DET_PLUGR, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ID_DET_PLUGF", - .start = AB8500_INT_ID_DET_PLUGF, - .end = AB8500_INT_ID_DET_PLUGF, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource ab8500_temp_resources[] = { - { - .name = "ABX500_TEMP_WARM", - .start = AB8500_INT_TEMP_WARM, - .end = AB8500_INT_TEMP_WARM, - .flags = IORESOURCE_IRQ, - }, -}; - static const struct mfd_cell ab8500_bm_devs[] = { { .name = "ab8500-charger", .of_compatible = "stericsson,ab8500-charger", - .num_resources = ARRAY_SIZE(ab8500_charger_resources), - .resources = ab8500_charger_resources, .platform_data = &ab8500_bm_data, .pdata_size = sizeof(ab8500_bm_data), }, { .name = "ab8500-btemp", .of_compatible = "stericsson,ab8500-btemp", - .num_resources = ARRAY_SIZE(ab8500_btemp_resources), - .resources = ab8500_btemp_resources, .platform_data = &ab8500_bm_data, .pdata_size = sizeof(ab8500_bm_data), }, { .name = "ab8500-fg", .of_compatible = "stericsson,ab8500-fg", - .num_resources = ARRAY_SIZE(ab8500_fg_resources), - .resources = ab8500_fg_resources, .platform_data = &ab8500_bm_data, .pdata_size = sizeof(ab8500_bm_data), }, { .name = "ab8500-chargalg", .of_compatible = "stericsson,ab8500-chargalg", - .num_resources = ARRAY_SIZE(ab8500_chargalg_resources), - .resources = ab8500_chargalg_resources, .platform_data = &ab8500_bm_data, .pdata_size = sizeof(ab8500_bm_data), }, @@ -1055,8 +641,6 @@ static const struct mfd_cell ab8500_devs[] = { { .name = "ab8500-debug", .of_compatible = "stericsson,ab8500-debug", - .num_resources = ARRAY_SIZE(ab8500_debug_resources), - .resources = ab8500_debug_resources, }, #endif { @@ -1078,27 +662,19 @@ static const struct mfd_cell ab8500_devs[] = { { .name = "ab8500-gpadc", .of_compatible = "stericsson,ab8500-gpadc", - .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), - .resources = ab8500_gpadc_resources, }, { .name = "ab8500-rtc", .of_compatible = "stericsson,ab8500-rtc", - .num_resources = ARRAY_SIZE(ab8500_rtc_resources), - .resources = ab8500_rtc_resources, }, { .name = "ab8500-acc-det", .of_compatible = "stericsson,ab8500-acc-det", - .num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources), - .resources = ab8500_av_acc_detect_resources, }, { .name = "ab8500-poweron-key", .of_compatible = "stericsson,ab8500-poweron-key", - .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), - .resources = ab8500_poweronkey_db_resources, }, { .name = "ab8500-pwm", @@ -1126,14 +702,10 @@ static const struct mfd_cell ab8500_devs[] = { { .name = "abx500-temp", .of_compatible = "stericsson,abx500-temp", - .num_resources = ARRAY_SIZE(ab8500_temp_resources), - .resources = ab8500_temp_resources, }, { .name = "ab8500-usb", .of_compatible = "stericsson,ab8500-usb", - .num_resources = ARRAY_SIZE(ab8500_usb_resources), - .resources = ab8500_usb_resources, }, { .name = "ab8500-codec", @@ -1145,8 +717,6 @@ static const struct mfd_cell ab9540_devs[] = { #ifdef CONFIG_DEBUG_FS { .name = "ab8500-debug", - .num_resources = ARRAY_SIZE(ab8500_debug_resources), - .resources = ab8500_debug_resources, }, #endif { @@ -1165,23 +735,15 @@ static const struct mfd_cell ab9540_devs[] = { { .name = "ab8500-gpadc", .of_compatible = "stericsson,ab8500-gpadc", - .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), - .resources = ab8500_gpadc_resources, }, { .name = "ab8500-rtc", - .num_resources = ARRAY_SIZE(ab8500_rtc_resources), - .resources = ab8500_rtc_resources, }, { .name = "ab8500-acc-det", - .num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources), - .resources = ab8500_av_acc_detect_resources, }, { .name = "ab8500-poweron-key", - .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), - .resources = ab8500_poweronkey_db_resources, }, { .name = "ab8500-pwm", @@ -1189,8 +751,6 @@ static const struct mfd_cell ab9540_devs[] = { }, { .name = "abx500-temp", - .num_resources = ARRAY_SIZE(ab8500_temp_resources), - .resources = ab8500_temp_resources, }, { .name = "pinctrl-ab9540", @@ -1198,16 +758,12 @@ static const struct mfd_cell ab9540_devs[] = { }, { .name = "ab9540-usb", - .num_resources = ARRAY_SIZE(ab8500_usb_resources), - .resources = ab8500_usb_resources, }, { .name = "ab9540-codec", }, { .name = "ab-iddet", - .num_resources = ARRAY_SIZE(ab8505_iddet_resources), - .resources = ab8505_iddet_resources, }, }; @@ -1216,8 +772,6 @@ static const struct mfd_cell ab8505_devs[] = { #ifdef CONFIG_DEBUG_FS { .name = "ab8500-debug", - .num_resources = ARRAY_SIZE(ab8500_debug_resources), - .resources = ab8500_debug_resources, }, #endif { @@ -1233,23 +787,15 @@ static const struct mfd_cell ab8505_devs[] = { { .name = "ab8500-gpadc", .of_compatible = "stericsson,ab8500-gpadc", - .num_resources = ARRAY_SIZE(ab8505_gpadc_resources), - .resources = ab8505_gpadc_resources, }, { .name = "ab8500-rtc", - .num_resources = ARRAY_SIZE(ab8500_rtc_resources), - .resources = ab8500_rtc_resources, }, { .name = "ab8500-acc-det", - .num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources), - .resources = ab8500_av_acc_detect_resources, }, { .name = "ab8500-poweron-key", - .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), - .resources = ab8500_poweronkey_db_resources, }, { .name = "ab8500-pwm", @@ -1260,16 +806,12 @@ static const struct mfd_cell ab8505_devs[] = { }, { .name = "ab8500-usb", - .num_resources = ARRAY_SIZE(ab8500_usb_resources), - .resources = ab8500_usb_resources, }, { .name = "ab8500-codec", }, { .name = "ab-iddet", - .num_resources = ARRAY_SIZE(ab8505_iddet_resources), - .resources = ab8505_iddet_resources, }, }; @@ -1277,8 +819,6 @@ static const struct mfd_cell ab8540_devs[] = { #ifdef CONFIG_DEBUG_FS { .name = "ab8500-debug", - .num_resources = ARRAY_SIZE(ab8500_debug_resources), - .resources = ab8500_debug_resources, }, #endif { @@ -1297,18 +837,12 @@ static const struct mfd_cell ab8540_devs[] = { { .name = "ab8500-gpadc", .of_compatible = "stericsson,ab8500-gpadc", - .num_resources = ARRAY_SIZE(ab8505_gpadc_resources), - .resources = ab8505_gpadc_resources, }, { .name = "ab8500-acc-det", - .num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources), - .resources = ab8500_av_acc_detect_resources, }, { .name = "ab8500-poweron-key", - .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), - .resources = ab8500_poweronkey_db_resources, }, { .name = "ab8500-pwm", @@ -1316,24 +850,18 @@ static const struct mfd_cell ab8540_devs[] = { }, { .name = "abx500-temp", - .num_resources = ARRAY_SIZE(ab8500_temp_resources), - .resources = ab8500_temp_resources, }, { .name = "pinctrl-ab8540", }, { .name = "ab8540-usb", - .num_resources = ARRAY_SIZE(ab8500_usb_resources), - .resources = ab8500_usb_resources, }, { .name = "ab8540-codec", }, { .name = "ab-iddet", - .num_resources = ARRAY_SIZE(ab8505_iddet_resources), - .resources = ab8505_iddet_resources, }, }; @@ -1341,8 +869,6 @@ static const struct mfd_cell ab8540_cut1_devs[] = { { .name = "ab8500-rtc", .of_compatible = "stericsson,ab8500-rtc", - .num_resources = ARRAY_SIZE(ab8500_rtc_resources), - .resources = ab8500_rtc_resources, }, }; @@ -1350,8 +876,6 @@ static const struct mfd_cell ab8540_cut2_devs[] = { { .name = "ab8540-rtc", .of_compatible = "stericsson,ab8540-rtc", - .num_resources = ARRAY_SIZE(ab8540_rtc_resources), - .resources = ab8540_rtc_resources, }, }; @@ -1750,12 +1274,6 @@ static int ab8500_probe(struct platform_device *pdev) if (ret) return ret; -#ifdef CONFIG_DEBUG_FS - /* Pass to debugfs */ - ab8500_debug_resources[0].start = ab8500->irq; - ab8500_debug_resources[0].end = ab8500->irq; -#endif - if (is_ab9540(ab8500)) ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, ARRAY_SIZE(ab9540_devs), NULL, -- GitLab From cf1199f792da92dabfd5dfb2bd2211b5d191da45 Mon Sep 17 00:00:00 2001 From: LABBE Corentin Date: Thu, 12 Nov 2015 08:49:59 +0100 Subject: [PATCH 0914/2855] mfd: qcom_rpm: Fix a possible NULL dereference of_match_device could return NULL, and so cause a NULL pointer dereference later. Signed-off-by: LABBE Corentin Signed-off-by: Lee Jones --- drivers/mfd/qcom_rpm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mfd/qcom_rpm.c b/drivers/mfd/qcom_rpm.c index 207a3bd685597..1be47ad6441bf 100644 --- a/drivers/mfd/qcom_rpm.c +++ b/drivers/mfd/qcom_rpm.c @@ -495,6 +495,8 @@ static int qcom_rpm_probe(struct platform_device *pdev) } match = of_match_device(qcom_rpm_of_match, &pdev->dev); + if (!match) + return -ENODEV; rpm->data = match->data; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- GitLab From 9a65a6d3cbeeb4429b3bdff6404fca0b98fb8222 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Tue, 3 Nov 2015 15:08:33 +0000 Subject: [PATCH 0915/2855] mfd: arizona: Update DT bindings to add CS47L24 and WM1831 This updates the Arizona MFD device tree bindings to add the Cirrus Logic CS47L24 and WM1831 codecs. Note that unlike all the other codecs the DCVDD-supply and MICVDD-supply are mandatory. Signed-off-by: Richard Fitzgerald Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/arizona.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt b/Documentation/devicetree/bindings/mfd/arizona.txt index 2c5d0387fe98c..2b6ccdb32bd91 100644 --- a/Documentation/devicetree/bindings/mfd/arizona.txt +++ b/Documentation/devicetree/bindings/mfd/arizona.txt @@ -1,4 +1,4 @@ -Wolfson Arizona class audio SoCs +Cirrus Logic/Wolfson Microelectronics Arizona class audio SoCs These devices are audio SoCs with extensive digital capabilites and a range of analogue I/O. @@ -6,12 +6,14 @@ of analogue I/O. Required properties: - compatible : One of the following chip-specific strings: + "cirrus,cs47l24" "wlf,wm5102" "wlf,wm5110" "wlf,wm8280" "wlf,wm8997" "wlf,wm8998" "wlf,wm1814" + "wlf,wm1831" - reg : I2C slave address when connected using I2C, chip select number when using SPI. @@ -41,6 +43,10 @@ Required properties: - SPKVDD-supply : Speaker driver power supply (wm8997) + - DCVDD-supply : Main power supply (cs47l24, wm1831) + + - MICVDD-supply : Microphone power supply (cs47l24, wm1831) + Optional properties: - wlf,reset : GPIO specifier for the GPIO controlling /RESET @@ -69,6 +75,7 @@ Optional properties: - DCVDD-supply, MICVDD-supply : Power supplies, only need to be specified if they are being externally supplied. As covered in Documentation/devicetree/bindings/regulator/regulator.txt + (wm5102, wm5110, wm8280, wm8997, wm8998, wm1814) Also see child specific device properties: Regulator - ../regulator/arizona-regulator.txt -- GitLab From ea1f3339909d8973b41f09ef7275d7e49974b910 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Tue, 3 Nov 2015 15:08:32 +0000 Subject: [PATCH 0916/2855] mfd: arizona: Support Cirrus Logic CS47L24 and WM1831 This patch adds the regmap configuration tables and core MFD handling for the CS47L24 and WM1831 codecs. Note that compared to the other Arizona codecs, these devices do not have an LDO1 or micsupp regulators, extcon driver, or the DCVDD isolation control. Signed-off-by: Richard Fitzgerald Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 18 +- drivers/mfd/Makefile | 3 + drivers/mfd/arizona-core.c | 74 +- drivers/mfd/arizona-irq.c | 40 +- drivers/mfd/arizona-spi.c | 7 + drivers/mfd/arizona.h | 4 + drivers/mfd/cs47l24-tables.c | 1629 ++++++++++++++++++++++++++++++ include/linux/mfd/arizona/core.h | 3 + 8 files changed, 1753 insertions(+), 25 deletions(-) create mode 100644 drivers/mfd/cs47l24-tables.c diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 4d92df6ef9fe9..9581ebbfb4a09 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1370,24 +1370,30 @@ config MFD_ARIZONA bool config MFD_ARIZONA_I2C - tristate "Wolfson Microelectronics Arizona platform with I2C" + tristate "Cirrus Logic/Wolfson Microelectronics Arizona platform with I2C" select MFD_ARIZONA select MFD_CORE select REGMAP_I2C depends on I2C help - Support for the Wolfson Microelectronics Arizona platform audio SoC - core functionality controlled via I2C. + Support for the Cirrus Logic/Wolfson Microelectronics Arizona platform + audio SoC core functionality controlled via I2C. config MFD_ARIZONA_SPI - tristate "Wolfson Microelectronics Arizona platform with SPI" + tristate "Cirrus Logic/Wolfson Microelectronics Arizona platform with SPI" select MFD_ARIZONA select MFD_CORE select REGMAP_SPI depends on SPI_MASTER help - Support for the Wolfson Microelectronics Arizona platform audio SoC - core functionality controlled via I2C. + Support for the Cirrus Logic/Wolfson Microelectronics Arizona platform + audio SoC core functionality controlled via I2C. + +config MFD_CS47L24 + bool "Cirrus Logic CS47L24 and WM1831" + depends on MFD_ARIZONA + help + Support for Cirrus Logic CS47L24 and WM1831 low power audio SoC config MFD_WM5102 bool "Wolfson Microelectronics WM5102" diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 99f93ab26348b..0f230a6103f86 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -51,6 +51,9 @@ endif ifeq ($(CONFIG_MFD_WM8998),y) obj-$(CONFIG_MFD_ARIZONA) += wm8998-tables.o endif +ifeq ($(CONFIG_MFD_CS47L24),y) +obj-$(CONFIG_MFD_ARIZONA) += cs47l24-tables.o +endif obj-$(CONFIG_MFD_WM8400) += wm8400-core.o wm831x-objs := wm831x-core.o wm831x-irq.o wm831x-otp.o wm831x-objs += wm831x-auxadc.o diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index d474732cc65c8..b9489a0d7fabe 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -598,6 +598,12 @@ static int arizona_runtime_resume(struct device *dev) goto err; } break; + case WM1831: + case CS47L24: + ret = arizona_wait_for_boot(arizona); + if (ret != 0) + goto err; + break; default: ret = arizona_wait_for_boot(arizona); if (ret != 0) @@ -682,6 +688,9 @@ static int arizona_runtime_suspend(struct device *dev) } } break; + case WM1831: + case CS47L24: + break; default: jd_active = arizona_is_jack_det_active(arizona); if (jd_active < 0) @@ -862,6 +871,8 @@ const struct of_device_id arizona_of_match[] = { { .compatible = "wlf,wm8997", .data = (void *)WM8997 }, { .compatible = "wlf,wm8998", .data = (void *)WM8998 }, { .compatible = "wlf,wm1814", .data = (void *)WM1814 }, + { .compatible = "wlf,wm1831", .data = (void *)WM1831 }, + { .compatible = "cirrus,cs47l24", .data = (void *)CS47L24 }, {}, }; EXPORT_SYMBOL_GPL(arizona_of_match); @@ -919,6 +930,23 @@ static const struct mfd_cell wm5110_devs[] = { }, }; +static const char * const cs47l24_supplies[] = { + "MICVDD", + "CPVDD", + "SPKVDD", +}; + +static const struct mfd_cell cs47l24_devs[] = { + { .name = "arizona-gpio" }, + { .name = "arizona-haptics" }, + { .name = "arizona-pwm" }, + { + .name = "cs47l24-codec", + .parent_supplies = cs47l24_supplies, + .num_parent_supplies = ARRAY_SIZE(cs47l24_supplies), + }, +}; + static const char * const wm8997_supplies[] = { "MICVDD", "DBVDD2", @@ -963,7 +991,7 @@ static const struct mfd_cell wm8998_devs[] = { int arizona_dev_init(struct arizona *arizona) { struct device *dev = arizona->dev; - const char *type_name; + const char *type_name = NULL; unsigned int reg, val, mask; int (*apply_patch)(struct arizona *) = NULL; const struct mfd_cell *subdevs = NULL; @@ -987,6 +1015,8 @@ int arizona_dev_init(struct arizona *arizona) case WM8997: case WM8998: case WM1814: + case WM1831: + case CS47L24: for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++) arizona->core_supplies[i].supply = wm5102_core_supplies[i]; @@ -1001,11 +1031,18 @@ int arizona_dev_init(struct arizona *arizona) /* Mark DCVDD as external, LDO1 driver will clear if internal */ arizona->external_dcvdd = true; - ret = mfd_add_devices(arizona->dev, -1, early_devs, - ARRAY_SIZE(early_devs), NULL, 0, NULL); - if (ret != 0) { - dev_err(dev, "Failed to add early children: %d\n", ret); - return ret; + switch (arizona->type) { + case WM1831: + case CS47L24: + break; /* No LDO1 regulator */ + default: + ret = mfd_add_devices(arizona->dev, -1, early_devs, + ARRAY_SIZE(early_devs), NULL, 0, NULL); + if (ret != 0) { + dev_err(dev, "Failed to add early children: %d\n", ret); + return ret; + } + break; } ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies, @@ -1069,6 +1106,7 @@ int arizona_dev_init(struct arizona *arizona) case 0x5102: case 0x5110: case 0x6349: + case 0x6363: case 0x8997: break; default: @@ -1167,6 +1205,30 @@ int arizona_dev_init(struct arizona *arizona) n_subdevs = ARRAY_SIZE(wm5110_devs); } break; + case 0x6363: + if (IS_ENABLED(CONFIG_MFD_CS47L24)) { + switch (arizona->type) { + case CS47L24: + type_name = "CS47L24"; + break; + + case WM1831: + type_name = "WM1831"; + break; + + default: + dev_warn(arizona->dev, + "CS47L24 registered as %d\n", + arizona->type); + arizona->type = CS47L24; + break; + } + + apply_patch = cs47l24_patch; + subdevs = cs47l24_devs; + n_subdevs = ARRAY_SIZE(cs47l24_devs); + } + break; case 0x8997: if (IS_ENABLED(CONFIG_MFD_WM8997)) { type_name = "WM8997"; diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c index 3d425e93ce845..682bc865fa8ba 100644 --- a/drivers/mfd/arizona-irq.c +++ b/drivers/mfd/arizona-irq.c @@ -30,11 +30,13 @@ static int arizona_map_irq(struct arizona *arizona, int irq) { int ret; - ret = regmap_irq_get_virq(arizona->aod_irq_chip, irq); - if (ret < 0) - ret = regmap_irq_get_virq(arizona->irq_chip, irq); + if (arizona->aod_irq_chip) { + ret = regmap_irq_get_virq(arizona->aod_irq_chip, irq); + if (ret >= 0) + return ret; + } - return ret; + return regmap_irq_get_virq(arizona->irq_chip, irq); } int arizona_request_irq(struct arizona *arizona, int irq, char *name, @@ -107,8 +109,8 @@ static irqreturn_t arizona_irq_thread(int irq, void *data) do { poll = false; - /* Always handle the AoD domain */ - handle_nested_irq(irq_find_mapping(arizona->virq, 0)); + if (arizona->aod_irq_chip) + handle_nested_irq(irq_find_mapping(arizona->virq, 0)); /* * Check if one of the main interrupts is asserted and only @@ -219,6 +221,15 @@ int arizona_irq_init(struct arizona *arizona) arizona->ctrlif_error = false; break; #endif +#ifdef CONFIG_MFD_CS47L24 + case WM1831: + case CS47L24: + aod = NULL; + irq = &cs47l24_irq; + + arizona->ctrlif_error = false; + break; +#endif #ifdef CONFIG_MFD_WM8997 case WM8997: aod = &wm8997_aod; @@ -291,13 +302,16 @@ int arizona_irq_init(struct arizona *arizona) goto err; } - ret = regmap_add_irq_chip(arizona->regmap, - irq_create_mapping(arizona->virq, 0), - IRQF_ONESHOT, 0, aod, - &arizona->aod_irq_chip); - if (ret != 0) { - dev_err(arizona->dev, "Failed to add AOD IRQs: %d\n", ret); - goto err_domain; + if (aod) { + ret = regmap_add_irq_chip(arizona->regmap, + irq_create_mapping(arizona->virq, 0), + IRQF_ONESHOT, 0, aod, + &arizona->aod_irq_chip); + if (ret != 0) { + dev_err(arizona->dev, + "Failed to add AOD IRQs: %d\n", ret); + goto err_domain; + } } ret = regmap_add_irq_chip(arizona->regmap, diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c index befbc89bfd345..5c1ccdeb9b706 100644 --- a/drivers/mfd/arizona-spi.c +++ b/drivers/mfd/arizona-spi.c @@ -46,6 +46,11 @@ static int arizona_spi_probe(struct spi_device *spi) if (IS_ENABLED(CONFIG_MFD_WM5110)) regmap_config = &wm5110_spi_regmap; break; + case WM1831: + case CS47L24: + if (IS_ENABLED(CONFIG_MFD_CS47L24)) + regmap_config = &cs47l24_spi_regmap; + break; default: dev_err(&spi->dev, "Unknown device type %ld\n", type); return -EINVAL; @@ -89,6 +94,8 @@ static const struct spi_device_id arizona_spi_ids[] = { { "wm5102", WM5102 }, { "wm5110", WM5110 }, { "wm8280", WM8280 }, + { "wm1831", WM1831 }, + { "cs47l24", CS47L24 }, { }, }; MODULE_DEVICE_TABLE(spi, arizona_spi_ids); diff --git a/drivers/mfd/arizona.h b/drivers/mfd/arizona.h index 3af12e938f578..198e9cea77f9c 100644 --- a/drivers/mfd/arizona.h +++ b/drivers/mfd/arizona.h @@ -25,6 +25,8 @@ extern const struct regmap_config wm5102_spi_regmap; extern const struct regmap_config wm5110_i2c_regmap; extern const struct regmap_config wm5110_spi_regmap; +extern const struct regmap_config cs47l24_spi_regmap; + extern const struct regmap_config wm8997_i2c_regmap; extern const struct regmap_config wm8998_i2c_regmap; @@ -40,6 +42,8 @@ extern const struct regmap_irq_chip wm5110_aod; extern const struct regmap_irq_chip wm5110_irq; extern const struct regmap_irq_chip wm5110_revd_irq; +extern const struct regmap_irq_chip cs47l24_irq; + extern const struct regmap_irq_chip wm8997_aod; extern const struct regmap_irq_chip wm8997_irq; diff --git a/drivers/mfd/cs47l24-tables.c b/drivers/mfd/cs47l24-tables.c new file mode 100644 index 0000000000000..8708006575943 --- /dev/null +++ b/drivers/mfd/cs47l24-tables.c @@ -0,0 +1,1629 @@ +/* + * Data tables for CS47L24 codec + * + * Copyright 2015 Cirrus Logic, Inc. + * + * Author: Richard Fitzgerald + * + * 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. + */ + +#include + +#include +#include +#include + +#include "arizona.h" + +#define CS47L24_NUM_ISR 5 + +static const struct reg_sequence cs47l24_reva_patch[] = { + { 0x80, 0x3 }, + { 0x27C, 0x0010 }, + { 0x221, 0x0070 }, + { 0x80, 0x0 }, +}; + +int cs47l24_patch(struct arizona *arizona) +{ + return regmap_register_patch(arizona->regmap, + cs47l24_reva_patch, + ARRAY_SIZE(cs47l24_reva_patch)); +} +EXPORT_SYMBOL_GPL(cs47l24_patch); + +static const struct regmap_irq cs47l24_irqs[ARIZONA_NUM_IRQ] = { + [ARIZONA_IRQ_GP2] = { .reg_offset = 0, .mask = ARIZONA_GP2_EINT1 }, + [ARIZONA_IRQ_GP1] = { .reg_offset = 0, .mask = ARIZONA_GP1_EINT1 }, + + [ARIZONA_IRQ_DSP3_RAM_RDY] = { + .reg_offset = 1, .mask = ARIZONA_DSP3_RAM_RDY_EINT1 + }, + [ARIZONA_IRQ_DSP2_RAM_RDY] = { + .reg_offset = 1, .mask = ARIZONA_DSP2_RAM_RDY_EINT1 + }, + [ARIZONA_IRQ_DSP_IRQ8] = { + .reg_offset = 1, .mask = ARIZONA_DSP_IRQ8_EINT1 + }, + [ARIZONA_IRQ_DSP_IRQ7] = { + .reg_offset = 1, .mask = ARIZONA_DSP_IRQ7_EINT1 + }, + [ARIZONA_IRQ_DSP_IRQ6] = { + .reg_offset = 1, .mask = ARIZONA_DSP_IRQ6_EINT1 + }, + [ARIZONA_IRQ_DSP_IRQ5] = { + .reg_offset = 1, .mask = ARIZONA_DSP_IRQ5_EINT1 + }, + [ARIZONA_IRQ_DSP_IRQ4] = { + .reg_offset = 1, .mask = ARIZONA_DSP_IRQ4_EINT1 + }, + [ARIZONA_IRQ_DSP_IRQ3] = { + .reg_offset = 1, .mask = ARIZONA_DSP_IRQ3_EINT1 + }, + [ARIZONA_IRQ_DSP_IRQ2] = { + .reg_offset = 1, .mask = ARIZONA_DSP_IRQ2_EINT1 + }, + [ARIZONA_IRQ_DSP_IRQ1] = { + .reg_offset = 1, .mask = ARIZONA_DSP_IRQ1_EINT1 + }, + + [ARIZONA_IRQ_SPK_OVERHEAT_WARN] = { + .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_WARN_EINT1 + }, + [ARIZONA_IRQ_SPK_OVERHEAT] = { + .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_EINT1 + }, + [ARIZONA_IRQ_WSEQ_DONE] = { + .reg_offset = 2, .mask = ARIZONA_WSEQ_DONE_EINT1 + }, + [ARIZONA_IRQ_DRC2_SIG_DET] = { + .reg_offset = 2, .mask = ARIZONA_DRC2_SIG_DET_EINT1 + }, + [ARIZONA_IRQ_DRC1_SIG_DET] = { + .reg_offset = 2, .mask = ARIZONA_DRC1_SIG_DET_EINT1 + }, + [ARIZONA_IRQ_ASRC2_LOCK] = { + .reg_offset = 2, .mask = ARIZONA_ASRC2_LOCK_EINT1 + }, + [ARIZONA_IRQ_ASRC1_LOCK] = { + .reg_offset = 2, .mask = ARIZONA_ASRC1_LOCK_EINT1 + }, + [ARIZONA_IRQ_UNDERCLOCKED] = { + .reg_offset = 2, .mask = ARIZONA_UNDERCLOCKED_EINT1 + }, + [ARIZONA_IRQ_OVERCLOCKED] = { + .reg_offset = 2, .mask = ARIZONA_OVERCLOCKED_EINT1 + }, + [ARIZONA_IRQ_FLL2_LOCK] = { + .reg_offset = 2, .mask = ARIZONA_FLL2_LOCK_EINT1 + }, + [ARIZONA_IRQ_FLL1_LOCK] = { + .reg_offset = 2, .mask = ARIZONA_FLL1_LOCK_EINT1 + }, + [ARIZONA_IRQ_CLKGEN_ERR] = { + .reg_offset = 2, .mask = ARIZONA_CLKGEN_ERR_EINT1 + }, + [ARIZONA_IRQ_CLKGEN_ERR_ASYNC] = { + .reg_offset = 2, .mask = ARIZONA_CLKGEN_ERR_ASYNC_EINT1 + }, + + [ARIZONA_IRQ_CTRLIF_ERR] = { + .reg_offset = 3, .mask = ARIZONA_V2_CTRLIF_ERR_EINT1 + }, + [ARIZONA_IRQ_MIXER_DROPPED_SAMPLES] = { + .reg_offset = 3, .mask = ARIZONA_V2_MIXER_DROPPED_SAMPLE_EINT1 + }, + [ARIZONA_IRQ_ASYNC_CLK_ENA_LOW] = { + .reg_offset = 3, .mask = ARIZONA_V2_ASYNC_CLK_ENA_LOW_EINT1 + }, + [ARIZONA_IRQ_SYSCLK_ENA_LOW] = { + .reg_offset = 3, .mask = ARIZONA_V2_SYSCLK_ENA_LOW_EINT1 + }, + [ARIZONA_IRQ_ISRC1_CFG_ERR] = { + .reg_offset = 3, .mask = ARIZONA_V2_ISRC1_CFG_ERR_EINT1 + }, + [ARIZONA_IRQ_ISRC2_CFG_ERR] = { + .reg_offset = 3, .mask = ARIZONA_V2_ISRC2_CFG_ERR_EINT1 + }, + [ARIZONA_IRQ_ISRC3_CFG_ERR] = { + .reg_offset = 3, .mask = ARIZONA_V2_ISRC3_CFG_ERR_EINT1 + }, + [ARIZONA_IRQ_HP1R_DONE] = { + .reg_offset = 3, .mask = ARIZONA_HP1R_DONE_EINT1 + }, + [ARIZONA_IRQ_HP1L_DONE] = { + .reg_offset = 3, .mask = ARIZONA_HP1L_DONE_EINT1 + }, + + [ARIZONA_IRQ_BOOT_DONE] = { + .reg_offset = 4, .mask = ARIZONA_BOOT_DONE_EINT1 + }, + [ARIZONA_IRQ_ASRC_CFG_ERR] = { + .reg_offset = 4, .mask = ARIZONA_V2_ASRC_CFG_ERR_EINT1 + }, + [ARIZONA_IRQ_FLL2_CLOCK_OK] = { + .reg_offset = 4, .mask = ARIZONA_FLL2_CLOCK_OK_EINT1 + }, + [ARIZONA_IRQ_FLL1_CLOCK_OK] = { + .reg_offset = 4, .mask = ARIZONA_FLL1_CLOCK_OK_EINT1 + }, + + [ARIZONA_IRQ_DSP_SHARED_WR_COLL] = { + .reg_offset = 5, .mask = ARIZONA_DSP_SHARED_WR_COLL_EINT1 + }, + [ARIZONA_IRQ_SPK_SHUTDOWN] = { + .reg_offset = 5, .mask = ARIZONA_SPK_SHUTDOWN_EINT1 + }, + [ARIZONA_IRQ_SPK1R_SHORT] = { + .reg_offset = 5, .mask = ARIZONA_SPK1R_SHORT_EINT1 + }, + [ARIZONA_IRQ_SPK1L_SHORT] = { + .reg_offset = 5, .mask = ARIZONA_SPK1L_SHORT_EINT1 + }, + [ARIZONA_IRQ_HP1R_SC_POS] = { + .reg_offset = 5, .mask = ARIZONA_HP1R_SC_POS_EINT1 + }, + [ARIZONA_IRQ_HP1L_SC_POS] = { + .reg_offset = 5, .mask = ARIZONA_HP1L_SC_POS_EINT1 + }, +}; + +const struct regmap_irq_chip cs47l24_irq = { + .name = "cs47l24 IRQ", + .status_base = ARIZONA_INTERRUPT_STATUS_1, + .mask_base = ARIZONA_INTERRUPT_STATUS_1_MASK, + .ack_base = ARIZONA_INTERRUPT_STATUS_1, + .num_regs = 6, + .irqs = cs47l24_irqs, + .num_irqs = ARRAY_SIZE(cs47l24_irqs), +}; +EXPORT_SYMBOL_GPL(cs47l24_irq); + +static const struct reg_default cs47l24_reg_default[] = { + { 0x00000008, 0x0019 }, /* R8 - Ctrl IF SPI CFG 1 */ + { 0x00000020, 0x0000 }, /* R32 - Tone Generator 1 */ + { 0x00000021, 0x1000 }, /* R33 - Tone Generator 2 */ + { 0x00000022, 0x0000 }, /* R34 - Tone Generator 3 */ + { 0x00000023, 0x1000 }, /* R35 - Tone Generator 4 */ + { 0x00000024, 0x0000 }, /* R36 - Tone Generator 5 */ + { 0x00000030, 0x0000 }, /* R48 - PWM Drive 1 */ + { 0x00000031, 0x0100 }, /* R49 - PWM Drive 2 */ + { 0x00000032, 0x0100 }, /* R50 - PWM Drive 3 */ + { 0x00000041, 0x0000 }, /* R65 - Sequence control */ + { 0x00000061, 0x01FF }, /* R97 - Sample Rate Sequence Select 1 */ + { 0x00000062, 0x01FF }, /* R98 - Sample Rate Sequence Select 2 */ + { 0x00000063, 0x01FF }, /* R99 - Sample Rate Sequence Select 3 */ + { 0x00000064, 0x01FF }, /* R100 - Sample Rate Sequence Select 4 */ + { 0x00000070, 0x0000 }, /* R112 - Comfort Noise Generator */ + { 0x00000090, 0x0000 }, /* R144 - Haptics Control 1 */ + { 0x00000091, 0x7FFF }, /* R145 - Haptics Control 2 */ + { 0x00000092, 0x0000 }, /* R146 - Haptics phase 1 intensity */ + { 0x00000093, 0x0000 }, /* R147 - Haptics phase 1 duration */ + { 0x00000094, 0x0000 }, /* R148 - Haptics phase 2 intensity */ + { 0x00000095, 0x0000 }, /* R149 - Haptics phase 2 duration */ + { 0x00000096, 0x0000 }, /* R150 - Haptics phase 3 intensity */ + { 0x00000097, 0x0000 }, /* R151 - Haptics phase 3 duration */ + { 0x00000100, 0x0002 }, /* R256 - Clock 32k 1 */ + { 0x00000101, 0x0504 }, /* R257 - System Clock 1 */ + { 0x00000102, 0x0011 }, /* R258 - Sample rate 1 */ + { 0x00000103, 0x0011 }, /* R259 - Sample rate 2 */ + { 0x00000104, 0x0011 }, /* R260 - Sample rate 3 */ + { 0x00000112, 0x0305 }, /* R274 - Async clock 1 */ + { 0x00000113, 0x0011 }, /* R275 - Async sample rate 1 */ + { 0x00000114, 0x0011 }, /* R276 - Async sample rate 2 */ + { 0x00000149, 0x0000 }, /* R329 - Output system clock */ + { 0x0000014A, 0x0000 }, /* R330 - Output async clock */ + { 0x00000152, 0x0000 }, /* R338 - Rate Estimator 1 */ + { 0x00000153, 0x0000 }, /* R339 - Rate Estimator 2 */ + { 0x00000154, 0x0000 }, /* R340 - Rate Estimator 3 */ + { 0x00000155, 0x0000 }, /* R341 - Rate Estimator 4 */ + { 0x00000156, 0x0000 }, /* R342 - Rate Estimator 5 */ + { 0x00000171, 0x0002 }, /* R369 - FLL1 Control 1 */ + { 0x00000172, 0x0008 }, /* R370 - FLL1 Control 2 */ + { 0x00000173, 0x0018 }, /* R371 - FLL1 Control 3 */ + { 0x00000174, 0x007D }, /* R372 - FLL1 Control 4 */ + { 0x00000175, 0x0006 }, /* R373 - FLL1 Control 5 */ + { 0x00000176, 0x0000 }, /* R374 - FLL1 Control 6 */ + { 0x00000177, 0x0281 }, /* R375 - FLL1 Loop Filter Test 1 */ + { 0x00000178, 0x0000 }, /* R376 - FLL1 NCO Test 0 */ + { 0x00000179, 0x0000 }, /* R376 - FLL1 Control 7 */ + { 0x00000181, 0x0000 }, /* R385 - FLL1 Synchroniser 1 */ + { 0x00000182, 0x0000 }, /* R386 - FLL1 Synchroniser 2 */ + { 0x00000183, 0x0000 }, /* R387 - FLL1 Synchroniser 3 */ + { 0x00000184, 0x0000 }, /* R388 - FLL1 Synchroniser 4 */ + { 0x00000185, 0x0000 }, /* R389 - FLL1 Synchroniser 5 */ + { 0x00000186, 0x0000 }, /* R390 - FLL1 Synchroniser 6 */ + { 0x00000187, 0x0001 }, /* R390 - FLL1 Synchroniser 7 */ + { 0x00000189, 0x0000 }, /* R393 - FLL1 Spread Spectrum */ + { 0x0000018A, 0x000C }, /* R394 - FLL1 GPIO Clock */ + { 0x00000191, 0x0002 }, /* R401 - FLL2 Control 1 */ + { 0x00000192, 0x0008 }, /* R402 - FLL2 Control 2 */ + { 0x00000193, 0x0018 }, /* R403 - FLL2 Control 3 */ + { 0x00000194, 0x007D }, /* R404 - FLL2 Control 4 */ + { 0x00000195, 0x000C }, /* R405 - FLL2 Control 5 */ + { 0x00000196, 0x0000 }, /* R406 - FLL2 Control 6 */ + { 0x00000197, 0x0000 }, /* R407 - FLL2 Loop Filter Test 1 */ + { 0x00000198, 0x0000 }, /* R408 - FLL2 NCO Test 0 */ + { 0x00000199, 0x0000 }, /* R408 - FLL2 Control 7 */ + { 0x000001A1, 0x0000 }, /* R417 - FLL2 Synchroniser 1 */ + { 0x000001A2, 0x0000 }, /* R418 - FLL2 Synchroniser 2 */ + { 0x000001A3, 0x0000 }, /* R419 - FLL2 Synchroniser 3 */ + { 0x000001A4, 0x0000 }, /* R420 - FLL2 Synchroniser 4 */ + { 0x000001A5, 0x0000 }, /* R421 - FLL2 Synchroniser 5 */ + { 0x000001A6, 0x0000 }, /* R422 - FLL2 Synchroniser 6 */ + { 0x000001A7, 0x0001 }, /* R422 - FLL2 Synchroniser 7 */ + { 0x000001A9, 0x0000 }, /* R425 - FLL2 Spread Spectrum */ + { 0x000001AA, 0x000C }, /* R426 - FLL2 GPIO Clock */ + { 0x00000218, 0x00E6 }, /* R536 - Mic Bias Ctrl 1 */ + { 0x00000219, 0x00E6 }, /* R537 - Mic Bias Ctrl 2 */ + { 0x00000300, 0x0000 }, /* R768 - Input Enables */ + { 0x00000308, 0x0000 }, /* R776 - Input Rate */ + { 0x00000309, 0x0022 }, /* R777 - Input Volume Ramp */ + { 0x0000030C, 0x0002 }, /* R780 - HPF Control */ + { 0x00000310, 0x2000 }, /* R784 - IN1L Control */ + { 0x00000311, 0x0180 }, /* R785 - ADC Digital Volume 1L */ + { 0x00000312, 0x0000 }, /* R786 - DMIC1L Control */ + { 0x00000314, 0x0000 }, /* R788 - IN1R Control */ + { 0x00000315, 0x0180 }, /* R789 - ADC Digital Volume 1R */ + { 0x00000316, 0x0000 }, /* R790 - DMIC1R Control */ + { 0x00000318, 0x2000 }, /* R792 - IN2L Control */ + { 0x00000319, 0x0180 }, /* R793 - ADC Digital Volume 2L */ + { 0x0000031A, 0x0000 }, /* R794 - DMIC2L Control */ + { 0x0000031C, 0x0000 }, /* R796 - IN2R Control */ + { 0x0000031D, 0x0180 }, /* R797 - ADC Digital Volume 2R */ + { 0x0000031E, 0x0000 }, /* R798 - DMIC2R Control */ + { 0x00000400, 0x0000 }, /* R1024 - Output Enables 1 */ + { 0x00000408, 0x0000 }, /* R1032 - Output Rate 1 */ + { 0x00000409, 0x0022 }, /* R1033 - Output Volume Ramp */ + { 0x00000410, 0x0080 }, /* R1040 - Output Path Config 1L */ + { 0x00000411, 0x0180 }, /* R1041 - DAC Digital Volume 1L */ + { 0x00000412, 0x0081 }, /* R1042 - DAC Volume Limit 1L */ + { 0x00000413, 0x0001 }, /* R1043 - Noise Gate Select 1L */ + { 0x00000415, 0x0180 }, /* R1045 - DAC Digital Volume 1R */ + { 0x00000416, 0x0081 }, /* R1046 - DAC Volume Limit 1R */ + { 0x00000417, 0x0002 }, /* R1047 - Noise Gate Select 1R */ + { 0x00000429, 0x0180 }, /* R1065 - DAC Digital Volume 4L */ + { 0x0000042A, 0x0081 }, /* R1066 - Out Volume 4L */ + { 0x0000042B, 0x0040 }, /* R1067 - Noise Gate Select 4L */ + { 0x00000450, 0x0000 }, /* R1104 - DAC AEC Control 1 */ + { 0x00000458, 0x0000 }, /* R1112 - Noise Gate Control */ + { 0x000004A0, 0x3480 }, /* R1184 - HP1 Short Circuit Ctrl */ + { 0x00000500, 0x000C }, /* R1280 - AIF1 BCLK Ctrl */ + { 0x00000501, 0x0008 }, /* R1281 - AIF1 Tx Pin Ctrl */ + { 0x00000502, 0x0000 }, /* R1282 - AIF1 Rx Pin Ctrl */ + { 0x00000503, 0x0000 }, /* R1283 - AIF1 Rate Ctrl */ + { 0x00000504, 0x0000 }, /* R1284 - AIF1 Format */ + { 0x00000506, 0x0040 }, /* R1286 - AIF1 Rx BCLK Rate */ + { 0x00000507, 0x1818 }, /* R1287 - AIF1 Frame Ctrl 1 */ + { 0x00000508, 0x1818 }, /* R1288 - AIF1 Frame Ctrl 2 */ + { 0x00000509, 0x0000 }, /* R1289 - AIF1 Frame Ctrl 3 */ + { 0x0000050A, 0x0001 }, /* R1290 - AIF1 Frame Ctrl 4 */ + { 0x0000050B, 0x0002 }, /* R1291 - AIF1 Frame Ctrl 5 */ + { 0x0000050C, 0x0003 }, /* R1292 - AIF1 Frame Ctrl 6 */ + { 0x0000050D, 0x0004 }, /* R1293 - AIF1 Frame Ctrl 7 */ + { 0x0000050E, 0x0005 }, /* R1294 - AIF1 Frame Ctrl 8 */ + { 0x0000050F, 0x0006 }, /* R1295 - AIF1 Frame Ctrl 9 */ + { 0x00000510, 0x0007 }, /* R1296 - AIF1 Frame Ctrl 10 */ + { 0x00000511, 0x0000 }, /* R1297 - AIF1 Frame Ctrl 11 */ + { 0x00000512, 0x0001 }, /* R1298 - AIF1 Frame Ctrl 12 */ + { 0x00000513, 0x0002 }, /* R1299 - AIF1 Frame Ctrl 13 */ + { 0x00000514, 0x0003 }, /* R1300 - AIF1 Frame Ctrl 14 */ + { 0x00000515, 0x0004 }, /* R1301 - AIF1 Frame Ctrl 15 */ + { 0x00000516, 0x0005 }, /* R1302 - AIF1 Frame Ctrl 16 */ + { 0x00000517, 0x0006 }, /* R1303 - AIF1 Frame Ctrl 17 */ + { 0x00000518, 0x0007 }, /* R1304 - AIF1 Frame Ctrl 18 */ + { 0x00000519, 0x0000 }, /* R1305 - AIF1 Tx Enables */ + { 0x0000051A, 0x0000 }, /* R1306 - AIF1 Rx Enables */ + { 0x00000540, 0x000C }, /* R1344 - AIF2 BCLK Ctrl */ + { 0x00000541, 0x0008 }, /* R1345 - AIF2 Tx Pin Ctrl */ + { 0x00000542, 0x0000 }, /* R1346 - AIF2 Rx Pin Ctrl */ + { 0x00000543, 0x0000 }, /* R1347 - AIF2 Rate Ctrl */ + { 0x00000544, 0x0000 }, /* R1348 - AIF2 Format */ + { 0x00000546, 0x0040 }, /* R1350 - AIF2 Rx BCLK Rate */ + { 0x00000547, 0x1818 }, /* R1351 - AIF2 Frame Ctrl 1 */ + { 0x00000548, 0x1818 }, /* R1352 - AIF2 Frame Ctrl 2 */ + { 0x00000549, 0x0000 }, /* R1353 - AIF2 Frame Ctrl 3 */ + { 0x0000054A, 0x0001 }, /* R1354 - AIF2 Frame Ctrl 4 */ + { 0x0000054B, 0x0002 }, /* R1355 - AIF2 Frame Ctrl 5 */ + { 0x0000054C, 0x0003 }, /* R1356 - AIF2 Frame Ctrl 6 */ + { 0x0000054D, 0x0004 }, /* R1357 - AIF2 Frame Ctrl 7 */ + { 0x0000054E, 0x0005 }, /* R1358 - AIF2 Frame Ctrl 8 */ + { 0x00000551, 0x0000 }, /* R1361 - AIF2 Frame Ctrl 11 */ + { 0x00000552, 0x0001 }, /* R1362 - AIF2 Frame Ctrl 12 */ + { 0x00000553, 0x0002 }, /* R1363 - AIF2 Frame Ctrl 13 */ + { 0x00000554, 0x0003 }, /* R1364 - AIF2 Frame Ctrl 14 */ + { 0x00000555, 0x0004 }, /* R1365 - AIF2 Frame Ctrl 15 */ + { 0x00000556, 0x0005 }, /* R1366 - AIF2 Frame Ctrl 16 */ + { 0x00000559, 0x0000 }, /* R1369 - AIF2 Tx Enables */ + { 0x0000055A, 0x0000 }, /* R1370 - AIF2 Rx Enables */ + { 0x00000580, 0x000C }, /* R1408 - AIF3 BCLK Ctrl */ + { 0x00000581, 0x0008 }, /* R1409 - AIF3 Tx Pin Ctrl */ + { 0x00000582, 0x0000 }, /* R1410 - AIF3 Rx Pin Ctrl */ + { 0x00000583, 0x0000 }, /* R1411 - AIF3 Rate Ctrl */ + { 0x00000584, 0x0000 }, /* R1412 - AIF3 Format */ + { 0x00000586, 0x0040 }, /* R1414 - AIF3 Rx BCLK Rate */ + { 0x00000587, 0x1818 }, /* R1415 - AIF3 Frame Ctrl 1 */ + { 0x00000588, 0x1818 }, /* R1416 - AIF3 Frame Ctrl 2 */ + { 0x00000589, 0x0000 }, /* R1417 - AIF3 Frame Ctrl 3 */ + { 0x0000058A, 0x0001 }, /* R1418 - AIF3 Frame Ctrl 4 */ + { 0x00000591, 0x0000 }, /* R1425 - AIF3 Frame Ctrl 11 */ + { 0x00000592, 0x0001 }, /* R1426 - AIF3 Frame Ctrl 12 */ + { 0x00000599, 0x0000 }, /* R1433 - AIF3 Tx Enables */ + { 0x0000059A, 0x0000 }, /* R1434 - AIF3 Rx Enables */ + { 0x00000640, 0x0000 }, /* R1600 - PWM1MIX Input 1 Source */ + { 0x00000641, 0x0080 }, /* R1601 - PWM1MIX Input 1 Volume */ + { 0x00000642, 0x0000 }, /* R1602 - PWM1MIX Input 2 Source */ + { 0x00000643, 0x0080 }, /* R1603 - PWM1MIX Input 2 Volume */ + { 0x00000644, 0x0000 }, /* R1604 - PWM1MIX Input 3 Source */ + { 0x00000645, 0x0080 }, /* R1605 - PWM1MIX Input 3 Volume */ + { 0x00000646, 0x0000 }, /* R1606 - PWM1MIX Input 4 Source */ + { 0x00000647, 0x0080 }, /* R1607 - PWM1MIX Input 4 Volume */ + { 0x00000648, 0x0000 }, /* R1608 - PWM2MIX Input 1 Source */ + { 0x00000649, 0x0080 }, /* R1609 - PWM2MIX Input 1 Volume */ + { 0x0000064A, 0x0000 }, /* R1610 - PWM2MIX Input 2 Source */ + { 0x0000064B, 0x0080 }, /* R1611 - PWM2MIX Input 2 Volume */ + { 0x0000064C, 0x0000 }, /* R1612 - PWM2MIX Input 3 Source */ + { 0x0000064D, 0x0080 }, /* R1613 - PWM2MIX Input 3 Volume */ + { 0x0000064E, 0x0000 }, /* R1614 - PWM2MIX Input 4 Source */ + { 0x0000064F, 0x0080 }, /* R1615 - PWM2MIX Input 4 Volume */ + { 0x00000680, 0x0000 }, /* R1664 - OUT1LMIX Input 1 Source */ + { 0x00000681, 0x0080 }, /* R1665 - OUT1LMIX Input 1 Volume */ + { 0x00000682, 0x0000 }, /* R1666 - OUT1LMIX Input 2 Source */ + { 0x00000683, 0x0080 }, /* R1667 - OUT1LMIX Input 2 Volume */ + { 0x00000684, 0x0000 }, /* R1668 - OUT1LMIX Input 3 Source */ + { 0x00000685, 0x0080 }, /* R1669 - OUT1LMIX Input 3 Volume */ + { 0x00000686, 0x0000 }, /* R1670 - OUT1LMIX Input 4 Source */ + { 0x00000687, 0x0080 }, /* R1671 - OUT1LMIX Input 4 Volume */ + { 0x00000688, 0x0000 }, /* R1672 - OUT1RMIX Input 1 Source */ + { 0x00000689, 0x0080 }, /* R1673 - OUT1RMIX Input 1 Volume */ + { 0x0000068A, 0x0000 }, /* R1674 - OUT1RMIX Input 2 Source */ + { 0x0000068B, 0x0080 }, /* R1675 - OUT1RMIX Input 2 Volume */ + { 0x0000068C, 0x0000 }, /* R1676 - OUT1RMIX Input 3 Source */ + { 0x0000068D, 0x0080 }, /* R1677 - OUT1RMIX Input 3 Volume */ + { 0x0000068E, 0x0000 }, /* R1678 - OUT1RMIX Input 4 Source */ + { 0x0000068F, 0x0080 }, /* R1679 - OUT1RMIX Input 4 Volume */ + { 0x000006B0, 0x0000 }, /* R1712 - OUT4LMIX Input 1 Source */ + { 0x000006B1, 0x0080 }, /* R1713 - OUT4LMIX Input 1 Volume */ + { 0x000006B2, 0x0000 }, /* R1714 - OUT4LMIX Input 2 Source */ + { 0x000006B3, 0x0080 }, /* R1715 - OUT4LMIX Input 2 Volume */ + { 0x000006B4, 0x0000 }, /* R1716 - OUT4LMIX Input 3 Source */ + { 0x000006B5, 0x0080 }, /* R1717 - OUT4LMIX Input 3 Volume */ + { 0x000006B6, 0x0000 }, /* R1718 - OUT4LMIX Input 4 Source */ + { 0x000006B7, 0x0080 }, /* R1719 - OUT4LMIX Input 4 Volume */ + { 0x00000700, 0x0000 }, /* R1792 - AIF1TX1MIX Input 1 Source */ + { 0x00000701, 0x0080 }, /* R1793 - AIF1TX1MIX Input 1 Volume */ + { 0x00000702, 0x0000 }, /* R1794 - AIF1TX1MIX Input 2 Source */ + { 0x00000703, 0x0080 }, /* R1795 - AIF1TX1MIX Input 2 Volume */ + { 0x00000704, 0x0000 }, /* R1796 - AIF1TX1MIX Input 3 Source */ + { 0x00000705, 0x0080 }, /* R1797 - AIF1TX1MIX Input 3 Volume */ + { 0x00000706, 0x0000 }, /* R1798 - AIF1TX1MIX Input 4 Source */ + { 0x00000707, 0x0080 }, /* R1799 - AIF1TX1MIX Input 4 Volume */ + { 0x00000708, 0x0000 }, /* R1800 - AIF1TX2MIX Input 1 Source */ + { 0x00000709, 0x0080 }, /* R1801 - AIF1TX2MIX Input 1 Volume */ + { 0x0000070A, 0x0000 }, /* R1802 - AIF1TX2MIX Input 2 Source */ + { 0x0000070B, 0x0080 }, /* R1803 - AIF1TX2MIX Input 2 Volume */ + { 0x0000070C, 0x0000 }, /* R1804 - AIF1TX2MIX Input 3 Source */ + { 0x0000070D, 0x0080 }, /* R1805 - AIF1TX2MIX Input 3 Volume */ + { 0x0000070E, 0x0000 }, /* R1806 - AIF1TX2MIX Input 4 Source */ + { 0x0000070F, 0x0080 }, /* R1807 - AIF1TX2MIX Input 4 Volume */ + { 0x00000710, 0x0000 }, /* R1808 - AIF1TX3MIX Input 1 Source */ + { 0x00000711, 0x0080 }, /* R1809 - AIF1TX3MIX Input 1 Volume */ + { 0x00000712, 0x0000 }, /* R1810 - AIF1TX3MIX Input 2 Source */ + { 0x00000713, 0x0080 }, /* R1811 - AIF1TX3MIX Input 2 Volume */ + { 0x00000714, 0x0000 }, /* R1812 - AIF1TX3MIX Input 3 Source */ + { 0x00000715, 0x0080 }, /* R1813 - AIF1TX3MIX Input 3 Volume */ + { 0x00000716, 0x0000 }, /* R1814 - AIF1TX3MIX Input 4 Source */ + { 0x00000717, 0x0080 }, /* R1815 - AIF1TX3MIX Input 4 Volume */ + { 0x00000718, 0x0000 }, /* R1816 - AIF1TX4MIX Input 1 Source */ + { 0x00000719, 0x0080 }, /* R1817 - AIF1TX4MIX Input 1 Volume */ + { 0x0000071A, 0x0000 }, /* R1818 - AIF1TX4MIX Input 2 Source */ + { 0x0000071B, 0x0080 }, /* R1819 - AIF1TX4MIX Input 2 Volume */ + { 0x0000071C, 0x0000 }, /* R1820 - AIF1TX4MIX Input 3 Source */ + { 0x0000071D, 0x0080 }, /* R1821 - AIF1TX4MIX Input 3 Volume */ + { 0x0000071E, 0x0000 }, /* R1822 - AIF1TX4MIX Input 4 Source */ + { 0x0000071F, 0x0080 }, /* R1823 - AIF1TX4MIX Input 4 Volume */ + { 0x00000720, 0x0000 }, /* R1824 - AIF1TX5MIX Input 1 Source */ + { 0x00000721, 0x0080 }, /* R1825 - AIF1TX5MIX Input 1 Volume */ + { 0x00000722, 0x0000 }, /* R1826 - AIF1TX5MIX Input 2 Source */ + { 0x00000723, 0x0080 }, /* R1827 - AIF1TX5MIX Input 2 Volume */ + { 0x00000724, 0x0000 }, /* R1828 - AIF1TX5MIX Input 3 Source */ + { 0x00000725, 0x0080 }, /* R1829 - AIF1TX5MIX Input 3 Volume */ + { 0x00000726, 0x0000 }, /* R1830 - AIF1TX5MIX Input 4 Source */ + { 0x00000727, 0x0080 }, /* R1831 - AIF1TX5MIX Input 4 Volume */ + { 0x00000728, 0x0000 }, /* R1832 - AIF1TX6MIX Input 1 Source */ + { 0x00000729, 0x0080 }, /* R1833 - AIF1TX6MIX Input 1 Volume */ + { 0x0000072A, 0x0000 }, /* R1834 - AIF1TX6MIX Input 2 Source */ + { 0x0000072B, 0x0080 }, /* R1835 - AIF1TX6MIX Input 2 Volume */ + { 0x0000072C, 0x0000 }, /* R1836 - AIF1TX6MIX Input 3 Source */ + { 0x0000072D, 0x0080 }, /* R1837 - AIF1TX6MIX Input 3 Volume */ + { 0x0000072E, 0x0000 }, /* R1838 - AIF1TX6MIX Input 4 Source */ + { 0x0000072F, 0x0080 }, /* R1839 - AIF1TX6MIX Input 4 Volume */ + { 0x00000730, 0x0000 }, /* R1840 - AIF1TX7MIX Input 1 Source */ + { 0x00000731, 0x0080 }, /* R1841 - AIF1TX7MIX Input 1 Volume */ + { 0x00000732, 0x0000 }, /* R1842 - AIF1TX7MIX Input 2 Source */ + { 0x00000733, 0x0080 }, /* R1843 - AIF1TX7MIX Input 2 Volume */ + { 0x00000734, 0x0000 }, /* R1844 - AIF1TX7MIX Input 3 Source */ + { 0x00000735, 0x0080 }, /* R1845 - AIF1TX7MIX Input 3 Volume */ + { 0x00000736, 0x0000 }, /* R1846 - AIF1TX7MIX Input 4 Source */ + { 0x00000737, 0x0080 }, /* R1847 - AIF1TX7MIX Input 4 Volume */ + { 0x00000738, 0x0000 }, /* R1848 - AIF1TX8MIX Input 1 Source */ + { 0x00000739, 0x0080 }, /* R1849 - AIF1TX8MIX Input 1 Volume */ + { 0x0000073A, 0x0000 }, /* R1850 - AIF1TX8MIX Input 2 Source */ + { 0x0000073B, 0x0080 }, /* R1851 - AIF1TX8MIX Input 2 Volume */ + { 0x0000073C, 0x0000 }, /* R1852 - AIF1TX8MIX Input 3 Source */ + { 0x0000073D, 0x0080 }, /* R1853 - AIF1TX8MIX Input 3 Volume */ + { 0x0000073E, 0x0000 }, /* R1854 - AIF1TX8MIX Input 4 Source */ + { 0x0000073F, 0x0080 }, /* R1855 - AIF1TX8MIX Input 4 Volume */ + { 0x00000740, 0x0000 }, /* R1856 - AIF2TX1MIX Input 1 Source */ + { 0x00000741, 0x0080 }, /* R1857 - AIF2TX1MIX Input 1 Volume */ + { 0x00000742, 0x0000 }, /* R1858 - AIF2TX1MIX Input 2 Source */ + { 0x00000743, 0x0080 }, /* R1859 - AIF2TX1MIX Input 2 Volume */ + { 0x00000744, 0x0000 }, /* R1860 - AIF2TX1MIX Input 3 Source */ + { 0x00000745, 0x0080 }, /* R1861 - AIF2TX1MIX Input 3 Volume */ + { 0x00000746, 0x0000 }, /* R1862 - AIF2TX1MIX Input 4 Source */ + { 0x00000747, 0x0080 }, /* R1863 - AIF2TX1MIX Input 4 Volume */ + { 0x00000748, 0x0000 }, /* R1864 - AIF2TX2MIX Input 1 Source */ + { 0x00000749, 0x0080 }, /* R1865 - AIF2TX2MIX Input 1 Volume */ + { 0x0000074A, 0x0000 }, /* R1866 - AIF2TX2MIX Input 2 Source */ + { 0x0000074B, 0x0080 }, /* R1867 - AIF2TX2MIX Input 2 Volume */ + { 0x0000074C, 0x0000 }, /* R1868 - AIF2TX2MIX Input 3 Source */ + { 0x0000074D, 0x0080 }, /* R1869 - AIF2TX2MIX Input 3 Volume */ + { 0x0000074E, 0x0000 }, /* R1870 - AIF2TX2MIX Input 4 Source */ + { 0x0000074F, 0x0080 }, /* R1871 - AIF2TX2MIX Input 4 Volume */ + { 0x00000750, 0x0000 }, /* R1872 - AIF2TX3MIX Input 1 Source */ + { 0x00000751, 0x0080 }, /* R1873 - AIF2TX3MIX Input 1 Volume */ + { 0x00000752, 0x0000 }, /* R1874 - AIF2TX3MIX Input 2 Source */ + { 0x00000753, 0x0080 }, /* R1875 - AIF2TX3MIX Input 2 Volume */ + { 0x00000754, 0x0000 }, /* R1876 - AIF2TX3MIX Input 3 Source */ + { 0x00000755, 0x0080 }, /* R1877 - AIF2TX3MIX Input 3 Volume */ + { 0x00000756, 0x0000 }, /* R1878 - AIF2TX3MIX Input 4 Source */ + { 0x00000757, 0x0080 }, /* R1879 - AIF2TX3MIX Input 4 Volume */ + { 0x00000758, 0x0000 }, /* R1880 - AIF2TX4MIX Input 1 Source */ + { 0x00000759, 0x0080 }, /* R1881 - AIF2TX4MIX Input 1 Volume */ + { 0x0000075A, 0x0000 }, /* R1882 - AIF2TX4MIX Input 2 Source */ + { 0x0000075B, 0x0080 }, /* R1883 - AIF2TX4MIX Input 2 Volume */ + { 0x0000075C, 0x0000 }, /* R1884 - AIF2TX4MIX Input 3 Source */ + { 0x0000075D, 0x0080 }, /* R1885 - AIF2TX4MIX Input 3 Volume */ + { 0x0000075E, 0x0000 }, /* R1886 - AIF2TX4MIX Input 4 Source */ + { 0x0000075F, 0x0080 }, /* R1887 - AIF2TX4MIX Input 4 Volume */ + { 0x00000760, 0x0000 }, /* R1888 - AIF2TX5MIX Input 1 Source */ + { 0x00000761, 0x0080 }, /* R1889 - AIF2TX5MIX Input 1 Volume */ + { 0x00000762, 0x0000 }, /* R1890 - AIF2TX5MIX Input 2 Source */ + { 0x00000763, 0x0080 }, /* R1891 - AIF2TX5MIX Input 2 Volume */ + { 0x00000764, 0x0000 }, /* R1892 - AIF2TX5MIX Input 3 Source */ + { 0x00000765, 0x0080 }, /* R1893 - AIF2TX5MIX Input 3 Volume */ + { 0x00000766, 0x0000 }, /* R1894 - AIF2TX5MIX Input 4 Source */ + { 0x00000767, 0x0080 }, /* R1895 - AIF2TX5MIX Input 4 Volume */ + { 0x00000768, 0x0000 }, /* R1896 - AIF2TX6MIX Input 1 Source */ + { 0x00000769, 0x0080 }, /* R1897 - AIF2TX6MIX Input 1 Volume */ + { 0x0000076A, 0x0000 }, /* R1898 - AIF2TX6MIX Input 2 Source */ + { 0x0000076B, 0x0080 }, /* R1899 - AIF2TX6MIX Input 2 Volume */ + { 0x0000076C, 0x0000 }, /* R1900 - AIF2TX6MIX Input 3 Source */ + { 0x0000076D, 0x0080 }, /* R1901 - AIF2TX6MIX Input 3 Volume */ + { 0x0000076E, 0x0000 }, /* R1902 - AIF2TX6MIX Input 4 Source */ + { 0x0000076F, 0x0080 }, /* R1903 - AIF2TX6MIX Input 4 Volume */ + { 0x00000780, 0x0000 }, /* R1920 - AIF3TX1MIX Input 1 Source */ + { 0x00000781, 0x0080 }, /* R1921 - AIF3TX1MIX Input 1 Volume */ + { 0x00000782, 0x0000 }, /* R1922 - AIF3TX1MIX Input 2 Source */ + { 0x00000783, 0x0080 }, /* R1923 - AIF3TX1MIX Input 2 Volume */ + { 0x00000784, 0x0000 }, /* R1924 - AIF3TX1MIX Input 3 Source */ + { 0x00000785, 0x0080 }, /* R1925 - AIF3TX1MIX Input 3 Volume */ + { 0x00000786, 0x0000 }, /* R1926 - AIF3TX1MIX Input 4 Source */ + { 0x00000787, 0x0080 }, /* R1927 - AIF3TX1MIX Input 4 Volume */ + { 0x00000788, 0x0000 }, /* R1928 - AIF3TX2MIX Input 1 Source */ + { 0x00000789, 0x0080 }, /* R1929 - AIF3TX2MIX Input 1 Volume */ + { 0x0000078A, 0x0000 }, /* R1930 - AIF3TX2MIX Input 2 Source */ + { 0x0000078B, 0x0080 }, /* R1931 - AIF3TX2MIX Input 2 Volume */ + { 0x0000078C, 0x0000 }, /* R1932 - AIF3TX2MIX Input 3 Source */ + { 0x0000078D, 0x0080 }, /* R1933 - AIF3TX2MIX Input 3 Volume */ + { 0x0000078E, 0x0000 }, /* R1934 - AIF3TX2MIX Input 4 Source */ + { 0x0000078F, 0x0080 }, /* R1935 - AIF3TX2MIX Input 4 Volume */ + { 0x00000880, 0x0000 }, /* R2176 - EQ1MIX Input 1 Source */ + { 0x00000881, 0x0080 }, /* R2177 - EQ1MIX Input 1 Volume */ + { 0x00000882, 0x0000 }, /* R2178 - EQ1MIX Input 2 Source */ + { 0x00000883, 0x0080 }, /* R2179 - EQ1MIX Input 2 Volume */ + { 0x00000884, 0x0000 }, /* R2180 - EQ1MIX Input 3 Source */ + { 0x00000885, 0x0080 }, /* R2181 - EQ1MIX Input 3 Volume */ + { 0x00000886, 0x0000 }, /* R2182 - EQ1MIX Input 4 Source */ + { 0x00000887, 0x0080 }, /* R2183 - EQ1MIX Input 4 Volume */ + { 0x00000888, 0x0000 }, /* R2184 - EQ2MIX Input 1 Source */ + { 0x00000889, 0x0080 }, /* R2185 - EQ2MIX Input 1 Volume */ + { 0x0000088A, 0x0000 }, /* R2186 - EQ2MIX Input 2 Source */ + { 0x0000088B, 0x0080 }, /* R2187 - EQ2MIX Input 2 Volume */ + { 0x0000088C, 0x0000 }, /* R2188 - EQ2MIX Input 3 Source */ + { 0x0000088D, 0x0080 }, /* R2189 - EQ2MIX Input 3 Volume */ + { 0x0000088E, 0x0000 }, /* R2190 - EQ2MIX Input 4 Source */ + { 0x0000088F, 0x0080 }, /* R2191 - EQ2MIX Input 4 Volume */ + { 0x000008C0, 0x0000 }, /* R2240 - DRC1LMIX Input 1 Source */ + { 0x000008C1, 0x0080 }, /* R2241 - DRC1LMIX Input 1 Volume */ + { 0x000008C2, 0x0000 }, /* R2242 - DRC1LMIX Input 2 Source */ + { 0x000008C3, 0x0080 }, /* R2243 - DRC1LMIX Input 2 Volume */ + { 0x000008C4, 0x0000 }, /* R2244 - DRC1LMIX Input 3 Source */ + { 0x000008C5, 0x0080 }, /* R2245 - DRC1LMIX Input 3 Volume */ + { 0x000008C6, 0x0000 }, /* R2246 - DRC1LMIX Input 4 Source */ + { 0x000008C7, 0x0080 }, /* R2247 - DRC1LMIX Input 4 Volume */ + { 0x000008C8, 0x0000 }, /* R2248 - DRC1RMIX Input 1 Source */ + { 0x000008C9, 0x0080 }, /* R2249 - DRC1RMIX Input 1 Volume */ + { 0x000008CA, 0x0000 }, /* R2250 - DRC1RMIX Input 2 Source */ + { 0x000008CB, 0x0080 }, /* R2251 - DRC1RMIX Input 2 Volume */ + { 0x000008CC, 0x0000 }, /* R2252 - DRC1RMIX Input 3 Source */ + { 0x000008CD, 0x0080 }, /* R2253 - DRC1RMIX Input 3 Volume */ + { 0x000008CE, 0x0000 }, /* R2254 - DRC1RMIX Input 4 Source */ + { 0x000008CF, 0x0080 }, /* R2255 - DRC1RMIX Input 4 Volume */ + { 0x000008D0, 0x0000 }, /* R2256 - DRC2LMIX Input 1 Source */ + { 0x000008D1, 0x0080 }, /* R2257 - DRC2LMIX Input 1 Volume */ + { 0x000008D2, 0x0000 }, /* R2258 - DRC2LMIX Input 2 Source */ + { 0x000008D3, 0x0080 }, /* R2259 - DRC2LMIX Input 2 Volume */ + { 0x000008D4, 0x0000 }, /* R2260 - DRC2LMIX Input 3 Source */ + { 0x000008D5, 0x0080 }, /* R2261 - DRC2LMIX Input 3 Volume */ + { 0x000008D6, 0x0000 }, /* R2262 - DRC2LMIX Input 4 Source */ + { 0x000008D7, 0x0080 }, /* R2263 - DRC2LMIX Input 4 Volume */ + { 0x000008D8, 0x0000 }, /* R2264 - DRC2RMIX Input 1 Source */ + { 0x000008D9, 0x0080 }, /* R2265 - DRC2RMIX Input 1 Volume */ + { 0x000008DA, 0x0000 }, /* R2266 - DRC2RMIX Input 2 Source */ + { 0x000008DB, 0x0080 }, /* R2267 - DRC2RMIX Input 2 Volume */ + { 0x000008DC, 0x0000 }, /* R2268 - DRC2RMIX Input 3 Source */ + { 0x000008DD, 0x0080 }, /* R2269 - DRC2RMIX Input 3 Volume */ + { 0x000008DE, 0x0000 }, /* R2270 - DRC2RMIX Input 4 Source */ + { 0x000008DF, 0x0080 }, /* R2271 - DRC2RMIX Input 4 Volume */ + { 0x00000900, 0x0000 }, /* R2304 - HPLP1MIX Input 1 Source */ + { 0x00000901, 0x0080 }, /* R2305 - HPLP1MIX Input 1 Volume */ + { 0x00000902, 0x0000 }, /* R2306 - HPLP1MIX Input 2 Source */ + { 0x00000903, 0x0080 }, /* R2307 - HPLP1MIX Input 2 Volume */ + { 0x00000904, 0x0000 }, /* R2308 - HPLP1MIX Input 3 Source */ + { 0x00000905, 0x0080 }, /* R2309 - HPLP1MIX Input 3 Volume */ + { 0x00000906, 0x0000 }, /* R2310 - HPLP1MIX Input 4 Source */ + { 0x00000907, 0x0080 }, /* R2311 - HPLP1MIX Input 4 Volume */ + { 0x00000908, 0x0000 }, /* R2312 - HPLP2MIX Input 1 Source */ + { 0x00000909, 0x0080 }, /* R2313 - HPLP2MIX Input 1 Volume */ + { 0x0000090A, 0x0000 }, /* R2314 - HPLP2MIX Input 2 Source */ + { 0x0000090B, 0x0080 }, /* R2315 - HPLP2MIX Input 2 Volume */ + { 0x0000090C, 0x0000 }, /* R2316 - HPLP2MIX Input 3 Source */ + { 0x0000090D, 0x0080 }, /* R2317 - HPLP2MIX Input 3 Volume */ + { 0x0000090E, 0x0000 }, /* R2318 - HPLP2MIX Input 4 Source */ + { 0x0000090F, 0x0080 }, /* R2319 - HPLP2MIX Input 4 Volume */ + { 0x00000910, 0x0000 }, /* R2320 - HPLP3MIX Input 1 Source */ + { 0x00000911, 0x0080 }, /* R2321 - HPLP3MIX Input 1 Volume */ + { 0x00000912, 0x0000 }, /* R2322 - HPLP3MIX Input 2 Source */ + { 0x00000913, 0x0080 }, /* R2323 - HPLP3MIX Input 2 Volume */ + { 0x00000914, 0x0000 }, /* R2324 - HPLP3MIX Input 3 Source */ + { 0x00000915, 0x0080 }, /* R2325 - HPLP3MIX Input 3 Volume */ + { 0x00000916, 0x0000 }, /* R2326 - HPLP3MIX Input 4 Source */ + { 0x00000917, 0x0080 }, /* R2327 - HPLP3MIX Input 4 Volume */ + { 0x00000918, 0x0000 }, /* R2328 - HPLP4MIX Input 1 Source */ + { 0x00000919, 0x0080 }, /* R2329 - HPLP4MIX Input 1 Volume */ + { 0x0000091A, 0x0000 }, /* R2330 - HPLP4MIX Input 2 Source */ + { 0x0000091B, 0x0080 }, /* R2331 - HPLP4MIX Input 2 Volume */ + { 0x0000091C, 0x0000 }, /* R2332 - HPLP4MIX Input 3 Source */ + { 0x0000091D, 0x0080 }, /* R2333 - HPLP4MIX Input 3 Volume */ + { 0x0000091E, 0x0000 }, /* R2334 - HPLP4MIX Input 4 Source */ + { 0x0000091F, 0x0080 }, /* R2335 - HPLP4MIX Input 4 Volume */ + { 0x00000980, 0x0000 }, /* R2432 - DSP2LMIX Input 1 Source */ + { 0x00000981, 0x0080 }, /* R2433 - DSP2LMIX Input 1 Volume */ + { 0x00000982, 0x0000 }, /* R2434 - DSP2LMIX Input 2 Source */ + { 0x00000983, 0x0080 }, /* R2435 - DSP2LMIX Input 2 Volume */ + { 0x00000984, 0x0000 }, /* R2436 - DSP2LMIX Input 3 Source */ + { 0x00000985, 0x0080 }, /* R2437 - DSP2LMIX Input 3 Volume */ + { 0x00000986, 0x0000 }, /* R2438 - DSP2LMIX Input 4 Source */ + { 0x00000987, 0x0080 }, /* R2439 - DSP2LMIX Input 4 Volume */ + { 0x00000988, 0x0000 }, /* R2440 - DSP2RMIX Input 1 Source */ + { 0x00000989, 0x0080 }, /* R2441 - DSP2RMIX Input 1 Volume */ + { 0x0000098A, 0x0000 }, /* R2442 - DSP2RMIX Input 2 Source */ + { 0x0000098B, 0x0080 }, /* R2443 - DSP2RMIX Input 2 Volume */ + { 0x0000098C, 0x0000 }, /* R2444 - DSP2RMIX Input 3 Source */ + { 0x0000098D, 0x0080 }, /* R2445 - DSP2RMIX Input 3 Volume */ + { 0x0000098E, 0x0000 }, /* R2446 - DSP2RMIX Input 4 Source */ + { 0x0000098F, 0x0080 }, /* R2447 - DSP2RMIX Input 4 Volume */ + { 0x00000990, 0x0000 }, /* R2448 - DSP2AUX1MIX Input 1 Source */ + { 0x00000998, 0x0000 }, /* R2456 - DSP2AUX2MIX Input 1 Source */ + { 0x000009A0, 0x0000 }, /* R2464 - DSP2AUX3MIX Input 1 Source */ + { 0x000009A8, 0x0000 }, /* R2472 - DSP2AUX4MIX Input 1 Source */ + { 0x000009B0, 0x0000 }, /* R2480 - DSP2AUX5MIX Input 1 Source */ + { 0x000009B8, 0x0000 }, /* R2488 - DSP2AUX6MIX Input 1 Source */ + { 0x000009C0, 0x0000 }, /* R2496 - DSP3LMIX Input 1 Source */ + { 0x000009C1, 0x0080 }, /* R2497 - DSP3LMIX Input 1 Volume */ + { 0x000009C2, 0x0000 }, /* R2498 - DSP3LMIX Input 2 Source */ + { 0x000009C3, 0x0080 }, /* R2499 - DSP3LMIX Input 2 Volume */ + { 0x000009C4, 0x0000 }, /* R2500 - DSP3LMIX Input 3 Source */ + { 0x000009C5, 0x0080 }, /* R2501 - DSP3LMIX Input 3 Volume */ + { 0x000009C6, 0x0000 }, /* R2502 - DSP3LMIX Input 4 Source */ + { 0x000009C7, 0x0080 }, /* R2503 - DSP3LMIX Input 4 Volume */ + { 0x000009C8, 0x0000 }, /* R2504 - DSP3RMIX Input 1 Source */ + { 0x000009C9, 0x0080 }, /* R2505 - DSP3RMIX Input 1 Volume */ + { 0x000009CA, 0x0000 }, /* R2506 - DSP3RMIX Input 2 Source */ + { 0x000009CB, 0x0080 }, /* R2507 - DSP3RMIX Input 2 Volume */ + { 0x000009CC, 0x0000 }, /* R2508 - DSP3RMIX Input 3 Source */ + { 0x000009CD, 0x0080 }, /* R2509 - DSP3RMIX Input 3 Volume */ + { 0x000009CE, 0x0000 }, /* R2510 - DSP3RMIX Input 4 Source */ + { 0x000009CF, 0x0080 }, /* R2511 - DSP3RMIX Input 4 Volume */ + { 0x000009D0, 0x0000 }, /* R2512 - DSP3AUX1MIX Input 1 Source */ + { 0x000009D8, 0x0000 }, /* R2520 - DSP3AUX2MIX Input 1 Source */ + { 0x000009E0, 0x0000 }, /* R2528 - DSP3AUX3MIX Input 1 Source */ + { 0x000009E8, 0x0000 }, /* R2536 - DSP3AUX4MIX Input 1 Source */ + { 0x000009F0, 0x0000 }, /* R2544 - DSP3AUX5MIX Input 1 Source */ + { 0x000009F8, 0x0000 }, /* R2552 - DSP3AUX6MIX Input 1 Source */ + { 0x00000A80, 0x0000 }, /* R2688 - ASRC1LMIX Input 1 Source */ + { 0x00000A88, 0x0000 }, /* R2696 - ASRC1RMIX Input 1 Source */ + { 0x00000A90, 0x0000 }, /* R2704 - ASRC2LMIX Input 1 Source */ + { 0x00000A98, 0x0000 }, /* R2712 - ASRC2RMIX Input 1 Source */ + { 0x00000B00, 0x0000 }, /* R2816 - ISRC1DEC1MIX Input 1 Source */ + { 0x00000B08, 0x0000 }, /* R2824 - ISRC1DEC2MIX Input 1 Source */ + { 0x00000B10, 0x0000 }, /* R2832 - ISRC1DEC3MIX Input 1 Source */ + { 0x00000B18, 0x0000 }, /* R2840 - ISRC1DEC4MIX Input 1 Source */ + { 0x00000B20, 0x0000 }, /* R2848 - ISRC1INT1MIX Input 1 Source */ + { 0x00000B28, 0x0000 }, /* R2856 - ISRC1INT2MIX Input 1 Source */ + { 0x00000B30, 0x0000 }, /* R2864 - ISRC1INT3MIX Input 1 Source */ + { 0x00000B38, 0x0000 }, /* R2872 - ISRC1INT4MIX Input 1 Source */ + { 0x00000B40, 0x0000 }, /* R2880 - ISRC2DEC1MIX Input 1 Source */ + { 0x00000B48, 0x0000 }, /* R2888 - ISRC2DEC2MIX Input 1 Source */ + { 0x00000B50, 0x0000 }, /* R2896 - ISRC2DEC3MIX Input 1 Source */ + { 0x00000B58, 0x0000 }, /* R2904 - ISRC2DEC4MIX Input 1 Source */ + { 0x00000B60, 0x0000 }, /* R2912 - ISRC2INT1MIX Input 1 Source */ + { 0x00000B68, 0x0000 }, /* R2920 - ISRC2INT2MIX Input 1 Source */ + { 0x00000B70, 0x0000 }, /* R2928 - ISRC2INT3MIX Input 1 Source */ + { 0x00000B78, 0x0000 }, /* R2936 - ISRC2INT4MIX Input 1 Source */ + { 0x00000B80, 0x0000 }, /* R2944 - ISRC3DEC1MIX Input 1 Source */ + { 0x00000B88, 0x0000 }, /* R2952 - ISRC3DEC2MIX Input 1 Source */ + { 0x00000B90, 0x0000 }, /* R2960 - ISRC3DEC3MIX Input 1 Source */ + { 0x00000B98, 0x0000 }, /* R2968 - ISRC3DEC4MIX Input 1 Source */ + { 0x00000BA0, 0x0000 }, /* R2976 - ISRC3INT1MIX Input 1 Source */ + { 0x00000BA8, 0x0000 }, /* R2984 - ISRC3INT2MIX Input 1 Source */ + { 0x00000BB0, 0x0000 }, /* R2992 - ISRC3INT3MIX Input 1 Source */ + { 0x00000BB8, 0x0000 }, /* R3000 - ISRC3INT4MIX Input 1 Source */ + { 0x00000C00, 0xA101 }, /* R3072 - GPIO1 CTRL */ + { 0x00000C01, 0xA101 }, /* R3073 - GPIO2 CTRL */ + { 0x00000C0F, 0x0400 }, /* R3087 - IRQ CTRL 1 */ + { 0x00000C10, 0x1000 }, /* R3088 - GPIO Debounce Config */ + { 0x00000C20, 0x0002 }, /* R3104 - Misc Pad Ctrl 1 */ + { 0x00000C21, 0x8001 }, /* R3105 - Misc Pad Ctrl 2 */ + { 0x00000C22, 0x0000 }, /* R3106 - Misc Pad Ctrl 3 */ + { 0x00000C23, 0x0000 }, /* R3107 - Misc Pad Ctrl 4 */ + { 0x00000C24, 0x0000 }, /* R3108 - Misc Pad Ctrl 5 */ + { 0x00000C25, 0x0000 }, /* R3109 - Misc Pad Ctrl 6 */ + { 0x00000C30, 0x0404 }, /* R3120 - Misc Pad Ctrl 7 */ + { 0x00000C32, 0x0404 }, /* R3122 - Misc Pad Ctrl 9 */ + { 0x00000C33, 0x0404 }, /* R3123 - Misc Pad Ctrl 10 */ + { 0x00000C34, 0x0404 }, /* R3124 - Misc Pad Ctrl 11 */ + { 0x00000C35, 0x0404 }, /* R3125 - Misc Pad Ctrl 12 */ + { 0x00000C36, 0x0400 }, /* R3126 - Misc Pad Ctrl 13 */ + { 0x00000C37, 0x0404 }, /* R3127 - Misc Pad Ctrl 14 */ + { 0x00000C39, 0x0400 }, /* R3129 - Misc Pad Ctrl 16 */ + { 0x00000D08, 0x0007 }, /* R3336 - Interrupt Status 1 Mask */ + { 0x00000D09, 0x06FF }, /* R3337 - Interrupt Status 2 Mask */ + { 0x00000D0A, 0xCFEF }, /* R3338 - Interrupt Status 3 Mask */ + { 0x00000D0B, 0xFFC3 }, /* R3339 - Interrupt Status 4 Mask */ + { 0x00000D0C, 0x000B }, /* R3340 - Interrupt Status 5 Mask */ + { 0x00000D0D, 0xD005 }, /* R3341 - Interrupt Status 6 Mask */ + { 0x00000D0F, 0x0000 }, /* R3343 - Interrupt Control */ + { 0x00000D18, 0x0007 }, /* R3352 - IRQ2 Status 1 Mask */ + { 0x00000D19, 0x06FF }, /* R3353 - IRQ2 Status 2 Mask */ + { 0x00000D1A, 0xCFEF }, /* R3354 - IRQ2 Status 3 Mask */ + { 0x00000D1B, 0xFFC3 }, /* R3355 - IRQ2 Status 4 Mask */ + { 0x00000D1C, 0x000B }, /* R3356 - IRQ2 Status 5 Mask */ + { 0x00000D1D, 0xD005 }, /* R3357 - IRQ2 Status 6 Mask */ + { 0x00000D1F, 0x0000 }, /* R3359 - IRQ2 Control */ + { 0x00000E00, 0x0000 }, /* R3584 - FX_Ctrl1 */ + { 0x00000E10, 0x6318 }, /* R3600 - EQ1_1 */ + { 0x00000E11, 0x6300 }, /* R3601 - EQ1_2 */ + { 0x00000E12, 0x0FC8 }, /* R3602 - EQ1_3 */ + { 0x00000E13, 0x03FE }, /* R3603 - EQ1_4 */ + { 0x00000E14, 0x00E0 }, /* R3604 - EQ1_5 */ + { 0x00000E15, 0x1EC4 }, /* R3605 - EQ1_6 */ + { 0x00000E16, 0xF136 }, /* R3606 - EQ1_7 */ + { 0x00000E17, 0x0409 }, /* R3607 - EQ1_8 */ + { 0x00000E18, 0x04CC }, /* R3608 - EQ1_9 */ + { 0x00000E19, 0x1C9B }, /* R3609 - EQ1_10 */ + { 0x00000E1A, 0xF337 }, /* R3610 - EQ1_11 */ + { 0x00000E1B, 0x040B }, /* R3611 - EQ1_12 */ + { 0x00000E1C, 0x0CBB }, /* R3612 - EQ1_13 */ + { 0x00000E1D, 0x16F8 }, /* R3613 - EQ1_14 */ + { 0x00000E1E, 0xF7D9 }, /* R3614 - EQ1_15 */ + { 0x00000E1F, 0x040A }, /* R3615 - EQ1_16 */ + { 0x00000E20, 0x1F14 }, /* R3616 - EQ1_17 */ + { 0x00000E21, 0x058C }, /* R3617 - EQ1_18 */ + { 0x00000E22, 0x0563 }, /* R3618 - EQ1_19 */ + { 0x00000E23, 0x4000 }, /* R3619 - EQ1_20 */ + { 0x00000E24, 0x0B75 }, /* R3620 - EQ1_21 */ + { 0x00000E26, 0x6318 }, /* R3622 - EQ2_1 */ + { 0x00000E27, 0x6300 }, /* R3623 - EQ2_2 */ + { 0x00000E28, 0x0FC8 }, /* R3624 - EQ2_3 */ + { 0x00000E29, 0x03FE }, /* R3625 - EQ2_4 */ + { 0x00000E2A, 0x00E0 }, /* R3626 - EQ2_5 */ + { 0x00000E2B, 0x1EC4 }, /* R3627 - EQ2_6 */ + { 0x00000E2C, 0xF136 }, /* R3628 - EQ2_7 */ + { 0x00000E2D, 0x0409 }, /* R3629 - EQ2_8 */ + { 0x00000E2E, 0x04CC }, /* R3630 - EQ2_9 */ + { 0x00000E2F, 0x1C9B }, /* R3631 - EQ2_10 */ + { 0x00000E30, 0xF337 }, /* R3632 - EQ2_11 */ + { 0x00000E31, 0x040B }, /* R3633 - EQ2_12 */ + { 0x00000E32, 0x0CBB }, /* R3634 - EQ2_13 */ + { 0x00000E33, 0x16F8 }, /* R3635 - EQ2_14 */ + { 0x00000E34, 0xF7D9 }, /* R3636 - EQ2_15 */ + { 0x00000E35, 0x040A }, /* R3637 - EQ2_16 */ + { 0x00000E36, 0x1F14 }, /* R3638 - EQ2_17 */ + { 0x00000E37, 0x058C }, /* R3639 - EQ2_18 */ + { 0x00000E38, 0x0563 }, /* R3640 - EQ2_19 */ + { 0x00000E39, 0x4000 }, /* R3641 - EQ2_20 */ + { 0x00000E3A, 0x0B75 }, /* R3642 - EQ2_21 */ + { 0x00000E80, 0x0018 }, /* R3712 - DRC1 ctrl1 */ + { 0x00000E81, 0x0933 }, /* R3713 - DRC1 ctrl2 */ + { 0x00000E82, 0x0018 }, /* R3714 - DRC1 ctrl3 */ + { 0x00000E83, 0x0000 }, /* R3715 - DRC1 ctrl4 */ + { 0x00000E84, 0x0000 }, /* R3716 - DRC1 ctrl5 */ + { 0x00000E89, 0x0018 }, /* R3721 - DRC2 ctrl1 */ + { 0x00000E8A, 0x0933 }, /* R3722 - DRC2 ctrl2 */ + { 0x00000E8B, 0x0018 }, /* R3723 - DRC2 ctrl3 */ + { 0x00000E8C, 0x0000 }, /* R3724 - DRC2 ctrl4 */ + { 0x00000E8D, 0x0000 }, /* R3725 - DRC2 ctrl5 */ + { 0x00000EC0, 0x0000 }, /* R3776 - HPLPF1_1 */ + { 0x00000EC1, 0x0000 }, /* R3777 - HPLPF1_2 */ + { 0x00000EC4, 0x0000 }, /* R3780 - HPLPF2_1 */ + { 0x00000EC5, 0x0000 }, /* R3781 - HPLPF2_2 */ + { 0x00000EC8, 0x0000 }, /* R3784 - HPLPF3_1 */ + { 0x00000EC9, 0x0000 }, /* R3785 - HPLPF3_2 */ + { 0x00000ECC, 0x0000 }, /* R3788 - HPLPF4_1 */ + { 0x00000ECD, 0x0000 }, /* R3789 - HPLPF4_2 */ + { 0x00000EE0, 0x0000 }, /* R3808 - ASRC_ENABLE */ + { 0x00000EE2, 0x0000 }, /* R3810 - ASRC_RATE1 */ + { 0x00000EE3, 0x4000 }, /* R3811 - ASRC_RATE2 */ + { 0x00000EF0, 0x0000 }, /* R3824 - ISRC 1 CTRL 1 */ + { 0x00000EF1, 0x0000 }, /* R3825 - ISRC 1 CTRL 2 */ + { 0x00000EF2, 0x0000 }, /* R3826 - ISRC 1 CTRL 3 */ + { 0x00000EF3, 0x0000 }, /* R3827 - ISRC 2 CTRL 1 */ + { 0x00000EF4, 0x0000 }, /* R3828 - ISRC 2 CTRL 2 */ + { 0x00000EF5, 0x0000 }, /* R3829 - ISRC 2 CTRL 3 */ + { 0x00000EF6, 0x0000 }, /* R3830 - ISRC 3 CTRL 1 */ + { 0x00000EF7, 0x0000 }, /* R3831 - ISRC 3 CTRL 2 */ + { 0x00000EF8, 0x0000 }, /* R3832 - ISRC 3 CTRL 3 */ + { 0x00001200, 0x0010 }, /* R4608 - DSP2 Control 1 */ + { 0x00001300, 0x0010 }, /* R4864 - DSP3 Control 1 */ +}; + +static bool cs47l24_is_adsp_memory(unsigned int reg) +{ + switch (reg) { + case 0x200000 ... 0x205fff: /* DSP2 PM */ + case 0x280000 ... 0x281fff: /* DSP2 ZM */ + case 0x290000 ... 0x2a7fff: /* DSP2 XM */ + case 0x2a8000 ... 0x2b3fff: /* DSP2 YM */ + case 0x300000 ... 0x308fff: /* DSP3 PM */ + case 0x380000 ... 0x381fff: /* DSP3 ZM */ + case 0x390000 ... 0x3a7fff: /* DSP3 XM */ + case 0x3a8000 ... 0x3b3fff: /* DSP3 YM */ + return true; + default: + return false; + } +} + +static bool cs47l24_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case ARIZONA_SOFTWARE_RESET: + case ARIZONA_DEVICE_REVISION: + case ARIZONA_CTRL_IF_SPI_CFG_1: + case ARIZONA_WRITE_SEQUENCER_CTRL_0: + case ARIZONA_WRITE_SEQUENCER_CTRL_1: + case ARIZONA_WRITE_SEQUENCER_CTRL_2: + case ARIZONA_TONE_GENERATOR_1: + case ARIZONA_TONE_GENERATOR_2: + case ARIZONA_TONE_GENERATOR_3: + case ARIZONA_TONE_GENERATOR_4: + case ARIZONA_TONE_GENERATOR_5: + case ARIZONA_PWM_DRIVE_1: + case ARIZONA_PWM_DRIVE_2: + case ARIZONA_PWM_DRIVE_3: + case ARIZONA_SEQUENCE_CONTROL: + case ARIZONA_SAMPLE_RATE_SEQUENCE_SELECT_1: + case ARIZONA_SAMPLE_RATE_SEQUENCE_SELECT_2: + case ARIZONA_SAMPLE_RATE_SEQUENCE_SELECT_3: + case ARIZONA_SAMPLE_RATE_SEQUENCE_SELECT_4: + case ARIZONA_COMFORT_NOISE_GENERATOR: + case ARIZONA_HAPTICS_CONTROL_1: + case ARIZONA_HAPTICS_CONTROL_2: + case ARIZONA_HAPTICS_PHASE_1_INTENSITY: + case ARIZONA_HAPTICS_PHASE_1_DURATION: + case ARIZONA_HAPTICS_PHASE_2_INTENSITY: + case ARIZONA_HAPTICS_PHASE_2_DURATION: + case ARIZONA_HAPTICS_PHASE_3_INTENSITY: + case ARIZONA_HAPTICS_PHASE_3_DURATION: + case ARIZONA_HAPTICS_STATUS: + case ARIZONA_CLOCK_32K_1: + case ARIZONA_SYSTEM_CLOCK_1: + case ARIZONA_SAMPLE_RATE_1: + case ARIZONA_SAMPLE_RATE_2: + case ARIZONA_SAMPLE_RATE_3: + case ARIZONA_SAMPLE_RATE_1_STATUS: + case ARIZONA_SAMPLE_RATE_2_STATUS: + case ARIZONA_SAMPLE_RATE_3_STATUS: + case ARIZONA_ASYNC_CLOCK_1: + case ARIZONA_ASYNC_SAMPLE_RATE_1: + case ARIZONA_ASYNC_SAMPLE_RATE_1_STATUS: + case ARIZONA_ASYNC_SAMPLE_RATE_2: + case ARIZONA_ASYNC_SAMPLE_RATE_2_STATUS: + case ARIZONA_OUTPUT_SYSTEM_CLOCK: + case ARIZONA_OUTPUT_ASYNC_CLOCK: + case ARIZONA_RATE_ESTIMATOR_1: + case ARIZONA_RATE_ESTIMATOR_2: + case ARIZONA_RATE_ESTIMATOR_3: + case ARIZONA_RATE_ESTIMATOR_4: + case ARIZONA_RATE_ESTIMATOR_5: + case ARIZONA_FLL1_CONTROL_1: + case ARIZONA_FLL1_CONTROL_2: + case ARIZONA_FLL1_CONTROL_3: + case ARIZONA_FLL1_CONTROL_4: + case ARIZONA_FLL1_CONTROL_5: + case ARIZONA_FLL1_CONTROL_6: + case ARIZONA_FLL1_CONTROL_7: + case ARIZONA_FLL1_LOOP_FILTER_TEST_1: + case ARIZONA_FLL1_NCO_TEST_0: + case ARIZONA_FLL1_SYNCHRONISER_1: + case ARIZONA_FLL1_SYNCHRONISER_2: + case ARIZONA_FLL1_SYNCHRONISER_3: + case ARIZONA_FLL1_SYNCHRONISER_4: + case ARIZONA_FLL1_SYNCHRONISER_5: + case ARIZONA_FLL1_SYNCHRONISER_6: + case ARIZONA_FLL1_SYNCHRONISER_7: + case ARIZONA_FLL1_SPREAD_SPECTRUM: + case ARIZONA_FLL1_GPIO_CLOCK: + case ARIZONA_FLL2_CONTROL_1: + case ARIZONA_FLL2_CONTROL_2: + case ARIZONA_FLL2_CONTROL_3: + case ARIZONA_FLL2_CONTROL_4: + case ARIZONA_FLL2_CONTROL_5: + case ARIZONA_FLL2_CONTROL_6: + case ARIZONA_FLL2_CONTROL_7: + case ARIZONA_FLL2_LOOP_FILTER_TEST_1: + case ARIZONA_FLL2_NCO_TEST_0: + case ARIZONA_FLL2_SYNCHRONISER_1: + case ARIZONA_FLL2_SYNCHRONISER_2: + case ARIZONA_FLL2_SYNCHRONISER_3: + case ARIZONA_FLL2_SYNCHRONISER_4: + case ARIZONA_FLL2_SYNCHRONISER_5: + case ARIZONA_FLL2_SYNCHRONISER_6: + case ARIZONA_FLL2_SYNCHRONISER_7: + case ARIZONA_FLL2_SPREAD_SPECTRUM: + case ARIZONA_FLL2_GPIO_CLOCK: + case ARIZONA_MIC_BIAS_CTRL_1: + case ARIZONA_MIC_BIAS_CTRL_2: + case ARIZONA_HP_CTRL_1L: + case ARIZONA_HP_CTRL_1R: + case ARIZONA_INPUT_ENABLES: + case ARIZONA_INPUT_ENABLES_STATUS: + case ARIZONA_INPUT_RATE: + case ARIZONA_INPUT_VOLUME_RAMP: + case ARIZONA_HPF_CONTROL: + case ARIZONA_IN1L_CONTROL: + case ARIZONA_ADC_DIGITAL_VOLUME_1L: + case ARIZONA_DMIC1L_CONTROL: + case ARIZONA_IN1R_CONTROL: + case ARIZONA_ADC_DIGITAL_VOLUME_1R: + case ARIZONA_DMIC1R_CONTROL: + case ARIZONA_IN2L_CONTROL: + case ARIZONA_ADC_DIGITAL_VOLUME_2L: + case ARIZONA_DMIC2L_CONTROL: + case ARIZONA_IN2R_CONTROL: + case ARIZONA_ADC_DIGITAL_VOLUME_2R: + case ARIZONA_DMIC2R_CONTROL: + case ARIZONA_OUTPUT_ENABLES_1: + case ARIZONA_OUTPUT_STATUS_1: + case ARIZONA_RAW_OUTPUT_STATUS_1: + case ARIZONA_OUTPUT_RATE_1: + case ARIZONA_OUTPUT_VOLUME_RAMP: + case ARIZONA_OUTPUT_PATH_CONFIG_1L: + case ARIZONA_DAC_DIGITAL_VOLUME_1L: + case ARIZONA_DAC_VOLUME_LIMIT_1L: + case ARIZONA_NOISE_GATE_SELECT_1L: + case ARIZONA_DAC_DIGITAL_VOLUME_1R: + case ARIZONA_DAC_VOLUME_LIMIT_1R: + case ARIZONA_NOISE_GATE_SELECT_1R: + case ARIZONA_DAC_DIGITAL_VOLUME_4L: + case ARIZONA_OUT_VOLUME_4L: + case ARIZONA_NOISE_GATE_SELECT_4L: + case ARIZONA_DAC_AEC_CONTROL_1: + case ARIZONA_NOISE_GATE_CONTROL: + case ARIZONA_HP1_SHORT_CIRCUIT_CTRL: + case ARIZONA_AIF1_BCLK_CTRL: + case ARIZONA_AIF1_TX_PIN_CTRL: + case ARIZONA_AIF1_RX_PIN_CTRL: + case ARIZONA_AIF1_RATE_CTRL: + case ARIZONA_AIF1_FORMAT: + case ARIZONA_AIF1_RX_BCLK_RATE: + case ARIZONA_AIF1_FRAME_CTRL_1: + case ARIZONA_AIF1_FRAME_CTRL_2: + case ARIZONA_AIF1_FRAME_CTRL_3: + case ARIZONA_AIF1_FRAME_CTRL_4: + case ARIZONA_AIF1_FRAME_CTRL_5: + case ARIZONA_AIF1_FRAME_CTRL_6: + case ARIZONA_AIF1_FRAME_CTRL_7: + case ARIZONA_AIF1_FRAME_CTRL_8: + case ARIZONA_AIF1_FRAME_CTRL_9: + case ARIZONA_AIF1_FRAME_CTRL_10: + case ARIZONA_AIF1_FRAME_CTRL_11: + case ARIZONA_AIF1_FRAME_CTRL_12: + case ARIZONA_AIF1_FRAME_CTRL_13: + case ARIZONA_AIF1_FRAME_CTRL_14: + case ARIZONA_AIF1_FRAME_CTRL_15: + case ARIZONA_AIF1_FRAME_CTRL_16: + case ARIZONA_AIF1_FRAME_CTRL_17: + case ARIZONA_AIF1_FRAME_CTRL_18: + case ARIZONA_AIF1_TX_ENABLES: + case ARIZONA_AIF1_RX_ENABLES: + case ARIZONA_AIF2_BCLK_CTRL: + case ARIZONA_AIF2_TX_PIN_CTRL: + case ARIZONA_AIF2_RX_PIN_CTRL: + case ARIZONA_AIF2_RATE_CTRL: + case ARIZONA_AIF2_FORMAT: + case ARIZONA_AIF2_RX_BCLK_RATE: + case ARIZONA_AIF2_FRAME_CTRL_1: + case ARIZONA_AIF2_FRAME_CTRL_2: + case ARIZONA_AIF2_FRAME_CTRL_3: + case ARIZONA_AIF2_FRAME_CTRL_4: + case ARIZONA_AIF2_FRAME_CTRL_5: + case ARIZONA_AIF2_FRAME_CTRL_6: + case ARIZONA_AIF2_FRAME_CTRL_7: + case ARIZONA_AIF2_FRAME_CTRL_8: + case ARIZONA_AIF2_FRAME_CTRL_11: + case ARIZONA_AIF2_FRAME_CTRL_12: + case ARIZONA_AIF2_FRAME_CTRL_13: + case ARIZONA_AIF2_FRAME_CTRL_14: + case ARIZONA_AIF2_FRAME_CTRL_15: + case ARIZONA_AIF2_FRAME_CTRL_16: + case ARIZONA_AIF2_TX_ENABLES: + case ARIZONA_AIF2_RX_ENABLES: + case ARIZONA_AIF3_BCLK_CTRL: + case ARIZONA_AIF3_TX_PIN_CTRL: + case ARIZONA_AIF3_RX_PIN_CTRL: + case ARIZONA_AIF3_RATE_CTRL: + case ARIZONA_AIF3_FORMAT: + case ARIZONA_AIF3_RX_BCLK_RATE: + case ARIZONA_AIF3_FRAME_CTRL_1: + case ARIZONA_AIF3_FRAME_CTRL_2: + case ARIZONA_AIF3_FRAME_CTRL_3: + case ARIZONA_AIF3_FRAME_CTRL_4: + case ARIZONA_AIF3_FRAME_CTRL_11: + case ARIZONA_AIF3_FRAME_CTRL_12: + case ARIZONA_AIF3_TX_ENABLES: + case ARIZONA_AIF3_RX_ENABLES: + case ARIZONA_PWM1MIX_INPUT_1_SOURCE: + case ARIZONA_PWM1MIX_INPUT_1_VOLUME: + case ARIZONA_PWM1MIX_INPUT_2_SOURCE: + case ARIZONA_PWM1MIX_INPUT_2_VOLUME: + case ARIZONA_PWM1MIX_INPUT_3_SOURCE: + case ARIZONA_PWM1MIX_INPUT_3_VOLUME: + case ARIZONA_PWM1MIX_INPUT_4_SOURCE: + case ARIZONA_PWM1MIX_INPUT_4_VOLUME: + case ARIZONA_PWM2MIX_INPUT_1_SOURCE: + case ARIZONA_PWM2MIX_INPUT_1_VOLUME: + case ARIZONA_PWM2MIX_INPUT_2_SOURCE: + case ARIZONA_PWM2MIX_INPUT_2_VOLUME: + case ARIZONA_PWM2MIX_INPUT_3_SOURCE: + case ARIZONA_PWM2MIX_INPUT_3_VOLUME: + case ARIZONA_PWM2MIX_INPUT_4_SOURCE: + case ARIZONA_PWM2MIX_INPUT_4_VOLUME: + case ARIZONA_OUT1LMIX_INPUT_1_SOURCE: + case ARIZONA_OUT1LMIX_INPUT_1_VOLUME: + case ARIZONA_OUT1LMIX_INPUT_2_SOURCE: + case ARIZONA_OUT1LMIX_INPUT_2_VOLUME: + case ARIZONA_OUT1LMIX_INPUT_3_SOURCE: + case ARIZONA_OUT1LMIX_INPUT_3_VOLUME: + case ARIZONA_OUT1LMIX_INPUT_4_SOURCE: + case ARIZONA_OUT1LMIX_INPUT_4_VOLUME: + case ARIZONA_OUT1RMIX_INPUT_1_SOURCE: + case ARIZONA_OUT1RMIX_INPUT_1_VOLUME: + case ARIZONA_OUT1RMIX_INPUT_2_SOURCE: + case ARIZONA_OUT1RMIX_INPUT_2_VOLUME: + case ARIZONA_OUT1RMIX_INPUT_3_SOURCE: + case ARIZONA_OUT1RMIX_INPUT_3_VOLUME: + case ARIZONA_OUT1RMIX_INPUT_4_SOURCE: + case ARIZONA_OUT1RMIX_INPUT_4_VOLUME: + case ARIZONA_OUT4LMIX_INPUT_1_SOURCE: + case ARIZONA_OUT4LMIX_INPUT_1_VOLUME: + case ARIZONA_OUT4LMIX_INPUT_2_SOURCE: + case ARIZONA_OUT4LMIX_INPUT_2_VOLUME: + case ARIZONA_OUT4LMIX_INPUT_3_SOURCE: + case ARIZONA_OUT4LMIX_INPUT_3_VOLUME: + case ARIZONA_OUT4LMIX_INPUT_4_SOURCE: + case ARIZONA_OUT4LMIX_INPUT_4_VOLUME: + case ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE: + case ARIZONA_AIF1TX1MIX_INPUT_1_VOLUME: + case ARIZONA_AIF1TX1MIX_INPUT_2_SOURCE: + case ARIZONA_AIF1TX1MIX_INPUT_2_VOLUME: + case ARIZONA_AIF1TX1MIX_INPUT_3_SOURCE: + case ARIZONA_AIF1TX1MIX_INPUT_3_VOLUME: + case ARIZONA_AIF1TX1MIX_INPUT_4_SOURCE: + case ARIZONA_AIF1TX1MIX_INPUT_4_VOLUME: + case ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE: + case ARIZONA_AIF1TX2MIX_INPUT_1_VOLUME: + case ARIZONA_AIF1TX2MIX_INPUT_2_SOURCE: + case ARIZONA_AIF1TX2MIX_INPUT_2_VOLUME: + case ARIZONA_AIF1TX2MIX_INPUT_3_SOURCE: + case ARIZONA_AIF1TX2MIX_INPUT_3_VOLUME: + case ARIZONA_AIF1TX2MIX_INPUT_4_SOURCE: + case ARIZONA_AIF1TX2MIX_INPUT_4_VOLUME: + case ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE: + case ARIZONA_AIF1TX3MIX_INPUT_1_VOLUME: + case ARIZONA_AIF1TX3MIX_INPUT_2_SOURCE: + case ARIZONA_AIF1TX3MIX_INPUT_2_VOLUME: + case ARIZONA_AIF1TX3MIX_INPUT_3_SOURCE: + case ARIZONA_AIF1TX3MIX_INPUT_3_VOLUME: + case ARIZONA_AIF1TX3MIX_INPUT_4_SOURCE: + case ARIZONA_AIF1TX3MIX_INPUT_4_VOLUME: + case ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE: + case ARIZONA_AIF1TX4MIX_INPUT_1_VOLUME: + case ARIZONA_AIF1TX4MIX_INPUT_2_SOURCE: + case ARIZONA_AIF1TX4MIX_INPUT_2_VOLUME: + case ARIZONA_AIF1TX4MIX_INPUT_3_SOURCE: + case ARIZONA_AIF1TX4MIX_INPUT_3_VOLUME: + case ARIZONA_AIF1TX4MIX_INPUT_4_SOURCE: + case ARIZONA_AIF1TX4MIX_INPUT_4_VOLUME: + case ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE: + case ARIZONA_AIF1TX5MIX_INPUT_1_VOLUME: + case ARIZONA_AIF1TX5MIX_INPUT_2_SOURCE: + case ARIZONA_AIF1TX5MIX_INPUT_2_VOLUME: + case ARIZONA_AIF1TX5MIX_INPUT_3_SOURCE: + case ARIZONA_AIF1TX5MIX_INPUT_3_VOLUME: + case ARIZONA_AIF1TX5MIX_INPUT_4_SOURCE: + case ARIZONA_AIF1TX5MIX_INPUT_4_VOLUME: + case ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE: + case ARIZONA_AIF1TX6MIX_INPUT_1_VOLUME: + case ARIZONA_AIF1TX6MIX_INPUT_2_SOURCE: + case ARIZONA_AIF1TX6MIX_INPUT_2_VOLUME: + case ARIZONA_AIF1TX6MIX_INPUT_3_SOURCE: + case ARIZONA_AIF1TX6MIX_INPUT_3_VOLUME: + case ARIZONA_AIF1TX6MIX_INPUT_4_SOURCE: + case ARIZONA_AIF1TX6MIX_INPUT_4_VOLUME: + case ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE: + case ARIZONA_AIF1TX7MIX_INPUT_1_VOLUME: + case ARIZONA_AIF1TX7MIX_INPUT_2_SOURCE: + case ARIZONA_AIF1TX7MIX_INPUT_2_VOLUME: + case ARIZONA_AIF1TX7MIX_INPUT_3_SOURCE: + case ARIZONA_AIF1TX7MIX_INPUT_3_VOLUME: + case ARIZONA_AIF1TX7MIX_INPUT_4_SOURCE: + case ARIZONA_AIF1TX7MIX_INPUT_4_VOLUME: + case ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE: + case ARIZONA_AIF1TX8MIX_INPUT_1_VOLUME: + case ARIZONA_AIF1TX8MIX_INPUT_2_SOURCE: + case ARIZONA_AIF1TX8MIX_INPUT_2_VOLUME: + case ARIZONA_AIF1TX8MIX_INPUT_3_SOURCE: + case ARIZONA_AIF1TX8MIX_INPUT_3_VOLUME: + case ARIZONA_AIF1TX8MIX_INPUT_4_SOURCE: + case ARIZONA_AIF1TX8MIX_INPUT_4_VOLUME: + case ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE: + case ARIZONA_AIF2TX1MIX_INPUT_1_VOLUME: + case ARIZONA_AIF2TX1MIX_INPUT_2_SOURCE: + case ARIZONA_AIF2TX1MIX_INPUT_2_VOLUME: + case ARIZONA_AIF2TX1MIX_INPUT_3_SOURCE: + case ARIZONA_AIF2TX1MIX_INPUT_3_VOLUME: + case ARIZONA_AIF2TX1MIX_INPUT_4_SOURCE: + case ARIZONA_AIF2TX1MIX_INPUT_4_VOLUME: + case ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE: + case ARIZONA_AIF2TX2MIX_INPUT_1_VOLUME: + case ARIZONA_AIF2TX2MIX_INPUT_2_SOURCE: + case ARIZONA_AIF2TX2MIX_INPUT_2_VOLUME: + case ARIZONA_AIF2TX2MIX_INPUT_3_SOURCE: + case ARIZONA_AIF2TX2MIX_INPUT_3_VOLUME: + case ARIZONA_AIF2TX2MIX_INPUT_4_SOURCE: + case ARIZONA_AIF2TX2MIX_INPUT_4_VOLUME: + case ARIZONA_AIF2TX3MIX_INPUT_1_SOURCE: + case ARIZONA_AIF2TX3MIX_INPUT_1_VOLUME: + case ARIZONA_AIF2TX3MIX_INPUT_2_SOURCE: + case ARIZONA_AIF2TX3MIX_INPUT_2_VOLUME: + case ARIZONA_AIF2TX3MIX_INPUT_3_SOURCE: + case ARIZONA_AIF2TX3MIX_INPUT_3_VOLUME: + case ARIZONA_AIF2TX3MIX_INPUT_4_SOURCE: + case ARIZONA_AIF2TX3MIX_INPUT_4_VOLUME: + case ARIZONA_AIF2TX4MIX_INPUT_1_SOURCE: + case ARIZONA_AIF2TX4MIX_INPUT_1_VOLUME: + case ARIZONA_AIF2TX4MIX_INPUT_2_SOURCE: + case ARIZONA_AIF2TX4MIX_INPUT_2_VOLUME: + case ARIZONA_AIF2TX4MIX_INPUT_3_SOURCE: + case ARIZONA_AIF2TX4MIX_INPUT_3_VOLUME: + case ARIZONA_AIF2TX4MIX_INPUT_4_SOURCE: + case ARIZONA_AIF2TX4MIX_INPUT_4_VOLUME: + case ARIZONA_AIF2TX5MIX_INPUT_1_SOURCE: + case ARIZONA_AIF2TX5MIX_INPUT_1_VOLUME: + case ARIZONA_AIF2TX5MIX_INPUT_2_SOURCE: + case ARIZONA_AIF2TX5MIX_INPUT_2_VOLUME: + case ARIZONA_AIF2TX5MIX_INPUT_3_SOURCE: + case ARIZONA_AIF2TX5MIX_INPUT_3_VOLUME: + case ARIZONA_AIF2TX5MIX_INPUT_4_SOURCE: + case ARIZONA_AIF2TX5MIX_INPUT_4_VOLUME: + case ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE: + case ARIZONA_AIF2TX6MIX_INPUT_1_VOLUME: + case ARIZONA_AIF2TX6MIX_INPUT_2_SOURCE: + case ARIZONA_AIF2TX6MIX_INPUT_2_VOLUME: + case ARIZONA_AIF2TX6MIX_INPUT_3_SOURCE: + case ARIZONA_AIF2TX6MIX_INPUT_3_VOLUME: + case ARIZONA_AIF2TX6MIX_INPUT_4_SOURCE: + case ARIZONA_AIF2TX6MIX_INPUT_4_VOLUME: + case ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE: + case ARIZONA_AIF3TX1MIX_INPUT_1_VOLUME: + case ARIZONA_AIF3TX1MIX_INPUT_2_SOURCE: + case ARIZONA_AIF3TX1MIX_INPUT_2_VOLUME: + case ARIZONA_AIF3TX1MIX_INPUT_3_SOURCE: + case ARIZONA_AIF3TX1MIX_INPUT_3_VOLUME: + case ARIZONA_AIF3TX1MIX_INPUT_4_SOURCE: + case ARIZONA_AIF3TX1MIX_INPUT_4_VOLUME: + case ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE: + case ARIZONA_AIF3TX2MIX_INPUT_1_VOLUME: + case ARIZONA_AIF3TX2MIX_INPUT_2_SOURCE: + case ARIZONA_AIF3TX2MIX_INPUT_2_VOLUME: + case ARIZONA_AIF3TX2MIX_INPUT_3_SOURCE: + case ARIZONA_AIF3TX2MIX_INPUT_3_VOLUME: + case ARIZONA_AIF3TX2MIX_INPUT_4_SOURCE: + case ARIZONA_AIF3TX2MIX_INPUT_4_VOLUME: + case ARIZONA_EQ1MIX_INPUT_1_SOURCE: + case ARIZONA_EQ1MIX_INPUT_1_VOLUME: + case ARIZONA_EQ1MIX_INPUT_2_SOURCE: + case ARIZONA_EQ1MIX_INPUT_2_VOLUME: + case ARIZONA_EQ1MIX_INPUT_3_SOURCE: + case ARIZONA_EQ1MIX_INPUT_3_VOLUME: + case ARIZONA_EQ1MIX_INPUT_4_SOURCE: + case ARIZONA_EQ1MIX_INPUT_4_VOLUME: + case ARIZONA_EQ2MIX_INPUT_1_SOURCE: + case ARIZONA_EQ2MIX_INPUT_1_VOLUME: + case ARIZONA_EQ2MIX_INPUT_2_SOURCE: + case ARIZONA_EQ2MIX_INPUT_2_VOLUME: + case ARIZONA_EQ2MIX_INPUT_3_SOURCE: + case ARIZONA_EQ2MIX_INPUT_3_VOLUME: + case ARIZONA_EQ2MIX_INPUT_4_SOURCE: + case ARIZONA_EQ2MIX_INPUT_4_VOLUME: + case ARIZONA_DRC1LMIX_INPUT_1_SOURCE: + case ARIZONA_DRC1LMIX_INPUT_1_VOLUME: + case ARIZONA_DRC1LMIX_INPUT_2_SOURCE: + case ARIZONA_DRC1LMIX_INPUT_2_VOLUME: + case ARIZONA_DRC1LMIX_INPUT_3_SOURCE: + case ARIZONA_DRC1LMIX_INPUT_3_VOLUME: + case ARIZONA_DRC1LMIX_INPUT_4_SOURCE: + case ARIZONA_DRC1LMIX_INPUT_4_VOLUME: + case ARIZONA_DRC1RMIX_INPUT_1_SOURCE: + case ARIZONA_DRC1RMIX_INPUT_1_VOLUME: + case ARIZONA_DRC1RMIX_INPUT_2_SOURCE: + case ARIZONA_DRC1RMIX_INPUT_2_VOLUME: + case ARIZONA_DRC1RMIX_INPUT_3_SOURCE: + case ARIZONA_DRC1RMIX_INPUT_3_VOLUME: + case ARIZONA_DRC1RMIX_INPUT_4_SOURCE: + case ARIZONA_DRC1RMIX_INPUT_4_VOLUME: + case ARIZONA_DRC2LMIX_INPUT_1_SOURCE: + case ARIZONA_DRC2LMIX_INPUT_1_VOLUME: + case ARIZONA_DRC2LMIX_INPUT_2_SOURCE: + case ARIZONA_DRC2LMIX_INPUT_2_VOLUME: + case ARIZONA_DRC2LMIX_INPUT_3_SOURCE: + case ARIZONA_DRC2LMIX_INPUT_3_VOLUME: + case ARIZONA_DRC2LMIX_INPUT_4_SOURCE: + case ARIZONA_DRC2LMIX_INPUT_4_VOLUME: + case ARIZONA_DRC2RMIX_INPUT_1_SOURCE: + case ARIZONA_DRC2RMIX_INPUT_1_VOLUME: + case ARIZONA_DRC2RMIX_INPUT_2_SOURCE: + case ARIZONA_DRC2RMIX_INPUT_2_VOLUME: + case ARIZONA_DRC2RMIX_INPUT_3_SOURCE: + case ARIZONA_DRC2RMIX_INPUT_3_VOLUME: + case ARIZONA_DRC2RMIX_INPUT_4_SOURCE: + case ARIZONA_DRC2RMIX_INPUT_4_VOLUME: + case ARIZONA_HPLP1MIX_INPUT_1_SOURCE: + case ARIZONA_HPLP1MIX_INPUT_1_VOLUME: + case ARIZONA_HPLP1MIX_INPUT_2_SOURCE: + case ARIZONA_HPLP1MIX_INPUT_2_VOLUME: + case ARIZONA_HPLP1MIX_INPUT_3_SOURCE: + case ARIZONA_HPLP1MIX_INPUT_3_VOLUME: + case ARIZONA_HPLP1MIX_INPUT_4_SOURCE: + case ARIZONA_HPLP1MIX_INPUT_4_VOLUME: + case ARIZONA_HPLP2MIX_INPUT_1_SOURCE: + case ARIZONA_HPLP2MIX_INPUT_1_VOLUME: + case ARIZONA_HPLP2MIX_INPUT_2_SOURCE: + case ARIZONA_HPLP2MIX_INPUT_2_VOLUME: + case ARIZONA_HPLP2MIX_INPUT_3_SOURCE: + case ARIZONA_HPLP2MIX_INPUT_3_VOLUME: + case ARIZONA_HPLP2MIX_INPUT_4_SOURCE: + case ARIZONA_HPLP2MIX_INPUT_4_VOLUME: + case ARIZONA_HPLP3MIX_INPUT_1_SOURCE: + case ARIZONA_HPLP3MIX_INPUT_1_VOLUME: + case ARIZONA_HPLP3MIX_INPUT_2_SOURCE: + case ARIZONA_HPLP3MIX_INPUT_2_VOLUME: + case ARIZONA_HPLP3MIX_INPUT_3_SOURCE: + case ARIZONA_HPLP3MIX_INPUT_3_VOLUME: + case ARIZONA_HPLP3MIX_INPUT_4_SOURCE: + case ARIZONA_HPLP3MIX_INPUT_4_VOLUME: + case ARIZONA_HPLP4MIX_INPUT_1_SOURCE: + case ARIZONA_HPLP4MIX_INPUT_1_VOLUME: + case ARIZONA_HPLP4MIX_INPUT_2_SOURCE: + case ARIZONA_HPLP4MIX_INPUT_2_VOLUME: + case ARIZONA_HPLP4MIX_INPUT_3_SOURCE: + case ARIZONA_HPLP4MIX_INPUT_3_VOLUME: + case ARIZONA_HPLP4MIX_INPUT_4_SOURCE: + case ARIZONA_HPLP4MIX_INPUT_4_VOLUME: + case ARIZONA_DSP2LMIX_INPUT_1_SOURCE: + case ARIZONA_DSP2LMIX_INPUT_1_VOLUME: + case ARIZONA_DSP2LMIX_INPUT_2_SOURCE: + case ARIZONA_DSP2LMIX_INPUT_2_VOLUME: + case ARIZONA_DSP2LMIX_INPUT_3_SOURCE: + case ARIZONA_DSP2LMIX_INPUT_3_VOLUME: + case ARIZONA_DSP2LMIX_INPUT_4_SOURCE: + case ARIZONA_DSP2LMIX_INPUT_4_VOLUME: + case ARIZONA_DSP2RMIX_INPUT_1_SOURCE: + case ARIZONA_DSP2RMIX_INPUT_1_VOLUME: + case ARIZONA_DSP2RMIX_INPUT_2_SOURCE: + case ARIZONA_DSP2RMIX_INPUT_2_VOLUME: + case ARIZONA_DSP2RMIX_INPUT_3_SOURCE: + case ARIZONA_DSP2RMIX_INPUT_3_VOLUME: + case ARIZONA_DSP2RMIX_INPUT_4_SOURCE: + case ARIZONA_DSP2RMIX_INPUT_4_VOLUME: + case ARIZONA_DSP2AUX1MIX_INPUT_1_SOURCE: + case ARIZONA_DSP2AUX2MIX_INPUT_1_SOURCE: + case ARIZONA_DSP2AUX3MIX_INPUT_1_SOURCE: + case ARIZONA_DSP2AUX4MIX_INPUT_1_SOURCE: + case ARIZONA_DSP2AUX5MIX_INPUT_1_SOURCE: + case ARIZONA_DSP2AUX6MIX_INPUT_1_SOURCE: + case ARIZONA_DSP3LMIX_INPUT_1_SOURCE: + case ARIZONA_DSP3LMIX_INPUT_1_VOLUME: + case ARIZONA_DSP3LMIX_INPUT_2_SOURCE: + case ARIZONA_DSP3LMIX_INPUT_2_VOLUME: + case ARIZONA_DSP3LMIX_INPUT_3_SOURCE: + case ARIZONA_DSP3LMIX_INPUT_3_VOLUME: + case ARIZONA_DSP3LMIX_INPUT_4_SOURCE: + case ARIZONA_DSP3LMIX_INPUT_4_VOLUME: + case ARIZONA_DSP3RMIX_INPUT_1_SOURCE: + case ARIZONA_DSP3RMIX_INPUT_1_VOLUME: + case ARIZONA_DSP3RMIX_INPUT_2_SOURCE: + case ARIZONA_DSP3RMIX_INPUT_2_VOLUME: + case ARIZONA_DSP3RMIX_INPUT_3_SOURCE: + case ARIZONA_DSP3RMIX_INPUT_3_VOLUME: + case ARIZONA_DSP3RMIX_INPUT_4_SOURCE: + case ARIZONA_DSP3RMIX_INPUT_4_VOLUME: + case ARIZONA_DSP3AUX1MIX_INPUT_1_SOURCE: + case ARIZONA_DSP3AUX2MIX_INPUT_1_SOURCE: + case ARIZONA_DSP3AUX3MIX_INPUT_1_SOURCE: + case ARIZONA_DSP3AUX4MIX_INPUT_1_SOURCE: + case ARIZONA_DSP3AUX5MIX_INPUT_1_SOURCE: + case ARIZONA_DSP3AUX6MIX_INPUT_1_SOURCE: + case ARIZONA_ASRC1LMIX_INPUT_1_SOURCE: + case ARIZONA_ASRC1RMIX_INPUT_1_SOURCE: + case ARIZONA_ASRC2LMIX_INPUT_1_SOURCE: + case ARIZONA_ASRC2RMIX_INPUT_1_SOURCE: + case ARIZONA_ISRC1DEC1MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC1DEC2MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC1DEC3MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC1DEC4MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC1INT1MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC1INT2MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC1INT3MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC1INT4MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC2DEC1MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC2DEC2MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC2DEC3MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC2DEC4MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC2INT1MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC2INT2MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC2INT3MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC2INT4MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC3DEC1MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC3DEC2MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC3DEC3MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC3DEC4MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC3INT1MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC3INT2MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC3INT3MIX_INPUT_1_SOURCE: + case ARIZONA_ISRC3INT4MIX_INPUT_1_SOURCE: + case ARIZONA_GPIO1_CTRL: + case ARIZONA_GPIO2_CTRL: + case ARIZONA_IRQ_CTRL_1: + case ARIZONA_GPIO_DEBOUNCE_CONFIG: + case ARIZONA_MISC_PAD_CTRL_1: + case ARIZONA_MISC_PAD_CTRL_2: + case ARIZONA_MISC_PAD_CTRL_3: + case ARIZONA_MISC_PAD_CTRL_4: + case ARIZONA_MISC_PAD_CTRL_5: + case ARIZONA_MISC_PAD_CTRL_6: + case ARIZONA_MISC_PAD_CTRL_7: + case ARIZONA_MISC_PAD_CTRL_9: + case ARIZONA_MISC_PAD_CTRL_10: + case ARIZONA_MISC_PAD_CTRL_11: + case ARIZONA_MISC_PAD_CTRL_12: + case ARIZONA_MISC_PAD_CTRL_13: + case ARIZONA_MISC_PAD_CTRL_14: + case ARIZONA_MISC_PAD_CTRL_16: + case ARIZONA_INTERRUPT_STATUS_1: + case ARIZONA_INTERRUPT_STATUS_2: + case ARIZONA_INTERRUPT_STATUS_3: + case ARIZONA_INTERRUPT_STATUS_4: + case ARIZONA_INTERRUPT_STATUS_5: + case ARIZONA_INTERRUPT_STATUS_6: + case ARIZONA_INTERRUPT_STATUS_1_MASK: + case ARIZONA_INTERRUPT_STATUS_2_MASK: + case ARIZONA_INTERRUPT_STATUS_3_MASK: + case ARIZONA_INTERRUPT_STATUS_4_MASK: + case ARIZONA_INTERRUPT_STATUS_5_MASK: + case ARIZONA_INTERRUPT_STATUS_6_MASK: + case ARIZONA_INTERRUPT_CONTROL: + case ARIZONA_IRQ2_STATUS_1: + case ARIZONA_IRQ2_STATUS_2: + case ARIZONA_IRQ2_STATUS_3: + case ARIZONA_IRQ2_STATUS_4: + case ARIZONA_IRQ2_STATUS_5: + case ARIZONA_IRQ2_STATUS_6: + case ARIZONA_IRQ2_STATUS_1_MASK: + case ARIZONA_IRQ2_STATUS_2_MASK: + case ARIZONA_IRQ2_STATUS_3_MASK: + case ARIZONA_IRQ2_STATUS_4_MASK: + case ARIZONA_IRQ2_STATUS_5_MASK: + case ARIZONA_IRQ2_STATUS_6_MASK: + case ARIZONA_IRQ2_CONTROL: + case ARIZONA_INTERRUPT_RAW_STATUS_2: + case ARIZONA_INTERRUPT_RAW_STATUS_3: + case ARIZONA_INTERRUPT_RAW_STATUS_4: + case ARIZONA_INTERRUPT_RAW_STATUS_5: + case ARIZONA_INTERRUPT_RAW_STATUS_6: + case ARIZONA_INTERRUPT_RAW_STATUS_7: + case ARIZONA_INTERRUPT_RAW_STATUS_8: + case ARIZONA_INTERRUPT_RAW_STATUS_9: + case ARIZONA_IRQ_PIN_STATUS: + case ARIZONA_FX_CTRL1: + case ARIZONA_FX_CTRL2: + case ARIZONA_EQ1_1: + case ARIZONA_EQ1_2: + case ARIZONA_EQ1_3: + case ARIZONA_EQ1_4: + case ARIZONA_EQ1_5: + case ARIZONA_EQ1_6: + case ARIZONA_EQ1_7: + case ARIZONA_EQ1_8: + case ARIZONA_EQ1_9: + case ARIZONA_EQ1_10: + case ARIZONA_EQ1_11: + case ARIZONA_EQ1_12: + case ARIZONA_EQ1_13: + case ARIZONA_EQ1_14: + case ARIZONA_EQ1_15: + case ARIZONA_EQ1_16: + case ARIZONA_EQ1_17: + case ARIZONA_EQ1_18: + case ARIZONA_EQ1_19: + case ARIZONA_EQ1_20: + case ARIZONA_EQ1_21: + case ARIZONA_EQ2_1: + case ARIZONA_EQ2_2: + case ARIZONA_EQ2_3: + case ARIZONA_EQ2_4: + case ARIZONA_EQ2_5: + case ARIZONA_EQ2_6: + case ARIZONA_EQ2_7: + case ARIZONA_EQ2_8: + case ARIZONA_EQ2_9: + case ARIZONA_EQ2_10: + case ARIZONA_EQ2_11: + case ARIZONA_EQ2_12: + case ARIZONA_EQ2_13: + case ARIZONA_EQ2_14: + case ARIZONA_EQ2_15: + case ARIZONA_EQ2_16: + case ARIZONA_EQ2_17: + case ARIZONA_EQ2_18: + case ARIZONA_EQ2_19: + case ARIZONA_EQ2_20: + case ARIZONA_EQ2_21: + case ARIZONA_DRC1_CTRL1: + case ARIZONA_DRC1_CTRL2: + case ARIZONA_DRC1_CTRL3: + case ARIZONA_DRC1_CTRL4: + case ARIZONA_DRC1_CTRL5: + case ARIZONA_DRC2_CTRL1: + case ARIZONA_DRC2_CTRL2: + case ARIZONA_DRC2_CTRL3: + case ARIZONA_DRC2_CTRL4: + case ARIZONA_DRC2_CTRL5: + case ARIZONA_HPLPF1_1: + case ARIZONA_HPLPF1_2: + case ARIZONA_HPLPF2_1: + case ARIZONA_HPLPF2_2: + case ARIZONA_HPLPF3_1: + case ARIZONA_HPLPF3_2: + case ARIZONA_HPLPF4_1: + case ARIZONA_HPLPF4_2: + case ARIZONA_ASRC_ENABLE: + case ARIZONA_ASRC_STATUS: + case ARIZONA_ASRC_RATE1: + case ARIZONA_ASRC_RATE2: + case ARIZONA_ISRC_1_CTRL_1: + case ARIZONA_ISRC_1_CTRL_2: + case ARIZONA_ISRC_1_CTRL_3: + case ARIZONA_ISRC_2_CTRL_1: + case ARIZONA_ISRC_2_CTRL_2: + case ARIZONA_ISRC_2_CTRL_3: + case ARIZONA_ISRC_3_CTRL_1: + case ARIZONA_ISRC_3_CTRL_2: + case ARIZONA_ISRC_3_CTRL_3: + case ARIZONA_DSP2_CONTROL_1: + case ARIZONA_DSP2_CLOCKING_1: + case ARIZONA_DSP2_STATUS_1: + case ARIZONA_DSP2_STATUS_2: + case ARIZONA_DSP2_STATUS_3: + case ARIZONA_DSP2_STATUS_4: + case ARIZONA_DSP2_WDMA_BUFFER_1: + case ARIZONA_DSP2_WDMA_BUFFER_2: + case ARIZONA_DSP2_WDMA_BUFFER_3: + case ARIZONA_DSP2_WDMA_BUFFER_4: + case ARIZONA_DSP2_WDMA_BUFFER_5: + case ARIZONA_DSP2_WDMA_BUFFER_6: + case ARIZONA_DSP2_WDMA_BUFFER_7: + case ARIZONA_DSP2_WDMA_BUFFER_8: + case ARIZONA_DSP2_RDMA_BUFFER_1: + case ARIZONA_DSP2_RDMA_BUFFER_2: + case ARIZONA_DSP2_RDMA_BUFFER_3: + case ARIZONA_DSP2_RDMA_BUFFER_4: + case ARIZONA_DSP2_RDMA_BUFFER_5: + case ARIZONA_DSP2_RDMA_BUFFER_6: + case ARIZONA_DSP2_WDMA_CONFIG_1: + case ARIZONA_DSP2_WDMA_CONFIG_2: + case ARIZONA_DSP2_WDMA_OFFSET_1: + case ARIZONA_DSP2_RDMA_CONFIG_1: + case ARIZONA_DSP2_RDMA_OFFSET_1: + case ARIZONA_DSP2_EXTERNAL_START_SELECT_1: + case ARIZONA_DSP2_SCRATCH_0: + case ARIZONA_DSP2_SCRATCH_1: + case ARIZONA_DSP2_SCRATCH_2: + case ARIZONA_DSP2_SCRATCH_3: + case ARIZONA_DSP3_CONTROL_1: + case ARIZONA_DSP3_CLOCKING_1: + case ARIZONA_DSP3_STATUS_1: + case ARIZONA_DSP3_STATUS_2: + case ARIZONA_DSP3_STATUS_3: + case ARIZONA_DSP3_STATUS_4: + case ARIZONA_DSP3_WDMA_BUFFER_1: + case ARIZONA_DSP3_WDMA_BUFFER_2: + case ARIZONA_DSP3_WDMA_BUFFER_3: + case ARIZONA_DSP3_WDMA_BUFFER_4: + case ARIZONA_DSP3_WDMA_BUFFER_5: + case ARIZONA_DSP3_WDMA_BUFFER_6: + case ARIZONA_DSP3_WDMA_BUFFER_7: + case ARIZONA_DSP3_WDMA_BUFFER_8: + case ARIZONA_DSP3_RDMA_BUFFER_1: + case ARIZONA_DSP3_RDMA_BUFFER_2: + case ARIZONA_DSP3_RDMA_BUFFER_3: + case ARIZONA_DSP3_RDMA_BUFFER_4: + case ARIZONA_DSP3_RDMA_BUFFER_5: + case ARIZONA_DSP3_RDMA_BUFFER_6: + case ARIZONA_DSP3_WDMA_CONFIG_1: + case ARIZONA_DSP3_WDMA_CONFIG_2: + case ARIZONA_DSP3_WDMA_OFFSET_1: + case ARIZONA_DSP3_RDMA_CONFIG_1: + case ARIZONA_DSP3_RDMA_OFFSET_1: + case ARIZONA_DSP3_EXTERNAL_START_SELECT_1: + case ARIZONA_DSP3_SCRATCH_0: + case ARIZONA_DSP3_SCRATCH_1: + case ARIZONA_DSP3_SCRATCH_2: + case ARIZONA_DSP3_SCRATCH_3: + return true; + default: + return cs47l24_is_adsp_memory(reg); + } +} + +static bool cs47l24_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case ARIZONA_SOFTWARE_RESET: + case ARIZONA_DEVICE_REVISION: + case ARIZONA_WRITE_SEQUENCER_CTRL_0: + case ARIZONA_WRITE_SEQUENCER_CTRL_1: + case ARIZONA_WRITE_SEQUENCER_CTRL_2: + case ARIZONA_HAPTICS_STATUS: + case ARIZONA_SAMPLE_RATE_1_STATUS: + case ARIZONA_SAMPLE_RATE_2_STATUS: + case ARIZONA_SAMPLE_RATE_3_STATUS: + case ARIZONA_ASYNC_SAMPLE_RATE_1_STATUS: + case ARIZONA_ASYNC_SAMPLE_RATE_2_STATUS: + case ARIZONA_HP_CTRL_1L: + case ARIZONA_HP_CTRL_1R: + case ARIZONA_INPUT_ENABLES_STATUS: + case ARIZONA_OUTPUT_STATUS_1: + case ARIZONA_RAW_OUTPUT_STATUS_1: + case ARIZONA_INTERRUPT_STATUS_1: + case ARIZONA_INTERRUPT_STATUS_2: + case ARIZONA_INTERRUPT_STATUS_3: + case ARIZONA_INTERRUPT_STATUS_4: + case ARIZONA_INTERRUPT_STATUS_5: + case ARIZONA_INTERRUPT_STATUS_6: + case ARIZONA_IRQ2_STATUS_1: + case ARIZONA_IRQ2_STATUS_2: + case ARIZONA_IRQ2_STATUS_3: + case ARIZONA_IRQ2_STATUS_4: + case ARIZONA_IRQ2_STATUS_5: + case ARIZONA_IRQ2_STATUS_6: + case ARIZONA_INTERRUPT_RAW_STATUS_2: + case ARIZONA_INTERRUPT_RAW_STATUS_3: + case ARIZONA_INTERRUPT_RAW_STATUS_4: + case ARIZONA_INTERRUPT_RAW_STATUS_5: + case ARIZONA_INTERRUPT_RAW_STATUS_6: + case ARIZONA_INTERRUPT_RAW_STATUS_7: + case ARIZONA_INTERRUPT_RAW_STATUS_8: + case ARIZONA_INTERRUPT_RAW_STATUS_9: + case ARIZONA_IRQ_PIN_STATUS: + case ARIZONA_FX_CTRL2: + case ARIZONA_ASRC_STATUS: + case ARIZONA_DSP2_STATUS_1: + case ARIZONA_DSP2_STATUS_2: + case ARIZONA_DSP2_STATUS_3: + case ARIZONA_DSP2_STATUS_4: + case ARIZONA_DSP2_WDMA_BUFFER_1: + case ARIZONA_DSP2_WDMA_BUFFER_2: + case ARIZONA_DSP2_WDMA_BUFFER_3: + case ARIZONA_DSP2_WDMA_BUFFER_4: + case ARIZONA_DSP2_WDMA_BUFFER_5: + case ARIZONA_DSP2_WDMA_BUFFER_6: + case ARIZONA_DSP2_WDMA_BUFFER_7: + case ARIZONA_DSP2_WDMA_BUFFER_8: + case ARIZONA_DSP2_RDMA_BUFFER_1: + case ARIZONA_DSP2_RDMA_BUFFER_2: + case ARIZONA_DSP2_RDMA_BUFFER_3: + case ARIZONA_DSP2_RDMA_BUFFER_4: + case ARIZONA_DSP2_RDMA_BUFFER_5: + case ARIZONA_DSP2_RDMA_BUFFER_6: + case ARIZONA_DSP2_WDMA_CONFIG_1: + case ARIZONA_DSP2_WDMA_CONFIG_2: + case ARIZONA_DSP2_WDMA_OFFSET_1: + case ARIZONA_DSP2_RDMA_CONFIG_1: + case ARIZONA_DSP2_RDMA_OFFSET_1: + case ARIZONA_DSP2_EXTERNAL_START_SELECT_1: + case ARIZONA_DSP2_SCRATCH_0: + case ARIZONA_DSP2_SCRATCH_1: + case ARIZONA_DSP2_SCRATCH_2: + case ARIZONA_DSP2_SCRATCH_3: + case ARIZONA_DSP2_CLOCKING_1: + case ARIZONA_DSP3_STATUS_1: + case ARIZONA_DSP3_STATUS_2: + case ARIZONA_DSP3_STATUS_3: + case ARIZONA_DSP3_STATUS_4: + case ARIZONA_DSP3_WDMA_BUFFER_1: + case ARIZONA_DSP3_WDMA_BUFFER_2: + case ARIZONA_DSP3_WDMA_BUFFER_3: + case ARIZONA_DSP3_WDMA_BUFFER_4: + case ARIZONA_DSP3_WDMA_BUFFER_5: + case ARIZONA_DSP3_WDMA_BUFFER_6: + case ARIZONA_DSP3_WDMA_BUFFER_7: + case ARIZONA_DSP3_WDMA_BUFFER_8: + case ARIZONA_DSP3_RDMA_BUFFER_1: + case ARIZONA_DSP3_RDMA_BUFFER_2: + case ARIZONA_DSP3_RDMA_BUFFER_3: + case ARIZONA_DSP3_RDMA_BUFFER_4: + case ARIZONA_DSP3_RDMA_BUFFER_5: + case ARIZONA_DSP3_RDMA_BUFFER_6: + case ARIZONA_DSP3_WDMA_CONFIG_1: + case ARIZONA_DSP3_WDMA_CONFIG_2: + case ARIZONA_DSP3_WDMA_OFFSET_1: + case ARIZONA_DSP3_RDMA_CONFIG_1: + case ARIZONA_DSP3_RDMA_OFFSET_1: + case ARIZONA_DSP3_EXTERNAL_START_SELECT_1: + case ARIZONA_DSP3_SCRATCH_0: + case ARIZONA_DSP3_SCRATCH_1: + case ARIZONA_DSP3_SCRATCH_2: + case ARIZONA_DSP3_SCRATCH_3: + case ARIZONA_DSP3_CLOCKING_1: + return true; + default: + return cs47l24_is_adsp_memory(reg); + } +} + +#define CS47L24_MAX_REGISTER 0x3b3fff + +const struct regmap_config cs47l24_spi_regmap = { + .reg_bits = 32, + .pad_bits = 16, + .val_bits = 16, + .reg_format_endian = REGMAP_ENDIAN_BIG, + .val_format_endian = REGMAP_ENDIAN_BIG, + + .max_register = CS47L24_MAX_REGISTER, + .readable_reg = cs47l24_readable_register, + .volatile_reg = cs47l24_volatile_register, + + .cache_type = REGCACHE_RBTREE, + .reg_defaults = cs47l24_reg_default, + .num_reg_defaults = ARRAY_SIZE(cs47l24_reg_default), +}; +EXPORT_SYMBOL_GPL(cs47l24_spi_regmap); + diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h index 79e607e2f0819..d55a42297d491 100644 --- a/include/linux/mfd/arizona/core.h +++ b/include/linux/mfd/arizona/core.h @@ -27,6 +27,8 @@ enum arizona_type { WM8280 = 4, WM8998 = 5, WM1814 = 6, + WM1831 = 7, + CS47L24 = 8, }; #define ARIZONA_IRQ_GP1 0 @@ -166,6 +168,7 @@ static inline int wm5102_patch(struct arizona *arizona) #endif int wm5110_patch(struct arizona *arizona); +int cs47l24_patch(struct arizona *arizona); int wm8997_patch(struct arizona *arizona); int wm8998_patch(struct arizona *arizona); -- GitLab From 12ebc1370766e85253f0db4b21e77d5ffca4abed Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Tue, 3 Nov 2015 15:08:36 +0000 Subject: [PATCH 0917/2855] MAINTAINERS: Update Wolfson Micro section to include CS47L24 source The CS47L24 source is part of the ex-Wolfson "Arizona" group of drivers. Not all cs47lxx devices are part of the Arizona driver group so the cs47l24 is explicitly listed by its full part number. Signed-off-by: Richard Fitzgerald Signed-off-by: Lee Jones --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 050d0e77a2cf0..25b727556dc77 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11671,6 +11671,7 @@ F: drivers/input/touchscreen/wm831x-ts.c F: drivers/input/touchscreen/wm97*.c F: drivers/mfd/arizona* F: drivers/mfd/wm*.c +F: drivers/mfd/cs47l24* F: drivers/power/wm83*.c F: drivers/rtc/rtc-wm83*.c F: drivers/regulator/wm8*.c @@ -11684,6 +11685,7 @@ F: include/linux/wm97xx.h F: include/sound/wm????.h F: sound/soc/codecs/arizona.? F: sound/soc/codecs/wm* +F: sound/soc/codecs/cs47l24* WORKQUEUE M: Tejun Heo -- GitLab From 9f6aa42bbbb23d2115704c5044da951a7e685cc5 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 3 Dec 2015 23:23:24 -0200 Subject: [PATCH 0918/2855] spi: imx: Add loopback mode support Loopback mode can be activated by setting bit LBC (LoopBack Control) of register ECSPI_TESTREG. Add support for it. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 0e5723ab47f0c..e7e4f0c0f14d8 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -244,6 +244,9 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, #define MX51_ECSPI_STAT 0x18 #define MX51_ECSPI_STAT_RR (1 << 3) +#define MX51_ECSPI_TESTREG 0x20 +#define MX51_ECSPI_TESTREG_LBC BIT(31) + /* MX51 eCSPI */ static unsigned int mx51_ecspi_clkdiv(unsigned int fin, unsigned int fspi, unsigned int *fres) @@ -313,7 +316,7 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, { u32 ctrl = MX51_ECSPI_CTRL_ENABLE, cfg = 0, dma = 0; u32 tx_wml_cfg, rx_wml_cfg, rxt_wml_cfg; - u32 clk = config->speed_hz, delay; + u32 clk = config->speed_hz, delay, reg; /* * The hardware seems to have a race condition when changing modes. The @@ -351,6 +354,13 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, else cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(config->cs); + reg = readl(spi_imx->base + MX51_ECSPI_TESTREG); + if (config->mode & SPI_LOOP) + reg |= MX51_ECSPI_TESTREG_LBC; + else + reg &= ~MX51_ECSPI_TESTREG_LBC; + writel(reg, spi_imx->base + MX51_ECSPI_TESTREG); + writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG); @@ -1141,7 +1151,8 @@ static int spi_imx_probe(struct platform_device *pdev) spi_imx->bitbang.master->cleanup = spi_imx_cleanup; spi_imx->bitbang.master->prepare_message = spi_imx_prepare_message; spi_imx->bitbang.master->unprepare_message = spi_imx_unprepare_message; - spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; + spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | + SPI_LOOP; init_completion(&spi_imx->xfer_done); -- GitLab From 50acb9a6a6167235a86d2d549a865af883347672 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Thu, 3 Dec 2015 18:29:53 +0530 Subject: [PATCH 0919/2855] spi: lm70llp: remove multiple blank lines checkpatch complains about multiple blank lines. Signed-off-by: Sudip Mukherjee Signed-off-by: Mark Brown --- drivers/spi/spi-lm70llp.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/spi/spi-lm70llp.c b/drivers/spi/spi-lm70llp.c index ba72347cb99d9..eb4b4218ee7d1 100644 --- a/drivers/spi/spi-lm70llp.c +++ b/drivers/spi/spi-lm70llp.c @@ -23,11 +23,9 @@ #include #include - #include #include - /* * The LM70 communicates with a host processor using a 3-wire variant of * the SPI/Microwire bus interface. This driver specifically supports an @@ -88,7 +86,6 @@ struct spi_lm70llp { /* REVISIT : ugly global ; provides "exclusive open" facility */ static struct spi_lm70llp *lm70llp; - /*-------------------------------------------------------------------*/ static inline struct spi_lm70llp *spidev_to_pp(struct spi_device *spi) @@ -319,7 +316,6 @@ static void spi_lm70llp_detach(struct parport *p) lm70llp = NULL; } - static struct parport_driver spi_lm70llp_drv = { .name = DRVNAME, .attach = spi_lm70llp_attach, -- GitLab From 832329d75a854863c99724193d9619aec1e68368 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Thu, 3 Dec 2015 18:29:54 +0530 Subject: [PATCH 0920/2855] spi: lm70llp: add blank line after declaration checkpatch complains about missing blank line after declaration. Signed-off-by: Sudip Mukherjee Signed-off-by: Mark Brown --- drivers/spi/spi-lm70llp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/spi/spi-lm70llp.c b/drivers/spi/spi-lm70llp.c index eb4b4218ee7d1..70370288dfed9 100644 --- a/drivers/spi/spi-lm70llp.c +++ b/drivers/spi/spi-lm70llp.c @@ -119,12 +119,14 @@ static inline void assertCS(struct spi_lm70llp *pp) static inline void clkHigh(struct spi_lm70llp *pp) { u8 data = parport_read_data(pp->port); + parport_write_data(pp->port, data | SCLK); } static inline void clkLow(struct spi_lm70llp *pp) { u8 data = parport_read_data(pp->port); + parport_write_data(pp->port, data & ~SCLK); } @@ -163,8 +165,10 @@ static inline void setmosi(struct spi_device *s, int is_on) static inline int getmiso(struct spi_device *s) { struct spi_lm70llp *pp = spidev_to_pp(s); + return ((SIO == (parport_read_status(pp->port) & SIO)) ? 0 : 1 ); } + /*--------------------------------------------------------------------*/ #include "spi-bitbang-txrx.h" -- GitLab From 25fb1a46e0f707b7660a96703843e66dd46f67ae Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Thu, 3 Dec 2015 18:29:55 +0530 Subject: [PATCH 0921/2855] spi: lm70llp: remove cast to void checkpatch was complaining about space after cast. But the cast to void is not required at that place. Signed-off-by: Sudip Mukherjee Signed-off-by: Mark Brown --- drivers/spi/spi-lm70llp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-lm70llp.c b/drivers/spi/spi-lm70llp.c index 70370288dfed9..133e76c38c54a 100644 --- a/drivers/spi/spi-lm70llp.c +++ b/drivers/spi/spi-lm70llp.c @@ -294,7 +294,7 @@ out_off_and_release: out_parport_unreg: parport_unregister_device(pd); out_free_master: - (void) spi_master_put(master); + spi_master_put(master); out_fail: pr_info("%s: spi_lm70llp probe fail, status %d\n", DRVNAME, status); } @@ -315,7 +315,7 @@ static void spi_lm70llp_detach(struct parport *p) parport_release(pp->pd); parport_unregister_device(pp->pd); - (void) spi_master_put(pp->bitbang.master); + spi_master_put(pp->bitbang.master); lm70llp = NULL; } -- GitLab From 44dc0fddd78c36160a2887767ab3f02a9a36a23f Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Thu, 3 Dec 2015 18:29:56 +0530 Subject: [PATCH 0922/2855] spi: lm70llp: correct alignment checkpatch complains about the allignment with open parenthesis. Signed-off-by: Sudip Mukherjee Signed-off-by: Mark Brown --- drivers/spi/spi-lm70llp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-lm70llp.c b/drivers/spi/spi-lm70llp.c index 133e76c38c54a..5f526ce7cfd0c 100644 --- a/drivers/spi/spi-lm70llp.c +++ b/drivers/spi/spi-lm70llp.c @@ -229,8 +229,8 @@ static void spi_lm70llp_attach(struct parport *p) */ pp->port = p; pd = parport_register_device(p, DRVNAME, - NULL, NULL, NULL, - PARPORT_FLAG_EXCL, pp); + NULL, NULL, NULL, + PARPORT_FLAG_EXCL, pp); if (!pd) { status = -ENOMEM; goto out_free_master; @@ -273,7 +273,7 @@ static void spi_lm70llp_attach(struct parport *p) pp->spidev_lm70 = spi_new_device(pp->bitbang.master, &pp->info); if (pp->spidev_lm70) dev_dbg(&pp->spidev_lm70->dev, "spidev_lm70 at %s\n", - dev_name(&pp->spidev_lm70->dev)); + dev_name(&pp->spidev_lm70->dev)); else { printk(KERN_WARNING "%s: spi_new_device failed\n", DRVNAME); status = -ENODEV; -- GitLab From 74bdced4b4ea8025d36880b923be16592d294c8e Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Thu, 3 Dec 2015 18:29:57 +0530 Subject: [PATCH 0923/2855] spi: lm70llp: remove space checkpatch complains about space before closing brace. Signed-off-by: Sudip Mukherjee Signed-off-by: Mark Brown --- drivers/spi/spi-lm70llp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-lm70llp.c b/drivers/spi/spi-lm70llp.c index 5f526ce7cfd0c..62d0f6dbbe454 100644 --- a/drivers/spi/spi-lm70llp.c +++ b/drivers/spi/spi-lm70llp.c @@ -166,7 +166,7 @@ static inline int getmiso(struct spi_device *s) { struct spi_lm70llp *pp = spidev_to_pp(s); - return ((SIO == (parport_read_status(pp->port) & SIO)) ? 0 : 1 ); + return ((SIO == (parport_read_status(pp->port) & SIO)) ? 0 : 1); } /*--------------------------------------------------------------------*/ -- GitLab From 2baed30cb30727b2637d26eac5a8887875a13420 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Thu, 3 Dec 2015 18:29:59 +0530 Subject: [PATCH 0924/2855] spi: lm70llp: use new parport device model Modify spi-lm70llp driver to use the new parallel port device model. Signed-off-by: Sudip Mukherjee Signed-off-by: Mark Brown --- drivers/spi/spi-lm70llp.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-lm70llp.c b/drivers/spi/spi-lm70llp.c index 62d0f6dbbe454..ef829081abd7c 100644 --- a/drivers/spi/spi-lm70llp.c +++ b/drivers/spi/spi-lm70llp.c @@ -197,6 +197,7 @@ static void spi_lm70llp_attach(struct parport *p) struct spi_lm70llp *pp; struct spi_master *master; int status; + struct pardev_cb lm70llp_cb; if (lm70llp) { printk(KERN_WARNING @@ -228,9 +229,11 @@ static void spi_lm70llp_attach(struct parport *p) * Parport hookup */ pp->port = p; - pd = parport_register_device(p, DRVNAME, - NULL, NULL, NULL, - PARPORT_FLAG_EXCL, pp); + memset(&lm70llp_cb, 0, sizeof(lm70llp_cb)); + lm70llp_cb.private = pp; + lm70llp_cb.flags = PARPORT_FLAG_EXCL; + pd = parport_register_dev_model(p, DRVNAME, &lm70llp_cb, 0); + if (!pd) { status = -ENOMEM; goto out_free_master; @@ -322,8 +325,9 @@ static void spi_lm70llp_detach(struct parport *p) static struct parport_driver spi_lm70llp_drv = { .name = DRVNAME, - .attach = spi_lm70llp_attach, + .match_port = spi_lm70llp_attach, .detach = spi_lm70llp_detach, + .devmodel = true, }; static int __init init_spi_lm70llp(void) -- GitLab From 6b82b1223e3b14afd89d167795671a9f4f77b2f0 Mon Sep 17 00:00:00 2001 From: Al Cooper Date: Wed, 2 Dec 2015 14:55:07 -0500 Subject: [PATCH 0925/2855] usb: Add connected retry on resume for non SS devices Currently usb_port_resume waits for up to 2 seconds for CONNECT status for SS devices only. This change will do the same thing for non-SS devices even though the reason is a little different. This will fix an issue where VBUS is turned off during system wide "suspend to ram" and some 2.0 devices take greater than the current max of 100ms to show connected after VBUS is enabled. This is most commonly seen on hard drive based devices and USB3.0 devices plugged into a 2.0 only port. Signed-off-by: Al Cooper Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index db7683e2d34c6..679b2ce014080 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3304,7 +3304,7 @@ static int finish_port_resume(struct usb_device *udev) /* * There are some SS USB devices which take longer time for link training. * XHCI specs 4.19.4 says that when Link training is successful, port - * sets CSC bit to 1. So if SW reads port status before successful link + * sets CCS bit to 1. So if SW reads port status before successful link * training, then it will not find device to be present. * USB Analyzer log with such buggy devices show that in some cases * device switch on the RX termination after long delay of host enabling @@ -3315,14 +3315,17 @@ static int finish_port_resume(struct usb_device *udev) * routine implements a 2000 ms timeout for link training. If in a case * link trains before timeout, loop will exit earlier. * + * There are also some 2.0 hard drive based devices and 3.0 thumb + * drives that, when plugged into a 2.0 only port, take a long + * time to set CCS after VBUS enable. + * * FIXME: If a device was connected before suspend, but was removed * while system was asleep, then the loop in the following routine will * only exit at timeout. * - * This routine should only be called when persist is enabled for a SS - * device. + * This routine should only be called when persist is enabled. */ -static int wait_for_ss_port_enable(struct usb_device *udev, +static int wait_for_connected(struct usb_device *udev, struct usb_hub *hub, int *port1, u16 *portchange, u16 *portstatus) { @@ -3335,6 +3338,7 @@ static int wait_for_ss_port_enable(struct usb_device *udev, delay_ms += 20; status = hub_port_status(hub, *port1, portstatus, portchange); } + dev_dbg(&udev->dev, "Waited %dms for CONNECT\n", delay_ms); return status; } @@ -3434,8 +3438,8 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) } } - if (udev->persist_enabled && hub_is_superspeed(hub->hdev)) - status = wait_for_ss_port_enable(udev, hub, &port1, &portchange, + if (udev->persist_enabled) + status = wait_for_connected(udev, hub, &port1, &portchange, &portstatus); status = check_port_resume_type(udev, -- GitLab From 2d80b52efe30b823b9b52521811fbfdd23b05648 Mon Sep 17 00:00:00 2001 From: "Geyslan G. Bem" Date: Wed, 2 Dec 2015 18:45:47 -0300 Subject: [PATCH 0926/2855] usb: whci: fhci: remove comparison to bool Get rid of bool explicit comparisons. Caught by Coccinelle. Signed-off-by: Geyslan G. Bem Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/fhci-tds.c | 2 +- drivers/usb/host/whci/qset.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c index 1498061f0aea8..f82ad5df1b0de 100644 --- a/drivers/usb/host/fhci-tds.c +++ b/drivers/usb/host/fhci-tds.c @@ -85,7 +85,7 @@ static struct usb_td __iomem *next_bd(struct usb_td __iomem *base, void fhci_push_dummy_bd(struct endpoint *ep) { - if (ep->already_pushed_dummy_bd == false) { + if (!ep->already_pushed_dummy_bd) { u16 td_status = in_be16(&ep->empty_td->status); out_be32(&ep->empty_td->buf_ptr, DUMMY_BD_BUFFER); diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c index 329747398f9ac..5e48a605c71eb 100644 --- a/drivers/usb/host/whci/qset.c +++ b/drivers/usb/host/whci/qset.c @@ -395,7 +395,7 @@ static void urb_dequeue_work(struct work_struct *work) struct whc *whc = qset->whc; unsigned long flags; - if (wurb->is_async == true) + if (wurb->is_async) asl_update(whc, WUSBCMD_ASYNC_UPDATED | WUSBCMD_ASYNC_SYNCED_DB | WUSBCMD_ASYNC_QSET_RM); -- GitLab From debe26af03497eeea3ac06bff21176c9732cd54a Mon Sep 17 00:00:00 2001 From: "Geyslan G. Bem" Date: Wed, 2 Dec 2015 19:18:19 -0300 Subject: [PATCH 0927/2855] usb: use BUG_ON() instead of BUG() Replace BUG() with BUG_ON(). Caught by coccinelle. Signed-off-by: Geyslan G. Bem Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/oxu210hp-hcd.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index 1f139d82cee08..bc74aca8a54c2 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -394,8 +394,7 @@ static void ehci_quiesce(struct oxu_hcd *oxu) u32 temp; #ifdef DEBUG - if (!HC_IS_RUNNING(oxu_to_hcd(oxu)->state)) - BUG(); + BUG_ON(!HC_IS_RUNNING(oxu_to_hcd(oxu)->state)); #endif /* wait for any schedule enables/disables to take effect */ @@ -1709,9 +1708,8 @@ static void start_unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh) #ifdef DEBUG assert_spin_locked(&oxu->lock); - if (oxu->reclaim || (qh->qh_state != QH_STATE_LINKED - && qh->qh_state != QH_STATE_UNLINK_WAIT)) - BUG(); + BUG_ON(oxu->reclaim || (qh->qh_state != QH_STATE_LINKED + && qh->qh_state != QH_STATE_UNLINK_WAIT)); #endif /* stop async schedule right now? */ -- GitLab From 40d581489adbb44a2d1005867d7a7695d61110e6 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 3 Dec 2015 15:03:32 +0100 Subject: [PATCH 0928/2855] Documentation: nousb is a module parameter The documentation wrongly implied that it is a core parameter. That is not true. If usbcore is compiled as a module, a module parameter needs a prefix. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- Documentation/kernel-parameters.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index e6b6e056cc115..fd333fbfd2ab3 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2575,8 +2575,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. notsc [BUGS=X86-32] Disable Time Stamp Counter - nousb [USB] Disable the USB subsystem - nowatchdog [KNL] Disable both lockup detectors, i.e. soft-lockup and NMI watchdog (hard-lockup). @@ -3898,6 +3896,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. USB_REQ_GET_DESCRIPTOR request in milliseconds (default 5000 = 5.0 seconds). + usbcore.nousb [USB] Disable the USB subsystem + usbhid.mousepoll= [USBHID] The interval which mice are to be polled at. -- GitLab From 097a9ea0e48fa33159ad47d1dc9ef3b215bfc090 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 3 Dec 2015 15:03:33 +0100 Subject: [PATCH 0929/2855] usb: make "nousb" a clear module parameter It shouldn't matter how usbcore is compiled. As it is a subsystem, the correct way to use nousb should be usbcore.nousb Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/usb.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index f8bbd0b6d9fe4..77e4c9bc0ab1f 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -49,12 +49,7 @@ const char *usbcore_name = "usbcore"; static bool nousb; /* Disable USB when built into kernel image */ -/* To disable USB, kernel command line is 'nousb' not 'usbcore.nousb' */ -#ifdef MODULE module_param(nousb, bool, 0444); -#else -core_param(nousb, nousb, bool, 0444); -#endif /* * for external read access to -- GitLab From 1eaf35e4dd592c59041bc1ed3248c46326da1f5f Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 3 Dec 2015 15:03:34 +0100 Subject: [PATCH 0930/2855] xhci: refuse loading if nousb is used The module should fail to load. Signed-off-by: Oliver Neukum CC: stable@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 887f308376f60..643d3121d100f 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -5068,6 +5068,10 @@ static int __init xhci_hcd_init(void) BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8); /* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */ BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8); + + if (usb_disabled()) + return -ENODEV; + return 0; } -- GitLab From 900937c0375efcbb2c9fb2eef50ccb5c98fc99ea Mon Sep 17 00:00:00 2001 From: "Geyslan G. Bem" Date: Wed, 2 Dec 2015 20:25:23 -0300 Subject: [PATCH 0931/2855] usb: ehci: ohci: fix bool assignments When assigning bool use true instead of 1. If declaring it as static and it's false there's no need to initialize it, since static variables are zeroed by default. Caught by coccinelle. Signed-off-by: Geyslan G. Bem Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 2 +- drivers/usb/host/ohci-hcd.c | 4 ++-- drivers/usb/host/u132-hcd.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 48c92bf78bd06..14178bbf06949 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -98,7 +98,7 @@ module_param (park, uint, S_IRUGO); MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets"); /* for flakey hardware, ignore overcurrent indicators */ -static bool ignore_oc = 0; +static bool ignore_oc; module_param (ignore_oc, bool, S_IRUGO); MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications"); diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 760cb57e954ef..04dcedfdebf87 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -99,13 +99,13 @@ static void io_watchdog_func(unsigned long _ohci); /* Some boards misreport power switching/overcurrent */ -static bool distrust_firmware = 1; +static bool distrust_firmware = true; module_param (distrust_firmware, bool, 0); MODULE_PARM_DESC (distrust_firmware, "true to distrust firmware power/overcurrent setup"); /* Some boards leave IR set wrongly, since they fail BIOS/SMM handshakes */ -static bool no_handshake = 0; +static bool no_handshake; module_param (no_handshake, bool, 0); MODULE_PARM_DESC (no_handshake, "true (not default) disables BIOS handshake"); diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 692ccc69345e4..05c85c7baf84e 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -73,7 +73,7 @@ MODULE_LICENSE("GPL"); #define INT_MODULE_PARM(n, v) static int n = v;module_param(n, int, 0444) INT_MODULE_PARM(testing, 0); /* Some boards misreport power switching/overcurrent*/ -static bool distrust_firmware = 1; +static bool distrust_firmware = true; module_param(distrust_firmware, bool, 0); MODULE_PARM_DESC(distrust_firmware, "true to distrust firmware power/overcurren" "t setup"); -- GitLab From 787c7b8cb3c5196f77e4682e0b1c71375e74822c Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 29 Oct 2015 09:13:04 +0800 Subject: [PATCH 0932/2855] f2fs: report error of f2fs_create_root_stats f2fs_create_root_stats can fail due to no memory, report it to user. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/debug.c | 7 +++++-- fs/f2fs/f2fs.h | 4 ++-- fs/f2fs/super.c | 6 +++++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index 478e5d54154f5..b0966f3b1c9a8 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -406,20 +406,23 @@ void f2fs_destroy_stats(struct f2fs_sb_info *sbi) kfree(si); } -void __init f2fs_create_root_stats(void) +int __init f2fs_create_root_stats(void) { struct dentry *file; f2fs_debugfs_root = debugfs_create_dir("f2fs", NULL); if (!f2fs_debugfs_root) - return; + return -ENOMEM; file = debugfs_create_file("status", S_IRUGO, f2fs_debugfs_root, NULL, &stat_fops); if (!file) { debugfs_remove(f2fs_debugfs_root); f2fs_debugfs_root = NULL; + return -ENOMEM; } + + return 0; } void f2fs_destroy_root_stats(void) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 9db5500d63d98..3f1570c4fcf05 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1987,7 +1987,7 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi) int f2fs_build_stats(struct f2fs_sb_info *); void f2fs_destroy_stats(struct f2fs_sb_info *); -void __init f2fs_create_root_stats(void); +int __init f2fs_create_root_stats(void); void f2fs_destroy_root_stats(void); #else #define stat_inc_cp_count(si) @@ -2015,7 +2015,7 @@ void f2fs_destroy_root_stats(void); static inline int f2fs_build_stats(struct f2fs_sb_info *sbi) { return 0; } static inline void f2fs_destroy_stats(struct f2fs_sb_info *sbi) { } -static inline void __init f2fs_create_root_stats(void) { } +static inline int __init f2fs_create_root_stats(void) { return 0; } static inline void f2fs_destroy_root_stats(void) { } #endif diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 3a65e01323528..67864ab376c89 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1478,10 +1478,14 @@ static int __init init_f2fs_fs(void) err = register_filesystem(&f2fs_fs_type); if (err) goto free_shrinker; - f2fs_create_root_stats(); + err = f2fs_create_root_stats(); + if (err) + goto free_filesystem; f2fs_proc_root = proc_mkdir("fs/f2fs", NULL); return 0; +free_filesystem: + unregister_filesystem(&f2fs_fs_type); free_shrinker: unregister_shrinker(&f2fs_shrinker_info); free_crypto: -- GitLab From 2da3e027461ab0148384b02bd5905f1a7b335dff Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 28 Oct 2015 17:56:14 +0800 Subject: [PATCH 0933/2855] f2fs: commit atomic written page in LFS mode We should always commit atomic written pages in LFS mode, otherwise data will become corrupted if we encounter suddent power cut after partial pages committed in IPU mode. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 972eab7ac0719..0cc8de2839c41 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1083,6 +1083,7 @@ int do_write_data_page(struct f2fs_io_info *fio) */ if (unlikely(fio->blk_addr != NEW_ADDR && !is_cold_data(page) && + !IS_ATOMIC_WRITTEN_PAGE(page) && need_inplace_update(inode))) { rewrite_data_page(fio); set_inode_flag(F2FS_I(inode), FI_UPDATE_WRITE); -- GitLab From d323d005ac4a2d413128267af76bb9d71f7303da Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 27 Oct 2015 09:53:45 +0800 Subject: [PATCH 0934/2855] f2fs: support file defragment This patch introduces a new ioctl F2FS_IOC_DEFRAGMENT to support file defragment in a specified range of regular file. This ioctl can be used in very limited workload: if user expects high sequential read performance in randomly written file, this interface can be used for defragmentation, after that file can be written as continuous as possible in the device. Meanwhile, it has side-effect, it will make holes in segments where blocks located originally, so it's better to trigger GC to eliminate fragment in segments. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 6 +- fs/f2fs/f2fs.h | 8 ++ fs/f2fs/file.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 208 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 0cc8de2839c41..c3e1ffa0c8d64 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -566,7 +566,7 @@ out: * b. do not use extent cache for better performance * c. give the block addresses to blockdev */ -static int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, +int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int create, int flag) { unsigned int maxblocks = map->m_len; @@ -1355,6 +1355,10 @@ static int f2fs_write_data_pages(struct address_space *mapping, available_free_memory(sbi, DIRTY_DENTS)) goto skip_write; + /* skip writing during file defragment */ + if (is_inode_flag_set(F2FS_I(inode), FI_DO_DEFRAG)) + goto skip_write; + /* during POR, we don't need to trigger writepage at all. */ if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING))) goto skip_write; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 3f1570c4fcf05..b01ad514fbd87 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -234,6 +234,7 @@ static inline bool __has_cursum_space(struct f2fs_summary_block *sum, int size, #define F2FS_IOC_ABORT_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 5) #define F2FS_IOC_GARBAGE_COLLECT _IO(F2FS_IOCTL_MAGIC, 6) #define F2FS_IOC_WRITE_CHECKPOINT _IO(F2FS_IOCTL_MAGIC, 7) +#define F2FS_IOC_DEFRAGMENT _IO(F2FS_IOCTL_MAGIC, 8) #define F2FS_IOC_SET_ENCRYPTION_POLICY \ _IOR('f', 19, struct f2fs_encryption_policy) @@ -260,6 +261,11 @@ static inline bool __has_cursum_space(struct f2fs_summary_block *sum, int size, #define F2FS_IOC32_SETFLAGS FS_IOC32_SETFLAGS #endif +struct f2fs_defragment { + u64 start; + u64 len; +}; + /* * For INODE and NODE manager */ @@ -1416,6 +1422,7 @@ enum { FI_DROP_CACHE, /* drop dirty page cache */ FI_DATA_EXIST, /* indicate data exists */ FI_INLINE_DOTS, /* indicate inline dot dentries */ + FI_DO_DEFRAG, /* indicate defragment is running */ }; static inline void set_inode_flag(struct f2fs_inode_info *fi, int flag) @@ -1847,6 +1854,7 @@ struct page *find_data_page(struct inode *, pgoff_t); struct page *get_lock_data_page(struct inode *, pgoff_t, bool); struct page *get_new_data_page(struct inode *, struct page *, pgoff_t, bool); int do_write_data_page(struct f2fs_io_info *); +int f2fs_map_blocks(struct inode *, struct f2fs_map_blocks *, int, int); int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *, u64, u64); void f2fs_invalidate_page(struct page *, unsigned int, unsigned int); int f2fs_release_page(struct page *, gfp_t); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index a197215ad52bf..2f392982c5970 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1646,6 +1646,199 @@ static int f2fs_ioc_write_checkpoint(struct file *filp, unsigned long arg) return 0; } +static int f2fs_defragment_range(struct f2fs_sb_info *sbi, + struct file *filp, + struct f2fs_defragment *range) +{ + struct inode *inode = file_inode(filp); + struct f2fs_map_blocks map; + struct extent_info ei; + pgoff_t pg_start, pg_end; + unsigned int blk_per_seg = 1 << sbi->log_blocks_per_seg; + unsigned int total = 0, sec_num; + unsigned int pages_per_sec = sbi->segs_per_sec * + (1 << sbi->log_blocks_per_seg); + block_t blk_end = 0; + bool fragmented = false; + int err; + + /* if in-place-update policy is enabled, don't waste time here */ + if (need_inplace_update(inode)) + return -EINVAL; + + pg_start = range->start >> PAGE_CACHE_SHIFT; + pg_end = (range->start + range->len) >> PAGE_CACHE_SHIFT; + + f2fs_balance_fs(sbi); + + mutex_lock(&inode->i_mutex); + + /* writeback all dirty pages in the range */ + err = filemap_write_and_wait_range(inode->i_mapping, range->start, + range->start + range->len); + if (err) + goto out; + + /* + * lookup mapping info in extent cache, skip defragmenting if physical + * block addresses are continuous. + */ + if (f2fs_lookup_extent_cache(inode, pg_start, &ei)) { + if (ei.fofs + ei.len >= pg_end) + goto out; + } + + map.m_lblk = pg_start; + map.m_len = pg_end - pg_start; + + /* + * lookup mapping info in dnode page cache, skip defragmenting if all + * physical block addresses are continuous even if there are hole(s) + * in logical blocks. + */ + while (map.m_lblk < pg_end) { + map.m_flags = 0; + err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_READ); + if (err) + goto out; + + if (!(map.m_flags & F2FS_MAP_FLAGS)) { + map.m_lblk++; + map.m_len--; + continue; + } + + if (blk_end && blk_end != map.m_pblk) { + fragmented = true; + break; + } + blk_end = map.m_pblk + map.m_len; + + map.m_lblk += map.m_len; + map.m_len = pg_end - map.m_lblk; + } + + if (!fragmented) + goto out; + + map.m_lblk = pg_start; + map.m_len = pg_end - pg_start; + + sec_num = (map.m_len + pages_per_sec - 1) / pages_per_sec; + + /* + * make sure there are enough free section for LFS allocation, this can + * avoid defragment running in SSR mode when free section are allocated + * intensively + */ + if (has_not_enough_free_secs(sbi, sec_num)) { + err = -EAGAIN; + goto out; + } + + while (map.m_lblk < pg_end) { + pgoff_t idx; + int cnt = 0; + +do_map: + map.m_flags = 0; + err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_READ); + if (err) + goto clear_out; + + if (!(map.m_flags & F2FS_MAP_FLAGS)) { + map.m_lblk++; + continue; + } + + set_inode_flag(F2FS_I(inode), FI_DO_DEFRAG); + + idx = map.m_lblk; + while (idx < map.m_lblk + map.m_len && cnt < blk_per_seg) { + struct page *page; + + page = get_lock_data_page(inode, idx, true); + if (IS_ERR(page)) { + err = PTR_ERR(page); + goto clear_out; + } + + set_page_dirty(page); + f2fs_put_page(page, 1); + + idx++; + cnt++; + total++; + } + + map.m_lblk = idx; + map.m_len = pg_end - idx; + + if (idx < pg_end && cnt < blk_per_seg) + goto do_map; + + clear_inode_flag(F2FS_I(inode), FI_DO_DEFRAG); + + err = filemap_fdatawrite(inode->i_mapping); + if (err) + goto out; + } +clear_out: + clear_inode_flag(F2FS_I(inode), FI_DO_DEFRAG); +out: + mutex_unlock(&inode->i_mutex); + if (!err) + range->len = (u64)total << PAGE_CACHE_SHIFT; + return err; +} + +static int f2fs_ioc_defragment(struct file *filp, unsigned long arg) +{ + struct inode *inode = file_inode(filp); + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct f2fs_defragment range; + int err; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (!S_ISREG(inode->i_mode)) + return -EINVAL; + + err = mnt_want_write_file(filp); + if (err) + return err; + + if (f2fs_readonly(sbi->sb)) { + err = -EROFS; + goto out; + } + + if (copy_from_user(&range, (struct f2fs_defragment __user *)arg, + sizeof(range))) { + err = -EFAULT; + goto out; + } + + /* verify alignment of offset & size */ + if (range.start & (F2FS_BLKSIZE - 1) || + range.len & (F2FS_BLKSIZE - 1)) { + err = -EINVAL; + goto out; + } + + err = f2fs_defragment_range(sbi, filp, &range); + if (err < 0) + goto out; + + if (copy_to_user((struct f2fs_defragment __user *)arg, &range, + sizeof(range))) + err = -EFAULT; +out: + mnt_drop_write_file(filp); + return err; +} + long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { switch (cmd) { @@ -1679,6 +1872,8 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return f2fs_ioc_gc(filp, arg); case F2FS_IOC_WRITE_CHECKPOINT: return f2fs_ioc_write_checkpoint(filp, arg); + case F2FS_IOC_DEFRAGMENT: + return f2fs_ioc_defragment(filp, arg); default: return -ENOTTY; } -- GitLab From 4bb9998d388b48dc0a4128bd1f4d85f09ec3b705 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Mon, 16 Nov 2015 20:46:28 +0900 Subject: [PATCH 0935/2855] Doc: f2fs: Fix typos in Documentation/filesystems/f2fs.txt This patch fix some typos in Documentation/filesystems/f2fs.txt Signed-off-by: Masanari Iida Acked-by: Randy Dunlap Signed-off-by: Jaegeuk Kim --- Documentation/filesystems/f2fs.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt index b102b436563eb..ad10494aa224f 100644 --- a/Documentation/filesystems/f2fs.txt +++ b/Documentation/filesystems/f2fs.txt @@ -102,7 +102,7 @@ background_gc=%s Turn on/off cleaning operations, namely garbage collection, triggered in background when I/O subsystem is idle. If background_gc=on, it will turn on the garbage collection and if background_gc=off, garbage collection - will be truned off. If background_gc=sync, it will turn + will be turned off. If background_gc=sync, it will turn on synchronous garbage collection running in background. Default value for this option is on. So garbage collection is on by default. @@ -145,7 +145,7 @@ extent_cache Enable an extent cache based on rb-tree, it can cache as many as extent which map between contiguous logical address and physical address per inode, resulting in increasing the cache hit ratio. Set by default. -noextent_cache Diable an extent cache based on rb-tree explicitly, see +noextent_cache Disable an extent cache based on rb-tree explicitly, see the above extent_cache mount option. noinline_data Disable the inline data feature, inline data feature is enabled by default. @@ -192,7 +192,7 @@ Files in /sys/fs/f2fs/ policy for garbage collection. Setting gc_idle = 0 (default) will disable this option. Setting gc_idle = 1 will select the Cost Benefit approach - & setting gc_idle = 2 will select the greedy aproach. + & setting gc_idle = 2 will select the greedy approach. reclaim_segments This parameter controls the number of prefree segments to be reclaimed. If the number of prefree @@ -298,7 +298,7 @@ The dump.f2fs shows the information of specific inode and dumps SSA and SIT to file. Each file is dump_ssa and dump_sit. The dump.f2fs is used to debug on-disk data structures of the f2fs filesystem. -It shows on-disk inode information reconized by a given inode number, and is +It shows on-disk inode information recognized by a given inode number, and is able to dump all the SSA and SIT entries into predefined files, ./dump_ssa and ./dump_sit respectively. -- GitLab From 29ba108d9ba44600961418a352871eb967d68c20 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Mon, 16 Nov 2015 20:38:25 +0800 Subject: [PATCH 0936/2855] f2fs: fix memory leak of kobject in error path of fill_super f2fs_sb_info::s_kobj should be released in error path of fill_super, otherwise it will lead to memory leak. This bug was found by kmemleak: dmesg: kmemleak: 2 new suspected memory leaks (see /sys/kernel/debug/kmemleak) cat /sys/kernel/debug/kmemleak unreferenced object 0xffff8800838dc358 (size 8): comm "mount", pid 4154, jiffies 4297482839 (age 1911.412s) hex dump (first 8 bytes): 7a 72 61 6d 31 00 ff ff zram1... backtrace: [] kmemleak_alloc+0x28/0x50 [] __kmalloc_track_caller+0xef/0x1c0 [] kstrdup+0x45/0x80 [] kstrdup_const+0x28/0x30 [] kvasprintf_const+0x63/0xa0 [] kobject_set_name_vargs+0x3c/0xa0 [] kobject_add_varg+0x25/0x60 [] kobject_init_and_add+0x53/0x70 [] f2fs_fill_super+0x9d9/0xc40 [f2fs] [] mount_bdev+0x192/0x1d0 [] f2fs_mount+0x15/0x20 [f2fs] [] mount_fs+0x43/0x170 [] vfs_kern_mount+0x76/0x160 [] do_mount+0x258/0xdc0 [] SyS_mount+0x7b/0xc0 [] entry_SYSCALL_64_fastpath+0x12/0x6f ... Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/super.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 67864ab376c89..bd7e9c6c42c80 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1361,6 +1361,8 @@ try_onemore: free_kobj: kobject_del(&sbi->s_kobj); + kobject_put(&sbi->s_kobj); + wait_for_completion(&sbi->s_kobj_unregister); free_proc: if (sbi->s_proc) { remove_proc_entry("segment_info", sbi->s_proc); -- GitLab From 04ef4b626c324a7529c80ffc45787b274a6fa68a Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 10 Nov 2015 18:44:20 +0800 Subject: [PATCH 0937/2855] f2fs: fix to enable missing ioctl interfaces in ->compat_ioctl In 64-bit kernel f2fs can supports 32-bit ioctl system call by identifying encoded code which is converted from 32-bit one to 64-bit one in ->compat_ioctl. When we introduced new interfaces in ->ioctl, we forgot to enable them in ->compat_ioctl, so enable them for fixing. Signed-off-by: Chao Yu [Jaegeuk Kim: fix wrongly added spaces together] Signed-off-by: Jaegeuk Kim --- fs/f2fs/f2fs.h | 5 +++-- fs/f2fs/file.c | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index b01ad514fbd87..904384427ca6f 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -257,8 +257,9 @@ static inline bool __has_cursum_space(struct f2fs_summary_block *sum, int size, /* * ioctl commands in 32 bit emulation */ -#define F2FS_IOC32_GETFLAGS FS_IOC32_GETFLAGS -#define F2FS_IOC32_SETFLAGS FS_IOC32_SETFLAGS +#define F2FS_IOC32_GETFLAGS FS_IOC32_GETFLAGS +#define F2FS_IOC32_SETFLAGS FS_IOC32_SETFLAGS +#define F2FS_IOC32_GETVERSION FS_IOC32_GETVERSION #endif struct f2fs_defragment { diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 2f392982c5970..3f1026caf8077 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1901,6 +1901,22 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case F2FS_IOC32_SETFLAGS: cmd = F2FS_IOC_SETFLAGS; break; + case F2FS_IOC32_GETVERSION: + cmd = F2FS_IOC_GETVERSION; + break; + case F2FS_IOC_START_ATOMIC_WRITE: + case F2FS_IOC_COMMIT_ATOMIC_WRITE: + case F2FS_IOC_START_VOLATILE_WRITE: + case F2FS_IOC_RELEASE_VOLATILE_WRITE: + case F2FS_IOC_ABORT_VOLATILE_WRITE: + case F2FS_IOC_SHUTDOWN: + case F2FS_IOC_SET_ENCRYPTION_POLICY: + case F2FS_IOC_GET_ENCRYPTION_PWSALT: + case F2FS_IOC_GET_ENCRYPTION_POLICY: + case F2FS_IOC_GARBAGE_COLLECT: + case F2FS_IOC_WRITE_CHECKPOINT: + case F2FS_IOC_DEFRAGMENT: + break; default: return -ENOIOCTLCMD; } -- GitLab From eb7e813cc791735f2428202d5249a8fd769df1f3 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 10 Nov 2015 18:45:07 +0800 Subject: [PATCH 0938/2855] f2fs: fix to remove directory inode from dirty list If last dirty dentry page was writebacked in reclaim path, we should remove its directory inode from global dirty list to avoid unnecessary flush for this inode when doing checkpoint. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index c3e1ffa0c8d64..6c689e9a86a38 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1182,8 +1182,10 @@ out: unlock_page(page); if (need_balance_fs) f2fs_balance_fs(sbi); - if (wbc->for_reclaim) + if (wbc->for_reclaim) { f2fs_submit_merged_bio(sbi, DATA, WRITE); + remove_dirty_dir_inode(inode); + } return 0; redirty_out: -- GitLab From 692223d132067ef2c392adec6f1324d581496212 Mon Sep 17 00:00:00 2001 From: Fan Li Date: Thu, 12 Nov 2015 08:43:04 +0800 Subject: [PATCH 0939/2855] f2fs: optimize __find_rev_next_bit 1. Skip __reverse_ulong if the bitmap is empty. 2. Reduce branches and codes. According to my test, the performance of this new version is 5% higher on an empty bitmap of 64bytes, and remains about the same in the worst scenario. Signed-off-by: Fan li Signed-off-by: Jaegeuk Kim --- fs/f2fs/segment.c | 46 ++++++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index f77b3258454a6..efbf6b5f1dc3a 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -86,6 +86,7 @@ static inline unsigned long __reverse_ffs(unsigned long word) /* * __find_rev_next(_zero)_bit is copied from lib/find_next_bit.c because * f2fs_set_bit makes MSB and LSB reversed in a byte. + * @size must be integral times of unsigned long. * Example: * MSB <--> LSB * f2fs_set_bit(0, bitmap) => 1000 0000 @@ -95,47 +96,36 @@ static unsigned long __find_rev_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset) { const unsigned long *p = addr + BIT_WORD(offset); - unsigned long result = offset & ~(BITS_PER_LONG - 1); + unsigned long result = size; unsigned long tmp; if (offset >= size) return size; - size -= result; + size -= (offset & ~(BITS_PER_LONG - 1)); offset %= BITS_PER_LONG; - if (!offset) - goto aligned; - tmp = __reverse_ulong((unsigned char *)p); - tmp &= ~0UL >> offset; - - if (size < BITS_PER_LONG) - goto found_first; - if (tmp) - goto found_middle; + while (1) { + if (*p == 0) + goto pass; - size -= BITS_PER_LONG; - result += BITS_PER_LONG; - p++; -aligned: - while (size & ~(BITS_PER_LONG-1)) { tmp = __reverse_ulong((unsigned char *)p); + + tmp &= ~0UL >> offset; + if (size < BITS_PER_LONG) + tmp &= (~0UL << (BITS_PER_LONG - size)); if (tmp) - goto found_middle; - result += BITS_PER_LONG; + goto found; +pass: + if (size <= BITS_PER_LONG) + break; size -= BITS_PER_LONG; + offset = 0; p++; } - if (!size) - return result; - - tmp = __reverse_ulong((unsigned char *)p); -found_first: - tmp &= (~0UL << (BITS_PER_LONG - size)); - if (!tmp) /* Are any bits set? */ - return result + size; /* Nope. */ -found_middle: - return result + __reverse_ffs(tmp); + return result; +found: + return result - size + __reverse_ffs(tmp); } static unsigned long __find_rev_next_zero_bit(const unsigned long *addr, -- GitLab From f478f43fa0d8f38537848d298980955244afdaee Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Fri, 13 Nov 2015 18:27:35 +0800 Subject: [PATCH 0940/2855] f2fs: clear page uptodate when dropping cache for atomic write We should clear uptodate flag for all pages atomic written when we drop them, otherwise before these cached pages were reclaimed or invalidated eventually, we will see invalid data when hitting them again. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/segment.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index efbf6b5f1dc3a..ed2c5dec75267 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -247,6 +247,7 @@ int commit_inmem_pages(struct inode *inode, bool abort) submit_bio = true; } } else { + ClearPageUptodate(cur->page); trace_f2fs_commit_inmem_page(cur->page, INMEM_DROP); } set_page_private(cur->page, 0); -- GitLab From 57b62d29ad5b384775974973087d47755a8c6fcc Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 19 Nov 2015 16:09:07 +0800 Subject: [PATCH 0941/2855] f2fs: fix to report error in f2fs_readdir get_lock_data_page in f2fs_readdir can fail due to a lot of reasons (i.e. no memory or IO error...), it's better to report this kind of error to user rather than ignoring it. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/dir.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 7c1678ba8f926..9de898d2ddff3 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -855,8 +855,13 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx) for (; n < npages; n++) { dentry_page = get_lock_data_page(inode, n, false); - if (IS_ERR(dentry_page)) - continue; + if (IS_ERR(dentry_page)) { + err = PTR_ERR(dentry_page); + if (err == -ENOENT) + continue; + else + goto out; + } dentry_blk = kmap(dentry_page); -- GitLab From 760de7914e27781abb44564449c761ea4440f982 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 30 Nov 2015 16:26:44 -0800 Subject: [PATCH 0942/2855] f2fs: avoid deadlock in f2fs_shrink_extent_tree While handling extent trees, we can enter into a reclaiming path anytime. If it tries to release some extent nodes in the same extent tree, write_lock(&et->lock) would be hanged. In order to avoid the deadlock, we can just skip it. Note that, if it is an unreferenced tree, we should get write_lock(&et->lock) successfully and release all of therein nodes. Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/extent_cache.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index 7ddba812e11b7..de063f2b23847 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -615,9 +615,10 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) for (i = 0; i < found; i++) { struct extent_tree *et = treevec[i]; - write_lock(&et->lock); - node_cnt += __free_extent_tree(sbi, et, false); - write_unlock(&et->lock); + if (write_trylock(&et->lock)) { + node_cnt += __free_extent_tree(sbi, et, false); + write_unlock(&et->lock); + } if (node_cnt + tree_cnt >= nr_shrink) goto unlock_out; -- GitLab From 807b1e1c8e08452948495b1a9985ab46d329e5c2 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 3 Dec 2015 14:14:40 -0800 Subject: [PATCH 0943/2855] f2fs: do not recover from previous remained wrong dnodes If device does not support discard, some obsolete dnodes can be recovered by roll-forward. This patch enhances the recovery flow. Signed-off-by: Jaegeuk Kim --- fs/f2fs/recovery.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index cbf74f47cce8a..fad010faa8591 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -168,6 +168,32 @@ static void recover_inode(struct inode *inode, struct page *page) ino_of_node(page), name); } +static bool is_same_inode(struct inode *inode, struct page *ipage) +{ + struct f2fs_inode *ri = F2FS_INODE(ipage); + struct timespec disk; + + if (!IS_INODE(ipage)) + return true; + + disk.tv_sec = le64_to_cpu(ri->i_ctime); + disk.tv_nsec = le32_to_cpu(ri->i_ctime_nsec); + if (timespec_compare(&inode->i_ctime, &disk) > 0) + return false; + + disk.tv_sec = le64_to_cpu(ri->i_atime); + disk.tv_nsec = le32_to_cpu(ri->i_atime_nsec); + if (timespec_compare(&inode->i_atime, &disk) > 0) + return false; + + disk.tv_sec = le64_to_cpu(ri->i_mtime); + disk.tv_nsec = le32_to_cpu(ri->i_mtime_nsec); + if (timespec_compare(&inode->i_mtime, &disk) > 0) + return false; + + return true; +} + static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head) { unsigned long long cp_ver = cur_cp_version(F2FS_CKPT(sbi)); @@ -197,7 +223,10 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head) goto next; entry = get_fsync_inode(head, ino_of_node(page)); - if (!entry) { + if (entry) { + if (!is_same_inode(entry->inode, page)) + goto next; + } else { if (IS_INODE(page) && is_dent_dnode(page)) { err = recover_inode_page(sbi, page); if (err) -- GitLab From e9837bc2a4a407ee366143cf721ee77154ac051e Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 1 Dec 2015 11:41:50 +0800 Subject: [PATCH 0944/2855] f2fs: clean up error path in f2fs_readdir No logic changes, just clean up the error path. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/dir.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 9de898d2ddff3..6554fd5fce88f 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -867,18 +867,15 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx) make_dentry_ptr(inode, &d, (void *)dentry_blk, 1); - if (f2fs_fill_dentries(ctx, &d, n * NR_DENTRY_IN_BLOCK, &fstr)) - goto stop; + if (f2fs_fill_dentries(ctx, &d, n * NR_DENTRY_IN_BLOCK, &fstr)) { + kunmap(dentry_page); + f2fs_put_page(dentry_page, 1); + break; + } ctx->pos = (n + 1) * NR_DENTRY_IN_BLOCK; kunmap(dentry_page); f2fs_put_page(dentry_page, 1); - dentry_page = NULL; - } -stop: - if (dentry_page && !IS_ERR(dentry_page)) { - kunmap(dentry_page); - f2fs_put_page(dentry_page, 1); } out: f2fs_fname_crypto_free_buffer(&fstr); -- GitLab From 855639decaa7ba5f356d6928c744a0ae1977c134 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 1 Dec 2015 11:42:54 +0800 Subject: [PATCH 0945/2855] f2fs: clean up code with __has_cursum_space Clean up codes in lookup_journal_in_cursum() with __has_cursum_space(). Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/segment.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index ed2c5dec75267..74c474821e5a1 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -1740,13 +1740,13 @@ int lookup_journal_in_cursum(struct f2fs_summary_block *sum, int type, if (le32_to_cpu(nid_in_journal(sum, i)) == val) return i; } - if (alloc && nats_in_cursum(sum) < NAT_JOURNAL_ENTRIES) + if (alloc && __has_cursum_space(sum, 1, NAT_JOURNAL)) return update_nats_in_cursum(sum, 1); } else if (type == SIT_JOURNAL) { for (i = 0; i < sits_in_cursum(sum); i++) if (le32_to_cpu(segno_in_journal(sum, i)) == val) return i; - if (alloc && sits_in_cursum(sum) < SIT_JOURNAL_ENTRIES) + if (alloc && __has_cursum_space(sum, 1, SIT_JOURNAL)) return update_sits_in_cursum(sum, 1); } return -1; -- GitLab From b7973f2378c619d0e17a075f13350bd58a9ebe3d Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 1 Dec 2015 11:43:59 +0800 Subject: [PATCH 0946/2855] f2fs: clean up argument of recover_data In recover_data, value of argument 'type' will be CURSEG_WARM_NODE all the time, remove it for cleanup. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/recovery.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index fad010faa8591..7fcb6e49defff 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -488,8 +488,7 @@ out: return err; } -static int recover_data(struct f2fs_sb_info *sbi, - struct list_head *head, int type) +static int recover_data(struct f2fs_sb_info *sbi, struct list_head *head) { unsigned long long cp_ver = cur_cp_version(F2FS_CKPT(sbi)); struct curseg_info *curseg; @@ -498,7 +497,7 @@ static int recover_data(struct f2fs_sb_info *sbi, block_t blkaddr; /* get node pages in the current segment */ - curseg = CURSEG_I(sbi, type); + curseg = CURSEG_I(sbi, CURSEG_WARM_NODE); blkaddr = NEXT_FREE_BLKADDR(sbi, curseg); while (1) { @@ -585,7 +584,7 @@ int recover_fsync_data(struct f2fs_sb_info *sbi) need_writecp = true; /* step #2: recover data */ - err = recover_data(sbi, &inode_list, CURSEG_WARM_NODE); + err = recover_data(sbi, &inode_list); if (!err) f2fs_bug_on(sbi, !list_empty(&inode_list)); out: -- GitLab From 9006f2c93fe5cc450bc0d3a4924b46393f165b4a Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 1 Dec 2015 11:47:33 +0800 Subject: [PATCH 0947/2855] f2fs: kill f2fs_drop_largest_extent For direct IO, f2fs only allocate new address for the block which is not exist in the disk before, its mapping info should not exist in extent cache previously, so here we do not need to call f2fs_drop_largest_extent to drop related cache. Due to no more callers for f2fs_drop_largest_extent now, kill it. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 4 ---- fs/f2fs/extent_cache.c | 8 -------- fs/f2fs/f2fs.h | 1 - 3 files changed, 13 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 6c689e9a86a38..90a2ffea875bf 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -494,10 +494,6 @@ alloc: if (i_size_read(dn->inode) < ((loff_t)(fofs + 1) << PAGE_CACHE_SHIFT)) i_size_write(dn->inode, ((loff_t)(fofs + 1) << PAGE_CACHE_SHIFT)); - - /* direct IO doesn't use extent cache to maximize the performance */ - f2fs_drop_largest_extent(dn->inode, fofs); - return 0; } diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index de063f2b23847..e86e9f1e0733a 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -164,14 +164,6 @@ static void __drop_largest_extent(struct inode *inode, largest->len = 0; } -void f2fs_drop_largest_extent(struct inode *inode, pgoff_t fofs) -{ - if (!f2fs_may_extent_tree(inode)) - return; - - __drop_largest_extent(inode, fofs, 1); -} - void f2fs_init_extent_tree(struct inode *inode, struct f2fs_extent *i_ext) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 904384427ca6f..0831db2f4b3ae 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -2078,7 +2078,6 @@ void f2fs_leave_shrinker(struct f2fs_sb_info *); * extent_cache.c */ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *, int); -void f2fs_drop_largest_extent(struct inode *, pgoff_t); void f2fs_init_extent_tree(struct inode *, struct f2fs_extent *); unsigned int f2fs_destroy_extent_node(struct inode *); void f2fs_destroy_extent_tree(struct inode *); -- GitLab From 3519e3f992995d46c200134cfbf84c61b7a01f4c Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 1 Dec 2015 11:56:52 +0800 Subject: [PATCH 0948/2855] f2fs: use sbi->blocks_per_seg to avoid unnecessary calculation Use sbi->blocks_per_seg directly to avoid unnecessary calculation when using 1 << sbi->log_blocks_per_seg. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/debug.c | 2 +- fs/f2fs/f2fs.h | 3 +-- fs/f2fs/file.c | 5 ++--- fs/f2fs/gc.c | 4 ++-- fs/f2fs/node.h | 2 +- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index b0966f3b1c9a8..8ce2fe3f65ab5 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -105,7 +105,7 @@ static void update_sit_info(struct f2fs_sb_info *sbi) bimodal = 0; total_vblocks = 0; - blks_per_sec = sbi->segs_per_sec * (1 << sbi->log_blocks_per_seg); + blks_per_sec = sbi->segs_per_sec * sbi->blocks_per_seg; hblks_per_sec = blks_per_sec / 2; for (segno = 0; segno < MAIN_SEGS(sbi); segno += sbi->segs_per_sec) { vblocks = get_valid_blocks(sbi, segno, sbi->segs_per_sec); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 0831db2f4b3ae..0052ae8bea3f6 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1099,8 +1099,7 @@ static inline int get_dirty_pages(struct inode *inode) static inline int get_blocktype_secs(struct f2fs_sb_info *sbi, int block_type) { - unsigned int pages_per_sec = sbi->segs_per_sec * - (1 << sbi->log_blocks_per_seg); + unsigned int pages_per_sec = sbi->segs_per_sec * sbi->blocks_per_seg; return ((get_pages(sbi, block_type) + pages_per_sec - 1) >> sbi->log_blocks_per_seg) / sbi->segs_per_sec; } diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 3f1026caf8077..96e4e048a8a1a 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1654,10 +1654,9 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi, struct f2fs_map_blocks map; struct extent_info ei; pgoff_t pg_start, pg_end; - unsigned int blk_per_seg = 1 << sbi->log_blocks_per_seg; + unsigned int blk_per_seg = sbi->blocks_per_seg; unsigned int total = 0, sec_num; - unsigned int pages_per_sec = sbi->segs_per_sec * - (1 << sbi->log_blocks_per_seg); + unsigned int pages_per_sec = sbi->segs_per_sec * blk_per_seg; block_t blk_end = 0; bool fragmented = false; int err; diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index fedbf67a08427..ce350c44b5cf4 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -173,9 +173,9 @@ static unsigned int get_max_cost(struct f2fs_sb_info *sbi, { /* SSR allocates in a segment unit */ if (p->alloc_mode == SSR) - return 1 << sbi->log_blocks_per_seg; + return sbi->blocks_per_seg; if (p->gc_mode == GC_GREEDY) - return (1 << sbi->log_blocks_per_seg) * p->ofs_unit; + return sbi->blocks_per_seg * p->ofs_unit; else if (p->gc_mode == GC_CB) return UINT_MAX; else /* No other gc_mode */ diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index e4fffd2d98c4b..2de759a7746f5 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h @@ -183,7 +183,7 @@ static inline pgoff_t current_nat_addr(struct f2fs_sb_info *sbi, nid_t start) block_addr = (pgoff_t)(nm_i->nat_blkaddr + (seg_off << sbi->log_blocks_per_seg << 1) + - (block_off & ((1 << sbi->log_blocks_per_seg) - 1))); + (block_off & (sbi->blocks_per_seg - 1))); if (f2fs_test_bit(block_off, nm_i->nat_bitmap)) block_addr += sbi->blocks_per_seg; -- GitLab From 0cab80ee0c9e17337468c4c0f96786ccbca693d9 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 1 Dec 2015 11:36:16 +0800 Subject: [PATCH 0949/2855] f2fs: fix to convert inline inode in ->setattr In commit 3c4541452748 ("f2fs: do not trim preallocated blocks when truncating after i_size"), in order to follow the regulation: "truncate(x) where x > i_size will not trim all blocks past i_size." like other file systems, in ->setattr we invoked truncate_setsize instead of f2fs_truncate to avoid unneeded block trimming in such case, but forgot to call f2fs_convert_inline_inode keep consistency of inline data conversion rule. This patch fixes to convert inline data if necessary. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 96e4e048a8a1a..a018ed327713b 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -686,6 +686,14 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr) * larger than i_size. */ truncate_setsize(inode, attr->ia_size); + + /* should convert inline inode here */ + if (f2fs_has_inline_data(inode) && + !f2fs_may_inline_data(inode)) { + err = f2fs_convert_inline_inode(inode); + if (err) + return err; + } inode->i_mtime = inode->i_ctime = CURRENT_TIME; } } -- GitLab From 20ef10c1b3068f105004e247d8e7dd8120fa4b9a Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 26 Nov 2015 09:42:08 +1030 Subject: [PATCH 0950/2855] module: Use the same logic for setting and unsetting RO/NX When setting a module's RO and NX permissions, set_section_ro_nx() is used, but when clearing them, unset_module_{init,core}_ro_nx() are used. The unset functions don't have the same checks the set function has for partial page protections. It's probably harmless, but it's still confusingly asymmetrical. Instead, use the same logic to do both. Also add some new set_module_{init,core}_ro_nx() helper functions for more symmetry with the unset functions. Signed-off-by: Josh Poimboeuf Signed-off-by: Rusty Russell Signed-off-by: Jiri Kosina --- kernel/module.c | 57 ++++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/kernel/module.c b/kernel/module.c index 8f051a106676f..14b224967e7b4 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1886,7 +1886,9 @@ void set_page_attributes(void *start, void *end, int (*set)(unsigned long start, static void set_section_ro_nx(void *base, unsigned long text_size, unsigned long ro_size, - unsigned long total_size) + unsigned long total_size, + int (*set_ro)(unsigned long start, int num_pages), + int (*set_nx)(unsigned long start, int num_pages)) { /* begin and end PFNs of the current subsection */ unsigned long begin_pfn; @@ -1898,7 +1900,7 @@ static void set_section_ro_nx(void *base, * - Do not protect last partial page. */ if (ro_size > 0) - set_page_attributes(base, base + ro_size, set_memory_ro); + set_page_attributes(base, base + ro_size, set_ro); /* * Set NX permissions for module data: @@ -1909,28 +1911,36 @@ static void set_section_ro_nx(void *base, begin_pfn = PFN_UP((unsigned long)base + text_size); end_pfn = PFN_UP((unsigned long)base + total_size); if (end_pfn > begin_pfn) - set_memory_nx(begin_pfn << PAGE_SHIFT, end_pfn - begin_pfn); + set_nx(begin_pfn << PAGE_SHIFT, end_pfn - begin_pfn); } } +static void set_module_core_ro_nx(struct module *mod) +{ + set_section_ro_nx(mod->module_core, mod->core_text_size, + mod->core_ro_size, mod->core_size, + set_memory_ro, set_memory_nx); +} + static void unset_module_core_ro_nx(struct module *mod) { - set_page_attributes(mod->module_core + mod->core_text_size, - mod->module_core + mod->core_size, - set_memory_x); - set_page_attributes(mod->module_core, - mod->module_core + mod->core_ro_size, - set_memory_rw); + set_section_ro_nx(mod->module_core, mod->core_text_size, + mod->core_ro_size, mod->core_size, + set_memory_rw, set_memory_x); +} + +static void set_module_init_ro_nx(struct module *mod) +{ + set_section_ro_nx(mod->module_init, mod->init_text_size, + mod->init_ro_size, mod->init_size, + set_memory_ro, set_memory_nx); } static void unset_module_init_ro_nx(struct module *mod) { - set_page_attributes(mod->module_init + mod->init_text_size, - mod->module_init + mod->init_size, - set_memory_x); - set_page_attributes(mod->module_init, - mod->module_init + mod->init_ro_size, - set_memory_rw); + set_section_ro_nx(mod->module_init, mod->init_text_size, + mod->init_ro_size, mod->init_size, + set_memory_rw, set_memory_x); } /* Iterate through all modules and set each module's text as RW */ @@ -1979,7 +1989,8 @@ void set_all_modules_text_ro(void) mutex_unlock(&module_mutex); } #else -static inline void set_section_ro_nx(void *base, unsigned long text_size, unsigned long ro_size, unsigned long total_size) { } +static void set_module_core_ro_nx(struct module *mod) { } +static void set_module_init_ro_nx(struct module *mod) { } static void unset_module_core_ro_nx(struct module *mod) { } static void unset_module_init_ro_nx(struct module *mod) { } #endif @@ -3373,17 +3384,9 @@ static int complete_formation(struct module *mod, struct load_info *info) /* This relies on module_mutex for list integrity. */ module_bug_finalize(info->hdr, info->sechdrs, mod); - /* Set RO and NX regions for core */ - set_section_ro_nx(mod->module_core, - mod->core_text_size, - mod->core_ro_size, - mod->core_size); - - /* Set RO and NX regions for init */ - set_section_ro_nx(mod->module_init, - mod->init_text_size, - mod->init_ro_size, - mod->init_size); + /* Set RO and NX regions */ + set_module_init_ro_nx(mod); + set_module_core_ro_nx(mod); /* Mark state as coming so strong_try_module_get() ignores us, * but kallsyms etc. can see us. */ -- GitLab From c65abf358f211c3f88c8ed714dff25775ab49fc1 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 26 Nov 2015 09:43:08 +1030 Subject: [PATCH 0951/2855] gcov: use within_module() helper. An exact mapping would be within_module_core(), but at this stage (MODULE_STATE_GOING) the init section is empty, and this is clearer. Reviewed-by: Peter Oberparleiter Signed-off-by: Rusty Russell Signed-off-by: Jiri Kosina --- kernel/gcov/base.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/kernel/gcov/base.c b/kernel/gcov/base.c index 7080ae1eb6c10..2f9df37940a0f 100644 --- a/kernel/gcov/base.c +++ b/kernel/gcov/base.c @@ -123,11 +123,6 @@ void gcov_enable_events(void) } #ifdef CONFIG_MODULES -static inline int within(void *addr, void *start, unsigned long size) -{ - return ((addr >= start) && (addr < start + size)); -} - /* Update list and generate events when modules are unloaded. */ static int gcov_module_notifier(struct notifier_block *nb, unsigned long event, void *data) @@ -142,7 +137,7 @@ static int gcov_module_notifier(struct notifier_block *nb, unsigned long event, /* Remove entries located in module from linked list. */ while ((info = gcov_info_next(info))) { - if (within(info, mod->module_core, mod->core_size)) { + if (within_module((unsigned long)info, mod)) { gcov_info_unlink(prev, info); if (gcov_events_enabled) gcov_event(GCOV_REMOVE, info); -- GitLab From 7523e4dc5057e157212b4741abd6256e03404cf1 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 26 Nov 2015 09:44:08 +1030 Subject: [PATCH 0952/2855] module: use a structure to encapsulate layout. Makes it easier to handle init vs core cleanly, though the change is fairly invasive across random architectures. It simplifies the rbtree code immediately, however, while keeping the core data together in the same cachline (now iff the rbtree code is enabled). Acked-by: Peter Zijlstra Reviewed-by: Josh Poimboeuf Signed-off-by: Rusty Russell Signed-off-by: Jiri Kosina --- arch/alpha/kernel/module.c | 2 +- arch/arc/kernel/unwind.c | 4 +- arch/arm/kernel/module-plts.c | 2 +- arch/avr32/kernel/module.c | 12 +- arch/ia64/kernel/module.c | 14 +-- arch/metag/kernel/module.c | 4 +- arch/mips/kernel/vpe.c | 6 +- arch/parisc/kernel/module.c | 32 ++--- arch/powerpc/kernel/module_32.c | 6 +- arch/s390/kernel/module.c | 22 ++-- arch/x86/kernel/livepatch.c | 6 +- include/linux/module.h | 64 +++++----- kernel/debug/kdb/kdb_main.c | 4 +- kernel/module.c | 199 +++++++++++++++----------------- 14 files changed, 178 insertions(+), 199 deletions(-) diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c index 2fd00b7077e41..936bc8f89a679 100644 --- a/arch/alpha/kernel/module.c +++ b/arch/alpha/kernel/module.c @@ -160,7 +160,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab, /* The small sections were sorted to the end of the segment. The following should definitely cover them. */ - gp = (u64)me->module_core + me->core_size - 0x8000; + gp = (u64)me->core_layout.base + me->core_layout.size - 0x8000; got = sechdrs[me->arch.gotsecindex].sh_addr; for (i = 0; i < n; i++) { diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c index 93c6ea52b6719..e0034a6656efc 100644 --- a/arch/arc/kernel/unwind.c +++ b/arch/arc/kernel/unwind.c @@ -372,8 +372,8 @@ void *unwind_add_table(struct module *module, const void *table_start, return NULL; init_unwind_table(table, module->name, - module->module_core, module->core_size, - module->module_init, module->init_size, + module->core_layout.base, module->core_layout.size, + module->init_layout.base, module->init_layout.size, table_start, table_size, NULL, 0); diff --git a/arch/arm/kernel/module-plts.c b/arch/arm/kernel/module-plts.c index 097e2e201b9f0..0c7efc3446c00 100644 --- a/arch/arm/kernel/module-plts.c +++ b/arch/arm/kernel/module-plts.c @@ -32,7 +32,7 @@ struct plt_entries { static bool in_init(const struct module *mod, u32 addr) { - return addr - (u32)mod->module_init < mod->init_size; + return addr - (u32)mod->init_layout.base < mod->init_layout.size; } u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val) diff --git a/arch/avr32/kernel/module.c b/arch/avr32/kernel/module.c index 164efa009e5be..2b4c54c04cb68 100644 --- a/arch/avr32/kernel/module.c +++ b/arch/avr32/kernel/module.c @@ -118,9 +118,9 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, * Increase core size to make room for GOT and set start * offset for GOT. */ - module->core_size = ALIGN(module->core_size, 4); - module->arch.got_offset = module->core_size; - module->core_size += module->arch.got_size; + module->core_layout.size = ALIGN(module->core_layout.size, 4); + module->arch.got_offset = module->core_layout.size; + module->core_layout.size += module->arch.got_size; return 0; @@ -177,7 +177,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, if (!info->got_initialized) { Elf32_Addr *gotent; - gotent = (module->module_core + gotent = (module->core_layout.base + module->arch.got_offset + info->got_offset); *gotent = relocation; @@ -255,8 +255,8 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, */ pr_debug("GOTPC: PC=0x%x, got_offset=0x%lx, core=0x%p\n", relocation, module->arch.got_offset, - module->module_core); - relocation -= ((unsigned long)module->module_core + module->core_layout.base); + relocation -= ((unsigned long)module->core_layout.base + module->arch.got_offset); *location = relocation; break; diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c index b15933c31b2ff..6ab0ae7d6535d 100644 --- a/arch/ia64/kernel/module.c +++ b/arch/ia64/kernel/module.c @@ -486,13 +486,13 @@ module_frob_arch_sections (Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings, static inline int in_init (const struct module *mod, uint64_t addr) { - return addr - (uint64_t) mod->module_init < mod->init_size; + return addr - (uint64_t) mod->init_layout.base < mod->init_layout.size; } static inline int in_core (const struct module *mod, uint64_t addr) { - return addr - (uint64_t) mod->module_core < mod->core_size; + return addr - (uint64_t) mod->core_layout.base < mod->core_layout.size; } static inline int @@ -675,7 +675,7 @@ do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, uint64_t addend, break; case RV_BDREL: - val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core); + val -= (uint64_t) (in_init(mod, val) ? mod->init_layout.base : mod->core_layout.base); break; case RV_LTV: @@ -810,15 +810,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind * addresses have been selected... */ uint64_t gp; - if (mod->core_size > MAX_LTOFF) + if (mod->core_layout.size > MAX_LTOFF) /* * This takes advantage of fact that SHF_ARCH_SMALL gets allocated * at the end of the module. */ - gp = mod->core_size - MAX_LTOFF / 2; + gp = mod->core_layout.size - MAX_LTOFF / 2; else - gp = mod->core_size / 2; - gp = (uint64_t) mod->module_core + ((gp + 7) & -8); + gp = mod->core_layout.size / 2; + gp = (uint64_t) mod->core_layout.base + ((gp + 7) & -8); mod->arch.gp = gp; DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp); } diff --git a/arch/metag/kernel/module.c b/arch/metag/kernel/module.c index 986331cd0a52c..bb8dfba9a763c 100644 --- a/arch/metag/kernel/module.c +++ b/arch/metag/kernel/module.c @@ -176,8 +176,8 @@ static uint32_t do_plt_call(void *location, Elf32_Addr val, tramp[1] = 0xac000001 | ((val & 0x0000ffff) << 3); /* Init, or core PLT? */ - if (location >= mod->module_core - && location < mod->module_core + mod->core_size) + if (location >= mod->core_layout.base + && location < mod->core_layout.base + mod->core_layout.size) entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr; else entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr; diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 9067b651c7a2d..544ea21bfef9c 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -205,11 +205,11 @@ static void layout_sections(struct module *mod, const Elf_Ehdr *hdr, || s->sh_entsize != ~0UL) continue; s->sh_entsize = - get_offset((unsigned long *)&mod->core_size, s); + get_offset((unsigned long *)&mod->core_layout.size, s); } if (m == 0) - mod->core_text_size = mod->core_size; + mod->core_layout.text_size = mod->core_layout.size; } } @@ -641,7 +641,7 @@ static int vpe_elfload(struct vpe *v) layout_sections(&mod, hdr, sechdrs, secstrings); } - v->load_addr = alloc_progmem(mod.core_size); + v->load_addr = alloc_progmem(mod.core_layout.size); if (!v->load_addr) return -ENOMEM; diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 3c63a820fcda4..b9d75d9fa9ace 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -42,9 +42,9 @@ * We are not doing SEGREL32 handling correctly. According to the ABI, we * should do a value offset, like this: * if (in_init(me, (void *)val)) - * val -= (uint32_t)me->module_init; + * val -= (uint32_t)me->init_layout.base; * else - * val -= (uint32_t)me->module_core; + * val -= (uint32_t)me->core_layout.base; * However, SEGREL32 is used only for PARISC unwind entries, and we want * those entries to have an absolute address, and not just an offset. * @@ -100,14 +100,14 @@ * or init pieces the location is */ static inline int in_init(struct module *me, void *loc) { - return (loc >= me->module_init && - loc <= (me->module_init + me->init_size)); + return (loc >= me->init_layout.base && + loc <= (me->init_layout.base + me->init_layout.size)); } static inline int in_core(struct module *me, void *loc) { - return (loc >= me->module_core && - loc <= (me->module_core + me->core_size)); + return (loc >= me->core_layout.base && + loc <= (me->core_layout.base + me->core_layout.size)); } static inline int in_local(struct module *me, void *loc) @@ -367,13 +367,13 @@ int module_frob_arch_sections(CONST Elf_Ehdr *hdr, } /* align things a bit */ - me->core_size = ALIGN(me->core_size, 16); - me->arch.got_offset = me->core_size; - me->core_size += gots * sizeof(struct got_entry); + me->core_layout.size = ALIGN(me->core_layout.size, 16); + me->arch.got_offset = me->core_layout.size; + me->core_layout.size += gots * sizeof(struct got_entry); - me->core_size = ALIGN(me->core_size, 16); - me->arch.fdesc_offset = me->core_size; - me->core_size += fdescs * sizeof(Elf_Fdesc); + me->core_layout.size = ALIGN(me->core_layout.size, 16); + me->arch.fdesc_offset = me->core_layout.size; + me->core_layout.size += fdescs * sizeof(Elf_Fdesc); me->arch.got_max = gots; me->arch.fdesc_max = fdescs; @@ -391,7 +391,7 @@ static Elf64_Word get_got(struct module *me, unsigned long value, long addend) BUG_ON(value == 0); - got = me->module_core + me->arch.got_offset; + got = me->core_layout.base + me->arch.got_offset; for (i = 0; got[i].addr; i++) if (got[i].addr == value) goto out; @@ -409,7 +409,7 @@ static Elf64_Word get_got(struct module *me, unsigned long value, long addend) #ifdef CONFIG_64BIT static Elf_Addr get_fdesc(struct module *me, unsigned long value) { - Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset; + Elf_Fdesc *fdesc = me->core_layout.base + me->arch.fdesc_offset; if (!value) { printk(KERN_ERR "%s: zero OPD requested!\n", me->name); @@ -427,7 +427,7 @@ static Elf_Addr get_fdesc(struct module *me, unsigned long value) /* Create new one */ fdesc->addr = value; - fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset; + fdesc->gp = (Elf_Addr)me->core_layout.base + me->arch.got_offset; return (Elf_Addr)fdesc; } #endif /* CONFIG_64BIT */ @@ -839,7 +839,7 @@ register_unwind_table(struct module *me, table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr; end = table + sechdrs[me->arch.unwind_section].sh_size; - gp = (Elf_Addr)me->module_core + me->arch.got_offset; + gp = (Elf_Addr)me->core_layout.base + me->arch.got_offset; DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n", me->arch.unwind_section, table, end, gp); diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c index c94d2e018d843..2c01665eb410a 100644 --- a/arch/powerpc/kernel/module_32.c +++ b/arch/powerpc/kernel/module_32.c @@ -188,8 +188,8 @@ static uint32_t do_plt_call(void *location, pr_debug("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location); /* Init, or core PLT? */ - if (location >= mod->module_core - && location < mod->module_core + mod->core_size) + if (location >= mod->core_layout.base + && location < mod->core_layout.base + mod->core_layout.size) entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr; else entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr; @@ -296,7 +296,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, } #ifdef CONFIG_DYNAMIC_FTRACE module->arch.tramp = - do_plt_call(module->module_core, + do_plt_call(module->core_layout.base, (unsigned long)ftrace_caller, sechdrs, module); #endif diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index 0c1a679314dd4..7873e171457cf 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c @@ -159,11 +159,11 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, /* Increase core size by size of got & plt and set start offsets for got and plt. */ - me->core_size = ALIGN(me->core_size, 4); - me->arch.got_offset = me->core_size; - me->core_size += me->arch.got_size; - me->arch.plt_offset = me->core_size; - me->core_size += me->arch.plt_size; + me->core_layout.size = ALIGN(me->core_layout.size, 4); + me->arch.got_offset = me->core_layout.size; + me->core_layout.size += me->arch.got_size; + me->arch.plt_offset = me->core_layout.size; + me->core_layout.size += me->arch.plt_size; return 0; } @@ -279,7 +279,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab, if (info->got_initialized == 0) { Elf_Addr *gotent; - gotent = me->module_core + me->arch.got_offset + + gotent = me->core_layout.base + me->arch.got_offset + info->got_offset; *gotent = val; info->got_initialized = 1; @@ -302,7 +302,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab, rc = apply_rela_bits(loc, val, 0, 64, 0); else if (r_type == R_390_GOTENT || r_type == R_390_GOTPLTENT) { - val += (Elf_Addr) me->module_core - loc; + val += (Elf_Addr) me->core_layout.base - loc; rc = apply_rela_bits(loc, val, 1, 32, 1); } break; @@ -315,7 +315,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab, case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */ if (info->plt_initialized == 0) { unsigned int *ip; - ip = me->module_core + me->arch.plt_offset + + ip = me->core_layout.base + me->arch.plt_offset + info->plt_offset; ip[0] = 0x0d10e310; /* basr 1,0; lg 1,10(1); br 1 */ ip[1] = 0x100a0004; @@ -334,7 +334,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab, val - loc + 0xffffUL < 0x1ffffeUL) || (r_type == R_390_PLT32DBL && val - loc + 0xffffffffULL < 0x1fffffffeULL))) - val = (Elf_Addr) me->module_core + + val = (Elf_Addr) me->core_layout.base + me->arch.plt_offset + info->plt_offset; val += rela->r_addend - loc; @@ -356,7 +356,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab, case R_390_GOTOFF32: /* 32 bit offset to GOT. */ case R_390_GOTOFF64: /* 64 bit offset to GOT. */ val = val + rela->r_addend - - ((Elf_Addr) me->module_core + me->arch.got_offset); + ((Elf_Addr) me->core_layout.base + me->arch.got_offset); if (r_type == R_390_GOTOFF16) rc = apply_rela_bits(loc, val, 0, 16, 0); else if (r_type == R_390_GOTOFF32) @@ -366,7 +366,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab, break; case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */ case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */ - val = (Elf_Addr) me->module_core + me->arch.got_offset + + val = (Elf_Addr) me->core_layout.base + me->arch.got_offset + rela->r_addend - loc; if (r_type == R_390_GOTPC) rc = apply_rela_bits(loc, val, 1, 32, 0); diff --git a/arch/x86/kernel/livepatch.c b/arch/x86/kernel/livepatch.c index d1d35ccffed3c..bcc06e82a593e 100644 --- a/arch/x86/kernel/livepatch.c +++ b/arch/x86/kernel/livepatch.c @@ -41,8 +41,8 @@ int klp_write_module_reloc(struct module *mod, unsigned long type, int ret, numpages, size = 4; bool readonly; unsigned long val; - unsigned long core = (unsigned long)mod->module_core; - unsigned long core_size = mod->core_size; + unsigned long core = (unsigned long)mod->core_layout.base; + unsigned long core_size = mod->core_layout.size; switch (type) { case R_X86_64_NONE: @@ -72,7 +72,7 @@ int klp_write_module_reloc(struct module *mod, unsigned long type, readonly = false; #ifdef CONFIG_DEBUG_SET_MODULE_RONX - if (loc < core + mod->core_ro_size) + if (loc < core + mod->core_layout.ro_size) readonly = true; #endif diff --git a/include/linux/module.h b/include/linux/module.h index 3a19c79918e02..6e68e8cf4d0d2 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -302,6 +302,28 @@ struct mod_tree_node { struct latch_tree_node node; }; +struct module_layout { + /* The actual code + data. */ + void *base; + /* Total size. */ + unsigned int size; + /* The size of the executable code. */ + unsigned int text_size; + /* Size of RO section of the module (text+rodata) */ + unsigned int ro_size; + +#ifdef CONFIG_MODULES_TREE_LOOKUP + struct mod_tree_node mtn; +#endif +}; + +#ifdef CONFIG_MODULES_TREE_LOOKUP +/* Only touch one cacheline for common rbtree-for-core-layout case. */ +#define __module_layout_align ____cacheline_aligned +#else +#define __module_layout_align +#endif + struct module { enum module_state state; @@ -366,37 +388,9 @@ struct module { /* Startup function. */ int (*init)(void); - /* - * If this is non-NULL, vfree() after init() returns. - * - * Cacheline align here, such that: - * module_init, module_core, init_size, core_size, - * init_text_size, core_text_size and mtn_core::{mod,node[0]} - * are on the same cacheline. - */ - void *module_init ____cacheline_aligned; - - /* Here is the actual code + data, vfree'd on unload. */ - void *module_core; - - /* Here are the sizes of the init and core sections */ - unsigned int init_size, core_size; - - /* The size of the executable code in each section. */ - unsigned int init_text_size, core_text_size; - -#ifdef CONFIG_MODULES_TREE_LOOKUP - /* - * We want mtn_core::{mod,node[0]} to be in the same cacheline as the - * above entries such that a regular lookup will only touch one - * cacheline. - */ - struct mod_tree_node mtn_core; - struct mod_tree_node mtn_init; -#endif - - /* Size of RO sections of the module (text+rodata) */ - unsigned int init_ro_size, core_ro_size; + /* Core layout: rbtree is accessed frequently, so keep together. */ + struct module_layout core_layout __module_layout_align; + struct module_layout init_layout; /* Arch-specific module values */ struct mod_arch_specific arch; @@ -505,15 +499,15 @@ bool is_module_text_address(unsigned long addr); static inline bool within_module_core(unsigned long addr, const struct module *mod) { - return (unsigned long)mod->module_core <= addr && - addr < (unsigned long)mod->module_core + mod->core_size; + return (unsigned long)mod->core_layout.base <= addr && + addr < (unsigned long)mod->core_layout.base + mod->core_layout.size; } static inline bool within_module_init(unsigned long addr, const struct module *mod) { - return (unsigned long)mod->module_init <= addr && - addr < (unsigned long)mod->module_init + mod->init_size; + return (unsigned long)mod->init_layout.base <= addr && + addr < (unsigned long)mod->init_layout.base + mod->init_layout.size; } static inline bool within_module(unsigned long addr, const struct module *mod) diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 4121345498e0e..2a20c0dfdafc7 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -2021,7 +2021,7 @@ static int kdb_lsmod(int argc, const char **argv) continue; kdb_printf("%-20s%8u 0x%p ", mod->name, - mod->core_size, (void *)mod); + mod->core_layout.size, (void *)mod); #ifdef CONFIG_MODULE_UNLOAD kdb_printf("%4d ", module_refcount(mod)); #endif @@ -2031,7 +2031,7 @@ static int kdb_lsmod(int argc, const char **argv) kdb_printf(" (Loading)"); else kdb_printf(" (Live)"); - kdb_printf(" 0x%p", mod->module_core); + kdb_printf(" 0x%p", mod->core_layout.base); #ifdef CONFIG_MODULE_UNLOAD { diff --git a/kernel/module.c b/kernel/module.c index 14b224967e7b4..a0a3d6d9d5e80 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -108,13 +108,6 @@ static LIST_HEAD(modules); * Use a latched RB-tree for __module_address(); this allows us to use * RCU-sched lookups of the address from any context. * - * Because modules have two address ranges: init and core, we need two - * latch_tree_nodes entries. Therefore we need the back-pointer from - * mod_tree_node. - * - * Because init ranges are short lived we mark them unlikely and have placed - * them outside the critical cacheline in struct module. - * * This is conditional on PERF_EVENTS || TRACING because those can really hit * __module_address() hard by doing a lot of stack unwinding; potentially from * NMI context. @@ -122,24 +115,16 @@ static LIST_HEAD(modules); static __always_inline unsigned long __mod_tree_val(struct latch_tree_node *n) { - struct mod_tree_node *mtn = container_of(n, struct mod_tree_node, node); - struct module *mod = mtn->mod; + struct module_layout *layout = container_of(n, struct module_layout, mtn.node); - if (unlikely(mtn == &mod->mtn_init)) - return (unsigned long)mod->module_init; - - return (unsigned long)mod->module_core; + return (unsigned long)layout->base; } static __always_inline unsigned long __mod_tree_size(struct latch_tree_node *n) { - struct mod_tree_node *mtn = container_of(n, struct mod_tree_node, node); - struct module *mod = mtn->mod; - - if (unlikely(mtn == &mod->mtn_init)) - return (unsigned long)mod->init_size; + struct module_layout *layout = container_of(n, struct module_layout, mtn.node); - return (unsigned long)mod->core_size; + return (unsigned long)layout->size; } static __always_inline bool @@ -197,23 +182,23 @@ static void __mod_tree_remove(struct mod_tree_node *node) */ static void mod_tree_insert(struct module *mod) { - mod->mtn_core.mod = mod; - mod->mtn_init.mod = mod; + mod->core_layout.mtn.mod = mod; + mod->init_layout.mtn.mod = mod; - __mod_tree_insert(&mod->mtn_core); - if (mod->init_size) - __mod_tree_insert(&mod->mtn_init); + __mod_tree_insert(&mod->core_layout.mtn); + if (mod->init_layout.size) + __mod_tree_insert(&mod->init_layout.mtn); } static void mod_tree_remove_init(struct module *mod) { - if (mod->init_size) - __mod_tree_remove(&mod->mtn_init); + if (mod->init_layout.size) + __mod_tree_remove(&mod->init_layout.mtn); } static void mod_tree_remove(struct module *mod) { - __mod_tree_remove(&mod->mtn_core); + __mod_tree_remove(&mod->core_layout.mtn); mod_tree_remove_init(mod); } @@ -267,9 +252,9 @@ static void __mod_update_bounds(void *base, unsigned int size) static void mod_update_bounds(struct module *mod) { - __mod_update_bounds(mod->module_core, mod->core_size); - if (mod->init_size) - __mod_update_bounds(mod->module_init, mod->init_size); + __mod_update_bounds(mod->core_layout.base, mod->core_layout.size); + if (mod->init_layout.size) + __mod_update_bounds(mod->init_layout.base, mod->init_layout.size); } #ifdef CONFIG_KGDB_KDB @@ -1214,7 +1199,7 @@ struct module_attribute module_uevent = static ssize_t show_coresize(struct module_attribute *mattr, struct module_kobject *mk, char *buffer) { - return sprintf(buffer, "%u\n", mk->mod->core_size); + return sprintf(buffer, "%u\n", mk->mod->core_layout.size); } static struct module_attribute modinfo_coresize = @@ -1223,7 +1208,7 @@ static struct module_attribute modinfo_coresize = static ssize_t show_initsize(struct module_attribute *mattr, struct module_kobject *mk, char *buffer) { - return sprintf(buffer, "%u\n", mk->mod->init_size); + return sprintf(buffer, "%u\n", mk->mod->init_layout.size); } static struct module_attribute modinfo_initsize = @@ -1917,29 +1902,29 @@ static void set_section_ro_nx(void *base, static void set_module_core_ro_nx(struct module *mod) { - set_section_ro_nx(mod->module_core, mod->core_text_size, - mod->core_ro_size, mod->core_size, + set_section_ro_nx(mod->core_layout.base, mod->core_layout.text_size, + mod->core_layout.ro_size, mod->core_layout.size, set_memory_ro, set_memory_nx); } static void unset_module_core_ro_nx(struct module *mod) { - set_section_ro_nx(mod->module_core, mod->core_text_size, - mod->core_ro_size, mod->core_size, + set_section_ro_nx(mod->core_layout.base, mod->core_layout.text_size, + mod->core_layout.ro_size, mod->core_layout.size, set_memory_rw, set_memory_x); } static void set_module_init_ro_nx(struct module *mod) { - set_section_ro_nx(mod->module_init, mod->init_text_size, - mod->init_ro_size, mod->init_size, + set_section_ro_nx(mod->init_layout.base, mod->init_layout.text_size, + mod->init_layout.ro_size, mod->init_layout.size, set_memory_ro, set_memory_nx); } static void unset_module_init_ro_nx(struct module *mod) { - set_section_ro_nx(mod->module_init, mod->init_text_size, - mod->init_ro_size, mod->init_size, + set_section_ro_nx(mod->init_layout.base, mod->init_layout.text_size, + mod->init_layout.ro_size, mod->init_layout.size, set_memory_rw, set_memory_x); } @@ -1952,14 +1937,14 @@ void set_all_modules_text_rw(void) list_for_each_entry_rcu(mod, &modules, list) { if (mod->state == MODULE_STATE_UNFORMED) continue; - if ((mod->module_core) && (mod->core_text_size)) { - set_page_attributes(mod->module_core, - mod->module_core + mod->core_text_size, + if ((mod->core_layout.base) && (mod->core_layout.text_size)) { + set_page_attributes(mod->core_layout.base, + mod->core_layout.base + mod->core_layout.text_size, set_memory_rw); } - if ((mod->module_init) && (mod->init_text_size)) { - set_page_attributes(mod->module_init, - mod->module_init + mod->init_text_size, + if ((mod->init_layout.base) && (mod->init_layout.text_size)) { + set_page_attributes(mod->init_layout.base, + mod->init_layout.base + mod->init_layout.text_size, set_memory_rw); } } @@ -1975,14 +1960,14 @@ void set_all_modules_text_ro(void) list_for_each_entry_rcu(mod, &modules, list) { if (mod->state == MODULE_STATE_UNFORMED) continue; - if ((mod->module_core) && (mod->core_text_size)) { - set_page_attributes(mod->module_core, - mod->module_core + mod->core_text_size, + if ((mod->core_layout.base) && (mod->core_layout.text_size)) { + set_page_attributes(mod->core_layout.base, + mod->core_layout.base + mod->core_layout.text_size, set_memory_ro); } - if ((mod->module_init) && (mod->init_text_size)) { - set_page_attributes(mod->module_init, - mod->module_init + mod->init_text_size, + if ((mod->init_layout.base) && (mod->init_layout.text_size)) { + set_page_attributes(mod->init_layout.base, + mod->init_layout.base + mod->init_layout.text_size, set_memory_ro); } } @@ -2047,16 +2032,16 @@ static void free_module(struct module *mod) /* This may be NULL, but that's OK */ unset_module_init_ro_nx(mod); module_arch_freeing_init(mod); - module_memfree(mod->module_init); + module_memfree(mod->init_layout.base); kfree(mod->args); percpu_modfree(mod); /* Free lock-classes; relies on the preceding sync_rcu(). */ - lockdep_free_key_range(mod->module_core, mod->core_size); + lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size); /* Finally, free the core (containing the module structure) */ unset_module_core_ro_nx(mod); - module_memfree(mod->module_core); + module_memfree(mod->core_layout.base); #ifdef CONFIG_MPU update_protections(current->mm); @@ -2259,20 +2244,20 @@ static void layout_sections(struct module *mod, struct load_info *info) || s->sh_entsize != ~0UL || strstarts(sname, ".init")) continue; - s->sh_entsize = get_offset(mod, &mod->core_size, s, i); + s->sh_entsize = get_offset(mod, &mod->core_layout.size, s, i); pr_debug("\t%s\n", sname); } switch (m) { case 0: /* executable */ - mod->core_size = debug_align(mod->core_size); - mod->core_text_size = mod->core_size; + mod->core_layout.size = debug_align(mod->core_layout.size); + mod->core_layout.text_size = mod->core_layout.size; break; case 1: /* RO: text and ro-data */ - mod->core_size = debug_align(mod->core_size); - mod->core_ro_size = mod->core_size; + mod->core_layout.size = debug_align(mod->core_layout.size); + mod->core_layout.ro_size = mod->core_layout.size; break; case 3: /* whole core */ - mod->core_size = debug_align(mod->core_size); + mod->core_layout.size = debug_align(mod->core_layout.size); break; } } @@ -2288,21 +2273,21 @@ static void layout_sections(struct module *mod, struct load_info *info) || s->sh_entsize != ~0UL || !strstarts(sname, ".init")) continue; - s->sh_entsize = (get_offset(mod, &mod->init_size, s, i) + s->sh_entsize = (get_offset(mod, &mod->init_layout.size, s, i) | INIT_OFFSET_MASK); pr_debug("\t%s\n", sname); } switch (m) { case 0: /* executable */ - mod->init_size = debug_align(mod->init_size); - mod->init_text_size = mod->init_size; + mod->init_layout.size = debug_align(mod->init_layout.size); + mod->init_layout.text_size = mod->init_layout.size; break; case 1: /* RO: text and ro-data */ - mod->init_size = debug_align(mod->init_size); - mod->init_ro_size = mod->init_size; + mod->init_layout.size = debug_align(mod->init_layout.size); + mod->init_layout.ro_size = mod->init_layout.size; break; case 3: /* whole init */ - mod->init_size = debug_align(mod->init_size); + mod->init_layout.size = debug_align(mod->init_layout.size); break; } } @@ -2477,7 +2462,7 @@ static void layout_symtab(struct module *mod, struct load_info *info) /* Put symbol section at end of init part of module. */ symsect->sh_flags |= SHF_ALLOC; - symsect->sh_entsize = get_offset(mod, &mod->init_size, symsect, + symsect->sh_entsize = get_offset(mod, &mod->init_layout.size, symsect, info->index.sym) | INIT_OFFSET_MASK; pr_debug("\t%s\n", info->secstrings + symsect->sh_name); @@ -2494,16 +2479,16 @@ static void layout_symtab(struct module *mod, struct load_info *info) } /* Append room for core symbols at end of core part. */ - info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1); - info->stroffs = mod->core_size = info->symoffs + ndst * sizeof(Elf_Sym); - mod->core_size += strtab_size; - mod->core_size = debug_align(mod->core_size); + info->symoffs = ALIGN(mod->core_layout.size, symsect->sh_addralign ?: 1); + info->stroffs = mod->core_layout.size = info->symoffs + ndst * sizeof(Elf_Sym); + mod->core_layout.size += strtab_size; + mod->core_layout.size = debug_align(mod->core_layout.size); /* Put string table section at end of init part of module. */ strsect->sh_flags |= SHF_ALLOC; - strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect, + strsect->sh_entsize = get_offset(mod, &mod->init_layout.size, strsect, info->index.str) | INIT_OFFSET_MASK; - mod->init_size = debug_align(mod->init_size); + mod->init_layout.size = debug_align(mod->init_layout.size); pr_debug("\t%s\n", info->secstrings + strsect->sh_name); } @@ -2524,8 +2509,8 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) for (i = 0; i < mod->num_symtab; i++) mod->symtab[i].st_info = elf_type(&mod->symtab[i], info); - mod->core_symtab = dst = mod->module_core + info->symoffs; - mod->core_strtab = s = mod->module_core + info->stroffs; + mod->core_symtab = dst = mod->core_layout.base + info->symoffs; + mod->core_strtab = s = mod->core_layout.base + info->stroffs; src = mod->symtab; for (ndst = i = 0; i < mod->num_symtab; i++) { if (i == 0 || @@ -2975,7 +2960,7 @@ static int move_module(struct module *mod, struct load_info *info) void *ptr; /* Do the allocs. */ - ptr = module_alloc(mod->core_size); + ptr = module_alloc(mod->core_layout.size); /* * The pointer to this block is stored in the module structure * which is inside the block. Just mark it as not being a @@ -2985,11 +2970,11 @@ static int move_module(struct module *mod, struct load_info *info) if (!ptr) return -ENOMEM; - memset(ptr, 0, mod->core_size); - mod->module_core = ptr; + memset(ptr, 0, mod->core_layout.size); + mod->core_layout.base = ptr; - if (mod->init_size) { - ptr = module_alloc(mod->init_size); + if (mod->init_layout.size) { + ptr = module_alloc(mod->init_layout.size); /* * The pointer to this block is stored in the module structure * which is inside the block. This block doesn't need to be @@ -2998,13 +2983,13 @@ static int move_module(struct module *mod, struct load_info *info) */ kmemleak_ignore(ptr); if (!ptr) { - module_memfree(mod->module_core); + module_memfree(mod->core_layout.base); return -ENOMEM; } - memset(ptr, 0, mod->init_size); - mod->module_init = ptr; + memset(ptr, 0, mod->init_layout.size); + mod->init_layout.base = ptr; } else - mod->module_init = NULL; + mod->init_layout.base = NULL; /* Transfer each section which specifies SHF_ALLOC */ pr_debug("final section addresses:\n"); @@ -3016,10 +3001,10 @@ static int move_module(struct module *mod, struct load_info *info) continue; if (shdr->sh_entsize & INIT_OFFSET_MASK) - dest = mod->module_init + dest = mod->init_layout.base + (shdr->sh_entsize & ~INIT_OFFSET_MASK); else - dest = mod->module_core + shdr->sh_entsize; + dest = mod->core_layout.base + shdr->sh_entsize; if (shdr->sh_type != SHT_NOBITS) memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size); @@ -3081,12 +3066,12 @@ static void flush_module_icache(const struct module *mod) * Do it before processing of module parameters, so the module * can provide parameter accessor functions of its own. */ - if (mod->module_init) - flush_icache_range((unsigned long)mod->module_init, - (unsigned long)mod->module_init - + mod->init_size); - flush_icache_range((unsigned long)mod->module_core, - (unsigned long)mod->module_core + mod->core_size); + if (mod->init_layout.base) + flush_icache_range((unsigned long)mod->init_layout.base, + (unsigned long)mod->init_layout.base + + mod->init_layout.size); + flush_icache_range((unsigned long)mod->core_layout.base, + (unsigned long)mod->core_layout.base + mod->core_layout.size); set_fs(old_fs); } @@ -3144,8 +3129,8 @@ static void module_deallocate(struct module *mod, struct load_info *info) { percpu_modfree(mod); module_arch_freeing_init(mod); - module_memfree(mod->module_init); - module_memfree(mod->module_core); + module_memfree(mod->init_layout.base); + module_memfree(mod->core_layout.base); } int __weak module_finalize(const Elf_Ehdr *hdr, @@ -3232,7 +3217,7 @@ static noinline int do_init_module(struct module *mod) ret = -ENOMEM; goto fail; } - freeinit->module_init = mod->module_init; + freeinit->module_init = mod->init_layout.base; /* * We want to find out whether @mod uses async during init. Clear @@ -3292,10 +3277,10 @@ static noinline int do_init_module(struct module *mod) mod_tree_remove_init(mod); unset_module_init_ro_nx(mod); module_arch_freeing_init(mod); - mod->module_init = NULL; - mod->init_size = 0; - mod->init_ro_size = 0; - mod->init_text_size = 0; + mod->init_layout.base = NULL; + mod->init_layout.size = 0; + mod->init_layout.ro_size = 0; + mod->init_layout.text_size = 0; /* * We want to free module_init, but be aware that kallsyms may be * walking this with preempt disabled. In all the failure paths, we @@ -3575,7 +3560,7 @@ static int load_module(struct load_info *info, const char __user *uargs, mutex_unlock(&module_mutex); free_module: /* Free lock-classes; relies on the preceding sync_rcu() */ - lockdep_free_key_range(mod->module_core, mod->core_size); + lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size); module_deallocate(mod, info); free_copy: @@ -3653,9 +3638,9 @@ static const char *get_ksymbol(struct module *mod, /* At worse, next value is at end of module */ if (within_module_init(addr, mod)) - nextval = (unsigned long)mod->module_init+mod->init_text_size; + nextval = (unsigned long)mod->init_layout.base+mod->init_layout.text_size; else - nextval = (unsigned long)mod->module_core+mod->core_text_size; + nextval = (unsigned long)mod->core_layout.base+mod->core_layout.text_size; /* Scan for closest preceding symbol, and next symbol. (ELF starts real symbols at 1). */ @@ -3902,7 +3887,7 @@ static int m_show(struct seq_file *m, void *p) return 0; seq_printf(m, "%s %u", - mod->name, mod->init_size + mod->core_size); + mod->name, mod->init_layout.size + mod->core_layout.size); print_unload_info(m, mod); /* Informative for users. */ @@ -3911,7 +3896,7 @@ static int m_show(struct seq_file *m, void *p) mod->state == MODULE_STATE_COMING ? "Loading" : "Live"); /* Used by oprofile and other similar tools. */ - seq_printf(m, " 0x%pK", mod->module_core); + seq_printf(m, " 0x%pK", mod->core_layout.base); /* Taints info */ if (mod->taints) @@ -4054,8 +4039,8 @@ struct module *__module_text_address(unsigned long addr) struct module *mod = __module_address(addr); if (mod) { /* Make sure it's within the text section. */ - if (!within(addr, mod->module_init, mod->init_text_size) - && !within(addr, mod->module_core, mod->core_text_size)) + if (!within(addr, mod->init_layout.base, mod->init_layout.text_size) + && !within(addr, mod->core_layout.base, mod->core_layout.text_size)) mod = NULL; } return mod; -- GitLab From 85c898db6327353d38f3dd428457384cf81f83f8 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 26 Nov 2015 09:45:08 +1030 Subject: [PATCH 0953/2855] module: clean up RO/NX handling. Modules have three sections: text, rodata and writable data. The code handled the case where these overlapped, however they never can: debug_align() ensures they are always page-aligned. This is why we got away with manually traversing the pages in set_all_modules_text_rw() without rounding. We create three helper functions: frob_text(), frob_rodata() and frob_writable_data(). We then call these explicitly at every point, so it's clear what we're doing. We also expose module_enable_ro() and module_disable_ro() for livepatch to use. Reviewed-by: Josh Poimboeuf Signed-off-by: Rusty Russell Signed-off-by: Jiri Kosina --- include/linux/module.h | 4 + kernel/module.c | 168 +++++++++++++++++++---------------------- 2 files changed, 81 insertions(+), 91 deletions(-) diff --git a/include/linux/module.h b/include/linux/module.h index 6e68e8cf4d0d2..4560d8f1545d2 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -762,9 +762,13 @@ extern int module_sysfs_initialized; #ifdef CONFIG_DEBUG_SET_MODULE_RONX extern void set_all_modules_text_rw(void); extern void set_all_modules_text_ro(void); +extern void module_enable_ro(const struct module *mod); +extern void module_disable_ro(const struct module *mod); #else static inline void set_all_modules_text_rw(void) { } static inline void set_all_modules_text_ro(void) { } +static inline void module_enable_ro(const struct module *mod) { } +static inline void module_disable_ro(const struct module *mod) { } #endif #ifdef CONFIG_GENERIC_BUG diff --git a/kernel/module.c b/kernel/module.c index a0a3d6d9d5e80..77212128f34ad 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -80,15 +80,6 @@ # define debug_align(X) (X) #endif -/* - * Given BASE and SIZE this macro calculates the number of pages the - * memory regions occupies - */ -#define MOD_NUMBER_OF_PAGES(BASE, SIZE) (((SIZE) > 0) ? \ - (PFN_DOWN((unsigned long)(BASE) + (SIZE) - 1) - \ - PFN_DOWN((unsigned long)BASE) + 1) \ - : (0UL)) - /* If this is set, the section belongs in the init part of the module */ #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) @@ -1858,74 +1849,75 @@ static void mod_sysfs_teardown(struct module *mod) /* * LKM RO/NX protection: protect module's text/ro-data * from modification and any data from execution. + * + * General layout of module is: + * [text] [read-only-data] [writable data] + * text_size -----^ ^ ^ + * ro_size ------------------------| | + * size -------------------------------------------| + * + * These values are always page-aligned (as is base) */ -void set_page_attributes(void *start, void *end, int (*set)(unsigned long start, int num_pages)) +static void frob_text(const struct module_layout *layout, + int (*set_memory)(unsigned long start, int num_pages)) { - unsigned long begin_pfn = PFN_DOWN((unsigned long)start); - unsigned long end_pfn = PFN_DOWN((unsigned long)end); - - if (end_pfn > begin_pfn) - set(begin_pfn << PAGE_SHIFT, end_pfn - begin_pfn); + BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); + BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1)); + set_memory((unsigned long)layout->base, + layout->text_size >> PAGE_SHIFT); } -static void set_section_ro_nx(void *base, - unsigned long text_size, - unsigned long ro_size, - unsigned long total_size, - int (*set_ro)(unsigned long start, int num_pages), - int (*set_nx)(unsigned long start, int num_pages)) +static void frob_rodata(const struct module_layout *layout, + int (*set_memory)(unsigned long start, int num_pages)) { - /* begin and end PFNs of the current subsection */ - unsigned long begin_pfn; - unsigned long end_pfn; - - /* - * Set RO for module text and RO-data: - * - Always protect first page. - * - Do not protect last partial page. - */ - if (ro_size > 0) - set_page_attributes(base, base + ro_size, set_ro); + BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); + BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1)); + BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1)); + set_memory((unsigned long)layout->base + layout->text_size, + (layout->ro_size - layout->text_size) >> PAGE_SHIFT); +} - /* - * Set NX permissions for module data: - * - Do not protect first partial page. - * - Always protect last page. - */ - if (total_size > text_size) { - begin_pfn = PFN_UP((unsigned long)base + text_size); - end_pfn = PFN_UP((unsigned long)base + total_size); - if (end_pfn > begin_pfn) - set_nx(begin_pfn << PAGE_SHIFT, end_pfn - begin_pfn); - } +static void frob_writable_data(const struct module_layout *layout, + int (*set_memory)(unsigned long start, int num_pages)) +{ + BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); + BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1)); + BUG_ON((unsigned long)layout->size & (PAGE_SIZE-1)); + set_memory((unsigned long)layout->base + layout->ro_size, + (layout->size - layout->ro_size) >> PAGE_SHIFT); } -static void set_module_core_ro_nx(struct module *mod) +/* livepatching wants to disable read-only so it can frob module. */ +void module_disable_ro(const struct module *mod) { - set_section_ro_nx(mod->core_layout.base, mod->core_layout.text_size, - mod->core_layout.ro_size, mod->core_layout.size, - set_memory_ro, set_memory_nx); + frob_text(&mod->core_layout, set_memory_rw); + frob_rodata(&mod->core_layout, set_memory_rw); + frob_text(&mod->init_layout, set_memory_rw); + frob_rodata(&mod->init_layout, set_memory_rw); } -static void unset_module_core_ro_nx(struct module *mod) +void module_enable_ro(const struct module *mod) { - set_section_ro_nx(mod->core_layout.base, mod->core_layout.text_size, - mod->core_layout.ro_size, mod->core_layout.size, - set_memory_rw, set_memory_x); + frob_text(&mod->core_layout, set_memory_ro); + frob_rodata(&mod->core_layout, set_memory_ro); + frob_text(&mod->init_layout, set_memory_ro); + frob_rodata(&mod->init_layout, set_memory_ro); } -static void set_module_init_ro_nx(struct module *mod) +static void module_enable_nx(const struct module *mod) { - set_section_ro_nx(mod->init_layout.base, mod->init_layout.text_size, - mod->init_layout.ro_size, mod->init_layout.size, - set_memory_ro, set_memory_nx); + frob_rodata(&mod->core_layout, set_memory_nx); + frob_writable_data(&mod->core_layout, set_memory_nx); + frob_rodata(&mod->init_layout, set_memory_nx); + frob_writable_data(&mod->init_layout, set_memory_nx); } -static void unset_module_init_ro_nx(struct module *mod) +static void module_disable_nx(const struct module *mod) { - set_section_ro_nx(mod->init_layout.base, mod->init_layout.text_size, - mod->init_layout.ro_size, mod->init_layout.size, - set_memory_rw, set_memory_x); + frob_rodata(&mod->core_layout, set_memory_x); + frob_writable_data(&mod->core_layout, set_memory_x); + frob_rodata(&mod->init_layout, set_memory_x); + frob_writable_data(&mod->init_layout, set_memory_x); } /* Iterate through all modules and set each module's text as RW */ @@ -1937,16 +1929,9 @@ void set_all_modules_text_rw(void) list_for_each_entry_rcu(mod, &modules, list) { if (mod->state == MODULE_STATE_UNFORMED) continue; - if ((mod->core_layout.base) && (mod->core_layout.text_size)) { - set_page_attributes(mod->core_layout.base, - mod->core_layout.base + mod->core_layout.text_size, - set_memory_rw); - } - if ((mod->init_layout.base) && (mod->init_layout.text_size)) { - set_page_attributes(mod->init_layout.base, - mod->init_layout.base + mod->init_layout.text_size, - set_memory_rw); - } + + frob_text(&mod->core_layout, set_memory_rw); + frob_text(&mod->init_layout, set_memory_rw); } mutex_unlock(&module_mutex); } @@ -1960,24 +1945,25 @@ void set_all_modules_text_ro(void) list_for_each_entry_rcu(mod, &modules, list) { if (mod->state == MODULE_STATE_UNFORMED) continue; - if ((mod->core_layout.base) && (mod->core_layout.text_size)) { - set_page_attributes(mod->core_layout.base, - mod->core_layout.base + mod->core_layout.text_size, - set_memory_ro); - } - if ((mod->init_layout.base) && (mod->init_layout.text_size)) { - set_page_attributes(mod->init_layout.base, - mod->init_layout.base + mod->init_layout.text_size, - set_memory_ro); - } + + frob_text(&mod->core_layout, set_memory_ro); + frob_text(&mod->init_layout, set_memory_ro); } mutex_unlock(&module_mutex); } + +static void disable_ro_nx(const struct module_layout *layout) +{ + frob_text(layout, set_memory_rw); + frob_rodata(layout, set_memory_rw); + frob_rodata(layout, set_memory_x); + frob_writable_data(layout, set_memory_x); +} + #else -static void set_module_core_ro_nx(struct module *mod) { } -static void set_module_init_ro_nx(struct module *mod) { } -static void unset_module_core_ro_nx(struct module *mod) { } -static void unset_module_init_ro_nx(struct module *mod) { } +static void disable_ro_nx(const struct module_layout *layout) { } +static void module_enable_nx(const struct module *mod) { } +static void module_disable_nx(const struct module *mod) { } #endif void __weak module_memfree(void *module_region) @@ -2029,8 +2015,8 @@ static void free_module(struct module *mod) synchronize_sched(); mutex_unlock(&module_mutex); - /* This may be NULL, but that's OK */ - unset_module_init_ro_nx(mod); + /* This may be empty, but that's OK */ + disable_ro_nx(&mod->init_layout); module_arch_freeing_init(mod); module_memfree(mod->init_layout.base); kfree(mod->args); @@ -2040,7 +2026,7 @@ static void free_module(struct module *mod) lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size); /* Finally, free the core (containing the module structure) */ - unset_module_core_ro_nx(mod); + disable_ro_nx(&mod->core_layout); module_memfree(mod->core_layout.base); #ifdef CONFIG_MPU @@ -3275,7 +3261,7 @@ static noinline int do_init_module(struct module *mod) mod->strtab = mod->core_strtab; #endif mod_tree_remove_init(mod); - unset_module_init_ro_nx(mod); + disable_ro_nx(&mod->init_layout); module_arch_freeing_init(mod); mod->init_layout.base = NULL; mod->init_layout.size = 0; @@ -3370,8 +3356,8 @@ static int complete_formation(struct module *mod, struct load_info *info) module_bug_finalize(info->hdr, info->sechdrs, mod); /* Set RO and NX regions */ - set_module_init_ro_nx(mod); - set_module_core_ro_nx(mod); + module_enable_ro(mod); + module_enable_nx(mod); /* Mark state as coming so strong_try_module_get() ignores us, * but kallsyms etc. can see us. */ @@ -3536,8 +3522,8 @@ static int load_module(struct load_info *info, const char __user *uargs, MODULE_STATE_GOING, mod); /* we can't deallocate the module until we clear memory protection */ - unset_module_init_ro_nx(mod); - unset_module_core_ro_nx(mod); + module_disable_ro(mod); + module_disable_nx(mod); ddebug_cleanup: dynamic_debug_remove(info->debug); -- GitLab From e0224418516b4d8a6c2160574bac18447c354ef0 Mon Sep 17 00:00:00 2001 From: Miroslav Benes Date: Thu, 26 Nov 2015 13:18:06 +1030 Subject: [PATCH 0954/2855] module: keep percpu symbols in module's symtab Currently, percpu symbols from .data..percpu ELF section of a module are not copied over and stored in final symtab array of struct module. Consequently such symbol cannot be returned via kallsyms API (for example kallsyms_lookup_name). This can be especially confusing when the percpu symbol is exported. Only its __ksymtab et al. are present in its symtab. The culprit is in layout_and_allocate() function where SHF_ALLOC flag is dropped for .data..percpu section. There is in fact no need to copy the section to final struct module, because kernel module loader allocates extra percpu section by itself. Unfortunately only symbols from SHF_ALLOC sections are copied due to a check in is_core_symbol(). The patch changes is_core_symbol() function to copy over also percpu symbols (their st_shndx points to .data..percpu ELF section). We do it only if CONFIG_KALLSYMS_ALL is set to be consistent with the rest of the function (ELF section is SHF_ALLOC but !SHF_EXECINSTR). Finally elf_type() returns type 'a' for a percpu symbol because its address is absolute. Signed-off-by: Miroslav Benes Signed-off-by: Rusty Russell Signed-off-by: Jiri Kosina --- kernel/module.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/kernel/module.c b/kernel/module.c index 77212128f34ad..912e891e0e2f1 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2383,7 +2383,7 @@ static char elf_type(const Elf_Sym *sym, const struct load_info *info) } if (sym->st_shndx == SHN_UNDEF) return 'U'; - if (sym->st_shndx == SHN_ABS) + if (sym->st_shndx == SHN_ABS || sym->st_shndx == info->index.pcpu) return 'a'; if (sym->st_shndx >= SHN_LORESERVE) return '?'; @@ -2412,7 +2412,7 @@ static char elf_type(const Elf_Sym *sym, const struct load_info *info) } static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs, - unsigned int shnum) + unsigned int shnum, unsigned int pcpundx) { const Elf_Shdr *sec; @@ -2421,6 +2421,11 @@ static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs, || !src->st_name) return false; +#ifdef CONFIG_KALLSYMS_ALL + if (src->st_shndx == pcpundx) + return true; +#endif + sec = sechdrs + src->st_shndx; if (!(sec->sh_flags & SHF_ALLOC) #ifndef CONFIG_KALLSYMS_ALL @@ -2458,7 +2463,8 @@ static void layout_symtab(struct module *mod, struct load_info *info) /* Compute total space required for the core symbols' strtab. */ for (ndst = i = 0; i < nsrc; i++) { if (i == 0 || - is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { + is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum, + info->index.pcpu)) { strtab_size += strlen(&info->strtab[src[i].st_name])+1; ndst++; } @@ -2500,7 +2506,8 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) src = mod->symtab; for (ndst = i = 0; i < mod->num_symtab; i++) { if (i == 0 || - is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { + is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum, + info->index.pcpu)) { dst[ndst] = src[i]; dst[ndst++].st_name = s - mod->core_strtab; s += strlcpy(s, &mod->strtab[src[i].st_name], -- GitLab From b56b36ee6751abe7fb3890681e86fc8de2122953 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 3 Dec 2015 16:33:26 -0600 Subject: [PATCH 0955/2855] livepatch: Cleanup module page permission changes Calling set_memory_rw() and set_memory_ro() for every iteration of the loop in klp_write_object_relocations() is messy, inefficient, and error-prone. Change all the read-only pages to read-write before the loop and convert them back to read-only again afterwards. Suggested-by: Miroslav Benes Signed-off-by: Josh Poimboeuf Reviewed-by: Petr Mladek Signed-off-by: Jiri Kosina --- arch/x86/kernel/livepatch.c | 25 ++----------------------- kernel/livepatch/core.c | 16 +++++++++++----- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/arch/x86/kernel/livepatch.c b/arch/x86/kernel/livepatch.c index bcc06e82a593e..92fc1a51f994e 100644 --- a/arch/x86/kernel/livepatch.c +++ b/arch/x86/kernel/livepatch.c @@ -20,8 +20,6 @@ #include #include -#include -#include #include #include @@ -38,8 +36,7 @@ int klp_write_module_reloc(struct module *mod, unsigned long type, unsigned long loc, unsigned long value) { - int ret, numpages, size = 4; - bool readonly; + size_t size = 4; unsigned long val; unsigned long core = (unsigned long)mod->core_layout.base; unsigned long core_size = mod->core_layout.size; @@ -69,23 +66,5 @@ int klp_write_module_reloc(struct module *mod, unsigned long type, /* loc does not point to any symbol inside the module */ return -EINVAL; - readonly = false; - -#ifdef CONFIG_DEBUG_SET_MODULE_RONX - if (loc < core + mod->core_layout.ro_size) - readonly = true; -#endif - - /* determine if the relocation spans a page boundary */ - numpages = ((loc & PAGE_MASK) == ((loc + size) & PAGE_MASK)) ? 1 : 2; - - if (readonly) - set_memory_rw(loc & PAGE_MASK, numpages); - - ret = probe_kernel_write((void *)loc, &val, size); - - if (readonly) - set_memory_ro(loc & PAGE_MASK, numpages); - - return ret; + return probe_kernel_write((void *)loc, &val, size); } diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 94893e844e445..bc2c85c064c1b 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -28,6 +28,7 @@ #include #include #include +#include /** * struct klp_ops - structure for tracking registered ftrace ops structs @@ -232,7 +233,7 @@ static int klp_find_external_symbol(struct module *pmod, const char *name, static int klp_write_object_relocations(struct module *pmod, struct klp_object *obj) { - int ret; + int ret = 0; unsigned long val; struct klp_reloc *reloc; @@ -242,13 +243,16 @@ static int klp_write_object_relocations(struct module *pmod, if (WARN_ON(!obj->relocs)) return -EINVAL; + module_disable_ro(pmod); + for (reloc = obj->relocs; reloc->name; reloc++) { /* discover the address of the referenced symbol */ if (reloc->external) { if (reloc->sympos > 0) { pr_err("non-zero sympos for external reloc symbol '%s' is not supported\n", reloc->name); - return -EINVAL; + ret = -EINVAL; + goto out; } ret = klp_find_external_symbol(pmod, reloc->name, &val); } else @@ -257,18 +261,20 @@ static int klp_write_object_relocations(struct module *pmod, reloc->sympos, &val); if (ret) - return ret; + goto out; ret = klp_write_module_reloc(pmod, reloc->type, reloc->loc, val + reloc->addend); if (ret) { pr_err("relocation failed for symbol '%s' at 0x%016lx (%d)\n", reloc->name, val, ret); - return ret; + goto out; } } - return 0; +out: + module_enable_ro(pmod); + return ret; } static void notrace klp_ftrace_handler(unsigned long ip, -- GitLab From 2524534dbb2372a666f30e0da2f97cd7f0d7f76c Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Thu, 19 Nov 2015 19:28:39 -0800 Subject: [PATCH 0956/2855] mtd: partitions: turn PART() macro into inline function We can guard against reorganization of struct mtd_part by using container_of(). We can also make sure we're using the right pointer types by making this a static inline function instead of a macro. Signed-off-by: Brian Norris --- drivers/mtd/mtdpart.c | 63 ++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 1fa3ca95d9c10..c32b127b19767 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -48,9 +48,12 @@ struct mtd_part { /* * Given a pointer to the MTD object in the mtd_part structure, we can retrieve - * the pointer to that structure with this macro. + * the pointer to that structure. */ -#define PART(x) ((struct mtd_part *)(x)) +static inline struct mtd_part *mtd_to_part(const struct mtd_info *mtd) +{ + return container_of(mtd, struct mtd_part, mtd); +} /* @@ -61,7 +64,7 @@ struct mtd_part { static int part_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); struct mtd_ecc_stats stats; int res; @@ -80,7 +83,7 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len, static int part_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); return part->master->_point(part->master, from + part->offset, len, retlen, virt, phys); @@ -88,7 +91,7 @@ static int part_point(struct mtd_info *mtd, loff_t from, size_t len, static int part_unpoint(struct mtd_info *mtd, loff_t from, size_t len) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); return part->master->_unpoint(part->master, from + part->offset, len); } @@ -98,7 +101,7 @@ static unsigned long part_get_unmapped_area(struct mtd_info *mtd, unsigned long offset, unsigned long flags) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); offset += part->offset; return part->master->_get_unmapped_area(part->master, len, offset, @@ -108,7 +111,7 @@ static unsigned long part_get_unmapped_area(struct mtd_info *mtd, static int part_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); int res; if (from >= mtd->size) @@ -146,7 +149,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from, static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); return part->master->_read_user_prot_reg(part->master, from, len, retlen, buf); } @@ -154,7 +157,7 @@ static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from, static int part_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen, struct otp_info *buf) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); return part->master->_get_user_prot_info(part->master, len, retlen, buf); } @@ -162,7 +165,7 @@ static int part_get_user_prot_info(struct mtd_info *mtd, size_t len, static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); return part->master->_read_fact_prot_reg(part->master, from, len, retlen, buf); } @@ -170,7 +173,7 @@ static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, static int part_get_fact_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen, struct otp_info *buf) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); return part->master->_get_fact_prot_info(part->master, len, retlen, buf); } @@ -178,7 +181,7 @@ static int part_get_fact_prot_info(struct mtd_info *mtd, size_t len, static int part_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); return part->master->_write(part->master, to + part->offset, len, retlen, buf); } @@ -186,7 +189,7 @@ static int part_write(struct mtd_info *mtd, loff_t to, size_t len, static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); return part->master->_panic_write(part->master, to + part->offset, len, retlen, buf); } @@ -194,7 +197,7 @@ static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len, static int part_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); if (to >= mtd->size) return -EINVAL; @@ -206,7 +209,7 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to, static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); return part->master->_write_user_prot_reg(part->master, from, len, retlen, buf); } @@ -214,21 +217,21 @@ static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from, static int part_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); return part->master->_lock_user_prot_reg(part->master, from, len); } static int part_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); return part->master->_writev(part->master, vecs, count, to + part->offset, retlen); } static int part_erase(struct mtd_info *mtd, struct erase_info *instr) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); int ret; instr->addr += part->offset; @@ -244,7 +247,7 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr) void mtd_erase_callback(struct erase_info *instr) { if (instr->mtd->_erase == part_erase) { - struct mtd_part *part = PART(instr->mtd); + struct mtd_part *part = mtd_to_part(instr->mtd); if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) instr->fail_addr -= part->offset; @@ -257,57 +260,57 @@ EXPORT_SYMBOL_GPL(mtd_erase_callback); static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); return part->master->_lock(part->master, ofs + part->offset, len); } static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); return part->master->_unlock(part->master, ofs + part->offset, len); } static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); return part->master->_is_locked(part->master, ofs + part->offset, len); } static void part_sync(struct mtd_info *mtd) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); part->master->_sync(part->master); } static int part_suspend(struct mtd_info *mtd) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); return part->master->_suspend(part->master); } static void part_resume(struct mtd_info *mtd) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); part->master->_resume(part->master); } static int part_block_isreserved(struct mtd_info *mtd, loff_t ofs) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); ofs += part->offset; return part->master->_block_isreserved(part->master, ofs); } static int part_block_isbad(struct mtd_info *mtd, loff_t ofs) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); ofs += part->offset; return part->master->_block_isbad(part->master, ofs); } static int part_block_markbad(struct mtd_info *mtd, loff_t ofs) { - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); int res; ofs += part->offset; @@ -558,7 +561,7 @@ static ssize_t mtd_partition_offset_show(struct device *dev, struct device_attribute *attr, char *buf) { struct mtd_info *mtd = dev_get_drvdata(dev); - struct mtd_part *part = PART(mtd); + struct mtd_part *part = mtd_to_part(mtd); return snprintf(buf, PAGE_SIZE, "%lld\n", part->offset); } @@ -814,6 +817,6 @@ uint64_t mtd_get_device_size(const struct mtd_info *mtd) if (!mtd_is_partition(mtd)) return mtd->size; - return PART(mtd)->master->size; + return mtd_to_part(mtd)->master->size; } EXPORT_SYMBOL_GPL(mtd_get_device_size); -- GitLab From 0f6d3f4097d2746925986af5e34b864c5f6b2682 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 20 Nov 2015 17:38:33 -0800 Subject: [PATCH 0957/2855] mtd: mtk-quadspi: drop unnecessary .owner assignment As of commit 807f16d4db95 ("mtd: core: set some defaults when dev.parent is set"), the MTD core will set this for us. Signed-off-by: Brian Norris Cc: Bayi Cheng --- drivers/mtd/spi-nor/mtk-quadspi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/spi-nor/mtk-quadspi.c b/drivers/mtd/spi-nor/mtk-quadspi.c index dd269650cd164..e1dd9fd16fbe0 100644 --- a/drivers/mtd/spi-nor/mtk-quadspi.c +++ b/drivers/mtd/spi-nor/mtk-quadspi.c @@ -390,7 +390,6 @@ static int __init mtk_nor_init(struct mt8173_nor *mt8173_nor, nor->read_reg = mt8173_nor_read_reg; nor->write = mt8173_nor_write; nor->write_reg = mt8173_nor_write_reg; - nor->mtd.owner = THIS_MODULE; nor->mtd.name = "mtk_nor"; /* initialized with NULL */ ret = spi_nor_scan(nor, NULL, SPI_NOR_DUAL); -- GitLab From d6af26944a02e6d325b82160d52e08dc4e315396 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 17 Nov 2015 20:18:54 +0100 Subject: [PATCH 0958/2855] mtd: spi-nor: fix error handling in spi_nor_erase The documenting comment of mtd_erase in mtdcore.c states: Device drivers are supposed to call instr->callback() whenever the operation completes, even if it completes with a failure. Currently the callback isn't called in case of failure. Fix this. Signed-off-by: Heiner Kallweit Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/spi-nor.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index f8a9b77aac768..3b2460efc0199 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -410,17 +410,13 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) write_disable(nor); +erase_err: spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE); - instr->state = MTD_ERASE_DONE; + instr->state = ret ? MTD_ERASE_FAILED : MTD_ERASE_DONE; mtd_erase_callback(instr); return ret; - -erase_err: - spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE); - instr->state = MTD_ERASE_FAILED; - return ret; } static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs, -- GitLab From 41849d49d7d5307d7399314b59fb16d1c39ce0f0 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 21 Nov 2015 12:14:44 +0100 Subject: [PATCH 0959/2855] mtd: nand: r852: Remove unnecessary synchronize_irq() before free_irq() Calling synchronize_irq() right before free_irq() is quite useless. On one hand the IRQ can easily fire again before free_irq() is entered, on the other hand free_irq() itself calls synchronize_irq() internally (in a race condition free way), before any state associated with the IRQ is freed. Patch was generated using the following semantic patch: // @@ expression irq; @@ -synchronize_irq(irq); free_irq(irq, ...); // Signed-off-by: Lars-Peter Clausen Signed-off-by: Brian Norris --- drivers/mtd/nand/r852.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index d8bb2be327f11..be28cddec9cdf 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c @@ -980,7 +980,6 @@ static void r852_remove(struct pci_dev *pci_dev) /* Stop interrupts */ r852_disable_irqs(dev); - synchronize_irq(dev->irq); free_irq(dev->irq, dev); /* Cleanup */ -- GitLab From b7e16ec6e3d2ea0b62cf93a0e849db55f403a871 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 6 Nov 2015 16:48:46 +0100 Subject: [PATCH 0960/2855] power: bq2415x_charger: Delete unnecessary checks before the function call "of_node_put" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The of_node_put() function tests whether its argument is NULL and then returns immediately. Thus the test around the calls is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Acked-by: Pali Rohár Signed-off-by: Sebastian Reichel --- drivers/power/bq2415x_charger.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c index 4afd76848bce5..27e89536689aa 100644 --- a/drivers/power/bq2415x_charger.c +++ b/drivers/power/bq2415x_charger.c @@ -1704,7 +1704,7 @@ error_4: error_3: bq2415x_power_supply_exit(bq); error_2: - if (bq && bq->notify_node) + if (bq) of_node_put(bq->notify_node); kfree(name); error_1: @@ -1724,9 +1724,7 @@ static int bq2415x_remove(struct i2c_client *client) if (bq->nb.notifier_call) power_supply_unreg_notifier(&bq->nb); - if (bq->notify_node) - of_node_put(bq->notify_node); - + of_node_put(bq->notify_node); bq2415x_sysfs_exit(bq); bq2415x_power_supply_exit(bq); -- GitLab From 79fbdb66cf6ab4e26e7bcb8399ac02cd81fc5d6d Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 13 Nov 2015 19:41:34 +0100 Subject: [PATCH 0961/2855] power: ds2782_battery: constify ds278x_battery_ops structure The ds278x_battery_ops structure is never modified, so declare it as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Sebastian Reichel --- drivers/power/ds2782_battery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/power/ds2782_battery.c b/drivers/power/ds2782_battery.c index ed4d756d21e4b..a1b7e0592245a 100644 --- a/drivers/power/ds2782_battery.c +++ b/drivers/power/ds2782_battery.c @@ -59,7 +59,7 @@ struct ds278x_info { struct i2c_client *client; struct power_supply *battery; struct power_supply_desc battery_desc; - struct ds278x_battery_ops *ops; + const struct ds278x_battery_ops *ops; struct delayed_work bat_work; int id; int rsns; @@ -361,7 +361,7 @@ enum ds278x_num_id { DS2786, }; -static struct ds278x_battery_ops ds278x_ops[] = { +static const struct ds278x_battery_ops ds278x_ops[] = { [DS2782] = { .get_battery_current = ds2782_get_current, .get_battery_voltage = ds2782_get_voltage, -- GitLab From c4c0edfbf875a5ecb38a4aa65e2bdb87739e81d6 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 18 Nov 2015 23:04:14 +0100 Subject: [PATCH 0962/2855] power/reset: at91-reset: add missing of_node_put for_each_matching_node performs an of_node_get on each iteration, so a break out of the loop requires an of_node_put. A simplified version of the semantic patch that fixes this problem is as follows (http://coccinelle.lip6.fr): // @@ expression e,e1; local idexpression np; @@ for_each_matching_node(np, e1) { ... when != of_node_put(np) when != e = np ( return np; | + of_node_put(np); ? return ...; ) ... } // Signed-off-by: Julia Lawall Signed-off-by: Sebastian Reichel --- drivers/power/reset/at91-reset.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index 3f6b5dd7c3d4e..1b5d450586d18 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -198,6 +198,7 @@ static int __init at91_reset_probe(struct platform_device *pdev) at91_ramc_base[idx] = of_iomap(np, 0); if (!at91_ramc_base[idx]) { dev_err(&pdev->dev, "Could not map ram controller address\n"); + of_node_put(np); return -ENODEV; } idx++; -- GitLab From d5fdfedc0ed946e96b2ac06d48b230e370105d7e Mon Sep 17 00:00:00 2001 From: Saurabh Sengar Date: Thu, 19 Nov 2015 12:42:59 +0530 Subject: [PATCH 0963/2855] power: max8903_charger: set IRQF_ONESHOT if no primary handler is specified If no primary handler is specified for threaded_irq then a default one is assigned which always returns IRQ_WAKE_THREAD. This handler requires the IRQF_ONESHOT, because the source of interrupt is not disabled. Signed-off-by: Saurabh Sengar Signed-off-by: Sebastian Reichel --- drivers/power/max8903_charger.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/power/max8903_charger.c b/drivers/power/max8903_charger.c index 6d39d52040d4a..17876caf31e5d 100644 --- a/drivers/power/max8903_charger.c +++ b/drivers/power/max8903_charger.c @@ -291,10 +291,10 @@ static int max8903_probe(struct platform_device *pdev) if (pdata->dc_valid) { ret = devm_request_threaded_irq(dev, gpio_to_irq(pdata->dok), - NULL, max8903_dcin, - IRQF_TRIGGER_FALLING | - IRQF_TRIGGER_RISING, - "MAX8903 DC IN", data); + NULL, max8903_dcin, + IRQF_TRIGGER_FALLING | + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "MAX8903 DC IN", data); if (ret) { dev_err(dev, "Cannot request irq %d for DC (%d)\n", gpio_to_irq(pdata->dok), ret); @@ -304,10 +304,10 @@ static int max8903_probe(struct platform_device *pdev) if (pdata->usb_valid) { ret = devm_request_threaded_irq(dev, gpio_to_irq(pdata->uok), - NULL, max8903_usbin, - IRQF_TRIGGER_FALLING | - IRQF_TRIGGER_RISING, - "MAX8903 USB IN", data); + NULL, max8903_usbin, + IRQF_TRIGGER_FALLING | + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "MAX8903 USB IN", data); if (ret) { dev_err(dev, "Cannot request irq %d for USB (%d)\n", gpio_to_irq(pdata->uok), ret); @@ -317,10 +317,10 @@ static int max8903_probe(struct platform_device *pdev) if (pdata->flt) { ret = devm_request_threaded_irq(dev, gpio_to_irq(pdata->flt), - NULL, max8903_fault, - IRQF_TRIGGER_FALLING | - IRQF_TRIGGER_RISING, - "MAX8903 Fault", data); + NULL, max8903_fault, + IRQF_TRIGGER_FALLING | + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "MAX8903 Fault", data); if (ret) { dev_err(dev, "Cannot request irq %d for Fault (%d)\n", gpio_to_irq(pdata->flt), ret); -- GitLab From 1f94b2563a02327aa8a1385c8a92b0c3f96d01b4 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 7 Oct 2015 20:42:38 +0200 Subject: [PATCH 0964/2855] power: bq27xxx: don't fill system log by missing battery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Print message that battery is not calibrated only once to avoid spamming the log. Suggested-By: H. Nikolaus Schaller Suggested-By: Pali Rohár Signed-off-by: Sebastian Reichel --- drivers/power/bq27xxx_battery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c index 880233ce93438..1cad7accf3392 100644 --- a/drivers/power/bq27xxx_battery.c +++ b/drivers/power/bq27xxx_battery.c @@ -722,7 +722,7 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di) if (cache.flags >= 0) { cache.temperature = bq27xxx_battery_read_temperature(di); if (has_ci_flag && (cache.flags & BQ27000_FLAG_CI)) { - dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n"); + dev_info_once(di->dev, "battery is not calibrated! ignoring capacity values\n"); cache.capacity = -ENODATA; cache.energy = -ENODATA; cache.time_to_empty = -ENODATA; -- GitLab From 703df6c097956d17a818e63961c82e8e9eef9fef Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Mon, 23 Nov 2015 10:53:51 -0600 Subject: [PATCH 0965/2855] power: bq27xxx_battery: Reorganize I2C into a module Separate out I2C functionality into a module. This fixes several small issues and simplifies the driver initialization. Signed-off-by: Andrew F. Davis Signed-off-by: Sebastian Reichel --- drivers/power/Kconfig | 14 +- drivers/power/Makefile | 1 + drivers/power/bq27xxx_battery.c | 326 ++------------------------ drivers/power/bq27xxx_battery_i2c.c | 150 ++++++++++++ include/linux/power/bq27xxx_battery.h | 57 ++++- 5 files changed, 227 insertions(+), 321 deletions(-) create mode 100644 drivers/power/bq27xxx_battery_i2c.c diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 237d7aa73e8c8..42a5b51c3d2ec 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -160,22 +160,16 @@ config BATTERY_SBS config BATTERY_BQ27XXX tristate "BQ27xxx battery driver" help - Say Y here to enable support for batteries with BQ27xxx (I2C/HDQ) chips. + Say Y here to enable support for batteries with BQ27xxx chips. config BATTERY_BQ27XXX_I2C - bool "BQ27xxx I2C support" + tristate "BQ27xxx I2C support" depends on BATTERY_BQ27XXX depends on I2C default y help - Say Y here to enable support for batteries with BQ27xxx (I2C) chips. - -config BATTERY_BQ27XXX_PLATFORM - bool "BQ27xxx HDQ support" - depends on BATTERY_BQ27XXX - default y - help - Say Y here to enable support for batteries with BQ27xxx (HDQ) chips. + Say Y here to enable support for batteries with BQ27xxx chips + connected over an I2C bus. config BATTERY_DA9030 tristate "DA9030 battery driver" diff --git a/drivers/power/Makefile b/drivers/power/Makefile index b656638f8b398..0e4eab55f8d70 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_BATTERY_IPAQ_MICRO) += ipaq_micro_battery.o obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o obj-$(CONFIG_BATTERY_SBS) += sbs-battery.o obj-$(CONFIG_BATTERY_BQ27XXX) += bq27xxx_battery.o +obj-$(CONFIG_BATTERY_BQ27XXX_I2C) += bq27xxx_battery_i2c.o obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o obj-$(CONFIG_CHARGER_DA9150) += da9150-charger.o diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c index 1cad7accf3392..8d4ef9fd9b6e8 100644 --- a/drivers/power/bq27xxx_battery.c +++ b/drivers/power/bq27xxx_battery.c @@ -45,11 +45,7 @@ #include #include #include -#include -#include #include -#include -#include #include @@ -78,11 +74,6 @@ #define BQ27XXX_POWER_CONSTANT (29200) /* 29.2 µV^2 * 1000 */ #define BQ27XXX_CURRENT_CONSTANT (3570) /* 3.57 µV * 1000 */ -struct bq27xxx_device_info; -struct bq27xxx_access_methods { - int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single); -}; - #define INVALID_REG_ADDR 0xff /* @@ -110,40 +101,6 @@ enum bq27xxx_reg_index { BQ27XXX_REG_AP, /* Average Power */ }; -struct bq27xxx_reg_cache { - int temperature; - int time_to_empty; - int time_to_empty_avg; - int time_to_full; - int charge_full; - int cycle_count; - int capacity; - int energy; - int flags; - int power_avg; - int health; -}; - -struct bq27xxx_device_info { - struct device *dev; - int id; - enum bq27xxx_chip chip; - - struct bq27xxx_reg_cache cache; - int charge_design_full; - - unsigned long last_update; - struct delayed_work work; - - struct power_supply *bat; - - struct bq27xxx_access_methods bus; - - struct mutex lock; - - u8 *regs; -}; - /* Register mappings */ static u8 bq27000_regs[] = { 0x00, /* CONTROL */ @@ -710,7 +667,7 @@ static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di) return POWER_SUPPLY_HEALTH_GOOD; } -static void bq27xxx_battery_update(struct bq27xxx_device_info *di) +void bq27xxx_battery_update(struct bq27xxx_device_info *di) { struct bq27xxx_reg_cache cache = {0, }; bool has_ci_flag = di->chip == BQ27000 || di->chip == BQ27010; @@ -761,6 +718,7 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di) di->last_update = jiffies; } +EXPORT_SYMBOL_GPL(bq27xxx_battery_update); static void bq27xxx_battery_poll(struct work_struct *work) { @@ -991,32 +949,30 @@ static void bq27xxx_external_power_changed(struct power_supply *psy) schedule_delayed_work(&di->work, 0); } -static int bq27xxx_powersupply_init(struct bq27xxx_device_info *di, - const char *name) +int bq27xxx_battery_setup(struct bq27xxx_device_info *di) { - int ret; struct power_supply_desc *psy_desc; struct power_supply_config psy_cfg = { .drv_data = di, }; + INIT_DELAYED_WORK(&di->work, bq27xxx_battery_poll); + mutex_init(&di->lock); + di->regs = bq27xxx_regs[di->chip]; + psy_desc = devm_kzalloc(di->dev, sizeof(*psy_desc), GFP_KERNEL); if (!psy_desc) return -ENOMEM; - psy_desc->name = name; + psy_desc->name = di->name; psy_desc->type = POWER_SUPPLY_TYPE_BATTERY; psy_desc->properties = bq27xxx_battery_props[di->chip].props; psy_desc->num_properties = bq27xxx_battery_props[di->chip].size; psy_desc->get_property = bq27xxx_battery_get_property; psy_desc->external_power_changed = bq27xxx_external_power_changed; - INIT_DELAYED_WORK(&di->work, bq27xxx_battery_poll); - mutex_init(&di->lock); - di->bat = power_supply_register_no_ws(di->dev, psy_desc, &psy_cfg); if (IS_ERR(di->bat)) { - ret = PTR_ERR(di->bat); - dev_err(di->dev, "failed to register battery: %d\n", ret); - return ret; + dev_err(di->dev, "failed to register battery\n"); + return PTR_ERR(di->bat); } dev_info(di->dev, "support ver. %s enabled\n", DRIVER_VERSION); @@ -1025,8 +981,9 @@ static int bq27xxx_powersupply_init(struct bq27xxx_device_info *di, return 0; } +EXPORT_SYMBOL_GPL(bq27xxx_battery_setup); -static void bq27xxx_powersupply_unregister(struct bq27xxx_device_info *di) +void bq27xxx_battery_teardown(struct bq27xxx_device_info *di) { /* * power_supply_unregister call bq27xxx_battery_get_property which @@ -1042,192 +999,7 @@ static void bq27xxx_powersupply_unregister(struct bq27xxx_device_info *di) mutex_destroy(&di->lock); } - -/* i2c specific code */ -#ifdef CONFIG_BATTERY_BQ27XXX_I2C - -/* If the system has several batteries we need a different name for each - * of them... - */ -static DEFINE_IDR(battery_id); -static DEFINE_MUTEX(battery_mutex); - -static irqreturn_t bq27xxx_battery_irq_handler_thread(int irq, void *data) -{ - struct bq27xxx_device_info *di = data; - - bq27xxx_battery_update(di); - - return IRQ_HANDLED; -} - -static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg, - bool single) -{ - struct i2c_client *client = to_i2c_client(di->dev); - struct i2c_msg msg[2]; - unsigned char data[2]; - int ret; - - if (!client->adapter) - return -ENODEV; - - msg[0].addr = client->addr; - msg[0].flags = 0; - msg[0].buf = ® - msg[0].len = sizeof(reg); - msg[1].addr = client->addr; - msg[1].flags = I2C_M_RD; - msg[1].buf = data; - if (single) - msg[1].len = 1; - else - msg[1].len = 2; - - ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); - if (ret < 0) - return ret; - - if (!single) - ret = get_unaligned_le16(data); - else - ret = data[0]; - - return ret; -} - -static int bq27xxx_battery_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - char *name; - struct bq27xxx_device_info *di; - int num; - int retval = 0; - - /* Get new ID for the new battery device */ - mutex_lock(&battery_mutex); - num = idr_alloc(&battery_id, client, 0, 0, GFP_KERNEL); - mutex_unlock(&battery_mutex); - if (num < 0) - return num; - - name = devm_kasprintf(&client->dev, GFP_KERNEL, "%s-%d", id->name, num); - if (!name) { - retval = -ENOMEM; - goto batt_failed; - } - - di = devm_kzalloc(&client->dev, sizeof(*di), GFP_KERNEL); - if (!di) { - retval = -ENOMEM; - goto batt_failed; - } - - di->id = num; - di->dev = &client->dev; - di->chip = id->driver_data; - di->bus.read = &bq27xxx_battery_i2c_read; - di->regs = bq27xxx_regs[di->chip]; - - retval = bq27xxx_powersupply_init(di, name); - if (retval) - goto batt_failed; - - /* Schedule a polling after about 1 min */ - schedule_delayed_work(&di->work, 60 * HZ); - - i2c_set_clientdata(client, di); - - if (client->irq) { - retval = devm_request_threaded_irq(&client->dev, client->irq, - NULL, bq27xxx_battery_irq_handler_thread, - IRQF_ONESHOT, - name, di); - if (retval) { - dev_err(&client->dev, - "Unable to register IRQ %d error %d\n", - client->irq, retval); - return retval; - } - } - - return 0; - -batt_failed: - mutex_lock(&battery_mutex); - idr_remove(&battery_id, num); - mutex_unlock(&battery_mutex); - - return retval; -} - -static int bq27xxx_battery_i2c_remove(struct i2c_client *client) -{ - struct bq27xxx_device_info *di = i2c_get_clientdata(client); - - bq27xxx_powersupply_unregister(di); - - mutex_lock(&battery_mutex); - idr_remove(&battery_id, di->id); - mutex_unlock(&battery_mutex); - - return 0; -} - -static const struct i2c_device_id bq27xxx_id[] = { - { "bq27200", BQ27000 }, - { "bq27210", BQ27010 }, - { "bq27500", BQ27500 }, - { "bq27510", BQ27500 }, - { "bq27520", BQ27500 }, - { "bq27530", BQ27530 }, - { "bq27531", BQ27530 }, - { "bq27541", BQ27541 }, - { "bq27542", BQ27541 }, - { "bq27546", BQ27541 }, - { "bq27742", BQ27541 }, - { "bq27545", BQ27545 }, - { "bq27421", BQ27421 }, - { "bq27425", BQ27421 }, - { "bq27441", BQ27421 }, - { "bq27621", BQ27421 }, - {}, -}; -MODULE_DEVICE_TABLE(i2c, bq27xxx_id); - -static struct i2c_driver bq27xxx_battery_i2c_driver = { - .driver = { - .name = "bq27xxx-battery", - }, - .probe = bq27xxx_battery_i2c_probe, - .remove = bq27xxx_battery_i2c_remove, - .id_table = bq27xxx_id, -}; - -static inline int bq27xxx_battery_i2c_init(void) -{ - int ret = i2c_add_driver(&bq27xxx_battery_i2c_driver); - - if (ret) - pr_err("Unable to register BQ27xxx i2c driver\n"); - - return ret; -} - -static inline void bq27xxx_battery_i2c_exit(void) -{ - i2c_del_driver(&bq27xxx_battery_i2c_driver); -} - -#else - -static inline int bq27xxx_battery_i2c_init(void) { return 0; } -static inline void bq27xxx_battery_i2c_exit(void) {}; - -#endif - -/* platform specific code */ -#ifdef CONFIG_BATTERY_BQ27XXX_PLATFORM +EXPORT_SYMBOL_GPL(bq27xxx_battery_teardown); static int bq27xxx_battery_platform_read(struct bq27xxx_device_info *di, u8 reg, bool single) @@ -1267,7 +1039,6 @@ static int bq27xxx_battery_platform_probe(struct platform_device *pdev) { struct bq27xxx_device_info *di; struct bq27xxx_platform_data *pdata = pdev->dev.platform_data; - const char *name; if (!pdata) { dev_err(&pdev->dev, "no platform_data supplied\n"); @@ -1292,83 +1063,36 @@ static int bq27xxx_battery_platform_probe(struct platform_device *pdev) di->dev = &pdev->dev; di->chip = pdata->chip; - di->regs = bq27xxx_regs[di->chip]; - - name = pdata->name ?: dev_name(&pdev->dev); - di->bus.read = &bq27xxx_battery_platform_read; + di->name = pdata->name ?: dev_name(&pdev->dev); + di->bus.read = bq27xxx_battery_platform_read; - return bq27xxx_powersupply_init(di, name); + return bq27xxx_battery_setup(di); } static int bq27xxx_battery_platform_remove(struct platform_device *pdev) { struct bq27xxx_device_info *di = platform_get_drvdata(pdev); - bq27xxx_powersupply_unregister(di); + bq27xxx_battery_teardown(di); return 0; } +static const struct platform_device_id bq27xxx_battery_platform_id_table[] = { + { "bq27000-battery", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, bq27xxx_battery_platform_id_table); + static struct platform_driver bq27xxx_battery_platform_driver = { .probe = bq27xxx_battery_platform_probe, .remove = bq27xxx_battery_platform_remove, .driver = { .name = "bq27000-battery", }, + .id_table = bq27xxx_battery_platform_id_table, }; - -static inline int bq27xxx_battery_platform_init(void) -{ - int ret = platform_driver_register(&bq27xxx_battery_platform_driver); - - if (ret) - pr_err("Unable to register BQ27xxx platform driver\n"); - - return ret; -} - -static inline void bq27xxx_battery_platform_exit(void) -{ - platform_driver_unregister(&bq27xxx_battery_platform_driver); -} - -#else - -static inline int bq27xxx_battery_platform_init(void) { return 0; } -static inline void bq27xxx_battery_platform_exit(void) {}; - -#endif - -/* - * Module stuff - */ - -static int __init bq27xxx_battery_init(void) -{ - int ret; - - ret = bq27xxx_battery_i2c_init(); - if (ret) - return ret; - - ret = bq27xxx_battery_platform_init(); - if (ret) - bq27xxx_battery_i2c_exit(); - - return ret; -} -module_init(bq27xxx_battery_init); - -static void __exit bq27xxx_battery_exit(void) -{ - bq27xxx_battery_platform_exit(); - bq27xxx_battery_i2c_exit(); -} -module_exit(bq27xxx_battery_exit); - -#ifdef CONFIG_BATTERY_BQ27XXX_PLATFORM -MODULE_ALIAS("platform:bq27000-battery"); -#endif +module_platform_driver(bq27xxx_battery_platform_driver); MODULE_AUTHOR("Rodolfo Giometti "); MODULE_DESCRIPTION("BQ27xxx battery monitor driver"); diff --git a/drivers/power/bq27xxx_battery_i2c.c b/drivers/power/bq27xxx_battery_i2c.c new file mode 100644 index 0000000000000..9429e66be0964 --- /dev/null +++ b/drivers/power/bq27xxx_battery_i2c.c @@ -0,0 +1,150 @@ +/* + * SCI Reset driver for Keystone based devices + * + * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ + * Andrew F. Davis + * + * 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. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include + +#include + +static irqreturn_t bq27xxx_battery_irq_handler_thread(int irq, void *data) +{ + struct bq27xxx_device_info *di = data; + + bq27xxx_battery_update(di); + + return IRQ_HANDLED; +} + +static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg, + bool single) +{ + struct i2c_client *client = to_i2c_client(di->dev); + struct i2c_msg msg[2]; + unsigned char data[2]; + int ret; + + if (!client->adapter) + return -ENODEV; + + msg[0].addr = client->addr; + msg[0].flags = 0; + msg[0].buf = ® + msg[0].len = sizeof(reg); + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = data; + if (single) + msg[1].len = 1; + else + msg[1].len = 2; + + ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); + if (ret < 0) + return ret; + + if (!single) + ret = get_unaligned_le16(data); + else + ret = data[0]; + + return ret; +} + +static int bq27xxx_battery_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct bq27xxx_device_info *di; + int ret; + + di = devm_kzalloc(&client->dev, sizeof(*di), GFP_KERNEL); + if (!di) + return -ENOMEM; + + di->dev = &client->dev; + di->chip = id->driver_data; + di->name = id->name; + di->bus.read = bq27xxx_battery_i2c_read; + + ret = bq27xxx_battery_setup(di); + if (ret) + return ret; + + /* Schedule a polling after about 1 min */ + schedule_delayed_work(&di->work, 60 * HZ); + + i2c_set_clientdata(client, di); + + if (client->irq) { + ret = devm_request_threaded_irq(&client->dev, client->irq, + NULL, bq27xxx_battery_irq_handler_thread, + IRQF_ONESHOT, + di->name, di); + if (ret) { + dev_err(&client->dev, + "Unable to register IRQ %d error %d\n", + client->irq, ret); + return ret; + } + } + + return 0; +} + +static int bq27xxx_battery_i2c_remove(struct i2c_client *client) +{ + struct bq27xxx_device_info *di = i2c_get_clientdata(client); + + bq27xxx_battery_teardown(di); + + return 0; +} + +static const struct i2c_device_id bq27xxx_i2c_id_table[] = { + { "bq27200", BQ27000 }, + { "bq27210", BQ27010 }, + { "bq27500", BQ27500 }, + { "bq27510", BQ27500 }, + { "bq27520", BQ27500 }, + { "bq27530", BQ27530 }, + { "bq27531", BQ27530 }, + { "bq27541", BQ27541 }, + { "bq27542", BQ27541 }, + { "bq27546", BQ27541 }, + { "bq27742", BQ27541 }, + { "bq27545", BQ27545 }, + { "bq27421", BQ27421 }, + { "bq27425", BQ27421 }, + { "bq27441", BQ27421 }, + { "bq27621", BQ27421 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, bq27xxx_i2c_id_table); + +static struct i2c_driver bq27xxx_battery_i2c_driver = { + .driver = { + .name = "bq27xxx-battery", + }, + .probe = bq27xxx_battery_i2c_probe, + .remove = bq27xxx_battery_i2c_remove, + .id_table = bq27xxx_i2c_id_table, +}; +module_i2c_driver(bq27xxx_battery_i2c_driver); + +MODULE_AUTHOR("Andrew F. Davis "); +MODULE_DESCRIPTION("BQ27xxx battery monitor i2c driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h index 45f6a7b5b3cb6..998d8f1c3c917 100644 --- a/include/linux/power/bq27xxx_battery.h +++ b/include/linux/power/bq27xxx_battery.h @@ -1,6 +1,16 @@ #ifndef __LINUX_BQ27X00_BATTERY_H__ #define __LINUX_BQ27X00_BATTERY_H__ +enum bq27xxx_chip { + BQ27000 = 1, /* bq27000, bq27200 */ + BQ27010, /* bq27010, bq27210 */ + BQ27500, /* bq27500, bq27510, bq27520 */ + BQ27530, /* bq27530, bq27531 */ + BQ27541, /* bq27541, bq27542, bq27546, bq27742 */ + BQ27545, /* bq27545 */ + BQ27421, /* bq27421, bq27425, bq27441, bq27621 */ +}; + /** * struct bq27xxx_plaform_data - Platform data for bq27xxx devices * @name: Name of the battery. @@ -12,20 +22,47 @@ * register to be read. The return value should either be the content of * the passed register or an error value. */ -enum bq27xxx_chip { - BQ27000 = 1, /* bq27000, bq27200 */ - BQ27010, /* bq27010, bq27210 */ - BQ27500, /* bq27500, bq27510, bq27520 */ - BQ27530, /* bq27530, bq27531 */ - BQ27541, /* bq27541, bq27542, bq27546, bq27742 */ - BQ27545, /* bq27545 */ - BQ27421, /* bq27421, bq27425, bq27441, bq27621 */ -}; - struct bq27xxx_platform_data { const char *name; enum bq27xxx_chip chip; int (*read)(struct device *dev, unsigned int); }; +struct bq27xxx_device_info; +struct bq27xxx_access_methods { + int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single); +}; + +struct bq27xxx_reg_cache { + int temperature; + int time_to_empty; + int time_to_empty_avg; + int time_to_full; + int charge_full; + int cycle_count; + int capacity; + int energy; + int flags; + int power_avg; + int health; +}; + +struct bq27xxx_device_info { + struct device *dev; + enum bq27xxx_chip chip; + const char *name; + struct bq27xxx_access_methods bus; + struct bq27xxx_reg_cache cache; + int charge_design_full; + unsigned long last_update; + struct delayed_work work; + struct power_supply *bat; + struct mutex lock; + u8 *regs; +}; + +void bq27xxx_battery_update(struct bq27xxx_device_info *di); +int bq27xxx_battery_setup(struct bq27xxx_device_info *di); +void bq27xxx_battery_teardown(struct bq27xxx_device_info *di); + #endif -- GitLab From bcf5b3deb0d269a3a28ecf4c73e1c89121ba61d4 Mon Sep 17 00:00:00 2001 From: Sander Vermin Date: Tue, 1 Dec 2015 13:25:05 -0800 Subject: [PATCH 0966/2855] Input: pixcir_i2c - add support for wake and enable gpios On some devices the wake and enable pins of the pixcir touchscreen controller are connected to gpios and these must be controlled by the driver for the device to operate properly. Signed-off-by: Sander Vermin Signed-off-by: Hans de Goede Acked-by: Rob Herring Signed-off-by: Dmitry Torokhov --- .../input/touchscreen/pixcir_i2c_ts.txt | 4 +- drivers/input/touchscreen/pixcir_i2c_ts.c | 41 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt b/Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt index 8eb240a287c8a..697a3e7831e73 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt @@ -9,7 +9,9 @@ Required properties: - touchscreen-size-y: vertical resolution of touchscreen (in pixels) Optional properties: -- reset-gpio: GPIO connected to the RESET line of the chip +- reset-gpios: GPIO connected to the RESET line of the chip +- enable-gpios: GPIO connected to the ENABLE line of the chip +- wake-gpios: GPIO connected to the WAKE line of the chip Example: diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c index 4b961ad9f0b51..09523a3d3f232 100644 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c @@ -38,6 +38,8 @@ struct pixcir_i2c_ts_data { struct input_dev *input; struct gpio_desc *gpio_attb; struct gpio_desc *gpio_reset; + struct gpio_desc *gpio_enable; + struct gpio_desc *gpio_wake; const struct pixcir_i2c_chip_data *chip; int max_fingers; /* Max fingers supported in this instance */ bool running; @@ -208,6 +210,11 @@ static int pixcir_set_power_mode(struct pixcir_i2c_ts_data *ts, struct device *dev = &ts->client->dev; int ret; + if (mode == PIXCIR_POWER_ACTIVE || mode == PIXCIR_POWER_IDLE) { + if (ts->gpio_wake) + gpiod_set_value_cansleep(ts->gpio_wake, 1); + } + ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_POWER_MODE); if (ret < 0) { dev_err(dev, "%s: can't read reg 0x%x : %d\n", @@ -228,6 +235,11 @@ static int pixcir_set_power_mode(struct pixcir_i2c_ts_data *ts, return ret; } + if (mode == PIXCIR_POWER_HALT) { + if (ts->gpio_wake) + gpiod_set_value_cansleep(ts->gpio_wake, 0); + } + return 0; } @@ -302,6 +314,11 @@ static int pixcir_start(struct pixcir_i2c_ts_data *ts) struct device *dev = &ts->client->dev; int error; + if (ts->gpio_enable) { + gpiod_set_value_cansleep(ts->gpio_enable, 1); + msleep(100); + } + /* LEVEL_TOUCH interrupt with active low polarity */ error = pixcir_set_int_mode(ts, PIXCIR_INT_LEVEL_TOUCH, 0); if (error) { @@ -343,6 +360,9 @@ static int pixcir_stop(struct pixcir_i2c_ts_data *ts) /* Wait till running ISR is complete */ synchronize_irq(ts->client->irq); + if (ts->gpio_enable) + gpiod_set_value_cansleep(ts->gpio_enable, 0); + return 0; } @@ -534,6 +554,27 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client, return error; } + tsdata->gpio_wake = devm_gpiod_get_optional(dev, "wake", + GPIOD_OUT_HIGH); + if (IS_ERR(tsdata->gpio_wake)) { + error = PTR_ERR(tsdata->gpio_wake); + if (error != -EPROBE_DEFER) + dev_err(dev, "Failed to get wake gpio: %d\n", error); + return error; + } + + tsdata->gpio_enable = devm_gpiod_get_optional(dev, "enable", + GPIOD_OUT_HIGH); + if (IS_ERR(tsdata->gpio_enable)) { + error = PTR_ERR(tsdata->gpio_enable); + if (error != -EPROBE_DEFER) + dev_err(dev, "Failed to get enable gpio: %d\n", error); + return error; + } + + if (tsdata->gpio_enable) + msleep(100); + error = devm_request_threaded_irq(dev, client->irq, NULL, pixcir_ts_isr, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->name, tsdata); -- GitLab From adf850bcca4eec45f06c6ad3e297a350a8a319bc Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 11 Nov 2015 12:37:55 +0200 Subject: [PATCH 0967/2855] dmaengine: omap-dma: Correct status reporting for memcpy During mem copy both src and dst position moves at the same pace. Check the dst position for progress reporting. Signed-off-by: Peter Ujfalusi Tested-by: Tomi Valkeinen Signed-off-by: Jyri Sarha Signed-off-by: Vinod Koul --- drivers/dma/omap-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index 1dfc71c90123f..8ed39ce24d461 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -719,7 +719,7 @@ static enum dma_status omap_dma_tx_status(struct dma_chan *chan, if (d->dir == DMA_MEM_TO_DEV) pos = omap_dma_get_src_pos(c); - else if (d->dir == DMA_DEV_TO_MEM) + else if (d->dir == DMA_DEV_TO_MEM || d->dir == DMA_MEM_TO_MEM) pos = omap_dma_get_dst_pos(c); else pos = 0; -- GitLab From e8a5e79c17f977d1820ffe9b6ac259c953b3b34b Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 11 Nov 2015 12:37:56 +0200 Subject: [PATCH 0968/2855] dmaengine: omap-dma: Clean up the prep_slave_sg sg list walk code The for_each_sg() macro's last parameter is inteded to be used as counter. We can use 'i' instead of 'j' within the loop for indexes. Signed-off-by: Peter Ujfalusi Signed-off-by: Vinod Koul --- drivers/dma/omap-dma.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index 8ed39ce24d461..4afc2c18d4514 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -768,7 +768,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg( struct scatterlist *sgent; struct omap_desc *d; dma_addr_t dev_addr; - unsigned i, j = 0, es, en, frame_bytes; + unsigned i, es, en, frame_bytes; u32 burst; if (dir == DMA_DEV_TO_MEM) { @@ -845,13 +845,12 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg( en = burst; frame_bytes = es_bytes[es] * en; for_each_sg(sgl, sgent, sglen, i) { - d->sg[j].addr = sg_dma_address(sgent); - d->sg[j].en = en; - d->sg[j].fn = sg_dma_len(sgent) / frame_bytes; - j++; + d->sg[i].addr = sg_dma_address(sgent); + d->sg[i].en = en; + d->sg[i].fn = sg_dma_len(sgent) / frame_bytes; } - d->sglen = j; + d->sglen = sglen; return vchan_tx_prep(&c->vc, &d->vd, tx_flags); } -- GitLab From 1c1d25f9f933211b622b0e209716372480051361 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 11 Nov 2015 12:37:57 +0200 Subject: [PATCH 0969/2855] dmaengine: omap-dma: Remove tasklet to start the transfers The use of tasklet to actually start the DMA transfer slightly decreases the DMA throughput since it adds small scheduling delay when the transfer is started. In normal use, even with high I/O load the tasklet would start one transaction at a time, however running the DMAtest for memcpy on all available channels will cause the tasklet to start about 15 transfers. The performance numbers on OMAP4 PandaBoard-es (test_buf_size = 6553): With the tasklet: dmatest: dma0chan30-copy: summary 5000 tests, 0 failures 186 iops 593 KB/s (0) dmatest: dma0chan8-copy0: summary 5000 tests, 0 failures 184 iops 584 KB/s (0) dmatest: dma0chan13-copy: summary 5000 tests, 0 failures 184 iops 585 KB/s (0) dmatest: dma0chan12-copy: summary 5000 tests, 0 failures 184 iops 585 KB/s (0) dmatest: dma0chan7-copy0: summary 5000 tests, 0 failures 183 iops 581 KB/s (0) With this patch (no tasklet): dmatest: dma0chan4-copy0: summary 5000 tests, 0 failures 199 iops 644 KB/s (0) dmatest: dma0chan5-copy0: summary 5000 tests, 0 failures 199 iops 645 KB/s (0) dmatest: dma0chan6-copy0: summary 5000 tests, 0 failures 199 iops 637 KB/s (0) dmatest: dma0chan24-copy: summary 5000 tests, 0 failures 199 iops 638 KB/s (0) dmatest: dma0chan16-copy: summary 5000 tests, 0 failures 199 iops 638 KB/s (0) Signed-off-by: Peter Ujfalusi Signed-off-by: Vinod Koul --- drivers/dma/omap-dma.c | 59 ++---------------------------------------- 1 file changed, 2 insertions(+), 57 deletions(-) diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index 4afc2c18d4514..4e4642f561f52 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -28,8 +28,6 @@ struct omap_dmadev { struct dma_device ddev; spinlock_t lock; - struct tasklet_struct task; - struct list_head pending; void __iomem *base; const struct omap_dma_reg *reg_map; struct omap_system_dma_plat_info *plat; @@ -42,7 +40,6 @@ struct omap_dmadev { struct omap_chan { struct virt_dma_chan vc; - struct list_head node; void __iomem *channel_base; const struct omap_dma_reg *reg_map; uint32_t ccr; @@ -454,33 +451,6 @@ static void omap_dma_callback(int ch, u16 status, void *data) spin_unlock_irqrestore(&c->vc.lock, flags); } -/* - * This callback schedules all pending channels. We could be more - * clever here by postponing allocation of the real DMA channels to - * this point, and freeing them when our virtual channel becomes idle. - * - * We would then need to deal with 'all channels in-use' - */ -static void omap_dma_sched(unsigned long data) -{ - struct omap_dmadev *d = (struct omap_dmadev *)data; - LIST_HEAD(head); - - spin_lock_irq(&d->lock); - list_splice_tail_init(&d->pending, &head); - spin_unlock_irq(&d->lock); - - while (!list_empty(&head)) { - struct omap_chan *c = list_first_entry(&head, - struct omap_chan, node); - - spin_lock_irq(&c->vc.lock); - list_del_init(&c->node); - omap_dma_start_desc(c); - spin_unlock_irq(&c->vc.lock); - } -} - static irqreturn_t omap_dma_irq(int irq, void *devid) { struct omap_dmadev *od = devid; @@ -739,22 +709,8 @@ static void omap_dma_issue_pending(struct dma_chan *chan) unsigned long flags; spin_lock_irqsave(&c->vc.lock, flags); - if (vchan_issue_pending(&c->vc) && !c->desc) { - /* - * c->cyclic is used only by audio and in this case the DMA need - * to be started without delay. - */ - if (!c->cyclic) { - struct omap_dmadev *d = to_omap_dma_dev(chan->device); - spin_lock(&d->lock); - if (list_empty(&c->node)) - list_add_tail(&c->node, &d->pending); - spin_unlock(&d->lock); - tasklet_schedule(&d->task); - } else { - omap_dma_start_desc(c); - } - } + if (vchan_issue_pending(&c->vc) && !c->desc) + omap_dma_start_desc(c); spin_unlock_irqrestore(&c->vc.lock, flags); } @@ -1017,17 +973,11 @@ static int omap_dma_slave_config(struct dma_chan *chan, struct dma_slave_config static int omap_dma_terminate_all(struct dma_chan *chan) { struct omap_chan *c = to_omap_dma_chan(chan); - struct omap_dmadev *d = to_omap_dma_dev(c->vc.chan.device); unsigned long flags; LIST_HEAD(head); spin_lock_irqsave(&c->vc.lock, flags); - /* Prevent this channel being scheduled */ - spin_lock(&d->lock); - list_del_init(&c->node); - spin_unlock(&d->lock); - /* * Stop DMA activity: we assume the callback will not be called * after omap_dma_stop() returns (even if it does, it will see @@ -1101,14 +1051,12 @@ static int omap_dma_chan_init(struct omap_dmadev *od) c->reg_map = od->reg_map; c->vc.desc_free = omap_dma_desc_free; vchan_init(&c->vc, &od->ddev); - INIT_LIST_HEAD(&c->node); return 0; } static void omap_dma_free(struct omap_dmadev *od) { - tasklet_kill(&od->task); while (!list_empty(&od->ddev.channels)) { struct omap_chan *c = list_first_entry(&od->ddev.channels, struct omap_chan, vc.chan.device_node); @@ -1164,12 +1112,9 @@ static int omap_dma_probe(struct platform_device *pdev) od->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; od->ddev.dev = &pdev->dev; INIT_LIST_HEAD(&od->ddev.channels); - INIT_LIST_HEAD(&od->pending); spin_lock_init(&od->lock); spin_lock_init(&od->irq_lock); - tasklet_init(&od->task, omap_dma_sched, (unsigned long)od); - od->dma_requests = OMAP_SDMA_REQUESTS; if (pdev->dev.of_node && of_property_read_u32(pdev->dev.of_node, "dma-requests", -- GitLab From 1a7cf7b26f2594bb1c622f76765f77d3a5140293 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 11 Nov 2015 12:37:58 +0200 Subject: [PATCH 0970/2855] dmaengine: omap-dma: Handle cases when the channel is polled for completion When a DMA client driver decides that it is not providing callback for completion of a transfer (and/or does not set the DMA_PREP_INTERRUPT) but it will poll the status of the transfer (in case of short memcpy for example) we will not get interrupt for the completion of the transfer and will not mark the transaction as done. Check the channel enable bit in the CCR when the status is queried and if the channel is no longer active, we call the omap_dma_callback() to handle the transfer completion. Signed-off-by: Peter Ujfalusi Signed-off-by: Vinod Koul --- drivers/dma/omap-dma.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index 4e4642f561f52..f86827ac0c8a2 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -673,8 +673,14 @@ static enum dma_status omap_dma_tx_status(struct dma_chan *chan, struct omap_chan *c = to_omap_dma_chan(chan); struct virt_dma_desc *vd; enum dma_status ret; + uint32_t ccr; unsigned long flags; + ccr = omap_dma_chan_read(c, CCR); + /* The channel is no longer active, handle the completion right away */ + if (!(ccr & CCR_ENABLE)) + omap_dma_callback(c->dma_ch, 0, c); + ret = dma_cookie_status(chan, cookie, txstate); if (ret == DMA_COMPLETE || !txstate) return ret; -- GitLab From d9f5efade2cfd729138a7cafb46d01044da40f5e Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Thu, 12 Nov 2015 13:37:40 +0900 Subject: [PATCH 0971/2855] dmaengine: usb-dmac: fix endless loop in usb_dmac_chan_terminate_all() This patch fixes an issue that list_for_each_entry() in usb_dmac_chan_terminate_all() is possible to cause endless loop because this will move own desc to the desc_freed. So, this driver should use list_for_each_entry_safe() instead of list_for_each_entry(). Signed-off-by: Yoshihiro Shimoda Signed-off-by: Vinod Koul --- drivers/dma/sh/usb-dmac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dma/sh/usb-dmac.c b/drivers/dma/sh/usb-dmac.c index ebd8a5f398b08..16fb33006a174 100644 --- a/drivers/dma/sh/usb-dmac.c +++ b/drivers/dma/sh/usb-dmac.c @@ -448,7 +448,7 @@ usb_dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, static int usb_dmac_chan_terminate_all(struct dma_chan *chan) { struct usb_dmac_chan *uchan = to_usb_dmac_chan(chan); - struct usb_dmac_desc *desc; + struct usb_dmac_desc *desc, *_desc; unsigned long flags; LIST_HEAD(head); LIST_HEAD(list); @@ -459,7 +459,7 @@ static int usb_dmac_chan_terminate_all(struct dma_chan *chan) if (uchan->desc) uchan->desc = NULL; list_splice_init(&uchan->desc_got, &list); - list_for_each_entry(desc, &list, node) + list_for_each_entry_safe(desc, _desc, &list, node) list_move_tail(&desc->node, &uchan->desc_freed); spin_unlock_irqrestore(&uchan->vc.lock, flags); vchan_dma_desc_free_list(&uchan->vc, &head); -- GitLab From b1d6ab1aa8cdc23b89bcd578ea8d5e3c501a13d9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 23 Nov 2015 11:06:43 +0100 Subject: [PATCH 0972/2855] dmaengine: Add might_sleep() to dmaengine_synchronize() Implementations of dmaengine_synchronize() are allowed to sleep, hence the function must not be called to from atomic context. Add might_sleep() to dmaengine_synchronize() to make it easier to detect non-compliant callers. Suggested-by: Andy Shevchenko Signed-off-by: Lars-Peter Clausen Signed-off-by: Vinod Koul --- include/linux/dmaengine.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 4662d9aa6d5a5..2f69e1d93f92e 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -895,6 +895,8 @@ static inline int dmaengine_terminate_async(struct dma_chan *chan) */ static inline void dmaengine_synchronize(struct dma_chan *chan) { + might_sleep(); + if (chan->device->device_synchronize) chan->device->device_synchronize(chan); } -- GitLab From 95da0c19d164f6df0b71a5187950f47d4b746e91 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Mon, 23 Nov 2015 14:09:39 +0100 Subject: [PATCH 0973/2855] dmaengine: at_xdmac: fix spurious flag status for mem2mem transfers When setting the channel configuration register, the perid field is not set to 0 since it is useless for mem2mem transfers. Unfortunately, a device has 0 as perid. It could cause spurious flags status because the controller could mix some events from the two channels. For that reason, use the highest perid value for mem2mem transfers since it doesn't match the perid of other devices. Signed-off-by: Ludovic Desroches Acked-by: Nicolas Ferre Signed-off-by: Vinod Koul --- drivers/dma/at_xdmac.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index b5e132d4bae5b..f2b6e7d227650 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -863,8 +863,12 @@ at_xdmac_interleaved_queue_desc(struct dma_chan *chan, * access. Hopefully we can access DDR through both ports (at least on * SAMA5D4x), so we can use the same interface for source and dest, * that solves the fact we don't know the direction. + * ERRATA: Even if useless for memory transfers, the PERID has to not + * match the one of another channel. If not, it could lead to spurious + * flag status. */ - u32 chan_cc = AT_XDMAC_CC_DIF(0) + u32 chan_cc = AT_XDMAC_CC_PERID(0x3f) + | AT_XDMAC_CC_DIF(0) | AT_XDMAC_CC_SIF(0) | AT_XDMAC_CC_MBSIZE_SIXTEEN | AT_XDMAC_CC_TYPE_MEM_TRAN; @@ -1039,8 +1043,12 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, * access DDR through both ports (at least on SAMA5D4x), so we can use * the same interface for source and dest, that solves the fact we * don't know the direction. + * ERRATA: Even if useless for memory transfers, the PERID has to not + * match the one of another channel. If not, it could lead to spurious + * flag status. */ - u32 chan_cc = AT_XDMAC_CC_DAM_INCREMENTED_AM + u32 chan_cc = AT_XDMAC_CC_PERID(0x3f) + | AT_XDMAC_CC_DAM_INCREMENTED_AM | AT_XDMAC_CC_SAM_INCREMENTED_AM | AT_XDMAC_CC_DIF(0) | AT_XDMAC_CC_SIF(0) @@ -1140,8 +1148,12 @@ static struct at_xdmac_desc *at_xdmac_memset_create_desc(struct dma_chan *chan, * access. Hopefully we can access DDR through both ports (at least on * SAMA5D4x), so we can use the same interface for source and dest, * that solves the fact we don't know the direction. + * ERRATA: Even if useless for memory transfers, the PERID has to not + * match the one of another channel. If not, it could lead to spurious + * flag status. */ - u32 chan_cc = AT_XDMAC_CC_DAM_UBS_AM + u32 chan_cc = AT_XDMAC_CC_PERID(0x3f) + | AT_XDMAC_CC_DAM_UBS_AM | AT_XDMAC_CC_SAM_INCREMENTED_AM | AT_XDMAC_CC_DIF(0) | AT_XDMAC_CC_SIF(0) -- GitLab From 37580559f314bfba0c8bdae002bc5c10088ac457 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 17 Nov 2015 13:37:07 +0200 Subject: [PATCH 0974/2855] dmaengine: idma64: drop IRQ enable / disable in handler There is no need to disable interrupts in the IRQ handler. The driver guarantess that at one time only one descriptor is active, besides the fact that each call to the same channel will be serialized in idma64_chan_irq() handler anyway. Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul --- drivers/dma/idma64.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c index 7d56b47e4fcfd..6bba0907c263f 100644 --- a/drivers/dma/idma64.c +++ b/drivers/dma/idma64.c @@ -178,20 +178,12 @@ static irqreturn_t idma64_irq(int irq, void *dev) if (!status) return IRQ_NONE; - /* Disable interrupts */ - channel_clear_bit(idma64, MASK(XFER), idma64->all_chan_mask); - channel_clear_bit(idma64, MASK(ERROR), idma64->all_chan_mask); - status_xfer = dma_readl(idma64, RAW(XFER)); status_err = dma_readl(idma64, RAW(ERROR)); for (i = 0; i < idma64->dma.chancnt; i++) idma64_chan_irq(idma64, i, status_err, status_xfer); - /* Re-enable interrupts */ - channel_set_bit(idma64, MASK(XFER), idma64->all_chan_mask); - channel_set_bit(idma64, MASK(ERROR), idma64->all_chan_mask); - return IRQ_HANDLED; } -- GitLab From e3fdb1894cfac6dd4a5bb24d3232fd97ddf74c93 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 17 Nov 2015 13:37:08 +0200 Subject: [PATCH 0975/2855] dmaengine: idma64: set maximum allowed segment size for DMA This tells, for example, IOMMU what the maximum size of a segment the DMA controller can send. Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul --- drivers/dma/idma64.c | 2 ++ drivers/dma/idma64.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c index 6bba0907c263f..97802be315883 100644 --- a/drivers/dma/idma64.c +++ b/drivers/dma/idma64.c @@ -588,6 +588,8 @@ static int idma64_probe(struct idma64_chip *chip) idma64->dma.dev = chip->dev; + dma_set_max_seg_size(idma64->dma.dev, IDMA64C_CTLH_BLOCK_TS_MASK); + ret = dma_async_device_register(&idma64->dma); if (ret) return ret; diff --git a/drivers/dma/idma64.h b/drivers/dma/idma64.h index f6aeff0af8a52..8423f13ed0da7 100644 --- a/drivers/dma/idma64.h +++ b/drivers/dma/idma64.h @@ -54,7 +54,8 @@ #define IDMA64C_CTLL_LLP_S_EN (1 << 28) /* src block chain */ /* Bitfields in CTL_HI */ -#define IDMA64C_CTLH_BLOCK_TS(x) ((x) & ((1 << 17) - 1)) +#define IDMA64C_CTLH_BLOCK_TS_MASK ((1 << 17) - 1) +#define IDMA64C_CTLH_BLOCK_TS(x) ((x) & IDMA64C_CTLH_BLOCK_TS_MASK) #define IDMA64C_CTLH_DONE (1 << 17) /* Bitfields in CFG_LO */ -- GitLab From ac02979413e0310f85bbcc2945d65da7071c08fe Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 17 Nov 2015 13:37:09 +0200 Subject: [PATCH 0976/2855] dmaengine: idma64: convert idma64_hw_desc_fill() to return void Explicitly show in idma64_desc_fill() how we link the hardware descriptors. Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul --- drivers/dma/idma64.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c index 97802be315883..b6c13f9fffb6e 100644 --- a/drivers/dma/idma64.c +++ b/drivers/dma/idma64.c @@ -231,7 +231,7 @@ static void idma64_vdesc_free(struct virt_dma_desc *vdesc) idma64_desc_free(idma64c, to_idma64_desc(vdesc)); } -static u64 idma64_hw_desc_fill(struct idma64_hw_desc *hw, +static void idma64_hw_desc_fill(struct idma64_hw_desc *hw, struct dma_slave_config *config, enum dma_transfer_direction direction, u64 llp) { @@ -268,7 +268,6 @@ static u64 idma64_hw_desc_fill(struct idma64_hw_desc *hw, IDMA64C_CTLL_SRC_WIDTH(src_width); lli->llp = llp; - return hw->llp; } static void idma64_desc_fill(struct idma64_chan *idma64c, @@ -283,7 +282,8 @@ static void idma64_desc_fill(struct idma64_chan *idma64c, /* Fill the hardware descriptors and link them to a list */ do { hw = &desc->hw[--i]; - llp = idma64_hw_desc_fill(hw, config, desc->direction, llp); + idma64_hw_desc_fill(hw, config, desc->direction, llp); + llp = hw->llp; desc->length += hw->len; } while (i); -- GitLab From 390c49f7174a85d88ec080058d8b5c2e301d3f6b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 17 Nov 2015 13:37:10 +0200 Subject: [PATCH 0977/2855] dmaengine: idma64: use local variable to index descriptor Since a local variable contains the number of hardware desriptors at the beginning of idma64_desc_fill() we may use it to index the last descriptor as well. Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul --- drivers/dma/idma64.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c index b6c13f9fffb6e..3cb7b2c781970 100644 --- a/drivers/dma/idma64.c +++ b/drivers/dma/idma64.c @@ -274,10 +274,10 @@ static void idma64_desc_fill(struct idma64_chan *idma64c, struct idma64_desc *desc) { struct dma_slave_config *config = &idma64c->config; - struct idma64_hw_desc *hw = &desc->hw[desc->ndesc - 1]; + unsigned int i = desc->ndesc; + struct idma64_hw_desc *hw = &desc->hw[i - 1]; struct idma64_lli *lli = hw->lli; u64 llp = 0; - unsigned int i = desc->ndesc; /* Fill the hardware descriptors and link them to a list */ do { @@ -287,7 +287,7 @@ static void idma64_desc_fill(struct idma64_chan *idma64c, desc->length += hw->len; } while (i); - /* Trigger interrupt after last block */ + /* Trigger an interrupt after the last block is transfered */ lli->ctllo |= IDMA64C_CTLL_INT_EN; } -- GitLab From f94cf9f4c54a72ccbd2078bb0cedd3691a71c431 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 17 Nov 2015 13:34:26 +0200 Subject: [PATCH 0978/2855] dmaengine: acpi-dma: check for 64-bit MMIO address Currently the match DMA controller is done only for lower 32 bits of address which might be not true on 64-bit platform. Check upper portion as well. Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul --- drivers/dma/acpi-dma.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/dma/acpi-dma.c b/drivers/dma/acpi-dma.c index 16d0daa058a54..eed6bda01790f 100644 --- a/drivers/dma/acpi-dma.c +++ b/drivers/dma/acpi-dma.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -72,7 +73,9 @@ static int acpi_dma_parse_resource_group(const struct acpi_csrt_group *grp, si = (const struct acpi_csrt_shared_info *)&grp[1]; /* Match device by MMIO and IRQ */ - if (si->mmio_base_low != mem || si->gsi_interrupt != irq) + if (si->mmio_base_low != lower_32_bits(mem) || + si->mmio_base_high != upper_32_bits(mem) || + si->gsi_interrupt != irq) return 0; dev_dbg(&adev->dev, "matches with %.4s%04X (rev %u)\n", -- GitLab From f0579c8ceaf18adf1eca8b4404f9caac37208655 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 17 Nov 2015 18:00:30 +0200 Subject: [PATCH 0979/2855] dmaengine: hsu: speed up residue calculation There is no need to calculate an overall length of the descriptor each time we call for DMA transfer status. Instead we do this at descriptor allocation stage and keep the stored length for further usage. Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul --- drivers/dma/hsu/hsu.c | 17 ++++------------- drivers/dma/hsu/hsu.h | 1 + 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c index 823ad728aecff..eef145edb9368 100644 --- a/drivers/dma/hsu/hsu.c +++ b/drivers/dma/hsu/hsu.c @@ -228,6 +228,8 @@ static struct dma_async_tx_descriptor *hsu_dma_prep_slave_sg( for_each_sg(sgl, sg, sg_len, i) { desc->sg[i].addr = sg_dma_address(sg); desc->sg[i].len = sg_dma_len(sg); + + desc->length += sg_dma_len(sg); } desc->nents = sg_len; @@ -249,21 +251,10 @@ static void hsu_dma_issue_pending(struct dma_chan *chan) spin_unlock_irqrestore(&hsuc->vchan.lock, flags); } -static size_t hsu_dma_desc_size(struct hsu_dma_desc *desc) -{ - size_t bytes = 0; - unsigned int i; - - for (i = desc->active; i < desc->nents; i++) - bytes += desc->sg[i].len; - - return bytes; -} - static size_t hsu_dma_active_desc_size(struct hsu_dma_chan *hsuc) { struct hsu_dma_desc *desc = hsuc->desc; - size_t bytes = hsu_dma_desc_size(desc); + size_t bytes = desc->length; int i; i = desc->active % HSU_DMA_CHAN_NR_DESC; @@ -294,7 +285,7 @@ static enum dma_status hsu_dma_tx_status(struct dma_chan *chan, dma_set_residue(state, bytes); status = hsuc->desc->status; } else if (vdesc) { - bytes = hsu_dma_desc_size(to_hsu_dma_desc(vdesc)); + bytes = to_hsu_dma_desc(vdesc)->length; dma_set_residue(state, bytes); } spin_unlock_irqrestore(&hsuc->vchan.lock, flags); diff --git a/drivers/dma/hsu/hsu.h b/drivers/dma/hsu/hsu.h index f06579c6d548d..578a8ee8cd054 100644 --- a/drivers/dma/hsu/hsu.h +++ b/drivers/dma/hsu/hsu.h @@ -65,6 +65,7 @@ struct hsu_dma_desc { enum dma_transfer_direction direction; struct hsu_dma_sg *sg; unsigned int nents; + size_t length; unsigned int active; enum dma_status status; }; -- GitLab From 82d149b86d31e11fbbbc1b850bebffe1bfa2e82d Mon Sep 17 00:00:00 2001 From: Yuan Yao Date: Fri, 30 Oct 2015 19:03:58 +0800 Subject: [PATCH 0980/2855] dmaengine: fsl-edma: add PM suspend/resume support This add power management suspend/resume support for the fsl-edma driver. eDMA acted as a basic function used by others. What it needs to do is the two steps below to support power management. In fsl_edma_suspend_late: Check whether the DMA chan is idle, if it is not idle disable DMA request. In fsl_edma_resume_early: Enable the eDMA and wait for being used. Signed-off-by: Yuan Yao Signed-off-by: Vinod Koul --- drivers/dma/fsl-edma.c | 85 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 3 deletions(-) diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c index 915eec3cc279c..be2e62b879481 100644 --- a/drivers/dma/fsl-edma.c +++ b/drivers/dma/fsl-edma.c @@ -116,6 +116,10 @@ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \ BIT(DMA_SLAVE_BUSWIDTH_8_BYTES) +enum fsl_edma_pm_state { + RUNNING = 0, + SUSPENDED, +}; struct fsl_edma_hw_tcd { __le32 saddr; @@ -147,6 +151,9 @@ struct fsl_edma_slave_config { struct fsl_edma_chan { struct virt_dma_chan vchan; enum dma_status status; + enum fsl_edma_pm_state pm_state; + bool idle; + u32 slave_id; struct fsl_edma_engine *edma; struct fsl_edma_desc *edesc; struct fsl_edma_slave_config fsc; @@ -298,6 +305,7 @@ static int fsl_edma_terminate_all(struct dma_chan *chan) spin_lock_irqsave(&fsl_chan->vchan.lock, flags); fsl_edma_disable_request(fsl_chan); fsl_chan->edesc = NULL; + fsl_chan->idle = true; vchan_get_all_descriptors(&fsl_chan->vchan, &head); spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); vchan_dma_desc_free_list(&fsl_chan->vchan, &head); @@ -313,6 +321,7 @@ static int fsl_edma_pause(struct dma_chan *chan) if (fsl_chan->edesc) { fsl_edma_disable_request(fsl_chan); fsl_chan->status = DMA_PAUSED; + fsl_chan->idle = true; } spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); return 0; @@ -327,6 +336,7 @@ static int fsl_edma_resume(struct dma_chan *chan) if (fsl_chan->edesc) { fsl_edma_enable_request(fsl_chan); fsl_chan->status = DMA_IN_PROGRESS; + fsl_chan->idle = false; } spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); return 0; @@ -648,6 +658,7 @@ static void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan) fsl_edma_set_tcd_regs(fsl_chan, fsl_chan->edesc->tcd[0].vtcd); fsl_edma_enable_request(fsl_chan); fsl_chan->status = DMA_IN_PROGRESS; + fsl_chan->idle = false; } static irqreturn_t fsl_edma_tx_handler(int irq, void *dev_id) @@ -676,6 +687,7 @@ static irqreturn_t fsl_edma_tx_handler(int irq, void *dev_id) vchan_cookie_complete(&fsl_chan->edesc->vdesc); fsl_chan->edesc = NULL; fsl_chan->status = DMA_COMPLETE; + fsl_chan->idle = true; } else { vchan_cyclic_callback(&fsl_chan->edesc->vdesc); } @@ -704,6 +716,7 @@ static irqreturn_t fsl_edma_err_handler(int irq, void *dev_id) edma_writeb(fsl_edma, EDMA_CERR_CERR(ch), fsl_edma->membase + EDMA_CERR); fsl_edma->chans[ch].status = DMA_ERROR; + fsl_edma->chans[ch].idle = true; } } return IRQ_HANDLED; @@ -724,6 +737,12 @@ static void fsl_edma_issue_pending(struct dma_chan *chan) spin_lock_irqsave(&fsl_chan->vchan.lock, flags); + if (unlikely(fsl_chan->pm_state != RUNNING)) { + spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); + /* cannot submit due to suspend */ + return; + } + if (vchan_issue_pending(&fsl_chan->vchan) && !fsl_chan->edesc) fsl_edma_xfer_desc(fsl_chan); @@ -735,6 +754,7 @@ static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec, { struct fsl_edma_engine *fsl_edma = ofdma->of_dma_data; struct dma_chan *chan, *_chan; + struct fsl_edma_chan *fsl_chan; unsigned long chans_per_mux = fsl_edma->n_chans / DMAMUX_NR; if (dma_spec->args_count != 2) @@ -748,8 +768,10 @@ static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec, chan = dma_get_slave_channel(chan); if (chan) { chan->device->privatecnt++; - fsl_edma_chan_mux(to_fsl_edma_chan(chan), - dma_spec->args[1], true); + fsl_chan = to_fsl_edma_chan(chan); + fsl_chan->slave_id = dma_spec->args[1]; + fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, + true); mutex_unlock(&fsl_edma->fsl_edma_mutex); return chan; } @@ -888,7 +910,9 @@ static int fsl_edma_probe(struct platform_device *pdev) struct fsl_edma_chan *fsl_chan = &fsl_edma->chans[i]; fsl_chan->edma = fsl_edma; - + fsl_chan->pm_state = RUNNING; + fsl_chan->slave_id = 0; + fsl_chan->idle = true; fsl_chan->vchan.desc_free = fsl_edma_free_desc; vchan_init(&fsl_chan->vchan, &fsl_edma->dma_dev); @@ -959,6 +983,60 @@ static int fsl_edma_remove(struct platform_device *pdev) return 0; } +static int fsl_edma_suspend_late(struct device *dev) +{ + struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev); + struct fsl_edma_chan *fsl_chan; + unsigned long flags; + int i; + + for (i = 0; i < fsl_edma->n_chans; i++) { + fsl_chan = &fsl_edma->chans[i]; + spin_lock_irqsave(&fsl_chan->vchan.lock, flags); + /* Make sure chan is idle or will force disable. */ + if (unlikely(!fsl_chan->idle)) { + dev_warn(dev, "WARN: There is non-idle channel."); + fsl_edma_disable_request(fsl_chan); + fsl_edma_chan_mux(fsl_chan, 0, false); + } + + fsl_chan->pm_state = SUSPENDED; + spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); + } + + return 0; +} + +static int fsl_edma_resume_early(struct device *dev) +{ + struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev); + struct fsl_edma_chan *fsl_chan; + int i; + + for (i = 0; i < fsl_edma->n_chans; i++) { + fsl_chan = &fsl_edma->chans[i]; + fsl_chan->pm_state = RUNNING; + edma_writew(fsl_edma, 0x0, fsl_edma->membase + EDMA_TCD_CSR(i)); + if (fsl_chan->slave_id != 0) + fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true); + } + + edma_writel(fsl_edma, EDMA_CR_ERGA | EDMA_CR_ERCA, + fsl_edma->membase + EDMA_CR); + + return 0; +} + +/* + * eDMA provides the service to others, so it should be suspend late + * and resume early. When eDMA suspend, all of the clients should stop + * the DMA data transmission and let the channel idle. + */ +static const struct dev_pm_ops fsl_edma_pm_ops = { + .suspend_late = fsl_edma_suspend_late, + .resume_early = fsl_edma_resume_early, +}; + static const struct of_device_id fsl_edma_dt_ids[] = { { .compatible = "fsl,vf610-edma", }, { /* sentinel */ } @@ -969,6 +1047,7 @@ static struct platform_driver fsl_edma_driver = { .driver = { .name = "fsl-edma", .of_match_table = fsl_edma_dt_ids, + .pm = &fsl_edma_pm_ops, }, .probe = fsl_edma_probe, .remove = fsl_edma_remove, -- GitLab From 1f281792f649fc40054fc9146d8aa6b8b3c2aaff Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 21 Nov 2015 12:09:47 +0100 Subject: [PATCH 0981/2855] dmaengine: at_xdmac: Remove unnecessary synchronize_irq() before free_irq() Calling synchronize_irq() right before free_irq() is quite useless. On one hand the IRQ can easily fire again before free_irq() is entered, on the other hand free_irq() itself calls synchronize_irq() internally (in a race condition free way), before any state associated with the IRQ is freed. Patch was generated using the following semantic patch: // @@ expression irq; @@ -synchronize_irq(irq); free_irq(irq, ...); // Signed-off-by: Lars-Peter Clausen Acked-by: Ludovic Desroches Signed-off-by: Vinod Koul --- drivers/dma/at_xdmac.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index f2b6e7d227650..d0ae4613b87ef 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -2007,8 +2007,6 @@ static int at_xdmac_remove(struct platform_device *pdev) dma_async_device_unregister(&atxdmac->dma); clk_disable_unprepare(atxdmac->clk); - synchronize_irq(atxdmac->irq); - free_irq(atxdmac->irq, atxdmac->dma.dev); for (i = 0; i < atxdmac->dma.chancnt; i++) { -- GitLab From 9ff68186eaac415bfc0b84d627b7ecec24b0c52d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 21 Nov 2015 12:09:48 +0100 Subject: [PATCH 0982/2855] dmaengine: img-mdc: Remove unnecessary synchronize_irq() before devm_free_irq() Calling synchronize_irq() right before devm_free_irq() is quite useless. On one hand the IRQ can easily fire again before devm_free_irq() is entered, on the other hand devm_free_irq() itself calls synchronize_irq() internally (in a race condition free way), before any state associated with the IRQ is freed. Patch was generated using the following semantic patch: // @@ expression irq, dev; @@ -synchronize_irq(irq); devm_free_irq(dev, irq, ...); // Signed-off-by: Lars-Peter Clausen Signed-off-by: Vinod Koul --- drivers/dma/img-mdc-dma.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/dma/img-mdc-dma.c b/drivers/dma/img-mdc-dma.c index 9ca56830cc63d..42ae58d1e3030 100644 --- a/drivers/dma/img-mdc-dma.c +++ b/drivers/dma/img-mdc-dma.c @@ -979,7 +979,6 @@ static int mdc_dma_remove(struct platform_device *pdev) vc.chan.device_node) { list_del(&mchan->vc.chan.device_node); - synchronize_irq(mchan->irq); devm_free_irq(&pdev->dev, mchan->irq, mchan); tasklet_kill(&mchan->vc.task); -- GitLab From edd3bdbe9db1415f744bb5da0752675ddbd9eee0 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Fri, 13 Nov 2015 16:39:38 +0000 Subject: [PATCH 0983/2855] dmaengine: tegra-apb: Correct runtime-pm usage The tegra-apb DMA driver enables runtime-pm but never calls pm_runtime_get/put and hence the runtime-pm callbacks are never invoked. The driver manages the clocks by directly calling clk_prepare_enable() and clk_unprepare_disable(). Fix this by replacing the clk_prepare_enable() and clk_disable_unprepare() with pm_runtime_get_sync() and pm_runtime_put(), respectively. Note that the consequence of this is that if runtime-pm is disabled, then the clocks will remain on the entire time the driver is loaded. However, if runtime-pm is disabled, then power is not most likely not a concern. Signed-off-by: Jon Hunter Signed-off-by: Vinod Koul --- drivers/dma/tegra20-apb-dma.c | 43 +++++++++++++++-------------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index c8f79dcaaee80..f68bccf55a240 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -1186,10 +1186,12 @@ static int tegra_dma_alloc_chan_resources(struct dma_chan *dc) dma_cookie_init(&tdc->dma_chan); tdc->config_init = false; - ret = clk_prepare_enable(tdma->dma_clk); + + ret = pm_runtime_get_sync(tdma->dev); if (ret < 0) - dev_err(tdc2dev(tdc), "clk_prepare_enable failed: %d\n", ret); - return ret; + return ret; + + return 0; } static void tegra_dma_free_chan_resources(struct dma_chan *dc) @@ -1232,7 +1234,7 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc) list_del(&sg_req->node); kfree(sg_req); } - clk_disable_unprepare(tdma->dma_clk); + pm_runtime_put(tdma->dev); tdc->slave_id = 0; } @@ -1356,20 +1358,14 @@ static int tegra_dma_probe(struct platform_device *pdev) spin_lock_init(&tdma->global_lock); pm_runtime_enable(&pdev->dev); - if (!pm_runtime_enabled(&pdev->dev)) { + if (!pm_runtime_enabled(&pdev->dev)) ret = tegra_dma_runtime_resume(&pdev->dev); - if (ret) { - dev_err(&pdev->dev, "dma_runtime_resume failed %d\n", - ret); - goto err_pm_disable; - } - } + else + ret = pm_runtime_get_sync(&pdev->dev); - /* Enable clock before accessing registers */ - ret = clk_prepare_enable(tdma->dma_clk); if (ret < 0) { - dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret); - goto err_pm_disable; + pm_runtime_disable(&pdev->dev); + return ret; } /* Reset DMA controller */ @@ -1382,7 +1378,7 @@ static int tegra_dma_probe(struct platform_device *pdev) tdma_write(tdma, TEGRA_APBDMA_CONTROL, 0); tdma_write(tdma, TEGRA_APBDMA_IRQ_MASK_SET, 0xFFFFFFFFul); - clk_disable_unprepare(tdma->dma_clk); + pm_runtime_put(&pdev->dev); INIT_LIST_HEAD(&tdma->dma_dev.channels); for (i = 0; i < cdata->nr_channels; i++) { @@ -1485,7 +1481,6 @@ err_irq: tasklet_kill(&tdc->tasklet); } -err_pm_disable: pm_runtime_disable(&pdev->dev); if (!pm_runtime_status_suspended(&pdev->dev)) tegra_dma_runtime_suspend(&pdev->dev); @@ -1543,7 +1538,7 @@ static int tegra_dma_pm_suspend(struct device *dev) int ret; /* Enable clock before accessing register */ - ret = tegra_dma_runtime_resume(dev); + ret = pm_runtime_get_sync(dev); if (ret < 0) return ret; @@ -1560,7 +1555,7 @@ static int tegra_dma_pm_suspend(struct device *dev) } /* Disable clock */ - tegra_dma_runtime_suspend(dev); + pm_runtime_put(dev); return 0; } @@ -1571,7 +1566,7 @@ static int tegra_dma_pm_resume(struct device *dev) int ret; /* Enable clock before accessing register */ - ret = tegra_dma_runtime_resume(dev); + ret = pm_runtime_get_sync(dev); if (ret < 0) return ret; @@ -1592,16 +1587,14 @@ static int tegra_dma_pm_resume(struct device *dev) } /* Disable clock */ - tegra_dma_runtime_suspend(dev); + pm_runtime_put(dev); return 0; } #endif static const struct dev_pm_ops tegra_dma_dev_pm_ops = { -#ifdef CONFIG_PM - .runtime_suspend = tegra_dma_runtime_suspend, - .runtime_resume = tegra_dma_runtime_resume, -#endif + SET_RUNTIME_PM_OPS(tegra_dma_runtime_suspend, tegra_dma_runtime_resume, + NULL) SET_SYSTEM_SLEEP_PM_OPS(tegra_dma_pm_suspend, tegra_dma_pm_resume) }; -- GitLab From 286a6441a333abfa21a700683db5b3302f75a4de Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Fri, 13 Nov 2015 16:39:39 +0000 Subject: [PATCH 0984/2855] dmaengine: tegra-apb: Use dev_get_drvdata() In the tegra_dma_runtime_suspend/resume functions, the pdev structure is not needed, and so just call dev_get_drvdata() to get the device data structure. Signed-off-by: Jon Hunter Signed-off-by: Vinod Koul --- drivers/dma/tegra20-apb-dma.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index f68bccf55a240..355dbc354818b 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -1509,8 +1509,7 @@ static int tegra_dma_remove(struct platform_device *pdev) static int tegra_dma_runtime_suspend(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct tegra_dma *tdma = platform_get_drvdata(pdev); + struct tegra_dma *tdma = dev_get_drvdata(dev); clk_disable_unprepare(tdma->dma_clk); return 0; @@ -1518,8 +1517,7 @@ static int tegra_dma_runtime_suspend(struct device *dev) static int tegra_dma_runtime_resume(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct tegra_dma *tdma = platform_get_drvdata(pdev); + struct tegra_dma *tdma = dev_get_drvdata(dev); int ret; ret = clk_prepare_enable(tdma->dma_clk); -- GitLab From 68ae7a93fb0e6432baaa7c323a650b1b5461643f Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Fri, 13 Nov 2015 16:39:40 +0000 Subject: [PATCH 0985/2855] dmaengine: tegra-apb: Save and restore word count Newer tegra devices have a separate word count register per channel that contains the number of words to be transferred. This register is not saved or restored by the suspend/resume helpers for these newer devices and so ensure that it is. Signed-off-by: Jon Hunter Signed-off-by: Vinod Koul --- drivers/dma/tegra20-apb-dma.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 355dbc354818b..18a561376c639 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -1550,6 +1550,9 @@ static int tegra_dma_pm_suspend(struct device *dev) ch_reg->apb_ptr = tdc_read(tdc, TEGRA_APBDMA_CHAN_APBPTR); ch_reg->ahb_seq = tdc_read(tdc, TEGRA_APBDMA_CHAN_AHBSEQ); ch_reg->apb_seq = tdc_read(tdc, TEGRA_APBDMA_CHAN_APBSEQ); + if (tdma->chip_data->support_separate_wcount_reg) + ch_reg->wcount = tdc_read(tdc, + TEGRA_APBDMA_CHAN_WCOUNT); } /* Disable clock */ @@ -1576,6 +1579,9 @@ static int tegra_dma_pm_resume(struct device *dev) struct tegra_dma_channel *tdc = &tdma->channels[i]; struct tegra_dma_channel_regs *ch_reg = &tdc->channel_reg; + if (tdma->chip_data->support_separate_wcount_reg) + tdc_write(tdc, TEGRA_APBDMA_CHAN_WCOUNT, + ch_reg->wcount); tdc_write(tdc, TEGRA_APBDMA_CHAN_APBSEQ, ch_reg->apb_seq); tdc_write(tdc, TEGRA_APBDMA_CHAN_APBPTR, ch_reg->apb_ptr); tdc_write(tdc, TEGRA_APBDMA_CHAN_AHBSEQ, ch_reg->ahb_seq); -- GitLab From 4aad5be04088d9b6c2783d5f0fb6b1ac7bbc45c1 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Fri, 13 Nov 2015 16:39:41 +0000 Subject: [PATCH 0986/2855] dmaengine: tegra-apb: Only save channel state for those in use Currently the tegra-apb DMA driver suspend/resume helpers, save and restore the registers for all channels regardless of whether they are in use or not. Change this so that only channels that have been allocated and configured are saved and restored. Signed-off-by: Jon Hunter Signed-off-by: Vinod Koul --- drivers/dma/tegra20-apb-dma.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 18a561376c639..d4cabd6931e5d 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -1545,6 +1545,10 @@ static int tegra_dma_pm_suspend(struct device *dev) struct tegra_dma_channel *tdc = &tdma->channels[i]; struct tegra_dma_channel_regs *ch_reg = &tdc->channel_reg; + /* Only save the state of DMA channels that are in use */ + if (!tdc->config_init) + continue; + ch_reg->csr = tdc_read(tdc, TEGRA_APBDMA_CHAN_CSR); ch_reg->ahb_ptr = tdc_read(tdc, TEGRA_APBDMA_CHAN_AHBPTR); ch_reg->apb_ptr = tdc_read(tdc, TEGRA_APBDMA_CHAN_APBPTR); @@ -1579,6 +1583,10 @@ static int tegra_dma_pm_resume(struct device *dev) struct tegra_dma_channel *tdc = &tdma->channels[i]; struct tegra_dma_channel_regs *ch_reg = &tdc->channel_reg; + /* Only restore the state of DMA channels that are in use */ + if (!tdc->config_init) + continue; + if (tdma->chip_data->support_separate_wcount_reg) tdc_write(tdc, TEGRA_APBDMA_CHAN_WCOUNT, ch_reg->wcount); -- GitLab From 8fe9739bc3ed616fb8cf935fb5099051493c2424 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Fri, 13 Nov 2015 16:39:42 +0000 Subject: [PATCH 0987/2855] dmaengine: tegra-apb: Update driver to use GFP_NOWAIT The tegra20-apb-dma driver currently uses the flag GFP_ATOMIC when allocating memory for structures used in conjunction with the DMA descriptors. It is preferred that dmaengine drivers use GFP_NOWAIT instead and so the emergency memory pool will not be used by these drivers. Signed-off-by: Jon Hunter Signed-off-by: Vinod Koul --- drivers/dma/tegra20-apb-dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index d4cabd6931e5d..754c1f54d4fef 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -296,7 +296,7 @@ static struct tegra_dma_desc *tegra_dma_desc_get( spin_unlock_irqrestore(&tdc->lock, flags); /* Allocate DMA desc */ - dma_desc = kzalloc(sizeof(*dma_desc), GFP_ATOMIC); + dma_desc = kzalloc(sizeof(*dma_desc), GFP_NOWAIT); if (!dma_desc) { dev_err(tdc2dev(tdc), "dma_desc alloc failed\n"); return NULL; @@ -336,7 +336,7 @@ static struct tegra_dma_sg_req *tegra_dma_sg_req_get( } spin_unlock_irqrestore(&tdc->lock, flags); - sg_req = kzalloc(sizeof(struct tegra_dma_sg_req), GFP_ATOMIC); + sg_req = kzalloc(sizeof(struct tegra_dma_sg_req), GFP_NOWAIT); if (!sg_req) dev_err(tdc2dev(tdc), "sg_req alloc failed\n"); return sg_req; -- GitLab From 05e866b42e65c2f68dea7fc7be4fcf534f4d8a12 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Fri, 13 Nov 2015 16:39:43 +0000 Subject: [PATCH 0988/2855] dmaengine: tegra-apb: Free interrupts before killing tasklets On probe failure or driver removal, before killing any tasklets, ensure that the channel interrupt is freed to ensure that another channel interrupt cannot occur and schedule the tasklet again. Signed-off-by: Jon Hunter Signed-off-by: Vinod Koul --- drivers/dma/tegra20-apb-dma.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 754c1f54d4fef..935da8192f59c 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -1396,8 +1396,7 @@ static int tegra_dma_probe(struct platform_device *pdev) } tdc->irq = res->start; snprintf(tdc->name, sizeof(tdc->name), "apbdma.%d", i); - ret = devm_request_irq(&pdev->dev, tdc->irq, - tegra_dma_isr, 0, tdc->name, tdc); + ret = request_irq(tdc->irq, tegra_dma_isr, 0, tdc->name, tdc); if (ret) { dev_err(&pdev->dev, "request_irq failed with err %d channel %d\n", @@ -1478,6 +1477,8 @@ err_unregister_dma_dev: err_irq: while (--i >= 0) { struct tegra_dma_channel *tdc = &tdma->channels[i]; + + free_irq(tdc->irq, tdc); tasklet_kill(&tdc->tasklet); } @@ -1497,6 +1498,7 @@ static int tegra_dma_remove(struct platform_device *pdev) for (i = 0; i < tdma->chip_data->nr_channels; ++i) { tdc = &tdma->channels[i]; + free_irq(tdc->irq, tdc); tasklet_kill(&tdc->tasklet); } -- GitLab From 8d6c16dd7213fa43702416e3dd1059e9e36bc758 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 5 Dec 2015 16:23:26 +0000 Subject: [PATCH 0989/2855] iio:configfs: Introduce iio/configfs.h to provide a location for the configfs_subsystem This exported element needs to be accesible to all drivers using configfs within IIO. Previously it was in the sw_trig.h file which only convered one such usecase. This also fixes a sparse warning as it is now in a header that makes sense to include from industrialio-configfs.c Signed-off-by: Jonathan Cameron < jic23@kernel.org> --- drivers/iio/industrialio-configfs.c | 1 + drivers/iio/industrialio-sw-trigger.c | 1 + include/linux/iio/configfs.h | 15 +++++++++++++++ include/linux/iio/sw_trigger.h | 1 - 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 include/linux/iio/configfs.h diff --git a/drivers/iio/industrialio-configfs.c b/drivers/iio/industrialio-configfs.c index 83563dd7fcf4b..45ce2bc471802 100644 --- a/drivers/iio/industrialio-configfs.c +++ b/drivers/iio/industrialio-configfs.c @@ -15,6 +15,7 @@ #include #include +#include static struct config_item_type iio_root_group_type = { .ct_owner = THIS_MODULE, diff --git a/drivers/iio/industrialio-sw-trigger.c b/drivers/iio/industrialio-sw-trigger.c index 4825cfd9c4ea4..311f9fe5aa34b 100644 --- a/drivers/iio/industrialio-sw-trigger.c +++ b/drivers/iio/industrialio-sw-trigger.c @@ -15,6 +15,7 @@ #include #include +#include #include static struct config_group *iio_triggers_group; diff --git a/include/linux/iio/configfs.h b/include/linux/iio/configfs.h new file mode 100644 index 0000000000000..93befd67c15cf --- /dev/null +++ b/include/linux/iio/configfs.h @@ -0,0 +1,15 @@ +/* + * Industrial I/O configfs support + * + * Copyright (c) 2015 Intel Corporation + * + * 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. + */ +#ifndef __IIO_CONFIGFS +#define __IIO_CONFIGFS + +extern struct configfs_subsystem iio_configfs_subsys; + +#endif /* __IIO_CONFIGFS */ diff --git a/include/linux/iio/sw_trigger.h b/include/linux/iio/sw_trigger.h index c2f33b2b35a5e..5198f8ed08a46 100644 --- a/include/linux/iio/sw_trigger.h +++ b/include/linux/iio/sw_trigger.h @@ -20,7 +20,6 @@ module_driver(__iio_sw_trigger_type, iio_register_sw_trigger_type, \ iio_unregister_sw_trigger_type) -extern struct configfs_subsystem iio_configfs_subsys; struct iio_sw_trigger_ops; struct iio_sw_trigger_type { -- GitLab From 366e65633cf4f117609965cd6e189f2cd11533d2 Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Tue, 1 Dec 2015 21:05:22 -0800 Subject: [PATCH 0990/2855] iio: proximity: lidar: optimize i2c transactions Optimize device tranactions using i2c transfers versus multiple possibly racey i2c_smbus_* function calls, and only one transaction for distance measurement. Falls back to smbus method if i2c functionality isn't available. Signed-off-by: Matt Ranostay Signed-off-by: Jonathan Cameron --- .../iio/proximity/pulsedlight-lidar-lite-v2.c | 95 ++++++++++++++----- 1 file changed, 70 insertions(+), 25 deletions(-) diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c index be8ccef735f8b..e7ea44d61942e 100644 --- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c +++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c @@ -36,8 +36,10 @@ #define LIDAR_REG_STATUS_INVALID BIT(3) #define LIDAR_REG_STATUS_READY BIT(0) -#define LIDAR_REG_DATA_HBYTE 0x0f -#define LIDAR_REG_DATA_LBYTE 0x10 +#define LIDAR_REG_DATA_HBYTE 0x0f +#define LIDAR_REG_DATA_LBYTE 0x10 +#define LIDAR_REG_DATA_WORD_READ BIT(7) + #define LIDAR_REG_PWR_CONTROL 0x65 #define LIDAR_DRV_NAME "lidar" @@ -46,6 +48,9 @@ struct lidar_data { struct iio_dev *indio_dev; struct i2c_client *client; + int (*xfer)(struct lidar_data *data, u8 reg, u8 *val, int len); + int i2c_enabled; + u16 buffer[8]; /* 2 byte distance + 8 byte timestamp */ }; @@ -64,7 +69,28 @@ static const struct iio_chan_spec lidar_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(1), }; -static int lidar_read_byte(struct lidar_data *data, int reg) +static int lidar_i2c_xfer(struct lidar_data *data, u8 reg, u8 *val, int len) +{ + struct i2c_client *client = data->client; + struct i2c_msg msg[2]; + int ret; + + msg[0].addr = client->addr; + msg[0].flags = client->flags | I2C_M_STOP; + msg[0].len = 1; + msg[0].buf = (char *) ® + + msg[1].addr = client->addr; + msg[1].flags = client->flags | I2C_M_RD; + msg[1].len = len; + msg[1].buf = (char *) val; + + ret = i2c_transfer(client->adapter, msg, 2); + + return (ret == 2) ? 0 : ret; +} + +static int lidar_smbus_xfer(struct lidar_data *data, u8 reg, u8 *val, int len) { struct i2c_client *client = data->client; int ret; @@ -74,17 +100,35 @@ static int lidar_read_byte(struct lidar_data *data, int reg) * so in turn i2c_smbus_read_byte_data cannot be used */ - ret = i2c_smbus_write_byte(client, reg); - if (ret < 0) { - dev_err(&client->dev, "cannot write addr value"); - return ret; + while (len--) { + ret = i2c_smbus_write_byte(client, reg++); + if (ret < 0) { + dev_err(&client->dev, "cannot write addr value"); + return ret; + } + + ret = i2c_smbus_read_byte(client); + if (ret < 0) { + dev_err(&client->dev, "cannot read data value"); + return ret; + } + + *(val++) = ret; } - ret = i2c_smbus_read_byte(client); + return 0; +} + +static int lidar_read_byte(struct lidar_data *data, u8 reg) +{ + int ret; + u8 val; + + ret = data->xfer(data, reg, &val, 1); if (ret < 0) - dev_err(&client->dev, "cannot read data value"); + return ret; - return ret; + return val; } static inline int lidar_write_control(struct lidar_data *data, int val) @@ -100,22 +144,14 @@ static inline int lidar_write_power(struct lidar_data *data, int val) static int lidar_read_measurement(struct lidar_data *data, u16 *reg) { - int ret; - int val; - - ret = lidar_read_byte(data, LIDAR_REG_DATA_HBYTE); - if (ret < 0) - return ret; - val = ret << 8; + int ret = data->xfer(data, LIDAR_REG_DATA_HBYTE | + (data->i2c_enabled ? LIDAR_REG_DATA_WORD_READ : 0), + (u8 *) reg, 2); - ret = lidar_read_byte(data, LIDAR_REG_DATA_LBYTE); - if (ret < 0) - return ret; + if (!ret) + *reg = be16_to_cpu(*reg); - val |= ret; - *reg = val; - - return 0; + return ret; } static int lidar_get_measurement(struct lidar_data *data, u16 *reg) @@ -233,6 +269,16 @@ static int lidar_probe(struct i2c_client *client, indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); if (!indio_dev) return -ENOMEM; + data = iio_priv(indio_dev); + + if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + data->xfer = lidar_i2c_xfer; + data->i2c_enabled = 1; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BYTE)) + data->xfer = lidar_smbus_xfer; + else + return -ENOTSUPP; indio_dev->info = &lidar_info; indio_dev->name = LIDAR_DRV_NAME; @@ -240,7 +286,6 @@ static int lidar_probe(struct i2c_client *client, indio_dev->num_channels = ARRAY_SIZE(lidar_channels); indio_dev->modes = INDIO_DIRECT_MODE; - data = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); data->client = client; -- GitLab From ec0096f853fef46000c80bb3fd035d8376d957ac Mon Sep 17 00:00:00 2001 From: Robert Kmiec Date: Fri, 4 Dec 2015 00:54:48 +0100 Subject: [PATCH 0991/2855] iio: st_accel_core: Remove unneeded define Definition of ST_SENSORS_WAI_ADDRESS was introduced within a very first commit of this driver, but it was never used. This address is already defined as ST_SENSORS_DEFAULT_WAI_ADDRESS in include/linux/iio/common/st_sensors.h To avoid duplication of the same constant in two different places called almost exactly the same, the one which was never used should be removed. Signed-off-by: Robert Kmiec Signed-off-by: Jonathan Cameron --- drivers/iio/common/st_sensors/st_sensors_core.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index 25258e2c1a82d..8447c31e27f26 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -18,9 +18,6 @@ #include #include - -#define ST_SENSORS_WAI_ADDRESS 0x0f - static inline u32 st_sensors_get_unaligned_le24(const u8 *p) { return (s32)((p[0] | p[1] << 8 | p[2] << 16) << 8) >> 8; -- GitLab From 9ab655a32e008bfe906b0bf8fb907b412f7c2e87 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 4 Dec 2015 00:28:17 +0100 Subject: [PATCH 0992/2855] staging: iio: select IRQ_WORK for IIO_DUMMY_EVGEN The iio dummy code was recently changed to use irq_work_queue, but that code is compiled into the kernel only if IRQ_WORK is set, so we can get a link error here: drivers/built-in.o: In function `iio_evgen_poke': (.text+0x208a04): undefined reference to `irq_work_queue' This changes the Kconfig file to match what other drivers do. Signed-off-by: Arnd Bergmann Fixes: fd2bb310ca3d ("Staging: iio: Move evgen interrupt generation to irq_work") Acked-by: Daniel Baluta Signed-off-by: Jonathan Cameron --- drivers/iio/dummy/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/iio/dummy/Kconfig b/drivers/iio/dummy/Kconfig index e8676aa97d62f..71805ced1aae3 100644 --- a/drivers/iio/dummy/Kconfig +++ b/drivers/iio/dummy/Kconfig @@ -5,7 +5,8 @@ menu "IIO dummy driver" depends on IIO config IIO_DUMMY_EVGEN - tristate + select IRQ_WORK + tristate config IIO_SIMPLE_DUMMY tristate "An example driver with no hardware requirements" -- GitLab From c31d0a00021d7289c01edc3d9670da52132d0457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Sat, 5 Dec 2015 18:51:31 +0100 Subject: [PATCH 0993/2855] i2c: emev2: add slave support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add I2C slave provider using the generic slave interface. Signed-off-by: Niklas Söderlund Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-emev2.c | 112 ++++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-emev2.c b/drivers/i2c/busses/i2c-emev2.c index 192ef6b50c794..96bb4e7490128 100644 --- a/drivers/i2c/busses/i2c-emev2.c +++ b/drivers/i2c/busses/i2c-emev2.c @@ -71,6 +71,7 @@ struct em_i2c_device { struct i2c_adapter adap; struct completion msg_done; struct clk *sclk; + struct i2c_client *slave; }; static inline void em_clear_set_bit(struct em_i2c_device *priv, u8 clear, u8 set, u8 reg) @@ -226,22 +227,131 @@ static int em_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, return num; } +static bool em_i2c_slave_irq(struct em_i2c_device *priv) +{ + u8 status, value; + enum i2c_slave_event event; + int ret; + + if (!priv->slave) + return false; + + status = readb(priv->base + I2C_OFS_IICSE0); + + /* Extension code, do not participate */ + if (status & I2C_BIT_EXC0) { + em_clear_set_bit(priv, 0, I2C_BIT_LREL0, I2C_OFS_IICC0); + return true; + } + + /* Stop detected, we don't know if it's for slave or master */ + if (status & I2C_BIT_SPD0) { + /* Notify slave device */ + i2c_slave_event(priv->slave, I2C_SLAVE_STOP, &value); + /* Pretend we did not handle the interrupt */ + return false; + } + + /* Only handle interrupts addressed to us */ + if (!(status & I2C_BIT_COI0)) + return false; + + /* Enable stop interrupts */ + em_clear_set_bit(priv, 0, I2C_BIT_SPIE0, I2C_OFS_IICC0); + + /* Transmission or Reception */ + if (status & I2C_BIT_TRC0) { + if (status & I2C_BIT_ACKD0) { + /* 9 bit interrupt mode */ + em_clear_set_bit(priv, 0, I2C_BIT_WTIM0, I2C_OFS_IICC0); + + /* Send data */ + event = status & I2C_BIT_STD0 ? + I2C_SLAVE_READ_REQUESTED : + I2C_SLAVE_READ_PROCESSED; + i2c_slave_event(priv->slave, event, &value); + writeb(value, priv->base + I2C_OFS_IIC0); + } else { + /* NACK, stop transmitting */ + em_clear_set_bit(priv, 0, I2C_BIT_LREL0, I2C_OFS_IICC0); + } + } else { + /* 8 bit interrupt mode */ + em_clear_set_bit(priv, I2C_BIT_WTIM0, I2C_BIT_ACKE0, + I2C_OFS_IICC0); + em_clear_set_bit(priv, I2C_BIT_WTIM0, I2C_BIT_WREL0, + I2C_OFS_IICC0); + + if (status & I2C_BIT_STD0) { + i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_REQUESTED, + &value); + } else { + /* Recv data */ + value = readb(priv->base + I2C_OFS_IIC0); + ret = i2c_slave_event(priv->slave, + I2C_SLAVE_WRITE_RECEIVED, &value); + if (ret < 0) + em_clear_set_bit(priv, I2C_BIT_ACKE0, 0, + I2C_OFS_IICC0); + } + } + + return true; +} + static irqreturn_t em_i2c_irq_handler(int this_irq, void *dev_id) { struct em_i2c_device *priv = dev_id; + if (em_i2c_slave_irq(priv)) + return IRQ_HANDLED; + complete(&priv->msg_done); + return IRQ_HANDLED; } static u32 em_i2c_func(struct i2c_adapter *adap) { - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SLAVE; +} + +static int em_i2c_reg_slave(struct i2c_client *slave) +{ + struct em_i2c_device *priv = i2c_get_adapdata(slave->adapter); + + if (priv->slave) + return -EBUSY; + + if (slave->flags & I2C_CLIENT_TEN) + return -EAFNOSUPPORT; + + priv->slave = slave; + + /* Set slave address */ + writeb(slave->addr << 1, priv->base + I2C_OFS_SVA0); + + return 0; +} + +static int em_i2c_unreg_slave(struct i2c_client *slave) +{ + struct em_i2c_device *priv = i2c_get_adapdata(slave->adapter); + + WARN_ON(!priv->slave); + + writeb(0, priv->base + I2C_OFS_SVA0); + + priv->slave = NULL; + + return 0; } static struct i2c_algorithm em_i2c_algo = { .master_xfer = em_i2c_xfer, .functionality = em_i2c_func, + .reg_slave = em_i2c_reg_slave, + .unreg_slave = em_i2c_unreg_slave, }; static int em_i2c_probe(struct platform_device *pdev) -- GitLab From e47b33c0765400d38ebaf57908f00abab2488f74 Mon Sep 17 00:00:00 2001 From: Anton Bondarenko Date: Sat, 5 Dec 2015 17:56:59 +0100 Subject: [PATCH 0994/2855] spi: imx: terminate RX DMA transaction in case of TX DMA timeout Not only TX DMA should be terminated, but RX DMA also. It's required to avoid accidential DMA memory writes from RX DMA channel and properly terminate transaction. Signed-off-by: Anton Bondarenko Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index e7e4f0c0f14d8..d6dc665428116 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -968,6 +968,7 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, dev_driver_string(&master->dev), dev_name(&master->dev)); dmaengine_terminate_all(master->dma_tx); + dmaengine_terminate_all(master->dma_rx); } else { timeout = wait_for_completion_timeout( &spi_imx->dma_rx_completion, IMX_DMA_TIMEOUT); -- GitLab From fab44ef1adcc585440c07c90539e2b9e2cded4bf Mon Sep 17 00:00:00 2001 From: Anton Bondarenko Date: Sat, 5 Dec 2015 17:57:00 +0100 Subject: [PATCH 0995/2855] spi: imx: reorder HW operations enable order to avoid possible RX data loss The overflow may happen due to rescheduling for another task and/or interrupt if we enable SPI HW before starting RX DMA. So RX DMA enabled first to make sure data would be read out from FIFO ASAP. TX DMA enabled next to start filling TX FIFO with new data. And finaly SPI HW enabled to start actual data transfer. The risk rise in case of heavy system load and high SPI clock. Signed-off-by: Anton Bondarenko Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index d6dc665428116..e6b1c74ade6bc 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -956,10 +956,18 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, if (left) writel(dma | (left << MX51_ECSPI_DMA_RXT_WML_OFFSET), spi_imx->base + MX51_ECSPI_DMA); + /* + * Set these order to avoid potential RX overflow. The overflow may + * happen if we enable SPI HW before starting RX DMA due to rescheduling + * for another task and/or interrupt. + * So RX DMA enabled first to make sure data would be read out from FIFO + * ASAP. TX DMA enabled next to start filling TX FIFO with new data. + * And finaly SPI HW enabled to start actual data transfer. + */ + dma_async_issue_pending(master->dma_rx); + dma_async_issue_pending(master->dma_tx); spi_imx->devtype_data->trigger(spi_imx); - dma_async_issue_pending(master->dma_tx); - dma_async_issue_pending(master->dma_rx); /* Wait SDMA to finish the data transfer.*/ timeout = wait_for_completion_timeout(&spi_imx->dma_tx_completion, IMX_DMA_TIMEOUT); -- GitLab From 0dfbaa8932a6c4ffd83a6459f247bf06b4652543 Mon Sep 17 00:00:00 2001 From: Anton Bondarenko Date: Sat, 5 Dec 2015 17:57:01 +0100 Subject: [PATCH 0996/2855] spi: imx: replace multiple watermarks with single for RX, TX and RXT There is no need to have different watermarks levels since they are the same. Merge them into one WML parameter. Signed-off-by: Anton Bondarenko Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index e6b1c74ade6bc..beba40b08ed1a 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -104,9 +104,7 @@ struct spi_imx_data { unsigned int dma_is_inited; unsigned int dma_finished; bool usedma; - u32 rx_wml; - u32 tx_wml; - u32 rxt_wml; + u32 wml; struct completion dma_rx_completion; struct completion dma_tx_completion; @@ -201,9 +199,8 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, { struct spi_imx_data *spi_imx = spi_master_get_devdata(master); - if (spi_imx->dma_is_inited - && transfer->len > spi_imx->rx_wml * sizeof(u32) - && transfer->len > spi_imx->tx_wml * sizeof(u32)) + if (spi_imx->dma_is_inited && + transfer->len > spi_imx->wml * sizeof(u32)) return true; return false; } @@ -388,10 +385,9 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, if (spi_imx->dma_is_inited) { dma = readl(spi_imx->base + MX51_ECSPI_DMA); - spi_imx->rxt_wml = spi_imx_get_fifosize(spi_imx) / 2; - rx_wml_cfg = spi_imx->rx_wml << MX51_ECSPI_DMA_RX_WML_OFFSET; - tx_wml_cfg = spi_imx->tx_wml << MX51_ECSPI_DMA_TX_WML_OFFSET; - rxt_wml_cfg = spi_imx->rxt_wml << MX51_ECSPI_DMA_RXT_WML_OFFSET; + rx_wml_cfg = spi_imx->wml << MX51_ECSPI_DMA_RX_WML_OFFSET; + tx_wml_cfg = spi_imx->wml << MX51_ECSPI_DMA_TX_WML_OFFSET; + rxt_wml_cfg = spi_imx->wml << MX51_ECSPI_DMA_RXT_WML_OFFSET; dma = (dma & ~MX51_ECSPI_DMA_TX_WML_MASK & ~MX51_ECSPI_DMA_RX_WML_MASK & ~MX51_ECSPI_DMA_RXT_WML_MASK) @@ -842,6 +838,8 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, if (of_machine_is_compatible("fsl,imx6dl")) return 0; + spi_imx->wml = spi_imx_get_fifosize(spi_imx) / 2; + /* Prepare for TX DMA: */ master->dma_tx = dma_request_slave_channel(dev, "tx"); if (!master->dma_tx) { @@ -853,7 +851,7 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, slave_config.direction = DMA_MEM_TO_DEV; slave_config.dst_addr = res->start + MXC_CSPITXDATA; slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; - slave_config.dst_maxburst = spi_imx_get_fifosize(spi_imx) / 2; + slave_config.dst_maxburst = spi_imx->wml; ret = dmaengine_slave_config(master->dma_tx, &slave_config); if (ret) { dev_err(dev, "error in TX dma configuration.\n"); @@ -871,7 +869,7 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, slave_config.direction = DMA_DEV_TO_MEM; slave_config.src_addr = res->start + MXC_CSPIRXDATA; slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; - slave_config.src_maxburst = spi_imx_get_fifosize(spi_imx) / 2; + slave_config.src_maxburst = spi_imx->wml; ret = dmaengine_slave_config(master->dma_rx, &slave_config); if (ret) { dev_err(dev, "error in RX dma configuration.\n"); @@ -884,8 +882,6 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, master->max_dma_len = MAX_SDMA_BD_BYTES; spi_imx->bitbang.master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX; - spi_imx->tx_wml = spi_imx_get_fifosize(spi_imx) / 2; - spi_imx->rx_wml = spi_imx_get_fifosize(spi_imx) / 2; spi_imx->dma_is_inited = 1; return 0; @@ -952,7 +948,7 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, dma = readl(spi_imx->base + MX51_ECSPI_DMA); dma = dma & (~MX51_ECSPI_DMA_RXT_WML_MASK); /* Change RX_DMA_LENGTH trigger dma fetch tail data */ - left = transfer->len % spi_imx->rxt_wml; + left = transfer->len % spi_imx->wml; if (left) writel(dma | (left << MX51_ECSPI_DMA_RXT_WML_OFFSET), spi_imx->base + MX51_ECSPI_DMA); @@ -987,8 +983,9 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, spi_imx->devtype_data->reset(spi_imx); dmaengine_terminate_all(master->dma_rx); } + dma &= ~MX51_ECSPI_DMA_RXT_WML_MASK; writel(dma | - spi_imx->rxt_wml << MX51_ECSPI_DMA_RXT_WML_OFFSET, + spi_imx->wml << MX51_ECSPI_DMA_RXT_WML_OFFSET, spi_imx->base + MX51_ECSPI_DMA); } -- GitLab From f8a876176f38e00aab200d308506ca4a4ba57b39 Mon Sep 17 00:00:00 2001 From: Anton Bondarenko Date: Sat, 5 Dec 2015 17:57:02 +0100 Subject: [PATCH 0997/2855] spi: imx: add function to check for IMX51 family controller Similar to other controller type checks add check function for IMX51. It includes IMX53 and IMX6. Signed-off-by: Anton Bondarenko Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index beba40b08ed1a..410522fdd4c91 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -122,9 +122,14 @@ static inline int is_imx35_cspi(struct spi_imx_data *d) return d->devtype_data->devtype == IMX35_CSPI; } +static inline int is_imx51_ecspi(struct spi_imx_data *d) +{ + return d->devtype_data->devtype == IMX51_ECSPI; +} + static inline unsigned spi_imx_get_fifosize(struct spi_imx_data *d) { - return (d->devtype_data->devtype == IMX51_ECSPI) ? 64 : 8; + return is_imx51_ecspi(d) ? 64 : 8; } #define MXC_SPI_BUF_RX(type) \ @@ -1210,8 +1215,8 @@ static int spi_imx_probe(struct platform_device *pdev) * Only validated on i.mx6 now, can remove the constrain if validated on * other chips. */ - if (spi_imx->devtype_data == &imx51_ecspi_devtype_data - && spi_imx_sdma_init(&pdev->dev, spi_imx, master, res)) + if (is_imx51_ecspi(spi_imx) && + spi_imx_sdma_init(&pdev->dev, spi_imx, master, res)) dev_err(&pdev->dev, "dma setup error,use pio instead\n"); spi_imx->devtype_data->reset(spi_imx); -- GitLab From 46c52c28deb38df19b1284468792fb59e6a6c27b Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Mon, 7 Dec 2015 16:17:34 +0530 Subject: [PATCH 0998/2855] spi: lm70llp: use dev_warn As we have a struct device available it is better to use dev_warn() instead of printk. Signed-off-by: Sudip Mukherjee Signed-off-by: Mark Brown --- drivers/spi/spi-lm70llp.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-lm70llp.c b/drivers/spi/spi-lm70llp.c index ef829081abd7c..cb2284475385a 100644 --- a/drivers/spi/spi-lm70llp.c +++ b/drivers/spi/spi-lm70llp.c @@ -249,9 +249,8 @@ static void spi_lm70llp_attach(struct parport *p) */ status = spi_bitbang_start(&pp->bitbang); if (status < 0) { - printk(KERN_WARNING - "%s: spi_bitbang_start failed with status %d\n", - DRVNAME, status); + dev_warn(&pd->dev, "spi_bitbang_start failed with status %d\n", + status); goto out_off_and_release; } @@ -278,7 +277,7 @@ static void spi_lm70llp_attach(struct parport *p) dev_dbg(&pp->spidev_lm70->dev, "spidev_lm70 at %s\n", dev_name(&pp->spidev_lm70->dev)); else { - printk(KERN_WARNING "%s: spi_new_device failed\n", DRVNAME); + dev_warn(&pd->dev, "spi_new_device failed\n"); status = -ENODEV; goto out_bitbang_stop; } -- GitLab From 22de54a9b929e7c11e445c8f329d33aa7b154495 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Mon, 7 Dec 2015 16:17:35 +0530 Subject: [PATCH 0999/2855] spi: lm70llp: remove printk Using pr_* macros are more prefferable than using printk. Start using pr_* family of macros and define pr_fmt to be used with it. While at it remove DRVNAME from an existing pr_info() as the name is now being printed by pr_fmt. Signed-off-by: Sudip Mukherjee Signed-off-by: Mark Brown --- drivers/spi/spi-lm70llp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-lm70llp.c b/drivers/spi/spi-lm70llp.c index cb2284475385a..61ee0f4269ae6 100644 --- a/drivers/spi/spi-lm70llp.c +++ b/drivers/spi/spi-lm70llp.c @@ -14,6 +14,8 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -200,9 +202,7 @@ static void spi_lm70llp_attach(struct parport *p) struct pardev_cb lm70llp_cb; if (lm70llp) { - printk(KERN_WARNING - "%s: spi_lm70llp instance already loaded. Aborting.\n", - DRVNAME); + pr_warn("spi_lm70llp instance already loaded. Aborting.\n"); return; } @@ -298,7 +298,7 @@ out_parport_unreg: out_free_master: spi_master_put(master); out_fail: - pr_info("%s: spi_lm70llp probe fail, status %d\n", DRVNAME, status); + pr_info("spi_lm70llp probe fail, status %d\n", status); } static void spi_lm70llp_detach(struct parport *p) -- GitLab From 23211c1e7ad7693e0f518383890308f42f3cc10d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 3 Dec 2015 07:57:35 +0100 Subject: [PATCH 1000/2855] scsi_dh_alua: Remove stale variables With commit 83ea0e5e3501 ("scsi_dh_alua: use scsi_vpd_tpg_id()") these variables became obsolete, but weren't removed. [mkp: Fixed checkpatch warning] Signed-off-by: Hannes Reinecke Reviewed-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/device_handler/scsi_dh_alua.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index f100cbb7d2e19..5a328bf818367 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -320,8 +320,6 @@ static int alua_check_tpgs(struct scsi_device *sdev) */ static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h) { - unsigned char *d; - unsigned char __rcu *vpd_pg83; int rel_port = -1, group_id; group_id = scsi_vpd_tpg_id(sdev, &rel_port); -- GitLab From c993e09504fca192bac4ac3f5a3411ac68cba2e6 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Tue, 1 Dec 2015 12:02:58 +0100 Subject: [PATCH 1001/2855] ARM: nand: make use of mtd_to_nand() where appropriate mtd_to_nand() was recently introduced to avoid direct accesses to the mtd->priv field. Update all ARM specific implementations to use this helper. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- arch/arm/mach-ep93xx/snappercl15.c | 4 ++-- arch/arm/mach-ep93xx/ts72xx.c | 4 ++-- arch/arm/mach-imx/mach-qong.c | 2 +- arch/arm/mach-ixp4xx/ixdp425-setup.c | 2 +- arch/arm/mach-omap1/board-nand.c | 2 +- arch/arm/mach-orion5x/ts78xx-setup.c | 6 +++--- arch/arm/mach-pxa/balloon3.c | 2 +- arch/arm/mach-pxa/em-x270.c | 2 +- arch/arm/mach-pxa/palmtx.c | 2 +- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c index c4904264256ad..b2db791b3b38b 100644 --- a/arch/arm/mach-ep93xx/snappercl15.c +++ b/arch/arm/mach-ep93xx/snappercl15.c @@ -49,7 +49,7 @@ static void snappercl15_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); static u16 nand_state = SNAPPERCL15_NAND_WPN; u16 set; @@ -76,7 +76,7 @@ static void snappercl15_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, static int snappercl15_nand_dev_ready(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); return !!(__raw_readw(NAND_CTRL_ADDR(chip)) & SNAPPERCL15_NAND_RDY); } diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index 61f4b5dc4d7dd..45b81a2bcd4b3 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c @@ -74,7 +74,7 @@ static void __init ts72xx_map_io(void) static void ts72xx_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); if (ctrl & NAND_CTRL_CHANGE) { void __iomem *addr = chip->IO_ADDR_R; @@ -96,7 +96,7 @@ static void ts72xx_nand_hwcontrol(struct mtd_info *mtd, static int ts72xx_nand_device_ready(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); void __iomem *addr = chip->IO_ADDR_R; addr += (1 << TS72XX_NAND_BUSY_ADDR_LINE); diff --git a/arch/arm/mach-imx/mach-qong.c b/arch/arm/mach-imx/mach-qong.c index a213e7b9cb1c9..5c27646047270 100644 --- a/arch/arm/mach-imx/mach-qong.c +++ b/arch/arm/mach-imx/mach-qong.c @@ -131,7 +131,7 @@ static void qong_init_nor_mtd(void) */ static void qong_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); if (cmd == NAND_CMD_NONE) return; diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index e7b8befa87295..333b0f9ea635e 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -76,7 +76,7 @@ static struct mtd_partition ixdp425_partitions[] = { static void ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); int offset = (int)this->priv; if (ctrl & NAND_CTRL_CHANGE) { diff --git a/arch/arm/mach-omap1/board-nand.c b/arch/arm/mach-omap1/board-nand.c index 4d0835327d203..7684f92034743 100644 --- a/arch/arm/mach-omap1/board-nand.c +++ b/arch/arm/mach-omap1/board-nand.c @@ -22,7 +22,7 @@ void omap1_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); unsigned long mask; if (cmd == NAND_CMD_NONE) diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c index 1b704d35cf5b2..96cf6b51eddc7 100644 --- a/arch/arm/mach-orion5x/ts78xx-setup.c +++ b/arch/arm/mach-orion5x/ts78xx-setup.c @@ -176,7 +176,7 @@ static void ts78xx_ts_rtc_unload(void) static void ts78xx_ts_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); if (ctrl & NAND_CTRL_CHANGE) { unsigned char bits; @@ -200,7 +200,7 @@ static int ts78xx_ts_nand_dev_ready(struct mtd_info *mtd) static void ts78xx_ts_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); void __iomem *io_base = chip->IO_ADDR_W; unsigned long off = ((unsigned long)buf & 3); int sz; @@ -227,7 +227,7 @@ static void ts78xx_ts_nand_write_buf(struct mtd_info *mtd, static void ts78xx_ts_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); void __iomem *io_base = chip->IO_ADDR_R; unsigned long off = ((unsigned long)buf & 3); int sz; diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c index a727282bfa996..7734ec4f13850 100644 --- a/arch/arm/mach-pxa/balloon3.c +++ b/arch/arm/mach-pxa/balloon3.c @@ -572,7 +572,7 @@ static inline void balloon3_i2c_init(void) {} #if defined(CONFIG_MTD_NAND_PLATFORM)||defined(CONFIG_MTD_NAND_PLATFORM_MODULE) static void balloon3_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); uint8_t balloon3_ctl_set = 0, balloon3_ctl_clr = 0; if (ctrl & NAND_CTRL_CHANGE) { diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index 9d7072b040458..38600a70e3cab 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -289,7 +289,7 @@ static void nand_cs_off(void) static void em_x270_nand_cmd_ctl(struct mtd_info *mtd, int dat, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); unsigned long nandaddr = (unsigned long)this->IO_ADDR_W; dsb(); diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index 83f830dd8ad89..d787dd17f6b2a 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c @@ -250,7 +250,7 @@ static inline void palmtx_keys_init(void) {} static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); char __iomem *nandaddr = this->IO_ADDR_W; if (cmd == NAND_CMD_NONE) -- GitLab From f96576bd63e5b9a7a9c33a7fc4209fffc4d433cc Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 7 Dec 2015 12:45:12 +0900 Subject: [PATCH 1002/2855] power: Fix unmet dependency on POWER_SUPPLY by POWER_RESET by uncoupling them Currently the reset/power off handlers (POWER_RESET) and Adaptive Voltage Scaling class (POWER_AVS) are not built when POWER_SUPPLY is disabled. The POWER_RESET is also not visible in drivers main section of config. However they do not really depend on power supply so they can be built always. The objects for power supply drivers already depend on particular Kconfig symbols so there is no need for any changes in drivers/power/Makefile. This allows selecting POWER_RESET from main drivers config section and fixes following build warning (encountered on ARM exynos defconfig when POWER_SUPPLY is disabled manually): warning: (ARCH_HISI && ARCH_INTEGRATOR && ARCH_EXYNOS && ARCH_VEXPRESS && REALVIEW_DT) selects POWER_RESET which has unmet direct dependencies (POWER_SUPPLY) warning: (ARCH_EXYNOS) selects POWER_RESET_SYSCON which has unmet direct dependencies (POWER_SUPPLY && POWER_RESET && OF) warning: (ARCH_EXYNOS) selects POWER_RESET_SYSCON_POWEROFF which has unmet direct dependencies (POWER_SUPPLY && POWER_RESET && OF) Reported-by: Pavel Fedin Signed-off-by: Krzysztof Kozlowski Signed-off-by: Sebastian Reichel --- drivers/Makefile | 2 +- drivers/power/Kconfig | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/Makefile b/drivers/Makefile index 795d0ca714bfe..8f5d076baeb0e 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -106,7 +106,7 @@ obj-y += i2c/ media/ obj-$(CONFIG_PPS) += pps/ obj-$(CONFIG_PTP_1588_CLOCK) += ptp/ obj-$(CONFIG_W1) += w1/ -obj-$(CONFIG_POWER_SUPPLY) += power/ +obj-y += power/ obj-$(CONFIG_HWMON) += hwmon/ obj-$(CONFIG_THERMAL) += thermal/ obj-$(CONFIG_WATCHDOG) += watchdog/ diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 42a5b51c3d2ec..1ddd13cc0c07e 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -502,8 +502,7 @@ config AXP20X_POWER This driver provides support for the power supply features of AXP20x PMIC. -source "drivers/power/reset/Kconfig" - endif # POWER_SUPPLY +source "drivers/power/reset/Kconfig" source "drivers/power/avs/Kconfig" -- GitLab From 7f7e92f7553c663fc1c53f999b0bf88e2d1f30a7 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 4 Sep 2015 12:45:05 +0200 Subject: [PATCH 1003/2855] lib: scatterlist: fix Kconfig description Spelling s/heler/helper/, grammar s/channel/channels/ Signed-off-by: Geert Uytterhoeven Signed-off-by: Jiri Kosina --- lib/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Kconfig b/lib/Kconfig index f0df318104e72..5a0c1c83cdf0a 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -512,9 +512,9 @@ source "lib/fonts/Kconfig" config SG_SPLIT def_bool n help - Provides a heler to split scatterlists into chunks, each chunk being a - scatterlist. This should be selected by a driver or an API which - whishes to split a scatterlist amongst multiple DMA channel. + Provides a helper to split scatterlists into chunks, each chunk being + a scatterlist. This should be selected by a driver or an API which + whishes to split a scatterlist amongst multiple DMA channels. # # sg chaining option -- GitLab From d83e2a4ea2296620e8f6cb724e60190826c43a3f Mon Sep 17 00:00:00 2001 From: Chris Dunlop Date: Fri, 18 Sep 2015 16:10:55 +1000 Subject: [PATCH 1004/2855] Documentation: fix sysfs-ptp s/avaiable/available/g This fixup is already in scripts/spelling.txt. The fix in Documentation/ABI/testing/sysfs-ptp affects documentation of a /sys entry: the /sys entry itself is correct. Signed-off-by: Chris Dunlop Signed-off-by: Jiri Kosina --- Documentation/ABI/testing/sysfs-ptp | 2 +- Documentation/sysctl/vm.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-ptp b/Documentation/ABI/testing/sysfs-ptp index 44806a678f12a..a17f817a93095 100644 --- a/Documentation/ABI/testing/sysfs-ptp +++ b/Documentation/ABI/testing/sysfs-ptp @@ -74,7 +74,7 @@ Description: assignment may be changed by two writing numbers into the file. -What: /sys/class/ptp/ptpN/pps_avaiable +What: /sys/class/ptp/ptpN/pps_available Date: September 2010 Contact: Richard Cochran Description: diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index a4482fceacecc..8e4025e6b44f0 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -135,7 +135,7 @@ Contains, as a percentage of total available memory that contains free pages and reclaimable pages, the number of pages at which the background kernel flusher threads will start writing out dirty data. -The total avaiable memory is not equal to total system memory. +The total available memory is not equal to total system memory. ============================================================== @@ -170,7 +170,7 @@ Contains, as a percentage of total available memory that contains free pages and reclaimable pages, the number of pages at which a process which is generating disk writes will itself start writing out dirty data. -The total avaiable memory is not equal to total system memory. +The total available memory is not equal to total system memory. ============================================================== -- GitLab From 22224a17587c90e25371e7d07c079548359b2039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Stehl=C3=A9?= Date: Mon, 21 Sep 2015 17:18:34 +0200 Subject: [PATCH 1005/2855] fs/super.c: use && instead of & for warn_on condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the following sparse warning: fs/super.c:1202:9: warning: dubious: x & !y Bitwise and logical and are equivalent here, but logical was intended. The generated code is identical, with and without CONFIG_LOCKDEP. Signed-off-by: Vincent Stehlé Acked-by: Oleg Nesterov Signed-off-by: Jiri Kosina --- fs/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/super.c b/fs/super.c index 954aeb80e202b..7ea56de57d4b8 100644 --- a/fs/super.c +++ b/fs/super.c @@ -1199,7 +1199,7 @@ int __sb_start_write(struct super_block *sb, int level, bool wait) else ret = percpu_down_read_trylock(sb->s_writers.rw_sem + level-1); - WARN_ON(force_trylock & !ret); + WARN_ON(force_trylock && !ret); return ret; } EXPORT_SYMBOL(__sb_start_write); -- GitLab From 20d5a865e1f1d98e8520c12fc647c9d4e47f46b3 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 22 Sep 2015 12:04:17 +0900 Subject: [PATCH 1006/2855] Documentation: filesystem: Fix typo in fs/eventfd.c This patch fix typos found in Documentation/filesystems.xml, DocBook/filesystems/API-eventfd-signal.html, and DocBook/filesystems.aux.xml These files are generated from comments within the source, so I had to fix typos in fs/eventfd.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- fs/eventfd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/eventfd.c b/fs/eventfd.c index 8d0c0df018549..ed70cf9fdc7b3 100644 --- a/fs/eventfd.c +++ b/fs/eventfd.c @@ -45,10 +45,10 @@ struct eventfd_ctx { * * This function is supposed to be called by the kernel in paths that do not * allow sleeping. In this function we allow the counter to reach the ULLONG_MAX - * value, and we signal this as overflow condition by returining a POLLERR + * value, and we signal this as overflow condition by returning a POLLERR * to poll(2). * - * Returns the amount by which the counter was incrememnted. This will be less + * Returns the amount by which the counter was incremented. This will be less * than @n if the counter has overflowed. */ __u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n) -- GitLab From e3d132d1239ae846e2f7c652fbdc5aa7ebcc4541 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 16 Oct 2015 21:14:29 +0900 Subject: [PATCH 1007/2855] treewide: Fix typos in printk This patch fix multiple spelling typos found in various part of kernel. Signed-off-by: Masanari Iida Acked-by: Randy Dunlap Signed-off-by: Jiri Kosina --- drivers/firmware/efi/libstub/fdt.c | 2 +- drivers/infiniband/hw/cxgb4/cm.c | 2 +- drivers/md/raid0.c | 4 ++-- drivers/media/common/saa7146/saa7146_video.c | 2 +- drivers/media/dvb-frontends/m88ds3103.c | 2 +- drivers/media/dvb-frontends/si2165.c | 4 ++-- drivers/media/pci/netup_unidvb/netup_unidvb_core.c | 2 +- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 2 +- drivers/soc/ti/knav_dma.c | 2 +- sound/drivers/pcm-indirect2.c | 2 +- sound/usb/6fire/firmware.c | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c index b62e2f5dcab3b..cf7b7d46302a2 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c @@ -253,7 +253,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table, sys_table->boottime->free_pool(memory_map); new_fdt_size += EFI_PAGE_SIZE; } else { - pr_efi_err(sys_table, "Unable to constuct new device tree.\n"); + pr_efi_err(sys_table, "Unable to construct new device tree.\n"); goto fail_free_mmap; } } diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index debc39d2cbc2a..9a389a0aa1749 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -449,7 +449,7 @@ static void act_open_req_arp_failure(void *handle, struct sk_buff *skb) { struct c4iw_ep *ep = handle; - printk(KERN_ERR MOD "ARP failure duing connect\n"); + printk(KERN_ERR MOD "ARP failure during connect\n"); kfree_skb(skb); connect_reply_upcall(ep, -EHOSTUNREACH); state_set(&ep->com, DEAD); diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index f8e5db0cb5aaa..2ea12c6bf6599 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -549,13 +549,13 @@ static void *raid0_takeover_raid10(struct mddev *mddev) * - all mirrors must be already degraded */ if (mddev->layout != ((1 << 8) + 2)) { - printk(KERN_ERR "md/raid0:%s:: Raid0 cannot takover layout: 0x%x\n", + printk(KERN_ERR "md/raid0:%s:: Raid0 cannot takeover layout: 0x%x\n", mdname(mddev), mddev->layout); return ERR_PTR(-EINVAL); } if (mddev->raid_disks & 1) { - printk(KERN_ERR "md/raid0:%s: Raid0 cannot takover Raid10 with odd disk number.\n", + printk(KERN_ERR "md/raid0:%s: Raid0 cannot takeover Raid10 with odd disk number.\n", mdname(mddev)); return ERR_PTR(-EINVAL); } diff --git a/drivers/media/common/saa7146/saa7146_video.c b/drivers/media/common/saa7146/saa7146_video.c index 30779498c173f..079f520ceef31 100644 --- a/drivers/media/common/saa7146/saa7146_video.c +++ b/drivers/media/common/saa7146/saa7146_video.c @@ -502,7 +502,7 @@ static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuf /* check if overlay is running */ if (IS_OVERLAY_ACTIVE(fh) != 0) { if (vv->video_fh != fh) { - DEB_D("refusing to change framebuffer informations while overlay is active in another open\n"); + DEB_D("refusing to change framebuffer information while overlay is active in another open\n"); return -EBUSY; } } diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index feeeb70d841ed..ce73a5ec6036b 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -685,7 +685,7 @@ static int m88ds3103_init(struct dvb_frontend *fe) /* request the firmware, this will block and timeout */ ret = request_firmware(&fw, fw_file, &client->dev); if (ret) { - dev_err(&client->dev, "firmare file '%s' not found\n", fw_file); + dev_err(&client->dev, "firmware file '%s' not found\n", fw_file); goto err; } diff --git a/drivers/media/dvb-frontends/si2165.c b/drivers/media/dvb-frontends/si2165.c index 7c2eeee697577..1fcd9252a09ab 100644 --- a/drivers/media/dvb-frontends/si2165.c +++ b/drivers/media/dvb-frontends/si2165.c @@ -511,7 +511,7 @@ static int si2165_upload_firmware(struct si2165_state *state) &offset, block_count); if (ret < 0) { dev_err(&state->i2c->dev, - "%s: firmare could not be uploaded\n", + "%s: firmware could not be uploaded\n", KBUILD_MODNAME); goto error; } @@ -535,7 +535,7 @@ static int si2165_upload_firmware(struct si2165_state *state) if (len != offset) { dev_err(&state->i2c->dev, - "%s: firmare len mismatch %04x != %04x\n", + "%s: firmware len mismatch %04x != %04x\n", KBUILD_MODNAME, len, offset); ret = -EINVAL; goto error; diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c index 83c90d3462e9b..487129b942927 100644 --- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c +++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c @@ -388,7 +388,7 @@ static int netup_unidvb_dvb_init(struct netup_unidvb_dev *ndev, vb2_dvb_alloc_frontend( &ndev->frontends[num], 3) == NULL) { dev_dbg(&ndev->pci_dev->dev, - "%s(): unable to to alllocate vb2_dvb_frontend\n", + "%s(): unable to allocate vb2_dvb_frontend\n", __func__); return -ENOMEM; } diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index d962164dfb0fb..6b84c0d7f1207 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -1229,7 +1229,7 @@ static void i40evf_configure_rss_aq(struct i40e_vsi *vsi, const u8 *seed) if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) { /* bail because we already have a command pending */ - dev_err(&adapter->pdev->dev, "Cannot confiure RSS, command %d pending\n", + dev_err(&adapter->pdev->dev, "Cannot configure RSS, command %d pending\n", adapter->current_op); return; } diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c index bc1b80ec6afe3..1a7b5caa127b5 100644 --- a/drivers/soc/ti/knav_dma.c +++ b/drivers/soc/ti/knav_dma.c @@ -389,7 +389,7 @@ static int of_channel_match_helper(struct device_node *np, const char *name, *dma_instance = dma_node->name; index = of_property_match_string(np, "ti,navigator-dma-names", name); if (index < 0) { - dev_err(kdev->dev, "No 'ti,navigator-dma-names' propery\n"); + dev_err(kdev->dev, "No 'ti,navigator-dma-names' property\n"); return -ENODEV; } diff --git a/sound/drivers/pcm-indirect2.c b/sound/drivers/pcm-indirect2.c index e73fafd761b35..d16bc14a0f0e7 100644 --- a/sound/drivers/pcm-indirect2.c +++ b/sound/drivers/pcm-indirect2.c @@ -47,7 +47,7 @@ void snd_pcm_indirect2_stat(struct snd_pcm_substream *substream, int seconds = (rec->lastbytetime - rec->firstbytetime) / HZ; snd_printk(KERN_DEBUG "STAT: mul_elapsed: %u, mul_elapsed_real: %d, " - "irq_occured: %d\n", + "irq_occurred: %d\n", rec->mul_elapsed, rec->mul_elapsed_real, rec->irq_occured); snd_printk(KERN_DEBUG "STAT: min_multiple: %d (irqs/period)\n", rec->min_multiple); diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c index 62c25e74f0e52..9520b4cd70385 100644 --- a/sound/usb/6fire/firmware.c +++ b/sound/usb/6fire/firmware.c @@ -350,7 +350,7 @@ static int usb6fire_fw_check(struct usb_interface *intf, const u8 *version) if (!memcmp(version, known_fw_versions + i, 2)) return 0; - dev_err(&intf->dev, "invalid fimware version in device: %4ph. " + dev_err(&intf->dev, "invalid firmware version in device: %4ph. " "please reconnect to power. if this failure " "still happens, check your firmware installation.", version); -- GitLab From 14d74598bcfaa93ed3dd429060eca2f5a2295713 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2015 12:42:49 +0100 Subject: [PATCH 1008/2855] cpufreq: ARM big LITTLE: correct dead link in documentation commit 3566c5b277a4 ("PM / OPP: Create a directory for opp bindings") renamed the file: Documentation/devicetree/bindings/power/opp.txt to Documentation/devicetree/bindings/opp/opp.txt leaving a dead link in cpufreq/arm_big_little_dt.txt. The link points now to the good file. Signed-off-by: Richard Genoud Signed-off-by: Jiri Kosina --- Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt b/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt index 0715695e94a98..2aa06ac0fac59 100644 --- a/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt +++ b/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt @@ -12,7 +12,7 @@ must be present contiguously. Generic DT driver will check only node 'x' for cpu:x. Required properties: -- operating-points: Refer to Documentation/devicetree/bindings/power/opp.txt +- operating-points: Refer to Documentation/devicetree/bindings/opp/opp.txt for details Optional properties: -- GitLab From 925f709fb381e21b08445f5da0797e198aac1460 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2015 13:09:23 +0100 Subject: [PATCH 1009/2855] cpufreq-dt: correct dead link in documentation commit 3566c5b277a4 ("PM / OPP: Create a directory for opp bindings") renamed the file: Documentation/devicetree/bindings/power/opp.txt to Documentation/devicetree/bindings/opp/opp.txt leaving a dead link in cpufreq/arm_big_little_dt.txt. The link points now to the good file. Signed-off-by: Richard Genoud Signed-off-by: Jiri Kosina --- Documentation/devicetree/bindings/cpufreq/cpufreq-dt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-dt.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-dt.txt index e41c98ffbccb2..dd3929e85decc 100644 --- a/Documentation/devicetree/bindings/cpufreq/cpufreq-dt.txt +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-dt.txt @@ -11,7 +11,7 @@ Required properties: - None Optional properties: -- operating-points: Refer to Documentation/devicetree/bindings/power/opp.txt for +- operating-points: Refer to Documentation/devicetree/bindings/opp/opp.txt for details. OPPs *must* be supplied either via DT, i.e. this property, or populated at runtime. - clock-latency: Specify the possible maximum transition latency for clock, -- GitLab From 0b4663a1f4a7541d070ddb3da4b606389a02d5c8 Mon Sep 17 00:00:00 2001 From: Ashley Towns Date: Thu, 12 Nov 2015 20:54:17 +1100 Subject: [PATCH 1010/2855] dt-bindings: fixes some incorrect header guards in dt-bindings where the preprocessor #ifndef/#define variables were mismatched. Signed-off-by: Ashley Towns Signed-off-by: Jiri Kosina --- include/dt-bindings/leds/common.h | 2 +- include/dt-bindings/mfd/palmas.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dt-bindings/leds/common.h b/include/dt-bindings/leds/common.h index 79fcef72ef57e..7958bec7de8c1 100644 --- a/include/dt-bindings/leds/common.h +++ b/include/dt-bindings/leds/common.h @@ -6,7 +6,7 @@ * Author: Jacek Anaszewski */ -#ifndef __DT_BINDINGS_LEDS_H__ +#ifndef __DT_BINDINGS_LEDS_H #define __DT_BINDINGS_LEDS_H /* External trigger type */ diff --git a/include/dt-bindings/mfd/palmas.h b/include/dt-bindings/mfd/palmas.h index 2c8ac48413857..cdb075aae4e1a 100644 --- a/include/dt-bindings/mfd/palmas.h +++ b/include/dt-bindings/mfd/palmas.h @@ -7,7 +7,7 @@ * */ -#ifndef __DT_BINDINGS_PALMAS_H__ +#ifndef __DT_BINDINGS_PALMAS_H #define __DT_BINDINGS_PALMAS_H /* External control pins */ -- GitLab From 8e3911178e0d406bc3e84e7dcd8b556edc47b9d7 Mon Sep 17 00:00:00 2001 From: Ashley Towns Date: Thu, 12 Nov 2015 21:03:27 +1100 Subject: [PATCH 1011/2855] exynos: fixes an incorrect header guard in the exynos gpu driver where the preprocessor #ifndef/#define variables were mismatched. Signed-off-by: Ashley Towns Signed-off-by: Jiri Kosina --- drivers/gpu/drm/exynos/exynos_drm_fb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.h b/drivers/gpu/drm/exynos/exynos_drm_fb.h index 85e4445b920e3..6b0f1acff1fc5 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.h +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.h @@ -12,7 +12,7 @@ */ #ifndef _EXYNOS_DRM_FB_H_ -#define _EXYNOS_DRM_FB_H +#define _EXYNOS_DRM_FB_H_ #include "exynos_drm_gem.h" -- GitLab From be853fd1c6a5fe127af3392157dfe95e9712a575 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Fri, 4 Dec 2015 14:45:27 -0800 Subject: [PATCH 1012/2855] HID: wacom: Apply lowres quirk to BAMBOO_TOUCH devices When splitting the touch-only "BAMBOO_TOUCH" type out of the existing "BAMBOO_PT" type in 3b164a00, the lowres quirk was not updated so that it would continue to apply to these devices (effectively only the 0xD0). The absence of this quirk does not significantly impact usability, but is a correctness issue nonetheless. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 3953416ff753b..bec23001c219e 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2421,7 +2421,7 @@ void wacom_setup_device_quirks(struct wacom *wacom) features->quirks |= WACOM_QUIRK_BATTERY; /* quirk for bamboo touch with 2 low res touches */ - if (features->type == BAMBOO_PT && + if ((features->type == BAMBOO_PT || features->type == BAMBOO_TOUCH) && features->pktlen == WACOM_PKGLEN_BBTOUCH) { features->x_max <<= 5; features->y_max <<= 5; -- GitLab From bcf4299e6215a475259c3ac329d43e776cfe9c0c Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 1 Dec 2015 15:54:01 +0100 Subject: [PATCH 1013/2855] floppy: make local variable non-static There's no reason for temparea to be static, since it's only used for temporary sprintf output. It's not immediately obvious that the output will always fit (in the worst case, the output including '\0' is exactly 32 bytes), so save a future reader from worrying about that. Signed-off-by: Rasmus Villemoes Signed-off-by: Jiri Kosina --- drivers/block/floppy.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 331363e7de0f1..9e251201dd48e 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -3585,7 +3585,7 @@ static void __init config_types(void) unsigned int type = UDP->cmos; struct floppy_drive_params *params; const char *name = NULL; - static char temparea[32]; + char temparea[32]; if (type < ARRAY_SIZE(default_drive_params)) { params = &default_drive_params[type].params; @@ -3596,7 +3596,8 @@ static void __init config_types(void) allowed_drive_mask &= ~(1 << drive); } else { params = &default_drive_params[0].params; - sprintf(temparea, "unknown type %d (usb?)", type); + snprintf(temparea, sizeof(temparea), + "unknown type %d (usb?)", type); name = temparea; } if (name) { -- GitLab From edd3899c8cd2a7f11d23686e375359f8ab1f818a Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 4 Dec 2015 10:59:14 -0200 Subject: [PATCH 1014/2855] spi: spidev_test: Fix typo in error message Fix the spelling of 'output' in the error message. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- tools/spi/spidev_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/spi/spidev_test.c b/tools/spi/spidev_test.c index eddfc336a960f..8a73d81853168 100644 --- a/tools/spi/spidev_test.c +++ b/tools/spi/spidev_test.c @@ -150,7 +150,7 @@ static void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len) ret = write(out_fd, rx, len); if (ret != len) - pabort("not all bytes written to utput file"); + pabort("not all bytes written to output file"); close(out_fd); } -- GitLab From c90456e36d9c89de0b6e9c8f21003208e0ad7f13 Mon Sep 17 00:00:00 2001 From: James Ban Date: Tue, 8 Dec 2015 10:57:29 +0900 Subject: [PATCH 1015/2855] regulator: pv88090: new regulator driver This is the driver for the Powerventure PV88090 BUCKs and LDOs regulator. It communicates via an I2C bus to the device. Signed-off-by: James Ban Signed-off-by: Mark Brown --- .../devicetree/bindings/regulator/pv88090.txt | 65 +++ drivers/regulator/Kconfig | 8 + drivers/regulator/Makefile | 1 + drivers/regulator/pv88090-regulator.c | 458 ++++++++++++++++++ drivers/regulator/pv88090-regulator.h | 98 ++++ 5 files changed, 630 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/pv88090.txt create mode 100644 drivers/regulator/pv88090-regulator.c create mode 100644 drivers/regulator/pv88090-regulator.h diff --git a/Documentation/devicetree/bindings/regulator/pv88090.txt b/Documentation/devicetree/bindings/regulator/pv88090.txt new file mode 100644 index 0000000000000..e52b2a95cdde0 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/pv88090.txt @@ -0,0 +1,65 @@ +* Powerventure Semiconductor PV88090 Voltage Regulator + +Required properties: +- compatible: "pvs,pv88090". +- reg: I2C slave address, usually 0x48. +- interrupts: the interrupt outputs of the controller +- regulators: A node that houses a sub-node for each regulator within the + device. Each sub-node is identified using the node's name, with valid + values listed below. The content of each sub-node is defined by the + standard binding for regulators; see regulator.txt. + BUCK1, BUCK2, BUCK3, LDO1, and LDO2. + +Optional properties: +- Any optional property defined in regulator.txt + +Example + + pmic: pv88090@48 { + compatible = "pvs,pv88090"; + reg = <0x48>; + interrupt-parent = <&gpio>; + interrupts = <24 24>; + + regulators { + BUCK1 { + regulator-name = "buck1"; + regulator-min-microvolt = < 600000>; + regulator-max-microvolt = <1393750>; + regulator-min-microamp = < 220000>; + regulator-max-microamp = <7040000>; + regulator-boot-on; + }; + + BUCK2 { + regulator-name = "buck2"; + regulator-min-microvolt = < 600000>; + regulator-max-microvolt = <1393750>; + regulator-min-microamp = <1496000>; + regulator-max-microamp = <4189000>; + }; + + BUCK3 { + regulator-name = "buck3"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1393750>; + regulator-min-microamp = <1496000>; + regulator-max-microamp = <4189000>; + regulator-boot-on; + }; + + LDO1 { + regulator-name = "ldo1"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <4350000>; + regulator-boot-on; + }; + + LDO2 { + regulator-name = "ldo2"; + regulator-min-microvolt = < 650000>; + regulator-max-microvolt = <2225000>; + regulator-boot-on; + }; + }; + }; diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index c61f72ff1dfde..5433c448aff24 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -512,6 +512,14 @@ config REGULATOR_PV88060 Say y here to support the voltage regulators and convertors PV88060 +config REGULATOR_PV88090 + tristate "Powerventure Semiconductor PV88090 regulator" + depends on I2C + select REGMAP_I2C + help + Say y here to support the voltage regulators and convertors + on PV88090 + config REGULATOR_PWM tristate "PWM voltage regulator" depends on PWM diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index b11c8a4f873ad..29cda9d537877 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o obj-$(CONFIG_REGULATOR_PV88060) += pv88060-regulator.o +obj-$(CONFIG_REGULATOR_PV88090) += pv88090-regulator.o obj-$(CONFIG_REGULATOR_PWM) += pwm-regulator.o obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o diff --git a/drivers/regulator/pv88090-regulator.c b/drivers/regulator/pv88090-regulator.c new file mode 100644 index 0000000000000..3ec5f2bdfc51d --- /dev/null +++ b/drivers/regulator/pv88090-regulator.c @@ -0,0 +1,458 @@ +/* + * pv88090-regulator.c - Regulator device driver for PV88090 + * Copyright (C) 2015 Powerventure Semiconductor Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pv88090-regulator.h" + +#define PV88090_MAX_REGULATORS 5 + +/* PV88090 REGULATOR IDs */ +enum { + /* BUCKs */ + PV88090_ID_BUCK1, + PV88090_ID_BUCK2, + PV88090_ID_BUCK3, + + /* LDOs */ + PV88090_ID_LDO1, + PV88090_ID_LDO2, +}; + +struct pv88090_regulator { + struct regulator_desc desc; + /* Current limiting */ + unsigned n_current_limits; + const int *current_limits; + unsigned int limit_mask; + unsigned int conf; + unsigned int conf2; +}; + +struct pv88090 { + struct device *dev; + struct regmap *regmap; + struct regulator_dev *rdev[PV88090_MAX_REGULATORS]; +}; + +struct pv88090_buck_voltage { + int min_uV; + int max_uV; + int uV_step; +}; + +static const struct regmap_config pv88090_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + +/* Current limits array (in uA) for BUCK1, BUCK2, BUCK3. + * Entry indexes corresponds to register values. + */ + +static const int pv88090_buck1_limits[] = { + 220000, 440000, 660000, 880000, 1100000, 1320000, 1540000, 1760000, + 1980000, 2200000, 2420000, 2640000, 2860000, 3080000, 3300000, 3520000, + 3740000, 3960000, 4180000, 4400000, 4620000, 4840000, 5060000, 5280000, + 5500000, 5720000, 5940000, 6160000, 6380000, 6600000, 6820000, 7040000 +}; + +static const int pv88090_buck23_limits[] = { + 1496000, 2393000, 3291000, 4189000 +}; + +static const struct pv88090_buck_voltage pv88090_buck_vol[3] = { + { + .min_uV = 600000, + .max_uV = 1393750, + .uV_step = 6250, + }, + + { + .min_uV = 1400000, + .max_uV = 2193750, + .uV_step = 6250, + }, + { + .min_uV = 1250000, + .max_uV = 2837500, + .uV_step = 12500, + }, +}; + +static unsigned int pv88090_buck_get_mode(struct regulator_dev *rdev) +{ + struct pv88090_regulator *info = rdev_get_drvdata(rdev); + unsigned int data; + int ret, mode = 0; + + ret = regmap_read(rdev->regmap, info->conf, &data); + if (ret < 0) + return ret; + + switch (data & PV88090_BUCK1_MODE_MASK) { + case PV88090_BUCK_MODE_SYNC: + mode = REGULATOR_MODE_FAST; + break; + case PV88090_BUCK_MODE_AUTO: + mode = REGULATOR_MODE_NORMAL; + break; + case PV88090_BUCK_MODE_SLEEP: + mode = REGULATOR_MODE_STANDBY; + break; + } + + return mode; +} + +static int pv88090_buck_set_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + struct pv88090_regulator *info = rdev_get_drvdata(rdev); + int val = 0; + + switch (mode) { + case REGULATOR_MODE_FAST: + val = PV88090_BUCK_MODE_SYNC; + break; + case REGULATOR_MODE_NORMAL: + val = PV88090_BUCK_MODE_AUTO; + break; + case REGULATOR_MODE_STANDBY: + val = PV88090_BUCK_MODE_SLEEP; + break; + default: + return -EINVAL; + } + + return regmap_update_bits(rdev->regmap, info->conf, + PV88090_BUCK1_MODE_MASK, val); +} + +static int pv88090_set_current_limit(struct regulator_dev *rdev, int min, + int max) +{ + struct pv88090_regulator *info = rdev_get_drvdata(rdev); + int i; + + /* search for closest to maximum */ + for (i = info->n_current_limits; i >= 0; i--) { + if (min <= info->current_limits[i] + && max >= info->current_limits[i]) { + return regmap_update_bits(rdev->regmap, + info->conf, + info->limit_mask, + i << PV88090_BUCK1_ILIM_SHIFT); + } + } + + return -EINVAL; +} + +static int pv88090_get_current_limit(struct regulator_dev *rdev) +{ + struct pv88090_regulator *info = rdev_get_drvdata(rdev); + unsigned int data; + int ret; + + ret = regmap_read(rdev->regmap, info->conf, &data); + if (ret < 0) + return ret; + + data = (data & info->limit_mask) >> PV88090_BUCK1_ILIM_SHIFT; + return info->current_limits[data]; +} + +static struct regulator_ops pv88090_buck_ops = { + .get_mode = pv88090_buck_get_mode, + .set_mode = pv88090_buck_set_mode, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, + .set_current_limit = pv88090_set_current_limit, + .get_current_limit = pv88090_get_current_limit, +}; + +static struct regulator_ops pv88090_ldo_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, +}; + +#define PV88090_BUCK(chip, regl_name, min, step, max, limits_array) \ +{\ + .desc = {\ + .id = chip##_ID_##regl_name,\ + .name = __stringify(chip##_##regl_name),\ + .of_match = of_match_ptr(#regl_name),\ + .regulators_node = of_match_ptr("regulators"),\ + .type = REGULATOR_VOLTAGE,\ + .owner = THIS_MODULE,\ + .ops = &pv88090_buck_ops,\ + .min_uV = min, \ + .uV_step = step, \ + .n_voltages = ((max) - (min))/(step) + 1, \ + .enable_reg = PV88090_REG_##regl_name##_CONF0, \ + .enable_mask = PV88090_##regl_name##_EN, \ + .vsel_reg = PV88090_REG_##regl_name##_CONF0, \ + .vsel_mask = PV88090_V##regl_name##_MASK, \ + },\ + .current_limits = limits_array, \ + .n_current_limits = ARRAY_SIZE(limits_array), \ + .limit_mask = PV88090_##regl_name##_ILIM_MASK, \ + .conf = PV88090_REG_##regl_name##_CONF1, \ + .conf2 = PV88090_REG_##regl_name##_CONF2, \ +} + +#define PV88090_LDO(chip, regl_name, min, step, max) \ +{\ + .desc = {\ + .id = chip##_ID_##regl_name,\ + .name = __stringify(chip##_##regl_name),\ + .of_match = of_match_ptr(#regl_name),\ + .regulators_node = of_match_ptr("regulators"),\ + .type = REGULATOR_VOLTAGE,\ + .owner = THIS_MODULE,\ + .ops = &pv88090_ldo_ops,\ + .min_uV = min, \ + .uV_step = step, \ + .n_voltages = ((max) - (min))/(step) + 1, \ + .enable_reg = PV88090_REG_##regl_name##_CONT, \ + .enable_mask = PV88090_##regl_name##_EN, \ + .vsel_reg = PV88090_REG_##regl_name##_CONT, \ + .vsel_mask = PV88090_V##regl_name##_MASK, \ + },\ +} + +static struct pv88090_regulator pv88090_regulator_info[] = { + PV88090_BUCK(PV88090, BUCK1, 600000, 6250, 1393750, + pv88090_buck1_limits), + PV88090_BUCK(PV88090, BUCK2, 600000, 6250, 1393750, + pv88090_buck23_limits), + PV88090_BUCK(PV88090, BUCK3, 600000, 6250, 1393750, + pv88090_buck23_limits), + PV88090_LDO(PV88090, LDO1, 1200000, 50000, 4350000), + PV88090_LDO(PV88090, LDO2, 650000, 25000, 2225000), +}; + +static irqreturn_t pv88090_irq_handler(int irq, void *data) +{ + struct pv88090 *chip = data; + int i, reg_val, err, ret = IRQ_NONE; + + err = regmap_read(chip->regmap, PV88090_REG_EVENT_A, ®_val); + if (err < 0) + goto error_i2c; + + if (reg_val & PV88090_E_VDD_FLT) { + for (i = 0; i < PV88090_MAX_REGULATORS; i++) { + if (chip->rdev[i] != NULL) { + regulator_notifier_call_chain(chip->rdev[i], + REGULATOR_EVENT_UNDER_VOLTAGE, + NULL); + } + } + + err = regmap_update_bits(chip->regmap, PV88090_REG_EVENT_A, + PV88090_E_VDD_FLT, PV88090_E_VDD_FLT); + if (err < 0) + goto error_i2c; + + ret = IRQ_HANDLED; + } + + if (reg_val & PV88090_E_OVER_TEMP) { + for (i = 0; i < PV88090_MAX_REGULATORS; i++) { + if (chip->rdev[i] != NULL) { + regulator_notifier_call_chain(chip->rdev[i], + REGULATOR_EVENT_OVER_TEMP, + NULL); + } + } + + err = regmap_update_bits(chip->regmap, PV88090_REG_EVENT_A, + PV88090_E_OVER_TEMP, PV88090_E_OVER_TEMP); + if (err < 0) + goto error_i2c; + + ret = IRQ_HANDLED; + } + + return ret; + +error_i2c: + dev_err(chip->dev, "I2C error : %d\n", err); + return IRQ_NONE; +} + +/* + * I2C driver interface functions + */ +static int pv88090_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev); + struct pv88090 *chip; + struct regulator_config config = { }; + int error, i, ret = 0; + unsigned int conf2, range, index; + + chip = devm_kzalloc(&i2c->dev, sizeof(struct pv88090), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->dev = &i2c->dev; + chip->regmap = devm_regmap_init_i2c(i2c, &pv88090_regmap_config); + if (IS_ERR(chip->regmap)) { + error = PTR_ERR(chip->regmap); + dev_err(chip->dev, "Failed to allocate register map: %d\n", + error); + return error; + } + + i2c_set_clientdata(i2c, chip); + + if (i2c->irq != 0) { + ret = regmap_write(chip->regmap, PV88090_REG_MASK_A, 0xFF); + if (ret < 0) { + dev_err(chip->dev, + "Failed to mask A reg: %d\n", ret); + return ret; + } + + ret = regmap_write(chip->regmap, PV88090_REG_MASK_B, 0xFF); + if (ret < 0) { + dev_err(chip->dev, + "Failed to mask B reg: %d\n", ret); + return ret; + } + + ret = request_threaded_irq(i2c->irq, NULL, + pv88090_irq_handler, + IRQF_TRIGGER_LOW|IRQF_ONESHOT, + "pv88090", chip); + if (ret != 0) { + dev_err(chip->dev, "Failed to request IRQ: %d\n", + i2c->irq); + return ret; + } + + ret = regmap_update_bits(chip->regmap, PV88090_REG_MASK_A, + PV88090_M_VDD_FLT | PV88090_M_OVER_TEMP, 0); + if (ret < 0) { + dev_err(chip->dev, + "Failed to update mask reg: %d\n", ret); + return ret; + } + + } else { + dev_warn(chip->dev, "No IRQ configured\n"); + } + + config.dev = chip->dev; + config.regmap = chip->regmap; + + for (i = 0; i < PV88090_MAX_REGULATORS; i++) { + if (init_data) + config.init_data = &init_data[i]; + + if (i == PV88090_ID_BUCK2 || i == PV88090_ID_BUCK3) { + ret = regmap_read(chip->regmap, + pv88090_regulator_info[i].conf2, &conf2); + if (ret < 0) + return ret; + + conf2 = ((conf2 >> PV88090_BUCK_VDAC_RANGE_SHIFT) + && PV88090_BUCK_VDAC_RANGE_MASK); + + ret = regmap_read(chip->regmap, + PV88090_REG_BUCK_FOLD_RANGE, &range); + if (ret < 0) + return ret; + + range = ((range + >> (PV88080_BUCK_VRANGE_GAIN_SHIFT + i - 1)) + && PV88080_BUCK_VRANGE_GAIN_MASK); + index = ((range << 1) | conf2); + + pv88090_regulator_info[i].desc.min_uV + = pv88090_buck_vol[index].min_uV; + pv88090_regulator_info[i].desc.uV_step + = pv88090_buck_vol[index].uV_step; + pv88090_regulator_info[i].desc.n_voltages + = ((pv88090_buck_vol[index].max_uV) + - (pv88090_buck_vol[index].min_uV)) + /(pv88090_buck_vol[index].uV_step) + 1; + } + + config.driver_data = (void *)&pv88090_regulator_info[i]; + chip->rdev[i] = devm_regulator_register(chip->dev, + &pv88090_regulator_info[i].desc, &config); + if (IS_ERR(chip->rdev[i])) { + dev_err(chip->dev, + "Failed to register PV88090 regulator\n"); + return PTR_ERR(chip->rdev[i]); + } + } + + return 0; +} + +static const struct i2c_device_id pv88090_i2c_id[] = { + {"pv88090", 0}, + {}, +}; +MODULE_DEVICE_TABLE(i2c, pv88090_i2c_id); + +#ifdef CONFIG_OF +static const struct of_device_id pv88090_dt_ids[] = { + { .compatible = "pvs,pv88090", .data = &pv88090_i2c_id[0] }, + {}, +}; +MODULE_DEVICE_TABLE(of, pv88090_dt_ids); +#endif + +static struct i2c_driver pv88090_regulator_driver = { + .driver = { + .name = "pv88090", + .of_match_table = of_match_ptr(pv88090_dt_ids), + }, + .probe = pv88090_i2c_probe, + .id_table = pv88090_i2c_id, +}; + +module_i2c_driver(pv88090_regulator_driver); + +MODULE_AUTHOR("James Ban "); +MODULE_DESCRIPTION("Regulator device driver for Powerventure PV88090"); +MODULE_LICENSE("GPL"); diff --git a/drivers/regulator/pv88090-regulator.h b/drivers/regulator/pv88090-regulator.h new file mode 100644 index 0000000000000..d7aca8d8266d0 --- /dev/null +++ b/drivers/regulator/pv88090-regulator.h @@ -0,0 +1,98 @@ +/* + * pv88090-regulator.h - Regulator definitions for PV88090 + * Copyright (C) 2015 Powerventure Semiconductor Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __PV88090_REGISTERS_H__ +#define __PV88090_REGISTERS_H__ + +/* System Control and Event Registers */ +#define PV88090_REG_EVENT_A 0x03 +#define PV88090_REG_MASK_A 0x06 +#define PV88090_REG_MASK_B 0x07 + +/* Regulator Registers */ +#define PV88090_REG_BUCK1_CONF0 0x18 +#define PV88090_REG_BUCK1_CONF1 0x19 +#define PV88090_REG_BUCK1_CONF2 0x1a +#define PV88090_REG_BUCK2_CONF0 0x1b +#define PV88090_REG_BUCK2_CONF1 0x1c +#define PV88090_REG_BUCK2_CONF2 0x58 +#define PV88090_REG_BUCK3_CONF0 0x1d +#define PV88090_REG_BUCK3_CONF1 0x1e +#define PV88090_REG_BUCK3_CONF2 0x5c + +#define PV88090_REG_LDO1_CONT 0x1f +#define PV88090_REG_LDO2_CONT 0x20 +#define PV88090_REG_LDO3_CONT 0x21 +#define PV88090_REG_BUCK_FOLD_RANGE 0x61 + +/* PV88090_REG_EVENT_A (addr=0x03) */ +#define PV88090_E_VDD_FLT 0x01 +#define PV88090_E_OVER_TEMP 0x02 + +/* PV88090_REG_MASK_A (addr=0x06) */ +#define PV88090_M_VDD_FLT 0x01 +#define PV88090_M_OVER_TEMP 0x02 + +/* PV88090_REG_BUCK1_CONF0 (addr=0x18) */ +#define PV88090_BUCK1_EN 0x80 +#define PV88090_VBUCK1_MASK 0x7F +/* PV88090_REG_BUCK2_CONF0 (addr=0x1b) */ +#define PV88090_BUCK2_EN 0x80 +#define PV88090_VBUCK2_MASK 0x7F +/* PV88090_REG_BUCK3_CONF0 (addr=0x1d) */ +#define PV88090_BUCK3_EN 0x80 +#define PV88090_VBUCK3_MASK 0x7F +/* PV88090_REG_LDO1_CONT (addr=0x1f) */ +#define PV88090_LDO1_EN 0x40 +#define PV88090_VLDO1_MASK 0x3F +/* PV88090_REG_LDO2_CONT (addr=0x20) */ +#define PV88090_LDO2_EN 0x40 +#define PV88090_VLDO2_MASK 0x3F + +/* PV88090_REG_BUCK1_CONF1 (addr=0x19) */ +#define PV88090_BUCK1_ILIM_SHIFT 2 +#define PV88090_BUCK1_ILIM_MASK 0x7C +#define PV88090_BUCK1_MODE_MASK 0x03 + +/* PV88090_REG_BUCK2_CONF1 (addr=0x1c) */ +#define PV88090_BUCK2_ILIM_SHIFT 2 +#define PV88090_BUCK2_ILIM_MASK 0x0C +#define PV88090_BUCK2_MODE_MASK 0x03 + +/* PV88090_REG_BUCK3_CONF1 (addr=0x1e) */ +#define PV88090_BUCK3_ILIM_SHIFT 2 +#define PV88090_BUCK3_ILIM_MASK 0x0C +#define PV88090_BUCK3_MODE_MASK 0x03 + +#define PV88090_BUCK_MODE_SLEEP 0x00 +#define PV88090_BUCK_MODE_AUTO 0x01 +#define PV88090_BUCK_MODE_SYNC 0x02 + +/* PV88090_REG_BUCK2_CONF2 (addr=0x58) */ +/* PV88090_REG_BUCK3_CONF2 (addr=0x5c) */ +#define PV88090_BUCK_VDAC_RANGE_SHIFT 7 +#define PV88090_BUCK_VDAC_RANGE_MASK 0x01 + +#define PV88090_BUCK_VDAC_RANGE_1 0x00 +#define PV88090_BUCK_VDAC_RANGE_2 0x01 + +/* PV88090_REG_BUCK_FOLD_RANGE (addr=0x61) */ +#define PV88080_BUCK_VRANGE_GAIN_SHIFT 3 +#define PV88080_BUCK_VRANGE_GAIN_MASK 0x01 + +#define PV88080_BUCK_VRANGE_GAIN_1 0x00 +#define PV88080_BUCK_VRANGE_GAIN_2 0x01 + +#endif /* __PV88090_REGISTERS_H__ */ -- GitLab From 7326ffef788dd5823c820a6ac5b5e864e8a486a0 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Tue, 1 Dec 2015 12:03:02 +0100 Subject: [PATCH 1016/2855] sh: nand: make use of mtd_to_nand() where appropriate mtd_to_nand() was recently introduced to avoid direct accesses to the mtd->priv field. Update all SH specific implementations to use this helper. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- arch/sh/boards/mach-migor/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index 29b7c0dcfc51c..8673f91ebd41b 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -167,7 +167,7 @@ static struct mtd_partition migor_nand_flash_partitions[] = { static void migor_nand_flash_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); if (cmd == NAND_CMD_NONE) return; -- GitLab From 862eba519e79c48fb6ee276081ddb98fe6926f02 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Tue, 1 Dec 2015 12:03:03 +0100 Subject: [PATCH 1017/2855] mtd: nand: make use of mtd_to_nand() in NAND core code mtd_to_nand() was recently introduced to avoid direct access to the mtd->priv field. Update core code to use mtd_to_nand(). Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_base.c | 84 ++++++++++++++++++------------------ drivers/mtd/nand/nand_bbt.c | 32 +++++++------- drivers/mtd/nand/nand_bch.c | 4 +- drivers/mtd/nand/nand_ecc.c | 4 +- drivers/mtd/nand/nandsim.c | 18 ++++---- 5 files changed, 71 insertions(+), 71 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 0748a13fc2be8..5aec1545cd399 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -106,7 +106,7 @@ DEFINE_LED_TRIGGER(nand_led_trigger); static int check_offs_len(struct mtd_info *mtd, loff_t ofs, uint64_t len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); int ret = 0; /* Start address must align on block boundary */ @@ -132,7 +132,7 @@ static int check_offs_len(struct mtd_info *mtd, */ static void nand_release_device(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); /* Release the controller and the chip */ spin_lock(&chip->controller->lock); @@ -150,7 +150,7 @@ static void nand_release_device(struct mtd_info *mtd) */ static uint8_t nand_read_byte(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); return readb(chip->IO_ADDR_R); } @@ -163,7 +163,7 @@ static uint8_t nand_read_byte(struct mtd_info *mtd) */ static uint8_t nand_read_byte16(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); return (uint8_t) cpu_to_le16(readw(chip->IO_ADDR_R)); } @@ -175,7 +175,7 @@ static uint8_t nand_read_byte16(struct mtd_info *mtd) */ static u16 nand_read_word(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); return readw(chip->IO_ADDR_R); } @@ -188,7 +188,7 @@ static u16 nand_read_word(struct mtd_info *mtd) */ static void nand_select_chip(struct mtd_info *mtd, int chipnr) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); switch (chipnr) { case -1: @@ -211,7 +211,7 @@ static void nand_select_chip(struct mtd_info *mtd, int chipnr) */ static void nand_write_byte(struct mtd_info *mtd, uint8_t byte) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); chip->write_buf(mtd, &byte, 1); } @@ -225,7 +225,7 @@ static void nand_write_byte(struct mtd_info *mtd, uint8_t byte) */ static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); uint16_t word = byte; /* @@ -257,7 +257,7 @@ static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte) */ static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); iowrite8_rep(chip->IO_ADDR_W, buf, len); } @@ -272,7 +272,7 @@ static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) */ static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); ioread8_rep(chip->IO_ADDR_R, buf, len); } @@ -287,7 +287,7 @@ static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) */ static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); u16 *p = (u16 *) buf; iowrite16_rep(chip->IO_ADDR_W, p, len >> 1); @@ -303,7 +303,7 @@ static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) */ static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); u16 *p = (u16 *) buf; ioread16_rep(chip->IO_ADDR_R, p, len >> 1); @@ -320,7 +320,7 @@ static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len) static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) { int page, chipnr, res = 0, i = 0; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); u16 bad; if (chip->bbt_options & NAND_BBT_SCANLASTPAGE) @@ -380,7 +380,7 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) */ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct mtd_oob_ops ops; uint8_t buf[2] = { 0, 0 }; int ret = 0, res, i = 0; @@ -430,7 +430,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) */ static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); int res, ret = 0; if (!(chip->bbt_options & NAND_BBT_NO_OOB_BBM)) { @@ -471,7 +471,7 @@ static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs) */ static int nand_check_wp(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); /* Broken xD cards report WP despite being writable */ if (chip->options & NAND_BROKEN_XD) @@ -491,7 +491,7 @@ static int nand_check_wp(struct mtd_info *mtd) */ static int nand_block_isreserved(struct mtd_info *mtd, loff_t ofs) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); if (!chip->bbt) return 0; @@ -512,7 +512,7 @@ static int nand_block_isreserved(struct mtd_info *mtd, loff_t ofs) static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); if (!chip->bbt) return chip->block_bad(mtd, ofs, getchip); @@ -531,7 +531,7 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, */ static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); int i; /* Wait for the device to get ready */ @@ -551,7 +551,7 @@ static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo) */ void nand_wait_ready(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); unsigned long timeo = 400; if (in_interrupt() || oops_in_progress) @@ -582,7 +582,7 @@ EXPORT_SYMBOL_GPL(nand_wait_ready); */ static void nand_wait_status_ready(struct mtd_info *mtd, unsigned long timeo) { - register struct nand_chip *chip = mtd->priv; + register struct nand_chip *chip = mtd_to_nand(mtd); timeo = jiffies + msecs_to_jiffies(timeo); do { @@ -605,7 +605,7 @@ static void nand_wait_status_ready(struct mtd_info *mtd, unsigned long timeo) static void nand_command(struct mtd_info *mtd, unsigned int command, int column, int page_addr) { - register struct nand_chip *chip = mtd->priv; + register struct nand_chip *chip = mtd_to_nand(mtd); int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE; /* Write out the command to the device */ @@ -708,7 +708,7 @@ static void nand_command(struct mtd_info *mtd, unsigned int command, static void nand_command_lp(struct mtd_info *mtd, unsigned int command, int column, int page_addr) { - register struct nand_chip *chip = mtd->priv; + register struct nand_chip *chip = mtd_to_nand(mtd); /* Emulate NAND_CMD_READOOB */ if (command == NAND_CMD_READOOB) { @@ -832,7 +832,7 @@ static void panic_nand_get_device(struct nand_chip *chip, static int nand_get_device(struct mtd_info *mtd, int new_state) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); spinlock_t *lock = &chip->controller->lock; wait_queue_head_t *wq = &chip->controller->wq; DECLARE_WAITQUEUE(wait, current); @@ -952,7 +952,7 @@ static int __nand_unlock(struct mtd_info *mtd, loff_t ofs, { int ret = 0; int status, page; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); /* Submit address of first page to unlock */ page = ofs >> chip->page_shift; @@ -987,7 +987,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { int ret = 0; int chipnr; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); pr_debug("%s: start = 0x%012llx, len = %llu\n", __func__, (unsigned long long)ofs, len); @@ -1050,7 +1050,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { int ret = 0; int chipnr, status, page; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); pr_debug("%s: start = 0x%012llx, len = %llu\n", __func__, (unsigned long long)ofs, len); @@ -1655,7 +1655,7 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, */ static int nand_setup_read_retry(struct mtd_info *mtd, int retry_mode) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); pr_debug("setting READ RETRY mode %d\n", retry_mode); @@ -1680,7 +1680,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) { int chipnr, page, realpage, col, bytes, aligned, oob_required; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); int ret = 0; uint32_t readlen = ops->len; uint32_t oobreadlen = ops->ooblen; @@ -2024,7 +2024,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) { int page, realpage, chipnr; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct mtd_ecc_stats stats; int readlen = ops->ooblen; int len; @@ -2472,7 +2472,7 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len, struct mtd_oob_ops *ops) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); /* * Initialise to all 0xFF, to avoid the possibility of left over OOB @@ -2532,7 +2532,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) { int chipnr, realpage, page, blockmask, column; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); uint32_t writelen = ops->len; uint32_t oobwritelen = ops->ooblen; @@ -2662,7 +2662,7 @@ err_out: static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const uint8_t *buf) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct mtd_oob_ops ops; int ret; @@ -2722,7 +2722,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) { int chipnr, page, status, len; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); pr_debug("%s: to = 0x%08x, len = %i\n", __func__, (unsigned int)to, (int)ops->ooblen); @@ -2847,7 +2847,7 @@ out: */ static int single_erase(struct mtd_info *mtd, int page) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); /* Send commands to erase a block */ chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page); chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1); @@ -2879,7 +2879,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, int allowbbt) { int page, status, pages_per_block, ret, chipnr; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); loff_t len; pr_debug("%s: start = 0x%012llx, len = %llu\n", @@ -3094,7 +3094,7 @@ static int nand_suspend(struct mtd_info *mtd) */ static void nand_resume(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); if (chip->state == FL_PM_SUSPENDED) nand_release_device(mtd); @@ -3266,7 +3266,7 @@ ext_out: static int nand_setup_read_retry_micron(struct mtd_info *mtd, int retry_mode) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {retry_mode}; return chip->onfi_set_features(mtd, chip, ONFI_FEATURE_ADDR_READ_RETRY, @@ -3985,7 +3985,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, struct nand_flash_dev *table) { int i, nand_maf_id, nand_dev_id; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct nand_flash_dev *type; int ret; @@ -4056,7 +4056,7 @@ EXPORT_SYMBOL(nand_scan_ident); */ static bool nand_ecc_strength_good(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct nand_ecc_ctrl *ecc = &chip->ecc; int corr, ds_corr; @@ -4085,7 +4085,7 @@ static bool nand_ecc_strength_good(struct mtd_info *mtd) int nand_scan_tail(struct mtd_info *mtd) { int i; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct nand_ecc_ctrl *ecc = &chip->ecc; struct nand_buffers *nbuf; @@ -4429,7 +4429,7 @@ EXPORT_SYMBOL(nand_scan); */ void nand_release(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); if (chip->ecc.mode == NAND_ECC_SOFT_BCH) nand_bch_free((struct nand_bch_control *)chip->ecc.priv); diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index b1d4f813aedc1..4b6a7085b442d 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -172,7 +172,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, struct nand_bbt_descr *td, int offs) { int res, ret = 0, i, j, act = 0; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); size_t retlen, len, totlen; loff_t from; int bits = td->options & NAND_BBT_NRBITS_MSK; @@ -263,7 +263,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, */ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); int res = 0, i; if (td->options & NAND_BBT_PERCHIP) { @@ -388,7 +388,7 @@ static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td) static void read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); /* Read the primary version, if available */ if (td->options & NAND_BBT_VERSION) { @@ -454,7 +454,7 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd, static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); int i, numblocks, numpages; int startblock; loff_t from; @@ -523,7 +523,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, */ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); int i, chips; int startblock, block, dir; int scanlen = mtd->writesize + mtd->oobsize; @@ -618,7 +618,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct erase_info einfo; int i, res, chip = 0; int bits, startblock, dir, page, offs, numblocks, sft, sftmsk; @@ -819,7 +819,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, */ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); return create_bbt(mtd, this->buffers->databuf, bd, -1); } @@ -838,7 +838,7 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd) { int i, chips, writeops, create, chipsel, res, res2; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct nand_bbt_descr *td = this->bbt_td; struct nand_bbt_descr *md = this->bbt_md; struct nand_bbt_descr *rd, *rd2; @@ -962,7 +962,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc */ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); int i, j, chips, block, nrblocks, update; uint8_t oldval; @@ -1022,7 +1022,7 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) */ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); u32 pattern_len; u32 bits; u32 table_size; @@ -1074,7 +1074,7 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd) */ static int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); int len, res; uint8_t *buf; struct nand_bbt_descr *td = this->bbt_td; @@ -1147,7 +1147,7 @@ err: */ static int nand_update_bbt(struct mtd_info *mtd, loff_t offs) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); int len, res = 0; int chip, chipsel; uint8_t *buf; @@ -1281,7 +1281,7 @@ static int nand_create_badblock_pattern(struct nand_chip *this) */ int nand_default_bbt(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); int ret; /* Is a flash based bad block table requested? */ @@ -1317,7 +1317,7 @@ int nand_default_bbt(struct mtd_info *mtd) */ int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); int block; block = (int)(offs >> this->bbt_erase_shift); @@ -1332,7 +1332,7 @@ int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs) */ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); int block, res; block = (int)(offs >> this->bbt_erase_shift); @@ -1359,7 +1359,7 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) */ int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); int block, ret = 0; block = (int)(offs >> this->bbt_erase_shift); diff --git a/drivers/mtd/nand/nand_bch.c b/drivers/mtd/nand/nand_bch.c index 3803e0bba23be..e5758d885943e 100644 --- a/drivers/mtd/nand/nand_bch.c +++ b/drivers/mtd/nand/nand_bch.c @@ -52,7 +52,7 @@ struct nand_bch_control { int nand_bch_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf, unsigned char *code) { - const struct nand_chip *chip = mtd->priv; + const struct nand_chip *chip = mtd_to_nand(mtd); struct nand_bch_control *nbc = chip->ecc.priv; unsigned int i; @@ -79,7 +79,7 @@ EXPORT_SYMBOL(nand_bch_calculate_ecc); int nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf, unsigned char *read_ecc, unsigned char *calc_ecc) { - const struct nand_chip *chip = mtd->priv; + const struct nand_chip *chip = mtd_to_nand(mtd); struct nand_bch_control *nbc = chip->ecc.priv; unsigned int *errloc = nbc->errloc; int i, count; diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c index 97c4c0216c907..e6129851bfd89 100644 --- a/drivers/mtd/nand/nand_ecc.c +++ b/drivers/mtd/nand/nand_ecc.c @@ -424,7 +424,7 @@ int nand_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf, unsigned char *code) { __nand_calculate_ecc(buf, - ((struct nand_chip *)mtd->priv)->ecc.size, code); + mtd_to_nand(mtd)->ecc.size, code); return 0; } @@ -524,7 +524,7 @@ int nand_correct_data(struct mtd_info *mtd, unsigned char *buf, unsigned char *read_ecc, unsigned char *calc_ecc) { return __nand_correct_data(buf, read_ecc, calc_ecc, - ((struct nand_chip *)mtd->priv)->ecc.size); + mtd_to_nand(mtd)->ecc.size); } EXPORT_SYMBOL(nand_correct_data); diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index b16d70aafd9ec..eb2a567f41d9d 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -666,7 +666,7 @@ static char *get_partition_name(int i) */ static int init_nandsim(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct nandsim *ns = chip->priv; int i, ret = 0; uint64_t remains; @@ -1908,7 +1908,7 @@ static void switch_state(struct nandsim *ns) static u_char ns_nand_read_byte(struct mtd_info *mtd) { - struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv; + struct nandsim *ns = mtd_to_nand(mtd)->priv; u_char outb = 0x00; /* Sanity and correctness checks */ @@ -1969,7 +1969,7 @@ static u_char ns_nand_read_byte(struct mtd_info *mtd) static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte) { - struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv; + struct nandsim *ns = mtd_to_nand(mtd)->priv; /* Sanity and correctness checks */ if (!ns->lines.ce) { @@ -2123,7 +2123,7 @@ static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte) static void ns_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int bitmask) { - struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv; + struct nandsim *ns = mtd_to_nand(mtd)->priv; ns->lines.cle = bitmask & NAND_CLE ? 1 : 0; ns->lines.ale = bitmask & NAND_ALE ? 1 : 0; @@ -2141,7 +2141,7 @@ static int ns_device_ready(struct mtd_info *mtd) static uint16_t ns_nand_read_word(struct mtd_info *mtd) { - struct nand_chip *chip = (struct nand_chip *)mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); NS_DBG("read_word\n"); @@ -2150,7 +2150,7 @@ static uint16_t ns_nand_read_word(struct mtd_info *mtd) static void ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) { - struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv; + struct nandsim *ns = mtd_to_nand(mtd)->priv; /* Check that chip is expecting data input */ if (!(ns->state & STATE_DATAIN_MASK)) { @@ -2177,7 +2177,7 @@ static void ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) static void ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) { - struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv; + struct nandsim *ns = mtd_to_nand(mtd)->priv; /* Sanity and correctness checks */ if (!ns->lines.ce) { @@ -2198,7 +2198,7 @@ static void ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) int i; for (i = 0; i < len; i++) - buf[i] = ((struct nand_chip *)mtd->priv)->read_byte(mtd); + buf[i] = mtd_to_nand(mtd)->read_byte(mtd); return; } @@ -2405,7 +2405,7 @@ module_init(ns_init_module); */ static void __exit ns_cleanup_module(void) { - struct nandsim *ns = ((struct nand_chip *)nsmtd->priv)->priv; + struct nandsim *ns = mtd_to_nand(nsmtd)->priv; int i; nandsim_debugfs_remove(ns); -- GitLab From a83dfa92850e521dfb6485ad4aa3c7c1fb52f06e Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Tue, 1 Dec 2015 12:03:05 +0100 Subject: [PATCH 1018/2855] staging: mt29f_spinand: make use of mtd_to_nand() mtd_to_nand() was recently introduced to avoid direct accesses to the mtd->priv field. Use it where appropriate. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/staging/mt29f_spinand/mt29f_spinand.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c index 6536066b23490..8924a9645a436 100644 --- a/drivers/staging/mt29f_spinand/mt29f_spinand.c +++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c @@ -31,7 +31,7 @@ static inline struct spinand_state *mtd_to_state(struct mtd_info *mtd) { - struct nand_chip *chip = (struct nand_chip *)mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct spinand_info *info = (struct spinand_info *)chip->priv; struct spinand_state *state = (struct spinand_state *)info->priv; @@ -744,7 +744,7 @@ static void spinand_reset(struct spi_device *spi_nand) static void spinand_cmdfunc(struct mtd_info *mtd, unsigned int command, int column, int page) { - struct nand_chip *chip = (struct nand_chip *)mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct spinand_info *info = (struct spinand_info *)chip->priv; struct spinand_state *state = (struct spinand_state *)info->priv; -- GitLab From 4bd4ebcc540c35d4477b098cf26394f976551464 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Tue, 1 Dec 2015 12:03:04 +0100 Subject: [PATCH 1019/2855] mtd: nand: make use of mtd_to_nand() in NAND drivers mtd_to_nand() was recently introduced to avoid direct accesses to the mtd->priv field. Update all NAND drivers to use it. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/ams-delta.c | 4 +- drivers/mtd/nand/atmel_nand.c | 50 +++++++-------- drivers/mtd/nand/au1550nd.c | 22 +++---- drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c | 16 ++--- drivers/mtd/nand/bf5xx_nand.c | 12 ++-- drivers/mtd/nand/brcmnand/brcmnand.c | 12 ++-- drivers/mtd/nand/cafe_nand.c | 18 +++--- drivers/mtd/nand/cmx270_nand.c | 8 +-- drivers/mtd/nand/cs553x_nand.c | 18 +++--- drivers/mtd/nand/davinci_nand.c | 8 +-- drivers/mtd/nand/diskonchip.c | 66 ++++++++++---------- drivers/mtd/nand/docg4.c | 34 +++++----- drivers/mtd/nand/fsl_elbc_nand.c | 14 ++--- drivers/mtd/nand/fsl_ifc_nand.c | 18 +++--- drivers/mtd/nand/fsl_upm.c | 4 +- drivers/mtd/nand/fsmc_nand.c | 10 +-- drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 18 +++--- drivers/mtd/nand/hisi504_nand.c | 16 ++--- drivers/mtd/nand/jz4740_nand.c | 4 +- drivers/mtd/nand/lpc32xx_mlc.c | 6 +- drivers/mtd/nand/lpc32xx_slc.c | 14 ++--- drivers/mtd/nand/mpc5121_nfc.c | 24 +++---- drivers/mtd/nand/mxc_nand.c | 34 +++++----- drivers/mtd/nand/ndfc.c | 14 ++--- drivers/mtd/nand/nuc900_nand.c | 2 +- drivers/mtd/nand/omap2.c | 12 ++-- drivers/mtd/nand/orion_nand.c | 4 +- drivers/mtd/nand/pasemi_nand.c | 8 +-- drivers/mtd/nand/pxa3xx_nand.c | 18 +++--- drivers/mtd/nand/r852.c | 2 +- drivers/mtd/nand/s3c2410.c | 6 +- drivers/mtd/nand/sharpsl.c | 2 +- drivers/mtd/nand/sm_common.c | 2 +- drivers/mtd/nand/socrates_nand.c | 8 +-- drivers/mtd/nand/sunxi_nand.c | 26 ++++---- drivers/mtd/nand/tmio_nand.c | 2 +- drivers/mtd/nand/txx9ndfmc.c | 12 ++-- drivers/mtd/nand/xway_nand.c | 4 +- 38 files changed, 276 insertions(+), 276 deletions(-) diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c index 842f8fe91b56c..b2b49c42920c2 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/ams-delta.c @@ -64,7 +64,7 @@ static struct mtd_partition partition_info[] = { static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); void __iomem *io_base = this->priv; writew(0, io_base + OMAP_MPUIO_IO_CNTL); @@ -77,7 +77,7 @@ static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte) static u_char ams_delta_read_byte(struct mtd_info *mtd) { u_char res; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); void __iomem *io_base = this->priv; gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NRE, 0); diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index f4e1f915c6963..edd191a6ee53c 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -182,7 +182,7 @@ static void atmel_nand_disable(struct atmel_nand_host *host) */ static void atmel_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct atmel_nand_host *host = nand_chip->priv; if (ctrl & NAND_CTRL_CHANGE) { @@ -205,7 +205,7 @@ static void atmel_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl */ static int atmel_nand_device_ready(struct mtd_info *mtd) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct atmel_nand_host *host = nand_chip->priv; return gpio_get_value(host->board.rdy_pin) ^ @@ -215,7 +215,7 @@ static int atmel_nand_device_ready(struct mtd_info *mtd) /* Set up for hardware ready pin and enable pin. */ static int atmel_nand_set_enable_ready_pins(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct atmel_nand_host *host = chip->priv; int res = 0; @@ -267,7 +267,7 @@ static int atmel_nand_set_enable_ready_pins(struct mtd_info *mtd) */ static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct atmel_nand_host *host = nand_chip->priv; if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { @@ -280,7 +280,7 @@ static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len) static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct atmel_nand_host *host = nand_chip->priv; if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { @@ -293,14 +293,14 @@ static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len) static void atmel_write_buf8(struct mtd_info *mtd, const u8 *buf, int len) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); __raw_writesb(nand_chip->IO_ADDR_W, buf, len); } static void atmel_write_buf16(struct mtd_info *mtd, const u8 *buf, int len) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); __raw_writesw(nand_chip->IO_ADDR_W, buf, len / 2); } @@ -352,7 +352,7 @@ static int atmel_nand_dma_op(struct mtd_info *mtd, void *buf, int len, dma_addr_t dma_src_addr, dma_dst_addr, phys_addr; struct dma_async_tx_descriptor *tx = NULL; dma_cookie_t cookie; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct atmel_nand_host *host = chip->priv; void *p = buf; int err = -EIO; @@ -425,7 +425,7 @@ err_buf: static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct atmel_nand_host *host = chip->priv; if (use_dma && len > mtd->oobsize) @@ -441,7 +441,7 @@ static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len) static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct atmel_nand_host *host = chip->priv; if (use_dma && len > mtd->oobsize) @@ -533,7 +533,7 @@ static int pmecc_data_alloc(struct atmel_nand_host *host) static void pmecc_gen_syndrome(struct mtd_info *mtd, int sector) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct atmel_nand_host *host = nand_chip->priv; int i; uint32_t value; @@ -550,7 +550,7 @@ static void pmecc_gen_syndrome(struct mtd_info *mtd, int sector) static void pmecc_substitute(struct mtd_info *mtd) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct atmel_nand_host *host = nand_chip->priv; int16_t __iomem *alpha_to = host->pmecc_alpha_to; int16_t __iomem *index_of = host->pmecc_index_of; @@ -592,7 +592,7 @@ static void pmecc_substitute(struct mtd_info *mtd) static void pmecc_get_sigma(struct mtd_info *mtd) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct atmel_nand_host *host = nand_chip->priv; int16_t *lmu = host->pmecc_lmu; @@ -750,7 +750,7 @@ static void pmecc_get_sigma(struct mtd_info *mtd) static int pmecc_err_location(struct mtd_info *mtd) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct atmel_nand_host *host = nand_chip->priv; unsigned long end_time; const int cap = host->pmecc_corr_cap; @@ -802,7 +802,7 @@ static int pmecc_err_location(struct mtd_info *mtd) static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc, int sector_num, int extra_bytes, int err_nbr) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct atmel_nand_host *host = nand_chip->priv; int i = 0; int byte_pos, bit_pos, sector_size, pos; @@ -848,7 +848,7 @@ static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc, static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf, u8 *ecc) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct atmel_nand_host *host = nand_chip->priv; int i, err_nbr; uint8_t *buf_pos; @@ -992,7 +992,7 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd, static void atmel_pmecc_core_init(struct mtd_info *mtd) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct atmel_nand_host *host = nand_chip->priv; uint32_t val = 0; struct nand_ecclayout *ecc_layout; @@ -1308,7 +1308,7 @@ err: static int atmel_nand_calculate(struct mtd_info *mtd, const u_char *dat, unsigned char *ecc_code) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct atmel_nand_host *host = nand_chip->priv; unsigned int ecc_value; @@ -1412,7 +1412,7 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *isnull) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct atmel_nand_host *host = nand_chip->priv; unsigned int ecc_status; unsigned int ecc_word, ecc_bit; @@ -1478,7 +1478,7 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, */ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct atmel_nand_host *host = nand_chip->priv; if (host->board.need_reset_workaround) @@ -1771,7 +1771,7 @@ static int nfc_send_command(struct atmel_nand_host *host, static int nfc_device_ready(struct mtd_info *mtd) { u32 status, mask; - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct atmel_nand_host *host = nand_chip->priv; status = nfc_read_status(host); @@ -1787,7 +1787,7 @@ static int nfc_device_ready(struct mtd_info *mtd) static void nfc_select_chip(struct mtd_info *mtd, int chip) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct atmel_nand_host *host = nand_chip->priv; if (chip == -1) @@ -1799,7 +1799,7 @@ static void nfc_select_chip(struct mtd_info *mtd, int chip) static int nfc_make_addr(struct mtd_info *mtd, int command, int column, int page_addr, unsigned int *addr1234, unsigned int *cycle0) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); int acycle = 0; unsigned char addr_bytes[8]; @@ -1839,7 +1839,7 @@ static int nfc_make_addr(struct mtd_info *mtd, int command, int column, static void nfc_nand_command(struct mtd_info *mtd, unsigned int command, int column, int page_addr) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct atmel_nand_host *host = chip->priv; unsigned long timeout; unsigned int nfc_addr_cmd = 0; @@ -2026,7 +2026,7 @@ static int nfc_sram_write_page(struct mtd_info *mtd, struct nand_chip *chip, static int nfc_sram_init(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct atmel_nand_host *host = chip->priv; int res = 0; diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 08a130f63faff..73fceb8743a24 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c @@ -39,7 +39,7 @@ struct au1550nd_ctx { */ static u_char au_read_byte(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); u_char ret = readb(this->IO_ADDR_R); wmb(); /* drain writebuffer */ return ret; @@ -54,7 +54,7 @@ static u_char au_read_byte(struct mtd_info *mtd) */ static void au_write_byte(struct mtd_info *mtd, u_char byte) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); writeb(byte, this->IO_ADDR_W); wmb(); /* drain writebuffer */ } @@ -67,7 +67,7 @@ static void au_write_byte(struct mtd_info *mtd, u_char byte) */ static u_char au_read_byte16(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); u_char ret = (u_char) cpu_to_le16(readw(this->IO_ADDR_R)); wmb(); /* drain writebuffer */ return ret; @@ -82,7 +82,7 @@ static u_char au_read_byte16(struct mtd_info *mtd) */ static void au_write_byte16(struct mtd_info *mtd, u_char byte) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); writew(le16_to_cpu((u16) byte), this->IO_ADDR_W); wmb(); /* drain writebuffer */ } @@ -95,7 +95,7 @@ static void au_write_byte16(struct mtd_info *mtd, u_char byte) */ static u16 au_read_word(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); u16 ret = readw(this->IO_ADDR_R); wmb(); /* drain writebuffer */ return ret; @@ -112,7 +112,7 @@ static u16 au_read_word(struct mtd_info *mtd) static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len) { int i; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); for (i = 0; i < len; i++) { writeb(buf[i], this->IO_ADDR_W); @@ -131,7 +131,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len) static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len) { int i; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); for (i = 0; i < len; i++) { buf[i] = readb(this->IO_ADDR_R); @@ -150,7 +150,7 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len) static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) { int i; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); u16 *p = (u16 *) buf; len >>= 1; @@ -172,7 +172,7 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len) { int i; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); u16 *p = (u16 *) buf; len >>= 1; @@ -198,7 +198,7 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len) static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) { struct au1550nd_ctx *ctx = container_of(mtd, struct au1550nd_ctx, info); - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); switch (cmd) { @@ -268,7 +268,7 @@ static void au1550_select_chip(struct mtd_info *mtd, int chip) static void au1550_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) { struct au1550nd_ctx *ctx = container_of(mtd, struct au1550nd_ctx, info); - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); int ce_override = 0, i; unsigned long flags = 0; diff --git a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c index 592befc7ffa12..e5b2e48658c4d 100644 --- a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c +++ b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c @@ -89,7 +89,7 @@ static int bcm47xxnflash_ops_bcm4706_poll(struct bcma_drv_cc *cc) static void bcm47xxnflash_ops_bcm4706_read(struct mtd_info *mtd, uint8_t *buf, int len) { - struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; u32 ctlcode; @@ -139,7 +139,7 @@ static void bcm47xxnflash_ops_bcm4706_read(struct mtd_info *mtd, uint8_t *buf, static void bcm47xxnflash_ops_bcm4706_write(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; struct bcma_drv_cc *cc = b47n->cc; @@ -173,7 +173,7 @@ static void bcm47xxnflash_ops_bcm4706_write(struct mtd_info *mtd, static void bcm47xxnflash_ops_bcm4706_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; u32 code = 0; @@ -199,7 +199,7 @@ static void bcm47xxnflash_ops_bcm4706_select_chip(struct mtd_info *mtd, static int bcm47xxnflash_ops_bcm4706_dev_ready(struct mtd_info *mtd) { - struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; return !!(bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_CTL) & NCTL_READY); @@ -216,7 +216,7 @@ static void bcm47xxnflash_ops_bcm4706_cmdfunc(struct mtd_info *mtd, unsigned command, int column, int page_addr) { - struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; struct bcma_drv_cc *cc = b47n->cc; u32 ctlcode; @@ -312,7 +312,7 @@ static void bcm47xxnflash_ops_bcm4706_cmdfunc(struct mtd_info *mtd, static u8 bcm47xxnflash_ops_bcm4706_read_byte(struct mtd_info *mtd) { - struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; struct bcma_drv_cc *cc = b47n->cc; u32 tmp = 0; @@ -341,7 +341,7 @@ static u8 bcm47xxnflash_ops_bcm4706_read_byte(struct mtd_info *mtd) static void bcm47xxnflash_ops_bcm4706_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { - struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; switch (b47n->curr_command) { @@ -357,7 +357,7 @@ static void bcm47xxnflash_ops_bcm4706_read_buf(struct mtd_info *mtd, static void bcm47xxnflash_ops_bcm4706_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; switch (b47n->curr_command) { diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index 61bd2160717ce..d9da5edb011ef 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c @@ -304,7 +304,7 @@ static int bf5xx_nand_correct_data_256(struct mtd_info *mtd, u_char *dat, static int bf5xx_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); int ret; ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc); @@ -329,7 +329,7 @@ static int bf5xx_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) { struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); u16 ecc0, ecc1; u32 code[2]; u8 *p; @@ -466,7 +466,7 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd, uint8_t *buf, int is_read) { struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); unsigned short val; dev_dbg(info->device, " mtd->%p, buf->%p, is_read %d\n", @@ -532,7 +532,7 @@ static void bf5xx_nand_dma_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); dev_dbg(info->device, "mtd->%p, buf->%p, int %d\n", mtd, buf, len); @@ -546,7 +546,7 @@ static void bf5xx_nand_dma_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); dev_dbg(info->device, "mtd->%p, buf->%p, len %d\n", mtd, buf, len); @@ -685,7 +685,7 @@ static int bf5xx_nand_remove(struct platform_device *pdev) static int bf5xx_nand_scan(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); int ret; ret = nand_scan_ident(mtd, 1, NULL); diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index 35d78f739d91d..190a99a66010b 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -873,7 +873,7 @@ static struct nand_ecclayout *brcmstb_choose_ecc_layout( static void brcmnand_wp(struct mtd_info *mtd, int wp) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct brcmnand_host *host = chip->priv; struct brcmnand_controller *ctrl = host->ctrl; @@ -1039,7 +1039,7 @@ static void brcmnand_cmd_ctrl(struct mtd_info *mtd, int dat, static int brcmnand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct brcmnand_host *host = chip->priv; struct brcmnand_controller *ctrl = host->ctrl; unsigned long timeo = msecs_to_jiffies(100); @@ -1113,7 +1113,7 @@ static int brcmnand_low_level_op(struct brcmnand_host *host, static void brcmnand_cmdfunc(struct mtd_info *mtd, unsigned command, int column, int page_addr) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct brcmnand_host *host = chip->priv; struct brcmnand_controller *ctrl = host->ctrl; u64 addr = (u64)page_addr << chip->page_shift; @@ -1219,7 +1219,7 @@ static void brcmnand_cmdfunc(struct mtd_info *mtd, unsigned command, static uint8_t brcmnand_read_byte(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct brcmnand_host *host = chip->priv; struct brcmnand_controller *ctrl = host->ctrl; uint8_t ret = 0; @@ -1286,7 +1286,7 @@ static void brcmnand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { int i; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct brcmnand_host *host = chip->priv; switch (host->last_cmd) { @@ -2061,7 +2061,7 @@ static int brcmnand_resume(struct device *dev) list_for_each_entry(host, &ctrl->host_list, node) { struct mtd_info *mtd = &host->mtd; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); brcmnand_save_restore_cs_config(host, 1); diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index cce3ac4939b6d..77c92f1b985fd 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c @@ -101,7 +101,7 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; static int cafe_device_ready(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct cafe_priv *cafe = chip->priv; int result = !!(cafe_readl(cafe, NAND_STATUS) & 0x40000000); uint32_t irqs = cafe_readl(cafe, NAND_IRQ); @@ -118,7 +118,7 @@ static int cafe_device_ready(struct mtd_info *mtd) static void cafe_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct cafe_priv *cafe = chip->priv; if (usedma) @@ -134,7 +134,7 @@ static void cafe_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) static void cafe_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct cafe_priv *cafe = chip->priv; if (usedma) @@ -149,7 +149,7 @@ static void cafe_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static uint8_t cafe_read_byte(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct cafe_priv *cafe = chip->priv; uint8_t d; @@ -162,7 +162,7 @@ static uint8_t cafe_read_byte(struct mtd_info *mtd) static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command, int column, int page_addr) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct cafe_priv *cafe = chip->priv; int adrbytes = 0; uint32_t ctl1; @@ -318,7 +318,7 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command, static void cafe_select_chip(struct mtd_info *mtd, int chipnr) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct cafe_priv *cafe = chip->priv; cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr); @@ -334,7 +334,7 @@ static void cafe_select_chip(struct mtd_info *mtd, int chipnr) static irqreturn_t cafe_nand_interrupt(int irq, void *id) { struct mtd_info *mtd = id; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct cafe_priv *cafe = chip->priv; uint32_t irqs = cafe_readl(cafe, NAND_IRQ); cafe_writel(cafe, irqs & ~0x90000000, NAND_IRQ); @@ -800,7 +800,7 @@ static int cafe_nand_probe(struct pci_dev *pdev, static void cafe_nand_remove(struct pci_dev *pdev) { struct mtd_info *mtd = pci_get_drvdata(pdev); - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct cafe_priv *cafe = chip->priv; /* Disable NAND IRQ in global IRQ mask register */ @@ -828,7 +828,7 @@ static int cafe_nand_resume(struct pci_dev *pdev) { uint32_t ctrl; struct mtd_info *mtd = pci_get_drvdata(pdev); - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct cafe_priv *cafe = chip->priv; /* Start off by resetting the NAND controller completely */ diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c index 66ec95e6ca6c7..43bded66bc44e 100644 --- a/drivers/mtd/nand/cmx270_nand.c +++ b/drivers/mtd/nand/cmx270_nand.c @@ -53,7 +53,7 @@ static struct mtd_partition partition_info[] = { static u_char cmx270_read_byte(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); return (readl(this->IO_ADDR_R) >> 16); } @@ -61,7 +61,7 @@ static u_char cmx270_read_byte(struct mtd_info *mtd) static void cmx270_write_buf(struct mtd_info *mtd, const u_char *buf, int len) { int i; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); for (i=0; iIO_ADDR_W); @@ -70,7 +70,7 @@ static void cmx270_write_buf(struct mtd_info *mtd, const u_char *buf, int len) static void cmx270_read_buf(struct mtd_info *mtd, u_char *buf, int len) { int i; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); for (i=0; iIO_ADDR_R) >> 16; @@ -94,7 +94,7 @@ static void nand_cs_off(void) static void cmx270_hwcontrol(struct mtd_info *mtd, int dat, unsigned int ctrl) { - struct nand_chip* this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); unsigned int nandaddr = (unsigned int)this->IO_ADDR_W; dsb(); diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index aec6045058c77..8904d685b257a 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c @@ -97,7 +97,7 @@ static void cs553x_read_buf(struct mtd_info *mtd, u_char *buf, int len) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); while (unlikely(len > 0x800)) { memcpy_fromio(buf, this->IO_ADDR_R, 0x800); @@ -109,7 +109,7 @@ static void cs553x_read_buf(struct mtd_info *mtd, u_char *buf, int len) static void cs553x_write_buf(struct mtd_info *mtd, const u_char *buf, int len) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); while (unlikely(len > 0x800)) { memcpy_toio(this->IO_ADDR_R, buf, 0x800); @@ -121,13 +121,13 @@ static void cs553x_write_buf(struct mtd_info *mtd, const u_char *buf, int len) static unsigned char cs553x_read_byte(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); return readb(this->IO_ADDR_R); } static void cs553x_write_byte(struct mtd_info *mtd, u_char byte) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); int i = 100000; while (i && readb(this->IO_ADDR_R + MM_NAND_STS) & CS_NAND_CTLR_BUSY) { @@ -140,7 +140,7 @@ static void cs553x_write_byte(struct mtd_info *mtd, u_char byte) static void cs553x_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); void __iomem *mmio_base = this->IO_ADDR_R; if (ctrl & NAND_CTRL_CHANGE) { unsigned char ctl = (ctrl & ~NAND_CTRL_CHANGE ) ^ 0x01; @@ -152,7 +152,7 @@ static void cs553x_hwcontrol(struct mtd_info *mtd, int cmd, static int cs553x_device_ready(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); void __iomem *mmio_base = this->IO_ADDR_R; unsigned char foo = readb(mmio_base + MM_NAND_STS); @@ -161,7 +161,7 @@ static int cs553x_device_ready(struct mtd_info *mtd) static void cs_enable_hwecc(struct mtd_info *mtd, int mode) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); void __iomem *mmio_base = this->IO_ADDR_R; writeb(0x07, mmio_base + MM_NAND_ECC_CTL); @@ -170,7 +170,7 @@ static void cs_enable_hwecc(struct mtd_info *mtd, int mode) static int cs_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) { uint32_t ecc; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); void __iomem *mmio_base = this->IO_ADDR_R; ecc = readl(mmio_base + MM_NAND_STS); @@ -337,7 +337,7 @@ static void __exit cs553x_cleanup(void) if (!mtd) continue; - this = cs553x_mtd[i]->priv; + this = mtd_to_nand(cs553x_mtd[i]); mmio_base = this->IO_ADDR_R; /* Release resources, unregister device */ diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 8e351af31e530..b5978d58e1df7 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -106,7 +106,7 @@ static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, { struct davinci_nand_info *info = to_davinci_nand(mtd); uint32_t addr = info->current_cs; - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); /* Did the control lines change? */ if (ctrl & NAND_CTRL_CHANGE) { @@ -192,7 +192,7 @@ static int nand_davinci_calculate_1bit(struct mtd_info *mtd, static int nand_davinci_correct_1bit(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); uint32_t eccNand = read_ecc[0] | (read_ecc[1] << 8) | (read_ecc[2] << 16); uint32_t eccCalc = calc_ecc[0] | (calc_ecc[1] << 8) | @@ -447,7 +447,7 @@ correct: */ static void nand_davinci_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0) ioread32_rep(chip->IO_ADDR_R, buf, len >> 2); @@ -460,7 +460,7 @@ static void nand_davinci_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static void nand_davinci_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0) iowrite32_rep(chip->IO_ADDR_R, buf, len >> 2); diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index 0802158a3f757..5f7bcc86486ee 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -299,7 +299,7 @@ static inline int DoC_WaitReady(struct doc_priv *doc) static void doc2000_write_byte(struct mtd_info *mtd, u_char datum) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; @@ -311,7 +311,7 @@ static void doc2000_write_byte(struct mtd_info *mtd, u_char datum) static u_char doc2000_read_byte(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; u_char ret; @@ -326,7 +326,7 @@ static u_char doc2000_read_byte(struct mtd_info *mtd) static void doc2000_writebuf(struct mtd_info *mtd, const u_char *buf, int len) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; int i; @@ -343,7 +343,7 @@ static void doc2000_writebuf(struct mtd_info *mtd, const u_char *buf, int len) static void doc2000_readbuf(struct mtd_info *mtd, u_char *buf, int len) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; int i; @@ -358,7 +358,7 @@ static void doc2000_readbuf(struct mtd_info *mtd, u_char *buf, int len) static void doc2000_readbuf_dword(struct mtd_info *mtd, u_char *buf, int len) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; int i; @@ -379,7 +379,7 @@ static void doc2000_readbuf_dword(struct mtd_info *mtd, u_char *buf, int len) static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; uint16_t ret; @@ -425,7 +425,7 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) static void __init doc2000_count_chips(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; uint16_t mfrid; int i; @@ -461,7 +461,7 @@ static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this) static void doc2001_write_byte(struct mtd_info *mtd, u_char datum) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; @@ -472,7 +472,7 @@ static void doc2001_write_byte(struct mtd_info *mtd, u_char datum) static u_char doc2001_read_byte(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; @@ -486,7 +486,7 @@ static u_char doc2001_read_byte(struct mtd_info *mtd) static void doc2001_writebuf(struct mtd_info *mtd, const u_char *buf, int len) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; int i; @@ -499,7 +499,7 @@ static void doc2001_writebuf(struct mtd_info *mtd, const u_char *buf, int len) static void doc2001_readbuf(struct mtd_info *mtd, u_char *buf, int len) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; int i; @@ -516,7 +516,7 @@ static void doc2001_readbuf(struct mtd_info *mtd, u_char *buf, int len) static u_char doc2001plus_read_byte(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; u_char ret; @@ -531,7 +531,7 @@ static u_char doc2001plus_read_byte(struct mtd_info *mtd) static void doc2001plus_writebuf(struct mtd_info *mtd, const u_char *buf, int len) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; int i; @@ -549,7 +549,7 @@ static void doc2001plus_writebuf(struct mtd_info *mtd, const u_char *buf, int le static void doc2001plus_readbuf(struct mtd_info *mtd, u_char *buf, int len) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; int i; @@ -580,7 +580,7 @@ static void doc2001plus_readbuf(struct mtd_info *mtd, u_char *buf, int len) static void doc2001plus_select_chip(struct mtd_info *mtd, int chip) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; int floor = 0; @@ -607,7 +607,7 @@ static void doc2001plus_select_chip(struct mtd_info *mtd, int chip) static void doc200x_select_chip(struct mtd_info *mtd, int chip) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; int floor = 0; @@ -638,7 +638,7 @@ static void doc200x_select_chip(struct mtd_info *mtd, int chip) static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; @@ -661,7 +661,7 @@ static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd, static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; @@ -767,7 +767,7 @@ static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int colu static int doc200x_dev_ready(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; @@ -807,7 +807,7 @@ static int doc200x_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; @@ -826,7 +826,7 @@ static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode) static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; @@ -846,7 +846,7 @@ static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode) /* This code is only called on write */ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat, unsigned char *ecc_code) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; int i; @@ -907,7 +907,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *isnull) { int i, ret = 0; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; uint8_t calc_ecc[6]; @@ -1007,7 +1007,7 @@ static struct nand_ecclayout doc200x_oobinfo = { mh1_page in the DOC private structure. */ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const char *id, int findmirror) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; unsigned offs; int ret; @@ -1050,7 +1050,7 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const ch static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partition *parts) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; int ret = 0; u_char *buf; @@ -1152,7 +1152,7 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partitio /* This is a stripped-down copy of the code in inftlmount.c */ static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partition *parts) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; int ret = 0; u_char *buf; @@ -1272,7 +1272,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partiti static int __init nftl_scan_bbt(struct mtd_info *mtd) { int ret, numparts; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; struct mtd_partition parts[2]; @@ -1307,7 +1307,7 @@ static int __init nftl_scan_bbt(struct mtd_info *mtd) static int __init inftl_scan_bbt(struct mtd_info *mtd) { int ret, numparts; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; struct mtd_partition parts[5]; @@ -1360,7 +1360,7 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd) static inline int __init doc2000_init(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; this->read_byte = doc2000_read_byte; @@ -1376,7 +1376,7 @@ static inline int __init doc2000_init(struct mtd_info *mtd) static inline int __init doc2001_init(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; this->read_byte = doc2001_read_byte; @@ -1406,7 +1406,7 @@ static inline int __init doc2001_init(struct mtd_info *mtd) static inline int __init doc2001plus_init(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct doc_priv *doc = this->priv; this->read_byte = doc2001plus_read_byte; @@ -1523,7 +1523,7 @@ static int __init doc_probe(unsigned long physadr) for (mtd = doclist; mtd; mtd = doc->nextdoc) { unsigned char oldval; unsigned char newval; - nand = mtd->priv; + nand = mtd_to_nand(mtd); doc = nand->priv; /* Use the alias resolution register to determine if this is in fact the same DOC aliased to a new address. If writes @@ -1643,7 +1643,7 @@ static void release_nanddoc(void) struct doc_priv *doc; for (mtd = doclist; mtd; mtd = nextmtd) { - nand = mtd->priv; + nand = mtd_to_nand(mtd); doc = nand->priv; nextmtd = doc->nextdoc; diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c index 408cf69b854b9..da93d7f5c8213 100644 --- a/drivers/mtd/nand/docg4.c +++ b/drivers/mtd/nand/docg4.c @@ -242,7 +242,7 @@ static inline void write_nop(void __iomem *docptr) static void docg4_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { int i; - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); uint16_t *p = (uint16_t *) buf; len >>= 1; @@ -253,7 +253,7 @@ static void docg4_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static void docg4_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) { int i; - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); uint16_t *p = (uint16_t *) buf; len >>= 1; @@ -318,7 +318,7 @@ static void docg4_select_chip(struct mtd_info *mtd, int chip) * Select among multiple cascaded chips ("floors"). Multiple floors are * not yet supported, so the only valid non-negative value is 0. */ - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct docg4_priv *doc = nand->priv; void __iomem *docptr = doc->virtadr; @@ -337,7 +337,7 @@ static void reset(struct mtd_info *mtd) { /* full device reset */ - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct docg4_priv *doc = nand->priv; void __iomem *docptr = doc->virtadr; @@ -375,7 +375,7 @@ static int correct_data(struct mtd_info *mtd, uint8_t *buf, int page) * Up to four bitflips can be corrected. */ - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct docg4_priv *doc = nand->priv; void __iomem *docptr = doc->virtadr; int i, numerrs, errpos[4]; @@ -464,7 +464,7 @@ static int correct_data(struct mtd_info *mtd, uint8_t *buf, int page) static uint8_t docg4_read_byte(struct mtd_info *mtd) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct docg4_priv *doc = nand->priv; dev_dbg(doc->dev, "%s\n", __func__); @@ -545,7 +545,7 @@ static int pageprog(struct mtd_info *mtd) * internal buffer out to the flash array, or some such. */ - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct docg4_priv *doc = nand->priv; void __iomem *docptr = doc->virtadr; int retval = 0; @@ -582,7 +582,7 @@ static void sequence_reset(struct mtd_info *mtd) { /* common starting sequence for all operations */ - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct docg4_priv *doc = nand->priv; void __iomem *docptr = doc->virtadr; @@ -599,7 +599,7 @@ static void read_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr) { /* first step in reading a page */ - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct docg4_priv *doc = nand->priv; void __iomem *docptr = doc->virtadr; @@ -626,7 +626,7 @@ static void write_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr) { /* first step in writing a page */ - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct docg4_priv *doc = nand->priv; void __iomem *docptr = doc->virtadr; @@ -691,7 +691,7 @@ static void docg4_command(struct mtd_info *mtd, unsigned command, int column, { /* handle standard nand commands */ - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct docg4_priv *doc = nand->priv; uint32_t g4_addr = mtd_to_docg4_address(page_addr, column); @@ -874,7 +874,7 @@ static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand, static int docg4_erase_block(struct mtd_info *mtd, int page) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct docg4_priv *doc = nand->priv; void __iomem *docptr = doc->virtadr; uint16_t g4_page; @@ -1016,7 +1016,7 @@ static int __init read_factory_bbt(struct mtd_info *mtd) * update the memory-based bbt accordingly. */ - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct docg4_priv *doc = nand->priv; uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0); uint8_t *buf; @@ -1089,7 +1089,7 @@ static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs) int ret, i; uint8_t *buf; - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct docg4_priv *doc = nand->priv; struct nand_bbt_descr *bbtd = nand->badblock_pattern; int page = (int)(ofs >> nand->page_shift); @@ -1202,7 +1202,7 @@ static void __init init_mtd_structs(struct mtd_info *mtd) * things as well, such as call nand_set_defaults(). */ - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct docg4_priv *doc = nand->priv; mtd->size = DOCG4_CHIP_SIZE; @@ -1261,7 +1261,7 @@ static void __init init_mtd_structs(struct mtd_info *mtd) static int __init read_id_reg(struct mtd_info *mtd) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct docg4_priv *doc = nand->priv; void __iomem *docptr = doc->virtadr; uint16_t id1, id2; @@ -1357,7 +1357,7 @@ static int __init probe_docg4(struct platform_device *pdev) iounmap(virtadr); if (mtd) { /* re-declarations avoid compiler warning */ - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct docg4_priv *doc = nand->priv; nand_release(mtd); /* deletes partitions and mtd devices */ free_bch(doc->bch); diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index bd6d49376382d..ad6d5daacb839 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -144,7 +144,7 @@ static struct nand_bbt_descr bbt_mirror_descr = { */ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_elbc_mtd *priv = chip->priv; struct fsl_lbc_ctrl *ctrl = priv->ctrl; struct fsl_lbc_regs __iomem *lbc = ctrl->regs; @@ -195,7 +195,7 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) */ static int fsl_elbc_run_command(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_elbc_mtd *priv = chip->priv; struct fsl_lbc_ctrl *ctrl = priv->ctrl; struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; @@ -300,7 +300,7 @@ static void fsl_elbc_do_read(struct nand_chip *chip, int oob) static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, int column, int page_addr) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_elbc_mtd *priv = chip->priv; struct fsl_lbc_ctrl *ctrl = priv->ctrl; struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; @@ -525,7 +525,7 @@ static void fsl_elbc_select_chip(struct mtd_info *mtd, int chip) */ static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_elbc_mtd *priv = chip->priv; struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; unsigned int bufsize = mtd->writesize + mtd->oobsize; @@ -563,7 +563,7 @@ static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) */ static u8 fsl_elbc_read_byte(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_elbc_mtd *priv = chip->priv; struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; @@ -580,7 +580,7 @@ static u8 fsl_elbc_read_byte(struct mtd_info *mtd) */ static void fsl_elbc_read_buf(struct mtd_info *mtd, u8 *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_elbc_mtd *priv = chip->priv; struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; int avail; @@ -619,7 +619,7 @@ static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip) static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_elbc_mtd *priv = chip->priv; struct fsl_lbc_ctrl *ctrl = priv->ctrl; struct fsl_lbc_regs __iomem *lbc = ctrl->regs; diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index f2608315774aa..3136842e88d56 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -230,7 +230,7 @@ static struct nand_bbt_descr bbt_mirror_descr = { */ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_ifc_mtd *priv = chip->priv; struct fsl_ifc_ctrl *ctrl = priv->ctrl; struct fsl_ifc_regs __iomem *ifc = ctrl->regs; @@ -253,7 +253,7 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) static int is_blank(struct mtd_info *mtd, unsigned int bufnum) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_ifc_mtd *priv = chip->priv; u8 __iomem *addr = priv->vbase + bufnum * (mtd->writesize * 2); u32 __iomem *mainarea = (u32 __iomem *)addr; @@ -292,7 +292,7 @@ static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl, */ static void fsl_ifc_run_command(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_ifc_mtd *priv = chip->priv; struct fsl_ifc_ctrl *ctrl = priv->ctrl; struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl; @@ -409,7 +409,7 @@ static void fsl_ifc_do_read(struct nand_chip *chip, /* cmdfunc send commands to the IFC NAND Machine */ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command, int column, int page_addr) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_ifc_mtd *priv = chip->priv; struct fsl_ifc_ctrl *ctrl = priv->ctrl; struct fsl_ifc_regs __iomem *ifc = ctrl->regs; @@ -624,7 +624,7 @@ static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip) */ static void fsl_ifc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_ifc_mtd *priv = chip->priv; unsigned int bufsize = mtd->writesize + mtd->oobsize; @@ -650,7 +650,7 @@ static void fsl_ifc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) */ static uint8_t fsl_ifc_read_byte(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_ifc_mtd *priv = chip->priv; unsigned int offset; @@ -673,7 +673,7 @@ static uint8_t fsl_ifc_read_byte(struct mtd_info *mtd) */ static uint8_t fsl_ifc_read_byte16(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_ifc_mtd *priv = chip->priv; uint16_t data; @@ -696,7 +696,7 @@ static uint8_t fsl_ifc_read_byte16(struct mtd_info *mtd) */ static void fsl_ifc_read_buf(struct mtd_info *mtd, u8 *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_ifc_mtd *priv = chip->priv; int avail; @@ -782,7 +782,7 @@ static int fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip, static int fsl_ifc_chip_init_tail(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_ifc_mtd *priv = chip->priv; dev_dbg(priv->dev, "%s: nand->numchips = %d\n", __func__, diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index b3f4a01621c1d..68ec128e822ca 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -79,7 +79,7 @@ static void fun_wait_rnb(struct fsl_upm_nand *fun) static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd); u32 mar; @@ -109,7 +109,7 @@ static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) static void fun_select_chip(struct mtd_info *mtd, int mchip_nr) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd); if (mchip_nr == -1) { diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 59fc6d0c39108..1c6c399496c2f 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -329,7 +329,7 @@ struct fsmc_nand_data { /* Assert CS signal based on chipnr */ static void fsmc_select_chip(struct mtd_info *mtd, int chipnr) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct fsmc_nand_data *host; host = container_of(mtd, struct fsmc_nand_data, mtd); @@ -358,7 +358,7 @@ static void fsmc_select_chip(struct mtd_info *mtd, int chipnr) */ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct fsmc_nand_data *host = container_of(mtd, struct fsmc_nand_data, mtd); void __iomem *regs = host->regs_va; @@ -629,7 +629,7 @@ unmap_dma: static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { int i; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); if (IS_ALIGNED((uint32_t)buf, sizeof(uint32_t)) && IS_ALIGNED(len, sizeof(uint32_t))) { @@ -652,7 +652,7 @@ static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) static void fsmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { int i; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); if (IS_ALIGNED((uint32_t)buf, sizeof(uint32_t)) && IS_ALIGNED(len, sizeof(uint32_t))) { @@ -784,7 +784,7 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat, { struct fsmc_nand_data *host = container_of(mtd, struct fsmc_nand_data, mtd); - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); void __iomem *regs = host->regs_va; unsigned int bank = host->bank; uint32_t err_idx[8]; diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 5a9b6966e97c6..802adb04bb973 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -140,7 +140,7 @@ static bool set_geometry_by_ecc_info(struct gpmi_nand_data *this) { struct bch_geometry *geo = &this->bch_geometry; struct mtd_info *mtd = &this->mtd; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct nand_oobfree *of = gpmi_hw_ecclayout.oobfree; unsigned int block_mark_bit_offset; @@ -856,7 +856,7 @@ error_alloc: static void gpmi_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct gpmi_nand_data *this = chip->priv; int ret; @@ -890,7 +890,7 @@ static void gpmi_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl) static int gpmi_dev_ready(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct gpmi_nand_data *this = chip->priv; return gpmi_is_ready(this, this->current_chip); @@ -898,7 +898,7 @@ static int gpmi_dev_ready(struct mtd_info *mtd) static void gpmi_select_chip(struct mtd_info *mtd, int chipnr) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct gpmi_nand_data *this = chip->priv; if ((this->current_chip < 0) && (chipnr >= 0)) @@ -911,7 +911,7 @@ static void gpmi_select_chip(struct mtd_info *mtd, int chipnr) static void gpmi_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct gpmi_nand_data *this = chip->priv; dev_dbg(this->dev, "len is %d\n", len); @@ -923,7 +923,7 @@ static void gpmi_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static void gpmi_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct gpmi_nand_data *this = chip->priv; dev_dbg(this->dev, "len is %d\n", len); @@ -935,7 +935,7 @@ static void gpmi_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) static uint8_t gpmi_read_byte(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct gpmi_nand_data *this = chip->priv; uint8_t *buf = this->data_buffer_dma; @@ -1538,7 +1538,7 @@ static int gpmi_ecc_write_oob_raw(struct mtd_info *mtd, struct nand_chip *chip, static int gpmi_block_markbad(struct mtd_info *mtd, loff_t ofs) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct gpmi_nand_data *this = chip->priv; int ret = 0; uint8_t *block_mark; @@ -1838,7 +1838,7 @@ static void gpmi_nand_exit(struct gpmi_nand_data *this) static int gpmi_init_last(struct gpmi_nand_data *this) { struct mtd_info *mtd = &this->mtd; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct nand_ecc_ctrl *ecc = &chip->ecc; struct bch_geometry *bch_geo = &this->bch_geometry; int ret; diff --git a/drivers/mtd/nand/hisi504_nand.c b/drivers/mtd/nand/hisi504_nand.c index 0aad4acab9d61..6358d4ae7b75e 100644 --- a/drivers/mtd/nand/hisi504_nand.c +++ b/drivers/mtd/nand/hisi504_nand.c @@ -190,7 +190,7 @@ static void wait_controller_finished(struct hinfc_host *host) static void hisi_nfc_dma_transfer(struct hinfc_host *host, int todev) { struct mtd_info *mtd = &host->mtd; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); unsigned long val; int ret; @@ -357,7 +357,7 @@ static int hisi_nfc_send_cmd_reset(struct hinfc_host *host, int chipselect) static void hisi_nfc_select_chip(struct mtd_info *mtd, int chipselect) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct hinfc_host *host = chip->priv; if (chipselect < 0) @@ -368,7 +368,7 @@ static void hisi_nfc_select_chip(struct mtd_info *mtd, int chipselect) static uint8_t hisi_nfc_read_byte(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct hinfc_host *host = chip->priv; if (host->command == NAND_CMD_STATUS) @@ -384,7 +384,7 @@ static uint8_t hisi_nfc_read_byte(struct mtd_info *mtd) static u16 hisi_nfc_read_word(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct hinfc_host *host = chip->priv; host->offset += 2; @@ -394,7 +394,7 @@ static u16 hisi_nfc_read_word(struct mtd_info *mtd) static void hisi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct hinfc_host *host = chip->priv; memcpy(host->buffer + host->offset, buf, len); @@ -403,7 +403,7 @@ hisi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) static void hisi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct hinfc_host *host = chip->priv; memcpy(buf, host->buffer + host->offset, len); @@ -412,7 +412,7 @@ static void hisi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static void set_addr(struct mtd_info *mtd, int column, int page_addr) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct hinfc_host *host = chip->priv; unsigned int command = host->command; @@ -448,7 +448,7 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr) static void hisi_nfc_cmdfunc(struct mtd_info *mtd, unsigned command, int column, int page_addr) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct hinfc_host *host = chip->priv; int is_cache_invalid = 1; unsigned int flag = 0; diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index 5a99a93ed0256..5a06fba9bd1ab 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c @@ -82,7 +82,7 @@ static inline struct jz_nand *mtd_to_jz_nand(struct mtd_info *mtd) static void jz_nand_select_chip(struct mtd_info *mtd, int chipnr) { struct jz_nand *nand = mtd_to_jz_nand(mtd); - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); uint32_t ctrl; int banknr; @@ -104,7 +104,7 @@ static void jz_nand_select_chip(struct mtd_info *mtd, int chipnr) static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl) { struct jz_nand *nand = mtd_to_jz_nand(mtd); - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); uint32_t reg; void __iomem *bank_base = nand->bank_base[nand->selected_bank]; diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c index 57c4b712cf1a3..373885659fe0f 100644 --- a/drivers/mtd/nand/lpc32xx_mlc.c +++ b/drivers/mtd/nand/lpc32xx_mlc.c @@ -275,7 +275,7 @@ static void lpc32xx_nand_setup(struct lpc32xx_nand_host *host) static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct lpc32xx_nand_host *host = nand_chip->priv; if (cmd != NAND_CMD_NONE) { @@ -291,7 +291,7 @@ static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, */ static int lpc32xx_nand_device_ready(struct mtd_info *mtd) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct lpc32xx_nand_host *host = nand_chip->priv; if ((readb(MLC_ISR(host->io_base)) & @@ -389,7 +389,7 @@ static void lpc32xx_dma_complete_func(void *completion) static int lpc32xx_xmit_dma(struct mtd_info *mtd, void *mem, int len, enum dma_transfer_direction dir) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct lpc32xx_nand_host *host = chip->priv; struct dma_async_tx_descriptor *desc; int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c index 277626e46379c..fcd9facad05ea 100644 --- a/drivers/mtd/nand/lpc32xx_slc.c +++ b/drivers/mtd/nand/lpc32xx_slc.c @@ -260,7 +260,7 @@ static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { uint32_t tmp; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct lpc32xx_nand_host *host = chip->priv; /* Does CE state need to be changed? */ @@ -284,7 +284,7 @@ static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, */ static int lpc32xx_nand_device_ready(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct lpc32xx_nand_host *host = chip->priv; int rdy = 0; @@ -339,7 +339,7 @@ static int lpc32xx_nand_ecc_calculate(struct mtd_info *mtd, */ static uint8_t lpc32xx_nand_read_byte(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct lpc32xx_nand_host *host = chip->priv; return (uint8_t)readl(SLC_DATA(host->io_base)); @@ -350,7 +350,7 @@ static uint8_t lpc32xx_nand_read_byte(struct mtd_info *mtd) */ static void lpc32xx_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct lpc32xx_nand_host *host = chip->priv; /* Direct device read with no ECC */ @@ -363,7 +363,7 @@ static void lpc32xx_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) */ static void lpc32xx_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct lpc32xx_nand_host *host = chip->priv; /* Direct device write with no ECC */ @@ -428,7 +428,7 @@ static void lpc32xx_dma_complete_func(void *completion) static int lpc32xx_xmit_dma(struct mtd_info *mtd, dma_addr_t dma, void *mem, int len, enum dma_transfer_direction dir) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct lpc32xx_nand_host *host = chip->priv; struct dma_async_tx_descriptor *desc; int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; @@ -488,7 +488,7 @@ out1: static int lpc32xx_xfer(struct mtd_info *mtd, uint8_t *buf, int eccsubpages, int read) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct lpc32xx_nand_host *host = chip->priv; int i, status = 0; unsigned long timeout; diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index 0fdfc42f75f81..642c486ea3c2d 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c @@ -135,7 +135,7 @@ static void mpc5121_nfc_done(struct mtd_info *mtd); /* Read NFC register */ static inline u16 nfc_read(struct mtd_info *mtd, uint reg) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct mpc5121_nfc_prv *prv = chip->priv; return in_be16(prv->regs + reg); @@ -144,7 +144,7 @@ static inline u16 nfc_read(struct mtd_info *mtd, uint reg) /* Write NFC register */ static inline void nfc_write(struct mtd_info *mtd, uint reg, u16 val) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct mpc5121_nfc_prv *prv = chip->priv; out_be16(prv->regs + reg, val); @@ -214,7 +214,7 @@ static inline void mpc5121_nfc_send_read_status(struct mtd_info *mtd) static irqreturn_t mpc5121_nfc_irq(int irq, void *data) { struct mtd_info *mtd = data; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct mpc5121_nfc_prv *prv = chip->priv; nfc_set(mtd, NFC_CONFIG1, NFC_INT_MASK); @@ -226,7 +226,7 @@ static irqreturn_t mpc5121_nfc_irq(int irq, void *data) /* Wait for operation complete */ static void mpc5121_nfc_done(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct mpc5121_nfc_prv *prv = chip->priv; int rv; @@ -246,7 +246,7 @@ static void mpc5121_nfc_done(struct mtd_info *mtd) /* Do address cycle(s) */ static void mpc5121_nfc_addr_cycle(struct mtd_info *mtd, int column, int page) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); u32 pagemask = chip->pagemask; if (column != -1) { @@ -281,7 +281,7 @@ static void mpc5121_nfc_select_chip(struct mtd_info *mtd, int chip) /* Init external chip select logic on ADS5121 board */ static int ads5121_chipselect_init(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct mpc5121_nfc_prv *prv = chip->priv; struct device_node *dn; @@ -303,7 +303,7 @@ static int ads5121_chipselect_init(struct mtd_info *mtd) /* Control chips select signal on ADS5121 board */ static void ads5121_select_chip(struct mtd_info *mtd, int chip) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct mpc5121_nfc_prv *prv = nand->priv; u8 v; @@ -333,7 +333,7 @@ static int mpc5121_nfc_dev_ready(struct mtd_info *mtd) static void mpc5121_nfc_command(struct mtd_info *mtd, unsigned command, int column, int page) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct mpc5121_nfc_prv *prv = chip->priv; prv->column = (column >= 0) ? column : 0; @@ -406,7 +406,7 @@ static void mpc5121_nfc_command(struct mtd_info *mtd, unsigned command, static void mpc5121_nfc_copy_spare(struct mtd_info *mtd, uint offset, u8 *buffer, uint size, int wr) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct mpc5121_nfc_prv *prv = nand->priv; uint o, s, sbsize, blksize; @@ -458,7 +458,7 @@ static void mpc5121_nfc_copy_spare(struct mtd_info *mtd, uint offset, static void mpc5121_nfc_buf_copy(struct mtd_info *mtd, u_char *buf, int len, int wr) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct mpc5121_nfc_prv *prv = chip->priv; uint c = prv->column; uint l; @@ -536,7 +536,7 @@ static u16 mpc5121_nfc_read_word(struct mtd_info *mtd) */ static int mpc5121_nfc_read_hw_config(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct mpc5121_nfc_prv *prv = chip->priv; struct mpc512x_reset_module *rm; struct device_node *rmnode; @@ -615,7 +615,7 @@ out: /* Free driver resources */ static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct mpc5121_nfc_prv *prv = chip->priv; if (prv->clk) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index f507d361b1a6a..b291258bfe7b2 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -532,7 +532,7 @@ static void send_addr_v1_v2(struct mxc_nand_host *host, uint16_t addr, int islas static void send_page_v3(struct mtd_info *mtd, unsigned int ops) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct mxc_nand_host *host = nand_chip->priv; uint32_t tmp; @@ -548,7 +548,7 @@ static void send_page_v3(struct mtd_info *mtd, unsigned int ops) static void send_page_v2(struct mtd_info *mtd, unsigned int ops) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct mxc_nand_host *host = nand_chip->priv; /* NANDFC buffer 0 is used for page read/write */ @@ -562,7 +562,7 @@ static void send_page_v2(struct mtd_info *mtd, unsigned int ops) static void send_page_v1(struct mtd_info *mtd, unsigned int ops) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct mxc_nand_host *host = nand_chip->priv; int bufs, i; @@ -663,7 +663,7 @@ static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode) static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct mxc_nand_host *host = nand_chip->priv; /* @@ -684,7 +684,7 @@ static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat, static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct mxc_nand_host *host = nand_chip->priv; u32 ecc_stat, err; int no_subpages = 1; @@ -722,7 +722,7 @@ static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, static u_char mxc_nand_read_byte(struct mtd_info *mtd) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct mxc_nand_host *host = nand_chip->priv; uint8_t ret; @@ -746,7 +746,7 @@ static u_char mxc_nand_read_byte(struct mtd_info *mtd) static uint16_t mxc_nand_read_word(struct mtd_info *mtd) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct mxc_nand_host *host = nand_chip->priv; uint16_t ret; @@ -762,7 +762,7 @@ static uint16_t mxc_nand_read_word(struct mtd_info *mtd) static void mxc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct mxc_nand_host *host = nand_chip->priv; u16 col = host->buf_start; int n = mtd->oobsize + mtd->writesize - col; @@ -780,7 +780,7 @@ static void mxc_nand_write_buf(struct mtd_info *mtd, */ static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct mxc_nand_host *host = nand_chip->priv; u16 col = host->buf_start; int n = mtd->oobsize + mtd->writesize - col; @@ -796,7 +796,7 @@ static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) * deselect of the NAND chip */ static void mxc_nand_select_chip_v1_v3(struct mtd_info *mtd, int chip) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct mxc_nand_host *host = nand_chip->priv; if (chip == -1) { @@ -817,7 +817,7 @@ static void mxc_nand_select_chip_v1_v3(struct mtd_info *mtd, int chip) static void mxc_nand_select_chip_v2(struct mtd_info *mtd, int chip) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct mxc_nand_host *host = nand_chip->priv; if (chip == -1) { @@ -850,7 +850,7 @@ static void mxc_nand_select_chip_v2(struct mtd_info *mtd, int chip) */ static void copy_spare(struct mtd_info *mtd, bool bfrom) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct mxc_nand_host *host = this->priv; u16 i, oob_chunk_size; u16 num_chunks = mtd->writesize / 512; @@ -893,7 +893,7 @@ static void copy_spare(struct mtd_info *mtd, bool bfrom) */ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct mxc_nand_host *host = nand_chip->priv; /* Write out column address, if necessary */ @@ -979,7 +979,7 @@ static void ecc_8bit_layout_4k(struct nand_ecclayout *layout) static void preset_v1(struct mtd_info *mtd) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct mxc_nand_host *host = nand_chip->priv; uint16_t config1 = 0; @@ -1007,7 +1007,7 @@ static void preset_v1(struct mtd_info *mtd) static void preset_v2(struct mtd_info *mtd) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct mxc_nand_host *host = nand_chip->priv; uint16_t config1 = 0; @@ -1053,7 +1053,7 @@ static void preset_v2(struct mtd_info *mtd) static void preset_v3(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct mxc_nand_host *host = chip->priv; uint32_t config2, config3; int i, addr_phases; @@ -1124,7 +1124,7 @@ static void preset_v3(struct mtd_info *mtd) static void mxc_nand_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct mxc_nand_host *host = nand_chip->priv; pr_debug("mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n", diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 69658584061b4..d8a23b052d501 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -48,7 +48,7 @@ static struct ndfc_controller ndfc_ctrl[NDFC_MAX_CS]; static void ndfc_select_chip(struct mtd_info *mtd, int chip) { uint32_t ccr; - struct nand_chip *nchip = mtd->priv; + struct nand_chip *nchip = mtd_to_nand(mtd); struct ndfc_controller *ndfc = nchip->priv; ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); @@ -62,7 +62,7 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip) static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct ndfc_controller *ndfc = chip->priv; if (cmd == NAND_CMD_NONE) @@ -76,7 +76,7 @@ static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) static int ndfc_ready(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct ndfc_controller *ndfc = chip->priv; return in_be32(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY; @@ -85,7 +85,7 @@ static int ndfc_ready(struct mtd_info *mtd) static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) { uint32_t ccr; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct ndfc_controller *ndfc = chip->priv; ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); @@ -97,7 +97,7 @@ static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) static int ndfc_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct ndfc_controller *ndfc = chip->priv; uint32_t ecc; uint8_t *p = (uint8_t *)&ecc; @@ -121,7 +121,7 @@ static int ndfc_calculate_ecc(struct mtd_info *mtd, */ static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct ndfc_controller *ndfc = chip->priv; uint32_t *p = (uint32_t *) buf; @@ -131,7 +131,7 @@ static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct ndfc_controller *ndfc = chip->priv; uint32_t *p = (uint32_t *) buf; diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/nuc900_nand.c index f0687f71fbd89..8148cd6896784 100644 --- a/drivers/mtd/nand/nuc900_nand.c +++ b/drivers/mtd/nand/nuc900_nand.c @@ -136,7 +136,7 @@ static int nuc900_nand_devready(struct mtd_info *mtd) static void nuc900_nand_command_lp(struct mtd_info *mtd, unsigned int command, int column, int page_addr) { - register struct nand_chip *chip = mtd->priv; + register struct nand_chip *chip = mtd_to_nand(mtd); struct nuc900_nand *nand; nand = container_of(mtd, struct nuc900_nand, mtd); diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index e307576f300b5..944a74e7a5130 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -270,7 +270,7 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) */ static void omap_read_buf8(struct mtd_info *mtd, u_char *buf, int len) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); ioread8_rep(nand->IO_ADDR_R, buf, len); } @@ -306,7 +306,7 @@ static void omap_write_buf8(struct mtd_info *mtd, const u_char *buf, int len) */ static void omap_read_buf16(struct mtd_info *mtd, u_char *buf, int len) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); ioread16_rep(nand->IO_ADDR_R, buf, len / 2); } @@ -955,7 +955,7 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) { struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0; u32 val; @@ -1001,7 +1001,7 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) */ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); unsigned long timeo = jiffies; @@ -1061,7 +1061,7 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info *mtd, int mode) struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); enum omap_ecc ecc_opt = info->ecc_opt; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); u32 val, wr_mode; unsigned int ecc_size1, ecc_size0; @@ -2056,7 +2056,7 @@ return_error: static int omap_nand_remove(struct platform_device *pdev) { struct mtd_info *mtd = platform_get_drvdata(pdev); - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); if (nand_chip->ecc.priv) { diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 5c214161244a0..4ed4f676ee05d 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -25,7 +25,7 @@ static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *nc = mtd->priv; + struct nand_chip *nc = mtd_to_nand(mtd); struct orion_nand_data *board = nc->priv; u32 offs; @@ -47,7 +47,7 @@ static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); void __iomem *io_base = chip->IO_ADDR_R; uint64_t *buf64; int i = 0; diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 83cf021b96512..0ececac2020fb 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c @@ -45,7 +45,7 @@ static const char driver_name[] = "pasemi-nand"; static void pasemi_read_buf(struct mtd_info *mtd, u_char *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); while (len > 0x800) { memcpy_fromio(buf, chip->IO_ADDR_R, 0x800); @@ -57,7 +57,7 @@ static void pasemi_read_buf(struct mtd_info *mtd, u_char *buf, int len) static void pasemi_write_buf(struct mtd_info *mtd, const u_char *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); while (len > 0x800) { memcpy_toio(chip->IO_ADDR_R, buf, 0x800); @@ -70,7 +70,7 @@ static void pasemi_write_buf(struct mtd_info *mtd, const u_char *buf, int len) static void pasemi_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); if (cmd == NAND_CMD_NONE) return; @@ -192,7 +192,7 @@ static int pasemi_nand_remove(struct platform_device *ofdev) if (!pasemi_nand_mtd) return 0; - chip = pasemi_nand_mtd->priv; + chip = mtd_to_nand(pasemi_nand_mtd); /* Release resources, unregister device */ nand_release(pasemi_nand_mtd); diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index bdbc2c231ceb2..dc39a9847bf5e 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -1113,7 +1113,7 @@ static int prepare_set_command(struct pxa3xx_nand_info *info, int command, static void nand_cmdfunc(struct mtd_info *mtd, unsigned command, int column, int page_addr) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct pxa3xx_nand_host *host = chip->priv; struct pxa3xx_nand_info *info = host->info_data; int exec_cmd; @@ -1162,7 +1162,7 @@ static void nand_cmdfunc_extended(struct mtd_info *mtd, const unsigned command, int column, int page_addr) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct pxa3xx_nand_host *host = chip->priv; struct pxa3xx_nand_info *info = host->info_data; int exec_cmd, ext_cmd_type; @@ -1309,7 +1309,7 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct pxa3xx_nand_host *host = chip->priv; struct pxa3xx_nand_info *info = host->info_data; char retval = 0xFF; @@ -1323,7 +1323,7 @@ static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) static u16 pxa3xx_nand_read_word(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct pxa3xx_nand_host *host = chip->priv; struct pxa3xx_nand_info *info = host->info_data; u16 retval = 0xFFFF; @@ -1337,7 +1337,7 @@ static u16 pxa3xx_nand_read_word(struct mtd_info *mtd) static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct pxa3xx_nand_host *host = chip->priv; struct pxa3xx_nand_info *info = host->info_data; int real_len = min_t(size_t, len, info->buf_count - info->buf_start); @@ -1349,7 +1349,7 @@ static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static void pxa3xx_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct pxa3xx_nand_host *host = chip->priv; struct pxa3xx_nand_info *info = host->info_data; int real_len = min_t(size_t, len, info->buf_count - info->buf_start); @@ -1365,7 +1365,7 @@ static void pxa3xx_nand_select_chip(struct mtd_info *mtd, int chip) static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct pxa3xx_nand_host *host = chip->priv; struct pxa3xx_nand_info *info = host->info_data; @@ -1416,7 +1416,7 @@ static void pxa3xx_nand_config_tail(struct pxa3xx_nand_info *info) { struct pxa3xx_nand_host *host = info->host[info->cs]; struct mtd_info *mtd = host->mtd; - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); info->reg_ndcr |= (host->col_addr_cycles == 2) ? NDCR_RA_START : 0; info->reg_ndcr |= (chip->page_shift == 6) ? NDCR_PG_PER_BLK : 0; @@ -1572,7 +1572,7 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info, static int pxa3xx_nand_scan(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct pxa3xx_nand_host *host = chip->priv; struct pxa3xx_nand_info *info = host->info_data; struct platform_device *pdev = info->pdev; diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index be28cddec9cdf..ca05b20c017fd 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c @@ -64,7 +64,7 @@ static inline void r852_write_reg_dword(struct r852_device *dev, /* returns pointer to our private structure */ static inline struct r852_device *r852_get_dev(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); return chip->priv; } diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 05105cadd0db9..e658b2988acfd 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -382,7 +382,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) { struct s3c2410_nand_info *info; struct s3c2410_nand_mtd *nmtd; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); unsigned long cur; nmtd = this->priv; @@ -634,7 +634,7 @@ static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); readsb(this->IO_ADDR_R, buf, len); } @@ -656,7 +656,7 @@ static void s3c2440_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); writesb(this->IO_ADDR_W, buf, len); } diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index 082b6009736d9..84129e5399301 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c @@ -66,7 +66,7 @@ static void sharpsl_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct sharpsl_nand *sharpsl = mtd_to_sharpsl(mtd); - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); if (ctrl & NAND_CTRL_CHANGE) { unsigned char bits = ctrl & 0x07; diff --git a/drivers/mtd/nand/sm_common.c b/drivers/mtd/nand/sm_common.c index e06b5e5d3287d..c514740f9a833 100644 --- a/drivers/mtd/nand/sm_common.c +++ b/drivers/mtd/nand/sm_common.c @@ -102,7 +102,7 @@ static struct nand_flash_dev nand_xd_flash_ids[] = { int sm_register_device(struct mtd_info *mtd, int smartmedia) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); int ret; chip->options |= NAND_SKIP_BBTSCAN; diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c index bde40433b4d9f..2dfb1e0d815a7 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/socrates_nand.c @@ -45,7 +45,7 @@ static void socrates_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { int i; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct socrates_nand_host *host = this->priv; for (i = 0; i < len; i++) { @@ -64,7 +64,7 @@ static void socrates_nand_write_buf(struct mtd_info *mtd, static void socrates_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { int i; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); struct socrates_nand_host *host = this->priv; uint32_t val; @@ -105,7 +105,7 @@ static uint16_t socrates_nand_read_word(struct mtd_info *mtd) static void socrates_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct socrates_nand_host *host = nand_chip->priv; uint32_t val; @@ -130,7 +130,7 @@ static void socrates_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, */ static int socrates_nand_device_ready(struct mtd_info *mtd) { - struct nand_chip *nand_chip = mtd->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); struct socrates_nand_host *host = nand_chip->priv; if (in_be32(host->io_base) & FPGA_NAND_BUSY) diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index 1bbcc0c2aab51..4ecd486011822 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c @@ -350,7 +350,7 @@ static int sunxi_nfc_rst(struct sunxi_nfc *nfc) static int sunxi_nfc_dev_ready(struct mtd_info *mtd) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); struct sunxi_nand_rb *rb; @@ -388,7 +388,7 @@ static int sunxi_nfc_dev_ready(struct mtd_info *mtd) static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); struct sunxi_nand_chip_sel *sel; @@ -433,7 +433,7 @@ static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip) static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); int ret; @@ -466,7 +466,7 @@ static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); int ret; @@ -507,7 +507,7 @@ static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd) static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); int ret; @@ -541,7 +541,7 @@ static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat, static void sunxi_nfc_hw_ecc_enable(struct mtd_info *mtd) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); struct sunxi_nand_hw_ecc *data = nand->ecc.priv; u32 ecc_ctl; @@ -556,7 +556,7 @@ static void sunxi_nfc_hw_ecc_enable(struct mtd_info *mtd) static void sunxi_nfc_hw_ecc_disable(struct mtd_info *mtd) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_ECC_EN, @@ -577,7 +577,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd, int *cur_off, unsigned int *max_bitflips) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); struct nand_ecc_ctrl *ecc = &nand->ecc; u32 status; @@ -638,7 +638,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd, static void sunxi_nfc_hw_ecc_read_extra_oob(struct mtd_info *mtd, u8 *oob, int *cur_off) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct nand_ecc_ctrl *ecc = &nand->ecc; int offset = ((ecc->bytes + 4) * ecc->steps); int len = mtd->oobsize - offset; @@ -665,7 +665,7 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd, const u8 *oob, int oob_off, int *cur_off) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); struct nand_ecc_ctrl *ecc = &nand->ecc; int ret; @@ -702,7 +702,7 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd, static void sunxi_nfc_hw_ecc_write_extra_oob(struct mtd_info *mtd, u8 *oob, int *cur_off) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct nand_ecc_ctrl *ecc = &nand->ecc; int offset = ((ecc->bytes + 4) * ecc->steps); int len = mtd->oobsize - offset; @@ -1031,7 +1031,7 @@ static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd, struct device_node *np) { static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 }; - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); struct sunxi_nand_hw_ecc *data; @@ -1189,7 +1189,7 @@ static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc) static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc, struct device_node *np) { - struct nand_chip *nand = mtd->priv; + struct nand_chip *nand = mtd_to_nand(mtd); int ret; if (!ecc->size) { diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c index befddf0776e4c..6d0cbe90b1b2d 100644 --- a/drivers/mtd/nand/tmio_nand.c +++ b/drivers/mtd/nand/tmio_nand.c @@ -128,7 +128,7 @@ static void tmio_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct tmio_nand *tmio = mtd_to_tmio(mtd); - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); if (ctrl & NAND_CTRL_CHANGE) { u8 mode; diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c index 8572519b8441b..ff9afb1eb3adb 100644 --- a/drivers/mtd/nand/txx9ndfmc.c +++ b/drivers/mtd/nand/txx9ndfmc.c @@ -79,7 +79,7 @@ struct txx9ndfmc_drvdata { static struct platform_device *mtd_to_platdev(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct txx9ndfmc_priv *txx9_priv = chip->priv; return txx9_priv->dev; } @@ -135,7 +135,7 @@ static void txx9ndfmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static void txx9ndfmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); struct txx9ndfmc_priv *txx9_priv = chip->priv; struct platform_device *dev = txx9_priv->dev; struct txx9ndfmc_platform_data *plat = dev_get_platdata(&dev->dev); @@ -175,7 +175,7 @@ static int txx9ndfmc_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat, uint8_t *ecc_code) { struct platform_device *dev = mtd_to_platdev(mtd); - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); int eccbytes; u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR); @@ -195,7 +195,7 @@ static int txx9ndfmc_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat, static int txx9ndfmc_correct_data(struct mtd_info *mtd, unsigned char *buf, unsigned char *read_ecc, unsigned char *calc_ecc) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); int eccsize; int corrected = 0; int stat; @@ -257,7 +257,7 @@ static void txx9ndfmc_initialize(struct platform_device *dev) static int txx9ndfmc_nand_scan(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); int ret; ret = nand_scan_ident(mtd, 1, NULL); @@ -391,7 +391,7 @@ static int __exit txx9ndfmc_remove(struct platform_device *dev) if (!mtd) continue; - chip = mtd->priv; + chip = mtd_to_nand(mtd); txx9_priv = chip->priv; nand_release(mtd); diff --git a/drivers/mtd/nand/xway_nand.c b/drivers/mtd/nand/xway_nand.c index 3b28db458ea04..0cf0ac07a8c25 100644 --- a/drivers/mtd/nand/xway_nand.c +++ b/drivers/mtd/nand/xway_nand.c @@ -89,7 +89,7 @@ static void xway_select_chip(struct mtd_info *mtd, int chip) static void xway_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); unsigned long nandaddr = (unsigned long) this->IO_ADDR_W; unsigned long flags; @@ -118,7 +118,7 @@ static int xway_dev_ready(struct mtd_info *mtd) static unsigned char xway_read_byte(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); unsigned long nandaddr = (unsigned long) this->IO_ADDR_R; unsigned long flags; int ret; -- GitLab From ed4f85c03cc7460a2f76afb73c22b8894b44ee20 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Tue, 1 Dec 2015 12:03:06 +0100 Subject: [PATCH 1020/2855] mtd: nand: embed an mtd_info structure into nand_chip Currently all NAND controller drivers are providing both the mtd_info and nand_chip struct and then let the NAND subsystem to initialize a few things before registering the mtd instance to the MTD layer. Embed an mtd_info field into nand_chip to add some consistency to all NAND controller drivers. This change will also help factorizing boilerplate code copied in all NAND drivers. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index fad634ea16857..d6710575ddb63 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -540,6 +540,7 @@ struct nand_buffers { /** * struct nand_chip - NAND Private Flash Chip Data + * @mtd: MTD device registered to the MTD framework * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the * flash device * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the @@ -640,6 +641,7 @@ struct nand_buffers { */ struct nand_chip { + struct mtd_info mtd; void __iomem *IO_ADDR_R; void __iomem *IO_ADDR_W; -- GitLab From ffd014f43fdcb6edb5a7f302de1e717e8c0673d5 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Tue, 1 Dec 2015 12:03:07 +0100 Subject: [PATCH 1021/2855] mtd: nand: add nand_to_mtd() helper Add a new helper to retrieve the MTD device attached to a NAND chip. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index d6710575ddb63..b614ed2105ac8 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -737,6 +737,11 @@ static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd) return mtd->priv; } +static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip) +{ + return &chip->mtd; +} + /* * NAND Flash Manufacturer ID Codes */ -- GitLab From 04104422bce2693d07001dc4efb5cb935c5053bb Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Tue, 1 Dec 2015 12:03:00 +0100 Subject: [PATCH 1022/2855] cris: nand: make use of mtd_to_nand() where appropriate mtd_to_nand() was recently introduced to avoid direct accesses to the mtd->priv field. Update all CRIS specific implementations to use this helper. Signed-off-by: Boris Brezillon Acked-by: Brian Norris Acked-by: Jesper Nilsson Signed-off-by: Brian Norris --- arch/cris/arch-v32/drivers/mach-a3/nandflash.c | 2 +- arch/cris/arch-v32/drivers/mach-fs/nandflash.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c index 7fb52128ddc90..db953cfabee11 100644 --- a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c +++ b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c @@ -52,7 +52,7 @@ static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd, { unsigned long flags; reg_pio_rw_dout dout; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); local_irq_save(flags); diff --git a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c index e03238454b0ee..22a6467ffe1f1 100644 --- a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c +++ b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c @@ -51,7 +51,7 @@ static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd, { unsigned long flags; reg_gio_rw_pa_dout dout; - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); local_irq_save(flags); -- GitLab From 4d17a89252ffb58c58f8b39d974ffd8231c33e85 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Tue, 1 Dec 2015 12:02:59 +0100 Subject: [PATCH 1023/2855] blackfin: nand: make use of mtd_to_nand() where appropriate mtd_to_nand() was recently introduced to avoid direct accesses to the mtd->priv field. Update all blackfin specific implementations to use this helper. Signed-off-by: Boris Brezillon Acked-by: Brian Norris Signed-off-by: Brian Norris --- arch/blackfin/mach-bf537/boards/stamp.c | 2 +- arch/blackfin/mach-bf561/boards/acvilon.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 88a19fc9844d8..c181543a399aa 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -404,7 +404,7 @@ static struct mtd_partition bfin_plat_nand_partitions[] = { #define BFIN_NAND_PLAT_ALE 1 static void bfin_plat_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); if (cmd == NAND_CMD_NONE) return; diff --git a/arch/blackfin/mach-bf561/boards/acvilon.c b/arch/blackfin/mach-bf561/boards/acvilon.c index 6ab951534d790..37f8f25a1347f 100644 --- a/arch/blackfin/mach-bf561/boards/acvilon.c +++ b/arch/blackfin/mach-bf561/boards/acvilon.c @@ -267,7 +267,7 @@ static struct mtd_partition bfin_plat_nand_partitions[] = { static void bfin_plat_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); if (cmd == NAND_CMD_NONE) return; -- GitLab From b1afda0e336f3b65e1dc765e3405d3231d9782fe Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Tue, 1 Dec 2015 12:03:01 +0100 Subject: [PATCH 1024/2855] mips: nand: make use of mtd_to_nand() where appropriate mtd_to_nand() was recently introduced to avoid direct accesses to the mtd->priv field. Update all MIPS specific implementations to use this helper. Signed-off-by: Boris Brezillon Acked-by: Brian Norris Signed-off-by: Brian Norris --- arch/mips/alchemy/devboards/db1200.c | 2 +- arch/mips/alchemy/devboards/db1300.c | 2 +- arch/mips/alchemy/devboards/db1550.c | 2 +- arch/mips/pnx833x/common/platform.c | 2 +- arch/mips/rb532/devices.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c index 8c13675a12e74..992442a03d8ba 100644 --- a/arch/mips/alchemy/devboards/db1200.c +++ b/arch/mips/alchemy/devboards/db1200.c @@ -200,7 +200,7 @@ static struct i2c_board_info db1200_i2c_devs[] __initdata = { static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); unsigned long ioaddr = (unsigned long)this->IO_ADDR_W; ioaddr &= 0xffffff00; diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c index b58077008a538..d3c087f59f1a9 100644 --- a/arch/mips/alchemy/devboards/db1300.c +++ b/arch/mips/alchemy/devboards/db1300.c @@ -150,7 +150,7 @@ static void __init db1300_gpio_config(void) static void au1300_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); unsigned long ioaddr = (unsigned long)this->IO_ADDR_W; ioaddr &= 0xffffff00; diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c index 5740bcfdfc7f6..b518f029f5e7b 100644 --- a/arch/mips/alchemy/devboards/db1550.c +++ b/arch/mips/alchemy/devboards/db1550.c @@ -128,7 +128,7 @@ static struct i2c_board_info db1550_i2c_devs[] __initdata = { static void au1550_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); unsigned long ioaddr = (unsigned long)this->IO_ADDR_W; ioaddr &= 0xffffff00; diff --git a/arch/mips/pnx833x/common/platform.c b/arch/mips/pnx833x/common/platform.c index b4b774bc31788..3cd357737a267 100644 --- a/arch/mips/pnx833x/common/platform.c +++ b/arch/mips/pnx833x/common/platform.c @@ -180,7 +180,7 @@ static struct platform_device pnx833x_sata_device = { static void pnx833x_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd_to_nand(mtd); unsigned long nandaddr = (unsigned long)this->IO_ADDR_W; if (cmd == NAND_CMD_NONE) diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c index 9bd7a2de0765f..0966adccf5200 100644 --- a/arch/mips/rb532/devices.c +++ b/arch/mips/rb532/devices.c @@ -148,7 +148,7 @@ static int rb532_dev_ready(struct mtd_info *mtd) static void rb532_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); unsigned char orbits, nandbits; if (ctrl & NAND_CTRL_CHANGE) { -- GitLab From bd26d0d0ce7434a86dde61a7c65c94fe3801d8f6 Mon Sep 17 00:00:00 2001 From: Dmitry Krivenok Date: Wed, 2 Dec 2015 00:48:12 +0300 Subject: [PATCH 1025/2855] nvdimm: improve diagnosibility of namespaces In order to bind namespace to the driver user must first set all mandatory attributes in the following order: - uuid - size - sector_size (for blk namespace only) If the order is wrong, then user either won't be able to set the attribute or bind the namespace. This simple patch improves diagnosibility of common operations with namespaces by printing some details about the error instead of failing silently. Below are examples of error messages (assuming dyndbg is enabled for nvdimms): [/]# echo 4194304 > /sys/bus/nd/devices/region5/namespace5.0/size [ 288.372612] nd namespace5.0: __size_store: uuid not set [ 288.374839] nd namespace5.0: size_store: 400000 fail (-6) sh: write error: No such device or address [/]# [/]# echo namespace5.0 > /sys/bus/nd/drivers/nd_blk/bind [ 554.671648] nd_blk namespace5.0: nvdimm_namespace_common_probe: sector size not set [ 554.674688] ndbus1: nd_blk.probe(namespace5.0) = -19 sh: write error: No such device [/]# Signed-off-by: Dmitry V. Krivenok Signed-off-by: Dan Williams --- drivers/nvdimm/namespace_devs.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index 0955b2cb10fe8..f981177524a19 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -791,6 +791,15 @@ static void nd_namespace_pmem_set_size(struct nd_region *nd_region, res->end = nd_region->ndr_start + size - 1; } +static bool uuid_not_set(const u8 *uuid, struct device *dev, const char *where) +{ + if (!uuid) { + dev_dbg(dev, "%s: uuid not set\n", where); + return true; + } + return false; +} + static ssize_t __size_store(struct device *dev, unsigned long long val) { resource_size_t allocated = 0, available = 0; @@ -820,8 +829,12 @@ static ssize_t __size_store(struct device *dev, unsigned long long val) * We need a uuid for the allocation-label and dimm(s) on which * to store the label. */ - if (!uuid || nd_region->ndr_mappings == 0) + if (uuid_not_set(uuid, dev, __func__)) return -ENXIO; + if (nd_region->ndr_mappings == 0) { + dev_dbg(dev, "%s: not associated with dimm(s)\n", __func__); + return -ENXIO; + } div_u64_rem(val, SZ_4K * nd_region->ndr_mappings, &remainder); if (remainder) { @@ -1343,14 +1356,19 @@ struct nd_namespace_common *nvdimm_namespace_common_probe(struct device *dev) struct nd_namespace_pmem *nspm; nspm = to_nd_namespace_pmem(&ndns->dev); - if (!nspm->uuid) { - dev_dbg(&ndns->dev, "%s: uuid not set\n", __func__); + if (uuid_not_set(nspm->uuid, &ndns->dev, __func__)) return ERR_PTR(-ENODEV); - } } else if (is_namespace_blk(&ndns->dev)) { struct nd_namespace_blk *nsblk; nsblk = to_nd_namespace_blk(&ndns->dev); + if (uuid_not_set(nsblk->uuid, &ndns->dev, __func__)) + return ERR_PTR(-ENODEV); + if (!nsblk->lbasize) { + dev_dbg(&ndns->dev, "%s: sector size not set\n", + __func__); + return ERR_PTR(-ENODEV); + } if (!nd_namespace_blk_validate(nsblk)) return ERR_PTR(-ENODEV); } -- GitLab From 6bb691ac089c39bb0aa73bdcc21ffd8c846e4ba5 Mon Sep 17 00:00:00 2001 From: Dmitry Krivenok Date: Wed, 2 Dec 2015 09:39:29 +0300 Subject: [PATCH 1026/2855] nvdimm: do not show pfn_seed for non pmem regions This simple change hides pfn_seed attribute for non pmem regions because they don't support pfn anyway. Signed-off-by: Dmitry V. Krivenok Signed-off-by: Dan Williams --- drivers/nvdimm/region_devs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index 529f3f02e7b2d..3d730d1f25db5 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c @@ -406,6 +406,9 @@ static umode_t region_visible(struct kobject *kobj, struct attribute *a, int n) struct nd_interleave_set *nd_set = nd_region->nd_set; int type = nd_region_to_nstype(nd_region); + if (!is_nd_pmem(dev) && a == &dev_attr_pfn_seed.attr) + return 0; + if (a != &dev_attr_set_cookie.attr && a != &dev_attr_available_size.attr) return a->mode; -- GitLab From 80609448cd63b700a37427e423c201fc5e16e95a Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 4 Dec 2015 16:51:13 -0800 Subject: [PATCH 1027/2855] f2fs: enhance the bit operation for SSR This patch enhances the existing bit operation when f2fs allocates SSR blocks. Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/segment.c | 50 +++++++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 74c474821e5a1..5fa519f028602 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -132,47 +132,37 @@ static unsigned long __find_rev_next_zero_bit(const unsigned long *addr, unsigned long size, unsigned long offset) { const unsigned long *p = addr + BIT_WORD(offset); - unsigned long result = offset & ~(BITS_PER_LONG - 1); + unsigned long result = size; unsigned long tmp; if (offset >= size) return size; - size -= result; + size -= (offset & ~(BITS_PER_LONG - 1)); offset %= BITS_PER_LONG; - if (!offset) - goto aligned; - - tmp = __reverse_ulong((unsigned char *)p); - tmp |= ~((~0UL << offset) >> offset); - - if (size < BITS_PER_LONG) - goto found_first; - if (tmp != ~0UL) - goto found_middle; - - size -= BITS_PER_LONG; - result += BITS_PER_LONG; - p++; -aligned: - while (size & ~(BITS_PER_LONG - 1)) { + + while (1) { + if (*p == ~0UL) + goto pass; + tmp = __reverse_ulong((unsigned char *)p); + + if (offset) + tmp |= ~0UL << (BITS_PER_LONG - offset); + if (size < BITS_PER_LONG) + tmp |= ~0UL >> size; if (tmp != ~0UL) - goto found_middle; - result += BITS_PER_LONG; + goto found; +pass: + if (size <= BITS_PER_LONG) + break; size -= BITS_PER_LONG; + offset = 0; p++; } - if (!size) - return result; - - tmp = __reverse_ulong((unsigned char *)p); -found_first: - tmp |= ~(~0UL << (BITS_PER_LONG - size)); - if (tmp == ~0UL) /* Are any bits zero? */ - return result + size; /* Nope. */ -found_middle: - return result + __reverse_ffz(tmp); + return result; +found: + return result - size + __reverse_ffz(tmp); } void register_inmem_page(struct inode *inode, struct page *page) -- GitLab From 5d909cdbbba244ecb4c2dfc4dc3e3bc29529fb05 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 7 Dec 2015 10:16:58 -0800 Subject: [PATCH 1028/2855] f2fs: refactor f2fs_commit_super Previously, f2fs_commit_super hacks the bh->blocknr to write the broken alternate superblock. Instead of it, we should use the correct logic to retrieve its buffer head with locking it appropriately. Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/super.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index bd7e9c6c42c80..dbf16ade0e9a7 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1099,27 +1099,35 @@ out: int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover) { struct buffer_head *sbh = sbi->raw_super_buf; - sector_t block = sbh->b_blocknr; + struct buffer_head *bh; int err; /* write back-up superblock first */ - sbh->b_blocknr = block ? 0 : 1; - mark_buffer_dirty(sbh); - err = sync_dirty_buffer(sbh); + bh = sb_getblk(sbi->sb, sbh->b_blocknr ? 0 : 1); + if (!bh) + return -EIO; - sbh->b_blocknr = block; + lock_buffer(bh); + memcpy(bh->b_data, sbh->b_data, sbh->b_size); + WARN_ON(sbh->b_size != F2FS_BLKSIZE); + set_buffer_uptodate(bh); + set_buffer_dirty(bh); + unlock_buffer(bh); + + /* it's rare case, we can do fua all the time */ + err = __sync_dirty_buffer(bh, WRITE_FLUSH_FUA); + brelse(bh); /* if we are in recovery path, skip writing valid superblock */ if (recover || err) - goto out; + return err; /* write current valid superblock */ - mark_buffer_dirty(sbh); - err = sync_dirty_buffer(sbh); -out: - clear_buffer_write_io_error(sbh); - set_buffer_uptodate(sbh); - return err; + lock_buffer(sbh); + set_buffer_dirty(sbh); + unlock_buffer(sbh); + + return __sync_dirty_buffer(sbh, WRITE_FLUSH_FUA); } static int f2fs_fill_super(struct super_block *sb, void *data, int silent) -- GitLab From ea212a4a7a432e0ecd0f0f53971b70172b3e7f96 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 7 Dec 2015 10:18:54 -0800 Subject: [PATCH 1029/2855] f2fs: use lock_buffer when changing superblock When modifying sb contents, we need to use lock its buffer. Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index a018ed327713b..294e71576cec9 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1591,14 +1591,18 @@ static int f2fs_ioc_get_encryption_pwsalt(struct file *filp, unsigned long arg) return err; /* update superblock with uuid */ + lock_buffer(sbi->raw_super_buf); generate_random_uuid(sbi->raw_super->encrypt_pw_salt); + unlock_buffer(sbi->raw_super_buf); err = f2fs_commit_super(sbi, false); mnt_drop_write_file(filp); if (err) { /* undo new data */ + lock_buffer(sbi->raw_super_buf); memset(sbi->raw_super->encrypt_pw_salt, 0, 16); + unlock_buffer(sbi->raw_super_buf); return err; } got_it: -- GitLab From c3168d26c8deea4cc0202bb19341ab55247c3941 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 4 Dec 2015 15:25:13 -0800 Subject: [PATCH 1030/2855] mtd: ofpart: assign return argument exactly once It's easier to refactor these parsers if the return value gets assigned only once, just like every other MTD partition parser. This prepares for making the second arg to the parse_fn() const. This is OK if we construct the partitions completely first, and assign them to the return pointer only after we're done modifying them. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- drivers/mtd/ofpart.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index 904645143397a..c7df2f1dd6b8d 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c @@ -29,6 +29,7 @@ static int parse_ofpart_partitions(struct mtd_info *master, struct mtd_partition **pparts, struct mtd_part_parser_data *data) { + struct mtd_partition *parts; struct device_node *mtd_node; struct device_node *ofpart_node; const char *partname; @@ -70,8 +71,8 @@ static int parse_ofpart_partitions(struct mtd_info *master, if (nr_parts == 0) return 0; - *pparts = kzalloc(nr_parts * sizeof(**pparts), GFP_KERNEL); - if (!*pparts) + parts = kzalloc(nr_parts * sizeof(*parts), GFP_KERNEL); + if (!parts) return -ENOMEM; i = 0; @@ -105,19 +106,19 @@ static int parse_ofpart_partitions(struct mtd_info *master, goto ofpart_fail; } - (*pparts)[i].offset = of_read_number(reg, a_cells); - (*pparts)[i].size = of_read_number(reg + a_cells, s_cells); + parts[i].offset = of_read_number(reg, a_cells); + parts[i].size = of_read_number(reg + a_cells, s_cells); partname = of_get_property(pp, "label", &len); if (!partname) partname = of_get_property(pp, "name", &len); - (*pparts)[i].name = partname; + parts[i].name = partname; if (of_get_property(pp, "read-only", &len)) - (*pparts)[i].mask_flags |= MTD_WRITEABLE; + parts[i].mask_flags |= MTD_WRITEABLE; if (of_get_property(pp, "lock", &len)) - (*pparts)[i].mask_flags |= MTD_POWERUP_LOCK; + parts[i].mask_flags |= MTD_POWERUP_LOCK; i++; } @@ -125,6 +126,7 @@ static int parse_ofpart_partitions(struct mtd_info *master, if (!nr_parts) goto ofpart_none; + *pparts = parts; return nr_parts; ofpart_fail: @@ -133,8 +135,7 @@ ofpart_fail: ret = -EINVAL; ofpart_none: of_node_put(pp); - kfree(*pparts); - *pparts = NULL; + kfree(parts); return ret; } @@ -147,6 +148,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master, struct mtd_partition **pparts, struct mtd_part_parser_data *data) { + struct mtd_partition *parts; struct device_node *dp; int i, plen, nr_parts; const struct { @@ -168,32 +170,33 @@ static int parse_ofoldpart_partitions(struct mtd_info *master, nr_parts = plen / sizeof(part[0]); - *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL); - if (!*pparts) + parts = kzalloc(nr_parts * sizeof(*parts), GFP_KERNEL); + if (!parts) return -ENOMEM; names = of_get_property(dp, "partition-names", &plen); for (i = 0; i < nr_parts; i++) { - (*pparts)[i].offset = be32_to_cpu(part->offset); - (*pparts)[i].size = be32_to_cpu(part->len) & ~1; + parts[i].offset = be32_to_cpu(part->offset); + parts[i].size = be32_to_cpu(part->len) & ~1; /* bit 0 set signifies read only partition */ if (be32_to_cpu(part->len) & 1) - (*pparts)[i].mask_flags = MTD_WRITEABLE; + parts[i].mask_flags = MTD_WRITEABLE; if (names && (plen > 0)) { int len = strlen(names) + 1; - (*pparts)[i].name = names; + parts[i].name = names; plen -= len; names += len; } else { - (*pparts)[i].name = "unnamed"; + parts[i].name = "unnamed"; } part++; } + *pparts = parts; return nr_parts; } -- GitLab From b9adf469f8abb8a66f5795bbd8fe50fe201a14a1 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 4 Dec 2015 15:25:14 -0800 Subject: [PATCH 1031/2855] mtd: partitions: make parsers return 'const' partition arrays We only want to modify these arrays inside the parser "drivers", so the drivers should construct them however they like, then return them as immutable arrays. This will make other refactorings easier. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- drivers/mtd/afs.c | 2 +- drivers/mtd/ar7part.c | 2 +- drivers/mtd/bcm47xxpart.c | 2 +- drivers/mtd/bcm63xxpart.c | 2 +- drivers/mtd/cmdlinepart.c | 2 +- drivers/mtd/ofpart.c | 4 ++-- drivers/mtd/redboot.c | 2 +- include/linux/mtd/partitions.h | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c index e02dae3b739bd..d61b7edfc9382 100644 --- a/drivers/mtd/afs.c +++ b/drivers/mtd/afs.c @@ -162,7 +162,7 @@ afs_read_iis_v1(struct mtd_info *mtd, struct image_info_v1 *iis, u_int ptr) } static int parse_afs_partitions(struct mtd_info *mtd, - struct mtd_partition **pparts, + const struct mtd_partition **pparts, struct mtd_part_parser_data *data) { struct mtd_partition *parts; diff --git a/drivers/mtd/ar7part.c b/drivers/mtd/ar7part.c index 9203b96fd7892..90575deff0ae5 100644 --- a/drivers/mtd/ar7part.c +++ b/drivers/mtd/ar7part.c @@ -43,7 +43,7 @@ struct ar7_bin_rec { }; static int create_mtd_partitions(struct mtd_info *master, - struct mtd_partition **pparts, + const struct mtd_partition **pparts, struct mtd_part_parser_data *data) { struct ar7_bin_rec header; diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index 92a6dd18198be..8282f47bcf5d3 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c @@ -82,7 +82,7 @@ out_default: } static int bcm47xxpart_parse(struct mtd_info *master, - struct mtd_partition **pparts, + const struct mtd_partition **pparts, struct mtd_part_parser_data *data) { struct mtd_partition *parts; diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index cf02135320bce..4409369985932 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c @@ -68,7 +68,7 @@ static int bcm63xx_detect_cfe(struct mtd_info *master) } static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, - struct mtd_partition **pparts, + const struct mtd_partition **pparts, struct mtd_part_parser_data *data) { /* CFE, NVRAM and global Linux are always present */ diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index 420489864bc2d..fbd5affc0acfe 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c @@ -304,7 +304,7 @@ static int mtdpart_setup_real(char *s) * the first one in the chain if a NULL mtd_id is passed in. */ static int parse_cmdline_partitions(struct mtd_info *master, - struct mtd_partition **pparts, + const struct mtd_partition **pparts, struct mtd_part_parser_data *data) { unsigned long long offset; diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index c7df2f1dd6b8d..ede407d6e1068 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c @@ -26,7 +26,7 @@ static bool node_has_compatible(struct device_node *pp) } static int parse_ofpart_partitions(struct mtd_info *master, - struct mtd_partition **pparts, + const struct mtd_partition **pparts, struct mtd_part_parser_data *data) { struct mtd_partition *parts; @@ -145,7 +145,7 @@ static struct mtd_part_parser ofpart_parser = { }; static int parse_ofoldpart_partitions(struct mtd_info *master, - struct mtd_partition **pparts, + const struct mtd_partition **pparts, struct mtd_part_parser_data *data) { struct mtd_partition *parts; diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c index 11c3447eb8ff7..7623ac5fc5865 100644 --- a/drivers/mtd/redboot.c +++ b/drivers/mtd/redboot.c @@ -57,7 +57,7 @@ static inline int redboot_checksum(struct fis_image_desc *img) } static int parse_redboot_partitions(struct mtd_info *master, - struct mtd_partition **pparts, + const struct mtd_partition **pparts, struct mtd_part_parser_data *data) { int nrparts = 0; diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index d002d9b5d7977..6185536daacc0 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -69,7 +69,7 @@ struct mtd_part_parser { struct list_head list; struct module *owner; const char *name; - int (*parse_fn)(struct mtd_info *, struct mtd_partition **, + int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, struct mtd_part_parser_data *); }; -- GitLab From 5531ae4818fb04b9a30f87099f44595c1786f518 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 4 Dec 2015 15:25:15 -0800 Subject: [PATCH 1032/2855] mtd: partitions: rename MTD parser get/put We're going to reuse put_partition_parser(), so let's fix up the prefix naming a bit, to hopefully be more consistent. Also make convert to a true C function instead of a macro. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- drivers/mtd/mtdpart.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index c32b127b19767..4a660ae27bb2e 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -687,7 +687,7 @@ int add_mtd_partitions(struct mtd_info *master, static DEFINE_SPINLOCK(part_parser_lock); static LIST_HEAD(part_parsers); -static struct mtd_part_parser *get_partition_parser(const char *name) +static struct mtd_part_parser *mtd_part_parser_get(const char *name) { struct mtd_part_parser *p, *ret = NULL; @@ -704,7 +704,10 @@ static struct mtd_part_parser *get_partition_parser(const char *name) return ret; } -#define put_partition_parser(p) do { module_put((p)->owner); } while (0) +static inline void mtd_part_parser_put(const struct mtd_part_parser *p) +{ + module_put(p->owner); +} int __register_mtd_parser(struct mtd_part_parser *p, struct module *owner) { @@ -768,9 +771,9 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, for ( ; *types; types++) { pr_debug("%s: parsing partitions %s\n", master->name, *types); - parser = get_partition_parser(*types); + parser = mtd_part_parser_get(*types); if (!parser && !request_module("%s", *types)) - parser = get_partition_parser(*types); + parser = mtd_part_parser_get(*types); pr_debug("%s: got parser %s\n", master->name, parser ? parser->name : NULL); if (!parser) @@ -778,7 +781,7 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, ret = (*parser->parse_fn)(master, pparts, data); pr_debug("%s: parser %s: %i\n", master->name, parser->name, ret); - put_partition_parser(parser); + mtd_part_parser_put(parser); if (ret > 0) { printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", ret, parser->name, master->name); -- GitLab From c42c2710d64381fd48d36b278e0744aa683d93fe Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 4 Dec 2015 15:25:16 -0800 Subject: [PATCH 1033/2855] mtd: partitions: remove kmemdup() The use of kmemdup() complicates the error handling a bit. We don't actually need to allocate new memory, since this reference is treated as const, and it is copied into new memory by the partition registration code anyway. So remove it. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- drivers/mtd/mtdcore.c | 16 +++++++--------- drivers/mtd/mtdcore.h | 2 +- drivers/mtd/mtdpart.c | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 62f83b0509784..868ee52d5063b 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -532,7 +532,7 @@ out_error: } static int mtd_add_device_partitions(struct mtd_info *mtd, - struct mtd_partition *real_parts, + const struct mtd_partition *real_parts, int nbparts) { int ret; @@ -589,16 +589,12 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, int nr_parts) { int ret; - struct mtd_partition *real_parts = NULL; + const struct mtd_partition *real_parts = NULL; ret = parse_mtd_partitions(mtd, types, &real_parts, parser_data); if (ret <= 0 && nr_parts && parts) { - real_parts = kmemdup(parts, sizeof(*parts) * nr_parts, - GFP_KERNEL); - if (!real_parts) - ret = -ENOMEM; - else - ret = nr_parts; + real_parts = parts; + ret = nr_parts; } /* Didn't come up with either parsed OR fallback partitions */ if (ret < 0) { @@ -628,7 +624,9 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, } out: - kfree(real_parts); + /* Cleanup any parsed partitions */ + if (real_parts != parts) + kfree(real_parts); return ret; } EXPORT_SYMBOL_GPL(mtd_device_parse_register); diff --git a/drivers/mtd/mtdcore.h b/drivers/mtd/mtdcore.h index 7b0353399a106..537ec66f9cfd8 100644 --- a/drivers/mtd/mtdcore.h +++ b/drivers/mtd/mtdcore.h @@ -11,7 +11,7 @@ int del_mtd_device(struct mtd_info *mtd); int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); int del_mtd_partitions(struct mtd_info *); int parse_mtd_partitions(struct mtd_info *master, const char * const *types, - struct mtd_partition **pparts, + const struct mtd_partition **pparts, struct mtd_part_parser_data *data); int __init init_mtdchar(void); diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 4a660ae27bb2e..898999c5aea16 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -760,7 +760,7 @@ static const char * const default_mtd_part_types[] = { * point to an array containing this number of &struct mtd_info objects. */ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, - struct mtd_partition **pparts, + const struct mtd_partition **pparts, struct mtd_part_parser_data *data) { struct mtd_part_parser *parser; -- GitLab From 07fd2f871c5e3dfb8ff5eb9c4b44fdb4cf1aeff5 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 4 Dec 2015 15:25:17 -0800 Subject: [PATCH 1034/2855] mtd: partitions: pass around 'mtd_partitions' wrapper struct For some of the core partitioning code, it helps to keep info about the parsed partition (and who parsed them) together in one place. Signed-off-by: Brian Norris --- drivers/mtd/mtdcore.c | 33 +++++++++++++++++++-------------- drivers/mtd/mtdcore.h | 5 ++++- drivers/mtd/mtdpart.c | 15 ++++++++------- include/linux/mtd/partitions.h | 7 +++++++ 4 files changed, 38 insertions(+), 22 deletions(-) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 868ee52d5063b..20b2b38247b6a 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -532,9 +532,10 @@ out_error: } static int mtd_add_device_partitions(struct mtd_info *mtd, - const struct mtd_partition *real_parts, - int nbparts) + struct mtd_partitions *parts) { + const struct mtd_partition *real_parts = parts->parts; + int nbparts = parts->nr_parts; int ret; if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) { @@ -588,23 +589,27 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, const struct mtd_partition *parts, int nr_parts) { + struct mtd_partitions parsed; int ret; - const struct mtd_partition *real_parts = NULL; - ret = parse_mtd_partitions(mtd, types, &real_parts, parser_data); - if (ret <= 0 && nr_parts && parts) { - real_parts = parts; - ret = nr_parts; - } - /* Didn't come up with either parsed OR fallback partitions */ - if (ret < 0) { + memset(&parsed, 0, sizeof(parsed)); + + ret = parse_mtd_partitions(mtd, types, &parsed, parser_data); + if ((ret < 0 || parsed.nr_parts == 0) && parts && nr_parts) { + /* Fall back to driver-provided partitions */ + parsed = (struct mtd_partitions){ + .parts = parts, + .nr_parts = nr_parts, + }; + } else if (ret < 0) { + /* Didn't come up with parsed OR fallback partitions */ pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n", ret); /* Don't abort on errors; we can still use unpartitioned MTD */ - ret = 0; + memset(&parsed, 0, sizeof(parsed)); } - ret = mtd_add_device_partitions(mtd, real_parts, ret); + ret = mtd_add_device_partitions(mtd, &parsed); if (ret) goto out; @@ -625,8 +630,8 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, out: /* Cleanup any parsed partitions */ - if (real_parts != parts) - kfree(real_parts); + if (parsed.parser) + kfree(parsed.parts); return ret; } EXPORT_SYMBOL_GPL(mtd_device_parse_register); diff --git a/drivers/mtd/mtdcore.h b/drivers/mtd/mtdcore.h index 537ec66f9cfd8..ce81cc2002f4d 100644 --- a/drivers/mtd/mtdcore.h +++ b/drivers/mtd/mtdcore.h @@ -10,8 +10,11 @@ int add_mtd_device(struct mtd_info *mtd); int del_mtd_device(struct mtd_info *mtd); int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); int del_mtd_partitions(struct mtd_info *); + +struct mtd_partitions; + int parse_mtd_partitions(struct mtd_info *master, const char * const *types, - const struct mtd_partition **pparts, + struct mtd_partitions *pparts, struct mtd_part_parser_data *data); int __init init_mtdchar(void); diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 898999c5aea16..53517d7653cb7 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -743,7 +743,7 @@ static const char * const default_mtd_part_types[] = { * parse_mtd_partitions - parse MTD partitions * @master: the master partition (describes whole MTD device) * @types: names of partition parsers to try or %NULL - * @pparts: array of partitions found is returned here + * @pparts: info about partitions found is returned here * @data: MTD partition parser-specific data * * This function tries to find partition on MTD device @master. It uses MTD @@ -755,12 +755,11 @@ static const char * const default_mtd_part_types[] = { * * This function may return: * o a negative error code in case of failure - * o zero if no partitions were found - * o a positive number of found partitions, in which case on exit @pparts will - * point to an array containing this number of &struct mtd_info objects. + * o zero otherwise, and @pparts will describe the partitions, number of + * partitions, and the parser which parsed them */ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, - const struct mtd_partition **pparts, + struct mtd_partitions *pparts, struct mtd_part_parser_data *data) { struct mtd_part_parser *parser; @@ -778,14 +777,16 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, parser ? parser->name : NULL); if (!parser) continue; - ret = (*parser->parse_fn)(master, pparts, data); + ret = (*parser->parse_fn)(master, &pparts->parts, data); pr_debug("%s: parser %s: %i\n", master->name, parser->name, ret); mtd_part_parser_put(parser); if (ret > 0) { printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", ret, parser->name, master->name); - return ret; + pparts->nr_parts = ret; + pparts->parser = parser; + return 0; } /* * Stash the first error we see; only report it if no parser diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index 6185536daacc0..cceaf7bd1537d 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -73,6 +73,13 @@ struct mtd_part_parser { struct mtd_part_parser_data *); }; +/* Container for passing around a set of parsed partitions */ +struct mtd_partitions { + const struct mtd_partition *parts; + int nr_parts; + const struct mtd_part_parser *parser; +}; + extern int __register_mtd_parser(struct mtd_part_parser *parser, struct module *owner); #define register_mtd_parser(parser) __register_mtd_parser(parser, THIS_MODULE) -- GitLab From 3d751eb057e6ed4e4fbce880c016ad967ba732d2 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Mon, 21 Sep 2015 11:25:40 -0500 Subject: [PATCH 1035/2855] Documentation: dt-bindings: Fix interrupt documentation file path Fix the incorrect interrupt documentation file path in binding docs. Signed-off-by: Andrew F. Davis Acked-by: Lee Jones Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt | 2 +- Documentation/devicetree/bindings/mfd/arizona.txt | 2 +- Documentation/devicetree/bindings/mfd/palmas.txt | 2 +- Documentation/devicetree/bindings/sound/wm8994.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt index dd5d2c0394b13..4d6c8cdc85860 100644 --- a/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt +++ b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt @@ -24,7 +24,7 @@ controller. - #interrupt-cells : Specifies the number of cells needed to encode an interrupt. Shall be set to 2. The first cell defines the interrupt number, the second encodes the triger flags encoded as described in - Documentation/devicetree/bindings/interrupts.txt + Documentation/devicetree/bindings/interrupt-controller/interrupts.txt - interrupt-parent : The parent interrupt controller. - interrupts : The interrupt to the parent controller raised when GPIOs generate the interrupts. diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt b/Documentation/devicetree/bindings/mfd/arizona.txt index 18be0cbfb456c..2c5d0387fe98c 100644 --- a/Documentation/devicetree/bindings/mfd/arizona.txt +++ b/Documentation/devicetree/bindings/mfd/arizona.txt @@ -24,7 +24,7 @@ Required properties: - #interrupt-cells: the number of cells to describe an IRQ, this should be 2. The first cell is the IRQ number. The second cell is the flags, encoded as the trigger masks from - Documentation/devicetree/bindings/interrupts.txt + Documentation/devicetree/bindings/interrupt-controller/interrupts.txt - gpio-controller : Indicates this device is a GPIO controller. - #gpio-cells : Must be 2. The first cell is the pin number and the diff --git a/Documentation/devicetree/bindings/mfd/palmas.txt b/Documentation/devicetree/bindings/mfd/palmas.txt index eda898978d333..8ae1a32bfb7eb 100644 --- a/Documentation/devicetree/bindings/mfd/palmas.txt +++ b/Documentation/devicetree/bindings/mfd/palmas.txt @@ -24,7 +24,7 @@ and also the generic series names - #interrupt-cells : should be set to 2 for IRQ number and flags The first cell is the IRQ number. The second cell is the flags, encoded as the trigger masks from - Documentation/devicetree/bindings/interrupts.txt + Documentation/devicetree/bindings/interrupt-controller/interrupts.txt - interrupt-parent : The parent interrupt controller. Optional properties: diff --git a/Documentation/devicetree/bindings/sound/wm8994.txt b/Documentation/devicetree/bindings/sound/wm8994.txt index e045e90a0924b..68c4e8d96bed6 100644 --- a/Documentation/devicetree/bindings/sound/wm8994.txt +++ b/Documentation/devicetree/bindings/sound/wm8994.txt @@ -30,7 +30,7 @@ Optional properties: - #interrupt-cells: the number of cells to describe an IRQ, this should be 2. The first cell is the IRQ number. The second cell is the flags, encoded as the trigger masks from - Documentation/devicetree/bindings/interrupts.txt + Documentation/devicetree/bindings/interrupt-controller/interrupts.txt - clocks : A list of up to two phandle and clock specifier pairs - clock-names : A list of clock names sorted in the same order as clocks. -- GitLab From 22697acdd72d6749d603cb861d4f6c1c2b583c1b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 19 Nov 2015 09:42:49 +0900 Subject: [PATCH 1036/2855] dt-bindings: Consolidate SRAM bindings from all vendors SRAM bindings for various SoCs, using the mmio-sram genalloc API, are spread over different places - per SoC vendor. Since all of these are quite similar (they depend on mmio-sram) move them to a common place. Suggested-by: Rob Herring Signed-off-by: Krzysztof Kozlowski Cc: Heiko Stuebner Cc: Maxime Ripard Cc: Chen-Yu Tsai Cc: Kukjin Kim Acked-by: Maxime Ripard Acked-by: Heiko Stuebner Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/arm/arm,scpi.txt | 2 +- .../{arm/rockchip/pmu-sram.txt => sram/rockchip-pmu-sram.txt} | 0 .../{arm/rockchip/smp-sram.txt => sram/rockchip-smp-sram.txt} | 2 +- .../{arm/exynos/smp-sysram.txt => sram/samsung-sram.txt} | 2 +- Documentation/devicetree/bindings/{misc => sram}/sram.txt | 0 .../bindings/{soc/sunxi/sram.txt => sram/sunxi-sram.txt} | 2 +- 6 files changed, 4 insertions(+), 4 deletions(-) rename Documentation/devicetree/bindings/{arm/rockchip/pmu-sram.txt => sram/rockchip-pmu-sram.txt} (100%) rename Documentation/devicetree/bindings/{arm/rockchip/smp-sram.txt => sram/rockchip-smp-sram.txt} (92%) rename Documentation/devicetree/bindings/{arm/exynos/smp-sysram.txt => sram/samsung-sram.txt} (95%) rename Documentation/devicetree/bindings/{misc => sram}/sram.txt (100%) rename Documentation/devicetree/bindings/{soc/sunxi/sram.txt => sram/sunxi-sram.txt} (97%) diff --git a/Documentation/devicetree/bindings/arm/arm,scpi.txt b/Documentation/devicetree/bindings/arm/arm,scpi.txt index 86302de67c2c7..313dabdc14f98 100644 --- a/Documentation/devicetree/bindings/arm/arm,scpi.txt +++ b/Documentation/devicetree/bindings/arm/arm,scpi.txt @@ -63,7 +63,7 @@ Required properties: - compatible : should be "arm,juno-sram-ns" for Non-secure SRAM on Juno The rest of the properties should follow the generic mmio-sram description -found in ../../misc/sysram.txt +found in ../../sram/sram.txt Each sub-node represents the reserved area for SCPI. diff --git a/Documentation/devicetree/bindings/arm/rockchip/pmu-sram.txt b/Documentation/devicetree/bindings/sram/rockchip-pmu-sram.txt similarity index 100% rename from Documentation/devicetree/bindings/arm/rockchip/pmu-sram.txt rename to Documentation/devicetree/bindings/sram/rockchip-pmu-sram.txt diff --git a/Documentation/devicetree/bindings/arm/rockchip/smp-sram.txt b/Documentation/devicetree/bindings/sram/rockchip-smp-sram.txt similarity index 92% rename from Documentation/devicetree/bindings/arm/rockchip/smp-sram.txt rename to Documentation/devicetree/bindings/sram/rockchip-smp-sram.txt index d9416fb8db6f7..800701ecffca3 100644 --- a/Documentation/devicetree/bindings/arm/rockchip/smp-sram.txt +++ b/Documentation/devicetree/bindings/sram/rockchip-smp-sram.txt @@ -12,7 +12,7 @@ Required sub-node properties: - compatible : should be "rockchip,rk3066-smp-sram" The rest of the properties should follow the generic mmio-sram discription -found in ../../misc/sram.txt +found in Documentation/devicetree/bindings/sram/sram.txt Example: diff --git a/Documentation/devicetree/bindings/arm/exynos/smp-sysram.txt b/Documentation/devicetree/bindings/sram/samsung-sram.txt similarity index 95% rename from Documentation/devicetree/bindings/arm/exynos/smp-sysram.txt rename to Documentation/devicetree/bindings/sram/samsung-sram.txt index 4a0a4f70a0ce3..6bc474b2b885a 100644 --- a/Documentation/devicetree/bindings/arm/exynos/smp-sysram.txt +++ b/Documentation/devicetree/bindings/sram/samsung-sram.txt @@ -15,7 +15,7 @@ Required sub-node properties: "samsung,exynos4210-sysram-ns" : for Non-secure SYSRAM The rest of the properties should follow the generic mmio-sram discription -found in ../../misc/sysram.txt +found in Documentation/devicetree/bindings/sram/sram.txt Example: diff --git a/Documentation/devicetree/bindings/misc/sram.txt b/Documentation/devicetree/bindings/sram/sram.txt similarity index 100% rename from Documentation/devicetree/bindings/misc/sram.txt rename to Documentation/devicetree/bindings/sram/sram.txt diff --git a/Documentation/devicetree/bindings/soc/sunxi/sram.txt b/Documentation/devicetree/bindings/sram/sunxi-sram.txt similarity index 97% rename from Documentation/devicetree/bindings/soc/sunxi/sram.txt rename to Documentation/devicetree/bindings/sram/sunxi-sram.txt index 067698112f5fd..8d5665468fe7e 100644 --- a/Documentation/devicetree/bindings/soc/sunxi/sram.txt +++ b/Documentation/devicetree/bindings/sram/sunxi-sram.txt @@ -16,7 +16,7 @@ SRAM nodes ---------- Each SRAM is described using the mmio-sram bindings documented in -Documentation/devicetree/bindings/misc/sram.txt +Documentation/devicetree/bindings/sram/sram.txt Each SRAM will have SRAM sections that are going to be handled by the SRAM controller as subnodes. These sections are represented following -- GitLab From 2729f62c96fa32c6bec062bf39251929dd6cc759 Mon Sep 17 00:00:00 2001 From: Michael Trimarchi Date: Sun, 15 Nov 2015 11:48:48 +0100 Subject: [PATCH 1037/2855] usb: misc: usb3503: Describe better how to bind clock to the hub Signed-off-by: Michael Trimarchi Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/usb/usb3503.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/usb/usb3503.txt b/Documentation/devicetree/bindings/usb/usb3503.txt index 52493b1480e27..c1a0a9191d261 100644 --- a/Documentation/devicetree/bindings/usb/usb3503.txt +++ b/Documentation/devicetree/bindings/usb/usb3503.txt @@ -18,7 +18,8 @@ Optional properties: - refclk: Clock used for driving REFCLK signal (optional, if not provided the driver assumes that clock signal is always available, its rate is specified by REF_SEL pins and a value from the primary - reference clock frequencies table is used) + reference clock frequencies table is used). Use clocks and + clock-names in order to assign it - refclk-frequency: Frequency of the REFCLK signal as defined by REF_SEL pins (optional, if not provided, driver will not set rate of the REFCLK signal and assume that a value from the primary reference @@ -33,4 +34,6 @@ Examples: intn-gpios = <&gpx3 4 1>; reset-gpios = <&gpx3 5 1>; initial-mode = <1>; + clocks = <&clks 80>; + clock-names = "refclk"; }; -- GitLab From 8cc73e58b9d7f421988d99803df055a4db7531bc Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 18 Nov 2015 01:13:20 +0200 Subject: [PATCH 1038/2855] Documentation/devicetree: document OCTEON USB bindings Document device-tree bindings for the USB controller on older OCTEON SOCs (OCTEON, OCTEON+). Signed-off-by: Aaro Koskinen Signed-off-by: Rob Herring --- .../devicetree/bindings/usb/octeon-usb.txt | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/octeon-usb.txt diff --git a/Documentation/devicetree/bindings/usb/octeon-usb.txt b/Documentation/devicetree/bindings/usb/octeon-usb.txt new file mode 100644 index 0000000000000..205c8d24d6e31 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/octeon-usb.txt @@ -0,0 +1,62 @@ +OCTEON/OCTEON+ USB BLOCK + +1) Main node + + Required properties: + + - compatible: must be "cavium,octeon-5750-usbn" + + - reg: specifies the physical base address of the USBN block and + the length of the memory mapped region. + + - #address-cells: specifies the number of cells needed to encode an + address. The value must be 2. + + - #size-cells: specifies the number of cells used to represent the size + of an address. The value must be 2. + + - ranges: specifies the translation between child address space and parent + address space. + + - clock-frequency: speed of the USB reference clock. Allowed values are + 12000000, 24000000 or 48000000. + + - cavium,refclk-type: type of the USB reference clock. Allowed values are + "crystal" or "external". + + - refclk-frequency: deprecated, use "clock-frequency". + + - refclk-type: deprecated, use "cavium,refclk-type". + +2) Child node + + The main node must have one child node which describes the built-in + USB controller. + + Required properties: + + - compatible: must be "cavium,octeon-5750-usbc" + + - reg: specifies the physical base address of the USBC block and + the length of the memory mapped region. + + - interrupts: specifies the interrupt number for the USB controller. + +3) Example: + + usbn: usbn@1180068000000 { + compatible = "cavium,octeon-5750-usbn"; + reg = <0x11800 0x68000000 0x0 0x1000>; + ranges; /* Direct mapping */ + #address-cells = <2>; + #size-cells = <2>; + clock-frequency = <12000000>; + cavium,refclk-type = "crystal"; + + usbc@16f0010000000 { + compatible = "cavium,octeon-5750-usbc"; + reg = <0x16f00 0x10000000 0x0 0x80000>; + interrupts = <0 56>; + }; + }; + -- GitLab From 4c9848c8ea5f91092e92839da9b6dd1bcaa5be79 Mon Sep 17 00:00:00 2001 From: Yao Yuan Date: Wed, 18 Nov 2015 17:18:11 +0800 Subject: [PATCH 1039/2855] Documentation: fsl-quadspi: Add fsl,ls1021-qspi compatible string new compatible string: "fsl,ls1021-qspi". Signed-off-by: Yuan Yao Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/mtd/fsl-quadspi.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt index 862aa2f8837af..00c587b3d3ae7 100644 --- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt +++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt @@ -2,7 +2,8 @@ Required properties: - compatible : Should be "fsl,vf610-qspi", "fsl,imx6sx-qspi", - "fsl,imx7d-qspi", "fsl,imx6ul-qspi" + "fsl,imx7d-qspi", "fsl,imx6ul-qspi", + "fsl,ls1021-qspi" - reg : the first contains the register location and length, the second contains the memory mapping address and length - reg-names: Should contain the reg names "QuadSPI" and "QuadSPI-memory" -- GitLab From 2193377bdade3bdfac164d7a7217c557a3c0878f Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Wed, 18 Nov 2015 12:20:58 +0000 Subject: [PATCH 1040/2855] DT: add Olimex to vendor prefixes This company already provided some products, so add them to the vendor prefix list. Signed-off-by: Stefan Wahren Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 55df1d444e9f8..a4f2035569ce7 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -161,6 +161,7 @@ nuvoton Nuvoton Technology Corporation nvidia NVIDIA nxp NXP Semiconductors okaya Okaya Electric America, Inc. +olimex OLIMEX Ltd. onnn ON Semiconductor Corp. opencores OpenCores.org option Option NV -- GitLab From bf400242a97697a0c6be8cd5a1a9f8f5c1594d6a Mon Sep 17 00:00:00 2001 From: Songjun Wu Date: Mon, 23 Nov 2015 17:19:58 +0800 Subject: [PATCH 1041/2855] ASoC: Atmel: ClassD: add GCK's parent clock in DT binding Set GCK's parent as audio clock. Signed-off-by: Songjun Wu Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/sound/atmel-classd.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/atmel-classd.txt b/Documentation/devicetree/bindings/sound/atmel-classd.txt index 0018451c43514..549e701cb7a1c 100644 --- a/Documentation/devicetree/bindings/sound/atmel-classd.txt +++ b/Documentation/devicetree/bindings/sound/atmel-classd.txt @@ -16,6 +16,10 @@ Required properties: Required elements: "pclk", "gclk" and "aclk". - clocks Please refer to clock-bindings.txt. +- assigned-clocks + Should be <&classd_gclk>. +- assigned-clock-parents + Should be <&audio_pll_pmc>. Optional properties: - pinctrl-names, pinctrl-0 @@ -43,6 +47,8 @@ classd: classd@fc048000 { dma-names = "tx"; clocks = <&classd_clk>, <&classd_gclk>, <&audio_pll_pmc>; clock-names = "pclk", "gclk", "aclk"; + assigned-clocks = <&classd_gclk>; + assigned-clock-parents = <&audio_pll_pmc>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_classd_default>; -- GitLab From 182f4f098efcd112bed074ec84854b8e1a016974 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 24 Nov 2015 20:31:51 +0900 Subject: [PATCH 1042/2855] dt-bindings: ARM: add arm,cortex-a72 compatible string Signed-off-by: Masahiro Yamada Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/arm/cpus.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index 3a07a87fef208..58e240d751699 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt @@ -157,6 +157,7 @@ nodes to be present and contain the properties described below. "arm,cortex-a17" "arm,cortex-a53" "arm,cortex-a57" + "arm,cortex-a72" "arm,cortex-m0" "arm,cortex-m0+" "arm,cortex-m1" -- GitLab From d9f43babb998b4061305ec682a423c709a503178 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 24 Nov 2015 16:06:41 +0000 Subject: [PATCH 1043/2855] Documentation: dt: Add bindings for Secure-only devices The existing device tree bindings assume that we are only trying to describe a single address space with a device tree (for ARM, either the Normal or the Secure world). Some uses for device tree need to describe both Normal and Secure worlds in a single device tree. Add documentation of how to do this, by adding extra properties which describe when a device appears differently in the two worlds or when it only appears in one of them. The binding describes the general principles for adding new properties describing the secure world, but for now we only need a single new property, "secure-status", which can be used to annotate devices to indicate that they are only visible in one of the two worlds. The primary expected use of this binding is for a virtual machine like QEMU to describe the VM layout to a TrustZone aware firmware (which would then use the secure-only devices itself, and pass the DT on to a kernel running in the non-secure world, which ignores the secure-only devices and uses the rest). Signed-off-by: Peter Maydell Signed-off-by: Rob Herring --- .../devicetree/bindings/arm/secure.txt | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/secure.txt diff --git a/Documentation/devicetree/bindings/arm/secure.txt b/Documentation/devicetree/bindings/arm/secure.txt new file mode 100644 index 0000000000000..e31303fb233ad --- /dev/null +++ b/Documentation/devicetree/bindings/arm/secure.txt @@ -0,0 +1,53 @@ +* ARM Secure world bindings + +ARM CPUs with TrustZone support have two distinct address spaces, +"Normal" and "Secure". Most devicetree consumers (including the Linux +kernel) are not TrustZone aware and run entirely in either the Normal +world or the Secure world. However some devicetree consumers are +TrustZone aware and need to be able to determine whether devices are +visible only in the Secure address space, only in the Normal address +space, or visible in both. (One example of that situation would be a +virtual machine which boots Secure firmware and wants to tell the +firmware about the layout of the machine via devicetree.) + +The general principle of the naming scheme for Secure world bindings +is that any property that needs a different value in the Secure world +can be supported by prefixing the property name with "secure-". So for +instance "secure-foo" would override "foo". For property names with +a vendor prefix, the Secure variant of "vendor,foo" would be +"vendor,secure-foo". If there is no "secure-" property then the Secure +world value is the same as specified for the Normal world by the +non-prefixed property. However, only the properties listed below may +validly have "secure-" versions; this list will be enlarged on a +case-by-case basis. + +Defining the bindings in this way means that a device tree which has +been annotated to indicate the presence of Secure-only devices can +still be processed unmodified by existing Non-secure software (and in +particular by the kernel). + +Note that it is still valid for bindings intended for purely Secure +world consumers (like kernels that run entirely in Secure) to simply +describe the view of Secure world using the standard bindings. These +secure- bindings only need to be used where both the Secure and Normal +world views need to be described in a single device tree. + +Valid Secure world properties: + +- secure-status : specifies whether the device is present and usable + in the secure world. The combination of this with "status" allows + the various possible combinations of device visibility to be + specified. If "secure-status" is not specified it defaults to the + same value as "status"; if "status" is not specified either then + both default to "okay". This means the following combinations are + possible: + + /* Neither specified: default to visible in both S and NS */ + secure-status = "okay"; /* visible in both */ + status = "okay"; /* visible in both */ + status = "okay"; secure-status = "okay"; /* visible in both */ + secure-status = "disabled"; /* NS-only */ + status = "okay"; secure-status = "disabled"; /* NS-only */ + status = "disabled"; secure-status = "okay"; /* S-only */ + status = "disabled"; /* disabled in both */ + status = "disabled"; secure-status = "disabled"; /* disabled in both */ -- GitLab From ef8322427e6bb956992079e3b5fac57e65a6b5d3 Mon Sep 17 00:00:00 2001 From: Alban Bedel Date: Sun, 29 Nov 2015 13:40:11 +0100 Subject: [PATCH 1044/2855] dt-bindings: Misc fix for the ATH79 MISC interrupt controllers Add a missing quote in the example Signed-off-by: Alban Bedel CC: trivial@kernel.org Signed-off-by: Rob Herring --- .../bindings/interrupt-controller/qca,ath79-misc-intc.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-misc-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-misc-intc.txt index ec96b1f014788..475ae9bd562b4 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-misc-intc.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-misc-intc.txt @@ -22,7 +22,7 @@ Interrupt Controllers bindings used by client devices. Example: interrupt-controller@18060010 { - compatible = "qca,ar9132-misc-intc", qca,ar7100-misc-intc"; + compatible = "qca,ar9132-misc-intc", "qca,ar7100-misc-intc"; reg = <0x18060010 0x4>; interrupt-parent = <&cpuintc>; -- GitLab From 1da2f213cfaef8e3b8a93c7779d96691d226083b Mon Sep 17 00:00:00 2001 From: Alban Bedel Date: Sun, 29 Nov 2015 13:40:12 +0100 Subject: [PATCH 1045/2855] dt-bindings: Misc fix for the ATH79 DDR controllers Fix a few typos and reword the description of the '#qca,ddr-wb-channel-cells' property. Signed-off-by: Alban Bedel CC: trivial@kernel.org Signed-off-by: Rob Herring --- .../bindings/memory-controllers/ath79-ddr-controller.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt b/Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt index efe35a065714e..c81af75bcd886 100644 --- a/Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt +++ b/Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt @@ -1,6 +1,6 @@ Binding for Qualcomm Atheros AR7xxx/AR9xxx DDR controller -The DDR controller of the ARxxx and AR9xxx families provides an interface +The DDR controller of the AR7xxx and AR9xxx families provides an interface to flush the FIFO between various devices and the DDR. This is mainly used by the IRQ controller to flush the FIFO before running the interrupt handler of such devices. @@ -11,9 +11,9 @@ Required properties: "qca,[ar7100|ar7240]-ddr-controller" as fallback. On SoC with PCI support "qca,ar7100-ddr-controller" should be used as fallback, otherwise "qca,ar7240-ddr-controller" should be used. -- reg: Base address and size of the controllers memory area -- #qca,ddr-wb-channel-cells: has to be 1, the index of the write buffer - channel +- reg: Base address and size of the controller's memory area +- #qca,ddr-wb-channel-cells: Specifies the number of cells needed to encode + the write buffer channel index, should be 1. Example: -- GitLab From d6403108aaf413c9677040c20519e5c14c2f6f7c Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 30 Nov 2015 14:51:46 +0100 Subject: [PATCH 1046/2855] net/macb: bindings doc: Merge cdns-emac to macb Merge two bindings for the same driver to together. Signed-off-by: Michal Simek Acked-by: Nicolas Ferre Acked-by: Moritz Fischer Signed-off-by: Rob Herring --- .../devicetree/bindings/net/cdns-emac.txt | 20 ------------------- .../devicetree/bindings/net/macb.txt | 3 +++ 2 files changed, 3 insertions(+), 20 deletions(-) delete mode 100644 Documentation/devicetree/bindings/net/cdns-emac.txt diff --git a/Documentation/devicetree/bindings/net/cdns-emac.txt b/Documentation/devicetree/bindings/net/cdns-emac.txt deleted file mode 100644 index 4451ee9732239..0000000000000 --- a/Documentation/devicetree/bindings/net/cdns-emac.txt +++ /dev/null @@ -1,20 +0,0 @@ -* Cadence EMAC Ethernet controller - -Required properties: -- compatible: Should be "cdns,[-]{emac}" - Use "cdns,at91rm9200-emac" Atmel at91rm9200 SoC. - Use "cdns,zynq-gem" Xilinx Zynq-7xxx SoC. - Or the generic form: "cdns,emac". -- reg: Address and length of the register set for the device -- interrupts: Should contain macb interrupt -- phy-mode: see ethernet.txt file in the same directory. - -Examples: - - macb0: ethernet@fffc4000 { - compatible = "cdns,at91rm9200-emac"; - reg = <0xfffc4000 0x4000>; - interrupts = <21>; - phy-mode = "rmii"; - local-mac-address = [3a 0e 03 04 05 06]; - }; diff --git a/Documentation/devicetree/bindings/net/macb.txt b/Documentation/devicetree/bindings/net/macb.txt index b5d79761ac970..1361a6daf63f6 100644 --- a/Documentation/devicetree/bindings/net/macb.txt +++ b/Documentation/devicetree/bindings/net/macb.txt @@ -2,6 +2,7 @@ Required properties: - compatible: Should be "cdns,[-]{macb|gem}" + Use "cdns,at91rm9200-emac" Atmel at91rm9200 SoC. Use "cdns,at91sam9260-macb" for Atmel at91sam9 SoCs or the 10/100Mbit IP available on sama5d3 SoCs. Use "cdns,at32ap7000-macb" for other 10/100 usage or use the generic form: "cdns,macb". @@ -10,7 +11,9 @@ Required properties: Use "atmel,sama5d2-gem" for the GEM IP (10/100) available on Atmel sama5d2 SoCs. Use "atmel,sama5d3-gem" for the Gigabit IP available on Atmel sama5d3 SoCs. Use "atmel,sama5d4-gem" for the GEM IP (10/100) available on Atmel sama5d4 SoCs. + Use "cdns,zynq-gem" Xilinx Zynq-7xxx SoC. Use "cdns,zynqmp-gem" for Zynq Ultrascale+ MPSoC. + Or the generic form: "cdns,emac". - reg: Address and length of the register set for the device - interrupts: Should contain macb interrupt - phy-mode: See ethernet.txt file in the same directory. -- GitLab From e9e5f6365073b5f717172834986df8e2ec5a80b4 Mon Sep 17 00:00:00 2001 From: Liviu Dudau Date: Wed, 2 Dec 2015 11:35:39 +0000 Subject: [PATCH 1047/2855] dt-bindings: tda998x: Document the required 'port' node. All the users of the tda998x driver are component based and bind the driver via the device graph method described in Documentation/devicetree/bindings/graph.txt. Add the fact that the 'port' node is required to the bindings. Signed-off-by: Liviu Dudau Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/display/bridge/tda998x.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/display/bridge/tda998x.txt b/Documentation/devicetree/bindings/display/bridge/tda998x.txt index e9e4bce40760e..e178e6b9f9ee1 100644 --- a/Documentation/devicetree/bindings/display/bridge/tda998x.txt +++ b/Documentation/devicetree/bindings/display/bridge/tda998x.txt @@ -5,6 +5,10 @@ Required properties; - reg: I2C address +Required node: + - port: Input port node with endpoint definition, as described + in Documentation/devicetree/bindings/graph.txt + Optional properties: - interrupts: interrupt number and trigger type default: polling -- GitLab From 264041e3796133003f010303629a249f9caa3275 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 24 Nov 2015 22:10:26 +0900 Subject: [PATCH 1048/2855] of/irq: optimize device node matching loop in of_irq_init() Currently, of_irq_init() iterates over interrupt controller nodes with for_each_matching_node(), and then gets each init function with of_match_node() later. This routine can be optimized with for_each_matching_node_and_match(). It allows to get the interrupt controller node and its init function at the same time, saving __of_match_node() callings. Signed-off-by: Masahiro Yamada Signed-off-by: Rob Herring --- drivers/of/irq.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 902b89be72171..4c0da87b417ca 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -472,6 +472,7 @@ EXPORT_SYMBOL_GPL(of_irq_to_resource_table); struct of_intc_desc { struct list_head list; + of_irq_init_cb_t irq_init_cb; struct device_node *dev; struct device_node *interrupt_parent; }; @@ -485,6 +486,7 @@ struct of_intc_desc { */ void __init of_irq_init(const struct of_device_id *matches) { + const struct of_device_id *match; struct device_node *np, *parent = NULL; struct of_intc_desc *desc, *temp_desc; struct list_head intc_desc_list, intc_parent_list; @@ -492,10 +494,15 @@ void __init of_irq_init(const struct of_device_id *matches) INIT_LIST_HEAD(&intc_desc_list); INIT_LIST_HEAD(&intc_parent_list); - for_each_matching_node(np, matches) { + for_each_matching_node_and_match(np, matches, &match) { if (!of_find_property(np, "interrupt-controller", NULL) || !of_device_is_available(np)) continue; + + if (WARN(!match->data, "of_irq_init: no init function for %s\n", + match->compatible)) + continue; + /* * Here, we allocate and populate an of_intc_desc with the node * pointer, interrupt-parent device_node etc. @@ -506,6 +513,7 @@ void __init of_irq_init(const struct of_device_id *matches) goto err; } + desc->irq_init_cb = match->data; desc->dev = of_node_get(np); desc->interrupt_parent = of_irq_find_parent(np); if (desc->interrupt_parent == np) @@ -525,27 +533,18 @@ void __init of_irq_init(const struct of_device_id *matches) * The assumption is that NULL parent means a root controller. */ list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) { - const struct of_device_id *match; int ret; - of_irq_init_cb_t irq_init_cb; if (desc->interrupt_parent != parent) continue; list_del(&desc->list); - match = of_match_node(matches, desc->dev); - if (WARN(!match->data, - "of_irq_init: no init function for %s\n", - match->compatible)) { - kfree(desc); - continue; - } - pr_debug("of_irq_init: init %s @ %p, parent %p\n", - match->compatible, + pr_debug("of_irq_init: init %s (%p), parent %p\n", + desc->dev->full_name, desc->dev, desc->interrupt_parent); - irq_init_cb = (of_irq_init_cb_t)match->data; - ret = irq_init_cb(desc->dev, desc->interrupt_parent); + ret = desc->irq_init_cb(desc->dev, + desc->interrupt_parent); if (ret) { kfree(desc); continue; -- GitLab From 289582eac070a960e3c1cbfd8d110342426c5842 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 30 Nov 2015 15:14:19 +0900 Subject: [PATCH 1049/2855] of/address: replace printk(KERN_ERR ...) with pr_err(...) A trivial change suggested by checkpatch.pl. Signed-off-by: Masahiro Yamada Signed-off-by: Rob Herring --- drivers/of/address.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/address.c b/drivers/of/address.c index cd53fe4a0c868..5289c80d54677 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -596,7 +596,7 @@ static u64 __of_translate_address(struct device_node *dev, pbus = of_match_bus(parent); pbus->count_cells(dev, &pna, &pns); if (!OF_CHECK_COUNTS(pna, pns)) { - printk(KERN_ERR "prom_parse: Bad cell count for %s\n", + pr_err("prom_parse: Bad cell count for %s\n", of_node_full_name(dev)); break; } -- GitLab From adc83bf8896353603213754353dd66dae69e3d7f Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 9 Dec 2015 10:24:03 -0800 Subject: [PATCH 1050/2855] mtd: partitions: support a cleanup callback for parsers If partition parsers need to clean up their resources, we shouldn't assume that all memory will fit in a single kmalloc() that the caller can kfree(). We should allow the parser to provide a proper cleanup routine. Note that this means we need to keep a hold on the parser's module for a bit longer, and release it later with mtd_part_parser_put(). Alongside this, define a default callback that we'll automatically use if the parser doesn't provide one, so we can still retain the old behavior. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- drivers/mtd/mtdcore.c | 3 +-- drivers/mtd/mtdcore.h | 2 ++ drivers/mtd/mtdpart.c | 35 ++++++++++++++++++++++++++++++++-- include/linux/mtd/partitions.h | 1 + 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 20b2b38247b6a..89d811e7b04ab 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -630,8 +630,7 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, out: /* Cleanup any parsed partitions */ - if (parsed.parser) - kfree(parsed.parts); + mtd_part_parser_cleanup(&parsed); return ret; } EXPORT_SYMBOL_GPL(mtd_device_parse_register); diff --git a/drivers/mtd/mtdcore.h b/drivers/mtd/mtdcore.h index ce81cc2002f4d..55fdb8e1fd2a8 100644 --- a/drivers/mtd/mtdcore.h +++ b/drivers/mtd/mtdcore.h @@ -17,6 +17,8 @@ int parse_mtd_partitions(struct mtd_info *master, const char * const *types, struct mtd_partitions *pparts, struct mtd_part_parser_data *data); +void mtd_part_parser_cleanup(struct mtd_partitions *parts); + int __init init_mtdchar(void); void __exit cleanup_mtdchar(void); diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 53517d7653cb7..10bf304027dd9 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -709,10 +709,23 @@ static inline void mtd_part_parser_put(const struct mtd_part_parser *p) module_put(p->owner); } +/* + * Many partition parsers just expected the core to kfree() all their data in + * one chunk. Do that by default. + */ +static void mtd_part_parser_cleanup_default(const struct mtd_partition *pparts, + int nr_parts) +{ + kfree(pparts); +} + int __register_mtd_parser(struct mtd_part_parser *p, struct module *owner) { p->owner = owner; + if (!p->cleanup) + p->cleanup = &mtd_part_parser_cleanup_default; + spin_lock(&part_parser_lock); list_add(&p->list, &part_parsers); spin_unlock(&part_parser_lock); @@ -756,7 +769,9 @@ static const char * const default_mtd_part_types[] = { * This function may return: * o a negative error code in case of failure * o zero otherwise, and @pparts will describe the partitions, number of - * partitions, and the parser which parsed them + * partitions, and the parser which parsed them. Caller must release + * resources with mtd_part_parser_cleanup() when finished with the returned + * data. */ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, struct mtd_partitions *pparts, @@ -780,7 +795,6 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, ret = (*parser->parse_fn)(master, &pparts->parts, data); pr_debug("%s: parser %s: %i\n", master->name, parser->name, ret); - mtd_part_parser_put(parser); if (ret > 0) { printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", ret, parser->name, master->name); @@ -788,6 +802,7 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, pparts->parser = parser; return 0; } + mtd_part_parser_put(parser); /* * Stash the first error we see; only report it if no parser * succeeds @@ -798,6 +813,22 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, return err; } +void mtd_part_parser_cleanup(struct mtd_partitions *parts) +{ + const struct mtd_part_parser *parser; + + if (!parts) + return; + + parser = parts->parser; + if (parser) { + if (parser->cleanup) + parser->cleanup(parts->parts, parts->nr_parts); + + mtd_part_parser_put(parser); + } +} + int mtd_is_partition(const struct mtd_info *mtd) { struct mtd_part *part; diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index cceaf7bd1537d..70736e1e6c8f7 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -71,6 +71,7 @@ struct mtd_part_parser { const char *name; int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, struct mtd_part_parser_data *); + void (*cleanup)(const struct mtd_partition *pparts, int nr_parts); }; /* Container for passing around a set of parsed partitions */ -- GitLab From f49289ce64b7f7da4d7129666854b499b9d415eb Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 20 Nov 2015 16:26:11 -0200 Subject: [PATCH 1051/2855] mtd: spi-nor: Check the return value from read_sr() We should better check the return value from read_sr() and propagate it in the case of error. Signed-off-by: Fabio Estevam Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/spi-nor.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 3b2460efc0199..7e5051e604b02 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -478,11 +478,13 @@ static int stm_is_locked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len, static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) { struct mtd_info *mtd = &nor->mtd; - u8 status_old, status_new; + int status_old, status_new; u8 mask = SR_BP2 | SR_BP1 | SR_BP0; u8 shift = ffs(mask) - 1, pow, val; status_old = read_sr(nor); + if (status_old < 0) + return status_old; /* SPI NOR always locks to the end */ if (ofs + len != mtd->size) { @@ -528,11 +530,13 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) { struct mtd_info *mtd = &nor->mtd; - uint8_t status_old, status_new; + int status_old, status_new; u8 mask = SR_BP2 | SR_BP1 | SR_BP0; u8 shift = ffs(mask) - 1, pow, val; status_old = read_sr(nor); + if (status_old < 0) + return status_old; /* Cannot unlock; would unlock larger region than requested */ if (stm_is_locked_sr(nor, status_old, ofs - mtd->erasesize, @@ -1032,6 +1036,8 @@ static int macronix_quad_enable(struct spi_nor *nor) int ret, val; val = read_sr(nor); + if (val < 0) + return val; write_enable(nor); write_sr(nor, val | SR_QUAD_EN_MX); -- GitLab From d5c5620167d0fde476a0c0d8bb1f5751bcc1e495 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 8 Dec 2015 18:40:59 +0100 Subject: [PATCH 1052/2855] mtd: nand: Confine MTD_NAND_SH_FLCTL to SUPERH As of commit a521422ea4ae6128 ("ARM: shmobile: mackerel: Remove Legacy C board code"), the Renesas SuperH FLCTL driver is no longer used on ARM SH-Mobile SoCs. Restrict the dependencies, unless compile-testing. Signed-off-by: Geert Uytterhoeven Signed-off-by: Brian Norris --- drivers/mtd/nand/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 289664089cf32..6c71f623a932b 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -480,7 +480,7 @@ config MTD_NAND_MXC config MTD_NAND_SH_FLCTL tristate "Support for NAND on Renesas SuperH FLCTL" - depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST + depends on SUPERH || COMPILE_TEST depends on HAS_IOMEM depends on HAS_DMA help -- GitLab From d135d1c158618c73346a898b6a08018013e43715 Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Wed, 9 Dec 2015 20:40:58 +0000 Subject: [PATCH 1053/2855] doc: dt: mtd: brcmnand: Add brcm,bcm6368-nand device tree binding Add device tree binding for NAND on the BCM6368. The BCM6368 has a NAND interrupt register with combined status and enable registers. It also requires a clock, so add an optional clock to the common brcmnand binding. Signed-off-by: Simon Arlott Reviewed-by: Florian Fainelli Acked-by: Rob Herring Signed-off-by: Brian Norris --- .../devicetree/bindings/mtd/brcm,brcmnand.txt | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt index 4ff7128ee3b20..c2546ced9c02a 100644 --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt @@ -45,6 +45,8 @@ Required properties: - #size-cells : <0> Optional properties: +- clock : reference to the clock for the NAND controller +- clock-names : "nand" (required for the above clock) - brcm,nand-has-wp : Some versions of this IP include a write-protect (WP) control bit. It is always available on >= v7.0. Use this property to describe the rare @@ -72,6 +74,12 @@ we define additional 'compatible' properties and associated register resources w and enable registers - reg-names: (required) "nand-int-base" + * "brcm,nand-bcm6368" + - compatible: should contain "brcm,nand-bcm", "brcm,nand-bcm6368" + - reg: (required) the 'NAND_INTR_BASE' register range, with combined status + and enable registers, and boot address registers + - reg-names: (required) "nand-int-base" + * "brcm,nand-iproc" - reg: (required) the "IDM" register range, for interrupt enable and APB bus access endianness configuration, and the "EXT" register range, @@ -148,3 +156,27 @@ nand@f0442800 { }; }; }; + +nand@10000200 { + compatible = "brcm,nand-bcm63168", "brcm,nand-bcm6368", + "brcm,brcmnand-v4.0", "brcm,brcmnand"; + reg = <0x10000200 0x180>, + <0x10000600 0x200>, + <0x100000b0 0x10>; + reg-names = "nand", "nand-cache", "nand-int-base"; + interrupt-parent = <&periph_intc>; + interrupts = <50>; + clocks = <&periph_clk 20>; + clock-names = "nand"; + + #address-cells = <1>; + #size-cells = <0>; + + nand0: nandcs@0 { + compatible = "brcm,nandcs"; + reg = <0>; + nand-on-flash-bbt; + nand-ecc-strength = <1>; + nand-ecc-step-size = <512>; + }; +}; -- GitLab From 5c05bc00721bbe223ce93d8873ac42c8170d809c Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Wed, 9 Dec 2015 20:42:25 +0000 Subject: [PATCH 1054/2855] mtd: brcmnand: Request and enable the clock if present Attempt to enable a clock named "nand" as some SoCs have a clock for the controller that needs to be enabled. Signed-off-by: Simon Arlott Reviewed-by: Florian Fainelli Signed-off-by: Brian Norris --- drivers/mtd/nand/brcmnand/brcmnand.c | 64 ++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index 190a99a66010b..dca816298aef0 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -11,6 +11,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -122,6 +123,9 @@ struct brcmnand_controller { /* Some SoCs provide custom interrupt status register(s) */ struct brcmnand_soc *soc; + /* Some SoCs have a gateable clock for the controller */ + struct clk *clk; + int cmd_pending; bool dma_pending; struct completion done; @@ -2127,10 +2131,24 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) if (IS_ERR(ctrl->nand_base)) return PTR_ERR(ctrl->nand_base); + /* Enable clock before using NAND registers */ + ctrl->clk = devm_clk_get(dev, "nand"); + if (!IS_ERR(ctrl->clk)) { + ret = clk_prepare_enable(ctrl->clk); + if (ret) + return ret; + } else { + ret = PTR_ERR(ctrl->clk); + if (ret == -EPROBE_DEFER) + return ret; + + ctrl->clk = NULL; + } + /* Initialize NAND revision */ ret = brcmnand_revision_init(ctrl); if (ret) - return ret; + goto err; /* * Most chips have this cache at a fixed offset within 'nand' block. @@ -2139,8 +2157,10 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand-cache"); if (res) { ctrl->nand_fc = devm_ioremap_resource(dev, res); - if (IS_ERR(ctrl->nand_fc)) - return PTR_ERR(ctrl->nand_fc); + if (IS_ERR(ctrl->nand_fc)) { + ret = PTR_ERR(ctrl->nand_fc); + goto err; + } } else { ctrl->nand_fc = ctrl->nand_base + ctrl->reg_offsets[BRCMNAND_FC_BASE]; @@ -2150,8 +2170,10 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "flash-dma"); if (res) { ctrl->flash_dma_base = devm_ioremap_resource(dev, res); - if (IS_ERR(ctrl->flash_dma_base)) - return PTR_ERR(ctrl->flash_dma_base); + if (IS_ERR(ctrl->flash_dma_base)) { + ret = PTR_ERR(ctrl->flash_dma_base); + goto err; + } flash_dma_writel(ctrl, FLASH_DMA_MODE, 1); /* linked-list */ flash_dma_writel(ctrl, FLASH_DMA_ERROR_STATUS, 0); @@ -2160,13 +2182,16 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) ctrl->dma_desc = dmam_alloc_coherent(dev, sizeof(*ctrl->dma_desc), &ctrl->dma_pa, GFP_KERNEL); - if (!ctrl->dma_desc) - return -ENOMEM; + if (!ctrl->dma_desc) { + ret = -ENOMEM; + goto err; + } ctrl->dma_irq = platform_get_irq(pdev, 1); if ((int)ctrl->dma_irq < 0) { dev_err(dev, "missing FLASH_DMA IRQ\n"); - return -ENODEV; + ret = -ENODEV; + goto err; } ret = devm_request_irq(dev, ctrl->dma_irq, @@ -2175,7 +2200,7 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) if (ret < 0) { dev_err(dev, "can't allocate IRQ %d: error %d\n", ctrl->dma_irq, ret); - return ret; + goto err; } dev_info(dev, "enabling FLASH_DMA\n"); @@ -2199,7 +2224,8 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) ctrl->irq = platform_get_irq(pdev, 0); if ((int)ctrl->irq < 0) { dev_err(dev, "no IRQ defined\n"); - return -ENODEV; + ret = -ENODEV; + goto err; } /* @@ -2223,7 +2249,7 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) if (ret < 0) { dev_err(dev, "can't allocate IRQ %d: error %d\n", ctrl->irq, ret); - return ret; + goto err; } for_each_available_child_of_node(dn, child) { @@ -2233,7 +2259,8 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); if (!host) { of_node_put(child); - return -ENOMEM; + ret = -ENOMEM; + goto err; } host->pdev = pdev; host->ctrl = ctrl; @@ -2249,10 +2276,17 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) } /* No chip-selects could initialize properly */ - if (list_empty(&ctrl->host_list)) - return -ENODEV; + if (list_empty(&ctrl->host_list)) { + ret = -ENODEV; + goto err; + } return 0; + +err: + clk_disable_unprepare(ctrl->clk); + return ret; + } EXPORT_SYMBOL_GPL(brcmnand_probe); @@ -2264,6 +2298,8 @@ int brcmnand_remove(struct platform_device *pdev) list_for_each_entry(host, &ctrl->host_list, node) nand_release(&host->mtd); + clk_disable_unprepare(ctrl->clk); + dev_set_drvdata(&pdev->dev, NULL); return 0; -- GitLab From af3855dd191799a797e80dc55ecd5a9a226c3e2c Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Wed, 9 Dec 2015 20:43:54 +0000 Subject: [PATCH 1055/2855] mtd: brcmnand: Add support for the BCM6368 The BCM6368 has a NAND interrupt register with combined status and enable registers. As the BCM6328, BCM6362 and BCM6368 all use v2.1 controllers, the first variant that will work with this driver is the BCM63268 using a v4.0 controller. Set up the device by disabling and acking all interrupts, then handle the CTRL_READY interrupt. Signed-off-by: Simon Arlott Reviewed-by: Florian Fainelli Signed-off-by: Brian Norris --- drivers/mtd/nand/brcmnand/Makefile | 1 + drivers/mtd/nand/brcmnand/bcm6368_nand.c | 145 +++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 drivers/mtd/nand/brcmnand/bcm6368_nand.c diff --git a/drivers/mtd/nand/brcmnand/Makefile b/drivers/mtd/nand/brcmnand/Makefile index 3b1fbfd27d4f3..b28ffb59eb432 100644 --- a/drivers/mtd/nand/brcmnand/Makefile +++ b/drivers/mtd/nand/brcmnand/Makefile @@ -2,5 +2,6 @@ # more specific iproc_nand.o, for instance obj-$(CONFIG_MTD_NAND_BRCMNAND) += iproc_nand.o obj-$(CONFIG_MTD_NAND_BRCMNAND) += bcm63138_nand.o +obj-$(CONFIG_MTD_NAND_BRCMNAND) += bcm6368_nand.o obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmstb_nand.o obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand.o diff --git a/drivers/mtd/nand/brcmnand/bcm6368_nand.c b/drivers/mtd/nand/brcmnand/bcm6368_nand.c new file mode 100644 index 0000000000000..7f5359be24f2e --- /dev/null +++ b/drivers/mtd/nand/brcmnand/bcm6368_nand.c @@ -0,0 +1,145 @@ +/* + * Copyright 2015 Simon Arlott + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Derived from bcm63138_nand.c: + * Copyright © 2015 Broadcom Corporation + * + * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/63268_map_part.h: + * Copyright 2000-2010 Broadcom Corporation + * + * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/flash/nandflash.c: + * Copyright 2000-2010 Broadcom Corporation + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "brcmnand.h" + +struct bcm6368_nand_soc { + struct brcmnand_soc soc; + void __iomem *base; +}; + +#define BCM6368_NAND_INT 0x00 +#define BCM6368_NAND_STATUS_SHIFT 0 +#define BCM6368_NAND_STATUS_MASK (0xfff << BCM6368_NAND_STATUS_SHIFT) +#define BCM6368_NAND_ENABLE_SHIFT 16 +#define BCM6368_NAND_ENABLE_MASK (0xffff << BCM6368_NAND_ENABLE_SHIFT) +#define BCM6368_NAND_BASE_ADDR0 0x04 +#define BCM6368_NAND_BASE_ADDR1 0x0c + +enum { + BCM6368_NP_READ = BIT(0), + BCM6368_BLOCK_ERASE = BIT(1), + BCM6368_COPY_BACK = BIT(2), + BCM6368_PAGE_PGM = BIT(3), + BCM6368_CTRL_READY = BIT(4), + BCM6368_DEV_RBPIN = BIT(5), + BCM6368_ECC_ERR_UNC = BIT(6), + BCM6368_ECC_ERR_CORR = BIT(7), +}; + +static bool bcm6368_nand_intc_ack(struct brcmnand_soc *soc) +{ + struct bcm6368_nand_soc *priv = + container_of(soc, struct bcm6368_nand_soc, soc); + void __iomem *mmio = priv->base + BCM6368_NAND_INT; + u32 val = brcmnand_readl(mmio); + + if (val & (BCM6368_CTRL_READY << BCM6368_NAND_STATUS_SHIFT)) { + /* Ack interrupt */ + val &= ~BCM6368_NAND_STATUS_MASK; + val |= BCM6368_CTRL_READY << BCM6368_NAND_STATUS_SHIFT; + brcmnand_writel(val, mmio); + return true; + } + + return false; +} + +static void bcm6368_nand_intc_set(struct brcmnand_soc *soc, bool en) +{ + struct bcm6368_nand_soc *priv = + container_of(soc, struct bcm6368_nand_soc, soc); + void __iomem *mmio = priv->base + BCM6368_NAND_INT; + u32 val = brcmnand_readl(mmio); + + /* Don't ack any interrupts */ + val &= ~BCM6368_NAND_STATUS_MASK; + + if (en) + val |= BCM6368_CTRL_READY << BCM6368_NAND_ENABLE_SHIFT; + else + val &= ~(BCM6368_CTRL_READY << BCM6368_NAND_ENABLE_SHIFT); + + brcmnand_writel(val, mmio); +} + +static int bcm6368_nand_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct bcm6368_nand_soc *priv; + struct brcmnand_soc *soc; + struct resource *res; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + soc = &priv->soc; + + res = platform_get_resource_byname(pdev, + IORESOURCE_MEM, "nand-int-base"); + if (!res) + return -EINVAL; + + priv->base = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + soc->ctlrdy_ack = bcm6368_nand_intc_ack; + soc->ctlrdy_set_enabled = bcm6368_nand_intc_set; + + /* Disable and ack all interrupts */ + brcmnand_writel(0, priv->base + BCM6368_NAND_INT); + brcmnand_writel(BCM6368_NAND_STATUS_MASK, + priv->base + BCM6368_NAND_INT); + + return brcmnand_probe(pdev, soc); +} + +static const struct of_device_id bcm6368_nand_of_match[] = { + { .compatible = "brcm,nand-bcm6368" }, + {}, +}; +MODULE_DEVICE_TABLE(of, bcm6368_nand_of_match); + +static struct platform_driver bcm6368_nand_driver = { + .probe = bcm6368_nand_probe, + .remove = brcmnand_remove, + .driver = { + .name = "bcm6368_nand", + .pm = &brcmnand_pm_ops, + .of_match_table = bcm6368_nand_of_match, + } +}; +module_platform_driver(bcm6368_nand_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Simon Arlott"); +MODULE_DESCRIPTION("NAND driver for BCM6368"); -- GitLab From e0f8c58003de9691a2cf4569aaa65361587dbc1e Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 16 Nov 2015 20:26:27 +0100 Subject: [PATCH 1056/2855] ste_dma40: Delete an unnecessary check before the function call "kmem_cache_destroy" The kmem_cache_destroy() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Acked-by: Linus Walleij Signed-off-by: Vinod Koul --- drivers/dma/ste_dma40.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index dd3e7ba273ad0..9132ae03f783d 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3694,8 +3694,7 @@ static int __init d40_probe(struct platform_device *pdev) failure: if (base) { - if (base->desc_slab) - kmem_cache_destroy(base->desc_slab); + kmem_cache_destroy(base->desc_slab); if (base->virtbase) iounmap(base->virtbase); -- GitLab From a9bae06dd05fc8262e7430b2e70ebc49d3e68488 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 16 Nov 2015 21:56:07 +0100 Subject: [PATCH 1057/2855] ste_dma40: Delete another unnecessary check in d40_probe() A single jump label was used by the d40_probe() function in several cases for error handling which was a bit inefficient here. * This implementation detail could be improved by the introduction of another jump label. * Remove an extra check for the variable "base". * Omit its explicit initialisation at the beginning then. Signed-off-by: Markus Elfring Acked-by: Linus Walleij Signed-off-by: Vinod Koul --- drivers/dma/ste_dma40.c | 82 ++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 9132ae03f783d..8ebfde12399aa 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3543,7 +3543,7 @@ static int __init d40_probe(struct platform_device *pdev) struct stedma40_platform_data *plat_data = dev_get_platdata(&pdev->dev); struct device_node *np = pdev->dev.of_node; int ret = -ENOENT; - struct d40_base *base = NULL; + struct d40_base *base; struct resource *res = NULL; int num_reserved_chans; u32 val; @@ -3552,17 +3552,17 @@ static int __init d40_probe(struct platform_device *pdev) if (np) { if (d40_of_probe(pdev, np)) { ret = -ENOMEM; - goto failure; + goto report_failure; } } else { d40_err(&pdev->dev, "No pdata or Device Tree provided\n"); - goto failure; + goto report_failure; } } base = d40_hw_detect_init(pdev); if (!base) - goto failure; + goto report_failure; num_reserved_chans = d40_phy_res_init(base); @@ -3693,50 +3693,48 @@ static int __init d40_probe(struct platform_device *pdev) return 0; failure: - if (base) { - kmem_cache_destroy(base->desc_slab); - if (base->virtbase) - iounmap(base->virtbase); + kmem_cache_destroy(base->desc_slab); + if (base->virtbase) + iounmap(base->virtbase); - if (base->lcla_pool.base && base->plat_data->use_esram_lcla) { - iounmap(base->lcla_pool.base); - base->lcla_pool.base = NULL; - } + if (base->lcla_pool.base && base->plat_data->use_esram_lcla) { + iounmap(base->lcla_pool.base); + base->lcla_pool.base = NULL; + } - if (base->lcla_pool.dma_addr) - dma_unmap_single(base->dev, base->lcla_pool.dma_addr, - SZ_1K * base->num_phy_chans, - DMA_TO_DEVICE); - - if (!base->lcla_pool.base_unaligned && base->lcla_pool.base) - free_pages((unsigned long)base->lcla_pool.base, - base->lcla_pool.pages); - - kfree(base->lcla_pool.base_unaligned); - - if (base->phy_lcpa) - release_mem_region(base->phy_lcpa, - base->lcpa_size); - if (base->phy_start) - release_mem_region(base->phy_start, - base->phy_size); - if (base->clk) { - clk_disable_unprepare(base->clk); - clk_put(base->clk); - } + if (base->lcla_pool.dma_addr) + dma_unmap_single(base->dev, base->lcla_pool.dma_addr, + SZ_1K * base->num_phy_chans, + DMA_TO_DEVICE); - if (base->lcpa_regulator) { - regulator_disable(base->lcpa_regulator); - regulator_put(base->lcpa_regulator); - } + if (!base->lcla_pool.base_unaligned && base->lcla_pool.base) + free_pages((unsigned long)base->lcla_pool.base, + base->lcla_pool.pages); - kfree(base->lcla_pool.alloc_map); - kfree(base->lookup_log_chans); - kfree(base->lookup_phy_chans); - kfree(base->phy_res); - kfree(base); + kfree(base->lcla_pool.base_unaligned); + + if (base->phy_lcpa) + release_mem_region(base->phy_lcpa, + base->lcpa_size); + if (base->phy_start) + release_mem_region(base->phy_start, + base->phy_size); + if (base->clk) { + clk_disable_unprepare(base->clk); + clk_put(base->clk); + } + + if (base->lcpa_regulator) { + regulator_disable(base->lcpa_regulator); + regulator_put(base->lcpa_regulator); } + kfree(base->lcla_pool.alloc_map); + kfree(base->lookup_log_chans); + kfree(base->lookup_phy_chans); + kfree(base->phy_res); + kfree(base); +report_failure: d40_err(&pdev->dev, "probe failed\n"); return ret; } -- GitLab From aeb8974ac70f07659b7e5b6fca5bf4d5b4495d4d Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 16 Nov 2015 22:00:28 +0100 Subject: [PATCH 1058/2855] ste_dma40: Delete an unnecessary variable initialisation in d40_probe() The variable "res" will eventually be set to a resource pointer from a call of the d40_hw_detect_init(() function. Thus let us omit the explicit initialisation at the beginning. Signed-off-by: Markus Elfring Acked-by: Linus Walleij Signed-off-by: Vinod Koul --- drivers/dma/ste_dma40.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 8ebfde12399aa..6fb8307468ab6 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3544,7 +3544,7 @@ static int __init d40_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; int ret = -ENOENT; struct d40_base *base; - struct resource *res = NULL; + struct resource *res; int num_reserved_chans; u32 val; -- GitLab From 0b2eed49875ec3605b7a71bdf05adc8c1cbd49fc Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 2 Dec 2015 14:53:54 +0900 Subject: [PATCH 1059/2855] dmaengine: usb-dmac: Document SoC specific compatibility strings In general Renesas hardware is not documented to the extent where the relationship between IP blocks on different SoCs can be assumed although they may appear to operate the same way. Furthermore the documentation typically does not specify a version for individual IP blocks. For these reasons a convention of using the SoC name in place of a version and providing SoC-specific compatibility strings has been adopted. Although not universally liked this convention is used in the bindings for most drivers for Renesas hardware. The purpose of this patch is to update the Renesas USB DMA Controller driver to follow this convention. Cc: devicetree@vger.kernel.org Acked-by: Rob Herring Acked-by: Yoshihiro Shimoda Signed-off-by: Simon Horman Signed-off-by: Vinod Koul --- .../devicetree/bindings/dma/renesas,usb-dmac.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/dma/renesas,usb-dmac.txt b/Documentation/devicetree/bindings/dma/renesas,usb-dmac.txt index 040f365954cc4..e7780a186a36b 100644 --- a/Documentation/devicetree/bindings/dma/renesas,usb-dmac.txt +++ b/Documentation/devicetree/bindings/dma/renesas,usb-dmac.txt @@ -1,7 +1,13 @@ * Renesas USB DMA Controller Device Tree bindings Required Properties: -- compatible: must contain "renesas,usb-dmac" +-compatible: "renesas,-usb-dmac", "renesas,usb-dmac" as fallback. + Examples with soctypes are: + - "renesas,r8a7790-usb-dmac" (R-Car H2) + - "renesas,r8a7791-usb-dmac" (R-Car M2-W) + - "renesas,r8a7793-usb-dmac" (R-Car M2-N) + - "renesas,r8a7794-usb-dmac" (R-Car E2) + - "renesas,r8a7795-usb-dmac" (R-Car H3) - reg: base address and length of the registers block for the DMAC - interrupts: interrupt specifiers for the DMAC, one for each entry in interrupt-names. @@ -15,7 +21,7 @@ Required Properties: Example: R8A7790 (R-Car H2) USB-DMACs usb_dmac0: dma-controller@e65a0000 { - compatible = "renesas,usb-dmac"; + compatible = "renesas,r8a7790-usb-dmac", "renesas,usb-dmac"; reg = <0 0xe65a0000 0 0x100>; interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH 0 109 IRQ_TYPE_LEVEL_HIGH>; -- GitLab From 4d42e95fc789393d267bbab8b4684936c1529378 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 4 Dec 2015 16:56:29 +0100 Subject: [PATCH 1060/2855] dmaengine: sh: Remove unused R-Car HPB-DMAC driver As of commit 4baadb9e05c68962 ("ARM: shmobile: r8a7778: remove obsolete setup code"), the Renesas R-Car HPB-DMAC driver is no longer used. In theory it could still be used on R-Car Gen1 SoCs, but that requires adding DT support to the driver, which is not planned. Remove the driver, it can be resurrected from git history when needed. Signed-off-by: Geert Uytterhoeven Acked-by: Simon Horman Signed-off-by: Vinod Koul --- drivers/dma/sh/Kconfig | 6 - drivers/dma/sh/Makefile | 1 - drivers/dma/sh/rcar-hpbdma.c | 669 ------------------ include/linux/platform_data/dma-rcar-hpbdma.h | 103 --- 4 files changed, 779 deletions(-) delete mode 100644 drivers/dma/sh/rcar-hpbdma.c delete mode 100644 include/linux/platform_data/dma-rcar-hpbdma.h diff --git a/drivers/dma/sh/Kconfig b/drivers/dma/sh/Kconfig index 9fda65af841eb..f32c430eb16cf 100644 --- a/drivers/dma/sh/Kconfig +++ b/drivers/dma/sh/Kconfig @@ -47,12 +47,6 @@ config RCAR_DMAC This driver supports the general purpose DMA controller found in the Renesas R-Car second generation SoCs. -config RCAR_HPB_DMAE - tristate "Renesas R-Car HPB DMAC support" - depends on SH_DMAE_BASE - help - Enable support for the Renesas R-Car series DMA controllers. - config RENESAS_USB_DMAC tristate "Renesas USB-DMA Controller" depends on ARCH_SHMOBILE || COMPILE_TEST diff --git a/drivers/dma/sh/Makefile b/drivers/dma/sh/Makefile index 0133e46581968..f1e2fd64f2790 100644 --- a/drivers/dma/sh/Makefile +++ b/drivers/dma/sh/Makefile @@ -14,6 +14,5 @@ shdma-objs := $(shdma-y) obj-$(CONFIG_SH_DMAE) += shdma.o obj-$(CONFIG_RCAR_DMAC) += rcar-dmac.o -obj-$(CONFIG_RCAR_HPB_DMAE) += rcar-hpbdma.o obj-$(CONFIG_RENESAS_USB_DMAC) += usb-dmac.o obj-$(CONFIG_SUDMAC) += sudmac.o diff --git a/drivers/dma/sh/rcar-hpbdma.c b/drivers/dma/sh/rcar-hpbdma.c deleted file mode 100644 index 749f26ecd3b32..0000000000000 --- a/drivers/dma/sh/rcar-hpbdma.c +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Copyright (C) 2011-2013 Renesas Electronics Corporation - * Copyright (C) 2013 Cogent Embedded, Inc. - * - * This file is based on the drivers/dma/sh/shdma.c - * - * Renesas SuperH DMA Engine support - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * - DMA of SuperH does not have Hardware DMA chain mode. - * - max DMA size is 16MB. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* DMA channel registers */ -#define HPB_DMAE_DSAR0 0x00 -#define HPB_DMAE_DDAR0 0x04 -#define HPB_DMAE_DTCR0 0x08 -#define HPB_DMAE_DSAR1 0x0C -#define HPB_DMAE_DDAR1 0x10 -#define HPB_DMAE_DTCR1 0x14 -#define HPB_DMAE_DSASR 0x18 -#define HPB_DMAE_DDASR 0x1C -#define HPB_DMAE_DTCSR 0x20 -#define HPB_DMAE_DPTR 0x24 -#define HPB_DMAE_DCR 0x28 -#define HPB_DMAE_DCMDR 0x2C -#define HPB_DMAE_DSTPR 0x30 -#define HPB_DMAE_DSTSR 0x34 -#define HPB_DMAE_DDBGR 0x38 -#define HPB_DMAE_DDBGR2 0x3C -#define HPB_DMAE_CHAN(n) (0x40 * (n)) - -/* DMA command register (DCMDR) bits */ -#define HPB_DMAE_DCMDR_BDOUT BIT(7) -#define HPB_DMAE_DCMDR_DQSPD BIT(6) -#define HPB_DMAE_DCMDR_DQSPC BIT(5) -#define HPB_DMAE_DCMDR_DMSPD BIT(4) -#define HPB_DMAE_DCMDR_DMSPC BIT(3) -#define HPB_DMAE_DCMDR_DQEND BIT(2) -#define HPB_DMAE_DCMDR_DNXT BIT(1) -#define HPB_DMAE_DCMDR_DMEN BIT(0) - -/* DMA forced stop register (DSTPR) bits */ -#define HPB_DMAE_DSTPR_DMSTP BIT(0) - -/* DMA status register (DSTSR) bits */ -#define HPB_DMAE_DSTSR_DQSTS BIT(2) -#define HPB_DMAE_DSTSR_DMSTS BIT(0) - -/* DMA common registers */ -#define HPB_DMAE_DTIMR 0x00 -#define HPB_DMAE_DINTSR0 0x0C -#define HPB_DMAE_DINTSR1 0x10 -#define HPB_DMAE_DINTCR0 0x14 -#define HPB_DMAE_DINTCR1 0x18 -#define HPB_DMAE_DINTMR0 0x1C -#define HPB_DMAE_DINTMR1 0x20 -#define HPB_DMAE_DACTSR0 0x24 -#define HPB_DMAE_DACTSR1 0x28 -#define HPB_DMAE_HSRSTR(n) (0x40 + (n) * 4) -#define HPB_DMAE_HPB_DMASPR(n) (0x140 + (n) * 4) -#define HPB_DMAE_HPB_DMLVLR0 0x160 -#define HPB_DMAE_HPB_DMLVLR1 0x164 -#define HPB_DMAE_HPB_DMSHPT0 0x168 -#define HPB_DMAE_HPB_DMSHPT1 0x16C - -#define HPB_DMA_SLAVE_NUMBER 256 -#define HPB_DMA_TCR_MAX 0x01000000 /* 16 MiB */ - -struct hpb_dmae_chan { - struct shdma_chan shdma_chan; - int xfer_mode; /* DMA transfer mode */ -#define XFER_SINGLE 1 -#define XFER_DOUBLE 2 - unsigned plane_idx; /* current DMA information set */ - bool first_desc; /* first/next transfer */ - int xmit_shift; /* log_2(bytes_per_xfer) */ - void __iomem *base; - const struct hpb_dmae_slave_config *cfg; - char dev_id[16]; /* unique name per DMAC of channel */ - dma_addr_t slave_addr; -}; - -struct hpb_dmae_device { - struct shdma_dev shdma_dev; - spinlock_t reg_lock; /* comm_reg operation lock */ - struct hpb_dmae_pdata *pdata; - void __iomem *chan_reg; - void __iomem *comm_reg; - void __iomem *reset_reg; - void __iomem *mode_reg; -}; - -struct hpb_dmae_regs { - u32 sar; /* SAR / source address */ - u32 dar; /* DAR / destination address */ - u32 tcr; /* TCR / transfer count */ -}; - -struct hpb_desc { - struct shdma_desc shdma_desc; - struct hpb_dmae_regs hw; - unsigned plane_idx; -}; - -#define to_chan(schan) container_of(schan, struct hpb_dmae_chan, shdma_chan) -#define to_desc(sdesc) container_of(sdesc, struct hpb_desc, shdma_desc) -#define to_dev(sc) container_of(sc->shdma_chan.dma_chan.device, \ - struct hpb_dmae_device, shdma_dev.dma_dev) - -static void ch_reg_write(struct hpb_dmae_chan *hpb_dc, u32 data, u32 reg) -{ - iowrite32(data, hpb_dc->base + reg); -} - -static u32 ch_reg_read(struct hpb_dmae_chan *hpb_dc, u32 reg) -{ - return ioread32(hpb_dc->base + reg); -} - -static void dcmdr_write(struct hpb_dmae_device *hpbdev, u32 data) -{ - iowrite32(data, hpbdev->chan_reg + HPB_DMAE_DCMDR); -} - -static void hsrstr_write(struct hpb_dmae_device *hpbdev, u32 ch) -{ - iowrite32(0x1, hpbdev->comm_reg + HPB_DMAE_HSRSTR(ch)); -} - -static u32 dintsr_read(struct hpb_dmae_device *hpbdev, u32 ch) -{ - u32 v; - - if (ch < 32) - v = ioread32(hpbdev->comm_reg + HPB_DMAE_DINTSR0) >> ch; - else - v = ioread32(hpbdev->comm_reg + HPB_DMAE_DINTSR1) >> (ch - 32); - return v & 0x1; -} - -static void dintcr_write(struct hpb_dmae_device *hpbdev, u32 ch) -{ - if (ch < 32) - iowrite32((0x1 << ch), hpbdev->comm_reg + HPB_DMAE_DINTCR0); - else - iowrite32((0x1 << (ch - 32)), - hpbdev->comm_reg + HPB_DMAE_DINTCR1); -} - -static void asyncmdr_write(struct hpb_dmae_device *hpbdev, u32 data) -{ - iowrite32(data, hpbdev->mode_reg); -} - -static u32 asyncmdr_read(struct hpb_dmae_device *hpbdev) -{ - return ioread32(hpbdev->mode_reg); -} - -static void hpb_dmae_enable_int(struct hpb_dmae_device *hpbdev, u32 ch) -{ - u32 intreg; - - spin_lock_irq(&hpbdev->reg_lock); - if (ch < 32) { - intreg = ioread32(hpbdev->comm_reg + HPB_DMAE_DINTMR0); - iowrite32(BIT(ch) | intreg, - hpbdev->comm_reg + HPB_DMAE_DINTMR0); - } else { - intreg = ioread32(hpbdev->comm_reg + HPB_DMAE_DINTMR1); - iowrite32(BIT(ch - 32) | intreg, - hpbdev->comm_reg + HPB_DMAE_DINTMR1); - } - spin_unlock_irq(&hpbdev->reg_lock); -} - -static void hpb_dmae_async_reset(struct hpb_dmae_device *hpbdev, u32 data) -{ - u32 rstr; - int timeout = 10000; /* 100 ms */ - - spin_lock(&hpbdev->reg_lock); - rstr = ioread32(hpbdev->reset_reg); - rstr |= data; - iowrite32(rstr, hpbdev->reset_reg); - do { - rstr = ioread32(hpbdev->reset_reg); - if ((rstr & data) == data) - break; - udelay(10); - } while (timeout--); - - if (timeout < 0) - dev_err(hpbdev->shdma_dev.dma_dev.dev, - "%s timeout\n", __func__); - - rstr &= ~data; - iowrite32(rstr, hpbdev->reset_reg); - spin_unlock(&hpbdev->reg_lock); -} - -static void hpb_dmae_set_async_mode(struct hpb_dmae_device *hpbdev, - u32 mask, u32 data) -{ - u32 mode; - - spin_lock_irq(&hpbdev->reg_lock); - mode = asyncmdr_read(hpbdev); - mode &= ~mask; - mode |= data; - asyncmdr_write(hpbdev, mode); - spin_unlock_irq(&hpbdev->reg_lock); -} - -static void hpb_dmae_ctl_stop(struct hpb_dmae_device *hpbdev) -{ - dcmdr_write(hpbdev, HPB_DMAE_DCMDR_DQSPD); -} - -static void hpb_dmae_reset(struct hpb_dmae_device *hpbdev) -{ - u32 ch; - - for (ch = 0; ch < hpbdev->pdata->num_hw_channels; ch++) - hsrstr_write(hpbdev, ch); -} - -static unsigned int calc_xmit_shift(struct hpb_dmae_chan *hpb_chan) -{ - struct hpb_dmae_device *hpbdev = to_dev(hpb_chan); - struct hpb_dmae_pdata *pdata = hpbdev->pdata; - int width = ch_reg_read(hpb_chan, HPB_DMAE_DCR); - int i; - - switch (width & (HPB_DMAE_DCR_SPDS_MASK | HPB_DMAE_DCR_DPDS_MASK)) { - case HPB_DMAE_DCR_SPDS_8BIT | HPB_DMAE_DCR_DPDS_8BIT: - default: - i = XMIT_SZ_8BIT; - break; - case HPB_DMAE_DCR_SPDS_16BIT | HPB_DMAE_DCR_DPDS_16BIT: - i = XMIT_SZ_16BIT; - break; - case HPB_DMAE_DCR_SPDS_32BIT | HPB_DMAE_DCR_DPDS_32BIT: - i = XMIT_SZ_32BIT; - break; - } - return pdata->ts_shift[i]; -} - -static void hpb_dmae_set_reg(struct hpb_dmae_chan *hpb_chan, - struct hpb_dmae_regs *hw, unsigned plane) -{ - ch_reg_write(hpb_chan, hw->sar, - plane ? HPB_DMAE_DSAR1 : HPB_DMAE_DSAR0); - ch_reg_write(hpb_chan, hw->dar, - plane ? HPB_DMAE_DDAR1 : HPB_DMAE_DDAR0); - ch_reg_write(hpb_chan, hw->tcr >> hpb_chan->xmit_shift, - plane ? HPB_DMAE_DTCR1 : HPB_DMAE_DTCR0); -} - -static void hpb_dmae_start(struct hpb_dmae_chan *hpb_chan, bool next) -{ - ch_reg_write(hpb_chan, (next ? HPB_DMAE_DCMDR_DNXT : 0) | - HPB_DMAE_DCMDR_DMEN, HPB_DMAE_DCMDR); -} - -static void hpb_dmae_halt(struct shdma_chan *schan) -{ - struct hpb_dmae_chan *chan = to_chan(schan); - - ch_reg_write(chan, HPB_DMAE_DCMDR_DQEND, HPB_DMAE_DCMDR); - ch_reg_write(chan, HPB_DMAE_DSTPR_DMSTP, HPB_DMAE_DSTPR); - - chan->plane_idx = 0; - chan->first_desc = true; -} - -static const struct hpb_dmae_slave_config * -hpb_dmae_find_slave(struct hpb_dmae_chan *hpb_chan, int slave_id) -{ - struct hpb_dmae_device *hpbdev = to_dev(hpb_chan); - struct hpb_dmae_pdata *pdata = hpbdev->pdata; - int i; - - if (slave_id >= HPB_DMA_SLAVE_NUMBER) - return NULL; - - for (i = 0; i < pdata->num_slaves; i++) - if (pdata->slaves[i].id == slave_id) - return pdata->slaves + i; - - return NULL; -} - -static void hpb_dmae_start_xfer(struct shdma_chan *schan, - struct shdma_desc *sdesc) -{ - struct hpb_dmae_chan *chan = to_chan(schan); - struct hpb_dmae_device *hpbdev = to_dev(chan); - struct hpb_desc *desc = to_desc(sdesc); - - if (chan->cfg->flags & HPB_DMAE_SET_ASYNC_RESET) - hpb_dmae_async_reset(hpbdev, chan->cfg->rstr); - - desc->plane_idx = chan->plane_idx; - hpb_dmae_set_reg(chan, &desc->hw, chan->plane_idx); - hpb_dmae_start(chan, !chan->first_desc); - - if (chan->xfer_mode == XFER_DOUBLE) { - chan->plane_idx ^= 1; - chan->first_desc = false; - } -} - -static bool hpb_dmae_desc_completed(struct shdma_chan *schan, - struct shdma_desc *sdesc) -{ - /* - * This is correct since we always have at most single - * outstanding DMA transfer per channel, and by the time - * we get completion interrupt the transfer is completed. - * This will change if we ever use alternating DMA - * information sets and submit two descriptors at once. - */ - return true; -} - -static bool hpb_dmae_chan_irq(struct shdma_chan *schan, int irq) -{ - struct hpb_dmae_chan *chan = to_chan(schan); - struct hpb_dmae_device *hpbdev = to_dev(chan); - int ch = chan->cfg->dma_ch; - - /* Check Complete DMA Transfer */ - if (dintsr_read(hpbdev, ch)) { - /* Clear Interrupt status */ - dintcr_write(hpbdev, ch); - return true; - } - return false; -} - -static int hpb_dmae_desc_setup(struct shdma_chan *schan, - struct shdma_desc *sdesc, - dma_addr_t src, dma_addr_t dst, size_t *len) -{ - struct hpb_desc *desc = to_desc(sdesc); - - if (*len > (size_t)HPB_DMA_TCR_MAX) - *len = (size_t)HPB_DMA_TCR_MAX; - - desc->hw.sar = src; - desc->hw.dar = dst; - desc->hw.tcr = *len; - - return 0; -} - -static size_t hpb_dmae_get_partial(struct shdma_chan *schan, - struct shdma_desc *sdesc) -{ - struct hpb_desc *desc = to_desc(sdesc); - struct hpb_dmae_chan *chan = to_chan(schan); - u32 tcr = ch_reg_read(chan, desc->plane_idx ? - HPB_DMAE_DTCR1 : HPB_DMAE_DTCR0); - - return (desc->hw.tcr - tcr) << chan->xmit_shift; -} - -static bool hpb_dmae_channel_busy(struct shdma_chan *schan) -{ - struct hpb_dmae_chan *chan = to_chan(schan); - u32 dstsr = ch_reg_read(chan, HPB_DMAE_DSTSR); - - if (chan->xfer_mode == XFER_DOUBLE) - return dstsr & HPB_DMAE_DSTSR_DQSTS; - else - return dstsr & HPB_DMAE_DSTSR_DMSTS; -} - -static int -hpb_dmae_alloc_chan_resources(struct hpb_dmae_chan *hpb_chan, - const struct hpb_dmae_slave_config *cfg) -{ - struct hpb_dmae_device *hpbdev = to_dev(hpb_chan); - struct hpb_dmae_pdata *pdata = hpbdev->pdata; - const struct hpb_dmae_channel *channel = pdata->channels; - int slave_id = cfg->id; - int i, err; - - for (i = 0; i < pdata->num_channels; i++, channel++) { - if (channel->s_id == slave_id) { - struct device *dev = hpb_chan->shdma_chan.dev; - - hpb_chan->base = hpbdev->chan_reg + - HPB_DMAE_CHAN(cfg->dma_ch); - - dev_dbg(dev, "Detected Slave device\n"); - dev_dbg(dev, " -- slave_id : 0x%x\n", slave_id); - dev_dbg(dev, " -- cfg->dma_ch : %d\n", cfg->dma_ch); - dev_dbg(dev, " -- channel->ch_irq: %d\n", - channel->ch_irq); - break; - } - } - - err = shdma_request_irq(&hpb_chan->shdma_chan, channel->ch_irq, - IRQF_SHARED, hpb_chan->dev_id); - if (err) { - dev_err(hpb_chan->shdma_chan.dev, - "DMA channel request_irq %d failed with error %d\n", - channel->ch_irq, err); - return err; - } - - hpb_chan->plane_idx = 0; - hpb_chan->first_desc = true; - - if ((cfg->dcr & (HPB_DMAE_DCR_CT | HPB_DMAE_DCR_DIP)) == 0) { - hpb_chan->xfer_mode = XFER_SINGLE; - } else if ((cfg->dcr & (HPB_DMAE_DCR_CT | HPB_DMAE_DCR_DIP)) == - (HPB_DMAE_DCR_CT | HPB_DMAE_DCR_DIP)) { - hpb_chan->xfer_mode = XFER_DOUBLE; - } else { - dev_err(hpb_chan->shdma_chan.dev, "DCR setting error"); - return -EINVAL; - } - - if (cfg->flags & HPB_DMAE_SET_ASYNC_MODE) - hpb_dmae_set_async_mode(hpbdev, cfg->mdm, cfg->mdr); - ch_reg_write(hpb_chan, cfg->dcr, HPB_DMAE_DCR); - ch_reg_write(hpb_chan, cfg->port, HPB_DMAE_DPTR); - hpb_chan->xmit_shift = calc_xmit_shift(hpb_chan); - hpb_dmae_enable_int(hpbdev, cfg->dma_ch); - - return 0; -} - -static int hpb_dmae_set_slave(struct shdma_chan *schan, int slave_id, - dma_addr_t slave_addr, bool try) -{ - struct hpb_dmae_chan *chan = to_chan(schan); - const struct hpb_dmae_slave_config *sc = - hpb_dmae_find_slave(chan, slave_id); - - if (!sc) - return -ENODEV; - if (try) - return 0; - chan->cfg = sc; - chan->slave_addr = slave_addr ? : sc->addr; - return hpb_dmae_alloc_chan_resources(chan, sc); -} - -static void hpb_dmae_setup_xfer(struct shdma_chan *schan, int slave_id) -{ -} - -static dma_addr_t hpb_dmae_slave_addr(struct shdma_chan *schan) -{ - struct hpb_dmae_chan *chan = to_chan(schan); - - return chan->slave_addr; -} - -static struct shdma_desc *hpb_dmae_embedded_desc(void *buf, int i) -{ - return &((struct hpb_desc *)buf)[i].shdma_desc; -} - -static const struct shdma_ops hpb_dmae_ops = { - .desc_completed = hpb_dmae_desc_completed, - .halt_channel = hpb_dmae_halt, - .channel_busy = hpb_dmae_channel_busy, - .slave_addr = hpb_dmae_slave_addr, - .desc_setup = hpb_dmae_desc_setup, - .set_slave = hpb_dmae_set_slave, - .setup_xfer = hpb_dmae_setup_xfer, - .start_xfer = hpb_dmae_start_xfer, - .embedded_desc = hpb_dmae_embedded_desc, - .chan_irq = hpb_dmae_chan_irq, - .get_partial = hpb_dmae_get_partial, -}; - -static int hpb_dmae_chan_probe(struct hpb_dmae_device *hpbdev, int id) -{ - struct shdma_dev *sdev = &hpbdev->shdma_dev; - struct platform_device *pdev = - to_platform_device(hpbdev->shdma_dev.dma_dev.dev); - struct hpb_dmae_chan *new_hpb_chan; - struct shdma_chan *schan; - - /* Alloc channel */ - new_hpb_chan = devm_kzalloc(&pdev->dev, - sizeof(struct hpb_dmae_chan), GFP_KERNEL); - if (!new_hpb_chan) { - dev_err(hpbdev->shdma_dev.dma_dev.dev, - "No free memory for allocating DMA channels!\n"); - return -ENOMEM; - } - - schan = &new_hpb_chan->shdma_chan; - schan->max_xfer_len = HPB_DMA_TCR_MAX; - - shdma_chan_probe(sdev, schan, id); - - if (pdev->id >= 0) - snprintf(new_hpb_chan->dev_id, sizeof(new_hpb_chan->dev_id), - "hpb-dmae%d.%d", pdev->id, id); - else - snprintf(new_hpb_chan->dev_id, sizeof(new_hpb_chan->dev_id), - "hpb-dma.%d", id); - - return 0; -} - -static int hpb_dmae_probe(struct platform_device *pdev) -{ - const enum dma_slave_buswidth widths = DMA_SLAVE_BUSWIDTH_1_BYTE | - DMA_SLAVE_BUSWIDTH_2_BYTES | DMA_SLAVE_BUSWIDTH_4_BYTES; - struct hpb_dmae_pdata *pdata = pdev->dev.platform_data; - struct hpb_dmae_device *hpbdev; - struct dma_device *dma_dev; - struct resource *chan, *comm, *rest, *mode, *irq_res; - int err, i; - - /* Get platform data */ - if (!pdata || !pdata->num_channels) - return -ENODEV; - - chan = platform_get_resource(pdev, IORESOURCE_MEM, 0); - comm = platform_get_resource(pdev, IORESOURCE_MEM, 1); - rest = platform_get_resource(pdev, IORESOURCE_MEM, 2); - mode = platform_get_resource(pdev, IORESOURCE_MEM, 3); - - irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!irq_res) - return -ENODEV; - - hpbdev = devm_kzalloc(&pdev->dev, sizeof(struct hpb_dmae_device), - GFP_KERNEL); - if (!hpbdev) { - dev_err(&pdev->dev, "Not enough memory\n"); - return -ENOMEM; - } - - hpbdev->chan_reg = devm_ioremap_resource(&pdev->dev, chan); - if (IS_ERR(hpbdev->chan_reg)) - return PTR_ERR(hpbdev->chan_reg); - - hpbdev->comm_reg = devm_ioremap_resource(&pdev->dev, comm); - if (IS_ERR(hpbdev->comm_reg)) - return PTR_ERR(hpbdev->comm_reg); - - hpbdev->reset_reg = devm_ioremap_resource(&pdev->dev, rest); - if (IS_ERR(hpbdev->reset_reg)) - return PTR_ERR(hpbdev->reset_reg); - - hpbdev->mode_reg = devm_ioremap_resource(&pdev->dev, mode); - if (IS_ERR(hpbdev->mode_reg)) - return PTR_ERR(hpbdev->mode_reg); - - dma_dev = &hpbdev->shdma_dev.dma_dev; - - spin_lock_init(&hpbdev->reg_lock); - - /* Platform data */ - hpbdev->pdata = pdata; - - pm_runtime_enable(&pdev->dev); - err = pm_runtime_get_sync(&pdev->dev); - if (err < 0) - dev_err(&pdev->dev, "%s(): GET = %d\n", __func__, err); - - /* Reset DMA controller */ - hpb_dmae_reset(hpbdev); - - pm_runtime_put(&pdev->dev); - - dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask); - dma_cap_set(DMA_SLAVE, dma_dev->cap_mask); - dma_dev->src_addr_widths = widths; - dma_dev->dst_addr_widths = widths; - dma_dev->directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM); - dma_dev->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; - - hpbdev->shdma_dev.ops = &hpb_dmae_ops; - hpbdev->shdma_dev.desc_size = sizeof(struct hpb_desc); - err = shdma_init(&pdev->dev, &hpbdev->shdma_dev, pdata->num_channels); - if (err < 0) - goto error; - - /* Create DMA channels */ - for (i = 0; i < pdata->num_channels; i++) - hpb_dmae_chan_probe(hpbdev, i); - - platform_set_drvdata(pdev, hpbdev); - err = dma_async_device_register(dma_dev); - if (!err) - return 0; - - shdma_cleanup(&hpbdev->shdma_dev); -error: - pm_runtime_disable(&pdev->dev); - return err; -} - -static void hpb_dmae_chan_remove(struct hpb_dmae_device *hpbdev) -{ - struct shdma_chan *schan; - int i; - - shdma_for_each_chan(schan, &hpbdev->shdma_dev, i) { - BUG_ON(!schan); - - shdma_chan_remove(schan); - } -} - -static int hpb_dmae_remove(struct platform_device *pdev) -{ - struct hpb_dmae_device *hpbdev = platform_get_drvdata(pdev); - - dma_async_device_unregister(&hpbdev->shdma_dev.dma_dev); - - pm_runtime_disable(&pdev->dev); - - hpb_dmae_chan_remove(hpbdev); - - return 0; -} - -static void hpb_dmae_shutdown(struct platform_device *pdev) -{ - struct hpb_dmae_device *hpbdev = platform_get_drvdata(pdev); - hpb_dmae_ctl_stop(hpbdev); -} - -static struct platform_driver hpb_dmae_driver = { - .probe = hpb_dmae_probe, - .remove = hpb_dmae_remove, - .shutdown = hpb_dmae_shutdown, - .driver = { - .name = "hpb-dma-engine", - }, -}; -module_platform_driver(hpb_dmae_driver); - -MODULE_AUTHOR("Max Filippov "); -MODULE_DESCRIPTION("Renesas HPB DMA Engine driver"); -MODULE_LICENSE("GPL"); diff --git a/include/linux/platform_data/dma-rcar-hpbdma.h b/include/linux/platform_data/dma-rcar-hpbdma.h deleted file mode 100644 index 648b8ea61a22d..0000000000000 --- a/include/linux/platform_data/dma-rcar-hpbdma.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2011-2013 Renesas Electronics Corporation - * Copyright (C) 2013 Cogent Embedded, Inc. - * - * 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. - */ - -#ifndef __DMA_RCAR_HPBDMA_H -#define __DMA_RCAR_HPBDMA_H - -#include -#include - -/* Transmit sizes and respective register values */ -enum { - XMIT_SZ_8BIT = 0, - XMIT_SZ_16BIT = 1, - XMIT_SZ_32BIT = 2, - XMIT_SZ_MAX -}; - -/* DMA control register (DCR) bits */ -#define HPB_DMAE_DCR_DTAMD (1u << 26) -#define HPB_DMAE_DCR_DTAC (1u << 25) -#define HPB_DMAE_DCR_DTAU (1u << 24) -#define HPB_DMAE_DCR_DTAU1 (1u << 23) -#define HPB_DMAE_DCR_SWMD (1u << 22) -#define HPB_DMAE_DCR_BTMD (1u << 21) -#define HPB_DMAE_DCR_PKMD (1u << 20) -#define HPB_DMAE_DCR_CT (1u << 18) -#define HPB_DMAE_DCR_ACMD (1u << 17) -#define HPB_DMAE_DCR_DIP (1u << 16) -#define HPB_DMAE_DCR_SMDL (1u << 13) -#define HPB_DMAE_DCR_SPDAM (1u << 12) -#define HPB_DMAE_DCR_SDRMD_MASK (3u << 10) -#define HPB_DMAE_DCR_SDRMD_MOD (0u << 10) -#define HPB_DMAE_DCR_SDRMD_AUTO (1u << 10) -#define HPB_DMAE_DCR_SDRMD_TIMER (2u << 10) -#define HPB_DMAE_DCR_SPDS_MASK (3u << 8) -#define HPB_DMAE_DCR_SPDS_8BIT (0u << 8) -#define HPB_DMAE_DCR_SPDS_16BIT (1u << 8) -#define HPB_DMAE_DCR_SPDS_32BIT (2u << 8) -#define HPB_DMAE_DCR_DMDL (1u << 5) -#define HPB_DMAE_DCR_DPDAM (1u << 4) -#define HPB_DMAE_DCR_DDRMD_MASK (3u << 2) -#define HPB_DMAE_DCR_DDRMD_MOD (0u << 2) -#define HPB_DMAE_DCR_DDRMD_AUTO (1u << 2) -#define HPB_DMAE_DCR_DDRMD_TIMER (2u << 2) -#define HPB_DMAE_DCR_DPDS_MASK (3u << 0) -#define HPB_DMAE_DCR_DPDS_8BIT (0u << 0) -#define HPB_DMAE_DCR_DPDS_16BIT (1u << 0) -#define HPB_DMAE_DCR_DPDS_32BIT (2u << 0) - -/* Asynchronous reset register (ASYNCRSTR) bits */ -#define HPB_DMAE_ASYNCRSTR_ASRST41 BIT(10) -#define HPB_DMAE_ASYNCRSTR_ASRST40 BIT(9) -#define HPB_DMAE_ASYNCRSTR_ASRST39 BIT(8) -#define HPB_DMAE_ASYNCRSTR_ASRST27 BIT(7) -#define HPB_DMAE_ASYNCRSTR_ASRST26 BIT(6) -#define HPB_DMAE_ASYNCRSTR_ASRST25 BIT(5) -#define HPB_DMAE_ASYNCRSTR_ASRST24 BIT(4) -#define HPB_DMAE_ASYNCRSTR_ASRST23 BIT(3) -#define HPB_DMAE_ASYNCRSTR_ASRST22 BIT(2) -#define HPB_DMAE_ASYNCRSTR_ASRST21 BIT(1) -#define HPB_DMAE_ASYNCRSTR_ASRST20 BIT(0) - -struct hpb_dmae_slave_config { - unsigned int id; - dma_addr_t addr; - u32 dcr; - u32 port; - u32 rstr; - u32 mdr; - u32 mdm; - u32 flags; -#define HPB_DMAE_SET_ASYNC_RESET BIT(0) -#define HPB_DMAE_SET_ASYNC_MODE BIT(1) - u32 dma_ch; -}; - -#define HPB_DMAE_CHANNEL(_irq, _s_id) \ -{ \ - .ch_irq = _irq, \ - .s_id = _s_id, \ -} - -struct hpb_dmae_channel { - unsigned int ch_irq; - unsigned int s_id; -}; - -struct hpb_dmae_pdata { - const struct hpb_dmae_slave_config *slaves; - int num_slaves; - const struct hpb_dmae_channel *channels; - int num_channels; - const unsigned int ts_shift[XMIT_SZ_MAX]; - int num_hw_channels; -}; - -#endif -- GitLab From aea08a5dfadf387153cdbbff89f775b0e19d32e4 Mon Sep 17 00:00:00 2001 From: M'boumba Cedric Madianga Date: Mon, 7 Dec 2015 12:00:28 +0100 Subject: [PATCH 1061/2855] dmaengine: stm32-dma: Fix unchecked deference of chan->desc 'commit d8b468394fb7 ("dmaengine: Add STM32 DMA driver")' leads to the following Smatch complaint: drivers/dma/stm32-dma.c:562 stm32_dma_issue_pending() error: we previously assumed 'chan->desc' could be null (see line 560) So, this patch fixes the unchecked dereference of chan->desc by returning operation not permitted error when stm32_dma_start_transfer() does not succeed to allocate a virtual channel descriptor. Reported-by: Dan Carpenter Signed-off-by: M'boumba Cedric Madianga Signed-off-by: Vinod Koul --- drivers/dma/stm32-dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c index 12f3a3eddba92..047476a1383dd 100644 --- a/drivers/dma/stm32-dma.c +++ b/drivers/dma/stm32-dma.c @@ -437,7 +437,7 @@ static int stm32_dma_start_transfer(struct stm32_dma_chan *chan) if (!chan->desc) { vdesc = vchan_next_desc(&chan->vchan); if (!vdesc) - return 0; + return -EPERM; chan->desc = to_stm32_dma_desc(vdesc); chan->next_sg = 0; @@ -559,7 +559,7 @@ static void stm32_dma_issue_pending(struct dma_chan *c) if (!chan->busy) { if (vchan_issue_pending(&chan->vchan) && !chan->desc) { ret = stm32_dma_start_transfer(chan); - if ((chan->desc->cyclic) && (!ret)) + if ((!ret) && (chan->desc->cyclic)) stm32_dma_configure_next_sg(chan); } } -- GitLab From d64d02ce4ebaa79bf1c026e81a956f133938af65 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 10 Dec 2015 20:04:05 +1100 Subject: [PATCH 1062/2855] powerpc: Call check_if_tm_restore_required() in enable_kernel_*() Commit a0e72cf12b1a ("powerpc: Create msr_check_and_{set,clear}()") removed a call to check_if_tm_restore_required() in the enable_kernel_*() functions. Add them back in. Fixes: a0e72cf12b1a ("powerpc: Create msr_check_and_{set,clear}()") Reported-by: Rashmica Gupta Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/process.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 58194c3f421ea..1eeda3b80b65b 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -181,8 +181,10 @@ void enable_kernel_fp(void) msr_check_and_set(MSR_FP); - if (current->thread.regs && (current->thread.regs->msr & MSR_FP)) + if (current->thread.regs && (current->thread.regs->msr & MSR_FP)) { + check_if_tm_restore_required(current); __giveup_fpu(current); + } } EXPORT_SYMBOL(enable_kernel_fp); #endif /* CONFIG_PPC_FPU */ @@ -204,8 +206,10 @@ void enable_kernel_altivec(void) msr_check_and_set(MSR_VEC); - if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) + if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) { + check_if_tm_restore_required(current); __giveup_altivec(current); + } } EXPORT_SYMBOL(enable_kernel_altivec); @@ -249,6 +253,7 @@ void enable_kernel_vsx(void) msr_check_and_set(MSR_FP|MSR_VEC|MSR_VSX); if (current->thread.regs && (current->thread.regs->msr & MSR_VSX)) { + check_if_tm_restore_required(current); if (current->thread.regs->msr & MSR_FP) __giveup_fpu(current); if (current->thread.regs->msr & MSR_VEC) @@ -289,8 +294,10 @@ void enable_kernel_spe(void) msr_check_and_set(MSR_SPE); - if (current->thread.regs && (current->thread.regs->msr & MSR_SPE)) + if (current->thread.regs && (current->thread.regs->msr & MSR_SPE)) { + check_if_tm_restore_required(current); __giveup_spe(current); + } } EXPORT_SYMBOL(enable_kernel_spe); -- GitLab From 20dbe67062062c2a790832f0d30e73dba45df7c4 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 10 Dec 2015 20:44:39 +1100 Subject: [PATCH 1063/2855] powerpc: Call restore_sprs() before _switch() commit 152d523e6307 ("powerpc: Create context switch helpers save_sprs() and restore_sprs()") moved the restore of SPRs after the call to _switch(). There is an issue with this approach - new tasks do not return through _switch(), they are set up by copy_thread() to directly return through ret_from_fork() or ret_from_kernel_thread(). This means restore_sprs() is not getting called for new tasks. Fix this by moving restore_sprs() before _switch(). Fixes: 152d523e6307 ("powerpc: Create context switch helpers save_sprs() and restore_sprs()") Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/process.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 1eeda3b80b65b..9da7b5f0c3a55 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -971,14 +971,17 @@ struct task_struct *__switch_to(struct task_struct *prev, tm_recheckpoint_new_task(new); - last = _switch(old_thread, new_thread); - - /* Need to recalculate these after calling _switch() */ - old_thread = &last->thread; - new_thread = ¤t->thread; - + /* + * Call restore_sprs() before calling _switch(). If we move it after + * _switch() then we miss out on calling it for new tasks. The reason + * for this is we manually create a stack frame for new tasks that + * directly returns through ret_from_fork() or + * ret_from_kernel_thread(). See copy_thread() for details. + */ restore_sprs(old_thread, new_thread); + last = _switch(old_thread, new_thread); + #ifdef CONFIG_PPC_BOOK3S_64 if (current_thread_info()->local_flags & _TLF_LAZY_MMU) { current_thread_info()->local_flags &= ~_TLF_LAZY_MMU; -- GitLab From db1231dcdb4dc6cdcbdef0babe641a9162c0dc98 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 9 Dec 2015 20:11:47 +1100 Subject: [PATCH 1064/2855] powerpc: Fix DSCR inheritance over fork() Two DSCR tests have a hack in them: /* * XXX: Force a context switch out so that DSCR * current value is copied into the thread struct * which is required for the child to inherit the * changed value. */ sleep(1); We should not be working around this in the testcase, it is a kernel bug. Fix it by copying the current DSCR to the child, instead of what we had in the thread struct at last context switch. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/process.c | 2 +- .../selftests/powerpc/dscr/dscr_inherit_exec_test.c | 8 -------- tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c | 8 -------- 3 files changed, 1 insertion(+), 17 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 9da7b5f0c3a55..6f76f25c3ee8b 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1287,7 +1287,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, #ifdef CONFIG_PPC64 if (cpu_has_feature(CPU_FTR_DSCR)) { p->thread.dscr_inherit = current->thread.dscr_inherit; - p->thread.dscr = current->thread.dscr; + p->thread.dscr = mfspr(SPRN_DSCR); } if (cpu_has_feature(CPU_FTR_HAS_PPR)) p->thread.ppr = INIT_PPR; diff --git a/tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c b/tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c index 8265504de5717..08a8b95e3bc18 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c +++ b/tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c @@ -60,14 +60,6 @@ int dscr_inherit_exec(void) else set_dscr(dscr); - /* - * XXX: Force a context switch out so that DSCR - * current value is copied into the thread struct - * which is required for the child to inherit the - * changed value. - */ - sleep(1); - pid = fork(); if (pid == -1) { perror("fork() failed"); diff --git a/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c b/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c index 4e414caf7f401..3e5a6d195e9ab 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c +++ b/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c @@ -40,14 +40,6 @@ int dscr_inherit(void) else set_dscr(dscr); - /* - * XXX: Force a context switch out so that DSCR - * current value is copied into the thread struct - * which is required for the child to inherit the - * changed value. - */ - sleep(1); - pid = fork(); if (pid == -1) { perror("fork() failed"); -- GitLab From e37390bee6fe7dfbe507a9d50cdc11344b53fa08 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 2 Dec 2015 17:26:28 -0600 Subject: [PATCH 1065/2855] cxlflash: a couple off by one bugs The "> MAX_CONTEXT" should be ">= MAX_CONTEXT". Otherwise we go one step beyond the end of the cfg->ctx_tbl[] array. Signed-off-by: Dan Carpenter Reviewed-by: Manoj Kumar Reviewed-by: Johannes Thumshirn Acked-by: Matthew R. Ochs Signed-off-by: Martin K. Petersen --- drivers/scsi/cxlflash/superpipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/cxlflash/superpipe.c b/drivers/scsi/cxlflash/superpipe.c index cac2e6a50efd8..34b21a0a926a0 100644 --- a/drivers/scsi/cxlflash/superpipe.c +++ b/drivers/scsi/cxlflash/superpipe.c @@ -1380,7 +1380,7 @@ static int cxlflash_disk_attach(struct scsi_device *sdev, } ctxid = cxl_process_element(ctx); - if (unlikely((ctxid > MAX_CONTEXT) || (ctxid < 0))) { + if (unlikely((ctxid >= MAX_CONTEXT) || (ctxid < 0))) { dev_err(dev, "%s: ctxid (%d) invalid!\n", __func__, ctxid); rc = -EPERM; goto err2; @@ -1508,7 +1508,7 @@ static int recover_context(struct cxlflash_cfg *cfg, struct ctx_info *ctxi) } ctxid = cxl_process_element(ctx); - if (unlikely((ctxid > MAX_CONTEXT) || (ctxid < 0))) { + if (unlikely((ctxid >= MAX_CONTEXT) || (ctxid < 0))) { dev_err(dev, "%s: ctxid (%d) invalid!\n", __func__, ctxid); rc = -EPERM; goto err1; -- GitLab From 21891a452a42afc2313f1e3a69040e46c1d068c1 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 3 Dec 2015 15:18:49 -0600 Subject: [PATCH 1066/2855] cxlflash: drop unlikely before IS_ERR_OR_NULL IS_ERR_OR_NULL already contain an unlikely compiler flag. Drop it. Signed-off-by: Geliang Tang Acked-by: Manoj Kumar Acked-by: Matthew R. Ochs Signed-off-by: Martin K. Petersen --- drivers/scsi/cxlflash/superpipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/cxlflash/superpipe.c b/drivers/scsi/cxlflash/superpipe.c index 34b21a0a926a0..f4020dbb55c32 100644 --- a/drivers/scsi/cxlflash/superpipe.c +++ b/drivers/scsi/cxlflash/superpipe.c @@ -1372,7 +1372,7 @@ static int cxlflash_disk_attach(struct scsi_device *sdev, } ctx = cxl_dev_context_init(cfg->dev); - if (unlikely(IS_ERR_OR_NULL(ctx))) { + if (IS_ERR_OR_NULL(ctx)) { dev_err(dev, "%s: Could not initialize context %p\n", __func__, ctx); rc = -ENODEV; @@ -1500,7 +1500,7 @@ static int recover_context(struct cxlflash_cfg *cfg, struct ctx_info *ctxi) struct afu *afu = cfg->afu; ctx = cxl_dev_context_init(cfg->dev); - if (unlikely(IS_ERR_OR_NULL(ctx))) { + if (IS_ERR_OR_NULL(ctx)) { dev_err(dev, "%s: Could not initialize context %p\n", __func__, ctx); rc = -ENODEV; -- GitLab From c965853ab06b3e8a9d024d86730b373c333fc6f3 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Thu, 3 Dec 2015 08:27:59 -0500 Subject: [PATCH 1067/2855] VMW_PVSCSI: Fix the issue of DMA-API related warnings. The driver is missing calls to pci_dma_mapping_error() after performing the DMA mapping, which caused DMA-API warning to show up in dmesg's output. Though that happens only when DMA_API_DEBUG option is enabled. This change fixes the issue and makes pvscsi_map_buffers() function more robust. Signed-off-by: Arvind Kumar Cc: Josh Boyer Reviewed-by: Thomas Hellstrom Signed-off-by: Josh Boyer Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/vmw_pvscsi.c | 45 +++++++++++++++++++++++++++++++++------ drivers/scsi/vmw_pvscsi.h | 2 +- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index 0f133c1817de3..6164634aff189 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c @@ -349,9 +349,9 @@ static void pvscsi_create_sg(struct pvscsi_ctx *ctx, * Map all data buffers for a command into PCI space and * setup the scatter/gather list if needed. */ -static void pvscsi_map_buffers(struct pvscsi_adapter *adapter, - struct pvscsi_ctx *ctx, struct scsi_cmnd *cmd, - struct PVSCSIRingReqDesc *e) +static int pvscsi_map_buffers(struct pvscsi_adapter *adapter, + struct pvscsi_ctx *ctx, struct scsi_cmnd *cmd, + struct PVSCSIRingReqDesc *e) { unsigned count; unsigned bufflen = scsi_bufflen(cmd); @@ -360,18 +360,30 @@ static void pvscsi_map_buffers(struct pvscsi_adapter *adapter, e->dataLen = bufflen; e->dataAddr = 0; if (bufflen == 0) - return; + return 0; sg = scsi_sglist(cmd); count = scsi_sg_count(cmd); if (count != 0) { int segs = scsi_dma_map(cmd); - if (segs > 1) { + + if (segs == -ENOMEM) { + scmd_printk(KERN_ERR, cmd, + "vmw_pvscsi: Failed to map cmd sglist for DMA.\n"); + return -ENOMEM; + } else if (segs > 1) { pvscsi_create_sg(ctx, sg, segs); e->flags |= PVSCSI_FLAG_CMD_WITH_SG_LIST; ctx->sglPA = pci_map_single(adapter->dev, ctx->sgl, SGL_SIZE, PCI_DMA_TODEVICE); + if (pci_dma_mapping_error(adapter->dev, ctx->sglPA)) { + scmd_printk(KERN_ERR, cmd, + "vmw_pvscsi: Failed to map ctx sglist for DMA.\n"); + scsi_dma_unmap(cmd); + ctx->sglPA = 0; + return -ENOMEM; + } e->dataAddr = ctx->sglPA; } else e->dataAddr = sg_dma_address(sg); @@ -382,8 +394,15 @@ static void pvscsi_map_buffers(struct pvscsi_adapter *adapter, */ ctx->dataPA = pci_map_single(adapter->dev, sg, bufflen, cmd->sc_data_direction); + if (pci_dma_mapping_error(adapter->dev, ctx->dataPA)) { + scmd_printk(KERN_ERR, cmd, + "vmw_pvscsi: Failed to map direct data buffer for DMA.\n"); + return -ENOMEM; + } e->dataAddr = ctx->dataPA; } + + return 0; } static void pvscsi_unmap_buffers(const struct pvscsi_adapter *adapter, @@ -690,6 +709,12 @@ static int pvscsi_queue_ring(struct pvscsi_adapter *adapter, ctx->sensePA = pci_map_single(adapter->dev, cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, PCI_DMA_FROMDEVICE); + if (pci_dma_mapping_error(adapter->dev, ctx->sensePA)) { + scmd_printk(KERN_ERR, cmd, + "vmw_pvscsi: Failed to map sense buffer for DMA.\n"); + ctx->sensePA = 0; + return -ENOMEM; + } e->senseAddr = ctx->sensePA; e->senseLen = SCSI_SENSE_BUFFERSIZE; } else { @@ -711,7 +736,15 @@ static int pvscsi_queue_ring(struct pvscsi_adapter *adapter, else e->flags = 0; - pvscsi_map_buffers(adapter, ctx, cmd, e); + if (pvscsi_map_buffers(adapter, ctx, cmd, e) != 0) { + if (cmd->sense_buffer) { + pci_unmap_single(adapter->dev, ctx->sensePA, + SCSI_SENSE_BUFFERSIZE, + PCI_DMA_FROMDEVICE); + ctx->sensePA = 0; + } + return -ENOMEM; + } e->context = pvscsi_map_context(adapter, ctx); diff --git a/drivers/scsi/vmw_pvscsi.h b/drivers/scsi/vmw_pvscsi.h index ee16f0c5c47d0..12712c92f37ac 100644 --- a/drivers/scsi/vmw_pvscsi.h +++ b/drivers/scsi/vmw_pvscsi.h @@ -26,7 +26,7 @@ #include -#define PVSCSI_DRIVER_VERSION_STRING "1.0.5.0-k" +#define PVSCSI_DRIVER_VERSION_STRING "1.0.6.0-k" #define PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT 128 -- GitLab From f8aea701b77c26732f151aab4f0a70e62eb53d86 Mon Sep 17 00:00:00 2001 From: Long Li Date: Fri, 4 Dec 2015 00:07:24 -0800 Subject: [PATCH 1068/2855] storvsc: add logging for error/warning messages Introduce a logging level for storvsc to log certain error/warning messages. Those messages are helpful in some environments, e.g. Microsoft Azure, for customer support and troubleshooting purposes. Signed-off-by: Long Li Acked-by: K. Y. Srinivasan Signed-off-by: Martin K. Petersen --- drivers/scsi/storvsc_drv.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 3fba42ad9fb8a..c41f6748823a7 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -164,6 +164,26 @@ static int sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE; */ static int vmstor_proto_version; +#define STORVSC_LOGGING_NONE 0 +#define STORVSC_LOGGING_ERROR 1 +#define STORVSC_LOGGING_WARN 2 + +static int logging_level = STORVSC_LOGGING_ERROR; +module_param(logging_level, int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(logging_level, + "Logging level, 0 - None, 1 - Error (default), 2 - Warning."); + +static inline bool do_logging(int level) +{ + return logging_level >= level; +} + +#define storvsc_log(dev, level, fmt, ...) \ +do { \ + if (do_logging(level)) \ + dev_warn(&(dev)->device, fmt, ##__VA_ARGS__); \ +} while (0) + struct vmscsi_win8_extension { /* * The following were added in Windows 8 @@ -941,7 +961,8 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request) if (scmnd->result) { if (scsi_normalize_sense(scmnd->sense_buffer, - SCSI_SENSE_BUFFERSIZE, &sense_hdr)) + SCSI_SENSE_BUFFERSIZE, &sense_hdr) && + do_logging(STORVSC_LOGGING_ERROR)) scsi_print_sense_hdr(scmnd->device, "storvsc", &sense_hdr); } @@ -995,6 +1016,13 @@ static void storvsc_on_io_completion(struct hv_device *device, stor_pkt->vm_srb.sense_info_length = vstor_packet->vm_srb.sense_info_length; + if (vstor_packet->vm_srb.scsi_status != 0 || + vstor_packet->vm_srb.srb_status != SRB_STATUS_SUCCESS) + storvsc_log(device, STORVSC_LOGGING_WARN, + "cmd 0x%x scsi status 0x%x srb status 0x%x\n", + stor_pkt->vm_srb.cdb[0], + vstor_packet->vm_srb.scsi_status, + vstor_packet->vm_srb.srb_status); if ((vstor_packet->vm_srb.scsi_status & 0xFF) == 0x02) { /* CHECK_CONDITION */ @@ -1002,6 +1030,10 @@ static void storvsc_on_io_completion(struct hv_device *device, SRB_STATUS_AUTOSENSE_VALID) { /* autosense data available */ + storvsc_log(device, STORVSC_LOGGING_WARN, + "stor pkt %p autosense data valid - len %d\n", + request, vstor_packet->vm_srb.sense_info_length); + memcpy(request->cmd->sense_buffer, vstor_packet->vm_srb.sense_data, vstor_packet->vm_srb.sense_info_length); -- GitLab From 9a2fcad8dce219df6cac3db91f373080f017856a Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 8 Dec 2015 15:25:16 +0100 Subject: [PATCH 1069/2855] osd: fix signed char versus %02x issue If char is signed and one of these bytes happen to have a value outside the ascii range, the corresponding output will consist of "ffffff" followed by the two hex chars that were actually intended. One way to fix it would be to change the casts to (u8*) aka (unsigned char*), but it is much simpler (and generates smaller code) to use the %ph extension which was created for such short hexdumps. Signed-off-by: Rasmus Villemoes Acked-by: Boaz Harrosh Signed-off-by: Martin K. Petersen --- drivers/scsi/osd/osd_initiator.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 0cccd6033feb6..d8a2b5185f56e 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c @@ -170,10 +170,7 @@ static int _osd_get_print_system_info(struct osd_dev *od, /* FIXME: Where are the time utilities */ pFirst = get_attrs[a++].val_ptr; - OSD_INFO("CLOCK [0x%02x%02x%02x%02x%02x%02x]\n", - ((char *)pFirst)[0], ((char *)pFirst)[1], - ((char *)pFirst)[2], ((char *)pFirst)[3], - ((char *)pFirst)[4], ((char *)pFirst)[5]); + OSD_INFO("CLOCK [0x%6phN]\n", pFirst); if (a < nelem) { /* IBM-OSD-SIM bug, Might not have it */ unsigned len = get_attrs[a].len; -- GitLab From 9c9d18e7a680f3eceeb891e24709eda817ef738e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 9 Dec 2015 13:48:36 +0300 Subject: [PATCH 1070/2855] hisi_sas: fix error codes in hisi_sas_task_prep() There were a couple cases where the error codes weren't set and also I changed the success return to "return 0;" which is the same as "return rc;" but more explicit. Fixes: 42e7a69368a5 ('hisi_sas: Add ssp command functio') Signed-off-by: Dan Carpenter Tested-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 29290181b1319..99b1950d751c2 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -208,15 +208,19 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba, slot->status_buffer = dma_pool_alloc(hisi_hba->status_buffer_pool, GFP_ATOMIC, &slot->status_buffer_dma); - if (!slot->status_buffer) + if (!slot->status_buffer) { + rc = -ENOMEM; goto err_out_slot_buf; + } memset(slot->status_buffer, 0, HISI_SAS_STATUS_BUF_SZ); slot->command_table = dma_pool_alloc(hisi_hba->command_table_pool, GFP_ATOMIC, &slot->command_table_dma); - if (!slot->command_table) + if (!slot->command_table) { + rc = -ENOMEM; goto err_out_status_buf; + } memset(slot->command_table, 0, HISI_SAS_COMMAND_TABLE_SZ); memset(slot->cmd_hdr, 0, sizeof(struct hisi_sas_cmd_hdr)); @@ -254,7 +258,7 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba, sas_dev->running_req++; ++(*pass); - return rc; + return 0; err_out_sge: dma_pool_free(hisi_hba->sge_page_pool, slot->sge_page, -- GitLab From 207f6582dd9adb8e2ed64b4c64d6d5c009e5bbf9 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 9 Dec 2015 18:33:17 -0800 Subject: [PATCH 1071/2855] mtd: brcmnand: defer to devm_ioremap_resource() for error checking devm_ioremap_resource() does error checking on the 'res' argument, so drop the error check in bcm6368_nand.c. Signed-off-by: Brian Norris Tested-by: Simon Arlott --- drivers/mtd/nand/brcmnand/bcm6368_nand.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/mtd/nand/brcmnand/bcm6368_nand.c b/drivers/mtd/nand/brcmnand/bcm6368_nand.c index 7f5359be24f2e..34c91b0e1e694 100644 --- a/drivers/mtd/nand/brcmnand/bcm6368_nand.c +++ b/drivers/mtd/nand/brcmnand/bcm6368_nand.c @@ -105,9 +105,6 @@ static int bcm6368_nand_probe(struct platform_device *pdev) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand-int-base"); - if (!res) - return -EINVAL; - priv->base = devm_ioremap_resource(dev, res); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); -- GitLab From 9f1e8cee7742cadbe6b97f2c80b787b4ee067bae Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 10 Dec 2015 15:14:20 -0800 Subject: [PATCH 1072/2855] libnvdimm, pfn: kill ND_PFN_ALIGN The alignment constraint isn't necessary now that devm_memremap_pages() allows for unaligned mappings. Signed-off-by: Dan Williams --- drivers/nvdimm/nd.h | 7 ------- drivers/nvdimm/pfn_devs.c | 11 +---------- drivers/nvdimm/pmem.c | 15 --------------- 3 files changed, 1 insertion(+), 32 deletions(-) diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h index 417e521d299cb..2ce428e9b5849 100644 --- a/drivers/nvdimm/nd.h +++ b/drivers/nvdimm/nd.h @@ -29,13 +29,6 @@ enum { ND_MAX_LANES = 256, SECTOR_SHIFT = 9, INT_LBASIZE_ALIGNMENT = 64, -#if IS_ENABLED(CONFIG_NVDIMM_PFN) - ND_PFN_ALIGN = PAGES_PER_SECTION * PAGE_SIZE, - ND_PFN_MASK = ND_PFN_ALIGN - 1, -#else - ND_PFN_ALIGN = 0, - ND_PFN_MASK = 0, -#endif }; struct nvdimm_drvdata { diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c index 71805a1aa0f3e..96c122918ee10 100644 --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c @@ -241,10 +241,6 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn) if (!is_nd_pmem(nd_pfn->dev.parent)) return -ENODEV; - /* section alignment for simple hotplug */ - if (nvdimm_namespace_capacity(ndns) < ND_PFN_ALIGN) - return -ENODEV; - if (nvdimm_read_bytes(ndns, SZ_4K, pfn_sb, sizeof(*pfn_sb))) return -ENXIO; @@ -286,12 +282,7 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn) */ offset = le64_to_cpu(pfn_sb->dataoff); nsio = to_nd_namespace_io(&ndns->dev); - if (nsio->res.start & ND_PFN_MASK) { - dev_err(&nd_pfn->dev, - "init failed: %s not section aligned\n", - dev_name(&ndns->dev)); - return -EBUSY; - } else if (offset >= resource_size(&nsio->res)) { + if (offset >= resource_size(&nsio->res)) { dev_err(&nd_pfn->dev, "pfn array size exceeds capacity of %s\n", dev_name(&ndns->dev)); return -EBUSY; diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 8ee79893d2f5f..520c00321dadd 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -241,11 +241,6 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) if (rc == 0 || rc == -EBUSY) return rc; - /* section alignment for simple hotplug */ - if (nvdimm_namespace_capacity(ndns) < ND_PFN_ALIGN - || pmem->phys_addr & ND_PFN_MASK) - return -ENODEV; - nd_region = to_nd_region(nd_pfn->dev.parent); if (nd_region->ro) { dev_info(&nd_pfn->dev, @@ -326,16 +321,6 @@ static int nvdimm_namespace_attach_pfn(struct nd_namespace_common *ndns) if (rc) return rc; - if (PAGE_SIZE != SZ_4K) { - dev_err(dev, "only supported on systems with 4K PAGE_SIZE\n"); - return -ENXIO; - } - if (nsio->res.start & ND_PFN_MASK) { - dev_err(dev, "%s not memory hotplug section aligned\n", - dev_name(&ndns->dev)); - return -ENXIO; - } - pfn_sb = nd_pfn->pfn_sb; offset = le64_to_cpu(pfn_sb->dataoff); nd_pfn->mode = le32_to_cpu(nd_pfn->pfn_sb->mode); -- GitLab From f7c6ab80fa5fee3daccb83a3c1b3a9f39d7b931c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 10 Dec 2015 16:11:59 -0800 Subject: [PATCH 1073/2855] libnvdimm, pfn: clean up pfn create parameters In all cases __nd_pfn_create is called with default parameters which are then overridden by values in the info block. Clean up pfn creation by dropping the parameters and setting default values internal to __nd_pfn_create. Signed-off-by: Dan Williams --- drivers/nvdimm/pfn_devs.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c index 96c122918ee10..613ffcca6ecbb 100644 --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c @@ -179,7 +179,6 @@ static const struct attribute_group *nd_pfn_attribute_groups[] = { }; static struct device *__nd_pfn_create(struct nd_region *nd_region, - u8 *uuid, enum nd_pfn_mode mode, struct nd_namespace_common *ndns) { struct nd_pfn *nd_pfn; @@ -199,10 +198,7 @@ static struct device *__nd_pfn_create(struct nd_region *nd_region, return NULL; } - nd_pfn->mode = mode; - if (uuid) - uuid = kmemdup(uuid, 16, GFP_KERNEL); - nd_pfn->uuid = uuid; + nd_pfn->mode = PFN_MODE_NONE; dev = &nd_pfn->dev; dev_set_name(dev, "pfn%d.%d", nd_region->id, nd_pfn->id); dev->parent = &nd_region->dev; @@ -220,8 +216,7 @@ static struct device *__nd_pfn_create(struct nd_region *nd_region, struct device *nd_pfn_create(struct nd_region *nd_region) { - struct device *dev = __nd_pfn_create(nd_region, NULL, PFN_MODE_NONE, - NULL); + struct device *dev = __nd_pfn_create(nd_region, NULL); if (dev) __nd_device_register(dev); @@ -304,7 +299,7 @@ int nd_pfn_probe(struct nd_namespace_common *ndns, void *drvdata) return -ENODEV; nvdimm_bus_lock(&ndns->dev); - dev = __nd_pfn_create(nd_region, NULL, PFN_MODE_NONE, ndns); + dev = __nd_pfn_create(nd_region, ndns); nvdimm_bus_unlock(&ndns->dev); if (!dev) return -ENOMEM; -- GitLab From 232dce89b5b00078fcb633322edadf8badae326a Mon Sep 17 00:00:00 2001 From: "Geyslan G. Bem" Date: Fri, 11 Dec 2015 06:46:41 -0300 Subject: [PATCH 1074/2855] USB: io_edgeport: remove redundant conditions This patch removes redundant conditions. (!A || (A && B)) is the same as (!A || B). Tested by compilation only. Caught by cppcheck. Signed-off-by: Geyslan G. Bem Signed-off-by: Johan Hovold --- drivers/usb/serial/io_edgeport.c | 35 +++++++++++++------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index c0866971db2bd..f49327d20ee82 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -1046,9 +1046,8 @@ static void edge_close(struct usb_serial_port *port) edge_port->closePending = true; - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPChase))) { + if (!edge_serial->is_epic || + edge_serial->epic_descriptor.Supports.IOSPChase) { /* flush and chase */ edge_port->chaseResponsePending = true; @@ -1061,9 +1060,8 @@ static void edge_close(struct usb_serial_port *port) edge_port->chaseResponsePending = false; } - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPClose))) { + if (!edge_serial->is_epic || + edge_serial->epic_descriptor.Supports.IOSPClose) { /* close the port */ dev_dbg(&port->dev, "%s - Sending IOSP_CMD_CLOSE_PORT\n", __func__); send_iosp_ext_cmd(edge_port, IOSP_CMD_CLOSE_PORT, 0); @@ -1612,9 +1610,8 @@ static void edge_break(struct tty_struct *tty, int break_state) struct edgeport_serial *edge_serial = usb_get_serial_data(port->serial); int status; - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPChase))) { + if (!edge_serial->is_epic || + edge_serial->epic_descriptor.Supports.IOSPChase) { /* flush and chase */ edge_port->chaseResponsePending = true; @@ -1628,9 +1625,8 @@ static void edge_break(struct tty_struct *tty, int break_state) } } - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPSetClrBreak))) { + if (!edge_serial->is_epic || + edge_serial->epic_descriptor.Supports.IOSPSetClrBreak) { if (break_state == -1) { dev_dbg(&port->dev, "%s - Sending IOSP_CMD_SET_BREAK\n", __func__); status = send_iosp_ext_cmd(edge_port, @@ -2465,9 +2461,8 @@ static void change_port_settings(struct tty_struct *tty, unsigned char stop_char = STOP_CHAR(tty); unsigned char start_char = START_CHAR(tty); - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPSetXChar))) { + if (!edge_serial->is_epic || + edge_serial->epic_descriptor.Supports.IOSPSetXChar) { send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_XON_CHAR, start_char); send_iosp_ext_cmd(edge_port, @@ -2494,13 +2489,11 @@ static void change_port_settings(struct tty_struct *tty, } /* Set flow control to the configured value */ - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPSetRxFlow))) + if (!edge_serial->is_epic || + edge_serial->epic_descriptor.Supports.IOSPSetRxFlow) send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_RX_FLOW, rxFlow); - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPSetTxFlow))) + if (!edge_serial->is_epic || + edge_serial->epic_descriptor.Supports.IOSPSetTxFlow) send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_TX_FLOW, txFlow); -- GitLab From 365a0442f6def11b0b3012778d6a838c7a8e6912 Mon Sep 17 00:00:00 2001 From: "Geyslan G. Bem" Date: Fri, 11 Dec 2015 06:46:42 -0300 Subject: [PATCH 1075/2855] USB: mos7840: remove redundant condition This patch removes redundant condition. (length && length > 5) can be reduced to a single evaluation. Tested by compilation only. Caught by cppcheck. Signed-off-by: Geyslan G. Bem Signed-off-by: Johan Hovold --- drivers/usb/serial/mos7840.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 8ac9b55f05afb..2c69bfcdacc64 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -635,7 +635,7 @@ static void mos7840_interrupt_callback(struct urb *urb) * Byte 4 IIR Port 4 (port.number is 3) * Byte 5 FIFO status for both */ - if (length && length > 5) { + if (length > 5) { dev_dbg(&urb->dev->dev, "%s", "Wrong data !!!\n"); return; } -- GitLab From 320092a05dab2f44819c42f33d6b51efb6c474f2 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Fri, 11 Dec 2015 15:02:34 +0100 Subject: [PATCH 1076/2855] mtd: nand: denali: add missing nand_release() call in denali_remove() Unregister the NAND device from the NAND subsystem when removing a denali NAND controller, otherwise the MTD attached to the NAND device is still exposed by the MTD layer, and accesses to this device will likely crash the system. Fixes: 2a0a288ec258 ("mtd: denali: split the generic driver and PCI layer") Signed-off-by: Boris Brezillon Acked-by: Dinh Nguyen Signed-off-by: Brian Norris --- drivers/mtd/nand/denali.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 67eb2be0db87b..9a5035cac1294 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -1622,9 +1622,16 @@ EXPORT_SYMBOL(denali_init); /* driver exit point */ void denali_remove(struct denali_nand_info *denali) { + /* + * Pre-compute DMA buffer size to avoid any problems in case + * nand_release() ever changes in a way that mtd->writesize and + * mtd->oobsize are not reliable after this call. + */ + int bufsize = denali->mtd.writesize + denali->mtd.oobsize; + + nand_release(&denali->mtd); denali_irq_cleanup(denali->irq, denali); - dma_unmap_single(denali->dev, denali->buf.dma_buf, - denali->mtd.writesize + denali->mtd.oobsize, + dma_unmap_single(denali->dev, denali->buf.dma_buf, bufsize, DMA_BIDIRECTIONAL); } EXPORT_SYMBOL(denali_remove); -- GitLab From b41fa86b67bd338d4ffa0b69f0fb1c3013a489e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=A4bler?= Date: Wed, 9 Dec 2015 10:24:04 +0100 Subject: [PATCH 1077/2855] iio:adc128s052: add support for adc124s021 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oliver Stäbler Reviewed-by: Martin Kepplinger Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/adc/ti-adc128s052.txt | 4 ++-- drivers/iio/adc/Kconfig | 6 +++--- drivers/iio/adc/ti-adc128s052.c | 13 ++++++++++++- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt index 15ca6b47958e9..daa2b2c294285 100644 --- a/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt +++ b/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt @@ -1,7 +1,7 @@ -* Texas Instruments' ADC128S052 and ADC122S021 ADC chip +* Texas Instruments' ADC128S052, ADC122S021 and ADC124S021 ADC chip Required properties: - - compatible: Should be "ti,adc128s052" or "ti,adc122s021" + - compatible: Should be "ti,adc128s052", "ti,adc122s021" or "ti,adc124s021" - reg: spi chip select number for the device - vref-supply: The regulator supply for ADC reference voltage diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 9162dfefff30d..57e3ca0b7ff45 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -332,11 +332,11 @@ config TI_ADC081C called ti-adc081c. config TI_ADC128S052 - tristate "Texas Instruments ADC128S052/ADC122S021" + tristate "Texas Instruments ADC128S052/ADC122S021/ADC124S021" depends on SPI help - If you say yes here you get support for Texas Instruments ADC128S052 - and ADC122S021 chips. + If you say yes here you get support for Texas Instruments ADC128S052, + ADC122S021 and ADC124S021 chips. This driver can also be built as a module. If so, the module will be called ti-adc128s052. diff --git a/drivers/iio/adc/ti-adc128s052.c b/drivers/iio/adc/ti-adc128s052.c index ff6f7f63c8d9b..bc58867d6e8d6 100644 --- a/drivers/iio/adc/ti-adc128s052.c +++ b/drivers/iio/adc/ti-adc128s052.c @@ -1,10 +1,11 @@ /* * Copyright (C) 2014 Angelo Compagnucci * - * Driver for Texas Instruments' ADC128S052 and ADC122S021 ADC chip. + * Driver for Texas Instruments' ADC128S052, ADC122S021 and ADC124S021 ADC chip. * Datasheets can be found here: * http://www.ti.com/lit/ds/symlink/adc128s052.pdf * http://www.ti.com/lit/ds/symlink/adc122s021.pdf + * http://www.ti.com/lit/ds/symlink/adc124s021.pdf * * 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 @@ -114,9 +115,17 @@ static const struct iio_chan_spec adc122s021_channels[] = { ADC128_VOLTAGE_CHANNEL(1), }; +static const struct iio_chan_spec adc124s021_channels[] = { + ADC128_VOLTAGE_CHANNEL(0), + ADC128_VOLTAGE_CHANNEL(1), + ADC128_VOLTAGE_CHANNEL(2), + ADC128_VOLTAGE_CHANNEL(3), +}; + static const struct adc128_configuration adc128_config[] = { { adc128s052_channels, ARRAY_SIZE(adc128s052_channels) }, { adc122s021_channels, ARRAY_SIZE(adc122s021_channels) }, + { adc124s021_channels, ARRAY_SIZE(adc124s021_channels) }, }; static const struct iio_info adc128_info = { @@ -177,6 +186,7 @@ static int adc128_remove(struct spi_device *spi) static const struct of_device_id adc128_of_match[] = { { .compatible = "ti,adc128s052", }, { .compatible = "ti,adc122s021", }, + { .compatible = "ti,adc124s021", }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, adc128_of_match); @@ -184,6 +194,7 @@ MODULE_DEVICE_TABLE(of, adc128_of_match); static const struct spi_device_id adc128_id[] = { { "adc128s052", 0}, /* index into adc128_config */ { "adc122s021", 1}, + { "adc124s021", 2}, { } }; MODULE_DEVICE_TABLE(spi, adc128_id); -- GitLab From 4d33615df58bf308626489cbfb8acbc8bbd45658 Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Wed, 9 Dec 2015 22:04:49 -0800 Subject: [PATCH 1078/2855] iio: light: add MAX30100 oximeter driver support MAX30100 is an heart rate and pulse oximeter sensor that works using two LEDS of different wavelengths, and detecting the light reflected back. This patchset adds support for both IR and RED LED channels which can be processed in userspace to determine heart rate and blood oxygen levels. Signed-off-by: Matt Ranostay Signed-off-by: Jonathan Cameron --- .../bindings/iio/health/max30100.txt | 21 + drivers/iio/Kconfig | 1 + drivers/iio/Makefile | 1 + drivers/iio/health/Kconfig | 21 + drivers/iio/health/Makefile | 7 + drivers/iio/health/max30100.c | 453 ++++++++++++++++++ 6 files changed, 504 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/health/max30100.txt create mode 100644 drivers/iio/health/Kconfig create mode 100644 drivers/iio/health/Makefile create mode 100644 drivers/iio/health/max30100.c diff --git a/Documentation/devicetree/bindings/iio/health/max30100.txt b/Documentation/devicetree/bindings/iio/health/max30100.txt new file mode 100644 index 0000000000000..f6fbac66ad06e --- /dev/null +++ b/Documentation/devicetree/bindings/iio/health/max30100.txt @@ -0,0 +1,21 @@ +Maxim MAX30100 heart rate and pulse oximeter sensor + +* https://datasheets.maximintegrated.com/en/ds/MAX30100.pdf + +Required properties: + - compatible: must be "maxim,max30100" + - reg: the I2C address of the sensor + - interrupt-parent: should be the phandle for the interrupt controller + - interrupts: the sole interrupt generated by the device + + Refer to interrupt-controller/interrupts.txt for generic + interrupt client node bindings. + +Example: + +max30100@057 { + compatible = "maxim,max30100"; + reg = <57>; + interrupt-parent = <&gpio1>; + interrupts = <16 2>; +}; diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index ac8715e56ba18..505e921f0b19e 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -69,6 +69,7 @@ source "drivers/iio/dac/Kconfig" source "drivers/iio/dummy/Kconfig" source "drivers/iio/frequency/Kconfig" source "drivers/iio/gyro/Kconfig" +source "drivers/iio/health/Kconfig" source "drivers/iio/humidity/Kconfig" source "drivers/iio/imu/Kconfig" source "drivers/iio/light/Kconfig" diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index f670b82298aae..20f649073462e 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -21,6 +21,7 @@ obj-y += dac/ obj-y += dummy/ obj-y += gyro/ obj-y += frequency/ +obj-y += health/ obj-y += humidity/ obj-y += imu/ obj-y += light/ diff --git a/drivers/iio/health/Kconfig b/drivers/iio/health/Kconfig new file mode 100644 index 0000000000000..a647679da805c --- /dev/null +++ b/drivers/iio/health/Kconfig @@ -0,0 +1,21 @@ +# +# Health sensors +# +# When adding new entries keep the list in alphabetical order + +menu "Health sensors" + +config MAX30100 + tristate "MAX30100 heart rate and pulse oximeter sensor" + depends on I2C + select REGMAP_I2C + select IIO_BUFFER + select IIO_KFIFO_BUF + help + Say Y here to build I2C interface support for the Maxim + MAX30100 heart rate, and pulse oximeter sensor. + + To compile this driver as a module, choose M here: the + module will be called max30100. + +endmenu diff --git a/drivers/iio/health/Makefile b/drivers/iio/health/Makefile new file mode 100644 index 0000000000000..7c475d7faad8f --- /dev/null +++ b/drivers/iio/health/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for IIO Health sensors +# + +# When adding new entries keep the list in alphabetical order + +obj-$(CONFIG_MAX30100) += max30100.o diff --git a/drivers/iio/health/max30100.c b/drivers/iio/health/max30100.c new file mode 100644 index 0000000000000..9d1c81f91dd77 --- /dev/null +++ b/drivers/iio/health/max30100.c @@ -0,0 +1,453 @@ +/* + * max30100.c - Support for MAX30100 heart rate and pulse oximeter sensor + * + * Copyright (C) 2015 Matt Ranostay + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * TODO: allow LED current and pulse length controls via device tree properties + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX30100_REGMAP_NAME "max30100_regmap" +#define MAX30100_DRV_NAME "max30100" + +#define MAX30100_REG_INT_STATUS 0x00 +#define MAX30100_REG_INT_STATUS_PWR_RDY BIT(0) +#define MAX30100_REG_INT_STATUS_SPO2_RDY BIT(4) +#define MAX30100_REG_INT_STATUS_HR_RDY BIT(5) +#define MAX30100_REG_INT_STATUS_FIFO_RDY BIT(7) + +#define MAX30100_REG_INT_ENABLE 0x01 +#define MAX30100_REG_INT_ENABLE_SPO2_EN BIT(0) +#define MAX30100_REG_INT_ENABLE_HR_EN BIT(1) +#define MAX30100_REG_INT_ENABLE_FIFO_EN BIT(3) +#define MAX30100_REG_INT_ENABLE_MASK 0xf0 +#define MAX30100_REG_INT_ENABLE_MASK_SHIFT 4 + +#define MAX30100_REG_FIFO_WR_PTR 0x02 +#define MAX30100_REG_FIFO_OVR_CTR 0x03 +#define MAX30100_REG_FIFO_RD_PTR 0x04 +#define MAX30100_REG_FIFO_DATA 0x05 +#define MAX30100_REG_FIFO_DATA_ENTRY_COUNT 16 +#define MAX30100_REG_FIFO_DATA_ENTRY_LEN 4 + +#define MAX30100_REG_MODE_CONFIG 0x06 +#define MAX30100_REG_MODE_CONFIG_MODE_SPO2_EN BIT(0) +#define MAX30100_REG_MODE_CONFIG_MODE_HR_EN BIT(1) +#define MAX30100_REG_MODE_CONFIG_MODE_MASK 0x03 +#define MAX30100_REG_MODE_CONFIG_TEMP_EN BIT(3) +#define MAX30100_REG_MODE_CONFIG_PWR BIT(7) + +#define MAX30100_REG_SPO2_CONFIG 0x07 +#define MAX30100_REG_SPO2_CONFIG_100HZ BIT(2) +#define MAX30100_REG_SPO2_CONFIG_HI_RES_EN BIT(6) +#define MAX30100_REG_SPO2_CONFIG_1600US 0x3 + +#define MAX30100_REG_LED_CONFIG 0x09 +#define MAX30100_REG_LED_CONFIG_RED_LED_SHIFT 4 + +#define MAX30100_REG_LED_CONFIG_24MA 0x07 +#define MAX30100_REG_LED_CONFIG_50MA 0x0f + +#define MAX30100_REG_TEMP_INTEGER 0x16 +#define MAX30100_REG_TEMP_FRACTION 0x17 + +struct max30100_data { + struct i2c_client *client; + struct iio_dev *indio_dev; + struct mutex lock; + struct regmap *regmap; + + __be16 buffer[2]; /* 2 16-bit channels */ +}; + +static bool max30100_is_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MAX30100_REG_INT_STATUS: + case MAX30100_REG_MODE_CONFIG: + case MAX30100_REG_FIFO_WR_PTR: + case MAX30100_REG_FIFO_OVR_CTR: + case MAX30100_REG_FIFO_RD_PTR: + case MAX30100_REG_FIFO_DATA: + case MAX30100_REG_TEMP_INTEGER: + case MAX30100_REG_TEMP_FRACTION: + return true; + default: + return false; + } +} + +static const struct regmap_config max30100_regmap_config = { + .name = MAX30100_REGMAP_NAME, + + .reg_bits = 8, + .val_bits = 8, + + .max_register = MAX30100_REG_TEMP_FRACTION, + .cache_type = REGCACHE_FLAT, + + .volatile_reg = max30100_is_volatile_reg, +}; + +static const unsigned long max30100_scan_masks[] = {0x3, 0}; + +static const struct iio_chan_spec max30100_channels[] = { + { + .type = IIO_INTENSITY, + .channel2 = IIO_MOD_LIGHT_IR, + .modified = 1, + + .scan_index = 0, + .scan_type = { + .sign = 'u', + .realbits = 16, + .storagebits = 16, + .endianness = IIO_BE, + }, + }, + { + .type = IIO_INTENSITY, + .channel2 = IIO_MOD_LIGHT_RED, + .modified = 1, + + .scan_index = 1, + .scan_type = { + .sign = 'u', + .realbits = 16, + .storagebits = 16, + .endianness = IIO_BE, + }, + }, + { + .type = IIO_TEMP, + .info_mask_separate = + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + .scan_index = -1, + }, +}; + +static int max30100_set_powermode(struct max30100_data *data, bool state) +{ + return regmap_update_bits(data->regmap, MAX30100_REG_MODE_CONFIG, + MAX30100_REG_MODE_CONFIG_PWR, + state ? 0 : MAX30100_REG_MODE_CONFIG_PWR); +} + +static int max30100_clear_fifo(struct max30100_data *data) +{ + int ret; + + ret = regmap_write(data->regmap, MAX30100_REG_FIFO_WR_PTR, 0); + if (ret) + return ret; + + ret = regmap_write(data->regmap, MAX30100_REG_FIFO_OVR_CTR, 0); + if (ret) + return ret; + + return regmap_write(data->regmap, MAX30100_REG_FIFO_RD_PTR, 0); +} + +static int max30100_buffer_postenable(struct iio_dev *indio_dev) +{ + struct max30100_data *data = iio_priv(indio_dev); + int ret; + + ret = max30100_set_powermode(data, true); + if (ret) + return ret; + + return max30100_clear_fifo(data); +} + +static int max30100_buffer_predisable(struct iio_dev *indio_dev) +{ + struct max30100_data *data = iio_priv(indio_dev); + + return max30100_set_powermode(data, false); +} + +static const struct iio_buffer_setup_ops max30100_buffer_setup_ops = { + .postenable = max30100_buffer_postenable, + .predisable = max30100_buffer_predisable, +}; + +static inline int max30100_fifo_count(struct max30100_data *data) +{ + unsigned int val; + int ret; + + ret = regmap_read(data->regmap, MAX30100_REG_INT_STATUS, &val); + if (ret) + return ret; + + /* FIFO is almost full */ + if (val & MAX30100_REG_INT_STATUS_FIFO_RDY) + return MAX30100_REG_FIFO_DATA_ENTRY_COUNT - 1; + + return 0; +} + +static int max30100_read_measurement(struct max30100_data *data) +{ + int ret; + + ret = i2c_smbus_read_i2c_block_data(data->client, + MAX30100_REG_FIFO_DATA, + MAX30100_REG_FIFO_DATA_ENTRY_LEN, + (u8 *) &data->buffer); + + return (ret == MAX30100_REG_FIFO_DATA_ENTRY_LEN) ? 0 : ret; +} + +static irqreturn_t max30100_interrupt_handler(int irq, void *private) +{ + struct iio_dev *indio_dev = private; + struct max30100_data *data = iio_priv(indio_dev); + int ret, cnt = 0; + + mutex_lock(&data->lock); + + while (cnt-- || (cnt = max30100_fifo_count(data) > 0)) { + ret = max30100_read_measurement(data); + if (ret) + break; + + iio_push_to_buffers(data->indio_dev, data->buffer); + } + + mutex_unlock(&data->lock); + + return IRQ_HANDLED; +} + +static int max30100_chip_init(struct max30100_data *data) +{ + int ret; + + /* RED IR LED = 24mA, IR LED = 50mA */ + ret = regmap_write(data->regmap, MAX30100_REG_LED_CONFIG, + (MAX30100_REG_LED_CONFIG_24MA << + MAX30100_REG_LED_CONFIG_RED_LED_SHIFT) | + MAX30100_REG_LED_CONFIG_50MA); + if (ret) + return ret; + + /* enable hi-res SPO2 readings at 100Hz */ + ret = regmap_write(data->regmap, MAX30100_REG_SPO2_CONFIG, + MAX30100_REG_SPO2_CONFIG_HI_RES_EN | + MAX30100_REG_SPO2_CONFIG_100HZ); + if (ret) + return ret; + + /* enable SPO2 mode */ + ret = regmap_update_bits(data->regmap, MAX30100_REG_MODE_CONFIG, + MAX30100_REG_MODE_CONFIG_MODE_MASK, + MAX30100_REG_MODE_CONFIG_MODE_HR_EN | + MAX30100_REG_MODE_CONFIG_MODE_SPO2_EN); + if (ret) + return ret; + + /* enable FIFO interrupt */ + return regmap_update_bits(data->regmap, MAX30100_REG_INT_ENABLE, + MAX30100_REG_INT_ENABLE_MASK, + MAX30100_REG_INT_ENABLE_FIFO_EN + << MAX30100_REG_INT_ENABLE_MASK_SHIFT); +} + +static int max30100_read_temp(struct max30100_data *data, int *val) +{ + int ret; + unsigned int reg; + + ret = regmap_read(data->regmap, MAX30100_REG_TEMP_INTEGER, ®); + if (ret < 0) + return ret; + *val = reg << 4; + + ret = regmap_read(data->regmap, MAX30100_REG_TEMP_FRACTION, ®); + if (ret < 0) + return ret; + + *val |= reg & 0xf; + *val = sign_extend32(*val, 11); + + return 0; +} + +static int max30100_get_temp(struct max30100_data *data, int *val) +{ + int ret; + + /* start acquisition */ + ret = regmap_update_bits(data->regmap, MAX30100_REG_MODE_CONFIG, + MAX30100_REG_MODE_CONFIG_TEMP_EN, + MAX30100_REG_MODE_CONFIG_TEMP_EN); + if (ret) + return ret; + + usleep_range(35000, 50000); + + return max30100_read_temp(data, val); +} + +static int max30100_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct max30100_data *data = iio_priv(indio_dev); + int ret = -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + /* + * Temperature reading can only be acquired while engine + * is running + */ + mutex_lock(&indio_dev->mlock); + + if (!iio_buffer_enabled(indio_dev)) + ret = -EAGAIN; + else { + ret = max30100_get_temp(data, val); + if (!ret) + ret = IIO_VAL_INT; + + } + + mutex_unlock(&indio_dev->mlock); + break; + case IIO_CHAN_INFO_SCALE: + *val = 1; /* 0.0625 */ + *val2 = 16; + ret = IIO_VAL_FRACTIONAL; + break; + } + + return ret; +} + +static const struct iio_info max30100_info = { + .driver_module = THIS_MODULE, + .read_raw = max30100_read_raw, +}; + +static int max30100_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct max30100_data *data; + struct iio_buffer *buffer; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + buffer = devm_iio_kfifo_allocate(&client->dev); + if (!buffer) + return -ENOMEM; + + iio_device_attach_buffer(indio_dev, buffer); + + indio_dev->name = MAX30100_DRV_NAME; + indio_dev->channels = max30100_channels; + indio_dev->info = &max30100_info; + indio_dev->num_channels = ARRAY_SIZE(max30100_channels); + indio_dev->available_scan_masks = max30100_scan_masks; + indio_dev->modes = (INDIO_BUFFER_SOFTWARE | INDIO_DIRECT_MODE); + indio_dev->setup_ops = &max30100_buffer_setup_ops; + + data = iio_priv(indio_dev); + data->indio_dev = indio_dev; + data->client = client; + + mutex_init(&data->lock); + i2c_set_clientdata(client, indio_dev); + + data->regmap = devm_regmap_init_i2c(client, &max30100_regmap_config); + if (IS_ERR(data->regmap)) { + dev_err(&client->dev, "regmap initialization failed.\n"); + return PTR_ERR(data->regmap); + } + max30100_set_powermode(data, false); + + ret = max30100_chip_init(data); + if (ret) + return ret; + + if (client->irq <= 0) { + dev_err(&client->dev, "no valid irq defined\n"); + return -EINVAL; + } + ret = devm_request_threaded_irq(&client->dev, client->irq, + NULL, max30100_interrupt_handler, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + "max30100_irq", indio_dev); + if (ret) { + dev_err(&client->dev, "request irq (%d) failed\n", client->irq); + return ret; + } + + return iio_device_register(indio_dev); +} + +static int max30100_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct max30100_data *data = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + max30100_set_powermode(data, false); + + return 0; +} + +static const struct i2c_device_id max30100_id[] = { + { "max30100", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, max30100_id); + +static const struct of_device_id max30100_dt_ids[] = { + { .compatible = "maxim,max30100" }, + { } +}; +MODULE_DEVICE_TABLE(of, max30100_dt_ids); + +static struct i2c_driver max30100_driver = { + .driver = { + .name = MAX30100_DRV_NAME, + .of_match_table = of_match_ptr(max30100_dt_ids), + }, + .probe = max30100_probe, + .remove = max30100_remove, + .id_table = max30100_id, +}; +module_i2c_driver(max30100_driver); + +MODULE_AUTHOR("Matt Ranostay "); +MODULE_DESCRIPTION("MAX30100 heart rate and pulse oximeter sensor"); +MODULE_LICENSE("GPL"); -- GitLab From 466df4d0c1a5edee243698bdcad1ec4f3a1799b1 Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Sat, 5 Dec 2015 22:58:22 -0800 Subject: [PATCH 1079/2855] iio: chemical: add AMS iAQ-core support Add support for AMS iAQ-core continuous and pulsed VOC sensors. Signed-off-by: Matt Ranostay Signed-off-by: Jonathan Cameron --- .../bindings/i2c/trivial-devices.txt | 1 + drivers/iio/chemical/Kconfig | 8 + drivers/iio/chemical/Makefile | 1 + drivers/iio/chemical/ams-iaq-core.c | 200 ++++++++++++++++++ 4 files changed, 210 insertions(+) create mode 100644 drivers/iio/chemical/ams-iaq-core.c diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt index c50cf13c852e5..f6fec952d6836 100644 --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt @@ -20,6 +20,7 @@ adi,adt7476 +/-1C TDM Extended Temp Range I.C adi,adt7490 +/-1C TDM Extended Temp Range I.C adi,adxl345 Three-Axis Digital Accelerometer adi,adxl346 Three-Axis Digital Accelerometer (backward-compatibility value "adi,adxl345" must be listed too) +ams,iaq-core AMS iAQ-Core VOC Sensor at,24c08 i2c serial eeprom (24cxx) atmel,24c00 i2c serial eeprom (24cxx) atmel,24c01 i2c serial eeprom (24cxx) diff --git a/drivers/iio/chemical/Kconfig b/drivers/iio/chemical/Kconfig index 3061b7299f0fc..f16de61be46df 100644 --- a/drivers/iio/chemical/Kconfig +++ b/drivers/iio/chemical/Kconfig @@ -4,6 +4,14 @@ menu "Chemical Sensors" +config IAQCORE + tristate "AMS iAQ-Core VOC sensors" + depends on I2C + help + Say Y here to build I2C interface support for the AMS + iAQ-Core Continuous/Pulsed VOC (Volatile Organic Compounds) + sensors + config VZ89X tristate "SGX Sensortech MiCS VZ89X VOC sensor" depends on I2C diff --git a/drivers/iio/chemical/Makefile b/drivers/iio/chemical/Makefile index 7292f2ded587a..167861fadfab7 100644 --- a/drivers/iio/chemical/Makefile +++ b/drivers/iio/chemical/Makefile @@ -3,4 +3,5 @@ # # When adding new entries keep the list in alphabetical order +obj-$(CONFIG_IAQCORE) += ams-iaq-core.o obj-$(CONFIG_VZ89X) += vz89x.o diff --git a/drivers/iio/chemical/ams-iaq-core.c b/drivers/iio/chemical/ams-iaq-core.c new file mode 100644 index 0000000000000..41a8e6f2e31db --- /dev/null +++ b/drivers/iio/chemical/ams-iaq-core.c @@ -0,0 +1,200 @@ +/* + * ams-iaq-core.c - Support for AMS iAQ-Core VOC sensors + * + * Copyright (C) 2015 Matt Ranostay + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include + +#define AMS_IAQCORE_DATA_SIZE 9 + +#define AMS_IAQCORE_VOC_CO2_IDX 0 +#define AMS_IAQCORE_VOC_RESISTANCE_IDX 1 +#define AMS_IAQCORE_VOC_TVOC_IDX 2 + +struct ams_iaqcore_reading { + __be16 co2_ppm; + u8 status; + __be32 resistance; + __be16 voc_ppb; +} __attribute__((__packed__)); + +struct ams_iaqcore_data { + struct i2c_client *client; + struct mutex lock; + unsigned long last_update; + + struct ams_iaqcore_reading buffer; +}; + +static const struct iio_chan_spec ams_iaqcore_channels[] = { + { + .type = IIO_CONCENTRATION, + .channel2 = IIO_MOD_CO2, + .modified = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .address = AMS_IAQCORE_VOC_CO2_IDX, + }, + { + .type = IIO_RESISTANCE, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .address = AMS_IAQCORE_VOC_RESISTANCE_IDX, + }, + { + .type = IIO_CONCENTRATION, + .channel2 = IIO_MOD_VOC, + .modified = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .address = AMS_IAQCORE_VOC_TVOC_IDX, + }, +}; + +static int ams_iaqcore_read_measurement(struct ams_iaqcore_data *data) +{ + struct i2c_client *client = data->client; + int ret; + + struct i2c_msg msg = { + .addr = client->addr, + .flags = client->flags | I2C_M_RD, + .len = AMS_IAQCORE_DATA_SIZE, + .buf = (char *) &data->buffer, + }; + + ret = i2c_transfer(client->adapter, &msg, 1); + + return (ret == AMS_IAQCORE_DATA_SIZE) ? 0 : ret; +} + +static int ams_iaqcore_get_measurement(struct ams_iaqcore_data *data) +{ + int ret; + + /* sensor can only be polled once a second max per datasheet */ + if (!time_after(jiffies, data->last_update + HZ)) + return 0; + + ret = ams_iaqcore_read_measurement(data); + if (ret < 0) + return ret; + + data->last_update = jiffies; + + return 0; +} + +static int ams_iaqcore_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + struct ams_iaqcore_data *data = iio_priv(indio_dev); + int ret; + + if (mask != IIO_CHAN_INFO_PROCESSED) + return -EINVAL; + + mutex_lock(&data->lock); + ret = ams_iaqcore_get_measurement(data); + + if (ret) + goto err_out; + + switch (chan->address) { + case AMS_IAQCORE_VOC_CO2_IDX: + *val = 0; + *val2 = be16_to_cpu(data->buffer.co2_ppm); + ret = IIO_VAL_INT_PLUS_MICRO; + break; + case AMS_IAQCORE_VOC_RESISTANCE_IDX: + *val = be32_to_cpu(data->buffer.resistance); + ret = IIO_VAL_INT; + break; + case AMS_IAQCORE_VOC_TVOC_IDX: + *val = 0; + *val2 = be16_to_cpu(data->buffer.voc_ppb); + ret = IIO_VAL_INT_PLUS_NANO; + break; + default: + ret = -EINVAL; + } + +err_out: + mutex_unlock(&data->lock); + + return ret; +} + +static const struct iio_info ams_iaqcore_info = { + .read_raw = ams_iaqcore_read_raw, + .driver_module = THIS_MODULE, +}; + +static int ams_iaqcore_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct iio_dev *indio_dev; + struct ams_iaqcore_data *data; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + data->client = client; + + /* so initial reading will complete */ + data->last_update = jiffies - HZ; + mutex_init(&data->lock); + + indio_dev->dev.parent = &client->dev; + indio_dev->info = &ams_iaqcore_info, + indio_dev->name = dev_name(&client->dev); + indio_dev->modes = INDIO_DIRECT_MODE; + + indio_dev->channels = ams_iaqcore_channels; + indio_dev->num_channels = ARRAY_SIZE(ams_iaqcore_channels); + + return devm_iio_device_register(&client->dev, indio_dev); +} + +static const struct i2c_device_id ams_iaqcore_id[] = { + { "ams-iaq-core", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ams_iaqcore_id); + +static const struct of_device_id ams_iaqcore_dt_ids[] = { + { .compatible = "ams,iaq-core" }, + { } +}; +MODULE_DEVICE_TABLE(of, ams_iaqcore_dt_ids); + +static struct i2c_driver ams_iaqcore_driver = { + .driver = { + .name = "ams-iaq-core", + .of_match_table = of_match_ptr(ams_iaqcore_dt_ids), + }, + .probe = ams_iaqcore_probe, + .id_table = ams_iaqcore_id, +}; +module_i2c_driver(ams_iaqcore_driver); + +MODULE_AUTHOR("Matt Ranostay "); +MODULE_DESCRIPTION("AMS iAQ-Core VOC sensors"); +MODULE_LICENSE("GPL v2"); -- GitLab From c43a102e67db99c8bfe6e8a9280cec13ff53b789 Mon Sep 17 00:00:00 2001 From: Marc Titinger Date: Mon, 7 Dec 2015 10:09:34 +0100 Subject: [PATCH 1080/2855] iio: ina2xx: add support for TI INA2xx Power Monitors in SOFTWARE buffer mode, a kthread will capture the active scan_elements into a kfifo, then compute the remaining time until the next capture tick and do an active wait (udelay). This will produce a stream of up to fours channels plus a 64bits timestamps (ns). Tested with ina226, on BeagleBoneBlack. Datasheet: http://www.ti.com/lit/gpn/ina226 Signed-off-by: Marc Titinger Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 10 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/ina2xx-adc.c | 668 +++++++++++++++++++++++++++++++++++ 3 files changed, 679 insertions(+) create mode 100644 drivers/iio/adc/ina2xx-adc.c diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 57e3ca0b7ff45..cb68bd9d20526 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -194,6 +194,16 @@ config HI8435 This driver can also be built as a module. If so, the module will be called hi8435. +config INA2XX_ADC + tristate "Texas Instruments INA2xx Power Monitors IIO driver" + depends on I2C && !SENSORS_INA2XX + select REGMAP_I2C + select IIO_BUFFER + select IIO_KFIFO_BUF + help + Say yes here to build support for TI INA2xx family of Power Monitors. + This driver is mutually exclusive with the HWMON version. + config LP8788_ADC tristate "LP8788 ADC driver" depends on MFD_LP8788 diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 91a65bf11c584..c62c5fa91c827 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o obj-$(CONFIG_DA9150_GPADC) += da9150-gpadc.o obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o obj-$(CONFIG_HI8435) += hi8435.o +obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o obj-$(CONFIG_MAX1027) += max1027.o obj-$(CONFIG_MAX1363) += max1363.o diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c new file mode 100644 index 0000000000000..707bd69a7353c --- /dev/null +++ b/drivers/iio/adc/ina2xx-adc.c @@ -0,0 +1,668 @@ +/* + * INA2XX Current and Power Monitors + * + * Copyright 2015 Baylibre SAS. + * + * 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. + * + * Based on linux/drivers/iio/adc/ad7291.c + * Copyright 2010-2011 Analog Devices Inc. + * + * Based on linux/drivers/hwmon/ina2xx.c + * Copyright 2012 Lothar Felten + * + * Licensed under the GPL-2 or later. + * + * IIO driver for INA219-220-226-230-231 + * + * Configurable 7-bit I2C slave address from 0x40 to 0x4F + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* INA2XX registers definition */ +#define INA2XX_CONFIG 0x00 +#define INA2XX_SHUNT_VOLTAGE 0x01 /* readonly */ +#define INA2XX_BUS_VOLTAGE 0x02 /* readonly */ +#define INA2XX_POWER 0x03 /* readonly */ +#define INA2XX_CURRENT 0x04 /* readonly */ +#define INA2XX_CALIBRATION 0x05 + +#define INA226_ALERT_MASK 0x06 +#define INA266_CVRF BIT(3) + +#define INA2XX_MAX_REGISTERS 8 + +/* settings - depend on use case */ +#define INA219_CONFIG_DEFAULT 0x399F /* PGA=8 */ +#define INA226_CONFIG_DEFAULT 0x4327 +#define INA226_DEFAULT_AVG 4 +#define INA226_DEFAULT_IT 1110 + +#define INA2XX_RSHUNT_DEFAULT 10000 + +/* + * bit mask for reading the averaging setting in the configuration register + * FIXME: use regmap_fields. + */ +#define INA2XX_MODE_MASK GENMASK(3, 0) + +#define INA226_AVG_MASK GENMASK(11, 9) +#define INA226_SHIFT_AVG(val) ((val) << 9) + +/* Integration time for VBus */ +#define INA226_ITB_MASK GENMASK(8, 6) +#define INA226_SHIFT_ITB(val) ((val) << 6) + +/* Integration time for VShunt */ +#define INA226_ITS_MASK GENMASK(5, 3) +#define INA226_SHIFT_ITS(val) ((val) << 3) + +/* Cosmetic macro giving the sampling period for a full P=UxI cycle */ +#define SAMPLING_PERIOD(c) ((c->int_time_vbus + c->int_time_vshunt) \ + * c->avg) + +static bool ina2xx_is_writeable_reg(struct device *dev, unsigned int reg) +{ + return (reg == INA2XX_CONFIG) || (reg > INA2XX_CURRENT); +} + +static bool ina2xx_is_volatile_reg(struct device *dev, unsigned int reg) +{ + return (reg != INA2XX_CONFIG); +} + +static inline bool is_signed_reg(unsigned int reg) +{ + return (reg == INA2XX_SHUNT_VOLTAGE) || (reg == INA2XX_CURRENT); +} + +static const struct regmap_config ina2xx_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .max_register = INA2XX_MAX_REGISTERS, + .writeable_reg = ina2xx_is_writeable_reg, + .volatile_reg = ina2xx_is_volatile_reg, +}; + +enum ina2xx_ids { ina219, ina226 }; + +struct ina2xx_config { + u16 config_default; + int calibration_factor; + int shunt_div; + int bus_voltage_shift; + int bus_voltage_lsb; /* uV */ + int power_lsb; /* uW */ +}; + +struct ina2xx_chip_info { + struct regmap *regmap; + struct task_struct *task; + const struct ina2xx_config *config; + struct mutex state_lock; + long rshunt; + int avg; + s64 prev_ns; /* track buffer capture time, check for underruns*/ + int int_time_vbus; /* Bus voltage integration time uS */ + int int_time_vshunt; /* Shunt voltage integration time uS */ +}; + +static const struct ina2xx_config ina2xx_config[] = { + [ina219] = { + .config_default = INA219_CONFIG_DEFAULT, + .calibration_factor = 40960000, + .shunt_div = 100, + .bus_voltage_shift = 3, + .bus_voltage_lsb = 4000, + .power_lsb = 20000, + }, + [ina226] = { + .config_default = INA226_CONFIG_DEFAULT, + .calibration_factor = 5120000, + .shunt_div = 400, + .bus_voltage_shift = 0, + .bus_voltage_lsb = 1250, + .power_lsb = 25000, + }, +}; + +static int ina2xx_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + int ret; + struct ina2xx_chip_info *chip = iio_priv(indio_dev); + unsigned int regval; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = regmap_read(chip->regmap, chan->address, ®val); + if (ret < 0) + return ret; + + if (is_signed_reg(chan->address)) + *val = (s16) regval; + else + *val = regval; + + return IIO_VAL_INT; + + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + *val = chip->avg; + return IIO_VAL_INT; + + case IIO_CHAN_INFO_INT_TIME: + *val = 0; + if (chan->address == INA2XX_SHUNT_VOLTAGE) + *val2 = chip->int_time_vshunt; + else + *val2 = chip->int_time_vbus; + + return IIO_VAL_INT_PLUS_MICRO; + + case IIO_CHAN_INFO_SAMP_FREQ: + /* + * Sample freq is read only, it is a consequence of + * 1/AVG*(CT_bus+CT_shunt). + */ + *val = DIV_ROUND_CLOSEST(1000000, SAMPLING_PERIOD(chip)); + + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + switch (chan->address) { + case INA2XX_SHUNT_VOLTAGE: + /* processed (mV) = raw*1000/shunt_div */ + *val2 = chip->config->shunt_div; + *val = 1000; + return IIO_VAL_FRACTIONAL; + + case INA2XX_BUS_VOLTAGE: + /* processed (mV) = raw*lsb (uV) / (1000 << shift) */ + *val = chip->config->bus_voltage_lsb; + *val2 = 1000 << chip->config->bus_voltage_shift; + return IIO_VAL_FRACTIONAL; + + case INA2XX_POWER: + /* processed (mW) = raw*lsb (uW) / 1000 */ + *val = chip->config->power_lsb; + *val2 = 1000; + return IIO_VAL_FRACTIONAL; + + case INA2XX_CURRENT: + /* processed (mA) = raw (mA) */ + *val = 1; + return IIO_VAL_INT; + } + } + + return -EINVAL; +} + +/* + * Available averaging rates for ina226. The indices correspond with + * the bit values expected by the chip (according to the ina226 datasheet, + * table 3 AVG bit settings, found at + * http://www.ti.com/lit/ds/symlink/ina226.pdf. + */ +static const int ina226_avg_tab[] = { 1, 4, 16, 64, 128, 256, 512, 1024 }; + +static int ina226_set_average(struct ina2xx_chip_info *chip, unsigned int val, + unsigned int *config) +{ + int bits; + + if (val > 1024 || val < 1) + return -EINVAL; + + bits = find_closest(val, ina226_avg_tab, + ARRAY_SIZE(ina226_avg_tab)); + + chip->avg = ina226_avg_tab[bits]; + + *config &= ~INA226_AVG_MASK; + *config |= INA226_SHIFT_AVG(bits) & INA226_AVG_MASK; + + return 0; +} + +/* Conversion times in uS */ +static const int ina226_conv_time_tab[] = { 140, 204, 332, 588, 1100, + 2116, 4156, 8244 }; + +static int ina226_set_int_time_vbus(struct ina2xx_chip_info *chip, + unsigned int val_us, unsigned int *config) +{ + int bits; + + if (val_us > 8244 || val_us < 140) + return -EINVAL; + + bits = find_closest(val_us, ina226_conv_time_tab, + ARRAY_SIZE(ina226_conv_time_tab)); + + chip->int_time_vbus = ina226_conv_time_tab[bits]; + + *config &= ~INA226_ITB_MASK; + *config |= INA226_SHIFT_ITB(bits) & INA226_ITB_MASK; + + return 0; +} + +static int ina226_set_int_time_vshunt(struct ina2xx_chip_info *chip, + unsigned int val_us, unsigned int *config) +{ + int bits; + + if (val_us > 8244 || val_us < 140) + return -EINVAL; + + bits = find_closest(val_us, ina226_conv_time_tab, + ARRAY_SIZE(ina226_conv_time_tab)); + + chip->int_time_vshunt = ina226_conv_time_tab[bits]; + + *config &= ~INA226_ITS_MASK; + *config |= INA226_SHIFT_ITS(bits) & INA226_ITS_MASK; + + return 0; +} + +static int ina2xx_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct ina2xx_chip_info *chip = iio_priv(indio_dev); + int ret; + unsigned int config, tmp; + + if (iio_buffer_enabled(indio_dev)) + return -EBUSY; + + mutex_lock(&chip->state_lock); + + ret = regmap_read(chip->regmap, INA2XX_CONFIG, &config); + if (ret < 0) + goto _err; + + tmp = config; + + switch (mask) { + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + ret = ina226_set_average(chip, val, &tmp); + break; + + case IIO_CHAN_INFO_INT_TIME: + if (chan->address == INA2XX_SHUNT_VOLTAGE) + ret = ina226_set_int_time_vshunt(chip, val2, &tmp); + else + ret = ina226_set_int_time_vbus(chip, val2, &tmp); + break; + default: + ret = -EINVAL; + } + + if (!ret && (tmp != config)) + ret = regmap_write(chip->regmap, INA2XX_CONFIG, tmp); +_err: + mutex_unlock(&chip->state_lock); + + return ret; +} + + +#define INA2XX_CHAN(_type, _index, _address) { \ + .type = (_type), \ + .address = (_address), \ + .indexed = 1, \ + .channel = (_index), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \ + | BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ + .scan_index = (_index), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_LE, \ + } \ +} + +/* + * Sampling Freq is a consequence of the integration times of + * the Voltage channels. + */ +#define INA2XX_CHAN_VOLTAGE(_index, _address) { \ + .type = IIO_VOLTAGE, \ + .address = (_address), \ + .indexed = 1, \ + .channel = (_index), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_INT_TIME), \ + .scan_index = (_index), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_LE, \ + } \ +} + +static const struct iio_chan_spec ina2xx_channels[] = { + INA2XX_CHAN_VOLTAGE(0, INA2XX_SHUNT_VOLTAGE), + INA2XX_CHAN_VOLTAGE(1, INA2XX_BUS_VOLTAGE), + INA2XX_CHAN(IIO_CURRENT, 2, INA2XX_CURRENT), + INA2XX_CHAN(IIO_POWER, 3, INA2XX_POWER), + IIO_CHAN_SOFT_TIMESTAMP(4), +}; + +static int ina2xx_work_buffer(struct iio_dev *indio_dev) +{ + struct ina2xx_chip_info *chip = iio_priv(indio_dev); + unsigned short data[8]; + int bit, ret, i = 0; + unsigned long buffer_us, elapsed_us; + s64 time_a, time_b; + unsigned int alert; + + time_a = iio_get_time_ns(); + + /* + * Because the timer thread and the chip conversion clock + * are asynchronous, the period difference will eventually + * result in reading V[k-1] again, or skip V[k] at time Tk. + * In order to resync the timer with the conversion process + * we check the ConVersionReadyFlag. + * On hardware that supports using the ALERT pin to toggle a + * GPIO a triggered buffer could be used instead. + * For now, we pay for that extra read of the ALERT register + */ + do { + ret = regmap_read(chip->regmap, INA226_ALERT_MASK, + &alert); + if (ret < 0) + return ret; + + alert &= INA266_CVRF; + trace_printk("Conversion ready: %d\n", !!alert); + + } while (!alert); + + /* + * Single register reads: bulk_read will not work with ina226 + * as there is no auto-increment of the address register for + * data length longer than 16bits. + */ + for_each_set_bit(bit, indio_dev->active_scan_mask, + indio_dev->masklength) { + unsigned int val; + + ret = regmap_read(chip->regmap, + INA2XX_SHUNT_VOLTAGE + bit, &val); + if (ret < 0) + return ret; + + data[i++] = val; + } + + time_b = iio_get_time_ns(); + + iio_push_to_buffers_with_timestamp(indio_dev, + (unsigned int *)data, time_a); + + buffer_us = (unsigned long)(time_b - time_a) / 1000; + elapsed_us = (unsigned long)(time_a - chip->prev_ns) / 1000; + + trace_printk("uS: elapsed: %lu, buf: %lu\n", elapsed_us, buffer_us); + + chip->prev_ns = time_a; + + return buffer_us; +}; + +static int ina2xx_capture_thread(void *data) +{ + struct iio_dev *indio_dev = (struct iio_dev *)data; + struct ina2xx_chip_info *chip = iio_priv(indio_dev); + unsigned int sampling_us = SAMPLING_PERIOD(chip); + int buffer_us; + + /* + * Poll a bit faster than the chip internal Fs, in case + * we wish to sync with the conversion ready flag. + */ + sampling_us -= 200; + + do { + buffer_us = ina2xx_work_buffer(indio_dev); + if (buffer_us < 0) + return buffer_us; + + if (sampling_us > buffer_us) + udelay(sampling_us - buffer_us); + + } while (!kthread_should_stop()); + + return 0; +} + +static int ina2xx_buffer_enable(struct iio_dev *indio_dev) +{ + struct ina2xx_chip_info *chip = iio_priv(indio_dev); + unsigned int sampling_us = SAMPLING_PERIOD(chip); + + trace_printk("Enabling buffer w/ scan_mask %02x, freq = %d, avg =%u\n", + (unsigned int)(*indio_dev->active_scan_mask), + 1000000/sampling_us, chip->avg); + + trace_printk("Expected work period: %u us\n", sampling_us); + + chip->prev_ns = iio_get_time_ns(); + + chip->task = kthread_run(ina2xx_capture_thread, (void *)indio_dev, + "ina2xx-%uus", sampling_us); + + return PTR_ERR_OR_ZERO(chip->task); +} + +static int ina2xx_buffer_disable(struct iio_dev *indio_dev) +{ + struct ina2xx_chip_info *chip = iio_priv(indio_dev); + + if (chip->task) { + kthread_stop(chip->task); + chip->task = NULL; + } + + return 0; +} + +static const struct iio_buffer_setup_ops ina2xx_setup_ops = { + .postenable = &ina2xx_buffer_enable, + .predisable = &ina2xx_buffer_disable, +}; + +static int ina2xx_debug_reg(struct iio_dev *indio_dev, + unsigned reg, unsigned writeval, unsigned *readval) +{ + struct ina2xx_chip_info *chip = iio_priv(indio_dev); + + if (!readval) + return regmap_write(chip->regmap, reg, writeval); + + return regmap_read(chip->regmap, reg, readval); +} + +/* Possible integration times for vshunt and vbus */ +static IIO_CONST_ATTR_INT_TIME_AVAIL \ + ("0.000140 0.000204 0.000332 0.000588 0.001100 0.002116 0.004156 0.008244"); + +static struct attribute *ina2xx_attributes[] = { + &iio_const_attr_integration_time_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ina2xx_attribute_group = { + .attrs = ina2xx_attributes, +}; + +static const struct iio_info ina2xx_info = { + .debugfs_reg_access = &ina2xx_debug_reg, + .read_raw = &ina2xx_read_raw, + .write_raw = &ina2xx_write_raw, + .attrs = &ina2xx_attribute_group, + .driver_module = THIS_MODULE, +}; + +/* Initialize the configuration and calibration registers. */ +static int ina2xx_init(struct ina2xx_chip_info *chip, unsigned int config) +{ + u16 regval; + int ret = regmap_write(chip->regmap, INA2XX_CONFIG, config); + + if (ret < 0) + return ret; + /* + * Set current LSB to 1mA, shunt is in uOhms + * (equation 13 in datasheet). We hardcode a Current_LSB + * of 1.0 x10-6. The only remaining parameter is RShunt. + * There is no need to expose the CALIBRATION register + * to the user for now. + */ + regval = DIV_ROUND_CLOSEST(chip->config->calibration_factor, + chip->rshunt); + + return regmap_write(chip->regmap, INA2XX_CALIBRATION, regval); +} + +static int ina2xx_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct ina2xx_chip_info *chip; + struct iio_dev *indio_dev; + struct iio_buffer *buffer; + int ret; + unsigned int val; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip)); + if (!indio_dev) + return -ENOMEM; + + chip = iio_priv(indio_dev); + + chip->config = &ina2xx_config[id->driver_data]; + + if (of_property_read_u32(client->dev.of_node, + "shunt-resistor", &val) < 0) { + struct ina2xx_platform_data *pdata = + dev_get_platdata(&client->dev); + + if (pdata) + val = pdata->shunt_uohms; + else + val = INA2XX_RSHUNT_DEFAULT; + } + + if (val <= 0 || val > chip->config->calibration_factor) + return -ENODEV; + + chip->rshunt = val; + + mutex_init(&chip->state_lock); + + /* This is only used for device removal purposes. */ + i2c_set_clientdata(client, indio_dev); + + indio_dev->name = id->name; + indio_dev->channels = ina2xx_channels; + indio_dev->num_channels = ARRAY_SIZE(ina2xx_channels); + + indio_dev->dev.parent = &client->dev; + indio_dev->info = &ina2xx_info; + indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE; + + chip->regmap = devm_regmap_init_i2c(client, &ina2xx_regmap_config); + if (IS_ERR(chip->regmap)) { + dev_err(&client->dev, "failed to allocate register map\n"); + return PTR_ERR(chip->regmap); + } + + /* Patch the current config register with default. */ + val = chip->config->config_default; + + if (id->driver_data == ina226) { + ina226_set_average(chip, INA226_DEFAULT_AVG, &val); + ina226_set_int_time_vbus(chip, INA226_DEFAULT_IT, &val); + ina226_set_int_time_vshunt(chip, INA226_DEFAULT_IT, &val); + } + + ret = ina2xx_init(chip, val); + if (ret < 0) { + dev_err(&client->dev, "error configuring the device: %d\n", + ret); + return -ENODEV; + } + + buffer = devm_iio_kfifo_allocate(&indio_dev->dev); + if (!buffer) + return -ENOMEM; + + indio_dev->setup_ops = &ina2xx_setup_ops; + + iio_device_attach_buffer(indio_dev, buffer); + + return iio_device_register(indio_dev); +} + + +static int ina2xx_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct ina2xx_chip_info *chip = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + + /* Powerdown */ + return regmap_update_bits(chip->regmap, INA2XX_CONFIG, + INA2XX_MODE_MASK, 0); +} + + +static const struct i2c_device_id ina2xx_id[] = { + {"ina219", ina219}, + {"ina220", ina219}, + {"ina226", ina226}, + {"ina230", ina226}, + {"ina231", ina226}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, ina2xx_id); + +static struct i2c_driver ina2xx_driver = { + .driver = { + .name = KBUILD_MODNAME, + }, + .probe = ina2xx_probe, + .remove = ina2xx_remove, + .id_table = ina2xx_id, +}; + +module_i2c_driver(ina2xx_driver); + +MODULE_AUTHOR("Marc Titinger "); +MODULE_DESCRIPTION("Texas Instruments INA2XX ADC driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From f9993c0771ce24063fe62bf73ac57bcfc9ad81de Mon Sep 17 00:00:00 2001 From: Marc Titinger Date: Mon, 7 Dec 2015 10:09:35 +0100 Subject: [PATCH 1081/2855] iio: ina2xx: provide a sysfs parameter to allow async readout of the ADCs This can lead to repeated or skipped samples depending on the clock beat between the capture thread and the chip sampling clock, but will also spare reading/waiting for the Capture Ready Flag and improve the available i2c bandwidth for reading measurements. Output of iio_info: ...snip... 4 device-specific attributes found: attr 0: in_oversampling_ratio value: 4 attr 1: in_allow_async_readout value: 0 attr 2: integration_time_available value: 140 204 332 588 1100 2116... attr 3: in_sampling_frequency value: 114 Signed-off-by: Marc Titinger Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ina2xx-adc.c | 54 ++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index 707bd69a7353c..ff31f5b49a416 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -116,6 +116,7 @@ struct ina2xx_chip_info { s64 prev_ns; /* track buffer capture time, check for underruns*/ int int_time_vbus; /* Bus voltage integration time uS */ int int_time_vshunt; /* Shunt voltage integration time uS */ + bool allow_async_readout; }; static const struct ina2xx_config ina2xx_config[] = { @@ -322,6 +323,33 @@ _err: } +static ssize_t ina2xx_allow_async_readout_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev)); + + return sprintf(buf, "%d\n", chip->allow_async_readout); +} + +static ssize_t ina2xx_allow_async_readout_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev)); + bool val; + int ret; + + ret = strtobool((const char *) buf, &val); + if (ret) + return ret; + + chip->allow_async_readout = val; + + return len; +} + + #define INA2XX_CHAN(_type, _index, _address) { \ .type = (_type), \ .address = (_address), \ @@ -390,16 +418,17 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev) * GPIO a triggered buffer could be used instead. * For now, we pay for that extra read of the ALERT register */ - do { - ret = regmap_read(chip->regmap, INA226_ALERT_MASK, - &alert); - if (ret < 0) - return ret; + if (!chip->allow_async_readout) + do { + ret = regmap_read(chip->regmap, INA226_ALERT_MASK, + &alert); + if (ret < 0) + return ret; - alert &= INA266_CVRF; - trace_printk("Conversion ready: %d\n", !!alert); + alert &= INA266_CVRF; + trace_printk("Conversion ready: %d\n", !!alert); - } while (!alert); + } while (!alert); /* * Single register reads: bulk_read will not work with ina226 @@ -444,7 +473,8 @@ static int ina2xx_capture_thread(void *data) * Poll a bit faster than the chip internal Fs, in case * we wish to sync with the conversion ready flag. */ - sampling_us -= 200; + if (!chip->allow_async_readout) + sampling_us -= 200; do { buffer_us = ina2xx_work_buffer(indio_dev); @@ -469,6 +499,7 @@ static int ina2xx_buffer_enable(struct iio_dev *indio_dev) 1000000/sampling_us, chip->avg); trace_printk("Expected work period: %u us\n", sampling_us); + trace_printk("Async readout mode: %d\n", chip->allow_async_readout); chip->prev_ns = iio_get_time_ns(); @@ -510,7 +541,12 @@ static int ina2xx_debug_reg(struct iio_dev *indio_dev, static IIO_CONST_ATTR_INT_TIME_AVAIL \ ("0.000140 0.000204 0.000332 0.000588 0.001100 0.002116 0.004156 0.008244"); +static IIO_DEVICE_ATTR(in_allow_async_readout, S_IRUGO | S_IWUSR, + ina2xx_allow_async_readout_show, + ina2xx_allow_async_readout_store, 0); + static struct attribute *ina2xx_attributes[] = { + &iio_dev_attr_in_allow_async_readout.dev_attr.attr, &iio_const_attr_integration_time_available.dev_attr.attr, NULL, }; -- GitLab From b17dc40155a973d0da68b54184dd9c237426c426 Mon Sep 17 00:00:00 2001 From: Marc Titinger Date: Fri, 11 Dec 2015 17:49:15 +0100 Subject: [PATCH 1082/2855] iio: ina2xx: re-instate a sysfs show/store for the shunt resistor value Different probe modules use different resistor values. The front-end application may read a probe ID (from eeprom) and set the shunt value accordingly. Signed-off-by: Marc Titinger Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ina2xx-adc.c | 52 +++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index ff31f5b49a416..dd4ff08d7b62e 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -111,7 +111,7 @@ struct ina2xx_chip_info { struct task_struct *task; const struct ina2xx_config *config; struct mutex state_lock; - long rshunt; + unsigned int shunt_resistor; int avg; s64 prev_ns; /* track buffer capture time, check for underruns*/ int int_time_vbus; /* Bus voltage integration time uS */ @@ -349,6 +349,42 @@ static ssize_t ina2xx_allow_async_readout_store(struct device *dev, return len; } +static int set_shunt_resistor(struct ina2xx_chip_info *chip, unsigned int val) +{ + if (val <= 0 || val > chip->config->calibration_factor) + return -EINVAL; + + chip->shunt_resistor = val; + return 0; +} + +static ssize_t ina2xx_shunt_resistor_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev)); + + return sprintf(buf, "%d\n", chip->shunt_resistor); +} + +static ssize_t ina2xx_shunt_resistor_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev)); + unsigned long val; + int ret; + + ret = kstrtoul((const char *) buf, 10, &val); + if (ret) + return ret; + + ret = set_shunt_resistor(chip, val); + if (ret) + return ret; + + return len; +} #define INA2XX_CHAN(_type, _index, _address) { \ .type = (_type), \ @@ -545,9 +581,14 @@ static IIO_DEVICE_ATTR(in_allow_async_readout, S_IRUGO | S_IWUSR, ina2xx_allow_async_readout_show, ina2xx_allow_async_readout_store, 0); +static IIO_DEVICE_ATTR(in_shunt_resistor, S_IRUGO | S_IWUSR, + ina2xx_shunt_resistor_show, + ina2xx_shunt_resistor_store, 0); + static struct attribute *ina2xx_attributes[] = { &iio_dev_attr_in_allow_async_readout.dev_attr.attr, &iio_const_attr_integration_time_available.dev_attr.attr, + &iio_dev_attr_in_shunt_resistor.dev_attr.attr, NULL, }; @@ -579,7 +620,7 @@ static int ina2xx_init(struct ina2xx_chip_info *chip, unsigned int config) * to the user for now. */ regval = DIV_ROUND_CLOSEST(chip->config->calibration_factor, - chip->rshunt); + chip->shunt_resistor); return regmap_write(chip->regmap, INA2XX_CALIBRATION, regval); } @@ -612,10 +653,9 @@ static int ina2xx_probe(struct i2c_client *client, val = INA2XX_RSHUNT_DEFAULT; } - if (val <= 0 || val > chip->config->calibration_factor) - return -ENODEV; - - chip->rshunt = val; + ret = set_shunt_resistor(chip, val); + if (ret) + return ret; mutex_init(&chip->state_lock); -- GitLab From 46294cd948d530d4feccfd3afd6635e16a55dcb1 Mon Sep 17 00:00:00 2001 From: Marc Titinger Date: Fri, 11 Dec 2015 17:49:16 +0100 Subject: [PATCH 1083/2855] iio: ina2xx: give the capture kthread a more useful name string. PID PPID USER STAT VSZ %VSZ %CPU COMMAND 144 2 root DW 0 0% 33% [ina226:1-8800us] 141 2 root DW 0 0% 25% [ina226:0-8800us] 40 2 root SW 0 0% 15% [irq/156-4802a00] 147 2 root DW 0 0% 7% [ina226:2-8800us] 145 1 root S 1236 0% 6% dd if /dev/iio:device1 of /dev/null 148 1 root S 1236 0% 4% dd if /dev/iio:device2 of /dev/null 149 137 root R 1244 0% 3% top -d 1 142 1 root S 1236 0% 2% dd if /dev/iio:device0 of /dev/null Signed-off-by: Marc Titinger Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ina2xx-adc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index dd4ff08d7b62e..4c18c4cc89394 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -540,7 +540,8 @@ static int ina2xx_buffer_enable(struct iio_dev *indio_dev) chip->prev_ns = iio_get_time_ns(); chip->task = kthread_run(ina2xx_capture_thread, (void *)indio_dev, - "ina2xx-%uus", sampling_us); + "%s:%d-%uus", indio_dev->name, indio_dev->id, + sampling_us); return PTR_ERR_OR_ZERO(chip->task); } -- GitLab From 16846ebeffe4e74a16f25237003eab6d0535d8dd Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Tue, 8 Dec 2015 18:26:20 +0800 Subject: [PATCH 1084/2855] iio: adc: add IMX7D ADC driver support Freescale i.MX7D soc contains a new ADC IP. This patch add this ADC driver support, and the driver only support ADC software trigger. Signed-off-by: Haibo Chen Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 9 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/imx7d_adc.c | 609 ++++++++++++++++++++++++++++++++++++ 3 files changed, 619 insertions(+) create mode 100644 drivers/iio/adc/imx7d_adc.c diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index cb68bd9d20526..605ff42c46310 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -204,6 +204,15 @@ config INA2XX_ADC Say yes here to build support for TI INA2xx family of Power Monitors. This driver is mutually exclusive with the HWMON version. +config IMX7D_ADC + tristate "IMX7D ADC driver" + depends on ARCH_MXC || COMPILE_TEST + help + Say yes here to build support for IMX7D ADC. + + This driver can also be built as a module. If so, the module will be + called imx7d_adc. + config LP8788_ADC tristate "LP8788 ADC driver" depends on MFD_LP8788 diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index c62c5fa91c827..6435780e9b717 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o obj-$(CONFIG_DA9150_GPADC) += da9150-gpadc.o obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o obj-$(CONFIG_HI8435) += hi8435.o +obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o obj-$(CONFIG_MAX1027) += max1027.o diff --git a/drivers/iio/adc/imx7d_adc.c b/drivers/iio/adc/imx7d_adc.c new file mode 100644 index 0000000000000..e2241ee947832 --- /dev/null +++ b/drivers/iio/adc/imx7d_adc.c @@ -0,0 +1,609 @@ +/* + * Freescale i.MX7D ADC driver + * + * Copyright (C) 2015 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* ADC register */ +#define IMX7D_REG_ADC_CH_A_CFG1 0x00 +#define IMX7D_REG_ADC_CH_A_CFG2 0x10 +#define IMX7D_REG_ADC_CH_B_CFG1 0x20 +#define IMX7D_REG_ADC_CH_B_CFG2 0x30 +#define IMX7D_REG_ADC_CH_C_CFG1 0x40 +#define IMX7D_REG_ADC_CH_C_CFG2 0x50 +#define IMX7D_REG_ADC_CH_D_CFG1 0x60 +#define IMX7D_REG_ADC_CH_D_CFG2 0x70 +#define IMX7D_REG_ADC_CH_SW_CFG 0x80 +#define IMX7D_REG_ADC_TIMER_UNIT 0x90 +#define IMX7D_REG_ADC_DMA_FIFO 0xa0 +#define IMX7D_REG_ADC_FIFO_STATUS 0xb0 +#define IMX7D_REG_ADC_INT_SIG_EN 0xc0 +#define IMX7D_REG_ADC_INT_EN 0xd0 +#define IMX7D_REG_ADC_INT_STATUS 0xe0 +#define IMX7D_REG_ADC_CHA_B_CNV_RSLT 0xf0 +#define IMX7D_REG_ADC_CHC_D_CNV_RSLT 0x100 +#define IMX7D_REG_ADC_CH_SW_CNV_RSLT 0x110 +#define IMX7D_REG_ADC_DMA_FIFO_DAT 0x120 +#define IMX7D_REG_ADC_ADC_CFG 0x130 + +#define IMX7D_REG_ADC_CHANNEL_CFG2_BASE 0x10 +#define IMX7D_EACH_CHANNEL_REG_OFFSET 0x20 + +#define IMX7D_REG_ADC_CH_CFG1_CHANNEL_EN (0x1 << 31) +#define IMX7D_REG_ADC_CH_CFG1_CHANNEL_SINGLE BIT(30) +#define IMX7D_REG_ADC_CH_CFG1_CHANNEL_AVG_EN BIT(29) +#define IMX7D_REG_ADC_CH_CFG1_CHANNEL_SEL(x) ((x) << 24) + +#define IMX7D_REG_ADC_CH_CFG2_AVG_NUM_4 (0x0 << 12) +#define IMX7D_REG_ADC_CH_CFG2_AVG_NUM_8 (0x1 << 12) +#define IMX7D_REG_ADC_CH_CFG2_AVG_NUM_16 (0x2 << 12) +#define IMX7D_REG_ADC_CH_CFG2_AVG_NUM_32 (0x3 << 12) + +#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_4 (0x0 << 29) +#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_8 (0x1 << 29) +#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_16 (0x2 << 29) +#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_32 (0x3 << 29) +#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_64 (0x4 << 29) +#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_128 (0x5 << 29) + +#define IMX7D_REG_ADC_ADC_CFG_ADC_CLK_DOWN BIT(31) +#define IMX7D_REG_ADC_ADC_CFG_ADC_POWER_DOWN BIT(1) +#define IMX7D_REG_ADC_ADC_CFG_ADC_EN BIT(0) + +#define IMX7D_REG_ADC_INT_CHA_COV_INT_EN BIT(8) +#define IMX7D_REG_ADC_INT_CHB_COV_INT_EN BIT(9) +#define IMX7D_REG_ADC_INT_CHC_COV_INT_EN BIT(10) +#define IMX7D_REG_ADC_INT_CHD_COV_INT_EN BIT(11) +#define IMX7D_REG_ADC_INT_CHANNEL_INT_EN \ + (IMX7D_REG_ADC_INT_CHA_COV_INT_EN | \ + IMX7D_REG_ADC_INT_CHB_COV_INT_EN | \ + IMX7D_REG_ADC_INT_CHC_COV_INT_EN | \ + IMX7D_REG_ADC_INT_CHD_COV_INT_EN) +#define IMX7D_REG_ADC_INT_STATUS_CHANNEL_INT_STATUS 0xf00 +#define IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT 0xf0000 + +#define IMX7D_ADC_TIMEOUT msecs_to_jiffies(100) + +enum imx7d_adc_clk_pre_div { + IMX7D_ADC_ANALOG_CLK_PRE_DIV_4, + IMX7D_ADC_ANALOG_CLK_PRE_DIV_8, + IMX7D_ADC_ANALOG_CLK_PRE_DIV_16, + IMX7D_ADC_ANALOG_CLK_PRE_DIV_32, + IMX7D_ADC_ANALOG_CLK_PRE_DIV_64, + IMX7D_ADC_ANALOG_CLK_PRE_DIV_128, +}; + +enum imx7d_adc_average_num { + IMX7D_ADC_AVERAGE_NUM_4, + IMX7D_ADC_AVERAGE_NUM_8, + IMX7D_ADC_AVERAGE_NUM_16, + IMX7D_ADC_AVERAGE_NUM_32, +}; + +struct imx7d_adc_feature { + enum imx7d_adc_clk_pre_div clk_pre_div; + enum imx7d_adc_average_num avg_num; + + u32 core_time_unit; /* impact the sample rate */ + + bool average_en; +}; + +struct imx7d_adc { + struct device *dev; + void __iomem *regs; + struct clk *clk; + + u32 vref_uv; + u32 value; + u32 channel; + u32 pre_div_num; + + struct regulator *vref; + struct imx7d_adc_feature adc_feature; + + struct completion completion; +}; + +struct imx7d_adc_analogue_core_clk { + u32 pre_div; + u32 reg_config; +}; + +#define IMX7D_ADC_ANALOGUE_CLK_CONFIG(_pre_div, _reg_conf) { \ + .pre_div = (_pre_div), \ + .reg_config = (_reg_conf), \ +} + +static const struct imx7d_adc_analogue_core_clk imx7d_adc_analogue_clk[] = { + IMX7D_ADC_ANALOGUE_CLK_CONFIG(4, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_4), + IMX7D_ADC_ANALOGUE_CLK_CONFIG(8, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_8), + IMX7D_ADC_ANALOGUE_CLK_CONFIG(16, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_16), + IMX7D_ADC_ANALOGUE_CLK_CONFIG(32, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_32), + IMX7D_ADC_ANALOGUE_CLK_CONFIG(64, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_64), + IMX7D_ADC_ANALOGUE_CLK_CONFIG(128, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_128), +}; + +#define IMX7D_ADC_CHAN(_idx) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = (_idx), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ +} + +static const struct iio_chan_spec imx7d_adc_iio_channels[] = { + IMX7D_ADC_CHAN(0), + IMX7D_ADC_CHAN(1), + IMX7D_ADC_CHAN(2), + IMX7D_ADC_CHAN(3), + IMX7D_ADC_CHAN(4), + IMX7D_ADC_CHAN(5), + IMX7D_ADC_CHAN(6), + IMX7D_ADC_CHAN(7), + IMX7D_ADC_CHAN(8), + IMX7D_ADC_CHAN(9), + IMX7D_ADC_CHAN(10), + IMX7D_ADC_CHAN(11), + IMX7D_ADC_CHAN(12), + IMX7D_ADC_CHAN(13), + IMX7D_ADC_CHAN(14), + IMX7D_ADC_CHAN(15), +}; + +static const u32 imx7d_adc_average_num[] = { + IMX7D_REG_ADC_CH_CFG2_AVG_NUM_4, + IMX7D_REG_ADC_CH_CFG2_AVG_NUM_8, + IMX7D_REG_ADC_CH_CFG2_AVG_NUM_16, + IMX7D_REG_ADC_CH_CFG2_AVG_NUM_32, +}; + +static void imx7d_adc_feature_config(struct imx7d_adc *info) +{ + info->adc_feature.clk_pre_div = IMX7D_ADC_ANALOG_CLK_PRE_DIV_4; + info->adc_feature.avg_num = IMX7D_ADC_AVERAGE_NUM_32; + info->adc_feature.core_time_unit = 1; + info->adc_feature.average_en = true; +} + +static void imx7d_adc_sample_rate_set(struct imx7d_adc *info) +{ + struct imx7d_adc_feature *adc_feature = &info->adc_feature; + struct imx7d_adc_analogue_core_clk adc_analogure_clk; + u32 i; + u32 tmp_cfg1; + u32 sample_rate = 0; + + /* + * Before sample set, disable channel A,B,C,D. Here we + * clear the bit 31 of register REG_ADC_CH_A\B\C\D_CFG1. + */ + for (i = 0; i < 4; i++) { + tmp_cfg1 = + readl(info->regs + i * IMX7D_EACH_CHANNEL_REG_OFFSET); + tmp_cfg1 &= ~IMX7D_REG_ADC_CH_CFG1_CHANNEL_EN; + writel(tmp_cfg1, + info->regs + i * IMX7D_EACH_CHANNEL_REG_OFFSET); + } + + adc_analogure_clk = imx7d_adc_analogue_clk[adc_feature->clk_pre_div]; + sample_rate |= adc_analogure_clk.reg_config; + info->pre_div_num = adc_analogure_clk.pre_div; + + sample_rate |= adc_feature->core_time_unit; + writel(sample_rate, info->regs + IMX7D_REG_ADC_TIMER_UNIT); +} + +static void imx7d_adc_hw_init(struct imx7d_adc *info) +{ + u32 cfg; + + /* power up and enable adc analogue core */ + cfg = readl(info->regs + IMX7D_REG_ADC_ADC_CFG); + cfg &= ~(IMX7D_REG_ADC_ADC_CFG_ADC_CLK_DOWN | + IMX7D_REG_ADC_ADC_CFG_ADC_POWER_DOWN); + cfg |= IMX7D_REG_ADC_ADC_CFG_ADC_EN; + writel(cfg, info->regs + IMX7D_REG_ADC_ADC_CFG); + + /* enable channel A,B,C,D interrupt */ + writel(IMX7D_REG_ADC_INT_CHANNEL_INT_EN, + info->regs + IMX7D_REG_ADC_INT_SIG_EN); + writel(IMX7D_REG_ADC_INT_CHANNEL_INT_EN, + info->regs + IMX7D_REG_ADC_INT_EN); + + imx7d_adc_sample_rate_set(info); +} + +static void imx7d_adc_channel_set(struct imx7d_adc *info) +{ + u32 cfg1 = 0; + u32 cfg2; + u32 channel; + + channel = info->channel; + + /* the channel choose single conversion, and enable average mode */ + cfg1 |= (IMX7D_REG_ADC_CH_CFG1_CHANNEL_EN | + IMX7D_REG_ADC_CH_CFG1_CHANNEL_SINGLE); + if (info->adc_feature.average_en) + cfg1 |= IMX7D_REG_ADC_CH_CFG1_CHANNEL_AVG_EN; + + /* + * physical channel 0 chose logical channel A + * physical channel 1 chose logical channel B + * physical channel 2 chose logical channel C + * physical channel 3 chose logical channel D + */ + cfg1 |= IMX7D_REG_ADC_CH_CFG1_CHANNEL_SEL(channel); + + /* + * read register REG_ADC_CH_A\B\C\D_CFG2, according to the + * channel chosen + */ + cfg2 = readl(info->regs + IMX7D_EACH_CHANNEL_REG_OFFSET * channel + + IMX7D_REG_ADC_CHANNEL_CFG2_BASE); + + cfg2 |= imx7d_adc_average_num[info->adc_feature.avg_num]; + + /* + * write the register REG_ADC_CH_A\B\C\D_CFG2, according to + * the channel chosen + */ + writel(cfg2, info->regs + IMX7D_EACH_CHANNEL_REG_OFFSET * channel + + IMX7D_REG_ADC_CHANNEL_CFG2_BASE); + writel(cfg1, info->regs + IMX7D_EACH_CHANNEL_REG_OFFSET * channel); +} + +static u32 imx7d_adc_get_sample_rate(struct imx7d_adc *info) +{ + /* input clock is always 24MHz */ + u32 input_clk = 24000000; + u32 analogue_core_clk; + u32 core_time_unit = info->adc_feature.core_time_unit; + u32 tmp; + + analogue_core_clk = input_clk / info->pre_div_num; + tmp = (core_time_unit + 1) * 6; + + return analogue_core_clk / tmp; +} + +static int imx7d_adc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long mask) +{ + struct imx7d_adc *info = iio_priv(indio_dev); + + u32 channel; + long ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&indio_dev->mlock); + reinit_completion(&info->completion); + + channel = chan->channel & 0x03; + info->channel = channel; + imx7d_adc_channel_set(info); + + ret = wait_for_completion_interruptible_timeout + (&info->completion, IMX7D_ADC_TIMEOUT); + if (ret == 0) { + mutex_unlock(&indio_dev->mlock); + return -ETIMEDOUT; + } + if (ret < 0) { + mutex_unlock(&indio_dev->mlock); + return ret; + } + + *val = info->value; + mutex_unlock(&indio_dev->mlock); + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + info->vref_uv = regulator_get_voltage(info->vref); + *val = info->vref_uv / 1000; + *val2 = 12; + return IIO_VAL_FRACTIONAL_LOG2; + + case IIO_CHAN_INFO_SAMP_FREQ: + *val = imx7d_adc_get_sample_rate(info); + return IIO_VAL_INT; + + default: + return -EINVAL; + } +} + +static int imx7d_adc_read_data(struct imx7d_adc *info) +{ + u32 channel; + u32 value; + + channel = info->channel & 0x03; + + /* + * channel A and B conversion result share one register, + * bit[27~16] is the channel B conversion result, + * bit[11~0] is the channel A conversion result. + * channel C and D is the same. + */ + if (channel < 2) + value = readl(info->regs + IMX7D_REG_ADC_CHA_B_CNV_RSLT); + else + value = readl(info->regs + IMX7D_REG_ADC_CHC_D_CNV_RSLT); + if (channel & 0x1) /* channel B or D */ + value = (value >> 16) & 0xFFF; + else /* channel A or C */ + value &= 0xFFF; + + return value; +} + +static irqreturn_t imx7d_adc_isr(int irq, void *dev_id) +{ + struct imx7d_adc *info = (struct imx7d_adc *)dev_id; + int status; + + status = readl(info->regs + IMX7D_REG_ADC_INT_STATUS); + if (status & IMX7D_REG_ADC_INT_STATUS_CHANNEL_INT_STATUS) { + info->value = imx7d_adc_read_data(info); + complete(&info->completion); + + /* + * The register IMX7D_REG_ADC_INT_STATUS can't clear + * itself after read operation, need software to write + * 0 to the related bit. Here we clear the channel A/B/C/D + * conversion finished flag. + */ + status &= ~IMX7D_REG_ADC_INT_STATUS_CHANNEL_INT_STATUS; + writel(status, info->regs + IMX7D_REG_ADC_INT_STATUS); + } + + /* + * If the channel A/B/C/D conversion timeout, report it and clear these + * timeout flags. + */ + if (status & IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT) { + pr_err("%s: ADC got conversion time out interrupt: 0x%08x\n", + dev_name(info->dev), status); + status &= ~IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT; + writel(status, info->regs + IMX7D_REG_ADC_INT_STATUS); + } + + return IRQ_HANDLED; +} + +static int imx7d_adc_reg_access(struct iio_dev *indio_dev, + unsigned reg, unsigned writeval, + unsigned *readval) +{ + struct imx7d_adc *info = iio_priv(indio_dev); + + if (!readval || reg % 4 || reg > IMX7D_REG_ADC_ADC_CFG) + return -EINVAL; + + *readval = readl(info->regs + reg); + + return 0; +} + +static const struct iio_info imx7d_adc_iio_info = { + .driver_module = THIS_MODULE, + .read_raw = &imx7d_adc_read_raw, + .debugfs_reg_access = &imx7d_adc_reg_access, +}; + +static const struct of_device_id imx7d_adc_match[] = { + { .compatible = "fsl,imx7d-adc", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imx7d_adc_match); + +static void imx7d_adc_power_down(struct imx7d_adc *info) +{ + u32 adc_cfg; + + adc_cfg = readl(info->regs + IMX7D_REG_ADC_ADC_CFG); + adc_cfg |= IMX7D_REG_ADC_ADC_CFG_ADC_CLK_DOWN | + IMX7D_REG_ADC_ADC_CFG_ADC_POWER_DOWN; + adc_cfg &= ~IMX7D_REG_ADC_ADC_CFG_ADC_EN; + writel(adc_cfg, info->regs + IMX7D_REG_ADC_ADC_CFG); +} + +static int imx7d_adc_probe(struct platform_device *pdev) +{ + struct imx7d_adc *info; + struct iio_dev *indio_dev; + struct resource *mem; + int irq; + int ret; + + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info)); + if (!indio_dev) { + dev_err(&pdev->dev, "Failed allocating iio device\n"); + return -ENOMEM; + } + + info = iio_priv(indio_dev); + info->dev = &pdev->dev; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + info->regs = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(info->regs)) { + ret = PTR_ERR(info->regs); + dev_err(&pdev->dev, + "Failed to remap adc memory, err = %d\n", ret); + return ret; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "No irq resource?\n"); + return irq; + } + + info->clk = devm_clk_get(&pdev->dev, "adc"); + if (IS_ERR(info->clk)) { + ret = PTR_ERR(info->clk); + dev_err(&pdev->dev, "Failed getting clock, err = %d\n", ret); + return ret; + } + + info->vref = devm_regulator_get(&pdev->dev, "vref"); + if (IS_ERR(info->vref)) { + ret = PTR_ERR(info->vref); + dev_err(&pdev->dev, + "Failed getting reference voltage, err = %d\n", ret); + return ret; + } + + ret = regulator_enable(info->vref); + if (ret) { + dev_err(&pdev->dev, + "Can't enable adc reference top voltage, err = %d\n", + ret); + return ret; + } + + platform_set_drvdata(pdev, indio_dev); + + init_completion(&info->completion); + + indio_dev->name = dev_name(&pdev->dev); + indio_dev->dev.parent = &pdev->dev; + indio_dev->info = &imx7d_adc_iio_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = imx7d_adc_iio_channels; + indio_dev->num_channels = ARRAY_SIZE(imx7d_adc_iio_channels); + + ret = clk_prepare_enable(info->clk); + if (ret) { + dev_err(&pdev->dev, + "Could not prepare or enable the clock.\n"); + goto error_adc_clk_enable; + } + + ret = devm_request_irq(info->dev, irq, + imx7d_adc_isr, 0, + dev_name(&pdev->dev), info); + if (ret < 0) { + dev_err(&pdev->dev, "Failed requesting irq, irq = %d\n", irq); + goto error_iio_device_register; + } + + imx7d_adc_feature_config(info); + imx7d_adc_hw_init(info); + + ret = iio_device_register(indio_dev); + if (ret) { + imx7d_adc_power_down(info); + dev_err(&pdev->dev, "Couldn't register the device.\n"); + goto error_iio_device_register; + } + + return 0; + +error_iio_device_register: + clk_disable_unprepare(info->clk); +error_adc_clk_enable: + regulator_disable(info->vref); + + return ret; +} + +static int imx7d_adc_remove(struct platform_device *pdev) +{ + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct imx7d_adc *info = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + + imx7d_adc_power_down(info); + + clk_disable_unprepare(info->clk); + regulator_disable(info->vref); + + return 0; +} + +static int __maybe_unused imx7d_adc_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct imx7d_adc *info = iio_priv(indio_dev); + + imx7d_adc_power_down(info); + + clk_disable_unprepare(info->clk); + regulator_disable(info->vref); + + return 0; +} + +static int __maybe_unused imx7d_adc_resume(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct imx7d_adc *info = iio_priv(indio_dev); + int ret; + + ret = regulator_enable(info->vref); + if (ret) { + dev_err(info->dev, + "Can't enable adc reference top voltage, err = %d\n", + ret); + return ret; + } + + ret = clk_prepare_enable(info->clk); + if (ret) { + dev_err(info->dev, + "Could not prepare or enable clock.\n"); + regulator_disable(info->vref); + return ret; + } + + imx7d_adc_hw_init(info); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(imx7d_adc_pm_ops, imx7d_adc_suspend, imx7d_adc_resume); + +static struct platform_driver imx7d_adc_driver = { + .probe = imx7d_adc_probe, + .remove = imx7d_adc_remove, + .driver = { + .name = "imx7d_adc", + .of_match_table = imx7d_adc_match, + .pm = &imx7d_adc_pm_ops, + }, +}; + +module_platform_driver(imx7d_adc_driver); + +MODULE_AUTHOR("Haibo Chen "); +MODULE_DESCRIPTION("Freeacale IMX7D ADC driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 50672011d676aea5e521bc77dfce0c9eea040782 Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Tue, 8 Dec 2015 18:26:21 +0800 Subject: [PATCH 1085/2855] Documentation: add the binding file for Freescale imx7d ADC driver The patch adds the binding file for Freescale imx7d ADC driver. Signed-off-by: Haibo Chen Acked-by: Rob Herring Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/adc/imx7d-adc.txt | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/imx7d-adc.txt diff --git a/Documentation/devicetree/bindings/iio/adc/imx7d-adc.txt b/Documentation/devicetree/bindings/iio/adc/imx7d-adc.txt new file mode 100644 index 0000000000000..5c184b9406693 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/imx7d-adc.txt @@ -0,0 +1,22 @@ +Freescale imx7d ADC bindings + +The devicetree bindings are for the ADC driver written for +imx7d SoC. + +Required properties: +- compatible: Should be "fsl,imx7d-adc" +- reg: Offset and length of the register set for the ADC device +- interrupts: The interrupt number for the ADC device +- clocks: The root clock of the ADC controller +- clock-names: Must contain "adc", matching entry in the clocks property +- vref-supply: The regulator supply ADC reference voltage + +Example: +adc1: adc@30610000 { + compatible = "fsl,imx7d-adc"; + reg = <0x30610000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_ADC_ROOT_CLK>; + clock-names = "adc"; + vref-supply = <®_vcc_3v3_mcu>; +}; -- GitLab From c34c18195d30aa3b95f5ae1b4349875c45fdb8e4 Mon Sep 17 00:00:00 2001 From: Anshul Garg Date: Tue, 8 Dec 2015 09:45:56 -0800 Subject: [PATCH 1086/2855] iio/inkern.c Use list_for_each_entry_safe Use list_for_each_entry_safe instead of list_for_each_safe and list_entry call. Signed-off-by: Anshul Garg Signed-off-by: Jonathan Cameron --- drivers/iio/inkern.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index c8bad3cf891df..80fbbfd76faf9 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -61,12 +61,10 @@ EXPORT_SYMBOL_GPL(iio_map_array_register); int iio_map_array_unregister(struct iio_dev *indio_dev) { int ret = -ENODEV; - struct iio_map_internal *mapi; - struct list_head *pos, *tmp; + struct iio_map_internal *mapi, *next; mutex_lock(&iio_map_list_lock); - list_for_each_safe(pos, tmp, &iio_map_list) { - mapi = list_entry(pos, struct iio_map_internal, l); + list_for_each_entry_safe(mapi, next, &iio_map_list, l) { if (indio_dev == mapi->indio_dev) { list_del(&mapi->l); kfree(mapi); -- GitLab From ecee988ac848fabbff6c926739a520b1748c4a79 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 10 Dec 2015 18:11:58 +0800 Subject: [PATCH 1087/2855] regulator: pv88090: Fix irq leak Use devm_request_threaded_irq to ensure the irq is freed when unload the module. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/pv88090-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/pv88090-regulator.c b/drivers/regulator/pv88090-regulator.c index 3ec5f2bdfc51d..2513fef374095 100644 --- a/drivers/regulator/pv88090-regulator.c +++ b/drivers/regulator/pv88090-regulator.c @@ -357,7 +357,7 @@ static int pv88090_i2c_probe(struct i2c_client *i2c, return ret; } - ret = request_threaded_irq(i2c->irq, NULL, + ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL, pv88090_irq_handler, IRQF_TRIGGER_LOW|IRQF_ONESHOT, "pv88090", chip); -- GitLab From d761c906179944c6000d3f0c29e00e7543b6c139 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 12 Dec 2015 15:38:43 +0300 Subject: [PATCH 1088/2855] regulator: pv88090: logical vs bitwise AND typo These were supposed to be bitwise AND instead of logical. Also kernel style is for the operator to be on the first line and I removed some extra parenthesis. Fixes: c90456e36d9c ('regulator: pv88090: new regulator driver') Signed-off-by: Dan Carpenter Signed-off-by: Mark Brown --- drivers/regulator/pv88090-regulator.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/regulator/pv88090-regulator.c b/drivers/regulator/pv88090-regulator.c index 2513fef374095..ac15f31b5fe0c 100644 --- a/drivers/regulator/pv88090-regulator.c +++ b/drivers/regulator/pv88090-regulator.c @@ -392,17 +392,17 @@ static int pv88090_i2c_probe(struct i2c_client *i2c, if (ret < 0) return ret; - conf2 = ((conf2 >> PV88090_BUCK_VDAC_RANGE_SHIFT) - && PV88090_BUCK_VDAC_RANGE_MASK); + conf2 = (conf2 >> PV88090_BUCK_VDAC_RANGE_SHIFT) & + PV88090_BUCK_VDAC_RANGE_MASK; ret = regmap_read(chip->regmap, PV88090_REG_BUCK_FOLD_RANGE, &range); if (ret < 0) return ret; - range = ((range - >> (PV88080_BUCK_VRANGE_GAIN_SHIFT + i - 1)) - && PV88080_BUCK_VRANGE_GAIN_MASK); + range = (range >> + (PV88080_BUCK_VRANGE_GAIN_SHIFT + i - 1)) & + PV88080_BUCK_VRANGE_GAIN_MASK; index = ((range << 1) | conf2); pv88090_regulator_info[i].desc.min_uV -- GitLab From 7f3ac71ac3b05aaa2c55c266448f973188275a8c Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Thu, 10 Dec 2015 21:59:04 +0530 Subject: [PATCH 1089/2855] spi: davinci: fix spurious i/o error davinci_spi_bufs() uses wait_for_completion_interruptible() without bothering to handle -ERESTARTSYS. Due to this, sometime, it returns prematurely when a signal is received. Since the return value is never checked, userspace eventually receives a spurious -EIO. To fix this, use un-interruptible wait_for_completion_timeout(). Signed-off-by: Sekhar Nori Signed-off-by: Mark Brown --- drivers/spi/spi-davinci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 7d3af3eacf57d..57d6960a62523 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -703,7 +703,8 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) /* Wait for the transfer to complete */ if (spicfg->io_type != SPI_IO_TYPE_POLL) { - wait_for_completion_interruptible(&(dspi->done)); + if (wait_for_completion_timeout(&dspi->done, HZ) == 0) + errors = SPIFLG_TIMEOUT_MASK; } else { while (dspi->rcount > 0 || dspi->wcount > 0) { errors = davinci_spi_process_events(dspi); -- GitLab From 21c015b776d4013b656bca8a4f42b953297b8b8c Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Thu, 10 Dec 2015 21:59:05 +0530 Subject: [PATCH 1090/2855] spi: davinci: use dev_err() for error reporting Use dev_err() for reporting errors rather than dev_dbg(). Signed-off-by: Sekhar Nori Signed-off-by: Mark Brown --- drivers/spi/spi-davinci.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 57d6960a62523..fddb7a3be322b 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -477,33 +477,33 @@ static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status) struct device *sdev = dspi->bitbang.master->dev.parent; if (int_status & SPIFLG_TIMEOUT_MASK) { - dev_dbg(sdev, "SPI Time-out Error\n"); + dev_err(sdev, "SPI Time-out Error\n"); return -ETIMEDOUT; } if (int_status & SPIFLG_DESYNC_MASK) { - dev_dbg(sdev, "SPI Desynchronization Error\n"); + dev_err(sdev, "SPI Desynchronization Error\n"); return -EIO; } if (int_status & SPIFLG_BITERR_MASK) { - dev_dbg(sdev, "SPI Bit error\n"); + dev_err(sdev, "SPI Bit error\n"); return -EIO; } if (dspi->version == SPI_VERSION_2) { if (int_status & SPIFLG_DLEN_ERR_MASK) { - dev_dbg(sdev, "SPI Data Length Error\n"); + dev_err(sdev, "SPI Data Length Error\n"); return -EIO; } if (int_status & SPIFLG_PARERR_MASK) { - dev_dbg(sdev, "SPI Parity Error\n"); + dev_err(sdev, "SPI Parity Error\n"); return -EIO; } if (int_status & SPIFLG_OVRRUN_MASK) { - dev_dbg(sdev, "SPI Data Overrun error\n"); + dev_err(sdev, "SPI Data Overrun error\n"); return -EIO; } if (int_status & SPIFLG_BUF_INIT_ACTIVE_MASK) { - dev_dbg(sdev, "SPI Buffer Init Active\n"); + dev_err(sdev, "SPI Buffer Init Active\n"); return -EBUSY; } } -- GitLab From 315c562536c42aa4da9b6c5a2135dd6715a5e0b5 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 10 Dec 2015 14:45:23 -0800 Subject: [PATCH 1091/2855] libnvdimm, pfn: add 'align' attribute, default to HPAGE_SIZE When setting aside capacity for struct page it must be aligned to the largest mapping size that is to be made available via DAX. Make the alignment configurable to enable support for 1GiB page-size mappings. The offset for PFN_MODE_RAM may now be larger than SZ_8K, so fixup the offset check in nvdimm_namespace_attach_pfn(). Reported-by: Toshi Kani Signed-off-by: Dan Williams --- drivers/nvdimm/nd.h | 1 + drivers/nvdimm/pfn_devs.c | 61 +++++++++++++++++++++++++++++++++++++++ drivers/nvdimm/pmem.c | 6 ++-- 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h index 2ce428e9b5849..e4e9f9ae0cc88 100644 --- a/drivers/nvdimm/nd.h +++ b/drivers/nvdimm/nd.h @@ -146,6 +146,7 @@ struct nd_pfn { int id; u8 *uuid; struct device dev; + unsigned long align; unsigned long npfns; enum nd_pfn_mode mode; struct nd_pfn_sb *pfn_sb; diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c index 613ffcca6ecbb..95ecd7b0fab3a 100644 --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c @@ -103,6 +103,52 @@ static ssize_t mode_store(struct device *dev, } static DEVICE_ATTR_RW(mode); +static ssize_t align_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nd_pfn *nd_pfn = to_nd_pfn(dev); + + return sprintf(buf, "%lx\n", nd_pfn->align); +} + +static ssize_t __align_store(struct nd_pfn *nd_pfn, const char *buf) +{ + unsigned long val; + int rc; + + rc = kstrtoul(buf, 0, &val); + if (rc) + return rc; + + if (!is_power_of_2(val) || val < PAGE_SIZE || val > SZ_1G) + return -EINVAL; + + if (nd_pfn->dev.driver) + return -EBUSY; + else + nd_pfn->align = val; + + return 0; +} + +static ssize_t align_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct nd_pfn *nd_pfn = to_nd_pfn(dev); + ssize_t rc; + + device_lock(dev); + nvdimm_bus_lock(dev); + rc = __align_store(nd_pfn, buf); + dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__, + rc, buf, buf[len - 1] == '\n' ? "" : "\n"); + nvdimm_bus_unlock(dev); + device_unlock(dev); + + return rc ? rc : len; +} +static DEVICE_ATTR_RW(align); + static ssize_t uuid_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -164,6 +210,7 @@ static struct attribute *nd_pfn_attributes[] = { &dev_attr_mode.attr, &dev_attr_namespace.attr, &dev_attr_uuid.attr, + &dev_attr_align.attr, NULL, }; @@ -199,6 +246,7 @@ static struct device *__nd_pfn_create(struct nd_region *nd_region, } nd_pfn->mode = PFN_MODE_NONE; + nd_pfn->align = HPAGE_SIZE; dev = &nd_pfn->dev; dev_set_name(dev, "pfn%d.%d", nd_region->id, nd_pfn->id); dev->parent = &nd_region->dev; @@ -269,6 +317,12 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn) return -EINVAL; } + if (nd_pfn->align > nvdimm_namespace_capacity(ndns)) { + dev_err(&nd_pfn->dev, "alignment: %lx exceeds capacity %llx\n", + nd_pfn->align, nvdimm_namespace_capacity(ndns)); + return -EINVAL; + } + /* * These warnings are verbose because they can only trigger in * the case where the physical address alignment of the @@ -283,6 +337,13 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn) return -EBUSY; } + nd_pfn->align = 1UL << ilog2(offset); + if (!is_power_of_2(offset) || offset < PAGE_SIZE) { + dev_err(&nd_pfn->dev, "bad offset: %#llx dax disabled\n", + offset); + return -ENXIO; + } + return 0; } EXPORT_SYMBOL(nd_pfn_validate); diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 520c00321dadd..5ba351e4f26a8 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -258,9 +258,9 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) * ->direct_access() to those that are included in the memmap. */ if (nd_pfn->mode == PFN_MODE_PMEM) - offset = ALIGN(SZ_8K + 64 * npfns, PMD_SIZE); + offset = ALIGN(SZ_8K + 64 * npfns, nd_pfn->align); else if (nd_pfn->mode == PFN_MODE_RAM) - offset = SZ_8K; + offset = ALIGN(SZ_8K, nd_pfn->align); else goto err; @@ -325,7 +325,7 @@ static int nvdimm_namespace_attach_pfn(struct nd_namespace_common *ndns) offset = le64_to_cpu(pfn_sb->dataoff); nd_pfn->mode = le32_to_cpu(nd_pfn->pfn_sb->mode); if (nd_pfn->mode == PFN_MODE_RAM) { - if (offset != SZ_8K) + if (offset < SZ_8K) return -EINVAL; nd_pfn->npfns = le64_to_cpu(pfn_sb->npfns); altmap = NULL; -- GitLab From 49ddedf3bfcb59a562c7db0e50aecd1422e9cdc9 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Fri, 27 Nov 2015 13:56:03 +0000 Subject: [PATCH 1092/2855] spi: add spi_message_init_no_memset to avoid zeroing the spi_message In the spi_loopback_test driver there is the need to initialize a spi_message that is filled with values from a static structure. Applying spi_message_init to such a prefilled structure results in all the settings getting reset to zero, which is not what we want. Copying each field of spi_message separately instead always includes the risk that some new fields have not been implemented in the copying code. So here we introduce a version of spi_message_init called spi_message_init_no_memset that does not fill the structure with zero first, but only initializes the relevant list_heads. Signed-off-by: Martin Sperl Signed-off-by: Mark Brown --- include/linux/spi/spi.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index cce80e6dc7d11..4c54d4744107d 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -762,10 +762,15 @@ struct spi_message { void *state; }; +static inline void spi_message_init_no_memset(struct spi_message *m) +{ + INIT_LIST_HEAD(&m->transfers); +} + static inline void spi_message_init(struct spi_message *m) { memset(m, 0, sizeof *m); - INIT_LIST_HEAD(&m->transfers); + spi_message_init_no_memset(m); } static inline void -- GitLab From 84e0c4e5e2c4ef42b9c6f6d4151973a297ee4656 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Fri, 27 Nov 2015 13:56:04 +0000 Subject: [PATCH 1093/2855] spi: add loopback test driver to allow for spi_master regression tests This driver is submitting lots of distinct spi-messages messages with all kinds of alignments and length pattern. Also distinct kinds of transfer pattern tests are implemented (rx, tx, rx/tx, tx+tx, tx+rx,...) Right now on a raspberry pi 752 distinct spi_messages are executed in 13 different scenarios. Configuration of additional test-pattern is easy, so that when new bugs in drivers get detected the relevant transfer pattern can also get added to the test framework, so that such situations are detected in other drivers as well. The idea behind this driver is to make it possible to also detect regressions in spi_master implementations when changes occur. Potentially these tests could get executed automatically in a test-server-farm. Signed-off-by: Martin Sperl Signed-off-by: Mark Brown --- drivers/spi/spi-loopback-test.c | 995 ++++++++++++++++++++++++++++++++ drivers/spi/spi-test.h | 135 +++++ 2 files changed, 1130 insertions(+) create mode 100644 drivers/spi/spi-loopback-test.c create mode 100644 drivers/spi/spi-test.h diff --git a/drivers/spi/spi-loopback-test.c b/drivers/spi/spi-loopback-test.c new file mode 100644 index 0000000000000..db207362e831f --- /dev/null +++ b/drivers/spi/spi-loopback-test.c @@ -0,0 +1,995 @@ +/* + * linux/drivers/spi/spi-loopback-test.c + * + * (c) Martin Sperl + * + * Loopback test driver to test several typical spi_message conditions + * that a spi_master driver may encounter + * this can also get used for regression testing + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "spi-test.h" + +/* flag to only simulate transfers */ +int simulate_only; +module_param(simulate_only, int, 0); +MODULE_PARM_DESC(simulate_only, "if not 0 do not execute the spi message"); + +/* dump spi messages */ +int dump_messages; +module_param(dump_messages, int, 0); +MODULE_PARM_DESC(dump_message, + "=1 dump the basic spi_message_structure, " \ + "=2 dump the spi_message_structure including data, " \ + "=3 dump the spi_message structure before and after execution"); +/* the device is jumpered for loopback - enabling some rx_buf tests */ +int loopback; +module_param(loopback, int, 0); +MODULE_PARM_DESC(loopback, + "if set enable loopback mode, where the rx_buf " \ + "is checked to match tx_buf after the spi_message " \ + "is executed"); + +/* run only a specific test */ +int run_only_test = -1; +module_param(run_only_test, int, 0); +MODULE_PARM_DESC(run_only_test, + "only run the test with this number (0-based !)"); + +/* the actual tests to execute */ +static struct spi_test spi_tests[] = { + { + .description = "tx/rx-transfer - start of page", + .fill_option = FILL_COUNT_8, + .iterate_len = { ITERATE_MAX_LEN }, + .iterate_tx_align = ITERATE_ALIGN, + .iterate_rx_align = ITERATE_ALIGN, + .transfers = { + { + .len = 1, + .tx_buf = TX(0), + .rx_buf = RX(0), + }, + }, + }, + { + .description = "tx/rx-transfer - crossing PAGE_SIZE", + .fill_option = FILL_COUNT_8, + .iterate_len = { ITERATE_MAX_LEN }, + .iterate_tx_align = ITERATE_ALIGN, + .iterate_rx_align = ITERATE_ALIGN, + .transfers = { + { + .len = 1, + .tx_buf = TX(PAGE_SIZE - 4), + .rx_buf = RX(PAGE_SIZE - 4), + }, + }, + }, + { + .description = "tx-transfer - only", + .fill_option = FILL_COUNT_8, + .iterate_len = { ITERATE_MAX_LEN }, + .iterate_tx_align = ITERATE_ALIGN, + .transfers = { + { + .len = 1, + .tx_buf = TX(0), + }, + }, + }, + { + .description = "rx-transfer - only", + .fill_option = FILL_COUNT_8, + .iterate_len = { ITERATE_MAX_LEN }, + .iterate_rx_align = ITERATE_ALIGN, + .transfers = { + { + .len = 1, + .rx_buf = RX(0), + }, + }, + }, + { + .description = "two tx-transfers - alter both", + .fill_option = FILL_COUNT_8, + .iterate_len = { ITERATE_LEN }, + .iterate_tx_align = ITERATE_ALIGN, + .iterate_transfer_mask = BIT(0) | BIT(1), + .transfers = { + { + .len = 1, + .tx_buf = TX(0), + }, + { + .len = 1, + /* this is why we cant use ITERATE_MAX_LEN */ + .tx_buf = TX(SPI_TEST_MAX_SIZE_HALF), + }, + }, + }, + { + .description = "two tx-transfers - alter first", + .fill_option = FILL_COUNT_8, + .iterate_len = { ITERATE_MAX_LEN }, + .iterate_tx_align = ITERATE_ALIGN, + .iterate_transfer_mask = BIT(1), + .transfers = { + { + .len = 1, + .tx_buf = TX(64), + }, + { + .len = 1, + .tx_buf = TX(0), + }, + }, + }, + { + .description = "two tx-transfers - alter second", + .fill_option = FILL_COUNT_8, + .iterate_len = { ITERATE_MAX_LEN }, + .iterate_tx_align = ITERATE_ALIGN, + .iterate_transfer_mask = BIT(0), + .transfers = { + { + .len = 16, + .tx_buf = TX(0), + }, + { + .len = 1, + .tx_buf = TX(64), + }, + }, + }, + { + .description = "two transfers tx then rx - alter both", + .fill_option = FILL_COUNT_8, + .iterate_len = { ITERATE_MAX_LEN }, + .iterate_tx_align = ITERATE_ALIGN, + .iterate_transfer_mask = BIT(0) | BIT(1), + .transfers = { + { + .len = 1, + .tx_buf = TX(0), + }, + { + .len = 1, + .rx_buf = RX(0), + }, + }, + }, + { + .description = "two transfers tx then rx - alter tx", + .fill_option = FILL_COUNT_8, + .iterate_len = { ITERATE_MAX_LEN }, + .iterate_tx_align = ITERATE_ALIGN, + .iterate_transfer_mask = BIT(0), + .transfers = { + { + .len = 1, + .tx_buf = TX(0), + }, + { + .len = 1, + .rx_buf = RX(0), + }, + }, + }, + { + .description = "two transfers tx then rx - alter rx", + .fill_option = FILL_COUNT_8, + .iterate_len = { ITERATE_MAX_LEN }, + .iterate_tx_align = ITERATE_ALIGN, + .iterate_transfer_mask = BIT(1), + .transfers = { + { + .len = 1, + .tx_buf = TX(0), + }, + { + .len = 1, + .rx_buf = RX(0), + }, + }, + }, + { + .description = "two tx+rx transfers - alter both", + .fill_option = FILL_COUNT_8, + .iterate_len = { ITERATE_LEN }, + .iterate_tx_align = ITERATE_ALIGN, + .iterate_transfer_mask = BIT(0) | BIT(1), + .transfers = { + { + .len = 1, + .tx_buf = TX(0), + .rx_buf = RX(0), + }, + { + .len = 1, + /* making sure we align without overwrite + * the reason we can not use ITERATE_MAX_LEN + */ + .tx_buf = TX(SPI_TEST_MAX_SIZE_HALF), + .rx_buf = RX(SPI_TEST_MAX_SIZE_HALF), + }, + }, + }, + { + .description = "two tx+rx transfers - alter first", + .fill_option = FILL_COUNT_8, + .iterate_len = { ITERATE_MAX_LEN }, + .iterate_tx_align = ITERATE_ALIGN, + .iterate_transfer_mask = BIT(0), + .transfers = { + { + .len = 1, + /* making sure we align without overwrite */ + .tx_buf = TX(1024), + .rx_buf = RX(1024), + }, + { + .len = 1, + /* making sure we align without overwrite */ + .tx_buf = TX(0), + .rx_buf = RX(0), + }, + }, + }, + { + .description = "two tx+rx transfers - alter second", + .fill_option = FILL_COUNT_8, + .iterate_len = { ITERATE_MAX_LEN }, + .iterate_tx_align = ITERATE_ALIGN, + .iterate_transfer_mask = BIT(0), + .transfers = { + { + .len = 1, + .tx_buf = TX(0), + .rx_buf = RX(0), + }, + { + .len = 1, + /* making sure we align without overwrite */ + .tx_buf = TX(1024), + .rx_buf = RX(1024), + }, + }, + }, + + { /* end of tests sequence */ } +}; + +static int spi_loopback_test_probe(struct spi_device *spi) +{ + int ret; + + dev_info(&spi->dev, "Executing spi-loopback-tests\n"); + + ret = spi_test_run_tests(spi, spi_tests); + + dev_info(&spi->dev, "Finished spi-loopback-tests with return: %i\n", + ret); + + return ret; +} + +/* non const match table to permit to change via a module parameter */ +static struct of_device_id spi_loopback_test_of_match[] = { + { .compatible = "linux,spi-loopback-test", }, + { } +}; + +/* allow to override the compatible string via a module_parameter */ +module_param_string(compatible, spi_loopback_test_of_match[0].compatible, + sizeof(spi_loopback_test_of_match[0].compatible), + 0000); + +MODULE_DEVICE_TABLE(of, spi_loopback_test_of_match); + +static struct spi_driver spi_loopback_test_driver = { + .driver = { + .name = "spi-loopback-test", + .owner = THIS_MODULE, + .of_match_table = spi_loopback_test_of_match, + }, + .probe = spi_loopback_test_probe, +}; + +module_spi_driver(spi_loopback_test_driver); + +MODULE_AUTHOR("Martin Sperl "); +MODULE_DESCRIPTION("test spi_driver to check core functionality"); +MODULE_LICENSE("GPL"); + +/*-------------------------------------------------------------------------*/ + +/* spi_test implementation */ + +#define RANGE_CHECK(ptr, plen, start, slen) \ + ((ptr >= start) && (ptr + plen <= start + slen)) + +/* we allocate one page more, to allow for offsets */ +#define SPI_TEST_MAX_SIZE_PLUS (SPI_TEST_MAX_SIZE + PAGE_SIZE) + +static void spi_test_print_hex_dump(char *pre, const void *ptr, size_t len) +{ + /* limit the hex_dump */ + if (len < 1024) { + print_hex_dump(KERN_INFO, pre, + DUMP_PREFIX_OFFSET, 16, 1, + ptr, len, 0); + return; + } + /* print head */ + print_hex_dump(KERN_INFO, pre, + DUMP_PREFIX_OFFSET, 16, 1, + ptr, 512, 0); + /* print tail */ + pr_info("%s truncated - continuing at offset %04x\n", + pre, len - 512); + print_hex_dump(KERN_INFO, pre, + DUMP_PREFIX_OFFSET, 16, 1, + ptr + (len - 512), 512, 0); +} + +static void spi_test_dump_message(struct spi_device *spi, + struct spi_message *msg, + bool dump_data) +{ + struct spi_transfer *xfer; + int i; + u8 b; + + dev_info(&spi->dev, " spi_msg@%pK\n", msg); + if (msg->status) + dev_info(&spi->dev, " status: %i\n", + msg->status); + dev_info(&spi->dev, " frame_length: %i\n", + msg->frame_length); + dev_info(&spi->dev, " actual_length: %i\n", + msg->actual_length); + + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + dev_info(&spi->dev, " spi_transfer@%pK\n", xfer); + dev_info(&spi->dev, " len: %i\n", xfer->len); + dev_info(&spi->dev, " tx_buf: %pK\n", xfer->tx_buf); + if (dump_data && xfer->tx_buf) + spi_test_print_hex_dump(" TX: ", + xfer->tx_buf, + xfer->len); + + dev_info(&spi->dev, " rx_buf: %pK\n", xfer->rx_buf); + if (dump_data && xfer->rx_buf) + spi_test_print_hex_dump(" RX: ", + xfer->rx_buf, + xfer->len); + /* check for unwritten test pattern on rx_buf */ + if (xfer->rx_buf) { + for (i = 0 ; i < xfer->len ; i++) { + b = ((u8 *)xfer->rx_buf)[xfer->len - 1 - i]; + if (b != SPI_TEST_PATTERN_UNWRITTEN) + break; + } + if (i) + dev_info(&spi->dev, + " rx_buf filled with %02x starts at offset: %i\n", + SPI_TEST_PATTERN_UNWRITTEN, + xfer->len - i); + } + } +} + +struct rx_ranges { + struct list_head list; + u8 *start; + u8 *end; +}; + +int rx_ranges_cmp(void *priv, struct list_head *a, struct list_head *b) +{ + struct rx_ranges *rx_a = list_entry(a, struct rx_ranges, list); + struct rx_ranges *rx_b = list_entry(b, struct rx_ranges, list); + + if (rx_a->start > rx_b->start) + return 1; + if (rx_a->start < rx_b->start) + return -1; + return 0; +} + +static int spi_check_rx_ranges(struct spi_device *spi, + struct spi_message *msg, + void *rx) +{ + struct spi_transfer *xfer; + struct rx_ranges ranges[SPI_TEST_MAX_TRANSFERS], *r; + int i = 0; + LIST_HEAD(ranges_list); + u8 *addr; + int ret = 0; + + /* loop over all transfers to fill in the rx_ranges */ + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + /* if there is no rx, then no check is needed */ + if (!xfer->rx_buf) + continue; + /* fill in the rx_range */ + if (RANGE_CHECK(xfer->rx_buf, xfer->len, + rx, SPI_TEST_MAX_SIZE_PLUS)) { + ranges[i].start = xfer->rx_buf; + ranges[i].end = xfer->rx_buf + xfer->len; + list_add(&ranges[i].list, &ranges_list); + i++; + } + } + + /* if no ranges, then we can return and avoid the checks...*/ + if (!i) + return 0; + + /* sort the list */ + list_sort(NULL, &ranges_list, rx_ranges_cmp); + + /* and iterate over all the rx addresses */ + for (addr = rx; addr < (u8 *)rx + SPI_TEST_MAX_SIZE_PLUS; addr++) { + /* if we are the DO not write pattern, + * then continue with the loop... + */ + if (*addr == SPI_TEST_PATTERN_DO_NOT_WRITE) + continue; + + /* check if we are inside a range */ + list_for_each_entry(r, &ranges_list, list) { + /* if so then set to end... */ + if ((addr >= r->start) && (addr < r->end)) + addr = r->end; + } + /* second test after a (hopefull) translation */ + if (*addr == SPI_TEST_PATTERN_DO_NOT_WRITE) + continue; + + /* if still not found then something has modified too much */ + /* we could list the "closest" transfer here... */ + dev_err(&spi->dev, + "loopback strangeness - rx changed outside of allowed range at: %pK\n", + addr); + /* do not return, only set ret, + * so that we list all addresses + */ + ret = -ERANGE; + } + + return ret; +} + +static int spi_test_check_loopback_result(struct spi_device *spi, + struct spi_message *msg, + void *tx, void *rx) +{ + struct spi_transfer *xfer; + u8 rxb, txb; + size_t i; + + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + /* if there is no rx, then no check is needed */ + if (!xfer->rx_buf) + continue; + /* so depending on tx_buf we need to handle things */ + if (xfer->tx_buf) { + for (i = 1; i < xfer->len; i++) { + txb = ((u8 *)xfer->tx_buf)[i]; + rxb = ((u8 *)xfer->rx_buf)[i]; + if (txb != rxb) + goto mismatch_error; + } + } else { + /* first byte received */ + txb = ((u8 *)xfer->rx_buf)[0]; + /* first byte may be 0 or xff */ + if (!((txb == 0) || (txb == 0xff))) { + dev_err(&spi->dev, + "loopback strangeness - we expect 0x00 or 0xff, but not 0x%02x\n", + txb); + return -EINVAL; + } + /* check that all bytes are identical */ + for (i = 1; i < xfer->len; i++) { + rxb = ((u8 *)xfer->rx_buf)[i]; + if (rxb != txb) + goto mismatch_error; + } + } + } + + return spi_check_rx_ranges(spi, msg, rx); + +mismatch_error: + dev_err(&spi->dev, + "loopback strangeness - transfer missmatch on byte %04x - expected 0x%02x, but got 0x%02x\n", + i, txb, rxb); + + return -EINVAL; +} + +static int spi_test_translate(struct spi_device *spi, + void **ptr, size_t len, + void *tx, void *rx) +{ + size_t off; + + /* return on null */ + if (!*ptr) + return 0; + + /* in the MAX_SIZE_HALF case modify the pointer */ + if (((size_t)*ptr) & SPI_TEST_MAX_SIZE_HALF) + /* move the pointer to the correct range */ + *ptr += (SPI_TEST_MAX_SIZE_PLUS / 2) - + SPI_TEST_MAX_SIZE_HALF; + + /* RX range + * - we check against MAX_SIZE_PLUS to allow for automated alignment + */ + if (RANGE_CHECK(*ptr, len, RX(0), SPI_TEST_MAX_SIZE_PLUS)) { + off = *ptr - RX(0); + *ptr = rx + off; + + return 0; + } + + /* TX range */ + if (RANGE_CHECK(*ptr, len, TX(0), SPI_TEST_MAX_SIZE_PLUS)) { + off = *ptr - TX(0); + *ptr = tx + off; + + return 0; + } + + dev_err(&spi->dev, + "PointerRange [%pK:%pK[ not in range [%pK:%pK[ or [%pK:%pK[\n", + *ptr, *ptr + len, + RX(0), RX(SPI_TEST_MAX_SIZE), + TX(0), TX(SPI_TEST_MAX_SIZE)); + + return -EINVAL; +} + +static int spi_test_fill_tx(struct spi_device *spi, struct spi_test *test) +{ + struct spi_transfer *xfers = test->transfers; + u8 *tx_buf; + size_t count = 0; + int i, j; + +#ifdef __BIG_ENDIAN +#define GET_VALUE_BYTE(value, index, bytes) \ + (value >> (8 * (bytes - 1 - count % bytes))) +#else +#define GET_VALUE_BYTE(value, index, bytes) \ + (value >> (8 * (count % bytes))) +#endif + + /* fill all transfers with the pattern requested */ + for (i = 0; i < test->transfer_count; i++) { + /* if tx_buf is NULL then skip */ + tx_buf = (u8 *)xfers[i].tx_buf; + if (!tx_buf) + continue; + /* modify all the transfers */ + for (j = 0; j < xfers[i].len; j++, tx_buf++, count++) { + /* fill tx */ + switch (test->fill_option) { + case FILL_MEMSET_8: + *tx_buf = test->fill_pattern; + break; + case FILL_MEMSET_16: + *tx_buf = GET_VALUE_BYTE(test->fill_pattern, + count, 2); + break; + case FILL_MEMSET_24: + *tx_buf = GET_VALUE_BYTE(test->fill_pattern, + count, 3); + break; + case FILL_MEMSET_32: + *tx_buf = GET_VALUE_BYTE(test->fill_pattern, + count, 4); + break; + case FILL_COUNT_8: + *tx_buf = count; + break; + case FILL_COUNT_16: + *tx_buf = GET_VALUE_BYTE(count, count, 2); + break; + case FILL_COUNT_24: + *tx_buf = GET_VALUE_BYTE(count, count, 3); + break; + case FILL_COUNT_32: + *tx_buf = GET_VALUE_BYTE(count, count, 4); + break; + case FILL_TRANSFER_BYTE_8: + *tx_buf = j; + break; + case FILL_TRANSFER_BYTE_16: + *tx_buf = GET_VALUE_BYTE(j, j, 2); + break; + case FILL_TRANSFER_BYTE_24: + *tx_buf = GET_VALUE_BYTE(j, j, 3); + break; + case FILL_TRANSFER_BYTE_32: + *tx_buf = GET_VALUE_BYTE(j, j, 4); + break; + case FILL_TRANSFER_NUM: + *tx_buf = i; + break; + default: + dev_err(&spi->dev, + "unsupported fill_option: %i\n", + test->fill_option); + return -EINVAL; + } + } + /* fill rx_buf with SPI_TEST_PATTERN_UNWRITTEN */ + if (xfers[i].rx_buf) + memset(xfers[i].rx_buf, SPI_TEST_PATTERN_UNWRITTEN, + xfers[i].len); + } + + return 0; +} + +static int _spi_test_run_iter(struct spi_device *spi, + struct spi_test *test, + void *tx, void *rx) +{ + struct spi_message *msg = &test->msg; + struct spi_transfer *x; + int i, ret; + + /* initialize message - zero-filled via static initialization */ + spi_message_init_no_memset(msg); + + /* fill rx with the DO_NOT_WRITE pattern */ + memset(rx, SPI_TEST_PATTERN_DO_NOT_WRITE, SPI_TEST_MAX_SIZE_PLUS); + + /* add the individual transfers */ + for (i = 0; i < test->transfer_count; i++) { + x = &test->transfers[i]; + + /* patch the values of tx_buf */ + ret = spi_test_translate(spi, (void **)&x->tx_buf, x->len, + (void *)tx, rx); + if (ret) + return ret; + + /* patch the values of rx_buf */ + ret = spi_test_translate(spi, &x->rx_buf, x->len, + (void *)tx, rx); + if (ret) + return ret; + + /* and add it to the list */ + spi_message_add_tail(x, msg); + } + + /* fill in the transfer data */ + ret = spi_test_fill_tx(spi, test); + if (ret) + return ret; + + /* and execute */ + if (test->execute_msg) + ret = test->execute_msg(spi, test, tx, rx); + else + ret = spi_test_execute_msg(spi, test, tx, rx); + + /* handle result */ + if (ret == test->expected_return) + return 0; + + dev_err(&spi->dev, + "test failed - test returned %i, but we expect %i\n", + ret, test->expected_return); + + if (ret) + return ret; + + /* if it is 0, as we expected something else, + * then return something special + */ + return -EFAULT; +} + +static int spi_test_run_iter(struct spi_device *spi, + const struct spi_test *testtemplate, + void *tx, void *rx, + size_t len, + size_t tx_off, + size_t rx_off + ) +{ + struct spi_test test; + int i, tx_count, rx_count; + + /* copy the test template to test */ + memcpy(&test, testtemplate, sizeof(test)); + + /* set up test->transfers to the correct count */ + if (!test.transfer_count) { + for (i = 0; + (i < SPI_TEST_MAX_TRANSFERS) && test.transfers[i].len; + i++) { + test.transfer_count++; + } + } + + /* if iterate_transfer_mask is not set, + * then set it to first transfer only + */ + if (!(test.iterate_transfer_mask & (BIT(test.transfer_count) - 1))) + test.iterate_transfer_mask = 1; + + /* count number of transfers with tx/rx_buf != NULL */ + for (i = 0; i < test.transfer_count; i++) { + if (test.transfers[i].tx_buf) + tx_count++; + if (test.transfers[i].rx_buf) + rx_count++; + } + + /* in some iteration cases warn and exit early, + * as there is nothing to do, that has not been tested already... + */ + if (tx_off && (!tx_count)) { + dev_warn_once(&spi->dev, + "%s: iterate_tx_off configured with tx_buf==NULL - ignoring\n", + test.description); + return 0; + } + if (rx_off && (!rx_count)) { + dev_warn_once(&spi->dev, + "%s: iterate_rx_off configured with rx_buf==NULL - ignoring\n", + test.description); + return 0; + } + + /* write out info */ + if (!(len || tx_off || rx_off)) { + dev_info(&spi->dev, "Running test %s\n", test.description); + } else { + dev_info(&spi->dev, + " with iteration values: len = %i, tx_off = %i, rx_off = %i\n", + len, tx_off, rx_off); + } + + /* update in the values from iteration values */ + for (i = 0; i < test.transfer_count; i++) { + /* only when bit in transfer mask is set */ + if (!(test.iterate_transfer_mask & BIT(i))) + continue; + if (len) + test.transfers[i].len = len; + if (test.transfers[i].tx_buf) + test.transfers[i].tx_buf += tx_off; + if (test.transfers[i].tx_buf) + test.transfers[i].rx_buf += rx_off; + } + + /* and execute */ + return _spi_test_run_iter(spi, &test, tx, rx); +} + +/** + * spi_test_execute_msg - default implementation to run a test + * + * spi: @spi_device on which to run the @spi_message + * test: the test to execute, which already contains @msg + * tx: the tx buffer allocated for the test sequence + * rx: the rx buffer allocated for the test sequence + * + * Returns: error code of spi_sync as well as basic error checking + */ +int spi_test_execute_msg(struct spi_device *spi, struct spi_test *test, + void *tx, void *rx) +{ + struct spi_message *msg = &test->msg; + int ret = 0; + int i; + + /* only if we do not simulate */ + if (!simulate_only) { + /* dump the complete message before and after the transfer */ + if (dump_messages == 3) + spi_test_dump_message(spi, msg, true); + + /* run spi message */ + ret = spi_sync(spi, msg); + if (ret == -ETIMEDOUT) { + dev_info(&spi->dev, + "spi-message timed out - reruning...\n"); + /* rerun after a few explicit schedules */ + for (i = 0; i < 16; i++) + schedule(); + ret = spi_sync(spi, msg); + } + if (ret) { + dev_err(&spi->dev, + "Failed to execute spi_message: %i\n", + ret); + goto exit; + } + + /* do some extra error checks */ + if (msg->frame_length != msg->actual_length) { + dev_err(&spi->dev, + "actual length differs from expected\n"); + ret = -EIO; + goto exit; + } + + /* run rx-tests when in loopback mode */ + if (loopback) + ret = spi_test_check_loopback_result(spi, msg, + tx, rx); + } + + /* if requested or on error dump message (including data) */ +exit: + if (dump_messages || ret) + spi_test_dump_message(spi, msg, + (dump_messages >= 2) || (ret)); + + return ret; +} +EXPORT_SYMBOL_GPL(spi_test_execute_msg); + +/** + * spi_test_run_test - run an individual spi_test + * including all the relevant iterations on: + * length and buffer alignment + * + * spi: the spi_device to send the messages to + * test: the test which we need to execute + * tx: the tx buffer allocated for the test sequence + * rx: the rx buffer allocated for the test sequence + * + * Returns: status code of spi_sync or other failures + */ + +int spi_test_run_test(struct spi_device *spi, const struct spi_test *test, + void *tx, void *rx) +{ + int idx_len; + size_t len; + size_t tx_align, rx_align; + int ret; + + /* test for transfer limits */ + if (test->transfer_count >= SPI_TEST_MAX_TRANSFERS) { + dev_err(&spi->dev, + "%s: Exceeded max number of transfers with %i\n", + test->description, test->transfer_count); + return -E2BIG; + } + + /* setting up some values in spi_message + * based on some settings in spi_master + * some of this can also get done in the run() method + */ + + /* iterate over all the iterable values using macros + * (to make it a bit more readable... + */ +#define FOR_EACH_ITERATE(var, defaultvalue) \ + for (idx_##var = -1, var = defaultvalue; \ + ((idx_##var < 0) || \ + ( \ + (idx_##var < SPI_TEST_MAX_ITERATE) && \ + (var = test->iterate_##var[idx_##var]) \ + ) \ + ); \ + idx_##var++) +#define FOR_EACH_ALIGNMENT(var) \ + for (var = 0; \ + var < (test->iterate_##var ? \ + (spi->master->dma_alignment ? \ + spi->master->dma_alignment : \ + test->iterate_##var) : \ + 1); \ + var++) + + FOR_EACH_ITERATE(len, 0) { + FOR_EACH_ALIGNMENT(tx_align) { + FOR_EACH_ALIGNMENT(rx_align) { + /* and run the iteration */ + ret = spi_test_run_iter(spi, test, + tx, rx, + len, + tx_align, + rx_align); + if (ret) + return ret; + } + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(spi_test_run_test); + +/** + * spi_test_run_tests - run an array of spi_messages tests + * @spi: the spi device on which to run the tests + * @tests: NULL-terminated array of @spi_test + * + * Returns: status errors as per @spi_test_run_test() + */ + +int spi_test_run_tests(struct spi_device *spi, + struct spi_test *tests) +{ + char *rx = NULL, *tx = NULL; + int ret = 0, count = 0; + struct spi_test *test; + + /* allocate rx/tx buffers of 128kB size without devm + * in the hope that is on a page boundary + */ + rx = kzalloc(SPI_TEST_MAX_SIZE_PLUS, GFP_KERNEL); + if (!rx) { + ret = -ENOMEM; + goto out; + } + + tx = kzalloc(SPI_TEST_MAX_SIZE_PLUS, GFP_KERNEL); + if (!tx) { + ret = -ENOMEM; + goto out; + } + + /* now run the individual tests in the table */ + for (test = tests, count = 0; test->description[0]; + test++, count++) { + /* only run test if requested */ + if ((run_only_test > -1) && (count != run_only_test)) + continue; + /* run custom implementation */ + if (test->run_test) + ret = test->run_test(spi, test, tx, rx); + else + ret = spi_test_run_test(spi, test, tx, rx); + if (ret) + goto out; + /* add some delays so that we can easily + * detect the individual tests when using a logic analyzer + * we also add scheduling to avoid potential spi_timeouts... + */ + mdelay(100); + schedule(); + } + +out: + kfree(rx); + kfree(tx); + return ret; +} +EXPORT_SYMBOL_GPL(spi_test_run_tests); diff --git a/drivers/spi/spi-test.h b/drivers/spi/spi-test.h new file mode 100644 index 0000000000000..7bfdbe24cf7e4 --- /dev/null +++ b/drivers/spi/spi-test.h @@ -0,0 +1,135 @@ +/* + * linux/drivers/spi/spi-test.h + * + * (c) Martin Sperl + * + * spi_test definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +#define SPI_TEST_MAX_TRANSFERS 4 +#define SPI_TEST_MAX_SIZE (32 * PAGE_SIZE) +#define SPI_TEST_MAX_ITERATE 16 + +/* the "dummy" start addresses used in spi_test + * these addresses get translated at a later stage + */ +#define RX_START BIT(30) +#define TX_START BIT(31) +#define RX(off) ((void *)(RX_START + off)) +#define TX(off) ((void *)(TX_START + off)) + +/* some special defines for offsets */ +#define SPI_TEST_MAX_SIZE_HALF BIT(29) + +/* detection pattern for unfinished reads... + * - 0x00 or 0xff could be valid levels for tx_buf = NULL, + * so we do not use either of them + */ +#define SPI_TEST_PATTERN_UNWRITTEN 0xAA +#define SPI_TEST_PATTERN_DO_NOT_WRITE 0x55 +#define SPI_TEST_CHECK_DO_NOT_WRITE 64 + +/** + * struct spi_test - describes a specific (set of) tests to execute + * + * @description: description of the test + * + * @msg: a template @spi_message usedfor the default settings + * @transfers: array of @spi_transfers that are part of the + * resulting spi_message. The first transfer with len == 0 + * signifies the end of the list + * @transfer_count: normally computed number of transfers with len > 0 + * + * @run_test: run a specific spi_test - this allows to override + * the default implementation of @spi_test_run_transfer + * either to add some custom filters for a specific test + * or to effectively run some very custom tests... + * @execute_msg: run the spi_message for real - this allows to override + * @spi_test_execute_msg to apply final modifications + * on the spi_message + * @expected_return: the expected return code - in some cases we want to + * test also for error conditions + * + * @iterate_len: list of length to iterate on (in addition to the + * explicitly set @spi_transfer.len) + * @iterate_tx_align: change the alignment of @spi_transfer.tx_buf + * for all values in the below range if set. + * the ranges are: + * [0 : @spi_master.dma_alignment[ if set + * [0 : iterate_tx_align[ if unset + * @iterate_rx_align: change the alignment of @spi_transfer.rx_buf + * see @iterate_tx_align for details + * @iterate_transfer_mask: the bitmask of transfers to which the iterations + * apply - if 0, then it applies to all transfer + * + * @fill_option: define the way how tx_buf is filled + * @fill_pattern: fill pattern to apply to the tx_buf + * (used in some of the @fill_options) + */ + +struct spi_test { + char description[64]; + struct spi_message msg; + struct spi_transfer transfers[SPI_TEST_MAX_TRANSFERS]; + unsigned int transfer_count; + int (*run_test)(struct spi_device *spi, struct spi_test *test, + void *tx, void *rx); + int (*execute_msg)(struct spi_device *spi, struct spi_test *test, + void *tx, void *rx); + int expected_return; + /* iterate over all the non-zero values */ + int iterate_len[SPI_TEST_MAX_ITERATE]; + int iterate_tx_align; + int iterate_rx_align; + u32 iterate_transfer_mask; + /* the tx-fill operation */ + u32 fill_option; +#define FILL_MEMSET_8 0 /* just memset with 8 bit */ +#define FILL_MEMSET_16 1 /* just memset with 16 bit */ +#define FILL_MEMSET_24 2 /* just memset with 24 bit */ +#define FILL_MEMSET_32 3 /* just memset with 32 bit */ +#define FILL_COUNT_8 4 /* fill with a 8 byte counter */ +#define FILL_COUNT_16 5 /* fill with a 16 bit counter */ +#define FILL_COUNT_24 6 /* fill with a 24 bit counter */ +#define FILL_COUNT_32 7 /* fill with a 32 bit counter */ +#define FILL_TRANSFER_BYTE_8 8 /* fill with the transfer byte - 8 bit */ +#define FILL_TRANSFER_BYTE_16 9 /* fill with the transfer byte - 16 bit */ +#define FILL_TRANSFER_BYTE_24 10 /* fill with the transfer byte - 24 bit */ +#define FILL_TRANSFER_BYTE_32 11 /* fill with the transfer byte - 32 bit */ +#define FILL_TRANSFER_NUM 16 /* fill with the transfer number */ + u32 fill_pattern; +}; + +/* default implementation for @spi_test.run_test */ +int spi_test_run_test(struct spi_device *spi, + const struct spi_test *test, + void *tx, void *rx); + +/* default implementation for @spi_test.execute_msg */ +int spi_test_execute_msg(struct spi_device *spi, + struct spi_test *test, + void *tx, void *rx); + +/* function to execute a set of tests */ +int spi_test_run_tests(struct spi_device *spi, + struct spi_test *tests); + +/* some of the default @spi_transfer.len to test */ +#define ITERATE_LEN 16, 32, 64, 128, 256, 1024, PAGE_SIZE, 65536 + +#define ITERATE_MAX_LEN ITERATE_LEN, SPI_TEST_MAX_SIZE + +/* the default alignment to test */ +#define ITERATE_ALIGN sizeof(int) -- GitLab From 97896195b3f7a6bcbfd52fd920cab5a3df2c5445 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Fri, 27 Nov 2015 16:17:21 +0000 Subject: [PATCH 1094/2855] spi: add spi-loopback-test to build framework adding the spi-loopback-test module to Kconfig and Makefile Signed-off-by: Martin Sperl Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 9 +++++++++ drivers/spi/Makefile | 1 + 2 files changed, 10 insertions(+) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 8b9c2a38d1ccd..0876d59537977 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -689,6 +689,15 @@ config SPI_SPIDEV Note that this application programming interface is EXPERIMENTAL and hence SUBJECT TO CHANGE WITHOUT NOTICE while it stabilizes. +config SPI_LOOPBACK_TEST + tristate "spi loopback test framework support" + depends on m + help + This enables the SPI loopback testing framework driver + + primarily used for development of spi_master drivers + and to detect regressions + config SPI_TLE62X0 tristate "Infineon TLE62X0 (for power switching)" depends on SYSFS diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 31fb7fb2a0b69..8991ffce6e12d 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -8,6 +8,7 @@ ccflags-$(CONFIG_SPI_DEBUG) := -DDEBUG # config declarations into driver model code obj-$(CONFIG_SPI_MASTER) += spi.o obj-$(CONFIG_SPI_SPIDEV) += spidev.o +obj-$(CONFIG_SPI_LOOPBACK_TEST) += spi-loopback-test.o # SPI master controller drivers (bus) obj-$(CONFIG_SPI_ALTERA) += spi-altera.o -- GitLab From f889beaaab1ce2ff9d018302359abb345f49be29 Mon Sep 17 00:00:00 2001 From: Steve Twiss Date: Sat, 12 Dec 2015 20:43:35 -0800 Subject: [PATCH 1095/2855] Input: da9063 - report KEY_POWER instead of KEY_SLEEP during power key-press Stop reporting KEY_SLEEP for a short key-press and report KEY_POWER instead This change applies to both DA9063 and DA9062 ONKEY drivers. A previous application used for testing by the developer required a KEY_SLEEP and KEY_POWER input_report_key event to distinguish between a short and long key-press of the power key. This is not the general convention and the typical solution is for KEY_POWER to be used in both cases: suspend and S/W power off. Signed-off-by: Steve Twiss Signed-off-by: Dmitry Torokhov --- drivers/input/misc/da9063_onkey.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/input/misc/da9063_onkey.c b/drivers/input/misc/da9063_onkey.c index 8eb697db82d03..bb863e062b03b 100644 --- a/drivers/input/misc/da9063_onkey.c +++ b/drivers/input/misc/da9063_onkey.c @@ -179,13 +179,13 @@ static irqreturn_t da9063_onkey_irq_handler(int irq, void *data) input_report_key(onkey->input, KEY_POWER, 1); input_sync(onkey->input); schedule_delayed_work(&onkey->work, 0); - dev_dbg(onkey->dev, "KEY_POWER pressed.\n"); + dev_dbg(onkey->dev, "KEY_POWER long press.\n"); } else { - input_report_key(onkey->input, KEY_SLEEP, 1); + input_report_key(onkey->input, KEY_POWER, 1); input_sync(onkey->input); - input_report_key(onkey->input, KEY_SLEEP, 0); + input_report_key(onkey->input, KEY_POWER, 0); input_sync(onkey->input); - dev_dbg(onkey->dev, "KEY_SLEEP pressed.\n"); + dev_dbg(onkey->dev, "KEY_POWER short press.\n"); } return IRQ_HANDLED; -- GitLab From 10cf4899f8affa468b9140f377857bfe3f563012 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 11 Nov 2015 11:45:30 -0800 Subject: [PATCH 1096/2855] gpiolib: tighten up ACPI legacy gpio lookups We should not fall back to the legacy unnamed gpio lookup style if the driver requests gpios with different names, because we'll give out the same gpio twice. Let's keep track of the names that were used for the device and only do the fallback for the first name used. Signed-off-by: Dmitry Torokhov Acked-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-acpi.c | 43 +++++++++++++++++++++++++++++++++++++ drivers/gpio/gpiolib.c | 3 +++ drivers/gpio/gpiolib.h | 8 +++++++ 3 files changed, 54 insertions(+) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 16a7b68167444..7ab7bc3c93003 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -922,3 +922,46 @@ int acpi_gpio_count(struct device *dev, const char *con_id) } return count; } + +struct acpi_crs_lookup { + struct list_head node; + struct acpi_device *adev; + const char *con_id; +}; + +static DEFINE_MUTEX(acpi_crs_lookup_lock); +static LIST_HEAD(acpi_crs_lookup_list); + +bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id) +{ + struct acpi_crs_lookup *l, *lookup = NULL; + + /* Never allow fallback if the device has properties */ + if (adev->data.properties || adev->driver_gpios) + return false; + + mutex_lock(&acpi_crs_lookup_lock); + + list_for_each_entry(l, &acpi_crs_lookup_list, node) { + if (l->adev == adev) { + lookup = l; + break; + } + } + + if (!lookup) { + lookup = kmalloc(sizeof(*lookup), GFP_KERNEL); + if (lookup) { + lookup->adev = adev; + lookup->con_id = con_id; + list_add_tail(&lookup->node, &acpi_crs_lookup_list); + } + } + + mutex_unlock(&acpi_crs_lookup_lock); + + return lookup && + ((!lookup->con_id && !con_id) || + (lookup->con_id && con_id && + strcmp(lookup->con_id, con_id) == 0)); +} diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index a18f00fc1bb87..3ca6c9f4391e8 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1868,6 +1868,9 @@ static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id, /* Then from plain _CRS GPIOs */ if (IS_ERR(desc)) { + if (!acpi_can_fallback_to_crs(adev, con_id)) + return ERR_PTR(-ENOENT); + desc = acpi_get_gpiod_by_index(adev, NULL, idx, &info); if (IS_ERR(desc)) return desc; diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 98ab08c0aa2d2..2b87cbd68478c 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -47,6 +47,8 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, struct acpi_gpio_info *info); int acpi_gpio_count(struct device *dev, const char *con_id); + +bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id); #else static inline void acpi_gpiochip_add(struct gpio_chip *chip) { } static inline void acpi_gpiochip_remove(struct gpio_chip *chip) { } @@ -73,6 +75,12 @@ static inline int acpi_gpio_count(struct device *dev, const char *con_id) { return -ENODEV; } + +static inline bool acpi_can_fallback_to_crs(struct acpi_device *adev, + const char *con_id) +{ + return false; +} #endif struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, -- GitLab From a34d5e8a6ad1a31b186019c9c351777626698863 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 12 Dec 2015 16:09:14 -0800 Subject: [PATCH 1097/2855] libnvdimm, pfn: add parent uuid validation Track and check the uuid of the namespace hosting a pfn instance. This forces the pfn info block to be invalidated if the namespace is re-configured with a different uuid. Signed-off-by: Dan Williams --- drivers/nvdimm/pfn_devs.c | 10 +++++++--- drivers/nvdimm/pmem.c | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c index 95ecd7b0fab3a..f9b674bc49db2 100644 --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c @@ -273,10 +273,11 @@ struct device *nd_pfn_create(struct nd_region *nd_region) int nd_pfn_validate(struct nd_pfn *nd_pfn) { - struct nd_namespace_common *ndns = nd_pfn->ndns; - struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; - struct nd_namespace_io *nsio; u64 checksum, offset; + struct nd_namespace_io *nsio; + struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; + struct nd_namespace_common *ndns = nd_pfn->ndns; + const u8 *parent_uuid = nd_dev_to_uuid(&ndns->dev); if (!pfn_sb || !ndns) return -ENODEV; @@ -296,6 +297,9 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn) return -ENODEV; pfn_sb->checksum = cpu_to_le64(checksum); + if (memcmp(pfn_sb->parent_uuid, parent_uuid, 16) != 0) + return -ENODEV; + switch (le32_to_cpu(pfn_sb->mode)) { case PFN_MODE_RAM: break; diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 5ba351e4f26a8..dc6866734f70f 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -270,6 +270,7 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) pfn_sb->npfns = cpu_to_le64(npfns); memcpy(pfn_sb->signature, PFN_SIG, PFN_SIG_LEN); memcpy(pfn_sb->uuid, nd_pfn->uuid, 16); + memcpy(pfn_sb->parent_uuid, nd_dev_to_uuid(&ndns->dev), 16); pfn_sb->version_major = cpu_to_le16(1); checksum = nd_sb_checksum((struct nd_gen_sb *) pfn_sb); pfn_sb->checksum = cpu_to_le64(checksum); -- GitLab From 2dc43331e34fa992a67f42ed44e5111cafafd6f3 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 13 Dec 2015 11:41:36 -0800 Subject: [PATCH 1098/2855] libnvdimm, pfn: fix pfn seed creation Similar to btt, plant a new pfn seed when the existing one is activated. Signed-off-by: Dan Williams --- drivers/nvdimm/namespace_devs.c | 12 ++++++++++++ drivers/nvdimm/nd-core.h | 1 + drivers/nvdimm/region_devs.c | 7 +++++++ 3 files changed, 20 insertions(+) diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index f981177524a19..ea8dd0cb28ca2 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -1707,6 +1707,18 @@ void nd_region_create_blk_seed(struct nd_region *nd_region) nd_device_register(nd_region->ns_seed); } +void nd_region_create_pfn_seed(struct nd_region *nd_region) +{ + WARN_ON(!is_nvdimm_bus_locked(&nd_region->dev)); + nd_region->pfn_seed = nd_pfn_create(nd_region); + /* + * Seed creation failures are not fatal, provisioning is simply + * disabled until memory becomes available + */ + if (!nd_region->pfn_seed) + dev_err(&nd_region->dev, "failed to create pfn namespace\n"); +} + void nd_region_create_btt_seed(struct nd_region *nd_region) { WARN_ON(!is_nvdimm_bus_locked(&nd_region->dev)); diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h index 159aed5320424..3249c498892a8 100644 --- a/drivers/nvdimm/nd-core.h +++ b/drivers/nvdimm/nd-core.h @@ -52,6 +52,7 @@ void nd_region_probe_success(struct nvdimm_bus *nvdimm_bus, struct device *dev); struct nd_region; void nd_region_create_blk_seed(struct nd_region *nd_region); void nd_region_create_btt_seed(struct nd_region *nd_region); +void nd_region_create_pfn_seed(struct nd_region *nd_region); void nd_region_disable(struct nvdimm_bus *nvdimm_bus, struct device *dev); int nvdimm_bus_create_ndctl(struct nvdimm_bus *nvdimm_bus); void nvdimm_bus_destroy_ndctl(struct nvdimm_bus *nvdimm_bus); diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index 3d730d1f25db5..9c632f73915e8 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c @@ -490,6 +490,13 @@ static void nd_region_notify_driver_action(struct nvdimm_bus *nvdimm_bus, nd_region_create_blk_seed(nd_region); nvdimm_bus_unlock(dev); } + if (is_nd_pfn(dev) && probe) { + nd_region = to_nd_region(dev->parent); + nvdimm_bus_lock(dev); + if (nd_region->pfn_seed == dev) + nd_region_create_pfn_seed(nd_region); + nvdimm_bus_unlock(dev); + } } void nd_region_probe_success(struct nvdimm_bus *nvdimm_bus, struct device *dev) -- GitLab From d58b9fda129d7f75358a36b71ec5cc685b4f993e Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Sun, 13 Dec 2015 09:42:55 +0000 Subject: [PATCH 1099/2855] spi: loopback: fix printk format issues with size_t Fixes the reported printk format issues reported by kbuild-test-robot. Signed-off-by: Martin Sperl Signed-off-by: Mark Brown --- drivers/spi/spi-loopback-test.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-loopback-test.c b/drivers/spi/spi-loopback-test.c index db207362e831f..4481ac7660295 100644 --- a/drivers/spi/spi-loopback-test.c +++ b/drivers/spi/spi-loopback-test.c @@ -345,7 +345,7 @@ static void spi_test_print_hex_dump(char *pre, const void *ptr, size_t len) DUMP_PREFIX_OFFSET, 16, 1, ptr, 512, 0); /* print tail */ - pr_info("%s truncated - continuing at offset %04x\n", + pr_info("%s truncated - continuing at offset %04zx\n", pre, len - 512); print_hex_dump(KERN_INFO, pre, DUMP_PREFIX_OFFSET, 16, 1, @@ -525,7 +525,7 @@ static int spi_test_check_loopback_result(struct spi_device *spi, mismatch_error: dev_err(&spi->dev, - "loopback strangeness - transfer missmatch on byte %04x - expected 0x%02x, but got 0x%02x\n", + "loopback strangeness - transfer missmatch on byte %04zx - expected 0x%02x, but got 0x%02x\n", i, txb, rxb); return -EINVAL; @@ -777,7 +777,7 @@ static int spi_test_run_iter(struct spi_device *spi, dev_info(&spi->dev, "Running test %s\n", test.description); } else { dev_info(&spi->dev, - " with iteration values: len = %i, tx_off = %i, rx_off = %i\n", + " with iteration values: len = %zu, tx_off = %zu, rx_off = %zu\n", len, tx_off, rx_off); } -- GitLab From fc8773e195350c61e61cc354b1535fb2c09a29f3 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Sun, 13 Dec 2015 09:45:01 +0000 Subject: [PATCH 1100/2855] spi: loopback: match configuration of test to description The test "two tx+rx transfers - alter second" actually modifies the first not the second transfer, which - in conjunction with testing the read data - results also in overwriting data read earlier. Signed-off-by: Martin Sperl Signed-off-by: Mark Brown --- drivers/spi/spi-loopback-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-loopback-test.c b/drivers/spi/spi-loopback-test.c index 4481ac7660295..7f497acc906ce 100644 --- a/drivers/spi/spi-loopback-test.c +++ b/drivers/spi/spi-loopback-test.c @@ -260,7 +260,7 @@ static struct spi_test spi_tests[] = { .fill_option = FILL_COUNT_8, .iterate_len = { ITERATE_MAX_LEN }, .iterate_tx_align = ITERATE_ALIGN, - .iterate_transfer_mask = BIT(0), + .iterate_transfer_mask = BIT(1), .transfers = { { .len = 1, -- GitLab From 739f3e92916b6076afbfc3b524ec120468478035 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Sun, 13 Dec 2015 09:46:25 +0000 Subject: [PATCH 1101/2855] spi: loopback: added additional non-power of 2 transfer lengthes Added additional transfer length to test that are not a power of 2. Signed-off-by: Martin Sperl Signed-off-by: Mark Brown --- drivers/spi/spi-test.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-test.h b/drivers/spi/spi-test.h index 7bfdbe24cf7e4..922c528332394 100644 --- a/drivers/spi/spi-test.h +++ b/drivers/spi/spi-test.h @@ -20,7 +20,7 @@ #define SPI_TEST_MAX_TRANSFERS 4 #define SPI_TEST_MAX_SIZE (32 * PAGE_SIZE) -#define SPI_TEST_MAX_ITERATE 16 +#define SPI_TEST_MAX_ITERATE 32 /* the "dummy" start addresses used in spi_test * these addresses get translated at a later stage @@ -127,9 +127,10 @@ int spi_test_run_tests(struct spi_device *spi, struct spi_test *tests); /* some of the default @spi_transfer.len to test */ -#define ITERATE_LEN 16, 32, 64, 128, 256, 1024, PAGE_SIZE, 65536 +#define ITERATE_LEN 2, 3, 7, 11, 16, 31, 32, 64, 97, 128, 251, 256, \ + 1021, 1024, 1031, 4093, PAGE_SIZE, 4099, 65536, 65537 -#define ITERATE_MAX_LEN ITERATE_LEN, SPI_TEST_MAX_SIZE +#define ITERATE_MAX_LEN ITERATE_LEN, SPI_TEST_MAX_SIZE - 1, SPI_TEST_MAX_SIZE /* the default alignment to test */ #define ITERATE_ALIGN sizeof(int) -- GitLab From 4d2ae601d80675af025e7a5bcbe918c58b6743aa Mon Sep 17 00:00:00 2001 From: Gavin Thomas Claugus Date: Tue, 1 Dec 2015 19:06:19 -0500 Subject: [PATCH 1102/2855] drivers: serial: jsm: Switch "jsm" to JSM_DRIVER_NAME This commit replaces every instance of the string "jsm" in the driver with JSM_DRIVER_NAME, as the two are equivalent. This should increase overall consistency. Signed-off-by: Gavin Thomas Claugus Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/jsm/jsm_driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c index efbd87a76656e..a119f11bf2f41 100644 --- a/drivers/tty/serial/jsm/jsm_driver.c +++ b/drivers/tty/serial/jsm/jsm_driver.c @@ -70,7 +70,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto out; } - rc = pci_request_regions(pdev, "jsm"); + rc = pci_request_regions(pdev, JSM_DRIVER_NAME); if (rc) { dev_err(&pdev->dev, "pci_request_region FAILED\n"); goto out_disable_device; @@ -328,7 +328,7 @@ static struct pci_device_id jsm_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, jsm_pci_tbl); static struct pci_driver jsm_driver = { - .name = "jsm", + .name = JSM_DRIVER_NAME, .id_table = jsm_pci_tbl, .probe = jsm_probe_one, .remove = jsm_remove_one, -- GitLab From 5f8b90431fc9613d4559a602a1070b2270ff4444 Mon Sep 17 00:00:00 2001 From: LABBE Corentin Date: Tue, 24 Nov 2015 15:36:57 +0100 Subject: [PATCH 1103/2855] serial: imx: fix a possible NULL dereference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit of_match_device could return NULL, and so cause a NULL pointer dereference later. Even if the probability of this case is very low, fixing it made static analyzers happy. Solving this with of_device_get_match_data made also code simplier. Signed-off-by: LABBE Corentin Acked-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 016e4be05cec3..76818f53f0ae6 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1857,11 +1857,10 @@ static int serial_imx_probe_dt(struct imx_port *sport, struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; - const struct of_device_id *of_id = - of_match_device(imx_uart_dt_ids, &pdev->dev); int ret; - if (!np) + sport->devdata = of_device_get_match_data(&pdev->dev); + if (!sport->devdata) /* no device tree device */ return 1; @@ -1878,8 +1877,6 @@ static int serial_imx_probe_dt(struct imx_port *sport, if (of_get_property(np, "fsl,dte-mode", NULL)) sport->dte_mode = 1; - sport->devdata = of_id->data; - return 0; } #else -- GitLab From 456ad4a138d306ed0137e3330d5e2ff5937c1bf9 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Mon, 19 Oct 2015 14:31:49 +0200 Subject: [PATCH 1104/2855] serial: sh-sci: Add device tree bindings for r8a7793 Also replaces "R-Car M2" with "R-Car M2-W" to avoid confusion. Signed-off-by: Ulrich Hecht Acked-by: Simon Horman Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- .../bindings/serial/renesas,sci-serial.txt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index 73f825e5e6448..ce23378064227 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -15,10 +15,14 @@ Required properties: - "renesas,scifa-r8a7790" for R8A7790 (R-Car H2) SCIFA compatible UART. - "renesas,scifb-r8a7790" for R8A7790 (R-Car H2) SCIFB compatible UART. - "renesas,hscif-r8a7790" for R8A7790 (R-Car H2) HSCIF compatible UART. - - "renesas,scif-r8a7791" for R8A7791 (R-Car M2) SCIF compatible UART. - - "renesas,scifa-r8a7791" for R8A7791 (R-Car M2) SCIFA compatible UART. - - "renesas,scifb-r8a7791" for R8A7791 (R-Car M2) SCIFB compatible UART. - - "renesas,hscif-r8a7791" for R8A7791 (R-Car M2) HSCIF compatible UART. + - "renesas,scif-r8a7791" for R8A7791 (R-Car M2-W) SCIF compatible UART. + - "renesas,scifa-r8a7791" for R8A7791 (R-Car M2-W) SCIFA compatible UART. + - "renesas,scifb-r8a7791" for R8A7791 (R-Car M2-W) SCIFB compatible UART. + - "renesas,hscif-r8a7791" for R8A7791 (R-Car M2-W) HSCIF compatible UART. + - "renesas,scif-r8a7793" for R8A7793 (R-Car M2-N) SCIF compatible UART. + - "renesas,scifa-r8a7793" for R8A7793 (R-Car M2-N) SCIFA compatible UART. + - "renesas,scifb-r8a7793" for R8A7793 (R-Car M2-N) SCIFB compatible UART. + - "renesas,hscif-r8a7793" for R8A7793 (R-Car M2-N) HSCIF compatible UART. - "renesas,scif-r8a7794" for R8A7794 (R-Car E2) SCIF compatible UART. - "renesas,scifa-r8a7794" for R8A7794 (R-Car E2) SCIFA compatible UART. - "renesas,scifb-r8a7794" for R8A7794 (R-Car E2) SCIFB compatible UART. -- GitLab From 18dfef9c7f87b75bbb0fb66a634f7c13a45b9f8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 18 Oct 2015 21:34:45 +0200 Subject: [PATCH 1105/2855] serial: atmel: convert to irq handling provided mctrl-gpio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tested-by: Nicolas Ferre Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 140 ++++-------------------------- 1 file changed, 18 insertions(+), 122 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 94294558943cb..002f7f25472c8 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -155,7 +155,6 @@ struct atmel_uart_port { struct circ_buf rx_ring; struct mctrl_gpios *gpios; - int gpio_irq[UART_GPIO_MAX]; unsigned int tx_done_mask; u32 fifo_size; u32 rts_high; @@ -550,27 +549,21 @@ static void atmel_enable_ms(struct uart_port *port) atmel_port->ms_irq_enabled = true; - if (atmel_port->gpio_irq[UART_GPIO_CTS] >= 0) - enable_irq(atmel_port->gpio_irq[UART_GPIO_CTS]); - else + if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_CTS)) ier |= ATMEL_US_CTSIC; - if (atmel_port->gpio_irq[UART_GPIO_DSR] >= 0) - enable_irq(atmel_port->gpio_irq[UART_GPIO_DSR]); - else + if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_DSR)) ier |= ATMEL_US_DSRIC; - if (atmel_port->gpio_irq[UART_GPIO_RI] >= 0) - enable_irq(atmel_port->gpio_irq[UART_GPIO_RI]); - else + if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_RI)) ier |= ATMEL_US_RIIC; - if (atmel_port->gpio_irq[UART_GPIO_DCD] >= 0) - enable_irq(atmel_port->gpio_irq[UART_GPIO_DCD]); - else + if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_DCD)) ier |= ATMEL_US_DCDIC; atmel_uart_writel(port, ATMEL_US_IER, ier); + + mctrl_gpio_enable_ms(atmel_port->gpios); } /* @@ -589,24 +582,18 @@ static void atmel_disable_ms(struct uart_port *port) atmel_port->ms_irq_enabled = false; - if (atmel_port->gpio_irq[UART_GPIO_CTS] >= 0) - disable_irq(atmel_port->gpio_irq[UART_GPIO_CTS]); - else + mctrl_gpio_disable_ms(atmel_port->gpios); + + if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_CTS)) idr |= ATMEL_US_CTSIC; - if (atmel_port->gpio_irq[UART_GPIO_DSR] >= 0) - disable_irq(atmel_port->gpio_irq[UART_GPIO_DSR]); - else + if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_DSR)) idr |= ATMEL_US_DSRIC; - if (atmel_port->gpio_irq[UART_GPIO_RI] >= 0) - disable_irq(atmel_port->gpio_irq[UART_GPIO_RI]); - else + if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_RI)) idr |= ATMEL_US_RIIC; - if (atmel_port->gpio_irq[UART_GPIO_DCD] >= 0) - disable_irq(atmel_port->gpio_irq[UART_GPIO_DCD]); - else + if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_DCD)) idr |= ATMEL_US_DCDIC; atmel_uart_writel(port, ATMEL_US_IDR, idr); @@ -1264,7 +1251,6 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id) struct uart_port *port = dev_id; struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); unsigned int status, pending, mask, pass_counter = 0; - bool gpio_handled = false; spin_lock(&atmel_port->lock_suspended); @@ -1272,24 +1258,6 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id) status = atmel_get_lines_status(port); mask = atmel_uart_readl(port, ATMEL_US_IMR); pending = status & mask; - if (!gpio_handled) { - /* - * Dealing with GPIO interrupt - */ - if (irq == atmel_port->gpio_irq[UART_GPIO_CTS]) - pending |= ATMEL_US_CTSIC; - - if (irq == atmel_port->gpio_irq[UART_GPIO_DSR]) - pending |= ATMEL_US_DSRIC; - - if (irq == atmel_port->gpio_irq[UART_GPIO_RI]) - pending |= ATMEL_US_RIIC; - - if (irq == atmel_port->gpio_irq[UART_GPIO_DCD]) - pending |= ATMEL_US_DCDIC; - - gpio_handled = true; - } if (!pending) break; @@ -1778,45 +1746,6 @@ static void atmel_get_ip_name(struct uart_port *port) } } -static void atmel_free_gpio_irq(struct uart_port *port) -{ - struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); - enum mctrl_gpio_idx i; - - for (i = 0; i < UART_GPIO_MAX; i++) - if (atmel_port->gpio_irq[i] >= 0) - free_irq(atmel_port->gpio_irq[i], port); -} - -static int atmel_request_gpio_irq(struct uart_port *port) -{ - struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); - int *irq = atmel_port->gpio_irq; - enum mctrl_gpio_idx i; - int err = 0; - - for (i = 0; (i < UART_GPIO_MAX) && !err; i++) { - if (irq[i] < 0) - continue; - - irq_set_status_flags(irq[i], IRQ_NOAUTOEN); - err = request_irq(irq[i], atmel_interrupt, IRQ_TYPE_EDGE_BOTH, - "atmel_serial", port); - if (err) - dev_err(port->dev, "atmel_startup - Can't get %d irq\n", - irq[i]); - } - - /* - * If something went wrong, rollback. - */ - while (err && (--i >= 0)) - if (irq[i] >= 0) - free_irq(irq[i], port); - - return err; -} - /* * Perform initialization and enable port for reception */ @@ -1846,13 +1775,6 @@ static int atmel_startup(struct uart_port *port) return retval; } - /* - * Get the GPIO lines IRQ - */ - retval = atmel_request_gpio_irq(port); - if (retval) - goto free_irq; - tasklet_enable(&atmel_port->tasklet); /* @@ -1948,11 +1870,6 @@ static int atmel_startup(struct uart_port *port) } return 0; - -free_irq: - free_irq(port->irq, port); - - return retval; } /* @@ -2018,7 +1935,6 @@ static void atmel_shutdown(struct uart_port *port) * Free the interrupts */ free_irq(port->irq, port); - atmel_free_gpio_irq(port); atmel_port->ms_irq_enabled = false; @@ -2686,26 +2602,6 @@ static int atmel_serial_resume(struct platform_device *pdev) #define atmel_serial_resume NULL #endif -static int atmel_init_gpios(struct atmel_uart_port *p, struct device *dev) -{ - enum mctrl_gpio_idx i; - struct gpio_desc *gpiod; - - p->gpios = mctrl_gpio_init_noauto(dev, 0); - if (IS_ERR(p->gpios)) - return PTR_ERR(p->gpios); - - for (i = 0; i < UART_GPIO_MAX; i++) { - gpiod = mctrl_gpio_to_gpiod(p->gpios, i); - if (gpiod && (gpiod_get_direction(gpiod) == GPIOF_DIR_IN)) - p->gpio_irq[i] = gpiod_to_irq(gpiod); - else - p->gpio_irq[i] = -EINVAL; - } - - return 0; -} - static void atmel_serial_probe_fifos(struct atmel_uart_port *port, struct platform_device *pdev) { @@ -2788,16 +2684,16 @@ static int atmel_serial_probe(struct platform_device *pdev) spin_lock_init(&port->lock_suspended); - ret = atmel_init_gpios(port, &pdev->dev); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to initialize GPIOs."); - goto err_clear_bit; - } - ret = atmel_init_port(port, pdev); if (ret) goto err_clear_bit; + port->gpios = mctrl_gpio_init(&port->uart, 0); + if (IS_ERR(port->gpios)) { + ret = PTR_ERR(port->gpios); + goto err_clear_bit; + } + if (!atmel_use_pdc_rx(&port->uart)) { ret = -ENOMEM; data = kmalloc(sizeof(struct atmel_uart_char) -- GitLab From 90ebc4838666d148eac5bbac6f4044e5b25cd2d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 18 Oct 2015 21:34:46 +0200 Subject: [PATCH 1106/2855] serial: imx: repair and complete handshaking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .get_mctrl callback should not report the status of RTS or LOOP, so drop this. Instead implement reporting the state of CAR (aka DCD) and RI. For .set_mctrl implement setting the DTR line. Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 76818f53f0ae6..086675e4ef73c 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -148,8 +148,11 @@ #define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */ #define USR2_DTRF (1<<13) /* DTR edge interrupt flag */ #define USR2_IDLE (1<<12) /* Idle condition */ +#define USR2_RIDELT (1<<10) /* Ring Interrupt Delta */ +#define USR2_RIIN (1<<9) /* Ring Indicator Input */ #define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */ #define USR2_WAKE (1<<7) /* Wake */ +#define USR2_DCDIN (1<<5) /* Data Carrier Detect Input */ #define USR2_RTSF (1<<4) /* RTS edge interrupt flag */ #define USR2_TXDC (1<<3) /* Transmitter complete */ #define USR2_BRCD (1<<2) /* Break condition */ @@ -804,16 +807,19 @@ static unsigned int imx_tx_empty(struct uart_port *port) static unsigned int imx_get_mctrl(struct uart_port *port) { struct imx_port *sport = (struct imx_port *)port; - unsigned int tmp = TIOCM_DSR | TIOCM_CAR; + unsigned int tmp = TIOCM_DSR; + unsigned usr1 = readl(sport->port.membase + USR1); - if (readl(sport->port.membase + USR1) & USR1_RTSS) + if (usr1 & USR1_RTSS) tmp |= TIOCM_CTS; - if (readl(sport->port.membase + UCR2) & UCR2_CTS) - tmp |= TIOCM_RTS; + /* in DCE mode DCDIN is always 0 */ + if (!(usr1 & USR2_DCDIN)) + tmp |= TIOCM_CAR; - if (readl(sport->port.membase + uts_reg(sport)) & UTS_LOOP) - tmp |= TIOCM_LOOP; + /* in DCE mode RIIN is always 0 */ + if (readl(sport->port.membase + USR2) & USR2_RIIN) + tmp |= TIOCM_RI; return tmp; } @@ -831,6 +837,11 @@ static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl) writel(temp, sport->port.membase + UCR2); } + temp = readl(sport->port.membase + UCR3) & ~UCR3_DSR; + if (!(mctrl & TIOCM_DTR)) + temp |= UCR3_DSR; + writel(temp, sport->port.membase + UCR3); + temp = readl(sport->port.membase + uts_reg(sport)) & ~UTS_LOOP; if (mctrl & TIOCM_LOOP) temp |= UTS_LOOP; -- GitLab From cc568849370bb131d896f4c5933cc72bf7ee603d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 18 Oct 2015 21:34:47 +0200 Subject: [PATCH 1107/2855] serial: imx: reorder functions and simplify a bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that imx_mctrl_check is implemented below imx_get_mctrl the former can call the latter directly instead of via sport->port.ops->get_mctrl. Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 90 ++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 086675e4ef73c..591f1c26e3e98 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -311,51 +311,6 @@ static void imx_port_ucrs_restore(struct uart_port *port, } #endif -/* - * Handle any change of modem status signal since we were last called. - */ -static void imx_mctrl_check(struct imx_port *sport) -{ - unsigned int status, changed; - - status = sport->port.ops->get_mctrl(&sport->port); - changed = status ^ sport->old_status; - - if (changed == 0) - return; - - sport->old_status = status; - - if (changed & TIOCM_RI) - sport->port.icount.rng++; - if (changed & TIOCM_DSR) - sport->port.icount.dsr++; - if (changed & TIOCM_CAR) - uart_handle_dcd_change(&sport->port, status & TIOCM_CAR); - if (changed & TIOCM_CTS) - uart_handle_cts_change(&sport->port, status & TIOCM_CTS); - - wake_up_interruptible(&sport->port.state->port.delta_msr_wait); -} - -/* - * This is our per-port timeout handler, for checking the - * modem status signals. - */ -static void imx_timeout(unsigned long data) -{ - struct imx_port *sport = (struct imx_port *)data; - unsigned long flags; - - if (sport->port.state) { - spin_lock_irqsave(&sport->port.lock, flags); - imx_mctrl_check(sport); - spin_unlock_irqrestore(&sport->port.lock, flags); - - mod_timer(&sport->timer, jiffies + MCTRL_TIMEOUT); - } -} - /* * interrupts disabled on entry */ @@ -868,6 +823,51 @@ static void imx_break_ctl(struct uart_port *port, int break_state) spin_unlock_irqrestore(&sport->port.lock, flags); } +/* + * Handle any change of modem status signal since we were last called. + */ +static void imx_mctrl_check(struct imx_port *sport) +{ + unsigned int status, changed; + + status = imx_get_mctrl(&sport->port); + changed = status ^ sport->old_status; + + if (changed == 0) + return; + + sport->old_status = status; + + if (changed & TIOCM_RI) + sport->port.icount.rng++; + if (changed & TIOCM_DSR) + sport->port.icount.dsr++; + if (changed & TIOCM_CAR) + uart_handle_dcd_change(&sport->port, status & TIOCM_CAR); + if (changed & TIOCM_CTS) + uart_handle_cts_change(&sport->port, status & TIOCM_CTS); + + wake_up_interruptible(&sport->port.state->port.delta_msr_wait); +} + +/* + * This is our per-port timeout handler, for checking the + * modem status signals. + */ +static void imx_timeout(unsigned long data) +{ + struct imx_port *sport = (struct imx_port *)data; + unsigned long flags; + + if (sport->port.state) { + spin_lock_irqsave(&sport->port.lock, flags); + imx_mctrl_check(sport); + spin_unlock_irqrestore(&sport->port.lock, flags); + + mod_timer(&sport->timer, jiffies + MCTRL_TIMEOUT); + } +} + #define RX_BUF_SIZE (PAGE_SIZE) static void imx_rx_dma_done(struct imx_port *sport) { -- GitLab From c39dfebc7798956fd2140ae6321786ff35da30c3 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 18 Oct 2015 18:21:16 -0400 Subject: [PATCH 1108/2855] drivers/tty/serial: make serial/atmel_serial.c explicitly non-modular The Kconfig currently controlling compilation of this code is: drivers/tty/serial/Kconfig:config SERIAL_ATMEL drivers/tty/serial/Kconfig: bool "AT91 / AT32 on-chip serial port support" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. We explicitly disallow a driver unbind, since that doesn't have a sensible use case anyway, and it allows us to drop the ".remove" code for non-modular drivers. Since module_init translates to device_initcall in the non-modular case, the init ordering remains unchanged with this commit. We don't replace module.h with init.h since the file already has that. We also delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. Cc: Nicolas Ferre Cc: Jiri Slaby Cc: linux-serial@vger.kernel.org Signed-off-by: Paul Gortmaker Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 45 +++---------------------------- 1 file changed, 4 insertions(+), 41 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 002f7f25472c8..50e785a0ea734 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -22,7 +22,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include #include #include #include @@ -2762,37 +2761,14 @@ err: return ret; } -static int atmel_serial_remove(struct platform_device *pdev) -{ - struct uart_port *port = platform_get_drvdata(pdev); - struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); - int ret = 0; - - tasklet_kill(&atmel_port->tasklet); - - device_init_wakeup(&pdev->dev, 0); - - ret = uart_remove_one_port(&atmel_uart, port); - - kfree(atmel_port->rx_ring.buf); - - /* "port" is allocated statically, so we shouldn't free it */ - - clear_bit(port->line, atmel_ports_in_use); - - clk_put(atmel_port->clk); - - return ret; -} - static struct platform_driver atmel_serial_driver = { .probe = atmel_serial_probe, - .remove = atmel_serial_remove, .suspend = atmel_serial_suspend, .resume = atmel_serial_resume, .driver = { - .name = "atmel_usart", - .of_match_table = of_match_ptr(atmel_serial_dt_ids), + .name = "atmel_usart", + .of_match_table = of_match_ptr(atmel_serial_dt_ids), + .suppress_bind_attrs = true, }, }; @@ -2810,17 +2786,4 @@ static int __init atmel_serial_init(void) return ret; } - -static void __exit atmel_serial_exit(void) -{ - platform_driver_unregister(&atmel_serial_driver); - uart_unregister_driver(&atmel_uart); -} - -module_init(atmel_serial_init); -module_exit(atmel_serial_exit); - -MODULE_AUTHOR("Rick Bronson"); -MODULE_DESCRIPTION("Atmel AT91 / AT32 serial port driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:atmel_usart"); +device_initcall(atmel_serial_init); -- GitLab From d72d391c126e0ffd3047c06c4bef4d795853d5d5 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 18 Oct 2015 18:21:18 -0400 Subject: [PATCH 1109/2855] drivers/tty/serial: make 8250/8250_mtk.c explicitly non-modular The Kconfig currently controlling compilation of this code is: drivers/tty/serial/8250/Kconfig:config SERIAL_8250_MT6577 drivers/tty/serial/8250/Kconfig: bool "Mediatek serial port support" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. We explicitly disallow a driver unbind, since that doesn't have a sensible use case anyway, and it allows us to drop the ".remove" code for non-modular drivers. Since module_platform_driver() uses the same init level priority as builtin_platform_driver() the init ordering remains unchanged with this commit. We also delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. Cc: Jiri Slaby Cc: Matthias Brugger Cc: linux-serial@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-mediatek@lists.infradead.org Signed-off-by: Paul Gortmaker Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_mtk.c | 35 ++++++------------------------ 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c index 78883ca64ddde..0e590b233f03b 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c @@ -16,7 +16,7 @@ */ #include #include -#include +#include #include #include #include @@ -245,23 +245,6 @@ static int mtk8250_probe(struct platform_device *pdev) return 0; } -static int mtk8250_remove(struct platform_device *pdev) -{ - struct mtk8250_data *data = platform_get_drvdata(pdev); - - pm_runtime_get_sync(&pdev->dev); - - serial8250_unregister_port(data->line); - - pm_runtime_disable(&pdev->dev); - pm_runtime_put_noidle(&pdev->dev); - - if (!pm_runtime_status_suspended(&pdev->dev)) - mtk8250_runtime_suspend(&pdev->dev); - - return 0; -} - #ifdef CONFIG_PM_SLEEP static int mtk8250_suspend(struct device *dev) { @@ -292,18 +275,18 @@ static const struct of_device_id mtk8250_of_match[] = { { .compatible = "mediatek,mt6577-uart" }, { /* Sentinel */ } }; -MODULE_DEVICE_TABLE(of, mtk8250_of_match); static struct platform_driver mtk8250_platform_driver = { .driver = { - .name = "mt6577-uart", - .pm = &mtk8250_pm_ops, - .of_match_table = mtk8250_of_match, + .name = "mt6577-uart", + .pm = &mtk8250_pm_ops, + .of_match_table = mtk8250_of_match, + .suppress_bind_attrs = true, + }, .probe = mtk8250_probe, - .remove = mtk8250_remove, }; -module_platform_driver(mtk8250_platform_driver); +builtin_platform_driver(mtk8250_platform_driver); #ifdef CONFIG_SERIAL_8250_CONSOLE static int __init early_mtk8250_setup(struct earlycon_device *device, @@ -319,7 +302,3 @@ static int __init early_mtk8250_setup(struct earlycon_device *device, OF_EARLYCON_DECLARE(mtk8250, "mediatek,mt6577-uart", early_mtk8250_setup); #endif - -MODULE_AUTHOR("Matthias Brugger"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Mediatek 8250 serial port driver"); -- GitLab From b8d20e06eaad4c2bd64746cacd95be9a5d3e747f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 30 Oct 2015 11:46:16 +0900 Subject: [PATCH 1110/2855] serial: 8250_uniphier: add earlycon support This reuses the code of drivers/tty/serial/8250/8250_early.c except - Overwrite device->port.iotype and device->port.regshift for UPIO_MEM32 because of_setup_earlycon() has set them for UPIO_MEM. - Set device->baud to zero to prevent early8250_setup() from initializing the divisor register because port->uartclk does not match the frequency expected by this hardware. Signed-off-by: Masahiro Yamada Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_uniphier.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/tty/serial/8250/8250_uniphier.c b/drivers/tty/serial/8250/8250_uniphier.c index d11621e2cf1df..1e2237a9c489b 100644 --- a/drivers/tty/serial/8250/8250_uniphier.c +++ b/drivers/tty/serial/8250/8250_uniphier.c @@ -13,6 +13,7 @@ */ #include +#include #include #include #include @@ -34,6 +35,29 @@ struct uniphier8250_priv { spinlock_t atomic_write_lock; }; +#ifdef CONFIG_SERIAL_8250_CONSOLE +static int __init uniphier_early_console_setup(struct earlycon_device *device, + const char *options) +{ + if (!device->port.membase) + return -ENODEV; + + /* This hardware always expects MMIO32 register interface. */ + device->port.iotype = UPIO_MEM32; + device->port.regshift = 2; + + /* + * Do not touch the divisor register in early_serial8250_setup(); + * we assume it has been initialized by a boot loader. + */ + device->baud = 0; + + return early_serial8250_setup(device, options); +} +OF_EARLYCON_DECLARE(uniphier, "socionext,uniphier-uart", + uniphier_early_console_setup); +#endif + /* * The register map is slightly different from that of 8250. * IO callbacks must be overridden for correct access to FCR, LCR, and MCR. -- GitLab From fbccaca9bd099e3b8bc6dfabb8dc6f57ad83d1a8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 23 Oct 2015 22:31:15 +0900 Subject: [PATCH 1111/2855] serial: 8250_ingenic: delete redundant "select SERIAL_EARLYCON" SERIAL_8250_INGENIC depends on SERIAL_8250_CONSOLE, which already selects SERIAL_EARLYCON. This line is redundant. Signed-off-by: Masahiro Yamada Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 6412f1455beb3..5d6808c226e99 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -363,7 +363,6 @@ config SERIAL_8250_INGENIC bool "Support for Ingenic SoC serial ports" depends on SERIAL_8250_CONSOLE && OF_FLATTREE select LIBFDT - select SERIAL_EARLYCON help If you have a system using an Ingenic SoC and wish to make use of its UARTs, say Y to this option. If unsure, say N. -- GitLab From 4828d5c30a2e1d300f7ca7c15868cead2ef7fb29 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 23 Oct 2015 22:31:16 +0900 Subject: [PATCH 1112/2855] serial: 8250_ingenic: allow to be independent of SERIAL_8250_CONSOLE This UART driver should not depend on the console. They should be orthogonal. Surround the earlycon code with CONFIG_SERIAL_EARLYCON conditional and rip off "depends on SERIAL_8250_CONSOLE". Signed-off-by: Masahiro Yamada Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_ingenic.c | 2 ++ drivers/tty/serial/8250/Kconfig | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c index 49394b4c5cfdc..d6e1ec9b4fdeb 100644 --- a/drivers/tty/serial/8250/8250_ingenic.c +++ b/drivers/tty/serial/8250/8250_ingenic.c @@ -48,6 +48,7 @@ static const struct of_device_id of_match[]; #define UART_MCR_MDCE BIT(7) #define UART_MCR_FCM BIT(6) +#ifdef CONFIG_SERIAL_EARLYCON static struct earlycon_device *early_device; static uint8_t __init early_in(struct uart_port *port, int offset) @@ -140,6 +141,7 @@ OF_EARLYCON_DECLARE(jz4775_uart, "ingenic,jz4775-uart", EARLYCON_DECLARE(jz4780_uart, ingenic_early_console_setup); OF_EARLYCON_DECLARE(jz4780_uart, "ingenic,jz4780-uart", ingenic_early_console_setup); +#endif /* CONFIG_SERIAL_EARLYCON */ static void ingenic_uart_serial_out(struct uart_port *p, int offset, int value) { diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 5d6808c226e99..25da430bb58b1 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -361,7 +361,7 @@ config SERIAL_8250_UNIPHIER config SERIAL_8250_INGENIC bool "Support for Ingenic SoC serial ports" - depends on SERIAL_8250_CONSOLE && OF_FLATTREE + depends on OF_FLATTREE select LIBFDT help If you have a system using an Ingenic SoC and wish to make use of -- GitLab From f88d86831b69be7d2ad1ac1ba80af386139e76af Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 17:39:55 +0100 Subject: [PATCH 1113/2855] cyclades: Deinline cyy_readb, save 368 bytes This function compiles to 32 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/cyclades.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index d4a1331675ed5..9600aa34e19e9 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c @@ -299,7 +299,7 @@ static inline void cyy_writeb(struct cyclades_port *port, u32 reg, u8 val) cy_writeb(port->u.cyy.base_addr + (reg << card->bus_index), val); } -static inline u8 cyy_readb(struct cyclades_port *port, u32 reg) +static u8 cyy_readb(struct cyclades_port *port, u32 reg) { struct cyclades_card *card = port->card; -- GitLab From f25d596fc2ef038ec91e1135ea7c7717bbd85f55 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 17:39:56 +0100 Subject: [PATCH 1114/2855] cyclades: Deinline cyy_writeb, save 880 bytes This function compiles to 35 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/cyclades.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index 9600aa34e19e9..da15d165557ab 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c @@ -292,7 +292,7 @@ static void cyz_rx_restart(unsigned long); static struct timer_list cyz_rx_full_timer[NR_PORTS]; #endif /* CONFIG_CYZ_INTR */ -static inline void cyy_writeb(struct cyclades_port *port, u32 reg, u8 val) +static void cyy_writeb(struct cyclades_port *port, u32 reg, u8 val) { struct cyclades_card *card = port->card; -- GitLab From 8c6ba003ee4dd43448b3986108f9d5299543b53f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 17:39:57 +0100 Subject: [PATCH 1115/2855] cyclades: Deinline serial_paranoia_check, save 304 bytes This function compiles to 52 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/cyclades.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index da15d165557ab..6ddf903906e29 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c @@ -329,7 +329,7 @@ static inline bool cyz_is_loaded(struct cyclades_card *card) readl(&fw_id->signature) == ZFIRM_ID; } -static inline int serial_paranoia_check(struct cyclades_port *info, +static int serial_paranoia_check(struct cyclades_port *info, const char *name, const char *routine) { #ifdef SERIAL_PARANOIA_CHECK -- GitLab From 810e20e705d76b6d3229b4417ab2ba1e178a92fa Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 17:39:58 +0100 Subject: [PATCH 1116/2855] isicom: Deinline WaitTillCardIsFree, save 1120 bytes This function compiles to 96 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/isicom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index 2054427992e0b..c7698fb127207 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c @@ -220,7 +220,7 @@ static struct isi_port isi_ports[PORT_COUNT]; * it wants to talk. */ -static inline int WaitTillCardIsFree(unsigned long base) +static int WaitTillCardIsFree(unsigned long base) { unsigned int count = 0; unsigned int a = in_atomic(); /* do we run under spinlock? */ -- GitLab From 1a5b34ebebf9be06b03a801cc12a676f2af42a9f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 17:39:59 +0100 Subject: [PATCH 1117/2855] serial/bcm63xx_uart: Deinline wait_for_xmitr, save 374 bytes This function compiles to 141 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/bcm63xx_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index a1c0a89d9c7f3..c28e5c24da160 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -653,7 +653,7 @@ static struct uart_ops bcm_uart_ops = { #ifdef CONFIG_SERIAL_BCM63XX_CONSOLE -static inline void wait_for_xmitr(struct uart_port *port) +static void wait_for_xmitr(struct uart_port *port) { unsigned int tmout; -- GitLab From 6d70f46ba0012d0cc4ade4d0eaad9db61b2e54bb Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 17:40:00 +0100 Subject: [PATCH 1118/2855] serial/jsm: Deinline neo_parse_isr, save 688 bytes This function compiles to 811 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/jsm/jsm_neo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/jsm/jsm_neo.c b/drivers/tty/serial/jsm/jsm_neo.c index 932b2accd06f7..c6fdd6369534c 100644 --- a/drivers/tty/serial/jsm/jsm_neo.c +++ b/drivers/tty/serial/jsm/jsm_neo.c @@ -714,7 +714,7 @@ static void neo_clear_break(struct jsm_channel *ch) /* * Parse the ISR register. */ -static inline void neo_parse_isr(struct jsm_board *brd, u32 port) +static void neo_parse_isr(struct jsm_board *brd, u32 port) { struct jsm_channel *ch; u8 isr; -- GitLab From f4581cab8ddd7270e6f342b163191e30e1398d74 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 17:40:01 +0100 Subject: [PATCH 1119/2855] serial_core: Deinline uart_update_mctrl, save 304 bytes This function compiles to 92 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index def5199ca004d..22cfc32717442 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -110,7 +110,7 @@ static void uart_start(struct tty_struct *tty) spin_unlock_irqrestore(&port->lock, flags); } -static inline void +static void uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear) { unsigned long flags; -- GitLab From cb128f69ca61b456126280bb9a969befe7cfdd7c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 17:40:02 +0100 Subject: [PATCH 1120/2855] tty/tty_ldisc: Deinline tty_ldisc_put, save 368 bytes This function compiles to 72 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 629e3c8650720..7d43ff12f6e20 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -185,7 +185,7 @@ static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc) * * Complement of tty_ldisc_get(). */ -static inline void tty_ldisc_put(struct tty_ldisc *ld) +static void tty_ldisc_put(struct tty_ldisc *ld) { if (WARN_ON_ONCE(!ld)) return; -- GitLab From 1c82363eef25420f41a49a53cda9f0f9e513bb38 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 18:46:33 +0100 Subject: [PATCH 1121/2855] cyclades: Deinline cyz_is_loaded, save 240 bytes This function compiles to 58 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/cyclades.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index 6ddf903906e29..abbed201dc744 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c @@ -321,7 +321,7 @@ static inline bool cyz_fpga_loaded(struct cyclades_card *card) return __cyz_fpga_loaded(card->ctl_addr.p9060); } -static inline bool cyz_is_loaded(struct cyclades_card *card) +static bool cyz_is_loaded(struct cyclades_card *card) { struct FIRM_ID __iomem *fw_id = card->base_addr + ID_ADDRESS; -- GitLab From 9428d712d1b42c48ab92e3466d58bf3ee5c9f58f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 18:46:34 +0100 Subject: [PATCH 1122/2855] isicom: Deinline drop_dtr, save 112 bytes This function compiles to 181 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/isicom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index c7698fb127207..99875949bfb77 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c @@ -280,7 +280,7 @@ static void raise_dtr(struct isi_port *port) } /* card->lock HAS to be held */ -static inline void drop_dtr(struct isi_port *port) +static void drop_dtr(struct isi_port *port) { struct isi_board *card = port->card; unsigned long base = card->base; -- GitLab From 9cdb933274662c4bf1a16146f4731782661b9831 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 18:46:37 +0100 Subject: [PATCH 1123/2855] serial/m32r_sio: Deinline wait_for_xmitr, save 165 bytes This function compiles to 141 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/m32r_sio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c index 8f7f83a14c93e..0eeb64f2499ca 100644 --- a/drivers/tty/serial/m32r_sio.c +++ b/drivers/tty/serial/m32r_sio.c @@ -990,7 +990,7 @@ static void __init m32r_sio_register_ports(struct uart_driver *drv) /* * Wait for transmitter & holding register to empty */ -static inline void wait_for_xmitr(struct uart_sio_port *up) +static void wait_for_xmitr(struct uart_sio_port *up) { unsigned int status, tmout = 10000; -- GitLab From fed76af0c7d005cb4b7d9b19d6d43137149b77ef Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 18:46:38 +0100 Subject: [PATCH 1124/2855] serial/men_z135_uart: Deinline men_z135_reg_clr, save 176 bytes This function compiles to 98 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Greg Kroah-Hartman CC: Peter Hurley CC: Jiri Slaby CC: linux-serial@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/men_z135_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/men_z135_uart.c b/drivers/tty/serial/men_z135_uart.c index 3141aa20843d7..a44290e9b5a8b 100644 --- a/drivers/tty/serial/men_z135_uart.c +++ b/drivers/tty/serial/men_z135_uart.c @@ -158,7 +158,7 @@ static inline void men_z135_reg_set(struct men_z135_port *uart, * @addr: Register address * @val: value to clear */ -static inline void men_z135_reg_clr(struct men_z135_port *uart, +static void men_z135_reg_clr(struct men_z135_port *uart, u32 addr, u32 val) { struct uart_port *port = &uart->port; -- GitLab From 2172076d2399660a1f49ee5a228ebcb56a2c3544 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 18:46:40 +0100 Subject: [PATCH 1125/2855] serial/omap-serial: Deinline wait_for_xmitr, save 165 bytes This function compiles to 141 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 9d4c84f7485f6..b645f9228ed77 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1165,7 +1165,7 @@ serial_omap_type(struct uart_port *port) #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) -static inline void wait_for_xmitr(struct uart_omap_port *up) +static void wait_for_xmitr(struct uart_omap_port *up) { unsigned int status, tmout = 10000; -- GitLab From be9ae5d9f7d771879dc93766e5cf8d923aed0e1e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 18:46:41 +0100 Subject: [PATCH 1126/2855] serial/pxa: Deinline wait_for_xmitr, save 165 bytes This function compiles to 141 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pxa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 9becba6548921..41eab75ba2af8 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -603,7 +603,7 @@ static struct uart_driver serial_pxa_reg; /* * Wait for transmitter & holding register to empty */ -static inline void wait_for_xmitr(struct uart_pxa_port *up) +static void wait_for_xmitr(struct uart_pxa_port *up) { unsigned int status, tmout = 10000; -- GitLab From 63744a690280d5b6981231072ba147c0c8b6da2e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 18:46:42 +0100 Subject: [PATCH 1127/2855] serial/sprd_serial: Deinline wait_for_xmitr, save 165 bytes This function compiles to 141 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sprd_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 9dbae01d41cef..ef26c4a60be42 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -517,7 +517,7 @@ static struct uart_ops serial_sprd_ops = { }; #ifdef CONFIG_SERIAL_SPRD_CONSOLE -static inline void wait_for_xmitr(struct uart_port *port) +static void wait_for_xmitr(struct uart_port *port) { unsigned int status, tmout = 10000; -- GitLab From 0d5547ca1bd7c7f55dab39c700e27ed33ff7eeef Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 18:46:43 +0100 Subject: [PATCH 1128/2855] serial/sunsu: Deinline wait_for_xmitr, save 165 bytes This function compiles to 141 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sunsu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index e124d2e88996f..9ad98eaa35bf8 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c @@ -1262,7 +1262,7 @@ static int sunsu_kbd_ms_init(struct uart_sunsu_port *up) /* * Wait for transmitter & holding register to empty */ -static __inline__ void wait_for_xmitr(struct uart_sunsu_port *up) +static void wait_for_xmitr(struct uart_sunsu_port *up) { unsigned int status, tmout = 10000; -- GitLab From eba3b47b26191385326406903120ca6f88300785 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 18:46:44 +0100 Subject: [PATCH 1129/2855] serial/vt8500_serial: Deinline wait_for_xmitr, save 165 bytes This function compiles to 141 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/vt8500_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index 4079ec56f5f90..b384060e3b1ff 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c @@ -485,7 +485,7 @@ static struct uart_driver vt8500_uart_driver; #ifdef CONFIG_SERIAL_VT8500_CONSOLE -static inline void wait_for_xmitr(struct uart_port *port) +static void wait_for_xmitr(struct uart_port *port) { unsigned int status, tmout = 10000; -- GitLab From fc0285f210500acad01dd8bd578dcd7f013db064 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 18:46:45 +0100 Subject: [PATCH 1130/2855] tty: Deinline __ldsem_down_read_nested, save 128 bytes This function compiles to 479 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldsem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/tty_ldsem.c b/drivers/tty/tty_ldsem.c index ad7eba5ca380f..f9010897d2ea5 100644 --- a/drivers/tty/tty_ldsem.c +++ b/drivers/tty/tty_ldsem.c @@ -319,7 +319,7 @@ down_write_failed(struct ld_semaphore *sem, long count, long timeout) -static inline int __ldsem_down_read_nested(struct ld_semaphore *sem, +static int __ldsem_down_read_nested(struct ld_semaphore *sem, int subclass, long timeout) { long count; -- GitLab From 5ef6504e9d0dcada48384b41d2cd77dba295bd36 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 18:46:46 +0100 Subject: [PATCH 1131/2855] tty: Deinline __ldsem_down_write_nested, save 128 bytes This function compiles to 491 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldsem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/tty_ldsem.c b/drivers/tty/tty_ldsem.c index f9010897d2ea5..1bf8ed13f8270 100644 --- a/drivers/tty/tty_ldsem.c +++ b/drivers/tty/tty_ldsem.c @@ -338,7 +338,7 @@ static int __ldsem_down_read_nested(struct ld_semaphore *sem, return 1; } -static inline int __ldsem_down_write_nested(struct ld_semaphore *sem, +static int __ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, long timeout) { long count; -- GitLab From c0f160a7355380e9b7f9c5cbb1a0f9eecf6ec601 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2015 18:46:47 +0100 Subject: [PATCH 1132/2855] vt: Deinline save_screen, save 238 bytes This function compiles to 79 bytes of machine code. Signed-off-by: Denys Vlasenko CC: Jiri Slaby CC: linux-serial@vger.kernel.org Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 4462d167900c5..e7cbc44eef575 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -634,7 +634,7 @@ static void set_origin(struct vc_data *vc) vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->vc_y + 2 * vc->vc_x; } -static inline void save_screen(struct vc_data *vc) +static void save_screen(struct vc_data *vc) { WARN_CONSOLE_UNLOCKED(); -- GitLab From 2cda227bba7e8398c6f8a7792c7f35818187dcc6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 30 Oct 2015 11:39:03 +0900 Subject: [PATCH 1133/2855] serial: 8250_early: do not save and restore IER in write callback The IER has already been masked in early_serial8250_setup(), there is no reason to save and restore it every time early_serial8250_write() is called. Signed-off-by: Masahiro Yamada Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_early.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index ceb85792a5cf2..5afc4d4403044 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c @@ -96,20 +96,11 @@ static void __init early_serial8250_write(struct console *console, { struct earlycon_device *device = console->data; struct uart_port *port = &device->port; - unsigned int ier; - - /* Save the IER and disable interrupts preserving the UUE bit */ - ier = serial8250_early_in(port, UART_IER); - if (ier) - serial8250_early_out(port, UART_IER, ier & UART_IER_UUE); uart_console_write(port, s, count, serial_putc); - /* Wait for transmitter to become empty and restore the IER */ + /* Wait for transmitter to become empty */ wait_for_xmitr(port); - - if (ier) - serial8250_early_out(port, UART_IER, ier); } static void __init init_port(struct earlycon_device *device) -- GitLab From f2bfdb0628d50339a70de475eb2be1c4c1eb9014 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 30 Oct 2015 11:39:04 +0900 Subject: [PATCH 1134/2855] serial: 8250_early: confirm empty transmitter after sending characters The current code waits until the transmitter becomes empty, before sending each character, and after finishing the whole string. This seems a bit redundant. It can be more efficient by checking the transmitter only after sending each character. This should be safe because the transmitter is already empty at the first entry of serial_putc(). Signed-off-by: Masahiro Yamada Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_early.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index 5afc4d4403044..20ec27bf13803 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c @@ -87,8 +87,8 @@ static void __init wait_for_xmitr(struct uart_port *port) static void __init serial_putc(struct uart_port *port, int c) { - wait_for_xmitr(port); serial8250_early_out(port, UART_TX, c); + wait_for_xmitr(port); } static void __init early_serial8250_write(struct console *console, @@ -98,9 +98,6 @@ static void __init early_serial8250_write(struct console *console, struct uart_port *port = &device->port; uart_console_write(port, s, count, serial_putc); - - /* Wait for transmitter to become empty */ - wait_for_xmitr(port); } static void __init init_port(struct earlycon_device *device) -- GitLab From 004e2ed5cc6d89201140ca96693bf9c0b2945f43 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 30 Oct 2015 11:39:05 +0900 Subject: [PATCH 1135/2855] serial: 8250_early: squash wait_for_xmitr() into serial_putc() Now, wait_for_xmitr() is only called from serial_putc(), and both are short enough. They can be merged into a single function. Signed-off-by: Masahiro Yamada Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_early.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index 20ec27bf13803..ca16195fb069f 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c @@ -73,24 +73,20 @@ static void __init serial8250_early_out(struct uart_port *port, int offset, int #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) -static void __init wait_for_xmitr(struct uart_port *port) +static void __init serial_putc(struct uart_port *port, int c) { unsigned int status; + serial8250_early_out(port, UART_TX, c); + for (;;) { status = serial8250_early_in(port, UART_LSR); if ((status & BOTH_EMPTY) == BOTH_EMPTY) - return; + break; cpu_relax(); } } -static void __init serial_putc(struct uart_port *port, int c) -{ - serial8250_early_out(port, UART_TX, c); - wait_for_xmitr(port); -} - static void __init early_serial8250_write(struct console *console, const char *s, unsigned int count) { -- GitLab From bd94c4077a0b2ecc35562c294f80f3659ecd8499 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 28 Oct 2015 12:46:05 +0900 Subject: [PATCH 1136/2855] serial: support 16-bit register interface for console Currently, 8-bit (MMIO) and 32-bit (MMIO32) register interfaces are supported for the 8250 console, but the 16-bit (MMIO16) is not. The 8250 UART device on my board is connected to a 16-bit bus and my main motivation is to use earlycon with it. (Refer to arch/arm/boot/dts/uniphier-support-card.dtsi) Signed-off-by: Masahiro Yamada Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- Documentation/kernel-parameters.txt | 9 +++++---- drivers/tty/serial/8250/8250_core.c | 7 ++++--- drivers/tty/serial/8250/8250_early.c | 5 +++++ drivers/tty/serial/8250/8250_port.c | 20 ++++++++++++++++++++ drivers/tty/serial/earlycon.c | 15 +++++++++++---- drivers/tty/serial/of_serial.c | 3 +++ drivers/tty/serial/serial_core.c | 9 +++++++-- include/linux/serial_core.h | 1 + include/uapi/linux/serial.h | 1 + 9 files changed, 57 insertions(+), 13 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 742f69d18fc89..054e11d33b6b0 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -721,16 +721,17 @@ bytes respectively. Such letter suffixes can also be entirely omitted. uart[8250],io,[,options] uart[8250],mmio,[,options] + uart[8250],mmio16,[,options] uart[8250],mmio32,[,options] uart[8250],0x[,options] Start an early, polled-mode console on the 8250/16550 UART at the specified I/O port or MMIO address, switching to the matching ttyS device later. MMIO inter-register address stride is either 8-bit - (mmio) or 32-bit (mmio32). - If none of [io|mmio|mmio32], is assumed to be - equivalent to 'mmio'. 'options' are specified in the - same format described for ttyS above; if unspecified, + (mmio), 16-bit (mmio16), or 32-bit (mmio32). + If none of [io|mmio|mmio16|mmio32], is assumed + to be equivalent to 'mmio'. 'options' are specified in + the same format described for ttyS above; if unspecified, the h/w is not re-initialized. hvc Use the hypervisor console device . This is for diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 39126460c1f59..c9720a97a9778 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -620,7 +620,7 @@ static int univ8250_console_setup(struct console *co, char *options) * @options: ptr to option string from console command line * * Only attempts to match console command lines of the form: - * console=uart[8250],io|mmio|mmio32,[,] + * console=uart[8250],io|mmio|mmio16|mmio32,[,] * console=uart[8250],0x[,] * This form is used to register an initial earlycon boot console and * replace it with the serial8250_console at 8250 driver init. @@ -650,8 +650,9 @@ static int univ8250_console_match(struct console *co, char *name, int idx, if (port->iotype != iotype) continue; - if ((iotype == UPIO_MEM || iotype == UPIO_MEM32) && - (port->mapbase != addr)) + if ((iotype == UPIO_MEM || iotype == UPIO_MEM16 || + iotype == UPIO_MEM32 || iotype == UPIO_MEM32BE) + && (port->mapbase != addr)) continue; if (iotype == UPIO_PORT && port->iobase != addr) continue; diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index ca16195fb069f..af62131af21ee 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c @@ -42,6 +42,8 @@ static unsigned int __init serial8250_early_in(struct uart_port *port, int offse switch (port->iotype) { case UPIO_MEM: return readb(port->membase + offset); + case UPIO_MEM16: + return readw(port->membase + (offset << 1)); case UPIO_MEM32: return readl(port->membase + (offset << 2)); case UPIO_MEM32BE: @@ -59,6 +61,9 @@ static void __init serial8250_early_out(struct uart_port *port, int offset, int case UPIO_MEM: writeb(value, port->membase + offset); break; + case UPIO_MEM16: + writew(value, port->membase + (offset << 1)); + break; case UPIO_MEM32: writel(value, port->membase + (offset << 2)); break; diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 52d82d2ac726b..8d262bce97e41 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -368,6 +368,18 @@ static void mem_serial_out(struct uart_port *p, int offset, int value) writeb(value, p->membase + offset); } +static void mem16_serial_out(struct uart_port *p, int offset, int value) +{ + offset = offset << p->regshift; + writew(value, p->membase + offset); +} + +static unsigned int mem16_serial_in(struct uart_port *p, int offset) +{ + offset = offset << p->regshift; + return readw(p->membase + offset); +} + static void mem32_serial_out(struct uart_port *p, int offset, int value) { offset = offset << p->regshift; @@ -425,6 +437,11 @@ static void set_io_from_upio(struct uart_port *p) p->serial_out = mem_serial_out; break; + case UPIO_MEM16: + p->serial_in = mem16_serial_in; + p->serial_out = mem16_serial_out; + break; + case UPIO_MEM32: p->serial_in = mem32_serial_in; p->serial_out = mem32_serial_out; @@ -459,6 +476,7 @@ serial_port_out_sync(struct uart_port *p, int offset, int value) { switch (p->iotype) { case UPIO_MEM: + case UPIO_MEM16: case UPIO_MEM32: case UPIO_MEM32BE: case UPIO_AU: @@ -2462,6 +2480,7 @@ static int serial8250_request_std_resource(struct uart_8250_port *up) case UPIO_TSI: case UPIO_MEM32: case UPIO_MEM32BE: + case UPIO_MEM16: case UPIO_MEM: if (!port->mapbase) break; @@ -2499,6 +2518,7 @@ static void serial8250_release_std_resource(struct uart_8250_port *up) case UPIO_TSI: case UPIO_MEM32: case UPIO_MEM32BE: + case UPIO_MEM16: case UPIO_MEM: if (!port->mapbase) break; diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c index f09636083426d..07f7393210dbb 100644 --- a/drivers/tty/serial/earlycon.c +++ b/drivers/tty/serial/earlycon.c @@ -71,10 +71,16 @@ static int __init parse_options(struct earlycon_device *device, char *options) return -EINVAL; switch (port->iotype) { + case UPIO_MEM: + port->mapbase = addr; + break; + case UPIO_MEM16: + port->regshift = 1; + port->mapbase = addr; + break; case UPIO_MEM32: case UPIO_MEM32BE: - port->regshift = 2; /* fall-through */ - case UPIO_MEM: + port->regshift = 2; port->mapbase = addr; break; case UPIO_PORT: @@ -91,10 +97,11 @@ static int __init parse_options(struct earlycon_device *device, char *options) strlcpy(device->options, options, length); } - if (port->iotype == UPIO_MEM || port->iotype == UPIO_MEM32 || - port->iotype == UPIO_MEM32BE) + if (port->iotype == UPIO_MEM || port->iotype == UPIO_MEM16 || + port->iotype == UPIO_MEM32 || port->iotype == UPIO_MEM32BE) pr_info("Early serial console at MMIO%s 0x%llx (options '%s')\n", (port->iotype == UPIO_MEM) ? "" : + (port->iotype == UPIO_MEM16) ? "16" : (port->iotype == UPIO_MEM32) ? "32" : "32be", (unsigned long long)port->mapbase, device->options); diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index de50296497955..6d002eeb25161 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -122,6 +122,9 @@ static int of_platform_serial_setup(struct platform_device *ofdev, case 1: port->iotype = UPIO_MEM; break; + case 2: + port->iotype = UPIO_MEM16; + break; case 4: port->iotype = of_device_is_big_endian(np) ? UPIO_MEM32BE : UPIO_MEM32; diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 22cfc32717442..b1f54ab1818c4 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1818,8 +1818,8 @@ uart_get_console(struct uart_port *ports, int nr, struct console *co) * @options: ptr for field; NULL if not present (out) * * Decodes earlycon kernel command line parameters of the form - * earlycon=,io|mmio|mmio32|mmio32be|mmio32native,, - * console=,io|mmio|mmio32|mmio32be|mmio32native,, + * earlycon=,io|mmio|mmio16|mmio32|mmio32be|mmio32native,, + * console=,io|mmio|mmio16|mmio32|mmio32be|mmio32native,, * * The optional form * earlycon=,0x, @@ -1834,6 +1834,9 @@ int uart_parse_earlycon(char *p, unsigned char *iotype, unsigned long *addr, if (strncmp(p, "mmio,", 5) == 0) { *iotype = UPIO_MEM; p += 5; + } else if (strncmp(p, "mmio16,", 7) == 0) { + *iotype = UPIO_MEM16; + p += 7; } else if (strncmp(p, "mmio32,", 7) == 0) { *iotype = UPIO_MEM32; p += 7; @@ -2186,6 +2189,7 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) "I/O 0x%lx offset 0x%x", port->iobase, port->hub6); break; case UPIO_MEM: + case UPIO_MEM16: case UPIO_MEM32: case UPIO_MEM32BE: case UPIO_AU: @@ -2831,6 +2835,7 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2) return (port1->iobase == port2->iobase) && (port1->hub6 == port2->hub6); case UPIO_MEM: + case UPIO_MEM16: case UPIO_MEM32: case UPIO_MEM32BE: case UPIO_AU: diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 297d4fa1cfe51..35aa87b96b711 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -150,6 +150,7 @@ struct uart_port { #define UPIO_AU (SERIAL_IO_AU) /* Au1x00 and RT288x type IO */ #define UPIO_TSI (SERIAL_IO_TSI) /* Tsi108/109 type IO */ #define UPIO_MEM32BE (SERIAL_IO_MEM32BE) /* 32b big endian */ +#define UPIO_MEM16 (SERIAL_IO_MEM16) /* 16b little endian */ unsigned int read_status_mask; /* driver specific */ unsigned int ignore_status_mask; /* driver specific */ diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h index 25331f9faa768..5d59c3ebf4596 100644 --- a/include/uapi/linux/serial.h +++ b/include/uapi/linux/serial.h @@ -69,6 +69,7 @@ struct serial_struct { #define SERIAL_IO_AU 4 #define SERIAL_IO_TSI 5 #define SERIAL_IO_MEM32BE 6 +#define SERIAL_IO_MEM16 7 #define UART_CLEAR_FIFO 0x01 #define UART_USE_FIFO 0x02 -- GitLab From 7583633921d54f33e96b65569a0c980ae1d05dba Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 3 Nov 2015 14:50:58 +0000 Subject: [PATCH 1137/2855] tty: amba-pl011: add register accessor functions Add register accessor functions to amba-pl011. Much of this transformation was done using the sed expression below, with any left-overs fixed up manually afterwards, and code formatted to remain within coding style. s/readw(\(uap->port.membase\|regs\|port->membase\) +/pl011_read(\1,/g s/writew(\(.*\) +/pl011_write(\1,/g Signed-off-by: Russell King Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 210 +++++++++++++++++--------------- 1 file changed, 112 insertions(+), 98 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 899a77187bdea..bd01e75128dc6 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -184,6 +184,16 @@ struct uart_amba_port { #endif }; +static unsigned int pl011_read(void __iomem *base, unsigned int reg) +{ + return readw(base + reg); +} + +static void pl011_write(unsigned int val, void __iomem *base, unsigned int reg) +{ + writew(val, base + reg); +} + /* * Reads up to 256 characters from the FIFO or until it's empty and * inserts them into the TTY layer. Returns the number of characters @@ -196,12 +206,12 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap) int fifotaken = 0; while (max_count--) { - status = readw(uap->port.membase + UART01x_FR); + status = pl011_read(uap->port.membase, UART01x_FR); if (status & UART01x_FR_RXFE) break; /* Take chars from the FIFO and update status */ - ch = readw(uap->port.membase + UART01x_DR) | + ch = pl011_read(uap->port.membase, UART01x_DR) | UART_DUMMY_DR_RX; flag = TTY_NORMAL; uap->port.icount.rx++; @@ -438,7 +448,7 @@ static void pl011_dma_tx_callback(void *data) dmacr = uap->dmacr; uap->dmacr = dmacr & ~UART011_TXDMAE; - writew(uap->dmacr, uap->port.membase + UART011_DMACR); + pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); /* * If TX DMA was disabled, it means that we've stopped the DMA for @@ -552,7 +562,7 @@ static int pl011_dma_tx_refill(struct uart_amba_port *uap) dma_dev->device_issue_pending(chan); uap->dmacr |= UART011_TXDMAE; - writew(uap->dmacr, uap->port.membase + UART011_DMACR); + pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); uap->dmatx.queued = true; /* @@ -588,9 +598,9 @@ static bool pl011_dma_tx_irq(struct uart_amba_port *uap) */ if (uap->dmatx.queued) { uap->dmacr |= UART011_TXDMAE; - writew(uap->dmacr, uap->port.membase + UART011_DMACR); + pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); uap->im &= ~UART011_TXIM; - writew(uap->im, uap->port.membase + UART011_IMSC); + pl011_write(uap->im, uap->port.membase, UART011_IMSC); return true; } @@ -600,7 +610,7 @@ static bool pl011_dma_tx_irq(struct uart_amba_port *uap) */ if (pl011_dma_tx_refill(uap) > 0) { uap->im &= ~UART011_TXIM; - writew(uap->im, uap->port.membase + UART011_IMSC); + pl011_write(uap->im, uap->port.membase, UART011_IMSC); return true; } return false; @@ -614,7 +624,7 @@ static inline void pl011_dma_tx_stop(struct uart_amba_port *uap) { if (uap->dmatx.queued) { uap->dmacr &= ~UART011_TXDMAE; - writew(uap->dmacr, uap->port.membase + UART011_DMACR); + pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); } } @@ -640,14 +650,14 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap) if (!uap->dmatx.queued) { if (pl011_dma_tx_refill(uap) > 0) { uap->im &= ~UART011_TXIM; - writew(uap->im, uap->port.membase + - UART011_IMSC); + pl011_write(uap->im, uap->port.membase, + UART011_IMSC); } else ret = false; } else if (!(uap->dmacr & UART011_TXDMAE)) { uap->dmacr |= UART011_TXDMAE; - writew(uap->dmacr, - uap->port.membase + UART011_DMACR); + pl011_write(uap->dmacr, uap->port.membase, + UART011_DMACR); } return ret; } @@ -658,9 +668,9 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap) */ dmacr = uap->dmacr; uap->dmacr &= ~UART011_TXDMAE; - writew(uap->dmacr, uap->port.membase + UART011_DMACR); + pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); - if (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) { + if (pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_TXFF) { /* * No space in the FIFO, so enable the transmit interrupt * so we know when there is space. Note that once we've @@ -669,13 +679,13 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap) return false; } - writew(uap->port.x_char, uap->port.membase + UART01x_DR); + pl011_write(uap->port.x_char, uap->port.membase, UART01x_DR); uap->port.icount.tx++; uap->port.x_char = 0; /* Success - restore the DMA state */ uap->dmacr = dmacr; - writew(dmacr, uap->port.membase + UART011_DMACR); + pl011_write(dmacr, uap->port.membase, UART011_DMACR); return true; } @@ -703,7 +713,7 @@ __acquires(&uap->port.lock) DMA_TO_DEVICE); uap->dmatx.queued = false; uap->dmacr &= ~UART011_TXDMAE; - writew(uap->dmacr, uap->port.membase + UART011_DMACR); + pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); } } @@ -743,11 +753,11 @@ static int pl011_dma_rx_trigger_dma(struct uart_amba_port *uap) dma_async_issue_pending(rxchan); uap->dmacr |= UART011_RXDMAE; - writew(uap->dmacr, uap->port.membase + UART011_DMACR); + pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); uap->dmarx.running = true; uap->im &= ~UART011_RXIM; - writew(uap->im, uap->port.membase + UART011_IMSC); + pl011_write(uap->im, uap->port.membase, UART011_IMSC); return 0; } @@ -805,8 +815,8 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, */ if (dma_count == pending && readfifo) { /* Clear any error flags */ - writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS, - uap->port.membase + UART011_ICR); + pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS | + UART011_FEIS, uap->port.membase, UART011_ICR); /* * If we read all the DMA'd characters, and we had an @@ -854,7 +864,7 @@ static void pl011_dma_rx_irq(struct uart_amba_port *uap) /* Disable RX DMA - incoming data will wait in the FIFO */ uap->dmacr &= ~UART011_RXDMAE; - writew(uap->dmacr, uap->port.membase + UART011_DMACR); + pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); uap->dmarx.running = false; pending = sgbuf->sg.length - state.residue; @@ -874,7 +884,7 @@ static void pl011_dma_rx_irq(struct uart_amba_port *uap) dev_dbg(uap->port.dev, "could not retrigger RX DMA job " "fall back to interrupt mode\n"); uap->im |= UART011_RXIM; - writew(uap->im, uap->port.membase + UART011_IMSC); + pl011_write(uap->im, uap->port.membase, UART011_IMSC); } } @@ -922,7 +932,7 @@ static void pl011_dma_rx_callback(void *data) dev_dbg(uap->port.dev, "could not retrigger RX DMA job " "fall back to interrupt mode\n"); uap->im |= UART011_RXIM; - writew(uap->im, uap->port.membase + UART011_IMSC); + pl011_write(uap->im, uap->port.membase, UART011_IMSC); } } @@ -935,7 +945,7 @@ static inline void pl011_dma_rx_stop(struct uart_amba_port *uap) { /* FIXME. Just disable the DMA enable */ uap->dmacr &= ~UART011_RXDMAE; - writew(uap->dmacr, uap->port.membase + UART011_DMACR); + pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); } /* @@ -979,7 +989,7 @@ static void pl011_dma_rx_poll(unsigned long args) spin_lock_irqsave(&uap->port.lock, flags); pl011_dma_rx_stop(uap); uap->im |= UART011_RXIM; - writew(uap->im, uap->port.membase + UART011_IMSC); + pl011_write(uap->im, uap->port.membase, UART011_IMSC); spin_unlock_irqrestore(&uap->port.lock, flags); uap->dmarx.running = false; @@ -1041,7 +1051,7 @@ static void pl011_dma_startup(struct uart_amba_port *uap) skip_rx: /* Turn on DMA error (RX/TX will be enabled on demand) */ uap->dmacr |= UART011_DMAONERR; - writew(uap->dmacr, uap->port.membase + UART011_DMACR); + pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); /* * ST Micro variants has some specific dma burst threshold @@ -1049,8 +1059,8 @@ skip_rx: * be issued above/below 16 bytes. */ if (uap->vendor->dma_threshold) - writew(ST_UART011_DMAWM_RX_16 | ST_UART011_DMAWM_TX_16, - uap->port.membase + ST_UART011_DMAWM); + pl011_write(ST_UART011_DMAWM_RX_16 | ST_UART011_DMAWM_TX_16, + uap->port.membase, ST_UART011_DMAWM); if (uap->using_rx_dma) { if (pl011_dma_rx_trigger_dma(uap)) @@ -1075,12 +1085,12 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap) return; /* Disable RX and TX DMA */ - while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY) + while (pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_BUSY) barrier(); spin_lock_irq(&uap->port.lock); uap->dmacr &= ~(UART011_DMAONERR | UART011_RXDMAE | UART011_TXDMAE); - writew(uap->dmacr, uap->port.membase + UART011_DMACR); + pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); spin_unlock_irq(&uap->port.lock); if (uap->using_tx_dma) { @@ -1181,7 +1191,7 @@ static void pl011_stop_tx(struct uart_port *port) container_of(port, struct uart_amba_port, port); uap->im &= ~UART011_TXIM; - writew(uap->im, uap->port.membase + UART011_IMSC); + pl011_write(uap->im, uap->port.membase, UART011_IMSC); pl011_dma_tx_stop(uap); } @@ -1191,7 +1201,7 @@ static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq); static void pl011_start_tx_pio(struct uart_amba_port *uap) { uap->im |= UART011_TXIM; - writew(uap->im, uap->port.membase + UART011_IMSC); + pl011_write(uap->im, uap->port.membase, UART011_IMSC); pl011_tx_chars(uap, false); } @@ -1211,7 +1221,7 @@ static void pl011_stop_rx(struct uart_port *port) uap->im &= ~(UART011_RXIM|UART011_RTIM|UART011_FEIM| UART011_PEIM|UART011_BEIM|UART011_OEIM); - writew(uap->im, uap->port.membase + UART011_IMSC); + pl011_write(uap->im, uap->port.membase, UART011_IMSC); pl011_dma_rx_stop(uap); } @@ -1222,7 +1232,7 @@ static void pl011_enable_ms(struct uart_port *port) container_of(port, struct uart_amba_port, port); uap->im |= UART011_RIMIM|UART011_CTSMIM|UART011_DCDMIM|UART011_DSRMIM; - writew(uap->im, uap->port.membase + UART011_IMSC); + pl011_write(uap->im, uap->port.membase, UART011_IMSC); } static void pl011_rx_chars(struct uart_amba_port *uap) @@ -1242,7 +1252,7 @@ __acquires(&uap->port.lock) dev_dbg(uap->port.dev, "could not trigger RX DMA job " "fall back to interrupt mode again\n"); uap->im |= UART011_RXIM; - writew(uap->im, uap->port.membase + UART011_IMSC); + pl011_write(uap->im, uap->port.membase, UART011_IMSC); } else { #ifdef CONFIG_DMA_ENGINE /* Start Rx DMA poll */ @@ -1263,10 +1273,10 @@ static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c, bool from_irq) { if (unlikely(!from_irq) && - readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) + pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_TXFF) return false; /* unable to transmit character */ - writew(c, uap->port.membase + UART01x_DR); + pl011_write(c, uap->port.membase, UART01x_DR); uap->port.icount.tx++; return true; @@ -1313,7 +1323,8 @@ static void pl011_modem_status(struct uart_amba_port *uap) { unsigned int status, delta; - status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; + status = pl011_read(uap->port.membase, UART01x_FR); + status &= UART01x_FR_MODEM_ANY; delta = status ^ uap->old_status; uap->old_status = status; @@ -1341,15 +1352,15 @@ static void check_apply_cts_event_workaround(struct uart_amba_port *uap) return; /* workaround to make sure that all bits are unlocked.. */ - writew(0x00, uap->port.membase + UART011_ICR); + pl011_write(0x00, uap->port.membase, UART011_ICR); /* * WA: introduce 26ns(1 uart clk) delay before W1C; * single apb access will incur 2 pclk(133.12Mhz) delay, * so add 2 dummy reads */ - dummy_read = readw(uap->port.membase + UART011_ICR); - dummy_read = readw(uap->port.membase + UART011_ICR); + dummy_read = pl011_read(uap->port.membase, UART011_ICR); + dummy_read = pl011_read(uap->port.membase, UART011_ICR); } static irqreturn_t pl011_int(int irq, void *dev_id) @@ -1361,15 +1372,15 @@ static irqreturn_t pl011_int(int irq, void *dev_id) int handled = 0; spin_lock_irqsave(&uap->port.lock, flags); - imsc = readw(uap->port.membase + UART011_IMSC); - status = readw(uap->port.membase + UART011_RIS) & imsc; + imsc = pl011_read(uap->port.membase, UART011_IMSC); + status = pl011_read(uap->port.membase, UART011_RIS) & imsc; if (status) { do { check_apply_cts_event_workaround(uap); - writew(status & ~(UART011_TXIS|UART011_RTIS| - UART011_RXIS), - uap->port.membase + UART011_ICR); + pl011_write(status & ~(UART011_TXIS|UART011_RTIS| + UART011_RXIS), + uap->port.membase, UART011_ICR); if (status & (UART011_RTIS|UART011_RXIS)) { if (pl011_dma_rx_running(uap)) @@ -1386,7 +1397,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id) if (pass_counter-- == 0) break; - status = readw(uap->port.membase + UART011_RIS) & imsc; + status = pl011_read(uap->port.membase, UART011_RIS) & imsc; } while (status != 0); handled = 1; } @@ -1400,7 +1411,7 @@ static unsigned int pl011_tx_empty(struct uart_port *port) { struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); - unsigned int status = readw(uap->port.membase + UART01x_FR); + unsigned int status = pl011_read(uap->port.membase, UART01x_FR); return status & (UART01x_FR_BUSY|UART01x_FR_TXFF) ? 0 : TIOCSER_TEMT; } @@ -1409,7 +1420,7 @@ static unsigned int pl011_get_mctrl(struct uart_port *port) struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); unsigned int result = 0; - unsigned int status = readw(uap->port.membase + UART01x_FR); + unsigned int status = pl011_read(uap->port.membase, UART01x_FR); #define TIOCMBIT(uartbit, tiocmbit) \ if (status & uartbit) \ @@ -1429,7 +1440,7 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) container_of(port, struct uart_amba_port, port); unsigned int cr; - cr = readw(uap->port.membase + UART011_CR); + cr = pl011_read(uap->port.membase, UART011_CR); #define TIOCMBIT(tiocmbit, uartbit) \ if (mctrl & tiocmbit) \ @@ -1449,7 +1460,7 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) } #undef TIOCMBIT - writew(cr, uap->port.membase + UART011_CR); + pl011_write(cr, uap->port.membase, UART011_CR); } static void pl011_break_ctl(struct uart_port *port, int break_state) @@ -1460,12 +1471,12 @@ static void pl011_break_ctl(struct uart_port *port, int break_state) unsigned int lcr_h; spin_lock_irqsave(&uap->port.lock, flags); - lcr_h = readw(uap->port.membase + uap->lcrh_tx); + lcr_h = pl011_read(uap->port.membase, uap->lcrh_tx); if (break_state == -1) lcr_h |= UART01x_LCRH_BRK; else lcr_h &= ~UART01x_LCRH_BRK; - writew(lcr_h, uap->port.membase + uap->lcrh_tx); + pl011_write(lcr_h, uap->port.membase, uap->lcrh_tx); spin_unlock_irqrestore(&uap->port.lock, flags); } @@ -1477,7 +1488,7 @@ static void pl011_quiesce_irqs(struct uart_port *port) container_of(port, struct uart_amba_port, port); unsigned char __iomem *regs = uap->port.membase; - writew(readw(regs + UART011_MIS), regs + UART011_ICR); + pl011_write(pl011_read(regs, UART011_MIS), regs, UART011_ICR); /* * There is no way to clear TXIM as this is "ready to transmit IRQ", so * we simply mask it. start_tx() will unmask it. @@ -1491,7 +1502,8 @@ static void pl011_quiesce_irqs(struct uart_port *port) * (including tx queue), so we're also fine with start_tx()'s caller * side. */ - writew(readw(regs + UART011_IMSC) & ~UART011_TXIM, regs + UART011_IMSC); + pl011_write(pl011_read(regs, UART011_IMSC) & ~UART011_TXIM, + regs, UART011_IMSC); } static int pl011_get_poll_char(struct uart_port *port) @@ -1506,11 +1518,11 @@ static int pl011_get_poll_char(struct uart_port *port) */ pl011_quiesce_irqs(port); - status = readw(uap->port.membase + UART01x_FR); + status = pl011_read(uap->port.membase, UART01x_FR); if (status & UART01x_FR_RXFE) return NO_POLL_CHAR; - return readw(uap->port.membase + UART01x_DR); + return pl011_read(uap->port.membase, UART01x_DR); } static void pl011_put_poll_char(struct uart_port *port, @@ -1519,10 +1531,10 @@ static void pl011_put_poll_char(struct uart_port *port, struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); - while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) + while (pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_TXFF) barrier(); - writew(ch, uap->port.membase + UART01x_DR); + pl011_write(ch, uap->port.membase, UART01x_DR); } #endif /* CONFIG_CONSOLE_POLL */ @@ -1546,15 +1558,17 @@ static int pl011_hwinit(struct uart_port *port) uap->port.uartclk = clk_get_rate(uap->clk); /* Clear pending error and receive interrupts */ - writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS | - UART011_RTIS | UART011_RXIS, uap->port.membase + UART011_ICR); + pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS | + UART011_FEIS | UART011_RTIS | UART011_RXIS, + uap->port.membase, UART011_ICR); /* * Save interrupts enable mask, and enable RX interrupts in case if * the interrupt is used for NMI entry. */ - uap->im = readw(uap->port.membase + UART011_IMSC); - writew(UART011_RTIM | UART011_RXIM, uap->port.membase + UART011_IMSC); + uap->im = pl011_read(uap->port.membase, UART011_IMSC); + pl011_write(UART011_RTIM | UART011_RXIM, uap->port.membase, + UART011_IMSC); if (dev_get_platdata(uap->port.dev)) { struct amba_pl011_data *plat; @@ -1568,7 +1582,7 @@ static int pl011_hwinit(struct uart_port *port) static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h) { - writew(lcr_h, uap->port.membase + uap->lcrh_rx); + pl011_write(lcr_h, uap->port.membase, uap->lcrh_rx); if (uap->lcrh_rx != uap->lcrh_tx) { int i; /* @@ -1576,14 +1590,14 @@ static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h) * to get this delay write read only register 10 times */ for (i = 0; i < 10; ++i) - writew(0xff, uap->port.membase + UART011_MIS); - writew(lcr_h, uap->port.membase + uap->lcrh_tx); + pl011_write(0xff, uap->port.membase, UART011_MIS); + pl011_write(lcr_h, uap->port.membase, uap->lcrh_tx); } } static int pl011_allocate_irq(struct uart_amba_port *uap) { - writew(uap->im, uap->port.membase + UART011_IMSC); + pl011_write(uap->im, uap->port.membase, UART011_IMSC); return request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap); } @@ -1598,12 +1612,12 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap) spin_lock_irq(&uap->port.lock); /* Clear out any spuriously appearing RX interrupts */ - writew(UART011_RTIS | UART011_RXIS, - uap->port.membase + UART011_ICR); + pl011_write(UART011_RTIS | UART011_RXIS, uap->port.membase, + UART011_ICR); uap->im = UART011_RTIM; if (!pl011_dma_rx_running(uap)) uap->im |= UART011_RXIM; - writew(uap->im, uap->port.membase + UART011_IMSC); + pl011_write(uap->im, uap->port.membase, UART011_IMSC); spin_unlock_irq(&uap->port.lock); } @@ -1622,21 +1636,21 @@ static int pl011_startup(struct uart_port *port) if (retval) goto clk_dis; - writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS); + pl011_write(uap->vendor->ifls, uap->port.membase, UART011_IFLS); spin_lock_irq(&uap->port.lock); /* restore RTS and DTR */ cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR); cr |= UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; - writew(cr, uap->port.membase + UART011_CR); + pl011_write(cr, uap->port.membase, UART011_CR); spin_unlock_irq(&uap->port.lock); /* * initialise the old status of the modem signals */ - uap->old_status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; + uap->old_status = pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_MODEM_ANY; /* Startup DMA */ pl011_dma_startup(uap); @@ -1677,9 +1691,9 @@ static void pl011_shutdown_channel(struct uart_amba_port *uap, { unsigned long val; - val = readw(uap->port.membase + lcrh); + val = pl011_read(uap->port.membase, lcrh); val &= ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN); - writew(val, uap->port.membase + lcrh); + pl011_write(val, uap->port.membase, lcrh); } /* @@ -1693,11 +1707,11 @@ static void pl011_disable_uart(struct uart_amba_port *uap) uap->autorts = false; spin_lock_irq(&uap->port.lock); - cr = readw(uap->port.membase + UART011_CR); + cr = pl011_read(uap->port.membase, UART011_CR); uap->old_cr = cr; cr &= UART011_CR_RTS | UART011_CR_DTR; cr |= UART01x_CR_UARTEN | UART011_CR_TXE; - writew(cr, uap->port.membase + UART011_CR); + pl011_write(cr, uap->port.membase, UART011_CR); spin_unlock_irq(&uap->port.lock); /* @@ -1714,8 +1728,8 @@ static void pl011_disable_interrupts(struct uart_amba_port *uap) /* mask all interrupts and clear all pending ones */ uap->im = 0; - writew(uap->im, uap->port.membase + UART011_IMSC); - writew(0xffff, uap->port.membase + UART011_ICR); + pl011_write(uap->im, uap->port.membase, UART011_IMSC); + pl011_write(0xffff, uap->port.membase, UART011_ICR); spin_unlock_irq(&uap->port.lock); } @@ -1867,8 +1881,8 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, pl011_enable_ms(port); /* first, disable everything */ - old_cr = readw(port->membase + UART011_CR); - writew(0, port->membase + UART011_CR); + old_cr = pl011_read(port->membase, UART011_CR); + pl011_write(0, port->membase, UART011_CR); if (termios->c_cflag & CRTSCTS) { if (old_cr & UART011_CR_RTS) @@ -1901,8 +1915,8 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, quot -= 2; } /* Set baud rate */ - writew(quot & 0x3f, port->membase + UART011_FBRD); - writew(quot >> 6, port->membase + UART011_IBRD); + pl011_write(quot & 0x3f, port->membase, UART011_FBRD); + pl011_write(quot >> 6, port->membase, UART011_IBRD); /* * ----------v----------v----------v----------v----- @@ -1911,7 +1925,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, * ----------^----------^----------^----------^----- */ pl011_write_lcr_h(uap, lcr_h); - writew(old_cr, port->membase + UART011_CR); + pl011_write(old_cr, port->membase, UART011_CR); spin_unlock_irqrestore(&port->lock, flags); } @@ -2052,9 +2066,9 @@ static void pl011_console_putchar(struct uart_port *port, int ch) struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); - while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) + while (pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_TXFF) barrier(); - writew(ch, uap->port.membase + UART01x_DR); + pl011_write(ch, uap->port.membase, UART01x_DR); } static void @@ -2079,10 +2093,10 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) * First save the CR then disable the interrupts */ if (!uap->vendor->always_enabled) { - old_cr = readw(uap->port.membase + UART011_CR); + old_cr = pl011_read(uap->port.membase, UART011_CR); new_cr = old_cr & ~UART011_CR_CTSEN; new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE; - writew(new_cr, uap->port.membase + UART011_CR); + pl011_write(new_cr, uap->port.membase, UART011_CR); } uart_console_write(&uap->port, s, count, pl011_console_putchar); @@ -2092,10 +2106,10 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) * and restore the TCR */ do { - status = readw(uap->port.membase + UART01x_FR); + status = pl011_read(uap->port.membase, UART01x_FR); } while (status & UART01x_FR_BUSY); if (!uap->vendor->always_enabled) - writew(old_cr, uap->port.membase + UART011_CR); + pl011_write(old_cr, uap->port.membase, UART011_CR); if (locked) spin_unlock(&uap->port.lock); @@ -2108,10 +2122,10 @@ static void __init pl011_console_get_options(struct uart_amba_port *uap, int *baud, int *parity, int *bits) { - if (readw(uap->port.membase + UART011_CR) & UART01x_CR_UARTEN) { + if (pl011_read(uap->port.membase, UART011_CR) & UART01x_CR_UARTEN) { unsigned int lcr_h, ibrd, fbrd; - lcr_h = readw(uap->port.membase + uap->lcrh_tx); + lcr_h = pl011_read(uap->port.membase, uap->lcrh_tx); *parity = 'n'; if (lcr_h & UART01x_LCRH_PEN) { @@ -2126,13 +2140,13 @@ pl011_console_get_options(struct uart_amba_port *uap, int *baud, else *bits = 8; - ibrd = readw(uap->port.membase + UART011_IBRD); - fbrd = readw(uap->port.membase + UART011_FBRD); + ibrd = pl011_read(uap->port.membase, UART011_IBRD); + fbrd = pl011_read(uap->port.membase, UART011_FBRD); *baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd); if (uap->vendor->oversampling) { - if (readw(uap->port.membase + UART011_CR) + if (pl011_read(uap->port.membase, UART011_CR) & ST_UART011_CR_OVSFACT) *baud *= 2; } @@ -2334,8 +2348,8 @@ static int pl011_register_port(struct uart_amba_port *uap) int ret; /* Ensure interrupts from this UART are masked and cleared */ - writew(0, uap->port.membase + UART011_IMSC); - writew(0xffff, uap->port.membase + UART011_ICR); + pl011_write(0, uap->port.membase, UART011_IMSC); + pl011_write(0xffff, uap->port.membase, UART011_ICR); if (!amba_reg.state) { ret = uart_register_driver(&amba_reg); -- GitLab From b2a4e24c2efd76a2c25478836fb35951e00d5b52 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 3 Nov 2015 14:51:03 +0000 Subject: [PATCH 1138/2855] tty: amba-pl011: convert accessor functions to take uart_amba_port Convert the new accessor functions to take the uart_amba_port instead of the port base address. Signed-off-by: Russell King Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 199 ++++++++++++++++---------------- 1 file changed, 97 insertions(+), 102 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index bd01e75128dc6..0e7f045b8f4f8 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -184,14 +184,16 @@ struct uart_amba_port { #endif }; -static unsigned int pl011_read(void __iomem *base, unsigned int reg) +static unsigned int pl011_read(const struct uart_amba_port *uap, + unsigned int reg) { - return readw(base + reg); + return readw(uap->port.membase + reg); } -static void pl011_write(unsigned int val, void __iomem *base, unsigned int reg) +static void pl011_write(unsigned int val, const struct uart_amba_port *uap, + unsigned int reg) { - writew(val, base + reg); + writew(val, uap->port.membase + reg); } /* @@ -206,13 +208,12 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap) int fifotaken = 0; while (max_count--) { - status = pl011_read(uap->port.membase, UART01x_FR); + status = pl011_read(uap, UART01x_FR); if (status & UART01x_FR_RXFE) break; /* Take chars from the FIFO and update status */ - ch = pl011_read(uap->port.membase, UART01x_DR) | - UART_DUMMY_DR_RX; + ch = pl011_read(uap, UART01x_DR) | UART_DUMMY_DR_RX; flag = TTY_NORMAL; uap->port.icount.rx++; fifotaken++; @@ -448,7 +449,7 @@ static void pl011_dma_tx_callback(void *data) dmacr = uap->dmacr; uap->dmacr = dmacr & ~UART011_TXDMAE; - pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); + pl011_write(uap->dmacr, uap, UART011_DMACR); /* * If TX DMA was disabled, it means that we've stopped the DMA for @@ -562,7 +563,7 @@ static int pl011_dma_tx_refill(struct uart_amba_port *uap) dma_dev->device_issue_pending(chan); uap->dmacr |= UART011_TXDMAE; - pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); + pl011_write(uap->dmacr, uap, UART011_DMACR); uap->dmatx.queued = true; /* @@ -598,9 +599,9 @@ static bool pl011_dma_tx_irq(struct uart_amba_port *uap) */ if (uap->dmatx.queued) { uap->dmacr |= UART011_TXDMAE; - pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); + pl011_write(uap->dmacr, uap, UART011_DMACR); uap->im &= ~UART011_TXIM; - pl011_write(uap->im, uap->port.membase, UART011_IMSC); + pl011_write(uap->im, uap, UART011_IMSC); return true; } @@ -610,7 +611,7 @@ static bool pl011_dma_tx_irq(struct uart_amba_port *uap) */ if (pl011_dma_tx_refill(uap) > 0) { uap->im &= ~UART011_TXIM; - pl011_write(uap->im, uap->port.membase, UART011_IMSC); + pl011_write(uap->im, uap, UART011_IMSC); return true; } return false; @@ -624,7 +625,7 @@ static inline void pl011_dma_tx_stop(struct uart_amba_port *uap) { if (uap->dmatx.queued) { uap->dmacr &= ~UART011_TXDMAE; - pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); + pl011_write(uap->dmacr, uap, UART011_DMACR); } } @@ -650,14 +651,12 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap) if (!uap->dmatx.queued) { if (pl011_dma_tx_refill(uap) > 0) { uap->im &= ~UART011_TXIM; - pl011_write(uap->im, uap->port.membase, - UART011_IMSC); + pl011_write(uap->im, uap, UART011_IMSC); } else ret = false; } else if (!(uap->dmacr & UART011_TXDMAE)) { uap->dmacr |= UART011_TXDMAE; - pl011_write(uap->dmacr, uap->port.membase, - UART011_DMACR); + pl011_write(uap->dmacr, uap, UART011_DMACR); } return ret; } @@ -668,9 +667,9 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap) */ dmacr = uap->dmacr; uap->dmacr &= ~UART011_TXDMAE; - pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); + pl011_write(uap->dmacr, uap, UART011_DMACR); - if (pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_TXFF) { + if (pl011_read(uap, UART01x_FR) & UART01x_FR_TXFF) { /* * No space in the FIFO, so enable the transmit interrupt * so we know when there is space. Note that once we've @@ -679,13 +678,13 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap) return false; } - pl011_write(uap->port.x_char, uap->port.membase, UART01x_DR); + pl011_write(uap->port.x_char, uap, UART01x_DR); uap->port.icount.tx++; uap->port.x_char = 0; /* Success - restore the DMA state */ uap->dmacr = dmacr; - pl011_write(dmacr, uap->port.membase, UART011_DMACR); + pl011_write(dmacr, uap, UART011_DMACR); return true; } @@ -713,7 +712,7 @@ __acquires(&uap->port.lock) DMA_TO_DEVICE); uap->dmatx.queued = false; uap->dmacr &= ~UART011_TXDMAE; - pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); + pl011_write(uap->dmacr, uap, UART011_DMACR); } } @@ -753,11 +752,11 @@ static int pl011_dma_rx_trigger_dma(struct uart_amba_port *uap) dma_async_issue_pending(rxchan); uap->dmacr |= UART011_RXDMAE; - pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); + pl011_write(uap->dmacr, uap, UART011_DMACR); uap->dmarx.running = true; uap->im &= ~UART011_RXIM; - pl011_write(uap->im, uap->port.membase, UART011_IMSC); + pl011_write(uap->im, uap, UART011_IMSC); return 0; } @@ -816,7 +815,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, if (dma_count == pending && readfifo) { /* Clear any error flags */ pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS | - UART011_FEIS, uap->port.membase, UART011_ICR); + UART011_FEIS, uap, UART011_ICR); /* * If we read all the DMA'd characters, and we had an @@ -864,7 +863,7 @@ static void pl011_dma_rx_irq(struct uart_amba_port *uap) /* Disable RX DMA - incoming data will wait in the FIFO */ uap->dmacr &= ~UART011_RXDMAE; - pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); + pl011_write(uap->dmacr, uap, UART011_DMACR); uap->dmarx.running = false; pending = sgbuf->sg.length - state.residue; @@ -884,7 +883,7 @@ static void pl011_dma_rx_irq(struct uart_amba_port *uap) dev_dbg(uap->port.dev, "could not retrigger RX DMA job " "fall back to interrupt mode\n"); uap->im |= UART011_RXIM; - pl011_write(uap->im, uap->port.membase, UART011_IMSC); + pl011_write(uap->im, uap, UART011_IMSC); } } @@ -932,7 +931,7 @@ static void pl011_dma_rx_callback(void *data) dev_dbg(uap->port.dev, "could not retrigger RX DMA job " "fall back to interrupt mode\n"); uap->im |= UART011_RXIM; - pl011_write(uap->im, uap->port.membase, UART011_IMSC); + pl011_write(uap->im, uap, UART011_IMSC); } } @@ -945,7 +944,7 @@ static inline void pl011_dma_rx_stop(struct uart_amba_port *uap) { /* FIXME. Just disable the DMA enable */ uap->dmacr &= ~UART011_RXDMAE; - pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); + pl011_write(uap->dmacr, uap, UART011_DMACR); } /* @@ -989,7 +988,7 @@ static void pl011_dma_rx_poll(unsigned long args) spin_lock_irqsave(&uap->port.lock, flags); pl011_dma_rx_stop(uap); uap->im |= UART011_RXIM; - pl011_write(uap->im, uap->port.membase, UART011_IMSC); + pl011_write(uap->im, uap, UART011_IMSC); spin_unlock_irqrestore(&uap->port.lock, flags); uap->dmarx.running = false; @@ -1051,7 +1050,7 @@ static void pl011_dma_startup(struct uart_amba_port *uap) skip_rx: /* Turn on DMA error (RX/TX will be enabled on demand) */ uap->dmacr |= UART011_DMAONERR; - pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); + pl011_write(uap->dmacr, uap, UART011_DMACR); /* * ST Micro variants has some specific dma burst threshold @@ -1060,7 +1059,7 @@ skip_rx: */ if (uap->vendor->dma_threshold) pl011_write(ST_UART011_DMAWM_RX_16 | ST_UART011_DMAWM_TX_16, - uap->port.membase, ST_UART011_DMAWM); + uap, ST_UART011_DMAWM); if (uap->using_rx_dma) { if (pl011_dma_rx_trigger_dma(uap)) @@ -1085,12 +1084,12 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap) return; /* Disable RX and TX DMA */ - while (pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_BUSY) + while (pl011_read(uap, UART01x_FR) & UART01x_FR_BUSY) barrier(); spin_lock_irq(&uap->port.lock); uap->dmacr &= ~(UART011_DMAONERR | UART011_RXDMAE | UART011_TXDMAE); - pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); + pl011_write(uap->dmacr, uap, UART011_DMACR); spin_unlock_irq(&uap->port.lock); if (uap->using_tx_dma) { @@ -1191,7 +1190,7 @@ static void pl011_stop_tx(struct uart_port *port) container_of(port, struct uart_amba_port, port); uap->im &= ~UART011_TXIM; - pl011_write(uap->im, uap->port.membase, UART011_IMSC); + pl011_write(uap->im, uap, UART011_IMSC); pl011_dma_tx_stop(uap); } @@ -1201,7 +1200,7 @@ static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq); static void pl011_start_tx_pio(struct uart_amba_port *uap) { uap->im |= UART011_TXIM; - pl011_write(uap->im, uap->port.membase, UART011_IMSC); + pl011_write(uap->im, uap, UART011_IMSC); pl011_tx_chars(uap, false); } @@ -1221,7 +1220,7 @@ static void pl011_stop_rx(struct uart_port *port) uap->im &= ~(UART011_RXIM|UART011_RTIM|UART011_FEIM| UART011_PEIM|UART011_BEIM|UART011_OEIM); - pl011_write(uap->im, uap->port.membase, UART011_IMSC); + pl011_write(uap->im, uap, UART011_IMSC); pl011_dma_rx_stop(uap); } @@ -1232,7 +1231,7 @@ static void pl011_enable_ms(struct uart_port *port) container_of(port, struct uart_amba_port, port); uap->im |= UART011_RIMIM|UART011_CTSMIM|UART011_DCDMIM|UART011_DSRMIM; - pl011_write(uap->im, uap->port.membase, UART011_IMSC); + pl011_write(uap->im, uap, UART011_IMSC); } static void pl011_rx_chars(struct uart_amba_port *uap) @@ -1252,7 +1251,7 @@ __acquires(&uap->port.lock) dev_dbg(uap->port.dev, "could not trigger RX DMA job " "fall back to interrupt mode again\n"); uap->im |= UART011_RXIM; - pl011_write(uap->im, uap->port.membase, UART011_IMSC); + pl011_write(uap->im, uap, UART011_IMSC); } else { #ifdef CONFIG_DMA_ENGINE /* Start Rx DMA poll */ @@ -1273,10 +1272,10 @@ static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c, bool from_irq) { if (unlikely(!from_irq) && - pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_TXFF) + pl011_read(uap, UART01x_FR) & UART01x_FR_TXFF) return false; /* unable to transmit character */ - pl011_write(c, uap->port.membase, UART01x_DR); + pl011_write(c, uap, UART01x_DR); uap->port.icount.tx++; return true; @@ -1323,8 +1322,7 @@ static void pl011_modem_status(struct uart_amba_port *uap) { unsigned int status, delta; - status = pl011_read(uap->port.membase, UART01x_FR); - status &= UART01x_FR_MODEM_ANY; + status = pl011_read(uap, UART01x_FR) & UART01x_FR_MODEM_ANY; delta = status ^ uap->old_status; uap->old_status = status; @@ -1352,15 +1350,15 @@ static void check_apply_cts_event_workaround(struct uart_amba_port *uap) return; /* workaround to make sure that all bits are unlocked.. */ - pl011_write(0x00, uap->port.membase, UART011_ICR); + pl011_write(0x00, uap, UART011_ICR); /* * WA: introduce 26ns(1 uart clk) delay before W1C; * single apb access will incur 2 pclk(133.12Mhz) delay, * so add 2 dummy reads */ - dummy_read = pl011_read(uap->port.membase, UART011_ICR); - dummy_read = pl011_read(uap->port.membase, UART011_ICR); + dummy_read = pl011_read(uap, UART011_ICR); + dummy_read = pl011_read(uap, UART011_ICR); } static irqreturn_t pl011_int(int irq, void *dev_id) @@ -1372,15 +1370,15 @@ static irqreturn_t pl011_int(int irq, void *dev_id) int handled = 0; spin_lock_irqsave(&uap->port.lock, flags); - imsc = pl011_read(uap->port.membase, UART011_IMSC); - status = pl011_read(uap->port.membase, UART011_RIS) & imsc; + imsc = pl011_read(uap, UART011_IMSC); + status = pl011_read(uap, UART011_RIS) & imsc; if (status) { do { check_apply_cts_event_workaround(uap); pl011_write(status & ~(UART011_TXIS|UART011_RTIS| UART011_RXIS), - uap->port.membase, UART011_ICR); + uap, UART011_ICR); if (status & (UART011_RTIS|UART011_RXIS)) { if (pl011_dma_rx_running(uap)) @@ -1397,7 +1395,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id) if (pass_counter-- == 0) break; - status = pl011_read(uap->port.membase, UART011_RIS) & imsc; + status = pl011_read(uap, UART011_RIS) & imsc; } while (status != 0); handled = 1; } @@ -1411,7 +1409,7 @@ static unsigned int pl011_tx_empty(struct uart_port *port) { struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); - unsigned int status = pl011_read(uap->port.membase, UART01x_FR); + unsigned int status = pl011_read(uap, UART01x_FR); return status & (UART01x_FR_BUSY|UART01x_FR_TXFF) ? 0 : TIOCSER_TEMT; } @@ -1420,7 +1418,7 @@ static unsigned int pl011_get_mctrl(struct uart_port *port) struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); unsigned int result = 0; - unsigned int status = pl011_read(uap->port.membase, UART01x_FR); + unsigned int status = pl011_read(uap, UART01x_FR); #define TIOCMBIT(uartbit, tiocmbit) \ if (status & uartbit) \ @@ -1440,7 +1438,7 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) container_of(port, struct uart_amba_port, port); unsigned int cr; - cr = pl011_read(uap->port.membase, UART011_CR); + cr = pl011_read(uap, UART011_CR); #define TIOCMBIT(tiocmbit, uartbit) \ if (mctrl & tiocmbit) \ @@ -1460,7 +1458,7 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) } #undef TIOCMBIT - pl011_write(cr, uap->port.membase, UART011_CR); + pl011_write(cr, uap, UART011_CR); } static void pl011_break_ctl(struct uart_port *port, int break_state) @@ -1471,12 +1469,12 @@ static void pl011_break_ctl(struct uart_port *port, int break_state) unsigned int lcr_h; spin_lock_irqsave(&uap->port.lock, flags); - lcr_h = pl011_read(uap->port.membase, uap->lcrh_tx); + lcr_h = pl011_read(uap, uap->lcrh_tx); if (break_state == -1) lcr_h |= UART01x_LCRH_BRK; else lcr_h &= ~UART01x_LCRH_BRK; - pl011_write(lcr_h, uap->port.membase, uap->lcrh_tx); + pl011_write(lcr_h, uap, uap->lcrh_tx); spin_unlock_irqrestore(&uap->port.lock, flags); } @@ -1486,9 +1484,8 @@ static void pl011_quiesce_irqs(struct uart_port *port) { struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); - unsigned char __iomem *regs = uap->port.membase; - pl011_write(pl011_read(regs, UART011_MIS), regs, UART011_ICR); + pl011_write(pl011_read(uap, UART011_MIS), uap, UART011_ICR); /* * There is no way to clear TXIM as this is "ready to transmit IRQ", so * we simply mask it. start_tx() will unmask it. @@ -1502,8 +1499,8 @@ static void pl011_quiesce_irqs(struct uart_port *port) * (including tx queue), so we're also fine with start_tx()'s caller * side. */ - pl011_write(pl011_read(regs, UART011_IMSC) & ~UART011_TXIM, - regs, UART011_IMSC); + pl011_write(pl011_read(uap, UART011_IMSC) & ~UART011_TXIM, uap, + UART011_IMSC); } static int pl011_get_poll_char(struct uart_port *port) @@ -1518,11 +1515,11 @@ static int pl011_get_poll_char(struct uart_port *port) */ pl011_quiesce_irqs(port); - status = pl011_read(uap->port.membase, UART01x_FR); + status = pl011_read(uap, UART01x_FR); if (status & UART01x_FR_RXFE) return NO_POLL_CHAR; - return pl011_read(uap->port.membase, UART01x_DR); + return pl011_read(uap, UART01x_DR); } static void pl011_put_poll_char(struct uart_port *port, @@ -1531,10 +1528,10 @@ static void pl011_put_poll_char(struct uart_port *port, struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); - while (pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_TXFF) + while (pl011_read(uap, UART01x_FR) & UART01x_FR_TXFF) barrier(); - pl011_write(ch, uap->port.membase, UART01x_DR); + pl011_write(ch, uap, UART01x_DR); } #endif /* CONFIG_CONSOLE_POLL */ @@ -1560,15 +1557,14 @@ static int pl011_hwinit(struct uart_port *port) /* Clear pending error and receive interrupts */ pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS | UART011_RTIS | UART011_RXIS, - uap->port.membase, UART011_ICR); + uap, UART011_ICR); /* * Save interrupts enable mask, and enable RX interrupts in case if * the interrupt is used for NMI entry. */ - uap->im = pl011_read(uap->port.membase, UART011_IMSC); - pl011_write(UART011_RTIM | UART011_RXIM, uap->port.membase, - UART011_IMSC); + uap->im = pl011_read(uap, UART011_IMSC); + pl011_write(UART011_RTIM | UART011_RXIM, uap, UART011_IMSC); if (dev_get_platdata(uap->port.dev)) { struct amba_pl011_data *plat; @@ -1582,7 +1578,7 @@ static int pl011_hwinit(struct uart_port *port) static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h) { - pl011_write(lcr_h, uap->port.membase, uap->lcrh_rx); + pl011_write(lcr_h, uap, uap->lcrh_rx); if (uap->lcrh_rx != uap->lcrh_tx) { int i; /* @@ -1590,14 +1586,14 @@ static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h) * to get this delay write read only register 10 times */ for (i = 0; i < 10; ++i) - pl011_write(0xff, uap->port.membase, UART011_MIS); - pl011_write(lcr_h, uap->port.membase, uap->lcrh_tx); + pl011_write(0xff, uap, UART011_MIS); + pl011_write(lcr_h, uap, uap->lcrh_tx); } } static int pl011_allocate_irq(struct uart_amba_port *uap) { - pl011_write(uap->im, uap->port.membase, UART011_IMSC); + pl011_write(uap->im, uap, UART011_IMSC); return request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap); } @@ -1612,12 +1608,11 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap) spin_lock_irq(&uap->port.lock); /* Clear out any spuriously appearing RX interrupts */ - pl011_write(UART011_RTIS | UART011_RXIS, uap->port.membase, - UART011_ICR); + pl011_write(UART011_RTIS | UART011_RXIS, uap, UART011_ICR); uap->im = UART011_RTIM; if (!pl011_dma_rx_running(uap)) uap->im |= UART011_RXIM; - pl011_write(uap->im, uap->port.membase, UART011_IMSC); + pl011_write(uap->im, uap, UART011_IMSC); spin_unlock_irq(&uap->port.lock); } @@ -1636,21 +1631,21 @@ static int pl011_startup(struct uart_port *port) if (retval) goto clk_dis; - pl011_write(uap->vendor->ifls, uap->port.membase, UART011_IFLS); + pl011_write(uap->vendor->ifls, uap, UART011_IFLS); spin_lock_irq(&uap->port.lock); /* restore RTS and DTR */ cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR); cr |= UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; - pl011_write(cr, uap->port.membase, UART011_CR); + pl011_write(cr, uap, UART011_CR); spin_unlock_irq(&uap->port.lock); /* * initialise the old status of the modem signals */ - uap->old_status = pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_MODEM_ANY; + uap->old_status = pl011_read(uap, UART01x_FR) & UART01x_FR_MODEM_ANY; /* Startup DMA */ pl011_dma_startup(uap); @@ -1691,9 +1686,9 @@ static void pl011_shutdown_channel(struct uart_amba_port *uap, { unsigned long val; - val = pl011_read(uap->port.membase, lcrh); + val = pl011_read(uap, lcrh); val &= ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN); - pl011_write(val, uap->port.membase, lcrh); + pl011_write(val, uap, lcrh); } /* @@ -1707,11 +1702,11 @@ static void pl011_disable_uart(struct uart_amba_port *uap) uap->autorts = false; spin_lock_irq(&uap->port.lock); - cr = pl011_read(uap->port.membase, UART011_CR); + cr = pl011_read(uap, UART011_CR); uap->old_cr = cr; cr &= UART011_CR_RTS | UART011_CR_DTR; cr |= UART01x_CR_UARTEN | UART011_CR_TXE; - pl011_write(cr, uap->port.membase, UART011_CR); + pl011_write(cr, uap, UART011_CR); spin_unlock_irq(&uap->port.lock); /* @@ -1728,8 +1723,8 @@ static void pl011_disable_interrupts(struct uart_amba_port *uap) /* mask all interrupts and clear all pending ones */ uap->im = 0; - pl011_write(uap->im, uap->port.membase, UART011_IMSC); - pl011_write(0xffff, uap->port.membase, UART011_ICR); + pl011_write(uap->im, uap, UART011_IMSC); + pl011_write(0xffff, uap, UART011_ICR); spin_unlock_irq(&uap->port.lock); } @@ -1881,8 +1876,8 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, pl011_enable_ms(port); /* first, disable everything */ - old_cr = pl011_read(port->membase, UART011_CR); - pl011_write(0, port->membase, UART011_CR); + old_cr = pl011_read(uap, UART011_CR); + pl011_write(0, uap, UART011_CR); if (termios->c_cflag & CRTSCTS) { if (old_cr & UART011_CR_RTS) @@ -1915,8 +1910,8 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, quot -= 2; } /* Set baud rate */ - pl011_write(quot & 0x3f, port->membase, UART011_FBRD); - pl011_write(quot >> 6, port->membase, UART011_IBRD); + pl011_write(quot & 0x3f, uap, UART011_FBRD); + pl011_write(quot >> 6, uap, UART011_IBRD); /* * ----------v----------v----------v----------v----- @@ -1925,7 +1920,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, * ----------^----------^----------^----------^----- */ pl011_write_lcr_h(uap, lcr_h); - pl011_write(old_cr, port->membase, UART011_CR); + pl011_write(old_cr, uap, UART011_CR); spin_unlock_irqrestore(&port->lock, flags); } @@ -2066,9 +2061,9 @@ static void pl011_console_putchar(struct uart_port *port, int ch) struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); - while (pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_TXFF) + while (pl011_read(uap, UART01x_FR) & UART01x_FR_TXFF) barrier(); - pl011_write(ch, uap->port.membase, UART01x_DR); + pl011_write(ch, uap, UART01x_DR); } static void @@ -2093,10 +2088,10 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) * First save the CR then disable the interrupts */ if (!uap->vendor->always_enabled) { - old_cr = pl011_read(uap->port.membase, UART011_CR); + old_cr = pl011_read(uap, UART011_CR); new_cr = old_cr & ~UART011_CR_CTSEN; new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE; - pl011_write(new_cr, uap->port.membase, UART011_CR); + pl011_write(new_cr, uap, UART011_CR); } uart_console_write(&uap->port, s, count, pl011_console_putchar); @@ -2106,10 +2101,10 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) * and restore the TCR */ do { - status = pl011_read(uap->port.membase, UART01x_FR); + status = pl011_read(uap, UART01x_FR); } while (status & UART01x_FR_BUSY); if (!uap->vendor->always_enabled) - pl011_write(old_cr, uap->port.membase, UART011_CR); + pl011_write(old_cr, uap, UART011_CR); if (locked) spin_unlock(&uap->port.lock); @@ -2122,10 +2117,10 @@ static void __init pl011_console_get_options(struct uart_amba_port *uap, int *baud, int *parity, int *bits) { - if (pl011_read(uap->port.membase, UART011_CR) & UART01x_CR_UARTEN) { + if (pl011_read(uap, UART011_CR) & UART01x_CR_UARTEN) { unsigned int lcr_h, ibrd, fbrd; - lcr_h = pl011_read(uap->port.membase, uap->lcrh_tx); + lcr_h = pl011_read(uap, uap->lcrh_tx); *parity = 'n'; if (lcr_h & UART01x_LCRH_PEN) { @@ -2140,13 +2135,13 @@ pl011_console_get_options(struct uart_amba_port *uap, int *baud, else *bits = 8; - ibrd = pl011_read(uap->port.membase, UART011_IBRD); - fbrd = pl011_read(uap->port.membase, UART011_FBRD); + ibrd = pl011_read(uap, UART011_IBRD); + fbrd = pl011_read(uap, UART011_FBRD); *baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd); if (uap->vendor->oversampling) { - if (pl011_read(uap->port.membase, UART011_CR) + if (pl011_read(uap, UART011_CR) & ST_UART011_CR_OVSFACT) *baud *= 2; } @@ -2348,8 +2343,8 @@ static int pl011_register_port(struct uart_amba_port *uap) int ret; /* Ensure interrupts from this UART are masked and cleared */ - pl011_write(0, uap->port.membase, UART011_IMSC); - pl011_write(0xffff, uap->port.membase, UART011_ICR); + pl011_write(0, uap, UART011_IMSC); + pl011_write(0xffff, uap, UART011_ICR); if (!amba_reg.state) { ret = uart_register_driver(&amba_reg); -- GitLab From 7fe9a5a9d91f0e9ac65c723665bbdf899c3a4a24 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 3 Nov 2015 14:51:08 +0000 Subject: [PATCH 1139/2855] tty: amba-pl011: add helper to detect split LCRH register Add a helper to detect the split LCRH register found on ST variants. Signed-off-by: Russell King Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 0e7f045b8f4f8..c9ae0a144f10e 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1576,10 +1576,15 @@ static int pl011_hwinit(struct uart_port *port) return 0; } +static bool pl011_split_lcrh(const struct uart_amba_port *uap) +{ + return uap->lcrh_rx != uap->lcrh_tx; +} + static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h) { pl011_write(lcr_h, uap, uap->lcrh_rx); - if (uap->lcrh_rx != uap->lcrh_tx) { + if (pl011_split_lcrh(uap)) { int i; /* * Wait 10 PCLKs before writing LCRH_TX register, @@ -1713,7 +1718,7 @@ static void pl011_disable_uart(struct uart_amba_port *uap) * disable break condition and fifos */ pl011_shutdown_channel(uap, uap->lcrh_rx); - if (uap->lcrh_rx != uap->lcrh_tx) + if (pl011_split_lcrh(uap)) pl011_shutdown_channel(uap, uap->lcrh_tx); } -- GitLab From 9f25bc510e960c551dc295c2d1d60e3da334590c Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 3 Nov 2015 14:51:13 +0000 Subject: [PATCH 1140/2855] tty: amba-pl011: prepare REG_* register indexes Prepare for REG_* register accessors. This change involves introducing pl011_reg_to_offset() to convert REG_* to the hardware register offset, and converting all call sites to use REG_* names. We need to fix up locations where we check for equivalence of register offsets as well. Much of this change was made via these sed expressions: s/ST_UART01[1x]\(_[^_]*\|_LCRH_[TR]X\)\>/REG_ST\1/ s/UART01[1x]_\(DR\|RSR\|ECR\|FR\|ILPR\|[IF]BRD\|LCRH\|CR\|IFLS\|IMSC\|RIS\|MIS\|ICR\|DMACR\)\>/REG_\1/g Signed-off-by: Russell King Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 205 +++++++++++++++++--------------- drivers/tty/serial/amba-pl011.h | 32 +++++ 2 files changed, 140 insertions(+), 97 deletions(-) create mode 100644 drivers/tty/serial/amba-pl011.h diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index c9ae0a144f10e..62b9cb2754020 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -60,6 +60,8 @@ #include #include +#include "amba-pl011.h" + #define UART_NR 14 #define SERIAL_AMBA_MAJOR 204 @@ -92,8 +94,8 @@ static unsigned int get_fifosize_arm(struct amba_device *dev) static struct vendor_data vendor_arm = { .ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, - .lcrh_tx = UART011_LCRH, - .lcrh_rx = UART011_LCRH, + .lcrh_tx = REG_LCRH, + .lcrh_rx = REG_LCRH, .oversampling = false, .dma_threshold = false, .cts_event_workaround = false, @@ -117,8 +119,8 @@ static unsigned int get_fifosize_st(struct amba_device *dev) static struct vendor_data vendor_st = { .ifls = UART011_IFLS_RX_HALF|UART011_IFLS_TX_HALF, - .lcrh_tx = ST_UART011_LCRH_TX, - .lcrh_rx = ST_UART011_LCRH_RX, + .lcrh_tx = REG_ST_LCRH_TX, + .lcrh_rx = REG_ST_LCRH_RX, .oversampling = true, .dma_threshold = true, .cts_event_workaround = true, @@ -184,16 +186,22 @@ struct uart_amba_port { #endif }; +static unsigned int pl011_reg_to_offset(const struct uart_amba_port *uap, + unsigned int reg) +{ + return reg; +} + static unsigned int pl011_read(const struct uart_amba_port *uap, unsigned int reg) { - return readw(uap->port.membase + reg); + return readw(uap->port.membase + pl011_reg_to_offset(uap, reg)); } static void pl011_write(unsigned int val, const struct uart_amba_port *uap, unsigned int reg) { - writew(val, uap->port.membase + reg); + writew(val, uap->port.membase + pl011_reg_to_offset(uap, reg)); } /* @@ -208,12 +216,12 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap) int fifotaken = 0; while (max_count--) { - status = pl011_read(uap, UART01x_FR); + status = pl011_read(uap, REG_FR); if (status & UART01x_FR_RXFE) break; /* Take chars from the FIFO and update status */ - ch = pl011_read(uap, UART01x_DR) | UART_DUMMY_DR_RX; + ch = pl011_read(uap, REG_DR) | UART_DUMMY_DR_RX; flag = TTY_NORMAL; uap->port.icount.rx++; fifotaken++; @@ -295,7 +303,8 @@ static void pl011_dma_probe(struct uart_amba_port *uap) struct amba_pl011_data *plat = dev_get_platdata(uap->port.dev); struct device *dev = uap->port.dev; struct dma_slave_config tx_conf = { - .dst_addr = uap->port.mapbase + UART01x_DR, + .dst_addr = uap->port.mapbase + + pl011_reg_to_offset(uap, REG_DR), .dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, .direction = DMA_MEM_TO_DEV, .dst_maxburst = uap->fifosize >> 1, @@ -350,7 +359,8 @@ static void pl011_dma_probe(struct uart_amba_port *uap) if (chan) { struct dma_slave_config rx_conf = { - .src_addr = uap->port.mapbase + UART01x_DR, + .src_addr = uap->port.mapbase + + pl011_reg_to_offset(uap, REG_DR), .src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, .direction = DMA_DEV_TO_MEM, .src_maxburst = uap->fifosize >> 2, @@ -449,7 +459,7 @@ static void pl011_dma_tx_callback(void *data) dmacr = uap->dmacr; uap->dmacr = dmacr & ~UART011_TXDMAE; - pl011_write(uap->dmacr, uap, UART011_DMACR); + pl011_write(uap->dmacr, uap, REG_DMACR); /* * If TX DMA was disabled, it means that we've stopped the DMA for @@ -563,7 +573,7 @@ static int pl011_dma_tx_refill(struct uart_amba_port *uap) dma_dev->device_issue_pending(chan); uap->dmacr |= UART011_TXDMAE; - pl011_write(uap->dmacr, uap, UART011_DMACR); + pl011_write(uap->dmacr, uap, REG_DMACR); uap->dmatx.queued = true; /* @@ -599,9 +609,9 @@ static bool pl011_dma_tx_irq(struct uart_amba_port *uap) */ if (uap->dmatx.queued) { uap->dmacr |= UART011_TXDMAE; - pl011_write(uap->dmacr, uap, UART011_DMACR); + pl011_write(uap->dmacr, uap, REG_DMACR); uap->im &= ~UART011_TXIM; - pl011_write(uap->im, uap, UART011_IMSC); + pl011_write(uap->im, uap, REG_IMSC); return true; } @@ -611,7 +621,7 @@ static bool pl011_dma_tx_irq(struct uart_amba_port *uap) */ if (pl011_dma_tx_refill(uap) > 0) { uap->im &= ~UART011_TXIM; - pl011_write(uap->im, uap, UART011_IMSC); + pl011_write(uap->im, uap, REG_IMSC); return true; } return false; @@ -625,7 +635,7 @@ static inline void pl011_dma_tx_stop(struct uart_amba_port *uap) { if (uap->dmatx.queued) { uap->dmacr &= ~UART011_TXDMAE; - pl011_write(uap->dmacr, uap, UART011_DMACR); + pl011_write(uap->dmacr, uap, REG_DMACR); } } @@ -651,12 +661,12 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap) if (!uap->dmatx.queued) { if (pl011_dma_tx_refill(uap) > 0) { uap->im &= ~UART011_TXIM; - pl011_write(uap->im, uap, UART011_IMSC); + pl011_write(uap->im, uap, REG_IMSC); } else ret = false; } else if (!(uap->dmacr & UART011_TXDMAE)) { uap->dmacr |= UART011_TXDMAE; - pl011_write(uap->dmacr, uap, UART011_DMACR); + pl011_write(uap->dmacr, uap, REG_DMACR); } return ret; } @@ -667,9 +677,9 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap) */ dmacr = uap->dmacr; uap->dmacr &= ~UART011_TXDMAE; - pl011_write(uap->dmacr, uap, UART011_DMACR); + pl011_write(uap->dmacr, uap, REG_DMACR); - if (pl011_read(uap, UART01x_FR) & UART01x_FR_TXFF) { + if (pl011_read(uap, REG_FR) & UART01x_FR_TXFF) { /* * No space in the FIFO, so enable the transmit interrupt * so we know when there is space. Note that once we've @@ -678,13 +688,13 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap) return false; } - pl011_write(uap->port.x_char, uap, UART01x_DR); + pl011_write(uap->port.x_char, uap, REG_DR); uap->port.icount.tx++; uap->port.x_char = 0; /* Success - restore the DMA state */ uap->dmacr = dmacr; - pl011_write(dmacr, uap, UART011_DMACR); + pl011_write(dmacr, uap, REG_DMACR); return true; } @@ -712,7 +722,7 @@ __acquires(&uap->port.lock) DMA_TO_DEVICE); uap->dmatx.queued = false; uap->dmacr &= ~UART011_TXDMAE; - pl011_write(uap->dmacr, uap, UART011_DMACR); + pl011_write(uap->dmacr, uap, REG_DMACR); } } @@ -752,11 +762,11 @@ static int pl011_dma_rx_trigger_dma(struct uart_amba_port *uap) dma_async_issue_pending(rxchan); uap->dmacr |= UART011_RXDMAE; - pl011_write(uap->dmacr, uap, UART011_DMACR); + pl011_write(uap->dmacr, uap, REG_DMACR); uap->dmarx.running = true; uap->im &= ~UART011_RXIM; - pl011_write(uap->im, uap, UART011_IMSC); + pl011_write(uap->im, uap, REG_IMSC); return 0; } @@ -815,7 +825,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, if (dma_count == pending && readfifo) { /* Clear any error flags */ pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS | - UART011_FEIS, uap, UART011_ICR); + UART011_FEIS, uap, REG_ICR); /* * If we read all the DMA'd characters, and we had an @@ -863,7 +873,7 @@ static void pl011_dma_rx_irq(struct uart_amba_port *uap) /* Disable RX DMA - incoming data will wait in the FIFO */ uap->dmacr &= ~UART011_RXDMAE; - pl011_write(uap->dmacr, uap, UART011_DMACR); + pl011_write(uap->dmacr, uap, REG_DMACR); uap->dmarx.running = false; pending = sgbuf->sg.length - state.residue; @@ -883,7 +893,7 @@ static void pl011_dma_rx_irq(struct uart_amba_port *uap) dev_dbg(uap->port.dev, "could not retrigger RX DMA job " "fall back to interrupt mode\n"); uap->im |= UART011_RXIM; - pl011_write(uap->im, uap, UART011_IMSC); + pl011_write(uap->im, uap, REG_IMSC); } } @@ -931,7 +941,7 @@ static void pl011_dma_rx_callback(void *data) dev_dbg(uap->port.dev, "could not retrigger RX DMA job " "fall back to interrupt mode\n"); uap->im |= UART011_RXIM; - pl011_write(uap->im, uap, UART011_IMSC); + pl011_write(uap->im, uap, REG_IMSC); } } @@ -944,7 +954,7 @@ static inline void pl011_dma_rx_stop(struct uart_amba_port *uap) { /* FIXME. Just disable the DMA enable */ uap->dmacr &= ~UART011_RXDMAE; - pl011_write(uap->dmacr, uap, UART011_DMACR); + pl011_write(uap->dmacr, uap, REG_DMACR); } /* @@ -988,7 +998,7 @@ static void pl011_dma_rx_poll(unsigned long args) spin_lock_irqsave(&uap->port.lock, flags); pl011_dma_rx_stop(uap); uap->im |= UART011_RXIM; - pl011_write(uap->im, uap, UART011_IMSC); + pl011_write(uap->im, uap, REG_IMSC); spin_unlock_irqrestore(&uap->port.lock, flags); uap->dmarx.running = false; @@ -1050,7 +1060,7 @@ static void pl011_dma_startup(struct uart_amba_port *uap) skip_rx: /* Turn on DMA error (RX/TX will be enabled on demand) */ uap->dmacr |= UART011_DMAONERR; - pl011_write(uap->dmacr, uap, UART011_DMACR); + pl011_write(uap->dmacr, uap, REG_DMACR); /* * ST Micro variants has some specific dma burst threshold @@ -1059,7 +1069,7 @@ skip_rx: */ if (uap->vendor->dma_threshold) pl011_write(ST_UART011_DMAWM_RX_16 | ST_UART011_DMAWM_TX_16, - uap, ST_UART011_DMAWM); + uap, REG_ST_DMAWM); if (uap->using_rx_dma) { if (pl011_dma_rx_trigger_dma(uap)) @@ -1084,12 +1094,12 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap) return; /* Disable RX and TX DMA */ - while (pl011_read(uap, UART01x_FR) & UART01x_FR_BUSY) + while (pl011_read(uap, REG_FR) & UART01x_FR_BUSY) barrier(); spin_lock_irq(&uap->port.lock); uap->dmacr &= ~(UART011_DMAONERR | UART011_RXDMAE | UART011_TXDMAE); - pl011_write(uap->dmacr, uap, UART011_DMACR); + pl011_write(uap->dmacr, uap, REG_DMACR); spin_unlock_irq(&uap->port.lock); if (uap->using_tx_dma) { @@ -1190,7 +1200,7 @@ static void pl011_stop_tx(struct uart_port *port) container_of(port, struct uart_amba_port, port); uap->im &= ~UART011_TXIM; - pl011_write(uap->im, uap, UART011_IMSC); + pl011_write(uap->im, uap, REG_IMSC); pl011_dma_tx_stop(uap); } @@ -1200,7 +1210,7 @@ static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq); static void pl011_start_tx_pio(struct uart_amba_port *uap) { uap->im |= UART011_TXIM; - pl011_write(uap->im, uap, UART011_IMSC); + pl011_write(uap->im, uap, REG_IMSC); pl011_tx_chars(uap, false); } @@ -1220,7 +1230,7 @@ static void pl011_stop_rx(struct uart_port *port) uap->im &= ~(UART011_RXIM|UART011_RTIM|UART011_FEIM| UART011_PEIM|UART011_BEIM|UART011_OEIM); - pl011_write(uap->im, uap, UART011_IMSC); + pl011_write(uap->im, uap, REG_IMSC); pl011_dma_rx_stop(uap); } @@ -1231,7 +1241,7 @@ static void pl011_enable_ms(struct uart_port *port) container_of(port, struct uart_amba_port, port); uap->im |= UART011_RIMIM|UART011_CTSMIM|UART011_DCDMIM|UART011_DSRMIM; - pl011_write(uap->im, uap, UART011_IMSC); + pl011_write(uap->im, uap, REG_IMSC); } static void pl011_rx_chars(struct uart_amba_port *uap) @@ -1251,7 +1261,7 @@ __acquires(&uap->port.lock) dev_dbg(uap->port.dev, "could not trigger RX DMA job " "fall back to interrupt mode again\n"); uap->im |= UART011_RXIM; - pl011_write(uap->im, uap, UART011_IMSC); + pl011_write(uap->im, uap, REG_IMSC); } else { #ifdef CONFIG_DMA_ENGINE /* Start Rx DMA poll */ @@ -1272,10 +1282,10 @@ static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c, bool from_irq) { if (unlikely(!from_irq) && - pl011_read(uap, UART01x_FR) & UART01x_FR_TXFF) + pl011_read(uap, REG_FR) & UART01x_FR_TXFF) return false; /* unable to transmit character */ - pl011_write(c, uap, UART01x_DR); + pl011_write(c, uap, REG_DR); uap->port.icount.tx++; return true; @@ -1322,7 +1332,7 @@ static void pl011_modem_status(struct uart_amba_port *uap) { unsigned int status, delta; - status = pl011_read(uap, UART01x_FR) & UART01x_FR_MODEM_ANY; + status = pl011_read(uap, REG_FR) & UART01x_FR_MODEM_ANY; delta = status ^ uap->old_status; uap->old_status = status; @@ -1350,15 +1360,15 @@ static void check_apply_cts_event_workaround(struct uart_amba_port *uap) return; /* workaround to make sure that all bits are unlocked.. */ - pl011_write(0x00, uap, UART011_ICR); + pl011_write(0x00, uap, REG_ICR); /* * WA: introduce 26ns(1 uart clk) delay before W1C; * single apb access will incur 2 pclk(133.12Mhz) delay, * so add 2 dummy reads */ - dummy_read = pl011_read(uap, UART011_ICR); - dummy_read = pl011_read(uap, UART011_ICR); + dummy_read = pl011_read(uap, REG_ICR); + dummy_read = pl011_read(uap, REG_ICR); } static irqreturn_t pl011_int(int irq, void *dev_id) @@ -1370,15 +1380,15 @@ static irqreturn_t pl011_int(int irq, void *dev_id) int handled = 0; spin_lock_irqsave(&uap->port.lock, flags); - imsc = pl011_read(uap, UART011_IMSC); - status = pl011_read(uap, UART011_RIS) & imsc; + imsc = pl011_read(uap, REG_IMSC); + status = pl011_read(uap, REG_RIS) & imsc; if (status) { do { check_apply_cts_event_workaround(uap); pl011_write(status & ~(UART011_TXIS|UART011_RTIS| UART011_RXIS), - uap, UART011_ICR); + uap, REG_ICR); if (status & (UART011_RTIS|UART011_RXIS)) { if (pl011_dma_rx_running(uap)) @@ -1395,7 +1405,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id) if (pass_counter-- == 0) break; - status = pl011_read(uap, UART011_RIS) & imsc; + status = pl011_read(uap, REG_RIS) & imsc; } while (status != 0); handled = 1; } @@ -1409,7 +1419,7 @@ static unsigned int pl011_tx_empty(struct uart_port *port) { struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); - unsigned int status = pl011_read(uap, UART01x_FR); + unsigned int status = pl011_read(uap, REG_FR); return status & (UART01x_FR_BUSY|UART01x_FR_TXFF) ? 0 : TIOCSER_TEMT; } @@ -1418,7 +1428,7 @@ static unsigned int pl011_get_mctrl(struct uart_port *port) struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); unsigned int result = 0; - unsigned int status = pl011_read(uap, UART01x_FR); + unsigned int status = pl011_read(uap, REG_FR); #define TIOCMBIT(uartbit, tiocmbit) \ if (status & uartbit) \ @@ -1438,7 +1448,7 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) container_of(port, struct uart_amba_port, port); unsigned int cr; - cr = pl011_read(uap, UART011_CR); + cr = pl011_read(uap, REG_CR); #define TIOCMBIT(tiocmbit, uartbit) \ if (mctrl & tiocmbit) \ @@ -1458,7 +1468,7 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) } #undef TIOCMBIT - pl011_write(cr, uap, UART011_CR); + pl011_write(cr, uap, REG_CR); } static void pl011_break_ctl(struct uart_port *port, int break_state) @@ -1485,7 +1495,7 @@ static void pl011_quiesce_irqs(struct uart_port *port) struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); - pl011_write(pl011_read(uap, UART011_MIS), uap, UART011_ICR); + pl011_write(pl011_read(uap, REG_MIS), uap, REG_ICR); /* * There is no way to clear TXIM as this is "ready to transmit IRQ", so * we simply mask it. start_tx() will unmask it. @@ -1499,8 +1509,8 @@ static void pl011_quiesce_irqs(struct uart_port *port) * (including tx queue), so we're also fine with start_tx()'s caller * side. */ - pl011_write(pl011_read(uap, UART011_IMSC) & ~UART011_TXIM, uap, - UART011_IMSC); + pl011_write(pl011_read(uap, REG_IMSC) & ~UART011_TXIM, uap, + REG_IMSC); } static int pl011_get_poll_char(struct uart_port *port) @@ -1515,11 +1525,11 @@ static int pl011_get_poll_char(struct uart_port *port) */ pl011_quiesce_irqs(port); - status = pl011_read(uap, UART01x_FR); + status = pl011_read(uap, REG_FR); if (status & UART01x_FR_RXFE) return NO_POLL_CHAR; - return pl011_read(uap, UART01x_DR); + return pl011_read(uap, REG_DR); } static void pl011_put_poll_char(struct uart_port *port, @@ -1528,10 +1538,10 @@ static void pl011_put_poll_char(struct uart_port *port, struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); - while (pl011_read(uap, UART01x_FR) & UART01x_FR_TXFF) + while (pl011_read(uap, REG_FR) & UART01x_FR_TXFF) barrier(); - pl011_write(ch, uap, UART01x_DR); + pl011_write(ch, uap, REG_DR); } #endif /* CONFIG_CONSOLE_POLL */ @@ -1557,14 +1567,14 @@ static int pl011_hwinit(struct uart_port *port) /* Clear pending error and receive interrupts */ pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS | UART011_RTIS | UART011_RXIS, - uap, UART011_ICR); + uap, REG_ICR); /* * Save interrupts enable mask, and enable RX interrupts in case if * the interrupt is used for NMI entry. */ - uap->im = pl011_read(uap, UART011_IMSC); - pl011_write(UART011_RTIM | UART011_RXIM, uap, UART011_IMSC); + uap->im = pl011_read(uap, REG_IMSC); + pl011_write(UART011_RTIM | UART011_RXIM, uap, REG_IMSC); if (dev_get_platdata(uap->port.dev)) { struct amba_pl011_data *plat; @@ -1578,7 +1588,8 @@ static int pl011_hwinit(struct uart_port *port) static bool pl011_split_lcrh(const struct uart_amba_port *uap) { - return uap->lcrh_rx != uap->lcrh_tx; + return pl011_reg_to_offset(uap, uap->lcrh_rx) != + pl011_reg_to_offset(uap, uap->lcrh_tx); } static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h) @@ -1591,14 +1602,14 @@ static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h) * to get this delay write read only register 10 times */ for (i = 0; i < 10; ++i) - pl011_write(0xff, uap, UART011_MIS); + pl011_write(0xff, uap, REG_MIS); pl011_write(lcr_h, uap, uap->lcrh_tx); } } static int pl011_allocate_irq(struct uart_amba_port *uap) { - pl011_write(uap->im, uap, UART011_IMSC); + pl011_write(uap->im, uap, REG_IMSC); return request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap); } @@ -1613,11 +1624,11 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap) spin_lock_irq(&uap->port.lock); /* Clear out any spuriously appearing RX interrupts */ - pl011_write(UART011_RTIS | UART011_RXIS, uap, UART011_ICR); + pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR); uap->im = UART011_RTIM; if (!pl011_dma_rx_running(uap)) uap->im |= UART011_RXIM; - pl011_write(uap->im, uap, UART011_IMSC); + pl011_write(uap->im, uap, REG_IMSC); spin_unlock_irq(&uap->port.lock); } @@ -1636,21 +1647,21 @@ static int pl011_startup(struct uart_port *port) if (retval) goto clk_dis; - pl011_write(uap->vendor->ifls, uap, UART011_IFLS); + pl011_write(uap->vendor->ifls, uap, REG_IFLS); spin_lock_irq(&uap->port.lock); /* restore RTS and DTR */ cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR); cr |= UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; - pl011_write(cr, uap, UART011_CR); + pl011_write(cr, uap, REG_CR); spin_unlock_irq(&uap->port.lock); /* * initialise the old status of the modem signals */ - uap->old_status = pl011_read(uap, UART01x_FR) & UART01x_FR_MODEM_ANY; + uap->old_status = pl011_read(uap, REG_FR) & UART01x_FR_MODEM_ANY; /* Startup DMA */ pl011_dma_startup(uap); @@ -1707,11 +1718,11 @@ static void pl011_disable_uart(struct uart_amba_port *uap) uap->autorts = false; spin_lock_irq(&uap->port.lock); - cr = pl011_read(uap, UART011_CR); + cr = pl011_read(uap, REG_CR); uap->old_cr = cr; cr &= UART011_CR_RTS | UART011_CR_DTR; cr |= UART01x_CR_UARTEN | UART011_CR_TXE; - pl011_write(cr, uap, UART011_CR); + pl011_write(cr, uap, REG_CR); spin_unlock_irq(&uap->port.lock); /* @@ -1728,8 +1739,8 @@ static void pl011_disable_interrupts(struct uart_amba_port *uap) /* mask all interrupts and clear all pending ones */ uap->im = 0; - pl011_write(uap->im, uap, UART011_IMSC); - pl011_write(0xffff, uap, UART011_ICR); + pl011_write(uap->im, uap, REG_IMSC); + pl011_write(0xffff, uap, REG_ICR); spin_unlock_irq(&uap->port.lock); } @@ -1881,8 +1892,8 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, pl011_enable_ms(port); /* first, disable everything */ - old_cr = pl011_read(uap, UART011_CR); - pl011_write(0, uap, UART011_CR); + old_cr = pl011_read(uap, REG_CR); + pl011_write(0, uap, REG_CR); if (termios->c_cflag & CRTSCTS) { if (old_cr & UART011_CR_RTS) @@ -1915,17 +1926,17 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, quot -= 2; } /* Set baud rate */ - pl011_write(quot & 0x3f, uap, UART011_FBRD); - pl011_write(quot >> 6, uap, UART011_IBRD); + pl011_write(quot & 0x3f, uap, REG_FBRD); + pl011_write(quot >> 6, uap, REG_IBRD); /* * ----------v----------v----------v----------v----- * NOTE: lcrh_tx and lcrh_rx MUST BE WRITTEN AFTER - * UART011_FBRD & UART011_IBRD. + * REG_FBRD & REG_IBRD. * ----------^----------^----------^----------^----- */ pl011_write_lcr_h(uap, lcr_h); - pl011_write(old_cr, uap, UART011_CR); + pl011_write(old_cr, uap, REG_CR); spin_unlock_irqrestore(&port->lock, flags); } @@ -2066,9 +2077,9 @@ static void pl011_console_putchar(struct uart_port *port, int ch) struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); - while (pl011_read(uap, UART01x_FR) & UART01x_FR_TXFF) + while (pl011_read(uap, REG_FR) & UART01x_FR_TXFF) barrier(); - pl011_write(ch, uap, UART01x_DR); + pl011_write(ch, uap, REG_DR); } static void @@ -2093,10 +2104,10 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) * First save the CR then disable the interrupts */ if (!uap->vendor->always_enabled) { - old_cr = pl011_read(uap, UART011_CR); + old_cr = pl011_read(uap, REG_CR); new_cr = old_cr & ~UART011_CR_CTSEN; new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE; - pl011_write(new_cr, uap, UART011_CR); + pl011_write(new_cr, uap, REG_CR); } uart_console_write(&uap->port, s, count, pl011_console_putchar); @@ -2106,10 +2117,10 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) * and restore the TCR */ do { - status = pl011_read(uap, UART01x_FR); + status = pl011_read(uap, REG_FR); } while (status & UART01x_FR_BUSY); if (!uap->vendor->always_enabled) - pl011_write(old_cr, uap, UART011_CR); + pl011_write(old_cr, uap, REG_CR); if (locked) spin_unlock(&uap->port.lock); @@ -2122,7 +2133,7 @@ static void __init pl011_console_get_options(struct uart_amba_port *uap, int *baud, int *parity, int *bits) { - if (pl011_read(uap, UART011_CR) & UART01x_CR_UARTEN) { + if (pl011_read(uap, REG_CR) & UART01x_CR_UARTEN) { unsigned int lcr_h, ibrd, fbrd; lcr_h = pl011_read(uap, uap->lcrh_tx); @@ -2140,13 +2151,13 @@ pl011_console_get_options(struct uart_amba_port *uap, int *baud, else *bits = 8; - ibrd = pl011_read(uap, UART011_IBRD); - fbrd = pl011_read(uap, UART011_FBRD); + ibrd = pl011_read(uap, REG_IBRD); + fbrd = pl011_read(uap, REG_FBRD); *baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd); if (uap->vendor->oversampling) { - if (pl011_read(uap, UART011_CR) + if (pl011_read(uap, REG_CR) & ST_UART011_CR_OVSFACT) *baud *= 2; } @@ -2218,10 +2229,10 @@ static struct console amba_console = { static void pl011_putc(struct uart_port *port, int c) { - while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF) + while (readl(port->membase + REG_FR) & UART01x_FR_TXFF) ; - writeb(c, port->membase + UART01x_DR); - while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY) + writeb(c, port->membase + REG_DR); + while (readl(port->membase + REG_FR) & UART01x_FR_BUSY) ; } @@ -2348,8 +2359,8 @@ static int pl011_register_port(struct uart_amba_port *uap) int ret; /* Ensure interrupts from this UART are masked and cleared */ - pl011_write(0, uap, UART011_IMSC); - pl011_write(0xffff, uap, UART011_ICR); + pl011_write(0, uap, REG_IMSC); + pl011_write(0xffff, uap, REG_ICR); if (!amba_reg.state) { ret = uart_register_driver(&amba_reg); diff --git a/drivers/tty/serial/amba-pl011.h b/drivers/tty/serial/amba-pl011.h new file mode 100644 index 0000000000000..b7eb1bc2fab9b --- /dev/null +++ b/drivers/tty/serial/amba-pl011.h @@ -0,0 +1,32 @@ +#ifndef AMBA_PL011_H +#define AMBA_PL011_H + +enum { + REG_DR = UART01x_DR, + REG_ST_DMAWM = ST_UART011_DMAWM, + REG_ST_TIMEOUT = ST_UART011_TIMEOUT, + REG_FR = UART01x_FR, + REG_ST_LCRH_RX = ST_UART011_LCRH_RX, + REG_IBRD = UART011_IBRD, + REG_FBRD = UART011_FBRD, + REG_LCRH = UART011_LCRH, + REG_ST_LCRH_TX = ST_UART011_LCRH_TX, + REG_CR = UART011_CR, + REG_IFLS = UART011_IFLS, + REG_IMSC = UART011_IMSC, + REG_RIS = UART011_RIS, + REG_MIS = UART011_MIS, + REG_ICR = UART011_ICR, + REG_DMACR = UART011_DMACR, + REG_ST_XFCR = ST_UART011_XFCR, + REG_ST_XON1 = ST_UART011_XON1, + REG_ST_XON2 = ST_UART011_XON2, + REG_ST_XOFF1 = ST_UART011_XOFF1, + REG_ST_XOFF2 = ST_UART011_XOFF2, + REG_ST_ITCR = ST_UART011_ITCR, + REG_ST_ITIP = ST_UART011_ITIP, + REG_ST_ABCR = ST_UART011_ABCR, + REG_ST_ABIMSC = ST_UART011_ABIMSC, +}; + +#endif -- GitLab From 998b4a4571b87eb6795863e07683fa5d4e0398ba Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:08 -0500 Subject: [PATCH 1141/2855] tty: Improve tty_debug() macro Incorporate suggestions for tty core debug macro improvements - printk(KERN_DEBUG) => pr_debug() - ##args => ##__VA_ARGS__ - remove do {} while() - output tty_name() first cc: Joe Perches Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- include/linux/tty.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/include/linux/tty.h b/include/linux/tty.h index 5e31f1b99037d..3695c884258a1 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -667,10 +667,7 @@ static inline void proc_tty_register_driver(struct tty_driver *d) {} static inline void proc_tty_unregister_driver(struct tty_driver *d) {} #endif -#define tty_debug(tty, f, args...) \ - do { \ - printk(KERN_DEBUG "%s: %s: " f, __func__, \ - tty_name(tty), ##args); \ - } while (0) +#define tty_debug(tty, f, ...) \ + pr_debug("%s: %s: " f, tty_name(tty), __func__, ##__VA_ARGS__) #endif -- GitLab From 82b8f888e99c81c609710901d8defbc8eff13f79 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:09 -0500 Subject: [PATCH 1142/2855] tty: Make tty_paranoia_check() file scope tty_paranoia_check() is only used within drivers/tty/tty_io.c; remove extern declaration in header and limit symbol to file scope. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 2 +- include/linux/tty.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index bcc8e1e8bb720..adc0229f6b5d8 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -256,7 +256,7 @@ const char *tty_name(const struct tty_struct *tty) EXPORT_SYMBOL(tty_name); -int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, +static int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, const char *routine) { #ifdef TTY_PARANOIA_CHECK diff --git a/include/linux/tty.h b/include/linux/tty.h index 3695c884258a1..0532465ea1420 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -419,8 +419,6 @@ static inline struct tty_struct *tty_kref_get(struct tty_struct *tty) return tty; } -extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, - const char *routine); extern const char *tty_name(const struct tty_struct *tty); extern void tty_wait_until_sent(struct tty_struct *tty, long timeout); extern int __tty_check_change(struct tty_struct *tty, int sig); -- GitLab From 076fe30334557d69c8f11db1f3f192f4ae448686 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:10 -0500 Subject: [PATCH 1143/2855] tty: synclink_gt: Rename tty_driver_name Eliminate symbol name collision with new tty core function, tty_driver_name(). Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/synclink_gt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 6fc39fbfc2755..5505ea8421793 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -89,7 +89,7 @@ * module identification */ static char *driver_name = "SyncLink GT"; -static char *tty_driver_name = "synclink_gt"; +static char *slgt_driver_name = "synclink_gt"; static char *tty_dev_prefix = "ttySLG"; MODULE_LICENSE("GPL"); #define MGSL_MAGIC 0x5401 @@ -3799,7 +3799,7 @@ static int __init slgt_init(void) /* Initialize the tty_driver structure */ - serial_driver->driver_name = tty_driver_name; + serial_driver->driver_name = slgt_driver_name; serial_driver->name = tty_dev_prefix; serial_driver->major = ttymajor; serial_driver->minor_start = 64; -- GitLab From 25080652a2d4a6d27a51fc1412e258f467174615 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:11 -0500 Subject: [PATCH 1144/2855] tty: core: Remove redundant oom message kmalloc() already emits a diagnostic for failed allocations; remove tty-specific message. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index adc0229f6b5d8..336714cf370af 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1580,10 +1580,8 @@ void tty_free_termios(struct tty_struct *tty) tp = tty->driver->termios[idx]; if (tp == NULL) { tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); - if (tp == NULL) { - pr_warn("tty: no memory to save termios state.\n"); + if (tp == NULL) return; - } tty->driver->termios[idx] = tp; } *tp = tty->termios; -- GitLab From 0a083eddae33b6e20234d05a9cf54f87b0095511 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:12 -0500 Subject: [PATCH 1145/2855] tty: core: Add helper fn to deref tty driver name Similar to tty_name(), add tty_driver_name() helper to safely dereference tty->driver->name (otherwise return empty string). Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 7 +++++++ include/linux/tty.h | 1 + 2 files changed, 8 insertions(+) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 336714cf370af..ef8ee34670c32 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -256,6 +256,13 @@ const char *tty_name(const struct tty_struct *tty) EXPORT_SYMBOL(tty_name); +const char *tty_driver_name(const struct tty_struct *tty) +{ + if (!tty || !tty->driver) + return ""; + return tty->driver->name; +} + static int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, const char *routine) { diff --git a/include/linux/tty.h b/include/linux/tty.h index 0532465ea1420..a9c1af990da96 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -420,6 +420,7 @@ static inline struct tty_struct *tty_kref_get(struct tty_struct *tty) } extern const char *tty_name(const struct tty_struct *tty); +extern const char *tty_driver_name(const struct tty_struct *tty); extern void tty_wait_until_sent(struct tty_struct *tty, long timeout); extern int __tty_check_change(struct tty_struct *tty, int sig); extern int tty_check_change(struct tty_struct *tty); -- GitLab From 339f36ba14cf9f8fcf6e6b78385bd6811ec59fbe Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:13 -0500 Subject: [PATCH 1146/2855] tty: Define tty_*() printk macros Since not all ttys are devices (eg., SysV ptys), dev_*() printk macros cannot be used. Define tty_*() printk macros that output in similar format to dev_*() macros (ie., : .....). Transform the most-trivial printk( LEVEL ...) usage to tty_*() usage. NB: The function name has been eliminated from messages with unique context, or prefixed to the format when given. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 7 ++----- drivers/tty/tty_io.c | 27 ++++++++++----------------- drivers/tty/tty_port.c | 9 ++++----- include/linux/tty.h | 12 +++++++++++- 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index ed776149261ea..c37c15d2f782e 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1201,9 +1201,7 @@ static void n_tty_receive_overrun(struct tty_struct *tty) ldata->num_overrun++; if (time_after(jiffies, ldata->overrun_time + HZ) || time_after(ldata->overrun_time, jiffies)) { - printk(KERN_WARNING "%s: %d input overrun(s)\n", - tty_name(tty), - ldata->num_overrun); + tty_warn(tty, "%d input overrun(s)\n", ldata->num_overrun); ldata->overrun_time = jiffies; ldata->num_overrun = 0; } @@ -1486,8 +1484,7 @@ n_tty_receive_char_flagged(struct tty_struct *tty, unsigned char c, char flag) n_tty_receive_overrun(tty); break; default: - printk(KERN_ERR "%s: unknown flag %d\n", - tty_name(tty), flag); + tty_err(tty, "unknown flag %d\n", flag); break; } } diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index ef8ee34670c32..c9d3989b1f14e 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -300,9 +300,8 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) tty->link && tty->link->count) count++; if (tty->count != count) { - printk(KERN_WARNING "Warning: dev (%s) tty->count(%d) " - "!= #fd's(%d) in %s\n", - tty->name, tty->count, count, routine); + tty_warn(tty, "%s: tty->count(%d) != #fd's(%d)\n", + routine, tty->count, count); return count; } #endif @@ -427,10 +426,8 @@ int __tty_check_change(struct tty_struct *tty, int sig) } rcu_read_unlock(); - if (!tty_pgrp) { - pr_warn("%s: tty_check_change: sig=%d, tty->pgrp == NULL!\n", - tty_name(tty), sig); - } + if (!tty_pgrp) + tty_warn(tty, "sig=%d, tty->pgrp == NULL!\n", sig); return ret; } @@ -1246,8 +1243,7 @@ static ssize_t tty_write(struct file *file, const char __user *buf, return -EIO; /* Short term debug to catch buggy drivers */ if (tty->ops->write_room == NULL) - printk(KERN_ERR "tty driver %s lacks a write_room method.\n", - tty->driver->name); + tty_err(tty, "missing write_room method\n"); ld = tty_ldisc_ref_wait(tty); if (!ld->ops->write) ret = -EIO; @@ -1568,8 +1564,8 @@ err_module_put: /* call the tty release_tty routine to clean out this slot */ err_release_tty: tty_unlock(tty); - printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " - "clearing slot %d\n", idx); + tty_info_ratelimited(tty, "ldisc open failed (%d), clearing slot %d\n", + retval, idx); release_tty(tty, idx); return ERR_PTR(retval); } @@ -1842,8 +1838,7 @@ int tty_release(struct inode *inode, struct file *filp) if (once) { once = 0; - printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", - __func__, tty_name(tty)); + tty_warn(tty, "read/write wait queue active!\n"); } schedule_timeout_killable(timeout); if (timeout < 120 * HZ) @@ -1854,14 +1849,12 @@ int tty_release(struct inode *inode, struct file *filp) if (o_tty) { if (--o_tty->count < 0) { - printk(KERN_WARNING "%s: bad pty slave count (%d) for %s\n", - __func__, o_tty->count, tty_name(o_tty)); + tty_warn(tty, "bad slave count (%d)\n", o_tty->count); o_tty->count = 0; } } if (--tty->count < 0) { - printk(KERN_WARNING "%s: bad tty->count (%d) for %s\n", - __func__, tty->count, tty_name(tty)); + tty_warn(tty, "bad tty->count (%d)\n", tty->count); tty->count = 0; } diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 482f33f200433..846ed481c24fe 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -462,14 +462,13 @@ int tty_port_close_start(struct tty_port *port, spin_lock_irqsave(&port->lock, flags); if (tty->count == 1 && port->count != 1) { - printk(KERN_WARNING - "tty_port_close_start: tty->count = 1 port count = %d.\n", - port->count); + tty_warn(tty, "%s: tty->count = 1 port count = %d\n", __func__, + port->count); port->count = 1; } if (--port->count < 0) { - printk(KERN_WARNING "tty_port_close_start: count = %d\n", - port->count); + tty_warn(tty, "%s: bad port count (%d)\n", __func__, + port->count); port->count = 0; } diff --git a/include/linux/tty.h b/include/linux/tty.h index a9c1af990da96..f578e8405ff00 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -666,7 +666,17 @@ static inline void proc_tty_register_driver(struct tty_driver *d) {} static inline void proc_tty_unregister_driver(struct tty_driver *d) {} #endif +#define tty_msg(fn, tty, f, ...) \ + fn("%s %s: " f, tty_driver_name(tty), tty_name(tty), ##__VA_ARGS__) + #define tty_debug(tty, f, ...) \ - pr_debug("%s: %s: " f, tty_name(tty), __func__, ##__VA_ARGS__) + tty_msg(pr_debug, tty, "%s:" f, __func__, ##__VA_ARGS__) +#define tty_info(tty, f, ...) tty_msg(pr_info, tty, f, ##__VA_ARGS__) +#define tty_notice(tty, f, ...) tty_msg(pr_notice, tty, f, ##__VA_ARGS__) +#define tty_warn(tty, f, ...) tty_msg(pr_warn, tty, f, ##__VA_ARGS__) +#define tty_err(tty, f, ...) tty_msg(pr_err, tty, f, ##__VA_ARGS__) + +#define tty_info_ratelimited(tty, f, ...) \ + tty_msg(pr_info_ratelimited, tty, f, ##__VA_ARGS__) #endif -- GitLab From 9b42bb750f24f5925d2fffed3f071726af72763a Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:14 -0500 Subject: [PATCH 1147/2855] tty: Convert SAK messages to tty_notice() Use tty_notice() for unified message format from the tty core. Fix each message to accurately reflect the cause of each termination. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index c9d3989b1f14e..b64cd64a05636 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3026,28 +3026,24 @@ void __do_SAK(struct tty_struct *tty) read_lock(&tasklist_lock); /* Kill the entire session */ do_each_pid_task(session, PIDTYPE_SID, p) { - printk(KERN_NOTICE "SAK: killed process %d" - " (%s): task_session(p)==tty->session\n", - task_pid_nr(p), p->comm); + tty_notice(tty, "SAK: killed process %d (%s): by session\n", + task_pid_nr(p), p->comm); send_sig(SIGKILL, p, 1); } while_each_pid_task(session, PIDTYPE_SID, p); - /* Now kill any processes that happen to have the - * tty open. - */ + + /* Now kill any processes that happen to have the tty open */ do_each_thread(g, p) { if (p->signal->tty == tty) { - printk(KERN_NOTICE "SAK: killed process %d" - " (%s): task_session(p)==tty->session\n", - task_pid_nr(p), p->comm); + tty_notice(tty, "SAK: killed process %d (%s): by controlling tty\n", + task_pid_nr(p), p->comm); send_sig(SIGKILL, p, 1); continue; } task_lock(p); i = iterate_fd(p->files, 0, this_tty, tty); if (i != 0) { - printk(KERN_NOTICE "SAK: killed process %d" - " (%s): fd#%d opened to the tty\n", - task_pid_nr(p), p->comm, i - 1); + tty_notice(tty, "SAK: killed process %d (%s): by fd#%d\n", + task_pid_nr(p), p->comm, i - 1); force_sig(SIGKILL, p); } task_unlock(p); -- GitLab From 656fb86770cffe25d002e1228931960219ccda6b Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:15 -0500 Subject: [PATCH 1148/2855] tty: core: Add driver name to invalid device registration message Include the driver name in the tty_register_device_attr() error message for invalid index. Note that tty_err() cannot be used here because there is no tty; use pr_err(). Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index b64cd64a05636..86e379a38219a 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3249,8 +3249,8 @@ struct device *tty_register_device_attr(struct tty_driver *driver, bool cdev = false; if (index >= driver->num) { - printk(KERN_ERR "Attempt to register invalid tty line number " - " (%d).\n", index); + pr_err("%s: Attempt to register invalid tty line number (%d)\n", + driver->name, index); return ERR_PTR(-EINVAL); } -- GitLab From d97ba9cdae73a69944c6051622c08bfa9016320e Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:16 -0500 Subject: [PATCH 1149/2855] tty: core: Refactor parameters for unset_locked_termios() helper Add tty as parameter to unset_locked_termios() and extract former parameters, termios and locked, as locals. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ioctl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 1445dd39aa622..b41c7089bfb25 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -239,10 +239,10 @@ EXPORT_SYMBOL(tty_wait_until_sent); * Termios Helper Methods */ -static void unset_locked_termios(struct ktermios *termios, - struct ktermios *old, - struct ktermios *locked) +static void unset_locked_termios(struct tty_struct *tty, struct ktermios *old) { + struct ktermios *termios = &tty->termios; + struct ktermios *locked = &tty->termios_locked; int i; #define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z))) @@ -556,7 +556,7 @@ int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios) down_write(&tty->termios_rwsem); old_termios = tty->termios; tty->termios = *new_termios; - unset_locked_termios(&tty->termios, &old_termios, &tty->termios_locked); + unset_locked_termios(tty, &old_termios); if (tty->ops->set_termios) tty->ops->set_termios(tty, &old_termios); -- GitLab From f658dca95075e0b6823650968edad68538494ab8 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:17 -0500 Subject: [PATCH 1150/2855] tty: Remove unset_locked_termios() error message With the refactor of 'locked' from parameter to local, it's now obvious locked cannot be NULL. Remove entire conditional. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ioctl.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index b41c7089bfb25..e54879d1e6769 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -247,11 +247,6 @@ static void unset_locked_termios(struct tty_struct *tty, struct ktermios *old) #define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z))) - if (!locked) { - printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n"); - return; - } - NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag); NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag); NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag); -- GitLab From 89222e62662237faee90cd8486d23350f26b181d Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:18 -0500 Subject: [PATCH 1151/2855] tty: core: Prefer pr_* to printk(*) Convert remaining printk() use to pr_*() when tty is unknown or unsafe to use. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 6 ++---- drivers/tty/tty_ioctl.c | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 86e379a38219a..d9df15f1086b0 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -268,14 +268,12 @@ static int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, { #ifdef TTY_PARANOIA_CHECK if (!tty) { - printk(KERN_WARNING - "null TTY for (%d:%d) in %s\n", + pr_warn("(%d:%d): %s: NULL tty\n", imajor(inode), iminor(inode), routine); return 1; } if (tty->magic != TTY_MAGIC) { - printk(KERN_WARNING - "bad magic number for tty struct (%d:%d) in %s\n", + pr_warn("(%d:%d): %s: bad magic number\n", imajor(inode), iminor(inode), routine); return 1; } diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index e54879d1e6769..40964eaf115fd 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -458,10 +458,8 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, if (ifound == -1 && (ibaud != obaud || ibinput)) termios->c_cflag |= (BOTHER << IBSHIFT); #else - if (ifound == -1 || ofound == -1) { - printk_once(KERN_WARNING "tty: Unable to return correct " - "speed data as your architecture needs updating.\n"); - } + if (ifound == -1 || ofound == -1) + pr_warn_once("tty: Unable to return correct speed data as your architecture needs updating.\n"); #endif } EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate); -- GitLab From d435cefe9cbc9308cac8d4b19069a572e2bd1558 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:19 -0500 Subject: [PATCH 1152/2855] tty: Remove __func__ from tty_debug() macro Now that tty_debug() macro uses pr_debug(), the function name can be printed when using dynamic debug; printing the function name within the format string is redundant. Remove the __func__ parameter and print specifier from the format string. Add context to messages for when the function name is not printed by dynamic debug, or when dynamic debug is not enabled. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 2 +- drivers/tty/tty_io.c | 14 +++++++------- drivers/tty/tty_ioctl.c | 2 +- include/linux/tty.h | 3 +-- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index a45660f62db54..b3110040164ae 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -788,7 +788,7 @@ static int ptmx_open(struct inode *inode, struct file *filp) if (retval) goto err_release; - tty_debug_hangup(tty, "(tty count=%d)\n", tty->count); + tty_debug_hangup(tty, "opening (count=%d)\n", tty->count); tty_unlock(tty); return 0; diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index d9df15f1086b0..f8e1fce9bdfd3 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -783,7 +783,7 @@ static void do_tty_hangup(struct work_struct *work) void tty_hangup(struct tty_struct *tty) { - tty_debug_hangup(tty, "\n"); + tty_debug_hangup(tty, "hangup\n"); schedule_work(&tty->hangup_work); } @@ -800,7 +800,7 @@ EXPORT_SYMBOL(tty_hangup); void tty_vhangup(struct tty_struct *tty) { - tty_debug_hangup(tty, "\n"); + tty_debug_hangup(tty, "vhangup\n"); __tty_hangup(tty, 0); } @@ -837,7 +837,7 @@ void tty_vhangup_self(void) static void tty_vhangup_session(struct tty_struct *tty) { - tty_debug_hangup(tty, "\n"); + tty_debug_hangup(tty, "session hangup\n"); __tty_hangup(tty, 1); } @@ -1787,7 +1787,7 @@ int tty_release(struct inode *inode, struct file *filp) return 0; } - tty_debug_hangup(tty, "(tty count=%d)...\n", tty->count); + tty_debug_hangup(tty, "releasing (count=%d)\n", tty->count); if (tty->ops->close) tty->ops->close(tty, filp); @@ -1903,7 +1903,7 @@ int tty_release(struct inode *inode, struct file *filp) /* Wait for pending work before tty destruction commmences */ tty_flush_works(tty); - tty_debug_hangup(tty, "freeing structure...\n"); + tty_debug_hangup(tty, "freeing structure\n"); /* * The release_tty function takes care of the details of clearing * the slots and preserving the termios structure. The tty_unlock_pair @@ -2093,7 +2093,7 @@ retry_open: tty->driver->subtype == PTY_TYPE_MASTER) noctty = 1; - tty_debug_hangup(tty, "(tty count=%d)\n", tty->count); + tty_debug_hangup(tty, "opening (count=%d)\n", tty->count); if (tty->ops->open) retval = tty->ops->open(tty, filp); @@ -2102,7 +2102,7 @@ retry_open: filp->f_flags = saved_flags; if (retval) { - tty_debug_hangup(tty, "error %d, releasing...\n", retval); + tty_debug_hangup(tty, "open error %d, releasing\n", retval); tty_unlock(tty); /* need to call tty_release without BTM */ tty_release(inode, filp); diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 40964eaf115fd..0ea351388724a 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -216,7 +216,7 @@ int tty_unthrottle_safe(struct tty_struct *tty) void tty_wait_until_sent(struct tty_struct *tty, long timeout) { - tty_debug_wait_until_sent(tty, "\n"); + tty_debug_wait_until_sent(tty, "wait until sent, timeout=%ld\n", timeout); if (!timeout) timeout = MAX_SCHEDULE_TIMEOUT; diff --git a/include/linux/tty.h b/include/linux/tty.h index f578e8405ff00..f06dd7a41a030 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -669,8 +669,7 @@ static inline void proc_tty_unregister_driver(struct tty_driver *d) {} #define tty_msg(fn, tty, f, ...) \ fn("%s %s: " f, tty_driver_name(tty), tty_name(tty), ##__VA_ARGS__) -#define tty_debug(tty, f, ...) \ - tty_msg(pr_debug, tty, "%s:" f, __func__, ##__VA_ARGS__) +#define tty_debug(tty, f, ...) tty_msg(pr_debug, tty, f, ##__VA_ARGS__) #define tty_info(tty, f, ...) tty_msg(pr_info, tty, f, ##__VA_ARGS__) #define tty_notice(tty, f, ...) tty_msg(pr_notice, tty, f, ##__VA_ARGS__) #define tty_warn(tty, f, ...) tty_msg(pr_warn, tty, f, ##__VA_ARGS__) -- GitLab From 6d029c68de1219ed791b484d0d289562a51520c7 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:20 -0500 Subject: [PATCH 1153/2855] tty: Merge conditional + error message + WARN_ON() WARN() does all of these things in one statement. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_mutex.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c index 0efcf713b756e..77703a3912075 100644 --- a/drivers/tty/tty_mutex.c +++ b/drivers/tty/tty_mutex.c @@ -12,11 +12,8 @@ void __lockfunc tty_lock(struct tty_struct *tty) { - if (tty->magic != TTY_MAGIC) { - pr_err("L Bad %p\n", tty); - WARN_ON(1); + if (WARN(tty->magic != TTY_MAGIC, "L Bad %p\n", tty)) return; - } tty_kref_get(tty); mutex_lock(&tty->legacy_mutex); } @@ -24,11 +21,8 @@ EXPORT_SYMBOL(tty_lock); void __lockfunc tty_unlock(struct tty_struct *tty) { - if (tty->magic != TTY_MAGIC) { - pr_err("U Bad %p\n", tty); - WARN_ON(1); + if (WARN(tty->magic != TTY_MAGIC, "U Bad %p\n", tty)) return; - } mutex_unlock(&tty->legacy_mutex); tty_kref_put(tty); } -- GitLab From 83db1df4461c8731a413cd6cb1cbf351f01a57b1 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:21 -0500 Subject: [PATCH 1154/2855] tty: core: Prefer dev_dbg() over pr_debug() Where possible, use dev_dbg() instead of pr_debug() Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index f8e1fce9bdfd3..f38ae01c3917f 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3211,7 +3211,7 @@ EXPORT_SYMBOL(tty_register_device); static void tty_device_create_release(struct device *dev) { - pr_debug("device: '%s': %s\n", dev_name(dev), __func__); + dev_dbg(dev, "releasing...\n"); kfree(dev); } -- GitLab From d1d3a0f7448fe038ce7e94e2c281dcd2f91b23c6 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 09:06:05 -0500 Subject: [PATCH 1155/2855] tty: Only allow slave pty as controlling tty A master pty should never be a controlling tty in Linux; if the master pty is specified to ioctl(TIOCSCTTY), silently substitute the slave pty as the controlling tty. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index f38ae01c3917f..892c923547450 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2866,7 +2866,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) no_tty(); return 0; case TIOCSCTTY: - return tiocsctty(tty, file, arg); + return tiocsctty(real_tty, file, arg); case TIOCGPGRP: return tiocgpgrp(tty, real_tty, p); case TIOCSPGRP: -- GitLab From 4de91ebcc788f81d2a974d91208f5560ddf36378 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 09:18:31 -0500 Subject: [PATCH 1156/2855] tty: Remove dead tty_write_flush() declaration and macro tty_write_flush() has no definition and the TTY_WRITE_FLUSH() macro is never invoked; remove. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- include/linux/tty.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/linux/tty.h b/include/linux/tty.h index f06dd7a41a030..2fd8708ea8889 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -345,8 +345,6 @@ struct tty_file_private { #define TTY_HUPPED 18 /* Post driver->hangup() */ #define TTY_LDISC_HALTED 22 /* Line discipline is halted */ -#define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) - /* Values for tty->flow_change */ #define TTY_THROTTLE_SAFE 1 #define TTY_UNTHROTTLE_SAFE 2 @@ -395,8 +393,6 @@ static inline int __init tty_init(void) { return 0; } #endif -extern void tty_write_flush(struct tty_struct *); - extern struct ktermios tty_std_termios; extern int vcs_init(void); -- GitLab From 5841fc4b136b8dbab551749d2b12d71628f34635 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 09:18:32 -0500 Subject: [PATCH 1157/2855] tty: Remove unused SERIAL_DO_RESTART define SERIAL_DO_RESTART is not used by these 3 drivers; remove. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/amiserial.c | 1 - drivers/tty/moxa.c | 1 - drivers/tty/serial/icom.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index e53d9a512c6dd..2caaf5a2516d3 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -32,7 +32,6 @@ #include #undef SERIAL_PARANOIA_CHECK -#define SERIAL_DO_RESTART /* Set of debugging defines */ diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 14c54e0410650..92982d7c04894 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -155,7 +155,6 @@ struct mon_str { #define LOWWAIT 2 #define EMPTYWAIT 3 -#define SERIAL_DO_RESTART #define WAKEUP_CHARS 256 diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index ffc7cb2585a6d..c60a8d5e40201 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c @@ -22,7 +22,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#define SERIAL_DO_RESTART #include #include #include -- GitLab From 63d8cb3f19dabb409a09b4f2b8827934ab9365a3 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 09:29:38 -0500 Subject: [PATCH 1158/2855] tty: Simplify tty_set_ldisc() exit handling Perform common exit for both successful and error exit handling in tty_set_ldisc(). Fixes unlikely possibility of failing to restart input kworker when switching to the same line discipline (noop case). Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 42 +++++++++++++---------------------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 7d43ff12f6e20..9ec1250463436 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -529,34 +529,21 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) tty_lock(tty); retval = tty_ldisc_lock(tty, 5 * HZ); - if (retval) { - tty_ldisc_put(new_ldisc); - tty_unlock(tty); - return retval; - } + if (retval) + goto err; - /* - * Check the no-op case - */ + /* Check the no-op case */ + if (tty->ldisc->ops->num == ldisc) + goto out; - if (tty->ldisc->ops->num == ldisc) { - tty_ldisc_unlock(tty); - tty_ldisc_put(new_ldisc); - tty_unlock(tty); - return 0; + if (test_bit(TTY_HUPPED, &tty->flags)) { + /* We were raced by hangup */ + retval = -EIO; + goto out; } old_ldisc = tty->ldisc; - if (test_bit(TTY_HUPPED, &tty->flags)) { - /* We were raced by the hangup method. It will have stomped - the ldisc data and closed the ldisc down */ - tty_ldisc_unlock(tty); - tty_ldisc_put(new_ldisc); - tty_unlock(tty); - return -EIO; - } - /* Shutdown the old discipline. */ tty_ldisc_close(tty, old_ldisc); @@ -582,18 +569,15 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) the old ldisc (if it was restored as part of error cleanup above). In either case, releasing a single reference from the old ldisc is correct. */ - - tty_ldisc_put(old_ldisc); - - /* - * Allow ldisc referencing to occur again - */ + new_ldisc = old_ldisc; +out: tty_ldisc_unlock(tty); /* Restart the work queue in case no characters kick it off. Safe if already running */ tty_buffer_restart_work(tty->port); - +err: + tty_ldisc_put(new_ldisc); /* drop the extra reference */ tty_unlock(tty); return retval; } -- GitLab From ed7a85045d0a0688a51bdab9e1a1d6ee79cb33b6 Mon Sep 17 00:00:00 2001 From: Florian Achleitner Date: Wed, 18 Nov 2015 09:04:12 +0100 Subject: [PATCH 1159/2855] sc16is7xx: Fix TX buffer overrun caused by wrong tx fifo level read-out We found that our sc16is7xx on spi reported a TX fifo free space value (TXLVL_REG) of 255 ocassionally, which is obviously wrong, with a 64 byte fifo and caused a buffer overrun and a kernel crash. To trigger this, a large write to the tty is sufficient. The fifo fills, TXLVL_REG reads zero, but the handle_tx function does a zero-data-length write to the TX fifo anyways through sc16is7xx_fifo_write. The next TXLVL_REG read then yields 255, for unknown reasons. A subsequent read is ok. Prevent zero-data-length writes if the TX fifo is full, because they are pointless, and because they trigger wrong TXLVL read-outs. Furthermore, prevent a TX buffer overrun if the peripheral reports values larger than the buffer size and thus, don't allow the peripheral to crash the kernel. Signed-off-by: Florian Achleitner Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sc16is7xx.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index edb5305b9d4da..5815bcbc55b2a 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -389,6 +389,13 @@ static void sc16is7xx_fifo_write(struct uart_port *port, u8 to_send) const u8 line = sc16is7xx_line(port); u8 addr = (SC16IS7XX_THR_REG << SC16IS7XX_REG_SHIFT) | line; + /* + * Don't send zero-length data, at least on SPI it confuses the chip + * delivering wrong TXLVL data. + */ + if (unlikely(!to_send)) + return; + regcache_cache_bypass(s->regmap, true); regmap_raw_write(s->regmap, addr, s->buf, to_send); regcache_cache_bypass(s->regmap, false); @@ -630,6 +637,12 @@ static void sc16is7xx_handle_tx(struct uart_port *port) if (likely(to_send)) { /* Limit to size of TX FIFO */ txlen = sc16is7xx_port_read(port, SC16IS7XX_TXLVL_REG); + if (txlen > SC16IS7XX_FIFO_SIZE) { + dev_err_ratelimited(port->dev, + "chip reports %d free bytes in TX fifo, but it only has %d", + txlen, SC16IS7XX_FIFO_SIZE); + txlen = 0; + } to_send = (to_send > txlen) ? txlen : to_send; /* Add data to send */ -- GitLab From 55fe84b17a8f9c7a3cdfbfefdb519311aa6ff1da Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 9 Nov 2015 10:31:14 +0100 Subject: [PATCH 1160/2855] serial: SERIAL_ATMEL should depend on HAS_DMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If NO_DMA=y: drivers/built-in.o: In function `atmel_release_rx_dma': atmel_serial.c:(.text+0x2502e): undefined reference to `dma_unmap_sg' drivers/built-in.o: In function `atmel_release_tx_dma': atmel_serial.c:(.text+0x25080): undefined reference to `dma_unmap_sg' drivers/built-in.o: In function `atmel_tx_dma': atmel_serial.c:(.text+0x2517a): undefined reference to `dma_sync_sg_for_cpu' drivers/built-in.o: In function `atmel_release_tx_pdc': atmel_serial.c:(.text+0x252e6): undefined reference to `dma_unmap_single' drivers/built-in.o: In function `atmel_prepare_tx_pdc': atmel_serial.c:(.text+0x2531a): undefined reference to `dma_map_single' drivers/built-in.o: In function `atmel_release_rx_pdc': atmel_serial.c:(.text+0x25362): undefined reference to `dma_unmap_single' drivers/built-in.o: In function `atmel_tx_pdc': atmel_serial.c:(.text+0x25722): undefined reference to `dma_sync_single_for_cpu' drivers/built-in.o: In function `atmel_rx_from_pdc': atmel_serial.c:(.text+0x2601a): undefined reference to `dma_sync_single_for_cpu' drivers/built-in.o: In function `atmel_rx_from_dma': atmel_serial.c:(.text+0x261b2): undefined reference to `dma_sync_sg_for_cpu' atmel_serial.c:(.text+0x26264): undefined reference to `dma_sync_sg_for_cpu' drivers/built-in.o: In function `atmel_prepare_rx_pdc': atmel_serial.c:(.text+0x262de): undefined reference to `dma_unmap_single' atmel_serial.c:(.text+0x26308): undefined reference to `dma_map_single' Add a dependency on HAS_DMA to fix this. Signed-off-by: Geert Uytterhoeven Acked-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index f38beb28e7ae6..a1003eaa65d40 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -115,6 +115,7 @@ config SERIAL_SB1250_DUART_CONSOLE config SERIAL_ATMEL bool "AT91 / AT32 on-chip serial port support" + depends on HAS_DMA depends on ARCH_AT91 || AVR32 || COMPILE_TEST select SERIAL_CORE select SERIAL_MCTRL_GPIO if GPIOLIB -- GitLab From f8032cb4f574c0de5ac1d65d61e972957e6f1631 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 9 Nov 2015 10:31:15 +0100 Subject: [PATCH 1161/2855] serial: SERIAL_IMX_AUART should depend on HAS_DMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If NO_DMA=y: ERROR: "dma_unmap_sg" [drivers/tty/serial/imx.ko] undefined! ERROR: "dma_map_sg" [drivers/tty/serial/imx.ko] undefined! Add a dependency on HAS_DMA to fix this. Signed-off-by: Geert Uytterhoeven Acked-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index a1003eaa65d40..1ec4764f9b058 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -572,6 +572,7 @@ config BFIN_UART3_CTSRTS config SERIAL_IMX tristate "IMX serial port support" + depends on HAS_DMA depends on ARCH_MXC || COMPILE_TEST select SERIAL_CORE select RATIONAL -- GitLab From 29647c483658f1e3d2e0ec9ad64ebd23edeecdf5 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 9 Nov 2015 10:31:16 +0100 Subject: [PATCH 1162/2855] serial: SERIAL_MXS_AUART should depend on HAS_DMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If NO_DMA=y: ERROR: "dma_unmap_sg" [drivers/tty/serial/mxs-auart.ko] undefined! ERROR: "dma_map_sg" [drivers/tty/serial/mxs-auart.ko] undefined! Add a dependency on HAS_DMA to fix this. Signed-off-by: Geert Uytterhoeven Acked-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 1ec4764f9b058..f0bbedf61caec 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1411,8 +1411,9 @@ config SERIAL_PCH_UART_CONSOLE warnings and which allows logins in single user mode). config SERIAL_MXS_AUART - depends on ARCH_MXS || COMPILE_TEST tristate "MXS AUART support" + depends on HAS_DMA + depends on ARCH_MXS || COMPILE_TEST select SERIAL_CORE select SERIAL_MCTRL_GPIO if GPIOLIB help -- GitLab From 3ac4ae4736d404c436edf3b2ecfd941368f9e247 Mon Sep 17 00:00:00 2001 From: DengChao Date: Thu, 12 Nov 2015 21:45:47 +0800 Subject: [PATCH 1163/2855] serial:bfin-uart:Remove 'struct timeval' The bfin-uart code uses real time with struct timeval. This will cause problems on 32-bit architectures in 2038 when time_t overflows. Since the code just needs delta value of time, it is not necessary to record them in real time. This patch changes the code to use the monotonic time instead, replaces struct timeval and do_gettimeofday() with u64 and ktime_get_ns(). Signed-off-by: DengChao Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/bfin_uart.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index ae3cf94b146b0..293ecbb00684c 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c @@ -213,7 +213,7 @@ static void bfin_serial_stop_rx(struct uart_port *port) static void bfin_serial_rx_chars(struct bfin_serial_port *uart) { unsigned int status, ch, flg; - static struct timeval anomaly_start = { .tv_sec = 0 }; + static u64 anomaly_start; status = UART_GET_LSR(uart); UART_CLEAR_LSR(uart); @@ -246,27 +246,24 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) * character time +/- some percent. So 1.5 sounds good. All other * Blackfin families operate properly. Woo. */ - if (anomaly_start.tv_sec) { - struct timeval curr; - suseconds_t usecs; + if (anomaly_start > 0) { + u64 curr, nsecs, threshold_ns; if ((~ch & (~ch + 1)) & 0xff) goto known_good_char; - do_gettimeofday(&curr); - if (curr.tv_sec - anomaly_start.tv_sec > 1) + curr = ktime_get_ns(); + nsecs = curr - anomaly_start; + if (nsecs >> 32) goto known_good_char; - usecs = 0; - if (curr.tv_sec != anomaly_start.tv_sec) - usecs += USEC_PER_SEC; - usecs += curr.tv_usec - anomaly_start.tv_usec; - - if (usecs > UART_GET_ANOMALY_THRESHOLD(uart)) + threshold_ns = UART_GET_ANOMALY_THRESHOLD(uart) + * NSEC_PER_USEC; + if (nsecs > threshold_ns) goto known_good_char; if (ch) - anomaly_start.tv_sec = 0; + anomaly_start = 0; else anomaly_start = curr; @@ -274,14 +271,14 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) known_good_char: status &= ~BI; - anomaly_start.tv_sec = 0; + anomaly_start = 0; } } if (status & BI) { if (ANOMALY_05000363) if (bfin_revid() < 5) - do_gettimeofday(&anomaly_start); + anomaly_start = ktime_get_ns(); uart->port.icount.brk++; if (uart_handle_break(&uart->port)) goto ignore_char; -- GitLab From d1b5c87fa8058a3f477ae05555916dd1cea934ad Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 16:48:12 +0100 Subject: [PATCH 1164/2855] serial: remove NWP serial support The NWP serial driver is no longer needed, as the two users of this hardware have migrated to a much faster generation hardware, see https://en.wikipedia.org/wiki/QPACE2 for the replacement. Signed-off-by: Arnd Bergmann Cc: Benjamin Krill Cc: linuxppc-dev@lists.ozlabs.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 19 +- drivers/tty/serial/Makefile | 1 - drivers/tty/serial/nwpserial.c | 477 ------------------------------- drivers/tty/serial/of_serial.c | 14 - include/linux/nwpserial.h | 18 -- include/uapi/linux/serial_core.h | 2 +- 6 files changed, 2 insertions(+), 529 deletions(-) delete mode 100644 drivers/tty/serial/nwpserial.c delete mode 100644 include/linux/nwpserial.h diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index f0bbedf61caec..643fc50bb741f 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1099,7 +1099,7 @@ config SERIAL_NETX_CONSOLE config SERIAL_OF_PLATFORM tristate "Serial port on Open Firmware platform bus" depends on OF - depends on SERIAL_8250 || SERIAL_OF_PLATFORM_NWPSERIAL + depends on SERIAL_8250 help If you have a PowerPC based system that has serial ports on a platform specific bus, you should enable this option. @@ -1133,23 +1133,6 @@ config SERIAL_OMAP_CONSOLE your boot loader about how to pass options to the kernel at boot time.) -config SERIAL_OF_PLATFORM_NWPSERIAL - tristate "NWP serial port driver" - depends on PPC_DCR - select SERIAL_OF_PLATFORM - select SERIAL_CORE_CONSOLE - select SERIAL_CORE - help - This driver supports the cell network processor nwp serial - device. - -config SERIAL_OF_PLATFORM_NWPSERIAL_CONSOLE - bool "Console on NWP serial port" - depends on SERIAL_OF_PLATFORM_NWPSERIAL=y - select SERIAL_CORE_CONSOLE - help - Support for Console on the NWP serial ports. - config SERIAL_LANTIQ bool "Lantiq serial driver" depends on LANTIQ diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 5ab41119b3dce..ee8893317433b 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -64,7 +64,6 @@ obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o obj-$(CONFIG_SERIAL_MSM) += msm_serial.o obj-$(CONFIG_SERIAL_NETX) += netx-serial.o obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o -obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o obj-$(CONFIG_SERIAL_KGDB_NMI) += kgdb_nmi.o obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o diff --git a/drivers/tty/serial/nwpserial.c b/drivers/tty/serial/nwpserial.c deleted file mode 100644 index 5da7622e88c30..0000000000000 --- a/drivers/tty/serial/nwpserial.c +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Serial Port driver for a NWP uart device - * - * Copyright (C) 2008 IBM Corp., Benjamin Krill - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NWPSERIAL_NR 2 - -#define NWPSERIAL_STATUS_RXVALID 0x1 -#define NWPSERIAL_STATUS_TXFULL 0x2 - -struct nwpserial_port { - struct uart_port port; - dcr_host_t dcr_host; - unsigned int ier; - unsigned int mcr; -}; - -static DEFINE_MUTEX(nwpserial_mutex); -static struct nwpserial_port nwpserial_ports[NWPSERIAL_NR]; - -static void wait_for_bits(struct nwpserial_port *up, int bits) -{ - unsigned int status, tmout = 10000; - - /* Wait up to 10ms for the character(s) to be sent. */ - do { - status = dcr_read(up->dcr_host, UART_LSR); - - if (--tmout == 0) - break; - udelay(1); - } while ((status & bits) != bits); -} - -#ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL_CONSOLE -static void nwpserial_console_putchar(struct uart_port *port, int c) -{ - struct nwpserial_port *up; - up = container_of(port, struct nwpserial_port, port); - /* check if tx buffer is full */ - wait_for_bits(up, UART_LSR_THRE); - dcr_write(up->dcr_host, UART_TX, c); - up->port.icount.tx++; -} - -static void -nwpserial_console_write(struct console *co, const char *s, unsigned int count) -{ - struct nwpserial_port *up = &nwpserial_ports[co->index]; - unsigned long flags; - int locked = 1; - - if (oops_in_progress) - locked = spin_trylock_irqsave(&up->port.lock, flags); - else - spin_lock_irqsave(&up->port.lock, flags); - - /* save and disable interrupt */ - up->ier = dcr_read(up->dcr_host, UART_IER); - dcr_write(up->dcr_host, UART_IER, up->ier & ~UART_IER_RDI); - - uart_console_write(&up->port, s, count, nwpserial_console_putchar); - - /* wait for transmitter to become empty */ - while ((dcr_read(up->dcr_host, UART_LSR) & UART_LSR_THRE) == 0) - cpu_relax(); - - /* restore interrupt state */ - dcr_write(up->dcr_host, UART_IER, up->ier); - - if (locked) - spin_unlock_irqrestore(&up->port.lock, flags); -} - -static struct uart_driver nwpserial_reg; -static struct console nwpserial_console = { - .name = "ttySQ", - .write = nwpserial_console_write, - .device = uart_console_device, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &nwpserial_reg, -}; -#define NWPSERIAL_CONSOLE (&nwpserial_console) -#else -#define NWPSERIAL_CONSOLE NULL -#endif /* CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL_CONSOLE */ - -/**************************************************************************/ - -static int nwpserial_request_port(struct uart_port *port) -{ - return 0; -} - -static void nwpserial_release_port(struct uart_port *port) -{ - /* N/A */ -} - -static void nwpserial_config_port(struct uart_port *port, int flags) -{ - port->type = PORT_NWPSERIAL; -} - -static irqreturn_t nwpserial_interrupt(int irq, void *dev_id) -{ - struct nwpserial_port *up = dev_id; - struct tty_port *port = &up->port.state->port; - irqreturn_t ret; - unsigned int iir; - unsigned char ch; - - spin_lock(&up->port.lock); - - /* check if the uart was the interrupt source. */ - iir = dcr_read(up->dcr_host, UART_IIR); - if (!iir) { - ret = IRQ_NONE; - goto out; - } - - do { - up->port.icount.rx++; - ch = dcr_read(up->dcr_host, UART_RX); - if (up->port.ignore_status_mask != NWPSERIAL_STATUS_RXVALID) - tty_insert_flip_char(port, ch, TTY_NORMAL); - } while (dcr_read(up->dcr_host, UART_LSR) & UART_LSR_DR); - - spin_unlock(&up->port.lock); - tty_flip_buffer_push(port); - spin_lock(&up->port.lock); - - ret = IRQ_HANDLED; - - /* clear interrupt */ - dcr_write(up->dcr_host, UART_IIR, 1); -out: - spin_unlock(&up->port.lock); - return ret; -} - -static int nwpserial_startup(struct uart_port *port) -{ - struct nwpserial_port *up; - int err; - - up = container_of(port, struct nwpserial_port, port); - - /* disable flow control by default */ - up->mcr = dcr_read(up->dcr_host, UART_MCR) & ~UART_MCR_AFE; - dcr_write(up->dcr_host, UART_MCR, up->mcr); - - /* register interrupt handler */ - err = request_irq(up->port.irq, nwpserial_interrupt, - IRQF_SHARED, "nwpserial", up); - if (err) - return err; - - /* enable interrupts */ - up->ier = UART_IER_RDI; - dcr_write(up->dcr_host, UART_IER, up->ier); - - /* enable receiving */ - up->port.ignore_status_mask &= ~NWPSERIAL_STATUS_RXVALID; - - return 0; -} - -static void nwpserial_shutdown(struct uart_port *port) -{ - struct nwpserial_port *up; - up = container_of(port, struct nwpserial_port, port); - - /* disable receiving */ - up->port.ignore_status_mask |= NWPSERIAL_STATUS_RXVALID; - - /* disable interrupts from this port */ - up->ier = 0; - dcr_write(up->dcr_host, UART_IER, up->ier); - - /* free irq */ - free_irq(up->port.irq, up); -} - -static int nwpserial_verify_port(struct uart_port *port, - struct serial_struct *ser) -{ - return -EINVAL; -} - -static const char *nwpserial_type(struct uart_port *port) -{ - return port->type == PORT_NWPSERIAL ? "nwpserial" : NULL; -} - -static void nwpserial_set_termios(struct uart_port *port, - struct ktermios *termios, struct ktermios *old) -{ - struct nwpserial_port *up; - up = container_of(port, struct nwpserial_port, port); - - up->port.read_status_mask = NWPSERIAL_STATUS_RXVALID - | NWPSERIAL_STATUS_TXFULL; - - up->port.ignore_status_mask = 0; - /* ignore all characters if CREAD is not set */ - if ((termios->c_cflag & CREAD) == 0) - up->port.ignore_status_mask |= NWPSERIAL_STATUS_RXVALID; - - /* Copy back the old hardware settings */ - if (old) - tty_termios_copy_hw(termios, old); -} - -static void nwpserial_break_ctl(struct uart_port *port, int ctl) -{ - /* N/A */ -} - -static void nwpserial_stop_rx(struct uart_port *port) -{ - struct nwpserial_port *up; - up = container_of(port, struct nwpserial_port, port); - /* don't forward any more data (like !CREAD) */ - up->port.ignore_status_mask = NWPSERIAL_STATUS_RXVALID; -} - -static void nwpserial_putchar(struct nwpserial_port *up, unsigned char c) -{ - /* check if tx buffer is full */ - wait_for_bits(up, UART_LSR_THRE); - dcr_write(up->dcr_host, UART_TX, c); - up->port.icount.tx++; -} - -static void nwpserial_start_tx(struct uart_port *port) -{ - struct nwpserial_port *up; - struct circ_buf *xmit; - up = container_of(port, struct nwpserial_port, port); - xmit = &up->port.state->xmit; - - if (port->x_char) { - nwpserial_putchar(up, up->port.x_char); - port->x_char = 0; - } - - while (!(uart_circ_empty(xmit) || uart_tx_stopped(&up->port))) { - nwpserial_putchar(up, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); - } -} - -static unsigned int nwpserial_get_mctrl(struct uart_port *port) -{ - return 0; -} - -static void nwpserial_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ - /* N/A */ -} - -static void nwpserial_stop_tx(struct uart_port *port) -{ - /* N/A */ -} - -static unsigned int nwpserial_tx_empty(struct uart_port *port) -{ - struct nwpserial_port *up; - unsigned long flags; - int ret; - up = container_of(port, struct nwpserial_port, port); - - spin_lock_irqsave(&up->port.lock, flags); - ret = dcr_read(up->dcr_host, UART_LSR); - spin_unlock_irqrestore(&up->port.lock, flags); - - return ret & UART_LSR_TEMT ? TIOCSER_TEMT : 0; -} - -static struct uart_ops nwpserial_pops = { - .tx_empty = nwpserial_tx_empty, - .set_mctrl = nwpserial_set_mctrl, - .get_mctrl = nwpserial_get_mctrl, - .stop_tx = nwpserial_stop_tx, - .start_tx = nwpserial_start_tx, - .stop_rx = nwpserial_stop_rx, - .break_ctl = nwpserial_break_ctl, - .startup = nwpserial_startup, - .shutdown = nwpserial_shutdown, - .set_termios = nwpserial_set_termios, - .type = nwpserial_type, - .release_port = nwpserial_release_port, - .request_port = nwpserial_request_port, - .config_port = nwpserial_config_port, - .verify_port = nwpserial_verify_port, -}; - -static struct uart_driver nwpserial_reg = { - .owner = THIS_MODULE, - .driver_name = "nwpserial", - .dev_name = "ttySQ", - .major = TTY_MAJOR, - .minor = 68, - .nr = NWPSERIAL_NR, - .cons = NWPSERIAL_CONSOLE, -}; - -int nwpserial_register_port(struct uart_port *port) -{ - struct nwpserial_port *up = NULL; - int ret = -1; - int i; - static int first = 1; - int dcr_len; - int dcr_base; - struct device_node *dn; - - mutex_lock(&nwpserial_mutex); - - dn = port->dev->of_node; - if (dn == NULL) - goto out; - - /* get dcr base. */ - dcr_base = dcr_resource_start(dn, 0); - - /* find matching entry */ - for (i = 0; i < NWPSERIAL_NR; i++) - if (nwpserial_ports[i].port.iobase == dcr_base) { - up = &nwpserial_ports[i]; - break; - } - - /* we didn't find a mtching entry, search for a free port */ - if (up == NULL) - for (i = 0; i < NWPSERIAL_NR; i++) - if (nwpserial_ports[i].port.type == PORT_UNKNOWN && - nwpserial_ports[i].port.iobase == 0) { - up = &nwpserial_ports[i]; - break; - } - - if (up == NULL) { - ret = -EBUSY; - goto out; - } - - if (first) - uart_register_driver(&nwpserial_reg); - first = 0; - - up->port.membase = port->membase; - up->port.irq = port->irq; - up->port.uartclk = port->uartclk; - up->port.fifosize = port->fifosize; - up->port.regshift = port->regshift; - up->port.iotype = port->iotype; - up->port.flags = port->flags; - up->port.mapbase = port->mapbase; - up->port.private_data = port->private_data; - - if (port->dev) - up->port.dev = port->dev; - - if (up->port.iobase != dcr_base) { - up->port.ops = &nwpserial_pops; - up->port.fifosize = 16; - - spin_lock_init(&up->port.lock); - - up->port.iobase = dcr_base; - dcr_len = dcr_resource_len(dn, 0); - - up->dcr_host = dcr_map(dn, dcr_base, dcr_len); - if (!DCR_MAP_OK(up->dcr_host)) { - printk(KERN_ERR "Cannot map DCR resources for NWPSERIAL"); - goto out; - } - } - - ret = uart_add_one_port(&nwpserial_reg, &up->port); - if (ret == 0) - ret = up->port.line; - -out: - mutex_unlock(&nwpserial_mutex); - - return ret; -} -EXPORT_SYMBOL(nwpserial_register_port); - -void nwpserial_unregister_port(int line) -{ - struct nwpserial_port *up = &nwpserial_ports[line]; - mutex_lock(&nwpserial_mutex); - uart_remove_one_port(&nwpserial_reg, &up->port); - - up->port.type = PORT_UNKNOWN; - - mutex_unlock(&nwpserial_mutex); -} -EXPORT_SYMBOL(nwpserial_unregister_port); - -#ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL_CONSOLE -static int __init nwpserial_console_init(void) -{ - struct nwpserial_port *up = NULL; - struct device_node *dn; - const char *name; - int dcr_base; - int dcr_len; - int i; - - /* search for a free port */ - for (i = 0; i < NWPSERIAL_NR; i++) - if (nwpserial_ports[i].port.type == PORT_UNKNOWN) { - up = &nwpserial_ports[i]; - break; - } - - if (up == NULL) - return -1; - - name = of_get_property(of_chosen, "linux,stdout-path", NULL); - if (name == NULL) - return -1; - - dn = of_find_node_by_path(name); - if (!dn) - return -1; - - spin_lock_init(&up->port.lock); - up->port.ops = &nwpserial_pops; - up->port.type = PORT_NWPSERIAL; - up->port.fifosize = 16; - - dcr_base = dcr_resource_start(dn, 0); - dcr_len = dcr_resource_len(dn, 0); - up->port.iobase = dcr_base; - - up->dcr_host = dcr_map(dn, dcr_base, dcr_len); - if (!DCR_MAP_OK(up->dcr_host)) { - printk("Cannot map DCR resources for SERIAL"); - return -1; - } - register_console(&nwpserial_console); - return 0; -} -console_initcall(nwpserial_console_init); -#endif /* CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL_CONSOLE */ diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 6d002eeb25161..920468bf4e833 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -215,11 +215,6 @@ static int of_platform_serial_probe(struct platform_device *ofdev) ret = serial8250_register_8250_port(&port8250); break; } -#endif -#ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL - case PORT_NWPSERIAL: - ret = nwpserial_register_port(&port); - break; #endif default: /* need to add code for these */ @@ -252,11 +247,6 @@ static int of_platform_serial_remove(struct platform_device *ofdev) case PORT_8250 ... PORT_MAX_8250: serial8250_unregister_port(info->line); break; -#endif -#ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL - case PORT_NWPSERIAL: - nwpserial_unregister_port(info->line); - break; #endif default: /* need to add code for these */ @@ -356,10 +346,6 @@ static const struct of_device_id of_platform_serial_table[] = { .data = (void *)PORT_XSCALE, }, { .compatible = "mrvl,pxa-uart", .data = (void *)PORT_XSCALE, }, -#ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL - { .compatible = "ibm,qpace-nwp-serial", - .data = (void *)PORT_NWPSERIAL, }, -#endif { /* end of list */ }, }; MODULE_DEVICE_TABLE(of, of_platform_serial_table); diff --git a/include/linux/nwpserial.h b/include/linux/nwpserial.h deleted file mode 100644 index 9acb21572eaf1..0000000000000 --- a/include/linux/nwpserial.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Serial Port driver for a NWP uart device - * - * Copyright (C) 2008 IBM Corp., Benjamin Krill - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ -#ifndef _NWPSERIAL_H -#define _NWPSERIAL_H - -int nwpserial_register_port(struct uart_port *port); -void nwpserial_unregister_port(int line); - -#endif /* _NWPSERIAL_H */ diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 93ba148f923e5..3e5d757407fbb 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -176,7 +176,7 @@ #define PORT_S3C6400 84 -/* NWPSERIAL */ +/* NWPSERIAL, now removed */ #define PORT_NWPSERIAL 85 /* MAX3100 */ -- GitLab From 4e33870b3bb691996354a8f9e8f69458b4fc34d9 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 16:48:13 +0100 Subject: [PATCH 1165/2855] serial: of: CONFIG_SERIAL_8250 is always set The only other user of this code was the nwp-serial driver, but that is now gone, so we can remove a couple of #ifdef statments in this driver. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/of_serial.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 920468bf4e833..d66fd24f87cf3 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -21,10 +21,6 @@ #include #include -#ifdef CONFIG_SERIAL_8250_MODULE -#define CONFIG_SERIAL_8250 CONFIG_SERIAL_8250_MODULE -#endif - #include "8250/8250.h" struct of_serial_info { @@ -198,7 +194,6 @@ static int of_platform_serial_probe(struct platform_device *ofdev) goto out; switch (port_type) { -#ifdef CONFIG_SERIAL_8250 case PORT_8250 ... PORT_MAX_8250: { struct uart_8250_port port8250; @@ -215,7 +210,6 @@ static int of_platform_serial_probe(struct platform_device *ofdev) ret = serial8250_register_8250_port(&port8250); break; } -#endif default: /* need to add code for these */ case PORT_UNKNOWN: @@ -243,11 +237,9 @@ static int of_platform_serial_remove(struct platform_device *ofdev) { struct of_serial_info *info = platform_get_drvdata(ofdev); switch (info->type) { -#ifdef CONFIG_SERIAL_8250 case PORT_8250 ... PORT_MAX_8250: serial8250_unregister_port(info->line); break; -#endif default: /* need to add code for these */ break; @@ -260,7 +252,6 @@ static int of_platform_serial_remove(struct platform_device *ofdev) } #ifdef CONFIG_PM_SLEEP -#ifdef CONFIG_SERIAL_8250 static void of_serial_suspend_8250(struct of_serial_info *info) { struct uart_8250_port *port8250 = serial8250_get_port(info->line); @@ -281,15 +272,6 @@ static void of_serial_resume_8250(struct of_serial_info *info) serial8250_resume_port(info->line); } -#else -static inline void of_serial_suspend_8250(struct of_serial_info *info) -{ -} - -static inline void of_serial_resume_8250(struct of_serial_info *info) -{ -} -#endif static int of_serial_suspend(struct device *dev) { -- GitLab From afd7f88f157796e586fc99d62da13a54024e0731 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 16:48:14 +0100 Subject: [PATCH 1166/2855] serial: 8250: move of_serial code to 8250 directory As the of-serial driver is now 8250 specific, we can move the file to a more appropriate place in teh 8250 subdirectory and adapt the Kconfig help text and file name. I'm leaving the CONFIG_SERIAL_OF_PLATFORM symbol unchanged to avoid breaking user configuration files unnecessarily. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/{of_serial.c => 8250/8250_of.c} | 0 drivers/tty/serial/8250/Kconfig | 9 +++++++++ drivers/tty/serial/8250/Makefile | 1 + drivers/tty/serial/Kconfig | 10 ---------- drivers/tty/serial/Makefile | 1 - 5 files changed, 10 insertions(+), 11 deletions(-) rename drivers/tty/serial/{of_serial.c => 8250/8250_of.c} (100%) diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/8250/8250_of.c similarity index 100% rename from drivers/tty/serial/of_serial.c rename to drivers/tty/serial/8250/8250_of.c diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 25da430bb58b1..54f8af8ab4fb5 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -377,3 +377,12 @@ config SERIAL_8250_MID Selecting this option will enable handling of the extra features present on the UART found on Intel Medfield SOC and various other Intel platforms. + +config SERIAL_OF_PLATFORM + tristate "Devicetree based probing for 8250 ports" + depends on SERIAL_8250 && OF + help + This option is used for all 8250 compatible serial ports that + are probed through devicetree, including Open Firmware based + PowerPC systems and embedded systems on architectures using the + flattened device tree format. diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index e177f8681adad..4ecb80d3549ae 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -28,5 +28,6 @@ obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o obj-$(CONFIG_SERIAL_8250_UNIPHIER) += 8250_uniphier.o obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o obj-$(CONFIG_SERIAL_8250_MID) += 8250_mid.o +obj-$(CONFIG_SERIAL_8250_OF) += 8250_of.o CFLAGS_8250_ingenic.o += -I$(srctree)/scripts/dtc/libfdt diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 643fc50bb741f..0bdf4d5c7c657 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1096,16 +1096,6 @@ config SERIAL_NETX_CONSOLE If you have enabled the serial port on the Hilscher NetX SoC you can make it the console by answering Y to this option. -config SERIAL_OF_PLATFORM - tristate "Serial port on Open Firmware platform bus" - depends on OF - depends on SERIAL_8250 - help - If you have a PowerPC based system that has serial ports - on a platform specific bus, you should enable this option. - Currently, only 8250 compatible ports are supported, but - others can easily be added. - config SERIAL_OMAP tristate "OMAP serial port support" depends on ARCH_OMAP2PLUS diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index ee8893317433b..b391c9b319602 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -63,7 +63,6 @@ obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o obj-$(CONFIG_SERIAL_MSM) += msm_serial.o obj-$(CONFIG_SERIAL_NETX) += netx-serial.o -obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o obj-$(CONFIG_SERIAL_KGDB_NMI) += kgdb_nmi.o obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o -- GitLab From 679e7c2999f963e542c6f4c3d3c9a0688b5d3587 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 27 Nov 2015 14:11:02 -0500 Subject: [PATCH 1167/2855] n_tty: Uninline tty_copy_to_user() Merge the multiple tty_copy_to_user() calls into a single copy sequence within tty_copy_to_user(). Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index c37c15d2f782e..b2b01d5439b70 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -162,12 +162,23 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x, return put_user(x, ptr); } -static inline int tty_copy_to_user(struct tty_struct *tty, - void __user *to, - const void *from, - unsigned long n) +static int tty_copy_to_user(struct tty_struct *tty, void __user *to, + size_t tail, size_t n) { struct n_tty_data *ldata = tty->disc_data; + size_t size = N_TTY_BUF_SIZE - tail; + const void *from = read_buf_addr(ldata, tail); + int uncopied; + + if (n > size) { + tty_audit_add_data(tty, from, size, ldata->icanon); + uncopied = copy_to_user(to, from, size); + if (uncopied) + return uncopied; + to += size; + n -= size; + from = ldata->read_buf; + } tty_audit_add_data(tty, from, n, ldata->icanon); return copy_to_user(to, from, n); @@ -2074,7 +2085,6 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, } else if (eol != size) found = 1; - size = N_TTY_BUF_SIZE - tail; n = eol - tail; if (n > N_TTY_BUF_SIZE) n += N_TTY_BUF_SIZE; @@ -2086,17 +2096,10 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, eof_push = !n && ldata->read_tail != ldata->line_start; } - n_tty_trace("%s: eol:%zu found:%d n:%zu c:%zu size:%zu more:%zu\n", - __func__, eol, found, n, c, size, more); - - if (n > size) { - ret = tty_copy_to_user(tty, *b, read_buf_addr(ldata, tail), size); - if (ret) - return -EFAULT; - ret = tty_copy_to_user(tty, *b + size, ldata->read_buf, n - size); - } else - ret = tty_copy_to_user(tty, *b, read_buf_addr(ldata, tail), n); + n_tty_trace("%s: eol:%zu found:%d n:%zu c:%zu tail:%zu more:%zu\n", + __func__, eol, found, n, c, tail, more); + ret = tty_copy_to_user(tty, *b, tail, n); if (ret) return -EFAULT; *b += n; -- GitLab From e661cf702003030daf2001cb88eb586300a18ee4 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 27 Nov 2015 14:11:03 -0500 Subject: [PATCH 1168/2855] n_tty: Clarify copy_from_read_buf() Add a temporary for the computed source address and substitute where appropriate. No functional change. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index b2b01d5439b70..bc613b868e711 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -2014,11 +2014,11 @@ static int copy_from_read_buf(struct tty_struct *tty, n = min(head - ldata->read_tail, N_TTY_BUF_SIZE - tail); n = min(*nr, n); if (n) { - retval = copy_to_user(*b, read_buf_addr(ldata, tail), n); + const unsigned char *from = read_buf_addr(ldata, tail); + retval = copy_to_user(*b, from, n); n -= retval; - is_eof = n == 1 && read_buf(ldata, tail) == EOF_CHAR(tty); - tty_audit_add_data(tty, read_buf_addr(ldata, tail), n, - ldata->icanon); + is_eof = n == 1 && *from == EOF_CHAR(tty); + tty_audit_add_data(tty, from, n, ldata->icanon); smp_store_release(&ldata->read_tail, ldata->read_tail + n); /* Turn single EOF into zero-length read */ if (L_EXTPROC(tty) && ldata->icanon && is_eof && -- GitLab From b985e9e368f0db4fee940ad86197f413779d4b63 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 27 Nov 2015 14:11:04 -0500 Subject: [PATCH 1169/2855] n_tty: Reduce branching in canon_copy_from_read_buf() Instead of compare-and-set, just compute 'found'. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index bc613b868e711..f2f64252814f9 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -2080,10 +2080,9 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, if (eol == N_TTY_BUF_SIZE && more) { /* scan wrapped without finding set bit */ eol = find_next_bit(ldata->read_flags, more, 0); - if (eol != more) - found = 1; - } else if (eol != size) - found = 1; + found = eol != more; + } else + found = eol != size; n = eol - tail; if (n > N_TTY_BUF_SIZE) -- GitLab From debb7f64f9bab5cd0d06b7ce1695f15c5c9304d0 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 16 Nov 2015 17:40:26 +0000 Subject: [PATCH 1170/2855] tty: amba-pl011: add register lookup table Add a register lookup table, which allows the register offsets to be adjusted on a per-port basis. Signed-off-by: Russell King Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 33 +++++++++++++++++++- drivers/tty/serial/amba-pl011.h | 53 +++++++++++++++++---------------- 2 files changed, 60 insertions(+), 26 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 62b9cb2754020..29526a1d39df6 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -73,6 +73,34 @@ #define UART_DR_ERROR (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE) #define UART_DUMMY_DR_RX (1 << 16) +static u16 pl011_std_offsets[REG_ARRAY_SIZE] = { + [REG_DR] = UART01x_DR, + [REG_ST_DMAWM] = ST_UART011_DMAWM, + [REG_ST_TIMEOUT] = ST_UART011_TIMEOUT, + [REG_FR] = UART01x_FR, + [REG_ST_LCRH_RX] = ST_UART011_LCRH_RX, + [REG_IBRD] = UART011_IBRD, + [REG_FBRD] = UART011_FBRD, + [REG_LCRH] = UART011_LCRH, + [REG_ST_LCRH_TX] = ST_UART011_LCRH_TX, + [REG_CR] = UART011_CR, + [REG_IFLS] = UART011_IFLS, + [REG_IMSC] = UART011_IMSC, + [REG_RIS] = UART011_RIS, + [REG_MIS] = UART011_MIS, + [REG_ICR] = UART011_ICR, + [REG_DMACR] = UART011_DMACR, + [REG_ST_XFCR] = ST_UART011_XFCR, + [REG_ST_XON1] = ST_UART011_XON1, + [REG_ST_XON2] = ST_UART011_XON2, + [REG_ST_XOFF1] = ST_UART011_XOFF1, + [REG_ST_XOFF2] = ST_UART011_XOFF2, + [REG_ST_ITCR] = ST_UART011_ITCR, + [REG_ST_ITIP] = ST_UART011_ITIP, + [REG_ST_ABCR] = ST_UART011_ABCR, + [REG_ST_ABIMSC] = ST_UART011_ABIMSC, +}; + /* There is by now at least one vendor with differing details, so handle it */ struct vendor_data { unsigned int ifls; @@ -164,6 +192,7 @@ struct pl011_dmatx_data { */ struct uart_amba_port { struct uart_port port; + const u16 *reg_offset; struct clk *clk; const struct vendor_data *vendor; unsigned int dmacr; /* dma control reg */ @@ -189,7 +218,7 @@ struct uart_amba_port { static unsigned int pl011_reg_to_offset(const struct uart_amba_port *uap, unsigned int reg) { - return reg; + return uap->reg_offset[reg]; } static unsigned int pl011_read(const struct uart_amba_port *uap, @@ -2397,6 +2426,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) if (IS_ERR(uap->clk)) return PTR_ERR(uap->clk); + uap->reg_offset = pl011_std_offsets; uap->vendor = vendor; uap->lcrh_rx = vendor->lcrh_rx; uap->lcrh_tx = vendor->lcrh_tx; @@ -2478,6 +2508,7 @@ static int sbsa_uart_probe(struct platform_device *pdev) if (!uap) return -ENOMEM; + uap->reg_offset = pl011_std_offsets; uap->vendor = &vendor_sbsa; uap->fifosize = 32; uap->port.irq = platform_get_irq(pdev, 0); diff --git a/drivers/tty/serial/amba-pl011.h b/drivers/tty/serial/amba-pl011.h index b7eb1bc2fab9b..0c6756dba2fea 100644 --- a/drivers/tty/serial/amba-pl011.h +++ b/drivers/tty/serial/amba-pl011.h @@ -2,31 +2,34 @@ #define AMBA_PL011_H enum { - REG_DR = UART01x_DR, - REG_ST_DMAWM = ST_UART011_DMAWM, - REG_ST_TIMEOUT = ST_UART011_TIMEOUT, - REG_FR = UART01x_FR, - REG_ST_LCRH_RX = ST_UART011_LCRH_RX, - REG_IBRD = UART011_IBRD, - REG_FBRD = UART011_FBRD, - REG_LCRH = UART011_LCRH, - REG_ST_LCRH_TX = ST_UART011_LCRH_TX, - REG_CR = UART011_CR, - REG_IFLS = UART011_IFLS, - REG_IMSC = UART011_IMSC, - REG_RIS = UART011_RIS, - REG_MIS = UART011_MIS, - REG_ICR = UART011_ICR, - REG_DMACR = UART011_DMACR, - REG_ST_XFCR = ST_UART011_XFCR, - REG_ST_XON1 = ST_UART011_XON1, - REG_ST_XON2 = ST_UART011_XON2, - REG_ST_XOFF1 = ST_UART011_XOFF1, - REG_ST_XOFF2 = ST_UART011_XOFF2, - REG_ST_ITCR = ST_UART011_ITCR, - REG_ST_ITIP = ST_UART011_ITIP, - REG_ST_ABCR = ST_UART011_ABCR, - REG_ST_ABIMSC = ST_UART011_ABIMSC, + REG_DR, + REG_ST_DMAWM, + REG_ST_TIMEOUT, + REG_FR, + REG_ST_LCRH_RX, + REG_IBRD, + REG_FBRD, + REG_LCRH, + REG_ST_LCRH_TX, + REG_CR, + REG_IFLS, + REG_IMSC, + REG_RIS, + REG_MIS, + REG_ICR, + REG_DMACR, + REG_ST_XFCR, + REG_ST_XON1, + REG_ST_XON2, + REG_ST_XOFF1, + REG_ST_XOFF2, + REG_ST_ITCR, + REG_ST_ITIP, + REG_ST_ABCR, + REG_ST_ABIMSC, + + /* The size of the array - must be last */ + REG_ARRAY_SIZE, }; #endif -- GitLab From 439403bde9fc9e655237d87fc44381f49025ea4f Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 16 Nov 2015 17:40:31 +0000 Subject: [PATCH 1171/2855] tty: amba-pl011: add register offset table to vendor data Add the register offset table to the vendor data, allowing vendor differences to be described in this table. Signed-off-by: Russell King Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 29526a1d39df6..4c122078d62be 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -103,6 +103,7 @@ static u16 pl011_std_offsets[REG_ARRAY_SIZE] = { /* There is by now at least one vendor with differing details, so handle it */ struct vendor_data { + const u16 *reg_offset; unsigned int ifls; unsigned int lcrh_tx; unsigned int lcrh_rx; @@ -121,6 +122,7 @@ static unsigned int get_fifosize_arm(struct amba_device *dev) } static struct vendor_data vendor_arm = { + .reg_offset = pl011_std_offsets, .ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, .lcrh_tx = REG_LCRH, .lcrh_rx = REG_LCRH, @@ -133,6 +135,7 @@ static struct vendor_data vendor_arm = { }; static struct vendor_data vendor_sbsa = { + .reg_offset = pl011_std_offsets, .oversampling = false, .dma_threshold = false, .cts_event_workaround = false, @@ -146,6 +149,7 @@ static unsigned int get_fifosize_st(struct amba_device *dev) } static struct vendor_data vendor_st = { + .reg_offset = pl011_std_offsets, .ifls = UART011_IFLS_RX_HALF|UART011_IFLS_TX_HALF, .lcrh_tx = REG_ST_LCRH_TX, .lcrh_rx = REG_ST_LCRH_RX, @@ -2426,7 +2430,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) if (IS_ERR(uap->clk)) return PTR_ERR(uap->clk); - uap->reg_offset = pl011_std_offsets; + uap->reg_offset = vendor->reg_offset; uap->vendor = vendor; uap->lcrh_rx = vendor->lcrh_rx; uap->lcrh_tx = vendor->lcrh_tx; @@ -2508,7 +2512,7 @@ static int sbsa_uart_probe(struct platform_device *pdev) if (!uap) return -ENOMEM; - uap->reg_offset = pl011_std_offsets; + uap->reg_offset = vendor_sbsa.reg_offset; uap->vendor = &vendor_sbsa; uap->fifosize = 32; uap->port.irq = platform_get_irq(pdev, 0); -- GitLab From bf69ff8a24358521f113b5c13f271681a74dd2a9 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 16 Nov 2015 17:40:36 +0000 Subject: [PATCH 1172/2855] tty: amba-pl011: add ST register offset table Add the ST variant register offset table to the driver. Currently, this is an identical copy of the standard version, but this will be modified in the following changes. Signed-off-by: Russell King Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 4c122078d62be..c4adecedde2c8 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -143,13 +143,41 @@ static struct vendor_data vendor_sbsa = { .fixed_options = true, }; +static u16 pl011_st_offsets[REG_ARRAY_SIZE] = { + [REG_DR] = UART01x_DR, + [REG_ST_DMAWM] = ST_UART011_DMAWM, + [REG_ST_TIMEOUT] = ST_UART011_TIMEOUT, + [REG_FR] = UART01x_FR, + [REG_ST_LCRH_RX] = ST_UART011_LCRH_RX, + [REG_IBRD] = UART011_IBRD, + [REG_FBRD] = UART011_FBRD, + [REG_LCRH] = UART011_LCRH, + [REG_ST_LCRH_TX] = ST_UART011_LCRH_TX, + [REG_CR] = UART011_CR, + [REG_IFLS] = UART011_IFLS, + [REG_IMSC] = UART011_IMSC, + [REG_RIS] = UART011_RIS, + [REG_MIS] = UART011_MIS, + [REG_ICR] = UART011_ICR, + [REG_DMACR] = UART011_DMACR, + [REG_ST_XFCR] = ST_UART011_XFCR, + [REG_ST_XON1] = ST_UART011_XON1, + [REG_ST_XON2] = ST_UART011_XON2, + [REG_ST_XOFF1] = ST_UART011_XOFF1, + [REG_ST_XOFF2] = ST_UART011_XOFF2, + [REG_ST_ITCR] = ST_UART011_ITCR, + [REG_ST_ITIP] = ST_UART011_ITIP, + [REG_ST_ABCR] = ST_UART011_ABCR, + [REG_ST_ABIMSC] = ST_UART011_ABIMSC, +}; + static unsigned int get_fifosize_st(struct amba_device *dev) { return 64; } static struct vendor_data vendor_st = { - .reg_offset = pl011_std_offsets, + .reg_offset = pl011_st_offsets, .ifls = UART011_IFLS_RX_HALF|UART011_IFLS_TX_HALF, .lcrh_tx = REG_ST_LCRH_TX, .lcrh_rx = REG_ST_LCRH_RX, -- GitLab From e4df9a8053f24b6f37cf11aca793a8deeca88caf Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 16 Nov 2015 17:40:41 +0000 Subject: [PATCH 1173/2855] tty: amba-pl011: clean up LCR register offsets As we can detect when the LCR register is split between TX and RX, we don't need three entries in the table to deal with this. Reduce this down to two entries by converting the REG_ST_LCRH_* entries to standard REG_LCRH_* and remove REG_LCRH. Signed-off-by: Russell King Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 40 ++++++++++++--------------------- drivers/tty/serial/amba-pl011.h | 5 ++--- 2 files changed, 16 insertions(+), 29 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index c4adecedde2c8..88ff97e0d6b06 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -78,11 +78,10 @@ static u16 pl011_std_offsets[REG_ARRAY_SIZE] = { [REG_ST_DMAWM] = ST_UART011_DMAWM, [REG_ST_TIMEOUT] = ST_UART011_TIMEOUT, [REG_FR] = UART01x_FR, - [REG_ST_LCRH_RX] = ST_UART011_LCRH_RX, + [REG_LCRH_RX] = UART011_LCRH, + [REG_LCRH_TX] = UART011_LCRH, [REG_IBRD] = UART011_IBRD, [REG_FBRD] = UART011_FBRD, - [REG_LCRH] = UART011_LCRH, - [REG_ST_LCRH_TX] = ST_UART011_LCRH_TX, [REG_CR] = UART011_CR, [REG_IFLS] = UART011_IFLS, [REG_IMSC] = UART011_IMSC, @@ -105,8 +104,6 @@ static u16 pl011_std_offsets[REG_ARRAY_SIZE] = { struct vendor_data { const u16 *reg_offset; unsigned int ifls; - unsigned int lcrh_tx; - unsigned int lcrh_rx; bool oversampling; bool dma_threshold; bool cts_event_workaround; @@ -124,8 +121,6 @@ static unsigned int get_fifosize_arm(struct amba_device *dev) static struct vendor_data vendor_arm = { .reg_offset = pl011_std_offsets, .ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, - .lcrh_tx = REG_LCRH, - .lcrh_rx = REG_LCRH, .oversampling = false, .dma_threshold = false, .cts_event_workaround = false, @@ -148,11 +143,10 @@ static u16 pl011_st_offsets[REG_ARRAY_SIZE] = { [REG_ST_DMAWM] = ST_UART011_DMAWM, [REG_ST_TIMEOUT] = ST_UART011_TIMEOUT, [REG_FR] = UART01x_FR, - [REG_ST_LCRH_RX] = ST_UART011_LCRH_RX, + [REG_LCRH_RX] = ST_UART011_LCRH_RX, + [REG_LCRH_TX] = ST_UART011_LCRH_TX, [REG_IBRD] = UART011_IBRD, [REG_FBRD] = UART011_FBRD, - [REG_LCRH] = UART011_LCRH, - [REG_ST_LCRH_TX] = ST_UART011_LCRH_TX, [REG_CR] = UART011_CR, [REG_IFLS] = UART011_IFLS, [REG_IMSC] = UART011_IMSC, @@ -179,8 +173,6 @@ static unsigned int get_fifosize_st(struct amba_device *dev) static struct vendor_data vendor_st = { .reg_offset = pl011_st_offsets, .ifls = UART011_IFLS_RX_HALF|UART011_IFLS_TX_HALF, - .lcrh_tx = REG_ST_LCRH_TX, - .lcrh_rx = REG_ST_LCRH_RX, .oversampling = true, .dma_threshold = true, .cts_event_workaround = true, @@ -231,8 +223,6 @@ struct uart_amba_port { unsigned int im; /* interrupt mask */ unsigned int old_status; unsigned int fifosize; /* vendor-specific */ - unsigned int lcrh_tx; /* vendor-specific */ - unsigned int lcrh_rx; /* vendor-specific */ unsigned int old_cr; /* state during shutdown */ bool autorts; unsigned int fixed_baud; /* vendor-set fixed baud rate */ @@ -1540,12 +1530,12 @@ static void pl011_break_ctl(struct uart_port *port, int break_state) unsigned int lcr_h; spin_lock_irqsave(&uap->port.lock, flags); - lcr_h = pl011_read(uap, uap->lcrh_tx); + lcr_h = pl011_read(uap, REG_LCRH_TX); if (break_state == -1) lcr_h |= UART01x_LCRH_BRK; else lcr_h &= ~UART01x_LCRH_BRK; - pl011_write(lcr_h, uap, uap->lcrh_tx); + pl011_write(lcr_h, uap, REG_LCRH_TX); spin_unlock_irqrestore(&uap->port.lock, flags); } @@ -1649,13 +1639,13 @@ static int pl011_hwinit(struct uart_port *port) static bool pl011_split_lcrh(const struct uart_amba_port *uap) { - return pl011_reg_to_offset(uap, uap->lcrh_rx) != - pl011_reg_to_offset(uap, uap->lcrh_tx); + return pl011_reg_to_offset(uap, REG_LCRH_RX) != + pl011_reg_to_offset(uap, REG_LCRH_TX); } static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h) { - pl011_write(lcr_h, uap, uap->lcrh_rx); + pl011_write(lcr_h, uap, REG_LCRH_RX); if (pl011_split_lcrh(uap)) { int i; /* @@ -1664,7 +1654,7 @@ static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h) */ for (i = 0; i < 10; ++i) pl011_write(0xff, uap, REG_MIS); - pl011_write(lcr_h, uap, uap->lcrh_tx); + pl011_write(lcr_h, uap, REG_LCRH_TX); } } @@ -1789,9 +1779,9 @@ static void pl011_disable_uart(struct uart_amba_port *uap) /* * disable break condition and fifos */ - pl011_shutdown_channel(uap, uap->lcrh_rx); + pl011_shutdown_channel(uap, REG_LCRH_RX); if (pl011_split_lcrh(uap)) - pl011_shutdown_channel(uap, uap->lcrh_tx); + pl011_shutdown_channel(uap, REG_LCRH_TX); } static void pl011_disable_interrupts(struct uart_amba_port *uap) @@ -1992,7 +1982,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, /* * ----------v----------v----------v----------v----- - * NOTE: lcrh_tx and lcrh_rx MUST BE WRITTEN AFTER + * NOTE: REG_LCRH_TX and REG_LCRH_RX MUST BE WRITTEN AFTER * REG_FBRD & REG_IBRD. * ----------^----------^----------^----------^----- */ @@ -2197,7 +2187,7 @@ pl011_console_get_options(struct uart_amba_port *uap, int *baud, if (pl011_read(uap, REG_CR) & UART01x_CR_UARTEN) { unsigned int lcr_h, ibrd, fbrd; - lcr_h = pl011_read(uap, uap->lcrh_tx); + lcr_h = pl011_read(uap, REG_LCRH_TX); *parity = 'n'; if (lcr_h & UART01x_LCRH_PEN) { @@ -2460,8 +2450,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) uap->reg_offset = vendor->reg_offset; uap->vendor = vendor; - uap->lcrh_rx = vendor->lcrh_rx; - uap->lcrh_tx = vendor->lcrh_tx; uap->fifosize = vendor->get_fifosize(dev); uap->port.irq = dev->irq[0]; uap->port.ops = &amba_pl011_pops; diff --git a/drivers/tty/serial/amba-pl011.h b/drivers/tty/serial/amba-pl011.h index 0c6756dba2fea..411c60e1f9a4c 100644 --- a/drivers/tty/serial/amba-pl011.h +++ b/drivers/tty/serial/amba-pl011.h @@ -6,11 +6,10 @@ enum { REG_ST_DMAWM, REG_ST_TIMEOUT, REG_FR, - REG_ST_LCRH_RX, + REG_LCRH_RX, + REG_LCRH_TX, REG_IBRD, REG_FBRD, - REG_LCRH, - REG_ST_LCRH_TX, REG_CR, REG_IFLS, REG_IMSC, -- GitLab From 10004a66240d7660179ccff9ac301926e783c76c Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 16 Nov 2015 17:40:47 +0000 Subject: [PATCH 1174/2855] tty: amba-pl011: remove ST micro registers from standard table Remove the ST micro registers from the standard table. These registers should never be accessed in non-ST micro variants. Signed-off-by: Russell King Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 88ff97e0d6b06..e0f9e3e739d09 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -75,8 +75,6 @@ static u16 pl011_std_offsets[REG_ARRAY_SIZE] = { [REG_DR] = UART01x_DR, - [REG_ST_DMAWM] = ST_UART011_DMAWM, - [REG_ST_TIMEOUT] = ST_UART011_TIMEOUT, [REG_FR] = UART01x_FR, [REG_LCRH_RX] = UART011_LCRH, [REG_LCRH_TX] = UART011_LCRH, @@ -89,15 +87,6 @@ static u16 pl011_std_offsets[REG_ARRAY_SIZE] = { [REG_MIS] = UART011_MIS, [REG_ICR] = UART011_ICR, [REG_DMACR] = UART011_DMACR, - [REG_ST_XFCR] = ST_UART011_XFCR, - [REG_ST_XON1] = ST_UART011_XON1, - [REG_ST_XON2] = ST_UART011_XON2, - [REG_ST_XOFF1] = ST_UART011_XOFF1, - [REG_ST_XOFF2] = ST_UART011_XOFF2, - [REG_ST_ITCR] = ST_UART011_ITCR, - [REG_ST_ITIP] = ST_UART011_ITIP, - [REG_ST_ABCR] = ST_UART011_ABCR, - [REG_ST_ABIMSC] = ST_UART011_ABIMSC, }; /* There is by now at least one vendor with differing details, so handle it */ -- GitLab From 84c3e03bdd1146191b7222ed62a08512199a45c7 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 16 Nov 2015 17:40:52 +0000 Subject: [PATCH 1175/2855] tty: amba-pl011: add support for 32-bit register access Add support for 32-bit register accesses to the AMBA PL011 UART. This is needed for ZTE UARTs, which require 32-bit accesses as opposed to the more normal 16-bit accesses. Signed-off-by: Russell King Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index e0f9e3e739d09..c8165b61dbf84 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -93,6 +93,7 @@ static u16 pl011_std_offsets[REG_ARRAY_SIZE] = { struct vendor_data { const u16 *reg_offset; unsigned int ifls; + bool access_32b; bool oversampling; bool dma_threshold; bool cts_event_workaround; @@ -214,6 +215,7 @@ struct uart_amba_port { unsigned int fifosize; /* vendor-specific */ unsigned int old_cr; /* state during shutdown */ bool autorts; + bool access_32b; unsigned int fixed_baud; /* vendor-set fixed baud rate */ char type[12]; #ifdef CONFIG_DMA_ENGINE @@ -235,13 +237,20 @@ static unsigned int pl011_reg_to_offset(const struct uart_amba_port *uap, static unsigned int pl011_read(const struct uart_amba_port *uap, unsigned int reg) { - return readw(uap->port.membase + pl011_reg_to_offset(uap, reg)); + void __iomem *addr = uap->port.membase + pl011_reg_to_offset(uap, reg); + + return uap->access_32b ? readl(addr) : readw(addr); } static void pl011_write(unsigned int val, const struct uart_amba_port *uap, unsigned int reg) { - writew(val, uap->port.membase + pl011_reg_to_offset(uap, reg)); + void __iomem *addr = uap->port.membase + pl011_reg_to_offset(uap, reg); + + if (uap->access_32b) + writel(val, addr); + else + writew(val, addr); } /* @@ -2438,6 +2447,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) return PTR_ERR(uap->clk); uap->reg_offset = vendor->reg_offset; + uap->access_32b = vendor->access_32b; uap->vendor = vendor; uap->fifosize = vendor->get_fifosize(dev); uap->port.irq = dev->irq[0]; @@ -2518,6 +2528,7 @@ static int sbsa_uart_probe(struct platform_device *pdev) return -ENOMEM; uap->reg_offset = vendor_sbsa.reg_offset; + uap->access_32b = vendor_sbsa.access_32b; uap->vendor = &vendor_sbsa; uap->fifosize = 32; uap->port.irq = platform_get_irq(pdev, 0); -- GitLab From 7ec758718920e5e5876d0d02ece6855128c8eb1e Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 16 Nov 2015 17:40:57 +0000 Subject: [PATCH 1176/2855] tty: amba-pl011: add support for ZTE UART (EXPERIMENTAL) Add (incomplete) support for the ZTE UART to the AMBA PL011 driver. This is similar to the ARM and ST variants, except it has a different register address layout, and requires 32-bit accesses to the registers. Use the newly introduced register tables and access size support to cope with these differences. Signed-off-by: Russell King Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 23 +++++++++++++++++++++++ include/linux/amba/serial.h | 18 ++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index c8165b61dbf84..295f0be128f9e 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -171,6 +171,29 @@ static struct vendor_data vendor_st = { .get_fifosize = get_fifosize_st, }; +static const u16 pl011_zte_offsets[REG_ARRAY_SIZE] = { + [REG_DR] = ZX_UART011_DR, + [REG_FR] = ZX_UART011_FR, + [REG_LCRH_RX] = ZX_UART011_LCRH, + [REG_LCRH_TX] = ZX_UART011_LCRH, + [REG_IBRD] = ZX_UART011_IBRD, + [REG_FBRD] = ZX_UART011_FBRD, + [REG_CR] = ZX_UART011_CR, + [REG_IFLS] = ZX_UART011_IFLS, + [REG_IMSC] = ZX_UART011_IMSC, + [REG_RIS] = ZX_UART011_RIS, + [REG_MIS] = ZX_UART011_MIS, + [REG_ICR] = ZX_UART011_ICR, + [REG_DMACR] = ZX_UART011_DMACR, +}; + +static struct vendor_data vendor_zte = { + .reg_offset = pl011_zte_offsets, + .access_32b = true, + .ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, + .get_fifosize = get_fifosize_arm, +}; + /* Deals with DMA transactions */ struct pl011_sgbuf { diff --git a/include/linux/amba/serial.h b/include/linux/amba/serial.h index 0ddb5c02ad8b6..d76a19ba2cffa 100644 --- a/include/linux/amba/serial.h +++ b/include/linux/amba/serial.h @@ -65,6 +65,24 @@ #define ST_UART011_ABCR 0x100 /* Autobaud control register. */ #define ST_UART011_ABIMSC 0x15C /* Autobaud interrupt mask/clear register. */ +/* + * ZTE UART register offsets. This UART has a radically different address + * allocation from the ARM and ST variants, so we list all registers here. + * We assume unlisted registers do not exist. + */ +#define ZX_UART011_DR 0x04 +#define ZX_UART011_FR 0x14 +#define ZX_UART011_IBRD 0x24 +#define ZX_UART011_FBRD 0x28 +#define ZX_UART011_LCRH 0x30 +#define ZX_UART011_CR 0x34 +#define ZX_UART011_IFLS 0x38 +#define ZX_UART011_IMSC 0x40 +#define ZX_UART011_RIS 0x44 +#define ZX_UART011_MIS 0x48 +#define ZX_UART011_ICR 0x4c +#define ZX_UART011_DMACR 0x50 + #define UART011_DR_OE (1 << 11) #define UART011_DR_BE (1 << 10) #define UART011_DR_PE (1 << 9) -- GitLab From f5ce6edd22cff94e7b4a17f26cad43e60ae3d080 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 16 Nov 2015 17:41:02 +0000 Subject: [PATCH 1177/2855] tty: amba-pl011: switch to using relaxed IO accessors Using relaxed IO accessors allows GCC to better optimise this code as we eliminate the heavy memory barriers - for example, GCC can now cache the address of a register across a read-modify-write sequence, rather than reloading the base address, offset and access size flag. Signed-off-by: Russell King Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 295f0be128f9e..3b24aea343de1 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -262,7 +262,7 @@ static unsigned int pl011_read(const struct uart_amba_port *uap, { void __iomem *addr = uap->port.membase + pl011_reg_to_offset(uap, reg); - return uap->access_32b ? readl(addr) : readw(addr); + return uap->access_32b ? readl_relaxed(addr) : readw_relaxed(addr); } static void pl011_write(unsigned int val, const struct uart_amba_port *uap, @@ -271,9 +271,9 @@ static void pl011_write(unsigned int val, const struct uart_amba_port *uap, void __iomem *addr = uap->port.membase + pl011_reg_to_offset(uap, reg); if (uap->access_32b) - writel(val, addr); + writel_relaxed(val, addr); else - writew(val, addr); + writew_relaxed(val, addr); } /* -- GitLab From 1bc1f17b7f1ca320b389622e3c7fbf4ee8991f61 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 18 Nov 2015 14:41:11 +0000 Subject: [PATCH 1178/2855] ARM: meson: serial: release region on port release The meson_uart_release_port() unmaps the register area but does not release it. The meson_uart_request_port() calls devm_request_mem_region so the release should call devm_release_mem_region() for that area so that anyt subsequent use of these calls will work. This fixes an issue where the addition of reset code before registering the uart stops the console from working. Signed-off-by: Ben Dooks Tested-by: Carlo Caione Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 0fc83c962d100..b9f0829ceda1e 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -367,9 +367,26 @@ static int meson_uart_verify_port(struct uart_port *port, return ret; } +static int meson_uart_res_size(struct uart_port *port) +{ + struct platform_device *pdev = to_platform_device(port->dev); + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(port->dev, "cannot obtain I/O memory region"); + return -ENODEV; + } + + return resource_size(res); +} + static void meson_uart_release_port(struct uart_port *port) { + int size = meson_uart_res_size(port); + if (port->flags & UPF_IOREMAP) { + devm_release_mem_region(port->dev, port->mapbase, size); devm_iounmap(port->dev, port->membase); port->membase = NULL; } @@ -377,16 +394,10 @@ static void meson_uart_release_port(struct uart_port *port) static int meson_uart_request_port(struct uart_port *port) { - struct platform_device *pdev = to_platform_device(port->dev); - struct resource *res; - int size; + int size = meson_uart_res_size(port); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "cannot obtain I/O memory region"); - return -ENODEV; - } - size = resource_size(res); + if (size < 0) + return size; if (!devm_request_mem_region(port->dev, port->mapbase, size, dev_name(port->dev))) { -- GitLab From 00661dd855b5b174aa176a9ab9437d86ef4f8f1a Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 18 Nov 2015 14:41:12 +0000 Subject: [PATCH 1179/2855] ARM: meson: serial: don't reset port on uart startup When the uart startup entry is called, do not reset the port as this could cause issues with anything left in the FIFO from a previous operation such as a console write. Move the hardware reset to probe time and simply clear the errors before enabling the port. This fixes the issue where the console could become corrupted as there where characters left in the output or output fifo when a user process such as systemd would open/close the uart to transmit characters. For example, you get: [ 3.252263] systemd[1]: Dete instead of: [ 3.338801] systemd[1]: Detected architecture arm. Signed-off-by: Ben Dooks Tested-by: Carlo Caione Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index b9f0829ceda1e..b87eb97e5e7af 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -241,10 +241,9 @@ static const char *meson_uart_type(struct uart_port *port) return (port->type == PORT_MESON) ? "meson_uart" : NULL; } -static int meson_uart_startup(struct uart_port *port) +static void meson_uart_reset(struct uart_port *port) { u32 val; - int ret = 0; val = readl(port->membase + AML_UART_CONTROL); val |= (AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR); @@ -252,6 +251,18 @@ static int meson_uart_startup(struct uart_port *port) val &= ~(AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR); writel(val, port->membase + AML_UART_CONTROL); +} + +static int meson_uart_startup(struct uart_port *port) +{ + u32 val; + int ret = 0; + + val = readl(port->membase + AML_UART_CONTROL); + val |= AML_UART_CLR_ERR; + writel(val, port->membase + AML_UART_CONTROL); + val &= ~AML_UART_CLR_ERR; + writel(val, port->membase + AML_UART_CONTROL); val |= (AML_UART_RX_EN | AML_UART_TX_EN); writel(val, port->membase + AML_UART_CONTROL); @@ -581,6 +592,12 @@ static int meson_uart_probe(struct platform_device *pdev) meson_ports[pdev->id] = port; platform_set_drvdata(pdev, port); + /* reset port before registering (and possibly registering console) */ + if (meson_uart_request_port(port) >= 0) { + meson_uart_reset(port); + meson_uart_release_port(port); + } + ret = uart_add_one_port(&meson_uart_driver, port); if (ret) meson_ports[pdev->id] = NULL; -- GitLab From 88679739012cda64b1a45ee9dea16d04380dba71 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 18 Nov 2015 14:41:13 +0000 Subject: [PATCH 1180/2855] ARM: meson: serial: tx_empty fails to check for transmitter busy The tx_empty() uart_op should only return empty if both the transmit fifo and the transmit state-machine are both idle. Add a test for the hardware's XMIT_BUSY flag. Note, this is possibly related to an issue where the port is being shutdown with paritally transmitted characters in it. Signed-off-by: Ben Dooks Reported-by: Edward Cragg Tested-by: Carlo Caione Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index b87eb97e5e7af..54d1b9591b8da 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -57,6 +57,7 @@ #define AML_UART_RX_EMPTY BIT(20) #define AML_UART_TX_FULL BIT(21) #define AML_UART_TX_EMPTY BIT(22) +#define AML_UART_XMIT_BUSY BIT(25) #define AML_UART_ERR (AML_UART_PARITY_ERR | \ AML_UART_FRAME_ERR | \ AML_UART_TX_FIFO_WERR) @@ -100,7 +101,8 @@ static unsigned int meson_uart_tx_empty(struct uart_port *port) u32 val; val = readl(port->membase + AML_UART_STATUS); - return (val & AML_UART_TX_EMPTY) ? TIOCSER_TEMT : 0; + val &= (AML_UART_TX_EMPTY | AML_UART_XMIT_BUSY); + return (val == AML_UART_TX_EMPTY) ? TIOCSER_TEMT : 0; } static void meson_uart_stop_tx(struct uart_port *port) -- GitLab From 41788f054920d591c2d44838b73457e9d33ebd2c Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 18 Nov 2015 14:41:14 +0000 Subject: [PATCH 1181/2855] ARM: meson: serial: ensure console port uart enabled Ensure the UART's transmitter is enabled when meson_console_putchar is called. If not, then the console output is corrupt (the hardware seems to try and send /something/ even if the TX is disabled). This fixes corrupt console output on events such as trying to reboot the system since the console tx may be called after drivers shutdown method has been called. Signed-off-by: Ben Dooks Reported-by: Edward Cragg Tested-by: Carlo Caione Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 54d1b9591b8da..c7bad2b5aa494 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -472,6 +472,7 @@ static void meson_serial_console_write(struct console *co, const char *s, struct uart_port *port; unsigned long flags; int locked; + u32 val; port = meson_ports[co->index]; if (!port) @@ -487,6 +488,9 @@ static void meson_serial_console_write(struct console *co, const char *s, locked = 1; } + val = readl(port->membase + AML_UART_CONTROL); + writel(val | AML_UART_TX_EN, port->membase + AML_UART_CONTROL); + uart_console_write(port, s, count, meson_console_putchar); if (locked) -- GitLab From 855ddcab352c15b8c4d0bd93759f821250c601fb Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 18 Nov 2015 14:41:15 +0000 Subject: [PATCH 1182/2855] ARM: meson: serial: only disable tx irq on stop Since disabling the transmit state machine still allows characters to be transmitted when written to the UART write FIFO, simply disable the transmit interrupt when the UART port is stopped. This has not shown an improvement with the console issues when running systemd, but seems like it should be done. Signed-off-by: Ben Dooks Reported-by: Edward Cragg Tested-by: Carlo Caione Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index c7bad2b5aa494..9327efd889180 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -110,7 +110,7 @@ static void meson_uart_stop_tx(struct uart_port *port) u32 val; val = readl(port->membase + AML_UART_CONTROL); - val &= ~AML_UART_TX_EN; + val &= ~AML_UART_TX_INT_EN; writel(val, port->membase + AML_UART_CONTROL); } @@ -133,7 +133,7 @@ static void meson_uart_shutdown(struct uart_port *port) spin_lock_irqsave(&port->lock, flags); val = readl(port->membase + AML_UART_CONTROL); - val &= ~(AML_UART_RX_EN | AML_UART_TX_EN); + val &= ~AML_UART_RX_EN; val &= ~(AML_UART_RX_INT_EN | AML_UART_TX_INT_EN); writel(val, port->membase + AML_UART_CONTROL); -- GitLab From f1f5c1400f7907a1b52be94cabe8992b480785cf Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 18 Nov 2015 14:41:16 +0000 Subject: [PATCH 1183/2855] ARM: meson: serial: use meson_uart_tx_empty() to wait for empty Use the meson_uart_tx_empty() instead of a direct read of the status register. This is easier to read and will ensure the UART's transmit state machine is idle when trying to update the baud rate. Signed-off-by: Ben Dooks Tested-by: Carlo Caione Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 9327efd889180..d3f2c967906cf 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -285,7 +285,7 @@ static void meson_uart_change_speed(struct uart_port *port, unsigned long baud) { u32 val; - while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_EMPTY)) + while (!meson_uart_tx_empty(port)) cpu_relax(); val = readl(port->membase + AML_UART_REG5); -- GitLab From 2561f068d91bbb1bd132b439c9023120c0b28cf4 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 18 Nov 2015 14:41:17 +0000 Subject: [PATCH 1184/2855] ARM: meson: serial: disable rx/tx irqs during console write As an attempt to stop issues with bad console output, ensure that both the rx and tx interrupts are disabled during the console write to avoid any problems with console and non-console being called together. This should help with the SMP case as it should stop other cores being signalled during the console write. Signed-off-by: Ben Dooks Tested-by: Carlo Caione Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index d3f2c967906cf..12436cceebb7f 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -472,7 +472,7 @@ static void meson_serial_console_write(struct console *co, const char *s, struct uart_port *port; unsigned long flags; int locked; - u32 val; + u32 val, tmp; port = meson_ports[co->index]; if (!port) @@ -489,9 +489,12 @@ static void meson_serial_console_write(struct console *co, const char *s, } val = readl(port->membase + AML_UART_CONTROL); - writel(val | AML_UART_TX_EN, port->membase + AML_UART_CONTROL); + val |= AML_UART_TX_EN; + tmp = val & ~(AML_UART_TX_INT_EN | AML_UART_RX_INT_EN); + writel(tmp, port->membase + AML_UART_CONTROL); uart_console_write(port, s, count, meson_console_putchar); + writel(val, port->membase + AML_UART_CONTROL); if (locked) spin_unlock(&port->lock); -- GitLab From f1dd05c82985f9c476969598fd97cc680f18e86b Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 18 Nov 2015 14:41:18 +0000 Subject: [PATCH 1185/2855] ARM: meson: serial: ensure tx irq on if more work to do The tx_stop() call turns the interrupt off, but the tx_start() does not check if the interrupt is enabled. Switch it back on if there is more work to do. Signed-off-by: Ben Dooks Tested-by: Carlo Caione Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 12436cceebb7f..6c365267e26a1 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -144,6 +144,7 @@ static void meson_uart_start_tx(struct uart_port *port) { struct circ_buf *xmit = &port->state->xmit; unsigned int ch; + u32 val; if (uart_tx_stopped(port)) { meson_uart_stop_tx(port); @@ -167,6 +168,12 @@ static void meson_uart_start_tx(struct uart_port *port) port->icount.tx++; } + if (!uart_circ_empty(xmit)) { + val = readl(port->membase + AML_UART_CONTROL); + val |= AML_UART_TX_INT_EN; + writel(val, port->membase + AML_UART_CONTROL); + } + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); } -- GitLab From 39469654db20a14915a7fb33ca2ec67547011ece Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 18 Nov 2015 14:41:19 +0000 Subject: [PATCH 1186/2855] ARM: meson: serial: check for tx-irq enabled in irq code Ensure that if the interrupt handler is entered then only try and do tx work if the tx irq is enabled. Signed-off-by: Ben Dooks Tested-by: Carlo Caione Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 6c365267e26a1..b12a37bd37b63 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -237,8 +237,10 @@ static irqreturn_t meson_uart_interrupt(int irq, void *dev_id) if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY)) meson_receive_chars(port); - if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL)) - meson_uart_start_tx(port); + if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL)) { + if (readl(port->membase + AML_UART_CONTROL) & AML_UART_TX_INT_EN) + meson_uart_start_tx(port); + } spin_unlock(&port->lock); -- GitLab From dd42bf1197144ede075a9d4793123f7689e164bc Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 27 Nov 2015 14:30:21 -0500 Subject: [PATCH 1187/2855] tty: Prevent ldisc drivers from re-using stale tty fields Line discipline drivers may mistakenly misuse ldisc-related fields when initializing. For example, a failure to initialize tty->receive_room in the N_GIGASET_M101 line discipline was recently found and fixed [1]. Now, the N_X25 line discipline has been discovered accessing the previous line discipline's already-freed private data [2]. Harden the ldisc interface against misuse by initializing revelant tty fields before instancing the new line discipline. [1] commit fd98e9419d8d622a4de91f76b306af6aa627aa9c Author: Tilman Schmidt Date: Tue Jul 14 00:37:13 2015 +0200 isdn/gigaset: reset tty->receive_room when attaching ser_gigaset [2] Report from Sasha Levin [ 634.336761] ================================================================== [ 634.338226] BUG: KASAN: use-after-free in x25_asy_open_tty+0x13d/0x490 at addr ffff8800a743efd0 [ 634.339558] Read of size 4 by task syzkaller_execu/8981 [ 634.340359] ============================================================================= [ 634.341598] BUG kmalloc-512 (Not tainted): kasan: bad access detected ... [ 634.405018] Call Trace: [ 634.405277] dump_stack (lib/dump_stack.c:52) [ 634.405775] print_trailer (mm/slub.c:655) [ 634.406361] object_err (mm/slub.c:662) [ 634.406824] kasan_report_error (mm/kasan/report.c:138 mm/kasan/report.c:236) [ 634.409581] __asan_report_load4_noabort (mm/kasan/report.c:279) [ 634.411355] x25_asy_open_tty (drivers/net/wan/x25_asy.c:559 (discriminator 1)) [ 634.413997] tty_ldisc_open.isra.2 (drivers/tty/tty_ldisc.c:447) [ 634.414549] tty_set_ldisc (drivers/tty/tty_ldisc.c:567) [ 634.415057] tty_ioctl (drivers/tty/tty_io.c:2646 drivers/tty/tty_io.c:2879) [ 634.423524] do_vfs_ioctl (fs/ioctl.c:43 fs/ioctl.c:607) [ 634.427491] SyS_ioctl (fs/ioctl.c:622 fs/ioctl.c:613) [ 634.427945] entry_SYSCALL_64_fastpath (arch/x86/entry/entry_64.S:188) Cc: Tilman Schmidt Cc: Sasha Levin Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 9ec1250463436..a054d03c22e7b 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -417,6 +417,10 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush); * they are not on hot paths so a little discipline won't do * any harm. * + * The line discipline-related tty_struct fields are reset to + * prevent the ldisc driver from re-using stale information for + * the new ldisc instance. + * * Locking: takes termios_rwsem */ @@ -425,6 +429,9 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num) down_write(&tty->termios_rwsem); tty->termios.c_line = num; up_write(&tty->termios_rwsem); + + tty->disc_data = NULL; + tty->receive_room = 0; } /** -- GitLab From 0ff4230584320b2153752ba54e2e8edbd6addf2c Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Thu, 10 Dec 2015 13:26:21 +0200 Subject: [PATCH 1188/2855] serial: 8250_mid: fix broken DMA dependency In order to enable HSU DMA PCI driver, the HSU DMA Engine must be enabled. This add a check for that. Reported-by: kbuild test robot Signed-off-by: Heikki Krogerus Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 54f8af8ab4fb5..b03cb51751130 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -371,7 +371,7 @@ config SERIAL_8250_MID tristate "Support for serial ports on Intel MID platforms" depends on SERIAL_8250 && PCI select HSU_DMA if SERIAL_8250_DMA - select HSU_DMA_PCI if X86_INTEL_MID + select HSU_DMA_PCI if (HSU_DMA && X86_INTEL_MID) select RATIONAL help Selecting this option will enable handling of the extra features -- GitLab From 858965d909db32fb567a06916bbebdb8951cd39e Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 27 Nov 2015 21:29:24 -0500 Subject: [PATCH 1189/2855] serial: Fix UPIO_MEM comment The original semantics of UPIO_MEM did not include the notion of bitness and endianness; different drivers used UPIO_MEM to refer to their original mmio bitness/endianness. For example, for the 8250 driver this is 8-bit LE but for the amba-pl011 driver this is 16-bit LE. Since UPIO_* values are userspace ABI via TIOCGSERIAL/TIOCSSERIAL ioctls, the original meaning of UPIIO_MEM must remain as it was: the original mmio stride/width/endianness of the driver. Signed-off-by: Peter Hurley Acked-by: Timur Tabi Signed-off-by: Greg Kroah-Hartman --- include/linux/serial_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 35aa87b96b711..e03d6ba5e5b42 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -145,7 +145,7 @@ struct uart_port { #define UPIO_PORT (SERIAL_IO_PORT) /* 8b I/O port access */ #define UPIO_HUB6 (SERIAL_IO_HUB6) /* Hub6 ISA card */ -#define UPIO_MEM (SERIAL_IO_MEM) /* 8b MMIO access */ +#define UPIO_MEM (SERIAL_IO_MEM) /* driver-specific */ #define UPIO_MEM32 (SERIAL_IO_MEM32) /* 32b little endian */ #define UPIO_AU (SERIAL_IO_AU) /* Au1x00 and RT288x type IO */ #define UPIO_TSI (SERIAL_IO_TSI) /* Tsi108/109 type IO */ -- GitLab From ba4f10ae1b731a7c2ceff49977e6df336805b839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frederik=20V=C3=B6lkel?= Date: Fri, 11 Dec 2015 11:36:01 +0100 Subject: [PATCH 1190/2855] drivers: tty: 68328serial.c: Add missing spaces(checkpatch) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds missing spaces reported by checkpatch. Signed-off-by: Frederik Völkel Signed-off-by: Lukas Braun Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/68328serial.c | 92 ++++++++++++++++---------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index 0140ba4aacded..4cdd8054db823 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c @@ -274,8 +274,8 @@ static void receive_chars(struct m68k_serial *info, unsigned short rx) #endif ch = GET_FIELD(rx, URX_RXDATA); - if(info->is_cons) { - if(URX_BREAK & rx) { /* whee, break received */ + if (info->is_cons) { + if (URX_BREAK & rx) { /* whee, break received */ return; #ifdef CONFIG_MAGIC_SYSRQ } else if (ch == 0x10) { /* ^P */ @@ -302,7 +302,7 @@ static void receive_chars(struct m68k_serial *info, unsigned short rx) tty_insert_flip_char(&info->tport, ch, flag); #ifndef CONFIG_XCOPILOT_BUGS - } while((rx = uart->urx.w) & URX_DATA_READY); + } while ((rx = uart->urx.w) & URX_DATA_READY); #endif tty_schedule_flip(&info->tport); @@ -330,7 +330,7 @@ static void transmit_chars(struct m68k_serial *info, struct tty_struct *tty) info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); info->xmit_cnt--; - if(info->xmit_cnt <= 0) { + if (info->xmit_cnt <= 0) { /* All done for now... TX ints off */ uart->ustcnt &= ~USTCNT_TX_INTR_MASK; goto clear_and_return; @@ -452,45 +452,45 @@ struct { } #ifndef CONFIG_M68VZ328 hw_baud_table[18] = { - {0,0}, /* 0 */ - {0,0}, /* 50 */ - {0,0}, /* 75 */ - {0,0}, /* 110 */ - {0,0}, /* 134 */ - {0,0}, /* 150 */ - {0,0}, /* 200 */ - {7,0x26}, /* 300 */ - {6,0x26}, /* 600 */ - {5,0x26}, /* 1200 */ - {0,0}, /* 1800 */ - {4,0x26}, /* 2400 */ - {3,0x26}, /* 4800 */ - {2,0x26}, /* 9600 */ - {1,0x26}, /* 19200 */ - {0,0x26}, /* 38400 */ - {1,0x38}, /* 57600 */ - {0,0x38}, /* 115200 */ + {0, 0}, /* 0 */ + {0, 0}, /* 50 */ + {0, 0}, /* 75 */ + {0, 0}, /* 110 */ + {0, 0}, /* 134 */ + {0, 0}, /* 150 */ + {0, 0}, /* 200 */ + {7, 0x26}, /* 300 */ + {6, 0x26}, /* 600 */ + {5, 0x26}, /* 1200 */ + {0, 0}, /* 1800 */ + {4, 0x26}, /* 2400 */ + {3, 0x26}, /* 4800 */ + {2, 0x26}, /* 9600 */ + {1, 0x26}, /* 19200 */ + {0, 0x26}, /* 38400 */ + {1, 0x38}, /* 57600 */ + {0, 0x38}, /* 115200 */ }; #else hw_baud_table[18] = { - {0,0}, /* 0 */ - {0,0}, /* 50 */ - {0,0}, /* 75 */ - {0,0}, /* 110 */ - {0,0}, /* 134 */ - {0,0}, /* 150 */ - {0,0}, /* 200 */ - {0,0}, /* 300 */ - {7,0x26}, /* 600 */ - {6,0x26}, /* 1200 */ - {0,0}, /* 1800 */ - {5,0x26}, /* 2400 */ - {4,0x26}, /* 4800 */ - {3,0x26}, /* 9600 */ - {2,0x26}, /* 19200 */ - {1,0x26}, /* 38400 */ - {0,0x26}, /* 57600 */ - {1,0x38}, /* 115200 */ + {0, 0}, /* 0 */ + {0, 0}, /* 50 */ + {0, 0}, /* 75 */ + {0, 0}, /* 110 */ + {0, 0}, /* 134 */ + {0, 0}, /* 150 */ + {0, 0}, /* 200 */ + {0, 0}, /* 300 */ + {7, 0x26}, /* 600 */ + {6, 0x26}, /* 1200 */ + {0, 0}, /* 1800 */ + {5, 0x26}, /* 2400 */ + {4, 0x26}, /* 4800 */ + {3, 0x26}, /* 9600 */ + {2, 0x26}, /* 19200 */ + {1, 0x26}, /* 38400 */ + {0, 0x26}, /* 57600 */ + {1, 0x38}, /* 115200 */ }; #endif /* rate = 1036800 / ((65 - prescale) * (1<name, "rs_flush_chars")) return; #ifndef USE_INTS - for(;;) { + for (;;) { #endif /* Enable transmitter */ @@ -700,7 +700,7 @@ static int rs_write(struct tty_struct * tty, /* Enable transmitter */ local_irq_disable(); #ifndef USE_INTS - while(info->xmit_cnt) { + while (info->xmit_cnt) { #endif uart->ustcnt |= USTCNT_TXEN; @@ -1180,7 +1180,7 @@ rs68328_init(void) local_irq_save(flags); - for(i=0;itport); @@ -1263,7 +1263,7 @@ int m68328_console_setup(struct console *cp, char *arg) return(-1); if (arg) - n = simple_strtoul(arg,NULL,0); + n = simple_strtoul(arg, NULL, 0); for (i = 0; i < ARRAY_SIZE(baud_table); i++) if (baud_table[i] == n) -- GitLab From 4b7bb2b288d32abd854c41a54ba1da2be462f43b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frederik=20V=C3=B6lkel?= Date: Fri, 11 Dec 2015 11:36:02 +0100 Subject: [PATCH 1191/2855] drivers: tty: 68328serial.c: remove unnecessary spaces(checkpatch) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch removes unnecessary spaces reported by checkpatch. Signed-off-by: Frederik Völkel Signed-off-by: Lukas Braun Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/68328serial.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index 4cdd8054db823..b26cbae609ef1 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c @@ -538,7 +538,7 @@ static void change_speed(struct m68k_serial *info, struct tty_struct *tty) #ifdef CONFIG_SERIAL_68328_RTS_CTS if (cflag & CRTSCTS) { - uart->utx.w &= ~ UTX_NOCTS; + uart->utx.w &= ~UTX_NOCTS; } else { uart->utx.w |= UTX_NOCTS; } @@ -1198,7 +1198,7 @@ rs68328_init(void) printk(" is a builtin MC68328 UART\n"); #ifdef CONFIG_M68VZ328 - if (i > 0 ) + if (i > 0) PJSEL &= 0xCF; /* PSW enable second port output */ #endif @@ -1298,7 +1298,7 @@ void m68328_console_write (struct console *co, const char *str, while (count--) { if (*str == '\n') rs_put_char('\r'); - rs_put_char( *str++ ); + rs_put_char(*str++); } } -- GitLab From e836ed7a2f549b605d10d5ff7b2ea72f2f024d99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frederik=20V=C3=B6lkel?= Date: Fri, 11 Dec 2015 11:36:03 +0100 Subject: [PATCH 1192/2855] drivers: tty: 68328serial.c: Do not initialize statics to 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch removes an initialization of a static to 0 as checkpatch suggests. Signed-off-by: Frederik Völkel Signed-off-by: Lukas Braun Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/68328serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index b26cbae609ef1..b6d7230c20868 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c @@ -157,7 +157,7 @@ static void change_speed(struct m68k_serial *info, struct tty_struct *tty); #endif -static int m68328_console_initted = 0; +static int m68328_console_initted; static int m68328_console_baud = CONSOLE_BAUD_RATE; static int m68328_console_cbaud = DEFAULT_CBAUD; -- GitLab From 2ababf9e791180a997ab367dfa97c1a7085bd170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frederik=20V=C3=B6lkel?= Date: Fri, 11 Dec 2015 11:36:04 +0100 Subject: [PATCH 1193/2855] drivers: tty: 68328serial.c: Fix "foo * bar" should be "foo *bar" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes checkpatch errors "foo * bar" should be "foo *bar". Signed-off-by: Frederik Völkel Signed-off-by: Lukas Braun Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/68328serial.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index b6d7230c20868..8d58517232efa 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c @@ -659,9 +659,9 @@ static void rs_flush_chars(struct tty_struct *tty) local_irq_restore(flags); } -extern void console_printn(const char * b, int count); +extern void console_printn(const char *b, int count); -static int rs_write(struct tty_struct * tty, +static int rs_write(struct tty_struct *tty, const unsigned char *buf, int count) { int c, total = 0; @@ -767,7 +767,7 @@ static void rs_flush_buffer(struct tty_struct *tty) * incoming characters should be throttled. * ------------------------------------------------------------ */ -static void rs_throttle(struct tty_struct * tty) +static void rs_throttle(struct tty_struct *tty) { struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; @@ -780,7 +780,7 @@ static void rs_throttle(struct tty_struct * tty) /* Turn off RTS line (do this atomic) */ } -static void rs_unthrottle(struct tty_struct * tty) +static void rs_unthrottle(struct tty_struct *tty) { struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; @@ -803,8 +803,8 @@ static void rs_unthrottle(struct tty_struct * tty) * ------------------------------------------------------------ */ -static int get_serial_info(struct m68k_serial * info, - struct serial_struct * retinfo) +static int get_serial_info(struct m68k_serial *info, + struct serial_struct *retinfo) { struct serial_struct tmp; @@ -827,7 +827,7 @@ static int get_serial_info(struct m68k_serial * info, } static int set_serial_info(struct m68k_serial *info, struct tty_struct *tty, - struct serial_struct * new_info) + struct serial_struct *new_info) { struct tty_port *port = &info->tport; struct serial_struct new_serial; @@ -883,7 +883,7 @@ check_and_exit: * transmit holding register is empty. This functionality * allows an RS485 driver to be written in user space. */ -static int get_lsr_info(struct m68k_serial * info, unsigned int *value) +static int get_lsr_info(struct m68k_serial *info, unsigned int *value) { #ifdef CONFIG_SERIAL_68328_RTS_CTS m68328_uart *uart = &uart_addr[info->line]; @@ -904,7 +904,7 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value) /* * This routine sends a break character out the serial port. */ -static void send_break(struct m68k_serial * info, unsigned int duration) +static void send_break(struct m68k_serial *info, unsigned int duration) { m68328_uart *uart = &uart_addr[info->line]; unsigned long flags; @@ -922,7 +922,7 @@ static void send_break(struct m68k_serial * info, unsigned int duration) static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { - struct m68k_serial * info = (struct m68k_serial *)tty->driver_data; + struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; int retval; if (serial_paranoia_check(info, tty->name, "rs_ioctl")) @@ -992,9 +992,9 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) * that IRQ if nothing is left in the chain. * ------------------------------------------------------------ */ -static void rs_close(struct tty_struct *tty, struct file * filp) +static void rs_close(struct tty_struct *tty, struct file *filp) { - struct m68k_serial * info = (struct m68k_serial *)tty->driver_data; + struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; struct tty_port *port = &info->tport; m68328_uart *uart = &uart_addr[info->line]; unsigned long flags; @@ -1079,7 +1079,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) */ void rs_hangup(struct tty_struct *tty) { - struct m68k_serial * info = (struct m68k_serial *)tty->driver_data; + struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; if (serial_paranoia_check(info, tty->name, "rs_hangup")) return; @@ -1098,7 +1098,7 @@ void rs_hangup(struct tty_struct *tty) * the IRQ chain. It also performs the serial-specific * initialization for the tty structure. */ -int rs_open(struct tty_struct *tty, struct file * filp) +int rs_open(struct tty_struct *tty, struct file *filp) { struct m68k_serial *info; int retval; -- GitLab From 5cbb457e35f76a5a7b0dac30a07447e94a770057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frederik=20V=C3=B6lkel?= Date: Fri, 11 Dec 2015 11:36:05 +0100 Subject: [PATCH 1194/2855] drivers: tty: 68328serial.c: Remove parentheses after return MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch removes parentheses after return as checkpatch suggests. Signed-off-by: Frederik Völkel Signed-off-by: Lukas Braun Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/68328serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index 8d58517232efa..0982c1a441873 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c @@ -1279,7 +1279,7 @@ int m68328_console_setup(struct console *cp, char *arg) } m68328_set_baud(); /* make sure baud rate changes */ - return(0); + return 0; } -- GitLab From 4f71a2e0a282611e55bacb60b564eaef5d16c27b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 13 Dec 2015 11:30:02 +0100 Subject: [PATCH 1195/2855] serial: mctrl_gpio: export mctrl_gpio_disable_ms and mctrl_gpio_init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To be able to make use of the mctrl-gpio helper from a module these functions must be exported. This was forgotten in the commit introducing support interrupt handling for these functions (while it was done for mctrl_gpio_enable_ms, *sigh*). Fixes: ce59e48fdbad ("serial: mctrl_gpio: implement interrupt handling") Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_mctrl_gpio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c index 3eb57eb532f18..226ad23b136cb 100644 --- a/drivers/tty/serial/serial_mctrl_gpio.c +++ b/drivers/tty/serial/serial_mctrl_gpio.c @@ -193,6 +193,7 @@ struct mctrl_gpios *mctrl_gpio_init(struct uart_port *port, unsigned int idx) return gpios; } +EXPORT_SYMBOL_GPL(mctrl_gpio_init); void mctrl_gpio_free(struct device *dev, struct mctrl_gpios *gpios) { @@ -247,3 +248,4 @@ void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios) disable_irq(gpios->irq[i]); } } +EXPORT_SYMBOL_GPL(mctrl_gpio_disable_ms); -- GitLab From 58362d5be35216f196b4a4d16aa2c6ef938087f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 13 Dec 2015 11:30:03 +0100 Subject: [PATCH 1196/2855] serial: imx: implement handshaking using gpios with the mctrl_gpio helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 1 + drivers/tty/serial/imx.c | 89 +++++++++++++++++++++++++++++--------- 2 files changed, 70 insertions(+), 20 deletions(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 0bdf4d5c7c657..d27a0c62a75f3 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -576,6 +576,7 @@ config SERIAL_IMX depends on ARCH_MXC || COMPILE_TEST select SERIAL_CORE select RATIONAL + select SERIAL_MCTRL_GPIO if GPIOLIB help If you have a machine based on a Motorola IMX CPU you can enable its onboard serial port by enabling this option. diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 591f1c26e3e98..9362f54c816c9 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -44,6 +44,8 @@ #include #include +#include "serial_mctrl_gpio.h" + /* Register definitions */ #define URXD0 0x0 /* Receiver Register */ #define URTX0 0x40 /* Transmitter Register */ @@ -209,6 +211,8 @@ struct imx_port { struct clk *clk_per; const struct imx_uart_data *devdata; + struct mctrl_gpios *gpios; + /* DMA fields */ unsigned int dma_is_inited:1; unsigned int dma_is_enabled:1; @@ -311,6 +315,26 @@ static void imx_port_ucrs_restore(struct uart_port *port, } #endif +static void imx_port_rts_active(struct imx_port *sport, unsigned long *ucr2) +{ + *ucr2 &= ~UCR2_CTSC; + *ucr2 |= UCR2_CTS; + + mctrl_gpio_set(sport->gpios, sport->port.mctrl | TIOCM_RTS); +} + +static void imx_port_rts_inactive(struct imx_port *sport, unsigned long *ucr2) +{ + *ucr2 &= ~(UCR2_CTSC | UCR2_CTS); + + mctrl_gpio_set(sport->gpios, sport->port.mctrl & ~TIOCM_RTS); +} + +static void imx_port_rts_auto(struct imx_port *sport, unsigned long *ucr2) +{ + *ucr2 |= UCR2_CTSC; +} + /* * interrupts disabled on entry */ @@ -334,9 +358,9 @@ static void imx_stop_tx(struct uart_port *port) readl(port->membase + USR2) & USR2_TXDC) { temp = readl(port->membase + UCR2); if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) - temp &= ~UCR2_CTS; + imx_port_rts_inactive(sport, &temp); else - temp |= UCR2_CTS; + imx_port_rts_active(sport, &temp); writel(temp, port->membase + UCR2); temp = readl(port->membase + UCR4); @@ -378,6 +402,8 @@ static void imx_enable_ms(struct uart_port *port) struct imx_port *sport = (struct imx_port *)port; mod_timer(&sport->timer, jiffies); + + mctrl_gpio_enable_ms(sport->gpios); } static void imx_dma_tx(struct imx_port *sport); @@ -537,14 +563,14 @@ static void imx_start_tx(struct uart_port *port) unsigned long temp; if (port->rs485.flags & SER_RS485_ENABLED) { - /* enable transmitter and shifter empty irq */ temp = readl(port->membase + UCR2); if (port->rs485.flags & SER_RS485_RTS_ON_SEND) - temp &= ~UCR2_CTS; + imx_port_rts_inactive(sport, &temp); else - temp |= UCR2_CTS; + imx_port_rts_active(sport, &temp); writel(temp, port->membase + UCR2); + /* enable transmitter and shifter empty irq */ temp = readl(port->membase + UCR4); temp |= UCR4_TCEN; writel(temp, port->membase + UCR4); @@ -759,9 +785,8 @@ static unsigned int imx_tx_empty(struct uart_port *port) /* * We have a modem side uart, so the meanings of RTS and CTS are inverted. */ -static unsigned int imx_get_mctrl(struct uart_port *port) +static unsigned int imx_get_hwmctrl(struct imx_port *sport) { - struct imx_port *sport = (struct imx_port *)port; unsigned int tmp = TIOCM_DSR; unsigned usr1 = readl(sport->port.membase + USR1); @@ -779,6 +804,16 @@ static unsigned int imx_get_mctrl(struct uart_port *port) return tmp; } +static unsigned int imx_get_mctrl(struct uart_port *port) +{ + struct imx_port *sport = (struct imx_port *)port; + unsigned int ret = imx_get_hwmctrl(sport); + + mctrl_gpio_get(sport->gpios, &ret); + + return ret; +} + static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl) { struct imx_port *sport = (struct imx_port *)port; @@ -801,6 +836,8 @@ static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl) if (mctrl & TIOCM_LOOP) temp |= UTS_LOOP; writel(temp, sport->port.membase + uts_reg(sport)); + + mctrl_gpio_set(sport->gpios, mctrl); } /* @@ -830,7 +867,7 @@ static void imx_mctrl_check(struct imx_port *sport) { unsigned int status, changed; - status = imx_get_mctrl(&sport->port); + status = imx_get_hwmctrl(sport); changed = status ^ sport->old_status; if (changed == 0) @@ -1218,6 +1255,8 @@ static void imx_shutdown(struct uart_port *port) imx_uart_dma_exit(sport); } + mctrl_gpio_disable_ms(sport->gpios); + spin_lock_irqsave(&sport->port.lock, flags); temp = readl(sport->port.membase + UCR2); temp &= ~(UCR2_TXEN); @@ -1295,9 +1334,10 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, { struct imx_port *sport = (struct imx_port *)port; unsigned long flags; - unsigned int ucr2, old_ucr1, old_ucr2, baud, quot; + unsigned long ucr2, old_ucr1, old_ucr2; + unsigned int baud, quot; unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; - unsigned int div, ufcr; + unsigned long div, ufcr; unsigned long num, denom; uint64_t tdiv64; @@ -1326,19 +1366,25 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, * it under manual control and keep transmitter * disabled. */ - if (!(port->rs485.flags & - SER_RS485_RTS_AFTER_SEND)) - ucr2 |= UCR2_CTS; + if (port->rs485.flags & + SER_RS485_RTS_AFTER_SEND) + imx_port_rts_inactive(sport, &ucr2); + else + imx_port_rts_active(sport, &ucr2); } else { - ucr2 |= UCR2_CTSC; + imx_port_rts_auto(sport, &ucr2); } } else { termios->c_cflag &= ~CRTSCTS; } - } else if (port->rs485.flags & SER_RS485_ENABLED) + } else if (port->rs485.flags & SER_RS485_ENABLED) { /* disable transmitter */ - if (!(port->rs485.flags & SER_RS485_RTS_AFTER_SEND)) - ucr2 |= UCR2_CTS; + if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) + imx_port_rts_inactive(sport, &ucr2); + else + imx_port_rts_active(sport, &ucr2); + } + if (termios->c_cflag & CSTOPB) ucr2 |= UCR2_STPB; @@ -1579,11 +1625,10 @@ static int imx_rs485_config(struct uart_port *port, /* disable transmitter */ temp = readl(sport->port.membase + UCR2); - temp &= ~UCR2_CTSC; if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND) - temp &= ~UCR2_CTS; + imx_port_rts_inactive(sport, &temp); else - temp |= UCR2_CTS; + imx_port_rts_active(sport, &temp); writel(temp, sport->port.membase + UCR2); } @@ -1956,6 +2001,10 @@ static int serial_imx_probe(struct platform_device *pdev) sport->timer.function = imx_timeout; sport->timer.data = (unsigned long)sport; + sport->gpios = mctrl_gpio_init(&sport->port, 0); + if (IS_ERR(sport->gpios)) + return PTR_ERR(sport->gpios); + sport->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); if (IS_ERR(sport->clk_ipg)) { ret = PTR_ERR(sport->clk_ipg); -- GitLab From 0863d7f2136550a281f40f4d8556bffd09fd4c2d Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Sat, 28 Nov 2015 22:39:33 +0530 Subject: [PATCH 1197/2855] powerpc/mm: Fix infinite loop in hash fault with 4K page size This is the same bug we fixed as part of 09567e7fd44291bfc08accfdd67ad8f467842332 ("powerpc/mm: Check paca psize is up to date for huge mappings"). Please check that for details. The difference here is that faults were happening on a 4K page at an address previously mapped by hugetlb. Signed-off-by: Aneesh Kumar K.V Reviewed-by: Anshuman Khandual Signed-off-by: Michael Ellerman --- arch/powerpc/mm/hash_utils_64.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 7f9616f7c4797..7d4f254a26719 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -1148,9 +1148,10 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, } } +#endif /* CONFIG_PPC_64K_PAGES */ + if (current->mm == mm) check_paca_psize(ea, mm, psize, user_region); -#endif /* CONFIG_PPC_64K_PAGES */ #ifdef CONFIG_PPC_64K_PAGES if (psize == MMU_PAGE_64K) -- GitLab From 26b6a3d9bb48f8b4624a62281bc2a295df3a8109 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:26 +0530 Subject: [PATCH 1198/2855] powerpc/mm: move pte headers to book3s directory Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- .../include/asm/{pte-hash32.h => book3s/32/hash.h} | 6 +++--- .../asm/{pte-hash64-4k.h => book3s/64/hash-4k.h} | 0 .../asm/{pte-hash64-64k.h => book3s/64/hash-64k.h} | 0 .../include/asm/{pte-hash64.h => book3s/64/hash.h} | 10 +++++----- arch/powerpc/include/asm/pgtable-ppc32.h | 2 +- arch/powerpc/include/asm/pgtable-ppc64.h | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) rename arch/powerpc/include/asm/{pte-hash32.h => book3s/32/hash.h} (93%) rename arch/powerpc/include/asm/{pte-hash64-4k.h => book3s/64/hash-4k.h} (100%) rename arch/powerpc/include/asm/{pte-hash64-64k.h => book3s/64/hash-64k.h} (100%) rename arch/powerpc/include/asm/{pte-hash64.h => book3s/64/hash.h} (90%) diff --git a/arch/powerpc/include/asm/pte-hash32.h b/arch/powerpc/include/asm/book3s/32/hash.h similarity index 93% rename from arch/powerpc/include/asm/pte-hash32.h rename to arch/powerpc/include/asm/book3s/32/hash.h index 62cfb0c663bb9..264b754d65b0b 100644 --- a/arch/powerpc/include/asm/pte-hash32.h +++ b/arch/powerpc/include/asm/book3s/32/hash.h @@ -1,5 +1,5 @@ -#ifndef _ASM_POWERPC_PTE_HASH32_H -#define _ASM_POWERPC_PTE_HASH32_H +#ifndef _ASM_POWERPC_BOOK3S_32_HASH_H +#define _ASM_POWERPC_BOOK3S_32_HASH_H #ifdef __KERNEL__ /* @@ -43,4 +43,4 @@ #define PTE_ATOMIC_UPDATES 1 #endif /* __KERNEL__ */ -#endif /* _ASM_POWERPC_PTE_HASH32_H */ +#endif /* _ASM_POWERPC_BOOK3S_32_HASH_H */ diff --git a/arch/powerpc/include/asm/pte-hash64-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h similarity index 100% rename from arch/powerpc/include/asm/pte-hash64-4k.h rename to arch/powerpc/include/asm/book3s/64/hash-4k.h diff --git a/arch/powerpc/include/asm/pte-hash64-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h similarity index 100% rename from arch/powerpc/include/asm/pte-hash64-64k.h rename to arch/powerpc/include/asm/book3s/64/hash-64k.h diff --git a/arch/powerpc/include/asm/pte-hash64.h b/arch/powerpc/include/asm/book3s/64/hash.h similarity index 90% rename from arch/powerpc/include/asm/pte-hash64.h rename to arch/powerpc/include/asm/book3s/64/hash.h index ef612c160da7c..8e60d4fa434d2 100644 --- a/arch/powerpc/include/asm/pte-hash64.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -1,5 +1,5 @@ -#ifndef _ASM_POWERPC_PTE_HASH64_H -#define _ASM_POWERPC_PTE_HASH64_H +#ifndef _ASM_POWERPC_BOOK3S_64_HASH_H +#define _ASM_POWERPC_BOOK3S_64_HASH_H #ifdef __KERNEL__ /* @@ -45,10 +45,10 @@ #define PTE_ATOMIC_UPDATES 1 #ifdef CONFIG_PPC_64K_PAGES -#include +#include #else -#include +#include #endif #endif /* __KERNEL__ */ -#endif /* _ASM_POWERPC_PTE_HASH64_H */ +#endif /* _ASM_POWERPC_BOOK3S_64_HASH_H */ diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h index 9c326565d498f..1a58a05be99c6 100644 --- a/arch/powerpc/include/asm/pgtable-ppc32.h +++ b/arch/powerpc/include/asm/pgtable-ppc32.h @@ -116,7 +116,7 @@ extern int icache_44x_need_flush; #elif defined(CONFIG_8xx) #include #else /* CONFIG_6xx */ -#include +#include #endif /* And here we include common definitions */ diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h index 3245f2d96d4f5..b36a932abdfb3 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64.h +++ b/arch/powerpc/include/asm/pgtable-ppc64.h @@ -98,7 +98,7 @@ * Include the PTE bits definitions */ #ifdef CONFIG_PPC_BOOK3S -#include +#include #else #include #endif -- GitLab From 3dfcb315d81e663bf70401de61940c1b4de2deea Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:28 +0530 Subject: [PATCH 1199/2855] powerpc/mm: make a separate copy for book3s In this patch we do: cp pgtable-ppc32.h book3s/32/pgtable.h cp pgtable-ppc64.h book3s/64/pgtable.h This enable us to do further changes to hash specific config. We will change the page table format for 64bit hash in later patches. Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/32/pgtable.h | 340 ++++++++++ arch/powerpc/include/asm/book3s/64/pgtable.h | 626 +++++++++++++++++++ arch/powerpc/include/asm/book3s/pgtable.h | 10 + arch/powerpc/include/asm/mmu-hash64.h | 2 +- arch/powerpc/include/asm/pgtable-ppc32.h | 2 - arch/powerpc/include/asm/pgtable-ppc64.h | 4 - arch/powerpc/include/asm/pgtable.h | 4 + 7 files changed, 981 insertions(+), 7 deletions(-) create mode 100644 arch/powerpc/include/asm/book3s/32/pgtable.h create mode 100644 arch/powerpc/include/asm/book3s/64/pgtable.h create mode 100644 arch/powerpc/include/asm/book3s/pgtable.h diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h new file mode 100644 index 0000000000000..418d2fa3ac7d8 --- /dev/null +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h @@ -0,0 +1,340 @@ +#ifndef _ASM_POWERPC_BOOK3S_32_PGTABLE_H +#define _ASM_POWERPC_BOOK3S_32_PGTABLE_H + +#include + +#ifndef __ASSEMBLY__ +#include +#include +#include /* For sub-arch specific PPC_PIN_SIZE */ + +extern unsigned long ioremap_bot; + +#ifdef CONFIG_44x +extern int icache_44x_need_flush; +#endif + +#endif /* __ASSEMBLY__ */ + +/* + * The normal case is that PTEs are 32-bits and we have a 1-page + * 1024-entry pgdir pointing to 1-page 1024-entry PTE pages. -- paulus + * + * For any >32-bit physical address platform, we can use the following + * two level page table layout where the pgdir is 8KB and the MS 13 bits + * are an index to the second level table. The combined pgdir/pmd first + * level has 2048 entries and the second level has 512 64-bit PTE entries. + * -Matt + */ +/* PGDIR_SHIFT determines what a top-level page table entry can map */ +#define PGDIR_SHIFT (PAGE_SHIFT + PTE_SHIFT) +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) + +/* + * entries per page directory level: our page-table tree is two-level, so + * we don't really have any PMD directory. + */ +#ifndef __ASSEMBLY__ +#define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_SHIFT) +#define PGD_TABLE_SIZE (sizeof(pgd_t) << (32 - PGDIR_SHIFT)) +#endif /* __ASSEMBLY__ */ + +#define PTRS_PER_PTE (1 << PTE_SHIFT) +#define PTRS_PER_PMD 1 +#define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT)) + +#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) +#define FIRST_USER_ADDRESS 0UL + +#define pte_ERROR(e) \ + pr_err("%s:%d: bad pte %llx.\n", __FILE__, __LINE__, \ + (unsigned long long)pte_val(e)) +#define pgd_ERROR(e) \ + pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) + +/* + * This is the bottom of the PKMAP area with HIGHMEM or an arbitrary + * value (for now) on others, from where we can start layout kernel + * virtual space that goes below PKMAP and FIXMAP + */ +#ifdef CONFIG_HIGHMEM +#define KVIRT_TOP PKMAP_BASE +#else +#define KVIRT_TOP (0xfe000000UL) /* for now, could be FIXMAP_BASE ? */ +#endif + +/* + * ioremap_bot starts at that address. Early ioremaps move down from there, + * until mem_init() at which point this becomes the top of the vmalloc + * and ioremap space + */ +#ifdef CONFIG_NOT_COHERENT_CACHE +#define IOREMAP_TOP ((KVIRT_TOP - CONFIG_CONSISTENT_SIZE) & PAGE_MASK) +#else +#define IOREMAP_TOP KVIRT_TOP +#endif + +/* + * Just any arbitrary offset to the start of the vmalloc VM area: the + * current 16MB value just means that there will be a 64MB "hole" after the + * physical memory until the kernel virtual memory starts. That means that + * any out-of-bounds memory accesses will hopefully be caught. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced + * area for the same reason. ;) + * + * We no longer map larger than phys RAM with the BATs so we don't have + * to worry about the VMALLOC_OFFSET causing problems. We do have to worry + * about clashes between our early calls to ioremap() that start growing down + * from ioremap_base being run into the VM area allocations (growing upwards + * from VMALLOC_START). For this reason we have ioremap_bot to check when + * we actually run into our mappings setup in the early boot with the VM + * system. This really does become a problem for machines with good amounts + * of RAM. -- Cort + */ +#define VMALLOC_OFFSET (0x1000000) /* 16M */ +#ifdef PPC_PIN_SIZE +#define VMALLOC_START (((_ALIGN((long)high_memory, PPC_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))) +#else +#define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))) +#endif +#define VMALLOC_END ioremap_bot + +/* + * Bits in a linux-style PTE. These match the bits in the + * (hardware-defined) PowerPC PTE as closely as possible. + */ + +#if defined(CONFIG_40x) +#include +#elif defined(CONFIG_44x) +#include +#elif defined(CONFIG_FSL_BOOKE) && defined(CONFIG_PTE_64BIT) +#include +#elif defined(CONFIG_FSL_BOOKE) +#include +#elif defined(CONFIG_8xx) +#include +#else /* CONFIG_6xx */ +#include +#endif + +/* And here we include common definitions */ +#include + +#ifndef __ASSEMBLY__ + +#define pte_clear(mm, addr, ptep) \ + do { pte_update(ptep, ~_PAGE_HASHPTE, 0); } while (0) + +#define pmd_none(pmd) (!pmd_val(pmd)) +#define pmd_bad(pmd) (pmd_val(pmd) & _PMD_BAD) +#define pmd_present(pmd) (pmd_val(pmd) & _PMD_PRESENT_MASK) +#define pmd_clear(pmdp) do { pmd_val(*(pmdp)) = 0; } while (0) + +/* + * When flushing the tlb entry for a page, we also need to flush the hash + * table entry. flush_hash_pages is assembler (for speed) in hashtable.S. + */ +extern int flush_hash_pages(unsigned context, unsigned long va, + unsigned long pmdval, int count); + +/* Add an HPTE to the hash table */ +extern void add_hash_page(unsigned context, unsigned long va, + unsigned long pmdval); + +/* Flush an entry from the TLB/hash table */ +extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, + unsigned long address); + +/* + * PTE updates. This function is called whenever an existing + * valid PTE is updated. This does -not- include set_pte_at() + * which nowadays only sets a new PTE. + * + * Depending on the type of MMU, we may need to use atomic updates + * and the PTE may be either 32 or 64 bit wide. In the later case, + * when using atomic updates, only the low part of the PTE is + * accessed atomically. + * + * In addition, on 44x, we also maintain a global flag indicating + * that an executable user mapping was modified, which is needed + * to properly flush the virtually tagged instruction cache of + * those implementations. + */ +#ifndef CONFIG_PTE_64BIT +static inline unsigned long pte_update(pte_t *p, + unsigned long clr, + unsigned long set) +{ +#ifdef PTE_ATOMIC_UPDATES + unsigned long old, tmp; + + __asm__ __volatile__("\ +1: lwarx %0,0,%3\n\ + andc %1,%0,%4\n\ + or %1,%1,%5\n" + PPC405_ERR77(0,%3) +" stwcx. %1,0,%3\n\ + bne- 1b" + : "=&r" (old), "=&r" (tmp), "=m" (*p) + : "r" (p), "r" (clr), "r" (set), "m" (*p) + : "cc" ); +#else /* PTE_ATOMIC_UPDATES */ + unsigned long old = pte_val(*p); + *p = __pte((old & ~clr) | set); +#endif /* !PTE_ATOMIC_UPDATES */ + +#ifdef CONFIG_44x + if ((old & _PAGE_USER) && (old & _PAGE_EXEC)) + icache_44x_need_flush = 1; +#endif + return old; +} +#else /* CONFIG_PTE_64BIT */ +static inline unsigned long long pte_update(pte_t *p, + unsigned long clr, + unsigned long set) +{ +#ifdef PTE_ATOMIC_UPDATES + unsigned long long old; + unsigned long tmp; + + __asm__ __volatile__("\ +1: lwarx %L0,0,%4\n\ + lwzx %0,0,%3\n\ + andc %1,%L0,%5\n\ + or %1,%1,%6\n" + PPC405_ERR77(0,%3) +" stwcx. %1,0,%4\n\ + bne- 1b" + : "=&r" (old), "=&r" (tmp), "=m" (*p) + : "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p) + : "cc" ); +#else /* PTE_ATOMIC_UPDATES */ + unsigned long long old = pte_val(*p); + *p = __pte((old & ~(unsigned long long)clr) | set); +#endif /* !PTE_ATOMIC_UPDATES */ + +#ifdef CONFIG_44x + if ((old & _PAGE_USER) && (old & _PAGE_EXEC)) + icache_44x_need_flush = 1; +#endif + return old; +} +#endif /* CONFIG_PTE_64BIT */ + +/* + * 2.6 calls this without flushing the TLB entry; this is wrong + * for our hash-based implementation, we fix that up here. + */ +#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG +static inline int __ptep_test_and_clear_young(unsigned int context, unsigned long addr, pte_t *ptep) +{ + unsigned long old; + old = pte_update(ptep, _PAGE_ACCESSED, 0); +#if _PAGE_HASHPTE != 0 + if (old & _PAGE_HASHPTE) { + unsigned long ptephys = __pa(ptep) & PAGE_MASK; + flush_hash_pages(context, addr, ptephys, 1); + } +#endif + return (old & _PAGE_ACCESSED) != 0; +} +#define ptep_test_and_clear_young(__vma, __addr, __ptep) \ + __ptep_test_and_clear_young((__vma)->vm_mm->context.id, __addr, __ptep) + +#define __HAVE_ARCH_PTEP_GET_AND_CLEAR +static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep) +{ + return __pte(pte_update(ptep, ~_PAGE_HASHPTE, 0)); +} + +#define __HAVE_ARCH_PTEP_SET_WRPROTECT +static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, + pte_t *ptep) +{ + pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), _PAGE_RO); +} +static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, + unsigned long addr, pte_t *ptep) +{ + ptep_set_wrprotect(mm, addr, ptep); +} + + +static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) +{ + unsigned long set = pte_val(entry) & + (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC); + unsigned long clr = ~pte_val(entry) & _PAGE_RO; + + pte_update(ptep, clr, set); +} + +#define __HAVE_ARCH_PTE_SAME +#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0) + +/* + * Note that on Book E processors, the pmd contains the kernel virtual + * (lowmem) address of the pte page. The physical address is less useful + * because everything runs with translation enabled (even the TLB miss + * handler). On everything else the pmd contains the physical address + * of the pte page. -- paulus + */ +#ifndef CONFIG_BOOKE +#define pmd_page_vaddr(pmd) \ + ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) +#define pmd_page(pmd) \ + pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT) +#else +#define pmd_page_vaddr(pmd) \ + ((unsigned long) (pmd_val(pmd) & PAGE_MASK)) +#define pmd_page(pmd) \ + pfn_to_page((__pa(pmd_val(pmd)) >> PAGE_SHIFT)) +#endif + +/* to find an entry in a kernel page-table-directory */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) + +/* to find an entry in a page-table-directory */ +#define pgd_index(address) ((address) >> PGDIR_SHIFT) +#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) + +/* Find an entry in the third-level page table.. */ +#define pte_index(address) \ + (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) +#define pte_offset_kernel(dir, addr) \ + ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(addr)) +#define pte_offset_map(dir, addr) \ + ((pte_t *) kmap_atomic(pmd_page(*(dir))) + pte_index(addr)) +#define pte_unmap(pte) kunmap_atomic(pte) + +/* + * Encode and decode a swap entry. + * Note that the bits we use in a PTE for representing a swap entry + * must not include the _PAGE_PRESENT bit or the _PAGE_HASHPTE bit (if used). + * -- paulus + */ +#define __swp_type(entry) ((entry).val & 0x1f) +#define __swp_offset(entry) ((entry).val >> 5) +#define __swp_entry(type, offset) ((swp_entry_t) { (type) | ((offset) << 5) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 3 }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val << 3 }) + +#ifndef CONFIG_PPC_4K_PAGES +void pgtable_cache_init(void); +#else +/* + * No page table caches to initialise + */ +#define pgtable_cache_init() do { } while (0) +#endif + +extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, + pmd_t **pmdp); + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_POWERPC_BOOK3S_32_PGTABLE_H */ diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h new file mode 100644 index 0000000000000..cdd5284d9eaa9 --- /dev/null +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -0,0 +1,626 @@ +#ifndef _ASM_POWERPC_BOOK3S_64_PGTABLE_H_ +#define _ASM_POWERPC_BOOK3S_64_PGTABLE_H_ +/* + * This file contains the functions and defines necessary to modify and use + * the ppc64 hashed page table. + */ + +#ifdef CONFIG_PPC_64K_PAGES +#include +#else +#include +#endif +#include + +#define FIRST_USER_ADDRESS 0UL + +/* + * Size of EA range mapped by our pagetables. + */ +#define PGTABLE_EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \ + PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT) +#define PGTABLE_RANGE (ASM_CONST(1) << PGTABLE_EADDR_SIZE) + +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +#define PMD_CACHE_INDEX (PMD_INDEX_SIZE + 1) +#else +#define PMD_CACHE_INDEX PMD_INDEX_SIZE +#endif +/* + * Define the address range of the kernel non-linear virtual area + */ + +#ifdef CONFIG_PPC_BOOK3E +#define KERN_VIRT_START ASM_CONST(0x8000000000000000) +#else +#define KERN_VIRT_START ASM_CONST(0xD000000000000000) +#endif +#define KERN_VIRT_SIZE ASM_CONST(0x0000100000000000) + +/* + * The vmalloc space starts at the beginning of that region, and + * occupies half of it on hash CPUs and a quarter of it on Book3E + * (we keep a quarter for the virtual memmap) + */ +#define VMALLOC_START KERN_VIRT_START +#ifdef CONFIG_PPC_BOOK3E +#define VMALLOC_SIZE (KERN_VIRT_SIZE >> 2) +#else +#define VMALLOC_SIZE (KERN_VIRT_SIZE >> 1) +#endif +#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE) + +/* + * The second half of the kernel virtual space is used for IO mappings, + * it's itself carved into the PIO region (ISA and PHB IO space) and + * the ioremap space + * + * ISA_IO_BASE = KERN_IO_START, 64K reserved area + * PHB_IO_BASE = ISA_IO_BASE + 64K to ISA_IO_BASE + 2G, PHB IO spaces + * IOREMAP_BASE = ISA_IO_BASE + 2G to VMALLOC_START + PGTABLE_RANGE + */ +#define KERN_IO_START (KERN_VIRT_START + (KERN_VIRT_SIZE >> 1)) +#define FULL_IO_SIZE 0x80000000ul +#define ISA_IO_BASE (KERN_IO_START) +#define ISA_IO_END (KERN_IO_START + 0x10000ul) +#define PHB_IO_BASE (ISA_IO_END) +#define PHB_IO_END (KERN_IO_START + FULL_IO_SIZE) +#define IOREMAP_BASE (PHB_IO_END) +#define IOREMAP_END (KERN_VIRT_START + KERN_VIRT_SIZE) + + +/* + * Region IDs + */ +#define REGION_SHIFT 60UL +#define REGION_MASK (0xfUL << REGION_SHIFT) +#define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT) + +#define VMALLOC_REGION_ID (REGION_ID(VMALLOC_START)) +#define KERNEL_REGION_ID (REGION_ID(PAGE_OFFSET)) +#define VMEMMAP_REGION_ID (0xfUL) /* Server only */ +#define USER_REGION_ID (0UL) + +/* + * Defines the address of the vmemap area, in its own region on + * hash table CPUs and after the vmalloc space on Book3E + */ +#ifdef CONFIG_PPC_BOOK3E +#define VMEMMAP_BASE VMALLOC_END +#define VMEMMAP_END KERN_IO_START +#else +#define VMEMMAP_BASE (VMEMMAP_REGION_ID << REGION_SHIFT) +#endif +#define vmemmap ((struct page *)VMEMMAP_BASE) + + +/* + * Include the PTE bits definitions + */ +#ifdef CONFIG_PPC_BOOK3S +#include +#else +#include +#endif +#include + +#ifdef CONFIG_PPC_MM_SLICES +#define HAVE_ARCH_UNMAPPED_AREA +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN +#endif /* CONFIG_PPC_MM_SLICES */ + +#ifndef __ASSEMBLY__ + +/* + * This is the default implementation of various PTE accessors, it's + * used in all cases except Book3S with 64K pages where we have a + * concept of sub-pages + */ +#ifndef __real_pte + +#ifdef CONFIG_STRICT_MM_TYPECHECKS +#define __real_pte(e,p) ((real_pte_t){(e)}) +#define __rpte_to_pte(r) ((r).pte) +#else +#define __real_pte(e,p) (e) +#define __rpte_to_pte(r) (__pte(r)) +#endif +#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >> 12) + +#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ + do { \ + index = 0; \ + shift = mmu_psize_defs[psize].shift; \ + +#define pte_iterate_hashed_end() } while(0) + +/* + * We expect this to be called only for user addresses or kernel virtual + * addresses other than the linear mapping. + */ +#define pte_pagesize_index(mm, addr, pte) MMU_PAGE_4K + +#endif /* __real_pte */ + + +/* pte_clear moved to later in this file */ + +#define PMD_BAD_BITS (PTE_TABLE_SIZE-1) +#define PUD_BAD_BITS (PMD_TABLE_SIZE-1) + +#define pmd_set(pmdp, pmdval) (pmd_val(*(pmdp)) = (pmdval)) +#define pmd_none(pmd) (!pmd_val(pmd)) +#define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \ + || (pmd_val(pmd) & PMD_BAD_BITS)) +#define pmd_present(pmd) (!pmd_none(pmd)) +#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0) +#define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS) +extern struct page *pmd_page(pmd_t pmd); + +#define pud_set(pudp, pudval) (pud_val(*(pudp)) = (pudval)) +#define pud_none(pud) (!pud_val(pud)) +#define pud_bad(pud) (!is_kernel_addr(pud_val(pud)) \ + || (pud_val(pud) & PUD_BAD_BITS)) +#define pud_present(pud) (pud_val(pud) != 0) +#define pud_clear(pudp) (pud_val(*(pudp)) = 0) +#define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS) + +extern struct page *pud_page(pud_t pud); + +static inline pte_t pud_pte(pud_t pud) +{ + return __pte(pud_val(pud)); +} + +static inline pud_t pte_pud(pte_t pte) +{ + return __pud(pte_val(pte)); +} +#define pud_write(pud) pte_write(pud_pte(pud)) +#define pgd_set(pgdp, pudp) ({pgd_val(*(pgdp)) = (unsigned long)(pudp);}) +#define pgd_write(pgd) pte_write(pgd_pte(pgd)) + +/* + * Find an entry in a page-table-directory. We combine the address region + * (the high order N bits) and the pgd portion of the address. + */ +#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD - 1)) + +#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) + +#define pmd_offset(pudp,addr) \ + (((pmd_t *) pud_page_vaddr(*(pudp))) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))) + +#define pte_offset_kernel(dir,addr) \ + (((pte_t *) pmd_page_vaddr(*(dir))) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))) + +#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr)) +#define pte_unmap(pte) do { } while(0) + +/* to find an entry in a kernel page-table-directory */ +/* This now only contains the vmalloc pages */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) +extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, unsigned long pte, int huge); + +/* Atomic PTE updates */ +static inline unsigned long pte_update(struct mm_struct *mm, + unsigned long addr, + pte_t *ptep, unsigned long clr, + unsigned long set, + int huge) +{ +#ifdef PTE_ATOMIC_UPDATES + unsigned long old, tmp; + + __asm__ __volatile__( + "1: ldarx %0,0,%3 # pte_update\n\ + andi. %1,%0,%6\n\ + bne- 1b \n\ + andc %1,%0,%4 \n\ + or %1,%1,%7\n\ + stdcx. %1,0,%3 \n\ + bne- 1b" + : "=&r" (old), "=&r" (tmp), "=m" (*ptep) + : "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY), "r" (set) + : "cc" ); +#else + unsigned long old = pte_val(*ptep); + *ptep = __pte((old & ~clr) | set); +#endif + /* huge pages use the old page table lock */ + if (!huge) + assert_pte_locked(mm, addr); + +#ifdef CONFIG_PPC_STD_MMU_64 + if (old & _PAGE_HASHPTE) + hpte_need_flush(mm, addr, ptep, old, huge); +#endif + + return old; +} + +static inline int __ptep_test_and_clear_young(struct mm_struct *mm, + unsigned long addr, pte_t *ptep) +{ + unsigned long old; + + if ((pte_val(*ptep) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0) + return 0; + old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0); + return (old & _PAGE_ACCESSED) != 0; +} +#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG +#define ptep_test_and_clear_young(__vma, __addr, __ptep) \ +({ \ + int __r; \ + __r = __ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep); \ + __r; \ +}) + +#define __HAVE_ARCH_PTEP_SET_WRPROTECT +static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, + pte_t *ptep) +{ + + if ((pte_val(*ptep) & _PAGE_RW) == 0) + return; + + pte_update(mm, addr, ptep, _PAGE_RW, 0, 0); +} + +static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, + unsigned long addr, pte_t *ptep) +{ + if ((pte_val(*ptep) & _PAGE_RW) == 0) + return; + + pte_update(mm, addr, ptep, _PAGE_RW, 0, 1); +} + +/* + * We currently remove entries from the hashtable regardless of whether + * the entry was young or dirty. The generic routines only flush if the + * entry was young or dirty which is not good enough. + * + * We should be more intelligent about this but for the moment we override + * these functions and force a tlb flush unconditionally + */ +#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH +#define ptep_clear_flush_young(__vma, __address, __ptep) \ +({ \ + int __young = __ptep_test_and_clear_young((__vma)->vm_mm, __address, \ + __ptep); \ + __young; \ +}) + +#define __HAVE_ARCH_PTEP_GET_AND_CLEAR +static inline pte_t ptep_get_and_clear(struct mm_struct *mm, + unsigned long addr, pte_t *ptep) +{ + unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0, 0); + return __pte(old); +} + +static inline void pte_clear(struct mm_struct *mm, unsigned long addr, + pte_t * ptep) +{ + pte_update(mm, addr, ptep, ~0UL, 0, 0); +} + + +/* Set the dirty and/or accessed bits atomically in a linux PTE, this + * function doesn't need to flush the hash entry + */ +static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) +{ + unsigned long bits = pte_val(entry) & + (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC); + +#ifdef PTE_ATOMIC_UPDATES + unsigned long old, tmp; + + __asm__ __volatile__( + "1: ldarx %0,0,%4\n\ + andi. %1,%0,%6\n\ + bne- 1b \n\ + or %0,%3,%0\n\ + stdcx. %0,0,%4\n\ + bne- 1b" + :"=&r" (old), "=&r" (tmp), "=m" (*ptep) + :"r" (bits), "r" (ptep), "m" (*ptep), "i" (_PAGE_BUSY) + :"cc"); +#else + unsigned long old = pte_val(*ptep); + *ptep = __pte(old | bits); +#endif +} + +#define __HAVE_ARCH_PTE_SAME +#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0) + +#define pte_ERROR(e) \ + pr_err("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) +#define pmd_ERROR(e) \ + pr_err("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) +#define pgd_ERROR(e) \ + pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) + +/* Encode and de-code a swap entry */ +#define MAX_SWAPFILES_CHECK() do { \ + BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS); \ + /* \ + * Don't have overlapping bits with _PAGE_HPTEFLAGS \ + * We filter HPTEFLAGS on set_pte. \ + */ \ + BUILD_BUG_ON(_PAGE_HPTEFLAGS & (0x1f << _PAGE_BIT_SWAP_TYPE)); \ + } while (0) +/* + * on pte we don't need handle RADIX_TREE_EXCEPTIONAL_SHIFT; + */ +#define SWP_TYPE_BITS 5 +#define __swp_type(x) (((x).val >> _PAGE_BIT_SWAP_TYPE) \ + & ((1UL << SWP_TYPE_BITS) - 1)) +#define __swp_offset(x) ((x).val >> PTE_RPN_SHIFT) +#define __swp_entry(type, offset) ((swp_entry_t) { \ + ((type) << _PAGE_BIT_SWAP_TYPE) \ + | ((offset) << PTE_RPN_SHIFT) }) + +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) }) +#define __swp_entry_to_pte(x) __pte((x).val) + +void pgtable_cache_add(unsigned shift, void (*ctor)(void *)); +void pgtable_cache_init(void); +#endif /* __ASSEMBLY__ */ + +/* + * THP pages can't be special. So use the _PAGE_SPECIAL + */ +#define _PAGE_SPLITTING _PAGE_SPECIAL + +/* + * We need to differentiate between explicit huge page and THP huge + * page, since THP huge page also need to track real subpage details + */ +#define _PAGE_THP_HUGE _PAGE_4K_PFN + +/* + * set of bits not changed in pmd_modify. + */ +#define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | \ + _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SPLITTING | \ + _PAGE_THP_HUGE) + +#ifndef __ASSEMBLY__ +/* + * The linux hugepage PMD now include the pmd entries followed by the address + * to the stashed pgtable_t. The stashed pgtable_t contains the hpte bits. + * [ 1 bit secondary | 3 bit hidx | 1 bit valid | 000]. We use one byte per + * each HPTE entry. With 16MB hugepage and 64K HPTE we need 256 entries and + * with 4K HPTE we need 4096 entries. Both will fit in a 4K pgtable_t. + * + * The last three bits are intentionally left to zero. This memory location + * are also used as normal page PTE pointers. So if we have any pointers + * left around while we collapse a hugepage, we need to make sure + * _PAGE_PRESENT bit of that is zero when we look at them + */ +static inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index) +{ + return (hpte_slot_array[index] >> 3) & 0x1; +} + +static inline unsigned int hpte_hash_index(unsigned char *hpte_slot_array, + int index) +{ + return hpte_slot_array[index] >> 4; +} + +static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array, + unsigned int index, unsigned int hidx) +{ + hpte_slot_array[index] = hidx << 4 | 0x1 << 3; +} + +struct page *realmode_pfn_to_page(unsigned long pfn); + +static inline char *get_hpte_slot_array(pmd_t *pmdp) +{ + /* + * The hpte hindex is stored in the pgtable whose address is in the + * second half of the PMD + * + * Order this load with the test for pmd_trans_huge in the caller + */ + smp_rmb(); + return *(char **)(pmdp + PTRS_PER_PMD); + + +} + +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +extern void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr, + pmd_t *pmdp, unsigned long old_pmd); +extern pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot); +extern pmd_t mk_pmd(struct page *page, pgprot_t pgprot); +extern pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot); +extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, + pmd_t *pmdp, pmd_t pmd); +extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, + pmd_t *pmd); +/* + * + * For core kernel code by design pmd_trans_huge is never run on any hugetlbfs + * page. The hugetlbfs page table walking and mangling paths are totally + * separated form the core VM paths and they're differentiated by + * VM_HUGETLB being set on vm_flags well before any pmd_trans_huge could run. + * + * pmd_trans_huge() is defined as false at build time if + * CONFIG_TRANSPARENT_HUGEPAGE=n to optimize away code blocks at build + * time in such case. + * + * For ppc64 we need to differntiate from explicit hugepages from THP, because + * for THP we also track the subpage details at the pmd level. We don't do + * that for explicit huge pages. + * + */ +static inline int pmd_trans_huge(pmd_t pmd) +{ + /* + * leaf pte for huge page, bottom two bits != 00 + */ + return (pmd_val(pmd) & 0x3) && (pmd_val(pmd) & _PAGE_THP_HUGE); +} + +static inline int pmd_trans_splitting(pmd_t pmd) +{ + if (pmd_trans_huge(pmd)) + return pmd_val(pmd) & _PAGE_SPLITTING; + return 0; +} + +extern int has_transparent_hugepage(void); +#else +static inline void hpte_do_hugepage_flush(struct mm_struct *mm, + unsigned long addr, pmd_t *pmdp, + unsigned long old_pmd) +{ + + WARN(1, "%s called with THP disabled\n", __func__); +} +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ + +static inline int pmd_large(pmd_t pmd) +{ + /* + * leaf pte for huge page, bottom two bits != 00 + */ + return ((pmd_val(pmd) & 0x3) != 0x0); +} + +static inline pte_t pmd_pte(pmd_t pmd) +{ + return __pte(pmd_val(pmd)); +} + +static inline pmd_t pte_pmd(pte_t pte) +{ + return __pmd(pte_val(pte)); +} + +static inline pte_t *pmdp_ptep(pmd_t *pmd) +{ + return (pte_t *)pmd; +} + +#define pmd_pfn(pmd) pte_pfn(pmd_pte(pmd)) +#define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd)) +#define pmd_young(pmd) pte_young(pmd_pte(pmd)) +#define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd))) +#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd))) +#define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd))) +#define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd))) +#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd))) + +#define __HAVE_ARCH_PMD_WRITE +#define pmd_write(pmd) pte_write(pmd_pte(pmd)) + +static inline pmd_t pmd_mkhuge(pmd_t pmd) +{ + /* Do nothing, mk_pmd() does this part. */ + return pmd; +} + +static inline pmd_t pmd_mknotpresent(pmd_t pmd) +{ + pmd_val(pmd) &= ~_PAGE_PRESENT; + return pmd; +} + +static inline pmd_t pmd_mksplitting(pmd_t pmd) +{ + pmd_val(pmd) |= _PAGE_SPLITTING; + return pmd; +} + +#define __HAVE_ARCH_PMD_SAME +static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b) +{ + return (((pmd_val(pmd_a) ^ pmd_val(pmd_b)) & ~_PAGE_HPTEFLAGS) == 0); +} + +#define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS +extern int pmdp_set_access_flags(struct vm_area_struct *vma, + unsigned long address, pmd_t *pmdp, + pmd_t entry, int dirty); + +extern unsigned long pmd_hugepage_update(struct mm_struct *mm, + unsigned long addr, + pmd_t *pmdp, + unsigned long clr, + unsigned long set); + +static inline int __pmdp_test_and_clear_young(struct mm_struct *mm, + unsigned long addr, pmd_t *pmdp) +{ + unsigned long old; + + if ((pmd_val(*pmdp) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0) + return 0; + old = pmd_hugepage_update(mm, addr, pmdp, _PAGE_ACCESSED, 0); + return ((old & _PAGE_ACCESSED) != 0); +} + +#define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG +extern int pmdp_test_and_clear_young(struct vm_area_struct *vma, + unsigned long address, pmd_t *pmdp); +#define __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH +extern int pmdp_clear_flush_young(struct vm_area_struct *vma, + unsigned long address, pmd_t *pmdp); + +#define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR +extern pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm, + unsigned long addr, pmd_t *pmdp); + +#define __HAVE_ARCH_PMDP_SET_WRPROTECT +static inline void pmdp_set_wrprotect(struct mm_struct *mm, unsigned long addr, + pmd_t *pmdp) +{ + + if ((pmd_val(*pmdp) & _PAGE_RW) == 0) + return; + + pmd_hugepage_update(mm, addr, pmdp, _PAGE_RW, 0); +} + +#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH +extern void pmdp_splitting_flush(struct vm_area_struct *vma, + unsigned long address, pmd_t *pmdp); + +extern pmd_t pmdp_collapse_flush(struct vm_area_struct *vma, + unsigned long address, pmd_t *pmdp); +#define pmdp_collapse_flush pmdp_collapse_flush + +#define __HAVE_ARCH_PGTABLE_DEPOSIT +extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, + pgtable_t pgtable); +#define __HAVE_ARCH_PGTABLE_WITHDRAW +extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); + +#define __HAVE_ARCH_PMDP_INVALIDATE +extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, + pmd_t *pmdp); + +#define pmd_move_must_withdraw pmd_move_must_withdraw +struct spinlock; +static inline int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl, + struct spinlock *old_pmd_ptl) +{ + /* + * Archs like ppc64 use pgtable to store per pmd + * specific information. So when we switch the pmd, + * we should also withdraw and deposit the pgtable + */ + return true; +} +#endif /* __ASSEMBLY__ */ +#endif /* _ASM_POWERPC_BOOK3S_64_PGTABLE_H_ */ diff --git a/arch/powerpc/include/asm/book3s/pgtable.h b/arch/powerpc/include/asm/book3s/pgtable.h new file mode 100644 index 0000000000000..a8d8e5152bd4e --- /dev/null +++ b/arch/powerpc/include/asm/book3s/pgtable.h @@ -0,0 +1,10 @@ +#ifndef _ASM_POWERPC_BOOK3S_PGTABLE_H +#define _ASM_POWERPC_BOOK3S_PGTABLE_H + +#ifdef CONFIG_PPC64 +#include +#else +#include +#endif + +#endif diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h index ba3342bbdbdaa..7352d3f212df9 100644 --- a/arch/powerpc/include/asm/mmu-hash64.h +++ b/arch/powerpc/include/asm/mmu-hash64.h @@ -21,7 +21,7 @@ * need for various slices related matters. Note that this isn't the * complete pgtable.h but only a portion of it. */ -#include +#include #include #include diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h index 1a58a05be99c6..aac6547b08234 100644 --- a/arch/powerpc/include/asm/pgtable-ppc32.h +++ b/arch/powerpc/include/asm/pgtable-ppc32.h @@ -115,8 +115,6 @@ extern int icache_44x_need_flush; #include #elif defined(CONFIG_8xx) #include -#else /* CONFIG_6xx */ -#include #endif /* And here we include common definitions */ diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h index b36a932abdfb3..1ef0fea32e1e6 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64.h +++ b/arch/powerpc/include/asm/pgtable-ppc64.h @@ -97,11 +97,7 @@ /* * Include the PTE bits definitions */ -#ifdef CONFIG_PPC_BOOK3S -#include -#else #include -#endif #include #ifdef CONFIG_PPC_MM_SLICES diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h index b64b4212b71f6..c304d0767919b 100644 --- a/arch/powerpc/include/asm/pgtable.h +++ b/arch/powerpc/include/asm/pgtable.h @@ -13,11 +13,15 @@ struct mm_struct; #endif /* !__ASSEMBLY__ */ +#ifdef CONFIG_PPC_BOOK3S +#include +#else #if defined(CONFIG_PPC64) # include #else # include #endif +#endif /* !CONFIG_PPC_BOOK3S */ /* * We save the slot number & secondary bit in the second half of the -- GitLab From ab537dca2f3303a6ef646c33cccf56eaa8a76f9c Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:30 +0530 Subject: [PATCH 1200/2855] powerpc/mm: Move hash specific pte width and other defines to book3s This further make a copy of pte defines to book3s/64/hash*.h. This remove the dependency on pgtable-ppc64-4k.h and pgtable-ppc64-64k.h Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/hash-4k.h | 86 ++++++++++++++++++- arch/powerpc/include/asm/book3s/64/hash-64k.h | 46 +++++++++- arch/powerpc/include/asm/book3s/64/pgtable.h | 6 +- 3 files changed, 129 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h index c134e809aac32..f2c51cd61f699 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-4k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h @@ -1,4 +1,51 @@ -/* To be include by pgtable-hash64.h only */ +#ifndef _ASM_POWERPC_BOOK3S_64_HASH_4K_H +#define _ASM_POWERPC_BOOK3S_64_HASH_4K_H +/* + * Entries per page directory level. The PTE level must use a 64b record + * for each page table entry. The PMD and PGD level use a 32b record for + * each entry by assuming that each entry is page aligned. + */ +#define PTE_INDEX_SIZE 9 +#define PMD_INDEX_SIZE 7 +#define PUD_INDEX_SIZE 9 +#define PGD_INDEX_SIZE 9 + +#ifndef __ASSEMBLY__ +#define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_INDEX_SIZE) +#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE) +#define PUD_TABLE_SIZE (sizeof(pud_t) << PUD_INDEX_SIZE) +#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE) +#endif /* __ASSEMBLY__ */ + +#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE) +#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) +#define PTRS_PER_PUD (1 << PUD_INDEX_SIZE) +#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE) + +/* PMD_SHIFT determines what a second-level page table entry can map */ +#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE) +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) + +/* With 4k base page size, hugepage PTEs go at the PMD level */ +#define MIN_HUGEPTE_SHIFT PMD_SHIFT + +/* PUD_SHIFT determines what a third-level page table entry can map */ +#define PUD_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE) +#define PUD_SIZE (1UL << PUD_SHIFT) +#define PUD_MASK (~(PUD_SIZE-1)) + +/* PGDIR_SHIFT determines what a fourth-level page table entry can map */ +#define PGDIR_SHIFT (PUD_SHIFT + PUD_INDEX_SIZE) +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) + +/* Bits to mask out from a PMD to get to the PTE page */ +#define PMD_MASKED_BITS 0 +/* Bits to mask out from a PUD to get to the PMD page */ +#define PUD_MASKED_BITS 0 +/* Bits to mask out from a PGD to get to the PUD page */ +#define PGD_MASKED_BITS 0 /* PTE bits */ #define _PAGE_HASHPTE 0x0400 /* software: pte has an associated HPTE */ @@ -15,3 +62,40 @@ /* shift to put page number into pte */ #define PTE_RPN_SHIFT (17) +#ifndef __ASSEMBLY__ +/* + * 4-level page tables related bits + */ + +#define pgd_none(pgd) (!pgd_val(pgd)) +#define pgd_bad(pgd) (pgd_val(pgd) == 0) +#define pgd_present(pgd) (pgd_val(pgd) != 0) +#define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0) +#define pgd_page_vaddr(pgd) (pgd_val(pgd) & ~PGD_MASKED_BITS) + +static inline pte_t pgd_pte(pgd_t pgd) +{ + return __pte(pgd_val(pgd)); +} + +static inline pgd_t pte_pgd(pte_t pte) +{ + return __pgd(pte_val(pte)); +} +extern struct page *pgd_page(pgd_t pgd); + +#define pud_offset(pgdp, addr) \ + (((pud_t *) pgd_page_vaddr(*(pgdp))) + \ + (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))) + +#define pud_ERROR(e) \ + pr_err("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e)) + +/* + * On all 4K setups, remap_4k_pfn() equates to remap_pfn_range() */ +#define remap_4k_pfn(vma, addr, pfn, prot) \ + remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot)) + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */ diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h index 4f4ec2ab45c97..ee073822145db 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h @@ -1,4 +1,35 @@ -/* To be include by pgtable-hash64.h only */ +#ifndef _ASM_POWERPC_BOOK3S_64_HASH_64K_H +#define _ASM_POWERPC_BOOK3S_64_HASH_64K_H + +#include + +#define PTE_INDEX_SIZE 8 +#define PMD_INDEX_SIZE 10 +#define PUD_INDEX_SIZE 0 +#define PGD_INDEX_SIZE 12 + +#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE) +#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) +#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE) + +/* With 4k base page size, hugepage PTEs go at the PMD level */ +#define MIN_HUGEPTE_SHIFT PAGE_SHIFT + +/* PMD_SHIFT determines what a second-level page table entry can map */ +#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE) +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) + +/* PGDIR_SHIFT determines what a third-level page table entry can map */ +#define PGDIR_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE) +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) + +/* Bits to mask out from a PMD to get to the PTE page */ +/* PMDs point to PTE table fragments which are 4K aligned. */ +#define PMD_MASKED_BITS 0xfff +/* Bits to mask out from a PGD/PUD to get to the PMD page */ +#define PUD_MASKED_BITS 0x1ff /* Additional PTE bits (don't change without checking asm in hash_low.S) */ #define _PAGE_SPECIAL 0x00000400 /* software: special page */ @@ -74,8 +105,8 @@ static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index) #define __rpte_to_pte(r) ((r).pte) #define __rpte_sub_valid(rpte, index) \ (pte_val(rpte.pte) & (_PAGE_HPTE_SUB0 >> (index))) - -/* Trick: we set __end to va + 64k, which happens works for +/* + * Trick: we set __end to va + 64k, which happens works for * a 16M page as well as we want only one iteration */ #define pte_iterate_hashed_subpages(rpte, psize, vpn, index, shift) \ @@ -99,4 +130,13 @@ static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index) remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \ __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN))) +#define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE) +#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE) +#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE) + +#define pgd_pte(pgd) (pud_pte(((pud_t){ pgd }))) +#define pte_pgd(pte) ((pgd_t)pte_pud(pte)) + #endif /* __ASSEMBLY__ */ + +#endif /* _ASM_POWERPC_BOOK3S_64_HASH_64K_H */ diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index cdd5284d9eaa9..2741ac6fbd3df 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -5,11 +5,7 @@ * the ppc64 hashed page table. */ -#ifdef CONFIG_PPC_64K_PAGES -#include -#else -#include -#endif +#include #include #define FIRST_USER_ADDRESS 0UL -- GitLab From cbbb8683fb632ecadafcf8a5f81d38156d4274ab Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:31 +0530 Subject: [PATCH 1201/2855] powerpc/mm: Delete booke bits from book3s We also move __ASSEMBLY__ towards the end of header. This avoid having #ifndef __ASSEMBLY___ all over the header Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/32/pgtable.h | 93 +++++--------------- arch/powerpc/include/asm/book3s/64/pgtable.h | 86 +++++------------- arch/powerpc/include/asm/book3s/pgtable.h | 1 + 3 files changed, 49 insertions(+), 131 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h index 418d2fa3ac7d8..5438c0b6aeec8 100644 --- a/arch/powerpc/include/asm/book3s/32/pgtable.h +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h @@ -3,18 +3,10 @@ #include -#ifndef __ASSEMBLY__ -#include -#include -#include /* For sub-arch specific PPC_PIN_SIZE */ - -extern unsigned long ioremap_bot; - -#ifdef CONFIG_44x -extern int icache_44x_need_flush; -#endif +#include -#endif /* __ASSEMBLY__ */ +/* And here we include common definitions */ +#include /* * The normal case is that PTEs are 32-bits and we have a 1-page @@ -31,28 +23,11 @@ extern int icache_44x_need_flush; #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) -/* - * entries per page directory level: our page-table tree is two-level, so - * we don't really have any PMD directory. - */ -#ifndef __ASSEMBLY__ -#define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_SHIFT) -#define PGD_TABLE_SIZE (sizeof(pgd_t) << (32 - PGDIR_SHIFT)) -#endif /* __ASSEMBLY__ */ - #define PTRS_PER_PTE (1 << PTE_SHIFT) #define PTRS_PER_PMD 1 #define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT)) #define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) -#define FIRST_USER_ADDRESS 0UL - -#define pte_ERROR(e) \ - pr_err("%s:%d: bad pte %llx.\n", __FILE__, __LINE__, \ - (unsigned long long)pte_val(e)) -#define pgd_ERROR(e) \ - pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) - /* * This is the bottom of the PKMAP area with HIGHMEM or an arbitrary * value (for now) on others, from where we can start layout kernel @@ -100,30 +75,30 @@ extern int icache_44x_need_flush; #endif #define VMALLOC_END ioremap_bot +#ifndef __ASSEMBLY__ +#include +#include +#include /* For sub-arch specific PPC_PIN_SIZE */ + +extern unsigned long ioremap_bot; + +/* + * entries per page directory level: our page-table tree is two-level, so + * we don't really have any PMD directory. + */ +#define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_SHIFT) +#define PGD_TABLE_SIZE (sizeof(pgd_t) << (32 - PGDIR_SHIFT)) + +#define pte_ERROR(e) \ + pr_err("%s:%d: bad pte %llx.\n", __FILE__, __LINE__, \ + (unsigned long long)pte_val(e)) +#define pgd_ERROR(e) \ + pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) /* * Bits in a linux-style PTE. These match the bits in the * (hardware-defined) PowerPC PTE as closely as possible. */ -#if defined(CONFIG_40x) -#include -#elif defined(CONFIG_44x) -#include -#elif defined(CONFIG_FSL_BOOKE) && defined(CONFIG_PTE_64BIT) -#include -#elif defined(CONFIG_FSL_BOOKE) -#include -#elif defined(CONFIG_8xx) -#include -#else /* CONFIG_6xx */ -#include -#endif - -/* And here we include common definitions */ -#include - -#ifndef __ASSEMBLY__ - #define pte_clear(mm, addr, ptep) \ do { pte_update(ptep, ~_PAGE_HASHPTE, 0); } while (0) @@ -167,7 +142,6 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr, unsigned long set) { -#ifdef PTE_ATOMIC_UPDATES unsigned long old, tmp; __asm__ __volatile__("\ @@ -180,15 +154,7 @@ static inline unsigned long pte_update(pte_t *p, : "=&r" (old), "=&r" (tmp), "=m" (*p) : "r" (p), "r" (clr), "r" (set), "m" (*p) : "cc" ); -#else /* PTE_ATOMIC_UPDATES */ - unsigned long old = pte_val(*p); - *p = __pte((old & ~clr) | set); -#endif /* !PTE_ATOMIC_UPDATES */ - -#ifdef CONFIG_44x - if ((old & _PAGE_USER) && (old & _PAGE_EXEC)) - icache_44x_need_flush = 1; -#endif + return old; } #else /* CONFIG_PTE_64BIT */ @@ -196,7 +162,6 @@ static inline unsigned long long pte_update(pte_t *p, unsigned long clr, unsigned long set) { -#ifdef PTE_ATOMIC_UPDATES unsigned long long old; unsigned long tmp; @@ -211,15 +176,7 @@ static inline unsigned long long pte_update(pte_t *p, : "=&r" (old), "=&r" (tmp), "=m" (*p) : "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p) : "cc" ); -#else /* PTE_ATOMIC_UPDATES */ - unsigned long long old = pte_val(*p); - *p = __pte((old & ~(unsigned long long)clr) | set); -#endif /* !PTE_ATOMIC_UPDATES */ - -#ifdef CONFIG_44x - if ((old & _PAGE_USER) && (old & _PAGE_EXEC)) - icache_44x_need_flush = 1; -#endif + return old; } #endif /* CONFIG_PTE_64BIT */ @@ -233,12 +190,10 @@ static inline int __ptep_test_and_clear_young(unsigned int context, unsigned lon { unsigned long old; old = pte_update(ptep, _PAGE_ACCESSED, 0); -#if _PAGE_HASHPTE != 0 if (old & _PAGE_HASHPTE) { unsigned long ptephys = __pa(ptep) & PAGE_MASK; flush_hash_pages(context, addr, ptephys, 1); } -#endif return (old & _PAGE_ACCESSED) != 0; } #define ptep_test_and_clear_young(__vma, __addr, __ptep) \ diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index 2741ac6fbd3df..ddc08bf227092 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -8,7 +8,6 @@ #include #include -#define FIRST_USER_ADDRESS 0UL /* * Size of EA range mapped by our pagetables. @@ -25,27 +24,16 @@ /* * Define the address range of the kernel non-linear virtual area */ - -#ifdef CONFIG_PPC_BOOK3E -#define KERN_VIRT_START ASM_CONST(0x8000000000000000) -#else #define KERN_VIRT_START ASM_CONST(0xD000000000000000) -#endif #define KERN_VIRT_SIZE ASM_CONST(0x0000100000000000) - /* * The vmalloc space starts at the beginning of that region, and * occupies half of it on hash CPUs and a quarter of it on Book3E * (we keep a quarter for the virtual memmap) */ #define VMALLOC_START KERN_VIRT_START -#ifdef CONFIG_PPC_BOOK3E -#define VMALLOC_SIZE (KERN_VIRT_SIZE >> 2) -#else #define VMALLOC_SIZE (KERN_VIRT_SIZE >> 1) -#endif #define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE) - /* * The second half of the kernel virtual space is used for IO mappings, * it's itself carved into the PIO region (ISA and PHB IO space) and @@ -64,7 +52,6 @@ #define IOREMAP_BASE (PHB_IO_END) #define IOREMAP_END (KERN_VIRT_START + KERN_VIRT_SIZE) - /* * Region IDs */ @@ -79,32 +66,39 @@ /* * Defines the address of the vmemap area, in its own region on - * hash table CPUs and after the vmalloc space on Book3E + * hash table CPUs. */ -#ifdef CONFIG_PPC_BOOK3E -#define VMEMMAP_BASE VMALLOC_END -#define VMEMMAP_END KERN_IO_START -#else #define VMEMMAP_BASE (VMEMMAP_REGION_ID << REGION_SHIFT) -#endif #define vmemmap ((struct page *)VMEMMAP_BASE) -/* - * Include the PTE bits definitions - */ -#ifdef CONFIG_PPC_BOOK3S -#include -#else -#include -#endif -#include - #ifdef CONFIG_PPC_MM_SLICES #define HAVE_ARCH_UNMAPPED_AREA #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN #endif /* CONFIG_PPC_MM_SLICES */ +/* + * THP pages can't be special. So use the _PAGE_SPECIAL + */ +#define _PAGE_SPLITTING _PAGE_SPECIAL + +/* + * We need to differentiate between explicit huge page and THP huge + * page, since THP huge page also need to track real subpage details + */ +#define _PAGE_THP_HUGE _PAGE_4K_PFN + +/* + * set of bits not changed in pmd_modify. + */ +#define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | \ + _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SPLITTING | \ + _PAGE_THP_HUGE) +/* + * Default defines for things which we don't use. + * We should get this removed. + */ +#include #ifndef __ASSEMBLY__ /* @@ -144,7 +138,7 @@ #define PMD_BAD_BITS (PTE_TABLE_SIZE-1) #define PUD_BAD_BITS (PMD_TABLE_SIZE-1) -#define pmd_set(pmdp, pmdval) (pmd_val(*(pmdp)) = (pmdval)) +#define pmd_set(pmdp, pmdval) (pmd_val(*(pmdp)) = (pmdval)) #define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \ || (pmd_val(pmd) & PMD_BAD_BITS)) @@ -206,7 +200,6 @@ static inline unsigned long pte_update(struct mm_struct *mm, unsigned long set, int huge) { -#ifdef PTE_ATOMIC_UPDATES unsigned long old, tmp; __asm__ __volatile__( @@ -220,18 +213,12 @@ static inline unsigned long pte_update(struct mm_struct *mm, : "=&r" (old), "=&r" (tmp), "=m" (*ptep) : "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY), "r" (set) : "cc" ); -#else - unsigned long old = pte_val(*ptep); - *ptep = __pte((old & ~clr) | set); -#endif /* huge pages use the old page table lock */ if (!huge) assert_pte_locked(mm, addr); -#ifdef CONFIG_PPC_STD_MMU_64 if (old & _PAGE_HASHPTE) hpte_need_flush(mm, addr, ptep, old, huge); -#endif return old; } @@ -313,7 +300,6 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) unsigned long bits = pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC); -#ifdef PTE_ATOMIC_UPDATES unsigned long old, tmp; __asm__ __volatile__( @@ -326,10 +312,6 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) :"=&r" (old), "=&r" (tmp), "=m" (*ptep) :"r" (bits), "r" (ptep), "m" (*ptep), "i" (_PAGE_BUSY) :"cc"); -#else - unsigned long old = pte_val(*ptep); - *ptep = __pte(old | bits); -#endif } #define __HAVE_ARCH_PTE_SAME @@ -367,27 +349,7 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) void pgtable_cache_add(unsigned shift, void (*ctor)(void *)); void pgtable_cache_init(void); -#endif /* __ASSEMBLY__ */ -/* - * THP pages can't be special. So use the _PAGE_SPECIAL - */ -#define _PAGE_SPLITTING _PAGE_SPECIAL - -/* - * We need to differentiate between explicit huge page and THP huge - * page, since THP huge page also need to track real subpage details - */ -#define _PAGE_THP_HUGE _PAGE_4K_PFN - -/* - * set of bits not changed in pmd_modify. - */ -#define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | \ - _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SPLITTING | \ - _PAGE_THP_HUGE) - -#ifndef __ASSEMBLY__ /* * The linux hugepage PMD now include the pmd entries followed by the address * to the stashed pgtable_t. The stashed pgtable_t contains the hpte bits. diff --git a/arch/powerpc/include/asm/book3s/pgtable.h b/arch/powerpc/include/asm/book3s/pgtable.h index a8d8e5152bd4e..3818cc7bc9b77 100644 --- a/arch/powerpc/include/asm/book3s/pgtable.h +++ b/arch/powerpc/include/asm/book3s/pgtable.h @@ -7,4 +7,5 @@ #include #endif +#define FIRST_USER_ADDRESS 0UL #endif -- GitLab From ee4889c7bc2a416d76730f318c741723cd64d432 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:32 +0530 Subject: [PATCH 1202/2855] powerpc/mm: Don't have generic headers introduce functions touching pte bits We are going to drop pte_common.h in the later patch. The idea is to enable hash code not require to define all PTE bits. Having PTE bits defined in pte_common.h made the code unnecessarily complex. Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/pgtable.h | 176 +++++++++++++++++++ arch/powerpc/include/asm/pgtable-book3e.h | 199 ++++++++++++++++++++++ arch/powerpc/include/asm/pgtable.h | 192 +-------------------- 3 files changed, 376 insertions(+), 191 deletions(-) create mode 100644 arch/powerpc/include/asm/pgtable-book3e.h diff --git a/arch/powerpc/include/asm/book3s/pgtable.h b/arch/powerpc/include/asm/book3s/pgtable.h index 3818cc7bc9b77..fa270cfcf30aa 100644 --- a/arch/powerpc/include/asm/book3s/pgtable.h +++ b/arch/powerpc/include/asm/book3s/pgtable.h @@ -8,4 +8,180 @@ #endif #define FIRST_USER_ADDRESS 0UL +#ifndef __ASSEMBLY__ + +/* Generic accessors to PTE bits */ +static inline int pte_write(pte_t pte) +{ + return (pte_val(pte) & (_PAGE_RW | _PAGE_RO)) != _PAGE_RO; +} +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; } +static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; } +static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); } + +#ifdef CONFIG_NUMA_BALANCING +/* + * These work without NUMA balancing but the kernel does not care. See the + * comment in include/asm-generic/pgtable.h . On powerpc, this will only + * work for user pages and always return true for kernel pages. + */ +static inline int pte_protnone(pte_t pte) +{ + return (pte_val(pte) & + (_PAGE_PRESENT | _PAGE_USER)) == _PAGE_PRESENT; +} + +static inline int pmd_protnone(pmd_t pmd) +{ + return pte_protnone(pmd_pte(pmd)); +} +#endif /* CONFIG_NUMA_BALANCING */ + +static inline int pte_present(pte_t pte) +{ + return pte_val(pte) & _PAGE_PRESENT; +} + +/* Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + * + * Even if PTEs can be unsigned long long, a PFN is always an unsigned + * long for now. + */ +static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) { + return __pte(((pte_basic_t)(pfn) << PTE_RPN_SHIFT) | + pgprot_val(pgprot)); } +static inline unsigned long pte_pfn(pte_t pte) { + return pte_val(pte) >> PTE_RPN_SHIFT; } + +/* Generic modifiers for PTE bits */ +static inline pte_t pte_wrprotect(pte_t pte) { + pte_val(pte) &= ~(_PAGE_RW | _PAGE_HWWRITE); + pte_val(pte) |= _PAGE_RO; return pte; } +static inline pte_t pte_mkclean(pte_t pte) { + pte_val(pte) &= ~(_PAGE_DIRTY | _PAGE_HWWRITE); return pte; } +static inline pte_t pte_mkold(pte_t pte) { + pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } +static inline pte_t pte_mkwrite(pte_t pte) { + pte_val(pte) &= ~_PAGE_RO; + pte_val(pte) |= _PAGE_RW; return pte; } +static inline pte_t pte_mkdirty(pte_t pte) { + pte_val(pte) |= _PAGE_DIRTY; return pte; } +static inline pte_t pte_mkyoung(pte_t pte) { + pte_val(pte) |= _PAGE_ACCESSED; return pte; } +static inline pte_t pte_mkspecial(pte_t pte) { + pte_val(pte) |= _PAGE_SPECIAL; return pte; } +static inline pte_t pte_mkhuge(pte_t pte) { + return pte; } +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); + return pte; +} + + +/* Insert a PTE, top-level function is out of line. It uses an inline + * low level function in the respective pgtable-* files + */ +extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, + pte_t pte); + +/* This low level function performs the actual PTE insertion + * Setting the PTE depends on the MMU type and other factors. It's + * an horrible mess that I'm not going to try to clean up now but + * I'm keeping it in one place rather than spread around + */ +static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte, int percpu) +{ +#if defined(CONFIG_PPC_STD_MMU_32) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT) + /* First case is 32-bit Hash MMU in SMP mode with 32-bit PTEs. We use the + * helper pte_update() which does an atomic update. We need to do that + * because a concurrent invalidation can clear _PAGE_HASHPTE. If it's a + * per-CPU PTE such as a kmap_atomic, we do a simple update preserving + * the hash bits instead (ie, same as the non-SMP case) + */ + if (percpu) + *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) + | (pte_val(pte) & ~_PAGE_HASHPTE)); + else + pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte)); + +#elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) + /* Second case is 32-bit with 64-bit PTE. In this case, we + * can just store as long as we do the two halves in the right order + * with a barrier in between. This is possible because we take care, + * in the hash code, to pre-invalidate if the PTE was already hashed, + * which synchronizes us with any concurrent invalidation. + * In the percpu case, we also fallback to the simple update preserving + * the hash bits + */ + if (percpu) { + *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) + | (pte_val(pte) & ~_PAGE_HASHPTE)); + return; + } + if (pte_val(*ptep) & _PAGE_HASHPTE) + flush_hash_entry(mm, ptep, addr); + __asm__ __volatile__("\ + stw%U0%X0 %2,%0\n\ + eieio\n\ + stw%U0%X0 %L2,%1" + : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4)) + : "r" (pte) : "memory"); + +#elif defined(CONFIG_PPC_STD_MMU_32) + /* Third case is 32-bit hash table in UP mode, we need to preserve + * the _PAGE_HASHPTE bit since we may not have invalidated the previous + * translation in the hash yet (done in a subsequent flush_tlb_xxx()) + * and see we need to keep track that this PTE needs invalidating + */ + *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) + | (pte_val(pte) & ~_PAGE_HASHPTE)); + +#else + /* Anything else just stores the PTE normally. That covers all 64-bit + * cases, and 32-bit non-hash with 32-bit PTEs. + */ + *ptep = pte; +#endif +} + + +#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS +extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, + pte_t *ptep, pte_t entry, int dirty); + +/* + * Macro to mark a page protection value as "uncacheable". + */ + +#define _PAGE_CACHE_CTL (_PAGE_COHERENT | _PAGE_GUARDED | _PAGE_NO_CACHE | \ + _PAGE_WRITETHRU) + +#define pgprot_noncached(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ + _PAGE_NO_CACHE | _PAGE_GUARDED)) + +#define pgprot_noncached_wc(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ + _PAGE_NO_CACHE)) + +#define pgprot_cached(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ + _PAGE_COHERENT)) + +#define pgprot_cached_wthru(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ + _PAGE_COHERENT | _PAGE_WRITETHRU)) + +#define pgprot_cached_noncoherent(prot) \ + (__pgprot(pgprot_val(prot) & ~_PAGE_CACHE_CTL)) + +#define pgprot_writecombine pgprot_noncached_wc + +struct file; +extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t vma_prot); +#define __HAVE_PHYS_MEM_ACCESS_PROT + +#endif /* __ASSEMBLY__ */ #endif diff --git a/arch/powerpc/include/asm/pgtable-book3e.h b/arch/powerpc/include/asm/pgtable-book3e.h new file mode 100644 index 0000000000000..a3221cff2e311 --- /dev/null +++ b/arch/powerpc/include/asm/pgtable-book3e.h @@ -0,0 +1,199 @@ +#ifndef _ASM_POWERPC_PGTABLE_BOOK3E_H +#define _ASM_POWERPC_PGTABLE_BOOK3E_H + +#if defined(CONFIG_PPC64) +#include +#else +#include +#endif + +#ifndef __ASSEMBLY__ + +/* Generic accessors to PTE bits */ +static inline int pte_write(pte_t pte) +{ + return (pte_val(pte) & (_PAGE_RW | _PAGE_RO)) != _PAGE_RO; +} +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; } +static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; } +static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); } + +#ifdef CONFIG_NUMA_BALANCING +/* + * These work without NUMA balancing but the kernel does not care. See the + * comment in include/asm-generic/pgtable.h . On powerpc, this will only + * work for user pages and always return true for kernel pages. + */ +static inline int pte_protnone(pte_t pte) +{ + return (pte_val(pte) & + (_PAGE_PRESENT | _PAGE_USER)) == _PAGE_PRESENT; +} + +static inline int pmd_protnone(pmd_t pmd) +{ + return pte_protnone(pmd_pte(pmd)); +} +#endif /* CONFIG_NUMA_BALANCING */ + +static inline int pte_present(pte_t pte) +{ + return pte_val(pte) & _PAGE_PRESENT; +} + +/* Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + * + * Even if PTEs can be unsigned long long, a PFN is always an unsigned + * long for now. + */ +static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) { + return __pte(((pte_basic_t)(pfn) << PTE_RPN_SHIFT) | + pgprot_val(pgprot)); } +static inline unsigned long pte_pfn(pte_t pte) { + return pte_val(pte) >> PTE_RPN_SHIFT; } + +/* Generic modifiers for PTE bits */ +static inline pte_t pte_wrprotect(pte_t pte) { + pte_val(pte) &= ~(_PAGE_RW | _PAGE_HWWRITE); + pte_val(pte) |= _PAGE_RO; return pte; } +static inline pte_t pte_mkclean(pte_t pte) { + pte_val(pte) &= ~(_PAGE_DIRTY | _PAGE_HWWRITE); return pte; } +static inline pte_t pte_mkold(pte_t pte) { + pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } +static inline pte_t pte_mkwrite(pte_t pte) { + pte_val(pte) &= ~_PAGE_RO; + pte_val(pte) |= _PAGE_RW; return pte; } +static inline pte_t pte_mkdirty(pte_t pte) { + pte_val(pte) |= _PAGE_DIRTY; return pte; } +static inline pte_t pte_mkyoung(pte_t pte) { + pte_val(pte) |= _PAGE_ACCESSED; return pte; } +static inline pte_t pte_mkspecial(pte_t pte) { + pte_val(pte) |= _PAGE_SPECIAL; return pte; } +static inline pte_t pte_mkhuge(pte_t pte) { + return pte; } +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); + return pte; +} + + +/* Insert a PTE, top-level function is out of line. It uses an inline + * low level function in the respective pgtable-* files + */ +extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, + pte_t pte); + +/* This low level function performs the actual PTE insertion + * Setting the PTE depends on the MMU type and other factors. It's + * an horrible mess that I'm not going to try to clean up now but + * I'm keeping it in one place rather than spread around + */ +static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte, int percpu) +{ +#if defined(CONFIG_PPC_STD_MMU_32) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT) + /* First case is 32-bit Hash MMU in SMP mode with 32-bit PTEs. We use the + * helper pte_update() which does an atomic update. We need to do that + * because a concurrent invalidation can clear _PAGE_HASHPTE. If it's a + * per-CPU PTE such as a kmap_atomic, we do a simple update preserving + * the hash bits instead (ie, same as the non-SMP case) + */ + if (percpu) + *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) + | (pte_val(pte) & ~_PAGE_HASHPTE)); + else + pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte)); + +#elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) + /* Second case is 32-bit with 64-bit PTE. In this case, we + * can just store as long as we do the two halves in the right order + * with a barrier in between. This is possible because we take care, + * in the hash code, to pre-invalidate if the PTE was already hashed, + * which synchronizes us with any concurrent invalidation. + * In the percpu case, we also fallback to the simple update preserving + * the hash bits + */ + if (percpu) { + *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) + | (pte_val(pte) & ~_PAGE_HASHPTE)); + return; + } +#if _PAGE_HASHPTE != 0 + if (pte_val(*ptep) & _PAGE_HASHPTE) + flush_hash_entry(mm, ptep, addr); +#endif + __asm__ __volatile__("\ + stw%U0%X0 %2,%0\n\ + eieio\n\ + stw%U0%X0 %L2,%1" + : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4)) + : "r" (pte) : "memory"); + +#elif defined(CONFIG_PPC_STD_MMU_32) + /* Third case is 32-bit hash table in UP mode, we need to preserve + * the _PAGE_HASHPTE bit since we may not have invalidated the previous + * translation in the hash yet (done in a subsequent flush_tlb_xxx()) + * and see we need to keep track that this PTE needs invalidating + */ + *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) + | (pte_val(pte) & ~_PAGE_HASHPTE)); + +#else + /* Anything else just stores the PTE normally. That covers all 64-bit + * cases, and 32-bit non-hash with 32-bit PTEs. + */ + *ptep = pte; + +#ifdef CONFIG_PPC_BOOK3E_64 + /* + * With hardware tablewalk, a sync is needed to ensure that + * subsequent accesses see the PTE we just wrote. Unlike userspace + * mappings, we can't tolerate spurious faults, so make sure + * the new PTE will be seen the first time. + */ + if (is_kernel_addr(addr)) + mb(); +#endif +#endif +} + + +#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS +extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, + pte_t *ptep, pte_t entry, int dirty); + +/* + * Macro to mark a page protection value as "uncacheable". + */ + +#define _PAGE_CACHE_CTL (_PAGE_COHERENT | _PAGE_GUARDED | _PAGE_NO_CACHE | \ + _PAGE_WRITETHRU) + +#define pgprot_noncached(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ + _PAGE_NO_CACHE | _PAGE_GUARDED)) + +#define pgprot_noncached_wc(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ + _PAGE_NO_CACHE)) + +#define pgprot_cached(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ + _PAGE_COHERENT)) + +#define pgprot_cached_wthru(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ + _PAGE_COHERENT | _PAGE_WRITETHRU)) + +#define pgprot_cached_noncoherent(prot) \ + (__pgprot(pgprot_val(prot) & ~_PAGE_CACHE_CTL)) + +#define pgprot_writecombine pgprot_noncached_wc + +struct file; +extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t vma_prot); +#define __HAVE_PHYS_MEM_ACCESS_PROT + +#endif /* __ASSEMBLY__ */ +#endif diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h index c304d0767919b..a27b8cef51d70 100644 --- a/arch/powerpc/include/asm/pgtable.h +++ b/arch/powerpc/include/asm/pgtable.h @@ -1,6 +1,5 @@ #ifndef _ASM_POWERPC_PGTABLE_H #define _ASM_POWERPC_PGTABLE_H -#ifdef __KERNEL__ #ifndef __ASSEMBLY__ #include @@ -16,11 +15,7 @@ struct mm_struct; #ifdef CONFIG_PPC_BOOK3S #include #else -#if defined(CONFIG_PPC64) -# include -#else -# include -#endif +#include #endif /* !CONFIG_PPC_BOOK3S */ /* @@ -33,194 +28,10 @@ struct mm_struct; #include -/* Generic accessors to PTE bits */ -static inline int pte_write(pte_t pte) -{ return (pte_val(pte) & (_PAGE_RW | _PAGE_RO)) != _PAGE_RO; } -static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } -static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; } -static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; } -static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); } - -#ifdef CONFIG_NUMA_BALANCING -/* - * These work without NUMA balancing but the kernel does not care. See the - * comment in include/asm-generic/pgtable.h . On powerpc, this will only - * work for user pages and always return true for kernel pages. - */ -static inline int pte_protnone(pte_t pte) -{ - return (pte_val(pte) & - (_PAGE_PRESENT | _PAGE_USER)) == _PAGE_PRESENT; -} - -static inline int pmd_protnone(pmd_t pmd) -{ - return pte_protnone(pmd_pte(pmd)); -} -#endif /* CONFIG_NUMA_BALANCING */ - -static inline int pte_present(pte_t pte) -{ - return pte_val(pte) & _PAGE_PRESENT; -} - -/* Conversion functions: convert a page and protection to a page entry, - * and a page entry and page directory to the page they refer to. - * - * Even if PTEs can be unsigned long long, a PFN is always an unsigned - * long for now. - */ -static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) { - return __pte(((pte_basic_t)(pfn) << PTE_RPN_SHIFT) | - pgprot_val(pgprot)); } -static inline unsigned long pte_pfn(pte_t pte) { - return pte_val(pte) >> PTE_RPN_SHIFT; } - /* Keep these as a macros to avoid include dependency mess */ #define pte_page(x) pfn_to_page(pte_pfn(x)) #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) -/* Generic modifiers for PTE bits */ -static inline pte_t pte_wrprotect(pte_t pte) { - pte_val(pte) &= ~(_PAGE_RW | _PAGE_HWWRITE); - pte_val(pte) |= _PAGE_RO; return pte; } -static inline pte_t pte_mkclean(pte_t pte) { - pte_val(pte) &= ~(_PAGE_DIRTY | _PAGE_HWWRITE); return pte; } -static inline pte_t pte_mkold(pte_t pte) { - pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } -static inline pte_t pte_mkwrite(pte_t pte) { - pte_val(pte) &= ~_PAGE_RO; - pte_val(pte) |= _PAGE_RW; return pte; } -static inline pte_t pte_mkdirty(pte_t pte) { - pte_val(pte) |= _PAGE_DIRTY; return pte; } -static inline pte_t pte_mkyoung(pte_t pte) { - pte_val(pte) |= _PAGE_ACCESSED; return pte; } -static inline pte_t pte_mkspecial(pte_t pte) { - pte_val(pte) |= _PAGE_SPECIAL; return pte; } -static inline pte_t pte_mkhuge(pte_t pte) { - return pte; } -static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -{ - pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); - return pte; -} - - -/* Insert a PTE, top-level function is out of line. It uses an inline - * low level function in the respective pgtable-* files - */ -extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, - pte_t pte); - -/* This low level function performs the actual PTE insertion - * Setting the PTE depends on the MMU type and other factors. It's - * an horrible mess that I'm not going to try to clean up now but - * I'm keeping it in one place rather than spread around - */ -static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t pte, int percpu) -{ -#if defined(CONFIG_PPC_STD_MMU_32) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT) - /* First case is 32-bit Hash MMU in SMP mode with 32-bit PTEs. We use the - * helper pte_update() which does an atomic update. We need to do that - * because a concurrent invalidation can clear _PAGE_HASHPTE. If it's a - * per-CPU PTE such as a kmap_atomic, we do a simple update preserving - * the hash bits instead (ie, same as the non-SMP case) - */ - if (percpu) - *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) - | (pte_val(pte) & ~_PAGE_HASHPTE)); - else - pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte)); - -#elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) - /* Second case is 32-bit with 64-bit PTE. In this case, we - * can just store as long as we do the two halves in the right order - * with a barrier in between. This is possible because we take care, - * in the hash code, to pre-invalidate if the PTE was already hashed, - * which synchronizes us with any concurrent invalidation. - * In the percpu case, we also fallback to the simple update preserving - * the hash bits - */ - if (percpu) { - *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) - | (pte_val(pte) & ~_PAGE_HASHPTE)); - return; - } -#if _PAGE_HASHPTE != 0 - if (pte_val(*ptep) & _PAGE_HASHPTE) - flush_hash_entry(mm, ptep, addr); -#endif - __asm__ __volatile__("\ - stw%U0%X0 %2,%0\n\ - eieio\n\ - stw%U0%X0 %L2,%1" - : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4)) - : "r" (pte) : "memory"); - -#elif defined(CONFIG_PPC_STD_MMU_32) - /* Third case is 32-bit hash table in UP mode, we need to preserve - * the _PAGE_HASHPTE bit since we may not have invalidated the previous - * translation in the hash yet (done in a subsequent flush_tlb_xxx()) - * and see we need to keep track that this PTE needs invalidating - */ - *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) - | (pte_val(pte) & ~_PAGE_HASHPTE)); - -#else - /* Anything else just stores the PTE normally. That covers all 64-bit - * cases, and 32-bit non-hash with 32-bit PTEs. - */ - *ptep = pte; - -#ifdef CONFIG_PPC_BOOK3E_64 - /* - * With hardware tablewalk, a sync is needed to ensure that - * subsequent accesses see the PTE we just wrote. Unlike userspace - * mappings, we can't tolerate spurious faults, so make sure - * the new PTE will be seen the first time. - */ - if (is_kernel_addr(addr)) - mb(); -#endif -#endif -} - - -#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS -extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, - pte_t *ptep, pte_t entry, int dirty); - -/* - * Macro to mark a page protection value as "uncacheable". - */ - -#define _PAGE_CACHE_CTL (_PAGE_COHERENT | _PAGE_GUARDED | _PAGE_NO_CACHE | \ - _PAGE_WRITETHRU) - -#define pgprot_noncached(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ - _PAGE_NO_CACHE | _PAGE_GUARDED)) - -#define pgprot_noncached_wc(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ - _PAGE_NO_CACHE)) - -#define pgprot_cached(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ - _PAGE_COHERENT)) - -#define pgprot_cached_wthru(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ - _PAGE_COHERENT | _PAGE_WRITETHRU)) - -#define pgprot_cached_noncoherent(prot) \ - (__pgprot(pgprot_val(prot) & ~_PAGE_CACHE_CTL)) - -#define pgprot_writecombine pgprot_noncached_wc - -struct file; -extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, - unsigned long size, pgprot_t vma_prot); -#define __HAVE_PHYS_MEM_ACCESS_PROT - /* * ZERO_PAGE is a global shared page that is always zero: used * for zero-mapped memory areas etc.. @@ -275,5 +86,4 @@ static inline pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, } #endif /* __ASSEMBLY__ */ -#endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_PGTABLE_H */ -- GitLab From b0412ea94bcbd08dc1e61043dfdd9c33272cec48 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:33 +0530 Subject: [PATCH 1203/2855] powerpc/mm: Drop pte-common.h from BOOK3S 64 We copy only needed PTE bits define from pte-common.h to respective hash related header. This should greatly simply later patches in which we are going to change the pte format for hash config Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/hash-4k.h | 1 + arch/powerpc/include/asm/book3s/64/hash.h | 2 + arch/powerpc/include/asm/book3s/64/pgtable.h | 104 ++++++++++++++++++- arch/powerpc/include/asm/book3s/pgtable.h | 16 ++- 4 files changed, 111 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h index f2c51cd61f699..15518b620f5a0 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-4k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h @@ -62,6 +62,7 @@ /* shift to put page number into pte */ #define PTE_RPN_SHIFT (17) +#define _PAGE_4K_PFN 0 #ifndef __ASSEMBLY__ /* * 4-level page tables related bits diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 8e60d4fa434d2..7deb5063ff8c9 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -20,6 +20,7 @@ #define _PAGE_EXEC 0x0004 /* No execute on POWER4 and newer (we invert) */ #define _PAGE_GUARDED 0x0008 /* We can derive Memory coherence from _PAGE_NO_CACHE */ +#define _PAGE_COHERENT 0x0 #define _PAGE_NO_CACHE 0x0020 /* I: cache inhibit */ #define _PAGE_WRITETHRU 0x0040 /* W: cache write-through */ #define _PAGE_DIRTY 0x0080 /* C: page changed */ @@ -30,6 +31,7 @@ /* No separate kernel read-only */ #define _PAGE_KERNEL_RW (_PAGE_RW | _PAGE_DIRTY) /* user access blocked by key */ #define _PAGE_KERNEL_RO _PAGE_KERNEL_RW +#define _PAGE_KERNEL_RWX (_PAGE_DIRTY | _PAGE_RW | _PAGE_EXEC) /* Strong Access Ordering */ #define _PAGE_SAO (_PAGE_WRITETHRU | _PAGE_NO_CACHE | _PAGE_COHERENT) diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index ddc08bf227092..f942b27e9c5f0 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -94,11 +94,109 @@ #define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | \ _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SPLITTING | \ _PAGE_THP_HUGE) +#define _PTE_NONE_MASK _PAGE_HPTEFLAGS /* - * Default defines for things which we don't use. - * We should get this removed. + * The mask convered by the RPN must be a ULL on 32-bit platforms with + * 64-bit PTEs */ -#include +#define PTE_RPN_MASK (~((1UL << PTE_RPN_SHIFT) - 1)) +/* + * _PAGE_CHG_MASK masks of bits that are to be preserved across + * pgprot changes + */ +#define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \ + _PAGE_ACCESSED | _PAGE_SPECIAL) +/* + * Mask of bits returned by pte_pgprot() + */ +#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \ + _PAGE_WRITETHRU | _PAGE_4K_PFN | \ + _PAGE_USER | _PAGE_ACCESSED | \ + _PAGE_RW | _PAGE_DIRTY | _PAGE_EXEC) +/* + * We define 2 sets of base prot bits, one for basic pages (ie, + * cacheable kernel and user pages) and one for non cacheable + * pages. We always set _PAGE_COHERENT when SMP is enabled or + * the processor might need it for DMA coherency. + */ +#define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_PSIZE) +#define _PAGE_BASE (_PAGE_BASE_NC | _PAGE_COHERENT) + +/* Permission masks used to generate the __P and __S table, + * + * Note:__pgprot is defined in arch/powerpc/include/asm/page.h + * + * Write permissions imply read permissions for now (we could make write-only + * pages on BookE but we don't bother for now). Execute permission control is + * possible on platforms that define _PAGE_EXEC + * + * Note due to the way vm flags are laid out, the bits are XWR + */ +#define PAGE_NONE __pgprot(_PAGE_BASE) +#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW) +#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | \ + _PAGE_EXEC) +#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER ) +#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) +#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER ) +#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) + +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY_X +#define __P101 PAGE_READONLY_X +#define __P110 PAGE_COPY_X +#define __P111 PAGE_COPY_X + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY_X +#define __S101 PAGE_READONLY_X +#define __S110 PAGE_SHARED_X +#define __S111 PAGE_SHARED_X + +/* Permission masks used for kernel mappings */ +#define PAGE_KERNEL __pgprot(_PAGE_BASE | _PAGE_KERNEL_RW) +#define PAGE_KERNEL_NC __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \ + _PAGE_NO_CACHE) +#define PAGE_KERNEL_NCG __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \ + _PAGE_NO_CACHE | _PAGE_GUARDED) +#define PAGE_KERNEL_X __pgprot(_PAGE_BASE | _PAGE_KERNEL_RWX) +#define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO) +#define PAGE_KERNEL_ROX __pgprot(_PAGE_BASE | _PAGE_KERNEL_ROX) + +/* Protection used for kernel text. We want the debuggers to be able to + * set breakpoints anywhere, so don't write protect the kernel text + * on platforms where such control is possible. + */ +#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) ||\ + defined(CONFIG_KPROBES) || defined(CONFIG_DYNAMIC_FTRACE) +#define PAGE_KERNEL_TEXT PAGE_KERNEL_X +#else +#define PAGE_KERNEL_TEXT PAGE_KERNEL_ROX +#endif + +/* Make modules code happy. We don't set RO yet */ +#define PAGE_KERNEL_EXEC PAGE_KERNEL_X + +/* + * Don't just check for any non zero bits in __PAGE_USER, since for book3e + * and PTE_64BIT, PAGE_KERNEL_X contains _PAGE_BAP_SR which is also in + * _PAGE_USER. Need to explicitly match _PAGE_BAP_UR bit in that case too. + */ +#define pte_user(val) ((val & _PAGE_USER) == _PAGE_USER) + +/* Advertise special mapping type for AGP */ +#define PAGE_AGP (PAGE_KERNEL_NC) +#define HAVE_PAGE_AGP + +/* Advertise support for _PAGE_SPECIAL */ +#define __HAVE_ARCH_PTE_SPECIAL + #ifndef __ASSEMBLY__ /* diff --git a/arch/powerpc/include/asm/book3s/pgtable.h b/arch/powerpc/include/asm/book3s/pgtable.h index fa270cfcf30aa..87333618af3bb 100644 --- a/arch/powerpc/include/asm/book3s/pgtable.h +++ b/arch/powerpc/include/asm/book3s/pgtable.h @@ -11,10 +11,7 @@ #ifndef __ASSEMBLY__ /* Generic accessors to PTE bits */ -static inline int pte_write(pte_t pte) -{ - return (pte_val(pte) & (_PAGE_RW | _PAGE_RO)) != _PAGE_RO; -} +static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & _PAGE_RW);} static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; } @@ -57,15 +54,16 @@ static inline unsigned long pte_pfn(pte_t pte) { return pte_val(pte) >> PTE_RPN_SHIFT; } /* Generic modifiers for PTE bits */ -static inline pte_t pte_wrprotect(pte_t pte) { - pte_val(pte) &= ~(_PAGE_RW | _PAGE_HWWRITE); - pte_val(pte) |= _PAGE_RO; return pte; } +static inline pte_t pte_wrprotect(pte_t pte) +{ + pte_val(pte) &= ~_PAGE_RW; + return pte; +} static inline pte_t pte_mkclean(pte_t pte) { - pte_val(pte) &= ~(_PAGE_DIRTY | _PAGE_HWWRITE); return pte; } + pte_val(pte) &= ~_PAGE_DIRTY; return pte; } static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } static inline pte_t pte_mkwrite(pte_t pte) { - pte_val(pte) &= ~_PAGE_RO; pte_val(pte) |= _PAGE_RW; return pte; } static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } -- GitLab From 10bd3808dfd067d6d6c941cc6e1b13be165f6a70 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:34 +0530 Subject: [PATCH 1204/2855] powerpc/mm: Don't use pte_val as lvalue We also convert few #define to static inline in this patch for better type checking Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/pgtable.h | 118 +++++++++++++++------- arch/powerpc/include/asm/page.h | 10 +- arch/powerpc/include/asm/pgtable-book3e.h | 68 +++++++++---- 3 files changed, 139 insertions(+), 57 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/pgtable.h b/arch/powerpc/include/asm/book3s/pgtable.h index 87333618af3bb..ebd6677ea017e 100644 --- a/arch/powerpc/include/asm/book3s/pgtable.h +++ b/arch/powerpc/include/asm/book3s/pgtable.h @@ -12,9 +12,9 @@ /* Generic accessors to PTE bits */ static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & _PAGE_RW);} -static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } -static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; } +static inline int pte_dirty(pte_t pte) { return !!(pte_val(pte) & _PAGE_DIRTY); } +static inline int pte_young(pte_t pte) { return !!(pte_val(pte) & _PAGE_ACCESSED); } +static inline int pte_special(pte_t pte) { return !!(pte_val(pte) & _PAGE_SPECIAL); } static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; } static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); } @@ -47,36 +47,61 @@ static inline int pte_present(pte_t pte) * Even if PTEs can be unsigned long long, a PFN is always an unsigned * long for now. */ -static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) { +static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) +{ return __pte(((pte_basic_t)(pfn) << PTE_RPN_SHIFT) | - pgprot_val(pgprot)); } -static inline unsigned long pte_pfn(pte_t pte) { - return pte_val(pte) >> PTE_RPN_SHIFT; } + pgprot_val(pgprot)); +} + +static inline unsigned long pte_pfn(pte_t pte) +{ + return pte_val(pte) >> PTE_RPN_SHIFT; +} /* Generic modifiers for PTE bits */ static inline pte_t pte_wrprotect(pte_t pte) { - pte_val(pte) &= ~_PAGE_RW; + return __pte(pte_val(pte) & ~_PAGE_RW); +} + +static inline pte_t pte_mkclean(pte_t pte) +{ + return __pte(pte_val(pte) & ~_PAGE_DIRTY); +} + +static inline pte_t pte_mkold(pte_t pte) +{ + return __pte(pte_val(pte) & ~_PAGE_ACCESSED); +} + +static inline pte_t pte_mkwrite(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_RW); +} + +static inline pte_t pte_mkdirty(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_DIRTY); +} + +static inline pte_t pte_mkyoung(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_ACCESSED); +} + +static inline pte_t pte_mkspecial(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_SPECIAL); +} + +static inline pte_t pte_mkhuge(pte_t pte) +{ return pte; } -static inline pte_t pte_mkclean(pte_t pte) { - pte_val(pte) &= ~_PAGE_DIRTY; return pte; } -static inline pte_t pte_mkold(pte_t pte) { - pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } -static inline pte_t pte_mkwrite(pte_t pte) { - pte_val(pte) |= _PAGE_RW; return pte; } -static inline pte_t pte_mkdirty(pte_t pte) { - pte_val(pte) |= _PAGE_DIRTY; return pte; } -static inline pte_t pte_mkyoung(pte_t pte) { - pte_val(pte) |= _PAGE_ACCESSED; return pte; } -static inline pte_t pte_mkspecial(pte_t pte) { - pte_val(pte) |= _PAGE_SPECIAL; return pte; } -static inline pte_t pte_mkhuge(pte_t pte) { - return pte; } + static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { - pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); - return pte; + return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)); } @@ -159,22 +184,45 @@ extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long addre #define _PAGE_CACHE_CTL (_PAGE_COHERENT | _PAGE_GUARDED | _PAGE_NO_CACHE | \ _PAGE_WRITETHRU) -#define pgprot_noncached(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ - _PAGE_NO_CACHE | _PAGE_GUARDED)) +#define pgprot_noncached pgprot_noncached +static inline pgprot_t pgprot_noncached(pgprot_t prot) +{ + return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | + _PAGE_NO_CACHE | _PAGE_GUARDED); +} -#define pgprot_noncached_wc(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ - _PAGE_NO_CACHE)) +#define pgprot_noncached_wc pgprot_noncached_wc +static inline pgprot_t pgprot_noncached_wc(pgprot_t prot) +{ + return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | + _PAGE_NO_CACHE); +} -#define pgprot_cached(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ - _PAGE_COHERENT)) +#define pgprot_cached pgprot_cached +static inline pgprot_t pgprot_cached(pgprot_t prot) +{ + return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | + _PAGE_COHERENT); +} -#define pgprot_cached_wthru(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ - _PAGE_COHERENT | _PAGE_WRITETHRU)) +#define pgprot_cached_wthru pgprot_cached_wthru +static inline pgprot_t pgprot_cached_wthru(pgprot_t prot) +{ + return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | + _PAGE_COHERENT | _PAGE_WRITETHRU); +} -#define pgprot_cached_noncoherent(prot) \ - (__pgprot(pgprot_val(prot) & ~_PAGE_CACHE_CTL)) +#define pgprot_cached_noncoherent pgprot_cached_noncoherent +static inline pgprot_t pgprot_cached_noncoherent(pgprot_t prot) +{ + return __pgprot(pgprot_val(prot) & ~_PAGE_CACHE_CTL); +} -#define pgprot_writecombine pgprot_noncached_wc +#define pgprot_writecombine pgprot_writecombine +static inline pgprot_t pgprot_writecombine(pgprot_t prot) +{ + return pgprot_noncached_wc(prot); +} struct file; extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index 3140c19c448c2..3ce5341403902 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h @@ -286,8 +286,11 @@ extern long long virt_phys_offset; /* PTE level */ typedef struct { pte_basic_t pte; } pte_t; -#define pte_val(x) ((x).pte) #define __pte(x) ((pte_t) { (x) }) +static inline pte_basic_t pte_val(pte_t x) +{ + return x.pte; +} /* 64k pages additionally define a bigger "real PTE" type that gathers * the "second half" part of the PTE for pseudo 64k pages @@ -329,8 +332,11 @@ typedef struct { unsigned long pgprot; } pgprot_t; */ typedef pte_basic_t pte_t; -#define pte_val(x) (x) #define __pte(x) (x) +static inline pte_basic_t pte_val(pte_t pte) +{ + return pte; +} #if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_STD_MMU_64) typedef struct { pte_t pte; unsigned long hidx; } real_pte_t; diff --git a/arch/powerpc/include/asm/pgtable-book3e.h b/arch/powerpc/include/asm/pgtable-book3e.h index a3221cff2e311..91325997ba257 100644 --- a/arch/powerpc/include/asm/pgtable-book3e.h +++ b/arch/powerpc/include/asm/pgtable-book3e.h @@ -56,30 +56,58 @@ static inline unsigned long pte_pfn(pte_t pte) { return pte_val(pte) >> PTE_RPN_SHIFT; } /* Generic modifiers for PTE bits */ -static inline pte_t pte_wrprotect(pte_t pte) { - pte_val(pte) &= ~(_PAGE_RW | _PAGE_HWWRITE); - pte_val(pte) |= _PAGE_RO; return pte; } -static inline pte_t pte_mkclean(pte_t pte) { - pte_val(pte) &= ~(_PAGE_DIRTY | _PAGE_HWWRITE); return pte; } -static inline pte_t pte_mkold(pte_t pte) { - pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } -static inline pte_t pte_mkwrite(pte_t pte) { - pte_val(pte) &= ~_PAGE_RO; - pte_val(pte) |= _PAGE_RW; return pte; } -static inline pte_t pte_mkdirty(pte_t pte) { - pte_val(pte) |= _PAGE_DIRTY; return pte; } -static inline pte_t pte_mkyoung(pte_t pte) { - pte_val(pte) |= _PAGE_ACCESSED; return pte; } -static inline pte_t pte_mkspecial(pte_t pte) { - pte_val(pte) |= _PAGE_SPECIAL; return pte; } -static inline pte_t pte_mkhuge(pte_t pte) { - return pte; } -static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +static inline pte_t pte_wrprotect(pte_t pte) +{ + pte_basic_t ptev; + + ptev = pte_val(pte) & ~(_PAGE_RW | _PAGE_HWWRITE); + ptev |= _PAGE_RO; + return __pte(ptev); +} + +static inline pte_t pte_mkclean(pte_t pte) +{ + return __pte(pte_val(pte) & ~(_PAGE_DIRTY | _PAGE_HWWRITE)); +} + +static inline pte_t pte_mkold(pte_t pte) +{ + return __pte(pte_val(pte) & ~_PAGE_ACCESSED); +} + +static inline pte_t pte_mkwrite(pte_t pte) +{ + pte_basic_t ptev; + + ptev = pte_val(pte) & ~_PAGE_RO; + ptev |= _PAGE_RW; + return __pte(ptev); +} + +static inline pte_t pte_mkdirty(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_DIRTY); +} + +static inline pte_t pte_mkyoung(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_ACCESSED); +} + +static inline pte_t pte_mkspecial(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_SPECIAL); +} + +static inline pte_t pte_mkhuge(pte_t pte) { - pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)); +} /* Insert a PTE, top-level function is out of line. It uses an inline * low level function in the respective pgtable-* files -- GitLab From f281b5d50c87ecca108dcbf8f791bd8923fde3de Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:35 +0530 Subject: [PATCH 1205/2855] powerpc/mm: Don't use pmd_val, pud_val and pgd_val as lvalue We convert them static inline function here as we did with pte_val in the previous patch Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/32/pgtable.h | 6 +++- arch/powerpc/include/asm/book3s/64/hash-4k.h | 6 +++- arch/powerpc/include/asm/book3s/64/pgtable.h | 36 +++++++++++++++----- arch/powerpc/include/asm/page.h | 34 +++++++++++++----- arch/powerpc/include/asm/pgalloc-32.h | 34 +++++++++++++----- arch/powerpc/include/asm/pgalloc-64.h | 17 ++++++--- arch/powerpc/include/asm/pgtable-ppc32.h | 7 +++- arch/powerpc/include/asm/pgtable-ppc64-4k.h | 6 +++- arch/powerpc/include/asm/pgtable-ppc64.h | 36 +++++++++++++++----- arch/powerpc/mm/40x_mmu.c | 10 +++--- arch/powerpc/mm/pgtable_64.c | 19 +++++------ 11 files changed, 154 insertions(+), 57 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h index 5438c0b6aeec8..226f29d39332c 100644 --- a/arch/powerpc/include/asm/book3s/32/pgtable.h +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h @@ -105,7 +105,11 @@ extern unsigned long ioremap_bot; #define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_bad(pmd) (pmd_val(pmd) & _PMD_BAD) #define pmd_present(pmd) (pmd_val(pmd) & _PMD_PRESENT_MASK) -#define pmd_clear(pmdp) do { pmd_val(*(pmdp)) = 0; } while (0) +static inline void pmd_clear(pmd_t *pmdp) +{ + *pmdp = __pmd(0); +} + /* * When flushing the tlb entry for a page, we also need to flush the hash diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h index 15518b620f5a0..537eacecf6e94 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-4k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h @@ -71,9 +71,13 @@ #define pgd_none(pgd) (!pgd_val(pgd)) #define pgd_bad(pgd) (pgd_val(pgd) == 0) #define pgd_present(pgd) (pgd_val(pgd) != 0) -#define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0) #define pgd_page_vaddr(pgd) (pgd_val(pgd) & ~PGD_MASKED_BITS) +static inline void pgd_clear(pgd_t *pgdp) +{ + *pgdp = __pgd(0); +} + static inline pte_t pgd_pte(pgd_t pgd) { return __pte(pgd_val(pgd)); diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index f942b27e9c5f0..09c6474f89c72 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -236,21 +236,38 @@ #define PMD_BAD_BITS (PTE_TABLE_SIZE-1) #define PUD_BAD_BITS (PMD_TABLE_SIZE-1) -#define pmd_set(pmdp, pmdval) (pmd_val(*(pmdp)) = (pmdval)) +static inline void pmd_set(pmd_t *pmdp, unsigned long val) +{ + *pmdp = __pmd(val); +} + +static inline void pmd_clear(pmd_t *pmdp) +{ + *pmdp = __pmd(0); +} + + #define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \ || (pmd_val(pmd) & PMD_BAD_BITS)) #define pmd_present(pmd) (!pmd_none(pmd)) -#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0) #define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS) extern struct page *pmd_page(pmd_t pmd); -#define pud_set(pudp, pudval) (pud_val(*(pudp)) = (pudval)) +static inline void pud_set(pud_t *pudp, unsigned long val) +{ + *pudp = __pud(val); +} + +static inline void pud_clear(pud_t *pudp) +{ + *pudp = __pud(0); +} + #define pud_none(pud) (!pud_val(pud)) #define pud_bad(pud) (!is_kernel_addr(pud_val(pud)) \ || (pud_val(pud) & PUD_BAD_BITS)) #define pud_present(pud) (pud_val(pud) != 0) -#define pud_clear(pudp) (pud_val(*(pudp)) = 0) #define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS) extern struct page *pud_page(pud_t pud); @@ -265,8 +282,11 @@ static inline pud_t pte_pud(pte_t pte) return __pud(pte_val(pte)); } #define pud_write(pud) pte_write(pud_pte(pud)) -#define pgd_set(pgdp, pudp) ({pgd_val(*(pgdp)) = (unsigned long)(pudp);}) #define pgd_write(pgd) pte_write(pgd_pte(pgd)) +static inline void pgd_set(pgd_t *pgdp, unsigned long val) +{ + *pgdp = __pgd(val); +} /* * Find an entry in a page-table-directory. We combine the address region @@ -588,14 +608,12 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd) static inline pmd_t pmd_mknotpresent(pmd_t pmd) { - pmd_val(pmd) &= ~_PAGE_PRESENT; - return pmd; + return __pmd(pmd_val(pmd) & ~_PAGE_PRESENT); } static inline pmd_t pmd_mksplitting(pmd_t pmd) { - pmd_val(pmd) |= _PAGE_SPLITTING; - return pmd; + return __pmd(pmd_val(pmd) | _PAGE_SPLITTING); } #define __HAVE_ARCH_PMD_SAME diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index 3ce5341403902..5a3e7c643d73d 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h @@ -304,21 +304,30 @@ typedef struct { pte_t pte; } real_pte_t; /* PMD level */ #ifdef CONFIG_PPC64 typedef struct { unsigned long pmd; } pmd_t; -#define pmd_val(x) ((x).pmd) #define __pmd(x) ((pmd_t) { (x) }) +static inline unsigned long pmd_val(pmd_t x) +{ + return x.pmd; +} /* PUD level exusts only on 4k pages */ #ifndef CONFIG_PPC_64K_PAGES typedef struct { unsigned long pud; } pud_t; -#define pud_val(x) ((x).pud) #define __pud(x) ((pud_t) { (x) }) +static inline unsigned long pud_val(pud_t x) +{ + return x.pud; +} #endif /* !CONFIG_PPC_64K_PAGES */ #endif /* CONFIG_PPC64 */ /* PGD level */ typedef struct { unsigned long pgd; } pgd_t; -#define pgd_val(x) ((x).pgd) #define __pgd(x) ((pgd_t) { (x) }) +static inline unsigned long pgd_val(pgd_t x) +{ + return x.pgd; +} /* Page protection bits */ typedef struct { unsigned long pgprot; } pgprot_t; @@ -347,22 +356,31 @@ typedef pte_t real_pte_t; #ifdef CONFIG_PPC64 typedef unsigned long pmd_t; -#define pmd_val(x) (x) #define __pmd(x) (x) +static inline unsigned long pmd_val(pmd_t pmd) +{ + return pmd; +} #ifndef CONFIG_PPC_64K_PAGES typedef unsigned long pud_t; -#define pud_val(x) (x) #define __pud(x) (x) +static inline unsigned long pud_val(pud_t pud) +{ + return pud; +} #endif /* !CONFIG_PPC_64K_PAGES */ #endif /* CONFIG_PPC64 */ typedef unsigned long pgd_t; -#define pgd_val(x) (x) -#define pgprot_val(x) (x) +#define __pgd(x) (x) +static inline unsigned long pgd_val(pgd_t pgd) +{ + return pgd; +} typedef unsigned long pgprot_t; -#define __pgd(x) (x) +#define pgprot_val(x) (x) #define __pgprot(x) (x) #endif diff --git a/arch/powerpc/include/asm/pgalloc-32.h b/arch/powerpc/include/asm/pgalloc-32.h index 842846c1b7118..76d6b9e0c8a94 100644 --- a/arch/powerpc/include/asm/pgalloc-32.h +++ b/arch/powerpc/include/asm/pgalloc-32.h @@ -21,16 +21,34 @@ extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); /* #define pgd_populate(mm, pmd, pte) BUG() */ #ifndef CONFIG_BOOKE -#define pmd_populate_kernel(mm, pmd, pte) \ - (pmd_val(*(pmd)) = __pa(pte) | _PMD_PRESENT) -#define pmd_populate(mm, pmd, pte) \ - (pmd_val(*(pmd)) = (page_to_pfn(pte) << PAGE_SHIFT) | _PMD_PRESENT) + +static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, + pte_t *pte) +{ + *pmdp = __pmd(__pa(pte) | _PMD_PRESENT); +} + +static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp, + pgtable_t pte_page) +{ + *pmdp = __pmd((page_to_pfn(pte_page) << PAGE_SHIFT) | _PMD_PRESENT); +} + #define pmd_pgtable(pmd) pmd_page(pmd) #else -#define pmd_populate_kernel(mm, pmd, pte) \ - (pmd_val(*(pmd)) = (unsigned long)pte | _PMD_PRESENT) -#define pmd_populate(mm, pmd, pte) \ - (pmd_val(*(pmd)) = (unsigned long)lowmem_page_address(pte) | _PMD_PRESENT) + +static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, + pte_t *pte) +{ + *pmdp = __pmd((unsigned long)pte | _PMD_PRESENT); +} + +static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp, + pgtable_t pte_page) +{ + *pmdp = __pmd((unsigned long)lowmem_page_address(pte_page) | _PMD_PRESENT); +} + #define pmd_pgtable(pmd) pmd_page(pmd) #endif diff --git a/arch/powerpc/include/asm/pgalloc-64.h b/arch/powerpc/include/asm/pgalloc-64.h index 4b0be20fcbfde..d8cde71f6734a 100644 --- a/arch/powerpc/include/asm/pgalloc-64.h +++ b/arch/powerpc/include/asm/pgalloc-64.h @@ -53,7 +53,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) #ifndef CONFIG_PPC_64K_PAGES -#define pgd_populate(MM, PGD, PUD) pgd_set(PGD, PUD) +#define pgd_populate(MM, PGD, PUD) pgd_set(PGD, (unsigned long)PUD) static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) { @@ -71,9 +71,18 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) pud_set(pud, (unsigned long)pmd); } -#define pmd_populate(mm, pmd, pte_page) \ - pmd_populate_kernel(mm, pmd, page_address(pte_page)) -#define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, (unsigned long)(pte)) +static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, + pte_t *pte) +{ + pmd_set(pmd, (unsigned long)pte); +} + +static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, + pgtable_t pte_page) +{ + pmd_set(pmd, (unsigned long)page_address(pte_page)); +} + #define pmd_pgtable(pmd) pmd_page(pmd) static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h index aac6547b08234..fbb23c54b998d 100644 --- a/arch/powerpc/include/asm/pgtable-ppc32.h +++ b/arch/powerpc/include/asm/pgtable-ppc32.h @@ -128,7 +128,12 @@ extern int icache_44x_need_flush; #define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_bad(pmd) (pmd_val(pmd) & _PMD_BAD) #define pmd_present(pmd) (pmd_val(pmd) & _PMD_PRESENT_MASK) -#define pmd_clear(pmdp) do { pmd_val(*(pmdp)) = 0; } while (0) +static inline void pmd_clear(pmd_t *pmdp) +{ + *pmdp = __pmd(0); +} + + /* * When flushing the tlb entry for a page, we also need to flush the hash diff --git a/arch/powerpc/include/asm/pgtable-ppc64-4k.h b/arch/powerpc/include/asm/pgtable-ppc64-4k.h index 132ee1d482c25..7bace25d6b62a 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64-4k.h +++ b/arch/powerpc/include/asm/pgtable-ppc64-4k.h @@ -55,11 +55,15 @@ #define pgd_none(pgd) (!pgd_val(pgd)) #define pgd_bad(pgd) (pgd_val(pgd) == 0) #define pgd_present(pgd) (pgd_val(pgd) != 0) -#define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0) #define pgd_page_vaddr(pgd) (pgd_val(pgd) & ~PGD_MASKED_BITS) #ifndef __ASSEMBLY__ +static inline void pgd_clear(pgd_t *pgdp) +{ + *pgdp = __pgd(0); +} + static inline pte_t pgd_pte(pgd_t pgd) { return __pte(pgd_val(pgd)); diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h index 1ef0fea32e1e6..6be203d43fd1d 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64.h +++ b/arch/powerpc/include/asm/pgtable-ppc64.h @@ -144,21 +144,37 @@ #define PMD_BAD_BITS (PTE_TABLE_SIZE-1) #define PUD_BAD_BITS (PMD_TABLE_SIZE-1) -#define pmd_set(pmdp, pmdval) (pmd_val(*(pmdp)) = (pmdval)) +static inline void pmd_set(pmd_t *pmdp, unsigned long val) +{ + *pmdp = __pmd(val); +} + +static inline void pmd_clear(pmd_t *pmdp) +{ + *pmdp = __pmd(0); +} + #define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \ || (pmd_val(pmd) & PMD_BAD_BITS)) #define pmd_present(pmd) (!pmd_none(pmd)) -#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0) #define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS) extern struct page *pmd_page(pmd_t pmd); -#define pud_set(pudp, pudval) (pud_val(*(pudp)) = (pudval)) +static inline void pud_set(pud_t *pudp, unsigned long val) +{ + *pudp = __pud(val); +} + +static inline void pud_clear(pud_t *pudp) +{ + *pudp = __pud(0); +} + #define pud_none(pud) (!pud_val(pud)) #define pud_bad(pud) (!is_kernel_addr(pud_val(pud)) \ || (pud_val(pud) & PUD_BAD_BITS)) #define pud_present(pud) (pud_val(pud) != 0) -#define pud_clear(pudp) (pud_val(*(pudp)) = 0) #define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS) extern struct page *pud_page(pud_t pud); @@ -173,9 +189,13 @@ static inline pud_t pte_pud(pte_t pte) return __pud(pte_val(pte)); } #define pud_write(pud) pte_write(pud_pte(pud)) -#define pgd_set(pgdp, pudp) ({pgd_val(*(pgdp)) = (unsigned long)(pudp);}) #define pgd_write(pgd) pte_write(pgd_pte(pgd)) +static inline void pgd_set(pgd_t *pgdp, unsigned long val) +{ + *pgdp = __pgd(val); +} + /* * Find an entry in a page-table-directory. We combine the address region * (the high order N bits) and the pgd portion of the address. @@ -528,14 +548,12 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd) static inline pmd_t pmd_mknotpresent(pmd_t pmd) { - pmd_val(pmd) &= ~_PAGE_PRESENT; - return pmd; + return __pmd(pmd_val(pmd) & ~_PAGE_PRESENT); } static inline pmd_t pmd_mksplitting(pmd_t pmd) { - pmd_val(pmd) |= _PAGE_SPLITTING; - return pmd; + return __pmd(pmd_val(pmd) | _PAGE_SPLITTING); } #define __HAVE_ARCH_PMD_SAME diff --git a/arch/powerpc/mm/40x_mmu.c b/arch/powerpc/mm/40x_mmu.c index 5810967511d4d..31a5d42df8c9a 100644 --- a/arch/powerpc/mm/40x_mmu.c +++ b/arch/powerpc/mm/40x_mmu.c @@ -110,10 +110,10 @@ unsigned long __init mmu_mapin_ram(unsigned long top) unsigned long val = p | _PMD_SIZE_16M | _PAGE_EXEC | _PAGE_HWWRITE; pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v); - pmd_val(*pmdp++) = val; - pmd_val(*pmdp++) = val; - pmd_val(*pmdp++) = val; - pmd_val(*pmdp++) = val; + *pmdp++ = __pmd(val); + *pmdp++ = __pmd(val); + *pmdp++ = __pmd(val); + *pmdp++ = __pmd(val); v += LARGE_PAGE_SIZE_16M; p += LARGE_PAGE_SIZE_16M; @@ -125,7 +125,7 @@ unsigned long __init mmu_mapin_ram(unsigned long top) unsigned long val = p | _PMD_SIZE_4M | _PAGE_EXEC | _PAGE_HWWRITE; pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v); - pmd_val(*pmdp) = val; + *pmdp = __pmd(val); v += LARGE_PAGE_SIZE_4M; p += LARGE_PAGE_SIZE_4M; diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index e92cb2146b186..d692ae31cfc76 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -759,22 +759,20 @@ void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr, static pmd_t pmd_set_protbits(pmd_t pmd, pgprot_t pgprot) { - pmd_val(pmd) |= pgprot_val(pgprot); - return pmd; + return __pmd(pmd_val(pmd) | pgprot_val(pgprot)); } pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot) { - pmd_t pmd; + unsigned long pmdv; /* * For a valid pte, we would have _PAGE_PRESENT always * set. We use this to check THP page at pmd level. * leaf pte for huge page, bottom two bits != 00 */ - pmd_val(pmd) = pfn << PTE_RPN_SHIFT; - pmd_val(pmd) |= _PAGE_THP_HUGE; - pmd = pmd_set_protbits(pmd, pgprot); - return pmd; + pmdv = pfn << PTE_RPN_SHIFT; + pmdv |= _PAGE_THP_HUGE; + return pmd_set_protbits(__pmd(pmdv), pgprot); } pmd_t mk_pmd(struct page *page, pgprot_t pgprot) @@ -784,10 +782,11 @@ pmd_t mk_pmd(struct page *page, pgprot_t pgprot) pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) { + unsigned long pmdv; - pmd_val(pmd) &= _HPAGE_CHG_MASK; - pmd = pmd_set_protbits(pmd, newprot); - return pmd; + pmdv = pmd_val(pmd); + pmdv &= _HPAGE_CHG_MASK; + return pmd_set_protbits(__pmd(pmdv), newprot); } /* -- GitLab From 371352ca0e7f3fad8406933e37c965d5a44365d9 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:36 +0530 Subject: [PATCH 1206/2855] powerpc/mm: Move hash64 PTE bits from book3s/64/pgtable.h to hash.h This enables us to keep hash64 related bits together, and makes it easy to follow. Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/hash.h | 448 ++++++++++++++++++- arch/powerpc/include/asm/book3s/64/pgtable.h | 445 +----------------- arch/powerpc/include/asm/pgtable.h | 6 - 3 files changed, 448 insertions(+), 451 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 7deb5063ff8c9..447b212649c80 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -2,6 +2,61 @@ #define _ASM_POWERPC_BOOK3S_64_HASH_H #ifdef __KERNEL__ +#ifdef CONFIG_PPC_64K_PAGES +#include +#else +#include +#endif + +/* + * Size of EA range mapped by our pagetables. + */ +#define PGTABLE_EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \ + PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT) +#define PGTABLE_RANGE (ASM_CONST(1) << PGTABLE_EADDR_SIZE) + +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +#define PMD_CACHE_INDEX (PMD_INDEX_SIZE + 1) +#else +#define PMD_CACHE_INDEX PMD_INDEX_SIZE +#endif +/* + * Define the address range of the kernel non-linear virtual area + */ +#define KERN_VIRT_START ASM_CONST(0xD000000000000000) +#define KERN_VIRT_SIZE ASM_CONST(0x0000100000000000) + +/* + * The vmalloc space starts at the beginning of that region, and + * occupies half of it on hash CPUs and a quarter of it on Book3E + * (we keep a quarter for the virtual memmap) + */ +#define VMALLOC_START KERN_VIRT_START +#define VMALLOC_SIZE (KERN_VIRT_SIZE >> 1) +#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE) + +/* + * Region IDs + */ +#define REGION_SHIFT 60UL +#define REGION_MASK (0xfUL << REGION_SHIFT) +#define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT) + +#define VMALLOC_REGION_ID (REGION_ID(VMALLOC_START)) +#define KERNEL_REGION_ID (REGION_ID(PAGE_OFFSET)) +#define VMEMMAP_REGION_ID (0xfUL) /* Server only */ +#define USER_REGION_ID (0UL) + +/* + * Defines the address of the vmemap area, in its own region on + * hash table CPUs. + */ +#define VMEMMAP_BASE (VMEMMAP_REGION_ID << REGION_SHIFT) + +#ifdef CONFIG_PPC_MM_SLICES +#define HAVE_ARCH_UNMAPPED_AREA +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN +#endif /* CONFIG_PPC_MM_SLICES */ /* * Common bits between 4K and 64K pages in a linux-style PTE. * These match the bits in the (hardware-defined) PowerPC PTE as closely @@ -46,11 +101,398 @@ /* Hash table based platforms need atomic updates of the linux PTE */ #define PTE_ATOMIC_UPDATES 1 -#ifdef CONFIG_PPC_64K_PAGES -#include +/* + * THP pages can't be special. So use the _PAGE_SPECIAL + */ +#define _PAGE_SPLITTING _PAGE_SPECIAL + +/* + * We need to differentiate between explicit huge page and THP huge + * page, since THP huge page also need to track real subpage details + */ +#define _PAGE_THP_HUGE _PAGE_4K_PFN + +/* + * set of bits not changed in pmd_modify. + */ +#define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | \ + _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SPLITTING | \ + _PAGE_THP_HUGE) +#define _PTE_NONE_MASK _PAGE_HPTEFLAGS +/* + * The mask convered by the RPN must be a ULL on 32-bit platforms with + * 64-bit PTEs + */ +#define PTE_RPN_MASK (~((1UL << PTE_RPN_SHIFT) - 1)) +/* + * _PAGE_CHG_MASK masks of bits that are to be preserved across + * pgprot changes + */ +#define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \ + _PAGE_ACCESSED | _PAGE_SPECIAL) +/* + * Mask of bits returned by pte_pgprot() + */ +#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \ + _PAGE_WRITETHRU | _PAGE_4K_PFN | \ + _PAGE_USER | _PAGE_ACCESSED | \ + _PAGE_RW | _PAGE_DIRTY | _PAGE_EXEC) +/* + * We define 2 sets of base prot bits, one for basic pages (ie, + * cacheable kernel and user pages) and one for non cacheable + * pages. We always set _PAGE_COHERENT when SMP is enabled or + * the processor might need it for DMA coherency. + */ +#define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_PSIZE) +#define _PAGE_BASE (_PAGE_BASE_NC | _PAGE_COHERENT) + +/* Permission masks used to generate the __P and __S table, + * + * Note:__pgprot is defined in arch/powerpc/include/asm/page.h + * + * Write permissions imply read permissions for now (we could make write-only + * pages on BookE but we don't bother for now). Execute permission control is + * possible on platforms that define _PAGE_EXEC + * + * Note due to the way vm flags are laid out, the bits are XWR + */ +#define PAGE_NONE __pgprot(_PAGE_BASE) +#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW) +#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | \ + _PAGE_EXEC) +#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER ) +#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) +#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER ) +#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) + +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY_X +#define __P101 PAGE_READONLY_X +#define __P110 PAGE_COPY_X +#define __P111 PAGE_COPY_X + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY_X +#define __S101 PAGE_READONLY_X +#define __S110 PAGE_SHARED_X +#define __S111 PAGE_SHARED_X + +/* Permission masks used for kernel mappings */ +#define PAGE_KERNEL __pgprot(_PAGE_BASE | _PAGE_KERNEL_RW) +#define PAGE_KERNEL_NC __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \ + _PAGE_NO_CACHE) +#define PAGE_KERNEL_NCG __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \ + _PAGE_NO_CACHE | _PAGE_GUARDED) +#define PAGE_KERNEL_X __pgprot(_PAGE_BASE | _PAGE_KERNEL_RWX) +#define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO) +#define PAGE_KERNEL_ROX __pgprot(_PAGE_BASE | _PAGE_KERNEL_ROX) + +/* Protection used for kernel text. We want the debuggers to be able to + * set breakpoints anywhere, so don't write protect the kernel text + * on platforms where such control is possible. + */ +#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) ||\ + defined(CONFIG_KPROBES) || defined(CONFIG_DYNAMIC_FTRACE) +#define PAGE_KERNEL_TEXT PAGE_KERNEL_X #else -#include +#define PAGE_KERNEL_TEXT PAGE_KERNEL_ROX #endif +/* Make modules code happy. We don't set RO yet */ +#define PAGE_KERNEL_EXEC PAGE_KERNEL_X +#define PAGE_AGP (PAGE_KERNEL_NC) + +#define PMD_BAD_BITS (PTE_TABLE_SIZE-1) +#define PUD_BAD_BITS (PMD_TABLE_SIZE-1) +/* + * We save the slot number & secondary bit in the second half of the + * PTE page. We use the 8 bytes per each pte entry. + */ +#define PTE_PAGE_HIDX_OFFSET (PTRS_PER_PTE * 8) + +#ifndef __ASSEMBLY__ +#define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \ + || (pmd_val(pmd) & PMD_BAD_BITS)) +#define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS) + +#define pud_bad(pud) (!is_kernel_addr(pud_val(pud)) \ + || (pud_val(pud) & PUD_BAD_BITS)) +#define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS) + +#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD - 1)) +#define pmd_index(address) (((address) >> (PMD_SHIFT)) & (PTRS_PER_PMD - 1)) +#define pte_index(address) (((address) >> (PAGE_SHIFT)) & (PTRS_PER_PTE - 1)) + +extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, unsigned long pte, int huge); +extern unsigned long pmd_hugepage_update(struct mm_struct *mm, + unsigned long addr, + pmd_t *pmdp, + unsigned long clr, + unsigned long set); +/* Atomic PTE updates */ +static inline unsigned long pte_update(struct mm_struct *mm, + unsigned long addr, + pte_t *ptep, unsigned long clr, + unsigned long set, + int huge) +{ + unsigned long old, tmp; + + __asm__ __volatile__( + "1: ldarx %0,0,%3 # pte_update\n\ + andi. %1,%0,%6\n\ + bne- 1b \n\ + andc %1,%0,%4 \n\ + or %1,%1,%7\n\ + stdcx. %1,0,%3 \n\ + bne- 1b" + : "=&r" (old), "=&r" (tmp), "=m" (*ptep) + : "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY), "r" (set) + : "cc" ); + /* huge pages use the old page table lock */ + if (!huge) + assert_pte_locked(mm, addr); + + if (old & _PAGE_HASHPTE) + hpte_need_flush(mm, addr, ptep, old, huge); + + return old; +} + +static inline int __ptep_test_and_clear_young(struct mm_struct *mm, + unsigned long addr, pte_t *ptep) +{ + unsigned long old; + + if ((pte_val(*ptep) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0) + return 0; + old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0); + return (old & _PAGE_ACCESSED) != 0; +} +#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG +#define ptep_test_and_clear_young(__vma, __addr, __ptep) \ +({ \ + int __r; \ + __r = __ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep); \ + __r; \ +}) + +#define __HAVE_ARCH_PTEP_SET_WRPROTECT +static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, + pte_t *ptep) +{ + + if ((pte_val(*ptep) & _PAGE_RW) == 0) + return; + + pte_update(mm, addr, ptep, _PAGE_RW, 0, 0); +} + +static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, + unsigned long addr, pte_t *ptep) +{ + if ((pte_val(*ptep) & _PAGE_RW) == 0) + return; + + pte_update(mm, addr, ptep, _PAGE_RW, 0, 1); +} + +/* + * We currently remove entries from the hashtable regardless of whether + * the entry was young or dirty. The generic routines only flush if the + * entry was young or dirty which is not good enough. + * + * We should be more intelligent about this but for the moment we override + * these functions and force a tlb flush unconditionally + */ +#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH +#define ptep_clear_flush_young(__vma, __address, __ptep) \ +({ \ + int __young = __ptep_test_and_clear_young((__vma)->vm_mm, __address, \ + __ptep); \ + __young; \ +}) + +#define __HAVE_ARCH_PTEP_GET_AND_CLEAR +static inline pte_t ptep_get_and_clear(struct mm_struct *mm, + unsigned long addr, pte_t *ptep) +{ + unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0, 0); + return __pte(old); +} + +static inline void pte_clear(struct mm_struct *mm, unsigned long addr, + pte_t * ptep) +{ + pte_update(mm, addr, ptep, ~0UL, 0, 0); +} + + +/* Set the dirty and/or accessed bits atomically in a linux PTE, this + * function doesn't need to flush the hash entry + */ +static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) +{ + unsigned long bits = pte_val(entry) & + (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC); + + unsigned long old, tmp; + + __asm__ __volatile__( + "1: ldarx %0,0,%4\n\ + andi. %1,%0,%6\n\ + bne- 1b \n\ + or %0,%3,%0\n\ + stdcx. %0,0,%4\n\ + bne- 1b" + :"=&r" (old), "=&r" (tmp), "=m" (*ptep) + :"r" (bits), "r" (ptep), "m" (*ptep), "i" (_PAGE_BUSY) + :"cc"); +} + +#define __HAVE_ARCH_PTE_SAME +#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0) + +static inline char *get_hpte_slot_array(pmd_t *pmdp) +{ + /* + * The hpte hindex is stored in the pgtable whose address is in the + * second half of the PMD + * + * Order this load with the test for pmd_trans_huge in the caller + */ + smp_rmb(); + return *(char **)(pmdp + PTRS_PER_PMD); + + +} +/* + * The linux hugepage PMD now include the pmd entries followed by the address + * to the stashed pgtable_t. The stashed pgtable_t contains the hpte bits. + * [ 1 bit secondary | 3 bit hidx | 1 bit valid | 000]. We use one byte per + * each HPTE entry. With 16MB hugepage and 64K HPTE we need 256 entries and + * with 4K HPTE we need 4096 entries. Both will fit in a 4K pgtable_t. + * + * The last three bits are intentionally left to zero. This memory location + * are also used as normal page PTE pointers. So if we have any pointers + * left around while we collapse a hugepage, we need to make sure + * _PAGE_PRESENT bit of that is zero when we look at them + */ +static inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index) +{ + return (hpte_slot_array[index] >> 3) & 0x1; +} + +static inline unsigned int hpte_hash_index(unsigned char *hpte_slot_array, + int index) +{ + return hpte_slot_array[index] >> 4; +} + +static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array, + unsigned int index, unsigned int hidx) +{ + hpte_slot_array[index] = hidx << 4 | 0x1 << 3; +} + +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +/* + * + * For core kernel code by design pmd_trans_huge is never run on any hugetlbfs + * page. The hugetlbfs page table walking and mangling paths are totally + * separated form the core VM paths and they're differentiated by + * VM_HUGETLB being set on vm_flags well before any pmd_trans_huge could run. + * + * pmd_trans_huge() is defined as false at build time if + * CONFIG_TRANSPARENT_HUGEPAGE=n to optimize away code blocks at build + * time in such case. + * + * For ppc64 we need to differntiate from explicit hugepages from THP, because + * for THP we also track the subpage details at the pmd level. We don't do + * that for explicit huge pages. + * + */ +static inline int pmd_trans_huge(pmd_t pmd) +{ + /* + * leaf pte for huge page, bottom two bits != 00 + */ + return (pmd_val(pmd) & 0x3) && (pmd_val(pmd) & _PAGE_THP_HUGE); +} + +static inline int pmd_trans_splitting(pmd_t pmd) +{ + if (pmd_trans_huge(pmd)) + return pmd_val(pmd) & _PAGE_SPLITTING; + return 0; +} + +#endif +static inline int pmd_large(pmd_t pmd) +{ + /* + * leaf pte for huge page, bottom two bits != 00 + */ + return ((pmd_val(pmd) & 0x3) != 0x0); +} + +static inline pmd_t pmd_mknotpresent(pmd_t pmd) +{ + return __pmd(pmd_val(pmd) & ~_PAGE_PRESENT); +} + +static inline pmd_t pmd_mksplitting(pmd_t pmd) +{ + return __pmd(pmd_val(pmd) | _PAGE_SPLITTING); +} + +#define __HAVE_ARCH_PMD_SAME +static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b) +{ + return (((pmd_val(pmd_a) ^ pmd_val(pmd_b)) & ~_PAGE_HPTEFLAGS) == 0); +} + +static inline int __pmdp_test_and_clear_young(struct mm_struct *mm, + unsigned long addr, pmd_t *pmdp) +{ + unsigned long old; + + if ((pmd_val(*pmdp) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0) + return 0; + old = pmd_hugepage_update(mm, addr, pmdp, _PAGE_ACCESSED, 0); + return ((old & _PAGE_ACCESSED) != 0); +} + +#define __HAVE_ARCH_PMDP_SET_WRPROTECT +static inline void pmdp_set_wrprotect(struct mm_struct *mm, unsigned long addr, + pmd_t *pmdp) +{ + + if ((pmd_val(*pmdp) & _PAGE_RW) == 0) + return; + + pmd_hugepage_update(mm, addr, pmdp, _PAGE_RW, 0); +} + +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +extern void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr, + pmd_t *pmdp, unsigned long old_pmd); +#else +static inline void hpte_do_hugepage_flush(struct mm_struct *mm, + unsigned long addr, pmd_t *pmdp, + unsigned long old_pmd) +{ + WARN(1, "%s called with THP disabled\n", __func__); +} +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ + +#endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_H */ diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index 09c6474f89c72..aac630b4a15e3 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -8,32 +8,6 @@ #include #include - -/* - * Size of EA range mapped by our pagetables. - */ -#define PGTABLE_EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \ - PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT) -#define PGTABLE_RANGE (ASM_CONST(1) << PGTABLE_EADDR_SIZE) - -#ifdef CONFIG_TRANSPARENT_HUGEPAGE -#define PMD_CACHE_INDEX (PMD_INDEX_SIZE + 1) -#else -#define PMD_CACHE_INDEX PMD_INDEX_SIZE -#endif -/* - * Define the address range of the kernel non-linear virtual area - */ -#define KERN_VIRT_START ASM_CONST(0xD000000000000000) -#define KERN_VIRT_SIZE ASM_CONST(0x0000100000000000) -/* - * The vmalloc space starts at the beginning of that region, and - * occupies half of it on hash CPUs and a quarter of it on Book3E - * (we keep a quarter for the virtual memmap) - */ -#define VMALLOC_START KERN_VIRT_START -#define VMALLOC_SIZE (KERN_VIRT_SIZE >> 1) -#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE) /* * The second half of the kernel virtual space is used for IO mappings, * it's itself carved into the PIO region (ISA and PHB IO space) and @@ -52,146 +26,9 @@ #define IOREMAP_BASE (PHB_IO_END) #define IOREMAP_END (KERN_VIRT_START + KERN_VIRT_SIZE) -/* - * Region IDs - */ -#define REGION_SHIFT 60UL -#define REGION_MASK (0xfUL << REGION_SHIFT) -#define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT) - -#define VMALLOC_REGION_ID (REGION_ID(VMALLOC_START)) -#define KERNEL_REGION_ID (REGION_ID(PAGE_OFFSET)) -#define VMEMMAP_REGION_ID (0xfUL) /* Server only */ -#define USER_REGION_ID (0UL) - -/* - * Defines the address of the vmemap area, in its own region on - * hash table CPUs. - */ -#define VMEMMAP_BASE (VMEMMAP_REGION_ID << REGION_SHIFT) #define vmemmap ((struct page *)VMEMMAP_BASE) - -#ifdef CONFIG_PPC_MM_SLICES -#define HAVE_ARCH_UNMAPPED_AREA -#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN -#endif /* CONFIG_PPC_MM_SLICES */ - -/* - * THP pages can't be special. So use the _PAGE_SPECIAL - */ -#define _PAGE_SPLITTING _PAGE_SPECIAL - -/* - * We need to differentiate between explicit huge page and THP huge - * page, since THP huge page also need to track real subpage details - */ -#define _PAGE_THP_HUGE _PAGE_4K_PFN - -/* - * set of bits not changed in pmd_modify. - */ -#define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | \ - _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SPLITTING | \ - _PAGE_THP_HUGE) -#define _PTE_NONE_MASK _PAGE_HPTEFLAGS -/* - * The mask convered by the RPN must be a ULL on 32-bit platforms with - * 64-bit PTEs - */ -#define PTE_RPN_MASK (~((1UL << PTE_RPN_SHIFT) - 1)) -/* - * _PAGE_CHG_MASK masks of bits that are to be preserved across - * pgprot changes - */ -#define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \ - _PAGE_ACCESSED | _PAGE_SPECIAL) -/* - * Mask of bits returned by pte_pgprot() - */ -#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \ - _PAGE_WRITETHRU | _PAGE_4K_PFN | \ - _PAGE_USER | _PAGE_ACCESSED | \ - _PAGE_RW | _PAGE_DIRTY | _PAGE_EXEC) -/* - * We define 2 sets of base prot bits, one for basic pages (ie, - * cacheable kernel and user pages) and one for non cacheable - * pages. We always set _PAGE_COHERENT when SMP is enabled or - * the processor might need it for DMA coherency. - */ -#define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_PSIZE) -#define _PAGE_BASE (_PAGE_BASE_NC | _PAGE_COHERENT) - -/* Permission masks used to generate the __P and __S table, - * - * Note:__pgprot is defined in arch/powerpc/include/asm/page.h - * - * Write permissions imply read permissions for now (we could make write-only - * pages on BookE but we don't bother for now). Execute permission control is - * possible on platforms that define _PAGE_EXEC - * - * Note due to the way vm flags are laid out, the bits are XWR - */ -#define PAGE_NONE __pgprot(_PAGE_BASE) -#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW) -#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | \ - _PAGE_EXEC) -#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER ) -#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) -#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER ) -#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) - -#define __P000 PAGE_NONE -#define __P001 PAGE_READONLY -#define __P010 PAGE_COPY -#define __P011 PAGE_COPY -#define __P100 PAGE_READONLY_X -#define __P101 PAGE_READONLY_X -#define __P110 PAGE_COPY_X -#define __P111 PAGE_COPY_X - -#define __S000 PAGE_NONE -#define __S001 PAGE_READONLY -#define __S010 PAGE_SHARED -#define __S011 PAGE_SHARED -#define __S100 PAGE_READONLY_X -#define __S101 PAGE_READONLY_X -#define __S110 PAGE_SHARED_X -#define __S111 PAGE_SHARED_X - -/* Permission masks used for kernel mappings */ -#define PAGE_KERNEL __pgprot(_PAGE_BASE | _PAGE_KERNEL_RW) -#define PAGE_KERNEL_NC __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \ - _PAGE_NO_CACHE) -#define PAGE_KERNEL_NCG __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \ - _PAGE_NO_CACHE | _PAGE_GUARDED) -#define PAGE_KERNEL_X __pgprot(_PAGE_BASE | _PAGE_KERNEL_RWX) -#define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO) -#define PAGE_KERNEL_ROX __pgprot(_PAGE_BASE | _PAGE_KERNEL_ROX) - -/* Protection used for kernel text. We want the debuggers to be able to - * set breakpoints anywhere, so don't write protect the kernel text - * on platforms where such control is possible. - */ -#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) ||\ - defined(CONFIG_KPROBES) || defined(CONFIG_DYNAMIC_FTRACE) -#define PAGE_KERNEL_TEXT PAGE_KERNEL_X -#else -#define PAGE_KERNEL_TEXT PAGE_KERNEL_ROX -#endif - -/* Make modules code happy. We don't set RO yet */ -#define PAGE_KERNEL_EXEC PAGE_KERNEL_X - -/* - * Don't just check for any non zero bits in __PAGE_USER, since for book3e - * and PTE_64BIT, PAGE_KERNEL_X contains _PAGE_BAP_SR which is also in - * _PAGE_USER. Need to explicitly match _PAGE_BAP_UR bit in that case too. - */ -#define pte_user(val) ((val & _PAGE_USER) == _PAGE_USER) - /* Advertise special mapping type for AGP */ -#define PAGE_AGP (PAGE_KERNEL_NC) #define HAVE_PAGE_AGP /* Advertise support for _PAGE_SPECIAL */ @@ -230,12 +67,6 @@ #endif /* __real_pte */ - -/* pte_clear moved to later in this file */ - -#define PMD_BAD_BITS (PTE_TABLE_SIZE-1) -#define PUD_BAD_BITS (PMD_TABLE_SIZE-1) - static inline void pmd_set(pmd_t *pmdp, unsigned long val) { *pmdp = __pmd(val); @@ -246,13 +77,8 @@ static inline void pmd_clear(pmd_t *pmdp) *pmdp = __pmd(0); } - #define pmd_none(pmd) (!pmd_val(pmd)) -#define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \ - || (pmd_val(pmd) & PMD_BAD_BITS)) #define pmd_present(pmd) (!pmd_none(pmd)) -#define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS) -extern struct page *pmd_page(pmd_t pmd); static inline void pud_set(pud_t *pudp, unsigned long val) { @@ -265,13 +91,10 @@ static inline void pud_clear(pud_t *pudp) } #define pud_none(pud) (!pud_val(pud)) -#define pud_bad(pud) (!is_kernel_addr(pud_val(pud)) \ - || (pud_val(pud) & PUD_BAD_BITS)) #define pud_present(pud) (pud_val(pud) != 0) -#define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS) extern struct page *pud_page(pud_t pud); - +extern struct page *pmd_page(pmd_t pmd); static inline pte_t pud_pte(pud_t pud) { return __pte(pud_val(pud)); @@ -292,15 +115,14 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val) * Find an entry in a page-table-directory. We combine the address region * (the high order N bits) and the pgd portion of the address. */ -#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD - 1)) #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) #define pmd_offset(pudp,addr) \ - (((pmd_t *) pud_page_vaddr(*(pudp))) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))) + (((pmd_t *) pud_page_vaddr(*(pudp))) + pmd_index(addr)) #define pte_offset_kernel(dir,addr) \ - (((pte_t *) pmd_page_vaddr(*(dir))) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))) + (((pte_t *) pmd_page_vaddr(*(dir))) + pte_index(addr)) #define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr)) #define pte_unmap(pte) do { } while(0) @@ -308,132 +130,6 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val) /* to find an entry in a kernel page-table-directory */ /* This now only contains the vmalloc pages */ #define pgd_offset_k(address) pgd_offset(&init_mm, address) -extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, unsigned long pte, int huge); - -/* Atomic PTE updates */ -static inline unsigned long pte_update(struct mm_struct *mm, - unsigned long addr, - pte_t *ptep, unsigned long clr, - unsigned long set, - int huge) -{ - unsigned long old, tmp; - - __asm__ __volatile__( - "1: ldarx %0,0,%3 # pte_update\n\ - andi. %1,%0,%6\n\ - bne- 1b \n\ - andc %1,%0,%4 \n\ - or %1,%1,%7\n\ - stdcx. %1,0,%3 \n\ - bne- 1b" - : "=&r" (old), "=&r" (tmp), "=m" (*ptep) - : "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY), "r" (set) - : "cc" ); - /* huge pages use the old page table lock */ - if (!huge) - assert_pte_locked(mm, addr); - - if (old & _PAGE_HASHPTE) - hpte_need_flush(mm, addr, ptep, old, huge); - - return old; -} - -static inline int __ptep_test_and_clear_young(struct mm_struct *mm, - unsigned long addr, pte_t *ptep) -{ - unsigned long old; - - if ((pte_val(*ptep) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0) - return 0; - old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0); - return (old & _PAGE_ACCESSED) != 0; -} -#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG -#define ptep_test_and_clear_young(__vma, __addr, __ptep) \ -({ \ - int __r; \ - __r = __ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep); \ - __r; \ -}) - -#define __HAVE_ARCH_PTEP_SET_WRPROTECT -static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, - pte_t *ptep) -{ - - if ((pte_val(*ptep) & _PAGE_RW) == 0) - return; - - pte_update(mm, addr, ptep, _PAGE_RW, 0, 0); -} - -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, - unsigned long addr, pte_t *ptep) -{ - if ((pte_val(*ptep) & _PAGE_RW) == 0) - return; - - pte_update(mm, addr, ptep, _PAGE_RW, 0, 1); -} - -/* - * We currently remove entries from the hashtable regardless of whether - * the entry was young or dirty. The generic routines only flush if the - * entry was young or dirty which is not good enough. - * - * We should be more intelligent about this but for the moment we override - * these functions and force a tlb flush unconditionally - */ -#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH -#define ptep_clear_flush_young(__vma, __address, __ptep) \ -({ \ - int __young = __ptep_test_and_clear_young((__vma)->vm_mm, __address, \ - __ptep); \ - __young; \ -}) - -#define __HAVE_ARCH_PTEP_GET_AND_CLEAR -static inline pte_t ptep_get_and_clear(struct mm_struct *mm, - unsigned long addr, pte_t *ptep) -{ - unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0, 0); - return __pte(old); -} - -static inline void pte_clear(struct mm_struct *mm, unsigned long addr, - pte_t * ptep) -{ - pte_update(mm, addr, ptep, ~0UL, 0, 0); -} - - -/* Set the dirty and/or accessed bits atomically in a linux PTE, this - * function doesn't need to flush the hash entry - */ -static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) -{ - unsigned long bits = pte_val(entry) & - (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC); - - unsigned long old, tmp; - - __asm__ __volatile__( - "1: ldarx %0,0,%4\n\ - andi. %1,%0,%6\n\ - bne- 1b \n\ - or %0,%3,%0\n\ - stdcx. %0,0,%4\n\ - bne- 1b" - :"=&r" (old), "=&r" (tmp), "=m" (*ptep) - :"r" (bits), "r" (ptep), "m" (*ptep), "i" (_PAGE_BUSY) - :"cc"); -} - -#define __HAVE_ARCH_PTE_SAME -#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0) #define pte_ERROR(e) \ pr_err("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) @@ -468,54 +164,9 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) void pgtable_cache_add(unsigned shift, void (*ctor)(void *)); void pgtable_cache_init(void); -/* - * The linux hugepage PMD now include the pmd entries followed by the address - * to the stashed pgtable_t. The stashed pgtable_t contains the hpte bits. - * [ 1 bit secondary | 3 bit hidx | 1 bit valid | 000]. We use one byte per - * each HPTE entry. With 16MB hugepage and 64K HPTE we need 256 entries and - * with 4K HPTE we need 4096 entries. Both will fit in a 4K pgtable_t. - * - * The last three bits are intentionally left to zero. This memory location - * are also used as normal page PTE pointers. So if we have any pointers - * left around while we collapse a hugepage, we need to make sure - * _PAGE_PRESENT bit of that is zero when we look at them - */ -static inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index) -{ - return (hpte_slot_array[index] >> 3) & 0x1; -} - -static inline unsigned int hpte_hash_index(unsigned char *hpte_slot_array, - int index) -{ - return hpte_slot_array[index] >> 4; -} - -static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array, - unsigned int index, unsigned int hidx) -{ - hpte_slot_array[index] = hidx << 4 | 0x1 << 3; -} - struct page *realmode_pfn_to_page(unsigned long pfn); -static inline char *get_hpte_slot_array(pmd_t *pmdp) -{ - /* - * The hpte hindex is stored in the pgtable whose address is in the - * second half of the PMD - * - * Order this load with the test for pmd_trans_huge in the caller - */ - smp_rmb(); - return *(char **)(pmdp + PTRS_PER_PMD); - - -} - #ifdef CONFIG_TRANSPARENT_HUGEPAGE -extern void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr, - pmd_t *pmdp, unsigned long old_pmd); extern pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot); extern pmd_t mk_pmd(struct page *page, pgprot_t pgprot); extern pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot); @@ -523,55 +174,9 @@ extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp, pmd_t pmd); extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, pmd_t *pmd); -/* - * - * For core kernel code by design pmd_trans_huge is never run on any hugetlbfs - * page. The hugetlbfs page table walking and mangling paths are totally - * separated form the core VM paths and they're differentiated by - * VM_HUGETLB being set on vm_flags well before any pmd_trans_huge could run. - * - * pmd_trans_huge() is defined as false at build time if - * CONFIG_TRANSPARENT_HUGEPAGE=n to optimize away code blocks at build - * time in such case. - * - * For ppc64 we need to differntiate from explicit hugepages from THP, because - * for THP we also track the subpage details at the pmd level. We don't do - * that for explicit huge pages. - * - */ -static inline int pmd_trans_huge(pmd_t pmd) -{ - /* - * leaf pte for huge page, bottom two bits != 00 - */ - return (pmd_val(pmd) & 0x3) && (pmd_val(pmd) & _PAGE_THP_HUGE); -} - -static inline int pmd_trans_splitting(pmd_t pmd) -{ - if (pmd_trans_huge(pmd)) - return pmd_val(pmd) & _PAGE_SPLITTING; - return 0; -} - extern int has_transparent_hugepage(void); -#else -static inline void hpte_do_hugepage_flush(struct mm_struct *mm, - unsigned long addr, pmd_t *pmdp, - unsigned long old_pmd) -{ - - WARN(1, "%s called with THP disabled\n", __func__); -} #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ -static inline int pmd_large(pmd_t pmd) -{ - /* - * leaf pte for huge page, bottom two bits != 00 - */ - return ((pmd_val(pmd) & 0x3) != 0x0); -} static inline pte_t pmd_pte(pmd_t pmd) { @@ -606,44 +211,11 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd) return pmd; } -static inline pmd_t pmd_mknotpresent(pmd_t pmd) -{ - return __pmd(pmd_val(pmd) & ~_PAGE_PRESENT); -} - -static inline pmd_t pmd_mksplitting(pmd_t pmd) -{ - return __pmd(pmd_val(pmd) | _PAGE_SPLITTING); -} - -#define __HAVE_ARCH_PMD_SAME -static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b) -{ - return (((pmd_val(pmd_a) ^ pmd_val(pmd_b)) & ~_PAGE_HPTEFLAGS) == 0); -} - #define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS extern int pmdp_set_access_flags(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp, pmd_t entry, int dirty); -extern unsigned long pmd_hugepage_update(struct mm_struct *mm, - unsigned long addr, - pmd_t *pmdp, - unsigned long clr, - unsigned long set); - -static inline int __pmdp_test_and_clear_young(struct mm_struct *mm, - unsigned long addr, pmd_t *pmdp) -{ - unsigned long old; - - if ((pmd_val(*pmdp) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0) - return 0; - old = pmd_hugepage_update(mm, addr, pmdp, _PAGE_ACCESSED, 0); - return ((old & _PAGE_ACCESSED) != 0); -} - #define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG extern int pmdp_test_and_clear_young(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp); @@ -655,17 +227,6 @@ extern int pmdp_clear_flush_young(struct vm_area_struct *vma, extern pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp); -#define __HAVE_ARCH_PMDP_SET_WRPROTECT -static inline void pmdp_set_wrprotect(struct mm_struct *mm, unsigned long addr, - pmd_t *pmdp) -{ - - if ((pmd_val(*pmdp) & _PAGE_RW) == 0) - return; - - pmd_hugepage_update(mm, addr, pmdp, _PAGE_RW, 0); -} - #define __HAVE_ARCH_PMDP_SPLITTING_FLUSH extern void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp); diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h index a27b8cef51d70..8f7338678fdcd 100644 --- a/arch/powerpc/include/asm/pgtable.h +++ b/arch/powerpc/include/asm/pgtable.h @@ -18,12 +18,6 @@ struct mm_struct; #include #endif /* !CONFIG_PPC_BOOK3S */ -/* - * We save the slot number & secondary bit in the second half of the - * PTE page. We use the 8 bytes per each pte entry. - */ -#define PTE_PAGE_HIDX_OFFSET (PTRS_PER_PTE * 8) - #ifndef __ASSEMBLY__ #include -- GitLab From 1ca7212932862e348f2f9307f35bd309a7da82d8 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:37 +0530 Subject: [PATCH 1207/2855] powerpc/mm: Move PTE bits from generic functions to hash64 functions. functions which operate on pte bits are moved to hash*.h and other generic functions are moved to pgtable.h Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/32/pgtable.h | 183 +++++++++++++++++ arch/powerpc/include/asm/book3s/64/hash.h | 151 ++++++++++++++ arch/powerpc/include/asm/book3s/64/pgtable.h | 6 + arch/powerpc/include/asm/book3s/pgtable.h | 204 ------------------- 4 files changed, 340 insertions(+), 204 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h index 226f29d39332c..38b33dcfcc9d2 100644 --- a/arch/powerpc/include/asm/book3s/32/pgtable.h +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h @@ -294,6 +294,189 @@ void pgtable_cache_init(void); extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp); +/* Generic accessors to PTE bits */ +static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & _PAGE_RW);} +static inline int pte_dirty(pte_t pte) { return !!(pte_val(pte) & _PAGE_DIRTY); } +static inline int pte_young(pte_t pte) { return !!(pte_val(pte) & _PAGE_ACCESSED); } +static inline int pte_special(pte_t pte) { return !!(pte_val(pte) & _PAGE_SPECIAL); } +static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; } +static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); } + +static inline int pte_present(pte_t pte) +{ + return pte_val(pte) & _PAGE_PRESENT; +} + +/* Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + * + * Even if PTEs can be unsigned long long, a PFN is always an unsigned + * long for now. + */ +static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) +{ + return __pte(((pte_basic_t)(pfn) << PTE_RPN_SHIFT) | + pgprot_val(pgprot)); +} + +static inline unsigned long pte_pfn(pte_t pte) +{ + return pte_val(pte) >> PTE_RPN_SHIFT; +} + +/* Generic modifiers for PTE bits */ +static inline pte_t pte_wrprotect(pte_t pte) +{ + return __pte(pte_val(pte) & ~_PAGE_RW); +} + +static inline pte_t pte_mkclean(pte_t pte) +{ + return __pte(pte_val(pte) & ~_PAGE_DIRTY); +} + +static inline pte_t pte_mkold(pte_t pte) +{ + return __pte(pte_val(pte) & ~_PAGE_ACCESSED); +} + +static inline pte_t pte_mkwrite(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_RW); +} + +static inline pte_t pte_mkdirty(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_DIRTY); +} + +static inline pte_t pte_mkyoung(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_ACCESSED); +} + +static inline pte_t pte_mkspecial(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_SPECIAL); +} + +static inline pte_t pte_mkhuge(pte_t pte) +{ + return pte; +} + +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)); +} + + + +/* This low level function performs the actual PTE insertion + * Setting the PTE depends on the MMU type and other factors. It's + * an horrible mess that I'm not going to try to clean up now but + * I'm keeping it in one place rather than spread around + */ +static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte, int percpu) +{ +#if defined(CONFIG_PPC_STD_MMU_32) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT) + /* First case is 32-bit Hash MMU in SMP mode with 32-bit PTEs. We use the + * helper pte_update() which does an atomic update. We need to do that + * because a concurrent invalidation can clear _PAGE_HASHPTE. If it's a + * per-CPU PTE such as a kmap_atomic, we do a simple update preserving + * the hash bits instead (ie, same as the non-SMP case) + */ + if (percpu) + *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) + | (pte_val(pte) & ~_PAGE_HASHPTE)); + else + pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte)); + +#elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) + /* Second case is 32-bit with 64-bit PTE. In this case, we + * can just store as long as we do the two halves in the right order + * with a barrier in between. This is possible because we take care, + * in the hash code, to pre-invalidate if the PTE was already hashed, + * which synchronizes us with any concurrent invalidation. + * In the percpu case, we also fallback to the simple update preserving + * the hash bits + */ + if (percpu) { + *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) + | (pte_val(pte) & ~_PAGE_HASHPTE)); + return; + } + if (pte_val(*ptep) & _PAGE_HASHPTE) + flush_hash_entry(mm, ptep, addr); + __asm__ __volatile__("\ + stw%U0%X0 %2,%0\n\ + eieio\n\ + stw%U0%X0 %L2,%1" + : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4)) + : "r" (pte) : "memory"); + +#elif defined(CONFIG_PPC_STD_MMU_32) + /* Third case is 32-bit hash table in UP mode, we need to preserve + * the _PAGE_HASHPTE bit since we may not have invalidated the previous + * translation in the hash yet (done in a subsequent flush_tlb_xxx()) + * and see we need to keep track that this PTE needs invalidating + */ + *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) + | (pte_val(pte) & ~_PAGE_HASHPTE)); + +#else +#error "Not supported " +#endif +} + +/* + * Macro to mark a page protection value as "uncacheable". + */ + +#define _PAGE_CACHE_CTL (_PAGE_COHERENT | _PAGE_GUARDED | _PAGE_NO_CACHE | \ + _PAGE_WRITETHRU) + +#define pgprot_noncached pgprot_noncached +static inline pgprot_t pgprot_noncached(pgprot_t prot) +{ + return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | + _PAGE_NO_CACHE | _PAGE_GUARDED); +} + +#define pgprot_noncached_wc pgprot_noncached_wc +static inline pgprot_t pgprot_noncached_wc(pgprot_t prot) +{ + return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | + _PAGE_NO_CACHE); +} + +#define pgprot_cached pgprot_cached +static inline pgprot_t pgprot_cached(pgprot_t prot) +{ + return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | + _PAGE_COHERENT); +} + +#define pgprot_cached_wthru pgprot_cached_wthru +static inline pgprot_t pgprot_cached_wthru(pgprot_t prot) +{ + return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | + _PAGE_COHERENT | _PAGE_WRITETHRU); +} + +#define pgprot_cached_noncoherent pgprot_cached_noncoherent +static inline pgprot_t pgprot_cached_noncoherent(pgprot_t prot) +{ + return __pgprot(pgprot_val(prot) & ~_PAGE_CACHE_CTL); +} + +#define pgprot_writecombine pgprot_writecombine +static inline pgprot_t pgprot_writecombine(pgprot_t prot) +{ + return pgprot_noncached_wc(prot); +} + #endif /* !__ASSEMBLY__ */ #endif /* _ASM_POWERPC_BOOK3S_32_PGTABLE_H */ diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 447b212649c80..48237e66e8239 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -481,6 +481,157 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm, unsigned long addr, pmd_hugepage_update(mm, addr, pmdp, _PAGE_RW, 0); } +/* Generic accessors to PTE bits */ +static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & _PAGE_RW);} +static inline int pte_dirty(pte_t pte) { return !!(pte_val(pte) & _PAGE_DIRTY); } +static inline int pte_young(pte_t pte) { return !!(pte_val(pte) & _PAGE_ACCESSED); } +static inline int pte_special(pte_t pte) { return !!(pte_val(pte) & _PAGE_SPECIAL); } +static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; } +static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); } + +#ifdef CONFIG_NUMA_BALANCING +/* + * These work without NUMA balancing but the kernel does not care. See the + * comment in include/asm-generic/pgtable.h . On powerpc, this will only + * work for user pages and always return true for kernel pages. + */ +static inline int pte_protnone(pte_t pte) +{ + return (pte_val(pte) & + (_PAGE_PRESENT | _PAGE_USER)) == _PAGE_PRESENT; +} +#endif /* CONFIG_NUMA_BALANCING */ + +static inline int pte_present(pte_t pte) +{ + return pte_val(pte) & _PAGE_PRESENT; +} + +/* Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + * + * Even if PTEs can be unsigned long long, a PFN is always an unsigned + * long for now. + */ +static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) +{ + return __pte(((pte_basic_t)(pfn) << PTE_RPN_SHIFT) | + pgprot_val(pgprot)); +} + +static inline unsigned long pte_pfn(pte_t pte) +{ + return pte_val(pte) >> PTE_RPN_SHIFT; +} + +/* Generic modifiers for PTE bits */ +static inline pte_t pte_wrprotect(pte_t pte) +{ + return __pte(pte_val(pte) & ~_PAGE_RW); +} + +static inline pte_t pte_mkclean(pte_t pte) +{ + return __pte(pte_val(pte) & ~_PAGE_DIRTY); +} + +static inline pte_t pte_mkold(pte_t pte) +{ + return __pte(pte_val(pte) & ~_PAGE_ACCESSED); +} + +static inline pte_t pte_mkwrite(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_RW); +} + +static inline pte_t pte_mkdirty(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_DIRTY); +} + +static inline pte_t pte_mkyoung(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_ACCESSED); +} + +static inline pte_t pte_mkspecial(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_SPECIAL); +} + +static inline pte_t pte_mkhuge(pte_t pte) +{ + return pte; +} + +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)); +} + +/* This low level function performs the actual PTE insertion + * Setting the PTE depends on the MMU type and other factors. It's + * an horrible mess that I'm not going to try to clean up now but + * I'm keeping it in one place rather than spread around + */ +static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte, int percpu) +{ + /* + * Anything else just stores the PTE normally. That covers all 64-bit + * cases, and 32-bit non-hash with 32-bit PTEs. + */ + *ptep = pte; +} + +/* + * Macro to mark a page protection value as "uncacheable". + */ + +#define _PAGE_CACHE_CTL (_PAGE_COHERENT | _PAGE_GUARDED | _PAGE_NO_CACHE | \ + _PAGE_WRITETHRU) + +#define pgprot_noncached pgprot_noncached +static inline pgprot_t pgprot_noncached(pgprot_t prot) +{ + return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | + _PAGE_NO_CACHE | _PAGE_GUARDED); +} + +#define pgprot_noncached_wc pgprot_noncached_wc +static inline pgprot_t pgprot_noncached_wc(pgprot_t prot) +{ + return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | + _PAGE_NO_CACHE); +} + +#define pgprot_cached pgprot_cached +static inline pgprot_t pgprot_cached(pgprot_t prot) +{ + return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | + _PAGE_COHERENT); +} + +#define pgprot_cached_wthru pgprot_cached_wthru +static inline pgprot_t pgprot_cached_wthru(pgprot_t prot) +{ + return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | + _PAGE_COHERENT | _PAGE_WRITETHRU); +} + +#define pgprot_cached_noncoherent pgprot_cached_noncoherent +static inline pgprot_t pgprot_cached_noncoherent(pgprot_t prot) +{ + return __pgprot(pgprot_val(prot) & ~_PAGE_CACHE_CTL); +} + +#define pgprot_writecombine pgprot_writecombine +static inline pgprot_t pgprot_writecombine(pgprot_t prot) +{ + return pgprot_noncached_wc(prot); +} + #ifdef CONFIG_TRANSPARENT_HUGEPAGE extern void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp, unsigned long old_pmd); diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index aac630b4a15e3..f2ace2cac7bbb 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -201,6 +201,12 @@ static inline pte_t *pmdp_ptep(pmd_t *pmd) #define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd))) #define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd))) #define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd))) +#ifdef CONFIG_NUMA_BALANCING +static inline int pmd_protnone(pmd_t pmd) +{ + return pte_protnone(pmd_pte(pmd)); +} +#endif /* CONFIG_NUMA_BALANCING */ #define __HAVE_ARCH_PMD_WRITE #define pmd_write(pmd) pte_write(pmd_pte(pmd)) diff --git a/arch/powerpc/include/asm/book3s/pgtable.h b/arch/powerpc/include/asm/book3s/pgtable.h index ebd6677ea017e..8b0f4a29259a9 100644 --- a/arch/powerpc/include/asm/book3s/pgtable.h +++ b/arch/powerpc/include/asm/book3s/pgtable.h @@ -9,221 +9,17 @@ #define FIRST_USER_ADDRESS 0UL #ifndef __ASSEMBLY__ - -/* Generic accessors to PTE bits */ -static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & _PAGE_RW);} -static inline int pte_dirty(pte_t pte) { return !!(pte_val(pte) & _PAGE_DIRTY); } -static inline int pte_young(pte_t pte) { return !!(pte_val(pte) & _PAGE_ACCESSED); } -static inline int pte_special(pte_t pte) { return !!(pte_val(pte) & _PAGE_SPECIAL); } -static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; } -static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); } - -#ifdef CONFIG_NUMA_BALANCING -/* - * These work without NUMA balancing but the kernel does not care. See the - * comment in include/asm-generic/pgtable.h . On powerpc, this will only - * work for user pages and always return true for kernel pages. - */ -static inline int pte_protnone(pte_t pte) -{ - return (pte_val(pte) & - (_PAGE_PRESENT | _PAGE_USER)) == _PAGE_PRESENT; -} - -static inline int pmd_protnone(pmd_t pmd) -{ - return pte_protnone(pmd_pte(pmd)); -} -#endif /* CONFIG_NUMA_BALANCING */ - -static inline int pte_present(pte_t pte) -{ - return pte_val(pte) & _PAGE_PRESENT; -} - -/* Conversion functions: convert a page and protection to a page entry, - * and a page entry and page directory to the page they refer to. - * - * Even if PTEs can be unsigned long long, a PFN is always an unsigned - * long for now. - */ -static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) -{ - return __pte(((pte_basic_t)(pfn) << PTE_RPN_SHIFT) | - pgprot_val(pgprot)); -} - -static inline unsigned long pte_pfn(pte_t pte) -{ - return pte_val(pte) >> PTE_RPN_SHIFT; -} - -/* Generic modifiers for PTE bits */ -static inline pte_t pte_wrprotect(pte_t pte) -{ - return __pte(pte_val(pte) & ~_PAGE_RW); -} - -static inline pte_t pte_mkclean(pte_t pte) -{ - return __pte(pte_val(pte) & ~_PAGE_DIRTY); -} - -static inline pte_t pte_mkold(pte_t pte) -{ - return __pte(pte_val(pte) & ~_PAGE_ACCESSED); -} - -static inline pte_t pte_mkwrite(pte_t pte) -{ - return __pte(pte_val(pte) | _PAGE_RW); -} - -static inline pte_t pte_mkdirty(pte_t pte) -{ - return __pte(pte_val(pte) | _PAGE_DIRTY); -} - -static inline pte_t pte_mkyoung(pte_t pte) -{ - return __pte(pte_val(pte) | _PAGE_ACCESSED); -} - -static inline pte_t pte_mkspecial(pte_t pte) -{ - return __pte(pte_val(pte) | _PAGE_SPECIAL); -} - -static inline pte_t pte_mkhuge(pte_t pte) -{ - return pte; -} - -static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -{ - return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)); -} - - /* Insert a PTE, top-level function is out of line. It uses an inline * low level function in the respective pgtable-* files */ extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte); -/* This low level function performs the actual PTE insertion - * Setting the PTE depends on the MMU type and other factors. It's - * an horrible mess that I'm not going to try to clean up now but - * I'm keeping it in one place rather than spread around - */ -static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t pte, int percpu) -{ -#if defined(CONFIG_PPC_STD_MMU_32) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT) - /* First case is 32-bit Hash MMU in SMP mode with 32-bit PTEs. We use the - * helper pte_update() which does an atomic update. We need to do that - * because a concurrent invalidation can clear _PAGE_HASHPTE. If it's a - * per-CPU PTE such as a kmap_atomic, we do a simple update preserving - * the hash bits instead (ie, same as the non-SMP case) - */ - if (percpu) - *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) - | (pte_val(pte) & ~_PAGE_HASHPTE)); - else - pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte)); - -#elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) - /* Second case is 32-bit with 64-bit PTE. In this case, we - * can just store as long as we do the two halves in the right order - * with a barrier in between. This is possible because we take care, - * in the hash code, to pre-invalidate if the PTE was already hashed, - * which synchronizes us with any concurrent invalidation. - * In the percpu case, we also fallback to the simple update preserving - * the hash bits - */ - if (percpu) { - *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) - | (pte_val(pte) & ~_PAGE_HASHPTE)); - return; - } - if (pte_val(*ptep) & _PAGE_HASHPTE) - flush_hash_entry(mm, ptep, addr); - __asm__ __volatile__("\ - stw%U0%X0 %2,%0\n\ - eieio\n\ - stw%U0%X0 %L2,%1" - : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4)) - : "r" (pte) : "memory"); - -#elif defined(CONFIG_PPC_STD_MMU_32) - /* Third case is 32-bit hash table in UP mode, we need to preserve - * the _PAGE_HASHPTE bit since we may not have invalidated the previous - * translation in the hash yet (done in a subsequent flush_tlb_xxx()) - * and see we need to keep track that this PTE needs invalidating - */ - *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) - | (pte_val(pte) & ~_PAGE_HASHPTE)); - -#else - /* Anything else just stores the PTE normally. That covers all 64-bit - * cases, and 32-bit non-hash with 32-bit PTEs. - */ - *ptep = pte; -#endif -} - #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, pte_t *ptep, pte_t entry, int dirty); -/* - * Macro to mark a page protection value as "uncacheable". - */ - -#define _PAGE_CACHE_CTL (_PAGE_COHERENT | _PAGE_GUARDED | _PAGE_NO_CACHE | \ - _PAGE_WRITETHRU) - -#define pgprot_noncached pgprot_noncached -static inline pgprot_t pgprot_noncached(pgprot_t prot) -{ - return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | - _PAGE_NO_CACHE | _PAGE_GUARDED); -} - -#define pgprot_noncached_wc pgprot_noncached_wc -static inline pgprot_t pgprot_noncached_wc(pgprot_t prot) -{ - return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | - _PAGE_NO_CACHE); -} - -#define pgprot_cached pgprot_cached -static inline pgprot_t pgprot_cached(pgprot_t prot) -{ - return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | - _PAGE_COHERENT); -} - -#define pgprot_cached_wthru pgprot_cached_wthru -static inline pgprot_t pgprot_cached_wthru(pgprot_t prot) -{ - return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | - _PAGE_COHERENT | _PAGE_WRITETHRU); -} - -#define pgprot_cached_noncoherent pgprot_cached_noncoherent -static inline pgprot_t pgprot_cached_noncoherent(pgprot_t prot) -{ - return __pgprot(pgprot_val(prot) & ~_PAGE_CACHE_CTL); -} - -#define pgprot_writecombine pgprot_writecombine -static inline pgprot_t pgprot_writecombine(pgprot_t prot) -{ - return pgprot_noncached_wc(prot); -} - struct file; extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, unsigned long size, pgprot_t vma_prot); -- GitLab From 17ed9e3192b2b29ad24ffe711fa4b71716ef3ff3 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:38 +0530 Subject: [PATCH 1208/2855] powerpc/booke: Move nohash headers Move the booke related headers below booke/32 or booke/64 Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- .../asm/{pgtable-ppc32.h => nohash/32/pgtable.h} | 16 ++++++++-------- .../include/asm/{ => nohash/32}/pte-40x.h | 6 +++--- .../include/asm/{ => nohash/32}/pte-44x.h | 6 +++--- .../include/asm/{ => nohash/32}/pte-8xx.h | 6 +++--- .../include/asm/{ => nohash/32}/pte-fsl-booke.h | 6 +++--- .../64/pgtable-4k.h} | 6 +++--- .../64/pgtable-64k.h} | 6 +++--- .../asm/{pgtable-ppc64.h => nohash/64/pgtable.h} | 14 +++++++------- .../asm/{pgtable-book3e.h => nohash/pgtable.h} | 8 ++++---- .../include/asm/{ => nohash}/pte-book3e.h | 6 +++--- arch/powerpc/include/asm/pgtable.h | 2 +- 11 files changed, 41 insertions(+), 41 deletions(-) rename arch/powerpc/include/asm/{pgtable-ppc32.h => nohash/32/pgtable.h} (97%) rename arch/powerpc/include/asm/{ => nohash/32}/pte-40x.h (95%) rename arch/powerpc/include/asm/{ => nohash/32}/pte-44x.h (96%) rename arch/powerpc/include/asm/{ => nohash/32}/pte-8xx.h (95%) rename arch/powerpc/include/asm/{ => nohash/32}/pte-fsl-booke.h (88%) rename arch/powerpc/include/asm/{pgtable-ppc64-4k.h => nohash/64/pgtable-4k.h} (94%) rename arch/powerpc/include/asm/{pgtable-ppc64-64k.h => nohash/64/pgtable-64k.h} (90%) rename arch/powerpc/include/asm/{pgtable-ppc64.h => nohash/64/pgtable.h} (98%) rename arch/powerpc/include/asm/{pgtable-book3e.h => nohash/pgtable.h} (97%) rename arch/powerpc/include/asm/{ => nohash}/pte-book3e.h (95%) diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/nohash/32/pgtable.h similarity index 97% rename from arch/powerpc/include/asm/pgtable-ppc32.h rename to arch/powerpc/include/asm/nohash/32/pgtable.h index fbb23c54b998d..c82cbf52d19ea 100644 --- a/arch/powerpc/include/asm/pgtable-ppc32.h +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h @@ -1,5 +1,5 @@ -#ifndef _ASM_POWERPC_PGTABLE_PPC32_H -#define _ASM_POWERPC_PGTABLE_PPC32_H +#ifndef _ASM_POWERPC_NOHASH_32_PGTABLE_H +#define _ASM_POWERPC_NOHASH_32_PGTABLE_H #include @@ -106,15 +106,15 @@ extern int icache_44x_need_flush; */ #if defined(CONFIG_40x) -#include +#include #elif defined(CONFIG_44x) -#include +#include #elif defined(CONFIG_FSL_BOOKE) && defined(CONFIG_PTE_64BIT) -#include +#include #elif defined(CONFIG_FSL_BOOKE) -#include +#include #elif defined(CONFIG_8xx) -#include +#include #endif /* And here we include common definitions */ @@ -340,4 +340,4 @@ extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, #endif /* !__ASSEMBLY__ */ -#endif /* _ASM_POWERPC_PGTABLE_PPC32_H */ +#endif /* __ASM_POWERPC_NOHASH_32_PGTABLE_H */ diff --git a/arch/powerpc/include/asm/pte-40x.h b/arch/powerpc/include/asm/nohash/32/pte-40x.h similarity index 95% rename from arch/powerpc/include/asm/pte-40x.h rename to arch/powerpc/include/asm/nohash/32/pte-40x.h index 486b1ef813387..9624ebdacc477 100644 --- a/arch/powerpc/include/asm/pte-40x.h +++ b/arch/powerpc/include/asm/nohash/32/pte-40x.h @@ -1,5 +1,5 @@ -#ifndef _ASM_POWERPC_PTE_40x_H -#define _ASM_POWERPC_PTE_40x_H +#ifndef _ASM_POWERPC_NOHASH_32_PTE_40x_H +#define _ASM_POWERPC_NOHASH_32_PTE_40x_H #ifdef __KERNEL__ /* @@ -61,4 +61,4 @@ #define PTE_ATOMIC_UPDATES 1 #endif /* __KERNEL__ */ -#endif /* _ASM_POWERPC_PTE_40x_H */ +#endif /* _ASM_POWERPC_NOHASH_32_PTE_40x_H */ diff --git a/arch/powerpc/include/asm/pte-44x.h b/arch/powerpc/include/asm/nohash/32/pte-44x.h similarity index 96% rename from arch/powerpc/include/asm/pte-44x.h rename to arch/powerpc/include/asm/nohash/32/pte-44x.h index 36f75fab23f52..fdab41c654efc 100644 --- a/arch/powerpc/include/asm/pte-44x.h +++ b/arch/powerpc/include/asm/nohash/32/pte-44x.h @@ -1,5 +1,5 @@ -#ifndef _ASM_POWERPC_PTE_44x_H -#define _ASM_POWERPC_PTE_44x_H +#ifndef _ASM_POWERPC_NOHASH_32_PTE_44x_H +#define _ASM_POWERPC_NOHASH_32_PTE_44x_H #ifdef __KERNEL__ /* @@ -94,4 +94,4 @@ #endif /* __KERNEL__ */ -#endif /* _ASM_POWERPC_PTE_44x_H */ +#endif /* _ASM_POWERPC_NOHASH_32_PTE_44x_H */ diff --git a/arch/powerpc/include/asm/pte-8xx.h b/arch/powerpc/include/asm/nohash/32/pte-8xx.h similarity index 95% rename from arch/powerpc/include/asm/pte-8xx.h rename to arch/powerpc/include/asm/nohash/32/pte-8xx.h index a0e2ba9609760..3742b19196615 100644 --- a/arch/powerpc/include/asm/pte-8xx.h +++ b/arch/powerpc/include/asm/nohash/32/pte-8xx.h @@ -1,5 +1,5 @@ -#ifndef _ASM_POWERPC_PTE_8xx_H -#define _ASM_POWERPC_PTE_8xx_H +#ifndef _ASM_POWERPC_NOHASH_32_PTE_8xx_H +#define _ASM_POWERPC_NOHASH_32_PTE_8xx_H #ifdef __KERNEL__ /* @@ -62,4 +62,4 @@ _PAGE_HWWRITE | _PAGE_EXEC) #endif /* __KERNEL__ */ -#endif /* _ASM_POWERPC_PTE_8xx_H */ +#endif /* _ASM_POWERPC_NOHASH_32_PTE_8xx_H */ diff --git a/arch/powerpc/include/asm/pte-fsl-booke.h b/arch/powerpc/include/asm/nohash/32/pte-fsl-booke.h similarity index 88% rename from arch/powerpc/include/asm/pte-fsl-booke.h rename to arch/powerpc/include/asm/nohash/32/pte-fsl-booke.h index 9f5c3d04a1a3e..5422d00c61452 100644 --- a/arch/powerpc/include/asm/pte-fsl-booke.h +++ b/arch/powerpc/include/asm/nohash/32/pte-fsl-booke.h @@ -1,5 +1,5 @@ -#ifndef _ASM_POWERPC_PTE_FSL_BOOKE_H -#define _ASM_POWERPC_PTE_FSL_BOOKE_H +#ifndef _ASM_POWERPC_NOHASH_32_PTE_FSL_BOOKE_H +#define _ASM_POWERPC_NOHASH_32_PTE_FSL_BOOKE_H #ifdef __KERNEL__ /* PTE bit definitions for Freescale BookE SW loaded TLB MMU based @@ -37,4 +37,4 @@ #define PTE_WIMGE_SHIFT (6) #endif /* __KERNEL__ */ -#endif /* _ASM_POWERPC_PTE_FSL_BOOKE_H */ +#endif /* _ASM_POWERPC_NOHASH_32_PTE_FSL_BOOKE_H */ diff --git a/arch/powerpc/include/asm/pgtable-ppc64-4k.h b/arch/powerpc/include/asm/nohash/64/pgtable-4k.h similarity index 94% rename from arch/powerpc/include/asm/pgtable-ppc64-4k.h rename to arch/powerpc/include/asm/nohash/64/pgtable-4k.h index 7bace25d6b62a..fc7d51753f811 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64-4k.h +++ b/arch/powerpc/include/asm/nohash/64/pgtable-4k.h @@ -1,5 +1,5 @@ -#ifndef _ASM_POWERPC_PGTABLE_PPC64_4K_H -#define _ASM_POWERPC_PGTABLE_PPC64_4K_H +#ifndef _ASM_POWERPC_NOHASH_64_PGTABLE_4K_H +#define _ASM_POWERPC_NOHASH_64_PGTABLE_4K_H /* * Entries per page directory level. The PTE level must use a 64b record * for each page table entry. The PMD and PGD level use a 32b record for @@ -89,4 +89,4 @@ extern struct page *pgd_page(pgd_t pgd); #define remap_4k_pfn(vma, addr, pfn, prot) \ remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot)) -#endif /* _ASM_POWERPC_PGTABLE_PPC64_4K_H */ +#endif /* _ _ASM_POWERPC_NOHASH_64_PGTABLE_4K_H */ diff --git a/arch/powerpc/include/asm/pgtable-ppc64-64k.h b/arch/powerpc/include/asm/nohash/64/pgtable-64k.h similarity index 90% rename from arch/powerpc/include/asm/pgtable-ppc64-64k.h rename to arch/powerpc/include/asm/nohash/64/pgtable-64k.h index 1de35bbd02a64..a44660d76096b 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64-64k.h +++ b/arch/powerpc/include/asm/nohash/64/pgtable-64k.h @@ -1,5 +1,5 @@ -#ifndef _ASM_POWERPC_PGTABLE_PPC64_64K_H -#define _ASM_POWERPC_PGTABLE_PPC64_64K_H +#ifndef _ASM_POWERPC_NOHASH_64_PGTABLE_64K_H +#define _ASM_POWERPC_NOHASH_64_PGTABLE_64K_H #include @@ -41,4 +41,4 @@ #define pgd_pte(pgd) (pud_pte(((pud_t){ pgd }))) #define pte_pgd(pte) ((pgd_t)pte_pud(pte)) -#endif /* _ASM_POWERPC_PGTABLE_PPC64_64K_H */ +#endif /* _ASM_POWERPC_NOHASH_64_PGTABLE_64K_H */ diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/nohash/64/pgtable.h similarity index 98% rename from arch/powerpc/include/asm/pgtable-ppc64.h rename to arch/powerpc/include/asm/nohash/64/pgtable.h index 6be203d43fd1d..c24e03f226556 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64.h +++ b/arch/powerpc/include/asm/nohash/64/pgtable.h @@ -1,14 +1,14 @@ -#ifndef _ASM_POWERPC_PGTABLE_PPC64_H_ -#define _ASM_POWERPC_PGTABLE_PPC64_H_ +#ifndef _ASM_POWERPC_NOHASH_64_PGTABLE_H +#define _ASM_POWERPC_NOHASH_64_PGTABLE_H /* * This file contains the functions and defines necessary to modify and use * the ppc64 hashed page table. */ #ifdef CONFIG_PPC_64K_PAGES -#include +#include #else -#include +#include #endif #include @@ -18,7 +18,7 @@ * Size of EA range mapped by our pagetables. */ #define PGTABLE_EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \ - PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT) + PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT) #define PGTABLE_RANGE (ASM_CONST(1) << PGTABLE_EADDR_SIZE) #ifdef CONFIG_TRANSPARENT_HUGEPAGE @@ -97,7 +97,7 @@ /* * Include the PTE bits definitions */ -#include +#include #include #ifdef CONFIG_PPC_MM_SLICES @@ -637,4 +637,4 @@ static inline int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl, return true; } #endif /* __ASSEMBLY__ */ -#endif /* _ASM_POWERPC_PGTABLE_PPC64_H_ */ +#endif /* _ASM_POWERPC_NOHASH_64_PGTABLE_H */ diff --git a/arch/powerpc/include/asm/pgtable-book3e.h b/arch/powerpc/include/asm/nohash/pgtable.h similarity index 97% rename from arch/powerpc/include/asm/pgtable-book3e.h rename to arch/powerpc/include/asm/nohash/pgtable.h index 91325997ba257..c0c41a2409d24 100644 --- a/arch/powerpc/include/asm/pgtable-book3e.h +++ b/arch/powerpc/include/asm/nohash/pgtable.h @@ -1,10 +1,10 @@ -#ifndef _ASM_POWERPC_PGTABLE_BOOK3E_H -#define _ASM_POWERPC_PGTABLE_BOOK3E_H +#ifndef _ASM_POWERPC_NOHASH_PGTABLE_H +#define _ASM_POWERPC_NOHASH_PGTABLE_H #if defined(CONFIG_PPC64) -#include +#include #else -#include +#include #endif #ifndef __ASSEMBLY__ diff --git a/arch/powerpc/include/asm/pte-book3e.h b/arch/powerpc/include/asm/nohash/pte-book3e.h similarity index 95% rename from arch/powerpc/include/asm/pte-book3e.h rename to arch/powerpc/include/asm/nohash/pte-book3e.h index 8d8473278d91c..e16807b78edf7 100644 --- a/arch/powerpc/include/asm/pte-book3e.h +++ b/arch/powerpc/include/asm/nohash/pte-book3e.h @@ -1,5 +1,5 @@ -#ifndef _ASM_POWERPC_PTE_BOOK3E_H -#define _ASM_POWERPC_PTE_BOOK3E_H +#ifndef _ASM_POWERPC_NOHASH_PTE_BOOK3E_H +#define _ASM_POWERPC_NOHASH_PTE_BOOK3E_H #ifdef __KERNEL__ /* PTE bit definitions for processors compliant to the Book3E @@ -84,4 +84,4 @@ #endif #endif /* __KERNEL__ */ -#endif /* _ASM_POWERPC_PTE_FSL_BOOKE_H */ +#endif /* _ASM_POWERPC_NOHASH_PTE_BOOK3E_H */ diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h index 8f7338678fdcd..ac9fb114e25d4 100644 --- a/arch/powerpc/include/asm/pgtable.h +++ b/arch/powerpc/include/asm/pgtable.h @@ -15,7 +15,7 @@ struct mm_struct; #ifdef CONFIG_PPC_BOOK3S #include #else -#include +#include #endif /* !CONFIG_PPC_BOOK3S */ #ifndef __ASSEMBLY__ -- GitLab From 91f1da99792a1d133df94c4753510305353064a1 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:43 +0530 Subject: [PATCH 1209/2855] powerpc/mm: Convert 4k hash insert to C Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/mm/Makefile | 3 + arch/powerpc/mm/hash64_64k.c | 202 +++++++++++++++++ arch/powerpc/mm/hash_low_64.S | 380 -------------------------------- arch/powerpc/mm/hash_utils_64.c | 4 +- 4 files changed, 208 insertions(+), 381 deletions(-) create mode 100644 arch/powerpc/mm/hash64_64k.c diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index 3eb73a38220de..f80ad1a76cc8f 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile @@ -18,6 +18,9 @@ obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o obj-$(CONFIG_PPC_STD_MMU) += hash_low_$(CONFIG_WORD_SIZE).o \ tlb_hash$(CONFIG_WORD_SIZE).o \ mmu_context_hash$(CONFIG_WORD_SIZE).o +ifeq ($(CONFIG_PPC_STD_MMU_64),y) +obj-$(CONFIG_PPC_64K_PAGES) += hash64_64k.o +endif obj-$(CONFIG_PPC_ICSWX) += icswx.o obj-$(CONFIG_PPC_ICSWX_PID) += icswx_pid.o obj-$(CONFIG_40x) += 40x_mmu.o diff --git a/arch/powerpc/mm/hash64_64k.c b/arch/powerpc/mm/hash64_64k.c new file mode 100644 index 0000000000000..9ffeae2cbb57d --- /dev/null +++ b/arch/powerpc/mm/hash64_64k.c @@ -0,0 +1,202 @@ +/* + * Copyright IBM Corporation, 2015 + * Author Aneesh Kumar K.V + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#include +#include +#include + +int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, + pte_t *ptep, unsigned long trap, unsigned long flags, + int ssize, int subpg_prot) +{ + real_pte_t rpte; + unsigned long *hidxp; + unsigned long hpte_group; + unsigned int subpg_index; + unsigned long rflags, pa, hidx; + unsigned long old_pte, new_pte, subpg_pte; + unsigned long vpn, hash, slot; + unsigned long shift = mmu_psize_defs[MMU_PAGE_4K].shift; + + /* + * atomically mark the linux large page PTE busy and dirty + */ + do { + pte_t pte = READ_ONCE(*ptep); + + old_pte = pte_val(pte); + /* If PTE busy, retry the access */ + if (unlikely(old_pte & _PAGE_BUSY)) + return 0; + /* If PTE permissions don't match, take page fault */ + if (unlikely(access & ~old_pte)) + return 1; + /* + * Try to lock the PTE, add ACCESSED and DIRTY if it was + * a write access. Since this is 4K insert of 64K page size + * also add _PAGE_COMBO + */ + new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED | _PAGE_COMBO; + if (access & _PAGE_RW) + new_pte |= _PAGE_DIRTY; + } while (old_pte != __cmpxchg_u64((unsigned long *)ptep, + old_pte, new_pte)); + /* + * Handle the subpage protection bits + */ + subpg_pte = new_pte & ~subpg_prot; + /* + * PP bits. _PAGE_USER is already PP bit 0x2, so we only + * need to add in 0x1 if it's a read-only user page + */ + rflags = subpg_pte & _PAGE_USER; + if ((subpg_pte & _PAGE_USER) && !((subpg_pte & _PAGE_RW) && + (subpg_pte & _PAGE_DIRTY))) + rflags |= 0x1; + /* + * _PAGE_EXEC -> HW_NO_EXEC since it's inverted + */ + rflags |= ((subpg_pte & _PAGE_EXEC) ? 0 : HPTE_R_N); + /* + * Always add C and Memory coherence bit + */ + rflags |= HPTE_R_C | HPTE_R_M; + /* + * Add in WIMG bits + */ + rflags |= (subpg_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE | + _PAGE_COHERENT | _PAGE_GUARDED)); + + if (!cpu_has_feature(CPU_FTR_NOEXECUTE) && + !cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) { + + /* + * No CPU has hugepages but lacks no execute, so we + * don't need to worry about that case + */ + rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap); + } + + subpg_index = (ea & (PAGE_SIZE - 1)) >> shift; + vpn = hpt_vpn(ea, vsid, ssize); + rpte = __real_pte(__pte(old_pte), ptep); + /* + *None of the sub 4k page is hashed + */ + if (!(old_pte & _PAGE_HASHPTE)) + goto htab_insert_hpte; + /* + * Check if the pte was already inserted into the hash table + * as a 64k HW page, and invalidate the 64k HPTE if so. + */ + if (!(old_pte & _PAGE_COMBO)) { + flush_hash_page(vpn, rpte, MMU_PAGE_64K, ssize, flags); + old_pte &= ~_PAGE_HPTE_SUB; + goto htab_insert_hpte; + } + /* + * Check for sub page valid and update + */ + if (__rpte_sub_valid(rpte, subpg_index)) { + int ret; + + hash = hpt_hash(vpn, shift, ssize); + hidx = __rpte_to_hidx(rpte, subpg_index); + if (hidx & _PTEIDX_SECONDARY) + hash = ~hash; + slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; + slot += hidx & _PTEIDX_GROUP_IX; + + ret = ppc_md.hpte_updatepp(slot, rflags, vpn, + MMU_PAGE_4K, MMU_PAGE_4K, + ssize, flags); + /* + *if we failed because typically the HPTE wasn't really here + * we try an insertion. + */ + if (ret == -1) + goto htab_insert_hpte; + + *ptep = __pte(new_pte & ~_PAGE_BUSY); + return 0; + } + +htab_insert_hpte: + /* + * handle _PAGE_4K_PFN case + */ + if (old_pte & _PAGE_4K_PFN) { + /* + * All the sub 4k page have the same + * physical address. + */ + pa = pte_pfn(__pte(old_pte)) << HW_PAGE_SHIFT; + } else { + pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT; + pa += (subpg_index << shift); + } + hash = hpt_hash(vpn, shift, ssize); +repeat: + hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL; + + /* Insert into the hash table, primary slot */ + slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, 0, + MMU_PAGE_4K, MMU_PAGE_4K, ssize); + /* + * Primary is full, try the secondary + */ + if (unlikely(slot == -1)) { + hpte_group = ((~hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL; + slot = ppc_md.hpte_insert(hpte_group, vpn, pa, + rflags, HPTE_V_SECONDARY, + MMU_PAGE_4K, MMU_PAGE_4K, ssize); + if (slot == -1) { + if (mftb() & 0x1) + hpte_group = ((hash & htab_hash_mask) * + HPTES_PER_GROUP) & ~0x7UL; + ppc_md.hpte_remove(hpte_group); + /* + * FIXME!! Should be try the group from which we removed ? + */ + goto repeat; + } + } + /* + * Hypervisor failure. Restore old pmd and return -1 + * similar to __hash_page_* + */ + if (unlikely(slot == -2)) { + *ptep = __pte(old_pte); + hash_failure_debug(ea, access, vsid, trap, ssize, + MMU_PAGE_4K, MMU_PAGE_4K, old_pte); + return -1; + } + /* + * Insert slot number & secondary bit in PTE second half, + * clear _PAGE_BUSY and set appropriate HPTE slot bit + * Since we have _PAGE_BUSY set on ptep, we can be sure + * nobody is undating hidx. + */ + hidxp = (unsigned long *)(ptep + PTRS_PER_PTE); + /* __real_pte use pte_val() any idea why ? FIXME!! */ + rpte.hidx &= ~(0xfUL << (subpg_index << 2)); + *hidxp = rpte.hidx | (slot << (subpg_index << 2)); + new_pte |= (_PAGE_HPTE_SUB0 >> subpg_index); + /* + * check __real_pte for details on matching smp_rmb() + */ + smp_wmb(); + *ptep = __pte(new_pte & ~_PAGE_BUSY); + return 0; +} diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S index 3b49e32959019..6b4d4c1d0628c 100644 --- a/arch/powerpc/mm/hash_low_64.S +++ b/arch/powerpc/mm/hash_low_64.S @@ -328,381 +328,8 @@ htab_pte_insert_failure: li r3,-1 b htab_bail - #else /* CONFIG_PPC_64K_PAGES */ - -/***************************************************************************** - * * - * 64K SW & 4K or 64K HW in a 4K segment pages implementation * - * * - *****************************************************************************/ - -/* _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, - * pte_t *ptep, unsigned long trap, unsigned local flags, - * int ssize, int subpg_prot) - */ - -/* - * For now, we do NOT implement Admixed pages - */ -_GLOBAL(__hash_page_4K) - mflr r0 - std r0,16(r1) - stdu r1,-STACKFRAMESIZE(r1) - /* Save all params that we need after a function call */ - std r6,STK_PARAM(R6)(r1) - std r8,STK_PARAM(R8)(r1) - std r9,STK_PARAM(R9)(r1) - - /* Save non-volatile registers. - * r31 will hold "old PTE" - * r30 is "new PTE" - * r29 is vpn - * r28 is a hash value - * r27 is hashtab mask (maybe dynamic patched instead ?) - * r26 is the hidx mask - * r25 is the index in combo page - */ - std r25,STK_REG(R25)(r1) - std r26,STK_REG(R26)(r1) - std r27,STK_REG(R27)(r1) - std r28,STK_REG(R28)(r1) - std r29,STK_REG(R29)(r1) - std r30,STK_REG(R30)(r1) - std r31,STK_REG(R31)(r1) - - /* Step 1: - * - * Check permissions, atomically mark the linux PTE busy - * and hashed. - */ -1: - ldarx r31,0,r6 - /* Check access rights (access & ~(pte_val(*ptep))) */ - andc. r0,r4,r31 - bne- htab_wrong_access - /* Check if PTE is busy */ - andi. r0,r31,_PAGE_BUSY - /* If so, just bail out and refault if needed. Someone else - * is changing this PTE anyway and might hash it. - */ - bne- htab_bail_ok - /* Prepare new PTE value (turn access RW into DIRTY, then - * add BUSY and ACCESSED) - */ - rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */ - or r30,r30,r31 - ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED - oris r30,r30,_PAGE_COMBO@h - /* Write the linux PTE atomically (setting busy) */ - stdcx. r30,0,r6 - bne- 1b - isync - - /* Step 2: - * - * Insert/Update the HPTE in the hash table. At this point, - * r4 (access) is re-useable, we use it for the new HPTE flags - */ - - /* Load the hidx index */ - rldicl r25,r3,64-12,60 - -BEGIN_FTR_SECTION - cmpdi r9,0 /* check segment size */ - bne 3f -END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) - /* Calc vpn and put it in r29 */ - sldi r29,r5,SID_SHIFT - VPN_SHIFT - /* - * clrldi r3,r3,64 - SID_SHIFT --> ea & 0xfffffff - * srdi r28,r3,VPN_SHIFT - */ - rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT) - or r29,r28,r29 - /* - * Calculate hash value for primary slot and store it in r28 - * r3 = va, r5 = vsid - * r0 = (va >> 12) & ((1ul << (28 - 12)) -1) - */ - rldicl r0,r3,64-12,48 - xor r28,r5,r0 /* hash */ - b 4f - -3: /* Calc vpn and put it in r29 */ - sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT - /* - * clrldi r3,r3,64 - SID_SHIFT_1T --> ea & 0xffffffffff - * srdi r28,r3,VPN_SHIFT - */ - rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT) - or r29,r28,r29 - - /* - * Calculate hash value for primary slot and - * store it in r28 for 1T segment - * r3 = va, r5 = vsid - */ - sldi r28,r5,25 /* vsid << 25 */ - /* r0 = (va >> 12) & ((1ul << (40 - 12)) -1) */ - rldicl r0,r3,64-12,36 - xor r28,r28,r5 /* vsid ^ ( vsid << 25) */ - xor r28,r28,r0 /* hash */ - - /* Convert linux PTE bits into HW equivalents */ -4: -#ifdef CONFIG_PPC_SUBPAGE_PROT - andc r10,r30,r10 - andi. r3,r10,0x1fe /* Get basic set of flags */ - rlwinm r0,r10,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */ -#else - andi. r3,r30,0x1fe /* Get basic set of flags */ - rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */ -#endif - xori r3,r3,HPTE_R_N /* _PAGE_EXEC -> NOEXEC */ - rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY -> _PAGE_USER (r4) */ - and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/ - andc r0,r3,r0 /* r0 = pte & ~r0 */ - rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */ - /* - * Always add "C" bit for perf. Memory coherence is always enabled - */ - ori r3,r3,HPTE_R_C | HPTE_R_M - - /* We eventually do the icache sync here (maybe inline that - * code rather than call a C function...) - */ -BEGIN_FTR_SECTION - mr r4,r30 - mr r5,r7 - bl hash_page_do_lazy_icache -END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) - - /* At this point, r3 contains new PP bits, save them in - * place of "access" in the param area (sic) - */ - std r3,STK_PARAM(R4)(r1) - - /* Get htab_hash_mask */ - ld r4,htab_hash_mask@got(2) - ld r27,0(r4) /* htab_hash_mask -> r27 */ - - /* Check if we may already be in the hashtable, in this case, we - * go to out-of-line code to try to modify the HPTE. We look for - * the bit at (1 >> (index + 32)) - */ - rldicl. r0,r31,64-12,48 - li r26,0 /* Default hidx */ - beq htab_insert_pte - - /* - * Check if the pte was already inserted into the hash table - * as a 64k HW page, and invalidate the 64k HPTE if so. - */ - andis. r0,r31,_PAGE_COMBO@h - beq htab_inval_old_hpte - - ld r6,STK_PARAM(R6)(r1) - ori r26,r6,PTE_PAGE_HIDX_OFFSET /* Load the hidx mask. */ - ld r26,0(r26) - addi r5,r25,36 /* Check actual HPTE_SUB bit, this */ - rldcr. r0,r31,r5,0 /* must match pgtable.h definition */ - bne htab_modify_pte - -htab_insert_pte: - /* real page number in r5, PTE RPN value + index */ - andis. r0,r31,_PAGE_4K_PFN@h - srdi r5,r31,PTE_RPN_SHIFT - bne- htab_special_pfn - sldi r5,r5,PAGE_FACTOR - add r5,r5,r25 -htab_special_pfn: - sldi r5,r5,HW_PAGE_SHIFT - - /* Calculate primary group hash */ - and r0,r28,r27 - rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ - - /* Call ppc_md.hpte_insert */ - ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ - mr r4,r29 /* Retrieve vpn */ - li r7,0 /* !bolted, !secondary */ - li r8,MMU_PAGE_4K /* page size */ - li r9,MMU_PAGE_4K /* actual page size */ - ld r10,STK_PARAM(R9)(r1) /* segment size */ -.globl htab_call_hpte_insert1 -htab_call_hpte_insert1: - bl . /* patched by htab_finish_init() */ - cmpdi 0,r3,0 - bge htab_pte_insert_ok /* Insertion successful */ - cmpdi 0,r3,-2 /* Critical failure */ - beq- htab_pte_insert_failure - - /* Now try secondary slot */ - - /* real page number in r5, PTE RPN value + index */ - andis. r0,r31,_PAGE_4K_PFN@h - srdi r5,r31,PTE_RPN_SHIFT - bne- 3f - sldi r5,r5,PAGE_FACTOR - add r5,r5,r25 -3: sldi r5,r5,HW_PAGE_SHIFT - - /* Calculate secondary group hash */ - andc r0,r27,r28 - rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */ - - /* Call ppc_md.hpte_insert */ - ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ - mr r4,r29 /* Retrieve vpn */ - li r7,HPTE_V_SECONDARY /* !bolted, secondary */ - li r8,MMU_PAGE_4K /* page size */ - li r9,MMU_PAGE_4K /* actual page size */ - ld r10,STK_PARAM(R9)(r1) /* segment size */ -.globl htab_call_hpte_insert2 -htab_call_hpte_insert2: - bl . /* patched by htab_finish_init() */ - cmpdi 0,r3,0 - bge+ htab_pte_insert_ok /* Insertion successful */ - cmpdi 0,r3,-2 /* Critical failure */ - beq- htab_pte_insert_failure - - /* Both are full, we need to evict something */ - mftb r0 - /* Pick a random group based on TB */ - andi. r0,r0,1 - mr r5,r28 - bne 2f - not r5,r5 -2: and r0,r5,r27 - rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ - /* Call ppc_md.hpte_remove */ -.globl htab_call_hpte_remove -htab_call_hpte_remove: - bl . /* patched by htab_finish_init() */ - - /* Try all again */ - b htab_insert_pte - - /* - * Call out to C code to invalidate an 64k HW HPTE that is - * useless now that the segment has been switched to 4k pages. - */ -htab_inval_old_hpte: - mr r3,r29 /* vpn */ - mr r4,r31 /* PTE.pte */ - li r5,0 /* PTE.hidx */ - li r6,MMU_PAGE_64K /* psize */ - ld r7,STK_PARAM(R9)(r1) /* ssize */ - ld r8,STK_PARAM(R8)(r1) /* flags */ - bl flush_hash_page - /* Clear out _PAGE_HPTE_SUB bits in the new linux PTE */ - lis r0,_PAGE_HPTE_SUB@h - ori r0,r0,_PAGE_HPTE_SUB@l - andc r30,r30,r0 - b htab_insert_pte - -htab_bail_ok: - li r3,0 - b htab_bail - -htab_pte_insert_ok: - /* Insert slot number & secondary bit in PTE second half, - * clear _PAGE_BUSY and set approriate HPTE slot bit - */ - ld r6,STK_PARAM(R6)(r1) - li r0,_PAGE_BUSY - andc r30,r30,r0 - /* HPTE SUB bit */ - li r0,1 - subfic r5,r25,27 /* Must match bit position in */ - sld r0,r0,r5 /* pgtable.h */ - or r30,r30,r0 - /* hindx */ - sldi r5,r25,2 - sld r3,r3,r5 - li r4,0xf - sld r4,r4,r5 - andc r26,r26,r4 - or r26,r26,r3 - ori r5,r6,PTE_PAGE_HIDX_OFFSET - std r26,0(r5) - lwsync - std r30,0(r6) - li r3, 0 -htab_bail: - ld r25,STK_REG(R25)(r1) - ld r26,STK_REG(R26)(r1) - ld r27,STK_REG(R27)(r1) - ld r28,STK_REG(R28)(r1) - ld r29,STK_REG(R29)(r1) - ld r30,STK_REG(R30)(r1) - ld r31,STK_REG(R31)(r1) - addi r1,r1,STACKFRAMESIZE - ld r0,16(r1) - mtlr r0 - blr - -htab_modify_pte: - /* Keep PP bits in r4 and slot idx from the PTE around in r3 */ - mr r4,r3 - sldi r5,r25,2 - srd r3,r26,r5 - - /* Secondary group ? if yes, get a inverted hash value */ - mr r5,r28 - andi. r0,r3,0x8 /* page secondary ? */ - beq 1f - not r5,r5 -1: andi. r3,r3,0x7 /* extract idx alone */ - - /* Calculate proper slot value for ppc_md.hpte_updatepp */ - and r0,r5,r27 - rldicr r0,r0,3,63-3 /* r0 = (hash & mask) << 3 */ - add r3,r0,r3 /* add slot idx */ - - /* Call ppc_md.hpte_updatepp */ - mr r5,r29 /* vpn */ - li r6,MMU_PAGE_4K /* base page size */ - li r7,MMU_PAGE_4K /* actual page size */ - ld r8,STK_PARAM(R9)(r1) /* segment size */ - ld r9,STK_PARAM(R8)(r1) /* get "flags" param */ -.globl htab_call_hpte_updatepp -htab_call_hpte_updatepp: - bl . /* patched by htab_finish_init() */ - - /* if we failed because typically the HPTE wasn't really here - * we try an insertion. - */ - cmpdi 0,r3,-1 - beq- htab_insert_pte - - /* Clear the BUSY bit and Write out the PTE */ - li r0,_PAGE_BUSY - andc r30,r30,r0 - ld r6,STK_PARAM(R6)(r1) - std r30,0(r6) - li r3,0 - b htab_bail - -htab_wrong_access: - /* Bail out clearing reservation */ - stdcx. r31,0,r6 - li r3,1 - b htab_bail - -htab_pte_insert_failure: - /* Bail out restoring old PTE */ - ld r6,STK_PARAM(R6)(r1) - std r31,0(r6) - li r3,-1 - b htab_bail - -#endif /* CONFIG_PPC_64K_PAGES */ - -#ifdef CONFIG_PPC_64K_PAGES - /***************************************************************************** * * * 64K SW & 64K HW in a 64K segment pages implementation * @@ -994,10 +621,3 @@ ht64_pte_insert_failure: #endif /* CONFIG_PPC_64K_PAGES */ - - -/***************************************************************************** - * * - * Huge pages implementation is in hugetlbpage.c * - * * - *****************************************************************************/ diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 7d4f254a26719..995809911f176 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -653,7 +653,7 @@ static void __init htab_finish_init(void) patch_branch(ht64_call_hpte_updatepp, ppc_function_entry(ppc_md.hpte_updatepp), BRANCH_SET_LINK); -#endif /* CONFIG_PPC_64K_PAGES */ +#else /* !CONFIG_PPC_64K_PAGES */ patch_branch(htab_call_hpte_insert1, ppc_function_entry(ppc_md.hpte_insert), @@ -667,6 +667,8 @@ static void __init htab_finish_init(void) patch_branch(htab_call_hpte_updatepp, ppc_function_entry(ppc_md.hpte_updatepp), BRANCH_SET_LINK); +#endif + } static void __init htab_initialize(void) -- GitLab From 106713a14590cd7b223db000f4f47f7d1d898153 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:44 +0530 Subject: [PATCH 1210/2855] powerpc/mm: Remove the dependency on pte bit position in asm code We should not expect pte bit position in asm code. Simply by moving part of that to C Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 18 ++++------------- arch/powerpc/mm/hash_utils_64.c | 29 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 1a03142a69fd1..3419cbf2ad596 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -1556,29 +1556,19 @@ do_hash_page: lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */ andis. r0,r0,NMI_MASK@h /* (i.e. an irq when soft-disabled) */ bne 77f /* then don't call hash_page now */ - /* - * We need to set the _PAGE_USER bit if MSR_PR is set or if we are - * accessing a userspace segment (even from the kernel). We assume - * kernel addresses always have the high bit set. - */ - rlwinm r4,r4,32-25+9,31-9,31-9 /* DSISR_STORE -> _PAGE_RW */ - rotldi r0,r3,15 /* Move high bit into MSR_PR posn */ - orc r0,r12,r0 /* MSR_PR | ~high_bit */ - rlwimi r4,r0,32-13,30,30 /* becomes _PAGE_USER access bit */ - ori r4,r4,1 /* add _PAGE_PRESENT */ - rlwimi r4,r5,22+2,31-2,31-2 /* Set _PAGE_EXEC if trap is 0x400 */ /* * r3 contains the faulting address - * r4 contains the required access permissions + * r4 msr * r5 contains the trap number * r6 contains dsisr * * at return r3 = 0 for success, 1 for page fault, negative for error */ + mr r4,r12 ld r6,_DSISR(r1) - bl hash_page /* build HPTE if possible */ - cmpdi r3,0 /* see if hash_page succeeded */ + bl __hash_page /* build HPTE if possible */ + cmpdi r3,0 /* see if __hash_page succeeded */ /* Success */ beq fast_exc_return_irq /* Return from exception on success */ diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 995809911f176..30b7648e687a5 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -1206,6 +1206,35 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap, } EXPORT_SYMBOL_GPL(hash_page); +int __hash_page(unsigned long ea, unsigned long msr, unsigned long trap, + unsigned long dsisr) +{ + unsigned long access = _PAGE_PRESENT; + unsigned long flags = 0; + struct mm_struct *mm = current->mm; + + if (REGION_ID(ea) == VMALLOC_REGION_ID) + mm = &init_mm; + + if (dsisr & DSISR_NOHPTE) + flags |= HPTE_NOHPTE_UPDATE; + + if (dsisr & DSISR_ISSTORE) + access |= _PAGE_RW; + /* + * We need to set the _PAGE_USER bit if MSR_PR is set or if we are + * accessing a userspace segment (even from the kernel). We assume + * kernel addresses always have the high bit set. + */ + if ((msr & MSR_PR) || (REGION_ID(ea) == USER_REGION_ID)) + access |= _PAGE_USER; + + if (trap == 0x400) + access |= _PAGE_EXEC; + + return hash_page_mm(mm, ea, access, trap, flags); +} + void hash_preload(struct mm_struct *mm, unsigned long ea, unsigned long access, unsigned long trap) { -- GitLab From bf680d51605662aae5482d87e0e0a54ba6db056b Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:45 +0530 Subject: [PATCH 1211/2855] powerpc/mm: Don't track subpage valid bit in pte_t This free up 11 bits in pte_t. In the later patch we also change the pte_t format so that we can start supporting migration pte at pmd level. We now track 4k subpage valid bit as below If we have _PAGE_COMBO set, we override the _PAGE_F_GIX_SHIFT and _PAGE_F_SECOND. Together we have 4 bits, each of them used to indicate whether any of the 4 4k subpage in that group is valid. ie, [ group 1 bit ] [ group 2 bit ] ..... [ group 4 ] [ subpage 1 - 4] [ subpage 5- 8] ..... [ subpage 13 - 16] We still track each 4k subpage slot number and secondary hash information in the second half of pgtable_t. Removing the subpage tracking have some significant overhead on aim9 and ebizzy benchmark and to support THP with 4K subpage, we do need a pgtable_t of 4096 bytes. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/hash-4k.h | 10 +----- arch/powerpc/include/asm/book3s/64/hash-64k.h | 35 ++++--------------- arch/powerpc/include/asm/book3s/64/hash.h | 10 +++--- arch/powerpc/mm/hash64_64k.c | 34 ++++++++++++++++-- arch/powerpc/mm/hash_low_64.S | 6 +--- arch/powerpc/mm/hugetlbpage-hash64.c | 5 +-- arch/powerpc/mm/pgtable_64.c | 2 +- 7 files changed, 48 insertions(+), 54 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h index 537eacecf6e94..75e8b9326e4b2 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-4k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h @@ -47,17 +47,9 @@ /* Bits to mask out from a PGD to get to the PUD page */ #define PGD_MASKED_BITS 0 -/* PTE bits */ -#define _PAGE_HASHPTE 0x0400 /* software: pte has an associated HPTE */ -#define _PAGE_SECONDARY 0x8000 /* software: HPTE is in secondary group */ -#define _PAGE_GROUP_IX 0x7000 /* software: HPTE index within group */ -#define _PAGE_F_SECOND _PAGE_SECONDARY -#define _PAGE_F_GIX _PAGE_GROUP_IX -#define _PAGE_SPECIAL 0x10000 /* software: special page */ - /* PTE flags to conserve for HPTE identification */ #define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | \ - _PAGE_SECONDARY | _PAGE_GROUP_IX) + _PAGE_F_SECOND | _PAGE_F_GIX) /* shift to put page number into pte */ #define PTE_RPN_SHIFT (17) diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h index ee073822145db..a268416ca4a49 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h @@ -31,33 +31,13 @@ /* Bits to mask out from a PGD/PUD to get to the PMD page */ #define PUD_MASKED_BITS 0x1ff -/* Additional PTE bits (don't change without checking asm in hash_low.S) */ -#define _PAGE_SPECIAL 0x00000400 /* software: special page */ -#define _PAGE_HPTE_SUB 0x0ffff000 /* combo only: sub pages HPTE bits */ -#define _PAGE_HPTE_SUB0 0x08000000 /* combo only: first sub page */ -#define _PAGE_COMBO 0x10000000 /* this is a combo 4k page */ -#define _PAGE_4K_PFN 0x20000000 /* PFN is for a single 4k page */ - -/* For 64K page, we don't have a separate _PAGE_HASHPTE bit. Instead, - * we set that to be the whole sub-bits mask. The C code will only - * test this, so a multi-bit mask will work. For combo pages, this - * is equivalent as effectively, the old _PAGE_HASHPTE was an OR of - * all the sub bits. For real 64k pages, we now have the assembly set - * _PAGE_HPTE_SUB0 in addition to setting the HIDX bits which overlap - * that mask. This is fine as long as the HIDX bits are never set on - * a PTE that isn't hashed, which is the case today. - * - * A little nit is for the huge page C code, which does the hashing - * in C, we need to provide which bit to use. - */ -#define _PAGE_HASHPTE _PAGE_HPTE_SUB - -/* Note the full page bits must be in the same location as for normal - * 4k pages as the same assembly will be used to insert 64K pages - * whether the kernel has CONFIG_PPC_64K_PAGES or not +#define _PAGE_COMBO 0x00020000 /* this is a combo 4k page */ +#define _PAGE_4K_PFN 0x00040000 /* PFN is for a single 4k page */ +/* + * Used to track subpage group valid if _PAGE_COMBO is set + * This overloads _PAGE_F_GIX and _PAGE_F_SECOND */ -#define _PAGE_F_SECOND 0x00008000 /* full page: hidx bits */ -#define _PAGE_F_GIX 0x00007000 /* full page: hidx bits */ +#define _PAGE_COMBO_VALID (_PAGE_F_GIX | _PAGE_F_SECOND) /* PTE flags to conserve for HPTE identification */ #define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | _PAGE_COMBO) @@ -103,8 +83,7 @@ static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index) } #define __rpte_to_pte(r) ((r).pte) -#define __rpte_sub_valid(rpte, index) \ - (pte_val(rpte.pte) & (_PAGE_HPTE_SUB0 >> (index))) +extern bool __rpte_sub_valid(real_pte_t rpte, unsigned long index); /* * Trick: we set __end to va + 64k, which happens works for * a 16M page as well as we want only one iteration diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 48237e66e8239..2f2034621a69b 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -81,7 +81,12 @@ #define _PAGE_DIRTY 0x0080 /* C: page changed */ #define _PAGE_ACCESSED 0x0100 /* R: page referenced */ #define _PAGE_RW 0x0200 /* software: user write access allowed */ +#define _PAGE_HASHPTE 0x0400 /* software: pte has an associated HPTE */ #define _PAGE_BUSY 0x0800 /* software: PTE & hash are busy */ +#define _PAGE_F_GIX 0x7000 /* full page: hidx bits */ +#define _PAGE_F_GIX_SHIFT 12 +#define _PAGE_F_SECOND 0x8000 /* Whether to use secondary hash or not */ +#define _PAGE_SPECIAL 0x10000 /* software: special page */ /* No separate kernel read-only */ #define _PAGE_KERNEL_RW (_PAGE_RW | _PAGE_DIRTY) /* user access blocked by key */ @@ -210,11 +215,6 @@ #define PMD_BAD_BITS (PTE_TABLE_SIZE-1) #define PUD_BAD_BITS (PMD_TABLE_SIZE-1) -/* - * We save the slot number & secondary bit in the second half of the - * PTE page. We use the 8 bytes per each pte entry. - */ -#define PTE_PAGE_HIDX_OFFSET (PTRS_PER_PTE * 8) #ifndef __ASSEMBLY__ #define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \ diff --git a/arch/powerpc/mm/hash64_64k.c b/arch/powerpc/mm/hash64_64k.c index 9ffeae2cbb57d..f1b86ba63430d 100644 --- a/arch/powerpc/mm/hash64_64k.c +++ b/arch/powerpc/mm/hash64_64k.c @@ -15,6 +15,35 @@ #include #include #include +/* + * index from 0 - 15 + */ +bool __rpte_sub_valid(real_pte_t rpte, unsigned long index) +{ + unsigned long g_idx; + unsigned long ptev = pte_val(rpte.pte); + + g_idx = (ptev & _PAGE_COMBO_VALID) >> _PAGE_F_GIX_SHIFT; + index = index >> 2; + if (g_idx & (0x1 << index)) + return true; + else + return false; +} +/* + * index from 0 - 15 + */ +static unsigned long mark_subptegroup_valid(unsigned long ptev, unsigned long index) +{ + unsigned long g_idx; + + if (!(ptev & _PAGE_COMBO)) + return ptev; + index = index >> 2; + g_idx = 0x1 << index; + + return ptev | (g_idx << _PAGE_F_GIX_SHIFT); +} int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, pte_t *ptep, unsigned long trap, unsigned long flags, @@ -102,7 +131,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, */ if (!(old_pte & _PAGE_COMBO)) { flush_hash_page(vpn, rpte, MMU_PAGE_64K, ssize, flags); - old_pte &= ~_PAGE_HPTE_SUB; + old_pte &= ~_PAGE_HASHPTE | _PAGE_F_GIX | _PAGE_F_SECOND; goto htab_insert_hpte; } /* @@ -192,7 +221,8 @@ repeat: /* __real_pte use pte_val() any idea why ? FIXME!! */ rpte.hidx &= ~(0xfUL << (subpg_index << 2)); *hidxp = rpte.hidx | (slot << (subpg_index << 2)); - new_pte |= (_PAGE_HPTE_SUB0 >> subpg_index); + new_pte = mark_subptegroup_valid(new_pte, subpg_index); + new_pte |= _PAGE_HASHPTE; /* * check __real_pte for details on matching smp_rmb() */ diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S index 6b4d4c1d0628c..359839a57f26f 100644 --- a/arch/powerpc/mm/hash_low_64.S +++ b/arch/powerpc/mm/hash_low_64.S @@ -285,7 +285,7 @@ htab_modify_pte: /* Secondary group ? if yes, get a inverted hash value */ mr r5,r28 - andi. r0,r31,_PAGE_SECONDARY + andi. r0,r31,_PAGE_F_SECOND beq 1f not r5,r5 1: @@ -473,11 +473,7 @@ ht64_insert_pte: lis r0,_PAGE_HPTEFLAGS@h ori r0,r0,_PAGE_HPTEFLAGS@l andc r30,r30,r0 -#ifdef CONFIG_PPC_64K_PAGES - oris r30,r30,_PAGE_HPTE_SUB0@h -#else ori r30,r30,_PAGE_HASHPTE -#endif /* Phyical address in r5 */ rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT sldi r5,r5,PAGE_SHIFT diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c index d94b1af53a936..7584e84455127 100644 --- a/arch/powerpc/mm/hugetlbpage-hash64.c +++ b/arch/powerpc/mm/hugetlbpage-hash64.c @@ -91,11 +91,8 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT; /* clear HPTE slot informations in new PTE */ -#ifdef CONFIG_PPC_64K_PAGES - new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HPTE_SUB0; -#else new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HASHPTE; -#endif + /* Add in WIMG bits */ rflags |= (new_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE | _PAGE_COHERENT | _PAGE_GUARDED)); diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index d692ae31cfc76..3967e3cce03ee 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -625,7 +625,7 @@ void pmdp_splitting_flush(struct vm_area_struct *vma, "1: ldarx %0,0,%3\n\ andi. %1,%0,%6\n\ bne- 1b \n\ - ori %1,%0,%4 \n\ + oris %1,%0,%4@h \n\ stdcx. %1,0,%3 \n\ bne- 1b" : "=&r" (old), "=&r" (tmp), "=m" (*pmdp) -- GitLab From 506b863c68cd6e720037f1548e101932af3bb006 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:46 +0530 Subject: [PATCH 1212/2855] powerpc/mm: Remove pte_val usage for the second half of pgtable_t Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/hash-64k.h | 4 +++- arch/powerpc/mm/hash64_64k.c | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h index a268416ca4a49..9fca7fae434bc 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h @@ -61,6 +61,7 @@ static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep) { real_pte_t rpte; + unsigned long *hidxp; rpte.pte = pte; rpte.hidx = 0; @@ -70,7 +71,8 @@ static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep) * check. The store side ordering is done in __hash_page_4K */ smp_rmb(); - rpte.hidx = pte_val(*((ptep) + PTRS_PER_PTE)); + hidxp = (unsigned long *)(ptep + PTRS_PER_PTE); + rpte.hidx = *hidxp; } return rpte; } diff --git a/arch/powerpc/mm/hash64_64k.c b/arch/powerpc/mm/hash64_64k.c index f1b86ba63430d..8f7328075f04d 100644 --- a/arch/powerpc/mm/hash64_64k.c +++ b/arch/powerpc/mm/hash64_64k.c @@ -218,7 +218,6 @@ repeat: * nobody is undating hidx. */ hidxp = (unsigned long *)(ptep + PTRS_PER_PTE); - /* __real_pte use pte_val() any idea why ? FIXME!! */ rpte.hidx &= ~(0xfUL << (subpg_index << 2)); *hidxp = rpte.hidx | (slot << (subpg_index << 2)); new_pte = mark_subptegroup_valid(new_pte, subpg_index); -- GitLab From 227fdbee5a963f4358bb1edd78a6f654574a4991 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:47 +0530 Subject: [PATCH 1213/2855] powerpc/mm: Increase the width of #define No real change, only style changes Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/hash.h | 26 +++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 2f2034621a69b..e4ea9d73a5419 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -69,23 +69,23 @@ * We could create separate kernel read-only if we used the 3 PP bits * combinations that newer processors provide but we currently don't. */ -#define _PAGE_PRESENT 0x0001 /* software: pte contains a translation */ -#define _PAGE_USER 0x0002 /* matches one of the PP bits */ +#define _PAGE_PRESENT 0x00001 /* software: pte contains a translation */ +#define _PAGE_USER 0x00002 /* matches one of the PP bits */ #define _PAGE_BIT_SWAP_TYPE 2 -#define _PAGE_EXEC 0x0004 /* No execute on POWER4 and newer (we invert) */ -#define _PAGE_GUARDED 0x0008 +#define _PAGE_EXEC 0x00004 /* No execute on POWER4 and newer (we invert) */ +#define _PAGE_GUARDED 0x00008 /* We can derive Memory coherence from _PAGE_NO_CACHE */ #define _PAGE_COHERENT 0x0 -#define _PAGE_NO_CACHE 0x0020 /* I: cache inhibit */ -#define _PAGE_WRITETHRU 0x0040 /* W: cache write-through */ -#define _PAGE_DIRTY 0x0080 /* C: page changed */ -#define _PAGE_ACCESSED 0x0100 /* R: page referenced */ -#define _PAGE_RW 0x0200 /* software: user write access allowed */ -#define _PAGE_HASHPTE 0x0400 /* software: pte has an associated HPTE */ -#define _PAGE_BUSY 0x0800 /* software: PTE & hash are busy */ -#define _PAGE_F_GIX 0x7000 /* full page: hidx bits */ +#define _PAGE_NO_CACHE 0x00020 /* I: cache inhibit */ +#define _PAGE_WRITETHRU 0x00040 /* W: cache write-through */ +#define _PAGE_DIRTY 0x00080 /* C: page changed */ +#define _PAGE_ACCESSED 0x00100 /* R: page referenced */ +#define _PAGE_RW 0x00200 /* software: user write access allowed */ +#define _PAGE_HASHPTE 0x00400 /* software: pte has an associated HPTE */ +#define _PAGE_BUSY 0x00800 /* software: PTE & hash are busy */ +#define _PAGE_F_GIX 0x07000 /* full page: hidx bits */ #define _PAGE_F_GIX_SHIFT 12 -#define _PAGE_F_SECOND 0x8000 /* Whether to use secondary hash or not */ +#define _PAGE_F_SECOND 0x08000 /* Whether to use secondary hash or not */ #define _PAGE_SPECIAL 0x10000 /* software: special page */ /* No separate kernel read-only */ -- GitLab From 89ff725051d177556b23d80f2a30f880a657a6c1 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:48 +0530 Subject: [PATCH 1214/2855] powerpc/mm: Convert __hash_page_64K to C Convert from asm to C Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/hash-64k.h | 3 +- arch/powerpc/mm/hash64_64k.c | 130 ++++++++ arch/powerpc/mm/hash_low_64.S | 290 +----------------- arch/powerpc/mm/hash_utils_64.c | 19 +- 4 files changed, 134 insertions(+), 308 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h index 9fca7fae434bc..46b5d0ab11de7 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h @@ -40,7 +40,8 @@ #define _PAGE_COMBO_VALID (_PAGE_F_GIX | _PAGE_F_SECOND) /* PTE flags to conserve for HPTE identification */ -#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | _PAGE_COMBO) +#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_F_SECOND | \ + _PAGE_F_GIX | _PAGE_HASHPTE | _PAGE_COMBO) /* Shift to put page number into pte. * diff --git a/arch/powerpc/mm/hash64_64k.c b/arch/powerpc/mm/hash64_64k.c index 8f7328075f04d..fc0898eb309d8 100644 --- a/arch/powerpc/mm/hash64_64k.c +++ b/arch/powerpc/mm/hash64_64k.c @@ -229,3 +229,133 @@ repeat: *ptep = __pte(new_pte & ~_PAGE_BUSY); return 0; } + +int __hash_page_64K(unsigned long ea, unsigned long access, + unsigned long vsid, pte_t *ptep, unsigned long trap, + unsigned long flags, int ssize) +{ + + unsigned long hpte_group; + unsigned long rflags, pa; + unsigned long old_pte, new_pte; + unsigned long vpn, hash, slot; + unsigned long shift = mmu_psize_defs[MMU_PAGE_64K].shift; + + /* + * atomically mark the linux large page PTE busy and dirty + */ + do { + pte_t pte = READ_ONCE(*ptep); + + old_pte = pte_val(pte); + /* If PTE busy, retry the access */ + if (unlikely(old_pte & _PAGE_BUSY)) + return 0; + /* If PTE permissions don't match, take page fault */ + if (unlikely(access & ~old_pte)) + return 1; + /* + * Check if PTE has the cache-inhibit bit set + * If so, bail out and refault as a 4k page + */ + if (!mmu_has_feature(MMU_FTR_CI_LARGE_PAGE) && + unlikely(old_pte & _PAGE_NO_CACHE)) + return 0; + /* + * Try to lock the PTE, add ACCESSED and DIRTY if it was + * a write access. Since this is 4K insert of 64K page size + * also add _PAGE_COMBO + */ + new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED; + if (access & _PAGE_RW) + new_pte |= _PAGE_DIRTY; + } while (old_pte != __cmpxchg_u64((unsigned long *)ptep, + old_pte, new_pte)); + /* + * PP bits. _PAGE_USER is already PP bit 0x2, so we only + * need to add in 0x1 if it's a read-only user page + */ + rflags = new_pte & _PAGE_USER; + if ((new_pte & _PAGE_USER) && !((new_pte & _PAGE_RW) && + (new_pte & _PAGE_DIRTY))) + rflags |= 0x1; + /* + * _PAGE_EXEC -> HW_NO_EXEC since it's inverted + */ + rflags |= ((new_pte & _PAGE_EXEC) ? 0 : HPTE_R_N); + /* + * Always add C and Memory coherence bit + */ + rflags |= HPTE_R_C | HPTE_R_M; + /* + * Add in WIMG bits + */ + rflags |= (new_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE | + _PAGE_COHERENT | _PAGE_GUARDED)); + + if (!cpu_has_feature(CPU_FTR_NOEXECUTE) && + !cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) + rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap); + + vpn = hpt_vpn(ea, vsid, ssize); + if (unlikely(old_pte & _PAGE_HASHPTE)) { + /* + * There MIGHT be an HPTE for this pte + */ + hash = hpt_hash(vpn, shift, ssize); + if (old_pte & _PAGE_F_SECOND) + hash = ~hash; + slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; + slot += (old_pte & _PAGE_F_GIX) >> _PAGE_F_GIX_SHIFT; + + if (ppc_md.hpte_updatepp(slot, rflags, vpn, MMU_PAGE_64K, + MMU_PAGE_64K, ssize, flags) == -1) + old_pte &= ~_PAGE_HPTEFLAGS; + } + + if (likely(!(old_pte & _PAGE_HASHPTE))) { + + pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT; + hash = hpt_hash(vpn, shift, ssize); + +repeat: + hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL; + + /* Insert into the hash table, primary slot */ + slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, 0, + MMU_PAGE_64K, MMU_PAGE_64K, ssize); + /* + * Primary is full, try the secondary + */ + if (unlikely(slot == -1)) { + hpte_group = ((~hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL; + slot = ppc_md.hpte_insert(hpte_group, vpn, pa, + rflags, HPTE_V_SECONDARY, + MMU_PAGE_64K, MMU_PAGE_64K, ssize); + if (slot == -1) { + if (mftb() & 0x1) + hpte_group = ((hash & htab_hash_mask) * + HPTES_PER_GROUP) & ~0x7UL; + ppc_md.hpte_remove(hpte_group); + /* + * FIXME!! Should be try the group from which we removed ? + */ + goto repeat; + } + } + /* + * Hypervisor failure. Restore old pmd and return -1 + * similar to __hash_page_* + */ + if (unlikely(slot == -2)) { + *ptep = __pte(old_pte); + hash_failure_debug(ea, access, vsid, trap, ssize, + MMU_PAGE_64K, MMU_PAGE_64K, old_pte); + return -1; + } + new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HASHPTE; + new_pte |= (slot << _PAGE_F_GIX_SHIFT) & (_PAGE_F_SECOND | _PAGE_F_GIX); + } + *ptep = __pte(new_pte & ~_PAGE_BUSY); + return 0; +} diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S index 359839a57f26f..f7d49cf0ccb7d 100644 --- a/arch/powerpc/mm/hash_low_64.S +++ b/arch/powerpc/mm/hash_low_64.S @@ -328,292 +328,4 @@ htab_pte_insert_failure: li r3,-1 b htab_bail -#else /* CONFIG_PPC_64K_PAGES */ - -/***************************************************************************** - * * - * 64K SW & 64K HW in a 64K segment pages implementation * - * * - *****************************************************************************/ - -_GLOBAL(__hash_page_64K) - mflr r0 - std r0,16(r1) - stdu r1,-STACKFRAMESIZE(r1) - /* Save all params that we need after a function call */ - std r6,STK_PARAM(R6)(r1) - std r8,STK_PARAM(R8)(r1) - std r9,STK_PARAM(R9)(r1) - - /* Save non-volatile registers. - * r31 will hold "old PTE" - * r30 is "new PTE" - * r29 is vpn - * r28 is a hash value - * r27 is hashtab mask (maybe dynamic patched instead ?) - */ - std r27,STK_REG(R27)(r1) - std r28,STK_REG(R28)(r1) - std r29,STK_REG(R29)(r1) - std r30,STK_REG(R30)(r1) - std r31,STK_REG(R31)(r1) - - /* Step 1: - * - * Check permissions, atomically mark the linux PTE busy - * and hashed. - */ -1: - ldarx r31,0,r6 - /* Check access rights (access & ~(pte_val(*ptep))) */ - andc. r0,r4,r31 - bne- ht64_wrong_access - /* Check if PTE is busy */ - andi. r0,r31,_PAGE_BUSY - /* If so, just bail out and refault if needed. Someone else - * is changing this PTE anyway and might hash it. - */ - bne- ht64_bail_ok -BEGIN_FTR_SECTION - /* Check if PTE has the cache-inhibit bit set */ - andi. r0,r31,_PAGE_NO_CACHE - /* If so, bail out and refault as a 4k page */ - bne- ht64_bail_ok -END_MMU_FTR_SECTION_IFCLR(MMU_FTR_CI_LARGE_PAGE) - /* Prepare new PTE value (turn access RW into DIRTY, then - * add BUSY and ACCESSED) - */ - rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */ - or r30,r30,r31 - ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED - /* Write the linux PTE atomically (setting busy) */ - stdcx. r30,0,r6 - bne- 1b - isync - - /* Step 2: - * - * Insert/Update the HPTE in the hash table. At this point, - * r4 (access) is re-useable, we use it for the new HPTE flags - */ - -BEGIN_FTR_SECTION - cmpdi r9,0 /* check segment size */ - bne 3f -END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) - /* Calc vpn and put it in r29 */ - sldi r29,r5,SID_SHIFT - VPN_SHIFT - rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT) - or r29,r28,r29 - - /* Calculate hash value for primary slot and store it in r28 - * r3 = va, r5 = vsid - * r0 = (va >> 16) & ((1ul << (28 - 16)) -1) - */ - rldicl r0,r3,64-16,52 - xor r28,r5,r0 /* hash */ - b 4f - -3: /* Calc vpn and put it in r29 */ - sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT - rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT) - or r29,r28,r29 - /* - * calculate hash value for primary slot and - * store it in r28 for 1T segment - * r3 = va, r5 = vsid - */ - sldi r28,r5,25 /* vsid << 25 */ - /* r0 = (va >> 16) & ((1ul << (40 - 16)) -1) */ - rldicl r0,r3,64-16,40 - xor r28,r28,r5 /* vsid ^ ( vsid << 25) */ - xor r28,r28,r0 /* hash */ - - /* Convert linux PTE bits into HW equivalents */ -4: andi. r3,r30,0x1fe /* Get basic set of flags */ - xori r3,r3,HPTE_R_N /* _PAGE_EXEC -> NOEXEC */ - rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */ - rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY -> _PAGE_USER (r4) */ - and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/ - andc r0,r30,r0 /* r0 = pte & ~r0 */ - rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */ - /* - * Always add "C" bit for perf. Memory coherence is always enabled - */ - ori r3,r3,HPTE_R_C | HPTE_R_M - - /* We eventually do the icache sync here (maybe inline that - * code rather than call a C function...) - */ -BEGIN_FTR_SECTION - mr r4,r30 - mr r5,r7 - bl hash_page_do_lazy_icache -END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) - - /* At this point, r3 contains new PP bits, save them in - * place of "access" in the param area (sic) - */ - std r3,STK_PARAM(R4)(r1) - - /* Get htab_hash_mask */ - ld r4,htab_hash_mask@got(2) - ld r27,0(r4) /* htab_hash_mask -> r27 */ - - /* Check if we may already be in the hashtable, in this case, we - * go to out-of-line code to try to modify the HPTE - */ - rldicl. r0,r31,64-12,48 - bne ht64_modify_pte - -ht64_insert_pte: - /* Clear hpte bits in new pte (we also clear BUSY btw) and - * add _PAGE_HPTE_SUB0 - */ - lis r0,_PAGE_HPTEFLAGS@h - ori r0,r0,_PAGE_HPTEFLAGS@l - andc r30,r30,r0 - ori r30,r30,_PAGE_HASHPTE - /* Phyical address in r5 */ - rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT - sldi r5,r5,PAGE_SHIFT - - /* Calculate primary group hash */ - and r0,r28,r27 - rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ - - /* Call ppc_md.hpte_insert */ - ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ - mr r4,r29 /* Retrieve vpn */ - li r7,0 /* !bolted, !secondary */ - li r8,MMU_PAGE_64K - li r9,MMU_PAGE_64K /* actual page size */ - ld r10,STK_PARAM(R9)(r1) /* segment size */ -.globl ht64_call_hpte_insert1 -ht64_call_hpte_insert1: - bl . /* patched by htab_finish_init() */ - cmpdi 0,r3,0 - bge ht64_pte_insert_ok /* Insertion successful */ - cmpdi 0,r3,-2 /* Critical failure */ - beq- ht64_pte_insert_failure - - /* Now try secondary slot */ - - /* Phyical address in r5 */ - rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT - sldi r5,r5,PAGE_SHIFT - - /* Calculate secondary group hash */ - andc r0,r27,r28 - rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */ - - /* Call ppc_md.hpte_insert */ - ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ - mr r4,r29 /* Retrieve vpn */ - li r7,HPTE_V_SECONDARY /* !bolted, secondary */ - li r8,MMU_PAGE_64K - li r9,MMU_PAGE_64K /* actual page size */ - ld r10,STK_PARAM(R9)(r1) /* segment size */ -.globl ht64_call_hpte_insert2 -ht64_call_hpte_insert2: - bl . /* patched by htab_finish_init() */ - cmpdi 0,r3,0 - bge+ ht64_pte_insert_ok /* Insertion successful */ - cmpdi 0,r3,-2 /* Critical failure */ - beq- ht64_pte_insert_failure - - /* Both are full, we need to evict something */ - mftb r0 - /* Pick a random group based on TB */ - andi. r0,r0,1 - mr r5,r28 - bne 2f - not r5,r5 -2: and r0,r5,r27 - rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ - /* Call ppc_md.hpte_remove */ -.globl ht64_call_hpte_remove -ht64_call_hpte_remove: - bl . /* patched by htab_finish_init() */ - - /* Try all again */ - b ht64_insert_pte - -ht64_bail_ok: - li r3,0 - b ht64_bail - -ht64_pte_insert_ok: - /* Insert slot number & secondary bit in PTE */ - rldimi r30,r3,12,63-15 - - /* Write out the PTE with a normal write - * (maybe add eieio may be good still ?) - */ -ht64_write_out_pte: - ld r6,STK_PARAM(R6)(r1) - std r30,0(r6) - li r3, 0 -ht64_bail: - ld r27,STK_REG(R27)(r1) - ld r28,STK_REG(R28)(r1) - ld r29,STK_REG(R29)(r1) - ld r30,STK_REG(R30)(r1) - ld r31,STK_REG(R31)(r1) - addi r1,r1,STACKFRAMESIZE - ld r0,16(r1) - mtlr r0 - blr - -ht64_modify_pte: - /* Keep PP bits in r4 and slot idx from the PTE around in r3 */ - mr r4,r3 - rlwinm r3,r31,32-12,29,31 - - /* Secondary group ? if yes, get a inverted hash value */ - mr r5,r28 - andi. r0,r31,_PAGE_F_SECOND - beq 1f - not r5,r5 -1: - /* Calculate proper slot value for ppc_md.hpte_updatepp */ - and r0,r5,r27 - rldicr r0,r0,3,63-3 /* r0 = (hash & mask) << 3 */ - add r3,r0,r3 /* add slot idx */ - - /* Call ppc_md.hpte_updatepp */ - mr r5,r29 /* vpn */ - li r6,MMU_PAGE_64K /* base page size */ - li r7,MMU_PAGE_64K /* actual page size */ - ld r8,STK_PARAM(R9)(r1) /* segment size */ - ld r9,STK_PARAM(R8)(r1) /* get "flags" param */ -.globl ht64_call_hpte_updatepp -ht64_call_hpte_updatepp: - bl . /* patched by htab_finish_init() */ - - /* if we failed because typically the HPTE wasn't really here - * we try an insertion. - */ - cmpdi 0,r3,-1 - beq- ht64_insert_pte - - /* Clear the BUSY bit and Write out the PTE */ - li r0,_PAGE_BUSY - andc r30,r30,r0 - b ht64_write_out_pte - -ht64_wrong_access: - /* Bail out clearing reservation */ - stdcx. r31,0,r6 - li r3,1 - b ht64_bail - -ht64_pte_insert_failure: - /* Bail out restoring old PTE */ - ld r6,STK_PARAM(R6)(r1) - std r31,0(r6) - li r3,-1 - b ht64_bail - - -#endif /* CONFIG_PPC_64K_PAGES */ +#endif diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 30b7648e687a5..fb6e15c607a64 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -633,28 +633,11 @@ extern u32 htab_call_hpte_insert1[]; extern u32 htab_call_hpte_insert2[]; extern u32 htab_call_hpte_remove[]; extern u32 htab_call_hpte_updatepp[]; -extern u32 ht64_call_hpte_insert1[]; -extern u32 ht64_call_hpte_insert2[]; -extern u32 ht64_call_hpte_remove[]; -extern u32 ht64_call_hpte_updatepp[]; static void __init htab_finish_init(void) { -#ifdef CONFIG_PPC_64K_PAGES - patch_branch(ht64_call_hpte_insert1, - ppc_function_entry(ppc_md.hpte_insert), - BRANCH_SET_LINK); - patch_branch(ht64_call_hpte_insert2, - ppc_function_entry(ppc_md.hpte_insert), - BRANCH_SET_LINK); - patch_branch(ht64_call_hpte_remove, - ppc_function_entry(ppc_md.hpte_remove), - BRANCH_SET_LINK); - patch_branch(ht64_call_hpte_updatepp, - ppc_function_entry(ppc_md.hpte_updatepp), - BRANCH_SET_LINK); -#else /* !CONFIG_PPC_64K_PAGES */ +#ifdef CONFIG_PPC_4K_PAGES patch_branch(htab_call_hpte_insert1, ppc_function_entry(ppc_md.hpte_insert), BRANCH_SET_LINK); -- GitLab From a43c0eb8364c022725df586e91dd753633374d66 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:49 +0530 Subject: [PATCH 1215/2855] powerpc/mm: Convert 4k insert from asm to C This is similar to 64K insert. May be we want to consolidate Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/mm/Makefile | 6 +- arch/powerpc/mm/hash64_4k.c | 139 ++++++++++++++ arch/powerpc/mm/hash_low_64.S | 331 -------------------------------- arch/powerpc/mm/hash_utils_64.c | 26 --- 4 files changed, 142 insertions(+), 360 deletions(-) create mode 100644 arch/powerpc/mm/hash64_4k.c delete mode 100644 arch/powerpc/mm/hash_low_64.S diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index f80ad1a76cc8f..1ffeda85c0861 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile @@ -14,11 +14,11 @@ obj-$(CONFIG_PPC_MMU_NOHASH) += mmu_context_nohash.o tlb_nohash.o \ obj-$(CONFIG_PPC_BOOK3E) += tlb_low_$(CONFIG_WORD_SIZE)e.o hash64-$(CONFIG_PPC_NATIVE) := hash_native_64.o obj-$(CONFIG_PPC_STD_MMU_64) += hash_utils_64.o slb_low.o slb.o $(hash64-y) -obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o -obj-$(CONFIG_PPC_STD_MMU) += hash_low_$(CONFIG_WORD_SIZE).o \ - tlb_hash$(CONFIG_WORD_SIZE).o \ +obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o hash_low_32.o +obj-$(CONFIG_PPC_STD_MMU) += tlb_hash$(CONFIG_WORD_SIZE).o \ mmu_context_hash$(CONFIG_WORD_SIZE).o ifeq ($(CONFIG_PPC_STD_MMU_64),y) +obj-$(CONFIG_PPC_4K_PAGES) += hash64_4k.o obj-$(CONFIG_PPC_64K_PAGES) += hash64_64k.o endif obj-$(CONFIG_PPC_ICSWX) += icswx.o diff --git a/arch/powerpc/mm/hash64_4k.c b/arch/powerpc/mm/hash64_4k.c new file mode 100644 index 0000000000000..3b49c6f187410 --- /dev/null +++ b/arch/powerpc/mm/hash64_4k.c @@ -0,0 +1,139 @@ +/* + * Copyright IBM Corporation, 2015 + * Author Aneesh Kumar K.V + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#include +#include +#include + +int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, + pte_t *ptep, unsigned long trap, unsigned long flags, + int ssize, int subpg_prot) +{ + unsigned long hpte_group; + unsigned long rflags, pa; + unsigned long old_pte, new_pte; + unsigned long vpn, hash, slot; + unsigned long shift = mmu_psize_defs[MMU_PAGE_4K].shift; + + /* + * atomically mark the linux large page PTE busy and dirty + */ + do { + pte_t pte = READ_ONCE(*ptep); + + old_pte = pte_val(pte); + /* If PTE busy, retry the access */ + if (unlikely(old_pte & _PAGE_BUSY)) + return 0; + /* If PTE permissions don't match, take page fault */ + if (unlikely(access & ~old_pte)) + return 1; + /* + * Try to lock the PTE, add ACCESSED and DIRTY if it was + * a write access. Since this is 4K insert of 64K page size + * also add _PAGE_COMBO + */ + new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE; + if (access & _PAGE_RW) + new_pte |= _PAGE_DIRTY; + } while (old_pte != __cmpxchg_u64((unsigned long *)ptep, + old_pte, new_pte)); + /* + * PP bits. _PAGE_USER is already PP bit 0x2, so we only + * need to add in 0x1 if it's a read-only user page + */ + rflags = new_pte & _PAGE_USER; + if ((new_pte & _PAGE_USER) && !((new_pte & _PAGE_RW) && + (new_pte & _PAGE_DIRTY))) + rflags |= 0x1; + /* + * _PAGE_EXEC -> HW_NO_EXEC since it's inverted + */ + rflags |= ((new_pte & _PAGE_EXEC) ? 0 : HPTE_R_N); + /* + * Always add C and Memory coherence bit + */ + rflags |= HPTE_R_C | HPTE_R_M; + /* + * Add in WIMG bits + */ + rflags |= (new_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE | + _PAGE_COHERENT | _PAGE_GUARDED)); + + if (!cpu_has_feature(CPU_FTR_NOEXECUTE) && + !cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) + rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap); + + vpn = hpt_vpn(ea, vsid, ssize); + if (unlikely(old_pte & _PAGE_HASHPTE)) { + /* + * There MIGHT be an HPTE for this pte + */ + hash = hpt_hash(vpn, shift, ssize); + if (old_pte & _PAGE_F_SECOND) + hash = ~hash; + slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; + slot += (old_pte & _PAGE_F_GIX) >> _PAGE_F_GIX_SHIFT; + + if (ppc_md.hpte_updatepp(slot, rflags, vpn, MMU_PAGE_4K, + MMU_PAGE_4K, ssize, flags) == -1) + old_pte &= ~_PAGE_HPTEFLAGS; + } + + if (likely(!(old_pte & _PAGE_HASHPTE))) { + + pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT; + hash = hpt_hash(vpn, shift, ssize); + +repeat: + hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL; + + /* Insert into the hash table, primary slot */ + slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, 0, + MMU_PAGE_4K, MMU_PAGE_4K, ssize); + /* + * Primary is full, try the secondary + */ + if (unlikely(slot == -1)) { + hpte_group = ((~hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL; + slot = ppc_md.hpte_insert(hpte_group, vpn, pa, + rflags, HPTE_V_SECONDARY, + MMU_PAGE_4K, MMU_PAGE_4K, ssize); + if (slot == -1) { + if (mftb() & 0x1) + hpte_group = ((hash & htab_hash_mask) * + HPTES_PER_GROUP) & ~0x7UL; + ppc_md.hpte_remove(hpte_group); + /* + * FIXME!! Should be try the group from which we removed ? + */ + goto repeat; + } + } + /* + * Hypervisor failure. Restore old pmd and return -1 + * similar to __hash_page_* + */ + if (unlikely(slot == -2)) { + *ptep = __pte(old_pte); + hash_failure_debug(ea, access, vsid, trap, ssize, + MMU_PAGE_4K, MMU_PAGE_4K, old_pte); + return -1; + } + new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HASHPTE; + new_pte |= (slot << _PAGE_F_GIX_SHIFT) & (_PAGE_F_SECOND | _PAGE_F_GIX); + } + *ptep = __pte(new_pte & ~_PAGE_BUSY); + return 0; +} diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S deleted file mode 100644 index f7d49cf0ccb7d..0000000000000 --- a/arch/powerpc/mm/hash_low_64.S +++ /dev/null @@ -1,331 +0,0 @@ -/* - * ppc64 MMU hashtable management routines - * - * (c) Copyright IBM Corp. 2003, 2005 - * - * Maintained by: Benjamin Herrenschmidt - * - * - * This file is covered by the GNU Public Licence v2 as - * described in the kernel's COPYING file. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - - .text - -/* - * Stackframe: - * - * +-> Back chain (SP + 256) - * | General register save area (SP + 112) - * | Parameter save area (SP + 48) - * | TOC save area (SP + 40) - * | link editor doubleword (SP + 32) - * | compiler doubleword (SP + 24) - * | LR save area (SP + 16) - * | CR save area (SP + 8) - * SP ---> +-- Back chain (SP + 0) - */ - -#ifndef CONFIG_PPC_64K_PAGES - -/***************************************************************************** - * * - * 4K SW & 4K HW pages implementation * - * * - *****************************************************************************/ - - -/* - * _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, - * pte_t *ptep, unsigned long trap, unsigned long flags, - * int ssize) - * - * Adds a 4K page to the hash table in a segment of 4K pages only - */ - -_GLOBAL(__hash_page_4K) - mflr r0 - std r0,16(r1) - stdu r1,-STACKFRAMESIZE(r1) - /* Save all params that we need after a function call */ - std r6,STK_PARAM(R6)(r1) - std r8,STK_PARAM(R8)(r1) - std r9,STK_PARAM(R9)(r1) - - /* Save non-volatile registers. - * r31 will hold "old PTE" - * r30 is "new PTE" - * r29 is vpn - * r28 is a hash value - * r27 is hashtab mask (maybe dynamic patched instead ?) - */ - std r27,STK_REG(R27)(r1) - std r28,STK_REG(R28)(r1) - std r29,STK_REG(R29)(r1) - std r30,STK_REG(R30)(r1) - std r31,STK_REG(R31)(r1) - - /* Step 1: - * - * Check permissions, atomically mark the linux PTE busy - * and hashed. - */ -1: - ldarx r31,0,r6 - /* Check access rights (access & ~(pte_val(*ptep))) */ - andc. r0,r4,r31 - bne- htab_wrong_access - /* Check if PTE is busy */ - andi. r0,r31,_PAGE_BUSY - /* If so, just bail out and refault if needed. Someone else - * is changing this PTE anyway and might hash it. - */ - bne- htab_bail_ok - - /* Prepare new PTE value (turn access RW into DIRTY, then - * add BUSY,HASHPTE and ACCESSED) - */ - rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */ - or r30,r30,r31 - ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE - /* Write the linux PTE atomically (setting busy) */ - stdcx. r30,0,r6 - bne- 1b - isync - - /* Step 2: - * - * Insert/Update the HPTE in the hash table. At this point, - * r4 (access) is re-useable, we use it for the new HPTE flags - */ - -BEGIN_FTR_SECTION - cmpdi r9,0 /* check segment size */ - bne 3f -END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) - /* Calc vpn and put it in r29 */ - sldi r29,r5,SID_SHIFT - VPN_SHIFT - rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT) - or r29,r28,r29 - /* - * Calculate hash value for primary slot and store it in r28 - * r3 = va, r5 = vsid - * r0 = (va >> 12) & ((1ul << (28 - 12)) -1) - */ - rldicl r0,r3,64-12,48 - xor r28,r5,r0 /* hash */ - b 4f - -3: /* Calc vpn and put it in r29 */ - sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT - rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT) - or r29,r28,r29 - - /* - * calculate hash value for primary slot and - * store it in r28 for 1T segment - * r3 = va, r5 = vsid - */ - sldi r28,r5,25 /* vsid << 25 */ - /* r0 = (va >> 12) & ((1ul << (40 - 12)) -1) */ - rldicl r0,r3,64-12,36 - xor r28,r28,r5 /* vsid ^ ( vsid << 25) */ - xor r28,r28,r0 /* hash */ - - /* Convert linux PTE bits into HW equivalents */ -4: andi. r3,r30,0x1fe /* Get basic set of flags */ - xori r3,r3,HPTE_R_N /* _PAGE_EXEC -> NOEXEC */ - rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */ - rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY -> _PAGE_USER (r4) */ - and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/ - andc r0,r30,r0 /* r0 = pte & ~r0 */ - rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */ - /* - * Always add "C" bit for perf. Memory coherence is always enabled - */ - ori r3,r3,HPTE_R_C | HPTE_R_M - - /* We eventually do the icache sync here (maybe inline that - * code rather than call a C function...) - */ -BEGIN_FTR_SECTION - mr r4,r30 - mr r5,r7 - bl hash_page_do_lazy_icache -END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) - - /* At this point, r3 contains new PP bits, save them in - * place of "access" in the param area (sic) - */ - std r3,STK_PARAM(R4)(r1) - - /* Get htab_hash_mask */ - ld r4,htab_hash_mask@got(2) - ld r27,0(r4) /* htab_hash_mask -> r27 */ - - /* Check if we may already be in the hashtable, in this case, we - * go to out-of-line code to try to modify the HPTE - */ - andi. r0,r31,_PAGE_HASHPTE - bne htab_modify_pte - -htab_insert_pte: - /* Clear hpte bits in new pte (we also clear BUSY btw) and - * add _PAGE_HASHPTE - */ - lis r0,_PAGE_HPTEFLAGS@h - ori r0,r0,_PAGE_HPTEFLAGS@l - andc r30,r30,r0 - ori r30,r30,_PAGE_HASHPTE - - /* physical address r5 */ - rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT - sldi r5,r5,PAGE_SHIFT - - /* Calculate primary group hash */ - and r0,r28,r27 - rldicr r3,r0,3,63-3 /* r3 = (hash & mask) << 3 */ - - /* Call ppc_md.hpte_insert */ - ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ - mr r4,r29 /* Retrieve vpn */ - li r7,0 /* !bolted, !secondary */ - li r8,MMU_PAGE_4K /* page size */ - li r9,MMU_PAGE_4K /* actual page size */ - ld r10,STK_PARAM(R9)(r1) /* segment size */ -.globl htab_call_hpte_insert1 -htab_call_hpte_insert1: - bl . /* Patched by htab_finish_init() */ - cmpdi 0,r3,0 - bge htab_pte_insert_ok /* Insertion successful */ - cmpdi 0,r3,-2 /* Critical failure */ - beq- htab_pte_insert_failure - - /* Now try secondary slot */ - - /* physical address r5 */ - rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT - sldi r5,r5,PAGE_SHIFT - - /* Calculate secondary group hash */ - andc r0,r27,r28 - rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */ - - /* Call ppc_md.hpte_insert */ - ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ - mr r4,r29 /* Retrieve vpn */ - li r7,HPTE_V_SECONDARY /* !bolted, secondary */ - li r8,MMU_PAGE_4K /* page size */ - li r9,MMU_PAGE_4K /* actual page size */ - ld r10,STK_PARAM(R9)(r1) /* segment size */ -.globl htab_call_hpte_insert2 -htab_call_hpte_insert2: - bl . /* Patched by htab_finish_init() */ - cmpdi 0,r3,0 - bge+ htab_pte_insert_ok /* Insertion successful */ - cmpdi 0,r3,-2 /* Critical failure */ - beq- htab_pte_insert_failure - - /* Both are full, we need to evict something */ - mftb r0 - /* Pick a random group based on TB */ - andi. r0,r0,1 - mr r5,r28 - bne 2f - not r5,r5 -2: and r0,r5,r27 - rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ - /* Call ppc_md.hpte_remove */ -.globl htab_call_hpte_remove -htab_call_hpte_remove: - bl . /* Patched by htab_finish_init() */ - - /* Try all again */ - b htab_insert_pte - -htab_bail_ok: - li r3,0 - b htab_bail - -htab_pte_insert_ok: - /* Insert slot number & secondary bit in PTE */ - rldimi r30,r3,12,63-15 - - /* Write out the PTE with a normal write - * (maybe add eieio may be good still ?) - */ -htab_write_out_pte: - ld r6,STK_PARAM(R6)(r1) - std r30,0(r6) - li r3, 0 -htab_bail: - ld r27,STK_REG(R27)(r1) - ld r28,STK_REG(R28)(r1) - ld r29,STK_REG(R29)(r1) - ld r30,STK_REG(R30)(r1) - ld r31,STK_REG(R31)(r1) - addi r1,r1,STACKFRAMESIZE - ld r0,16(r1) - mtlr r0 - blr - -htab_modify_pte: - /* Keep PP bits in r4 and slot idx from the PTE around in r3 */ - mr r4,r3 - rlwinm r3,r31,32-12,29,31 - - /* Secondary group ? if yes, get a inverted hash value */ - mr r5,r28 - andi. r0,r31,_PAGE_F_SECOND - beq 1f - not r5,r5 -1: - /* Calculate proper slot value for ppc_md.hpte_updatepp */ - and r0,r5,r27 - rldicr r0,r0,3,63-3 /* r0 = (hash & mask) << 3 */ - add r3,r0,r3 /* add slot idx */ - - /* Call ppc_md.hpte_updatepp */ - mr r5,r29 /* vpn */ - li r6,MMU_PAGE_4K /* base page size */ - li r7,MMU_PAGE_4K /* actual page size */ - ld r8,STK_PARAM(R9)(r1) /* segment size */ - ld r9,STK_PARAM(R8)(r1) /* get "flags" param */ -.globl htab_call_hpte_updatepp -htab_call_hpte_updatepp: - bl . /* Patched by htab_finish_init() */ - - /* if we failed because typically the HPTE wasn't really here - * we try an insertion. - */ - cmpdi 0,r3,-1 - beq- htab_insert_pte - - /* Clear the BUSY bit and Write out the PTE */ - li r0,_PAGE_BUSY - andc r30,r30,r0 - b htab_write_out_pte - -htab_wrong_access: - /* Bail out clearing reservation */ - stdcx. r31,0,r6 - li r3,1 - b htab_bail - -htab_pte_insert_failure: - /* Bail out restoring old PTE */ - ld r6,STK_PARAM(R6)(r1) - std r31,0(r6) - li r3,-1 - b htab_bail - -#endif diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index fb6e15c607a64..cab2deb8d20b2 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -629,31 +629,6 @@ int remove_section_mapping(unsigned long start, unsigned long end) } #endif /* CONFIG_MEMORY_HOTPLUG */ -extern u32 htab_call_hpte_insert1[]; -extern u32 htab_call_hpte_insert2[]; -extern u32 htab_call_hpte_remove[]; -extern u32 htab_call_hpte_updatepp[]; - -static void __init htab_finish_init(void) -{ - -#ifdef CONFIG_PPC_4K_PAGES - patch_branch(htab_call_hpte_insert1, - ppc_function_entry(ppc_md.hpte_insert), - BRANCH_SET_LINK); - patch_branch(htab_call_hpte_insert2, - ppc_function_entry(ppc_md.hpte_insert), - BRANCH_SET_LINK); - patch_branch(htab_call_hpte_remove, - ppc_function_entry(ppc_md.hpte_remove), - BRANCH_SET_LINK); - patch_branch(htab_call_hpte_updatepp, - ppc_function_entry(ppc_md.hpte_updatepp), - BRANCH_SET_LINK); -#endif - -} - static void __init htab_initialize(void) { unsigned long table; @@ -800,7 +775,6 @@ static void __init htab_initialize(void) mmu_linear_psize, mmu_kernel_ssize)); } - htab_finish_init(); DBG(" <- htab_initialize()\n"); } -- GitLab From c6a3c495f05a070d4c4016d4a51c384cba723971 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:50 +0530 Subject: [PATCH 1216/2855] powerpc/mm: Add helper for converting pte bit to hpte bits Instead of open coding it in multiple code paths, export the helper and add more documentation. Also make sure we don't make assumption regarding pte bit position Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/hash.h | 1 + arch/powerpc/mm/hash64_4k.c | 13 +-------- arch/powerpc/mm/hash64_64k.c | 35 ++--------------------- arch/powerpc/mm/hash_utils_64.c | 22 ++++++++------ arch/powerpc/mm/hugepage-hash64.c | 13 +-------- arch/powerpc/mm/hugetlbpage-hash64.c | 4 +-- 6 files changed, 21 insertions(+), 67 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index e4ea9d73a5419..9c212449b2e82 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -236,6 +236,7 @@ extern unsigned long pmd_hugepage_update(struct mm_struct *mm, pmd_t *pmdp, unsigned long clr, unsigned long set); +extern unsigned long htab_convert_pte_flags(unsigned long pteflags); /* Atomic PTE updates */ static inline unsigned long pte_update(struct mm_struct *mm, unsigned long addr, diff --git a/arch/powerpc/mm/hash64_4k.c b/arch/powerpc/mm/hash64_4k.c index 3b49c6f187410..ee863137035ae 100644 --- a/arch/powerpc/mm/hash64_4k.c +++ b/arch/powerpc/mm/hash64_4k.c @@ -53,18 +53,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, * PP bits. _PAGE_USER is already PP bit 0x2, so we only * need to add in 0x1 if it's a read-only user page */ - rflags = new_pte & _PAGE_USER; - if ((new_pte & _PAGE_USER) && !((new_pte & _PAGE_RW) && - (new_pte & _PAGE_DIRTY))) - rflags |= 0x1; - /* - * _PAGE_EXEC -> HW_NO_EXEC since it's inverted - */ - rflags |= ((new_pte & _PAGE_EXEC) ? 0 : HPTE_R_N); - /* - * Always add C and Memory coherence bit - */ - rflags |= HPTE_R_C | HPTE_R_M; + rflags = htab_convert_pte_flags(new_pte); /* * Add in WIMG bits */ diff --git a/arch/powerpc/mm/hash64_64k.c b/arch/powerpc/mm/hash64_64k.c index fc0898eb309d8..b14280e9d850a 100644 --- a/arch/powerpc/mm/hash64_64k.c +++ b/arch/powerpc/mm/hash64_64k.c @@ -85,22 +85,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, * Handle the subpage protection bits */ subpg_pte = new_pte & ~subpg_prot; - /* - * PP bits. _PAGE_USER is already PP bit 0x2, so we only - * need to add in 0x1 if it's a read-only user page - */ - rflags = subpg_pte & _PAGE_USER; - if ((subpg_pte & _PAGE_USER) && !((subpg_pte & _PAGE_RW) && - (subpg_pte & _PAGE_DIRTY))) - rflags |= 0x1; - /* - * _PAGE_EXEC -> HW_NO_EXEC since it's inverted - */ - rflags |= ((subpg_pte & _PAGE_EXEC) ? 0 : HPTE_R_N); - /* - * Always add C and Memory coherence bit - */ - rflags |= HPTE_R_C | HPTE_R_M; + rflags = htab_convert_pte_flags(subpg_pte); /* * Add in WIMG bits */ @@ -271,22 +256,8 @@ int __hash_page_64K(unsigned long ea, unsigned long access, new_pte |= _PAGE_DIRTY; } while (old_pte != __cmpxchg_u64((unsigned long *)ptep, old_pte, new_pte)); - /* - * PP bits. _PAGE_USER is already PP bit 0x2, so we only - * need to add in 0x1 if it's a read-only user page - */ - rflags = new_pte & _PAGE_USER; - if ((new_pte & _PAGE_USER) && !((new_pte & _PAGE_RW) && - (new_pte & _PAGE_DIRTY))) - rflags |= 0x1; - /* - * _PAGE_EXEC -> HW_NO_EXEC since it's inverted - */ - rflags |= ((new_pte & _PAGE_EXEC) ? 0 : HPTE_R_N); - /* - * Always add C and Memory coherence bit - */ - rflags |= HPTE_R_C | HPTE_R_M; + + rflags = htab_convert_pte_flags(new_pte); /* * Add in WIMG bits */ diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index cab2deb8d20b2..6c67bd0bec557 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -159,20 +159,26 @@ static struct mmu_psize_def mmu_psize_defaults_gp[] = { }, }; -static unsigned long htab_convert_pte_flags(unsigned long pteflags) +unsigned long htab_convert_pte_flags(unsigned long pteflags) { - unsigned long rflags = pteflags & 0x1fa; + unsigned long rflags = 0; /* _PAGE_EXEC -> NOEXEC */ if ((pteflags & _PAGE_EXEC) == 0) rflags |= HPTE_R_N; - - /* PP bits. PAGE_USER is already PP bit 0x2, so we only - * need to add in 0x1 if it's a read-only user page + /* + * PP bits: + * Linux use slb key 0 for kernel and 1 for user. + * kernel areas are mapped by PP bits 00 + * and and there is no kernel RO (_PAGE_KERNEL_RO). + * User area mapped by 0x2 and read only use by + * 0x3. */ - if ((pteflags & _PAGE_USER) && !((pteflags & _PAGE_RW) && - (pteflags & _PAGE_DIRTY))) - rflags |= 1; + if (pteflags & _PAGE_USER) { + rflags |= 0x2; + if (!((pteflags & _PAGE_RW) && (pteflags & _PAGE_DIRTY))) + rflags |= 0x1; + } /* * Always add "C" bit for perf. Memory coherence is always enabled */ diff --git a/arch/powerpc/mm/hugepage-hash64.c b/arch/powerpc/mm/hugepage-hash64.c index 4d87122cf6a72..91fcac6f989d6 100644 --- a/arch/powerpc/mm/hugepage-hash64.c +++ b/arch/powerpc/mm/hugepage-hash64.c @@ -54,18 +54,7 @@ int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid, new_pmd |= _PAGE_DIRTY; } while (old_pmd != __cmpxchg_u64((unsigned long *)pmdp, old_pmd, new_pmd)); - /* - * PP bits. _PAGE_USER is already PP bit 0x2, so we only - * need to add in 0x1 if it's a read-only user page - */ - rflags = new_pmd & _PAGE_USER; - if ((new_pmd & _PAGE_USER) && !((new_pmd & _PAGE_RW) && - (new_pmd & _PAGE_DIRTY))) - rflags |= 0x1; - /* - * _PAGE_EXEC -> HW_NO_EXEC since it's inverted - */ - rflags |= ((new_pmd & _PAGE_EXEC) ? 0 : HPTE_R_N); + rflags = htab_convert_pte_flags(new_pmd); #if 0 if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) { diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c index 7584e84455127..304c8520506e7 100644 --- a/arch/powerpc/mm/hugetlbpage-hash64.c +++ b/arch/powerpc/mm/hugetlbpage-hash64.c @@ -59,10 +59,8 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, new_pte |= _PAGE_DIRTY; } while(old_pte != __cmpxchg_u64((unsigned long *)ptep, old_pte, new_pte)); + rflags = htab_convert_pte_flags(new_pte); - rflags = 0x2 | (!(new_pte & _PAGE_RW)); - /* _PAGE_EXEC -> HW_NO_EXEC since it's inverted */ - rflags |= ((new_pte & _PAGE_EXEC) ? 0 : HPTE_R_N); sz = ((1UL) << shift); if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) /* No CPU has hugepages but lacks no execute, so we -- GitLab From 40e8550afc19dfc588171c089cb3f31f7b9e16f7 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:51 +0530 Subject: [PATCH 1217/2855] powerpc/mm: Move WIMG update to helper. Only difference here is, we apply the WIMG mapping early, so rflags passed to updatepp will also be changed. Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/mm/hash64_4k.c | 5 ----- arch/powerpc/mm/hash64_64k.c | 10 ---------- arch/powerpc/mm/hash_utils_64.c | 13 ++++++++++++- arch/powerpc/mm/hugepage-hash64.c | 7 ------- arch/powerpc/mm/hugetlbpage-hash64.c | 8 -------- 5 files changed, 12 insertions(+), 31 deletions(-) diff --git a/arch/powerpc/mm/hash64_4k.c b/arch/powerpc/mm/hash64_4k.c index ee863137035ae..e7c04542ba622 100644 --- a/arch/powerpc/mm/hash64_4k.c +++ b/arch/powerpc/mm/hash64_4k.c @@ -54,11 +54,6 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, * need to add in 0x1 if it's a read-only user page */ rflags = htab_convert_pte_flags(new_pte); - /* - * Add in WIMG bits - */ - rflags |= (new_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE | - _PAGE_COHERENT | _PAGE_GUARDED)); if (!cpu_has_feature(CPU_FTR_NOEXECUTE) && !cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) diff --git a/arch/powerpc/mm/hash64_64k.c b/arch/powerpc/mm/hash64_64k.c index b14280e9d850a..0762c1e08c886 100644 --- a/arch/powerpc/mm/hash64_64k.c +++ b/arch/powerpc/mm/hash64_64k.c @@ -86,11 +86,6 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, */ subpg_pte = new_pte & ~subpg_prot; rflags = htab_convert_pte_flags(subpg_pte); - /* - * Add in WIMG bits - */ - rflags |= (subpg_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE | - _PAGE_COHERENT | _PAGE_GUARDED)); if (!cpu_has_feature(CPU_FTR_NOEXECUTE) && !cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) { @@ -258,11 +253,6 @@ int __hash_page_64K(unsigned long ea, unsigned long access, old_pte, new_pte)); rflags = htab_convert_pte_flags(new_pte); - /* - * Add in WIMG bits - */ - rflags |= (new_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE | - _PAGE_COHERENT | _PAGE_GUARDED)); if (!cpu_has_feature(CPU_FTR_NOEXECUTE) && !cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 6c67bd0bec557..4233dcccbaf77 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -182,7 +182,18 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags) /* * Always add "C" bit for perf. Memory coherence is always enabled */ - return rflags | HPTE_R_C | HPTE_R_M; + rflags |= HPTE_R_C | HPTE_R_M; + /* + * Add in WIG bits + */ + if (pteflags & _PAGE_WRITETHRU) + rflags |= HPTE_R_W; + if (pteflags & _PAGE_NO_CACHE) + rflags |= HPTE_R_I; + if (pteflags & _PAGE_GUARDED) + rflags |= HPTE_R_G; + + return rflags; } int htab_bolt_mapping(unsigned long vstart, unsigned long vend, diff --git a/arch/powerpc/mm/hugepage-hash64.c b/arch/powerpc/mm/hugepage-hash64.c index 91fcac6f989d6..1f666de0110ac 100644 --- a/arch/powerpc/mm/hugepage-hash64.c +++ b/arch/powerpc/mm/hugepage-hash64.c @@ -120,13 +120,6 @@ int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid, pa = pmd_pfn(__pmd(old_pmd)) << PAGE_SHIFT; new_pmd |= _PAGE_HASHPTE; - /* Add in WIMG bits */ - rflags |= (new_pmd & (_PAGE_WRITETHRU | _PAGE_NO_CACHE | - _PAGE_GUARDED)); - /* - * enable the memory coherence always - */ - rflags |= HPTE_R_M; repeat: hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL; diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c index 304c8520506e7..0734e4daffefd 100644 --- a/arch/powerpc/mm/hugetlbpage-hash64.c +++ b/arch/powerpc/mm/hugetlbpage-hash64.c @@ -91,14 +91,6 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, /* clear HPTE slot informations in new PTE */ new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HASHPTE; - /* Add in WIMG bits */ - rflags |= (new_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE | - _PAGE_COHERENT | _PAGE_GUARDED)); - /* - * enable the memory coherence always - */ - rflags |= HPTE_R_M; - slot = hpte_insert_repeating(hash, vpn, pa, rflags, 0, mmu_psize, ssize); -- GitLab From 26a344aea48c99cfd80d292a470a480e1c2bd5d9 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:52 +0530 Subject: [PATCH 1218/2855] powerpc/mm: Move hugetlb related headers W.r.t hugetlb, we support two format for pmd. With book3s_64 and 64K linux page size, we can have pte at the pmd level. Hence we don't need to support hugepd there. For everything else hugepd is supported and pmd_huge is (0). Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/hash-4k.h | 31 ++++++++ arch/powerpc/include/asm/book3s/64/hash-64k.h | 51 +++++++++++++ arch/powerpc/include/asm/nohash/pgtable.h | 25 +++++++ arch/powerpc/include/asm/page.h | 42 ++--------- arch/powerpc/mm/hugetlbpage-hash64.c | 18 +++++ arch/powerpc/mm/hugetlbpage.c | 72 ------------------- 6 files changed, 129 insertions(+), 110 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h index 75e8b9326e4b2..b4d25529d1798 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-4k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h @@ -93,6 +93,37 @@ extern struct page *pgd_page(pgd_t pgd); #define remap_4k_pfn(vma, addr, pfn, prot) \ remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot)) +#ifdef CONFIG_HUGETLB_PAGE +/* + * For 4k page size, we support explicit hugepage via hugepd + */ +static inline int pmd_huge(pmd_t pmd) +{ + return 0; +} + +static inline int pud_huge(pud_t pud) +{ + return 0; +} + +static inline int pgd_huge(pgd_t pgd) +{ + return 0; +} +#define pgd_huge pgd_huge + +static inline int hugepd_ok(hugepd_t hpd) +{ + /* + * hugepd pointer, bottom two bits == 00 and next 4 bits + * indicate size of table + */ + return (((hpd.pd & 0x3) == 0x0) && ((hpd.pd & HUGEPD_SHIFT_MASK) != 0)); +} +#define is_hugepd(hpd) (hugepd_ok(hpd)) +#endif + #endif /* !__ASSEMBLY__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */ diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h index 46b5d0ab11de7..1857d19de18ec 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h @@ -119,6 +119,57 @@ extern bool __rpte_sub_valid(real_pte_t rpte, unsigned long index); #define pgd_pte(pgd) (pud_pte(((pud_t){ pgd }))) #define pte_pgd(pte) ((pgd_t)pte_pud(pte)) +#ifdef CONFIG_HUGETLB_PAGE +/* + * We have PGD_INDEX_SIZ = 12 and PTE_INDEX_SIZE = 8, so that we can have + * 16GB hugepage pte in PGD and 16MB hugepage pte at PMD; + * + * Defined in such a way that we can optimize away code block at build time + * if CONFIG_HUGETLB_PAGE=n. + */ +static inline int pmd_huge(pmd_t pmd) +{ + /* + * leaf pte for huge page, bottom two bits != 00 + */ + return ((pmd_val(pmd) & 0x3) != 0x0); +} + +static inline int pud_huge(pud_t pud) +{ + /* + * leaf pte for huge page, bottom two bits != 00 + */ + return ((pud_val(pud) & 0x3) != 0x0); +} + +static inline int pgd_huge(pgd_t pgd) +{ + /* + * leaf pte for huge page, bottom two bits != 00 + */ + return ((pgd_val(pgd) & 0x3) != 0x0); +} +#define pgd_huge pgd_huge + +#ifdef CONFIG_DEBUG_VM +extern int hugepd_ok(hugepd_t hpd); +#define is_hugepd(hpd) (hugepd_ok(hpd)) +#else +/* + * With 64k page size, we have hugepage ptes in the pgd and pmd entries. We don't + * need to setup hugepage directory for them. Our pte and page directory format + * enable us to have this enabled. + */ +static inline int hugepd_ok(hugepd_t hpd) +{ + return 0; +} +#define is_hugepd(pdep) 0 +#endif /* CONFIG_DEBUG_VM */ + +#endif /* CONFIG_HUGETLB_PAGE */ + #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_64K_H */ diff --git a/arch/powerpc/include/asm/nohash/pgtable.h b/arch/powerpc/include/asm/nohash/pgtable.h index c0c41a2409d24..1263c22d60d85 100644 --- a/arch/powerpc/include/asm/nohash/pgtable.h +++ b/arch/powerpc/include/asm/nohash/pgtable.h @@ -223,5 +223,30 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, unsigned long size, pgprot_t vma_prot); #define __HAVE_PHYS_MEM_ACCESS_PROT +#ifdef CONFIG_HUGETLB_PAGE +static inline int hugepd_ok(hugepd_t hpd) +{ + return (hpd.pd > 0); +} + +static inline int pmd_huge(pmd_t pmd) +{ + return 0; +} + +static inline int pud_huge(pud_t pud) +{ + return 0; +} + +static inline int pgd_huge(pgd_t pgd) +{ + return 0; +} +#define pgd_huge pgd_huge + +#define is_hugepd(hpd) (hugepd_ok(hpd)) +#endif + #endif /* __ASSEMBLY__ */ #endif diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index 5a3e7c643d73d..e34124f6fbf27 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h @@ -387,45 +387,11 @@ typedef unsigned long pgprot_t; typedef struct { signed long pd; } hugepd_t; -#ifdef CONFIG_HUGETLB_PAGE -#ifdef CONFIG_PPC_BOOK3S_64 -#ifdef CONFIG_PPC_64K_PAGES -/* - * With 64k page size, we have hugepage ptes in the pgd and pmd entries. We don't - * need to setup hugepage directory for them. Our pte and page directory format - * enable us to have this enabled. But to avoid errors when implementing new - * features disable hugepd for 64K. We enable a debug version here, So we catch - * wrong usage. - */ -#ifdef CONFIG_DEBUG_VM -extern int hugepd_ok(hugepd_t hpd); -#else -#define hugepd_ok(x) (0) -#endif -#else -static inline int hugepd_ok(hugepd_t hpd) -{ - /* - * hugepd pointer, bottom two bits == 00 and next 4 bits - * indicate size of table - */ - return (((hpd.pd & 0x3) == 0x0) && ((hpd.pd & HUGEPD_SHIFT_MASK) != 0)); -} -#endif -#else -static inline int hugepd_ok(hugepd_t hpd) -{ - return (hpd.pd > 0); -} -#endif - -#define is_hugepd(hpd) (hugepd_ok(hpd)) -#define pgd_huge pgd_huge -int pgd_huge(pgd_t pgd); -#else /* CONFIG_HUGETLB_PAGE */ -#define is_hugepd(pdep) 0 -#define pgd_huge(pgd) 0 +#ifndef CONFIG_HUGETLB_PAGE +#define is_hugepd(pdep) (0) +#define pgd_huge(pgd) (0) #endif /* CONFIG_HUGETLB_PAGE */ + #define __hugepd(x) ((hugepd_t) { (x) }) struct page; diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c index 0734e4daffefd..e2138c7ae70fe 100644 --- a/arch/powerpc/mm/hugetlbpage-hash64.c +++ b/arch/powerpc/mm/hugetlbpage-hash64.c @@ -114,3 +114,21 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, *ptep = __pte(new_pte & ~_PAGE_BUSY); return 0; } + +#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_DEBUG_VM) +/* + * This enables us to catch the wrong page directory format + * Moved here so that we can use WARN() in the call. + */ +int hugepd_ok(hugepd_t hpd) +{ + bool is_hugepd; + + /* + * We should not find this format in page directory, warn otherwise. + */ + is_hugepd = (((hpd.pd & 0x3) == 0x0) && ((hpd.pd & HUGEPD_SHIFT_MASK) != 0)); + WARN(is_hugepd, "Found wrong page directory format\n"); + return 0; +} +#endif diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 9833fee493ec4..bc72e542a83ee 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -53,78 +53,6 @@ static unsigned nr_gpages; #define hugepd_none(hpd) ((hpd).pd == 0) -#ifdef CONFIG_PPC_BOOK3S_64 -/* - * At this point we do the placement change only for BOOK3S 64. This would - * possibly work on other subarchs. - */ - -/* - * We have PGD_INDEX_SIZ = 12 and PTE_INDEX_SIZE = 8, so that we can have - * 16GB hugepage pte in PGD and 16MB hugepage pte at PMD; - * - * Defined in such a way that we can optimize away code block at build time - * if CONFIG_HUGETLB_PAGE=n. - */ -int pmd_huge(pmd_t pmd) -{ - /* - * leaf pte for huge page, bottom two bits != 00 - */ - return ((pmd_val(pmd) & 0x3) != 0x0); -} - -int pud_huge(pud_t pud) -{ - /* - * leaf pte for huge page, bottom two bits != 00 - */ - return ((pud_val(pud) & 0x3) != 0x0); -} - -int pgd_huge(pgd_t pgd) -{ - /* - * leaf pte for huge page, bottom two bits != 00 - */ - return ((pgd_val(pgd) & 0x3) != 0x0); -} - -#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_DEBUG_VM) -/* - * This enables us to catch the wrong page directory format - * Moved here so that we can use WARN() in the call. - */ -int hugepd_ok(hugepd_t hpd) -{ - bool is_hugepd; - - /* - * We should not find this format in page directory, warn otherwise. - */ - is_hugepd = (((hpd.pd & 0x3) == 0x0) && ((hpd.pd & HUGEPD_SHIFT_MASK) != 0)); - WARN(is_hugepd, "Found wrong page directory format\n"); - return 0; -} -#endif - -#else -int pmd_huge(pmd_t pmd) -{ - return 0; -} - -int pud_huge(pud_t pud) -{ - return 0; -} - -int pgd_huge(pgd_t pgd) -{ - return 0; -} -#endif - pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) { /* Only called for hugetlbfs pages, hence can ignore THP */ -- GitLab From e34aa03ca48d0c7982530436ce996f374b65913c Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:53 +0530 Subject: [PATCH 1219/2855] powerpc/mm: Move THP headers around We support THP only with book3s_64 and 64K page size. Move THP details to hash64-64k.h to clarify the same. Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/hash-64k.h | 126 +++++++++ arch/powerpc/include/asm/book3s/64/hash.h | 223 ++++----------- arch/powerpc/include/asm/nohash/64/pgtable.h | 253 +----------------- arch/powerpc/mm/hash_native_64.c | 10 + arch/powerpc/mm/pgtable_64.c | 2 +- arch/powerpc/platforms/pseries/lpar.c | 10 + 6 files changed, 201 insertions(+), 423 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h index 1857d19de18ec..7570677c11c3e 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h @@ -170,6 +170,132 @@ static inline int hugepd_ok(hugepd_t hpd) #endif /* CONFIG_HUGETLB_PAGE */ +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +extern unsigned long pmd_hugepage_update(struct mm_struct *mm, + unsigned long addr, + pmd_t *pmdp, + unsigned long clr, + unsigned long set); +static inline char *get_hpte_slot_array(pmd_t *pmdp) +{ + /* + * The hpte hindex is stored in the pgtable whose address is in the + * second half of the PMD + * + * Order this load with the test for pmd_trans_huge in the caller + */ + smp_rmb(); + return *(char **)(pmdp + PTRS_PER_PMD); + + +} +/* + * The linux hugepage PMD now include the pmd entries followed by the address + * to the stashed pgtable_t. The stashed pgtable_t contains the hpte bits. + * [ 1 bit secondary | 3 bit hidx | 1 bit valid | 000]. We use one byte per + * each HPTE entry. With 16MB hugepage and 64K HPTE we need 256 entries and + * with 4K HPTE we need 4096 entries. Both will fit in a 4K pgtable_t. + * + * The last three bits are intentionally left to zero. This memory location + * are also used as normal page PTE pointers. So if we have any pointers + * left around while we collapse a hugepage, we need to make sure + * _PAGE_PRESENT bit of that is zero when we look at them + */ +static inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index) +{ + return (hpte_slot_array[index] >> 3) & 0x1; +} + +static inline unsigned int hpte_hash_index(unsigned char *hpte_slot_array, + int index) +{ + return hpte_slot_array[index] >> 4; +} + +static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array, + unsigned int index, unsigned int hidx) +{ + hpte_slot_array[index] = hidx << 4 | 0x1 << 3; +} + +/* + * + * For core kernel code by design pmd_trans_huge is never run on any hugetlbfs + * page. The hugetlbfs page table walking and mangling paths are totally + * separated form the core VM paths and they're differentiated by + * VM_HUGETLB being set on vm_flags well before any pmd_trans_huge could run. + * + * pmd_trans_huge() is defined as false at build time if + * CONFIG_TRANSPARENT_HUGEPAGE=n to optimize away code blocks at build + * time in such case. + * + * For ppc64 we need to differntiate from explicit hugepages from THP, because + * for THP we also track the subpage details at the pmd level. We don't do + * that for explicit huge pages. + * + */ +static inline int pmd_trans_huge(pmd_t pmd) +{ + /* + * leaf pte for huge page, bottom two bits != 00 + */ + return (pmd_val(pmd) & 0x3) && (pmd_val(pmd) & _PAGE_THP_HUGE); +} + +static inline int pmd_trans_splitting(pmd_t pmd) +{ + if (pmd_trans_huge(pmd)) + return pmd_val(pmd) & _PAGE_SPLITTING; + return 0; +} + +static inline int pmd_large(pmd_t pmd) +{ + /* + * leaf pte for huge page, bottom two bits != 00 + */ + return ((pmd_val(pmd) & 0x3) != 0x0); +} + +static inline pmd_t pmd_mknotpresent(pmd_t pmd) +{ + return __pmd(pmd_val(pmd) & ~_PAGE_PRESENT); +} + +static inline pmd_t pmd_mksplitting(pmd_t pmd) +{ + return __pmd(pmd_val(pmd) | _PAGE_SPLITTING); +} + +#define __HAVE_ARCH_PMD_SAME +static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b) +{ + return (((pmd_val(pmd_a) ^ pmd_val(pmd_b)) & ~_PAGE_HPTEFLAGS) == 0); +} + +static inline int __pmdp_test_and_clear_young(struct mm_struct *mm, + unsigned long addr, pmd_t *pmdp) +{ + unsigned long old; + + if ((pmd_val(*pmdp) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0) + return 0; + old = pmd_hugepage_update(mm, addr, pmdp, _PAGE_ACCESSED, 0); + return ((old & _PAGE_ACCESSED) != 0); +} + +#define __HAVE_ARCH_PMDP_SET_WRPROTECT +static inline void pmdp_set_wrprotect(struct mm_struct *mm, unsigned long addr, + pmd_t *pmdp) +{ + + if ((pmd_val(*pmdp) & _PAGE_RW) == 0) + return; + + pmd_hugepage_update(mm, addr, pmdp, _PAGE_RW, 0); +} + +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_64K_H */ diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 9c212449b2e82..42e1273adad1b 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -2,6 +2,55 @@ #define _ASM_POWERPC_BOOK3S_64_HASH_H #ifdef __KERNEL__ +/* + * Common bits between 4K and 64K pages in a linux-style PTE. + * These match the bits in the (hardware-defined) PowerPC PTE as closely + * as possible. Additional bits may be defined in pgtable-hash64-*.h + * + * Note: We only support user read/write permissions. Supervisor always + * have full read/write to pages above PAGE_OFFSET (pages below that + * always use the user access permissions). + * + * We could create separate kernel read-only if we used the 3 PP bits + * combinations that newer processors provide but we currently don't. + */ +#define _PAGE_PRESENT 0x00001 /* software: pte contains a translation */ +#define _PAGE_USER 0x00002 /* matches one of the PP bits */ +#define _PAGE_BIT_SWAP_TYPE 2 +#define _PAGE_EXEC 0x00004 /* No execute on POWER4 and newer (we invert) */ +#define _PAGE_GUARDED 0x00008 +/* We can derive Memory coherence from _PAGE_NO_CACHE */ +#define _PAGE_COHERENT 0x0 +#define _PAGE_NO_CACHE 0x00020 /* I: cache inhibit */ +#define _PAGE_WRITETHRU 0x00040 /* W: cache write-through */ +#define _PAGE_DIRTY 0x00080 /* C: page changed */ +#define _PAGE_ACCESSED 0x00100 /* R: page referenced */ +#define _PAGE_RW 0x00200 /* software: user write access allowed */ +#define _PAGE_HASHPTE 0x00400 /* software: pte has an associated HPTE */ +#define _PAGE_BUSY 0x00800 /* software: PTE & hash are busy */ +#define _PAGE_F_GIX 0x07000 /* full page: hidx bits */ +#define _PAGE_F_GIX_SHIFT 12 +#define _PAGE_F_SECOND 0x08000 /* Whether to use secondary hash or not */ +#define _PAGE_SPECIAL 0x10000 /* software: special page */ + +/* + * THP pages can't be special. So use the _PAGE_SPECIAL + */ +#define _PAGE_SPLITTING _PAGE_SPECIAL + +/* + * We need to differentiate between explicit huge page and THP huge + * page, since THP huge page also need to track real subpage details + */ +#define _PAGE_THP_HUGE _PAGE_4K_PFN + +/* + * set of bits not changed in pmd_modify. + */ +#define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | \ + _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SPLITTING | \ + _PAGE_THP_HUGE) + #ifdef CONFIG_PPC_64K_PAGES #include #else @@ -57,36 +106,6 @@ #define HAVE_ARCH_UNMAPPED_AREA #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN #endif /* CONFIG_PPC_MM_SLICES */ -/* - * Common bits between 4K and 64K pages in a linux-style PTE. - * These match the bits in the (hardware-defined) PowerPC PTE as closely - * as possible. Additional bits may be defined in pgtable-hash64-*.h - * - * Note: We only support user read/write permissions. Supervisor always - * have full read/write to pages above PAGE_OFFSET (pages below that - * always use the user access permissions). - * - * We could create separate kernel read-only if we used the 3 PP bits - * combinations that newer processors provide but we currently don't. - */ -#define _PAGE_PRESENT 0x00001 /* software: pte contains a translation */ -#define _PAGE_USER 0x00002 /* matches one of the PP bits */ -#define _PAGE_BIT_SWAP_TYPE 2 -#define _PAGE_EXEC 0x00004 /* No execute on POWER4 and newer (we invert) */ -#define _PAGE_GUARDED 0x00008 -/* We can derive Memory coherence from _PAGE_NO_CACHE */ -#define _PAGE_COHERENT 0x0 -#define _PAGE_NO_CACHE 0x00020 /* I: cache inhibit */ -#define _PAGE_WRITETHRU 0x00040 /* W: cache write-through */ -#define _PAGE_DIRTY 0x00080 /* C: page changed */ -#define _PAGE_ACCESSED 0x00100 /* R: page referenced */ -#define _PAGE_RW 0x00200 /* software: user write access allowed */ -#define _PAGE_HASHPTE 0x00400 /* software: pte has an associated HPTE */ -#define _PAGE_BUSY 0x00800 /* software: PTE & hash are busy */ -#define _PAGE_F_GIX 0x07000 /* full page: hidx bits */ -#define _PAGE_F_GIX_SHIFT 12 -#define _PAGE_F_SECOND 0x08000 /* Whether to use secondary hash or not */ -#define _PAGE_SPECIAL 0x10000 /* software: special page */ /* No separate kernel read-only */ #define _PAGE_KERNEL_RW (_PAGE_RW | _PAGE_DIRTY) /* user access blocked by key */ @@ -105,24 +124,6 @@ /* Hash table based platforms need atomic updates of the linux PTE */ #define PTE_ATOMIC_UPDATES 1 - -/* - * THP pages can't be special. So use the _PAGE_SPECIAL - */ -#define _PAGE_SPLITTING _PAGE_SPECIAL - -/* - * We need to differentiate between explicit huge page and THP huge - * page, since THP huge page also need to track real subpage details - */ -#define _PAGE_THP_HUGE _PAGE_4K_PFN - -/* - * set of bits not changed in pmd_modify. - */ -#define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | \ - _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SPLITTING | \ - _PAGE_THP_HUGE) #define _PTE_NONE_MASK _PAGE_HPTEFLAGS /* * The mask convered by the RPN must be a ULL on 32-bit platforms with @@ -231,11 +232,6 @@ extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr, pte_t *ptep, unsigned long pte, int huge); -extern unsigned long pmd_hugepage_update(struct mm_struct *mm, - unsigned long addr, - pmd_t *pmdp, - unsigned long clr, - unsigned long set); extern unsigned long htab_convert_pte_flags(unsigned long pteflags); /* Atomic PTE updates */ static inline unsigned long pte_update(struct mm_struct *mm, @@ -361,127 +357,6 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) #define __HAVE_ARCH_PTE_SAME #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0) -static inline char *get_hpte_slot_array(pmd_t *pmdp) -{ - /* - * The hpte hindex is stored in the pgtable whose address is in the - * second half of the PMD - * - * Order this load with the test for pmd_trans_huge in the caller - */ - smp_rmb(); - return *(char **)(pmdp + PTRS_PER_PMD); - - -} -/* - * The linux hugepage PMD now include the pmd entries followed by the address - * to the stashed pgtable_t. The stashed pgtable_t contains the hpte bits. - * [ 1 bit secondary | 3 bit hidx | 1 bit valid | 000]. We use one byte per - * each HPTE entry. With 16MB hugepage and 64K HPTE we need 256 entries and - * with 4K HPTE we need 4096 entries. Both will fit in a 4K pgtable_t. - * - * The last three bits are intentionally left to zero. This memory location - * are also used as normal page PTE pointers. So if we have any pointers - * left around while we collapse a hugepage, we need to make sure - * _PAGE_PRESENT bit of that is zero when we look at them - */ -static inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index) -{ - return (hpte_slot_array[index] >> 3) & 0x1; -} - -static inline unsigned int hpte_hash_index(unsigned char *hpte_slot_array, - int index) -{ - return hpte_slot_array[index] >> 4; -} - -static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array, - unsigned int index, unsigned int hidx) -{ - hpte_slot_array[index] = hidx << 4 | 0x1 << 3; -} - -#ifdef CONFIG_TRANSPARENT_HUGEPAGE -/* - * - * For core kernel code by design pmd_trans_huge is never run on any hugetlbfs - * page. The hugetlbfs page table walking and mangling paths are totally - * separated form the core VM paths and they're differentiated by - * VM_HUGETLB being set on vm_flags well before any pmd_trans_huge could run. - * - * pmd_trans_huge() is defined as false at build time if - * CONFIG_TRANSPARENT_HUGEPAGE=n to optimize away code blocks at build - * time in such case. - * - * For ppc64 we need to differntiate from explicit hugepages from THP, because - * for THP we also track the subpage details at the pmd level. We don't do - * that for explicit huge pages. - * - */ -static inline int pmd_trans_huge(pmd_t pmd) -{ - /* - * leaf pte for huge page, bottom two bits != 00 - */ - return (pmd_val(pmd) & 0x3) && (pmd_val(pmd) & _PAGE_THP_HUGE); -} - -static inline int pmd_trans_splitting(pmd_t pmd) -{ - if (pmd_trans_huge(pmd)) - return pmd_val(pmd) & _PAGE_SPLITTING; - return 0; -} - -#endif -static inline int pmd_large(pmd_t pmd) -{ - /* - * leaf pte for huge page, bottom two bits != 00 - */ - return ((pmd_val(pmd) & 0x3) != 0x0); -} - -static inline pmd_t pmd_mknotpresent(pmd_t pmd) -{ - return __pmd(pmd_val(pmd) & ~_PAGE_PRESENT); -} - -static inline pmd_t pmd_mksplitting(pmd_t pmd) -{ - return __pmd(pmd_val(pmd) | _PAGE_SPLITTING); -} - -#define __HAVE_ARCH_PMD_SAME -static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b) -{ - return (((pmd_val(pmd_a) ^ pmd_val(pmd_b)) & ~_PAGE_HPTEFLAGS) == 0); -} - -static inline int __pmdp_test_and_clear_young(struct mm_struct *mm, - unsigned long addr, pmd_t *pmdp) -{ - unsigned long old; - - if ((pmd_val(*pmdp) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0) - return 0; - old = pmd_hugepage_update(mm, addr, pmdp, _PAGE_ACCESSED, 0); - return ((old & _PAGE_ACCESSED) != 0); -} - -#define __HAVE_ARCH_PMDP_SET_WRPROTECT -static inline void pmdp_set_wrprotect(struct mm_struct *mm, unsigned long addr, - pmd_t *pmdp) -{ - - if ((pmd_val(*pmdp) & _PAGE_RW) == 0) - return; - - pmd_hugepage_update(mm, addr, pmdp, _PAGE_RW, 0); -} - /* Generic accessors to PTE bits */ static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & _PAGE_RW);} static inline int pte_dirty(pte_t pte) { return !!(pte_val(pte) & _PAGE_DIRTY); } diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h index c24e03f226556..d635a924d652b 100644 --- a/arch/powerpc/include/asm/nohash/64/pgtable.h +++ b/arch/powerpc/include/asm/nohash/64/pgtable.h @@ -154,6 +154,11 @@ static inline void pmd_clear(pmd_t *pmdp) *pmdp = __pmd(0); } +static inline pte_t pmd_pte(pmd_t pmd) +{ + return __pte(pmd_val(pmd)); +} + #define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \ || (pmd_val(pmd) & PMD_BAD_BITS)) @@ -389,252 +394,4 @@ void pgtable_cache_add(unsigned shift, void (*ctor)(void *)); void pgtable_cache_init(void); #endif /* __ASSEMBLY__ */ -/* - * THP pages can't be special. So use the _PAGE_SPECIAL - */ -#define _PAGE_SPLITTING _PAGE_SPECIAL - -/* - * We need to differentiate between explicit huge page and THP huge - * page, since THP huge page also need to track real subpage details - */ -#define _PAGE_THP_HUGE _PAGE_4K_PFN - -/* - * set of bits not changed in pmd_modify. - */ -#define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | \ - _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SPLITTING | \ - _PAGE_THP_HUGE) - -#ifndef __ASSEMBLY__ -/* - * The linux hugepage PMD now include the pmd entries followed by the address - * to the stashed pgtable_t. The stashed pgtable_t contains the hpte bits. - * [ 1 bit secondary | 3 bit hidx | 1 bit valid | 000]. We use one byte per - * each HPTE entry. With 16MB hugepage and 64K HPTE we need 256 entries and - * with 4K HPTE we need 4096 entries. Both will fit in a 4K pgtable_t. - * - * The last three bits are intentionally left to zero. This memory location - * are also used as normal page PTE pointers. So if we have any pointers - * left around while we collapse a hugepage, we need to make sure - * _PAGE_PRESENT bit of that is zero when we look at them - */ -static inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index) -{ - return (hpte_slot_array[index] >> 3) & 0x1; -} - -static inline unsigned int hpte_hash_index(unsigned char *hpte_slot_array, - int index) -{ - return hpte_slot_array[index] >> 4; -} - -static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array, - unsigned int index, unsigned int hidx) -{ - hpte_slot_array[index] = hidx << 4 | 0x1 << 3; -} - -struct page *realmode_pfn_to_page(unsigned long pfn); - -static inline char *get_hpte_slot_array(pmd_t *pmdp) -{ - /* - * The hpte hindex is stored in the pgtable whose address is in the - * second half of the PMD - * - * Order this load with the test for pmd_trans_huge in the caller - */ - smp_rmb(); - return *(char **)(pmdp + PTRS_PER_PMD); - - -} - -#ifdef CONFIG_TRANSPARENT_HUGEPAGE -extern void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr, - pmd_t *pmdp, unsigned long old_pmd); -extern pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot); -extern pmd_t mk_pmd(struct page *page, pgprot_t pgprot); -extern pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot); -extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, - pmd_t *pmdp, pmd_t pmd); -extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, - pmd_t *pmd); -/* - * - * For core kernel code by design pmd_trans_huge is never run on any hugetlbfs - * page. The hugetlbfs page table walking and mangling paths are totally - * separated form the core VM paths and they're differentiated by - * VM_HUGETLB being set on vm_flags well before any pmd_trans_huge could run. - * - * pmd_trans_huge() is defined as false at build time if - * CONFIG_TRANSPARENT_HUGEPAGE=n to optimize away code blocks at build - * time in such case. - * - * For ppc64 we need to differntiate from explicit hugepages from THP, because - * for THP we also track the subpage details at the pmd level. We don't do - * that for explicit huge pages. - * - */ -static inline int pmd_trans_huge(pmd_t pmd) -{ - /* - * leaf pte for huge page, bottom two bits != 00 - */ - return (pmd_val(pmd) & 0x3) && (pmd_val(pmd) & _PAGE_THP_HUGE); -} - -static inline int pmd_trans_splitting(pmd_t pmd) -{ - if (pmd_trans_huge(pmd)) - return pmd_val(pmd) & _PAGE_SPLITTING; - return 0; -} - -extern int has_transparent_hugepage(void); -#else -static inline void hpte_do_hugepage_flush(struct mm_struct *mm, - unsigned long addr, pmd_t *pmdp, - unsigned long old_pmd) -{ - - WARN(1, "%s called with THP disabled\n", __func__); -} -#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ - -static inline int pmd_large(pmd_t pmd) -{ - /* - * leaf pte for huge page, bottom two bits != 00 - */ - return ((pmd_val(pmd) & 0x3) != 0x0); -} - -static inline pte_t pmd_pte(pmd_t pmd) -{ - return __pte(pmd_val(pmd)); -} - -static inline pmd_t pte_pmd(pte_t pte) -{ - return __pmd(pte_val(pte)); -} - -static inline pte_t *pmdp_ptep(pmd_t *pmd) -{ - return (pte_t *)pmd; -} - -#define pmd_pfn(pmd) pte_pfn(pmd_pte(pmd)) -#define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd)) -#define pmd_young(pmd) pte_young(pmd_pte(pmd)) -#define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd))) -#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd))) -#define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd))) -#define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd))) -#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd))) - -#define __HAVE_ARCH_PMD_WRITE -#define pmd_write(pmd) pte_write(pmd_pte(pmd)) - -static inline pmd_t pmd_mkhuge(pmd_t pmd) -{ - /* Do nothing, mk_pmd() does this part. */ - return pmd; -} - -static inline pmd_t pmd_mknotpresent(pmd_t pmd) -{ - return __pmd(pmd_val(pmd) & ~_PAGE_PRESENT); -} - -static inline pmd_t pmd_mksplitting(pmd_t pmd) -{ - return __pmd(pmd_val(pmd) | _PAGE_SPLITTING); -} - -#define __HAVE_ARCH_PMD_SAME -static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b) -{ - return (((pmd_val(pmd_a) ^ pmd_val(pmd_b)) & ~_PAGE_HPTEFLAGS) == 0); -} - -#define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS -extern int pmdp_set_access_flags(struct vm_area_struct *vma, - unsigned long address, pmd_t *pmdp, - pmd_t entry, int dirty); - -extern unsigned long pmd_hugepage_update(struct mm_struct *mm, - unsigned long addr, - pmd_t *pmdp, - unsigned long clr, - unsigned long set); - -static inline int __pmdp_test_and_clear_young(struct mm_struct *mm, - unsigned long addr, pmd_t *pmdp) -{ - unsigned long old; - - if ((pmd_val(*pmdp) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0) - return 0; - old = pmd_hugepage_update(mm, addr, pmdp, _PAGE_ACCESSED, 0); - return ((old & _PAGE_ACCESSED) != 0); -} - -#define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG -extern int pmdp_test_and_clear_young(struct vm_area_struct *vma, - unsigned long address, pmd_t *pmdp); -#define __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH -extern int pmdp_clear_flush_young(struct vm_area_struct *vma, - unsigned long address, pmd_t *pmdp); - -#define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR -extern pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm, - unsigned long addr, pmd_t *pmdp); - -#define __HAVE_ARCH_PMDP_SET_WRPROTECT -static inline void pmdp_set_wrprotect(struct mm_struct *mm, unsigned long addr, - pmd_t *pmdp) -{ - - if ((pmd_val(*pmdp) & _PAGE_RW) == 0) - return; - - pmd_hugepage_update(mm, addr, pmdp, _PAGE_RW, 0); -} - -#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH -extern void pmdp_splitting_flush(struct vm_area_struct *vma, - unsigned long address, pmd_t *pmdp); - -extern pmd_t pmdp_collapse_flush(struct vm_area_struct *vma, - unsigned long address, pmd_t *pmdp); -#define pmdp_collapse_flush pmdp_collapse_flush - -#define __HAVE_ARCH_PGTABLE_DEPOSIT -extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, - pgtable_t pgtable); -#define __HAVE_ARCH_PGTABLE_WITHDRAW -extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); - -#define __HAVE_ARCH_PMDP_INVALIDATE -extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, - pmd_t *pmdp); - -#define pmd_move_must_withdraw pmd_move_must_withdraw -struct spinlock; -static inline int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl, - struct spinlock *old_pmd_ptl) -{ - /* - * Archs like ppc64 use pgtable to store per pmd - * specific information. So when we switch the pmd, - * we should also withdraw and deposit the pgtable - */ - return true; -} -#endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_NOHASH_64_PGTABLE_H */ diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index c8822af10a587..8eaac81347fdb 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c @@ -429,6 +429,7 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn, local_irq_restore(flags); } +#ifdef CONFIG_TRANSPARENT_HUGEPAGE static void native_hugepage_invalidate(unsigned long vsid, unsigned long addr, unsigned char *hpte_slot_array, @@ -482,6 +483,15 @@ static void native_hugepage_invalidate(unsigned long vsid, } local_irq_restore(flags); } +#else +static void native_hugepage_invalidate(unsigned long vsid, + unsigned long addr, + unsigned char *hpte_slot_array, + int psize, int ssize, int local) +{ + WARN(1, "%s called without THP support\n", __func__); +} +#endif static inline int __hpte_actual_psize(unsigned int lp, int psize) { diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 3967e3cce03ee..d42dd289abfed 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -359,7 +359,7 @@ struct page *pud_page(pud_t pud) struct page *pmd_page(pmd_t pmd) { if (pmd_trans_huge(pmd) || pmd_huge(pmd)) - return pfn_to_page(pmd_pfn(pmd)); + return pte_page(pmd_pte(pmd)); return virt_to_page(pmd_page_vaddr(pmd)); } diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index b7a67e3d2201e..6d46547871aaa 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -396,6 +396,7 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long vpn, BUG_ON(lpar_rc != H_SUCCESS); } +#ifdef CONFIG_TRANSPARENT_HUGEPAGE /* * Limit iterations holding pSeries_lpar_tlbie_lock to 3. We also need * to make sure that we avoid bouncing the hypervisor tlbie lock. @@ -494,6 +495,15 @@ static void pSeries_lpar_hugepage_invalidate(unsigned long vsid, __pSeries_lpar_hugepage_invalidate(slot_array, vpn_array, index, psize, ssize); } +#else +static void pSeries_lpar_hugepage_invalidate(unsigned long vsid, + unsigned long addr, + unsigned char *hpte_slot_array, + int psize, int ssize, int local) +{ + WARN(1, "%s called without THP support\n", __func__); +} +#endif static void pSeries_lpar_hpte_removebolted(unsigned long ea, int psize, int ssize) -- GitLab From 6a119eae942c51ccf1091936c534bac12cae630e Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:54 +0530 Subject: [PATCH 1220/2855] powerpc/mm: Add a _PAGE_PTE bit For a pte entry we will have _PAGE_PTE set. Our pte page address have a minimum alignment requirement of HUGEPD_SHIFT_MASK + 1. We use the lower 7 bits to indicate hugepd. ie. For pmd and pgd we can find: 1) _PAGE_PTE set pte -> indicate PTE 2) bits [2..6] non zero -> indicate hugepd. They also encode the size. We skip bit 1 (_PAGE_PRESENT). 3) othewise pointer to next table. Acked-by: Scott Wood Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/hash-4k.h | 9 +++++--- arch/powerpc/include/asm/book3s/64/hash-64k.h | 23 ++++++++----------- arch/powerpc/include/asm/book3s/64/hash.h | 13 ++++++----- arch/powerpc/include/asm/book3s/64/pgtable.h | 3 +-- arch/powerpc/include/asm/pte-common.h | 5 ++++ arch/powerpc/mm/hugetlbpage.c | 4 ++-- arch/powerpc/mm/pgtable.c | 4 ++++ arch/powerpc/mm/pgtable_64.c | 7 +----- 8 files changed, 35 insertions(+), 33 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h index b4d25529d1798..e59832c946094 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-4k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h @@ -116,10 +116,13 @@ static inline int pgd_huge(pgd_t pgd) static inline int hugepd_ok(hugepd_t hpd) { /* - * hugepd pointer, bottom two bits == 00 and next 4 bits - * indicate size of table + * if it is not a pte and have hugepd shift mask + * set, then it is a hugepd directory pointer */ - return (((hpd.pd & 0x3) == 0x0) && ((hpd.pd & HUGEPD_SHIFT_MASK) != 0)); + if (!(hpd.pd & _PAGE_PTE) && + ((hpd.pd & HUGEPD_SHIFT_MASK) != 0)) + return true; + return false; } #define is_hugepd(hpd) (hugepd_ok(hpd)) #endif diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h index 7570677c11c3e..52110d7af6597 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h @@ -130,25 +130,25 @@ extern bool __rpte_sub_valid(real_pte_t rpte, unsigned long index); static inline int pmd_huge(pmd_t pmd) { /* - * leaf pte for huge page, bottom two bits != 00 + * leaf pte for huge page */ - return ((pmd_val(pmd) & 0x3) != 0x0); + return !!(pmd_val(pmd) & _PAGE_PTE); } static inline int pud_huge(pud_t pud) { /* - * leaf pte for huge page, bottom two bits != 00 + * leaf pte for huge page */ - return ((pud_val(pud) & 0x3) != 0x0); + return !!(pud_val(pud) & _PAGE_PTE); } static inline int pgd_huge(pgd_t pgd) { /* - * leaf pte for huge page, bottom two bits != 00 + * leaf pte for huge page */ - return ((pgd_val(pgd) & 0x3) != 0x0); + return !!(pgd_val(pgd) & _PAGE_PTE); } #define pgd_huge pgd_huge @@ -236,10 +236,8 @@ static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array, */ static inline int pmd_trans_huge(pmd_t pmd) { - /* - * leaf pte for huge page, bottom two bits != 00 - */ - return (pmd_val(pmd) & 0x3) && (pmd_val(pmd) & _PAGE_THP_HUGE); + return !!((pmd_val(pmd) & (_PAGE_PTE | _PAGE_THP_HUGE)) == + (_PAGE_PTE | _PAGE_THP_HUGE)); } static inline int pmd_trans_splitting(pmd_t pmd) @@ -251,10 +249,7 @@ static inline int pmd_trans_splitting(pmd_t pmd) static inline int pmd_large(pmd_t pmd) { - /* - * leaf pte for huge page, bottom two bits != 00 - */ - return ((pmd_val(pmd) & 0x3) != 0x0); + return !!(pmd_val(pmd) & _PAGE_PTE); } static inline pmd_t pmd_mknotpresent(pmd_t pmd) diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 42e1273adad1b..8b929e5317588 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -14,11 +14,12 @@ * We could create separate kernel read-only if we used the 3 PP bits * combinations that newer processors provide but we currently don't. */ -#define _PAGE_PRESENT 0x00001 /* software: pte contains a translation */ -#define _PAGE_USER 0x00002 /* matches one of the PP bits */ +#define _PAGE_PTE 0x00001 +#define _PAGE_PRESENT 0x00002 /* software: pte contains a translation */ #define _PAGE_BIT_SWAP_TYPE 2 -#define _PAGE_EXEC 0x00004 /* No execute on POWER4 and newer (we invert) */ -#define _PAGE_GUARDED 0x00008 +#define _PAGE_USER 0x00004 /* matches one of the PP bits */ +#define _PAGE_EXEC 0x00008 /* No execute on POWER4 and newer (we invert) */ +#define _PAGE_GUARDED 0x00010 /* We can derive Memory coherence from _PAGE_NO_CACHE */ #define _PAGE_COHERENT 0x0 #define _PAGE_NO_CACHE 0x00020 /* I: cache inhibit */ @@ -49,7 +50,7 @@ */ #define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | \ _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SPLITTING | \ - _PAGE_THP_HUGE) + _PAGE_THP_HUGE | _PAGE_PTE) #ifdef CONFIG_PPC_64K_PAGES #include @@ -135,7 +136,7 @@ * pgprot changes */ #define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \ - _PAGE_ACCESSED | _PAGE_SPECIAL) + _PAGE_ACCESSED | _PAGE_SPECIAL | _PAGE_PTE) /* * Mask of bits returned by pte_pgprot() */ diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index f2ace2cac7bbb..bb97b6a52b846 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -213,8 +213,7 @@ static inline int pmd_protnone(pmd_t pmd) static inline pmd_t pmd_mkhuge(pmd_t pmd) { - /* Do nothing, mk_pmd() does this part. */ - return pmd; + return __pmd(pmd_val(pmd) | (_PAGE_PTE | _PAGE_THP_HUGE)); } #define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h index 71537a319fc82..1ec67b0430657 100644 --- a/arch/powerpc/include/asm/pte-common.h +++ b/arch/powerpc/include/asm/pte-common.h @@ -40,6 +40,11 @@ #else #define _PAGE_RW 0 #endif + +#ifndef _PAGE_PTE +#define _PAGE_PTE 0 +#endif + #ifndef _PMD_PRESENT_MASK #define _PMD_PRESENT_MASK _PMD_PRESENT #endif diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index bc72e542a83ee..61b8b7ccea4f5 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -894,8 +894,8 @@ void flush_dcache_icache_hugepage(struct page *page) * We have 4 cases for pgds and pmds: * (1) invalid (all zeroes) * (2) pointer to next table, as normal; bottom 6 bits == 0 - * (3) leaf pte for huge page, bottom two bits != 00 - * (4) hugepd pointer, bottom two bits == 00, next 4 bits indicate size of table + * (3) leaf pte for huge page _PAGE_PTE set + * (4) hugepd pointer, _PAGE_PTE = 0 and bits [2..6] indicate size of table * * So long as we atomically load page table pointers we are safe against teardown, * we can follow the address down to the the page and take a ref on it. diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c index 83dfcb55ffef6..83dfd7925c72c 100644 --- a/arch/powerpc/mm/pgtable.c +++ b/arch/powerpc/mm/pgtable.c @@ -179,6 +179,10 @@ void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, */ VM_WARN_ON((pte_val(*ptep) & (_PAGE_PRESENT | _PAGE_USER)) == (_PAGE_PRESENT | _PAGE_USER)); + /* + * Add the pte bit when tryint set a pte + */ + pte = __pte(pte_val(pte) | _PAGE_PTE); /* Note: mm->context.id might not yet have been assigned as * this context might not have been activated yet when this diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index d42dd289abfed..ea6bc31debb05 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -765,13 +765,8 @@ static pmd_t pmd_set_protbits(pmd_t pmd, pgprot_t pgprot) pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot) { unsigned long pmdv; - /* - * For a valid pte, we would have _PAGE_PRESENT always - * set. We use this to check THP page at pmd level. - * leaf pte for huge page, bottom two bits != 00 - */ + pmdv = pfn << PTE_RPN_SHIFT; - pmdv |= _PAGE_THP_HUGE; return pmd_set_protbits(__pmd(pmdv), pgprot); } -- GitLab From 62607bc64c5cbb8d9b330da4be34c6d5302348af Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:55 +0530 Subject: [PATCH 1221/2855] powerpc/mm: Don't hardcode page table size pte and pmd table size are dependent on config items. Don't hard code the same. This make sure we use the right value when masking pmd entries and also while checking pmd_bad Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/hash-64k.h | 30 ++++++++++++++----- .../include/asm/nohash/64/pgtable-64k.h | 21 ++++++++++--- arch/powerpc/include/asm/pgalloc-64.h | 10 ------- arch/powerpc/mm/init_64.c | 4 --- 4 files changed, 40 insertions(+), 25 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h index 52110d7af6597..cca050aa1aa86 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h @@ -25,12 +25,6 @@ #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) -/* Bits to mask out from a PMD to get to the PTE page */ -/* PMDs point to PTE table fragments which are 4K aligned. */ -#define PMD_MASKED_BITS 0xfff -/* Bits to mask out from a PGD/PUD to get to the PMD page */ -#define PUD_MASKED_BITS 0x1ff - #define _PAGE_COMBO 0x00020000 /* this is a combo 4k page */ #define _PAGE_4K_PFN 0x00040000 /* PFN is for a single 4k page */ /* @@ -49,6 +43,24 @@ * of addressable physical space, or 46 bits for the special 4k PFNs. */ #define PTE_RPN_SHIFT (30) +/* + * we support 16 fragments per PTE page of 64K size. + */ +#define PTE_FRAG_NR 16 +/* + * We use a 2K PTE page fragment and another 2K for storing + * real_pte_t hash index + */ +#define PTE_FRAG_SIZE_SHIFT 12 +#define PTE_FRAG_SIZE (1UL << PTE_FRAG_SIZE_SHIFT) + +/* + * Bits to mask out from a PMD to get to the PTE page + * PMDs point to PTE table fragments which are PTE_FRAG_SIZE aligned. + */ +#define PMD_MASKED_BITS (PTE_FRAG_SIZE - 1) +/* Bits to mask out from a PGD/PUD to get to the PMD page */ +#define PUD_MASKED_BITS 0x1ff #ifndef __ASSEMBLY__ @@ -112,8 +124,12 @@ extern bool __rpte_sub_valid(real_pte_t rpte, unsigned long index); remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \ __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN))) -#define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE) +#define PTE_TABLE_SIZE PTE_FRAG_SIZE +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +#define PMD_TABLE_SIZE ((sizeof(pmd_t) << PMD_INDEX_SIZE) + (sizeof(unsigned long) << PMD_INDEX_SIZE)) +#else #define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE) +#endif #define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE) #define pgd_pte(pgd) (pud_pte(((pud_t){ pgd }))) diff --git a/arch/powerpc/include/asm/nohash/64/pgtable-64k.h b/arch/powerpc/include/asm/nohash/64/pgtable-64k.h index a44660d76096b..2217de6454d69 100644 --- a/arch/powerpc/include/asm/nohash/64/pgtable-64k.h +++ b/arch/powerpc/include/asm/nohash/64/pgtable-64k.h @@ -9,8 +9,19 @@ #define PUD_INDEX_SIZE 0 #define PGD_INDEX_SIZE 12 +/* + * we support 16 fragments per PTE page of 64K size. + */ +#define PTE_FRAG_NR 16 +/* + * We use a 2K PTE page fragment and another 2K for storing + * real_pte_t hash index + */ +#define PTE_FRAG_SIZE_SHIFT 12 +#define PTE_FRAG_SIZE (1UL << PTE_FRAG_SIZE_SHIFT) + #ifndef __ASSEMBLY__ -#define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE) +#define PTE_TABLE_SIZE PTE_FRAG_SIZE #define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE) #define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE) #endif /* __ASSEMBLY__ */ @@ -32,9 +43,11 @@ #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) -/* Bits to mask out from a PMD to get to the PTE page */ -/* PMDs point to PTE table fragments which are 4K aligned. */ -#define PMD_MASKED_BITS 0xfff +/* + * Bits to mask out from a PMD to get to the PTE page + * PMDs point to PTE table fragments which are PTE_FRAG_SIZE aligned. + */ +#define PMD_MASKED_BITS (PTE_FRAG_SIZE - 1) /* Bits to mask out from a PGD/PUD to get to the PMD page */ #define PUD_MASKED_BITS 0x1ff diff --git a/arch/powerpc/include/asm/pgalloc-64.h b/arch/powerpc/include/asm/pgalloc-64.h index d8cde71f6734a..69ef28a817335 100644 --- a/arch/powerpc/include/asm/pgalloc-64.h +++ b/arch/powerpc/include/asm/pgalloc-64.h @@ -163,16 +163,6 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table, } #else /* if CONFIG_PPC_64K_PAGES */ -/* - * we support 16 fragments per PTE page. - */ -#define PTE_FRAG_NR 16 -/* - * We use a 2K PTE page fragment and another 2K for storing - * real_pte_t hash index - */ -#define PTE_FRAG_SIZE_SHIFT 12 -#define PTE_FRAG_SIZE (2 * PTRS_PER_PTE * sizeof(pte_t)) extern pte_t *page_table_alloc(struct mm_struct *, unsigned long, int); extern void page_table_free(struct mm_struct *, unsigned long *, int); diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index d747dd7bc90b7..379a6a90644be 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -87,11 +87,7 @@ static void pgd_ctor(void *addr) static void pmd_ctor(void *addr) { -#ifdef CONFIG_TRANSPARENT_HUGEPAGE - memset(addr, 0, PMD_TABLE_SIZE * 2); -#else memset(addr, 0, PMD_TABLE_SIZE); -#endif } struct kmem_cache *pgtable_cache[MAX_PGTABLE_INDEX_SIZE]; -- GitLab From 4d9057c39aceb3a94ccb6005f4433a0105e60521 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:56 +0530 Subject: [PATCH 1222/2855] powerpc/mm: Don't hardcode the hash pte slot shift Use the #define instead of open-coding the same Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/hash-64k.h | 2 +- arch/powerpc/include/asm/book3s/64/pgtable.h | 2 +- arch/powerpc/include/asm/nohash/64/pgtable.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h index cca050aa1aa86..9f9942998587c 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h @@ -94,7 +94,7 @@ static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index) { if ((pte_val(rpte.pte) & _PAGE_COMBO)) return (rpte.hidx >> (index<<2)) & 0xf; - return (pte_val(rpte.pte) >> 12) & 0xf; + return (pte_val(rpte.pte) >> _PAGE_F_GIX_SHIFT) & 0xf; } #define __rpte_to_pte(r) ((r).pte) diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index bb97b6a52b846..a2d4e0e370676 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -50,7 +50,7 @@ #define __real_pte(e,p) (e) #define __rpte_to_pte(r) (__pte(r)) #endif -#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >> 12) +#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >>_PAGE_F_GIX_SHIFT) #define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ do { \ diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h index d635a924d652b..03c226965b466 100644 --- a/arch/powerpc/include/asm/nohash/64/pgtable.h +++ b/arch/powerpc/include/asm/nohash/64/pgtable.h @@ -121,7 +121,7 @@ #define __real_pte(e,p) (e) #define __rpte_to_pte(r) (__pte(r)) #endif -#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >> 12) +#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >> _PAGE_F_GIX_SHIFT) #define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ do { \ -- GitLab From cc50380db32771af61201cff39da1043b90f2a6d Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:57 +0530 Subject: [PATCH 1223/2855] powerpc/nohash: Update 64K nohash config to have 32 pte fragement They don't need to track 4k subpage slot details and hence don't need second half of pgtable_t. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/nohash/64/pgtable-64k.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/nohash/64/pgtable-64k.h b/arch/powerpc/include/asm/nohash/64/pgtable-64k.h index 2217de6454d69..570fb30be21c0 100644 --- a/arch/powerpc/include/asm/nohash/64/pgtable-64k.h +++ b/arch/powerpc/include/asm/nohash/64/pgtable-64k.h @@ -10,14 +10,14 @@ #define PGD_INDEX_SIZE 12 /* - * we support 16 fragments per PTE page of 64K size. + * we support 32 fragments per PTE page of 64K size */ -#define PTE_FRAG_NR 16 +#define PTE_FRAG_NR 32 /* * We use a 2K PTE page fragment and another 2K for storing * real_pte_t hash index */ -#define PTE_FRAG_SIZE_SHIFT 12 +#define PTE_FRAG_SIZE_SHIFT 11 #define PTE_FRAG_SIZE (1UL << PTE_FRAG_SIZE_SHIFT) #ifndef __ASSEMBLY__ -- GitLab From 45949ebe6c748cba93c1dd6ab9d03190f862ecf7 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:58 +0530 Subject: [PATCH 1224/2855] powerpc/nohash: we don't use real_pte_t for nohash Remove the related functions and #defines Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/nohash/64/pgtable.h | 33 -------------------- 1 file changed, 33 deletions(-) diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h index 03c226965b466..b9f734dd5b81c 100644 --- a/arch/powerpc/include/asm/nohash/64/pgtable.h +++ b/arch/powerpc/include/asm/nohash/64/pgtable.h @@ -106,39 +106,6 @@ #endif /* CONFIG_PPC_MM_SLICES */ #ifndef __ASSEMBLY__ - -/* - * This is the default implementation of various PTE accessors, it's - * used in all cases except Book3S with 64K pages where we have a - * concept of sub-pages - */ -#ifndef __real_pte - -#ifdef CONFIG_STRICT_MM_TYPECHECKS -#define __real_pte(e,p) ((real_pte_t){(e)}) -#define __rpte_to_pte(r) ((r).pte) -#else -#define __real_pte(e,p) (e) -#define __rpte_to_pte(r) (__pte(r)) -#endif -#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >> _PAGE_F_GIX_SHIFT) - -#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ - do { \ - index = 0; \ - shift = mmu_psize_defs[psize].shift; \ - -#define pte_iterate_hashed_end() } while(0) - -/* - * We expect this to be called only for user addresses or kernel virtual - * addresses other than the linear mapping. - */ -#define pte_pagesize_index(mm, addr, pte) MMU_PAGE_4K - -#endif /* __real_pte */ - - /* pte_clear moved to later in this file */ #define PMD_BAD_BITS (PTE_TABLE_SIZE-1) -- GitLab From 4ad90c864989337e7946f456478b6417325689d0 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:06:59 +0530 Subject: [PATCH 1225/2855] powerpc/mm: Use H_READ with H_READ_4 This will bulk read 4 hash pte slot entries and should reduce the loop Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/plpar_wrappers.h | 17 +++++++ arch/powerpc/platforms/pseries/lpar.c | 54 +++++++++++------------ 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/arch/powerpc/include/asm/plpar_wrappers.h b/arch/powerpc/include/asm/plpar_wrappers.h index 67859edbf8fd3..1b394247afc2d 100644 --- a/arch/powerpc/include/asm/plpar_wrappers.h +++ b/arch/powerpc/include/asm/plpar_wrappers.h @@ -201,6 +201,23 @@ static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex, return rc; } +/* + * ptes must be 8*sizeof(unsigned long) + */ +static inline long plpar_pte_read_4(unsigned long flags, unsigned long ptex, + unsigned long *ptes) + +{ + long rc; + unsigned long retbuf[PLPAR_HCALL9_BUFSIZE]; + + rc = plpar_hcall9(H_READ, retbuf, flags | H_READ_4, ptex); + + memcpy(ptes, retbuf, 8*sizeof(unsigned long)); + + return rc; +} + /* * plpar_pte_read_4_raw can be called in real mode. * ptes must be 8*sizeof(unsigned long) diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 6d46547871aaa..477290ad855e5 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -315,48 +315,48 @@ static long pSeries_lpar_hpte_updatepp(unsigned long slot, return 0; } -static unsigned long pSeries_lpar_hpte_getword0(unsigned long slot) +static long __pSeries_lpar_hpte_find(unsigned long want_v, unsigned long hpte_group) { - unsigned long dword0; - unsigned long lpar_rc; - unsigned long dummy_word1; - unsigned long flags; + long lpar_rc; + unsigned long i, j; + struct { + unsigned long pteh; + unsigned long ptel; + } ptes[4]; - /* Read 1 pte at a time */ - /* Do not need RPN to logical page translation */ - /* No cross CEC PFT access */ - flags = 0; + for (i = 0; i < HPTES_PER_GROUP; i += 4, hpte_group += 4) { - lpar_rc = plpar_pte_read(flags, slot, &dword0, &dummy_word1); + lpar_rc = plpar_pte_read_4(0, hpte_group, (void *)ptes); + if (lpar_rc != H_SUCCESS) + continue; - BUG_ON(lpar_rc != H_SUCCESS); + for (j = 0; j < 4; j++) { + if (HPTE_V_COMPARE(ptes[j].pteh, want_v) && + (ptes[j].pteh & HPTE_V_VALID)) + return i + j; + } + } - return dword0; + return -1; } static long pSeries_lpar_hpte_find(unsigned long vpn, int psize, int ssize) { - unsigned long hash; - unsigned long i; long slot; - unsigned long want_v, hpte_v; + unsigned long hash; + unsigned long want_v; + unsigned long hpte_group; hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, ssize); want_v = hpte_encode_avpn(vpn, psize, ssize); /* Bolted entries are always in the primary group */ - slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; - for (i = 0; i < HPTES_PER_GROUP; i++) { - hpte_v = pSeries_lpar_hpte_getword0(slot); - - if (HPTE_V_COMPARE(hpte_v, want_v) && (hpte_v & HPTE_V_VALID)) - /* HPTE matches */ - return slot; - ++slot; - } - - return -1; -} + hpte_group = (hash & htab_hash_mask) * HPTES_PER_GROUP; + slot = __pSeries_lpar_hpte_find(want_v, hpte_group); + if (slot < 0) + return -1; + return hpte_group + slot; +} static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp, unsigned long ea, -- GitLab From 4dcbd88eb600d52ce52a75c5075c2eff2f6849e6 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 1 Dec 2015 09:07:00 +0530 Subject: [PATCH 1226/2855] powerpc/mm: Don't open code pgtable_t size The slot information of base page size hash pte is stored in the pgtable_t w.r.t transparent hugepage. We need to make sure we don't index beyond pgtable_t size. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/mm/hugepage-hash64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/mm/hugepage-hash64.c b/arch/powerpc/mm/hugepage-hash64.c index 1f666de0110ac..baf1301ded0cc 100644 --- a/arch/powerpc/mm/hugepage-hash64.c +++ b/arch/powerpc/mm/hugepage-hash64.c @@ -71,7 +71,7 @@ int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid, */ shift = mmu_psize_defs[psize].shift; index = (ea & ~HPAGE_PMD_MASK) >> shift; - BUG_ON(index >= 4096); + BUG_ON(index >= PTE_FRAG_SIZE); vpn = hpt_vpn(ea, vsid, ssize); hpte_slot_array = get_hpte_slot_array(pmdp); -- GitLab From 49e9cf3f0c04bf76ffa59242254110309554861d Mon Sep 17 00:00:00 2001 From: Boqun Feng Date: Mon, 2 Nov 2015 09:30:31 +0800 Subject: [PATCH 1227/2855] powerpc: Make value-returning atomics fully ordered According to memory-barriers.txt: > Any atomic operation that modifies some state in memory and returns > information about the state (old or new) implies an SMP-conditional > general memory barrier (smp_mb()) on each side of the actual > operation ... Which mean these operations should be fully ordered. However on PPC, PPC_ATOMIC_ENTRY_BARRIER is the barrier before the actual operation, which is currently "lwsync" if SMP=y. The leading "lwsync" can not guarantee fully ordered atomics, according to Paul Mckenney: https://lkml.org/lkml/2015/10/14/970 To fix this, we define PPC_ATOMIC_ENTRY_BARRIER as "sync" to guarantee the fully-ordered semantics. This also makes futex atomics fully ordered, which can avoid possible memory ordering problems if userspace code relies on futex system call for fully ordered semantics. Fixes: b97021f85517 ("powerpc: Fix atomic_xxx_return barrier semantics") Cc: stable@vger.kernel.org # 3.2+ Signed-off-by: Boqun Feng Reviewed-by: Paul E. McKenney Acked-by: Peter Zijlstra (Intel) Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/synch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/synch.h b/arch/powerpc/include/asm/synch.h index e682a7143edb7..c50868681f9ea 100644 --- a/arch/powerpc/include/asm/synch.h +++ b/arch/powerpc/include/asm/synch.h @@ -44,7 +44,7 @@ static inline void isync(void) MAKE_LWSYNC_SECTION_ENTRY(97, __lwsync_fixup); #define PPC_ACQUIRE_BARRIER "\n" stringify_in_c(__PPC_ACQUIRE_BARRIER) #define PPC_RELEASE_BARRIER stringify_in_c(LWSYNC) "\n" -#define PPC_ATOMIC_ENTRY_BARRIER "\n" stringify_in_c(LWSYNC) "\n" +#define PPC_ATOMIC_ENTRY_BARRIER "\n" stringify_in_c(sync) "\n" #define PPC_ATOMIC_EXIT_BARRIER "\n" stringify_in_c(sync) "\n" #else #define PPC_ACQUIRE_BARRIER -- GitLab From 81d7a3294de7e9828310bbf986a67246b13fa01e Mon Sep 17 00:00:00 2001 From: Boqun Feng Date: Mon, 2 Nov 2015 09:30:32 +0800 Subject: [PATCH 1228/2855] powerpc: Make {cmp}xchg* and their atomic_ versions fully ordered According to memory-barriers.txt, xchg*, cmpxchg* and their atomic_ versions all need to be fully ordered, however they are now just RELEASE+ACQUIRE, which are not fully ordered. So also replace PPC_RELEASE_BARRIER and PPC_ACQUIRE_BARRIER with PPC_ATOMIC_ENTRY_BARRIER and PPC_ATOMIC_EXIT_BARRIER in __{cmp,}xchg_{u32,u64} respectively to guarantee fully ordered semantics of atomic{,64}_{cmp,}xchg() and {cmp,}xchg(), as a complement of commit b97021f85517 ("powerpc: Fix atomic_xxx_return barrier semantics") This patch depends on patch "powerpc: Make value-returning atomics fully ordered" for PPC_ATOMIC_ENTRY_BARRIER definition. Cc: stable@vger.kernel.org # 3.2+ Signed-off-by: Boqun Feng Reviewed-by: Paul E. McKenney Acked-by: Peter Zijlstra (Intel) Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/cmpxchg.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/include/asm/cmpxchg.h b/arch/powerpc/include/asm/cmpxchg.h index ad6263cffb0fd..d1a8d93cccfd4 100644 --- a/arch/powerpc/include/asm/cmpxchg.h +++ b/arch/powerpc/include/asm/cmpxchg.h @@ -18,12 +18,12 @@ __xchg_u32(volatile void *p, unsigned long val) unsigned long prev; __asm__ __volatile__( - PPC_RELEASE_BARRIER + PPC_ATOMIC_ENTRY_BARRIER "1: lwarx %0,0,%2 \n" PPC405_ERR77(0,%2) " stwcx. %3,0,%2 \n\ bne- 1b" - PPC_ACQUIRE_BARRIER + PPC_ATOMIC_EXIT_BARRIER : "=&r" (prev), "+m" (*(volatile unsigned int *)p) : "r" (p), "r" (val) : "cc", "memory"); @@ -61,12 +61,12 @@ __xchg_u64(volatile void *p, unsigned long val) unsigned long prev; __asm__ __volatile__( - PPC_RELEASE_BARRIER + PPC_ATOMIC_ENTRY_BARRIER "1: ldarx %0,0,%2 \n" PPC405_ERR77(0,%2) " stdcx. %3,0,%2 \n\ bne- 1b" - PPC_ACQUIRE_BARRIER + PPC_ATOMIC_EXIT_BARRIER : "=&r" (prev), "+m" (*(volatile unsigned long *)p) : "r" (p), "r" (val) : "cc", "memory"); @@ -151,14 +151,14 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new) unsigned int prev; __asm__ __volatile__ ( - PPC_RELEASE_BARRIER + PPC_ATOMIC_ENTRY_BARRIER "1: lwarx %0,0,%2 # __cmpxchg_u32\n\ cmpw 0,%0,%3\n\ bne- 2f\n" PPC405_ERR77(0,%2) " stwcx. %4,0,%2\n\ bne- 1b" - PPC_ACQUIRE_BARRIER + PPC_ATOMIC_EXIT_BARRIER "\n\ 2:" : "=&r" (prev), "+m" (*p) @@ -197,13 +197,13 @@ __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new) unsigned long prev; __asm__ __volatile__ ( - PPC_RELEASE_BARRIER + PPC_ATOMIC_ENTRY_BARRIER "1: ldarx %0,0,%2 # __cmpxchg_u64\n\ cmpd 0,%0,%3\n\ bne- 2f\n\ stdcx. %4,0,%2\n\ bne- 1b" - PPC_ACQUIRE_BARRIER + PPC_ATOMIC_EXIT_BARRIER "\n\ 2:" : "=&r" (prev), "+m" (*p) -- GitLab From 99b809d7bdd17de7a68f1625a8973052c8311657 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 8 Dec 2015 10:37:45 +0100 Subject: [PATCH 1229/2855] i2c: document generic DT bindings for timing parameters Also, sort the properties alphabetically and make indentation consistent. Wording largely taken from i2c-rk3x.txt, thanks guys! Only "i2c-scl-internal-delay-ns" is new, the rest is used by two drivers already and was documented in their driver binding documentation. Signed-off-by: Wolfram Sang Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c.txt | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c.txt b/Documentation/devicetree/bindings/i2c/i2c.txt index 8a99150ac3a7f..a00219f5ee073 100644 --- a/Documentation/devicetree/bindings/i2c/i2c.txt +++ b/Documentation/devicetree/bindings/i2c/i2c.txt @@ -29,12 +29,33 @@ Optional properties These properties may not be supported by all drivers. However, if a driver wants to support one of the below features, it should adapt the bindings below. -- clock-frequency - frequency of bus clock in Hz. -- wakeup-source - device can be used as a wakeup source. +- clock-frequency + frequency of bus clock in Hz. -- interrupts - interrupts used by the device. -- interrupt-names - "irq" and "wakeup" names are recognized by I2C core, - other names are left to individual drivers. +- i2c-scl-falling-time-ns + Number of nanoseconds the SCL signal takes to fall; t(f) in the I2C + specification. + +- i2c-scl-internal-delay-ns + Number of nanoseconds the IP core additionally needs to setup SCL. + +- i2c-scl-rising-time-ns + Number of nanoseconds the SCL signal takes to rise; t(r) in the I2C + specification. + +- i2c-sda-falling-time-ns + Number of nanoseconds the SDA signal takes to fall; t(f) in the I2C + specification. + +- interrupts + interrupts used by the device. + +- interrupt-names + "irq" and "wakeup" names are recognized by I2C core, other names are + left to individual drivers. + +- wakeup-source + device can be used as a wakeup source. Binding may contain optional "interrupts" property, describing interrupts used by the device. I2C core will assign "irq" interrupt (or the very first -- GitLab From 801c0b2c4db3a33d56b3e19240df7b897e5bbfbc Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Fri, 20 Nov 2015 15:15:32 +1100 Subject: [PATCH 1230/2855] powerpc: Print MSR TM bits in oops messages Print MSR TM bits in oops messages. This appends them to the end like this: MSR: 8000000502823031 You get the TM[] only if at least one TM MSR bit is set. Inside the TM[], E means Enabled (bit 32), S means Suspended (bit 33), and T means Transactional (bit 34) If no bits are set, you get no TM[] output. Include rework of printbits() to handle this case. Signed-off-by: Michael Neuling Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/process.c | 51 +++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 6f76f25c3ee8b..ab9373bfabdae 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1033,10 +1033,12 @@ static void show_instructions(struct pt_regs *regs) printk("\n"); } -static struct regbit { +struct regbit { unsigned long bit; const char *name; -} msr_bits[] = { +}; + +static struct regbit msr_bits[] = { #if defined(CONFIG_PPC64) && !defined(CONFIG_BOOKE) {MSR_SF, "SF"}, {MSR_HV, "HV"}, @@ -1066,16 +1068,49 @@ static struct regbit { {0, NULL} }; -static void printbits(unsigned long val, struct regbit *bits) +static void print_bits(unsigned long val, struct regbit *bits, const char *sep) { - const char *sep = ""; + const char *s = ""; - printk("<"); for (; bits->bit; ++bits) if (val & bits->bit) { - printk("%s%s", sep, bits->name); - sep = ","; + printk("%s%s", s, bits->name); + s = sep; } +} + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +static struct regbit msr_tm_bits[] = { + {MSR_TS_T, "T"}, + {MSR_TS_S, "S"}, + {MSR_TM, "E"}, + {0, NULL} +}; + +static void print_tm_bits(unsigned long val) +{ +/* + * This only prints something if at least one of the TM bit is set. + * Inside the TM[], the output means: + * E: Enabled (bit 32) + * S: Suspended (bit 33) + * T: Transactional (bit 34) + */ + if (val & (MSR_TM | MSR_TS_S | MSR_TS_T)) { + printk(",TM["); + print_bits(val, msr_tm_bits, ""); + printk("]"); + } +} +#else +static void print_tm_bits(unsigned long val) {} +#endif + +static void print_msr_bits(unsigned long val) +{ + printk("<"); + print_bits(val, msr_bits, ","); + print_tm_bits(val); printk(">"); } @@ -1100,7 +1135,7 @@ void show_regs(struct pt_regs * regs) printk("REGS: %p TRAP: %04lx %s (%s)\n", regs, regs->trap, print_tainted(), init_utsname()->release); printk("MSR: "REG" ", regs->msr); - printbits(regs->msr, msr_bits); + print_msr_bits(regs->msr); printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer); trap = TRAP(regs); if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR)) -- GitLab From fcb45ec074725baeb3aaa1b1854b9f44c3eebacf Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 24 Nov 2015 13:05:38 +1100 Subject: [PATCH 1231/2855] selftests/powerpc: Move get_auxv_entry() into utils.c This doesn't really belong in harness.c, it's a helper function. So move it into utils.c. Signed-off-by: Michael Ellerman --- tools/testing/selftests/powerpc/harness.c | 43 -------------- tools/testing/selftests/powerpc/pmu/Makefile | 2 + .../selftests/powerpc/pmu/ebb/Makefile | 3 +- tools/testing/selftests/powerpc/tm/Makefile | 2 +- tools/testing/selftests/powerpc/utils.c | 58 +++++++++++++++++++ 5 files changed, 63 insertions(+), 45 deletions(-) create mode 100644 tools/testing/selftests/powerpc/utils.c diff --git a/tools/testing/selftests/powerpc/harness.c b/tools/testing/selftests/powerpc/harness.c index f7997affd1436..52f9be7f61f02 100644 --- a/tools/testing/selftests/powerpc/harness.c +++ b/tools/testing/selftests/powerpc/harness.c @@ -116,46 +116,3 @@ int test_harness(int (test_function)(void), char *name) return rc; } - -static char auxv[4096]; - -void *get_auxv_entry(int type) -{ - ElfW(auxv_t) *p; - void *result; - ssize_t num; - int fd; - - fd = open("/proc/self/auxv", O_RDONLY); - if (fd == -1) { - perror("open"); - return NULL; - } - - result = NULL; - - num = read(fd, auxv, sizeof(auxv)); - if (num < 0) { - perror("read"); - goto out; - } - - if (num > sizeof(auxv)) { - printf("Overflowed auxv buffer\n"); - goto out; - } - - p = (ElfW(auxv_t) *)auxv; - - while (p->a_type != AT_NULL) { - if (p->a_type == type) { - result = (void *)p->a_un.a_val; - break; - } - - p++; - } -out: - close(fd); - return result; -} diff --git a/tools/testing/selftests/powerpc/pmu/Makefile b/tools/testing/selftests/powerpc/pmu/Makefile index a9099d9f8f39e..50326cbb372d6 100644 --- a/tools/testing/selftests/powerpc/pmu/Makefile +++ b/tools/testing/selftests/powerpc/pmu/Makefile @@ -12,6 +12,8 @@ $(TEST_PROGS): $(EXTRA_SOURCES) count_instructions: loop.S count_instructions.c $(EXTRA_SOURCES) $(CC) $(CFLAGS) -m64 -o $@ $^ +per_event_excludes: ../utils.c + include ../../lib.mk DEFAULT_RUN_TESTS := $(RUN_TESTS) diff --git a/tools/testing/selftests/powerpc/pmu/ebb/Makefile b/tools/testing/selftests/powerpc/pmu/ebb/Makefile index 5cdc9dbf2b279..8d2279c4bb4b6 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/Makefile +++ b/tools/testing/selftests/powerpc/pmu/ebb/Makefile @@ -18,7 +18,8 @@ TEST_PROGS := reg_access_test event_attributes_test cycles_test \ all: $(TEST_PROGS) -$(TEST_PROGS): ../../harness.c ../event.c ../lib.c ebb.c ebb_handler.S trace.c busy_loop.S +$(TEST_PROGS): ../../harness.c ../../utils.c ../event.c ../lib.c \ + ebb.c ebb_handler.S trace.c busy_loop.S instruction_count_test: ../loop.S diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile index 4bea62a319dca..e7b9be7947c88 100644 --- a/tools/testing/selftests/powerpc/tm/Makefile +++ b/tools/testing/selftests/powerpc/tm/Makefile @@ -4,7 +4,7 @@ all: $(TEST_PROGS) $(TEST_PROGS): ../harness.c -tm-syscall: tm-syscall-asm.S +tm-syscall: tm-syscall-asm.S ../utils.c tm-syscall: CFLAGS += -mhtm -I../../../../../usr/include include ../../lib.mk diff --git a/tools/testing/selftests/powerpc/utils.c b/tools/testing/selftests/powerpc/utils.c new file mode 100644 index 0000000000000..536113add3800 --- /dev/null +++ b/tools/testing/selftests/powerpc/utils.c @@ -0,0 +1,58 @@ +/* + * Copyright 2013-2015, Michael Ellerman, IBM Corp. + * Licensed under GPLv2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" + +static char auxv[4096]; + +void *get_auxv_entry(int type) +{ + ElfW(auxv_t) *p; + void *result; + ssize_t num; + int fd; + + fd = open("/proc/self/auxv", O_RDONLY); + if (fd == -1) { + perror("open"); + return NULL; + } + + result = NULL; + + num = read(fd, auxv, sizeof(auxv)); + if (num < 0) { + perror("read"); + goto out; + } + + if (num > sizeof(auxv)) { + printf("Overflowed auxv buffer\n"); + goto out; + } + + p = (ElfW(auxv_t) *)auxv; + + while (p->a_type != AT_NULL) { + if (p->a_type == type) { + result = (void *)p->a_un.a_val; + break; + } + + p++; + } +out: + close(fd); + return result; +} -- GitLab From ede8ef3f824ea6e853a5e4b27467f583cdaa314e Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 24 Nov 2015 13:05:39 +1100 Subject: [PATCH 1232/2855] selftests/powerpc: Add have_hwcap2() helper We already do this twice and want to add another so add a helper. Signed-off-by: Michael Ellerman --- tools/testing/selftests/powerpc/pmu/ebb/ebb.c | 3 +-- tools/testing/selftests/powerpc/tm/tm-syscall.c | 3 +-- tools/testing/selftests/powerpc/utils.h | 6 ++++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb.c b/tools/testing/selftests/powerpc/pmu/ebb/ebb.c index 9729d9f902187..e67452f1bcffd 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/ebb.c +++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb.c @@ -13,7 +13,6 @@ #include #include #include -#include #include "trace.h" #include "reg.h" @@ -324,7 +323,7 @@ bool ebb_is_supported(void) { #ifdef PPC_FEATURE2_EBB /* EBB requires at least POWER8 */ - return ((long)get_auxv_entry(AT_HWCAP2) & PPC_FEATURE2_EBB); + return have_hwcap2(PPC_FEATURE2_EBB); #else return false; #endif diff --git a/tools/testing/selftests/powerpc/tm/tm-syscall.c b/tools/testing/selftests/powerpc/tm/tm-syscall.c index e835bf7ec7aed..d7256b79ec4c9 100644 --- a/tools/testing/selftests/powerpc/tm/tm-syscall.c +++ b/tools/testing/selftests/powerpc/tm/tm-syscall.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -80,7 +79,7 @@ pid_t getppid_tm(bool suspend) static inline bool have_htm_nosc(void) { #ifdef PPC_FEATURE2_HTM_NOSC - return ((long)get_auxv_entry(AT_HWCAP2) & PPC_FEATURE2_HTM_NOSC); + return have_hwcap2(PPC_FEATURE2_HTM_NOSC); #else printf("PPC_FEATURE2_HTM_NOSC not defined, can't check AT_HWCAP2\n"); return false; diff --git a/tools/testing/selftests/powerpc/utils.h b/tools/testing/selftests/powerpc/utils.h index b7d41086bb0a7..fbf2bf530e50e 100644 --- a/tools/testing/selftests/powerpc/utils.h +++ b/tools/testing/selftests/powerpc/utils.h @@ -8,6 +8,7 @@ #include #include +#include /* Avoid headaches with PRI?64 - just use %ll? always */ typedef unsigned long long u64; @@ -22,6 +23,11 @@ typedef uint8_t u8; int test_harness(int (test_function)(void), char *name); extern void *get_auxv_entry(int type); +static inline bool have_hwcap2(unsigned long ftr2) +{ + return ((unsigned long)get_auxv_entry(AT_HWCAP2) & ftr2) == ftr2; +} + /* Yes, this is evil */ #define FAIL_IF(x) \ do { \ -- GitLab From 34dc8b279dc5dd3ce863298056989bdd7f4979c8 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 24 Nov 2015 13:05:40 +1100 Subject: [PATCH 1233/2855] selftests/powerpc: Move TM helpers into tm.h Move have_htm_nosc() into a new tm.h, and add a new helper, have_htm() which we'll use in the next patch. Signed-off-by: Michael Ellerman --- .../testing/selftests/powerpc/tm/tm-syscall.c | 12 +------ tools/testing/selftests/powerpc/tm/tm.h | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 tools/testing/selftests/powerpc/tm/tm.h diff --git a/tools/testing/selftests/powerpc/tm/tm-syscall.c b/tools/testing/selftests/powerpc/tm/tm-syscall.c index d7256b79ec4c9..60560cb20e380 100644 --- a/tools/testing/selftests/powerpc/tm/tm-syscall.c +++ b/tools/testing/selftests/powerpc/tm/tm-syscall.c @@ -13,11 +13,11 @@ #include #include #include -#include #include #include #include "utils.h" +#include "tm.h" extern int getppid_tm_active(void); extern int getppid_tm_suspended(void); @@ -76,16 +76,6 @@ pid_t getppid_tm(bool suspend) exit(-1); } -static inline bool have_htm_nosc(void) -{ -#ifdef PPC_FEATURE2_HTM_NOSC - return have_hwcap2(PPC_FEATURE2_HTM_NOSC); -#else - printf("PPC_FEATURE2_HTM_NOSC not defined, can't check AT_HWCAP2\n"); - return false; -#endif -} - int tm_syscall(void) { unsigned count = 0; diff --git a/tools/testing/selftests/powerpc/tm/tm.h b/tools/testing/selftests/powerpc/tm/tm.h new file mode 100644 index 0000000000000..24144b25772cf --- /dev/null +++ b/tools/testing/selftests/powerpc/tm/tm.h @@ -0,0 +1,34 @@ +/* + * Copyright 2015, Michael Ellerman, IBM Corp. + * Licensed under GPLv2. + */ + +#ifndef _SELFTESTS_POWERPC_TM_TM_H +#define _SELFTESTS_POWERPC_TM_TM_H + +#include +#include + +#include "../utils.h" + +static inline bool have_htm(void) +{ +#ifdef PPC_FEATURE2_HTM + return have_hwcap2(PPC_FEATURE2_HTM); +#else + printf("PPC_FEATURE2_HTM not defined, can't check AT_HWCAP2\n"); + return false; +#endif +} + +static inline bool have_htm_nosc(void) +{ +#ifdef PPC_FEATURE2_HTM_NOSC + return have_hwcap2(PPC_FEATURE2_HTM_NOSC); +#else + printf("PPC_FEATURE2_HTM_NOSC not defined, can't check AT_HWCAP2\n"); + return false; +#endif +} + +#endif /* _SELFTESTS_POWERPC_TM_TM_H */ -- GitLab From b319ee8445961c5f7b2fd199c0ef99c418ee2d4a Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 2 Dec 2015 16:00:04 +1100 Subject: [PATCH 1234/2855] selftests/powerpc: Skip tm-resched-dscr if we don't have TM Signed-off-by: Michael Ellerman --- tools/testing/selftests/powerpc/tm/Makefile | 4 ++-- tools/testing/selftests/powerpc/tm/tm-resched-dscr.c | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile index e7b9be7947c88..63b55d01da356 100644 --- a/tools/testing/selftests/powerpc/tm/Makefile +++ b/tools/testing/selftests/powerpc/tm/Makefile @@ -2,9 +2,9 @@ TEST_PROGS := tm-resched-dscr tm-syscall all: $(TEST_PROGS) -$(TEST_PROGS): ../harness.c +$(TEST_PROGS): ../harness.c ../utils.c -tm-syscall: tm-syscall-asm.S ../utils.c +tm-syscall: tm-syscall-asm.S tm-syscall: CFLAGS += -mhtm -I../../../../../usr/include include ../../lib.mk diff --git a/tools/testing/selftests/powerpc/tm/tm-resched-dscr.c b/tools/testing/selftests/powerpc/tm/tm-resched-dscr.c index 42d4c8caad813..8fde93d6021f6 100644 --- a/tools/testing/selftests/powerpc/tm/tm-resched-dscr.c +++ b/tools/testing/selftests/powerpc/tm/tm-resched-dscr.c @@ -29,6 +29,7 @@ #include #include "utils.h" +#include "tm.h" #define TBEGIN ".long 0x7C00051D ;" #define TEND ".long 0x7C00055D ;" @@ -42,6 +43,8 @@ int test_body(void) { uint64_t rv, dscr1 = 1, dscr2, texasr; + SKIP_IF(!have_htm()); + printf("Check DSCR TM context switch: "); fflush(stdout); for (;;) { -- GitLab From 25007a69e852389985ee98235e76d740d4821c6c Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Fri, 20 Nov 2015 15:15:33 +1100 Subject: [PATCH 1235/2855] selftests/powerpc: Add TM signal return test Test the kernel's signal return code to ensure that it doesn't crash when both the transactional and suspend MSR bits are set in the signal context. Signed-off-by: Michael Neuling Tested-by: Anshuman Khandual [mpe: Skip if we don't have TM] Signed-off-by: Michael Ellerman --- tools/testing/selftests/powerpc/tm/.gitignore | 1 + tools/testing/selftests/powerpc/tm/Makefile | 2 +- .../selftests/powerpc/tm/tm-signal-msr-resv.c | 74 +++++++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c diff --git a/tools/testing/selftests/powerpc/tm/.gitignore b/tools/testing/selftests/powerpc/tm/.gitignore index 2699635d2cd93..61c318fdace4e 100644 --- a/tools/testing/selftests/powerpc/tm/.gitignore +++ b/tools/testing/selftests/powerpc/tm/.gitignore @@ -1,2 +1,3 @@ tm-resched-dscr tm-syscall +tm-signal-msr-resv diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile index 63b55d01da356..c6b4ca8b2812b 100644 --- a/tools/testing/selftests/powerpc/tm/Makefile +++ b/tools/testing/selftests/powerpc/tm/Makefile @@ -1,4 +1,4 @@ -TEST_PROGS := tm-resched-dscr tm-syscall +TEST_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv all: $(TEST_PROGS) diff --git a/tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c b/tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c new file mode 100644 index 0000000000000..d86653f282b14 --- /dev/null +++ b/tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c @@ -0,0 +1,74 @@ +/* + * Copyright 2015, Michael Neuling, IBM Corp. + * Licensed under GPLv2. + * + * Test the kernel's signal return code to ensure that it doesn't + * crash when both the transactional and suspend MSR bits are set in + * the signal context. + * + * For this test, we send ourselves a SIGUSR1. In the SIGUSR1 handler + * we modify the signal context to set both MSR TM S and T bits (which + * is "reserved" by the PowerISA). When we return from the signal + * handler (implicit sigreturn), the kernel should detect reserved MSR + * value and send us with a SIGSEGV. + */ + +#include +#include +#include +#include + +#include "utils.h" +#include "tm.h" + +int segv_expected = 0; + +void signal_segv(int signum) +{ + if (segv_expected && (signum == SIGSEGV)) + _exit(0); + _exit(1); +} + +void signal_usr1(int signum, siginfo_t *info, void *uc) +{ + ucontext_t *ucp = uc; + + /* Link tm checkpointed context to normal context */ + ucp->uc_link = ucp; + /* Set all TM bits so that the context is now invalid */ +#ifdef __powerpc64__ + ucp->uc_mcontext.gp_regs[PT_MSR] |= (7ULL << 32); +#else + ucp->uc_mcontext.regs->gpr[PT_MSR] |= (7ULL); +#endif + /* Should segv on return becuase of invalid context */ + segv_expected = 1; +} + +int tm_signal_msr_resv() +{ + struct sigaction act; + + SKIP_IF(!have_htm()); + + act.sa_sigaction = signal_usr1; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO; + if (sigaction(SIGUSR1, &act, NULL) < 0) { + perror("sigaction sigusr1"); + exit(1); + } + if (signal(SIGSEGV, signal_segv) == SIG_ERR) + exit(1); + + raise(SIGUSR1); + + /* We shouldn't get here as we exit in the segv handler */ + return 1; +} + +int main(void) +{ + return test_harness(tm_signal_msr_resv, "tm_signal_msr_resv"); +} -- GitLab From a26f415bf71640f0141e5e946384444675206b6a Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Fri, 20 Nov 2015 15:15:34 +1100 Subject: [PATCH 1236/2855] selftests/powerpc: Add TM signal with invalid stack test Test the kernels signal generation code to ensure it can handle an invalid stack pointer when transactional. Signed-off-by: Michael Neuling Tested-by: Anshuman Khandual [mpe: Skip if we don't have TM] Signed-off-by: Michael Ellerman --- tools/testing/selftests/powerpc/tm/.gitignore | 1 + tools/testing/selftests/powerpc/tm/Makefile | 2 +- .../selftests/powerpc/tm/tm-signal-stack.c | 76 +++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/tm/tm-signal-stack.c diff --git a/tools/testing/selftests/powerpc/tm/.gitignore b/tools/testing/selftests/powerpc/tm/.gitignore index 61c318fdace4e..e6668217ccd07 100644 --- a/tools/testing/selftests/powerpc/tm/.gitignore +++ b/tools/testing/selftests/powerpc/tm/.gitignore @@ -1,3 +1,4 @@ tm-resched-dscr tm-syscall tm-signal-msr-resv +tm-signal-stack diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile index c6b4ca8b2812b..e7ceff809fa0f 100644 --- a/tools/testing/selftests/powerpc/tm/Makefile +++ b/tools/testing/selftests/powerpc/tm/Makefile @@ -1,4 +1,4 @@ -TEST_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv +TEST_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack all: $(TEST_PROGS) diff --git a/tools/testing/selftests/powerpc/tm/tm-signal-stack.c b/tools/testing/selftests/powerpc/tm/tm-signal-stack.c new file mode 100644 index 0000000000000..e44a238c1d778 --- /dev/null +++ b/tools/testing/selftests/powerpc/tm/tm-signal-stack.c @@ -0,0 +1,76 @@ +/* + * Copyright 2015, Michael Neuling, IBM Corp. + * Licensed under GPLv2. + * + * Test the kernel's signal delievery code to ensure that we don't + * trelaim twice in the kernel signal delivery code. This can happen + * if we trigger a signal when in a transaction and the stack pointer + * is bogus. + * + * This test case registers a SEGV handler, sets the stack pointer + * (r1) to NULL, starts a transaction and then generates a SEGV. The + * SEGV should be handled but we exit here as the stack pointer is + * invalid and hance we can't sigreturn. We only need to check that + * this flow doesn't crash the kernel. + */ + +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "tm.h" + +void signal_segv(int signum) +{ + /* This should never actually run since stack is foobar */ + exit(1); +} + +int tm_signal_stack() +{ + int pid; + + SKIP_IF(!have_htm()); + + pid = fork(); + if (pid < 0) + exit(1); + + if (pid) { /* Parent */ + /* + * It's likely the whole machine will crash here so if + * the child ever exits, we are good. + */ + wait(NULL); + return 0; + } + + /* + * The flow here is: + * 1) register a signal handler (so signal delievery occurs) + * 2) make stack pointer (r1) = NULL + * 3) start transaction + * 4) cause segv + */ + if (signal(SIGSEGV, signal_segv) == SIG_ERR) + exit(1); + asm volatile("li 1, 0 ;" /* stack ptr == NULL */ + "1:" + ".long 0x7C00051D ;" /* tbegin */ + "beq 1b ;" /* retry forever */ + ".long 0x7C0005DD ; ;" /* tsuspend */ + "ld 2, 0(1) ;" /* trigger segv" */ + : : : "memory"); + + /* This should never get here due to above segv */ + return 1; +} + +int main(void) +{ + return test_harness(tm_signal_stack, "tm_signal_stack"); +} -- GitLab From b4af279a7cba5cc1f665485e8ecdf272f1ba0cc5 Mon Sep 17 00:00:00 2001 From: Vipin K Parashar Date: Tue, 1 Dec 2015 16:43:42 +0530 Subject: [PATCH 1237/2855] powerpc/pseries: Limit EPOW reset event warnings Kernel prints respective warnings about various EPOW events for user information/action after parsing EPOW interrupts. At times below EPOW reset event warning is seen to be flooding kernel log over a period of time. May 25 03:46:34 alp kernel: Non critical power or cooling issue cleared May 25 03:46:52 alp kernel: Non critical power or cooling issue cleared May 25 03:53:48 alp kernel: Non critical power or cooling issue cleared May 25 03:55:46 alp kernel: Non critical power or cooling issue cleared May 25 03:56:34 alp kernel: Non critical power or cooling issue cleared May 25 03:59:04 alp kernel: Non critical power or cooling issue cleared May 25 04:02:01 alp kernel: Non critical power or cooling issue cleared These EPOW reset events are spurious in nature and are triggered by firmware without an actual EPOW event being reset. This patch avoids these multiple EPOW reset warnings by using a counter variable. This variable is incremented every time an EPOW event is reported. Upon receiving a EPOW reset event the same variable is checked to filter out spurious events and decremented accordingly. This patch also improves log messages to better describe EPOW event being reported. Merged adjacent log messages into single one to reduce number of lines printed per event. Signed-off-by: Kamalesh Babulal Signed-off-by: Vipin K Parashar Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/ras.c | 55 ++++++++++++++++------------ 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index 3b6647e574b6d..9a3e27b863ce5 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -40,6 +40,9 @@ static int ras_check_exception_token; #define EPOW_SENSOR_TOKEN 9 #define EPOW_SENSOR_INDEX 0 +/* EPOW events counter variable */ +static int num_epow_events; + static irqreturn_t ras_epow_interrupt(int irq, void *dev_id); static irqreturn_t ras_error_interrupt(int irq, void *dev_id); @@ -82,32 +85,30 @@ static void handle_system_shutdown(char event_modifier) { switch (event_modifier) { case EPOW_SHUTDOWN_NORMAL: - pr_emerg("Firmware initiated power off"); + pr_emerg("Power off requested\n"); orderly_poweroff(true); break; case EPOW_SHUTDOWN_ON_UPS: - pr_emerg("Loss of power reported by firmware, system is " - "running on UPS/battery"); - pr_emerg("Check RTAS error log for details"); + pr_emerg("Loss of system power detected. System is running on" + " UPS/battery. Check RTAS error log for details\n"); orderly_poweroff(true); break; case EPOW_SHUTDOWN_LOSS_OF_CRITICAL_FUNCTIONS: - pr_emerg("Loss of system critical functions reported by " - "firmware"); - pr_emerg("Check RTAS error log for details"); + pr_emerg("Loss of system critical functions detected. Check" + " RTAS error log for details\n"); orderly_poweroff(true); break; case EPOW_SHUTDOWN_AMBIENT_TEMPERATURE_TOO_HIGH: - pr_emerg("Ambient temperature too high reported by firmware"); - pr_emerg("Check RTAS error log for details"); + pr_emerg("High ambient temperature detected. Check RTAS" + " error log for details\n"); orderly_poweroff(true); break; default: - pr_err("Unknown power/cooling shutdown event (modifier %d)", + pr_err("Unknown power/cooling shutdown event (modifier = %d)\n", event_modifier); } } @@ -145,17 +146,20 @@ static void rtas_parse_epow_errlog(struct rtas_error_log *log) switch (action_code) { case EPOW_RESET: - pr_err("Non critical power or cooling issue cleared"); + if (num_epow_events) { + pr_info("Non critical power/cooling issue cleared\n"); + num_epow_events--; + } break; case EPOW_WARN_COOLING: - pr_err("Non critical cooling issue reported by firmware"); - pr_err("Check RTAS error log for details"); + pr_info("Non-critical cooling issue detected. Check RTAS error" + " log for details\n"); break; case EPOW_WARN_POWER: - pr_err("Non critical power issue reported by firmware"); - pr_err("Check RTAS error log for details"); + pr_info("Non-critical power issue detected. Check RTAS error" + " log for details\n"); break; case EPOW_SYSTEM_SHUTDOWN: @@ -163,23 +167,27 @@ static void rtas_parse_epow_errlog(struct rtas_error_log *log) break; case EPOW_SYSTEM_HALT: - pr_emerg("Firmware initiated power off"); + pr_emerg("Critical power/cooling issue detected. Check RTAS" + " error log for details. Powering off.\n"); orderly_poweroff(true); break; case EPOW_MAIN_ENCLOSURE: case EPOW_POWER_OFF: - pr_emerg("Critical power/cooling issue reported by firmware"); - pr_emerg("Check RTAS error log for details"); - pr_emerg("Immediate power off"); + pr_emerg("System about to lose power. Check RTAS error log " + " for details. Powering off immediately.\n"); emergency_sync(); kernel_power_off(); break; default: - pr_err("Unknown power/cooling event (action code %d)", + pr_err("Unknown power/cooling event (action code = %d)\n", action_code); } + + /* Increment epow events counter variable */ + if (action_code != EPOW_RESET) + num_epow_events++; } /* Handle environmental and power warning (EPOW) interrupts. */ @@ -249,13 +257,12 @@ static irqreturn_t ras_error_interrupt(int irq, void *dev_id) log_error(ras_log_buf, ERR_TYPE_RTAS_LOG, fatal); if (fatal) { - pr_emerg("Fatal hardware error reported by firmware"); - pr_emerg("Check RTAS error log for details"); - pr_emerg("Immediate power off"); + pr_emerg("Fatal hardware error detected. Check RTAS error" + " log for details. Powering off immediately\n"); emergency_sync(); kernel_power_off(); } else { - pr_err("Recoverable hardware error reported by firmware"); + pr_err("Recoverable hardware error detected\n"); } spin_unlock(&ras_log_buf_lock); -- GitLab From 24ad1648edcc8b1c4a68c406296e0b171753a981 Mon Sep 17 00:00:00 2001 From: Rashmica Gupta Date: Tue, 1 Dec 2015 14:51:38 +1100 Subject: [PATCH 1238/2855] powerpc/cell: Remove the Cell QPACE code All users of QPACE have upgraded to QPACE2 so remove the Cell QPACE code. Signed-off-by: Rashmica Gupta Acked-by: Arnd Bergmann Signed-off-by: Michael Ellerman --- .../devicetree/bindings/serial/8250.txt | 1 - arch/powerpc/boot/Makefile | 2 - arch/powerpc/configs/ppc64_defconfig | 1 - arch/powerpc/platforms/cell/Kconfig | 5 - arch/powerpc/platforms/cell/Makefile | 4 - arch/powerpc/platforms/cell/qpace_setup.c | 148 ------------------ 6 files changed, 161 deletions(-) delete mode 100644 arch/powerpc/platforms/cell/qpace_setup.c diff --git a/Documentation/devicetree/bindings/serial/8250.txt b/Documentation/devicetree/bindings/serial/8250.txt index 91d5ab0e60fc4..936ab5b87324c 100644 --- a/Documentation/devicetree/bindings/serial/8250.txt +++ b/Documentation/devicetree/bindings/serial/8250.txt @@ -14,7 +14,6 @@ Required properties: tegra132, or tegra210. - "nxp,lpc3220-uart" - "ralink,rt2880-uart" - - "ibm,qpace-nwp-serial" - "altr,16550-FIFO32" - "altr,16550-FIFO64" - "altr,16550-FIFO128" diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 99e4487248ff3..61165101342c8 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -113,7 +113,6 @@ src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c epapr-wrapper.c src-plat-$(CONFIG_PPC_PSERIES) += pseries-head.S src-plat-$(CONFIG_PPC_POWERNV) += pseries-head.S src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) += pseries-head.S -src-plat-$(CONFIG_PPC_CELL_QPACE) += pseries-head.S src-wlib := $(sort $(src-wlib-y)) src-plat := $(sort $(src-plat-y)) @@ -217,7 +216,6 @@ image-$(CONFIG_PPC_POWERNV) += zImage.pseries image-$(CONFIG_PPC_MAPLE) += zImage.maple image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries image-$(CONFIG_PPC_PS3) += dtbImage.ps3 -image-$(CONFIG_PPC_CELL_QPACE) += zImage.pseries image-$(CONFIG_PPC_CHRP) += zImage.chrp image-$(CONFIG_PPC_EFIKA) += zImage.chrp image-$(CONFIG_PPC_PMAC) += zImage.pmac diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 2c041b535a64e..b041fb6073766 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -36,7 +36,6 @@ CONFIG_PS3_ROM=m CONFIG_PS3_FLASH=m CONFIG_PS3_LPM=m CONFIG_PPC_IBM_CELL_BLADE=y -CONFIG_PPC_CELL_QPACE=y CONFIG_RTAS_FLASH=m CONFIG_IBMEBUS=y CONFIG_CPU_FREQ_PMAC64=y diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig index 429fc59d2a476..d9088f0b8fcc5 100644 --- a/arch/powerpc/platforms/cell/Kconfig +++ b/arch/powerpc/platforms/cell/Kconfig @@ -33,11 +33,6 @@ config PPC_IBM_CELL_BLADE select PPC_UDBG_16550 select UDBG_RTAS_CONSOLE -config PPC_CELL_QPACE - bool "IBM Cell - QPACE" - depends on PPC64 && PPC_BOOK3S && CPU_BIG_ENDIAN - select PPC_CELL_COMMON - config AXON_MSI bool depends on PPC_IBM_CELL_BLADE && PCI_MSI diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile index 34699bddfdddb..00464305763d7 100644 --- a/arch/powerpc/platforms/cell/Makefile +++ b/arch/powerpc/platforms/cell/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_PPC_IBM_CELL_POWERBUTTON) += cbe_powerbutton.o ifeq ($(CONFIG_SMP),y) obj-$(CONFIG_PPC_CELL_NATIVE) += smp.o -obj-$(CONFIG_PPC_CELL_QPACE) += smp.o endif # needed only when building loadable spufs.ko @@ -26,6 +25,3 @@ obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \ spufs/ obj-$(CONFIG_AXON_MSI) += axon_msi.o - -# qpace setup -obj-$(CONFIG_PPC_CELL_QPACE) += qpace_setup.o diff --git a/arch/powerpc/platforms/cell/qpace_setup.c b/arch/powerpc/platforms/cell/qpace_setup.c deleted file mode 100644 index d328140dc6f5e..0000000000000 --- a/arch/powerpc/platforms/cell/qpace_setup.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * linux/arch/powerpc/platforms/cell/qpace_setup.c - * - * Copyright (C) 1995 Linus Torvalds - * Adapted from 'alpha' version by Gary Thomas - * Modified by Cort Dougan (cort@cs.nmt.edu) - * Modified by PPC64 Team, IBM Corp - * Modified by Cell Team, IBM Deutschland Entwicklung GmbH - * Modified by Benjamin Krill , IBM Corp. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "interrupt.h" -#include "pervasive.h" -#include "ras.h" - -static void qpace_show_cpuinfo(struct seq_file *m) -{ - struct device_node *root; - const char *model = ""; - - root = of_find_node_by_path("/"); - if (root) - model = of_get_property(root, "model", NULL); - seq_printf(m, "machine\t\t: CHRP %s\n", model); - of_node_put(root); -} - -static void qpace_progress(char *s, unsigned short hex) -{ - printk("*** %04x : %s\n", hex, s ? s : ""); -} - -static const struct of_device_id qpace_bus_ids[] __initconst = { - { .type = "soc", }, - { .compatible = "soc", }, - { .type = "spider", }, - { .type = "axon", }, - { .type = "plb5", }, - { .type = "plb4", }, - { .type = "opb", }, - { .type = "ebc", }, - {}, -}; - -static int __init qpace_publish_devices(void) -{ - int node; - - /* Publish OF platform devices for southbridge IOs */ - of_platform_bus_probe(NULL, qpace_bus_ids, NULL); - - /* There is no device for the MIC memory controller, thus we create - * a platform device for it to attach the EDAC driver to. - */ - for_each_online_node(node) { - if (cbe_get_cpu_mic_tm_regs(cbe_node_to_cpu(node)) == NULL) - continue; - platform_device_register_simple("cbe-mic", node, NULL, 0); - } - - return 0; -} -machine_subsys_initcall(qpace, qpace_publish_devices); - -static void __init qpace_setup_arch(void) -{ -#ifdef CONFIG_SPU_BASE - spu_priv1_ops = &spu_priv1_mmio_ops; - spu_management_ops = &spu_management_of_ops; -#endif - - cbe_regs_init(); - -#ifdef CONFIG_CBE_RAS - cbe_ras_init(); -#endif - -#ifdef CONFIG_SMP - smp_init_cell(); -#endif - - /* init to some ~sane value until calibrate_delay() runs */ - loops_per_jiffy = 50000000; - - cbe_pervasive_init(); -#ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#endif -} - -static int __init qpace_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); - - if (!of_flat_dt_is_compatible(root, "IBM,QPACE")) - return 0; - - hpte_init_native(); - pm_power_off = rtas_power_off; - - return 1; -} - -define_machine(qpace) { - .name = "QPACE", - .probe = qpace_probe, - .setup_arch = qpace_setup_arch, - .show_cpuinfo = qpace_show_cpuinfo, - .restart = rtas_restart, - .halt = rtas_halt, - .get_boot_time = rtas_get_boot_time, - .get_rtc_time = rtas_get_rtc_time, - .set_rtc_time = rtas_set_rtc_time, - .calibrate_decr = generic_calibrate_decr, - .progress = qpace_progress, - .init_IRQ = iic_init_IRQ, -}; -- GitLab From eb925d64604991095b6e9476d7c437a994f3369c Mon Sep 17 00:00:00 2001 From: Rashmica Gupta Date: Wed, 25 Nov 2015 13:46:25 +1100 Subject: [PATCH 1239/2855] powerpc/xmon: Append linux_banner to exception information in xmon. Currently if you are in xmon without an oops etc. to view the kernel version you have to type "d $linux_banner" - not necessarily obvious. As this is useful information, append to the output of "e" command. Example output: $mon> e cpu 0x1: Vector: 0 at [c0000000f879ba80] pc: c000000000081718: sysrq_handle_xmon+0x68/0x80 lr: c000000000081718: sysrq_handle_xmon+0x68/0x80 sp: c0000000f879bbe0 msr: 8000000000009033 current = 0xc0000000f604d5c0 paca = 0xc00000000fdc0480 softe: 0 irq_happened: 0x01 pid = 2467, comm = bash Linux version 4.4.0-rc2-00008-gc51af91c3ab3-dirty (rashmica@circle) (gcc version 5.1.1 20150629 (GCC) ) #45 SMP Wed Nov 25 10:25:12 AEDT 2015 Signed-off-by: Rashmica Gupta Signed-off-by: Michael Ellerman --- arch/powerpc/xmon/xmon.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 786bf01691c98..e8c7a937955ec 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -1522,6 +1522,8 @@ static void excprint(struct pt_regs *fp) if (trap == 0x700) print_bug_trap(fp); + + printf(linux_banner); } static void prregs(struct pt_regs *fp) -- GitLab From 5f337e3e5b04b32793fd51adab438d46df99c933 Mon Sep 17 00:00:00 2001 From: Rashmica Gupta Date: Thu, 10 Dec 2015 20:49:33 +1100 Subject: [PATCH 1240/2855] selftests/powerpc: Add test to check if VSRs are corrupted When a transaction is aborted, VSR values should rollback to the checkpointed values before the transaction began. VSRs used elsewhere in the kernel during a transaction, or while the transaction is suspended should not affect the checkpointed values. Prior to the bug fix in commit d31626f70b61 ("powerpc: Don't corrupt transactional state when using FP/VMX in kernel") when VMX was requested by the kernel the .vr_state (which held the checkpointed state of VSRs before the transaction) was overwritten with the current state from outside the transation. Thus if the transaction did not complete, the VSR values would be "rolled back" to potentially incorrect values. Signed-off-by: Rashmica Gupta Signed-off-by: Michael Ellerman --- tools/testing/selftests/powerpc/tm/.gitignore | 1 + tools/testing/selftests/powerpc/tm/Makefile | 2 +- .../testing/selftests/powerpc/tm/tm-vmxcopy.c | 103 ++++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/tm/tm-vmxcopy.c diff --git a/tools/testing/selftests/powerpc/tm/.gitignore b/tools/testing/selftests/powerpc/tm/.gitignore index e6668217ccd07..7d0f14b8cb2e4 100644 --- a/tools/testing/selftests/powerpc/tm/.gitignore +++ b/tools/testing/selftests/powerpc/tm/.gitignore @@ -2,3 +2,4 @@ tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack +tm-vmxcopy diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile index e7ceff809fa0f..737f72c964e65 100644 --- a/tools/testing/selftests/powerpc/tm/Makefile +++ b/tools/testing/selftests/powerpc/tm/Makefile @@ -1,4 +1,4 @@ -TEST_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack +TEST_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack tm-vmxcopy all: $(TEST_PROGS) diff --git a/tools/testing/selftests/powerpc/tm/tm-vmxcopy.c b/tools/testing/selftests/powerpc/tm/tm-vmxcopy.c new file mode 100644 index 0000000000000..0274de7b11f38 --- /dev/null +++ b/tools/testing/selftests/powerpc/tm/tm-vmxcopy.c @@ -0,0 +1,103 @@ +/* + * Copyright 2015, Michael Neuling, IBM Corp. + * Licensed under GPLv2. + * + * Original: Michael Neuling 4/12/2013 + * Edited: Rashmica Gupta 4/12/2015 + * + * See if the altivec state is leaked out of an aborted transaction due to + * kernel vmx copy loops. + * + * When the transaction aborts, VSR values should rollback to the values + * they held before the transaction commenced. Using VSRs while transaction + * is suspended should not affect the checkpointed values. + * + * (1) write A to a VSR + * (2) start transaction + * (3) suspend transaction + * (4) change the VSR to B + * (5) trigger kernel vmx copy loop + * (6) abort transaction + * (7) check that the VSR value is A + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "tm.h" +#include "utils.h" + +int test_vmxcopy() +{ + long double vecin = 1.3; + long double vecout; + unsigned long pgsize = getpagesize(); + int i; + int fd; + int size = pgsize*16; + char tmpfile[] = "/tmp/page_faultXXXXXX"; + char buf[pgsize]; + char *a; + uint64_t aborted = 0; + + SKIP_IF(!have_htm()); + + fd = mkstemp(tmpfile); + assert(fd >= 0); + + memset(buf, 0, pgsize); + for (i = 0; i < size; i += pgsize) + assert(write(fd, buf, pgsize) == pgsize); + + unlink(tmpfile); + + a = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); + assert(a != MAP_FAILED); + + asm __volatile__( + "lxvd2x 40,0,%[vecinptr];" /* set 40 to initial value*/ + "tbegin.;" + "beq 3f;" + "tsuspend.;" + "xxlxor 40,40,40;" /* set 40 to 0 */ + "std 5, 0(%[map]);" /* cause kernel vmx copy page */ + "tabort. 0;" + "tresume.;" + "tend.;" + "li %[res], 0;" + "b 5f;" + + /* Abort handler */ + "3:;" + "li %[res], 1;" + + "5:;" + "stxvd2x 40,0,%[vecoutptr];" + : [res]"=r"(aborted) + : [vecinptr]"r"(&vecin), + [vecoutptr]"r"(&vecout), + [map]"r"(a) + : "memory", "r0", "r3", "r4", "r5", "r6", "r7"); + + if (aborted && (vecin != vecout)){ + printf("FAILED: vector state leaked on abort %f != %f\n", + (double)vecin, (double)vecout); + return 1; + } + + munmap(a, size); + + close(fd); + + return 0; +} + +int main(void) +{ + return test_harness(test_vmxcopy, "tm_vmxcopy"); +} -- GitLab From e1dba01ca620bb0b3864d5237c1c597d9e012ebf Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 8 Dec 2015 10:37:46 +0100 Subject: [PATCH 1241/2855] i2c: add generic routine to parse DT for timing information Inspired from the i2c-rk3x driver (thanks guys!) but refactored and extended. See built-in docs for further information. Signed-off-by: Wolfram Sang Reviewed-by: Mika Westerberg Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core.c | 53 ++++++++++++++++++++++++++++++++++++++++++ include/linux/i2c.h | 18 ++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index ba8eb087f2246..b34c412bd2c24 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -53,6 +53,7 @@ #include #include #include +#include #include "i2c-core.h" @@ -1438,6 +1439,58 @@ static void of_i2c_register_devices(struct i2c_adapter *adap) } } +/** + * i2c_parse_fw_timings - get I2C related timing parameters from firmware + * @dev: The device to scan for I2C timing properties + * @t: the i2c_timings struct to be filled with values + * @use_defaults: bool to use sane defaults derived from the I2C specification + * when properties are not found, otherwise use 0 + * + * Scan the device for the generic I2C properties describing timing parameters + * for the signal and fill the given struct with the results. If a property was + * not found and use_defaults was true, then maximum timings are assumed which + * are derived from the I2C specification. If use_defaults is not used, the + * results will be 0, so drivers can apply their own defaults later. The latter + * is mainly intended for avoiding regressions of existing drivers which want + * to switch to this function. New drivers almost always should use the defaults. + */ + +void i2c_parse_fw_timings(struct device *dev, struct i2c_timings *t, bool use_defaults) +{ + int ret; + + memset(t, 0, sizeof(*t)); + + ret = device_property_read_u32(dev, "clock-frequency", &t->bus_freq_hz); + if (ret && use_defaults) + t->bus_freq_hz = 100000; + + ret = device_property_read_u32(dev, "i2c-scl-rising-time-ns", &t->scl_rise_ns); + if (ret && use_defaults) { + if (t->bus_freq_hz <= 100000) + t->scl_rise_ns = 1000; + else if (t->bus_freq_hz <= 400000) + t->scl_rise_ns = 300; + else + t->scl_rise_ns = 120; + } + + ret = device_property_read_u32(dev, "i2c-scl-falling-time-ns", &t->scl_fall_ns); + if (ret && use_defaults) { + if (t->bus_freq_hz <= 400000) + t->scl_fall_ns = 300; + else + t->scl_fall_ns = 120; + } + + device_property_read_u32(dev, "i2c-scl-internal-delay-ns", &t->scl_int_delay_ns); + + ret = device_property_read_u32(dev, "i2c-sda-falling-time-ns", &t->sda_fall_ns); + if (ret && use_defaults) + t->sda_fall_ns = t->scl_fall_ns; +} +EXPORT_SYMBOL_GPL(i2c_parse_fw_timings); + static int of_dev_node_match(struct device *dev, void *data) { return dev->of_node == data; diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 51028f351d13e..bc2b19ad93578 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -413,6 +413,22 @@ struct i2c_algorithm { #endif }; +/** + * struct i2c_timings - I2C timing information + * @bus_freq_hz: the bus frequency in Hz + * @scl_rise_ns: time SCL signal takes to rise in ns; t(r) in the I2C specification + * @scl_fall_ns: time SCL signal takes to fall in ns; t(f) in the I2C specification + * @scl_int_delay_ns: time IP core additionally needs to setup SCL in ns + * @sda_fall_ns: time SDA signal takes to fall in ns; t(f) in the I2C specification + */ +struct i2c_timings { + u32 bus_freq_hz; + u32 scl_rise_ns; + u32 scl_fall_ns; + u32 scl_int_delay_ns; + u32 sda_fall_ns; +}; + /** * struct i2c_bus_recovery_info - I2C bus recovery information * @recover_bus: Recover routine. Either pass driver's recover_bus() routine, or @@ -604,6 +620,7 @@ extern void i2c_clients_command(struct i2c_adapter *adap, extern struct i2c_adapter *i2c_get_adapter(int nr); extern void i2c_put_adapter(struct i2c_adapter *adap); +void i2c_parse_fw_timings(struct device *dev, struct i2c_timings *t, bool use_defaults); /* Return the functionality mask */ static inline u32 i2c_get_functionality(struct i2c_adapter *adap) @@ -660,6 +677,7 @@ extern struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node) /* must call i2c_put_adapter() when done with returned i2c_adapter device */ struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node); + #else static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) -- GitLab From f9c9d31bdd37970d2aaaac794d93691170008f5a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 8 Dec 2015 10:37:47 +0100 Subject: [PATCH 1242/2855] i2c: rcar: refactor probe function a little The probe function is a little bit messy, something here, something there. Rework it so that there is some order: first init the private structure, then the adapter, then do HW init. This also allows us to remove the device argument of the clock calculation function, because it now can be deduced from the private structure. Also, shorten some lines where possible. This is a preparation for further refactoring. Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 40 +++++++++++++++-------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index 3ed1f0aa5eeb1..d4322a9096786 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -162,15 +162,11 @@ static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv) return -EBUSY; } -static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, - u32 bus_speed, - struct device *dev) +static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, u32 bus_speed) { - u32 scgd, cdf; - u32 round, ick; - u32 scl; - u32 cdf_width; + u32 scgd, cdf, round, ick, scl, cdf_width; unsigned long rate; + struct device *dev = rcar_i2c_priv_to_dev(priv); switch (priv->devtype) { case I2C_RCAR_GEN1: @@ -610,21 +606,7 @@ static int rcar_i2c_probe(struct platform_device *pdev) if (IS_ERR(priv->io)) return PTR_ERR(priv->io); - bus_speed = 100000; /* default 100 kHz */ - of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed); - priv->devtype = (enum rcar_i2c_type)of_match_device(rcar_i2c_dt_ids, dev)->data; - - pm_runtime_enable(dev); - pm_runtime_get_sync(dev); - ret = rcar_i2c_clock_calculate(priv, bus_speed, dev); - if (ret < 0) - goto out_pm_put; - - rcar_i2c_init(priv); - pm_runtime_put(dev); - - irq = platform_get_irq(pdev, 0); init_waitqueue_head(&priv->wait); adap = &priv->adap; @@ -637,8 +619,20 @@ static int rcar_i2c_probe(struct platform_device *pdev) i2c_set_adapdata(adap, priv); strlcpy(adap->name, pdev->name, sizeof(adap->name)); - ret = devm_request_irq(dev, irq, rcar_i2c_irq, 0, - dev_name(dev), priv); + bus_speed = 100000; /* default 100 kHz */ + of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed); + + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); + ret = rcar_i2c_clock_calculate(priv, bus_speed); + if (ret < 0) + goto out_pm_put; + + rcar_i2c_init(priv); + pm_runtime_put(dev); + + irq = platform_get_irq(pdev, 0); + ret = devm_request_irq(dev, irq, rcar_i2c_irq, 0, dev_name(dev), priv); if (ret < 0) { dev_err(dev, "cannot get irq %d\n", irq); goto out_pm_disable; -- GitLab From c7881871de878ab3a40b973142e4ca17857b6b73 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 8 Dec 2015 10:37:48 +0100 Subject: [PATCH 1243/2855] i2c: rcar: switch to i2c generic dt parsing Switch to the new generic functions. Plain convert, no functionality added yet. Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index d4322a9096786..c663f4389bf89 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -162,12 +162,15 @@ static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv) return -EBUSY; } -static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, u32 bus_speed) +static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, struct i2c_timings *t) { u32 scgd, cdf, round, ick, scl, cdf_width; unsigned long rate; struct device *dev = rcar_i2c_priv_to_dev(priv); + /* Fall back to previously used values if not supplied */ + t->bus_freq_hz = t->bus_freq_hz ?: 100000; + switch (priv->devtype) { case I2C_RCAR_GEN1: cdf_width = 2; @@ -230,7 +233,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, u32 bus_speed) */ for (scgd = 0; scgd < 0x40; scgd++) { scl = ick / (20 + (scgd * 8) + round); - if (scl <= bus_speed) + if (scl <= t->bus_freq_hz) goto scgd_find; } dev_err(dev, "it is impossible to calculate best SCL\n"); @@ -238,7 +241,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, u32 bus_speed) scgd_find: dev_dbg(dev, "clk %d/%d(%lu), round %u, CDF:0x%x, SCGD: 0x%x\n", - scl, bus_speed, clk_get_rate(priv->clk), round, cdf, scgd); + scl, t->bus_freq_hz, clk_get_rate(priv->clk), round, cdf, scgd); /* keep icccr value */ priv->icccr = scgd << cdf_width | cdf; @@ -588,7 +591,7 @@ static int rcar_i2c_probe(struct platform_device *pdev) struct i2c_adapter *adap; struct resource *res; struct device *dev = &pdev->dev; - u32 bus_speed; + struct i2c_timings i2c_t; int irq, ret; priv = devm_kzalloc(dev, sizeof(struct rcar_i2c_priv), GFP_KERNEL); @@ -619,12 +622,11 @@ static int rcar_i2c_probe(struct platform_device *pdev) i2c_set_adapdata(adap, priv); strlcpy(adap->name, pdev->name, sizeof(adap->name)); - bus_speed = 100000; /* default 100 kHz */ - of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed); + i2c_parse_fw_timings(dev, &i2c_t, false); pm_runtime_enable(dev); pm_runtime_get_sync(dev); - ret = rcar_i2c_clock_calculate(priv, bus_speed); + ret = rcar_i2c_clock_calculate(priv, &i2c_t); if (ret < 0) goto out_pm_put; -- GitLab From ca68eade666a6ad7e954cc8c1af07ce477726087 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 8 Dec 2015 10:37:49 +0100 Subject: [PATCH 1244/2855] i2c: rcar: honor additional i2c timings from DT Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- .../devicetree/bindings/i2c/i2c-rcar.txt | 4 ++++ drivers/i2c/busses/i2c-rcar.c | 21 +++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt index ea406eb20fa5a..95e97223a71c8 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt @@ -20,6 +20,10 @@ Optional properties: propoerty indicates the default frequency 100 kHz. - clocks: clock specifier. +- i2c-scl-falling-time-ns: see i2c.txt +- i2c-scl-internal-delay-ns: see i2c.txt +- i2c-scl-rising-time-ns: see i2c.txt + Examples : i2c0: i2c@e6508000 { diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index c663f4389bf89..b2389c492579c 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -164,12 +164,15 @@ static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv) static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, struct i2c_timings *t) { - u32 scgd, cdf, round, ick, scl, cdf_width; + u32 scgd, cdf, round, ick, sum, scl, cdf_width; unsigned long rate; struct device *dev = rcar_i2c_priv_to_dev(priv); /* Fall back to previously used values if not supplied */ t->bus_freq_hz = t->bus_freq_hz ?: 100000; + t->scl_fall_ns = t->scl_fall_ns ?: 35; + t->scl_rise_ns = t->scl_rise_ns ?: 200; + t->scl_int_delay_ns = t->scl_int_delay_ns ?: 50; switch (priv->devtype) { case I2C_RCAR_GEN1: @@ -193,9 +196,9 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, struct i2c_timin * SCL = ick / (20 + SCGD * 8 + F[(ticf + tr + intd) * ick]) * * ick : I2C internal clock < 20 MHz - * ticf : I2C SCL falling time = 35 ns here - * tr : I2C SCL rising time = 200 ns here - * intd : LSI internal delay = 50 ns here + * ticf : I2C SCL falling time + * tr : I2C SCL rising time + * intd : LSI internal delay * clkp : peripheral_clk * F[] : integer up-valuation */ @@ -211,12 +214,12 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, struct i2c_timin * it is impossible to calculate large scale * number on u32. separate it * - * F[(ticf + tr + intd) * ick] - * = F[(35 + 200 + 50)ns * ick] - * = F[285 * ick / 1000000000] - * = F[(ick / 1000000) * 285 / 1000] + * F[(ticf + tr + intd) * ick] with sum = (ticf + tr + intd) + * = F[sum * ick / 1000000000] + * = F[(ick / 1000000) * sum / 1000] */ - round = (ick + 500000) / 1000000 * 285; + sum = t->scl_fall_ns + t->scl_rise_ns + t->scl_int_delay_ns; + round = (ick + 500000) / 1000000 * sum; round = (round + 500) / 1000; /* -- GitLab From 1ff49b34bfd1261277d2c97ec48efb067b87f5e5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 30 Nov 2015 18:53:33 +0900 Subject: [PATCH 1245/2855] i2c: uniphier: error out if clock rate is zero This input clock is used to generate the sampling clock for I2C bus. If the clock rate is zero, there is something wrong with the clock driver. Bail out with the appropriate error message in such a case. It would make it easier to find the root cause of failure. Signed-off-by: Masahiro Yamada Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-uniphier.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-uniphier.c b/drivers/i2c/busses/i2c-uniphier.c index e3c3861c33251..2b2c20b3a57a3 100644 --- a/drivers/i2c/busses/i2c-uniphier.c +++ b/drivers/i2c/busses/i2c-uniphier.c @@ -342,6 +342,10 @@ static int uniphier_i2c_clk_init(struct device *dev, return ret; clk_rate = clk_get_rate(priv->clk); + if (!clk_rate) { + dev_err(dev, "input clock rate should not be zero\n"); + return -EINVAL; + } uniphier_i2c_reset(priv, true); @@ -388,7 +392,7 @@ static int uniphier_i2c_probe(struct platform_device *pdev) ret = uniphier_i2c_clk_init(dev, priv); if (ret) - return ret; + goto err; ret = devm_request_irq(dev, irq, uniphier_i2c_interrupt, 0, pdev->name, priv); -- GitLab From 2d5d23b96a4a660d0d04455150570c6257d4ce25 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 30 Nov 2015 18:53:34 +0900 Subject: [PATCH 1246/2855] i2c: uniphier: error out if bus speed is zero There is code to divide by "bus_speed" some lines below. To eliminate the possibility of division by zero, bail out if "clock-frequency" is specified as zero. Signed-off-by: Masahiro Yamada Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-uniphier.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/i2c/busses/i2c-uniphier.c b/drivers/i2c/busses/i2c-uniphier.c index 2b2c20b3a57a3..1f4f3f53819c7 100644 --- a/drivers/i2c/busses/i2c-uniphier.c +++ b/drivers/i2c/busses/i2c-uniphier.c @@ -327,6 +327,11 @@ static int uniphier_i2c_clk_init(struct device *dev, if (of_property_read_u32(np, "clock-frequency", &bus_speed)) bus_speed = UNIPHIER_I2C_DEFAULT_SPEED; + if (!bus_speed) { + dev_err(dev, "clock-freqyency should not be zero\n"); + return -EINVAL; + } + if (bus_speed > UNIPHIER_I2C_MAX_SPEED) bus_speed = UNIPHIER_I2C_MAX_SPEED; -- GitLab From ac9b91f39d86f04eeacfccb6b6113b1ffa001ec1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 30 Nov 2015 18:53:35 +0900 Subject: [PATCH 1247/2855] i2c: uniphier_f: error out if clock rate is zero This input clock is used to generate the sampling clock for I2C bus. If the clock rate is zero, there is something wrong with the clock driver. Bail out with the appropriate error message in such a case. It would make it easier to find the root cause of failure. Signed-off-by: Masahiro Yamada Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-uniphier-f.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-uniphier-f.c b/drivers/i2c/busses/i2c-uniphier-f.c index e8d03bcfe3e0a..67109e1d66c32 100644 --- a/drivers/i2c/busses/i2c-uniphier-f.c +++ b/drivers/i2c/busses/i2c-uniphier-f.c @@ -481,6 +481,10 @@ static int uniphier_fi2c_clk_init(struct device *dev, return ret; clk_rate = clk_get_rate(priv->clk); + if (!clk_rate) { + dev_err(dev, "input clock rate should not be zero\n"); + return -EINVAL; + } uniphier_fi2c_reset(priv); @@ -531,7 +535,7 @@ static int uniphier_fi2c_probe(struct platform_device *pdev) ret = uniphier_fi2c_clk_init(dev, priv); if (ret) - return ret; + goto err; ret = devm_request_irq(dev, irq, uniphier_fi2c_interrupt, 0, pdev->name, priv); -- GitLab From 51549c087f2eb5788de48a7278c3eb169d66f554 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 30 Nov 2015 18:53:36 +0900 Subject: [PATCH 1248/2855] i2c: uniphier_f: error out if bus speed is zero There is code to divide by "bus_speed" some lines below. To eliminate the possibility of division by zero, bail out if "clock-frequency" is specified as zero. Signed-off-by: Masahiro Yamada Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-uniphier-f.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/i2c/busses/i2c-uniphier-f.c b/drivers/i2c/busses/i2c-uniphier-f.c index 67109e1d66c32..f3e5ff8522f0a 100644 --- a/drivers/i2c/busses/i2c-uniphier-f.c +++ b/drivers/i2c/busses/i2c-uniphier-f.c @@ -466,6 +466,11 @@ static int uniphier_fi2c_clk_init(struct device *dev, if (of_property_read_u32(np, "clock-frequency", &bus_speed)) bus_speed = UNIPHIER_FI2C_DEFAULT_SPEED; + if (!bus_speed) { + dev_err(dev, "clock-freqyency should not be zero\n"); + return -EINVAL; + } + if (bus_speed > UNIPHIER_FI2C_MAX_SPEED) bus_speed = UNIPHIER_FI2C_MAX_SPEED; -- GitLab From 7da5446367122fd5cc00283e6b6cce5d3ef68c90 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sat, 12 Dec 2015 16:30:04 -0500 Subject: [PATCH 1249/2855] fs: make quota/netlink.c explicitly non-modular The Kconfig currently controlling compilation of this code is: config QUOTA_NETLINK_INTERFACE bool "Report quota messages through netlink interface" ...meaning that it currently is not being built as a module by anyone. Lets remove the couple traces of modularity so that when reading the driver there is no doubt it is builtin-only. Since module_init translates to device_initcall in the non-modular case, the init ordering gets bumped to one level earlier when we use the more appropriate fs_initcall here. However we've made similar changes before without any fallout and none is expected here either. Cc: Jan Kara Signed-off-by: Paul Gortmaker Signed-off-by: Jan Kara --- fs/quota/netlink.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/fs/quota/netlink.c b/fs/quota/netlink.c index bb2869f5dfd89..d07a2f91d8580 100644 --- a/fs/quota/netlink.c +++ b/fs/quota/netlink.c @@ -1,7 +1,5 @@ - #include #include -#include #include #include #include @@ -105,5 +103,4 @@ static int __init quota_init(void) "VFS: Failed to create quota netlink interface.\n"); return 0; }; - -module_init(quota_init); +fs_initcall(quota_init); -- GitLab From 331221fac721788615dd9d5b27f710f7c758d60a Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sat, 12 Dec 2015 16:30:12 -0500 Subject: [PATCH 1250/2855] fs: make quota/dquot.c explicitly non-modular The Kconfig currently controlling compilation of this code is: config QUOTA bool "Quota support" ...meaning that it currently is not being built as a module by anyone. Lets remove the couple traces of modularity so that when reading the driver there is no doubt it is builtin-only. Since module_init translates to device_initcall in the non-modular case, the init ordering gets bumped to one level earlier when we use the more appropriate fs_initcall here. However we've made similar changes before without any fallout and none is expected here either. We don't delete module.h because the code in turn tries to load other modules as appropriate and so it still needs that header. Cc: Jan Kara Cc: Alexander Viro Cc: linux-fsdevel@vger.kernel.org Signed-off-by: Paul Gortmaker Signed-off-by: Jan Kara --- fs/quota/dquot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index ef0d64b2a6d94..fbd70af988207 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -2924,4 +2924,4 @@ static int __init dquot_init(void) return 0; } -module_init(dquot_init); +fs_initcall(dquot_init); -- GitLab From e1c51b9f1df2f9efc2ec11488717e40cd12015f9 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Fri, 11 Dec 2015 16:08:22 +0800 Subject: [PATCH 1251/2855] f2fs: clean up node page updating flow If read_node_page return LOCKED_PAGE, in its caller it's better a) skip unneeded 'Update' flag and mapping info verfication; b) check nid value stored in footer structure of node page. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/node.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 7bcbc6e9c40d4..d842b199cd024 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1063,12 +1063,13 @@ repeat: if (err < 0) { f2fs_put_page(page, 1); return ERR_PTR(err); - } else if (err != LOCKED_PAGE) { - lock_page(page); + } else if (err == LOCKED_PAGE) { + goto page_hit; } - if (unlikely(!PageUptodate(page) || nid != nid_of_node(page))) { - ClearPageUptodate(page); + lock_page(page); + + if (unlikely(!PageUptodate(page))) { f2fs_put_page(page, 1); return ERR_PTR(-EIO); } @@ -1076,6 +1077,8 @@ repeat: f2fs_put_page(page, 1); goto repeat; } +page_hit: + f2fs_bug_on(sbi, nid != nid_of_node(page)); return page; } @@ -1114,24 +1117,25 @@ repeat: end = start + MAX_RA_NODE; end = min(end, NIDS_PER_BLOCK); for (i = start + 1; i < end; i++) { - nid = get_nid(parent, i, false); - if (!nid) + nid_t tnid = get_nid(parent, i, false); + if (!tnid) continue; - ra_node_page(sbi, nid); + ra_node_page(sbi, tnid); } blk_finish_plug(&plug); lock_page(page); + if (unlikely(!PageUptodate(page))) { + f2fs_put_page(page, 1); + return ERR_PTR(-EIO); + } if (unlikely(page->mapping != NODE_MAPPING(sbi))) { f2fs_put_page(page, 1); goto repeat; } page_hit: - if (unlikely(!PageUptodate(page))) { - f2fs_put_page(page, 1); - return ERR_PTR(-EIO); - } + f2fs_bug_on(sbi, nid != nid_of_node(page)); return page; } -- GitLab From 665d2c2848f14c0c2a2e89192bde9073c4d352f7 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 8 Dec 2015 17:04:59 -0800 Subject: [PATCH 1252/2855] mtd: bcm47xxnflash: really unregister NAND on device removal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The field bcma_nflash::mtd is never set to be non-zero anywhere, but we test for it in the removal path. So the MTD is never unregistered. Also, we should use nand_release(), not mtd_device_unregister(). Finally, we don't need to use the 'platdata' for stashing/retrieving our *driver* data -- that's what *_{get,set}_drvdata() are for. So, kill off bcm_nflash::mtd, and stash the struct bcm47xxnflash in drvdata instead. Also move the forward declaration of mtd_info up a bit, since struct bcma_sflash should be using it. Caught while inspecting other changes being made to this driver. Compile tested only. Signed-off-by: Brian Norris Cc: "Rafał Miłecki" Cc: linux-wireless@vger.kernel.org Acked-by: Boris Brezillon --- drivers/mtd/nand/bcm47xxnflash/main.c | 7 ++++--- include/linux/bcma/bcma_driver_chipcommon.h | 6 ++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/bcm47xxnflash/main.c b/drivers/mtd/nand/bcm47xxnflash/main.c index 9ba0c0f2cd9bb..0b3acc4391818 100644 --- a/drivers/mtd/nand/bcm47xxnflash/main.c +++ b/drivers/mtd/nand/bcm47xxnflash/main.c @@ -49,6 +49,8 @@ static int bcm47xxnflash_probe(struct platform_device *pdev) return err; } + platform_set_drvdata(pdev, b47n); + err = mtd_device_parse_register(&b47n->mtd, probes, NULL, NULL, 0); if (err) { pr_err("Failed to register MTD device: %d\n", err); @@ -60,10 +62,9 @@ static int bcm47xxnflash_probe(struct platform_device *pdev) static int bcm47xxnflash_remove(struct platform_device *pdev) { - struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); + struct bcm47xxnflash *nflash = platform_get_drvdata(pdev); - if (nflash->mtd) - mtd_device_unregister(nflash->mtd); + nand_release(&nflash->mtd); return 0; } diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index cf038431a5cc8..db51a6ffb7d68 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h @@ -579,6 +579,8 @@ struct bcma_pflash { }; #ifdef CONFIG_BCMA_SFLASH +struct mtd_info; + struct bcma_sflash { bool present; u32 window; @@ -592,13 +594,9 @@ struct bcma_sflash { #endif #ifdef CONFIG_BCMA_NFLASH -struct mtd_info; - struct bcma_nflash { bool present; bool boot; /* This is the flash the SoC boots from */ - - struct mtd_info *mtd; }; #endif -- GitLab From d8fe4f0e74cb27e79b2b500ca6eae9f9b02748b4 Mon Sep 17 00:00:00 2001 From: Fan Li Date: Mon, 14 Dec 2015 13:34:00 +0800 Subject: [PATCH 1253/2855] f2fs: write only the pages in range during defragment @lend of filemap_write_and_wait_range is supposed to be a "offset in bytes where the range ends (inclusive)". Subtract 1 to avoid writing an extra page. Signed-off-by: Fan li Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 294e71576cec9..5fac4f2599651 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1686,7 +1686,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi, /* writeback all dirty pages in the range */ err = filemap_write_and_wait_range(inode->i_mapping, range->start, - range->start + range->len); + range->start + range->len - 1); if (err) goto out; -- GitLab From e8931582bdaf4d4a6ee7e520ef0ccd481713a42a Mon Sep 17 00:00:00 2001 From: Fan Li Date: Mon, 14 Dec 2015 15:26:04 +0800 Subject: [PATCH 1254/2855] f2fs: fix to update variable correctly when skip a unmapped block map.m_len should be reduced after skip a block Signed-off-by: Fan li Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 5fac4f2599651..9949d0f332c2a 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1759,6 +1759,7 @@ do_map: if (!(map.m_flags & F2FS_MAP_FLAGS)) { map.m_lblk++; + map.m_len--; continue; } -- GitLab From e2042a8a80ab598bbb8d06cd7f3078923c7c77e3 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Thu, 15 Oct 2015 10:37:47 +0200 Subject: [PATCH 1255/2855] checkkconfigsymbols.py: multiprocessing of files Distribute the parsing of source and Kconfig files on all available cores to speed up processing. Signed-off-by: Valentin Rothberg Signed-off-by: Greg Kroah-Hartman --- scripts/checkkconfigsymbols.py | 128 ++++++++++++++++++++++++++------- 1 file changed, 102 insertions(+), 26 deletions(-) diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py index 2f4b7ffd55700..cfe397b61c48c 100755 --- a/scripts/checkkconfigsymbols.py +++ b/scripts/checkkconfigsymbols.py @@ -10,9 +10,11 @@ import os import re +import signal import sys -from subprocess import Popen, PIPE, STDOUT +from multiprocessing import Pool, cpu_count from optparse import OptionParser +from subprocess import Popen, PIPE, STDOUT # regex expressions @@ -26,7 +28,7 @@ SOURCE_FEATURE = r"(?:\W|\b)+[D]{,1}CONFIG_(" + FEATURE + r")" # regex objects REGEX_FILE_KCONFIG = re.compile(r".*Kconfig[\.\w+\-]*$") -REGEX_FEATURE = re.compile(r'(?!\B"[^"]*)' + FEATURE + r'(?![^"]*"\B)') +REGEX_FEATURE = re.compile(r'(?!\B)' + FEATURE + r'(?!\B)') REGEX_SOURCE_FEATURE = re.compile(SOURCE_FEATURE) REGEX_KCONFIG_DEF = re.compile(DEF) REGEX_KCONFIG_EXPR = re.compile(EXPR) @@ -34,6 +36,7 @@ REGEX_KCONFIG_STMT = re.compile(STMT) REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$") REGEX_FILTER_FEATURES = re.compile(r"[A-Za-z0-9]$") REGEX_NUMERIC = re.compile(r"0[xX][0-9a-fA-F]+|[0-9]+") +REGEX_QUOTES = re.compile("(\"(.*?)\")") def parse_options(): @@ -209,14 +212,36 @@ def get_head(): return stdout.strip('\n') +def partition(lst, size): + """Partition list @lst into eveni-sized lists of size @size.""" + return [lst[i::size] for i in xrange(size)] + + +def init_worker(): + """Set signal handler to ignore SIGINT.""" + signal.signal(signal.SIGINT, signal.SIG_IGN) + + def check_symbols(ignore): """Find undefined Kconfig symbols and return a dict with the symbol as key and a list of referencing files as value. Files matching %ignore are not checked for undefined symbols.""" + pool = Pool(cpu_count(), init_worker) + try: + return check_symbols_helper(pool, ignore) + except KeyboardInterrupt: + pool.terminate() + pool.join() + sys.exit(1) + + +def check_symbols_helper(pool, ignore): + """Helper method for check_symbols(). Used to catch keyboard interrupts in + check_symbols() in order to properly terminate running worker processes.""" source_files = [] kconfig_files = [] - defined_features = set() - referenced_features = dict() # {feature: [files]} + defined_features = [] + referenced_features = dict() # {file: [features]} # use 'git ls-files' to get the worklist stdout = execute("git ls-files") @@ -231,21 +256,33 @@ def check_symbols(ignore): if REGEX_FILE_KCONFIG.match(gitfile): kconfig_files.append(gitfile) else: - # all non-Kconfig files are checked for consistency + if ignore and not re.match(ignore, gitfile): + continue + # add source files that do not match the ignore pattern source_files.append(gitfile) - for sfile in source_files: - if ignore and re.match(ignore, sfile): - # do not check files matching %ignore - continue - parse_source_file(sfile, referenced_features) + # parse source files + arglist = partition(source_files, cpu_count()) + for res in pool.map(parse_source_files, arglist): + referenced_features.update(res) - for kfile in kconfig_files: - if ignore and re.match(ignore, kfile): - # do not collect references for files matching %ignore - parse_kconfig_file(kfile, defined_features, dict()) - else: - parse_kconfig_file(kfile, defined_features, referenced_features) + + # parse kconfig files + arglist = [] + for part in partition(kconfig_files, cpu_count()): + arglist.append((part, ignore)) + for res in pool.map(parse_kconfig_files, arglist): + defined_features.extend(res[0]) + referenced_features.update(res[1]) + defined_features = set(defined_features) + + # inverse mapping of referenced_features to dict(feature: [files]) + inv_map = dict() + for _file, features in referenced_features.iteritems(): + for feature in features: + inv_map[feature] = inv_map.get(feature, set()) + inv_map[feature].add(_file) + referenced_features = inv_map undefined = {} # {feature: [files]} for feature in sorted(referenced_features): @@ -262,9 +299,23 @@ def check_symbols(ignore): return undefined -def parse_source_file(sfile, referenced_features): - """Parse @sfile for referenced Kconfig features.""" +def parse_source_files(source_files): + """Parse each source file in @source_files and return dictionary with source + files as keys and lists of references Kconfig symbols as values.""" + referenced_features = dict() + for sfile in source_files: + referenced_features[sfile] = parse_source_file(sfile) + return referenced_features + + +def parse_source_file(sfile): + """Parse @sfile and return a list of referenced Kconfig features.""" lines = [] + references = [] + + if not os.path.exists(sfile): + return references + with open(sfile, "r") as stream: lines = stream.readlines() @@ -275,9 +326,9 @@ def parse_source_file(sfile, referenced_features): for feature in features: if not REGEX_FILTER_FEATURES.search(feature): continue - sfiles = referenced_features.get(feature, set()) - sfiles.add(sfile) - referenced_features[feature] = sfiles + references.append(feature) + + return references def get_features_in_line(line): @@ -285,11 +336,35 @@ def get_features_in_line(line): return REGEX_FEATURE.findall(line) -def parse_kconfig_file(kfile, defined_features, referenced_features): +def parse_kconfig_files(args): + """Parse kconfig files and return tuple of defined and references Kconfig + symbols. Note, @args is a tuple of a list of files and the @ignore + pattern.""" + kconfig_files = args[0] + ignore = args[1] + defined_features = [] + referenced_features = dict() + + for kfile in kconfig_files: + defined, references = parse_kconfig_file(kfile) + defined_features.extend(defined) + if ignore and re.match(ignore, kfile): + # do not collect references for files that match the ignore pattern + continue + referenced_features[kfile] = references + return (defined_features, referenced_features) + + +def parse_kconfig_file(kfile): """Parse @kfile and update feature definitions and references.""" lines = [] + defined = [] + references = [] skip = False + if not os.path.exists(kfile): + return defined, references + with open(kfile, "r") as stream: lines = stream.readlines() @@ -300,7 +375,7 @@ def parse_kconfig_file(kfile, defined_features, referenced_features): if REGEX_KCONFIG_DEF.match(line): feature_def = REGEX_KCONFIG_DEF.findall(line) - defined_features.add(feature_def[0]) + defined.append(feature_def[0]) skip = False elif REGEX_KCONFIG_HELP.match(line): skip = True @@ -308,6 +383,7 @@ def parse_kconfig_file(kfile, defined_features, referenced_features): # ignore content of help messages pass elif REGEX_KCONFIG_STMT.match(line): + line = REGEX_QUOTES.sub("", line) features = get_features_in_line(line) # multi-line statements while line.endswith("\\"): @@ -319,9 +395,9 @@ def parse_kconfig_file(kfile, defined_features, referenced_features): if REGEX_NUMERIC.match(feature): # ignore numeric values continue - paths = referenced_features.get(feature, set()) - paths.add(kfile) - referenced_features[feature] = paths + references.append(feature) + + return defined, references if __name__ == "__main__": -- GitLab From 1b2c841467515425636c15799ac90f6c4821acc0 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Thu, 26 Nov 2015 14:17:15 +0100 Subject: [PATCH 1256/2855] checkkconfigsymbols.py: find similar symbols Add support to find string-similar symbols. When option --sim SYM is specified, checkkconfigsymbols.py will print at most 10 symbols defined in Kconfig that are string similar to SYM in the following format: Similar symbols: $COMMA_SEPARATED_LIST_OF_SYMBOLS Note, if no similar symbols are found it is indicated as follows: Similar symbols: no similar symbols found Since the implemented functionality is also useful when searching the entire source or when diffing two commits, a list of similar symbols is printed unconditionally with the other data. In order to make the output more readable, the format now looks as follows: $UNDEFINED_SYMBOL Referencing files: $COMMA_SEPARATED_LIST_OF_FILES Similar symbols: $COMMA_SEPARATED_LIST_OF_SYMBOLS [Optional with '--find'] Commits changing symbol: - $COMMIT_1_HASH ("$COMMIT_1_MESSAGE") - $COMMIT_2_HASH ("$COMMIT_2_MESSAGE") or - no commit found Signed-off-by: Valentin Rothberg Signed-off-by: Greg Kroah-Hartman --- scripts/checkkconfigsymbols.py | 114 +++++++++++++++++++++++++-------- 1 file changed, 88 insertions(+), 26 deletions(-) diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py index cfe397b61c48c..d8f6c094cce5d 100755 --- a/scripts/checkkconfigsymbols.py +++ b/scripts/checkkconfigsymbols.py @@ -8,6 +8,7 @@ # Licensed under the terms of the GNU GPL License version 2 +import difflib import os import re import signal @@ -74,6 +75,9 @@ def parse_options(): "the pattern needs to be a Python regex. To " "ignore defconfigs, specify -i '.*defconfig'.") + parser.add_option('-s', '--sim', dest='sim', action='store', default="", + help="Print a list of maximum 10 string-similar symbols.") + parser.add_option('', '--force', dest='force', action='store_true', default=False, help="Reset current Git tree even when it's dirty.") @@ -112,6 +116,18 @@ def main(): """Main function of this module.""" opts = parse_options() + if opts.sim and not opts.commit and not opts.diff: + sims = find_sims(opts.sim, opts.ignore) + if sims: + print "%s: %s" % (yel("Similar symbols"), ', '.join(sims)) + else: + print "%s: no similar symbols found" % yel("Similar symbols") + sys.exit(0) + + # dictionary of (un)defined symbols + defined = {} + undefined = {} + if opts.commit or opts.diff: head = get_head() @@ -130,40 +146,56 @@ def main(): # get undefined items before the commit execute("git reset --hard %s" % commit_a) - undefined_a = check_symbols(opts.ignore) + undefined_a, _ = check_symbols(opts.ignore) # get undefined items for the commit execute("git reset --hard %s" % commit_b) - undefined_b = check_symbols(opts.ignore) + undefined_b, defined = check_symbols(opts.ignore) # report cases that are present for the commit but not before for feature in sorted(undefined_b): # feature has not been undefined before if not feature in undefined_a: files = sorted(undefined_b.get(feature)) - print "%s\t%s" % (yel(feature), ", ".join(files)) - if opts.find: - commits = find_commits(feature, opts.diff) - print red(commits) + undefined[feature] = files # check if there are new files that reference the undefined feature else: files = sorted(undefined_b.get(feature) - undefined_a.get(feature)) if files: - print "%s\t%s" % (yel(feature), ", ".join(files)) - if opts.find: - commits = find_commits(feature, opts.diff) - print red(commits) + undefined[feature] = files # reset to head execute("git reset --hard %s" % head) # default to check the entire tree else: - undefined = check_symbols(opts.ignore) - for feature in sorted(undefined): - files = sorted(undefined.get(feature)) - print "%s\t%s" % (yel(feature), ", ".join(files)) + undefined, defined = check_symbols(opts.ignore) + + # now print the output + for feature in sorted(undefined): + print red(feature) + + files = sorted(undefined.get(feature)) + print "%s: %s" % (yel("Referencing files"), ", ".join(files)) + + sims = find_sims(feature, opts.ignore, defined) + sims_out = yel("Similar symbols") + if sims: + print "%s: %s" % (sims_out, ', '.join(sims)) + else: + print "%s: %s" % (sims_out, "no similar symbols found") + + if opts.find: + print "%s:" % yel("Commits changing symbol") + commits = find_commits(feature, opts.diff) + if commits: + for commit in commits: + commit = commit.split(" ", 1) + print "\t- %s (\"%s\")" % (yel(commit[0]), commit[1]) + else: + print "\t- no commit found" + print # new line def yel(string): @@ -193,7 +225,7 @@ def find_commits(symbol, diff): """Find commits changing %symbol in the given range of %diff.""" commits = execute("git log --pretty=oneline --abbrev-commit -G %s %s" % (symbol, diff)) - return commits + return [x for x in commits.split("\n") if x] def tree_is_dirty(): @@ -222,6 +254,45 @@ def init_worker(): signal.signal(signal.SIGINT, signal.SIG_IGN) +def find_sims(symbol, ignore, defined = []): + """Return a list of max. ten Kconfig symbols that are string-similar to + @symbol.""" + if defined: + return sorted(difflib.get_close_matches(symbol, set(defined), 10)) + + pool = Pool(cpu_count(), init_worker) + kfiles = [] + for gitfile in get_files(): + if REGEX_FILE_KCONFIG.match(gitfile): + kfiles.append(gitfile) + + arglist = [] + for part in partition(kfiles, cpu_count()): + arglist.append((part, ignore)) + + for res in pool.map(parse_kconfig_files, arglist): + defined.extend(res[0]) + + return sorted(difflib.get_close_matches(symbol, set(defined), 10)) + + +def get_files(): + """Return a list of all files in the current git directory.""" + # use 'git ls-files' to get the worklist + stdout = execute("git ls-files") + if len(stdout) > 0 and stdout[-1] == "\n": + stdout = stdout[:-1] + + files = [] + for gitfile in stdout.rsplit("\n"): + if ".git" in gitfile or "ChangeLog" in gitfile or \ + ".log" in gitfile or os.path.isdir(gitfile) or \ + gitfile.startswith("tools/"): + continue + files.append(gitfile) + return files + + def check_symbols(ignore): """Find undefined Kconfig symbols and return a dict with the symbol as key and a list of referencing files as value. Files matching %ignore are not @@ -243,16 +314,7 @@ def check_symbols_helper(pool, ignore): defined_features = [] referenced_features = dict() # {file: [features]} - # use 'git ls-files' to get the worklist - stdout = execute("git ls-files") - if len(stdout) > 0 and stdout[-1] == "\n": - stdout = stdout[:-1] - - for gitfile in stdout.rsplit("\n"): - if ".git" in gitfile or "ChangeLog" in gitfile or \ - ".log" in gitfile or os.path.isdir(gitfile) or \ - gitfile.startswith("tools/"): - continue + for gitfile in get_files(): if REGEX_FILE_KCONFIG.match(gitfile): kconfig_files.append(gitfile) else: @@ -296,7 +358,7 @@ def check_symbols_helper(pool, ignore): if feature[:-len("_MODULE")] in defined_features: continue undefined[feature] = referenced_features.get(feature) - return undefined + return undefined, defined_features def parse_source_files(source_files): -- GitLab From d3ae4fa40088045b500f4d1ce85eb926b6cd2d3e Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Thu, 26 Nov 2015 11:03:56 -0200 Subject: [PATCH 1257/2855] staging/android: add TODO to de-stage android sync framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - remove CONFIG_SW_SYNC_USER, it is used only for testing/debugging and should not be upstreamed. - port CONFIG_SW_SYNC_USER tests interfaces to use debugfs somehow - port libsync tests to kselftest - clean up and ABI check for security issues - move the sync framework to drivers/base/dma-buf Cc: Arve Hjønnevåg Cc: Riley Andrews Cc: Daniel Vetter Cc: Rob Clark Cc: Greg Hackmann Cc: John Harrison Signed-off-by: Gustavo Padovan Acked-by: Daniel Vetter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/TODO | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/staging/android/TODO b/drivers/staging/android/TODO index 8f3ac37bfe12e..64d8c87209605 100644 --- a/drivers/staging/android/TODO +++ b/drivers/staging/android/TODO @@ -25,5 +25,13 @@ ion/ exposes existing cma regions and doesn't reserve unecessarily memory when booting a system which doesn't use ion. +sync framework: + - remove CONFIG_SW_SYNC_USER, it is used only for testing/debugging and + should not be upstreamed. + - port CONFIG_SW_SYNC_USER tests interfaces to use debugfs somehow + - port libsync tests to kselftest + - clean up and ABI check for security issues + - move it to drivers/base/dma-buf + Please send patches to Greg Kroah-Hartman and Cc: Arve Hjønnevåg and Riley Andrews -- GitLab From e7a4eb861203b605c6428ec29e0b5e3c3f4f537f Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Thu, 10 Dec 2015 17:13:41 +0100 Subject: [PATCH 1258/2855] udf: limit the maximum number of TD redirections Filesystem fuzzing revealed that we could get stuck in the udf_process_sequence() loop. The maximum limit was chosen arbitrarily but fixes the problem I saw. Signed-off-by: Vegard Nossum Signed-off-by: Jan Kara --- fs/udf/super.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/fs/udf/super.c b/fs/udf/super.c index 81155b9b445b3..fd45537eaa018 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1585,6 +1585,13 @@ static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_ brelse(bh); } +/* + * Maximum number of Terminating Descriptor redirections. The chosen number is + * arbitrary - just that we hopefully don't limit any real use of rewritten + * inode on write-once media but avoid looping for too long on corrupted media. + */ +#define UDF_MAX_TD_NESTING 64 + /* * Process a main/reserve volume descriptor sequence. * @block First block of first extent of the sequence. @@ -1609,6 +1616,7 @@ static noinline int udf_process_sequence( uint16_t ident; long next_s = 0, next_e = 0; int ret; + unsigned int indirections = 0; memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH); @@ -1679,6 +1687,12 @@ static noinline int udf_process_sequence( } break; case TAG_IDENT_TD: /* ISO 13346 3/10.9 */ + if (++indirections > UDF_MAX_TD_NESTING) { + udf_err(sb, "too many TDs (max %u supported)\n", UDF_MAX_TD_NESTING); + brelse(bh); + return -EIO; + } + vds[VDS_POS_TERMINATING_DESC].block = block; if (next_e) { block = next_s; -- GitLab From 9220e39b5c900c67ddcb517d52fe52d90fb5e3c8 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Fri, 11 Dec 2015 14:23:11 +0530 Subject: [PATCH 1259/2855] Drivers: hv: vmbus: fix build warning We were getting build warning about unused variable "tsc_msr" and "va_tsc" while building for i386 allmodconfig. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 6341be8739ae6..ad7fc6d92c359 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -192,9 +192,7 @@ int hv_init(void) { int max_leaf; union hv_x64_msr_hypercall_contents hypercall_msr; - union hv_x64_msr_hypercall_contents tsc_msr; void *virtaddr = NULL; - void *va_tsc = NULL; memset(hv_context.synic_event_page, 0, sizeof(void *) * NR_CPUS); memset(hv_context.synic_message_page, 0, @@ -240,6 +238,9 @@ int hv_init(void) #ifdef CONFIG_X86_64 if (ms_hyperv.features & HV_X64_MSR_REFERENCE_TSC_AVAILABLE) { + union hv_x64_msr_hypercall_contents tsc_msr; + void *va_tsc; + va_tsc = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL); if (!va_tsc) goto cleanup; -- GitLab From bb6da5d954b934305cc536f8cc970c500d1dd54d Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 14 Dec 2015 10:37:11 +0000 Subject: [PATCH 1260/2855] extcon: arizona: Add device bindings for the micd configurations Add device bindings to support configuring the jack detection configurations. Each configuration needs to specify the connection of the mic det pins, which micbias should be used and the value of the micd polarity GPIO required to activate that configuration. Signed-off-by: Charles Keepax Acked-by: Chanwoo Choi Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-arizona.c | 56 +++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index 86475338e51ee..c121d01a5cd6f 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -1201,10 +1201,58 @@ static void arizona_micd_set_level(struct arizona *arizona, int index, regmap_update_bits(arizona->regmap, reg, mask, level); } -static int arizona_extcon_device_get_pdata(struct arizona *arizona) +static int arizona_extcon_get_micd_configs(struct device *dev, + struct arizona *arizona) +{ + const char * const prop = "wlf,micd-configs"; + const int entries_per_config = 3; + struct arizona_micd_config *micd_configs; + int nconfs, ret; + int i, j; + u32 *vals; + + nconfs = device_property_read_u32_array(arizona->dev, prop, NULL, 0); + if (nconfs <= 0) + return 0; + + vals = kcalloc(nconfs, sizeof(u32), GFP_KERNEL); + if (!vals) + return -ENOMEM; + + ret = device_property_read_u32_array(arizona->dev, prop, vals, nconfs); + if (ret < 0) + goto out; + + nconfs /= entries_per_config; + + micd_configs = devm_kzalloc(dev, + nconfs * sizeof(struct arizona_micd_range), + GFP_KERNEL); + if (!micd_configs) { + ret = -ENOMEM; + goto out; + } + + for (i = 0, j = 0; i < nconfs; ++i) { + micd_configs[i].src = vals[j++] ? ARIZONA_ACCDET_SRC : 0; + micd_configs[i].bias = vals[j++]; + micd_configs[i].gpio = vals[j++]; + } + + arizona->pdata.micd_configs = micd_configs; + arizona->pdata.num_micd_configs = nconfs; + +out: + kfree(vals); + return ret; +} + +static int arizona_extcon_device_get_pdata(struct device *dev, + struct arizona *arizona) { struct arizona_pdata *pdata = &arizona->pdata; unsigned int val = ARIZONA_ACCDET_MODE_HPL; + int ret; device_property_read_u32(arizona->dev, "wlf,hpdet-channel", &val); switch (val) { @@ -1249,6 +1297,10 @@ static int arizona_extcon_device_get_pdata(struct arizona *arizona) pdata->jd_gpio5_nopull = device_property_read_bool(arizona->dev, "wlf,use-jd2-nopull"); + ret = arizona_extcon_get_micd_configs(dev, arizona); + if (ret < 0) + dev_err(arizona->dev, "Failed to read micd configs: %d\n", ret); + return 0; } @@ -1270,7 +1322,7 @@ static int arizona_extcon_probe(struct platform_device *pdev) return -ENOMEM; if (!dev_get_platdata(arizona->dev)) - arizona_extcon_device_get_pdata(arizona); + arizona_extcon_device_get_pdata(&pdev->dev, arizona); info->micvdd = devm_regulator_get(&pdev->dev, "MICVDD"); if (IS_ERR(info->micvdd)) { -- GitLab From cb0eac8fd1a3180ce260a8dca01584bc5495a8e8 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 14 Dec 2015 10:37:12 +0000 Subject: [PATCH 1261/2855] extcon: arizona: Update device tree binding for mic detect configurations Update the device tree binding documentation to include documentation for the wlf,micd-configs property that is used to specify the configurations for headset polarity detection (CTIA / OTMP). Signed-off-by: Charles Keepax Acked-by: Rob Herring Signed-off-by: Chanwoo Choi --- .../devicetree/bindings/extcon/extcon-arizona.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/extcon/extcon-arizona.txt b/Documentation/devicetree/bindings/extcon/extcon-arizona.txt index 238e10e86a204..fd9b898d2d7de 100644 --- a/Documentation/devicetree/bindings/extcon/extcon-arizona.txt +++ b/Documentation/devicetree/bindings/extcon/extcon-arizona.txt @@ -37,5 +37,13 @@ Optional properties: milliseconds. - wlf,micd-force-micbias : Force MICBIAS continuously on during microphone detection. + - wlf,micd-configs : Headset polarity configurations (generally used for + detection of CTIA / OMTP headsets), the field can be of variable length + but should always be a multiple of 3 cells long, each three cell group + represents one polarity configuration. + The first cell defines the accessory detection pin, zero will use MICDET1 + and all other values will use MICDET2. + The second cell represents the MICBIAS to be used. + The third cell represents the value of the micd-pol-gpio pin. - wlf,gpsw : Settings for the general purpose switch -- GitLab From 36e2693b68562d4b984b841c041ffa76370e9b7f Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 14 Dec 2015 10:37:13 +0000 Subject: [PATCH 1262/2855] extcon: arizona: Add DT binding examples Add an example for all elements of the Arizona extcon device tree binding. Signed-off-by: Charles Keepax Signed-off-by: Chanwoo Choi --- .../bindings/extcon/extcon-arizona.txt | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/Documentation/devicetree/bindings/extcon/extcon-arizona.txt b/Documentation/devicetree/bindings/extcon/extcon-arizona.txt index fd9b898d2d7de..e27341f8a4c7e 100644 --- a/Documentation/devicetree/bindings/extcon/extcon-arizona.txt +++ b/Documentation/devicetree/bindings/extcon/extcon-arizona.txt @@ -47,3 +47,29 @@ Optional properties: The third cell represents the value of the micd-pol-gpio pin. - wlf,gpsw : Settings for the general purpose switch + +Example: + +codec: wm8280@0 { + compatible = "wlf,wm8280"; + reg = <0>; + ... + + wlf,use-jd2; + wlf,use-jd2-nopull; + wlf,jd-invert; + + wlf,micd-software-compare; + wlf,micd-detect-debounce = <0>; + wlf,micd-pol-gpio = <&codec 2 0>; + wlf,micd-rate = ; + wlf,micd-dbtime = <4>; + wlf,micd-timeout-ms = <100>; + wlf,micd-force-micbias; + wlf,micd-configs = < + 0 1 0 /* MICDET1 MICBIAS1 GPIO=low */ + 1 2 1 /* MICDET2 MICBIAS2 GPIO=high */ + >; + + wlf,gpsw = <0>; +}; -- GitLab From c2957563ad0965c8bfb393dcd22ddb683dd1ff1c Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 14 Dec 2015 11:06:02 +0100 Subject: [PATCH 1263/2855] extcon: max14577: fix handling return value of regmap_irq_get_virq The function can return negative values, so its result should be assigned to signed variable. The problem has been detected using proposed semantic patch scripts/coccinelle/tests/assign_signed_to_unsigned.cocci [1]. [1]: http://permalink.gmane.org/gmane.linux.kernel/2046107 Signed-off-by: Andrzej Hajda Reviewed-by: Krzysztof Kozlowski Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-max14577.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/extcon/extcon-max14577.c b/drivers/extcon/extcon-max14577.c index 601dbd9964874..b30ab97ce75f7 100644 --- a/drivers/extcon/extcon-max14577.c +++ b/drivers/extcon/extcon-max14577.c @@ -692,7 +692,7 @@ static int max14577_muic_probe(struct platform_device *pdev) /* Support irq domain for max14577 MUIC device */ for (i = 0; i < info->muic_irqs_num; i++) { struct max14577_muic_irq *muic_irq = &info->muic_irqs[i]; - unsigned int virq = 0; + int virq = 0; virq = regmap_irq_get_virq(max14577->irq_data, muic_irq->irq); if (virq <= 0) -- GitLab From cbc46603df56b5933aef6765fc50d3aa18f96ced Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 14 Dec 2015 12:12:42 +0100 Subject: [PATCH 1264/2855] extcon: max77693: fix handling return value of regmap_irq_get_virq The function can return negative values, so its result should be assigned to signed variable. Signed-off-by: Andrzej Hajda Suggested-by: Krzysztof Kozlowski Reviewed-by: Krzysztof Kozlowski Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-max77693.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index 44c499e1beeed..fdf8f5d4d4e9f 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -1127,11 +1127,11 @@ static int max77693_muic_probe(struct platform_device *pdev) /* Support irq domain for MAX77693 MUIC device */ for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) { struct max77693_muic_irq *muic_irq = &muic_irqs[i]; - unsigned int virq = 0; + int virq; virq = regmap_irq_get_virq(max77693->irq_data_muic, muic_irq->irq); - if (!virq) + if (virq <= 0) return -EINVAL; muic_irq->virq = virq; -- GitLab From c05c0d544edfb0ffbbd01acd199ea9626bdfd6c3 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 14 Dec 2015 11:06:03 +0100 Subject: [PATCH 1265/2855] extcon: max77843: fix handling return value of regmap_irq_get_virq The function can return negative values, so its result should be assigned to signed variable. The problem has been detected using proposed semantic patch scripts/coccinelle/tests/assign_signed_to_unsigned.cocci [1]. [1]: http://permalink.gmane.org/gmane.linux.kernel/2046107 Signed-off-by: Andrzej Hajda Reviewed-by: Krzysztof Kozlowski Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-max77843.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/extcon/extcon-max77843.c b/drivers/extcon/extcon-max77843.c index 9f9ea334399c1..74dfb7f4f2774 100644 --- a/drivers/extcon/extcon-max77843.c +++ b/drivers/extcon/extcon-max77843.c @@ -811,7 +811,7 @@ static int max77843_muic_probe(struct platform_device *pdev) for (i = 0; i < ARRAY_SIZE(max77843_muic_irqs); i++) { struct max77843_muic_irq *muic_irq = &max77843_muic_irqs[i]; - unsigned int virq = 0; + int virq = 0; virq = regmap_irq_get_virq(max77843->irq_data_muic, muic_irq->irq); -- GitLab From 9a59b62fd88196844cee5fff851bee2cfd7afb6e Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 15 Dec 2015 09:58:18 +0800 Subject: [PATCH 1266/2855] f2fs: do more integrity verification for superblock Do more sanity check for superblock during ->mount. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/super.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index dbf16ade0e9a7..a6f2beda22b9f 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -918,6 +918,79 @@ static loff_t max_file_size(unsigned bits) return result; } +static inline bool sanity_check_area_boundary(struct super_block *sb, + struct f2fs_super_block *raw_super) +{ + u32 segment0_blkaddr = le32_to_cpu(raw_super->segment0_blkaddr); + u32 cp_blkaddr = le32_to_cpu(raw_super->cp_blkaddr); + u32 sit_blkaddr = le32_to_cpu(raw_super->sit_blkaddr); + u32 nat_blkaddr = le32_to_cpu(raw_super->nat_blkaddr); + u32 ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr); + u32 main_blkaddr = le32_to_cpu(raw_super->main_blkaddr); + u32 segment_count_ckpt = le32_to_cpu(raw_super->segment_count_ckpt); + u32 segment_count_sit = le32_to_cpu(raw_super->segment_count_sit); + u32 segment_count_nat = le32_to_cpu(raw_super->segment_count_nat); + u32 segment_count_ssa = le32_to_cpu(raw_super->segment_count_ssa); + u32 segment_count_main = le32_to_cpu(raw_super->segment_count_main); + u32 segment_count = le32_to_cpu(raw_super->segment_count); + u32 log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg); + + if (segment0_blkaddr != cp_blkaddr) { + f2fs_msg(sb, KERN_INFO, + "Mismatch start address, segment0(%u) cp_blkaddr(%u)", + segment0_blkaddr, cp_blkaddr); + return true; + } + + if (cp_blkaddr + (segment_count_ckpt << log_blocks_per_seg) != + sit_blkaddr) { + f2fs_msg(sb, KERN_INFO, + "Wrong CP boundary, start(%u) end(%u) blocks(%u)", + cp_blkaddr, sit_blkaddr, + segment_count_ckpt << log_blocks_per_seg); + return true; + } + + if (sit_blkaddr + (segment_count_sit << log_blocks_per_seg) != + nat_blkaddr) { + f2fs_msg(sb, KERN_INFO, + "Wrong SIT boundary, start(%u) end(%u) blocks(%u)", + sit_blkaddr, nat_blkaddr, + segment_count_sit << log_blocks_per_seg); + return true; + } + + if (nat_blkaddr + (segment_count_nat << log_blocks_per_seg) != + ssa_blkaddr) { + f2fs_msg(sb, KERN_INFO, + "Wrong NAT boundary, start(%u) end(%u) blocks(%u)", + nat_blkaddr, ssa_blkaddr, + segment_count_nat << log_blocks_per_seg); + return true; + } + + if (ssa_blkaddr + (segment_count_ssa << log_blocks_per_seg) != + main_blkaddr) { + f2fs_msg(sb, KERN_INFO, + "Wrong SSA boundary, start(%u) end(%u) blocks(%u)", + ssa_blkaddr, main_blkaddr, + segment_count_ssa << log_blocks_per_seg); + return true; + } + + if (main_blkaddr + (segment_count_main << log_blocks_per_seg) != + segment0_blkaddr + (segment_count << log_blocks_per_seg)) { + f2fs_msg(sb, KERN_INFO, + "Wrong MAIN_AREA boundary, start(%u) end(%u) blocks(%u)", + main_blkaddr, + segment0_blkaddr + (segment_count << log_blocks_per_seg), + segment_count_main << log_blocks_per_seg); + return true; + } + + return false; +} + static int sanity_check_raw_super(struct super_block *sb, struct f2fs_super_block *raw_super) { @@ -947,6 +1020,14 @@ static int sanity_check_raw_super(struct super_block *sb, return 1; } + /* check log blocks per segment */ + if (le32_to_cpu(raw_super->log_blocks_per_seg) != 9) { + f2fs_msg(sb, KERN_INFO, + "Invalid log blocks per segment (%u)\n", + le32_to_cpu(raw_super->log_blocks_per_seg)); + return 1; + } + /* Currently, support 512/1024/2048/4096 bytes sector size */ if (le32_to_cpu(raw_super->log_sectorsize) > F2FS_MAX_LOG_SECTOR_SIZE || @@ -965,6 +1046,23 @@ static int sanity_check_raw_super(struct super_block *sb, le32_to_cpu(raw_super->log_sectorsize)); return 1; } + + /* check reserved ino info */ + if (le32_to_cpu(raw_super->node_ino) != 1 || + le32_to_cpu(raw_super->meta_ino) != 2 || + le32_to_cpu(raw_super->root_ino) != 3) { + f2fs_msg(sb, KERN_INFO, + "Invalid Fs Meta Ino: node(%u) meta(%u) root(%u)", + le32_to_cpu(raw_super->node_ino), + le32_to_cpu(raw_super->meta_ino), + le32_to_cpu(raw_super->root_ino)); + return 1; + } + + /* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */ + if (sanity_check_area_boundary(sb, raw_super)) + return 1; + return 0; } -- GitLab From a11fac3776fc4db6a9fa1104b1d0477809c677e0 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 14 Dec 2015 18:58:42 -0800 Subject: [PATCH 1267/2855] f2fs: add symbol to avoid any confusion with tools This patch adds MAX_VOLUME_NAME to sync with f2fs-tools. Signed-off-by: Jaegeuk Kim --- include/linux/f2fs_fs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index 25c6324a0dd04..e59c3be921069 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -51,6 +51,7 @@ #define MAX_ACTIVE_DATA_LOGS 8 #define VERSION_LEN 256 +#define MAX_VOLUME_NAME 512 /* * For superblock @@ -84,7 +85,7 @@ struct f2fs_super_block { __le32 node_ino; /* node inode number */ __le32 meta_ino; /* meta inode number */ __u8 uuid[16]; /* 128-bit uuid for volume */ - __le16 volume_name[512]; /* volume name */ + __le16 volume_name[MAX_VOLUME_NAME]; /* volume name */ __le32 extension_count; /* # of extensions below */ __u8 extension_list[F2FS_MAX_EXTENSION][8]; /* extension array */ __le32 cp_payload; -- GitLab From c0b200cfb0403740171c7527b3ac71d03f82947a Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 14 Dec 2015 16:01:32 -0800 Subject: [PATCH 1268/2855] Drivers: hv: util: Increase the timeout for util services Util services such as KVP and FCOPY need assistance from daemon's running in user space. Increase the timeout so we don't prematurely terminate the transaction in the kernel. Host sets up a 60 second timeout for all util driver transactions. The host will retry the transaction if it times out. Set the guest timeout at 30 seconds. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_fcopy.c | 3 ++- drivers/hv/hv_kvp.c | 3 ++- drivers/hv/hyperv_vmbus.h | 5 +++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c index db4b887b889d2..bbdec50c4a1c1 100644 --- a/drivers/hv/hv_fcopy.c +++ b/drivers/hv/hv_fcopy.c @@ -275,7 +275,8 @@ void hv_fcopy_onchannelcallback(void *context) * Send the information to the user-level daemon. */ schedule_work(&fcopy_send_work); - schedule_delayed_work(&fcopy_timeout_work, 5*HZ); + schedule_delayed_work(&fcopy_timeout_work, + HV_UTIL_TIMEOUT * HZ); return; } icmsghdr->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index 74c38a9f34a60..e6aa33a89b0ea 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c @@ -668,7 +668,8 @@ void hv_kvp_onchannelcallback(void *context) * user-mode not responding. */ schedule_work(&kvp_sendkey_work); - schedule_delayed_work(&kvp_timeout_work, 5*HZ); + schedule_delayed_work(&kvp_timeout_work, + HV_UTIL_TIMEOUT * HZ); return; diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 3782636562a1b..225b96bcf7fe1 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -30,6 +30,11 @@ #include #include +/* + * Timeout for services such as KVP and fcopy. + */ +#define HV_UTIL_TIMEOUT 30 + /* * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent * is set by CPUID(HVCPUID_VERSION_FEATURES). -- GitLab From 3cace4a616108539e2730f8dc21a636474395e0f Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Mon, 14 Dec 2015 16:01:33 -0800 Subject: [PATCH 1269/2855] Drivers: hv: utils: run polling callback always in interrupt context All channel interrupts are bound to specific VCPUs in the guest at the point channel is created. While currently, we invoke the polling function on the correct CPU (the CPU to which the channel is bound to) in some cases we may run the polling function in a non-interrupt context. This potentially can cause an issue as the polling function can be interrupted by the channel callback function. Fix the issue by running the polling function on the appropriate CPU at interrupt level. Additional details of the issue being addressed by this patch are given below: Currently hv_fcopy_onchannelcallback is called from interrupts and also via the ->write function of hv_utils. Since the used global variables to maintain state are not thread safe the state can get out of sync. This affects the variable state as well as the channel inbound buffer. As suggested by KY adjust hv_poll_channel to always run the given callback on the cpu which the channel is bound to. This avoids the need for locking because all the util services are single threaded and only one transaction is active at any given point in time. Additionally, remove the context variable, they will always be the same as recv_channel. Signed-off-by: Olaf Hering Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_fcopy.c | 34 ++++++++++++---------------------- drivers/hv/hv_kvp.c | 28 ++++++++++------------------ drivers/hv/hv_snapshot.c | 29 +++++++++++------------------ drivers/hv/hyperv_vmbus.h | 6 +----- 4 files changed, 34 insertions(+), 63 deletions(-) diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c index bbdec50c4a1c1..c37a71e13de09 100644 --- a/drivers/hv/hv_fcopy.c +++ b/drivers/hv/hv_fcopy.c @@ -51,7 +51,6 @@ static struct { struct hv_fcopy_hdr *fcopy_msg; /* current message */ struct vmbus_channel *recv_channel; /* chn we got the request */ u64 recv_req_id; /* request ID. */ - void *fcopy_context; /* for the channel callback */ } fcopy_transaction; static void fcopy_respond_to_host(int error); @@ -67,6 +66,13 @@ static struct hvutil_transport *hvt; */ static int dm_reg_value; +static void fcopy_poll_wrapper(void *channel) +{ + /* Transaction is finished, reset the state here to avoid races. */ + fcopy_transaction.state = HVUTIL_READY; + hv_fcopy_onchannelcallback(channel); +} + static void fcopy_timeout_func(struct work_struct *dummy) { /* @@ -74,13 +80,7 @@ static void fcopy_timeout_func(struct work_struct *dummy) * process the pending transaction. */ fcopy_respond_to_host(HV_E_FAIL); - - /* Transaction is finished, reset the state. */ - if (fcopy_transaction.state > HVUTIL_READY) - fcopy_transaction.state = HVUTIL_READY; - - hv_poll_channel(fcopy_transaction.fcopy_context, - hv_fcopy_onchannelcallback); + hv_poll_channel(fcopy_transaction.recv_channel, fcopy_poll_wrapper); } static int fcopy_handle_handshake(u32 version) @@ -108,9 +108,7 @@ static int fcopy_handle_handshake(u32 version) return -EINVAL; } pr_debug("FCP: userspace daemon ver. %d registered\n", version); - fcopy_transaction.state = HVUTIL_READY; - hv_poll_channel(fcopy_transaction.fcopy_context, - hv_fcopy_onchannelcallback); + hv_poll_channel(fcopy_transaction.recv_channel, fcopy_poll_wrapper); return 0; } @@ -227,15 +225,8 @@ void hv_fcopy_onchannelcallback(void *context) int util_fw_version; int fcopy_srv_version; - if (fcopy_transaction.state > HVUTIL_READY) { - /* - * We will defer processing this callback once - * the current transaction is complete. - */ - fcopy_transaction.fcopy_context = context; + if (fcopy_transaction.state > HVUTIL_READY) return; - } - fcopy_transaction.fcopy_context = NULL; vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen, &requestid); @@ -305,9 +296,8 @@ static int fcopy_on_msg(void *msg, int len) if (cancel_delayed_work_sync(&fcopy_timeout_work)) { fcopy_transaction.state = HVUTIL_USERSPACE_RECV; fcopy_respond_to_host(*val); - fcopy_transaction.state = HVUTIL_READY; - hv_poll_channel(fcopy_transaction.fcopy_context, - hv_fcopy_onchannelcallback); + hv_poll_channel(fcopy_transaction.recv_channel, + fcopy_poll_wrapper); } return 0; diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index e6aa33a89b0ea..2a3420c4ca598 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c @@ -66,7 +66,6 @@ static struct { struct hv_kvp_msg *kvp_msg; /* current message */ struct vmbus_channel *recv_channel; /* chn we got the request */ u64 recv_req_id; /* request ID. */ - void *kvp_context; /* for the channel callback */ } kvp_transaction; /* @@ -94,6 +93,13 @@ static struct hvutil_transport *hvt; */ #define HV_DRV_VERSION "3.1" +static void kvp_poll_wrapper(void *channel) +{ + /* Transaction is finished, reset the state here to avoid races. */ + kvp_transaction.state = HVUTIL_READY; + hv_kvp_onchannelcallback(channel); +} + static void kvp_register(int reg_value) { @@ -121,12 +127,7 @@ static void kvp_timeout_func(struct work_struct *dummy) */ kvp_respond_to_host(NULL, HV_E_FAIL); - /* Transaction is finished, reset the state. */ - if (kvp_transaction.state > HVUTIL_READY) - kvp_transaction.state = HVUTIL_READY; - - hv_poll_channel(kvp_transaction.kvp_context, - hv_kvp_onchannelcallback); + hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper); } static int kvp_handle_handshake(struct hv_kvp_msg *msg) @@ -218,9 +219,7 @@ static int kvp_on_msg(void *msg, int len) */ if (cancel_delayed_work_sync(&kvp_timeout_work)) { kvp_respond_to_host(message, error); - kvp_transaction.state = HVUTIL_READY; - hv_poll_channel(kvp_transaction.kvp_context, - hv_kvp_onchannelcallback); + hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper); } return 0; @@ -596,15 +595,8 @@ void hv_kvp_onchannelcallback(void *context) int util_fw_version; int kvp_srv_version; - if (kvp_transaction.state > HVUTIL_READY) { - /* - * We will defer processing this callback once - * the current transaction is complete. - */ - kvp_transaction.kvp_context = context; + if (kvp_transaction.state > HVUTIL_READY) return; - } - kvp_transaction.kvp_context = NULL; vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 4, &recvlen, &requestid); diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c index 815405f2e777d..a548ae42c927a 100644 --- a/drivers/hv/hv_snapshot.c +++ b/drivers/hv/hv_snapshot.c @@ -53,7 +53,6 @@ static struct { struct vmbus_channel *recv_channel; /* chn we got the request */ u64 recv_req_id; /* request ID. */ struct hv_vss_msg *msg; /* current message */ - void *vss_context; /* for the channel callback */ } vss_transaction; @@ -74,6 +73,13 @@ static void vss_timeout_func(struct work_struct *dummy); static DECLARE_DELAYED_WORK(vss_timeout_work, vss_timeout_func); static DECLARE_WORK(vss_send_op_work, vss_send_op); +static void vss_poll_wrapper(void *channel) +{ + /* Transaction is finished, reset the state here to avoid races. */ + vss_transaction.state = HVUTIL_READY; + hv_vss_onchannelcallback(channel); +} + /* * Callback when data is received from user mode. */ @@ -86,12 +92,7 @@ static void vss_timeout_func(struct work_struct *dummy) pr_warn("VSS: timeout waiting for daemon to reply\n"); vss_respond_to_host(HV_E_FAIL); - /* Transaction is finished, reset the state. */ - if (vss_transaction.state > HVUTIL_READY) - vss_transaction.state = HVUTIL_READY; - - hv_poll_channel(vss_transaction.vss_context, - hv_vss_onchannelcallback); + hv_poll_channel(vss_transaction.recv_channel, vss_poll_wrapper); } static int vss_handle_handshake(struct hv_vss_msg *vss_msg) @@ -138,9 +139,8 @@ static int vss_on_msg(void *msg, int len) if (cancel_delayed_work_sync(&vss_timeout_work)) { vss_respond_to_host(vss_msg->error); /* Transaction is finished, reset the state. */ - vss_transaction.state = HVUTIL_READY; - hv_poll_channel(vss_transaction.vss_context, - hv_vss_onchannelcallback); + hv_poll_channel(vss_transaction.recv_channel, + vss_poll_wrapper); } } else { /* This is a spurious call! */ @@ -238,15 +238,8 @@ void hv_vss_onchannelcallback(void *context) struct icmsg_hdr *icmsghdrp; struct icmsg_negotiate *negop = NULL; - if (vss_transaction.state > HVUTIL_READY) { - /* - * We will defer processing this callback once - * the current transaction is complete. - */ - vss_transaction.vss_context = context; + if (vss_transaction.state > HVUTIL_READY) return; - } - vss_transaction.vss_context = NULL; vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen, &requestid); diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 225b96bcf7fe1..12156db2e88e2 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -764,11 +764,7 @@ static inline void hv_poll_channel(struct vmbus_channel *channel, if (!channel) return; - if (channel->target_cpu != smp_processor_id()) - smp_call_function_single(channel->target_cpu, - cb, channel, true); - else - cb(channel); + smp_call_function_single(channel->target_cpu, cb, channel, true); } enum hvutil_device_state { -- GitLab From b4ed5d1682c6613988c2eb1de55df5ac9988afcc Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Mon, 14 Dec 2015 16:01:34 -0800 Subject: [PATCH 1270/2855] tools: hv: report ENOSPC errors in hv_fcopy_daemon Currently some "Unspecified error 0x80004005" is reported on the Windows side if something fails. Handle the ENOSPC case and return ERROR_DISK_FULL, which allows at least Copy-VMFile to report a meaning full error. Signed-off-by: Olaf Hering Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/hyperv.h | 1 + tools/hv/hv_fcopy_daemon.c | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/include/uapi/linux/hyperv.h b/include/uapi/linux/hyperv.h index e4c0a35d6417c..e347b24ef9fb6 100644 --- a/include/uapi/linux/hyperv.h +++ b/include/uapi/linux/hyperv.h @@ -313,6 +313,7 @@ enum hv_kvp_exchg_pool { #define HV_INVALIDARG 0x80070057 #define HV_GUID_NOTFOUND 0x80041002 #define HV_ERROR_ALREADY_EXISTS 0x80070050 +#define HV_ERROR_DISK_FULL 0x80070070 #define ADDR_FAMILY_NONE 0x00 #define ADDR_FAMILY_IPV4 0x01 diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c index 5480e4e424eb1..f1d7426823179 100644 --- a/tools/hv/hv_fcopy_daemon.c +++ b/tools/hv/hv_fcopy_daemon.c @@ -37,12 +37,14 @@ static int target_fd; static char target_fname[W_MAX_PATH]; +static unsigned long long filesize; static int hv_start_fcopy(struct hv_start_fcopy *smsg) { int error = HV_E_FAIL; char *q, *p; + filesize = 0; p = (char *)smsg->path_name; snprintf(target_fname, sizeof(target_fname), "%s/%s", (char *)smsg->path_name, (char *)smsg->file_name); @@ -98,14 +100,26 @@ done: static int hv_copy_data(struct hv_do_fcopy *cpmsg) { ssize_t bytes_written; + int ret = 0; bytes_written = pwrite(target_fd, cpmsg->data, cpmsg->size, cpmsg->offset); - if (bytes_written != cpmsg->size) - return HV_E_FAIL; + filesize += cpmsg->size; + if (bytes_written != cpmsg->size) { + switch (errno) { + case ENOSPC: + ret = HV_ERROR_DISK_FULL; + break; + default: + ret = HV_E_FAIL; + break; + } + syslog(LOG_ERR, "pwrite failed to write %llu bytes: %ld (%s)", + filesize, (long)bytes_written, strerror(errno)); + } - return 0; + return ret; } static int hv_copy_finished(void) -- GitLab From 6dfb867cea9e93ae9220f0b2e702b0440e4c8b4b Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Mon, 14 Dec 2015 16:01:35 -0800 Subject: [PATCH 1271/2855] tools: hv: remove repeated HV_FCOPY string HV_FCOPY is already used as identifier in syslog. Signed-off-by: Olaf Hering Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- tools/hv/hv_fcopy_daemon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c index f1d7426823179..fdc9ca4c03563 100644 --- a/tools/hv/hv_fcopy_daemon.c +++ b/tools/hv/hv_fcopy_daemon.c @@ -179,7 +179,7 @@ int main(int argc, char *argv[]) } openlog("HV_FCOPY", 0, LOG_USER); - syslog(LOG_INFO, "HV_FCOPY starting; pid is:%d", getpid()); + syslog(LOG_INFO, "starting; pid is:%d", getpid()); fcopy_fd = open("/dev/vmbus/hv_fcopy", O_RDWR); @@ -215,7 +215,7 @@ int main(int argc, char *argv[]) } kernel_modver = *(__u32 *)buffer; in_handshake = 0; - syslog(LOG_INFO, "HV_FCOPY: kernel module version: %d", + syslog(LOG_INFO, "kernel module version: %d", kernel_modver); continue; } -- GitLab From cdc0c0c94e4e6dfa371d497a3130f83349b6ead6 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Mon, 14 Dec 2015 16:01:36 -0800 Subject: [PATCH 1272/2855] Drivers: hv: util: catch allocation errors Catch allocation errors in hvutil_transport_send. Fixes: 14b50f80c32d ('Drivers: hv: util: introduce hv_utils_transport abstraction') Signed-off-by: Olaf Hering Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_utils_transport.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/hv/hv_utils_transport.c b/drivers/hv/hv_utils_transport.c index 6a9d80a5332d3..1505ee6e6605e 100644 --- a/drivers/hv/hv_utils_transport.c +++ b/drivers/hv/hv_utils_transport.c @@ -204,9 +204,12 @@ int hvutil_transport_send(struct hvutil_transport *hvt, void *msg, int len) goto out_unlock; } hvt->outmsg = kzalloc(len, GFP_KERNEL); - memcpy(hvt->outmsg, msg, len); - hvt->outmsg_len = len; - wake_up_interruptible(&hvt->outmsg_q); + if (hvt->outmsg) { + memcpy(hvt->outmsg, msg, len); + hvt->outmsg_len = len; + wake_up_interruptible(&hvt->outmsg_q); + } else + ret = -ENOMEM; out_unlock: mutex_unlock(&hvt->outmsg_lock); return ret; -- GitLab From b00359642c2427da89dc8f77daa2c9e8a84e6d76 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Mon, 14 Dec 2015 16:01:37 -0800 Subject: [PATCH 1273/2855] Drivers: hv: utils: use memdup_user in hvt_op_write Use memdup_user to handle OOM. Fixes: 14b50f80c32d ('Drivers: hv: util: introduce hv_utils_transport abstraction') Signed-off-by: Olaf Hering Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_utils_transport.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/hv/hv_utils_transport.c b/drivers/hv/hv_utils_transport.c index 1505ee6e6605e..24b2766a6d345 100644 --- a/drivers/hv/hv_utils_transport.c +++ b/drivers/hv/hv_utils_transport.c @@ -80,11 +80,10 @@ static ssize_t hvt_op_write(struct file *file, const char __user *buf, hvt = container_of(file->f_op, struct hvutil_transport, fops); - inmsg = kzalloc(count, GFP_KERNEL); - if (copy_from_user(inmsg, buf, count)) { - kfree(inmsg); - return -EFAULT; - } + inmsg = memdup_user(buf, count); + if (IS_ERR(inmsg)) + return PTR_ERR(inmsg); + if (hvt->on_msg(inmsg, count)) return -EFAULT; kfree(inmsg); -- GitLab From 17efbee8ba02ef00d3b270998978f8a1a90f1d92 Mon Sep 17 00:00:00 2001 From: Andrey Smetanin Date: Mon, 14 Dec 2015 16:01:38 -0800 Subject: [PATCH 1274/2855] drivers/hv: cleanup synic msrs if vmbus connect failed Before vmbus_connect() synic is setup per vcpu - this means hypervisor receives writes at synic msr's and probably allocate hypervisor resources per synic setup. If vmbus_connect() failed for some reason it's neccessary to cleanup synic setup by call hv_synic_cleanup() at each vcpu to get a chance to free allocated resources by hypervisor per synic. This patch does appropriate cleanup in case of vmbus_connect() failure. Signed-off-by: Andrey Smetanin Signed-off-by: Denis V. Lunev Reviewed-by: Vitaly Kuznetsov CC: "K. Y. Srinivasan" CC: Haiyang Zhang CC: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/vmbus_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index f19b6f7a467a6..3297731017e42 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -867,7 +867,7 @@ static int vmbus_bus_init(int irq) on_each_cpu(hv_synic_init, NULL, 1); ret = vmbus_connect(); if (ret) - goto err_alloc; + goto err_connect; if (vmbus_proto_version > VERSION_WIN7) cpu_hotplug_disable(); @@ -885,6 +885,8 @@ static int vmbus_bus_init(int irq) return 0; +err_connect: + on_each_cpu(hv_synic_cleanup, NULL, 1); err_alloc: hv_synic_free(); hv_remove_vmbus_irq(); -- GitLab From 619848bd074343ff2bdeeafca0be39748f6da372 Mon Sep 17 00:00:00 2001 From: Jake Oshins Date: Mon, 14 Dec 2015 16:01:39 -0800 Subject: [PATCH 1275/2855] drivers:hv: Export a function that maps Linux CPU num onto Hyper-V proc num This patch exposes the mapping between Linux CPU number and Hyper-V virtual processor number. This is necessary because the hypervisor needs to know which virtual processors to target when making a mapping in the Interrupt Redirection Table in the I/O MMU. Signed-off-by: Jake Oshins Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/vmbus_drv.c | 17 +++++++++++++++++ include/linux/hyperv.h | 2 ++ 2 files changed, 19 insertions(+) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 3297731017e42..c01b689e39b17 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -1193,6 +1193,23 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, } EXPORT_SYMBOL_GPL(vmbus_allocate_mmio); +/** + * vmbus_cpu_number_to_vp_number() - Map CPU to VP. + * @cpu_number: CPU number in Linux terms + * + * This function returns the mapping between the Linux processor + * number and the hypervisor's virtual processor number, useful + * in making hypercalls and such that talk about specific + * processors. + * + * Return: Virtual processor number in Hyper-V terms + */ +int vmbus_cpu_number_to_vp_number(int cpu_number) +{ + return hv_context.vp_index[cpu_number]; +} +EXPORT_SYMBOL_GPL(vmbus_cpu_number_to_vp_number); + static int vmbus_acpi_add(struct acpi_device *device) { acpi_status result; diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 8fdc17b84739b..fddb3e0e8febd 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -983,6 +983,8 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, resource_size_t size, resource_size_t align, bool fb_overlap_ok); +int vmbus_cpu_number_to_vp_number(int cpu_number); + /** * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device * -- GitLab From a108393dbf764efb2405f21ca759806c65b8bc16 Mon Sep 17 00:00:00 2001 From: Jake Oshins Date: Mon, 14 Dec 2015 16:01:40 -0800 Subject: [PATCH 1276/2855] drivers:hv: Export the API to invoke a hypercall on Hyper-V This patch exposes the function that hv_vmbus.ko uses to make hypercalls. This is necessary for retargeting an interrupt when it is given a new affinity. Since we are exporting this API, rename the API as it will be visible outside the hv.c file. Signed-off-by: Jake Oshins Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv.c | 20 ++++++++++---------- drivers/hv/hyperv_vmbus.h | 2 +- include/linux/hyperv.h | 1 + 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index ad7fc6d92c359..eb4e383dbc58d 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -89,9 +89,9 @@ static int query_hypervisor_info(void) } /* - * do_hypercall- Invoke the specified hypercall + * hv_do_hypercall- Invoke the specified hypercall */ -static u64 do_hypercall(u64 control, void *input, void *output) +u64 hv_do_hypercall(u64 control, void *input, void *output) { u64 input_address = (input) ? virt_to_phys(input) : 0; u64 output_address = (output) ? virt_to_phys(output) : 0; @@ -132,6 +132,7 @@ static u64 do_hypercall(u64 control, void *input, void *output) return hv_status_lo | ((u64)hv_status_hi << 32); #endif /* !x86_64 */ } +EXPORT_SYMBOL_GPL(hv_do_hypercall); #ifdef CONFIG_X86_64 static cycle_t read_hv_clock_tsc(struct clocksource *arg) @@ -316,7 +317,7 @@ int hv_post_message(union hv_connection_id connection_id, { struct hv_input_post_message *aligned_msg; - u16 status; + u64 status; if (payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT) return -EMSGSIZE; @@ -330,11 +331,10 @@ int hv_post_message(union hv_connection_id connection_id, aligned_msg->payload_size = payload_size; memcpy((void *)aligned_msg->payload, payload, payload_size); - status = do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL) - & 0xFFFF; + status = hv_do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL); put_cpu(); - return status; + return status & 0xFFFF; } @@ -344,13 +344,13 @@ int hv_post_message(union hv_connection_id connection_id, * * This involves a hypercall. */ -u16 hv_signal_event(void *con_id) +int hv_signal_event(void *con_id) { - u16 status; + u64 status; - status = (do_hypercall(HVCALL_SIGNAL_EVENT, con_id, NULL) & 0xFFFF); + status = hv_do_hypercall(HVCALL_SIGNAL_EVENT, con_id, NULL); - return status; + return status & 0xFFFF; } static int hv_ce_set_next_event(unsigned long delta, diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 12156db2e88e2..9beeb148797fa 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -587,7 +587,7 @@ extern int hv_post_message(union hv_connection_id connection_id, enum hv_message_type message_type, void *payload, size_t payload_size); -extern u16 hv_signal_event(void *con_id); +extern int hv_signal_event(void *con_id); extern int hv_synic_alloc(void); diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index fddb3e0e8febd..24d0b656e6e7b 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -984,6 +984,7 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, bool fb_overlap_ok); int vmbus_cpu_number_to_vp_number(int cpu_number); +u64 hv_do_hypercall(u64 control, void *input, void *output); /** * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device -- GitLab From 3053c762444a83ec6a8777f9476668b23b8ab180 Mon Sep 17 00:00:00 2001 From: Jake Oshins Date: Mon, 14 Dec 2015 16:01:41 -0800 Subject: [PATCH 1277/2855] drivers:hv: Define the channel type for Hyper-V PCI Express pass-through This defines the channel type for PCI front-ends in Hyper-V VMs. Signed-off-by: Jake Oshins Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel_mgmt.c | 3 +++ include/linux/hyperv.h | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 652afd11a9efd..a77646b4fcc8b 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -358,6 +358,7 @@ enum { SCSI, NIC, ND_NIC, + PCIE, MAX_PERF_CHN, }; @@ -375,6 +376,8 @@ static const struct hv_vmbus_device_id hp_devs[] = { { HV_NIC_GUID, }, /* NetworkDirect Guest RDMA */ { HV_ND_GUID, }, + /* PCI Express Pass Through */ + { HV_PCIE_GUID, }, }; diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 24d0b656e6e7b..c9a9eed89af29 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1140,6 +1140,17 @@ u64 hv_do_hypercall(u64 control, void *input, void *output); 0xab, 0x99, 0xbd, 0x1f, 0x1c, 0x86, 0xb5, 0x01 \ } +/* + * PCI Express Pass Through + * {44C4F61D-4444-4400-9D52-802E27EDE19F} + */ + +#define HV_PCIE_GUID \ + .guid = { \ + 0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \ + 0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \ + } + /* * Common header for Hyper-V ICs */ -- GitLab From ed9ba608e4851144af8c7061cbb19f751c73e998 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Mon, 14 Dec 2015 16:01:42 -0800 Subject: [PATCH 1278/2855] Drivers: hv: vss: run only on supported host versions The Backup integration service on WS2012 has appearently trouble to negotiate with a guest which does not support the provided util version. Currently the VSS driver supports only version 5/0. A WS2012 offers only version 1/x and 3/x, and vmbus_prep_negotiate_resp correctly returns an empty icframe_vercnt/icmsg_vercnt. But the host ignores that and continues to send ICMSGTYPE_NEGOTIATE messages. The result are weird errors during boot and general misbehaviour. Check the Windows version to work around the host bug, skip hv_vss_init on WS2012 and older. Signed-off-by: Olaf Hering Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_snapshot.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c index a548ae42c927a..81882d4848bdf 100644 --- a/drivers/hv/hv_snapshot.c +++ b/drivers/hv/hv_snapshot.c @@ -331,6 +331,11 @@ static void vss_on_reset(void) int hv_vss_init(struct hv_util_service *srv) { + if (vmbus_proto_version < VERSION_WIN8_1) { + pr_warn("Integration service 'Backup (volume snapshot)'" + " not supported on this host version.\n"); + return -ENOTSUPP; + } recv_buffer = srv->recv_buffer; /* -- GitLab From af3ff643ea91ba64dd8d0b1cbed54d44512f96cd Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 14 Dec 2015 16:01:43 -0800 Subject: [PATCH 1279/2855] Drivers: hv: vmbus: Use uuid_le type consistently Consistently use uuid_le type in the Hyper-V driver code. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel_mgmt.c | 2 +- drivers/hv/vmbus_drv.c | 10 ++-- include/linux/hyperv.h | 92 ++++++++++++--------------------- include/linux/mod_devicetable.h | 2 +- scripts/mod/file2alias.c | 2 +- 5 files changed, 40 insertions(+), 68 deletions(-) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index a77646b4fcc8b..38470aa4387f0 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -408,7 +408,7 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui struct cpumask *alloced_mask; for (i = IDE; i < MAX_PERF_CHN; i++) { - if (!memcmp(type_guid->b, hp_devs[i].guid, + if (!memcmp(type_guid->b, &hp_devs[i].guid, sizeof(uuid_le))) { perf_chn = true; break; diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index c01b689e39b17..7078b5f143a24 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -531,7 +531,7 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) static const uuid_le null_guid; -static inline bool is_null_guid(const __u8 *guid) +static inline bool is_null_guid(const uuid_le *guid) { if (memcmp(guid, &null_guid, sizeof(uuid_le))) return false; @@ -544,9 +544,9 @@ static inline bool is_null_guid(const __u8 *guid) */ static const struct hv_vmbus_device_id *hv_vmbus_get_id( const struct hv_vmbus_device_id *id, - const __u8 *guid) + const uuid_le *guid) { - for (; !is_null_guid(id->guid); id++) + for (; !is_null_guid(&id->guid); id++) if (!memcmp(&id->guid, guid, sizeof(uuid_le))) return id; @@ -563,7 +563,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver) struct hv_driver *drv = drv_to_hv_drv(driver); struct hv_device *hv_dev = device_to_hv_device(device); - if (hv_vmbus_get_id(drv->id_table, hv_dev->dev_type.b)) + if (hv_vmbus_get_id(drv->id_table, &hv_dev->dev_type)) return 1; return 0; @@ -580,7 +580,7 @@ static int vmbus_probe(struct device *child_device) struct hv_device *dev = device_to_hv_device(child_device); const struct hv_vmbus_device_id *dev_id; - dev_id = hv_vmbus_get_id(drv->id_table, dev->dev_type.b); + dev_id = hv_vmbus_get_id(drv->id_table, &dev->dev_type); if (drv->probe) { ret = drv->probe(dev, dev_id); if (ret != 0) diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index c9a9eed89af29..b9f3bb25d8b48 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -997,6 +997,8 @@ u64 hv_do_hypercall(u64 control, void *input, void *output); .guid = { g0, g1, g2, g3, g4, g5, g6, g7, \ g8, g9, ga, gb, gc, gd, ge, gf }, + + /* * GUID definitions of various offer types - services offered to the guest. */ @@ -1006,118 +1008,94 @@ u64 hv_do_hypercall(u64 control, void *input, void *output); * {f8615163-df3e-46c5-913f-f2d2f965ed0e} */ #define HV_NIC_GUID \ - .guid = { \ - 0x63, 0x51, 0x61, 0xf8, 0x3e, 0xdf, 0xc5, 0x46, \ - 0x91, 0x3f, 0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e \ - } + .guid = UUID_LE(0xf8615163, 0xdf3e, 0x46c5, 0x91, 0x3f, \ + 0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e) /* * IDE GUID * {32412632-86cb-44a2-9b5c-50d1417354f5} */ #define HV_IDE_GUID \ - .guid = { \ - 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, \ - 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 \ - } + .guid = UUID_LE(0x32412632, 0x86cb, 0x44a2, 0x9b, 0x5c, \ + 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5) /* * SCSI GUID * {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ #define HV_SCSI_GUID \ - .guid = { \ - 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, \ - 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f \ - } + .guid = UUID_LE(0xba6163d9, 0x04a1, 0x4d29, 0xb6, 0x05, \ + 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f) /* * Shutdown GUID * {0e0b6031-5213-4934-818b-38d90ced39db} */ #define HV_SHUTDOWN_GUID \ - .guid = { \ - 0x31, 0x60, 0x0b, 0x0e, 0x13, 0x52, 0x34, 0x49, \ - 0x81, 0x8b, 0x38, 0xd9, 0x0c, 0xed, 0x39, 0xdb \ - } + .guid = UUID_LE(0x0e0b6031, 0x5213, 0x4934, 0x81, 0x8b, \ + 0x38, 0xd9, 0x0c, 0xed, 0x39, 0xdb) /* * Time Synch GUID * {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */ #define HV_TS_GUID \ - .guid = { \ - 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, \ - 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf \ - } + .guid = UUID_LE(0x9527e630, 0xd0ae, 0x497b, 0xad, 0xce, \ + 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf) /* * Heartbeat GUID * {57164f39-9115-4e78-ab55-382f3bd5422d} */ #define HV_HEART_BEAT_GUID \ - .guid = { \ - 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, \ - 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d \ - } + .guid = UUID_LE(0x57164f39, 0x9115, 0x4e78, 0xab, 0x55, \ + 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d) /* * KVP GUID * {a9a0f4e7-5a45-4d96-b827-8a841e8c03e6} */ #define HV_KVP_GUID \ - .guid = { \ - 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, \ - 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 \ - } + .guid = UUID_LE(0xa9a0f4e7, 0x5a45, 0x4d96, 0xb8, 0x27, \ + 0x8a, 0x84, 0x1e, 0x8c, 0x03, 0xe6) /* * Dynamic memory GUID * {525074dc-8985-46e2-8057-a307dc18a502} */ #define HV_DM_GUID \ - .guid = { \ - 0xdc, 0x74, 0x50, 0X52, 0x85, 0x89, 0xe2, 0x46, \ - 0x80, 0x57, 0xa3, 0x07, 0xdc, 0x18, 0xa5, 0x02 \ - } + .guid = UUID_LE(0x525074dc, 0x8985, 0x46e2, 0x80, 0x57, \ + 0xa3, 0x07, 0xdc, 0x18, 0xa5, 0x02) /* * Mouse GUID * {cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a} */ #define HV_MOUSE_GUID \ - .guid = { \ - 0x9e, 0xb6, 0xa8, 0xcf, 0x4a, 0x5b, 0xc0, 0x4c, \ - 0xb9, 0x8b, 0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a \ - } + .guid = UUID_LE(0xcfa8b69e, 0x5b4a, 0x4cc0, 0xb9, 0x8b, \ + 0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a) /* * VSS (Backup/Restore) GUID */ #define HV_VSS_GUID \ - .guid = { \ - 0x29, 0x2e, 0xfa, 0x35, 0x23, 0xea, 0x36, 0x42, \ - 0x96, 0xae, 0x3a, 0x6e, 0xba, 0xcb, 0xa4, 0x40 \ - } + .guid = UUID_LE(0x35fa2e29, 0xea23, 0x4236, 0x96, 0xae, \ + 0x3a, 0x6e, 0xba, 0xcb, 0xa4, 0x40) /* * Synthetic Video GUID * {DA0A7802-E377-4aac-8E77-0558EB1073F8} */ #define HV_SYNTHVID_GUID \ - .guid = { \ - 0x02, 0x78, 0x0a, 0xda, 0x77, 0xe3, 0xac, 0x4a, \ - 0x8e, 0x77, 0x05, 0x58, 0xeb, 0x10, 0x73, 0xf8 \ - } + .guid = UUID_LE(0xda0a7802, 0xe377, 0x4aac, 0x8e, 0x77, \ + 0x05, 0x58, 0xeb, 0x10, 0x73, 0xf8) /* * Synthetic FC GUID * {2f9bcc4a-0069-4af3-b76b-6fd0be528cda} */ #define HV_SYNTHFC_GUID \ - .guid = { \ - 0x4A, 0xCC, 0x9B, 0x2F, 0x69, 0x00, 0xF3, 0x4A, \ - 0xB7, 0x6B, 0x6F, 0xD0, 0xBE, 0x52, 0x8C, 0xDA \ - } + .guid = UUID_LE(0x2f9bcc4a, 0x0069, 0x4af3, 0xb7, 0x6b, \ + 0x6f, 0xd0, 0xbe, 0x52, 0x8c, 0xda) /* * Guest File Copy Service @@ -1125,20 +1103,16 @@ u64 hv_do_hypercall(u64 control, void *input, void *output); */ #define HV_FCOPY_GUID \ - .guid = { \ - 0xE3, 0x4B, 0xD1, 0x34, 0xE4, 0xDE, 0xC8, 0x41, \ - 0x9A, 0xE7, 0x6B, 0x17, 0x49, 0x77, 0xC1, 0x92 \ - } + .guid = UUID_LE(0x34d14be3, 0xdee4, 0x41c8, 0x9a, 0xe7, \ + 0x6b, 0x17, 0x49, 0x77, 0xc1, 0x92) /* * NetworkDirect. This is the guest RDMA service. * {8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501} */ #define HV_ND_GUID \ - .guid = { \ - 0x3d, 0xaf, 0x2e, 0x8c, 0xa7, 0x32, 0x09, 0x4b, \ - 0xab, 0x99, 0xbd, 0x1f, 0x1c, 0x86, 0xb5, 0x01 \ - } + .guid = UUID_LE(0x8c2eaf3d, 0x32a7, 0x4b09, 0xab, 0x99, \ + 0xbd, 0x1f, 0x1c, 0x86, 0xb5, 0x01) /* * PCI Express Pass Through @@ -1146,10 +1120,8 @@ u64 hv_do_hypercall(u64 control, void *input, void *output); */ #define HV_PCIE_GUID \ - .guid = { \ - 0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \ - 0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \ - } + .guid = UUID_LE(0x44c4f61d, 0x4444, 0x4400, 0x9d, 0x52, \ + 0x80, 0x2e, 0x27, 0xed, 0xe1, 0x9f) /* * Common header for Hyper-V ICs diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 64f36e09a7901..6e4c645e1c0d4 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -404,7 +404,7 @@ struct virtio_device_id { * For Hyper-V devices we use the device guid as the id. */ struct hv_vmbus_device_id { - __u8 guid[16]; + uuid_le guid; kernel_ulong_t driver_data; /* Data private to the driver */ }; diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 5b96206e9aab8..8adca44061980 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -917,7 +917,7 @@ static int do_vmbus_entry(const char *filename, void *symval, char guid_name[(sizeof(*guid) + 1) * 2]; for (i = 0; i < (sizeof(*guid) * 2); i += 2) - sprintf(&guid_name[i], "%02x", TO_NATIVE((*guid)[i/2])); + sprintf(&guid_name[i], "%02x", TO_NATIVE((guid->b)[i/2])); strcpy(alias, "vmbus:"); strcat(alias, guid_name); -- GitLab From 4ae9250893485f380275e7d5cb291df87c4d9710 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 14 Dec 2015 16:01:44 -0800 Subject: [PATCH 1280/2855] Drivers: hv: vmbus: Use uuid_le_cmp() for comparing GUIDs Use uuid_le_cmp() for comparing GUIDs. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel_mgmt.c | 3 +-- drivers/hv/vmbus_drv.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 38470aa4387f0..dc4fb0bccb8d8 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -408,8 +408,7 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui struct cpumask *alloced_mask; for (i = IDE; i < MAX_PERF_CHN; i++) { - if (!memcmp(type_guid->b, &hp_devs[i].guid, - sizeof(uuid_le))) { + if (!uuid_le_cmp(*type_guid, hp_devs[i].guid)) { perf_chn = true; break; } diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 7078b5f143a24..9e0e25c394f5d 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -533,7 +533,7 @@ static const uuid_le null_guid; static inline bool is_null_guid(const uuid_le *guid) { - if (memcmp(guid, &null_guid, sizeof(uuid_le))) + if (uuid_le_cmp(*guid, null_guid)) return false; return true; } @@ -547,7 +547,7 @@ static const struct hv_vmbus_device_id *hv_vmbus_get_id( const uuid_le *guid) { for (; !is_null_guid(&id->guid); id++) - if (!memcmp(&id->guid, guid, sizeof(uuid_le))) + if (!uuid_le_cmp(id->guid, *guid)) return id; return NULL; -- GitLab From 90e031fa06ad6b660a8e9bebbb80bd30e555a2a5 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 14 Dec 2015 16:01:45 -0800 Subject: [PATCH 1281/2855] Drivers: hv: vmbus: Get rid of the unused macro The macro VMBUS_DEVICE() is unused; get rid of it. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- include/linux/hyperv.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index b9f3bb25d8b48..f773a6871f4c6 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -986,19 +986,6 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, int vmbus_cpu_number_to_vp_number(int cpu_number); u64 hv_do_hypercall(u64 control, void *input, void *output); -/** - * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device - * - * This macro is used to create a struct hv_vmbus_device_id that matches a - * specific device. - */ -#define VMBUS_DEVICE(g0, g1, g2, g3, g4, g5, g6, g7, \ - g8, g9, ga, gb, gc, gd, ge, gf) \ - .guid = { g0, g1, g2, g3, g4, g5, g6, g7, \ - g8, g9, ga, gb, gc, gd, ge, gf }, - - - /* * GUID definitions of various offer types - services offered to the guest. */ -- GitLab From efc267226b827f347a329c395e16c08973b0e3d6 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 14 Dec 2015 16:01:46 -0800 Subject: [PATCH 1282/2855] Drivers: hv: vmbus: Get rid of the unused irq variable The irq we extract from ACPI is not used - we deliver hypervisor interrupts on a special vector. Make the necessary adjustments. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/vmbus_drv.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 9e0e25c394f5d..ab888a1abef8f 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -47,7 +47,6 @@ static struct acpi_device *hv_acpi_dev; static struct tasklet_struct msg_dpc; static struct completion probe_event; -static int irq; static void hyperv_report_panic(struct pt_regs *regs) @@ -835,10 +834,9 @@ static void vmbus_isr(void) * Here, we * - initialize the vmbus driver context * - invoke the vmbus hv main init routine - * - get the irq resource * - retrieve the channel offers */ -static int vmbus_bus_init(int irq) +static int vmbus_bus_init(void) { int ret; @@ -1033,9 +1031,6 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx) struct resource **prev_res = NULL; switch (res->type) { - case ACPI_RESOURCE_TYPE_IRQ: - irq = res->data.irq.interrupts[0]; - return AE_OK; /* * "Address" descriptors are for bus windows. Ignore @@ -1294,7 +1289,7 @@ static int __init hv_acpi_init(void) init_completion(&probe_event); /* - * Get irq resources first. + * Get ACPI resources first. */ ret = acpi_bus_register_driver(&vmbus_acpi_driver); @@ -1307,12 +1302,7 @@ static int __init hv_acpi_init(void) goto cleanup; } - if (irq <= 0) { - ret = -ENODEV; - goto cleanup; - } - - ret = vmbus_bus_init(irq); + ret = vmbus_bus_init(); if (ret) goto cleanup; -- GitLab From 63d55b2aeb5e4faa170316fee73c3c47ea9268c7 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 14 Dec 2015 16:01:47 -0800 Subject: [PATCH 1283/2855] Drivers: hv: vmbus: serialize process_chn_event() and vmbus_close_internal() process_chn_event(), running in the tasklet, can race with vmbus_close_internal() in the case of SMP guest, e.g., when the former is accessing channel->inbound.ring_buffer, the latter could be freeing the ring_buffer pages. To resolve the race, we can serialize them by disabling the tasklet when the latter is running here. Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index c4dcab048cb8e..f7f3d5ccd6bd0 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "hyperv_vmbus.h" @@ -496,8 +497,21 @@ static void reset_channel_cb(void *arg) static int vmbus_close_internal(struct vmbus_channel *channel) { struct vmbus_channel_close_channel *msg; + struct tasklet_struct *tasklet; int ret; + /* + * process_chn_event(), running in the tasklet, can race + * with vmbus_close_internal() in the case of SMP guest, e.g., when + * the former is accessing channel->inbound.ring_buffer, the latter + * could be freeing the ring_buffer pages. + * + * To resolve the race, we can serialize them by disabling the + * tasklet when the latter is running here. + */ + tasklet = hv_context.event_dpc[channel->target_cpu]; + tasklet_disable(tasklet); + channel->state = CHANNEL_OPEN_STATE; channel->sc_creation_callback = NULL; /* Stop callback and cancel the timer asap */ @@ -525,7 +539,7 @@ static int vmbus_close_internal(struct vmbus_channel *channel) * If we failed to post the close msg, * it is perhaps better to leak memory. */ - return ret; + goto out; } /* Tear down the gpadl for the channel's ring buffer */ @@ -538,7 +552,7 @@ static int vmbus_close_internal(struct vmbus_channel *channel) * If we failed to teardown gpadl, * it is perhaps better to leak memory. */ - return ret; + goto out; } } @@ -555,6 +569,9 @@ static int vmbus_close_internal(struct vmbus_channel *channel) if (channel->rescind) hv_process_channel_removal(channel, channel->offermsg.child_relid); +out: + tasklet_enable(tasklet); + return ret; } -- GitLab From 64b7faf903dae2df94d89edf2c688b16751800e4 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 14 Dec 2015 16:01:48 -0800 Subject: [PATCH 1284/2855] Drivers: hv: vmbus: do sanity check of channel state in vmbus_close_internal() This fixes an incorrect assumption of channel state in the function. Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index f7f3d5ccd6bd0..00e1be7759080 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -512,6 +512,18 @@ static int vmbus_close_internal(struct vmbus_channel *channel) tasklet = hv_context.event_dpc[channel->target_cpu]; tasklet_disable(tasklet); + /* + * In case a device driver's probe() fails (e.g., + * util_probe() -> vmbus_open() returns -ENOMEM) and the device is + * rescinded later (e.g., we dynamically disble an Integrated Service + * in Hyper-V Manager), the driver's remove() invokes vmbus_close(): + * here we should skip most of the below cleanup work. + */ + if (channel->state != CHANNEL_OPENED_STATE) { + ret = -EINVAL; + goto out; + } + channel->state = CHANNEL_OPEN_STATE; channel->sc_creation_callback = NULL; /* Stop callback and cancel the timer asap */ -- GitLab From 34c6801e3310ad286c7bb42bc88d42926b8f99bf Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 14 Dec 2015 16:01:49 -0800 Subject: [PATCH 1285/2855] Drivers: hv: vmbus: fix rescind-offer handling for device without a driver In the path vmbus_onoffer_rescind() -> vmbus_device_unregister() -> device_unregister() -> ... -> __device_release_driver(), we can see for a device without a driver loaded: dev->driver is NULL, so dev->bus->remove(dev), namely vmbus_remove(), isn't invoked. As a result, vmbus_remove() -> hv_process_channel_removal() isn't invoked and some cleanups(like sending a CHANNELMSG_RELID_RELEASED message to the host) aren't done. We can demo the issue this way: 1. rmmod hv_utils; 2. disable the Heartbeat Integration Service in Hyper-V Manager and lsvmbus shows the device disappears. 3. re-enable the Heartbeat in Hyper-V Manager and modprobe hv_utils, but lsvmbus shows the device can't appear again. This is because, the host thinks the VM hasn't released the relid, so can't re-offer the device to the VM. We can fix the issue by moving hv_process_channel_removal() from vmbus_close_internal() to vmbus_device_release(), since the latter is always invoked on device_unregister(), whether or not the dev has a driver loaded. Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel.c | 6 ------ drivers/hv/channel_mgmt.c | 6 +++--- drivers/hv/vmbus_drv.c | 15 +++------------ 3 files changed, 6 insertions(+), 21 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 00e1be7759080..77d2579d61241 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -575,12 +575,6 @@ static int vmbus_close_internal(struct vmbus_channel *channel) free_pages((unsigned long)channel->ringbuffer_pages, get_order(channel->ringbuffer_pagecount * PAGE_SIZE)); - /* - * If the channel has been rescinded; process device removal. - */ - if (channel->rescind) - hv_process_channel_removal(channel, - channel->offermsg.child_relid); out: tasklet_enable(tasklet); diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index dc4fb0bccb8d8..7903acc3403e9 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -191,6 +191,8 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) if (channel == NULL) return; + BUG_ON(!channel->rescind); + if (channel->target_cpu != get_cpu()) { put_cpu(); smp_call_function_single(channel->target_cpu, @@ -230,9 +232,7 @@ void vmbus_free_channels(void) list_for_each_entry_safe(channel, tmp, &vmbus_connection.chn_list, listentry) { - /* if we don't set rescind to true, vmbus_close_internal() - * won't invoke hv_process_channel_removal(). - */ + /* hv_process_channel_removal() needs this */ channel->rescind = true; vmbus_device_unregister(channel->device_obj); diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index ab888a1abef8f..f123bca778086 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -601,23 +601,11 @@ static int vmbus_remove(struct device *child_device) { struct hv_driver *drv; struct hv_device *dev = device_to_hv_device(child_device); - u32 relid = dev->channel->offermsg.child_relid; if (child_device->driver) { drv = drv_to_hv_drv(child_device->driver); if (drv->remove) drv->remove(dev); - else { - hv_process_channel_removal(dev->channel, relid); - pr_err("remove not set for driver %s\n", - dev_name(child_device)); - } - } else { - /* - * We don't have a driver for this device; deal with the - * rescind message by removing the channel. - */ - hv_process_channel_removal(dev->channel, relid); } return 0; @@ -652,7 +640,10 @@ static void vmbus_shutdown(struct device *child_device) static void vmbus_device_release(struct device *device) { struct hv_device *hv_dev = device_to_hv_device(device); + struct vmbus_channel *channel = hv_dev->channel; + hv_process_channel_removal(channel, + channel->offermsg.child_relid); kfree(hv_dev); } -- GitLab From f52078cf5711ce47c113a58702b35c8ff5f212f5 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 14 Dec 2015 16:01:50 -0800 Subject: [PATCH 1286/2855] Drivers: hv: vmbus: release relid on error in vmbus_process_offer() We want to simplify vmbus_onoffer_rescind() by not invoking hv_process_channel_removal(NULL, ...). Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel_mgmt.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 7903acc3403e9..9c9da3a6c03af 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -177,19 +177,22 @@ static void percpu_channel_deq(void *arg) } -void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) +static void vmbus_release_relid(u32 relid) { struct vmbus_channel_relid_released msg; - unsigned long flags; - struct vmbus_channel *primary_channel; memset(&msg, 0, sizeof(struct vmbus_channel_relid_released)); msg.child_relid = relid; msg.header.msgtype = CHANNELMSG_RELID_RELEASED; vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released)); +} - if (channel == NULL) - return; +void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) +{ + unsigned long flags; + struct vmbus_channel *primary_channel; + + vmbus_release_relid(relid); BUG_ON(!channel->rescind); @@ -336,6 +339,8 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) return; err_deq_chan: + vmbus_release_relid(newchannel->offermsg.child_relid); + spin_lock_irqsave(&vmbus_connection.channel_lock, flags); list_del(&newchannel->listentry); spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); @@ -587,7 +592,11 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) channel = relid2channel(rescind->child_relid); if (channel == NULL) { - hv_process_channel_removal(NULL, rescind->child_relid); + /* + * This is very impossible, because in + * vmbus_process_offer(), we have already invoked + * vmbus_release_relid() on error. + */ return; } -- GitLab From d6f591e339d23f434efda11917da511870891472 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 14 Dec 2015 16:01:51 -0800 Subject: [PATCH 1287/2855] Drivers: hv: vmbus: channge vmbus_connection.channel_lock to mutex spinlock is unnecessary here. mutex is enough. Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel_mgmt.c | 12 ++++++------ drivers/hv/connection.c | 7 +++---- drivers/hv/hyperv_vmbus.h | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 9c9da3a6c03af..d0131717c1d5d 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -206,9 +206,9 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) } if (channel->primary_channel == NULL) { - spin_lock_irqsave(&vmbus_connection.channel_lock, flags); + mutex_lock(&vmbus_connection.channel_mutex); list_del(&channel->listentry); - spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); + mutex_unlock(&vmbus_connection.channel_mutex); primary_channel = channel; } else { @@ -253,7 +253,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) unsigned long flags; /* Make sure this is a new offer */ - spin_lock_irqsave(&vmbus_connection.channel_lock, flags); + mutex_lock(&vmbus_connection.channel_mutex); list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) { if (!uuid_le_cmp(channel->offermsg.offer.if_type, @@ -269,7 +269,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) list_add_tail(&newchannel->listentry, &vmbus_connection.chn_list); - spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); + mutex_unlock(&vmbus_connection.channel_mutex); if (!fnew) { /* @@ -341,9 +341,9 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) err_deq_chan: vmbus_release_relid(newchannel->offermsg.child_relid); - spin_lock_irqsave(&vmbus_connection.channel_lock, flags); + mutex_lock(&vmbus_connection.channel_mutex); list_del(&newchannel->listentry); - spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); + mutex_unlock(&vmbus_connection.channel_mutex); if (newchannel->target_cpu != get_cpu()) { put_cpu(); diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index 4fc2e8836e60d..521f48ed188e4 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c @@ -146,7 +146,7 @@ int vmbus_connect(void) spin_lock_init(&vmbus_connection.channelmsg_lock); INIT_LIST_HEAD(&vmbus_connection.chn_list); - spin_lock_init(&vmbus_connection.channel_lock); + mutex_init(&vmbus_connection.channel_mutex); /* * Setup the vmbus event connection for channel interrupt @@ -282,11 +282,10 @@ struct vmbus_channel *relid2channel(u32 relid) { struct vmbus_channel *channel; struct vmbus_channel *found_channel = NULL; - unsigned long flags; struct list_head *cur, *tmp; struct vmbus_channel *cur_sc; - spin_lock_irqsave(&vmbus_connection.channel_lock, flags); + mutex_lock(&vmbus_connection.channel_mutex); list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) { if (channel->offermsg.child_relid == relid) { found_channel = channel; @@ -305,7 +304,7 @@ struct vmbus_channel *relid2channel(u32 relid) } } } - spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); + mutex_unlock(&vmbus_connection.channel_mutex); return found_channel; } diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 9beeb148797fa..4d67e984ac4fa 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -683,7 +683,7 @@ struct vmbus_connection { /* List of channels */ struct list_head chn_list; - spinlock_t channel_lock; + struct mutex channel_mutex; struct workqueue_struct *work_queue; }; -- GitLab From 40f26f3168bf7a4da490db308dc0bd9f9923f41f Mon Sep 17 00:00:00 2001 From: Jake Oshins Date: Mon, 14 Dec 2015 16:01:52 -0800 Subject: [PATCH 1288/2855] drivers:hv: Allow for MMIO claims that span ACPI _CRS records This patch makes 16GB GPUs work in Hyper-V VMs, since, for compatibility reasons, the Hyper-V BIOS lists MMIO ranges in 2GB chunks in its root bus's _CRS object. Signed-off-by: Jake Oshins Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/vmbus_drv.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index f123bca778086..328e4c3808e06 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -1063,12 +1063,28 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx) new_res->start = start; new_res->end = end; + /* + * Stick ranges from higher in address space at the front of the list. + * If two ranges are adjacent, merge them. + */ do { if (!*old_res) { *old_res = new_res; break; } + if (((*old_res)->end + 1) == new_res->start) { + (*old_res)->end = new_res->end; + kfree(new_res); + break; + } + + if ((*old_res)->start == new_res->end + 1) { + (*old_res)->start = new_res->start; + kfree(new_res); + break; + } + if ((*old_res)->end < new_res->start) { new_res->sibling = *old_res; if (prev_res) -- GitLab From 8599846d73997cdbccf63f23394d871cfad1e5e6 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 14 Dec 2015 16:01:54 -0800 Subject: [PATCH 1289/2855] Drivers: hv: vmbus: Fix a Host signaling bug Currently we have two policies for deciding when to signal the host: One based on the ring buffer state and the other based on what the VMBUS client driver wants to do. Consider the case when the client wants to explicitly control when to signal the host. In this case, if the client were to defer signaling, we will not be able to signal the host subsequently when the client does want to signal since the ring buffer state will prevent the signaling. Implement logic to have only one signaling policy in force for a given channel. Signed-off-by: K. Y. Srinivasan Reviewed-by: Haiyang Zhang Tested-by: Haiyang Zhang Cc: # v4.2+ Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel.c | 18 ++++++++++++++++++ include/linux/hyperv.h | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 77d2579d61241..2889d97c03b1d 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -653,10 +653,19 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer, * on the ring. We will not signal if more data is * to be placed. * + * Based on the channel signal state, we will decide + * which signaling policy will be applied. + * * If we cannot write to the ring-buffer; signal the host * even if we may not have written anything. This is a rare * enough condition that it should not matter. */ + + if (channel->signal_policy) + signal = true; + else + kick_q = true; + if (((ret == 0) && kick_q && signal) || (ret)) vmbus_setevent(channel); @@ -756,10 +765,19 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel, * on the ring. We will not signal if more data is * to be placed. * + * Based on the channel signal state, we will decide + * which signaling policy will be applied. + * * If we cannot write to the ring-buffer; signal the host * even if we may not have written anything. This is a rare * enough condition that it should not matter. */ + + if (channel->signal_policy) + signal = true; + else + kick_q = true; + if (((ret == 0) && kick_q && signal) || (ret)) vmbus_setevent(channel); diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index f773a6871f4c6..acd995b81c6bb 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -630,6 +630,11 @@ struct hv_input_signal_event_buffer { struct hv_input_signal_event event; }; +enum hv_signal_policy { + HV_SIGNAL_POLICY_DEFAULT = 0, + HV_SIGNAL_POLICY_EXPLICIT, +}; + struct vmbus_channel { /* Unique channel id */ int id; @@ -757,8 +762,21 @@ struct vmbus_channel { * link up channels based on their CPU affinity. */ struct list_head percpu_list; + /* + * Host signaling policy: The default policy will be + * based on the ring buffer state. We will also support + * a policy where the client driver can have explicit + * signaling control. + */ + enum hv_signal_policy signal_policy; }; +static inline void set_channel_signal_state(struct vmbus_channel *c, + enum hv_signal_policy policy) +{ + c->signal_policy = policy; +} + static inline void set_channel_read_state(struct vmbus_channel *c, bool state) { c->batched_reading = state; -- GitLab From c35b82ef0294ae5052120615f5cfcef17c5a6bf7 Mon Sep 17 00:00:00 2001 From: Andrey Smetanin Date: Mon, 14 Dec 2015 16:01:55 -0800 Subject: [PATCH 1290/2855] drivers/hv: correct tsc page sequence invalid value Hypervisor Top Level Functional Specification v3/4 says that TSC page sequence value = -1(0xFFFFFFFF) is used to indicate that TSC page no longer reliable source of reference timer. Unfortunately, we found that Windows Hyper-V guest side implementation uses sequence value = 0 to indicate that Tsc page no longer valid. This is clearly visible inside Windows 2012R2 ntoskrnl.exe HvlGetReferenceTime() function dissassembly: HvlGetReferenceTime proc near xchg ax, ax loc_1401C3132: mov rax, cs:HvlpReferenceTscPage mov r9d, [rax] test r9d, r9d jz short loc_1401C3176 rdtsc mov rcx, cs:HvlpReferenceTscPage shl rdx, 20h or rdx, rax mov rax, [rcx+8] mov rcx, cs:HvlpReferenceTscPage mov r8, [rcx+10h] mul rdx mov rax, cs:HvlpReferenceTscPage add rdx, r8 mov ecx, [rax] cmp ecx, r9d jnz short loc_1401C3132 jmp short loc_1401C3184 loc_1401C3176: mov ecx, 40000020h rdmsr shl rdx, 20h or rdx, rax loc_1401C3184: mov rax, rdx retn HvlGetReferenceTime endp This patch aligns Tsc page invalid sequence value with Windows Hyper-V guest implementation which is more compatible with both Hyper-V hypervisor and KVM hypervisor. Signed-off-by: Andrey Smetanin Signed-off-by: Denis V. Lunev CC: "K. Y. Srinivasan" CC: Haiyang Zhang CC: Vitaly Kuznetsov Signed-off-by: Denis V. Lunev Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index eb4e383dbc58d..11bca51ef5ff9 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -140,7 +140,7 @@ static cycle_t read_hv_clock_tsc(struct clocksource *arg) cycle_t current_tick; struct ms_hyperv_tsc_page *tsc_pg = hv_context.tsc_page; - if (tsc_pg->tsc_sequence != -1) { + if (tsc_pg->tsc_sequence != 0) { /* * Use the tsc page to compute the value. */ @@ -162,7 +162,7 @@ static cycle_t read_hv_clock_tsc(struct clocksource *arg) if (tsc_pg->tsc_sequence == sequence) return current_tick; - if (tsc_pg->tsc_sequence != -1) + if (tsc_pg->tsc_sequence != 0) continue; /* * Fallback using MSR method. -- GitLab From b282e4c06fe89fc750fb26791c0bd7b25315973a Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 14 Dec 2015 16:01:56 -0800 Subject: [PATCH 1291/2855] Drivers: hv: vmbus: Force all channel messages to be delivered on CPU 0 Force all channel messages to be delivered on CPU0. These messages are not performance critical and are used during the setup and teardown of the channel. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/connection.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index 521f48ed188e4..3dc5a9c7fad6e 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c @@ -83,10 +83,13 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, msg->interrupt_page = virt_to_phys(vmbus_connection.int_page); msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]); msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]); - if (version >= VERSION_WIN8_1) { - msg->target_vcpu = hv_context.vp_index[get_cpu()]; - put_cpu(); - } + /* + * We want all channel messages to be delivered on CPU 0. + * This has been the behavior pre-win8. This is not + * perf issue and having all channel messages delivered on CPU 0 + * would be ok. + */ + msg->target_vcpu = 0; /* * Add to list before we send the request since we may -- GitLab From 2d0c3b5ad739697a68dc8a444f5b9f4817cf8f8f Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 14 Dec 2015 16:01:57 -0800 Subject: [PATCH 1292/2855] Drivers: hv: utils: Invoke the poll function after handshake When the handshake with daemon is complete, we should poll the channel since during the handshake, we will not be processing any messages. This is a potential bug if the host is waiting for a response from the guest. I would like to thank Dexuan for pointing this out. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_kvp.c | 2 +- drivers/hv/hv_snapshot.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index 2a3420c4ca598..d4ab81bcd5150 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c @@ -154,7 +154,7 @@ static int kvp_handle_handshake(struct hv_kvp_msg *msg) pr_debug("KVP: userspace daemon ver. %d registered\n", KVP_OP_REGISTER); kvp_register(dm_reg_value); - kvp_transaction.state = HVUTIL_READY; + hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper); return 0; } diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c index 81882d4848bdf..67def4a831c80 100644 --- a/drivers/hv/hv_snapshot.c +++ b/drivers/hv/hv_snapshot.c @@ -113,7 +113,7 @@ static int vss_handle_handshake(struct hv_vss_msg *vss_msg) default: return -EINVAL; } - vss_transaction.state = HVUTIL_READY; + hv_poll_channel(vss_transaction.recv_channel, vss_poll_wrapper); pr_debug("VSS: userspace daemon ver. %d registered\n", dm_reg_value); return 0; } -- GitLab From a689d2510f188e75391dbebacbddfd74d42f2a7e Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 14 Dec 2015 16:01:58 -0800 Subject: [PATCH 1293/2855] tools: hv: vss: fix the write()'s argument: error -> vss_msg Fix the write()'s argument in the daemon code. Cc: Vitaly Kuznetsov Cc: "K. Y. Srinivasan" Signed-off-by: Dexuan Cui Cc: stable@vger.kernel.org Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- tools/hv/hv_vss_daemon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c index 96234b638249e..5d51d6ff08e6a 100644 --- a/tools/hv/hv_vss_daemon.c +++ b/tools/hv/hv_vss_daemon.c @@ -254,7 +254,7 @@ int main(int argc, char *argv[]) syslog(LOG_ERR, "Illegal op:%d\n", op); } vss_msg->error = error; - len = write(vss_fd, &error, sizeof(struct hv_vss_msg)); + len = write(vss_fd, vss_msg, sizeof(struct hv_vss_msg)); if (len != sizeof(struct hv_vss_msg)) { syslog(LOG_ERR, "write failed; error: %d %s", errno, strerror(errno)); -- GitLab From 1f75338b6fece2bbd42ac3623830c65e2df6e031 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 14 Dec 2015 19:01:53 -0800 Subject: [PATCH 1294/2855] Drivers: hv: utils: fix memory leak on on_msg() failure inmsg should be freed in case of on_msg() failure to avoid memory leak. Preserve the error code from on_msg(). Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_utils_transport.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/hv/hv_utils_transport.c b/drivers/hv/hv_utils_transport.c index 24b2766a6d345..40abe44fcd984 100644 --- a/drivers/hv/hv_utils_transport.c +++ b/drivers/hv/hv_utils_transport.c @@ -77,6 +77,7 @@ static ssize_t hvt_op_write(struct file *file, const char __user *buf, { struct hvutil_transport *hvt; u8 *inmsg; + int ret; hvt = container_of(file->f_op, struct hvutil_transport, fops); @@ -84,11 +85,11 @@ static ssize_t hvt_op_write(struct file *file, const char __user *buf, if (IS_ERR(inmsg)) return PTR_ERR(inmsg); - if (hvt->on_msg(inmsg, count)) - return -EFAULT; + ret = hvt->on_msg(inmsg, count); + kfree(inmsg); - return count; + return ret ? ret : count; } static unsigned int hvt_op_poll(struct file *file, poll_table *wait) -- GitLab From a72f3a4ccff22de879a1f599210ecdd9bd483a43 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 14 Dec 2015 19:01:54 -0800 Subject: [PATCH 1295/2855] Drivers: hv: utils: rename outmsg_lock As a preparation to reusing outmsg_lock to protect test-and-set openrations on 'mode' rename it the more general 'lock'. Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_utils_transport.c | 14 +++++++------- drivers/hv/hv_utils_transport.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/hv/hv_utils_transport.c b/drivers/hv/hv_utils_transport.c index 40abe44fcd984..59c6f3d29f9a1 100644 --- a/drivers/hv/hv_utils_transport.c +++ b/drivers/hv/hv_utils_transport.c @@ -27,11 +27,11 @@ static struct list_head hvt_list = LIST_HEAD_INIT(hvt_list); static void hvt_reset(struct hvutil_transport *hvt) { - mutex_lock(&hvt->outmsg_lock); + mutex_lock(&hvt->lock); kfree(hvt->outmsg); hvt->outmsg = NULL; hvt->outmsg_len = 0; - mutex_unlock(&hvt->outmsg_lock); + mutex_unlock(&hvt->lock); if (hvt->on_reset) hvt->on_reset(); } @@ -47,7 +47,7 @@ static ssize_t hvt_op_read(struct file *file, char __user *buf, if (wait_event_interruptible(hvt->outmsg_q, hvt->outmsg_len > 0)) return -EINTR; - mutex_lock(&hvt->outmsg_lock); + mutex_lock(&hvt->lock); if (!hvt->outmsg) { ret = -EAGAIN; goto out_unlock; @@ -68,7 +68,7 @@ static ssize_t hvt_op_read(struct file *file, char __user *buf, hvt->outmsg_len = 0; out_unlock: - mutex_unlock(&hvt->outmsg_lock); + mutex_unlock(&hvt->lock); return ret; } @@ -197,7 +197,7 @@ int hvutil_transport_send(struct hvutil_transport *hvt, void *msg, int len) return ret; } /* HVUTIL_TRANSPORT_CHARDEV */ - mutex_lock(&hvt->outmsg_lock); + mutex_lock(&hvt->lock); if (hvt->outmsg) { /* Previous message wasn't received */ ret = -EFAULT; @@ -211,7 +211,7 @@ int hvutil_transport_send(struct hvutil_transport *hvt, void *msg, int len) } else ret = -ENOMEM; out_unlock: - mutex_unlock(&hvt->outmsg_lock); + mutex_unlock(&hvt->lock); return ret; } @@ -242,7 +242,7 @@ struct hvutil_transport *hvutil_transport_init(const char *name, hvt->mdev.fops = &hvt->fops; init_waitqueue_head(&hvt->outmsg_q); - mutex_init(&hvt->outmsg_lock); + mutex_init(&hvt->lock); spin_lock(&hvt_list_lock); list_add(&hvt->list, &hvt_list); diff --git a/drivers/hv/hv_utils_transport.h b/drivers/hv/hv_utils_transport.h index 314c76ce1b07f..bff4c921e8178 100644 --- a/drivers/hv/hv_utils_transport.h +++ b/drivers/hv/hv_utils_transport.h @@ -38,7 +38,7 @@ struct hvutil_transport { u8 *outmsg; /* message to the userspace */ int outmsg_len; /* its length */ wait_queue_head_t outmsg_q; /* poll/read wait queue */ - struct mutex outmsg_lock; /* protects outmsg */ + struct mutex lock; /* protects struct members */ }; struct hvutil_transport *hvutil_transport_init(const char *name, -- GitLab From a15025660d4703a8b37290a14734cb4a84875770 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 14 Dec 2015 19:01:55 -0800 Subject: [PATCH 1296/2855] Drivers: hv: utils: introduce HVUTIL_TRANSPORT_DESTROY mode When Hyper-V host asks us to remove some util driver by closing the appropriate channel there is no easy way to force the current file descriptor holder to hang up but we can start to respond -EBADF to all operations asking it to exit gracefully. As we're setting hvt->mode from two separate contexts now we need to use a proper locking. Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_utils_transport.c | 71 ++++++++++++++++++++++++++------- drivers/hv/hv_utils_transport.h | 1 + 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/drivers/hv/hv_utils_transport.c b/drivers/hv/hv_utils_transport.c index 59c6f3d29f9a1..31c2f8649271f 100644 --- a/drivers/hv/hv_utils_transport.c +++ b/drivers/hv/hv_utils_transport.c @@ -27,11 +27,9 @@ static struct list_head hvt_list = LIST_HEAD_INIT(hvt_list); static void hvt_reset(struct hvutil_transport *hvt) { - mutex_lock(&hvt->lock); kfree(hvt->outmsg); hvt->outmsg = NULL; hvt->outmsg_len = 0; - mutex_unlock(&hvt->lock); if (hvt->on_reset) hvt->on_reset(); } @@ -44,10 +42,17 @@ static ssize_t hvt_op_read(struct file *file, char __user *buf, hvt = container_of(file->f_op, struct hvutil_transport, fops); - if (wait_event_interruptible(hvt->outmsg_q, hvt->outmsg_len > 0)) + if (wait_event_interruptible(hvt->outmsg_q, hvt->outmsg_len > 0 || + hvt->mode != HVUTIL_TRANSPORT_CHARDEV)) return -EINTR; mutex_lock(&hvt->lock); + + if (hvt->mode == HVUTIL_TRANSPORT_DESTROY) { + ret = -EBADF; + goto out_unlock; + } + if (!hvt->outmsg) { ret = -EAGAIN; goto out_unlock; @@ -85,7 +90,10 @@ static ssize_t hvt_op_write(struct file *file, const char __user *buf, if (IS_ERR(inmsg)) return PTR_ERR(inmsg); - ret = hvt->on_msg(inmsg, count); + if (hvt->mode == HVUTIL_TRANSPORT_DESTROY) + ret = -EBADF; + else + ret = hvt->on_msg(inmsg, count); kfree(inmsg); @@ -99,6 +107,10 @@ static unsigned int hvt_op_poll(struct file *file, poll_table *wait) hvt = container_of(file->f_op, struct hvutil_transport, fops); poll_wait(file, &hvt->outmsg_q, wait); + + if (hvt->mode == HVUTIL_TRANSPORT_DESTROY) + return -EBADF; + if (hvt->outmsg_len > 0) return POLLIN | POLLRDNORM; @@ -108,26 +120,39 @@ static unsigned int hvt_op_poll(struct file *file, poll_table *wait) static int hvt_op_open(struct inode *inode, struct file *file) { struct hvutil_transport *hvt; + int ret = 0; + bool issue_reset = false; hvt = container_of(file->f_op, struct hvutil_transport, fops); - /* - * Switching to CHARDEV mode. We switch bach to INIT when device - * gets released. - */ - if (hvt->mode == HVUTIL_TRANSPORT_INIT) + mutex_lock(&hvt->lock); + + if (hvt->mode == HVUTIL_TRANSPORT_DESTROY) { + ret = -EBADF; + } else if (hvt->mode == HVUTIL_TRANSPORT_INIT) { + /* + * Switching to CHARDEV mode. We switch bach to INIT when + * device gets released. + */ hvt->mode = HVUTIL_TRANSPORT_CHARDEV; + } else if (hvt->mode == HVUTIL_TRANSPORT_NETLINK) { /* * We're switching from netlink communication to using char * device. Issue the reset first. */ - hvt_reset(hvt); + issue_reset = true; hvt->mode = HVUTIL_TRANSPORT_CHARDEV; - } else - return -EBUSY; + } else { + ret = -EBUSY; + } - return 0; + if (issue_reset) + hvt_reset(hvt); + + mutex_unlock(&hvt->lock); + + return ret; } static int hvt_op_release(struct inode *inode, struct file *file) @@ -136,12 +161,15 @@ static int hvt_op_release(struct inode *inode, struct file *file) hvt = container_of(file->f_op, struct hvutil_transport, fops); - hvt->mode = HVUTIL_TRANSPORT_INIT; + mutex_lock(&hvt->lock); + if (hvt->mode != HVUTIL_TRANSPORT_DESTROY) + hvt->mode = HVUTIL_TRANSPORT_INIT; /* * Cleanup message buffers to avoid spurious messages when the daemon * connects back. */ hvt_reset(hvt); + mutex_unlock(&hvt->lock); return 0; } @@ -168,6 +196,7 @@ static void hvt_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) * Switching to NETLINK mode. Switching to CHARDEV happens when someone * opens the device. */ + mutex_lock(&hvt->lock); if (hvt->mode == HVUTIL_TRANSPORT_INIT) hvt->mode = HVUTIL_TRANSPORT_NETLINK; @@ -175,6 +204,7 @@ static void hvt_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) hvt_found->on_msg(msg->data, msg->len); else pr_warn("hvt_cn_callback: unexpected netlink message!\n"); + mutex_unlock(&hvt->lock); } int hvutil_transport_send(struct hvutil_transport *hvt, void *msg, int len) @@ -182,7 +212,8 @@ int hvutil_transport_send(struct hvutil_transport *hvt, void *msg, int len) struct cn_msg *cn_msg; int ret = 0; - if (hvt->mode == HVUTIL_TRANSPORT_INIT) { + if (hvt->mode == HVUTIL_TRANSPORT_INIT || + hvt->mode == HVUTIL_TRANSPORT_DESTROY) { return -EINVAL; } else if (hvt->mode == HVUTIL_TRANSPORT_NETLINK) { cn_msg = kzalloc(sizeof(*cn_msg) + len, GFP_ATOMIC); @@ -198,6 +229,11 @@ int hvutil_transport_send(struct hvutil_transport *hvt, void *msg, int len) } /* HVUTIL_TRANSPORT_CHARDEV */ mutex_lock(&hvt->lock); + if (hvt->mode != HVUTIL_TRANSPORT_CHARDEV) { + ret = -EINVAL; + goto out_unlock; + } + if (hvt->outmsg) { /* Previous message wasn't received */ ret = -EFAULT; @@ -268,6 +304,11 @@ err_free_hvt: void hvutil_transport_destroy(struct hvutil_transport *hvt) { + mutex_lock(&hvt->lock); + hvt->mode = HVUTIL_TRANSPORT_DESTROY; + wake_up_interruptible(&hvt->outmsg_q); + mutex_unlock(&hvt->lock); + spin_lock(&hvt_list_lock); list_del(&hvt->list); spin_unlock(&hvt_list_lock); diff --git a/drivers/hv/hv_utils_transport.h b/drivers/hv/hv_utils_transport.h index bff4c921e8178..06254a165a18a 100644 --- a/drivers/hv/hv_utils_transport.h +++ b/drivers/hv/hv_utils_transport.h @@ -25,6 +25,7 @@ enum hvutil_transport_mode { HVUTIL_TRANSPORT_INIT = 0, HVUTIL_TRANSPORT_NETLINK, HVUTIL_TRANSPORT_CHARDEV, + HVUTIL_TRANSPORT_DESTROY, }; struct hvutil_transport { -- GitLab From 9420098adc50a88d4a441e0f92d54bfa7af44448 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 14 Dec 2015 19:01:56 -0800 Subject: [PATCH 1297/2855] Drivers: hv: utils: fix crash when device is removed from host side The crash is observed when a service is being disabled host side while userspace daemon is connected to the device: [ 90.244859] general protection fault: 0000 [#1] SMP ... [ 90.800082] Call Trace: [ 90.800082] [] __fput+0xc8/0x1f0 [ 90.800082] [] ____fput+0xe/0x10 ... [ 90.800082] [] do_signal+0x28/0x580 [ 90.800082] [] ? finish_task_switch+0xa6/0x180 [ 90.800082] [] ? __schedule+0x28f/0x870 [ 90.800082] [] ? hvt_op_read+0x12a/0x140 [hv_utils] ... The problem is that hvutil_transport_destroy() which does misc_deregister() freeing the appropriate device is reachable by two paths: module unload and from util_remove(). While module unload path is protected by .owner in struct file_operations util_remove() path is not. Freeing the device while someone holds an open fd for it is a show stopper. In general, it is not possible to revoke an fd from all users so the only way to solve the issue is to defer freeing the hvutil_transport structure. Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_utils_transport.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/hv/hv_utils_transport.c b/drivers/hv/hv_utils_transport.c index 31c2f8649271f..ee20b50742385 100644 --- a/drivers/hv/hv_utils_transport.c +++ b/drivers/hv/hv_utils_transport.c @@ -155,13 +155,22 @@ static int hvt_op_open(struct inode *inode, struct file *file) return ret; } +static void hvt_transport_free(struct hvutil_transport *hvt) +{ + misc_deregister(&hvt->mdev); + kfree(hvt->outmsg); + kfree(hvt); +} + static int hvt_op_release(struct inode *inode, struct file *file) { struct hvutil_transport *hvt; + int mode_old; hvt = container_of(file->f_op, struct hvutil_transport, fops); mutex_lock(&hvt->lock); + mode_old = hvt->mode; if (hvt->mode != HVUTIL_TRANSPORT_DESTROY) hvt->mode = HVUTIL_TRANSPORT_INIT; /* @@ -171,6 +180,9 @@ static int hvt_op_release(struct inode *inode, struct file *file) hvt_reset(hvt); mutex_unlock(&hvt->lock); + if (mode_old == HVUTIL_TRANSPORT_DESTROY) + hvt_transport_free(hvt); + return 0; } @@ -304,17 +316,25 @@ err_free_hvt: void hvutil_transport_destroy(struct hvutil_transport *hvt) { + int mode_old; + mutex_lock(&hvt->lock); + mode_old = hvt->mode; hvt->mode = HVUTIL_TRANSPORT_DESTROY; wake_up_interruptible(&hvt->outmsg_q); mutex_unlock(&hvt->lock); + /* + * In case we were in 'chardev' mode we still have an open fd so we + * have to defer freeing the device. Netlink interface can be freed + * now. + */ spin_lock(&hvt_list_lock); list_del(&hvt->list); spin_unlock(&hvt_list_lock); if (hvt->cn_id.idx > 0 && hvt->cn_id.val > 0) cn_del_callback(&hvt->cn_id); - misc_deregister(&hvt->mdev); - kfree(hvt->outmsg); - kfree(hvt); + + if (mode_old != HVUTIL_TRANSPORT_CHARDEV) + hvt_transport_free(hvt); } -- GitLab From 822f18d4d3e9d4efb4996bbe562d0f99ab82d7dd Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 14 Dec 2015 19:01:57 -0800 Subject: [PATCH 1298/2855] Drivers: hv: ring_buffer.c: fix comment style Convert 6+-string comments repeating function names to normal kernel-style comments and fix a couple of other comment style issues. No textual or functional changes intended. Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/ring_buffer.c | 135 ++++++++------------------------------- 1 file changed, 26 insertions(+), 109 deletions(-) diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c index 70a1a9a22f872..7bca513e32b02 100644 --- a/drivers/hv/ring_buffer.c +++ b/drivers/hv/ring_buffer.c @@ -112,9 +112,7 @@ static bool hv_need_to_signal_on_read(u32 prev_write_sz, u32 read_loc = rbi->ring_buffer->read_index; u32 pending_sz = rbi->ring_buffer->pending_send_sz; - /* - * If the other end is not blocked on write don't bother. - */ + /* If the other end is not blocked on write don't bother. */ if (pending_sz == 0) return false; @@ -128,12 +126,7 @@ static bool hv_need_to_signal_on_read(u32 prev_write_sz, return false; } -/* - * hv_get_next_write_location() - * - * Get the next write location for the specified ring buffer - * - */ +/* Get the next write location for the specified ring buffer. */ static inline u32 hv_get_next_write_location(struct hv_ring_buffer_info *ring_info) { @@ -142,12 +135,7 @@ hv_get_next_write_location(struct hv_ring_buffer_info *ring_info) return next; } -/* - * hv_set_next_write_location() - * - * Set the next write location for the specified ring buffer - * - */ +/* Set the next write location for the specified ring buffer. */ static inline void hv_set_next_write_location(struct hv_ring_buffer_info *ring_info, u32 next_write_location) @@ -155,11 +143,7 @@ hv_set_next_write_location(struct hv_ring_buffer_info *ring_info, ring_info->ring_buffer->write_index = next_write_location; } -/* - * hv_get_next_read_location() - * - * Get the next read location for the specified ring buffer - */ +/* Get the next read location for the specified ring buffer. */ static inline u32 hv_get_next_read_location(struct hv_ring_buffer_info *ring_info) { @@ -169,10 +153,8 @@ hv_get_next_read_location(struct hv_ring_buffer_info *ring_info) } /* - * hv_get_next_readlocation_withoffset() - * * Get the next read location + offset for the specified ring buffer. - * This allows the caller to skip + * This allows the caller to skip. */ static inline u32 hv_get_next_readlocation_withoffset(struct hv_ring_buffer_info *ring_info, @@ -186,13 +168,7 @@ hv_get_next_readlocation_withoffset(struct hv_ring_buffer_info *ring_info, return next; } -/* - * - * hv_set_next_read_location() - * - * Set the next read location for the specified ring buffer - * - */ +/* Set the next read location for the specified ring buffer. */ static inline void hv_set_next_read_location(struct hv_ring_buffer_info *ring_info, u32 next_read_location) @@ -201,12 +177,7 @@ hv_set_next_read_location(struct hv_ring_buffer_info *ring_info, } -/* - * - * hv_get_ring_buffer() - * - * Get the start of the ring buffer - */ +/* Get the start of the ring buffer. */ static inline void * hv_get_ring_buffer(struct hv_ring_buffer_info *ring_info) { @@ -214,25 +185,14 @@ hv_get_ring_buffer(struct hv_ring_buffer_info *ring_info) } -/* - * - * hv_get_ring_buffersize() - * - * Get the size of the ring buffer - */ +/* Get the size of the ring buffer. */ static inline u32 hv_get_ring_buffersize(struct hv_ring_buffer_info *ring_info) { return ring_info->ring_datasize; } -/* - * - * hv_get_ring_bufferindices() - * - * Get the read and write indices as u64 of the specified ring buffer - * - */ +/* Get the read and write indices as u64 of the specified ring buffer. */ static inline u64 hv_get_ring_bufferindices(struct hv_ring_buffer_info *ring_info) { @@ -240,12 +200,8 @@ hv_get_ring_bufferindices(struct hv_ring_buffer_info *ring_info) } /* - * - * hv_copyfrom_ringbuffer() - * * Helper routine to copy to source from ring buffer. * Assume there is enough room. Handles wrap-around in src case only!! - * */ static u32 hv_copyfrom_ringbuffer( struct hv_ring_buffer_info *ring_info, @@ -277,12 +233,8 @@ static u32 hv_copyfrom_ringbuffer( /* - * - * hv_copyto_ringbuffer() - * * Helper routine to copy from source to ring buffer. * Assume there is enough room. Handles wrap-around in dest case only!! - * */ static u32 hv_copyto_ringbuffer( struct hv_ring_buffer_info *ring_info, @@ -308,13 +260,7 @@ static u32 hv_copyto_ringbuffer( return start_write_offset; } -/* - * - * hv_ringbuffer_get_debuginfo() - * - * Get various debug metrics for the specified ring buffer - * - */ +/* Get various debug metrics for the specified ring buffer. */ void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info, struct hv_ring_buffer_debug_info *debug_info) { @@ -337,13 +283,7 @@ void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info, } } -/* - * - * hv_ringbuffer_init() - * - *Initialize the ring buffer - * - */ +/* Initialize the ring buffer. */ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, void *buffer, u32 buflen) { @@ -356,9 +296,7 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, ring_info->ring_buffer->read_index = ring_info->ring_buffer->write_index = 0; - /* - * Set the feature bit for enabling flow control. - */ + /* Set the feature bit for enabling flow control. */ ring_info->ring_buffer->feature_bits.value = 1; ring_info->ring_size = buflen; @@ -369,24 +307,12 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, return 0; } -/* - * - * hv_ringbuffer_cleanup() - * - * Cleanup the ring buffer - * - */ +/* Cleanup the ring buffer. */ void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info) { } -/* - * - * hv_ringbuffer_write() - * - * Write to the ring buffer - * - */ +/* Write to the ring buffer. */ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, struct kvec *kv_list, u32 kv_count, bool *signal) { @@ -411,10 +337,11 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, &bytes_avail_toread, &bytes_avail_towrite); - - /* If there is only room for the packet, assume it is full. */ - /* Otherwise, the next time around, we think the ring buffer */ - /* is empty since the read index == write index */ + /* + * If there is only room for the packet, assume it is full. + * Otherwise, the next time around, we think the ring buffer + * is empty since the read index == write index. + */ if (bytes_avail_towrite <= totalbytes_towrite) { spin_unlock_irqrestore(&outring_info->ring_lock, flags); return -EAGAIN; @@ -454,13 +381,7 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, } -/* - * - * hv_ringbuffer_peek() - * - * Read without advancing the read index - * - */ +/* Read without advancing the read index. */ int hv_ringbuffer_peek(struct hv_ring_buffer_info *Inring_info, void *Buffer, u32 buflen) { @@ -497,13 +418,7 @@ int hv_ringbuffer_peek(struct hv_ring_buffer_info *Inring_info, } -/* - * - * hv_ringbuffer_read() - * - * Read and advance the read index - * - */ +/* Read and advance the read index. */ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer, u32 buflen, u32 offset, bool *signal) { @@ -542,9 +457,11 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer, sizeof(u64), next_read_location); - /* Make sure all reads are done before we update the read index since */ - /* the writer may start writing to the read area once the read index */ - /*is updated */ + /* + * Make sure all reads are done before we update the read index since + * the writer may start writing to the read area once the read index + * is updated. + */ mb(); /* Update the read index */ -- GitLab From 45870a441361d1c05a5f767c4ece2f6e30e0da9c Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 14 Dec 2015 19:01:58 -0800 Subject: [PATCH 1299/2855] Drivers: hv: ring_buffer: remove stray smp_read_barrier_depends() smp_read_barrier_depends() does nothing on almost all arcitectures including x86 and having it in the beginning of hv_get_ringbuffer_availbytes() does not provide any guarantees anyway. Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- include/linux/hyperv.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index acd995b81c6bb..179ff330af597 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -141,8 +141,6 @@ hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi, { u32 read_loc, write_loc, dsize; - smp_read_barrier_depends(); - /* Capture the read/write indices before they changed */ read_loc = rbi->ring_buffer->read_index; write_loc = rbi->ring_buffer->write_index; -- GitLab From b5f53dde8d8e84a6ee200dbd0bd90a400a8fe1a1 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 14 Dec 2015 19:01:59 -0800 Subject: [PATCH 1300/2855] Drivers: hv: ring_buffer: remove code duplication from hv_ringbuffer_peek/read() hv_ringbuffer_peek() does the same as hv_ringbuffer_read() without advancing the read index. The only functional change this patch brings is moving hv_need_to_signal_on_read() call under the ring_lock but this function is just a couple of comparisons. Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/ring_buffer.c | 68 +++++++++++++++------------------------- 1 file changed, 25 insertions(+), 43 deletions(-) diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c index 7bca513e32b02..07f9408fc59e0 100644 --- a/drivers/hv/ring_buffer.c +++ b/drivers/hv/ring_buffer.c @@ -380,47 +380,9 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, return 0; } - -/* Read without advancing the read index. */ -int hv_ringbuffer_peek(struct hv_ring_buffer_info *Inring_info, - void *Buffer, u32 buflen) -{ - u32 bytes_avail_towrite; - u32 bytes_avail_toread; - u32 next_read_location = 0; - unsigned long flags; - - spin_lock_irqsave(&Inring_info->ring_lock, flags); - - hv_get_ringbuffer_availbytes(Inring_info, - &bytes_avail_toread, - &bytes_avail_towrite); - - /* Make sure there is something to read */ - if (bytes_avail_toread < buflen) { - - spin_unlock_irqrestore(&Inring_info->ring_lock, flags); - - return -EAGAIN; - } - - /* Convert to byte offset */ - next_read_location = hv_get_next_read_location(Inring_info); - - next_read_location = hv_copyfrom_ringbuffer(Inring_info, - Buffer, - buflen, - next_read_location); - - spin_unlock_irqrestore(&Inring_info->ring_lock, flags); - - return 0; -} - - -/* Read and advance the read index. */ -int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer, - u32 buflen, u32 offset, bool *signal) +static inline int __hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, + void *buffer, u32 buflen, u32 offset, + bool *signal, bool advance) { u32 bytes_avail_towrite; u32 bytes_avail_toread; @@ -452,6 +414,9 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer, buflen, next_read_location); + if (!advance) + goto out_unlock; + next_read_location = hv_copyfrom_ringbuffer(inring_info, &prev_indices, sizeof(u64), @@ -467,9 +432,26 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer, /* Update the read index */ hv_set_next_read_location(inring_info, next_read_location); - spin_unlock_irqrestore(&inring_info->ring_lock, flags); - *signal = hv_need_to_signal_on_read(bytes_avail_towrite, inring_info); +out_unlock: + spin_unlock_irqrestore(&inring_info->ring_lock, flags); return 0; } + +/* Read from ring buffer without advancing the read index. */ +int hv_ringbuffer_peek(struct hv_ring_buffer_info *inring_info, + void *buffer, u32 buflen) +{ + return __hv_ringbuffer_read(inring_info, buffer, buflen, + 0, NULL, false); +} + +/* Read from ring buffer and advance the read index. */ +int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, + void *buffer, u32 buflen, u32 offset, + bool *signal) +{ + return __hv_ringbuffer_read(inring_info, buffer, buflen, + offset, signal, true); +} -- GitLab From 667d374064b0cc48b6122101b287908d1b392bdb Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 14 Dec 2015 19:02:00 -0800 Subject: [PATCH 1301/2855] Drivers: hv: remove code duplication between vmbus_recvpacket()/vmbus_recvpacket_raw() vmbus_recvpacket() and vmbus_recvpacket_raw() are almost identical but there are two discrepancies: 1) vmbus_recvpacket() doesn't propagate errors from hv_ringbuffer_read() which looks like it is not desired. 2) There is an error message printed in packetlen > bufferlen case in vmbus_recvpacket(). I'm removing it as it is usless for users to see such messages and /vmbus_recvpacket_raw() doesn't have it. Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel.c | 65 +++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 43 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 2889d97c03b1d..dd6de7fc442f9 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -922,8 +922,10 @@ EXPORT_SYMBOL_GPL(vmbus_sendpacket_multipagebuffer); * * Mainly used by Hyper-V drivers. */ -int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, - u32 bufferlen, u32 *buffer_actual_len, u64 *requestid) +static inline int +__vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, + u32 bufferlen, u32 *buffer_actual_len, u64 *requestid, + bool raw) { struct vmpacket_descriptor desc; u32 packetlen; @@ -941,27 +943,34 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, return 0; packetlen = desc.len8 << 3; - userlen = packetlen - (desc.offset8 << 3); + if (!raw) + userlen = packetlen - (desc.offset8 << 3); + else + userlen = packetlen; *buffer_actual_len = userlen; - if (userlen > bufferlen) { - - pr_err("Buffer too small - got %d needs %d\n", - bufferlen, userlen); - return -ETOOSMALL; - } + if (userlen > bufferlen) + return -ENOBUFS; *requestid = desc.trans_id; /* Copy over the packet to the user buffer */ ret = hv_ringbuffer_read(&channel->inbound, buffer, userlen, - (desc.offset8 << 3), &signal); + raw ? 0 : desc.offset8 << 3, &signal); if (signal) vmbus_setevent(channel); - return 0; + return ret; +} + +int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, + u32 bufferlen, u32 *buffer_actual_len, + u64 *requestid) +{ + return __vmbus_recvpacket(channel, buffer, bufferlen, + buffer_actual_len, requestid, false); } EXPORT_SYMBOL(vmbus_recvpacket); @@ -972,37 +981,7 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, u32 bufferlen, u32 *buffer_actual_len, u64 *requestid) { - struct vmpacket_descriptor desc; - u32 packetlen; - int ret; - bool signal = false; - - *buffer_actual_len = 0; - *requestid = 0; - - - ret = hv_ringbuffer_peek(&channel->inbound, &desc, - sizeof(struct vmpacket_descriptor)); - if (ret != 0) - return 0; - - - packetlen = desc.len8 << 3; - - *buffer_actual_len = packetlen; - - if (packetlen > bufferlen) - return -ENOBUFS; - - *requestid = desc.trans_id; - - /* Copy over the entire packet to the user buffer */ - ret = hv_ringbuffer_read(&channel->inbound, buffer, packetlen, 0, - &signal); - - if (signal) - vmbus_setevent(channel); - - return ret; + return __vmbus_recvpacket(channel, buffer, bufferlen, + buffer_actual_len, requestid, true); } EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw); -- GitLab From 940b68e2c3e4ebf032885203c3970e9649f814af Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 14 Dec 2015 19:02:01 -0800 Subject: [PATCH 1302/2855] Drivers: hv: ring_buffer: eliminate hv_ringbuffer_peek() Currently, there is only one user for hv_ringbuffer_read()/ hv_ringbuffer_peak() functions and the usage of these functions is: - insecure as we drop ring_lock between them, someone else (in theory only) can acquire it in between; - non-optimal as we do a number of things (acquire/release the above mentioned lock, calculate available space on the ring, ...) twice and this path is performance-critical. Remove hv_ringbuffer_peek() moving the logic from __vmbus_recvpacket() to hv_ringbuffer_read(). Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel.c | 30 ++---------------- drivers/hv/hyperv_vmbus.h | 11 ++----- drivers/hv/ring_buffer.c | 65 ++++++++++++++++++++++----------------- 3 files changed, 42 insertions(+), 64 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index dd6de7fc442f9..1161d68a18635 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -927,37 +927,11 @@ __vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, u32 bufferlen, u32 *buffer_actual_len, u64 *requestid, bool raw) { - struct vmpacket_descriptor desc; - u32 packetlen; - u32 userlen; int ret; bool signal = false; - *buffer_actual_len = 0; - *requestid = 0; - - - ret = hv_ringbuffer_peek(&channel->inbound, &desc, - sizeof(struct vmpacket_descriptor)); - if (ret != 0) - return 0; - - packetlen = desc.len8 << 3; - if (!raw) - userlen = packetlen - (desc.offset8 << 3); - else - userlen = packetlen; - - *buffer_actual_len = userlen; - - if (userlen > bufferlen) - return -ENOBUFS; - - *requestid = desc.trans_id; - - /* Copy over the packet to the user buffer */ - ret = hv_ringbuffer_read(&channel->inbound, buffer, userlen, - raw ? 0 : desc.offset8 << 3, &signal); + ret = hv_ringbuffer_read(&channel->inbound, buffer, bufferlen, + buffer_actual_len, requestid, &signal, raw); if (signal) vmbus_setevent(channel); diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 4d67e984ac4fa..0411b7bfb3c0b 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -619,14 +619,9 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *ring_info, struct kvec *kv_list, u32 kv_count, bool *signal); -int hv_ringbuffer_peek(struct hv_ring_buffer_info *ring_info, void *buffer, - u32 buflen); - -int hv_ringbuffer_read(struct hv_ring_buffer_info *ring_info, - void *buffer, - u32 buflen, - u32 offset, bool *signal); - +int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, + void *buffer, u32 buflen, u32 *buffer_actual_len, + u64 *requestid, bool *signal, bool raw); void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info, struct hv_ring_buffer_debug_info *debug_info); diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c index 07f9408fc59e0..b53702ce692f3 100644 --- a/drivers/hv/ring_buffer.c +++ b/drivers/hv/ring_buffer.c @@ -380,30 +380,59 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, return 0; } -static inline int __hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, - void *buffer, u32 buflen, u32 offset, - bool *signal, bool advance) +int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, + void *buffer, u32 buflen, u32 *buffer_actual_len, + u64 *requestid, bool *signal, bool raw) { u32 bytes_avail_towrite; u32 bytes_avail_toread; u32 next_read_location = 0; u64 prev_indices = 0; unsigned long flags; + struct vmpacket_descriptor desc; + u32 offset; + u32 packetlen; + int ret = 0; if (buflen <= 0) return -EINVAL; spin_lock_irqsave(&inring_info->ring_lock, flags); + *buffer_actual_len = 0; + *requestid = 0; + hv_get_ringbuffer_availbytes(inring_info, &bytes_avail_toread, &bytes_avail_towrite); /* Make sure there is something to read */ - if (bytes_avail_toread < buflen) { - spin_unlock_irqrestore(&inring_info->ring_lock, flags); + if (bytes_avail_toread < sizeof(desc)) { + /* + * No error is set when there is even no header, drivers are + * supposed to analyze buffer_actual_len. + */ + goto out_unlock; + } - return -EAGAIN; + next_read_location = hv_get_next_read_location(inring_info); + next_read_location = hv_copyfrom_ringbuffer(inring_info, &desc, + sizeof(desc), + next_read_location); + + offset = raw ? 0 : (desc.offset8 << 3); + packetlen = (desc.len8 << 3) - offset; + *buffer_actual_len = packetlen; + *requestid = desc.trans_id; + + if (bytes_avail_toread < packetlen + offset) { + ret = -EAGAIN; + goto out_unlock; + } + + if (packetlen > buflen) { + ret = -ENOBUFS; + goto out_unlock; } next_read_location = @@ -411,12 +440,9 @@ static inline int __hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, next_read_location = hv_copyfrom_ringbuffer(inring_info, buffer, - buflen, + packetlen, next_read_location); - if (!advance) - goto out_unlock; - next_read_location = hv_copyfrom_ringbuffer(inring_info, &prev_indices, sizeof(u64), @@ -436,22 +462,5 @@ static inline int __hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, out_unlock: spin_unlock_irqrestore(&inring_info->ring_lock, flags); - return 0; -} - -/* Read from ring buffer without advancing the read index. */ -int hv_ringbuffer_peek(struct hv_ring_buffer_info *inring_info, - void *buffer, u32 buflen) -{ - return __hv_ringbuffer_read(inring_info, buffer, buflen, - 0, NULL, false); -} - -/* Read from ring buffer and advance the read index. */ -int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, - void *buffer, u32 buflen, u32 offset, - bool *signal) -{ - return __hv_ringbuffer_read(inring_info, buffer, buflen, - offset, signal, true); + return ret; } -- GitLab From 979fccfb7348dbd968daf0249aa484a0297f83df Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 15 Dec 2015 00:34:21 -0800 Subject: [PATCH 1303/2855] libnvdimm, pfn: enable pfn sysfs interface unit testing The unit test infrastructure uses CMA and real memory to emulate nvdimm resources. The call to devm_memremap_pages() can simply be mocked in the same manner as memremap and we mock phys_to_pfn_t() to clear PFN_MAP since these resources are not registered with in the pgmap_radix. Signed-off-by: Dan Williams --- tools/testing/nvdimm/Kbuild | 2 ++ tools/testing/nvdimm/test/iomap.c | 48 +++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild index 38b00ecb2ed55..a34bfd0c89289 100644 --- a/tools/testing/nvdimm/Kbuild +++ b/tools/testing/nvdimm/Kbuild @@ -9,6 +9,8 @@ ldflags-y += --wrap=memunmap ldflags-y += --wrap=__devm_request_region ldflags-y += --wrap=__request_region ldflags-y += --wrap=__release_region +ldflags-y += --wrap=devm_memremap_pages +ldflags-y += --wrap=phys_to_pfn_t DRIVERS := ../../../drivers NVDIMM_SRC := $(DRIVERS)/nvdimm diff --git a/tools/testing/nvdimm/test/iomap.c b/tools/testing/nvdimm/test/iomap.c index b7251314bbc03..79e110d4a81a1 100644 --- a/tools/testing/nvdimm/test/iomap.c +++ b/tools/testing/nvdimm/test/iomap.c @@ -94,6 +94,54 @@ void *__wrap_devm_memremap(struct device *dev, resource_size_t offset, } EXPORT_SYMBOL(__wrap_devm_memremap); +#ifdef __HAVE_ARCH_PTE_DEVMAP +#include +#include + +void *__wrap_devm_memremap_pages(struct device *dev, struct resource *res, + struct percpu_ref *ref, struct vmem_altmap *altmap) +{ + resource_size_t offset = res->start; + struct nfit_test_resource *nfit_res; + + rcu_read_lock(); + nfit_res = get_nfit_res(offset); + rcu_read_unlock(); + if (nfit_res) + return nfit_res->buf + offset - nfit_res->res->start; + return devm_memremap_pages(dev, res, ref, altmap); +} +EXPORT_SYMBOL(__wrap_devm_memremap_pages); + +pfn_t __wrap_phys_to_pfn_t(dma_addr_t addr, unsigned long flags) +{ + struct nfit_test_resource *nfit_res; + + rcu_read_lock(); + nfit_res = get_nfit_res(addr); + rcu_read_unlock(); + if (nfit_res) + flags &= ~PFN_MAP; + return phys_to_pfn_t(addr, flags); +} +EXPORT_SYMBOL(__wrap_phys_to_pfn_t); +#else +/* to be removed post 4.5-rc1 */ +void *__wrap_devm_memremap_pages(struct device *dev, struct resource *res) +{ + resource_size_t offset = res->start; + struct nfit_test_resource *nfit_res; + + rcu_read_lock(); + nfit_res = get_nfit_res(offset); + rcu_read_unlock(); + if (nfit_res) + return nfit_res->buf + offset - nfit_res->res->start; + return devm_memremap_pages(dev, res); +} +EXPORT_SYMBOL(__wrap_devm_memremap_pages); +#endif + void *__wrap_memremap(resource_size_t offset, size_t size, unsigned long flags) { -- GitLab From 75d31c2372e4a08319919b14bd160c48305373a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5ns=20Rullg=C3=A5rd?= Date: Mon, 2 Nov 2015 02:03:36 +0000 Subject: [PATCH 1304/2855] i2c: xlr: add support for Sigma Designs controller variant Sigma Designs chips use a variant of this controller with the following differences: - The BUSY bit in the STATUS register is inverted - Bit 8 of the CONFIG register must be set - The controller can generate interrupts This patch adds support for the first two of these. It also calculates and sets the correct clock divisor if a clk is provided. The bus frequency is optionally speficied in the device tree node. Signed-off-by: Mans Rullgard Signed-off-by: Wolfram Sang --- drivers/i2c/busses/Kconfig | 6 +-- drivers/i2c/busses/i2c-xlr.c | 81 ++++++++++++++++++++++++++++++++++-- 2 files changed, 80 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 69c46fe137771..eaa7b4a0e4843 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -963,11 +963,11 @@ config I2C_XILINX will be called xilinx_i2c. config I2C_XLR - tristate "XLR I2C support" - depends on CPU_XLR + tristate "Netlogic XLR and Sigma Designs I2C support" + depends on CPU_XLR || ARCH_TANGOX help This driver enables support for the on-chip I2C interface of - the Netlogic XLR/XLS MIPS processors. + the Netlogic XLR/XLS MIPS processors and Sigma Designs SOCs. This driver can also be built as a module. If so, the module will be called i2c-xlr. diff --git a/drivers/i2c/busses/i2c-xlr.c b/drivers/i2c/busses/i2c-xlr.c index 8b36bcfd952dd..10fb916fa8c76 100644 --- a/drivers/i2c/busses/i2c-xlr.c +++ b/drivers/i2c/busses/i2c-xlr.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include /* XLR I2C REGISTERS */ #define XLR_I2C_CFG 0x00 @@ -63,11 +65,23 @@ static inline u32 xlr_i2c_rdreg(u32 __iomem *base, unsigned int reg) return __raw_readl(base + reg); } +struct xlr_i2c_config { + u32 status_busy; /* value of STATUS[0] when busy */ + u32 cfg_extra; /* extra CFG bits to set */ +}; + struct xlr_i2c_private { struct i2c_adapter adap; u32 __iomem *iobase; + const struct xlr_i2c_config *cfg; + struct clk *clk; }; +static int xlr_i2c_busy(struct xlr_i2c_private *priv, u32 status) +{ + return (status & XLR_I2C_BUS_BUSY) == priv->cfg->status_busy; +} + static int xlr_i2c_tx(struct xlr_i2c_private *priv, u16 len, u8 *buf, u16 addr) { @@ -80,7 +94,8 @@ static int xlr_i2c_tx(struct xlr_i2c_private *priv, u16 len, offset = buf[0]; xlr_i2c_wreg(priv->iobase, XLR_I2C_ADDR, offset); xlr_i2c_wreg(priv->iobase, XLR_I2C_DEVADDR, addr); - xlr_i2c_wreg(priv->iobase, XLR_I2C_CFG, XLR_I2C_CFG_ADDR); + xlr_i2c_wreg(priv->iobase, XLR_I2C_CFG, + XLR_I2C_CFG_ADDR | priv->cfg->cfg_extra); xlr_i2c_wreg(priv->iobase, XLR_I2C_BYTECNT, len - 1); timeout = msecs_to_jiffies(XLR_I2C_TIMEOUT); @@ -121,7 +136,7 @@ retry: if (i2c_status & XLR_I2C_ACK_ERR) return -EIO; - if ((i2c_status & XLR_I2C_BUS_BUSY) == 0 && pos >= len) + if (!xlr_i2c_busy(priv, i2c_status) && pos >= len) return 0; } dev_err(&adap->dev, "I2C transmit timeout\n"); @@ -136,7 +151,8 @@ static int xlr_i2c_rx(struct xlr_i2c_private *priv, u16 len, u8 *buf, u16 addr) int nbytes, timedout; u8 byte; - xlr_i2c_wreg(priv->iobase, XLR_I2C_CFG, XLR_I2C_CFG_NOADDR); + xlr_i2c_wreg(priv->iobase, XLR_I2C_CFG, + XLR_I2C_CFG_NOADDR | priv->cfg->cfg_extra); xlr_i2c_wreg(priv->iobase, XLR_I2C_BYTECNT, len); xlr_i2c_wreg(priv->iobase, XLR_I2C_DEVADDR, addr); @@ -174,7 +190,7 @@ retry: if (i2c_status & XLR_I2C_ACK_ERR) return -EIO; - if ((i2c_status & XLR_I2C_BUS_BUSY) == 0) + if (!xlr_i2c_busy(priv, i2c_status)) return 0; } @@ -190,6 +206,10 @@ static int xlr_i2c_xfer(struct i2c_adapter *adap, int ret = 0; struct xlr_i2c_private *priv = i2c_get_adapdata(adap); + ret = clk_enable(priv->clk); + if (ret) + return ret; + for (i = 0; ret == 0 && i < num; i++) { msg = &msgs[i]; if (msg->flags & I2C_M_RD) @@ -200,6 +220,8 @@ static int xlr_i2c_xfer(struct i2c_adapter *adap, msg->addr); } + clk_disable(priv->clk); + return (ret != 0) ? ret : num; } @@ -214,22 +236,70 @@ static struct i2c_algorithm xlr_i2c_algo = { .functionality = xlr_func, }; +static const struct xlr_i2c_config xlr_i2c_config_default = { + .status_busy = XLR_I2C_BUS_BUSY, + .cfg_extra = 0, +}; + +static const struct xlr_i2c_config xlr_i2c_config_tangox = { + .status_busy = 0, + .cfg_extra = 1 << 8, +}; + +static const struct of_device_id xlr_i2c_dt_ids[] = { + { + .compatible = "sigma,smp8642-i2c", + .data = &xlr_i2c_config_tangox, + }, + { } +}; + static int xlr_i2c_probe(struct platform_device *pdev) { + const struct of_device_id *match; struct xlr_i2c_private *priv; struct resource *res; + struct clk *clk; + unsigned long clk_rate; + unsigned long clk_div; + u32 busfreq; int ret; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + match = of_match_device(xlr_i2c_dt_ids, &pdev->dev); + if (match) + priv->cfg = match->data; + else + priv->cfg = &xlr_i2c_config_default; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->iobase = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->iobase)) return PTR_ERR(priv->iobase); + if (of_property_read_u32(pdev->dev.of_node, "clock-frequency", + &busfreq)) + busfreq = 100000; + + clk = devm_clk_get(&pdev->dev, NULL); + if (!IS_ERR(clk)) { + ret = clk_prepare_enable(clk); + if (ret) + return ret; + + clk_rate = clk_get_rate(clk); + clk_div = DIV_ROUND_UP(clk_rate, 2 * busfreq); + xlr_i2c_wreg(priv->iobase, XLR_I2C_CLKDIV, clk_div); + + clk_disable(clk); + priv->clk = clk; + } + priv->adap.dev.parent = &pdev->dev; + priv->adap.dev.of_node = pdev->dev.of_node; priv->adap.owner = THIS_MODULE; priv->adap.algo_data = priv; priv->adap.algo = &xlr_i2c_algo; @@ -255,6 +325,8 @@ static int xlr_i2c_remove(struct platform_device *pdev) priv = platform_get_drvdata(pdev); i2c_del_adapter(&priv->adap); + clk_unprepare(priv->clk); + return 0; } @@ -263,6 +335,7 @@ static struct platform_driver xlr_i2c_driver = { .remove = xlr_i2c_remove, .driver = { .name = "xlr-i2cbus", + .of_match_table = xlr_i2c_dt_ids, }, }; -- GitLab From bb423984c28e9f94a8f466b791baa762cef0543d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 16 Nov 2015 15:31:21 -0600 Subject: [PATCH 1305/2855] usb: dwc3: gadget: simplify dwc3_gadget_ep_queue() By moving our sanity checks our internal function __dwc3_gadget_ep_queue() we can simplify the externally visible API while also making sure that callers of __dwc3_gadget_ep_queue() also make use of the same checks. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index a58376fd65fe6..98fb8028c792a 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1044,6 +1044,17 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) struct dwc3 *dwc = dep->dwc; int ret; + if (!dep->endpoint.desc) { + dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n", + &req->request, dep->endpoint.name); + return -ESHUTDOWN; + } + + if (WARN(req->dep != dep, "request %p belongs to '%s'\n", + &req->request, req->dep->name)) { + return -EINVAL; + } + req->request.actual = 0; req->request.status = -EINPROGRESS; req->direction = dep->direction; @@ -1161,22 +1172,7 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, int ret; spin_lock_irqsave(&dwc->lock, flags); - if (!dep->endpoint.desc) { - dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n", - request, ep->name); - ret = -ESHUTDOWN; - goto out; - } - - if (WARN(req->dep != dep, "request %p belongs to '%s'\n", - request, req->dep->name)) { - ret = -EINVAL; - goto out; - } - ret = __dwc3_gadget_ep_queue(dep, req); - -out: spin_unlock_irqrestore(&dwc->lock, flags); return ret; -- GitLab From ec5e795cdefb74b55c9fce918aa8a9226a8eec41 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 16 Nov 2015 16:04:13 -0600 Subject: [PATCH 1306/2855] usb: dwc3: gadget: purge dev_dbg() calls The last few dev_dbg() messages are converted to tracepoints and we can finally ignore dev_dbg() messages during debug sessions. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 98fb8028c792a..ca06ab8e2e4e5 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -265,9 +265,6 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, usb_gadget_unmap_request(&dwc->gadget, &req->request, req->direction); - dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", - req, dep->name, req->request.actual, - req->request.length, status); trace_dwc3_gadget_giveback(req); spin_unlock(&dwc->lock); @@ -985,8 +982,6 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param, cmd |= DWC3_DEPCMD_PARAM(cmd_param); ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); if (ret < 0) { - dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n"); - /* * FIXME we need to iterate over the list of requests * here and stop, unmap, free and del each of the linked @@ -1045,13 +1040,16 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) int ret; if (!dep->endpoint.desc) { - dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n", + dwc3_trace(trace_dwc3_gadget, + "trying to queue request %p to disabled %s\n", &req->request, dep->endpoint.name); return -ESHUTDOWN; } if (WARN(req->dep != dep, "request %p belongs to '%s'\n", &req->request, req->dep->name)) { + dwc3_trace(trace_dwc3_gadget, "request %p belongs to '%s'\n", + &req->request, req->dep->name); return -EINVAL; } @@ -1152,7 +1150,8 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) out: if (ret && ret != -EBUSY) - dev_dbg(dwc->dev, "%s: failed to kick transfers\n", + dwc3_trace(trace_dwc3_gadget, + "%s: failed to kick transfers\n", dep->name); if (ret == -EBUSY) ret = 0; @@ -1242,7 +1241,8 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol) if (!protocol && ((dep->direction && dep->flags & DWC3_EP_BUSY) || (!list_empty(&dep->req_queued) || !list_empty(&dep->request_list)))) { - dev_dbg(dwc->dev, "%s: pending request, cannot halt\n", + dwc3_trace(trace_dwc3_gadget, + "%s: pending request, cannot halt\n", dep->name); return -EAGAIN; } @@ -1369,7 +1369,7 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g) speed = reg & DWC3_DSTS_CONNECTSPD; if (speed == DWC3_DSTS_SUPERSPEED) { - dev_dbg(dwc->dev, "no wakeup on SuperSpeed\n"); + dwc3_trace(trace_dwc3_gadget, "no wakeup on SuperSpeed\n"); ret = -EINVAL; goto out; } @@ -1381,8 +1381,9 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g) case DWC3_LINK_STATE_U3: /* in HS, means SUSPEND */ break; default: - dev_dbg(dwc->dev, "can't wakeup from link state %d\n", - link_state); + dwc3_trace(trace_dwc3_gadget, + "can't wakeup from '%s'\n", + dwc3_gadget_link_string(link_state)); ret = -EINVAL; goto out; } @@ -1821,7 +1822,8 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, if (count) { trb_status = DWC3_TRB_SIZE_TRBSTS(trb->size); if (trb_status == DWC3_TRBSTS_MISSED_ISOC) { - dev_dbg(dwc->dev, "incomplete IN transfer %s\n", + dwc3_trace(trace_dwc3_gadget, + "%s: incomplete IN transfer\n", dep->name); /* * If missed isoc occurred and there is @@ -2000,7 +2002,8 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, dep->resource_index = 0; if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { - dev_dbg(dwc->dev, "%s is an Isochronous endpoint\n", + dwc3_trace(trace_dwc3_gadget, + "%s is an Isochronous endpoint\n", dep->name); return; } @@ -2027,7 +2030,8 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, if (!ret || ret == -EBUSY) return; - dev_dbg(dwc->dev, "%s: failed to kick transfers\n", + dwc3_trace(trace_dwc3_gadget, + "%s: failed to kick transfers\n", dep->name); } @@ -2049,11 +2053,12 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, case DEPEVT_STREAMEVT_NOTFOUND: /* FALLTHROUGH */ default: - dev_dbg(dwc->dev, "Couldn't find suitable stream\n"); + dwc3_trace(trace_dwc3_gadget, + "unable to find suitable stream\n"); } break; case DWC3_DEPEVT_RXTXFIFOEVT: - dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name); + dwc3_trace(trace_dwc3_gadget, "%s FIFO Overrun\n", dep->name); break; case DWC3_DEPEVT_EPCMDCMPLT: dwc3_trace(trace_dwc3_gadget, "Endpoint Command Complete"); -- GitLab From 1407bf13e3bf5f1168484c3e68b6ef9d8cf2bc72 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 16 Nov 2015 16:06:37 -0600 Subject: [PATCH 1307/2855] usb: dwc3: core: purge dev_dbg() calls The last few dev_dbg() messages are converted to tracepoints and we can finally ignore dev_dbg() messages during debug sessions. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 22b4797383cd0..de5e01f41bc21 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -272,7 +272,8 @@ static int dwc3_event_buffers_setup(struct dwc3 *dwc) for (n = 0; n < dwc->num_event_buffers; n++) { evt = dwc->ev_buffs[n]; - dev_dbg(dwc->dev, "Event buf %p dma %08llx length %d\n", + dwc3_trace(trace_dwc3_core, + "Event buf %p dma %08llx length %d\n", evt->buf, (unsigned long long) evt->dma, evt->length); @@ -608,12 +609,13 @@ static int dwc3_core_init(struct dwc3 *dwc) reg |= DWC3_GCTL_GBLHIBERNATIONEN; break; default: - dev_dbg(dwc->dev, "No power optimization available\n"); + dwc3_trace(trace_dwc3_core, "No power optimization available\n"); } /* check if current dwc3 is on simulation board */ if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) { - dev_dbg(dwc->dev, "it is on FPGA board\n"); + dwc3_trace(trace_dwc3_core, + "running on FPGA platform\n"); dwc->is_fpga = true; } -- GitLab From acc38c4970caac17cd81dc941226ed17fe505d73 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 16 Nov 2015 16:08:09 -0600 Subject: [PATCH 1308/2855] usb: dwc3: ep0: purge dev_dbg() calls The last few dev_dbg() messages are converted to tracepoints and we can finally ignore dev_dbg() messages during debug sessions. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 5320e939e0902..3ea2bda0bd4d1 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -971,7 +971,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, ret = usb_gadget_map_request(&dwc->gadget, &req->request, dep->number); if (ret) { - dev_dbg(dwc->dev, "failed to map request\n"); + dwc3_trace(trace_dwc3_ep0, "failed to map request\n"); return; } @@ -999,7 +999,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, ret = usb_gadget_map_request(&dwc->gadget, &req->request, dep->number); if (ret) { - dev_dbg(dwc->dev, "failed to map request\n"); + dwc3_trace(trace_dwc3_ep0, "failed to map request\n"); return; } -- GitLab From ac7bdcc1b3ad042d21bc65e57503d7b41fc69f05 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 16 Nov 2015 16:13:57 -0600 Subject: [PATCH 1309/2855] usb: dwc3: gadget: simplify next_request() return check In dwc3_cleanup_done_reqs() we expect that all iterations of our while (1) loop will find a valid struct dwc3_request *. In case we don't, we're dumping a WARN_ON_ONCE() splat so that people report the failure. This patch is a simple cleanup converting: if (!req) { WARN_ON_ONCE(1); return 1; } to: if (WARN_ON_ONCE(!req)) return 1; which is a little easier to read. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index ca06ab8e2e4e5..3d131b7aae597 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1885,10 +1885,9 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, do { req = next_request(&dep->req_queued); - if (!req) { - WARN_ON_ONCE(1); + if (WARN_ON_ONCE(!req)) return 1; - } + i = 0; do { slot = req->start_slot + i; -- GitLab From b5d335e5ea6a60f5254c1f3d5fddd47f4531bccf Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 16 Nov 2015 16:20:34 -0600 Subject: [PATCH 1310/2855] usb: dwc3: ep0: fix setup_packet_pending initialization It just ocurred to me that dwc3 already gives a really hint of when a setup packet is pending and that's the SETUP_PENDING TRB Status for EP0 IRQs. Fix setup_packet_pending initialization based on that. While at that, also make sure the comment in gadget.c matches what code is doing. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 8 +++++--- drivers/usb/dwc3/gadget.c | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 3ea2bda0bd4d1..3a9354abcb68b 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -817,6 +817,8 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, status = DWC3_TRB_SIZE_TRBSTS(trb->size); if (status == DWC3_TRBSTS_SETUP_PENDING) { + dwc->setup_packet_pending = true; + dwc3_trace(trace_dwc3_ep0, "Setup Pending received"); if (r) @@ -916,8 +918,10 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc, } status = DWC3_TRB_SIZE_TRBSTS(trb->size); - if (status == DWC3_TRBSTS_SETUP_PENDING) + if (status == DWC3_TRBSTS_SETUP_PENDING) { + dwc->setup_packet_pending = true; dwc3_trace(trace_dwc3_ep0, "Setup Pending received"); + } dwc->ep0state = EP0_SETUP_PHASE; dwc3_ep0_out_start(dwc); @@ -1063,8 +1067,6 @@ static void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep) static void dwc3_ep0_xfernotready(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { - dwc->setup_packet_pending = true; - switch (event->status) { case DEPEVT_STATUS_CONTROL_DATA: dwc3_trace(trace_dwc3_ep0, "Control Data"); diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 3d131b7aae597..e4203b79908a4 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2230,8 +2230,8 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) * * Our suggested workaround is to follow the Disconnect * Event steps here, instead, based on a setup_packet_pending - * flag. Such flag gets set whenever we have a XferNotReady - * event on EP0 and gets cleared on XferComplete for the + * flag. Such flag gets set whenever we have a SETUP_PENDING + * status for EP0 TRBs and gets cleared on XferComplete for the * same endpoint. * * Refers to: -- GitLab From 16adc674d0d68a50dfc725574738d7ae11cf5d7e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 18 Nov 2015 13:15:20 -0600 Subject: [PATCH 1311/2855] usb: dwc3: add generic OF glue layer For simple platforms which merely enable some clocks and populate its children, we can use this generic glue layer to avoid boilerplate code duplication. For now this supports Qcom and Xilinx, but if we find a way to add generic handling of regulators and optional PHYs, we can absorb exynos as well. Tested-by: Subbaraya Sundeep Bhatta Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/Kconfig | 9 ++ drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 178 ++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+) create mode 100644 drivers/usb/dwc3/dwc3-of-simple.c diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 5a42c45904029..070e704829e5e 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -87,6 +87,15 @@ config USB_DWC3_KEYSTONE Support of USB2/3 functionality in TI Keystone2 platforms. Say 'Y' or 'M' here if you have one such device +config USB_DWC3_OF_SIMPLE + tristate "Generic OF Simple Glue Layer" + depends on OF && COMMON_CLK + default USB_DWC3 + help + Support USB2/3 functionality in simple SoC integrations. + Currently supports Xilinx and Qualcomm DWC USB3 IP. + Say 'Y' or 'M' if you have one such device. + config USB_DWC3_ST tristate "STMicroelectronics Platforms" depends on ARCH_STI && OF diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index acc951d46c278..6491f9b474d47 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -37,5 +37,6 @@ obj-$(CONFIG_USB_DWC3_OMAP) += dwc3-omap.o obj-$(CONFIG_USB_DWC3_EXYNOS) += dwc3-exynos.o obj-$(CONFIG_USB_DWC3_PCI) += dwc3-pci.o obj-$(CONFIG_USB_DWC3_KEYSTONE) += dwc3-keystone.o +obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c new file mode 100644 index 0000000000000..60c4c5a443072 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -0,0 +1,178 @@ +/** + * dwc3-of-simple.c - OF glue layer for simple integrations + * + * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com + * + * Author: Felipe Balbi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 of + * the License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * This is a combination of the old dwc3-qcom.c by Ivan T. Ivanov + * and the original patch adding support for Xilinx' SoC + * by Subbaraya Sundeep Bhatta + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct dwc3_of_simple { + struct device *dev; + struct clk **clks; + int num_clocks; +}; + +static int dwc3_of_simple_probe(struct platform_device *pdev) +{ + struct dwc3_of_simple *simple; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + + int ret; + int i; + + simple = devm_kzalloc(dev, sizeof(*simple), GFP_KERNEL); + if (!simple) + return -ENOMEM; + + ret = of_clk_get_parent_count(np); + if (ret < 0) + return ret; + + simple->num_clocks = ret; + + simple->clks = devm_kcalloc(dev, simple->num_clocks, + sizeof(struct clk *), GFP_KERNEL); + if (!simple->clks) + return -ENOMEM; + + simple->dev = dev; + + for (i = 0; i < simple->num_clocks; i++) { + struct clk *clk; + + clk = of_clk_get(np, i); + if (IS_ERR(clk)) { + while (--i >= 0) + clk_put(simple->clks[i]); + return PTR_ERR(clk); + } + + ret = clk_prepare_enable(clk); + if (ret < 0) { + while (--i >= 0) { + clk_disable_unprepare(simple->clks[i]); + clk_put(simple->clks[i]); + } + clk_put(clk); + + return ret; + } + + simple->clks[i] = clk; + } + + ret = of_platform_populate(np, NULL, NULL, dev); + if (ret) { + for (i = 0; i < simple->num_clocks; i++) { + clk_disable_unprepare(simple->clks[i]); + clk_put(simple->clks[i]); + } + + return ret; + } + + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); + + return 0; +} + +static int dwc3_of_simple_remove(struct platform_device *pdev) +{ + struct dwc3_of_simple *simple = platform_get_drvdata(pdev); + struct device *dev = &pdev->dev; + int i; + + for (i = 0; i < simple->num_clocks; i++) { + clk_unprepare(simple->clks[i]); + clk_put(simple->clks[i]); + } + + of_platform_depopulate(dev); + + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); + + return 0; +} + +static int dwc3_of_simple_runtime_suspend(struct device *dev) +{ + struct dwc3_of_simple *simple = dev_get_drvdata(dev); + int i; + + for (i = 0; i < simple->num_clocks; i++) + clk_disable(simple->clks[i]); + + return 0; +} + +static int dwc3_of_simple_runtime_resume(struct device *dev) +{ + struct dwc3_of_simple *simple = dev_get_drvdata(dev); + int ret; + int i; + + for (i = 0; i < simple->num_clocks; i++) { + ret = clk_enable(simple->clks[i]); + if (ret < 0) { + while (--i >= 0) + clk_disable(simple->clks[i]); + return ret; + } + } + + return 0; +} + +static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = { + SET_RUNTIME_PM_OPS(dwc3_of_simple_runtime_suspend, + dwc3_of_simple_runtime_resume, NULL) +}; + +static const struct of_device_id of_dwc3_simple_match[] = { + { .compatible = "qcom,dwc3" }, + { .compatible = "xlnx,zynqmp-dwc3" }, + { /* Sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_dwc3_simple_match); + +static struct platform_driver dwc3_of_simple_driver = { + .probe = dwc3_of_simple_probe, + .remove = dwc3_of_simple_remove, + .driver = { + .name = "dwc3-of-simple", + .of_match_table = of_dwc3_simple_match, + }, +}; + +module_platform_driver(dwc3_of_simple_driver); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("DesignWare USB3 OF Simple Glue Layer"); +MODULE_AUTHOR("Felipe Balbi "); -- GitLab From f8764406a8a9a6443048f9c5c8e512504684ed1a Mon Sep 17 00:00:00 2001 From: Subbaraya Sundeep Bhatta Date: Wed, 18 Nov 2015 18:20:31 +0530 Subject: [PATCH 1312/2855] usb: doc: dwc3-xilinx: Add devicetree bindings This patch adds binding doc for Xilinx DWC3 glue driver. Acked-by: Rob Herring Signed-off-by: Subbaraya Sundeep Bhatta Signed-off-by: Felipe Balbi --- .../devicetree/bindings/usb/dwc3-xilinx.txt | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/dwc3-xilinx.txt diff --git a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt new file mode 100644 index 0000000000000..30361b32a4602 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt @@ -0,0 +1,33 @@ +Xilinx SuperSpeed DWC3 USB SoC controller + +Required properties: +- compatible: Should contain "xlnx,zynqmp-dwc3" +- clocks: A list of phandles for the clocks listed in clock-names +- clock-names: Should contain the following: + "bus_clk" Master/Core clock, have to be >= 125 MHz for SS + operation and >= 60MHz for HS operation + + "ref_clk" Clock source to core during PHY power down + +Required child node: +A child node must exist to represent the core DWC3 IP block. The name of +the node is not important. The content of the node is defined in dwc3.txt. + +Example device node: + + usb@0 { + #address-cells = <0x2>; + #size-cells = <0x1>; + status = "okay"; + compatible = "xlnx,zynqmp-dwc3"; + clock-names = "bus_clk" "ref_clk"; + clocks = <&clk125>, <&clk125>; + ranges; + + dwc3@fe200000 { + compatible = "snps,dwc3"; + reg = <0x0 0xfe200000 0x40000>; + interrupts = <0x0 0x41 0x4>; + dr_mode = "host"; + }; + }; -- GitLab From b084662776be8b07ab9114ff1a16a4e9bf907d35 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 19 Nov 2015 12:15:43 -0600 Subject: [PATCH 1313/2855] usb: dwc3: remove dwc3-qcom in favor of dwc3-of-simple Now that we have a generic dwc3-of-simple.c, we can use that instead of maintaining dwc3-qcom.c which is extremely similar. Cc: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/Kconfig | 8 --- drivers/usb/dwc3/Makefile | 1 - drivers/usb/dwc3/dwc3-qcom.c | 130 ----------------------------------- 3 files changed, 139 deletions(-) delete mode 100644 drivers/usb/dwc3/dwc3-qcom.c diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 070e704829e5e..a64ce1c94d6d3 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -105,12 +105,4 @@ config USB_DWC3_ST inside (i.e. STiH407). Say 'Y' or 'M' if you have one such device. -config USB_DWC3_QCOM - tristate "Qualcomm Platforms" - depends on ARCH_QCOM || COMPILE_TEST - default USB_DWC3 - help - Recent Qualcomm SoCs ship with one DesignWare Core USB3 IP inside, - say 'Y' or 'M' if you have one such device. - endif diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index 6491f9b474d47..22420e17d68bc 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -38,5 +38,4 @@ obj-$(CONFIG_USB_DWC3_EXYNOS) += dwc3-exynos.o obj-$(CONFIG_USB_DWC3_PCI) += dwc3-pci.o obj-$(CONFIG_USB_DWC3_KEYSTONE) += dwc3-keystone.o obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o -obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c deleted file mode 100644 index 088026048f49f..0000000000000 --- a/drivers/usb/dwc3/dwc3-qcom.c +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include - -struct dwc3_qcom { - struct device *dev; - - struct clk *core_clk; - struct clk *iface_clk; - struct clk *sleep_clk; -}; - -static int dwc3_qcom_probe(struct platform_device *pdev) -{ - struct device_node *node = pdev->dev.of_node; - struct dwc3_qcom *qdwc; - int ret; - - qdwc = devm_kzalloc(&pdev->dev, sizeof(*qdwc), GFP_KERNEL); - if (!qdwc) - return -ENOMEM; - - platform_set_drvdata(pdev, qdwc); - - qdwc->dev = &pdev->dev; - - qdwc->core_clk = devm_clk_get(qdwc->dev, "core"); - if (IS_ERR(qdwc->core_clk)) { - dev_err(qdwc->dev, "failed to get core clock\n"); - return PTR_ERR(qdwc->core_clk); - } - - qdwc->iface_clk = devm_clk_get(qdwc->dev, "iface"); - if (IS_ERR(qdwc->iface_clk)) { - dev_info(qdwc->dev, "failed to get optional iface clock\n"); - qdwc->iface_clk = NULL; - } - - qdwc->sleep_clk = devm_clk_get(qdwc->dev, "sleep"); - if (IS_ERR(qdwc->sleep_clk)) { - dev_info(qdwc->dev, "failed to get optional sleep clock\n"); - qdwc->sleep_clk = NULL; - } - - ret = clk_prepare_enable(qdwc->core_clk); - if (ret) { - dev_err(qdwc->dev, "failed to enable core clock\n"); - goto err_core; - } - - ret = clk_prepare_enable(qdwc->iface_clk); - if (ret) { - dev_err(qdwc->dev, "failed to enable optional iface clock\n"); - goto err_iface; - } - - ret = clk_prepare_enable(qdwc->sleep_clk); - if (ret) { - dev_err(qdwc->dev, "failed to enable optional sleep clock\n"); - goto err_sleep; - } - - ret = of_platform_populate(node, NULL, NULL, qdwc->dev); - if (ret) { - dev_err(qdwc->dev, "failed to register core - %d\n", ret); - goto err_clks; - } - - return 0; - -err_clks: - clk_disable_unprepare(qdwc->sleep_clk); -err_sleep: - clk_disable_unprepare(qdwc->iface_clk); -err_iface: - clk_disable_unprepare(qdwc->core_clk); -err_core: - return ret; -} - -static int dwc3_qcom_remove(struct platform_device *pdev) -{ - struct dwc3_qcom *qdwc = platform_get_drvdata(pdev); - - of_platform_depopulate(&pdev->dev); - - clk_disable_unprepare(qdwc->sleep_clk); - clk_disable_unprepare(qdwc->iface_clk); - clk_disable_unprepare(qdwc->core_clk); - - return 0; -} - -static const struct of_device_id of_dwc3_match[] = { - { .compatible = "qcom,dwc3" }, - { /* Sentinel */ } -}; -MODULE_DEVICE_TABLE(of, of_dwc3_match); - -static struct platform_driver dwc3_qcom_driver = { - .probe = dwc3_qcom_probe, - .remove = dwc3_qcom_remove, - .driver = { - .name = "qcom-dwc3", - .of_match_table = of_dwc3_match, - }, -}; - -module_platform_driver(dwc3_qcom_driver); - -MODULE_ALIAS("platform:qcom-dwc3"); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("DesignWare USB3 QCOM Glue Layer"); -MODULE_AUTHOR("Ivan T. Ivanov "); -- GitLab From 0d6c3d96678d11505f4923759af1e6c5fd260ff8 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 19 Nov 2015 15:02:16 +0800 Subject: [PATCH 1314/2855] usb: gadget: f_sourcesink: add queue depth Add queue depth for both iso and bulk transfer, with more queues, we can do performance and stress test using sourcesink, and update g_zero accordingly. Reviewed-by: Krzysztof Opasiak Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_sourcesink.c | 142 ++++++++++++++++----- drivers/usb/gadget/function/g_zero.h | 6 + drivers/usb/gadget/legacy/zero.c | 12 ++ 3 files changed, 127 insertions(+), 33 deletions(-) diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index 9f3ced62d9162..9df4aa1ea011d 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -34,13 +34,6 @@ * plus two that support control-OUT tests. If the optional "autoresume" * mode is enabled, it provides good functional coverage for the "USBCV" * test harness from USB-IF. - * - * Note that because this doesn't queue more than one request at a time, - * some other function must be used to test queueing logic. The network - * link (g_ether) is the best overall option for that, since its TX and RX - * queues are relatively independent, will receive a range of packet sizes, - * and can often be made to run out completely. Those issues are important - * when stress testing peripheral controller drivers. */ struct f_sourcesink { struct usb_function function; @@ -57,6 +50,8 @@ struct f_sourcesink { unsigned isoc_mult; unsigned isoc_maxburst; unsigned buflen; + unsigned bulk_qlen; + unsigned iso_qlen; }; static inline struct f_sourcesink *func_to_ss(struct usb_function *f) @@ -595,31 +590,33 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in, { struct usb_ep *ep; struct usb_request *req; - int i, size, status; - - for (i = 0; i < 8; i++) { - if (is_iso) { - switch (speed) { - case USB_SPEED_SUPER: - size = ss->isoc_maxpacket * - (ss->isoc_mult + 1) * - (ss->isoc_maxburst + 1); - break; - case USB_SPEED_HIGH: - size = ss->isoc_maxpacket * (ss->isoc_mult + 1); - break; - default: - size = ss->isoc_maxpacket > 1023 ? - 1023 : ss->isoc_maxpacket; - break; - } - ep = is_in ? ss->iso_in_ep : ss->iso_out_ep; - req = ss_alloc_ep_req(ep, size); - } else { - ep = is_in ? ss->in_ep : ss->out_ep; - req = ss_alloc_ep_req(ep, 0); + int i, size, qlen, status = 0; + + if (is_iso) { + switch (speed) { + case USB_SPEED_SUPER: + size = ss->isoc_maxpacket * + (ss->isoc_mult + 1) * + (ss->isoc_maxburst + 1); + break; + case USB_SPEED_HIGH: + size = ss->isoc_maxpacket * (ss->isoc_mult + 1); + break; + default: + size = ss->isoc_maxpacket > 1023 ? + 1023 : ss->isoc_maxpacket; + break; } + ep = is_in ? ss->iso_in_ep : ss->iso_out_ep; + qlen = ss->iso_qlen; + } else { + ep = is_in ? ss->in_ep : ss->out_ep; + qlen = ss->bulk_qlen; + size = 0; + } + for (i = 0; i < qlen; i++) { + req = ss_alloc_ep_req(ep, size); if (!req) return -ENOMEM; @@ -639,9 +636,6 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in, ep->name, status); free_ep_req(ep, req); } - - if (!is_iso) - break; } return status; @@ -869,6 +863,8 @@ static struct usb_function *source_sink_alloc_func( ss->isoc_mult = ss_opts->isoc_mult; ss->isoc_maxburst = ss_opts->isoc_maxburst; ss->buflen = ss_opts->bulk_buflen; + ss->bulk_qlen = ss_opts->bulk_qlen; + ss->iso_qlen = ss_opts->iso_qlen; ss->function.name = "source/sink"; ss->function.bind = sourcesink_bind; @@ -1153,6 +1149,82 @@ end: CONFIGFS_ATTR(f_ss_opts_, bulk_buflen); +static ssize_t f_ss_opts_bulk_qlen_show(struct config_item *item, char *page) +{ + struct f_ss_opts *opts = to_f_ss_opts(item); + int result; + + mutex_lock(&opts->lock); + result = sprintf(page, "%u\n", opts->bulk_qlen); + mutex_unlock(&opts->lock); + + return result; +} + +static ssize_t f_ss_opts_bulk_qlen_store(struct config_item *item, + const char *page, size_t len) +{ + struct f_ss_opts *opts = to_f_ss_opts(item); + int ret; + u32 num; + + mutex_lock(&opts->lock); + if (opts->refcnt) { + ret = -EBUSY; + goto end; + } + + ret = kstrtou32(page, 0, &num); + if (ret) + goto end; + + opts->bulk_qlen = num; + ret = len; +end: + mutex_unlock(&opts->lock); + return ret; +} + +CONFIGFS_ATTR(f_ss_opts_, bulk_qlen); + +static ssize_t f_ss_opts_iso_qlen_show(struct config_item *item, char *page) +{ + struct f_ss_opts *opts = to_f_ss_opts(item); + int result; + + mutex_lock(&opts->lock); + result = sprintf(page, "%u\n", opts->iso_qlen); + mutex_unlock(&opts->lock); + + return result; +} + +static ssize_t f_ss_opts_iso_qlen_store(struct config_item *item, + const char *page, size_t len) +{ + struct f_ss_opts *opts = to_f_ss_opts(item); + int ret; + u32 num; + + mutex_lock(&opts->lock); + if (opts->refcnt) { + ret = -EBUSY; + goto end; + } + + ret = kstrtou32(page, 0, &num); + if (ret) + goto end; + + opts->iso_qlen = num; + ret = len; +end: + mutex_unlock(&opts->lock); + return ret; +} + +CONFIGFS_ATTR(f_ss_opts_, iso_qlen); + static struct configfs_attribute *ss_attrs[] = { &f_ss_opts_attr_pattern, &f_ss_opts_attr_isoc_interval, @@ -1160,6 +1232,8 @@ static struct configfs_attribute *ss_attrs[] = { &f_ss_opts_attr_isoc_mult, &f_ss_opts_attr_isoc_maxburst, &f_ss_opts_attr_bulk_buflen, + &f_ss_opts_attr_bulk_qlen, + &f_ss_opts_attr_iso_qlen, NULL, }; @@ -1189,6 +1263,8 @@ static struct usb_function_instance *source_sink_alloc_inst(void) ss_opts->isoc_interval = GZERO_ISOC_INTERVAL; ss_opts->isoc_maxpacket = GZERO_ISOC_MAXPACKET; ss_opts->bulk_buflen = GZERO_BULK_BUFLEN; + ss_opts->bulk_qlen = GZERO_SS_BULK_QLEN; + ss_opts->iso_qlen = GZERO_SS_ISO_QLEN; config_group_init_type_name(&ss_opts->func_inst.group, "", &ss_func_type); diff --git a/drivers/usb/gadget/function/g_zero.h b/drivers/usb/gadget/function/g_zero.h index 15f180904f8a3..4f61d95bf1772 100644 --- a/drivers/usb/gadget/function/g_zero.h +++ b/drivers/usb/gadget/function/g_zero.h @@ -10,6 +10,8 @@ #define GZERO_QLEN 32 #define GZERO_ISOC_INTERVAL 4 #define GZERO_ISOC_MAXPACKET 1024 +#define GZERO_SS_BULK_QLEN 1 +#define GZERO_SS_ISO_QLEN 8 struct usb_zero_options { unsigned pattern; @@ -19,6 +21,8 @@ struct usb_zero_options { unsigned isoc_maxburst; unsigned bulk_buflen; unsigned qlen; + unsigned ss_bulk_qlen; + unsigned ss_iso_qlen; }; struct f_ss_opts { @@ -29,6 +33,8 @@ struct f_ss_opts { unsigned isoc_mult; unsigned isoc_maxburst; unsigned bulk_buflen; + unsigned bulk_qlen; + unsigned iso_qlen; /* * Read/write access to configfs attributes is handled by configfs. diff --git a/drivers/usb/gadget/legacy/zero.c b/drivers/usb/gadget/legacy/zero.c index 37a410056fed2..0ccdcd9c64a59 100644 --- a/drivers/usb/gadget/legacy/zero.c +++ b/drivers/usb/gadget/legacy/zero.c @@ -68,6 +68,8 @@ static struct usb_zero_options gzero_options = { .isoc_maxpacket = GZERO_ISOC_MAXPACKET, .bulk_buflen = GZERO_BULK_BUFLEN, .qlen = GZERO_QLEN, + .ss_bulk_qlen = GZERO_SS_BULK_QLEN, + .ss_iso_qlen = GZERO_SS_ISO_QLEN, }; /*-------------------------------------------------------------------------*/ @@ -255,6 +257,14 @@ static struct usb_function_instance *func_inst_lb; module_param_named(qlen, gzero_options.qlen, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(qlen, "depth of loopback queue"); +module_param_named(ss_bulk_qlen, gzero_options.ss_bulk_qlen, uint, + S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(bulk_qlen, "depth of sourcesink queue for bulk transfer"); + +module_param_named(ss_iso_qlen, gzero_options.ss_iso_qlen, uint, + S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(iso_qlen, "depth of sourcesink queue for iso transfer"); + static int zero_bind(struct usb_composite_dev *cdev) { struct f_ss_opts *ss_opts; @@ -285,6 +295,8 @@ static int zero_bind(struct usb_composite_dev *cdev) ss_opts->isoc_mult = gzero_options.isoc_mult; ss_opts->isoc_maxburst = gzero_options.isoc_maxburst; ss_opts->bulk_buflen = gzero_options.bulk_buflen; + ss_opts->bulk_qlen = gzero_options.ss_bulk_qlen; + ss_opts->iso_qlen = gzero_options.ss_iso_qlen; func_ss = usb_get_function(func_inst_ss); if (IS_ERR(func_ss)) { -- GitLab From df001894e3bfe02d06b83924623dd88babfe5dbd Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 19 Nov 2015 15:02:17 +0800 Subject: [PATCH 1315/2855] Documentation: usb: gadget-testing: add description for depth of queue Add both bulk and iso depth of queue for sourcesink. Reviewed-by: Krzysztof Opasiak Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- Documentation/usb/gadget-testing.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/usb/gadget-testing.txt b/Documentation/usb/gadget-testing.txt index b24d3ef89166b..84b3d10365017 100644 --- a/Documentation/usb/gadget-testing.txt +++ b/Documentation/usb/gadget-testing.txt @@ -579,6 +579,8 @@ The SOURCESINK function provides these attributes in its function directory: isoc_mult - 0..2 (hs/ss only) isoc_maxburst - 0..15 (ss only) bulk_buflen - buffer length + bulk_qlen - depth of queue for bulk + iso_qlen - depth of queue for iso Testing the SOURCESINK function ------------------------------- -- GitLab From 4cee4fa5de70606e9eda1f605db1a681137cdaf8 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 18 Nov 2015 17:40:23 +0800 Subject: [PATCH 1316/2855] usb: misc: usbtest: improve the description for error message Now the function of complicated_callback is not only used for iso transfer, improve the error message to reflect it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/misc/usbtest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 637f3f7cfce8b..c1bd1eb548bb9 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -1849,7 +1849,7 @@ static void complicated_callback(struct urb *urb) goto done; default: dev_err(&ctx->dev->intf->dev, - "iso resubmit err %d\n", + "resubmit err %d\n", status); /* FALLTHROUGH */ case -ENODEV: /* disconnected */ @@ -1863,7 +1863,7 @@ static void complicated_callback(struct urb *urb) if (ctx->pending == 0) { if (ctx->errors) dev_err(&ctx->dev->intf->dev, - "iso test, %lu errors out of %lu\n", + "during the test, %lu errors out of %lu\n", ctx->errors, ctx->packet_count); complete(&ctx->done); } -- GitLab From 3ac38d260fa5dc8ec26ee5b6f5330d726ec00065 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Thu, 5 Nov 2015 09:41:37 +0100 Subject: [PATCH 1317/2855] usb: dwc2: host: ensure filling of isoc desc is correctly done Increment qtd->isoc_frame_index_last before testing it, else below check will never be true and IOC (Interrupt On Complete) bit for last frame will never be set in descriptor status. /* Set IOC for each descriptor corresponding to last frame of URB */ if (qtd->isoc_frame_index_last == qtd->urb->packet_count) dma_desc->status |= HOST_DMA_IOC; Acked-by: John Youn Signed-off-by: Gregory Herrero Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd_ddma.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c index 78993aba9335c..4b0be93dac6f7 100644 --- a/drivers/usb/dwc2/hcd_ddma.c +++ b/drivers/usb/dwc2/hcd_ddma.c @@ -524,14 +524,15 @@ static void dwc2_fill_host_isoc_dma_desc(struct dwc2_hsotg *hsotg, dma_desc->status = qh->n_bytes[idx] << HOST_DMA_ISOC_NBYTES_SHIFT & HOST_DMA_ISOC_NBYTES_MASK; + qh->ntd++; + qtd->isoc_frame_index_last++; + #ifdef ISOC_URB_GIVEBACK_ASAP /* Set IOC for each descriptor corresponding to last frame of URB */ if (qtd->isoc_frame_index_last == qtd->urb->packet_count) dma_desc->status |= HOST_DMA_IOC; #endif - qh->ntd++; - qtd->isoc_frame_index_last++; } static void dwc2_init_isoc_dma_desc(struct dwc2_hsotg *hsotg, -- GitLab From dde4c1bf5df0f852e497e5644d3578885b969fdb Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Thu, 5 Nov 2015 09:41:38 +0100 Subject: [PATCH 1318/2855] usb: dwc2: host: set active bit in isochronous descriptors Active bit must be enabled in all scheduled descriptors. Else transfer never start. Remove previous code which was not correctly configuring descriptors. Active bit was set before calling dwc2_fill_host_isoc_dma_desc() which is erasing dma_desc->status. Acked-by: John Youn Signed-off-by: Gregory Herrero Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd_ddma.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c index 4b0be93dac6f7..98d862726b5ab 100644 --- a/drivers/usb/dwc2/hcd_ddma.c +++ b/drivers/usb/dwc2/hcd_ddma.c @@ -524,6 +524,9 @@ static void dwc2_fill_host_isoc_dma_desc(struct dwc2_hsotg *hsotg, dma_desc->status = qh->n_bytes[idx] << HOST_DMA_ISOC_NBYTES_SHIFT & HOST_DMA_ISOC_NBYTES_MASK; + /* Set active bit */ + dma_desc->status |= HOST_DMA_A; + qh->ntd++; qtd->isoc_frame_index_last++; @@ -559,8 +562,6 @@ static void dwc2_init_isoc_dma_desc(struct dwc2_hsotg *hsotg, list_for_each_entry(qtd, &qh->qtd_list, qtd_list_entry) { while (qh->ntd < ntd_max && qtd->isoc_frame_index_last < qtd->urb->packet_count) { - if (n_desc > 1) - qh->desc_list[n_desc - 1].status |= HOST_DMA_A; dwc2_fill_host_isoc_dma_desc(hsotg, qtd, qh, max_xfer_size, idx); idx = dwc2_desclist_idx_inc(idx, inc, qh->dev_speed); @@ -606,12 +607,6 @@ static void dwc2_init_isoc_dma_desc(struct dwc2_hsotg *hsotg, qh->desc_list[idx].status |= HOST_DMA_IOC; #endif - - if (n_desc) { - qh->desc_list[n_desc - 1].status |= HOST_DMA_A; - if (n_desc > 1) - qh->desc_list[0].status |= HOST_DMA_A; - } } static void dwc2_fill_host_dma_desc(struct dwc2_hsotg *hsotg, -- GitLab From c503b38153852d88774b54ae17f7723f68c6dc33 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Thu, 5 Nov 2015 09:41:39 +0100 Subject: [PATCH 1319/2855] usb: dwc2: host: rework isochronous halt path When a channel is halted because of urb dequeue during transfer completion, no other qtds must be scheduled until halt is done. Moreover, all in progress qtds must be given back. Acked-by: John Youn Signed-off-by: Gregory Herrero Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd_ddma.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c index 98d862726b5ab..5f72656373344 100644 --- a/drivers/usb/dwc2/hcd_ddma.c +++ b/drivers/usb/dwc2/hcd_ddma.c @@ -1161,6 +1161,21 @@ void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg, /* Release the channel if halted or session completed */ if (halt_status != DWC2_HC_XFER_COMPLETE || list_empty(&qh->qtd_list)) { + struct dwc2_qtd *qtd, *qtd_tmp; + + /* + * Kill all remainings QTDs since channel has been + * halted. + */ + list_for_each_entry_safe(qtd, qtd_tmp, + &qh->qtd_list, + qtd_list_entry) { + dwc2_host_complete(hsotg, qtd, + -ECONNRESET); + dwc2_hcd_qtd_unlink_and_free(hsotg, + qtd, qh); + } + /* Halt the channel if session completed */ if (halt_status == DWC2_HC_XFER_COMPLETE) dwc2_hc_halt(hsotg, chan, halt_status); @@ -1170,7 +1185,12 @@ void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg, /* Keep in assigned schedule to continue transfer */ list_move(&qh->qh_list_entry, &hsotg->periodic_sched_assigned); - continue_isoc_xfer = 1; + /* + * If channel has been halted during giveback of urb + * then prevent any new scheduling. + */ + if (!chan->halt_status) + continue_isoc_xfer = 1; } /* * Todo: Consider the case when period exceeds FrameList size. -- GitLab From 26a19ea699060fded98257e65b0ae5272a5ea1da Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Thu, 5 Nov 2015 09:41:40 +0100 Subject: [PATCH 1320/2855] usb: dwc2: host: fix use of qtd after free in desc dma mode When completing non isoc xfer, dwc2_complete_non_isoc_xfer_ddma() is relying on qtd->n_desc to process the corresponding number of descriptors. During the processing of these descriptors, qtd could be unlinked and freed if xfer is done and urb is no more in progress. In this case, dwc2_complete_non_isoc_xfer_ddma() will read again qtd->n_desc whereas qtd has been freed. This will lead to unpredictable results since qtd->n_desc is no more valid value. To avoid this error, return a result != 0 in dwc2_process_non_isoc_desc(), so that dwc2_complete_non_isoc_xfer_ddma() stops desc processing. This has been seen with Slub debug enabled. Acked-by: John Youn Signed-off-by: Gregory Herrero Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd_ddma.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c index 5f72656373344..4801e693353a4 100644 --- a/drivers/usb/dwc2/hcd_ddma.c +++ b/drivers/usb/dwc2/hcd_ddma.c @@ -1033,7 +1033,10 @@ static int dwc2_process_non_isoc_desc(struct dwc2_hsotg *hsotg, failed = dwc2_update_non_isoc_urb_state_ddma(hsotg, chan, qtd, dma_desc, halt_status, n_bytes, xfer_done); - if (failed || (*xfer_done && urb->status != -EINPROGRESS)) { + if (*xfer_done && urb->status != -EINPROGRESS) + failed = 1; + + if (failed) { dwc2_host_complete(hsotg, qtd, urb->status); dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); dev_vdbg(hsotg->dev, "failed=%1x xfer_done=%1x status=%08x\n", -- GitLab From 2b046bc5aaefd4aba7195e6a73afe14f7f786692 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Thu, 5 Nov 2015 09:41:41 +0100 Subject: [PATCH 1321/2855] usb: dwc2: host: spinlock release channel Prevent dwc2 driver from accessing channel while it frees it. Acked-by: John Youn Signed-off-by: Gregory Herrero Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd_ddma.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c index 4801e693353a4..a76a58c35feab 100644 --- a/drivers/usb/dwc2/hcd_ddma.c +++ b/drivers/usb/dwc2/hcd_ddma.c @@ -360,6 +360,8 @@ err0: */ void dwc2_hcd_qh_free_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { + unsigned long flags; + dwc2_desc_list_free(hsotg, qh); /* @@ -369,8 +371,10 @@ void dwc2_hcd_qh_free_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) * when it comes here from endpoint disable routine * channel remains assigned. */ + spin_lock_irqsave(&hsotg->lock, flags); if (qh->channel) dwc2_release_channel_ddma(hsotg, qh); + spin_unlock_irqrestore(&hsotg->lock, flags); if ((qh->ep_type == USB_ENDPOINT_XFER_ISOC || qh->ep_type == USB_ENDPOINT_XFER_INT) && -- GitLab From b9392d9920fdce50abbe4af758cd1a24b922c81c Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Thu, 5 Nov 2015 09:41:42 +0100 Subject: [PATCH 1322/2855] usb: dwc2: host: add function to compare frame index This function allow comparing frame index used for descriptor list which has 64 entries. Acked-by: John Youn Signed-off-by: Gregory Herrero Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h index f105bada2fd13..a19837f655c97 100644 --- a/drivers/usb/dwc2/hcd.h +++ b/drivers/usb/dwc2/hcd.h @@ -534,6 +534,19 @@ static inline bool dbg_perio(void) { return false; } /* Packet size for any kind of endpoint descriptor */ #define dwc2_max_packet(wmaxpacketsize) ((wmaxpacketsize) & 0x07ff) +/* + * Returns true if frame1 index is greater than frame2 index. The comparison + * is done modulo FRLISTEN_64_SIZE. This accounts for the rollover of the + * frame number when the max index frame number is reached. + */ +static inline bool dwc2_frame_idx_num_gt(u16 fr_idx1, u16 fr_idx2) +{ + u16 diff = fr_idx1 - fr_idx2; + u16 sign = diff & (FRLISTEN_64_SIZE >> 1); + + return diff && !sign; +} + /* * Returns true if frame1 is less than or equal to frame2. The comparison is * done modulo HFNUM_MAX_FRNUM. This accounts for the rollover of the -- GitLab From c17b337c1ea4c681595531912585a94f4bd7f8e7 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Thu, 5 Nov 2015 09:41:43 +0100 Subject: [PATCH 1323/2855] usb: dwc2: host: program descriptor for next frame Isochronous descriptor is currently programmed for the frame after the last descriptor was programmed. If the last descriptor frame underrun, then current descriptor must take this into account and must be programmed on the current frame + 1. This overrun usually happens when system is loaded and dwc2 can't init descriptor list in time. Acked-by: John Youn Signed-off-by: Gregory Herrero Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd.h | 2 ++ drivers/usb/dwc2/hcd_ddma.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h index a19837f655c97..2e5e9d9a00161 100644 --- a/drivers/usb/dwc2/hcd.h +++ b/drivers/usb/dwc2/hcd.h @@ -340,6 +340,8 @@ struct dwc2_qtd { u8 isoc_split_pos; u16 isoc_frame_index; u16 isoc_split_offset; + u16 isoc_td_last; + u16 isoc_td_first; u32 ssplit_out_xfer_count; u8 error_count; u8 n_desc; diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c index a76a58c35feab..9635d8d4bba40 100644 --- a/drivers/usb/dwc2/hcd_ddma.c +++ b/drivers/usb/dwc2/hcd_ddma.c @@ -547,11 +547,32 @@ static void dwc2_init_isoc_dma_desc(struct dwc2_hsotg *hsotg, { struct dwc2_qtd *qtd; u32 max_xfer_size; - u16 idx, inc, n_desc, ntd_max = 0; + u16 idx, inc, n_desc = 0, ntd_max = 0; + u16 cur_idx; + u16 next_idx; idx = qh->td_last; inc = qh->interval; - n_desc = 0; + hsotg->frame_number = dwc2_hcd_get_frame_number(hsotg); + cur_idx = dwc2_frame_list_idx(hsotg->frame_number); + next_idx = dwc2_desclist_idx_inc(qh->td_last, inc, qh->dev_speed); + + /* + * Ensure current frame number didn't overstep last scheduled + * descriptor. If it happens, the only way to recover is to move + * qh->td_last to current frame number + 1. + * So that next isoc descriptor will be scheduled on frame number + 1 + * and not on a past frame. + */ + if (dwc2_frame_idx_num_gt(cur_idx, next_idx) || (cur_idx == next_idx)) { + if (inc < 32) { + dev_vdbg(hsotg->dev, + "current frame number overstep last descriptor\n"); + qh->td_last = dwc2_desclist_idx_inc(cur_idx, inc, + qh->dev_speed); + idx = qh->td_last; + } + } if (qh->interval) { ntd_max = (dwc2_max_desc_num(qh) + qh->interval - 1) / @@ -564,6 +585,12 @@ static void dwc2_init_isoc_dma_desc(struct dwc2_hsotg *hsotg, MAX_ISOC_XFER_SIZE_HS : MAX_ISOC_XFER_SIZE_FS; list_for_each_entry(qtd, &qh->qtd_list, qtd_list_entry) { + if (qtd->in_process && + qtd->isoc_frame_index_last == + qtd->urb->packet_count) + continue; + + qtd->isoc_td_first = idx; while (qh->ntd < ntd_max && qtd->isoc_frame_index_last < qtd->urb->packet_count) { dwc2_fill_host_isoc_dma_desc(hsotg, qtd, qh, @@ -571,6 +598,7 @@ static void dwc2_init_isoc_dma_desc(struct dwc2_hsotg *hsotg, idx = dwc2_desclist_idx_inc(idx, inc, qh->dev_speed); n_desc++; } + qtd->isoc_td_last = idx; qtd->in_process = 1; } -- GitLab From 3f808bdae75eaf464b1b2710894950772a3784f8 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Thu, 5 Nov 2015 09:41:44 +0100 Subject: [PATCH 1324/2855] usb: dwc2: host: always increment available host channel during release When releasing a channel, increment hsotg->available_host_channels even in case a periodic channel is released. Acked-by: John Youn Signed-off-by: Gregory Herrero Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd_ddma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c index 9635d8d4bba40..edccac662d740 100644 --- a/drivers/usb/dwc2/hcd_ddma.c +++ b/drivers/usb/dwc2/hcd_ddma.c @@ -278,6 +278,7 @@ static void dwc2_release_channel_ddma(struct dwc2_hsotg *hsotg, hsotg->non_periodic_channels--; } else { dwc2_update_frame_list(hsotg, qh, 0); + hsotg->available_host_channels++; } /* -- GitLab From 762d3a1a9cd7438a8453e005ee5b2bab3203d9c3 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Thu, 5 Nov 2015 09:41:45 +0100 Subject: [PATCH 1325/2855] usb: dwc2: host: process all completed urbs Process all completed urbs, if more urbs are complete by the time driver processes completion interrupt. Acked-by: John Youn Signed-off-by: Gregory Herrero Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd_ddma.c | 38 +++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c index edccac662d740..f98c7e91f6bcd 100644 --- a/drivers/usb/dwc2/hcd_ddma.c +++ b/drivers/usb/dwc2/hcd_ddma.c @@ -940,17 +940,51 @@ static void dwc2_complete_isoc_xfer_ddma(struct dwc2_hsotg *hsotg, list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list, qtd_list_entry) { if (!qtd->in_process) break; + + /* + * Ensure idx corresponds to descriptor where first urb of this + * qtd was added. In fact, during isoc desc init, dwc2 may skip + * an index if current frame number is already over this index. + */ + if (idx != qtd->isoc_td_first) { + dev_vdbg(hsotg->dev, + "try to complete %d instead of %d\n", + idx, qtd->isoc_td_first); + idx = qtd->isoc_td_first; + } + do { + struct dwc2_qtd *qtd_next; + u16 cur_idx; + rc = dwc2_cmpl_host_isoc_dma_desc(hsotg, chan, qtd, qh, idx); if (rc < 0) return; idx = dwc2_desclist_idx_inc(idx, qh->interval, chan->speed); - if (rc == DWC2_CMPL_STOP) - goto stop_scan; + if (!rc) + continue; + if (rc == DWC2_CMPL_DONE) break; + + /* rc == DWC2_CMPL_STOP */ + + if (qh->interval >= 32) + goto stop_scan; + + qh->td_first = idx; + cur_idx = dwc2_frame_list_idx(hsotg->frame_number); + qtd_next = list_first_entry(&qh->qtd_list, + struct dwc2_qtd, + qtd_list_entry); + if (dwc2_frame_idx_num_gt(cur_idx, + qtd_next->isoc_td_last)) + break; + + goto stop_scan; + } while (idx != qh->td_first); } -- GitLab From 51f141a97a1406bb0b59d490e837a39ccb7c3999 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 18 Nov 2015 14:34:09 +0900 Subject: [PATCH 1326/2855] usb: renesas_usbhs: Modify pipe configuration The current code has info->bufnmb_last to calculate the BUFNMB bits of PIPEBUF register. However, since the bufnmb_last is initialized in the usbhs_pipe_init() only, this driver is possible to set unexpected value to the register if usb_ep_{enable,disable}() are called many times. So, this patch modifies the pipe configuration via struct renesas_usbhs_driver_param to simplify the code. Also this patch changes: - a double buffer configuration - isochronous buffer size from 512 to 1024 Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/common.c | 69 ++++++++--------- drivers/usb/renesas_usbhs/mod_host.c | 11 +-- drivers/usb/renesas_usbhs/pipe.c | 112 +++++++-------------------- drivers/usb/renesas_usbhs/pipe.h | 1 - include/linux/usb/renesas_usbhs.h | 18 ++++- 5 files changed, 82 insertions(+), 129 deletions(-) diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index d82fa36c34650..7ccc2fe4f6ec5 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -302,37 +302,37 @@ static void usbhsc_set_buswait(struct usbhs_priv *priv) */ /* commonly used on old SH-Mobile SoCs */ -static u32 usbhsc_default_pipe_type[] = { - USB_ENDPOINT_XFER_CONTROL, - USB_ENDPOINT_XFER_ISOC, - USB_ENDPOINT_XFER_ISOC, - USB_ENDPOINT_XFER_BULK, - USB_ENDPOINT_XFER_BULK, - USB_ENDPOINT_XFER_BULK, - USB_ENDPOINT_XFER_INT, - USB_ENDPOINT_XFER_INT, - USB_ENDPOINT_XFER_INT, - USB_ENDPOINT_XFER_INT, +static struct renesas_usbhs_driver_pipe_config usbhsc_default_pipe[] = { + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_CONTROL, 64, 0x00, false), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_ISOC, 1024, 0x08, false), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_ISOC, 1024, 0x18, false), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x28, true), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x38, true), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x48, true), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x04, false), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x05, false), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x06, false), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x07, false), }; /* commonly used on newer SH-Mobile and R-Car SoCs */ -static u32 usbhsc_new_pipe_type[] = { - USB_ENDPOINT_XFER_CONTROL, - USB_ENDPOINT_XFER_ISOC, - USB_ENDPOINT_XFER_ISOC, - USB_ENDPOINT_XFER_BULK, - USB_ENDPOINT_XFER_BULK, - USB_ENDPOINT_XFER_BULK, - USB_ENDPOINT_XFER_INT, - USB_ENDPOINT_XFER_INT, - USB_ENDPOINT_XFER_INT, - USB_ENDPOINT_XFER_BULK, - USB_ENDPOINT_XFER_BULK, - USB_ENDPOINT_XFER_BULK, - USB_ENDPOINT_XFER_BULK, - USB_ENDPOINT_XFER_BULK, - USB_ENDPOINT_XFER_BULK, - USB_ENDPOINT_XFER_BULK, +static struct renesas_usbhs_driver_pipe_config usbhsc_new_pipe[] = { + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_CONTROL, 64, 0x00, false), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_ISOC, 1024, 0x08, true), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_ISOC, 1024, 0x28, true), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x48, true), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x58, true), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x68, true), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x04, false), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x05, false), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x06, false), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x78, true), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x88, true), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x98, true), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0xa8, true), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0xb8, true), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0xc8, true), + RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0xd8, true), }; /* @@ -564,10 +564,9 @@ static int usbhs_probe(struct platform_device *pdev) switch (priv->dparam.type) { case USBHS_TYPE_RCAR_GEN2: priv->pfunc = usbhs_rcar2_ops; - if (!priv->dparam.pipe_type) { - priv->dparam.pipe_type = usbhsc_new_pipe_type; - priv->dparam.pipe_size = - ARRAY_SIZE(usbhsc_new_pipe_type); + if (!priv->dparam.pipe_configs) { + priv->dparam.pipe_configs = usbhsc_new_pipe; + priv->dparam.pipe_size = ARRAY_SIZE(usbhsc_new_pipe); } break; default: @@ -586,9 +585,9 @@ static int usbhs_probe(struct platform_device *pdev) dfunc->notify_hotplug = usbhsc_drvcllbck_notify_hotplug; /* set default param if platform doesn't have */ - if (!priv->dparam.pipe_type) { - priv->dparam.pipe_type = usbhsc_default_pipe_type; - priv->dparam.pipe_size = ARRAY_SIZE(usbhsc_default_pipe_type); + if (!priv->dparam.pipe_configs) { + priv->dparam.pipe_configs = usbhsc_default_pipe; + priv->dparam.pipe_size = ARRAY_SIZE(usbhsc_default_pipe); } if (!priv->dparam.pio_dma_border) priv->dparam.pio_dma_border = 64; /* 64byte */ diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index bd050359926c5..1a8e4c45c4c55 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c @@ -1414,7 +1414,8 @@ static void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) { struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); struct usbhs_pipe *pipe; - u32 *pipe_type = usbhs_get_dparam(priv, pipe_type); + struct renesas_usbhs_driver_pipe_config *pipe_configs = + usbhs_get_dparam(priv, pipe_configs); int pipe_size = usbhs_get_dparam(priv, pipe_size); int old_type, dir_in, i; @@ -1442,15 +1443,15 @@ static void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) * USB_ENDPOINT_XFER_BULK -> dir in * ... */ - dir_in = (pipe_type[i] == old_type); - old_type = pipe_type[i]; + dir_in = (pipe_configs[i].type == old_type); + old_type = pipe_configs[i].type; - if (USB_ENDPOINT_XFER_CONTROL == pipe_type[i]) { + if (USB_ENDPOINT_XFER_CONTROL == pipe_configs[i].type) { pipe = usbhs_dcp_malloc(priv); usbhsh_hpriv_to_dcp(hpriv) = pipe; } else { pipe = usbhs_pipe_malloc(priv, - pipe_type[i], + pipe_configs[i].type, dir_in); } diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c index 4f9c3356127ad..0e95d2925dc58 100644 --- a/drivers/usb/renesas_usbhs/pipe.c +++ b/drivers/usb/renesas_usbhs/pipe.c @@ -44,6 +44,15 @@ char *usbhs_pipe_name(struct usbhs_pipe *pipe) return usbhsp_pipe_name[usbhs_pipe_type(pipe)]; } +static struct renesas_usbhs_driver_pipe_config +*usbhsp_get_pipe_config(struct usbhs_priv *priv, int pipe_num) +{ + struct renesas_usbhs_driver_pipe_config *pipe_configs = + usbhs_get_dparam(priv, pipe_configs); + + return &pipe_configs[pipe_num]; +} + /* * DCPCTR/PIPEnCTR functions */ @@ -384,18 +393,6 @@ void usbhs_pipe_set_trans_count_if_bulk(struct usbhs_pipe *pipe, int len) /* * pipe setup */ -static int usbhsp_possible_double_buffer(struct usbhs_pipe *pipe) -{ - /* - * only ISO / BULK pipe can use double buffer - */ - if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK) || - usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC)) - return 1; - - return 0; -} - static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe, int is_host, int dir_in) @@ -412,7 +409,6 @@ static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe, [USB_ENDPOINT_XFER_INT] = TYPE_INT, [USB_ENDPOINT_XFER_ISOC] = TYPE_ISO, }; - int is_double = usbhsp_possible_double_buffer(pipe); if (usbhs_pipe_is_dcp(pipe)) return -EINVAL; @@ -434,10 +430,7 @@ static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe, usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK)) bfre = 0; /* FIXME */ - /* DBLB */ - if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC) || - usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK)) - dblb = (is_double) ? DBLB : 0; + /* DBLB: see usbhs_pipe_config_update() */ /* CNTMD */ if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK)) @@ -473,13 +466,13 @@ static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe, static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe) { struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); - struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv); struct device *dev = usbhs_priv_to_dev(priv); int pipe_num = usbhs_pipe_number(pipe); - int is_double = usbhsp_possible_double_buffer(pipe); u16 buff_size; u16 bufnmb; u16 bufnmb_cnt; + struct renesas_usbhs_driver_pipe_config *pipe_config = + usbhsp_get_pipe_config(priv, pipe_num); /* * PIPEBUF @@ -489,56 +482,13 @@ static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe) * - "Features" - "Pipe configuration" * - "Operation" - "FIFO Buffer Memory" * - "Operation" - "Pipe Control" - * - * ex) if pipe6 - pipe9 are USB_ENDPOINT_XFER_INT (SH7724) - * - * BUFNMB: PIPE - * 0: pipe0 (DCP 256byte) - * 1: - - * 2: - - * 3: - - * 4: pipe6 (INT 64byte) - * 5: pipe7 (INT 64byte) - * 6: pipe8 (INT 64byte) - * 7: pipe9 (INT 64byte) - * 8 - xx: free (for BULK, ISOC) */ - - /* - * FIXME - * - * it doesn't have good buffer allocator - * - * DCP : 256 byte - * BULK: 512 byte - * INT : 64 byte - * ISOC: 512 byte - */ - if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_CONTROL)) - buff_size = 256; - else if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_INT)) - buff_size = 64; - else - buff_size = 512; + buff_size = pipe_config->bufsize; + bufnmb = pipe_config->bufnum; /* change buff_size to register value */ bufnmb_cnt = (buff_size / 64) - 1; - /* BUFNMB has been reserved for INT pipe - * see above */ - if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_INT)) { - bufnmb = pipe_num - 2; - } else { - bufnmb = info->bufnmb_last; - info->bufnmb_last += bufnmb_cnt + 1; - - /* - * double buffer - */ - if (is_double) - info->bufnmb_last += bufnmb_cnt + 1; - } - dev_dbg(dev, "pipe : %d : buff_size 0x%x: bufnmb 0x%x\n", pipe_num, buff_size, bufnmb); @@ -549,8 +499,13 @@ static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe) void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel, u16 epnum, u16 maxp) { + struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); + int pipe_num = usbhs_pipe_number(pipe); + struct renesas_usbhs_driver_pipe_config *pipe_config = + usbhsp_get_pipe_config(priv, pipe_num); + u16 dblb = pipe_config->double_buf ? DBLB : 0; + if (devsel > 0xA) { - struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); struct device *dev = usbhs_priv_to_dev(priv); dev_err(dev, "devsel error %d\n", devsel); @@ -568,7 +523,7 @@ void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel, maxp); if (!usbhs_pipe_is_dcp(pipe)) - usbhsp_pipe_cfg_set(pipe, 0x000F, epnum); + usbhsp_pipe_cfg_set(pipe, 0x000F | DBLB, epnum | dblb); } /* @@ -708,23 +663,7 @@ void usbhs_pipe_init(struct usbhs_priv *priv, struct usbhs_pipe *pipe; int i; - /* - * FIXME - * - * driver needs good allocator. - * - * find first free buffer area (BULK, ISOC) - * (DCP, INT area is fixed) - * - * buffer number 0 - 3 have been reserved for DCP - * see - * usbhsp_to_bufnmb - */ - info->bufnmb_last = 4; usbhs_for_each_pipe_with_dcp(pipe, priv, i) { - if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_INT)) - info->bufnmb_last++; - usbhsp_flags_init(pipe); pipe->fifo = NULL; pipe->mod_private = NULL; @@ -851,12 +790,13 @@ int usbhs_pipe_probe(struct usbhs_priv *priv) struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv); struct usbhs_pipe *pipe; struct device *dev = usbhs_priv_to_dev(priv); - u32 *pipe_type = usbhs_get_dparam(priv, pipe_type); + struct renesas_usbhs_driver_pipe_config *pipe_configs = + usbhs_get_dparam(priv, pipe_configs); int pipe_size = usbhs_get_dparam(priv, pipe_size); int i; /* This driver expects 1st pipe is DCP */ - if (pipe_type[0] != USB_ENDPOINT_XFER_CONTROL) { + if (pipe_configs[0].type != USB_ENDPOINT_XFER_CONTROL) { dev_err(dev, "1st PIPE is not DCP\n"); return -EINVAL; } @@ -876,10 +816,10 @@ int usbhs_pipe_probe(struct usbhs_priv *priv) pipe->priv = priv; usbhs_pipe_type(pipe) = - pipe_type[i] & USB_ENDPOINT_XFERTYPE_MASK; + pipe_configs[i].type & USB_ENDPOINT_XFERTYPE_MASK; dev_dbg(dev, "pipe %x\t: %s\n", - i, usbhsp_pipe_name[pipe_type[i]]); + i, usbhsp_pipe_name[pipe_configs[i].type]); } return 0; diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h index b0bc7b6030167..3212ab51e844b 100644 --- a/drivers/usb/renesas_usbhs/pipe.h +++ b/drivers/usb/renesas_usbhs/pipe.h @@ -46,7 +46,6 @@ struct usbhs_pipe { struct usbhs_pipe_info { struct usbhs_pipe *pipe; int size; /* array size of "pipe" */ - int bufnmb_last; /* FIXME : driver needs good allocator */ int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map); }; diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h index bfb74723f1515..4db191fe8c2ce 100644 --- a/include/linux/usb/renesas_usbhs.h +++ b/include/linux/usb/renesas_usbhs.h @@ -105,12 +105,26 @@ struct renesas_usbhs_platform_callback { * some register needs USB chip specific parameters. * This struct show it to driver */ + +struct renesas_usbhs_driver_pipe_config { + u8 type; /* USB_ENDPOINT_XFER_xxx */ + u16 bufsize; + u8 bufnum; + bool double_buf; +}; +#define RENESAS_USBHS_PIPE(_type, _size, _num, _double_buf) { \ + .type = (_type), \ + .bufsize = (_size), \ + .bufnum = (_num), \ + .double_buf = (_double_buf), \ + } + struct renesas_usbhs_driver_param { /* * pipe settings */ - u32 *pipe_type; /* array of USB_ENDPOINT_XFER_xxx (from ep0) */ - int pipe_size; /* pipe_type array size */ + struct renesas_usbhs_driver_pipe_config *pipe_configs; + int pipe_size; /* pipe_configs array size */ /* * option: -- GitLab From 64c5f48b100e92f189a32b6d660e3329681ec9b5 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 18 Nov 2015 14:34:10 +0900 Subject: [PATCH 1327/2855] usb: renesas_usbhs: Modify ep.caps.type_xxx and usb_ep_maxpacket_limit() This patch modifies the ep.caps.type_{iso,bulk,int} setting and the second argument of usb_ep_maxpacket_limit() using the dparam.pipe_configs. In the previous code, all the type_{iso,bulk,int} were set to true. However, to avoid waste time for finding suitable pipe in usb_ep_enable(), this driver should set correct type. Also the second argument of usb_ep_maxpacket_limit() was set to 512 even if the pipe is isochronous or interrupt. So, this driver could not bind a gadget driver like the g_audio driver. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/mod_gadget.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 8f7a78e709759..657f9672ceba7 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -1042,6 +1042,8 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) struct usbhsg_gpriv *gpriv; struct usbhsg_uep *uep; struct device *dev = usbhs_priv_to_dev(priv); + struct renesas_usbhs_driver_pipe_config *pipe_configs = + usbhs_get_dparam(priv, pipe_configs); int pipe_size = usbhs_get_dparam(priv, pipe_size); int i; int ret; @@ -1111,13 +1113,16 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) gpriv->gadget.ep0 = &uep->ep; usb_ep_set_maxpacket_limit(&uep->ep, 64); uep->ep.caps.type_control = true; - } - /* init normal pipe */ - else { - usb_ep_set_maxpacket_limit(&uep->ep, 512); - uep->ep.caps.type_iso = true; - uep->ep.caps.type_bulk = true; - uep->ep.caps.type_int = true; + } else { + /* init normal pipe */ + if (pipe_configs[i].type == USB_ENDPOINT_XFER_ISOC) + uep->ep.caps.type_iso = true; + if (pipe_configs[i].type == USB_ENDPOINT_XFER_BULK) + uep->ep.caps.type_bulk = true; + if (pipe_configs[i].type == USB_ENDPOINT_XFER_INT) + uep->ep.caps.type_int = true; + usb_ep_set_maxpacket_limit(&uep->ep, + pipe_configs[i].bufsize); list_add_tail(&uep->ep.ep_list, &gpriv->gadget.ep_list); } uep->ep.caps.dir_in = true; -- GitLab From 4405a2ced55f375708669550cda750452885c9de Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 13 Nov 2015 16:00:27 +0800 Subject: [PATCH 1328/2855] Doc: ABI: configfs-usb-gadget-sourcesink: add two entries for depth of queue Add both bulk and iso depth of queue entries. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- Documentation/ABI/testing/configfs-usb-gadget-sourcesink | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-sourcesink b/Documentation/ABI/testing/configfs-usb-gadget-sourcesink index bc7ff731aa0cf..f56335af2d88f 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-sourcesink +++ b/Documentation/ABI/testing/configfs-usb-gadget-sourcesink @@ -10,3 +10,5 @@ Description: isoc_mult - 0..2 (hs/ss only) isoc_maxburst - 0..15 (ss only) buflen - buffer length + bulk_qlen - depth of queue for bulk + iso_qlen - depth of queue for iso -- GitLab From bc1d3cdc9c3cbbd9040da8c53237e177c38048b0 Mon Sep 17 00:00:00 2001 From: "Felipe F. Tonello" Date: Tue, 10 Nov 2015 17:52:04 +0000 Subject: [PATCH 1329/2855] usb: gadget: f_midi: remove duplicated code This code is duplicated from f_midi_start_ep(midi, f, midi->out_ep). Reviewed-by: Robert Baldyga Signed-off-by: Felipe F. Tonello Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_midi.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index 898a570319f17..695cf75428e34 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -324,7 +324,6 @@ static int f_midi_start_ep(struct f_midi *midi, static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct f_midi *midi = func_to_midi(f); - struct usb_composite_dev *cdev = f->config->cdev; unsigned i; int err; @@ -340,24 +339,6 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (err) return err; - usb_ep_disable(midi->out_ep); - - err = config_ep_by_speed(midi->gadget, f, midi->out_ep); - if (err) { - ERROR(cdev, "can't configure %s: %d\n", - midi->out_ep->name, err); - return err; - } - - err = usb_ep_enable(midi->out_ep); - if (err) { - ERROR(cdev, "can't start %s: %d\n", - midi->out_ep->name, err); - return err; - } - - midi->out_ep->driver_data = midi; - /* allocate a bunch of read buffers and queue them all at once. */ for (i = 0; i < midi->qlen && err == 0; i++) { struct usb_request *req = -- GitLab From 079fe5a6da616891cca1a26e803e1df2a87e9ae5 Mon Sep 17 00:00:00 2001 From: "Felipe F. Tonello" Date: Tue, 10 Nov 2015 17:52:05 +0000 Subject: [PATCH 1330/2855] usb: gadget: define free_ep_req as universal function This function is shared between gadget functions, so this avoid unnecessary duplicated code and potentially avoid memory leaks. Reviewed-by: Robert Baldyga Signed-off-by: Felipe F. Tonello Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_midi.c | 6 ------ drivers/usb/gadget/function/f_sourcesink.c | 6 ------ drivers/usb/gadget/function/g_zero.h | 1 - drivers/usb/gadget/u_f.c | 1 - drivers/usb/gadget/u_f.h | 10 ++++++++-- 5 files changed, 8 insertions(+), 16 deletions(-) diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index 695cf75428e34..29bfca1a47bb3 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -201,12 +201,6 @@ static inline struct usb_request *midi_alloc_ep_req(struct usb_ep *ep, return alloc_ep_req(ep, length, length); } -static void free_ep_req(struct usb_ep *ep, struct usb_request *req) -{ - kfree(req->buf); - usb_ep_free_request(ep, req); -} - static const uint8_t f_midi_cin_length[] = { 0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1 }; diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index 9df4aa1ea011d..12e3eb4ee140e 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -298,12 +298,6 @@ static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len) return alloc_ep_req(ep, len, ss->buflen); } -void free_ep_req(struct usb_ep *ep, struct usb_request *req) -{ - kfree(req->buf); - usb_ep_free_request(ep, req); -} - static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep) { int value; diff --git a/drivers/usb/gadget/function/g_zero.h b/drivers/usb/gadget/function/g_zero.h index 4f61d95bf1772..492924d0d599b 100644 --- a/drivers/usb/gadget/function/g_zero.h +++ b/drivers/usb/gadget/function/g_zero.h @@ -65,7 +65,6 @@ void lb_modexit(void); int lb_modinit(void); /* common utilities */ -void free_ep_req(struct usb_ep *ep, struct usb_request *req); void disable_endpoints(struct usb_composite_dev *cdev, struct usb_ep *in, struct usb_ep *out, struct usb_ep *iso_in, struct usb_ep *iso_out); diff --git a/drivers/usb/gadget/u_f.c b/drivers/usb/gadget/u_f.c index c6276f0268ae5..4bc7eea8bfc84 100644 --- a/drivers/usb/gadget/u_f.c +++ b/drivers/usb/gadget/u_f.c @@ -11,7 +11,6 @@ * published by the Free Software Foundation. */ -#include #include "u_f.h" struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len) diff --git a/drivers/usb/gadget/u_f.h b/drivers/usb/gadget/u_f.h index 1d5f0eb685521..4247cc098a891 100644 --- a/drivers/usb/gadget/u_f.h +++ b/drivers/usb/gadget/u_f.h @@ -16,6 +16,8 @@ #ifndef __U_F_H__ #define __U_F_H__ +#include + /* Variable Length Array Macros **********************************************/ #define vla_group(groupname) size_t groupname##__next = 0 #define vla_group_size(groupname) groupname##__next @@ -45,8 +47,12 @@ struct usb_ep; struct usb_request; +/* Requests allocated via alloc_ep_req() must be freed by free_ep_req(). */ struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len); +static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req) +{ + kfree(req->buf); + usb_ep_free_request(ep, req); +} #endif /* __U_F_H__ */ - - -- GitLab From 38660ac7beb53b5f7bdb1d325a93c70cb7ba429f Mon Sep 17 00:00:00 2001 From: "Felipe F. Tonello" Date: Tue, 10 Nov 2015 17:52:07 +0000 Subject: [PATCH 1331/2855] usb: gadget: gmidi: Cleanup legacy code Remove unnecessary headers and variables. Reviewed-by: Robert Baldyga Signed-off-by: Felipe F. Tonello Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/gmidi.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/usb/gadget/legacy/gmidi.c b/drivers/usb/gadget/legacy/gmidi.c index 8a18348ae86ee..be8e91d68e146 100644 --- a/drivers/usb/gadget/legacy/gmidi.c +++ b/drivers/usb/gadget/legacy/gmidi.c @@ -21,19 +21,12 @@ /* #define VERBOSE_DEBUG */ #include -#include #include -#include -#include #include -#include -#include #include #include -#include -#include #include "u_midi.h" @@ -42,7 +35,6 @@ MODULE_AUTHOR("Ben Williamson"); MODULE_LICENSE("GPL v2"); -static const char shortname[] = "g_midi"; static const char longname[] = "MIDI Gadget"; USB_GADGET_COMPOSITE_OPTIONS(); -- GitLab From 75f5c434c30b22a48a1d4a0f827473dc29036d78 Mon Sep 17 00:00:00 2001 From: Deepa Dinamani Date: Wed, 4 Nov 2015 15:29:11 -0800 Subject: [PATCH 1332/2855] usb: misc: usbtest: Remove timeval usage timeval is deprecated and not y2038 safe. Its size also changes according to 32 bit/ 64 bit compilation. Replace it with 32 and 64 bit versions of its individual fields, giving two ioctls with different code values. The two ioctls are necessary to maintain the 32 bit and 64 bit userspace compatibility with a 64/32 bit kernel. Change unsigned to __u32 types for a definitive userspace interface. This is in accordance with the psABI that the unsigned type is always 32 bits. Also use motonic timer instead of real time to ensure positive delta values. Refactor usbtest_ioctl for readability to isolate the handling of the testing timing measurement. The official testusb userspace tool can be changed in a separate patch to reflect the __u32 changes as well. It can use the usbtest_param_32 struct, since 32 bit seconds is long enough for test durations. Reviewed-by: Arnd Bergmann Signed-off-by: Deepa Dinamani Signed-off-by: Felipe Balbi --- drivers/usb/misc/usbtest.c | 229 ++++++++++++++++++++++++------------- 1 file changed, 147 insertions(+), 82 deletions(-) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index c1bd1eb548bb9..92fdb6e9faff4 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -22,18 +22,42 @@ static void complicated_callback(struct urb *urb); /*-------------------------------------------------------------------------*/ /* FIXME make these public somewhere; usbdevfs.h? */ -struct usbtest_param { + +/* Parameter for usbtest driver. */ +struct usbtest_param_32 { /* inputs */ - unsigned test_num; /* 0..(TEST_CASES-1) */ - unsigned iterations; - unsigned length; - unsigned vary; - unsigned sglen; + __u32 test_num; /* 0..(TEST_CASES-1) */ + __u32 iterations; + __u32 length; + __u32 vary; + __u32 sglen; /* outputs */ - struct timeval duration; + __s32 duration_sec; + __s32 duration_usec; }; -#define USBTEST_REQUEST _IOWR('U', 100, struct usbtest_param) + +/* + * Compat parameter to the usbtest driver. + * This supports older user space binaries compiled with 64 bit compiler. + */ +struct usbtest_param_64 { + /* inputs */ + __u32 test_num; /* 0..(TEST_CASES-1) */ + __u32 iterations; + __u32 length; + __u32 vary; + __u32 sglen; + + /* outputs */ + __s64 duration_sec; + __s64 duration_usec; +}; + +/* IOCTL interface to the driver. */ +#define USBTEST_REQUEST_32 _IOWR('U', 100, struct usbtest_param_32) +/* COMPAT IOCTL interface to the driver. */ +#define USBTEST_REQUEST_64 _IOWR('U', 100, struct usbtest_param_64) /*-------------------------------------------------------------------------*/ @@ -1030,7 +1054,7 @@ struct ctrl_ctx { unsigned pending; int status; struct urb **urb; - struct usbtest_param *param; + struct usbtest_param_32 *param; int last; }; @@ -1155,7 +1179,7 @@ error: } static int -test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param) +test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param) { struct usb_device *udev = testdev_to_usbdev(dev); struct urb **urb; @@ -1930,7 +1954,7 @@ static struct urb *iso_alloc_urb( } static int -test_queue(struct usbtest_dev *dev, struct usbtest_param *param, +test_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param, int pipe, struct usb_endpoint_descriptor *desc, unsigned offset) { struct transfer_context context; @@ -2049,81 +2073,20 @@ static int test_unaligned_bulk( return retval; } -/*-------------------------------------------------------------------------*/ - -/* We only have this one interface to user space, through usbfs. - * User mode code can scan usbfs to find N different devices (maybe on - * different busses) to use when testing, and allocate one thread per - * test. So discovery is simplified, and we have no device naming issues. - * - * Don't use these only as stress/load tests. Use them along with with - * other USB bus activity: plugging, unplugging, mousing, mp3 playback, - * video capture, and so on. Run different tests at different times, in - * different sequences. Nothing here should interact with other devices, - * except indirectly by consuming USB bandwidth and CPU resources for test - * threads and request completion. But the only way to know that for sure - * is to test when HC queues are in use by many devices. - * - * WARNING: Because usbfs grabs udev->dev.sem before calling this ioctl(), - * it locks out usbcore in certain code paths. Notably, if you disconnect - * the device-under-test, hub_wq will wait block forever waiting for the - * ioctl to complete ... so that usb_disconnect() can abort the pending - * urbs and then call usbtest_disconnect(). To abort a test, you're best - * off just killing the userspace task and waiting for it to exit. - */ - +/* Run tests. */ static int -usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) +usbtest_do_ioctl(struct usb_interface *intf, struct usbtest_param_32 *param) { struct usbtest_dev *dev = usb_get_intfdata(intf); struct usb_device *udev = testdev_to_usbdev(dev); - struct usbtest_param *param = buf; - int retval = -EOPNOTSUPP; struct urb *urb; struct scatterlist *sg; struct usb_sg_request req; - struct timeval start; unsigned i; - - /* FIXME USBDEVFS_CONNECTINFO doesn't say how fast the device is. */ - - pattern = mod_pattern; - - if (code != USBTEST_REQUEST) - return -EOPNOTSUPP; + int retval = -EOPNOTSUPP; if (param->iterations <= 0) return -EINVAL; - - if (param->sglen > MAX_SGLEN) - return -EINVAL; - - if (mutex_lock_interruptible(&dev->lock)) - return -ERESTARTSYS; - - /* FIXME: What if a system sleep starts while a test is running? */ - - /* some devices, like ez-usb default devices, need a non-default - * altsetting to have any active endpoints. some tests change - * altsettings; force a default so most tests don't need to check. - */ - if (dev->info->alt >= 0) { - int res; - - if (intf->altsetting->desc.bInterfaceNumber) { - mutex_unlock(&dev->lock); - return -ENODEV; - } - res = set_altsetting(dev, dev->info->alt); - if (res) { - dev_err(&intf->dev, - "set altsetting to %d failed, %d\n", - dev->info->alt, res); - mutex_unlock(&dev->lock); - return res; - } - } - /* * Just a bunch of test cases that every HCD is expected to handle. * @@ -2133,7 +2096,6 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) * FIXME add more tests! cancel requests, verify the data, control * queueing, concurrent read+write threads, and so on. */ - do_gettimeofday(&start); switch (param->test_num) { case 0: @@ -2548,13 +2510,116 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) dev->in_pipe, NULL, 0); break; } - do_gettimeofday(¶m->duration); - param->duration.tv_sec -= start.tv_sec; - param->duration.tv_usec -= start.tv_usec; - if (param->duration.tv_usec < 0) { - param->duration.tv_usec += 1000 * 1000; - param->duration.tv_sec -= 1; + return retval; +} + +/*-------------------------------------------------------------------------*/ + +/* We only have this one interface to user space, through usbfs. + * User mode code can scan usbfs to find N different devices (maybe on + * different busses) to use when testing, and allocate one thread per + * test. So discovery is simplified, and we have no device naming issues. + * + * Don't use these only as stress/load tests. Use them along with with + * other USB bus activity: plugging, unplugging, mousing, mp3 playback, + * video capture, and so on. Run different tests at different times, in + * different sequences. Nothing here should interact with other devices, + * except indirectly by consuming USB bandwidth and CPU resources for test + * threads and request completion. But the only way to know that for sure + * is to test when HC queues are in use by many devices. + * + * WARNING: Because usbfs grabs udev->dev.sem before calling this ioctl(), + * it locks out usbcore in certain code paths. Notably, if you disconnect + * the device-under-test, hub_wq will wait block forever waiting for the + * ioctl to complete ... so that usb_disconnect() can abort the pending + * urbs and then call usbtest_disconnect(). To abort a test, you're best + * off just killing the userspace task and waiting for it to exit. + */ + +static int +usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) +{ + + struct usbtest_dev *dev = usb_get_intfdata(intf); + struct usbtest_param_64 *param_64 = buf; + struct usbtest_param_32 temp; + struct usbtest_param_32 *param_32 = buf; + struct timespec64 start; + struct timespec64 end; + struct timespec64 duration; + int retval = -EOPNOTSUPP; + + /* FIXME USBDEVFS_CONNECTINFO doesn't say how fast the device is. */ + + pattern = mod_pattern; + + if (mutex_lock_interruptible(&dev->lock)) + return -ERESTARTSYS; + + /* FIXME: What if a system sleep starts while a test is running? */ + + /* some devices, like ez-usb default devices, need a non-default + * altsetting to have any active endpoints. some tests change + * altsettings; force a default so most tests don't need to check. + */ + if (dev->info->alt >= 0) { + if (intf->altsetting->desc.bInterfaceNumber) { + retval = -ENODEV; + goto free_mutex; + } + retval = set_altsetting(dev, dev->info->alt); + if (retval) { + dev_err(&intf->dev, + "set altsetting to %d failed, %d\n", + dev->info->alt, retval); + goto free_mutex; + } + } + + switch (code) { + case USBTEST_REQUEST_64: + temp.test_num = param_64->test_num; + temp.iterations = param_64->iterations; + temp.length = param_64->length; + temp.sglen = param_64->sglen; + temp.vary = param_64->vary; + param_32 = &temp; + break; + + case USBTEST_REQUEST_32: + break; + + default: + retval = -EOPNOTSUPP; + goto free_mutex; + } + + ktime_get_ts64(&start); + + retval = usbtest_do_ioctl(intf, param_32); + if (retval) + goto free_mutex; + + ktime_get_ts64(&end); + + duration = timespec64_sub(end, start); + + temp.duration_sec = duration.tv_sec; + temp.duration_usec = duration.tv_nsec/NSEC_PER_USEC; + + switch (code) { + case USBTEST_REQUEST_32: + param_32->duration_sec = temp.duration_sec; + param_32->duration_usec = temp.duration_usec; + break; + + case USBTEST_REQUEST_64: + param_64->duration_sec = temp.duration_sec; + param_64->duration_usec = temp.duration_usec; + break; } + +free_mutex: mutex_unlock(&dev->lock); return retval; } -- GitLab From fbb9e22b15ad3c9a98c66bad801b4d1366e8bf20 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Fri, 20 Nov 2015 11:49:28 +0100 Subject: [PATCH 1333/2855] usb: dwc2: host: enable descriptor dma for fs devices As descriptor dma mode does not support split transfers, it can't be enabled for high speed devices. Add a core parameter to enable it for full speed devices. Ensure frame list and descriptor list are correctly freed during disconnect. Acked-by: John Youn Signed-off-by: Mian Yousaf Kaukab Signed-off-by: Gregory Herrero Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 24 ++++++++++++++++++++++++ drivers/usb/dwc2/core.h | 20 ++++++++++++++++++++ drivers/usb/dwc2/hcd.c | 22 ++++++++++++++++++++++ drivers/usb/dwc2/hcd_intr.c | 15 +++++++++++++-- drivers/usb/dwc2/hcd_queue.c | 2 +- drivers/usb/dwc2/platform.c | 4 ++++ 6 files changed, 84 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index ef73e498e98fc..5568d9c8e213c 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -2485,6 +2485,29 @@ void dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val) hsotg->core_params->dma_desc_enable = val; } +void dwc2_set_param_dma_desc_fs_enable(struct dwc2_hsotg *hsotg, int val) +{ + int valid = 1; + + if (val > 0 && (hsotg->core_params->dma_enable <= 0 || + !hsotg->hw_params.dma_desc_enable)) + valid = 0; + if (val < 0) + valid = 0; + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for dma_desc_fs_enable parameter. Check HW configuration.\n", + val); + val = (hsotg->core_params->dma_enable > 0 && + hsotg->hw_params.dma_desc_enable); + } + + hsotg->core_params->dma_desc_fs_enable = val; + dev_dbg(hsotg->dev, "Setting dma_desc_fs_enable to %d\n", val); +} + void dwc2_set_param_host_support_fs_ls_low_power(struct dwc2_hsotg *hsotg, int val) { @@ -3016,6 +3039,7 @@ void dwc2_set_parameters(struct dwc2_hsotg *hsotg, dwc2_set_param_otg_cap(hsotg, params->otg_cap); dwc2_set_param_dma_enable(hsotg, params->dma_enable); dwc2_set_param_dma_desc_enable(hsotg, params->dma_desc_enable); + dwc2_set_param_dma_desc_fs_enable(hsotg, params->dma_desc_fs_enable); dwc2_set_param_host_support_fs_ls_low_power(hsotg, params->host_support_fs_ls_low_power); dwc2_set_param_enable_dynamic_fifo(hsotg, diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index a66d3cb62b659..fd4c2365069ae 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -246,6 +246,13 @@ enum dwc2_ep0_state { * value for this if none is specified. * 0 - Address DMA * 1 - Descriptor DMA (default, if available) + * @dma_desc_fs_enable: When DMA mode is enabled, specifies whether to use + * address DMA mode or descriptor DMA mode for accessing + * the data FIFOs in Full Speed mode only. The driver + * will automatically detect the value for this if none is + * specified. + * 0 - Address DMA + * 1 - Descriptor DMA in FS (default, if available) * @speed: Specifies the maximum speed of operation in host and * device mode. The actual speed depends on the speed of * the attached device and the value of phy_type. @@ -375,6 +382,7 @@ struct dwc2_core_params { int otg_ver; int dma_enable; int dma_desc_enable; + int dma_desc_fs_enable; int speed; int enable_dynamic_fifo; int en_multiple_tx_fifo; @@ -456,6 +464,7 @@ struct dwc2_hw_params { unsigned op_mode:3; unsigned arch:2; unsigned dma_desc_enable:1; + unsigned dma_desc_fs_enable:1; unsigned enable_dynamic_fifo:1; unsigned en_multiple_tx_fifo:1; unsigned host_rx_fifo_size:16; @@ -770,6 +779,7 @@ struct dwc2_hsotg { u16 frame_number; u16 periodic_qh_count; bool bus_suspended; + bool new_connection; #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS #define FRAME_NUM_ARRAY_SIZE 1000 @@ -941,6 +951,16 @@ extern void dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val); */ extern void dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val); +/* + * When DMA mode is enabled specifies whether to use + * address DMA or DMA Descritor mode with full speed devices + * for accessing the data FIFOs in host mode. + * 0 - address DMA + * 1 - FS DMA Descriptor(default, if available) + */ +extern void dwc2_set_param_dma_desc_fs_enable(struct dwc2_hsotg *hsotg, + int val); + /* * Specifies the maximum speed of operation in host and device mode. * The actual speed depends on the speed of the attached device and diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 571c21727ff9f..32c84e7a81ab3 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1734,6 +1734,28 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, port_status |= USB_PORT_STAT_TEST; /* USB_PORT_FEAT_INDICATOR unsupported always 0 */ + if (hsotg->core_params->dma_desc_fs_enable) { + /* + * Enable descriptor DMA only if a full speed + * device is connected. + */ + if (hsotg->new_connection && + ((port_status & + (USB_PORT_STAT_CONNECTION | + USB_PORT_STAT_HIGH_SPEED | + USB_PORT_STAT_LOW_SPEED)) == + USB_PORT_STAT_CONNECTION)) { + u32 hcfg; + + dev_info(hsotg->dev, "Enabling descriptor DMA mode\n"); + hsotg->core_params->dma_desc_enable = 1; + hcfg = dwc2_readl(hsotg->regs + HCFG); + hcfg |= HCFG_DESCDMA; + dwc2_writel(hcfg, hsotg->regs + HCFG); + hsotg->new_connection = false; + } + } + dev_vdbg(hsotg->dev, "port_status=%08x\n", port_status); *(__le32 *)buf = cpu_to_le32(port_status); break; diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index bda0b21b850f6..7c15f03b069c5 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c @@ -372,10 +372,21 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg) " --Port Interrupt HPRT0=0x%08x Port Enable Changed (now %d)--\n", hprt0, !!(hprt0 & HPRT0_ENA)); hprt0_modify |= HPRT0_ENACHG; - if (hprt0 & HPRT0_ENA) + if (hprt0 & HPRT0_ENA) { + hsotg->new_connection = true; dwc2_hprt0_enable(hsotg, hprt0, &hprt0_modify); - else + } else { hsotg->flags.b.port_enable_change = 1; + if (hsotg->core_params->dma_desc_fs_enable) { + u32 hcfg; + + hsotg->core_params->dma_desc_enable = 0; + hsotg->new_connection = false; + hcfg = dwc2_readl(hsotg->regs + HCFG); + hcfg &= ~HCFG_DESCDMA; + dwc2_writel(hcfg, hsotg->regs + HCFG); + } + } } /* Overcurrent Change Interrupt */ diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c index 7d8d06cfe3c1d..27d402f680a32 100644 --- a/drivers/usb/dwc2/hcd_queue.c +++ b/drivers/usb/dwc2/hcd_queue.c @@ -232,7 +232,7 @@ struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg, */ void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { - if (hsotg->core_params->dma_desc_enable > 0) { + if (qh->desc_list) { dwc2_hcd_qh_free_ddma(hsotg, qh); } else { /* kfree(NULL) is safe */ diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 39c1cbf0e75d9..095bc05f76cae 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -59,6 +59,7 @@ static const struct dwc2_core_params params_bcm2835 = { .otg_ver = 0, /* 1.3 */ .dma_enable = 1, .dma_desc_enable = 0, + .dma_desc_fs_enable = 0, .speed = 0, /* High Speed */ .enable_dynamic_fifo = 1, .en_multiple_tx_fifo = 1, @@ -89,6 +90,7 @@ static const struct dwc2_core_params params_rk3066 = { .otg_ver = -1, .dma_enable = -1, .dma_desc_enable = 0, + .dma_desc_fs_enable = 0, .speed = -1, .enable_dynamic_fifo = 1, .en_multiple_tx_fifo = -1, @@ -348,8 +350,10 @@ static int dwc2_driver_probe(struct platform_device *dev) /* * Disable descriptor dma mode by default as the HW can support * it, but does not support it for SPLIT transactions. + * Disable it for FS devices as well. */ defparams.dma_desc_enable = 0; + defparams.dma_desc_fs_enable = 0; } hsotg = devm_kzalloc(&dev->dev, sizeof(*hsotg), GFP_KERNEL); -- GitLab From 95105a998dff0747327f11708ea24480ee0eca54 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Fri, 20 Nov 2015 11:49:29 +0100 Subject: [PATCH 1334/2855] usb: dwc2: host: avoid usage of dma_alloc_coherent with irqs disabled Use Streaming DMA mappings to handle cache coherency of frame list and descriptor list. Cache are always flushed before controller access it or before cpu access it. Acked-by: John Youn Signed-off-by: Gregory Herrero Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 3 + drivers/usb/dwc2/core.h | 2 + drivers/usb/dwc2/hcd.c | 4 +- drivers/usb/dwc2/hcd.h | 4 ++ drivers/usb/dwc2/hcd_ddma.c | 106 ++++++++++++++++++++++++++++-------- 5 files changed, 94 insertions(+), 25 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 5568d9c8e213c..542c9e6d95db6 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -1934,6 +1934,9 @@ void dwc2_hc_start_transfer_ddma(struct dwc2_hsotg *hsotg, dwc2_writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num)); + dma_sync_single_for_device(hsotg->dev, chan->desc_list_addr, + chan->desc_list_sz, DMA_TO_DEVICE); + hc_dma = (u32)chan->desc_list_addr & HCDMA_DMA_ADDR_MASK; /* Always start from first descriptor */ diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index fd4c2365069ae..e7cc54268f2f5 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -685,6 +685,7 @@ struct dwc2_hregs_backup { * @otg_port: OTG port number * @frame_list: Frame list * @frame_list_dma: Frame list DMA address + * @frame_list_sz: Frame list size * * These are for peripheral mode: * @@ -804,6 +805,7 @@ struct dwc2_hsotg { u8 otg_port; u32 *frame_list; dma_addr_t frame_list_dma; + u32 frame_list_sz; #ifdef DEBUG u32 frrem_samples; diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 32c84e7a81ab3..7fd4f41e12a79 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -881,8 +881,10 @@ static int dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) */ chan->multi_count = dwc2_hb_mult(qh->maxp); - if (hsotg->core_params->dma_desc_enable > 0) + if (hsotg->core_params->dma_desc_enable > 0) { chan->desc_list_addr = qh->desc_list_dma; + chan->desc_list_sz = qh->desc_list_sz; + } dwc2_hc_init(hsotg, chan); chan->qh = qh; diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h index 2e5e9d9a00161..6e822661a69e3 100644 --- a/drivers/usb/dwc2/hcd.h +++ b/drivers/usb/dwc2/hcd.h @@ -107,6 +107,7 @@ struct dwc2_qh; * @qh: QH for the transfer being processed by this channel * @hc_list_entry: For linking to list of host channels * @desc_list_addr: Current QH's descriptor list DMA address + * @desc_list_sz: Current QH's descriptor list size * * This structure represents the state of a single host channel when acting in * host mode. It contains the data items needed to transfer packets to an @@ -159,6 +160,7 @@ struct dwc2_host_chan { struct dwc2_qh *qh; struct list_head hc_list_entry; dma_addr_t desc_list_addr; + u32 desc_list_sz; }; struct dwc2_hcd_pipe_info { @@ -251,6 +253,7 @@ enum dwc2_transaction_type { * schedule * @desc_list: List of transfer descriptors * @desc_list_dma: Physical address of desc_list + * @desc_list_sz: Size of descriptors list * @n_bytes: Xfer Bytes array. Each element corresponds to a transfer * descriptor and indicates original XferSize value for the * descriptor @@ -284,6 +287,7 @@ struct dwc2_qh { struct list_head qh_list_entry; struct dwc2_hcd_dma_desc *desc_list; dma_addr_t desc_list_dma; + u32 desc_list_sz; u32 *n_bytes; unsigned tt_buffer_dirty:1; }; diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c index f98c7e91f6bcd..85d7816d29f1d 100644 --- a/drivers/usb/dwc2/hcd_ddma.c +++ b/drivers/usb/dwc2/hcd_ddma.c @@ -87,22 +87,23 @@ static u16 dwc2_frame_incr_val(struct dwc2_qh *qh) static int dwc2_desc_list_alloc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, gfp_t flags) { - qh->desc_list = dma_alloc_coherent(hsotg->dev, - sizeof(struct dwc2_hcd_dma_desc) * - dwc2_max_desc_num(qh), &qh->desc_list_dma, - flags); + qh->desc_list_sz = sizeof(struct dwc2_hcd_dma_desc) * + dwc2_max_desc_num(qh); + qh->desc_list = kzalloc(qh->desc_list_sz, flags | GFP_DMA); if (!qh->desc_list) return -ENOMEM; - memset(qh->desc_list, 0, - sizeof(struct dwc2_hcd_dma_desc) * dwc2_max_desc_num(qh)); + qh->desc_list_dma = dma_map_single(hsotg->dev, qh->desc_list, + qh->desc_list_sz, + DMA_TO_DEVICE); qh->n_bytes = kzalloc(sizeof(u32) * dwc2_max_desc_num(qh), flags); if (!qh->n_bytes) { - dma_free_coherent(hsotg->dev, sizeof(struct dwc2_hcd_dma_desc) - * dwc2_max_desc_num(qh), qh->desc_list, - qh->desc_list_dma); + dma_unmap_single(hsotg->dev, qh->desc_list_dma, + qh->desc_list_sz, + DMA_FROM_DEVICE); + kfree(qh->desc_list); qh->desc_list = NULL; return -ENOMEM; } @@ -113,9 +114,9 @@ static int dwc2_desc_list_alloc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, static void dwc2_desc_list_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { if (qh->desc_list) { - dma_free_coherent(hsotg->dev, sizeof(struct dwc2_hcd_dma_desc) - * dwc2_max_desc_num(qh), qh->desc_list, - qh->desc_list_dma); + dma_unmap_single(hsotg->dev, qh->desc_list_dma, + qh->desc_list_sz, DMA_FROM_DEVICE); + kfree(qh->desc_list); qh->desc_list = NULL; } @@ -128,21 +129,20 @@ static int dwc2_frame_list_alloc(struct dwc2_hsotg *hsotg, gfp_t mem_flags) if (hsotg->frame_list) return 0; - hsotg->frame_list = dma_alloc_coherent(hsotg->dev, - 4 * FRLISTEN_64_SIZE, - &hsotg->frame_list_dma, - mem_flags); + hsotg->frame_list_sz = 4 * FRLISTEN_64_SIZE; + hsotg->frame_list = kzalloc(hsotg->frame_list_sz, GFP_ATOMIC | GFP_DMA); if (!hsotg->frame_list) return -ENOMEM; - memset(hsotg->frame_list, 0, 4 * FRLISTEN_64_SIZE); + hsotg->frame_list_dma = dma_map_single(hsotg->dev, hsotg->frame_list, + hsotg->frame_list_sz, + DMA_TO_DEVICE); + return 0; } static void dwc2_frame_list_free(struct dwc2_hsotg *hsotg) { - u32 *frame_list; - dma_addr_t frame_list_dma; unsigned long flags; spin_lock_irqsave(&hsotg->lock, flags); @@ -152,14 +152,14 @@ static void dwc2_frame_list_free(struct dwc2_hsotg *hsotg) return; } - frame_list = hsotg->frame_list; - frame_list_dma = hsotg->frame_list_dma; + dma_unmap_single(hsotg->dev, hsotg->frame_list_dma, + hsotg->frame_list_sz, DMA_FROM_DEVICE); + + kfree(hsotg->frame_list); hsotg->frame_list = NULL; spin_unlock_irqrestore(&hsotg->lock, flags); - dma_free_coherent(hsotg->dev, 4 * FRLISTEN_64_SIZE, frame_list, - frame_list_dma); } static void dwc2_per_sched_enable(struct dwc2_hsotg *hsotg, u32 fr_list_en) @@ -249,6 +249,15 @@ static void dwc2_update_frame_list(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, j = (j + inc) & (FRLISTEN_64_SIZE - 1); } while (j != i); + /* + * Sync frame list since controller will access it if periodic + * channel is currently enabled. + */ + dma_sync_single_for_device(hsotg->dev, + hsotg->frame_list_dma, + hsotg->frame_list_sz, + DMA_TO_DEVICE); + if (!enable) return; @@ -541,6 +550,11 @@ static void dwc2_fill_host_isoc_dma_desc(struct dwc2_hsotg *hsotg, dma_desc->status |= HOST_DMA_IOC; #endif + dma_sync_single_for_device(hsotg->dev, + qh->desc_list_dma + + (idx * sizeof(struct dwc2_hcd_dma_desc)), + sizeof(struct dwc2_hcd_dma_desc), + DMA_TO_DEVICE); } static void dwc2_init_isoc_dma_desc(struct dwc2_hsotg *hsotg, @@ -610,6 +624,11 @@ static void dwc2_init_isoc_dma_desc(struct dwc2_hsotg *hsotg, if (qh->ntd == ntd_max) { idx = dwc2_desclist_idx_dec(qh->td_last, inc, qh->dev_speed); qh->desc_list[idx].status |= HOST_DMA_IOC; + dma_sync_single_for_device(hsotg->dev, + qh->desc_list_dma + (idx * + sizeof(struct dwc2_hcd_dma_desc)), + sizeof(struct dwc2_hcd_dma_desc), + DMA_TO_DEVICE); } #else /* @@ -639,6 +658,11 @@ static void dwc2_init_isoc_dma_desc(struct dwc2_hsotg *hsotg, idx = dwc2_desclist_idx_dec(qh->td_last, inc, qh->dev_speed); qh->desc_list[idx].status |= HOST_DMA_IOC; + dma_sync_single_for_device(hsotg->dev, + qh->desc_list_dma + + (idx * sizeof(struct dwc2_hcd_dma_desc)), + sizeof(struct dwc2_hcd_dma_desc), + DMA_TO_DEVICE); #endif } @@ -676,6 +700,12 @@ static void dwc2_fill_host_dma_desc(struct dwc2_hsotg *hsotg, dma_desc->buf = (u32)chan->xfer_dma; + dma_sync_single_for_device(hsotg->dev, + qh->desc_list_dma + + (n_desc * sizeof(struct dwc2_hcd_dma_desc)), + sizeof(struct dwc2_hcd_dma_desc), + DMA_TO_DEVICE); + /* * Last (or only) descriptor of IN transfer with actual size less * than MaxPacket @@ -726,6 +756,12 @@ static void dwc2_init_non_isoc_dma_desc(struct dwc2_hsotg *hsotg, "set A bit in desc %d (%p)\n", n_desc - 1, &qh->desc_list[n_desc - 1]); + dma_sync_single_for_device(hsotg->dev, + qh->desc_list_dma + + ((n_desc - 1) * + sizeof(struct dwc2_hcd_dma_desc)), + sizeof(struct dwc2_hcd_dma_desc), + DMA_TO_DEVICE); } dwc2_fill_host_dma_desc(hsotg, chan, qtd, qh, n_desc); dev_vdbg(hsotg->dev, @@ -751,10 +787,19 @@ static void dwc2_init_non_isoc_dma_desc(struct dwc2_hsotg *hsotg, HOST_DMA_IOC | HOST_DMA_EOL | HOST_DMA_A; dev_vdbg(hsotg->dev, "set IOC/EOL/A bits in desc %d (%p)\n", n_desc - 1, &qh->desc_list[n_desc - 1]); + dma_sync_single_for_device(hsotg->dev, + qh->desc_list_dma + (n_desc - 1) * + sizeof(struct dwc2_hcd_dma_desc), + sizeof(struct dwc2_hcd_dma_desc), + DMA_TO_DEVICE); if (n_desc > 1) { qh->desc_list[0].status |= HOST_DMA_A; dev_vdbg(hsotg->dev, "set A bit in desc 0 (%p)\n", &qh->desc_list[0]); + dma_sync_single_for_device(hsotg->dev, + qh->desc_list_dma, + sizeof(struct dwc2_hcd_dma_desc), + DMA_TO_DEVICE); } chan->ntd = n_desc; } @@ -829,7 +874,7 @@ static int dwc2_cmpl_host_isoc_dma_desc(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, struct dwc2_qh *qh, u16 idx) { - struct dwc2_hcd_dma_desc *dma_desc = &qh->desc_list[idx]; + struct dwc2_hcd_dma_desc *dma_desc; struct dwc2_hcd_iso_packet_desc *frame_desc; u16 remain = 0; int rc = 0; @@ -837,6 +882,13 @@ static int dwc2_cmpl_host_isoc_dma_desc(struct dwc2_hsotg *hsotg, if (!qtd->urb) return -EINVAL; + dma_sync_single_for_cpu(hsotg->dev, qh->desc_list_dma + (idx * + sizeof(struct dwc2_hcd_dma_desc)), + sizeof(struct dwc2_hcd_dma_desc), + DMA_FROM_DEVICE); + + dma_desc = &qh->desc_list[idx]; + frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index_last]; dma_desc->buf = (u32)(qtd->urb->dma + frame_desc->offset); if (chan->ep_is_in) @@ -1092,6 +1144,12 @@ static int dwc2_process_non_isoc_desc(struct dwc2_hsotg *hsotg, if (!urb) return -EINVAL; + dma_sync_single_for_cpu(hsotg->dev, + qh->desc_list_dma + (desc_num * + sizeof(struct dwc2_hcd_dma_desc)), + sizeof(struct dwc2_hcd_dma_desc), + DMA_FROM_DEVICE); + dma_desc = &qh->desc_list[desc_num]; n_bytes = qh->n_bytes[desc_num]; dev_vdbg(hsotg->dev, -- GitLab From e23b8a54a440a2b8ee5c9dc3eb2099ecf813ef70 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Fri, 20 Nov 2015 11:49:30 +0100 Subject: [PATCH 1335/2855] usb: dwc2: host: fix descriptor list address masking Masks for HCDMA.CTD and HCDMA.DMAAddr are incorrect. As we always start from first descriptor, no need to mask the address anyway. Acked-by: John Youn Signed-off-by: Mian Yousaf Kaukab Signed-off-by: Gregory Herrero Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 10 +++------- drivers/usb/dwc2/hw.h | 4 ---- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 542c9e6d95db6..97de85521eb68 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -1905,7 +1905,6 @@ void dwc2_hc_start_transfer_ddma(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan) { u32 hcchar; - u32 hc_dma; u32 hctsiz = 0; if (chan->do_ping) @@ -1937,14 +1936,11 @@ void dwc2_hc_start_transfer_ddma(struct dwc2_hsotg *hsotg, dma_sync_single_for_device(hsotg->dev, chan->desc_list_addr, chan->desc_list_sz, DMA_TO_DEVICE); - hc_dma = (u32)chan->desc_list_addr & HCDMA_DMA_ADDR_MASK; + dwc2_writel(chan->desc_list_addr, hsotg->regs + HCDMA(chan->hc_num)); - /* Always start from first descriptor */ - hc_dma &= ~HCDMA_CTD_MASK; - dwc2_writel(hc_dma, hsotg->regs + HCDMA(chan->hc_num)); if (dbg_hc(chan)) - dev_vdbg(hsotg->dev, "Wrote %08x to HCDMA(%d)\n", - hc_dma, chan->hc_num); + dev_vdbg(hsotg->dev, "Wrote %pad to HCDMA(%d)\n", + &chan->desc_list_addr, chan->hc_num); hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num)); hcchar &= ~HCCHAR_MULTICNT_MASK; diff --git a/drivers/usb/dwc2/hw.h b/drivers/usb/dwc2/hw.h index 553f24606c43c..281b57b36ab44 100644 --- a/drivers/usb/dwc2/hw.h +++ b/drivers/usb/dwc2/hw.h @@ -769,10 +769,6 @@ #define TSIZ_XFERSIZE_SHIFT 0 #define HCDMA(_ch) HSOTG_REG(0x0514 + 0x20 * (_ch)) -#define HCDMA_DMA_ADDR_MASK (0x1fffff << 11) -#define HCDMA_DMA_ADDR_SHIFT 11 -#define HCDMA_CTD_MASK (0xff << 3) -#define HCDMA_CTD_SHIFT 3 #define HCDMAB(_ch) HSOTG_REG(0x051c + 0x20 * (_ch)) -- GitLab From 3b5fcc9ac2f4453a5609cc89ac7618b1b27ccb01 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Fri, 20 Nov 2015 11:49:31 +0100 Subject: [PATCH 1336/2855] usb: dwc2: host: use kmem cache to allocate descriptors Kmem caches help to get correct boundary for descriptor buffers which need to be 512 bytes aligned for dwc2 controller. Two kmem caches are needed for generic descriptors and for hs isochronous descriptors which doesn't have same size. Acked-by: John Youn Signed-off-by: Gregory Herrero Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.h | 4 +++ drivers/usb/dwc2/hcd.c | 50 ++++++++++++++++++++++++++++++++++++- drivers/usb/dwc2/hcd_ddma.c | 20 +++++++++++++-- 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index e7cc54268f2f5..baee2bc1e8a88 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -686,6 +686,8 @@ struct dwc2_hregs_backup { * @frame_list: Frame list * @frame_list_dma: Frame list DMA address * @frame_list_sz: Frame list size + * @desc_gen_cache: Kmem cache for generic descriptors + * @desc_hsisoc_cache: Kmem cache for hs isochronous descriptors * * These are for peripheral mode: * @@ -806,6 +808,8 @@ struct dwc2_hsotg { u32 *frame_list; dma_addr_t frame_list_dma; u32 frame_list_sz; + struct kmem_cache *desc_gen_cache; + struct kmem_cache *desc_hsisoc_cache; #ifdef DEBUG u32 frrem_samples; diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 7fd4f41e12a79..b2afe913d5593 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -3146,6 +3146,47 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq) if (!hsotg->status_buf) goto error3; + /* + * Create kmem caches to handle descriptor buffers in descriptor + * DMA mode. + * Alignment must be set to 512 bytes. + */ + if (hsotg->core_params->dma_desc_enable || + hsotg->core_params->dma_desc_fs_enable) { + hsotg->desc_gen_cache = kmem_cache_create("dwc2-gen-desc", + sizeof(struct dwc2_hcd_dma_desc) * + MAX_DMA_DESC_NUM_GENERIC, 512, SLAB_CACHE_DMA, + NULL); + if (!hsotg->desc_gen_cache) { + dev_err(hsotg->dev, + "unable to create dwc2 generic desc cache\n"); + + /* + * Disable descriptor dma mode since it will not be + * usable. + */ + hsotg->core_params->dma_desc_enable = 0; + hsotg->core_params->dma_desc_fs_enable = 0; + } + + hsotg->desc_hsisoc_cache = kmem_cache_create("dwc2-hsisoc-desc", + sizeof(struct dwc2_hcd_dma_desc) * + MAX_DMA_DESC_NUM_HS_ISOC, 512, 0, NULL); + if (!hsotg->desc_hsisoc_cache) { + dev_err(hsotg->dev, + "unable to create dwc2 hs isoc desc cache\n"); + + kmem_cache_destroy(hsotg->desc_gen_cache); + + /* + * Disable descriptor dma mode since it will not be + * usable. + */ + hsotg->core_params->dma_desc_enable = 0; + hsotg->core_params->dma_desc_fs_enable = 0; + } + } + hsotg->otg_port = 1; hsotg->frame_list = NULL; hsotg->frame_list_dma = 0; @@ -3169,7 +3210,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq) */ retval = usb_add_hcd(hcd, irq, IRQF_SHARED); if (retval < 0) - goto error3; + goto error4; device_wakeup_enable(hcd->self.controller); @@ -3179,6 +3220,9 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq) return 0; +error4: + kmem_cache_destroy(hsotg->desc_gen_cache); + kmem_cache_destroy(hsotg->desc_hsisoc_cache); error3: dwc2_hcd_release(hsotg); error2: @@ -3219,6 +3263,10 @@ void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) usb_remove_hcd(hcd); hsotg->priv = NULL; + + kmem_cache_destroy(hsotg->desc_gen_cache); + kmem_cache_destroy(hsotg->desc_hsisoc_cache); + dwc2_hcd_release(hsotg); usb_put_hcd(hcd); diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c index 85d7816d29f1d..36606fc33c0d3 100644 --- a/drivers/usb/dwc2/hcd_ddma.c +++ b/drivers/usb/dwc2/hcd_ddma.c @@ -87,10 +87,18 @@ static u16 dwc2_frame_incr_val(struct dwc2_qh *qh) static int dwc2_desc_list_alloc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, gfp_t flags) { + struct kmem_cache *desc_cache; + + if (qh->ep_type == USB_ENDPOINT_XFER_ISOC + && qh->dev_speed == USB_SPEED_HIGH) + desc_cache = hsotg->desc_hsisoc_cache; + else + desc_cache = hsotg->desc_gen_cache; + qh->desc_list_sz = sizeof(struct dwc2_hcd_dma_desc) * dwc2_max_desc_num(qh); - qh->desc_list = kzalloc(qh->desc_list_sz, flags | GFP_DMA); + qh->desc_list = kmem_cache_zalloc(desc_cache, flags | GFP_DMA); if (!qh->desc_list) return -ENOMEM; @@ -113,10 +121,18 @@ static int dwc2_desc_list_alloc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, static void dwc2_desc_list_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { + struct kmem_cache *desc_cache; + + if (qh->ep_type == USB_ENDPOINT_XFER_ISOC + && qh->dev_speed == USB_SPEED_HIGH) + desc_cache = hsotg->desc_hsisoc_cache; + else + desc_cache = hsotg->desc_gen_cache; + if (qh->desc_list) { dma_unmap_single(hsotg->dev, qh->desc_list_dma, qh->desc_list_sz, DMA_FROM_DEVICE); - kfree(qh->desc_list); + kmem_cache_free(desc_cache, qh->desc_list); qh->desc_list = NULL; } -- GitLab From 37dd9d65cc41fcc7e77645a1cdf2659472809b96 Mon Sep 17 00:00:00 2001 From: Zhangfei Gao Date: Wed, 18 Nov 2015 15:39:47 +0800 Subject: [PATCH 1337/2855] usb: dwc2: add support of hi6220 Support hisilicon,hi6220-usb for HiKey board Acked-by: Rob Herring Acked-by: John Youn Signed-off-by: Zhangfei Gao Signed-off-by: Felipe Balbi --- .../devicetree/bindings/usb/dwc2.txt | 1 + drivers/usb/dwc2/platform.c | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt index fd132cbee70ea..221368207ca4c 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.txt +++ b/Documentation/devicetree/bindings/usb/dwc2.txt @@ -4,6 +4,7 @@ Platform DesignWare HS OTG USB 2.0 controller Required properties: - compatible : One of: - brcm,bcm2835-usb: The DWC2 USB controller instance in the BCM2835 SoC. + - hisilicon,hi6220-usb: The DWC2 USB controller instance in the hi6220 SoC. - rockchip,rk3066-usb: The DWC2 USB controller instance in the rk3066 Soc; - "rockchip,rk3188-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3188 Soc; - "rockchip,rk3288-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3288 Soc; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 095bc05f76cae..5df2adf6f4e7d 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -54,6 +54,38 @@ static const char dwc2_driver_name[] = "dwc2"; +static const struct dwc2_core_params params_hi6220 = { + .otg_cap = 2, /* No HNP/SRP capable */ + .otg_ver = 0, /* 1.3 */ + .dma_enable = 1, + .dma_desc_enable = 0, + .dma_desc_fs_enable = 0, + .speed = 0, /* High Speed */ + .enable_dynamic_fifo = 1, + .en_multiple_tx_fifo = 1, + .host_rx_fifo_size = 512, + .host_nperio_tx_fifo_size = 512, + .host_perio_tx_fifo_size = 512, + .max_transfer_size = 65535, + .max_packet_count = 511, + .host_channels = 16, + .phy_type = 1, /* UTMI */ + .phy_utmi_width = 8, + .phy_ulpi_ddr = 0, /* Single */ + .phy_ulpi_ext_vbus = 0, + .i2c_enable = 0, + .ulpi_fs_ls = 0, + .host_support_fs_ls_low_power = 0, + .host_ls_low_power_phy_clk = 0, /* 48 MHz */ + .ts_dline = 0, + .reload_ctl = 0, + .ahbcfg = GAHBCFG_HBSTLEN_INCR16 << + GAHBCFG_HBSTLEN_SHIFT, + .uframe_sched = 0, + .external_id_pin_ctl = -1, + .hibernation = -1, +}; + static const struct dwc2_core_params params_bcm2835 = { .otg_cap = 0, /* HNP/SRP capable */ .otg_ver = 0, /* 1.3 */ @@ -310,6 +342,7 @@ static int dwc2_driver_remove(struct platform_device *dev) static const struct of_device_id dwc2_of_match_table[] = { { .compatible = "brcm,bcm2835-usb", .data = ¶ms_bcm2835 }, + { .compatible = "hisilicon,hi6220-usb", .data = ¶ms_hi6220 }, { .compatible = "rockchip,rk3066-usb", .data = ¶ms_rk3066 }, { .compatible = "snps,dwc2", .data = NULL }, { .compatible = "samsung,s3c6400-hsotg", .data = NULL}, -- GitLab From 6a6595318ac2dd169d2931a1d9431a64f4ada75c Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Thu, 19 Nov 2015 13:23:14 -0800 Subject: [PATCH 1338/2855] usb: dwc2: host: Fix missing device insertions If you've got your interrupt signals bouncing a bit as you insert your USB device, you might end up in a state when the device is connected but the driver doesn't know it. Specifically, the observed order is: 1. hardware sees connect 2. hardware sees disconnect 3. hardware sees connect 4. dwc2_port_intr() - clears connect interrupt 5. dwc2_handle_common_intr() - calls dwc2_hcd_disconnect() Now you'll be stuck with the cable plugged in and no further interrupts coming in but the driver will think we're disconnected. We'll fix this by checking for the missing connect interrupt and re-connecting after the disconnect is posted. We don't skip the disconnect because if there is a transitory disconnect we really want to de-enumerate and re-enumerate. Notes: 1. As part of this change we add a "force" parameter to dwc2_hcd_disconnect() so that when we're unloading the module we avoid the new behavior. The need for this was pointed out by John Youn. 2. The bit of code needed at the end of dwc2_hcd_disconnect() is exactly the same bit of code from dwc2_port_intr(). To avoid duplication, we refactor that code out into a new function dwc2_hcd_connect(). Signed-off-by: Douglas Anderson Acked-by: John Youn Tested-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.h | 6 ++++-- drivers/usb/dwc2/core_intr.c | 4 ++-- drivers/usb/dwc2/hcd.c | 40 ++++++++++++++++++++++++++++++++++-- drivers/usb/dwc2/hcd_intr.c | 6 +----- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index baee2bc1e8a88..05f01785de05d 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -1180,12 +1180,14 @@ static inline int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) extern int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg); -extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg); +extern void dwc2_hcd_connect(struct dwc2_hsotg *hsotg); +extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force); extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg); #else static inline int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) { return 0; } -static inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg) {} +static inline void dwc2_hcd_connect(struct dwc2_hsotg *hsotg) {} +static inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force) {} static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {} static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {} static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 27daa42788b1a..61601d16e233f 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -239,7 +239,7 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "a_suspend->a_peripheral (%d)\n", hsotg->op_state); spin_unlock(&hsotg->lock); - dwc2_hcd_disconnect(hsotg); + dwc2_hcd_disconnect(hsotg, false); spin_lock(&hsotg->lock); hsotg->op_state = OTG_STATE_A_PERIPHERAL; } else { @@ -401,7 +401,7 @@ static void dwc2_handle_disconnect_intr(struct dwc2_hsotg *hsotg) dwc2_op_state_str(hsotg)); if (hsotg->op_state == OTG_STATE_A_HOST) - dwc2_hcd_disconnect(hsotg); + dwc2_hcd_disconnect(hsotg, false); dwc2_writel(GINTSTS_DISCONNINT, hsotg->regs + GINTSTS); } diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index b2afe913d5593..cbfdcb804adb0 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -267,16 +267,34 @@ static void dwc2_hcd_cleanup_channels(struct dwc2_hsotg *hsotg) } } +/** + * dwc2_hcd_connect() - Handles connect of the HCD + * + * @hsotg: Pointer to struct dwc2_hsotg + * + * Must be called with interrupt disabled and spinlock held + */ +void dwc2_hcd_connect(struct dwc2_hsotg *hsotg) +{ + if (hsotg->lx_state != DWC2_L0) + usb_hcd_resume_root_hub(hsotg->priv); + + hsotg->flags.b.port_connect_status_change = 1; + hsotg->flags.b.port_connect_status = 1; +} + /** * dwc2_hcd_disconnect() - Handles disconnect of the HCD * * @hsotg: Pointer to struct dwc2_hsotg + * @force: If true, we won't try to reconnect even if we see device connected. * * Must be called with interrupt disabled and spinlock held */ -void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg) +void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force) { u32 intr; + u32 hprt0; /* Set status flags for the hub driver */ hsotg->flags.b.port_connect_status_change = 1; @@ -315,6 +333,24 @@ void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg) dwc2_hcd_cleanup_channels(hsotg); dwc2_host_disconnect(hsotg); + + /* + * Add an extra check here to see if we're actually connected but + * we don't have a detection interrupt pending. This can happen if: + * 1. hardware sees connect + * 2. hardware sees disconnect + * 3. hardware sees connect + * 4. dwc2_port_intr() - clears connect interrupt + * 5. dwc2_handle_common_intr() - calls here + * + * Without the extra check here we will end calling disconnect + * and won't get any future interrupts to handle the connect. + */ + if (!force) { + hprt0 = dwc2_readl(hsotg->regs + HPRT0); + if (!(hprt0 & HPRT0_CONNDET) && (hprt0 & HPRT0_CONNSTS)) + dwc2_hcd_connect(hsotg); + } } /** @@ -2390,7 +2426,7 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) spin_lock_irqsave(&hsotg->lock, flags); /* Ensure hcd is disconnected */ - dwc2_hcd_disconnect(hsotg); + dwc2_hcd_disconnect(hsotg, true); dwc2_hcd_stop(hsotg); hsotg->lx_state = DWC2_L3; hcd->state = HC_STATE_HALT; diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index 7c15f03b069c5..a1eb48e548583 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c @@ -350,11 +350,7 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg) dev_vdbg(hsotg->dev, "--Port Interrupt HPRT0=0x%08x Port Connect Detected--\n", hprt0); - if (hsotg->lx_state != DWC2_L0) - usb_hcd_resume_root_hub(hsotg->priv); - - hsotg->flags.b.port_connect_status_change = 1; - hsotg->flags.b.port_connect_status = 1; + dwc2_hcd_connect(hsotg); hprt0_modify |= HPRT0_CONNDET; /* -- GitLab From 69b76cdff592058ea445cd40e18c75dffaba4cb9 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Wed, 11 Nov 2015 10:33:52 -0800 Subject: [PATCH 1339/2855] usb: dwc2: host: Support immediate retries for split transactions In some cases, like when you've got a "Microsoft Wireless Keyboard 2000" connected to dwc2 with a hub, expected that we'll get some transfer errors sometimes. The controller is expected to try at least 3 times before giving up. See figure "Figure A-67. Normal HS CSPLIT 3 Strikes Smash" in the USB spec. The dwc2 controller has a way to support this by using the "EC_MC" field. The Raspberry Pi driver has logic for setting this right. See fiq_fsm_queue_split_transaction() in their "dwc_otg_hcd.c". Let's use the same logic. After making this change, we no longer get dropped characters from the above mentioned keyboard. Other devices on the same bus as the keyboard also behave more properly. Thanks for Julius Werner for the expert analysis and suggestions. Acked-by: John Youn Signed-off-by: Douglas Anderson Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 97de85521eb68..0a9ebe00fbcca 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -1707,6 +1707,7 @@ void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg, u32 hcchar; u32 hctsiz = 0; u16 num_packets; + u32 ec_mc; if (dbg_hc(chan)) dev_vdbg(hsotg->dev, "%s()\n", __func__); @@ -1743,6 +1744,13 @@ void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg, hctsiz |= chan->xfer_len << TSIZ_XFERSIZE_SHIFT & TSIZ_XFERSIZE_MASK; + + /* For split set ec_mc for immediate retries */ + if (chan->ep_type == USB_ENDPOINT_XFER_INT || + chan->ep_type == USB_ENDPOINT_XFER_ISOC) + ec_mc = 3; + else + ec_mc = 1; } else { if (dbg_hc(chan)) dev_vdbg(hsotg->dev, "no split\n"); @@ -1805,6 +1813,9 @@ void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg, hctsiz |= chan->xfer_len << TSIZ_XFERSIZE_SHIFT & TSIZ_XFERSIZE_MASK; + + /* The ec_mc gets the multi_count for non-split */ + ec_mc = chan->multi_count; } chan->start_pkt_count = num_packets; @@ -1855,8 +1866,7 @@ void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg, hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num)); hcchar &= ~HCCHAR_MULTICNT_MASK; - hcchar |= chan->multi_count << HCCHAR_MULTICNT_SHIFT & - HCCHAR_MULTICNT_MASK; + hcchar |= (ec_mc << HCCHAR_MULTICNT_SHIFT) & HCCHAR_MULTICNT_MASK; dwc2_hc_set_even_odd_frame(hsotg, chan, &hcchar); if (hcchar & HCCHAR_CHDIS) -- GitLab From 0aecfc1b359dffddf74bd0e0ea5ee47066d210ac Mon Sep 17 00:00:00 2001 From: Igor Kotrasinski Date: Tue, 20 Oct 2015 18:33:13 +0200 Subject: [PATCH 1340/2855] usb: gadget: composite: remove redundant bcdUSB setting in legacy Since composite now overwrites bcdUSB for any gadget, remove setting it in legacy gadgets. All legacy gadgets set 0x0200, the same as the value additionally set by composite, so there is no behaviour change. Signed-off-by: Igor Kotrasinski Rebase onto current balbi/next Signed-off-by: Krzysztof Opasiak Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/acm_ms.c | 2 +- drivers/usb/gadget/legacy/audio.c | 2 +- drivers/usb/gadget/legacy/cdc2.c | 2 +- drivers/usb/gadget/legacy/ether.c | 2 +- drivers/usb/gadget/legacy/g_ffs.c | 2 +- drivers/usb/gadget/legacy/gmidi.c | 2 +- drivers/usb/gadget/legacy/hid.c | 2 +- drivers/usb/gadget/legacy/mass_storage.c | 2 +- drivers/usb/gadget/legacy/multi.c | 2 +- drivers/usb/gadget/legacy/ncm.c | 2 +- drivers/usb/gadget/legacy/nokia.c | 2 +- drivers/usb/gadget/legacy/printer.c | 2 +- drivers/usb/gadget/legacy/serial.c | 2 +- drivers/usb/gadget/legacy/tcm_usb_gadget.c | 2 +- drivers/usb/gadget/legacy/webcam.c | 2 +- drivers/usb/gadget/legacy/zero.c | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/usb/gadget/legacy/acm_ms.c b/drivers/usb/gadget/legacy/acm_ms.c index 4b158e2d1e57b..c16089efc3224 100644 --- a/drivers/usb/gadget/legacy/acm_ms.c +++ b/drivers/usb/gadget/legacy/acm_ms.c @@ -40,7 +40,7 @@ static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16(0x0200), + /* .bcdUSB = DYNAMIC */ .bDeviceClass = USB_CLASS_MISC /* 0xEF */, .bDeviceSubClass = 2, diff --git a/drivers/usb/gadget/legacy/audio.c b/drivers/usb/gadget/legacy/audio.c index 685cf3b4b78f8..5d7b3c6a422ba 100644 --- a/drivers/usb/gadget/legacy/audio.c +++ b/drivers/usb/gadget/legacy/audio.c @@ -123,7 +123,7 @@ static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16(0x200), + /* .bcdUSB = DYNAMIC */ #ifdef CONFIG_GADGET_UAC1 .bDeviceClass = USB_CLASS_PER_INTERFACE, diff --git a/drivers/usb/gadget/legacy/cdc2.c b/drivers/usb/gadget/legacy/cdc2.c index ecd8c8d62f2e9..51c08682de846 100644 --- a/drivers/usb/gadget/legacy/cdc2.c +++ b/drivers/usb/gadget/legacy/cdc2.c @@ -43,7 +43,7 @@ static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16(0x0200), + /* .bcdUSB = DYNAMIC */ .bDeviceClass = USB_CLASS_COMM, .bDeviceSubClass = 0, diff --git a/drivers/usb/gadget/legacy/ether.c b/drivers/usb/gadget/legacy/ether.c index 31e9160223e9a..25a2c2e485920 100644 --- a/drivers/usb/gadget/legacy/ether.c +++ b/drivers/usb/gadget/legacy/ether.c @@ -151,7 +151,7 @@ static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16 (0x0200), + /* .bcdUSB = DYNAMIC */ .bDeviceClass = USB_CLASS_COMM, .bDeviceSubClass = 0, diff --git a/drivers/usb/gadget/legacy/g_ffs.c b/drivers/usb/gadget/legacy/g_ffs.c index 320a81b2baa68..f85639ef8a8f6 100644 --- a/drivers/usb/gadget/legacy/g_ffs.c +++ b/drivers/usb/gadget/legacy/g_ffs.c @@ -69,7 +69,7 @@ static struct usb_device_descriptor gfs_dev_desc = { .bLength = sizeof gfs_dev_desc, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16(0x0200), + /* .bcdUSB = DYNAMIC */ .bDeviceClass = USB_CLASS_PER_INTERFACE, .idVendor = cpu_to_le16(GFS_VENDOR_ID), diff --git a/drivers/usb/gadget/legacy/gmidi.c b/drivers/usb/gadget/legacy/gmidi.c index be8e91d68e146..e27aad5e50b9a 100644 --- a/drivers/usb/gadget/legacy/gmidi.c +++ b/drivers/usb/gadget/legacy/gmidi.c @@ -78,7 +78,7 @@ MODULE_PARM_DESC(out_ports, "Number of MIDI output ports"); static struct usb_device_descriptor device_desc = { .bLength = USB_DT_DEVICE_SIZE, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16(0x0200), + /* .bcdUSB = DYNAMIC */ .bDeviceClass = USB_CLASS_PER_INTERFACE, .idVendor = cpu_to_le16(DRIVER_VENDOR_NUM), .idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM), diff --git a/drivers/usb/gadget/legacy/hid.c b/drivers/usb/gadget/legacy/hid.c index 7e5d2c48476e5..a71a884f79fc7 100644 --- a/drivers/usb/gadget/legacy/hid.c +++ b/drivers/usb/gadget/legacy/hid.c @@ -47,7 +47,7 @@ static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16(0x0200), + /* .bcdUSB = DYNAMIC */ /* .bDeviceClass = USB_CLASS_COMM, */ /* .bDeviceSubClass = 0, */ diff --git a/drivers/usb/gadget/legacy/mass_storage.c b/drivers/usb/gadget/legacy/mass_storage.c index bda3c519110fe..e61af53c7d2b3 100644 --- a/drivers/usb/gadget/legacy/mass_storage.c +++ b/drivers/usb/gadget/legacy/mass_storage.c @@ -55,7 +55,7 @@ static struct usb_device_descriptor msg_device_desc = { .bLength = sizeof msg_device_desc, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16(0x0200), + /* .bcdUSB = DYNAMIC */ .bDeviceClass = USB_CLASS_PER_INTERFACE, /* Vendor and product id can be overridden by module parameters. */ diff --git a/drivers/usb/gadget/legacy/multi.c b/drivers/usb/gadget/legacy/multi.c index 4fe794ddcd49c..229d704a620b3 100644 --- a/drivers/usb/gadget/legacy/multi.c +++ b/drivers/usb/gadget/legacy/multi.c @@ -67,7 +67,7 @@ static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16(0x0200), + /* .bcdUSB = DYNAMIC */ .bDeviceClass = USB_CLASS_MISC /* 0xEF */, .bDeviceSubClass = 2, diff --git a/drivers/usb/gadget/legacy/ncm.c b/drivers/usb/gadget/legacy/ncm.c index 2bae4381332d5..0aba68253e3d6 100644 --- a/drivers/usb/gadget/legacy/ncm.c +++ b/drivers/usb/gadget/legacy/ncm.c @@ -49,7 +49,7 @@ static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16 (0x0200), + /* .bcdUSB = DYNAMIC */ .bDeviceClass = USB_CLASS_COMM, .bDeviceSubClass = 0, diff --git a/drivers/usb/gadget/legacy/nokia.c b/drivers/usb/gadget/legacy/nokia.c index 8b3f6fb1825d5..09975046c6941 100644 --- a/drivers/usb/gadget/legacy/nokia.c +++ b/drivers/usb/gadget/legacy/nokia.c @@ -89,7 +89,7 @@ static struct usb_gadget_strings *dev_strings[] = { static struct usb_device_descriptor device_desc = { .bLength = USB_DT_DEVICE_SIZE, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16(0x0200), + /* .bcdUSB = DYNAMIC */ .bDeviceClass = USB_CLASS_COMM, .idVendor = cpu_to_le16(NOKIA_VENDOR_ID), .idProduct = cpu_to_le16(NOKIA_PRODUCT_ID), diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index a22d30a4def1e..6f969a86175c3 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -71,7 +71,7 @@ static struct usb_function *f_printer; static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16(0x0200), + /* .bcdUSB = DYNAMIC */ .bDeviceClass = USB_CLASS_PER_INTERFACE, .bDeviceSubClass = 0, .bDeviceProtocol = 0, diff --git a/drivers/usb/gadget/legacy/serial.c b/drivers/usb/gadget/legacy/serial.c index c5d42e0347a94..9d89adce756d1 100644 --- a/drivers/usb/gadget/legacy/serial.c +++ b/drivers/usb/gadget/legacy/serial.c @@ -65,7 +65,7 @@ static struct usb_gadget_strings *dev_strings[] = { static struct usb_device_descriptor device_desc = { .bLength = USB_DT_DEVICE_SIZE, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16(0x0200), + /* .bcdUSB = DYNAMIC */ /* .bDeviceClass = f(use_acm) */ .bDeviceSubClass = 0, .bDeviceProtocol = 0, diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index 22e56158d5850..7857fa411636b 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c @@ -1974,7 +1974,7 @@ static struct usb_descriptor_header *uasp_ss_function_desc[] = { static struct usb_device_descriptor usbg_device_desc = { .bLength = sizeof(usbg_device_desc), .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16(0x0200), + /* .bcdUSB = DYNAMIC */ .bDeviceClass = USB_CLASS_PER_INTERFACE, .idVendor = cpu_to_le16(UAS_VENDOR_ID), .idProduct = cpu_to_le16(UAS_PRODUCT_ID), diff --git a/drivers/usb/gadget/legacy/webcam.c b/drivers/usb/gadget/legacy/webcam.c index 72c976bf3530f..f9661cd627c8e 100644 --- a/drivers/usb/gadget/legacy/webcam.c +++ b/drivers/usb/gadget/legacy/webcam.c @@ -77,7 +77,7 @@ static struct usb_function *f_uvc; static struct usb_device_descriptor webcam_device_descriptor = { .bLength = USB_DT_DEVICE_SIZE, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16(0x0200), + /* .bcdUSB = DYNAMIC */ .bDeviceClass = USB_CLASS_MISC, .bDeviceSubClass = 0x02, .bDeviceProtocol = 0x01, diff --git a/drivers/usb/gadget/legacy/zero.c b/drivers/usb/gadget/legacy/zero.c index 0ccdcd9c64a59..d02e2ce73ea5f 100644 --- a/drivers/usb/gadget/legacy/zero.c +++ b/drivers/usb/gadget/legacy/zero.c @@ -115,7 +115,7 @@ static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16(0x0200), + /* .bcdUSB = DYNAMIC */ .bDeviceClass = USB_CLASS_VENDOR_SPEC, .idVendor = cpu_to_le16(DRIVER_VENDOR_NUM), -- GitLab From fa4dce2022241f3c938372af0faf9d263061f6a9 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 19 Nov 2015 15:02:19 +0800 Subject: [PATCH 1341/2855] usb: gadget: f_sourcesink: quit if usb_ep_queue returns error Since now, we may have more than one request during the test, and it is better we just quit once the error occurs instead of try queueing further requests. Signed-off-by: Peter Chen Suggested-by: Krzysztof Opasiak Reviewed-by: Krzysztof Opasiak Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_sourcesink.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index 12e3eb4ee140e..242ba5caffe58 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -629,6 +629,7 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in, is_iso ? "ISO-" : "", is_in ? "IN" : "OUT", ep->name, status); free_ep_req(ep, req); + return status; } } -- GitLab From 98bfb39466954c69d2a448e6ddcab6d91cd48e25 Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Tue, 3 Nov 2015 11:51:15 -0600 Subject: [PATCH 1342/2855] usb: of: add an api to get dr_mode by the phy node Some USB phy drivers have different handling for the controller in each dr_mode. But the phy driver does not have visibility to the dr_mode of the controller. This adds an api to return the dr_mode of the controller which associates the given phy node. Signed-off-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/common/common.c | 60 +++++++++++++++++++++++++++++++++---- include/linux/usb/of.h | 5 ++++ 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c index 673d53038ed22..e6ec125e44850 100644 --- a/drivers/usb/common/common.c +++ b/drivers/usb/common/common.c @@ -17,6 +17,7 @@ #include #include #include +#include const char *usb_otg_state_string(enum usb_otg_state state) { @@ -106,24 +107,71 @@ static const char *const usb_dr_modes[] = { [USB_DR_MODE_OTG] = "otg", }; +static enum usb_dr_mode usb_get_dr_mode_from_string(const char *str) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++) + if (!strcmp(usb_dr_modes[i], str)) + return i; + + return USB_DR_MODE_UNKNOWN; +} + enum usb_dr_mode usb_get_dr_mode(struct device *dev) { const char *dr_mode; - int err, i; + int err; err = device_property_read_string(dev, "dr_mode", &dr_mode); if (err < 0) return USB_DR_MODE_UNKNOWN; - for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++) - if (!strcmp(dr_mode, usb_dr_modes[i])) - return i; - - return USB_DR_MODE_UNKNOWN; + return usb_get_dr_mode_from_string(dr_mode); } EXPORT_SYMBOL_GPL(usb_get_dr_mode); #ifdef CONFIG_OF +/** + * of_usb_get_dr_mode_by_phy - Get dual role mode for the controller device + * which is associated with the given phy device_node + * @np: Pointer to the given phy device_node + * + * In dts a usb controller associates with phy devices. The function gets + * the string from property 'dr_mode' of the controller associated with the + * given phy device node, and returns the correspondig enum usb_dr_mode. + */ +enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np) +{ + struct device_node *controller = NULL; + struct device_node *phy; + const char *dr_mode; + int index; + int err; + + do { + controller = of_find_node_with_property(controller, "phys"); + index = 0; + do { + phy = of_parse_phandle(controller, "phys", index); + of_node_put(phy); + if (phy == phy_np) + goto finish; + index++; + } while (phy); + } while (controller); + +finish: + err = of_property_read_string(controller, "dr_mode", &dr_mode); + of_node_put(controller); + + if (err < 0) + return USB_DR_MODE_UNKNOWN; + + return usb_get_dr_mode_from_string(dr_mode); +} +EXPORT_SYMBOL_GPL(of_usb_get_dr_mode_by_phy); + /** * of_usb_host_tpl_support - to get if Targeted Peripheral List is supported * for given targeted hosts (non-PC hosts) diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h index c3fe9e48ce27c..3805757dcdc26 100644 --- a/include/linux/usb/of.h +++ b/include/linux/usb/of.h @@ -12,10 +12,15 @@ #include #if IS_ENABLED(CONFIG_OF) +enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np); bool of_usb_host_tpl_support(struct device_node *np); int of_usb_update_otg_caps(struct device_node *np, struct usb_otg_caps *otg_caps); #else +enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np) +{ + return USB_DR_MODE_UNKNOWN; +} static inline bool of_usb_host_tpl_support(struct device_node *np) { return false; -- GitLab From 4a065c7bdbec9536f7b899241b125b9c3b5ba97a Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Fri, 20 Nov 2015 09:06:27 -0800 Subject: [PATCH 1343/2855] usb: dwc2: host: Add missing spinlock in dwc2_hcd_reset_func() The dwc2_hcd_reset_func() function is only ever called directly by a delayed work function. As such no locks are already held when the function is called. Doing a read-modify-write of CPU registers and setting fields in the main hsotg data structure is a bad idea without locks. Let's add locks. The bug was found by code inspection only. It turns out that the dwc2_hcd_reset_func() is only ever called today if the "host_support_fs_ls_low_power" parameter is enabled and no code in mainline enables that parameter. Thus no known issues in mainline are fixed by this patch, but it's still probably wise to fix the function. Signed-off-by: Douglas Anderson Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index cbfdcb804adb0..880b549f737ae 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -2358,13 +2358,19 @@ static void dwc2_hcd_reset_func(struct work_struct *work) { struct dwc2_hsotg *hsotg = container_of(work, struct dwc2_hsotg, reset_work.work); + unsigned long flags; u32 hprt0; dev_dbg(hsotg->dev, "USB RESET function called\n"); + + spin_lock_irqsave(&hsotg->lock, flags); + hprt0 = dwc2_read_hprt0(hsotg); hprt0 &= ~HPRT0_RST; dwc2_writel(hprt0, hsotg->regs + HPRT0); hsotg->flags.b.port_reset_change = 1; + + spin_unlock_irqrestore(&hsotg->lock, flags); } /* -- GitLab From 29539019b46f0e5f64f80f2e9dc8f9bb34d16b4b Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Fri, 20 Nov 2015 09:06:28 -0800 Subject: [PATCH 1344/2855] usb: dwc2: host: Clear interrupts before handling them In general it is wise to clear interrupts before processing them. If you don't do that, you can get: 1. Interrupt happens 2. You look at system state and process interrupt 3. A new interrupt happens 4. You clear interrupt without processing it. This patch was actually a first attempt to fix missing device insertions as described in (usb: dwc2: host: Fix missing device insertions) and it did solve some of the signal bouncing problems but not all of them (which is why I submitted the other patch). Specifically, this patch itself would sometimes change: 1. hardware sees connect 2. hardware sees disconnect 3. hardware sees connect 4. dwc2_port_intr() - clears connect interrupt 5. dwc2_handle_common_intr() - calls dwc2_hcd_disconnect() ...to: 1. hardware sees connect 2. hardware sees disconnect 3. dwc2_port_intr() - clears connect interrupt 4. hardware sees connect 5. dwc2_handle_common_intr() - calls dwc2_hcd_disconnect() ...but with different timing then sometimes we'd still miss cable insertions. In any case, though this patch doesn't fix any (known) problems, it still seems wise as a general policy to clear interrupt before handling them. Note that for dwc2_handle_usb_port_intr(), instead of moving the clear of PRTINT to the beginning of the function we remove it completely. The only way to clear PRTINT is to clear the sources that set it in the first place. Signed-off-by: Douglas Anderson Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core_intr.c | 49 +++++++++++++++++------------------- drivers/usb/dwc2/hcd_intr.c | 18 ++++++------- 2 files changed, 32 insertions(+), 35 deletions(-) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 61601d16e233f..d85c5c9f96c1d 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -86,9 +86,6 @@ static void dwc2_handle_usb_port_intr(struct dwc2_hsotg *hsotg) hprt0 &= ~HPRT0_ENA; dwc2_writel(hprt0, hsotg->regs + HPRT0); } - - /* Clear interrupt */ - dwc2_writel(GINTSTS_PRTINT, hsotg->regs + GINTSTS); } /** @@ -98,11 +95,11 @@ static void dwc2_handle_usb_port_intr(struct dwc2_hsotg *hsotg) */ static void dwc2_handle_mode_mismatch_intr(struct dwc2_hsotg *hsotg) { - dev_warn(hsotg->dev, "Mode Mismatch Interrupt: currently in %s mode\n", - dwc2_is_host_mode(hsotg) ? "Host" : "Device"); - /* Clear interrupt */ dwc2_writel(GINTSTS_MODEMIS, hsotg->regs + GINTSTS); + + dev_warn(hsotg->dev, "Mode Mismatch Interrupt: currently in %s mode\n", + dwc2_is_host_mode(hsotg) ? "Host" : "Device"); } /** @@ -276,9 +273,13 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) */ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) { - u32 gintmsk = dwc2_readl(hsotg->regs + GINTMSK); + u32 gintmsk; + + /* Clear interrupt */ + dwc2_writel(GINTSTS_CONIDSTSCHNG, hsotg->regs + GINTSTS); /* Need to disable SOF interrupt immediately */ + gintmsk = dwc2_readl(hsotg->regs + GINTMSK); gintmsk &= ~GINTSTS_SOF; dwc2_writel(gintmsk, hsotg->regs + GINTMSK); @@ -295,9 +296,6 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) queue_work(hsotg->wq_otg, &hsotg->wf_otg); spin_lock(&hsotg->lock); } - - /* Clear interrupt */ - dwc2_writel(GINTSTS_CONIDSTSCHNG, hsotg->regs + GINTSTS); } /** @@ -315,12 +313,12 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) { int ret; - dev_dbg(hsotg->dev, "Session request interrupt - lx_state=%d\n", - hsotg->lx_state); - /* Clear interrupt */ dwc2_writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS); + dev_dbg(hsotg->dev, "Session request interrupt - lx_state=%d\n", + hsotg->lx_state); + if (dwc2_is_device_mode(hsotg)) { if (hsotg->lx_state == DWC2_L2) { ret = dwc2_exit_hibernation(hsotg, true); @@ -347,6 +345,10 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) { int ret; + + /* Clear interrupt */ + dwc2_writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS); + dev_dbg(hsotg->dev, "++Resume or Remote Wakeup Detected Interrupt++\n"); dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state); @@ -368,10 +370,9 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) /* Change to L0 state */ hsotg->lx_state = DWC2_L0; } else { - if (hsotg->core_params->hibernation) { - dwc2_writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS); + if (hsotg->core_params->hibernation) return; - } + if (hsotg->lx_state != DWC2_L1) { u32 pcgcctl = dwc2_readl(hsotg->regs + PCGCTL); @@ -385,9 +386,6 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) hsotg->lx_state = DWC2_L0; } } - - /* Clear interrupt */ - dwc2_writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS); } /* @@ -396,14 +394,14 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) */ static void dwc2_handle_disconnect_intr(struct dwc2_hsotg *hsotg) { + dwc2_writel(GINTSTS_DISCONNINT, hsotg->regs + GINTSTS); + dev_dbg(hsotg->dev, "++Disconnect Detected Interrupt++ (%s) %s\n", dwc2_is_host_mode(hsotg) ? "Host" : "Device", dwc2_op_state_str(hsotg)); if (hsotg->op_state == OTG_STATE_A_HOST) dwc2_hcd_disconnect(hsotg, false); - - dwc2_writel(GINTSTS_DISCONNINT, hsotg->regs + GINTSTS); } /* @@ -419,6 +417,9 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) u32 dsts; int ret; + /* Clear interrupt */ + dwc2_writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS); + dev_dbg(hsotg->dev, "USB SUSPEND\n"); if (dwc2_is_device_mode(hsotg)) { @@ -437,7 +438,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) if (!dwc2_is_device_connected(hsotg)) { dev_dbg(hsotg->dev, "ignore suspend request before enumeration\n"); - goto clear_int; + return; } ret = dwc2_enter_hibernation(hsotg); @@ -476,10 +477,6 @@ skip_power_saving: hsotg->op_state = OTG_STATE_A_HOST; } } - -clear_int: - /* Clear interrupt */ - dwc2_writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS); } #define GINTMSK_COMMON (GINTSTS_WKUPINT | GINTSTS_SESSREQINT | \ diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index a1eb48e548583..f8253803a0507 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c @@ -122,6 +122,9 @@ static void dwc2_sof_intr(struct dwc2_hsotg *hsotg) struct dwc2_qh *qh; enum dwc2_transaction_type tr_type; + /* Clear interrupt */ + dwc2_writel(GINTSTS_SOF, hsotg->regs + GINTSTS); + #ifdef DEBUG_SOF dev_vdbg(hsotg->dev, "--Start of Frame Interrupt--\n"); #endif @@ -146,9 +149,6 @@ static void dwc2_sof_intr(struct dwc2_hsotg *hsotg) tr_type = dwc2_hcd_select_transactions(hsotg); if (tr_type != DWC2_TRANSACTION_NONE) dwc2_hcd_queue_transactions(hsotg, tr_type); - - /* Clear interrupt */ - dwc2_writel(GINTSTS_SOF, hsotg->regs + GINTSTS); } /* @@ -312,6 +312,7 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0, if (do_reset) { *hprt0_modify |= HPRT0_RST; + dwc2_writel(*hprt0_modify, hsotg->regs + HPRT0); queue_delayed_work(hsotg->wq_otg, &hsotg->reset_work, msecs_to_jiffies(60)); } else { @@ -347,11 +348,12 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg) * Set flag and clear if detected */ if (hprt0 & HPRT0_CONNDET) { + dwc2_writel(hprt0_modify | HPRT0_CONNDET, hsotg->regs + HPRT0); + dev_vdbg(hsotg->dev, "--Port Interrupt HPRT0=0x%08x Port Connect Detected--\n", hprt0); dwc2_hcd_connect(hsotg); - hprt0_modify |= HPRT0_CONNDET; /* * The Hub driver asserts a reset when it sees port connect @@ -364,10 +366,10 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg) * Clear if detected - Set internal flag if disabled */ if (hprt0 & HPRT0_ENACHG) { + dwc2_writel(hprt0_modify | HPRT0_ENACHG, hsotg->regs + HPRT0); dev_vdbg(hsotg->dev, " --Port Interrupt HPRT0=0x%08x Port Enable Changed (now %d)--\n", hprt0, !!(hprt0 & HPRT0_ENA)); - hprt0_modify |= HPRT0_ENACHG; if (hprt0 & HPRT0_ENA) { hsotg->new_connection = true; dwc2_hprt0_enable(hsotg, hprt0, &hprt0_modify); @@ -387,15 +389,13 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg) /* Overcurrent Change Interrupt */ if (hprt0 & HPRT0_OVRCURRCHG) { + dwc2_writel(hprt0_modify | HPRT0_OVRCURRCHG, + hsotg->regs + HPRT0); dev_vdbg(hsotg->dev, " --Port Interrupt HPRT0=0x%08x Port Overcurrent Changed--\n", hprt0); hsotg->flags.b.port_over_current_change = 1; - hprt0_modify |= HPRT0_OVRCURRCHG; } - - /* Clear Port Interrupts */ - dwc2_writel(hprt0_modify, hsotg->regs + HPRT0); } /* -- GitLab From 3ff4b5733ba70f77b84272b01bfe5937218b1301 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Fri, 27 Nov 2015 11:38:21 +0100 Subject: [PATCH 1345/2855] usb: musb: convert printk to pr_* This file already uses pr_debug in a few places; this converts the remaining printks. Signed-off-by: Rasmus Villemoes Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index ee9ff7028b926..cd37e9fc2e629 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1360,8 +1360,7 @@ static int ep_config_from_table(struct musb *musb) break; } - printk(KERN_DEBUG "%s: setup fifo_mode %d\n", - musb_driver_name, fifo_mode); + pr_debug("%s: setup fifo_mode %d\n", musb_driver_name, fifo_mode); done: @@ -1390,7 +1389,7 @@ done: musb->nr_endpoints = max(epn, musb->nr_endpoints); } - printk(KERN_DEBUG "%s: %d/%d max ep, %d/%d memory\n", + pr_debug("%s: %d/%d max ep, %d/%d memory\n", musb_driver_name, n + 1, musb->config->num_eps * 2 - 1, offset, (1 << (musb->config->ram_bits + 2))); @@ -1491,8 +1490,7 @@ static int musb_core_init(u16 musb_type, struct musb *musb) if (reg & MUSB_CONFIGDATA_SOFTCONE) strcat(aInfo, ", SoftConn"); - printk(KERN_DEBUG "%s: ConfigData=0x%02x (%s)\n", - musb_driver_name, reg, aInfo); + pr_debug("%s: ConfigData=0x%02x (%s)\n", musb_driver_name, reg, aInfo); aDate[0] = 0; if (MUSB_CONTROLLER_MHDRC == musb_type) { @@ -1502,9 +1500,8 @@ static int musb_core_init(u16 musb_type, struct musb *musb) musb->is_multipoint = 0; type = ""; #ifndef CONFIG_USB_OTG_BLACKLIST_HUB - printk(KERN_ERR - "%s: kernel must blacklist external hubs\n", - musb_driver_name); + pr_err("%s: kernel must blacklist external hubs\n", + musb_driver_name); #endif } @@ -1513,8 +1510,8 @@ static int musb_core_init(u16 musb_type, struct musb *musb) snprintf(aRevision, 32, "%d.%d%s", MUSB_HWVERS_MAJOR(musb->hwvers), MUSB_HWVERS_MINOR(musb->hwvers), (musb->hwvers & MUSB_HWVERS_RC) ? "RC" : ""); - printk(KERN_DEBUG "%s: %sHDRC RTL version %s %s\n", - musb_driver_name, type, aRevision, aDate); + pr_debug("%s: %sHDRC RTL version %s %s\n", + musb_driver_name, type, aRevision, aDate); /* configure ep0 */ musb_configure_ep0(musb); -- GitLab From 04c03d10e507052cfce6910ddf34091196e79e1c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 2 Dec 2015 10:06:45 -0600 Subject: [PATCH 1346/2855] usb: dwc3: gadget: handle request->zero So far, dwc3 has always missed request->zero handling for every endpoint. Let's implement that so we can handle cases where transfer must be finished with a ZLP. Note that dwc3 is a little special. Even though we're dealing with a ZLP, we still need a buffer of wMaxPacketSize bytes; to hide that detail from every gadget driver, we have a preallocated buffer of 1024 bytes (biggest bulk size) to use (and share) among all endpoints. Reported-by: Ravi B Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/gadget.c | 50 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 36f1cb74588c5..29130682e547e 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -37,6 +37,7 @@ #define DWC3_MSG_MAX 500 /* Global constants */ +#define DWC3_ZLP_BUF_SIZE 1024 /* size of a superspeed bulk */ #define DWC3_EP0_BOUNCE_SIZE 512 #define DWC3_ENDPOINTS_NUM 32 #define DWC3_XHCI_RESOURCES_NUM 2 @@ -647,6 +648,7 @@ struct dwc3_scratchpad_array { * @ctrl_req: usb control request which is used for ep0 * @ep0_trb: trb which is used for the ctrl_req * @ep0_bounce: bounce buffer for ep0 + * @zlp_buf: used when request->zero is set * @setup_buf: used while precessing STD USB requests * @ctrl_req_addr: dma address of ctrl_req * @ep0_trb: dma address of ep0_trb @@ -734,6 +736,7 @@ struct dwc3 { struct usb_ctrlrequest *ctrl_req; struct dwc3_trb *ep0_trb; void *ep0_bounce; + void *zlp_buf; void *scratchbuf; u8 *setup_buf; dma_addr_t ctrl_req_addr; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index e4203b79908a4..975801839355a 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1159,6 +1159,32 @@ out: return ret; } +static void __dwc3_gadget_ep_zlp_complete(struct usb_ep *ep, + struct usb_request *request) +{ + dwc3_gadget_ep_free_request(ep, request); +} + +static int __dwc3_gadget_ep_queue_zlp(struct dwc3 *dwc, struct dwc3_ep *dep) +{ + struct dwc3_request *req; + struct usb_request *request; + struct usb_ep *ep = &dep->endpoint; + + dwc3_trace(trace_dwc3_gadget, "queueing ZLP\n"); + request = dwc3_gadget_ep_alloc_request(ep, GFP_ATOMIC); + if (!request) + return -ENOMEM; + + request->length = 0; + request->buf = dwc->zlp_buf; + request->complete = __dwc3_gadget_ep_zlp_complete; + + req = to_dwc3_request(request); + + return __dwc3_gadget_ep_queue(dep, req); +} + static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, gfp_t gfp_flags) { @@ -1172,6 +1198,16 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, spin_lock_irqsave(&dwc->lock, flags); ret = __dwc3_gadget_ep_queue(dep, req); + + /* + * Okay, here's the thing, if gadget driver has requested for a ZLP by + * setting request->zero, instead of doing magic, we will just queue an + * extra usb_request ourselves so that it gets handled the same way as + * any other request. + */ + if (ret == 0 && request->zero && (request->length % ep->maxpacket == 0)) + ret = __dwc3_gadget_ep_queue_zlp(dwc, dep); + spin_unlock_irqrestore(&dwc->lock, flags); return ret; @@ -2744,6 +2780,12 @@ int dwc3_gadget_init(struct dwc3 *dwc) goto err3; } + dwc->zlp_buf = kzalloc(DWC3_ZLP_BUF_SIZE, GFP_KERNEL); + if (!dwc->zlp_buf) { + ret = -ENOMEM; + goto err4; + } + dwc->gadget.ops = &dwc3_gadget_ops; dwc->gadget.speed = USB_SPEED_UNKNOWN; dwc->gadget.sg_supported = true; @@ -2785,16 +2827,19 @@ int dwc3_gadget_init(struct dwc3 *dwc) ret = dwc3_gadget_init_endpoints(dwc); if (ret) - goto err4; + goto err5; ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget); if (ret) { dev_err(dwc->dev, "failed to register udc\n"); - goto err4; + goto err5; } return 0; +err5: + kfree(dwc->zlp_buf); + err4: dwc3_gadget_free_endpoints(dwc); dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE, @@ -2827,6 +2872,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc) dwc->ep0_bounce, dwc->ep0_bounce_addr); kfree(dwc->setup_buf); + kfree(dwc->zlp_buf); dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb), dwc->ep0_trb, dwc->ep0_trb_addr); -- GitLab From 46a01427e969e53d993b988ebbdb8c7c3562b66f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 3 Dec 2015 15:27:32 -0600 Subject: [PATCH 1347/2855] usb: dwc3: trace: show request flags struct usb_request have 3 flags which might be important to know about during debug. This patch shows each of the 3 flags as a single letter: z -> for zero s -> short not okay i -> interrupt A capital letter means the feature is enabled while a lower case letter means it is disabled; Thus 'zsI' indicates that a ZLP is not needed, that we can accept a short packet and interrupt for this request should be enabled. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/trace.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/trace.h b/drivers/usb/dwc3/trace.h index 9c10669ab91f7..3ac7252f44275 100644 --- a/drivers/usb/dwc3/trace.h +++ b/drivers/usb/dwc3/trace.h @@ -117,6 +117,9 @@ DECLARE_EVENT_CLASS(dwc3_log_request, __field(unsigned, actual) __field(unsigned, length) __field(int, status) + __field(int, zero) + __field(int, short_not_ok) + __field(int, no_interrupt) ), TP_fast_assign( snprintf(__get_str(name), DWC3_MSG_MAX, "%s", req->dep->name); @@ -124,9 +127,15 @@ DECLARE_EVENT_CLASS(dwc3_log_request, __entry->actual = req->request.actual; __entry->length = req->request.length; __entry->status = req->request.status; + __entry->zero = req->request.zero; + __entry->short_not_ok = req->request.short_not_ok; + __entry->no_interrupt = req->request.no_interrupt; ), - TP_printk("%s: req %p length %u/%u ==> %d", + TP_printk("%s: req %p length %u/%u %s%s%s ==> %d", __get_str(name), __entry->req, __entry->actual, __entry->length, + __entry->zero ? "Z" : "z", + __entry->short_not_ok ? "S" : "s", + __entry->no_interrupt ? "i" : "I", __entry->status ) ); -- GitLab From 2de59c09feb735874ea38c29d396b13e46dd0a69 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Tue, 8 Dec 2015 02:31:13 +0200 Subject: [PATCH 1348/2855] usb: gadget: lpc32xxx_udc: clean up and sort include directives out Remove mach/irq.h from the list of included headers, there is no compilation dependency on this include file, and the change is needed to prevent a compilation failure, when mach/irq.h is removed. Additionally remove other unneeded includes and sort out their order. Signed-off-by: Vladimir Zapolskiy Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/lpc32xx_udc.c | 35 +++++++++------------------- 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index 00b5006baf154..79fe6b77ee44d 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -28,42 +28,29 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include -#include +#include #include -#include -#include -#include -#include -#include +#include +#include +#include #include +#include +#include +#include #include -#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include - -#include -#include -#include #ifdef CONFIG_USB_GADGET_DEBUG_FILES #include #include #endif +#include +#include + /* * USB device configuration structure */ -- GitLab From 375da6271b685e97d2d936fffa6e405b93674c26 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 4 Dec 2015 17:04:25 +0100 Subject: [PATCH 1349/2855] usb: phy: Remove unused Renesas R-Car (Gen1) USB PHY driver As of commit 3d7608e4c169af03 ("ARM: shmobile: bockw: remove legacy board file and config"), the Renesas R-Car (Gen1) USB PHY driver is no longer used. In theory it could still be used on R-Car Gen1 SoCs, but that would require adding DT support to the driver. Instead, a new driver using the generic PHY framework should be written, as was done for R-Car Gen2. Remove the driver for good. Acked-by: Simon Horman Signed-off-by: Geert Uytterhoeven Signed-off-by: Felipe Balbi --- drivers/usb/phy/Kconfig | 13 -- drivers/usb/phy/Makefile | 1 - drivers/usb/phy/phy-rcar-usb.c | 247 --------------------- include/linux/platform_data/usb-rcar-phy.h | 28 --- 4 files changed, 289 deletions(-) delete mode 100644 drivers/usb/phy/phy-rcar-usb.c delete mode 100644 include/linux/platform_data/usb-rcar-phy.h diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 22e8ecb6bfbd2..155694c1a5366 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -186,19 +186,6 @@ config USB_MXS_PHY MXS Phy is used by some of the i.MX SoCs, for example imx23/28/6x. -config USB_RCAR_PHY - tristate "Renesas R-Car USB PHY support" - depends on USB || USB_GADGET - depends on ARCH_R8A7778 || ARCH_R8A7779 || COMPILE_TEST - select USB_PHY - help - Say Y here to add support for the Renesas R-Car USB common PHY driver. - This chip is typically used as USB PHY for USB host, gadget. - This driver supports R8A7778 and R8A7779. - - To compile this driver as a module, choose M here: the - module will be called phy-rcar-usb. - config USB_ULPI bool "Generic ULPI Transceiver Driver" depends on ARM || ARM64 diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index 19c0dccbb1161..b433e5d89be4b 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -23,7 +23,6 @@ obj-$(CONFIG_USB_MSM_OTG) += phy-msm-usb.o obj-$(CONFIG_USB_QCOM_8X16_PHY) += phy-qcom-8x16-usb.o obj-$(CONFIG_USB_MV_OTG) += phy-mv-usb.o obj-$(CONFIG_USB_MXS_PHY) += phy-mxs-usb.o -obj-$(CONFIG_USB_RCAR_PHY) += phy-rcar-usb.o obj-$(CONFIG_USB_ULPI) += phy-ulpi.o obj-$(CONFIG_USB_ULPI_VIEWPORT) += phy-ulpi-viewport.o obj-$(CONFIG_KEYSTONE_USB_PHY) += phy-keystone.o diff --git a/drivers/usb/phy/phy-rcar-usb.c b/drivers/usb/phy/phy-rcar-usb.c deleted file mode 100644 index 1e09b83778853..0000000000000 --- a/drivers/usb/phy/phy-rcar-usb.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Renesas R-Car USB phy driver - * - * Copyright (C) 2012-2013 Renesas Solutions Corp. - * Kuninori Morimoto - * Copyright (C) 2013 Cogent Embedded, Inc. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include - -/* REGS block */ -#define USBPCTRL0 0x00 -#define USBPCTRL1 0x04 -#define USBST 0x08 -#define USBEH0 0x0C -#define USBOH0 0x1C -#define USBCTL0 0x58 - -/* High-speed signal quality characteristic control registers (R8A7778 only) */ -#define HSQCTL1 0x24 -#define HSQCTL2 0x28 - -/* USBPCTRL0 */ -#define OVC2 (1 << 10) /* (R8A7779 only) */ - /* Switches the OVC input pin for port 2: */ - /* 1: USB_OVC2, 0: OVC2 */ -#define OVC1_VBUS1 (1 << 9) /* Switches the OVC input pin for port 1: */ - /* 1: USB_OVC1, 0: OVC1/VBUS1 */ - /* Function mode: set to 0 */ -#define OVC0 (1 << 8) /* Switches the OVC input pin for port 0: */ - /* 1: USB_OVC0 pin, 0: OVC0 */ -#define OVC2_ACT (1 << 6) /* (R8A7779 only) */ - /* Host mode: OVC2 polarity: */ - /* 1: active-high, 0: active-low */ -#define PENC (1 << 4) /* Function mode: output level of PENC1 pin: */ - /* 1: high, 0: low */ -#define OVC0_ACT (1 << 3) /* Host mode: OVC0 polarity: */ - /* 1: active-high, 0: active-low */ -#define OVC1_ACT (1 << 1) /* Host mode: OVC1 polarity: */ - /* 1: active-high, 0: active-low */ - /* Function mode: be sure to set to 1 */ -#define PORT1 (1 << 0) /* Selects port 1 mode: */ - /* 1: function, 0: host */ -/* USBPCTRL1 */ -#define PHY_RST (1 << 2) -#define PLL_ENB (1 << 1) -#define PHY_ENB (1 << 0) - -/* USBST */ -#define ST_ACT (1 << 31) -#define ST_PLL (1 << 30) - -struct rcar_usb_phy_priv { - struct usb_phy phy; - spinlock_t lock; - - void __iomem *reg0; - void __iomem *reg1; - int counter; -}; - -#define usb_phy_to_priv(p) container_of(p, struct rcar_usb_phy_priv, phy) - - -/* - * USB initial/install operation. - * - * This function setup USB phy. - * The used value and setting order came from - * [USB :: Initial setting] on datasheet. - */ -static int rcar_usb_phy_init(struct usb_phy *phy) -{ - struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy); - struct device *dev = phy->dev; - struct rcar_phy_platform_data *pdata = dev_get_platdata(dev); - void __iomem *reg0 = priv->reg0; - void __iomem *reg1 = priv->reg1; - static const u8 ovcn_act[] = { OVC0_ACT, OVC1_ACT, OVC2_ACT }; - int i; - u32 val; - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - if (priv->counter++ == 0) { - - /* - * USB phy start-up - */ - - /* (1) USB-PHY standby release */ - iowrite32(PHY_ENB, (reg0 + USBPCTRL1)); - - /* (2) start USB-PHY internal PLL */ - iowrite32(PHY_ENB | PLL_ENB, (reg0 + USBPCTRL1)); - - /* (3) set USB-PHY in accord with the conditions of usage */ - if (reg1) { - u32 hsqctl1 = pdata->ferrite_bead ? 0x41 : 0; - u32 hsqctl2 = pdata->ferrite_bead ? 0x0d : 7; - - iowrite32(hsqctl1, reg1 + HSQCTL1); - iowrite32(hsqctl2, reg1 + HSQCTL2); - } - - /* (4) USB module status check */ - for (i = 0; i < 1024; i++) { - udelay(10); - val = ioread32(reg0 + USBST); - if (val == (ST_ACT | ST_PLL)) - break; - } - - if (val != (ST_ACT | ST_PLL)) { - dev_err(dev, "USB phy not ready\n"); - goto phy_init_end; - } - - /* (5) USB-PHY reset clear */ - iowrite32(PHY_ENB | PLL_ENB | PHY_RST, (reg0 + USBPCTRL1)); - - /* Board specific port settings */ - val = 0; - if (pdata->port1_func) - val |= PORT1; - if (pdata->penc1) - val |= PENC; - for (i = 0; i < 3; i++) { - /* OVCn bits follow each other in the right order */ - if (pdata->ovc_pin[i].select_3_3v) - val |= OVC0 << i; - /* OVCn_ACT bits are spaced by irregular intervals */ - if (pdata->ovc_pin[i].active_high) - val |= ovcn_act[i]; - } - iowrite32(val, (reg0 + USBPCTRL0)); - - /* - * Bus alignment settings - */ - - /* (1) EHCI bus alignment (little endian) */ - iowrite32(0x00000000, (reg0 + USBEH0)); - - /* (1) OHCI bus alignment (little endian) */ - iowrite32(0x00000000, (reg0 + USBOH0)); - } - -phy_init_end: - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - -static void rcar_usb_phy_shutdown(struct usb_phy *phy) -{ - struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy); - void __iomem *reg0 = priv->reg0; - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - - if (priv->counter-- == 1) /* last user */ - iowrite32(0x00000000, (reg0 + USBPCTRL1)); - - spin_unlock_irqrestore(&priv->lock, flags); -} - -static int rcar_usb_phy_probe(struct platform_device *pdev) -{ - struct rcar_usb_phy_priv *priv; - struct resource *res0, *res1; - struct device *dev = &pdev->dev; - void __iomem *reg0, *reg1 = NULL; - int ret; - - if (!dev_get_platdata(&pdev->dev)) { - dev_err(dev, "No platform data\n"); - return -EINVAL; - } - - res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); - reg0 = devm_ioremap_resource(dev, res0); - if (IS_ERR(reg0)) - return PTR_ERR(reg0); - - res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); - reg1 = devm_ioremap_resource(dev, res1); - if (IS_ERR(reg1)) - return PTR_ERR(reg1); - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->reg0 = reg0; - priv->reg1 = reg1; - priv->counter = 0; - priv->phy.dev = dev; - priv->phy.label = dev_name(dev); - priv->phy.init = rcar_usb_phy_init; - priv->phy.shutdown = rcar_usb_phy_shutdown; - spin_lock_init(&priv->lock); - - ret = usb_add_phy(&priv->phy, USB_PHY_TYPE_USB2); - if (ret < 0) { - dev_err(dev, "usb phy addition error\n"); - return ret; - } - - platform_set_drvdata(pdev, priv); - - return ret; -} - -static int rcar_usb_phy_remove(struct platform_device *pdev) -{ - struct rcar_usb_phy_priv *priv = platform_get_drvdata(pdev); - - usb_remove_phy(&priv->phy); - - return 0; -} - -static struct platform_driver rcar_usb_phy_driver = { - .driver = { - .name = "rcar_usb_phy", - }, - .probe = rcar_usb_phy_probe, - .remove = rcar_usb_phy_remove, -}; - -module_platform_driver(rcar_usb_phy_driver); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Renesas R-Car USB phy"); -MODULE_AUTHOR("Kuninori Morimoto "); diff --git a/include/linux/platform_data/usb-rcar-phy.h b/include/linux/platform_data/usb-rcar-phy.h deleted file mode 100644 index 8ec6964a32a52..0000000000000 --- a/include/linux/platform_data/usb-rcar-phy.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2013 Renesas Solutions Corp. - * Copyright (C) 2013 Cogent Embedded, Inc. - * - * 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. - */ - -#ifndef __USB_RCAR_PHY_H -#define __USB_RCAR_PHY_H - -#include - -struct rcar_phy_platform_data { - bool ferrite_bead:1; /* (R8A7778 only) */ - - bool port1_func:1; /* true: port 1 used by function, false: host */ - unsigned penc1:1; /* Output of the PENC1 pin in function mode */ - struct { /* Overcurrent pin control for ports 0..2 */ - bool select_3_3v:1; /* true: USB_OVCn pin, false: OVCn pin */ - /* Set to false on port 1 in function mode */ - bool active_high:1; /* true: active high, false: active low */ - /* Set to true on port 1 in function mode */ - } ovc_pin[3]; /* (R8A7778 only has 2 ports) */ -}; - -#endif /* __USB_RCAR_PHY_H */ -- GitLab From a49324f127dec918f5a3b3f145d0bf2fb81f4588 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 15 Dec 2015 13:29:47 +0800 Subject: [PATCH 1350/2855] f2fs: rename {add,remove,release}_dirty_inode to {add,remove,release}_ino_entry remove_dirty_dir_inode will be renamed to remove_dirty_inode as a generic function in following patch for removing directory/regular/symlink inode in global dirty list. Here rename ino management related functions for readability, also in order to avoid name conflict. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 8 ++++---- fs/f2fs/f2fs.h | 6 +++--- fs/f2fs/file.c | 4 ++-- fs/f2fs/inode.c | 4 ++-- fs/f2fs/super.c | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index f661d80474be7..b839f5f3385c4 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -410,13 +410,13 @@ static void __remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type) spin_unlock(&im->ino_lock); } -void add_dirty_inode(struct f2fs_sb_info *sbi, nid_t ino, int type) +void add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type) { /* add new dirty ino entry into list */ __add_ino_entry(sbi, ino, type); } -void remove_dirty_inode(struct f2fs_sb_info *sbi, nid_t ino, int type) +void remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type) { /* remove dirty ino entry from list */ __remove_ino_entry(sbi, ino, type); @@ -434,7 +434,7 @@ bool exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode) return e ? true : false; } -void release_dirty_inode(struct f2fs_sb_info *sbi) +void release_ino_entry(struct f2fs_sb_info *sbi) { struct ino_entry *e, *tmp; int i; @@ -1081,7 +1081,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) invalidate_mapping_pages(META_MAPPING(sbi), discard_blk, discard_blk); - release_dirty_inode(sbi); + release_ino_entry(sbi); if (unlikely(f2fs_cp_error(sbi))) return; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 0052ae8bea3f6..ee8bcbf34f449 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1820,9 +1820,9 @@ bool is_valid_blkaddr(struct f2fs_sb_info *, block_t, int); int ra_meta_pages(struct f2fs_sb_info *, block_t, int, int, bool); void ra_meta_pages_cond(struct f2fs_sb_info *, pgoff_t); long sync_meta_pages(struct f2fs_sb_info *, enum page_type, long); -void add_dirty_inode(struct f2fs_sb_info *, nid_t, int type); -void remove_dirty_inode(struct f2fs_sb_info *, nid_t, int type); -void release_dirty_inode(struct f2fs_sb_info *); +void add_ino_entry(struct f2fs_sb_info *, nid_t, int type); +void remove_ino_entry(struct f2fs_sb_info *, nid_t, int type); +void release_ino_entry(struct f2fs_sb_info *); bool exist_written_data(struct f2fs_sb_info *, nid_t, int); int acquire_orphan_inode(struct f2fs_sb_info *); void release_orphan_inode(struct f2fs_sb_info *); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 9949d0f332c2a..c6d909e9661e9 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -275,10 +275,10 @@ sync_nodes: goto out; /* once recovery info is written, don't need to tack this */ - remove_dirty_inode(sbi, ino, APPEND_INO); + remove_ino_entry(sbi, ino, APPEND_INO); clear_inode_flag(fi, FI_APPEND_WRITE); flush_out: - remove_dirty_inode(sbi, ino, UPDATE_INO); + remove_ino_entry(sbi, ino, UPDATE_INO); clear_inode_flag(fi, FI_UPDATE_WRITE); ret = f2fs_issue_flush(sbi); out: diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 97e20decacb4e..3d2fe595d0782 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -357,9 +357,9 @@ no_delete: if (xnid) invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid); if (is_inode_flag_set(fi, FI_APPEND_WRITE)) - add_dirty_inode(sbi, inode->i_ino, APPEND_INO); + add_ino_entry(sbi, inode->i_ino, APPEND_INO); if (is_inode_flag_set(fi, FI_UPDATE_WRITE)) - add_dirty_inode(sbi, inode->i_ino, UPDATE_INO); + add_ino_entry(sbi, inode->i_ino, UPDATE_INO); if (is_inode_flag_set(fi, FI_FREE_NID)) { if (err && err != -ENOENT) alloc_nid_done(sbi, inode->i_ino); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index a6f2beda22b9f..9ee7144c53673 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -548,7 +548,7 @@ static void f2fs_put_super(struct super_block *sb) * normally superblock is clean, so we need to release this. * In addition, EIO will skip do checkpoint, we need this as well. */ - release_dirty_inode(sbi); + release_ino_entry(sbi); release_discard_addrs(sbi); f2fs_leave_shrinker(sbi); -- GitLab From 2710fd7e00b4f77dbe807efaf546bed00b62e65e Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 15 Dec 2015 13:30:45 +0800 Subject: [PATCH 1351/2855] f2fs: introduce dirty list node in inode info Add a new dirt list node member in inode info for linking the inode to global dirty list in superblock, instead of old implementation which allocate slab cache memory as an entry to inode. It avoids memory pressure due to slab cache allocation, and also makes codes more clean. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 54 ++++++++++++++------------------------------ fs/f2fs/debug.c | 1 - fs/f2fs/f2fs.h | 10 ++------ fs/f2fs/super.c | 1 + 4 files changed, 20 insertions(+), 46 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index b839f5f3385c4..1aca402cab9ce 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -722,25 +722,23 @@ fail_no_cp: return -EINVAL; } -static int __add_dirty_inode(struct inode *inode, struct inode_entry *new) +static void __add_dirty_inode(struct inode *inode) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct f2fs_inode_info *fi = F2FS_I(inode); - if (is_inode_flag_set(F2FS_I(inode), FI_DIRTY_DIR)) - return -EEXIST; + if (is_inode_flag_set(fi, FI_DIRTY_DIR)) + return; - set_inode_flag(F2FS_I(inode), FI_DIRTY_DIR); - F2FS_I(inode)->dirty_dir = new; - list_add_tail(&new->list, &sbi->dir_inode_list); + set_inode_flag(fi, FI_DIRTY_DIR); + list_add_tail(&fi->dirty_list, &sbi->dir_inode_list); stat_inc_dirty_dir(sbi); - return 0; + return; } void update_dirty_page(struct inode *inode, struct page *page) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - struct inode_entry *new; - int ret = 0; if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode)) @@ -751,17 +749,11 @@ void update_dirty_page(struct inode *inode, struct page *page) goto out; } - new = f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS); - new->inode = inode; - INIT_LIST_HEAD(&new->list); - spin_lock(&sbi->dir_inode_lock); - ret = __add_dirty_inode(inode, new); + __add_dirty_inode(inode); inode_inc_dirty_pages(inode); spin_unlock(&sbi->dir_inode_lock); - if (ret) - kmem_cache_free(inode_entry_slab, new); out: SetPagePrivate(page); f2fs_trace_pid(page); @@ -770,25 +762,16 @@ out: void add_dirty_dir_inode(struct inode *inode) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - struct inode_entry *new = - f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS); - int ret = 0; - - new->inode = inode; - INIT_LIST_HEAD(&new->list); spin_lock(&sbi->dir_inode_lock); - ret = __add_dirty_inode(inode, new); + __add_dirty_inode(inode); spin_unlock(&sbi->dir_inode_lock); - - if (ret) - kmem_cache_free(inode_entry_slab, new); } void remove_dirty_dir_inode(struct inode *inode) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - struct inode_entry *entry; + struct f2fs_inode_info *fi = F2FS_I(inode); if (!S_ISDIR(inode->i_mode)) return; @@ -800,17 +783,14 @@ void remove_dirty_dir_inode(struct inode *inode) return; } - entry = F2FS_I(inode)->dirty_dir; - list_del(&entry->list); - F2FS_I(inode)->dirty_dir = NULL; - clear_inode_flag(F2FS_I(inode), FI_DIRTY_DIR); + list_del_init(&fi->dirty_list); + clear_inode_flag(fi, FI_DIRTY_DIR); stat_dec_dirty_dir(sbi); spin_unlock(&sbi->dir_inode_lock); - kmem_cache_free(inode_entry_slab, entry); /* Only from the recovery routine */ - if (is_inode_flag_set(F2FS_I(inode), FI_DELAY_IPUT)) { - clear_inode_flag(F2FS_I(inode), FI_DELAY_IPUT); + if (is_inode_flag_set(fi, FI_DELAY_IPUT)) { + clear_inode_flag(fi, FI_DELAY_IPUT); iput(inode); } } @@ -818,8 +798,8 @@ void remove_dirty_dir_inode(struct inode *inode) void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi) { struct list_head *head; - struct inode_entry *entry; struct inode *inode; + struct f2fs_inode_info *fi; retry: if (unlikely(f2fs_cp_error(sbi))) return; @@ -831,8 +811,8 @@ retry: spin_unlock(&sbi->dir_inode_lock); return; } - entry = list_entry(head->next, struct inode_entry, list); - inode = igrab(entry->inode); + fi = list_entry(head->next, struct f2fs_inode_info, dirty_list); + inode = igrab(&fi->vfs_inode); spin_unlock(&sbi->dir_inode_lock); if (inode) { filemap_fdatawrite(inode->i_mapping); diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index 8ce2fe3f65ab5..f4a7b9e9416d3 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -189,7 +189,6 @@ get_cache: si->cache_mem += NM_I(sbi)->dirty_nat_cnt * sizeof(struct nat_entry_set); si->cache_mem += si->inmem_pages * sizeof(struct inmem_pages); - si->cache_mem += sbi->n_dirty_dirs * sizeof(struct inode_entry); for (i = 0; i <= UPDATE_INO; i++) si->cache_mem += sbi->im[i].ino_num * sizeof(struct ino_entry); si->cache_mem += sbi->total_ext_tree * sizeof(struct extent_tree); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index ee8bcbf34f449..21048edb72cb3 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -158,13 +158,7 @@ struct ino_entry { nid_t ino; /* inode number */ }; -/* - * for the list of directory inodes or gc inodes. - * NOTE: there are two slab users for this structure, if we add/modify/delete - * fields in structure for one of slab users, it may affect fields or size of - * other one, in this condition, it's better to split both of slab and related - * data structure. - */ +/* for the list of inodes to be GCed */ struct inode_entry { struct list_head list; /* list head */ struct inode *inode; /* vfs inode pointer */ @@ -441,8 +435,8 @@ struct f2fs_inode_info { unsigned int clevel; /* maximum level of given file name */ nid_t i_xattr_nid; /* node id that contains xattrs */ unsigned long long xattr_ver; /* cp version of xattr modification */ - struct inode_entry *dirty_dir; /* the pointer of dirty dir */ + struct list_head dirty_list; /* linked in global dirty list */ struct list_head inmem_pages; /* inmemory pages managed by f2fs */ struct mutex inmem_lock; /* lock for inmemory pages */ diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 9ee7144c53673..4031f8ed9d240 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -432,6 +432,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb) fi->i_current_depth = 1; fi->i_advise = 0; init_rwsem(&fi->i_sem); + INIT_LIST_HEAD(&fi->dirty_list); INIT_LIST_HEAD(&fi->inmem_pages); mutex_init(&fi->inmem_lock); -- GitLab From 6ad7609a183a250f1a346c7edfcbeaa30a29cfcc Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 15 Dec 2015 13:31:40 +0800 Subject: [PATCH 1352/2855] f2fs: introduce __remove_dirty_inode Introduce __remove_dirty_inode to clean up codes in remove_dirty_dir_inode. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 1aca402cab9ce..a4392f06f7339 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -736,6 +736,20 @@ static void __add_dirty_inode(struct inode *inode) return; } +static void __remove_dirty_inode(struct inode *inode) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct f2fs_inode_info *fi = F2FS_I(inode); + + if (get_dirty_pages(inode) || + !is_inode_flag_set(F2FS_I(inode), FI_DIRTY_DIR)) + return; + + list_del_init(&fi->dirty_list); + clear_inode_flag(fi, FI_DIRTY_DIR); + stat_dec_dirty_dir(sbi); +} + void update_dirty_page(struct inode *inode, struct page *page) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); @@ -777,15 +791,7 @@ void remove_dirty_dir_inode(struct inode *inode) return; spin_lock(&sbi->dir_inode_lock); - if (get_dirty_pages(inode) || - !is_inode_flag_set(F2FS_I(inode), FI_DIRTY_DIR)) { - spin_unlock(&sbi->dir_inode_lock); - return; - } - - list_del_init(&fi->dirty_list); - clear_inode_flag(fi, FI_DIRTY_DIR); - stat_dec_dirty_dir(sbi); + __remove_dirty_inode(inode); spin_unlock(&sbi->dir_inode_lock); /* Only from the recovery routine */ -- GitLab From f677f17cced0ca72a4331b64de119b35b19facb0 Mon Sep 17 00:00:00 2001 From: Anton Bondarenko Date: Tue, 8 Dec 2015 07:43:43 +0100 Subject: [PATCH 1353/2855] spi: imx: fix loopback mode setup after controller reset If controller hold in reset it's not possible to write any register except CTRL. So all other registers must be updated only after controller bring out from reset. Signed-off-by: Anton Bondarenko Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 410522fdd4c91..3aa33c8c819f4 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -356,6 +356,9 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, else cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(config->cs); + /* CTRL register always go first to bring out controller from reset */ + writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); + reg = readl(spi_imx->base + MX51_ECSPI_TESTREG); if (config->mode & SPI_LOOP) reg |= MX51_ECSPI_TESTREG_LBC; @@ -363,7 +366,6 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, reg &= ~MX51_ECSPI_TESTREG_LBC; writel(reg, spi_imx->base + MX51_ECSPI_TESTREG); - writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG); /* -- GitLab From 4686d1c3d17a146192aa707a92edc2e122ada39e Mon Sep 17 00:00:00 2001 From: Anton Bondarenko Date: Tue, 8 Dec 2015 07:43:44 +0100 Subject: [PATCH 1354/2855] spi: imx: enable loopback only for ECSPI controller family Limit SPI_LOOP mode to ECSPI controller (iMX.51, iMX53 and i.MX6) only since there is no support in other families specific code for now. Signed-off-by: Anton Bondarenko Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 3aa33c8c819f4..17a90dcab3286 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -1140,6 +1140,9 @@ static int spi_imx_probe(struct platform_device *pdev) spi_imx = spi_master_get_devdata(master); spi_imx->bitbang.master = master; + spi_imx->devtype_data = of_id ? of_id->data : + (struct spi_imx_devtype_data *)pdev->id_entry->driver_data; + for (i = 0; i < master->num_chipselect; i++) { int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); if (!gpio_is_valid(cs_gpio) && mxc_platform_info) @@ -1164,14 +1167,12 @@ static int spi_imx_probe(struct platform_device *pdev) spi_imx->bitbang.master->cleanup = spi_imx_cleanup; spi_imx->bitbang.master->prepare_message = spi_imx_prepare_message; spi_imx->bitbang.master->unprepare_message = spi_imx_unprepare_message; - spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | - SPI_LOOP; + spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; + if (is_imx51_ecspi(spi_imx)) + spi_imx->bitbang.master->mode_bits |= SPI_LOOP; init_completion(&spi_imx->xfer_done); - spi_imx->devtype_data = of_id ? of_id->data : - (struct spi_imx_devtype_data *) pdev->id_entry->driver_data; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); spi_imx->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(spi_imx->base)) { -- GitLab From 3760047a7d83353163b69b96d216a13148a321d9 Mon Sep 17 00:00:00 2001 From: Anton Bondarenko Date: Tue, 8 Dec 2015 07:43:45 +0100 Subject: [PATCH 1355/2855] spi: imx: return error from dma channel request On SDMA initialization return exactly the same error, which is reported by dma_request_slave_channel_reason(), it is a preceding change to defer SPI DMA initialization, if SDMA module is not yet available. Signed-off-by: Vladimir Zapolskiy Signed-off-by: Anton Bondarenko Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 17a90dcab3286..c12306099d246 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -848,10 +848,11 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, spi_imx->wml = spi_imx_get_fifosize(spi_imx) / 2; /* Prepare for TX DMA: */ - master->dma_tx = dma_request_slave_channel(dev, "tx"); - if (!master->dma_tx) { - dev_err(dev, "cannot get the TX DMA channel!\n"); - ret = -EINVAL; + master->dma_tx = dma_request_slave_channel_reason(dev, "tx"); + if (IS_ERR(master->dma_tx)) { + ret = PTR_ERR(master->dma_tx); + dev_dbg(dev, "can't get the TX DMA channel, error %d!\n", ret); + master->dma_tx = NULL; goto err; } @@ -866,10 +867,11 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, } /* Prepare for RX : */ - master->dma_rx = dma_request_slave_channel(dev, "rx"); - if (!master->dma_rx) { - dev_dbg(dev, "cannot get the DMA channel.\n"); - ret = -EINVAL; + master->dma_rx = dma_request_slave_channel_reason(dev, "rx"); + if (IS_ERR(master->dma_rx)) { + ret = PTR_ERR(master->dma_rx); + dev_dbg(dev, "can't get the RX DMA channel, error %d\n", ret); + master->dma_rx = NULL; goto err; } @@ -1218,9 +1220,12 @@ static int spi_imx_probe(struct platform_device *pdev) * Only validated on i.mx6 now, can remove the constrain if validated on * other chips. */ - if (is_imx51_ecspi(spi_imx) && - spi_imx_sdma_init(&pdev->dev, spi_imx, master, res)) - dev_err(&pdev->dev, "dma setup error,use pio instead\n"); + if (is_imx51_ecspi(spi_imx)) { + ret = spi_imx_sdma_init(&pdev->dev, spi_imx, master, res); + if (ret < 0) + dev_err(&pdev->dev, "dma setup error %d, use pio\n", + ret); + } spi_imx->devtype_data->reset(spi_imx); -- GitLab From bf9af08cd5151f1915119ea4c6a873d5a4880d74 Mon Sep 17 00:00:00 2001 From: Anton Bondarenko Date: Tue, 8 Dec 2015 07:43:46 +0100 Subject: [PATCH 1356/2855] spi: imx: defer spi initialization, if DMA engine is If SPI device supports DMA mode, but DMA controller is not yet available due to e.g. a delay in the corresponding kernel module initialization, retry to initialize SPI driver later on instead of falling back into PIO only mode. Signed-off-by: Anton Bondarenko Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index c12306099d246..d98c33cb64f9b 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -1222,6 +1222,9 @@ static int spi_imx_probe(struct platform_device *pdev) */ if (is_imx51_ecspi(spi_imx)) { ret = spi_imx_sdma_init(&pdev->dev, spi_imx, master, res); + if (ret == -EPROBE_DEFER) + goto out_clk_put; + if (ret < 0) dev_err(&pdev->dev, "dma setup error %d, use pio\n", ret); -- GitLab From 00b912b0c88e690b1662067497182454357b18b0 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Tue, 15 Dec 2015 18:09:14 +1100 Subject: [PATCH 1357/2855] powerpc: Remove broken GregorianDay() GregorianDay() is supposed to calculate the day of the week (tm->tm_wday) for a given day/month/year. In that calcuation it indexed into an array called MonthOffset using tm->tm_mon-1. However tm_mon is zero-based, not one-based, so this is off-by-one. It also means that every January, GregoiranDay() will access element -1 of the MonthOffset array. It also doesn't appear to be a correct algorithm either: see in contrast kernel/time/timeconv.c's time_to_tm function. It's been broken forever, which suggests no-one in userland uses this. It looks like no-one in the kernel uses tm->tm_wday either (see e.g. drivers/rtc/rtc-ds1305.c:319). tm->tm_wday is conventionally set to -1 when not available in hardware so we can simply set it to -1 and drop the function. (There are over a dozen other drivers in drivers/rtc that do this.) Found using UBSAN. Cc: Andrey Ryabinin Cc: Andrew Morton # as an example of what UBSan finds. Cc: Alessandro Zummo Cc: Alexandre Belloni Cc: rtc-linux@googlegroups.com Signed-off-by: Daniel Axtens Acked-by: Alexandre Belloni Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/time.h | 1 - arch/powerpc/kernel/time.c | 36 ++--------------------- arch/powerpc/platforms/maple/time.c | 2 +- arch/powerpc/platforms/powernv/opal-rtc.c | 3 +- drivers/rtc/rtc-opal.c | 2 +- 5 files changed, 5 insertions(+), 39 deletions(-) diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h index 10fc784a2ad4c..2d7109a8d2961 100644 --- a/arch/powerpc/include/asm/time.h +++ b/arch/powerpc/include/asm/time.h @@ -27,7 +27,6 @@ extern struct clock_event_device decrementer_clockevent; struct rtc_time; extern void to_tm(int tim, struct rtc_time * tm); -extern void GregorianDay(struct rtc_time *tm); extern void tick_broadcast_ipi_handler(void); extern void generic_calibrate_decr(void); diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 1be1092c72042..81b0900a39eef 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -1002,38 +1002,6 @@ static int month_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; -/* - * This only works for the Gregorian calendar - i.e. after 1752 (in the UK) - */ -void GregorianDay(struct rtc_time * tm) -{ - int leapsToDate; - int lastYear; - int day; - int MonthOffset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; - - lastYear = tm->tm_year - 1; - - /* - * Number of leap corrections to apply up to end of last year - */ - leapsToDate = lastYear / 4 - lastYear / 100 + lastYear / 400; - - /* - * This year is a leap year if it is divisible by 4 except when it is - * divisible by 100 unless it is divisible by 400 - * - * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 was - */ - day = tm->tm_mon > 2 && leapyear(tm->tm_year); - - day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + - tm->tm_mday; - - tm->tm_wday = day % 7; -} -EXPORT_SYMBOL_GPL(GregorianDay); - void to_tm(int tim, struct rtc_time * tm) { register int i; @@ -1064,9 +1032,9 @@ void to_tm(int tim, struct rtc_time * tm) tm->tm_mday = day + 1; /* - * Determine the day of week + * No-one uses the day of the week. */ - GregorianDay(tm); + tm->tm_wday = -1; } EXPORT_SYMBOL(to_tm); diff --git a/arch/powerpc/platforms/maple/time.c b/arch/powerpc/platforms/maple/time.c index b4a369dac3a8a..81799d70a1eeb 100644 --- a/arch/powerpc/platforms/maple/time.c +++ b/arch/powerpc/platforms/maple/time.c @@ -77,7 +77,7 @@ void maple_get_rtc_time(struct rtc_time *tm) if ((tm->tm_year + 1900) < 1970) tm->tm_year += 100; - GregorianDay(tm); + tm->tm_wday = -1; } int maple_set_rtc_time(struct rtc_time *tm) diff --git a/arch/powerpc/platforms/powernv/opal-rtc.c b/arch/powerpc/platforms/powernv/opal-rtc.c index 37dbee15769fd..1b149c92fca16 100644 --- a/arch/powerpc/platforms/powernv/opal-rtc.c +++ b/arch/powerpc/platforms/powernv/opal-rtc.c @@ -31,8 +31,7 @@ static void opal_to_tm(u32 y_m_d, u64 h_m_s_ms, struct rtc_time *tm) tm->tm_hour = bcd2bin((h_m_s_ms >> 56) & 0xff); tm->tm_min = bcd2bin((h_m_s_ms >> 48) & 0xff); tm->tm_sec = bcd2bin((h_m_s_ms >> 40) & 0xff); - - GregorianDay(tm); + tm->tm_wday = -1; } unsigned long __init opal_get_boot_time(void) diff --git a/drivers/rtc/rtc-opal.c b/drivers/rtc/rtc-opal.c index df39ce02a99d3..9c18d6fd81075 100644 --- a/drivers/rtc/rtc-opal.c +++ b/drivers/rtc/rtc-opal.c @@ -40,7 +40,7 @@ static void opal_to_tm(u32 y_m_d, u64 h_m_s_ms, struct rtc_time *tm) tm->tm_min = bcd2bin((h_m_s_ms >> 48) & 0xff); tm->tm_sec = bcd2bin((h_m_s_ms >> 40) & 0xff); - GregorianDay(tm); + tm->tm_wday = -1; } static void tm_to_opal(struct rtc_time *tm, u32 *y_m_d, u64 *h_m_s_ms) -- GitLab From a45af72a609b095820feab26c49286337301377e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5ns=20Rullg=C3=A5rd?= Date: Tue, 15 Dec 2015 23:15:05 +0000 Subject: [PATCH 1358/2855] i2c: xlr: fix extra read/write at end of rx transfer The BYTECNT register holds the transfer size minus one. Setting it to the correct value removes the need for a dummy read/write at the end of each transfer. As zero-length transfers are not supported, do not advertise I2C_FUNC_SMBUS_QUICK. In other words, this patch makes the driver transfer the number of bytes requested unless this is zero, which is not supported by the hardware and is thus refused. Signed-off-by: Mans Rullgard Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-xlr.c | 50 +++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/drivers/i2c/busses/i2c-xlr.c b/drivers/i2c/busses/i2c-xlr.c index 10fb916fa8c76..2cfaba7c1f923 100644 --- a/drivers/i2c/busses/i2c-xlr.c +++ b/drivers/i2c/busses/i2c-xlr.c @@ -89,38 +89,43 @@ static int xlr_i2c_tx(struct xlr_i2c_private *priv, u16 len, unsigned long timeout, stoptime, checktime; u32 i2c_status; int pos, timedout; - u8 offset, byte; + u8 offset; + u32 xfer; + + if (!len) + return -EOPNOTSUPP; offset = buf[0]; xlr_i2c_wreg(priv->iobase, XLR_I2C_ADDR, offset); xlr_i2c_wreg(priv->iobase, XLR_I2C_DEVADDR, addr); xlr_i2c_wreg(priv->iobase, XLR_I2C_CFG, XLR_I2C_CFG_ADDR | priv->cfg->cfg_extra); - xlr_i2c_wreg(priv->iobase, XLR_I2C_BYTECNT, len - 1); timeout = msecs_to_jiffies(XLR_I2C_TIMEOUT); stoptime = jiffies + timeout; timedout = 0; - pos = 1; -retry: + if (len == 1) { - xlr_i2c_wreg(priv->iobase, XLR_I2C_STARTXFR, - XLR_I2C_STARTXFR_ND); + xlr_i2c_wreg(priv->iobase, XLR_I2C_BYTECNT, len - 1); + xfer = XLR_I2C_STARTXFR_ND; + pos = 1; } else { - xlr_i2c_wreg(priv->iobase, XLR_I2C_DATAOUT, buf[pos]); - xlr_i2c_wreg(priv->iobase, XLR_I2C_STARTXFR, - XLR_I2C_STARTXFR_WR); + xlr_i2c_wreg(priv->iobase, XLR_I2C_BYTECNT, len - 2); + xlr_i2c_wreg(priv->iobase, XLR_I2C_DATAOUT, buf[1]); + xfer = XLR_I2C_STARTXFR_WR; + pos = 2; } +retry: + /* retry can only happen on the first byte */ + xlr_i2c_wreg(priv->iobase, XLR_I2C_STARTXFR, xfer); + while (!timedout) { checktime = jiffies; i2c_status = xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS); - if (i2c_status & XLR_I2C_SDOEMPTY) { - pos++; - /* need to do a empty dataout after the last byte */ - byte = (pos < len) ? buf[pos] : 0; - xlr_i2c_wreg(priv->iobase, XLR_I2C_DATAOUT, byte); + if ((i2c_status & XLR_I2C_SDOEMPTY) && pos < len) { + xlr_i2c_wreg(priv->iobase, XLR_I2C_DATAOUT, buf[pos++]); /* reset timeout on successful xmit */ stoptime = jiffies + timeout; @@ -149,11 +154,13 @@ static int xlr_i2c_rx(struct xlr_i2c_private *priv, u16 len, u8 *buf, u16 addr) u32 i2c_status; unsigned long timeout, stoptime, checktime; int nbytes, timedout; - u8 byte; + + if (!len) + return -EOPNOTSUPP; xlr_i2c_wreg(priv->iobase, XLR_I2C_CFG, XLR_I2C_CFG_NOADDR | priv->cfg->cfg_extra); - xlr_i2c_wreg(priv->iobase, XLR_I2C_BYTECNT, len); + xlr_i2c_wreg(priv->iobase, XLR_I2C_BYTECNT, len - 1); xlr_i2c_wreg(priv->iobase, XLR_I2C_DEVADDR, addr); timeout = msecs_to_jiffies(XLR_I2C_TIMEOUT); @@ -167,14 +174,11 @@ retry: checktime = jiffies; i2c_status = xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS); if (i2c_status & XLR_I2C_RXRDY) { - if (nbytes > len) + if (nbytes >= len) return -EIO; /* should not happen */ - /* we need to do a dummy datain when nbytes == len */ - byte = xlr_i2c_rdreg(priv->iobase, XLR_I2C_DATAIN); - if (nbytes < len) - buf[nbytes] = byte; - nbytes++; + buf[nbytes++] = + xlr_i2c_rdreg(priv->iobase, XLR_I2C_DATAIN); /* reset timeout on successful read */ stoptime = jiffies + timeout; @@ -228,7 +232,7 @@ static int xlr_i2c_xfer(struct i2c_adapter *adap, static u32 xlr_func(struct i2c_adapter *adap) { /* Emulate SMBUS over I2C */ - return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; + return (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) | I2C_FUNC_I2C; } static struct i2c_algorithm xlr_i2c_algo = { -- GitLab From 5398b7ef6cdbc88581457b26b924081fc53d1de8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5ns=20Rullg=C3=A5rd?= Date: Tue, 15 Dec 2015 23:15:06 +0000 Subject: [PATCH 1359/2855] i2c: xlr: add interrupt support for Sigma Designs chips The Sigma Designs variant of this controller has the ability to generate interrupts. This is controlled using two additional registers, oddly enough overlapping with the defined but unused HDSTATIM. This patch adds support for using this feature instead of busy-looping if an IRQ is specified. Signed-off-by: Mans Rullgard Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-xlr.c | 119 +++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/drivers/i2c/busses/i2c-xlr.c b/drivers/i2c/busses/i2c-xlr.c index 2cfaba7c1f923..613c3a4f2c514 100644 --- a/drivers/i2c/busses/i2c-xlr.c +++ b/drivers/i2c/busses/i2c-xlr.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include /* XLR I2C REGISTERS */ #define XLR_I2C_CFG 0x00 @@ -32,6 +34,10 @@ #define XLR_I2C_BYTECNT 0x08 #define XLR_I2C_HDSTATIM 0x09 +/* Sigma Designs additional registers */ +#define XLR_I2C_INT_EN 0x09 +#define XLR_I2C_INT_STAT 0x0a + /* XLR I2C REGISTERS FLAGS */ #define XLR_I2C_BUS_BUSY 0x01 #define XLR_I2C_SDOEMPTY 0x02 @@ -65,7 +71,10 @@ static inline u32 xlr_i2c_rdreg(u32 __iomem *base, unsigned int reg) return __raw_readl(base + reg); } +#define XLR_I2C_FLAG_IRQ 1 + struct xlr_i2c_config { + u32 flags; /* optional feature support */ u32 status_busy; /* value of STATUS[0] when busy */ u32 cfg_extra; /* extra CFG bits to set */ }; @@ -73,7 +82,11 @@ struct xlr_i2c_config { struct xlr_i2c_private { struct i2c_adapter adap; u32 __iomem *iobase; + int irq; + int pos; + struct i2c_msg *msg; const struct xlr_i2c_config *cfg; + wait_queue_head_t wait; struct clk *clk; }; @@ -82,6 +95,74 @@ static int xlr_i2c_busy(struct xlr_i2c_private *priv, u32 status) return (status & XLR_I2C_BUS_BUSY) == priv->cfg->status_busy; } +static int xlr_i2c_idle(struct xlr_i2c_private *priv) +{ + return !xlr_i2c_busy(priv, xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS)); +} + +static int xlr_i2c_wait(struct xlr_i2c_private *priv, unsigned long timeout) +{ + int status; + int t; + + t = wait_event_timeout(priv->wait, xlr_i2c_idle(priv), + msecs_to_jiffies(timeout)); + if (!t) + return -ETIMEDOUT; + + status = xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS); + + return status & XLR_I2C_ACK_ERR ? -EIO : 0; +} + +static void xlr_i2c_tx_irq(struct xlr_i2c_private *priv, u32 status) +{ + struct i2c_msg *msg = priv->msg; + + if (status & XLR_I2C_SDOEMPTY) + xlr_i2c_wreg(priv->iobase, XLR_I2C_DATAOUT, + msg->buf[priv->pos++]); +} + +static void xlr_i2c_rx_irq(struct xlr_i2c_private *priv, u32 status) +{ + struct i2c_msg *msg = priv->msg; + + if (status & XLR_I2C_RXRDY) + msg->buf[priv->pos++] = + xlr_i2c_rdreg(priv->iobase, XLR_I2C_DATAIN); +} + +static irqreturn_t xlr_i2c_irq(int irq, void *dev_id) +{ + struct xlr_i2c_private *priv = dev_id; + struct i2c_msg *msg = priv->msg; + u32 int_stat, status; + + int_stat = xlr_i2c_rdreg(priv->iobase, XLR_I2C_INT_STAT); + if (!int_stat) + return IRQ_NONE; + + xlr_i2c_wreg(priv->iobase, XLR_I2C_INT_STAT, int_stat); + + if (!msg) + return IRQ_HANDLED; + + status = xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS); + + if (priv->pos < msg->len) { + if (msg->flags & I2C_M_RD) + xlr_i2c_rx_irq(priv, status); + else + xlr_i2c_tx_irq(priv, status); + } + + if (!xlr_i2c_busy(priv, status)) + wake_up(&priv->wait); + + return IRQ_HANDLED; +} + static int xlr_i2c_tx(struct xlr_i2c_private *priv, u16 len, u8 *buf, u16 addr) { @@ -116,10 +197,15 @@ static int xlr_i2c_tx(struct xlr_i2c_private *priv, u16 len, pos = 2; } + priv->pos = pos; + retry: /* retry can only happen on the first byte */ xlr_i2c_wreg(priv->iobase, XLR_I2C_STARTXFR, xfer); + if (priv->irq > 0) + return xlr_i2c_wait(priv, XLR_I2C_TIMEOUT * len); + while (!timedout) { checktime = jiffies; i2c_status = xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS); @@ -163,6 +249,8 @@ static int xlr_i2c_rx(struct xlr_i2c_private *priv, u16 len, u8 *buf, u16 addr) xlr_i2c_wreg(priv->iobase, XLR_I2C_BYTECNT, len - 1); xlr_i2c_wreg(priv->iobase, XLR_I2C_DEVADDR, addr); + priv->pos = 0; + timeout = msecs_to_jiffies(XLR_I2C_TIMEOUT); stoptime = jiffies + timeout; timedout = 0; @@ -170,6 +258,9 @@ static int xlr_i2c_rx(struct xlr_i2c_private *priv, u16 len, u8 *buf, u16 addr) retry: xlr_i2c_wreg(priv->iobase, XLR_I2C_STARTXFR, XLR_I2C_STARTXFR_RD); + if (priv->irq > 0) + return xlr_i2c_wait(priv, XLR_I2C_TIMEOUT * len); + while (!timedout) { checktime = jiffies; i2c_status = xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS); @@ -214,8 +305,13 @@ static int xlr_i2c_xfer(struct i2c_adapter *adap, if (ret) return ret; + if (priv->irq) + xlr_i2c_wreg(priv->iobase, XLR_I2C_INT_EN, 0xf); + + for (i = 0; ret == 0 && i < num; i++) { msg = &msgs[i]; + priv->msg = msg; if (msg->flags & I2C_M_RD) ret = xlr_i2c_rx(priv, msg->len, &msg->buf[0], msg->addr); @@ -224,7 +320,11 @@ static int xlr_i2c_xfer(struct i2c_adapter *adap, msg->addr); } + if (priv->irq) + xlr_i2c_wreg(priv->iobase, XLR_I2C_INT_EN, 0); + clk_disable(priv->clk); + priv->msg = NULL; return (ret != 0) ? ret : num; } @@ -246,6 +346,7 @@ static const struct xlr_i2c_config xlr_i2c_config_default = { }; static const struct xlr_i2c_config xlr_i2c_config_tangox = { + .flags = XLR_I2C_FLAG_IRQ, .status_busy = 0, .cfg_extra = 1 << 8, }; @@ -267,6 +368,7 @@ static int xlr_i2c_probe(struct platform_device *pdev) unsigned long clk_rate; unsigned long clk_div; u32 busfreq; + int irq; int ret; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); @@ -284,6 +386,23 @@ static int xlr_i2c_probe(struct platform_device *pdev) if (IS_ERR(priv->iobase)) return PTR_ERR(priv->iobase); + irq = platform_get_irq(pdev, 0); + + if (irq > 0 && (priv->cfg->flags & XLR_I2C_FLAG_IRQ)) { + priv->irq = irq; + + xlr_i2c_wreg(priv->iobase, XLR_I2C_INT_EN, 0); + xlr_i2c_wreg(priv->iobase, XLR_I2C_INT_STAT, 0xf); + + ret = devm_request_irq(&pdev->dev, priv->irq, xlr_i2c_irq, + IRQF_SHARED, dev_name(&pdev->dev), + priv); + if (ret) + return ret; + + init_waitqueue_head(&priv->wait); + } + if (of_property_read_u32(pdev->dev.of_node, "clock-frequency", &busfreq)) busfreq = 100000; -- GitLab From 7a400585893e7aa52a845027bce1bf529bdf65d1 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Mon, 14 Dec 2015 23:30:43 -0600 Subject: [PATCH 1360/2855] soc: qcom: documentation: Update SMD/RPM Docs This patch moves the qcom,smd-rpm.txt to the correct location and splits out the smd and rpm documentation. In addition, a smd-rpm-regulator document is added. Signed-off-by: Andy Gross Acked-by: Bjorn Andersson Signed-off-by: Mark Brown --- .../qcom,smd-rpm-regulator.txt} | 31 ++++------ .../bindings/soc/qcom/qcom,smd-rpm.txt | 58 +++++++++++++++++++ 2 files changed, 68 insertions(+), 21 deletions(-) rename Documentation/devicetree/bindings/{soc/qcom,smd-rpm.txt => regulator/qcom,smd-rpm-regulator.txt} (75%) create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt diff --git a/Documentation/devicetree/bindings/soc/qcom,smd-rpm.txt b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt similarity index 75% rename from Documentation/devicetree/bindings/soc/qcom,smd-rpm.txt rename to Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt index e27f5c4c54fdb..bda2ed96ba661 100644 --- a/Documentation/devicetree/bindings/soc/qcom,smd-rpm.txt +++ b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt @@ -1,27 +1,17 @@ -Qualcomm Resource Power Manager (RPM) over SMD +QCOM SMD RPM REGULATOR -This driver is used to interface with the Resource Power Manager (RPM) found in -various Qualcomm platforms. The RPM allows each component in the system to vote -for state of the system resources, such as clocks, regulators and bus -frequencies. +The Qualcomm RPM over SMD regulator is modelled as a subdevice of the RPM. +Because SMD is used as the communication transport mechanism, the RPM resides as +a subnode of the SMD. As such, the SMD-RPM regulator requires that the SMD and +RPM nodes be present. -- compatible: - Usage: required - Value type: - Definition: must be one of: - "qcom,rpm-msm8974" +Please refer to Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt for +information pertaining to the SMD node. -- qcom,smd-channels: - Usage: required - Value type: - Definition: Shared Memory channel used for communication with the RPM - -= SUBDEVICES +Please refer to Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt for +information regarding the RPM node. -The RPM exposes resources to its subnodes. The below bindings specify the set -of valid subnodes that can operate on these resources. - -== Regulators +== Regulator Regulator nodes are identified by their compatible: @@ -114,4 +104,3 @@ see regulator.txt. }; }; }; - diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt new file mode 100644 index 0000000000000..a48049ccf6d0d --- /dev/null +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt @@ -0,0 +1,58 @@ +Qualcomm Resource Power Manager (RPM) over SMD + +This driver is used to interface with the Resource Power Manager (RPM) found in +various Qualcomm platforms. The RPM allows each component in the system to vote +for state of the system resources, such as clocks, regulators and bus +frequencies. + +The SMD information for the RPM edge should be filled out. See qcom,smd.txt for +the required edge properties. All SMD related properties will reside within the +RPM node itself. + += SUBDEVICES + +The RPM exposes resources to its subnodes. The rpm_requests node must be +present and this subnode may contain children that designate regulator +resources. + +- compatible: + Usage: required + Value type: + Definition: must be one of: + "qcom,rpm-apq8084" + "qcom,rpm-msm8916" + "qcom,rpm-msm8974" + +- qcom,smd-channels: + Usage: required + Value type: + Definition: must be "rpm_requests" + +Refer to Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt +for information on the regulator subnodes that can exist under the rpm_requests. + +Example: + + soc { + apcs: syscon@f9011000 { + compatible = "syscon"; + reg = <0xf9011000 0x1000>; + }; + }; + + smd { + compatible = "qcom,smd"; + + rpm { + interrupts = <0 168 1>; + qcom,ipc = <&apcs 8 0>; + qcom,smd-edge = <15>; + + rpm_requests { + compatible = "qcom,rpm-msm8974"; + qcom,smd-channels = "rpm_requests"; + + ... + }; + }; + }; -- GitLab From 57d6567680edf9075d14b7fad9473e9c4a4b337e Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Mon, 14 Dec 2015 23:30:44 -0600 Subject: [PATCH 1361/2855] regulator: qcom-smd: Add PM8916 support This patch adds support and documentation for the PM8916 regulators found on MSM8916 platforms. Acked-by: Bjorn Andersson Signed-off-by: Andy Gross Signed-off-by: Mark Brown --- .../regulator/qcom,smd-rpm-regulator.txt | 18 ++++++ drivers/regulator/qcom_smd-regulator.c | 64 +++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt index bda2ed96ba661..82557e1742587 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt @@ -20,6 +20,7 @@ Regulator nodes are identified by their compatible: Value type: Definition: must be one of: "qcom,rpm-pm8841-regulators" + "qcom,rpm-pm8916-regulators" "qcom,rpm-pm8941-regulators" - vdd_s1-supply: @@ -35,6 +36,19 @@ Regulator nodes are identified by their compatible: Definition: reference to regulator supplying the input pin, as described in the data sheet +- vdd_s1-supply: +- vdd_s2-supply: +- vdd_s3-supply: +- vdd_s4-supply: +- vdd_l1_l2_l3-supply: +- vdd_l4_l5_l6-supply: +- vdd_l7-supply: +- vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18-supply: + Usage: optional (pm8916 only) + Value type: + Definition: reference to regulator supplying the input pin, as + described in the data sheet + - vdd_s1-supply: - vdd_s2-supply: - vdd_s3-supply: @@ -60,6 +74,10 @@ of the pmics below. pm8841: s1, s2, s3, s4, s5, s6, s7, s8 +pm8916: + s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, + l14, l15, l16, l17, l18 + pm8941: s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index 6fa0c7d132909..8464eadf2c85f 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -211,6 +211,43 @@ static const struct regulator_desc pm8941_switch = { .ops = &rpm_switch_ops, }; +static const struct regulator_desc pm8916_pldo = { + .linear_ranges = (struct regulator_linear_range[]) { + REGULATOR_LINEAR_RANGE(750000, 0, 208, 12500), + }, + .n_linear_ranges = 1, + .n_voltages = 209, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pm8916_nldo = { + .linear_ranges = (struct regulator_linear_range[]) { + REGULATOR_LINEAR_RANGE(375000, 0, 93, 12500), + }, + .n_linear_ranges = 1, + .n_voltages = 94, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pm8916_buck_lvo_smps = { + .linear_ranges = (struct regulator_linear_range[]) { + REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500), + REGULATOR_LINEAR_RANGE(750000, 96, 127, 25000), + }, + .n_linear_ranges = 2, + .n_voltages = 128, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pm8916_buck_hvo_smps = { + .linear_ranges = (struct regulator_linear_range[]) { + REGULATOR_LINEAR_RANGE(1550000, 0, 31, 25000), + }, + .n_linear_ranges = 1, + .n_voltages = 32, + .ops = &rpm_smps_ldo_ops, +}; + struct rpm_regulator_data { const char *name; u32 type; @@ -231,6 +268,32 @@ static const struct rpm_regulator_data rpm_pm8841_regulators[] = { {} }; +static const struct rpm_regulator_data rpm_pm8916_regulators[] = { + { "s1", QCOM_SMD_RPM_SMPA, 1, &pm8916_buck_lvo_smps, "vdd_s1" }, + { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8916_buck_lvo_smps, "vdd_s2" }, + { "s3", QCOM_SMD_RPM_SMPA, 3, &pm8916_buck_lvo_smps, "vdd_s3" }, + { "s4", QCOM_SMD_RPM_SMPA, 4, &pm8916_buck_hvo_smps, "vdd_s4" }, + { "l1", QCOM_SMD_RPM_LDOA, 1, &pm8916_nldo, "vdd_l1_l2_l3" }, + { "l2", QCOM_SMD_RPM_LDOA, 2, &pm8916_nldo, "vdd_l1_l2_l3" }, + { "l3", QCOM_SMD_RPM_LDOA, 3, &pm8916_nldo, "vdd_l1_l2_l3" }, + { "l4", QCOM_SMD_RPM_LDOA, 4, &pm8916_pldo, "vdd_l4_l5_l6" }, + { "l5", QCOM_SMD_RPM_LDOA, 5, &pm8916_pldo, "vdd_l4_l5_l6" }, + { "l6", QCOM_SMD_RPM_LDOA, 6, &pm8916_pldo, "vdd_l4_l5_l6" }, + { "l7", QCOM_SMD_RPM_LDOA, 7, &pm8916_pldo, "vdd_l7" }, + { "l8", QCOM_SMD_RPM_LDOA, 8, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18" }, + { "l9", QCOM_SMD_RPM_LDOA, 9, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18" }, + { "l10", QCOM_SMD_RPM_LDOA, 10, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + { "l11", QCOM_SMD_RPM_LDOA, 11, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + { "l12", QCOM_SMD_RPM_LDOA, 12, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + { "l13", QCOM_SMD_RPM_LDOA, 13, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + { "l14", QCOM_SMD_RPM_LDOA, 14, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + { "l15", QCOM_SMD_RPM_LDOA, 15, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + { "l16", QCOM_SMD_RPM_LDOA, 16, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + { "l17", QCOM_SMD_RPM_LDOA, 17, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + { "l18", QCOM_SMD_RPM_LDOA, 18, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + {} +}; + static const struct rpm_regulator_data rpm_pm8941_regulators[] = { { "s1", QCOM_SMD_RPM_SMPA, 1, &pm8x41_hfsmps, "vdd_s1" }, { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8x41_hfsmps, "vdd_s2" }, @@ -274,6 +337,7 @@ static const struct rpm_regulator_data rpm_pm8941_regulators[] = { static const struct of_device_id rpm_of_match[] = { { .compatible = "qcom,rpm-pm8841-regulators", .data = &rpm_pm8841_regulators }, + { .compatible = "qcom,rpm-pm8916-regulators", .data = &rpm_pm8916_regulators }, { .compatible = "qcom,rpm-pm8941-regulators", .data = &rpm_pm8941_regulators }, {} }; -- GitLab From ee01d0c91ef1c198fd7819c2eb166580e41dc2ea Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Mon, 14 Dec 2015 23:30:45 -0600 Subject: [PATCH 1362/2855] regulator: qcom-smd: Add support for PMA8084 This patch adds support and documentation for the PMA8084 regulators found on APQ8084 platforms. Signed-off-by: Andy Gross Acked-by: Bjorn Andersson Signed-off-by: Mark Brown --- .../regulator/qcom,smd-rpm-regulator.txt | 35 +++++++ drivers/regulator/qcom_smd-regulator.c | 95 +++++++++++++++++++ 2 files changed, 130 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt index 82557e1742587..1f8d6f84b657d 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt @@ -22,6 +22,7 @@ Regulator nodes are identified by their compatible: "qcom,rpm-pm8841-regulators" "qcom,rpm-pm8916-regulators" "qcom,rpm-pm8941-regulators" + "qcom,rpm-pma8084-regulators" - vdd_s1-supply: - vdd_s2-supply: @@ -67,6 +68,35 @@ Regulator nodes are identified by their compatible: Definition: reference to regulator supplying the input pin, as described in the data sheet +- vdd_s1-supply: +- vdd_s2-supply: +- vdd_s3-supply: +- vdd_s4-supply: +- vdd_s5-supply: +- vdd_s6-supply: +- vdd_s7-supply: +- vdd_s8-supply: +- vdd_s9-supply: +- vdd_s10-supply: +- vdd_s11-supply: +- vdd_s12-supply: +- vdd_l1_l11-supply: +- vdd_l2_l3_l4_l27-supply: +- vdd_l5_l7-supply: +- vdd_l6_l12_l14_l15_l26-supply: +- vdd_l8-supply: +- vdd_l9_l10_l13_l20_l23_l24-supply: +- vdd_l16_l25-supply: +- vdd_l17-supply: +- vdd_l18-supply: +- vdd_l19-supply: +- vdd_l21-supply: +- vdd_l22-supply: + Usage: optional (pma8084 only) + Value type: + Definition: reference to regulator supplying the input pin, as + described in the data sheet + The regulator node houses sub-nodes for each regulator within the device. Each sub-node is identified using the node's name, with valid values listed for each of the pmics below. @@ -83,6 +113,11 @@ pm8941: l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, lvs3, 5vs1, 5vs2 +pma8084: + s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, l1, l2, l3, l4, l5, + l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20, + l21, l22, l23, l24, l25, l26, l27, lvs1, lvs2, lvs3, lvs4, 5vs1 + The content of each sub-node is defined by the standard binding for regulators - see regulator.txt. diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index 8464eadf2c85f..56a17ec5b5efe 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -153,6 +153,49 @@ static const struct regulator_ops rpm_switch_ops = { .is_enabled = rpm_reg_is_enabled, }; +static const struct regulator_desc pma8084_hfsmps = { + .linear_ranges = (struct regulator_linear_range[]) { + REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500), + REGULATOR_LINEAR_RANGE(1550000, 96, 158, 25000), + }, + .n_linear_ranges = 2, + .n_voltages = 159, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pma8084_ftsmps = { + .linear_ranges = (struct regulator_linear_range[]) { + REGULATOR_LINEAR_RANGE(350000, 0, 184, 5000), + REGULATOR_LINEAR_RANGE(700000, 185, 339, 10000), + }, + .n_linear_ranges = 2, + .n_voltages = 340, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pma8084_pldo = { + .linear_ranges = (struct regulator_linear_range[]) { + REGULATOR_LINEAR_RANGE(750000, 0, 30, 25000), + REGULATOR_LINEAR_RANGE(1500000, 31, 99, 50000), + }, + .n_linear_ranges = 2, + .n_voltages = 100, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pma8084_nldo = { + .linear_ranges = (struct regulator_linear_range[]) { + REGULATOR_LINEAR_RANGE(750000, 0, 63, 12500), + }, + .n_linear_ranges = 1, + .n_voltages = 64, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pma8084_switch = { + .ops = &rpm_switch_ops, +}; + static const struct regulator_desc pm8x41_hfsmps = { .linear_ranges = (struct regulator_linear_range[]) { REGULATOR_LINEAR_RANGE( 375000, 0, 95, 12500), @@ -335,10 +378,62 @@ static const struct rpm_regulator_data rpm_pm8941_regulators[] = { {} }; +static const struct rpm_regulator_data rpm_pma8084_regulators[] = { + { "s1", QCOM_SMD_RPM_SMPA, 1, &pma8084_ftsmps, "vdd_s1" }, + { "s2", QCOM_SMD_RPM_SMPA, 2, &pma8084_ftsmps, "vdd_s2" }, + { "s3", QCOM_SMD_RPM_SMPA, 3, &pma8084_hfsmps, "vdd_s3" }, + { "s4", QCOM_SMD_RPM_SMPA, 4, &pma8084_hfsmps, "vdd_s4" }, + { "s5", QCOM_SMD_RPM_SMPA, 5, &pma8084_hfsmps, "vdd_s5" }, + { "s6", QCOM_SMD_RPM_SMPA, 6, &pma8084_ftsmps, "vdd_s6" }, + { "s7", QCOM_SMD_RPM_SMPA, 7, &pma8084_ftsmps, "vdd_s7" }, + { "s8", QCOM_SMD_RPM_SMPA, 8, &pma8084_ftsmps, "vdd_s8" }, + { "s9", QCOM_SMD_RPM_SMPA, 9, &pma8084_ftsmps, "vdd_s9" }, + { "s10", QCOM_SMD_RPM_SMPA, 10, &pma8084_ftsmps, "vdd_s10" }, + { "s11", QCOM_SMD_RPM_SMPA, 11, &pma8084_ftsmps, "vdd_s11" }, + { "s12", QCOM_SMD_RPM_SMPA, 12, &pma8084_ftsmps, "vdd_s12" }, + + { "l1", QCOM_SMD_RPM_LDOA, 1, &pma8084_nldo, "vdd_l1_l11" }, + { "l2", QCOM_SMD_RPM_LDOA, 2, &pma8084_nldo, "vdd_l2_l3_l4_l27" }, + { "l3", QCOM_SMD_RPM_LDOA, 3, &pma8084_nldo, "vdd_l2_l3_l4_l27" }, + { "l4", QCOM_SMD_RPM_LDOA, 4, &pma8084_nldo, "vdd_l2_l3_l4_l27" }, + { "l5", QCOM_SMD_RPM_LDOA, 5, &pma8084_pldo, "vdd_l5_l7" }, + { "l6", QCOM_SMD_RPM_LDOA, 6, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" }, + { "l7", QCOM_SMD_RPM_LDOA, 7, &pma8084_pldo, "vdd_l5_l7" }, + { "l8", QCOM_SMD_RPM_LDOA, 8, &pma8084_pldo, "vdd_l8" }, + { "l9", QCOM_SMD_RPM_LDOA, 9, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, + { "l10", QCOM_SMD_RPM_LDOA, 10, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, + { "l11", QCOM_SMD_RPM_LDOA, 11, &pma8084_nldo, "vdd_l1_l11" }, + { "l12", QCOM_SMD_RPM_LDOA, 12, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" }, + { "l13", QCOM_SMD_RPM_LDOA, 13, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, + { "l14", QCOM_SMD_RPM_LDOA, 14, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" }, + { "l15", QCOM_SMD_RPM_LDOA, 15, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" }, + { "l16", QCOM_SMD_RPM_LDOA, 16, &pma8084_pldo, "vdd_l16_l25" }, + { "l17", QCOM_SMD_RPM_LDOA, 17, &pma8084_pldo, "vdd_l17" }, + { "l18", QCOM_SMD_RPM_LDOA, 18, &pma8084_pldo, "vdd_l18" }, + { "l19", QCOM_SMD_RPM_LDOA, 19, &pma8084_pldo, "vdd_l19" }, + { "l20", QCOM_SMD_RPM_LDOA, 20, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, + { "l21", QCOM_SMD_RPM_LDOA, 21, &pma8084_pldo, "vdd_l21" }, + { "l22", QCOM_SMD_RPM_LDOA, 22, &pma8084_pldo, "vdd_l22" }, + { "l23", QCOM_SMD_RPM_LDOA, 23, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, + { "l24", QCOM_SMD_RPM_LDOA, 24, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, + { "l25", QCOM_SMD_RPM_LDOA, 25, &pma8084_pldo, "vdd_l16_l25" }, + { "l26", QCOM_SMD_RPM_LDOA, 26, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" }, + { "l27", QCOM_SMD_RPM_LDOA, 27, &pma8084_nldo, "vdd_l2_l3_l4_l27" }, + + { "lvs1", QCOM_SMD_RPM_VSA, 1, &pma8084_switch }, + { "lvs2", QCOM_SMD_RPM_VSA, 2, &pma8084_switch }, + { "lvs3", QCOM_SMD_RPM_VSA, 3, &pma8084_switch }, + { "lvs4", QCOM_SMD_RPM_VSA, 4, &pma8084_switch }, + { "5vs1", QCOM_SMD_RPM_VSA, 5, &pma8084_switch }, + + {} +}; + static const struct of_device_id rpm_of_match[] = { { .compatible = "qcom,rpm-pm8841-regulators", .data = &rpm_pm8841_regulators }, { .compatible = "qcom,rpm-pm8916-regulators", .data = &rpm_pm8916_regulators }, { .compatible = "qcom,rpm-pm8941-regulators", .data = &rpm_pm8941_regulators }, + { .compatible = "qcom,rpm-pma8084-regulators", .data = &rpm_pma8084_regulators }, {} }; MODULE_DEVICE_TABLE(of, rpm_of_match); -- GitLab From 5306661eff1a70f99456340eddf8e0cf85c2e8af Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Fri, 20 Nov 2015 16:13:07 -0600 Subject: [PATCH 1363/2855] usb: phy: correct the am335x phy header filename The filename of am35x-phy-control.h is confusing. The header is used by the am335x phy driver, but the filename refers to am35x. Even worse there is indeed another device called am35x but it does not use this header at all. Signed-off-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-am335x-control.c | 2 +- drivers/usb/phy/{am35x-phy-control.h => phy-am335x-control.h} | 0 drivers/usb/phy/phy-am335x.c | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename drivers/usb/phy/{am35x-phy-control.h => phy-am335x-control.h} (100%) diff --git a/drivers/usb/phy/phy-am335x-control.c b/drivers/usb/phy/phy-am335x-control.c index 7b3035ff94347..23fca5192a6ba 100644 --- a/drivers/usb/phy/phy-am335x-control.c +++ b/drivers/usb/phy/phy-am335x-control.c @@ -4,7 +4,7 @@ #include #include #include -#include "am35x-phy-control.h" +#include "phy-am335x-control.h" struct am335x_control_usb { struct device *dev; diff --git a/drivers/usb/phy/am35x-phy-control.h b/drivers/usb/phy/phy-am335x-control.h similarity index 100% rename from drivers/usb/phy/am35x-phy-control.h rename to drivers/usb/phy/phy-am335x-control.h diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c index 90b67a4ca2216..8b6139dec5ebb 100644 --- a/drivers/usb/phy/phy-am335x.c +++ b/drivers/usb/phy/phy-am335x.c @@ -9,7 +9,7 @@ #include #include -#include "am35x-phy-control.h" +#include "phy-am335x-control.h" #include "phy-generic.h" struct am335x_phy { -- GitLab From 59f042f644c5aa10b65b7881966bed78c5c82923 Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Tue, 8 Dec 2015 10:31:50 -0600 Subject: [PATCH 1364/2855] usb: phy: phy-am335x: bypass first VBUS sensing for host-only mode To prevent VBUS contention, the am335x MUSB phy senses VBUS first before transitioning to host mode. However, for host-only mode, VBUS could be directly tied to 5V power rail which could prevent MUSB transitions to host mode. This change receives dr_mode of the controller then bypass the first VBUS sensing for host-only mode, so that MUSB can work in host mode event if VBUS is tied to 5V. Signed-off-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/phy/Kconfig | 1 + drivers/usb/phy/phy-am335x-control.c | 14 +++++++++++--- drivers/usb/phy/phy-am335x-control.h | 8 +++++--- drivers/usb/phy/phy-am335x.c | 15 ++++++++++----- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 155694c1a5366..c6904742e2aa4 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -66,6 +66,7 @@ config AM335X_PHY_USB select USB_PHY select AM335X_CONTROL_USB select NOP_USB_XCEIV + select USB_COMMON help This driver provides PHY support for that phy which part for the AM335x SoC. diff --git a/drivers/usb/phy/phy-am335x-control.c b/drivers/usb/phy/phy-am335x-control.c index 23fca5192a6ba..42a1afe36a905 100644 --- a/drivers/usb/phy/phy-am335x-control.c +++ b/drivers/usb/phy/phy-am335x-control.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "phy-am335x-control.h" struct am335x_control_usb { @@ -58,7 +59,8 @@ static void am335x_phy_wkup(struct phy_control *phy_ctrl, u32 id, bool on) spin_unlock(&usb_ctrl->lock); } -static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on) +static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, + enum usb_dr_mode dr_mode, bool on) { struct am335x_control_usb *usb_ctrl; u32 val; @@ -80,8 +82,14 @@ static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on) val = readl(usb_ctrl->phy_reg + reg); if (on) { - val &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN); - val |= USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN; + if (dr_mode == USB_DR_MODE_HOST) { + val &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN | + USBPHY_OTGVDET_EN); + val |= USBPHY_OTGSESSEND_EN; + } else { + val &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN); + val |= USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN; + } } else { val |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN; } diff --git a/drivers/usb/phy/phy-am335x-control.h b/drivers/usb/phy/phy-am335x-control.h index b96594d1962c9..e86b3165d69d3 100644 --- a/drivers/usb/phy/phy-am335x-control.h +++ b/drivers/usb/phy/phy-am335x-control.h @@ -2,13 +2,15 @@ #define _AM335x_PHY_CONTROL_H_ struct phy_control { - void (*phy_power)(struct phy_control *phy_ctrl, u32 id, bool on); + void (*phy_power)(struct phy_control *phy_ctrl, u32 id, + enum usb_dr_mode dr_mode, bool on); void (*phy_wkup)(struct phy_control *phy_ctrl, u32 id, bool on); }; -static inline void phy_ctrl_power(struct phy_control *phy_ctrl, u32 id, bool on) +static inline void phy_ctrl_power(struct phy_control *phy_ctrl, u32 id, + enum usb_dr_mode dr_mode, bool on) { - phy_ctrl->phy_power(phy_ctrl, id, on); + phy_ctrl->phy_power(phy_ctrl, id, dr_mode, on); } static inline void phy_ctrl_wkup(struct phy_control *phy_ctrl, u32 id, bool on) diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c index 8b6139dec5ebb..39b424f7f6295 100644 --- a/drivers/usb/phy/phy-am335x.c +++ b/drivers/usb/phy/phy-am335x.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "phy-am335x-control.h" #include "phy-generic.h" @@ -16,13 +17,14 @@ struct am335x_phy { struct usb_phy_generic usb_phy_gen; struct phy_control *phy_ctrl; int id; + enum usb_dr_mode dr_mode; }; static int am335x_init(struct usb_phy *phy) { struct am335x_phy *am_phy = dev_get_drvdata(phy->dev); - phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, true); + phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, true); return 0; } @@ -30,7 +32,7 @@ static void am335x_shutdown(struct usb_phy *phy) { struct am335x_phy *am_phy = dev_get_drvdata(phy->dev); - phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, false); + phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, false); } static int am335x_phy_probe(struct platform_device *pdev) @@ -46,12 +48,15 @@ static int am335x_phy_probe(struct platform_device *pdev) am_phy->phy_ctrl = am335x_get_phy_control(dev); if (!am_phy->phy_ctrl) return -EPROBE_DEFER; + am_phy->id = of_alias_get_id(pdev->dev.of_node, "phy"); if (am_phy->id < 0) { dev_err(&pdev->dev, "Missing PHY id: %d\n", am_phy->id); return am_phy->id; } + am_phy->dr_mode = of_usb_get_dr_mode_by_phy(pdev->dev.of_node); + ret = usb_phy_gen_create_phy(dev, &am_phy->usb_phy_gen, NULL); if (ret) return ret; @@ -75,7 +80,7 @@ static int am335x_phy_probe(struct platform_device *pdev) */ device_set_wakeup_enable(dev, false); - phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, false); + phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, false); return 0; } @@ -105,7 +110,7 @@ static int am335x_phy_suspend(struct device *dev) if (device_may_wakeup(dev)) phy_ctrl_wkup(am_phy->phy_ctrl, am_phy->id, true); - phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, false); + phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, false); return 0; } @@ -115,7 +120,7 @@ static int am335x_phy_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct am335x_phy *am_phy = platform_get_drvdata(pdev); - phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, true); + phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, true); if (device_may_wakeup(dev)) phy_ctrl_wkup(am_phy->phy_ctrl, am_phy->id, false); -- GitLab From 2284b29d3d9dd16490909962574d7f3fef83fd97 Mon Sep 17 00:00:00 2001 From: Ruslan Bilovol Date: Mon, 23 Nov 2015 09:56:35 +0100 Subject: [PATCH 1365/2855] usb: gadget: bind UDC by name passed via usb_gadget_driver structure Introduce new 'udc_name' member to usb_gadget_driver structure. The 'udc_name' is a name of UDC that usb_gadget_driver should be bound to. If udc_name is NULL, it will be bound to any available UDC. Tested-by: Maxime Ripard Signed-off-by: Ruslan Bilovol Signed-off-by: Marek Szyprowski Tested-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/udc-core.c | 24 +++++++++++++++++++----- include/linux/usb/gadget.h | 4 ++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index f660afba715da..429d64e679414 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -549,21 +549,35 @@ EXPORT_SYMBOL_GPL(usb_udc_attach_driver); int usb_gadget_probe_driver(struct usb_gadget_driver *driver) { struct usb_udc *udc = NULL; - int ret; + int ret = -ENODEV; if (!driver || !driver->bind || !driver->setup) return -EINVAL; mutex_lock(&udc_lock); - list_for_each_entry(udc, &udc_list, list) { - /* For now we take the first one */ - if (!udc->driver) + if (driver->udc_name) { + list_for_each_entry(udc, &udc_list, list) { + ret = strcmp(driver->udc_name, dev_name(&udc->dev)); + if (!ret) + break; + } + if (ret) + ret = -ENODEV; + else if (udc->driver) + ret = -EBUSY; + else goto found; + } else { + list_for_each_entry(udc, &udc_list, list) { + /* For now we take the first one */ + if (!udc->driver) + goto found; + } } pr_debug("couldn't find an available UDC\n"); mutex_unlock(&udc_lock); - return -ENODEV; + return ret; found: ret = udc_bind_to_driver(udc, driver); mutex_unlock(&udc_lock); diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 3d583a10b9269..63963c21866df 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -1012,6 +1012,8 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget) * @reset: Invoked on USB bus reset. It is mandatory for all gadget drivers * and should be called in_interrupt. * @driver: Driver model state for this driver. + * @udc_name: A name of UDC this driver should be bound to. If udc_name is NULL, + * this driver will be bound to any available UDC. * * Devices are disabled till a gadget driver successfully bind()s, which * means the driver will handle setup() requests needed to enumerate (and @@ -1072,6 +1074,8 @@ struct usb_gadget_driver { /* FIXME support safe rmmod */ struct device_driver driver; + + char *udc_name; }; -- GitLab From afdaadc3c8530b4bc20777bc6ec15bda89b3bd65 Mon Sep 17 00:00:00 2001 From: Ruslan Bilovol Date: Mon, 23 Nov 2015 09:56:36 +0100 Subject: [PATCH 1366/2855] usb: gadget: configfs: pass UDC name via usb_gadget_driver struct Now when udc-core supports binding to specific UDC by passing its name via 'udc_name' member of usb_gadget_driver struct, switch to this generic approach. Tested-by: Maxime Ripard Signed-off-by: Ruslan Bilovol [rebased and fixed checkpatch issues] Signed-off-by: Marek Szyprowski Tested-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/configfs.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 163d305e1200b..590c44989e5eb 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -56,7 +56,6 @@ struct gadget_info { struct list_head string_list; struct list_head available_func; - const char *udc_name; struct usb_composite_driver composite; struct usb_composite_dev cdev; bool use_os_desc; @@ -233,21 +232,23 @@ static ssize_t gadget_dev_desc_bcdUSB_store(struct config_item *item, static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page) { - return sprintf(page, "%s\n", to_gadget_info(item)->udc_name ?: ""); + char *udc_name = to_gadget_info(item)->composite.gadget_driver.udc_name; + + return sprintf(page, "%s\n", udc_name ?: ""); } static int unregister_gadget(struct gadget_info *gi) { int ret; - if (!gi->udc_name) + if (!gi->composite.gadget_driver.udc_name) return -ENODEV; ret = usb_gadget_unregister_driver(&gi->composite.gadget_driver); if (ret) return ret; - kfree(gi->udc_name); - gi->udc_name = NULL; + kfree(gi->composite.gadget_driver.udc_name); + gi->composite.gadget_driver.udc_name = NULL; return 0; } @@ -271,14 +272,16 @@ static ssize_t gadget_dev_desc_UDC_store(struct config_item *item, if (ret) goto err; } else { - if (gi->udc_name) { + if (gi->composite.gadget_driver.udc_name) { ret = -EBUSY; goto err; } - ret = usb_udc_attach_driver(name, &gi->composite.gadget_driver); - if (ret) + gi->composite.gadget_driver.udc_name = name; + ret = usb_gadget_probe_driver(&gi->composite.gadget_driver); + if (ret) { + gi->composite.gadget_driver.udc_name = NULL; goto err; - gi->udc_name = name; + } } mutex_unlock(&gi->lock); return len; @@ -427,9 +430,9 @@ static int config_usb_cfg_unlink( * remove the function. */ mutex_lock(&gi->lock); - if (gi->udc_name) + if (gi->composite.gadget_driver.udc_name) unregister_gadget(gi); - WARN_ON(gi->udc_name); + WARN_ON(gi->composite.gadget_driver.udc_name); list_for_each_entry(f, &cfg->func_list, list) { if (f->fi == fi) { @@ -873,10 +876,10 @@ static int os_desc_unlink(struct config_item *os_desc_ci, struct usb_composite_dev *cdev = &gi->cdev; mutex_lock(&gi->lock); - if (gi->udc_name) + if (gi->composite.gadget_driver.udc_name) unregister_gadget(gi); cdev->os_desc_config = NULL; - WARN_ON(gi->udc_name); + WARN_ON(gi->composite.gadget_driver.udc_name); mutex_unlock(&gi->lock); return 0; } -- GitLab From 88f73ebdfa75602af18e070a4d5d6d9091bcfada Mon Sep 17 00:00:00 2001 From: Ruslan Bilovol Date: Mon, 23 Nov 2015 09:56:37 +0100 Subject: [PATCH 1367/2855] usb: gadget: udc-core: remove unused usb_udc_attach_driver() Now when last user of usb_udc_attach_driver() is switched to passing UDC name via usb_gadget_driver struct, it's safe to remove this function Tested-by: Maxime Ripard Signed-off-by: Ruslan Bilovol Signed-off-by: Marek Szyprowski Tested-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/udc-core.c | 26 -------------------------- include/linux/usb/gadget.h | 2 -- 2 files changed, 28 deletions(-) diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index 429d64e679414..f76ebc8c1ed24 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -520,32 +520,6 @@ err1: return ret; } -int usb_udc_attach_driver(const char *name, struct usb_gadget_driver *driver) -{ - struct usb_udc *udc = NULL; - int ret = -ENODEV; - - mutex_lock(&udc_lock); - list_for_each_entry(udc, &udc_list, list) { - ret = strcmp(name, dev_name(&udc->dev)); - if (!ret) - break; - } - if (ret) { - ret = -ENODEV; - goto out; - } - if (udc->driver) { - ret = -EBUSY; - goto out; - } - ret = udc_bind_to_driver(udc, driver); -out: - mutex_unlock(&udc_lock); - return ret; -} -EXPORT_SYMBOL_GPL(usb_udc_attach_driver); - int usb_gadget_probe_driver(struct usb_gadget_driver *driver) { struct usb_udc *udc = NULL; diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 63963c21866df..ce2188d338e60 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -1121,8 +1121,6 @@ extern int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, void (*release)(struct device *dev)); extern int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget); extern void usb_del_gadget_udc(struct usb_gadget *gadget); -extern int usb_udc_attach_driver(const char *name, - struct usb_gadget_driver *driver); /*-------------------------------------------------------------------------*/ -- GitLab From 855ed04a3758b205e84b269f92d26ab36ed8e2f7 Mon Sep 17 00:00:00 2001 From: Ruslan Bilovol Date: Mon, 23 Nov 2015 09:56:38 +0100 Subject: [PATCH 1368/2855] usb: gadget: udc-core: independent registration of gadgets and gadget drivers Change behavior during registration of gadgets and gadget drivers in udc-core. Instead of previous approach when for successful probe of usb gadget driver at least one usb gadget should be already registered use another one where gadget drivers and gadgets can be registered in udc-core independently. Independent registration of gadgets and gadget drivers is useful for built-in into kernel gadget and gadget driver case - because it's possible that gadget is really probed only on late_init stage (due to deferred probe) whereas gadget driver's probe is silently failed on module_init stage due to no any UDC added. Also it is useful for modules case - now there is no difference what module to insert first: gadget module or gadget driver one. Tested-by: Maxime Ripard Signed-off-by: Ruslan Bilovol [simplified code as requested by Alan Stern and Felipe Balbi, fixed checkpatch issues] Signed-off-by: Marek Szyprowski Tested-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/udc-core.c | 41 ++++++++++++++++++++++++------- include/linux/usb/gadget.h | 2 ++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index f76ebc8c1ed24..fd73a3ea07c20 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -51,8 +51,12 @@ struct usb_udc { static struct class *udc_class; static LIST_HEAD(udc_list); +static LIST_HEAD(gadget_driver_pending_list); static DEFINE_MUTEX(udc_lock); +static int udc_bind_to_driver(struct usb_udc *udc, + struct usb_gadget_driver *driver); + /* ------------------------------------------------------------------------- */ #ifdef CONFIG_HAS_DMA @@ -356,6 +360,7 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, void (*release)(struct device *dev)) { struct usb_udc *udc; + struct usb_gadget_driver *driver; int ret = -ENOMEM; udc = kzalloc(sizeof(*udc), GFP_KERNEL); @@ -403,6 +408,18 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED); udc->vbus = true; + /* pick up one of pending gadget drivers */ + list_for_each_entry(driver, &gadget_driver_pending_list, pending) { + if (!driver->udc_name || strcmp(driver->udc_name, + dev_name(&udc->dev)) == 0) { + ret = udc_bind_to_driver(udc, driver); + if (ret) + goto err4; + list_del(&driver->pending); + break; + } + } + mutex_unlock(&udc_lock); return 0; @@ -473,10 +490,14 @@ void usb_del_gadget_udc(struct usb_gadget *gadget) mutex_lock(&udc_lock); list_del(&udc->list); - mutex_unlock(&udc_lock); - if (udc->driver) + if (udc->driver) { + struct usb_gadget_driver *driver = udc->driver; + usb_gadget_remove_driver(udc); + list_add(&driver->pending, &gadget_driver_pending_list); + } + mutex_unlock(&udc_lock); kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE); flush_work(&gadget->work); @@ -535,11 +556,7 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver) if (!ret) break; } - if (ret) - ret = -ENODEV; - else if (udc->driver) - ret = -EBUSY; - else + if (!ret && !udc->driver) goto found; } else { list_for_each_entry(udc, &udc_list, list) { @@ -549,9 +566,11 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver) } } - pr_debug("couldn't find an available UDC\n"); + list_add_tail(&driver->pending, &gadget_driver_pending_list); + pr_info("udc-core: couldn't find an available UDC - added [%s] to list of pending drivers\n", + driver->function); mutex_unlock(&udc_lock); - return ret; + return 0; found: ret = udc_bind_to_driver(udc, driver); mutex_unlock(&udc_lock); @@ -577,6 +596,10 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) break; } + if (ret) { + list_del(&driver->pending); + ret = 0; + } mutex_unlock(&udc_lock); return ret; } diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index ce2188d338e60..92467eea76def 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -1014,6 +1014,7 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget) * @driver: Driver model state for this driver. * @udc_name: A name of UDC this driver should be bound to. If udc_name is NULL, * this driver will be bound to any available UDC. + * @pending: UDC core private data used for deferred probe of this driver. * * Devices are disabled till a gadget driver successfully bind()s, which * means the driver will handle setup() requests needed to enumerate (and @@ -1076,6 +1077,7 @@ struct usb_gadget_driver { struct device_driver driver; char *udc_name; + struct list_head pending; }; -- GitLab From 95ca961c758cd9ce789247098b09c39017637e58 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 10 Dec 2015 13:08:20 -0600 Subject: [PATCH 1369/2855] usb: dwc3: gadget: pass a condition to dev_WARN_ONCE() instead of using: if (condition) { dev_WARN_ONCE(dev, true, "foo"); return -EINVAL; } let's use: if (dev_WARN_ONCE(dev, condition, "foo")) return -EINVAL; Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 975801839355a..64b2a8303d33d 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -661,11 +661,10 @@ static int dwc3_gadget_ep_enable(struct usb_ep *ep, dep = to_dwc3_ep(ep); dwc = dep->dwc; - if (dep->flags & DWC3_EP_ENABLED) { - dev_WARN_ONCE(dwc->dev, true, "%s is already enabled\n", - dep->name); + if (dev_WARN_ONCE(dwc->dev, dep->flags & DWC3_EP_ENABLED, + "%s is already enabled\n", + dep->name)) return 0; - } spin_lock_irqsave(&dwc->lock, flags); ret = __dwc3_gadget_ep_enable(dep, desc, ep->comp_desc, false, false); @@ -689,11 +688,10 @@ static int dwc3_gadget_ep_disable(struct usb_ep *ep) dep = to_dwc3_ep(ep); dwc = dep->dwc; - if (!(dep->flags & DWC3_EP_ENABLED)) { - dev_WARN_ONCE(dwc->dev, true, "%s is already disabled\n", - dep->name); + if (dev_WARN_ONCE(dwc->dev, !(dep->flags & DWC3_EP_ENABLED), + "%s is already disabled\n", + dep->name)) return 0; - } spin_lock_irqsave(&dwc->lock, flags); ret = __dwc3_gadget_ep_disable(dep); -- GitLab From ca07099460231576cd7aceed5da47a06cee8063b Mon Sep 17 00:00:00 2001 From: "Geyslan G. Bem" Date: Thu, 10 Dec 2015 17:50:10 -0300 Subject: [PATCH 1370/2855] usb: gadget: s3c-hsudc: remove redundant condition This patch removes redundant condition. (!A || (A && B)) is the same as (!A || B). Tested by compilation only. Caught by cppcheck. Signed-off-by: Geyslan G. Bem Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/s3c-hsudc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/s3c-hsudc.c b/drivers/usb/gadget/udc/s3c-hsudc.c index e9def42ce50d7..82a9e2a3bedc2 100644 --- a/drivers/usb/gadget/udc/s3c-hsudc.c +++ b/drivers/usb/gadget/udc/s3c-hsudc.c @@ -569,7 +569,7 @@ static int s3c_hsudc_handle_reqfeat(struct s3c_hsudc *hsudc, hsep = &hsudc->ep[ep_num]; switch (le16_to_cpu(ctrl->wValue)) { case USB_ENDPOINT_HALT: - if (set || (!set && !hsep->wedge)) + if (set || !hsep->wedge) s3c_hsudc_set_halt(&hsep->ep, set); return 0; } -- GitLab From 1a1716260008b16887d72b417bd069ee4220c42e Mon Sep 17 00:00:00 2001 From: "Geyslan G. Bem" Date: Thu, 10 Dec 2015 17:50:12 -0300 Subject: [PATCH 1371/2855] usb: musb: gadget: remove redundant condition This patch removes redundant condition. (!A || (A && B)) is the same as (!A || B). Fixes indentation too. Tested by: compilation only Caught by: cppcheck Signed-off-by: Geyslan G. Bem Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 67ad630c86c9c..87bd578799a8a 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -353,9 +353,8 @@ static void txstate(struct musb *musb, struct musb_request *req) * 1 >0 Yes(FS bulk) */ if (!musb_ep->hb_mult || - (musb_ep->hb_mult && - can_bulk_split(musb, - musb_ep->type))) + can_bulk_split(musb, + musb_ep->type)) csr |= MUSB_TXCSR_AUTOSET; } csr &= ~MUSB_TXCSR_P_UNDERRUN; -- GitLab From 8055555fc4590fbda32d4bbf7888bdb2cd4b2b74 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 30 Nov 2015 21:37:12 -0800 Subject: [PATCH 1372/2855] usb: musb: core: Fix handling of the phy notifications We currently can't unload omap2430 MUSB platform glue driver module and this cause issues for fixing the MUSB code further. The reason we can't remove omap2430 is because it uses the PHY functions and also exports the omap_musb_mailbox function that some PHY drivers are using. Let's fix the issue by exporting a more generic musb_mailbox function from the MUSB core and allow platform glue layers to register phy_callback function as needed. And now we can now also get rid of the include/linux/musb-omap.h. Cc: Bin Liu Cc: Felipe Balbi Cc: Kishon Vijay Abraham I Cc: NeilBrown Reviewed-by: Kishon Vijay Abraham I Signed-off-by: Tony Lindgren Signed-off-by: Felipe Balbi --- drivers/phy/phy-twl4030-usb.c | 32 +++++++++++++++---------------- drivers/usb/musb/musb_core.c | 21 ++++++++++++++++++++ drivers/usb/musb/musb_core.h | 2 ++ drivers/usb/musb/omap2430.c | 27 +++++++++++++------------- drivers/usb/phy/phy-twl6030-usb.c | 30 ++++++++++++++--------------- include/linux/usb/musb-omap.h | 30 ----------------------------- include/linux/usb/musb.h | 15 +++++++++++++++ 7 files changed, 83 insertions(+), 74 deletions(-) delete mode 100644 include/linux/usb/musb-omap.h diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c index 3a707dd14238e..4a3fc6e59f8e1 100644 --- a/drivers/phy/phy-twl4030-usb.c +++ b/drivers/phy/phy-twl4030-usb.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include @@ -148,10 +148,10 @@ * If VBUS is valid or ID is ground, then we know a * cable is present and we need to be runtime-enabled */ -static inline bool cable_present(enum omap_musb_vbus_id_status stat) +static inline bool cable_present(enum musb_vbus_id_status stat) { - return stat == OMAP_MUSB_VBUS_VALID || - stat == OMAP_MUSB_ID_GROUND; + return stat == MUSB_VBUS_VALID || + stat == MUSB_ID_GROUND; } struct twl4030_usb { @@ -170,7 +170,7 @@ struct twl4030_usb { enum twl4030_usb_mode usb_mode; int irq; - enum omap_musb_vbus_id_status linkstat; + enum musb_vbus_id_status linkstat; bool vbus_supplied; struct delayed_work id_workaround_work; @@ -276,11 +276,11 @@ static bool twl4030_is_driving_vbus(struct twl4030_usb *twl) return (ret & (ULPI_OTG_DRVVBUS | ULPI_OTG_CHRGVBUS)) ? true : false; } -static enum omap_musb_vbus_id_status +static enum musb_vbus_id_status twl4030_usb_linkstat(struct twl4030_usb *twl) { int status; - enum omap_musb_vbus_id_status linkstat = OMAP_MUSB_UNKNOWN; + enum musb_vbus_id_status linkstat = MUSB_UNKNOWN; twl->vbus_supplied = false; @@ -306,14 +306,14 @@ static enum omap_musb_vbus_id_status } if (status & BIT(2)) - linkstat = OMAP_MUSB_ID_GROUND; + linkstat = MUSB_ID_GROUND; else if (status & BIT(7)) - linkstat = OMAP_MUSB_VBUS_VALID; + linkstat = MUSB_VBUS_VALID; else - linkstat = OMAP_MUSB_VBUS_OFF; + linkstat = MUSB_VBUS_OFF; } else { - if (twl->linkstat != OMAP_MUSB_UNKNOWN) - linkstat = OMAP_MUSB_VBUS_OFF; + if (twl->linkstat != MUSB_UNKNOWN) + linkstat = MUSB_VBUS_OFF; } dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", @@ -535,7 +535,7 @@ static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL); static irqreturn_t twl4030_usb_irq(int irq, void *_twl) { struct twl4030_usb *twl = _twl; - enum omap_musb_vbus_id_status status; + enum musb_vbus_id_status status; bool status_changed = false; status = twl4030_usb_linkstat(twl); @@ -567,11 +567,11 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) pm_runtime_mark_last_busy(twl->dev); pm_runtime_put_autosuspend(twl->dev); } - omap_musb_mailbox(status); + musb_mailbox(status); } /* don't schedule during sleep - irq works right then */ - if (status == OMAP_MUSB_ID_GROUND && pm_runtime_active(twl->dev)) { + if (status == MUSB_ID_GROUND && pm_runtime_active(twl->dev)) { cancel_delayed_work(&twl->id_workaround_work); schedule_delayed_work(&twl->id_workaround_work, HZ); } @@ -670,7 +670,7 @@ static int twl4030_usb_probe(struct platform_device *pdev) twl->dev = &pdev->dev; twl->irq = platform_get_irq(pdev, 0); twl->vbus_supplied = false; - twl->linkstat = OMAP_MUSB_UNKNOWN; + twl->linkstat = MUSB_UNKNOWN; twl->phy.dev = twl->dev; twl->phy.label = "twl4030"; diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index cd37e9fc2e629..04548423094b8 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1702,6 +1702,23 @@ EXPORT_SYMBOL_GPL(musb_dma_completion); #define use_dma 0 #endif +static void (*musb_phy_callback)(enum musb_vbus_id_status status); + +/* + * musb_mailbox - optional phy notifier function + * @status phy state change + * + * Optionally gets called from the USB PHY. Note that the USB PHY must be + * disabled at the point the phy_callback is registered or unregistered. + */ +void musb_mailbox(enum musb_vbus_id_status status) +{ + if (musb_phy_callback) + musb_phy_callback(status); + +}; +EXPORT_SYMBOL_GPL(musb_mailbox); + /*-------------------------------------------------------------------------*/ static ssize_t @@ -2114,6 +2131,9 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) musb->xceiv->io_ops = &musb_ulpi_access; } + if (musb->ops->phy_callback) + musb_phy_callback = musb->ops->phy_callback; + pm_runtime_get_sync(musb->controller); if (use_dma && dev->dma_mask) { @@ -2292,6 +2312,7 @@ static int musb_remove(struct platform_device *pdev) */ musb_exit_debugfs(musb); musb_shutdown(pdev); + musb_phy_callback = NULL; if (musb->dma_controller) musb_dma_controller_destroy(musb->dma_controller); diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 2337d7a7d62d6..fd215fb45fd40 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -168,6 +168,7 @@ struct musb_io; * @adjust_channel_params: pre check for standard dma channel_program func * @pre_root_reset_end: called before the root usb port reset flag gets cleared * @post_root_reset_end: called after the root usb port reset flag gets cleared + * @phy_callback: optional callback function for the phy to call */ struct musb_platform_ops { @@ -214,6 +215,7 @@ struct musb_platform_ops { dma_addr_t *dma_addr, u32 *len); void (*pre_root_reset_end)(struct musb *musb); void (*post_root_reset_end)(struct musb *musb); + void (*phy_callback)(enum musb_vbus_id_status status); }; /* diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 1bd9232ff76fc..bf05f807729f8 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include @@ -46,7 +46,7 @@ struct omap2430_glue { struct device *dev; struct platform_device *musb; - enum omap_musb_vbus_id_status status; + enum musb_vbus_id_status status; struct work_struct omap_musb_mailbox_work; struct device *control_otghs; }; @@ -234,7 +234,7 @@ static inline void omap2430_low_level_init(struct musb *musb) musb_writel(musb->mregs, OTG_FORCESTDBY, l); } -void omap_musb_mailbox(enum omap_musb_vbus_id_status status) +static void omap2430_musb_mailbox(enum musb_vbus_id_status status) { struct omap2430_glue *glue = _glue; @@ -251,7 +251,6 @@ void omap_musb_mailbox(enum omap_musb_vbus_id_status status) schedule_work(&glue->omap_musb_mailbox_work); } -EXPORT_SYMBOL_GPL(omap_musb_mailbox); static void omap_musb_set_mailbox(struct omap2430_glue *glue) { @@ -262,7 +261,7 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) struct usb_otg *otg = musb->xceiv->otg; switch (glue->status) { - case OMAP_MUSB_ID_GROUND: + case MUSB_ID_GROUND: dev_dbg(dev, "ID GND\n"); otg->default_a = true; @@ -276,7 +275,7 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) } break; - case OMAP_MUSB_VBUS_VALID: + case MUSB_VBUS_VALID: dev_dbg(dev, "VBUS Connect\n"); otg->default_a = false; @@ -287,8 +286,8 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE); break; - case OMAP_MUSB_ID_FLOAT: - case OMAP_MUSB_VBUS_OFF: + case MUSB_ID_FLOAT: + case MUSB_VBUS_OFF: dev_dbg(dev, "VBUS Disconnect\n"); musb->xceiv->last_event = USB_EVENT_NONE; @@ -430,7 +429,7 @@ static int omap2430_musb_init(struct musb *musb) setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); - if (glue->status != OMAP_MUSB_UNKNOWN) + if (glue->status != MUSB_UNKNOWN) omap_musb_set_mailbox(glue); phy_init(musb->phy); @@ -455,7 +454,7 @@ static void omap2430_musb_enable(struct musb *musb) switch (glue->status) { - case OMAP_MUSB_ID_GROUND: + case MUSB_ID_GROUND: omap_control_usb_set_mode(glue->control_otghs, USB_MODE_HOST); if (data->interface_type != MUSB_INTERFACE_UTMI) break; @@ -474,7 +473,7 @@ static void omap2430_musb_enable(struct musb *musb) } break; - case OMAP_MUSB_VBUS_VALID: + case MUSB_VBUS_VALID: omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE); break; @@ -488,7 +487,7 @@ static void omap2430_musb_disable(struct musb *musb) struct device *dev = musb->controller; struct omap2430_glue *glue = dev_get_drvdata(dev->parent); - if (glue->status != OMAP_MUSB_UNKNOWN) + if (glue->status != MUSB_UNKNOWN) omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DISCONNECT); } @@ -520,6 +519,8 @@ static const struct musb_platform_ops omap2430_ops = { .enable = omap2430_musb_enable, .disable = omap2430_musb_disable, + + .phy_callback = omap2430_musb_mailbox, }; static u64 omap2430_dmamask = DMA_BIT_MASK(32); @@ -551,7 +552,7 @@ static int omap2430_probe(struct platform_device *pdev) glue->dev = &pdev->dev; glue->musb = musb; - glue->status = OMAP_MUSB_UNKNOWN; + glue->status = MUSB_UNKNOWN; glue->control_otghs = ERR_PTR(-ENODEV); if (np) { diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c index 12741856a75c3..014dbbd721320 100644 --- a/drivers/usb/phy/phy-twl6030-usb.c +++ b/drivers/usb/phy/phy-twl6030-usb.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include @@ -102,7 +102,7 @@ struct twl6030_usb { int irq1; int irq2; - enum omap_musb_vbus_id_status linkstat; + enum musb_vbus_id_status linkstat; u8 asleep; bool vbus_enable; const char *regulator; @@ -189,13 +189,13 @@ static ssize_t twl6030_usb_vbus_show(struct device *dev, spin_lock_irqsave(&twl->lock, flags); switch (twl->linkstat) { - case OMAP_MUSB_VBUS_VALID: + case MUSB_VBUS_VALID: ret = snprintf(buf, PAGE_SIZE, "vbus\n"); break; - case OMAP_MUSB_ID_GROUND: + case MUSB_ID_GROUND: ret = snprintf(buf, PAGE_SIZE, "id\n"); break; - case OMAP_MUSB_VBUS_OFF: + case MUSB_VBUS_OFF: ret = snprintf(buf, PAGE_SIZE, "none\n"); break; default: @@ -210,7 +210,7 @@ static DEVICE_ATTR(vbus, 0444, twl6030_usb_vbus_show, NULL); static irqreturn_t twl6030_usb_irq(int irq, void *_twl) { struct twl6030_usb *twl = _twl; - enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN; + enum musb_vbus_id_status status = MUSB_UNKNOWN; u8 vbus_state, hw_state; int ret; @@ -225,14 +225,14 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl) dev_err(twl->dev, "Failed to enable usb3v3\n"); twl->asleep = 1; - status = OMAP_MUSB_VBUS_VALID; + status = MUSB_VBUS_VALID; twl->linkstat = status; - omap_musb_mailbox(status); + musb_mailbox(status); } else { - if (twl->linkstat != OMAP_MUSB_UNKNOWN) { - status = OMAP_MUSB_VBUS_OFF; + if (twl->linkstat != MUSB_UNKNOWN) { + status = MUSB_VBUS_OFF; twl->linkstat = status; - omap_musb_mailbox(status); + musb_mailbox(status); if (twl->asleep) { regulator_disable(twl->usb3v3); twl->asleep = 0; @@ -248,7 +248,7 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl) static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) { struct twl6030_usb *twl = _twl; - enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN; + enum musb_vbus_id_status status = MUSB_UNKNOWN; u8 hw_state; int ret; @@ -262,9 +262,9 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) twl->asleep = 1; twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_CLR); twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_SET); - status = OMAP_MUSB_ID_GROUND; + status = MUSB_ID_GROUND; twl->linkstat = status; - omap_musb_mailbox(status); + musb_mailbox(status); } else { twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_CLR); twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); @@ -334,7 +334,7 @@ static int twl6030_usb_probe(struct platform_device *pdev) twl->dev = &pdev->dev; twl->irq1 = platform_get_irq(pdev, 0); twl->irq2 = platform_get_irq(pdev, 1); - twl->linkstat = OMAP_MUSB_UNKNOWN; + twl->linkstat = MUSB_UNKNOWN; twl->comparator.set_vbus = twl6030_set_vbus; twl->comparator.start_srp = twl6030_start_srp; diff --git a/include/linux/usb/musb-omap.h b/include/linux/usb/musb-omap.h deleted file mode 100644 index 7774c5986f07e..0000000000000 --- a/include/linux/usb/musb-omap.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2011-2012 by Texas Instruments - * - * The Inventra Controller Driver for Linux 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. - */ - -#ifndef __MUSB_OMAP_H__ -#define __MUSB_OMAP_H__ - -enum omap_musb_vbus_id_status { - OMAP_MUSB_UNKNOWN = 0, - OMAP_MUSB_ID_GROUND, - OMAP_MUSB_ID_FLOAT, - OMAP_MUSB_VBUS_VALID, - OMAP_MUSB_VBUS_OFF, -}; - -#if (defined(CONFIG_USB_MUSB_OMAP2PLUS) || \ - defined(CONFIG_USB_MUSB_OMAP2PLUS_MODULE)) -void omap_musb_mailbox(enum omap_musb_vbus_id_status status); -#else -static inline void omap_musb_mailbox(enum omap_musb_vbus_id_status status) -{ -} -#endif - -#endif /* __MUSB_OMAP_H__ */ diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h index fa6dc132bd1b9..96ddfb7ab018a 100644 --- a/include/linux/usb/musb.h +++ b/include/linux/usb/musb.h @@ -133,6 +133,21 @@ struct musb_hdrc_platform_data { const void *platform_ops; }; +enum musb_vbus_id_status { + MUSB_UNKNOWN = 0, + MUSB_ID_GROUND, + MUSB_ID_FLOAT, + MUSB_VBUS_VALID, + MUSB_VBUS_OFF, +}; + +#if IS_ENABLED(CONFIG_USB_MUSB_HDRC) +void musb_mailbox(enum musb_vbus_id_status status); +#else +static inline void musb_mailbox(enum musb_vbus_id_status status) +{ +} +#endif /* TUSB 6010 support */ -- GitLab From 03e43528ab68449921201744a731c1bac50bc9d1 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 30 Nov 2015 21:37:13 -0800 Subject: [PATCH 1373/2855] usb: musb: Fix unbalanced pm_runtime_enable When reloading omap2430 kernel module we get a warning about unbalanced pm_runtime_enable. Let's fix this. Note that we need to do this after the child musb-core platform_device is removed because of pm_runtime_irq_safe being set at the child. Cc: Bin Liu Cc: Felipe Balbi Cc: Kishon Vijay Abraham I Cc: NeilBrown Reviewed-by: Kishon Vijay Abraham I Signed-off-by: Tony Lindgren Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index bf05f807729f8..c84e0322c1087 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -664,8 +664,11 @@ static int omap2430_remove(struct platform_device *pdev) { struct omap2430_glue *glue = platform_get_drvdata(pdev); + pm_runtime_get_sync(glue->dev); cancel_work_sync(&glue->omap_musb_mailbox_work); platform_device_unregister(glue->musb); + pm_runtime_put_sync(glue->dev); + pm_runtime_disable(glue->dev); return 0; } -- GitLab From 919de443c2acd9fbd691ea0ed7d1ad858e5f8bed Mon Sep 17 00:00:00 2001 From: "Felipe F. Tonello" Date: Tue, 1 Dec 2015 18:31:00 +0000 Subject: [PATCH 1374/2855] usb: gadget: f_midi: set altsettings only for MIDIStreaming interface This avoids duplication of USB requests for OUT endpoint and re-enabling endpoints. Signed-off-by: Felipe F. Tonello Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_midi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index 29bfca1a47bb3..e804231bd8e59 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -75,6 +75,7 @@ struct f_midi { struct usb_ep *in_ep, *out_ep; struct snd_card *card; struct snd_rawmidi *rmidi; + u8 ms_id; struct snd_rawmidi_substream *in_substream[MAX_PORTS]; struct snd_rawmidi_substream *out_substream[MAX_PORTS]; @@ -321,8 +322,8 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) unsigned i; int err; - /* For Control Device interface we do nothing */ - if (intf == 0) + /* we only set alt for MIDIStreaming interface */ + if (intf != midi->ms_id) return 0; err = f_midi_start_ep(midi, f, midi->in_ep); @@ -730,6 +731,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) goto fail; ms_interface_desc.bInterfaceNumber = status; ac_header_desc.baInterfaceNr[0] = status; + midi->ms_id = status; status = -ENODEV; -- GitLab From f0f1b8cac4d8d973e95f25d9ea132775fb43c5f4 Mon Sep 17 00:00:00 2001 From: "Felipe F. Tonello" Date: Tue, 1 Dec 2015 18:31:01 +0000 Subject: [PATCH 1375/2855] usb: gadget: f_midi: fail if set_alt fails to allocate requests This ensures that the midi function will only work if the proper number of IN and OUT requrests are allocated. Otherwise the function will work with less requests then what the user wants. Signed-off-by: Felipe F. Tonello Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_midi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index e804231bd8e59..79dc611a2fc46 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -344,9 +344,10 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) req->complete = f_midi_complete; err = usb_ep_queue(midi->out_ep, req, GFP_ATOMIC); if (err) { - ERROR(midi, "%s queue req: %d\n", + ERROR(midi, "%s: couldn't enqueue request: %d\n", midi->out_ep->name, err); free_ep_req(midi->out_ep, req); + return err; } } -- GitLab From e1e3d7ec5da32af3bded733a61c248d7db0b4e34 Mon Sep 17 00:00:00 2001 From: "Felipe F. Tonello" Date: Tue, 1 Dec 2015 18:31:02 +0000 Subject: [PATCH 1376/2855] usb: gadget: f_midi: pre-allocate IN requests This patch introduces pre-allocation of IN endpoint USB requests. This improves on latency (requires no usb request allocation on transmit) and avoid several potential probles on allocating too many usb requests (which involves DMA pool allocation problems). This implementation also handles better multiple MIDI Gadget ports, always processing the last processed MIDI substream if the last USB request wasn't enought to handle the whole stream. Signed-off-by: Felipe F. Tonello Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_midi.c | 166 +++++++++++++++++++++------ drivers/usb/gadget/legacy/gmidi.c | 2 +- 2 files changed, 129 insertions(+), 39 deletions(-) diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index 79dc611a2fc46..fb1fe96d32153 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -88,6 +89,9 @@ struct f_midi { int index; char *id; unsigned int buflen, qlen; + /* This fifo is used as a buffer ring for pre-allocated IN usb_requests */ + DECLARE_KFIFO_PTR(in_req_fifo, struct usb_request *); + unsigned int in_last_port; }; static inline struct f_midi *func_to_midi(struct usb_function *f) @@ -95,7 +99,7 @@ static inline struct f_midi *func_to_midi(struct usb_function *f) return container_of(f, struct f_midi, func); } -static void f_midi_transmit(struct f_midi *midi, struct usb_request *req); +static void f_midi_transmit(struct f_midi *midi); DECLARE_UAC_AC_HEADER_DESCRIPTOR(1); DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1); @@ -253,7 +257,8 @@ f_midi_complete(struct usb_ep *ep, struct usb_request *req) } else if (ep == midi->in_ep) { /* Our transmit completed. See if there's more to go. * f_midi_transmit eats req, don't queue it again. */ - f_midi_transmit(midi, req); + req->length = 0; + f_midi_transmit(midi); return; } break; @@ -264,10 +269,12 @@ f_midi_complete(struct usb_ep *ep, struct usb_request *req) case -ESHUTDOWN: /* disconnect from host */ VDBG(cdev, "%s gone (%d), %d/%d\n", ep->name, status, req->actual, req->length); - if (ep == midi->out_ep) + if (ep == midi->out_ep) { f_midi_handle_out_data(ep, req); - - free_ep_req(ep, req); + /* We don't need to free IN requests because it's handled + * by the midi->in_req_fifo. */ + free_ep_req(ep, req); + } return; case -EOVERFLOW: /* buffer overrun on read means that @@ -334,6 +341,20 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (err) return err; + /* pre-allocate write usb requests to use on f_midi_transmit. */ + while (kfifo_avail(&midi->in_req_fifo)) { + struct usb_request *req = + midi_alloc_ep_req(midi->in_ep, midi->buflen); + + if (req == NULL) + return -ENOMEM; + + req->length = 0; + req->complete = f_midi_complete; + + kfifo_put(&midi->in_req_fifo, req); + } + /* allocate a bunch of read buffers and queue them all at once. */ for (i = 0; i < midi->qlen && err == 0; i++) { struct usb_request *req = @@ -358,6 +379,7 @@ static void f_midi_disable(struct usb_function *f) { struct f_midi *midi = func_to_midi(f); struct usb_composite_dev *cdev = f->config->cdev; + struct usb_request *req = NULL; DBG(cdev, "disable\n"); @@ -367,6 +389,10 @@ static void f_midi_disable(struct usb_function *f) */ usb_ep_disable(midi->in_ep); usb_ep_disable(midi->out_ep); + + /* release IN requests */ + while (kfifo_get(&midi->in_req_fifo, &req)) + free_ep_req(midi->in_ep, req); } static int f_midi_snd_free(struct snd_device *device) @@ -488,57 +514,113 @@ static void f_midi_transmit_byte(struct usb_request *req, } } -static void f_midi_transmit(struct f_midi *midi, struct usb_request *req) +static void f_midi_drop_out_substreams(struct f_midi *midi) { - struct usb_ep *ep = midi->in_ep; - int i; - - if (!ep) - return; - - if (!req) - req = midi_alloc_ep_req(ep, midi->buflen); - - if (!req) { - ERROR(midi, "%s: alloc_ep_request failed\n", __func__); - return; - } - req->length = 0; - req->complete = f_midi_complete; + unsigned int i; for (i = 0; i < MAX_PORTS; i++) { struct gmidi_in_port *port = midi->in_port[i]; struct snd_rawmidi_substream *substream = midi->in_substream[i]; - if (!port || !port->active || !substream) + if (!port) + break; + + if (!port->active || !substream) continue; - while (req->length + 3 < midi->buflen) { - uint8_t b; - if (snd_rawmidi_transmit(substream, &b, 1) != 1) { - port->active = 0; + snd_rawmidi_drop_output(substream); + } +} + +static void f_midi_transmit(struct f_midi *midi) +{ + struct usb_ep *ep = midi->in_ep; + bool active; + + /* We only care about USB requests if IN endpoint is enabled */ + if (!ep || !ep->enabled) + goto drop_out; + + do { + struct usb_request *req = NULL; + unsigned int len, i; + + active = false; + + /* We peek the request in order to reuse it if it fails + * to enqueue on its endpoint */ + len = kfifo_peek(&midi->in_req_fifo, &req); + if (len != 1) { + ERROR(midi, "%s: Couldn't get usb request\n", __func__); + goto drop_out; + } + + /* If buffer overrun, then we ignore this transmission. + * IMPORTANT: This will cause the user-space rawmidi device to block until a) usb + * requests have been completed or b) snd_rawmidi_write() times out. */ + if (req->length > 0) + return; + + for (i = midi->in_last_port; i < MAX_PORTS; i++) { + struct gmidi_in_port *port = midi->in_port[i]; + struct snd_rawmidi_substream *substream = midi->in_substream[i]; + + if (!port) { + /* Reset counter when we reach the last available port */ + midi->in_last_port = 0; + break; + } + + if (!port->active || !substream) + continue; + + while (req->length + 3 < midi->buflen) { + uint8_t b; + + if (snd_rawmidi_transmit(substream, &b, 1) != 1) { + port->active = 0; + break; + } + f_midi_transmit_byte(req, port, b); + } + + active = !!port->active; + /* Check if last port is still active, which means that + * there is still data on that substream but this current + * request run out of space. */ + if (active) { + midi->in_last_port = i; + /* There is no need to re-iterate though midi ports. */ break; } - f_midi_transmit_byte(req, port, b); } - } - if (req->length > 0 && ep->enabled) { - int err; + if (req->length > 0) { + int err; - err = usb_ep_queue(ep, req, GFP_ATOMIC); - if (err < 0) - ERROR(midi, "%s queue req: %d\n", - midi->in_ep->name, err); - } else { - free_ep_req(ep, req); - } + err = usb_ep_queue(ep, req, GFP_ATOMIC); + if (err < 0) { + ERROR(midi, "%s failed to queue req: %d\n", + midi->in_ep->name, err); + req->length = 0; /* Re-use request next time. */ + } else { + /* Upon success, put request at the back of the queue. */ + kfifo_skip(&midi->in_req_fifo); + kfifo_put(&midi->in_req_fifo, req); + } + } + } while (active); + + return; + +drop_out: + f_midi_drop_out_substreams(midi); } static void f_midi_in_tasklet(unsigned long data) { struct f_midi *midi = (struct f_midi *) data; - f_midi_transmit(midi, NULL); + f_midi_transmit(midi); } static int f_midi_in_open(struct snd_rawmidi_substream *substream) @@ -664,6 +746,7 @@ static int f_midi_register_card(struct f_midi *midi) goto fail; } midi->rmidi = rmidi; + midi->in_last_port = 0; strcpy(rmidi->name, card->shortname); rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | @@ -1053,6 +1136,7 @@ static void f_midi_free(struct usb_function *f) mutex_lock(&opts->lock); for (i = opts->in_ports - 1; i >= 0; --i) kfree(midi->in_port[i]); + kfifo_free(&midi->in_req_fifo); kfree(midi); --opts->refcnt; mutex_unlock(&opts->lock); @@ -1126,6 +1210,12 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi) midi->index = opts->index; midi->buflen = opts->buflen; midi->qlen = opts->qlen; + midi->in_last_port = 0; + + status = kfifo_alloc(&midi->in_req_fifo, midi->qlen, GFP_KERNEL); + if (status) + goto setup_fail; + ++opts->refcnt; mutex_unlock(&opts->lock); diff --git a/drivers/usb/gadget/legacy/gmidi.c b/drivers/usb/gadget/legacy/gmidi.c index e27aad5e50b9a..fc2ac150f5ffc 100644 --- a/drivers/usb/gadget/legacy/gmidi.c +++ b/drivers/usb/gadget/legacy/gmidi.c @@ -53,7 +53,7 @@ MODULE_PARM_DESC(buflen, "MIDI buffer length"); static unsigned int qlen = 32; module_param(qlen, uint, S_IRUGO); -MODULE_PARM_DESC(qlen, "USB read request queue length"); +MODULE_PARM_DESC(qlen, "USB read and write request queue length"); static unsigned int in_ports = 1; module_param(in_ports, uint, S_IRUGO); -- GitLab From f310abb33bf1e2e93f2b8d788b47100f07f1cf09 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Fri, 11 Dec 2015 12:24:40 +0100 Subject: [PATCH 1377/2855] Documentation: usb: update usb-tools repository address It seems that gitorious repository is no longer accessible, so we replace it with address to active repository. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- Documentation/usb/gadget-testing.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/usb/gadget-testing.txt b/Documentation/usb/gadget-testing.txt index 84b3d10365017..5819605748894 100644 --- a/Documentation/usb/gadget-testing.txt +++ b/Documentation/usb/gadget-testing.txt @@ -434,7 +434,7 @@ On host: serialc -v -p -i -a1 -s1024 \ where seriald and serialc are Felipe's utilities found here: -https://git.gitorious.org/usb/usb-tools.git master +https://github.com/felipebalbi/usb-tools.git master 12. PHONET function =================== -- GitLab From ab738ff1991d183a67c37ce38b3fc39cd28798c6 Mon Sep 17 00:00:00 2001 From: Mike Looijmans Date: Mon, 30 Nov 2015 12:18:23 +0100 Subject: [PATCH 1378/2855] usb: gadget: ether: Allow changing the MTU The gadget ethernet driver supports changing the MTU, but only allows this when the USB cable is removed. The comment indicates that this is because the "peer won't know". Even if the network link is still down and only the USB link is established, the driver won't allow the change. Other network interfaces allow changing the MTU any time, and don't force the link to be disabled. This makes perfect sense, because in order to be able to negotiate the MTU, the link needs to be up. Remove the restriction so that it is now actually possible to change the MTU (e.g. using "ifconfig usb0 mtu 15000") without having to manually pull the plug or change the driver's default setting. This is especially important after commit bba787a860fa ("usb: gadget: ether: Allow jumbo frames") Signed-off-by: Mike Looijmans Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/u_ether.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index 6554322af2c16..637809e3bd0d4 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -143,21 +143,11 @@ static inline int qlen(struct usb_gadget *gadget, unsigned qmult) static int ueth_change_mtu(struct net_device *net, int new_mtu) { - struct eth_dev *dev = netdev_priv(net); - unsigned long flags; - int status = 0; + if (new_mtu <= ETH_HLEN || new_mtu > GETHER_MAX_ETH_FRAME_LEN) + return -ERANGE; + net->mtu = new_mtu; - /* don't change MTU on "live" link (peer won't know) */ - spin_lock_irqsave(&dev->lock, flags); - if (dev->port_usb) - status = -EBUSY; - else if (new_mtu <= ETH_HLEN || new_mtu > GETHER_MAX_ETH_FRAME_LEN) - status = -ERANGE; - else - net->mtu = new_mtu; - spin_unlock_irqrestore(&dev->lock, flags); - - return status; + return 0; } static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p) -- GitLab From 89d75bf18d0e3e9a02961f537c87d7991df3bd32 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 16 Dec 2015 13:51:50 +0900 Subject: [PATCH 1379/2855] usb: renesas_usbhs: add SoC names to compatibility string documentation This extends the documentation of compatibility strings a little to include the SoC names. Signed-off-by: Simon Horman Acked-by: Kuninori Morimoto Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/renesas_usbhs.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt index 7d48f63db44ec..a14c0bb561d58 100644 --- a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt +++ b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt @@ -2,10 +2,10 @@ Renesas Electronics USBHS driver Required properties: - compatible: Must contain one of the following: - - "renesas,usbhs-r8a7790" - - "renesas,usbhs-r8a7791" - - "renesas,usbhs-r8a7794" - - "renesas,usbhs-r8a7795" + - "renesas,usbhs-r8a7790" for r8a7790 (R-Car H2) compatible device + - "renesas,usbhs-r8a7791" for r8a7791 (R-Car M2-W) compatible device + - "renesas,usbhs-r8a7794" for r8a7794 (R-Car E2) compatible device + - "renesas,usbhs-r8a7795" for r8a7795 (R-Car H3) compatible device - reg: Base address and length of the register for the USBHS - interrupts: Interrupt specifier for the USBHS - clocks: A list of phandle + clock specifier pairs -- GitLab From 2f1a993a0da652c50e08159f16590b7f9820d192 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 16 Dec 2015 13:51:51 +0900 Subject: [PATCH 1380/2855] usb: renesas_usbhs: add fallback compatibility strings Add fallback compatibility strings for R-Car Gen2 and Gen3. This is in keeping with the fallback scheme being adopted wherever appropriate for drivers for Renesas SoCs. Signed-off-by: Simon Horman Acked-by: Kuninori Morimoto Signed-off-by: Felipe Balbi --- .../devicetree/bindings/usb/renesas_usbhs.txt | 12 ++++++++++-- drivers/usb/renesas_usbhs/common.c | 9 +++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt index a14c0bb561d58..45d9ae13ffa3c 100644 --- a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt +++ b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt @@ -1,11 +1,19 @@ Renesas Electronics USBHS driver Required properties: - - compatible: Must contain one of the following: + - compatible: Must contain one or more of the following: + - "renesas,usbhs-r8a7790" for r8a7790 (R-Car H2) compatible device - "renesas,usbhs-r8a7791" for r8a7791 (R-Car M2-W) compatible device - "renesas,usbhs-r8a7794" for r8a7794 (R-Car E2) compatible device - "renesas,usbhs-r8a7795" for r8a7795 (R-Car H3) compatible device + - "renesas,rcar-gen2-usbhs" for R-Car Gen2 compatible device + - "renesas,rcar-gen3-usbhs" for R-Car Gen3 compatible device + + When compatible with the generic version, nodes must list the + SoC-specific version corresponding to the platform first followed + by the generic version. + - reg: Base address and length of the register for the USBHS - interrupts: Interrupt specifier for the USBHS - clocks: A list of phandle + clock specifier pairs @@ -22,7 +30,7 @@ Optional properties: Example: usbhs: usb@e6590000 { - compatible = "renesas,usbhs-r8a7790"; + compatible = "renesas,usbhs-r8a7790", "renesas,rcar-gen2-usbhs"; reg = <0 0xe6590000 0 0x100>; interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp7_clks R8A7790_CLK_HSUSB>; diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 7ccc2fe4f6ec5..5af9ca5d54abc 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -481,6 +481,15 @@ static const struct of_device_id usbhs_of_match[] = { .compatible = "renesas,usbhs-r8a7795", .data = (void *)USBHS_TYPE_RCAR_GEN2, }, + { + .compatible = "renesas,rcar-gen2-usbhs", + .data = (void *)USBHS_TYPE_RCAR_GEN2, + }, + { + /* Gen3 is compatible with Gen2 */ + .compatible = "renesas,rcar-gen3-usbhs", + .data = (void *)USBHS_TYPE_RCAR_GEN2, + }, { }, }; MODULE_DEVICE_TABLE(of, usbhs_of_match); -- GitLab From d0450272a6b9c6326017f490a808eb7caf214400 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 16 Dec 2015 13:51:52 +0900 Subject: [PATCH 1381/2855] usb: renesas_usbhs: add device tree support for r8a779[23] Simply document new compatibility string. As a previous patch adds a generic R-Car Gen2 compatibility string there appears to be no need for a driver updates. Signed-off-by: Simon Horman Acked-by: Rob Herring Acked-by: Kuninori Morimoto Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/renesas_usbhs.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt index 45d9ae13ffa3c..b6040563e51a3 100644 --- a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt +++ b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt @@ -5,6 +5,8 @@ Required properties: - "renesas,usbhs-r8a7790" for r8a7790 (R-Car H2) compatible device - "renesas,usbhs-r8a7791" for r8a7791 (R-Car M2-W) compatible device + - "renesas,usbhs-r8a7792" for r8a7792 (R-Car V2H) compatible device + - "renesas,usbhs-r8a7793" for r8a7793 (R-Car M2-N) compatible device - "renesas,usbhs-r8a7794" for r8a7794 (R-Car E2) compatible device - "renesas,usbhs-r8a7795" for r8a7795 (R-Car H3) compatible device - "renesas,rcar-gen2-usbhs" for R-Car Gen2 compatible device -- GitLab From a1c1e9b74ff380176bf3862c764061e0a7efd9bb Mon Sep 17 00:00:00 2001 From: Fan Li Date: Tue, 15 Dec 2015 17:02:41 +0800 Subject: [PATCH 1382/2855] f2fs: fix to reset variable correctlly f2fs_map_blocks will set m_flags and m_len to 0, so we don't need to reset m_flags ourselves, but have to reset m_len to correct value before use it again. Signed-off-by: Fan li Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index c6d909e9661e9..1f5892f380189 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1700,7 +1700,6 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi, } map.m_lblk = pg_start; - map.m_len = pg_end - pg_start; /* * lookup mapping info in dnode page cache, skip defragmenting if all @@ -1708,14 +1707,13 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi, * in logical blocks. */ while (map.m_lblk < pg_end) { - map.m_flags = 0; + map.m_len = pg_end - map.m_lblk; err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_READ); if (err) goto out; if (!(map.m_flags & F2FS_MAP_FLAGS)) { map.m_lblk++; - map.m_len--; continue; } @@ -1726,7 +1724,6 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi, blk_end = map.m_pblk + map.m_len; map.m_lblk += map.m_len; - map.m_len = pg_end - map.m_lblk; } if (!fragmented) @@ -1752,14 +1749,13 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi, int cnt = 0; do_map: - map.m_flags = 0; + map.m_len = pg_end - map.m_lblk; err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_READ); if (err) goto clear_out; if (!(map.m_flags & F2FS_MAP_FLAGS)) { map.m_lblk++; - map.m_len--; continue; } @@ -1784,7 +1780,6 @@ do_map: } map.m_lblk = idx; - map.m_len = pg_end - idx; if (idx < pg_end && cnt < blk_per_seg) goto do_map; -- GitLab From b39f0de23d8f22253d441b3b68414e9a1d027cf6 Mon Sep 17 00:00:00 2001 From: Yunlei He Date: Tue, 15 Dec 2015 17:17:20 +0800 Subject: [PATCH 1383/2855] f2fs: backup raw_super in sbi f2fs use fields of f2fs_super_block struct directly in a grabbed buffer. Once the buffer happen to be destroyed (e.g. through dd), it may bring in unpredictable effect on f2fs. This patch fixes to allocate additional buffer to store datas of super block rather than using grabbed block buffer directly. Signed-off-by: Yunlei He Signed-off-by: Jaegeuk Kim Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/super.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 4031f8ed9d240..6dfe0d32ad885 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -568,6 +568,7 @@ static void f2fs_put_super(struct super_block *sb) sb->s_fs_info = NULL; brelse(sbi->raw_super_buf); + kfree(sbi->raw_super); kfree(sbi); } @@ -1139,6 +1140,9 @@ static int read_raw_super_block(struct super_block *sb, struct f2fs_super_block *super; int err = 0; + super = kzalloc(sizeof(struct f2fs_super_block), GFP_KERNEL); + if (!super) + return -ENOMEM; retry: buffer = sb_bread(sb, block); if (!buffer) { @@ -1154,8 +1158,7 @@ retry: } } - super = (struct f2fs_super_block *) - ((char *)(buffer)->b_data + F2FS_SUPER_OFFSET); + memcpy(super, buffer->b_data + F2FS_SUPER_OFFSET, sizeof(*super)); /* sanity checking of raw super */ if (sanity_check_raw_super(sb, super)) { @@ -1189,14 +1192,17 @@ retry: out: /* No valid superblock */ - if (!*raw_super) + if (!*raw_super) { + kfree(super); return err; + } return 0; } int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover) { + struct f2fs_super_block *super = F2FS_RAW_SUPER(sbi); struct buffer_head *sbh = sbi->raw_super_buf; struct buffer_head *bh; int err; @@ -1207,7 +1213,7 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover) return -EIO; lock_buffer(bh); - memcpy(bh->b_data, sbh->b_data, sbh->b_size); + memcpy(bh->b_data + F2FS_SUPER_OFFSET, super, sizeof(*super)); WARN_ON(sbh->b_size != F2FS_BLKSIZE); set_buffer_uptodate(bh); set_buffer_dirty(bh); @@ -1223,6 +1229,10 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover) /* write current valid superblock */ lock_buffer(sbh); + if (memcmp(sbh->b_data + F2FS_SUPER_OFFSET, super, sizeof(*super))) { + f2fs_msg(sbi->sb, KERN_INFO, "Write modified valid superblock"); + memcpy(sbh->b_data + F2FS_SUPER_OFFSET, super, sizeof(*super)); + } set_buffer_dirty(sbh); unlock_buffer(sbh); @@ -1497,6 +1507,7 @@ free_options: kfree(options); free_sb_buf: brelse(raw_super_buf); + kfree(raw_super); free_sbi: kfree(sbi); -- GitLab From e8240f656d4d5d718ce8cf6b4ea266d6719ef547 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 15 Dec 2015 17:19:26 +0800 Subject: [PATCH 1384/2855] f2fs: don't grab super block buffer header all the time We have already got one copy of valid super block in memory, do not grab buffer header of super block all the time. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/f2fs.h | 2 +- fs/f2fs/file.c | 8 ++--- fs/f2fs/super.c | 81 +++++++++++++++++++++---------------------------- 3 files changed, 38 insertions(+), 53 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 21048edb72cb3..37cf04b3ff379 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -715,8 +715,8 @@ enum { struct f2fs_sb_info { struct super_block *sb; /* pointer to VFS super block */ struct proc_dir_entry *s_proc; /* proc entry */ - struct buffer_head *raw_super_buf; /* buffer head of raw sb */ struct f2fs_super_block *raw_super; /* raw super block pointer */ + int valid_super_block; /* valid super block no */ int s_flag; /* flags for sbi */ /* for node-related operations */ diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 1f5892f380189..7f8ca47be0afd 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1591,20 +1591,16 @@ static int f2fs_ioc_get_encryption_pwsalt(struct file *filp, unsigned long arg) return err; /* update superblock with uuid */ - lock_buffer(sbi->raw_super_buf); generate_random_uuid(sbi->raw_super->encrypt_pw_salt); - unlock_buffer(sbi->raw_super_buf); err = f2fs_commit_super(sbi, false); - - mnt_drop_write_file(filp); if (err) { /* undo new data */ - lock_buffer(sbi->raw_super_buf); memset(sbi->raw_super->encrypt_pw_salt, 0, 16); - unlock_buffer(sbi->raw_super_buf); + mnt_drop_write_file(filp); return err; } + mnt_drop_write_file(filp); got_it: if (copy_to_user((__u8 __user *)arg, sbi->raw_super->encrypt_pw_salt, 16)) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 6dfe0d32ad885..8c8b4673a5db3 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -567,7 +567,6 @@ static void f2fs_put_super(struct super_block *sb) wait_for_completion(&sbi->s_kobj_unregister); sb->s_fs_info = NULL; - brelse(sbi->raw_super_buf); kfree(sbi->raw_super); kfree(sbi); } @@ -1132,65 +1131,53 @@ static void init_sb_info(struct f2fs_sb_info *sbi) */ static int read_raw_super_block(struct super_block *sb, struct f2fs_super_block **raw_super, - struct buffer_head **raw_super_buf, - int *recovery) + int *valid_super_block, int *recovery) { int block = 0; - struct buffer_head *buffer; - struct f2fs_super_block *super; + struct buffer_head *bh; + struct f2fs_super_block *super, *buf; int err = 0; super = kzalloc(sizeof(struct f2fs_super_block), GFP_KERNEL); if (!super) return -ENOMEM; retry: - buffer = sb_bread(sb, block); - if (!buffer) { + bh = sb_bread(sb, block); + if (!bh) { *recovery = 1; f2fs_msg(sb, KERN_ERR, "Unable to read %dth superblock", block + 1); - if (block == 0) { - block++; - goto retry; - } else { - err = -EIO; - goto out; - } + err = -EIO; + goto next; } - memcpy(super, buffer->b_data + F2FS_SUPER_OFFSET, sizeof(*super)); + buf = (struct f2fs_super_block *)(bh->b_data + F2FS_SUPER_OFFSET); /* sanity checking of raw super */ - if (sanity_check_raw_super(sb, super)) { - brelse(buffer); + if (sanity_check_raw_super(sb, buf)) { + brelse(bh); *recovery = 1; f2fs_msg(sb, KERN_ERR, "Can't find valid F2FS filesystem in %dth superblock", block + 1); - if (block == 0) { - block++; - goto retry; - } else { - err = -EINVAL; - goto out; - } + err = -EINVAL; + goto next; } if (!*raw_super) { - *raw_super_buf = buffer; + memcpy(super, buf, sizeof(*super)); + *valid_super_block = block; *raw_super = super; - } else { - /* already have a valid superblock */ - brelse(buffer); } + brelse(bh); +next: /* check the validity of the second superblock */ if (block == 0) { block++; goto retry; } -out: /* No valid superblock */ if (!*raw_super) { kfree(super); @@ -1203,18 +1190,16 @@ out: int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover) { struct f2fs_super_block *super = F2FS_RAW_SUPER(sbi); - struct buffer_head *sbh = sbi->raw_super_buf; struct buffer_head *bh; int err; /* write back-up superblock first */ - bh = sb_getblk(sbi->sb, sbh->b_blocknr ? 0 : 1); + bh = sb_getblk(sbi->sb, sbi->valid_super_block ? 0 : 1); if (!bh) return -EIO; lock_buffer(bh); memcpy(bh->b_data + F2FS_SUPER_OFFSET, super, sizeof(*super)); - WARN_ON(sbh->b_size != F2FS_BLKSIZE); set_buffer_uptodate(bh); set_buffer_dirty(bh); unlock_buffer(bh); @@ -1227,33 +1212,37 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover) if (recover || err) return err; + bh = sb_getblk(sbi->sb, sbi->valid_super_block); + if (!bh) + return -EIO; + /* write current valid superblock */ - lock_buffer(sbh); - if (memcmp(sbh->b_data + F2FS_SUPER_OFFSET, super, sizeof(*super))) { - f2fs_msg(sbi->sb, KERN_INFO, "Write modified valid superblock"); - memcpy(sbh->b_data + F2FS_SUPER_OFFSET, super, sizeof(*super)); - } - set_buffer_dirty(sbh); - unlock_buffer(sbh); + lock_buffer(bh); + memcpy(bh->b_data + F2FS_SUPER_OFFSET, super, sizeof(*super)); + set_buffer_uptodate(bh); + set_buffer_dirty(bh); + unlock_buffer(bh); - return __sync_dirty_buffer(sbh, WRITE_FLUSH_FUA); + err = __sync_dirty_buffer(bh, WRITE_FLUSH_FUA); + brelse(bh); + + return err; } static int f2fs_fill_super(struct super_block *sb, void *data, int silent) { struct f2fs_sb_info *sbi; struct f2fs_super_block *raw_super; - struct buffer_head *raw_super_buf; struct inode *root; long err; bool retry = true, need_fsck = false; char *options = NULL; - int recovery, i; + int recovery, i, valid_super_block; try_onemore: err = -EINVAL; raw_super = NULL; - raw_super_buf = NULL; + valid_super_block = -1; recovery = 0; /* allocate memory for f2fs-specific super block info */ @@ -1267,7 +1256,8 @@ try_onemore: goto free_sbi; } - err = read_raw_super_block(sb, &raw_super, &raw_super_buf, &recovery); + err = read_raw_super_block(sb, &raw_super, &valid_super_block, + &recovery); if (err) goto free_sbi; @@ -1300,7 +1290,7 @@ try_onemore: /* init f2fs-specific super block info */ sbi->sb = sb; sbi->raw_super = raw_super; - sbi->raw_super_buf = raw_super_buf; + sbi->valid_super_block = valid_super_block; mutex_init(&sbi->gc_mutex); mutex_init(&sbi->writepages); mutex_init(&sbi->cp_mutex); @@ -1506,7 +1496,6 @@ free_meta_inode: free_options: kfree(options); free_sb_buf: - brelse(raw_super_buf); kfree(raw_super); free_sbi: kfree(sbi); -- GitLab From 55d1cdb25a815ba92a917ae579c27cc3ffb9a57d Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 15 Dec 2015 16:07:14 -0800 Subject: [PATCH 1385/2855] f2fs: relocate tracepoint of write_checkpoint It needs to relocate its location to see exact trace logs. Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index a4392f06f7339..5008b872f3165 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -1130,9 +1130,9 @@ void write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) /* do checkpoint periodically */ sbi->cp_expires = round_jiffies_up(jiffies + HZ * sbi->cp_interval); + trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint"); out: mutex_unlock(&sbi->cp_mutex); - trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint"); } void init_ino_entry_info(struct f2fs_sb_info *sbi) -- GitLab From b3980910f746d885111db7252f664600de2a5ea3 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 16 Dec 2015 13:19:35 +0800 Subject: [PATCH 1386/2855] f2fs: introduce __f2fs_commit_super Introduce __f2fs_commit_super to include duplicated codes in f2fs_commit_super for cleanup. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/super.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 8c8b4673a5db3..bc1a8cd38bc8c 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1187,14 +1187,13 @@ next: return 0; } -int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover) +int __f2fs_commit_super(struct f2fs_sb_info *sbi, int block) { struct f2fs_super_block *super = F2FS_RAW_SUPER(sbi); struct buffer_head *bh; int err; - /* write back-up superblock first */ - bh = sb_getblk(sbi->sb, sbi->valid_super_block ? 0 : 1); + bh = sb_getblk(sbi->sb, block); if (!bh) return -EIO; @@ -1208,25 +1207,22 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover) err = __sync_dirty_buffer(bh, WRITE_FLUSH_FUA); brelse(bh); + return err; +} + +int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover) +{ + int err; + + /* write back-up superblock first */ + err = __f2fs_commit_super(sbi, sbi->valid_super_block ? 0 : 1); + /* if we are in recovery path, skip writing valid superblock */ if (recover || err) return err; - bh = sb_getblk(sbi->sb, sbi->valid_super_block); - if (!bh) - return -EIO; - /* write current valid superblock */ - lock_buffer(bh); - memcpy(bh->b_data + F2FS_SUPER_OFFSET, super, sizeof(*super)); - set_buffer_uptodate(bh); - set_buffer_dirty(bh); - unlock_buffer(bh); - - err = __sync_dirty_buffer(bh, WRITE_FLUSH_FUA); - brelse(bh); - - return err; + return __f2fs_commit_super(sbi, sbi->valid_super_block); } static int f2fs_fill_super(struct super_block *sb, void *data, int silent) -- GitLab From c227f912732f204c0ec4a577ba812401ac4672af Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 16 Dec 2015 13:09:20 +0800 Subject: [PATCH 1387/2855] f2fs: record dirty status of regular/symlink inode Maintain regular/symlink inode which has dirty pages in global dirty list and record their total dirty pages count like the way of handling directory inode. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 66 ++++++++++++++++++++++---------------------- fs/f2fs/data.c | 4 +-- fs/f2fs/dir.c | 2 +- fs/f2fs/f2fs.h | 27 +++++++++++------- fs/f2fs/inode.c | 2 +- fs/f2fs/super.c | 6 ++-- 6 files changed, 58 insertions(+), 49 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 5008b872f3165..a037bbd89dc64 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -722,53 +722,51 @@ fail_no_cp: return -EINVAL; } -static void __add_dirty_inode(struct inode *inode) +static void __add_dirty_inode(struct inode *inode, enum inode_type type) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_inode_info *fi = F2FS_I(inode); + int flag = (type == DIR_INODE) ? FI_DIRTY_DIR : FI_DIRTY_FILE; - if (is_inode_flag_set(fi, FI_DIRTY_DIR)) + if (is_inode_flag_set(fi, flag)) return; - set_inode_flag(fi, FI_DIRTY_DIR); - list_add_tail(&fi->dirty_list, &sbi->dir_inode_list); - stat_inc_dirty_dir(sbi); - return; + set_inode_flag(fi, flag); + list_add_tail(&fi->dirty_list, &sbi->inode_list[type]); + if (type == DIR_INODE) + stat_inc_dirty_dir(sbi); } -static void __remove_dirty_inode(struct inode *inode) +static void __remove_dirty_inode(struct inode *inode, enum inode_type type) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_inode_info *fi = F2FS_I(inode); + int flag = (type == DIR_INODE) ? FI_DIRTY_DIR : FI_DIRTY_FILE; if (get_dirty_pages(inode) || - !is_inode_flag_set(F2FS_I(inode), FI_DIRTY_DIR)) + !is_inode_flag_set(F2FS_I(inode), flag)) return; list_del_init(&fi->dirty_list); - clear_inode_flag(fi, FI_DIRTY_DIR); - stat_dec_dirty_dir(sbi); + clear_inode_flag(fi, flag); + if (type == DIR_INODE) + stat_dec_dirty_dir(sbi); } void update_dirty_page(struct inode *inode, struct page *page) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + enum inode_type type = S_ISDIR(inode->i_mode) ? DIR_INODE : FILE_INODE; if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode)) return; - if (!S_ISDIR(inode->i_mode)) { - inode_inc_dirty_pages(inode); - goto out; - } - - spin_lock(&sbi->dir_inode_lock); - __add_dirty_inode(inode); + spin_lock(&sbi->inode_lock[type]); + __add_dirty_inode(inode, type); inode_inc_dirty_pages(inode); - spin_unlock(&sbi->dir_inode_lock); + spin_unlock(&sbi->inode_lock[type]); -out: SetPagePrivate(page); f2fs_trace_pid(page); } @@ -777,22 +775,24 @@ void add_dirty_dir_inode(struct inode *inode) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - spin_lock(&sbi->dir_inode_lock); - __add_dirty_inode(inode); - spin_unlock(&sbi->dir_inode_lock); + spin_lock(&sbi->inode_lock[DIR_INODE]); + __add_dirty_inode(inode, DIR_INODE); + spin_unlock(&sbi->inode_lock[DIR_INODE]); } -void remove_dirty_dir_inode(struct inode *inode) +void remove_dirty_inode(struct inode *inode) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_inode_info *fi = F2FS_I(inode); + enum inode_type type = S_ISDIR(inode->i_mode) ? DIR_INODE : FILE_INODE; - if (!S_ISDIR(inode->i_mode)) + if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode) && + !S_ISLNK(inode->i_mode)) return; - spin_lock(&sbi->dir_inode_lock); - __remove_dirty_inode(inode); - spin_unlock(&sbi->dir_inode_lock); + spin_lock(&sbi->inode_lock[type]); + __remove_dirty_inode(inode, type); + spin_unlock(&sbi->inode_lock[type]); /* Only from the recovery routine */ if (is_inode_flag_set(fi, FI_DELAY_IPUT)) { @@ -801,7 +801,7 @@ void remove_dirty_dir_inode(struct inode *inode) } } -void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi) +void sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type) { struct list_head *head; struct inode *inode; @@ -810,16 +810,16 @@ retry: if (unlikely(f2fs_cp_error(sbi))) return; - spin_lock(&sbi->dir_inode_lock); + spin_lock(&sbi->inode_lock[type]); - head = &sbi->dir_inode_list; + head = &sbi->inode_list[type]; if (list_empty(head)) { - spin_unlock(&sbi->dir_inode_lock); + spin_unlock(&sbi->inode_lock[type]); return; } fi = list_entry(head->next, struct f2fs_inode_info, dirty_list); inode = igrab(&fi->vfs_inode); - spin_unlock(&sbi->dir_inode_lock); + spin_unlock(&sbi->inode_lock[type]); if (inode) { filemap_fdatawrite(inode->i_mapping); iput(inode); @@ -854,7 +854,7 @@ retry_flush_dents: /* write all the dirty dentry pages */ if (get_pages(sbi, F2FS_DIRTY_DENTS)) { f2fs_unlock_all(sbi); - sync_dirty_dir_inodes(sbi); + sync_dirty_inodes(sbi, DIR_INODE); if (unlikely(f2fs_cp_error(sbi))) { err = -EIO; goto out; diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 90a2ffea875bf..292a06cbea072 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1180,7 +1180,7 @@ out: f2fs_balance_fs(sbi); if (wbc->for_reclaim) { f2fs_submit_merged_bio(sbi, DATA, WRITE); - remove_dirty_dir_inode(inode); + remove_dirty_inode(inode); } return 0; @@ -1372,7 +1372,7 @@ static int f2fs_write_data_pages(struct address_space *mapping, if (locked) mutex_unlock(&sbi->writepages); - remove_dirty_dir_inode(inode); + remove_dirty_inode(inode); wbc->nr_to_write = max((long)0, wbc->nr_to_write - diff); return ret; diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 6554fd5fce88f..3da58265c0d40 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -444,7 +444,7 @@ error: /* once the failed inode becomes a bad inode, i_mode is S_IFREG */ truncate_inode_pages(&inode->i_data, 0); truncate_blocks(inode, 0, false); - remove_dirty_dir_inode(inode); + remove_dirty_inode(inode); remove_inode_page(inode); return ERR_PTR(err); } diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 37cf04b3ff379..03a2b86a28ba4 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -648,6 +648,7 @@ struct f2fs_sm_info { enum count_type { F2FS_WRITEBACK, F2FS_DIRTY_DENTS, + F2FS_DIRTY_DATA, F2FS_DIRTY_NODES, F2FS_DIRTY_META, F2FS_INMEM_PAGES, @@ -696,6 +697,12 @@ struct f2fs_bio_info { struct rw_semaphore io_rwsem; /* blocking op for bio */ }; +enum inode_type { + DIR_INODE, /* for dirty dir inode */ + FILE_INODE, /* for dirty regular/symlink inode */ + NR_INODE_TYPE, +}; + /* for inner inode cache management */ struct inode_management { struct radix_tree_root ino_root; /* ino entry array */ @@ -745,9 +752,9 @@ struct f2fs_sb_info { /* for orphan inode, use 0'th array */ unsigned int max_orphans; /* max orphan inodes */ - /* for directory inode management */ - struct list_head dir_inode_list; /* dir inode list */ - spinlock_t dir_inode_lock; /* for dir inode list lock */ + /* for inode management */ + struct list_head inode_list[NR_INODE_TYPE]; /* dirty inode list */ + spinlock_t inode_lock[NR_INODE_TYPE]; /* for dirty inode list lock */ /* for extent tree cache */ struct radix_tree_root extent_tree_root;/* cache extent cache entries */ @@ -1060,8 +1067,8 @@ static inline void inc_page_count(struct f2fs_sb_info *sbi, int count_type) static inline void inode_inc_dirty_pages(struct inode *inode) { atomic_inc(&F2FS_I(inode)->dirty_pages); - if (S_ISDIR(inode->i_mode)) - inc_page_count(F2FS_I_SB(inode), F2FS_DIRTY_DENTS); + inc_page_count(F2FS_I_SB(inode), S_ISDIR(inode->i_mode) ? + F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA); } static inline void dec_page_count(struct f2fs_sb_info *sbi, int count_type) @@ -1076,9 +1083,8 @@ static inline void inode_dec_dirty_pages(struct inode *inode) return; atomic_dec(&F2FS_I(inode)->dirty_pages); - - if (S_ISDIR(inode->i_mode)) - dec_page_count(F2FS_I_SB(inode), F2FS_DIRTY_DENTS); + dec_page_count(F2FS_I_SB(inode), S_ISDIR(inode->i_mode) ? + F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA); } static inline int get_pages(struct f2fs_sb_info *sbi, int count_type) @@ -1417,6 +1423,7 @@ enum { FI_DATA_EXIST, /* indicate data exists */ FI_INLINE_DOTS, /* indicate inline dot dentries */ FI_DO_DEFRAG, /* indicate defragment is running */ + FI_DIRTY_FILE, /* indicate regular/symlink has dirty pages */ }; static inline void set_inode_flag(struct f2fs_inode_info *fi, int flag) @@ -1826,8 +1833,8 @@ int recover_orphan_inodes(struct f2fs_sb_info *); int get_valid_checkpoint(struct f2fs_sb_info *); void update_dirty_page(struct inode *, struct page *); void add_dirty_dir_inode(struct inode *); -void remove_dirty_dir_inode(struct inode *); -void sync_dirty_dir_inodes(struct f2fs_sb_info *); +void remove_dirty_inode(struct inode *); +void sync_dirty_inodes(struct f2fs_sb_info *, enum inode_type); void write_checkpoint(struct f2fs_sb_info *, struct cp_control *); void init_ino_entry_info(struct f2fs_sb_info *); int __init create_checkpoint_caches(void); diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 3d2fe595d0782..ec3fb32c47262 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -327,7 +327,7 @@ void f2fs_evict_inode(struct inode *inode) goto out_clear; f2fs_bug_on(sbi, get_dirty_pages(inode)); - remove_dirty_dir_inode(inode); + remove_dirty_inode(inode); f2fs_destroy_extent_tree(inode); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index bc1a8cd38bc8c..5b596d6a8d248 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1339,8 +1339,10 @@ try_onemore: le64_to_cpu(sbi->ckpt->valid_block_count); sbi->last_valid_block_count = sbi->total_valid_block_count; sbi->alloc_valid_block_count = 0; - INIT_LIST_HEAD(&sbi->dir_inode_list); - spin_lock_init(&sbi->dir_inode_lock); + for (i = 0; i < NR_INODE_TYPE; i++) { + INIT_LIST_HEAD(&sbi->inode_list[i]); + spin_lock_init(&sbi->inode_lock[i]); + } init_extent_cache_info(sbi); -- GitLab From 343f40f0a70eb7cee9cc8d6fcfbb3917252a5245 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 16 Dec 2015 13:12:16 +0800 Subject: [PATCH 1388/2855] f2fs: introduce new option for controlling data flush Add a new option 'data_flush' to enable data flush functionality. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- Documentation/filesystems/f2fs.txt | 2 ++ fs/f2fs/f2fs.h | 1 + fs/f2fs/super.c | 7 +++++++ 3 files changed, 10 insertions(+) diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt index ad10494aa224f..e1c9f0849da6d 100644 --- a/Documentation/filesystems/f2fs.txt +++ b/Documentation/filesystems/f2fs.txt @@ -149,6 +149,8 @@ noextent_cache Disable an extent cache based on rb-tree explicitly, see the above extent_cache mount option. noinline_data Disable the inline data feature, inline data feature is enabled by default. +data_flush Enable data flushing before checkpoint in order to + persist data of regular and symlink. ================================================================================ DEBUGFS ENTRIES diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 03a2b86a28ba4..b1fb8f73fe427 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -54,6 +54,7 @@ #define F2FS_MOUNT_FASTBOOT 0x00001000 #define F2FS_MOUNT_EXTENT_CACHE 0x00002000 #define F2FS_MOUNT_FORCE_FG_GC 0x00004000 +#define F2FS_MOUNT_DATA_FLUSH 0x00008000 #define clear_opt(sbi, option) (sbi->mount_opt.opt &= ~F2FS_MOUNT_##option) #define set_opt(sbi, option) (sbi->mount_opt.opt |= F2FS_MOUNT_##option) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 5b596d6a8d248..c3070c149c0ec 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -67,6 +67,7 @@ enum { Opt_extent_cache, Opt_noextent_cache, Opt_noinline_data, + Opt_data_flush, Opt_err, }; @@ -91,6 +92,7 @@ static match_table_t f2fs_tokens = { {Opt_extent_cache, "extent_cache"}, {Opt_noextent_cache, "noextent_cache"}, {Opt_noinline_data, "noinline_data"}, + {Opt_data_flush, "data_flush"}, {Opt_err, NULL}, }; @@ -406,6 +408,9 @@ static int parse_options(struct super_block *sb, char *options) case Opt_noinline_data: clear_opt(sbi, INLINE_DATA); break; + case Opt_data_flush: + set_opt(sbi, DATA_FLUSH); + break; default: f2fs_msg(sb, KERN_ERR, "Unrecognized mount option \"%s\" or missing value", @@ -687,6 +692,8 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) seq_puts(seq, ",extent_cache"); else seq_puts(seq, ",noextent_cache"); + if (test_opt(sbi, DATA_FLUSH)) + seq_puts(seq, ",data_flush"); seq_printf(seq, ",active_logs=%u", sbi->active_logs); return 0; -- GitLab From b554e1450658039df28486f19216d6962d29dba6 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Mon, 14 Dec 2015 12:06:55 +0530 Subject: [PATCH 1389/2855] regulator: tps65917/palmas: Add bypass ops for LDOs with bypass capability set/get_bypass ops were missing for ldo1/ldo2 on tps65917 and ldo9 on palmas/tps659038 which support bypass mode. Adding the bypass ops helps consumers configure these ldos in bypass mode or remove bypass mode if need be. Signed-off-by: Keerthy Reported-by: Kishon Vijay Abraham I Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 39 ++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 8217613807d37..6efc7ee8aea30 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -612,6 +612,18 @@ static struct regulator_ops palmas_ops_ldo = { .map_voltage = regulator_map_voltage_linear, }; +static struct regulator_ops palmas_ops_ldo9 = { + .is_enabled = palmas_is_enabled_ldo, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .set_bypass = regulator_set_bypass_regmap, + .get_bypass = regulator_get_bypass_regmap, +}; + static struct regulator_ops palmas_ops_ext_control_ldo = { .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, @@ -639,6 +651,19 @@ static struct regulator_ops tps65917_ops_ldo = { .set_voltage_time_sel = regulator_set_voltage_time_sel, }; +static struct regulator_ops tps65917_ops_ldo_1_2 = { + .is_enabled = palmas_is_enabled_ldo, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_bypass = regulator_set_bypass_regmap, + .get_bypass = regulator_get_bypass_regmap, +}; + static int palmas_regulator_config_external(struct palmas *palmas, int id, struct palmas_reg_init *reg_init) { @@ -915,6 +940,13 @@ static int palmas_ldo_registration(struct palmas_pmic *pmic, if (pdata && pdata->ldo6_vibrator && (id == PALMAS_REG_LDO6)) desc->enable_time = 2000; + + if (id == PALMAS_REG_LDO9) { + desc->ops = &palmas_ops_ldo9; + desc->bypass_reg = desc->enable_reg; + desc->bypass_mask = + PALMAS_LDO9_CTRL_LDO_BYPASS_EN; + } } else { if (!ddata->has_regen3 && id == PALMAS_REG_REGEN3) continue; @@ -1019,6 +1051,13 @@ static int tps65917_ldo_registration(struct palmas_pmic *pmic, * It is of the order of ~60mV/uS. */ desc->ramp_delay = 2500; + if (id == TPS65917_REG_LDO1 || + id == TPS65917_REG_LDO2) { + desc->ops = &tps65917_ops_ldo_1_2; + desc->bypass_reg = desc->enable_reg; + desc->bypass_mask = + TPS65917_LDO1_CTRL_BYPASS_EN; + } } else { desc->n_voltages = 1; if (reg_init && reg_init->roof_floor) -- GitLab From 6b0f8f9c52efe24d6dac06ab963b7bd91c723751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=B6sz=C3=B6rm=C3=A9nyi=20Zolt=C3=A1n?= Date: Wed, 16 Dec 2015 11:11:50 -0800 Subject: [PATCH 1390/2855] Input: add eGalaxTouch serial touchscreen driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are two EETI touchscreen drivers in the kernel (eeti_ts and egalax_ts) but both are for I2C-connected panels. This is for a different, serial and not multi-touch touchscreen panel. The protocol documentation is at http://www.eeti.com.tw/pdf/Software%20Programming%20Guide_v2.0.pdf Signed-off-by: Böszörményi Zoltán Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 10 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/egalax_ts_serial.c | 194 +++++++++++++++++++ include/uapi/linux/serio.h | 1 + 4 files changed, 206 insertions(+) create mode 100644 drivers/input/touchscreen/egalax_ts_serial.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index ae33da7ab51ff..9bcb718668b23 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -295,6 +295,16 @@ config TOUCHSCREEN_EGALAX To compile this driver as a module, choose M here: the module will be called egalax_ts. +config TOUCHSCREEN_EGALAX_SERIAL + tristate "EETI eGalax serial touchscreen" + select SERIO + help + Say Y here to enable support for serial connected EETI + eGalax touch panels. + + To compile this driver as a module, choose M here: the + module will be called egalax_ts_serial. + config TOUCHSCREEN_FT6236 tristate "FT6236 I2C touchscreen" depends on I2C diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index cbaa6abb08dae..001357c3f73f9 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o obj-$(CONFIG_TOUCHSCREEN_ELAN) += elants_i2c.o obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_ts.o +obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL) += egalax_ts_serial.o obj-$(CONFIG_TOUCHSCREEN_FT6236) += ft6236.o obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o diff --git a/drivers/input/touchscreen/egalax_ts_serial.c b/drivers/input/touchscreen/egalax_ts_serial.c new file mode 100644 index 0000000000000..a078c1c2c3f91 --- /dev/null +++ b/drivers/input/touchscreen/egalax_ts_serial.c @@ -0,0 +1,194 @@ +/* + * EETI Egalax serial touchscreen driver + * + * Copyright (c) 2015 Zoltán Böszörményi + * + * based on the + * + * Hampshire serial touchscreen driver (Copyright (c) 2010 Adam Bennett) + */ + +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#define DRIVER_DESC "EETI Egalax serial touchscreen driver" + +/* + * Definitions & global arrays. + */ + +#define EGALAX_FORMAT_MAX_LENGTH 6 +#define EGALAX_FORMAT_START_BIT BIT(7) +#define EGALAX_FORMAT_PRESSURE_BIT BIT(6) +#define EGALAX_FORMAT_TOUCH_BIT BIT(0) +#define EGALAX_FORMAT_RESOLUTION_MASK 0x06 + +#define EGALAX_MIN_XC 0 +#define EGALAX_MAX_XC 0x4000 +#define EGALAX_MIN_YC 0 +#define EGALAX_MAX_YC 0x4000 + +/* + * Per-touchscreen data. + */ +struct egalax { + struct input_dev *input; + struct serio *serio; + int idx; + u8 data[EGALAX_FORMAT_MAX_LENGTH]; + char phys[32]; +}; + +static void egalax_process_data(struct egalax *egalax) +{ + struct input_dev *dev = egalax->input; + u8 *data = egalax->data; + u16 x, y; + u8 shift; + u8 mask; + + shift = 3 - ((data[0] & EGALAX_FORMAT_RESOLUTION_MASK) >> 1); + mask = 0xff >> (shift + 1); + + x = (((u16)(data[1] & mask) << 7) | (data[2] & 0x7f)) << shift; + y = (((u16)(data[3] & mask) << 7) | (data[4] & 0x7f)) << shift; + + input_report_key(dev, BTN_TOUCH, data[0] & EGALAX_FORMAT_TOUCH_BIT); + input_report_abs(dev, ABS_X, x); + input_report_abs(dev, ABS_Y, y); + input_sync(dev); +} + +static irqreturn_t egalax_interrupt(struct serio *serio, + unsigned char data, unsigned int flags) +{ + struct egalax *egalax = serio_get_drvdata(serio); + int pkt_len; + + egalax->data[egalax->idx++] = data; + + if (likely(egalax->data[0] & EGALAX_FORMAT_START_BIT)) { + pkt_len = egalax->data[0] & EGALAX_FORMAT_PRESSURE_BIT ? 6 : 5; + if (pkt_len == egalax->idx) { + egalax_process_data(egalax); + egalax->idx = 0; + } + } else { + dev_dbg(&serio->dev, "unknown/unsynchronized data: %x\n", + egalax->data[0]); + egalax->idx = 0; + } + + return IRQ_HANDLED; +} + +/* + * egalax_connect() is the routine that is called when someone adds a + * new serio device that supports egalax protocol and registers it as + * an input device. This is usually accomplished using inputattach. + */ +static int egalax_connect(struct serio *serio, struct serio_driver *drv) +{ + struct egalax *egalax; + struct input_dev *input_dev; + int error; + + egalax = kzalloc(sizeof(struct egalax), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!egalax) { + error = -ENOMEM; + goto err_free_mem; + } + + egalax->serio = serio; + egalax->input = input_dev; + snprintf(egalax->phys, sizeof(egalax->phys), + "%s/input0", serio->phys); + + input_dev->name = "EETI eGalaxTouch Serial TouchScreen"; + input_dev->phys = egalax->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_EGALAX; + input_dev->id.product = 0; + input_dev->id.version = 0x0001; + input_dev->dev.parent = &serio->dev; + + input_set_capability(input_dev, EV_KEY, BTN_TOUCH); + input_set_abs_params(input_dev, ABS_X, + EGALAX_MIN_XC, EGALAX_MAX_XC, 0, 0); + input_set_abs_params(input_dev, ABS_Y, + EGALAX_MIN_YC, EGALAX_MAX_YC, 0, 0); + + serio_set_drvdata(serio, egalax); + + error = serio_open(serio, drv); + if (error) + goto err_reset_drvdata; + + error = input_register_device(input_dev); + if (error) + goto err_close_serio; + + return 0; + +err_close_serio: + serio_close(serio); +err_reset_drvdata: + serio_set_drvdata(serio, NULL); +err_free_mem: + input_free_device(input_dev); + kfree(egalax); + return error; +} + +static void egalax_disconnect(struct serio *serio) +{ + struct egalax *egalax = serio_get_drvdata(serio); + + serio_close(serio); + serio_set_drvdata(serio, NULL); + input_unregister_device(egalax->input); + kfree(egalax); +} + +/* + * The serio driver structure. + */ + +static const struct serio_device_id egalax_serio_ids[] = { + { + .type = SERIO_RS232, + .proto = SERIO_EGALAX, + .id = SERIO_ANY, + .extra = SERIO_ANY, + }, + { 0 } +}; + +MODULE_DEVICE_TABLE(serio, egalax_serio_ids); + +static struct serio_driver egalax_drv = { + .driver = { + .name = "egalax", + }, + .description = DRIVER_DESC, + .id_table = egalax_serio_ids, + .interrupt = egalax_interrupt, + .connect = egalax_connect, + .disconnect = egalax_disconnect, +}; +module_serio_driver(egalax_drv); + +MODULE_AUTHOR("Zoltán Böszörményi "); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL v2"); diff --git a/include/uapi/linux/serio.h b/include/uapi/linux/serio.h index becdd78295cc6..c2ea1698257f6 100644 --- a/include/uapi/linux/serio.h +++ b/include/uapi/linux/serio.h @@ -77,5 +77,6 @@ #define SERIO_PS2MULT 0x3c #define SERIO_TSC40 0x3d #define SERIO_WACOM_IV 0x3e +#define SERIO_EGALAX 0x3f #endif /* _UAPI_SERIO_H */ -- GitLab From b7bd98b7db9fc8fe19da1a5ff0215311c6b95e46 Mon Sep 17 00:00:00 2001 From: David Eccher Date: Fri, 11 Dec 2015 22:13:55 +0100 Subject: [PATCH 1391/2855] usb: gadget: inode.c: fix unbalanced spin_lock in ep0_write Fix bad unlock balance: ep0_write enter with the locks locked from inode.c:1769, hence it must exit with spinlock held to avoid double unlock in dev_config. Signed-off-by: David Eccher Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/inode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index f454c7af489ce..365afd7e14f8c 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1137,10 +1137,9 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) dev->gadget->ep0, dev->req, GFP_KERNEL); } + spin_lock_irq(&dev->lock); if (retval < 0) { - spin_lock_irq (&dev->lock); clean_req (dev->gadget->ep0, dev->req); - spin_unlock_irq (&dev->lock); } else retval = len; -- GitLab From 40e3be3933aee185fd6ab1ec87dfaf3502d9f5b3 Mon Sep 17 00:00:00 2001 From: Damien Riegel Date: Wed, 16 Dec 2015 11:49:14 -0800 Subject: [PATCH 1392/2855] Input: add touchscreen support for TS-4800 On this board, the touchscreen, an ads7843, is not handled directly by Linux but by a companion FPGA. This FPGA is memory-mapped and the IP design is very similar to the mk712. This commit adds the support for this IP. Signed-off-by: Damien Riegel Acked-by: Rob Herring Signed-off-by: Dmitry Torokhov --- .../bindings/input/touchscreen/ts4800-ts.txt | 11 + drivers/input/touchscreen/Kconfig | 16 ++ drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/ts4800-ts.c | 216 ++++++++++++++++++ 4 files changed, 244 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/ts4800-ts.txt create mode 100644 drivers/input/touchscreen/ts4800-ts.c diff --git a/Documentation/devicetree/bindings/input/touchscreen/ts4800-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/ts4800-ts.txt new file mode 100644 index 0000000000000..4c1c092c276bc --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/ts4800-ts.txt @@ -0,0 +1,11 @@ +* TS-4800 Touchscreen bindings + +Required properties: +- compatible: must be "technologic,ts4800-ts" +- reg: physical base address of the controller and length of memory mapped + region. +- syscon: phandle / integers array that points to the syscon node which + describes the FPGA's syscon registers. + - phandle to FPGA's syscon + - offset to the touchscreen register + - offset to the touchscreen enable bit diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 9bcb718668b23..f986e8b44b5fa 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -937,6 +937,22 @@ config TOUCHSCREEN_TOUCHIT213 To compile this driver as a module, choose M here: the module will be called touchit213. +config TOUCHSCREEN_TS4800 + tristate "TS-4800 touchscreen" + depends on HAS_IOMEM && OF + select MFD_SYSCON + select INPUT_POLLDEV + help + Say Y here if you have a touchscreen on a TS-4800 board. + + On TS-4800, the touchscreen is not handled directly by Linux but by + a companion FPGA. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called ts4800_ts. + config TOUCHSCREEN_TSC_SERIO tristate "TSC-10/25/40 serial touchscreen support" select SERIO diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 001357c3f73f9..968ff12e31325 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -69,6 +69,7 @@ obj-$(CONFIG_TOUCHSCREEN_TI_AM335X_TSC) += ti_am335x_tsc.o obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o +obj-$(CONFIG_TOUCHSCREEN_TS4800) += ts4800-ts.o obj-$(CONFIG_TOUCHSCREEN_TSC_SERIO) += tsc40.o obj-$(CONFIG_TOUCHSCREEN_TSC200X_CORE) += tsc200x-core.o obj-$(CONFIG_TOUCHSCREEN_TSC2004) += tsc2004.o diff --git a/drivers/input/touchscreen/ts4800-ts.c b/drivers/input/touchscreen/ts4800-ts.c new file mode 100644 index 0000000000000..3c3dd78303be0 --- /dev/null +++ b/drivers/input/touchscreen/ts4800-ts.c @@ -0,0 +1,216 @@ +/* + * Touchscreen driver for the TS-4800 board + * + * Copyright (c) 2015 - Savoir-faire Linux + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* polling interval in ms */ +#define POLL_INTERVAL 3 + +#define DEBOUNCE_COUNT 1 + +/* sensor values are 12-bit wide */ +#define MAX_12BIT ((1 << 12) - 1) + +#define PENDOWN_MASK 0x1 + +#define X_OFFSET 0x0 +#define Y_OFFSET 0x2 + +struct ts4800_ts { + struct input_polled_dev *poll_dev; + struct device *dev; + char phys[32]; + + void __iomem *base; + struct regmap *regmap; + unsigned int reg; + unsigned int bit; + + bool pendown; + int debounce; +}; + +static void ts4800_ts_open(struct input_polled_dev *dev) +{ + struct ts4800_ts *ts = dev->private; + int ret; + + ts->pendown = false; + ts->debounce = DEBOUNCE_COUNT; + + ret = regmap_update_bits(ts->regmap, ts->reg, ts->bit, ts->bit); + if (ret) + dev_warn(ts->dev, "Failed to enable touchscreen\n"); +} + +static void ts4800_ts_close(struct input_polled_dev *dev) +{ + struct ts4800_ts *ts = dev->private; + int ret; + + ret = regmap_update_bits(ts->regmap, ts->reg, ts->bit, 0); + if (ret) + dev_warn(ts->dev, "Failed to disable touchscreen\n"); + +} + +static void ts4800_ts_poll(struct input_polled_dev *dev) +{ + struct input_dev *input_dev = dev->input; + struct ts4800_ts *ts = dev->private; + u16 last_x = readw(ts->base + X_OFFSET); + u16 last_y = readw(ts->base + Y_OFFSET); + bool pendown = last_x & PENDOWN_MASK; + + if (pendown) { + if (ts->debounce) { + ts->debounce--; + return; + } + + if (!ts->pendown) { + input_report_key(input_dev, BTN_TOUCH, 1); + ts->pendown = true; + } + + last_x = ((~last_x) >> 4) & MAX_12BIT; + last_y = ((~last_y) >> 4) & MAX_12BIT; + + input_report_abs(input_dev, ABS_X, last_x); + input_report_abs(input_dev, ABS_Y, last_y); + input_sync(input_dev); + } else if (ts->pendown) { + ts->pendown = false; + ts->debounce = DEBOUNCE_COUNT; + input_report_key(input_dev, BTN_TOUCH, 0); + input_sync(input_dev); + } +} + +static int ts4800_parse_dt(struct platform_device *pdev, + struct ts4800_ts *ts) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct device_node *syscon_np; + u32 reg, bit; + int error; + + syscon_np = of_parse_phandle(np, "syscon", 0); + if (!syscon_np) { + dev_err(dev, "no syscon property\n"); + return -ENODEV; + } + + error = of_property_read_u32_index(np, "syscon", 1, ®); + if (error < 0) { + dev_err(dev, "no offset in syscon\n"); + return error; + } + + ts->reg = reg; + + error = of_property_read_u32_index(np, "syscon", 2, &bit); + if (error < 0) { + dev_err(dev, "no bit in syscon\n"); + return error; + } + + ts->bit = BIT(bit); + + ts->regmap = syscon_node_to_regmap(syscon_np); + if (IS_ERR(ts->regmap)) { + dev_err(dev, "cannot get parent's regmap\n"); + return PTR_ERR(ts->regmap); + } + + return 0; +} + +static int ts4800_ts_probe(struct platform_device *pdev) +{ + struct input_polled_dev *poll_dev; + struct ts4800_ts *ts; + struct resource *res; + int error; + + ts = devm_kzalloc(&pdev->dev, sizeof(*ts), GFP_KERNEL); + if (!ts) + return -ENOMEM; + + error = ts4800_parse_dt(pdev, ts); + if (error) + return error; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ts->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(ts->base)) + return PTR_ERR(ts->base); + + poll_dev = devm_input_allocate_polled_device(&pdev->dev); + if (!poll_dev) + return -ENOMEM; + + snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&pdev->dev)); + ts->poll_dev = poll_dev; + ts->dev = &pdev->dev; + + poll_dev->private = ts; + poll_dev->poll_interval = POLL_INTERVAL; + poll_dev->open = ts4800_ts_open; + poll_dev->close = ts4800_ts_close; + poll_dev->poll = ts4800_ts_poll; + + poll_dev->input->name = "TS-4800 Touchscreen"; + poll_dev->input->phys = ts->phys; + + input_set_capability(poll_dev->input, EV_KEY, BTN_TOUCH); + input_set_abs_params(poll_dev->input, ABS_X, 0, MAX_12BIT, 0, 0); + input_set_abs_params(poll_dev->input, ABS_Y, 0, MAX_12BIT, 0, 0); + + error = input_register_polled_device(poll_dev); + if (error) { + dev_err(&pdev->dev, + "Unabled to register polled input device (%d)\n", + error); + return error; + } + + return 0; +} + +static const struct of_device_id ts4800_ts_of_match[] = { + { .compatible = "technologic,ts4800-ts", }, + { }, +}; +MODULE_DEVICE_TABLE(of, ts4800_ts_of_match); + +static struct platform_driver ts4800_ts_driver = { + .driver = { + .name = "ts4800-ts", + .of_match_table = ts4800_ts_of_match, + }, + .probe = ts4800_ts_probe, +}; +module_platform_driver(ts4800_ts_driver); + +MODULE_AUTHOR("Damien Riegel "); +MODULE_DESCRIPTION("TS-4800 Touchscreen Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:ts4800_ts"); -- GitLab From d1301afd71bd38b1610b391e50debf766faa84be Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 16 Dec 2015 18:59:31 +1100 Subject: [PATCH 1393/2855] selftests/powerpc: Move pick_online_cpu() up into utils.c We want to use this in another test, so make it available at the top of the powerpc selftests tree. Signed-off-by: Michael Ellerman --- tools/testing/selftests/powerpc/pmu/Makefile | 2 +- tools/testing/selftests/powerpc/pmu/lib.c | 26 ------------------ tools/testing/selftests/powerpc/pmu/lib.h | 1 - tools/testing/selftests/powerpc/utils.c | 29 ++++++++++++++++++++ tools/testing/selftests/powerpc/utils.h | 1 + 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/tools/testing/selftests/powerpc/pmu/Makefile b/tools/testing/selftests/powerpc/pmu/Makefile index 50326cbb372d6..ac41a7177f2e2 100644 --- a/tools/testing/selftests/powerpc/pmu/Makefile +++ b/tools/testing/selftests/powerpc/pmu/Makefile @@ -2,7 +2,7 @@ noarg: $(MAKE) -C ../ TEST_PROGS := count_instructions l3_bank_test per_event_excludes -EXTRA_SOURCES := ../harness.c event.c lib.c +EXTRA_SOURCES := ../harness.c event.c lib.c ../utils.c all: $(TEST_PROGS) ebb diff --git a/tools/testing/selftests/powerpc/pmu/lib.c b/tools/testing/selftests/powerpc/pmu/lib.c index a07104c2afe69..a361ad3334ce3 100644 --- a/tools/testing/selftests/powerpc/pmu/lib.c +++ b/tools/testing/selftests/powerpc/pmu/lib.c @@ -15,32 +15,6 @@ #include "lib.h" -int pick_online_cpu(void) -{ - cpu_set_t mask; - int cpu; - - CPU_ZERO(&mask); - - if (sched_getaffinity(0, sizeof(mask), &mask)) { - perror("sched_getaffinity"); - return -1; - } - - /* We prefer a primary thread, but skip 0 */ - for (cpu = 8; cpu < CPU_SETSIZE; cpu += 8) - if (CPU_ISSET(cpu, &mask)) - return cpu; - - /* Search for anything, but in reverse */ - for (cpu = CPU_SETSIZE - 1; cpu >= 0; cpu--) - if (CPU_ISSET(cpu, &mask)) - return cpu; - - printf("No cpus in affinity mask?!\n"); - return -1; -} - int bind_to_cpu(int cpu) { cpu_set_t mask; diff --git a/tools/testing/selftests/powerpc/pmu/lib.h b/tools/testing/selftests/powerpc/pmu/lib.h index ca5d72ae3be6b..0213af4ff332d 100644 --- a/tools/testing/selftests/powerpc/pmu/lib.h +++ b/tools/testing/selftests/powerpc/pmu/lib.h @@ -19,7 +19,6 @@ union pipe { int fds[2]; }; -extern int pick_online_cpu(void); extern int bind_to_cpu(int cpu); extern int kill_child_and_wait(pid_t child_pid); extern int wait_for_child(pid_t child_pid); diff --git a/tools/testing/selftests/powerpc/utils.c b/tools/testing/selftests/powerpc/utils.c index 536113add3800..dcf74184bfd0a 100644 --- a/tools/testing/selftests/powerpc/utils.c +++ b/tools/testing/selftests/powerpc/utils.c @@ -3,10 +3,13 @@ * Licensed under GPLv2. */ +#define _GNU_SOURCE /* For CPU_ZERO etc. */ + #include #include #include #include +#include #include #include #include @@ -56,3 +59,29 @@ out: close(fd); return result; } + +int pick_online_cpu(void) +{ + cpu_set_t mask; + int cpu; + + CPU_ZERO(&mask); + + if (sched_getaffinity(0, sizeof(mask), &mask)) { + perror("sched_getaffinity"); + return -1; + } + + /* We prefer a primary thread, but skip 0 */ + for (cpu = 8; cpu < CPU_SETSIZE; cpu += 8) + if (CPU_ISSET(cpu, &mask)) + return cpu; + + /* Search for anything, but in reverse */ + for (cpu = CPU_SETSIZE - 1; cpu >= 0; cpu--) + if (CPU_ISSET(cpu, &mask)) + return cpu; + + printf("No cpus in affinity mask?!\n"); + return -1; +} diff --git a/tools/testing/selftests/powerpc/utils.h b/tools/testing/selftests/powerpc/utils.h index fbf2bf530e50e..175ac6ad10dde 100644 --- a/tools/testing/selftests/powerpc/utils.h +++ b/tools/testing/selftests/powerpc/utils.h @@ -22,6 +22,7 @@ typedef uint8_t u8; int test_harness(int (test_function)(void), char *name); extern void *get_auxv_entry(int type); +int pick_online_cpu(void); static inline bool have_hwcap2(unsigned long ftr2) { -- GitLab From 00b7ec5c9cf338902faea2e40801573a384e45be Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 2 Dec 2015 20:44:09 +1100 Subject: [PATCH 1394/2855] selftests/powerpc: Import Anton's context_switch2 benchmark This gets referred to a lot in commit messages, so let's pull it into the selftests. Almost vanilla from: http://ozlabs.org/~anton/junkcode/context_switch2.c Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman Acked-by: Anton Blanchard --- .../selftests/powerpc/benchmarks/.gitignore | 1 + .../selftests/powerpc/benchmarks/Makefile | 4 +- .../powerpc/benchmarks/context_switch.c | 452 ++++++++++++++++++ 3 files changed, 456 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/benchmarks/context_switch.c diff --git a/tools/testing/selftests/powerpc/benchmarks/.gitignore b/tools/testing/selftests/powerpc/benchmarks/.gitignore index b4709ea588c1b..6fa673316ac2c 100644 --- a/tools/testing/selftests/powerpc/benchmarks/.gitignore +++ b/tools/testing/selftests/powerpc/benchmarks/.gitignore @@ -1 +1,2 @@ gettimeofday +context_switch diff --git a/tools/testing/selftests/powerpc/benchmarks/Makefile b/tools/testing/selftests/powerpc/benchmarks/Makefile index 5fa48702070dd..8cb7415c55aaf 100644 --- a/tools/testing/selftests/powerpc/benchmarks/Makefile +++ b/tools/testing/selftests/powerpc/benchmarks/Makefile @@ -1,4 +1,4 @@ -TEST_PROGS := gettimeofday +TEST_PROGS := gettimeofday context_switch CFLAGS += -O2 @@ -6,6 +6,8 @@ all: $(TEST_PROGS) $(TEST_PROGS): ../harness.c +context_switch: LDLIBS += -lpthread + include ../../lib.mk clean: diff --git a/tools/testing/selftests/powerpc/benchmarks/context_switch.c b/tools/testing/selftests/powerpc/benchmarks/context_switch.c new file mode 100644 index 0000000000000..ed21a83a0f996 --- /dev/null +++ b/tools/testing/selftests/powerpc/benchmarks/context_switch.c @@ -0,0 +1,452 @@ +/* + * Context switch microbenchmark. + * + * Copyright (C) 2015 Anton Blanchard , IBM + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static unsigned int timeout = INT_MAX; + +static int touch_vdso; +struct timeval tv; + +static int touch_fp; +double fp; + +static int touch_vector; +typedef int v4si __attribute__ ((vector_size (16))); +v4si a, b, c; + +#ifdef __powerpc__ +static int touch_altivec; + +static void __attribute__((__target__("no-vsx"))) altivec_touch_fn(void) +{ + c = a + b; +} +#endif + +static void touch(void) +{ + if (touch_vdso) + gettimeofday(&tv, NULL); + + if (touch_fp) + fp += 0.1; + +#ifdef __powerpc__ + if (touch_altivec) + altivec_touch_fn(); +#endif + + if (touch_vector) + c = a + b; + + asm volatile("# %0 %1 %2": : "r"(&tv), "r"(&fp), "r"(&c)); +} + +static void start_thread_on(void *(*fn)(void *), void *arg, unsigned long cpu) +{ + pthread_t tid; + cpu_set_t cpuset; + pthread_attr_t attr; + + CPU_ZERO(&cpuset); + CPU_SET(cpu, &cpuset); + + pthread_attr_init(&attr); + + if (pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpuset)) { + perror("pthread_attr_setaffinity_np"); + exit(1); + } + + if (pthread_create(&tid, &attr, fn, arg)) { + perror("pthread_create"); + exit(1); + } +} + +static void start_process_on(void *(*fn)(void *), void *arg, unsigned long cpu) +{ + int pid; + cpu_set_t cpuset; + + pid = fork(); + if (pid == -1) { + perror("fork"); + exit(1); + } + + if (pid) + return; + + CPU_ZERO(&cpuset); + CPU_SET(cpu, &cpuset); + + if (sched_setaffinity(0, sizeof(cpuset), &cpuset)) { + perror("sched_setaffinity"); + exit(1); + } + + fn(arg); + + exit(0); +} + +static unsigned long iterations; +static unsigned long iterations_prev; + +static void sigalrm_handler(int junk) +{ + unsigned long i = iterations; + + printf("%ld\n", i - iterations_prev); + iterations_prev = i; + + if (--timeout == 0) + kill(0, SIGUSR1); + + alarm(1); +} + +static void sigusr1_handler(int junk) +{ + exit(0); +} + +struct actions { + void (*setup)(int, int); + void *(*thread1)(void *); + void *(*thread2)(void *); +}; + +#define READ 0 +#define WRITE 1 + +static int pipe_fd1[2]; +static int pipe_fd2[2]; + +static void pipe_setup(int cpu1, int cpu2) +{ + if (pipe(pipe_fd1) || pipe(pipe_fd2)) + exit(1); +} + +static void *pipe_thread1(void *arg) +{ + signal(SIGALRM, sigalrm_handler); + alarm(1); + + while (1) { + assert(read(pipe_fd1[READ], &c, 1) == 1); + touch(); + + assert(write(pipe_fd2[WRITE], &c, 1) == 1); + touch(); + + iterations += 2; + } + + return NULL; +} + +static void *pipe_thread2(void *arg) +{ + while (1) { + assert(write(pipe_fd1[WRITE], &c, 1) == 1); + touch(); + + assert(read(pipe_fd2[READ], &c, 1) == 1); + touch(); + } + + return NULL; +} + +static struct actions pipe_actions = { + .setup = pipe_setup, + .thread1 = pipe_thread1, + .thread2 = pipe_thread2, +}; + +static void yield_setup(int cpu1, int cpu2) +{ + if (cpu1 != cpu2) { + fprintf(stderr, "Both threads must be on the same CPU for yield test\n"); + exit(1); + } +} + +static void *yield_thread1(void *arg) +{ + signal(SIGALRM, sigalrm_handler); + alarm(1); + + while (1) { + sched_yield(); + touch(); + + iterations += 2; + } + + return NULL; +} + +static void *yield_thread2(void *arg) +{ + while (1) { + sched_yield(); + touch(); + } + + return NULL; +} + +static struct actions yield_actions = { + .setup = yield_setup, + .thread1 = yield_thread1, + .thread2 = yield_thread2, +}; + +static long sys_futex(void *addr1, int op, int val1, struct timespec *timeout, + void *addr2, int val3) +{ + return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3); +} + +static unsigned long cmpxchg(unsigned long *p, unsigned long expected, + unsigned long desired) +{ + unsigned long exp = expected; + + __atomic_compare_exchange_n(p, &exp, desired, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); + return exp; +} + +static unsigned long xchg(unsigned long *p, unsigned long val) +{ + return __atomic_exchange_n(p, val, __ATOMIC_SEQ_CST); +} + +static int mutex_lock(unsigned long *m) +{ + int c; + + c = cmpxchg(m, 0, 1); + if (!c) + return 0; + + if (c == 1) + c = xchg(m, 2); + + while (c) { + sys_futex(m, FUTEX_WAIT, 2, NULL, NULL, 0); + c = xchg(m, 2); + } + + return 0; +} + +static int mutex_unlock(unsigned long *m) +{ + if (*m == 2) + *m = 0; + else if (xchg(m, 0) == 1) + return 0; + + sys_futex(m, FUTEX_WAKE, 1, NULL, NULL, 0); + + return 0; +} + +static unsigned long *m1, *m2; + +static void futex_setup(int cpu1, int cpu2) +{ + int shmid; + void *shmaddr; + + shmid = shmget(IPC_PRIVATE, getpagesize(), SHM_R | SHM_W); + if (shmid < 0) { + perror("shmget"); + exit(1); + } + + shmaddr = shmat(shmid, NULL, 0); + if (shmaddr == (char *)-1) { + perror("shmat"); + shmctl(shmid, IPC_RMID, NULL); + exit(1); + } + + shmctl(shmid, IPC_RMID, NULL); + + m1 = shmaddr; + m2 = shmaddr + sizeof(*m1); + + *m1 = 0; + *m2 = 0; + + mutex_lock(m1); + mutex_lock(m2); +} + +static void *futex_thread1(void *arg) +{ + signal(SIGALRM, sigalrm_handler); + alarm(1); + + while (1) { + mutex_lock(m2); + mutex_unlock(m1); + + iterations += 2; + } + + return NULL; +} + +static void *futex_thread2(void *arg) +{ + while (1) { + mutex_unlock(m2); + mutex_lock(m1); + } + + return NULL; +} + +static struct actions futex_actions = { + .setup = futex_setup, + .thread1 = futex_thread1, + .thread2 = futex_thread2, +}; + +static int processes; + +static struct option options[] = { + { "test", required_argument, 0, 't' }, + { "process", no_argument, &processes, 1 }, + { "timeout", required_argument, 0, 's' }, + { "vdso", no_argument, &touch_vdso, 1 }, + { "fp", no_argument, &touch_fp, 1 }, +#ifdef __powerpc__ + { "altivec", no_argument, &touch_altivec, 1 }, +#endif + { "vector", no_argument, &touch_vector, 1 }, + { 0, }, +}; + +static void usage(void) +{ + fprintf(stderr, "Usage: context_switch2 CPU1 CPU2\n\n"); + fprintf(stderr, "\t\t--test=X\tpipe, futex or yield\n"); + fprintf(stderr, "\t\t--process\tUse processes (default threads)\n"); + fprintf(stderr, "\t\t--timeout=X\tDuration in seconds to run\n"); + fprintf(stderr, "\t\t--vdso\t\ttouch VDSO\n"); + fprintf(stderr, "\t\t--fp\t\ttouch FP\n"); +#ifdef __powerpc__ + fprintf(stderr, "\t\t--altivec\ttouch altivec\n"); +#endif + fprintf(stderr, "\t\t--vector\ttouch vector\n"); +} + +int main(int argc, char *argv[]) +{ + signed char c; + struct actions *actions = &pipe_actions; + int cpu1; + int cpu2; + static void (*start_fn)(void *(*fn)(void *), void *arg, unsigned long cpu); + + while (1) { + int option_index = 0; + + c = getopt_long(argc, argv, "", options, &option_index); + + if (c == -1) + break; + + switch (c) { + case 0: + if (options[option_index].flag != 0) + break; + + usage(); + exit(1); + break; + + case 't': + if (!strcmp(optarg, "pipe")) { + actions = &pipe_actions; + } else if (!strcmp(optarg, "yield")) { + actions = &yield_actions; + } else if (!strcmp(optarg, "futex")) { + actions = &futex_actions; + } else { + usage(); + exit(1); + } + break; + + case 's': + timeout = atoi(optarg); + break; + + default: + usage(); + exit(1); + } + } + + if (processes) + start_fn = start_process_on; + else + start_fn = start_thread_on; + + if (((argc - optind) != 2)) { + usage(); + exit(1); + } + + /* Create a new process group so we can signal everyone for exit */ + setpgid(getpid(), getpid()); + + signal(SIGUSR1, sigusr1_handler); + + cpu1 = atoi(argv[optind++]); + cpu2 = atoi(argv[optind++]); + + actions->setup(cpu1, cpu2); + + start_fn(actions->thread1, NULL, cpu1); + start_fn(actions->thread2, NULL, cpu2); + + while (1) + sleep(3600); + + return 0; +} -- GitLab From ea0c321784565c681507e02acf900deaa1e9e952 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 2 Dec 2015 20:44:10 +1100 Subject: [PATCH 1395/2855] selftests/powerpc: Make context_switch do something with no args For ease of use make the context_switch test do something useful when called with no arguments. Default to a 30 second run, using threads, doing yield, and use any online cpu. Make it print out what it's doing to avoid confusion. Signed-off-by: Michael Ellerman Acked-by: Anton Blanchard --- .../selftests/powerpc/benchmarks/Makefile | 1 + .../powerpc/benchmarks/context_switch.c | 32 +++++++++++++------ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/powerpc/benchmarks/Makefile b/tools/testing/selftests/powerpc/benchmarks/Makefile index 8cb7415c55aaf..912445ff7ce76 100644 --- a/tools/testing/selftests/powerpc/benchmarks/Makefile +++ b/tools/testing/selftests/powerpc/benchmarks/Makefile @@ -6,6 +6,7 @@ all: $(TEST_PROGS) $(TEST_PROGS): ../harness.c +context_switch: ../utils.c context_switch: LDLIBS += -lpthread include ../../lib.mk diff --git a/tools/testing/selftests/powerpc/benchmarks/context_switch.c b/tools/testing/selftests/powerpc/benchmarks/context_switch.c index ed21a83a0f996..d8b6d10f36a6e 100644 --- a/tools/testing/selftests/powerpc/benchmarks/context_switch.c +++ b/tools/testing/selftests/powerpc/benchmarks/context_switch.c @@ -26,7 +26,9 @@ #include #include -static unsigned int timeout = INT_MAX; +#include "../utils.h" + +static unsigned int timeout = 30; static int touch_vdso; struct timeval tv; @@ -363,9 +365,9 @@ static struct option options[] = { static void usage(void) { fprintf(stderr, "Usage: context_switch2 CPU1 CPU2\n\n"); - fprintf(stderr, "\t\t--test=X\tpipe, futex or yield\n"); + fprintf(stderr, "\t\t--test=X\tpipe, futex or yield (default)\n"); fprintf(stderr, "\t\t--process\tUse processes (default threads)\n"); - fprintf(stderr, "\t\t--timeout=X\tDuration in seconds to run\n"); + fprintf(stderr, "\t\t--timeout=X\tDuration in seconds to run (default 30)\n"); fprintf(stderr, "\t\t--vdso\t\ttouch VDSO\n"); fprintf(stderr, "\t\t--fp\t\ttouch FP\n"); #ifdef __powerpc__ @@ -377,7 +379,7 @@ static void usage(void) int main(int argc, char *argv[]) { signed char c; - struct actions *actions = &pipe_actions; + struct actions *actions = &yield_actions; int cpu1; int cpu2; static void (*start_fn)(void *(*fn)(void *), void *arg, unsigned long cpu); @@ -428,18 +430,30 @@ int main(int argc, char *argv[]) start_fn = start_thread_on; if (((argc - optind) != 2)) { - usage(); - exit(1); + cpu1 = cpu2 = pick_online_cpu(); + } else { + cpu1 = atoi(argv[optind++]); + cpu2 = atoi(argv[optind++]); } + printf("Using %s with ", processes ? "processes" : "threads"); + + if (actions == &pipe_actions) + printf("pipe"); + else if (actions == &yield_actions) + printf("yield"); + else + printf("futex"); + + printf(" on cpus %d/%d touching FP:%s altivec:%s vector:%s vdso:%s\n", + cpu1, cpu2, touch_fp ? "yes" : "no", touch_altivec ? "yes" : "no", + touch_vector ? "yes" : "no", touch_vdso ? "yes" : "no"); + /* Create a new process group so we can signal everyone for exit */ setpgid(getpid(), getpid()); signal(SIGUSR1, sigusr1_handler); - cpu1 = atoi(argv[optind++]); - cpu2 = atoi(argv[optind++]); - actions->setup(cpu1, cpu2); start_fn(actions->thread1, NULL, cpu1); -- GitLab From 51c21e72eb99d1136614135d633baae269893778 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 2 Dec 2015 20:44:11 +1100 Subject: [PATCH 1396/2855] selftests/powerpc: Make context_switch touch FP/altivec/vector by default Simply because it touches more code paths that way, and therefore tests more things. Signed-off-by: Michael Ellerman Acked-by: Anton Blanchard --- .../selftests/powerpc/benchmarks/context_switch.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/powerpc/benchmarks/context_switch.c b/tools/testing/selftests/powerpc/benchmarks/context_switch.c index d8b6d10f36a6e..7b785941adec4 100644 --- a/tools/testing/selftests/powerpc/benchmarks/context_switch.c +++ b/tools/testing/selftests/powerpc/benchmarks/context_switch.c @@ -33,15 +33,15 @@ static unsigned int timeout = 30; static int touch_vdso; struct timeval tv; -static int touch_fp; +static int touch_fp = 1; double fp; -static int touch_vector; +static int touch_vector = 1; typedef int v4si __attribute__ ((vector_size (16))); v4si a, b, c; #ifdef __powerpc__ -static int touch_altivec; +static int touch_altivec = 1; static void __attribute__((__target__("no-vsx"))) altivec_touch_fn(void) { @@ -354,11 +354,11 @@ static struct option options[] = { { "process", no_argument, &processes, 1 }, { "timeout", required_argument, 0, 's' }, { "vdso", no_argument, &touch_vdso, 1 }, - { "fp", no_argument, &touch_fp, 1 }, + { "no-fp", no_argument, &touch_fp, 0 }, #ifdef __powerpc__ - { "altivec", no_argument, &touch_altivec, 1 }, + { "no-altivec", no_argument, &touch_altivec, 0 }, #endif - { "vector", no_argument, &touch_vector, 1 }, + { "no-vector", no_argument, &touch_vector, 0 }, { 0, }, }; -- GitLab From a8da474ec18f4c4c39f83202d64d73a23b755c1d Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Mon, 7 Dec 2015 10:50:51 +1100 Subject: [PATCH 1397/2855] selftests/powerpc: Add script to test HMI functionality HMIs (Hypervisor Management|Maintenance Interrupts) are a class of interrupt on POWER systems. HMI support has traditionally been exceptionally difficult to test, however Skiboot ships a tool that, with the correct magic numbers, will inject them. This, therefore, is a first pass at a script to inject HMIs and monitor Linux's response. It injects an HMI on each core on every chip in turn It then watches dmesg to see if it's acknowledged by Linux. On a Tuletta, I observed that we see 8 (or sometimes 9 or more) events per injection, regardless of SMT setting, so we wait for 8 before progressing. It sits in a new scripts/ directory in selftests/powerpc, because it's not designed to be run as part of the regular make selftests process. In particular, it is quite possibly going to end up garding lots of your CPUs, so it should only be run if you know how to undo that. CC: Mahesh J Salgaonkar Signed-off-by: Daniel Axtens Signed-off-by: Michael Ellerman --- .../testing/selftests/powerpc/scripts/hmi.sh | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100755 tools/testing/selftests/powerpc/scripts/hmi.sh diff --git a/tools/testing/selftests/powerpc/scripts/hmi.sh b/tools/testing/selftests/powerpc/scripts/hmi.sh new file mode 100755 index 0000000000000..83fb253ae3bd3 --- /dev/null +++ b/tools/testing/selftests/powerpc/scripts/hmi.sh @@ -0,0 +1,89 @@ +#!/bin/sh +# +# Copyright 2015, Daniel Axtens, IBM Corporation +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# do we have ./getscom, ./putscom? +if [ -x ./getscom ] && [ -x ./putscom ]; then + GETSCOM=./getscom + PUTSCOM=./putscom +elif which getscom > /dev/null; then + GETSCOM=$(which getscom) + PUTSCOM=$(which putscom) +else + cat < /dev/null; then + echo "Error injecting. Aborting!" + exit 1 + fi + + # now we want to wait for all the HMIs to be processed + # we expect one per thread on the core + i=0; + new_hmis=$(COUNT_HMIS) + while [ $new_hmis -lt $((old_hmis + expected_hmis)) ] && [ $i -lt 12 ]; do + echo "Seen $((new_hmis - old_hmis)) HMI(s) out of $expected_hmis expected, sleeping" + sleep 5; + i=$((i + 1)) + new_hmis=$(COUNT_HMIS) + done + if [ $i = 12 ]; then + echo "Haven't seen expected $expected_hmis recoveries after 1 min. Aborting." + exit 1 + fi + echo "Processed $expected_hmis events; presumed success. Check dmesg." + echo "" +done -- GitLab From df2d8213d9e3f636f8273847cf906ded3535ec2f Mon Sep 17 00:00:00 2001 From: John Garry Date: Fri, 11 Dec 2015 20:03:21 +0800 Subject: [PATCH 1398/2855] hisi_sas: use platform_get_irq() It is preferred that drivers use platform_get_irq() instead of irq_of_parse_and_map(), so replace. Signed-off-by: John Garry Acked-by: Rob Herring Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 1 - drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 13 +++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 30a9ab94cd291..5af2e4187f01e 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 0ed2f92c8959d..d54381149c0d5 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1673,19 +1673,16 @@ static irq_handler_t fatal_interrupts[HISI_SAS_MAX_QUEUES] = { static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) { - struct device *dev = &hisi_hba->pdev->dev; - struct device_node *np = dev->of_node; + struct platform_device *pdev = hisi_hba->pdev; + struct device *dev = &pdev->dev; int i, j, irq, rc, idx; - if (!np) - return -ENOENT; - for (i = 0; i < hisi_hba->n_phy; i++) { struct hisi_sas_phy *phy = &hisi_hba->phy[i]; idx = i * HISI_SAS_PHY_INT_NR; for (j = 0; j < HISI_SAS_PHY_INT_NR; j++, idx++) { - irq = irq_of_parse_and_map(np, idx); + irq = platform_get_irq(pdev, idx); if (!irq) { dev_err(dev, "irq init: fail map phy interrupt %d\n", @@ -1706,7 +1703,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx = hisi_hba->n_phy * HISI_SAS_PHY_INT_NR; for (i = 0; i < hisi_hba->queue_count; i++, idx++) { - irq = irq_of_parse_and_map(np, idx); + irq = platform_get_irq(pdev, idx); if (!irq) { dev_err(dev, "irq init: could not map cq interrupt %d\n", idx); @@ -1724,7 +1721,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx = (hisi_hba->n_phy * HISI_SAS_PHY_INT_NR) + hisi_hba->queue_count; for (i = 0; i < HISI_SAS_FATAL_INT_NR; i++, idx++) { - irq = irq_of_parse_and_map(np, idx); + irq = platform_get_irq(pdev, idx); if (!irq) { dev_err(dev, "irq init: could not map fatal interrupt %d\n", idx); -- GitLab From a9ec81f4ed5c05dbbc671e5fa39de0540eb0495f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 14 Sep 2015 15:14:23 +0300 Subject: [PATCH 1399/2855] serial: sh-sci: Drop the interface clock As no platform defines an interface clock the SCI driver always falls back to a clock named "peripheral_clk". - On SH platforms that clock is the base clock for the SCI functional clock and has the same frequency, - On ARM platforms that clock doesn't exist, and clk_get() will return the default clock for the device. We can thus make the functional clock mandatory and drop the interface clock. EPROBE_DEFER is handled for clocks that may be referenced from DT (i.e. "fck", and the deprecated "sci_ick"). Cc: devicetree@vger.kernel.org Signed-off-by: Laurent Pinchart Acked-by: Simon Horman [geert: Handle EPROBE_DEFER, reformat description, break long comment line] Signed-off-by: Geert Uytterhoeven Acked-by: Rob Herring Acked-by: Greg Kroah-Hartman --- .../bindings/serial/renesas,sci-serial.txt | 4 +- drivers/tty/serial/sh-sci.c | 64 ++++++++++++------- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index 73f825e5e6448..2c9e6b8477e92 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -42,7 +42,7 @@ Required properties: - clocks: Must contain a phandle and clock-specifier pair for each entry in clock-names. - - clock-names: Must contain "sci_ick" for the SCIx UART interface clock. + - clock-names: Must contain "fck" for the SCIx UART functional clock. Note: Each enabled SCIx UART should have an alias correctly numbered in the "aliases" node. @@ -63,7 +63,7 @@ Example: interrupt-parent = <&gic>; interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp2_clks R8A7790_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x21>, <&dmac0 0x22>; dma-names = "tx", "rx"; }; diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 960e50a97558c..cc6fa55231ba3 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -92,8 +92,6 @@ struct sci_port { struct timer_list break_timer; int break_flag; - /* Interface clock */ - struct clk *iclk; /* Function clock */ struct clk *fclk; @@ -457,9 +455,8 @@ static void sci_port_enable(struct sci_port *sci_port) pm_runtime_get_sync(sci_port->port.dev); - clk_prepare_enable(sci_port->iclk); - sci_port->port.uartclk = clk_get_rate(sci_port->iclk); clk_prepare_enable(sci_port->fclk); + sci_port->port.uartclk = clk_get_rate(sci_port->fclk); } static void sci_port_disable(struct sci_port *sci_port) @@ -476,7 +473,6 @@ static void sci_port_disable(struct sci_port *sci_port) sci_port->break_flag = 0; clk_disable_unprepare(sci_port->fclk); - clk_disable_unprepare(sci_port->iclk); pm_runtime_put_sync(sci_port->port.dev); } @@ -1622,7 +1618,7 @@ static int sci_notifier(struct notifier_block *self, struct uart_port *port = &sci_port->port; spin_lock_irqsave(&port->lock, flags); - port->uartclk = clk_get_rate(sci_port->iclk); + port->uartclk = clk_get_rate(sci_port->fclk); spin_unlock_irqrestore(&port->lock, flags); } @@ -2241,6 +2237,42 @@ static struct uart_ops sci_uart_ops = { #endif }; +static int sci_init_clocks(struct sci_port *sci_port, struct device *dev) +{ + /* Get the SCI functional clock. It's called "fck" on ARM. */ + sci_port->fclk = clk_get(dev, "fck"); + if (PTR_ERR(sci_port->fclk) == -EPROBE_DEFER) + return -EPROBE_DEFER; + if (!IS_ERR(sci_port->fclk)) + return 0; + + /* + * But it used to be called "sci_ick", and we need to maintain DT + * backward compatibility. + */ + sci_port->fclk = clk_get(dev, "sci_ick"); + if (PTR_ERR(sci_port->fclk) == -EPROBE_DEFER) + return -EPROBE_DEFER; + if (!IS_ERR(sci_port->fclk)) + return 0; + + /* SH has historically named the clock "sci_fck". */ + sci_port->fclk = clk_get(dev, "sci_fck"); + if (!IS_ERR(sci_port->fclk)) + return 0; + + /* + * Not all SH platforms declare a clock lookup entry for SCI devices, + * in which case we need to get the global "peripheral_clk" clock. + */ + sci_port->fclk = clk_get(dev, "peripheral_clk"); + if (!IS_ERR(sci_port->fclk)) + return 0; + + dev_err(dev, "failed to get functional clock\n"); + return PTR_ERR(sci_port->fclk); +} + static int sci_init_single(struct platform_device *dev, struct sci_port *sci_port, unsigned int index, struct plat_sci_port *p, bool early) @@ -2333,22 +2365,9 @@ static int sci_init_single(struct platform_device *dev, sci_port->sampling_rate = p->sampling_rate; if (!early) { - sci_port->iclk = clk_get(&dev->dev, "sci_ick"); - if (IS_ERR(sci_port->iclk)) { - sci_port->iclk = clk_get(&dev->dev, "peripheral_clk"); - if (IS_ERR(sci_port->iclk)) { - dev_err(&dev->dev, "can't get iclk\n"); - return PTR_ERR(sci_port->iclk); - } - } - - /* - * The function clock is optional, ignore it if we can't - * find it. - */ - sci_port->fclk = clk_get(&dev->dev, "sci_fck"); - if (IS_ERR(sci_port->fclk)) - sci_port->fclk = NULL; + ret = sci_init_clocks(sci_port, &dev->dev); + if (ret < 0) + return ret; port->dev = &dev->dev; @@ -2405,7 +2424,6 @@ static int sci_init_single(struct platform_device *dev, static void sci_cleanup_single(struct sci_port *port) { - clk_put(port->iclk); clk_put(port->fclk); pm_runtime_disable(port->port.dev); -- GitLab From 598604ff22109a025af8d5038664ebeb2402afdc Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 11 Dec 2015 12:48:15 +0100 Subject: [PATCH 1400/2855] serial: sh-sci: Add fallback compatibility strings Add fallback compatibility strings for R-Car Gen1, Gen2, and Gen3. This is in keeping with the fallback scheme being adopted wherever appropriate for drivers for Renesas SoCs. Signed-off-by: Geert Uytterhoeven --- .../bindings/serial/renesas,sci-serial.txt | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index 2c9e6b8477e92..7091213f02513 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -2,7 +2,7 @@ Required properties: - - compatible: Must contain one of the following: + - compatible: Must contain one or more of the following: - "renesas,scif-r7s72100" for R7S72100 (RZ/A1H) SCIF compatible UART. - "renesas,scifa-r8a73a4" for R8A73A4 (R-Mobile APE6) SCIFA compatible UART. @@ -27,6 +27,14 @@ Required properties: - "renesas,hscif-r8a7795" for R8A7795 (R-Car H3) HSCIF compatible UART. - "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART. - "renesas,scifb-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFB compatible UART. + - "renesas,rcar-gen1-scif" for R-Car Gen1 SCIF compatible UART, + - "renesas,rcar-gen2-scif" for R-Car Gen2 SCIF compatible UART, + - "renesas,rcar-gen3-scif" for R-Car Gen3 SCIF compatible UART, + - "renesas,rcar-gen2-scifa" for R-Car Gen2 SCIFA compatible UART, + - "renesas,rcar-gen2-scifb" for R-Car Gen2 SCIFB compatible UART, + - "renesas,rcar-gen1-hscif" for R-Car Gen1 HSCIF compatible UART, + - "renesas,rcar-gen2-hscif" for R-Car Gen2 HSCIF compatible UART, + - "renesas,rcar-gen3-hscif" for R-Car Gen3 HSCIF compatible UART, - "renesas,scif" for generic SCIF compatible UART. - "renesas,scifa" for generic SCIFA compatible UART. - "renesas,scifb" for generic SCIFB compatible UART. @@ -34,8 +42,8 @@ Required properties: - "renesas,sci" for generic SCI compatible UART. When compatible with the generic version, nodes must list the - SoC-specific version corresponding to the platform first followed by the - generic version. + SoC-specific version corresponding to the platform first, followed by the + family-specific and/or generic versions. - reg: Base address and length of the I/O registers used by the UART. - interrupts: Must contain an interrupt-specifier for the SCIx interrupt. @@ -58,7 +66,8 @@ Example: }; scifa0: serial@e6c40000 { - compatible = "renesas,scifa-r8a7790", "renesas,scifa"; + compatible = "renesas,scifa-r8a7790", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; interrupt-parent = <&gic>; interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; -- GitLab From 9a040c9f2170e0e6d092fc7cf8289a4466b8d8d6 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 12 Nov 2015 13:44:29 +0100 Subject: [PATCH 1401/2855] serial: sh-sci: Update DT binding documentation for external clock input Amend the DT bindings to include the optional external clock on (H)SCI(F) and some SCIFA, where this pin can serve as a clock input, depending on board wiring. Clarify the use of the divided functional clock as a source for the sampling clock. Signed-off-by: Geert Uytterhoeven Acked-by: Greg Kroah-Hartman --- .../devicetree/bindings/serial/renesas,sci-serial.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index 7091213f02513..31cc0631ef7ca 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -51,6 +51,11 @@ Required properties: - clocks: Must contain a phandle and clock-specifier pair for each entry in clock-names. - clock-names: Must contain "fck" for the SCIx UART functional clock. + Apart from the divided functional clock, there may be other possible + sources for the sampling clock, depending on SCIx variant. + On (H)SCI(F) and some SCIFA, an additional clock may be specified: + - "hsck" for the optional external clock input (on HSCIF), + - "sck" for the optional external clock input (on other variants). Note: Each enabled SCIx UART should have an alias correctly numbered in the "aliases" node. -- GitLab From 176ae5f674ebd2049f99e97eb8319200f1d211b6 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 26 Oct 2015 09:43:22 +0100 Subject: [PATCH 1402/2855] serial: sh-sci: Update DT binding documentation for BRG support Amend the DT bindings to include the optional clock sources for the Baud Rate Generator for External Clock (BRG), as found on some SCIF variants and on HSCIF. Signed-off-by: Geert Uytterhoeven Acked-by: Greg Kroah-Hartman --- .../devicetree/bindings/serial/renesas,sci-serial.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index 31cc0631ef7ca..f4ad30ef1628f 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -56,6 +56,12 @@ Required properties: On (H)SCI(F) and some SCIFA, an additional clock may be specified: - "hsck" for the optional external clock input (on HSCIF), - "sck" for the optional external clock input (on other variants). + On UARTs equipped with a Baud Rate Generator for External Clock (BRG) + (some SCIF and HSCIF), additional clocks may be specified: + - "brg_int" for the optional internal clock source for the frequency + divider (typically the (AXI or SHwy) bus clock), + - "scif_clk" for the optional external clock source for the frequency + divider (SCIF_CLK). Note: Each enabled SCIx UART should have an alias correctly numbered in the "aliases" node. -- GitLab From dcafbb47bdfde32b9f3c275aa4b435c120d02f15 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 3 Nov 2015 18:14:10 +0100 Subject: [PATCH 1403/2855] serial: sh-sci: Drop useless check for zero sampling_rate sci_port.sampling_rate is always non-zero, except for HSCIF, which uses sci_baud_calc_hscif() instead of sci_scbrr_calc(). Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index cc6fa55231ba3..dfee7a2f51f14 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1863,13 +1863,7 @@ static void sci_shutdown(struct uart_port *port) static unsigned int sci_scbrr_calc(struct sci_port *s, unsigned int bps, unsigned long freq) { - if (s->sampling_rate) - return DIV_ROUND_CLOSEST(freq, s->sampling_rate * bps) - 1; - - /* Warn, but use a safe default */ - WARN_ON(1); - - return ((freq + 16 * bps) / (32 * bps) - 1); + return DIV_ROUND_CLOSEST(freq, s->sampling_rate * bps) - 1; } /* calculate frame length from SMR */ -- GitLab From 2095fc76953aeec2a091d321426daca3534fca12 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 12 Nov 2015 13:39:49 +0100 Subject: [PATCH 1404/2855] serial: sh-sci: Grammar s/Get ... for/Get ... from/ Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index dfee7a2f51f14..5ec1a70cd2f49 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2645,7 +2645,7 @@ sci_parse_dt(struct platform_device *pdev, unsigned int *dev_id) if (!p) return NULL; - /* Get the line number for the aliases node. */ + /* Get the line number from the aliases node. */ id = of_alias_get_id(np, "serial"); if (id < 0) { dev_err(&pdev->dev, "failed to get alias id (%d)\n", id); -- GitLab From 495bb47c5dfe92bedce92fd5f3a3a0258d72ac36 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 10 Dec 2015 16:02:17 +0100 Subject: [PATCH 1405/2855] serial: sh-sci: Use existing local variable in sci_parse_dt() Signed-off-by: Geert Uytterhoeven --- drivers/tty/serial/sh-sci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 5ec1a70cd2f49..36077193f1116 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2635,7 +2635,7 @@ sci_parse_dt(struct platform_device *pdev, unsigned int *dev_id) if (!IS_ENABLED(CONFIG_OF) || !np) return NULL; - match = of_match_node(of_sci_match, pdev->dev.of_node); + match = of_match_node(of_sci_match, np); if (!match) return NULL; -- GitLab From bdcb3826976e60204cce52470c01bb9541e547b3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 13 Nov 2015 09:48:34 +0100 Subject: [PATCH 1406/2855] serial: sh-sci: Drop unused frame_len parameter for sci_baud_calc_hscif() As F is assumed to be zero in the receive margin formula, frame_len is not used. Remove it, together with the sci_baud_calc_frame_len() helper function. Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 36077193f1116..05ac15336e4f9 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1866,26 +1866,9 @@ static unsigned int sci_scbrr_calc(struct sci_port *s, unsigned int bps, return DIV_ROUND_CLOSEST(freq, s->sampling_rate * bps) - 1; } -/* calculate frame length from SMR */ -static int sci_baud_calc_frame_len(unsigned int smr_val) -{ - int len = 10; - - if (smr_val & SCSMR_CHR) - len--; - if (smr_val & SCSMR_PE) - len++; - if (smr_val & SCSMR_STOP) - len++; - - return len; -} - - /* calculate sample rate, BRR, and clock select for HSCIF */ -static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, - int *brr, unsigned int *srr, - unsigned int *cks, int frame_len) +static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, int *brr, + unsigned int *srr, unsigned int *cks) { int sr, c, br, err, recv_margin; int min_err = 1000; /* 100% */ @@ -1987,9 +1970,8 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, baud = uart_get_baud_rate(port, termios, old, 0, max_baud); if (likely(baud && port->uartclk)) { if (s->cfg->type == PORT_HSCIF) { - int frame_len = sci_baud_calc_frame_len(smr_val); sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, - &cks, frame_len); + &cks); } else { t = sci_scbrr_calc(s, baud, port->uartclk); for (cks = 0; t >= 256 && cks <= 3; cks++) -- GitLab From a67969b5fd366d488ffa1defd5256e8c3a87434d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 18 Nov 2015 16:20:44 +0100 Subject: [PATCH 1407/2855] serial: sh-sci: Don't overwrite clock selection in serial_console_write() Blindly writing the default configuration value into the SCSCR register may change the clock selection bits, breaking the serial console if the current driver settings differ from the default settings. Keep the current clock selection bits to prevent this from happening on e.g. r8a7791/koelsch when support for the BRG will be added. Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 05ac15336e4f9..136ad2f633413 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2420,7 +2420,7 @@ static void serial_console_write(struct console *co, const char *s, { struct sci_port *sci_port = &sci_ports[co->index]; struct uart_port *port = &sci_port->port; - unsigned short bits, ctrl; + unsigned short bits, ctrl, ctrl_temp; unsigned long flags; int locked = 1; @@ -2432,9 +2432,11 @@ static void serial_console_write(struct console *co, const char *s, else spin_lock(&port->lock); - /* first save the SCSCR then disable the interrupts */ + /* first save SCSCR then disable interrupts, keep clock source */ ctrl = serial_port_in(port, SCSCR); - serial_port_out(port, SCSCR, sci_port->cfg->scscr); + ctrl_temp = (sci_port->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0)) | + (ctrl & (SCSCR_CKE1 | SCSCR_CKE0)); + serial_port_out(port, SCSCR, ctrl_temp); uart_console_write(port, s, count, serial_console_putchar); -- GitLab From f4de472ef2ff8937b04d5da9d885c78fcbd4c171 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 26 Oct 2015 09:56:20 +0100 Subject: [PATCH 1408/2855] serial: sh-sci: Convert from clk_get() to devm_clk_get() Transfer clock cleanup handling to the core device management code. Signed-off-by: Geert Uytterhoeven Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 136ad2f633413..b9eb4b525c0a7 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2216,7 +2216,7 @@ static struct uart_ops sci_uart_ops = { static int sci_init_clocks(struct sci_port *sci_port, struct device *dev) { /* Get the SCI functional clock. It's called "fck" on ARM. */ - sci_port->fclk = clk_get(dev, "fck"); + sci_port->fclk = devm_clk_get(dev, "fck"); if (PTR_ERR(sci_port->fclk) == -EPROBE_DEFER) return -EPROBE_DEFER; if (!IS_ERR(sci_port->fclk)) @@ -2226,14 +2226,14 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev) * But it used to be called "sci_ick", and we need to maintain DT * backward compatibility. */ - sci_port->fclk = clk_get(dev, "sci_ick"); + sci_port->fclk = devm_clk_get(dev, "sci_ick"); if (PTR_ERR(sci_port->fclk) == -EPROBE_DEFER) return -EPROBE_DEFER; if (!IS_ERR(sci_port->fclk)) return 0; /* SH has historically named the clock "sci_fck". */ - sci_port->fclk = clk_get(dev, "sci_fck"); + sci_port->fclk = devm_clk_get(dev, "sci_fck"); if (!IS_ERR(sci_port->fclk)) return 0; @@ -2241,7 +2241,7 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev) * Not all SH platforms declare a clock lookup entry for SCI devices, * in which case we need to get the global "peripheral_clk" clock. */ - sci_port->fclk = clk_get(dev, "peripheral_clk"); + sci_port->fclk = devm_clk_get(dev, "peripheral_clk"); if (!IS_ERR(sci_port->fclk)) return 0; @@ -2400,8 +2400,6 @@ static int sci_init_single(struct platform_device *dev, static void sci_cleanup_single(struct sci_port *port) { - clk_put(port->fclk); - pm_runtime_disable(port->port.dev); } -- GitLab From 95a2703e36530c09a9416321ec21c062f3e91d01 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 13 Nov 2015 16:56:08 +0100 Subject: [PATCH 1409/2855] serial: sh-sci: Make unsigned values in sci_baud_calc_hscif() unsigned Move the -1 offset of br to the assignment to *brr, so br cannot become negative anymore, and update the clamp() call. Now all unsigned values in sci_baud_calc_hscif() can become unsigned. Signed-off-by: Geert Uytterhoeven Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index b9eb4b525c0a7..77e0a582da449 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1870,7 +1870,8 @@ static unsigned int sci_scbrr_calc(struct sci_port *s, unsigned int bps, static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, int *brr, unsigned int *srr, unsigned int *cks) { - int sr, c, br, err, recv_margin; + unsigned int sr, br, c; + int err, recv_margin; int min_err = 1000; /* 100% */ int recv_max_margin = 0; @@ -1880,9 +1881,9 @@ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, int *brr, for (c = 0; c <= 3; c++) { /* integerized formulas from HSCIF documentation */ br = DIV_ROUND_CLOSEST(freq, (sr * - (1 << (2 * c + 1)) * bps)) - 1; - br = clamp(br, 0, 255); - err = DIV_ROUND_CLOSEST(freq, ((br + 1) * bps * sr * + (1 << (2 * c + 1)) * bps)); + br = clamp(br, 1U, 256U); + err = DIV_ROUND_CLOSEST(freq, (br * bps * sr * (1 << (2 * c + 1)) / 1000)) - 1000; /* Calc recv margin @@ -1908,7 +1909,7 @@ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, int *brr, else continue; - *brr = br; + *brr = br - 1; *srr = sr - 1; *cks = c; } -- GitLab From de01e6cd0b100bac088b1d59a7040ebe2af64f1c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 13 Nov 2015 17:04:56 +0100 Subject: [PATCH 1410/2855] serial: sh-sci: Avoid overflow in sci_baud_calc_hscif() If bps >= 1048576, the multiplication of the predivider and "bps" will overflow, and both br and err will contain bogus values. Skip the current and all higher clock select predividers when overflow is detected. Simplify the calculations using intermediates while we're at it. Signed-off-by: Geert Uytterhoeven Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 77e0a582da449..c490c51d60327 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1870,7 +1870,7 @@ static unsigned int sci_scbrr_calc(struct sci_port *s, unsigned int bps, static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, int *brr, unsigned int *srr, unsigned int *cks) { - unsigned int sr, br, c; + unsigned int sr, br, prediv, scrate, c; int err, recv_margin; int min_err = 1000; /* 100% */ int recv_max_margin = 0; @@ -1880,12 +1880,25 @@ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, int *brr, for (sr = 8; sr <= 32; sr++) { for (c = 0; c <= 3; c++) { /* integerized formulas from HSCIF documentation */ - br = DIV_ROUND_CLOSEST(freq, (sr * - (1 << (2 * c + 1)) * bps)); + prediv = sr * (1 << (2 * c + 1)); + + /* + * We need to calculate: + * + * br = freq / (prediv * bps) clamped to [1..256] + * err = (freq / (br * prediv * bps / 1000)) - 1000 + * + * Watch out for overflow when calculating the desired + * sampling clock rate! + */ + if (bps > UINT_MAX / prediv) + break; + + scrate = prediv * bps; + br = DIV_ROUND_CLOSEST(freq, scrate); br = clamp(br, 1U, 256U); - err = DIV_ROUND_CLOSEST(freq, (br * bps * sr * - (1 << (2 * c + 1)) / 1000)) - - 1000; + err = DIV_ROUND_CLOSEST(freq, (br * scrate) / 1000) - + 1000; /* Calc recv margin * M: Receive margin (%) * N: Ratio of bit rate to clock (N = sampling rate) -- GitLab From 881a7489f463e59a44417ad89ecb4ea21b2b86cd Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 16 Nov 2015 15:54:47 +0100 Subject: [PATCH 1411/2855] serial: sh-sci: Improve bit rate error calculation for HSCIF The algorithm to find the best parameters for the requested bit rate calculates the relative bit rate error, using "(br * scrate) / 1000". For small "br * scrate", this has two problems: - The quotient may be zero, leading to a division by zero error, - This may introduce a large rounding error. Switch from relative to absolute bit rate error calculation to fix this. The default baud rate generator values can be removed, as there will always be one set of values that gives the smallest absolute error. Print the best set of values when debugging. Signed-off-by: Geert Uytterhoeven Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index c490c51d60327..306497ee5c326 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1867,12 +1867,13 @@ static unsigned int sci_scbrr_calc(struct sci_port *s, unsigned int bps, } /* calculate sample rate, BRR, and clock select for HSCIF */ -static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, int *brr, +static void sci_baud_calc_hscif(struct sci_port *s, unsigned int bps, + unsigned long freq, int *brr, unsigned int *srr, unsigned int *cks) { unsigned int sr, br, prediv, scrate, c; int err, recv_margin; - int min_err = 1000; /* 100% */ + int min_err = INT_MAX; int recv_max_margin = 0; /* Find the combination of sample rate and clock select with the @@ -1886,7 +1887,7 @@ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, int *brr, * We need to calculate: * * br = freq / (prediv * bps) clamped to [1..256] - * err = (freq / (br * prediv * bps / 1000)) - 1000 + * err = freq / (br * prediv) - bps * * Watch out for overflow when calculating the desired * sampling clock rate! @@ -1897,8 +1898,7 @@ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, int *brr, scrate = prediv * bps; br = DIV_ROUND_CLOSEST(freq, scrate); br = clamp(br, 1U, 256U); - err = DIV_ROUND_CLOSEST(freq, (br * scrate) / 1000) - - 1000; + err = DIV_ROUND_CLOSEST(freq, br * prediv) - bps; /* Calc recv margin * M: Receive margin (%) * N: Ratio of bit rate to clock (N = sampling rate) @@ -1928,13 +1928,8 @@ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, int *brr, } } - if (min_err == 1000) { - WARN_ON(1); - /* use defaults */ - *brr = 255; - *srr = 15; - *cks = 0; - } + dev_dbg(s->port.dev, "BRR: %u%+d bps using N %u SR %u cks %u\n", bps, + min_err, *brr, *srr + 1, *cks); } static void sci_reset(struct uart_port *port) @@ -1984,7 +1979,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, baud = uart_get_baud_rate(port, termios, old, 0, max_baud); if (likely(baud && port->uartclk)) { if (s->cfg->type == PORT_HSCIF) { - sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, + sci_baud_calc_hscif(s, baud, port->uartclk, &t, &srr, &cks); } else { t = sci_scbrr_calc(s, baud, port->uartclk); -- GitLab From 6c51332dfc23fc7c2c58244e35d36744db202077 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 16 Nov 2015 16:33:22 +0100 Subject: [PATCH 1412/2855] serial: sh-sci: Avoid calculating the receive margin for HSCIF When assuming D = 0.5 and F = 0, maximizing the receive margin M is equivalent to maximizing the sample rate N. Hence there's no need to calculate the receive margin, as we can obtain the same result by iterating over all possible sample rates in reverse order, and skipping parameter sets that don't provide a lower bit rate error. Signed-off-by: Geert Uytterhoeven Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 51 +++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 306497ee5c326..c3a193616484a 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1872,13 +1872,24 @@ static void sci_baud_calc_hscif(struct sci_port *s, unsigned int bps, unsigned int *srr, unsigned int *cks) { unsigned int sr, br, prediv, scrate, c; - int err, recv_margin; - int min_err = INT_MAX; - int recv_max_margin = 0; + int err, min_err = INT_MAX; - /* Find the combination of sample rate and clock select with the - smallest deviation from the desired baud rate. */ - for (sr = 8; sr <= 32; sr++) { + /* + * Find the combination of sample rate and clock select with the + * smallest deviation from the desired baud rate. + * Prefer high sample rates to maximise the receive margin. + * + * M: Receive margin (%) + * N: Ratio of bit rate to clock (N = sampling rate) + * D: Clock duty (D = 0 to 1.0) + * L: Frame length (L = 9 to 12) + * F: Absolute value of clock frequency deviation + * + * M = |(0.5 - 1 / 2 * N) - ((L - 0.5) * F) - + * (|D - 0.5| / N * (1 + F))| + * NOTE: Usually, treat D for 0.5, F is 0 by this calculation. + */ + for (sr = 32; sr >= 8; sr--) { for (c = 0; c <= 3; c++) { /* integerized formulas from HSCIF documentation */ prediv = sr * (1 << (2 * c + 1)); @@ -1898,36 +1909,22 @@ static void sci_baud_calc_hscif(struct sci_port *s, unsigned int bps, scrate = prediv * bps; br = DIV_ROUND_CLOSEST(freq, scrate); br = clamp(br, 1U, 256U); + err = DIV_ROUND_CLOSEST(freq, br * prediv) - bps; - /* Calc recv margin - * M: Receive margin (%) - * N: Ratio of bit rate to clock (N = sampling rate) - * D: Clock duty (D = 0 to 1.0) - * L: Frame length (L = 9 to 12) - * F: Absolute value of clock frequency deviation - * - * M = |(0.5 - 1 / 2 * N) - ((L - 0.5) * F) - - * (|D - 0.5| / N * (1 + F))| - * NOTE: Usually, treat D for 0.5, F is 0 by this - * calculation. - */ - recv_margin = abs((500 - - DIV_ROUND_CLOSEST(1000, sr << 1)) / 10); - if (abs(min_err) > abs(err)) { - min_err = err; - recv_max_margin = recv_margin; - } else if ((min_err == err) && - (recv_margin > recv_max_margin)) - recv_max_margin = recv_margin; - else + if (abs(err) >= abs(min_err)) continue; + min_err = err; *brr = br - 1; *srr = sr - 1; *cks = c; + + if (!err) + goto found; } } +found: dev_dbg(s->port.dev, "BRR: %u%+d bps using N %u SR %u cks %u\n", bps, min_err, *brr, *srr + 1, *cks); } -- GitLab From b4a5c459088b724734573a550c9da42a9a19c9d0 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 16 Nov 2015 17:22:16 +0100 Subject: [PATCH 1413/2855] serial: sh-sci: Merge sci_scbrr_calc() and sci_baud_calc_hscif() For low bit rates, the for-loop that reduces the divider returned by sci_scbrr_calc() and picks the clock select value may terminate without finding suitable values, leading to out-of-range divider and clock select values. sci_baud_calc_hscif() doesn't suffer from this problem, as it correctly uses clamp(). Since there are only two relevant differences between HSCIF and other variants w.r.t. bit rate configuration (fixed vs. variable sample rate, and an additional factor of two), sci_scbrr_calc() and sci_baud_calc_hscif() can be merged, fixing the issue with out-of-range values. Signed-off-by: Geert Uytterhoeven Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 42 +++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index c3a193616484a..d89d4b7576cf3 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1860,20 +1860,24 @@ static void sci_shutdown(struct uart_port *port) sci_free_irq(s); } -static unsigned int sci_scbrr_calc(struct sci_port *s, unsigned int bps, - unsigned long freq) +/* calculate sample rate, BRR, and clock select */ +static void sci_scbrr_calc(struct sci_port *s, unsigned int bps, + unsigned long freq, int *brr, unsigned int *srr, + unsigned int *cks) { - return DIV_ROUND_CLOSEST(freq, s->sampling_rate * bps) - 1; -} - -/* calculate sample rate, BRR, and clock select for HSCIF */ -static void sci_baud_calc_hscif(struct sci_port *s, unsigned int bps, - unsigned long freq, int *brr, - unsigned int *srr, unsigned int *cks) -{ - unsigned int sr, br, prediv, scrate, c; + unsigned int min_sr, max_sr, shift, sr, br, prediv, scrate, c; int err, min_err = INT_MAX; + if (s->sampling_rate) { + min_sr = max_sr = s->sampling_rate; + shift = 0; + } else { + /* HSCIF has a variable sample rate */ + min_sr = 8; + max_sr = 32; + shift = 1; + } + /* * Find the combination of sample rate and clock select with the * smallest deviation from the desired baud rate. @@ -1889,10 +1893,10 @@ static void sci_baud_calc_hscif(struct sci_port *s, unsigned int bps, * (|D - 0.5| / N * (1 + F))| * NOTE: Usually, treat D for 0.5, F is 0 by this calculation. */ - for (sr = 32; sr >= 8; sr--) { + for (sr = max_sr; sr >= min_sr; sr--) { for (c = 0; c <= 3; c++) { /* integerized formulas from HSCIF documentation */ - prediv = sr * (1 << (2 * c + 1)); + prediv = sr * (1 << (2 * c + shift)); /* * We need to calculate: @@ -1974,16 +1978,8 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, max_baud = port->uartclk ? port->uartclk / 16 : 115200; baud = uart_get_baud_rate(port, termios, old, 0, max_baud); - if (likely(baud && port->uartclk)) { - if (s->cfg->type == PORT_HSCIF) { - sci_baud_calc_hscif(s, baud, port->uartclk, &t, &srr, - &cks); - } else { - t = sci_scbrr_calc(s, baud, port->uartclk); - for (cks = 0; t >= 256 && cks <= 3; cks++) - t >>= 2; - } - } + if (likely(baud && port->uartclk)) + sci_scbrr_calc(s, baud, port->uartclk, &t, &srr, &cks); sci_port_enable(s); -- GitLab From ff8b275f1f0927621cf543c2a6f02761052c360d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 19 Nov 2015 14:35:09 +0100 Subject: [PATCH 1414/2855] serial: sh-sci: Take into account sampling rate for max baud rate The maximum baud rate depends on the sampling rate. HSCIF has a variable sampling rate and sets s->sampling_rate to zero, hence use the minimum sampling rate of 8. Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index d89d4b7576cf3..5b120757c02a5 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1975,7 +1975,10 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, * that the previous boot loader has enabled required clocks and * setup the baud rate generator hardware for us already. */ - max_baud = port->uartclk ? port->uartclk / 16 : 115200; + if (port->uartclk) + max_baud = port->uartclk / max(s->sampling_rate, 8U); + else + max_baud = 115200; baud = uart_get_baud_rate(port, termios, old, 0, max_baud); if (likely(baud && port->uartclk)) -- GitLab From b8bbd6b2923279f1c9c74d59638b38a1eace78e8 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 12 Nov 2015 13:36:06 +0100 Subject: [PATCH 1415/2855] serial: sh-sci: Add BRG register definitions Add register definitions for the Baud Rate Generator for External Clock (BRG), as found in some SCIF and in HSCIF, including a new regtype for the "SH-4(A)"-derived SCIF variant with BRG. Signed-off-by: Geert Uytterhoeven Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 46 +++++++++++++++++++++++++++++++++++++ drivers/tty/serial/sh-sci.h | 10 ++++++++ include/linux/serial_sci.h | 1 + 3 files changed, 57 insertions(+) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 5b120757c02a5..fb5eac2e31823 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -161,6 +161,8 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [HSSRR] = sci_reg_invalid, [SCPCR] = sci_reg_invalid, [SCPDR] = sci_reg_invalid, + [SCDL] = sci_reg_invalid, + [SCCKS] = sci_reg_invalid, }, /* @@ -183,6 +185,8 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [HSSRR] = sci_reg_invalid, [SCPCR] = sci_reg_invalid, [SCPDR] = sci_reg_invalid, + [SCDL] = sci_reg_invalid, + [SCCKS] = sci_reg_invalid, }, /* @@ -204,6 +208,8 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [HSSRR] = sci_reg_invalid, [SCPCR] = { 0x30, 16 }, [SCPDR] = { 0x34, 16 }, + [SCDL] = sci_reg_invalid, + [SCCKS] = sci_reg_invalid, }, /* @@ -225,6 +231,8 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [HSSRR] = sci_reg_invalid, [SCPCR] = { 0x30, 16 }, [SCPDR] = { 0x34, 16 }, + [SCDL] = sci_reg_invalid, + [SCCKS] = sci_reg_invalid, }, /* @@ -247,6 +255,8 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [HSSRR] = sci_reg_invalid, [SCPCR] = sci_reg_invalid, [SCPDR] = sci_reg_invalid, + [SCDL] = sci_reg_invalid, + [SCCKS] = sci_reg_invalid, }, /* @@ -268,6 +278,8 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [HSSRR] = sci_reg_invalid, [SCPCR] = sci_reg_invalid, [SCPDR] = sci_reg_invalid, + [SCDL] = sci_reg_invalid, + [SCCKS] = sci_reg_invalid, }, /* @@ -289,6 +301,32 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [HSSRR] = sci_reg_invalid, [SCPCR] = sci_reg_invalid, [SCPDR] = sci_reg_invalid, + [SCDL] = sci_reg_invalid, + [SCCKS] = sci_reg_invalid, + }, + + /* + * Common SCIF definitions for ports with a Baud Rate Generator for + * External Clock (BRG). + */ + [SCIx_SH4_SCIF_BRG_REGTYPE] = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x0c, 8 }, + [SCxSR] = { 0x10, 16 }, + [SCxRDR] = { 0x14, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCTFDR] = sci_reg_invalid, + [SCRFDR] = sci_reg_invalid, + [SCSPTR] = { 0x20, 16 }, + [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, + [SCPCR] = sci_reg_invalid, + [SCPDR] = sci_reg_invalid, + [SCDL] = { 0x30, 16 }, + [SCCKS] = { 0x34, 16 }, }, /* @@ -310,6 +348,8 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [HSSRR] = { 0x40, 16 }, [SCPCR] = sci_reg_invalid, [SCPDR] = sci_reg_invalid, + [SCDL] = { 0x30, 16 }, + [SCCKS] = { 0x34, 16 }, }, /* @@ -332,6 +372,8 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [HSSRR] = sci_reg_invalid, [SCPCR] = sci_reg_invalid, [SCPDR] = sci_reg_invalid, + [SCDL] = sci_reg_invalid, + [SCCKS] = sci_reg_invalid, }, /* @@ -354,6 +396,8 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [HSSRR] = sci_reg_invalid, [SCPCR] = sci_reg_invalid, [SCPDR] = sci_reg_invalid, + [SCDL] = sci_reg_invalid, + [SCCKS] = sci_reg_invalid, }, /* @@ -376,6 +420,8 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [HSSRR] = sci_reg_invalid, [SCPCR] = sci_reg_invalid, [SCPDR] = sci_reg_invalid, + [SCDL] = sci_reg_invalid, + [SCCKS] = sci_reg_invalid, }, }; diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index bf69bbdcc1f9a..fb17602504218 100644 --- a/drivers/tty/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h @@ -27,6 +27,8 @@ enum { HSSRR, /* Sampling Rate Register */ SCPCR, /* Serial Port Control Register */ SCPDR, /* Serial Port Data Register */ + SCDL, /* BRG Frequency Division Register */ + SCCKS, /* BRG Clock Select Register */ SCIx_NR_REGS, }; @@ -109,6 +111,14 @@ enum { #define SCPDR_RTSD BIT(4) /* Serial Port RTS Output Pin Data */ #define SCPDR_CTSD BIT(3) /* Serial Port CTS Input Pin Data */ +/* + * BRG Clock Select Register (Some SCIF and HSCIF) + * The Baud Rate Generator for external clock can provide a clock source for + * the sampling clock. It outputs either its frequency divided clock, or the + * (undivided) (H)SCK external clock. + */ +#define SCCKS_CKS BIT(15) /* Select (H)SCK (1) or divided SC_CLK (0) */ +#define SCCKS_XIN BIT(14) /* SC_CLK uses bus clock (1) or SCIF_CLK (0) */ #define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND) #define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF) diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index 7c536ac5be05d..9f2bfd0557429 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -32,6 +32,7 @@ enum { SCIx_SH2_SCIF_FIFODATA_REGTYPE, SCIx_SH3_SCIF_REGTYPE, SCIx_SH4_SCIF_REGTYPE, + SCIx_SH4_SCIF_BRG_REGTYPE, SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, SCIx_SH4_SCIF_FIFODATA_REGTYPE, SCIx_SH7705_SCIF_REGTYPE, -- GitLab From bd2238fb84df6054d966364d07e0414b54ef8e19 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 10 Nov 2015 16:09:23 +0100 Subject: [PATCH 1416/2855] serial: sh-sci: Replace struct sci_port_info by type/regtype encoding Store the encoded port and register types directly in of_device_id.data, instead of using a pointer to a structure. This saves memory and simplifies the source code, especially when adding more compatible entries later. Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 40 ++++++++++--------------------------- 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index fb5eac2e31823..13c6abe9d842c 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2614,42 +2614,27 @@ static int sci_remove(struct platform_device *dev) return 0; } -struct sci_port_info { - unsigned int type; - unsigned int regtype; -}; + +#define SCI_OF_DATA(type, regtype) (void *)((type) << 16 | (regtype)) +#define SCI_OF_TYPE(data) ((unsigned long)(data) >> 16) +#define SCI_OF_REGTYPE(data) ((unsigned long)(data) & 0xffff) static const struct of_device_id of_sci_match[] = { { .compatible = "renesas,scif", - .data = &(const struct sci_port_info) { - .type = PORT_SCIF, - .regtype = SCIx_SH4_SCIF_REGTYPE, - }, + .data = SCI_OF_DATA(PORT_SCIF, SCIx_SH4_SCIF_REGTYPE), }, { .compatible = "renesas,scifa", - .data = &(const struct sci_port_info) { - .type = PORT_SCIFA, - .regtype = SCIx_SCIFA_REGTYPE, - }, + .data = SCI_OF_DATA(PORT_SCIFA, SCIx_SCIFA_REGTYPE), }, { .compatible = "renesas,scifb", - .data = &(const struct sci_port_info) { - .type = PORT_SCIFB, - .regtype = SCIx_SCIFB_REGTYPE, - }, + .data = SCI_OF_DATA(PORT_SCIFB, SCIx_SCIFB_REGTYPE), }, { .compatible = "renesas,hscif", - .data = &(const struct sci_port_info) { - .type = PORT_HSCIF, - .regtype = SCIx_HSCIF_REGTYPE, - }, + .data = SCI_OF_DATA(PORT_HSCIF, SCIx_HSCIF_REGTYPE), }, { .compatible = "renesas,sci", - .data = &(const struct sci_port_info) { - .type = PORT_SCI, - .regtype = SCIx_SCI_REGTYPE, - }, + .data = SCI_OF_DATA(PORT_SCI, SCIx_SCI_REGTYPE), }, { /* Terminator */ }, @@ -2661,7 +2646,6 @@ sci_parse_dt(struct platform_device *pdev, unsigned int *dev_id) { struct device_node *np = pdev->dev.of_node; const struct of_device_id *match; - const struct sci_port_info *info; struct plat_sci_port *p; int id; @@ -2672,8 +2656,6 @@ sci_parse_dt(struct platform_device *pdev, unsigned int *dev_id) if (!match) return NULL; - info = match->data; - p = devm_kzalloc(&pdev->dev, sizeof(struct plat_sci_port), GFP_KERNEL); if (!p) return NULL; @@ -2688,8 +2670,8 @@ sci_parse_dt(struct platform_device *pdev, unsigned int *dev_id) *dev_id = id; p->flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; - p->type = info->type; - p->regtype = info->regtype; + p->type = SCI_OF_TYPE(match->data); + p->regtype = SCI_OF_REGTYPE(match->data); p->scscr = SCSCR_RE | SCSCR_TE; return p; -- GitLab From f443ff80d02d74be6c3930e325a6573eb06347ea Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 10 Nov 2015 16:16:54 +0100 Subject: [PATCH 1417/2855] serial: sh-sci: Correct SCIF type on RZ/A1H The "renesas,scif" compatible value is currently used for the SCIF variant in all Renesas SoCs of the R-Car and RZ families. However, the variant used in the RZ family is not the common "SH-4(A)" variant, but the "SH-2(A) with FIFO data count register" variant, as it has the "Serial Extension Mode Register" (SCEMR), just like on sh7203, sh7263, sh7264, and sh7269. Use the (already documented) SoC-specific "renesas,scif-r7s72100" compatible value to differentiate. The "renesas,scif" compatible value can still be used as a common denominator for SCIF variants with the "SH-4(A)" register layout (i.e. ignoring the SCEMR register). Note that currently both variants are treated the same, but this may change if support for the SCEMR register is ever added. Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 13c6abe9d842c..5b8504bfd42e9 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2620,6 +2620,12 @@ static int sci_remove(struct platform_device *dev) #define SCI_OF_REGTYPE(data) ((unsigned long)(data) & 0xffff) static const struct of_device_id of_sci_match[] = { + /* SoC-specific types */ + { + .compatible = "renesas,scif-r7s72100", + .data = SCI_OF_DATA(PORT_SCIF, SCIx_SH2_SCIF_FIFODATA_REGTYPE), + }, + /* Generic types */ { .compatible = "renesas,scif", .data = SCI_OF_DATA(PORT_SCIF, SCIx_SH4_SCIF_REGTYPE), -- GitLab From 9ed44bb209d0ece90abb6b4279d8b18e17680476 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 10 Nov 2015 18:57:23 +0100 Subject: [PATCH 1418/2855] serial: sh-sci: Correct SCIF type on R-Car for BRG The "renesas,scif" compatible value is currently used for the SCIF variant in all Renesas SoCs of the R-Car family. However, the variant used in the R-Car family is not the common "SH-4(A)" variant, but a derivative with added "Baud Rate Generator for External Clock" (BRG), which is also present in sh7734. Use the family-specific SCIF compatible values for R-Car Gen1, Gen2, and Gen3 SoCs to differentiate. The "renesas,scif" compatible value can still be used as a common denominator for SCIF variants with the "SH-4(A)" register layout (i.e. ignoring the "Serial Extension Mode Register" (SCEMR) and the new BRG-specific registers). Signed-off-by: Geert Uytterhoeven Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 5b8504bfd42e9..a202e4e40b8ad 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2625,6 +2625,17 @@ static const struct of_device_id of_sci_match[] = { .compatible = "renesas,scif-r7s72100", .data = SCI_OF_DATA(PORT_SCIF, SCIx_SH2_SCIF_FIFODATA_REGTYPE), }, + /* Family-specific types */ + { + .compatible = "renesas,rcar-gen1-scif", + .data = SCI_OF_DATA(PORT_SCIF, SCIx_SH4_SCIF_BRG_REGTYPE), + }, { + .compatible = "renesas,rcar-gen2-scif", + .data = SCI_OF_DATA(PORT_SCIF, SCIx_SH4_SCIF_BRG_REGTYPE), + }, { + .compatible = "renesas,rcar-gen3-scif", + .data = SCI_OF_DATA(PORT_SCIF, SCIx_SH4_SCIF_BRG_REGTYPE), + }, /* Generic types */ { .compatible = "renesas,scif", -- GitLab From f4998e55b8987428aa86de02c934fb6e0988d9a3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 26 Oct 2015 09:58:16 +0100 Subject: [PATCH 1419/2855] serial: sh-sci: Prepare for multiple sampling clock sources Refactor the clock and baud rate parameter code to ease adding support for multiple sampling clock sources. sci_scbrr_calc() now returns the bit rate error, so it can be compared to the bit rate error using other sampling clock sources. Signed-off-by: Geert Uytterhoeven Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 194 +++++++++++++++++++++++++----------- 1 file changed, 134 insertions(+), 60 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index a202e4e40b8ad..fa3fd876105b2 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2,6 +2,7 @@ * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO) * * Copyright (C) 2002 - 2011 Paul Mundt + * Copyright (C) 2015 Glider bvba * Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Jul 2007). * * based off of the old drivers/char/sh-sci.c by: @@ -76,6 +77,11 @@ enum { ((port)->irqs[SCIx_ERI_IRQ] && \ ((port)->irqs[SCIx_RXI_IRQ] < 0)) +enum SCI_CLKS { + SCI_FCK, /* Functional Clock */ + SCI_NUM_CLKS +}; + struct sci_port { struct uart_port port; @@ -92,8 +98,9 @@ struct sci_port { struct timer_list break_timer; int break_flag; - /* Function clock */ - struct clk *fclk; + /* Clocks */ + struct clk *clks[SCI_NUM_CLKS]; + unsigned long clk_rates[SCI_NUM_CLKS]; int irqs[SCIx_NR_IRQS]; char *irqstr[SCIx_NR_IRQS]; @@ -496,17 +503,24 @@ static int sci_probe_regmap(struct plat_sci_port *cfg) static void sci_port_enable(struct sci_port *sci_port) { + unsigned int i; + if (!sci_port->port.dev) return; pm_runtime_get_sync(sci_port->port.dev); - clk_prepare_enable(sci_port->fclk); - sci_port->port.uartclk = clk_get_rate(sci_port->fclk); + for (i = 0; i < SCI_NUM_CLKS; i++) { + clk_prepare_enable(sci_port->clks[i]); + sci_port->clk_rates[i] = clk_get_rate(sci_port->clks[i]); + } + sci_port->port.uartclk = sci_port->clk_rates[SCI_FCK]; } static void sci_port_disable(struct sci_port *sci_port) { + unsigned int i; + if (!sci_port->port.dev) return; @@ -518,7 +532,8 @@ static void sci_port_disable(struct sci_port *sci_port) del_timer_sync(&sci_port->break_timer); sci_port->break_flag = 0; - clk_disable_unprepare(sci_port->fclk); + for (i = SCI_NUM_CLKS; i-- > 0; ) + clk_disable_unprepare(sci_port->clks[i]); pm_runtime_put_sync(sci_port->port.dev); } @@ -1657,6 +1672,7 @@ static int sci_notifier(struct notifier_block *self, { struct sci_port *sci_port; unsigned long flags; + unsigned int i; sci_port = container_of(self, struct sci_port, freq_transition); @@ -1664,7 +1680,9 @@ static int sci_notifier(struct notifier_block *self, struct uart_port *port = &sci_port->port; spin_lock_irqsave(&port->lock, flags); - port->uartclk = clk_get_rate(sci_port->fclk); + for (i = 0; i < SCI_NUM_CLKS; i++) + sci_port->clk_rates[i] = + clk_get_rate(sci_port->clks[i]); spin_unlock_irqrestore(&port->lock, flags); } @@ -1907,11 +1925,12 @@ static void sci_shutdown(struct uart_port *port) } /* calculate sample rate, BRR, and clock select */ -static void sci_scbrr_calc(struct sci_port *s, unsigned int bps, - unsigned long freq, int *brr, unsigned int *srr, - unsigned int *cks) +static int sci_scbrr_calc(struct sci_port *s, unsigned int bps, + unsigned int *brr, unsigned int *srr, + unsigned int *cks) { unsigned int min_sr, max_sr, shift, sr, br, prediv, scrate, c; + unsigned long freq = s->clk_rates[SCI_FCK]; int err, min_err = INT_MAX; if (s->sampling_rate) { @@ -1977,6 +1996,7 @@ static void sci_scbrr_calc(struct sci_port *s, unsigned int bps, found: dev_dbg(s->port.dev, "BRR: %u%+d bps using N %u SR %u cks %u\n", bps, min_err, *brr, *srr + 1, *cks); + return min_err; } static void sci_reset(struct uart_port *port) @@ -1998,11 +2018,14 @@ static void sci_reset(struct uart_port *port) static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { + unsigned int baud, smr_val = 0, scr_val = 0, i; + unsigned int brr = 255, cks = 0, srr = 15; + unsigned int brr1 = 255, cks1 = 0, srr1 = 15; struct sci_port *s = to_sci_port(port); const struct plat_sci_reg *reg; - unsigned int baud, smr_val = 0, max_baud, cks = 0; - int t = -1; - unsigned int srr = 15; + int min_err = INT_MAX, err; + unsigned long max_freq = 0; + int best_clk = -1; if ((termios->c_cflag & CSIZE) == CS7) smr_val |= SCSMR_CHR; @@ -2021,35 +2044,64 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, * that the previous boot loader has enabled required clocks and * setup the baud rate generator hardware for us already. */ - if (port->uartclk) - max_baud = port->uartclk / max(s->sampling_rate, 8U); - else - max_baud = 115200; + if (!port->uartclk) { + baud = uart_get_baud_rate(port, termios, old, 0, 115200); + goto done; + } - baud = uart_get_baud_rate(port, termios, old, 0, max_baud); - if (likely(baud && port->uartclk)) - sci_scbrr_calc(s, baud, port->uartclk, &t, &srr, &cks); + for (i = 0; i < SCI_NUM_CLKS; i++) + max_freq = max(max_freq, s->clk_rates[i]); + + baud = uart_get_baud_rate(port, termios, old, 0, + max_freq / max(s->sampling_rate, 8U)); + if (!baud) + goto done; + + /* + * There can be multiple sources for the sampling clock. Find the one + * that gives us the smallest deviation from the desired baud rate. + */ + + /* Divided Functional Clock using standard Bit Rate Register */ + err = sci_scbrr_calc(s, baud, &brr1, &srr1, &cks1); + if (abs(err) < abs(min_err)) { + best_clk = SCI_FCK; + min_err = err; + brr = brr1; + srr = srr1; + cks = cks1; + } + +done: + if (best_clk >= 0) + dev_dbg(port->dev, "Using clk %pC for %u%+d bps\n", + s->clks[best_clk], baud, min_err); sci_port_enable(s); sci_reset(port); - smr_val |= serial_port_in(port, SCSMR) & SCSMR_CKS; - uart_update_timeout(port, termios->c_cflag, baud); - dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n", - __func__, smr_val, cks, t, s->cfg->scscr); - - if (t >= 0) { - serial_port_out(port, SCSMR, (smr_val & ~SCSMR_CKS) | cks); - serial_port_out(port, SCBRR, t); - reg = sci_getreg(port, HSSRR); - if (reg->size) + if (best_clk >= 0) { + smr_val |= cks; + dev_dbg(port->dev, "SMR 0x%x BRR %u SRR %u\n", smr_val, brr, + srr); + serial_port_out(port, SCSMR, smr_val); + serial_port_out(port, SCBRR, brr); + if (sci_getreg(port, HSSRR)->size) serial_port_out(port, HSSRR, srr | HSCIF_SRE); - udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ - } else + + /* Wait one bit interval */ + udelay((1000000 + (baud - 1)) / baud); + } else { + /* Don't touch the bit rate configuration */ + scr_val = s->cfg->scscr & (SCSCR_CKE1 | SCSCR_CKE0); + smr_val |= serial_port_in(port, SCSMR) & SCSMR_CKS; + dev_dbg(port->dev, "SCR 0x%x SMR 0x%x\n", scr_val, smr_val); + serial_port_out(port, SCSCR, scr_val); serial_port_out(port, SCSMR, smr_val); + } sci_init_pins(port, termios->c_cflag); @@ -2074,7 +2126,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, serial_port_out(port, SCFCR, ctrl); } - serial_port_out(port, SCSCR, s->cfg->scscr); + scr_val |= s->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0); + dev_dbg(port->dev, "SCSCR 0x%x\n", scr_val); + serial_port_out(port, SCSCR, scr_val); #ifdef CONFIG_SERIAL_SH_SCI_DMA /* @@ -2266,38 +2320,58 @@ static struct uart_ops sci_uart_ops = { static int sci_init_clocks(struct sci_port *sci_port, struct device *dev) { - /* Get the SCI functional clock. It's called "fck" on ARM. */ - sci_port->fclk = devm_clk_get(dev, "fck"); - if (PTR_ERR(sci_port->fclk) == -EPROBE_DEFER) - return -EPROBE_DEFER; - if (!IS_ERR(sci_port->fclk)) - return 0; + const char *clk_names[] = { + [SCI_FCK] = "fck", + }; + struct clk *clk; + unsigned int i; - /* - * But it used to be called "sci_ick", and we need to maintain DT - * backward compatibility. - */ - sci_port->fclk = devm_clk_get(dev, "sci_ick"); - if (PTR_ERR(sci_port->fclk) == -EPROBE_DEFER) - return -EPROBE_DEFER; - if (!IS_ERR(sci_port->fclk)) - return 0; + for (i = 0; i < SCI_NUM_CLKS; i++) { + clk = devm_clk_get(dev, clk_names[i]); + if (PTR_ERR(clk) == -EPROBE_DEFER) + return -EPROBE_DEFER; - /* SH has historically named the clock "sci_fck". */ - sci_port->fclk = devm_clk_get(dev, "sci_fck"); - if (!IS_ERR(sci_port->fclk)) - return 0; + if (IS_ERR(clk) && i == SCI_FCK) { + /* + * "fck" used to be called "sci_ick", and we need to + * maintain DT backward compatibility. + */ + clk = devm_clk_get(dev, "sci_ick"); + if (PTR_ERR(clk) == -EPROBE_DEFER) + return -EPROBE_DEFER; - /* - * Not all SH platforms declare a clock lookup entry for SCI devices, - * in which case we need to get the global "peripheral_clk" clock. - */ - sci_port->fclk = devm_clk_get(dev, "peripheral_clk"); - if (!IS_ERR(sci_port->fclk)) - return 0; + if (!IS_ERR(clk)) + goto found; - dev_err(dev, "failed to get functional clock\n"); - return PTR_ERR(sci_port->fclk); + /* SH has historically named the clock "sci_fck". */ + clk = devm_clk_get(dev, "sci_fck"); + if (!IS_ERR(clk)) + goto found; + + /* + * Not all SH platforms declare a clock lookup entry + * for SCI devices, in which case we need to get the + * global "peripheral_clk" clock. + */ + clk = devm_clk_get(dev, "peripheral_clk"); + if (!IS_ERR(clk)) + goto found; + + dev_err(dev, "failed to get %s (%ld)\n", clk_names[i], + PTR_ERR(clk)); + return PTR_ERR(clk); + } + +found: + if (IS_ERR(clk)) + dev_dbg(dev, "failed to get %s (%ld)\n", clk_names[i], + PTR_ERR(clk)); + else + dev_dbg(dev, "clk %s is %pC rate %pCr\n", clk_names[i], + clk, clk); + sci_port->clks[i] = IS_ERR(clk) ? NULL : clk; + } + return 0; } static int sci_init_single(struct platform_device *dev, -- GitLab From 6af27bf299e2d66ade25f278f0c13d51007e9879 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 18 Nov 2015 11:12:26 +0100 Subject: [PATCH 1420/2855] serial: sh-sci: Add support for optional external (H)SCK input Add support for using the SCIx clock pin "(H)SCK" as an external clock input on (H)SCI(F), providing the sampling clock. Note that this feature is not yet supported on the select SCIFA variants that also have it (e.g. sh7723, sh7724, and r8a7740). On (H)SCIF variants with an External Baud Rate Generator (BRG), the BRG Clock Select Register must be configured for the external clock. Signed-off-by: Geert Uytterhoeven Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 69 +++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index fa3fd876105b2..229162481fd67 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -79,6 +79,7 @@ enum { enum SCI_CLKS { SCI_FCK, /* Functional Clock */ + SCI_SCK, /* Optional External Clock */ SCI_NUM_CLKS }; @@ -1924,6 +1925,39 @@ static void sci_shutdown(struct uart_port *port) sci_free_irq(s); } +static int sci_sck_calc(struct sci_port *s, unsigned int bps, + unsigned int *srr) +{ + unsigned long freq = s->clk_rates[SCI_SCK]; + unsigned int min_sr, max_sr, sr; + int err, min_err = INT_MAX; + + if (s->sampling_rate) { + /* SCI(F) has a fixed sampling rate */ + min_sr = max_sr = s->sampling_rate / 2; + } else { + /* HSCIF has a variable 1/(8..32) sampling rate */ + min_sr = 8; + max_sr = 32; + } + + for (sr = max_sr; sr >= min_sr; sr--) { + err = DIV_ROUND_CLOSEST(freq, sr) - bps; + if (abs(err) >= abs(min_err)) + continue; + + min_err = err; + *srr = sr - 1; + + if (!err) + break; + } + + dev_dbg(s->port.dev, "SCK: %u%+d bps using SR %u\n", bps, min_err, + *srr + 1); + return min_err; +} + /* calculate sample rate, BRR, and clock select */ static int sci_scbrr_calc(struct sci_port *s, unsigned int bps, unsigned int *brr, unsigned int *srr, @@ -2019,7 +2053,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned int baud, smr_val = 0, scr_val = 0, i; - unsigned int brr = 255, cks = 0, srr = 15; + unsigned int brr = 255, cks = 0, srr = 15, sccks = 0; unsigned int brr1 = 255, cks1 = 0, srr1 = 15; struct sci_port *s = to_sci_port(port); const struct plat_sci_reg *reg; @@ -2062,10 +2096,26 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, * that gives us the smallest deviation from the desired baud rate. */ + /* Optional Undivided External Clock */ + if (s->clk_rates[SCI_SCK] && port->type != PORT_SCIFA && + port->type != PORT_SCIFB) { + err = sci_sck_calc(s, baud, &srr1); + if (abs(err) < abs(min_err)) { + best_clk = SCI_SCK; + scr_val = SCSCR_CKE1; + sccks = SCCKS_CKS; + min_err = err; + srr = srr1; + if (!err) + goto done; + } + } + /* Divided Functional Clock using standard Bit Rate Register */ err = sci_scbrr_calc(s, baud, &brr1, &srr1, &cks1); if (abs(err) < abs(min_err)) { best_clk = SCI_FCK; + scr_val = 0; min_err = err; brr = brr1; srr = srr1; @@ -2079,14 +2129,23 @@ done: sci_port_enable(s); + /* + * Program the optional External Baud Rate Generator (BRG) first. + * It controls the mux to select (H)SCK or frequency divided clock. + */ + if (best_clk >= 0 && sci_getreg(port, SCCKS)->size) + serial_port_out(port, SCCKS, sccks); + sci_reset(port); uart_update_timeout(port, termios->c_cflag, baud); if (best_clk >= 0) { smr_val |= cks; - dev_dbg(port->dev, "SMR 0x%x BRR %u SRR %u\n", smr_val, brr, - srr); + dev_dbg(port->dev, + "SCR 0x%x SMR 0x%x BRR %u CKS 0x%x SRR %u\n", + scr_val, smr_val, brr, sccks, srr); + serial_port_out(port, SCSCR, scr_val); serial_port_out(port, SCSMR, smr_val); serial_port_out(port, SCBRR, brr); if (sci_getreg(port, HSSRR)->size) @@ -2322,10 +2381,14 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev) { const char *clk_names[] = { [SCI_FCK] = "fck", + [SCI_SCK] = "sck", }; struct clk *clk; unsigned int i; + if (sci_port->cfg->type == PORT_HSCIF) + clk_names[SCI_SCK] = "hsck"; + for (i = 0; i < SCI_NUM_CLKS; i++) { clk = devm_clk_get(dev, clk_names[i]); if (PTR_ERR(clk) == -EPROBE_DEFER) -- GitLab From 1270f86517f342f455dc146b1b321a18d3a274f9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 18 Nov 2015 11:25:53 +0100 Subject: [PATCH 1421/2855] serial: sh-sci: Add support for optional BRG on (H)SCIF Add support for using the Baud Rate Generator for External Clock (BRG), as found on some SCIF and HSCIF variants, to provide the sampling clock. This can improve baud rate range and accuracy. Signed-off-by: Geert Uytterhoeven Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 85 ++++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 229162481fd67..4ff5d0cf81268 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -80,6 +80,8 @@ enum { enum SCI_CLKS { SCI_FCK, /* Functional Clock */ SCI_SCK, /* Optional External Clock */ + SCI_BRG_INT, /* Optional BRG Internal Clock Source */ + SCI_SCIF_CLK, /* Optional BRG External Clock Source */ SCI_NUM_CLKS }; @@ -1958,6 +1960,43 @@ static int sci_sck_calc(struct sci_port *s, unsigned int bps, return min_err; } +static int sci_brg_calc(struct sci_port *s, unsigned int bps, + unsigned long freq, unsigned int *dlr, + unsigned int *srr) +{ + unsigned int min_sr, max_sr, sr, dl; + int err, min_err = INT_MAX; + + if (s->sampling_rate) { + /* SCIF has a fixed sampling rate */ + min_sr = max_sr = s->sampling_rate / 2; + } else { + /* HSCIF has a variable 1/(8..32) sampling rate */ + min_sr = 8; + max_sr = 32; + } + + for (sr = max_sr; sr >= min_sr; sr--) { + dl = DIV_ROUND_CLOSEST(freq, sr * bps); + dl = clamp(dl, 1U, 65535U); + + err = DIV_ROUND_CLOSEST(freq, sr * dl) - bps; + if (abs(err) >= abs(min_err)) + continue; + + min_err = err; + *dlr = dl; + *srr = sr - 1; + + if (!err) + break; + } + + dev_dbg(s->port.dev, "BRG: %u%+d bps using DL %u SR %u\n", bps, + min_err, *dlr, *srr + 1); + return min_err; +} + /* calculate sample rate, BRR, and clock select */ static int sci_scbrr_calc(struct sci_port *s, unsigned int bps, unsigned int *brr, unsigned int *srr, @@ -2053,8 +2092,8 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned int baud, smr_val = 0, scr_val = 0, i; - unsigned int brr = 255, cks = 0, srr = 15, sccks = 0; - unsigned int brr1 = 255, cks1 = 0, srr1 = 15; + unsigned int brr = 255, cks = 0, srr = 15, dl = 0, sccks = 0; + unsigned int brr1 = 255, cks1 = 0, srr1 = 15, dl1 = 0; struct sci_port *s = to_sci_port(port); const struct plat_sci_reg *reg; int min_err = INT_MAX, err; @@ -2111,6 +2150,38 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, } } + /* Optional BRG Frequency Divided External Clock */ + if (s->clk_rates[SCI_SCIF_CLK] && sci_getreg(port, SCDL)->size) { + err = sci_brg_calc(s, baud, s->clk_rates[SCI_SCIF_CLK], &dl1, + &srr1); + if (abs(err) < abs(min_err)) { + best_clk = SCI_SCIF_CLK; + scr_val = SCSCR_CKE1; + sccks = 0; + min_err = err; + dl = dl1; + srr = srr1; + if (!err) + goto done; + } + } + + /* Optional BRG Frequency Divided Internal Clock */ + if (s->clk_rates[SCI_BRG_INT] && sci_getreg(port, SCDL)->size) { + err = sci_brg_calc(s, baud, s->clk_rates[SCI_BRG_INT], &dl1, + &srr1); + if (abs(err) < abs(min_err)) { + best_clk = SCI_BRG_INT; + scr_val = SCSCR_CKE1; + sccks = SCCKS_XIN; + min_err = err; + dl = dl1; + srr = srr1; + if (!min_err) + goto done; + } + } + /* Divided Functional Clock using standard Bit Rate Register */ err = sci_scbrr_calc(s, baud, &brr1, &srr1, &cks1); if (abs(err) < abs(min_err)) { @@ -2133,8 +2204,10 @@ done: * Program the optional External Baud Rate Generator (BRG) first. * It controls the mux to select (H)SCK or frequency divided clock. */ - if (best_clk >= 0 && sci_getreg(port, SCCKS)->size) + if (best_clk >= 0 && sci_getreg(port, SCCKS)->size) { + serial_port_out(port, SCDL, dl); serial_port_out(port, SCCKS, sccks); + } sci_reset(port); @@ -2143,8 +2216,8 @@ done: if (best_clk >= 0) { smr_val |= cks; dev_dbg(port->dev, - "SCR 0x%x SMR 0x%x BRR %u CKS 0x%x SRR %u\n", - scr_val, smr_val, brr, sccks, srr); + "SCR 0x%x SMR 0x%x BRR %u CKS 0x%x DL %u SRR %u\n", + scr_val, smr_val, brr, sccks, dl, srr); serial_port_out(port, SCSCR, scr_val); serial_port_out(port, SCSMR, smr_val); serial_port_out(port, SCBRR, brr); @@ -2382,6 +2455,8 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev) const char *clk_names[] = { [SCI_FCK] = "fck", [SCI_SCK] = "sck", + [SCI_BRG_INT] = "brg_int", + [SCI_SCIF_CLK] = "scif_clk", }; struct clk *clk; unsigned int i; -- GitLab From fa3d39bf25558262675334f26fada57bd75c4e2e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 14 Sep 2015 15:14:24 +0300 Subject: [PATCH 1422/2855] sh: Rename sci_ick and sci_fck clock to fck The SCI driver requires a functional clock named "fck" and falls back to "sci_ick" or "sci_fck" when the "fck" clock doesn't exist. To allow removal of the fallback code rename the sci_ick and sci_fck clocks to fck for all SH platforms. Signed-off-by: Laurent Pinchart Acked-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- arch/sh/kernel/cpu/sh2a/clock-sh7264.c | 9 ++++++++- arch/sh/kernel/cpu/sh2a/clock-sh7269.c | 16 ++++++++-------- arch/sh/kernel/cpu/sh4a/clock-sh7343.c | 8 ++++---- arch/sh/kernel/cpu/sh4a/clock-sh7366.c | 6 +++--- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 12 ++++++------ arch/sh/kernel/cpu/sh4a/clock-sh7734.c | 12 ++++++------ arch/sh/kernel/cpu/sh4a/clock-sh7757.c | 6 +++--- arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 12 ++++++------ arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 12 ++++++------ arch/sh/kernel/cpu/sh4a/clock-shx3.c | 8 ++++---- 10 files changed, 54 insertions(+), 47 deletions(-) diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7264.c b/arch/sh/kernel/cpu/sh2a/clock-sh7264.c index 8638fba6cd7fb..7e06e39b09586 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7264.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7264.c @@ -115,7 +115,14 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]), /* MSTP clocks */ - CLKDEV_CON_ID("sci_ick", &mstp_clks[MSTP77]), + CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP77]), + CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP77]), + CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP77]), + CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP77]), + CLKDEV_ICK_ID("fck", "sh-sci.4", &mstp_clks[MSTP77]), + CLKDEV_ICK_ID("fck", "sh-sci.5", &mstp_clks[MSTP77]), + CLKDEV_ICK_ID("fck", "sh-sci.6", &mstp_clks[MSTP77]), + CLKDEV_ICK_ID("fck", "sh-sci.7", &mstp_clks[MSTP77]), CLKDEV_CON_ID("vdc3", &mstp_clks[MSTP74]), CLKDEV_ICK_ID("fck", "sh-cmt-16.0", &mstp_clks[MSTP72]), CLKDEV_CON_ID("usb0", &mstp_clks[MSTP60]), diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7269.c b/arch/sh/kernel/cpu/sh2a/clock-sh7269.c index f8a5c2abdfb3c..663a97bed554e 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7269.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7269.c @@ -150,14 +150,14 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]), /* MSTP clocks */ - CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP47]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP46]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP45]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP44]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP43]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP42]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.6", &mstp_clks[MSTP41]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.7", &mstp_clks[MSTP40]), + CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP47]), + CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP46]), + CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP45]), + CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP44]), + CLKDEV_ICK_ID("fck", "sh-sci.4", &mstp_clks[MSTP43]), + CLKDEV_ICK_ID("fck", "sh-sci.5", &mstp_clks[MSTP42]), + CLKDEV_ICK_ID("fck", "sh-sci.6", &mstp_clks[MSTP41]), + CLKDEV_ICK_ID("fck", "sh-sci.7", &mstp_clks[MSTP40]), CLKDEV_ICK_ID("fck", "sh-cmt-16.0", &mstp_clks[MSTP72]), CLKDEV_CON_ID("usb0", &mstp_clks[MSTP60]), CLKDEV_ICK_ID("fck", "sh-mtu2", &mstp_clks[MSTP35]), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c index 9edc06c02dcf1..a907ee2388bfc 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -232,10 +232,10 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]), CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP007]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP006]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP005]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP004]), + CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP007]), + CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP006]), + CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP005]), + CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP004]), CLKDEV_CON_ID("sio0", &mstp_clks[MSTP003]), CLKDEV_CON_ID("siof0", &mstp_clks[MSTP002]), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c index 955b9add78106..ac9854179dee8 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c @@ -230,9 +230,9 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]), CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP007]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP006]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP005]), + CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP007]), + CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP006]), + CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP005]), CLKDEV_CON_ID("msiof0", &mstp_clks[MSTP002]), CLKDEV_CON_ID("sbr0", &mstp_clks[MSTP001]), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index ccbcab550df24..fe844222f3f6a 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -267,12 +267,12 @@ static struct clk_lookup lookups[] = { CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[HWBLK_TMU0]), CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[HWBLK_TMU1]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[HWBLK_SCIF0]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[HWBLK_SCIF1]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[HWBLK_SCIF2]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[HWBLK_SCIF3]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[HWBLK_SCIF4]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[HWBLK_SCIF5]), + CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[HWBLK_SCIF0]), + CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[HWBLK_SCIF1]), + CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[HWBLK_SCIF2]), + CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[HWBLK_SCIF3]), + CLKDEV_ICK_ID("fck", "sh-sci.4", &mstp_clks[HWBLK_SCIF4]), + CLKDEV_ICK_ID("fck", "sh-sci.5", &mstp_clks[HWBLK_SCIF5]), CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[HWBLK_LCDC]), }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7734.c b/arch/sh/kernel/cpu/sh4a/clock-sh7734.c index 7f54bf2f453d7..354dcac5e4cd9 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7734.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7734.c @@ -194,12 +194,12 @@ static struct clk_lookup lookups[] = { /* MSTP32 clocks */ CLKDEV_DEV_ID("i2c-sh7734.0", &mstp_clks[MSTP030]), CLKDEV_DEV_ID("i2c-sh7734.1", &mstp_clks[MSTP029]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP026]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP025]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP024]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP023]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP022]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP021]), + CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP026]), + CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP025]), + CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP024]), + CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP023]), + CLKDEV_ICK_ID("fck", "sh-sci.4", &mstp_clks[MSTP022]), + CLKDEV_ICK_ID("fck", "sh-sci.5", &mstp_clks[MSTP021]), CLKDEV_CON_ID("hscif", &mstp_clks[MSTP019]), CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP016]), CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[MSTP015]), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c index e40ec2c97ad19..b10af2ae9f350 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c @@ -125,9 +125,9 @@ static struct clk_lookup lookups[] = { CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP113]), CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[MSTP114]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP112]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP111]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP110]), + CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP112]), + CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP111]), + CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP110]), CLKDEV_CON_ID("usb_fck", &mstp_clks[MSTP103]), CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP102]), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 8eb6e62340c95..1aafd5496752f 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -132,12 +132,12 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), /* MSTP32 clocks */ - CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP029]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP028]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP027]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP026]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP025]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP024]), + CLKDEV_ICK_ID("fck", "sh-sci.5", &mstp_clks[MSTP029]), + CLKDEV_ICK_ID("fck", "sh-sci.4", &mstp_clks[MSTP028]), + CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP027]), + CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP026]), + CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP025]), + CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP024]), CLKDEV_CON_ID("ssi1_fck", &mstp_clks[MSTP021]), CLKDEV_CON_ID("ssi0_fck", &mstp_clks[MSTP020]), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index 5e50e7ebeff08..ac3dcfe5d303d 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -139,12 +139,12 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), /* MSTP32 clocks */ - CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP029]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP028]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP027]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP026]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP025]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP024]), + CLKDEV_ICK_ID("fck", "sh-sci.5", &mstp_clks[MSTP029]), + CLKDEV_ICK_ID("fck", "sh-sci.4", &mstp_clks[MSTP028]), + CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP027]), + CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP026]), + CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP025]), + CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP024]), CLKDEV_CON_ID("ssi3_fck", &mstp_clks[MSTP023]), CLKDEV_CON_ID("ssi2_fck", &mstp_clks[MSTP022]), diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c index 605221d1448a1..b1bdbc3cbc219 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c @@ -114,10 +114,10 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), /* MSTP32 clocks */ - CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP027]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP026]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP025]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP024]), + CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP027]), + CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP026]), + CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP025]), + CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP024]), CLKDEV_CON_ID("h8ex_fck", &mstp_clks[MSTP003]), CLKDEV_CON_ID("csm_fck", &mstp_clks[MSTP002]), -- GitLab From 6441d314b4d898d871f21196fb5e6e4f82caedc7 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 14 Sep 2015 15:14:25 +0300 Subject: [PATCH 1423/2855] sh: Remove sci_ick clock alias The sh-sci driver falls back to the peripheral clock if the sci_ick clock doesn't exist. There's thus no need to create an alias for the peripheral clock named sci_ick. Signed-off-by: Laurent Pinchart Acked-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- arch/sh/kernel/cpu/clock-cpg.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c index 8525a671266fe..786c0769b4c39 100644 --- a/arch/sh/kernel/cpu/clock-cpg.c +++ b/arch/sh/kernel/cpu/clock-cpg.c @@ -63,7 +63,6 @@ int __init __deprecated cpg_clk_init(void) clk_add_alias("fck", "sh-mtu2", "peripheral_clk", NULL); clk_add_alias("fck", "sh-cmt-16.0", "peripheral_clk", NULL); clk_add_alias("fck", "sh-cmt-32.0", "peripheral_clk", NULL); - clk_add_alias("sci_ick", NULL, "peripheral_clk", NULL); return ret; } -- GitLab From 0a036681888f417e365e0b2935ff6f3f0273f843 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 10 Nov 2015 18:59:28 +0100 Subject: [PATCH 1424/2855] sh: sh7734: Correct SCIF type for BRG The SCIF variant in the sh7734 SoC is not the common "SH-4(A)" variant, but a derivative with added "Baud Rate Generator for External Clock" (BRG). Correct the regtype value in platform data to fix this. Signed-off-by: Geert Uytterhoeven --- arch/sh/kernel/cpu/sh4a/setup-sh7734.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7734.c b/arch/sh/kernel/cpu/sh4a/setup-sh7734.c index f617bcb734dfe..69b8a50310d9a 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7734.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7734.c @@ -28,7 +28,7 @@ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, - .regtype = SCIx_SH4_SCIF_REGTYPE, + .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, }; static struct resource scif0_resources[] = { @@ -50,7 +50,7 @@ static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, - .regtype = SCIx_SH4_SCIF_REGTYPE, + .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, }; static struct resource scif1_resources[] = { @@ -72,7 +72,7 @@ static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, - .regtype = SCIx_SH4_SCIF_REGTYPE, + .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, }; static struct resource scif2_resources[] = { @@ -94,7 +94,7 @@ static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, - .regtype = SCIx_SH4_SCIF_REGTYPE, + .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, }; static struct resource scif3_resources[] = { @@ -116,7 +116,7 @@ static struct plat_sci_port scif4_platform_data = { .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, - .regtype = SCIx_SH4_SCIF_REGTYPE, + .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, }; static struct resource scif4_resources[] = { @@ -138,7 +138,7 @@ static struct plat_sci_port scif5_platform_data = { .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, - .regtype = SCIx_SH4_SCIF_REGTYPE, + .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, }; static struct resource scif5_resources[] = { -- GitLab From 192d367f218d0cd94aa9b5059992e4aa19ec5b36 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 14 Sep 2015 15:14:36 +0300 Subject: [PATCH 1425/2855] serial: sh-sci: Drop the sci_fck clock fallback All platforms that used to define an sci_fck clock have now switched to the fck name. Remove the fallback code. Signed-off-by: Laurent Pinchart Acked-by: Simon Horman Signed-off-by: Geert Uytterhoeven Acked-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 4ff5d0cf81268..6571f4d944c26 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2481,11 +2481,6 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev) if (!IS_ERR(clk)) goto found; - /* SH has historically named the clock "sci_fck". */ - clk = devm_clk_get(dev, "sci_fck"); - if (!IS_ERR(clk)) - goto found; - /* * Not all SH platforms declare a clock lookup entry * for SCI devices, in which case we need to get the -- GitLab From 786842b62f81f20d14894925e8c225328ee8144b Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Wed, 9 Dec 2015 17:18:18 +1100 Subject: [PATCH 1426/2855] powerpc/powernv: panic() on OPAL < V3 The OpenPower Abstraction Layer firmware went through a couple of iterations in the lab before being released. What we now know as OPAL advertises itself as OPALv3. OPALv2 and OPALv1 never made it outside the lab, and the possibility of anyone at all ever building a mainline kernel today and expecting it to boot on such hardware is zero. Signed-off-by: Stewart Smith Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/opal.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 4296d55e88f30..faea1abaa7859 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -103,11 +103,8 @@ int __init early_init_dt_scan_opal(unsigned long node, powerpc_firmware_features |= FW_FEATURE_OPALv2; powerpc_firmware_features |= FW_FEATURE_OPALv3; pr_info("OPAL V3 detected !\n"); - } else if (of_flat_dt_is_compatible(node, "ibm,opal-v2")) { - powerpc_firmware_features |= FW_FEATURE_OPALv2; - pr_info("OPAL V2 detected !\n"); } else { - pr_info("OPAL V1 detected !\n"); + panic("OPAL != V3 detected, no longer supported.\n"); } /* Reinit all cores with the right endian */ -- GitLab From 7261aafc095763b119136a562540dea7b1ccf657 Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Wed, 9 Dec 2015 17:18:19 +1100 Subject: [PATCH 1427/2855] powerpc/powernv: Remove OPALv2 firmware define and references OPALv2 only ever existed in the lab and didn't escape to the world. All OPAL systems in the wild are OPALv3. The probability of there being an OPALv2 system still powered on anywhere inside IBM is approximately zero, let alone anyone expecting to run mainline kernels. So, start to remove references to OPALv2. Signed-off-by: Stewart Smith Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/firmware.h | 4 +--- arch/powerpc/platforms/powernv/opal.c | 8 ++------ arch/powerpc/platforms/powernv/setup.c | 4 ---- arch/powerpc/platforms/powernv/smp.c | 4 ++-- 4 files changed, 5 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h index e05808a328db2..50af5e5ea86fd 100644 --- a/arch/powerpc/include/asm/firmware.h +++ b/arch/powerpc/include/asm/firmware.h @@ -47,7 +47,6 @@ #define FW_FEATURE_VPHN ASM_CONST(0x0000000004000000) #define FW_FEATURE_XCMO ASM_CONST(0x0000000008000000) #define FW_FEATURE_OPAL ASM_CONST(0x0000000010000000) -#define FW_FEATURE_OPALv2 ASM_CONST(0x0000000020000000) #define FW_FEATURE_SET_MODE ASM_CONST(0x0000000040000000) #define FW_FEATURE_BEST_ENERGY ASM_CONST(0x0000000080000000) #define FW_FEATURE_TYPE1_AFFINITY ASM_CONST(0x0000000100000000) @@ -70,8 +69,7 @@ enum { FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY | FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN, FW_FEATURE_PSERIES_ALWAYS = 0, - FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2 | - FW_FEATURE_OPALv3, + FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv3, FW_FEATURE_POWERNV_ALWAYS = 0, FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index faea1abaa7859..5ce51d9b4ca6f 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -100,7 +100,6 @@ int __init early_init_dt_scan_opal(unsigned long node, powerpc_firmware_features |= FW_FEATURE_OPAL; if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) { - powerpc_firmware_features |= FW_FEATURE_OPALv2; powerpc_firmware_features |= FW_FEATURE_OPALv3; pr_info("OPAL V3 detected !\n"); } else { @@ -349,7 +348,7 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len) * enough room and be done with it */ spin_lock_irqsave(&opal_write_lock, flags); - if (firmware_has_feature(FW_FEATURE_OPALv2)) { + if (firmware_has_feature(FW_FEATURE_OPALv3)) { rc = opal_console_write_buffer_space(vtermno, &olen); len = be64_to_cpu(olen); if (rc || len < total_len) { @@ -693,10 +692,7 @@ static int __init opal_init(void) } /* Register OPAL consoles if any ports */ - if (firmware_has_feature(FW_FEATURE_OPALv2)) - consoles = of_find_node_by_path("/ibm,opal/consoles"); - else - consoles = of_node_get(opal_node); + consoles = of_find_node_by_path("/ibm,opal/consoles"); if (consoles) { for_each_child_of_node(consoles, np) { if (strcmp(np->name, "serial")) diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index a9a8fa37a555f..54583fc417bed 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -92,10 +92,6 @@ static void pnv_show_cpuinfo(struct seq_file *m) seq_printf(m, "machine\t\t: PowerNV %s\n", model); if (firmware_has_feature(FW_FEATURE_OPALv3)) seq_printf(m, "firmware\t: OPAL v3\n"); - else if (firmware_has_feature(FW_FEATURE_OPALv2)) - seq_printf(m, "firmware\t: OPAL v2\n"); - else if (firmware_has_feature(FW_FEATURE_OPAL)) - seq_printf(m, "firmware\t: OPAL v1\n"); else seq_printf(m, "firmware\t: BML\n"); of_node_put(root); diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index ca264833ee64d..9b968a3151035 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c @@ -65,10 +65,10 @@ static int pnv_smp_kick_cpu(int nr) BUG_ON(nr < 0 || nr >= NR_CPUS); /* - * If we already started or OPALv2 is not supported, we just + * If we already started or OPALv3 is not supported, we just * kick the CPU via the PACA */ - if (paca[nr].cpu_start || !firmware_has_feature(FW_FEATURE_OPALv2)) + if (paca[nr].cpu_start || !firmware_has_feature(FW_FEATURE_OPALv3)) goto kick; /* -- GitLab From e4d54f71d29997344b4c4c8d47708240f9f23a5c Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Wed, 9 Dec 2015 17:18:20 +1100 Subject: [PATCH 1428/2855] powerpc/powernv: remove FW_FEATURE_OPALv3 and just use FW_FEATURE_OPAL Long ago, only in the lab, there was OPALv1 and OPALv2. Now there is just OPALv3, with nobody ever expecting anything on pre-OPALv3 to be cared about or supported by mainline kernels. So, let's remove FW_FEATURE_OPALv3 and instead use FW_FEATURE_OPAL exclusively. Signed-off-by: Stewart Smith Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/firmware.h | 3 +- arch/powerpc/platforms/powernv/eeh-powernv.c | 4 +- arch/powerpc/platforms/powernv/idle.c | 2 +- arch/powerpc/platforms/powernv/opal-xscom.c | 2 +- arch/powerpc/platforms/powernv/opal.c | 25 +++---- arch/powerpc/platforms/powernv/pci-ioda.c | 2 +- arch/powerpc/platforms/powernv/setup.c | 8 +-- arch/powerpc/platforms/powernv/smp.c | 74 ++++++++------------ drivers/cpufreq/powernv-cpufreq.c | 2 +- drivers/cpuidle/cpuidle-powernv.c | 2 +- 10 files changed, 54 insertions(+), 70 deletions(-) diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h index 50af5e5ea86fd..b0629249778b3 100644 --- a/arch/powerpc/include/asm/firmware.h +++ b/arch/powerpc/include/asm/firmware.h @@ -51,7 +51,6 @@ #define FW_FEATURE_BEST_ENERGY ASM_CONST(0x0000000080000000) #define FW_FEATURE_TYPE1_AFFINITY ASM_CONST(0x0000000100000000) #define FW_FEATURE_PRRN ASM_CONST(0x0000000200000000) -#define FW_FEATURE_OPALv3 ASM_CONST(0x0000000400000000) #ifndef __ASSEMBLY__ @@ -69,7 +68,7 @@ enum { FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY | FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN, FW_FEATURE_PSERIES_ALWAYS = 0, - FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv3, + FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL, FW_FEATURE_POWERNV_ALWAYS = 0, FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index e1c90725522a1..5f152b95ca0c8 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -48,8 +48,8 @@ static int pnv_eeh_init(void) struct pci_controller *hose; struct pnv_phb *phb; - if (!firmware_has_feature(FW_FEATURE_OPALv3)) { - pr_warn("%s: OPALv3 is required !\n", + if (!firmware_has_feature(FW_FEATURE_OPAL)) { + pr_warn("%s: OPAL is required !\n", __func__); return -EINVAL; } diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index 59d735d2e5c05..15bfbcd5debc2 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -242,7 +242,7 @@ static int __init pnv_init_idle_states(void) if (cpuidle_disable != IDLE_NO_OVERRIDE) goto out; - if (!firmware_has_feature(FW_FEATURE_OPALv3)) + if (!firmware_has_feature(FW_FEATURE_OPAL)) goto out; power_mgt = of_find_node_by_path("/ibm,opal/power-mgt"); diff --git a/arch/powerpc/platforms/powernv/opal-xscom.c b/arch/powerpc/platforms/powernv/opal-xscom.c index 7634d1c62299b..d0ac535cf5d7c 100644 --- a/arch/powerpc/platforms/powernv/opal-xscom.c +++ b/arch/powerpc/platforms/powernv/opal-xscom.c @@ -126,7 +126,7 @@ static const struct scom_controller opal_scom_controller = { static int opal_xscom_init(void) { - if (firmware_has_feature(FW_FEATURE_OPALv3)) + if (firmware_has_feature(FW_FEATURE_OPAL)) scom_init(&opal_scom_controller); return 0; } diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 5ce51d9b4ca6f..aad0033d65d1e 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -98,10 +98,9 @@ int __init early_init_dt_scan_opal(unsigned long node, pr_debug("OPAL Entry = 0x%llx (sizep=%p runtimesz=%d)\n", opal.size, sizep, runtimesz); - powerpc_firmware_features |= FW_FEATURE_OPAL; if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) { - powerpc_firmware_features |= FW_FEATURE_OPALv3; - pr_info("OPAL V3 detected !\n"); + powerpc_firmware_features |= FW_FEATURE_OPAL; + pr_info("OPAL detected !\n"); } else { panic("OPAL != V3 detected, no longer supported.\n"); } @@ -348,17 +347,15 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len) * enough room and be done with it */ spin_lock_irqsave(&opal_write_lock, flags); - if (firmware_has_feature(FW_FEATURE_OPALv3)) { - rc = opal_console_write_buffer_space(vtermno, &olen); - len = be64_to_cpu(olen); - if (rc || len < total_len) { - spin_unlock_irqrestore(&opal_write_lock, flags); - /* Closed -> drop characters */ - if (rc) - return total_len; - opal_poll_events(NULL); - return -EAGAIN; - } + rc = opal_console_write_buffer_space(vtermno, &olen); + len = be64_to_cpu(olen); + if (rc || len < total_len) { + spin_unlock_irqrestore(&opal_write_lock, flags); + /* Closed -> drop characters */ + if (rc) + return total_len; + opal_poll_events(NULL); + return -EAGAIN; } /* We still try to handle partial completions, though they diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 414fd1a00fda8..cdd5fa942aedc 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -344,7 +344,7 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb) return; } - if (!firmware_has_feature(FW_FEATURE_OPALv3)) { + if (!firmware_has_feature(FW_FEATURE_OPAL)) { pr_info(" Firmware too old to support M64 window\n"); return; } diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 54583fc417bed..1acb0c72d9231 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -90,8 +90,8 @@ static void pnv_show_cpuinfo(struct seq_file *m) if (root) model = of_get_property(root, "model", NULL); seq_printf(m, "machine\t\t: PowerNV %s\n", model); - if (firmware_has_feature(FW_FEATURE_OPALv3)) - seq_printf(m, "firmware\t: OPAL v3\n"); + if (firmware_has_feature(FW_FEATURE_OPAL)) + seq_printf(m, "firmware\t: OPAL\n"); else seq_printf(m, "firmware\t: BML\n"); of_node_put(root); @@ -220,9 +220,9 @@ static void pnv_kexec_cpu_down(int crash_shutdown, int secondary) { xics_kexec_teardown_cpu(secondary); - /* On OPAL v3, we return all CPUs to firmware */ + /* On OPAL, we return all CPUs to firmware */ - if (!firmware_has_feature(FW_FEATURE_OPALv3)) + if (!firmware_has_feature(FW_FEATURE_OPAL)) return; if (secondary) { diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index 9b968a3151035..ad7b1a3dbed09 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c @@ -61,14 +61,15 @@ static int pnv_smp_kick_cpu(int nr) unsigned long start_here = __pa(ppc_function_entry(generic_secondary_smp_init)); long rc; + uint8_t status; BUG_ON(nr < 0 || nr >= NR_CPUS); /* - * If we already started or OPALv3 is not supported, we just + * If we already started or OPAL is not supported, we just * kick the CPU via the PACA */ - if (paca[nr].cpu_start || !firmware_has_feature(FW_FEATURE_OPALv3)) + if (paca[nr].cpu_start || !firmware_has_feature(FW_FEATURE_OPAL)) goto kick; /* @@ -77,55 +78,42 @@ static int pnv_smp_kick_cpu(int nr) * first time. OPAL v3 allows us to query OPAL to know if it * has the CPUs, so we do that */ - if (firmware_has_feature(FW_FEATURE_OPALv3)) { - uint8_t status; - - rc = opal_query_cpu_status(pcpu, &status); - if (rc != OPAL_SUCCESS) { - pr_warn("OPAL Error %ld querying CPU %d state\n", - rc, nr); - return -ENODEV; - } + rc = opal_query_cpu_status(pcpu, &status); + if (rc != OPAL_SUCCESS) { + pr_warn("OPAL Error %ld querying CPU %d state\n", rc, nr); + return -ENODEV; + } - /* - * Already started, just kick it, probably coming from - * kexec and spinning - */ - if (status == OPAL_THREAD_STARTED) - goto kick; + /* + * Already started, just kick it, probably coming from + * kexec and spinning + */ + if (status == OPAL_THREAD_STARTED) + goto kick; - /* - * Available/inactive, let's kick it - */ - if (status == OPAL_THREAD_INACTIVE) { - pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", - nr, pcpu); - rc = opal_start_cpu(pcpu, start_here); - if (rc != OPAL_SUCCESS) { - pr_warn("OPAL Error %ld starting CPU %d\n", - rc, nr); - return -ENODEV; - } - } else { - /* - * An unavailable CPU (or any other unknown status) - * shouldn't be started. It should also - * not be in the possible map but currently it can - * happen - */ - pr_devel("OPAL: CPU %d (HW 0x%x) is unavailable" - " (status %d)...\n", nr, pcpu, status); + /* + * Available/inactive, let's kick it + */ + if (status == OPAL_THREAD_INACTIVE) { + pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", nr, pcpu); + rc = opal_start_cpu(pcpu, start_here); + if (rc != OPAL_SUCCESS) { + pr_warn("OPAL Error %ld starting CPU %d\n", rc, nr); return -ENODEV; } } else { /* - * On OPAL v2, we just kick it and hope for the best, - * we must not test the error from opal_start_cpu() or - * we would fail to get CPUs from kexec. + * An unavailable CPU (or any other unknown status) + * shouldn't be started. It should also + * not be in the possible map but currently it can + * happen */ - opal_start_cpu(pcpu, start_here); + pr_devel("OPAL: CPU %d (HW 0x%x) is unavailable" + " (status %d)...\n", nr, pcpu, status); + return -ENODEV; } - kick: + +kick: return smp_generic_kick_cpu(nr); } diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index cb501386eb6ef..547890fd95721 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c @@ -586,7 +586,7 @@ static int __init powernv_cpufreq_init(void) int rc = 0; /* Don't probe on pseries (guest) platforms */ - if (!firmware_has_feature(FW_FEATURE_OPALv3)) + if (!firmware_has_feature(FW_FEATURE_OPAL)) return -ENODEV; /* Discover pstates from device tree and init */ diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c index 845bafcfa7929..e12dc30d8864e 100644 --- a/drivers/cpuidle/cpuidle-powernv.c +++ b/drivers/cpuidle/cpuidle-powernv.c @@ -264,7 +264,7 @@ static int powernv_idle_probe(void) if (cpuidle_disable != IDLE_NO_OVERRIDE) return -ENODEV; - if (firmware_has_feature(FW_FEATURE_OPALv3)) { + if (firmware_has_feature(FW_FEATURE_OPAL)) { cpuidle_state_table = powernv_states; /* Device tree can indicate more idle states */ max_idle_state = powernv_add_idle_states(); -- GitLab From 209eb4e5cbaba53ab555f3e7b43aa27176f3a925 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 16 Dec 2015 21:01:42 +1100 Subject: [PATCH 1429/2855] powerpc/rtas: Add rtas_call_unlocked() Most users of RTAS (Run-Time Abstraction Services) use rtas_call(), which deals with locking as well as endian handling. However we have two users outside of rtas.c that can't use rtas_call() because they have different locking requirements. The hotplug CPU code can't take the RTAS lock because the CPU would go offline with the lock held and no other CPUs would be able to call RTAS until the CPU came back online. The xmon code doesn't want to take the lock because it would risk dead locking when we are trying to recover from a crash. Both sites required multiple patches when we added little endian support, proving that programmers can't do endian right. Although that ship has sailed, we can still clean the code up by providing an unlocked version of rtas_call() which avoids the need to open code the logic elsewhere. Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/rtas.h | 2 ++ arch/powerpc/kernel/rtas.c | 44 ++++++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index b77ef369c0f0e..6db1d6977a0df 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h @@ -338,6 +338,8 @@ extern void enter_rtas(unsigned long); extern int rtas_token(const char *service); extern int rtas_service_present(const char *service); extern int rtas_call(int token, int, int, int *, ...); +void rtas_call_unlocked(struct rtas_args *args, int token, int nargs, + int nret, ...); extern void rtas_restart(char *cmd); extern void rtas_power_off(void); extern void rtas_halt(void); diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 5a753fae8265a..fcf2d653a6fe3 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -418,6 +418,36 @@ static char *__fetch_rtas_last_error(char *altbuf) #define get_errorlog_buffer() NULL #endif + +static void +va_rtas_call_unlocked(struct rtas_args *args, int token, int nargs, int nret, + va_list list) +{ + int i; + + args->token = cpu_to_be32(token); + args->nargs = cpu_to_be32(nargs); + args->nret = cpu_to_be32(nret); + args->rets = &(args->args[nargs]); + + for (i = 0; i < nargs; ++i) + args->args[i] = cpu_to_be32(va_arg(list, __u32)); + + for (i = 0; i < nret; ++i) + args->rets[i] = 0; + + enter_rtas(__pa(args)); +} + +void rtas_call_unlocked(struct rtas_args *args, int token, int nargs, int nret, ...) +{ + va_list list; + + va_start(list, nret); + va_rtas_call_unlocked(args, token, nargs, nret, list); + va_end(list); +} + int rtas_call(int token, int nargs, int nret, int *outputs, ...) { va_list list; @@ -431,22 +461,14 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) return -1; s = lock_rtas(); + + /* We use the global rtas args buffer */ rtas_args = &rtas.args; - rtas_args->token = cpu_to_be32(token); - rtas_args->nargs = cpu_to_be32(nargs); - rtas_args->nret = cpu_to_be32(nret); - rtas_args->rets = &(rtas_args->args[nargs]); va_start(list, outputs); - for (i = 0; i < nargs; ++i) - rtas_args->args[i] = cpu_to_be32(va_arg(list, __u32)); + va_rtas_call_unlocked(rtas_args, token, nargs, nret, list); va_end(list); - for (i = 0; i < nret; ++i) - rtas_args->rets[i] = 0; - - enter_rtas(__pa(rtas_args)); - /* A -1 return code indicates that the last command couldn't be completed due to a hardware error. */ if (be32_to_cpu(rtas_args->rets[0]) == -1) -- GitLab From 08eb105a7c18c917f2ed7afc5a151f0514f26460 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 24 Nov 2015 22:26:09 +1100 Subject: [PATCH 1430/2855] powerpc/xmon: Use rtas_call_unlocked() in xmon Avoid open coding the logic by using rtas_call_unlocked(). Signed-off-by: Michael Ellerman --- arch/powerpc/xmon/xmon.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index e8c7a937955ec..07a8508cb7fae 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -320,6 +320,7 @@ static inline void disable_surveillance(void) #ifdef CONFIG_PPC_PSERIES /* Since this can't be a module, args should end up below 4GB. */ static struct rtas_args args; + int token; /* * At this point we have got all the cpus we can into @@ -328,17 +329,12 @@ static inline void disable_surveillance(void) * If we did try to take rtas.lock there would be a * real possibility of deadlock. */ - args.token = rtas_token("set-indicator"); - if (args.token == RTAS_UNKNOWN_SERVICE) + token = rtas_token("set-indicator"); + if (token == RTAS_UNKNOWN_SERVICE) return; - args.token = cpu_to_be32(args.token); - args.nargs = cpu_to_be32(3); - args.nret = cpu_to_be32(1); - args.rets = &args.args[3]; - args.args[0] = cpu_to_be32(SURVEILLANCE_TOKEN); - args.args[1] = 0; - args.args[2] = 0; - enter_rtas(__pa(&args)); + + rtas_call_unlocked(&args, token, 3, 1, NULL, SURVEILLANCE_TOKEN, 0, 0); + #endif /* CONFIG_PPC_PSERIES */ } -- GitLab From b2e8590fa1e35c38680dcb87c9d1bfdcc6c61a40 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 24 Nov 2015 22:26:10 +1100 Subject: [PATCH 1431/2855] powerpc/pseries: Use rtas_call_unlocked() in pseries hotplug Avoid open coding the logic by using rtas_call_unlocked(). Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 62475440fd453..86d2ecacb237e 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -88,13 +88,7 @@ void set_default_offline_state(int cpu) static void rtas_stop_self(void) { - static struct rtas_args args = { - .nargs = 0, - .nret = cpu_to_be32(1), - .rets = &args.args[0], - }; - - args.token = cpu_to_be32(rtas_stop_self_token); + static struct rtas_args args; local_irq_disable(); @@ -102,7 +96,8 @@ static void rtas_stop_self(void) printk("cpu %u (hwid %u) Ready to die...\n", smp_processor_id(), hard_smp_processor_id()); - enter_rtas(__pa(&args)); + + rtas_call_unlocked(&args, rtas_stop_self_token, 0, 1, NULL); panic("Alas, I survived.\n"); } -- GitLab From 4456f4524604be2558e5f6a8e0f7cc9ed17c783e Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 24 Nov 2015 22:26:11 +1100 Subject: [PATCH 1432/2855] powerpc/rtas: Use rtas_call_unlocked() in call_rtas_display_status() Although call_rtas_display_status() does actually want to use the regular RTAS locking, it doesn't want the extra logic that is in rtas_call(), so currently it open codes the logic. Instead we can use rtas_call_unlocked(), after taking the RTAS lock. Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/rtas.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index fcf2d653a6fe3..f4fa137292c43 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -93,21 +93,13 @@ static void unlock_rtas(unsigned long flags) */ static void call_rtas_display_status(unsigned char c) { - struct rtas_args *args = &rtas.args; unsigned long s; if (!rtas.base) return; - s = lock_rtas(); - - args->token = cpu_to_be32(10); - args->nargs = cpu_to_be32(1); - args->nret = cpu_to_be32(1); - args->rets = &(args->args[1]); - args->args[0] = cpu_to_be32(c); - - enter_rtas(__pa(args)); + s = lock_rtas(); + rtas_call_unlocked(&rtas.args, 10, 1, 1, NULL, c); unlock_rtas(s); } -- GitLab From cd5cdeb6c8a42fb87644b0eb5d240f6ce6172402 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 24 Nov 2015 22:26:12 +1100 Subject: [PATCH 1433/2855] powerpc/rtas: Make enter_rtas() private There are no longer any users of enter_rtas() outside of rtas.c, so make it "private", by moving the declaration inside rtas.c. Hopefully this will encourage people to use one of the wrappers which takes the sharp edges off the RTAS calling sequence. Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/rtas.h | 1 - arch/powerpc/kernel/rtas.c | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index 6db1d6977a0df..51400baa8d48d 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h @@ -334,7 +334,6 @@ extern void (*rtas_flash_term_hook)(int); extern struct rtas_t rtas; -extern void enter_rtas(unsigned long); extern int rtas_token(const char *service); extern int rtas_service_present(const char *service); extern int rtas_call(int token, int, int, int *, ...); diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index f4fa137292c43..28736ff27fea1 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -44,6 +44,9 @@ #include #include +/* This is here deliberately so it's only used in this file */ +void enter_rtas(unsigned long); + struct rtas_t rtas = { .lock = __ARCH_SPIN_LOCK_UNLOCKED }; -- GitLab From d6265aeaf815801ad53a95f11cea8ea752862176 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 25 Nov 2015 14:25:16 +1100 Subject: [PATCH 1434/2855] powerpc/kernel: Drop HMT_MEDIUM_PPR_DISCARD HMT_MEDIUM_PPR_DISCARD is a macro which is present at the start of most of our first level exception handlers. It conditionally executes a HMT_MEDIUM instruction, which sets the processor priority to medium. On on modern systems, ie. Power7 and later, it is nop'ed out at boot. All it does is make the exception vectors more cramped, and consume 4 bytes of icache. On old systems it has the effect of boosting the processor priority at the start of exception processing. If we were previously in the idle loop for example, we may be at low or very low priority. This is desirable as we want to process the exception as fast as possible. However looking closely at the generated code, we see that in all cases we execute another HMT_MEDIUM just four instructions later. With code patching applied, the final code on an old (Power6) system will look like, eg: c000000000000300 : c000000000000300: 7c 42 13 78 mr r2,r2 <- c000000000000304: 7d b2 43 a6 mtsprg 2,r13 c000000000000308: 7d b1 42 a6 mfsprg r13,1 c00000000000030c: f9 2d 00 80 std r9,128(r13) c000000000000310: 60 00 00 00 nop c000000000000314: 7c 42 13 78 mr r2,r2 <- So I suggest that the added code complexity of HMT_MEDIUM_PPR_DISCARD is not justified by the benefit of boosting the processor priority for the duration of four instructions, and therefore we drop it. Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 15 --------------- arch/powerpc/kernel/exceptions-64s.S | 9 --------- 2 files changed, 24 deletions(-) diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 9ee10781121fc..60b2bbda212df 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -129,15 +129,6 @@ BEGIN_FTR_SECTION_NESTED(941) \ mtspr SPRN_PPR,ra; \ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,941) -/* - * Increase the priority on systems where PPR save/restore is not - * implemented/ supported. - */ -#define HMT_MEDIUM_PPR_DISCARD \ -BEGIN_FTR_SECTION_NESTED(942) \ - HMT_MEDIUM; \ -END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,0,942) /*non P7*/ - /* * Get an SPR into a register if the CPU has the given feature */ @@ -346,7 +337,6 @@ do_kvm_##n: \ . = loc; \ .globl label##_pSeries; \ label##_pSeries: \ - HMT_MEDIUM_PPR_DISCARD; \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ EXC_STD, KVMTEST, vec) @@ -362,7 +352,6 @@ label##_pSeries: \ . = loc; \ .globl label##_hv; \ label##_hv: \ - HMT_MEDIUM_PPR_DISCARD; \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ EXC_HV, KVMTEST, vec) @@ -378,7 +367,6 @@ label##_hv: \ . = loc; \ .globl label##_relon_pSeries; \ label##_relon_pSeries: \ - HMT_MEDIUM_PPR_DISCARD; \ /* No guest interrupts come through here */ \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ @@ -394,7 +382,6 @@ label##_relon_pSeries: \ . = loc; \ .globl label##_relon_hv; \ label##_relon_hv: \ - HMT_MEDIUM_PPR_DISCARD; \ /* No guest interrupts come through here */ \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ @@ -448,7 +435,6 @@ label##_relon_hv: \ . = loc; \ .globl label##_pSeries; \ label##_pSeries: \ - HMT_MEDIUM_PPR_DISCARD; \ _MASKABLE_EXCEPTION_PSERIES(vec, label, \ EXC_STD, SOFTEN_TEST_PR) @@ -466,7 +452,6 @@ label##_hv: \ EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_HV); #define __MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra) \ - HMT_MEDIUM_PPR_DISCARD; \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(PACA_EXGEN); \ __EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \ diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 3419cbf2ad596..0757f23d35aa7 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -96,7 +96,6 @@ __start_interrupts: .globl system_reset_pSeries; system_reset_pSeries: - HMT_MEDIUM_PPR_DISCARD SET_SCRATCH0(r13) #ifdef CONFIG_PPC_P7_NAP BEGIN_FTR_SECTION @@ -164,7 +163,6 @@ machine_check_pSeries_1: * some code path might still want to branch into the original * vector */ - HMT_MEDIUM_PPR_DISCARD SET_SCRATCH0(r13) /* save r13 */ #ifdef CONFIG_PPC_P7_NAP BEGIN_FTR_SECTION @@ -199,7 +197,6 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) . = 0x300 .globl data_access_pSeries data_access_pSeries: - HMT_MEDIUM_PPR_DISCARD SET_SCRATCH0(r13) EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common, EXC_STD, KVMTEST, 0x300) @@ -207,7 +204,6 @@ data_access_pSeries: . = 0x380 .globl data_access_slb_pSeries data_access_slb_pSeries: - HMT_MEDIUM_PPR_DISCARD SET_SCRATCH0(r13) EXCEPTION_PROLOG_0(PACA_EXSLB) EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x380) @@ -239,7 +235,6 @@ data_access_slb_pSeries: . = 0x480 .globl instruction_access_slb_pSeries instruction_access_slb_pSeries: - HMT_MEDIUM_PPR_DISCARD SET_SCRATCH0(r13) EXCEPTION_PROLOG_0(PACA_EXSLB) EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x480) @@ -269,7 +264,6 @@ instruction_access_slb_pSeries: .globl hardware_interrupt_hv; hardware_interrupt_pSeries: hardware_interrupt_hv: - HMT_MEDIUM_PPR_DISCARD BEGIN_FTR_SECTION _MASKABLE_EXCEPTION_PSERIES(0x502, hardware_interrupt, EXC_HV, SOFTEN_TEST_HV) @@ -413,7 +407,6 @@ hv_facility_unavailable_trampoline: . = 0x1500 .global denorm_exception_hv denorm_exception_hv: - HMT_MEDIUM_PPR_DISCARD mtspr SPRN_SPRG_HSCRATCH0,r13 EXCEPTION_PROLOG_0(PACA_EXGEN) EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, 0x1500) @@ -527,7 +520,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) machine_check_pSeries: .globl machine_check_fwnmi machine_check_fwnmi: - HMT_MEDIUM_PPR_DISCARD SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0(PACA_EXMC) machine_check_pSeries_0: @@ -711,7 +703,6 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) .globl system_reset_fwnmi .align 7 system_reset_fwnmi: - HMT_MEDIUM_PPR_DISCARD SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD, NOTEST, 0x100) -- GitLab From d030a4b5eb7e9514c15b84a765bcc395cc26ab40 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 25 Nov 2015 14:25:17 +1100 Subject: [PATCH 1435/2855] powerpc/kernel: Open code HMT_MEDIUM_LOW_HAS_PPR HMT_MEDIUM_LOW_HAS_PPR is only used in once place, open code it. Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/ppc_asm.h | 5 ----- arch/powerpc/kernel/entry_64.S | 6 +++++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index dd0fc18d81031..67f05d4935a0b 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h @@ -418,11 +418,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) * PPR restore macros used in entry_64.S * Used for P7 or later processors */ -#define HMT_MEDIUM_LOW_HAS_PPR \ -BEGIN_FTR_SECTION_NESTED(944) \ - HMT_MEDIUM_LOW; \ -END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,944) - #define SET_DEFAULT_THREAD_PPR(ra, rb) \ BEGIN_FTR_SECTION_NESTED(945) \ lis ra,INIT_PPR@highest; /* default ppr=3 */ \ diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index c8b4225a0095a..651a65552ac80 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -223,7 +223,11 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) beq- 1f ACCOUNT_CPU_USER_EXIT(r11, r12) - HMT_MEDIUM_LOW_HAS_PPR + +BEGIN_FTR_SECTION + HMT_MEDIUM_LOW +END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) + ld r13,GPR13(r1) /* only restore r13 if returning to usermode */ 1: ld r2,GPR2(r1) ld r1,GPR1(r1) -- GitLab From d8725ce86c37fa750fc01f739ee4d4ced39167da Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 25 Nov 2015 14:25:18 +1100 Subject: [PATCH 1436/2855] powerpc/kernel: Open code SET_DEFAULT_THREAD_PPR This is only used in one location, open code it. Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/ppc_asm.h | 13 ------------- arch/powerpc/kernel/entry_64.S | 8 +++++++- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index 67f05d4935a0b..499d9f89435a2 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h @@ -413,19 +413,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) FTR_SECTION_ELSE_NESTED(848); \ mtocrf (FXM), RS; \ ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_NOEXECUTE, 848) - -/* - * PPR restore macros used in entry_64.S - * Used for P7 or later processors - */ -#define SET_DEFAULT_THREAD_PPR(ra, rb) \ -BEGIN_FTR_SECTION_NESTED(945) \ - lis ra,INIT_PPR@highest; /* default ppr=3 */ \ - ld rb,PACACURRENT(r13); \ - sldi ra,ra,32; /* 11- 13 bits are used for ppr */ \ - std ra,TASKTHREADPPR(rb); \ -END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,945) - #endif /* diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 651a65552ac80..0d525ce3717fb 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -316,7 +316,13 @@ syscall_exit_work: subi r12,r12,TI_FLAGS 4: /* Anything else left to do? */ - SET_DEFAULT_THREAD_PPR(r3, r10) /* Set thread.ppr = 3 */ +BEGIN_FTR_SECTION + lis r3,INIT_PPR@highest /* Set thread.ppr = 3 */ + ld r10,PACACURRENT(r13) + sldi r3,r3,32 /* bits 11-13 are used for ppr */ + std r3,TASKTHREADPPR(r10) +END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) + andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP) beq ret_from_except_lite -- GitLab From 2613265cb5b07a46bc01eb67202874136efd7049 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 16 Dec 2015 21:10:22 +1100 Subject: [PATCH 1437/2855] powerpc/kernel: Combine vec/loc for STD_EXCEPTION_PSERIES The STD_EXCEPTION_PSERIES macro takes both a vector number, and a location (memory address). However both are always identical, so combine them to save repeating ourselves. This does mean an exception handler must always exist at the location in memory that matches its vector number. But that's OK because this is the "STD" macro (standard), which does exactly that. We have other macros for the other cases, eg. STD_EXCEPTION_PSERIES_OOL (out of line). Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 4 ++-- arch/powerpc/kernel/exceptions-64s.S | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 60b2bbda212df..93ae809fe5ea3 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -333,8 +333,8 @@ do_kvm_##n: \ /* * Exception vectors. */ -#define STD_EXCEPTION_PSERIES(loc, vec, label) \ - . = loc; \ +#define STD_EXCEPTION_PSERIES(vec, label) \ + . = vec; \ .globl label##_pSeries; \ label##_pSeries: \ SET_SCRATCH0(r13); /* save r13 */ \ diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 0757f23d35aa7..7716cebf4b8ea 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -230,7 +230,7 @@ data_access_slb_pSeries: bctr #endif - STD_EXCEPTION_PSERIES(0x400, 0x400, instruction_access) + STD_EXCEPTION_PSERIES(0x400, instruction_access) . = 0x480 .globl instruction_access_slb_pSeries @@ -274,13 +274,13 @@ hardware_interrupt_hv: KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x500) ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) - STD_EXCEPTION_PSERIES(0x600, 0x600, alignment) + STD_EXCEPTION_PSERIES(0x600, alignment) KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x600) - STD_EXCEPTION_PSERIES(0x700, 0x700, program_check) + STD_EXCEPTION_PSERIES(0x700, program_check) KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x700) - STD_EXCEPTION_PSERIES(0x800, 0x800, fp_unavailable) + STD_EXCEPTION_PSERIES(0x800, fp_unavailable) KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x800) . = 0x900 @@ -293,7 +293,7 @@ decrementer_pSeries: MASKABLE_EXCEPTION_PSERIES(0xa00, 0xa00, doorbell_super) KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xa00) - STD_EXCEPTION_PSERIES(0xb00, 0xb00, trap_0b) + STD_EXCEPTION_PSERIES(0xb00, trap_0b) KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xb00) . = 0xc00 @@ -325,7 +325,7 @@ system_call_pSeries: SYSCALL_PSERIES_3 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xc00) - STD_EXCEPTION_PSERIES(0xd00, 0xd00, single_step) + STD_EXCEPTION_PSERIES(0xd00, single_step) KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xd00) /* At 0xe??? we have a bunch of hypervisor exceptions, we branch @@ -401,7 +401,7 @@ hv_facility_unavailable_trampoline: KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1202) #endif /* CONFIG_CBE_RAS */ - STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint) + STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint) KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x1300) . = 0x1500 @@ -428,7 +428,7 @@ denorm_exception_hv: KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1602) #endif /* CONFIG_CBE_RAS */ - STD_EXCEPTION_PSERIES(0x1700, 0x1700, altivec_assist) + STD_EXCEPTION_PSERIES(0x1700, altivec_assist) KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x1700) #ifdef CONFIG_CBE_RAS -- GitLab From 7207f43665b83ed7881c5111bc45475ccf5ce48b Mon Sep 17 00:00:00 2001 From: Laurent Dufour Date: Thu, 3 Dec 2015 11:29:19 +0100 Subject: [PATCH 1438/2855] powerpc/mm: Add page soft dirty tracking User space checkpoint and restart tool (CRIU) needs the page's change to be soft tracked. This allows to do a pre checkpoint and then dump only touched pages. This is done by using a newly assigned PTE bit (_PAGE_SOFT_DIRTY) when the page is backed in memory, and a new _PAGE_SWP_SOFT_DIRTY bit when the page is swapped out. To introduce a new PTE _PAGE_SOFT_DIRTY bit value common to hash 4k and hash 64k pte, the bits already defined in hash-*4k.h should be shifted left by one. The _PAGE_SWP_SOFT_DIRTY bit is dynamically put after the swap type in the swap pte. A check is added to ensure that the bit is not overwritten by _PAGE_HPTEFLAGS. Signed-off-by: Laurent Dufour CC: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/Kconfig | 2 ++ arch/powerpc/include/asm/book3s/64/hash-4k.h | 2 +- arch/powerpc/include/asm/book3s/64/hash-64k.h | 4 +-- arch/powerpc/include/asm/book3s/64/hash.h | 30 +++++++++++++++---- arch/powerpc/include/asm/book3s/64/pgtable.h | 26 ++++++++++++++++ 5 files changed, 56 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index db49e0d796b1b..6e03f85b11cd5 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -559,6 +559,7 @@ choice config PPC_4K_PAGES bool "4k page size" + select HAVE_ARCH_SOFT_DIRTY if CHECKPOINT_RESTORE && PPC_BOOK3S config PPC_16K_PAGES bool "16k page size" @@ -567,6 +568,7 @@ config PPC_16K_PAGES config PPC_64K_PAGES bool "64k page size" depends on !PPC_FSL_BOOK3E && (44x || PPC_STD_MMU_64 || PPC_BOOK3E_64) + select HAVE_ARCH_SOFT_DIRTY if CHECKPOINT_RESTORE && PPC_BOOK3S config PPC_256K_PAGES bool "256k page size" diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h index e59832c946094..ea0414d6659e0 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-4k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h @@ -52,7 +52,7 @@ _PAGE_F_SECOND | _PAGE_F_GIX) /* shift to put page number into pte */ -#define PTE_RPN_SHIFT (17) +#define PTE_RPN_SHIFT (18) #define _PAGE_4K_PFN 0 #ifndef __ASSEMBLY__ diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h index 9f9942998587c..9e55e3b1fef0e 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h @@ -25,8 +25,8 @@ #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) -#define _PAGE_COMBO 0x00020000 /* this is a combo 4k page */ -#define _PAGE_4K_PFN 0x00040000 /* PFN is for a single 4k page */ +#define _PAGE_COMBO 0x00040000 /* this is a combo 4k page */ +#define _PAGE_4K_PFN 0x00080000 /* PFN is for a single 4k page */ /* * Used to track subpage group valid if _PAGE_COMBO is set * This overloads _PAGE_F_GIX and _PAGE_F_SECOND diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 8b929e5317588..9e861b4378bd8 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -33,6 +33,7 @@ #define _PAGE_F_GIX_SHIFT 12 #define _PAGE_F_SECOND 0x08000 /* Whether to use secondary hash or not */ #define _PAGE_SPECIAL 0x10000 /* software: special page */ +#define _PAGE_SOFT_DIRTY 0x20000 /* software: software dirty tracking */ /* * THP pages can't be special. So use the _PAGE_SPECIAL @@ -50,7 +51,7 @@ */ #define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | \ _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SPLITTING | \ - _PAGE_THP_HUGE | _PAGE_PTE) + _PAGE_THP_HUGE | _PAGE_PTE | _PAGE_SOFT_DIRTY) #ifdef CONFIG_PPC_64K_PAGES #include @@ -136,14 +137,16 @@ * pgprot changes */ #define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \ - _PAGE_ACCESSED | _PAGE_SPECIAL | _PAGE_PTE) + _PAGE_ACCESSED | _PAGE_SPECIAL | _PAGE_PTE | \ + _PAGE_SOFT_DIRTY) /* * Mask of bits returned by pte_pgprot() */ #define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \ _PAGE_WRITETHRU | _PAGE_4K_PFN | \ _PAGE_USER | _PAGE_ACCESSED | \ - _PAGE_RW | _PAGE_DIRTY | _PAGE_EXEC) + _PAGE_RW | _PAGE_DIRTY | _PAGE_EXEC | \ + _PAGE_SOFT_DIRTY) /* * We define 2 sets of base prot bits, one for basic pages (ie, * cacheable kernel and user pages) and one for non cacheable @@ -339,7 +342,8 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) { unsigned long bits = pte_val(entry) & - (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC); + (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC | + _PAGE_SOFT_DIRTY); unsigned long old, tmp; @@ -366,6 +370,22 @@ static inline int pte_special(pte_t pte) { return !!(pte_val(pte) & _PAGE_SPECIA static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; } static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); } +#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY +static inline bool pte_soft_dirty(pte_t pte) +{ + return !!(pte_val(pte) & _PAGE_SOFT_DIRTY); +} +static inline pte_t pte_mksoft_dirty(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_SOFT_DIRTY); +} + +static inline pte_t pte_clear_soft_dirty(pte_t pte) +{ + return __pte(pte_val(pte) & ~_PAGE_SOFT_DIRTY); +} +#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */ + #ifdef CONFIG_NUMA_BALANCING /* * These work without NUMA balancing but the kernel does not care. See the @@ -424,7 +444,7 @@ static inline pte_t pte_mkwrite(pte_t pte) static inline pte_t pte_mkdirty(pte_t pte) { - return __pte(pte_val(pte) | _PAGE_DIRTY); + return __pte(pte_val(pte) | _PAGE_DIRTY | _PAGE_SOFT_DIRTY); } static inline pte_t pte_mkyoung(pte_t pte) diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index a2d4e0e370676..03c1a5a21c0ce 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -146,6 +146,7 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val) * We filter HPTEFLAGS on set_pte. \ */ \ BUILD_BUG_ON(_PAGE_HPTEFLAGS & (0x1f << _PAGE_BIT_SWAP_TYPE)); \ + BUILD_BUG_ON(_PAGE_HPTEFLAGS & _PAGE_SWP_SOFT_DIRTY); \ } while (0) /* * on pte we don't need handle RADIX_TREE_EXCEPTIONAL_SHIFT; @@ -161,6 +162,24 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) }) #define __swp_entry_to_pte(x) __pte((x).val) +#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY +#define _PAGE_SWP_SOFT_DIRTY (1UL << (SWP_TYPE_BITS + _PAGE_BIT_SWAP_TYPE)) +static inline pte_t pte_swp_mksoft_dirty(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_SWP_SOFT_DIRTY); +} +static inline bool pte_swp_soft_dirty(pte_t pte) +{ + return !!(pte_val(pte) & _PAGE_SWP_SOFT_DIRTY); +} +static inline pte_t pte_swp_clear_soft_dirty(pte_t pte) +{ + return __pte(pte_val(pte) & ~_PAGE_SWP_SOFT_DIRTY); +} +#else +#define _PAGE_SWP_SOFT_DIRTY 0 +#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */ + void pgtable_cache_add(unsigned shift, void (*ctor)(void *)); void pgtable_cache_init(void); @@ -201,6 +220,13 @@ static inline pte_t *pmdp_ptep(pmd_t *pmd) #define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd))) #define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd))) #define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd))) + +#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY +#define pmd_soft_dirty(pmd) pte_soft_dirty(pmd_pte(pmd)) +#define pmd_mksoft_dirty(pmd) pte_pmd(pte_mksoft_dirty(pmd_pte(pmd))) +#define pmd_clear_soft_dirty(pmd) pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd))) +#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */ + #ifdef CONFIG_NUMA_BALANCING static inline int pmd_protnone(pmd_t pmd) { -- GitLab From e80c4e7ca5aed7d2fa766191bcf4e83fa411c720 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Thu, 22 Oct 2015 12:03:08 +1100 Subject: [PATCH 1439/2855] powerpc/powernv: Fix M64 resource name in /proc/iomem The name of PCI root bus's M64 resource isn't initialized properly. When dumping "/proc/iomem", "" is seen for those M64 resources on PCI root buses. ~# cat /proc/iomem | grep -e "BAD" 3b0000000000-3b0fefffffff : 3b1000000000-3b1fefffffff : 3c0000000000-3c0fefffffff : 3c1000000000-3c1fefffffff : 3c2000000000-3c2fefffffff : This fixes the issue by setting the name of PCI root bus's M64 resource to that of PHB's device node full name. With the patch, no "" is seen from "/proc/iomem". Signed-off-by: Gavin Shan Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci-ioda.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index cdd5fa942aedc..272f6566d790c 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -357,6 +357,7 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb) } res = &hose->mem_resources[1]; + res->name = dn->full_name; res->start = of_translate_address(dn, r + 2); res->end = res->start + of_read_number(r + 4, 2) - 1; res->flags = (IORESOURCE_MEM | IORESOURCE_MEM_64 | IORESOURCE_PREFETCH); -- GitLab From 94973b24d61b03f99017f836d85e7d6739741bab Mon Sep 17 00:00:00 2001 From: Alistair Popple Date: Thu, 17 Dec 2015 13:43:11 +1100 Subject: [PATCH 1440/2855] Revert "powerpc/pci: Remove unused struct pci_dn.pcidev field" This commit removed the pcidev field from struct pci_dn as it was no longer in use by the kernel. However to support finding the association of Nvlink devices to GPU devices from the device-tree this field is required. This reverts commit 250c7b277c65 ("powerpc/pci: Remove unused struct pci_dn.pcidev field"). Signed-off-by: Alistair Popple Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/pci-bridge.h | 1 + arch/powerpc/platforms/powernv/pci-ioda.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 37fc53587bb45..54843ca5fa2bf 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -205,6 +205,7 @@ struct pci_dn { int pci_ext_config_space; /* for pci devices */ + struct pci_dev *pcidev; /* back-pointer to the pci device */ #ifdef CONFIG_EEH struct eeh_dev *edev; /* eeh device */ #endif diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 272f6566d790c..258ece5c0a8ff 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -1008,6 +1008,7 @@ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe) pci_name(dev)); continue; } + pdn->pcidev = dev; pdn->pe_number = pe->pe_number; pe->dma_weight += pnv_ioda_dma_weight(dev); if ((pe->flags & PNV_IODA_PE_BUS_ALL) && dev->subordinate) -- GitLab From a84bf321401ab206baafbbfd3bfad485a1a2c3b4 Mon Sep 17 00:00:00 2001 From: Alistair Popple Date: Thu, 17 Dec 2015 13:43:12 +1100 Subject: [PATCH 1441/2855] powerpc: Add __raw_rm_writeq() function Move __raw_rm_writeq() from platforms/powernv/pci-ioda.c to include/asm/io.h so that it can be used by other code. Signed-off-by: Alistair Popple Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/io.h | 11 +++++++++++ arch/powerpc/platforms/powernv/pci-ioda.c | 10 ---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index 5879fde56f3c9..6c1297ec374cc 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h @@ -385,6 +385,17 @@ static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr) { *(volatile unsigned long __force *)PCI_FIX_ADDR(addr) = v; } + +/* + * Real mode version of the above. stdcix is only supposed to be used + * in hypervisor real mode as per the architecture spec. + */ +static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr) +{ + __asm__ __volatile__("stdcix %0,0,%1" + : : "r" (val), "r" (paddr) : "memory"); +} + #endif /* __powerpc64__ */ /* diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 258ece5c0a8ff..7a3a30ee64683 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -116,16 +116,6 @@ static int __init iommu_setup(char *str) } early_param("iommu", iommu_setup); -/* - * stdcix is only supposed to be used in hypervisor real mode as per - * the architecture spec - */ -static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr) -{ - __asm__ __volatile__("stdcix %0,0,%1" - : : "r" (val), "r" (paddr) : "memory"); -} - static inline bool pnv_pci_is_mem_pref_64(unsigned long flags) { return ((flags & (IORESOURCE_MEM_64 | IORESOURCE_PREFETCH)) == -- GitLab From 5d2aa710e697244f5504125e4aa6e2cfcf6c4791 Mon Sep 17 00:00:00 2001 From: Alistair Popple Date: Thu, 17 Dec 2015 13:43:13 +1100 Subject: [PATCH 1442/2855] powerpc/powernv: Add support for Nvlink NPUs NVLink is a high speed interconnect that is used in conjunction with a PCI-E connection to create an interface between CPU and GPU that provides very high data bandwidth. A PCI-E connection to a GPU is used as the control path to initiate and report status of large data transfers sent via the NVLink. On IBM Power systems the NVLink processing unit (NPU) is similar to the existing PHB3. This patch adds support for a new NPU PHB type. DMA operations on the NPU are not supported as this patch sets the TCE translation tables to be the same as the related GPU PCIe device for each NVLink. Therefore all DMA operations are setup and controlled via the PCIe device. EEH is not presently supported for the NPU devices, although it may be added in future. Signed-off-by: Alistair Popple Signed-off-by: Gavin Shan Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/pci.h | 4 + arch/powerpc/platforms/powernv/Makefile | 2 +- arch/powerpc/platforms/powernv/npu-dma.c | 348 ++++++++++++++++++++++ arch/powerpc/platforms/powernv/pci-ioda.c | 138 ++++++++- arch/powerpc/platforms/powernv/pci.c | 4 + arch/powerpc/platforms/powernv/pci.h | 19 ++ 6 files changed, 502 insertions(+), 13 deletions(-) create mode 100644 arch/powerpc/platforms/powernv/npu-dma.c diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h index 3453bd8dc18f3..6f8065a7d487f 100644 --- a/arch/powerpc/include/asm/pci.h +++ b/arch/powerpc/include/asm/pci.h @@ -149,4 +149,8 @@ extern void pcibios_setup_phb_io_space(struct pci_controller *hose); extern void pcibios_scan_phb(struct pci_controller *hose); #endif /* __KERNEL__ */ + +extern struct pci_dev *pnv_pci_get_gpu_dev(struct pci_dev *npdev); +extern struct pci_dev *pnv_pci_get_npu_dev(struct pci_dev *gpdev, int index); + #endif /* __ASM_POWERPC_PCI_H */ diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index 1c8cdb6250e7c..ee774e8a48375 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile @@ -4,7 +4,7 @@ obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o obj-y += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o -obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o +obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o npu-dma.o obj-$(CONFIG_EEH) += eeh-powernv.o obj-$(CONFIG_PPC_SCOM) += opal-xscom.o obj-$(CONFIG_MEMORY_FAILURE) += opal-memory-errors.o diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c new file mode 100644 index 0000000000000..e85aa900f5c07 --- /dev/null +++ b/arch/powerpc/platforms/powernv/npu-dma.c @@ -0,0 +1,348 @@ +/* + * This file implements the DMA operations for NVLink devices. The NPU + * devices all point to the same iommu table as the parent PCI device. + * + * Copyright Alistair Popple, IBM Corporation 2015. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "powernv.h" +#include "pci.h" + +/* + * Other types of TCE cache invalidation are not functional in the + * hardware. + */ +#define TCE_KILL_INVAL_ALL PPC_BIT(0) + +static struct pci_dev *get_pci_dev(struct device_node *dn) +{ + return PCI_DN(dn)->pcidev; +} + +/* Given a NPU device get the associated PCI device. */ +struct pci_dev *pnv_pci_get_gpu_dev(struct pci_dev *npdev) +{ + struct device_node *dn; + struct pci_dev *gpdev; + + /* Get assoicated PCI device */ + dn = of_parse_phandle(npdev->dev.of_node, "ibm,gpu", 0); + if (!dn) + return NULL; + + gpdev = get_pci_dev(dn); + of_node_put(dn); + + return gpdev; +} +EXPORT_SYMBOL(pnv_pci_get_gpu_dev); + +/* Given the real PCI device get a linked NPU device. */ +struct pci_dev *pnv_pci_get_npu_dev(struct pci_dev *gpdev, int index) +{ + struct device_node *dn; + struct pci_dev *npdev; + + /* Get assoicated PCI device */ + dn = of_parse_phandle(gpdev->dev.of_node, "ibm,npu", index); + if (!dn) + return NULL; + + npdev = get_pci_dev(dn); + of_node_put(dn); + + return npdev; +} +EXPORT_SYMBOL(pnv_pci_get_npu_dev); + +#define NPU_DMA_OP_UNSUPPORTED() \ + dev_err_once(dev, "%s operation unsupported for NVLink devices\n", \ + __func__) + +static void *dma_npu_alloc(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag, + struct dma_attrs *attrs) +{ + NPU_DMA_OP_UNSUPPORTED(); + return NULL; +} + +static void dma_npu_free(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle, + struct dma_attrs *attrs) +{ + NPU_DMA_OP_UNSUPPORTED(); +} + +static dma_addr_t dma_npu_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction direction, + struct dma_attrs *attrs) +{ + NPU_DMA_OP_UNSUPPORTED(); + return 0; +} + +static int dma_npu_map_sg(struct device *dev, struct scatterlist *sglist, + int nelems, enum dma_data_direction direction, + struct dma_attrs *attrs) +{ + NPU_DMA_OP_UNSUPPORTED(); + return 0; +} + +static int dma_npu_dma_supported(struct device *dev, u64 mask) +{ + NPU_DMA_OP_UNSUPPORTED(); + return 0; +} + +static u64 dma_npu_get_required_mask(struct device *dev) +{ + NPU_DMA_OP_UNSUPPORTED(); + return 0; +} + +struct dma_map_ops dma_npu_ops = { + .map_page = dma_npu_map_page, + .map_sg = dma_npu_map_sg, + .alloc = dma_npu_alloc, + .free = dma_npu_free, + .dma_supported = dma_npu_dma_supported, + .get_required_mask = dma_npu_get_required_mask, +}; + +/* + * Returns the PE assoicated with the PCI device of the given + * NPU. Returns the linked pci device if pci_dev != NULL. + */ +static struct pnv_ioda_pe *get_gpu_pci_dev_and_pe(struct pnv_ioda_pe *npe, + struct pci_dev **gpdev) +{ + struct pnv_phb *phb; + struct pci_controller *hose; + struct pci_dev *pdev; + struct pnv_ioda_pe *pe; + struct pci_dn *pdn; + + if (npe->flags & PNV_IODA_PE_PEER) { + pe = npe->peers[0]; + pdev = pe->pdev; + } else { + pdev = pnv_pci_get_gpu_dev(npe->pdev); + if (!pdev) + return NULL; + + pdn = pci_get_pdn(pdev); + if (WARN_ON(!pdn || pdn->pe_number == IODA_INVALID_PE)) + return NULL; + + hose = pci_bus_to_host(pdev->bus); + phb = hose->private_data; + pe = &phb->ioda.pe_array[pdn->pe_number]; + } + + if (gpdev) + *gpdev = pdev; + + return pe; +} + +void pnv_npu_tce_invalidate_entire(struct pnv_ioda_pe *npe) +{ + struct pnv_phb *phb = npe->phb; + + if (WARN_ON(phb->type != PNV_PHB_NPU || + !phb->ioda.tce_inval_reg || + !(npe->flags & PNV_IODA_PE_DEV))) + return; + + mb(); /* Ensure previous TCE table stores are visible */ + __raw_writeq(cpu_to_be64(TCE_KILL_INVAL_ALL), + phb->ioda.tce_inval_reg); +} + +void pnv_npu_tce_invalidate(struct pnv_ioda_pe *npe, + struct iommu_table *tbl, + unsigned long index, + unsigned long npages, + bool rm) +{ + struct pnv_phb *phb = npe->phb; + + /* We can only invalidate the whole cache on NPU */ + unsigned long val = TCE_KILL_INVAL_ALL; + + if (WARN_ON(phb->type != PNV_PHB_NPU || + !phb->ioda.tce_inval_reg || + !(npe->flags & PNV_IODA_PE_DEV))) + return; + + mb(); /* Ensure previous TCE table stores are visible */ + if (rm) + __raw_rm_writeq(cpu_to_be64(val), + (__be64 __iomem *) phb->ioda.tce_inval_reg_phys); + else + __raw_writeq(cpu_to_be64(val), + phb->ioda.tce_inval_reg); +} + +void pnv_npu_init_dma_pe(struct pnv_ioda_pe *npe) +{ + struct pnv_ioda_pe *gpe; + struct pci_dev *gpdev; + int i, avail = -1; + + if (!npe->pdev || !(npe->flags & PNV_IODA_PE_DEV)) + return; + + gpe = get_gpu_pci_dev_and_pe(npe, &gpdev); + if (!gpe) + return; + + for (i = 0; i < PNV_IODA_MAX_PEER_PES; i++) { + /* Nothing to do if the PE is already connected. */ + if (gpe->peers[i] == npe) + return; + + if (!gpe->peers[i]) + avail = i; + } + + if (WARN_ON(avail < 0)) + return; + + gpe->peers[avail] = npe; + gpe->flags |= PNV_IODA_PE_PEER; + + /* + * We assume that the NPU devices only have a single peer PE + * (the GPU PCIe device PE). + */ + npe->peers[0] = gpe; + npe->flags |= PNV_IODA_PE_PEER; +} + +/* + * For the NPU we want to point the TCE table at the same table as the + * real PCI device. + */ +static void pnv_npu_disable_bypass(struct pnv_ioda_pe *npe) +{ + struct pnv_phb *phb = npe->phb; + struct pci_dev *gpdev; + struct pnv_ioda_pe *gpe; + void *addr; + unsigned int size; + int64_t rc; + + /* + * Find the assoicated PCI devices and get the dma window + * information from there. + */ + if (!npe->pdev || !(npe->flags & PNV_IODA_PE_DEV)) + return; + + gpe = get_gpu_pci_dev_and_pe(npe, &gpdev); + if (!gpe) + return; + + addr = (void *)gpe->table_group.tables[0]->it_base; + size = gpe->table_group.tables[0]->it_size << 3; + rc = opal_pci_map_pe_dma_window(phb->opal_id, npe->pe_number, + npe->pe_number, 1, __pa(addr), + size, 0x1000); + if (rc != OPAL_SUCCESS) + pr_warn("%s: Error %lld setting DMA window on PHB#%d-PE#%d\n", + __func__, rc, phb->hose->global_number, npe->pe_number); + + /* + * We don't initialise npu_pe->tce32_table as we always use + * dma_npu_ops which are nops. + */ + set_dma_ops(&npe->pdev->dev, &dma_npu_ops); +} + +/* + * Enable/disable bypass mode on the NPU. The NPU only supports one + * window per link, so bypass needs to be explicity enabled or + * disabled. Unlike for a PHB3 bypass and non-bypass modes can't be + * active at the same time. + */ +int pnv_npu_dma_set_bypass(struct pnv_ioda_pe *npe, bool enable) +{ + struct pnv_phb *phb = npe->phb; + int64_t rc = 0; + + if (phb->type != PNV_PHB_NPU || !npe->pdev) + return -EINVAL; + + if (enable) { + /* Enable the bypass window */ + phys_addr_t top = memblock_end_of_DRAM(); + + npe->tce_bypass_base = 0; + top = roundup_pow_of_two(top); + dev_info(&npe->pdev->dev, "Enabling bypass for PE %d\n", + npe->pe_number); + rc = opal_pci_map_pe_dma_window_real(phb->opal_id, + npe->pe_number, npe->pe_number, + npe->tce_bypass_base, top); + } else { + /* + * Disable the bypass window by replacing it with the + * TCE32 window. + */ + pnv_npu_disable_bypass(npe); + } + + return rc; +} + +int pnv_npu_dma_set_mask(struct pci_dev *npdev, u64 dma_mask) +{ + struct pci_controller *hose = pci_bus_to_host(npdev->bus); + struct pnv_phb *phb = hose->private_data; + struct pci_dn *pdn = pci_get_pdn(npdev); + struct pnv_ioda_pe *npe, *gpe; + struct pci_dev *gpdev; + uint64_t top; + bool bypass = false; + + if (WARN_ON(!pdn || pdn->pe_number == IODA_INVALID_PE)) + return -ENXIO; + + /* We only do bypass if it's enabled on the linked device */ + npe = &phb->ioda.pe_array[pdn->pe_number]; + gpe = get_gpu_pci_dev_and_pe(npe, &gpdev); + if (!gpe) + return -ENODEV; + + if (gpe->tce_bypass_enabled) { + top = gpe->tce_bypass_base + memblock_end_of_DRAM() - 1; + bypass = (dma_mask >= top); + } + + if (bypass) + dev_info(&npdev->dev, "Using 64-bit DMA iommu bypass\n"); + else + dev_info(&npdev->dev, "Using 32-bit DMA via iommu\n"); + + pnv_npu_dma_set_bypass(npe, bypass); + *npdev->dev.dma_mask = dma_mask; + + return 0; +} diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 7a3a30ee64683..323e1e58da93c 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -771,8 +771,12 @@ static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) return -ENXIO; } - /* Configure PELTV */ - pnv_ioda_set_peltv(phb, pe, true); + /* + * Configure PELTV. NPUs don't have a PELTV table so skip + * configuration on them. + */ + if (phb->type != PNV_PHB_NPU) + pnv_ioda_set_peltv(phb, pe, true); /* Setup reverse map */ for (rid = pe->rid; rid < rid_end; rid++) @@ -915,7 +919,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset) } #endif /* CONFIG_PCI_IOV */ -#if 0 static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev) { struct pci_controller *hose = pci_bus_to_host(dev->bus); @@ -932,11 +935,7 @@ static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev) if (pdn->pe_number != IODA_INVALID_PE) return NULL; - /* PE#0 has been pre-set */ - if (dev->bus->number == 0) - pe_num = 0; - else - pe_num = pnv_ioda_alloc_pe(phb); + pe_num = pnv_ioda_alloc_pe(phb); if (pe_num == IODA_INVALID_PE) { pr_warning("%s: Not enough PE# available, disabling device\n", pci_name(dev)); @@ -954,6 +953,7 @@ static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev) pci_dev_get(dev); pdn->pcidev = dev; pdn->pe_number = pe_num; + pe->flags = PNV_IODA_PE_DEV; pe->pdev = dev; pe->pbus = NULL; pe->tce32_seg = -1; @@ -984,7 +984,6 @@ static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev) return pe; } -#endif /* Useful for SRIOV case */ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe) { @@ -1075,6 +1074,18 @@ static void pnv_ioda_setup_bus_PE(struct pci_bus *bus, bool all) pnv_ioda_link_pe_by_weight(phb, pe); } +static void pnv_ioda_setup_dev_PEs(struct pci_bus *bus) +{ + struct pci_bus *child; + struct pci_dev *pdev; + + list_for_each_entry(pdev, &bus->devices, bus_list) + pnv_ioda_setup_dev_PE(pdev); + + list_for_each_entry(child, &bus->children, node) + pnv_ioda_setup_dev_PEs(child); +} + static void pnv_ioda_setup_PEs(struct pci_bus *bus) { struct pci_dev *dev; @@ -1111,7 +1122,15 @@ static void pnv_pci_ioda_setup_PEs(void) if (phb->reserve_m64_pe) phb->reserve_m64_pe(hose->bus, NULL, true); - pnv_ioda_setup_PEs(hose->bus); + /* + * On NPU PHB, we expect separate PEs for individual PCI + * functions. PCI bus dependent PEs are required for the + * remaining types of PHBs. + */ + if (phb->type == PNV_PHB_NPU) + pnv_ioda_setup_dev_PEs(hose->bus); + else + pnv_ioda_setup_PEs(hose->bus); } } @@ -1570,6 +1589,8 @@ static int pnv_pci_ioda_dma_set_mask(struct pci_dev *pdev, u64 dma_mask) struct pnv_ioda_pe *pe; uint64_t top; bool bypass = false; + struct pci_dev *linked_npu_dev; + int i; if (WARN_ON(!pdn || pdn->pe_number == IODA_INVALID_PE)) return -ENODEV;; @@ -1588,6 +1609,15 @@ static int pnv_pci_ioda_dma_set_mask(struct pci_dev *pdev, u64 dma_mask) set_dma_ops(&pdev->dev, &dma_iommu_ops); } *pdev->dev.dma_mask = dma_mask; + + /* Update peer npu devices */ + if (pe->flags & PNV_IODA_PE_PEER) + for (i = 0; pe->peers[i]; i++) { + linked_npu_dev = pe->peers[i]->pdev; + if (dma_get_mask(&linked_npu_dev->dev) != dma_mask) + dma_set_mask(&linked_npu_dev->dev, dma_mask); + } + return 0; } @@ -1732,12 +1762,23 @@ static inline void pnv_pci_ioda2_tce_invalidate_entire(struct pnv_ioda_pe *pe) /* 01xb - invalidate TCEs that match the specified PE# */ unsigned long val = (0x4ull << 60) | (pe->pe_number & 0xFF); struct pnv_phb *phb = pe->phb; + struct pnv_ioda_pe *npe; + int i; if (!phb->ioda.tce_inval_reg) return; mb(); /* Ensure above stores are visible */ __raw_writeq(cpu_to_be64(val), phb->ioda.tce_inval_reg); + + if (pe->flags & PNV_IODA_PE_PEER) + for (i = 0; i < PNV_IODA_MAX_PEER_PES; i++) { + npe = pe->peers[i]; + if (!npe || npe->phb->type != PNV_PHB_NPU) + continue; + + pnv_npu_tce_invalidate_entire(npe); + } } static void pnv_pci_ioda2_do_tce_invalidate(unsigned pe_number, bool rm, @@ -1772,15 +1813,28 @@ static void pnv_pci_ioda2_tce_invalidate(struct iommu_table *tbl, struct iommu_table_group_link *tgl; list_for_each_entry_rcu(tgl, &tbl->it_group_list, next) { + struct pnv_ioda_pe *npe; struct pnv_ioda_pe *pe = container_of(tgl->table_group, struct pnv_ioda_pe, table_group); __be64 __iomem *invalidate = rm ? (__be64 __iomem *)pe->phb->ioda.tce_inval_reg_phys : pe->phb->ioda.tce_inval_reg; + int i; pnv_pci_ioda2_do_tce_invalidate(pe->pe_number, rm, invalidate, tbl->it_page_shift, index, npages); + + if (pe->flags & PNV_IODA_PE_PEER) + /* Invalidate PEs using the same TCE table */ + for (i = 0; i < PNV_IODA_MAX_PEER_PES; i++) { + npe = pe->peers[i]; + if (!npe || npe->phb->type != PNV_PHB_NPU) + continue; + + pnv_npu_tce_invalidate(npe, tbl, index, + npages, rm); + } } } @@ -2428,10 +2482,17 @@ static void pnv_ioda_setup_dma(struct pnv_phb *phb) pe_info(pe, "DMA weight %d, assigned %d DMA32 segments\n", pe->dma_weight, segs); pnv_pci_ioda_setup_dma_pe(phb, pe, base, segs); - } else { + } else if (phb->type == PNV_PHB_IODA2) { pe_info(pe, "Assign DMA32 space\n"); segs = 0; pnv_pci_ioda2_setup_dma_pe(phb, pe); + } else if (phb->type == PNV_PHB_NPU) { + /* + * We initialise the DMA space for an NPU PHB + * after setup of the PHB is complete as we + * point the NPU TVT to the the same location + * as the PHB3 TVT. + */ } remaining -= segs; @@ -2873,6 +2934,11 @@ static void pnv_pci_ioda_setup_seg(void) list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { phb = hose->private_data; + + /* NPU PHB does not support IO or MMIO segmentation */ + if (phb->type == PNV_PHB_NPU) + continue; + list_for_each_entry(pe, &phb->ioda.pe_list, list) { pnv_ioda_setup_pe_seg(hose, pe); } @@ -2912,6 +2978,27 @@ static void pnv_pci_ioda_create_dbgfs(void) #endif /* CONFIG_DEBUG_FS */ } +static void pnv_npu_ioda_fixup(void) +{ + bool enable_bypass; + struct pci_controller *hose, *tmp; + struct pnv_phb *phb; + struct pnv_ioda_pe *pe; + + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { + phb = hose->private_data; + if (phb->type != PNV_PHB_NPU) + continue; + + list_for_each_entry(pe, &phb->ioda.pe_dma_list, dma_link) { + enable_bypass = dma_get_mask(&pe->pdev->dev) == + DMA_BIT_MASK(64); + pnv_npu_init_dma_pe(pe); + pnv_npu_dma_set_bypass(pe, enable_bypass); + } + } +} + static void pnv_pci_ioda_fixup(void) { pnv_pci_ioda_setup_PEs(); @@ -2924,6 +3011,9 @@ static void pnv_pci_ioda_fixup(void) eeh_init(); eeh_addr_cache_build(); #endif + + /* Link NPU IODA tables to their PCI devices. */ + pnv_npu_ioda_fixup(); } /* @@ -3038,6 +3128,19 @@ static const struct pci_controller_ops pnv_pci_ioda_controller_ops = { .shutdown = pnv_pci_ioda_shutdown, }; +static const struct pci_controller_ops pnv_npu_ioda_controller_ops = { + .dma_dev_setup = pnv_pci_dma_dev_setup, +#ifdef CONFIG_PCI_MSI + .setup_msi_irqs = pnv_setup_msi_irqs, + .teardown_msi_irqs = pnv_teardown_msi_irqs, +#endif + .enable_device_hook = pnv_pci_enable_device_hook, + .window_alignment = pnv_pci_window_alignment, + .reset_secondary_bus = pnv_pci_reset_secondary_bus, + .dma_set_mask = pnv_npu_dma_set_mask, + .shutdown = pnv_pci_ioda_shutdown, +}; + static void __init pnv_pci_init_ioda_phb(struct device_node *np, u64 hub_id, int ioda_type) { @@ -3093,6 +3196,8 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, phb->model = PNV_PHB_MODEL_P7IOC; else if (of_device_is_compatible(np, "ibm,power8-pciex")) phb->model = PNV_PHB_MODEL_PHB3; + else if (of_device_is_compatible(np, "ibm,power8-npu-pciex")) + phb->model = PNV_PHB_MODEL_NPU; else phb->model = PNV_PHB_MODEL_UNKNOWN; @@ -3193,7 +3298,11 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, * the child P2P bridges) can form individual PE. */ ppc_md.pcibios_fixup = pnv_pci_ioda_fixup; - hose->controller_ops = pnv_pci_ioda_controller_ops; + + if (phb->type == PNV_PHB_NPU) + hose->controller_ops = pnv_npu_ioda_controller_ops; + else + hose->controller_ops = pnv_pci_ioda_controller_ops; #ifdef CONFIG_PCI_IOV ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov_resources; @@ -3228,6 +3337,11 @@ void __init pnv_pci_init_ioda2_phb(struct device_node *np) pnv_pci_init_ioda_phb(np, 0, PNV_PHB_IODA2); } +void __init pnv_pci_init_npu_phb(struct device_node *np) +{ + pnv_pci_init_ioda_phb(np, 0, PNV_PHB_NPU); +} + void __init pnv_pci_init_ioda_hub(struct device_node *np) { struct device_node *phbn; diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index f2dd772342403..ff4e42d9d2599 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -807,6 +807,10 @@ void __init pnv_pci_init(void) for_each_compatible_node(np, NULL, "ibm,ioda2-phb") pnv_pci_init_ioda2_phb(np); + /* Look for NPU PHBs */ + for_each_compatible_node(np, NULL, "ibm,ioda2-npu-phb") + pnv_pci_init_npu_phb(np); + /* Setup the linkage between OF nodes and PHBs */ pci_devs_phb_init(); diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index c8ff50e907662..7f56313e8d722 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -7,6 +7,7 @@ enum pnv_phb_type { PNV_PHB_P5IOC2 = 0, PNV_PHB_IODA1 = 1, PNV_PHB_IODA2 = 2, + PNV_PHB_NPU = 3, }; /* Precise PHB model for error management */ @@ -15,6 +16,7 @@ enum pnv_phb_model { PNV_PHB_MODEL_P5IOC2, PNV_PHB_MODEL_P7IOC, PNV_PHB_MODEL_PHB3, + PNV_PHB_MODEL_NPU, }; #define PNV_PCI_DIAG_BUF_SIZE 8192 @@ -24,6 +26,7 @@ enum pnv_phb_model { #define PNV_IODA_PE_MASTER (1 << 3) /* Master PE in compound case */ #define PNV_IODA_PE_SLAVE (1 << 4) /* Slave PE in compound case */ #define PNV_IODA_PE_VF (1 << 5) /* PE for one VF */ +#define PNV_IODA_PE_PEER (1 << 6) /* PE has peers */ /* Data associated with a PE, including IOMMU tracking etc.. */ struct pnv_phb; @@ -31,6 +34,9 @@ struct pnv_ioda_pe { unsigned long flags; struct pnv_phb *phb; +#define PNV_IODA_MAX_PEER_PES 8 + struct pnv_ioda_pe *peers[PNV_IODA_MAX_PEER_PES]; + /* A PE can be associated with a single device or an * entire bus (& children). In the former case, pdev * is populated, in the later case, pbus is. @@ -229,6 +235,7 @@ extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl, extern void pnv_pci_init_p5ioc2_hub(struct device_node *np); extern void pnv_pci_init_ioda_hub(struct device_node *np); extern void pnv_pci_init_ioda2_phb(struct device_node *np); +extern void pnv_pci_init_npu_phb(struct device_node *np); extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl, __be64 *startp, __be64 *endp, bool rm); extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev); @@ -238,4 +245,16 @@ extern void pnv_pci_dma_dev_setup(struct pci_dev *pdev); extern int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type); extern void pnv_teardown_msi_irqs(struct pci_dev *pdev); +/* Nvlink functions */ +extern void pnv_npu_tce_invalidate_entire(struct pnv_ioda_pe *npe); +extern void pnv_npu_tce_invalidate(struct pnv_ioda_pe *npe, + struct iommu_table *tbl, + unsigned long index, + unsigned long npages, + bool rm); +extern void pnv_npu_init_dma_pe(struct pnv_ioda_pe *npe); +extern void pnv_npu_setup_dma_pe(struct pnv_ioda_pe *npe); +extern int pnv_npu_dma_set_bypass(struct pnv_ioda_pe *npe, bool enabled); +extern int pnv_npu_dma_set_mask(struct pci_dev *npdev, u64 dma_mask); + #endif /* __POWERNV_PCI_H */ -- GitLab From 4450022b4952ce67d2f3006b4c38e12a0f38cd77 Mon Sep 17 00:00:00 2001 From: Alistair Popple Date: Mon, 14 Dec 2015 14:31:24 +1100 Subject: [PATCH 1443/2855] powerpc/476fpe: Add support for kexec PPC476FPE has a different PVR from previous PPC476 processors. The kexec code checks the PVR in order to correctly setup the MMU. When the initial support for 476FPE processors was added the corresponding change in the kexec code was missed. This patch simply adds the check and solves the following bug on kexec: kexec: Starting new kernel Bye! Unable to handle kernel paging request for instruction fetch Faulting instruction address: 0xee9a50f8 cpu 0x0: Vector: 400 (Instruction Access) at [ee9d7d20] pc: ee9a50f8 lr: ee9a50e4 sp: ee9d7dd0 msr: 21020 current = 0xee40f000 pid = 960, comm = kexec enter ? for help [link register ] ee9a50e4 [ee9d7dd0] c0013748 default_machine_kexec+0x58/0x70 (unreliable) [ee9d7df0] c0012f04 machine_kexec+0x34/0x40 [ee9d7e00] c00aa1ec kernel_kexec+0x9c/0xb0 [ee9d7e20] c005d704 SyS_reboot+0x1f4/0x220 [ee9d7f40] c000db68 ret_from_syscall+0x0/0x3c Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/misc_32.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index ed3ab509facac..be8edd67f05be 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -743,6 +743,8 @@ relocate_new_kernel: /* Check for 47x cores */ mfspr r3,SPRN_PVR srwi r3,r3,16 + cmplwi cr0,r3,PVR_476FPE@h + beq setup_map_47x cmplwi cr0,r3,PVR_476@h beq setup_map_47x cmplwi cr0,r3,PVR_476_ISS@h -- GitLab From 1f859adb9253c201079962582253236e9b2cc3ce Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Fri, 23 Oct 2015 12:45:57 -0500 Subject: [PATCH 1444/2855] powerpc/pseries: Verify CPU doesn't exist before adding When DLPAR adding a CPU we should verify that the CPU does not already exist. Failure to do so can generate a kernel oops; [ 9.465585] kernel BUG at arch/powerpc/platforms/pseries/dlpar.c:382! [ 9.465796] Oops: Exception in kernel mode, sig: 5 [#1] This oops can be generated by causing a probe to be performed on a cpu by writing to the sysfs cpu probe file (/sys/devices/system/cpu/probe). This patch adds a check for the existence of cpu prior to probing the cpu so userspace doing the wrong thing won't trigger a BUG_ON(). Signed-off-by: Nathan Fontenot Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/dlpar.c | 43 +++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index f244dcb4f2cf0..fe6320db92551 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -381,6 +381,32 @@ out: } +static bool dlpar_cpu_exists(struct device_node *parent, u32 drc_index) +{ + struct device_node *child = NULL; + u32 my_drc_index; + bool found; + int rc; + + /* Assume cpu doesn't exist */ + found = false; + + for_each_child_of_node(parent, child) { + rc = of_property_read_u32(child, "ibm,my-drc-index", + &my_drc_index); + if (rc) + continue; + + if (my_drc_index == drc_index) { + of_node_put(child); + found = true; + break; + } + } + + return found; +} + static ssize_t dlpar_cpu_probe(const char *buf, size_t count) { struct device_node *dn, *parent; @@ -391,14 +417,23 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count) if (rc) return -EINVAL; - rc = dlpar_acquire_drc(drc_index); - if (rc) - return -EINVAL; - parent = of_find_node_by_path("/cpus"); if (!parent) return -ENODEV; + if (dlpar_cpu_exists(parent, drc_index)) { + of_node_put(parent); + printk(KERN_WARNING "CPU with drc index %x already exists\n", + drc_index); + return -EINVAL; + } + + rc = dlpar_acquire_drc(drc_index); + if (rc) { + of_node_put(parent); + return -EINVAL; + } + dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent); of_node_put(parent); if (!dn) { -- GitLab From 183deeea5871a6f750ec64ab1cff85fb089d38df Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Wed, 16 Dec 2015 14:50:21 -0600 Subject: [PATCH 1445/2855] powerpc/pseries: Consolidate CPU hotplug code to hotplug-cpu.c No functional changes, this patch is simply a move of the cpu hotplug code from pseries/dlpar.c to pseries/hotplug-cpu.c. This is in an effort to consolidate all of the cpu hotplug code in a common place. Signed-off-by: Nathan Fontenot Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/dlpar.c | 226 +------------------ arch/powerpc/platforms/pseries/hotplug-cpu.c | 218 ++++++++++++++++++ 2 files changed, 219 insertions(+), 225 deletions(-) diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index fe6320db92551..438fdbd7e40e5 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -20,7 +20,6 @@ #include #include "of_helpers.h" -#include "offline_states.h" #include "pseries.h" #include @@ -338,220 +337,6 @@ int dlpar_release_drc(u32 drc_index) return 0; } -#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE - -static int dlpar_online_cpu(struct device_node *dn) -{ - int rc = 0; - unsigned int cpu; - int len, nthreads, i; - const __be32 *intserv; - u32 thread; - - intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len); - if (!intserv) - return -EINVAL; - - nthreads = len / sizeof(u32); - - cpu_maps_update_begin(); - for (i = 0; i < nthreads; i++) { - thread = be32_to_cpu(intserv[i]); - for_each_present_cpu(cpu) { - if (get_hard_smp_processor_id(cpu) != thread) - continue; - BUG_ON(get_cpu_current_state(cpu) - != CPU_STATE_OFFLINE); - cpu_maps_update_done(); - rc = device_online(get_cpu_device(cpu)); - if (rc) - goto out; - cpu_maps_update_begin(); - - break; - } - if (cpu == num_possible_cpus()) - printk(KERN_WARNING "Could not find cpu to online " - "with physical id 0x%x\n", thread); - } - cpu_maps_update_done(); - -out: - return rc; - -} - -static bool dlpar_cpu_exists(struct device_node *parent, u32 drc_index) -{ - struct device_node *child = NULL; - u32 my_drc_index; - bool found; - int rc; - - /* Assume cpu doesn't exist */ - found = false; - - for_each_child_of_node(parent, child) { - rc = of_property_read_u32(child, "ibm,my-drc-index", - &my_drc_index); - if (rc) - continue; - - if (my_drc_index == drc_index) { - of_node_put(child); - found = true; - break; - } - } - - return found; -} - -static ssize_t dlpar_cpu_probe(const char *buf, size_t count) -{ - struct device_node *dn, *parent; - u32 drc_index; - int rc; - - rc = kstrtou32(buf, 0, &drc_index); - if (rc) - return -EINVAL; - - parent = of_find_node_by_path("/cpus"); - if (!parent) - return -ENODEV; - - if (dlpar_cpu_exists(parent, drc_index)) { - of_node_put(parent); - printk(KERN_WARNING "CPU with drc index %x already exists\n", - drc_index); - return -EINVAL; - } - - rc = dlpar_acquire_drc(drc_index); - if (rc) { - of_node_put(parent); - return -EINVAL; - } - - dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent); - of_node_put(parent); - if (!dn) { - dlpar_release_drc(drc_index); - return -EINVAL; - } - - rc = dlpar_attach_node(dn); - if (rc) { - dlpar_release_drc(drc_index); - dlpar_free_cc_nodes(dn); - return rc; - } - - rc = dlpar_online_cpu(dn); - if (rc) - return rc; - - return count; -} - -static int dlpar_offline_cpu(struct device_node *dn) -{ - int rc = 0; - unsigned int cpu; - int len, nthreads, i; - const __be32 *intserv; - u32 thread; - - intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len); - if (!intserv) - return -EINVAL; - - nthreads = len / sizeof(u32); - - cpu_maps_update_begin(); - for (i = 0; i < nthreads; i++) { - thread = be32_to_cpu(intserv[i]); - for_each_present_cpu(cpu) { - if (get_hard_smp_processor_id(cpu) != thread) - continue; - - if (get_cpu_current_state(cpu) == CPU_STATE_OFFLINE) - break; - - if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) { - set_preferred_offline_state(cpu, CPU_STATE_OFFLINE); - cpu_maps_update_done(); - rc = device_offline(get_cpu_device(cpu)); - if (rc) - goto out; - cpu_maps_update_begin(); - break; - - } - - /* - * The cpu is in CPU_STATE_INACTIVE. - * Upgrade it's state to CPU_STATE_OFFLINE. - */ - set_preferred_offline_state(cpu, CPU_STATE_OFFLINE); - BUG_ON(plpar_hcall_norets(H_PROD, thread) - != H_SUCCESS); - __cpu_die(cpu); - break; - } - if (cpu == num_possible_cpus()) - printk(KERN_WARNING "Could not find cpu to offline " - "with physical id 0x%x\n", thread); - } - cpu_maps_update_done(); - -out: - return rc; - -} - -static ssize_t dlpar_cpu_release(const char *buf, size_t count) -{ - struct device_node *dn; - u32 drc_index; - int rc; - - dn = of_find_node_by_path(buf); - if (!dn) - return -EINVAL; - - rc = of_property_read_u32(dn, "ibm,my-drc-index", &drc_index); - if (rc) { - of_node_put(dn); - return -EINVAL; - } - - rc = dlpar_offline_cpu(dn); - if (rc) { - of_node_put(dn); - return -EINVAL; - } - - rc = dlpar_release_drc(drc_index); - if (rc) { - of_node_put(dn); - return rc; - } - - rc = dlpar_detach_node(dn); - if (rc) { - dlpar_acquire_drc(drc_index); - return rc; - } - - of_node_put(dn); - - return count; -} - -#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */ - static int handle_dlpar_errorlog(struct pseries_hp_errorlog *hp_elog) { int rc; @@ -659,16 +444,7 @@ static CLASS_ATTR(dlpar, S_IWUSR, NULL, dlpar_store); static int __init pseries_dlpar_init(void) { - int rc; - -#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE - ppc_md.cpu_probe = dlpar_cpu_probe; - ppc_md.cpu_release = dlpar_cpu_release; -#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */ - - rc = sysfs_create_file(kernel_kobj, &class_attr_dlpar.attr); - - return rc; + return sysfs_create_file(kernel_kobj, &class_attr_dlpar.attr); } machine_device_initcall(pseries, pseries_dlpar_init); diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 86d2ecacb237e..66d8c2c64aa9b 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -32,6 +32,7 @@ #include #include +#include "pseries.h" #include "offline_states.h" /* This version can't take the spinlock, because it never returns */ @@ -334,6 +335,218 @@ static void pseries_remove_processor(struct device_node *np) cpu_maps_update_done(); } +#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE + +static int dlpar_online_cpu(struct device_node *dn) +{ + int rc = 0; + unsigned int cpu; + int len, nthreads, i; + const __be32 *intserv; + u32 thread; + + intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len); + if (!intserv) + return -EINVAL; + + nthreads = len / sizeof(u32); + + cpu_maps_update_begin(); + for (i = 0; i < nthreads; i++) { + thread = be32_to_cpu(intserv[i]); + for_each_present_cpu(cpu) { + if (get_hard_smp_processor_id(cpu) != thread) + continue; + BUG_ON(get_cpu_current_state(cpu) + != CPU_STATE_OFFLINE); + cpu_maps_update_done(); + rc = device_online(get_cpu_device(cpu)); + if (rc) + goto out; + cpu_maps_update_begin(); + + break; + } + if (cpu == num_possible_cpus()) + printk(KERN_WARNING "Could not find cpu to online " + "with physical id 0x%x\n", thread); + } + cpu_maps_update_done(); + +out: + return rc; + +} + +static bool dlpar_cpu_exists(struct device_node *parent, u32 drc_index) +{ + struct device_node *child = NULL; + u32 my_drc_index; + bool found; + int rc; + + /* Assume cpu doesn't exist */ + found = false; + + for_each_child_of_node(parent, child) { + rc = of_property_read_u32(child, "ibm,my-drc-index", + &my_drc_index); + if (rc) + continue; + + if (my_drc_index == drc_index) { + of_node_put(child); + found = true; + break; + } + } + + return found; +} + +static ssize_t dlpar_cpu_probe(const char *buf, size_t count) +{ + struct device_node *dn, *parent; + u32 drc_index; + int rc; + + rc = kstrtou32(buf, 0, &drc_index); + if (rc) + return -EINVAL; + + parent = of_find_node_by_path("/cpus"); + if (!parent) + return -ENODEV; + + if (dlpar_cpu_exists(parent, drc_index)) { + of_node_put(parent); + printk(KERN_WARNING "CPU with drc index %x already exists\n", + drc_index); + return -EINVAL; + } + + rc = dlpar_acquire_drc(drc_index); + if (rc) { + of_node_put(parent); + return -EINVAL; + } + + dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent); + of_node_put(parent); + if (!dn) + return -EINVAL; + + rc = dlpar_attach_node(dn); + if (rc) { + dlpar_release_drc(drc_index); + dlpar_free_cc_nodes(dn); + return rc; + } + + rc = dlpar_online_cpu(dn); + if (rc) + return rc; + + return count; +} + +static int dlpar_offline_cpu(struct device_node *dn) +{ + int rc = 0; + unsigned int cpu; + int len, nthreads, i; + const __be32 *intserv; + u32 thread; + + intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len); + if (!intserv) + return -EINVAL; + + nthreads = len / sizeof(u32); + + cpu_maps_update_begin(); + for (i = 0; i < nthreads; i++) { + thread = be32_to_cpu(intserv[i]); + for_each_present_cpu(cpu) { + if (get_hard_smp_processor_id(cpu) != thread) + continue; + + if (get_cpu_current_state(cpu) == CPU_STATE_OFFLINE) + break; + + if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) { + set_preferred_offline_state(cpu, + CPU_STATE_OFFLINE); + cpu_maps_update_done(); + rc = device_offline(get_cpu_device(cpu)); + if (rc) + goto out; + cpu_maps_update_begin(); + break; + + } + + /* + * The cpu is in CPU_STATE_INACTIVE. + * Upgrade it's state to CPU_STATE_OFFLINE. + */ + set_preferred_offline_state(cpu, CPU_STATE_OFFLINE); + BUG_ON(plpar_hcall_norets(H_PROD, thread) + != H_SUCCESS); + __cpu_die(cpu); + break; + } + if (cpu == num_possible_cpus()) + printk(KERN_WARNING "Could not find cpu to offline with physical id 0x%x\n", thread); + } + cpu_maps_update_done(); + +out: + return rc; + +} + +static ssize_t dlpar_cpu_release(const char *buf, size_t count) +{ + struct device_node *dn; + u32 drc_index; + int rc; + + dn = of_find_node_by_path(buf); + if (!dn) + return -EINVAL; + + rc = of_property_read_u32(dn, "ibm,my-drc-index", &drc_index); + if (rc) { + of_node_put(dn); + return -EINVAL; + } + + rc = dlpar_offline_cpu(dn); + if (rc) { + of_node_put(dn); + return -EINVAL; + } + + rc = dlpar_release_drc(drc_index); + if (rc) { + of_node_put(dn); + return rc; + } + + rc = dlpar_detach_node(dn); + if (rc) { + dlpar_acquire_drc(drc_index); + return rc; + } + + of_node_put(dn); + + return count; +} + +#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */ + static int pseries_smp_notifier(struct notifier_block *nb, unsigned long action, void *data) { @@ -380,6 +593,11 @@ static int __init pseries_cpu_hotplug_init(void) int cpu; int qcss_tok; +#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE + ppc_md.cpu_probe = dlpar_cpu_probe; + ppc_md.cpu_release = dlpar_cpu_release; +#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */ + for_each_node_by_name(np, "interrupt-controller") { typep = of_get_property(np, "compatible", NULL); if (strstr(typep, "open-pic")) { -- GitLab From d98389f375329b7a37d0e9211a1216d9141d7a5f Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Wed, 16 Dec 2015 14:51:26 -0600 Subject: [PATCH 1446/2855] powerpc/pseries: Factor out common cpu hotplug code Re-factor the cpu hotplug code to support doing cpu hotplug completely in the kernel and using the existing sysfs probe/release interfaces. This patch pulls out pieces of existing cpu hotplug code into common routines, dlpar_cpu_add() and dlpar_cpu_remove(), to be used by both interfaces. There are no functional changes introduced. Signed-off-by: Nathan Fontenot Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 70 +++++++++++--------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 66d8c2c64aa9b..6fb28cf229e7e 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -335,8 +335,6 @@ static void pseries_remove_processor(struct device_node *np) cpu_maps_update_done(); } -#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE - static int dlpar_online_cpu(struct device_node *dn) { int rc = 0; @@ -404,16 +402,11 @@ static bool dlpar_cpu_exists(struct device_node *parent, u32 drc_index) return found; } -static ssize_t dlpar_cpu_probe(const char *buf, size_t count) +static ssize_t dlpar_cpu_add(u32 drc_index) { struct device_node *dn, *parent; - u32 drc_index; int rc; - rc = kstrtou32(buf, 0, &drc_index); - if (rc) - return -EINVAL; - parent = of_find_node_by_path("/cpus"); if (!parent) return -ENODEV; @@ -444,10 +437,7 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count) } rc = dlpar_online_cpu(dn); - if (rc) - return rc; - - return count; + return rc; } static int dlpar_offline_cpu(struct device_node *dn) @@ -506,6 +496,41 @@ out: } +static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index) +{ + int rc; + + rc = dlpar_offline_cpu(dn); + if (rc) + return -EINVAL; + + rc = dlpar_release_drc(drc_index); + if (rc) + return rc; + + rc = dlpar_detach_node(dn); + if (rc) + dlpar_acquire_drc(drc_index); + + return rc; +} + +#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE + +static ssize_t dlpar_cpu_probe(const char *buf, size_t count) +{ + u32 drc_index; + int rc; + + rc = kstrtou32(buf, 0, &drc_index); + if (rc) + return -EINVAL; + + rc = dlpar_cpu_add(drc_index); + + return rc ? rc : count; +} + static ssize_t dlpar_cpu_release(const char *buf, size_t count) { struct device_node *dn; @@ -522,27 +547,10 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count) return -EINVAL; } - rc = dlpar_offline_cpu(dn); - if (rc) { - of_node_put(dn); - return -EINVAL; - } - - rc = dlpar_release_drc(drc_index); - if (rc) { - of_node_put(dn); - return rc; - } - - rc = dlpar_detach_node(dn); - if (rc) { - dlpar_acquire_drc(drc_index); - return rc; - } - + rc = dlpar_cpu_remove(dn, drc_index); of_node_put(dn); - return count; + return rc ? rc : count; } #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */ -- GitLab From e666ae0b10aaa1c961c928558bafc28bc049ac87 Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Wed, 16 Dec 2015 14:52:39 -0600 Subject: [PATCH 1447/2855] powerpc/pseries: Update CPU hotplug error recovery Update the cpu dlpar add/remove paths to do better error recovery when a failure occurs during the add/remove operation. Signed-off-by: Nathan Fontenot Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 76 ++++++++++++++++---- 1 file changed, 63 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 6fb28cf229e7e..a54aee982589f 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -18,6 +18,8 @@ * 2 of the License, or (at your option) any later version. */ +#define pr_fmt(fmt) "pseries-hotplug-cpu: " fmt + #include #include #include @@ -405,38 +407,67 @@ static bool dlpar_cpu_exists(struct device_node *parent, u32 drc_index) static ssize_t dlpar_cpu_add(u32 drc_index) { struct device_node *dn, *parent; - int rc; + int rc, saved_rc; + + pr_debug("Attempting to add CPU, drc index: %x\n", drc_index); parent = of_find_node_by_path("/cpus"); - if (!parent) + if (!parent) { + pr_warn("Failed to find CPU root node \"/cpus\"\n"); return -ENODEV; + } if (dlpar_cpu_exists(parent, drc_index)) { of_node_put(parent); - printk(KERN_WARNING "CPU with drc index %x already exists\n", - drc_index); + pr_warn("CPU with drc index %x already exists\n", drc_index); return -EINVAL; } rc = dlpar_acquire_drc(drc_index); if (rc) { + pr_warn("Failed to acquire DRC, rc: %d, drc index: %x\n", + rc, drc_index); of_node_put(parent); return -EINVAL; } dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent); of_node_put(parent); - if (!dn) + if (!dn) { + pr_warn("Failed call to configure-connector, drc index: %x\n", + drc_index); + dlpar_release_drc(drc_index); return -EINVAL; + } rc = dlpar_attach_node(dn); if (rc) { - dlpar_release_drc(drc_index); - dlpar_free_cc_nodes(dn); - return rc; + saved_rc = rc; + pr_warn("Failed to attach node %s, rc: %d, drc index: %x\n", + dn->name, rc, drc_index); + + rc = dlpar_release_drc(drc_index); + if (!rc) + dlpar_free_cc_nodes(dn); + + return saved_rc; } rc = dlpar_online_cpu(dn); + if (rc) { + saved_rc = rc; + pr_warn("Failed to online cpu %s, rc: %d, drc index: %x\n", + dn->name, rc, drc_index); + + rc = dlpar_detach_node(dn); + if (!rc) + dlpar_release_drc(drc_index); + + return saved_rc; + } + + pr_debug("Successfully added CPU %s, drc index: %x\n", dn->name, + drc_index); return rc; } @@ -500,19 +531,38 @@ static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index) { int rc; + pr_debug("Attemping to remove CPU %s, drc index: %x\n", + dn->name, drc_index); + rc = dlpar_offline_cpu(dn); - if (rc) + if (rc) { + pr_warn("Failed to offline CPU %s, rc: %d\n", dn->name, rc); return -EINVAL; + } rc = dlpar_release_drc(drc_index); - if (rc) + if (rc) { + pr_warn("Failed to release drc (%x) for CPU %s, rc: %d\n", + drc_index, dn->name, rc); + dlpar_online_cpu(dn); return rc; + } rc = dlpar_detach_node(dn); - if (rc) - dlpar_acquire_drc(drc_index); + if (rc) { + int saved_rc = rc; - return rc; + pr_warn("Failed to detach CPU %s, rc: %d", dn->name, rc); + + rc = dlpar_acquire_drc(drc_index); + if (!rc) + dlpar_online_cpu(dn); + + return saved_rc; + } + + pr_debug("Successfully removed CPU, drc index: %x\n", drc_index); + return 0; } #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE -- GitLab From ac71380071d19d4ac7cd5f9fe4168d7109902cd5 Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Wed, 16 Dec 2015 14:54:05 -0600 Subject: [PATCH 1448/2855] powerpc/pseries: Add CPU dlpar remove functionality Add the ability to dlpar remove CPUs via hotplug rtas events, either by specifying the drc-index of the CPU to remove or providing a count of cpus to remove. To remove multiple cpus in a single request we create a list of possible DR (Dynamic Reconfiguration) cpus and their drc indexes that can be removed. We can then traverse the list remove each cpu and easily clean up in any cases of failure. Signed-off-by: Nathan Fontenot Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 147 +++++++++++++++++++ arch/powerpc/platforms/pseries/pseries.h | 9 ++ 2 files changed, 156 insertions(+) diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index a54aee982589f..86c7ae3db50ed 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -26,6 +26,7 @@ #include /* for idle_task_exit */ #include #include +#include #include #include #include @@ -565,6 +566,152 @@ static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index) return 0; } +static struct device_node *cpu_drc_index_to_dn(u32 drc_index) +{ + struct device_node *dn; + u32 my_index; + int rc; + + for_each_node_by_type(dn, "cpu") { + rc = of_property_read_u32(dn, "ibm,my-drc-index", &my_index); + if (rc) + continue; + + if (my_index == drc_index) + break; + } + + return dn; +} + +static int dlpar_cpu_remove_by_index(u32 drc_index) +{ + struct device_node *dn; + int rc; + + dn = cpu_drc_index_to_dn(drc_index); + if (!dn) { + pr_warn("Cannot find CPU (drc index %x) to remove\n", + drc_index); + return -ENODEV; + } + + rc = dlpar_cpu_remove(dn, drc_index); + of_node_put(dn); + return rc; +} + +static int find_dlpar_cpus_to_remove(u32 *cpu_drcs, int cpus_to_remove) +{ + struct device_node *dn; + int cpus_found = 0; + int rc; + + /* We want to find cpus_to_remove + 1 CPUs to ensure we do not + * remove the last CPU. + */ + for_each_node_by_type(dn, "cpu") { + cpus_found++; + + if (cpus_found > cpus_to_remove) { + of_node_put(dn); + break; + } + + /* Note that cpus_found is always 1 ahead of the index + * into the cpu_drcs array, so we use cpus_found - 1 + */ + rc = of_property_read_u32(dn, "ibm,my-drc-index", + &cpu_drcs[cpus_found - 1]); + if (rc) { + pr_warn("Error occurred getting drc-index for %s\n", + dn->name); + of_node_put(dn); + return -1; + } + } + + if (cpus_found < cpus_to_remove) { + pr_warn("Failed to find enough CPUs (%d of %d) to remove\n", + cpus_found, cpus_to_remove); + } else if (cpus_found == cpus_to_remove) { + pr_warn("Cannot remove all CPUs\n"); + } + + return cpus_found; +} + +static int dlpar_cpu_remove_by_count(u32 cpus_to_remove) +{ + u32 *cpu_drcs; + int cpus_found; + int cpus_removed = 0; + int i, rc; + + pr_debug("Attempting to hot-remove %d CPUs\n", cpus_to_remove); + + cpu_drcs = kcalloc(cpus_to_remove, sizeof(*cpu_drcs), GFP_KERNEL); + if (!cpu_drcs) + return -EINVAL; + + cpus_found = find_dlpar_cpus_to_remove(cpu_drcs, cpus_to_remove); + if (cpus_found <= cpus_to_remove) { + kfree(cpu_drcs); + return -EINVAL; + } + + for (i = 0; i < cpus_to_remove; i++) { + rc = dlpar_cpu_remove_by_index(cpu_drcs[i]); + if (rc) + break; + + cpus_removed++; + } + + if (cpus_removed != cpus_to_remove) { + pr_warn("CPU hot-remove failed, adding back removed CPUs\n"); + + for (i = 0; i < cpus_removed; i++) + dlpar_cpu_add(cpu_drcs[i]); + + rc = -EINVAL; + } else { + rc = 0; + } + + kfree(cpu_drcs); + return rc; +} + +int dlpar_cpu(struct pseries_hp_errorlog *hp_elog) +{ + u32 count, drc_index; + int rc; + + count = hp_elog->_drc_u.drc_count; + drc_index = hp_elog->_drc_u.drc_index; + + lock_device_hotplug(); + + switch (hp_elog->action) { + case PSERIES_HP_ELOG_ACTION_REMOVE: + if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT) + rc = dlpar_cpu_remove_by_count(count); + else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX) + rc = dlpar_cpu_remove_by_index(drc_index); + else + rc = -EINVAL; + break; + default: + pr_err("Invalid action (%d) specified\n", hp_elog->action); + rc = -EINVAL; + break; + } + + unlock_device_hotplug(); + return rc; +} + #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE static ssize_t dlpar_cpu_probe(const char *buf, size_t count) diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 8411c27293e44..7aa83f00ac620 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h @@ -73,6 +73,15 @@ static inline int dlpar_memory(struct pseries_hp_errorlog *hp_elog) } #endif +#ifdef CONFIG_HOTPLUG_CPU +int dlpar_cpu(struct pseries_hp_errorlog *hp_elog); +#else +static inline int dlpar_cpu(struct pseries_hp_errorlog *hp_elog) +{ + return -EOPNOTSUPP; +} +#endif + /* PCI root bridge prepare function override for pseries */ struct pci_host_bridge; int pseries_root_bridge_prepare(struct pci_host_bridge *bridge); -- GitLab From 90edf184b9b7275d248f1b9902733a0000e4ecf8 Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Wed, 16 Dec 2015 14:55:07 -0600 Subject: [PATCH 1449/2855] powerpc/pseries: Add CPU dlpar add functionality Add the ability to hotplug add cpus via rtas hotplug events by either specifying the drc index of the CPU to add, or providing a count of the number of CPUs to add. Signed-off-by: Nathan Fontenot Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 116 +++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 86c7ae3db50ed..32274f72fe3fc 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -405,6 +405,27 @@ static bool dlpar_cpu_exists(struct device_node *parent, u32 drc_index) return found; } +static bool valid_cpu_drc_index(struct device_node *parent, u32 drc_index) +{ + bool found = false; + int rc, index; + + index = 0; + while (!found) { + u32 drc; + + rc = of_property_read_u32_index(parent, "ibm,drc-indexes", + index++, &drc); + if (rc) + break; + + if (drc == drc_index) + found = true; + } + + return found; +} + static ssize_t dlpar_cpu_add(u32 drc_index) { struct device_node *dn, *parent; @@ -424,6 +445,12 @@ static ssize_t dlpar_cpu_add(u32 drc_index) return -EINVAL; } + if (!valid_cpu_drc_index(parent, drc_index)) { + of_node_put(parent); + pr_warn("Cannot find CPU (drc index %x) to add.\n", drc_index); + return -EINVAL; + } + rc = dlpar_acquire_drc(drc_index); if (rc) { pr_warn("Failed to acquire DRC, rc: %d, drc index: %x\n", @@ -683,6 +710,87 @@ static int dlpar_cpu_remove_by_count(u32 cpus_to_remove) return rc; } +static int find_dlpar_cpus_to_add(u32 *cpu_drcs, u32 cpus_to_add) +{ + struct device_node *parent; + int cpus_found = 0; + int index, rc; + + parent = of_find_node_by_path("/cpus"); + if (!parent) { + pr_warn("Could not find CPU root node in device tree\n"); + kfree(cpu_drcs); + return -1; + } + + /* Search the ibm,drc-indexes array for possible CPU drcs to + * add. Note that the format of the ibm,drc-indexes array is + * the number of entries in the array followed by the array + * of drc values so we start looking at index = 1. + */ + index = 1; + while (cpus_found < cpus_to_add) { + u32 drc; + + rc = of_property_read_u32_index(parent, "ibm,drc-indexes", + index++, &drc); + if (rc) + break; + + if (dlpar_cpu_exists(parent, drc)) + continue; + + cpu_drcs[cpus_found++] = drc; + } + + of_node_put(parent); + return cpus_found; +} + +static int dlpar_cpu_add_by_count(u32 cpus_to_add) +{ + u32 *cpu_drcs; + int cpus_added = 0; + int cpus_found; + int i, rc; + + pr_debug("Attempting to hot-add %d CPUs\n", cpus_to_add); + + cpu_drcs = kcalloc(cpus_to_add, sizeof(*cpu_drcs), GFP_KERNEL); + if (!cpu_drcs) + return -EINVAL; + + cpus_found = find_dlpar_cpus_to_add(cpu_drcs, cpus_to_add); + if (cpus_found < cpus_to_add) { + pr_warn("Failed to find enough CPUs (%d of %d) to add\n", + cpus_found, cpus_to_add); + kfree(cpu_drcs); + return -EINVAL; + } + + for (i = 0; i < cpus_to_add; i++) { + rc = dlpar_cpu_add(cpu_drcs[i]); + if (rc) + break; + + cpus_added++; + } + + if (cpus_added < cpus_to_add) { + pr_warn("CPU hot-add failed, removing any added CPUs\n"); + + for (i = 0; i < cpus_added; i++) + dlpar_cpu_remove_by_index(cpu_drcs[i]); + + rc = -EINVAL; + } else { + rc = 0; + } + + kfree(cpu_drcs); + return rc; +} + int dlpar_cpu(struct pseries_hp_errorlog *hp_elog) { u32 count, drc_index; @@ -702,6 +810,14 @@ int dlpar_cpu(struct pseries_hp_errorlog *hp_elog) else rc = -EINVAL; break; + case PSERIES_HP_ELOG_ACTION_ADD: + if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT) + rc = dlpar_cpu_add_by_count(count); + else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX) + rc = dlpar_cpu_add(drc_index); + else + rc = -EINVAL; + break; default: pr_err("Invalid action (%d) specified\n", hp_elog->action); rc = -EINVAL; -- GitLab From e9d764f803964a54ca7da4a67d124fe824ebd80a Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Wed, 16 Dec 2015 14:56:02 -0600 Subject: [PATCH 1450/2855] powerpc/pseries: Enable kernel CPU dlpar from sysfs Enable new kernel cpu hotplug functionality by allowing cpu dlpar requests to be initiated from sysfs. Signed-off-by: Nathan Fontenot Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/dlpar.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 438fdbd7e40e5..2b93ae8d557a3 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -356,6 +356,9 @@ static int handle_dlpar_errorlog(struct pseries_hp_errorlog *hp_elog) case PSERIES_HP_ELOG_RESOURCE_MEM: rc = dlpar_memory(hp_elog); break; + case PSERIES_HP_ELOG_RESOURCE_CPU: + rc = dlpar_cpu(hp_elog); + break; default: pr_warn_ratelimited("Invalid resource (%d) specified\n", hp_elog->resource); @@ -385,6 +388,9 @@ static ssize_t dlpar_store(struct class *class, struct class_attribute *attr, if (!strncmp(arg, "memory", 6)) { hp_elog->resource = PSERIES_HP_ELOG_RESOURCE_MEM; arg += strlen("memory "); + } else if (!strncmp(arg, "cpu", 3)) { + hp_elog->resource = PSERIES_HP_ELOG_RESOURCE_CPU; + arg += strlen("cpu "); } else { pr_err("Invalid resource specified: \"%s\"\n", buf); rc = -EINVAL; -- GitLab From 1b855e167b90fcb353977c08932d0a52eb8ae5b9 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Thu, 17 Dec 2015 19:41:00 +1100 Subject: [PATCH 1451/2855] powerpc: Add missing calls to va_end() cppcheck picked up that there were a couple of missing va_end() calls in functions using va_start(). Signed-off-by: Daniel Axtens Reviewed-by: Russell Currey Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/prom_init.c | 1 + arch/powerpc/platforms/powermac/bootx_init.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 92dea8df6b26d..da5192590c445 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -389,6 +389,7 @@ static void __init prom_printf(const char *format, ...) break; } } + va_end(args); } diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c index 76f5013c35e5c..c3c9bbb3573ae 100644 --- a/arch/powerpc/platforms/powermac/bootx_init.c +++ b/arch/powerpc/platforms/powermac/bootx_init.c @@ -84,6 +84,7 @@ static void __init bootx_printf(const char *format, ...) break; } } + va_end(args); } #else /* CONFIG_BOOTX_TEXT */ static void __init bootx_printf(const char *format, ...) {} -- GitLab From be99c84300950e876074916b215b511f69f83d3b Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 17 Dec 2015 09:55:41 -0600 Subject: [PATCH 1452/2855] usb: of: fix build breakage on !OF If OF is disabled, we will try to define a stub for of_usb_get_dr_mode_by_phy(), however that missed a static inline annotation which made us redefine the stub over and over again. Fix that. Fixes: 98bfb3946695 ("usb: of: add an api to get dr_mode by the phy node") Signed-off-by: Felipe Balbi --- include/linux/usb/of.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h index 3805757dcdc26..974bce93aa289 100644 --- a/include/linux/usb/of.h +++ b/include/linux/usb/of.h @@ -17,7 +17,8 @@ bool of_usb_host_tpl_support(struct device_node *np); int of_usb_update_otg_caps(struct device_node *np, struct usb_otg_caps *otg_caps); #else -enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np) +static inline enum usb_dr_mode +of_usb_get_dr_mode_by_phy(struct device_node *phy_np) { return USB_DR_MODE_UNKNOWN; } -- GitLab From fcd71d9cc6e301bdbd71829b79e80168473ca609 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 8 Dec 2015 14:17:55 +0530 Subject: [PATCH 1453/2855] of: fix declaration of of_io_request_and_map We are having build failure with linux-next for sparc allmodconfig with the error messages: drivers/built-in.o: In function `meson6_timer_init': meson6_timer.c:(.init.text+0x5fe8): undefined reference to `of_io_request_and_map' drivers/built-in.o: In function `mtk_timer_init': mtk_timer.c:(.init.text+0x6af0): undefined reference to `of_io_request_and_map' drivers/built-in.o: In function `asm9260_timer_init': asm9260_timer.c:(.init.text+0x6c48): undefined reference to `of_io_request_and_map' CONFIG_OF is defined for sparc so it is expected that we have a definition of of_io_request_and_map() but of/address.c is only compiled if it is !SPARC. In other words, CONFIG_OF_ADDRESS is not defined for sparc so we get the build failure. Fixes: e572f844ca66 ("clocksource/drivers/meson6: Add the COMPILE_TEST option") Fixes: bec8c4617611 ("clocksource/drivers/mediatek: Add the COMPILE_TEST option") Fixes: 4a373b45f94a ("clocksource/drivers/asm9260: Add the COMPILE_TEST option") Acked-by: Daniel Lezcano Signed-off-by: Sudip Mukherjee [robh: move include of io.h out of ifdef's] Signed-off-by: Rob Herring --- include/linux/of_address.h | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/include/linux/of_address.h b/include/linux/of_address.h index 507daad0bc8d5..01c0a556448b2 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h @@ -3,6 +3,7 @@ #include #include #include +#include struct of_pci_range_parser { struct device_node *node; @@ -36,6 +37,8 @@ extern struct device_node *of_find_matching_node_by_address( const struct of_device_id *matches, u64 base_address); extern void __iomem *of_iomap(struct device_node *device, int index); +void __iomem *of_io_request_and_map(struct device_node *device, + int index, const char *name); /* Extract an address from a device, returns the region size and * the address space flags too. The PCI version uses a BAR number @@ -57,6 +60,11 @@ extern int of_dma_get_range(struct device_node *np, u64 *dma_addr, u64 *paddr, u64 *size); extern bool of_dma_is_coherent(struct device_node *np); #else /* CONFIG_OF_ADDRESS */ +static inline void __iomem *of_io_request_and_map(struct device_node *device, + int index, const char *name) +{ + return IOMEM_ERR_PTR(-EINVAL); +} static inline u64 of_translate_address(struct device_node *np, const __be32 *addr) @@ -112,12 +120,7 @@ static inline bool of_dma_is_coherent(struct device_node *np) extern int of_address_to_resource(struct device_node *dev, int index, struct resource *r); void __iomem *of_iomap(struct device_node *node, int index); -void __iomem *of_io_request_and_map(struct device_node *device, - int index, const char *name); #else - -#include - static inline int of_address_to_resource(struct device_node *dev, int index, struct resource *r) { @@ -128,12 +131,6 @@ static inline void __iomem *of_iomap(struct device_node *device, int index) { return NULL; } - -static inline void __iomem *of_io_request_and_map(struct device_node *device, - int index, const char *name) -{ - return IOMEM_ERR_PTR(-EINVAL); -} #endif #if defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI) -- GitLab From 33fbd5100de6d0a87f354ecf5ec0486ba01a6da7 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 17 Dec 2015 17:14:44 +0800 Subject: [PATCH 1454/2855] f2fs: stat dirty regular/symlink inodes Add to stat dirty regular and symlink inode for showing in debugfs. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 7 ++----- fs/f2fs/debug.c | 6 +++++- fs/f2fs/f2fs.h | 13 +++++++------ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index a037bbd89dc64..53044ea8bb5d8 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -733,13 +733,11 @@ static void __add_dirty_inode(struct inode *inode, enum inode_type type) set_inode_flag(fi, flag); list_add_tail(&fi->dirty_list, &sbi->inode_list[type]); - if (type == DIR_INODE) - stat_inc_dirty_dir(sbi); + stat_inc_dirty_inode(sbi, type); } static void __remove_dirty_inode(struct inode *inode, enum inode_type type) { - struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_inode_info *fi = F2FS_I(inode); int flag = (type == DIR_INODE) ? FI_DIRTY_DIR : FI_DIRTY_FILE; @@ -749,8 +747,7 @@ static void __remove_dirty_inode(struct inode *inode, enum inode_type type) list_del_init(&fi->dirty_list); clear_inode_flag(fi, flag); - if (type == DIR_INODE) - stat_dec_dirty_dir(sbi); + stat_dec_dirty_inode(F2FS_I_SB(inode), type); } void update_dirty_page(struct inode *inode, struct page *page) diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index f4a7b9e9416d3..bb307e642fdde 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -42,8 +42,10 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->ext_node = atomic_read(&sbi->total_ext_node); si->ndirty_node = get_pages(sbi, F2FS_DIRTY_NODES); si->ndirty_dent = get_pages(sbi, F2FS_DIRTY_DENTS); - si->ndirty_dirs = sbi->n_dirty_dirs; si->ndirty_meta = get_pages(sbi, F2FS_DIRTY_META); + si->ndirty_data = get_pages(sbi, F2FS_DIRTY_DATA); + si->ndirty_dirs = sbi->ndirty_inode[DIR_INODE]; + si->ndirty_files = sbi->ndirty_inode[FILE_INODE]; si->inmem_pages = get_pages(sbi, F2FS_INMEM_PAGES); si->wb_pages = get_pages(sbi, F2FS_WRITEBACK); si->total_count = (int)sbi->user_block_count / sbi->blocks_per_seg; @@ -298,6 +300,8 @@ static int stat_show(struct seq_file *s, void *v) si->ndirty_node, si->node_pages); seq_printf(s, " - dents: %4d in dirs:%4d\n", si->ndirty_dent, si->ndirty_dirs); + seq_printf(s, " - datas: %4d in files:%4d\n", + si->ndirty_data, si->ndirty_files); seq_printf(s, " - meta: %4d in %4d\n", si->ndirty_meta, si->meta_pages); seq_printf(s, " - NATs: %9d/%9d\n - SITs: %9d/%9d\n", diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index b1fb8f73fe427..19beabefd8395 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -818,7 +818,7 @@ struct f2fs_sb_info { atomic_t inline_inode; /* # of inline_data inodes */ atomic_t inline_dir; /* # of inline_dentry inodes */ int bg_gc; /* background gc calls */ - unsigned int n_dirty_dirs; /* # of dir inodes */ + unsigned int ndirty_inode[NR_INODE_TYPE]; /* # of dirty inodes */ #endif unsigned int last_victim[2]; /* last victim segment # */ spinlock_t stat_lock; /* lock for stat operations */ @@ -1888,7 +1888,8 @@ struct f2fs_stat_info { unsigned long long hit_largest, hit_cached, hit_rbtree; unsigned long long hit_total, total_ext; int ext_tree, ext_node; - int ndirty_node, ndirty_dent, ndirty_dirs, ndirty_meta; + int ndirty_node, ndirty_meta; + int ndirty_dent, ndirty_dirs, ndirty_data, ndirty_files; int nats, dirty_nats, sits, dirty_sits, fnids; int total_count, utilization; int bg_gc, inmem_pages, wb_pages; @@ -1921,8 +1922,8 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi) #define stat_inc_cp_count(si) ((si)->cp_count++) #define stat_inc_call_count(si) ((si)->call_count++) #define stat_inc_bggc_count(sbi) ((sbi)->bg_gc++) -#define stat_inc_dirty_dir(sbi) ((sbi)->n_dirty_dirs++) -#define stat_dec_dirty_dir(sbi) ((sbi)->n_dirty_dirs--) +#define stat_inc_dirty_inode(sbi, type) ((sbi)->ndirty_inode[type]++) +#define stat_dec_dirty_inode(sbi, type) ((sbi)->ndirty_inode[type]--) #define stat_inc_total_hit(sbi) (atomic64_inc(&(sbi)->total_hit_ext)) #define stat_inc_rbtree_node_hit(sbi) (atomic64_inc(&(sbi)->read_hit_rbtree)) #define stat_inc_largest_node_hit(sbi) (atomic64_inc(&(sbi)->read_hit_largest)) @@ -2003,8 +2004,8 @@ void f2fs_destroy_root_stats(void); #define stat_inc_cp_count(si) #define stat_inc_call_count(si) #define stat_inc_bggc_count(si) -#define stat_inc_dirty_dir(sbi) -#define stat_dec_dirty_dir(sbi) +#define stat_inc_dirty_inode(sbi, type) +#define stat_dec_dirty_inode(sbi, type) #define stat_inc_total_hit(sb) #define stat_inc_rbtree_node_hit(sb) #define stat_inc_largest_node_hit(sbi) -- GitLab From 36b35a0dbe904a06e94154f29db0d0e218420c98 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 17 Dec 2015 17:13:28 +0800 Subject: [PATCH 1455/2855] f2fs: support data flush in background Previously, when finishing a checkpoint, we have persisted all fs meta info including meta inode, node inode, dentry page of directory inode, so, after a sudden power cut, f2fs can recover from last checkpoint with full directory structure. But during checkpoint, we didn't flush dirty pages of regular and symlink inode, so such dirty datas still in memory will be lost in that moment of power off. In order to reduce the chance of lost data, this patch enables f2fs_balance_fs_bg with the ability of data flushing. It will try to flush user data before starting a checkpoint. So user's data written after last checkpoint which may not be fsynced could be saved. When we mount with data_flush option, after every period of cp_interval (could be configured in sysfs: /sys/fs/f2fs/device/cp_interval) seconds user data could be flushed into device once f2fs_balance_fs_bg was called in kworker thread or gc thread. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/segment.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 5fa519f028602..c2474509e5de5 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -291,8 +291,11 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi) if (!available_free_memory(sbi, NAT_ENTRIES) || excess_prefree_segs(sbi) || !available_free_memory(sbi, INO_ENTRIES) || - jiffies > sbi->cp_expires) + jiffies > sbi->cp_expires) { + if (test_opt(sbi, DATA_FLUSH)) + sync_dirty_inodes(sbi, FILE_INODE); f2fs_sync_fs(sbi->sb, true); + } } static int issue_flush_thread(void *data) -- GitLab From 7df3a4318d07ba520b4a8eddad29e9ac748b0a19 Mon Sep 17 00:00:00 2001 From: Fan Li Date: Thu, 17 Dec 2015 13:20:59 +0800 Subject: [PATCH 1456/2855] f2fs: optimize the flow of f2fs_map_blocks check map->m_len right after it changes to avoid excess call to update dnode_of_data. Signed-off-by: Fan li Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 69 ++++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 292a06cbea072..e34b1bdfc9955 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -573,6 +573,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int err = 0, ofs = 1; struct extent_info ei; bool allocated = false; + block_t blkaddr; map->m_len = 0; map->m_flags = 0; @@ -636,6 +637,9 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, pgofs++; get_next: + if (map->m_len >= maxblocks) + goto sync_out; + if (dn.ofs_in_node >= end_offset) { if (allocated) sync_inode_page(&dn); @@ -653,44 +657,43 @@ get_next: end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); } - if (maxblocks > map->m_len) { - block_t blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); + blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); - if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR) { - if (create) { - if (unlikely(f2fs_cp_error(sbi))) { - err = -EIO; - goto sync_out; - } - err = __allocate_data_block(&dn); - if (err) - goto sync_out; - allocated = true; - map->m_flags |= F2FS_MAP_NEW; - blkaddr = dn.data_blkaddr; - } else { - /* - * we only merge preallocated unwritten blocks - * for fiemap. - */ - if (flag != F2FS_GET_BLOCK_FIEMAP || - blkaddr != NEW_ADDR) - goto sync_out; + if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR) { + if (create) { + if (unlikely(f2fs_cp_error(sbi))) { + err = -EIO; + goto sync_out; } + err = __allocate_data_block(&dn); + if (err) + goto sync_out; + allocated = true; + map->m_flags |= F2FS_MAP_NEW; + blkaddr = dn.data_blkaddr; + } else { + /* + * we only merge preallocated unwritten blocks + * for fiemap. + */ + if (flag != F2FS_GET_BLOCK_FIEMAP || + blkaddr != NEW_ADDR) + goto sync_out; } + } - /* Give more consecutive addresses for the readahead */ - if ((map->m_pblk != NEW_ADDR && - blkaddr == (map->m_pblk + ofs)) || - (map->m_pblk == NEW_ADDR && - blkaddr == NEW_ADDR)) { - ofs++; - dn.ofs_in_node++; - pgofs++; - map->m_len++; - goto get_next; - } + /* Give more consecutive addresses for the readahead */ + if ((map->m_pblk != NEW_ADDR && + blkaddr == (map->m_pblk + ofs)) || + (map->m_pblk == NEW_ADDR && + blkaddr == NEW_ADDR)) { + ofs++; + dn.ofs_in_node++; + pgofs++; + map->m_len++; + goto get_next; } + sync_out: if (allocated) sync_inode_page(&dn); -- GitLab From 4cf185379b7504d640c9dd72f959f081b25f6ea2 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 17 Dec 2015 17:17:16 +0800 Subject: [PATCH 1457/2855] f2fs: add a tracepoint for sync_dirty_inodes This patch adds a tracepoint for sync_dirty_inodes. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 8 ++++++++ include/trace/events/f2fs.h | 38 +++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 53044ea8bb5d8..fdd43f71d2c6c 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -803,6 +803,11 @@ void sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type) struct list_head *head; struct inode *inode; struct f2fs_inode_info *fi; + bool is_dir = (type == DIR_INODE); + + trace_f2fs_sync_dirty_inodes_enter(sbi->sb, is_dir, + get_pages(sbi, is_dir ? + F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA)); retry: if (unlikely(f2fs_cp_error(sbi))) return; @@ -812,6 +817,9 @@ retry: head = &sbi->inode_list[type]; if (list_empty(head)) { spin_unlock(&sbi->inode_lock[type]); + trace_f2fs_sync_dirty_inodes_exit(sbi->sb, is_dir, + get_pages(sbi, is_dir ? + F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA)); return; } fi = list_entry(head->next, struct f2fs_inode_info, dirty_list); diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index 00b4a6308249e..a1b488809f069 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -1265,6 +1265,44 @@ TRACE_EVENT(f2fs_destroy_extent_tree, __entry->node_cnt) ); +DECLARE_EVENT_CLASS(f2fs_sync_dirty_inodes, + + TP_PROTO(struct super_block *sb, int type, int count), + + TP_ARGS(sb, type, count), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(int, type) + __field(int, count) + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->type = type; + __entry->count = count; + ), + + TP_printk("dev = (%d,%d), %s, dirty count = %d", + show_dev(__entry), + show_file_type(__entry->type), + __entry->count) +); + +DEFINE_EVENT(f2fs_sync_dirty_inodes, f2fs_sync_dirty_inodes_enter, + + TP_PROTO(struct super_block *sb, int type, int count), + + TP_ARGS(sb, type, count) +); + +DEFINE_EVENT(f2fs_sync_dirty_inodes, f2fs_sync_dirty_inodes_exit, + + TP_PROTO(struct super_block *sb, int type, int count), + + TP_ARGS(sb, type, count) +); + #endif /* _TRACE_F2FS_H */ /* This part must be outside protection */ -- GitLab From b7d518e6f4c6d8a0b66effe3bda22417b7dc1e04 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 17 Dec 2015 13:09:32 +0100 Subject: [PATCH 1458/2855] i2c: emev: select I2C slave support Until we have proper support to make I2C slave support fully optional, select it to prevent build errors on randconfigs. Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index eaa7b4a0e4843..0299dfa746a38 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -532,6 +532,7 @@ config I2C_EG20T config I2C_EMEV2 tristate "EMMA Mobile series I2C adapter" depends on HAVE_CLK + select I2C_SLAVE help If you say yes to this option, support will be included for the I2C interface on the Renesas Electronics EM/EV family of processors. -- GitLab From 54177ccfbe95fcf250a89508a705bfe4706e3b86 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 17 Dec 2015 13:32:36 +0100 Subject: [PATCH 1459/2855] i2c: make i2c_parse_fw_timings() always visible This function used to be DT only, so it lived inside a CONFIG_OF block. Now it uses device attributes and must be moved outside of it. No further code changes, only one whitespace improvement. Reported-by: Jim Davis Signed-off-by: Wolfram Sang Reviewed-by: Mika Westerberg Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core.c | 104 ++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index b34c412bd2c24..7349b00f41017 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1439,58 +1439,6 @@ static void of_i2c_register_devices(struct i2c_adapter *adap) } } -/** - * i2c_parse_fw_timings - get I2C related timing parameters from firmware - * @dev: The device to scan for I2C timing properties - * @t: the i2c_timings struct to be filled with values - * @use_defaults: bool to use sane defaults derived from the I2C specification - * when properties are not found, otherwise use 0 - * - * Scan the device for the generic I2C properties describing timing parameters - * for the signal and fill the given struct with the results. If a property was - * not found and use_defaults was true, then maximum timings are assumed which - * are derived from the I2C specification. If use_defaults is not used, the - * results will be 0, so drivers can apply their own defaults later. The latter - * is mainly intended for avoiding regressions of existing drivers which want - * to switch to this function. New drivers almost always should use the defaults. - */ - -void i2c_parse_fw_timings(struct device *dev, struct i2c_timings *t, bool use_defaults) -{ - int ret; - - memset(t, 0, sizeof(*t)); - - ret = device_property_read_u32(dev, "clock-frequency", &t->bus_freq_hz); - if (ret && use_defaults) - t->bus_freq_hz = 100000; - - ret = device_property_read_u32(dev, "i2c-scl-rising-time-ns", &t->scl_rise_ns); - if (ret && use_defaults) { - if (t->bus_freq_hz <= 100000) - t->scl_rise_ns = 1000; - else if (t->bus_freq_hz <= 400000) - t->scl_rise_ns = 300; - else - t->scl_rise_ns = 120; - } - - ret = device_property_read_u32(dev, "i2c-scl-falling-time-ns", &t->scl_fall_ns); - if (ret && use_defaults) { - if (t->bus_freq_hz <= 400000) - t->scl_fall_ns = 300; - else - t->scl_fall_ns = 120; - } - - device_property_read_u32(dev, "i2c-scl-internal-delay-ns", &t->scl_int_delay_ns); - - ret = device_property_read_u32(dev, "i2c-sda-falling-time-ns", &t->sda_fall_ns); - if (ret && use_defaults) - t->sda_fall_ns = t->scl_fall_ns; -} -EXPORT_SYMBOL_GPL(i2c_parse_fw_timings); - static int of_dev_node_match(struct device *dev, void *data) { return dev->of_node == data; @@ -1892,6 +1840,58 @@ void i2c_del_adapter(struct i2c_adapter *adap) } EXPORT_SYMBOL(i2c_del_adapter); +/** + * i2c_parse_fw_timings - get I2C related timing parameters from firmware + * @dev: The device to scan for I2C timing properties + * @t: the i2c_timings struct to be filled with values + * @use_defaults: bool to use sane defaults derived from the I2C specification + * when properties are not found, otherwise use 0 + * + * Scan the device for the generic I2C properties describing timing parameters + * for the signal and fill the given struct with the results. If a property was + * not found and use_defaults was true, then maximum timings are assumed which + * are derived from the I2C specification. If use_defaults is not used, the + * results will be 0, so drivers can apply their own defaults later. The latter + * is mainly intended for avoiding regressions of existing drivers which want + * to switch to this function. New drivers almost always should use the defaults. + */ + +void i2c_parse_fw_timings(struct device *dev, struct i2c_timings *t, bool use_defaults) +{ + int ret; + + memset(t, 0, sizeof(*t)); + + ret = device_property_read_u32(dev, "clock-frequency", &t->bus_freq_hz); + if (ret && use_defaults) + t->bus_freq_hz = 100000; + + ret = device_property_read_u32(dev, "i2c-scl-rising-time-ns", &t->scl_rise_ns); + if (ret && use_defaults) { + if (t->bus_freq_hz <= 100000) + t->scl_rise_ns = 1000; + else if (t->bus_freq_hz <= 400000) + t->scl_rise_ns = 300; + else + t->scl_rise_ns = 120; + } + + ret = device_property_read_u32(dev, "i2c-scl-falling-time-ns", &t->scl_fall_ns); + if (ret && use_defaults) { + if (t->bus_freq_hz <= 400000) + t->scl_fall_ns = 300; + else + t->scl_fall_ns = 120; + } + + device_property_read_u32(dev, "i2c-scl-internal-delay-ns", &t->scl_int_delay_ns); + + ret = device_property_read_u32(dev, "i2c-sda-falling-time-ns", &t->sda_fall_ns); + if (ret && use_defaults) + t->sda_fall_ns = t->scl_fall_ns; +} +EXPORT_SYMBOL_GPL(i2c_parse_fw_timings); + /* ------------------------------------------------------------------------- */ int i2c_for_each_dev(void *data, int (*fn)(struct device *, void *)) -- GitLab From 8f9cfdd359478ea70da0144b0cb407a4734f14cd Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 9 Dec 2015 13:22:05 +0300 Subject: [PATCH 1460/2855] HID: wacom: bitwise vs logical ORs Smatch complains that these should probably be bitwise ORs instead of logical. It doesn't matter for "prox" but it makes a difference for "strip1" and "strip2". Fixes: c7f0522a1ad1 ('HID: wacom: Slim down wacom_intuos_pad processing') Signed-off-by: Dan Carpenter Reviewed-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index bec23001c219e..22d32259e1f1a 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -545,12 +545,12 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) ((data[6] & 0x0F) << 4) | (data[5] & 0x0F); } - strip1 = (data[1] << 8) || data[2]; - strip2 = (data[3] << 8) || data[4]; + strip1 = (data[1] << 8) | data[2]; + strip2 = (data[3] << 8) | data[4]; } - prox = (buttons & ~(~0 << nbuttons)) || (keys & ~(~0 << nkeys)) || - (ring1 & 0x80) || (ring2 & 0x80) || strip1 || strip2; + prox = (buttons & ~(~0 << nbuttons)) | (keys & ~(~0 << nkeys)) | + (ring1 & 0x80) | (ring2 & 0x80) | strip1 | strip2; wacom_report_numbered_buttons(input, nbuttons, buttons); -- GitLab From f73d08d073a4bcb8bb1bd88444f07f39c84400da Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Wed, 16 Dec 2015 13:37:33 -0800 Subject: [PATCH 1461/2855] HID: wacom: Limit touchstrip data to 13 bits Commit c7f0522 uses sixteen bits of data in the construction of 'strip1' and 'strip2'. This can cause problems in some cases, however, since some tablets store flags in the MSB of data[2] and data[4] that should not be included in these values. This restores the 0x1f mask that used prior to c7f0522. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 22d32259e1f1a..cf878106f4ed8 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -545,8 +545,8 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) ((data[6] & 0x0F) << 4) | (data[5] & 0x0F); } - strip1 = (data[1] << 8) | data[2]; - strip2 = (data[3] << 8) | data[4]; + strip1 = ((data[1] & 0x1f) << 8) | data[2]; + strip2 = ((data[3] & 0x1f) << 8) | data[4]; } prox = (buttons & ~(~0 << nbuttons)) | (keys & ~(~0 << nkeys)) | -- GitLab From 03a0dc546be3fa6091214bd2c05d678d3e8d67df Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Wed, 16 Dec 2015 13:37:34 -0800 Subject: [PATCH 1462/2855] HID: wacom: Report 'strip2' values in ABS_RY Commit c7f0522 accidentally used ABS_RX for reporting both 'strip1' and 'strip2', when the latter should actually be reported through ABS_RY. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index cf878106f4ed8..94dffde5f3d5c 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -558,7 +558,7 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) input_report_key(input, KEY_PROG1 + i, keys & (1 << i)); input_report_abs(input, ABS_RX, strip1); - input_report_abs(input, ABS_RX, strip2); + input_report_abs(input, ABS_RY, strip2); input_report_abs(input, ABS_WHEEL, ring1 & 0x7f ? ring1 : 0); input_report_abs(input, ABS_THROTTLE, ring2 & 0x07 ? ring2 : 0); -- GitLab From aaae03e4f7f0c641a258dde855ab677c9b58b155 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Wed, 16 Dec 2015 13:37:35 -0800 Subject: [PATCH 1463/2855] HID: wacom: Fix touchring value reporting Commit c7f0522 reports incorrect touchring values to userspace. This is due to its incorrect handling of the 'touched' bit present in the 'ring1' and 'ring2' variables. Instead of using this bit when determining if a value should be sent, the ABS_WHEEL and ABS_INPUT check (different?!) portions of the position bits. Furthermore, the full values of 'ring1' and 'ring2' are reported to userspace, despite the 'touched' flag needing to be trimmed beforehand. This commit addresses both issues. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 94dffde5f3d5c..23212af7fa767 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -560,8 +560,8 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) input_report_abs(input, ABS_RX, strip1); input_report_abs(input, ABS_RY, strip2); - input_report_abs(input, ABS_WHEEL, ring1 & 0x7f ? ring1 : 0); - input_report_abs(input, ABS_THROTTLE, ring2 & 0x07 ? ring2 : 0); + input_report_abs(input, ABS_WHEEL, (ring1 & 0x80) ? (ring1 & 0x7f) : 0); + input_report_abs(input, ABS_THROTTLE, (ring2 & 0x80) ? (ring2 & 0x7f) : 0); input_report_key(input, wacom->tool[1], prox ? 1 : 0); input_report_abs(input, ABS_MISC, prox ? PAD_DEVICE_ID : 0); -- GitLab From 0402b6b77a35205072087d7f774e4c2b2797f8c3 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Wed, 16 Dec 2015 13:37:36 -0800 Subject: [PATCH 1464/2855] HID: wacom: Fix pad button range for CINTIQ_COMPANION_2 Commit c7f0522 incorrectly constructs the 'buttons' variable for the CINTIQ_COMPANION_2 case. The high nybble of data[2] is shifted four bits too far, leaving the bits associated with BTN_7 through BTN_A unset. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 23212af7fa767..f70660465a54f 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -516,7 +516,7 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) * d-pad down -> data[4] & 0x80 * d-pad center -> data[3] & 0x01 */ - buttons = ((data[2] & 0xF0) << 7) | + buttons = ((data[2] >> 4) << 7) | ((data[1] & 0x04) << 6) | ((data[2] & 0x0F) << 2) | (data[1] & 0x03); -- GitLab From 5d9374cf5f66ebe38007bccf0b4adc14f0013663 Mon Sep 17 00:00:00 2001 From: "Alexander E. Patrakov" Date: Mon, 14 Dec 2015 17:42:26 +0500 Subject: [PATCH 1465/2855] HID: input: ignore the battery in OKLICK Laser BTmouse This mouse, when asked about the battery, ceases to report movements and clicks. So just don't ask. Signed-off-by: Alexander E. Patrakov Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 2ba6bf69b7d0c..0869faef13086 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -303,6 +303,7 @@ static enum power_supply_property hidinput_battery_props[] = { #define HID_BATTERY_QUIRK_PERCENT (1 << 0) /* always reports percent */ #define HID_BATTERY_QUIRK_FEATURE (1 << 1) /* ask for feature report */ +#define HID_BATTERY_QUIRK_IGNORE (1 << 2) /* completely ignore the battery */ static const struct hid_device_id hid_battery_quirks[] = { { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, @@ -320,6 +321,9 @@ static const struct hid_device_id hid_battery_quirks[] = { { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, + USB_DEVICE_ID_ELECOM_BM084), + HID_BATTERY_QUIRK_IGNORE }, {} }; @@ -408,6 +412,14 @@ static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, if (dev->battery != NULL) goto out; /* already initialized? */ + quirks = find_battery_quirk(dev); + + hid_dbg(dev, "device %x:%x:%x %d quirks %d\n", + dev->bus, dev->vendor, dev->product, dev->version, quirks); + + if (quirks & HID_BATTERY_QUIRK_IGNORE) + goto out; + psy_desc = kzalloc(sizeof(*psy_desc), GFP_KERNEL); if (psy_desc == NULL) goto out; @@ -424,11 +436,6 @@ static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, psy_desc->use_for_apm = 0; psy_desc->get_property = hidinput_get_battery_property; - quirks = find_battery_quirk(dev); - - hid_dbg(dev, "device %x:%x:%x %d quirks %d\n", - dev->bus, dev->vendor, dev->product, dev->version, quirks); - min = field->logical_minimum; max = field->logical_maximum; -- GitLab From 0a88d60784440da1ef8f72156cb9547aeebf56cf Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 27 Nov 2015 20:29:22 -0800 Subject: [PATCH 1466/2855] Input: psmouse - use switch statement in psmouse_process_byte() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of a series mostly exclusive "if" statements testing protocol type of the mouse let's use "switch" statement. Reviewed-by: Hans de Goede Reviewed-by: Pali Rohár Tested-by: Marcin Sochacki Tested-by: Till Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/psmouse-base.c | 65 ++++++++++++++---------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index ad18dab0ac476..4e43e7e70edb9 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -138,22 +138,16 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) if (psmouse->pktcnt < psmouse->pktsize) return PSMOUSE_GOOD_DATA; -/* - * Full packet accumulated, process it - */ - -/* - * Scroll wheel on IntelliMice, scroll buttons on NetMice - */ + /* Full packet accumulated, process it */ - if (psmouse->type == PSMOUSE_IMPS || psmouse->type == PSMOUSE_GENPS) + switch (psmouse->type) { + case PSMOUSE_IMPS: + /* IntelliMouse has scroll wheel */ input_report_rel(dev, REL_WHEEL, -(signed char) packet[3]); + break; -/* - * Scroll wheel and buttons on IntelliMouse Explorer - */ - - if (psmouse->type == PSMOUSE_IMEX) { + case PSMOUSE_IMEX: + /* Scroll wheel and buttons on IntelliMouse Explorer */ switch (packet[3] & 0xC0) { case 0x80: /* vertical scroll on IntelliMouse Explorer 4.0 */ input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); @@ -168,39 +162,42 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1); break; } - } + break; -/* - * Extra buttons on Genius NewNet 3D - */ + case PSMOUSE_GENPS: + /* Report scroll buttons on NetMice */ + input_report_rel(dev, REL_WHEEL, -(signed char) packet[3]); - if (psmouse->type == PSMOUSE_GENPS) { + /* Extra buttons on Genius NewNet 3D */ input_report_key(dev, BTN_SIDE, (packet[0] >> 6) & 1); input_report_key(dev, BTN_EXTRA, (packet[0] >> 7) & 1); - } + break; -/* - * Extra button on ThinkingMouse - */ - if (psmouse->type == PSMOUSE_THINKPS) { + case PSMOUSE_THINKPS: + /* Extra button on ThinkingMouse */ input_report_key(dev, BTN_EXTRA, (packet[0] >> 3) & 1); - /* Without this bit of weirdness moving up gives wildly high Y changes. */ + + /* + * Without this bit of weirdness moving up gives wildly + * high Y changes. + */ packet[1] |= (packet[0] & 0x40) << 1; - } + break; -/* - * Cortron PS2 Trackball reports SIDE button on the 4th bit of the first - * byte. - */ - if (psmouse->type == PSMOUSE_CORTRON) { + case PSMOUSE_CORTRON: + /* + * Cortron PS2 Trackball reports SIDE button in the + * 4th bit of the first byte. + */ input_report_key(dev, BTN_SIDE, (packet[0] >> 3) & 1); packet[0] |= 0x08; - } + break; -/* - * Generic PS/2 Mouse - */ + default: + break; + } + /* Generic PS/2 Mouse */ input_report_key(dev, BTN_LEFT, packet[0] & 1); input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1); input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1); -- GitLab From ad5307715b2d0afed511b2cad9aed530bbbb236b Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 27 Nov 2015 20:47:08 -0800 Subject: [PATCH 1467/2855] Input: psmouse - fix comment style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The module was using non-standard comment style with comment blocks often starting at the very beginning of a line instead of being aligned with the code. Let's switch to standard formatting. Reviewed-by: Hans de Goede Reviewed-by: Pali Rohár Tested-by: Marcin Sochacki Tested-by: Till Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/psmouse-base.c | 279 +++++++++++++---------------- 1 file changed, 124 insertions(+), 155 deletions(-) diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 4e43e7e70edb9..525de2e7c08b1 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -129,7 +129,6 @@ struct psmouse_protocol { * psmouse_process_byte() analyzes the PS/2 data stream and reports * relevant events to the input module once full packet has arrived. */ - psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) { struct input_dev *dev = psmouse->dev; @@ -219,7 +218,6 @@ void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work, /* * __psmouse_set_state() sets new psmouse state and resets all flags. */ - static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) { psmouse->state = new_state; @@ -228,13 +226,11 @@ static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_sta psmouse->last = jiffies; } - /* * psmouse_set_state() sets new psmouse state and resets all flags and * counters while holding serio lock so fighting with interrupt handler * is not a concern. */ - void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) { serio_pause_rx(psmouse->ps2dev.serio); @@ -246,7 +242,6 @@ void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) * psmouse_handle_byte() processes one byte of the input data stream * by calling corresponding protocol handler. */ - static int psmouse_handle_byte(struct psmouse *psmouse) { psmouse_ret_t rc = psmouse->protocol_handler(psmouse); @@ -289,7 +284,6 @@ static int psmouse_handle_byte(struct psmouse *psmouse) * psmouse_interrupt() handles incoming characters, either passing them * for normal processing or gathering them as command response. */ - static irqreturn_t psmouse_interrupt(struct serio *serio, unsigned char data, unsigned int flags) { @@ -332,9 +326,8 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, } psmouse->packet[psmouse->pktcnt++] = data; -/* - * Check if this is a new device announcement (0xAA 0x00) - */ + + /* Check if this is a new device announcement (0xAA 0x00) */ if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) { if (psmouse->pktcnt == 1) { psmouse->last = jiffies; @@ -348,9 +341,8 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, serio_reconnect(serio); goto out; } -/* - * Not a new device, try processing first byte normally - */ + + /* Not a new device, try processing first byte normally */ psmouse->pktcnt = 1; if (psmouse_handle_byte(psmouse)) goto out; @@ -358,9 +350,10 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, psmouse->packet[psmouse->pktcnt++] = data; } -/* - * See if we need to force resync because mouse was idle for too long - */ + /* + * See if we need to force resync because mouse was idle for + * too long. + */ if (psmouse->state == PSMOUSE_ACTIVATED && psmouse->pktcnt == 1 && psmouse->resync_time && time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) { @@ -377,7 +370,6 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, return IRQ_HANDLED; } - /* * psmouse_sliced_command() sends an extended PS/2 command to the mouse * using sliced syntax, understood by advanced devices, such as Logitech @@ -401,7 +393,6 @@ int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command) return 0; } - /* * psmouse_reset() resets the mouse into power-on state. */ @@ -421,7 +412,6 @@ int psmouse_reset(struct psmouse *psmouse) /* * Here we set the mouse resolution. */ - void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution) { static const unsigned char params[] = { 0, 1, 2, 2, 3 }; @@ -438,7 +428,6 @@ void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution) /* * Here we set the mouse report rate. */ - static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate) { static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 }; @@ -454,7 +443,6 @@ static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate) /* * Here we set the mouse scaling. */ - static void psmouse_set_scale(struct psmouse *psmouse, enum psmouse_scale scale) { ps2_command(&psmouse->ps2dev, NULL, @@ -465,7 +453,6 @@ static void psmouse_set_scale(struct psmouse *psmouse, enum psmouse_scale scale) /* * psmouse_poll() - default poll handler. Everyone except for ALPS uses it. */ - static int psmouse_poll(struct psmouse *psmouse) { return ps2_command(&psmouse->ps2dev, psmouse->packet, @@ -599,7 +586,7 @@ static int im_explorer_detect(struct psmouse *psmouse, bool set_properties) if (param[0] != 4) return -1; -/* Magic to enable horizontal scrolling on IntelliMouse 4.0 */ + /* Magic to enable horizontal scrolling on IntelliMouse 4.0 */ param[0] = 200; ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); param[0] = 80; @@ -669,10 +656,10 @@ static int ps2bare_detect(struct psmouse *psmouse, bool set_properties) if (!psmouse->name) psmouse->name = "Mouse"; -/* - * We have no way of figuring true number of buttons so let's - * assume that the device has 3. - */ + /* + * We have no way of figuring true number of buttons so let's + * assume that the device has 3. + */ __set_bit(BTN_MIDDLE, psmouse->dev->keybit); } @@ -700,7 +687,6 @@ static int cortron_detect(struct psmouse *psmouse, bool set_properties) * Apply default settings to the psmouse structure. Most of them will * be overridden by individual protocol initialization routines. */ - static void psmouse_apply_defaults(struct psmouse *psmouse) { struct input_dev *input_dev = psmouse->dev; @@ -753,13 +739,15 @@ static int psmouse_do_detect(int (*detect)(struct psmouse *psmouse, * psmouse_extensions() probes for any extensions to the basic PS/2 protocol * the mouse may have. */ - static int psmouse_extensions(struct psmouse *psmouse, unsigned int max_proto, bool set_properties) { bool synaptics_hardware = false; -/* Always check for focaltech, this is safe as it uses pnp-id matching */ + /* + * Always check for focaltech, this is safe as it uses pnp-id + * matching. + */ if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) { if (max_proto > PSMOUSE_IMEX) { if (!set_properties || focaltech_init(psmouse) == 0) { @@ -777,10 +765,10 @@ static int psmouse_extensions(struct psmouse *psmouse, } } -/* - * We always check for lifebook because it does not disturb mouse - * (it only checks DMI information). - */ + /* + * We always check for LifeBook because it does not disturb mouse + * (it only checks DMI information). + */ if (psmouse_do_detect(lifebook_detect, psmouse, set_properties) == 0) { if (max_proto > PSMOUSE_IMEX) { if (!set_properties || lifebook_init(psmouse) == 0) @@ -795,53 +783,57 @@ static int psmouse_extensions(struct psmouse *psmouse, } } -/* - * Try Kensington ThinkingMouse (we try first, because synaptics probe - * upsets the thinkingmouse). - */ - + /* + * Try Kensington ThinkingMouse (we try first, because Synaptics + * probe upsets the ThinkingMouse). + */ if (max_proto > PSMOUSE_IMEX && psmouse_do_detect(thinking_detect, psmouse, set_properties) == 0) { return PSMOUSE_THINKPS; } -/* - * Try Synaptics TouchPad. Note that probing is done even if Synaptics protocol - * support is disabled in config - we need to know if it is synaptics so we - * can reset it properly after probing for intellimouse. - */ + /* + * Try Synaptics TouchPad. Note that probing is done even if + * Synaptics protocol support is disabled in config - we need to + * know if it is Synaptics so we can reset it properly after + * probing for IntelliMouse. + */ if (max_proto > PSMOUSE_PS2 && psmouse_do_detect(synaptics_detect, psmouse, set_properties) == 0) { synaptics_hardware = true; if (max_proto > PSMOUSE_IMEX) { -/* - * Try activating protocol, but check if support is enabled first, since - * we try detecting Synaptics even when protocol is disabled. - */ + /* + * Try activating protocol, but check if support is + * enabled first, since we try detecting Synaptics + * even when protocol is disabled. + */ if (IS_ENABLED(CONFIG_MOUSE_PS2_SYNAPTICS) && (!set_properties || synaptics_init(psmouse) == 0)) { return PSMOUSE_SYNAPTICS; } -/* - * Some Synaptics touchpads can emulate extended protocols (like IMPS/2). - * Unfortunately Logitech/Genius probes confuse some firmware versions so - * we'll have to skip them. - */ + /* + * Some Synaptics touchpads can emulate extended + * protocols (like IMPS/2). Unfortunately + * Logitech/Genius probes confuse some firmware + * versions so we'll have to skip them. + */ max_proto = PSMOUSE_IMEX; } -/* - * Make sure that touchpad is in relative mode, gestures (taps) are enabled - */ + + /* + * Make sure that touchpad is in relative mode, gestures + * (taps) are enabled. + */ synaptics_reset(psmouse); } -/* - * Try Cypress Trackpad. - * Must try it before Finger Sensing Pad because Finger Sensing Pad probe - * upsets some modules of Cypress Trackpads. - */ + /* + * Try Cypress Trackpad. We must try it before Finger Sensing Pad + * because Finger Sensing Pad probe upsets some modules of Cypress + * Trackpads. + */ if (max_proto > PSMOUSE_IMEX && cypress_detect(psmouse, set_properties) == 0) { if (IS_ENABLED(CONFIG_MOUSE_PS2_CYPRESS)) { @@ -859,45 +851,34 @@ static int psmouse_extensions(struct psmouse *psmouse, max_proto = PSMOUSE_IMEX; } -/* - * Try ALPS TouchPad - */ + /* Try ALPS TouchPad */ if (max_proto > PSMOUSE_IMEX) { ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); if (psmouse_do_detect(alps_detect, psmouse, set_properties) == 0) { if (!set_properties || alps_init(psmouse) == 0) return PSMOUSE_ALPS; -/* - * Init failed, try basic relative protocols - */ + + /* Init failed, try basic relative protocols */ max_proto = PSMOUSE_IMEX; } } -/* - * Try OLPC HGPK touchpad. - */ + /* Try OLPC HGPK touchpad */ if (max_proto > PSMOUSE_IMEX && psmouse_do_detect(hgpk_detect, psmouse, set_properties) == 0) { if (!set_properties || hgpk_init(psmouse) == 0) return PSMOUSE_HGPK; -/* - * Init failed, try basic relative protocols - */ + /* Init failed, try basic relative protocols */ max_proto = PSMOUSE_IMEX; } -/* - * Try Elantech touchpad. - */ + /* Try Elantech touchpad */ if (max_proto > PSMOUSE_IMEX && psmouse_do_detect(elantech_detect, psmouse, set_properties) == 0) { if (!set_properties || elantech_init(psmouse) == 0) return PSMOUSE_ELANTECH; -/* - * Init failed, try basic relative protocols - */ + /* Init failed, try basic relative protocols */ max_proto = PSMOUSE_IMEX; } @@ -919,27 +900,25 @@ static int psmouse_extensions(struct psmouse *psmouse, return PSMOUSE_TOUCHKIT_PS2; } -/* - * Try Finger Sensing Pad. We do it here because its probe upsets - * Trackpoint devices (causing TP_READ_ID command to time out). - */ + /* + * Try Finger Sensing Pad. We do it here because its probe upsets + * Trackpoint devices (causing TP_READ_ID command to time out). + */ if (max_proto > PSMOUSE_IMEX) { if (psmouse_do_detect(fsp_detect, psmouse, set_properties) == 0) { if (!set_properties || fsp_init(psmouse) == 0) return PSMOUSE_FSP; -/* - * Init failed, try basic relative protocols - */ + /* Init failed, try basic relative protocols */ max_proto = PSMOUSE_IMEX; } } -/* - * Reset to defaults in case the device got confused by extended - * protocol probes. Note that we follow up with full reset because - * some mice put themselves to sleep when they see PSMOUSE_RESET_DIS. - */ + /* + * Reset to defaults in case the device got confused by extended + * protocol probes. Note that we follow up with full reset because + * some mice put themselves to sleep when they see PSMOUSE_RESET_DIS. + */ ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); psmouse_reset(psmouse); @@ -955,19 +934,19 @@ static int psmouse_extensions(struct psmouse *psmouse, return PSMOUSE_IMPS; } -/* - * Okay, all failed, we have a standard mouse here. The number of the buttons - * is still a question, though. We assume 3. - */ + /* + * Okay, all failed, we have a standard mouse here. The number of + * the buttons is still a question, though. We assume 3. + */ psmouse_do_detect(ps2bare_detect, psmouse, set_properties); if (synaptics_hardware) { -/* - * We detected Synaptics hardware but it did not respond to IMPS/2 probes. - * We need to reset the touchpad because if there is a track point on the - * pass through port it could get disabled while probing for protocol - * extensions. - */ + /* + * We detected Synaptics hardware but it did not respond to + * IMPS/2 probes. We need to reset the touchpad because if + * there is a track point on the pass through port it could + * get disabled while probing for protocol extensions. + */ psmouse_reset(psmouse); } @@ -1167,19 +1146,17 @@ static const struct psmouse_protocol *psmouse_protocol_by_name(const char *name, /* * psmouse_probe() probes for a PS/2 mouse. */ - static int psmouse_probe(struct psmouse *psmouse) { struct ps2dev *ps2dev = &psmouse->ps2dev; unsigned char param[2]; -/* - * First, we check if it's a mouse. It should send 0x00 or 0x03 - * in case of an IntelliMouse in 4-byte mode or 0x04 for IM Explorer. - * Sunrex K8561 IR Keyboard/Mouse reports 0xff on second and subsequent - * ID queries, probably due to a firmware bug. - */ - + /* + * First, we check if it's a mouse. It should send 0x00 or 0x03 in + * case of an IntelliMouse in 4-byte mode or 0x04 for IM Explorer. + * Sunrex K8561 IR Keyboard/Mouse reports 0xff on second and + * subsequent ID queries, probably due to a firmware bug. + */ param[0] = 0xa5; if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETID)) return -1; @@ -1188,10 +1165,10 @@ static int psmouse_probe(struct psmouse *psmouse) param[0] != 0x04 && param[0] != 0xff) return -1; -/* - * Then we reset and disable the mouse so that it doesn't generate events. - */ - + /* + * Then we reset and disable the mouse so that it doesn't generate + * events. + */ if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS)) psmouse_warn(psmouse, "Failed to reset mouse on %s\n", ps2dev->serio->phys); @@ -1202,13 +1179,11 @@ static int psmouse_probe(struct psmouse *psmouse) /* * psmouse_initialize() initializes the mouse to a sane state. */ - static void psmouse_initialize(struct psmouse *psmouse) { -/* - * We set the mouse report rate, resolution and scaling. - */ - + /* + * We set the mouse report rate, resolution and scaling. + */ if (psmouse_max_proto != PSMOUSE_PS2) { psmouse->set_rate(psmouse, psmouse->rate); psmouse->set_resolution(psmouse, psmouse->resolution); @@ -1219,7 +1194,6 @@ static void psmouse_initialize(struct psmouse *psmouse) /* * psmouse_activate() enables the mouse so that we get motion reports from it. */ - int psmouse_activate(struct psmouse *psmouse) { if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) { @@ -1233,10 +1207,9 @@ int psmouse_activate(struct psmouse *psmouse) } /* - * psmouse_deactivate() puts the mouse into poll mode so that we don't get motion - * reports from it unless we explicitly request it. + * psmouse_deactivate() puts the mouse into poll mode so that we don't get + * motion reports from it unless we explicitly request it. */ - int psmouse_deactivate(struct psmouse *psmouse) { if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) { @@ -1249,11 +1222,9 @@ int psmouse_deactivate(struct psmouse *psmouse) return 0; } - /* * psmouse_resync() attempts to re-validate current protocol. */ - static void psmouse_resync(struct work_struct *work) { struct psmouse *parent = NULL, *psmouse = @@ -1273,16 +1244,16 @@ static void psmouse_resync(struct work_struct *work) psmouse_deactivate(parent); } -/* - * Some mice don't ACK commands sent while they are in the middle of - * transmitting motion packet. To avoid delay we use ps2_sendbyte() - * instead of ps2_command() which would wait for 200ms for an ACK - * that may never come. - * As an additional quirk ALPS touchpads may not only forget to ACK - * disable command but will stop reporting taps, so if we see that - * mouse at least once ACKs disable we will do full reconnect if ACK - * is missing. - */ + /* + * Some mice don't ACK commands sent while they are in the middle of + * transmitting motion packet. To avoid delay we use ps2_sendbyte() + * instead of ps2_command() which would wait for 200ms for an ACK + * that may never come. + * As an additional quirk ALPS touchpads may not only forget to ACK + * disable command but will stop reporting taps, so if we see that + * mouse at least once ACKs disable we will do full reconnect if ACK + * is missing. + */ psmouse->num_resyncs++; if (ps2_sendbyte(&psmouse->ps2dev, PSMOUSE_CMD_DISABLE, 20)) { @@ -1291,13 +1262,13 @@ static void psmouse_resync(struct work_struct *work) } else psmouse->acks_disable_command = true; -/* - * Poll the mouse. If it was reset the packet will be shorter than - * psmouse->pktsize and ps2_command will fail. We do not expect and - * do not handle scenario when mouse "upgrades" its protocol while - * disconnected since it would require additional delay. If we ever - * see a mouse that does it we'll adjust the code. - */ + /* + * Poll the mouse. If it was reset the packet will be shorter than + * psmouse->pktsize and ps2_command will fail. We do not expect and + * do not handle scenario when mouse "upgrades" its protocol while + * disconnected since it would require additional delay. If we ever + * see a mouse that does it we'll adjust the code. + */ if (!failed) { if (psmouse->poll(psmouse)) failed = true; @@ -1314,11 +1285,12 @@ static void psmouse_resync(struct work_struct *work) psmouse_set_state(psmouse, PSMOUSE_RESYNCING); } } -/* - * Now try to enable mouse. We try to do that even if poll failed and also - * repeat our attempts 5 times, otherwise we may be left out with disabled - * mouse. - */ + + /* + * Now try to enable mouse. We try to do that even if poll failed + * and also repeat our attempts 5 times, otherwise we may be left + * out with disabled mouse. + */ for (i = 0; i < 5; i++) { if (!ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) { enabled = true; @@ -1350,7 +1322,6 @@ static void psmouse_resync(struct work_struct *work) /* * psmouse_cleanup() resets the mouse into power-on state. */ - static void psmouse_cleanup(struct serio *serio) { struct psmouse *psmouse = serio_get_drvdata(serio); @@ -1375,15 +1346,15 @@ static void psmouse_cleanup(struct serio *serio) if (psmouse->cleanup) psmouse->cleanup(psmouse); -/* - * Reset the mouse to defaults (bare PS/2 protocol). - */ + /* + * Reset the mouse to defaults (bare PS/2 protocol). + */ ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); -/* - * Some boxes, such as HP nx7400, get terribly confused if mouse - * is not fully enabled before suspending/shutting down. - */ + /* + * Some boxes, such as HP nx7400, get terribly confused if mouse + * is not fully enabled before suspending/shutting down. + */ ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE); if (parent) { @@ -1399,7 +1370,6 @@ static void psmouse_cleanup(struct serio *serio) /* * psmouse_disconnect() closes and frees. */ - static void psmouse_disconnect(struct serio *serio) { struct psmouse *psmouse, *parent = NULL; @@ -1599,7 +1569,6 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) goto out; } - static int psmouse_reconnect(struct serio *serio) { struct psmouse *psmouse = serio_get_drvdata(serio); -- GitLab From 2b6f39e9ee7b6a9fa98f6047b05733053876fdbe Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 27 Nov 2015 20:52:36 -0800 Subject: [PATCH 1468/2855] Input: psmouse - rearrange Focaltech init code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The fact that we were calling focaltech_init() even when Focaltech support is disabled was confusing. Rearrange the code so that if support is disabled we continue to fall through the rest of protocol probing code until we get to full reset that Focaltech devices need to work properly. Also, replace focaltech_init() with a stub now that it is only called when protocol is enabled. Reviewed-by: Hans de Goede Reviewed-by: Pali Rohár Tested-by: Marcin Sochacki Tested-by: Till Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/focaltech.c | 22 ++++++---------------- drivers/input/mouse/focaltech.h | 8 ++++++++ drivers/input/mouse/psmouse-base.c | 23 ++++++++++++----------- 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c index 4d5576de81be6..c8c6a8cc329d7 100644 --- a/drivers/input/mouse/focaltech.c +++ b/drivers/input/mouse/focaltech.c @@ -49,12 +49,6 @@ int focaltech_detect(struct psmouse *psmouse, bool set_properties) return 0; } -static void focaltech_reset(struct psmouse *psmouse) -{ - ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); - psmouse_reset(psmouse); -} - #ifdef CONFIG_MOUSE_PS2_FOCALTECH /* @@ -300,6 +294,12 @@ static int focaltech_switch_protocol(struct psmouse *psmouse) return 0; } +static void focaltech_reset(struct psmouse *psmouse) +{ + ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); + psmouse_reset(psmouse); +} + static void focaltech_disconnect(struct psmouse *psmouse) { focaltech_reset(psmouse); @@ -456,14 +456,4 @@ fail: kfree(priv); return error; } - -#else /* CONFIG_MOUSE_PS2_FOCALTECH */ - -int focaltech_init(struct psmouse *psmouse) -{ - focaltech_reset(psmouse); - - return 0; -} - #endif /* CONFIG_MOUSE_PS2_FOCALTECH */ diff --git a/drivers/input/mouse/focaltech.h b/drivers/input/mouse/focaltech.h index ca61ebff373e9..783b28e8e10be 100644 --- a/drivers/input/mouse/focaltech.h +++ b/drivers/input/mouse/focaltech.h @@ -18,6 +18,14 @@ #define _FOCALTECH_H int focaltech_detect(struct psmouse *psmouse, bool set_properties); + +#ifdef CONFIG_MOUSE_PS2_FOCALTECH int focaltech_init(struct psmouse *psmouse); +#else +static inline int focaltech_init(struct psmouse *psmouse) +{ + return -ENOSYS; +} +#endif #endif diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 525de2e7c08b1..c2bd8665e9f22 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -750,19 +750,20 @@ static int psmouse_extensions(struct psmouse *psmouse, */ if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) { if (max_proto > PSMOUSE_IMEX) { - if (!set_properties || focaltech_init(psmouse) == 0) { - if (IS_ENABLED(CONFIG_MOUSE_PS2_FOCALTECH)) - return PSMOUSE_FOCALTECH; - /* - * Note that we need to also restrict - * psmouse_max_proto so that psmouse_initialize() - * does not try to reset rate and resolution, - * because even that upsets the device. - */ - psmouse_max_proto = PSMOUSE_PS2; - return PSMOUSE_PS2; + if (IS_ENABLED(CONFIG_MOUSE_PS2_FOCALTECH) && + (!set_properties || focaltech_init(psmouse) == 0)) { + return PSMOUSE_FOCALTECH; } } + /* + * Restrict psmouse_max_proto so that psmouse_initialize() + * does not try to reset rate and resolution, because even + * that upsets the device. + * This also causes us to basically fall through to basic + * protocol detection, where we fully reset the mouse, + * and set it up as bare PS/2 protocol device. + */ + psmouse_max_proto = max_proto = PSMOUSE_PS2; } /* -- GitLab From 24a06f3e3ab640490f49c8e8812d9550d6f15e92 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 2 Dec 2015 16:50:42 -0800 Subject: [PATCH 1469/2855] Input: psmouse - clean up Cypress probe When Cypress protocol support is disabled cypress_init() is a stub that always returns -ENOSYS, so there is not point in testing for CONFIG_MOUSE_PS2_CYPRESS after we decided that we are dealing with a Cypress device. Also, we should only be calling cypress_detect() when set_properties argument is "true", like with other protocols. There is a slight change in behavior to make follow-up patches more uniform: when we detect Cypress but its initialization fails, instead of immediately returning PSMOUSE_PS2 protocol we now continue trying IntelliMouse [Explorer]. Given that Cypress devices only have issue with Sentelic probes probing Imtellimouse should be safe. Reviewed-by: Hans de Goede Tested-by: Marcin Sochacki Tested-by: Till Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/psmouse-base.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index c2bd8665e9f22..978ba0bb4bd9b 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -836,19 +836,15 @@ static int psmouse_extensions(struct psmouse *psmouse, * Trackpads. */ if (max_proto > PSMOUSE_IMEX && - cypress_detect(psmouse, set_properties) == 0) { - if (IS_ENABLED(CONFIG_MOUSE_PS2_CYPRESS)) { - if (cypress_init(psmouse) == 0) - return PSMOUSE_CYPRESS; - - /* - * Finger Sensing Pad probe upsets some modules of - * Cypress Trackpad, must avoid Finger Sensing Pad - * probe if Cypress Trackpad device detected. - */ - return PSMOUSE_PS2; - } + psmouse_do_detect(cypress_detect, psmouse, set_properties) == 0) { + if (!set_properties || cypress_init(psmouse) == 0) + return PSMOUSE_CYPRESS; + /* + * Finger Sensing Pad probe upsets some modules of + * Cypress Trackpad, must avoid Finger Sensing Pad + * probe if Cypress Trackpad device detected. + */ max_proto = PSMOUSE_IMEX; } -- GitLab From 5fa75cfe23633edf2fd26abe4a08f22ced4415d1 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 27 Nov 2015 21:08:28 -0800 Subject: [PATCH 1470/2855] Input: psmouse - move protocol descriptions around MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We move protocol descriptions and psmouse_find_by_type() and pmouse_find_by_name() so that we can use them without forward declarations in the subsequent patches. Reviewed-by: Hans de Goede Reviewed-by: Pali Rohár Tested-by: Marcin Sochacki Tested-by: Till Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/psmouse-base.c | 379 ++++++++++++++--------------- 1 file changed, 189 insertions(+), 190 deletions(-) diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 978ba0bb4bd9b..131bbc1bd4462 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -683,6 +683,195 @@ static int cortron_detect(struct psmouse *psmouse, bool set_properties) return 0; } +static const struct psmouse_protocol psmouse_protocols[] = { + { + .type = PSMOUSE_PS2, + .name = "PS/2", + .alias = "bare", + .maxproto = true, + .ignore_parity = true, + .detect = ps2bare_detect, + }, +#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP + { + .type = PSMOUSE_PS2PP, + .name = "PS2++", + .alias = "logitech", + .detect = ps2pp_init, + }, +#endif + { + .type = PSMOUSE_THINKPS, + .name = "ThinkPS/2", + .alias = "thinkps", + .detect = thinking_detect, + }, +#ifdef CONFIG_MOUSE_PS2_CYPRESS + { + .type = PSMOUSE_CYPRESS, + .name = "CyPS/2", + .alias = "cypress", + .detect = cypress_detect, + .init = cypress_init, + }, +#endif + { + .type = PSMOUSE_GENPS, + .name = "GenPS/2", + .alias = "genius", + .detect = genius_detect, + }, + { + .type = PSMOUSE_IMPS, + .name = "ImPS/2", + .alias = "imps", + .maxproto = true, + .ignore_parity = true, + .detect = intellimouse_detect, + }, + { + .type = PSMOUSE_IMEX, + .name = "ImExPS/2", + .alias = "exps", + .maxproto = true, + .ignore_parity = true, + .detect = im_explorer_detect, + }, +#ifdef CONFIG_MOUSE_PS2_SYNAPTICS + { + .type = PSMOUSE_SYNAPTICS, + .name = "SynPS/2", + .alias = "synaptics", + .detect = synaptics_detect, + .init = synaptics_init, + }, + { + .type = PSMOUSE_SYNAPTICS_RELATIVE, + .name = "SynRelPS/2", + .alias = "synaptics-relative", + .detect = synaptics_detect, + .init = synaptics_init_relative, + }, +#endif +#ifdef CONFIG_MOUSE_PS2_ALPS + { + .type = PSMOUSE_ALPS, + .name = "AlpsPS/2", + .alias = "alps", + .detect = alps_detect, + .init = alps_init, + }, +#endif +#ifdef CONFIG_MOUSE_PS2_LIFEBOOK + { + .type = PSMOUSE_LIFEBOOK, + .name = "LBPS/2", + .alias = "lifebook", + .init = lifebook_init, + }, +#endif +#ifdef CONFIG_MOUSE_PS2_TRACKPOINT + { + .type = PSMOUSE_TRACKPOINT, + .name = "TPPS/2", + .alias = "trackpoint", + .detect = trackpoint_detect, + }, +#endif +#ifdef CONFIG_MOUSE_PS2_TOUCHKIT + { + .type = PSMOUSE_TOUCHKIT_PS2, + .name = "touchkitPS/2", + .alias = "touchkit", + .detect = touchkit_ps2_detect, + }, +#endif +#ifdef CONFIG_MOUSE_PS2_OLPC + { + .type = PSMOUSE_HGPK, + .name = "OLPC HGPK", + .alias = "hgpk", + .detect = hgpk_detect, + }, +#endif +#ifdef CONFIG_MOUSE_PS2_ELANTECH + { + .type = PSMOUSE_ELANTECH, + .name = "ETPS/2", + .alias = "elantech", + .detect = elantech_detect, + .init = elantech_init, + }, +#endif +#ifdef CONFIG_MOUSE_PS2_SENTELIC + { + .type = PSMOUSE_FSP, + .name = "FSPPS/2", + .alias = "fsp", + .detect = fsp_detect, + .init = fsp_init, + }, +#endif + { + .type = PSMOUSE_CORTRON, + .name = "CortronPS/2", + .alias = "cortps", + .detect = cortron_detect, + }, +#ifdef CONFIG_MOUSE_PS2_FOCALTECH + { + .type = PSMOUSE_FOCALTECH, + .name = "FocalTechPS/2", + .alias = "focaltech", + .detect = focaltech_detect, + .init = focaltech_init, + }, +#endif +#ifdef CONFIG_MOUSE_PS2_VMMOUSE + { + .type = PSMOUSE_VMMOUSE, + .name = VMMOUSE_PSNAME, + .alias = "vmmouse", + .detect = vmmouse_detect, + .init = vmmouse_init, + }, +#endif + { + .type = PSMOUSE_AUTO, + .name = "auto", + .alias = "any", + .maxproto = true, + }, +}; + +static const struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(psmouse_protocols); i++) + if (psmouse_protocols[i].type == type) + return &psmouse_protocols[i]; + + WARN_ON(1); + return &psmouse_protocols[0]; +} + +static const struct psmouse_protocol *psmouse_protocol_by_name(const char *name, size_t len) +{ + const struct psmouse_protocol *p; + int i; + + for (i = 0; i < ARRAY_SIZE(psmouse_protocols); i++) { + p = &psmouse_protocols[i]; + + if ((strlen(p->name) == len && !strncmp(p->name, name, len)) || + (strlen(p->alias) == len && !strncmp(p->alias, name, len))) + return &psmouse_protocols[i]; + } + + return NULL; +} + /* * Apply default settings to the psmouse structure. Most of them will * be overridden by individual protocol initialization routines. @@ -950,196 +1139,6 @@ static int psmouse_extensions(struct psmouse *psmouse, return PSMOUSE_PS2; } -static const struct psmouse_protocol psmouse_protocols[] = { - { - .type = PSMOUSE_PS2, - .name = "PS/2", - .alias = "bare", - .maxproto = true, - .ignore_parity = true, - .detect = ps2bare_detect, - }, -#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP - { - .type = PSMOUSE_PS2PP, - .name = "PS2++", - .alias = "logitech", - .detect = ps2pp_init, - }, -#endif - { - .type = PSMOUSE_THINKPS, - .name = "ThinkPS/2", - .alias = "thinkps", - .detect = thinking_detect, - }, -#ifdef CONFIG_MOUSE_PS2_CYPRESS - { - .type = PSMOUSE_CYPRESS, - .name = "CyPS/2", - .alias = "cypress", - .detect = cypress_detect, - .init = cypress_init, - }, -#endif - { - .type = PSMOUSE_GENPS, - .name = "GenPS/2", - .alias = "genius", - .detect = genius_detect, - }, - { - .type = PSMOUSE_IMPS, - .name = "ImPS/2", - .alias = "imps", - .maxproto = true, - .ignore_parity = true, - .detect = intellimouse_detect, - }, - { - .type = PSMOUSE_IMEX, - .name = "ImExPS/2", - .alias = "exps", - .maxproto = true, - .ignore_parity = true, - .detect = im_explorer_detect, - }, -#ifdef CONFIG_MOUSE_PS2_SYNAPTICS - { - .type = PSMOUSE_SYNAPTICS, - .name = "SynPS/2", - .alias = "synaptics", - .detect = synaptics_detect, - .init = synaptics_init, - }, - { - .type = PSMOUSE_SYNAPTICS_RELATIVE, - .name = "SynRelPS/2", - .alias = "synaptics-relative", - .detect = synaptics_detect, - .init = synaptics_init_relative, - }, -#endif -#ifdef CONFIG_MOUSE_PS2_ALPS - { - .type = PSMOUSE_ALPS, - .name = "AlpsPS/2", - .alias = "alps", - .detect = alps_detect, - .init = alps_init, - }, -#endif -#ifdef CONFIG_MOUSE_PS2_LIFEBOOK - { - .type = PSMOUSE_LIFEBOOK, - .name = "LBPS/2", - .alias = "lifebook", - .init = lifebook_init, - }, -#endif -#ifdef CONFIG_MOUSE_PS2_TRACKPOINT - { - .type = PSMOUSE_TRACKPOINT, - .name = "TPPS/2", - .alias = "trackpoint", - .detect = trackpoint_detect, - }, -#endif -#ifdef CONFIG_MOUSE_PS2_TOUCHKIT - { - .type = PSMOUSE_TOUCHKIT_PS2, - .name = "touchkitPS/2", - .alias = "touchkit", - .detect = touchkit_ps2_detect, - }, -#endif -#ifdef CONFIG_MOUSE_PS2_OLPC - { - .type = PSMOUSE_HGPK, - .name = "OLPC HGPK", - .alias = "hgpk", - .detect = hgpk_detect, - }, -#endif -#ifdef CONFIG_MOUSE_PS2_ELANTECH - { - .type = PSMOUSE_ELANTECH, - .name = "ETPS/2", - .alias = "elantech", - .detect = elantech_detect, - .init = elantech_init, - }, -#endif -#ifdef CONFIG_MOUSE_PS2_SENTELIC - { - .type = PSMOUSE_FSP, - .name = "FSPPS/2", - .alias = "fsp", - .detect = fsp_detect, - .init = fsp_init, - }, -#endif - { - .type = PSMOUSE_CORTRON, - .name = "CortronPS/2", - .alias = "cortps", - .detect = cortron_detect, - }, -#ifdef CONFIG_MOUSE_PS2_FOCALTECH - { - .type = PSMOUSE_FOCALTECH, - .name = "FocalTechPS/2", - .alias = "focaltech", - .detect = focaltech_detect, - .init = focaltech_init, - }, -#endif -#ifdef CONFIG_MOUSE_PS2_VMMOUSE - { - .type = PSMOUSE_VMMOUSE, - .name = VMMOUSE_PSNAME, - .alias = "vmmouse", - .detect = vmmouse_detect, - .init = vmmouse_init, - }, -#endif - { - .type = PSMOUSE_AUTO, - .name = "auto", - .alias = "any", - .maxproto = true, - }, -}; - -static const struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(psmouse_protocols); i++) - if (psmouse_protocols[i].type == type) - return &psmouse_protocols[i]; - - WARN_ON(1); - return &psmouse_protocols[0]; -} - -static const struct psmouse_protocol *psmouse_protocol_by_name(const char *name, size_t len) -{ - const struct psmouse_protocol *p; - int i; - - for (i = 0; i < ARRAY_SIZE(psmouse_protocols); i++) { - p = &psmouse_protocols[i]; - - if ((strlen(p->name) == len && !strncmp(p->name, name, len)) || - (strlen(p->alias) == len && !strncmp(p->alias, name, len))) - return &psmouse_protocols[i]; - } - - return NULL; -} - - /* * psmouse_probe() probes for a PS/2 mouse. */ -- GitLab From c378b5119eb0ea25bfd3348a06b51fca654d9903 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 27 Nov 2015 21:17:40 -0800 Subject: [PATCH 1471/2855] Input: psmouse - factor out common protocol probing code In preparation of limiting protocols that we try on pass-through ports, let's rework initialization code and factor common code into psmouse_try_protocol() that accepts protocol type (instead of detec() function pointer) and can, for most protocols, perform both detection and initialization. Note that this removes option of forcing Lifebook protocol on devices that are not recognized by lifebook_detect() as having the hardware, but I do not recall anyone using this option. Reviewed-by: Hans de Goede Tested-by: Marcin Sochacki Tested-by: Till Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/psmouse-base.c | 164 +++++++++++++++-------------- 1 file changed, 86 insertions(+), 78 deletions(-) diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 131bbc1bd4462..316105e30064f 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -767,6 +767,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { .type = PSMOUSE_LIFEBOOK, .name = "LBPS/2", .alias = "lifebook", + .detect = lifebook_detect, .init = lifebook_init, }, #endif @@ -844,7 +845,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { }, }; -static const struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type) +static const struct psmouse_protocol *__psmouse_protocol_by_type(enum psmouse_type type) { int i; @@ -852,6 +853,17 @@ static const struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type if (psmouse_protocols[i].type == type) return &psmouse_protocols[i]; + return NULL; +} + +static const struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type) +{ + const struct psmouse_protocol *proto; + + proto = __psmouse_protocol_by_type(type); + if (proto) + return proto; + WARN_ON(1); return &psmouse_protocols[0]; } @@ -910,18 +922,37 @@ static void psmouse_apply_defaults(struct psmouse *psmouse) psmouse->pt_deactivate = NULL; } -/* - * Apply default settings to the psmouse structure and call specified - * protocol detection or initialization routine. - */ -static int psmouse_do_detect(int (*detect)(struct psmouse *psmouse, - bool set_properties), - struct psmouse *psmouse, bool set_properties) +static bool psmouse_try_protocol(struct psmouse *psmouse, + enum psmouse_type type, + unsigned int *max_proto, + bool set_properties, bool init_allowed) { + const struct psmouse_protocol *proto; + + proto = __psmouse_protocol_by_type(type); + if (!proto) + return false; + if (set_properties) psmouse_apply_defaults(psmouse); - return detect(psmouse, set_properties); + if (proto->detect(psmouse, set_properties) != 0) + return false; + + if (set_properties && proto->init && init_allowed) { + if (proto->init(psmouse) != 0) { + /* + * We detected device, but init failed. Adjust + * max_proto so we only try standard protocols. + */ + if (*max_proto > PSMOUSE_IMEX) + *max_proto = PSMOUSE_IMEX; + + return false; + } + } + + return true; } /* @@ -937,12 +968,12 @@ static int psmouse_extensions(struct psmouse *psmouse, * Always check for focaltech, this is safe as it uses pnp-id * matching. */ - if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) { - if (max_proto > PSMOUSE_IMEX) { - if (IS_ENABLED(CONFIG_MOUSE_PS2_FOCALTECH) && - (!set_properties || focaltech_init(psmouse) == 0)) { - return PSMOUSE_FOCALTECH; - } + if (psmouse_try_protocol(psmouse, PSMOUSE_FOCALTECH, + &max_proto, set_properties, false)) { + if (max_proto > PSMOUSE_IMEX && + IS_ENABLED(CONFIG_MOUSE_PS2_FOCALTECH) && + (!set_properties || focaltech_init(psmouse) == 0)) { + return PSMOUSE_FOCALTECH; } /* * Restrict psmouse_max_proto so that psmouse_initialize() @@ -959,26 +990,21 @@ static int psmouse_extensions(struct psmouse *psmouse, * We always check for LifeBook because it does not disturb mouse * (it only checks DMI information). */ - if (psmouse_do_detect(lifebook_detect, psmouse, set_properties) == 0) { - if (max_proto > PSMOUSE_IMEX) { - if (!set_properties || lifebook_init(psmouse) == 0) - return PSMOUSE_LIFEBOOK; - } - } + if (psmouse_try_protocol(psmouse, PSMOUSE_LIFEBOOK, &max_proto, + set_properties, max_proto > PSMOUSE_IMEX)) + return PSMOUSE_LIFEBOOK; - if (psmouse_do_detect(vmmouse_detect, psmouse, set_properties) == 0) { - if (max_proto > PSMOUSE_IMEX) { - if (!set_properties || vmmouse_init(psmouse) == 0) - return PSMOUSE_VMMOUSE; - } - } + if (psmouse_try_protocol(psmouse, PSMOUSE_VMMOUSE, &max_proto, + set_properties, max_proto > PSMOUSE_IMEX)) + return PSMOUSE_VMMOUSE; /* * Try Kensington ThinkingMouse (we try first, because Synaptics * probe upsets the ThinkingMouse). */ if (max_proto > PSMOUSE_IMEX && - psmouse_do_detect(thinking_detect, psmouse, set_properties) == 0) { + psmouse_try_protocol(psmouse, PSMOUSE_THINKPS, &max_proto, + set_properties, true)) { return PSMOUSE_THINKPS; } @@ -989,7 +1015,8 @@ static int psmouse_extensions(struct psmouse *psmouse, * probing for IntelliMouse. */ if (max_proto > PSMOUSE_PS2 && - psmouse_do_detect(synaptics_detect, psmouse, set_properties) == 0) { + psmouse_try_protocol(psmouse, PSMOUSE_SYNAPTICS, &max_proto, + set_properties, false)) { synaptics_hardware = true; if (max_proto > PSMOUSE_IMEX) { @@ -1025,64 +1052,48 @@ static int psmouse_extensions(struct psmouse *psmouse, * Trackpads. */ if (max_proto > PSMOUSE_IMEX && - psmouse_do_detect(cypress_detect, psmouse, set_properties) == 0) { - if (!set_properties || cypress_init(psmouse) == 0) - return PSMOUSE_CYPRESS; - - /* - * Finger Sensing Pad probe upsets some modules of - * Cypress Trackpad, must avoid Finger Sensing Pad - * probe if Cypress Trackpad device detected. - */ - max_proto = PSMOUSE_IMEX; + psmouse_try_protocol(psmouse, PSMOUSE_CYPRESS, &max_proto, + set_properties, true)) { + return PSMOUSE_CYPRESS; } /* Try ALPS TouchPad */ if (max_proto > PSMOUSE_IMEX) { ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); - if (psmouse_do_detect(alps_detect, - psmouse, set_properties) == 0) { - if (!set_properties || alps_init(psmouse) == 0) - return PSMOUSE_ALPS; - - /* Init failed, try basic relative protocols */ - max_proto = PSMOUSE_IMEX; - } + if (psmouse_try_protocol(psmouse, PSMOUSE_ALPS, + &max_proto, set_properties, true)) + return PSMOUSE_ALPS; } /* Try OLPC HGPK touchpad */ if (max_proto > PSMOUSE_IMEX && - psmouse_do_detect(hgpk_detect, psmouse, set_properties) == 0) { - if (!set_properties || hgpk_init(psmouse) == 0) - return PSMOUSE_HGPK; - /* Init failed, try basic relative protocols */ - max_proto = PSMOUSE_IMEX; + psmouse_try_protocol(psmouse, PSMOUSE_HGPK, &max_proto, + set_properties, true)) { + return PSMOUSE_HGPK; } /* Try Elantech touchpad */ if (max_proto > PSMOUSE_IMEX && - psmouse_do_detect(elantech_detect, psmouse, set_properties) == 0) { - if (!set_properties || elantech_init(psmouse) == 0) - return PSMOUSE_ELANTECH; - /* Init failed, try basic relative protocols */ - max_proto = PSMOUSE_IMEX; + psmouse_try_protocol(psmouse, PSMOUSE_ELANTECH, + &max_proto, set_properties, true)) { + return PSMOUSE_ELANTECH; } if (max_proto > PSMOUSE_IMEX) { - if (psmouse_do_detect(genius_detect, - psmouse, set_properties) == 0) + if (psmouse_try_protocol(psmouse, PSMOUSE_GENPS, + &max_proto, set_properties, true)) return PSMOUSE_GENPS; - if (psmouse_do_detect(ps2pp_init, - psmouse, set_properties) == 0) + if (psmouse_try_protocol(psmouse, PSMOUSE_PS2PP, + &max_proto, set_properties, true)) return PSMOUSE_PS2PP; - if (psmouse_do_detect(trackpoint_detect, - psmouse, set_properties) == 0) + if (psmouse_try_protocol(psmouse, PSMOUSE_TRACKPOINT, + &max_proto, set_properties, true)) return PSMOUSE_TRACKPOINT; - if (psmouse_do_detect(touchkit_ps2_detect, - psmouse, set_properties) == 0) + if (psmouse_try_protocol(psmouse, PSMOUSE_TOUCHKIT_PS2, + &max_proto, set_properties, true)) return PSMOUSE_TOUCHKIT_PS2; } @@ -1090,14 +1101,10 @@ static int psmouse_extensions(struct psmouse *psmouse, * Try Finger Sensing Pad. We do it here because its probe upsets * Trackpoint devices (causing TP_READ_ID command to time out). */ - if (max_proto > PSMOUSE_IMEX) { - if (psmouse_do_detect(fsp_detect, - psmouse, set_properties) == 0) { - if (!set_properties || fsp_init(psmouse) == 0) - return PSMOUSE_FSP; - /* Init failed, try basic relative protocols */ - max_proto = PSMOUSE_IMEX; - } + if (max_proto > PSMOUSE_IMEX && + psmouse_try_protocol(psmouse, PSMOUSE_FSP, + &max_proto, set_properties, true)) { + return PSMOUSE_FSP; } /* @@ -1109,14 +1116,14 @@ static int psmouse_extensions(struct psmouse *psmouse, psmouse_reset(psmouse); if (max_proto >= PSMOUSE_IMEX && - psmouse_do_detect(im_explorer_detect, - psmouse, set_properties) == 0) { + psmouse_try_protocol(psmouse, PSMOUSE_IMEX, + &max_proto, set_properties, true)) { return PSMOUSE_IMEX; } if (max_proto >= PSMOUSE_IMPS && - psmouse_do_detect(intellimouse_detect, - psmouse, set_properties) == 0) { + psmouse_try_protocol(psmouse, PSMOUSE_IMPS, + &max_proto, set_properties, true)) { return PSMOUSE_IMPS; } @@ -1124,7 +1131,8 @@ static int psmouse_extensions(struct psmouse *psmouse, * Okay, all failed, we have a standard mouse here. The number of * the buttons is still a question, though. We assume 3. */ - psmouse_do_detect(ps2bare_detect, psmouse, set_properties); + psmouse_try_protocol(psmouse, PSMOUSE_PS2, + &max_proto, set_properties, true); if (synaptics_hardware) { /* -- GitLab From ec6184b1c717b8768122e25fe6d312f609cc1bb4 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 24 Nov 2015 12:58:46 -0800 Subject: [PATCH 1472/2855] Input: psmouse - limit protocols that we try on passthrough ports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PS/2 protocol is slow, and using it with pass-through port (where we encapsulate PS/2 into PS/2) is slower yet so it takes quite a bit of time to do full protocol discovery for device attached to a pass-through port. However, so far we have not see anything but trackpoints or basic PS/2 mice on pass-through ports, so let's limit protocols that we probe there to Trackpoint, IntelliMouse Explorer, IntelliMouse, and bare PS/2 protocol, and avoid other extended protocols, such as Synaptics, ALPS, etc. Reviewed-by: Hans de Goede Reviewed-by: Pali Rohár Tested-by: Marcin Sochacki Tested-by: Till Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/psmouse-base.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 316105e30064f..f12df771eeb21 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -119,6 +119,7 @@ struct psmouse_protocol { enum psmouse_type type; bool maxproto; bool ignore_parity; /* Protocol should ignore parity errors from KBC */ + bool try_passthru; /* Try protocol also on passthrough ports */ const char *name; const char *alias; int (*detect)(struct psmouse *, bool); @@ -691,6 +692,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { .maxproto = true, .ignore_parity = true, .detect = ps2bare_detect, + .try_passthru = true, }, #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP { @@ -728,6 +730,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { .maxproto = true, .ignore_parity = true, .detect = intellimouse_detect, + .try_passthru = true, }, { .type = PSMOUSE_IMEX, @@ -736,6 +739,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { .maxproto = true, .ignore_parity = true, .detect = im_explorer_detect, + .try_passthru = true, }, #ifdef CONFIG_MOUSE_PS2_SYNAPTICS { @@ -777,6 +781,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { .name = "TPPS/2", .alias = "trackpoint", .detect = trackpoint_detect, + .try_passthru = true, }, #endif #ifdef CONFIG_MOUSE_PS2_TOUCHKIT @@ -933,6 +938,11 @@ static bool psmouse_try_protocol(struct psmouse *psmouse, if (!proto) return false; + if (psmouse->ps2dev.serio->id.type == SERIO_PS_PSTHRU && + !proto->try_passthru) { + return false; + } + if (set_properties) psmouse_apply_defaults(psmouse); -- GitLab From 190e2031e2db542094659cfa55bfc28545458df5 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 2 Dec 2015 11:02:39 -0800 Subject: [PATCH 1473/2855] Input: psmouse - rename ps2pp_init() to ps2pp_detect() This makes Logitech PS2++ protocol implementation consistent with the naming in other protocols. Also mark the stub as "static inline" Reviewed-by: Hans de Goede Tested-by: Marcin Sochacki Tested-by: Till Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/logips2pp.c | 2 +- drivers/input/mouse/logips2pp.h | 4 ++-- drivers/input/mouse/psmouse-base.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 136e222e2a164..422da1cd9e763 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c @@ -325,7 +325,7 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse, * that support it. */ -int ps2pp_init(struct psmouse *psmouse, bool set_properties) +int ps2pp_detect(struct psmouse *psmouse, bool set_properties) { struct ps2dev *ps2dev = &psmouse->ps2dev; unsigned char param[4]; diff --git a/drivers/input/mouse/logips2pp.h b/drivers/input/mouse/logips2pp.h index 0c186f0282d97..bf629453e0953 100644 --- a/drivers/input/mouse/logips2pp.h +++ b/drivers/input/mouse/logips2pp.h @@ -12,9 +12,9 @@ #define _LOGIPS2PP_H #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP -int ps2pp_init(struct psmouse *psmouse, bool set_properties); +int ps2pp_detect(struct psmouse *psmouse, bool set_properties); #else -inline int ps2pp_init(struct psmouse *psmouse, bool set_properties) +static inline int ps2pp_detect(struct psmouse *psmouse, bool set_properties) { return -ENOSYS; } diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index f12df771eeb21..b9e4ee34c132d 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -699,7 +699,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { .type = PSMOUSE_PS2PP, .name = "PS2++", .alias = "logitech", - .detect = ps2pp_init, + .detect = ps2pp_detect, }, #endif { -- GitLab From a779fbc6c931007559b74fd74c2dc7b1c25bac33 Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Thu, 17 Dec 2015 15:55:21 -0800 Subject: [PATCH 1474/2855] Input: goodix - use actual config length for each device type Each of the Goodix devices supported by this driver has a fixed size for the configuration information registers. The size varies depending on the device and is specified in the datasheet. Use the proper configuration length as specified in the datasheet for each device model, so we do not read more than the actual size of the configuration registers. Signed-off-by: Irina Tirdea Acked-by: Bastien Nocera Tested-by: Bastien Nocera Tested-by: Aleksei Mamlin Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/goodix.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 4d113c9e4b771..5479aa17dba80 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -36,6 +36,7 @@ struct goodix_ts_data { unsigned int max_touch_num; unsigned int int_trigger_type; bool rotated_screen; + int cfg_len; }; #define GOODIX_MAX_HEIGHT 4096 @@ -45,6 +46,8 @@ struct goodix_ts_data { #define GOODIX_MAX_CONTACTS 10 #define GOODIX_CONFIG_MAX_LENGTH 240 +#define GOODIX_CONFIG_911_LENGTH 186 +#define GOODIX_CONFIG_967_LENGTH 228 /* Register defines */ #define GOODIX_READ_COOR_ADDR 0x814E @@ -115,6 +118,25 @@ static int goodix_i2c_read(struct i2c_client *client, return ret < 0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0); } +static int goodix_get_cfg_len(u16 id) +{ + switch (id) { + case 911: + case 9271: + case 9110: + case 927: + case 928: + return GOODIX_CONFIG_911_LENGTH; + + case 912: + case 967: + return GOODIX_CONFIG_967_LENGTH; + + default: + return GOODIX_CONFIG_MAX_LENGTH; + } +} + static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data) { int touch_num; @@ -230,8 +252,7 @@ static void goodix_read_config(struct goodix_ts_data *ts) int error; error = goodix_i2c_read(ts->client, GOODIX_REG_CONFIG_DATA, - config, - GOODIX_CONFIG_MAX_LENGTH); + config, ts->cfg_len); if (error) { dev_warn(&ts->client->dev, "Error reading config (%d), using defaults\n", @@ -398,6 +419,8 @@ static int goodix_ts_probe(struct i2c_client *client, return error; } + ts->cfg_len = goodix_get_cfg_len(id_info); + goodix_read_config(ts); error = goodix_request_input_dev(ts, version_info, id_info); -- GitLab From ec6e1b4082d9f5b0858ce33169a1c22a27a982f6 Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Thu, 17 Dec 2015 15:57:34 -0800 Subject: [PATCH 1475/2855] Input: goodix - reset device at init After power on, it is recommended that the driver resets the device. The reset procedure timing is described in the datasheet and is used at device init (before writing device configuration) and for power management. It is a sequence of setting the interrupt and reset pins high/low at specific timing intervals. This procedure also includes setting the slave address to the one specified in the ACPI/device tree. This is based on Goodix datasheets for GT911 and GT9271 and on Goodix driver gt9xx.c for Android (publicly available in Android kernel trees for various devices). For reset the driver needs to control the interrupt and reset gpio pins (configured through ACPI/device tree). For devices that do not have the gpio pins properly declared, the functionality depending on these pins will not be available, but the device can still be used with basic functionality. For both device tree and ACPI, the interrupt gpio pin configuration is read from the "irq-gpios" property and the reset pin configuration is read from the "reset-gpios" property. For ACPI 5.1, named properties can be specified using the _DSD section. This functionality will not be available for devices that use indexed gpio pins declared in the _CRS section (we need to provide backward compatibility with devices that do not support using the interrupt gpio pin as output). For ACPI, the pins can be specified using ACPI 5.1: Device (STAC) { Name (_HID, "GDIX1001") ... Method (_CRS, 0, Serialized) { Name (RBUF, ResourceTemplate () { I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80, AddressingMode7Bit, "\\I2C0", 0x00, ResourceConsumer, , ) GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000, "\\I2C0", 0x00, ResourceConsumer, , ) { // Pin list 0 } GpioIo (Exclusive, PullDown, 0x0000, 0x0000, IoRestrictionOutputOnly, "\\I2C0", 0x00, ResourceConsumer, , ) { 1 } }) Return (RBUF) } Name (_DSD, Package () { ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }}, Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }}, ... } } Signed-off-by: Octavian Purdila Signed-off-by: Irina Tirdea Acked-by: Rob Herring Acked-by: Bastien Nocera Tested-by: Bastien Nocera Tested-by: Aleksei Mamlin Signed-off-by: Dmitry Torokhov --- .../bindings/input/touchscreen/goodix.txt | 9 ++ drivers/input/touchscreen/Kconfig | 1 + drivers/input/touchscreen/goodix.c | 119 ++++++++++++++++++ 3 files changed, 129 insertions(+) diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt index 8ba98eec765bc..c42d2cebac8eb 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt @@ -13,6 +13,12 @@ Required properties: - interrupt-parent : Interrupt controller to which the chip is connected - interrupts : Interrupt to which the chip is connected +Optional properties: + + - irq-gpios : GPIO pin used for IRQ. The driver uses the + interrupt gpio pin as output to reset the device. + - reset-gpios : GPIO pin used for reset + Example: i2c@00000000 { @@ -23,6 +29,9 @@ Example: reg = <0x5d>; interrupt-parent = <&gpio>; interrupts = <0 0>; + + irq-gpios = <&gpio1 0 0>; + reset-gpios = <&gpio1 1 0>; }; /* ... */ diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index ae33da7ab51ff..709527cd4c2ee 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -324,6 +324,7 @@ config TOUCHSCREEN_FUJITSU config TOUCHSCREEN_GOODIX tristate "Goodix I2C touchscreen" depends on I2C + depends on GPIOLIB help Say Y here if you have the Goodix touchscreen (such as one installed in Onda v975w tablets) connected to your diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 5479aa17dba80..6ad379aace723 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -37,8 +38,13 @@ struct goodix_ts_data { unsigned int int_trigger_type; bool rotated_screen; int cfg_len; + struct gpio_desc *gpiod_int; + struct gpio_desc *gpiod_rst; }; +#define GOODIX_GPIO_INT_NAME "irq" +#define GOODIX_GPIO_RST_NAME "reset" + #define GOODIX_MAX_HEIGHT 4096 #define GOODIX_MAX_WIDTH 4096 #define GOODIX_INT_TRIGGER 1 @@ -239,6 +245,106 @@ static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } +static int goodix_int_sync(struct goodix_ts_data *ts) +{ + int error; + + error = gpiod_direction_output(ts->gpiod_int, 0); + if (error) + return error; + + msleep(50); /* T5: 50ms */ + + error = gpiod_direction_input(ts->gpiod_int); + if (error) + return error; + + return 0; +} + +/** + * goodix_reset - Reset device during power on + * + * @ts: goodix_ts_data pointer + */ +static int goodix_reset(struct goodix_ts_data *ts) +{ + int error; + + /* begin select I2C slave addr */ + error = gpiod_direction_output(ts->gpiod_rst, 0); + if (error) + return error; + + msleep(20); /* T2: > 10ms */ + + /* HIGH: 0x28/0x29, LOW: 0xBA/0xBB */ + error = gpiod_direction_output(ts->gpiod_int, ts->client->addr == 0x14); + if (error) + return error; + + usleep_range(100, 2000); /* T3: > 100us */ + + error = gpiod_direction_output(ts->gpiod_rst, 1); + if (error) + return error; + + usleep_range(6000, 10000); /* T4: > 5ms */ + + /* end select I2C slave addr */ + error = gpiod_direction_input(ts->gpiod_rst); + if (error) + return error; + + error = goodix_int_sync(ts); + if (error) + return error; + + return 0; +} + +/** + * goodix_get_gpio_config - Get GPIO config from ACPI/DT + * + * @ts: goodix_ts_data pointer + */ +static int goodix_get_gpio_config(struct goodix_ts_data *ts) +{ + int error; + struct device *dev; + struct gpio_desc *gpiod; + + if (!ts->client) + return -EINVAL; + dev = &ts->client->dev; + + /* Get the interrupt GPIO pin number */ + gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_INT_NAME, GPIOD_IN); + if (IS_ERR(gpiod)) { + error = PTR_ERR(gpiod); + if (error != -EPROBE_DEFER) + dev_dbg(dev, "Failed to get %s GPIO: %d\n", + GOODIX_GPIO_INT_NAME, error); + return error; + } + + ts->gpiod_int = gpiod; + + /* Get the reset line GPIO pin number */ + gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_RST_NAME, GPIOD_IN); + if (IS_ERR(gpiod)) { + error = PTR_ERR(gpiod); + if (error != -EPROBE_DEFER) + dev_dbg(dev, "Failed to get %s GPIO: %d\n", + GOODIX_GPIO_RST_NAME, error); + return error; + } + + ts->gpiod_rst = gpiod; + + return 0; +} + /** * goodix_read_config - Read the embedded configuration of the panel * @@ -407,6 +513,19 @@ static int goodix_ts_probe(struct i2c_client *client, ts->client = client; i2c_set_clientdata(client, ts); + error = goodix_get_gpio_config(ts); + if (error) + return error; + + if (ts->gpiod_int && ts->gpiod_rst) { + /* reset the controller */ + error = goodix_reset(ts); + if (error) { + dev_err(&client->dev, "Controller reset failed.\n"); + return error; + } + } + error = goodix_i2c_test(client); if (error) { dev_err(&client->dev, "I2C communication failure: %d\n", error); -- GitLab From 68caf85881cd842b59d5e2124a236ecce0389a73 Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Thu, 17 Dec 2015 16:05:42 -0800 Subject: [PATCH 1476/2855] Input: goodix - write configuration data to device Goodix devices can be configured by writing custom data to the device at init. The configuration data is read with request_firmware from "goodix__cfg.bin", where is the product id read from the device (e.g.: goodix_911_cfg.bin for Goodix GT911, goodix_9271_cfg.bin for GT9271). The configuration information has a specific format described in the Goodix datasheet. It includes X/Y resolution, maximum supported touch points, interrupt flags, various sensitivity factors and settings for advanced features (like gesture recognition). Before writing the firmware, it is necessary to reset the device. If the device ACPI/DT information does not declare gpio pins (needed for reset), writing the firmware will not be available for these devices. This is based on Goodix datasheets for GT911 and GT9271 and on Goodix driver gt9xx.c for Android (publicly available in Android kernel trees for various devices). Signed-off-by: Octavian Purdila Signed-off-by: Irina Tirdea Tested-by: Bastien Nocera Tested-by: Aleksei Mamlin Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/goodix.c | 244 +++++++++++++++++++++++++---- 1 file changed, 212 insertions(+), 32 deletions(-) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 6ad379aace723..cd92d8ff30598 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -40,6 +41,10 @@ struct goodix_ts_data { int cfg_len; struct gpio_desc *gpiod_int; struct gpio_desc *gpiod_rst; + u16 id; + u16 version; + const char *cfg_name; + struct completion firmware_loading_complete; }; #define GOODIX_GPIO_INT_NAME "irq" @@ -124,6 +129,39 @@ static int goodix_i2c_read(struct i2c_client *client, return ret < 0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0); } +/** + * goodix_i2c_write - write data to a register of the i2c slave device. + * + * @client: i2c device. + * @reg: the register to write to. + * @buf: raw data buffer to write. + * @len: length of the buffer to write + */ +static int goodix_i2c_write(struct i2c_client *client, u16 reg, const u8 *buf, + unsigned len) +{ + u8 *addr_buf; + struct i2c_msg msg; + int ret; + + addr_buf = kmalloc(len + 2, GFP_KERNEL); + if (!addr_buf) + return -ENOMEM; + + addr_buf[0] = reg >> 8; + addr_buf[1] = reg & 0xFF; + memcpy(&addr_buf[2], buf, len); + + msg.flags = 0; + msg.addr = client->addr; + msg.buf = addr_buf; + msg.len = len + 2; + + ret = i2c_transfer(client->adapter, &msg, 1); + kfree(addr_buf); + return ret < 0 ? ret : (ret != 1 ? -EIO : 0); +} + static int goodix_get_cfg_len(u16 id) { switch (id) { @@ -245,6 +283,73 @@ static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } +/** + * goodix_check_cfg - Checks if config fw is valid + * + * @ts: goodix_ts_data pointer + * @cfg: firmware config data + */ +static int goodix_check_cfg(struct goodix_ts_data *ts, + const struct firmware *cfg) +{ + int i, raw_cfg_len; + u8 check_sum = 0; + + if (cfg->size > GOODIX_CONFIG_MAX_LENGTH) { + dev_err(&ts->client->dev, + "The length of the config fw is not correct"); + return -EINVAL; + } + + raw_cfg_len = cfg->size - 2; + for (i = 0; i < raw_cfg_len; i++) + check_sum += cfg->data[i]; + check_sum = (~check_sum) + 1; + if (check_sum != cfg->data[raw_cfg_len]) { + dev_err(&ts->client->dev, + "The checksum of the config fw is not correct"); + return -EINVAL; + } + + if (cfg->data[raw_cfg_len + 1] != 1) { + dev_err(&ts->client->dev, + "Config fw must have Config_Fresh register set"); + return -EINVAL; + } + + return 0; +} + +/** + * goodix_send_cfg - Write fw config to device + * + * @ts: goodix_ts_data pointer + * @cfg: config firmware to write to device + */ +static int goodix_send_cfg(struct goodix_ts_data *ts, + const struct firmware *cfg) +{ + int error; + + error = goodix_check_cfg(ts, cfg); + if (error) + return error; + + error = goodix_i2c_write(ts->client, GOODIX_REG_CONFIG_DATA, cfg->data, + cfg->size); + if (error) { + dev_err(&ts->client->dev, "Failed to write config data: %d", + error); + return error; + } + dev_dbg(&ts->client->dev, "Config sent successfully."); + + /* Let the firmware reconfigure itself, so sleep for 10ms */ + usleep_range(10000, 11000); + + return 0; +} + static int goodix_int_sync(struct goodix_ts_data *ts) { int error; @@ -391,30 +496,29 @@ static void goodix_read_config(struct goodix_ts_data *ts) /** * goodix_read_version - Read goodix touchscreen version * - * @client: the i2c client - * @version: output buffer containing the version on success - * @id: output buffer containing the id on success + * @ts: our goodix_ts_data pointer */ -static int goodix_read_version(struct i2c_client *client, u16 *version, u16 *id) +static int goodix_read_version(struct goodix_ts_data *ts) { int error; u8 buf[6]; char id_str[5]; - error = goodix_i2c_read(client, GOODIX_REG_ID, buf, sizeof(buf)); + error = goodix_i2c_read(ts->client, GOODIX_REG_ID, buf, sizeof(buf)); if (error) { - dev_err(&client->dev, "read version failed: %d\n", error); + dev_err(&ts->client->dev, "read version failed: %d\n", error); return error; } memcpy(id_str, buf, 4); id_str[4] = 0; - if (kstrtou16(id_str, 10, id)) - *id = 0x1001; + if (kstrtou16(id_str, 10, &ts->id)) + ts->id = 0x1001; - *version = get_unaligned_le16(&buf[4]); + ts->version = get_unaligned_le16(&buf[4]); - dev_info(&client->dev, "ID %d, version: %04x\n", *id, *version); + dev_info(&ts->client->dev, "ID %d, version: %04x\n", ts->id, + ts->version); return 0; } @@ -448,13 +552,10 @@ static int goodix_i2c_test(struct i2c_client *client) * goodix_request_input_dev - Allocate, populate and register the input device * * @ts: our goodix_ts_data pointer - * @version: device firmware version - * @id: device ID * * Must be called during probe */ -static int goodix_request_input_dev(struct goodix_ts_data *ts, u16 version, - u16 id) +static int goodix_request_input_dev(struct goodix_ts_data *ts) { int error; @@ -478,8 +579,8 @@ static int goodix_request_input_dev(struct goodix_ts_data *ts, u16 version, ts->input_dev->phys = "input/ts"; ts->input_dev->id.bustype = BUS_I2C; ts->input_dev->id.vendor = 0x0416; - ts->input_dev->id.product = id; - ts->input_dev->id.version = version; + ts->input_dev->id.product = ts->id; + ts->input_dev->id.version = ts->version; error = input_register_device(ts->input_dev); if (error) { @@ -491,13 +592,71 @@ static int goodix_request_input_dev(struct goodix_ts_data *ts, u16 version, return 0; } +/** + * goodix_configure_dev - Finish device initialization + * + * @ts: our goodix_ts_data pointer + * + * Must be called from probe to finish initialization of the device. + * Contains the common initialization code for both devices that + * declare gpio pins and devices that do not. It is either called + * directly from probe or from request_firmware_wait callback. + */ +static int goodix_configure_dev(struct goodix_ts_data *ts) +{ + int error; + unsigned long irq_flags; + + goodix_read_config(ts); + + error = goodix_request_input_dev(ts); + if (error) + return error; + + irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT; + error = devm_request_threaded_irq(&ts->client->dev, ts->client->irq, + NULL, goodix_ts_irq_handler, + irq_flags, ts->client->name, ts); + if (error) { + dev_err(&ts->client->dev, "request IRQ failed: %d\n", error); + return error; + } + + return 0; +} + +/** + * goodix_config_cb - Callback to finish device init + * + * @ts: our goodix_ts_data pointer + * + * request_firmware_wait callback that finishes + * initialization of the device. + */ +static void goodix_config_cb(const struct firmware *cfg, void *ctx) +{ + struct goodix_ts_data *ts = ctx; + int error; + + if (cfg) { + /* send device configuration to the firmware */ + error = goodix_send_cfg(ts, cfg); + if (error) + goto err_release_cfg; + } + + goodix_configure_dev(ts); + +err_release_cfg: + release_firmware(cfg); + complete_all(&ts->firmware_loading_complete); +} + static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct goodix_ts_data *ts; - unsigned long irq_flags; int error; - u16 version_info, id_info; dev_dbg(&client->dev, "I2C Address: 0x%02x\n", client->addr); @@ -512,6 +671,7 @@ static int goodix_ts_probe(struct i2c_client *client, ts->client = client; i2c_set_clientdata(client, ts); + init_completion(&ts->firmware_loading_complete); error = goodix_get_gpio_config(ts); if (error) @@ -532,32 +692,51 @@ static int goodix_ts_probe(struct i2c_client *client, return error; } - error = goodix_read_version(client, &version_info, &id_info); + error = goodix_read_version(ts); if (error) { dev_err(&client->dev, "Read version failed.\n"); return error; } - ts->cfg_len = goodix_get_cfg_len(id_info); - - goodix_read_config(ts); + ts->cfg_len = goodix_get_cfg_len(ts->id); - error = goodix_request_input_dev(ts, version_info, id_info); - if (error) - return error; + if (ts->gpiod_int && ts->gpiod_rst) { + /* update device config */ + ts->cfg_name = devm_kasprintf(&client->dev, GFP_KERNEL, + "goodix_%d_cfg.bin", ts->id); + if (!ts->cfg_name) + return -ENOMEM; + + error = request_firmware_nowait(THIS_MODULE, true, ts->cfg_name, + &client->dev, GFP_KERNEL, ts, + goodix_config_cb); + if (error) { + dev_err(&client->dev, + "Failed to invoke firmware loader: %d\n", + error); + return error; + } - irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT; - error = devm_request_threaded_irq(&ts->client->dev, client->irq, - NULL, goodix_ts_irq_handler, - irq_flags, client->name, ts); - if (error) { - dev_err(&client->dev, "request IRQ failed: %d\n", error); - return error; + return 0; + } else { + error = goodix_configure_dev(ts); + if (error) + return error; } return 0; } +static int goodix_ts_remove(struct i2c_client *client) +{ + struct goodix_ts_data *ts = i2c_get_clientdata(client); + + if (ts->gpiod_int && ts->gpiod_rst) + wait_for_completion(&ts->firmware_loading_complete); + + return 0; +} + static const struct i2c_device_id goodix_ts_id[] = { { "GDIX1001:00", 0 }, { } @@ -588,6 +767,7 @@ MODULE_DEVICE_TABLE(of, goodix_of_match); static struct i2c_driver goodix_ts_driver = { .probe = goodix_ts_probe, + .remove = goodix_ts_remove, .id_table = goodix_ts_id, .driver = { .name = "Goodix-TS", -- GitLab From 5ab09d6a8f6406134085fb3f30ab61968c6f1ddf Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Thu, 17 Dec 2015 16:43:39 -0800 Subject: [PATCH 1477/2855] Input: goodix - add power management support Implement suspend/resume for goodix driver. The suspend and resume process uses the gpio pins. If the device ACPI/DT information does not declare gpio pins, suspend/resume will not be available for these devices. This is based on Goodix datasheets for GT911 and GT9271 and on Goodix driver gt9xx.c for Android (publicly available in Android kernel trees for various devices). Signed-off-by: Octavian Purdila Signed-off-by: Irina Tirdea Tested-by: Bastien Nocera Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/goodix.c | 103 +++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 5 deletions(-) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index cd92d8ff30598..34ed68679853c 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -45,6 +45,7 @@ struct goodix_ts_data { u16 version; const char *cfg_name; struct completion firmware_loading_complete; + unsigned long irq_flags; }; #define GOODIX_GPIO_INT_NAME "irq" @@ -61,6 +62,9 @@ struct goodix_ts_data { #define GOODIX_CONFIG_967_LENGTH 228 /* Register defines */ +#define GOODIX_REG_COMMAND 0x8040 +#define GOODIX_CMD_SCREEN_OFF 0x05 + #define GOODIX_READ_COOR_ADDR 0x814E #define GOODIX_REG_CONFIG_DATA 0x8047 #define GOODIX_REG_ID 0x8140 @@ -162,6 +166,11 @@ static int goodix_i2c_write(struct i2c_client *client, u16 reg, const u8 *buf, return ret < 0 ? ret : (ret != 1 ? -EIO : 0); } +static int goodix_i2c_write_u8(struct i2c_client *client, u16 reg, u8 value) +{ + return goodix_i2c_write(client, reg, &value, sizeof(value)); +} + static int goodix_get_cfg_len(u16 id) { switch (id) { @@ -283,6 +292,18 @@ static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } +static void goodix_free_irq(struct goodix_ts_data *ts) +{ + devm_free_irq(&ts->client->dev, ts->client->irq, ts); +} + +static int goodix_request_irq(struct goodix_ts_data *ts) +{ + return devm_request_threaded_irq(&ts->client->dev, ts->client->irq, + NULL, goodix_ts_irq_handler, + ts->irq_flags, ts->client->name, ts); +} + /** * goodix_check_cfg - Checks if config fw is valid * @@ -605,7 +626,6 @@ static int goodix_request_input_dev(struct goodix_ts_data *ts) static int goodix_configure_dev(struct goodix_ts_data *ts) { int error; - unsigned long irq_flags; goodix_read_config(ts); @@ -613,10 +633,8 @@ static int goodix_configure_dev(struct goodix_ts_data *ts) if (error) return error; - irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT; - error = devm_request_threaded_irq(&ts->client->dev, ts->client->irq, - NULL, goodix_ts_irq_handler, - irq_flags, ts->client->name, ts); + ts->irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT; + error = goodix_request_irq(ts); if (error) { dev_err(&ts->client->dev, "request IRQ failed: %d\n", error); return error; @@ -737,6 +755,80 @@ static int goodix_ts_remove(struct i2c_client *client) return 0; } +static int __maybe_unused goodix_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct goodix_ts_data *ts = i2c_get_clientdata(client); + int error; + + /* We need gpio pins to suspend/resume */ + if (!ts->gpiod_int || !ts->gpiod_rst) + return 0; + + wait_for_completion(&ts->firmware_loading_complete); + + /* Free IRQ as IRQ pin is used as output in the suspend sequence */ + goodix_free_irq(ts); + + /* Output LOW on the INT pin for 5 ms */ + error = gpiod_direction_output(ts->gpiod_int, 0); + if (error) { + goodix_request_irq(ts); + return error; + } + + usleep_range(5000, 6000); + + error = goodix_i2c_write_u8(ts->client, GOODIX_REG_COMMAND, + GOODIX_CMD_SCREEN_OFF); + if (error) { + dev_err(&ts->client->dev, "Screen off command failed\n"); + gpiod_direction_input(ts->gpiod_int); + goodix_request_irq(ts); + return -EAGAIN; + } + + /* + * The datasheet specifies that the interval between sending screen-off + * command and wake-up should be longer than 58 ms. To avoid waking up + * sooner, delay 58ms here. + */ + msleep(58); + return 0; +} + +static int __maybe_unused goodix_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct goodix_ts_data *ts = i2c_get_clientdata(client); + int error; + + if (!ts->gpiod_int || !ts->gpiod_rst) + return 0; + + /* + * Exit sleep mode by outputting HIGH level to INT pin + * for 2ms~5ms. + */ + error = gpiod_direction_output(ts->gpiod_int, 1); + if (error) + return error; + + usleep_range(2000, 5000); + + error = goodix_int_sync(ts); + if (error) + return error; + + error = goodix_request_irq(ts); + if (error) + return error; + + return 0; +} + +static SIMPLE_DEV_PM_OPS(goodix_pm_ops, goodix_suspend, goodix_resume); + static const struct i2c_device_id goodix_ts_id[] = { { "GDIX1001:00", 0 }, { } @@ -773,6 +865,7 @@ static struct i2c_driver goodix_ts_driver = { .name = "Goodix-TS", .acpi_match_table = ACPI_PTR(goodix_acpi_match), .of_match_table = of_match_ptr(goodix_of_match), + .pm = &goodix_pm_ops, }, }; module_i2c_driver(goodix_ts_driver); -- GitLab From 5d655b35466835c6bb8774122db95ecb4e18888d Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Thu, 17 Dec 2015 16:47:42 -0800 Subject: [PATCH 1478/2855] Input: goodix - use goodix_i2c_write_u8 instead of i2c_master_send Use goodix_i2c_write_u8 instead of i2c_master_send to simplify code. Signed-off-by: Irina Tirdea Tested-by: Bastien Nocera Tested-by: Aleksei Mamlin Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/goodix.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 34ed68679853c..0acefe49540d7 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -277,16 +277,11 @@ static void goodix_process_events(struct goodix_ts_data *ts) */ static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id) { - static const u8 end_cmd[] = { - GOODIX_READ_COOR_ADDR >> 8, - GOODIX_READ_COOR_ADDR & 0xff, - 0 - }; struct goodix_ts_data *ts = dev_id; goodix_process_events(ts); - if (i2c_master_send(ts->client, end_cmd, sizeof(end_cmd)) < 0) + if (goodix_i2c_write_u8(ts->client, GOODIX_READ_COOR_ADDR, 0) < 0) dev_err(&ts->client->dev, "I2C write end_cmd error\n"); return IRQ_HANDLED; -- GitLab From ad48cf5e9597147bb2bb526a6d379ee88970dec8 Mon Sep 17 00:00:00 2001 From: Karsten Merker Date: Thu, 17 Dec 2015 17:02:53 -0800 Subject: [PATCH 1479/2855] Input: goodix - add axis swapping and axis inversion support Implement support for the following device-tree and ACPI 5.1 DSD properties in the goodix touchscreen driver: - touchscreen-inverted-x: X axis is inverted (boolean) - touchscreen-inverted-y: Y axis is inverted (boolean) - touchscreen-swapped-x-y: X and Y axis are swapped (boolean) These are necessary on tablets which have a display in portrait format while the touchscreen is in landscape format, such as e.g. the MSI Primo 81. Signed-off-by: Karsten Merker Tested-by: Bastien Nocera Tested-by: Irina Tirdea (with ACPI DSD properties) Tested-by: Aleksei Mamlin (with device-tree properties) Acked-by: Rob Herring Signed-off-by: Dmitry Torokhov --- .../bindings/input/touchscreen/goodix.txt | 5 ++++ drivers/input/touchscreen/goodix.c | 25 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt index c42d2cebac8eb..c98757a69110d 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt @@ -19,6 +19,11 @@ Optional properties: interrupt gpio pin as output to reset the device. - reset-gpios : GPIO pin used for reset + - touchscreen-inverted-x : X axis is inverted (boolean) + - touchscreen-inverted-y : Y axis is inverted (boolean) + - touchscreen-swapped-x-y : X and Y axis are swapped (boolean) + (swapping is done after inverting the axis) + Example: i2c@00000000 { diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 0acefe49540d7..b5e910a44cdf0 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -2,6 +2,7 @@ * Driver for Goodix Touchscreens * * Copyright (c) 2014 Red Hat Inc. + * Copyright (c) 2015 K. Merker * * This code is based on gt9xx.c authored by andrew@goodix.com: * @@ -35,6 +36,9 @@ struct goodix_ts_data { struct input_dev *input_dev; int abs_x_max; int abs_y_max; + bool swapped_x_y; + bool inverted_x; + bool inverted_y; unsigned int max_touch_num; unsigned int int_trigger_type; bool rotated_screen; @@ -235,6 +239,14 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) input_y = ts->abs_y_max - input_y; } + /* Inversions have to happen before axis swapping */ + if (ts->inverted_x) + input_x = ts->abs_x_max - input_x; + if (ts->inverted_y) + input_y = ts->abs_y_max - input_y; + if (ts->swapped_x_y) + swap(input_x, input_y); + input_mt_slot(ts->input_dev, id); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x); @@ -486,6 +498,8 @@ static void goodix_read_config(struct goodix_ts_data *ts) error); ts->abs_x_max = GOODIX_MAX_WIDTH; ts->abs_y_max = GOODIX_MAX_HEIGHT; + if (ts->swapped_x_y) + swap(ts->abs_x_max, ts->abs_y_max); ts->int_trigger_type = GOODIX_INT_TRIGGER; ts->max_touch_num = GOODIX_MAX_CONTACTS; return; @@ -493,6 +507,8 @@ static void goodix_read_config(struct goodix_ts_data *ts) ts->abs_x_max = get_unaligned_le16(&config[RESOLUTION_LOC]); ts->abs_y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]); + if (ts->swapped_x_y) + swap(ts->abs_x_max, ts->abs_y_max); ts->int_trigger_type = config[TRIGGER_LOC] & 0x03; ts->max_touch_num = config[MAX_CONTACTS_LOC] & 0x0f; if (!ts->abs_x_max || !ts->abs_y_max || !ts->max_touch_num) { @@ -500,6 +516,8 @@ static void goodix_read_config(struct goodix_ts_data *ts) "Invalid config, using defaults\n"); ts->abs_x_max = GOODIX_MAX_WIDTH; ts->abs_y_max = GOODIX_MAX_HEIGHT; + if (ts->swapped_x_y) + swap(ts->abs_x_max, ts->abs_y_max); ts->max_touch_num = GOODIX_MAX_CONTACTS; } @@ -622,6 +640,13 @@ static int goodix_configure_dev(struct goodix_ts_data *ts) { int error; + ts->swapped_x_y = device_property_read_bool(&ts->client->dev, + "touchscreen-swapped-x-y"); + ts->inverted_x = device_property_read_bool(&ts->client->dev, + "touchscreen-inverted-x"); + ts->inverted_y = device_property_read_bool(&ts->client->dev, + "touchscreen-inverted-y"); + goodix_read_config(ts); error = goodix_request_input_dev(ts); -- GitLab From 57c80e8e5d1cddae0651e5314394e6069ebbbe3c Mon Sep 17 00:00:00 2001 From: Karsten Merker Date: Thu, 17 Dec 2015 17:08:31 -0800 Subject: [PATCH 1480/2855] Input: goodix - use "inverted_[xy]" flags instead of "rotated_screen" The goodix touchscreen driver uses a "rotated_screen" flag for systems on which the touchscreen is mounted rotated by 180 degrees with respect to the display. With the addition of support for the dt properties "touchscreen-inverted-x" and "touchscreen-inverted-y", a separate "rotated_screen" flag is not necessary anymore. This patch replaces it by setting the inverted_x and inverted_y flags instead. Signed-off-by: Karsten Merker Reviewed-by: Irina Tirdea Tested-by: Bastien Nocera Acked-by: Bastien Nocera Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/goodix.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index b5e910a44cdf0..240b16f3ee979 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -41,7 +41,6 @@ struct goodix_ts_data { bool inverted_y; unsigned int max_touch_num; unsigned int int_trigger_type; - bool rotated_screen; int cfg_len; struct gpio_desc *gpiod_int; struct gpio_desc *gpiod_rst; @@ -234,11 +233,6 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) int input_y = get_unaligned_le16(&coor_data[3]); int input_w = get_unaligned_le16(&coor_data[5]); - if (ts->rotated_screen) { - input_x = ts->abs_x_max - input_x; - input_y = ts->abs_y_max - input_y; - } - /* Inversions have to happen before axis swapping */ if (ts->inverted_x) input_x = ts->abs_x_max - input_x; @@ -521,10 +515,12 @@ static void goodix_read_config(struct goodix_ts_data *ts) ts->max_touch_num = GOODIX_MAX_CONTACTS; } - ts->rotated_screen = dmi_check_system(rotated_screen); - if (ts->rotated_screen) + if (dmi_check_system(rotated_screen)) { + ts->inverted_x = true; + ts->inverted_y = true; dev_dbg(&ts->client->dev, "Applying '180 degrees rotated screen' quirk\n"); + } } /** -- GitLab From 2b574ba9c50a06a1aa6cf908cd44119367111006 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Thu, 17 Dec 2015 23:30:57 +0000 Subject: [PATCH 1481/2855] dmaengine: dw: fix potential memory leak in dw_dma_parse_dt() If the "dma-channels" DT property is missing, the dw_dma_parse_dt() function return NULL, but not before allocating memory for a struct dw_dma_platform_data through devres. If the device supports parameter detection, the probe still succeeds and the allocated memory is not released until the device is removed. Fix this by deferring the allocation until after checking the "dma-channels" property. Signed-off-by: Mans Rullgard Acked-by: Viresh Kumar Signed-off-by: Vinod Koul --- drivers/dma/dw/platform.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c index 68a4815750b51..5a417bbdfbd74 100644 --- a/drivers/dma/dw/platform.c +++ b/drivers/dma/dw/platform.c @@ -103,18 +103,21 @@ dw_dma_parse_dt(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct dw_dma_platform_data *pdata; u32 tmp, arr[DW_DMA_MAX_NR_MASTERS]; + u32 nr_channels; if (!np) { dev_err(&pdev->dev, "Missing DT data\n"); return NULL; } + if (of_property_read_u32(np, "dma-channels", &nr_channels)) + return NULL; + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return NULL; - if (of_property_read_u32(np, "dma-channels", &pdata->nr_channels)) - return NULL; + pdata->nr_channels = nr_channels; if (of_property_read_bool(np, "is_private")) pdata->is_private = true; -- GitLab From 4fa2d09c1ae879c2ee2760ab419a4f97026dd97b Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Dec 2015 15:19:05 +0200 Subject: [PATCH 1482/2855] dmaengine: edma: Add probe callback to edma_tptc_driver Due to changes in device and platform code drivers w/o probe will fail to load. This means that the devices for eDMA TPTCs are goign to be without driver and omap hwmod code will turn them off after the kernel finished loading: [ 3.015900] platform 49800000.tptc: omap_device_late_idle: enabled but no driver. Idling [ 3.024671] platform 49a00000.tptc: omap_device_late_idle: enabled but no driver. Idling This will prevent eDMA to work since the TPTCs are not enabled. Signed-off-by: Peter Ujfalusi Fixes: 34635b1accb9 ("dmaengine: edma: Add dummy driver skeleton for edma3-tptc") Signed-off-by: Vinod Koul --- drivers/dma/edma.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index 6b03e4e84e6bf..5317ae642d1cc 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -2404,7 +2404,13 @@ static struct platform_driver edma_driver = { }, }; +static int edma_tptc_probe(struct platform_device *pdev) +{ + return 0; +} + static struct platform_driver edma_tptc_driver = { + .probe = edma_tptc_probe, .driver = { .name = "edma3-tptc", .of_match_table = edma_tptc_of_ids, -- GitLab From 0c328de77148ddccaa7a2c31f5751e4d443c213b Mon Sep 17 00:00:00 2001 From: "Damien.Horsley" Date: Thu, 10 Dec 2015 15:07:23 +0000 Subject: [PATCH 1483/2855] dmaengine: mdc: Correct terminate_all handling Use of the CANCEL bit in mdc_terminate_all creates an additional 'command done' to appear in the registers (in addition to an interrupt). In addition, there is a potential race between mdc_terminate_all and the irq handler if a transfer completes at the same time as the terminate all (presently this results in an inappropriate warning). To handle these issues, any outstanding 'command done' events are cleared during mdc_terminate_all and the irq handler takes no action when there are no new 'command done' events. Signed-off-by: Damien.Horsley Signed-off-by: Vinod Koul --- drivers/dma/img-mdc-dma.c | 77 ++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 26 deletions(-) diff --git a/drivers/dma/img-mdc-dma.c b/drivers/dma/img-mdc-dma.c index 42ae58d1e3030..a4c53be482cf3 100644 --- a/drivers/dma/img-mdc-dma.c +++ b/drivers/dma/img-mdc-dma.c @@ -651,6 +651,48 @@ static enum dma_status mdc_tx_status(struct dma_chan *chan, return ret; } +static unsigned int mdc_get_new_events(struct mdc_chan *mchan) +{ + u32 val, processed, done1, done2; + unsigned int ret; + + val = mdc_chan_readl(mchan, MDC_CMDS_PROCESSED); + processed = (val >> MDC_CMDS_PROCESSED_CMDS_PROCESSED_SHIFT) & + MDC_CMDS_PROCESSED_CMDS_PROCESSED_MASK; + /* + * CMDS_DONE may have incremented between reading CMDS_PROCESSED + * and clearing INT_ACTIVE. Re-read CMDS_PROCESSED to ensure we + * didn't miss a command completion. + */ + do { + val = mdc_chan_readl(mchan, MDC_CMDS_PROCESSED); + + done1 = (val >> MDC_CMDS_PROCESSED_CMDS_DONE_SHIFT) & + MDC_CMDS_PROCESSED_CMDS_DONE_MASK; + + val &= ~((MDC_CMDS_PROCESSED_CMDS_PROCESSED_MASK << + MDC_CMDS_PROCESSED_CMDS_PROCESSED_SHIFT) | + MDC_CMDS_PROCESSED_INT_ACTIVE); + + val |= done1 << MDC_CMDS_PROCESSED_CMDS_PROCESSED_SHIFT; + + mdc_chan_writel(mchan, val, MDC_CMDS_PROCESSED); + + val = mdc_chan_readl(mchan, MDC_CMDS_PROCESSED); + + done2 = (val >> MDC_CMDS_PROCESSED_CMDS_DONE_SHIFT) & + MDC_CMDS_PROCESSED_CMDS_DONE_MASK; + } while (done1 != done2); + + if (done1 >= processed) + ret = done1 - processed; + else + ret = ((MDC_CMDS_PROCESSED_CMDS_PROCESSED_MASK + 1) - + processed) + done1; + + return ret; +} + static int mdc_terminate_all(struct dma_chan *chan) { struct mdc_chan *mchan = to_mdc_chan(chan); @@ -667,6 +709,8 @@ static int mdc_terminate_all(struct dma_chan *chan) mchan->desc = NULL; vchan_get_all_descriptors(&mchan->vc, &head); + mdc_get_new_events(mchan); + spin_unlock_irqrestore(&mchan->vc.lock, flags); if (mdesc) @@ -703,35 +747,17 @@ static irqreturn_t mdc_chan_irq(int irq, void *dev_id) { struct mdc_chan *mchan = (struct mdc_chan *)dev_id; struct mdc_tx_desc *mdesc; - u32 val, processed, done1, done2; - unsigned int i; + unsigned int i, new_events; spin_lock(&mchan->vc.lock); - val = mdc_chan_readl(mchan, MDC_CMDS_PROCESSED); - processed = (val >> MDC_CMDS_PROCESSED_CMDS_PROCESSED_SHIFT) & - MDC_CMDS_PROCESSED_CMDS_PROCESSED_MASK; - /* - * CMDS_DONE may have incremented between reading CMDS_PROCESSED - * and clearing INT_ACTIVE. Re-read CMDS_PROCESSED to ensure we - * didn't miss a command completion. - */ - do { - val = mdc_chan_readl(mchan, MDC_CMDS_PROCESSED); - done1 = (val >> MDC_CMDS_PROCESSED_CMDS_DONE_SHIFT) & - MDC_CMDS_PROCESSED_CMDS_DONE_MASK; - val &= ~((MDC_CMDS_PROCESSED_CMDS_PROCESSED_MASK << - MDC_CMDS_PROCESSED_CMDS_PROCESSED_SHIFT) | - MDC_CMDS_PROCESSED_INT_ACTIVE); - val |= done1 << MDC_CMDS_PROCESSED_CMDS_PROCESSED_SHIFT; - mdc_chan_writel(mchan, val, MDC_CMDS_PROCESSED); - val = mdc_chan_readl(mchan, MDC_CMDS_PROCESSED); - done2 = (val >> MDC_CMDS_PROCESSED_CMDS_DONE_SHIFT) & - MDC_CMDS_PROCESSED_CMDS_DONE_MASK; - } while (done1 != done2); - dev_dbg(mdma2dev(mchan->mdma), "IRQ on channel %d\n", mchan->chan_nr); + new_events = mdc_get_new_events(mchan); + + if (!new_events) + goto out; + mdesc = mchan->desc; if (!mdesc) { dev_warn(mdma2dev(mchan->mdma), @@ -740,8 +766,7 @@ static irqreturn_t mdc_chan_irq(int irq, void *dev_id) goto out; } - for (i = processed; i != done1; - i = (i + 1) % (MDC_CMDS_PROCESSED_CMDS_PROCESSED_MASK + 1)) { + for (i = 0; i < new_events; i++) { /* * The first interrupt in a transfer indicates that the * command list has been loaded, not that a command has -- GitLab From 26b64256e0c4573f3668ac8329a1266ebb9d6120 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 14 Dec 2015 22:47:38 +0200 Subject: [PATCH 1484/2855] dmaengine: core: Skip mask matching when it is not provided to private_candidate If mask is NULL skip the mask matching against the DMA device capabilities. Signed-off-by: Peter Ujfalusi Reviewed-by: Andy Shevchenko Reviewed-by: Arnd Bergmann Signed-off-by: Vinod Koul --- drivers/dma/dmaengine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 3ecec1445adfc..f2cbff95b56ef 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -511,7 +511,7 @@ static struct dma_chan *private_candidate(const dma_cap_mask_t *mask, { struct dma_chan *chan; - if (!__dma_device_satisfies_mask(dev, mask)) { + if (mask && !__dma_device_satisfies_mask(dev, mask)) { pr_debug("%s: wrong capabilities\n", __func__); return NULL; } -- GitLab From 7bd903c5ca47fde5ad52370a47776491813c772e Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 14 Dec 2015 22:47:39 +0200 Subject: [PATCH 1485/2855] dmaengine: core: Move and merge the code paths using private_candidate Channel matching with private_candidate() is used in two paths, the error checking is slightly different in them and they are duplicating code also. Move the code under find_candidate() to provide consistent execution and going to allow us to reuse this mode of channel lookup later. Signed-off-by: Peter Ujfalusi Reviewed-by: Andy Shevchenko Reviewed-by: Arnd Bergmann Signed-off-by: Vinod Koul --- drivers/dma/dmaengine.c | 81 +++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index f2cbff95b56ef..81a36fc445a75 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -542,6 +542,42 @@ static struct dma_chan *private_candidate(const dma_cap_mask_t *mask, return NULL; } +static struct dma_chan *find_candidate(struct dma_device *device, + const dma_cap_mask_t *mask, + dma_filter_fn fn, void *fn_param) +{ + struct dma_chan *chan = private_candidate(mask, device, fn, fn_param); + int err; + + if (chan) { + /* Found a suitable channel, try to grab, prep, and return it. + * We first set DMA_PRIVATE to disable balance_ref_count as this + * channel will not be published in the general-purpose + * allocator + */ + dma_cap_set(DMA_PRIVATE, device->cap_mask); + device->privatecnt++; + err = dma_chan_get(chan); + + if (err) { + if (err == -ENODEV) { + pr_debug("%s: %s module removed\n", __func__, + dma_chan_name(chan)); + list_del_rcu(&device->global_node); + } else + pr_debug("%s: failed to get %s: (%d)\n", + __func__, dma_chan_name(chan), err); + + if (--device->privatecnt == 0) + dma_cap_clear(DMA_PRIVATE, device->cap_mask); + + chan = ERR_PTR(err); + } + } + + return chan ? chan : ERR_PTR(-EPROBE_DEFER); +} + /** * dma_get_slave_channel - try to get specific channel exclusively * @chan: target channel @@ -580,7 +616,6 @@ struct dma_chan *dma_get_any_slave_channel(struct dma_device *device) { dma_cap_mask_t mask; struct dma_chan *chan; - int err; dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); @@ -588,23 +623,11 @@ struct dma_chan *dma_get_any_slave_channel(struct dma_device *device) /* lock against __dma_request_channel */ mutex_lock(&dma_list_mutex); - chan = private_candidate(&mask, device, NULL, NULL); - if (chan) { - dma_cap_set(DMA_PRIVATE, device->cap_mask); - device->privatecnt++; - err = dma_chan_get(chan); - if (err) { - pr_debug("%s: failed to get %s: (%d)\n", - __func__, dma_chan_name(chan), err); - chan = NULL; - if (--device->privatecnt == 0) - dma_cap_clear(DMA_PRIVATE, device->cap_mask); - } - } + chan = find_candidate(device, &mask, NULL, NULL); mutex_unlock(&dma_list_mutex); - return chan; + return IS_ERR(chan) ? NULL : chan; } EXPORT_SYMBOL_GPL(dma_get_any_slave_channel); @@ -621,35 +644,15 @@ struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, { struct dma_device *device, *_d; struct dma_chan *chan = NULL; - int err; /* Find a channel */ mutex_lock(&dma_list_mutex); list_for_each_entry_safe(device, _d, &dma_device_list, global_node) { - chan = private_candidate(mask, device, fn, fn_param); - if (chan) { - /* Found a suitable channel, try to grab, prep, and - * return it. We first set DMA_PRIVATE to disable - * balance_ref_count as this channel will not be - * published in the general-purpose allocator - */ - dma_cap_set(DMA_PRIVATE, device->cap_mask); - device->privatecnt++; - err = dma_chan_get(chan); + chan = find_candidate(device, mask, fn, fn_param); + if (!IS_ERR(chan)) + break; - if (err == -ENODEV) { - pr_debug("%s: %s module removed\n", - __func__, dma_chan_name(chan)); - list_del_rcu(&device->global_node); - } else if (err) - pr_debug("%s: failed to get %s: (%d)\n", - __func__, dma_chan_name(chan), err); - else - break; - if (--device->privatecnt == 0) - dma_cap_clear(DMA_PRIVATE, device->cap_mask); - chan = NULL; - } + chan = NULL; } mutex_unlock(&dma_list_mutex); -- GitLab From a8135d0d79e9d0ad3a4ff494fceeaae838becf38 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 14 Dec 2015 22:47:40 +0200 Subject: [PATCH 1486/2855] dmaengine: core: Introduce new, universal API to request a channel The two API function can cover most, if not all current APIs used to request a channel. With minimal effort dmaengine drivers, platforms and dmaengine user drivers can be converted to use the two function. struct dma_chan *dma_request_chan_by_mask(const dma_cap_mask_t *mask); To request any channel matching with the requested capabilities, can be used to request channel for memcpy, memset, xor, etc where no hardware synchronization is needed. struct dma_chan *dma_request_chan(struct device *dev, const char *name); To request a slave channel. The dma_request_chan() will try to find the channel via DT, ACPI or in case if the kernel booted in non DT/ACPI mode it will use a filter lookup table and retrieves the needed information from the dma_slave_map provided by the DMA drivers. This legacy mode needs changes in platform code, in dmaengine drivers and finally the dmaengine user drivers can be converted: For each dmaengine driver an array of DMA device, slave and the parameter for the filter function needs to be added: static const struct dma_slave_map da830_edma_map[] = { { "davinci-mcasp.0", "rx", EDMA_FILTER_PARAM(0, 0) }, { "davinci-mcasp.0", "tx", EDMA_FILTER_PARAM(0, 1) }, { "davinci-mcasp.1", "rx", EDMA_FILTER_PARAM(0, 2) }, { "davinci-mcasp.1", "tx", EDMA_FILTER_PARAM(0, 3) }, { "davinci-mcasp.2", "rx", EDMA_FILTER_PARAM(0, 4) }, { "davinci-mcasp.2", "tx", EDMA_FILTER_PARAM(0, 5) }, { "spi_davinci.0", "rx", EDMA_FILTER_PARAM(0, 14) }, { "spi_davinci.0", "tx", EDMA_FILTER_PARAM(0, 15) }, { "da830-mmc.0", "rx", EDMA_FILTER_PARAM(0, 16) }, { "da830-mmc.0", "tx", EDMA_FILTER_PARAM(0, 17) }, { "spi_davinci.1", "rx", EDMA_FILTER_PARAM(0, 18) }, { "spi_davinci.1", "tx", EDMA_FILTER_PARAM(0, 19) }, }; This information is going to be needed by the dmaengine driver, so modification to the platform_data is needed, and the driver map should be added to the pdata of the DMA driver: da8xx_edma0_pdata.slave_map = da830_edma_map; da8xx_edma0_pdata.slavecnt = ARRAY_SIZE(da830_edma_map); The DMA driver then needs to configure the needed device -> filter_fn mapping before it registers with dma_async_device_register() : ecc->dma_slave.filter_map.map = info->slave_map; ecc->dma_slave.filter_map.mapcnt = info->slavecnt; ecc->dma_slave.filter_map.fn = edma_filter_fn; When neither DT or ACPI lookup is available the dma_request_chan() will try to match the requester's device name with the filter_map's list of device names, when a match found it will use the information from the dma_slave_map to get the channel with the dma_get_channel() internal function. Signed-off-by: Peter Ujfalusi Reviewed-by: Arnd Bergmann Signed-off-by: Vinod Koul --- Documentation/dmaengine/client.txt | 23 ++------ drivers/dma/dmaengine.c | 89 ++++++++++++++++++++++++++---- include/linux/dmaengine.h | 51 ++++++++++++++--- 3 files changed, 127 insertions(+), 36 deletions(-) diff --git a/Documentation/dmaengine/client.txt b/Documentation/dmaengine/client.txt index 11fb87ff6cd09..4b04d89887081 100644 --- a/Documentation/dmaengine/client.txt +++ b/Documentation/dmaengine/client.txt @@ -22,25 +22,14 @@ The slave DMA usage consists of following steps: Channel allocation is slightly different in the slave DMA context, client drivers typically need a channel from a particular DMA controller only and even in some cases a specific channel is desired. - To request a channel dma_request_channel() API is used. + To request a channel dma_request_chan() API is used. Interface: - struct dma_chan *dma_request_channel(dma_cap_mask_t mask, - dma_filter_fn filter_fn, - void *filter_param); - where dma_filter_fn is defined as: - typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param); - - The 'filter_fn' parameter is optional, but highly recommended for - slave and cyclic channels as they typically need to obtain a specific - DMA channel. - - When the optional 'filter_fn' parameter is NULL, dma_request_channel() - simply returns the first channel that satisfies the capability mask. - - Otherwise, the 'filter_fn' routine will be called once for each free - channel which has a capability in 'mask'. 'filter_fn' is expected to - return 'true' when the desired DMA channel is found. + struct dma_chan *dma_request_chan(struct device *dev, const char *name); + + Which will find and return the 'name' DMA channel associated with the 'dev' + device. The association is done via DT, ACPI or board file based + dma_slave_map matching table. A channel allocated via this interface is exclusive to the caller, until dma_release_channel() is called. diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 81a36fc445a75..a094dbb54f464 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -43,6 +43,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include #include @@ -665,27 +666,73 @@ struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, } EXPORT_SYMBOL_GPL(__dma_request_channel); +static const struct dma_slave_map *dma_filter_match(struct dma_device *device, + const char *name, + struct device *dev) +{ + int i; + + if (!device->filter.mapcnt) + return NULL; + + for (i = 0; i < device->filter.mapcnt; i++) { + const struct dma_slave_map *map = &device->filter.map[i]; + + if (!strcmp(map->devname, dev_name(dev)) && + !strcmp(map->slave, name)) + return map; + } + + return NULL; +} + /** - * dma_request_slave_channel_reason - try to allocate an exclusive slave channel + * dma_request_chan - try to allocate an exclusive slave channel * @dev: pointer to client device structure * @name: slave channel name * * Returns pointer to appropriate DMA channel on success or an error pointer. */ -struct dma_chan *dma_request_slave_channel_reason(struct device *dev, - const char *name) +struct dma_chan *dma_request_chan(struct device *dev, const char *name) { + struct dma_device *d, *_d; + struct dma_chan *chan = NULL; + /* If device-tree is present get slave info from here */ if (dev->of_node) - return of_dma_request_slave_channel(dev->of_node, name); + chan = of_dma_request_slave_channel(dev->of_node, name); /* If device was enumerated by ACPI get slave info from here */ - if (ACPI_HANDLE(dev)) - return acpi_dma_request_slave_chan_by_name(dev, name); + if (has_acpi_companion(dev) && !chan) + chan = acpi_dma_request_slave_chan_by_name(dev, name); + + if (chan) { + /* Valid channel found or requester need to be deferred */ + if (!IS_ERR(chan) || PTR_ERR(chan) == -EPROBE_DEFER) + return chan; + } + + /* Try to find the channel via the DMA filter map(s) */ + mutex_lock(&dma_list_mutex); + list_for_each_entry_safe(d, _d, &dma_device_list, global_node) { + dma_cap_mask_t mask; + const struct dma_slave_map *map = dma_filter_match(d, name, dev); + + if (!map) + continue; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); - return ERR_PTR(-ENODEV); + chan = find_candidate(d, &mask, d->filter.fn, map->param); + if (!IS_ERR(chan)) + break; + } + mutex_unlock(&dma_list_mutex); + + return chan ? chan : ERR_PTR(-EPROBE_DEFER); } -EXPORT_SYMBOL_GPL(dma_request_slave_channel_reason); +EXPORT_SYMBOL_GPL(dma_request_chan); /** * dma_request_slave_channel - try to allocate an exclusive slave channel @@ -697,17 +744,35 @@ EXPORT_SYMBOL_GPL(dma_request_slave_channel_reason); struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name) { - struct dma_chan *ch = dma_request_slave_channel_reason(dev, name); + struct dma_chan *ch = dma_request_chan(dev, name); if (IS_ERR(ch)) return NULL; - dma_cap_set(DMA_PRIVATE, ch->device->cap_mask); - ch->device->privatecnt++; - return ch; } EXPORT_SYMBOL_GPL(dma_request_slave_channel); +/** + * dma_request_chan_by_mask - allocate a channel satisfying certain capabilities + * @mask: capabilities that the channel must satisfy + * + * Returns pointer to appropriate DMA channel on success or an error pointer. + */ +struct dma_chan *dma_request_chan_by_mask(const dma_cap_mask_t *mask) +{ + struct dma_chan *chan; + + if (!mask) + return ERR_PTR(-ENODEV); + + chan = __dma_request_channel(mask, NULL, NULL); + if (!chan) + chan = ERR_PTR(-ENODEV); + + return chan; +} +EXPORT_SYMBOL_GPL(dma_request_chan_by_mask); + void dma_release_channel(struct dma_chan *chan) { mutex_lock(&dma_list_mutex); diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index c47c68e535e8d..d50a6b51a73d6 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -606,12 +606,39 @@ enum dmaengine_alignment { DMAENGINE_ALIGN_64_BYTES = 6, }; +/** + * struct dma_slave_map - associates slave device and it's slave channel with + * parameter to be used by a filter function + * @devname: name of the device + * @slave: slave channel name + * @param: opaque parameter to pass to struct dma_filter.fn + */ +struct dma_slave_map { + const char *devname; + const char *slave; + void *param; +}; + +/** + * struct dma_filter - information for slave device/channel to filter_fn/param + * mapping + * @fn: filter function callback + * @mapcnt: number of slave device/channel in the map + * @map: array of channel to filter mapping data + */ +struct dma_filter { + dma_filter_fn fn; + int mapcnt; + const struct dma_slave_map *map; +}; + /** * struct dma_device - info on the entity supplying DMA services * @chancnt: how many DMA channels are supported * @privatecnt: how many DMA channels are requested by dma_request_channel * @channels: the list of struct dma_chan * @global_node: list_head for global dma_device_list + * @filter: information for device/slave to filter function/param mapping * @cap_mask: one or more dma_capability flags * @max_xor: maximum number of xor sources, 0 if no capability * @max_pq: maximum number of PQ sources and PQ-continue capability @@ -666,6 +693,7 @@ struct dma_device { unsigned int privatecnt; struct list_head channels; struct list_head global_node; + struct dma_filter filter; dma_cap_mask_t cap_mask; unsigned short max_xor; unsigned short max_pq; @@ -1140,9 +1168,11 @@ enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx); void dma_issue_pending_all(void); struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param); -struct dma_chan *dma_request_slave_channel_reason(struct device *dev, - const char *name); struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name); + +struct dma_chan *dma_request_chan(struct device *dev, const char *name); +struct dma_chan *dma_request_chan_by_mask(const dma_cap_mask_t *mask); + void dma_release_channel(struct dma_chan *chan); int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps); #else @@ -1166,16 +1196,21 @@ static inline struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, { return NULL; } -static inline struct dma_chan *dma_request_slave_channel_reason( - struct device *dev, const char *name) -{ - return ERR_PTR(-ENODEV); -} static inline struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name) { return NULL; } +static inline struct dma_chan *dma_request_chan(struct device *dev, + const char *name) +{ + return ERR_PTR(-ENODEV); +} +static inline struct dma_chan *dma_request_chan_by_mask( + const dma_cap_mask_t *mask) +{ + return ERR_PTR(-ENODEV); +} static inline void dma_release_channel(struct dma_chan *chan) { } @@ -1186,6 +1221,8 @@ static inline int dma_get_slave_caps(struct dma_chan *chan, } #endif +#define dma_request_slave_channel_reason(dev, name) dma_request_chan(dev, name) + static inline int dmaengine_desc_set_reuse(struct dma_async_tx_descriptor *tx) { struct dma_slave_caps caps; -- GitLab From 23e6723c060faf5a0fc8d7bfbec440d29943fa99 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 14 Dec 2015 22:47:41 +0200 Subject: [PATCH 1487/2855] dmaengine: edma: Add support for DMA filter mapping to slave devices Add support for providing device to filter_fn mapping so client drivers can switch to use the dma_request_chan() API. Signed-off-by: Peter Ujfalusi Reviewed-by: Arnd Bergmann Signed-off-by: Vinod Koul --- drivers/dma/edma.c | 4 ++++ include/linux/platform_data/edma.h | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index 6b03e4e84e6bf..c7a011f4b860c 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -2297,6 +2297,10 @@ static int edma_probe(struct platform_device *pdev) edma_set_chmap(&ecc->slave_chans[i], ecc->dummy_slot); } + ecc->dma_slave.filter.map = info->slave_map; + ecc->dma_slave.filter.mapcnt = info->slavecnt; + ecc->dma_slave.filter.fn = edma_filter_fn; + ret = dma_async_device_register(&ecc->dma_slave); if (ret) { dev_err(dev, "slave ddev registration failed (%d)\n", ret); diff --git a/include/linux/platform_data/edma.h b/include/linux/platform_data/edma.h index e2878baeb90e8..105700e62ea18 100644 --- a/include/linux/platform_data/edma.h +++ b/include/linux/platform_data/edma.h @@ -53,12 +53,16 @@ enum dma_event_q { #define EDMA_CTLR(i) ((i) >> 16) #define EDMA_CHAN_SLOT(i) ((i) & 0xffff) +#define EDMA_FILTER_PARAM(ctlr, chan) ((int[]) { EDMA_CTLR_CHAN(ctlr, chan) }) + struct edma_rsv_info { const s16 (*rsv_chans)[2]; const s16 (*rsv_slots)[2]; }; +struct dma_slave_map; + /* platform_data for EDMA driver */ struct edma_soc_info { /* @@ -76,6 +80,9 @@ struct edma_soc_info { s8 (*queue_priority_mapping)[2]; const s16 (*xbar_chans)[2]; + + const struct dma_slave_map *slave_map; + int slavecnt; }; #endif -- GitLab From 020c62ae38946cae01571a0b4e6f445dfdb7ec1c Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 14 Dec 2015 22:47:42 +0200 Subject: [PATCH 1488/2855] dmaengine: omap-dma: Add support for DMA filter mapping to slave devices Add support for providing device to filter_fn mapping so client drivers can switch to use the dma_request_chan() API. Signed-off-by: Peter Ujfalusi Reviewed-by: Arnd Bergmann Signed-off-by: Vinod Koul --- drivers/dma/omap-dma.c | 4 ++++ include/linux/omap-dma.h | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index 1dfc71c90123f..48f77c289cd3f 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -1203,6 +1203,10 @@ static int omap_dma_probe(struct platform_device *pdev) return rc; } + od->ddev.filter.map = od->plat->slave_map; + od->ddev.filter.mapcnt = od->plat->slavecnt; + od->ddev.filter.fn = omap_dma_filter_fn; + rc = dma_async_device_register(&od->ddev); if (rc) { pr_warn("OMAP-DMA: failed to register slave DMA engine device: %d\n", diff --git a/include/linux/omap-dma.h b/include/linux/omap-dma.h index 88fa8af2b937c..1d99b61adc65f 100644 --- a/include/linux/omap-dma.h +++ b/include/linux/omap-dma.h @@ -267,6 +267,9 @@ struct omap_dma_reg { u8 type; }; +#define SDMA_FILTER_PARAM(hw_req) ((int[]) { (hw_req) }) +struct dma_slave_map; + /* System DMA platform data structure */ struct omap_system_dma_plat_info { const struct omap_dma_reg *reg_map; @@ -278,6 +281,9 @@ struct omap_system_dma_plat_info { void (*clear_dma)(int lch); void (*dma_write)(u32 val, int reg, int lch); u32 (*dma_read)(int reg, int lch); + + const struct dma_slave_map *slave_map; + int slavecnt; }; #ifdef CONFIG_ARCH_OMAP2PLUS -- GitLab From 47769cbc09ebb13ffd1e2d017b698dddf7fd2855 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Fri, 18 Dec 2015 15:11:33 +0800 Subject: [PATCH 1489/2855] regulator: mt6311: Use REGCACHE_RBTREE This regulator is on a slow i2c bus. Register accesses are very simple, they all either enable/disable a regulator channel, or select a new voltage level. Thus, reading registers from the device will always return what was last written. Therefore we can save a lot of time when reading registers by using a regmap_cache. Since the register map is relatively large, but we only ever access a few of them, we use an RBTREE cache. Signed-off-by: Daniel Kurtz Acked-by: Henry Chen Signed-off-by: Mark Brown --- drivers/regulator/mt6311-regulator.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/regulator/mt6311-regulator.c b/drivers/regulator/mt6311-regulator.c index 02c4e5feca8e4..0495716fd35f1 100644 --- a/drivers/regulator/mt6311-regulator.c +++ b/drivers/regulator/mt6311-regulator.c @@ -30,6 +30,7 @@ static const struct regmap_config mt6311_regmap_config = { .reg_bits = 8, .val_bits = 8, .max_register = MT6311_FQMTR_CON4, + .cache_type = REGCACHE_RBTREE, }; /* Default limits measured in millivolts and milliamps */ -- GitLab From 9552a66fe622ed53b87278a90917a37a5245e68a Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 24 Nov 2015 12:18:22 +0100 Subject: [PATCH 1490/2855] s390/facilities: use stfl mnemonic instead of insn magic Now that 31 bit support is gone, the assembler always knows about the stfl instruction. Therefore lets use a readable mnemonic. Also remove the not needed extable entry for the inline assembly and fix the output constraint. Signed-off-by: Heiko Carstens Reviewed-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/facility.h | 6 ++---- arch/s390/kernel/head.S | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/s390/include/asm/facility.h b/arch/s390/include/asm/facility.h index 0aa6a7ed95a35..b4f99d22ba047 100644 --- a/arch/s390/include/asm/facility.h +++ b/arch/s390/include/asm/facility.h @@ -44,10 +44,8 @@ static inline void stfle(u64 *stfle_fac_list, int size) preempt_disable(); asm volatile( - " .insn s,0xb2b10000,0(0)\n" /* stfl */ - "0:\n" - EX_TABLE(0b, 0b) - : "+m" (S390_lowcore.stfl_fac_list)); + " stfl 0(0)\n" + : "=m" (S390_lowcore.stfl_fac_list)); nr = 4; /* bytes stored by stfl */ memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4); if (S390_lowcore.stfl_fac_list & 0x01000000) { diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index 301ee9c70688b..d893d5aeb3070 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -306,7 +306,7 @@ ENTRY(startup_kdump) mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13) xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10} - .insn s,0xb2b10000,0 # store facilities @ __LC_STFL_FAC_LIST + stfl 0(%r0) # store facilities @ __LC_STFL_FAC_LIST tm __LC_STFL_FAC_LIST,0x01 # stfle available ? jz 0f la %r0,1 -- GitLab From 76cdd44c2e56ffabc297494c090c6babc8985998 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 24 Nov 2015 12:33:07 +0100 Subject: [PATCH 1491/2855] s390/facilities: always use lowcore's stfle field for storing facility bits head.s contains an stfle instruction which stores it result at the storage location that is assigned to the stfl instruction. This is currently no problem, since we only care about one double word. However if the number of double words in the ALS bitfield grows the current code is not very stable. E.g. before issuing the stfle command the memory to which it stores must be cleared, since the instruction may or may not clear memory contents where no bits are set. In order to simplify the code a bit always use the storage location that we reserved for the stfle result. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/asm-offsets.c | 1 + arch/s390/kernel/head.S | 10 +++++----- arch/s390/kernel/head64.S | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index ae7b565b6c4c7..d8d18f8d8b775 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -120,6 +120,7 @@ int main(void) OFFSET(__LC_IO_INT_PARM, _lowcore, io_int_parm); OFFSET(__LC_IO_INT_WORD, _lowcore, io_int_word); OFFSET(__LC_STFL_FAC_LIST, _lowcore, stfl_fac_list); + OFFSET(__LC_STFLE_FAC_LIST, _lowcore, stfle_fac_list); OFFSET(__LC_MCCK_CODE, _lowcore, mcck_interruption_code); OFFSET(__LC_MCCK_FAIL_STOR_ADDR, _lowcore, failing_storage_address); OFFSET(__LC_LAST_BREAK, _lowcore, breaking_event_addr); diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index d893d5aeb3070..d28a148491268 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -300,19 +300,19 @@ ENTRY(startup_kdump) xc 0x200(256),0x200 # partially clear lowcore xc 0x300(256),0x300 xc 0xe00(256),0xe00 + xc 0xf00(256),0xf00 lctlg %c0,%c15,0x200(%r0) # initialize control registers stck __LC_LAST_UPDATE_CLOCK spt 6f-.LPG0(%r13) mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13) - xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST - # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10} stfl 0(%r0) # store facilities @ __LC_STFL_FAC_LIST - tm __LC_STFL_FAC_LIST,0x01 # stfle available ? + mvc __LC_STFLE_FAC_LIST(4),__LC_STFL_FAC_LIST + tm __LC_STFLE_FAC_LIST,0x01 # stfle available ? jz 0f la %r0,1 - .insn s,0xb2b00000,__LC_STFL_FAC_LIST # store facility list extended + .insn s,0xb2b00000,__LC_STFLE_FAC_LIST # store facility list extended # verify if all required facilities are supported by the machine -0: la %r1,__LC_STFL_FAC_LIST +0: la %r1,__LC_STFLE_FAC_LIST la %r2,3f+8-.LPG0(%r13) l %r3,0(%r2) 1: l %r0,0(%r1) diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 58b719fa8067a..c5febe84eba63 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S @@ -16,7 +16,7 @@ __HEAD ENTRY(startup_continue) - tm __LC_STFL_FAC_LIST+6,0x80 # LPP available ? + tm __LC_STFLE_FAC_LIST+6,0x80 # LPP available ? jz 0f xc __LC_LPP+1(7,0),__LC_LPP+1 # clear lpp and current_pid mvi __LC_LPP,0x80 # and set LPP_MAGIC -- GitLab From c30f6828fed9d33c2d54dfaf3621717c56f9c779 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 2 Feb 2015 07:08:44 +0100 Subject: [PATCH 1492/2855] s390/facilities: add helper tool to generate facility lists Modifying the architecture level set facility lists was always very error prone. Given the numbering of the facility bits within the Principles of Operation, where the most significant bit number is 0, it happened a lot of times that wrong bits were set or cleared. Therefore this patch adds a tool "gen_facilities" which generates include/generated/facilites.h. The definition of the bits to be set is contained within arch/s390/include/asm/facilities_src.h and can be easily extended to e.g. also generate such lists for the KVM module. The generated file looks like this: #define FACILITIES_ALS _AC(0xc1006450f0040000,UL) #define FACILITIES_ALS_DWORDS 1 The facility bits defined in this patch match 1:1 to the current masks that can be found in head.S. That is if the tool gets executed with -march=z990 then the generated masks will equal the masks in head.S for CONFIG_MARCH_Z990. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Makefile | 5 ++ arch/s390/include/asm/facilities_src.h | 67 ++++++++++++++++++++++++++ arch/s390/include/asm/facility.h | 5 ++ arch/s390/tools/.gitignore | 1 + arch/s390/tools/Makefile | 15 ++++++ arch/s390/tools/gen_facilities.c | 67 ++++++++++++++++++++++++++ 6 files changed, 160 insertions(+) create mode 100644 arch/s390/include/asm/facilities_src.h create mode 100644 arch/s390/tools/.gitignore create mode 100644 arch/s390/tools/Makefile create mode 100644 arch/s390/tools/gen_facilities.c diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 647bd14b223e0..224b42734f0d9 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -106,6 +106,7 @@ drivers-y += drivers/s390/ drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/ boot := arch/s390/boot +tools := arch/s390/tools all: image bzImage @@ -124,6 +125,10 @@ vdso_install: archclean: $(Q)$(MAKE) $(clean)=$(boot) + $(Q)$(MAKE) $(clean)=$(tools) + +archprepare: + $(Q)$(MAKE) $(build)=$(tools) include/generated/facilities.h # Don't use tabs in echo arguments define archhelp diff --git a/arch/s390/include/asm/facilities_src.h b/arch/s390/include/asm/facilities_src.h new file mode 100644 index 0000000000000..4555fa69a29e6 --- /dev/null +++ b/arch/s390/include/asm/facilities_src.h @@ -0,0 +1,67 @@ +/* + * Copyright IBM Corp. 2015 + */ + +#ifndef S390_GEN_FACILITIES_C +#error "This file can only be included by gen_facilities.c" +#endif + +#include + +struct facility_def { + char *name; + int *bits; +}; + +static struct facility_def facility_defs[] = { + { + /* + * FACILITIES_ALS contains the list of facilities that are + * required to run a kernel that is compiled e.g. with + * -march=. + */ + .name = "FACILITIES_ALS", + .bits = (int[]){ +#ifdef CONFIG_HAVE_MARCH_Z900_FEATURES + 0, /* N3 instructions */ + 1, /* z/Arch mode installed */ +#endif +#ifdef CONFIG_HAVE_MARCH_Z990_FEATURES + 18, /* long displacement facility */ +#endif +#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES + 7, /* stfle */ + 16, /* extended translation facility 2 */ + 17, /* message security assist */ + 20, /* HFP-multiply-and-add */ + 21, /* extended-immediate facility */ + 22, /* extended-translation facility 3 */ + 23, /* HFP-unnormalized-extension */ + 24, /* ETF2-enhancement */ + 25, /* store clock fast */ + 30, /* ETF3-enhancement */ +#endif +#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES + 26, /* parsing enhancement facility */ + 27, /* mvcos */ + 32, /* compare and swap and store */ + 33, /* compare and swap and store 2 */ + 34, /* general extension facility */ + 35, /* execute extensions */ + 41, /* floating point support enhancement */ + 42, /* DFP facility */ + 44, /* PFPO */ +#endif +#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES + 37, /* floating point extension */ + 45, /* fast-BCR, etc. */ +#endif +#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES + 48, /* decimal floating point zoned */ + 49, /* misc-instruction-extensions */ + 52, /* interlocked facility 2 */ +#endif + -1 /* END */ + } + }, +}; diff --git a/arch/s390/include/asm/facility.h b/arch/s390/include/asm/facility.h index b4f99d22ba047..007163f91856d 100644 --- a/arch/s390/include/asm/facility.h +++ b/arch/s390/include/asm/facility.h @@ -7,6 +7,10 @@ #ifndef __ASM_FACILITY_H #define __ASM_FACILITY_H +#include + +#ifndef __ASSEMBLY__ + #include #include #include @@ -62,4 +66,5 @@ static inline void stfle(u64 *stfle_fac_list, int size) preempt_enable(); } +#endif /* __ASSEMBLY__ */ #endif /* __ASM_FACILITY_H */ diff --git a/arch/s390/tools/.gitignore b/arch/s390/tools/.gitignore new file mode 100644 index 0000000000000..72a4b2cf13653 --- /dev/null +++ b/arch/s390/tools/.gitignore @@ -0,0 +1 @@ +gen_facilities diff --git a/arch/s390/tools/Makefile b/arch/s390/tools/Makefile new file mode 100644 index 0000000000000..6d9814c9df2bc --- /dev/null +++ b/arch/s390/tools/Makefile @@ -0,0 +1,15 @@ +# +# Makefile for s390 specific build tools +# + +hostprogs-y += gen_facilities +HOSTCFLAGS_gen_facilities.o += -Wall $(LINUXINCLUDE) + +define filechk_facilities.h + $(obj)/gen_facilities +endef + +$(obj)/gen_facilities.o: $(srctree)/arch/s390/tools/gen_facilities.c + +include/generated/facilities.h: $(obj)/gen_facilities FORCE + $(call filechk,facilities.h) diff --git a/arch/s390/tools/gen_facilities.c b/arch/s390/tools/gen_facilities.c new file mode 100644 index 0000000000000..e2660d27889b6 --- /dev/null +++ b/arch/s390/tools/gen_facilities.c @@ -0,0 +1,67 @@ +/* + * Simple program to generate defines out of facility lists that use the bit + * numbering scheme from the Princples of Operations: most significant bit + * has bit number 0. + * + * Copyright IBM Corp. 2015 + * + */ + +#define S390_GEN_FACILITIES_C + +#include +#include +#include +#include +#include + +static void print_facility_list(struct facility_def *def) +{ + unsigned int high, bit, dword, i; + unsigned long long *array; + + array = calloc(1, 8); + if (!array) + exit(EXIT_FAILURE); + high = 0; + for (i = 0; def->bits[i] != -1; i++) { + bit = 63 - (def->bits[i] & 63); + dword = def->bits[i] / 64; + if (dword > high) { + array = realloc(array, (dword + 1) * 8); + if (!array) + exit(EXIT_FAILURE); + memset(array + high + 1, 0, (dword - high) * 8); + high = dword; + } + array[dword] |= 1ULL << bit; + } + printf("#define %s ", def->name); + for (i = 0; i <= high; i++) + printf("_AC(0x%016llx,UL)%c", array[i], i < high ? ',' : '\n'); + printf("#define %s_DWORDS %d\n", def->name, high + 1); + free(array); +} + +static void print_facility_lists(void) +{ + unsigned int i; + + for (i = 0; i < sizeof(facility_defs) / sizeof(facility_defs[0]); i++) + print_facility_list(&facility_defs[i]); +} + +int main(int argc, char **argv) +{ + printf("#ifndef __ASM_S390_FACILITIES__\n"); + printf("#define __ASM_S390_FACILITIES__\n"); + printf("/*\n"); + printf(" * DO NOT MODIFY.\n"); + printf(" *\n"); + printf(" * This file was generated by %s\n", __FILE__); + printf(" */\n\n"); + printf("#include \n\n"); + print_facility_lists(); + printf("\n#endif\n"); + return 0; +} -- GitLab From 0358ecf7327f0cb206b14138353e1cbe612c5d64 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 24 Nov 2015 12:47:14 +0100 Subject: [PATCH 1493/2855] s390/facilities: make use of generated facility list Change head.S to make use of the generated facility list. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/head.S | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index d28a148491268..fcaefb041364c 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -309,18 +310,18 @@ ENTRY(startup_kdump) mvc __LC_STFLE_FAC_LIST(4),__LC_STFL_FAC_LIST tm __LC_STFLE_FAC_LIST,0x01 # stfle available ? jz 0f - la %r0,1 + lghi %r0,FACILITIES_ALS_DWORDS-1 .insn s,0xb2b00000,__LC_STFLE_FAC_LIST # store facility list extended # verify if all required facilities are supported by the machine 0: la %r1,__LC_STFLE_FAC_LIST la %r2,3f+8-.LPG0(%r13) - l %r3,0(%r2) -1: l %r0,0(%r1) - n %r0,4(%r2) - cl %r0,4(%r2) + lhi %r3,FACILITIES_ALS_DWORDS +1: lg %r0,0(%r1) + ng %r0,0(%r2) + clg %r0,0(%r2) jne 2f - la %r1,4(%r1) - la %r2,4(%r2) + la %r1,8(%r1) + la %r2,8(%r2) ahi %r3,-1 jnz 1b j 4f @@ -340,24 +341,10 @@ ENTRY(startup_kdump) 3: .long 0x000a0000,0x8badcccc # List of facilities that are required. If not all facilities are present -# the kernel will crash. Format is number of facility words with bits set, -# followed by the facility words. +# the kernel will crash. + + .quad FACILITIES_ALS -#if defined(CONFIG_MARCH_Z13) - .long 2, 0xc100eff2, 0xf46cc800 -#elif defined(CONFIG_MARCH_ZEC12) - .long 2, 0xc100eff2, 0xf46cc800 -#elif defined(CONFIG_MARCH_Z196) - .long 2, 0xc100eff2, 0xf46c0000 -#elif defined(CONFIG_MARCH_Z10) - .long 2, 0xc100eff2, 0xf0680000 -#elif defined(CONFIG_MARCH_Z9_109) - .long 1, 0xc100efc2 -#elif defined(CONFIG_MARCH_Z990) - .long 1, 0xc0002000 -#elif defined(CONFIG_MARCH_Z900) - .long 1, 0xc0000000 -#endif 4: /* Continue with startup code in head64.S */ jg startup_continue -- GitLab From 185edd4431f0dfd48a465e19ccc3280b08e9fa1a Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 24 Nov 2015 13:11:18 +0100 Subject: [PATCH 1494/2855] s390/facilities: remove unneeded facility bits The facility lists contain a lot of bits which are not necessary to run the kernel. Therefore remove them and keep only those bits which are required for the kernel. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/facilities_src.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/arch/s390/include/asm/facilities_src.h b/arch/s390/include/asm/facilities_src.h index 4555fa69a29e6..493e88b4941c1 100644 --- a/arch/s390/include/asm/facilities_src.h +++ b/arch/s390/include/asm/facilities_src.h @@ -31,33 +31,21 @@ static struct facility_def facility_defs[] = { #endif #ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES 7, /* stfle */ - 16, /* extended translation facility 2 */ 17, /* message security assist */ - 20, /* HFP-multiply-and-add */ 21, /* extended-immediate facility */ - 22, /* extended-translation facility 3 */ - 23, /* HFP-unnormalized-extension */ - 24, /* ETF2-enhancement */ 25, /* store clock fast */ - 30, /* ETF3-enhancement */ #endif #ifdef CONFIG_HAVE_MARCH_Z10_FEATURES - 26, /* parsing enhancement facility */ 27, /* mvcos */ 32, /* compare and swap and store */ 33, /* compare and swap and store 2 */ 34, /* general extension facility */ 35, /* execute extensions */ - 41, /* floating point support enhancement */ - 42, /* DFP facility */ - 44, /* PFPO */ #endif #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES - 37, /* floating point extension */ 45, /* fast-BCR, etc. */ #endif #ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES - 48, /* decimal floating point zoned */ 49, /* misc-instruction-extensions */ 52, /* interlocked facility 2 */ #endif -- GitLab From 6ab6c31a5450b73133e04c3976469d6d72f55df3 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 24 Nov 2015 13:48:27 +0100 Subject: [PATCH 1495/2855] s390/facilities: optimize test_facility() test_facility() can be optimized for bits which must be set anyway, due to the check in head.S. This removes a couple of superfluous runtime checks. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/facility.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/s390/include/asm/facility.h b/arch/s390/include/asm/facility.h index 007163f91856d..09b406db7529a 100644 --- a/arch/s390/include/asm/facility.h +++ b/arch/s390/include/asm/facility.h @@ -34,6 +34,12 @@ static inline int __test_facility(unsigned long nr, void *facilities) */ static inline int test_facility(unsigned long nr) { + unsigned long facilities_als[] = { FACILITIES_ALS }; + + if (__builtin_constant_p(nr) && nr < sizeof(facilities_als) * 8) { + if (__test_facility(nr, &facilities_als)) + return 1; + } return __test_facility(nr, &S390_lowcore.stfle_fac_list); } -- GitLab From f3d05f9de75e233d8f1090af91fc6c23ddc600e8 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 25 Nov 2015 12:54:46 +0100 Subject: [PATCH 1496/2855] s390/facilities: add z13 als bit If configured for z13 assume the kernel makes use of the instructions that are part of the load-and-zero-rightmost-byte facility and load/store-on-condition facility 2. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/facilities_src.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/s390/include/asm/facilities_src.h b/arch/s390/include/asm/facilities_src.h index 493e88b4941c1..4917728e58285 100644 --- a/arch/s390/include/asm/facilities_src.h +++ b/arch/s390/include/asm/facilities_src.h @@ -48,6 +48,9 @@ static struct facility_def facility_defs[] = { #ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES 49, /* misc-instruction-extensions */ 52, /* interlocked facility 2 */ +#endif +#ifdef CONFIG_HAVE_MARCH_Z13_FEATURES + 53, /* load-and-zero-rightmost-byte, etc. */ #endif -1 /* END */ } -- GitLab From a7e137eb94b6abd180050cf0b42e8b3db7efbf5f Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 5 Nov 2015 14:03:27 +0100 Subject: [PATCH 1497/2855] kbuild: add AFLAGS_REMOVE_(basename).o option It is already possible to remove CFLAGS with the CFLAGS_REMOVE option that was introduced with commit 656ee82cc855 ("kbuild: create new CFLAGS_REMOVE_(basename).o option"). However it is not possible to remove AFLAGS for assembler files. So this patch just adds the AFLAGS_REMOVE option which works the same like CFLAGS_REMOVE. Signed-off-by: Heiko Carstens Acked-by: Michal Marek Signed-off-by: Martin Schwidefsky --- scripts/Makefile.lib | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 79e86613712f2..26a48d76eb9d0 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -104,8 +104,9 @@ modname_flags = $(if $(filter 1,$(words $(modname))),\ orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \ $(ccflags-y) $(CFLAGS_$(basetarget).o) _c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) -_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(KBUILD_SUBDIR_ASFLAGS) \ +orig_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(KBUILD_SUBDIR_ASFLAGS) \ $(asflags-y) $(AFLAGS_$(basetarget).o) +_a_flags = $(filter-out $(AFLAGS_REMOVE_$(basetarget).o), $(orig_a_flags)) _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F)) # -- GitLab From 6527f6e0cb6a14c3938140f609d2fde59f4299fc Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 5 Nov 2015 14:03:32 +0100 Subject: [PATCH 1498/2855] s390: compile head.S always with -march=z900 head.S on s390 contains some sanity checks if the kernel will run on a machine or if the machine is too old, e.g. if the kernel contains instructions not available on the machine. If so, it will emit an error message to the console before it stops execution. Therefore head.S contains only instructions which are availanble with the earliest machine generation (z900). In order to make sure we don't accidently add instructions which are not available on z900, always compile with -march=z900. This makes sure compilation will fail if wrong instructions are used. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index dc167a23b9205..e9a328d426105 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -34,8 +34,10 @@ CFLAGS_sysinfo.o += -w # CFLAGS_REMOVE_sclp.o = $(CC_FLAGS_FTRACE) ifneq ($(CC_FLAGS_MARCH),-march=z900) -CFLAGS_REMOVE_sclp.o += $(CC_FLAGS_MARCH) -CFLAGS_sclp.o += -march=z900 +CFLAGS_REMOVE_sclp.o += $(CC_FLAGS_MARCH) +CFLAGS_sclp.o += -march=z900 +AFLAGS_REMOVE_head.o += $(CC_FLAGS_MARCH) +AFLAGS_head.o += -march=z900 endif GCOV_PROFILE_sclp.o := n -- GitLab From f9101e639cf7e707b9a379737ea1b66a16e82097 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Mon, 7 Dec 2015 11:03:30 +0100 Subject: [PATCH 1499/2855] s390/traps: Remove unused variable location is assigned but never used. Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/traps.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 1b18118bbc06b..d69d648759c9f 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -260,11 +260,8 @@ void vector_exception(struct pt_regs *regs) void data_exception(struct pt_regs *regs) { - __u16 __user *location; int signal = 0; - location = get_trap_ip(regs); - save_fpu_regs(); if (current->thread.fpu.fpc & FPC_DXC_MASK) signal = SIGFPE; -- GitLab From 292d8d71576c471e53eb7342ea6130f0241145e8 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Mon, 7 Dec 2015 12:50:03 +0100 Subject: [PATCH 1500/2855] s390/fault: remove unused variable address is assigned but never used. Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- arch/s390/mm/fault.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index ec1a30d0d11ab..1b903f6ad54a3 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -254,7 +254,6 @@ static noinline void do_sigsegv(struct pt_regs *regs, int si_code) static noinline void do_no_context(struct pt_regs *regs) { const struct exception_table_entry *fixup; - unsigned long address; /* Are we prepared to handle this kernel fault? */ fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); @@ -267,7 +266,6 @@ static noinline void do_no_context(struct pt_regs *regs) * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice. */ - address = regs->int_parm_long & __FAIL_ADDR_MASK; if (!user_space_fault(regs)) printk(KERN_ALERT "Unable to handle kernel pointer dereference" " in virtual kernel address space\n"); -- GitLab From 90f405e859840abe1ebf64a836a61e300c11e1c9 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Mon, 7 Dec 2015 12:52:20 +0100 Subject: [PATCH 1501/2855] s390/extmem: remove unused variable findseg_scode is assigned, but never used. Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- arch/s390/mm/extmem.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 18fccc303db7e..a1bf4ad8925de 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c @@ -94,7 +94,7 @@ static DEFINE_MUTEX(dcss_lock); static LIST_HEAD(dcss_list); static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC", "EW/EN-MIXED" }; -static int loadshr_scode, loadnsr_scode, findseg_scode; +static int loadshr_scode, loadnsr_scode; static int segext_scode, purgeseg_scode; static int scode_set; @@ -130,7 +130,6 @@ dcss_set_subcodes(void) loadshr_scode = DCSS_LOADSHRX; loadnsr_scode = DCSS_LOADNSRX; purgeseg_scode = DCSS_PURGESEG; - findseg_scode = DCSS_FINDSEGX; segext_scode = DCSS_SEGEXTX; return 0; } @@ -138,7 +137,6 @@ dcss_set_subcodes(void) loadshr_scode = DCSS_LOADNOLY; loadnsr_scode = DCSS_LOADNSR; purgeseg_scode = DCSS_PURGESEG; - findseg_scode = DCSS_FINDSEG; segext_scode = DCSS_SEGEXT; return 0; } -- GitLab From e527aec434b59745654d3b34a3aa7ce3392a85a5 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Mon, 7 Dec 2015 13:08:48 +0100 Subject: [PATCH 1502/2855] s390/sysinfo: Remove unused variables max_mnest and rc are never used. Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/sysinfo.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c index 99babea026ca0..efacda2fc5683 100644 --- a/arch/s390/kernel/sysinfo.c +++ b/arch/s390/kernel/sysinfo.c @@ -111,8 +111,7 @@ static void stsi_1_1_1(struct seq_file *m, struct sysinfo_1_1_1 *info) static void stsi_15_1_x(struct seq_file *m, struct sysinfo_15_1_x *info) { - static int max_mnest; - int i, rc; + int i; seq_putc(m, '\n'); if (!MACHINE_HAS_TOPOLOGY) -- GitLab From 3dbc78d3a179d99611111d2d86d4283f1f4f82b4 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 8 Dec 2015 14:10:12 +0100 Subject: [PATCH 1503/2855] s390/smp: save timestamp on external calls This is supposed to make debugging easier: if within a dump we can see that an external call or emergency signal IPI is pending but all cpus are idle, we have no idea for how long the interrupt is outstanding. Therefore save a timestamp into the per cpu pcpu array of the target cpu whenever such an IPI is sent. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 9da95d8dfc62c..654c36ec0c603 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -66,6 +66,7 @@ static DEFINE_PER_CPU(struct cpu *, cpu_device); struct pcpu { struct _lowcore *lowcore; /* lowcore page(s) for the cpu */ unsigned long ec_mask; /* bit mask for ec_xxx functions */ + unsigned long ec_clk; /* sigp timestamp for ec_xxx */ signed char state; /* physical cpu state */ signed char polarization; /* physical polarization */ u16 address; /* physical cpu address */ @@ -174,6 +175,7 @@ static void pcpu_ec_call(struct pcpu *pcpu, int ec_bit) if (test_and_set_bit(ec_bit, &pcpu->ec_mask)) return; order = pcpu_running(pcpu) ? SIGP_EXTERNAL_CALL : SIGP_EMERGENCY_SIGNAL; + pcpu->ec_clk = get_tod_clock_fast(); pcpu_sigp_retry(pcpu, order, 0); } -- GitLab From d7ae65aec0dac187d29a2963ac46574aad840a20 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 15 Dec 2015 09:26:30 +0100 Subject: [PATCH 1504/2855] s390/setup: cleanup machine flags Over time some machine flags got unused (e.g. MACHINE_FLAG_MVPG) or are available on all 64bit systems (MACHINE_FLAG_CSP, MACHINE_FLAG_IEEE) - let's remove them. Reorder the other ones to match the order of the MACHINE_HAS_* macros and renumber all bits to avoid holes. Also fix the comment about where the flags are detected. Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/setup.h | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 23537661da0ed..69837225119e6 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h @@ -12,27 +12,24 @@ #define PARMAREA 0x10400 /* - * Machine features detected in head.S + * Machine features detected in early.c */ #define MACHINE_FLAG_VM _BITUL(0) -#define MACHINE_FLAG_IEEE _BITUL(1) -#define MACHINE_FLAG_CSP _BITUL(2) -#define MACHINE_FLAG_MVPG _BITUL(3) -#define MACHINE_FLAG_DIAG44 _BITUL(4) +#define MACHINE_FLAG_KVM _BITUL(1) +#define MACHINE_FLAG_LPAR _BITUL(2) +#define MACHINE_FLAG_DIAG9C _BITUL(3) +#define MACHINE_FLAG_ESOP _BITUL(4) #define MACHINE_FLAG_IDTE _BITUL(5) -#define MACHINE_FLAG_DIAG9C _BITUL(6) -#define MACHINE_FLAG_KVM _BITUL(8) -#define MACHINE_FLAG_ESOP _BITUL(9) -#define MACHINE_FLAG_EDAT1 _BITUL(10) -#define MACHINE_FLAG_EDAT2 _BITUL(11) -#define MACHINE_FLAG_LPAR _BITUL(12) -#define MACHINE_FLAG_LPP _BITUL(13) -#define MACHINE_FLAG_TOPOLOGY _BITUL(14) -#define MACHINE_FLAG_TE _BITUL(15) -#define MACHINE_FLAG_TLB_LC _BITUL(17) -#define MACHINE_FLAG_VX _BITUL(18) -#define MACHINE_FLAG_CAD _BITUL(19) +#define MACHINE_FLAG_DIAG44 _BITUL(6) +#define MACHINE_FLAG_EDAT1 _BITUL(7) +#define MACHINE_FLAG_EDAT2 _BITUL(8) +#define MACHINE_FLAG_LPP _BITUL(9) +#define MACHINE_FLAG_TOPOLOGY _BITUL(10) +#define MACHINE_FLAG_TE _BITUL(11) +#define MACHINE_FLAG_TLB_LC _BITUL(12) +#define MACHINE_FLAG_VX _BITUL(13) +#define MACHINE_FLAG_CAD _BITUL(14) #define LPP_MAGIC _BITUL(31) #define LPP_PFAULT_PID_MASK _AC(0xffffffff, UL) -- GitLab From 62e65da994768e0d599d78dd2cebef5716ffb0ae Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Fri, 18 Dec 2015 12:58:47 +0100 Subject: [PATCH 1505/2855] s390/cio: Remove unused inline assemblies There is no longer a need to maintain two versions of the same inline assembly - one with exception handling, and one without - so get rid of the duplicates and adjust names accordingly. This applies to stsch_err and msch_err which are now renamed to stsch and msch respectively, while the original msch function is removed. Signed-off-by: Peter Oberparleiter Acked-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/chsc_sch.c | 2 +- drivers/s390/cio/cio.c | 24 ++++++++++++------------ drivers/s390/cio/css.c | 2 +- drivers/s390/cio/device_fsm.c | 2 +- drivers/s390/cio/ioasm.h | 17 +---------------- 5 files changed, 16 insertions(+), 31 deletions(-) diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 378c57178bb8d..b6f12c2bb114a 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c @@ -133,7 +133,7 @@ static int chsc_subchannel_prepare(struct subchannel *sch) * since we don't have a way to clear the subchannel and * cannot disable it with a request running. */ - cc = stsch_err(sch->schid, &schib); + cc = stsch(sch->schid, &schib); if (!cc && scsw_stctl(&schib.scsw)) return -EAGAIN; return 0; diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 2d18205526b66..5f5c24030405c 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -345,18 +345,18 @@ int cio_commit_config(struct subchannel *sch) struct schib schib; struct irb irb; - if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib)) + if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib)) return -ENODEV; for (retry = 0; retry < 5; retry++) { /* copy desired changes to local schib */ cio_apply_config(sch, &schib); - ccode = msch_err(sch->schid, &schib); + ccode = msch(sch->schid, &schib); if (ccode < 0) /* -EIO if msch gets a program check. */ return ccode; switch (ccode) { case 0: /* successful */ - if (stsch_err(sch->schid, &schib) || + if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib)) return -ENODEV; if (cio_check_config(sch, &schib)) { @@ -391,7 +391,7 @@ int cio_update_schib(struct subchannel *sch) { struct schib schib; - if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib)) + if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib)) return -ENODEV; memcpy(&sch->schib, &schib, sizeof(schib)); @@ -500,7 +500,7 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid) * If stsch gets an exception, it means the current subchannel set * is not valid. */ - ccode = stsch_err(schid, &sch->schib); + ccode = stsch(schid, &sch->schib); if (ccode) { err = (ccode == 3) ? -ENXIO : ccode; goto out; @@ -616,7 +616,7 @@ static int cio_test_for_console(struct subchannel_id schid, void *data) { struct schib schib; - if (stsch_err(schid, &schib) != 0) + if (stsch(schid, &schib) != 0) return -ENXIO; if ((schib.pmcw.st == SUBCHANNEL_TYPE_IO) && schib.pmcw.dnv && (schib.pmcw.dev == console_devno)) { @@ -635,7 +635,7 @@ static int cio_get_console_sch_no(void) if (console_irq != -1) { /* VM provided us with the irq number of the console. */ schid.sch_no = console_irq; - if (stsch_err(schid, &schib) != 0 || + if (stsch(schid, &schib) != 0 || (schib.pmcw.st != SUBCHANNEL_TYPE_IO) || !schib.pmcw.dnv) return -1; console_devno = schib.pmcw.dev; @@ -705,10 +705,10 @@ __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib) cc = 0; for (retry=0;retry<3;retry++) { schib->pmcw.ena = 0; - cc = msch_err(schid, schib); + cc = msch(schid, schib); if (cc) return (cc==3?-ENODEV:-EBUSY); - if (stsch_err(schid, schib) || !css_sch_is_valid(schib)) + if (stsch(schid, schib) || !css_sch_is_valid(schib)) return -ENODEV; if (!schib->pmcw.ena) return 0; @@ -755,7 +755,7 @@ static int stsch_reset(struct subchannel_id schid, struct schib *addr) pgm_check_occured = 0; s390_base_pgm_handler_fn = cio_reset_pgm_check_handler; - rc = stsch_err(schid, addr); + rc = stsch(schid, addr); s390_base_pgm_handler_fn = NULL; /* The program check handler could have changed pgm_check_occured. */ @@ -792,7 +792,7 @@ static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data) /* No default clear strategy */ break; } - stsch_err(schid, &schib); + stsch(schid, &schib); __disable_subchannel_easy(schid, &schib); } out: @@ -940,7 +940,7 @@ int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo) if (__chsc_enable_facility(&sda_area, CHSC_SDA_OC_MSS)) return -ENODEV; } - if (stsch_err(schid, &schib)) + if (stsch(schid, &schib)) return -ENODEV; if (schib.pmcw.st != SUBCHANNEL_TYPE_IO) return -ENODEV; diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 489e703dc82d8..3d2b20ee613f8 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -390,7 +390,7 @@ static int css_evaluate_new_subchannel(struct subchannel_id schid, int slow) /* Will be done on the slow path. */ return -EAGAIN; } - if (stsch_err(schid, &schib)) { + if (stsch(schid, &schib)) { /* Subchannel is not provided. */ return -ENXIO; } diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 92e03b42e661f..8327d47e08b6a 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c @@ -44,7 +44,7 @@ static void ccw_timeout_log(struct ccw_device *cdev) sch = to_subchannel(cdev->dev.parent); private = to_io_private(sch); orb = &private->orb; - cc = stsch_err(sch->schid, &schib); + cc = stsch(sch->schid, &schib); printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, " "device information:\n", get_tod_clock()); diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h index 4d80fc67a06b1..be6e2f5e11f75 100644 --- a/drivers/s390/cio/ioasm.h +++ b/drivers/s390/cio/ioasm.h @@ -25,7 +25,7 @@ struct tpi_info { * Some S390 specific IO instructions as inline */ -static inline int stsch_err(struct subchannel_id schid, struct schib *addr) +static inline int stsch(struct subchannel_id schid, struct schib *addr) { register struct subchannel_id reg1 asm ("1") = schid; int ccode = -EIO; @@ -43,21 +43,6 @@ static inline int stsch_err(struct subchannel_id schid, struct schib *addr) } static inline int msch(struct subchannel_id schid, struct schib *addr) -{ - register struct subchannel_id reg1 asm ("1") = schid; - int ccode; - - asm volatile( - " msch 0(%2)\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (reg1), "a" (addr), "m" (*addr) - : "cc"); - return ccode; -} - -static inline int msch_err(struct subchannel_id schid, struct schib *addr) { register struct subchannel_id reg1 asm ("1") = schid; int ccode = -EIO; -- GitLab From ac357c4105ef6b2d44227aa349850a3c1a2994a5 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Fri, 18 Dec 2015 12:59:28 +0100 Subject: [PATCH 1506/2855] s390/cio: Fix incorrect xsch opcode specification The numeric representation of the xsch instruction was incorrectly specified, resulting in reserved fields of the instruction opcode potentially being set to a non-zero value. While this doesn't currently cause any problem, a future architecture might make use of these fields so that the current specification could result in an exception or unwanted side-effects. Fix this by using the xsch instruction code for which support in binutils was added in 2003. Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/io_sch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h index b108f4a5c7dd3..789ce783d3e1b 100644 --- a/drivers/s390/cio/io_sch.h +++ b/drivers/s390/cio/io_sch.h @@ -205,7 +205,7 @@ static inline int xsch(struct subchannel_id schid) int ccode; asm volatile( - " .insn rre,0xb2760000,%1,0\n" + " xsch\n" " ipm %0\n" " srl %0,28" : "=d" (ccode) -- GitLab From 2ab59de7c5ce7c5ed6db07278554901d43fe80a0 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Fri, 18 Dec 2015 12:59:32 +0100 Subject: [PATCH 1507/2855] s390/cio: Consolidate inline assemblies and related data definitions Replace the current semi-arbitrary distribution of inline assemblies: - Inline assemblies used by CIO go into ioasm.h - Data definitions used by inline assemblies go into cio.h Beyond cleaning up the current structure this is also required for use of tracepoints in inline assemblies introduced by a follow-on patch. Signed-off-by: Peter Oberparleiter Acked-by: Sebastian Ott Acked-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/crw.h | 14 ------- drivers/s390/cio/cio.h | 12 ++++++ drivers/s390/cio/crw.c | 1 + drivers/s390/cio/io_sch.h | 45 ---------------------- drivers/s390/cio/ioasm.h | 75 +++++++++++++++++++++++++++++-------- 5 files changed, 73 insertions(+), 74 deletions(-) diff --git a/arch/s390/include/asm/crw.h b/arch/s390/include/asm/crw.h index 7c31d3e25cd13..bcb9cd2a730aa 100644 --- a/arch/s390/include/asm/crw.h +++ b/arch/s390/include/asm/crw.h @@ -52,18 +52,4 @@ void crw_wait_for_channel_report(void); #define CRW_ERC_PERRI 0x07 /* perm. error, facility init */ #define CRW_ERC_PMOD 0x08 /* installed parameters modified */ -static inline int stcrw(struct crw *pcrw) -{ - int ccode; - - asm volatile( - " stcrw 0(%2)\n" - " ipm %0\n" - " srl %0,28\n" - : "=d" (ccode), "=m" (*pcrw) - : "a" (pcrw) - : "cc" ); - return ccode; -} - #endif /* _ASM_S390_CRW_H */ diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index a01376ae17493..93de0b46b4899 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -45,6 +45,18 @@ struct pmcw { /* ... in an operand exception. */ } __attribute__ ((packed)); +/* I/O-Interruption Code as stored by TEST PENDING INTERRUPTION (TPI). */ +struct tpi_info { + struct subchannel_id schid; + u32 intparm; + u32 adapter_IO:1; + u32 :1; + u32 isc:3; + u32 :27; + u32 type:3; + u32 :12; +} __packed __aligned(4); + /* Target SCHIB configuration. */ struct schib_config { u64 mba; diff --git a/drivers/s390/cio/crw.c b/drivers/s390/cio/crw.c index 0f8a25f98b106..3d3cd402b3768 100644 --- a/drivers/s390/cio/crw.c +++ b/drivers/s390/cio/crw.c @@ -14,6 +14,7 @@ #include #include #include +#include "ioasm.h" static DEFINE_MUTEX(crw_handler_mutex); static crw_handler_t crw_handlers[NR_RSCS]; diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h index 789ce783d3e1b..8975060af96cb 100644 --- a/drivers/s390/cio/io_sch.h +++ b/drivers/s390/cio/io_sch.h @@ -169,49 +169,4 @@ struct ccw_device_private { enum interruption_class int_class; }; -static inline int rsch(struct subchannel_id schid) -{ - register struct subchannel_id reg1 asm("1") = schid; - int ccode; - - asm volatile( - " rsch\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (reg1) - : "cc", "memory"); - return ccode; -} - -static inline int hsch(struct subchannel_id schid) -{ - register struct subchannel_id reg1 asm("1") = schid; - int ccode; - - asm volatile( - " hsch\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (reg1) - : "cc"); - return ccode; -} - -static inline int xsch(struct subchannel_id schid) -{ - register struct subchannel_id reg1 asm("1") = schid; - int ccode; - - asm volatile( - " xsch\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (reg1) - : "cc"); - return ccode; -} - #endif diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h index be6e2f5e11f75..dce25500812aa 100644 --- a/drivers/s390/cio/ioasm.h +++ b/drivers/s390/cio/ioasm.h @@ -3,24 +3,10 @@ #include #include +#include #include "orb.h" #include "cio.h" -/* - * TPI info structure - */ -struct tpi_info { - struct subchannel_id schid; - __u32 intparm; /* interruption parameter */ - __u32 adapter_IO : 1; - __u32 reserved2 : 1; - __u32 isc : 3; - __u32 reserved3 : 12; - __u32 int_type : 3; - __u32 reserved4 : 12; -} __attribute__ ((packed)); - - /* * Some S390 specific IO instructions as inline */ @@ -149,4 +135,63 @@ static inline int rchp(struct chp_id chpid) return ccode; } +static inline int rsch(struct subchannel_id schid) +{ + register struct subchannel_id reg1 asm("1") = schid; + int ccode; + + asm volatile( + " rsch\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) + : "d" (reg1) + : "cc", "memory"); + return ccode; +} + +static inline int hsch(struct subchannel_id schid) +{ + register struct subchannel_id reg1 asm("1") = schid; + int ccode; + + asm volatile( + " hsch\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) + : "d" (reg1) + : "cc"); + return ccode; +} + +static inline int xsch(struct subchannel_id schid) +{ + register struct subchannel_id reg1 asm("1") = schid; + int ccode; + + asm volatile( + " xsch\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) + : "d" (reg1) + : "cc"); + return ccode; +} + +static inline int stcrw(struct crw *crw) +{ + int ccode; + + asm volatile( + " stcrw 0(%2)\n" + " ipm %0\n" + " srl %0,28\n" + : "=d" (ccode), "=m" (*crw) + : "a" (crw) + : "cc"); + return ccode; +} + #endif -- GitLab From 42248979d5705e056b509cdcfb548e40f708cba8 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Fri, 18 Dec 2015 12:59:36 +0100 Subject: [PATCH 1508/2855] s390/cio: Introduce common I/O layer tracepoints Add tracepoints to interrupt handler and core inline assemblies used by the s390 common I/O layer. These tracepoints can be used to monitor and validate hardware and hypervisor requests and responses. Signed-off-by: Peter Oberparleiter Reviewed-by: Sebastian Ott Reviewed-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/Makefile | 5 +- drivers/s390/cio/airq.c | 1 + drivers/s390/cio/cio.c | 2 + drivers/s390/cio/ioasm.h | 25 +++ drivers/s390/cio/trace.c | 24 +++ drivers/s390/cio/trace.h | 363 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 419 insertions(+), 1 deletion(-) create mode 100644 drivers/s390/cio/trace.c create mode 100644 drivers/s390/cio/trace.h diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile index 8c4a386e97f6e..2c7cf0b3c5a0d 100644 --- a/drivers/s390/cio/Makefile +++ b/drivers/s390/cio/Makefile @@ -2,8 +2,11 @@ # Makefile for the S/390 common i/o drivers # +# The following is required for define_trace.h to find ./trace.h +CFLAGS_trace.o := -I$(src) + obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o \ - fcx.o itcw.o crw.o ccwreq.o + fcx.o itcw.o crw.o ccwreq.o trace.o ccw_device-objs += device.o device_fsm.o device_ops.o ccw_device-objs += device_id.o device_pgid.o device_status.o obj-y += ccw_device.o cmf.o diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c index 56eb4ee4deba0..99b5db4690978 100644 --- a/drivers/s390/cio/airq.c +++ b/drivers/s390/cio/airq.c @@ -89,6 +89,7 @@ static irqreturn_t do_airq_interrupt(int irq, void *dummy) set_cpu_flag(CIF_NOHZ_DELAY); tpi_info = (struct tpi_info *) &get_irq_regs()->int_code; + trace_s390_cio_adapter_int(tpi_info); head = &airq_lists[tpi_info->isc]; rcu_read_lock(); hlist_for_each_entry_rcu(airq, head, list) diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 5f5c24030405c..39a8ae54e9c1d 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -41,6 +41,7 @@ #include "blacklist.h" #include "cio_debug.h" #include "chp.h" +#include "trace.h" debug_info_t *cio_debug_msg_id; debug_info_t *cio_debug_trace_id; @@ -539,6 +540,7 @@ static irqreturn_t do_cio_interrupt(int irq, void *dummy) set_cpu_flag(CIF_NOHZ_DELAY); tpi_info = (struct tpi_info *) &get_irq_regs()->int_code; + trace_s390_cio_interrupt(tpi_info); irb = this_cpu_ptr(&cio_irb); sch = (struct subchannel *)(unsigned long) tpi_info->intparm; if (!sch) { diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h index dce25500812aa..11e255a4fbadb 100644 --- a/drivers/s390/cio/ioasm.h +++ b/drivers/s390/cio/ioasm.h @@ -6,6 +6,7 @@ #include #include "orb.h" #include "cio.h" +#include "trace.h" /* * Some S390 specific IO instructions as inline @@ -25,6 +26,8 @@ static inline int stsch(struct subchannel_id schid, struct schib *addr) : "+d" (ccode), "=m" (*addr) : "d" (reg1), "a" (addr) : "cc"); + trace_s390_cio_stsch(schid, addr, ccode); + return ccode; } @@ -42,6 +45,8 @@ static inline int msch(struct subchannel_id schid, struct schib *addr) : "+d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); + trace_s390_cio_msch(schid, addr, ccode); + return ccode; } @@ -57,6 +62,8 @@ static inline int tsch(struct subchannel_id schid, struct irb *addr) : "=d" (ccode), "=m" (*addr) : "d" (reg1), "a" (addr) : "cc"); + trace_s390_cio_tsch(schid, addr, ccode); + return ccode; } @@ -74,6 +81,8 @@ static inline int ssch(struct subchannel_id schid, union orb *addr) : "+d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc", "memory"); + trace_s390_cio_ssch(schid, addr, ccode); + return ccode; } @@ -89,6 +98,8 @@ static inline int csch(struct subchannel_id schid) : "=d" (ccode) : "d" (reg1) : "cc"); + trace_s390_cio_csch(schid, ccode); + return ccode; } @@ -103,6 +114,8 @@ static inline int tpi(struct tpi_info *addr) : "=d" (ccode), "=m" (*addr) : "a" (addr) : "cc"); + trace_s390_cio_tpi(addr, ccode); + return ccode; } @@ -118,6 +131,8 @@ static inline int chsc(void *chsc_area) : "=d" (cc), "=m" (*(addr_type *) chsc_area) : "d" (chsc_area), "m" (*(addr_type *) chsc_area) : "cc"); + trace_s390_cio_chsc(chsc_area, cc); + return cc; } @@ -132,6 +147,8 @@ static inline int rchp(struct chp_id chpid) " ipm %0\n" " srl %0,28" : "=d" (ccode) : "d" (reg1) : "cc"); + trace_s390_cio_rchp(chpid, ccode); + return ccode; } @@ -147,6 +164,8 @@ static inline int rsch(struct subchannel_id schid) : "=d" (ccode) : "d" (reg1) : "cc", "memory"); + trace_s390_cio_rsch(schid, ccode); + return ccode; } @@ -162,6 +181,8 @@ static inline int hsch(struct subchannel_id schid) : "=d" (ccode) : "d" (reg1) : "cc"); + trace_s390_cio_hsch(schid, ccode); + return ccode; } @@ -177,6 +198,8 @@ static inline int xsch(struct subchannel_id schid) : "=d" (ccode) : "d" (reg1) : "cc"); + trace_s390_cio_xsch(schid, ccode); + return ccode; } @@ -191,6 +214,8 @@ static inline int stcrw(struct crw *crw) : "=d" (ccode), "=m" (*crw) : "a" (crw) : "cc"); + trace_s390_cio_stcrw(crw, ccode); + return ccode; } diff --git a/drivers/s390/cio/trace.c b/drivers/s390/cio/trace.c new file mode 100644 index 0000000000000..8e706669ac8b2 --- /dev/null +++ b/drivers/s390/cio/trace.c @@ -0,0 +1,24 @@ +/* + * Tracepoint definitions for s390_cio + * + * Copyright IBM Corp. 2015 + * Author(s): Peter Oberparleiter + */ + +#include +#include "cio.h" + +#define CREATE_TRACE_POINTS +#include "trace.h" + +EXPORT_TRACEPOINT_SYMBOL(s390_cio_stsch); +EXPORT_TRACEPOINT_SYMBOL(s390_cio_msch); +EXPORT_TRACEPOINT_SYMBOL(s390_cio_tsch); +EXPORT_TRACEPOINT_SYMBOL(s390_cio_tpi); +EXPORT_TRACEPOINT_SYMBOL(s390_cio_ssch); +EXPORT_TRACEPOINT_SYMBOL(s390_cio_csch); +EXPORT_TRACEPOINT_SYMBOL(s390_cio_hsch); +EXPORT_TRACEPOINT_SYMBOL(s390_cio_xsch); +EXPORT_TRACEPOINT_SYMBOL(s390_cio_rsch); +EXPORT_TRACEPOINT_SYMBOL(s390_cio_rchp); +EXPORT_TRACEPOINT_SYMBOL(s390_cio_chsc); diff --git a/drivers/s390/cio/trace.h b/drivers/s390/cio/trace.h new file mode 100644 index 0000000000000..5b807a09f21b2 --- /dev/null +++ b/drivers/s390/cio/trace.h @@ -0,0 +1,363 @@ +/* + * Tracepoint header for the s390 Common I/O layer (CIO) + * + * Copyright IBM Corp. 2015 + * Author(s): Peter Oberparleiter + */ + +#include +#include +#include +#include +#include "cio.h" +#include "orb.h" + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM s390 + +#if !defined(_TRACE_S390_CIO_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_S390_CIO_H + +#include + +DECLARE_EVENT_CLASS(s390_class_schib, + TP_PROTO(struct subchannel_id schid, struct schib *schib, int cc), + TP_ARGS(schid, schib, cc), + TP_STRUCT__entry( + __field(u8, cssid) + __field(u8, ssid) + __field(u16, schno) + __field(u16, devno) + __field_struct(struct schib, schib) + __field(int, cc) + ), + TP_fast_assign( + __entry->cssid = schid.cssid; + __entry->ssid = schid.ssid; + __entry->schno = schid.sch_no; + __entry->devno = schib->pmcw.dev; + __entry->schib = *schib; + __entry->cc = cc; + ), + TP_printk("schid=%x.%x.%04x cc=%d ena=%d st=%d dnv=%d dev=%04x " + "lpm=0x%02x pnom=0x%02x lpum=0x%02x pim=0x%02x pam=0x%02x " + "pom=0x%02x chpids=%016llx", + __entry->cssid, __entry->ssid, __entry->schno, __entry->cc, + __entry->schib.pmcw.ena, __entry->schib.pmcw.st, + __entry->schib.pmcw.dnv, __entry->schib.pmcw.dev, + __entry->schib.pmcw.lpm, __entry->schib.pmcw.pnom, + __entry->schib.pmcw.lpum, __entry->schib.pmcw.pim, + __entry->schib.pmcw.pam, __entry->schib.pmcw.pom, + *((u64 *) __entry->schib.pmcw.chpid) + ) +); + +/** + * s390_cio_stsch - Store Subchannel instruction (STSCH) was performed + * @schid: Subchannel ID + * @schib: Subchannel-Information block + * @cc: Condition code + */ +DEFINE_EVENT(s390_class_schib, s390_cio_stsch, + TP_PROTO(struct subchannel_id schid, struct schib *schib, int cc), + TP_ARGS(schid, schib, cc) +); + +/** + * s390_cio_msch - Modify Subchannel instruction (MSCH) was performed + * @schid: Subchannel ID + * @schib: Subchannel-Information block + * @cc: Condition code + */ +DEFINE_EVENT(s390_class_schib, s390_cio_msch, + TP_PROTO(struct subchannel_id schid, struct schib *schib, int cc), + TP_ARGS(schid, schib, cc) +); + +/** + * s390_cio_tsch - Test Subchannel instruction (TSCH) was performed + * @schid: Subchannel ID + * @irb: Interruption-Response Block + * @cc: Condition code + */ +TRACE_EVENT(s390_cio_tsch, + TP_PROTO(struct subchannel_id schid, struct irb *irb, int cc), + TP_ARGS(schid, irb, cc), + TP_STRUCT__entry( + __field(u8, cssid) + __field(u8, ssid) + __field(u16, schno) + __field_struct(struct irb, irb) + __field(int, cc) + ), + TP_fast_assign( + __entry->cssid = schid.cssid; + __entry->ssid = schid.ssid; + __entry->schno = schid.sch_no; + __entry->irb = *irb; + __entry->cc = cc; + ), + TP_printk("schid=%x.%x.%04x cc=%d dcc=%d pno=%d fctl=0x%x actl=0x%x " + "stctl=0x%x dstat=0x%x cstat=0x%x", + __entry->cssid, __entry->ssid, __entry->schno, __entry->cc, + scsw_cc(&__entry->irb.scsw), scsw_pno(&__entry->irb.scsw), + scsw_fctl(&__entry->irb.scsw), scsw_actl(&__entry->irb.scsw), + scsw_stctl(&__entry->irb.scsw), + scsw_dstat(&__entry->irb.scsw), scsw_cstat(&__entry->irb.scsw) + ) +); + +/** + * s390_cio_tpi - Test Pending Interruption instruction (TPI) was performed + * @addr: Address of the I/O interruption code or %NULL + * @cc: Condition code + */ +TRACE_EVENT(s390_cio_tpi, + TP_PROTO(struct tpi_info *addr, int cc), + TP_ARGS(addr, cc), + TP_STRUCT__entry( + __field(int, cc) + __field_struct(struct tpi_info, tpi_info) + __field(u8, cssid) + __field(u8, ssid) + __field(u16, schno) + ), + TP_fast_assign( + __entry->cc = cc; + if (cc != 0) + memset(&__entry->tpi_info, 0, sizeof(struct tpi_info)); + else if (addr) + __entry->tpi_info = *addr; + else { + memcpy(&__entry->tpi_info, &S390_lowcore.subchannel_id, + sizeof(struct tpi_info)); + } + __entry->cssid = __entry->tpi_info.schid.cssid; + __entry->ssid = __entry->tpi_info.schid.ssid; + __entry->schno = __entry->tpi_info.schid.sch_no; + ), + TP_printk("schid=%x.%x.%04x cc=%d a=%d isc=%d type=%d", + __entry->cssid, __entry->ssid, __entry->schno, __entry->cc, + __entry->tpi_info.adapter_IO, __entry->tpi_info.isc, + __entry->tpi_info.type + ) +); + +/** + * s390_cio_ssch - Start Subchannel instruction (SSCH) was performed + * @schid: Subchannel ID + * @orb: Operation-Request Block + * @cc: Condition code + */ +TRACE_EVENT(s390_cio_ssch, + TP_PROTO(struct subchannel_id schid, union orb *orb, int cc), + TP_ARGS(schid, orb, cc), + TP_STRUCT__entry( + __field(u8, cssid) + __field(u8, ssid) + __field(u16, schno) + __field_struct(union orb, orb) + __field(int, cc) + ), + TP_fast_assign( + __entry->cssid = schid.cssid; + __entry->ssid = schid.ssid; + __entry->schno = schid.sch_no; + __entry->orb = *orb; + __entry->cc = cc; + ), + TP_printk("schid=%x.%x.%04x cc=%d", __entry->cssid, __entry->ssid, + __entry->schno, __entry->cc + ) +); + +DECLARE_EVENT_CLASS(s390_class_schid, + TP_PROTO(struct subchannel_id schid, int cc), + TP_ARGS(schid, cc), + TP_STRUCT__entry( + __field(u8, cssid) + __field(u8, ssid) + __field(u16, schno) + __field(int, cc) + ), + TP_fast_assign( + __entry->cssid = schid.cssid; + __entry->ssid = schid.ssid; + __entry->schno = schid.sch_no; + __entry->cc = cc; + ), + TP_printk("schid=%x.%x.%04x cc=%d", __entry->cssid, __entry->ssid, + __entry->schno, __entry->cc + ) +); + +/** + * s390_cio_csch - Clear Subchannel instruction (CSCH) was performed + * @schid: Subchannel ID + * @cc: Condition code + */ +DEFINE_EVENT(s390_class_schid, s390_cio_csch, + TP_PROTO(struct subchannel_id schid, int cc), + TP_ARGS(schid, cc) +); + +/** + * s390_cio_hsch - Halt Subchannel instruction (HSCH) was performed + * @schid: Subchannel ID + * @cc: Condition code + */ +DEFINE_EVENT(s390_class_schid, s390_cio_hsch, + TP_PROTO(struct subchannel_id schid, int cc), + TP_ARGS(schid, cc) +); + +/** + * s390_cio_xsch - Cancel Subchannel instruction (XSCH) was performed + * @schid: Subchannel ID + * @cc: Condition code + */ +DEFINE_EVENT(s390_class_schid, s390_cio_xsch, + TP_PROTO(struct subchannel_id schid, int cc), + TP_ARGS(schid, cc) +); + +/** + * s390_cio_rsch - Resume Subchannel instruction (RSCH) was performed + * @schid: Subchannel ID + * @cc: Condition code + */ +DEFINE_EVENT(s390_class_schid, s390_cio_rsch, + TP_PROTO(struct subchannel_id schid, int cc), + TP_ARGS(schid, cc) +); + +/** + * s390_cio_rchp - Reset Channel Path (RCHP) instruction was performed + * @chpid: Channel-Path Identifier + * @cc: Condition code + */ +TRACE_EVENT(s390_cio_rchp, + TP_PROTO(struct chp_id chpid, int cc), + TP_ARGS(chpid, cc), + TP_STRUCT__entry( + __field(u8, cssid) + __field(u8, id) + __field(int, cc) + ), + TP_fast_assign( + __entry->cssid = chpid.cssid; + __entry->id = chpid.id; + __entry->cc = cc; + ), + TP_printk("chpid=%x.%02x cc=%d", __entry->cssid, __entry->id, + __entry->cc + ) +); + +#define CHSC_MAX_REQUEST_LEN 64 +#define CHSC_MAX_RESPONSE_LEN 64 + +/** + * s390_cio_chsc - Channel Subsystem Call (CHSC) instruction was performed + * @chsc: CHSC block + * @cc: Condition code + */ +TRACE_EVENT(s390_cio_chsc, + TP_PROTO(struct chsc_header *chsc, int cc), + TP_ARGS(chsc, cc), + TP_STRUCT__entry( + __field(int, cc) + __field(u16, code) + __field(u16, rcode) + __array(u8, request, CHSC_MAX_REQUEST_LEN) + __array(u8, response, CHSC_MAX_RESPONSE_LEN) + ), + TP_fast_assign( + __entry->cc = cc; + __entry->code = chsc->code; + memcpy(&entry->request, chsc, + min_t(u16, chsc->length, CHSC_MAX_REQUEST_LEN)); + chsc = (struct chsc_header *) ((char *) chsc + chsc->length); + __entry->rcode = chsc->code; + memcpy(&entry->response, chsc, + min_t(u16, chsc->length, CHSC_MAX_RESPONSE_LEN)); + ), + TP_printk("code=0x%04x cc=%d rcode=0x%04x", __entry->code, + __entry->cc, __entry->rcode) +); + +/** + * s390_cio_interrupt - An I/O interrupt occurred + * @tpi_info: Address of the I/O interruption code + */ +TRACE_EVENT(s390_cio_interrupt, + TP_PROTO(struct tpi_info *tpi_info), + TP_ARGS(tpi_info), + TP_STRUCT__entry( + __field_struct(struct tpi_info, tpi_info) + __field(u8, cssid) + __field(u8, ssid) + __field(u16, schno) + ), + TP_fast_assign( + __entry->tpi_info = *tpi_info; + __entry->cssid = __entry->tpi_info.schid.cssid; + __entry->ssid = __entry->tpi_info.schid.ssid; + __entry->schno = __entry->tpi_info.schid.sch_no; + ), + TP_printk("schid=%x.%x.%04x isc=%d type=%d", + __entry->cssid, __entry->ssid, __entry->schno, + __entry->tpi_info.isc, __entry->tpi_info.type + ) +); + +/** + * s390_cio_adapter_int - An adapter interrupt occurred + * @tpi_info: Address of the I/O interruption code + */ +TRACE_EVENT(s390_cio_adapter_int, + TP_PROTO(struct tpi_info *tpi_info), + TP_ARGS(tpi_info), + TP_STRUCT__entry( + __field_struct(struct tpi_info, tpi_info) + ), + TP_fast_assign( + __entry->tpi_info = *tpi_info; + ), + TP_printk("isc=%d", __entry->tpi_info.isc) +); + +/** + * s390_cio_stcrw - Store Channel Report Word (STCRW) was performed + * @crw: Channel Report Word + * @cc: Condition code + */ +TRACE_EVENT(s390_cio_stcrw, + TP_PROTO(struct crw *crw, int cc), + TP_ARGS(crw, cc), + TP_STRUCT__entry( + __field_struct(struct crw, crw) + __field(int, cc) + ), + TP_fast_assign( + __entry->crw = *crw; + __entry->cc = cc; + ), + TP_printk("cc=%d slct=%d oflw=%d chn=%d rsc=%d anc=%d erc=0x%x " + "rsid=0x%x", + __entry->cc, __entry->crw.slct, __entry->crw.oflw, + __entry->crw.chn, __entry->crw.rsc, __entry->crw.anc, + __entry->crw.erc, __entry->crw.rsid + ) +); + +#endif /* _TRACE_S390_CIO_H */ + +/* This part must be outside protection */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . + +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE trace + +#include -- GitLab From 11b64c8acca05d7e50a873e0e8758b75d6d6650f Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Fri, 18 Dec 2015 12:59:40 +0100 Subject: [PATCH 1509/2855] s390/cio: Change I/O instructions from inline to normal functions Adding tracepoints to inline functions adds tracepoint invocation code for each instance where the function is inlined. The resulting increase in kernel code size can have negative impact: - More cache misses in instruction cache - Reduced amount of DMA-capable memory Therefore change all functions implementing I/O instructions from inline to normal functions. Bloat-o-meter summary after change (using performance_defconfig): add/remove: 24/2 grow/shrink: 4/39 up/down: 2205/-4858 (-2653) Signed-off-by: Peter Oberparleiter Acked-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/Makefile | 2 +- drivers/s390/cio/ioasm.c | 224 ++++++++++++++++++++++++++++++++++++++ drivers/s390/cio/ioasm.h | 220 +++---------------------------------- 3 files changed, 238 insertions(+), 208 deletions(-) create mode 100644 drivers/s390/cio/ioasm.c diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile index 2c7cf0b3c5a0d..3ab9aedeb84a2 100644 --- a/drivers/s390/cio/Makefile +++ b/drivers/s390/cio/Makefile @@ -6,7 +6,7 @@ CFLAGS_trace.o := -I$(src) obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o \ - fcx.o itcw.o crw.o ccwreq.o trace.o + fcx.o itcw.o crw.o ccwreq.o trace.o ioasm.o ccw_device-objs += device.o device_fsm.o device_ops.o ccw_device-objs += device_id.o device_pgid.o device_status.o obj-y += ccw_device.o cmf.o diff --git a/drivers/s390/cio/ioasm.c b/drivers/s390/cio/ioasm.c new file mode 100644 index 0000000000000..98984818618f2 --- /dev/null +++ b/drivers/s390/cio/ioasm.c @@ -0,0 +1,224 @@ +/* + * Channel subsystem I/O instructions. + */ + +#include + +#include +#include +#include + +#include "ioasm.h" +#include "orb.h" +#include "cio.h" + +int stsch(struct subchannel_id schid, struct schib *addr) +{ + register struct subchannel_id reg1 asm ("1") = schid; + int ccode = -EIO; + + asm volatile( + " stsch 0(%3)\n" + "0: ipm %0\n" + " srl %0,28\n" + "1:\n" + EX_TABLE(0b, 1b) + : "+d" (ccode), "=m" (*addr) + : "d" (reg1), "a" (addr) + : "cc"); + trace_s390_cio_stsch(schid, addr, ccode); + + return ccode; +} +EXPORT_SYMBOL(stsch); + +int msch(struct subchannel_id schid, struct schib *addr) +{ + register struct subchannel_id reg1 asm ("1") = schid; + int ccode = -EIO; + + asm volatile( + " msch 0(%2)\n" + "0: ipm %0\n" + " srl %0,28\n" + "1:\n" + EX_TABLE(0b, 1b) + : "+d" (ccode) + : "d" (reg1), "a" (addr), "m" (*addr) + : "cc"); + trace_s390_cio_msch(schid, addr, ccode); + + return ccode; +} + +int tsch(struct subchannel_id schid, struct irb *addr) +{ + register struct subchannel_id reg1 asm ("1") = schid; + int ccode; + + asm volatile( + " tsch 0(%3)\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode), "=m" (*addr) + : "d" (reg1), "a" (addr) + : "cc"); + trace_s390_cio_tsch(schid, addr, ccode); + + return ccode; +} + +int ssch(struct subchannel_id schid, union orb *addr) +{ + register struct subchannel_id reg1 asm("1") = schid; + int ccode = -EIO; + + asm volatile( + " ssch 0(%2)\n" + "0: ipm %0\n" + " srl %0,28\n" + "1:\n" + EX_TABLE(0b, 1b) + : "+d" (ccode) + : "d" (reg1), "a" (addr), "m" (*addr) + : "cc", "memory"); + trace_s390_cio_ssch(schid, addr, ccode); + + return ccode; +} +EXPORT_SYMBOL(ssch); + +int csch(struct subchannel_id schid) +{ + register struct subchannel_id reg1 asm("1") = schid; + int ccode; + + asm volatile( + " csch\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) + : "d" (reg1) + : "cc"); + trace_s390_cio_csch(schid, ccode); + + return ccode; +} +EXPORT_SYMBOL(csch); + +int tpi(struct tpi_info *addr) +{ + int ccode; + + asm volatile( + " tpi 0(%2)\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode), "=m" (*addr) + : "a" (addr) + : "cc"); + trace_s390_cio_tpi(addr, ccode); + + return ccode; +} + +int chsc(void *chsc_area) +{ + typedef struct { char _[4096]; } addr_type; + int cc; + + asm volatile( + " .insn rre,0xb25f0000,%2,0\n" + " ipm %0\n" + " srl %0,28\n" + : "=d" (cc), "=m" (*(addr_type *) chsc_area) + : "d" (chsc_area), "m" (*(addr_type *) chsc_area) + : "cc"); + trace_s390_cio_chsc(chsc_area, cc); + + return cc; +} +EXPORT_SYMBOL(chsc); + +int rchp(struct chp_id chpid) +{ + register struct chp_id reg1 asm ("1") = chpid; + int ccode; + + asm volatile( + " lr 1,%1\n" + " rchp\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) : "d" (reg1) : "cc"); + trace_s390_cio_rchp(chpid, ccode); + + return ccode; +} + +int rsch(struct subchannel_id schid) +{ + register struct subchannel_id reg1 asm("1") = schid; + int ccode; + + asm volatile( + " rsch\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) + : "d" (reg1) + : "cc", "memory"); + trace_s390_cio_rsch(schid, ccode); + + return ccode; +} + +int hsch(struct subchannel_id schid) +{ + register struct subchannel_id reg1 asm("1") = schid; + int ccode; + + asm volatile( + " hsch\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) + : "d" (reg1) + : "cc"); + trace_s390_cio_hsch(schid, ccode); + + return ccode; +} + +int xsch(struct subchannel_id schid) +{ + register struct subchannel_id reg1 asm("1") = schid; + int ccode; + + asm volatile( + " xsch\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) + : "d" (reg1) + : "cc"); + trace_s390_cio_xsch(schid, ccode); + + return ccode; +} + +int stcrw(struct crw *crw) +{ + int ccode; + + asm volatile( + " stcrw 0(%2)\n" + " ipm %0\n" + " srl %0,28\n" + : "=d" (ccode), "=m" (*crw) + : "a" (crw) + : "cc"); + trace_s390_cio_stcrw(crw, ccode); + + return ccode; +} diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h index 11e255a4fbadb..b31ee6bff1e48 100644 --- a/drivers/s390/cio/ioasm.h +++ b/drivers/s390/cio/ioasm.h @@ -9,214 +9,20 @@ #include "trace.h" /* - * Some S390 specific IO instructions as inline + * Some S390 specific IO instructions */ -static inline int stsch(struct subchannel_id schid, struct schib *addr) -{ - register struct subchannel_id reg1 asm ("1") = schid; - int ccode = -EIO; - - asm volatile( - " stsch 0(%3)\n" - "0: ipm %0\n" - " srl %0,28\n" - "1:\n" - EX_TABLE(0b,1b) - : "+d" (ccode), "=m" (*addr) - : "d" (reg1), "a" (addr) - : "cc"); - trace_s390_cio_stsch(schid, addr, ccode); - - return ccode; -} - -static inline int msch(struct subchannel_id schid, struct schib *addr) -{ - register struct subchannel_id reg1 asm ("1") = schid; - int ccode = -EIO; - - asm volatile( - " msch 0(%2)\n" - "0: ipm %0\n" - " srl %0,28\n" - "1:\n" - EX_TABLE(0b,1b) - : "+d" (ccode) - : "d" (reg1), "a" (addr), "m" (*addr) - : "cc"); - trace_s390_cio_msch(schid, addr, ccode); - - return ccode; -} - -static inline int tsch(struct subchannel_id schid, struct irb *addr) -{ - register struct subchannel_id reg1 asm ("1") = schid; - int ccode; - - asm volatile( - " tsch 0(%3)\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode), "=m" (*addr) - : "d" (reg1), "a" (addr) - : "cc"); - trace_s390_cio_tsch(schid, addr, ccode); - - return ccode; -} - -static inline int ssch(struct subchannel_id schid, union orb *addr) -{ - register struct subchannel_id reg1 asm("1") = schid; - int ccode = -EIO; - - asm volatile( - " ssch 0(%2)\n" - "0: ipm %0\n" - " srl %0,28\n" - "1:\n" - EX_TABLE(0b, 1b) - : "+d" (ccode) - : "d" (reg1), "a" (addr), "m" (*addr) - : "cc", "memory"); - trace_s390_cio_ssch(schid, addr, ccode); - - return ccode; -} - -static inline int csch(struct subchannel_id schid) -{ - register struct subchannel_id reg1 asm("1") = schid; - int ccode; - - asm volatile( - " csch\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (reg1) - : "cc"); - trace_s390_cio_csch(schid, ccode); - - return ccode; -} - -static inline int tpi(struct tpi_info *addr) -{ - int ccode; - - asm volatile( - " tpi 0(%2)\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode), "=m" (*addr) - : "a" (addr) - : "cc"); - trace_s390_cio_tpi(addr, ccode); - - return ccode; -} - -static inline int chsc(void *chsc_area) -{ - typedef struct { char _[4096]; } addr_type; - int cc; - - asm volatile( - " .insn rre,0xb25f0000,%2,0\n" - " ipm %0\n" - " srl %0,28\n" - : "=d" (cc), "=m" (*(addr_type *) chsc_area) - : "d" (chsc_area), "m" (*(addr_type *) chsc_area) - : "cc"); - trace_s390_cio_chsc(chsc_area, cc); - - return cc; -} - -static inline int rchp(struct chp_id chpid) -{ - register struct chp_id reg1 asm ("1") = chpid; - int ccode; - - asm volatile( - " lr 1,%1\n" - " rchp\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) : "d" (reg1) : "cc"); - trace_s390_cio_rchp(chpid, ccode); - - return ccode; -} - -static inline int rsch(struct subchannel_id schid) -{ - register struct subchannel_id reg1 asm("1") = schid; - int ccode; - - asm volatile( - " rsch\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (reg1) - : "cc", "memory"); - trace_s390_cio_rsch(schid, ccode); - - return ccode; -} - -static inline int hsch(struct subchannel_id schid) -{ - register struct subchannel_id reg1 asm("1") = schid; - int ccode; - - asm volatile( - " hsch\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (reg1) - : "cc"); - trace_s390_cio_hsch(schid, ccode); - - return ccode; -} - -static inline int xsch(struct subchannel_id schid) -{ - register struct subchannel_id reg1 asm("1") = schid; - int ccode; - - asm volatile( - " xsch\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (reg1) - : "cc"); - trace_s390_cio_xsch(schid, ccode); - - return ccode; -} - -static inline int stcrw(struct crw *crw) -{ - int ccode; - - asm volatile( - " stcrw 0(%2)\n" - " ipm %0\n" - " srl %0,28\n" - : "=d" (ccode), "=m" (*crw) - : "a" (crw) - : "cc"); - trace_s390_cio_stcrw(crw, ccode); - - return ccode; -} +int stsch(struct subchannel_id schid, struct schib *addr); +int msch(struct subchannel_id schid, struct schib *addr); +int tsch(struct subchannel_id schid, struct irb *addr); +int ssch(struct subchannel_id schid, union orb *addr); +int csch(struct subchannel_id schid); +int tpi(struct tpi_info *addr); +int chsc(void *chsc_area); +int rchp(struct chp_id chpid); +int rsch(struct subchannel_id schid); +int hsch(struct subchannel_id schid); +int xsch(struct subchannel_id schid); +int stcrw(struct crw *crw); #endif -- GitLab From ce7f28531fe05fcabc8ccff8b6dc9b4b296a811e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 18 Dec 2015 14:15:17 +0100 Subject: [PATCH 1510/2855] mtd: omap_elm: print interrupt resource using %pr When CONFIG_LPAE is set on ARM, resource_size_t is 64-bit wide and we get a warning about an incorrect format string for printing the interrupt number in elm_probe: drivers/mtd/nand/omap_elm.c: In function 'elm_probe': drivers/mtd/nand/omap_elm.c:417:23: warning: format '%i' expects argument of type 'int', but argument 3 has type 'resource_size_t {aka long long unsigned int}' [-Wformat=] This patch avoids the type mismatch by printing the interrupt as a resource using the %pr format string. Signed-off-by: Arnd Bergmann Signed-off-by: Brian Norris --- drivers/mtd/nand/omap_elm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/omap_elm.c b/drivers/mtd/nand/omap_elm.c index 235ec7992b4cf..a3f32f939cc17 100644 --- a/drivers/mtd/nand/omap_elm.c +++ b/drivers/mtd/nand/omap_elm.c @@ -414,7 +414,7 @@ static int elm_probe(struct platform_device *pdev) ret = devm_request_irq(&pdev->dev, irq->start, elm_isr, 0, pdev->name, info); if (ret) { - dev_err(&pdev->dev, "failure requesting irq %i\n", irq->start); + dev_err(&pdev->dev, "failure requesting %pr\n", irq); return ret; } -- GitLab From 277af429fb40cf484c4a76c0b4cde2afc3e0c3d0 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 08:59:46 +0100 Subject: [PATCH 1511/2855] mtd: nand: fsmc: create and use mtd_to_fsmc() Create and use mtd_to_fsmc() to avoid duplication of container_of(mtd, struct fsmc_nand_data, mtd) calls. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/fsmc_nand.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 1c6c399496c2f..499fc5925c23d 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -326,13 +326,18 @@ struct fsmc_nand_data { void (*select_chip)(uint32_t bank, uint32_t busw); }; +static inline struct fsmc_nand_data *mtd_to_fsmc(struct mtd_info *mtd) +{ + return container_of(mtd, struct fsmc_nand_data, mtd); +} + /* Assert CS signal based on chipnr */ static void fsmc_select_chip(struct mtd_info *mtd, int chipnr) { struct nand_chip *chip = mtd_to_nand(mtd); struct fsmc_nand_data *host; - host = container_of(mtd, struct fsmc_nand_data, mtd); + host = mtd_to_fsmc(mtd); switch (chipnr) { case -1: @@ -359,8 +364,7 @@ static void fsmc_select_chip(struct mtd_info *mtd, int chipnr) static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *this = mtd_to_nand(mtd); - struct fsmc_nand_data *host = container_of(mtd, - struct fsmc_nand_data, mtd); + struct fsmc_nand_data *host = mtd_to_fsmc(mtd); void __iomem *regs = host->regs_va; unsigned int bank = host->bank; @@ -445,8 +449,7 @@ static void fsmc_nand_setup(void __iomem *regs, uint32_t bank, */ static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode) { - struct fsmc_nand_data *host = container_of(mtd, - struct fsmc_nand_data, mtd); + struct fsmc_nand_data *host = mtd_to_fsmc(mtd); void __iomem *regs = host->regs_va; uint32_t bank = host->bank; @@ -466,8 +469,7 @@ static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode) static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data, uint8_t *ecc) { - struct fsmc_nand_data *host = container_of(mtd, - struct fsmc_nand_data, mtd); + struct fsmc_nand_data *host = mtd_to_fsmc(mtd); void __iomem *regs = host->regs_va; uint32_t bank = host->bank; uint32_t ecc_tmp; @@ -517,8 +519,7 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data, static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data, uint8_t *ecc) { - struct fsmc_nand_data *host = container_of(mtd, - struct fsmc_nand_data, mtd); + struct fsmc_nand_data *host = mtd_to_fsmc(mtd); void __iomem *regs = host->regs_va; uint32_t bank = host->bank; uint32_t ecc_tmp; @@ -674,9 +675,8 @@ static void fsmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) */ static void fsmc_read_buf_dma(struct mtd_info *mtd, uint8_t *buf, int len) { - struct fsmc_nand_data *host; + struct fsmc_nand_data *host = mtd_to_fsmc(mtd); - host = container_of(mtd, struct fsmc_nand_data, mtd); dma_xfer(host, buf, len, DMA_FROM_DEVICE); } @@ -689,9 +689,8 @@ static void fsmc_read_buf_dma(struct mtd_info *mtd, uint8_t *buf, int len) static void fsmc_write_buf_dma(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct fsmc_nand_data *host; + struct fsmc_nand_data *host = mtd_to_fsmc(mtd); - host = container_of(mtd, struct fsmc_nand_data, mtd); dma_xfer(host, (void *)buf, len, DMA_TO_DEVICE); } @@ -712,8 +711,7 @@ static void fsmc_write_buf_dma(struct mtd_info *mtd, const uint8_t *buf, static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - struct fsmc_nand_data *host = container_of(mtd, - struct fsmc_nand_data, mtd); + struct fsmc_nand_data *host = mtd_to_fsmc(mtd); struct fsmc_eccplace *ecc_place = host->ecc_place; int i, j, s, stat, eccsize = chip->ecc.size; int eccbytes = chip->ecc.bytes; @@ -782,9 +780,8 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat, uint8_t *read_ecc, uint8_t *calc_ecc) { - struct fsmc_nand_data *host = container_of(mtd, - struct fsmc_nand_data, mtd); struct nand_chip *chip = mtd_to_nand(mtd); + struct fsmc_nand_data *host = mtd_to_fsmc(mtd); void __iomem *regs = host->regs_va; unsigned int bank = host->bank; uint32_t err_idx[8]; -- GitLab From faee6c358b0f1906f0f653a9d9f8beb5ebef174f Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 08:59:47 +0100 Subject: [PATCH 1512/2855] mtd: nand: nuc900: create and use mtd_to_nuc900() Create and use mtd_to_nuc900() instead of direct container_of() calls. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/nuc900_nand.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/nuc900_nand.c index 8148cd6896784..65908c0e65100 100644 --- a/drivers/mtd/nand/nuc900_nand.c +++ b/drivers/mtd/nand/nuc900_nand.c @@ -62,6 +62,11 @@ struct nuc900_nand { spinlock_t lock; }; +static inline struct nuc900_nand *mtd_to_nuc900(struct mtd_info *mtd) +{ + return container_of(mtd, struct nuc900_nand, mtd); +} + static const struct mtd_partition partitions[] = { { .name = "NAND FS 0", @@ -78,9 +83,7 @@ static const struct mtd_partition partitions[] = { static unsigned char nuc900_nand_read_byte(struct mtd_info *mtd) { unsigned char ret; - struct nuc900_nand *nand; - - nand = container_of(mtd, struct nuc900_nand, mtd); + struct nuc900_nand *nand = mtd_to_nuc900(mtd); ret = (unsigned char)read_data_reg(nand); @@ -91,9 +94,7 @@ static void nuc900_nand_read_buf(struct mtd_info *mtd, unsigned char *buf, int len) { int i; - struct nuc900_nand *nand; - - nand = container_of(mtd, struct nuc900_nand, mtd); + struct nuc900_nand *nand = mtd_to_nuc900(mtd); for (i = 0; i < len; i++) buf[i] = (unsigned char)read_data_reg(nand); @@ -103,9 +104,7 @@ static void nuc900_nand_write_buf(struct mtd_info *mtd, const unsigned char *buf, int len) { int i; - struct nuc900_nand *nand; - - nand = container_of(mtd, struct nuc900_nand, mtd); + struct nuc900_nand *nand = mtd_to_nuc900(mtd); for (i = 0; i < len; i++) write_data_reg(nand, buf[i]); @@ -124,11 +123,9 @@ static int nuc900_check_rb(struct nuc900_nand *nand) static int nuc900_nand_devready(struct mtd_info *mtd) { - struct nuc900_nand *nand; + struct nuc900_nand *nand = mtd_to_nuc900(mtd); int ready; - nand = container_of(mtd, struct nuc900_nand, mtd); - ready = (nuc900_check_rb(nand)) ? 1 : 0; return ready; } @@ -137,9 +134,7 @@ static void nuc900_nand_command_lp(struct mtd_info *mtd, unsigned int command, int column, int page_addr) { register struct nand_chip *chip = mtd_to_nand(mtd); - struct nuc900_nand *nand; - - nand = container_of(mtd, struct nuc900_nand, mtd); + struct nuc900_nand *nand = mtd_to_nuc900(mtd); if (command == NAND_CMD_READOOB) { column += mtd->writesize; -- GitLab From 4578ea9a9989d19633b005b9bdc23729ceb58a1b Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 08:59:48 +0100 Subject: [PATCH 1513/2855] mtd: nand: omap2: create and use mtd_to_omap() Define and use mtd_to_omap() instead of container_of(); Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/omap2.c | 55 +++++++++++++++------------------------- 1 file changed, 21 insertions(+), 34 deletions(-) diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 944a74e7a5130..1fb40db94bb58 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -177,6 +177,10 @@ struct omap_nand_info { struct device_node *of_node; }; +static inline struct omap_nand_info *mtd_to_omap(struct mtd_info *mtd) +{ + return container_of(mtd, struct omap_nand_info, mtd); +} /** * omap_prefetch_enable - configures and starts prefetch transfer * @cs: cs (chip select) number @@ -247,8 +251,7 @@ static int omap_prefetch_reset(int cs, struct omap_nand_info *info) */ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct omap_nand_info *info = container_of(mtd, - struct omap_nand_info, mtd); + struct omap_nand_info *info = mtd_to_omap(mtd); if (cmd != NAND_CMD_NONE) { if (ctrl & NAND_CLE) @@ -283,8 +286,7 @@ static void omap_read_buf8(struct mtd_info *mtd, u_char *buf, int len) */ static void omap_write_buf8(struct mtd_info *mtd, const u_char *buf, int len) { - struct omap_nand_info *info = container_of(mtd, - struct omap_nand_info, mtd); + struct omap_nand_info *info = mtd_to_omap(mtd); u_char *p = (u_char *)buf; u32 status = 0; @@ -319,8 +321,7 @@ static void omap_read_buf16(struct mtd_info *mtd, u_char *buf, int len) */ static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len) { - struct omap_nand_info *info = container_of(mtd, - struct omap_nand_info, mtd); + struct omap_nand_info *info = mtd_to_omap(mtd); u16 *p = (u16 *) buf; u32 status = 0; /* FIXME try bursts of writesw() or DMA ... */ @@ -344,8 +345,7 @@ static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len) */ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) { - struct omap_nand_info *info = container_of(mtd, - struct omap_nand_info, mtd); + struct omap_nand_info *info = mtd_to_omap(mtd); uint32_t r_count = 0; int ret = 0; u32 *p = (u32 *)buf; @@ -392,8 +392,7 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) static void omap_write_buf_pref(struct mtd_info *mtd, const u_char *buf, int len) { - struct omap_nand_info *info = container_of(mtd, - struct omap_nand_info, mtd); + struct omap_nand_info *info = mtd_to_omap(mtd); uint32_t w_count = 0; int i = 0, ret = 0; u16 *p = (u16 *)buf; @@ -458,8 +457,7 @@ static void omap_nand_dma_callback(void *data) static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, unsigned int len, int is_write) { - struct omap_nand_info *info = container_of(mtd, - struct omap_nand_info, mtd); + struct omap_nand_info *info = mtd_to_omap(mtd); struct dma_async_tx_descriptor *tx; enum dma_data_direction dir = is_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE; @@ -623,8 +621,7 @@ done: */ static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len) { - struct omap_nand_info *info = container_of(mtd, - struct omap_nand_info, mtd); + struct omap_nand_info *info = mtd_to_omap(mtd); int ret = 0; if (len <= mtd->oobsize) { @@ -671,8 +668,7 @@ out_copy: static void omap_write_buf_irq_pref(struct mtd_info *mtd, const u_char *buf, int len) { - struct omap_nand_info *info = container_of(mtd, - struct omap_nand_info, mtd); + struct omap_nand_info *info = mtd_to_omap(mtd); int ret = 0; unsigned long tim, limit; u32 val; @@ -886,8 +882,7 @@ static int omap_compare_ecc(u8 *ecc_data1, /* read from NAND memory */ static int omap_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) { - struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, - mtd); + struct omap_nand_info *info = mtd_to_omap(mtd); int blockCnt = 0, i = 0, ret = 0; int stat = 0; @@ -928,8 +923,7 @@ static int omap_correct_data(struct mtd_info *mtd, u_char *dat, static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) { - struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, - mtd); + struct omap_nand_info *info = mtd_to_omap(mtd); u32 val; val = readl(info->reg.gpmc_ecc_config); @@ -953,8 +947,7 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat, */ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) { - struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, - mtd); + struct omap_nand_info *info = mtd_to_omap(mtd); struct nand_chip *chip = mtd_to_nand(mtd); unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0; u32 val; @@ -1002,8 +995,7 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) { struct nand_chip *this = mtd_to_nand(mtd); - struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, - mtd); + struct omap_nand_info *info = mtd_to_omap(mtd); unsigned long timeo = jiffies; int status, state = this->state; @@ -1031,8 +1023,7 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) static int omap_dev_ready(struct mtd_info *mtd) { unsigned int val = 0; - struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, - mtd); + struct omap_nand_info *info = mtd_to_omap(mtd); val = readl(info->reg.gpmc_status); @@ -1058,8 +1049,7 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info *mtd, int mode) { unsigned int bch_type; unsigned int dev_width, nsectors; - struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, - mtd); + struct omap_nand_info *info = mtd_to_omap(mtd); enum omap_ecc ecc_opt = info->ecc_opt; struct nand_chip *chip = mtd_to_nand(mtd); u32 val, wr_mode; @@ -1162,8 +1152,7 @@ static u8 bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2, static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd, const u_char *dat, u_char *ecc_calc) { - struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, - mtd); + struct omap_nand_info *info = mtd_to_omap(mtd); int eccbytes = info->nand.ecc.bytes; struct gpmc_nand_regs *gpmc_regs = &info->reg; u8 *ecc_code; @@ -1334,8 +1323,7 @@ static int erased_sector_bitflips(u_char *data, u_char *oob, static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data, u_char *read_ecc, u_char *calc_ecc) { - struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, - mtd); + struct omap_nand_info *info = mtd_to_omap(mtd); struct nand_ecc_ctrl *ecc = &info->nand.ecc; int eccsteps = info->nand.ecc.steps; int i , j, stat = 0; @@ -2057,8 +2045,7 @@ static int omap_nand_remove(struct platform_device *pdev) { struct mtd_info *mtd = platform_get_drvdata(pdev); struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, - mtd); + struct omap_nand_info *info = mtd_to_omap(mtd); if (nand_chip->ecc.priv) { nand_bch_free(nand_chip->ecc.priv); nand_chip->ecc.priv = NULL; -- GitLab From 187d6ada2a129b3829c81b3e4f4bdf660859bb11 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 08:59:49 +0100 Subject: [PATCH 1514/2855] mtd: nand: ams-delta: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance instead of allocating our own. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/ams-delta.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c index b2b49c42920c2..0f638c628a0d5 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/ams-delta.c @@ -183,19 +183,16 @@ static int ams_delta_init(struct platform_device *pdev) return -ENXIO; /* Allocate memory for MTD device structure and private data */ - ams_delta_mtd = kzalloc(sizeof(struct mtd_info) + - sizeof(struct nand_chip), GFP_KERNEL); - if (!ams_delta_mtd) { + this = kzalloc(sizeof(struct nand_chip), GFP_KERNEL); + if (!this) { printk (KERN_WARNING "Unable to allocate E3 NAND MTD device structure.\n"); err = -ENOMEM; goto out; } + ams_delta_mtd = nand_to_mtd(this); ams_delta_mtd->owner = THIS_MODULE; - /* Get pointer to private data */ - this = (struct nand_chip *) (&ams_delta_mtd[1]); - /* Link the private data with the MTD structure */ ams_delta_mtd->priv = this; @@ -256,7 +253,7 @@ out_gpio: gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB); iounmap(io_base); out_free: - kfree(ams_delta_mtd); + kfree(this); out: return err; } @@ -276,7 +273,7 @@ static int ams_delta_cleanup(struct platform_device *pdev) iounmap(io_base); /* Free the MTD device structure */ - kfree(ams_delta_mtd); + kfree(mtd_to_nand(ams_delta_mtd)); return 0; } -- GitLab From ac01efebb1075a51a2803237159a440b71383117 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 08:59:50 +0100 Subject: [PATCH 1515/2855] mtd: nand: atmel: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/atmel_nand.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index edd191a6ee53c..9ba2831277eaa 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -116,7 +116,6 @@ static struct atmel_nfc nand_nfc; struct atmel_nand_host { struct nand_chip nand_chip; - struct mtd_info mtd; void __iomem *io_base; dma_addr_t io_phys; struct atmel_nand_data board; @@ -317,8 +316,10 @@ static int nfc_set_sram_bank(struct atmel_nand_host *host, unsigned int bank) return -EINVAL; if (bank) { + struct mtd_info *mtd = nand_to_mtd(&host->nand_chip); + /* Only for a 2k-page or lower flash, NFC can handle 2 banks */ - if (host->mtd.writesize > 2048) + if (mtd->writesize > 2048) return -EINVAL; nfc_writel(host->nfc->hsmc_regs, BANK, ATMEL_HSMC_NFC_BANK1); } else { @@ -1159,8 +1160,8 @@ static uint16_t *create_lookup_table(struct device *dev, int sector_size) static int atmel_pmecc_nand_init_params(struct platform_device *pdev, struct atmel_nand_host *host) { - struct mtd_info *mtd = &host->mtd; struct nand_chip *nand_chip = &host->nand_chip; + struct mtd_info *mtd = nand_to_mtd(nand_chip); struct resource *regs, *regs_pmerr, *regs_rom; uint16_t *galois_table; int cap, sector_size, err_no; @@ -1586,8 +1587,8 @@ static int atmel_of_init_port(struct atmel_nand_host *host, static int atmel_hw_nand_init_params(struct platform_device *pdev, struct atmel_nand_host *host) { - struct mtd_info *mtd = &host->mtd; struct nand_chip *nand_chip = &host->nand_chip; + struct mtd_info *mtd = nand_to_mtd(nand_chip); struct resource *regs; regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); @@ -2112,8 +2113,8 @@ static int atmel_nand_probe(struct platform_device *pdev) } host->io_phys = (dma_addr_t)mem->start; - mtd = &host->mtd; nand_chip = &host->nand_chip; + mtd = nand_to_mtd(nand_chip); host->dev = &pdev->dev; if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { nand_set_flash_node(nand_chip, pdev->dev.of_node); @@ -2283,7 +2284,7 @@ err_nand_ioremap: static int atmel_nand_remove(struct platform_device *pdev) { struct atmel_nand_host *host = platform_get_drvdata(pdev); - struct mtd_info *mtd = &host->mtd; + struct mtd_info *mtd = nand_to_mtd(&host->nand_chip); nand_release(mtd); -- GitLab From ff70f354a960f01afb2e0d4313bd664b88b1532f Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 08:59:51 +0100 Subject: [PATCH 1516/2855] mtd: nand: au1550nd: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/au1550nd.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 73fceb8743a24..280e5b61b815a 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c @@ -23,7 +23,6 @@ struct au1550nd_ctx { - struct mtd_info info; struct nand_chip chip; int cs; @@ -197,8 +196,9 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len) static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) { - struct au1550nd_ctx *ctx = container_of(mtd, struct au1550nd_ctx, info); struct nand_chip *this = mtd_to_nand(mtd); + struct au1550nd_ctx *ctx = container_of(this, struct au1550nd_ctx, + chip); switch (cmd) { @@ -267,8 +267,9 @@ static void au1550_select_chip(struct mtd_info *mtd, int chip) */ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) { - struct au1550nd_ctx *ctx = container_of(mtd, struct au1550nd_ctx, info); struct nand_chip *this = mtd_to_nand(mtd); + struct au1550nd_ctx *ctx = container_of(this, struct au1550nd_ctx, + chip); int ce_override = 0, i; unsigned long flags = 0; @@ -405,6 +406,7 @@ static int au1550nd_probe(struct platform_device *pdev) struct au1550nd_platdata *pd; struct au1550nd_ctx *ctx; struct nand_chip *this; + struct mtd_info *mtd; struct resource *r; int ret, cs; @@ -438,8 +440,9 @@ static int au1550nd_probe(struct platform_device *pdev) } this = &ctx->chip; - ctx->info.priv = this; - ctx->info.dev.parent = &pdev->dev; + mtd = nand_to_mtd(this); + mtd->priv = this; + mtd->dev.parent = &pdev->dev; /* figure out which CS# r->start belongs to */ cs = find_nand_cs(r->start); @@ -467,13 +470,13 @@ static int au1550nd_probe(struct platform_device *pdev) this->write_buf = (pd->devwidth) ? au_write_buf16 : au_write_buf; this->read_buf = (pd->devwidth) ? au_read_buf16 : au_read_buf; - ret = nand_scan(&ctx->info, 1); + ret = nand_scan(mtd, 1); if (ret) { dev_err(&pdev->dev, "NAND scan failed with %d\n", ret); goto out3; } - mtd_device_register(&ctx->info, pd->parts, pd->num_parts); + mtd_device_register(mtd, pd->parts, pd->num_parts); platform_set_drvdata(pdev, ctx); @@ -493,7 +496,7 @@ static int au1550nd_remove(struct platform_device *pdev) struct au1550nd_ctx *ctx = platform_get_drvdata(pdev); struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - nand_release(&ctx->info); + nand_release(nand_to_mtd(&ctx->chip)); iounmap(ctx->base); release_mem_region(r->start, 0x1000); kfree(ctx); -- GitLab From 7085a3bee3a20e3be07a103dd1f1cd997375527a Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 08:59:53 +0100 Subject: [PATCH 1517/2855] mtd: nand: bf5xx: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/bf5xx_nand.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index d9da5edb011ef..928d599205693 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c @@ -142,7 +142,6 @@ static struct nand_ecclayout bootrom_ecclayout = { struct bf5xx_nand_info { /* mtd info */ struct nand_hw_control controller; - struct mtd_info mtd; struct nand_chip chip; /* platform info */ @@ -160,7 +159,8 @@ struct bf5xx_nand_info { */ static struct bf5xx_nand_info *mtd_to_nand_info(struct mtd_info *mtd) { - return container_of(mtd, struct bf5xx_nand_info, mtd); + return container_of(mtd_to_nand(mtd), struct bf5xx_nand_info, + chip); } static struct bf5xx_nand_info *to_nand_info(struct platform_device *pdev) @@ -660,7 +660,7 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info) */ static int bf5xx_nand_add_partition(struct bf5xx_nand_info *info) { - struct mtd_info *mtd = &info->mtd; + struct mtd_info *mtd = nand_to_mtd(&info->chip); struct mtd_partition *parts = info->platform->partitions; int nr = info->platform->nr_partitions; @@ -675,7 +675,7 @@ static int bf5xx_nand_remove(struct platform_device *pdev) * and their partitions, then go through freeing the * resources used */ - nand_release(&info->mtd); + nand_release(nand_to_mtd(&info->chip)); peripheral_free_list(bfin_nfc_pin_req); bf5xx_nand_dma_remove(info); @@ -756,6 +756,7 @@ static int bf5xx_nand_probe(struct platform_device *pdev) /* initialise chip data struct */ chip = &info->chip; + mtd = nand_to_mtd(&info->chip); if (plat->data_width) chip->options |= NAND_BUSWIDTH_16; @@ -772,7 +773,7 @@ static int bf5xx_nand_probe(struct platform_device *pdev) chip->cmd_ctrl = bf5xx_nand_hwcontrol; chip->dev_ready = bf5xx_nand_devready; - chip->priv = &info->mtd; + chip->priv = mtd; chip->controller = &info->controller; chip->IO_ADDR_R = (void __iomem *) NFC_READ; @@ -781,7 +782,6 @@ static int bf5xx_nand_probe(struct platform_device *pdev) chip->chip_delay = 0; /* initialise mtd info data struct */ - mtd = &info->mtd; mtd->priv = chip; mtd->dev.parent = &pdev->dev; -- GitLab From f1c4c9992b1f088ab42ff9fa483ad9eed411e421 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 08:59:54 +0100 Subject: [PATCH 1518/2855] mtd: nand: brcm: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/brcmnand/brcmnand.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index dca816298aef0..c05723b4d7734 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -182,7 +182,6 @@ struct brcmnand_host { struct list_head node; struct nand_chip chip; - struct mtd_info mtd; struct platform_device *pdev; int cs; @@ -1078,7 +1077,7 @@ static int brcmnand_low_level_op(struct brcmnand_host *host, enum brcmnand_llop_type type, u32 data, bool last_op) { - struct mtd_info *mtd = &host->mtd; + struct mtd_info *mtd = nand_to_mtd(&host->chip); struct nand_chip *chip = &host->chip; struct brcmnand_controller *ctrl = host->ctrl; u32 tmp; @@ -1806,7 +1805,7 @@ static inline int get_blk_adr_bytes(u64 size, u32 writesize) static int brcmnand_setup_dev(struct brcmnand_host *host) { - struct mtd_info *mtd = &host->mtd; + struct mtd_info *mtd = nand_to_mtd(&host->chip); struct nand_chip *chip = &host->chip; struct brcmnand_controller *ctrl = host->ctrl; struct brcmnand_cfg *cfg = &host->hwcfg; @@ -1920,7 +1919,7 @@ static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn) return -ENXIO; } - mtd = &host->mtd; + mtd = nand_to_mtd(&host->chip); chip = &host->chip; nand_set_flash_node(chip, dn); @@ -2064,8 +2063,8 @@ static int brcmnand_resume(struct device *dev) } list_for_each_entry(host, &ctrl->host_list, node) { - struct mtd_info *mtd = &host->mtd; - struct nand_chip *chip = mtd_to_nand(mtd); + struct nand_chip *chip = &host->chip; + struct mtd_info *mtd = nand_to_mtd(chip); brcmnand_save_restore_cs_config(host, 1); @@ -2296,7 +2295,7 @@ int brcmnand_remove(struct platform_device *pdev) struct brcmnand_host *host; list_for_each_entry(host, &ctrl->host_list, node) - nand_release(&host->mtd); + nand_release(nand_to_mtd(&host->chip)); clk_disable_unprepare(ctrl->clk); -- GitLab From e787dfd1be424e0546d05d6819c8ab9c222ec248 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 08:59:55 +0100 Subject: [PATCH 1519/2855] mtd: nand: cafe: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/cafe_nand.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 77c92f1b985fd..7d6a14218bef8 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c @@ -605,11 +605,11 @@ static int cafe_nand_probe(struct pci_dev *pdev, pci_set_master(pdev); - mtd = kzalloc(sizeof(*mtd) + sizeof(struct cafe_priv), GFP_KERNEL); - if (!mtd) + cafe = kzalloc(sizeof(*cafe), GFP_KERNEL); + if (!cafe) return -ENOMEM; - cafe = (void *)(&mtd[1]); + mtd = nand_to_mtd(&cafe->nand); mtd->dev.parent = &pdev->dev; mtd->priv = &cafe->nand; cafe->nand.priv = cafe; @@ -792,7 +792,7 @@ static int cafe_nand_probe(struct pci_dev *pdev, out_ior: pci_iounmap(pdev, cafe->mmio); out_free_mtd: - kfree(mtd); + kfree(cafe); out: return err; } @@ -813,7 +813,7 @@ static void cafe_nand_remove(struct pci_dev *pdev) 2112 + sizeof(struct nand_buffers) + mtd->writesize + mtd->oobsize, cafe->dmabuf, cafe->dmaaddr); - kfree(mtd); + kfree(cafe); } static const struct pci_device_id cafe_nand_tbl[] = { -- GitLab From 8cd65d1a63d272a20bcd51b459b0550da53a80e5 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 08:59:57 +0100 Subject: [PATCH 1520/2855] mtd: nand: cs553x: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/cs553x_nand.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index 8904d685b257a..386ae832e03f9 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c @@ -197,14 +197,13 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) } /* Allocate memory for MTD device structure and private data */ - new_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); - if (!new_mtd) { + this = kzalloc(sizeof(struct nand_chip), GFP_KERNEL); + if (!this) { err = -ENOMEM; goto out; } - /* Get pointer to private data */ - this = (struct nand_chip *)(&new_mtd[1]); + new_mtd = nand_to_mtd(this); /* Link the private data with the MTD structure */ new_mtd->priv = this; @@ -257,7 +256,7 @@ out_free: out_ior: iounmap(this->IO_ADDR_R); out_mtd: - kfree(new_mtd); + kfree(this); out: return err; } @@ -337,19 +336,19 @@ static void __exit cs553x_cleanup(void) if (!mtd) continue; - this = mtd_to_nand(cs553x_mtd[i]); + this = mtd_to_nand(mtd); mmio_base = this->IO_ADDR_R; /* Release resources, unregister device */ - nand_release(cs553x_mtd[i]); - kfree(cs553x_mtd[i]->name); + nand_release(mtd); + kfree(mtd->name); cs553x_mtd[i] = NULL; /* unmap physical address */ iounmap(mmio_base); /* Free the MTD device structure */ - kfree(mtd); + kfree(this); } } -- GitLab From 2afd14f9270e4161a1f2528e75ff517c2d23d2f8 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 08:59:56 +0100 Subject: [PATCH 1521/2855] mtd: nand: cmx270: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon [Brian: dropped a defunct comment] Signed-off-by: Brian Norris --- drivers/mtd/nand/cmx270_nand.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c index 43bded66bc44e..00fd0e933ffb9 100644 --- a/drivers/mtd/nand/cmx270_nand.c +++ b/drivers/mtd/nand/cmx270_nand.c @@ -160,10 +160,8 @@ static int __init cmx270_init(void) gpio_direction_input(GPIO_NAND_RB); /* Allocate memory for MTD device structure and private data */ - cmx270_nand_mtd = kzalloc(sizeof(struct mtd_info) + - sizeof(struct nand_chip), - GFP_KERNEL); - if (!cmx270_nand_mtd) { + this = kzalloc(sizeof(struct nand_chip), GFP_KERNEL); + if (!this) { ret = -ENOMEM; goto err_kzalloc; } @@ -175,8 +173,7 @@ static int __init cmx270_init(void) goto err_ioremap; } - /* Get pointer to private data */ - this = (struct nand_chip *)(&cmx270_nand_mtd[1]); + cmx270_nand_mtd = nand_to_mtd(this); /* Link the private data with the MTD structure */ cmx270_nand_mtd->owner = THIS_MODULE; @@ -216,7 +213,7 @@ static int __init cmx270_init(void) err_scan: iounmap(cmx270_nand_io); err_ioremap: - kfree(cmx270_nand_mtd); + kfree(this); err_kzalloc: gpio_free(GPIO_NAND_RB); err_gpio_request: @@ -240,8 +237,7 @@ static void __exit cmx270_cleanup(void) iounmap(cmx270_nand_io); - /* Free the MTD device structure */ - kfree (cmx270_nand_mtd); + kfree(mtd_to_nand(cmx270_nand_mtd)); } module_exit(cmx270_cleanup); -- GitLab From a5cfb4db89bc73e9d35b8a348133fa0b4b99d81e Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 08:59:58 +0100 Subject: [PATCH 1522/2855] mtd: nand: davinci: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/davinci_nand.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index b5978d58e1df7..b1f69f9820703 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -53,7 +53,6 @@ * outputs in a "wire-AND" configuration, with no per-chip signals. */ struct davinci_nand_info { - struct mtd_info mtd; struct nand_chip chip; struct nand_ecclayout ecclayout; @@ -80,8 +79,10 @@ struct davinci_nand_info { static DEFINE_SPINLOCK(davinci_nand_lock); static bool ecc4_busy; -#define to_davinci_nand(m) container_of(m, struct davinci_nand_info, mtd) - +static inline struct davinci_nand_info *to_davinci_nand(struct mtd_info *mtd) +{ + return container_of(mtd_to_nand(mtd), struct davinci_nand_info, chip); +} static inline unsigned int davinci_nand_readl(struct davinci_nand_info *info, int offset) @@ -636,6 +637,7 @@ static int nand_davinci_probe(struct platform_device *pdev) int ret; uint32_t val; nand_ecc_modes_t ecc_mode; + struct mtd_info *mtd; pdata = nand_davinci_get_pdata(pdev); if (IS_ERR(pdata)) @@ -682,8 +684,9 @@ static int nand_davinci_probe(struct platform_device *pdev) info->base = base; info->vaddr = vaddr; - info->mtd.priv = &info->chip; - info->mtd.dev.parent = &pdev->dev; + mtd = nand_to_mtd(&info->chip); + mtd->priv = &info->chip; + mtd->dev.parent = &pdev->dev; nand_set_flash_node(&info->chip, pdev->dev.of_node); info->chip.IO_ADDR_R = vaddr; @@ -785,7 +788,7 @@ static int nand_davinci_probe(struct platform_device *pdev) spin_unlock_irq(&davinci_nand_lock); /* Scan to find existence of the device(s) */ - ret = nand_scan_ident(&info->mtd, pdata->mask_chipsel ? 2 : 1, NULL); + ret = nand_scan_ident(mtd, pdata->mask_chipsel ? 2 : 1, NULL); if (ret < 0) { dev_dbg(&pdev->dev, "no NAND chip(s) found\n"); goto err; @@ -797,9 +800,9 @@ static int nand_davinci_probe(struct platform_device *pdev) * usable: 10 bytes are needed, not 6. */ if (pdata->ecc_bits == 4) { - int chunks = info->mtd.writesize / 512; + int chunks = mtd->writesize / 512; - if (!chunks || info->mtd.oobsize < 16) { + if (!chunks || mtd->oobsize < 16) { dev_dbg(&pdev->dev, "too small\n"); ret = -EINVAL; goto err; @@ -811,8 +814,7 @@ static int nand_davinci_probe(struct platform_device *pdev) */ if (chunks == 1) { info->ecclayout = hwecc4_small; - info->ecclayout.oobfree[1].length = - info->mtd.oobsize - 16; + info->ecclayout.oobfree[1].length = mtd->oobsize - 16; goto syndrome_done; } if (chunks == 4) { @@ -833,15 +835,15 @@ syndrome_done: info->chip.ecc.layout = &info->ecclayout; } - ret = nand_scan_tail(&info->mtd); + ret = nand_scan_tail(mtd); if (ret < 0) goto err; if (pdata->parts) - ret = mtd_device_parse_register(&info->mtd, NULL, NULL, + ret = mtd_device_parse_register(mtd, NULL, NULL, pdata->parts, pdata->nr_parts); else - ret = mtd_device_register(&info->mtd, NULL, 0); + ret = mtd_device_register(mtd, NULL, 0); if (ret < 0) goto err; @@ -871,7 +873,7 @@ static int nand_davinci_remove(struct platform_device *pdev) ecc4_busy = false; spin_unlock_irq(&davinci_nand_lock); - nand_release(&info->mtd); + nand_release(nand_to_mtd(&info->chip)); clk_disable_unprepare(info->clk); -- GitLab From b0c423c7b630ecfff1e12f7bd7c3c7f0556bebb1 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:00 +0100 Subject: [PATCH 1523/2855] mtd: nand: diskonchip: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/diskonchip.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index 5f7bcc86486ee..fff7a4a697599 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -1556,15 +1556,15 @@ static int __init doc_probe(unsigned long physadr) printk(KERN_NOTICE "DiskOnChip found at 0x%lx\n", physadr); - len = sizeof(struct mtd_info) + - sizeof(struct nand_chip) + sizeof(struct doc_priv) + (2 * sizeof(struct nand_bbt_descr)); - mtd = kzalloc(len, GFP_KERNEL); - if (!mtd) { + len = sizeof(struct nand_chip) + sizeof(struct doc_priv) + + (2 * sizeof(struct nand_bbt_descr)); + nand = kzalloc(len, GFP_KERNEL); + if (!nand) { ret = -ENOMEM; goto fail; } - nand = (struct nand_chip *) (mtd + 1); + mtd = nand_to_mtd(nand); doc = (struct doc_priv *) (nand + 1); nand->bbt_td = (struct nand_bbt_descr *) (doc + 1); nand->bbt_md = nand->bbt_td + 1; @@ -1615,7 +1615,7 @@ static int __init doc_probe(unsigned long physadr) haven't yet added it. This is handled without incident by mtd_device_unregister, as far as I can tell. */ nand_release(mtd); - kfree(mtd); + kfree(nand); goto fail; } @@ -1650,7 +1650,7 @@ static void release_nanddoc(void) nand_release(mtd); iounmap(doc->virtadr); release_mem_region(doc->physadr, DOC_IOREMAP_LEN); - kfree(mtd); + kfree(nand); } } -- GitLab From 5d07379681a3b4b6b1543388cb0c4b5148292351 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:01 +0100 Subject: [PATCH 1524/2855] mtd: nand: docg4: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/docg4.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c index da93d7f5c8213..cb6efadd712eb 100644 --- a/drivers/mtd/nand/docg4.c +++ b/drivers/mtd/nand/docg4.c @@ -1305,14 +1305,14 @@ static int __init probe_docg4(struct platform_device *pdev) return -EIO; } - len = sizeof(struct mtd_info) + sizeof(struct nand_chip) + - sizeof(struct docg4_priv); - mtd = kzalloc(len, GFP_KERNEL); - if (mtd == NULL) { + len = sizeof(struct nand_chip) + sizeof(struct docg4_priv); + nand = kzalloc(len, GFP_KERNEL); + if (nand == NULL) { retval = -ENOMEM; - goto fail; + goto fail_unmap; } - nand = (struct nand_chip *) (mtd + 1); + + mtd = nand_to_mtd(nand); doc = (struct docg4_priv *) (nand + 1); mtd->priv = nand; nand->priv = doc; @@ -1354,16 +1354,17 @@ static int __init probe_docg4(struct platform_device *pdev) return 0; fail: - iounmap(virtadr); - if (mtd) { + if (nand) { /* re-declarations avoid compiler warning */ - struct nand_chip *nand = mtd_to_nand(mtd); struct docg4_priv *doc = nand->priv; nand_release(mtd); /* deletes partitions and mtd devices */ free_bch(doc->bch); - kfree(mtd); + kfree(nand); } +fail_unmap: + iounmap(virtadr); + return retval; } @@ -1372,7 +1373,7 @@ static int __exit cleanup_docg4(struct platform_device *pdev) struct docg4_priv *doc = platform_get_drvdata(pdev); nand_release(doc->mtd); free_bch(doc->bch); - kfree(doc->mtd); + kfree(mtd_to_nand(doc->mtd)); iounmap(doc->virtadr); return 0; } -- GitLab From 18ba50c3c0cc423019f8ed4b1c07e7a74203b289 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:02 +0100 Subject: [PATCH 1525/2855] mtd: nand: fsl_elbc: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/fsl_elbc_nand.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index ad6d5daacb839..7bde76a02555b 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -48,7 +48,6 @@ /* mtd information per set */ struct fsl_elbc_mtd { - struct mtd_info mtd; struct nand_chip chip; struct fsl_lbc_ctrl *ctrl; @@ -742,12 +741,13 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) struct fsl_lbc_regs __iomem *lbc = ctrl->regs; struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; struct nand_chip *chip = &priv->chip; + struct mtd_info *mtd = nand_to_mtd(chip); dev_dbg(priv->dev, "eLBC Set Information for bank %d\n", priv->bank); /* Fill in fsl_elbc_mtd structure */ - priv->mtd.priv = chip; - priv->mtd.dev.parent = priv->dev; + mtd->priv = chip; + mtd->dev.parent = priv->dev; nand_set_flash_node(chip, priv->dev->of_node); /* set timeout to maximum */ @@ -798,9 +798,11 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv) { struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; - nand_release(&priv->mtd); + struct mtd_info *mtd = nand_to_mtd(&priv->chip); - kfree(priv->mtd.name); + nand_release(mtd); + + kfree(mtd->name); if (priv->vbase) iounmap(priv->vbase); @@ -824,6 +826,7 @@ static int fsl_elbc_nand_probe(struct platform_device *pdev) int bank; struct device *dev; struct device_node *node = pdev->dev.of_node; + struct mtd_info *mtd; if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs) return -ENODEV; @@ -886,8 +889,9 @@ static int fsl_elbc_nand_probe(struct platform_device *pdev) goto err; } - priv->mtd.name = kasprintf(GFP_KERNEL, "%llx.flash", (u64)res.start); - if (!priv->mtd.name) { + mtd = nand_to_mtd(&priv->chip); + mtd->name = kasprintf(GFP_KERNEL, "%llx.flash", (u64)res.start); + if (!nand_to_mtd(&priv->chip)->name) { ret = -ENOMEM; goto err; } @@ -896,21 +900,21 @@ static int fsl_elbc_nand_probe(struct platform_device *pdev) if (ret) goto err; - ret = nand_scan_ident(&priv->mtd, 1, NULL); + ret = nand_scan_ident(mtd, 1, NULL); if (ret) goto err; - ret = fsl_elbc_chip_init_tail(&priv->mtd); + ret = fsl_elbc_chip_init_tail(mtd); if (ret) goto err; - ret = nand_scan_tail(&priv->mtd); + ret = nand_scan_tail(mtd); if (ret) goto err; /* First look for RedBoot table or partitions on the command * line, these take precedence over device tree information */ - mtd_device_parse_register(&priv->mtd, part_probe_types, NULL, + mtd_device_parse_register(mtd, part_probe_types, NULL, NULL, 0); printk(KERN_INFO "eLBC NAND device at 0x%llx, bank %d\n", -- GitLab From 5e9fb93dd3782eba5e6f282e01f4fc577f2d653a Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:03 +0100 Subject: [PATCH 1526/2855] mtd: nand: fsl_ifc: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/fsl_ifc_nand.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 3136842e88d56..3f5654f52cee9 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -40,7 +40,6 @@ struct fsl_ifc_ctrl; /* mtd information per set */ struct fsl_ifc_mtd { - struct mtd_info mtd; struct nand_chip chip; struct fsl_ifc_ctrl *ctrl; @@ -877,12 +876,13 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv) struct fsl_ifc_ctrl *ctrl = priv->ctrl; struct fsl_ifc_regs __iomem *ifc = ctrl->regs; struct nand_chip *chip = &priv->chip; + struct mtd_info *mtd = nand_to_mtd(&priv->chip); struct nand_ecclayout *layout; u32 csor; /* Fill in fsl_ifc_mtd structure */ - priv->mtd.priv = chip; - priv->mtd.dev.parent = priv->dev; + mtd->priv = chip; + mtd->dev.parent = priv->dev; nand_set_flash_node(chip, priv->dev->of_node); /* fill in nand_chip structure */ @@ -994,9 +994,11 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv) static int fsl_ifc_chip_remove(struct fsl_ifc_mtd *priv) { - nand_release(&priv->mtd); + struct mtd_info *mtd = nand_to_mtd(&priv->chip); - kfree(priv->mtd.name); + nand_release(mtd); + + kfree(mtd->name); if (priv->vbase) iounmap(priv->vbase); @@ -1031,6 +1033,7 @@ static int fsl_ifc_nand_probe(struct platform_device *dev) int ret; int bank; struct device_node *node = dev->dev.of_node; + struct mtd_info *mtd; if (!fsl_ifc_ctrl_dev || !fsl_ifc_ctrl_dev->regs) return -ENODEV; @@ -1103,8 +1106,10 @@ static int fsl_ifc_nand_probe(struct platform_device *dev) IFC_NAND_EVTER_INTR_FTOERIR_EN | IFC_NAND_EVTER_INTR_WPERIR_EN, &ifc->ifc_nand.nand_evter_intr_en); - priv->mtd.name = kasprintf(GFP_KERNEL, "%llx.flash", (u64)res.start); - if (!priv->mtd.name) { + + mtd = nand_to_mtd(&priv->chip); + mtd->name = kasprintf(GFP_KERNEL, "%llx.flash", (u64)res.start); + if (!mtd->name) { ret = -ENOMEM; goto err; } @@ -1113,22 +1118,21 @@ static int fsl_ifc_nand_probe(struct platform_device *dev) if (ret) goto err; - ret = nand_scan_ident(&priv->mtd, 1, NULL); + ret = nand_scan_ident(mtd, 1, NULL); if (ret) goto err; - ret = fsl_ifc_chip_init_tail(&priv->mtd); + ret = fsl_ifc_chip_init_tail(mtd); if (ret) goto err; - ret = nand_scan_tail(&priv->mtd); + ret = nand_scan_tail(mtd); if (ret) goto err; /* First look for RedBoot table or partitions on the command * line, these take precedence over device tree information */ - mtd_device_parse_register(&priv->mtd, part_probe_types, NULL, - NULL, 0); + mtd_device_parse_register(mtd, part_probe_types, NULL, NULL, 0); dev_info(priv->dev, "IFC NAND device at 0x%llx, bank %d\n", (unsigned long long)res.start, priv->bank); -- GitLab From 478d51f0213b9a4b0e605481aa3c14f4a084df4f Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:04 +0100 Subject: [PATCH 1527/2855] mtd: nand: fsl_upm: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/fsl_upm.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 68ec128e822ca..0379adc2d90e7 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -31,7 +31,6 @@ struct fsl_upm_nand { struct device *dev; - struct mtd_info mtd; struct nand_chip chip; int last_ctrl; struct mtd_partition *parts; @@ -49,7 +48,8 @@ struct fsl_upm_nand { static inline struct fsl_upm_nand *to_fsl_upm_nand(struct mtd_info *mtdinfo) { - return container_of(mtdinfo, struct fsl_upm_nand, mtd); + return container_of(mtd_to_nand(mtdinfo), struct fsl_upm_nand, + chip); } static int fun_chip_ready(struct mtd_info *mtd) @@ -66,9 +66,10 @@ static int fun_chip_ready(struct mtd_info *mtd) static void fun_wait_rnb(struct fsl_upm_nand *fun) { if (fun->rnb_gpio[fun->mchip_number] >= 0) { + struct mtd_info *mtd = nand_to_mtd(&fun->chip); int cnt = 1000000; - while (--cnt && !fun_chip_ready(&fun->mtd)) + while (--cnt && !fun_chip_ready(mtd)) cpu_relax(); if (!cnt) dev_err(fun->dev, "tired waiting for RNB\n"); @@ -157,6 +158,7 @@ static int fun_chip_init(struct fsl_upm_nand *fun, const struct device_node *upm_np, const struct resource *io_res) { + struct mtd_info *mtd = nand_to_mtd(&fun->chip); int ret; struct device_node *flash_np; @@ -174,30 +176,30 @@ static int fun_chip_init(struct fsl_upm_nand *fun, if (fun->rnb_gpio[0] >= 0) fun->chip.dev_ready = fun_chip_ready; - fun->mtd.priv = &fun->chip; - fun->mtd.dev.parent = fun->dev; + mtd->priv = &fun->chip; + mtd->dev.parent = fun->dev; flash_np = of_get_next_child(upm_np, NULL); if (!flash_np) return -ENODEV; nand_set_flash_node(&fun->chip, flash_np); - fun->mtd.name = kasprintf(GFP_KERNEL, "0x%llx.%s", (u64)io_res->start, - flash_np->name); - if (!fun->mtd.name) { + mtd->name = kasprintf(GFP_KERNEL, "0x%llx.%s", (u64)io_res->start, + flash_np->name); + if (!mtd->name) { ret = -ENOMEM; goto err; } - ret = nand_scan(&fun->mtd, fun->mchip_count); + ret = nand_scan(mtd, fun->mchip_count); if (ret) goto err; - ret = mtd_device_register(&fun->mtd, NULL, 0); + ret = mtd_device_register(mtd, NULL, 0); err: of_node_put(flash_np); if (ret) - kfree(fun->mtd.name); + kfree(mtd->name); return ret; } @@ -321,10 +323,11 @@ err1: static int fun_remove(struct platform_device *ofdev) { struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev); + struct mtd_info *mtd = nand_to_mtd(&fun->chip); int i; - nand_release(&fun->mtd); - kfree(fun->mtd.name); + nand_release(mtd); + kfree(mtd->name); for (i = 0; i < fun->mchip_count; i++) { if (fun->rnb_gpio[i] < 0) -- GitLab From bdf3a5550152606c7541094e14f892c2f4825856 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:05 +0100 Subject: [PATCH 1528/2855] mtd: nand: fsmc: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/fsmc_nand.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 499fc5925c23d..4c68e7a39b50b 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -299,7 +299,6 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = { */ struct fsmc_nand_data { u32 pid; - struct mtd_info mtd; struct nand_chip nand; struct mtd_partition *partitions; unsigned int nr_partitions; @@ -328,7 +327,7 @@ struct fsmc_nand_data { static inline struct fsmc_nand_data *mtd_to_fsmc(struct mtd_info *mtd) { - return container_of(mtd, struct fsmc_nand_data, mtd); + return container_of(mtd_to_nand(mtd), struct fsmc_nand_data, nand); } /* Assert CS signal based on chipnr */ @@ -1008,13 +1007,13 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) init_completion(&host->dma_access_complete); /* Link all private pointers */ - mtd = &host->mtd; + mtd = nand_to_mtd(&host->nand); nand = &host->nand; mtd->priv = nand; nand->priv = host; nand_set_flash_node(nand, np); - host->mtd.dev.parent = &pdev->dev; + mtd->dev.parent = &pdev->dev; nand->IO_ADDR_R = host->data_va; nand->IO_ADDR_W = host->data_va; nand->cmd_ctrl = fsmc_cmd_ctrl; @@ -1077,14 +1076,14 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) /* * Scan to find existence of the device */ - if (nand_scan_ident(&host->mtd, 1, NULL)) { + if (nand_scan_ident(mtd, 1, NULL)) { ret = -ENXIO; dev_err(&pdev->dev, "No NAND Device found!\n"); goto err_scan_ident; } if (AMBA_REV_BITS(host->pid) >= 8) { - switch (host->mtd.oobsize) { + switch (mtd->oobsize) { case 16: nand->ecc.layout = &fsmc_ecc4_16_layout; host->ecc_place = &fsmc_ecc4_sp_place; @@ -1135,7 +1134,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) * generated later in nand_bch_init() later. */ if (nand->ecc.mode != NAND_ECC_SOFT_BCH) { - switch (host->mtd.oobsize) { + switch (mtd->oobsize) { case 16: nand->ecc.layout = &fsmc_ecc1_16_layout; break; @@ -1156,7 +1155,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) } /* Second stage of scan to fill MTD data-structures */ - if (nand_scan_tail(&host->mtd)) { + if (nand_scan_tail(mtd)) { ret = -ENXIO; goto err_probe; } @@ -1171,9 +1170,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) /* * Check for partition info passed */ - host->mtd.name = "nand"; - ret = mtd_device_register(&host->mtd, host->partitions, - host->nr_partitions); + mtd->name = "nand"; + ret = mtd_device_register(mtd, host->partitions, host->nr_partitions); if (ret) goto err_probe; @@ -1203,7 +1201,7 @@ static int fsmc_nand_remove(struct platform_device *pdev) struct fsmc_nand_data *host = platform_get_drvdata(pdev); if (host) { - nand_release(&host->mtd); + nand_release(nand_to_mtd(&host->nand)); if (host->mode == USE_DMA_ACCESS) { dma_release_channel(host->write_dma_chan); -- GitLab From dc2948ca66e4133ccac1948dd7631072e84e996d Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:06 +0100 Subject: [PATCH 1529/2855] mtd: nand: gpio: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/gpio.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c index d57a07a597bec..99dd74c110383 100644 --- a/drivers/mtd/nand/gpio.c +++ b/drivers/mtd/nand/gpio.c @@ -35,12 +35,14 @@ struct gpiomtd { void __iomem *io_sync; - struct mtd_info mtd_info; struct nand_chip nand_chip; struct gpio_nand_platdata plat; }; -#define gpio_nand_getpriv(x) container_of(x, struct gpiomtd, mtd_info) +static inline struct gpiomtd *gpio_nand_getpriv(struct mtd_info *mtd) +{ + return container_of(mtd_to_nand(mtd), struct gpiomtd, nand_chip); +} #ifdef CONFIG_ARM @@ -195,7 +197,7 @@ static int gpio_nand_remove(struct platform_device *pdev) { struct gpiomtd *gpiomtd = platform_get_drvdata(pdev); - nand_release(&gpiomtd->mtd_info); + nand_release(nand_to_mtd(&gpiomtd->nand_chip)); if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) gpio_set_value(gpiomtd->plat.gpio_nwp, 0); @@ -208,6 +210,7 @@ static int gpio_nand_probe(struct platform_device *pdev) { struct gpiomtd *gpiomtd; struct nand_chip *chip; + struct mtd_info *mtd; struct resource *res; int ret = 0; @@ -274,24 +277,24 @@ static int gpio_nand_probe(struct platform_device *pdev) chip->chip_delay = gpiomtd->plat.chip_delay; chip->cmd_ctrl = gpio_nand_cmd_ctrl; - gpiomtd->mtd_info.priv = chip; - gpiomtd->mtd_info.dev.parent = &pdev->dev; + mtd = nand_to_mtd(chip); + mtd->priv = chip; + mtd->dev.parent = &pdev->dev; platform_set_drvdata(pdev, gpiomtd); if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) gpio_direction_output(gpiomtd->plat.gpio_nwp, 1); - if (nand_scan(&gpiomtd->mtd_info, 1)) { + if (nand_scan(mtd, 1)) { ret = -ENXIO; goto err_wp; } if (gpiomtd->plat.adjust_parts) - gpiomtd->plat.adjust_parts(&gpiomtd->plat, - gpiomtd->mtd_info.size); + gpiomtd->plat.adjust_parts(&gpiomtd->plat, mtd->size); - ret = mtd_device_register(&gpiomtd->mtd_info, gpiomtd->plat.parts, + ret = mtd_device_register(mtd, gpiomtd->plat.parts, gpiomtd->plat.num_parts); if (!ret) return 0; -- GitLab From 2a690b25f6c770e70cc00357846f39327531c464 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:07 +0100 Subject: [PATCH 1530/2855] mtd: nand: gpmi: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/gpmi-nand/gpmi-lib.c | 2 +- drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 23 +++++++++++------------ drivers/mtd/nand/gpmi-nand/gpmi-nand.h | 1 - 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c index 43fa16b5f5107..0f68a99fc4ad0 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c @@ -919,7 +919,7 @@ static int enable_edo_mode(struct gpmi_nand_data *this, int mode) { struct resources *r = &this->resources; struct nand_chip *nand = &this->nand; - struct mtd_info *mtd = &this->mtd; + struct mtd_info *mtd = nand_to_mtd(nand); uint8_t *feature; unsigned long rate; int ret; diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 802adb04bb973..38b07c7aa1e44 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -107,7 +107,7 @@ static irqreturn_t bch_irq(int irq, void *cookie) static inline int get_ecc_strength(struct gpmi_nand_data *this) { struct bch_geometry *geo = &this->bch_geometry; - struct mtd_info *mtd = &this->mtd; + struct mtd_info *mtd = nand_to_mtd(&this->nand); int ecc_strength; ecc_strength = ((mtd->oobsize - geo->metadata_size) * 8) @@ -139,8 +139,8 @@ static inline bool gpmi_check_ecc(struct gpmi_nand_data *this) static bool set_geometry_by_ecc_info(struct gpmi_nand_data *this) { struct bch_geometry *geo = &this->bch_geometry; - struct mtd_info *mtd = &this->mtd; - struct nand_chip *chip = mtd_to_nand(mtd); + struct nand_chip *chip = &this->nand; + struct mtd_info *mtd = nand_to_mtd(chip); struct nand_oobfree *of = gpmi_hw_ecclayout.oobfree; unsigned int block_mark_bit_offset; @@ -257,7 +257,7 @@ static bool set_geometry_by_ecc_info(struct gpmi_nand_data *this) static int legacy_set_geometry(struct gpmi_nand_data *this) { struct bch_geometry *geo = &this->bch_geometry; - struct mtd_info *mtd = &this->mtd; + struct mtd_info *mtd = nand_to_mtd(&this->nand); unsigned int metadata_size; unsigned int status_size; unsigned int block_mark_bit_offset; @@ -804,7 +804,7 @@ static int gpmi_alloc_dma_buffer(struct gpmi_nand_data *this) { struct bch_geometry *geo = &this->bch_geometry; struct device *dev = this->dev; - struct mtd_info *mtd = &this->mtd; + struct mtd_info *mtd = nand_to_mtd(&this->nand); /* [1] Allocate a command buffer. PAGE_SIZE is enough. */ this->cmd_buffer = kzalloc(PAGE_SIZE, GFP_DMA | GFP_KERNEL); @@ -1600,8 +1600,8 @@ static int mx23_check_transcription_stamp(struct gpmi_nand_data *this) { struct boot_rom_geometry *rom_geo = &this->rom_geometry; struct device *dev = this->dev; - struct mtd_info *mtd = &this->mtd; struct nand_chip *chip = &this->nand; + struct mtd_info *mtd = nand_to_mtd(chip); unsigned int search_area_size_in_strides; unsigned int stride; unsigned int page; @@ -1655,8 +1655,8 @@ static int mx23_write_transcription_stamp(struct gpmi_nand_data *this) { struct device *dev = this->dev; struct boot_rom_geometry *rom_geo = &this->rom_geometry; - struct mtd_info *mtd = &this->mtd; struct nand_chip *chip = &this->nand; + struct mtd_info *mtd = nand_to_mtd(chip); unsigned int block_size_in_pages; unsigned int search_area_size_in_strides; unsigned int search_area_size_in_pages; @@ -1735,7 +1735,7 @@ static int mx23_boot_init(struct gpmi_nand_data *this) { struct device *dev = this->dev; struct nand_chip *chip = &this->nand; - struct mtd_info *mtd = &this->mtd; + struct mtd_info *mtd = nand_to_mtd(chip); unsigned int block_count; unsigned int block; int chipnr; @@ -1831,14 +1831,13 @@ static int gpmi_set_geometry(struct gpmi_nand_data *this) static void gpmi_nand_exit(struct gpmi_nand_data *this) { - nand_release(&this->mtd); + nand_release(nand_to_mtd(&this->nand)); gpmi_free_dma_buffer(this); } static int gpmi_init_last(struct gpmi_nand_data *this) { - struct mtd_info *mtd = &this->mtd; - struct nand_chip *chip = mtd_to_nand(mtd); + struct nand_chip *chip = &this->nand; struct nand_ecc_ctrl *ecc = &chip->ecc; struct bch_geometry *bch_geo = &this->bch_geometry; int ret; @@ -1886,8 +1885,8 @@ static int gpmi_init_last(struct gpmi_nand_data *this) static int gpmi_nand_init(struct gpmi_nand_data *this) { - struct mtd_info *mtd = &this->mtd; struct nand_chip *chip = &this->nand; + struct mtd_info *mtd = nand_to_mtd(chip); int ret; /* init current chip */ diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h index 544062f65020e..4e49a1f5fa27a 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h @@ -160,7 +160,6 @@ struct gpmi_nand_data { /* MTD / NAND */ struct nand_chip nand; - struct mtd_info mtd; /* General-use Variables */ int current_chip; -- GitLab From fa100163d38ef8607652681fbe6f75491032610e Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:08 +0100 Subject: [PATCH 1531/2855] mtd: nand: hisi504: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/hisi504_nand.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/hisi504_nand.c b/drivers/mtd/nand/hisi504_nand.c index 6358d4ae7b75e..6e6e482c02a38 100644 --- a/drivers/mtd/nand/hisi504_nand.c +++ b/drivers/mtd/nand/hisi504_nand.c @@ -134,7 +134,6 @@ struct hinfc_host { struct nand_chip chip; - struct mtd_info mtd; struct device *dev; void __iomem *iobase; void __iomem *mmio; @@ -189,8 +188,8 @@ static void wait_controller_finished(struct hinfc_host *host) static void hisi_nfc_dma_transfer(struct hinfc_host *host, int todev) { - struct mtd_info *mtd = &host->mtd; - struct nand_chip *chip = mtd_to_nand(mtd); + struct nand_chip *chip = &host->chip; + struct mtd_info *mtd = nand_to_mtd(chip); unsigned long val; int ret; @@ -262,7 +261,7 @@ static int hisi_nfc_send_cmd_pageprog(struct hinfc_host *host) static int hisi_nfc_send_cmd_readstart(struct hinfc_host *host) { - struct mtd_info *mtd = &host->mtd; + struct mtd_info *mtd = nand_to_mtd(&host->chip); if ((host->addr_value[0] == host->cache_addr_value[0]) && (host->addr_value[1] == host->cache_addr_value[1])) @@ -643,7 +642,7 @@ static int hisi_nfc_ecc_probe(struct hinfc_host *host) int size, strength, ecc_bits; struct device *dev = host->dev; struct nand_chip *chip = &host->chip; - struct mtd_info *mtd = &host->mtd; + struct mtd_info *mtd = nand_to_mtd(chip); struct device_node *np = host->dev->of_node; size = of_get_nand_ecc_step_size(np); @@ -712,7 +711,7 @@ static int hisi_nfc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, host); chip = &host->chip; - mtd = &host->mtd; + mtd = nand_to_mtd(chip); irq = platform_get_irq(pdev, 0); if (irq < 0) { @@ -822,7 +821,7 @@ err_res: static int hisi_nfc_remove(struct platform_device *pdev) { struct hinfc_host *host = platform_get_drvdata(pdev); - struct mtd_info *mtd = &host->mtd; + struct mtd_info *mtd = nand_to_mtd(&host->chip); nand_release(mtd); -- GitLab From d25cc7abb164cea73894934d6b699c465b0bedaf Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:09 +0100 Subject: [PATCH 1532/2855] mtd: nand: jz4740: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/jz4740_nand.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index 5a06fba9bd1ab..03239a5a04cd6 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c @@ -59,7 +59,6 @@ #define JZ_NAND_MEM_ADDR_OFFSET 0x10000 struct jz_nand { - struct mtd_info mtd; struct nand_chip chip; void __iomem *base; struct resource *mem; @@ -76,7 +75,7 @@ struct jz_nand { static inline struct jz_nand *mtd_to_jz_nand(struct mtd_info *mtd) { - return container_of(mtd, struct jz_nand, mtd); + return container_of(mtd_to_nand(mtd), struct jz_nand, chip); } static void jz_nand_select_chip(struct mtd_info *mtd, int chipnr) @@ -334,8 +333,8 @@ static int jz_nand_detect_bank(struct platform_device *pdev, char gpio_name[9]; char res_name[6]; uint32_t ctrl; - struct mtd_info *mtd = &nand->mtd; struct nand_chip *chip = &nand->chip; + struct mtd_info *mtd = nand_to_mtd(chip); /* Request GPIO port. */ gpio = JZ_GPIO_MEM_CS0 + bank - 1; @@ -432,8 +431,8 @@ static int jz_nand_probe(struct platform_device *pdev) goto err_iounmap_mmio; } - mtd = &nand->mtd; chip = &nand->chip; + mtd = nand_to_mtd(chip); mtd->priv = chip; mtd->dev.parent = &pdev->dev; mtd->name = "jz4740-nand"; @@ -543,7 +542,7 @@ static int jz_nand_remove(struct platform_device *pdev) struct jz_nand *nand = platform_get_drvdata(pdev); size_t i; - nand_release(&nand->mtd); + nand_release(nand_to_mtd(&nand->chip)); /* Deassert and disable all chips */ writel(0, nand->base + JZ_REG_NAND_CTRL); -- GitLab From 0faf8c39c0580ecc0edfc2f5c932972ee3424935 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:10 +0100 Subject: [PATCH 1533/2855] mtd: nand: lpc32xx: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/lpc32xx_mlc.c | 7 +++---- drivers/mtd/nand/lpc32xx_slc.c | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c index 373885659fe0f..3400b3f99d30e 100644 --- a/drivers/mtd/nand/lpc32xx_mlc.c +++ b/drivers/mtd/nand/lpc32xx_mlc.c @@ -173,7 +173,6 @@ struct lpc32xx_nand_host { struct nand_chip nand_chip; struct lpc32xx_mlc_platform_data *pdata; struct clk *clk; - struct mtd_info mtd; void __iomem *io_base; int irq; struct lpc32xx_nand_cfg_mlc *ncfg; @@ -566,7 +565,7 @@ static void lpc32xx_ecc_enable(struct mtd_info *mtd, int mode) static int lpc32xx_dma_setup(struct lpc32xx_nand_host *host) { - struct mtd_info *mtd = &host->mtd; + struct mtd_info *mtd = nand_to_mtd(&host->nand_chip); dma_cap_mask_t mask; if (!host->pdata || !host->pdata->dma_filter) { @@ -660,8 +659,8 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) host->io_base_phy = rc->start; - mtd = &host->mtd; nand_chip = &host->nand_chip; + mtd = nand_to_mtd(nand_chip); if (pdev->dev.of_node) host->ncfg = lpc32xx_parse_dt(&pdev->dev); if (!host->ncfg) { @@ -814,7 +813,7 @@ err_exit1: static int lpc32xx_nand_remove(struct platform_device *pdev) { struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); - struct mtd_info *mtd = &host->mtd; + struct mtd_info *mtd = nand_to_mtd(&host->nand_chip); nand_release(mtd); free_irq(host->irq, host); diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c index fcd9facad05ea..61b2961297df4 100644 --- a/drivers/mtd/nand/lpc32xx_slc.c +++ b/drivers/mtd/nand/lpc32xx_slc.c @@ -204,7 +204,6 @@ struct lpc32xx_nand_host { struct nand_chip nand_chip; struct lpc32xx_slc_platform_data *pdata; struct clk *clk; - struct mtd_info mtd; void __iomem *io_base; struct lpc32xx_nand_cfg_slc *ncfg; @@ -703,7 +702,7 @@ static int lpc32xx_nand_write_page_raw_syndrome(struct mtd_info *mtd, static int lpc32xx_nand_dma_setup(struct lpc32xx_nand_host *host) { - struct mtd_info *mtd = &host->mtd; + struct mtd_info *mtd = nand_to_mtd(&host->nand_chip); dma_cap_mask_t mask; if (!host->pdata || !host->pdata->dma_filter) { @@ -799,8 +798,8 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) host->pdata = dev_get_platdata(&pdev->dev); - mtd = &host->mtd; chip = &host->nand_chip; + mtd = nand_to_mtd(chip); chip->priv = host; nand_set_flash_node(chip, pdev->dev.of_node); mtd->priv = chip; @@ -932,7 +931,7 @@ static int lpc32xx_nand_remove(struct platform_device *pdev) { uint32_t tmp; struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); - struct mtd_info *mtd = &host->mtd; + struct mtd_info *mtd = nand_to_mtd(&host->nand_chip); nand_release(mtd); dma_release_channel(host->dma_chan); -- GitLab From 5a9f23ffb6da3a6141ab58aeeb7470e0ec69f2ff Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:11 +0100 Subject: [PATCH 1534/2855] mtd: nand: mpc5121: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/mpc5121_nfc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index 642c486ea3c2d..8b4cd82f019e0 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c @@ -118,7 +118,6 @@ #define NFC_TIMEOUT (HZ / 10) /* 1/10 s */ struct mpc5121_nfc_prv { - struct mtd_info mtd; struct nand_chip chip; int irq; void __iomem *regs; @@ -654,8 +653,8 @@ static int mpc5121_nfc_probe(struct platform_device *op) if (!prv) return -ENOMEM; - mtd = &prv->mtd; chip = &prv->chip; + mtd = nand_to_mtd(chip); mtd->priv = chip; mtd->dev.parent = dev; -- GitLab From a008deb1655ca7301dd388237aa60f867d9f784c Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:12 +0100 Subject: [PATCH 1535/2855] mtd: nand: mxc: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/mxc_nand.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index b291258bfe7b2..9dd71af363c36 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -173,7 +173,6 @@ struct mxc_nand_devtype_data { }; struct mxc_nand_host { - struct mtd_info mtd; struct nand_chip nand; struct device *dev; @@ -1514,7 +1513,7 @@ static int mxcnd_probe(struct platform_device *pdev) host->dev = &pdev->dev; /* structures must be linked */ this = &host->nand; - mtd = &host->mtd; + mtd = nand_to_mtd(this); mtd->priv = this; mtd->dev.parent = &pdev->dev; mtd->name = DRIVER_NAME; @@ -1702,7 +1701,7 @@ static int mxcnd_remove(struct platform_device *pdev) { struct mxc_nand_host *host = platform_get_drvdata(pdev); - nand_release(&host->mtd); + nand_release(nand_to_mtd(&host->nand)); if (host->clk_act) clk_disable_unprepare(host->clk); -- GitLab From ed10f1655832de0c7e26d4c76ef1bad3bbf87b51 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:13 +0100 Subject: [PATCH 1536/2855] mtd: nand: nandsim: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/nandsim.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index eb2a567f41d9d..442eeaf09ebae 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -2236,13 +2236,13 @@ static int __init ns_init_module(void) } /* Allocate and initialize mtd_info, nand_chip and nandsim structures */ - nsmtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip) - + sizeof(struct nandsim), GFP_KERNEL); - if (!nsmtd) { + chip = kzalloc(sizeof(struct nand_chip) + sizeof(struct nandsim), + GFP_KERNEL); + if (!chip) { NS_ERR("unable to allocate core structures.\n"); return -ENOMEM; } - chip = (struct nand_chip *)(nsmtd + 1); + nsmtd = nand_to_mtd(chip); nsmtd->priv = (void *)chip; nand = (struct nandsim *)(chip + 1); chip->priv = (void *)nand; @@ -2392,7 +2392,7 @@ err_exit: for (i = 0;i < ARRAY_SIZE(nand->partitions); ++i) kfree(nand->partitions[i].name); error: - kfree(nsmtd); + kfree(chip); free_lists(); return retval; @@ -2413,7 +2413,7 @@ static void __exit ns_cleanup_module(void) nand_release(nsmtd); /* Unregister driver */ for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i) kfree(ns->partitions[i].name); - kfree(nsmtd); /* Free other structures */ + kfree(mtd_to_nand(nsmtd)); /* Free other structures */ free_lists(); } -- GitLab From ca921b537aea1731d0c14805452662eb5ac37fcb Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:14 +0100 Subject: [PATCH 1537/2855] mtd: nand: ndfc: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/ndfc.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index d8a23b052d501..3a7168e520072 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -37,7 +37,6 @@ struct ndfc_controller { struct platform_device *ofdev; void __iomem *ndfcbase; - struct mtd_info mtd; struct nand_chip chip; int chip_select; struct nand_hw_control ndfc_control; @@ -147,6 +146,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, { struct device_node *flash_np; struct nand_chip *chip = &ndfc->chip; + struct mtd_info *mtd = nand_to_mtd(chip); int ret; chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA; @@ -167,31 +167,32 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, chip->ecc.strength = 1; chip->priv = ndfc; - ndfc->mtd.priv = chip; - ndfc->mtd.dev.parent = &ndfc->ofdev->dev; + mtd->priv = chip; + mtd->dev.parent = &ndfc->ofdev->dev; flash_np = of_get_next_child(node, NULL); if (!flash_np) return -ENODEV; nand_set_flash_node(chip, flash_np); - ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s", - dev_name(&ndfc->ofdev->dev), flash_np->name); - if (!ndfc->mtd.name) { + ppdata.of_node = flash_np; + mtd->name = kasprintf(GFP_KERNEL, "%s.%s", dev_name(&ndfc->ofdev->dev), + flash_np->name); + if (!mtd->name) { ret = -ENOMEM; goto err; } - ret = nand_scan(&ndfc->mtd, 1); + ret = nand_scan(mtd, 1); if (ret) goto err; - ret = mtd_device_register(&ndfc->mtd, NULL, 0); + ret = mtd_device_register(mtd, NULL, 0); err: of_node_put(flash_np); if (ret) - kfree(ndfc->mtd.name); + kfree(mtd->name); return ret; } @@ -258,9 +259,10 @@ static int ndfc_probe(struct platform_device *ofdev) static int ndfc_remove(struct platform_device *ofdev) { struct ndfc_controller *ndfc = dev_get_drvdata(&ofdev->dev); + struct mtd_info *mtd = nand_to_mtd(&ndfc->chip); - nand_release(&ndfc->mtd); - kfree(ndfc->mtd.name); + nand_release(mtd); + kfree(mtd->name); return 0; } -- GitLab From 396a9c437bc0e884de58f58b4b4d7cce52181528 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:15 +0100 Subject: [PATCH 1538/2855] mtd: nand: nuc900: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/nuc900_nand.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/nuc900_nand.c index 65908c0e65100..4dad170f6545f 100644 --- a/drivers/mtd/nand/nuc900_nand.c +++ b/drivers/mtd/nand/nuc900_nand.c @@ -55,7 +55,6 @@ __raw_writel((val), (dev)->reg + REG_SMADDR) struct nuc900_nand { - struct mtd_info mtd; struct nand_chip chip; void __iomem *reg; struct clk *clk; @@ -64,7 +63,7 @@ struct nuc900_nand { static inline struct nuc900_nand *mtd_to_nuc900(struct mtd_info *mtd) { - return container_of(mtd, struct nuc900_nand, mtd); + return container_of(mtd_to_nand(mtd), struct nuc900_nand, chip); } static const struct mtd_partition partitions[] = { @@ -236,6 +235,7 @@ static int nuc900_nand_probe(struct platform_device *pdev) { struct nuc900_nand *nuc900_nand; struct nand_chip *chip; + struct mtd_info *mtd; struct resource *res; nuc900_nand = devm_kzalloc(&pdev->dev, sizeof(struct nuc900_nand), @@ -243,9 +243,10 @@ static int nuc900_nand_probe(struct platform_device *pdev) if (!nuc900_nand) return -ENOMEM; chip = &(nuc900_nand->chip); + mtd = nand_to_mtd(chip); - nuc900_nand->mtd.priv = chip; - nuc900_nand->mtd.dev.parent = &pdev->dev; + mtd->priv = chip; + mtd->dev.parent = &pdev->dev; spin_lock_init(&nuc900_nand->lock); nuc900_nand->clk = devm_clk_get(&pdev->dev, NULL); @@ -269,11 +270,10 @@ static int nuc900_nand_probe(struct platform_device *pdev) nuc900_nand_enable(nuc900_nand); - if (nand_scan(&(nuc900_nand->mtd), 1)) + if (nand_scan(mtd, 1)) return -ENXIO; - mtd_device_register(&(nuc900_nand->mtd), partitions, - ARRAY_SIZE(partitions)); + mtd_device_register(mtd, partitions, ARRAY_SIZE(partitions)); platform_set_drvdata(pdev, nuc900_nand); @@ -284,7 +284,7 @@ static int nuc900_nand_remove(struct platform_device *pdev) { struct nuc900_nand *nuc900_nand = platform_get_drvdata(pdev); - nand_release(&nuc900_nand->mtd); + nand_release(nand_to_mtd(&nuc900_nand->chip)); clk_disable(nuc900_nand->clk); return 0; -- GitLab From 432420c0fc8d077c30900a4e90779cd7dca021da Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:16 +0100 Subject: [PATCH 1539/2855] mtd: nand: omap2: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/omap2.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 1fb40db94bb58..f9d0b58323e38 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -152,7 +152,6 @@ static struct nand_hw_control omap_gpmc_controller = { struct omap_nand_info { struct omap_nand_platform_data *pdata; - struct mtd_info mtd; struct nand_chip nand; struct platform_device *pdev; @@ -179,8 +178,9 @@ struct omap_nand_info { static inline struct omap_nand_info *mtd_to_omap(struct mtd_info *mtd) { - return container_of(mtd, struct omap_nand_info, mtd); + return container_of(mtd_to_nand(mtd), struct omap_nand_info, nand); } + /** * omap_prefetch_enable - configures and starts prefetch transfer * @cs: cs (chip select) number @@ -1670,10 +1670,10 @@ static int omap_nand_probe(struct platform_device *pdev) info->reg = pdata->reg; info->of_node = pdata->of_node; info->ecc_opt = pdata->ecc_opt; - mtd = &info->mtd; + nand_chip = &info->nand; + mtd = nand_to_mtd(nand_chip); mtd->priv = &info->nand; mtd->dev.parent = &pdev->dev; - nand_chip = &info->nand; nand_chip->ecc.priv = NULL; nand_set_flash_node(nand_chip, pdata->of_node); @@ -1897,7 +1897,7 @@ static int omap_nand_probe(struct platform_device *pdev) ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; err = elm_config(info->elm_dev, BCH4_ECC, - info->mtd.writesize / nand_chip->ecc.size, + mtd->writesize / nand_chip->ecc.size, nand_chip->ecc.size, nand_chip->ecc.bytes); if (err < 0) goto return_error; @@ -1951,7 +1951,7 @@ static int omap_nand_probe(struct platform_device *pdev) nand_chip->ecc.write_page = omap_write_page_bch; err = elm_config(info->elm_dev, BCH8_ECC, - info->mtd.writesize / nand_chip->ecc.size, + mtd->writesize / nand_chip->ecc.size, nand_chip->ecc.size, nand_chip->ecc.bytes); if (err < 0) goto return_error; @@ -1981,7 +1981,7 @@ static int omap_nand_probe(struct platform_device *pdev) nand_chip->ecc.write_page = omap_write_page_bch; err = elm_config(info->elm_dev, BCH16_ECC, - info->mtd.writesize / nand_chip->ecc.size, + mtd->writesize / nand_chip->ecc.size, nand_chip->ecc.size, nand_chip->ecc.bytes); if (err < 0) goto return_error; -- GitLab From 53cd2681e02bee59e433b20934bf71f4db5a87d8 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:17 +0100 Subject: [PATCH 1540/2855] mtd: nand: orion: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/orion_nand.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 4ed4f676ee05d..087a04024d6a0 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -85,11 +85,11 @@ static int __init orion_nand_probe(struct platform_device *pdev) u32 val = 0; nc = devm_kzalloc(&pdev->dev, - sizeof(struct nand_chip) + sizeof(struct mtd_info), + sizeof(struct nand_chip), GFP_KERNEL); if (!nc) return -ENOMEM; - mtd = (struct mtd_info *)(nc + 1); + mtd = nand_to_mtd(nc); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); io_base = devm_ioremap_resource(&pdev->dev, res); -- GitLab From 4e3b6d1701be50dfb33879a066bae16c627f5794 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:18 +0100 Subject: [PATCH 1541/2855] mtd: nand: pasemi: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/pasemi_nand.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 0ececac2020fb..4dd298523e815 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c @@ -110,17 +110,15 @@ static int pasemi_nand_probe(struct platform_device *ofdev) pr_debug("pasemi_nand at %pR\n", &res); /* Allocate memory for MTD device structure and private data */ - pasemi_nand_mtd = kzalloc(sizeof(struct mtd_info) + - sizeof(struct nand_chip), GFP_KERNEL); - if (!pasemi_nand_mtd) { + chip = kzalloc(sizeof(struct nand_chip), GFP_KERNEL); + if (!chip) { printk(KERN_WARNING "Unable to allocate PASEMI NAND MTD device structure\n"); err = -ENOMEM; goto out; } - /* Get pointer to private data */ - chip = (struct nand_chip *)&pasemi_nand_mtd[1]; + pasemi_nand_mtd = nand_to_mtd(chip); /* Link the private data with the MTD structure */ pasemi_nand_mtd->priv = chip; @@ -180,7 +178,7 @@ static int pasemi_nand_probe(struct platform_device *ofdev) out_ior: iounmap(chip->IO_ADDR_R); out_mtd: - kfree(pasemi_nand_mtd); + kfree(chip); out: return err; } @@ -202,7 +200,7 @@ static int pasemi_nand_remove(struct platform_device *ofdev) iounmap(chip->IO_ADDR_R); /* Free the MTD device structure */ - kfree(pasemi_nand_mtd); + kfree(chip); pasemi_nand_mtd = NULL; -- GitLab From a0260d21ac91c5deaeadf4d53a27b3f9f40cb77b Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:19 +0100 Subject: [PATCH 1542/2855] mtd: nand: plat: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/plat_nand.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index 06ac6c64dcd53..796eb7d54f2f1 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c @@ -20,7 +20,6 @@ struct plat_nand_data { struct nand_chip chip; - struct mtd_info mtd; void __iomem *io_base; }; @@ -31,6 +30,7 @@ static int plat_nand_probe(struct platform_device *pdev) { struct platform_nand_data *pdata = dev_get_platdata(&pdev->dev); struct plat_nand_data *data; + struct mtd_info *mtd; struct resource *res; const char **part_types; int err = 0; @@ -58,8 +58,9 @@ static int plat_nand_probe(struct platform_device *pdev) data->chip.priv = &data; nand_set_flash_node(&data->chip, pdev->dev.of_node); - data->mtd.priv = &data->chip; - data->mtd.dev.parent = &pdev->dev; + mtd = nand_to_mtd(&data->chip); + mtd->priv = &data->chip; + mtd->dev.parent = &pdev->dev; data->chip.IO_ADDR_R = data->io_base; data->chip.IO_ADDR_W = data->io_base; @@ -87,21 +88,21 @@ static int plat_nand_probe(struct platform_device *pdev) } /* Scan to find existence of the device */ - if (nand_scan(&data->mtd, pdata->chip.nr_chips)) { + if (nand_scan(mtd, pdata->chip.nr_chips)) { err = -ENXIO; goto out; } part_types = pdata->chip.part_probe_types; - err = mtd_device_parse_register(&data->mtd, part_types, NULL, + err = mtd_device_parse_register(mtd, part_types, NULL, pdata->chip.partitions, pdata->chip.nr_partitions); if (!err) return err; - nand_release(&data->mtd); + nand_release(mtd); out: if (pdata->ctrl.remove) pdata->ctrl.remove(pdev); @@ -116,7 +117,7 @@ static int plat_nand_remove(struct platform_device *pdev) struct plat_nand_data *data = platform_get_drvdata(pdev); struct platform_nand_data *pdata = dev_get_platdata(&pdev->dev); - nand_release(&data->mtd); + nand_release(nand_to_mtd(&data->chip)); if (pdata->ctrl.remove) pdata->ctrl.remove(pdev); -- GitLab From 063294a36e8e8c2642b6c63a709d6792a609ec33 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:20 +0100 Subject: [PATCH 1543/2855] mtd: nand: pxa3xx: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/pxa3xx_nand.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index dc39a9847bf5e..c4d578809ea97 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -167,7 +167,6 @@ enum pxa3xx_nand_variant { struct pxa3xx_nand_host { struct nand_chip chip; - struct mtd_info *mtd; void *info_data; /* page size of attached chip */ @@ -450,14 +449,15 @@ static int pxa3xx_nand_init_timings_compat(struct pxa3xx_nand_host *host, struct nand_chip *chip = &host->chip; struct pxa3xx_nand_info *info = host->info_data; const struct pxa3xx_nand_flash *f = NULL; + struct mtd_info *mtd = nand_to_mtd(&host->chip); int i, id, ntypes; ntypes = ARRAY_SIZE(builtin_flash_types); - chip->cmdfunc(host->mtd, NAND_CMD_READID, 0x00, -1); + chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); - id = chip->read_byte(host->mtd); - id |= chip->read_byte(host->mtd) << 0x8; + id = chip->read_byte(mtd); + id |= chip->read_byte(mtd) << 0x8; for (i = 0; i < ntypes; i++) { f = &builtin_flash_types[i]; @@ -890,7 +890,7 @@ static void set_command_address(struct pxa3xx_nand_info *info, static void prepare_start_command(struct pxa3xx_nand_info *info, int command) { struct pxa3xx_nand_host *host = info->host[info->cs]; - struct mtd_info *mtd = host->mtd; + struct mtd_info *mtd = nand_to_mtd(&host->chip); /* reset data and oob column point to handle data */ info->buf_start = 0; @@ -943,7 +943,7 @@ static int prepare_set_command(struct pxa3xx_nand_info *info, int command, struct mtd_info *mtd; host = info->host[info->cs]; - mtd = host->mtd; + mtd = nand_to_mtd(&host->chip); addr_cycle = 0; exec_cmd = 1; @@ -1415,8 +1415,8 @@ static int pxa3xx_nand_config_ident(struct pxa3xx_nand_info *info) static void pxa3xx_nand_config_tail(struct pxa3xx_nand_info *info) { struct pxa3xx_nand_host *host = info->host[info->cs]; - struct mtd_info *mtd = host->mtd; - struct nand_chip *chip = mtd_to_nand(mtd); + struct nand_chip *chip = &host->chip; + struct mtd_info *mtd = nand_to_mtd(chip); info->reg_ndcr |= (host->col_addr_cycles == 2) ? NDCR_RA_START : 0; info->reg_ndcr |= (chip->page_shift == 6) ? NDCR_PG_PER_BLK : 0; @@ -1693,19 +1693,20 @@ static int alloc_nand_resource(struct platform_device *pdev) pdata = dev_get_platdata(&pdev->dev); if (pdata->num_cs <= 0) return -ENODEV; - info = devm_kzalloc(&pdev->dev, sizeof(*info) + (sizeof(*mtd) + - sizeof(*host)) * pdata->num_cs, GFP_KERNEL); + info = devm_kzalloc(&pdev->dev, + sizeof(*info) + sizeof(*host) * pdata->num_cs, + GFP_KERNEL); if (!info) return -ENOMEM; info->pdev = pdev; info->variant = pxa3xx_nand_get_variant(pdev); for (cs = 0; cs < pdata->num_cs; cs++) { - mtd = (void *)&info[1] + (sizeof(*mtd) + sizeof(*host)) * cs; - chip = (struct nand_chip *)(&mtd[1]); - host = (struct pxa3xx_nand_host *)chip; + host = (void *)&info[1] + sizeof(*host) * cs; + chip = &host->chip; + chip->priv = host; + mtd = nand_to_mtd(chip); info->host[cs] = host; - host->mtd = mtd; host->cs = cs; host->info_data = info; mtd->priv = chip; @@ -1833,7 +1834,7 @@ static int pxa3xx_nand_remove(struct platform_device *pdev) clk_disable_unprepare(info->clk); for (cs = 0; cs < pdata->num_cs; cs++) - nand_release(info->host[cs]->mtd); + nand_release(nand_to_mtd(&info->host[cs]->chip)); return 0; } @@ -1904,7 +1905,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) info = platform_get_drvdata(pdev); probe_success = 0; for (cs = 0; cs < pdata->num_cs; cs++) { - struct mtd_info *mtd = info->host[cs]->mtd; + struct mtd_info *mtd = nand_to_mtd(&info->host[cs]->chip); /* * The mtd name matches the one used in 'mtdparts' kernel -- GitLab From de9f56f9137b8a6bfaf9b9dcb7d297bf0b61ffbf Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:21 +0100 Subject: [PATCH 1544/2855] mtd: nand: r852: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/r852.c | 34 +++++++++++++++------------------- drivers/mtd/nand/r852.h | 1 - 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index ca05b20c017fd..1ac8ef2ed2dbc 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c @@ -634,25 +634,22 @@ static void r852_update_media_status(struct r852_device *dev) */ static int r852_register_nand_device(struct r852_device *dev) { - dev->mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL); - - if (!dev->mtd) - goto error1; + struct mtd_info *mtd = nand_to_mtd(dev->chip); WARN_ON(dev->card_registred); - dev->mtd->priv = dev->chip; - dev->mtd->dev.parent = &dev->pci_dev->dev; + mtd->priv = dev->chip; + mtd->dev.parent = &dev->pci_dev->dev; if (dev->readonly) dev->chip->options |= NAND_ROM; r852_engine_enable(dev); - if (sm_register_device(dev->mtd, dev->sm)) - goto error2; + if (sm_register_device(mtd, dev->sm)) + goto error1; - if (device_create_file(&dev->mtd->dev, &dev_attr_media_type)) { + if (device_create_file(&mtd->dev, &dev_attr_media_type)) { message("can't create media type sysfs attribute"); goto error3; } @@ -660,9 +657,7 @@ static int r852_register_nand_device(struct r852_device *dev) dev->card_registred = 1; return 0; error3: - nand_release(dev->mtd); -error2: - kfree(dev->mtd); + nand_release(mtd); error1: /* Force card redetect */ dev->card_detected = 0; @@ -675,15 +670,15 @@ error1: static void r852_unregister_nand_device(struct r852_device *dev) { + struct mtd_info *mtd = nand_to_mtd(dev->chip); + if (!dev->card_registred) return; - device_remove_file(&dev->mtd->dev, &dev_attr_media_type); - nand_release(dev->mtd); + device_remove_file(&mtd->dev, &dev_attr_media_type); + nand_release(mtd); r852_engine_disable(dev); dev->card_registred = 0; - kfree(dev->mtd); - dev->mtd = NULL; } /* Card state updater */ @@ -1031,6 +1026,7 @@ static int r852_suspend(struct device *device) static int r852_resume(struct device *device) { struct r852_device *dev = pci_get_drvdata(to_pci_dev(device)); + struct mtd_info *mtd = nand_to_mtd(dev->chip); r852_disable_irqs(dev); r852_card_update_present(dev); @@ -1050,9 +1046,9 @@ static int r852_resume(struct device *device) /* Otherwise, initialize the card */ if (dev->card_registred) { r852_engine_enable(dev); - dev->chip->select_chip(dev->mtd, 0); - dev->chip->cmdfunc(dev->mtd, NAND_CMD_RESET, -1, -1); - dev->chip->select_chip(dev->mtd, -1); + dev->chip->select_chip(mtd, 0); + dev->chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); + dev->chip->select_chip(mtd, -1); } /* Program card detection IRQ */ diff --git a/drivers/mtd/nand/r852.h b/drivers/mtd/nand/r852.h index e6a21d9d22c60..d042ddb71a8b8 100644 --- a/drivers/mtd/nand/r852.h +++ b/drivers/mtd/nand/r852.h @@ -108,7 +108,6 @@ struct r852_device { void __iomem *mmio; /* mmio */ - struct mtd_info *mtd; /* mtd backpointer */ struct nand_chip *chip; /* nand chip backpointer */ struct pci_dev *pci_dev; /* pci backpointer */ -- GitLab From 9c9eef89ec74433f00593938f8af5113383d898a Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:23 +0100 Subject: [PATCH 1545/2855] mtd: nand: sh_flctl: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/sh_flctl.c | 8 ++++---- include/linux/mtd/sh_flctl.h | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index 57dc52578e078..0ec4b04b35362 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c @@ -607,13 +607,13 @@ static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr) case FL_REPAIRABLE: dev_info(&flctl->pdev->dev, "applied ecc on page 0x%x", page_addr); - flctl->mtd.ecc_stats.corrected++; + mtd->ecc_stats.corrected++; break; case FL_ERROR: dev_warn(&flctl->pdev->dev, "page 0x%x contains corrupted data\n", page_addr); - flctl->mtd.ecc_stats.failed++; + mtd->ecc_stats.failed++; break; default: ; @@ -1120,8 +1120,8 @@ static int flctl_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, flctl); - flctl_mtd = &flctl->mtd; nand = &flctl->chip; + flctl_mtd = nand_to_mtd(nand); nand_set_flash_node(nand, pdev->dev.of_node); flctl_mtd->priv = nand; flctl_mtd->dev.parent = &pdev->dev; @@ -1178,7 +1178,7 @@ static int flctl_remove(struct platform_device *pdev) struct sh_flctl *flctl = platform_get_drvdata(pdev); flctl_release_dma(flctl); - nand_release(&flctl->mtd); + nand_release(nand_to_mtd(&flctl->chip)); pm_runtime_disable(&pdev->dev); return 0; diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h index 1c28f8879b1c2..76e3e88bedfeb 100644 --- a/include/linux/mtd/sh_flctl.h +++ b/include/linux/mtd/sh_flctl.h @@ -143,7 +143,6 @@ enum flctl_ecc_res_t { struct dma_chan; struct sh_flctl { - struct mtd_info mtd; struct nand_chip chip; struct platform_device *pdev; struct dev_pm_qos_request pm_qos; @@ -186,7 +185,7 @@ struct sh_flctl_platform_data { static inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo) { - return container_of(mtdinfo, struct sh_flctl, mtd); + return container_of(mtd_to_nand(mtdinfo), struct sh_flctl, chip); } #endif /* __SH_FLCTL_H__ */ -- GitLab From 0324e6469ab056bef1ffd7c36833448ab1f3df8d Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:24 +0100 Subject: [PATCH 1546/2855] mtd: nand: sharpsl: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/sharpsl.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index 84129e5399301..4b649fbad66ec 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c @@ -29,13 +29,15 @@ #include struct sharpsl_nand { - struct mtd_info mtd; struct nand_chip chip; void __iomem *io; }; -#define mtd_to_sharpsl(_mtd) container_of(_mtd, struct sharpsl_nand, mtd) +static inline struct sharpsl_nand *mtd_to_sharpsl(struct mtd_info *mtd) +{ + return container_of(mtd_to_nand(mtd), struct sharpsl_nand, chip); +} /* register offset */ #define ECCLPLB 0x00 /* line parity 7 - 0 bit */ @@ -109,6 +111,7 @@ static int sharpsl_nand_calculate_ecc(struct mtd_info *mtd, const u_char * dat, static int sharpsl_nand_probe(struct platform_device *pdev) { struct nand_chip *this; + struct mtd_info *mtd; struct resource *r; int err = 0; struct sharpsl_nand *sharpsl; @@ -143,8 +146,9 @@ static int sharpsl_nand_probe(struct platform_device *pdev) this = (struct nand_chip *)(&sharpsl->chip); /* Link the private data with the MTD structure */ - sharpsl->mtd.priv = this; - sharpsl->mtd.dev.parent = &pdev->dev; + mtd = nand_to_mtd(this); + mtd->priv = this; + mtd->dev.parent = &pdev->dev; platform_set_drvdata(pdev, sharpsl); @@ -173,14 +177,14 @@ static int sharpsl_nand_probe(struct platform_device *pdev) this->ecc.correct = nand_correct_data; /* Scan to find existence of the device */ - err = nand_scan(&sharpsl->mtd, 1); + err = nand_scan(mtd, 1); if (err) goto err_scan; /* Register the partitions */ - sharpsl->mtd.name = "sharpsl-nand"; + mtd->name = "sharpsl-nand"; - err = mtd_device_parse_register(&sharpsl->mtd, NULL, NULL, + err = mtd_device_parse_register(mtd, NULL, NULL, data->partitions, data->nr_partitions); if (err) goto err_add; @@ -189,7 +193,7 @@ static int sharpsl_nand_probe(struct platform_device *pdev) return 0; err_add: - nand_release(&sharpsl->mtd); + nand_release(mtd); err_scan: iounmap(sharpsl->io); @@ -207,7 +211,7 @@ static int sharpsl_nand_remove(struct platform_device *pdev) struct sharpsl_nand *sharpsl = platform_get_drvdata(pdev); /* Release resources, unregister device */ - nand_release(&sharpsl->mtd); + nand_release(nand_to_mtd(&sharpsl->chip)); iounmap(sharpsl->io); -- GitLab From 32e9f2d8dd83f30019915f8393a470b3ff3fadbe Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:26 +0100 Subject: [PATCH 1547/2855] mtd: nand: sunxi: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/sunxi_nand.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index 4ecd486011822..c29d659a747a4 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c @@ -234,7 +234,6 @@ struct sunxi_nand_hw_ecc { struct sunxi_nand_chip { struct list_head node; struct nand_chip nand; - struct mtd_info mtd; unsigned long clk_rate; u32 timing_cfg; u32 timing_ctl; @@ -991,6 +990,7 @@ static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip, static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip, struct device_node *np) { + struct mtd_info *mtd = nand_to_mtd(&chip->nand); const struct nand_sdr_timings *timings; int ret; int mode; @@ -1008,12 +1008,11 @@ static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip, feature[0] = mode; for (i = 0; i < chip->nsels; i++) { - chip->nand.select_chip(&chip->mtd, i); - ret = chip->nand.onfi_set_features(&chip->mtd, - &chip->nand, + chip->nand.select_chip(mtd, i); + ret = chip->nand.onfi_set_features(mtd, &chip->nand, ONFI_FEATURE_ADDR_TIMING_MODE, feature); - chip->nand.select_chip(&chip->mtd, -1); + chip->nand.select_chip(mtd, -1); if (ret) return ret; } @@ -1336,7 +1335,7 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc, nand->write_buf = sunxi_nfc_write_buf; nand->read_byte = sunxi_nfc_read_byte; - mtd = &chip->mtd; + mtd = nand_to_mtd(nand); mtd->dev.parent = dev; mtd->priv = nand; @@ -1407,7 +1406,7 @@ static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc) while (!list_empty(&nfc->chips)) { chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip, node); - nand_release(&chip->mtd); + nand_release(nand_to_mtd(&chip->nand)); sunxi_nand_ecc_cleanup(&chip->nand.ecc); list_del(&chip->node); } -- GitLab From 66c9595d499e9a10bee27bf4026d91452cc78568 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:27 +0100 Subject: [PATCH 1548/2855] mtd: nand: tmio: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/tmio_nand.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c index 6d0cbe90b1b2d..e7b82e11c7958 100644 --- a/drivers/mtd/nand/tmio_nand.c +++ b/drivers/mtd/nand/tmio_nand.c @@ -103,7 +103,6 @@ /*--------------------------------------------------------------------------*/ struct tmio_nand { - struct mtd_info mtd; struct nand_chip chip; struct platform_device *dev; @@ -119,7 +118,10 @@ struct tmio_nand { unsigned read_good:1; }; -#define mtd_to_tmio(m) container_of(m, struct tmio_nand, mtd) +static inline struct tmio_nand *mtd_to_tmio(struct mtd_info *mtd) +{ + return container_of(mtd_to_nand(mtd), struct tmio_nand, chip); +} /*--------------------------------------------------------------------------*/ @@ -378,8 +380,8 @@ static int tmio_probe(struct platform_device *dev) tmio->dev = dev; platform_set_drvdata(dev, tmio); - mtd = &tmio->mtd; nand_chip = &tmio->chip; + mtd = nand_to_mtd(nand_chip); mtd->priv = nand_chip; mtd->name = "tmio-nand"; mtd->dev.parent = &dev->dev; @@ -456,7 +458,7 @@ static int tmio_remove(struct platform_device *dev) { struct tmio_nand *tmio = platform_get_drvdata(dev); - nand_release(&tmio->mtd); + nand_release(nand_to_mtd(&tmio->chip)); tmio_hw_stop(dev, tmio); return 0; } -- GitLab From a3f5437788fde26f9354324cb711461bdc02c6e0 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:28 +0100 Subject: [PATCH 1549/2855] mtd: nand: txx9ndfmc: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/txx9ndfmc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c index ff9afb1eb3adb..da7fcbd37f3a1 100644 --- a/drivers/mtd/nand/txx9ndfmc.c +++ b/drivers/mtd/nand/txx9ndfmc.c @@ -63,7 +63,6 @@ struct txx9ndfmc_priv { struct platform_device *dev; struct nand_chip chip; - struct mtd_info mtd; int cs; const char *mtdname; }; @@ -322,7 +321,7 @@ static int __init txx9ndfmc_probe(struct platform_device *dev) if (!txx9_priv) continue; chip = &txx9_priv->chip; - mtd = &txx9_priv->mtd; + mtd = nand_to_mtd(chip); mtd->dev.parent = &dev->dev; mtd->priv = chip; -- GitLab From 960823a226b37eea01151d608636d09d1abac8f9 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:29 +0100 Subject: [PATCH 1550/2855] mtd: nand: vf610: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/vf610_nfc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c index 1c86c6b42515a..1bbb93a7b4e5f 100644 --- a/drivers/mtd/nand/vf610_nfc.c +++ b/drivers/mtd/nand/vf610_nfc.c @@ -156,7 +156,6 @@ enum vf610_nfc_variant { }; struct vf610_nfc { - struct mtd_info mtd; struct nand_chip chip; struct device *dev; void __iomem *regs; @@ -171,7 +170,10 @@ struct vf610_nfc { u32 ecc_mode; }; -#define mtd_to_nfc(_mtd) container_of(_mtd, struct vf610_nfc, mtd) +static inline struct vf610_nfc *mtd_to_nfc(struct mtd_info *mtd) +{ + return container_of(mtd_to_nand(mtd), struct vf610_nfc, chip); +} static struct nand_ecclayout vf610_nfc_ecc45 = { .eccbytes = 45, @@ -674,8 +676,8 @@ static int vf610_nfc_probe(struct platform_device *pdev) return -ENOMEM; nfc->dev = &pdev->dev; - mtd = &nfc->mtd; chip = &nfc->chip; + mtd = nand_to_mtd(chip); mtd->priv = chip; mtd->owner = THIS_MODULE; -- GitLab From 3eb064e4b0f423810562b8a7aef3ca0083152e90 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:30 +0100 Subject: [PATCH 1551/2855] mtd: nand: update the documentation to reflect framework changes The MTD device is now directly embedded in the nand_chip struct. Update the mtdnand documentation to mention this aspect and fix the different examples. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- Documentation/DocBook/mtdnand.tmpl | 31 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl index 403a7abfc2bca..b442921bca540 100644 --- a/Documentation/DocBook/mtdnand.tmpl +++ b/Documentation/DocBook/mtdnand.tmpl @@ -162,12 +162,15 @@ Basic defines - At least you have to provide a mtd structure and - a storage for the ioremap'ed chip address. - You can allocate the mtd structure using kmalloc - or you can allocate it statically. - In case of static allocation you have to allocate - a nand_chip structure too. + At least you have to provide a nand_chip structure + and a storage for the ioremap'ed chip address. + You can allocate the nand_chip structure using + kmalloc or you can allocate it statically. + The NAND chip structure embeds an mtd structure + which will be registered to the MTD subsystem. + You can extract a pointer to the mtd structure + from a nand_chip pointer using the nand_to_mtd() + helper. Kmalloc based example @@ -180,7 +183,6 @@ static void __iomem *baseaddr; Static example -static struct mtd_info board_mtd; static struct nand_chip board_chip; static void __iomem *baseaddr; @@ -274,13 +276,15 @@ static int __init board_init (void) int err = 0; /* Allocate memory for MTD device structure and private data */ - board_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); - if (!board_mtd) { + this = kzalloc(sizeof(struct nand_chip), GFP_KERNEL); + if (!this) { printk ("Unable to allocate NAND MTD device structure.\n"); err = -ENOMEM; goto out; } + board_mtd = nand_to_mtd(this); + /* map physical address */ baseaddr = ioremap(CHIP_PHYSICAL_ADDRESS, 1024); if (!baseaddr) { @@ -289,11 +293,6 @@ static int __init board_init (void) goto out_mtd; } - /* Get pointer to private data */ - this = (struct nand_chip *) (); - /* Link the private data with the MTD structure */ - board_mtd->priv = this; - /* Set address of NAND IO lines */ this->IO_ADDR_R = baseaddr; this->IO_ADDR_W = baseaddr; @@ -317,7 +316,7 @@ static int __init board_init (void) out_ior: iounmap(baseaddr); out_mtd: - kfree (board_mtd); + kfree (this); out: return err; } @@ -343,7 +342,7 @@ static void __exit board_cleanup (void) iounmap(baseaddr); /* Free the MTD device structure */ - kfree (board_mtd); + kfree (mtd_to_nand(board_mtd)); } module_exit(board_cleanup); #endif -- GitLab From 7208b997b726522cdbea61f53a82c763704c015a Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:22 +0100 Subject: [PATCH 1552/2855] mtd: nand: s3c2410: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Reviewed-by: Krzysztof Kozlowski Signed-off-by: Brian Norris --- drivers/mtd/nand/s3c2410.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index e658b2988acfd..c074a491d087f 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -104,7 +104,6 @@ struct s3c2410_nand_info; * @scan_res: The result from calling nand_scan_ident(). */ struct s3c2410_nand_mtd { - struct mtd_info mtd; struct nand_chip chip; struct s3c2410_nand_set *set; struct s3c2410_nand_info *info; @@ -168,7 +167,8 @@ struct s3c2410_nand_info { static struct s3c2410_nand_mtd *s3c2410_nand_mtd_toours(struct mtd_info *mtd) { - return container_of(mtd, struct s3c2410_nand_mtd, mtd); + return container_of(mtd_to_nand(mtd), struct s3c2410_nand_mtd, + chip); } static struct s3c2410_nand_info *s3c2410_nand_mtd_toinfo(struct mtd_info *mtd) @@ -745,7 +745,7 @@ static int s3c24xx_nand_remove(struct platform_device *pdev) for (mtdno = 0; mtdno < info->mtd_count; mtdno++, ptr++) { pr_debug("releasing mtd %d (%p)\n", mtdno, ptr); - nand_release(&ptr->mtd); + nand_release(nand_to_mtd(&ptr->chip)); } } @@ -762,9 +762,11 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, struct s3c2410_nand_set *set) { if (set) { - mtd->mtd.name = set->name; + struct mtd_info *mtdinfo = nand_to_mtd(&mtd->chip); - return mtd_device_parse_register(&mtd->mtd, NULL, NULL, + mtdinfo->name = set->name; + + return mtd_device_parse_register(mtdinfo, NULL, NULL, set->partitions, set->nr_partitions); } @@ -786,6 +788,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, struct s3c2410_nand_set *set) { struct nand_chip *chip = &nmtd->chip; + struct mtd_info *mtd = nand_to_mtd(chip); void __iomem *regs = info->regs; chip->write_buf = s3c2410_nand_write_buf; @@ -831,7 +834,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, chip->IO_ADDR_R = chip->IO_ADDR_W; nmtd->info = info; - nmtd->mtd.priv = chip; + mtd->priv = chip; nmtd->set = set; #ifdef CONFIG_MTD_NAND_S3C2410_HWECC @@ -1012,19 +1015,21 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) nmtd = info->mtds; for (setno = 0; setno < nr_sets; setno++, nmtd++) { + struct mtd_info *mtd = nand_to_mtd(&nmtd->chip); + pr_debug("initialising set %d (%p, info %p)\n", setno, nmtd, info); - nmtd->mtd.dev.parent = &pdev->dev; + mtd->dev.parent = &pdev->dev; s3c2410_nand_init_chip(info, nmtd, sets); - nmtd->scan_res = nand_scan_ident(&nmtd->mtd, + nmtd->scan_res = nand_scan_ident(mtd, (sets) ? sets->nr_chips : 1, NULL); if (nmtd->scan_res == 0) { s3c2410_nand_update_chip(info, nmtd); - nand_scan_tail(&nmtd->mtd); + nand_scan_tail(mtd); s3c2410_nand_add_partition(info, nmtd, sets); } -- GitLab From 38b95bcf122545db7035a06d79ec9e851be2e011 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 5 Nov 2015 11:37:08 +0300 Subject: [PATCH 1553/2855] xprtrdma: clean up some curly braces It doesn't matter either way, but the curly braces were clearly intended here. It causes a Smatch warning. Signed-off-by: Dan Carpenter Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/verbs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index eadd1655145a3..2cc101410a768 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -852,10 +852,11 @@ retry: if (extras) { rc = rpcrdma_ep_post_extra_recv(r_xprt, extras); - if (rc) + if (rc) { pr_warn("%s: rpcrdma_ep_post_extra_recv: %i\n", __func__, rc); rc = 0; + } } } -- GitLab From abfb689711aaebd14d893236c6ea4bcdfb61e74c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 5 Nov 2015 11:39:52 +0300 Subject: [PATCH 1554/2855] xprtrdma: checking for NULL instead of IS_ERR() The rpcrdma_create_req() function returns error pointers or success. It never returns NULL. Fixes: f531a5dbc451 ('xprtrdma: Pre-allocate backward rpc_rqst and send/receive buffers') Signed-off-by: Dan Carpenter Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/backchannel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/xprtrdma/backchannel.c b/net/sunrpc/xprtrdma/backchannel.c index 2dcb44f69e539..97554ca681915 100644 --- a/net/sunrpc/xprtrdma/backchannel.c +++ b/net/sunrpc/xprtrdma/backchannel.c @@ -42,8 +42,8 @@ static int rpcrdma_bc_setup_rqst(struct rpcrdma_xprt *r_xprt, size_t size; req = rpcrdma_create_req(r_xprt); - if (!req) - return -ENOMEM; + if (IS_ERR(req)) + return PTR_ERR(req); req->rl_backchannel = true; size = RPCRDMA_INLINE_WRITE_THRESHOLD(rqst); -- GitLab From 9b06688bc3b9f13f8de90f832c455fddec3d4e8a Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 16 Dec 2015 17:22:06 -0500 Subject: [PATCH 1555/2855] xprtrdma: Fix additional uses of spin_lock_irqsave(rb_lock) Clean up. rb_lock critical sections added in rpcrdma_ep_post_extra_recv() should have first been converted to use normal spin_lock now that the reply handler is a work queue. The backchannel set up code should use the appropriate helper instead of open-coding a rb_recv_bufs list add. Problem introduced by glib patch re-ordering on my part. Fixes: f531a5dbc451 ('xprtrdma: Pre-allocate backward rpc_rqst') Signed-off-by: Chuck Lever Tested-by: Devesh Sharma Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/backchannel.c | 6 +----- net/sunrpc/xprtrdma/verbs.c | 7 +++---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/net/sunrpc/xprtrdma/backchannel.c b/net/sunrpc/xprtrdma/backchannel.c index 97554ca681915..40f48c62f9b1a 100644 --- a/net/sunrpc/xprtrdma/backchannel.c +++ b/net/sunrpc/xprtrdma/backchannel.c @@ -84,9 +84,7 @@ out_fail: static int rpcrdma_bc_setup_reps(struct rpcrdma_xprt *r_xprt, unsigned int count) { - struct rpcrdma_buffer *buffers = &r_xprt->rx_buf; struct rpcrdma_rep *rep; - unsigned long flags; int rc = 0; while (count--) { @@ -98,9 +96,7 @@ static int rpcrdma_bc_setup_reps(struct rpcrdma_xprt *r_xprt, break; } - spin_lock_irqsave(&buffers->rb_lock, flags); - list_add(&rep->rr_list, &buffers->rb_recv_bufs); - spin_unlock_irqrestore(&buffers->rb_lock, flags); + rpcrdma_recv_buffer_put(rep); } return rc; diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 2cc101410a768..003630733ef31 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -1338,15 +1338,14 @@ rpcrdma_ep_post_extra_recv(struct rpcrdma_xprt *r_xprt, unsigned int count) struct rpcrdma_ia *ia = &r_xprt->rx_ia; struct rpcrdma_ep *ep = &r_xprt->rx_ep; struct rpcrdma_rep *rep; - unsigned long flags; int rc; while (count--) { - spin_lock_irqsave(&buffers->rb_lock, flags); + spin_lock(&buffers->rb_lock); if (list_empty(&buffers->rb_recv_bufs)) goto out_reqbuf; rep = rpcrdma_buffer_get_rep_locked(buffers); - spin_unlock_irqrestore(&buffers->rb_lock, flags); + spin_unlock(&buffers->rb_lock); rc = rpcrdma_ep_post_recv(ia, ep, rep); if (rc) @@ -1356,7 +1355,7 @@ rpcrdma_ep_post_extra_recv(struct rpcrdma_xprt *r_xprt, unsigned int count) return 0; out_reqbuf: - spin_unlock_irqrestore(&buffers->rb_lock, flags); + spin_unlock(&buffers->rb_lock); pr_warn("%s: no extra receive buffers\n", __func__); return -ENOMEM; -- GitLab From ffc4d9b1596c34caa98962722e930e97912c8a9f Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 16 Dec 2015 17:22:14 -0500 Subject: [PATCH 1556/2855] xprtrdma: xprt_rdma_free() must not release backchannel reqs Preserve any rpcrdma_req that is attached to rpc_rqst's allocated for the backchannel. Otherwise, after all the pre-allocated backchannel req's are consumed, incoming backward calls start writing on freed memory. Somehow this hunk got lost. Fixes: f531a5dbc451 ('xprtrdma: Pre-allocate backward rpc_rqst') Signed-off-by: Chuck Lever Tested-by: Devesh Sharma Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/transport.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 8c545f7d75257..740bddcf3488f 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c @@ -576,6 +576,9 @@ xprt_rdma_free(void *buffer) rb = container_of(buffer, struct rpcrdma_regbuf, rg_base[0]); req = rb->rg_owner; + if (req->rl_backchannel) + return; + r_xprt = container_of(req->rl_buffer, struct rpcrdma_xprt, rx_buf); dprintk("RPC: %s: called on 0x%p\n", __func__, req->rl_reply); -- GitLab From c8bbe0c7fec3a6fd01d445eea11e72e902403ea9 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 16 Dec 2015 17:22:23 -0500 Subject: [PATCH 1557/2855] xprtrdma: Disable RPC/RDMA backchannel debugging messages Clean up. Fixes: 63cae47005af ('xprtrdma: Handle incoming backward direction') Signed-off-by: Chuck Lever Tested-by: Devesh Sharma Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/backchannel.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/net/sunrpc/xprtrdma/backchannel.c b/net/sunrpc/xprtrdma/backchannel.c index 40f48c62f9b1a..cc1251d072970 100644 --- a/net/sunrpc/xprtrdma/backchannel.c +++ b/net/sunrpc/xprtrdma/backchannel.c @@ -15,7 +15,7 @@ # define RPCDBG_FACILITY RPCDBG_TRANS #endif -#define RPCRDMA_BACKCHANNEL_DEBUG +#undef RPCRDMA_BACKCHANNEL_DEBUG static void rpcrdma_bc_free_rqst(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst) @@ -136,6 +136,7 @@ int xprt_rdma_bc_setup(struct rpc_xprt *xprt, unsigned int reqs) __func__); goto out_free; } + dprintk("RPC: %s: new rqst %p\n", __func__, rqst); rqst->rq_xprt = &r_xprt->rx_xprt; INIT_LIST_HEAD(&rqst->rq_list); @@ -216,12 +217,14 @@ int rpcrdma_bc_marshal_reply(struct rpc_rqst *rqst) rpclen = rqst->rq_svec[0].iov_len; +#ifdef RPCRDMA_BACKCHANNEL_DEBUG pr_info("RPC: %s: rpclen %zd headerp 0x%p lkey 0x%x\n", __func__, rpclen, headerp, rdmab_lkey(req->rl_rdmabuf)); pr_info("RPC: %s: RPC/RDMA: %*ph\n", __func__, (int)RPCRDMA_HDRLEN_MIN, headerp); pr_info("RPC: %s: RPC: %*ph\n", __func__, (int)rpclen, rqst->rq_svec[0].iov_base); +#endif req->rl_send_iov[0].addr = rdmab_addr(req->rl_rdmabuf); req->rl_send_iov[0].length = RPCRDMA_HDRLEN_MIN; @@ -265,6 +268,9 @@ void xprt_rdma_bc_free_rqst(struct rpc_rqst *rqst) { struct rpc_xprt *xprt = rqst->rq_xprt; + dprintk("RPC: %s: freeing rqst %p (req %p)\n", + __func__, rqst, rpcr_to_rdmar(rqst)); + smp_mb__before_atomic(); WARN_ON_ONCE(!test_bit(RPC_BC_PA_IN_USE, &rqst->rq_bc_pa_state)); clear_bit(RPC_BC_PA_IN_USE, &rqst->rq_bc_pa_state); @@ -329,9 +335,7 @@ void rpcrdma_bc_receive_call(struct rpcrdma_xprt *r_xprt, struct rpc_rqst, rq_bc_pa_list); list_del(&rqst->rq_bc_pa_list); spin_unlock(&xprt->bc_pa_lock); -#ifdef RPCRDMA_BACKCHANNEL_DEBUG - pr_info("RPC: %s: using rqst %p\n", __func__, rqst); -#endif + dprintk("RPC: %s: using rqst %p\n", __func__, rqst); /* Prepare rqst */ rqst->rq_reply_bytes_recvd = 0; @@ -351,10 +355,8 @@ void rpcrdma_bc_receive_call(struct rpcrdma_xprt *r_xprt, * direction reply. */ req = rpcr_to_rdmar(rqst); -#ifdef RPCRDMA_BACKCHANNEL_DEBUG - pr_info("RPC: %s: attaching rep %p to req %p\n", + dprintk("RPC: %s: attaching rep %p to req %p\n", __func__, rep, req); -#endif req->rl_reply = rep; /* Defeat the retransmit detection logic in send_request */ -- GitLab From 3cf4e169be95e1a3a70a063b6bd8103fbd5911f3 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 16 Dec 2015 17:22:31 -0500 Subject: [PATCH 1558/2855] xprtrdma: Move struct ib_send_wr off the stack For FRWR FASTREG and LOCAL_INV, move the ib_*_wr structure off the stack. This allows frwr_op_map and frwr_op_unmap to chain WRs together without limit to register or invalidate a set of MRs with a single ib_post_send(). (This will be for chaining LOCAL_INV requests). Signed-off-by: Chuck Lever Tested-by: Devesh Sharma Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/frwr_ops.c | 38 +++++++++++++++++---------------- net/sunrpc/xprtrdma/xprt_rdma.h | 4 ++++ 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c index 88cf9e7269c2b..31a45786137b4 100644 --- a/net/sunrpc/xprtrdma/frwr_ops.c +++ b/net/sunrpc/xprtrdma/frwr_ops.c @@ -319,7 +319,7 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, struct rpcrdma_mw *mw; struct rpcrdma_frmr *frmr; struct ib_mr *mr; - struct ib_reg_wr reg_wr; + struct ib_reg_wr *reg_wr; struct ib_send_wr *bad_wr; int rc, i, n, dma_nents; u8 key; @@ -336,6 +336,7 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, frmr = &mw->r.frmr; frmr->fr_state = FRMR_IS_VALID; mr = frmr->fr_mr; + reg_wr = &frmr->fr_regwr; if (nsegs > ia->ri_max_frmr_depth) nsegs = ia->ri_max_frmr_depth; @@ -381,19 +382,19 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, key = (u8)(mr->rkey & 0x000000FF); ib_update_fast_reg_key(mr, ++key); - reg_wr.wr.next = NULL; - reg_wr.wr.opcode = IB_WR_REG_MR; - reg_wr.wr.wr_id = (uintptr_t)mw; - reg_wr.wr.num_sge = 0; - reg_wr.wr.send_flags = 0; - reg_wr.mr = mr; - reg_wr.key = mr->rkey; - reg_wr.access = writing ? - IB_ACCESS_REMOTE_WRITE | IB_ACCESS_LOCAL_WRITE : - IB_ACCESS_REMOTE_READ; + reg_wr->wr.next = NULL; + reg_wr->wr.opcode = IB_WR_REG_MR; + reg_wr->wr.wr_id = (uintptr_t)mw; + reg_wr->wr.num_sge = 0; + reg_wr->wr.send_flags = 0; + reg_wr->mr = mr; + reg_wr->key = mr->rkey; + reg_wr->access = writing ? + IB_ACCESS_REMOTE_WRITE | IB_ACCESS_LOCAL_WRITE : + IB_ACCESS_REMOTE_READ; DECR_CQCOUNT(&r_xprt->rx_ep); - rc = ib_post_send(ia->ri_id->qp, ®_wr.wr, &bad_wr); + rc = ib_post_send(ia->ri_id->qp, ®_wr->wr, &bad_wr); if (rc) goto out_senderr; @@ -423,23 +424,24 @@ frwr_op_unmap(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg) struct rpcrdma_ia *ia = &r_xprt->rx_ia; struct rpcrdma_mw *mw = seg1->rl_mw; struct rpcrdma_frmr *frmr = &mw->r.frmr; - struct ib_send_wr invalidate_wr, *bad_wr; + struct ib_send_wr *invalidate_wr, *bad_wr; int rc, nsegs = seg->mr_nsegs; dprintk("RPC: %s: FRMR %p\n", __func__, mw); seg1->rl_mw = NULL; frmr->fr_state = FRMR_IS_INVALID; + invalidate_wr = &mw->r.frmr.fr_invwr; - memset(&invalidate_wr, 0, sizeof(invalidate_wr)); - invalidate_wr.wr_id = (unsigned long)(void *)mw; - invalidate_wr.opcode = IB_WR_LOCAL_INV; - invalidate_wr.ex.invalidate_rkey = frmr->fr_mr->rkey; + memset(invalidate_wr, 0, sizeof(*invalidate_wr)); + invalidate_wr->wr_id = (uintptr_t)mw; + invalidate_wr->opcode = IB_WR_LOCAL_INV; + invalidate_wr->ex.invalidate_rkey = frmr->fr_mr->rkey; DECR_CQCOUNT(&r_xprt->rx_ep); ib_dma_unmap_sg(ia->ri_device, frmr->sg, frmr->sg_nents, seg1->mr_dir); read_lock(&ia->ri_qplock); - rc = ib_post_send(ia->ri_id->qp, &invalidate_wr, &bad_wr); + rc = ib_post_send(ia->ri_id->qp, invalidate_wr, &bad_wr); read_unlock(&ia->ri_qplock); if (rc) goto out_err; diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index ac7f8d4f632a9..5c1e0c600faf0 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h @@ -207,6 +207,10 @@ struct rpcrdma_frmr { enum rpcrdma_frmr_state fr_state; struct work_struct fr_work; struct rpcrdma_xprt *fr_xprt; + union { + struct ib_reg_wr fr_regwr; + struct ib_send_wr fr_invwr; + }; }; struct rpcrdma_fmr { -- GitLab From 32d0ceecdfd0e941c492390fe5b6237cc1cf9fa6 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 16 Dec 2015 17:22:39 -0500 Subject: [PATCH 1559/2855] xprtrdma: Introduce ro_unmap_sync method In the current xprtrdma implementation, some memreg strategies implement ro_unmap synchronously (the MR is knocked down before the method returns) and some asynchonously (the MR will be knocked down and returned to the pool in the background). To guarantee the MR is truly invalid before the RPC consumer is allowed to resume execution, we need an unmap method that is always synchronous, invoked from the RPC/RDMA reply handler. The new method unmaps all MRs for an RPC. The existing ro_unmap method unmaps only one MR at a time. Signed-off-by: Chuck Lever Tested-by: Devesh Sharma Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/xprt_rdma.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index 5c1e0c600faf0..c32cba3f21fbf 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h @@ -368,6 +368,8 @@ struct rpcrdma_xprt; struct rpcrdma_memreg_ops { int (*ro_map)(struct rpcrdma_xprt *, struct rpcrdma_mr_seg *, int, bool); + void (*ro_unmap_sync)(struct rpcrdma_xprt *, + struct rpcrdma_req *); int (*ro_unmap)(struct rpcrdma_xprt *, struct rpcrdma_mr_seg *); int (*ro_open)(struct rpcrdma_ia *, -- GitLab From c9918ff56dfb175ce427140c641280d0b4522dbe Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 16 Dec 2015 17:22:47 -0500 Subject: [PATCH 1560/2855] xprtrdma: Add ro_unmap_sync method for FRWR FRWR's ro_unmap is asynchronous. The new ro_unmap_sync posts LOCAL_INV Work Requests and waits for them to complete before returning. Note also, DMA unmapping is now done _after_ invalidation. Signed-off-by: Chuck Lever Tested-by: Devesh Sharma Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/frwr_ops.c | 136 +++++++++++++++++++++++++++++++- net/sunrpc/xprtrdma/xprt_rdma.h | 2 + 2 files changed, 134 insertions(+), 4 deletions(-) diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c index 31a45786137b4..c6836844bd0eb 100644 --- a/net/sunrpc/xprtrdma/frwr_ops.c +++ b/net/sunrpc/xprtrdma/frwr_ops.c @@ -245,12 +245,14 @@ frwr_op_maxpages(struct rpcrdma_xprt *r_xprt) rpcrdma_max_segments(r_xprt) * ia->ri_max_frmr_depth); } -/* If FAST_REG or LOCAL_INV failed, indicate the frmr needs to be reset. */ +/* If FAST_REG or LOCAL_INV failed, indicate the frmr needs + * to be reset. + * + * WARNING: Only wr_id and status are reliable at this point + */ static void -frwr_sendcompletion(struct ib_wc *wc) +__frwr_sendcompletion_flush(struct ib_wc *wc, struct rpcrdma_mw *r) { - struct rpcrdma_mw *r; - if (likely(wc->status == IB_WC_SUCCESS)) return; @@ -261,9 +263,23 @@ frwr_sendcompletion(struct ib_wc *wc) else pr_warn("RPC: %s: frmr %p error, status %s (%d)\n", __func__, r, ib_wc_status_msg(wc->status), wc->status); + r->r.frmr.fr_state = FRMR_IS_STALE; } +static void +frwr_sendcompletion(struct ib_wc *wc) +{ + struct rpcrdma_mw *r = (struct rpcrdma_mw *)(unsigned long)wc->wr_id; + struct rpcrdma_frmr *f = &r->r.frmr; + + if (unlikely(wc->status != IB_WC_SUCCESS)) + __frwr_sendcompletion_flush(wc, r); + + if (f->fr_waiter) + complete(&f->fr_linv_done); +} + static int frwr_op_init(struct rpcrdma_xprt *r_xprt) { @@ -335,6 +351,7 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, } while (mw->r.frmr.fr_state != FRMR_IS_INVALID); frmr = &mw->r.frmr; frmr->fr_state = FRMR_IS_VALID; + frmr->fr_waiter = false; mr = frmr->fr_mr; reg_wr = &frmr->fr_regwr; @@ -414,6 +431,116 @@ out_senderr: return rc; } +static struct ib_send_wr * +__frwr_prepare_linv_wr(struct rpcrdma_mr_seg *seg) +{ + struct rpcrdma_mw *mw = seg->rl_mw; + struct rpcrdma_frmr *f = &mw->r.frmr; + struct ib_send_wr *invalidate_wr; + + f->fr_waiter = false; + f->fr_state = FRMR_IS_INVALID; + invalidate_wr = &f->fr_invwr; + + memset(invalidate_wr, 0, sizeof(*invalidate_wr)); + invalidate_wr->wr_id = (unsigned long)(void *)mw; + invalidate_wr->opcode = IB_WR_LOCAL_INV; + invalidate_wr->ex.invalidate_rkey = f->fr_mr->rkey; + + return invalidate_wr; +} + +static void +__frwr_dma_unmap(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, + int rc) +{ + struct ib_device *device = r_xprt->rx_ia.ri_device; + struct rpcrdma_mw *mw = seg->rl_mw; + struct rpcrdma_frmr *f = &mw->r.frmr; + + seg->rl_mw = NULL; + + ib_dma_unmap_sg(device, f->sg, f->sg_nents, seg->mr_dir); + + if (!rc) + rpcrdma_put_mw(r_xprt, mw); + else + __frwr_queue_recovery(mw); +} + +/* Invalidate all memory regions that were registered for "req". + * + * Sleeps until it is safe for the host CPU to access the + * previously mapped memory regions. + */ +static void +frwr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) +{ + struct ib_send_wr *invalidate_wrs, *pos, *prev, *bad_wr; + struct rpcrdma_ia *ia = &r_xprt->rx_ia; + struct rpcrdma_mr_seg *seg; + unsigned int i, nchunks; + struct rpcrdma_frmr *f; + int rc; + + dprintk("RPC: %s: req %p\n", __func__, req); + + /* ORDER: Invalidate all of the req's MRs first + * + * Chain the LOCAL_INV Work Requests and post them with + * a single ib_post_send() call. + */ + invalidate_wrs = pos = prev = NULL; + seg = NULL; + for (i = 0, nchunks = req->rl_nchunks; nchunks; nchunks--) { + seg = &req->rl_segments[i]; + + pos = __frwr_prepare_linv_wr(seg); + + if (!invalidate_wrs) + invalidate_wrs = pos; + else + prev->next = pos; + prev = pos; + + i += seg->mr_nsegs; + } + f = &seg->rl_mw->r.frmr; + + /* Strong send queue ordering guarantees that when the + * last WR in the chain completes, all WRs in the chain + * are complete. + */ + f->fr_invwr.send_flags = IB_SEND_SIGNALED; + f->fr_waiter = true; + init_completion(&f->fr_linv_done); + INIT_CQCOUNT(&r_xprt->rx_ep); + + /* Transport disconnect drains the receive CQ before it + * replaces the QP. The RPC reply handler won't call us + * unless ri_id->qp is a valid pointer. + */ + rc = ib_post_send(ia->ri_id->qp, invalidate_wrs, &bad_wr); + if (rc) + pr_warn("%s: ib_post_send failed %i\n", __func__, rc); + + wait_for_completion(&f->fr_linv_done); + + /* ORDER: Now DMA unmap all of the req's MRs, and return + * them to the free MW list. + */ + for (i = 0, nchunks = req->rl_nchunks; nchunks; nchunks--) { + seg = &req->rl_segments[i]; + + __frwr_dma_unmap(r_xprt, seg, rc); + + i += seg->mr_nsegs; + seg->mr_nsegs = 0; + } + + req->rl_nchunks = 0; +} + /* Post a LOCAL_INV Work Request to prevent further remote access * via RDMA READ or RDMA WRITE. */ @@ -473,6 +600,7 @@ frwr_op_destroy(struct rpcrdma_buffer *buf) const struct rpcrdma_memreg_ops rpcrdma_frwr_memreg_ops = { .ro_map = frwr_op_map, + .ro_unmap_sync = frwr_op_unmap_sync, .ro_unmap = frwr_op_unmap, .ro_open = frwr_op_open, .ro_maxpages = frwr_op_maxpages, diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index c32cba3f21fbf..ddae4909982bf 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h @@ -207,6 +207,8 @@ struct rpcrdma_frmr { enum rpcrdma_frmr_state fr_state; struct work_struct fr_work; struct rpcrdma_xprt *fr_xprt; + bool fr_waiter; + struct completion fr_linv_done;; union { struct ib_reg_wr fr_regwr; struct ib_send_wr fr_invwr; -- GitLab From 7c7a5390dc6c8d89fc368424b69a4eef8e43f411 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 16 Dec 2015 17:22:55 -0500 Subject: [PATCH 1561/2855] xprtrdma: Add ro_unmap_sync method for FMR FMR's ro_unmap method is already synchronous because ib_unmap_fmr() is a synchronous verb. However, some improvements can be made here. 1. Gather all the MRs for the RPC request onto a list, and invoke ib_unmap_fmr() once with that list. This reduces the number of doorbells when there is more than one MR to invalidate 2. Perform the DMA unmap _after_ the MRs are unmapped, not before. This is critical after invalidating a Write chunk. Signed-off-by: Chuck Lever Tested-by: Devesh Sharma Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/fmr_ops.c | 64 +++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/net/sunrpc/xprtrdma/fmr_ops.c b/net/sunrpc/xprtrdma/fmr_ops.c index f1e8dafbd5079..c14f3a4bff682 100644 --- a/net/sunrpc/xprtrdma/fmr_ops.c +++ b/net/sunrpc/xprtrdma/fmr_ops.c @@ -179,6 +179,69 @@ out_maperr: return rc; } +static void +__fmr_dma_unmap(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg) +{ + struct ib_device *device = r_xprt->rx_ia.ri_device; + struct rpcrdma_mw *mw = seg->rl_mw; + int nsegs = seg->mr_nsegs; + + seg->rl_mw = NULL; + + while (nsegs--) + rpcrdma_unmap_one(device, seg++); + + rpcrdma_put_mw(r_xprt, mw); +} + +/* Invalidate all memory regions that were registered for "req". + * + * Sleeps until it is safe for the host CPU to access the + * previously mapped memory regions. + */ +static void +fmr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) +{ + struct rpcrdma_mr_seg *seg; + unsigned int i, nchunks; + struct rpcrdma_mw *mw; + LIST_HEAD(unmap_list); + int rc; + + dprintk("RPC: %s: req %p\n", __func__, req); + + /* ORDER: Invalidate all of the req's MRs first + * + * ib_unmap_fmr() is slow, so use a single call instead + * of one call per mapped MR. + */ + for (i = 0, nchunks = req->rl_nchunks; nchunks; nchunks--) { + seg = &req->rl_segments[i]; + mw = seg->rl_mw; + + list_add(&mw->r.fmr.fmr->list, &unmap_list); + + i += seg->mr_nsegs; + } + rc = ib_unmap_fmr(&unmap_list); + if (rc) + pr_warn("%s: ib_unmap_fmr failed (%i)\n", __func__, rc); + + /* ORDER: Now DMA unmap all of the req's MRs, and return + * them to the free MW list. + */ + for (i = 0, nchunks = req->rl_nchunks; nchunks; nchunks--) { + seg = &req->rl_segments[i]; + + __fmr_dma_unmap(r_xprt, seg); + + i += seg->mr_nsegs; + seg->mr_nsegs = 0; + } + + req->rl_nchunks = 0; +} + /* Use the ib_unmap_fmr() verb to prevent further remote * access via RDMA READ or RDMA WRITE. */ @@ -231,6 +294,7 @@ fmr_op_destroy(struct rpcrdma_buffer *buf) const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops = { .ro_map = fmr_op_map, + .ro_unmap_sync = fmr_op_unmap_sync, .ro_unmap = fmr_op_unmap, .ro_open = fmr_op_open, .ro_maxpages = fmr_op_maxpages, -- GitLab From 73eee9b2de1fa08f2a82bb32ac4ec5e605716a91 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 16 Dec 2015 17:23:03 -0500 Subject: [PATCH 1562/2855] xprtrdma: Add ro_unmap_sync method for all-physical registration physical's ro_unmap is synchronous already. The new ro_unmap_sync method just has to DMA unmap all MRs associated with the RPC request. Signed-off-by: Chuck Lever Tested-by: Devesh Sharma Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/physical_ops.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/net/sunrpc/xprtrdma/physical_ops.c b/net/sunrpc/xprtrdma/physical_ops.c index 617b76f22154c..dbb302ecf5901 100644 --- a/net/sunrpc/xprtrdma/physical_ops.c +++ b/net/sunrpc/xprtrdma/physical_ops.c @@ -83,6 +83,18 @@ physical_op_unmap(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg) return 1; } +/* DMA unmap all memory regions that were mapped for "req". + */ +static void +physical_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) +{ + struct ib_device *device = r_xprt->rx_ia.ri_device; + unsigned int i; + + for (i = 0; req->rl_nchunks; --req->rl_nchunks) + rpcrdma_unmap_one(device, &req->rl_segments[i++]); +} + static void physical_op_destroy(struct rpcrdma_buffer *buf) { @@ -90,6 +102,7 @@ physical_op_destroy(struct rpcrdma_buffer *buf) const struct rpcrdma_memreg_ops rpcrdma_physical_memreg_ops = { .ro_map = physical_op_map, + .ro_unmap_sync = physical_op_unmap_sync, .ro_unmap = physical_op_unmap, .ro_open = physical_op_open, .ro_maxpages = physical_op_maxpages, -- GitLab From 68791649a725ac58c88b472ea6187853e67b3415 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 16 Dec 2015 17:23:11 -0500 Subject: [PATCH 1563/2855] xprtrdma: Invalidate in the RPC reply handler There is a window between the time the RPC reply handler wakes the waiting RPC task and when xprt_release() invokes ops->buf_free. During this time, memory regions containing the data payload may still be accessed by a broken or malicious server, but the RPC application has already been allowed access to the memory containing the RPC request's data payloads. The server should be fenced from client memory containing RPC data payloads _before_ the RPC application is allowed to continue. This change also more strongly enforces send queue accounting. There is a maximum number of RPC calls allowed to be outstanding. When an RPC/RDMA transport is set up, just enough send queue resources are allocated to handle registration, Send, and invalidation WRs for each those RPCs at the same time. Before, additional RPC calls could be dispatched while invalidation WRs were still consuming send WQEs. When invalidation WRs backed up, dispatching additional RPCs resulted in a send queue overrun. Now, the reply handler prevents RPC dispatch until invalidation is complete. This prevents RPC call dispatch until there are enough send queue resources to proceed. Still to do: If an RPC exits early (say, ^C), the reply handler has no opportunity to perform invalidation. Currently, xprt_rdma_free() still frees remaining RDMA resources, which could deadlock. Additional changes are needed to handle invalidation properly in this case. Reported-by: Jason Gunthorpe Signed-off-by: Chuck Lever Tested-by: Devesh Sharma Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/rpc_rdma.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index c10d9699441c3..0f28f2d743eda 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c @@ -804,6 +804,11 @@ rpcrdma_reply_handler(struct rpcrdma_rep *rep) if (req->rl_reply) goto out_duplicate; + /* Sanity checking has passed. We are now committed + * to complete this transaction. + */ + list_del_init(&rqst->rq_list); + spin_unlock_bh(&xprt->transport_lock); dprintk("RPC: %s: reply 0x%p completes request 0x%p\n" " RPC request 0x%p xid 0x%08x\n", __func__, rep, req, rqst, @@ -888,12 +893,23 @@ badheader: break; } + /* Invalidate and flush the data payloads before waking the + * waiting application. This guarantees the memory region is + * properly fenced from the server before the application + * accesses the data. It also ensures proper send flow + * control: waking the next RPC waits until this RPC has + * relinquished all its Send Queue entries. + */ + if (req->rl_nchunks) + r_xprt->rx_ia.ri_ops->ro_unmap_sync(r_xprt, req); + credits = be32_to_cpu(headerp->rm_credit); if (credits == 0) credits = 1; /* don't deadlock */ else if (credits > r_xprt->rx_buf.rb_max_requests) credits = r_xprt->rx_buf.rb_max_requests; + spin_lock_bh(&xprt->transport_lock); cwnd = xprt->cwnd; xprt->cwnd = credits << RPC_CWNDSHIFT; if (xprt->cwnd > cwnd) -- GitLab From 26ae9d1c5af1b1d669ca1c28fc02bbca3d778d45 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 16 Dec 2015 17:23:20 -0500 Subject: [PATCH 1564/2855] xprtrdma: Revert commit e7104a2a9606 ('xprtrdma: Cap req_cqinit'). The root of the problem was that sends (especially unsignalled FASTREG and LOCAL_INV Work Requests) were not properly flow- controlled, which allowed a send queue overrun. Now that the RPC/RDMA reply handler waits for invalidation to complete, the send queue is properly flow-controlled. Thus this limit is no longer necessary. Signed-off-by: Chuck Lever Tested-by: Devesh Sharma Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/verbs.c | 6 ++---- net/sunrpc/xprtrdma/xprt_rdma.h | 6 ------ 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 003630733ef31..732c71ce5dcab 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -616,10 +616,8 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia, /* set trigger for requesting send completion */ ep->rep_cqinit = ep->rep_attr.cap.max_send_wr/2 - 1; - if (ep->rep_cqinit > RPCRDMA_MAX_UNSIGNALED_SENDS) - ep->rep_cqinit = RPCRDMA_MAX_UNSIGNALED_SENDS; - else if (ep->rep_cqinit <= 2) - ep->rep_cqinit = 0; + if (ep->rep_cqinit <= 2) + ep->rep_cqinit = 0; /* always signal? */ INIT_CQCOUNT(ep); init_waitqueue_head(&ep->rep_connect_wait); INIT_DELAYED_WORK(&ep->rep_connect_worker, rpcrdma_connect_worker); diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index ddae4909982bf..728101ddc44bf 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h @@ -88,12 +88,6 @@ struct rpcrdma_ep { struct delayed_work rep_connect_worker; }; -/* - * Force a signaled SEND Work Request every so often, - * in case the provider needs to do some housekeeping. - */ -#define RPCRDMA_MAX_UNSIGNALED_SENDS (32) - #define INIT_CQCOUNT(ep) atomic_set(&(ep)->rep_cqcount, (ep)->rep_cqinit) #define DECR_CQCOUNT(ep) atomic_sub_return(1, &(ep)->rep_cqcount) -- GitLab From 2d3743944a6b425f3a3795a967499c13e0d8856c Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 18 Dec 2015 11:39:53 -0800 Subject: [PATCH 1565/2855] mtd: nand: docg4: simplify error case Other refactorings have left the 'fail' label much simpler, so it shouldn't have to handle the failed allocation case. This also fixes a -Wshadow warning. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- drivers/mtd/nand/docg4.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c index cb6efadd712eb..24d478d90dcc0 100644 --- a/drivers/mtd/nand/docg4.c +++ b/drivers/mtd/nand/docg4.c @@ -1353,14 +1353,10 @@ static int __init probe_docg4(struct platform_device *pdev) doc->mtd = mtd; return 0; - fail: - if (nand) { - /* re-declarations avoid compiler warning */ - struct docg4_priv *doc = nand->priv; - nand_release(mtd); /* deletes partitions and mtd devices */ - free_bch(doc->bch); - kfree(nand); - } +fail: + nand_release(mtd); /* deletes partitions and mtd devices */ + free_bch(doc->bch); + kfree(nand); fail_unmap: iounmap(virtadr); -- GitLab From ba4ed8605cb09b2cb72bf14499cf4605a0f9eb23 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:31 +0100 Subject: [PATCH 1566/2855] staging: mt29f_spinand: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device, use it instead of allocating a new one. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/staging/mt29f_spinand/mt29f_spinand.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c index 8924a9645a436..8171b741ff86e 100644 --- a/drivers/staging/mt29f_spinand/mt29f_spinand.c +++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c @@ -903,9 +903,7 @@ static int spinand_probe(struct spi_device *spi_nand) chip->options |= NAND_CACHEPRG; chip->select_chip = spinand_select_chip; - mtd = devm_kzalloc(&spi_nand->dev, sizeof(struct mtd_info), GFP_KERNEL); - if (!mtd) - return -ENOMEM; + mtd = nand_to_mtd(chip); dev_set_drvdata(&spi_nand->dev, mtd); -- GitLab From 4883090bedd79c2c5b408976f0f49e7041cbc3cb Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:32 +0100 Subject: [PATCH 1567/2855] cris: nand: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Patch all drivers to make use of this mtd instance instead of using the instance embedded in their private struct or dynamically allocated. Signed-off-by: Boris Brezillon Acked-by: Jesper Nilsson Signed-off-by: Brian Norris --- arch/cris/arch-v32/drivers/mach-a3/nandflash.c | 3 +-- arch/cris/arch-v32/drivers/mach-fs/nandflash.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c index db953cfabee11..ee74e45a5cf4d 100644 --- a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c +++ b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c @@ -36,7 +36,6 @@ #define CE_BIT 12 struct mtd_info_wrapper { - struct mtd_info info; struct nand_chip chip; }; @@ -148,7 +147,7 @@ struct mtd_info *__init crisv32_nand_flash_probe(void) /* Get pointer to private data */ this = &wrapper->chip; - crisv32_mtd = &wrapper->info; + crisv32_mtd = nand_to_mtd(this); /* Link the private data with the MTD structure */ crisv32_mtd->priv = this; diff --git a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c index 22a6467ffe1f1..56262973ed2b2 100644 --- a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c +++ b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c @@ -31,7 +31,6 @@ #define BY_BIT 7 struct mtd_info_wrapper { - struct mtd_info info; struct nand_chip chip; }; @@ -129,7 +128,7 @@ struct mtd_info *__init crisv32_nand_flash_probe(void) /* Get pointer to private data */ this = &wrapper->chip; - crisv32_mtd = &wrapper->info; + crisv32_mtd = nand_to_mtd(this); pa_oe.oe |= 1 << CE_BIT; pa_oe.oe |= 1 << ALE_BIT; -- GitLab From 17dd20bd7d4389d3bc54d71e263088039203ea07 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 08:59:52 +0100 Subject: [PATCH 1568/2855] mtd: nand: bcm47xx: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h | 1 - drivers/mtd/nand/bcm47xxnflash/main.c | 10 ++++++---- drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h b/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h index c005a62330b14..8ea75710a8544 100644 --- a/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h +++ b/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h @@ -12,7 +12,6 @@ struct bcm47xxnflash { struct bcma_drv_cc *cc; struct nand_chip nand_chip; - struct mtd_info mtd; unsigned curr_command; int curr_page_addr; diff --git a/drivers/mtd/nand/bcm47xxnflash/main.c b/drivers/mtd/nand/bcm47xxnflash/main.c index 0b3acc4391818..2c9bffb614c5b 100644 --- a/drivers/mtd/nand/bcm47xxnflash/main.c +++ b/drivers/mtd/nand/bcm47xxnflash/main.c @@ -27,6 +27,7 @@ static int bcm47xxnflash_probe(struct platform_device *pdev) { struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); struct bcm47xxnflash *b47n; + struct mtd_info *mtd; int err = 0; b47n = devm_kzalloc(&pdev->dev, sizeof(*b47n), GFP_KERNEL); @@ -34,8 +35,9 @@ static int bcm47xxnflash_probe(struct platform_device *pdev) return -ENOMEM; b47n->nand_chip.priv = b47n; - b47n->mtd.dev.parent = &pdev->dev; - b47n->mtd.priv = &b47n->nand_chip; /* Required */ + mtd = nand_to_mtd(&b47n->nand_chip); + mtd->dev.parent = &pdev->dev; + mtd->priv = &b47n->nand_chip; /* Required */ b47n->cc = container_of(nflash, struct bcma_drv_cc, nflash); if (b47n->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { @@ -51,7 +53,7 @@ static int bcm47xxnflash_probe(struct platform_device *pdev) platform_set_drvdata(pdev, b47n); - err = mtd_device_parse_register(&b47n->mtd, probes, NULL, NULL, 0); + err = mtd_device_parse_register(mtd, probes, NULL, NULL, 0); if (err) { pr_err("Failed to register MTD device: %d\n", err); return err; @@ -64,7 +66,7 @@ static int bcm47xxnflash_remove(struct platform_device *pdev) { struct bcm47xxnflash *nflash = platform_get_drvdata(pdev); - nand_release(&nflash->mtd); + nand_release(nand_to_mtd(&nflash->nand_chip)); return 0; } diff --git a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c index e5b2e48658c4d..652478035a7de 100644 --- a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c +++ b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c @@ -421,7 +421,7 @@ int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n) (w4 << 24 | w3 << 18 | w2 << 12 | w1 << 6 | w0)); /* Scan NAND */ - err = nand_scan(&b47n->mtd, 1); + err = nand_scan(nand_to_mtd(&b47n->nand_chip), 1); if (err) { pr_err("Could not scan NAND flash: %d\n", err); goto exit; -- GitLab From a723bf6a58b17379c27f869402baddf4b0d2c7dc Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Fri, 11 Dec 2015 15:04:06 +0100 Subject: [PATCH 1569/2855] mtd: nand: socrates: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/socrates_nand.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c index 2dfb1e0d815a7..925761c240ca6 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/socrates_nand.c @@ -30,7 +30,6 @@ struct socrates_nand_host { struct nand_chip nand_chip; - struct mtd_info mtd; void __iomem *io_base; struct device *dev; }; @@ -159,8 +158,8 @@ static int socrates_nand_probe(struct platform_device *ofdev) return -EIO; } - mtd = &host->mtd; nand_chip = &host->nand_chip; + mtd = nand_to_mtd(nand_chip); host->dev = &ofdev->dev; nand_chip->priv = host; /* link the private data structures */ @@ -216,7 +215,7 @@ out: static int socrates_nand_remove(struct platform_device *ofdev) { struct socrates_nand_host *host = dev_get_drvdata(&ofdev->dev); - struct mtd_info *mtd = &host->mtd; + struct mtd_info *mtd = nand_to_mtd(&host->nand_chip); nand_release(mtd); -- GitLab From 442f201b93b5222ac2e4f7513be86fdbd00e9065 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Fri, 11 Dec 2015 15:06:00 +0100 Subject: [PATCH 1570/2855] mtd: nand: denali: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/denali.c | 69 +++++++++++++++++++++------------------ drivers/mtd/nand/denali.h | 1 - 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 9a5035cac1294..b1dd172ef5653 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -75,7 +75,10 @@ MODULE_PARM_DESC(onfi_timing_mode, * this macro allows us to convert from an MTD structure to our own * device context (denali) structure. */ -#define mtd_to_denali(m) container_of(m, struct denali_nand_info, mtd) +static inline struct denali_nand_info *mtd_to_denali(struct mtd_info *mtd) +{ + return container_of(mtd_to_nand(mtd), struct denali_nand_info, nand); +} /* * These constants are defined by the driver to enable common driver @@ -986,6 +989,8 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, * than one NAND connected. */ if (err_byte < ECC_SECTOR_SIZE) { + struct mtd_info *mtd = + nand_to_mtd(&denali->nand); int offset; offset = (err_sector * @@ -995,7 +1000,7 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, err_device; /* correct the ECC error */ buf[offset] ^= err_correction_value; - denali->mtd.ecc_stats.corrected++; + mtd->ecc_stats.corrected++; bitflips++; } } else { @@ -1062,7 +1067,7 @@ static int write_page(struct mtd_info *mtd, struct nand_chip *chip, { struct denali_nand_info *denali = mtd_to_denali(mtd); dma_addr_t addr = denali->buf.dma_buf; - size_t size = denali->mtd.writesize + denali->mtd.oobsize; + size_t size = mtd->writesize + mtd->oobsize; uint32_t irq_status; uint32_t irq_mask = INTR_STATUS__DMA_CMD_COMP | INTR_STATUS__PROGRAM_FAIL; @@ -1160,7 +1165,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, struct denali_nand_info *denali = mtd_to_denali(mtd); dma_addr_t addr = denali->buf.dma_buf; - size_t size = denali->mtd.writesize + denali->mtd.oobsize; + size_t size = mtd->writesize + mtd->oobsize; uint32_t irq_status; uint32_t irq_mask = INTR_STATUS__ECC_TRANSACTION_DONE | @@ -1193,14 +1198,14 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, denali_enable_dma(denali, false); if (check_erased_page) { - read_oob_data(&denali->mtd, chip->oob_poi, denali->page); + read_oob_data(mtd, chip->oob_poi, denali->page); /* check ECC failures that may have occurred on erased pages */ if (check_erased_page) { - if (!is_erased(buf, denali->mtd.writesize)) - denali->mtd.ecc_stats.failed++; - if (!is_erased(buf, denali->mtd.oobsize)) - denali->mtd.ecc_stats.failed++; + if (!is_erased(buf, mtd->writesize)) + mtd->ecc_stats.failed++; + if (!is_erased(buf, mtd->oobsize)) + mtd->ecc_stats.failed++; } } return max_bitflips; @@ -1211,7 +1216,7 @@ static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, { struct denali_nand_info *denali = mtd_to_denali(mtd); dma_addr_t addr = denali->buf.dma_buf; - size_t size = denali->mtd.writesize + denali->mtd.oobsize; + size_t size = mtd->writesize + mtd->oobsize; uint32_t irq_mask = INTR_STATUS__DMA_CMD_COMP; if (page != denali->page) { @@ -1428,6 +1433,7 @@ static void denali_drv_init(struct denali_nand_info *denali) int denali_init(struct denali_nand_info *denali) { + struct mtd_info *mtd = nand_to_mtd(&denali->nand); int ret; if (denali->platform == INTEL_CE4100) { @@ -1447,7 +1453,7 @@ int denali_init(struct denali_nand_info *denali) if (!denali->buf.buf) return -ENOMEM; - denali->mtd.dev.parent = denali->dev; + mtd->dev.parent = denali->dev; denali_hw_init(denali); denali_drv_init(denali); @@ -1463,8 +1469,8 @@ int denali_init(struct denali_nand_info *denali) /* now that our ISR is registered, we can enable interrupts */ denali_set_intr_modes(denali, true); - denali->mtd.name = "denali-nand"; - denali->mtd.priv = &denali->nand; + mtd->name = "denali-nand"; + mtd->priv = &denali->nand; /* register the driver with the NAND core subsystem */ denali->nand.select_chip = denali_select_chip; @@ -1477,7 +1483,7 @@ int denali_init(struct denali_nand_info *denali) * this is the first stage in a two step process to register * with the nand subsystem */ - if (nand_scan_ident(&denali->mtd, denali->max_banks, NULL)) { + if (nand_scan_ident(mtd, denali->max_banks, NULL)) { ret = -ENXIO; goto failed_req_irq; } @@ -1485,7 +1491,7 @@ int denali_init(struct denali_nand_info *denali) /* allocate the right size buffer now */ devm_kfree(denali->dev, denali->buf.buf); denali->buf.buf = devm_kzalloc(denali->dev, - denali->mtd.writesize + denali->mtd.oobsize, + mtd->writesize + mtd->oobsize, GFP_KERNEL); if (!denali->buf.buf) { ret = -ENOMEM; @@ -1500,7 +1506,7 @@ int denali_init(struct denali_nand_info *denali) } denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf, - denali->mtd.writesize + denali->mtd.oobsize, + mtd->writesize + mtd->oobsize, DMA_BIDIRECTIONAL); if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) { dev_err(denali->dev, "Spectra: failed to map DMA buffer\n"); @@ -1521,10 +1527,10 @@ int denali_init(struct denali_nand_info *denali) denali->nand.bbt_erase_shift += (denali->devnum - 1); denali->nand.phys_erase_shift = denali->nand.bbt_erase_shift; denali->nand.chip_shift += (denali->devnum - 1); - denali->mtd.writesize <<= (denali->devnum - 1); - denali->mtd.oobsize <<= (denali->devnum - 1); - denali->mtd.erasesize <<= (denali->devnum - 1); - denali->mtd.size = denali->nand.numchips * denali->nand.chipsize; + mtd->writesize <<= (denali->devnum - 1); + mtd->oobsize <<= (denali->devnum - 1); + mtd->erasesize <<= (denali->devnum - 1); + mtd->size = denali->nand.numchips * denali->nand.chipsize; denali->bbtskipbytes *= denali->devnum; /* @@ -1551,16 +1557,16 @@ int denali_init(struct denali_nand_info *denali) * SLC if possible. * */ if (!nand_is_slc(&denali->nand) && - (denali->mtd.oobsize > (denali->bbtskipbytes + - ECC_15BITS * (denali->mtd.writesize / + (mtd->oobsize > (denali->bbtskipbytes + + ECC_15BITS * (mtd->writesize / ECC_SECTOR_SIZE)))) { /* if MLC OOB size is large enough, use 15bit ECC*/ denali->nand.ecc.strength = 15; denali->nand.ecc.layout = &nand_15bit_oob; denali->nand.ecc.bytes = ECC_15BITS; iowrite32(15, denali->flash_reg + ECC_CORRECTION); - } else if (denali->mtd.oobsize < (denali->bbtskipbytes + - ECC_8BITS * (denali->mtd.writesize / + } else if (mtd->oobsize < (denali->bbtskipbytes + + ECC_8BITS * (mtd->writesize / ECC_SECTOR_SIZE))) { pr_err("Your NAND chip OOB is not large enough to contain 8bit ECC correction codes"); goto failed_req_irq; @@ -1574,11 +1580,11 @@ int denali_init(struct denali_nand_info *denali) denali->nand.ecc.bytes *= denali->devnum; denali->nand.ecc.strength *= denali->devnum; denali->nand.ecc.layout->eccbytes *= - denali->mtd.writesize / ECC_SECTOR_SIZE; + mtd->writesize / ECC_SECTOR_SIZE; denali->nand.ecc.layout->oobfree[0].offset = denali->bbtskipbytes + denali->nand.ecc.layout->eccbytes; denali->nand.ecc.layout->oobfree[0].length = - denali->mtd.oobsize - denali->nand.ecc.layout->eccbytes - + mtd->oobsize - denali->nand.ecc.layout->eccbytes - denali->bbtskipbytes; /* @@ -1586,7 +1592,7 @@ int denali_init(struct denali_nand_info *denali) * contained by each nand chip. blksperchip will help driver to * know how many blocks is taken by FW. */ - denali->totalblks = denali->mtd.size >> denali->nand.phys_erase_shift; + denali->totalblks = mtd->size >> denali->nand.phys_erase_shift; denali->blksperchip = denali->totalblks / denali->nand.numchips; /* override the default read operations */ @@ -1599,12 +1605,12 @@ int denali_init(struct denali_nand_info *denali) denali->nand.ecc.write_oob = denali_write_oob; denali->nand.erase = denali_erase; - if (nand_scan_tail(&denali->mtd)) { + if (nand_scan_tail(mtd)) { ret = -ENXIO; goto failed_req_irq; } - ret = mtd_device_register(&denali->mtd, NULL, 0); + ret = mtd_device_register(mtd, NULL, 0); if (ret) { dev_err(denali->dev, "Spectra: Failed to register MTD: %d\n", ret); @@ -1622,14 +1628,15 @@ EXPORT_SYMBOL(denali_init); /* driver exit point */ void denali_remove(struct denali_nand_info *denali) { + struct mtd_info *mtd = nand_to_mtd(&denali->nand); /* * Pre-compute DMA buffer size to avoid any problems in case * nand_release() ever changes in a way that mtd->writesize and * mtd->oobsize are not reliable after this call. */ - int bufsize = denali->mtd.writesize + denali->mtd.oobsize; + int bufsize = mtd->writesize + mtd->oobsize; - nand_release(&denali->mtd); + nand_release(mtd); denali_irq_cleanup(denali->irq, denali); dma_unmap_single(denali->dev, denali->buf.dma_buf, bufsize, DMA_BIDIRECTIONAL); diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h index 4b12cd302819a..e7ab4866a5da8 100644 --- a/drivers/mtd/nand/denali.h +++ b/drivers/mtd/nand/denali.h @@ -450,7 +450,6 @@ struct nand_buf { #define DT 3 struct denali_nand_info { - struct mtd_info mtd; struct nand_chip nand; int flash_bank; /* currently selected chip */ int status; -- GitLab From 2d3b77bac34bf99d7fdfd712ec2dc4317b3e850b Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:33 +0100 Subject: [PATCH 1571/2855] mtd: nand: update mtd_to_nand() Now that all drivers are using the mtd instance embedded in the nand_chip struct we can safely update the mtd_to_nand() implementation to use the container_of macro instead of returning the content of mtd->priv. This will allow us to remove mtd->priv = chip assignments done in all NAND controller drivers. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index b614ed2105ac8..9cb7ace6fb1f5 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -734,7 +734,7 @@ static inline struct device_node *nand_get_flash_node(struct nand_chip *chip) static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd) { - return mtd->priv; + return container_of(mtd, struct nand_chip, mtd); } static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip) -- GitLab From 37f5a54646da0760306ab8570115e20d0ed615f5 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:34 +0100 Subject: [PATCH 1572/2855] mtd: nand: remove useless mtd->priv = chip assignments mtd_to_nand() now uses the container_of() approach to transform an mtd_info pointer into a nand_chip one. Drop useless mtd->priv assignments from NAND controller drivers. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/ams-delta.c | 3 --- drivers/mtd/nand/atmel_nand.c | 1 - drivers/mtd/nand/au1550nd.c | 1 - drivers/mtd/nand/bcm47xxnflash/main.c | 1 - drivers/mtd/nand/bf5xx_nand.c | 1 - drivers/mtd/nand/brcmnand/brcmnand.c | 1 - drivers/mtd/nand/cafe_nand.c | 1 - drivers/mtd/nand/cmx270_nand.c | 1 - drivers/mtd/nand/cs553x_nand.c | 1 - drivers/mtd/nand/davinci_nand.c | 1 - drivers/mtd/nand/denali.c | 1 - drivers/mtd/nand/diskonchip.c | 1 - drivers/mtd/nand/docg4.c | 1 - drivers/mtd/nand/fsl_elbc_nand.c | 1 - drivers/mtd/nand/fsl_ifc_nand.c | 1 - drivers/mtd/nand/fsl_upm.c | 1 - drivers/mtd/nand/fsmc_nand.c | 1 - drivers/mtd/nand/gpio.c | 1 - drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 1 - drivers/mtd/nand/hisi504_nand.c | 1 - drivers/mtd/nand/jz4740_nand.c | 1 - drivers/mtd/nand/lpc32xx_mlc.c | 1 - drivers/mtd/nand/lpc32xx_slc.c | 1 - drivers/mtd/nand/mpc5121_nfc.c | 1 - drivers/mtd/nand/mxc_nand.c | 1 - drivers/mtd/nand/nandsim.c | 1 - drivers/mtd/nand/ndfc.c | 1 - drivers/mtd/nand/nuc900_nand.c | 1 - drivers/mtd/nand/omap2.c | 1 - drivers/mtd/nand/orion_nand.c | 1 - drivers/mtd/nand/pasemi_nand.c | 1 - drivers/mtd/nand/plat_nand.c | 1 - drivers/mtd/nand/pxa3xx_nand.c | 1 - drivers/mtd/nand/r852.c | 1 - drivers/mtd/nand/s3c2410.c | 2 -- drivers/mtd/nand/sh_flctl.c | 1 - drivers/mtd/nand/sharpsl.c | 1 - drivers/mtd/nand/socrates_nand.c | 1 - drivers/mtd/nand/sunxi_nand.c | 1 - drivers/mtd/nand/tmio_nand.c | 1 - drivers/mtd/nand/txx9ndfmc.c | 2 -- drivers/mtd/nand/vf610_nfc.c | 1 - 42 files changed, 46 deletions(-) diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c index 0f638c628a0d5..1a18938565ac8 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/ams-delta.c @@ -193,9 +193,6 @@ static int ams_delta_init(struct platform_device *pdev) ams_delta_mtd = nand_to_mtd(this); ams_delta_mtd->owner = THIS_MODULE; - /* Link the private data with the MTD structure */ - ams_delta_mtd->priv = this; - /* * Don't try to request the memory region from here, * it should have been already requested from the diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 9ba2831277eaa..18c4e14ec29f6 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -2128,7 +2128,6 @@ static int atmel_nand_probe(struct platform_device *pdev) } nand_chip->priv = host; /* link the private data structures */ - mtd->priv = nand_chip; mtd->dev.parent = &pdev->dev; /* Set address of NAND IO lines */ diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 280e5b61b815a..341ea4904164d 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c @@ -441,7 +441,6 @@ static int au1550nd_probe(struct platform_device *pdev) this = &ctx->chip; mtd = nand_to_mtd(this); - mtd->priv = this; mtd->dev.parent = &pdev->dev; /* figure out which CS# r->start belongs to */ diff --git a/drivers/mtd/nand/bcm47xxnflash/main.c b/drivers/mtd/nand/bcm47xxnflash/main.c index 2c9bffb614c5b..b44f821b1a3a9 100644 --- a/drivers/mtd/nand/bcm47xxnflash/main.c +++ b/drivers/mtd/nand/bcm47xxnflash/main.c @@ -37,7 +37,6 @@ static int bcm47xxnflash_probe(struct platform_device *pdev) b47n->nand_chip.priv = b47n; mtd = nand_to_mtd(&b47n->nand_chip); mtd->dev.parent = &pdev->dev; - mtd->priv = &b47n->nand_chip; /* Required */ b47n->cc = container_of(nflash, struct bcma_drv_cc, nflash); if (b47n->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index 928d599205693..9514e136542ff 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c @@ -782,7 +782,6 @@ static int bf5xx_nand_probe(struct platform_device *pdev) chip->chip_delay = 0; /* initialise mtd info data struct */ - mtd->priv = chip; mtd->dev.parent = &pdev->dev; /* initialise the hardware */ diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index c05723b4d7734..aea08816d3ac9 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -1924,7 +1924,6 @@ static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn) nand_set_flash_node(chip, dn); chip->priv = host; - mtd->priv = chip; mtd->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "brcmnand.%d", host->cs); mtd->owner = THIS_MODULE; diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 7d6a14218bef8..00c15e22d8277 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c @@ -611,7 +611,6 @@ static int cafe_nand_probe(struct pci_dev *pdev, mtd = nand_to_mtd(&cafe->nand); mtd->dev.parent = &pdev->dev; - mtd->priv = &cafe->nand; cafe->nand.priv = cafe; cafe->pdev = pdev; diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c index 00fd0e933ffb9..6f97ebba52c4c 100644 --- a/drivers/mtd/nand/cmx270_nand.c +++ b/drivers/mtd/nand/cmx270_nand.c @@ -177,7 +177,6 @@ static int __init cmx270_init(void) /* Link the private data with the MTD structure */ cmx270_nand_mtd->owner = THIS_MODULE; - cmx270_nand_mtd->priv = this; /* insert callbacks */ this->IO_ADDR_R = cmx270_nand_io; diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index 386ae832e03f9..a65e4e0f57a1c 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c @@ -206,7 +206,6 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) new_mtd = nand_to_mtd(this); /* Link the private data with the MTD structure */ - new_mtd->priv = this; new_mtd->owner = THIS_MODULE; /* map physical address */ diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index b1f69f9820703..3b49fe86625d2 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -685,7 +685,6 @@ static int nand_davinci_probe(struct platform_device *pdev) info->vaddr = vaddr; mtd = nand_to_mtd(&info->chip); - mtd->priv = &info->chip; mtd->dev.parent = &pdev->dev; nand_set_flash_node(&info->chip, pdev->dev.of_node); diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index b1dd172ef5653..30bf5f690f787 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -1470,7 +1470,6 @@ int denali_init(struct denali_nand_info *denali) /* now that our ISR is registered, we can enable interrupts */ denali_set_intr_modes(denali, true); mtd->name = "denali-nand"; - mtd->priv = &denali->nand; /* register the driver with the NAND core subsystem */ denali->nand.select_chip = denali_select_chip; diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index fff7a4a697599..a5c046654233c 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -1569,7 +1569,6 @@ static int __init doc_probe(unsigned long physadr) nand->bbt_td = (struct nand_bbt_descr *) (doc + 1); nand->bbt_md = nand->bbt_td + 1; - mtd->priv = nand; mtd->owner = THIS_MODULE; nand->priv = doc; diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c index 24d478d90dcc0..95cd139e8a407 100644 --- a/drivers/mtd/nand/docg4.c +++ b/drivers/mtd/nand/docg4.c @@ -1314,7 +1314,6 @@ static int __init probe_docg4(struct platform_device *pdev) mtd = nand_to_mtd(nand); doc = (struct docg4_priv *) (nand + 1); - mtd->priv = nand; nand->priv = doc; mtd->dev.parent = &pdev->dev; doc->virtadr = virtadr; diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 7bde76a02555b..e96d5bcc29221 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -746,7 +746,6 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) dev_dbg(priv->dev, "eLBC Set Information for bank %d\n", priv->bank); /* Fill in fsl_elbc_mtd structure */ - mtd->priv = chip; mtd->dev.parent = priv->dev; nand_set_flash_node(chip, priv->dev->of_node); diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 3f5654f52cee9..9d2b4ed06c81e 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -881,7 +881,6 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv) u32 csor; /* Fill in fsl_ifc_mtd structure */ - mtd->priv = chip; mtd->dev.parent = priv->dev; nand_set_flash_node(chip, priv->dev->of_node); diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 0379adc2d90e7..cafd12de72766 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -176,7 +176,6 @@ static int fun_chip_init(struct fsl_upm_nand *fun, if (fun->rnb_gpio[0] >= 0) fun->chip.dev_ready = fun_chip_ready; - mtd->priv = &fun->chip; mtd->dev.parent = fun->dev; flash_np = of_get_next_child(upm_np, NULL); diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 4c68e7a39b50b..9a7c1f5ffcaaf 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -1009,7 +1009,6 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) /* Link all private pointers */ mtd = nand_to_mtd(&host->nand); nand = &host->nand; - mtd->priv = nand; nand->priv = host; nand_set_flash_node(nand, np); diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c index 99dd74c110383..ded658fc7d73d 100644 --- a/drivers/mtd/nand/gpio.c +++ b/drivers/mtd/nand/gpio.c @@ -278,7 +278,6 @@ static int gpio_nand_probe(struct platform_device *pdev) chip->cmd_ctrl = gpio_nand_cmd_ctrl; mtd = nand_to_mtd(chip); - mtd->priv = chip; mtd->dev.parent = &pdev->dev; platform_set_drvdata(pdev, gpiomtd); diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 38b07c7aa1e44..df61f49d37709 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -1893,7 +1893,6 @@ static int gpmi_nand_init(struct gpmi_nand_data *this) this->current_chip = -1; /* init the MTD data structures */ - mtd->priv = chip; mtd->name = "gpmi-nand"; mtd->dev.parent = this->dev; diff --git a/drivers/mtd/nand/hisi504_nand.c b/drivers/mtd/nand/hisi504_nand.c index 6e6e482c02a38..2aee212b6169c 100644 --- a/drivers/mtd/nand/hisi504_nand.c +++ b/drivers/mtd/nand/hisi504_nand.c @@ -735,7 +735,6 @@ static int hisi_nfc_probe(struct platform_device *pdev) goto err_res; } - mtd->priv = chip; mtd->name = "hisi_nand"; mtd->dev.parent = &pdev->dev; diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index 03239a5a04cd6..a2363d33cecc5 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c @@ -433,7 +433,6 @@ static int jz_nand_probe(struct platform_device *pdev) chip = &nand->chip; mtd = nand_to_mtd(chip); - mtd->priv = chip; mtd->dev.parent = &pdev->dev; mtd->name = "jz4740-nand"; diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c index 3400b3f99d30e..db59fa28d5c86 100644 --- a/drivers/mtd/nand/lpc32xx_mlc.c +++ b/drivers/mtd/nand/lpc32xx_mlc.c @@ -681,7 +681,6 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) nand_chip->priv = host; /* link the private data structures */ nand_set_flash_node(nand_chip, pdev->dev.of_node); - mtd->priv = nand_chip; mtd->dev.parent = &pdev->dev; /* Get NAND clock */ diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c index 61b2961297df4..ccd10b182a220 100644 --- a/drivers/mtd/nand/lpc32xx_slc.c +++ b/drivers/mtd/nand/lpc32xx_slc.c @@ -802,7 +802,6 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) mtd = nand_to_mtd(chip); chip->priv = host; nand_set_flash_node(chip, pdev->dev.of_node); - mtd->priv = chip; mtd->owner = THIS_MODULE; mtd->dev.parent = &pdev->dev; diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index 8b4cd82f019e0..6d0ca33dd7abc 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c @@ -656,7 +656,6 @@ static int mpc5121_nfc_probe(struct platform_device *op) chip = &prv->chip; mtd = nand_to_mtd(chip); - mtd->priv = chip; mtd->dev.parent = dev; chip->priv = prv; nand_set_flash_node(chip, dn); diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 9dd71af363c36..95400992c3e9e 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -1514,7 +1514,6 @@ static int mxcnd_probe(struct platform_device *pdev) /* structures must be linked */ this = &host->nand; mtd = nand_to_mtd(this); - mtd->priv = this; mtd->dev.parent = &pdev->dev; mtd->name = DRIVER_NAME; diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 442eeaf09ebae..78de37ddf88b0 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -2243,7 +2243,6 @@ static int __init ns_init_module(void) return -ENOMEM; } nsmtd = nand_to_mtd(chip); - nsmtd->priv = (void *)chip; nand = (struct nandsim *)(chip + 1); chip->priv = (void *)nand; diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 3a7168e520072..0709ea9dd8ede 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -167,7 +167,6 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, chip->ecc.strength = 1; chip->priv = ndfc; - mtd->priv = chip; mtd->dev.parent = &ndfc->ofdev->dev; flash_np = of_get_next_child(node, NULL); diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/nuc900_nand.c index 4dad170f6545f..220ddfcf29f52 100644 --- a/drivers/mtd/nand/nuc900_nand.c +++ b/drivers/mtd/nand/nuc900_nand.c @@ -245,7 +245,6 @@ static int nuc900_nand_probe(struct platform_device *pdev) chip = &(nuc900_nand->chip); mtd = nand_to_mtd(chip); - mtd->priv = chip; mtd->dev.parent = &pdev->dev; spin_lock_init(&nuc900_nand->lock); diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index f9d0b58323e38..e9cbbc63c566f 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -1672,7 +1672,6 @@ static int omap_nand_probe(struct platform_device *pdev) info->ecc_opt = pdata->ecc_opt; nand_chip = &info->nand; mtd = nand_to_mtd(nand_chip); - mtd->priv = &info->nand; mtd->dev.parent = &pdev->dev; nand_chip->ecc.priv = NULL; nand_set_flash_node(nand_chip, pdata->of_node); diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 087a04024d6a0..2c2be612448e7 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -122,7 +122,6 @@ static int __init orion_nand_probe(struct platform_device *pdev) board = dev_get_platdata(&pdev->dev); } - mtd->priv = nc; mtd->dev.parent = &pdev->dev; nc->priv = board; diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 4dd298523e815..3ab53ca53cca2 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c @@ -121,7 +121,6 @@ static int pasemi_nand_probe(struct platform_device *ofdev) pasemi_nand_mtd = nand_to_mtd(chip); /* Link the private data with the MTD structure */ - pasemi_nand_mtd->priv = chip; pasemi_nand_mtd->dev.parent = &ofdev->dev; chip->IO_ADDR_R = of_iomap(np, 0); diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index 796eb7d54f2f1..dc88a58d5cdeb 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c @@ -59,7 +59,6 @@ static int plat_nand_probe(struct platform_device *pdev) data->chip.priv = &data; nand_set_flash_node(&data->chip, pdev->dev.of_node); mtd = nand_to_mtd(&data->chip); - mtd->priv = &data->chip; mtd->dev.parent = &pdev->dev; data->chip.IO_ADDR_R = data->io_base; diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index c4d578809ea97..10704ae129fc2 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -1709,7 +1709,6 @@ static int alloc_nand_resource(struct platform_device *pdev) info->host[cs] = host; host->cs = cs; host->info_data = info; - mtd->priv = chip; mtd->dev.parent = &pdev->dev; /* FIXME: all chips use the same device tree partitions */ nand_set_flash_node(chip, np); diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index 1ac8ef2ed2dbc..cb0bf09214d5c 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c @@ -638,7 +638,6 @@ static int r852_register_nand_device(struct r852_device *dev) WARN_ON(dev->card_registred); - mtd->priv = dev->chip; mtd->dev.parent = &dev->pci_dev->dev; if (dev->readonly) diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index c074a491d087f..bc94c5db01bf1 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -788,7 +788,6 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, struct s3c2410_nand_set *set) { struct nand_chip *chip = &nmtd->chip; - struct mtd_info *mtd = nand_to_mtd(chip); void __iomem *regs = info->regs; chip->write_buf = s3c2410_nand_write_buf; @@ -834,7 +833,6 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, chip->IO_ADDR_R = chip->IO_ADDR_W; nmtd->info = info; - mtd->priv = chip; nmtd->set = set; #ifdef CONFIG_MTD_NAND_S3C2410_HWECC diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index 0ec4b04b35362..c7126b75fb014 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c @@ -1123,7 +1123,6 @@ static int flctl_probe(struct platform_device *pdev) nand = &flctl->chip; flctl_mtd = nand_to_mtd(nand); nand_set_flash_node(nand, pdev->dev.of_node); - flctl_mtd->priv = nand; flctl_mtd->dev.parent = &pdev->dev; flctl->pdev = pdev; flctl->hwecc = pdata->has_hwecc; diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index 4b649fbad66ec..b7d1b55a160b4 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c @@ -147,7 +147,6 @@ static int sharpsl_nand_probe(struct platform_device *pdev) /* Link the private data with the MTD structure */ mtd = nand_to_mtd(this); - mtd->priv = this; mtd->dev.parent = &pdev->dev; platform_set_drvdata(pdev, sharpsl); diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c index 925761c240ca6..d7e9d4df8c282 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/socrates_nand.c @@ -164,7 +164,6 @@ static int socrates_nand_probe(struct platform_device *ofdev) nand_chip->priv = host; /* link the private data structures */ nand_set_flash_node(nand_chip, ofdev->dev.of_node); - mtd->priv = nand_chip; mtd->name = "socrates_nand"; mtd->dev.parent = &ofdev->dev; diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index c29d659a747a4..51e10a35fe08c 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c @@ -1337,7 +1337,6 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc, mtd = nand_to_mtd(nand); mtd->dev.parent = dev; - mtd->priv = nand; ret = nand_scan_ident(mtd, nsels, NULL); if (ret) diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c index e7b82e11c7958..08b30549ec0a0 100644 --- a/drivers/mtd/nand/tmio_nand.c +++ b/drivers/mtd/nand/tmio_nand.c @@ -382,7 +382,6 @@ static int tmio_probe(struct platform_device *dev) platform_set_drvdata(dev, tmio); nand_chip = &tmio->chip; mtd = nand_to_mtd(nand_chip); - mtd->priv = nand_chip; mtd->name = "tmio-nand"; mtd->dev.parent = &dev->dev; diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c index da7fcbd37f3a1..27488ee443864 100644 --- a/drivers/mtd/nand/txx9ndfmc.c +++ b/drivers/mtd/nand/txx9ndfmc.c @@ -324,8 +324,6 @@ static int __init txx9ndfmc_probe(struct platform_device *dev) mtd = nand_to_mtd(chip); mtd->dev.parent = &dev->dev; - mtd->priv = chip; - chip->read_byte = txx9ndfmc_read_byte; chip->read_buf = txx9ndfmc_read_buf; chip->write_buf = txx9ndfmc_write_buf; diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c index 1bbb93a7b4e5f..034420f313d50 100644 --- a/drivers/mtd/nand/vf610_nfc.c +++ b/drivers/mtd/nand/vf610_nfc.c @@ -679,7 +679,6 @@ static int vf610_nfc_probe(struct platform_device *pdev) chip = &nfc->chip; mtd = nand_to_mtd(chip); - mtd->priv = chip; mtd->owner = THIS_MODULE; mtd->dev.parent = nfc->dev; mtd->name = DRV_NAME; -- GitLab From 038a5380e3698615eea341f10f42b1fd74e54e1c Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:35 +0100 Subject: [PATCH 1573/2855] cris: nand: remove useless mtd->priv = chip assignments mtd_to_nand() now uses the container_of() approach to transform an mtd_info pointer into a nand_chip one. Drop useless mtd->priv assignments from NAND controller drivers. Signed-off-by: Boris Brezillon Acked-by: Jesper Nilsson Signed-off-by: Brian Norris --- arch/cris/arch-v32/drivers/mach-a3/nandflash.c | 3 --- arch/cris/arch-v32/drivers/mach-fs/nandflash.c | 3 --- 2 files changed, 6 deletions(-) diff --git a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c index ee74e45a5cf4d..5aa3f51623108 100644 --- a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c +++ b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c @@ -149,9 +149,6 @@ struct mtd_info *__init crisv32_nand_flash_probe(void) this = &wrapper->chip; crisv32_mtd = nand_to_mtd(this); - /* Link the private data with the MTD structure */ - crisv32_mtd->priv = this; - /* Set address of NAND IO lines */ this->IO_ADDR_R = read_cs; this->IO_ADDR_W = write_cs; diff --git a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c index 56262973ed2b2..a7c17b0f172a3 100644 --- a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c +++ b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c @@ -140,9 +140,6 @@ struct mtd_info *__init crisv32_nand_flash_probe(void) bif_cfg.gated_csp1 = regk_bif_core_wr; REG_WR(bif_core, regi_bif_core, rw_grp3_cfg, bif_cfg); - /* Link the private data with the MTD structure */ - crisv32_mtd->priv = this; - /* Set address of NAND IO lines */ this->IO_ADDR_R = read_cs; this->IO_ADDR_W = write_cs; -- GitLab From f12d86afc5594c89492fb7c78fce07a4e94b2384 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:36 +0100 Subject: [PATCH 1574/2855] staging: mt29f_spinand: remove useless mtd->priv = chip assignment mtd_to_nand() now uses the container_of() approach to transform an mtd_info pointer into a nand_chip one. Drop useless mtd->priv assignments from NAND controller drivers. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/staging/mt29f_spinand/mt29f_spinand.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c index 8171b741ff86e..b7d429d45dab7 100644 --- a/drivers/staging/mt29f_spinand/mt29f_spinand.c +++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c @@ -907,7 +907,6 @@ static int spinand_probe(struct spi_device *spi_nand) dev_set_drvdata(&spi_nand->dev, mtd); - mtd->priv = chip; mtd->dev.parent = &spi_nand->dev; mtd->oobsize = 64; -- GitLab From 7194a29a9bf1e5abcda8b181bba771fbe0e95b6c Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:37 +0100 Subject: [PATCH 1575/2855] mtd: nand: simplify nand_dt_init() usage nand_dt_init() function requires 3 arguments where it actually needs one (dn and mtd can both be retrieved from chip). Drop these parameters. Testing for dn != NULL inside nand_dt_init() also helps simplifying the caller code. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_base.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 5aec1545cd399..ae3fd2a8c2f50 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3937,11 +3937,17 @@ ident_done: return type; } -static int nand_dt_init(struct mtd_info *mtd, struct nand_chip *chip, - struct device_node *dn) +static int nand_dt_init(struct nand_chip *chip) { + struct device_node *dn = nand_get_flash_node(chip); int ecc_mode, ecc_strength, ecc_step; + if (!dn) + return 0; + + /* MTD can automatically handle DT partitions, etc. */ + mtd_set_of_node(nand_to_mtd(chip), dn); + if (of_get_nand_bus_width(dn) == 16) chip->options |= NAND_BUSWIDTH_16; @@ -3989,14 +3995,9 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, struct nand_flash_dev *type; int ret; - if (nand_get_flash_node(chip)) { - /* MTD can automatically handle DT partitions, etc. */ - mtd_set_of_node(mtd, nand_get_flash_node(chip)); - - ret = nand_dt_init(mtd, chip, nand_get_flash_node(chip)); - if (ret) - return ret; - } + ret = nand_dt_init(chip); + if (ret) + return ret; /* Set the default functions */ nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); -- GitLab From 29574ede097438c560e8115caff9b6b8668730be Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:38 +0100 Subject: [PATCH 1576/2855] mtd: nand: kill the chip->flash_node field Now that the nand_chip struct directly embeds an mtd_info struct we can get rid of the ->flash_node field and forward set/get_flash_node requests to the MTD layer. As a side effect, we no longer need the mtd_set_of_node() call done in nand_dt_init(). Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_base.c | 3 --- include/linux/mtd/nand.h | 7 ++----- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index ae3fd2a8c2f50..8bb8ebd62aaac 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3945,9 +3945,6 @@ static int nand_dt_init(struct nand_chip *chip) if (!dn) return 0; - /* MTD can automatically handle DT partitions, etc. */ - mtd_set_of_node(nand_to_mtd(chip), dn); - if (of_get_nand_bus_width(dn) == 16) chip->options |= NAND_BUSWIDTH_16; diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 9cb7ace6fb1f5..2bee2e42ae2f1 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -545,7 +545,6 @@ struct nand_buffers { * flash device * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the * flash device. - * @flash_node: [BOARDSPECIFIC] device node describing this instance * @read_byte: [REPLACEABLE] read one byte from the chip * @read_word: [REPLACEABLE] read one word from the chip * @write_byte: [REPLACEABLE] write a single byte to the chip on the @@ -645,8 +644,6 @@ struct nand_chip { void __iomem *IO_ADDR_R; void __iomem *IO_ADDR_W; - struct device_node *flash_node; - uint8_t (*read_byte)(struct mtd_info *mtd); u16 (*read_word)(struct mtd_info *mtd); void (*write_byte)(struct mtd_info *mtd, uint8_t byte); @@ -724,12 +721,12 @@ struct nand_chip { static inline void nand_set_flash_node(struct nand_chip *chip, struct device_node *np) { - chip->flash_node = np; + mtd_set_of_node(&chip->mtd, np); } static inline struct device_node *nand_get_flash_node(struct nand_chip *chip) { - return chip->flash_node; + return mtd_get_of_node(&chip->mtd); } static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd) -- GitLab From 706ab42eae8a7a320d0364c7040c9419bfdea235 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:48:54 +0900 Subject: [PATCH 1577/2855] staging: wilc1000: fix return type of host_int_add_ptk This patch changes return type of host_int_add_ptk from s32 to int. The result variable gets return value from wilc_mq_send that has return type of int. It should be changed return type of this function as well as data type of result variable. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index d5b7725ec2bf5..082450f4459cf 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3207,12 +3207,12 @@ int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, return result; } -s32 host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk, +int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk, u8 u8PtkKeylen, const u8 *mac_addr, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode, u8 u8Idx) { - s32 result = 0; + int result = 0; struct host_if_msg msg; u8 u8KeyLen = u8PtkKeylen; u32 i; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 57e1d424afdc4..ee9c8fed01343 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -311,7 +311,7 @@ int host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv, int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, const u8 *key, u8 len, u8 index, u8 mode, enum AUTHTYPE auth_type); -s32 host_int_add_ptk(struct host_if_drv *hWFIDrv, const u8 *pu8Ptk, +int host_int_add_ptk(struct host_if_drv *hWFIDrv, const u8 *pu8Ptk, u8 u8PtkKeylen, const u8 *mac_addr, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode, u8 u8Idx); -- GitLab From d17b7dd24212b7bb823c4c568268b29577943f96 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:48:55 +0900 Subject: [PATCH 1578/2855] staging: wilc1000: fix argument name of host_int_add_ptk This patch changes struct host_if_drv of host_int_add_ptk function declaration from hWFIDrv to hif_drv. With this change, first parameter of this function declaration and definition has same name as hif_drv. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index ee9c8fed01343..12deff432d585 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -311,7 +311,7 @@ int host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv, int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, const u8 *key, u8 len, u8 index, u8 mode, enum AUTHTYPE auth_type); -int host_int_add_ptk(struct host_if_drv *hWFIDrv, const u8 *pu8Ptk, +int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk, u8 u8PtkKeylen, const u8 *mac_addr, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode, u8 u8Idx); -- GitLab From d170536f3add3ef96fe0015ac38c886f17f5aeb6 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:48:56 +0900 Subject: [PATCH 1579/2855] staging: wilc1000: rename pu8Ptk in host_int_add_ptk This patch changes pu8Ptk to ptk to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 082450f4459cf..d225dbf3c1b04 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3207,7 +3207,7 @@ int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, return result; } -int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk, +int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, u8 u8PtkKeylen, const u8 *mac_addr, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode, u8 u8Idx) @@ -3240,7 +3240,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk, msg.body.key_info.action = ADDKEY; msg.body.key_info.attr.wpa.key = kmalloc(u8PtkKeylen, GFP_KERNEL); - memcpy(msg.body.key_info.attr.wpa.key, pu8Ptk, u8PtkKeylen); + memcpy(msg.body.key_info.attr.wpa.key, ptk, u8PtkKeylen); if (pu8RxMic) { memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic, RX_MIC_KEY_LEN); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 12deff432d585..ae70dc578e638 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -311,7 +311,7 @@ int host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv, int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, const u8 *key, u8 len, u8 index, u8 mode, enum AUTHTYPE auth_type); -int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk, +int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, u8 u8PtkKeylen, const u8 *mac_addr, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode, u8 u8Idx); -- GitLab From 0743b7eaffa7380842e59372094ba236b3763322 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:48:57 +0900 Subject: [PATCH 1580/2855] staging: wilc1000: rename u8PtkKeylen in host_int_add_ptk This patch changes u8PtkKeylen to ptk_key_len to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 8 ++++---- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index d225dbf3c1b04..96a0a58900022 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3208,13 +3208,13 @@ int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, } int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, - u8 u8PtkKeylen, const u8 *mac_addr, + u8 ptk_key_len, const u8 *mac_addr, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode, u8 u8Idx) { int result = 0; struct host_if_msg msg; - u8 u8KeyLen = u8PtkKeylen; + u8 u8KeyLen = ptk_key_len; u32 i; if (!hif_drv) { @@ -3239,8 +3239,8 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, if (mode == STATION_MODE) msg.body.key_info.action = ADDKEY; - msg.body.key_info.attr.wpa.key = kmalloc(u8PtkKeylen, GFP_KERNEL); - memcpy(msg.body.key_info.attr.wpa.key, ptk, u8PtkKeylen); + msg.body.key_info.attr.wpa.key = kmalloc(ptk_key_len, GFP_KERNEL); + memcpy(msg.body.key_info.attr.wpa.key, ptk, ptk_key_len); if (pu8RxMic) { memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic, RX_MIC_KEY_LEN); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index ae70dc578e638..ae0e260d3ca6f 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -312,7 +312,7 @@ int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, const u8 *key, u8 len, u8 index, u8 mode, enum AUTHTYPE auth_type); int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, - u8 u8PtkKeylen, const u8 *mac_addr, + u8 ptk_key_len, const u8 *mac_addr, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode, u8 u8Idx); s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, -- GitLab From 38f6629054b974af4ccee3bef055b97b5b048089 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:48:58 +0900 Subject: [PATCH 1581/2855] staging: wilc1000: rename pu8RxMic in host_int_add_ptk This patch changes pu8RxMic to rx_mic to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 10 +++++----- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 96a0a58900022..9616a6136619d 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3209,7 +3209,7 @@ int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, u8 ptk_key_len, const u8 *mac_addr, - const u8 *pu8RxMic, const u8 *pu8TxMic, + const u8 *rx_mic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode, u8 u8Idx) { int result = 0; @@ -3222,7 +3222,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, return -EFAULT; } - if (pu8RxMic) + if (rx_mic) u8KeyLen += RX_MIC_KEY_LEN; if (pu8TxMic) @@ -3242,11 +3242,11 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, msg.body.key_info.attr.wpa.key = kmalloc(ptk_key_len, GFP_KERNEL); memcpy(msg.body.key_info.attr.wpa.key, ptk, ptk_key_len); - if (pu8RxMic) { - memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic, RX_MIC_KEY_LEN); + if (rx_mic) { + memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic, RX_MIC_KEY_LEN); if (INFO) { for (i = 0; i < RX_MIC_KEY_LEN; i++) - PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, pu8RxMic[i]); + PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, rx_mic[i]); } } if (pu8TxMic) { diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index ae0e260d3ca6f..2ee93045aaf58 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -313,7 +313,7 @@ int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, enum AUTHTYPE auth_type); int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, u8 ptk_key_len, const u8 *mac_addr, - const u8 *pu8RxMic, const u8 *pu8TxMic, + const u8 *rx_mic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode, u8 u8Idx); s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, u32 *pu32InactiveTime); -- GitLab From d7c0242be1a380110502396e79ec782e02f14d60 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:48:59 +0900 Subject: [PATCH 1582/2855] staging: wilc1000: rename pu8TxMic in host_int_add_ptk This patch changes pu8TxMic to tx_mic to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 10 +++++----- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 9616a6136619d..a8566eebda8ae 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3209,7 +3209,7 @@ int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, u8 ptk_key_len, const u8 *mac_addr, - const u8 *rx_mic, const u8 *pu8TxMic, + const u8 *rx_mic, const u8 *tx_mic, u8 mode, u8 u8Ciphermode, u8 u8Idx) { int result = 0; @@ -3225,7 +3225,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, if (rx_mic) u8KeyLen += RX_MIC_KEY_LEN; - if (pu8TxMic) + if (tx_mic) u8KeyLen += TX_MIC_KEY_LEN; memset(&msg, 0, sizeof(struct host_if_msg)); @@ -3249,11 +3249,11 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, rx_mic[i]); } } - if (pu8TxMic) { - memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic, TX_MIC_KEY_LEN); + if (tx_mic) { + memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic, TX_MIC_KEY_LEN); if (INFO) { for (i = 0; i < TX_MIC_KEY_LEN; i++) - PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, pu8TxMic[i]); + PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, tx_mic[i]); } } diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 2ee93045aaf58..5da584b9d8cc0 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -313,7 +313,7 @@ int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, enum AUTHTYPE auth_type); int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, u8 ptk_key_len, const u8 *mac_addr, - const u8 *rx_mic, const u8 *pu8TxMic, + const u8 *rx_mic, const u8 *tx_mic, u8 mode, u8 u8Ciphermode, u8 u8Idx); s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, u32 *pu32InactiveTime); -- GitLab From f0c82579d853825d5728d189dba8dbbad61cbaca Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:00 +0900 Subject: [PATCH 1583/2855] staging: wilc1000: rename u8Ciphermode in host_int_add_ptk This patch changes u8Ciphermode to cipher_mode to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index a8566eebda8ae..80a1442ab6d2c 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3210,7 +3210,7 @@ int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, u8 ptk_key_len, const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic, - u8 mode, u8 u8Ciphermode, u8 u8Idx) + u8 mode, u8 cipher_mode, u8 u8Idx) { int result = 0; struct host_if_msg msg; @@ -3259,7 +3259,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, msg.body.key_info.attr.wpa.key_len = u8KeyLen; msg.body.key_info.attr.wpa.mac_addr = mac_addr; - msg.body.key_info.attr.wpa.mode = u8Ciphermode; + msg.body.key_info.attr.wpa.mode = cipher_mode; msg.drv = hif_drv; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 5da584b9d8cc0..04ecf502a3a36 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -314,7 +314,7 @@ int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, u8 ptk_key_len, const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic, - u8 mode, u8 u8Ciphermode, u8 u8Idx); + u8 mode, u8 cipher_mode, u8 u8Idx); s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, u32 *pu32InactiveTime); s32 host_int_add_rx_gtk(struct host_if_drv *hWFIDrv, const u8 *pu8RxGtk, -- GitLab From 3e5c4ab6cf313ec9feec075fdcc0d28ba2316849 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:01 +0900 Subject: [PATCH 1584/2855] staging: wilc1000: rename u8Idx in host_int_add_ptk This patch changes u8Idx to index to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 80a1442ab6d2c..fedd099b52986 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3210,7 +3210,7 @@ int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, u8 ptk_key_len, const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic, - u8 mode, u8 cipher_mode, u8 u8Idx) + u8 mode, u8 cipher_mode, u8 index) { int result = 0; struct host_if_msg msg; @@ -3234,7 +3234,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, msg.body.key_info.type = WPA_PTK; if (mode == AP_MODE) { msg.body.key_info.action = ADDKEY_AP; - msg.body.key_info.attr.wpa.index = u8Idx; + msg.body.key_info.attr.wpa.index = index; } if (mode == STATION_MODE) msg.body.key_info.action = ADDKEY; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 04ecf502a3a36..92383158b8430 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -314,7 +314,7 @@ int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, u8 ptk_key_len, const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic, - u8 mode, u8 cipher_mode, u8 u8Idx); + u8 mode, u8 cipher_mode, u8 index); s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, u32 *pu32InactiveTime); s32 host_int_add_rx_gtk(struct host_if_drv *hWFIDrv, const u8 *pu8RxGtk, -- GitLab From fa2690747580c9f6f6ce5da7ca2dc7d311c35051 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:02 +0900 Subject: [PATCH 1585/2855] staging: wilc1000: replace u32 with int The data type of variable i changes u32 to int. It is used as array index to print debug message so that it is better to use data type of int. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index fedd099b52986..a959f48d03f64 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3215,7 +3215,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, int result = 0; struct host_if_msg msg; u8 u8KeyLen = ptk_key_len; - u32 i; + int i; if (!hif_drv) { PRINT_ER("driver is null\n"); -- GitLab From 53bbbb575cb8d557fcf96998da42d0a2ab57d036 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:03 +0900 Subject: [PATCH 1586/2855] staging: wilc1000: rename u8KeyLen in host_int_add_ptk This patch changes u8KeyLen to key_len to avoid camelcase. It is used as local variable in order to save pkt_key_len that is argument of this function. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index a959f48d03f64..dd7e8edb850dd 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3214,7 +3214,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, { int result = 0; struct host_if_msg msg; - u8 u8KeyLen = ptk_key_len; + u8 key_len = ptk_key_len; int i; if (!hif_drv) { @@ -3223,10 +3223,10 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, } if (rx_mic) - u8KeyLen += RX_MIC_KEY_LEN; + key_len += RX_MIC_KEY_LEN; if (tx_mic) - u8KeyLen += TX_MIC_KEY_LEN; + key_len += TX_MIC_KEY_LEN; memset(&msg, 0, sizeof(struct host_if_msg)); @@ -3257,7 +3257,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, } } - msg.body.key_info.attr.wpa.key_len = u8KeyLen; + msg.body.key_info.attr.wpa.key_len = key_len; msg.body.key_info.attr.wpa.mac_addr = mac_addr; msg.body.key_info.attr.wpa.mode = cipher_mode; msg.drv = hif_drv; -- GitLab From 8ab8c59218d79effc763d6f20cb0d0bad783fd56 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:04 +0900 Subject: [PATCH 1587/2855] staging: wilc1000: use kmemdup in host_int_add_ptk This patch changes kmalloc followed by memcpy to kmemdup The error checking is also added when kmemdup is failed. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index dd7e8edb850dd..18623c7b99da5 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3239,8 +3239,9 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, if (mode == STATION_MODE) msg.body.key_info.action = ADDKEY; - msg.body.key_info.attr.wpa.key = kmalloc(ptk_key_len, GFP_KERNEL); - memcpy(msg.body.key_info.attr.wpa.key, ptk, ptk_key_len); + msg.body.key_info.attr.wpa.key = kmemdup(ptk, ptk_key_len, GFP_KERNEL); + if (!msg.body.key_info.attr.wpa.key) + return -ENOMEM; if (rx_mic) { memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic, RX_MIC_KEY_LEN); -- GitLab From 1503457f7f08c2a9907060f8beca3a35c6c0c047 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:05 +0900 Subject: [PATCH 1588/2855] staging: wilc1000: fix return type of host_int_add_rx_gtk This patch changes return type of host_int_add_rx_gtk from s32 to int. The result variable gets return value from wilc_mq_send that has return type of int. It should be changed return type of this function as well as data type of result variable. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 18623c7b99da5..12b3f1dc5cf11 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3273,13 +3273,13 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, return result; } -s32 host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk, +int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk, u8 u8GtkKeylen, u8 u8KeyIdx, u32 u32KeyRSClen, const u8 *KeyRSC, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode) { - s32 result = 0; + int result = 0; struct host_if_msg msg; u8 u8KeyLen = u8GtkKeylen; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 92383158b8430..2f1059884b334 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -317,7 +317,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, u8 mode, u8 cipher_mode, u8 index); s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, u32 *pu32InactiveTime); -s32 host_int_add_rx_gtk(struct host_if_drv *hWFIDrv, const u8 *pu8RxGtk, +int host_int_add_rx_gtk(struct host_if_drv *hWFIDrv, const u8 *pu8RxGtk, u8 u8GtkKeylen, u8 u8KeyIdx, u32 u32KeyRSClen, const u8 *KeyRSC, const u8 *pu8RxMic, const u8 *pu8TxMic, -- GitLab From 84f82ed814196acbdc892cd2b98d3e696e6dd607 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:06 +0900 Subject: [PATCH 1589/2855] staging: wilc1000: fix argument name of host_int_add_rx_gtk This patch changes struct host_if_drv of host_int_add_rx_gtk function declaration from hWFIDrv to hif_drv. With this change, first argument of this function declaration and definition has same name as hif_drv. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 2f1059884b334..5f1b20cef2b33 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -317,7 +317,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, u8 mode, u8 cipher_mode, u8 index); s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, u32 *pu32InactiveTime); -int host_int_add_rx_gtk(struct host_if_drv *hWFIDrv, const u8 *pu8RxGtk, +int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk, u8 u8GtkKeylen, u8 u8KeyIdx, u32 u32KeyRSClen, const u8 *KeyRSC, const u8 *pu8RxMic, const u8 *pu8TxMic, -- GitLab From 3c0bf6b577bbd6900141e75e028e0dcb43be3903 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:07 +0900 Subject: [PATCH 1590/2855] staging: wilc1000: rename pu8RxGtk in host_int_add_rx_gtk This patch changes pu8RxGtk to rx_gtk to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 12b3f1dc5cf11..b79383ef9e951 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3273,7 +3273,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, return result; } -int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk, +int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, u8 u8GtkKeylen, u8 u8KeyIdx, u32 u32KeyRSClen, const u8 *KeyRSC, const u8 *pu8RxMic, const u8 *pu8TxMic, @@ -3312,7 +3312,7 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk, msg.body.key_info.action = ADDKEY; msg.body.key_info.attr.wpa.key = kmalloc(u8KeyLen, GFP_KERNEL); - memcpy(msg.body.key_info.attr.wpa.key, pu8RxGtk, u8GtkKeylen); + memcpy(msg.body.key_info.attr.wpa.key, rx_gtk, u8GtkKeylen); if (pu8RxMic) memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic, diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 5f1b20cef2b33..51f51be9a5543 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -317,7 +317,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, u8 mode, u8 cipher_mode, u8 index); s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, u32 *pu32InactiveTime); -int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk, +int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, u8 u8GtkKeylen, u8 u8KeyIdx, u32 u32KeyRSClen, const u8 *KeyRSC, const u8 *pu8RxMic, const u8 *pu8TxMic, -- GitLab From 5285e910fb57418e78b1675a279ad63e0ba0491c Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:08 +0900 Subject: [PATCH 1591/2855] staging: wilc1000: rename u8GtkKeylen in host_int_add_rx_gtk This patch changes u8GtkKeylen to gtk_key_len to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 +++--- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index b79383ef9e951..5c40d40ff7fbd 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3274,14 +3274,14 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, } int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, - u8 u8GtkKeylen, u8 u8KeyIdx, + u8 gtk_key_len, u8 u8KeyIdx, u32 u32KeyRSClen, const u8 *KeyRSC, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode) { int result = 0; struct host_if_msg msg; - u8 u8KeyLen = u8GtkKeylen; + u8 u8KeyLen = gtk_key_len; if (!hif_drv) { PRINT_ER("driver is null\n"); @@ -3312,7 +3312,7 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, msg.body.key_info.action = ADDKEY; msg.body.key_info.attr.wpa.key = kmalloc(u8KeyLen, GFP_KERNEL); - memcpy(msg.body.key_info.attr.wpa.key, rx_gtk, u8GtkKeylen); + memcpy(msg.body.key_info.attr.wpa.key, rx_gtk, gtk_key_len); if (pu8RxMic) memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic, diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 51f51be9a5543..6b7b05e41bc4a 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -318,7 +318,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, u32 *pu32InactiveTime); int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, - u8 u8GtkKeylen, u8 u8KeyIdx, + u8 gtk_key_len, u8 u8KeyIdx, u32 u32KeyRSClen, const u8 *KeyRSC, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode); -- GitLab From 9a5e57362474e1c508c20c4757b1f43855ae377e Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:09 +0900 Subject: [PATCH 1592/2855] staging: wilc1000: rename u8KeyIdx in host_int_add_rx_gtk This patch changes u8KeyIdx to index to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 5c40d40ff7fbd..22fdca597e4a0 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3274,7 +3274,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, } int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, - u8 gtk_key_len, u8 u8KeyIdx, + u8 gtk_key_len, u8 index, u32 u32KeyRSClen, const u8 *KeyRSC, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode) @@ -3322,7 +3322,7 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic, TX_MIC_KEY_LEN); - msg.body.key_info.attr.wpa.index = u8KeyIdx; + msg.body.key_info.attr.wpa.index = index; msg.body.key_info.attr.wpa.key_len = u8KeyLen; msg.body.key_info.attr.wpa.seq_len = u32KeyRSClen; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 6b7b05e41bc4a..41ca349c47cac 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -318,7 +318,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, u32 *pu32InactiveTime); int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, - u8 gtk_key_len, u8 u8KeyIdx, + u8 gtk_key_len, u8 index, u32 u32KeyRSClen, const u8 *KeyRSC, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode); -- GitLab From 18bef999b1c01c79c11a310649a1a590a6523959 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:10 +0900 Subject: [PATCH 1593/2855] staging: wilc1000: rename u32KeyRSClen in host_int_add_rx_gtk This patch changes u32KeyRSClen to key_rsc_len to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 8 ++++---- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 22fdca597e4a0..32d46064faf5d 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3275,7 +3275,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, u8 gtk_key_len, u8 index, - u32 u32KeyRSClen, const u8 *KeyRSC, + u32 key_rsc_len, const u8 *KeyRSC, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode) { @@ -3296,8 +3296,8 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, u8KeyLen += TX_MIC_KEY_LEN; if (KeyRSC) { - msg.body.key_info.attr.wpa.seq = kmalloc(u32KeyRSClen, GFP_KERNEL); - memcpy(msg.body.key_info.attr.wpa.seq, KeyRSC, u32KeyRSClen); + msg.body.key_info.attr.wpa.seq = kmalloc(key_rsc_len, GFP_KERNEL); + memcpy(msg.body.key_info.attr.wpa.seq, KeyRSC, key_rsc_len); } msg.id = HOST_IF_MSG_KEY; @@ -3324,7 +3324,7 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, msg.body.key_info.attr.wpa.index = index; msg.body.key_info.attr.wpa.key_len = u8KeyLen; - msg.body.key_info.attr.wpa.seq_len = u32KeyRSClen; + msg.body.key_info.attr.wpa.seq_len = key_rsc_len; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 41ca349c47cac..f75bfa1b0437f 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -319,7 +319,7 @@ s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, u32 *pu32InactiveTime); int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, u8 gtk_key_len, u8 index, - u32 u32KeyRSClen, const u8 *KeyRSC, + u32 key_rsc_len, const u8 *KeyRSC, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode); s32 host_int_add_tx_gtk(struct host_if_drv *hWFIDrv, u8 u8KeyLen, -- GitLab From 982859ccf4a7bb2d49b24afa3007c048c2a986c2 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:11 +0900 Subject: [PATCH 1594/2855] staging: wilc1000: rename KeyRSC in host_int_add_rx_gtk This patch changes KeyRSC to key_rsc to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 +++--- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 32d46064faf5d..b50e78dddb896 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3275,7 +3275,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, u8 gtk_key_len, u8 index, - u32 key_rsc_len, const u8 *KeyRSC, + u32 key_rsc_len, const u8 *key_rsc, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode) { @@ -3295,9 +3295,9 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, if (pu8TxMic) u8KeyLen += TX_MIC_KEY_LEN; - if (KeyRSC) { + if (key_rsc) { msg.body.key_info.attr.wpa.seq = kmalloc(key_rsc_len, GFP_KERNEL); - memcpy(msg.body.key_info.attr.wpa.seq, KeyRSC, key_rsc_len); + memcpy(msg.body.key_info.attr.wpa.seq, key_rsc, key_rsc_len); } msg.id = HOST_IF_MSG_KEY; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index f75bfa1b0437f..66bb7d7f3eb2f 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -319,7 +319,7 @@ s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, u32 *pu32InactiveTime); int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, u8 gtk_key_len, u8 index, - u32 key_rsc_len, const u8 *KeyRSC, + u32 key_rsc_len, const u8 *key_rsc, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode); s32 host_int_add_tx_gtk(struct host_if_drv *hWFIDrv, u8 u8KeyLen, -- GitLab From 6d36c2737b9d642fdf9675de105bfb803c43fd2e Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:12 +0900 Subject: [PATCH 1595/2855] staging: wilc1000: rename pu8RxMic in host_int_add_rx_gtk This patch changes pu8RxMic to rx_mic to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 8 ++++---- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index b50e78dddb896..df364dc69682d 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3276,7 +3276,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, u8 gtk_key_len, u8 index, u32 key_rsc_len, const u8 *key_rsc, - const u8 *pu8RxMic, const u8 *pu8TxMic, + const u8 *rx_mic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode) { int result = 0; @@ -3289,7 +3289,7 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, } memset(&msg, 0, sizeof(struct host_if_msg)); - if (pu8RxMic) + if (rx_mic) u8KeyLen += RX_MIC_KEY_LEN; if (pu8TxMic) @@ -3314,8 +3314,8 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, msg.body.key_info.attr.wpa.key = kmalloc(u8KeyLen, GFP_KERNEL); memcpy(msg.body.key_info.attr.wpa.key, rx_gtk, gtk_key_len); - if (pu8RxMic) - memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic, + if (rx_mic) + memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic, RX_MIC_KEY_LEN); if (pu8TxMic) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 66bb7d7f3eb2f..42c8749117c2d 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -320,7 +320,7 @@ s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, u8 gtk_key_len, u8 index, u32 key_rsc_len, const u8 *key_rsc, - const u8 *pu8RxMic, const u8 *pu8TxMic, + const u8 *rx_mic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode); s32 host_int_add_tx_gtk(struct host_if_drv *hWFIDrv, u8 u8KeyLen, u8 *pu8TxGtk, u8 u8KeyIdx); -- GitLab From 2f79758de5c0bcefd897c78a9b5994f5fe74ab23 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:13 +0900 Subject: [PATCH 1596/2855] staging: wilc1000: rename pu8TxMic in host_int_add_rx_gtk This patch changes pu8TxMic to tx_mic to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 8 ++++---- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index df364dc69682d..7ca924a279e2a 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3276,7 +3276,7 @@ int host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, u8 gtk_key_len, u8 index, u32 key_rsc_len, const u8 *key_rsc, - const u8 *rx_mic, const u8 *pu8TxMic, + const u8 *rx_mic, const u8 *tx_mic, u8 mode, u8 u8Ciphermode) { int result = 0; @@ -3292,7 +3292,7 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, if (rx_mic) u8KeyLen += RX_MIC_KEY_LEN; - if (pu8TxMic) + if (tx_mic) u8KeyLen += TX_MIC_KEY_LEN; if (key_rsc) { @@ -3318,8 +3318,8 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic, RX_MIC_KEY_LEN); - if (pu8TxMic) - memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic, + if (tx_mic) + memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic, TX_MIC_KEY_LEN); msg.body.key_info.attr.wpa.index = index; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 42c8749117c2d..e25f838a188e3 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -320,7 +320,7 @@ s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, u8 gtk_key_len, u8 index, u32 key_rsc_len, const u8 *key_rsc, - const u8 *rx_mic, const u8 *pu8TxMic, + const u8 *rx_mic, const u8 *tx_mic, u8 mode, u8 u8Ciphermode); s32 host_int_add_tx_gtk(struct host_if_drv *hWFIDrv, u8 u8KeyLen, u8 *pu8TxGtk, u8 u8KeyIdx); -- GitLab From 57bfcbc4d33491648500c739ee45594117a7cb0d Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:14 +0900 Subject: [PATCH 1597/2855] staging: wilc1000: rename u8Ciphermode in host_int_add_rx_gtk This patch changes u8Ciphermode to cipher_mode to avoid camelcase. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 ++-- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 7ca924a279e2a..7b647ce65fae7 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3277,7 +3277,7 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, u8 gtk_key_len, u8 index, u32 key_rsc_len, const u8 *key_rsc, const u8 *rx_mic, const u8 *tx_mic, - u8 mode, u8 u8Ciphermode) + u8 mode, u8 cipher_mode) { int result = 0; struct host_if_msg msg; @@ -3306,7 +3306,7 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, if (mode == AP_MODE) { msg.body.key_info.action = ADDKEY_AP; - msg.body.key_info.attr.wpa.mode = u8Ciphermode; + msg.body.key_info.attr.wpa.mode = cipher_mode; } if (mode == STATION_MODE) msg.body.key_info.action = ADDKEY; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index e25f838a188e3..da81b92719798 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -321,7 +321,7 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, u8 gtk_key_len, u8 index, u32 key_rsc_len, const u8 *key_rsc, const u8 *rx_mic, const u8 *tx_mic, - u8 mode, u8 u8Ciphermode); + u8 mode, u8 cipher_mode); s32 host_int_add_tx_gtk(struct host_if_drv *hWFIDrv, u8 u8KeyLen, u8 *pu8TxGtk, u8 u8KeyIdx); s32 host_int_set_pmkid_info(struct host_if_drv *hWFIDrv, -- GitLab From d002fcc0f2de5e05af3c9e753899985985a4d390 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:15 +0900 Subject: [PATCH 1598/2855] staging: wilc1000: rename u8KeyLen in host_int_add_rx_gtk This patch changes u8KeyLen to key_len to avoid camelcase. It is used as local variable in order to save gtk_key_len that is argument of this function. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 7b647ce65fae7..0028bed54eaef 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3281,7 +3281,7 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, { int result = 0; struct host_if_msg msg; - u8 u8KeyLen = gtk_key_len; + u8 key_len = gtk_key_len; if (!hif_drv) { PRINT_ER("driver is null\n"); @@ -3290,10 +3290,10 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, memset(&msg, 0, sizeof(struct host_if_msg)); if (rx_mic) - u8KeyLen += RX_MIC_KEY_LEN; + key_len += RX_MIC_KEY_LEN; if (tx_mic) - u8KeyLen += TX_MIC_KEY_LEN; + key_len += TX_MIC_KEY_LEN; if (key_rsc) { msg.body.key_info.attr.wpa.seq = kmalloc(key_rsc_len, GFP_KERNEL); @@ -3311,7 +3311,7 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, if (mode == STATION_MODE) msg.body.key_info.action = ADDKEY; - msg.body.key_info.attr.wpa.key = kmalloc(u8KeyLen, GFP_KERNEL); + msg.body.key_info.attr.wpa.key = kmalloc(key_len, GFP_KERNEL); memcpy(msg.body.key_info.attr.wpa.key, rx_gtk, gtk_key_len); if (rx_mic) @@ -3323,7 +3323,7 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, TX_MIC_KEY_LEN); msg.body.key_info.attr.wpa.index = index; - msg.body.key_info.attr.wpa.key_len = u8KeyLen; + msg.body.key_info.attr.wpa.key_len = key_len; msg.body.key_info.attr.wpa.seq_len = key_rsc_len; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); -- GitLab From 9bfda3820fe4e7e509aebe3b32b1514b5a615851 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:16 +0900 Subject: [PATCH 1599/2855] staging: wilc1000: use kmemdup in host_int_add_rx_gtk This patch changes kmalloc followed by memcpy to kmemdup. The error checking is also added when kmemdup is failed. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 0028bed54eaef..51b6ddb821f76 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3296,8 +3296,11 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, key_len += TX_MIC_KEY_LEN; if (key_rsc) { - msg.body.key_info.attr.wpa.seq = kmalloc(key_rsc_len, GFP_KERNEL); - memcpy(msg.body.key_info.attr.wpa.seq, key_rsc, key_rsc_len); + msg.body.key_info.attr.wpa.seq = kmemdup(key_rsc, + key_rsc_len, + GFP_KERNEL); + if (!msg.body.key_info.attr.wpa.seq) + return -ENOMEM; } msg.id = HOST_IF_MSG_KEY; @@ -3311,8 +3314,11 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, if (mode == STATION_MODE) msg.body.key_info.action = ADDKEY; - msg.body.key_info.attr.wpa.key = kmalloc(key_len, GFP_KERNEL); - memcpy(msg.body.key_info.attr.wpa.key, rx_gtk, gtk_key_len); + msg.body.key_info.attr.wpa.key = kmemdup(rx_gtk, + key_len, + GFP_KERNEL); + if (!msg.body.key_info.attr.wpa.key) + return -ENOMEM; if (rx_mic) memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic, -- GitLab From 36e4cb257a8b49b72287416edb64e166f3fd0315 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:17 +0900 Subject: [PATCH 1600/2855] staging: wilc1000: remove host_int_add_tx_gtk declaration This patch removes host_int_add_tx_gtk declaration that is defined in host_interface.h file. It can not find any host_int_add_tx_gtk function definition in this driver so just remove it. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index da81b92719798..91fbfa6493ccf 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -322,8 +322,6 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, u32 key_rsc_len, const u8 *key_rsc, const u8 *rx_mic, const u8 *tx_mic, u8 mode, u8 cipher_mode); -s32 host_int_add_tx_gtk(struct host_if_drv *hWFIDrv, u8 u8KeyLen, - u8 *pu8TxGtk, u8 u8KeyIdx); s32 host_int_set_pmkid_info(struct host_if_drv *hWFIDrv, struct host_if_pmkid_attr *pu8PmkidInfoArray); s32 host_int_get_pmkid_info(struct host_if_drv *hWFIDrv, u8 *pu8PmkidInfoArray, -- GitLab From 9d8b9156a67c9a0f00d10f93e7cb51c7b80312cb Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:18 +0900 Subject: [PATCH 1601/2855] staging: wilc1000: remove host_int_get_pmkid_info This patch removes host_int_get_pmkid_info function definition and declaration that is defined at host_interface.c and host_interface.h. This function is defined but not used anywhere in this driver so just remove it. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 14 -------------- drivers/staging/wilc1000/host_interface.h | 2 -- 2 files changed, 16 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 51b6ddb821f76..601558282ac42 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3373,20 +3373,6 @@ s32 host_int_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_at return result; } -s32 host_int_get_pmkid_info(struct host_if_drv *hif_drv, - u8 *pu8PmkidInfoArray, - u32 u32PmkidInfoLen) -{ - struct wid wid; - - wid.id = (u16)WID_PMKID_INFO; - wid.type = WID_STR; - wid.size = u32PmkidInfoLen; - wid.val = pu8PmkidInfoArray; - - return 0; -} - s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv, u8 *pu8PassPhrase, u8 u8Psklength) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 91fbfa6493ccf..dd5a14a222d5d 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -324,8 +324,6 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, u8 mode, u8 cipher_mode); s32 host_int_set_pmkid_info(struct host_if_drv *hWFIDrv, struct host_if_pmkid_attr *pu8PmkidInfoArray); -s32 host_int_get_pmkid_info(struct host_if_drv *hWFIDrv, u8 *pu8PmkidInfoArray, - u32 u32PmkidInfoLen); s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hWFIDrv, u8 *pu8PassPhrase, u8 u8Psklength); -- GitLab From bd6ef876c64cac2e3f4a5d49f47200158736d3d7 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:19 +0900 Subject: [PATCH 1602/2855] staging: wilc1000: remove host_int_set_RSNAConfigPSKPassPhrase This patch removes host_int_set_RSNAConfigPSKPassPhrase function definition and declaration that is defined at host_interface.c and host_interface.h. This function is defined but not used anywhere in this driver so just remove it. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 16 ---------------- drivers/staging/wilc1000/host_interface.h | 3 --- 2 files changed, 19 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 601558282ac42..fb6f353b6df2f 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3373,22 +3373,6 @@ s32 host_int_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_at return result; } -s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv, - u8 *pu8PassPhrase, - u8 u8Psklength) -{ - struct wid wid; - - if ((u8Psklength > 7) && (u8Psklength < 65)) { - wid.id = (u16)WID_11I_PSK; - wid.type = WID_STR; - wid.val = pu8PassPhrase; - wid.size = u8Psklength; - } - - return 0; -} - s32 hif_get_mac_address(struct host_if_drv *hif_drv, u8 *pu8MacAddress) { s32 result = 0; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index dd5a14a222d5d..8113d7656bc5b 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -324,9 +324,6 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, u8 mode, u8 cipher_mode); s32 host_int_set_pmkid_info(struct host_if_drv *hWFIDrv, struct host_if_pmkid_attr *pu8PmkidInfoArray); -s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hWFIDrv, - u8 *pu8PassPhrase, - u8 u8Psklength); s32 host_int_get_RSNAConfigPSKPassPhrase(struct host_if_drv *hWFIDrv, u8 *pu8PassPhrase, u8 u8Psklength); s32 hif_get_mac_address(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); -- GitLab From cb12ac574fe0edf7a7812e0ec9af5b94c394580f Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:20 +0900 Subject: [PATCH 1603/2855] staging: wilc1000: remove host_int_get_RSNAConfigPSKPassPhrase This patch removes host_int_get_RSNAConfigPSKPassPhrase function definition and declaration that is defined at host_interface.c and host_interface.h. This function is defined but not used anywhere in this driver so just remove it. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 13 ------------- drivers/staging/wilc1000/host_interface.h | 2 -- 2 files changed, 15 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index fb6f353b6df2f..f7bbad0de708d 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3413,19 +3413,6 @@ s32 host_int_set_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress) return result; } -s32 host_int_get_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv, - u8 *pu8PassPhrase, u8 u8Psklength) -{ - struct wid wid; - - wid.id = (u16)WID_11I_PSK; - wid.type = WID_STR; - wid.size = u8Psklength; - wid.val = pu8PassPhrase; - - return 0; -} - s32 host_int_set_start_scan_req(struct host_if_drv *hif_drv, u8 scanSource) { struct wid wid; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 8113d7656bc5b..976067a34db07 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -324,8 +324,6 @@ int host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, u8 mode, u8 cipher_mode); s32 host_int_set_pmkid_info(struct host_if_drv *hWFIDrv, struct host_if_pmkid_attr *pu8PmkidInfoArray); -s32 host_int_get_RSNAConfigPSKPassPhrase(struct host_if_drv *hWFIDrv, - u8 *pu8PassPhrase, u8 u8Psklength); s32 hif_get_mac_address(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); s32 host_int_set_MacAddress(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); int host_int_wait_msg_queue_idle(void); -- GitLab From a17a1f2bd204a10082e7e88bdbc433a85cc92e1e Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:21 +0900 Subject: [PATCH 1604/2855] staging: wilc1000: remove host_int_set_start_scan_req This patch removes host_int_set_start_scan_req function definition and declaration that is defined at host_interface.c and host_interface.h. This function is defined but not used anywhere in this driver so that just remove it. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 12 ------------ drivers/staging/wilc1000/host_interface.h | 1 - 2 files changed, 13 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index f7bbad0de708d..174cb6adb64c8 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3413,18 +3413,6 @@ s32 host_int_set_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress) return result; } -s32 host_int_set_start_scan_req(struct host_if_drv *hif_drv, u8 scanSource) -{ - struct wid wid; - - wid.id = (u16)WID_START_SCAN_REQ; - wid.type = WID_CHAR; - wid.val = (s8 *)&scanSource; - wid.size = sizeof(char); - - return 0; -} - s32 host_int_get_start_scan_req(struct host_if_drv *hif_drv, u8 *pu8ScanSource) { struct wid wid; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 976067a34db07..14ce3972711f6 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -327,7 +327,6 @@ s32 host_int_set_pmkid_info(struct host_if_drv *hWFIDrv, s32 hif_get_mac_address(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); s32 host_int_set_MacAddress(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); int host_int_wait_msg_queue_idle(void); -s32 host_int_set_start_scan_req(struct host_if_drv *hWFIDrv, u8 scanSource); s32 host_int_get_start_scan_req(struct host_if_drv *hWFIDrv, u8 *pu8ScanSource); s32 host_int_set_join_req(struct host_if_drv *hWFIDrv, u8 *pu8bssid, const u8 *pu8ssid, size_t ssidLen, -- GitLab From 9c2a6f282636214e6cfb7e4c454e84151f31467b Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:22 +0900 Subject: [PATCH 1605/2855] staging: wilc1000: remove host_int_get_start_scan_req This patch removes host_int_get_start_scan_req function definition and declaration that is defined at host_interface.c and host_interface.h. This function is defined but not used anywhere in this driver so just remove it. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 12 ------------ drivers/staging/wilc1000/host_interface.h | 1 - 2 files changed, 13 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 174cb6adb64c8..057534518f49c 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3413,18 +3413,6 @@ s32 host_int_set_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress) return result; } -s32 host_int_get_start_scan_req(struct host_if_drv *hif_drv, u8 *pu8ScanSource) -{ - struct wid wid; - - wid.id = (u16)WID_START_SCAN_REQ; - wid.type = WID_CHAR; - wid.val = (s8 *)pu8ScanSource; - wid.size = sizeof(char); - - return 0; -} - s32 host_int_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid, const u8 *pu8ssid, size_t ssidLen, const u8 *pu8IEs, size_t IEsLen, diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 14ce3972711f6..52622dfd97359 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -327,7 +327,6 @@ s32 host_int_set_pmkid_info(struct host_if_drv *hWFIDrv, s32 hif_get_mac_address(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); s32 host_int_set_MacAddress(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); int host_int_wait_msg_queue_idle(void); -s32 host_int_get_start_scan_req(struct host_if_drv *hWFIDrv, u8 *pu8ScanSource); s32 host_int_set_join_req(struct host_if_drv *hWFIDrv, u8 *pu8bssid, const u8 *pu8ssid, size_t ssidLen, const u8 *pu8IEs, size_t IEsLen, -- GitLab From 3fbb77f2b3aacd054564e7431c17f1f44fdf65c3 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:23 +0900 Subject: [PATCH 1606/2855] staging: wilc1000: remove host_int_disconnect_station This patch removes host_int_disconnect_station function definition and declaration that is defined at host_interface.c and host_interface.h. This function is defined but not used anywhere so just remove it. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 12 ------------ drivers/staging/wilc1000/host_interface.h | 1 - 2 files changed, 13 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 057534518f49c..676b3c7afeb02 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3529,18 +3529,6 @@ s32 host_int_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode) return result; } -s32 host_int_disconnect_station(struct host_if_drv *hif_drv, u8 assoc_id) -{ - struct wid wid; - - wid.id = (u16)WID_DISCONNECT; - wid.type = WID_CHAR; - wid.val = (s8 *)&assoc_id; - wid.size = sizeof(char); - - return 0; -} - s32 host_int_get_assoc_req_info(struct host_if_drv *hif_drv, u8 *pu8AssocReqInfo, u32 u32AssocReqInfoLen) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 52622dfd97359..e51a56351f3dd 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -335,7 +335,6 @@ s32 host_int_set_join_req(struct host_if_drv *hWFIDrv, u8 *pu8bssid, u8 u8channel, void *pJoinParams); s32 host_int_flush_join_req(struct host_if_drv *hWFIDrv); s32 host_int_disconnect(struct host_if_drv *hWFIDrv, u16 u16ReasonCode); -s32 host_int_disconnect_station(struct host_if_drv *hWFIDrv, u8 assoc_id); s32 host_int_get_assoc_req_info(struct host_if_drv *hWFIDrv, u8 *pu8AssocReqInfo, u32 u32AssocReqInfoLen); -- GitLab From 409bee3de116090091e214aa0396143314295676 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:24 +0900 Subject: [PATCH 1607/2855] staging: wilc1000: remove host_int_get_assoc_req_info This patch removes host_int_get_assoc_req_info function definition and declaration that is defined at host_interface.c and host_interface.h. This function is defined but not used anywhere in this driver so just remove it. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 14 -------------- drivers/staging/wilc1000/host_interface.h | 3 --- 2 files changed, 17 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 676b3c7afeb02..ff15179140692 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3529,20 +3529,6 @@ s32 host_int_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode) return result; } -s32 host_int_get_assoc_req_info(struct host_if_drv *hif_drv, - u8 *pu8AssocReqInfo, - u32 u32AssocReqInfoLen) -{ - struct wid wid; - - wid.id = (u16)WID_ASSOC_REQ_INFO; - wid.type = WID_STR; - wid.val = pu8AssocReqInfo; - wid.size = u32AssocReqInfoLen; - - return 0; -} - s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv, u8 *pu8AssocRespInfo, u32 u32MaxAssocRespInfoLen, diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index e51a56351f3dd..887045844085f 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -335,9 +335,6 @@ s32 host_int_set_join_req(struct host_if_drv *hWFIDrv, u8 *pu8bssid, u8 u8channel, void *pJoinParams); s32 host_int_flush_join_req(struct host_if_drv *hWFIDrv); s32 host_int_disconnect(struct host_if_drv *hWFIDrv, u16 u16ReasonCode); -s32 host_int_get_assoc_req_info(struct host_if_drv *hWFIDrv, - u8 *pu8AssocReqInfo, - u32 u32AssocReqInfoLen); s32 host_int_get_assoc_res_info(struct host_if_drv *hWFIDrv, u8 *pu8AssocRespInfo, u32 u32MaxAssocRespInfoLen, -- GitLab From e3b14ba3779d4e4d5d72801bbe14bb11c052aaa8 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Sun, 8 Nov 2015 16:49:25 +0900 Subject: [PATCH 1608/2855] staging: wilc1000: remove host_int_get_rx_power_level This patch removes host_int_get_rx_power_level function definition and declaration that is defined at host_interface.c and host_interface.h. This function is defined but not used anywhere in this driver so just remove it. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 14 -------------- drivers/staging/wilc1000/host_interface.h | 3 --- 2 files changed, 17 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index ff15179140692..5bf9a55ce4ea1 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3560,20 +3560,6 @@ s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv, return result; } -s32 host_int_get_rx_power_level(struct host_if_drv *hif_drv, - u8 *pu8RxPowerLevel, - u32 u32RxPowerLevelLen) -{ - struct wid wid; - - wid.id = (u16)WID_RX_POWER_LEVEL; - wid.type = WID_STR; - wid.val = pu8RxPowerLevel; - wid.size = u32RxPowerLevelLen; - - return 0; -} - int host_int_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel) { int result; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 887045844085f..c01f441a780b0 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -339,9 +339,6 @@ s32 host_int_get_assoc_res_info(struct host_if_drv *hWFIDrv, u8 *pu8AssocRespInfo, u32 u32MaxAssocRespInfoLen, u32 *pu32RcvdAssocRespInfoLen); -s32 host_int_get_rx_power_level(struct host_if_drv *hWFIDrv, - u8 *pu8RxPowerLevel, - u32 u32RxPowerLevelLen); int host_int_set_mac_chnl_num(struct host_if_drv *wfi_drv, u8 channel); s32 host_int_get_host_chnl_num(struct host_if_drv *hWFIDrv, u8 *pu8ChNo); s32 host_int_get_rssi(struct host_if_drv *hWFIDrv, s8 *ps8Rssi); -- GitLab From 5f550d930791b4b78f2c946060ee7cca3c03b113 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:04:52 +0100 Subject: [PATCH 1609/2855] staging/wilc1000: remove unused functions A number of symbols in the wilc1000 driver are completely unused and can be removed. This includes two variables that are only written but not read. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 295 ------------------ drivers/staging/wilc1000/host_interface.h | 19 -- drivers/staging/wilc1000/linux_wlan_sdio.c | 11 - drivers/staging/wilc1000/linux_wlan_sdio.h | 1 - drivers/staging/wilc1000/linux_wlan_spi.c | 14 - drivers/staging/wilc1000/linux_wlan_spi.h | 1 - drivers/staging/wilc1000/wilc_sdio.c | 56 ---- drivers/staging/wilc1000/wilc_spi.c | 225 ------------- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 36 --- drivers/staging/wilc1000/wilc_wlan.c | 4 - 10 files changed, 662 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index d5b7725ec2bf5..6c205b97293db 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3366,36 +3366,6 @@ s32 host_int_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_at return result; } -s32 host_int_get_pmkid_info(struct host_if_drv *hif_drv, - u8 *pu8PmkidInfoArray, - u32 u32PmkidInfoLen) -{ - struct wid wid; - - wid.id = (u16)WID_PMKID_INFO; - wid.type = WID_STR; - wid.size = u32PmkidInfoLen; - wid.val = pu8PmkidInfoArray; - - return 0; -} - -s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv, - u8 *pu8PassPhrase, - u8 u8Psklength) -{ - struct wid wid; - - if ((u8Psklength > 7) && (u8Psklength < 65)) { - wid.id = (u16)WID_11I_PSK; - wid.type = WID_STR; - wid.val = pu8PassPhrase; - wid.size = u8Psklength; - } - - return 0; -} - s32 hif_get_mac_address(struct host_if_drv *hif_drv, u8 *pu8MacAddress) { s32 result = 0; @@ -3436,19 +3406,6 @@ s32 host_int_set_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress) return result; } -s32 host_int_get_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv, - u8 *pu8PassPhrase, u8 u8Psklength) -{ - struct wid wid; - - wid.id = (u16)WID_11I_PSK; - wid.type = WID_STR; - wid.size = u8Psklength; - wid.val = pu8PassPhrase; - - return 0; -} - s32 host_int_set_start_scan_req(struct host_if_drv *hif_drv, u8 scanSource) { struct wid wid; @@ -3461,18 +3418,6 @@ s32 host_int_set_start_scan_req(struct host_if_drv *hif_drv, u8 scanSource) return 0; } -s32 host_int_get_start_scan_req(struct host_if_drv *hif_drv, u8 *pu8ScanSource) -{ - struct wid wid; - - wid.id = (u16)WID_START_SCAN_REQ; - wid.type = WID_CHAR; - wid.val = (s8 *)pu8ScanSource; - wid.size = sizeof(char); - - return 0; -} - s32 host_int_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid, const u8 *pu8ssid, size_t ssidLen, const u8 *pu8IEs, size_t IEsLen, @@ -3589,31 +3534,6 @@ s32 host_int_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode) return result; } -s32 host_int_disconnect_station(struct host_if_drv *hif_drv, u8 assoc_id) -{ - struct wid wid; - - wid.id = (u16)WID_DISCONNECT; - wid.type = WID_CHAR; - wid.val = (s8 *)&assoc_id; - wid.size = sizeof(char); - - return 0; -} - -s32 host_int_get_assoc_req_info(struct host_if_drv *hif_drv, - u8 *pu8AssocReqInfo, - u32 u32AssocReqInfoLen) -{ - struct wid wid; - - wid.id = (u16)WID_ASSOC_REQ_INFO; - wid.type = WID_STR; - wid.val = pu8AssocReqInfo; - wid.size = u32AssocReqInfoLen; - - return 0; -} s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv, u8 *pu8AssocRespInfo, @@ -3646,20 +3566,6 @@ s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv, return result; } -s32 host_int_get_rx_power_level(struct host_if_drv *hif_drv, - u8 *pu8RxPowerLevel, - u32 u32RxPowerLevelLen) -{ - struct wid wid; - - wid.id = (u16)WID_RX_POWER_LEVEL; - wid.type = WID_STR; - wid.val = pu8RxPowerLevel; - wid.size = u32RxPowerLevelLen; - - return 0; -} - int host_int_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel) { int result; @@ -3740,31 +3646,6 @@ int host_int_set_operation_mode(struct host_if_drv *hif_drv, u32 mode) return result; } -s32 host_int_get_host_chnl_num(struct host_if_drv *hif_drv, u8 *pu8ChNo) -{ - s32 result = 0; - struct host_if_msg msg; - - if (!hif_drv) { - PRINT_ER("driver is null\n"); - return -EFAULT; - } - - memset(&msg, 0, sizeof(struct host_if_msg)); - - msg.id = HOST_IF_MSG_GET_CHNL; - msg.drv = hif_drv; - - result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); - if (result) - PRINT_ER("wilc mq send fail\n"); - down(&hif_drv->sem_get_chnl); - - *pu8ChNo = ch_no; - - return result; -} - s32 host_int_get_inactive_time(struct host_if_drv *hif_drv, const u8 *mac, u32 *pu32InactiveTime) { @@ -3793,34 +3674,6 @@ s32 host_int_get_inactive_time(struct host_if_drv *hif_drv, return result; } -s32 host_int_test_get_int_wid(struct host_if_drv *hif_drv, u32 *pu32TestMemAddr) -{ - s32 result = 0; - struct wid wid; - - if (!hif_drv) { - PRINT_ER("driver is null\n"); - return -EFAULT; - } - - wid.id = (u16)WID_MEMORY_ADDRESS; - wid.type = WID_INT; - wid.val = (s8 *)pu32TestMemAddr; - wid.size = sizeof(u32); - - result = send_config_pkt(GET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); - - if (result) { - PRINT_ER("Failed to get wid value\n"); - return -EINVAL; - } else { - PRINT_D(HOSTINF_DBG, "Successfully got wid value\n"); - } - - return result; -} - s32 host_int_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi) { s32 result = 0; @@ -3848,33 +3701,6 @@ s32 host_int_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi) return result; } -s32 host_int_get_link_speed(struct host_if_drv *hif_drv, s8 *ps8lnkspd) -{ - struct host_if_msg msg; - s32 result = 0; - - memset(&msg, 0, sizeof(struct host_if_msg)); - msg.id = HOST_IF_MSG_GET_LINKSPEED; - msg.drv = hif_drv; - - result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); - if (result) { - PRINT_ER("Failed to send GET_LINKSPEED to message queue "); - return -EFAULT; - } - - down(&hif_drv->sem_get_link_speed); - - if (!ps8lnkspd) { - PRINT_ER("LINKSPEED pointer value is null"); - return -EFAULT; - } - - *ps8lnkspd = link_speed; - - return result; -} - s32 host_int_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics) { s32 result = 0; @@ -3969,99 +3795,6 @@ s32 hif_set_cfg(struct host_if_drv *hif_drv, return result; } -s32 hif_get_cfg(struct host_if_drv *hif_drv, u16 u16WID, u16 *pu16WID_Value) -{ - s32 result = 0; - - down(&hif_drv->sem_cfg_values); - - if (!hif_drv) { - PRINT_ER("hif_drv NULL\n"); - return -EFAULT; - } - PRINT_D(HOSTINF_DBG, "Getting configuration parameters\n"); - switch (u16WID) { - case WID_BSS_TYPE: - *pu16WID_Value = (u16)hif_drv->cfg_values.bss_type; - break; - - case WID_AUTH_TYPE: - *pu16WID_Value = (u16)hif_drv->cfg_values.auth_type; - break; - - case WID_AUTH_TIMEOUT: - *pu16WID_Value = hif_drv->cfg_values.auth_timeout; - break; - - case WID_POWER_MANAGEMENT: - *pu16WID_Value = (u16)hif_drv->cfg_values.power_mgmt_mode; - break; - - case WID_SHORT_RETRY_LIMIT: - *pu16WID_Value = hif_drv->cfg_values.short_retry_limit; - break; - - case WID_LONG_RETRY_LIMIT: - *pu16WID_Value = hif_drv->cfg_values.long_retry_limit; - break; - - case WID_FRAG_THRESHOLD: - *pu16WID_Value = hif_drv->cfg_values.frag_threshold; - break; - - case WID_RTS_THRESHOLD: - *pu16WID_Value = hif_drv->cfg_values.rts_threshold; - break; - - case WID_PREAMBLE: - *pu16WID_Value = (u16)hif_drv->cfg_values.preamble_type; - break; - - case WID_SHORT_SLOT_ALLOWED: - *pu16WID_Value = (u16)hif_drv->cfg_values.short_slot_allowed; - break; - - case WID_11N_TXOP_PROT_DISABLE: - *pu16WID_Value = (u16)hif_drv->cfg_values.txop_prot_disabled; - break; - - case WID_BEACON_INTERVAL: - *pu16WID_Value = hif_drv->cfg_values.beacon_interval; - break; - - case WID_DTIM_PERIOD: - *pu16WID_Value = (u16)hif_drv->cfg_values.dtim_period; - break; - - case WID_SITE_SURVEY: - *pu16WID_Value = (u16)hif_drv->cfg_values.site_survey_enabled; - break; - - case WID_SITE_SURVEY_SCAN_TIME: - *pu16WID_Value = hif_drv->cfg_values.site_survey_scan_time; - break; - - case WID_ACTIVE_SCAN_TIME: - *pu16WID_Value = hif_drv->cfg_values.active_scan_time; - break; - - case WID_PASSIVE_SCAN_TIME: - *pu16WID_Value = hif_drv->cfg_values.passive_scan_time; - break; - - case WID_CURRENT_TX_RATE: - *pu16WID_Value = hif_drv->cfg_values.curr_tx_rate; - break; - - default: - break; - } - - up(&hif_drv->sem_cfg_values); - - return result; -} - static void GetPeriodicRSSI(unsigned long arg) { struct host_if_drv *hif_drv = (struct host_if_drv *)arg; @@ -4916,34 +4649,6 @@ void host_int_freeJoinParams(void *pJoinParams) PRINT_ER("Unable to FREE null pointer\n"); } -s32 host_int_delBASession(struct host_if_drv *hif_drv, char *pBSSID, char TID) -{ - s32 result = 0; - struct host_if_msg msg; - struct ba_session_info *pBASessionInfo = &msg.body.session_info; - - if (!hif_drv) { - PRINT_ER("driver is null\n"); - return -EFAULT; - } - - memset(&msg, 0, sizeof(struct host_if_msg)); - - msg.id = HOST_IF_MSG_DEL_BA_SESSION; - - memcpy(pBASessionInfo->bssid, pBSSID, ETH_ALEN); - pBASessionInfo->tid = TID; - msg.drv = hif_drv; - - result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); - if (result) - PRINT_ER("wilc_mq_send fail\n"); - - down(&hif_sema_wait_response); - - return result; -} - s32 host_int_del_All_Rx_BASession(struct host_if_drv *hif_drv, char *pBSSID, char TID) diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 57e1d424afdc4..c1ed2e236ee22 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -326,18 +326,10 @@ s32 host_int_add_tx_gtk(struct host_if_drv *hWFIDrv, u8 u8KeyLen, u8 *pu8TxGtk, u8 u8KeyIdx); s32 host_int_set_pmkid_info(struct host_if_drv *hWFIDrv, struct host_if_pmkid_attr *pu8PmkidInfoArray); -s32 host_int_get_pmkid_info(struct host_if_drv *hWFIDrv, u8 *pu8PmkidInfoArray, - u32 u32PmkidInfoLen); -s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hWFIDrv, - u8 *pu8PassPhrase, - u8 u8Psklength); -s32 host_int_get_RSNAConfigPSKPassPhrase(struct host_if_drv *hWFIDrv, - u8 *pu8PassPhrase, u8 u8Psklength); s32 hif_get_mac_address(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); s32 host_int_set_MacAddress(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); int host_int_wait_msg_queue_idle(void); s32 host_int_set_start_scan_req(struct host_if_drv *hWFIDrv, u8 scanSource); -s32 host_int_get_start_scan_req(struct host_if_drv *hWFIDrv, u8 *pu8ScanSource); s32 host_int_set_join_req(struct host_if_drv *hWFIDrv, u8 *pu8bssid, const u8 *pu8ssid, size_t ssidLen, const u8 *pu8IEs, size_t IEsLen, @@ -346,21 +338,12 @@ s32 host_int_set_join_req(struct host_if_drv *hWFIDrv, u8 *pu8bssid, u8 u8channel, void *pJoinParams); s32 host_int_flush_join_req(struct host_if_drv *hWFIDrv); s32 host_int_disconnect(struct host_if_drv *hWFIDrv, u16 u16ReasonCode); -s32 host_int_disconnect_station(struct host_if_drv *hWFIDrv, u8 assoc_id); -s32 host_int_get_assoc_req_info(struct host_if_drv *hWFIDrv, - u8 *pu8AssocReqInfo, - u32 u32AssocReqInfoLen); s32 host_int_get_assoc_res_info(struct host_if_drv *hWFIDrv, u8 *pu8AssocRespInfo, u32 u32MaxAssocRespInfoLen, u32 *pu32RcvdAssocRespInfoLen); -s32 host_int_get_rx_power_level(struct host_if_drv *hWFIDrv, - u8 *pu8RxPowerLevel, - u32 u32RxPowerLevelLen); int host_int_set_mac_chnl_num(struct host_if_drv *wfi_drv, u8 channel); -s32 host_int_get_host_chnl_num(struct host_if_drv *hWFIDrv, u8 *pu8ChNo); s32 host_int_get_rssi(struct host_if_drv *hWFIDrv, s8 *ps8Rssi); -s32 host_int_get_link_speed(struct host_if_drv *hWFIDrv, s8 *ps8lnkspd); s32 host_int_scan(struct host_if_drv *hWFIDrv, u8 u8ScanSource, u8 u8ScanType, u8 *pu8ChnlFreqList, u8 u8ChnlListLen, const u8 *pu8IEs, @@ -368,7 +351,6 @@ s32 host_int_scan(struct host_if_drv *hWFIDrv, u8 u8ScanSource, void *pvUserArg, struct hidden_network *pstrHiddenNetwork); s32 hif_set_cfg(struct host_if_drv *hWFIDrv, struct cfg_param_val *pstrCfgParamVal); -s32 hif_get_cfg(struct host_if_drv *hWFIDrv, u16 u16WID, u16 *pu16WID_Value); s32 host_int_init(struct net_device *dev, struct host_if_drv **phWFIDrv); s32 host_int_deinit(struct host_if_drv *hWFIDrv); s32 host_int_add_beacon(struct host_if_drv *hWFIDrv, u32 u32Interval, @@ -394,7 +376,6 @@ s32 host_int_setup_multicast_filter(struct host_if_drv *hWFIDrv, s32 host_int_setup_ipaddress(struct host_if_drv *hWFIDrv, u8 *pu8IPAddr, u8 idx); -s32 host_int_delBASession(struct host_if_drv *hWFIDrv, char *pBSSID, char TID); s32 host_int_del_All_Rx_BASession(struct host_if_drv *hWFIDrv, char *pBSSID, char TID); diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index e854d376878fe..9e8ba04ca9c8d 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -226,17 +226,6 @@ int linux_sdio_init(void) return 1; } -void linux_sdio_deinit(void *pv) -{ - - /** - * TODO : - **/ - - - sdio_unregister_driver(&wilc_bus); -} - int linux_sdio_set_max_speed(void) { return linux_sdio_set_speed(MAX_SPEED); diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.h b/drivers/staging/wilc1000/linux_wlan_sdio.h index 6f42bc75b5076..7c59b2f6543ab 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.h +++ b/drivers/staging/wilc1000/linux_wlan_sdio.h @@ -4,7 +4,6 @@ extern struct sdio_driver wilc_bus; #include int linux_sdio_init(void); -void linux_sdio_deinit(void *); int linux_sdio_cmd52(sdio_cmd52_t *cmd); int linux_sdio_cmd53(sdio_cmd53_t *cmd); int enable_sdio_interrupt(void); diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index 73c788f602c02..3655077a936f7 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -42,7 +42,6 @@ static u32 SPEED = MIN_SPEED; struct spi_device *wilc_spi_dev; -void linux_spi_deinit(void *vp); static int __init wilc_bus_probe(struct spi_device *spi) { @@ -80,19 +79,6 @@ struct spi_driver wilc_bus __refdata = { .remove = __exit_p(wilc_bus_remove), }; - -void linux_spi_deinit(void *vp) -{ - - spi_unregister_driver(&wilc_bus); - - SPEED = MIN_SPEED; - PRINT_ER("@@@@@@@@@@@@ restore SPI speed to %d @@@@@@@@@\n", SPEED); - -} - - - int linux_spi_init(void) { int ret = 1; diff --git a/drivers/staging/wilc1000/linux_wlan_spi.h b/drivers/staging/wilc1000/linux_wlan_spi.h index b9561003ecf0a..2edd97b4c5ccf 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.h +++ b/drivers/staging/wilc1000/linux_wlan_spi.h @@ -6,7 +6,6 @@ extern struct spi_device *wilc_spi_dev; extern struct spi_driver wilc_bus; int linux_spi_init(void); -void linux_spi_deinit(void *vp); int linux_spi_write(u8 *b, u32 len); int linux_spi_read(u8 *rb, u32 rlen); int linux_spi_write_read(u8 *wb, u8 *rb, u32 rlen); diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index 8aacf55e5eb80..d26e4cf0f4369 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -157,67 +157,11 @@ static int sdio_clear_int(void) } -u32 sdio_xfer_cnt(void) -{ - u32 cnt = 0; - sdio_cmd52_t cmd; - - cmd.read_write = 0; - cmd.function = 1; - cmd.raw = 0; - cmd.address = 0x1C; - cmd.data = 0; - linux_sdio_cmd52(&cmd); - cnt = cmd.data; - - cmd.read_write = 0; - cmd.function = 1; - cmd.raw = 0; - cmd.address = 0x1D; - cmd.data = 0; - linux_sdio_cmd52(&cmd); - cnt |= (cmd.data << 8); - - cmd.read_write = 0; - cmd.function = 1; - cmd.raw = 0; - cmd.address = 0x1E; - cmd.data = 0; - linux_sdio_cmd52(&cmd); - cnt |= (cmd.data << 16); - - return cnt; -} - /******************************************** * * Sdio interfaces * ********************************************/ -int sdio_check_bs(void) -{ - sdio_cmd52_t cmd; - - /** - * poll until BS is 0 - **/ - cmd.read_write = 0; - cmd.function = 0; - cmd.raw = 0; - cmd.address = 0xc; - cmd.data = 0; - if (!linux_sdio_cmd52(&cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get BS register...\n"); - goto _fail_; - } - - return 1; - -_fail_: - - return 0; -} - static int sdio_write_reg(u32 addr, u32 data) { #ifdef BIG_ENDIAN diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 3741836dad419..9af35d1ef99e3 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -108,163 +108,6 @@ static u8 crc7(u8 crc, const u8 *buffer, u32 len) #define DATA_PKT_SZ_8K (8 * 1024) #define DATA_PKT_SZ DATA_PKT_SZ_8K -static int spi_cmd(u8 cmd, u32 adr, u32 data, u32 sz, u8 clockless) -{ - u8 bc[9]; - int len = 5; - int result = N_OK; - - bc[0] = cmd; - switch (cmd) { - case CMD_SINGLE_READ: /* single word (4 bytes) read */ - bc[1] = (u8)(adr >> 16); - bc[2] = (u8)(adr >> 8); - bc[3] = (u8)adr; - len = 5; - break; - - case CMD_INTERNAL_READ: /* internal register read */ - bc[1] = (u8)(adr >> 8); - if (clockless) - bc[1] |= BIT(7); - bc[2] = (u8)adr; - bc[3] = 0x00; - len = 5; - break; - - case CMD_TERMINATE: /* termination */ - bc[1] = 0x00; - bc[2] = 0x00; - bc[3] = 0x00; - len = 5; - break; - - case CMD_REPEAT: /* repeat */ - bc[1] = 0x00; - bc[2] = 0x00; - bc[3] = 0x00; - len = 5; - break; - - case CMD_RESET: /* reset */ - bc[1] = 0xff; - bc[2] = 0xff; - bc[3] = 0xff; - len = 5; - break; - - case CMD_DMA_WRITE: /* dma write */ - case CMD_DMA_READ: /* dma read */ - bc[1] = (u8)(adr >> 16); - bc[2] = (u8)(adr >> 8); - bc[3] = (u8)adr; - bc[4] = (u8)(sz >> 8); - bc[5] = (u8)(sz); - len = 7; - break; - - case CMD_DMA_EXT_WRITE: /* dma extended write */ - case CMD_DMA_EXT_READ: /* dma extended read */ - bc[1] = (u8)(adr >> 16); - bc[2] = (u8)(adr >> 8); - bc[3] = (u8)adr; - bc[4] = (u8)(sz >> 16); - bc[5] = (u8)(sz >> 8); - bc[6] = (u8)(sz); - len = 8; - break; - - case CMD_INTERNAL_WRITE: /* internal register write */ - bc[1] = (u8)(adr >> 8); - if (clockless) - bc[1] |= BIT(7); - bc[2] = (u8)(adr); - bc[3] = (u8)(data >> 24); - bc[4] = (u8)(data >> 16); - bc[5] = (u8)(data >> 8); - bc[6] = (u8)(data); - len = 8; - break; - - case CMD_SINGLE_WRITE: /* single word write */ - bc[1] = (u8)(adr >> 16); - bc[2] = (u8)(adr >> 8); - bc[3] = (u8)(adr); - bc[4] = (u8)(data >> 24); - bc[5] = (u8)(data >> 16); - bc[6] = (u8)(data >> 8); - bc[7] = (u8)(data); - len = 9; - break; - - default: - result = N_FAIL; - break; - } - - if (result) { - if (!g_spi.crc_off) - bc[len - 1] = (crc7(0x7f, (const u8 *)&bc[0], len - 1)) << 1; - else - len -= 1; - - if (!linux_spi_write(bc, len)) { - PRINT_ER("[wilc spi]: Failed cmd write, bus error...\n"); - result = N_FAIL; - } - } - - return result; -} - -static int spi_cmd_rsp(u8 cmd) -{ - u8 rsp; - int result = N_OK; - - /** - * Command/Control response - **/ - if ((cmd == CMD_RESET) || - (cmd == CMD_TERMINATE) || - (cmd == CMD_REPEAT)) { - if (!linux_spi_read(&rsp, 1)) { - result = N_FAIL; - goto _fail_; - } - } - - if (!linux_spi_read(&rsp, 1)) { - PRINT_ER("[wilc spi]: Failed cmd response read, bus error...\n"); - result = N_FAIL; - goto _fail_; - } - - if (rsp != cmd) { - PRINT_ER("[wilc spi]: Failed cmd response, cmd (%02x), resp (%02x)\n", cmd, rsp); - result = N_FAIL; - goto _fail_; - } - - /** - * State response - **/ - if (!linux_spi_read(&rsp, 1)) { - PRINT_ER("[wilc spi]: Failed cmd state read, bus error...\n"); - result = N_FAIL; - goto _fail_; - } - - if (rsp != 0x00) { - PRINT_ER("[wilc spi]: Failed cmd state response state (%02x)\n", rsp); - result = N_FAIL; - } - -_fail_: - - return result; -} - static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless) { u8 wb[32], rb[32]; @@ -604,74 +447,6 @@ _error_: return result; } -static int spi_data_read(u8 *b, u32 sz) -{ - int retry, ix, nbytes; - int result = N_OK; - u8 crc[2]; - u8 rsp; - - /** - * Data - **/ - ix = 0; - do { - if (sz <= DATA_PKT_SZ) - nbytes = sz; - else - nbytes = DATA_PKT_SZ; - - /** - * Data Respnose header - **/ - retry = 10; - do { - if (!linux_spi_read(&rsp, 1)) { - PRINT_ER("[wilc spi]: Failed data response read, bus error...\n"); - result = N_FAIL; - break; - } - if (((rsp >> 4) & 0xf) == 0xf) - break; - } while (retry--); - - if (result == N_FAIL) - break; - - if (retry <= 0) { - PRINT_ER("[wilc spi]: Failed data response read...(%02x)\n", rsp); - result = N_FAIL; - break; - } - - /** - * Read bytes - **/ - if (!linux_spi_read(&b[ix], nbytes)) { - PRINT_ER("[wilc spi]: Failed data block read, bus error...\n"); - result = N_FAIL; - break; - } - - /** - * Read Crc - **/ - if (!g_spi.crc_off) { - if (!linux_spi_read(crc, 2)) { - PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n"); - result = N_FAIL; - break; - } - } - - ix += nbytes; - sz -= nbytes; - - } while (sz); - - return result; -} - static int spi_data_write(u8 *b, u32 sz) { int ix, nbytes; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 6f405221030cb..849f86b5ff309 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -470,42 +470,6 @@ static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNet } -/** - * @brief WILC_WFI_Set_PMKSA - * @details Check if pmksa is cached and set it. - * @param[in] - * @return int : Return 0 on Success - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ -int WILC_WFI_Set_PMKSA(u8 *bssid, struct wilc_priv *priv) -{ - u32 i; - s32 s32Error = 0; - - - for (i = 0; i < priv->pmkid_list.numpmkid; i++) { - - if (!memcmp(bssid, priv->pmkid_list.pmkidlist[i].bssid, - ETH_ALEN)) { - PRINT_D(CFG80211_DBG, "PMKID successful comparison"); - - /*If bssid is found, set the values*/ - s32Error = host_int_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list); - - if (s32Error != 0) - PRINT_ER("Error in pmkid\n"); - - break; - } - } - - return s32Error; - - -} - /** * @brief CfgConnectResult * @details diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 9d257b06c8537..f702cca2095ad 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -193,8 +193,6 @@ static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe) return 0; } -u32 total_acks = 0, dropped_acks = 0; - #ifdef TCP_ACK_FILTER struct ack_session_info; struct ack_session_info { @@ -249,7 +247,6 @@ static inline int update_tcp_session(u32 index, u32 ack) static inline int add_tcp_pending_ack(u32 ack, u32 session_index, struct txq_entry_t *txqe) { - total_acks++; if (pending_acks < MAX_PENDING_ACKS) { pending_acks_info[pending_base + pending_acks].ack_num = ack; pending_acks_info[pending_base + pending_acks].txqe = txqe; @@ -361,7 +358,6 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) tqe = pending_acks_info[i].txqe; if (tqe) { wilc_wlan_txq_remove(tqe); - dropped_acks++; tqe->status = 1; if (tqe->tx_complete_func) tqe->tx_complete_func(tqe->priv, -- GitLab From 1608c4034eee98e3f24ffa9100f96b893d5e5492 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:04:53 +0100 Subject: [PATCH 1610/2855] staging/wilc1000: make symbols static if possible All symbols that are only referenced in the file that defines them can be declared 'static' to avoid namespace pollution, to produce better object code, and to make the source more readable. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/Makefile | 3 +- drivers/staging/wilc1000/coreconfigurator.c | 4 +- drivers/staging/wilc1000/host_interface.c | 35 +++++++----- drivers/staging/wilc1000/host_interface.h | 8 --- drivers/staging/wilc1000/linux_mon.c | 6 +- drivers/staging/wilc1000/linux_wlan.c | 19 +++---- drivers/staging/wilc1000/linux_wlan_sdio.c | 4 +- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 56 +++++++++---------- .../staging/wilc1000/wilc_wfi_cfgoperations.h | 1 - drivers/staging/wilc1000/wilc_wlan.c | 23 +++++--- 10 files changed, 81 insertions(+), 78 deletions(-) diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile index 650123df0b4c1..9696f69bda485 100644 --- a/drivers/staging/wilc1000/Makefile +++ b/drivers/staging/wilc1000/Makefile @@ -8,8 +8,7 @@ ccflags-y += -DSTA_FIRMWARE=\"atmel/wilc1000_fw.bin\" \ -DAP_FIRMWARE=\"atmel/wilc1000_ap_fw.bin\" \ -DP2P_CONCURRENCY_FIRMWARE=\"atmel/wilc1000_p2p_fw.bin\" -ccflags-y += -I$(src)/ -D__CHECK_ENDIAN__ -DWILC_ASIC_A0 \ - -Wno-unused-function -DWILC_DEBUGFS +ccflags-y += -I$(src)/ -D__CHECK_ENDIAN__ -DWILC_ASIC_A0 -DWILC_DEBUGFS #ccflags-y += -DTCP_ACK_FILTER ccflags-$(CONFIG_WILC1000_PREALLOCATE_AT_LOADING_DRIVER) += -DMEMORY_STATIC \ diff --git a/drivers/staging/wilc1000/coreconfigurator.c b/drivers/staging/wilc1000/coreconfigurator.c index 56e0cf90fde6c..d676d047f141d 100644 --- a/drivers/staging/wilc1000/coreconfigurator.c +++ b/drivers/staging/wilc1000/coreconfigurator.c @@ -287,7 +287,7 @@ static inline u16 get_asoc_id(u8 *data) return asoc_id; } -u8 *get_tim_elm(u8 *pu8msa, u16 u16RxLen, u16 u16TagParamOffset) +static u8 *get_tim_elm(u8 *pu8msa, u16 u16RxLen, u16 u16TagParamOffset) { u16 u16index; @@ -315,7 +315,7 @@ u8 *get_tim_elm(u8 *pu8msa, u16 u16RxLen, u16 u16TagParamOffset) /* This function gets the current channel information from * the 802.11n beacon/probe response frame */ -u8 get_current_channel_802_11n(u8 *pu8msa, u16 u16RxLen) +static u8 get_current_channel_802_11n(u8 *pu8msa, u16 u16RxLen) { u16 index; diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 6c205b97293db..93bdb224f9733 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -234,7 +234,7 @@ struct join_bss_param { static struct host_if_drv *wfidrv_list[NUM_CONCURRENT_IFC + 1]; struct host_if_drv *terminated_handle; bool g_obtainingIP; -u8 P2P_LISTEN_STATE; +static u8 P2P_LISTEN_STATE; static struct task_struct *hif_thread_handler; static WILC_MsgQueueHandle hif_msg_q; static struct semaphore hif_sema_thread; @@ -259,10 +259,10 @@ static u8 del_beacon; static u32 clients_count; static u8 *join_req; -u8 *info_element; +static u8 *info_element; static u8 mode_11i; -u8 auth_type; -u32 join_req_size; +static u8 auth_type; +static u32 join_req_size; static u32 info_element_size; static struct host_if_drv *join_req_drv; #define REAL_JOIN_REQ 0 @@ -396,7 +396,9 @@ static s32 handle_set_operation_mode(struct host_if_drv *hif_drv, return result; } -s32 handle_set_ip_address(struct host_if_drv *hif_drv, u8 *ip_addr, u8 idx) +static s32 host_int_get_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx); + +static s32 handle_set_ip_address(struct host_if_drv *hif_drv, u8 *ip_addr, u8 idx) { s32 result = 0; struct wid wid; @@ -430,7 +432,7 @@ s32 handle_set_ip_address(struct host_if_drv *hif_drv, u8 *ip_addr, u8 idx) return result; } -s32 handle_get_ip_address(struct host_if_drv *hif_drv, u8 idx) +static s32 handle_get_ip_address(struct host_if_drv *hif_drv, u8 idx) { s32 result = 0; struct wid wid; @@ -817,6 +819,9 @@ static void Handle_wait_msg_q_empty(void) up(&hif_sema_wait_response); } +static s32 Handle_ScanDone(struct host_if_drv *hif_drv, + enum scan_event enuEvent); + static s32 Handle_Scan(struct host_if_drv *hif_drv, struct scan_attr *pstrHostIFscanAttr) { @@ -1483,6 +1488,11 @@ done: return result; } +static s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv, + u8 *pu8AssocRespInfo, + u32 u32MaxAssocRespInfoLen, + u32 *pu32RcvdAssocRespInfoLen); + static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, struct rcvd_async_info *pstrRcvdGnrlAsyncInfo) { @@ -2140,7 +2150,7 @@ static void Handle_GetLinkspeed(struct host_if_drv *hif_drv) up(&hif_drv->sem_get_link_speed); } -s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics) +static s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics) { struct wid strWIDList[5]; u32 u32WidsCount = 0, result = 0; @@ -3534,11 +3544,10 @@ s32 host_int_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode) return result; } - -s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv, - u8 *pu8AssocRespInfo, - u32 u32MaxAssocRespInfoLen, - u32 *pu32RcvdAssocRespInfoLen) +static s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv, + u8 *pu8AssocRespInfo, + u32 u32MaxAssocRespInfoLen, + u32 *pu32RcvdAssocRespInfoLen) { s32 result = 0; struct wid wid; @@ -4706,7 +4715,7 @@ s32 host_int_setup_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx) return result; } -s32 host_int_get_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx) +static s32 host_int_get_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx) { s32 result = 0; struct host_if_msg msg; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index c1ed2e236ee22..312da75fc02e3 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -338,10 +338,6 @@ s32 host_int_set_join_req(struct host_if_drv *hWFIDrv, u8 *pu8bssid, u8 u8channel, void *pJoinParams); s32 host_int_flush_join_req(struct host_if_drv *hWFIDrv); s32 host_int_disconnect(struct host_if_drv *hWFIDrv, u16 u16ReasonCode); -s32 host_int_get_assoc_res_info(struct host_if_drv *hWFIDrv, - u8 *pu8AssocRespInfo, - u32 u32MaxAssocRespInfoLen, - u32 *pu32RcvdAssocRespInfoLen); int host_int_set_mac_chnl_num(struct host_if_drv *wfi_drv, u8 channel); s32 host_int_get_rssi(struct host_if_drv *hWFIDrv, s8 *ps8Rssi); s32 host_int_scan(struct host_if_drv *hWFIDrv, u8 u8ScanSource, @@ -379,7 +375,6 @@ s32 host_int_setup_ipaddress(struct host_if_drv *hWFIDrv, s32 host_int_del_All_Rx_BASession(struct host_if_drv *hWFIDrv, char *pBSSID, char TID); -s32 host_int_get_ipaddress(struct host_if_drv *hWFIDrv, u8 *pu8IPAddr, u8 idx); s32 host_int_remain_on_channel(struct host_if_drv *hWFIDrv, u32 u32SessionID, u32 u32duration, @@ -394,9 +389,6 @@ s32 host_int_frame_register(struct host_if_drv *hWFIDrv, int host_int_set_wfi_drv_handler(struct host_if_drv *address); int host_int_set_operation_mode(struct host_if_drv *wfi_drv, u32 mode); -static s32 Handle_ScanDone(struct host_if_drv *drvHandler, - enum scan_event enuEvent); - void host_int_freeJoinParams(void *pJoinParams); s32 host_int_get_statistics(struct host_if_drv *hWFIDrv, diff --git a/drivers/staging/wilc1000/linux_mon.c b/drivers/staging/wilc1000/linux_mon.c index 589a11fd977c3..2d518acb4af33 100644 --- a/drivers/staging/wilc1000/linux_mon.c +++ b/drivers/staging/wilc1000/linux_mon.c @@ -29,9 +29,9 @@ static struct net_device *wilc_wfi_mon; /* global monitor netdev */ extern int mac_xmit(struct sk_buff *skb, struct net_device *dev); -u8 srcAdd[6]; -u8 bssid[6]; -u8 broadcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +static u8 srcAdd[6]; +static u8 bssid[6]; +static u8 broadcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; /** * @brief WILC_WFI_monitor_rx * @details diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 086f1dbfb157d..b95dba74a37d7 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -225,9 +225,8 @@ static irqreturn_t isr_uh_routine(int irq, void *user_data) } return IRQ_WAKE_THREAD; } -#endif -irqreturn_t isr_bh_routine(int irq, void *userdata) +static irqreturn_t isr_bh_routine(int irq, void *userdata) { perInterface_wlan_t *nic; struct wilc *wilc; @@ -246,7 +245,6 @@ irqreturn_t isr_bh_routine(int irq, void *userdata) return IRQ_HANDLED; } -#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO) static int init_irq(struct net_device *dev) { int ret = 0; @@ -333,7 +331,7 @@ void linux_wlan_mac_indicate(struct wilc *wilc, int flag) } } -struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header) +static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header) { u8 *bssid, *bssid1; int i = 0; @@ -839,7 +837,7 @@ void wilc1000_wlan_deinit(struct net_device *dev) } } -int wlan_init_locks(struct net_device *dev) +static int wlan_init_locks(struct net_device *dev) { perInterface_wlan_t *nic; struct wilc *wl; @@ -884,7 +882,7 @@ static int wlan_deinit_locks(struct net_device *dev) return 0; } -void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic) +static void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic) { PRINT_D(INIT_DBG, "Linux to Wlan services ...\n"); @@ -895,7 +893,7 @@ void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic) #endif } -int wlan_initialize_threads(struct net_device *dev) +static int wlan_initialize_threads(struct net_device *dev) { perInterface_wlan_t *nic; struct wilc *wilc; @@ -921,7 +919,6 @@ static void wlan_deinitialize_threads(struct net_device *dev) { perInterface_wlan_t *nic; struct wilc *wl; - nic = netdev_priv(dev); wl = nic->wilc; @@ -1049,7 +1046,7 @@ _fail_locks_: return ret; } -int mac_init_fn(struct net_device *ndev) +static int mac_init_fn(struct net_device *ndev) { netif_start_queue(ndev); netif_stop_queue(ndev); @@ -1131,7 +1128,7 @@ int mac_open(struct net_device *ndev) return 0; } -struct net_device_stats *mac_stats(struct net_device *dev) +static struct net_device_stats *mac_stats(struct net_device *dev) { perInterface_wlan_t *nic = netdev_priv(dev); @@ -1325,7 +1322,7 @@ int mac_close(struct net_device *ndev) return 0; } -int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) +static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) { u8 *buff = NULL; s8 rssi; diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index 9e8ba04ca9c8d..a0640ebe904e0 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -39,18 +39,18 @@ static const struct sdio_device_id wilc_sdio_ids[] = { }; +#ifndef WILC_SDIO_IRQ_GPIO static void wilc_sdio_interrupt(struct sdio_func *func) { struct wilc_sdio *wl_sdio; wl_sdio = sdio_get_drvdata(func); -#ifndef WILC_SDIO_IRQ_GPIO sdio_release_host(func); wilc_handle_isr(wl_sdio->wilc); sdio_claim_host(func); -#endif } +#endif int linux_sdio_cmd52(sdio_cmd52_t *cmd) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 849f86b5ff309..842f0e4bec97b 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -24,10 +24,10 @@ extern int mac_open(struct net_device *ndev); extern int mac_close(struct net_device *ndev); -tstrNetworkInfo astrLastScannedNtwrksShadow[MAX_NUM_SCANNED_NETWORKS_SHADOW]; -u32 u32LastScannedNtwrksCountShadow; +static tstrNetworkInfo astrLastScannedNtwrksShadow[MAX_NUM_SCANNED_NETWORKS_SHADOW]; +static u32 u32LastScannedNtwrksCountShadow; struct timer_list hDuringIpTimer; -struct timer_list hAgingTimer; +static struct timer_list hAgingTimer; static u8 op_ifcs; extern u8 u8ConnectedSSID[6]; @@ -90,15 +90,15 @@ struct p2p_mgmt_data { }; /*Global variable used to state the current connected STA channel*/ -u8 u8WLANChannel = INVALID_CHANNEL; +static u8 u8WLANChannel = INVALID_CHANNEL; -u8 curr_channel; +static u8 curr_channel; -u8 u8P2P_oui[] = {0x50, 0x6f, 0x9A, 0x09}; -u8 u8P2Plocalrandom = 0x01; -u8 u8P2Precvrandom = 0x00; -u8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03}; -bool bWilc_ie; +static u8 u8P2P_oui[] = {0x50, 0x6f, 0x9A, 0x09}; +static u8 u8P2Plocalrandom = 0x01; +static u8 u8P2Precvrandom = 0x00; +static u8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03}; +static bool bWilc_ie; static struct ieee80211_supported_band WILC_WFI_band_2ghz = { .channels = WILC_WFI_2ghz_channels, @@ -113,19 +113,19 @@ struct add_key_params { bool pairwise; u8 *mac_addr; }; -struct add_key_params g_add_gtk_key_params; -struct wilc_wfi_key g_key_gtk_params; -struct add_key_params g_add_ptk_key_params; -struct wilc_wfi_key g_key_ptk_params; -struct wilc_wfi_wep_key g_key_wep_params; -bool g_ptk_keys_saved; -bool g_gtk_keys_saved; -bool g_wep_keys_saved; +static struct add_key_params g_add_gtk_key_params; +static struct wilc_wfi_key g_key_gtk_params; +static struct add_key_params g_add_ptk_key_params; +static struct wilc_wfi_key g_key_ptk_params; +static struct wilc_wfi_wep_key g_key_wep_params; +static bool g_ptk_keys_saved; +static bool g_gtk_keys_saved; +static bool g_wep_keys_saved; #define AGING_TIME (9 * 1000) #define duringIP_TIME 15000 -void clear_shadow_scan(void *pUserVoid) +static void clear_shadow_scan(void *pUserVoid) { int i; @@ -147,7 +147,7 @@ void clear_shadow_scan(void *pUserVoid) } -u32 get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo) +static u32 get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo) { u8 i; int rssi_v = 0; @@ -160,7 +160,7 @@ u32 get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo) return rssi_v; } -void refresh_scan(void *pUserVoid, u8 all, bool bDirectScan) +static void refresh_scan(void *pUserVoid, u8 all, bool bDirectScan) { struct wilc_priv *priv; struct wiphy *wiphy; @@ -200,7 +200,7 @@ void refresh_scan(void *pUserVoid, u8 all, bool bDirectScan) } -void reset_shadow_found(void *pUserVoid) +static void reset_shadow_found(void *pUserVoid) { int i; @@ -210,7 +210,7 @@ void reset_shadow_found(void *pUserVoid) } } -void update_scan_time(void *pUserVoid) +static void update_scan_time(void *pUserVoid) { int i; @@ -256,7 +256,7 @@ static void clear_duringIP(unsigned long arg) g_obtainingIP = false; } -int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid) +static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid) { int state = -1; int i; @@ -279,7 +279,7 @@ int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid) return state; } -void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams) +static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams) { int ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid); u32 ap_index = 0; @@ -1766,7 +1766,7 @@ static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) * @version */ -void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len) +static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len) { u32 index = 0; u32 i = 0, j = 0; @@ -1818,7 +1818,7 @@ void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len) * @date 12 DEC 2012 * @version */ -void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype) +static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype) { u32 index = 0; u32 i = 0, j = 0; @@ -3285,7 +3285,7 @@ int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed) * @date 01 MAR 2012 * @version 1.0 */ -struct wireless_dev *WILC_WFI_CfgAlloc(void) +static struct wireless_dev *WILC_WFI_CfgAlloc(void) { struct wireless_dev *wdev; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h index d7bdca1f4c5ba..9f9a9aeb36554 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h @@ -90,7 +90,6 @@ static const struct ieee80211_txrx_stypes #define WILC_WFI_DWELL_PASSIVE 100 #define WILC_WFI_DWELL_ACTIVE 40 -struct wireless_dev *WILC_WFI_CfgAlloc(void); struct wireless_dev *wilc_create_wiphy(struct net_device *net); void wilc_free_wiphy(struct net_device *net); int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed); diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index f702cca2095ad..5c8c59257f589 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -40,7 +40,9 @@ typedef struct { static wilc_wlan_dev_t g_wlan; +#ifdef WILC_OPTIMIZE_SLEEP_INT static inline void chip_allow_sleep(void); +#endif static inline void chip_wakeup(void); static u32 dbgflag = N_INIT | N_ERR | N_INTR | N_TXQ | N_RXQ; @@ -81,6 +83,7 @@ static inline void release_bus(BUS_RELEASE_T release) mutex_unlock(&g_linux_wlan->hif_cs); } +#ifdef TCP_ACK_FILTER static void wilc_wlan_txq_remove(struct txq_entry_t *tqe) { wilc_wlan_dev_t *p = &g_wlan; @@ -99,6 +102,7 @@ static void wilc_wlan_txq_remove(struct txq_entry_t *tqe) } p->txq_entries -= 1; } +#endif static struct txq_entry_t * wilc_wlan_txq_remove_from_head(struct net_device *dev) @@ -209,16 +213,17 @@ struct pending_acks_info { struct txq_entry_t *txqe; }; + #define NOT_TCP_ACK (-1) #define MAX_TCP_SESSION 25 #define MAX_PENDING_ACKS 256 -struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION]; -struct pending_acks_info pending_acks_info[MAX_PENDING_ACKS]; +static struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION]; +static struct pending_acks_info pending_acks_info[MAX_PENDING_ACKS]; -u32 pending_base; -u32 tcp_session; -u32 pending_acks; +static u32 pending_base; +static u32 tcp_session; +static u32 pending_acks; static inline int init_tcp_tracking(void) { @@ -386,17 +391,19 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) } #endif -bool enabled = false; +static bool enabled = false; void enable_tcp_ack_filter(bool value) { enabled = value; } -bool is_tcp_ack_filter_enabled(void) +#ifdef TCP_ACK_FILTER +static bool is_tcp_ack_filter_enabled(void) { return enabled; } +#endif static int wilc_wlan_txq_add_cfg_pkt(u8 *buffer, u32 buffer_size) { @@ -1582,7 +1589,7 @@ void wilc_bus_set_default_speed(void) g_wlan.hif_func.hif_set_default_bus_speed(); } -u32 init_chip(struct net_device *dev) +static u32 init_chip(struct net_device *dev) { u32 chipid; u32 reg, ret = 0; -- GitLab From 0e1af73ddeb9747fd1aa8b0c6040b8b3709ae9bb Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:04:54 +0100 Subject: [PATCH 1611/2855] staging/wilc1000: use proper naming for global symbols There are many global symbols in the wilc1000 driver, some of them with names like "DEBUG_LEVEL" or "probe" that are not acceptable for globals in the linux kernel as they may easily conflict with other (equally broken) drivers. This renames all the globals that do not already start with wilc or a variation of that to start with wilc_ and to follow the usual naming conventions. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/coreconfigurator.c | 10 +- drivers/staging/wilc1000/coreconfigurator.h | 16 +- drivers/staging/wilc1000/host_interface.c | 260 +++++++++--------- drivers/staging/wilc1000/host_interface.h | 82 +++--- drivers/staging/wilc1000/linux_mon.c | 4 +- drivers/staging/wilc1000/linux_wlan.c | 115 ++++---- drivers/staging/wilc1000/linux_wlan_common.h | 18 +- drivers/staging/wilc1000/linux_wlan_sdio.c | 50 ++-- drivers/staging/wilc1000/linux_wlan_sdio.h | 16 +- drivers/staging/wilc1000/linux_wlan_spi.c | 14 +- drivers/staging/wilc1000/linux_wlan_spi.h | 10 +- drivers/staging/wilc1000/wilc_debugfs.c | 18 +- drivers/staging/wilc1000/wilc_sdio.c | 62 ++--- drivers/staging/wilc1000/wilc_spi.c | 48 ++-- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 260 +++++++++--------- .../staging/wilc1000/wilc_wfi_cfgoperations.h | 2 +- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 8 +- drivers/staging/wilc1000/wilc_wlan.c | 42 +-- drivers/staging/wilc1000/wilc_wlan.h | 2 +- drivers/staging/wilc1000/wilc_wlan_cfg.c | 6 +- 20 files changed, 521 insertions(+), 522 deletions(-) diff --git a/drivers/staging/wilc1000/coreconfigurator.c b/drivers/staging/wilc1000/coreconfigurator.c index d676d047f141d..47fa82f26b53a 100644 --- a/drivers/staging/wilc1000/coreconfigurator.c +++ b/drivers/staging/wilc1000/coreconfigurator.c @@ -344,7 +344,7 @@ static u8 get_current_channel_802_11n(u8 *pu8msa, u16 u16RxLen) * @date 1 Mar 2012 * @version 1.0 */ -s32 parse_network_info(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo) +s32 wilc_parse_network_info(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo) { tstrNetworkInfo *pstrNetworkInfo = NULL; u8 u8MsgType = 0; @@ -466,7 +466,7 @@ s32 parse_network_info(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo) * @date 1 Mar 2012 * @version 1.0 */ -s32 DeallocateNetworkInfo(tstrNetworkInfo *pstrNetworkInfo) +s32 wilc_dealloc_network_info(tstrNetworkInfo *pstrNetworkInfo) { s32 s32Error = 0; @@ -499,7 +499,7 @@ s32 DeallocateNetworkInfo(tstrNetworkInfo *pstrNetworkInfo) * @date 2 Apr 2012 * @version 1.0 */ -s32 ParseAssocRespInfo(u8 *pu8Buffer, u32 u32BufferLen, +s32 wilc_parse_assoc_resp_info(u8 *pu8Buffer, u32 u32BufferLen, tstrConnectRespInfo **ppstrConnectRespInfo) { s32 s32Error = 0; @@ -551,7 +551,7 @@ s32 ParseAssocRespInfo(u8 *pu8Buffer, u32 u32BufferLen, * @date 2 Apr 2012 * @version 1.0 */ -s32 DeallocateAssocRespInfo(tstrConnectRespInfo *pstrConnectRespInfo) +s32 wilc_dealloc_assoc_resp_info(tstrConnectRespInfo *pstrConnectRespInfo) { s32 s32Error = 0; @@ -588,7 +588,7 @@ s32 DeallocateAssocRespInfo(tstrConnectRespInfo *pstrConnectRespInfo) * @date 1 Mar 2012 * @version 1.0 */ -s32 send_config_pkt(u8 mode, struct wid *wids, u32 count, u32 drv) +s32 wilc_send_config_pkt(u8 mode, struct wid *wids, u32 count, u32 drv) { s32 counter = 0, ret = 0; diff --git a/drivers/staging/wilc1000/coreconfigurator.h b/drivers/staging/wilc1000/coreconfigurator.h index 3253f6f1393ae..912d5c2879e47 100644 --- a/drivers/staging/wilc1000/coreconfigurator.h +++ b/drivers/staging/wilc1000/coreconfigurator.h @@ -127,16 +127,16 @@ typedef struct { size_t ie_len; } tstrDisconnectNotifInfo; -s32 send_config_pkt(u8 mode, struct wid *wids, u32 count, u32 drv); -s32 parse_network_info(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo); -s32 DeallocateNetworkInfo(tstrNetworkInfo *pstrNetworkInfo); +s32 wilc_send_config_pkt(u8 mode, struct wid *wids, u32 count, u32 drv); +s32 wilc_parse_network_info(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo); +s32 wilc_dealloc_network_info(tstrNetworkInfo *pstrNetworkInfo); -s32 ParseAssocRespInfo(u8 *pu8Buffer, u32 u32BufferLen, +s32 wilc_parse_assoc_resp_info(u8 *pu8Buffer, u32 u32BufferLen, tstrConnectRespInfo **ppstrConnectRespInfo); -s32 DeallocateAssocRespInfo(tstrConnectRespInfo *pstrConnectRespInfo); +s32 wilc_dealloc_assoc_resp_info(tstrConnectRespInfo *pstrConnectRespInfo); -void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length); -void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length); -void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length); +void wilc_network_info_received(u8 *pu8Buffer, u32 u32Length); +void wilc_gnrl_async_info_received(u8 *pu8Buffer, u32 u32Length); +void wilc_scan_complete_received(u8 *pu8Buffer, u32 u32Length); #endif diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 93bdb224f9733..228a2fefe7148 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -9,11 +9,11 @@ #include #include "wilc_wfi_netdevice.h" -extern u8 connecting; +extern u8 wilc_connecting; -extern struct timer_list hDuringIpTimer; +extern struct timer_list wilc_during_ip_timer; -extern u8 g_wilc_initialized; +extern u8 wilc_initialized; #define HOST_IF_MSG_SCAN 0 #define HOST_IF_MSG_CONNECT 1 @@ -233,7 +233,7 @@ struct join_bss_param { static struct host_if_drv *wfidrv_list[NUM_CONCURRENT_IFC + 1]; struct host_if_drv *terminated_handle; -bool g_obtainingIP; +bool wilc_optaining_ip; static u8 P2P_LISTEN_STATE; static struct task_struct *hif_thread_handler; static WILC_MsgQueueHandle hif_msg_q; @@ -243,7 +243,7 @@ static struct semaphore hif_sema_wait_response; static struct semaphore hif_sema_deinit; static struct timer_list periodic_rssi; -u8 multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; +u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE]; @@ -271,7 +271,7 @@ static struct host_if_drv *join_req_drv; static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo); -extern int linux_wlan_get_num_conn_ifcs(void); +extern int wilc_wlan_get_num_conn_ifcs(void); static int add_handler_in_list(struct host_if_drv *handler) { @@ -336,7 +336,7 @@ static s32 handle_set_channel(struct host_if_drv *hif_drv, PRINT_D(HOSTINF_DBG, "Setting channel\n"); - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { @@ -358,7 +358,7 @@ static s32 handle_set_wfi_drv_handler(struct host_if_drv *hif_drv, wid.val = (s8 *)&hif_drv_handler->handler; wid.size = sizeof(u32); - result = send_config_pkt(SET_CFG, &wid, 1, hif_drv_handler->handler); + result = wilc_send_config_pkt(SET_CFG, &wid, 1, hif_drv_handler->handler); if (!hif_drv) up(&hif_sema_driver); @@ -382,7 +382,7 @@ static s32 handle_set_operation_mode(struct host_if_drv *hif_drv, wid.val = (s8 *)&hif_op_mode->mode; wid.size = sizeof(u32); - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if ((hif_op_mode->mode) == IDLE_MODE) @@ -417,7 +417,7 @@ static s32 handle_set_ip_address(struct host_if_drv *hif_drv, u8 *ip_addr, u8 id wid.val = (u8 *)ip_addr; wid.size = IP_ALEN; - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); host_int_get_ipaddress(hif_drv, firmware_ip_addr, idx); @@ -442,7 +442,7 @@ static s32 handle_get_ip_address(struct host_if_drv *hif_drv, u8 idx) wid.val = kmalloc(IP_ALEN, GFP_KERNEL); wid.size = IP_ALEN; - result = send_config_pkt(GET_CFG, &wid, 1, + result = wilc_send_config_pkt(GET_CFG, &wid, 1, get_id_from_handler(hif_drv)); PRINT_INFO(HOSTINF_DBG, "%pI4\n", wid.val); @@ -452,7 +452,7 @@ static s32 handle_get_ip_address(struct host_if_drv *hif_drv, u8 idx) kfree(wid.val); if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0) - host_int_setup_ipaddress(hif_drv, set_ip[idx], idx); + wilc_setup_ipaddress(hif_drv, set_ip[idx], idx); if (result != 0) { PRINT_ER("Failed to get IP address\n"); @@ -485,7 +485,7 @@ static s32 handle_set_mac_address(struct host_if_drv *hif_drv, wid.size = ETH_ALEN; PRINT_D(GENERIC_DBG, "mac addr = :%pM\n", wid.val); - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { PRINT_ER("Failed to set mac address\n"); @@ -507,7 +507,7 @@ static s32 handle_get_mac_address(struct host_if_drv *hif_drv, wid.val = get_mac_addr->mac_addr; wid.size = ETH_ALEN; - result = send_config_pkt(GET_CFG, &wid, 1, + result = wilc_send_config_pkt(GET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { @@ -802,7 +802,7 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, wid_cnt++; } - result = send_config_pkt(SET_CFG, wid_list, wid_cnt, + result = wilc_send_config_pkt(SET_CFG, wid_list, wid_cnt, get_id_from_handler(hif_drv)); if (result) @@ -815,7 +815,7 @@ ERRORHANDLER: static void Handle_wait_msg_q_empty(void) { - g_wilc_initialized = 0; + wilc_initialized = 0; up(&hif_sema_wait_response); } @@ -848,7 +848,7 @@ static s32 Handle_Scan(struct host_if_drv *hif_drv, goto ERRORHANDLER; } - if (g_obtainingIP || connecting) { + if (wilc_optaining_ip || wilc_connecting) { PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n"); PRINT_ER("Don't do obss scan\n"); result = -EBUSY; @@ -925,7 +925,7 @@ static s32 Handle_Scan(struct host_if_drv *hif_drv, else if (hif_drv->hif_state == HOST_IF_IDLE) scan_while_connected = false; - result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount, + result = wilc_send_config_pkt(SET_CFG, strWIDList, u32WidsCount, get_id_from_handler(hif_drv)); if (result) @@ -969,7 +969,7 @@ static s32 Handle_ScanDone(struct host_if_drv *hif_drv, wid.val = (s8 *)&u8abort_running_scan; wid.size = sizeof(char); - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { @@ -992,7 +992,7 @@ static s32 Handle_ScanDone(struct host_if_drv *hif_drv, return result; } -u8 u8ConnectedSSID[6] = {0}; +u8 wilc_connected_SSID[6] = {0}; static s32 Handle_Connect(struct host_if_drv *hif_drv, struct connect_attr *pstrHostIFconnectAttr) { @@ -1004,7 +1004,7 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv, PRINT_D(GENERIC_DBG, "Handling connect request\n"); - if (memcmp(pstrHostIFconnectAttr->bssid, u8ConnectedSSID, ETH_ALEN) == 0) { + if (memcmp(pstrHostIFconnectAttr->bssid, wilc_connected_SSID, ETH_ALEN) == 0) { result = 0; PRINT_ER("Trying to connect to an already connected AP, Discard connect request\n"); return result; @@ -1217,13 +1217,13 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv, PRINT_D(GENERIC_DBG, "send HOST_IF_WAITING_CONN_RESP\n"); if (pstrHostIFconnectAttr->bssid) { - memcpy(u8ConnectedSSID, pstrHostIFconnectAttr->bssid, ETH_ALEN); + memcpy(wilc_connected_SSID, pstrHostIFconnectAttr->bssid, ETH_ALEN); PRINT_D(GENERIC_DBG, "save Bssid = %pM\n", pstrHostIFconnectAttr->bssid); - PRINT_D(GENERIC_DBG, "save bssid = %pM\n", u8ConnectedSSID); + PRINT_D(GENERIC_DBG, "save bssid = %pM\n", wilc_connected_SSID); } - result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount, + result = wilc_send_config_pkt(SET_CFG, strWIDList, u32WidsCount, get_id_from_handler(hif_drv)); if (result) { PRINT_ER("failed to send config packet\n"); @@ -1240,7 +1240,7 @@ ERRORHANDLER: del_timer(&hif_drv->connect_timer); - PRINT_D(HOSTINF_DBG, "could not start connecting to the required network\n"); + PRINT_D(HOSTINF_DBG, "could not start wilc_connecting to the required network\n"); memset(&strConnectInfo, 0, sizeof(tstrConnectInfo)); @@ -1320,7 +1320,7 @@ static s32 Handle_FlushConnect(struct host_if_drv *hif_drv) u32WidsCount++; - result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount, + result = wilc_send_config_pkt(SET_CFG, strWIDList, u32WidsCount, get_id_from_handler(join_req_drv)); if (result) { PRINT_ER("failed to send config packet\n"); @@ -1381,7 +1381,7 @@ static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv) PRINT_D(HOSTINF_DBG, "Sending disconnect request\n"); - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send dissconect config packet\n"); @@ -1392,7 +1392,7 @@ static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv) hif_drv->usr_conn_req.ies_len = 0; kfree(hif_drv->usr_conn_req.ies); - eth_zero_addr(u8ConnectedSSID); + eth_zero_addr(wilc_connected_SSID); if (join_req && join_req_drv == hif_drv) { kfree(join_req); @@ -1421,7 +1421,7 @@ static s32 Handle_RcvdNtwrkInfo(struct host_if_drv *hif_drv, if (hif_drv->usr_scan_req.scan_result) { PRINT_D(HOSTINF_DBG, "State: Scanning, parsing network information received\n"); - parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo); + wilc_parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo); if ((!pstrNetworkInfo) || (!hif_drv->usr_scan_req.scan_result)) { PRINT_ER("driver is null\n"); @@ -1481,7 +1481,7 @@ done: pstrRcvdNetworkInfo->buffer = NULL; if (pstrNetworkInfo) { - DeallocateNetworkInfo(pstrNetworkInfo); + wilc_dealloc_network_info(pstrNetworkInfo); pstrNetworkInfo = NULL; } @@ -1560,10 +1560,10 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, if (u32RcvdAssocRespInfoLen != 0) { PRINT_D(HOSTINF_DBG, "Parsing association response\n"); - s32Err = ParseAssocRespInfo(rcv_assoc_resp, u32RcvdAssocRespInfoLen, + s32Err = wilc_parse_assoc_resp_info(rcv_assoc_resp, u32RcvdAssocRespInfoLen, &pstrConnectRespInfo); if (s32Err) { - PRINT_ER("ParseAssocRespInfo() returned error %d\n", s32Err); + PRINT_ER("wilc_parse_assoc_resp_info() returned error %d\n", s32Err); } else { strConnectInfo.u16ConnectStatus = pstrConnectRespInfo->u16ConnectStatus; @@ -1578,7 +1578,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, } if (pstrConnectRespInfo) { - DeallocateAssocRespInfo(pstrConnectRespInfo); + wilc_dealloc_assoc_resp_info(pstrConnectRespInfo); pstrConnectRespInfo = NULL; } } @@ -1588,11 +1588,11 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, if ((u8MacStatus == MAC_CONNECTED) && (strConnectInfo.u16ConnectStatus != SUCCESSFUL_STATUSCODE)) { PRINT_ER("Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n"); - eth_zero_addr(u8ConnectedSSID); + eth_zero_addr(wilc_connected_SSID); } else if (u8MacStatus == MAC_DISCONNECTED) { PRINT_ER("Received MAC status is MAC_DISCONNECTED\n"); - eth_zero_addr(u8ConnectedSSID); + eth_zero_addr(wilc_connected_SSID); } if (hif_drv->usr_conn_req.pu8bssid) { @@ -1623,14 +1623,14 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, if ((u8MacStatus == MAC_CONNECTED) && (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) { - host_int_set_power_mgmt(hif_drv, 0, 0); + wilc_set_power_mgmt(hif_drv, 0, 0); PRINT_D(HOSTINF_DBG, "MAC status : CONNECTED and Connect Status : Successful\n"); hif_drv->hif_state = HOST_IF_CONNECTED; PRINT_D(GENERIC_DBG, "Obtaining an IP, Disable Scan\n"); - g_obtainingIP = true; - mod_timer(&hDuringIpTimer, + wilc_optaining_ip = true; + mod_timer(&wilc_during_ip_timer, jiffies + msecs_to_jiffies(10000)); } else { PRINT_D(HOSTINF_DBG, "MAC status : %d and Connect Status : %d\n", u8MacStatus, strConnectInfo.u16ConnectStatus); @@ -1665,8 +1665,8 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, strDisconnectNotifInfo.ie_len = 0; if (hif_drv->usr_conn_req.conn_result) { - g_obtainingIP = false; - host_int_set_power_mgmt(hif_drv, 0, 0); + wilc_optaining_ip = false; + wilc_set_power_mgmt(hif_drv, 0, 0); hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL, @@ -1764,7 +1764,7 @@ static int Handle_Key(struct host_if_drv *hif_drv, strWIDList[3].size = pstrHostIFkeyAttr->attr.wep.key_len; strWIDList[3].val = (s8 *)pu8keybuf; - result = send_config_pkt(SET_CFG, strWIDList, 4, + result = wilc_send_config_pkt(SET_CFG, strWIDList, 4, get_id_from_handler(hif_drv)); kfree(pu8keybuf); } @@ -1787,7 +1787,7 @@ static int Handle_Key(struct host_if_drv *hif_drv, wid.val = (s8 *)pu8keybuf; wid.size = pstrHostIFkeyAttr->attr.wep.key_len + 2; - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); kfree(pu8keybuf); } else if (pstrHostIFkeyAttr->action & REMOVEKEY) { @@ -1799,7 +1799,7 @@ static int Handle_Key(struct host_if_drv *hif_drv, wid.val = s8idxarray; wid.size = 1; - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); } else { wid.id = (u16)WID_KEY_ID; @@ -1809,7 +1809,7 @@ static int Handle_Key(struct host_if_drv *hif_drv, PRINT_D(HOSTINF_DBG, "Setting default key index\n"); - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); } up(&hif_drv->sem_test_key_block); @@ -1842,7 +1842,7 @@ static int Handle_Key(struct host_if_drv *hif_drv, strWIDList[1].val = (s8 *)pu8keybuf; strWIDList[1].size = RX_MIC_KEY_MSG_LEN; - result = send_config_pkt(SET_CFG, strWIDList, 2, + result = wilc_send_config_pkt(SET_CFG, strWIDList, 2, get_id_from_handler(hif_drv)); kfree(pu8keybuf); @@ -1875,7 +1875,7 @@ static int Handle_Key(struct host_if_drv *hif_drv, wid.val = (s8 *)pu8keybuf; wid.size = RX_MIC_KEY_MSG_LEN; - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); kfree(pu8keybuf); @@ -1914,7 +1914,7 @@ _WPARxGtk_end_case_: strWIDList[1].val = (s8 *)pu8keybuf; strWIDList[1].size = PTK_KEY_MSG_LEN + 1; - result = send_config_pkt(SET_CFG, strWIDList, 2, + result = wilc_send_config_pkt(SET_CFG, strWIDList, 2, get_id_from_handler(hif_drv)); kfree(pu8keybuf); up(&hif_drv->sem_test_key_block); @@ -1937,7 +1937,7 @@ _WPARxGtk_end_case_: wid.val = (s8 *)pu8keybuf; wid.size = PTK_KEY_MSG_LEN; - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); kfree(pu8keybuf); up(&hif_drv->sem_test_key_block); @@ -1972,7 +1972,7 @@ _WPAPtk_end_case_: wid.val = (s8 *)pu8keybuf; wid.size = (pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1; - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); kfree(pu8keybuf); @@ -1999,12 +1999,12 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) PRINT_D(HOSTINF_DBG, "Sending disconnect request\n"); - g_obtainingIP = false; - host_int_set_power_mgmt(hif_drv, 0, 0); + wilc_optaining_ip = false; + wilc_set_power_mgmt(hif_drv, 0, 0); - eth_zero_addr(u8ConnectedSSID); + eth_zero_addr(wilc_connected_SSID); - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { @@ -2068,14 +2068,14 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) up(&hif_drv->sem_test_disconn_block); } -void resolve_disconnect_aberration(struct host_if_drv *hif_drv) +void wilc_resolve_disconnect_aberration(struct host_if_drv *hif_drv) { if (!hif_drv) return; if ((hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) || (hif_drv->hif_state == HOST_IF_CONNECTING)) { PRINT_D(HOSTINF_DBG, "\n\n<< correcting Supplicant state machine >>\n\n"); - host_int_disconnect(hif_drv, 1); + wilc_disconnect(hif_drv, 1); } } @@ -2091,7 +2091,7 @@ static s32 Handle_GetChnl(struct host_if_drv *hif_drv) PRINT_D(HOSTINF_DBG, "Getting channel value\n"); - result = send_config_pkt(GET_CFG, &wid, 1, + result = wilc_send_config_pkt(GET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { @@ -2116,7 +2116,7 @@ static void Handle_GetRssi(struct host_if_drv *hif_drv) PRINT_D(HOSTINF_DBG, "Getting RSSI value\n"); - result = send_config_pkt(GET_CFG, &wid, 1, + result = wilc_send_config_pkt(GET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { PRINT_ER("Failed to get RSSI value\n"); @@ -2140,7 +2140,7 @@ static void Handle_GetLinkspeed(struct host_if_drv *hif_drv) PRINT_D(HOSTINF_DBG, "Getting LINKSPEED value\n"); - result = send_config_pkt(GET_CFG, &wid, 1, + result = wilc_send_config_pkt(GET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { PRINT_ER("Failed to get LINKSPEED value\n"); @@ -2185,7 +2185,7 @@ static s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pst strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_fail_cnt; u32WidsCount++; - result = send_config_pkt(GET_CFG, strWIDList, u32WidsCount, + result = wilc_send_config_pkt(GET_CFG, strWIDList, u32WidsCount, get_id_from_handler(hif_drv)); if (result) @@ -2212,7 +2212,7 @@ static s32 Handle_Get_InActiveTime(struct host_if_drv *hif_drv, PRINT_D(CFG80211_DBG, "SETING STA inactive time\n"); - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { @@ -2225,7 +2225,7 @@ static s32 Handle_Get_InActiveTime(struct host_if_drv *hif_drv, wid.val = (s8 *)&inactive_time; wid.size = sizeof(u32); - result = send_config_pkt(GET_CFG, &wid, 1, + result = wilc_send_config_pkt(GET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { @@ -2284,7 +2284,7 @@ static void Handle_AddBeacon(struct host_if_drv *hif_drv, memcpy(pu8CurrByte, pstrSetBeaconParam->tail, pstrSetBeaconParam->tail_len); pu8CurrByte += pstrSetBeaconParam->tail_len; - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send add beacon config packet\n"); @@ -2313,7 +2313,7 @@ static void Handle_DelBeacon(struct host_if_drv *hif_drv) PRINT_D(HOSTINF_DBG, "Deleting BEACON\n"); - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send delete beacon config packet\n"); @@ -2386,7 +2386,7 @@ static void Handle_AddStation(struct host_if_drv *hif_drv, pu8CurrByte = wid.val; pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam); - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result != 0) PRINT_ER("Failed to send add station config packet\n"); @@ -2428,7 +2428,7 @@ static void Handle_DelAllSta(struct host_if_drv *hif_drv, pu8CurrByte += ETH_ALEN; } - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send add station config packet\n"); @@ -2460,7 +2460,7 @@ static void Handle_DelStation(struct host_if_drv *hif_drv, memcpy(pu8CurrByte, pstrDelStaParam->mac_addr, ETH_ALEN); - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send add station config packet\n"); @@ -2488,7 +2488,7 @@ static void Handle_EditStation(struct host_if_drv *hif_drv, pu8CurrByte = wid.val; pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam); - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send edit station config packet\n"); @@ -2527,7 +2527,7 @@ static int Handle_RemainOnChan(struct host_if_drv *hif_drv, goto ERRORHANDLER; } - if (g_obtainingIP || connecting) { + if (wilc_optaining_ip || wilc_connecting) { PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n"); result = -EBUSY; goto ERRORHANDLER; @@ -2549,7 +2549,7 @@ static int Handle_RemainOnChan(struct host_if_drv *hif_drv, wid.val[0] = u8remain_on_chan_flag; wid.val[1] = (s8)pstrHostIfRemainOnChan->ch; - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result != 0) PRINT_ER("Failed to set remain on channel\n"); @@ -2597,7 +2597,7 @@ static int Handle_RegisterFrame(struct host_if_drv *hif_drv, wid.size = sizeof(u16) + 2; - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { PRINT_ER("Failed to frame register config packet\n"); @@ -2629,7 +2629,7 @@ static u32 Handle_ListenStateExpired(struct host_if_drv *hif_drv, wid.val[0] = u8remain_on_chan_flag; wid.val[1] = FALSE_FRMWR_CHANNEL; - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result != 0) { PRINT_ER("Failed to set remain on channel\n"); @@ -2687,7 +2687,7 @@ static void Handle_PowerManagement(struct host_if_drv *hif_drv, PRINT_D(HOSTINF_DBG, "Handling Power Management\n"); - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send power management config packet\n"); @@ -2721,10 +2721,10 @@ static void Handle_SetMulticastFilter(struct host_if_drv *hif_drv, *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 24) & 0xFF); if ((strHostIfSetMulti->cnt) > 0) - memcpy(pu8CurrByte, multicast_mac_addr_list, + memcpy(pu8CurrByte, wilc_multicast_mac_addr_list, ((strHostIfSetMulti->cnt) * ETH_ALEN)); - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send setup multicast config packet\n"); @@ -2770,7 +2770,7 @@ static s32 Handle_AddBASession(struct host_if_drv *hif_drv, *ptr++ = 8; *ptr++ = 0; - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_D(HOSTINF_DBG, "Couldn't open BA Session\n"); @@ -2789,7 +2789,7 @@ static s32 Handle_AddBASession(struct host_if_drv *hif_drv, *ptr++ = (strHostIfBASessionInfo->buf_size & 0xFF); *ptr++ = ((strHostIfBASessionInfo->time_out >> 16) & 0xFF); *ptr++ = 3; - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); kfree(wid.val); @@ -2824,7 +2824,7 @@ static s32 Handle_DelAllRxBASessions(struct host_if_drv *hif_drv, *ptr++ = 0; *ptr++ = 32; - result = send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n"); @@ -2852,7 +2852,7 @@ static int hostIFthread(void *pvArg) break; } - if ((!g_wilc_initialized)) { + if ((!wilc_initialized)) { PRINT_D(GENERIC_DBG, "--WAIT--"); usleep_range(200 * 1000, 200 * 1000); wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -2912,8 +2912,8 @@ static int hostIFthread(void *pvArg) del_timer(&hif_drv->scan_timer); PRINT_D(HOSTINF_DBG, "scan completed successfully\n"); - if (!linux_wlan_get_num_conn_ifcs()) - chip_sleep_manually(); + if (!wilc_wlan_get_num_conn_ifcs()) + wilc_chip_sleep_manually(); Handle_ScanDone(msg.drv, SCAN_EVENT_DONE); @@ -3073,7 +3073,7 @@ static void TimerCB_Connect(unsigned long arg) wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); } -s32 host_int_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress) +s32 wilc_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress) { struct wid wid; @@ -3085,7 +3085,7 @@ s32 host_int_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress) return 0; } -int host_int_remove_wep_key(struct host_if_drv *hif_drv, u8 index) +int wilc_remove_wep_key(struct host_if_drv *hif_drv, u8 index) { int result = 0; struct host_if_msg msg; @@ -3112,7 +3112,7 @@ int host_int_remove_wep_key(struct host_if_drv *hif_drv, u8 index) return result; } -int host_int_set_wep_default_key(struct host_if_drv *hif_drv, u8 index) +int wilc_set_wep_default_keyid(struct host_if_drv *hif_drv, u8 index) { int result = 0; struct host_if_msg msg; @@ -3139,7 +3139,7 @@ int host_int_set_wep_default_key(struct host_if_drv *hif_drv, u8 index) return result; } -int host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv, +int wilc_add_wep_key_bss_sta(struct host_if_drv *hif_drv, const u8 *key, u8 len, u8 index) @@ -3173,12 +3173,12 @@ int host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv, return result; } -int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, - const u8 *key, - u8 len, - u8 index, - u8 mode, - enum AUTHTYPE auth_type) +int wilc_add_wep_key_bss_ap(struct host_if_drv *hif_drv, + const u8 *key, + u8 len, + u8 index, + u8 mode, + enum AUTHTYPE auth_type) { int result = 0; struct host_if_msg msg; @@ -3217,7 +3217,7 @@ int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, return result; } -s32 host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk, +s32 wilc_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk, u8 u8PtkKeylen, const u8 *mac_addr, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode, u8 u8Idx) @@ -3282,7 +3282,7 @@ s32 host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk, return result; } -s32 host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk, +s32 wilc_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk, u8 u8GtkKeylen, u8 u8KeyIdx, u32 u32KeyRSClen, const u8 *KeyRSC, const u8 *pu8RxMic, const u8 *pu8TxMic, @@ -3344,7 +3344,7 @@ s32 host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk, return result; } -s32 host_int_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_attr *pu8PmkidInfoArray) +s32 wilc_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_attr *pu8PmkidInfoArray) { s32 result = 0; struct host_if_msg msg; @@ -3376,7 +3376,7 @@ s32 host_int_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_at return result; } -s32 hif_get_mac_address(struct host_if_drv *hif_drv, u8 *pu8MacAddress) +s32 wilc_get_mac_address(struct host_if_drv *hif_drv, u8 *pu8MacAddress) { s32 result = 0; struct host_if_msg msg; @@ -3397,7 +3397,7 @@ s32 hif_get_mac_address(struct host_if_drv *hif_drv, u8 *pu8MacAddress) return result; } -s32 host_int_set_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress) +s32 wilc_set_mac_address(struct host_if_drv *hif_drv, u8 *pu8MacAddress) { s32 result = 0; struct host_if_msg msg; @@ -3428,7 +3428,7 @@ s32 host_int_set_start_scan_req(struct host_if_drv *hif_drv, u8 scanSource) return 0; } -s32 host_int_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid, +s32 wilc_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid, const u8 *pu8ssid, size_t ssidLen, const u8 *pu8IEs, size_t IEsLen, wilc_connect_result pfConnectResult, void *pvUserArg, @@ -3495,7 +3495,7 @@ s32 host_int_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid, return result; } -s32 host_int_flush_join_req(struct host_if_drv *hif_drv) +s32 wilc_flush_join_req(struct host_if_drv *hif_drv) { s32 result = 0; struct host_if_msg msg; @@ -3520,7 +3520,7 @@ s32 host_int_flush_join_req(struct host_if_drv *hif_drv) return result; } -s32 host_int_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode) +s32 wilc_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode) { s32 result = 0; struct host_if_msg msg; @@ -3562,7 +3562,7 @@ static s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv, wid.val = pu8AssocRespInfo; wid.size = u32MaxAssocRespInfoLen; - result = send_config_pkt(GET_CFG, &wid, 1, + result = wilc_send_config_pkt(GET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { *pu32RcvdAssocRespInfoLen = 0; @@ -3575,7 +3575,7 @@ static s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv, return result; } -int host_int_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel) +int wilc_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel) { int result; struct host_if_msg msg; @@ -3599,7 +3599,7 @@ int host_int_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel) return 0; } -int host_int_wait_msg_queue_idle(void) +int wilc_wait_msg_queue_idle(void) { int result = 0; struct host_if_msg msg; @@ -3617,7 +3617,7 @@ int host_int_wait_msg_queue_idle(void) return result; } -int host_int_set_wfi_drv_handler(struct host_if_drv *hif_drv) +int wilc_set_wfi_drv_handler(struct host_if_drv *hif_drv) { int result = 0; struct host_if_msg msg; @@ -3636,7 +3636,7 @@ int host_int_set_wfi_drv_handler(struct host_if_drv *hif_drv) return result; } -int host_int_set_operation_mode(struct host_if_drv *hif_drv, u32 mode) +int wilc_set_operation_mode(struct host_if_drv *hif_drv, u32 mode) { int result = 0; struct host_if_msg msg; @@ -3655,7 +3655,7 @@ int host_int_set_operation_mode(struct host_if_drv *hif_drv, u32 mode) return result; } -s32 host_int_get_inactive_time(struct host_if_drv *hif_drv, +s32 wilc_get_inactive_time(struct host_if_drv *hif_drv, const u8 *mac, u32 *pu32InactiveTime) { s32 result = 0; @@ -3683,7 +3683,7 @@ s32 host_int_get_inactive_time(struct host_if_drv *hif_drv, return result; } -s32 host_int_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi) +s32 wilc_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi) { s32 result = 0; struct host_if_msg msg; @@ -3710,7 +3710,7 @@ s32 host_int_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi) return result; } -s32 host_int_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics) +s32 wilc_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics) { s32 result = 0; struct host_if_msg msg; @@ -3730,7 +3730,7 @@ s32 host_int_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrSta return result; } -s32 host_int_scan(struct host_if_drv *hif_drv, u8 u8ScanSource, +s32 wilc_scan(struct host_if_drv *hif_drv, u8 u8ScanSource, u8 u8ScanType, u8 *pu8ChnlFreqList, u8 u8ChnlListLen, const u8 *pu8IEs, size_t IEsLen, wilc_scan_result ScanResult, @@ -3783,7 +3783,7 @@ s32 host_int_scan(struct host_if_drv *hif_drv, u8 u8ScanSource, return result; } -s32 hif_set_cfg(struct host_if_drv *hif_drv, +s32 wilc_hif_set_cfg(struct host_if_drv *hif_drv, struct cfg_param_val *pstrCfgParamVal) { s32 result = 0; @@ -3832,7 +3832,7 @@ static void GetPeriodicRSSI(unsigned long arg) mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000)); } -s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) +s32 wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) { s32 result = 0; struct host_if_drv *hif_drv; @@ -3861,7 +3861,7 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) goto _fail_timer_2; } - g_obtainingIP = false; + wilc_optaining_ip = false; PRINT_D(HOSTINF_DBG, "Global handle pointer value=%p\n", hif_drv); if (clients_count == 0) { @@ -3940,7 +3940,7 @@ _fail_: return result; } -s32 host_int_deinit(struct host_if_drv *hif_drv) +s32 wilc_deinit(struct host_if_drv *hif_drv) { s32 result = 0; struct host_if_msg msg; @@ -3967,7 +3967,7 @@ s32 host_int_deinit(struct host_if_drv *hif_drv) del_timer_sync(&hif_drv->remain_on_ch_timer); - host_int_set_wfi_drv_handler(NULL); + wilc_set_wfi_drv_handler(NULL); down(&hif_sema_driver); if (hif_drv->usr_scan_req.scan_result) { @@ -4012,7 +4012,7 @@ s32 host_int_deinit(struct host_if_drv *hif_drv) return result; } -void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length) +void wilc_network_info_received(u8 *pu8Buffer, u32 u32Length) { s32 result = 0; struct host_if_msg msg; @@ -4041,7 +4041,7 @@ void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length) PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n", result); } -void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length) +void wilc_gnrl_async_info_received(u8 *pu8Buffer, u32 u32Length) { s32 result = 0; struct host_if_msg msg; @@ -4082,7 +4082,7 @@ void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length) up(&hif_sema_deinit); } -void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length) +void wilc_scan_complete_received(u8 *pu8Buffer, u32 u32Length) { s32 result = 0; struct host_if_msg msg; @@ -4111,7 +4111,7 @@ void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length) return; } -s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID, +s32 wilc_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID, u32 u32duration, u16 chan, wilc_remain_on_chan_expired RemainOnChanExpired, wilc_remain_on_chan_ready RemainOnChanReady, @@ -4143,7 +4143,7 @@ s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID, return result; } -s32 host_int_ListenStateExpired(struct host_if_drv *hif_drv, u32 u32SessionID) +s32 wilc_listen_state_expired(struct host_if_drv *hif_drv, u32 u32SessionID) { s32 result = 0; struct host_if_msg msg; @@ -4167,7 +4167,7 @@ s32 host_int_ListenStateExpired(struct host_if_drv *hif_drv, u32 u32SessionID) return result; } -s32 host_int_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool bReg) +s32 wilc_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool bReg) { s32 result = 0; struct host_if_msg msg; @@ -4206,7 +4206,7 @@ s32 host_int_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool return result; } -s32 host_int_add_beacon(struct host_if_drv *hif_drv, u32 u32Interval, +s32 wilc_add_beacon(struct host_if_drv *hif_drv, u32 u32Interval, u32 u32DTIMPeriod, u32 u32HeadLen, u8 *pu8Head, u32 u32TailLen, u8 *pu8Tail) { @@ -4260,7 +4260,7 @@ ERRORHANDLER: return result; } -int host_int_del_beacon(struct host_if_drv *hif_drv) +int wilc_del_beacon(struct host_if_drv *hif_drv) { int result = 0; struct host_if_msg msg; @@ -4281,8 +4281,8 @@ int host_int_del_beacon(struct host_if_drv *hif_drv) return result; } -int host_int_add_station(struct host_if_drv *hif_drv, - struct add_sta_param *sta_param) +int wilc_add_station(struct host_if_drv *hif_drv, + struct add_sta_param *sta_param) { int result = 0; struct host_if_msg msg; @@ -4315,7 +4315,7 @@ int host_int_add_station(struct host_if_drv *hif_drv, return result; } -int host_int_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr) +int wilc_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr) { int result = 0; struct host_if_msg msg; @@ -4344,7 +4344,7 @@ int host_int_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr) return result; } -s32 host_int_del_allstation(struct host_if_drv *hif_drv, +s32 wilc_del_allstation(struct host_if_drv *hif_drv, u8 pu8MacAddr[][ETH_ALEN]) { s32 result = 0; @@ -4395,7 +4395,7 @@ s32 host_int_del_allstation(struct host_if_drv *hif_drv, return result; } -s32 host_int_edit_station(struct host_if_drv *hif_drv, +s32 wilc_edit_station(struct host_if_drv *hif_drv, struct add_sta_param *pstrStaParams) { s32 result = 0; @@ -4433,7 +4433,7 @@ s32 host_int_edit_station(struct host_if_drv *hif_drv, return result; } -s32 host_int_set_power_mgmt(struct host_if_drv *hif_drv, +s32 wilc_set_power_mgmt(struct host_if_drv *hif_drv, bool bIsEnabled, u32 u32Timeout) { @@ -4464,7 +4464,7 @@ s32 host_int_set_power_mgmt(struct host_if_drv *hif_drv, return result; } -s32 host_int_setup_multicast_filter(struct host_if_drv *hif_drv, +s32 wilc_setup_multicast_filter(struct host_if_drv *hif_drv, bool bIsEnabled, u32 u32count) { @@ -4650,7 +4650,7 @@ static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo) return (void *)pNewJoinBssParam; } -void host_int_freeJoinParams(void *pJoinParams) +void wilc_free_join_params(void *pJoinParams) { if ((struct bss_param *)pJoinParams) kfree((struct bss_param *)pJoinParams); @@ -4658,7 +4658,7 @@ void host_int_freeJoinParams(void *pJoinParams) PRINT_ER("Unable to FREE null pointer\n"); } -s32 host_int_del_All_Rx_BASession(struct host_if_drv *hif_drv, +s32 wilc_del_all_rx_ba_session(struct host_if_drv *hif_drv, char *pBSSID, char TID) { @@ -4688,7 +4688,7 @@ s32 host_int_del_All_Rx_BASession(struct host_if_drv *hif_drv, return result; } -s32 host_int_setup_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx) +s32 wilc_setup_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx) { s32 result = 0; struct host_if_msg msg; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 312da75fc02e3..d0b85a53c29ee 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -303,95 +303,95 @@ struct add_sta_param { u16 flags_set; }; -s32 host_int_remove_key(struct host_if_drv *hWFIDrv, const u8 *pu8StaAddress); -int host_int_remove_wep_key(struct host_if_drv *wfi_drv, u8 index); -int host_int_set_wep_default_key(struct host_if_drv *hif_drv, u8 index); -int host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv, +s32 wilc_remove_key(struct host_if_drv *hWFIDrv, const u8 *pu8StaAddress); +int wilc_remove_wep_key(struct host_if_drv *wfi_drv, u8 index); +int wilc_set_wep_default_keyid(struct host_if_drv *hif_drv, u8 index); +int wilc_add_wep_key_bss_sta(struct host_if_drv *hif_drv, const u8 *key, u8 len, u8 index); -int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, +int wilc_add_wep_key_bss_ap(struct host_if_drv *hif_drv, const u8 *key, u8 len, u8 index, u8 mode, enum AUTHTYPE auth_type); -s32 host_int_add_ptk(struct host_if_drv *hWFIDrv, const u8 *pu8Ptk, +s32 wilc_add_ptk(struct host_if_drv *hWFIDrv, const u8 *pu8Ptk, u8 u8PtkKeylen, const u8 *mac_addr, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode, u8 u8Idx); -s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, +s32 wilc_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, u32 *pu32InactiveTime); -s32 host_int_add_rx_gtk(struct host_if_drv *hWFIDrv, const u8 *pu8RxGtk, +s32 wilc_add_rx_gtk(struct host_if_drv *hWFIDrv, const u8 *pu8RxGtk, u8 u8GtkKeylen, u8 u8KeyIdx, u32 u32KeyRSClen, const u8 *KeyRSC, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode); -s32 host_int_add_tx_gtk(struct host_if_drv *hWFIDrv, u8 u8KeyLen, +s32 wilc_add_tx_gtk(struct host_if_drv *hWFIDrv, u8 u8KeyLen, u8 *pu8TxGtk, u8 u8KeyIdx); -s32 host_int_set_pmkid_info(struct host_if_drv *hWFIDrv, +s32 wilc_set_pmkid_info(struct host_if_drv *hWFIDrv, struct host_if_pmkid_attr *pu8PmkidInfoArray); -s32 hif_get_mac_address(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); -s32 host_int_set_MacAddress(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); -int host_int_wait_msg_queue_idle(void); -s32 host_int_set_start_scan_req(struct host_if_drv *hWFIDrv, u8 scanSource); -s32 host_int_set_join_req(struct host_if_drv *hWFIDrv, u8 *pu8bssid, +s32 wilc_get_mac_address(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); +s32 wilc_set_mac_address(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); +int wilc_wait_msg_queue_idle(void); +s32 wilc_set_start_scan_req(struct host_if_drv *hWFIDrv, u8 scanSource); +s32 wilc_set_join_req(struct host_if_drv *hWFIDrv, u8 *pu8bssid, const u8 *pu8ssid, size_t ssidLen, const u8 *pu8IEs, size_t IEsLen, wilc_connect_result pfConnectResult, void *pvUserArg, u8 u8security, enum AUTHTYPE tenuAuth_type, u8 u8channel, void *pJoinParams); -s32 host_int_flush_join_req(struct host_if_drv *hWFIDrv); -s32 host_int_disconnect(struct host_if_drv *hWFIDrv, u16 u16ReasonCode); -int host_int_set_mac_chnl_num(struct host_if_drv *wfi_drv, u8 channel); -s32 host_int_get_rssi(struct host_if_drv *hWFIDrv, s8 *ps8Rssi); -s32 host_int_scan(struct host_if_drv *hWFIDrv, u8 u8ScanSource, +s32 wilc_flush_join_req(struct host_if_drv *hWFIDrv); +s32 wilc_disconnect(struct host_if_drv *hWFIDrv, u16 u16ReasonCode); +int wilc_set_mac_chnl_num(struct host_if_drv *wfi_drv, u8 channel); +s32 wilc_get_rssi(struct host_if_drv *hWFIDrv, s8 *ps8Rssi); +s32 wilc_scan(struct host_if_drv *hWFIDrv, u8 u8ScanSource, u8 u8ScanType, u8 *pu8ChnlFreqList, u8 u8ChnlListLen, const u8 *pu8IEs, size_t IEsLen, wilc_scan_result ScanResult, void *pvUserArg, struct hidden_network *pstrHiddenNetwork); -s32 hif_set_cfg(struct host_if_drv *hWFIDrv, +s32 wilc_hif_set_cfg(struct host_if_drv *hWFIDrv, struct cfg_param_val *pstrCfgParamVal); -s32 host_int_init(struct net_device *dev, struct host_if_drv **phWFIDrv); -s32 host_int_deinit(struct host_if_drv *hWFIDrv); -s32 host_int_add_beacon(struct host_if_drv *hWFIDrv, u32 u32Interval, +s32 wilc_init(struct net_device *dev, struct host_if_drv **phWFIDrv); +s32 wilc_deinit(struct host_if_drv *hWFIDrv); +s32 wilc_add_beacon(struct host_if_drv *hWFIDrv, u32 u32Interval, u32 u32DTIMPeriod, u32 u32HeadLen, u8 *pu8Head, u32 u32TailLen, u8 *pu8tail); -int host_int_del_beacon(struct host_if_drv *hif_drv); -int host_int_add_station(struct host_if_drv *hif_drv, +int wilc_del_beacon(struct host_if_drv *hif_drv); +int wilc_add_station(struct host_if_drv *hif_drv, struct add_sta_param *sta_param); -s32 host_int_del_allstation(struct host_if_drv *hWFIDrv, +s32 wilc_del_allstation(struct host_if_drv *hWFIDrv, u8 pu8MacAddr[][ETH_ALEN]); -int host_int_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr); -s32 host_int_edit_station(struct host_if_drv *hWFIDrv, +int wilc_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr); +s32 wilc_edit_station(struct host_if_drv *hWFIDrv, struct add_sta_param *pstrStaParams); -s32 host_int_set_power_mgmt(struct host_if_drv *hWFIDrv, +s32 wilc_set_power_mgmt(struct host_if_drv *hWFIDrv, bool bIsEnabled, u32 u32Timeout); -s32 host_int_setup_multicast_filter(struct host_if_drv *hWFIDrv, +s32 wilc_setup_multicast_filter(struct host_if_drv *hWFIDrv, bool bIsEnabled, u32 u32count); -s32 host_int_setup_ipaddress(struct host_if_drv *hWFIDrv, +s32 wilc_setup_ipaddress(struct host_if_drv *hWFIDrv, u8 *pu8IPAddr, u8 idx); -s32 host_int_del_All_Rx_BASession(struct host_if_drv *hWFIDrv, +s32 wilc_del_all_rx_ba_session(struct host_if_drv *hWFIDrv, char *pBSSID, char TID); -s32 host_int_remain_on_channel(struct host_if_drv *hWFIDrv, +s32 wilc_remain_on_channel(struct host_if_drv *hWFIDrv, u32 u32SessionID, u32 u32duration, u16 chan, wilc_remain_on_chan_expired RemainOnChanExpired, wilc_remain_on_chan_ready RemainOnChanReady, void *pvUserArg); -s32 host_int_ListenStateExpired(struct host_if_drv *hWFIDrv, u32 u32SessionID); -s32 host_int_frame_register(struct host_if_drv *hWFIDrv, +s32 wilc_listen_state_expired(struct host_if_drv *hWFIDrv, u32 u32SessionID); +s32 wilc_frame_register(struct host_if_drv *hWFIDrv, u16 u16FrameType, bool bReg); -int host_int_set_wfi_drv_handler(struct host_if_drv *address); -int host_int_set_operation_mode(struct host_if_drv *wfi_drv, u32 mode); +int wilc_set_wfi_drv_handler(struct host_if_drv *address); +int wilc_set_operation_mode(struct host_if_drv *wfi_drv, u32 mode); -void host_int_freeJoinParams(void *pJoinParams); +void wilc_free_join_params(void *pJoinParams); -s32 host_int_get_statistics(struct host_if_drv *hWFIDrv, +s32 wilc_get_statistics(struct host_if_drv *hWFIDrv, struct rf_info *pstrStatistics); -void resolve_disconnect_aberration(struct host_if_drv *hif_drv); +void wilc_resolve_disconnect_aberration(struct host_if_drv *hif_drv); #endif diff --git a/drivers/staging/wilc1000/linux_mon.c b/drivers/staging/wilc1000/linux_mon.c index 2d518acb4af33..f0a458764ff2a 100644 --- a/drivers/staging/wilc1000/linux_mon.c +++ b/drivers/staging/wilc1000/linux_mon.c @@ -26,7 +26,7 @@ struct wilc_wfi_radiotap_cb_hdr { static struct net_device *wilc_wfi_mon; /* global monitor netdev */ -extern int mac_xmit(struct sk_buff *skb, struct net_device *dev); +extern int wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev); static u8 srcAdd[6]; @@ -298,7 +298,7 @@ static netdev_tx_t WILC_WFI_mon_xmit(struct sk_buff *skb, mon_mgmt_tx(mon_priv->real_ndev, skb->data, skb->len); dev_kfree_skb(skb); } else - ret = mac_xmit(skb, mon_priv->real_ndev); + ret = wilc_mac_xmit(skb, mon_priv->real_ndev); return ret; } diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index b95dba74a37d7..d3d07fc30e23e 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -37,9 +37,9 @@ #define _linux_wlan_device_detection() {} #define _linux_wlan_device_removal() {} -extern bool g_obtainingIP; -extern u8 multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; -extern struct timer_list hDuringIpTimer; +extern bool wilc_optaining_ip; +extern u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; +extern struct timer_list wilc_during_ip_timer; static int linux_wlan_device_power(int on_off) { @@ -86,20 +86,20 @@ extern void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size); static void linux_wlan_tx_complete(void *priv, int status); static int mac_init_fn(struct net_device *ndev); -int mac_xmit(struct sk_buff *skb, struct net_device *dev); -int mac_open(struct net_device *ndev); -int mac_close(struct net_device *ndev); +int wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev); +int wilc_mac_open(struct net_device *ndev); +int wilc_mac_close(struct net_device *ndev); static struct net_device_stats *mac_stats(struct net_device *dev); static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd); static void wilc_set_multicast_list(struct net_device *dev); -struct wilc *g_linux_wlan; -bool bEnablePS = true; +struct wilc *wilc_dev; +bool wilc_enable_ps = true; static const struct net_device_ops wilc_netdev_ops = { .ndo_init = mac_init_fn, - .ndo_open = mac_open, - .ndo_stop = mac_close, - .ndo_start_xmit = mac_xmit, + .ndo_open = wilc_mac_open, + .ndo_stop = wilc_mac_close, + .ndo_start_xmit = wilc_mac_xmit, .ndo_do_ioctl = mac_ioctl, .ndo_get_stats = mac_stats, .ndo_set_rx_mode = wilc_set_multicast_list, @@ -155,13 +155,13 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) { hif_drv->IFC_UP = 1; - g_obtainingIP = false; - del_timer(&hDuringIpTimer); + wilc_optaining_ip = false; + del_timer(&wilc_during_ip_timer); PRINT_D(GENERIC_DBG, "IP obtained , enable scan\n"); } - if (bEnablePS) - host_int_set_power_mgmt(hif_drv, 1, 0); + if (wilc_enable_ps) + wilc_set_power_mgmt(hif_drv, 1, 0); PRINT_D(GENERIC_DBG, "[%s] Up IP\n", dev_iface->ifa_label); @@ -169,7 +169,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n", ip_addr_buf[0], ip_addr_buf[1], ip_addr_buf[2], ip_addr_buf[3]); - host_int_setup_ipaddress(hif_drv, ip_addr_buf, nic->u8IfIdx); + wilc_setup_ipaddress(hif_drv, ip_addr_buf, nic->u8IfIdx); break; @@ -179,13 +179,13 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Released ===============\n\n"); if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) { hif_drv->IFC_UP = 0; - g_obtainingIP = false; + wilc_optaining_ip = false; } if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0) - host_int_set_power_mgmt(hif_drv, 0, 0); + wilc_set_power_mgmt(hif_drv, 0, 0); - resolve_disconnect_aberration(hif_drv); + wilc_resolve_disconnect_aberration(hif_drv); PRINT_D(GENERIC_DBG, "[%s] Down IP\n", dev_iface->ifa_label); @@ -194,7 +194,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event ip_addr_buf[0], ip_addr_buf[1], ip_addr_buf[2], ip_addr_buf[3]); - host_int_setup_ipaddress(hif_drv, ip_addr_buf, nic->u8IfIdx); + wilc_setup_ipaddress(hif_drv, ip_addr_buf, nic->u8IfIdx); break; @@ -358,7 +358,7 @@ static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header) return NULL; } -int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid) +int wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid) { int i = 0; int ret = -1; @@ -378,14 +378,14 @@ int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid) return ret; } -int linux_wlan_get_num_conn_ifcs(void) +int wilc_wlan_get_num_conn_ifcs(void) { u8 i = 0; u8 null_bssid[6] = {0}; u8 ret_val = 0; - for (i = 0; i < g_linux_wlan->vif_num; i++) - if (memcmp(g_linux_wlan->vif[i].bssid, null_bssid, 6)) + for (i = 0; i < wilc_dev->vif_num; i++) + if (memcmp(wilc_dev->vif[i].bssid, null_bssid, 6)) ret_val++; return ret_val; @@ -466,7 +466,7 @@ void linux_wlan_rx_complete(void) PRINT_D(RX_DBG, "RX completed\n"); } -int linux_wlan_get_firmware(struct net_device *dev) +int wilc_wlan_get_firmware(struct net_device *dev) { perInterface_wlan_t *nic; struct wilc *wilc; @@ -799,7 +799,7 @@ void wilc1000_wlan_deinit(struct net_device *dev) PRINT_D(INIT_DBG, "Disabling IRQ\n"); #ifdef WILC_SDIO mutex_lock(&wl->hif_cs); - disable_sdio_interrupt(); + wilc_sdio_disable_interrupt(); mutex_unlock(&wl->hif_cs); #endif if (&wl->txq_event) @@ -820,7 +820,7 @@ void wilc1000_wlan_deinit(struct net_device *dev) PRINT_D(INIT_DBG, "Disabling IRQ 2\n"); mutex_lock(&wl->hif_cs); - disable_sdio_interrupt(); + wilc_sdio_disable_interrupt(); mutex_unlock(&wl->hif_cs); #endif #endif @@ -972,14 +972,14 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) } #if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO) - if (enable_sdio_interrupt()) { + if (wilc_sdio_enable_interrupt()) { PRINT_ER("couldn't initialize IRQ\n"); ret = -EIO; goto _fail_irq_init_; } #endif - if (linux_wlan_get_firmware(dev)) { + if (wilc_wlan_get_firmware(dev)) { PRINT_ER("Can't get firmware\n"); ret = -EIO; goto _fail_irq_enable_; @@ -1027,7 +1027,7 @@ _fail_fw_start_: _fail_irq_enable_: #if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO) - disable_sdio_interrupt(); + wilc_sdio_disable_interrupt(); _fail_irq_init_: #endif #if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO) @@ -1054,7 +1054,7 @@ static int mac_init_fn(struct net_device *ndev) return 0; } -int mac_open(struct net_device *ndev) +int wilc_mac_open(struct net_device *ndev) { perInterface_wlan_t *nic; @@ -1092,9 +1092,9 @@ int mac_open(struct net_device *ndev) return ret; } - set_machw_change_vir_if(ndev, false); + wilc_set_machw_change_vir_if(ndev, false); - hif_get_mac_address(priv->hWILCWFIDrv, mac_add); + wilc_get_mac_address(priv->hWILCWFIDrv, mac_add); PRINT_D(INIT_DBG, "Mac address: %pM\n", mac_add); for (i = 0; i < wl->vif_num; i++) { @@ -1159,29 +1159,29 @@ static void wilc_set_multicast_list(struct net_device *dev) if ((dev->flags & IFF_ALLMULTI) || (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) { PRINT_D(INIT_DBG, "Disable multicast filter, retrive all multicast packets\n"); - host_int_setup_multicast_filter(hif_drv, false, 0); + wilc_setup_multicast_filter(hif_drv, false, 0); return; } if ((dev->mc.count) == 0) { PRINT_D(INIT_DBG, "Enable multicast filter, retrive directed packets only.\n"); - host_int_setup_multicast_filter(hif_drv, true, 0); + wilc_setup_multicast_filter(hif_drv, true, 0); return; } netdev_for_each_mc_addr(ha, dev) { - memcpy(multicast_mac_addr_list[i], ha->addr, ETH_ALEN); + memcpy(wilc_multicast_mac_addr_list[i], ha->addr, ETH_ALEN); PRINT_D(INIT_DBG, "Entry[%d]: %x:%x:%x:%x:%x:%x\n", i, - multicast_mac_addr_list[i][0], - multicast_mac_addr_list[i][1], - multicast_mac_addr_list[i][2], - multicast_mac_addr_list[i][3], - multicast_mac_addr_list[i][4], - multicast_mac_addr_list[i][5]); + wilc_multicast_mac_addr_list[i][0], + wilc_multicast_mac_addr_list[i][1], + wilc_multicast_mac_addr_list[i][2], + wilc_multicast_mac_addr_list[i][3], + wilc_multicast_mac_addr_list[i][4], + wilc_multicast_mac_addr_list[i][5]); i++; } - host_int_setup_multicast_filter(hif_drv, true, (dev->mc.count)); + wilc_setup_multicast_filter(hif_drv, true, (dev->mc.count)); return; } @@ -1198,7 +1198,7 @@ static void linux_wlan_tx_complete(void *priv, int status) kfree(pv_data); } -int mac_xmit(struct sk_buff *skb, struct net_device *ndev) +int wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev) { perInterface_wlan_t *nic; struct tx_complete_data *tx_data = NULL; @@ -1259,7 +1259,7 @@ int mac_xmit(struct sk_buff *skb, struct net_device *ndev) return 0; } -int mac_close(struct net_device *ndev) +int wilc_mac_close(struct net_device *ndev) { struct wilc_priv *priv; perInterface_wlan_t *nic; @@ -1353,8 +1353,7 @@ static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) if (strncasecmp(buff, "RSSI", length) == 0) { priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy); - ret = host_int_get_rssi(priv->hWILCWFIDrv, - &rssi); + ret = wilc_get_rssi(priv->hWILCWFIDrv, &rssi); if (ret) PRINT_ER("Failed to send get rssi param's message queue "); PRINT_INFO(GENERIC_DBG, "RSSI :%d\n", rssi); @@ -1472,7 +1471,7 @@ void wl_wlan_cleanup(struct wilc *wilc) for (i = 0; i < NUM_CONCURRENT_IFC; i++) if (wilc->vif[i].ndev) if (nic[i]->mac_opened) - mac_close(wilc->vif[i].ndev); + wilc_mac_close(wilc->vif[i].ndev); for (i = 0; i < NUM_CONCURRENT_IFC; i++) { unregister_netdev(wilc->vif[i].ndev); @@ -1498,11 +1497,11 @@ int wilc_netdev_init(struct wilc **wilc) sema_init(&close_exit_sync, 0); - g_linux_wlan = kzalloc(sizeof(*g_linux_wlan), GFP_KERNEL); - if (!g_linux_wlan) + wilc_dev = kzalloc(sizeof(*wilc_dev), GFP_KERNEL); + if (!wilc_dev) return -ENOMEM; - *wilc = g_linux_wlan; + *wilc = wilc_dev; register_inetaddr_notifier(&g_dev_notifier); @@ -1521,11 +1520,11 @@ int wilc_netdev_init(struct wilc **wilc) else strcpy(ndev->name, "p2p%d"); - nic->u8IfIdx = g_linux_wlan->vif_num; + nic->u8IfIdx = wilc_dev->vif_num; nic->wilc_netdev = ndev; nic->wilc = *wilc; - g_linux_wlan->vif[g_linux_wlan->vif_num].ndev = ndev; - g_linux_wlan->vif_num++; + wilc_dev->vif[wilc_dev->vif_num].ndev = ndev; + wilc_dev->vif_num++; ndev->netdev_ops = &wilc_netdev_ops; { @@ -1533,7 +1532,7 @@ int wilc_netdev_init(struct wilc **wilc) wdev = wilc_create_wiphy(ndev); #ifdef WILC_SDIO - SET_NETDEV_DEV(ndev, &local_sdio_func->dev); + SET_NETDEV_DEV(ndev, &wilc_sdio_func->dev); #endif if (!wdev) { @@ -1561,13 +1560,13 @@ int wilc_netdev_init(struct wilc **wilc) } #ifndef WILC_SDIO - if (!linux_spi_init()) { + if (!wilc_spi_init()) { PRINT_ER("Can't initialize SPI\n"); return -1; } - g_linux_wlan->wilc_spidev = wilc_spi_dev; + wilc_dev->wilc_spidev = wilc_spi_dev; #else - g_linux_wlan->wilc_sdio_func = local_sdio_func; + wilc_dev->wilc_sdio_func = wilc_sdio_func; #endif return 0; diff --git a/drivers/staging/wilc1000/linux_wlan_common.h b/drivers/staging/wilc1000/linux_wlan_common.h index 2b76e41ebd4d5..b8dfc4a5e5cb5 100644 --- a/drivers/staging/wilc1000/linux_wlan_common.h +++ b/drivers/staging/wilc1000/linux_wlan_common.h @@ -41,8 +41,8 @@ enum debug_region { int wilc_debugfs_init(void); void wilc_debugfs_remove(void); -extern atomic_t REGION; -extern atomic_t DEBUG_LEVEL; +extern atomic_t WILC_REGION; +extern atomic_t WILC_DEBUG_LEVEL; #define DEBUG BIT(0) #define INFO BIT(1) @@ -51,8 +51,8 @@ extern atomic_t DEBUG_LEVEL; #define PRINT_D(region, ...) \ do { \ - if ((atomic_read(&DEBUG_LEVEL) & DEBUG) && \ - ((atomic_read(®ION)) & (region))) { \ + if ((atomic_read(&WILC_DEBUG_LEVEL) & DEBUG) && \ + ((atomic_read(&WILC_REGION)) & (region))) { \ printk("DBG [%s: %d]", __func__, __LINE__); \ printk(__VA_ARGS__); \ } \ @@ -60,8 +60,8 @@ extern atomic_t DEBUG_LEVEL; #define PRINT_INFO(region, ...) \ do { \ - if ((atomic_read(&DEBUG_LEVEL) & INFO) && \ - ((atomic_read(®ION)) & (region))) { \ + if ((atomic_read(&WILC_DEBUG_LEVEL) & INFO) && \ + ((atomic_read(&WILC_REGION)) & (region))) { \ printk("INFO [%s]", __func__); \ printk(__VA_ARGS__); \ } \ @@ -69,8 +69,8 @@ extern atomic_t DEBUG_LEVEL; #define PRINT_WRN(region, ...) \ do { \ - if ((atomic_read(&DEBUG_LEVEL) & WRN) && \ - ((atomic_read(®ION)) & (region))) { \ + if ((atomic_read(&WILC_DEBUG_LEVEL) & WRN) && \ + ((atomic_read(&WILC_REGION)) & (region))) { \ printk("WRN [%s: %d]", __func__, __LINE__); \ printk(__VA_ARGS__); \ } \ @@ -78,7 +78,7 @@ extern atomic_t DEBUG_LEVEL; #define PRINT_ER(...) \ do { \ - if ((atomic_read(&DEBUG_LEVEL) & ERR)) { \ + if ((atomic_read(&WILC_DEBUG_LEVEL) & ERR)) { \ printk("ERR [%s: %d]", __func__, __LINE__); \ printk(__VA_ARGS__); \ } \ diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index a0640ebe904e0..0b01873faf790 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -26,7 +26,7 @@ struct wilc_sdio { struct wilc *wilc; }; -struct sdio_func *local_sdio_func; +struct sdio_func *wilc_sdio_func; static unsigned int sdio_default_speed; @@ -53,9 +53,9 @@ static void wilc_sdio_interrupt(struct sdio_func *func) #endif -int linux_sdio_cmd52(sdio_cmd52_t *cmd) +int wilc_sdio_cmd52(sdio_cmd52_t *cmd) { - struct sdio_func *func = g_linux_wlan->wilc_sdio_func; + struct sdio_func *func = wilc_dev->wilc_sdio_func; int ret; u8 data; @@ -85,9 +85,9 @@ int linux_sdio_cmd52(sdio_cmd52_t *cmd) } -int linux_sdio_cmd53(sdio_cmd53_t *cmd) +int wilc_sdio_cmd53(sdio_cmd53_t *cmd) { - struct sdio_func *func = g_linux_wlan->wilc_sdio_func; + struct sdio_func *func = wilc_dev->wilc_sdio_func; int size, ret; sdio_claim_host(func); @@ -127,7 +127,7 @@ static int linux_sdio_probe(struct sdio_func *func, const struct sdio_device_id return -ENOMEM; PRINT_D(INIT_DBG, "Initializing netdev\n"); - local_sdio_func = func; + wilc_sdio_func = func; if (wilc_netdev_init(&wilc)) { PRINT_ER("Couldn't initialize netdev\n"); kfree(wl_sdio); @@ -157,14 +157,14 @@ struct sdio_driver wilc_bus = { .remove = linux_sdio_remove, }; -int enable_sdio_interrupt(void) +int wilc_sdio_enable_interrupt(void) { int ret = 0; #ifndef WILC_SDIO_IRQ_GPIO - sdio_claim_host(local_sdio_func); - ret = sdio_claim_irq(local_sdio_func, wilc_sdio_interrupt); - sdio_release_host(local_sdio_func); + sdio_claim_host(wilc_sdio_func); + ret = sdio_claim_irq(wilc_sdio_func, wilc_sdio_interrupt); + sdio_release_host(wilc_sdio_func); if (ret < 0) { PRINT_ER("can't claim sdio_irq, err(%d)\n", ret); @@ -174,22 +174,22 @@ int enable_sdio_interrupt(void) return ret; } -void disable_sdio_interrupt(void) +void wilc_sdio_disable_interrupt(void) { #ifndef WILC_SDIO_IRQ_GPIO int ret; - PRINT_D(INIT_DBG, "disable_sdio_interrupt IN\n"); + PRINT_D(INIT_DBG, "wilc_sdio_disable_interrupt IN\n"); - sdio_claim_host(local_sdio_func); - ret = sdio_release_irq(local_sdio_func); + sdio_claim_host(wilc_sdio_func); + ret = sdio_release_irq(wilc_sdio_func); if (ret < 0) { PRINT_ER("can't release sdio_irq, err(%d)\n", ret); } - sdio_release_host(local_sdio_func); + sdio_release_host(wilc_sdio_func); - PRINT_D(INIT_DBG, "disable_sdio_interrupt OUT\n"); + PRINT_D(INIT_DBG, "wilc_sdio_disable_interrupt OUT\n"); #endif } @@ -197,13 +197,13 @@ static int linux_sdio_set_speed(int speed) { struct mmc_ios ios; - sdio_claim_host(local_sdio_func); + sdio_claim_host(wilc_sdio_func); - memcpy((void *)&ios, (void *)&local_sdio_func->card->host->ios, sizeof(struct mmc_ios)); - local_sdio_func->card->host->ios.clock = speed; + memcpy((void *)&ios, (void *)&wilc_sdio_func->card->host->ios, sizeof(struct mmc_ios)); + wilc_sdio_func->card->host->ios.clock = speed; ios.clock = speed; - local_sdio_func->card->host->ops->set_ios(local_sdio_func->card->host, &ios); - sdio_release_host(local_sdio_func); + wilc_sdio_func->card->host->ops->set_ios(wilc_sdio_func->card->host, &ios); + sdio_release_host(wilc_sdio_func); PRINT_INFO(INIT_DBG, "@@@@@@@@@@@@ change SDIO speed to %d @@@@@@@@@\n", speed); return 1; @@ -211,10 +211,10 @@ static int linux_sdio_set_speed(int speed) static int linux_sdio_get_speed(void) { - return local_sdio_func->card->host->ios.clock; + return wilc_sdio_func->card->host->ios.clock; } -int linux_sdio_init(void) +int wilc_sdio_init(void) { /** @@ -226,12 +226,12 @@ int linux_sdio_init(void) return 1; } -int linux_sdio_set_max_speed(void) +int wilc_sdio_set_max_speed(void) { return linux_sdio_set_speed(MAX_SPEED); } -int linux_sdio_set_default_speed(void) +int wilc_sdio_set_default_speed(void) { return linux_sdio_set_speed(sdio_default_speed); } diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.h b/drivers/staging/wilc1000/linux_wlan_sdio.h index 7c59b2f6543ab..49cce2c434102 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.h +++ b/drivers/staging/wilc1000/linux_wlan_sdio.h @@ -1,13 +1,13 @@ -extern struct sdio_func *local_sdio_func; +extern struct sdio_func *wilc_sdio_func; extern struct sdio_driver wilc_bus; #include -int linux_sdio_init(void); -int linux_sdio_cmd52(sdio_cmd52_t *cmd); -int linux_sdio_cmd53(sdio_cmd53_t *cmd); -int enable_sdio_interrupt(void); -void disable_sdio_interrupt(void); -int linux_sdio_set_max_speed(void); -int linux_sdio_set_default_speed(void); +int wilc_sdio_init(void); +int wilc_sdio_cmd52(sdio_cmd52_t *cmd); +int wilc_sdio_cmd53(sdio_cmd53_t *cmd); +int wilc_sdio_enable_interrupt(void); +void wilc_sdio_disable_interrupt(void); +int wilc_sdio_set_max_speed(void); +int wilc_sdio_set_default_speed(void); diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index 3655077a936f7..790128f6d0348 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -79,7 +79,7 @@ struct spi_driver wilc_bus __refdata = { .remove = __exit_p(wilc_bus_remove), }; -int linux_spi_init(void) +int wilc_spi_init(void) { int ret = 1; static int called; @@ -102,7 +102,7 @@ int linux_spi_init(void) #if defined(TXRX_PHASE_SIZE) -int linux_spi_write(u8 *b, u32 len) +int wilc_spi_write(u8 *b, u32 len) { int ret; @@ -179,7 +179,7 @@ int linux_spi_write(u8 *b, u32 len) } #else -int linux_spi_write(u8 *b, u32 len) +int wilc_spi_write(u8 *b, u32 len) { int ret; @@ -230,7 +230,7 @@ int linux_spi_write(u8 *b, u32 len) #if defined(TXRX_PHASE_SIZE) -int linux_spi_read(u8 *rb, u32 rlen) +int wilc_spi_read(u8 *rb, u32 rlen) { int ret; @@ -304,7 +304,7 @@ int linux_spi_read(u8 *rb, u32 rlen) } #else -int linux_spi_read(u8 *rb, u32 rlen) +int wilc_spi_read(u8 *rb, u32 rlen) { int ret; @@ -349,7 +349,7 @@ int linux_spi_read(u8 *rb, u32 rlen) #endif -int linux_spi_write_read(u8 *wb, u8 *rb, u32 rlen) +int wilc_spi_write_read(u8 *wb, u8 *rb, u32 rlen) { int ret; @@ -386,7 +386,7 @@ int linux_spi_write_read(u8 *wb, u8 *rb, u32 rlen) return ret; } -int linux_spi_set_max_speed(void) +int wilc_spi_set_max_speed(void) { SPEED = MAX_SPEED; diff --git a/drivers/staging/wilc1000/linux_wlan_spi.h b/drivers/staging/wilc1000/linux_wlan_spi.h index 2edd97b4c5ccf..aecb522ff56d3 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.h +++ b/drivers/staging/wilc1000/linux_wlan_spi.h @@ -5,9 +5,9 @@ extern struct spi_device *wilc_spi_dev; extern struct spi_driver wilc_bus; -int linux_spi_init(void); -int linux_spi_write(u8 *b, u32 len); -int linux_spi_read(u8 *rb, u32 rlen); -int linux_spi_write_read(u8 *wb, u8 *rb, u32 rlen); -int linux_spi_set_max_speed(void); +int wilc_spi_init(void); +int wilc_spi_write(u8 *b, u32 len); +int wilc_spi_read(u8 *rb, u32 rlen); +int wilc_spi_write_read(u8 *wb, u8 *rb, u32 rlen); +int wilc_spi_set_max_speed(void); #endif diff --git a/drivers/staging/wilc1000/wilc_debugfs.c b/drivers/staging/wilc1000/wilc_debugfs.c index ae111862e7a96..d70f96f475b80 100644 --- a/drivers/staging/wilc1000/wilc_debugfs.c +++ b/drivers/staging/wilc1000/wilc_debugfs.c @@ -26,8 +26,8 @@ static struct dentry *wilc_dir; #define DBG_REGION_ALL (GENERIC_DBG | HOSTAPD_DBG | HOSTINF_DBG | CORECONFIG_DBG | CFG80211_DBG | INT_DBG | TX_DBG | RX_DBG | LOCK_DBG | INIT_DBG | BUS_DBG | MEM_DBG) #define DBG_LEVEL_ALL (DEBUG | INFO | WRN | ERR) -atomic_t REGION = ATOMIC_INIT(INIT_DBG | GENERIC_DBG | CFG80211_DBG | FIRM_DBG | HOSTAPD_DBG); -atomic_t DEBUG_LEVEL = ATOMIC_INIT(ERR); +atomic_t WILC_REGION = ATOMIC_INIT(INIT_DBG | GENERIC_DBG | CFG80211_DBG | FIRM_DBG | HOSTAPD_DBG); +atomic_t WILC_DEBUG_LEVEL = ATOMIC_INIT(ERR); /* * -------------------------------------------------------------------------------- @@ -43,7 +43,7 @@ static ssize_t wilc_debug_level_read(struct file *file, char __user *userbuf, si if (*ppos > 0) return 0; - res = scnprintf(buf, sizeof(buf), "Debug Level: %x\n", atomic_read(&DEBUG_LEVEL)); + res = scnprintf(buf, sizeof(buf), "Debug Level: %x\n", atomic_read(&WILC_DEBUG_LEVEL)); return simple_read_from_buffer(userbuf, count, ppos, buf, res); } @@ -59,11 +59,11 @@ static ssize_t wilc_debug_level_write(struct file *filp, const char __user *buf, return ret; if (flag > DBG_LEVEL_ALL) { - printk("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n", __func__, flag, atomic_read(&DEBUG_LEVEL)); + printk("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n", __func__, flag, atomic_read(&WILC_DEBUG_LEVEL)); return -EINVAL; } - atomic_set(&DEBUG_LEVEL, (int)flag); + atomic_set(&WILC_DEBUG_LEVEL, (int)flag); if (flag == 0) printk("Debug-level disabled\n"); @@ -82,7 +82,7 @@ static ssize_t wilc_debug_region_read(struct file *file, char __user *userbuf, s if (*ppos > 0) return 0; - res = scnprintf(buf, sizeof(buf), "Debug region: %x\n", atomic_read(®ION)); + res = scnprintf(buf, sizeof(buf), "Debug region: %x\n", atomic_read(&WILC_REGION)); return simple_read_from_buffer(userbuf, count, ppos, buf, res); } @@ -102,12 +102,12 @@ static ssize_t wilc_debug_region_write(struct file *filp, const char *buf, size_ flag = buffer[0] - '0'; if (flag > DBG_REGION_ALL) { - printk("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n", __func__, flag, atomic_read(®ION)); + printk("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n", __func__, flag, atomic_read(&WILC_REGION)); return -EFAULT; } - atomic_set(®ION, (int)flag); - printk("new debug-region is %x\n", atomic_read(®ION)); + atomic_set(&WILC_REGION, (int)flag); + printk("new debug-region is %x\n", atomic_read(&WILC_REGION)); return count; } diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index d26e4cf0f4369..7fca3b23b4851 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -48,21 +48,21 @@ static int sdio_set_func0_csa_address(u32 adr) cmd.raw = 0; cmd.address = 0x10c; cmd.data = (u8)adr; - if (!linux_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10c data...\n"); goto _fail_; } cmd.address = 0x10d; cmd.data = (u8)(adr >> 8); - if (!linux_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10d data...\n"); goto _fail_; } cmd.address = 0x10e; cmd.data = (u8)(adr >> 16); - if (!linux_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10e data...\n"); goto _fail_; } @@ -81,14 +81,14 @@ static int sdio_set_func0_block_size(u32 block_size) cmd.raw = 0; cmd.address = 0x10; cmd.data = (u8)block_size; - if (!linux_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10 data...\n"); goto _fail_; } cmd.address = 0x11; cmd.data = (u8)(block_size >> 8); - if (!linux_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x11 data...\n"); goto _fail_; } @@ -113,13 +113,13 @@ static int sdio_set_func1_block_size(u32 block_size) cmd.raw = 0; cmd.address = 0x110; cmd.data = (u8)block_size; - if (!linux_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x110 data...\n"); goto _fail_; } cmd.address = 0x111; cmd.data = (u8)(block_size >> 8); - if (!linux_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x111 data...\n"); goto _fail_; } @@ -140,7 +140,7 @@ static int sdio_clear_int(void) cmd.raw = 0; cmd.address = 0x4; cmd.data = 0; - linux_sdio_cmd52(&cmd); + wilc_sdio_cmd52(&cmd); return cmd.data; #else @@ -176,7 +176,7 @@ static int sdio_write_reg(u32 addr, u32 data) cmd.raw = 0; cmd.address = addr; cmd.data = data; - if (!linux_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr); goto _fail_; } @@ -198,7 +198,7 @@ static int sdio_write_reg(u32 addr, u32 data) cmd.buffer = (u8 *)&data; cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */ - if (!linux_sdio_cmd53(&cmd)) { + if (!wilc_sdio_cmd53(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, write reg (%08x)...\n", addr); goto _fail_; } @@ -261,7 +261,7 @@ static int sdio_write(u32 addr, u8 *buf, u32 size) if (!sdio_set_func0_csa_address(addr)) goto _fail_; } - if (!linux_sdio_cmd53(&cmd)) { + if (!wilc_sdio_cmd53(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block send...\n", addr); goto _fail_; } @@ -282,7 +282,7 @@ static int sdio_write(u32 addr, u8 *buf, u32 size) if (!sdio_set_func0_csa_address(addr)) goto _fail_; } - if (!linux_sdio_cmd53(&cmd)) { + if (!wilc_sdio_cmd53(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes send...\n", addr); goto _fail_; } @@ -304,7 +304,7 @@ static int sdio_read_reg(u32 addr, u32 *data) cmd.function = 0; cmd.raw = 0; cmd.address = addr; - if (!linux_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr); goto _fail_; } @@ -325,7 +325,7 @@ static int sdio_read_reg(u32 addr, u32 *data) cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */ - if (!linux_sdio_cmd53(&cmd)) { + if (!wilc_sdio_cmd53(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, read reg (%08x)...\n", addr); goto _fail_; } @@ -392,7 +392,7 @@ static int sdio_read(u32 addr, u8 *buf, u32 size) if (!sdio_set_func0_csa_address(addr)) goto _fail_; } - if (!linux_sdio_cmd53(&cmd)) { + if (!wilc_sdio_cmd53(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block read...\n", addr); goto _fail_; } @@ -413,7 +413,7 @@ static int sdio_read(u32 addr, u8 *buf, u32 size) if (!sdio_set_func0_csa_address(addr)) goto _fail_; } - if (!linux_sdio_cmd53(&cmd)) { + if (!wilc_sdio_cmd53(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes read...\n", addr); goto _fail_; } @@ -505,7 +505,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) g_sdio.dPrint = func; - if (!linux_sdio_init()) { + if (!wilc_sdio_init()) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed io init bus...\n"); return 0; } else { @@ -520,7 +520,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) cmd.raw = 1; cmd.address = 0x100; cmd.data = 0x80; - if (!linux_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, enable csa...\n"); goto _fail_; } @@ -542,7 +542,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) cmd.raw = 1; cmd.address = 0x2; cmd.data = 0x2; - if (!linux_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio] Fail cmd 52, set IOE register...\n"); goto _fail_; } @@ -557,7 +557,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) loop = 3; do { cmd.data = 0; - if (!linux_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get IOR register...\n"); goto _fail_; } @@ -586,7 +586,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) cmd.raw = 1; cmd.address = 0x4; cmd.data = 0x3; - if (!linux_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(&cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set IEN register...\n"); goto _fail_; } @@ -614,12 +614,12 @@ _fail_: static void sdio_set_max_speed(void) { - linux_sdio_set_max_speed(); + wilc_sdio_set_max_speed(); } static void sdio_set_default_speed(void) { - linux_sdio_set_default_speed(); + wilc_sdio_set_default_speed(); } static int sdio_read_size(u32 *size) @@ -636,7 +636,7 @@ static int sdio_read_size(u32 *size) cmd.raw = 0; cmd.address = 0xf2; cmd.data = 0; - linux_sdio_cmd52(&cmd); + wilc_sdio_cmd52(&cmd); tmp = cmd.data; /* cmd.read_write = 0; */ @@ -644,7 +644,7 @@ static int sdio_read_size(u32 *size) /* cmd.raw = 0; */ cmd.address = 0xf3; cmd.data = 0; - linux_sdio_cmd52(&cmd); + wilc_sdio_cmd52(&cmd); tmp |= (cmd.data << 8); *size = tmp; @@ -666,7 +666,7 @@ static int sdio_read_int(u32 *int_status) cmd.function = 1; cmd.address = 0x04; cmd.data = 0; - linux_sdio_cmd52(&cmd); + wilc_sdio_cmd52(&cmd); if (cmd.data & BIT(0)) tmp |= INT_0; @@ -699,7 +699,7 @@ static int sdio_read_int(u32 *int_status) cmd.raw = 0; cmd.address = 0xf7; cmd.data = 0; - linux_sdio_cmd52(&cmd); + wilc_sdio_cmd52(&cmd); irq_flags = cmd.data & 0x1f; tmp |= ((irq_flags >> 0) << IRG_FLAGS_OFFSET); } @@ -746,7 +746,7 @@ static int sdio_clear_int_ext(u32 val) cmd.address = 0xf8; cmd.data = reg; - ret = linux_sdio_cmd52(&cmd); + ret = wilc_sdio_cmd52(&cmd); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__); goto _fail_; @@ -775,7 +775,7 @@ static int sdio_clear_int_ext(u32 val) cmd.address = 0xf8; cmd.data = BIT(i); - ret = linux_sdio_cmd52(&cmd); + ret = wilc_sdio_cmd52(&cmd); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__); goto _fail_; @@ -819,7 +819,7 @@ static int sdio_clear_int_ext(u32 val) cmd.raw = 0; cmd.address = 0xf6; cmd.data = vmm_ctl; - ret = linux_sdio_cmd52(&cmd); + ret = wilc_sdio_cmd52(&cmd); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf6 data (%d) ...\n", __LINE__); goto _fail_; @@ -925,7 +925,7 @@ static int sdio_sync_ext(int nint /* how mant interrupts to enable. */) * ********************************************/ -struct wilc_hif_func hif_sdio = { +struct wilc_hif_func wilc_hif_sdio = { sdio_init, sdio_deinit, sdio_read_reg, diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 9af35d1ef99e3..dc9cdf5e4065d 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -22,8 +22,8 @@ typedef struct { static wilc_spi_t g_spi; -static int wilc_spi_read(u32, u8 *, u32); -static int wilc_spi_write(u32, u8 *, u32); +static int _wilc_spi_read(u32, u8 *, u32); +static int _wilc_spi_write(u32, u8 *, u32); /******************************************** * @@ -249,7 +249,7 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless) } rix = len; - if (!linux_spi_write_read(wb, rb, len2)) { + if (!wilc_spi_write_read(wb, rb, len2)) { PRINT_ER("[wilc spi]: Failed cmd write, bus error...\n"); result = N_FAIL; return result; @@ -364,7 +364,7 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless) /** * Read bytes **/ - if (!linux_spi_read(&b[ix], nbytes)) { + if (!wilc_spi_read(&b[ix], nbytes)) { PRINT_ER("[wilc spi]: Failed data block read, bus error...\n"); result = N_FAIL; goto _error_; @@ -374,7 +374,7 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless) * Read Crc **/ if (!g_spi.crc_off) { - if (!linux_spi_read(crc, 2)) { + if (!wilc_spi_read(crc, 2)) { PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n"); result = N_FAIL; goto _error_; @@ -405,7 +405,7 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless) **/ retry = 10; do { - if (!linux_spi_read(&rsp, 1)) { + if (!wilc_spi_read(&rsp, 1)) { PRINT_ER("[wilc spi]: Failed data response read, bus error...\n"); result = N_FAIL; break; @@ -421,7 +421,7 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless) /** * Read bytes **/ - if (!linux_spi_read(&b[ix], nbytes)) { + if (!wilc_spi_read(&b[ix], nbytes)) { PRINT_ER("[wilc spi]: Failed data block read, bus error...\n"); result = N_FAIL; break; @@ -431,7 +431,7 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless) * Read Crc **/ if (!g_spi.crc_off) { - if (!linux_spi_read(crc, 2)) { + if (!wilc_spi_read(crc, 2)) { PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n"); result = N_FAIL; break; @@ -481,7 +481,7 @@ static int spi_data_write(u8 *b, u32 sz) order = 0x2; } cmd |= order; - if (!linux_spi_write(&cmd, 1)) { + if (!wilc_spi_write(&cmd, 1)) { PRINT_ER("[wilc spi]: Failed data block cmd write, bus error...\n"); result = N_FAIL; break; @@ -490,7 +490,7 @@ static int spi_data_write(u8 *b, u32 sz) /** * Write data **/ - if (!linux_spi_write(&b[ix], nbytes)) { + if (!wilc_spi_write(&b[ix], nbytes)) { PRINT_ER("[wilc spi]: Failed data block write, bus error...\n"); result = N_FAIL; break; @@ -500,7 +500,7 @@ static int spi_data_write(u8 *b, u32 sz) * Write Crc **/ if (!g_spi.crc_off) { - if (!linux_spi_write(crc, 2)) { + if (!wilc_spi_write(crc, 2)) { PRINT_ER("[wilc spi]: Failed data block crc write, bus error...\n"); result = N_FAIL; break; @@ -585,7 +585,7 @@ static int wilc_spi_write_reg(u32 addr, u32 data) return result; } -static int wilc_spi_write(u32 addr, u8 *buf, u32 size) +static int _wilc_spi_write(u32 addr, u8 *buf, u32 size) { int result; u8 cmd = CMD_DMA_EXT_WRITE; @@ -639,7 +639,7 @@ static int wilc_spi_read_reg(u32 addr, u32 *data) return 1; } -static int wilc_spi_read(u32 addr, u8 *buf, u32 size) +static int _wilc_spi_read(u32 addr, u8 *buf, u32 size) { u8 cmd = CMD_DMA_EXT_READ; int result; @@ -675,7 +675,7 @@ static int wilc_spi_clear_int(void) return 1; } -static int wilc_spi_deinit(void *pv) +static int _wilc_spi_deinit(void *pv) { /** * TODO: @@ -721,7 +721,7 @@ static int wilc_spi_sync(void) return 1; } -static int wilc_spi_init(struct wilc *wilc, wilc_debug_func func) +static int _wilc_spi_init(struct wilc *wilc, wilc_debug_func func) { u32 reg; u32 chipid; @@ -740,7 +740,7 @@ static int wilc_spi_init(struct wilc *wilc, wilc_debug_func func) memset(&g_spi, 0, sizeof(wilc_spi_t)); g_spi.dPrint = func; - if (!linux_spi_init()) { + if (!wilc_spi_init()) { PRINT_ER("[wilc spi]: Failed io init bus...\n"); return 0; } else { @@ -795,7 +795,7 @@ static int wilc_spi_init(struct wilc *wilc, wilc_debug_func func) static void wilc_spi_max_bus_speed(void) { - linux_spi_set_max_speed(); + wilc_spi_set_max_speed(); } static void wilc_spi_default_bus_speed(void) @@ -1021,20 +1021,20 @@ static int wilc_spi_sync_ext(int nint /* how mant interrupts to enable. */) * Global spi HIF function table * ********************************************/ -struct wilc_hif_func hif_spi = { - wilc_spi_init, - wilc_spi_deinit, +struct wilc_hif_func wilc_hif_spi = { + _wilc_spi_init, + _wilc_spi_deinit, wilc_spi_read_reg, wilc_spi_write_reg, - wilc_spi_read, - wilc_spi_write, + _wilc_spi_read, + _wilc_spi_write, wilc_spi_sync, wilc_spi_clear_int, wilc_spi_read_int, wilc_spi_clear_int_ext, wilc_spi_read_size, - wilc_spi_write, - wilc_spi_read, + _wilc_spi_write, + _wilc_spi_read, wilc_spi_sync_ext, wilc_spi_max_bus_speed, wilc_spi_default_bus_speed, diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 842f0e4bec97b..f8fd7a895d449 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -21,18 +21,18 @@ #define IS_MGMT_STATUS_SUCCES 0x040 #define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff) -extern int mac_open(struct net_device *ndev); -extern int mac_close(struct net_device *ndev); +extern int wilc_mac_open(struct net_device *ndev); +extern int wilc_mac_close(struct net_device *ndev); static tstrNetworkInfo astrLastScannedNtwrksShadow[MAX_NUM_SCANNED_NETWORKS_SHADOW]; static u32 u32LastScannedNtwrksCountShadow; -struct timer_list hDuringIpTimer; +struct timer_list wilc_during_ip_timer; static struct timer_list hAgingTimer; static u8 op_ifcs; -extern u8 u8ConnectedSSID[6]; +extern u8 wilc_connected_SSID[6]; -u8 g_wilc_initialized = 1; -extern bool g_obtainingIP; +u8 wilc_initialized = 1; +extern bool wilc_optaining_ip; #define CHAN2G(_channel, _freq, _flags) { \ .band = IEEE80211_BAND_2GHZ, \ @@ -139,7 +139,7 @@ static void clear_shadow_scan(void *pUserVoid) astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs = NULL; } - host_int_freeJoinParams(astrLastScannedNtwrksShadow[i].pJoinParams); + wilc_free_join_params(astrLastScannedNtwrksShadow[i].pJoinParams); astrLastScannedNtwrksShadow[i].pJoinParams = NULL; } u32LastScannedNtwrksCountShadow = 0; @@ -232,7 +232,7 @@ static void remove_network_from_shadow(unsigned long arg) kfree(astrLastScannedNtwrksShadow[i].pu8IEs); astrLastScannedNtwrksShadow[i].pu8IEs = NULL; - host_int_freeJoinParams(astrLastScannedNtwrksShadow[i].pJoinParams); + wilc_free_join_params(astrLastScannedNtwrksShadow[i].pJoinParams); for (j = i; (j < u32LastScannedNtwrksCountShadow - 1); j++) { astrLastScannedNtwrksShadow[j] = astrLastScannedNtwrksShadow[j + 1]; @@ -253,7 +253,7 @@ static void remove_network_from_shadow(unsigned long arg) static void clear_duringIP(unsigned long arg) { PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n"); - g_obtainingIP = false; + wilc_optaining_ip = false; } static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid) @@ -331,7 +331,7 @@ static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserV astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScanCached = jiffies; astrLastScannedNtwrksShadow[ap_index].u8Found = 1; if (ap_found != -1) - host_int_freeJoinParams(astrLastScannedNtwrksShadow[ap_index].pJoinParams); + wilc_free_join_params(astrLastScannedNtwrksShadow[ap_index].pJoinParams); astrLastScannedNtwrksShadow[ap_index].pJoinParams = pJoinParams; } @@ -484,7 +484,7 @@ static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNet * @date 01 MAR 2012 * @version 1.0 */ -int connecting; +int wilc_connecting; static void CfgConnectResult(enum conn_event enuConnDisconnEvent, tstrConnectInfo *pstrConnectInfo, @@ -499,7 +499,7 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, struct wilc *wl; perInterface_wlan_t *nic; - connecting = 0; + wilc_connecting = 0; priv = (struct wilc_priv *)pUserVoid; dev = priv->dev; @@ -520,8 +520,8 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, /* The case here is that our station was waiting for association response frame and has just received it containing status code * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */ u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE; - linux_wlan_set_bssid(priv->dev, NullBssid); - eth_zero_addr(u8ConnectedSSID); + wilc_wlan_set_bssid(priv->dev, NullBssid); + eth_zero_addr(wilc_connected_SSID); /*Invalidate u8WLANChannel value on wlan0 disconnect*/ if (!pstrWFIDrv->p2p_connect) @@ -572,15 +572,15 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */ /* be replaced by pstrConnectInfo->u16ConnectStatus */ } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) { - g_obtainingIP = false; + wilc_optaining_ip = false; PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n", pstrDisconnectNotifInfo->u16reason, priv->dev); u8P2Plocalrandom = 0x01; u8P2Precvrandom = 0x00; bWilc_ie = false; eth_zero_addr(priv->au8AssociatedBss); - linux_wlan_set_bssid(priv->dev, NullBssid); - eth_zero_addr(u8ConnectedSSID); + wilc_wlan_set_bssid(priv->dev, NullBssid); + eth_zero_addr(wilc_connected_SSID); /*Invalidate u8WLANChannel value on wlan0 disconnect*/ if (!pstrWFIDrv->p2p_connect) @@ -630,7 +630,7 @@ static int set_channel(struct wiphy *wiphy, PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq); curr_channel = channelnum; - result = host_int_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum); + result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum); if (result != 0) PRINT_ER("Error in setting channel %d\n", channelnum); @@ -665,7 +665,7 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) priv->u32RcvdChCount = 0; - host_int_set_wfi_drv_handler(priv->hWILCWFIDrv); + wilc_set_wfi_drv_handler(priv->hWILCWFIDrv); reset_shadow_found(priv); @@ -702,13 +702,13 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) } } PRINT_D(CFG80211_DBG, "Trigger Scan Request\n"); - s32Error = host_int_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN, + s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN, au8ScanChanList, request->n_channels, (const u8 *)request->ie, request->ie_len, CfgScanResult, (void *)priv, &strHiddenNetwork); } else { PRINT_D(CFG80211_DBG, "Trigger Scan Request\n"); - s32Error = host_int_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN, + s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN, au8ScanChanList, request->n_channels, (const u8 *)request->ie, request->ie_len, CfgScanResult, (void *)priv, NULL); @@ -755,11 +755,11 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, tstrNetworkInfo *pstrNetworkInfo = NULL; - connecting = 1; + wilc_connecting = 1; priv = wiphy_priv(wiphy); pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv); - host_int_set_wfi_drv_handler(priv->hWILCWFIDrv); + wilc_set_wfi_drv_handler(priv->hWILCWFIDrv); PRINT_D(CFG80211_DBG, "Connecting to SSID [%s] on netdev [%p] host if [%p]\n", sme->ssid, dev, priv->hWILCWFIDrv); if (!(strncmp(sme->ssid, "DIRECT-", 7))) { @@ -852,8 +852,8 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, g_key_wep_params.key_idx = sme->key_idx; g_wep_keys_saved = true; - host_int_set_wep_default_key(priv->hWILCWFIDrv, sme->key_idx); - host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx); + wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx); + wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx); } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) { u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED; pcgroup_encrypt_val = "WEP104"; @@ -869,8 +869,8 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, g_key_wep_params.key_idx = sme->key_idx; g_wep_keys_saved = true; - host_int_set_wep_default_key(priv->hWILCWFIDrv, sme->key_idx); - host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx); + wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx); + wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx); } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) { if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) { u8security = ENCRYPT_ENABLED | WPA2 | TKIP; @@ -961,15 +961,15 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, if (!pstrWFIDrv->p2p_connect) u8WLANChannel = pstrNetworkInfo->u8channel; - linux_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid); + wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid); - s32Error = host_int_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid, + s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid, sme->ssid_len, sme->ie, sme->ie_len, CfgConnectResult, (void *)priv, u8security, tenuAuth_type, pstrNetworkInfo->u8channel, pstrNetworkInfo->pJoinParams); if (s32Error != 0) { - PRINT_ER("host_int_set_join_req(): Error(%d)\n", s32Error); + PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error); s32Error = -ENOENT; goto done; } @@ -996,14 +996,14 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_co struct host_if_drv *pstrWFIDrv; u8 NullBssid[ETH_ALEN] = {0}; - connecting = 0; + wilc_connecting = 0; priv = wiphy_priv(wiphy); /*Invalidate u8WLANChannel value on wlan0 disconnect*/ pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv; if (!pstrWFIDrv->p2p_connect) u8WLANChannel = INVALID_CHANNEL; - linux_wlan_set_bssid(priv->dev, NullBssid); + wilc_wlan_set_bssid(priv->dev, NullBssid); PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code); @@ -1012,7 +1012,7 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_co bWilc_ie = false; pstrWFIDrv->p2p_timeout = 0; - s32Error = host_int_disconnect(priv->hWILCWFIDrv, reason_code); + s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code); if (s32Error != 0) { PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error); s32Error = -EINVAL; @@ -1083,7 +1083,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, else u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED; - host_int_add_wep_key_bss_ap(priv->hWILCWFIDrv, params->key, params->key_len, key_index, u8mode, tenuAuth_type); + wilc_add_wep_key_bss_ap(priv->hWILCWFIDrv, params->key, params->key_len, key_index, u8mode, tenuAuth_type); break; } if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) { @@ -1097,7 +1097,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, for (i = 0; i < params->key_len; i++) PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]); } - host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index); + wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index); } break; @@ -1160,7 +1160,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, } - host_int_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen, + wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen, key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode); } else { @@ -1205,7 +1205,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, priv->wilc_ptk[key_index]->key_len = params->key_len; priv->wilc_ptk[key_index]->seq_len = params->seq_len; - host_int_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr, + wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr, pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index); } break; @@ -1247,7 +1247,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, g_gtk_keys_saved = true; } - host_int_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen, + wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen, key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode); } else { if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) { @@ -1283,7 +1283,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, g_ptk_keys_saved = true; } - host_int_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr, + wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr, pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index); PRINT_D(CFG80211_DBG, "Adding pairwise key\n"); if (INFO) { @@ -1372,7 +1372,7 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev, g_key_gtk_params.seq = NULL; /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/ - set_machw_change_vir_if(netdev, false); + wilc_set_machw_change_vir_if(netdev, false); } if (key_index >= 0 && key_index <= 3) { @@ -1380,10 +1380,10 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev, priv->WILC_WFI_wep_key_len[key_index] = 0; PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index); - host_int_remove_wep_key(priv->hWILCWFIDrv, key_index); + wilc_remove_wep_key(priv->hWILCWFIDrv, key_index); } else { PRINT_D(CFG80211_DBG, "Removing all installed keys\n"); - host_int_remove_key(priv->hWILCWFIDrv, mac_addr); + wilc_remove_key(priv->hWILCWFIDrv, mac_addr); } return 0; @@ -1461,7 +1461,7 @@ static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 ke if (key_index != priv->WILC_WFI_wep_default) { - host_int_set_wep_default_key(priv->hWILCWFIDrv, key_index); + wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index); } return 0; @@ -1509,7 +1509,7 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME); - host_int_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time)); + wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time)); sinfo->inactive_time = 1000 * inactive_time; PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time); @@ -1518,7 +1518,7 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, if (nic->iftype == STATION_MODE) { struct rf_info strStatistics; - host_int_get_statistics(priv->hWILCWFIDrv, &strStatistics); + wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics); sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) | BIT(NL80211_STA_INFO_RX_PACKETS) | @@ -1534,9 +1534,9 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) && (strStatistics.link_speed != DEFAULT_LINK_SPEED)) - enable_tcp_ack_filter(true); + wilc_enable_tcp_ack_filter(true); else if (strStatistics.link_speed != DEFAULT_LINK_SPEED) - enable_tcp_ack_filter(false); + wilc_enable_tcp_ack_filter(false); PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets, sinfo->tx_failed, sinfo->txrate.legacy); @@ -1623,7 +1623,7 @@ static int set_wiphy_params(struct wiphy *wiphy, u32 changed) } PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n"); - s32Error = hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal); + s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal); if (s32Error) PRINT_ER("Error in setting WIPHY PARAMS\n"); @@ -1678,7 +1678,7 @@ static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev, if (!s32Error) { PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n"); - s32Error = host_int_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list); + s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list); } return s32Error; } @@ -2101,7 +2101,7 @@ static int remain_on_channel(struct wiphy *wiphy, priv->strRemainOnChanParams.u32ListenDuration = duration; priv->strRemainOnChanParams.u32ListenSessionID++; - s32Error = host_int_remain_on_channel(priv->hWILCWFIDrv + s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv , priv->strRemainOnChanParams.u32ListenSessionID , duration , chan->hw_value @@ -2136,7 +2136,7 @@ static int cancel_remain_on_channel(struct wiphy *wiphy, PRINT_D(CFG80211_DBG, "Cancel remain on channel\n"); - s32Error = host_int_ListenStateExpired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID); + s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID); return s32Error; } /** @@ -2149,7 +2149,7 @@ static int cancel_remain_on_channel(struct wiphy *wiphy, * @date 01 JUL 2012 * @version */ -extern bool bEnablePS; +extern bool wilc_enable_ps; static int mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, struct cfg80211_mgmt_tx_params *params, @@ -2196,7 +2196,7 @@ static int mgmt_tx(struct wiphy *wiphy, if (ieee80211_is_probe_resp(mgmt->frame_control)) { PRINT_D(GENERIC_DBG, "TX: Probe Response\n"); PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value); - host_int_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value); + wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value); /*Save the current channel after we tune to it*/ curr_channel = chan->hw_value; } else if (ieee80211_is_action(mgmt->frame_control)) { @@ -2211,7 +2211,7 @@ static int mgmt_tx(struct wiphy *wiphy, if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC || buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) { PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value); - host_int_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value); + wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value); /*Save the current channel after we tune to it*/ curr_channel = chan->hw_value; } @@ -2383,7 +2383,7 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, PRINT_D(GENERIC_DBG, "Return since mac is closed\n"); return; } - host_int_frame_register(priv->hWILCWFIDrv, frame_type, reg); + wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg); } @@ -2434,7 +2434,7 @@ static int dump_station(struct wiphy *wiphy, struct net_device *dev, sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); - host_int_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal)); + wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal)); return 0; @@ -2466,8 +2466,8 @@ static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, return -EIO; } - if (bEnablePS) - host_int_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout); + if (wilc_enable_ps) + wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout); return 0; @@ -2507,17 +2507,17 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, bWilc_ie = false; - g_obtainingIP = false; - del_timer(&hDuringIpTimer); + wilc_optaining_ip = false; + del_timer(&wilc_during_ip_timer); PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n"); /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/ if (g_ptk_keys_saved && g_gtk_keys_saved) { - set_machw_change_vir_if(dev, true); + wilc_set_machw_change_vir_if(dev, true); } switch (type) { case NL80211_IFTYPE_STATION: - connecting = 0; + wilc_connecting = 0; PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n"); /* send delba over wlan interface */ @@ -2534,30 +2534,30 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, nic->iftype = STATION_MODE; if (wl->initialized) { - host_int_del_All_Rx_BASession(priv->hWILCWFIDrv, - wl->vif[0].bssid, TID); + wilc_del_all_rx_ba_session(priv->hWILCWFIDrv, + wl->vif[0].bssid, TID); /* ensure that the message Q is empty */ - host_int_wait_msg_queue_idle(); + wilc_wait_msg_queue_idle(); /*Eliminate host interface blocking state*/ up(&wl->cfg_event); wilc1000_wlan_deinit(dev); wilc1000_wlan_init(dev, nic); - g_wilc_initialized = 1; + wilc_initialized = 1; nic->iftype = interface_type; /*Setting interface 1 drv handler and mac address in newly downloaded FW*/ - host_int_set_wfi_drv_handler(wl->vif[0].hif_drv); - host_int_set_MacAddress(wl->vif[0].hif_drv, + wilc_set_wfi_drv_handler(wl->vif[0].hif_drv); + wilc_set_mac_address(wl->vif[0].hif_drv, wl->vif[0].src_addr); - host_int_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE); + wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE); /*Add saved WEP keys, if any*/ if (g_wep_keys_saved) { - host_int_set_wep_default_key(wl->vif[0].hif_drv, + wilc_set_wep_default_keyid(wl->vif[0].hif_drv, g_key_wep_params.key_idx); - host_int_add_wep_key_bss_sta(wl->vif[0].hif_drv, + wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv, g_key_wep_params.key, g_key_wep_params.key_len, g_key_wep_params.key_idx); @@ -2565,7 +2565,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, /*No matter the driver handler passed here, it will be overwriiten*/ /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/ - host_int_flush_join_req(priv->hWILCWFIDrv); + wilc_flush_join_req(priv->hWILCWFIDrv); /*Add saved PTK and GTK keys, if any*/ if (g_ptk_keys_saved && g_gtk_keys_saved) { @@ -2594,25 +2594,25 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, for (i = 0; i < num_reg_frame; i++) { PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type, nic->g_struct_frame_reg[i].reg); - host_int_frame_register(priv->hWILCWFIDrv, + wilc_frame_register(priv->hWILCWFIDrv, nic->g_struct_frame_reg[i].frame_type, nic->g_struct_frame_reg[i].reg); } } - bEnablePS = true; - host_int_set_power_mgmt(priv->hWILCWFIDrv, 1, 0); + wilc_enable_ps = true; + wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0); } break; case NL80211_IFTYPE_P2P_CLIENT: - bEnablePS = false; - host_int_set_power_mgmt(priv->hWILCWFIDrv, 0, 0); - connecting = 0; + wilc_enable_ps = false; + wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0); + wilc_connecting = 0; PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n"); - host_int_del_All_Rx_BASession(priv->hWILCWFIDrv, - wl->vif[0].bssid, TID); + wilc_del_all_rx_ba_session(priv->hWILCWFIDrv, + wl->vif[0].bssid, TID); dev->ieee80211_ptr->iftype = type; priv->wdev->iftype = type; @@ -2624,30 +2624,30 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, if (wl->initialized) { /* ensure that the message Q is empty */ - host_int_wait_msg_queue_idle(); + wilc_wait_msg_queue_idle(); wilc1000_wlan_deinit(dev); wilc1000_wlan_init(dev, nic); - g_wilc_initialized = 1; + wilc_initialized = 1; - host_int_set_wfi_drv_handler(wl->vif[0].hif_drv); - host_int_set_MacAddress(wl->vif[0].hif_drv, + wilc_set_wfi_drv_handler(wl->vif[0].hif_drv); + wilc_set_mac_address(wl->vif[0].hif_drv, wl->vif[0].src_addr); - host_int_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE); + wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE); /*Add saved WEP keys, if any*/ if (g_wep_keys_saved) { - host_int_set_wep_default_key(wl->vif[0].hif_drv, - g_key_wep_params.key_idx); - host_int_add_wep_key_bss_sta(wl->vif[0].hif_drv, - g_key_wep_params.key, - g_key_wep_params.key_len, - g_key_wep_params.key_idx); + wilc_set_wep_default_keyid(wl->vif[0].hif_drv, + g_key_wep_params.key_idx); + wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv, + g_key_wep_params.key, + g_key_wep_params.key_len, + g_key_wep_params.key_idx); } /*No matter the driver handler passed here, it will be overwriiten*/ /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/ - host_int_flush_join_req(priv->hWILCWFIDrv); + wilc_flush_join_req(priv->hWILCWFIDrv); /*Add saved PTK and GTK keys, if any*/ if (g_ptk_keys_saved && g_gtk_keys_saved) { @@ -2674,13 +2674,13 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, /*Refresh scan, to refresh the scan results to the wpa_supplicant. Set MachHw to false to enable further key installments*/ refresh_scan(priv, 1, true); - set_machw_change_vir_if(dev, false); + wilc_set_machw_change_vir_if(dev, false); if (wl->initialized) { for (i = 0; i < num_reg_frame; i++) { PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type, nic->g_struct_frame_reg[i].reg); - host_int_frame_register(priv->hWILCWFIDrv, + wilc_frame_register(priv->hWILCWFIDrv, nic->g_struct_frame_reg[i].frame_type, nic->g_struct_frame_reg[i].reg); } @@ -2689,7 +2689,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, break; case NL80211_IFTYPE_AP: - bEnablePS = false; + wilc_enable_ps = false; PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type); dev->ieee80211_ptr->iftype = type; priv->wdev->iftype = type; @@ -2697,17 +2697,17 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv); PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n"); - linux_wlan_get_firmware(dev); + wilc_wlan_get_firmware(dev); /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/ if (wl->initialized) { nic->iftype = AP_MODE; - mac_close(dev); - mac_open(dev); + wilc_mac_close(dev); + wilc_mac_open(dev); for (i = 0; i < num_reg_frame; i++) { PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type, nic->g_struct_frame_reg[i].reg); - host_int_frame_register(priv->hWILCWFIDrv, + wilc_frame_register(priv->hWILCWFIDrv, nic->g_struct_frame_reg[i].frame_type, nic->g_struct_frame_reg[i].reg); } @@ -2717,16 +2717,16 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, case NL80211_IFTYPE_P2P_GO: PRINT_D(GENERIC_DBG, "start duringIP timer\n"); - g_obtainingIP = true; - mod_timer(&hDuringIpTimer, jiffies + msecs_to_jiffies(duringIP_TIME)); - host_int_set_power_mgmt(priv->hWILCWFIDrv, 0, 0); + wilc_optaining_ip = true; + mod_timer(&wilc_during_ip_timer, jiffies + msecs_to_jiffies(duringIP_TIME)); + wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0); /*Delete block ack has to be the latest config packet*/ /*sent before downloading new FW. This is because it blocks on*/ /*hWaitResponse semaphore, which allows previous config*/ /*packets to actually take action on old FW*/ - host_int_del_All_Rx_BASession(priv->hWILCWFIDrv, - wl->vif[0].bssid, TID); - bEnablePS = false; + wilc_del_all_rx_ba_session(priv->hWILCWFIDrv, + wl->vif[0].bssid, TID); + wilc_enable_ps = false; PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n"); dev->ieee80211_ptr->iftype = type; priv->wdev->iftype = type; @@ -2739,23 +2739,23 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, nic->iftype = GO_MODE; /* ensure that the message Q is empty */ - host_int_wait_msg_queue_idle(); + wilc_wait_msg_queue_idle(); wilc1000_wlan_deinit(dev); wilc1000_wlan_init(dev, nic); - g_wilc_initialized = 1; + wilc_initialized = 1; /*Setting interface 1 drv handler and mac address in newly downloaded FW*/ - host_int_set_wfi_drv_handler(wl->vif[0].hif_drv); - host_int_set_MacAddress(wl->vif[0].hif_drv, - wl->vif[0].src_addr); - host_int_set_operation_mode(priv->hWILCWFIDrv, AP_MODE); + wilc_set_wfi_drv_handler(wl->vif[0].hif_drv); + wilc_set_mac_address(wl->vif[0].hif_drv, + wl->vif[0].src_addr); + wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE); /*Add saved WEP keys, if any*/ if (g_wep_keys_saved) { - host_int_set_wep_default_key(wl->vif[0].hif_drv, - g_key_wep_params.key_idx); - host_int_add_wep_key_bss_sta(wl->vif[0].hif_drv, + wilc_set_wep_default_keyid(wl->vif[0].hif_drv, + g_key_wep_params.key_idx); + wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv, g_key_wep_params.key, g_key_wep_params.key_len, g_key_wep_params.key_idx); @@ -2763,7 +2763,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, /*No matter the driver handler passed here, it will be overwriiten*/ /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/ - host_int_flush_join_req(priv->hWILCWFIDrv); + wilc_flush_join_req(priv->hWILCWFIDrv); /*Add saved PTK and GTK keys, if any*/ if (g_ptk_keys_saved && g_gtk_keys_saved) { @@ -2794,7 +2794,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, for (i = 0; i < num_reg_frame; i++) { PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type, nic->g_struct_frame_reg[i].reg); - host_int_frame_register(priv->hWILCWFIDrv, + wilc_frame_register(priv->hWILCWFIDrv, nic->g_struct_frame_reg[i].frame_type, nic->g_struct_frame_reg[i].reg); } @@ -2857,9 +2857,9 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev, if (s32Error != 0) PRINT_ER("Error in setting channel\n"); - linux_wlan_set_bssid(dev, wl->vif[0].src_addr); + wilc_wlan_set_bssid(dev, wl->vif[0].src_addr); - s32Error = host_int_add_beacon(priv->hWILCWFIDrv, + s32Error = wilc_add_beacon(priv->hWILCWFIDrv, settings->beacon_interval, settings->dtim_period, beacon->head_len, (u8 *)beacon->head, @@ -2890,7 +2890,7 @@ static int change_beacon(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "Setting beacon\n"); - s32Error = host_int_add_beacon(priv->hWILCWFIDrv, + s32Error = wilc_add_beacon(priv->hWILCWFIDrv, 0, 0, beacon->head_len, (u8 *)beacon->head, @@ -2921,9 +2921,9 @@ static int stop_ap(struct wiphy *wiphy, struct net_device *dev) PRINT_D(HOSTAPD_DBG, "Deleting beacon\n"); - linux_wlan_set_bssid(dev, NullBssid); + wilc_wlan_set_bssid(dev, NullBssid); - s32Error = host_int_del_beacon(priv->hWILCWFIDrv); + s32Error = wilc_del_beacon(priv->hWILCWFIDrv); if (s32Error) PRINT_ER("Host delete beacon fail\n"); @@ -3003,7 +3003,7 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.flags_set); - s32Error = host_int_add_station(priv->hWILCWFIDrv, &strStaParams); + s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams); if (s32Error) PRINT_ER("Host add station fail\n"); } @@ -3040,12 +3040,12 @@ static int del_station(struct wiphy *wiphy, struct net_device *dev, if (mac == NULL) { PRINT_D(HOSTAPD_DBG, "All associated stations\n"); - s32Error = host_int_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss); + s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss); } else { PRINT_D(HOSTAPD_DBG, "With mac address: %x%x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } - s32Error = host_int_del_station(priv->hWILCWFIDrv, mac); + s32Error = wilc_del_station(priv->hWILCWFIDrv, mac); if (s32Error) PRINT_ER("Host delete station fail\n"); @@ -3127,7 +3127,7 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.flags_set); - s32Error = host_int_edit_station(priv->hWILCWFIDrv, &strStaParams); + s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams); if (s32Error) PRINT_ER("Host edit station fail\n"); } @@ -3387,7 +3387,7 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net) wdev->wiphy->interface_modes, wdev->iftype); #ifdef WILC_SDIO - set_wiphy_dev(wdev->wiphy, &local_sdio_func->dev); + set_wiphy_dev(wdev->wiphy, &wilc_sdio_func->dev); #endif /*Register wiphy structure*/ @@ -3424,7 +3424,7 @@ int wilc_init_host_int(struct net_device *net) priv = wdev_priv(net->ieee80211_ptr); if (op_ifcs == 0) { setup_timer(&hAgingTimer, remove_network_from_shadow, 0); - setup_timer(&hDuringIpTimer, clear_duringIP, 0); + setup_timer(&wilc_during_ip_timer, clear_duringIP, 0); } op_ifcs++; if (s32Error < 0) { @@ -3437,7 +3437,7 @@ int wilc_init_host_int(struct net_device *net) priv->bInP2PlistenState = false; sema_init(&(priv->hSemScanReq), 1); - s32Error = host_int_init(net, &priv->hWILCWFIDrv); + s32Error = wilc_init(net, &priv->hWILCWFIDrv); if (s32Error) PRINT_ER("Error while initializing hostinterface\n"); @@ -3467,13 +3467,13 @@ int wilc_deinit_host_int(struct net_device *net) op_ifcs--; - s32Error = host_int_deinit(priv->hWILCWFIDrv); + s32Error = wilc_deinit(priv->hWILCWFIDrv); /* Clear the Shadow scan */ clear_shadow_scan(priv); if (op_ifcs == 0) { PRINT_D(CORECONFIG_DBG, "destroy during ip\n"); - del_timer_sync(&hDuringIpTimer); + del_timer_sync(&wilc_during_ip_timer); } if (s32Error) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h index 9f9a9aeb36554..5262b2513fa84 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h @@ -103,6 +103,6 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, #define TCP_ACK_FILTER_LINK_SPEED_THRESH 54 #define DEFAULT_LINK_SPEED 72 -void enable_tcp_ack_filter(bool value); +void wilc_enable_tcp_ack_filter(bool value); #endif diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 54ed723367750..2a0a3b166a7cc 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -206,7 +206,7 @@ struct WILC_WFI_mon_priv { struct net_device *real_ndev; }; -extern struct wilc *g_linux_wlan; +extern struct wilc *wilc_dev; extern struct net_device *WILC_WFI_devs[]; void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset); void linux_wlan_mac_indicate(struct wilc *wilc, int flag); @@ -217,7 +217,7 @@ void wl_wlan_cleanup(struct wilc *wilc); int wilc_netdev_init(struct wilc **wilc); void wilc1000_wlan_deinit(struct net_device *dev); void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size); -u16 set_machw_change_vir_if(struct net_device *dev, bool value); -int linux_wlan_get_firmware(struct net_device *dev); -int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid); +u16 wilc_set_machw_change_vir_if(struct net_device *dev, bool value); +int wilc_wlan_get_firmware(struct net_device *dev); +int wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid); #endif diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 5c8c59257f589..a797c61e80615 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -3,9 +3,9 @@ #include "wilc_wlan_cfg.h" #ifdef WILC_SDIO -extern struct wilc_hif_func hif_sdio; +extern struct wilc_hif_func wilc_hif_sdio; #else -extern struct wilc_hif_func hif_spi; +extern struct wilc_hif_func wilc_hif_spi; #endif u32 wilc_get_chipid(u8 update); @@ -64,7 +64,7 @@ static CHIP_PS_STATE_T chip_ps_state = CHIP_WAKEDUP; static inline void acquire_bus(BUS_ACQUIRE_T acquire) { - mutex_lock(&g_linux_wlan->hif_cs); + mutex_lock(&wilc_dev->hif_cs); #ifndef WILC_OPTIMIZE_SLEEP_INT if (chip_ps_state != CHIP_WAKEDUP) #endif @@ -80,7 +80,7 @@ static inline void release_bus(BUS_RELEASE_T release) if (release == RELEASE_ALLOW_SLEEP) chip_allow_sleep(); #endif - mutex_unlock(&g_linux_wlan->hif_cs); + mutex_unlock(&wilc_dev->hif_cs); } #ifdef TCP_ACK_FILTER @@ -169,11 +169,11 @@ static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe) { wilc_wlan_dev_t *p = &g_wlan; unsigned long flags; - if (linux_wlan_lock_timeout(&g_linux_wlan->txq_add_to_head_cs, + if (linux_wlan_lock_timeout(&wilc_dev->txq_add_to_head_cs, CFG_PKTS_TIMEOUT)) return -1; - spin_lock_irqsave(&g_linux_wlan->txq_spinlock, flags); + spin_lock_irqsave(&wilc_dev->txq_spinlock, flags); if (!p->txq_head) { tqe->next = NULL; @@ -189,9 +189,9 @@ static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe) p->txq_entries += 1; PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", p->txq_entries); - spin_unlock_irqrestore(&g_linux_wlan->txq_spinlock, flags); - up(&g_linux_wlan->txq_add_to_head_cs); - up(&g_linux_wlan->txq_event); + spin_unlock_irqrestore(&wilc_dev->txq_spinlock, flags); + up(&wilc_dev->txq_add_to_head_cs); + up(&wilc_dev->txq_event); PRINT_D(TX_DBG, "Wake up the txq_handler\n"); return 0; @@ -266,9 +266,9 @@ static inline int remove_TCP_related(void) wilc_wlan_dev_t *p = &g_wlan; unsigned long flags; - spin_lock_irqsave(&g_linux_wlan->txq_spinlock, flags); + spin_lock_irqsave(&wilc_dev->txq_spinlock, flags); - spin_unlock_irqrestore(&g_linux_wlan->txq_spinlock, flags); + spin_unlock_irqrestore(&wilc_dev->txq_spinlock, flags); return 0; } @@ -393,7 +393,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) static bool enabled = false; -void enable_tcp_ack_filter(bool value) +void wilc_enable_tcp_ack_filter(bool value) { enabled = value; } @@ -413,7 +413,7 @@ static int wilc_wlan_txq_add_cfg_pkt(u8 *buffer, u32 buffer_size) PRINT_D(TX_DBG, "Adding config packet ...\n"); if (p->quit) { PRINT_D(TX_DBG, "Return due to clear function\n"); - up(&g_linux_wlan->cfg_event); + up(&wilc_dev->cfg_event); return 0; } @@ -684,7 +684,7 @@ static inline void chip_wakeup(void) chip_ps_state = CHIP_WAKEDUP; } #endif -void chip_sleep_manually(void) +void wilc_chip_sleep_manually(void) { if (chip_ps_state != CHIP_WAKEDUP) return; @@ -1520,7 +1520,7 @@ int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, if (wilc_wlan_cfg_commit(WILC_CFG_SET, drv_handler)) ret_size = 0; - if (linux_wlan_lock_timeout(&g_linux_wlan->cfg_event, + if (linux_wlan_lock_timeout(&wilc_dev->cfg_event, CFG_PKTS_TIMEOUT)) { PRINT_D(TX_DBG, "Set Timed Out\n"); ret_size = 0; @@ -1556,7 +1556,7 @@ int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drv_handler) if (wilc_wlan_cfg_commit(WILC_CFG_QUERY, drv_handler)) ret_size = 0; - if (linux_wlan_lock_timeout(&g_linux_wlan->cfg_event, + if (linux_wlan_lock_timeout(&wilc_dev->cfg_event, CFG_PKTS_TIMEOUT)) { PRINT_D(TX_DBG, "Get Timed Out\n"); ret_size = 0; @@ -1670,18 +1670,18 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) sizeof(wilc_wlan_io_func_t)); #ifdef WILC_SDIO - if (!hif_sdio.hif_init(wilc, wilc_debug)) { + if (!wilc_hif_sdio.hif_init(wilc, wilc_debug)) { ret = -EIO; goto _fail_; } - memcpy((void *)&g_wlan.hif_func, &hif_sdio, + memcpy((void *)&g_wlan.hif_func, &wilc_hif_sdio, sizeof(struct wilc_hif_func)); #else - if (!hif_spi.hif_init(wilc, wilc_debug)) { + if (!wilc_hif_spi.hif_init(wilc, wilc_debug)) { ret = -EIO; goto _fail_; } - memcpy((void *)&g_wlan.hif_func, &hif_spi, + memcpy((void *)&g_wlan.hif_func, &wilc_hif_spi, sizeof(struct wilc_hif_func)); #endif @@ -1733,7 +1733,7 @@ _fail_: return ret; } -u16 set_machw_change_vir_if(struct net_device *dev, bool value) +u16 wilc_set_machw_change_vir_if(struct net_device *dev, bool value) { u16 ret; u32 reg; diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 64fd019595cec..6cb6abe26096d 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -290,5 +290,5 @@ int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drv_handler); int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size); int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func); -void chip_sleep_manually(void); +void wilc_chip_sleep_manually(void); #endif diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.c b/drivers/staging/wilc1000/wilc_wlan_cfg.c index e23796392e9c1..274052f36400c 100644 --- a/drivers/staging/wilc1000/wilc_wlan_cfg.c +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.c @@ -532,17 +532,17 @@ int wilc_wlan_cfg_indicate_rx(u8 *frame, int size, struct wilc_cfg_rsp *rsp) rsp->seq_no = msg_id; /*call host interface info parse as well*/ PRINT_INFO(RX_DBG, "Info message received\n"); - GnrlAsyncInfoReceived(frame - 4, size + 4); + wilc_gnrl_async_info_received(frame - 4, size + 4); break; case 'N': - NetworkInfoReceived(frame - 4, size + 4); + wilc_network_info_received(frame - 4, size + 4); rsp->type = 0; break; case 'S': PRINT_INFO(RX_DBG, "Scan Notification Received\n"); - host_int_ScanCompleteReceived(frame - 4, size + 4); + wilc_scan_complete_received(frame - 4, size + 4); break; default: -- GitLab From 491880eb47a693bb194096eec094b2166d2b2354 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:04:55 +0100 Subject: [PATCH 1612/2855] staging/wilc1000: move extern declarations to headers 'extern' declarations belong into a header file rather than a .c file, to ensure that the definition matches the declaration. This moves all declarations into a header file that seems most appropriate for it. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 9 +------- drivers/staging/wilc1000/host_interface.h | 9 ++++++++ drivers/staging/wilc1000/linux_mon.c | 3 --- drivers/staging/wilc1000/linux_wlan.c | 9 -------- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 6 +----- .../staging/wilc1000/wilc_wfi_cfgoperations.h | 1 - drivers/staging/wilc1000/wilc_wfi_netdevice.h | 2 ++ drivers/staging/wilc1000/wilc_wlan.c | 8 +------ drivers/staging/wilc1000/wilc_wlan.h | 21 +++++++++++++++++++ 9 files changed, 35 insertions(+), 33 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 228a2fefe7148..d968483c6f00d 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -4,17 +4,12 @@ #include #include "host_interface.h" #include "coreconfigurator.h" +#include "wilc_wlan.h" #include "wilc_wlan_if.h" #include "wilc_msgqueue.h" #include #include "wilc_wfi_netdevice.h" -extern u8 wilc_connecting; - -extern struct timer_list wilc_during_ip_timer; - -extern u8 wilc_initialized; - #define HOST_IF_MSG_SCAN 0 #define HOST_IF_MSG_CONNECT 1 #define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO 2 @@ -271,8 +266,6 @@ static struct host_if_drv *join_req_drv; static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo); -extern int wilc_wlan_get_num_conn_ifcs(void); - static int add_handler_in_list(struct host_if_drv *handler) { int i; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index d0b85a53c29ee..efeb9e2335896 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -394,4 +394,13 @@ void wilc_free_join_params(void *pJoinParams); s32 wilc_get_statistics(struct host_if_drv *hWFIDrv, struct rf_info *pstrStatistics); void wilc_resolve_disconnect_aberration(struct host_if_drv *hif_drv); + +extern bool wilc_optaining_ip; +extern u8 wilc_connected_SSID[6]; +extern u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; + +extern int wilc_connecting; +extern u8 wilc_initialized; +extern struct timer_list wilc_during_ip_timer; + #endif diff --git a/drivers/staging/wilc1000/linux_mon.c b/drivers/staging/wilc1000/linux_mon.c index f0a458764ff2a..e550027645b79 100644 --- a/drivers/staging/wilc1000/linux_mon.c +++ b/drivers/staging/wilc1000/linux_mon.c @@ -26,9 +26,6 @@ struct wilc_wfi_radiotap_cb_hdr { static struct net_device *wilc_wfi_mon; /* global monitor netdev */ -extern int wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev); - - static u8 srcAdd[6]; static u8 bssid[6]; static u8 broadcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index d3d07fc30e23e..f1e70b225deba 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -37,10 +37,6 @@ #define _linux_wlan_device_detection() {} #define _linux_wlan_device_removal() {} -extern bool wilc_optaining_ip; -extern u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; -extern struct timer_list wilc_during_ip_timer; - static int linux_wlan_device_power(int on_off) { PRINT_D(INIT_DBG, "linux_wlan_device_power.. (%d)\n", on_off); @@ -81,14 +77,9 @@ static struct semaphore close_exit_sync; static int wlan_deinit_locks(struct net_device *dev); static void wlan_deinitialize_threads(struct net_device *dev); -extern void WILC_WFI_monitor_rx(u8 *buff, u32 size); -extern void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size); static void linux_wlan_tx_complete(void *priv, int status); static int mac_init_fn(struct net_device *ndev); -int wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev); -int wilc_mac_open(struct net_device *ndev); -int wilc_mac_close(struct net_device *ndev); static struct net_device_stats *mac_stats(struct net_device *dev); static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd); static void wilc_set_multicast_list(struct net_device *dev); diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index f8fd7a895d449..49b82b4a06884 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -14,6 +14,7 @@ #ifdef WILC_SDIO #include "linux_wlan_sdio.h" #endif +#include "host_interface.h" #include #define IS_MANAGMEMENT 0x100 @@ -29,10 +30,8 @@ static u32 u32LastScannedNtwrksCountShadow; struct timer_list wilc_during_ip_timer; static struct timer_list hAgingTimer; static u8 op_ifcs; -extern u8 wilc_connected_SSID[6]; u8 wilc_initialized = 1; -extern bool wilc_optaining_ip; #define CHAN2G(_channel, _freq, _flags) { \ .band = IEEE80211_BAND_2GHZ, \ @@ -2149,7 +2148,6 @@ static int cancel_remain_on_channel(struct wiphy *wiphy, * @date 01 JUL 2012 * @version */ -extern bool wilc_enable_ps; static int mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, struct cfg80211_mgmt_tx_params *params, @@ -2484,8 +2482,6 @@ static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, * @date 01 MAR 2012 * @version 1.0 */ -int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic); - static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, enum nl80211_iftype type, u32 *flags, struct vif_params *params) { diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h index 5262b2513fa84..ae2aaea508db4 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h @@ -103,6 +103,5 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, #define TCP_ACK_FILTER_LINK_SPEED_THRESH 54 #define DEFAULT_LINK_SPEED 72 -void wilc_enable_tcp_ack_filter(bool value); #endif diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 2a0a3b166a7cc..3358fe3bcd0aa 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -206,6 +206,8 @@ struct WILC_WFI_mon_priv { struct net_device *real_ndev; }; +int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic); + extern struct wilc *wilc_dev; extern struct net_device *WILC_WFI_devs[]; void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset); diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index a797c61e80615..f7359f79ff8d1 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1,14 +1,8 @@ #include "wilc_wlan_if.h" +#include "wilc_wlan.h" #include "wilc_wfi_netdevice.h" #include "wilc_wlan_cfg.h" -#ifdef WILC_SDIO -extern struct wilc_hif_func wilc_hif_sdio; -#else -extern struct wilc_hif_func wilc_hif_spi; -#endif -u32 wilc_get_chipid(u8 update); - typedef struct { int quit; wilc_wlan_io_func_t io_func; diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 6cb6abe26096d..326d71bf91dfb 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -1,7 +1,10 @@ #ifndef WILC_WLAN_H #define WILC_WLAN_H +#include + #define ISWILC1000(id) ((id & 0xfffff000) == 0x100000 ? 1 : 0) + /******************************************** * * Mac eth header length @@ -255,6 +258,9 @@ struct wilc_hif_func { void (*hif_set_default_bus_speed)(void); }; +extern struct wilc_hif_func wilc_hif_spi; +extern struct wilc_hif_func wilc_hif_sdio; + /******************************************** * * Configuration Structure @@ -276,6 +282,8 @@ struct wilc_cfg_rsp { u32 seq_no; }; +struct wilc; + int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size); int wilc_wlan_start(void); int wilc_wlan_stop(void); @@ -291,4 +299,17 @@ int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size); int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func); void wilc_chip_sleep_manually(void); + +void wilc_enable_tcp_ack_filter(bool value); +int wilc_wlan_get_num_conn_ifcs(void); +int wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev); + +int wilc_mac_open(struct net_device *ndev); +int wilc_mac_close(struct net_device *ndev); + +int wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *pBSSID); +void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size); + +extern bool wilc_enable_ps; + #endif -- GitLab From b4d04c15e17156f18a57576d9e958792add30a6a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:04:56 +0100 Subject: [PATCH 1613/2855] staging/wilc1000: use NO_SECURITY instead of NO_ENCRYPT The linux_wlan.c file uses a set of enums from wilc_wlan_if.h, with the exception of the NO_ENCRYPT that comes from wilc_wfi_cfgoperations.h. The two sets of enums clearly have the same intention but are defined a bit different. To prepare to clean up the ones in wilc_wfi_cfgoperations.h, this first changes over the only other user. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index f1e70b225deba..040caa0d0d0be 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -643,7 +643,7 @@ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_ni if (!wilc_wlan_cfg_set(0, WID_POWER_MANAGEMENT, c_val, 1, 0, 0)) goto _fail_; - c_val[0] = NO_ENCRYPT; + c_val[0] = NO_SECURITY; /* NO_ENCRYPT, 0x79 */ if (!wilc_wlan_cfg_set(0, WID_11I_MODE, c_val, 1, 0, 0)) goto _fail_; -- GitLab From 15162fbc78a74a5910e84ad310934aab6b84be02 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:04:57 +0100 Subject: [PATCH 1614/2855] staging/wilc1000: avoid static definitions in header The wilc_wfi_cfgoperations.h header defines the ieee80211_txrx_stypes and cipher_suites variables that are only used in wilc_wfi_cfgoperations.c and should not be shared in a header file. This moves over all that data into the .c file, and also moves all the macro definitions from the file that are also not needed here. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 84 +++++++++++++++++++ .../staging/wilc1000/wilc_wfi_cfgoperations.h | 83 ------------------ 2 files changed, 84 insertions(+), 83 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 49b82b4a06884..46c3f578a6fdc 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -17,6 +17,90 @@ #include "host_interface.h" #include +/* The following macros describe the bitfield map used by the firmware to determine its 11i mode */ +#define NO_ENCRYPT 0 +#define ENCRYPT_ENABLED BIT(0) +#define WEP BIT(1) +#define WEP_EXTENDED BIT(2) +#define WPA BIT(3) +#define WPA2 BIT(4) +#define AES BIT(5) +#define TKIP BIT(6) + +/*Public action frame index IDs*/ +#define FRAME_TYPE_ID 0 +#define ACTION_CAT_ID 24 +#define ACTION_SUBTYPE_ID 25 +#define P2P_PUB_ACTION_SUBTYPE 30 + +/*Public action frame Attribute IDs*/ +#define ACTION_FRAME 0xd0 +#define GO_INTENT_ATTR_ID 0x04 +#define CHANLIST_ATTR_ID 0x0b +#define OPERCHAN_ATTR_ID 0x11 +#define PUB_ACTION_ATTR_ID 0x04 +#define P2PELEM_ATTR_ID 0xdd + +/*Public action subtype values*/ +#define GO_NEG_REQ 0x00 +#define GO_NEG_RSP 0x01 +#define GO_NEG_CONF 0x02 +#define P2P_INV_REQ 0x03 +#define P2P_INV_RSP 0x04 +#define PUBLIC_ACT_VENDORSPEC 0x09 +#define GAS_INTIAL_REQ 0x0a +#define GAS_INTIAL_RSP 0x0b + +#define INVALID_CHANNEL 0 + +#define nl80211_SCAN_RESULT_EXPIRE (3 * HZ) +#define SCAN_RESULT_EXPIRE (40 * HZ) + +static const u32 cipher_suites[] = { + WLAN_CIPHER_SUITE_WEP40, + WLAN_CIPHER_SUITE_WEP104, + WLAN_CIPHER_SUITE_TKIP, + WLAN_CIPHER_SUITE_CCMP, + WLAN_CIPHER_SUITE_AES_CMAC, +}; + +static const struct ieee80211_txrx_stypes + wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = { + [NL80211_IFTYPE_STATION] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + }, + [NL80211_IFTYPE_AP] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4) + }, + [NL80211_IFTYPE_P2P_CLIENT] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) + } +}; + +/* Time to stay on the channel */ +#define WILC_WFI_DWELL_PASSIVE 100 +#define WILC_WFI_DWELL_ACTIVE 40 + +#define TCP_ACK_FILTER_LINK_SPEED_THRESH 54 +#define DEFAULT_LINK_SPEED 72 + + #define IS_MANAGMEMENT 0x100 #define IS_MANAGMEMENT_CALLBACK 0x080 #define IS_MGMT_STATUS_SUCCES 0x040 diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h index ae2aaea508db4..158d98c0eb87e 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h @@ -10,86 +10,6 @@ #define NM_WFI_CFGOPERATIONS #include "wilc_wfi_netdevice.h" -/* The following macros describe the bitfield map used by the firmware to determine its 11i mode */ -#define NO_ENCRYPT 0 -#define ENCRYPT_ENABLED BIT(0) -#define WEP BIT(1) -#define WEP_EXTENDED BIT(2) -#define WPA BIT(3) -#define WPA2 BIT(4) -#define AES BIT(5) -#define TKIP BIT(6) - -/*Public action frame index IDs*/ -#define FRAME_TYPE_ID 0 -#define ACTION_CAT_ID 24 -#define ACTION_SUBTYPE_ID 25 -#define P2P_PUB_ACTION_SUBTYPE 30 - -/*Public action frame Attribute IDs*/ -#define ACTION_FRAME 0xd0 -#define GO_INTENT_ATTR_ID 0x04 -#define CHANLIST_ATTR_ID 0x0b -#define OPERCHAN_ATTR_ID 0x11 -#define PUB_ACTION_ATTR_ID 0x04 -#define P2PELEM_ATTR_ID 0xdd - -/*Public action subtype values*/ -#define GO_NEG_REQ 0x00 -#define GO_NEG_RSP 0x01 -#define GO_NEG_CONF 0x02 -#define P2P_INV_REQ 0x03 -#define P2P_INV_RSP 0x04 -#define PUBLIC_ACT_VENDORSPEC 0x09 -#define GAS_INTIAL_REQ 0x0a -#define GAS_INTIAL_RSP 0x0b - -#define INVALID_CHANNEL 0 - -#define nl80211_SCAN_RESULT_EXPIRE (3 * HZ) -#define SCAN_RESULT_EXPIRE (40 * HZ) - -static const u32 cipher_suites[] = { - WLAN_CIPHER_SUITE_WEP40, - WLAN_CIPHER_SUITE_WEP104, - WLAN_CIPHER_SUITE_TKIP, - WLAN_CIPHER_SUITE_CCMP, - WLAN_CIPHER_SUITE_AES_CMAC, -}; - -static const struct ieee80211_txrx_stypes - wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = { - [NL80211_IFTYPE_STATION] = { - .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4) - }, - [NL80211_IFTYPE_AP] = { - .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | - BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | - BIT(IEEE80211_STYPE_DISASSOC >> 4) | - BIT(IEEE80211_STYPE_AUTH >> 4) | - BIT(IEEE80211_STYPE_DEAUTH >> 4) | - BIT(IEEE80211_STYPE_ACTION >> 4) - }, - [NL80211_IFTYPE_P2P_CLIENT] = { - .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | - BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | - BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | - BIT(IEEE80211_STYPE_DISASSOC >> 4) | - BIT(IEEE80211_STYPE_AUTH >> 4) | - BIT(IEEE80211_STYPE_DEAUTH >> 4) - } -}; - -/* Time to stay on the channel */ -#define WILC_WFI_DWELL_PASSIVE 100 -#define WILC_WFI_DWELL_ACTIVE 40 - struct wireless_dev *wilc_create_wiphy(struct net_device *net); void wilc_free_wiphy(struct net_device *net); int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed); @@ -101,7 +21,4 @@ struct net_device *WILC_WFI_init_mon_interface(const char *name, struct net_devi void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, u16 frame_type, bool reg); -#define TCP_ACK_FILTER_LINK_SPEED_THRESH 54 -#define DEFAULT_LINK_SPEED 72 - #endif -- GitLab From 25ad41cb25142a8b50164ce7b4b9565173f3d48f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:04:58 +0100 Subject: [PATCH 1615/2855] staging/wilc1000: remove linux_wlan_{device_power,device_detection} The driver provides an interface for custom power management and detection that is meant to be filled by people customizing the driver. The default implementation of this is empty, and we don't actually want people to have to modify the source code. If anybody needs this, they need to describe the respective hardware specifics using device tree or platform data and make the driver handle this is a more general way. This removes the empty stubs. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 40 --------------------------- 1 file changed, 40 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 040caa0d0d0be..6e1ef99fc8563 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -31,40 +31,6 @@ #include "linux_wlan_spi.h" #endif - #define _linux_wlan_device_power_on() {} - #define _linux_wlan_device_power_off() {} - - #define _linux_wlan_device_detection() {} - #define _linux_wlan_device_removal() {} - -static int linux_wlan_device_power(int on_off) -{ - PRINT_D(INIT_DBG, "linux_wlan_device_power.. (%d)\n", on_off); - - if (on_off) { - _linux_wlan_device_power_on(); - } else { - _linux_wlan_device_power_off(); - } - - return 0; -} - -static int linux_wlan_device_detection(int on_off) -{ - PRINT_D(INIT_DBG, "linux_wlan_device_detection.. (%d)\n", on_off); - -#ifdef WILC_SDIO - if (on_off) { - _linux_wlan_device_detection(); - } else { - _linux_wlan_device_removal(); - } -#endif - - return 0; -} - static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr); static struct notifier_block g_dev_notifier = { @@ -1476,8 +1442,6 @@ void wl_wlan_cleanup(struct wilc *wilc) #if defined(WILC_DEBUGFS) wilc_debugfs_remove(); #endif - linux_wlan_device_detection(0); - linux_wlan_device_power(0); } int wilc_netdev_init(struct wilc **wilc) @@ -1579,10 +1543,6 @@ static int __init init_wilc_driver(void) printk("IN INIT FUNCTION\n"); printk("*** WILC1000 driver VERSION=[10.2] FW_VER=[10.2] ***\n"); - linux_wlan_device_power(1); - msleep(100); - linux_wlan_device_detection(1); - #ifdef WILC_SDIO { int ret; -- GitLab From 4bd7baf04de9ce5f8117da30d5ee2368f3c41b3e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:04:59 +0100 Subject: [PATCH 1616/2855] staging/wilc1000: move wilc_wlan_inp_t into struct wilc wilc_wlan_inp_t is an unnecessary indirection and requires linux_wlan.c to have knowledge of the specific sdio and spi front-ends. This removes the structure and places io_type directly inside the struct wilc. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 21 ++++++------------- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 1 + drivers/staging/wilc1000/wilc_wlan.c | 19 ++++++++--------- drivers/staging/wilc1000/wilc_wlan_if.h | 11 +--------- 4 files changed, 17 insertions(+), 35 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 6e1ef99fc8563..0747a0eefe92a 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -839,17 +839,6 @@ static int wlan_deinit_locks(struct net_device *dev) return 0; } -static void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic) -{ - PRINT_D(INIT_DBG, "Linux to Wlan services ...\n"); - -#ifdef WILC_SDIO - nwi->io_func.io_type = HIF_SDIO; -#else - nwi->io_func.io_type = HIF_SPI; -#endif -} - static int wlan_initialize_threads(struct net_device *dev) { perInterface_wlan_t *nic; @@ -893,7 +882,6 @@ static void wlan_deinitialize_threads(struct net_device *dev) int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) { - wilc_wlan_inp_t nwi; perInterface_wlan_t *nic = p_nic; int ret = 0; struct wilc *wl = nic->wilc; @@ -904,9 +892,12 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) wlan_init_locks(dev); - linux_to_wlan(&nwi, wl); - - ret = wilc_wlan_init(dev, &nwi); +#ifdef WILC_SDIO + wl->io_type = HIF_SDIO; +#else + wl->io_type = HIF_SPI; +#endif + ret = wilc_wlan_init(dev); if (ret < 0) { PRINT_ER("Initializing WILC_Wlan FAILED\n"); ret = -EIO; diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 3358fe3bcd0aa..0c608d73a22e7 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -156,6 +156,7 @@ struct wilc_vif { }; struct wilc { + int io_type; int mac_status; bool initialized; #if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index f7359f79ff8d1..2958689a13c67 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -5,7 +5,7 @@ typedef struct { int quit; - wilc_wlan_io_func_t io_func; + int io_type; struct wilc_hif_func hif_func; int cfg_frame_in_use; struct wilc_cfg_frame cfg_frame; @@ -576,7 +576,7 @@ static inline void chip_wakeup(void) u32 reg, clk_status_reg, trials = 0; u32 sleep_time; - if ((g_wlan.io_func.io_type & 0x1) == HIF_SPI) { + if ((g_wlan.io_type & 0x1) == HIF_SPI) { do { g_wlan.hif_func.hif_read_reg(1, ®); g_wlan.hif_func.hif_write_reg(1, reg | BIT(1)); @@ -590,7 +590,7 @@ static inline void chip_wakeup(void) } while ((wilc_get_chipid(true) == 0) && ((++trials % 3) == 0)); } while (wilc_get_chipid(true) == 0); - } else if ((g_wlan.io_func.io_type & 0x1) == HIF_SDIO) { + } else if ((g_wlan.io_type & 0x1) == HIF_SDIO) { g_wlan.hif_func.hif_read_reg(0xf0, ®); do { g_wlan.hif_func.hif_write_reg(0xf0, reg | BIT(0)); @@ -636,12 +636,12 @@ static inline void chip_wakeup(void) u32 reg, trials = 0; do { - if ((g_wlan.io_func.io_type & 0x1) == HIF_SPI) { + if ((g_wlan.io_type & 0x1) == HIF_SPI) { g_wlan.hif_func.hif_read_reg(1, ®); g_wlan.hif_func.hif_write_reg(1, reg & ~BIT(1)); g_wlan.hif_func.hif_write_reg(1, reg | BIT(1)); g_wlan.hif_func.hif_write_reg(1, reg & ~BIT(1)); - } else if ((g_wlan.io_func.io_type & 0x1) == HIF_SDIO) { + } else if ((g_wlan.io_type & 0x1) == HIF_SDIO) { g_wlan.hif_func.hif_read_reg(0xf0, ®); g_wlan.hif_func.hif_write_reg(0xf0, reg & ~BIT(0)); g_wlan.hif_func.hif_write_reg(0xf0, reg | BIT(0)); @@ -1252,10 +1252,10 @@ int wilc_wlan_start(void) int ret; u32 chipid; - if (p->io_func.io_type == HIF_SDIO) { + if (p->io_type == HIF_SDIO) { reg = 0; reg |= BIT(3); - } else if (p->io_func.io_type == HIF_SPI) { + } else if (p->io_type == HIF_SPI) { reg = 1; } acquire_bus(ACQUIRE_ONLY); @@ -1649,7 +1649,7 @@ _fail_: return chipid; } -int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) +int wilc_wlan_init(struct net_device *dev) { int ret = 0; perInterface_wlan_t *nic = netdev_priv(dev); @@ -1660,8 +1660,7 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp) PRINT_D(INIT_DBG, "Initializing WILC_Wlan ...\n"); memset((void *)&g_wlan, 0, sizeof(wilc_wlan_dev_t)); - memcpy((void *)&g_wlan.io_func, (void *)&inp->io_func, - sizeof(wilc_wlan_io_func_t)); + g_wlan.io_type = wilc->io_type; #ifdef WILC_SDIO if (!wilc_hif_sdio.hif_init(wilc, wilc_debug)) { diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index 5980ece49daa1..2f465f4fb063c 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -72,10 +72,6 @@ typedef struct { u32 block_size; } sdio_cmd53_t; -typedef struct { - int io_type; -} wilc_wlan_io_func_t; - #define WILC_MAC_INDICATE_STATUS 0x1 #define WILC_MAC_STATUS_INIT -1 #define WILC_MAC_STATUS_READY 0 @@ -83,10 +79,6 @@ typedef struct { #define WILC_MAC_INDICATE_SCAN 0x2 -typedef struct { - wilc_wlan_io_func_t io_func; -} wilc_wlan_inp_t; - struct tx_complete_data { int size; void *buff; @@ -917,8 +909,7 @@ typedef enum { WID_MAX = 0xFFFF } WID_T; -int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp); - +int wilc_wlan_init(struct net_device *dev); void wilc_bus_set_max_speed(void); void wilc_bus_set_default_speed(void); u32 wilc_get_chipid(u8 update); -- GitLab From 857c7b00d2400b2f8a825b4710e9c3d2ebef4aa1 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:05:00 +0100 Subject: [PATCH 1617/2855] staging/wilc1000: move init/exit functions to driver files The driver interfaces are in linux_wlan_sdio.c and linux_wlan_spi.c, so this is where the init and exit functions should be. Splitting this up enables further cleanups, including eventually allowing both modules to be built together. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 51 +------------------ drivers/staging/wilc1000/linux_wlan_common.h | 10 ++++ drivers/staging/wilc1000/linux_wlan_sdio.c | 16 +++++- drivers/staging/wilc1000/linux_wlan_sdio.h | 6 +-- drivers/staging/wilc1000/linux_wlan_spi.c | 23 ++++++++- drivers/staging/wilc1000/linux_wlan_spi.h | 3 +- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 2 +- 7 files changed, 52 insertions(+), 59 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 0747a0eefe92a..876bcfb3b5462 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1398,7 +1398,7 @@ void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size) WILC_WFI_p2p_rx(wilc->vif[1].ndev, buff, size); } -void wl_wlan_cleanup(struct wilc *wilc) +void wilc_netdev_cleanup(struct wilc *wilc) { int i = 0; perInterface_wlan_t *nic[NUM_CONCURRENT_IFC]; @@ -1517,52 +1517,3 @@ int wilc_netdev_init(struct wilc **wilc) return 0; } - -static int __init init_wilc_driver(void) -{ -#ifdef WILC_SPI - struct wilc *wilc; -#endif - -#if defined(WILC_DEBUGFS) - if (wilc_debugfs_init() < 0) { - PRINT_D(GENERIC_DBG, "fail to create debugfs for wilc driver\n"); - return -1; - } -#endif - - printk("IN INIT FUNCTION\n"); - printk("*** WILC1000 driver VERSION=[10.2] FW_VER=[10.2] ***\n"); - -#ifdef WILC_SDIO - { - int ret; - - ret = sdio_register_driver(&wilc_bus); - if (ret < 0) - PRINT_D(INIT_DBG, "init_wilc_driver: Failed register sdio driver\n"); - - return ret; - } -#else - PRINT_D(INIT_DBG, "Initializing netdev\n"); - if (wilc_netdev_init(&wilc)) - PRINT_ER("Couldn't initialize netdev\n"); - return 0; -#endif -} -late_initcall(init_wilc_driver); - -static void __exit exit_wilc_driver(void) -{ -#ifndef WILC_SDIO - PRINT_D(INIT_DBG, "SPI unregister...\n"); - spi_unregister_driver(&wilc_bus); -#else - PRINT_D(INIT_DBG, "SDIO unregister...\n"); - sdio_unregister_driver(&wilc_bus); -#endif -} -module_exit(exit_wilc_driver); - -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/wilc1000/linux_wlan_common.h b/drivers/staging/wilc1000/linux_wlan_common.h index b8dfc4a5e5cb5..f2ea8280b8f86 100644 --- a/drivers/staging/wilc1000/linux_wlan_common.h +++ b/drivers/staging/wilc1000/linux_wlan_common.h @@ -121,6 +121,16 @@ extern atomic_t WILC_DEBUG_LEVEL; printk("ERR [%s: %d]", __func__, __LINE__); \ printk(__VA_ARGS__); \ } while (0) + +static inline int wilc_debugfs_init(void) +{ + return 0; +} + +static inline void wilc_debugfs_remove(void) +{ +} + #endif #define FN_IN /* PRINT_D(">>> \n") */ diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index 0b01873faf790..06fd0e600c2a9 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -146,11 +146,11 @@ static void linux_sdio_remove(struct sdio_func *func) struct wilc_sdio *wl_sdio; wl_sdio = sdio_get_drvdata(func); - wl_wlan_cleanup(wl_sdio->wilc); + wilc_netdev_cleanup(wl_sdio->wilc); kfree(wl_sdio); } -struct sdio_driver wilc_bus = { +static struct sdio_driver wilc_bus = { .name = SDIO_MODALIAS, .id_table = wilc_sdio_ids, .probe = linux_sdio_probe, @@ -237,4 +237,16 @@ int wilc_sdio_set_default_speed(void) } +static int __init init_wilc_sdio_driver(void) +{ + return sdio_register_driver(&wilc_bus); +} +late_initcall(init_wilc_sdio_driver); + +static void __exit exit_wilc_sdio_driver(void) +{ + sdio_unregister_driver(&wilc_bus); +} +module_exit(exit_wilc_sdio_driver); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.h b/drivers/staging/wilc1000/linux_wlan_sdio.h index 49cce2c434102..3e1618526e78a 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.h +++ b/drivers/staging/wilc1000/linux_wlan_sdio.h @@ -1,11 +1,11 @@ -extern struct sdio_func *wilc_sdio_func; -extern struct sdio_driver wilc_bus; - #include +extern struct sdio_func *wilc_sdio_func; + int wilc_sdio_init(void); int wilc_sdio_cmd52(sdio_cmd52_t *cmd); int wilc_sdio_cmd53(sdio_cmd53_t *cmd); + int wilc_sdio_enable_interrupt(void); void wilc_sdio_disable_interrupt(void); int wilc_sdio_set_max_speed(void); diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index 790128f6d0348..f279a434c4c2d 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -11,6 +11,7 @@ #include "linux_wlan_common.h" #include "linux_wlan_spi.h" +#include "wilc_wfi_netdevice.h" #define USE_SPI_DMA 0 /* johnny add */ @@ -68,7 +69,7 @@ static const struct of_device_id wilc1000_of_match[] = { MODULE_DEVICE_TABLE(of, wilc1000_of_match); #endif -struct spi_driver wilc_bus __refdata = { +static struct spi_driver wilc_bus __refdata = { .driver = { .name = MODALIAS, #ifdef CONFIG_OF @@ -393,3 +394,23 @@ int wilc_spi_set_max_speed(void) PRINT_INFO(BUS_DBG, "@@@@@@@@@@@@ change SPI speed to %d @@@@@@@@@\n", SPEED); return 1; } + +static struct wilc *wilc; + +static int __init init_wilc_spi_driver(void) +{ + wilc_debugfs_init(); + return wilc_netdev_init(&wilc); +} +late_initcall(init_wilc_spi_driver); + +static void __exit exit_wilc_spi_driver(void) +{ + if (wilc) + wilc_netdev_cleanup(wilc); + spi_unregister_driver(&wilc_bus); + wilc_debugfs_remove(); +} +module_exit(exit_wilc_spi_driver); + +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/wilc1000/linux_wlan_spi.h b/drivers/staging/wilc1000/linux_wlan_spi.h index aecb522ff56d3..f434f79913abc 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.h +++ b/drivers/staging/wilc1000/linux_wlan_spi.h @@ -2,12 +2,11 @@ #define LINUX_WLAN_SPI_H #include -extern struct spi_device *wilc_spi_dev; -extern struct spi_driver wilc_bus; int wilc_spi_init(void); int wilc_spi_write(u8 *b, u32 len); int wilc_spi_read(u8 *rb, u32 rlen); int wilc_spi_write_read(u8 *wb, u8 *rb, u32 rlen); int wilc_spi_set_max_speed(void); + #endif diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 0c608d73a22e7..9adac5c781eec 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -216,7 +216,7 @@ void linux_wlan_mac_indicate(struct wilc *wilc, int flag); void linux_wlan_rx_complete(void); void linux_wlan_dbg(u8 *buff); int linux_wlan_lock_timeout(void *vp, u32 timeout); -void wl_wlan_cleanup(struct wilc *wilc); +void wilc_netdev_cleanup(struct wilc *wilc); int wilc_netdev_init(struct wilc **wilc); void wilc1000_wlan_deinit(struct net_device *dev); void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size); -- GitLab From b03314e22571783488828f7f38fa708cbd3a1888 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:05:01 +0100 Subject: [PATCH 1618/2855] staging/wilc1000: unify device pointer struct wilc has two pointers to store the device, one for sdio_func and one for spi_device. By changing the pointer to a 'struct device', we can simplify the logic and avoid a few #ifdefs. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 25 ++------------ drivers/staging/wilc1000/linux_wlan_sdio.c | 33 ++++--------------- drivers/staging/wilc1000/linux_wlan_spi.c | 22 +++++++++++-- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 6 +--- 4 files changed, 30 insertions(+), 56 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 876bcfb3b5462..faad01f6f2d11 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -453,19 +453,11 @@ int wilc_wlan_get_firmware(struct net_device *dev) goto _fail_; } -#ifdef WILC_SDIO - if (request_firmware(&wilc_firmware, firmware, &wilc->wilc_sdio_func->dev) != 0) { - PRINT_ER("%s - firmare not available\n", firmware); - ret = -1; - goto _fail_; - } -#else - if (request_firmware(&wilc_firmware, firmware, &wilc->wilc_spidev->dev) != 0) { + if (request_firmware(&wilc_firmware, firmware, wilc->dev) != 0) { PRINT_ER("%s - firmare not available\n", firmware); ret = -1; goto _fail_; } -#endif wilc->firmware = wilc_firmware; _fail_: @@ -1015,12 +1007,11 @@ int wilc_mac_open(struct net_device *ndev) nic = netdev_priv(ndev); wl = nic->wilc; -#ifdef WILC_SPI - if (!wl || !wl->wilc_spidev) { + if (!wl|| !wl->dev) { netdev_err(ndev, "wilc1000: SPI device not ready\n"); return -ENODEV; } -#endif + nic = netdev_priv(ndev); priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy); PRINT_D(INIT_DBG, "MAC OPEN[%p]\n", ndev); @@ -1505,15 +1496,5 @@ int wilc_netdev_init(struct wilc **wilc) nic->mac_opened = 0; } - #ifndef WILC_SDIO - if (!wilc_spi_init()) { - PRINT_ER("Can't initialize SPI\n"); - return -1; - } - wilc_dev->wilc_spidev = wilc_spi_dev; - #else - wilc_dev->wilc_sdio_func = wilc_sdio_func; - #endif - return 0; } diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index 06fd0e600c2a9..8df69b2aff2d6 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -21,13 +21,7 @@ #define MAX_SPEED (6 * 1000000) /* Max 50M */ #endif -struct wilc_sdio { - struct sdio_func *func; - struct wilc *wilc; -}; - struct sdio_func *wilc_sdio_func; - static unsigned int sdio_default_speed; #define SDIO_VENDOR_ID_WILC 0x0296 @@ -42,12 +36,8 @@ static const struct sdio_device_id wilc_sdio_ids[] = { #ifndef WILC_SDIO_IRQ_GPIO static void wilc_sdio_interrupt(struct sdio_func *func) { - struct wilc_sdio *wl_sdio; - - wl_sdio = sdio_get_drvdata(func); - sdio_release_host(func); - wilc_handle_isr(wl_sdio->wilc); + wilc_handle_isr(sdio_get_drvdata(func)); sdio_claim_host(func); } #endif @@ -55,7 +45,7 @@ static void wilc_sdio_interrupt(struct sdio_func *func) int wilc_sdio_cmd52(sdio_cmd52_t *cmd) { - struct sdio_func *func = wilc_dev->wilc_sdio_func; + struct sdio_func *func = container_of(wilc_dev->dev, struct sdio_func, dev); int ret; u8 data; @@ -87,7 +77,7 @@ int wilc_sdio_cmd52(sdio_cmd52_t *cmd) int wilc_sdio_cmd53(sdio_cmd53_t *cmd) { - struct sdio_func *func = wilc_dev->wilc_sdio_func; + struct sdio_func *func = container_of(wilc_dev->dev, struct sdio_func, dev); int size, ret; sdio_claim_host(func); @@ -118,24 +108,17 @@ int wilc_sdio_cmd53(sdio_cmd53_t *cmd) static int linux_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { - struct wilc_sdio *wl_sdio; struct wilc *wilc; - PRINT_D(INIT_DBG, "probe function\n"); - wl_sdio = kzalloc(sizeof(struct wilc_sdio), GFP_KERNEL); - if (!wl_sdio) - return -ENOMEM; PRINT_D(INIT_DBG, "Initializing netdev\n"); wilc_sdio_func = func; if (wilc_netdev_init(&wilc)) { PRINT_ER("Couldn't initialize netdev\n"); - kfree(wl_sdio); return -1; } - wl_sdio->func = func; - wl_sdio->wilc = wilc; - sdio_set_drvdata(func, wl_sdio); + sdio_set_drvdata(func, wilc); + wilc->dev = &func->dev; printk("Driver Initializing success\n"); return 0; @@ -143,11 +126,7 @@ static int linux_sdio_probe(struct sdio_func *func, const struct sdio_device_id static void linux_sdio_remove(struct sdio_func *func) { - struct wilc_sdio *wl_sdio; - - wl_sdio = sdio_get_drvdata(func); - wilc_netdev_cleanup(wl_sdio->wilc); - kfree(wl_sdio); + wilc_netdev_cleanup(sdio_get_drvdata(func)); } static struct sdio_driver wilc_bus = { diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index f279a434c4c2d..29dd9d4e5ff02 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -9,9 +9,10 @@ #include #include +#include "wilc_wfi_netdevice.h" #include "linux_wlan_common.h" #include "linux_wlan_spi.h" -#include "wilc_wfi_netdevice.h" +#include "wilc_wlan_if.h" #define USE_SPI_DMA 0 /* johnny add */ @@ -399,8 +400,25 @@ static struct wilc *wilc; static int __init init_wilc_spi_driver(void) { + int ret; + wilc_debugfs_init(); - return wilc_netdev_init(&wilc); + + ret = wilc_netdev_init(&wilc); + if (ret) { + wilc_debugfs_remove(); + return ret; + } + + if (!wilc_spi_init() || !wilc_spi_dev) { + PRINT_ER("Can't initialize SPI\n"); + wilc_netdev_cleanup(wilc); + wilc_debugfs_remove(); + return -ENXIO; + } + wilc_dev->dev = &wilc_spi_dev->dev; + + return ret; } late_initcall(init_wilc_spi_driver); diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 9adac5c781eec..a099f2877b6ed 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -185,11 +185,7 @@ struct wilc { const struct firmware *firmware; -#ifdef WILC_SDIO - struct sdio_func *wilc_sdio_func; -#else - struct spi_device *wilc_spidev; -#endif + struct device *dev; }; typedef struct { -- GitLab From 6703992896cc95f0bc7c9ccece1fcb3c7e8a2f87 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:05:02 +0100 Subject: [PATCH 1619/2855] staging/wilc1000: pass io_type to wilc_netdev_init In order to avoid some of the #ifdefs, this passes the io_type and device pointer as an argument to wilc_netdev_init. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 18 ++++-------------- drivers/staging/wilc1000/linux_wlan_sdio.c | 4 ++-- drivers/staging/wilc1000/linux_wlan_spi.c | 4 ++-- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 2 +- 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index faad01f6f2d11..b1707147aa7d0 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -25,11 +25,7 @@ #include -#ifdef WILC_SDIO #include "linux_wlan_sdio.h" -#else -#include "linux_wlan_spi.h" -#endif static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr); @@ -884,11 +880,6 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) wlan_init_locks(dev); -#ifdef WILC_SDIO - wl->io_type = HIF_SDIO; -#else - wl->io_type = HIF_SPI; -#endif ret = wilc_wlan_init(dev); if (ret < 0) { PRINT_ER("Initializing WILC_Wlan FAILED\n"); @@ -1426,7 +1417,7 @@ void wilc_netdev_cleanup(struct wilc *wilc) #endif } -int wilc_netdev_init(struct wilc **wilc) +int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type) { int i; perInterface_wlan_t *nic; @@ -1439,7 +1430,7 @@ int wilc_netdev_init(struct wilc **wilc) return -ENOMEM; *wilc = wilc_dev; - + wilc_dev->io_type = io_type; register_inetaddr_notifier(&g_dev_notifier); for (i = 0; i < NUM_CONCURRENT_IFC; i++) { @@ -1468,9 +1459,8 @@ int wilc_netdev_init(struct wilc **wilc) struct wireless_dev *wdev; wdev = wilc_create_wiphy(ndev); - #ifdef WILC_SDIO - SET_NETDEV_DEV(ndev, &wilc_sdio_func->dev); - #endif + if (dev) + SET_NETDEV_DEV(ndev, dev); if (!wdev) { PRINT_ER("Can't register WILC Wiphy\n"); diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index 8df69b2aff2d6..d2843b949a1b7 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -1,4 +1,5 @@ #include "wilc_wfi_netdevice.h" +#include "linux_wlan_sdio.h" #include #include @@ -113,7 +114,7 @@ static int linux_sdio_probe(struct sdio_func *func, const struct sdio_device_id PRINT_D(INIT_DBG, "Initializing netdev\n"); wilc_sdio_func = func; - if (wilc_netdev_init(&wilc)) { + if (wilc_netdev_init(&wilc, &func->dev, HIF_SDIO)) { PRINT_ER("Couldn't initialize netdev\n"); return -1; } @@ -215,7 +216,6 @@ int wilc_sdio_set_default_speed(void) return linux_sdio_set_speed(sdio_default_speed); } - static int __init init_wilc_sdio_driver(void) { return sdio_register_driver(&wilc_bus); diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index 29dd9d4e5ff02..a459c502a8a86 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -9,9 +9,9 @@ #include #include +#include "linux_wlan_spi.h" #include "wilc_wfi_netdevice.h" #include "linux_wlan_common.h" -#include "linux_wlan_spi.h" #include "wilc_wlan_if.h" #define USE_SPI_DMA 0 /* johnny add */ @@ -404,7 +404,7 @@ static int __init init_wilc_spi_driver(void) wilc_debugfs_init(); - ret = wilc_netdev_init(&wilc); + ret = wilc_netdev_init(&wilc, NULL, HIF_SPI); if (ret) { wilc_debugfs_remove(); return ret; diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index a099f2877b6ed..eae9ce1753512 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -213,7 +213,7 @@ void linux_wlan_rx_complete(void); void linux_wlan_dbg(u8 *buff); int linux_wlan_lock_timeout(void *vp, u32 timeout); void wilc_netdev_cleanup(struct wilc *wilc); -int wilc_netdev_init(struct wilc **wilc); +int wilc_netdev_init(struct wilc **wilc, struct device *, int io_type); void wilc1000_wlan_deinit(struct net_device *dev); void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size); u16 wilc_set_machw_change_vir_if(struct net_device *dev, bool value); -- GitLab From 2e7d5377f684ea1b337a4182f5f025b300d024ff Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:05:03 +0100 Subject: [PATCH 1620/2855] staging/wilc1000: use device pointer for phy creation wilc_create_wiphy tries to get a pointer to a device from the global wilc_sdio_func variable. This is a layering violation and we can use the wilc_dev->dev pointer instead. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 2 +- drivers/staging/wilc1000/linux_wlan_sdio.c | 2 +- drivers/staging/wilc1000/linux_wlan_sdio.h | 2 -- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 9 ++------- drivers/staging/wilc1000/wilc_wfi_cfgoperations.h | 2 +- 5 files changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index b1707147aa7d0..08c3be8728b23 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1457,7 +1457,7 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type) { struct wireless_dev *wdev; - wdev = wilc_create_wiphy(ndev); + wdev = wilc_create_wiphy(ndev, dev); if (dev) SET_NETDEV_DEV(ndev, dev); diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index d2843b949a1b7..874a859cad21f 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -22,7 +22,7 @@ #define MAX_SPEED (6 * 1000000) /* Max 50M */ #endif -struct sdio_func *wilc_sdio_func; +static struct sdio_func *wilc_sdio_func; static unsigned int sdio_default_speed; #define SDIO_VENDOR_ID_WILC 0x0296 diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.h b/drivers/staging/wilc1000/linux_wlan_sdio.h index 3e1618526e78a..df733c25e7702 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.h +++ b/drivers/staging/wilc1000/linux_wlan_sdio.h @@ -1,7 +1,5 @@ #include -extern struct sdio_func *wilc_sdio_func; - int wilc_sdio_init(void); int wilc_sdio_cmd52(sdio_cmd52_t *cmd); int wilc_sdio_cmd53(sdio_cmd53_t *cmd); diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 46c3f578a6fdc..cc279c654e53b 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -11,9 +11,6 @@ */ #include "wilc_wfi_cfgoperations.h" -#ifdef WILC_SDIO -#include "linux_wlan_sdio.h" -#endif #include "host_interface.h" #include @@ -3414,7 +3411,7 @@ _fail_: * @date 01 MAR 2012 * @version 1.0 */ -struct wireless_dev *wilc_create_wiphy(struct net_device *net) +struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev) { struct wilc_priv *priv; struct wireless_dev *wdev; @@ -3466,9 +3463,7 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net) wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type, wdev->wiphy->interface_modes, wdev->iftype); - #ifdef WILC_SDIO - set_wiphy_dev(wdev->wiphy, &wilc_sdio_func->dev); - #endif + set_wiphy_dev(wdev->wiphy, dev); /*Register wiphy structure*/ s32Error = wiphy_register(wdev->wiphy); diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h index 158d98c0eb87e..ab53d9d590811 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h @@ -10,7 +10,7 @@ #define NM_WFI_CFGOPERATIONS #include "wilc_wfi_netdevice.h" -struct wireless_dev *wilc_create_wiphy(struct net_device *net); +struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev); void wilc_free_wiphy(struct net_device *net); int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed); int wilc_deinit_host_int(struct net_device *net); -- GitLab From c4d139cb8d7dbe67cfbaefa70230d144dbada34c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:05:04 +0100 Subject: [PATCH 1621/2855] staging/wilc1000: get rid of WILC_SDIO_IRQ_GPIO Whether the SDIO function uses an internal or external interrupt should not be a compiletime decision but be determined at runtime. This changes the code to pass a GPIO number from the init code as early as possible, and leaves just one #ifdef WILC_SDIO_IRQ_GPIO to preserve the previous behavior. All other locations that check for the interrupt method are turned into runtime checks based on the gpio number (>=0) or the interrupt number (>0). Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/Makefile | 1 - drivers/staging/wilc1000/linux_wlan.c | 69 ++++++------ drivers/staging/wilc1000/linux_wlan_sdio.c | 18 +-- drivers/staging/wilc1000/linux_wlan_spi.c | 2 +- drivers/staging/wilc1000/wilc_sdio.c | 105 ++++++++---------- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 7 +- drivers/staging/wilc1000/wilc_wlan.c | 8 +- 7 files changed, 92 insertions(+), 118 deletions(-) diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile index 9696f69bda485..fe480c76c521a 100644 --- a/drivers/staging/wilc1000/Makefile +++ b/drivers/staging/wilc1000/Makefile @@ -1,7 +1,6 @@ obj-$(CONFIG_WILC1000) += wilc1000.o ccflags-$(CONFIG_WILC1000_SDIO) += -DWILC_SDIO -DCOMPLEMENT_BOOT -ccflags-$(CONFIG_WILC1000_HW_OOB_INTR) += -DWILC_SDIO_IRQ_GPIO ccflags-$(CONFIG_WILC1000_SPI) += -DWILC_SPI ccflags-y += -DSTA_FIRMWARE=\"atmel/wilc1000_fw.bin\" \ diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 08c3be8728b23..e81e90678d0fc 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -161,7 +161,6 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event return NOTIFY_DONE; } -#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO) static irqreturn_t isr_uh_routine(int irq, void *user_data) { perInterface_wlan_t *nic; @@ -207,9 +206,9 @@ static int init_irq(struct net_device *dev) nic = netdev_priv(dev); wl = nic->wilc; - if ((gpio_request(GPIO_NUM, "WILC_INTR") == 0) && - (gpio_direction_input(GPIO_NUM) == 0)) { - wl->dev_irq_num = gpio_to_irq(GPIO_NUM); + if ((gpio_request(wl->gpio, "WILC_INTR") == 0) && + (gpio_direction_input(wl->gpio) == 0)) { + wl->dev_irq_num = gpio_to_irq(wl->gpio); } else { ret = -1; PRINT_ER("could not obtain gpio for WILC_INTR\n"); @@ -220,16 +219,16 @@ static int init_irq(struct net_device *dev) isr_bh_routine, IRQF_TRIGGER_LOW | IRQF_ONESHOT, "WILC_IRQ", dev) < 0) { - PRINT_ER("Failed to request IRQ for GPIO: %d\n", GPIO_NUM); + PRINT_ER("Failed to request IRQ for GPIO: %d\n", wl->gpio); + gpio_free(wl->gpio); ret = -1; } else { PRINT_D(INIT_DBG, "IRQ request succeeded IRQ-NUM= %d on GPIO: %d\n", - wl->dev_irq_num, GPIO_NUM); + wl->dev_irq_num, wl->gpio); } return ret; } -#endif static void deinit_irq(struct net_device *dev) { @@ -239,13 +238,11 @@ static void deinit_irq(struct net_device *dev) nic = netdev_priv(dev); wilc = nic->wilc; -#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO) - if (&wilc->dev_irq_num != 0) { + /* Deintialize IRQ */ + if (wilc->dev_irq_num) { free_irq(wilc->dev_irq_num, wilc); - - gpio_free(GPIO_NUM); + gpio_free(wilc->gpio); } -#endif } void linux_wlan_dbg(u8 *buff) @@ -742,11 +739,11 @@ void wilc1000_wlan_deinit(struct net_device *dev) #endif PRINT_D(INIT_DBG, "Disabling IRQ\n"); -#ifdef WILC_SDIO - mutex_lock(&wl->hif_cs); - wilc_sdio_disable_interrupt(); - mutex_unlock(&wl->hif_cs); -#endif + if (!wl->dev_irq_num) { + mutex_lock(&wl->hif_cs); + wilc_sdio_disable_interrupt(); + mutex_unlock(&wl->hif_cs); + } if (&wl->txq_event) up(&wl->txq_event); @@ -760,14 +757,14 @@ void wilc1000_wlan_deinit(struct net_device *dev) PRINT_D(INIT_DBG, "Deinitializing WILC Wlan\n"); wilc_wlan_cleanup(dev); -#if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO) - #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31) - PRINT_D(INIT_DBG, "Disabling IRQ 2\n"); - - mutex_lock(&wl->hif_cs); - wilc_sdio_disable_interrupt(); - mutex_unlock(&wl->hif_cs); - #endif +#if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31) + if (!wl->dev_irq_num) { + PRINT_D(INIT_DBG, "Disabling IRQ 2\n"); + + mutex_lock(&wl->hif_cs); + wilc_sdio_disable_interrupt(); + mutex_unlock(&wl->hif_cs); + } #endif PRINT_D(INIT_DBG, "Deinitializing Locks\n"); @@ -887,13 +884,11 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) goto _fail_locks_; } -#if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO) - if (init_irq(dev)) { + if (wl->gpio >= 0 && init_irq(dev)) { PRINT_ER("couldn't initialize IRQ\n"); ret = -EIO; goto _fail_locks_; } -#endif ret = wlan_initialize_threads(dev); if (ret < 0) { @@ -902,13 +897,11 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) goto _fail_wilc_wlan_; } -#if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO) - if (wilc_sdio_enable_interrupt()) { + if (!wl->dev_irq_num && wilc_sdio_enable_interrupt()) { PRINT_ER("couldn't initialize IRQ\n"); ret = -EIO; goto _fail_irq_init_; } -#endif if (wilc_wlan_get_firmware(dev)) { PRINT_ER("Can't get firmware\n"); @@ -957,14 +950,12 @@ _fail_fw_start_: wilc_wlan_stop(); _fail_irq_enable_: -#if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO) - wilc_sdio_disable_interrupt(); + if (!wl->dev_irq_num) + wilc_sdio_disable_interrupt(); _fail_irq_init_: -#endif -#if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO) - deinit_irq(dev); + if (wl->dev_irq_num) + deinit_irq(dev); -#endif wlan_deinitialize_threads(dev); _fail_wilc_wlan_: wilc_wlan_cleanup(dev); @@ -1417,7 +1408,7 @@ void wilc_netdev_cleanup(struct wilc *wilc) #endif } -int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type) +int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, int gpio) { int i; perInterface_wlan_t *nic; @@ -1431,6 +1422,8 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type) *wilc = wilc_dev; wilc_dev->io_type = io_type; + wilc_dev->gpio = gpio; + register_inetaddr_notifier(&g_dev_notifier); for (i = 0; i < NUM_CONCURRENT_IFC; i++) { diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index 874a859cad21f..732b0d66366bf 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -6,6 +6,7 @@ #include #include #include +#include @@ -34,15 +35,12 @@ static const struct sdio_device_id wilc_sdio_ids[] = { }; -#ifndef WILC_SDIO_IRQ_GPIO static void wilc_sdio_interrupt(struct sdio_func *func) { sdio_release_host(func); wilc_handle_isr(sdio_get_drvdata(func)); sdio_claim_host(func); } -#endif - int wilc_sdio_cmd52(sdio_cmd52_t *cmd) { @@ -110,11 +108,18 @@ int wilc_sdio_cmd53(sdio_cmd53_t *cmd) static int linux_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { struct wilc *wilc; + int gpio; + gpio = -1; + if (IS_ENABLED(CONFIG_WILC1000_HW_OOB_INTR)) { + gpio = of_get_gpio(func->dev.of_node, 0); + if (gpio < 0) + gpio = GPIO_NUM; + } PRINT_D(INIT_DBG, "Initializing netdev\n"); wilc_sdio_func = func; - if (wilc_netdev_init(&wilc, &func->dev, HIF_SDIO)) { + if (wilc_netdev_init(&wilc, &func->dev, HIF_SDIO, gpio)) { PRINT_ER("Couldn't initialize netdev\n"); return -1; } @@ -140,7 +145,6 @@ static struct sdio_driver wilc_bus = { int wilc_sdio_enable_interrupt(void) { int ret = 0; -#ifndef WILC_SDIO_IRQ_GPIO sdio_claim_host(wilc_sdio_func); ret = sdio_claim_irq(wilc_sdio_func, wilc_sdio_interrupt); @@ -150,14 +154,11 @@ int wilc_sdio_enable_interrupt(void) PRINT_ER("can't claim sdio_irq, err(%d)\n", ret); ret = -EIO; } -#endif return ret; } void wilc_sdio_disable_interrupt(void) { - -#ifndef WILC_SDIO_IRQ_GPIO int ret; PRINT_D(INIT_DBG, "wilc_sdio_disable_interrupt IN\n"); @@ -170,7 +171,6 @@ void wilc_sdio_disable_interrupt(void) sdio_release_host(wilc_sdio_func); PRINT_D(INIT_DBG, "wilc_sdio_disable_interrupt OUT\n"); -#endif } static int linux_sdio_set_speed(int speed) diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index a459c502a8a86..f4dda4a6fa7b3 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -404,7 +404,7 @@ static int __init init_wilc_spi_driver(void) wilc_debugfs_init(); - ret = wilc_netdev_init(&wilc, NULL, HIF_SPI); + ret = wilc_netdev_init(&wilc, NULL, HIF_SPI, GPIO_NUM); if (ret) { wilc_debugfs_remove(); return ret; diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index 7fca3b23b4851..8441fcccccc4b 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -16,6 +16,7 @@ #define WILC_SDIO_BLOCK_SIZE 512 typedef struct { + bool irq_gpio; u32 block_size; wilc_debug_func dPrint; int nint; @@ -25,10 +26,8 @@ typedef struct { static wilc_sdio_t g_sdio; -#ifdef WILC_SDIO_IRQ_GPIO static int sdio_write_reg(u32 addr, u32 data); static int sdio_read_reg(u32 addr, u32 *data); -#endif /******************************************** * @@ -131,29 +130,29 @@ _fail_: static int sdio_clear_int(void) { -#ifndef WILC_SDIO_IRQ_GPIO - /* u32 sts; */ - sdio_cmd52_t cmd; + if (!g_sdio.irq_gpio) { + /* u32 sts; */ + sdio_cmd52_t cmd; - cmd.read_write = 0; - cmd.function = 1; - cmd.raw = 0; - cmd.address = 0x4; - cmd.data = 0; - wilc_sdio_cmd52(&cmd); + cmd.read_write = 0; + cmd.function = 1; + cmd.raw = 0; + cmd.address = 0x4; + cmd.data = 0; + wilc_sdio_cmd52(&cmd); - return cmd.data; -#else - u32 reg; + return cmd.data; + } else { + u32 reg; - if (!sdio_read_reg(WILC_HOST_RX_CTRL_0, ®)) { - g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0); - return 0; + if (!sdio_read_reg(WILC_HOST_RX_CTRL_0, ®)) { + g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0); + return 0; + } + reg &= ~0x1; + sdio_write_reg(WILC_HOST_RX_CTRL_0, reg); + return 1; } - reg &= ~0x1; - sdio_write_reg(WILC_HOST_RX_CTRL_0, reg); - return 1; -#endif } @@ -455,8 +454,7 @@ static int sdio_sync(void) return 0; } -#ifdef WILC_SDIO_IRQ_GPIO - { + if (g_sdio.irq_gpio) { u32 reg; int ret; @@ -490,7 +488,6 @@ static int sdio_sync(void) return 0; } } -#endif return 1; } @@ -504,6 +501,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) memset(&g_sdio, 0, sizeof(wilc_sdio_t)); g_sdio.dPrint = func; + g_sdio.irq_gpio = (wilc->dev_irq_num); if (!wilc_sdio_init()) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed io init bus...\n"); @@ -662,36 +660,33 @@ static int sdio_read_int(u32 *int_status) /** * Read IRQ flags **/ -#ifndef WILC_SDIO_IRQ_GPIO - cmd.function = 1; - cmd.address = 0x04; - cmd.data = 0; - wilc_sdio_cmd52(&cmd); - - if (cmd.data & BIT(0)) - tmp |= INT_0; - if (cmd.data & BIT(2)) - tmp |= INT_1; - if (cmd.data & BIT(3)) - tmp |= INT_2; - if (cmd.data & BIT(4)) - tmp |= INT_3; - if (cmd.data & BIT(5)) - tmp |= INT_4; - if (cmd.data & BIT(6)) - tmp |= INT_5; - { + if (!g_sdio.irq_gpio) { int i; + cmd.function = 1; + cmd.address = 0x04; + cmd.data = 0; + wilc_sdio_cmd52(&cmd); + + if (cmd.data & BIT(0)) + tmp |= INT_0; + if (cmd.data & BIT(2)) + tmp |= INT_1; + if (cmd.data & BIT(3)) + tmp |= INT_2; + if (cmd.data & BIT(4)) + tmp |= INT_3; + if (cmd.data & BIT(5)) + tmp |= INT_4; + if (cmd.data & BIT(6)) + tmp |= INT_5; for (i = g_sdio.nint; i < MAX_NUM_INT; i++) { if ((tmp >> (IRG_FLAGS_OFFSET + i)) & 0x1) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Unexpected interrupt (1) : tmp=%x, data=%x\n", tmp, cmd.data); break; } } - } -#else - { + } else { u32 irq_flags; cmd.read_write = 0; @@ -704,8 +699,6 @@ static int sdio_read_int(u32 *int_status) tmp |= ((irq_flags >> 0) << IRG_FLAGS_OFFSET); } -#endif - *int_status = tmp; return 1; @@ -718,16 +711,14 @@ static int sdio_clear_int_ext(u32 val) if (g_sdio.has_thrpt_enh3) { u32 reg; -#ifdef WILC_SDIO_IRQ_GPIO - { + if (g_sdio.irq_gpio) { u32 flags; flags = val & (BIT(MAX_NUN_INT_THRPT_ENH2) - 1); reg = flags; + } else { + reg = 0; } -#else - reg = 0; -#endif /* select VMM table 0 */ if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0) reg |= BIT(5); @@ -754,8 +745,7 @@ static int sdio_clear_int_ext(u32 val) } } else { -#ifdef WILC_SDIO_IRQ_GPIO - { + if (g_sdio.irq_gpio) { /* see below. has_thrpt_enh2 uses register 0xf8 to clear interrupts. */ /* Cannot clear multiple interrupts. Must clear each interrupt individually */ u32 flags; @@ -795,7 +785,6 @@ static int sdio_clear_int_ext(u32 val) } } } -#endif /* WILC_SDIO_IRQ_GPIO */ { u32 vmm_ctl; @@ -862,8 +851,7 @@ static int sdio_sync_ext(int nint /* how mant interrupts to enable. */) return 0; } -#ifdef WILC_SDIO_IRQ_GPIO - { + if (g_sdio.irq_gpio) { u32 reg; int ret, i; @@ -915,7 +903,6 @@ static int sdio_sync_ext(int nint /* how mant interrupts to enable. */) } } } -#endif /* WILC_SDIO_IRQ_GPIO */ return 1; } diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index eae9ce1753512..92f4cb71608dd 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -158,10 +158,9 @@ struct wilc_vif { struct wilc { int io_type; int mac_status; + int gpio; bool initialized; - #if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO) - unsigned short dev_irq_num; - #endif + int dev_irq_num; int close; u8 vif_num; struct wilc_vif vif[NUM_CONCURRENT_IFC]; @@ -213,7 +212,7 @@ void linux_wlan_rx_complete(void); void linux_wlan_dbg(u8 *buff); int linux_wlan_lock_timeout(void *vp, u32 timeout); void wilc_netdev_cleanup(struct wilc *wilc); -int wilc_netdev_init(struct wilc **wilc, struct device *, int io_type); +int wilc_netdev_init(struct wilc **wilc, struct device *, int io_type, int gpio); void wilc1000_wlan_deinit(struct net_device *dev); void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size); u16 wilc_set_machw_change_vir_if(struct net_device *dev, bool value); diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 2958689a13c67..3d53550149fba 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1174,9 +1174,6 @@ void wilc_handle_isr(void *wilc) wilc_sleeptimer_isr_ext(int_status); if (!(int_status & (ALL_INT_EXT))) { -#ifdef WILC_SDIO - PRINT_D(TX_DBG, ">> UNKNOWN_INTERRUPT - 0x%08x\n", int_status); -#endif wilc_unknown_isr_ext(); } release_bus(RELEASE_ALLOW_SLEEP); @@ -1267,9 +1264,8 @@ int wilc_wlan_start(void) return ret; } reg = 0; -#ifdef WILC_SDIO_IRQ_GPIO - reg |= WILC_HAVE_SDIO_IRQ_GPIO; -#endif + if (p->io_type == HIF_SDIO && wilc_dev->dev_irq_num) + reg |= WILC_HAVE_SDIO_IRQ_GPIO; #ifdef WILC_DISABLE_PMU #else -- GitLab From 7d37a4a1b48ff6c365f6fd3d74ebe043cb8cb8a7 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:05:05 +0100 Subject: [PATCH 1622/2855] staging/wilc1000: pass hif operations through initialization The wilc_hif_spi and wilc_hif_sdio structures are part of the bus specific code, and the generic code should have no knowledge of their addresses. This changes the code to reference them only from the bus specific initialization code, which we can then use to split up the driver into separate modules. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 4 ++- drivers/staging/wilc1000/linux_wlan_sdio.c | 3 +- drivers/staging/wilc1000/linux_wlan_spi.c | 2 +- drivers/staging/wilc1000/wilc_sdio.c | 35 +++++++++---------- drivers/staging/wilc1000/wilc_spi.c | 34 +++++++++--------- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 4 ++- drivers/staging/wilc1000/wilc_wlan.c | 15 ++------ drivers/staging/wilc1000/wilc_wlan.h | 4 +-- 8 files changed, 47 insertions(+), 54 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index e81e90678d0fc..2fb1d97bded1e 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1408,7 +1408,8 @@ void wilc_netdev_cleanup(struct wilc *wilc) #endif } -int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, int gpio) +int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, + int gpio, const struct wilc_hif_func *ops) { int i; perInterface_wlan_t *nic; @@ -1423,6 +1424,7 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, int gp *wilc = wilc_dev; wilc_dev->io_type = io_type; wilc_dev->gpio = gpio; + wilc_dev->ops = ops; register_inetaddr_notifier(&g_dev_notifier); diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index 732b0d66366bf..f4250fda6cf1d 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -119,7 +119,8 @@ static int linux_sdio_probe(struct sdio_func *func, const struct sdio_device_id PRINT_D(INIT_DBG, "Initializing netdev\n"); wilc_sdio_func = func; - if (wilc_netdev_init(&wilc, &func->dev, HIF_SDIO, gpio)) { + if (wilc_netdev_init(&wilc, &func->dev, HIF_SDIO, gpio, + &wilc_hif_sdio)) { PRINT_ER("Couldn't initialize netdev\n"); return -1; } diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index f4dda4a6fa7b3..a7a52593156ad 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -404,7 +404,7 @@ static int __init init_wilc_spi_driver(void) wilc_debugfs_init(); - ret = wilc_netdev_init(&wilc, NULL, HIF_SPI, GPIO_NUM); + ret = wilc_netdev_init(&wilc, NULL, HIF_SPI, GPIO_NUM, &wilc_hif_spi); if (ret) { wilc_debugfs_remove(); return ret; diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index 8441fcccccc4b..006aae4679cb9 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -912,23 +912,22 @@ static int sdio_sync_ext(int nint /* how mant interrupts to enable. */) * ********************************************/ -struct wilc_hif_func wilc_hif_sdio = { - sdio_init, - sdio_deinit, - sdio_read_reg, - sdio_write_reg, - sdio_read, - sdio_write, - sdio_sync, - sdio_clear_int, - sdio_read_int, - sdio_clear_int_ext, - sdio_read_size, - sdio_write, - sdio_read, - sdio_sync_ext, - - sdio_set_max_speed, - sdio_set_default_speed, +const struct wilc_hif_func wilc_hif_sdio = { + .hif_init = sdio_init, + .hif_deinit = sdio_deinit, + .hif_read_reg = sdio_read_reg, + .hif_write_reg = sdio_write_reg, + .hif_block_rx = sdio_read, + .hif_block_tx = sdio_write, + .hif_sync = sdio_sync, + .hif_clear_int = sdio_clear_int, + .hif_read_int = sdio_read_int, + .hif_clear_int_ext = sdio_clear_int_ext, + .hif_read_size = sdio_read_size, + .hif_block_tx_ext = sdio_write, + .hif_block_rx_ext = sdio_read, + .hif_sync_ext = sdio_sync_ext, + .hif_set_max_bus_speed = sdio_set_max_speed, + .hif_set_default_bus_speed = sdio_set_default_speed, }; diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index dc9cdf5e4065d..39dd75665ba74 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -1021,21 +1021,21 @@ static int wilc_spi_sync_ext(int nint /* how mant interrupts to enable. */) * Global spi HIF function table * ********************************************/ -struct wilc_hif_func wilc_hif_spi = { - _wilc_spi_init, - _wilc_spi_deinit, - wilc_spi_read_reg, - wilc_spi_write_reg, - _wilc_spi_read, - _wilc_spi_write, - wilc_spi_sync, - wilc_spi_clear_int, - wilc_spi_read_int, - wilc_spi_clear_int_ext, - wilc_spi_read_size, - _wilc_spi_write, - _wilc_spi_read, - wilc_spi_sync_ext, - wilc_spi_max_bus_speed, - wilc_spi_default_bus_speed, +const struct wilc_hif_func wilc_hif_spi = { + .hif_init = _wilc_spi_init, + .hif_deinit = _wilc_spi_deinit, + .hif_read_reg = wilc_spi_read_reg, + .hif_write_reg = wilc_spi_write_reg, + .hif_block_rx = _wilc_spi_read, + .hif_block_tx = _wilc_spi_write, + .hif_sync = wilc_spi_sync, + .hif_clear_int = wilc_spi_clear_int, + .hif_read_int = wilc_spi_read_int, + .hif_clear_int_ext = wilc_spi_clear_int_ext, + .hif_read_size = wilc_spi_read_size, + .hif_block_tx_ext = _wilc_spi_write, + .hif_block_rx_ext = _wilc_spi_read, + .hif_sync_ext = wilc_spi_sync_ext, + .hif_set_max_bus_speed = wilc_spi_max_bus_speed, + .hif_set_default_bus_speed = wilc_spi_default_bus_speed, }; diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 92f4cb71608dd..761bc3f591386 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -156,6 +156,7 @@ struct wilc_vif { }; struct wilc { + const struct wilc_hif_func *ops; int io_type; int mac_status; int gpio; @@ -212,7 +213,8 @@ void linux_wlan_rx_complete(void); void linux_wlan_dbg(u8 *buff); int linux_wlan_lock_timeout(void *vp, u32 timeout); void wilc_netdev_cleanup(struct wilc *wilc); -int wilc_netdev_init(struct wilc **wilc, struct device *, int io_type, int gpio); +int wilc_netdev_init(struct wilc **wilc, struct device *, int io_type, int gpio, + const struct wilc_hif_func *ops); void wilc1000_wlan_deinit(struct net_device *dev); void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size); u16 wilc_set_machw_change_vir_if(struct net_device *dev, bool value); diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 3d53550149fba..5e37ec65d3bb1 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1657,22 +1657,11 @@ int wilc_wlan_init(struct net_device *dev) memset((void *)&g_wlan, 0, sizeof(wilc_wlan_dev_t)); g_wlan.io_type = wilc->io_type; - -#ifdef WILC_SDIO - if (!wilc_hif_sdio.hif_init(wilc, wilc_debug)) { - ret = -EIO; - goto _fail_; - } - memcpy((void *)&g_wlan.hif_func, &wilc_hif_sdio, - sizeof(struct wilc_hif_func)); -#else - if (!wilc_hif_spi.hif_init(wilc, wilc_debug)) { + g_wlan.hif_func = *wilc->ops; + if (!g_wlan.hif_func.hif_init(wilc, wilc_debug)) { ret = -EIO; goto _fail_; } - memcpy((void *)&g_wlan.hif_func, &wilc_hif_spi, - sizeof(struct wilc_hif_func)); -#endif if (!wilc_wlan_cfg_init(wilc_debug)) { ret = -ENOBUFS; diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 326d71bf91dfb..c0a5a955b1d4b 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -258,8 +258,8 @@ struct wilc_hif_func { void (*hif_set_default_bus_speed)(void); }; -extern struct wilc_hif_func wilc_hif_spi; -extern struct wilc_hif_func wilc_hif_sdio; +extern const struct wilc_hif_func wilc_hif_spi; +extern const struct wilc_hif_func wilc_hif_sdio; /******************************************** * -- GitLab From 5547c1f09c070f74978f3cb6c74556b3c5d5d09c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:05:06 +0100 Subject: [PATCH 1623/2855] staging/wilc1000: turn enable_irq/disable_irq into callbacks As a preparation for turning the SDIO side of wilc1000 into a separate module, this removes the last direct caller from the core module into the sdio specific portion. All calls to wilc_sdio_enable_interrupt() and wilc_sdio_disable_interrupt() now go through a function pointer in wilc_hif_func. We also change arguments slightly to pass the device, as we are already touching those lines and the change will be needed later to remove the global variables. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 22 +++++++++++++--------- drivers/staging/wilc1000/linux_wlan_sdio.c | 21 +++++++++++---------- drivers/staging/wilc1000/linux_wlan_sdio.h | 4 ++-- drivers/staging/wilc1000/wilc_sdio.c | 2 ++ drivers/staging/wilc1000/wilc_wlan.h | 2 ++ 5 files changed, 30 insertions(+), 21 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 2fb1d97bded1e..1b6e1eec24469 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -25,8 +25,6 @@ #include -#include "linux_wlan_sdio.h" - static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr); static struct notifier_block g_dev_notifier = { @@ -739,9 +737,10 @@ void wilc1000_wlan_deinit(struct net_device *dev) #endif PRINT_D(INIT_DBG, "Disabling IRQ\n"); - if (!wl->dev_irq_num) { + if (!wl->dev_irq_num && + wl->ops->disable_interrupt) { mutex_lock(&wl->hif_cs); - wilc_sdio_disable_interrupt(); + wl->ops->disable_interrupt(wl); mutex_unlock(&wl->hif_cs); } if (&wl->txq_event) @@ -758,11 +757,13 @@ void wilc1000_wlan_deinit(struct net_device *dev) PRINT_D(INIT_DBG, "Deinitializing WILC Wlan\n"); wilc_wlan_cleanup(dev); #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31) - if (!wl->dev_irq_num) { + if (!wl->dev_irq_num && + wl->ops->disable_interrupt) { + PRINT_D(INIT_DBG, "Disabling IRQ 2\n"); mutex_lock(&wl->hif_cs); - wilc_sdio_disable_interrupt(); + wl->ops->disable_interrupt(wl); mutex_unlock(&wl->hif_cs); } #endif @@ -897,7 +898,9 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) goto _fail_wilc_wlan_; } - if (!wl->dev_irq_num && wilc_sdio_enable_interrupt()) { + if (!wl->dev_irq_num && + wl->ops->enable_interrupt && + wl->ops->enable_interrupt(wl)) { PRINT_ER("couldn't initialize IRQ\n"); ret = -EIO; goto _fail_irq_init_; @@ -950,8 +953,9 @@ _fail_fw_start_: wilc_wlan_stop(); _fail_irq_enable_: - if (!wl->dev_irq_num) - wilc_sdio_disable_interrupt(); + if (!wl->dev_irq_num && + wl->ops->disable_interrupt) + wl->ops->disable_interrupt(wl); _fail_irq_init_: if (wl->dev_irq_num) deinit_irq(dev); diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index f4250fda6cf1d..9072de43bcd9f 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -1,5 +1,4 @@ #include "wilc_wfi_netdevice.h" -#include "linux_wlan_sdio.h" #include #include @@ -8,7 +7,7 @@ #include #include - +#include "linux_wlan_sdio.h" #define SDIO_MODALIAS "wilc1000_sdio" @@ -143,13 +142,14 @@ static struct sdio_driver wilc_bus = { .remove = linux_sdio_remove, }; -int wilc_sdio_enable_interrupt(void) +int wilc_sdio_enable_interrupt(struct wilc *dev) { + struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev); int ret = 0; - sdio_claim_host(wilc_sdio_func); - ret = sdio_claim_irq(wilc_sdio_func, wilc_sdio_interrupt); - sdio_release_host(wilc_sdio_func); + sdio_claim_host(func); + ret = sdio_claim_irq(func, wilc_sdio_interrupt); + sdio_release_host(func); if (ret < 0) { PRINT_ER("can't claim sdio_irq, err(%d)\n", ret); @@ -158,18 +158,19 @@ int wilc_sdio_enable_interrupt(void) return ret; } -void wilc_sdio_disable_interrupt(void) +void wilc_sdio_disable_interrupt(struct wilc *dev) { + struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev); int ret; PRINT_D(INIT_DBG, "wilc_sdio_disable_interrupt IN\n"); - sdio_claim_host(wilc_sdio_func); - ret = sdio_release_irq(wilc_sdio_func); + sdio_claim_host(func); + ret = sdio_release_irq(func); if (ret < 0) { PRINT_ER("can't release sdio_irq, err(%d)\n", ret); } - sdio_release_host(wilc_sdio_func); + sdio_release_host(func); PRINT_D(INIT_DBG, "wilc_sdio_disable_interrupt OUT\n"); } diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.h b/drivers/staging/wilc1000/linux_wlan_sdio.h index df733c25e7702..d7b213a7b18d1 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.h +++ b/drivers/staging/wilc1000/linux_wlan_sdio.h @@ -4,8 +4,8 @@ int wilc_sdio_init(void); int wilc_sdio_cmd52(sdio_cmd52_t *cmd); int wilc_sdio_cmd53(sdio_cmd53_t *cmd); -int wilc_sdio_enable_interrupt(void); -void wilc_sdio_disable_interrupt(void); +int wilc_sdio_enable_interrupt(struct wilc *); +void wilc_sdio_disable_interrupt(struct wilc *); int wilc_sdio_set_max_speed(void); int wilc_sdio_set_default_speed(void); diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index 006aae4679cb9..f550ce059c159 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -929,5 +929,7 @@ const struct wilc_hif_func wilc_hif_sdio = { .hif_sync_ext = sdio_sync_ext, .hif_set_max_bus_speed = sdio_set_max_speed, .hif_set_default_bus_speed = sdio_set_default_speed, + .enable_interrupt = wilc_sdio_enable_interrupt, + .disable_interrupt = wilc_sdio_disable_interrupt, }; diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index c0a5a955b1d4b..44a590f80def2 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -256,6 +256,8 @@ struct wilc_hif_func { int (*hif_sync_ext)(int); void (*hif_set_max_bus_speed)(void); void (*hif_set_default_bus_speed)(void); + int (*enable_interrupt)(struct wilc *nic); + void (*disable_interrupt)(struct wilc *nic); }; extern const struct wilc_hif_func wilc_hif_spi; -- GitLab From e28e84d29395278860626bb967286f0e21fe3263 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:05:07 +0100 Subject: [PATCH 1624/2855] staging/wilc1000: remove WILC_SDIO/WILC_SPI macros The last remaining user of WILC_SDIO macro checks for the correct time to wait in an interrupt for the PLL to settle. We can replace this with a runtime check and remove both WILC_SDIO and WILC_SPI, as we no longer need conditional compilation based on the hardware type. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/Makefile | 3 +-- drivers/staging/wilc1000/wilc_wlan.c | 5 ++++- drivers/staging/wilc1000/wilc_wlan.h | 7 ++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile index fe480c76c521a..dcba27bd3bce8 100644 --- a/drivers/staging/wilc1000/Makefile +++ b/drivers/staging/wilc1000/Makefile @@ -1,7 +1,6 @@ obj-$(CONFIG_WILC1000) += wilc1000.o -ccflags-$(CONFIG_WILC1000_SDIO) += -DWILC_SDIO -DCOMPLEMENT_BOOT -ccflags-$(CONFIG_WILC1000_SPI) += -DWILC_SPI +ccflags-$(CONFIG_WILC1000_SDIO) += -DCOMPLEMENT_BOOT ccflags-y += -DSTA_FIRMWARE=\"atmel/wilc1000_fw.bin\" \ -DAP_FIRMWARE=\"atmel/wilc1000_ap_fw.bin\" \ diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 5e37ec65d3bb1..f72f976906cc4 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1067,7 +1067,10 @@ static void wilc_pllupdate_isr_ext(u32 int_stats) g_wlan.hif_func.hif_clear_int_ext(PLL_INT_CLR); - mdelay(WILC_PLL_TO); + if (g_wlan.io_type == HIF_SDIO) + mdelay(WILC_PLL_TO_SDIO); + else + mdelay(WILC_PLL_TO_SPI); while (!(ISWILC1000(wilc_get_chipid(true)) && --trials)) { PRINT_D(TX_DBG, "PLL update retrying\n"); diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 44a590f80def2..90ef650e722d2 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -134,11 +134,8 @@ #define WILC_CFG_RSP_STATUS 2 #define WILC_CFG_RSP_SCAN 3 -#ifdef WILC_SDIO -#define WILC_PLL_TO 4 -#else -#define WILC_PLL_TO 2 -#endif +#define WILC_PLL_TO_SDIO 4 +#define WILC_PLL_TO_SPI 2 #define ABORT_INT BIT(31) /*******************************************/ -- GitLab From 750ffe9bdc9605193178c9b20147f83c6f52d3ef Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:05:08 +0100 Subject: [PATCH 1625/2855] staging/wilc1000: split out bus specific modules The SPI and SDIO specific code is now separate enough that we just need to restructure the Makefile and Kconfig logic a bit and export a couple of symbols from the common module to have separate bus glue drivers. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/Kconfig | 66 +++++++++++-------------- drivers/staging/wilc1000/Makefile | 7 ++- drivers/staging/wilc1000/linux_wlan.c | 4 ++ drivers/staging/wilc1000/wilc_debugfs.c | 2 + drivers/staging/wilc1000/wilc_wlan.c | 1 + 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/drivers/staging/wilc1000/Kconfig b/drivers/staging/wilc1000/Kconfig index ee51b42780889..2923122346eff 100644 --- a/drivers/staging/wilc1000/Kconfig +++ b/drivers/staging/wilc1000/Kconfig @@ -1,41 +1,12 @@ -config WILC1000_DRIVER - bool "WILC1000 support (WiFi only)" - depends on CFG80211 && WEXT_CORE && INET - ---help--- - This module only support IEEE 802.11n WiFi. - -if WILC1000_DRIVER - config WILC1000 tristate - -choice - prompt "Memory Allocation" - default WILC1000_PREALLOCATE_AT_LOADING_DRIVER - -config WILC1000_PREALLOCATE_AT_LOADING_DRIVER - bool "Preallocate memory at loading driver" + select WIRELESS_EXT ---help--- - This choice supports static allocation of the memory - for the receive buffer. The driver will allocate the RX buffer - during initial time. The driver will also free the buffer - by calling network device stop. - -config WILC1000_DYNAMICALLY_ALLOCATE_MEMROY - bool "Dynamically allocate memory in real time" - ---help--- - This choice supports dynamic allocation of the memory - for the receive buffer. The driver will allocate the RX buffer - when it is required. -endchoice - -choice - prompt "Bus Type" - default WILC1000_SDIO + This module only support IEEE 802.11n WiFi. config WILC1000_SDIO - bool "SDIO support" - depends on MMC + tristate "Atmel WILC1000 SDIO (WiFi only)" + depends on CFG80211 && INET && MMC select WILC1000 ---help--- This module adds support for the SDIO interface of adapters using @@ -48,9 +19,9 @@ config WILC1000_SDIO this if your platform is using the SDIO bus. config WILC1000_SPI - depends on SPI + tristate "Atmel WILC1000 SPI (WiFi only)" + depends on CFG80211 && INET && SPI select WILC1000 - bool "SPI support" ---help--- This module adds support for the SPI interface of adapters using WILC1000 chipset. The Atmel WILC1000 has a Serial Peripheral @@ -59,10 +30,31 @@ config WILC1000_SPI full-duplex slave synchronous serial interface that is available immediately following reset when pin 9 (SDIO_SPI_CFG) is tied to VDDIO. Select this if your platform is using the SPI bus. + +choice + prompt "WILC1000 Memory Allocation" + depends on WILC1000 + default WILC1000_PREALLOCATE_AT_LOADING_DRIVER + +config WILC1000_PREALLOCATE_AT_LOADING_DRIVER + bool "Preallocate memory at loading driver" + ---help--- + This choice supports static allocation of the memory + for the receive buffer. The driver will allocate the RX buffer + during initial time. The driver will also free the buffer + by calling network device stop. + +config WILC1000_DYNAMICALLY_ALLOCATE_MEMROY + bool "Dynamically allocate memory in real time" + ---help--- + This choice supports dynamic allocation of the memory + for the receive buffer. The driver will allocate the RX buffer + when it is required. endchoice + config WILC1000_HW_OOB_INTR - bool "Use out of band interrupt" + bool "WILC1000 out of band interrupt" depends on WILC1000_SDIO default n ---help--- @@ -71,5 +63,3 @@ config WILC1000_HW_OOB_INTR mechanism for SDIO host controllers that don't support SDIO interrupt. Select this option If the SDIO host controller in your platform doesn't support SDIO time devision interrupt. - -endif diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile index dcba27bd3bce8..198d536da57c5 100644 --- a/drivers/staging/wilc1000/Makefile +++ b/drivers/staging/wilc1000/Makefile @@ -21,5 +21,8 @@ wilc1000-objs := wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \ wilc_wlan_cfg.o wilc_debugfs.o \ wilc_wlan.o -wilc1000-$(CONFIG_WILC1000_SDIO) += linux_wlan_sdio.o wilc_sdio.o -wilc1000-$(CONFIG_WILC1000_SPI) += linux_wlan_spi.o wilc_spi.o +obj-$(CONFIG_WILC1000_SDIO) += wilc1000-sdio.o +wilc1000-sdio-objs += linux_wlan_sdio.o wilc_sdio.o + +obj-$(CONFIG_WILC1000_SPI) += wilc1000-spi.o +wilc1000-spi-objs += linux_wlan_spi.o wilc_spi.o diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 1b6e1eec24469..0d6c22ca79206 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -44,6 +44,8 @@ static struct net_device_stats *mac_stats(struct net_device *dev); static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd); static void wilc_set_multicast_list(struct net_device *dev); struct wilc *wilc_dev; +EXPORT_SYMBOL_GPL(wilc_dev); + bool wilc_enable_ps = true; static const struct net_device_ops wilc_netdev_ops = { @@ -1411,6 +1413,7 @@ void wilc_netdev_cleanup(struct wilc *wilc) wilc_debugfs_remove(); #endif } +EXPORT_SYMBOL_GPL(wilc_netdev_cleanup); int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, int gpio, const struct wilc_hif_func *ops) @@ -1487,3 +1490,4 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, return 0; } +EXPORT_SYMBOL_GPL(wilc_netdev_init); diff --git a/drivers/staging/wilc1000/wilc_debugfs.c b/drivers/staging/wilc1000/wilc_debugfs.c index d70f96f475b80..158a1df171959 100644 --- a/drivers/staging/wilc1000/wilc_debugfs.c +++ b/drivers/staging/wilc1000/wilc_debugfs.c @@ -27,7 +27,9 @@ static struct dentry *wilc_dir; #define DBG_REGION_ALL (GENERIC_DBG | HOSTAPD_DBG | HOSTINF_DBG | CORECONFIG_DBG | CFG80211_DBG | INT_DBG | TX_DBG | RX_DBG | LOCK_DBG | INIT_DBG | BUS_DBG | MEM_DBG) #define DBG_LEVEL_ALL (DEBUG | INFO | WRN | ERR) atomic_t WILC_REGION = ATOMIC_INIT(INIT_DBG | GENERIC_DBG | CFG80211_DBG | FIRM_DBG | HOSTAPD_DBG); +EXPORT_SYMBOL_GPL(WILC_REGION); atomic_t WILC_DEBUG_LEVEL = ATOMIC_INIT(ERR); +EXPORT_SYMBOL_GPL(WILC_DEBUG_LEVEL); /* * -------------------------------------------------------------------------------- diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index f72f976906cc4..a71901c226536 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1181,6 +1181,7 @@ void wilc_handle_isr(void *wilc) } release_bus(RELEASE_ALLOW_SLEEP); } +EXPORT_SYMBOL_GPL(wilc_handle_isr); int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size) { -- GitLab From c94f05ee6bb5b5fabe730f0a2656643bc43862ed Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:05:09 +0100 Subject: [PATCH 1626/2855] staging/wilc1000: use more regular probing So far, my patches tried to do equivalent conversions of the existing code. This one goes beyond that by restructuring how the devices get probed. In particular, the spi driver no longer creates the netdev until the device is probed, and I've removed the global wilc_sdio_func and wilc_spi_dev variables in favor of retrieving them from the wilc_dev variable that will eventually get passed through all functions instead of using a global. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 6 +- drivers/staging/wilc1000/linux_wlan_common.h | 12 -- drivers/staging/wilc1000/linux_wlan_sdio.c | 30 ++--- drivers/staging/wilc1000/linux_wlan_spi.c | 122 +++++++------------ drivers/staging/wilc1000/wilc_debugfs.c | 6 +- 5 files changed, 58 insertions(+), 118 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 0d6c22ca79206..c3b521e085f2d 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1408,10 +1408,6 @@ void wilc_netdev_cleanup(struct wilc *wilc) } kfree(wilc); - -#if defined(WILC_DEBUGFS) - wilc_debugfs_remove(); -#endif } EXPORT_SYMBOL_GPL(wilc_netdev_cleanup); @@ -1491,3 +1487,5 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, return 0; } EXPORT_SYMBOL_GPL(wilc_netdev_init); + +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/wilc1000/linux_wlan_common.h b/drivers/staging/wilc1000/linux_wlan_common.h index f2ea8280b8f86..72b524a98cbad 100644 --- a/drivers/staging/wilc1000/linux_wlan_common.h +++ b/drivers/staging/wilc1000/linux_wlan_common.h @@ -38,9 +38,6 @@ enum debug_region { #define FIRM_DBG (1 << Firmware_debug) #if defined (WILC_DEBUGFS) -int wilc_debugfs_init(void); -void wilc_debugfs_remove(void); - extern atomic_t WILC_REGION; extern atomic_t WILC_DEBUG_LEVEL; @@ -122,15 +119,6 @@ extern atomic_t WILC_DEBUG_LEVEL; printk(__VA_ARGS__); \ } while (0) -static inline int wilc_debugfs_init(void) -{ - return 0; -} - -static inline void wilc_debugfs_remove(void) -{ -} - #endif #define FN_IN /* PRINT_D(">>> \n") */ diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index 9072de43bcd9f..1f366b5f0d2d2 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -135,12 +135,14 @@ static void linux_sdio_remove(struct sdio_func *func) wilc_netdev_cleanup(sdio_get_drvdata(func)); } -static struct sdio_driver wilc_bus = { +static struct sdio_driver wilc1000_sdio_driver = { .name = SDIO_MODALIAS, .id_table = wilc_sdio_ids, .probe = linux_sdio_probe, .remove = linux_sdio_remove, }; +module_driver(wilc1000_sdio_driver, sdio_register_driver, sdio_unregister_driver); +MODULE_LICENSE("GPL"); int wilc_sdio_enable_interrupt(struct wilc *dev) { @@ -178,14 +180,15 @@ void wilc_sdio_disable_interrupt(struct wilc *dev) static int linux_sdio_set_speed(int speed) { struct mmc_ios ios; + struct sdio_func *func = container_of(wilc_dev->dev, struct sdio_func, dev); - sdio_claim_host(wilc_sdio_func); + sdio_claim_host(func); - memcpy((void *)&ios, (void *)&wilc_sdio_func->card->host->ios, sizeof(struct mmc_ios)); - wilc_sdio_func->card->host->ios.clock = speed; + memcpy((void *)&ios, (void *)&func->card->host->ios, sizeof(struct mmc_ios)); + func->card->host->ios.clock = speed; ios.clock = speed; - wilc_sdio_func->card->host->ops->set_ios(wilc_sdio_func->card->host, &ios); - sdio_release_host(wilc_sdio_func); + func->card->host->ops->set_ios(func->card->host, &ios); + sdio_release_host(func); PRINT_INFO(INIT_DBG, "@@@@@@@@@@@@ change SDIO speed to %d @@@@@@@@@\n", speed); return 1; @@ -193,7 +196,8 @@ static int linux_sdio_set_speed(int speed) static int linux_sdio_get_speed(void) { - return wilc_sdio_func->card->host->ios.clock; + struct sdio_func *func = container_of(wilc_dev->dev, struct sdio_func, dev); + return func->card->host->ios.clock; } int wilc_sdio_init(void) @@ -218,16 +222,4 @@ int wilc_sdio_set_default_speed(void) return linux_sdio_set_speed(sdio_default_speed); } -static int __init init_wilc_sdio_driver(void) -{ - return sdio_register_driver(&wilc_bus); -} -late_initcall(init_wilc_sdio_driver); - -static void __exit exit_wilc_sdio_driver(void) -{ - sdio_unregister_driver(&wilc_bus); -} -module_exit(exit_wilc_sdio_driver); - MODULE_LICENSE("GPL"); diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index a7a52593156ad..1d8922d6eb6ad 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "linux_wlan_spi.h" #include "wilc_wfi_netdevice.h" @@ -43,59 +44,53 @@ static u32 SPEED = MIN_SPEED; -struct spi_device *wilc_spi_dev; +static const struct wilc1000_ops wilc1000_spi_ops; -static int __init wilc_bus_probe(struct spi_device *spi) +static int wilc_bus_probe(struct spi_device *spi) { + int ret, gpio; + struct wilc *wilc; - PRINT_D(BUS_DBG, "spiModalias: %s\n", spi->modalias); - PRINT_D(BUS_DBG, "spiMax-Speed: %d\n", spi->max_speed_hz); - wilc_spi_dev = spi; + gpio = of_get_gpio(spi->dev.of_node, 0); + if (gpio < 0) + gpio = GPIO_NUM; + + ret = wilc_netdev_init(&wilc, NULL, HIF_SPI, GPIO_NUM, &wilc_hif_spi); + if (ret) + return ret; + + spi_set_drvdata(spi, wilc); + wilc->dev = &spi->dev; - printk("Driver Initializing success\n"); return 0; } -static int __exit wilc_bus_remove(struct spi_device *spi) +static int wilc_bus_remove(struct spi_device *spi) { - + wilc_netdev_cleanup(spi_get_drvdata(spi)); return 0; } -#ifdef CONFIG_OF static const struct of_device_id wilc1000_of_match[] = { { .compatible = "atmel,wilc_spi", }, {} }; MODULE_DEVICE_TABLE(of, wilc1000_of_match); -#endif -static struct spi_driver wilc_bus __refdata = { +struct spi_driver wilc1000_spi_driver = { .driver = { .name = MODALIAS, -#ifdef CONFIG_OF .of_match_table = wilc1000_of_match, -#endif }, .probe = wilc_bus_probe, - .remove = __exit_p(wilc_bus_remove), + .remove = wilc_bus_remove, }; +module_spi_driver(wilc1000_spi_driver); +MODULE_LICENSE("GPL"); int wilc_spi_init(void) { - int ret = 1; - static int called; - - - if (called == 0) { - called++; - ret = spi_register_driver(&wilc_bus); - } - - /* change return value to match WILC interface */ - (ret < 0) ? (ret = 0) : (ret = 1); - - return ret; + return 1; } #if defined(PLAT_WMS8304) @@ -106,6 +101,7 @@ int wilc_spi_init(void) int wilc_spi_write(u8 *b, u32 len) { + struct spi_device *spi = to_spi_device(wilc_dev->dev); int ret; if (len > 0 && b != NULL) { @@ -132,11 +128,11 @@ int wilc_spi_write(u8 *b, u32 len) memset(&msg, 0, sizeof(msg)); spi_message_init(&msg); - msg.spi = wilc_spi_dev; + msg.spi = spi; msg.is_dma_mapped = USE_SPI_DMA; spi_message_add_tail(&tr, &msg); - ret = spi_sync(wilc_spi_dev, &msg); + ret = spi_sync(spi, &msg); if (ret < 0) { PRINT_ER("SPI transaction failed\n"); } @@ -157,11 +153,11 @@ int wilc_spi_write(u8 *b, u32 len) memset(&msg, 0, sizeof(msg)); spi_message_init(&msg); - msg.spi = wilc_spi_dev; + msg.spi = spi; msg.is_dma_mapped = USE_SPI_DMA; /* rachel */ spi_message_add_tail(&tr, &msg); - ret = spi_sync(wilc_spi_dev, &msg); + ret = spi_sync(spi, &msg); if (ret < 0) { PRINT_ER("SPI transaction failed\n"); } @@ -183,7 +179,7 @@ int wilc_spi_write(u8 *b, u32 len) #else int wilc_spi_write(u8 *b, u32 len) { - + struct spi_device *spi = to_spi_device(wilc_dev->dev); int ret; struct spi_message msg; @@ -204,12 +200,12 @@ int wilc_spi_write(u8 *b, u32 len) memset(&msg, 0, sizeof(msg)); spi_message_init(&msg); /* [[johnny add */ - msg.spi = wilc_spi_dev; + msg.spi = spi; msg.is_dma_mapped = USE_SPI_DMA; /* ]] */ spi_message_add_tail(&tr, &msg); - ret = spi_sync(wilc_spi_dev, &msg); + ret = spi_sync(spi, &msg); if (ret < 0) { PRINT_ER("SPI transaction failed\n"); } @@ -234,6 +230,7 @@ int wilc_spi_write(u8 *b, u32 len) int wilc_spi_read(u8 *rb, u32 rlen) { + struct spi_device *spi = to_spi_device(wilc_dev->dev); int ret; if (rlen > 0) { @@ -260,11 +257,11 @@ int wilc_spi_read(u8 *rb, u32 rlen) memset(&msg, 0, sizeof(msg)); spi_message_init(&msg); - msg.spi = wilc_spi_dev; + msg.spi = spi; msg.is_dma_mapped = USE_SPI_DMA; spi_message_add_tail(&tr, &msg); - ret = spi_sync(wilc_spi_dev, &msg); + ret = spi_sync(spi, &msg); if (ret < 0) { PRINT_ER("SPI transaction failed\n"); } @@ -284,11 +281,11 @@ int wilc_spi_read(u8 *rb, u32 rlen) memset(&msg, 0, sizeof(msg)); spi_message_init(&msg); - msg.spi = wilc_spi_dev; + msg.spi = spi; msg.is_dma_mapped = USE_SPI_DMA; /* rachel */ spi_message_add_tail(&tr, &msg); - ret = spi_sync(wilc_spi_dev, &msg); + ret = spi_sync(spi, &msg); if (ret < 0) { PRINT_ER("SPI transaction failed\n"); } @@ -308,7 +305,7 @@ int wilc_spi_read(u8 *rb, u32 rlen) #else int wilc_spi_read(u8 *rb, u32 rlen) { - + struct spi_device *spi = to_spi_device(wilc_dev->dev); int ret; if (rlen > 0) { @@ -329,12 +326,12 @@ int wilc_spi_read(u8 *rb, u32 rlen) memset(&msg, 0, sizeof(msg)); spi_message_init(&msg); /* [[ johnny add */ - msg.spi = wilc_spi_dev; + msg.spi = spi; msg.is_dma_mapped = USE_SPI_DMA; /* ]] */ spi_message_add_tail(&tr, &msg); - ret = spi_sync(wilc_spi_dev, &msg); + ret = spi_sync(spi, &msg); if (ret < 0) { PRINT_ER("SPI transaction failed\n"); } @@ -353,7 +350,7 @@ int wilc_spi_read(u8 *rb, u32 rlen) int wilc_spi_write_read(u8 *wb, u8 *rb, u32 rlen) { - + struct spi_device *spi = to_spi_device(wilc_dev->dev); int ret; if (rlen > 0) { @@ -370,11 +367,11 @@ int wilc_spi_write_read(u8 *wb, u8 *rb, u32 rlen) memset(&msg, 0, sizeof(msg)); spi_message_init(&msg); - msg.spi = wilc_spi_dev; + msg.spi = spi; msg.is_dma_mapped = USE_SPI_DMA; spi_message_add_tail(&tr, &msg); - ret = spi_sync(wilc_spi_dev, &msg); + ret = spi_sync(spi, &msg); if (ret < 0) { PRINT_ER("SPI transaction failed\n"); } @@ -395,40 +392,3 @@ int wilc_spi_set_max_speed(void) PRINT_INFO(BUS_DBG, "@@@@@@@@@@@@ change SPI speed to %d @@@@@@@@@\n", SPEED); return 1; } - -static struct wilc *wilc; - -static int __init init_wilc_spi_driver(void) -{ - int ret; - - wilc_debugfs_init(); - - ret = wilc_netdev_init(&wilc, NULL, HIF_SPI, GPIO_NUM, &wilc_hif_spi); - if (ret) { - wilc_debugfs_remove(); - return ret; - } - - if (!wilc_spi_init() || !wilc_spi_dev) { - PRINT_ER("Can't initialize SPI\n"); - wilc_netdev_cleanup(wilc); - wilc_debugfs_remove(); - return -ENXIO; - } - wilc_dev->dev = &wilc_spi_dev->dev; - - return ret; -} -late_initcall(init_wilc_spi_driver); - -static void __exit exit_wilc_spi_driver(void) -{ - if (wilc) - wilc_netdev_cleanup(wilc); - spi_unregister_driver(&wilc_bus); - wilc_debugfs_remove(); -} -module_exit(exit_wilc_spi_driver); - -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/wilc1000/wilc_debugfs.c b/drivers/staging/wilc1000/wilc_debugfs.c index 158a1df171959..27c653a0cdf94 100644 --- a/drivers/staging/wilc1000/wilc_debugfs.c +++ b/drivers/staging/wilc1000/wilc_debugfs.c @@ -138,7 +138,7 @@ static struct wilc_debugfs_info_t debugfs_info[] = { { "wilc_debug_region", 0666, (INIT_DBG | GENERIC_DBG | CFG80211_DBG), FOPS(NULL, wilc_debug_region_read, wilc_debug_region_write, NULL), }, }; -int wilc_debugfs_init(void) +static int __init wilc_debugfs_init(void) { int i; @@ -173,11 +173,13 @@ int wilc_debugfs_init(void) } return 0; } +module_init(wilc_debugfs_init); -void wilc_debugfs_remove(void) +static void __exit wilc_debugfs_remove(void) { debugfs_remove_recursive(wilc_dir); } +module_exit(wilc_debugfs_remove); #endif -- GitLab From 562ed3f1f78a87746f128c313a5f92083ecb9408 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 15:05:10 +0100 Subject: [PATCH 1627/2855] staging/wilc1000: pass struct wilc to most linux_wlan.c functions We want to get rid of all global variables in this driver, and instead pass device structures from one function to another. This changes the linux_wlan.c and wilc_wlan.c to do this for the most part. There are a few exceptions where these functions are themselves called from another part of the driver that does not have an instance pointer at hand. Changing those would be a follow-up step. There are a few other globals that will have to get moved into struct wilc at a later point. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 +- drivers/staging/wilc1000/linux_wlan.c | 55 ++++--- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 12 +- drivers/staging/wilc1000/wilc_wlan.c | 145 +++++++++--------- drivers/staging/wilc1000/wilc_wlan.h | 10 +- 5 files changed, 119 insertions(+), 105 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index d968483c6f00d..640cb6bdf5237 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2905,7 +2905,7 @@ static int hostIFthread(void *pvArg) del_timer(&hif_drv->scan_timer); PRINT_D(HOSTINF_DBG, "scan completed successfully\n"); - if (!wilc_wlan_get_num_conn_ifcs()) + if (!wilc_wlan_get_num_conn_ifcs(wilc_dev)) wilc_chip_sleep_manually(); Handle_ScanDone(msg.drv, SCAN_EVENT_DONE); diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index c3b521e085f2d..89b5aca2115c5 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -245,13 +245,14 @@ static void deinit_irq(struct net_device *dev) } } -void linux_wlan_dbg(u8 *buff) +void wilc_dbg(struct wilc *wilc, u8 *buff) { PRINT_D(INIT_DBG, "%d\n", *buff); } -int linux_wlan_lock_timeout(void *vp, u32 timeout) +int wilc_lock_timeout(struct wilc *nic, void *vp, u32 timeout) { + /* FIXME: replace with mutex_lock or wait_for_completion */ int error = -1; PRINT_D(LOCK_DBG, "Locking %p\n", vp); @@ -263,7 +264,7 @@ int linux_wlan_lock_timeout(void *vp, u32 timeout) return error; } -void linux_wlan_mac_indicate(struct wilc *wilc, int flag) +void wilc_mac_indicate(struct wilc *wilc, int flag) { int status; @@ -328,14 +329,14 @@ int wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid) return ret; } -int wilc_wlan_get_num_conn_ifcs(void) +int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc) { u8 i = 0; u8 null_bssid[6] = {0}; u8 ret_val = 0; - for (i = 0; i < wilc_dev->vif_num; i++) - if (memcmp(wilc_dev->vif[i].bssid, null_bssid, 6)) + for (i = 0; i < wilc->vif_num; i++) + if (memcmp(wilc->vif[i].bssid, null_bssid, 6)) ret_val++; return ret_val; @@ -411,7 +412,7 @@ static int linux_wlan_txq_task(void *vp) return 0; } -void linux_wlan_rx_complete(void) +void wilc_rx_complete(struct wilc *nic) { PRINT_D(RX_DBG, "RX completed\n"); } @@ -468,14 +469,14 @@ static int linux_wlan_start_firmware(struct net_device *dev) wilc = nic->wilc; PRINT_D(INIT_DBG, "Starting Firmware ...\n"); - ret = wilc_wlan_start(); + ret = wilc_wlan_start(wilc); if (ret < 0) { PRINT_ER("Failed to start Firmware\n"); return ret; } PRINT_D(INIT_DBG, "Waiting for Firmware to get ready ...\n"); - ret = linux_wlan_lock_timeout(&wilc->sync_event, 5000); + ret = wilc_lock_timeout(wilc, &wilc->sync_event, 5000); if (ret) { PRINT_D(INIT_DBG, "Firmware start timed out"); return ret; @@ -485,7 +486,7 @@ static int linux_wlan_start_firmware(struct net_device *dev) return 0; } -static int linux_wlan_firmware_download(struct net_device *dev) +static int wilc1000_firmware_download(struct net_device *dev) { perInterface_wlan_t *nic; struct wilc *wilc; @@ -499,7 +500,7 @@ static int linux_wlan_firmware_download(struct net_device *dev) return -ENOBUFS; } PRINT_D(INIT_DBG, "Downloading Firmware ...\n"); - ret = wilc_wlan_firmware_download(wilc->firmware->data, + ret = wilc_wlan_firmware_download(wilc, wilc->firmware->data, wilc->firmware->size); if (ret < 0) return ret; @@ -754,7 +755,7 @@ void wilc1000_wlan_deinit(struct net_device *dev) PRINT_D(INIT_DBG, "Deinitializing IRQ\n"); deinit_irq(dev); - wilc_wlan_stop(); + wilc_wlan_stop(wl); PRINT_D(INIT_DBG, "Deinitializing WILC Wlan\n"); wilc_wlan_cleanup(dev); @@ -914,7 +915,7 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) goto _fail_irq_enable_; } - ret = linux_wlan_firmware_download(dev); + ret = wilc1000_firmware_download(dev); if (ret < 0) { PRINT_ER("Failed to download firmware\n"); ret = -EIO; @@ -952,7 +953,7 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) return 0; _fail_fw_start_: - wilc_wlan_stop(); + wilc_wlan_stop(wl); _fail_irq_enable_: if (!wl->dev_irq_num && @@ -985,6 +986,7 @@ static int mac_init_fn(struct net_device *ndev) int wilc_mac_open(struct net_device *ndev) { perInterface_wlan_t *nic; + struct wilc *wilc; unsigned char mac_add[ETH_ALEN] = {0}; int ret = 0; @@ -1001,6 +1003,7 @@ int wilc_mac_open(struct net_device *ndev) } nic = netdev_priv(ndev); + wilc = nic->wilc; priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy); PRINT_D(INIT_DBG, "MAC OPEN[%p]\n", ndev); @@ -1314,7 +1317,7 @@ done: return ret; } -void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset) +void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset) { unsigned int frame_len = 0; int stats; @@ -1393,7 +1396,7 @@ void wilc_netdev_cleanup(struct wilc *wilc) release_firmware(wilc->firmware); if (wilc && (wilc->vif[0].ndev || wilc->vif[1].ndev)) { - linux_wlan_lock_timeout(&close_exit_sync, 12 * 1000); + wilc_lock_timeout(wilc, &close_exit_sync, 12 * 1000); for (i = 0; i < NUM_CONCURRENT_IFC; i++) if (wilc->vif[i].ndev) @@ -1417,17 +1420,18 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, int i; perInterface_wlan_t *nic; struct net_device *ndev; + struct wilc *wl; sema_init(&close_exit_sync, 0); - wilc_dev = kzalloc(sizeof(*wilc_dev), GFP_KERNEL); - if (!wilc_dev) + wl = kzalloc(sizeof(*wilc_dev), GFP_KERNEL); + if (!wl) return -ENOMEM; - *wilc = wilc_dev; - wilc_dev->io_type = io_type; - wilc_dev->gpio = gpio; - wilc_dev->ops = ops; + *wilc = wl; + wl->io_type = io_type; + wl->gpio = gpio; + wl->ops = ops; register_inetaddr_notifier(&g_dev_notifier); @@ -1446,11 +1450,11 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, else strcpy(ndev->name, "p2p%d"); - nic->u8IfIdx = wilc_dev->vif_num; + nic->u8IfIdx = wl->vif_num; nic->wilc_netdev = ndev; nic->wilc = *wilc; - wilc_dev->vif[wilc_dev->vif_num].ndev = ndev; - wilc_dev->vif_num++; + wl->vif[wl->vif_num].ndev = ndev; + wl->vif_num++; ndev->netdev_ops = &wilc_netdev_ops; { @@ -1483,6 +1487,7 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, nic->iftype = STATION_MODE; nic->mac_opened = 0; } + wilc_dev = *wilc = wl; return 0; } diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 761bc3f591386..6ec6d6a2868c2 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -207,11 +207,12 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic); extern struct wilc *wilc_dev; extern struct net_device *WILC_WFI_devs[]; -void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset); -void linux_wlan_mac_indicate(struct wilc *wilc, int flag); -void linux_wlan_rx_complete(void); -void linux_wlan_dbg(u8 *buff); -int linux_wlan_lock_timeout(void *vp, u32 timeout); +void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset); +void wilc_mac_indicate(struct wilc *wilc, int flag); +void wilc_rx_complete(struct wilc *wilc); +void wilc_dbg(struct wilc *, u8 *buff); + +int wilc_lock_timeout(struct wilc *wilc, void *, u32 timeout); void wilc_netdev_cleanup(struct wilc *wilc); int wilc_netdev_init(struct wilc **wilc, struct device *, int io_type, int gpio, const struct wilc_hif_func *ops); @@ -220,4 +221,5 @@ void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size); u16 wilc_set_machw_change_vir_if(struct net_device *dev, bool value); int wilc_wlan_get_firmware(struct net_device *dev); int wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid); + #endif diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index a71901c226536..df8503f83a12c 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -40,6 +40,7 @@ static inline void chip_allow_sleep(void); static inline void chip_wakeup(void); static u32 dbgflag = N_INIT | N_ERR | N_INTR | N_TXQ | N_RXQ; +/* FIXME: replace with dev_debug() */ static void wilc_debug(u32 flag, char *fmt, ...) { char buf[256]; @@ -50,15 +51,15 @@ static void wilc_debug(u32 flag, char *fmt, ...) vsprintf(buf, fmt, args); va_end(args); - linux_wlan_dbg(buf); + wilc_dbg(wilc_dev, buf); } } static CHIP_PS_STATE_T chip_ps_state = CHIP_WAKEDUP; -static inline void acquire_bus(BUS_ACQUIRE_T acquire) +static inline void acquire_bus(struct wilc *wilc, BUS_ACQUIRE_T acquire) { - mutex_lock(&wilc_dev->hif_cs); + mutex_lock(&wilc->hif_cs); #ifndef WILC_OPTIMIZE_SLEEP_INT if (chip_ps_state != CHIP_WAKEDUP) #endif @@ -68,13 +69,13 @@ static inline void acquire_bus(BUS_ACQUIRE_T acquire) } } -static inline void release_bus(BUS_RELEASE_T release) +static inline void release_bus(struct wilc *wilc, BUS_RELEASE_T release) { #ifdef WILC_OPTIMIZE_SLEEP_INT if (release == RELEASE_ALLOW_SLEEP) chip_allow_sleep(); #endif - mutex_unlock(&wilc_dev->hif_cs); + mutex_unlock(&wilc->hif_cs); } #ifdef TCP_ACK_FILTER @@ -159,15 +160,15 @@ static void wilc_wlan_txq_add_to_tail(struct net_device *dev, up(&wilc->txq_event); } -static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe) +static int wilc_wlan_txq_add_to_head(struct wilc *wilc, struct txq_entry_t *tqe) { wilc_wlan_dev_t *p = &g_wlan; unsigned long flags; - if (linux_wlan_lock_timeout(&wilc_dev->txq_add_to_head_cs, + if (wilc_lock_timeout(wilc, &wilc->txq_add_to_head_cs, CFG_PKTS_TIMEOUT)) return -1; - spin_lock_irqsave(&wilc_dev->txq_spinlock, flags); + spin_lock_irqsave(&wilc->txq_spinlock, flags); if (!p->txq_head) { tqe->next = NULL; @@ -183,9 +184,9 @@ static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe) p->txq_entries += 1; PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", p->txq_entries); - spin_unlock_irqrestore(&wilc_dev->txq_spinlock, flags); - up(&wilc_dev->txq_add_to_head_cs); - up(&wilc_dev->txq_event); + spin_unlock_irqrestore(&wilc->txq_spinlock, flags); + up(&wilc->txq_add_to_head_cs); + up(&wilc->txq_event); PRINT_D(TX_DBG, "Wake up the txq_handler\n"); return 0; @@ -255,14 +256,14 @@ static inline int add_tcp_pending_ack(u32 ack, u32 session_index, } return 0; } -static inline int remove_TCP_related(void) +static inline int remove_TCP_related(struct wilc *wilc) { wilc_wlan_dev_t *p = &g_wlan; unsigned long flags; - spin_lock_irqsave(&wilc_dev->txq_spinlock, flags); + spin_lock_irqsave(&wilc->txq_spinlock, flags); - spin_unlock_irqrestore(&wilc_dev->txq_spinlock, flags); + spin_unlock_irqrestore(&wilc->txq_spinlock, flags); return 0; } @@ -281,7 +282,6 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) nic = netdev_priv(dev); wilc = nic->wilc; - spin_lock_irqsave(&wilc->txq_spinlock, flags); eth_hdr_ptr = &buffer[0]; h_proto = ntohs(*((unsigned short *)ð_hdr_ptr[12])); @@ -377,7 +377,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) spin_unlock_irqrestore(&wilc->txq_spinlock, p->txq_spinlock_flags); while (dropped > 0) { - linux_wlan_lock_timeout(&wilc->txq_event, 1); + wilc_lock_timeout(wilc, &wilc->txq_event, 1); dropped--; } @@ -399,7 +399,7 @@ static bool is_tcp_ack_filter_enabled(void) } #endif -static int wilc_wlan_txq_add_cfg_pkt(u8 *buffer, u32 buffer_size) +static int wilc_wlan_txq_add_cfg_pkt(struct wilc *wilc, u8 *buffer, u32 buffer_size) { wilc_wlan_dev_t *p = &g_wlan; struct txq_entry_t *tqe; @@ -407,7 +407,7 @@ static int wilc_wlan_txq_add_cfg_pkt(u8 *buffer, u32 buffer_size) PRINT_D(TX_DBG, "Adding config packet ...\n"); if (p->quit) { PRINT_D(TX_DBG, "Return due to clear function\n"); - up(&wilc_dev->cfg_event); + up(&wilc->cfg_event); return 0; } @@ -427,7 +427,7 @@ static int wilc_wlan_txq_add_cfg_pkt(u8 *buffer, u32 buffer_size) #endif PRINT_D(TX_DBG, "Adding the config packet at the Queue tail\n"); - if (wilc_wlan_txq_add_to_head(tqe)) + if (wilc_wlan_txq_add_to_head(wilc, tqe)) return 0; return 1; } @@ -682,7 +682,7 @@ void wilc_chip_sleep_manually(void) { if (chip_ps_state != CHIP_WAKEDUP) return; - acquire_bus(ACQUIRE_ONLY); + acquire_bus(wilc_dev, ACQUIRE_ONLY); #ifdef WILC_OPTIMIZE_SLEEP_INT chip_allow_sleep(); @@ -690,7 +690,7 @@ void wilc_chip_sleep_manually(void) g_wlan.hif_func.hif_write_reg(0x10a8, 1); chip_ps_state = CHIP_SLEEPING_MANUAL; - release_bus(RELEASE_ONLY); + release_bus(wilc_dev, RELEASE_ONLY); } int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) @@ -718,7 +718,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) if (p->quit) break; - linux_wlan_lock_timeout(&wilc->txq_add_to_head_cs, + wilc_lock_timeout(wilc, &wilc->txq_add_to_head_cs, CFG_PKTS_TIMEOUT); #ifdef TCP_ACK_FILTER wilc_wlan_txq_filter_dup_tcp_ack(dev); @@ -775,7 +775,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) PRINT_D(TX_DBG, "Mark the last entry in VMM table - number of previous entries = %d\n", i); vmm_table[i] = 0x0; } - acquire_bus(ACQUIRE_AND_WAKEUP); + acquire_bus(wilc, ACQUIRE_AND_WAKEUP); counter = 0; do { ret = p->hif_func.hif_read_reg(WILC_HOST_TX_CTRL, ®); @@ -796,9 +796,9 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) break; } PRINT_WRN(GENERIC_DBG, "[wilc txq]: warn, vmm table not clear yet, wait...\n"); - release_bus(RELEASE_ALLOW_SLEEP); + release_bus(wilc, RELEASE_ALLOW_SLEEP); usleep_range(3000, 3000); - acquire_bus(ACQUIRE_AND_WAKEUP); + acquire_bus(wilc, ACQUIRE_AND_WAKEUP); } } while (!p->quit); @@ -829,9 +829,9 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) entries = ((reg >> 3) & 0x3f); break; } else { - release_bus(RELEASE_ALLOW_SLEEP); + release_bus(wilc, RELEASE_ALLOW_SLEEP); usleep_range(3000, 3000); - acquire_bus(ACQUIRE_AND_WAKEUP); + acquire_bus(wilc, ACQUIRE_AND_WAKEUP); PRINT_WRN(GENERIC_DBG, "Can't get VMM entery - reg = %2x\n", reg); } } while (--timeout); @@ -871,7 +871,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) goto _end_; } - release_bus(RELEASE_ALLOW_SLEEP); + release_bus(wilc, RELEASE_ALLOW_SLEEP); offset = 0; i = 0; @@ -926,7 +926,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) } } while (--entries); - acquire_bus(ACQUIRE_AND_WAKEUP); + acquire_bus(wilc, ACQUIRE_AND_WAKEUP); ret = p->hif_func.hif_clear_int_ext(ENABLE_TX_VMM); if (!ret) { @@ -942,7 +942,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) _end_: - release_bus(RELEASE_ALLOW_SLEEP); + release_bus(wilc, RELEASE_ALLOW_SLEEP); if (ret != 1) break; } while (0); @@ -1016,7 +1016,7 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) } else { if (!is_cfg_packet) { if (pkt_len > 0) { - frmw_to_linux(wilc, + wilc_frmw_to_linux(wilc, &buffer[offset], pkt_len, pkt_offset); @@ -1031,10 +1031,10 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) if (p->cfg_seq_no == rsp.seq_no) up(&wilc->cfg_event); } else if (rsp.type == WILC_CFG_RSP_STATUS) { - linux_wlan_mac_indicate(wilc, WILC_MAC_INDICATE_STATUS); + wilc_mac_indicate(wilc, WILC_MAC_INDICATE_STATUS); } else if (rsp.type == WILC_CFG_RSP_SCAN) { - linux_wlan_mac_indicate(wilc, WILC_MAC_INDICATE_SCAN); + wilc_mac_indicate(wilc, WILC_MAC_INDICATE_SCAN); } } } @@ -1048,7 +1048,7 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) kfree(rqe); if (has_packet) - linux_wlan_rx_complete(); + wilc_rx_complete(wilc); } while (1); @@ -1157,11 +1157,11 @@ _end_: wilc_wlan_handle_rxq(wilc); } -void wilc_handle_isr(void *wilc) +void wilc_handle_isr(struct wilc *wilc) { u32 int_status; - acquire_bus(ACQUIRE_AND_WAKEUP); + acquire_bus(wilc, ACQUIRE_AND_WAKEUP); g_wlan.hif_func.hif_read_int(&int_status); if (int_status & PLL_INT_EXT) @@ -1179,11 +1179,11 @@ void wilc_handle_isr(void *wilc) if (!(int_status & (ALL_INT_EXT))) { wilc_unknown_isr_ext(); } - release_bus(RELEASE_ALLOW_SLEEP); + release_bus(wilc, RELEASE_ALLOW_SLEEP); } EXPORT_SYMBOL_GPL(wilc_handle_isr); -int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size) +int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, u32 buffer_size) { wilc_wlan_dev_t *p = &g_wlan; u32 offset; @@ -1210,7 +1210,7 @@ int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size) addr = BYTE_SWAP(addr); size = BYTE_SWAP(size); #endif - acquire_bus(ACQUIRE_ONLY); + acquire_bus(wilc, ACQUIRE_ONLY); offset += 8; while (((int)size) && (offset < buffer_size)) { if (size <= blksz) @@ -1227,7 +1227,7 @@ int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size) offset += size2; size -= size2; } - release_bus(RELEASE_ONLY); + release_bus(wilc, RELEASE_ONLY); if (!ret) { ret = -EIO; @@ -1246,7 +1246,7 @@ _fail_1: return (ret < 0) ? ret : 0; } -int wilc_wlan_start(void) +int wilc_wlan_start(struct wilc *wilc) { wilc_wlan_dev_t *p = &g_wlan; u32 reg = 0; @@ -1259,16 +1259,16 @@ int wilc_wlan_start(void) } else if (p->io_type == HIF_SPI) { reg = 1; } - acquire_bus(ACQUIRE_ONLY); + acquire_bus(wilc, ACQUIRE_ONLY); ret = p->hif_func.hif_write_reg(WILC_VMM_CORE_CFG, reg); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail write reg vmm_core_cfg...\n"); - release_bus(RELEASE_ONLY); + release_bus(wilc, RELEASE_ONLY); ret = -EIO; return ret; } reg = 0; - if (p->io_type == HIF_SDIO && wilc_dev->dev_irq_num) + if (p->io_type == HIF_SDIO && wilc->dev_irq_num) reg |= WILC_HAVE_SDIO_IRQ_GPIO; #ifdef WILC_DISABLE_PMU @@ -1297,7 +1297,7 @@ int wilc_wlan_start(void) ret = p->hif_func.hif_write_reg(WILC_GP_REG_1, reg); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail write WILC_GP_REG_1 ...\n"); - release_bus(RELEASE_ONLY); + release_bus(wilc, RELEASE_ONLY); ret = -EIO; return ret; } @@ -1307,7 +1307,7 @@ int wilc_wlan_start(void) ret = p->hif_func.hif_read_reg(0x1000, &chipid); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail read reg 0x1000 ...\n"); - release_bus(RELEASE_ONLY); + release_bus(wilc, RELEASE_ONLY); ret = -EIO; return ret; } @@ -1322,32 +1322,32 @@ int wilc_wlan_start(void) reg |= BIT(10); ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg); p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); - release_bus(RELEASE_ONLY); + release_bus(wilc, RELEASE_ONLY); return (ret < 0) ? ret : 0; } -void wilc_wlan_global_reset(void) +void wilc_wlan_global_reset(struct wilc *wilc) { wilc_wlan_dev_t *p = &g_wlan; - acquire_bus(ACQUIRE_AND_WAKEUP); + acquire_bus(wilc, ACQUIRE_AND_WAKEUP); p->hif_func.hif_write_reg(WILC_GLB_RESET_0, 0x0); - release_bus(RELEASE_ONLY); + release_bus(wilc, RELEASE_ONLY); } -int wilc_wlan_stop(void) +int wilc_wlan_stop(struct wilc *wilc) { wilc_wlan_dev_t *p = &g_wlan; u32 reg = 0; int ret; u8 timeout = 10; - acquire_bus(ACQUIRE_AND_WAKEUP); + acquire_bus(wilc, ACQUIRE_AND_WAKEUP); ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); if (!ret) { PRINT_ER("Error while reading reg\n"); - release_bus(RELEASE_ALLOW_SLEEP); + release_bus(wilc, RELEASE_ALLOW_SLEEP); return ret; } @@ -1355,7 +1355,7 @@ int wilc_wlan_stop(void) ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg); if (!ret) { PRINT_ER("Error while writing reg\n"); - release_bus(RELEASE_ALLOW_SLEEP); + release_bus(wilc, RELEASE_ALLOW_SLEEP); return ret; } @@ -1363,7 +1363,7 @@ int wilc_wlan_stop(void) ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); if (!ret) { PRINT_ER("Error while reading reg\n"); - release_bus(RELEASE_ALLOW_SLEEP); + release_bus(wilc, RELEASE_ALLOW_SLEEP); return ret; } PRINT_D(GENERIC_DBG, "Read RESET Reg %x : Retry%d\n", @@ -1381,7 +1381,7 @@ int wilc_wlan_stop(void) ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); if (!ret) { PRINT_ER("Error while reading reg\n"); - release_bus(RELEASE_ALLOW_SLEEP); + release_bus(wilc, RELEASE_ALLOW_SLEEP); return ret; } PRINT_D(GENERIC_DBG, "Read RESET Reg %x : Retry%d\n", @@ -1398,7 +1398,7 @@ int wilc_wlan_stop(void) ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg); - release_bus(RELEASE_ALLOW_SLEEP); + release_bus(wilc, RELEASE_ALLOW_SLEEP); return ret; } @@ -1442,24 +1442,24 @@ void wilc_wlan_cleanup(struct net_device *dev) #endif kfree(p->tx_buffer); - acquire_bus(ACQUIRE_AND_WAKEUP); + acquire_bus(wilc, ACQUIRE_AND_WAKEUP); ret = p->hif_func.hif_read_reg(WILC_GP_REG_0, ®); if (!ret) { PRINT_ER("Error while reading reg\n"); - release_bus(RELEASE_ALLOW_SLEEP); + release_bus(wilc, RELEASE_ALLOW_SLEEP); } PRINT_ER("Writing ABORT reg\n"); ret = p->hif_func.hif_write_reg(WILC_GP_REG_0, (reg | ABORT_INT)); if (!ret) { PRINT_ER("Error while writing reg\n"); - release_bus(RELEASE_ALLOW_SLEEP); + release_bus(wilc, RELEASE_ALLOW_SLEEP); } - release_bus(RELEASE_ALLOW_SLEEP); + release_bus(wilc, RELEASE_ALLOW_SLEEP); p->hif_func.hif_deinit(NULL); } -static int wilc_wlan_cfg_commit(int type, u32 drv_handler) +static int wilc_wlan_cfg_commit(struct wilc *wilc, int type, u32 drv_handler) { wilc_wlan_dev_t *p = &g_wlan; struct wilc_cfg_frame *cfg = &p->cfg_frame; @@ -1480,7 +1480,7 @@ static int wilc_wlan_cfg_commit(int type, u32 drv_handler) cfg->wid_header[7] = (u8)(driver_handler >> 24); p->cfg_seq_no = seq_no; - if (!wilc_wlan_txq_add_cfg_pkt(&cfg->wid_header[0], total_len)) + if (!wilc_wlan_txq_add_cfg_pkt(wilc, &cfg->wid_header[0], total_len)) return -1; return 0; @@ -1490,6 +1490,7 @@ int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, int commit, u32 drv_handler) { wilc_wlan_dev_t *p = &g_wlan; + struct wilc *wilc = wilc_dev; u32 offset; int ret_size; @@ -1511,10 +1512,10 @@ int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, PRINT_D(RX_DBG, "Processing cfg_set()\n"); p->cfg_frame_in_use = 1; - if (wilc_wlan_cfg_commit(WILC_CFG_SET, drv_handler)) + if (wilc_wlan_cfg_commit(wilc, WILC_CFG_SET, drv_handler)) ret_size = 0; - if (linux_wlan_lock_timeout(&wilc_dev->cfg_event, + if (wilc_lock_timeout(wilc, &wilc->cfg_event, CFG_PKTS_TIMEOUT)) { PRINT_D(TX_DBG, "Set Timed Out\n"); ret_size = 0; @@ -1530,6 +1531,7 @@ int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drv_handler) { wilc_wlan_dev_t *p = &g_wlan; + struct wilc *wilc = wilc_dev; u32 offset; int ret_size; @@ -1547,10 +1549,10 @@ int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drv_handler) if (commit) { p->cfg_frame_in_use = 1; - if (wilc_wlan_cfg_commit(WILC_CFG_QUERY, drv_handler)) + if (wilc_wlan_cfg_commit(wilc, WILC_CFG_QUERY, drv_handler)) ret_size = 0; - if (linux_wlan_lock_timeout(&wilc_dev->cfg_event, + if (wilc_lock_timeout(wilc, &wilc->cfg_event, CFG_PKTS_TIMEOUT)) { PRINT_D(TX_DBG, "Get Timed Out\n"); ret_size = 0; @@ -1587,8 +1589,13 @@ static u32 init_chip(struct net_device *dev) { u32 chipid; u32 reg, ret = 0; + perInterface_wlan_t *nic; + struct wilc *wilc; + + nic = netdev_priv(dev); + wilc = nic->wilc; - acquire_bus(ACQUIRE_ONLY); + acquire_bus(wilc, ACQUIRE_ONLY); chipid = wilc_get_chipid(true); @@ -1611,7 +1618,7 @@ static u32 init_chip(struct net_device *dev) } } - release_bus(RELEASE_ONLY); + release_bus(wilc, RELEASE_ONLY); return ret; } diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 90ef650e722d2..20bca44bc8ba5 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -283,13 +283,13 @@ struct wilc_cfg_rsp { struct wilc; -int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size); -int wilc_wlan_start(void); -int wilc_wlan_stop(void); +int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, u32 buffer_size); +int wilc_wlan_start(struct wilc *); +int wilc_wlan_stop(struct wilc *); int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func); int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count); -void wilc_handle_isr(void *wilc); +void wilc_handle_isr(struct wilc *wilc); void wilc_wlan_cleanup(struct net_device *dev); int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, int commit, u32 drv_handler); @@ -300,7 +300,7 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, void wilc_chip_sleep_manually(void); void wilc_enable_tcp_ack_filter(bool value); -int wilc_wlan_get_num_conn_ifcs(void); +int wilc_wlan_get_num_conn_ifcs(struct wilc *); int wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev); int wilc_mac_open(struct net_device *ndev); -- GitLab From 8142b47ef33c655a34e08efd46b65732fe190675 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 14 Dec 2015 16:13:31 +0100 Subject: [PATCH 1628/2855] mtd: nand: remove unused and buggy get_platform_nandchip() helper function Nobody uses the get_platform_nandchip() helper function which is supposed to return a pointer to a platform_nand_chip struct from an mtd_info pointer. Moreover, this function is buggy since the introduction of the plat_nand layer (chip->priv is now storing a pointer to an intermediate plat_nand_data structure allocated in plat_nand_probe(), and we have no way to retrieve a pointer to the provided platform_nand_chip struct from this plat_nand_data pointer). While we are at it, remove the useless (and buggy, since it's pointing to something stored on the stack) data->chip.priv assignment. Signed-off-by: Boris Brezillon Fixes: 711fdf627ce1 ("[MTD] [NAND] platform NAND driver: add driver") Cc: Vitaly Wool Signed-off-by: Brian Norris --- drivers/mtd/nand/plat_nand.c | 1 - include/linux/mtd/nand.h | 9 --------- 2 files changed, 10 deletions(-) diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index dc88a58d5cdeb..a0e26dea1424b 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c @@ -56,7 +56,6 @@ static int plat_nand_probe(struct platform_device *pdev) if (IS_ERR(data->io_base)) return PTR_ERR(data->io_base); - data->chip.priv = &data; nand_set_flash_node(&data->chip, pdev->dev.of_node); mtd = nand_to_mtd(&data->chip); mtd->dev.parent = &pdev->dev; diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 2bee2e42ae2f1..3e92be1d2d439 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -927,15 +927,6 @@ struct platform_nand_data { struct platform_nand_ctrl ctrl; }; -/* Some helpers to access the data structures */ -static inline -struct platform_nand_chip *get_platform_nandchip(struct mtd_info *mtd) -{ - struct nand_chip *chip = mtd->priv; - - return chip->priv; -} - /* return the supported features. */ static inline int onfi_feature(struct nand_chip *chip) { -- GitLab From 49645e5c87fbb51f0608218f78325996ce8401f8 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Wed, 18 Nov 2015 15:11:22 +0900 Subject: [PATCH 1629/2855] staging: wilc1000: remove sdio speed control codes This patch removes spi speed control related functions and variable. We cannot get exact clock what we need in this way and it can causes some problem in host side by setting the clock, so remove the codes. Speed control codes in spi also will removed in next patch, so it's ok to remove functions in linux_wlan.c and wilc_wlan.c which also not used anymore. The Following functions and varialbe are removed. MAX_SPEED, sdio_default_speed wilc_bus_set_default_speed wilc_bus_set_max_speed linux_sdio_set_speed linux_sdio_get_speed wilc_sdio_set_max_speed wilc_sdio_set_default_speed Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 8 ---- drivers/staging/wilc1000/linux_wlan_sdio.c | 52 ---------------------- drivers/staging/wilc1000/linux_wlan_sdio.h | 3 -- drivers/staging/wilc1000/wilc_sdio.c | 12 ----- drivers/staging/wilc1000/wilc_wlan.c | 10 ----- 5 files changed, 85 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 89b5aca2115c5..ab17110fb17e2 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -733,12 +733,6 @@ void wilc1000_wlan_deinit(struct net_device *dev) if (wl->initialized) { netdev_info(dev, "Deinitializing wilc1000...\n"); -#if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31) - PRINT_D(INIT_DBG, "skip wilc_bus_set_default_speed\n"); -#else - wilc_bus_set_default_speed(); -#endif - PRINT_D(INIT_DBG, "Disabling IRQ\n"); if (!wl->dev_irq_num && wl->ops->disable_interrupt) { @@ -929,8 +923,6 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) goto _fail_irq_enable_; } - wilc_bus_set_max_speed(); - if (wilc_wlan_cfg_get(1, WID_FIRMWARE_VERSION, 1, 0)) { int size; char Firmware_ver[20]; diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index 1f366b5f0d2d2..761cb3ddd132d 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -11,19 +11,7 @@ #define SDIO_MODALIAS "wilc1000_sdio" -#if defined(CUSTOMER_PLATFORM) -/* TODO : User have to stable bus clock as user's environment. */ - #ifdef MAX_BUS_SPEED - #define MAX_SPEED MAX_BUS_SPEED - #else - #define MAX_SPEED 50000000 - #endif -#else - #define MAX_SPEED (6 * 1000000) /* Max 50M */ -#endif - static struct sdio_func *wilc_sdio_func; -static unsigned int sdio_default_speed; #define SDIO_VENDOR_ID_WILC 0x0296 #define SDIO_DEVICE_ID_WILC 0x5347 @@ -177,49 +165,9 @@ void wilc_sdio_disable_interrupt(struct wilc *dev) PRINT_D(INIT_DBG, "wilc_sdio_disable_interrupt OUT\n"); } -static int linux_sdio_set_speed(int speed) -{ - struct mmc_ios ios; - struct sdio_func *func = container_of(wilc_dev->dev, struct sdio_func, dev); - - sdio_claim_host(func); - - memcpy((void *)&ios, (void *)&func->card->host->ios, sizeof(struct mmc_ios)); - func->card->host->ios.clock = speed; - ios.clock = speed; - func->card->host->ops->set_ios(func->card->host, &ios); - sdio_release_host(func); - PRINT_INFO(INIT_DBG, "@@@@@@@@@@@@ change SDIO speed to %d @@@@@@@@@\n", speed); - - return 1; -} - -static int linux_sdio_get_speed(void) -{ - struct sdio_func *func = container_of(wilc_dev->dev, struct sdio_func, dev); - return func->card->host->ios.clock; -} - int wilc_sdio_init(void) { - - /** - * TODO : - **/ - - - sdio_default_speed = linux_sdio_get_speed(); return 1; } -int wilc_sdio_set_max_speed(void) -{ - return linux_sdio_set_speed(MAX_SPEED); -} - -int wilc_sdio_set_default_speed(void) -{ - return linux_sdio_set_speed(sdio_default_speed); -} - MODULE_LICENSE("GPL"); diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.h b/drivers/staging/wilc1000/linux_wlan_sdio.h index d7b213a7b18d1..dbe911a9ae3d0 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.h +++ b/drivers/staging/wilc1000/linux_wlan_sdio.h @@ -6,6 +6,3 @@ int wilc_sdio_cmd53(sdio_cmd53_t *cmd); int wilc_sdio_enable_interrupt(struct wilc *); void wilc_sdio_disable_interrupt(struct wilc *); -int wilc_sdio_set_max_speed(void); -int wilc_sdio_set_default_speed(void); - diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index f550ce059c159..b0454a7e78a51 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -610,16 +610,6 @@ _fail_: return 0; } -static void sdio_set_max_speed(void) -{ - wilc_sdio_set_max_speed(); -} - -static void sdio_set_default_speed(void) -{ - wilc_sdio_set_default_speed(); -} - static int sdio_read_size(u32 *size) { @@ -927,8 +917,6 @@ const struct wilc_hif_func wilc_hif_sdio = { .hif_block_tx_ext = sdio_write, .hif_block_rx_ext = sdio_read, .hif_sync_ext = sdio_sync_ext, - .hif_set_max_bus_speed = sdio_set_max_speed, - .hif_set_default_bus_speed = sdio_set_default_speed, .enable_interrupt = wilc_sdio_enable_interrupt, .disable_interrupt = wilc_sdio_disable_interrupt, }; diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index df8503f83a12c..114ea9535f790 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1575,16 +1575,6 @@ int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size) return ret; } -void wilc_bus_set_max_speed(void) -{ - g_wlan.hif_func.hif_set_max_bus_speed(); -} - -void wilc_bus_set_default_speed(void) -{ - g_wlan.hif_func.hif_set_default_bus_speed(); -} - static u32 init_chip(struct net_device *dev) { u32 chipid; -- GitLab From 4c885c6b2617809474499912e3d51e73339640be Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Wed, 18 Nov 2015 15:11:23 +0900 Subject: [PATCH 1630/2855] staging: wilc1000: remove spi speed control codes This patch removes spi speed control codes. We are not using define SPEED to specify speed of spi, it is not proper way of doing this. It will be provided by the device tree. The following functions and variable are removed. MIN_SPEED, MAX_SPEED, SPEED wilc_spi_set_max_speed wilc_spi_max_bus_speed wilc_spi_default_bus_speed hif_set_max_bus_speed hif_set_default_bus_speed Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_spi.c | 42 ----------------------- drivers/staging/wilc1000/linux_wlan_spi.h | 2 -- drivers/staging/wilc1000/wilc_spi.c | 11 ------ drivers/staging/wilc1000/wilc_wlan.h | 2 -- 4 files changed, 57 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index 1d8922d6eb6ad..5e3bff05a95fd 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -17,33 +17,6 @@ #define USE_SPI_DMA 0 /* johnny add */ -#ifdef WILC_ASIC_A0 - #if defined(PLAT_PANDA_ES_OMAP4460) - #define MIN_SPEED 12000000 - #define MAX_SPEED 24000000 - #elif defined(PLAT_WMS8304) - #define MIN_SPEED 12000000 - #define MAX_SPEED 24000000 /* 4000000 */ - #elif defined(CUSTOMER_PLATFORM) -/* - TODO : define Clock speed under 48M. - * - * ex) - * #define MIN_SPEED 24000000 - * #define MAX_SPEED 48000000 - */ - #else - #define MIN_SPEED 24000000 - #define MAX_SPEED 48000000 - #endif -#else /* WILC_ASIC_A0 */ -/* Limit clk to 6MHz on FPGA. */ - #define MIN_SPEED 6000000 - #define MAX_SPEED 6000000 -#endif /* WILC_ASIC_A0 */ - -static u32 SPEED = MIN_SPEED; - static const struct wilc1000_ops wilc1000_spi_ops; static int wilc_bus_probe(struct spi_device *spi) @@ -119,7 +92,6 @@ int wilc_spi_write(u8 *b, u32 len) struct spi_transfer tr = { .tx_buf = b + (i * TXRX_PHASE_SIZE), .len = TXRX_PHASE_SIZE, - .speed_hz = SPEED, .bits_per_word = 8, .delay_usecs = 0, }; @@ -145,7 +117,6 @@ int wilc_spi_write(u8 *b, u32 len) struct spi_transfer tr = { .tx_buf = b + (blk * TXRX_PHASE_SIZE), .len = remainder, - .speed_hz = SPEED, .bits_per_word = 8, .delay_usecs = 0, }; @@ -187,7 +158,6 @@ int wilc_spi_write(u8 *b, u32 len) struct spi_transfer tr = { .tx_buf = b, .len = len, - .speed_hz = SPEED, .delay_usecs = 0, }; char *r_buffer = kzalloc(len, GFP_KERNEL); @@ -249,7 +219,6 @@ int wilc_spi_read(u8 *rb, u32 rlen) struct spi_transfer tr = { .rx_buf = rb + (i * TXRX_PHASE_SIZE), .len = TXRX_PHASE_SIZE, - .speed_hz = SPEED, .bits_per_word = 8, .delay_usecs = 0, }; @@ -273,7 +242,6 @@ int wilc_spi_read(u8 *rb, u32 rlen) struct spi_transfer tr = { .rx_buf = rb + (blk * TXRX_PHASE_SIZE), .len = remainder, - .speed_hz = SPEED, .bits_per_word = 8, .delay_usecs = 0, }; @@ -313,7 +281,6 @@ int wilc_spi_read(u8 *rb, u32 rlen) struct spi_transfer tr = { .rx_buf = rb, .len = rlen, - .speed_hz = SPEED, .delay_usecs = 0, }; @@ -359,7 +326,6 @@ int wilc_spi_write_read(u8 *wb, u8 *rb, u32 rlen) .rx_buf = rb, .tx_buf = wb, .len = rlen, - .speed_hz = SPEED, .bits_per_word = 8, .delay_usecs = 0, @@ -384,11 +350,3 @@ int wilc_spi_write_read(u8 *wb, u8 *rb, u32 rlen) return ret; } - -int wilc_spi_set_max_speed(void) -{ - SPEED = MAX_SPEED; - - PRINT_INFO(BUS_DBG, "@@@@@@@@@@@@ change SPI speed to %d @@@@@@@@@\n", SPEED); - return 1; -} diff --git a/drivers/staging/wilc1000/linux_wlan_spi.h b/drivers/staging/wilc1000/linux_wlan_spi.h index f434f79913abc..baa98cc9a247e 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.h +++ b/drivers/staging/wilc1000/linux_wlan_spi.h @@ -7,6 +7,4 @@ int wilc_spi_init(void); int wilc_spi_write(u8 *b, u32 len); int wilc_spi_read(u8 *rb, u32 rlen); int wilc_spi_write_read(u8 *wb, u8 *rb, u32 rlen); -int wilc_spi_set_max_speed(void); - #endif diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 39dd75665ba74..1c5dcda4b6345 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -793,15 +793,6 @@ static int _wilc_spi_init(struct wilc *wilc, wilc_debug_func func) return 1; } -static void wilc_spi_max_bus_speed(void) -{ - wilc_spi_set_max_speed(); -} - -static void wilc_spi_default_bus_speed(void) -{ -} - static int wilc_spi_read_size(u32 *size) { int ret; @@ -1036,6 +1027,4 @@ const struct wilc_hif_func wilc_hif_spi = { .hif_block_tx_ext = _wilc_spi_write, .hif_block_rx_ext = _wilc_spi_read, .hif_sync_ext = wilc_spi_sync_ext, - .hif_set_max_bus_speed = wilc_spi_max_bus_speed, - .hif_set_default_bus_speed = wilc_spi_default_bus_speed, }; diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 20bca44bc8ba5..ee13771eb54cd 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -251,8 +251,6 @@ struct wilc_hif_func { int (*hif_block_tx_ext)(u32, u8 *, u32); int (*hif_block_rx_ext)(u32, u8 *, u32); int (*hif_sync_ext)(int); - void (*hif_set_max_bus_speed)(void); - void (*hif_set_default_bus_speed)(void); int (*enable_interrupt)(struct wilc *nic); void (*disable_interrupt)(struct wilc *nic); }; -- GitLab From aeed77f42709f0d7a7f6f70dd3a2a2fa63acbee8 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Wed, 18 Nov 2015 15:11:24 +0900 Subject: [PATCH 1631/2855] staging: wilc1000: remove paltform define PLAT_WMS8304 This patch removes PLAT_WMS8304 and it's related codes as well. We will not use this way of supporting other platform. This will be supported if necessary by device tree later. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_spi.c | 161 ---------------------- 1 file changed, 161 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index 5e3bff05a95fd..bfd3cc3914946 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -66,88 +66,6 @@ int wilc_spi_init(void) return 1; } -#if defined(PLAT_WMS8304) -#define TXRX_PHASE_SIZE (4096) -#endif - -#if defined(TXRX_PHASE_SIZE) - -int wilc_spi_write(u8 *b, u32 len) -{ - struct spi_device *spi = to_spi_device(wilc_dev->dev); - int ret; - - if (len > 0 && b != NULL) { - int i = 0; - int blk = len / TXRX_PHASE_SIZE; - int remainder = len % TXRX_PHASE_SIZE; - - char *r_buffer = kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL); - if (!r_buffer) - return -ENOMEM; - - if (blk) { - while (i < blk) { - struct spi_message msg; - struct spi_transfer tr = { - .tx_buf = b + (i * TXRX_PHASE_SIZE), - .len = TXRX_PHASE_SIZE, - .bits_per_word = 8, - .delay_usecs = 0, - }; - - tr.rx_buf = r_buffer; - - memset(&msg, 0, sizeof(msg)); - spi_message_init(&msg); - msg.spi = spi; - msg.is_dma_mapped = USE_SPI_DMA; - - spi_message_add_tail(&tr, &msg); - ret = spi_sync(spi, &msg); - if (ret < 0) { - PRINT_ER("SPI transaction failed\n"); - } - i++; - - } - } - if (remainder) { - struct spi_message msg; - struct spi_transfer tr = { - .tx_buf = b + (blk * TXRX_PHASE_SIZE), - .len = remainder, - .bits_per_word = 8, - .delay_usecs = 0, - }; - tr.rx_buf = r_buffer; - - memset(&msg, 0, sizeof(msg)); - spi_message_init(&msg); - msg.spi = spi; - msg.is_dma_mapped = USE_SPI_DMA; /* rachel */ - - spi_message_add_tail(&tr, &msg); - ret = spi_sync(spi, &msg); - if (ret < 0) { - PRINT_ER("SPI transaction failed\n"); - } - } - kfree(r_buffer); - } else { - PRINT_ER("can't write data with the following length: %d\n", len); - PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len); - ret = -1; - } - - /* change return value to match WILC interface */ - (ret < 0) ? (ret = 0) : (ret = 1); - - return ret; - -} - -#else int wilc_spi_write(u8 *b, u32 len) { struct spi_device *spi = to_spi_device(wilc_dev->dev); @@ -194,83 +112,6 @@ int wilc_spi_write(u8 *b, u32 len) return ret; } -#endif - -#if defined(TXRX_PHASE_SIZE) - -int wilc_spi_read(u8 *rb, u32 rlen) -{ - struct spi_device *spi = to_spi_device(wilc_dev->dev); - int ret; - - if (rlen > 0) { - int i = 0; - - int blk = rlen / TXRX_PHASE_SIZE; - int remainder = rlen % TXRX_PHASE_SIZE; - - char *t_buffer = kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL); - if (!t_buffer) - return -ENOMEM; - - if (blk) { - while (i < blk) { - struct spi_message msg; - struct spi_transfer tr = { - .rx_buf = rb + (i * TXRX_PHASE_SIZE), - .len = TXRX_PHASE_SIZE, - .bits_per_word = 8, - .delay_usecs = 0, - }; - tr.tx_buf = t_buffer; - - memset(&msg, 0, sizeof(msg)); - spi_message_init(&msg); - msg.spi = spi; - msg.is_dma_mapped = USE_SPI_DMA; - - spi_message_add_tail(&tr, &msg); - ret = spi_sync(spi, &msg); - if (ret < 0) { - PRINT_ER("SPI transaction failed\n"); - } - i++; - } - } - if (remainder) { - struct spi_message msg; - struct spi_transfer tr = { - .rx_buf = rb + (blk * TXRX_PHASE_SIZE), - .len = remainder, - .bits_per_word = 8, - .delay_usecs = 0, - }; - tr.tx_buf = t_buffer; - - memset(&msg, 0, sizeof(msg)); - spi_message_init(&msg); - msg.spi = spi; - msg.is_dma_mapped = USE_SPI_DMA; /* rachel */ - - spi_message_add_tail(&tr, &msg); - ret = spi_sync(spi, &msg); - if (ret < 0) { - PRINT_ER("SPI transaction failed\n"); - } - } - - kfree(t_buffer); - } else { - PRINT_ER("can't read data with the following length: %u\n", rlen); - ret = -1; - } - /* change return value to match WILC interface */ - (ret < 0) ? (ret = 0) : (ret = 1); - - return ret; -} - -#else int wilc_spi_read(u8 *rb, u32 rlen) { struct spi_device *spi = to_spi_device(wilc_dev->dev); @@ -313,8 +154,6 @@ int wilc_spi_read(u8 *rb, u32 rlen) return ret; } -#endif - int wilc_spi_write_read(u8 *wb, u8 *rb, u32 rlen) { struct spi_device *spi = to_spi_device(wilc_dev->dev); -- GitLab From 00215dde5e386f548227f2d435908b36e3f90f29 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Wed, 18 Nov 2015 15:11:25 +0900 Subject: [PATCH 1632/2855] staging: wilc1000: pass struct wilc to the functions which use hif_func This patch passes struct wilc to the functions which use hif_func inside. The function pointers of wilc_hif_func will pass wilc also in the later patch. Pass wilc to the functions if necessary. Flollowings are modified functions. chip_wakeup wilc_chip_sleep_manually chip_allow_sleep wilc_get_chipid wilc_unknown_isr_ext wilc_pllupdate_isr_ext wilc_sleeptimer_isr_ext Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 3 +- drivers/staging/wilc1000/linux_wlan.c | 5 +- drivers/staging/wilc1000/wilc_wlan.c | 56 +++++++++++------------ drivers/staging/wilc1000/wilc_wlan.h | 2 +- drivers/staging/wilc1000/wilc_wlan_if.h | 3 +- 5 files changed, 36 insertions(+), 33 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 4acd936fd572a..672092b386dc6 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2834,6 +2834,7 @@ static int hostIFthread(void *pvArg) u32 u32Ret; struct host_if_msg msg; struct host_if_drv *hif_drv; + struct wilc *wilc = (struct wilc*)pvArg; memset(&msg, 0, sizeof(struct host_if_msg)); @@ -2906,7 +2907,7 @@ static int hostIFthread(void *pvArg) PRINT_D(HOSTINF_DBG, "scan completed successfully\n"); if (!wilc_wlan_get_num_conn_ifcs(wilc_dev)) - wilc_chip_sleep_manually(); + wilc_chip_sleep_manually(wilc); Handle_ScanDone(msg.drv, SCAN_EVENT_DONE); diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index ab17110fb17e2..43458e6ca691a 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -514,7 +514,8 @@ static int wilc1000_firmware_download(struct net_device *dev) return 0; } -static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_nic) +static int linux_wlan_init_test_config(struct net_device *dev, + struct wilc *wilc) { unsigned char c_val[64]; unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xff}; @@ -532,7 +533,7 @@ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_ni PRINT_D(INIT_DBG, "MAC address is : %02x-%02x-%02x-%02x-%02x-%02x\n", mac_add[0], mac_add[1], mac_add[2], mac_add[3], mac_add[4], mac_add[5]); - wilc_get_chipid(0); + wilc_get_chipid(wilc, 0); *(int *)c_val = 1; diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 114ea9535f790..e30a34dae2316 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -35,9 +35,9 @@ typedef struct { static wilc_wlan_dev_t g_wlan; #ifdef WILC_OPTIMIZE_SLEEP_INT -static inline void chip_allow_sleep(void); +static inline void chip_allow_sleep(struct wilc *wilc); #endif -static inline void chip_wakeup(void); +static inline void chip_wakeup(struct wilc *wilc); static u32 dbgflag = N_INIT | N_ERR | N_INTR | N_TXQ | N_RXQ; /* FIXME: replace with dev_debug() */ @@ -65,7 +65,7 @@ static inline void acquire_bus(struct wilc *wilc, BUS_ACQUIRE_T acquire) #endif { if (acquire == ACQUIRE_AND_WAKEUP) - chip_wakeup(); + chip_wakeup(wilc); } } @@ -73,7 +73,7 @@ static inline void release_bus(struct wilc *wilc, BUS_RELEASE_T release) { #ifdef WILC_OPTIMIZE_SLEEP_INT if (release == RELEASE_ALLOW_SLEEP) - chip_allow_sleep(); + chip_allow_sleep(wilc); #endif mutex_unlock(&wilc->hif_cs); } @@ -562,7 +562,7 @@ static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc) #ifdef WILC_OPTIMIZE_SLEEP_INT -static inline void chip_allow_sleep(void) +static inline void chip_allow_sleep(struct wilc *wilc) { u32 reg = 0; @@ -571,7 +571,7 @@ static inline void chip_allow_sleep(void) g_wlan.hif_func.hif_write_reg(0xf0, reg & ~BIT(0)); } -static inline void chip_wakeup(void) +static inline void chip_wakeup(struct wilc *wilc) { u32 reg, clk_status_reg, trials = 0; u32 sleep_time; @@ -584,12 +584,12 @@ static inline void chip_wakeup(void) do { usleep_range(2 * 1000, 2 * 1000); - if ((wilc_get_chipid(true) == 0)) + if ((wilc_get_chipid(wilc, true) == 0)) wilc_debug(N_ERR, "Couldn't read chip id. Wake up failed\n"); - } while ((wilc_get_chipid(true) == 0) && ((++trials % 3) == 0)); + } while ((wilc_get_chipid(wilc, true) == 0) && ((++trials % 3) == 0)); - } while (wilc_get_chipid(true) == 0); + } while (wilc_get_chipid(wilc, true) == 0); } else if ((g_wlan.io_type & 0x1) == HIF_SDIO) { g_wlan.hif_func.hif_read_reg(0xf0, ®); do { @@ -616,7 +616,7 @@ static inline void chip_wakeup(void) reg &= ~BIT(0); g_wlan.hif_func.hif_write_reg(0x1C0C, reg); - if (wilc_get_chipid(false) >= 0x1002b0) { + if (wilc_get_chipid(wilc, false) >= 0x1002b0) { u32 val32; g_wlan.hif_func.hif_read_reg(0x1e1c, &val32); @@ -631,7 +631,7 @@ static inline void chip_wakeup(void) chip_ps_state = CHIP_WAKEDUP; } #else -static inline void chip_wakeup(void) +static inline void chip_wakeup(struct wilc *wilc) { u32 reg, trials = 0; @@ -651,19 +651,19 @@ static inline void chip_wakeup(void) do { mdelay(3); - if ((wilc_get_chipid(true) == 0)) + if ((wilc_get_chipid(wilc, true) == 0)) wilc_debug(N_ERR, "Couldn't read chip id. Wake up failed\n"); - } while ((wilc_get_chipid(true) == 0) && ((++trials % 3) == 0)); + } while ((wilc_get_chipid(wilc, true) == 0) && ((++trials % 3) == 0)); - } while (wilc_get_chipid(true) == 0); + } while (wilc_get_chipid(wilc, true) == 0); if (chip_ps_state == CHIP_SLEEPING_MANUAL) { g_wlan.hif_func.hif_read_reg(0x1C0C, ®); reg &= ~BIT(0); g_wlan.hif_func.hif_write_reg(0x1C0C, reg); - if (wilc_get_chipid(false) >= 0x1002b0) { + if (wilc_get_chipid(wilc, false) >= 0x1002b0) { u32 val32; g_wlan.hif_func.hif_read_reg(0x1e1c, &val32); @@ -678,19 +678,19 @@ static inline void chip_wakeup(void) chip_ps_state = CHIP_WAKEDUP; } #endif -void wilc_chip_sleep_manually(void) +void wilc_chip_sleep_manually(struct wilc *wilc) { if (chip_ps_state != CHIP_WAKEDUP) return; - acquire_bus(wilc_dev, ACQUIRE_ONLY); + acquire_bus(wilc, ACQUIRE_ONLY); #ifdef WILC_OPTIMIZE_SLEEP_INT - chip_allow_sleep(); + chip_allow_sleep(wilc); #endif g_wlan.hif_func.hif_write_reg(0x10a8, 1); chip_ps_state = CHIP_SLEEPING_MANUAL; - release_bus(wilc_dev, RELEASE_ONLY); + release_bus(wilc, RELEASE_ONLY); } int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) @@ -1056,12 +1056,12 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) PRINT_D(RX_DBG, "THREAD: Exiting RX thread\n"); } -static void wilc_unknown_isr_ext(void) +static void wilc_unknown_isr_ext(struct wilc *wilc) { g_wlan.hif_func.hif_clear_int_ext(0); } -static void wilc_pllupdate_isr_ext(u32 int_stats) +static void wilc_pllupdate_isr_ext(struct wilc *wilc, u32 int_stats) { int trials = 10; @@ -1072,13 +1072,13 @@ static void wilc_pllupdate_isr_ext(u32 int_stats) else mdelay(WILC_PLL_TO_SPI); - while (!(ISWILC1000(wilc_get_chipid(true)) && --trials)) { + while (!(ISWILC1000(wilc_get_chipid(wilc, true)) && --trials)) { PRINT_D(TX_DBG, "PLL update retrying\n"); mdelay(1); } } -static void wilc_sleeptimer_isr_ext(u32 int_stats1) +static void wilc_sleeptimer_isr_ext(struct wilc *wilc, u32 int_stats1) { g_wlan.hif_func.hif_clear_int_ext(SLEEP_INT_CLR); #ifndef WILC_OPTIMIZE_SLEEP_INT @@ -1165,7 +1165,7 @@ void wilc_handle_isr(struct wilc *wilc) g_wlan.hif_func.hif_read_int(&int_status); if (int_status & PLL_INT_EXT) - wilc_pllupdate_isr_ext(int_status); + wilc_pllupdate_isr_ext(wilc, int_status); if (int_status & DATA_INT_EXT) { wilc_wlan_handle_isr_ext(wilc, int_status); @@ -1174,10 +1174,10 @@ void wilc_handle_isr(struct wilc *wilc) #endif } if (int_status & SLEEP_INT_EXT) - wilc_sleeptimer_isr_ext(int_status); + wilc_sleeptimer_isr_ext(wilc, int_status); if (!(int_status & (ALL_INT_EXT))) { - wilc_unknown_isr_ext(); + wilc_unknown_isr_ext(wilc); } release_bus(wilc, RELEASE_ALLOW_SLEEP); } @@ -1587,7 +1587,7 @@ static u32 init_chip(struct net_device *dev) acquire_bus(wilc, ACQUIRE_ONLY); - chipid = wilc_get_chipid(true); + chipid = wilc_get_chipid(wilc, true); if ((chipid & 0xfff) != 0xa0) { ret = g_wlan.hif_func.hif_read_reg(0x1118, ®); @@ -1613,7 +1613,7 @@ static u32 init_chip(struct net_device *dev) return ret; } -u32 wilc_get_chipid(u8 update) +u32 wilc_get_chipid(struct wilc *wilc, u8 update) { static u32 chipid; u32 tempchipid = 0; diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index ee13771eb54cd..334abafe3b0fe 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -295,7 +295,7 @@ int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drv_handler); int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size); int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func); -void wilc_chip_sleep_manually(void); +void wilc_chip_sleep_manually(struct wilc *wilc); void wilc_enable_tcp_ack_filter(bool value); int wilc_wlan_get_num_conn_ifcs(struct wilc *); diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index 2f465f4fb063c..618903caff542 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -909,9 +909,10 @@ typedef enum { WID_MAX = 0xFFFF } WID_T; +struct wilc; int wilc_wlan_init(struct net_device *dev); void wilc_bus_set_max_speed(void); void wilc_bus_set_default_speed(void); -u32 wilc_get_chipid(u8 update); +u32 wilc_get_chipid(struct wilc *wilc, u8 update); #endif -- GitLab From 49dcd0dd0e70ee7dc8cd6bf1d16a4c25e1bdfc6f Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Wed, 18 Nov 2015 15:11:26 +0900 Subject: [PATCH 1633/2855] staging: wilc1000: pass wilc to all function pointers of wilc_hif_func This patch adds new function parameter struct wilc to all function pointers of struct wilc_hif_func, and all functions of wilc_sdio.c and wilc_spi.c need to be changed as it's function pointer is changed. Pass wilc in all the functions call as well. The wilc will be passed to functions in linux_wlan_sdio.c and linux_wlan_spi.c to replace with global variable wilc_dev in the next patch. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_sdio.c | 84 +++++++------- drivers/staging/wilc1000/wilc_spi.c | 113 ++++++++++-------- drivers/staging/wilc1000/wilc_wlan.c | 167 +++++++++++++++------------ drivers/staging/wilc1000/wilc_wlan.h | 26 ++--- 4 files changed, 208 insertions(+), 182 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index b0454a7e78a51..3f8260477f7c0 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -26,8 +26,8 @@ typedef struct { static wilc_sdio_t g_sdio; -static int sdio_write_reg(u32 addr, u32 data); -static int sdio_read_reg(u32 addr, u32 *data); +static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data); +static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data); /******************************************** * @@ -35,7 +35,7 @@ static int sdio_read_reg(u32 addr, u32 *data); * ********************************************/ -static int sdio_set_func0_csa_address(u32 adr) +static int sdio_set_func0_csa_address(struct wilc *wilc, u32 adr) { sdio_cmd52_t cmd; @@ -71,7 +71,7 @@ _fail_: return 0; } -static int sdio_set_func0_block_size(u32 block_size) +static int sdio_set_func0_block_size(struct wilc *wilc, u32 block_size) { sdio_cmd52_t cmd; @@ -103,7 +103,7 @@ _fail_: * ********************************************/ -static int sdio_set_func1_block_size(u32 block_size) +static int sdio_set_func1_block_size(struct wilc *wilc, u32 block_size) { sdio_cmd52_t cmd; @@ -128,7 +128,7 @@ _fail_: return 0; } -static int sdio_clear_int(void) +static int sdio_clear_int(struct wilc *wilc) { if (!g_sdio.irq_gpio) { /* u32 sts; */ @@ -145,12 +145,12 @@ static int sdio_clear_int(void) } else { u32 reg; - if (!sdio_read_reg(WILC_HOST_RX_CTRL_0, ®)) { + if (!sdio_read_reg(wilc, WILC_HOST_RX_CTRL_0, ®)) { g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0); return 0; } reg &= ~0x1; - sdio_write_reg(WILC_HOST_RX_CTRL_0, reg); + sdio_write_reg(wilc, WILC_HOST_RX_CTRL_0, reg); return 1; } @@ -161,7 +161,7 @@ static int sdio_clear_int(void) * Sdio interfaces * ********************************************/ -static int sdio_write_reg(u32 addr, u32 data) +static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) { #ifdef BIG_ENDIAN data = BYTE_SWAP(data); @@ -185,7 +185,7 @@ static int sdio_write_reg(u32 addr, u32 data) /** * set the AHB address **/ - if (!sdio_set_func0_csa_address(addr)) + if (!sdio_set_func0_csa_address(wilc, addr)) goto _fail_; cmd.read_write = 1; @@ -210,7 +210,7 @@ _fail_: return 0; } -static int sdio_write(u32 addr, u8 *buf, u32 size) +static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { u32 block_size = g_sdio.block_size; sdio_cmd53_t cmd; @@ -257,7 +257,7 @@ static int sdio_write(u32 addr, u8 *buf, u32 size) cmd.buffer = buf; cmd.block_size = block_size; if (addr > 0) { - if (!sdio_set_func0_csa_address(addr)) + if (!sdio_set_func0_csa_address(wilc, addr)) goto _fail_; } if (!wilc_sdio_cmd53(&cmd)) { @@ -278,7 +278,7 @@ static int sdio_write(u32 addr, u8 *buf, u32 size) cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */ if (addr > 0) { - if (!sdio_set_func0_csa_address(addr)) + if (!sdio_set_func0_csa_address(wilc, addr)) goto _fail_; } if (!wilc_sdio_cmd53(&cmd)) { @@ -294,7 +294,7 @@ _fail_: return 0; } -static int sdio_read_reg(u32 addr, u32 *data) +static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) { if ((addr >= 0xf0) && (addr <= 0xff)) { sdio_cmd52_t cmd; @@ -311,7 +311,7 @@ static int sdio_read_reg(u32 addr, u32 *data) } else { sdio_cmd53_t cmd; - if (!sdio_set_func0_csa_address(addr)) + if (!sdio_set_func0_csa_address(wilc, addr)) goto _fail_; cmd.read_write = 0; @@ -341,7 +341,7 @@ _fail_: return 0; } -static int sdio_read(u32 addr, u8 *buf, u32 size) +static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { u32 block_size = g_sdio.block_size; sdio_cmd53_t cmd; @@ -388,7 +388,7 @@ static int sdio_read(u32 addr, u8 *buf, u32 size) cmd.buffer = buf; cmd.block_size = block_size; if (addr > 0) { - if (!sdio_set_func0_csa_address(addr)) + if (!sdio_set_func0_csa_address(wilc, addr)) goto _fail_; } if (!wilc_sdio_cmd53(&cmd)) { @@ -409,7 +409,7 @@ static int sdio_read(u32 addr, u8 *buf, u32 size) cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */ if (addr > 0) { - if (!sdio_set_func0_csa_address(addr)) + if (!sdio_set_func0_csa_address(wilc, addr)) goto _fail_; } if (!wilc_sdio_cmd53(&cmd)) { @@ -431,25 +431,25 @@ _fail_: * ********************************************/ -static int sdio_deinit(void *pv) +static int sdio_deinit(struct wilc *wilc) { return 1; } -static int sdio_sync(void) +static int sdio_sync(struct wilc *wilc) { u32 reg; /** * Disable power sequencer **/ - if (!sdio_read_reg(WILC_MISC, ®)) { + if (!sdio_read_reg(wilc, WILC_MISC, ®)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read misc reg...\n"); return 0; } reg &= ~BIT(8); - if (!sdio_write_reg(WILC_MISC, reg)) { + if (!sdio_write_reg(wilc, WILC_MISC, reg)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write misc reg...\n"); return 0; } @@ -461,13 +461,13 @@ static int sdio_sync(void) /** * interrupt pin mux select **/ - ret = sdio_read_reg(WILC_PIN_MUX_0, ®); + ret = sdio_read_reg(wilc, WILC_PIN_MUX_0, ®); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); return 0; } reg |= BIT(8); - ret = sdio_write_reg(WILC_PIN_MUX_0, reg); + ret = sdio_write_reg(wilc, WILC_PIN_MUX_0, reg); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); return 0; @@ -476,13 +476,13 @@ static int sdio_sync(void) /** * interrupt enable **/ - ret = sdio_read_reg(WILC_INTR_ENABLE, ®); + ret = sdio_read_reg(wilc, WILC_INTR_ENABLE, ®); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); return 0; } reg |= BIT(16); - ret = sdio_write_reg(WILC_INTR_ENABLE, reg); + ret = sdio_write_reg(wilc, WILC_INTR_ENABLE, reg); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); return 0; @@ -526,7 +526,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) /** * function 0 block size **/ - if (!sdio_set_func0_block_size(WILC_SDIO_BLOCK_SIZE)) { + if (!sdio_set_func0_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set func 0 block size...\n"); goto _fail_; } @@ -571,7 +571,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) /** * func 1 is ready, set func 1 block size **/ - if (!sdio_set_func1_block_size(WILC_SDIO_BLOCK_SIZE)) { + if (!sdio_set_func1_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail set func 1 block size...\n"); goto _fail_; } @@ -592,7 +592,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) /** * make sure can read back chip id correctly **/ - if (!sdio_read_reg(0x1000, &chipid)) { + if (!sdio_read_reg(wilc, 0x1000, &chipid)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd read chip id...\n"); goto _fail_; } @@ -610,7 +610,7 @@ _fail_: return 0; } -static int sdio_read_size(u32 *size) +static int sdio_read_size(struct wilc *wilc, u32 *size) { u32 tmp; @@ -639,13 +639,13 @@ static int sdio_read_size(u32 *size) return 1; } -static int sdio_read_int(u32 *int_status) +static int sdio_read_int(struct wilc *wilc, u32 *int_status) { u32 tmp; sdio_cmd52_t cmd; - sdio_read_size(&tmp); + sdio_read_size(wilc, &tmp); /** * Read IRQ flags @@ -694,7 +694,7 @@ static int sdio_read_int(u32 *int_status) return 1; } -static int sdio_clear_int_ext(u32 val) +static int sdio_clear_int_ext(struct wilc *wilc, u32 val) { int ret; @@ -812,7 +812,7 @@ _fail_: return 0; } -static int sdio_sync_ext(int nint /* how mant interrupts to enable. */) +static int sdio_sync_ext(struct wilc *wilc, int nint) { u32 reg; @@ -830,13 +830,13 @@ static int sdio_sync_ext(int nint /* how mant interrupts to enable. */) /** * Disable power sequencer **/ - if (!sdio_read_reg(WILC_MISC, ®)) { + if (!sdio_read_reg(wilc, WILC_MISC, ®)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read misc reg...\n"); return 0; } reg &= ~BIT(8); - if (!sdio_write_reg(WILC_MISC, reg)) { + if (!sdio_write_reg(wilc, WILC_MISC, reg)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write misc reg...\n"); return 0; } @@ -848,13 +848,13 @@ static int sdio_sync_ext(int nint /* how mant interrupts to enable. */) /** * interrupt pin mux select **/ - ret = sdio_read_reg(WILC_PIN_MUX_0, ®); + ret = sdio_read_reg(wilc, WILC_PIN_MUX_0, ®); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); return 0; } reg |= BIT(8); - ret = sdio_write_reg(WILC_PIN_MUX_0, reg); + ret = sdio_write_reg(wilc, WILC_PIN_MUX_0, reg); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); return 0; @@ -863,7 +863,7 @@ static int sdio_sync_ext(int nint /* how mant interrupts to enable. */) /** * interrupt enable **/ - ret = sdio_read_reg(WILC_INTR_ENABLE, ®); + ret = sdio_read_reg(wilc, WILC_INTR_ENABLE, ®); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); return 0; @@ -871,13 +871,13 @@ static int sdio_sync_ext(int nint /* how mant interrupts to enable. */) for (i = 0; (i < 5) && (nint > 0); i++, nint--) reg |= BIT((27 + i)); - ret = sdio_write_reg(WILC_INTR_ENABLE, reg); + ret = sdio_write_reg(wilc, WILC_INTR_ENABLE, reg); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); return 0; } if (nint) { - ret = sdio_read_reg(WILC_INTR2_ENABLE, ®); + ret = sdio_read_reg(wilc, WILC_INTR2_ENABLE, ®); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_INTR2_ENABLE); return 0; @@ -886,7 +886,7 @@ static int sdio_sync_ext(int nint /* how mant interrupts to enable. */) for (i = 0; (i < 3) && (nint > 0); i++, nint--) reg |= BIT(i); - ret = sdio_read_reg(WILC_INTR2_ENABLE, ®); + ret = sdio_read_reg(wilc, WILC_INTR2_ENABLE, ®); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_INTR2_ENABLE); return 0; diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 1c5dcda4b6345..53d098f801568 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -22,8 +22,8 @@ typedef struct { static wilc_spi_t g_spi; -static int _wilc_spi_read(u32, u8 *, u32); -static int _wilc_spi_write(u32, u8 *, u32); +static int _wilc_spi_read(struct wilc *wilc, u32, u8 *, u32); +static int _wilc_spi_write(struct wilc *wilc, u32, u8 *, u32); /******************************************** * @@ -108,7 +108,8 @@ static u8 crc7(u8 crc, const u8 *buffer, u32 len) #define DATA_PKT_SZ_8K (8 * 1024) #define DATA_PKT_SZ DATA_PKT_SZ_8K -static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless) +static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, + u8 clockless) { u8 wb[32], rb[32]; u8 wix, rix; @@ -447,7 +448,7 @@ _error_: return result; } -static int spi_data_write(u8 *b, u32 sz) +static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz) { int ix, nbytes; int result = 1; @@ -524,14 +525,15 @@ static int spi_data_write(u8 *b, u32 sz) * ********************************************/ -static int spi_internal_write(u32 adr, u32 dat) +static int spi_internal_write(struct wilc *wilc, u32 adr, u32 dat) { int result; #ifdef BIG_ENDIAN dat = BYTE_SWAP(dat); #endif - result = spi_cmd_complete(CMD_INTERNAL_WRITE, adr, (u8 *)&dat, 4, 0); + result = spi_cmd_complete(wilc, CMD_INTERNAL_WRITE, adr, (u8 *)&dat, 4, + 0); if (result != N_OK) { PRINT_ER("[wilc spi]: Failed internal write cmd...\n"); } @@ -539,11 +541,12 @@ static int spi_internal_write(u32 adr, u32 dat) return result; } -static int spi_internal_read(u32 adr, u32 *data) +static int spi_internal_read(struct wilc *wilc, u32 adr, u32 *data) { int result; - result = spi_cmd_complete(CMD_INTERNAL_READ, adr, (u8 *)data, 4, 0); + result = spi_cmd_complete(wilc, CMD_INTERNAL_READ, adr, (u8 *)data, 4, + 0); if (result != N_OK) { PRINT_ER("[wilc spi]: Failed internal read cmd...\n"); return 0; @@ -562,7 +565,7 @@ static int spi_internal_read(u32 adr, u32 *data) * ********************************************/ -static int wilc_spi_write_reg(u32 addr, u32 data) +static int wilc_spi_write_reg(struct wilc *wilc, u32 addr, u32 data) { int result = N_OK; u8 cmd = CMD_SINGLE_WRITE; @@ -577,7 +580,7 @@ static int wilc_spi_write_reg(u32 addr, u32 data) clockless = 1; } - result = spi_cmd_complete(cmd, addr, (u8 *)&data, 4, clockless); + result = spi_cmd_complete(wilc, cmd, addr, (u8 *)&data, 4, clockless); if (result != N_OK) { PRINT_ER("[wilc spi]: Failed cmd, write reg (%08x)...\n", addr); } @@ -585,7 +588,7 @@ static int wilc_spi_write_reg(u32 addr, u32 data) return result; } -static int _wilc_spi_write(u32 addr, u8 *buf, u32 size) +static int _wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { int result; u8 cmd = CMD_DMA_EXT_WRITE; @@ -596,7 +599,7 @@ static int _wilc_spi_write(u32 addr, u8 *buf, u32 size) if (size <= 4) return 0; - result = spi_cmd_complete(cmd, addr, NULL, size, 0); + result = spi_cmd_complete(wilc, cmd, addr, NULL, size, 0); if (result != N_OK) { PRINT_ER("[wilc spi]: Failed cmd, write block (%08x)...\n", addr); return 0; @@ -605,7 +608,7 @@ static int _wilc_spi_write(u32 addr, u8 *buf, u32 size) /** * Data **/ - result = spi_data_write(buf, size); + result = spi_data_write(wilc, buf, size); if (result != N_OK) { PRINT_ER("[wilc spi]: Failed block data write...\n"); } @@ -613,7 +616,7 @@ static int _wilc_spi_write(u32 addr, u8 *buf, u32 size) return 1; } -static int wilc_spi_read_reg(u32 addr, u32 *data) +static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data) { int result = N_OK; u8 cmd = CMD_SINGLE_READ; @@ -626,7 +629,7 @@ static int wilc_spi_read_reg(u32 addr, u32 *data) clockless = 1; } - result = spi_cmd_complete(cmd, addr, (u8 *)data, 4, clockless); + result = spi_cmd_complete(wilc, cmd, addr, (u8 *)data, 4, clockless); if (result != N_OK) { PRINT_ER("[wilc spi]: Failed cmd, read reg (%08x)...\n", addr); return 0; @@ -639,7 +642,7 @@ static int wilc_spi_read_reg(u32 addr, u32 *data) return 1; } -static int _wilc_spi_read(u32 addr, u8 *buf, u32 size) +static int _wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { u8 cmd = CMD_DMA_EXT_READ; int result; @@ -647,7 +650,7 @@ static int _wilc_spi_read(u32 addr, u8 *buf, u32 size) if (size <= 4) return 0; - result = spi_cmd_complete(cmd, addr, buf, size, 0); + result = spi_cmd_complete(wilc, cmd, addr, buf, size, 0); if (result != N_OK) { PRINT_ER("[wilc spi]: Failed cmd, read block (%08x)...\n", addr); return 0; @@ -662,20 +665,20 @@ static int _wilc_spi_read(u32 addr, u8 *buf, u32 size) * ********************************************/ -static int wilc_spi_clear_int(void) +static int wilc_spi_clear_int(struct wilc *wilc) { u32 reg; - if (!wilc_spi_read_reg(WILC_HOST_RX_CTRL_0, ®)) { + if (!wilc_spi_read_reg(wilc, WILC_HOST_RX_CTRL_0, ®)) { PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0); return 0; } reg &= ~0x1; - wilc_spi_write_reg(WILC_HOST_RX_CTRL_0, reg); + wilc_spi_write_reg(wilc, WILC_HOST_RX_CTRL_0, reg); return 1; } -static int _wilc_spi_deinit(void *pv) +static int _wilc_spi_deinit(struct wilc *wilc) { /** * TODO: @@ -683,7 +686,7 @@ static int _wilc_spi_deinit(void *pv) return 1; } -static int wilc_spi_sync(void) +static int wilc_spi_sync(struct wilc *wilc) { u32 reg; int ret; @@ -691,13 +694,13 @@ static int wilc_spi_sync(void) /** * interrupt pin mux select **/ - ret = wilc_spi_read_reg(WILC_PIN_MUX_0, ®); + ret = wilc_spi_read_reg(wilc, WILC_PIN_MUX_0, ®); if (!ret) { PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); return 0; } reg |= BIT(8); - ret = wilc_spi_write_reg(WILC_PIN_MUX_0, reg); + ret = wilc_spi_write_reg(wilc, WILC_PIN_MUX_0, reg); if (!ret) { PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); return 0; @@ -706,13 +709,13 @@ static int wilc_spi_sync(void) /** * interrupt enable **/ - ret = wilc_spi_read_reg(WILC_INTR_ENABLE, ®); + ret = wilc_spi_read_reg(wilc, WILC_INTR_ENABLE, ®); if (!ret) { PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); return 0; } reg |= BIT(16); - ret = wilc_spi_write_reg(WILC_INTR_ENABLE, reg); + ret = wilc_spi_write_reg(wilc, WILC_INTR_ENABLE, reg); if (!ret) { PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); return 0; @@ -730,7 +733,7 @@ static int _wilc_spi_init(struct wilc *wilc, wilc_debug_func func) if (isinit) { - if (!wilc_spi_read_reg(0x1000, &chipid)) { + if (!wilc_spi_read_reg(wilc, 0x1000, &chipid)) { PRINT_ER("[wilc spi]: Fail cmd read chip id...\n"); return 0; } @@ -754,12 +757,12 @@ static int _wilc_spi_init(struct wilc *wilc, wilc_debug_func func) /* TODO: We can remove the CRC trials if there is a definite way to reset */ /* the SPI to it's initial value. */ - if (!spi_internal_read(WILC_SPI_PROTOCOL_OFFSET, ®)) { + if (!spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, ®)) { /* Read failed. Try with CRC off. This might happen when module * is removed but chip isn't reset*/ g_spi.crc_off = 1; PRINT_ER("[wilc spi]: Failed internal read protocol with CRC on, retyring with CRC off...\n"); - if (!spi_internal_read(WILC_SPI_PROTOCOL_OFFSET, ®)) { + if (!spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, ®)) { /* Reaad failed with both CRC on and off, something went bad */ PRINT_ER("[wilc spi]: Failed internal read protocol...\n"); return 0; @@ -769,7 +772,7 @@ static int _wilc_spi_init(struct wilc *wilc, wilc_debug_func func) reg &= ~0xc; /* disable crc checking */ reg &= ~0x70; reg |= (0x5 << 4); - if (!spi_internal_write(WILC_SPI_PROTOCOL_OFFSET, reg)) { + if (!spi_internal_write(wilc, WILC_SPI_PROTOCOL_OFFSET, reg)) { PRINT_ER("[wilc spi %d]: Failed internal write protocol reg...\n", __LINE__); return 0; } @@ -780,7 +783,7 @@ static int _wilc_spi_init(struct wilc *wilc, wilc_debug_func func) /** * make sure can read back chip id correctly **/ - if (!wilc_spi_read_reg(0x1000, &chipid)) { + if (!wilc_spi_read_reg(wilc, 0x1000, &chipid)) { PRINT_ER("[wilc spi]: Fail cmd read chip id...\n"); return 0; } @@ -793,18 +796,20 @@ static int _wilc_spi_init(struct wilc *wilc, wilc_debug_func func) return 1; } -static int wilc_spi_read_size(u32 *size) +static int wilc_spi_read_size(struct wilc *wilc, u32 *size) { int ret; if (g_spi.has_thrpt_enh) { - ret = spi_internal_read(0xe840 - WILC_SPI_REG_BASE, size); + ret = spi_internal_read(wilc, 0xe840 - WILC_SPI_REG_BASE, + size); *size = *size & IRQ_DMA_WD_CNT_MASK; } else { u32 tmp; u32 byte_cnt; - ret = wilc_spi_read_reg(WILC_VMM_TO_HOST_SIZE, &byte_cnt); + ret = wilc_spi_read_reg(wilc, WILC_VMM_TO_HOST_SIZE, + &byte_cnt); if (!ret) { PRINT_ER("[wilc spi]: Failed read WILC_VMM_TO_HOST_SIZE ...\n"); goto _fail_; @@ -821,17 +826,19 @@ _fail_: -static int wilc_spi_read_int(u32 *int_status) +static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status) { int ret; if (g_spi.has_thrpt_enh) { - ret = spi_internal_read(0xe840 - WILC_SPI_REG_BASE, int_status); + ret = spi_internal_read(wilc, 0xe840 - WILC_SPI_REG_BASE, + int_status); } else { u32 tmp; u32 byte_cnt; - ret = wilc_spi_read_reg(WILC_VMM_TO_HOST_SIZE, &byte_cnt); + ret = wilc_spi_read_reg(wilc, WILC_VMM_TO_HOST_SIZE, + &byte_cnt); if (!ret) { PRINT_ER("[wilc spi]: Failed read WILC_VMM_TO_HOST_SIZE ...\n"); goto _fail_; @@ -847,11 +854,12 @@ static int wilc_spi_read_int(u32 *int_status) happended = 0; - wilc_spi_read_reg(0x1a90, &irq_flags); + wilc_spi_read_reg(wilc, 0x1a90, &irq_flags); tmp |= ((irq_flags >> 27) << IRG_FLAGS_OFFSET); if (g_spi.nint > 5) { - wilc_spi_read_reg(0x1a94, &irq_flags); + wilc_spi_read_reg(wilc, 0x1a94, + &irq_flags); tmp |= (((irq_flags >> 0) & 0x7) << (IRG_FLAGS_OFFSET + 5)); } @@ -877,12 +885,13 @@ _fail_: return ret; } -static int wilc_spi_clear_int_ext(u32 val) +static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val) { int ret; if (g_spi.has_thrpt_enh) { - ret = spi_internal_write(0xe844 - WILC_SPI_REG_BASE, val); + ret = spi_internal_write(wilc, 0xe844 - WILC_SPI_REG_BASE, + val); } else { u32 flags; @@ -894,7 +903,7 @@ static int wilc_spi_clear_int_ext(u32 val) for (i = 0; i < g_spi.nint; i++) { /* No matter what you write 1 or 0, it will clear interrupt. */ if (flags & 1) - ret = wilc_spi_write_reg(0x10c8 + i * 4, 1); + ret = wilc_spi_write_reg(wilc, 0x10c8 + i * 4, 1); if (!ret) break; flags >>= 1; @@ -921,7 +930,8 @@ static int wilc_spi_clear_int_ext(u32 val) if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1) tbl_ctl |= BIT(1); - ret = wilc_spi_write_reg(WILC_VMM_TBL_CTL, tbl_ctl); + ret = wilc_spi_write_reg(wilc, WILC_VMM_TBL_CTL, + tbl_ctl); if (!ret) { PRINT_ER("[wilc spi]: fail write reg vmm_tbl_ctl...\n"); goto _fail_; @@ -931,7 +941,8 @@ static int wilc_spi_clear_int_ext(u32 val) /** * enable vmm transfer. **/ - ret = wilc_spi_write_reg(WILC_VMM_CORE_CTL, 1); + ret = wilc_spi_write_reg(wilc, + WILC_VMM_CORE_CTL, 1); if (!ret) { PRINT_ER("[wilc spi]: fail write reg vmm_core_ctl...\n"); goto _fail_; @@ -943,7 +954,7 @@ _fail_: return ret; } -static int wilc_spi_sync_ext(int nint /* how mant interrupts to enable. */) +static int wilc_spi_sync_ext(struct wilc *wilc, int nint) { u32 reg; int ret, i; @@ -958,13 +969,13 @@ static int wilc_spi_sync_ext(int nint /* how mant interrupts to enable. */) /** * interrupt pin mux select **/ - ret = wilc_spi_read_reg(WILC_PIN_MUX_0, ®); + ret = wilc_spi_read_reg(wilc, WILC_PIN_MUX_0, ®); if (!ret) { PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); return 0; } reg |= BIT(8); - ret = wilc_spi_write_reg(WILC_PIN_MUX_0, reg); + ret = wilc_spi_write_reg(wilc, WILC_PIN_MUX_0, reg); if (!ret) { PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); return 0; @@ -973,7 +984,7 @@ static int wilc_spi_sync_ext(int nint /* how mant interrupts to enable. */) /** * interrupt enable **/ - ret = wilc_spi_read_reg(WILC_INTR_ENABLE, ®); + ret = wilc_spi_read_reg(wilc, WILC_INTR_ENABLE, ®); if (!ret) { PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); return 0; @@ -982,13 +993,13 @@ static int wilc_spi_sync_ext(int nint /* how mant interrupts to enable. */) for (i = 0; (i < 5) && (nint > 0); i++, nint--) { reg |= (BIT((27 + i))); } - ret = wilc_spi_write_reg(WILC_INTR_ENABLE, reg); + ret = wilc_spi_write_reg(wilc, WILC_INTR_ENABLE, reg); if (!ret) { PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); return 0; } if (nint) { - ret = wilc_spi_read_reg(WILC_INTR2_ENABLE, ®); + ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, ®); if (!ret) { PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR2_ENABLE); return 0; @@ -998,7 +1009,7 @@ static int wilc_spi_sync_ext(int nint /* how mant interrupts to enable. */) reg |= BIT(i); } - ret = wilc_spi_read_reg(WILC_INTR2_ENABLE, ®); + ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, ®); if (!ret) { PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR2_ENABLE); return 0; diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index e30a34dae2316..9ac6ad7df6055 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -566,9 +566,9 @@ static inline void chip_allow_sleep(struct wilc *wilc) { u32 reg = 0; - g_wlan.hif_func.hif_read_reg(0xf0, ®); + g_wlan.hif_func.hif_read_reg(wilc, 0xf0, ®); - g_wlan.hif_func.hif_write_reg(0xf0, reg & ~BIT(0)); + g_wlan.hif_func.hif_write_reg(wilc, 0xf0, reg & ~BIT(0)); } static inline void chip_wakeup(struct wilc *wilc) @@ -578,9 +578,9 @@ static inline void chip_wakeup(struct wilc *wilc) if ((g_wlan.io_type & 0x1) == HIF_SPI) { do { - g_wlan.hif_func.hif_read_reg(1, ®); - g_wlan.hif_func.hif_write_reg(1, reg | BIT(1)); - g_wlan.hif_func.hif_write_reg(1, reg & ~BIT(1)); + g_wlan.hif_func.hif_read_reg(wilc, 1, ®); + g_wlan.hif_func.hif_write_reg(wilc, 1, reg | BIT(1)); + g_wlan.hif_func.hif_write_reg(wilc, 1, reg & ~BIT(1)); do { usleep_range(2 * 1000, 2 * 1000); @@ -591,41 +591,44 @@ static inline void chip_wakeup(struct wilc *wilc) } while (wilc_get_chipid(wilc, true) == 0); } else if ((g_wlan.io_type & 0x1) == HIF_SDIO) { - g_wlan.hif_func.hif_read_reg(0xf0, ®); + g_wlan.hif_func.hif_read_reg(wilc, 0xf0, ®); do { - g_wlan.hif_func.hif_write_reg(0xf0, reg | BIT(0)); - g_wlan.hif_func.hif_read_reg(0xf1, &clk_status_reg); + g_wlan.hif_func.hif_write_reg(wilc, 0xf0, + reg | BIT(0)); + g_wlan.hif_func.hif_read_reg(wilc, 0xf1, + &clk_status_reg); while (((clk_status_reg & 0x1) == 0) && (((++trials) % 3) == 0)) { usleep_range(2 * 1000, 2 * 1000); - g_wlan.hif_func.hif_read_reg(0xf1, &clk_status_reg); + g_wlan.hif_func.hif_read_reg(wilc, 0xf1, + &clk_status_reg); if ((clk_status_reg & 0x1) == 0) wilc_debug(N_ERR, "clocks still OFF. Wake up failed\n"); } if ((clk_status_reg & 0x1) == 0) { - g_wlan.hif_func.hif_write_reg(0xf0, reg & - (~BIT(0))); + g_wlan.hif_func.hif_write_reg(wilc, 0xf0, + reg & (~BIT(0))); } } while ((clk_status_reg & 0x1) == 0); } if (chip_ps_state == CHIP_SLEEPING_MANUAL) { - g_wlan.hif_func.hif_read_reg(0x1C0C, ®); + g_wlan.hif_func.hif_read_reg(wilc, 0x1C0C, ®); reg &= ~BIT(0); - g_wlan.hif_func.hif_write_reg(0x1C0C, reg); + g_wlan.hif_func.hif_write_reg(wilc, 0x1C0C, reg); if (wilc_get_chipid(wilc, false) >= 0x1002b0) { u32 val32; - g_wlan.hif_func.hif_read_reg(0x1e1c, &val32); + g_wlan.hif_func.hif_read_reg(wilc, 0x1e1c, &val32); val32 |= BIT(6); - g_wlan.hif_func.hif_write_reg(0x1e1c, val32); + g_wlan.hif_func.hif_write_reg(wilc, 0x1e1c, val32); - g_wlan.hif_func.hif_read_reg(0x1e9c, &val32); + g_wlan.hif_func.hif_read_reg(wilc, 0x1e9c, &val32); val32 |= BIT(6); - g_wlan.hif_func.hif_write_reg(0x1e9c, val32); + g_wlan.hif_func.hif_write_reg(wilc, 0x1e9c, val32); } } chip_ps_state = CHIP_WAKEDUP; @@ -637,15 +640,18 @@ static inline void chip_wakeup(struct wilc *wilc) do { if ((g_wlan.io_type & 0x1) == HIF_SPI) { - g_wlan.hif_func.hif_read_reg(1, ®); - g_wlan.hif_func.hif_write_reg(1, reg & ~BIT(1)); - g_wlan.hif_func.hif_write_reg(1, reg | BIT(1)); - g_wlan.hif_func.hif_write_reg(1, reg & ~BIT(1)); + g_wlan.hif_func.hif_read_reg(wilc, 1, ®); + g_wlan.hif_func.hif_write_reg(wilc, 1, reg & ~BIT(1)); + g_wlan.hif_func.hif_write_reg(wilc, 1, reg | BIT(1)); + g_wlan.hif_func.hif_write_reg(wilc, 1, reg & ~BIT(1)); } else if ((g_wlan.io_type & 0x1) == HIF_SDIO) { - g_wlan.hif_func.hif_read_reg(0xf0, ®); - g_wlan.hif_func.hif_write_reg(0xf0, reg & ~BIT(0)); - g_wlan.hif_func.hif_write_reg(0xf0, reg | BIT(0)); - g_wlan.hif_func.hif_write_reg(0xf0, reg & ~BIT(0)); + g_wlan.hif_func.hif_read_reg(wilc, 0xf0, ®); + g_wlan.hif_func.hif_write_reg(wilc, 0xf0, + reg & ~BIT(0)); + g_wlan.hif_func.hif_write_reg(wilc, 0xf0, + reg | BIT(0)); + g_wlan.hif_func.hif_write_reg(wilc, 0xf0, + reg & ~BIT(0)); } do { @@ -659,20 +665,20 @@ static inline void chip_wakeup(struct wilc *wilc) } while (wilc_get_chipid(wilc, true) == 0); if (chip_ps_state == CHIP_SLEEPING_MANUAL) { - g_wlan.hif_func.hif_read_reg(0x1C0C, ®); + g_wlan.hif_func.hif_read_reg(wilc, 0x1C0C, ®); reg &= ~BIT(0); - g_wlan.hif_func.hif_write_reg(0x1C0C, reg); + g_wlan.hif_func.hif_write_reg(wilc, 0x1C0C, reg); if (wilc_get_chipid(wilc, false) >= 0x1002b0) { u32 val32; - g_wlan.hif_func.hif_read_reg(0x1e1c, &val32); + g_wlan.hif_func.hif_read_reg(wilc, 0x1e1c, &val32); val32 |= BIT(6); - g_wlan.hif_func.hif_write_reg(0x1e1c, val32); + g_wlan.hif_func.hif_write_reg(wilc, 0x1e1c, val32); - g_wlan.hif_func.hif_read_reg(0x1e9c, &val32); + g_wlan.hif_func.hif_read_reg(wilc, 0x1e9c, &val32); val32 |= BIT(6); - g_wlan.hif_func.hif_write_reg(0x1e9c, val32); + g_wlan.hif_func.hif_write_reg(wilc, 0x1e9c, val32); } } chip_ps_state = CHIP_WAKEDUP; @@ -687,7 +693,7 @@ void wilc_chip_sleep_manually(struct wilc *wilc) #ifdef WILC_OPTIMIZE_SLEEP_INT chip_allow_sleep(wilc); #endif - g_wlan.hif_func.hif_write_reg(0x10a8, 1); + g_wlan.hif_func.hif_write_reg(wilc, 0x10a8, 1); chip_ps_state = CHIP_SLEEPING_MANUAL; release_bus(wilc, RELEASE_ONLY); @@ -778,7 +784,8 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) acquire_bus(wilc, ACQUIRE_AND_WAKEUP); counter = 0; do { - ret = p->hif_func.hif_read_reg(WILC_HOST_TX_CTRL, ®); + ret = p->hif_func.hif_read_reg(wilc, WILC_HOST_TX_CTRL, + ®); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't read reg vmm_tbl_entry..\n"); break; @@ -792,7 +799,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) if (counter > 200) { counter = 0; PRINT_D(TX_DBG, "Looping in tx ctrl , forcce quit\n"); - ret = p->hif_func.hif_write_reg(WILC_HOST_TX_CTRL, 0); + ret = p->hif_func.hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0); break; } PRINT_WRN(GENERIC_DBG, "[wilc txq]: warn, vmm table not clear yet, wait...\n"); @@ -807,20 +814,21 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) timeout = 200; do { - ret = p->hif_func.hif_block_tx(WILC_VMM_TBL_RX_SHADOW_BASE, (u8 *)vmm_table, ((i + 1) * 4)); + ret = p->hif_func.hif_block_tx(wilc, WILC_VMM_TBL_RX_SHADOW_BASE, (u8 *)vmm_table, ((i + 1) * 4)); if (!ret) { wilc_debug(N_ERR, "ERR block TX of VMM table.\n"); break; } - ret = p->hif_func.hif_write_reg(WILC_HOST_VMM_CTL, 0x2); + ret = p->hif_func.hif_write_reg(wilc, WILC_HOST_VMM_CTL, + 0x2); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't write reg host_vmm_ctl..\n"); break; } do { - ret = p->hif_func.hif_read_reg(WILC_HOST_VMM_CTL, ®); + ret = p->hif_func.hif_read_reg(wilc, WILC_HOST_VMM_CTL, ®); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't read reg host_vmm_ctl..\n"); break; @@ -836,7 +844,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) } } while (--timeout); if (timeout <= 0) { - ret = p->hif_func.hif_write_reg(WILC_HOST_VMM_CTL, 0x0); + ret = p->hif_func.hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0); break; } @@ -846,13 +854,13 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) if (entries == 0) { PRINT_WRN(GENERIC_DBG, "[wilc txq]: no more buffer in the chip (reg: %08x), retry later [[ %d, %x ]]\n", reg, i, vmm_table[i - 1]); - ret = p->hif_func.hif_read_reg(WILC_HOST_TX_CTRL, ®); + ret = p->hif_func.hif_read_reg(wilc, WILC_HOST_TX_CTRL, ®); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't read reg WILC_HOST_TX_CTRL..\n"); break; } reg &= ~BIT(0); - ret = p->hif_func.hif_write_reg(WILC_HOST_TX_CTRL, reg); + ret = p->hif_func.hif_write_reg(wilc, WILC_HOST_TX_CTRL, reg); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't write reg WILC_HOST_TX_CTRL..\n"); break; @@ -928,13 +936,13 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) acquire_bus(wilc, ACQUIRE_AND_WAKEUP); - ret = p->hif_func.hif_clear_int_ext(ENABLE_TX_VMM); + ret = p->hif_func.hif_clear_int_ext(wilc, ENABLE_TX_VMM); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't start tx VMM ...\n"); goto _end_; } - ret = p->hif_func.hif_block_tx_ext(0, txb, offset); + ret = p->hif_func.hif_block_tx_ext(wilc, 0, txb, offset); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't block tx ext...\n"); goto _end_; @@ -1058,14 +1066,14 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) static void wilc_unknown_isr_ext(struct wilc *wilc) { - g_wlan.hif_func.hif_clear_int_ext(0); + g_wlan.hif_func.hif_clear_int_ext(wilc, 0); } static void wilc_pllupdate_isr_ext(struct wilc *wilc, u32 int_stats) { int trials = 10; - g_wlan.hif_func.hif_clear_int_ext(PLL_INT_CLR); + g_wlan.hif_func.hif_clear_int_ext(wilc, PLL_INT_CLR); if (g_wlan.io_type == HIF_SDIO) mdelay(WILC_PLL_TO_SDIO); @@ -1080,7 +1088,7 @@ static void wilc_pllupdate_isr_ext(struct wilc *wilc, u32 int_stats) static void wilc_sleeptimer_isr_ext(struct wilc *wilc, u32 int_stats1) { - g_wlan.hif_func.hif_clear_int_ext(SLEEP_INT_CLR); + g_wlan.hif_func.hif_clear_int_ext(wilc, SLEEP_INT_CLR); #ifndef WILC_OPTIMIZE_SLEEP_INT chip_ps_state = CHIP_SLEEPING_AUTO; #endif @@ -1104,7 +1112,7 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) u32 time = 0; wilc_debug(N_ERR, "RX Size equal zero ... Trying to read it again for %d time\n", time++); - p->hif_func.hif_read_size(&size); + p->hif_func.hif_read_size(wilc, &size); size = ((size & 0x7fff) << 2); retries++; } @@ -1128,8 +1136,9 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) goto _end_; } #endif - p->hif_func.hif_clear_int_ext(DATA_INT_CLR | ENABLE_RX_VMM); - ret = p->hif_func.hif_block_rx_ext(0, buffer, size); + p->hif_func.hif_clear_int_ext(wilc, + DATA_INT_CLR | ENABLE_RX_VMM); + ret = p->hif_func.hif_block_rx_ext(wilc, 0, buffer, size); if (!ret) { wilc_debug(N_ERR, "[wilc isr]: fail block rx...\n"); @@ -1162,7 +1171,7 @@ void wilc_handle_isr(struct wilc *wilc) u32 int_status; acquire_bus(wilc, ACQUIRE_AND_WAKEUP); - g_wlan.hif_func.hif_read_int(&int_status); + g_wlan.hif_func.hif_read_int(wilc, &int_status); if (int_status & PLL_INT_EXT) wilc_pllupdate_isr_ext(wilc, int_status); @@ -1219,7 +1228,8 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, u32 buffer_ size2 = blksz; memcpy(dma_buffer, &buffer[offset], size2); - ret = p->hif_func.hif_block_tx(addr, dma_buffer, size2); + ret = p->hif_func.hif_block_tx(wilc, addr, dma_buffer, + size2); if (!ret) break; @@ -1260,7 +1270,7 @@ int wilc_wlan_start(struct wilc *wilc) reg = 1; } acquire_bus(wilc, ACQUIRE_ONLY); - ret = p->hif_func.hif_write_reg(WILC_VMM_CORE_CFG, reg); + ret = p->hif_func.hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail write reg vmm_core_cfg...\n"); release_bus(wilc, RELEASE_ONLY); @@ -1294,7 +1304,7 @@ int wilc_wlan_start(struct wilc *wilc) reg |= WILC_HAVE_DISABLE_WILC_UART; #endif - ret = p->hif_func.hif_write_reg(WILC_GP_REG_1, reg); + ret = p->hif_func.hif_write_reg(wilc, WILC_GP_REG_1, reg); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail write WILC_GP_REG_1 ...\n"); release_bus(wilc, RELEASE_ONLY); @@ -1302,9 +1312,9 @@ int wilc_wlan_start(struct wilc *wilc) return ret; } - p->hif_func.hif_sync_ext(NUM_INT_EXT); + p->hif_func.hif_sync_ext(wilc, NUM_INT_EXT); - ret = p->hif_func.hif_read_reg(0x1000, &chipid); + ret = p->hif_func.hif_read_reg(wilc, 0x1000, &chipid); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail read reg 0x1000 ...\n"); release_bus(wilc, RELEASE_ONLY); @@ -1312,16 +1322,16 @@ int wilc_wlan_start(struct wilc *wilc) return ret; } - p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); + p->hif_func.hif_read_reg(wilc, WILC_GLB_RESET_0, ®); if ((reg & BIT(10)) == BIT(10)) { reg &= ~BIT(10); - p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg); - p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); + p->hif_func.hif_write_reg(wilc, WILC_GLB_RESET_0, reg); + p->hif_func.hif_read_reg(wilc, WILC_GLB_RESET_0, ®); } reg |= BIT(10); - ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg); - p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); + ret = p->hif_func.hif_write_reg(wilc, WILC_GLB_RESET_0, reg); + p->hif_func.hif_read_reg(wilc, WILC_GLB_RESET_0, ®); release_bus(wilc, RELEASE_ONLY); return (ret < 0) ? ret : 0; @@ -1333,7 +1343,7 @@ void wilc_wlan_global_reset(struct wilc *wilc) wilc_wlan_dev_t *p = &g_wlan; acquire_bus(wilc, ACQUIRE_AND_WAKEUP); - p->hif_func.hif_write_reg(WILC_GLB_RESET_0, 0x0); + p->hif_func.hif_write_reg(wilc, WILC_GLB_RESET_0, 0x0); release_bus(wilc, RELEASE_ONLY); } int wilc_wlan_stop(struct wilc *wilc) @@ -1344,7 +1354,7 @@ int wilc_wlan_stop(struct wilc *wilc) u8 timeout = 10; acquire_bus(wilc, ACQUIRE_AND_WAKEUP); - ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); + ret = p->hif_func.hif_read_reg(wilc, WILC_GLB_RESET_0, ®); if (!ret) { PRINT_ER("Error while reading reg\n"); release_bus(wilc, RELEASE_ALLOW_SLEEP); @@ -1352,7 +1362,7 @@ int wilc_wlan_stop(struct wilc *wilc) } reg &= ~BIT(10); - ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg); + ret = p->hif_func.hif_write_reg(wilc, WILC_GLB_RESET_0, reg); if (!ret) { PRINT_ER("Error while writing reg\n"); release_bus(wilc, RELEASE_ALLOW_SLEEP); @@ -1360,7 +1370,7 @@ int wilc_wlan_stop(struct wilc *wilc) } do { - ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); + ret = p->hif_func.hif_read_reg(wilc, WILC_GLB_RESET_0, ®); if (!ret) { PRINT_ER("Error while reading reg\n"); release_bus(wilc, RELEASE_ALLOW_SLEEP); @@ -1373,12 +1383,14 @@ int wilc_wlan_stop(struct wilc *wilc) PRINT_D(GENERIC_DBG, "Bit 10 not reset : Retry %d\n", timeout); reg &= ~BIT(10); - ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg); + ret = p->hif_func.hif_write_reg(wilc, WILC_GLB_RESET_0, + reg); timeout--; } else { PRINT_D(GENERIC_DBG, "Bit 10 reset after : Retry %d\n", timeout); - ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); + ret = p->hif_func.hif_read_reg(wilc, WILC_GLB_RESET_0, + ®); if (!ret) { PRINT_ER("Error while reading reg\n"); release_bus(wilc, RELEASE_ALLOW_SLEEP); @@ -1393,10 +1405,10 @@ int wilc_wlan_stop(struct wilc *wilc) reg = (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(8) | BIT(9) | BIT(26) | BIT(29) | BIT(30) | BIT(31)); - p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg); + p->hif_func.hif_write_reg(wilc, WILC_GLB_RESET_0, reg); reg = (u32)~BIT(10); - ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg); + ret = p->hif_func.hif_write_reg(wilc, WILC_GLB_RESET_0, reg); release_bus(wilc, RELEASE_ALLOW_SLEEP); @@ -1444,13 +1456,14 @@ void wilc_wlan_cleanup(struct net_device *dev) acquire_bus(wilc, ACQUIRE_AND_WAKEUP); - ret = p->hif_func.hif_read_reg(WILC_GP_REG_0, ®); + ret = p->hif_func.hif_read_reg(wilc, WILC_GP_REG_0, ®); if (!ret) { PRINT_ER("Error while reading reg\n"); release_bus(wilc, RELEASE_ALLOW_SLEEP); } PRINT_ER("Writing ABORT reg\n"); - ret = p->hif_func.hif_write_reg(WILC_GP_REG_0, (reg | ABORT_INT)); + ret = p->hif_func.hif_write_reg(wilc, WILC_GP_REG_0, + (reg | ABORT_INT)); if (!ret) { PRINT_ER("Error while writing reg\n"); release_bus(wilc, RELEASE_ALLOW_SLEEP); @@ -1590,18 +1603,18 @@ static u32 init_chip(struct net_device *dev) chipid = wilc_get_chipid(wilc, true); if ((chipid & 0xfff) != 0xa0) { - ret = g_wlan.hif_func.hif_read_reg(0x1118, ®); + ret = g_wlan.hif_func.hif_read_reg(wilc, 0x1118, ®); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail read reg 0x1118 ...\n"); return ret; } reg |= BIT(0); - ret = g_wlan.hif_func.hif_write_reg(0x1118, reg); + ret = g_wlan.hif_func.hif_write_reg(wilc, 0x1118, reg); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail write reg 0x1118 ...\n"); return ret; } - ret = g_wlan.hif_func.hif_write_reg(0xc0000, 0x71); + ret = g_wlan.hif_func.hif_write_reg(wilc, 0xc0000, 0x71); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail write reg 0xc0000 ...\n"); return ret; @@ -1620,8 +1633,8 @@ u32 wilc_get_chipid(struct wilc *wilc, u8 update) u32 rfrevid; if (chipid == 0 || update != 0) { - g_wlan.hif_func.hif_read_reg(0x1000, &tempchipid); - g_wlan.hif_func.hif_read_reg(0x13f4, &rfrevid); + g_wlan.hif_func.hif_read_reg(wilc, 0x1000, &tempchipid); + g_wlan.hif_func.hif_read_reg(wilc, 0x13f4, &rfrevid); if (!ISWILC1000(tempchipid)) { chipid = 0; goto _fail_; @@ -1723,7 +1736,8 @@ u16 wilc_set_machw_change_vir_if(struct net_device *dev, bool value) wilc = nic->wilc; mutex_lock(&wilc->hif_cs); - ret = (&g_wlan)->hif_func.hif_read_reg(WILC_CHANGING_VIR_IF, ®); + ret = (&g_wlan)->hif_func.hif_read_reg(wilc, WILC_CHANGING_VIR_IF, + ®); if (!ret) PRINT_ER("Error while Reading reg WILC_CHANGING_VIR_IF\n"); @@ -1732,7 +1746,8 @@ u16 wilc_set_machw_change_vir_if(struct net_device *dev, bool value) else reg &= ~BIT(31); - ret = (&g_wlan)->hif_func.hif_write_reg(WILC_CHANGING_VIR_IF, reg); + ret = (&g_wlan)->hif_func.hif_write_reg(wilc, WILC_CHANGING_VIR_IF, + reg); if (!ret) PRINT_ER("Error while writing reg WILC_CHANGING_VIR_IF\n"); diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 334abafe3b0fe..c3f13aa14c70a 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -238,19 +238,19 @@ struct rxq_entry_t { struct wilc; struct wilc_hif_func { int (*hif_init)(struct wilc *, wilc_debug_func); - int (*hif_deinit)(void *); - int (*hif_read_reg)(u32, u32 *); - int (*hif_write_reg)(u32, u32); - int (*hif_block_rx)(u32, u8 *, u32); - int (*hif_block_tx)(u32, u8 *, u32); - int (*hif_sync)(void); - int (*hif_clear_int)(void); - int (*hif_read_int)(u32 *); - int (*hif_clear_int_ext)(u32); - int (*hif_read_size)(u32 *); - int (*hif_block_tx_ext)(u32, u8 *, u32); - int (*hif_block_rx_ext)(u32, u8 *, u32); - int (*hif_sync_ext)(int); + int (*hif_deinit)(struct wilc *); + int (*hif_read_reg)(struct wilc *, u32, u32 *); + int (*hif_write_reg)(struct wilc *, u32, u32); + int (*hif_block_rx)(struct wilc *, u32, u8 *, u32); + int (*hif_block_tx)(struct wilc *, u32, u8 *, u32); + int (*hif_sync)(struct wilc *); + int (*hif_clear_int)(struct wilc *); + int (*hif_read_int)(struct wilc *, u32 *); + int (*hif_clear_int_ext)(struct wilc *, u32); + int (*hif_read_size)(struct wilc *, u32 *); + int (*hif_block_tx_ext)(struct wilc *, u32, u8 *, u32); + int (*hif_block_rx_ext)(struct wilc *, u32, u8 *, u32); + int (*hif_sync_ext)(struct wilc *, int); int (*enable_interrupt)(struct wilc *nic); void (*disable_interrupt)(struct wilc *nic); }; -- GitLab From ea5779b4fbc722cec770e20557d883c959a34d74 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Wed, 18 Nov 2015 15:11:27 +0900 Subject: [PATCH 1634/2855] staging: wilc1000: wilc_sdio_cmd52: pass struct wilc This patch adds new function parameter struct wilc and use it instead of wilc_dev. Pass wilc to the function as well. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_sdio.c | 4 +-- drivers/staging/wilc1000/linux_wlan_sdio.h | 2 +- drivers/staging/wilc1000/wilc_sdio.c | 42 +++++++++++----------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index 761cb3ddd132d..6a38876ab2dfd 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -29,9 +29,9 @@ static void wilc_sdio_interrupt(struct sdio_func *func) sdio_claim_host(func); } -int wilc_sdio_cmd52(sdio_cmd52_t *cmd) +int wilc_sdio_cmd52(struct wilc *wilc, sdio_cmd52_t *cmd) { - struct sdio_func *func = container_of(wilc_dev->dev, struct sdio_func, dev); + struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev); int ret; u8 data; diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.h b/drivers/staging/wilc1000/linux_wlan_sdio.h index dbe911a9ae3d0..d966bb96d2690 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.h +++ b/drivers/staging/wilc1000/linux_wlan_sdio.h @@ -1,7 +1,7 @@ #include int wilc_sdio_init(void); -int wilc_sdio_cmd52(sdio_cmd52_t *cmd); +int wilc_sdio_cmd52(struct wilc *wilc, sdio_cmd52_t *cmd); int wilc_sdio_cmd53(sdio_cmd53_t *cmd); int wilc_sdio_enable_interrupt(struct wilc *); diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index 3f8260477f7c0..6e53ea001ee5e 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -47,21 +47,21 @@ static int sdio_set_func0_csa_address(struct wilc *wilc, u32 adr) cmd.raw = 0; cmd.address = 0x10c; cmd.data = (u8)adr; - if (!wilc_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10c data...\n"); goto _fail_; } cmd.address = 0x10d; cmd.data = (u8)(adr >> 8); - if (!wilc_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10d data...\n"); goto _fail_; } cmd.address = 0x10e; cmd.data = (u8)(adr >> 16); - if (!wilc_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10e data...\n"); goto _fail_; } @@ -80,14 +80,14 @@ static int sdio_set_func0_block_size(struct wilc *wilc, u32 block_size) cmd.raw = 0; cmd.address = 0x10; cmd.data = (u8)block_size; - if (!wilc_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10 data...\n"); goto _fail_; } cmd.address = 0x11; cmd.data = (u8)(block_size >> 8); - if (!wilc_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x11 data...\n"); goto _fail_; } @@ -112,13 +112,13 @@ static int sdio_set_func1_block_size(struct wilc *wilc, u32 block_size) cmd.raw = 0; cmd.address = 0x110; cmd.data = (u8)block_size; - if (!wilc_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x110 data...\n"); goto _fail_; } cmd.address = 0x111; cmd.data = (u8)(block_size >> 8); - if (!wilc_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x111 data...\n"); goto _fail_; } @@ -139,7 +139,7 @@ static int sdio_clear_int(struct wilc *wilc) cmd.raw = 0; cmd.address = 0x4; cmd.data = 0; - wilc_sdio_cmd52(&cmd); + wilc_sdio_cmd52(wilc, &cmd); return cmd.data; } else { @@ -175,7 +175,7 @@ static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) cmd.raw = 0; cmd.address = addr; cmd.data = data; - if (!wilc_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr); goto _fail_; } @@ -303,7 +303,7 @@ static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) cmd.function = 0; cmd.raw = 0; cmd.address = addr; - if (!wilc_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr); goto _fail_; } @@ -518,7 +518,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) cmd.raw = 1; cmd.address = 0x100; cmd.data = 0x80; - if (!wilc_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, enable csa...\n"); goto _fail_; } @@ -540,7 +540,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) cmd.raw = 1; cmd.address = 0x2; cmd.data = 0x2; - if (!wilc_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio] Fail cmd 52, set IOE register...\n"); goto _fail_; } @@ -555,7 +555,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) loop = 3; do { cmd.data = 0; - if (!wilc_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get IOR register...\n"); goto _fail_; } @@ -584,7 +584,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) cmd.raw = 1; cmd.address = 0x4; cmd.data = 0x3; - if (!wilc_sdio_cmd52(&cmd)) { + if (!wilc_sdio_cmd52(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set IEN register...\n"); goto _fail_; } @@ -624,7 +624,7 @@ static int sdio_read_size(struct wilc *wilc, u32 *size) cmd.raw = 0; cmd.address = 0xf2; cmd.data = 0; - wilc_sdio_cmd52(&cmd); + wilc_sdio_cmd52(wilc, &cmd); tmp = cmd.data; /* cmd.read_write = 0; */ @@ -632,7 +632,7 @@ static int sdio_read_size(struct wilc *wilc, u32 *size) /* cmd.raw = 0; */ cmd.address = 0xf3; cmd.data = 0; - wilc_sdio_cmd52(&cmd); + wilc_sdio_cmd52(wilc, &cmd); tmp |= (cmd.data << 8); *size = tmp; @@ -656,7 +656,7 @@ static int sdio_read_int(struct wilc *wilc, u32 *int_status) cmd.function = 1; cmd.address = 0x04; cmd.data = 0; - wilc_sdio_cmd52(&cmd); + wilc_sdio_cmd52(wilc, &cmd); if (cmd.data & BIT(0)) tmp |= INT_0; @@ -684,7 +684,7 @@ static int sdio_read_int(struct wilc *wilc, u32 *int_status) cmd.raw = 0; cmd.address = 0xf7; cmd.data = 0; - wilc_sdio_cmd52(&cmd); + wilc_sdio_cmd52(wilc, &cmd); irq_flags = cmd.data & 0x1f; tmp |= ((irq_flags >> 0) << IRG_FLAGS_OFFSET); } @@ -727,7 +727,7 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val) cmd.address = 0xf8; cmd.data = reg; - ret = wilc_sdio_cmd52(&cmd); + ret = wilc_sdio_cmd52(wilc, &cmd); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__); goto _fail_; @@ -755,7 +755,7 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val) cmd.address = 0xf8; cmd.data = BIT(i); - ret = wilc_sdio_cmd52(&cmd); + ret = wilc_sdio_cmd52(wilc, &cmd); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__); goto _fail_; @@ -798,7 +798,7 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val) cmd.raw = 0; cmd.address = 0xf6; cmd.data = vmm_ctl; - ret = wilc_sdio_cmd52(&cmd); + ret = wilc_sdio_cmd52(wilc, &cmd); if (!ret) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf6 data (%d) ...\n", __LINE__); goto _fail_; -- GitLab From 9b410fe82f444e473f1f13b3476f5aecdff50610 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Wed, 18 Nov 2015 15:11:28 +0900 Subject: [PATCH 1635/2855] staging: wilc1000: wilc_sdio_cmd53: pass struct wilc This patch adds new function parameter struct wilc and use it instead of global variable wilc_dev and pass wilc to the function as well. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_sdio.c | 4 ++-- drivers/staging/wilc1000/linux_wlan_sdio.h | 2 +- drivers/staging/wilc1000/wilc_sdio.c | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index 6a38876ab2dfd..92633aa2c0bbe 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -61,9 +61,9 @@ int wilc_sdio_cmd52(struct wilc *wilc, sdio_cmd52_t *cmd) } -int wilc_sdio_cmd53(sdio_cmd53_t *cmd) +int wilc_sdio_cmd53(struct wilc *wilc, sdio_cmd53_t *cmd) { - struct sdio_func *func = container_of(wilc_dev->dev, struct sdio_func, dev); + struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev); int size, ret; sdio_claim_host(func); diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.h b/drivers/staging/wilc1000/linux_wlan_sdio.h index d966bb96d2690..8d276c61cdcc8 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.h +++ b/drivers/staging/wilc1000/linux_wlan_sdio.h @@ -2,7 +2,7 @@ int wilc_sdio_init(void); int wilc_sdio_cmd52(struct wilc *wilc, sdio_cmd52_t *cmd); -int wilc_sdio_cmd53(sdio_cmd53_t *cmd); +int wilc_sdio_cmd53(struct wilc *wilc, sdio_cmd53_t *cmd); int wilc_sdio_enable_interrupt(struct wilc *); void wilc_sdio_disable_interrupt(struct wilc *); diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index 6e53ea001ee5e..ff7990a0b5ec9 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -197,7 +197,7 @@ static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) cmd.buffer = (u8 *)&data; cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */ - if (!wilc_sdio_cmd53(&cmd)) { + if (!wilc_sdio_cmd53(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, write reg (%08x)...\n", addr); goto _fail_; } @@ -260,7 +260,7 @@ static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) if (!sdio_set_func0_csa_address(wilc, addr)) goto _fail_; } - if (!wilc_sdio_cmd53(&cmd)) { + if (!wilc_sdio_cmd53(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block send...\n", addr); goto _fail_; } @@ -281,7 +281,7 @@ static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) if (!sdio_set_func0_csa_address(wilc, addr)) goto _fail_; } - if (!wilc_sdio_cmd53(&cmd)) { + if (!wilc_sdio_cmd53(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes send...\n", addr); goto _fail_; } @@ -324,7 +324,7 @@ static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */ - if (!wilc_sdio_cmd53(&cmd)) { + if (!wilc_sdio_cmd53(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, read reg (%08x)...\n", addr); goto _fail_; } @@ -391,7 +391,7 @@ static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) if (!sdio_set_func0_csa_address(wilc, addr)) goto _fail_; } - if (!wilc_sdio_cmd53(&cmd)) { + if (!wilc_sdio_cmd53(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block read...\n", addr); goto _fail_; } @@ -412,7 +412,7 @@ static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) if (!sdio_set_func0_csa_address(wilc, addr)) goto _fail_; } - if (!wilc_sdio_cmd53(&cmd)) { + if (!wilc_sdio_cmd53(wilc, &cmd)) { g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes read...\n", addr); goto _fail_; } -- GitLab From 643b2e42621f66ea951059880f2ba33163b0fef5 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Wed, 18 Nov 2015 15:11:29 +0900 Subject: [PATCH 1636/2855] staging: wilc1000: wilc_spi_write: pass struct wilc This patch add new function parameter struct wilc and use it instead of wilc_dev, and pass wilc to the function as well. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_spi.c | 4 ++-- drivers/staging/wilc1000/linux_wlan_spi.h | 3 ++- drivers/staging/wilc1000/wilc_spi.c | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index bfd3cc3914946..7be750bbe9da8 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -66,9 +66,9 @@ int wilc_spi_init(void) return 1; } -int wilc_spi_write(u8 *b, u32 len) +int wilc_spi_write(struct wilc *wilc, u8 *b, u32 len) { - struct spi_device *spi = to_spi_device(wilc_dev->dev); + struct spi_device *spi = to_spi_device(wilc->dev); int ret; struct spi_message msg; diff --git a/drivers/staging/wilc1000/linux_wlan_spi.h b/drivers/staging/wilc1000/linux_wlan_spi.h index baa98cc9a247e..41d47dc9cf959 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.h +++ b/drivers/staging/wilc1000/linux_wlan_spi.h @@ -2,9 +2,10 @@ #define LINUX_WLAN_SPI_H #include +#include "wilc_wfi_netdevice.h" int wilc_spi_init(void); -int wilc_spi_write(u8 *b, u32 len); +int wilc_spi_write(struct wilc *wilc, u8 *b, u32 len); int wilc_spi_read(u8 *rb, u32 rlen); int wilc_spi_write_read(u8 *wb, u8 *rb, u32 rlen); #endif diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 53d098f801568..46f7ea8357702 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -482,7 +482,7 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz) order = 0x2; } cmd |= order; - if (!wilc_spi_write(&cmd, 1)) { + if (!wilc_spi_write(wilc, &cmd, 1)) { PRINT_ER("[wilc spi]: Failed data block cmd write, bus error...\n"); result = N_FAIL; break; @@ -491,7 +491,7 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz) /** * Write data **/ - if (!wilc_spi_write(&b[ix], nbytes)) { + if (!wilc_spi_write(wilc, &b[ix], nbytes)) { PRINT_ER("[wilc spi]: Failed data block write, bus error...\n"); result = N_FAIL; break; @@ -501,7 +501,7 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz) * Write Crc **/ if (!g_spi.crc_off) { - if (!wilc_spi_write(crc, 2)) { + if (!wilc_spi_write(wilc, crc, 2)) { PRINT_ER("[wilc spi]: Failed data block crc write, bus error...\n"); result = N_FAIL; break; -- GitLab From 1b8d17a0c94fe6e42443a01f33a36a199ec58fe6 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Wed, 18 Nov 2015 15:11:30 +0900 Subject: [PATCH 1637/2855] staging: wilc1000: wilc_spi_read: pass struct wilc This patch adds new function parameter struct wilc and use it instead of global variable wilc_dev, and pass wilc to the functions as well. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_spi.c | 4 ++-- drivers/staging/wilc1000/linux_wlan_spi.h | 2 +- drivers/staging/wilc1000/wilc_spi.c | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index 7be750bbe9da8..5066191b90130 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -112,9 +112,9 @@ int wilc_spi_write(struct wilc *wilc, u8 *b, u32 len) return ret; } -int wilc_spi_read(u8 *rb, u32 rlen) +int wilc_spi_read(struct wilc *wilc, u8 *rb, u32 rlen) { - struct spi_device *spi = to_spi_device(wilc_dev->dev); + struct spi_device *spi = to_spi_device(wilc->dev); int ret; if (rlen > 0) { diff --git a/drivers/staging/wilc1000/linux_wlan_spi.h b/drivers/staging/wilc1000/linux_wlan_spi.h index 41d47dc9cf959..16f0b9fb82f8c 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.h +++ b/drivers/staging/wilc1000/linux_wlan_spi.h @@ -6,6 +6,6 @@ int wilc_spi_init(void); int wilc_spi_write(struct wilc *wilc, u8 *b, u32 len); -int wilc_spi_read(u8 *rb, u32 rlen); +int wilc_spi_read(struct wilc *wilc, u8 *rb, u32 rlen); int wilc_spi_write_read(u8 *wb, u8 *rb, u32 rlen); #endif diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 46f7ea8357702..5e21109ceadf6 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -365,7 +365,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, /** * Read bytes **/ - if (!wilc_spi_read(&b[ix], nbytes)) { + if (!wilc_spi_read(wilc, &b[ix], nbytes)) { PRINT_ER("[wilc spi]: Failed data block read, bus error...\n"); result = N_FAIL; goto _error_; @@ -375,7 +375,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, * Read Crc **/ if (!g_spi.crc_off) { - if (!wilc_spi_read(crc, 2)) { + if (!wilc_spi_read(wilc, crc, 2)) { PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n"); result = N_FAIL; goto _error_; @@ -406,7 +406,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, **/ retry = 10; do { - if (!wilc_spi_read(&rsp, 1)) { + if (!wilc_spi_read(wilc, &rsp, 1)) { PRINT_ER("[wilc spi]: Failed data response read, bus error...\n"); result = N_FAIL; break; @@ -422,7 +422,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, /** * Read bytes **/ - if (!wilc_spi_read(&b[ix], nbytes)) { + if (!wilc_spi_read(wilc, &b[ix], nbytes)) { PRINT_ER("[wilc spi]: Failed data block read, bus error...\n"); result = N_FAIL; break; @@ -432,7 +432,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, * Read Crc **/ if (!g_spi.crc_off) { - if (!wilc_spi_read(crc, 2)) { + if (!wilc_spi_read(wilc, crc, 2)) { PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n"); result = N_FAIL; break; -- GitLab From f8598aaa21b222864badc5d7f9e04fe1c4fbc12d Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Wed, 18 Nov 2015 15:11:31 +0900 Subject: [PATCH 1638/2855] staging: wilc1000: wilc_spi_write_read: pass struct wilc This patch adds new function parameter struct wilc and use it instead of global variable wilc_dev, and pass wilc to the function as well. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_spi.c | 4 ++-- drivers/staging/wilc1000/linux_wlan_spi.h | 2 +- drivers/staging/wilc1000/wilc_spi.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index 5066191b90130..f3ffc9e6d6262 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -154,9 +154,9 @@ int wilc_spi_read(struct wilc *wilc, u8 *rb, u32 rlen) return ret; } -int wilc_spi_write_read(u8 *wb, u8 *rb, u32 rlen) +int wilc_spi_write_read(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen) { - struct spi_device *spi = to_spi_device(wilc_dev->dev); + struct spi_device *spi = to_spi_device(wilc->dev); int ret; if (rlen > 0) { diff --git a/drivers/staging/wilc1000/linux_wlan_spi.h b/drivers/staging/wilc1000/linux_wlan_spi.h index 16f0b9fb82f8c..00733aba91790 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.h +++ b/drivers/staging/wilc1000/linux_wlan_spi.h @@ -7,5 +7,5 @@ int wilc_spi_init(void); int wilc_spi_write(struct wilc *wilc, u8 *b, u32 len); int wilc_spi_read(struct wilc *wilc, u8 *rb, u32 rlen); -int wilc_spi_write_read(u8 *wb, u8 *rb, u32 rlen); +int wilc_spi_write_read(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen); #endif diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 5e21109ceadf6..d6f412117fd87 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -250,7 +250,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, } rix = len; - if (!wilc_spi_write_read(wb, rb, len2)) { + if (!wilc_spi_write_read(wilc, wb, rb, len2)) { PRINT_ER("[wilc spi]: Failed cmd write, bus error...\n"); result = N_FAIL; return result; -- GitLab From b82d940db037d1aaf591845cdd1352ceb439b929 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Wed, 18 Nov 2015 15:11:32 +0900 Subject: [PATCH 1639/2855] staging: wilc1000: add struct wilc to host_if_drv This patch adds struct wilc to host_if_dev and assign wilc to use driver's primary structure in host_if_dev. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 1 + drivers/staging/wilc1000/host_interface.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 672092b386dc6..4fae80dae6e02 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3843,6 +3843,7 @@ s32 wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) result = -ENOMEM; goto _fail_; } + hif_drv->wilc = wilc; *hif_drv_handler = hif_drv; err = add_handler_in_list(hif_drv); if (err) { diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index efeb9e2335896..004467c655026 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -259,7 +259,9 @@ enum p2p_listen_state { P2P_GRP_FORMATION }; +struct wilc; struct host_if_drv { + struct wilc *wilc; struct user_scan_req usr_scan_req; struct user_conn_req usr_conn_req; struct remain_ch remain_on_ch; -- GitLab From ec62e6d1ec3f668ee0462734ede28be6b3d7db1c Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Wed, 18 Nov 2015 15:11:33 +0900 Subject: [PATCH 1640/2855] staging: wilc1000: wilc_send_config_pkt: pass struct wilc This patch passes struct wilc to wilc_send_config_pkt. The function wilc_wlan_cfg_set and wilc_wlan_cfg_get function will get wilc to replace wilc_dev with it. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/coreconfigurator.c | 3 +- drivers/staging/wilc1000/coreconfigurator.h | 3 +- drivers/staging/wilc1000/host_interface.c | 127 +++++++++++--------- 3 files changed, 74 insertions(+), 59 deletions(-) diff --git a/drivers/staging/wilc1000/coreconfigurator.c b/drivers/staging/wilc1000/coreconfigurator.c index 47fa82f26b53a..dc290d13fd37a 100644 --- a/drivers/staging/wilc1000/coreconfigurator.c +++ b/drivers/staging/wilc1000/coreconfigurator.c @@ -588,7 +588,8 @@ s32 wilc_dealloc_assoc_resp_info(tstrConnectRespInfo *pstrConnectRespInfo) * @date 1 Mar 2012 * @version 1.0 */ -s32 wilc_send_config_pkt(u8 mode, struct wid *wids, u32 count, u32 drv) +s32 wilc_send_config_pkt(struct wilc *wilc, u8 mode, struct wid *wids, + u32 count, u32 drv) { s32 counter = 0, ret = 0; diff --git a/drivers/staging/wilc1000/coreconfigurator.h b/drivers/staging/wilc1000/coreconfigurator.h index 912d5c2879e47..3f2a7d3c3a174 100644 --- a/drivers/staging/wilc1000/coreconfigurator.h +++ b/drivers/staging/wilc1000/coreconfigurator.h @@ -127,7 +127,8 @@ typedef struct { size_t ie_len; } tstrDisconnectNotifInfo; -s32 wilc_send_config_pkt(u8 mode, struct wid *wids, u32 count, u32 drv); +s32 wilc_send_config_pkt(struct wilc *wilc, u8 mode, struct wid *wids, + u32 count, u32 drv); s32 wilc_parse_network_info(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo); s32 wilc_dealloc_network_info(tstrNetworkInfo *pstrNetworkInfo); diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 4fae80dae6e02..db34048864e66 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -329,7 +329,7 @@ static s32 handle_set_channel(struct host_if_drv *hif_drv, PRINT_D(HOSTINF_DBG, "Setting channel\n"); - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { @@ -351,7 +351,8 @@ static s32 handle_set_wfi_drv_handler(struct host_if_drv *hif_drv, wid.val = (s8 *)&hif_drv_handler->handler; wid.size = sizeof(u32); - result = wilc_send_config_pkt(SET_CFG, &wid, 1, hif_drv_handler->handler); + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + hif_drv_handler->handler); if (!hif_drv) up(&hif_sema_driver); @@ -375,7 +376,7 @@ static s32 handle_set_operation_mode(struct host_if_drv *hif_drv, wid.val = (s8 *)&hif_op_mode->mode; wid.size = sizeof(u32); - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if ((hif_op_mode->mode) == IDLE_MODE) @@ -410,7 +411,7 @@ static s32 handle_set_ip_address(struct host_if_drv *hif_drv, u8 *ip_addr, u8 id wid.val = (u8 *)ip_addr; wid.size = IP_ALEN; - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); host_int_get_ipaddress(hif_drv, firmware_ip_addr, idx); @@ -435,7 +436,7 @@ static s32 handle_get_ip_address(struct host_if_drv *hif_drv, u8 idx) wid.val = kmalloc(IP_ALEN, GFP_KERNEL); wid.size = IP_ALEN; - result = wilc_send_config_pkt(GET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, get_id_from_handler(hif_drv)); PRINT_INFO(HOSTINF_DBG, "%pI4\n", wid.val); @@ -478,7 +479,7 @@ static s32 handle_set_mac_address(struct host_if_drv *hif_drv, wid.size = ETH_ALEN; PRINT_D(GENERIC_DBG, "mac addr = :%pM\n", wid.val); - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { PRINT_ER("Failed to set mac address\n"); @@ -500,7 +501,7 @@ static s32 handle_get_mac_address(struct host_if_drv *hif_drv, wid.val = get_mac_addr->mac_addr; wid.size = ETH_ALEN; - result = wilc_send_config_pkt(GET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { @@ -795,8 +796,8 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv, wid_cnt++; } - result = wilc_send_config_pkt(SET_CFG, wid_list, wid_cnt, - get_id_from_handler(hif_drv)); + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, wid_list, + wid_cnt, get_id_from_handler(hif_drv)); if (result) PRINT_ER("Error in setting CFG params\n"); @@ -918,8 +919,9 @@ static s32 Handle_Scan(struct host_if_drv *hif_drv, else if (hif_drv->hif_state == HOST_IF_IDLE) scan_while_connected = false; - result = wilc_send_config_pkt(SET_CFG, strWIDList, u32WidsCount, - get_id_from_handler(hif_drv)); + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, strWIDList, + u32WidsCount, + get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send scan paramters config packet\n"); @@ -962,7 +964,7 @@ static s32 Handle_ScanDone(struct host_if_drv *hif_drv, wid.val = (s8 *)&u8abort_running_scan; wid.size = sizeof(char); - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { @@ -1216,8 +1218,9 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv, PRINT_D(GENERIC_DBG, "save bssid = %pM\n", wilc_connected_SSID); } - result = wilc_send_config_pkt(SET_CFG, strWIDList, u32WidsCount, - get_id_from_handler(hif_drv)); + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, strWIDList, + u32WidsCount, + get_id_from_handler(hif_drv)); if (result) { PRINT_ER("failed to send config packet\n"); result = -EFAULT; @@ -1313,8 +1316,9 @@ static s32 Handle_FlushConnect(struct host_if_drv *hif_drv) u32WidsCount++; - result = wilc_send_config_pkt(SET_CFG, strWIDList, u32WidsCount, - get_id_from_handler(join_req_drv)); + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, strWIDList, + u32WidsCount, + get_id_from_handler(join_req_drv)); if (result) { PRINT_ER("failed to send config packet\n"); result = -EINVAL; @@ -1374,7 +1378,7 @@ static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv) PRINT_D(HOSTINF_DBG, "Sending disconnect request\n"); - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send dissconect config packet\n"); @@ -1757,8 +1761,9 @@ static int Handle_Key(struct host_if_drv *hif_drv, strWIDList[3].size = pstrHostIFkeyAttr->attr.wep.key_len; strWIDList[3].val = (s8 *)pu8keybuf; - result = wilc_send_config_pkt(SET_CFG, strWIDList, 4, - get_id_from_handler(hif_drv)); + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, + strWIDList, 4, + get_id_from_handler(hif_drv)); kfree(pu8keybuf); } @@ -1780,8 +1785,9 @@ static int Handle_Key(struct host_if_drv *hif_drv, wid.val = (s8 *)pu8keybuf; wid.size = pstrHostIFkeyAttr->attr.wep.key_len + 2; - result = wilc_send_config_pkt(SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, + &wid, 1, + get_id_from_handler(hif_drv)); kfree(pu8keybuf); } else if (pstrHostIFkeyAttr->action & REMOVEKEY) { PRINT_D(HOSTINF_DBG, "Removing key\n"); @@ -1792,8 +1798,9 @@ static int Handle_Key(struct host_if_drv *hif_drv, wid.val = s8idxarray; wid.size = 1; - result = wilc_send_config_pkt(SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, + &wid, 1, + get_id_from_handler(hif_drv)); } else { wid.id = (u16)WID_KEY_ID; wid.type = WID_CHAR; @@ -1802,8 +1809,9 @@ static int Handle_Key(struct host_if_drv *hif_drv, PRINT_D(HOSTINF_DBG, "Setting default key index\n"); - result = wilc_send_config_pkt(SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, + &wid, 1, + get_id_from_handler(hif_drv)); } up(&hif_drv->sem_test_key_block); break; @@ -1835,8 +1843,9 @@ static int Handle_Key(struct host_if_drv *hif_drv, strWIDList[1].val = (s8 *)pu8keybuf; strWIDList[1].size = RX_MIC_KEY_MSG_LEN; - result = wilc_send_config_pkt(SET_CFG, strWIDList, 2, - get_id_from_handler(hif_drv)); + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, + strWIDList, 2, + get_id_from_handler(hif_drv)); kfree(pu8keybuf); up(&hif_drv->sem_test_key_block); @@ -1868,8 +1877,9 @@ static int Handle_Key(struct host_if_drv *hif_drv, wid.val = (s8 *)pu8keybuf; wid.size = RX_MIC_KEY_MSG_LEN; - result = wilc_send_config_pkt(SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, + &wid, 1, + get_id_from_handler(hif_drv)); kfree(pu8keybuf); up(&hif_drv->sem_test_key_block); @@ -1907,8 +1917,9 @@ _WPARxGtk_end_case_: strWIDList[1].val = (s8 *)pu8keybuf; strWIDList[1].size = PTK_KEY_MSG_LEN + 1; - result = wilc_send_config_pkt(SET_CFG, strWIDList, 2, - get_id_from_handler(hif_drv)); + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, + strWIDList, 2, + get_id_from_handler(hif_drv)); kfree(pu8keybuf); up(&hif_drv->sem_test_key_block); } @@ -1930,8 +1941,9 @@ _WPARxGtk_end_case_: wid.val = (s8 *)pu8keybuf; wid.size = PTK_KEY_MSG_LEN; - result = wilc_send_config_pkt(SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, + &wid, 1, + get_id_from_handler(hif_drv)); kfree(pu8keybuf); up(&hif_drv->sem_test_key_block); } @@ -1965,7 +1977,7 @@ _WPAPtk_end_case_: wid.val = (s8 *)pu8keybuf; wid.size = (pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1; - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); kfree(pu8keybuf); @@ -1997,7 +2009,7 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) eth_zero_addr(wilc_connected_SSID); - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { @@ -2084,7 +2096,7 @@ static s32 Handle_GetChnl(struct host_if_drv *hif_drv) PRINT_D(HOSTINF_DBG, "Getting channel value\n"); - result = wilc_send_config_pkt(GET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { @@ -2109,7 +2121,7 @@ static void Handle_GetRssi(struct host_if_drv *hif_drv) PRINT_D(HOSTINF_DBG, "Getting RSSI value\n"); - result = wilc_send_config_pkt(GET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { PRINT_ER("Failed to get RSSI value\n"); @@ -2133,7 +2145,7 @@ static void Handle_GetLinkspeed(struct host_if_drv *hif_drv) PRINT_D(HOSTINF_DBG, "Getting LINKSPEED value\n"); - result = wilc_send_config_pkt(GET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { PRINT_ER("Failed to get LINKSPEED value\n"); @@ -2178,8 +2190,9 @@ static s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pst strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_fail_cnt; u32WidsCount++; - result = wilc_send_config_pkt(GET_CFG, strWIDList, u32WidsCount, - get_id_from_handler(hif_drv)); + result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, strWIDList, + u32WidsCount, + get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send scan paramters config packet\n"); @@ -2205,7 +2218,7 @@ static s32 Handle_Get_InActiveTime(struct host_if_drv *hif_drv, PRINT_D(CFG80211_DBG, "SETING STA inactive time\n"); - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { @@ -2218,7 +2231,7 @@ static s32 Handle_Get_InActiveTime(struct host_if_drv *hif_drv, wid.val = (s8 *)&inactive_time; wid.size = sizeof(u32); - result = wilc_send_config_pkt(GET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { @@ -2277,7 +2290,7 @@ static void Handle_AddBeacon(struct host_if_drv *hif_drv, memcpy(pu8CurrByte, pstrSetBeaconParam->tail, pstrSetBeaconParam->tail_len); pu8CurrByte += pstrSetBeaconParam->tail_len; - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send add beacon config packet\n"); @@ -2306,7 +2319,7 @@ static void Handle_DelBeacon(struct host_if_drv *hif_drv) PRINT_D(HOSTINF_DBG, "Deleting BEACON\n"); - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send delete beacon config packet\n"); @@ -2379,7 +2392,7 @@ static void Handle_AddStation(struct host_if_drv *hif_drv, pu8CurrByte = wid.val; pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam); - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result != 0) PRINT_ER("Failed to send add station config packet\n"); @@ -2421,7 +2434,7 @@ static void Handle_DelAllSta(struct host_if_drv *hif_drv, pu8CurrByte += ETH_ALEN; } - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send add station config packet\n"); @@ -2453,7 +2466,7 @@ static void Handle_DelStation(struct host_if_drv *hif_drv, memcpy(pu8CurrByte, pstrDelStaParam->mac_addr, ETH_ALEN); - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send add station config packet\n"); @@ -2481,7 +2494,7 @@ static void Handle_EditStation(struct host_if_drv *hif_drv, pu8CurrByte = wid.val; pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam); - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send edit station config packet\n"); @@ -2542,7 +2555,7 @@ static int Handle_RemainOnChan(struct host_if_drv *hif_drv, wid.val[0] = u8remain_on_chan_flag; wid.val[1] = (s8)pstrHostIfRemainOnChan->ch; - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result != 0) PRINT_ER("Failed to set remain on channel\n"); @@ -2590,7 +2603,7 @@ static int Handle_RegisterFrame(struct host_if_drv *hif_drv, wid.size = sizeof(u16) + 2; - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { PRINT_ER("Failed to frame register config packet\n"); @@ -2622,7 +2635,7 @@ static u32 Handle_ListenStateExpired(struct host_if_drv *hif_drv, wid.val[0] = u8remain_on_chan_flag; wid.val[1] = FALSE_FRMWR_CHANNEL; - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result != 0) { PRINT_ER("Failed to set remain on channel\n"); @@ -2680,7 +2693,7 @@ static void Handle_PowerManagement(struct host_if_drv *hif_drv, PRINT_D(HOSTINF_DBG, "Handling Power Management\n"); - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send power management config packet\n"); @@ -2717,7 +2730,7 @@ static void Handle_SetMulticastFilter(struct host_if_drv *hif_drv, memcpy(pu8CurrByte, wilc_multicast_mac_addr_list, ((strHostIfSetMulti->cnt) * ETH_ALEN)); - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_ER("Failed to send setup multicast config packet\n"); @@ -2763,7 +2776,7 @@ static s32 Handle_AddBASession(struct host_if_drv *hif_drv, *ptr++ = 8; *ptr++ = 0; - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_D(HOSTINF_DBG, "Couldn't open BA Session\n"); @@ -2782,7 +2795,7 @@ static s32 Handle_AddBASession(struct host_if_drv *hif_drv, *ptr++ = (strHostIfBASessionInfo->buf_size & 0xFF); *ptr++ = ((strHostIfBASessionInfo->time_out >> 16) & 0xFF); *ptr++ = 3; - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); kfree(wid.val); @@ -2817,7 +2830,7 @@ static s32 Handle_DelAllRxBASessions(struct host_if_drv *hif_drv, *ptr++ = 0; *ptr++ = 32; - result = wilc_send_config_pkt(SET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n"); @@ -3551,7 +3564,7 @@ static s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv, wid.val = pu8AssocRespInfo; wid.size = u32MaxAssocRespInfoLen; - result = wilc_send_config_pkt(GET_CFG, &wid, 1, + result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, get_id_from_handler(hif_drv)); if (result) { *pu32RcvdAssocRespInfoLen = 0; -- GitLab From 89758e13b89608e168a192a6df51a70d32ebd737 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Wed, 18 Nov 2015 15:11:34 +0900 Subject: [PATCH 1641/2855] staging: wilc1000: wilc_wlan_cfg_set: pass struct wilc This patch pass struct wilc to the function and use it instead of global variable wilc_dev. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/coreconfigurator.c | 2 +- drivers/staging/wilc1000/linux_wlan.c | 101 +++++++++++--------- drivers/staging/wilc1000/wilc_wlan.c | 5 +- drivers/staging/wilc1000/wilc_wlan.h | 4 +- 4 files changed, 63 insertions(+), 49 deletions(-) diff --git a/drivers/staging/wilc1000/coreconfigurator.c b/drivers/staging/wilc1000/coreconfigurator.c index dc290d13fd37a..6278aecba2f79 100644 --- a/drivers/staging/wilc1000/coreconfigurator.c +++ b/drivers/staging/wilc1000/coreconfigurator.c @@ -616,7 +616,7 @@ s32 wilc_send_config_pkt(struct wilc *wilc, u8 mode, struct wid *wids, } else if (mode == SET_CFG) { for (counter = 0; counter < count; counter++) { PRINT_D(CORECONFIG_DBG, "Sending config SET PACKET WID:%x\n", wids[counter].id); - if (!wilc_wlan_cfg_set(!counter, + if (!wilc_wlan_cfg_set(wilc, !counter, wids[counter].id, wids[counter].val, wids[counter].size, diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 43458e6ca691a..792cc0be5a635 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -537,179 +537,194 @@ static int linux_wlan_init_test_config(struct net_device *dev, *(int *)c_val = 1; - if (!wilc_wlan_cfg_set(1, WID_SET_DRV_HANDLER, c_val, 4, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 1, WID_SET_DRV_HANDLER, c_val, 4, 0, 0)) goto _fail_; c_val[0] = 0; - if (!wilc_wlan_cfg_set(0, WID_PC_TEST_MODE, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_PC_TEST_MODE, c_val, 1, 0, 0)) goto _fail_; c_val[0] = INFRASTRUCTURE; - if (!wilc_wlan_cfg_set(0, WID_BSS_TYPE, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_BSS_TYPE, c_val, 1, 0, 0)) goto _fail_; c_val[0] = RATE_AUTO; - if (!wilc_wlan_cfg_set(0, WID_CURRENT_TX_RATE, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_CURRENT_TX_RATE, c_val, 1, 0, 0)) goto _fail_; c_val[0] = G_MIXED_11B_2_MODE; - if (!wilc_wlan_cfg_set(0, WID_11G_OPERATING_MODE, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_11G_OPERATING_MODE, c_val, 1, 0, + 0)) goto _fail_; c_val[0] = 1; - if (!wilc_wlan_cfg_set(0, WID_CURRENT_CHANNEL, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_CURRENT_CHANNEL, c_val, 1, 0, 0)) goto _fail_; c_val[0] = G_SHORT_PREAMBLE; - if (!wilc_wlan_cfg_set(0, WID_PREAMBLE, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_PREAMBLE, c_val, 1, 0, 0)) goto _fail_; c_val[0] = AUTO_PROT; - if (!wilc_wlan_cfg_set(0, WID_11N_PROT_MECH, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_PROT_MECH, c_val, 1, 0, 0)) goto _fail_; c_val[0] = ACTIVE_SCAN; - if (!wilc_wlan_cfg_set(0, WID_SCAN_TYPE, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_SCAN_TYPE, c_val, 1, 0, 0)) goto _fail_; c_val[0] = SITE_SURVEY_OFF; - if (!wilc_wlan_cfg_set(0, WID_SITE_SURVEY, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_SITE_SURVEY, c_val, 1, 0, 0)) goto _fail_; *((int *)c_val) = 0xffff; - if (!wilc_wlan_cfg_set(0, WID_RTS_THRESHOLD, c_val, 2, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_RTS_THRESHOLD, c_val, 2, 0, 0)) goto _fail_; *((int *)c_val) = 2346; - if (!wilc_wlan_cfg_set(0, WID_FRAG_THRESHOLD, c_val, 2, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_FRAG_THRESHOLD, c_val, 2, 0, 0)) goto _fail_; c_val[0] = 0; - if (!wilc_wlan_cfg_set(0, WID_BCAST_SSID, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_BCAST_SSID, c_val, 1, 0, 0)) goto _fail_; c_val[0] = 1; - if (!wilc_wlan_cfg_set(0, WID_QOS_ENABLE, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_QOS_ENABLE, c_val, 1, 0, 0)) goto _fail_; c_val[0] = NO_POWERSAVE; - if (!wilc_wlan_cfg_set(0, WID_POWER_MANAGEMENT, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_POWER_MANAGEMENT, c_val, 1, 0, 0)) goto _fail_; c_val[0] = NO_SECURITY; /* NO_ENCRYPT, 0x79 */ - if (!wilc_wlan_cfg_set(0, WID_11I_MODE, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_11I_MODE, c_val, 1, 0, 0)) goto _fail_; c_val[0] = OPEN_SYSTEM; - if (!wilc_wlan_cfg_set(0, WID_AUTH_TYPE, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_AUTH_TYPE, c_val, 1, 0, 0)) goto _fail_; strcpy(c_val, "123456790abcdef1234567890"); - if (!wilc_wlan_cfg_set(0, WID_WEP_KEY_VALUE, c_val, (strlen(c_val) + 1), 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_WEP_KEY_VALUE, c_val, + (strlen(c_val) + 1), 0, 0)) goto _fail_; strcpy(c_val, "12345678"); - if (!wilc_wlan_cfg_set(0, WID_11I_PSK, c_val, (strlen(c_val)), 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_11I_PSK, c_val, (strlen(c_val)), 0, + 0)) goto _fail_; strcpy(c_val, "password"); - if (!wilc_wlan_cfg_set(0, WID_1X_KEY, c_val, (strlen(c_val) + 1), 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_1X_KEY, c_val, (strlen(c_val) + 1), + 0, 0)) goto _fail_; c_val[0] = 192; c_val[1] = 168; c_val[2] = 1; c_val[3] = 112; - if (!wilc_wlan_cfg_set(0, WID_1X_SERV_ADDR, c_val, 4, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_1X_SERV_ADDR, c_val, 4, 0, 0)) goto _fail_; c_val[0] = 3; - if (!wilc_wlan_cfg_set(0, WID_LISTEN_INTERVAL, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_LISTEN_INTERVAL, c_val, 1, 0, 0)) goto _fail_; c_val[0] = 3; - if (!wilc_wlan_cfg_set(0, WID_DTIM_PERIOD, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_DTIM_PERIOD, c_val, 1, 0, 0)) goto _fail_; c_val[0] = NORMAL_ACK; - if (!wilc_wlan_cfg_set(0, WID_ACK_POLICY, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_ACK_POLICY, c_val, 1, 0, 0)) goto _fail_; c_val[0] = 0; - if (!wilc_wlan_cfg_set(0, WID_USER_CONTROL_ON_TX_POWER, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_USER_CONTROL_ON_TX_POWER, c_val, 1, + 0, 0)) goto _fail_; c_val[0] = 48; - if (!wilc_wlan_cfg_set(0, WID_TX_POWER_LEVEL_11A, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_TX_POWER_LEVEL_11A, c_val, 1, 0, + 0)) goto _fail_; c_val[0] = 28; - if (!wilc_wlan_cfg_set(0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0, + 0)) goto _fail_; *((int *)c_val) = 100; - if (!wilc_wlan_cfg_set(0, WID_BEACON_INTERVAL, c_val, 2, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_BEACON_INTERVAL, c_val, 2, 0, 0)) goto _fail_; c_val[0] = REKEY_DISABLE; - if (!wilc_wlan_cfg_set(0, WID_REKEY_POLICY, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_REKEY_POLICY, c_val, 1, 0, 0)) goto _fail_; *((int *)c_val) = 84600; - if (!wilc_wlan_cfg_set(0, WID_REKEY_PERIOD, c_val, 4, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_REKEY_PERIOD, c_val, 4, 0, 0)) goto _fail_; *((int *)c_val) = 500; - if (!wilc_wlan_cfg_set(0, WID_REKEY_PACKET_COUNT, c_val, 4, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_REKEY_PACKET_COUNT, c_val, 4, 0, + 0)) goto _fail_; c_val[0] = 1; - if (!wilc_wlan_cfg_set(0, WID_SHORT_SLOT_ALLOWED, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_SHORT_SLOT_ALLOWED, c_val, 1, 0, + 0)) goto _fail_; c_val[0] = G_SELF_CTS_PROT; - if (!wilc_wlan_cfg_set(0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0, 0)) goto _fail_; c_val[0] = 1; - if (!wilc_wlan_cfg_set(0, WID_11N_ENABLE, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_ENABLE, c_val, 1, 0, 0)) goto _fail_; c_val[0] = HT_MIXED_MODE; - if (!wilc_wlan_cfg_set(0, WID_11N_OPERATING_MODE, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_OPERATING_MODE, c_val, 1, 0, + 0)) goto _fail_; c_val[0] = 1; - if (!wilc_wlan_cfg_set(0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0, + 0)) goto _fail_; memcpy(c_val, mac_add, 6); - if (!wilc_wlan_cfg_set(0, WID_MAC_ADDR, c_val, 6, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_MAC_ADDR, c_val, 6, 0, 0)) goto _fail_; c_val[0] = DETECT_PROTECT_REPORT; - if (!wilc_wlan_cfg_set(0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1, + 0, 0)) goto _fail_; c_val[0] = RTS_CTS_NONHT_PROT; - if (!wilc_wlan_cfg_set(0, WID_11N_HT_PROT_TYPE, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_HT_PROT_TYPE, c_val, 1, 0, 0)) goto _fail_; c_val[0] = 0; - if (!wilc_wlan_cfg_set(0, WID_11N_RIFS_PROT_ENABLE, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_RIFS_PROT_ENABLE, c_val, 1, 0, + 0)) goto _fail_; c_val[0] = MIMO_MODE; - if (!wilc_wlan_cfg_set(0, WID_11N_SMPS_MODE, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_SMPS_MODE, c_val, 1, 0, 0)) goto _fail_; c_val[0] = 7; - if (!wilc_wlan_cfg_set(0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0, 0)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0, + 0)) goto _fail_; c_val[0] = 1; - if (!wilc_wlan_cfg_set(0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1, 1, 1)) + if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1, + 1, 1)) goto _fail_; return 0; diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 9ac6ad7df6055..03c707b6488f8 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1499,11 +1499,10 @@ static int wilc_wlan_cfg_commit(struct wilc *wilc, int type, u32 drv_handler) return 0; } -int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, - int commit, u32 drv_handler) +int wilc_wlan_cfg_set(struct wilc *wilc, int start, u32 wid, u8 *buffer, + u32 buffer_size, int commit, u32 drv_handler) { wilc_wlan_dev_t *p = &g_wlan; - struct wilc *wilc = wilc_dev; u32 offset; int ret_size; diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index c3f13aa14c70a..e1a8c730831c9 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -289,8 +289,8 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count); void wilc_handle_isr(struct wilc *wilc); void wilc_wlan_cleanup(struct net_device *dev); -int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, - int commit, u32 drv_handler); +int wilc_wlan_cfg_set(struct wilc *wilc, int start, u32 wid, u8 *buffer, + u32 buffer_size, int commit, u32 drv_handler); int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drv_handler); int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size); int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, -- GitLab From d40c99c74c91441b935a900b5c92df7f81e0b8b1 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Wed, 18 Nov 2015 15:11:35 +0900 Subject: [PATCH 1642/2855] staging: wilc1000: wilc_wlan_cfg_get: pass struct wilc This patch passes the struct wilc to the function and use it instead of global variable wilc_dev. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/coreconfigurator.c | 2 +- drivers/staging/wilc1000/linux_wlan.c | 2 +- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- drivers/staging/wilc1000/wilc_wlan.h | 3 ++- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/coreconfigurator.c b/drivers/staging/wilc1000/coreconfigurator.c index 6278aecba2f79..0cd2accf1a348 100644 --- a/drivers/staging/wilc1000/coreconfigurator.c +++ b/drivers/staging/wilc1000/coreconfigurator.c @@ -597,7 +597,7 @@ s32 wilc_send_config_pkt(struct wilc *wilc, u8 mode, struct wid *wids, for (counter = 0; counter < count; counter++) { PRINT_INFO(CORECONFIG_DBG, "Sending CFG packet [%d][%d]\n", !counter, (counter == count - 1)); - if (!wilc_wlan_cfg_get(!counter, + if (!wilc_wlan_cfg_get(wilc, !counter, wids[counter].id, (counter == count - 1), drv)) { diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 792cc0be5a635..1457e755dc49b 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -939,7 +939,7 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) goto _fail_irq_enable_; } - if (wilc_wlan_cfg_get(1, WID_FIRMWARE_VERSION, 1, 0)) { + if (wilc_wlan_cfg_get(wl, 1, WID_FIRMWARE_VERSION, 1, 0)) { int size; char Firmware_ver[20]; diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 03c707b6488f8..a27185115e49b 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1540,10 +1540,10 @@ int wilc_wlan_cfg_set(struct wilc *wilc, int start, u32 wid, u8 *buffer, return ret_size; } -int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drv_handler) +int wilc_wlan_cfg_get(struct wilc *wilc, int start, u32 wid, int commit, + u32 drv_handler) { wilc_wlan_dev_t *p = &g_wlan; - struct wilc *wilc = wilc_dev; u32 offset; int ret_size; diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index e1a8c730831c9..2ac63a3e092a1 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -291,7 +291,8 @@ void wilc_handle_isr(struct wilc *wilc); void wilc_wlan_cleanup(struct net_device *dev); int wilc_wlan_cfg_set(struct wilc *wilc, int start, u32 wid, u8 *buffer, u32 buffer_size, int commit, u32 drv_handler); -int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drv_handler); +int wilc_wlan_cfg_get(struct wilc *wilc, int start, u32 wid, int commit, + u32 drv_handler); int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size); int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func); -- GitLab From d36ec22d1d9b8020e08d9ae9ee7db73554a355e7 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Wed, 18 Nov 2015 15:11:36 +0900 Subject: [PATCH 1643/2855] staging: wilc1000: wilc_dbg: remove wilc This patch remove parameter struct wilc since it is not used and also wilc_dev will be removed. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 2 +- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 2 +- drivers/staging/wilc1000/wilc_wlan.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 1457e755dc49b..cd471abcedf77 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -245,7 +245,7 @@ static void deinit_irq(struct net_device *dev) } } -void wilc_dbg(struct wilc *wilc, u8 *buff) +void wilc_dbg(u8 *buff) { PRINT_D(INIT_DBG, "%d\n", *buff); } diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 6ec6d6a2868c2..4c8de8b19c835 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -210,7 +210,7 @@ extern struct net_device *WILC_WFI_devs[]; void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset); void wilc_mac_indicate(struct wilc *wilc, int flag); void wilc_rx_complete(struct wilc *wilc); -void wilc_dbg(struct wilc *, u8 *buff); +void wilc_dbg(u8 *buff); int wilc_lock_timeout(struct wilc *wilc, void *, u32 timeout); void wilc_netdev_cleanup(struct wilc *wilc); diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index a27185115e49b..a73e99f64f27c 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -51,7 +51,7 @@ static void wilc_debug(u32 flag, char *fmt, ...) vsprintf(buf, fmt, args); va_end(args); - wilc_dbg(wilc_dev, buf); + wilc_dbg(buf); } } -- GitLab From 825b966f9ee283b47cc8fa463c638c7ed1d1d922 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Wed, 18 Nov 2015 15:11:37 +0900 Subject: [PATCH 1644/2855] staging: wilc1000: use wilc instead of wilc_dev and remove wilc_dev This patch changes wilc_dev with wilc in the function call wilc_wlan_get_num_conn_ifcs, and remove wilc_dev and it's related codes. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 +- drivers/staging/wilc1000/linux_wlan.c | 5 +---- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 1 - 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index db34048864e66..b1b4802fc56ae 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2919,7 +2919,7 @@ static int hostIFthread(void *pvArg) del_timer(&hif_drv->scan_timer); PRINT_D(HOSTINF_DBG, "scan completed successfully\n"); - if (!wilc_wlan_get_num_conn_ifcs(wilc_dev)) + if (!wilc_wlan_get_num_conn_ifcs(wilc)) wilc_chip_sleep_manually(wilc); Handle_ScanDone(msg.drv, SCAN_EVENT_DONE); diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index cd471abcedf77..73954f468ae8e 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -43,8 +43,6 @@ static int mac_init_fn(struct net_device *ndev); static struct net_device_stats *mac_stats(struct net_device *dev); static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd); static void wilc_set_multicast_list(struct net_device *dev); -struct wilc *wilc_dev; -EXPORT_SYMBOL_GPL(wilc_dev); bool wilc_enable_ps = true; @@ -1432,7 +1430,7 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, sema_init(&close_exit_sync, 0); - wl = kzalloc(sizeof(*wilc_dev), GFP_KERNEL); + wl = kzalloc(sizeof(*wl), GFP_KERNEL); if (!wl) return -ENOMEM; @@ -1495,7 +1493,6 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, nic->iftype = STATION_MODE; nic->mac_opened = 0; } - wilc_dev = *wilc = wl; return 0; } diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 4c8de8b19c835..212d607748e98 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -205,7 +205,6 @@ struct WILC_WFI_mon_priv { int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic); -extern struct wilc *wilc_dev; extern struct net_device *WILC_WFI_devs[]; void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset); void wilc_mac_indicate(struct wilc *wilc, int flag); -- GitLab From 771fbae49b5c49bd692b42d46fe4f4d96c61d953 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:10 +0900 Subject: [PATCH 1645/2855] staging: wilc1000: rename u32LastScannedNtwrksCountShadow variable This patch renames u32LastScannedNtwrksCountShadow variable to last_scanned_cnt to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 50 +++++++++---------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index cc279c654e53b..97848e400288c 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -107,7 +107,7 @@ extern int wilc_mac_open(struct net_device *ndev); extern int wilc_mac_close(struct net_device *ndev); static tstrNetworkInfo astrLastScannedNtwrksShadow[MAX_NUM_SCANNED_NETWORKS_SHADOW]; -static u32 u32LastScannedNtwrksCountShadow; +static u32 last_scanned_cnt; struct timer_list wilc_during_ip_timer; static struct timer_list hAgingTimer; static u8 op_ifcs; @@ -213,16 +213,16 @@ static void clear_shadow_scan(void *pUserVoid) del_timer_sync(&hAgingTimer); PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n"); - for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) { - if (astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs != NULL) { + for (i = 0; i < last_scanned_cnt; i++) { + if (astrLastScannedNtwrksShadow[last_scanned_cnt].pu8IEs != NULL) { kfree(astrLastScannedNtwrksShadow[i].pu8IEs); - astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs = NULL; + astrLastScannedNtwrksShadow[last_scanned_cnt].pu8IEs = NULL; } wilc_free_join_params(astrLastScannedNtwrksShadow[i].pJoinParams); astrLastScannedNtwrksShadow[i].pJoinParams = NULL; } - u32LastScannedNtwrksCountShadow = 0; + last_scanned_cnt = 0; } } @@ -251,7 +251,7 @@ static void refresh_scan(void *pUserVoid, u8 all, bool bDirectScan) priv = (struct wilc_priv *)pUserVoid; wiphy = priv->dev->ieee80211_ptr->wiphy; - for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) { + for (i = 0; i < last_scanned_cnt; i++) { tstrNetworkInfo *pstrNetworkInfo; pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]); @@ -284,19 +284,16 @@ static void reset_shadow_found(void *pUserVoid) { int i; - for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) { + for (i = 0; i < last_scanned_cnt; i++) astrLastScannedNtwrksShadow[i].u8Found = 0; - - } } static void update_scan_time(void *pUserVoid) { int i; - for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) { + for (i = 0; i < last_scanned_cnt; i++) astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies; - } } static void remove_network_from_shadow(unsigned long arg) @@ -305,7 +302,7 @@ static void remove_network_from_shadow(unsigned long arg) int i, j; - for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) { + for (i = 0; i < last_scanned_cnt; i++) { if (time_after(now, astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) { PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", astrLastScannedNtwrksShadow[i].au8ssid); @@ -314,15 +311,16 @@ static void remove_network_from_shadow(unsigned long arg) wilc_free_join_params(astrLastScannedNtwrksShadow[i].pJoinParams); - for (j = i; (j < u32LastScannedNtwrksCountShadow - 1); j++) { + for (j = i; (j < last_scanned_cnt - 1); j++) astrLastScannedNtwrksShadow[j] = astrLastScannedNtwrksShadow[j + 1]; - } - u32LastScannedNtwrksCountShadow--; + + last_scanned_cnt--; } } - PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n", u32LastScannedNtwrksCountShadow); - if (u32LastScannedNtwrksCountShadow != 0) { + PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n", + last_scanned_cnt); + if (last_scanned_cnt != 0) { hAgingTimer.data = arg; mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME)); } else { @@ -341,14 +339,14 @@ static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoi int state = -1; int i; - if (u32LastScannedNtwrksCountShadow == 0) { + if (last_scanned_cnt == 0) { PRINT_D(CFG80211_DBG, "Starting Aging timer\n"); hAgingTimer.data = (unsigned long)pUserVoid; mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME)); state = -1; } else { /* Linear search for now */ - for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) { + for (i = 0; i < last_scanned_cnt; i++) { if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) { state = i; @@ -365,13 +363,13 @@ static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserV u32 ap_index = 0; u8 rssi_index = 0; - if (u32LastScannedNtwrksCountShadow >= MAX_NUM_SCANNED_NETWORKS_SHADOW) { + if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) { PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n"); return; } if (ap_found == -1) { - ap_index = u32LastScannedNtwrksCountShadow; - u32LastScannedNtwrksCountShadow++; + ap_index = last_scanned_cnt; + last_scanned_cnt++; } else { ap_index = ap_found; @@ -619,7 +617,7 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN); - for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) { + for (i = 0; i < last_scanned_cnt; i++) { if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid, pstrConnectInfo->au8bssid, ETH_ALEN) == 0) { unsigned long now = jiffies; @@ -850,7 +848,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, } PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type); - for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) { + for (i = 0; i < last_scanned_cnt; i++) { if ((sme->ssid_len == astrLastScannedNtwrksShadow[i].u8SsidLen) && memcmp(astrLastScannedNtwrksShadow[i].au8ssid, sme->ssid, @@ -874,7 +872,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, } } - if (i < u32LastScannedNtwrksCountShadow) { + if (i < last_scanned_cnt) { PRINT_D(CFG80211_DBG, "Required bss is in scan results\n"); pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]); @@ -885,7 +883,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]); } else { s32Error = -ENOENT; - if (u32LastScannedNtwrksCountShadow == 0) + if (last_scanned_cnt == 0) PRINT_D(CFG80211_DBG, "No Scan results yet\n"); else PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error); -- GitLab From f1ab117db845a6cd63c75c1b9a8be3b9589b0c1b Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:11 +0900 Subject: [PATCH 1646/2855] staging: wilc1000: rename astrLastScannedNtwrksShadow variable This patch renames astrLastScannedNtwrksShadow variable to last_scanned_shadow to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 124 ++++++++---------- 1 file changed, 58 insertions(+), 66 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 97848e400288c..32cc7349c4534 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -106,7 +106,7 @@ static const struct ieee80211_txrx_stypes extern int wilc_mac_open(struct net_device *ndev); extern int wilc_mac_close(struct net_device *ndev); -static tstrNetworkInfo astrLastScannedNtwrksShadow[MAX_NUM_SCANNED_NETWORKS_SHADOW]; +static tstrNetworkInfo last_scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW]; static u32 last_scanned_cnt; struct timer_list wilc_during_ip_timer; static struct timer_list hAgingTimer; @@ -214,13 +214,13 @@ static void clear_shadow_scan(void *pUserVoid) PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n"); for (i = 0; i < last_scanned_cnt; i++) { - if (astrLastScannedNtwrksShadow[last_scanned_cnt].pu8IEs != NULL) { - kfree(astrLastScannedNtwrksShadow[i].pu8IEs); - astrLastScannedNtwrksShadow[last_scanned_cnt].pu8IEs = NULL; + if (last_scanned_shadow[last_scanned_cnt].pu8IEs) { + kfree(last_scanned_shadow[i].pu8IEs); + last_scanned_shadow[last_scanned_cnt].pu8IEs = NULL; } - wilc_free_join_params(astrLastScannedNtwrksShadow[i].pJoinParams); - astrLastScannedNtwrksShadow[i].pJoinParams = NULL; + wilc_free_join_params(last_scanned_shadow[i].pJoinParams); + last_scanned_shadow[i].pJoinParams = NULL; } last_scanned_cnt = 0; } @@ -254,8 +254,7 @@ static void refresh_scan(void *pUserVoid, u8 all, bool bDirectScan) for (i = 0; i < last_scanned_cnt; i++) { tstrNetworkInfo *pstrNetworkInfo; - pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]); - + pstrNetworkInfo = &last_scanned_shadow[i]; if ((!pstrNetworkInfo->u8Found) || all) { s32 s32Freq; @@ -285,7 +284,7 @@ static void reset_shadow_found(void *pUserVoid) int i; for (i = 0; i < last_scanned_cnt; i++) - astrLastScannedNtwrksShadow[i].u8Found = 0; + last_scanned_shadow[i].u8Found = 0; } static void update_scan_time(void *pUserVoid) @@ -293,7 +292,7 @@ static void update_scan_time(void *pUserVoid) int i; for (i = 0; i < last_scanned_cnt; i++) - astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies; + last_scanned_shadow[i].u32TimeRcvdInScan = jiffies; } static void remove_network_from_shadow(unsigned long arg) @@ -303,16 +302,16 @@ static void remove_network_from_shadow(unsigned long arg) for (i = 0; i < last_scanned_cnt; i++) { - if (time_after(now, astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) { - PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", astrLastScannedNtwrksShadow[i].au8ssid); + if (time_after(now, last_scanned_shadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) { + PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", last_scanned_shadow[i].au8ssid); - kfree(astrLastScannedNtwrksShadow[i].pu8IEs); - astrLastScannedNtwrksShadow[i].pu8IEs = NULL; + kfree(last_scanned_shadow[i].pu8IEs); + last_scanned_shadow[i].pu8IEs = NULL; - wilc_free_join_params(astrLastScannedNtwrksShadow[i].pJoinParams); + wilc_free_join_params(last_scanned_shadow[i].pJoinParams); for (j = i; (j < last_scanned_cnt - 1); j++) - astrLastScannedNtwrksShadow[j] = astrLastScannedNtwrksShadow[j + 1]; + last_scanned_shadow[j] = last_scanned_shadow[j + 1]; last_scanned_cnt--; } @@ -347,8 +346,8 @@ static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoi } else { /* Linear search for now */ for (i = 0; i < last_scanned_cnt; i++) { - if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid, - pstrNetworkInfo->au8bssid, 6) == 0) { + if (memcmp(last_scanned_shadow[i].au8bssid, + pstrNetworkInfo->au8bssid, 6) == 0) { state = i; break; } @@ -374,44 +373,37 @@ static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserV } else { ap_index = ap_found; } - rssi_index = astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index; - astrLastScannedNtwrksShadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi; + rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index; + last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi; if (rssi_index == NUM_RSSI) { rssi_index = 0; - astrLastScannedNtwrksShadow[ap_index].strRssi.u8Full = 1; - } - astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index = rssi_index; - - astrLastScannedNtwrksShadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi; - astrLastScannedNtwrksShadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo; - - astrLastScannedNtwrksShadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen; - memcpy(astrLastScannedNtwrksShadow[ap_index].au8ssid, - pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen); - - memcpy(astrLastScannedNtwrksShadow[ap_index].au8bssid, - pstrNetworkInfo->au8bssid, ETH_ALEN); - - astrLastScannedNtwrksShadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod; - astrLastScannedNtwrksShadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod; - astrLastScannedNtwrksShadow[ap_index].u8channel = pstrNetworkInfo->u8channel; - - astrLastScannedNtwrksShadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen; - astrLastScannedNtwrksShadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf; + last_scanned_shadow[ap_index].strRssi.u8Full = 1; + } + last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index; + last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi; + last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo; + last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen; + memcpy(last_scanned_shadow[ap_index].au8ssid, + pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen); + memcpy(last_scanned_shadow[ap_index].au8bssid, + pstrNetworkInfo->au8bssid, ETH_ALEN); + last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod; + last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod; + last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel; + last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen; + last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf; if (ap_found != -1) - kfree(astrLastScannedNtwrksShadow[ap_index].pu8IEs); - astrLastScannedNtwrksShadow[ap_index].pu8IEs = + kfree(last_scanned_shadow[ap_index].pu8IEs); + last_scanned_shadow[ap_index].pu8IEs = kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); /* will be deallocated by the WILC_WFI_CfgScan() function */ - memcpy(astrLastScannedNtwrksShadow[ap_index].pu8IEs, - pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen); - - astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScan = jiffies; - astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScanCached = jiffies; - astrLastScannedNtwrksShadow[ap_index].u8Found = 1; + memcpy(last_scanned_shadow[ap_index].pu8IEs, + pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen); + last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies; + last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies; + last_scanned_shadow[ap_index].u8Found = 1; if (ap_found != -1) - wilc_free_join_params(astrLastScannedNtwrksShadow[ap_index].pJoinParams); - astrLastScannedNtwrksShadow[ap_index].pJoinParams = pJoinParams; - + wilc_free_join_params(last_scanned_shadow[ap_index].pJoinParams); + last_scanned_shadow[ap_index].pJoinParams = pJoinParams; } @@ -497,11 +489,11 @@ static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNet u32 i; /* So this network is discovered before, we'll just update its RSSI */ for (i = 0; i < priv->u32RcvdChCount; i++) { - if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) { - PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", astrLastScannedNtwrksShadow[i].au8ssid); + if (memcmp(last_scanned_shadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) { + PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid); - astrLastScannedNtwrksShadow[i].s8rssi = pstrNetworkInfo->s8rssi; - astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies; + last_scanned_shadow[i].s8rssi = pstrNetworkInfo->s8rssi; + last_scanned_shadow[i].u32TimeRcvdInScan = jiffies; break; } } @@ -618,12 +610,12 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, for (i = 0; i < last_scanned_cnt; i++) { - if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid, - pstrConnectInfo->au8bssid, ETH_ALEN) == 0) { + if (memcmp(last_scanned_shadow[i].au8bssid, + pstrConnectInfo->au8bssid, ETH_ALEN) == 0) { unsigned long now = jiffies; if (time_after(now, - astrLastScannedNtwrksShadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) { + last_scanned_shadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) { bNeedScanRefresh = true; } @@ -849,10 +841,10 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type); for (i = 0; i < last_scanned_cnt; i++) { - if ((sme->ssid_len == astrLastScannedNtwrksShadow[i].u8SsidLen) && - memcmp(astrLastScannedNtwrksShadow[i].au8ssid, - sme->ssid, - sme->ssid_len) == 0) { + if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) && + memcmp(last_scanned_shadow[i].au8ssid, + sme->ssid, + sme->ssid_len) == 0) { PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid); if (sme->bssid == NULL) { /* BSSID is not passed from the user, so decision of matching @@ -862,9 +854,9 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, } else { /* BSSID is also passed from the user, so decision of matching * should consider also this passed BSSID */ - if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid, - sme->bssid, - ETH_ALEN) == 0) { + if (memcmp(last_scanned_shadow[i].au8bssid, + sme->bssid, + ETH_ALEN) == 0) { PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n"); break; } @@ -875,7 +867,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, if (i < last_scanned_cnt) { PRINT_D(CFG80211_DBG, "Required bss is in scan results\n"); - pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]); + pstrNetworkInfo = &last_scanned_shadow[i]; PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n", pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1], -- GitLab From 2736f476aed92e96109c16a4cfba92ce2289e095 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:12 +0900 Subject: [PATCH 1647/2855] staging: wilc1000: rename WILC_WFI_2ghz_channels variable This patch renames WILC_WFI_2ghz_channels variable to ieee80211_2ghz_channels to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 32cc7349c4534..349b720fe57b6 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -124,7 +124,7 @@ u8 wilc_initialized = 1; } /*Frequency range for channels*/ -static struct ieee80211_channel WILC_WFI_2ghz_channels[] = { +static struct ieee80211_channel ieee80211_2ghz_channels[] = { CHAN2G(1, 2412, 0), CHAN2G(2, 2417, 0), CHAN2G(3, 2422, 0), @@ -181,8 +181,8 @@ static u8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03}; static bool bWilc_ie; static struct ieee80211_supported_band WILC_WFI_band_2ghz = { - .channels = WILC_WFI_2ghz_channels, - .n_channels = ARRAY_SIZE(WILC_WFI_2ghz_channels), + .channels = ieee80211_2ghz_channels, + .n_channels = ARRAY_SIZE(ieee80211_2ghz_channels), .bitrates = WILC_WFI_rates, .n_bitrates = ARRAY_SIZE(WILC_WFI_rates), }; -- GitLab From 8d48b5bab62f1e9eaafa12467874cab4a1bfb1bc Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:13 +0900 Subject: [PATCH 1648/2855] staging: wilc1000: rename WILC_WFI_rates variable This patch renames WILC_WFI_rates variable to ieee80211_bitrates to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 349b720fe57b6..c2e7bf89d0caf 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -149,7 +149,7 @@ static struct ieee80211_channel ieee80211_2ghz_channels[] = { /* Table 6 in section 3.2.1.1 */ -static struct ieee80211_rate WILC_WFI_rates[] = { +static struct ieee80211_rate ieee80211_bitrates[] = { RATETAB_ENT(10, 0, 0), RATETAB_ENT(20, 1, 0), RATETAB_ENT(55, 2, 0), @@ -183,8 +183,8 @@ static bool bWilc_ie; static struct ieee80211_supported_band WILC_WFI_band_2ghz = { .channels = ieee80211_2ghz_channels, .n_channels = ARRAY_SIZE(ieee80211_2ghz_channels), - .bitrates = WILC_WFI_rates, - .n_bitrates = ARRAY_SIZE(WILC_WFI_rates), + .bitrates = ieee80211_bitrates, + .n_bitrates = ARRAY_SIZE(ieee80211_bitrates), }; -- GitLab From 0bd8274fb8a8155bef0289a0eb669611cce9eb3e Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:14 +0900 Subject: [PATCH 1649/2855] staging: wilc1000: rename u8WLANChannel variable This patch renames u8WLANChannel variable to wlan_channel to avoid camelcase. And, remove the relation comment. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index c2e7bf89d0caf..3b072ef27e68b 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -169,9 +169,7 @@ struct p2p_mgmt_data { u8 *buff; }; -/*Global variable used to state the current connected STA channel*/ -static u8 u8WLANChannel = INVALID_CHANNEL; - +static u8 wlan_channel = INVALID_CHANNEL; static u8 curr_channel; static u8 u8P2P_oui[] = {0x50, 0x6f, 0x9A, 0x09}; @@ -593,9 +591,8 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, wilc_wlan_set_bssid(priv->dev, NullBssid); eth_zero_addr(wilc_connected_SSID); - /*Invalidate u8WLANChannel value on wlan0 disconnect*/ if (!pstrWFIDrv->p2p_connect) - u8WLANChannel = INVALID_CHANNEL; + wlan_channel = INVALID_CHANNEL; PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus); } @@ -652,9 +649,8 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, wilc_wlan_set_bssid(priv->dev, NullBssid); eth_zero_addr(wilc_connected_SSID); - /*Invalidate u8WLANChannel value on wlan0 disconnect*/ if (!pstrWFIDrv->p2p_connect) - u8WLANChannel = INVALID_CHANNEL; + wlan_channel = INVALID_CHANNEL; /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change * virtual interface to station*/ if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) { @@ -1029,7 +1025,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, curr_channel = pstrNetworkInfo->u8channel; if (!pstrWFIDrv->p2p_connect) - u8WLANChannel = pstrNetworkInfo->u8channel; + wlan_channel = pstrNetworkInfo->u8channel; wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid); @@ -1069,10 +1065,9 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_co wilc_connecting = 0; priv = wiphy_priv(wiphy); - /*Invalidate u8WLANChannel value on wlan0 disconnect*/ pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv; if (!pstrWFIDrv->p2p_connect) - u8WLANChannel = INVALID_CHANNEL; + wlan_channel = INVALID_CHANNEL; wilc_wlan_set_bssid(priv->dev, NullBssid); PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code); @@ -1855,15 +1850,14 @@ static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len) op_channel_attr_index = index; index += buf[index + 1] + 3; /* ID,Length byte */ } - if (u8WLANChannel != INVALID_CHANNEL) { - + if (wlan_channel != INVALID_CHANNEL) { /*Modify channel list attribute*/ if (channel_list_attr_index) { PRINT_D(GENERIC_DBG, "Modify channel list attribute\n"); for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) { if (buf[i] == 0x51) { for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) { - buf[j] = u8WLANChannel; + buf[j] = wlan_channel; } break; } @@ -1873,7 +1867,7 @@ static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len) if (op_channel_attr_index) { PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n"); buf[op_channel_attr_index + 6] = 0x51; - buf[op_channel_attr_index + 7] = u8WLANChannel; + buf[op_channel_attr_index + 7] = wlan_channel; } } } @@ -1909,15 +1903,14 @@ static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftyp op_channel_attr_index = index; index += buf[index + 1] + 3; /* ID,Length byte */ } - if (u8WLANChannel != INVALID_CHANNEL && bOperChan) { - + if (wlan_channel != INVALID_CHANNEL && bOperChan) { /*Modify channel list attribute*/ if (channel_list_attr_index) { PRINT_D(GENERIC_DBG, "Modify channel list attribute\n"); for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) { if (buf[i] == 0x51) { for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) { - buf[j] = u8WLANChannel; + buf[j] = wlan_channel; } break; } @@ -1927,7 +1920,7 @@ static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftyp if (op_channel_attr_index) { PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n"); buf[op_channel_attr_index + 6] = 0x51; - buf[op_channel_attr_index + 7] = u8WLANChannel; + buf[op_channel_attr_index + 7] = wlan_channel; } } } -- GitLab From 881eb5d812ec76e69b37e644e77b3a16b83d52fd Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:15 +0900 Subject: [PATCH 1650/2855] staging: wilc1000: rename u8P2P_oui variable This patch renames u8P2P_oui variable to p2p_oui to avoid camelcase. And, remove the relation comment. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 3b072ef27e68b..6ab4a79e70e09 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -171,8 +171,7 @@ struct p2p_mgmt_data { static u8 wlan_channel = INVALID_CHANNEL; static u8 curr_channel; - -static u8 u8P2P_oui[] = {0x50, 0x6f, 0x9A, 0x09}; +static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09}; static u8 u8P2Plocalrandom = 0x01; static u8 u8P2Precvrandom = 0x00; static u8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03}; @@ -1997,9 +1996,7 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) break; case PUBLIC_ACT_VENDORSPEC: - /*Now we have a public action vendor specific action frame, check if its a p2p public action frame - * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/ - if (!memcmp(u8P2P_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) { + if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) { if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) { if (!bWilc_ie) { for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) { @@ -2016,7 +2013,7 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) { for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) { - if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buff[i + 2], 4))) { + if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) { WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6)); break; } @@ -2292,9 +2289,7 @@ static int mgmt_tx(struct wiphy *wiphy, case PUBLIC_ACT_VENDORSPEC: { - /*Now we have a public action vendor specific action frame, check if its a p2p public action frame - * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/ - if (!memcmp(u8P2P_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) { + if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) { /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/ if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) { if (u8P2Plocalrandom == 1 && u8P2Precvrandom < u8P2Plocalrandom) { @@ -2311,7 +2306,7 @@ static int mgmt_tx(struct wiphy *wiphy, /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/ for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) { - if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buf[i + 2], 4))) { + if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) { if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP) WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype); -- GitLab From 583d972cf7bbb1714c4ad26819d5ead12bfb69d7 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:16 +0900 Subject: [PATCH 1651/2855] staging: wilc1000: rename u8P2Plocalrandom variable This patch renames u8P2Plocalrandom variable to p2p_local_random to avoid camelcase. And, remove the relation comment. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 6ab4a79e70e09..dd8d4040622b0 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -172,7 +172,7 @@ struct p2p_mgmt_data { static u8 wlan_channel = INVALID_CHANNEL; static u8 curr_channel; static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09}; -static u8 u8P2Plocalrandom = 0x01; +static u8 p2p_local_random = 0x01; static u8 u8P2Precvrandom = 0x00; static u8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03}; static bool bWilc_ie; @@ -641,7 +641,7 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, wilc_optaining_ip = false; PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n", pstrDisconnectNotifInfo->u16reason, priv->dev); - u8P2Plocalrandom = 0x01; + p2p_local_random = 0x01; u8P2Precvrandom = 0x00; bWilc_ie = false; eth_zero_addr(priv->au8AssociatedBss); @@ -1071,7 +1071,7 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_co PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code); - u8P2Plocalrandom = 0x01; + p2p_local_random = 0x01; u8P2Precvrandom = 0x00; bWilc_ie = false; pstrWFIDrv->p2p_timeout = 0; @@ -2009,7 +2009,7 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) } } } - if (u8P2Plocalrandom > u8P2Precvrandom) { + if (p2p_local_random > u8P2Precvrandom) { if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) { for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) { @@ -2019,8 +2019,9 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) } } } - } else - PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom); + } else { + PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, u8P2Precvrandom); + } } @@ -2224,7 +2225,7 @@ static int mgmt_tx(struct wiphy *wiphy, struct host_if_drv *pstrWFIDrv; u32 i; perInterface_wlan_t *nic; - u32 buf_len = len + sizeof(u8P2P_vendorspec) + sizeof(u8P2Plocalrandom); + u32 buf_len = len + sizeof(u8P2P_vendorspec) + sizeof(p2p_local_random); nic = netdev_priv(wdev->netdev); priv = wiphy_priv(wiphy); @@ -2292,17 +2293,16 @@ static int mgmt_tx(struct wiphy *wiphy, if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) { /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/ if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) { - if (u8P2Plocalrandom == 1 && u8P2Precvrandom < u8P2Plocalrandom) { - get_random_bytes(&u8P2Plocalrandom, 1); - /*Increment the number to prevent if its 0*/ - u8P2Plocalrandom++; + if (p2p_local_random == 1 && u8P2Precvrandom < p2p_local_random) { + get_random_bytes(&p2p_local_random, 1); + p2p_local_random++; } } if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) { - if (u8P2Plocalrandom > u8P2Precvrandom) { - PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom); + if (p2p_local_random > u8P2Precvrandom) { + PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, u8P2Precvrandom); /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/ for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) { @@ -2324,11 +2324,12 @@ static int mgmt_tx(struct wiphy *wiphy, * identify each other and connect */ memcpy(&mgmt_tx->buff[len], u8P2P_vendorspec, sizeof(u8P2P_vendorspec)); - mgmt_tx->buff[len + sizeof(u8P2P_vendorspec)] = u8P2Plocalrandom; + mgmt_tx->buff[len + sizeof(u8P2P_vendorspec)] = p2p_local_random; mgmt_tx->size = buf_len; } - } else - PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom); + } else { + PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, u8P2Precvrandom); + } } } else { @@ -2557,7 +2558,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n"); PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name); - u8P2Plocalrandom = 0x01; + p2p_local_random = 0x01; u8P2Precvrandom = 0x00; bWilc_ie = false; -- GitLab From b84a3ac4276033baeae12bcfcdc8c970747d0f78 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:17 +0900 Subject: [PATCH 1652/2855] staging: wilc1000: rename u8P2Precvrandom variable This patch renames u8P2Precvrandom variable to p2p_recv_random to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index dd8d4040622b0..904b21485f052 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -173,7 +173,7 @@ static u8 wlan_channel = INVALID_CHANNEL; static u8 curr_channel; static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09}; static u8 p2p_local_random = 0x01; -static u8 u8P2Precvrandom = 0x00; +static u8 p2p_recv_random = 0x00; static u8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03}; static bool bWilc_ie; @@ -642,7 +642,7 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n", pstrDisconnectNotifInfo->u16reason, priv->dev); p2p_local_random = 0x01; - u8P2Precvrandom = 0x00; + p2p_recv_random = 0x00; bWilc_ie = false; eth_zero_addr(priv->au8AssociatedBss); wilc_wlan_set_bssid(priv->dev, NullBssid); @@ -1072,7 +1072,7 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_co PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code); p2p_local_random = 0x01; - u8P2Precvrandom = 0x00; + p2p_recv_random = 0x00; bWilc_ie = false; pstrWFIDrv->p2p_timeout = 0; @@ -2001,15 +2001,15 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) if (!bWilc_ie) { for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) { if (!memcmp(u8P2P_vendorspec, &buff[i], 6)) { - u8P2Precvrandom = buff[i + 6]; + p2p_recv_random = buff[i + 6]; bWilc_ie = true; - PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", u8P2Precvrandom); + PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random); break; } } } } - if (p2p_local_random > u8P2Precvrandom) { + if (p2p_local_random > p2p_recv_random) { if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) { for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) { @@ -2020,7 +2020,7 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) } } } else { - PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, u8P2Precvrandom); + PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random); } } @@ -2293,7 +2293,7 @@ static int mgmt_tx(struct wiphy *wiphy, if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) { /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/ if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) { - if (p2p_local_random == 1 && u8P2Precvrandom < p2p_local_random) { + if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) { get_random_bytes(&p2p_local_random, 1); p2p_local_random++; } @@ -2301,8 +2301,8 @@ static int mgmt_tx(struct wiphy *wiphy, if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) { - if (p2p_local_random > u8P2Precvrandom) { - PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, u8P2Precvrandom); + if (p2p_local_random > p2p_recv_random) { + PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random); /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/ for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) { @@ -2328,7 +2328,7 @@ static int mgmt_tx(struct wiphy *wiphy, mgmt_tx->size = buf_len; } } else { - PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, u8P2Precvrandom); + PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random); } } @@ -2559,7 +2559,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n"); PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name); p2p_local_random = 0x01; - u8P2Precvrandom = 0x00; + p2p_recv_random = 0x00; bWilc_ie = false; -- GitLab From 8668594a96516fad01e3336a6b13072a51ed188b Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:18 +0900 Subject: [PATCH 1653/2855] staging: wilc1000: rename u8P2P_vendorspec variable This patch renames u8P2P_vendorspec variable to p2p_vendor_spec to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 904b21485f052..0a7226c4c5c67 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -174,7 +174,7 @@ static u8 curr_channel; static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09}; static u8 p2p_local_random = 0x01; static u8 p2p_recv_random = 0x00; -static u8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03}; +static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03}; static bool bWilc_ie; static struct ieee80211_supported_band WILC_WFI_band_2ghz = { @@ -2000,7 +2000,7 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) { if (!bWilc_ie) { for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) { - if (!memcmp(u8P2P_vendorspec, &buff[i], 6)) { + if (!memcmp(p2p_vendor_spec, &buff[i], 6)) { p2p_recv_random = buff[i + 6]; bWilc_ie = true; PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random); @@ -2225,7 +2225,7 @@ static int mgmt_tx(struct wiphy *wiphy, struct host_if_drv *pstrWFIDrv; u32 i; perInterface_wlan_t *nic; - u32 buf_len = len + sizeof(u8P2P_vendorspec) + sizeof(p2p_local_random); + u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random); nic = netdev_priv(wdev->netdev); priv = wiphy_priv(wiphy); @@ -2323,8 +2323,8 @@ static int mgmt_tx(struct wiphy *wiphy, * Adding WILC information element to allow two WILC devices to * identify each other and connect */ - memcpy(&mgmt_tx->buff[len], u8P2P_vendorspec, sizeof(u8P2P_vendorspec)); - mgmt_tx->buff[len + sizeof(u8P2P_vendorspec)] = p2p_local_random; + memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec)); + mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random; mgmt_tx->size = buf_len; } } else { -- GitLab From a25d51860c58e73e9cae1e458a927d4db2f8fcaa Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:19 +0900 Subject: [PATCH 1654/2855] staging: wilc1000: rename bWilc_ie variable This patch renames bWilc_ie variable to wilc_ie to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 0a7226c4c5c67..24e1e1516b76a 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -175,7 +175,7 @@ static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09}; static u8 p2p_local_random = 0x01; static u8 p2p_recv_random = 0x00; static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03}; -static bool bWilc_ie; +static bool wilc_ie; static struct ieee80211_supported_band WILC_WFI_band_2ghz = { .channels = ieee80211_2ghz_channels, @@ -643,7 +643,7 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, pstrDisconnectNotifInfo->u16reason, priv->dev); p2p_local_random = 0x01; p2p_recv_random = 0x00; - bWilc_ie = false; + wilc_ie = false; eth_zero_addr(priv->au8AssociatedBss); wilc_wlan_set_bssid(priv->dev, NullBssid); eth_zero_addr(wilc_connected_SSID); @@ -1073,7 +1073,7 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_co p2p_local_random = 0x01; p2p_recv_random = 0x00; - bWilc_ie = false; + wilc_ie = false; pstrWFIDrv->p2p_timeout = 0; s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code); @@ -1998,11 +1998,11 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) case PUBLIC_ACT_VENDORSPEC: if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) { if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) { - if (!bWilc_ie) { + if (!wilc_ie) { for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) { if (!memcmp(p2p_vendor_spec, &buff[i], 6)) { p2p_recv_random = buff[i + 6]; - bWilc_ie = true; + wilc_ie = true; PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random); break; } @@ -2025,7 +2025,7 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) } - if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (bWilc_ie)) { + if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (wilc_ie)) { PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n"); /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */ cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0); @@ -2560,9 +2560,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name); p2p_local_random = 0x01; p2p_recv_random = 0x00; - - bWilc_ie = false; - + wilc_ie = false; wilc_optaining_ip = false; del_timer(&wilc_during_ip_timer); PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n"); -- GitLab From 7e872df9cd627614f74ec343e11bb98aeb2f59e2 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:20 +0900 Subject: [PATCH 1655/2855] staging: wilc1000: rename duringIP_TIME variable This patch renames duringIP_TIME variable to during_ip_time to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 24e1e1516b76a..c49b989c7ef31 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -200,7 +200,7 @@ static bool g_gtk_keys_saved; static bool g_wep_keys_saved; #define AGING_TIME (9 * 1000) -#define duringIP_TIME 15000 +#define during_ip_time 15000 static void clear_shadow_scan(void *pUserVoid) { @@ -2772,7 +2772,8 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, PRINT_D(GENERIC_DBG, "start duringIP timer\n"); wilc_optaining_ip = true; - mod_timer(&wilc_during_ip_timer, jiffies + msecs_to_jiffies(duringIP_TIME)); + mod_timer(&wilc_during_ip_timer, + jiffies + msecs_to_jiffies(during_ip_time)); wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0); /*Delete block ack has to be the latest config packet*/ /*sent before downloading new FW. This is because it blocks on*/ -- GitLab From e554a305529598750eb71d65560554773450f081 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:21 +0900 Subject: [PATCH 1656/2855] staging: wilc1000: rename wilc_connected_SSID variable This patch renames wilc_connected_SSID variable to wilc_connected_ssid to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 22 +++++++++---------- drivers/staging/wilc1000/host_interface.h | 2 +- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index b1b4802fc56ae..900b7ca2870f7 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -987,7 +987,7 @@ static s32 Handle_ScanDone(struct host_if_drv *hif_drv, return result; } -u8 wilc_connected_SSID[6] = {0}; +u8 wilc_connected_ssid[6] = {0}; static s32 Handle_Connect(struct host_if_drv *hif_drv, struct connect_attr *pstrHostIFconnectAttr) { @@ -999,7 +999,7 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv, PRINT_D(GENERIC_DBG, "Handling connect request\n"); - if (memcmp(pstrHostIFconnectAttr->bssid, wilc_connected_SSID, ETH_ALEN) == 0) { + if (memcmp(pstrHostIFconnectAttr->bssid, wilc_connected_ssid, ETH_ALEN) == 0) { result = 0; PRINT_ER("Trying to connect to an already connected AP, Discard connect request\n"); return result; @@ -1212,10 +1212,11 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv, PRINT_D(GENERIC_DBG, "send HOST_IF_WAITING_CONN_RESP\n"); if (pstrHostIFconnectAttr->bssid) { - memcpy(wilc_connected_SSID, pstrHostIFconnectAttr->bssid, ETH_ALEN); - - PRINT_D(GENERIC_DBG, "save Bssid = %pM\n", pstrHostIFconnectAttr->bssid); - PRINT_D(GENERIC_DBG, "save bssid = %pM\n", wilc_connected_SSID); + memcpy(wilc_connected_ssid, + pstrHostIFconnectAttr->bssid, ETH_ALEN); + PRINT_D(GENERIC_DBG, "save Bssid = %pM\n", + pstrHostIFconnectAttr->bssid); + PRINT_D(GENERIC_DBG, "save bssid = %pM\n", wilc_connected_ssid); } result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, strWIDList, @@ -1389,7 +1390,7 @@ static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv) hif_drv->usr_conn_req.ies_len = 0; kfree(hif_drv->usr_conn_req.ies); - eth_zero_addr(wilc_connected_SSID); + eth_zero_addr(wilc_connected_ssid); if (join_req && join_req_drv == hif_drv) { kfree(join_req); @@ -1585,11 +1586,10 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, if ((u8MacStatus == MAC_CONNECTED) && (strConnectInfo.u16ConnectStatus != SUCCESSFUL_STATUSCODE)) { PRINT_ER("Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n"); - eth_zero_addr(wilc_connected_SSID); - + eth_zero_addr(wilc_connected_ssid); } else if (u8MacStatus == MAC_DISCONNECTED) { PRINT_ER("Received MAC status is MAC_DISCONNECTED\n"); - eth_zero_addr(wilc_connected_SSID); + eth_zero_addr(wilc_connected_ssid); } if (hif_drv->usr_conn_req.pu8bssid) { @@ -2007,7 +2007,7 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) wilc_optaining_ip = false; wilc_set_power_mgmt(hif_drv, 0, 0); - eth_zero_addr(wilc_connected_SSID); + eth_zero_addr(wilc_connected_ssid); result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 004467c655026..4f5300d096eb2 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -398,7 +398,7 @@ s32 wilc_get_statistics(struct host_if_drv *hWFIDrv, void wilc_resolve_disconnect_aberration(struct host_if_drv *hif_drv); extern bool wilc_optaining_ip; -extern u8 wilc_connected_SSID[6]; +extern u8 wilc_connected_ssid[6]; extern u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; extern int wilc_connecting; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index c49b989c7ef31..718b060463990 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -588,7 +588,7 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */ u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE; wilc_wlan_set_bssid(priv->dev, NullBssid); - eth_zero_addr(wilc_connected_SSID); + eth_zero_addr(wilc_connected_ssid); if (!pstrWFIDrv->p2p_connect) wlan_channel = INVALID_CHANNEL; @@ -646,7 +646,7 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, wilc_ie = false; eth_zero_addr(priv->au8AssociatedBss); wilc_wlan_set_bssid(priv->dev, NullBssid); - eth_zero_addr(wilc_connected_SSID); + eth_zero_addr(wilc_connected_ssid); if (!pstrWFIDrv->p2p_connect) wlan_channel = INVALID_CHANNEL; -- GitLab From d14991afe0a84900cfd51d63d2c142b6b36d3e26 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:22 +0900 Subject: [PATCH 1657/2855] staging: wilc1000: clear_shadow_scan: remove unused argument This patch removes pUserVoid that is first argument of clear_shadow_scan function because it is not used in this function. Remove argument in the function call also. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 718b060463990..e72608b0df423 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -202,7 +202,7 @@ static bool g_wep_keys_saved; #define AGING_TIME (9 * 1000) #define during_ip_time 15000 -static void clear_shadow_scan(void *pUserVoid) +static void clear_shadow_scan(void) { int i; @@ -3523,7 +3523,7 @@ int wilc_deinit_host_int(struct net_device *net) s32Error = wilc_deinit(priv->hWILCWFIDrv); /* Clear the Shadow scan */ - clear_shadow_scan(priv); + clear_shadow_scan(); if (op_ifcs == 0) { PRINT_D(CORECONFIG_DBG, "destroy during ip\n"); del_timer_sync(&wilc_during_ip_timer); -- GitLab From 84df0e6d718239cc5839d817ea30dbe26dd69cb2 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:23 +0900 Subject: [PATCH 1658/2855] staging: wilc1000: rename pUserVoid in refresh_scan function This patch renames pUserVoid to user_void that is first argument of refresh_scan function to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index e72608b0df423..e987e78217eaa 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -237,7 +237,7 @@ static u32 get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo) return rssi_v; } -static void refresh_scan(void *pUserVoid, u8 all, bool bDirectScan) +static void refresh_scan(void *user_void, u8 all, bool bDirectScan) { struct wilc_priv *priv; struct wiphy *wiphy; @@ -245,7 +245,7 @@ static void refresh_scan(void *pUserVoid, u8 all, bool bDirectScan) int i; int rssi = 0; - priv = (struct wilc_priv *)pUserVoid; + priv = (struct wilc_priv *)user_void; wiphy = priv->dev->ieee80211_ptr->wiphy; for (i = 0; i < last_scanned_cnt; i++) { -- GitLab From 48ee7bad3e1ec0c782b4908f68e2922629d95351 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:24 +0900 Subject: [PATCH 1659/2855] staging: wilc1000: rename bDirectScan in refresh_scan function This patch renames bDirectScan to direct_scan that is third argument of refresh_scan function to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index e987e78217eaa..6f79662728f2d 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -237,7 +237,7 @@ static u32 get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo) return rssi_v; } -static void refresh_scan(void *user_void, u8 all, bool bDirectScan) +static void refresh_scan(void *user_void, u8 all, bool direct_scan) { struct wilc_priv *priv; struct wiphy *wiphy; @@ -263,7 +263,8 @@ static void refresh_scan(void *user_void, u8 all, bool bDirectScan) channel = ieee80211_get_channel(wiphy, s32Freq); rssi = get_rssi_avg(pstrNetworkInfo); - if (memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) || bDirectScan) { + if (memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) || + direct_scan) { bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs, (size_t)pstrNetworkInfo->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL); -- GitLab From ce3b1b5a85e846c3d5b307b7aa614ccbd19e9d52 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:25 +0900 Subject: [PATCH 1660/2855] staging: wilc1000: rename pstrNetworkInfo variable This patch renames pstrNetworkInfo variable to network_info to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 6f79662728f2d..9416644a2e072 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -249,25 +249,24 @@ static void refresh_scan(void *user_void, u8 all, bool direct_scan) wiphy = priv->dev->ieee80211_ptr->wiphy; for (i = 0; i < last_scanned_cnt; i++) { - tstrNetworkInfo *pstrNetworkInfo; + tstrNetworkInfo *network_info; - pstrNetworkInfo = &last_scanned_shadow[i]; + network_info = &last_scanned_shadow[i]; - if ((!pstrNetworkInfo->u8Found) || all) { + if (!network_info->u8Found || all) { s32 s32Freq; struct ieee80211_channel *channel; - if (pstrNetworkInfo != NULL) { - - s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ); + if (network_info) { + s32Freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ); channel = ieee80211_get_channel(wiphy, s32Freq); - rssi = get_rssi_avg(pstrNetworkInfo); - if (memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) || + rssi = get_rssi_avg(network_info); + if (memcmp("DIRECT-", network_info->au8ssid, 7) || direct_scan) { - bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo, - pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs, - (size_t)pstrNetworkInfo->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL); + bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo, + network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs, + (size_t)network_info->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL); cfg80211_put_bss(wiphy, bss); } } -- GitLab From c6f5e3a67b8afdf8623114e9d2ff57b94e3b69b1 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:26 +0900 Subject: [PATCH 1661/2855] staging: wilc1000: rename s32Freq variable This patch renames s32Freq variable to freq to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 9416644a2e072..55cf444d37265 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -254,12 +254,12 @@ static void refresh_scan(void *user_void, u8 all, bool direct_scan) network_info = &last_scanned_shadow[i]; if (!network_info->u8Found || all) { - s32 s32Freq; + s32 freq; struct ieee80211_channel *channel; if (network_info) { - s32Freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ); - channel = ieee80211_get_channel(wiphy, s32Freq); + freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ); + channel = ieee80211_get_channel(wiphy, freq); rssi = get_rssi_avg(network_info); if (memcmp("DIRECT-", network_info->au8ssid, 7) || -- GitLab From 12b0138b2a3f6e526ab23f3e46a357910183534d Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:27 +0900 Subject: [PATCH 1662/2855] staging: wilc1000: reset_shadow_found: remove unused argument This patch removes pUserVoid that is first argument of reset_shadow_found function because it is not used in this function. Remove argument in the function call also. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 55cf444d37265..50327056ca866 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -276,7 +276,7 @@ static void refresh_scan(void *user_void, u8 all, bool direct_scan) } -static void reset_shadow_found(void *pUserVoid) +static void reset_shadow_found(void) { int i; @@ -731,9 +731,7 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) priv->u32RcvdChCount = 0; wilc_set_wfi_drv_handler(priv->hWILCWFIDrv); - - - reset_shadow_found(priv); + reset_shadow_found(); priv->bCfgScanning = true; if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */ -- GitLab From 5e51d8ba0badb84cada670436dffb05761042ec3 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:28 +0900 Subject: [PATCH 1663/2855] staging: wilc1000: update_scan_time: remove unused argument This patch removes pUserVoid that is first argument of update_scan_time function because it is not used in this function. Remove argument in the function call also. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 50327056ca866..56005f6e51745 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -284,7 +284,7 @@ static void reset_shadow_found(void) last_scanned_shadow[i].u8Found = 0; } -static void update_scan_time(void *pUserVoid) +static void update_scan_time(void) { int i; @@ -523,8 +523,7 @@ static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNet PRINT_D(CFG80211_DBG, "Scan Aborted\n"); if (priv->pstrScanReq != NULL) { - - update_scan_time(priv); + update_scan_time(); refresh_scan(priv, 1, false); cfg80211_scan_done(priv->pstrScanReq, false); -- GitLab From 157814f07d994cd892da332f6ba0ab7f912b1a3a Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:29 +0900 Subject: [PATCH 1664/2855] staging: wilc1000: rename pUserVoid in is_network_in_shadow function This patch renames pUserVoid to user_void that is second argument of is_network_in_shadow function to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 56005f6e51745..5a9d0e23dffcf 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -330,14 +330,15 @@ static void clear_duringIP(unsigned long arg) wilc_optaining_ip = false; } -static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid) +static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, + void *user_void) { int state = -1; int i; if (last_scanned_cnt == 0) { PRINT_D(CFG80211_DBG, "Starting Aging timer\n"); - hAgingTimer.data = (unsigned long)pUserVoid; + hAgingTimer.data = (unsigned long)user_void; mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME)); state = -1; } else { -- GitLab From 5c4cf0dda6dc941a515a91c5c94a56546576f0e3 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:30 +0900 Subject: [PATCH 1665/2855] staging: wilc1000: rename pUserVoid in add_network_to_shadow function This patch renames pUserVoid to user_void that is second argument of add_network_to_shadow function to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 5a9d0e23dffcf..7905f37c241b3 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -354,9 +354,10 @@ static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, return state; } -static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams) +static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, + void *user_void, void *pJoinParams) { - int ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid); + int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void); u32 ap_index = 0; u8 rssi_index = 0; -- GitLab From 1a4c8ce78438bc4a61dd3fce5dc5a52a0f356d80 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:31 +0900 Subject: [PATCH 1666/2855] staging: wilc1000: rename enuScanEvent in CfgScanResult function This patch renames enuScanEvent to scan_event that is first argument of CfgScanResult function to avoid camelcase. And, remove the relation comment. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 7905f37c241b3..646beff5d73fa 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -419,7 +419,10 @@ static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, * @date * @version 1.0 */ -static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams) +static void CfgScanResult(enum scan_event scan_event, + tstrNetworkInfo *pstrNetworkInfo, + void *pUserVoid, + void *pJoinParams) { struct wilc_priv *priv; struct wiphy *wiphy; @@ -429,7 +432,7 @@ static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNet priv = (struct wilc_priv *)pUserVoid; if (priv->bCfgScanning) { - if (enuScanEvent == SCAN_EVENT_NETWORK_FOUND) { + if (scan_event == SCAN_EVENT_NETWORK_FOUND) { wiphy = priv->dev->ieee80211_ptr->wiphy; if (!wiphy) @@ -498,7 +501,7 @@ static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNet } } } - } else if (enuScanEvent == SCAN_EVENT_DONE) { + } else if (scan_event == SCAN_EVENT_DONE) { PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev); PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n"); refresh_scan(priv, 1, false); @@ -517,10 +520,7 @@ static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNet priv->pstrScanReq = NULL; } up(&(priv->hSemScanReq)); - - } - /*Aborting any scan operation during mac close*/ - else if (enuScanEvent == SCAN_EVENT_ABORTED) { + } else if (scan_event == SCAN_EVENT_ABORTED) { down(&(priv->hSemScanReq)); PRINT_D(CFG80211_DBG, "Scan Aborted\n"); -- GitLab From 0551a72e6970b91451572c9328af0a33ee8f8bdc Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:32 +0900 Subject: [PATCH 1667/2855] staging: wilc1000: rename pstrNetworkInfo in CfgScanResult function This patch renames pstrNetworkInfo to network_info that is second argument of CfgScanResult function to avoid camelcase. And, remove the relation comment. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 41 ++++++++----------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 646beff5d73fa..b0d1ed36b6672 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -420,7 +420,7 @@ static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, * @version 1.0 */ static void CfgScanResult(enum scan_event scan_event, - tstrNetworkInfo *pstrNetworkInfo, + tstrNetworkInfo *network_info, void *pUserVoid, void *pJoinParams) { @@ -438,33 +438,27 @@ static void CfgScanResult(enum scan_event scan_event, if (!wiphy) return; - if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC - && - ((((s32)pstrNetworkInfo->s8rssi) * 100) < 0 - || - (((s32)pstrNetworkInfo->s8rssi) * 100) > 100) - ) { + if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC && + (((s32)network_info->s8rssi * 100) < 0 || + ((s32)network_info->s8rssi * 100) > 100)) { PRINT_ER("wiphy signal type fial\n"); return; } - if (pstrNetworkInfo != NULL) { - s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ); + if (network_info) { + s32Freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ); channel = ieee80211_get_channel(wiphy, s32Freq); if (!channel) return; PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d," - "BeaconPeriod: %d\n", channel->center_freq, (((s32)pstrNetworkInfo->s8rssi) * 100), - pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod); + "BeaconPeriod: %d\n", channel->center_freq, (((s32)network_info->s8rssi) * 100), + network_info->u16CapInfo, network_info->u16BeaconPeriod); - if (pstrNetworkInfo->bNewNetwork) { + if (network_info->bNewNetwork) { if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */ - /* max_scan_ssids */ - PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid); - - + PRINT_D(CFG80211_DBG, "Network %s found\n", network_info->au8ssid); priv->u32RcvdChCount++; @@ -472,14 +466,13 @@ static void CfgScanResult(enum scan_event scan_event, if (pJoinParams == NULL) { PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n"); } - add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams); + add_network_to_shadow(network_info, priv, pJoinParams); /*P2P peers are sent to WPA supplicant and added to shadow table*/ - - if (!(memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) { - bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo, - pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs, - (size_t)pstrNetworkInfo->u16IEsLen, (((s32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL); + if (!(memcmp("DIRECT-", network_info->au8ssid, 7))) { + bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo, + network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs, + (size_t)network_info->u16IEsLen, (((s32)network_info->s8rssi) * 100), GFP_KERNEL); cfg80211_put_bss(wiphy, bss); } @@ -491,10 +484,10 @@ static void CfgScanResult(enum scan_event scan_event, u32 i; /* So this network is discovered before, we'll just update its RSSI */ for (i = 0; i < priv->u32RcvdChCount; i++) { - if (memcmp(last_scanned_shadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) { + if (memcmp(last_scanned_shadow[i].au8bssid, network_info->au8bssid, 6) == 0) { PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid); - last_scanned_shadow[i].s8rssi = pstrNetworkInfo->s8rssi; + last_scanned_shadow[i].s8rssi = network_info->s8rssi; last_scanned_shadow[i].u32TimeRcvdInScan = jiffies; break; } -- GitLab From 30cd10c466a26c215e2a10b07d8a9c7e94ed519c Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:33 +0900 Subject: [PATCH 1668/2855] staging: wilc1000: rename pUserVoid in CfgScanResult function This patch renames pUserVoid to user_void that is third argument of CfgScanResult function to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index b0d1ed36b6672..0b03e54f3568b 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -421,7 +421,7 @@ static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, */ static void CfgScanResult(enum scan_event scan_event, tstrNetworkInfo *network_info, - void *pUserVoid, + void *user_void, void *pJoinParams) { struct wilc_priv *priv; @@ -430,7 +430,7 @@ static void CfgScanResult(enum scan_event scan_event, struct ieee80211_channel *channel; struct cfg80211_bss *bss = NULL; - priv = (struct wilc_priv *)pUserVoid; + priv = (struct wilc_priv *)user_void; if (priv->bCfgScanning) { if (scan_event == SCAN_EVENT_NETWORK_FOUND) { wiphy = priv->dev->ieee80211_ptr->wiphy; -- GitLab From bdd3460f77452392b2e29932133f1b43c6d5eede Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:34 +0900 Subject: [PATCH 1669/2855] staging: wilc1000: rename pJoinParams in CfgScanResult function This patch renames pJoinParams to join_params that is fourth argument of CfgScanResult function to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 0b03e54f3568b..a429167a9bf59 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -422,7 +422,7 @@ static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, static void CfgScanResult(enum scan_event scan_event, tstrNetworkInfo *network_info, void *user_void, - void *pJoinParams) + void *join_params) { struct wilc_priv *priv; struct wiphy *wiphy; @@ -461,12 +461,9 @@ static void CfgScanResult(enum scan_event scan_event, PRINT_D(CFG80211_DBG, "Network %s found\n", network_info->au8ssid); priv->u32RcvdChCount++; - - - if (pJoinParams == NULL) { + if (!join_params) PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n"); - } - add_network_to_shadow(network_info, priv, pJoinParams); + add_network_to_shadow(network_info, priv, join_params); /*P2P peers are sent to WPA supplicant and added to shadow table*/ if (!(memcmp("DIRECT-", network_info->au8ssid, 7))) { -- GitLab From 0b8bea1cac363cd7de8b1a23b91b0b436cc03d15 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Thu, 19 Nov 2015 15:56:35 +0900 Subject: [PATCH 1670/2855] staging: wilc1000: rename pstrNetworkInfo in get_rssi_avg function This patch renames pstrNetworkInfo to network_info that is first argument of get_rssi_avg function to avoid camelcase. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index a429167a9bf59..bcfddbfe7e9b8 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -224,14 +224,14 @@ static void clear_shadow_scan(void) } -static u32 get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo) +static u32 get_rssi_avg(tstrNetworkInfo *network_info) { u8 i; int rssi_v = 0; - u8 num_rssi = (pstrNetworkInfo->strRssi.u8Full) ? NUM_RSSI : (pstrNetworkInfo->strRssi.u8Index); + u8 num_rssi = (network_info->strRssi.u8Full) ? NUM_RSSI : (network_info->strRssi.u8Index); for (i = 0; i < num_rssi; i++) - rssi_v += pstrNetworkInfo->strRssi.as8RSSI[i]; + rssi_v += network_info->strRssi.as8RSSI[i]; rssi_v /= num_rssi; return rssi_v; -- GitLab From 604f6e2dae1c502018c32dd9e8de92767268eaa5 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 20 Nov 2015 16:56:31 +0900 Subject: [PATCH 1671/2855] staging: wilc1000: remove unused variable wilc_sdio_func is not used anymore so just delete it. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_sdio.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index 92633aa2c0bbe..ae31f7d896938 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -11,8 +11,6 @@ #define SDIO_MODALIAS "wilc1000_sdio" -static struct sdio_func *wilc_sdio_func; - #define SDIO_VENDOR_ID_WILC 0x0296 #define SDIO_DEVICE_ID_WILC 0x5347 @@ -105,7 +103,6 @@ static int linux_sdio_probe(struct sdio_func *func, const struct sdio_device_id } PRINT_D(INIT_DBG, "Initializing netdev\n"); - wilc_sdio_func = func; if (wilc_netdev_init(&wilc, &func->dev, HIF_SDIO, gpio, &wilc_hif_sdio)) { PRINT_ER("Couldn't initialize netdev\n"); -- GitLab From c2ba8b2bc232721e8bddd86bfe22503b0bf5f2e5 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 20 Nov 2015 16:56:32 +0900 Subject: [PATCH 1672/2855] staging: wilc1000: return linux error value Return proper linux error value -ETIMEDOUT instead of -1. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/coreconfigurator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/coreconfigurator.c b/drivers/staging/wilc1000/coreconfigurator.c index 0cd2accf1a348..329477ab5adc0 100644 --- a/drivers/staging/wilc1000/coreconfigurator.c +++ b/drivers/staging/wilc1000/coreconfigurator.c @@ -601,7 +601,7 @@ s32 wilc_send_config_pkt(struct wilc *wilc, u8 mode, struct wid *wids, wids[counter].id, (counter == count - 1), drv)) { - ret = -1; + ret = -ETIMEDOUT; printk("[Sendconfigpkt]Get Timed out\n"); break; } @@ -622,7 +622,7 @@ s32 wilc_send_config_pkt(struct wilc *wilc, u8 mode, struct wid *wids, wids[counter].size, (counter == count - 1), drv)) { - ret = -1; + ret = -ETIMEDOUT; printk("[Sendconfigpkt]Set Timed out\n"); break; } -- GitLab From 6f72ed75e5c572640ca45b439f27ffbb0a50e8c8 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Wed, 25 Nov 2015 11:59:40 +0900 Subject: [PATCH 1673/2855] staging: wilc1000: fix rmmod failure This patch fixes rmmod failure. wilc->firmware needs to be set to NULL because it is used again to check firmware is released when module exit. Fixes: 8b8ad7bc90bc ("staging: wilc1000: rename wilc_firmware in the struct wilc") Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 73954f468ae8e..d1c3e4c10d02e 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -506,6 +506,7 @@ static int wilc1000_firmware_download(struct net_device *dev) PRINT_D(INIT_DBG, "Freeing FW buffer ...\n"); PRINT_D(INIT_DBG, "Releasing firmware\n"); release_firmware(wilc->firmware); + wilc->firmware = NULL; PRINT_D(INIT_DBG, "Download Succeeded\n"); -- GitLab From a89f7c551af21058ee0a2d5a425d410fc1abfc13 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Wed, 25 Nov 2015 11:59:41 +0900 Subject: [PATCH 1674/2855] staging: wilc1000: wilc_wfi_cfgoperations.c: remove over-commenting There are over-commenting in the wilc_wfi_cfgoperations.c file and most of them are not helpful to explain what the code does and generate 80 ending line over warnings. So, all of comments are removed in this patch and the comments will later be added if necessary with the preferred Linux style. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 681 +----------------- 1 file changed, 23 insertions(+), 658 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index bcfddbfe7e9b8..bfef022c315b5 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -1,20 +1,7 @@ -/*! - * @file wilc_wfi_cfgopertaions.c - * @brief CFG80211 Function Implementation functionality - * @author aabouzaeid - * mabubakr - * mdaftedar - * zsalah - * @sa wilc_wfi_cfgopertaions.h top level OS wrapper file - * @date 31 Aug 2010 - * @version 1.0 - */ - #include "wilc_wfi_cfgoperations.h" #include "host_interface.h" #include -/* The following macros describe the bitfield map used by the firmware to determine its 11i mode */ #define NO_ENCRYPT 0 #define ENCRYPT_ENABLED BIT(0) #define WEP BIT(1) @@ -24,13 +11,11 @@ #define AES BIT(5) #define TKIP BIT(6) -/*Public action frame index IDs*/ #define FRAME_TYPE_ID 0 #define ACTION_CAT_ID 24 #define ACTION_SUBTYPE_ID 25 #define P2P_PUB_ACTION_SUBTYPE 30 -/*Public action frame Attribute IDs*/ #define ACTION_FRAME 0xd0 #define GO_INTENT_ATTR_ID 0x04 #define CHANLIST_ATTR_ID 0x0b @@ -38,7 +23,6 @@ #define PUB_ACTION_ATTR_ID 0x04 #define P2PELEM_ATTR_ID 0xdd -/*Public action subtype values*/ #define GO_NEG_REQ 0x00 #define GO_NEG_RSP 0x01 #define GO_NEG_CONF 0x02 @@ -90,7 +74,6 @@ static const struct ieee80211_txrx_stypes } }; -/* Time to stay on the channel */ #define WILC_WFI_DWELL_PASSIVE 100 #define WILC_WFI_DWELL_ACTIVE 40 @@ -123,7 +106,6 @@ u8 wilc_initialized = 1; .max_power = 30, \ } -/*Frequency range for channels*/ static struct ieee80211_channel ieee80211_2ghz_channels[] = { CHAN2G(1, 2412, 0), CHAN2G(2, 2417, 0), @@ -147,8 +129,6 @@ static struct ieee80211_channel ieee80211_2ghz_channels[] = { .flags = (_flags), \ } - -/* Table 6 in section 3.2.1.1 */ static struct ieee80211_rate ieee80211_bitrates[] = { RATETAB_ENT(10, 0, 0), RATETAB_ENT(20, 1, 0), @@ -342,7 +322,6 @@ static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME)); state = -1; } else { - /* Linear search for now */ for (i = 0; i < last_scanned_cnt; i++) { if (memcmp(last_scanned_shadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) { @@ -394,7 +373,7 @@ static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, if (ap_found != -1) kfree(last_scanned_shadow[ap_index].pu8IEs); last_scanned_shadow[ap_index].pu8IEs = - kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); /* will be deallocated by the WILC_WFI_CfgScan() function */ + kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); memcpy(last_scanned_shadow[ap_index].pu8IEs, pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen); last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies; @@ -405,20 +384,6 @@ static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, last_scanned_shadow[ap_index].pJoinParams = pJoinParams; } - -/** - * @brief CfgScanResult - * @details Callback function which returns the scan results found - * - * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is - * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE - * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information - * void* pUserVoid: Private structure associated with the wireless interface - * @return NONE - * @author mabubakr - * @date - * @version 1.0 - */ static void CfgScanResult(enum scan_event scan_event, tstrNetworkInfo *network_info, void *user_void, @@ -457,7 +422,7 @@ static void CfgScanResult(enum scan_event scan_event, network_info->u16CapInfo, network_info->u16BeaconPeriod); if (network_info->bNewNetwork) { - if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */ + if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { PRINT_D(CFG80211_DBG, "Network %s found\n", network_info->au8ssid); priv->u32RcvdChCount++; @@ -465,7 +430,6 @@ static void CfgScanResult(enum scan_event scan_event, PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n"); add_network_to_shadow(network_info, priv, join_params); - /*P2P peers are sent to WPA supplicant and added to shadow table*/ if (!(memcmp("DIRECT-", network_info->au8ssid, 7))) { bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo, network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs, @@ -479,7 +443,7 @@ static void CfgScanResult(enum scan_event scan_event, } } else { u32 i; - /* So this network is discovered before, we'll just update its RSSI */ + for (i = 0; i < priv->u32RcvdChCount; i++) { if (memcmp(last_scanned_shadow[i].au8bssid, network_info->au8bssid, 6) == 0) { PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid); @@ -527,21 +491,6 @@ static void CfgScanResult(enum scan_event scan_event, } } - -/** - * @brief CfgConnectResult - * @details - * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either - * connection response or disconnection notification. - * tstrConnectInfo* pstrConnectInfo: COnnection information. - * u8 u8MacStatus: Mac Status from firmware - * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification - * void* pUserVoid: Private data associated with wireless interface - * @return NONE - * @author mabubakr - * @date 01 MAR 2012 - * @version 1.0 - */ int wilc_connecting; static void CfgConnectResult(enum conn_event enuConnDisconnEvent, @@ -566,7 +515,6 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv; if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) { - /*Initialization*/ u16 u16ConnectStatus; u16ConnectStatus = pstrConnectInfo->u16ConnectStatus; @@ -575,8 +523,6 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, if ((u8MacStatus == MAC_DISCONNECTED) && (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) { - /* The case here is that our station was waiting for association response frame and has just received it containing status code - * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */ u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE; wilc_wlan_set_bssid(priv->dev, NullBssid); eth_zero_addr(wilc_connected_ssid); @@ -610,12 +556,8 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, } } - if (bNeedScanRefresh) { - /*Also, refrsh DIRECT- results if */ + if (bNeedScanRefresh) refresh_scan(priv, 1, true); - - } - } @@ -626,8 +568,7 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, cfg80211_connect_result(dev, pstrConnectInfo->au8bssid, pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen, pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen, - u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */ - /* be replaced by pstrConnectInfo->u16ConnectStatus */ + u16ConnectStatus, GFP_KERNEL); } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) { wilc_optaining_ip = false; PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n", @@ -641,14 +582,9 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, if (!pstrWFIDrv->p2p_connect) wlan_channel = INVALID_CHANNEL; - /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change - * virtual interface to station*/ if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) { pstrDisconnectNotifInfo->u16reason = 3; - } - /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT - * to scan again and retry the connection*/ - else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) { + } else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) { pstrDisconnectNotifInfo->u16reason = 1; } cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie, @@ -659,20 +595,6 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, } - -/** - * @brief set_channel - * @details Set channel for a given wireless interface. Some devices - * may support multi-channel operation (by channel hopping) so cfg80211 - * doesn't verify much. Note, however, that the passed netdev may be - * %NULL as well if the user requested changing the channel for the - * device itself, or for a monitor interface. - * @param[in] - * @return int : Return 0 on Success - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int set_channel(struct wiphy *wiphy, struct cfg80211_chan_def *chandef) { @@ -694,19 +616,6 @@ static int set_channel(struct wiphy *wiphy, return result; } -/** - * @brief scan - * @details Request to do a scan. If returning zero, the scan request is given - * the driver, and will be valid until passed to cfg80211_scan_done(). - * For scan results, call cfg80211_inform_bss(); you can call this outside - * the scan/scan_done bracket too. - * @param[in] - * @return int : Return 0 on Success - * @author mabubakr - * @date 01 MAR 2012 - * @version 1.0 - */ - static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) { struct wilc_priv *priv; @@ -725,8 +634,7 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) reset_shadow_found(); priv->bCfgScanning = true; - if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */ - /* max_scan_ssids */ + if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { for (i = 0; i < request->n_channels; i++) { au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq); PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]); @@ -781,18 +689,6 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) return s32Error; } -/** - * @brief connect - * @details Connect to the ESS with the specified parameters. When connected, - * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS. - * If the connection fails for some reason, call cfg80211_connect_result() - * with the status from the AP. - * @param[in] - * @return int : Return 0 on Success - * @author mabubakr - * @date 01 MAR 2012 - * @version 1.0 - */ static int connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) { @@ -831,13 +727,9 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, sme->ssid_len) == 0) { PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid); if (sme->bssid == NULL) { - /* BSSID is not passed from the user, so decision of matching - * is done by SSID only */ PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n"); break; } else { - /* BSSID is also passed from the user, so decision of matching - * should consider also this passed BSSID */ if (memcmp(last_scanned_shadow[i].au8bssid, sme->bssid, ETH_ALEN) == 0) { @@ -882,8 +774,6 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, } if (sme->crypto.cipher_group != NO_ENCRYPT) { - /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2} - * we will add to it the pairwise cipher suite(s) */ pcwpa_version = "Default"; PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions); if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) { @@ -930,8 +820,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, u8security = ENCRYPT_ENABLED | WPA2 | TKIP; pcgroup_encrypt_val = "WPA2_TKIP"; pccipher_group = "TKIP"; - } else { /* TODO: mostafa: here we assume that any other encryption type is AES */ - /* tenuSecurity_t = WPA2_AES; */ + } else { u8security = ENCRYPT_ENABLED | WPA2 | AES; pcgroup_encrypt_val = "WPA2_AES"; pccipher_group = "AES"; @@ -942,8 +831,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, u8security = ENCRYPT_ENABLED | WPA | TKIP; pcgroup_encrypt_val = "WPA_TKIP"; pccipher_group = "TKIP"; - } else { /* TODO: mostafa: here we assume that any other encryption type is AES */ - /* tenuSecurity_t = WPA_AES; */ + } else { u8security = ENCRYPT_ENABLED | WPA | AES; pcgroup_encrypt_val = "WPA_AES"; pccipher_group = "AES"; @@ -960,14 +848,12 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, } - /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will - * add to it the pairwise cipher suite(s) */ if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) { for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) { if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) { u8security = u8security | TKIP; - } else { /* TODO: mostafa: here we assume that any other encryption type is AES */ + } else { u8security = u8security | AES; } } @@ -991,8 +877,6 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type); } - - /* ai: key_mgmt: enterprise case */ if (sme->crypto.n_akm_suites) { switch (sme->crypto.akm_suites[0]) { case WLAN_AKM_SUITE_8021X: @@ -1033,16 +917,6 @@ done: return s32Error; } - -/** - * @brief disconnect - * @details Disconnect from the BSS/ESS. - * @param[in] - * @return int : Return 0 on Success - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code) { s32 s32Error = 0; @@ -1074,16 +948,6 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_co return s32Error; } -/** - * @brief add_key - * @details Add a key with the given parameters. @mac_addr will be %NULL - * when adding a group key. - * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key - * @return int : Return 0 on Success - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) @@ -1187,13 +1051,10 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, pu8RxMic = params->key + 16; KeyLen = params->key_len - 16; } - /* if there has been previous allocation for the same index through its key, free that memory and allocate again*/ kfree(priv->wilc_gtk[key_index]->key); priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL); memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len); - - /* if there has been previous allocation for the same index through its seq, free that memory and allocate again*/ kfree(priv->wilc_gtk[key_index]->seq); if ((params->seq_len) > 0) { @@ -1268,13 +1129,11 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, u8mode = 0; if (!pairwise) { if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) { - /* swap the tx mic by rx mic */ pu8RxMic = params->key + 24; pu8TxMic = params->key + 16; KeyLen = params->key_len - 16; } - /*save keys only on interface 0 (wifi interface)*/ if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) { g_add_gtk_key_params.key_idx = key_index; g_add_gtk_key_params.pairwise = pairwise; @@ -1304,13 +1163,11 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode); } else { if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) { - /* swap the tx mic by rx mic */ pu8RxMic = params->key + 24; pu8TxMic = params->key + 16; KeyLen = params->key_len - 16; } - /*save keys only on interface 0 (wifi interface)*/ if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) { g_add_ptk_key_params.key_idx = key_index; g_add_ptk_key_params.pairwise = pairwise; @@ -1356,16 +1213,6 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, return s32Error; } -/** - * @brief del_key - * @details Remove a key given the @mac_addr (%NULL for a group key) - * and @key_index, return -ENOENT if the key doesn't exist. - * @param[in] - * @return int : Return 0 on Success - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int del_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool pairwise, @@ -1379,18 +1226,14 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev, nic = netdev_priv(netdev); wl = nic->wilc; - /*delete saved keys, if any*/ if (netdev == wl->vif[0].ndev) { g_ptk_keys_saved = false; g_gtk_keys_saved = false; g_wep_keys_saved = false; - /*Delete saved WEP keys params, if any*/ kfree(g_key_wep_params.key); g_key_wep_params.key = NULL; - /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/ - if ((priv->wilc_gtk[key_index]) != NULL) { kfree(priv->wilc_gtk[key_index]->key); @@ -1413,7 +1256,6 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev, priv->wilc_ptk[key_index] = NULL; } - /*Delete saved PTK and GTK keys params, if any*/ kfree(g_key_ptk_params.key); g_key_ptk_params.key = NULL; kfree(g_key_ptk_params.seq); @@ -1424,7 +1266,6 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev, kfree(g_key_gtk_params.seq); g_key_gtk_params.seq = NULL; - /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/ wilc_set_machw_change_vir_if(netdev, false); } @@ -1442,19 +1283,6 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev, return 0; } -/** - * @brief get_key - * @details Get information about the key with the given parameters. - * @mac_addr will be %NULL when requesting information for a group - * key. All pointers given to the @callback function need not be valid - * after it returns. This function should return an error if it is - * not possible to retrieve the key, -ENOENT if it doesn't exist. - * @param[in] - * @return int : Return 0 on Success - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool pairwise, const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *)) @@ -1490,18 +1318,9 @@ static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, callback(cookie, &key_params); - return 0; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */ + return 0; } -/** - * @brief set_default_key - * @details Set the default management frame key on an interface - * @param[in] - * @return int : Return 0 on Success. - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool unicast, bool multicast) { @@ -1520,16 +1339,6 @@ static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 ke return 0; } -/** - * @brief get_station - * @details Get station information for the station identified by @mac - * @param[in] NONE - * @return int : Return 0 on Success. - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ - static int get_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac, struct station_info *sinfo) { @@ -1597,28 +1406,6 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, return 0; } - -/** - * @brief change_bss - * @details Modify parameters for a given BSS. - * @param[in] - * -use_cts_prot: Whether to use CTS protection - * (0 = no, 1 = yes, -1 = do not change) - * -use_short_preamble: Whether the use of short preambles is allowed - * (0 = no, 1 = yes, -1 = do not change) - * -use_short_slot_time: Whether the use of short slot time is allowed - * (0 = no, 1 = yes, -1 = do not change) - * -basic_rates: basic rates in IEEE 802.11 format - * (or NULL for no change) - * -basic_rates_len: number of basic rates - * -ap_isolate: do not forward packets between connected stations - * -ht_opmode: HT Operation mode - * (u16 = opmode, -1 = do not change) - * @return int : Return 0 on Success. - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int change_bss(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params) { @@ -1626,16 +1413,6 @@ static int change_bss(struct wiphy *wiphy, struct net_device *dev, return 0; } -/** - * @brief set_wiphy_params - * @details Notify that wiphy parameters have changed; - * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values - * have changed. - * @return int : Return 0 on Success - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int set_wiphy_params(struct wiphy *wiphy, u32 changed) { s32 s32Error = 0; @@ -1684,17 +1461,6 @@ static int set_wiphy_params(struct wiphy *wiphy, u32 changed) return s32Error; } -/** - * @brief set_pmksa - * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac - * devices running firmwares capable of generating the (re) association - * RSN IE. It allows for faster roaming between WPA2 BSSIDs. - * @param[in] - * @return int : Return 0 on Success - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev, struct cfg80211_pmksa *pmksa) { @@ -1710,7 +1476,6 @@ static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev, for (i = 0; i < priv->pmkid_list.numpmkid; i++) { if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid, ETH_ALEN)) { - /*If bssid already exists and pmkid value needs to reset*/ flag = PMKID_FOUND; PRINT_D(CFG80211_DBG, "PMKID already exists\n"); break; @@ -1736,15 +1501,6 @@ static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev, return s32Error; } -/** - * @brief del_pmksa - * @details Delete a cached PMKID. - * @param[in] - * @return int : Return 0 on Success - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev, struct cfg80211_pmksa *pmksa) { @@ -1759,7 +1515,6 @@ static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev, for (i = 0; i < priv->pmkid_list.numpmkid; i++) { if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid, ETH_ALEN)) { - /*If bssid is found, reset the values*/ PRINT_D(CFG80211_DBG, "Reseting PMKID values\n"); memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid)); break; @@ -1783,42 +1538,17 @@ static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev, return s32Error; } -/** - * @brief flush_pmksa - * @details Flush all cached PMKIDs. - * @param[in] - * @return int : Return 0 on Success - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) { struct wilc_priv *priv = wiphy_priv(wiphy); PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n"); - /*Get cashed Pmkids and set all with zeros*/ memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr)); return 0; } - -/** - * @brief WILC_WFI_CfgParseRxAction - * @details Function parses the received frames and modifies the following attributes: - * -GO Intent - * -Channel list - * -Operating Channel - * - * @param[in] u8* Buffer, u32 length - * @return NONE. - * @author mdaftedar - * @date 12 DEC 2012 - * @version - */ - static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len) { u32 index = 0; @@ -1836,10 +1566,9 @@ static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len) channel_list_attr_index = index; else if (buf[index] == OPERCHAN_ATTR_ID) op_channel_attr_index = index; - index += buf[index + 1] + 3; /* ID,Length byte */ + index += buf[index + 1] + 3; } if (wlan_channel != INVALID_CHANNEL) { - /*Modify channel list attribute*/ if (channel_list_attr_index) { PRINT_D(GENERIC_DBG, "Modify channel list attribute\n"); for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) { @@ -1851,7 +1580,7 @@ static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len) } } } - /*Modify operating channel attribute*/ + if (op_channel_attr_index) { PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n"); buf[op_channel_attr_index + 6] = 0x51; @@ -1860,16 +1589,6 @@ static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len) } } -/** - * @brief WILC_WFI_CfgParseTxAction - * @details Function parses the transmitted action frames and modifies the - * GO Intent attribute - * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype - * @return NONE. - * @author mdaftedar - * @date 12 DEC 2012 - * @version - */ static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype) { u32 index = 0; @@ -1889,10 +1608,9 @@ static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftyp channel_list_attr_index = index; else if (buf[index] == OPERCHAN_ATTR_ID) op_channel_attr_index = index; - index += buf[index + 1] + 3; /* ID,Length byte */ + index += buf[index + 1] + 3; } if (wlan_channel != INVALID_CHANNEL && bOperChan) { - /*Modify channel list attribute*/ if (channel_list_attr_index) { PRINT_D(GENERIC_DBG, "Modify channel list attribute\n"); for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) { @@ -1904,7 +1622,7 @@ static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftyp } } } - /*Modify operating channel attribute*/ + if (op_channel_attr_index) { PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n"); buf[op_channel_attr_index + 6] = 0x51; @@ -1913,16 +1631,6 @@ static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftyp } } -/* @brief WILC_WFI_p2p_rx - * @details - * @param[in] - * - * @return None - * @author Mai Daftedar - * @date 2 JUN 2013 - * @version 1.0 - */ - void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) { @@ -1935,11 +1643,8 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) priv = wiphy_priv(dev->ieee80211_ptr->wiphy); pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv; - /* Get WILC header */ memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET); - /* The packet offset field conain info about what type of managment frame */ - /* we are dealing with and ack status */ pkt_offset = GET_PKT_OFFSET(header); if (pkt_offset & IS_MANAGMEMENT_CALLBACK) { @@ -1963,7 +1668,6 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]); - /*Upper layer is informed that the frame is received on this freq*/ s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ); if (ieee80211_is_action(buff[FRAME_TYPE_ID])) { @@ -2016,7 +1720,6 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (wilc_ie)) { PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n"); - /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */ cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0); return; } @@ -2033,16 +1736,6 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) } } -/** - * @brief WILC_WFI_mgmt_tx_complete - * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here) - * @param[in] priv - * transmitting status - * @return None - * @author Amr Abdelmoghny - * @date 20 MAY 2013 - * @version 1.0 - */ static void WILC_WFI_mgmt_tx_complete(void *priv, int status) { struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv; @@ -2052,16 +1745,6 @@ static void WILC_WFI_mgmt_tx_complete(void *priv, int status) kfree(pv_data); } -/** - * @brief WILC_WFI_RemainOnChannelReady - * @details Callback function, called from handle_remain_on_channel on being ready on channel - * @param - * @return none - * @author Amr abdelmoghny - * @date 9 JUNE 2013 - * @version - */ - static void WILC_WFI_RemainOnChannelReady(void *pUserVoid) { struct wilc_priv *priv; @@ -2079,16 +1762,6 @@ static void WILC_WFI_RemainOnChannelReady(void *pUserVoid) GFP_KERNEL); } -/** - * @brief WILC_WFI_RemainOnChannelExpired - * @details Callback function, called on expiration of remain-on-channel duration - * @param - * @return none - * @author Amr abdelmoghny - * @date 15 MAY 2013 - * @version - */ - static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID) { struct wilc_priv *priv; @@ -2100,7 +1773,6 @@ static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID) priv->bInP2PlistenState = false; - /*Inform wpas of remain-on-channel expiration*/ cfg80211_remain_on_channel_expired(priv->wdev, priv->strRemainOnChanParams.u64ListenCookie, priv->strRemainOnChanParams.pstrListenChan, @@ -2111,20 +1783,6 @@ static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID) } } - -/** - * @brief remain_on_channel - * @details Request the driver to remain awake on the specified - * channel for the specified duration to complete an off-channel - * operation (e.g., public action frame exchange). When the driver is - * ready on the requested channel, it must indicate this with an event - * notification by calling cfg80211_ready_on_channel(). - * @param[in] - * @return int : Return 0 on Success - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, struct ieee80211_channel *chan, @@ -2145,7 +1803,6 @@ static int remain_on_channel(struct wiphy *wiphy, curr_channel = chan->hw_value; - /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/ priv->strRemainOnChanParams.pstrListenChan = chan; priv->strRemainOnChanParams.u64ListenCookie = *cookie; priv->strRemainOnChanParams.u32ListenDuration = duration; @@ -2162,19 +1819,6 @@ static int remain_on_channel(struct wiphy *wiphy, return s32Error; } -/** - * @brief cancel_remain_on_channel - * @details Cancel an on-going remain-on-channel operation. - * This allows the operation to be terminated prior to timeout based on - * the duration value. - * @param[in] struct wiphy *wiphy, - * @param[in] struct net_device *dev - * @param[in] u64 cookie, - * @return int : Return 0 on Success - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int cancel_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie) @@ -2189,16 +1833,7 @@ static int cancel_remain_on_channel(struct wiphy *wiphy, s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID); return s32Error; } -/** - * @brief WILC_WFI_mgmt_tx_frame - * @details - * - * @param[in] - * @return NONE. - * @author mdaftedar - * @date 01 JUL 2012 - * @version - */ + static int mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, struct cfg80211_mgmt_tx_params *params, @@ -2225,8 +1860,6 @@ static int mgmt_tx(struct wiphy *wiphy, mgmt = (const struct ieee80211_mgmt *) buf; if (ieee80211_is_mgmt(mgmt->frame_control)) { - - /*mgmt frame allocation*/ mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL); if (mgmt_tx == NULL) { PRINT_ER("Failed to allocate memory for mgmt_tx structure\n"); @@ -2246,22 +1879,16 @@ static int mgmt_tx(struct wiphy *wiphy, PRINT_D(GENERIC_DBG, "TX: Probe Response\n"); PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value); wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value); - /*Save the current channel after we tune to it*/ curr_channel = chan->hw_value; } else if (ieee80211_is_action(mgmt->frame_control)) { PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control); if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) { - /*Only set the channel, if not a negotiation confirmation frame - * (If Negotiation confirmation frame, force it - * to be transmitted on the same negotiation channel)*/ - if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC || buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) { PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value); wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value); - /*Save the current channel after we tune to it*/ curr_channel = chan->hw_value; } switch (buf[ACTION_SUBTYPE_ID]) { @@ -2280,7 +1907,6 @@ static int mgmt_tx(struct wiphy *wiphy, case PUBLIC_ACT_VENDORSPEC: { if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) { - /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/ if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) { if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) { get_random_bytes(&p2p_local_random, 1); @@ -2293,14 +1919,10 @@ static int mgmt_tx(struct wiphy *wiphy, if (p2p_local_random > p2p_recv_random) { PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random); - /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/ for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) { if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) { if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP) WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype); - - /*If using supplicant go intent, no need at all*/ - /*to parse transmitted negotiation frames*/ else WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype); break; @@ -2308,10 +1930,6 @@ static int mgmt_tx(struct wiphy *wiphy, } if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) { - /* - * Adding WILC information element to allow two WILC devices to - * identify each other and connect - */ memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec)); mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random; mgmt_tx->size = buf_len; @@ -2377,17 +1995,6 @@ static int mgmt_tx_cancel_wait(struct wiphy *wiphy, return 0; } -/** - * @brief wilc_mgmt_frame_register - * @details Notify driver that a management frame type was - * registered. Note that this callback may not sleep, and cannot run - * concurrently with itself. - * @param[in] - * @return NONE. - * @author mdaftedar - * @date 01 JUL 2012 - * @version - */ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, u16 frame_type, bool reg) { @@ -2425,7 +2032,7 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, } } - /*If mac is closed, then return*/ + if (!wl->initialized) { PRINT_D(GENERIC_DBG, "Return since mac is closed\n"); return; @@ -2435,18 +2042,6 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, } -/** - * @brief set_cqm_rssi_config - * @details Configure connection quality monitor RSSI threshold. - * @param[in] struct wiphy *wiphy: - * @param[in] struct net_device *dev: - * @param[in] s32 rssi_thold: - * @param[in] u32 rssi_hyst: - * @return int : Return 0 on Success - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev, s32 rssi_thold, u32 rssi_hyst) { @@ -2454,19 +2049,7 @@ static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev, return 0; } -/** - * @brief dump_station - * @details Configure connection quality monitor RSSI threshold. - * @param[in] struct wiphy *wiphy: - * @param[in] struct net_device *dev - * @param[in] int idx - * @param[in] u8 *mac - * @param[in] struct station_info *sinfo - * @return int : Return 0 on Success - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ + static int dump_station(struct wiphy *wiphy, struct net_device *dev, int idx, u8 *mac, struct station_info *sinfo) { @@ -2487,16 +2070,6 @@ static int dump_station(struct wiphy *wiphy, struct net_device *dev, } - -/** - * @brief set_power_mgmt - * @details - * @param[in] - * @return int : Return 0 on Success. - * @author mdaftedar - * @date 01 JUL 2012 - * @version 1.0 - */ static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout) { @@ -2521,16 +2094,6 @@ static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, } -/** - * @brief change_virtual_intf - * @details Change type/configuration of virtual interface, - * keep the struct wireless_dev's iftype updated. - * @param[in] NONE - * @return int : Return 0 on Success. - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, enum nl80211_iftype type, u32 *flags, struct vif_params *params) { @@ -2553,7 +2116,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, wilc_optaining_ip = false; del_timer(&wilc_during_ip_timer); PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n"); - /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/ + if (g_ptk_keys_saved && g_gtk_keys_saved) { wilc_set_machw_change_vir_if(dev, true); } @@ -2563,15 +2126,11 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, wilc_connecting = 0; PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n"); - /* send delba over wlan interface */ - - dev->ieee80211_ptr->iftype = type; priv->wdev->iftype = type; nic->monitor_flag = 0; nic->iftype = STATION_MODE; - /*Remove the enteries of the previously connected clients*/ memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN); interface_type = nic->iftype; nic->iftype = STATION_MODE; @@ -2579,10 +2138,8 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, if (wl->initialized) { wilc_del_all_rx_ba_session(priv->hWILCWFIDrv, wl->vif[0].bssid, TID); - /* ensure that the message Q is empty */ wilc_wait_msg_queue_idle(); - /*Eliminate host interface blocking state*/ up(&wl->cfg_event); wilc1000_wlan_deinit(dev); @@ -2590,13 +2147,11 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, wilc_initialized = 1; nic->iftype = interface_type; - /*Setting interface 1 drv handler and mac address in newly downloaded FW*/ wilc_set_wfi_drv_handler(wl->vif[0].hif_drv); wilc_set_mac_address(wl->vif[0].hif_drv, wl->vif[0].src_addr); wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE); - /*Add saved WEP keys, if any*/ if (g_wep_keys_saved) { wilc_set_wep_default_keyid(wl->vif[0].hif_drv, g_key_wep_params.key_idx); @@ -2606,11 +2161,8 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, g_key_wep_params.key_idx); } - /*No matter the driver handler passed here, it will be overwriiten*/ - /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/ wilc_flush_join_req(priv->hWILCWFIDrv); - /*Add saved PTK and GTK keys, if any*/ if (g_ptk_keys_saved && g_gtk_keys_saved) { PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0], g_key_ptk_params.key[1], @@ -2666,7 +2218,6 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, if (wl->initialized) { - /* ensure that the message Q is empty */ wilc_wait_msg_queue_idle(); wilc1000_wlan_deinit(dev); @@ -2678,7 +2229,6 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, wl->vif[0].src_addr); wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE); - /*Add saved WEP keys, if any*/ if (g_wep_keys_saved) { wilc_set_wep_default_keyid(wl->vif[0].hif_drv, g_key_wep_params.key_idx); @@ -2688,11 +2238,8 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, g_key_wep_params.key_idx); } - /*No matter the driver handler passed here, it will be overwriiten*/ - /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/ wilc_flush_join_req(priv->hWILCWFIDrv); - /*Add saved PTK and GTK keys, if any*/ if (g_ptk_keys_saved && g_gtk_keys_saved) { PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0], g_key_ptk_params.key[1], @@ -2715,7 +2262,6 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, (struct key_params *)(&g_key_gtk_params)); } - /*Refresh scan, to refresh the scan results to the wpa_supplicant. Set MachHw to false to enable further key installments*/ refresh_scan(priv, 1, true); wilc_set_machw_change_vir_if(dev, false); @@ -2741,7 +2287,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n"); wilc_wlan_get_firmware(dev); - /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/ + if (wl->initialized) { nic->iftype = AP_MODE; wilc_mac_close(dev); @@ -2764,10 +2310,6 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, mod_timer(&wilc_during_ip_timer, jiffies + msecs_to_jiffies(during_ip_time)); wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0); - /*Delete block ack has to be the latest config packet*/ - /*sent before downloading new FW. This is because it blocks on*/ - /*hWaitResponse semaphore, which allows previous config*/ - /*packets to actually take action on old FW*/ wilc_del_all_rx_ba_session(priv->hWILCWFIDrv, wl->vif[0].bssid, TID); wilc_enable_ps = false; @@ -2782,20 +2324,16 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, nic->iftype = GO_MODE; - /* ensure that the message Q is empty */ wilc_wait_msg_queue_idle(); wilc1000_wlan_deinit(dev); wilc1000_wlan_init(dev, nic); wilc_initialized = 1; - - /*Setting interface 1 drv handler and mac address in newly downloaded FW*/ wilc_set_wfi_drv_handler(wl->vif[0].hif_drv); wilc_set_mac_address(wl->vif[0].hif_drv, wl->vif[0].src_addr); wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE); - /*Add saved WEP keys, if any*/ if (g_wep_keys_saved) { wilc_set_wep_default_keyid(wl->vif[0].hif_drv, g_key_wep_params.key_idx); @@ -2805,11 +2343,8 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, g_key_wep_params.key_idx); } - /*No matter the driver handler passed here, it will be overwriiten*/ - /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/ wilc_flush_join_req(priv->hWILCWFIDrv); - /*Add saved PTK and GTK keys, if any*/ if (g_ptk_keys_saved && g_gtk_keys_saved) { PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0], g_key_ptk_params.key[1], @@ -2853,32 +2388,6 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, return 0; } -/* (austin.2013-07-23) - * - * To support revised cfg80211_ops - * - * add_beacon --> start_ap - * set_beacon --> change_beacon - * del_beacon --> stop_ap - * - * beacon_parameters --> cfg80211_ap_settings - * cfg80211_beacon_data - * - * applicable for linux kernel 3.4+ - */ - -/** - * @brief start_ap - * @details Add a beacon with given parameters, @head, @interval - * and @dtim_period will be valid, @tail is optional. - * @param[in] wiphy - * @param[in] dev The net device structure - * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added - * @return int : Return 0 on Success. - * @author austin - * @date 23 JUL 2013 - * @version 1.0 - */ static int start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings) { @@ -2912,18 +2421,6 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev, return s32Error; } -/** - * @brief change_beacon - * @details Add a beacon with given parameters, @head, @interval - * and @dtim_period will be valid, @tail is optional. - * @param[in] wiphy - * @param[in] dev The net device structure - * @param[in] beacon cfg80211_beacon_data for the beacon to be changed - * @return int : Return 0 on Success. - * @author austin - * @date 23 JUL 2013 - * @version 1.0 - */ static int change_beacon(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_beacon_data *beacon) { @@ -2943,15 +2440,6 @@ static int change_beacon(struct wiphy *wiphy, struct net_device *dev, return s32Error; } -/** - * @brief stop_ap - * @details Remove beacon configuration and stop sending the beacon. - * @param[in] - * @return int : Return 0 on Success. - * @author austin - * @date 23 JUL 2013 - * @version 1.0 - */ static int stop_ap(struct wiphy *wiphy, struct net_device *dev) { s32 s32Error = 0; @@ -2975,15 +2463,6 @@ static int stop_ap(struct wiphy *wiphy, struct net_device *dev) return s32Error; } -/** - * @brief add_station - * @details Add a new station. - * @param[in] - * @return int : Return 0 on Success. - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int add_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac, struct station_parameters *params) { @@ -3055,15 +2534,6 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, return s32Error; } -/** - * @brief del_station - * @details Remove a station; @mac may be NULL to remove all stations. - * @param[in] - * @return int : Return 0 on Success. - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int del_station(struct wiphy *wiphy, struct net_device *dev, struct station_del_parameters *params) { @@ -3097,15 +2567,6 @@ static int del_station(struct wiphy *wiphy, struct net_device *dev, return s32Error; } -/** - * @brief change_station - * @details Modify a given station. - * @param[in] - * @return int : Return 0 on Success. - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static int change_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac, struct station_parameters *params) { @@ -3178,16 +2639,6 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, return s32Error; } - -/** - * @brief add_virtual_intf - * @details - * @param[in] - * @return int : Return 0 on Success. - * @author mdaftedar - * @date 01 JUL 2012 - * @version 1.0 - */ static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy, const char *name, unsigned char name_assign_type, @@ -3222,15 +2673,6 @@ static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy, return priv->wdev; } -/** - * @brief del_virtual_intf - * @details - * @param[in] - * @return int : Return 0 on Success. - * @author mdaftedar - * @date 01 JUL 2012 - * @version 1.0 - */ static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) { PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n"); @@ -3275,19 +2717,6 @@ static struct cfg80211_ops wilc_cfg80211_ops = { }; - - - - -/** - * @brief WILC_WFI_update_stats - * @details Modify parameters for a given BSS. - * @param[in] - * @return int : Return 0 on Success. - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed) { @@ -3319,16 +2748,6 @@ int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed) return 0; } -/** - * @brief WILC_WFI_CfgAlloc - * @details Allocation of the wireless device structure and assigning it - * to the cfg80211 operations structure. - * @param[in] NONE - * @return wireless_dev : Returns pointer to wireless_dev structure. - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ static struct wireless_dev *WILC_WFI_CfgAlloc(void) { @@ -3336,14 +2755,13 @@ static struct wireless_dev *WILC_WFI_CfgAlloc(void) PRINT_D(CFG80211_DBG, "Allocating wireless device\n"); - /*Allocating the wireless device structure*/ + wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) { PRINT_ER("Cannot allocate wireless device\n"); goto _fail_; } - /*Creating a new wiphy, linking wireless structure with the wiphy structure*/ wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv)); if (!wdev->wiphy) { PRINT_ER("Cannot allocate wiphy\n"); @@ -3351,14 +2769,12 @@ static struct wireless_dev *WILC_WFI_CfgAlloc(void) } - /* enable 802.11n HT */ WILC_WFI_band_2ghz.ht_cap.ht_supported = 1; WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff; WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K; WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; - /*wiphy bands*/ wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz; return wdev; @@ -3369,15 +2785,7 @@ _fail_: return NULL; } -/** - * @brief wilc_create_wiphy - * @details Registering of the wiphy structure and interface modes - * @param[in] NONE - * @return NONE - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ + struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev) { struct wilc_priv *priv; @@ -3392,33 +2800,20 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *de return NULL; } - - /*Return hardware description structure (wiphy)'s priv*/ priv = wdev_priv(wdev); sema_init(&(priv->SemHandleUpdateStats), 1); - - /*Link the wiphy with wireless structure*/ priv->wdev = wdev; - - /*Maximum number of probed ssid to be added by user for the scan request*/ wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID; - /*Maximum number of pmkids to be cashed*/ wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS; PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids); wdev->wiphy->max_scan_ie_len = 1000; - - /*signal strength in mBm (100*dBm) */ wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - - /*Set the availaible cipher suites*/ wdev->wiphy->cipher_suites = cipher_suites; wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); - /*Setting default managment types: for register action frame: */ wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types; wdev->wiphy->max_remain_on_channel_duration = 500; - /*Setting the wiphy interfcae mode and type before registering the wiphy*/ wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_CLIENT); wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; @@ -3432,11 +2827,9 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *de set_wiphy_dev(wdev->wiphy, dev); - /*Register wiphy structure*/ s32Error = wiphy_register(wdev->wiphy); if (s32Error) { PRINT_ER("Cannot register wiphy device\n"); - /*should define what action to be taken in such failure*/ } else { PRINT_D(CFG80211_DBG, "Successful Registering\n"); } @@ -3446,15 +2839,7 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *de } -/** - * @brief WILC_WFI_WiphyFree - * @details Freeing allocation of the wireless device structure - * @param[in] NONE - * @return NONE - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ + int wilc_init_host_int(struct net_device *net) { @@ -3486,15 +2871,6 @@ int wilc_init_host_int(struct net_device *net) return s32Error; } -/** - * @brief WILC_WFI_WiphyFree - * @details Freeing allocation of the wireless device structure - * @param[in] NONE - * @return NONE - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ int wilc_deinit_host_int(struct net_device *net) { int s32Error = 0; @@ -3511,7 +2887,6 @@ int wilc_deinit_host_int(struct net_device *net) s32Error = wilc_deinit(priv->hWILCWFIDrv); - /* Clear the Shadow scan */ clear_shadow_scan(); if (op_ifcs == 0) { PRINT_D(CORECONFIG_DBG, "destroy during ip\n"); @@ -3524,16 +2899,6 @@ int wilc_deinit_host_int(struct net_device *net) return s32Error; } - -/** - * @brief WILC_WFI_WiphyFree - * @details Freeing allocation of the wireless device structure - * @param[in] NONE - * @return NONE - * @author mdaftedar - * @date 01 MAR 2012 - * @version 1.0 - */ void wilc_free_wiphy(struct net_device *net) { PRINT_D(CFG80211_DBG, "Unregistering wiphy\n"); -- GitLab From da537229b6d324dba7788070afb0a64c1af468e5 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Wed, 25 Nov 2015 11:59:42 +0900 Subject: [PATCH 1675/2855] staging: wilc1000: fixes blank lines aren't necessary brace This patch fixes the checks reported by checkpatch.pl for Blank lines aren't necessary after an open brace '{' and Blank lines aren't necessary before a close brace '}'. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 50 ------------------- 1 file changed, 50 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index bfef022c315b5..71038b1c202df 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -201,7 +201,6 @@ static void clear_shadow_scan(void) } last_scanned_cnt = 0; } - } static u32 get_rssi_avg(tstrNetworkInfo *network_info) @@ -250,10 +249,8 @@ static void refresh_scan(void *user_void, u8 all, bool direct_scan) cfg80211_put_bss(wiphy, bss); } } - } } - } static void reset_shadow_found(void) @@ -347,7 +344,6 @@ static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, if (ap_found == -1) { ap_index = last_scanned_cnt; last_scanned_cnt++; - } else { ap_index = ap_found; } @@ -590,9 +586,7 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie, pstrDisconnectNotifInfo->ie_len, false, GFP_KERNEL); - } - } static int set_channel(struct wiphy *wiphy, @@ -646,14 +640,11 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids); if (request->n_ssids >= 1) { - - strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL); strHiddenNetwork.u8ssidnum = request->n_ssids; for (i = 0; i < request->n_ssids; i++) { - if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) { strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL); memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len); @@ -675,7 +666,6 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) (const u8 *)request->ie, request->ie_len, CfgScanResult, (void *)priv, NULL); } - } else { PRINT_ER("Requested num of scanned channels is greater than the max, supported" " channels\n"); @@ -835,7 +825,6 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, u8security = ENCRYPT_ENABLED | WPA | AES; pcgroup_encrypt_val = "WPA_AES"; pccipher_group = "AES"; - } pcwpa_version = "WPA_VERSION_1"; @@ -845,7 +834,6 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, goto done; } - } if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) @@ -982,7 +970,6 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: if (priv->wdev->iftype == NL80211_IFTYPE_AP) { - priv->WILC_WFI_wep_default = key_index; priv->WILC_WFI_wep_key_len[key_index] = params->key_len; memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len); @@ -1022,12 +1009,10 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, case WLAN_CIPHER_SUITE_TKIP: case WLAN_CIPHER_SUITE_CCMP: if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) { - if (priv->wilc_gtk[key_index] == NULL) { priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL); priv->wilc_gtk[key_index]->key = NULL; priv->wilc_gtk[key_index]->seq = NULL; - } if (priv->wilc_ptk[key_index] == NULL) { priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL); @@ -1046,7 +1031,6 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, priv->wilc_groupkey = u8gmode; if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) { - pu8TxMic = params->key + 24; pu8RxMic = params->key + 16; KeyLen = params->key_len - 16; @@ -1087,7 +1071,6 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) { - pu8TxMic = params->key + 24; pu8RxMic = params->key + 16; KeyLen = params->key_len - 16; @@ -1207,7 +1190,6 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, default: PRINT_ER("Not supported cipher: Error(%d)\n", s32Error); s32Error = -ENOTSUPP; - } return s32Error; @@ -1235,7 +1217,6 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev, g_key_wep_params.key = NULL; if ((priv->wilc_gtk[key_index]) != NULL) { - kfree(priv->wilc_gtk[key_index]->key); priv->wilc_gtk[key_index]->key = NULL; kfree(priv->wilc_gtk[key_index]->seq); @@ -1243,11 +1224,9 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev, kfree(priv->wilc_gtk[key_index]); priv->wilc_gtk[key_index] = NULL; - } if ((priv->wilc_ptk[key_index]) != NULL) { - kfree(priv->wilc_ptk[key_index]->key); priv->wilc_ptk[key_index]->key = NULL; kfree(priv->wilc_ptk[key_index]->seq); @@ -1332,7 +1311,6 @@ static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 ke PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index); if (key_index != priv->WILC_WFI_wep_default) { - wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index); } @@ -1356,12 +1334,10 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]); for (i = 0; i < NUM_STA_ASSOCIATED; i++) { - if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) { associatedsta = i; break; } - } if (associatedsta == -1) { @@ -1374,7 +1350,6 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time)); sinfo->inactive_time = 1000 * inactive_time; PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time); - } if (nic->iftype == STATION_MODE) { @@ -1431,17 +1406,14 @@ static int set_wiphy_params(struct wiphy *wiphy, u32 changed) pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short; } if (changed & WIPHY_PARAM_RETRY_LONG) { - PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_LONG %d\n", priv->dev->ieee80211_ptr->wiphy->retry_long); pstrCfgParamVal.flag |= RETRY_LONG; pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long; - } if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->frag_threshold); pstrCfgParamVal.flag |= FRAG_THRESHOLD; pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold; - } if (changed & WIPHY_PARAM_RTS_THRESHOLD) { @@ -1449,7 +1421,6 @@ static int set_wiphy_params(struct wiphy *wiphy, u32 changed) pstrCfgParamVal.flag |= RTS_THRESHOLD; pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold; - } PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n"); @@ -1504,7 +1475,6 @@ static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev, static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev, struct cfg80211_pmksa *pmksa) { - u32 i; s32 s32Error = 0; @@ -1633,7 +1603,6 @@ static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftyp void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) { - struct wilc_priv *priv; u32 header, pkt_offset; struct host_if_drv *pstrWFIDrv; @@ -1665,7 +1634,6 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) return; } } else { - PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]); s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ); @@ -1678,7 +1646,6 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size) return; } if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) { - switch (buff[ACTION_SUBTYPE_ID]) { case GAS_INTIAL_REQ: PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]); @@ -1952,7 +1919,6 @@ static int mgmt_tx(struct wiphy *wiphy, break; } } - } PRINT_D(GENERIC_DBG, "TX: ACTION FRAME Type:%x : Chan:%d\n", buf[ACTION_SUBTYPE_ID], chan->hw_value); @@ -1998,7 +1964,6 @@ static int mgmt_tx_cancel_wait(struct wiphy *wiphy, void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, u16 frame_type, bool reg) { - struct wilc_priv *priv; perInterface_wlan_t *nic; struct wilc *wl; @@ -2030,7 +1995,6 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, { break; } - } if (!wl->initialized) { @@ -2038,8 +2002,6 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, return; } wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg); - - } static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev, @@ -2047,7 +2009,6 @@ static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev, { PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n"); return 0; - } static int dump_station(struct wiphy *wiphy, struct net_device *dev, @@ -2067,7 +2028,6 @@ static int dump_station(struct wiphy *wiphy, struct net_device *dev, wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal)); return 0; - } static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, @@ -2091,7 +2051,6 @@ static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, return 0; - } static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, @@ -2680,7 +2639,6 @@ static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) } static struct cfg80211_ops wilc_cfg80211_ops = { - .set_monitor_channel = set_channel, .scan = scan, .connect = connect, @@ -2719,12 +2677,10 @@ static struct cfg80211_ops wilc_cfg80211_ops = { int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed) { - struct wilc_priv *priv; priv = wiphy_priv(wiphy); switch (changed) { - case WILC_WFI_RX_PKT: { priv->netstats.rx_packets++; @@ -2750,7 +2706,6 @@ int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed) static struct wireless_dev *WILC_WFI_CfgAlloc(void) { - struct wireless_dev *wdev; @@ -2766,7 +2721,6 @@ static struct wireless_dev *WILC_WFI_CfgAlloc(void) if (!wdev->wiphy) { PRINT_ER("Cannot allocate wiphy\n"); goto _fail_mem_; - } WILC_WFI_band_2ghz.ht_cap.ht_supported = 1; @@ -2783,7 +2737,6 @@ _fail_mem_: kfree(wdev); _fail_: return NULL; - } struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev) @@ -2836,13 +2789,10 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *de priv->dev = net; return wdev; - - } int wilc_init_host_int(struct net_device *net) { - int s32Error = 0; struct wilc_priv *priv; -- GitLab From b0b9f3e4d24baa62dda7cd48284fd2842164974f Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Wed, 25 Nov 2015 11:59:47 +0900 Subject: [PATCH 1676/2855] staging: wilc1000: Handle_AddBASession: remove unused function This patch removes unused a function Handle_AddBASession. And, removes the relation define. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 69 ----------------------- 1 file changed, 69 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 900b7ca2870f7..e6c4ce5b31788 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -43,7 +43,6 @@ #define HOST_IF_MSG_FLUSH_CONNECT 30 #define HOST_IF_MSG_GET_STATISTICS 31 #define HOST_IF_MSG_SET_MULTICAST_FILTER 32 -#define HOST_IF_MSG_ADD_BA_SESSION 33 #define HOST_IF_MSG_DEL_BA_SESSION 34 #define HOST_IF_MSG_Q_IDLE 35 #define HOST_IF_MSG_DEL_ALL_STA 36 @@ -2739,70 +2738,6 @@ ERRORHANDLER: kfree(wid.val); } -static s32 Handle_AddBASession(struct host_if_drv *hif_drv, - struct ba_session_info *strHostIfBASessionInfo) -{ - s32 result = 0; - struct wid wid; - int AddbaTimeout = 100; - char *ptr = NULL; - - PRINT_D(HOSTINF_DBG, "Opening Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\nBufferSize == %d\nSessionTimeOut = %d\n", - strHostIfBASessionInfo->bssid[0], - strHostIfBASessionInfo->bssid[1], - strHostIfBASessionInfo->bssid[2], - strHostIfBASessionInfo->buf_size, - strHostIfBASessionInfo->time_out, - strHostIfBASessionInfo->tid); - - wid.id = (u16)WID_11E_P_ACTION_REQ; - wid.type = WID_STR; - wid.val = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL); - wid.size = BLOCK_ACK_REQ_SIZE; - ptr = wid.val; - *ptr++ = 0x14; - *ptr++ = 0x3; - *ptr++ = 0x0; - memcpy(ptr, strHostIfBASessionInfo->bssid, ETH_ALEN); - ptr += ETH_ALEN; - *ptr++ = strHostIfBASessionInfo->tid; - *ptr++ = 1; - *ptr++ = (strHostIfBASessionInfo->buf_size & 0xFF); - *ptr++ = ((strHostIfBASessionInfo->buf_size >> 16) & 0xFF); - *ptr++ = (strHostIfBASessionInfo->time_out & 0xFF); - *ptr++ = ((strHostIfBASessionInfo->time_out >> 16) & 0xFF); - *ptr++ = (AddbaTimeout & 0xFF); - *ptr++ = ((AddbaTimeout >> 16) & 0xFF); - *ptr++ = 8; - *ptr++ = 0; - - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); - if (result) - PRINT_D(HOSTINF_DBG, "Couldn't open BA Session\n"); - - wid.id = (u16)WID_11E_P_ACTION_REQ; - wid.type = WID_STR; - wid.size = 15; - ptr = wid.val; - *ptr++ = 15; - *ptr++ = 7; - *ptr++ = 0x2; - memcpy(ptr, strHostIfBASessionInfo->bssid, ETH_ALEN); - ptr += ETH_ALEN; - *ptr++ = strHostIfBASessionInfo->tid; - *ptr++ = 8; - *ptr++ = (strHostIfBASessionInfo->buf_size & 0xFF); - *ptr++ = ((strHostIfBASessionInfo->time_out >> 16) & 0xFF); - *ptr++ = 3; - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); - - kfree(wid.val); - - return result; -} - static s32 Handle_DelAllRxBASessions(struct host_if_drv *hif_drv, struct ba_session_info *strHostIfBASessionInfo) { @@ -3033,10 +2968,6 @@ static int hostIFthread(void *pvArg) Handle_SetMulticastFilter(msg.drv, &msg.body.multicast_info); break; - case HOST_IF_MSG_ADD_BA_SESSION: - Handle_AddBASession(msg.drv, &msg.body.session_info); - break; - case HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS: Handle_DelAllRxBASessions(msg.drv, &msg.body.session_info); break; -- GitLab From 9edaa5f3c28e529c98fcb26035630fa64d140ffb Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Wed, 25 Nov 2015 11:59:48 +0900 Subject: [PATCH 1677/2855] staging: wilc1000: change if with else if The if statement should be else if since it is part of whole if condition. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index e6c4ce5b31788..2408858c8a4c1 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1764,9 +1764,7 @@ static int Handle_Key(struct host_if_drv *hif_drv, strWIDList, 4, get_id_from_handler(hif_drv)); kfree(pu8keybuf); - } - - if (pstrHostIFkeyAttr->action & ADDKEY) { + } else if (pstrHostIFkeyAttr->action & ADDKEY) { PRINT_D(HOSTINF_DBG, "Handling WEP key\n"); pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2, GFP_KERNEL); if (!pu8keybuf) { @@ -1848,9 +1846,7 @@ static int Handle_Key(struct host_if_drv *hif_drv, kfree(pu8keybuf); up(&hif_drv->sem_test_key_block); - } - - if (pstrHostIFkeyAttr->action & ADDKEY) { + } else if (pstrHostIFkeyAttr->action & ADDKEY) { PRINT_D(HOSTINF_DBG, "Handling group key(Rx) function\n"); pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL); @@ -1921,8 +1917,7 @@ _WPARxGtk_end_case_: get_id_from_handler(hif_drv)); kfree(pu8keybuf); up(&hif_drv->sem_test_key_block); - } - if (pstrHostIFkeyAttr->action & ADDKEY) { + } else if (pstrHostIFkeyAttr->action & ADDKEY) { pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL); if (!pu8keybuf) { PRINT_ER("No buffer to send PTK Key\n"); -- GitLab From c8751ad7d22459b973b26c5bd37b444cf77d6412 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Wed, 25 Nov 2015 11:59:49 +0900 Subject: [PATCH 1678/2855] staging: wilc1000: Handle_SetMulticastFilter(): fixes right shifting more than type allows This patch fixes the warning reported by smatch. - Handle_SetMulticastFilter() warn: right shifting more than type allows That is unnecessary action of boolean type. just assign 0. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 2408858c8a4c1..772d524bc2b40 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2711,9 +2711,9 @@ static void Handle_SetMulticastFilter(struct host_if_drv *hif_drv, pu8CurrByte = wid.val; *pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF); - *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF); - *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF); - *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF); + *pu8CurrByte++ = 0; + *pu8CurrByte++ = 0; + *pu8CurrByte++ = 0; *pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF); *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF); -- GitLab From cc28e4bf6e5279728c4b03497e95b9a5f5054f9c Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Fri, 18 Dec 2015 18:26:02 +0900 Subject: [PATCH 1679/2855] staging: wilc1000: fix a bug when unload driver kernel crashes when load and unload driver several times. I used git bisect to track down and found that removing NULL setting caused the panic. This reverts only related codes of the patch(a4ab1ade75a3). Fixes: a4ab1ade75a3 ("staging: wilc1000: replace drvHandler and hWFIDrv with hif_drv") Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 772d524bc2b40..36303c310c2c0 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1385,9 +1385,12 @@ static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv) hif_drv->usr_conn_req.ssid_len = 0; kfree(hif_drv->usr_conn_req.pu8ssid); + hif_drv->usr_conn_req.pu8ssid = NULL; kfree(hif_drv->usr_conn_req.pu8bssid); + hif_drv->usr_conn_req.pu8bssid = NULL; hif_drv->usr_conn_req.ies_len = 0; kfree(hif_drv->usr_conn_req.ies); + hif_drv->usr_conn_req.ies = NULL; eth_zero_addr(wilc_connected_ssid); @@ -1641,9 +1644,12 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, strConnectInfo.pu8ReqIEs = NULL; hif_drv->usr_conn_req.ssid_len = 0; kfree(hif_drv->usr_conn_req.pu8ssid); + hif_drv->usr_conn_req.pu8ssid = NULL; kfree(hif_drv->usr_conn_req.pu8bssid); + hif_drv->usr_conn_req.pu8bssid = NULL; hif_drv->usr_conn_req.ies_len = 0; kfree(hif_drv->usr_conn_req.ies); + hif_drv->usr_conn_req.ies = NULL; } else if ((u8MacStatus == MAC_DISCONNECTED) && (hif_drv->hif_state == HOST_IF_CONNECTED)) { PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW\n"); @@ -1677,9 +1683,12 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, hif_drv->usr_conn_req.ssid_len = 0; kfree(hif_drv->usr_conn_req.pu8ssid); + hif_drv->usr_conn_req.pu8ssid = NULL; kfree(hif_drv->usr_conn_req.pu8bssid); + hif_drv->usr_conn_req.pu8bssid = NULL; hif_drv->usr_conn_req.ies_len = 0; kfree(hif_drv->usr_conn_req.ies); + hif_drv->usr_conn_req.ies = NULL; if (join_req && join_req_drv == hif_drv) { kfree(join_req); @@ -2049,9 +2058,12 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) hif_drv->usr_conn_req.ssid_len = 0; kfree(hif_drv->usr_conn_req.pu8ssid); + hif_drv->usr_conn_req.pu8ssid = NULL; kfree(hif_drv->usr_conn_req.pu8bssid); + hif_drv->usr_conn_req.pu8bssid = NULL; hif_drv->usr_conn_req.ies_len = 0; kfree(hif_drv->usr_conn_req.ies); + hif_drv->usr_conn_req.ies = NULL; if (join_req && join_req_drv == hif_drv) { kfree(join_req); -- GitLab From ff5d40a4d3b6319cbc4ac9b454205cf662eb42b1 Mon Sep 17 00:00:00 2001 From: Chandra S Gorentla Date: Sun, 15 Nov 2015 09:36:58 +0530 Subject: [PATCH 1680/2855] staging: wilc1000: Remove 'if' statement, which is always false - 'if' which is always false is removed - variable associated with this 'if' is deleted Signed-off-by: Chandra S Gorentla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_msgqueue.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_msgqueue.c b/drivers/staging/wilc1000/wilc_msgqueue.c index 0eff121b8291e..098390cdf3199 100644 --- a/drivers/staging/wilc1000/wilc_msgqueue.c +++ b/drivers/staging/wilc1000/wilc_msgqueue.c @@ -115,7 +115,6 @@ int wilc_mq_recv(WILC_MsgQueueHandle *pHandle, u32 *pu32ReceivedLength) { Message *pstrMessage; - int result = 0; unsigned long flags; if ((!pHandle) || (u32RecvBufferSize == 0) @@ -135,12 +134,6 @@ int wilc_mq_recv(WILC_MsgQueueHandle *pHandle, down(&pHandle->hSem); - /* other non-timeout scenarios */ - if (result) { - PRINT_ER("Non-timeout\n"); - return result; - } - if (pHandle->bExiting) { PRINT_ER("pHandle fail\n"); return -EFAULT; @@ -174,5 +167,5 @@ int wilc_mq_recv(WILC_MsgQueueHandle *pHandle, spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); - return result; + return 0; } -- GitLab From f6e0e2a5649d56d308212583a8ca1b9d7a26c64c Mon Sep 17 00:00:00 2001 From: Bogicevic Sasa Date: Wed, 18 Nov 2015 12:45:05 +0100 Subject: [PATCH 1681/2855] drivers:staging:wilc1000 Fix all comparison to NULL could be written ... This fixes all "comparison to NULL could be written like ..." Signed-off-by: Bogicevic Sasa Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/coreconfigurator.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/coreconfigurator.c b/drivers/staging/wilc1000/coreconfigurator.c index 329477ab5adc0..2d4d3f190c013 100644 --- a/drivers/staging/wilc1000/coreconfigurator.c +++ b/drivers/staging/wilc1000/coreconfigurator.c @@ -436,7 +436,7 @@ s32 wilc_parse_network_info(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo /* Get DTIM Period */ pu8TimElm = get_tim_elm(pu8msa, u16RxLen + FCS_LEN, u8index); - if (pu8TimElm != NULL) + if (pu8TimElm) pstrNetworkInfo->u8DtimPeriod = pu8TimElm[3]; pu8IEs = &pu8msa[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN]; u16IEsLen = u16RxLen - (MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN); @@ -470,8 +470,8 @@ s32 wilc_dealloc_network_info(tstrNetworkInfo *pstrNetworkInfo) { s32 s32Error = 0; - if (pstrNetworkInfo != NULL) { - if (pstrNetworkInfo->pu8IEs != NULL) { + if (pstrNetworkInfo) { + if (pstrNetworkInfo->pu8IEs) { kfree(pstrNetworkInfo->pu8IEs); pstrNetworkInfo->pu8IEs = NULL; } else { @@ -555,8 +555,8 @@ s32 wilc_dealloc_assoc_resp_info(tstrConnectRespInfo *pstrConnectRespInfo) { s32 s32Error = 0; - if (pstrConnectRespInfo != NULL) { - if (pstrConnectRespInfo->pu8RespIEs != NULL) { + if (pstrConnectRespInfo) { + if (pstrConnectRespInfo->pu8RespIEs) { kfree(pstrConnectRespInfo->pu8RespIEs); pstrConnectRespInfo->pu8RespIEs = NULL; } else { -- GitLab From 6b05fcc9c6ec08f4bd53e585afe4ec2f2f5b4ffb Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Mon, 23 Nov 2015 22:41:17 +0900 Subject: [PATCH 1682/2855] staging: wilc1000: Fix typo in wilc_msgqueue.h This patch fix some spelling typo in wilc_msgqueue.h Signed-off-by: Masanari Iida Acked-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_msgqueue.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_msgqueue.h b/drivers/staging/wilc1000/wilc_msgqueue.h index d231c334ed933..d7e0328baceef 100644 --- a/drivers/staging/wilc1000/wilc_msgqueue.h +++ b/drivers/staging/wilc1000/wilc_msgqueue.h @@ -35,7 +35,7 @@ typedef struct __MessageQueue_struct { * any other message queue having the same name in the system * @param[in,out] pHandle handle to the message queue object * @param[in] pstrAttrs Optional attributes, NULL for default - * @return Error code indicating sucess/failure + * @return Error code indicating success/failure * @author syounan * @date 30 Aug 2010 * @version 1.0 @@ -44,7 +44,7 @@ int wilc_mq_create(WILC_MsgQueueHandle *pHandle); /*! * @brief Sends a message - * @details Sends a message, this API will block unil the message is + * @details Sends a message, this API will block until the message is * actually sent or until it is timedout (as long as the feature * CONFIG_WILC_MSG_QUEUE_TIMEOUT is enabled and pstrAttrs->u32Timeout * is not set to WILC_OS_INFINITY), zero timeout is a valid value @@ -52,7 +52,7 @@ int wilc_mq_create(WILC_MsgQueueHandle *pHandle); * @param[in] pvSendBuffer pointer to the data to send * @param[in] u32SendBufferSize the size of the data to send * @param[in] pstrAttrs Optional attributes, NULL for default - * @return Error code indicating sucess/failure + * @return Error code indicating success/failure * @author syounan * @date 30 Aug 2010 * @version 1.0 @@ -62,7 +62,7 @@ int wilc_mq_send(WILC_MsgQueueHandle *pHandle, /*! * @brief Receives a message - * @details Receives a message, this API will block unil a message is + * @details Receives a message, this API will block until a message is * received or until it is timedout (as long as the feature * CONFIG_WILC_MSG_QUEUE_TIMEOUT is enabled and pstrAttrs->u32Timeout * is not set to WILC_OS_INFINITY), zero timeout is a valid value @@ -71,7 +71,7 @@ int wilc_mq_send(WILC_MsgQueueHandle *pHandle, * @param[in] u32RecvBufferSize the size of the receive buffer * @param[out] pu32ReceivedLength the length of received data * @param[in] pstrAttrs Optional attributes, NULL for default - * @return Error code indicating sucess/failure + * @return Error code indicating success/failure * @author syounan * @date 30 Aug 2010 * @version 1.0 @@ -84,7 +84,7 @@ int wilc_mq_recv(WILC_MsgQueueHandle *pHandle, * @brief Destroys an existing Message queue * @param[in] pHandle handle to the message queue object * @param[in] pstrAttrs Optional attributes, NULL for default - * @return Error code indicating sucess/failure + * @return Error code indicating success/failure * @author syounan * @date 30 Aug 2010 * @version 1.0 -- GitLab From 7cf8e59e54b322a1663a3e2beaab8324240e1801 Mon Sep 17 00:00:00 2001 From: "Mario J. Rugiero" Date: Thu, 3 Dec 2015 13:24:05 -0300 Subject: [PATCH 1683/2855] staging: wilc1000: replace 'ptr > 0' check by 'ptr' check. This silences a sparse warning about incompatible comparisons, while making the intent of the check a bit clearer. Signed-off-by: Mario J. Rugiero Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 36303c310c2c0..d1707f6f0dccd 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2292,7 +2292,7 @@ static void Handle_AddBeacon(struct host_if_drv *hif_drv, *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 16) & 0xFF); *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 24) & 0xFF); - if (pstrSetBeaconParam->tail > 0) + if (pstrSetBeaconParam->tail) memcpy(pu8CurrByte, pstrSetBeaconParam->tail, pstrSetBeaconParam->tail_len); pu8CurrByte += pstrSetBeaconParam->tail_len; -- GitLab From 14b93bb6bbf08c5002eddda1af1916e72e542eb8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 12:39:26 -0700 Subject: [PATCH 1684/2855] staging: comedi: adv_pci_dio: separate out PCI-1760 support The PCI-1760 is board unique. It uses an outgoing/incoming mailbox programming sequence to access the hardware. The other boards supported by this driver use simple register mapping. Including support for the PCI-1760 in this driver just makes it harder to understand. Separate out the PCI-1760 support into a new driver, adv_pci1760. Clean up the new driver. The original code had a bunch of CamelCase and other checkpatch.pl issues. The code used to access the outgoing/incoming mailboxes was also a bit awkward with the passing of the arrays for the outgoing and incoming mailbox bytes. Replace them with two new functions that send a command and return the feedback data from the command based on the programming flow chart in the datasheet for the PCI-1760. The new adv_pci1760 driver also fixes the incomplete timer subdevice. This subdevice is actually the 2 PWM outputs so the subdevice type has been changed to COMEDI_SUBD_PWM. The counter subdevice support was not complete in the original code. They are also a bit strange since they are up counters connected to each of the digital inputs. For now that subdevice has been disabled (COMEDI_SUBD_UNUSED). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 12 +- drivers/staging/comedi/drivers/Makefile | 1 + drivers/staging/comedi/drivers/adv_pci1760.c | 432 +++++++++++++++++++ drivers/staging/comedi/drivers/adv_pci_dio.c | 426 +----------------- 4 files changed, 445 insertions(+), 426 deletions(-) create mode 100644 drivers/staging/comedi/drivers/adv_pci1760.c diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 945c85a107930..e7255f811611c 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -772,6 +772,14 @@ config COMEDI_ADV_PCI1724 To compile this driver as a module, choose M here: the module will be called adv_pci1724. +config COMEDI_ADV_PCI1760 + tristate "Advantech PCI-1760 support" + ---help--- + Enable support for Advantech PCI-1760 board. + + To compile this driver as a module, choose M here: the module will be + called adv_pci1760. + config COMEDI_ADV_PCI_DIO tristate "Advantech PCI DIO card support" select COMEDI_8254 @@ -779,8 +787,8 @@ config COMEDI_ADV_PCI_DIO ---help--- Enable support for Advantech PCI DIO cards PCI-1730, PCI-1733, PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U, - PCI-1750, PCI-1751, PCI-1752, PCI-1753/E, PCI-1754, PCI-1756, - PCI-1760 and PCI-1762 + PCI-1750, PCI-1751, PCI-1752, PCI-1753/E, PCI-1754, PCI-1756 and + PCI-1762 To compile this driver as a module, choose M here: the module will be called adv_pci_dio. diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index 94c179bea71ef..0c8cfa738727e 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -81,6 +81,7 @@ obj-$(CONFIG_COMEDI_ADV_PCI1710) += adv_pci1710.o obj-$(CONFIG_COMEDI_ADV_PCI1720) += adv_pci1720.o obj-$(CONFIG_COMEDI_ADV_PCI1723) += adv_pci1723.o obj-$(CONFIG_COMEDI_ADV_PCI1724) += adv_pci1724.o +obj-$(CONFIG_COMEDI_ADV_PCI1760) += adv_pci1760.o obj-$(CONFIG_COMEDI_ADV_PCI_DIO) += adv_pci_dio.o obj-$(CONFIG_COMEDI_AMPLC_DIO200_PCI) += amplc_dio200_pci.o obj-$(CONFIG_COMEDI_AMPLC_PC236_PCI) += amplc_pci236.o diff --git a/drivers/staging/comedi/drivers/adv_pci1760.c b/drivers/staging/comedi/drivers/adv_pci1760.c new file mode 100644 index 0000000000000..d7dd1e55e347b --- /dev/null +++ b/drivers/staging/comedi/drivers/adv_pci1760.c @@ -0,0 +1,432 @@ +/* + * COMEDI driver for the Advantech PCI-1760 + * Copyright (C) 2015 H Hartley Sweeten + * + * Based on the pci1760 support in the adv_pci_dio driver written by: + * Michal Dobes + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 2000 David A. Schleef + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * Driver: adv_pci1760 + * Description: Advantech PCI-1760 Relay & Isolated Digital Input Card + * Devices: [Advantech] PCI-1760 (adv_pci1760) + * Author: H Hartley Sweeten + * Updated: Fri, 13 Nov 2015 12:34:00 -0700 + * Status: untested + * + * Configuration Options: not applicable, uses PCI auto config + */ + +#include + +#include "../comedi_pci.h" + +/* + * PCI-1760 Register Map + * + * Outgoing Mailbox Bytes + * OMB3: Not used (must be 0) + * OMB2: The command code to the PCI-1760 + * OMB1: The hi byte of the parameter for the command in OMB2 + * OMB0: The lo byte of the parameter for the command in OMB2 + * + * Incoming Mailbox Bytes + * IMB3: The Isolated Digital Input status (updated every 100us) + * IMB2: The current command (matches OMB2 when command is successful) + * IMB1: The hi byte of the feedback data for the command in OMB2 + * IMB0: The lo byte of the feedback data for the command in OMB2 + * + * Interrupt Control/Status + * INTCSR3: Not used (must be 0) + * INTCSR2: The interrupt status (read only) + * INTCSR1: Interrupt enable/disable + * INTCSR0: Not used (must be 0) + */ +#define PCI1760_OMB_REG(x) (0x0c + (x)) +#define PCI1760_IMB_REG(x) (0x1c + (x)) +#define PCI1760_INTCSR_REG(x) (0x38 + (x)) +#define PCI1760_INTCSR1_IRQ_ENA BIT(5) +#define PCI1760_INTCSR2_OMB_IRQ BIT(0) +#define PCI1760_INTCSR2_IMB_IRQ BIT(1) +#define PCI1760_INTCSR2_IRQ_STATUS BIT(6) +#define PCI1760_INTCSR2_IRQ_ASSERTED BIT(7) + +/* PCI-1760 command codes */ +#define PCI1760_CMD_CLR_IMB2 0x00 /* Clears IMB2 */ +#define PCI1760_CMD_SET_DO 0x01 /* Set output state */ +#define PCI1760_CMD_GET_DO 0x02 /* Read output status */ +#define PCI1760_CMD_GET_STATUS 0x03 /* Read current status */ +#define PCI1760_CMD_GET_FW_VER 0x0e /* Read firware version */ +#define PCI1760_CMD_GET_HW_VER 0x0f /* Read hardware version */ +#define PCI1760_CMD_SET_PWM_HI(x) (0x10 + (x) * 2) /* Set "hi" period */ +#define PCI1760_CMD_SET_PWM_LO(x) (0x11 + (x) * 2) /* Set "lo" period */ +#define PCI1760_CMD_SET_PWM_CNT(x) (0x14 + (x)) /* Set burst count */ +#define PCI1760_CMD_ENA_PWM 0x1f /* Enable PWM outputs */ +#define PCI1760_CMD_ENA_FILT 0x20 /* Enable input filter */ +#define PCI1760_CMD_ENA_PAT_MATCH 0x21 /* Enable input pattern match */ +#define PCI1760_CMD_SET_PAT_MATCH 0x22 /* Set input pattern match */ +#define PCI1760_CMD_ENA_RISE_EDGE 0x23 /* Enable input rising edge */ +#define PCI1760_CMD_ENA_FALL_EDGE 0x24 /* Enable input falling edge */ +#define PCI1760_CMD_ENA_CNT 0x28 /* Enable counter */ +#define PCI1760_CMD_RST_CNT 0x29 /* Reset counter */ +#define PCI1760_CMD_ENA_CNT_OFLOW 0x2a /* Enable counter overflow */ +#define PCI1760_CMD_ENA_CNT_MATCH 0x2b /* Enable counter match */ +#define PCI1760_CMD_SET_CNT_EDGE 0x2c /* Set counter edge */ +#define PCI1760_CMD_GET_CNT 0x2f /* Reads counter value */ +#define PCI1760_CMD_SET_HI_SAMP(x) (0x30 + (x)) /* Set "hi" sample time */ +#define PCI1760_CMD_SET_LO_SAMP(x) (0x38 + (x)) /* Set "lo" sample time */ +#define PCI1760_CMD_SET_CNT(x) (0x40 + (x)) /* Set counter reset val */ +#define PCI1760_CMD_SET_CNT_MATCH(x) (0x48 + (x)) /* Set counter match val */ +#define PCI1760_CMD_GET_INT_FLAGS 0x60 /* Read interrupt flags */ +#define PCI1760_CMD_GET_INT_FLAGS_MATCH BIT(0) +#define PCI1760_CMD_GET_INT_FLAGS_COS BIT(1) +#define PCI1760_CMD_GET_INT_FLAGS_OFLOW BIT(2) +#define PCI1760_CMD_GET_OS 0x61 /* Read edge change flags */ +#define PCI1760_CMD_GET_CNT_STATUS 0x62 /* Read counter oflow/match */ + +#define PCI1760_CMD_TIMEOUT 250 /* 250 usec timeout */ +#define PCI1760_CMD_RETRIES 3 /* limit number of retries */ + +#define PCI1760_PWM_TIMEBASE 100000 /* 1 unit = 100 usec */ + +static int pci1760_send_cmd(struct comedi_device *dev, + unsigned char cmd, unsigned short val) +{ + unsigned long timeout; + + /* send the command and parameter */ + outb(val & 0xff, dev->iobase + PCI1760_OMB_REG(0)); + outb((val >> 8) & 0xff, dev->iobase + PCI1760_OMB_REG(1)); + outb(cmd, dev->iobase + PCI1760_OMB_REG(2)); + outb(0, dev->iobase + PCI1760_OMB_REG(3)); + + /* datasheet says to allow up to 250 usec for the command to complete */ + timeout = jiffies + usecs_to_jiffies(PCI1760_CMD_TIMEOUT); + do { + if (inb(dev->iobase + PCI1760_IMB_REG(2)) == cmd) { + /* command success; return the feedback data */ + return inb(dev->iobase + PCI1760_IMB_REG(0)) | + (inb(dev->iobase + PCI1760_IMB_REG(1)) << 8); + } + cpu_relax(); + } while (time_before(jiffies, timeout)); + + return -EBUSY; +} + +static int pci1760_cmd(struct comedi_device *dev, + unsigned char cmd, unsigned short val) +{ + int repeats; + int ret; + + /* send PCI1760_CMD_CLR_IMB2 between identical commands */ + if (inb(dev->iobase + PCI1760_IMB_REG(2)) == cmd) { + ret = pci1760_send_cmd(dev, PCI1760_CMD_CLR_IMB2, 0); + if (ret < 0) { + /* timeout? try it once more */ + ret = pci1760_send_cmd(dev, PCI1760_CMD_CLR_IMB2, 0); + if (ret < 0) + return -ETIMEDOUT; + } + } + + /* datasheet says to keep retrying the command */ + for (repeats = 0; repeats < PCI1760_CMD_RETRIES; repeats++) { + ret = pci1760_send_cmd(dev, cmd, val); + if (ret >= 0) + return ret; + } + + /* command failed! */ + return -ETIMEDOUT; +} + +static int pci1760_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + data[1] = inb(dev->iobase + PCI1760_IMB_REG(3)); + + return insn->n; +} + +static int pci1760_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + int ret; + + if (comedi_dio_update_state(s, data)) { + ret = pci1760_cmd(dev, PCI1760_CMD_SET_DO, s->state); + if (ret < 0) + return ret; + } + + data[1] = s->state; + + return insn->n; +} + +static int pci1760_pwm_ns_to_div(unsigned int flags, unsigned int ns) +{ + unsigned int divisor; + + switch (flags) { + case CMDF_ROUND_NEAREST: + divisor = DIV_ROUND_CLOSEST(ns, PCI1760_PWM_TIMEBASE); + break; + case CMDF_ROUND_UP: + divisor = DIV_ROUND_UP(ns, PCI1760_PWM_TIMEBASE); + break; + case CMDF_ROUND_DOWN: + divisor = ns / PCI1760_PWM_TIMEBASE; + default: + return -EINVAL; + } + + if (divisor < 1) + divisor = 1; + if (divisor > 0xffff) + divisor = 0xffff; + + return divisor; +} + +static int pci1760_pwm_enable(struct comedi_device *dev, + unsigned int chan, bool enable) +{ + int ret; + + ret = pci1760_cmd(dev, PCI1760_CMD_GET_STATUS, PCI1760_CMD_ENA_PWM); + if (ret < 0) + return ret; + + if (enable) + ret |= BIT(chan); + else + ret &= ~BIT(chan); + + return pci1760_cmd(dev, PCI1760_CMD_ENA_PWM, ret); +} + +static int pci1760_pwm_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int chan = CR_CHAN(insn->chanspec); + int hi_div; + int lo_div; + int ret; + + switch (data[0]) { + case INSN_CONFIG_ARM: + ret = pci1760_pwm_enable(dev, chan, false); + if (ret < 0) + return ret; + + if (data[1] > 0xffff) + return -EINVAL; + ret = pci1760_cmd(dev, PCI1760_CMD_SET_PWM_CNT(chan), data[1]); + if (ret < 0) + return ret; + + ret = pci1760_pwm_enable(dev, chan, true); + if (ret < 0) + return ret; + break; + case INSN_CONFIG_DISARM: + ret = pci1760_pwm_enable(dev, chan, false); + if (ret < 0) + return ret; + break; + case INSN_CONFIG_PWM_OUTPUT: + ret = pci1760_pwm_enable(dev, chan, false); + if (ret < 0) + return ret; + + hi_div = pci1760_pwm_ns_to_div(data[1], data[2]); + lo_div = pci1760_pwm_ns_to_div(data[3], data[4]); + if (hi_div < 0 || lo_div < 0) + return -EINVAL; + if ((hi_div * PCI1760_PWM_TIMEBASE) != data[2] || + (lo_div * PCI1760_PWM_TIMEBASE) != data[4]) { + data[2] = hi_div * PCI1760_PWM_TIMEBASE; + data[4] = lo_div * PCI1760_PWM_TIMEBASE; + return -EAGAIN; + } + ret = pci1760_cmd(dev, PCI1760_CMD_SET_PWM_HI(chan), hi_div); + if (ret < 0) + return ret; + ret = pci1760_cmd(dev, PCI1760_CMD_SET_PWM_LO(chan), lo_div); + if (ret < 0) + return ret; + break; + case INSN_CONFIG_GET_PWM_OUTPUT: + hi_div = pci1760_cmd(dev, PCI1760_CMD_GET_STATUS, + PCI1760_CMD_SET_PWM_HI(chan)); + lo_div = pci1760_cmd(dev, PCI1760_CMD_GET_STATUS, + PCI1760_CMD_SET_PWM_LO(chan)); + if (hi_div < 0 || lo_div < 0) + return -ETIMEDOUT; + + data[1] = hi_div * PCI1760_PWM_TIMEBASE; + data[2] = lo_div * PCI1760_PWM_TIMEBASE; + break; + case INSN_CONFIG_GET_PWM_STATUS: + ret = pci1760_cmd(dev, PCI1760_CMD_GET_STATUS, + PCI1760_CMD_ENA_PWM); + if (ret < 0) + return ret; + + data[1] = (ret & BIT(chan)) ? 1 : 0; + break; + default: + return -EINVAL; + } + + return insn->n; +} + +static void pci1760_reset(struct comedi_device *dev) +{ + int i; + + /* disable interrupts (intcsr2 is read-only) */ + outb(0, dev->iobase + PCI1760_INTCSR_REG(0)); + outb(0, dev->iobase + PCI1760_INTCSR_REG(1)); + outb(0, dev->iobase + PCI1760_INTCSR_REG(3)); + + /* disable counters */ + pci1760_cmd(dev, PCI1760_CMD_ENA_CNT, 0); + + /* disable overflow interrupts */ + pci1760_cmd(dev, PCI1760_CMD_ENA_CNT_OFLOW, 0); + + /* disable match */ + pci1760_cmd(dev, PCI1760_CMD_ENA_CNT_MATCH, 0); + + /* set match and counter reset values */ + for (i = 0; i < 8; i++) { + pci1760_cmd(dev, PCI1760_CMD_SET_CNT_MATCH(i), 0x8000); + pci1760_cmd(dev, PCI1760_CMD_SET_CNT(i), 0x0000); + } + + /* reset counters to reset values */ + pci1760_cmd(dev, PCI1760_CMD_RST_CNT, 0xff); + + /* set counter count edges */ + pci1760_cmd(dev, PCI1760_CMD_SET_CNT_EDGE, 0); + + /* disable input filters */ + pci1760_cmd(dev, PCI1760_CMD_ENA_FILT, 0); + + /* disable pattern matching */ + pci1760_cmd(dev, PCI1760_CMD_ENA_PAT_MATCH, 0); + + /* set pattern match value */ + pci1760_cmd(dev, PCI1760_CMD_SET_PAT_MATCH, 0); +} + +static int pci1760_auto_attach(struct comedi_device *dev, + unsigned long context) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct comedi_subdevice *s; + int ret; + + ret = comedi_pci_enable(dev); + if (ret) + return ret; + dev->iobase = pci_resource_start(pcidev, 0); + + pci1760_reset(dev); + + ret = comedi_alloc_subdevices(dev, 4); + if (ret) + return ret; + + /* Digital Input subdevice */ + s = &dev->subdevices[0]; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = 8; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = pci1760_di_insn_bits; + + /* Digital Output subdevice */ + s = &dev->subdevices[1]; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 8; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = pci1760_do_insn_bits; + + /* get the current state of the outputs */ + ret = pci1760_cmd(dev, PCI1760_CMD_GET_DO, 0); + if (ret < 0) + return ret; + s->state = ret; + + /* PWM subdevice */ + s = &dev->subdevices[2]; + s->type = COMEDI_SUBD_PWM; + s->subdev_flags = SDF_PWM_COUNTER; + s->n_chan = 2; + s->insn_config = pci1760_pwm_insn_config; + + /* Counter subdevice */ + s = &dev->subdevices[3]; + s->type = COMEDI_SUBD_UNUSED; + + return 0; +} + +static struct comedi_driver pci1760_driver = { + .driver_name = "adv_pci1760", + .module = THIS_MODULE, + .auto_attach = pci1760_auto_attach, + .detach = comedi_pci_detach, +}; + +static int pci1760_pci_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + return comedi_pci_auto_config(dev, &pci1760_driver, id->driver_data); +} + +static const struct pci_device_id pci1760_pci_table[] = { + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1760) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, pci1760_pci_table); + +static struct pci_driver pci1760_pci_driver = { + .name = "adv_pci1760", + .id_table = pci1760_pci_table, + .probe = pci1760_pci_probe, + .remove = comedi_pci_auto_unconfig, +}; +module_comedi_pci_driver(pci1760_driver, pci1760_pci_driver); + +MODULE_AUTHOR("Comedi http://www.comedi.org"); +MODULE_DESCRIPTION("Comedi driver for Advantech PCI-1760"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index f1b3c5aa8d794..81b2cf27182c4 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -9,13 +9,13 @@ Driver: adv_pci_dio Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U, PCI-1750, PCI-1751, PCI-1752, - PCI-1753/E, PCI-1754, PCI-1756, PCI-1760, PCI-1762 + PCI-1753/E, PCI-1754, PCI-1756, PCI-1762 Author: Michal Dobes Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733, PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U, PCI-1750, PCI-1751, PCI-1752, PCI-1753, PCI-1753+PCI-1753E, PCI-1754, PCI-1756, - PCI-1760, PCI-1762 + PCI-1762 Status: untested Updated: Mon, 09 Jan 2012 12:40:46 +0000 @@ -46,7 +46,6 @@ enum hw_cards_id { TYPE_PCI1752, TYPE_PCI1753, TYPE_PCI1753E, TYPE_PCI1754, TYPE_PCI1756, - TYPE_PCI1760, TYPE_PCI1762 }; @@ -141,84 +140,6 @@ enum hw_io_access { #define PCI1762_ICR 6 /* W: Interrupt control register */ #define PCI1762_ISR 6 /* R: Interrupt status register */ -/* Advantech PCI-1760 registers */ -#define OMB0 0x0c /* W: Mailbox outgoing registers */ -#define OMB1 0x0d -#define OMB2 0x0e -#define OMB3 0x0f -#define IMB0 0x1c /* R: Mailbox incoming registers */ -#define IMB1 0x1d -#define IMB2 0x1e -#define IMB3 0x1f -#define INTCSR0 0x38 /* R/W: Interrupt control registers */ -#define INTCSR1 0x39 -#define INTCSR2 0x3a -#define INTCSR3 0x3b - -/* PCI-1760 mailbox commands */ -#define CMD_ClearIMB2 0x00 /* Clear IMB2 status and return actual - * DI status in IMB3 */ -#define CMD_SetRelaysOutput 0x01 /* Set relay output from OMB0 */ -#define CMD_GetRelaysStatus 0x02 /* Get relay status to IMB0 */ -#define CMD_ReadCurrentStatus 0x07 /* Read the current status of the - * register in OMB0, result in IMB0 */ -#define CMD_ReadFirmwareVersion 0x0e /* Read the firmware ver., result in - * IMB1.IMB0 */ -#define CMD_ReadHardwareVersion 0x0f /* Read the hardware ver., result in - * IMB1.IMB0 */ -#define CMD_EnableIDIFilters 0x20 /* Enable IDI filters based on bits in - * OMB0 */ -#define CMD_EnableIDIPatternMatch 0x21 /* Enable IDI pattern match based on - * bits in OMB0 */ -#define CMD_SetIDIPatternMatch 0x22 /* Enable IDI pattern match based on - * bits in OMB0 */ -#define CMD_EnableIDICounters 0x28 /* Enable IDI counters based on bits in - * OMB0 */ -#define CMD_ResetIDICounters 0x29 /* Reset IDI counters based on bits in - * OMB0 to its reset values */ -#define CMD_OverflowIDICounters 0x2a /* Enable IDI counters overflow - * interrupts based on bits in OMB0 */ -#define CMD_MatchIntIDICounters 0x2b /* Enable IDI counters match value - * interrupts based on bits in OMB0 */ -#define CMD_EdgeIDICounters 0x2c /* Set IDI up counters count edge (bit=0 - * - rising, =1 - falling) */ -#define CMD_GetIDICntCurValue 0x2f /* Read IDI{OMB0} up counter current - * value */ -#define CMD_SetIDI0CntResetValue 0x40 /* Set IDI0 Counter Reset Value - * 256*OMB1+OMB0 */ -#define CMD_SetIDI1CntResetValue 0x41 /* Set IDI1 Counter Reset Value - * 256*OMB1+OMB0 */ -#define CMD_SetIDI2CntResetValue 0x42 /* Set IDI2 Counter Reset Value - * 256*OMB1+OMB0 */ -#define CMD_SetIDI3CntResetValue 0x43 /* Set IDI3 Counter Reset Value - * 256*OMB1+OMB0 */ -#define CMD_SetIDI4CntResetValue 0x44 /* Set IDI4 Counter Reset Value - * 256*OMB1+OMB0 */ -#define CMD_SetIDI5CntResetValue 0x45 /* Set IDI5 Counter Reset Value - * 256*OMB1+OMB0 */ -#define CMD_SetIDI6CntResetValue 0x46 /* Set IDI6 Counter Reset Value - * 256*OMB1+OMB0 */ -#define CMD_SetIDI7CntResetValue 0x47 /* Set IDI7 Counter Reset Value - * 256*OMB1+OMB0 */ -#define CMD_SetIDI0CntMatchValue 0x48 /* Set IDI0 Counter Match Value - * 256*OMB1+OMB0 */ -#define CMD_SetIDI1CntMatchValue 0x49 /* Set IDI1 Counter Match Value - * 256*OMB1+OMB0 */ -#define CMD_SetIDI2CntMatchValue 0x4a /* Set IDI2 Counter Match Value - * 256*OMB1+OMB0 */ -#define CMD_SetIDI3CntMatchValue 0x4b /* Set IDI3 Counter Match Value - * 256*OMB1+OMB0 */ -#define CMD_SetIDI4CntMatchValue 0x4c /* Set IDI4 Counter Match Value - * 256*OMB1+OMB0 */ -#define CMD_SetIDI5CntMatchValue 0x4d /* Set IDI5 Counter Match Value - * 256*OMB1+OMB0 */ -#define CMD_SetIDI6CntMatchValue 0x4e /* Set IDI6 Counter Match Value - * 256*OMB1+OMB0 */ -#define CMD_SetIDI7CntMatchValue 0x4f /* Set IDI7 Counter Match Value - * 256*OMB1+OMB0 */ - -#define OMBCMD_RETRY 0x03 /* 3 times try request before error */ - struct diosubd_data { int chans; /* num of chans */ int addr; /* PCI address ofset */ @@ -365,14 +286,6 @@ static const struct dio_boardtype boardtypes[] = { .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, .io_access = IO_16b, }, - [TYPE_PCI1760] = { - /* This card has its own 'attach' */ - .name = "pci1760", - .main_pci_region = 0, - .cardtype = TYPE_PCI1760, - .nsubdevs = 4, - .io_access = IO_8b, - }, [TYPE_PCI1762] = { .name = "pci1762", .main_pci_region = PCIDIO_MAINREG, @@ -385,25 +298,6 @@ static const struct dio_boardtype boardtypes[] = { }, }; -struct pci_dio_private { - char GlobalIrqEnabled; /* 1= any IRQ source is enabled */ - /* PCI-1760 specific data */ - unsigned char IDICntEnable; /* counter's counting enable status */ - unsigned char IDICntOverEnable; /* counter's overflow interrupts enable - * status */ - unsigned char IDICntMatchEnable; /* counter's match interrupts - * enable status */ - unsigned char IDICntEdge; /* counter's count edge value - * (bit=0 - rising, =1 - falling) */ - unsigned short CntResValue[8]; /* counters' reset value */ - unsigned short CntMatchValue[8]; /* counters' match interrupt value */ - unsigned char IDIFiltersEn; /* IDI's digital filters enable status */ - unsigned char IDIPatMatchEn; /* IDI's pattern match enable status */ - unsigned char IDIPatMatchValue; /* IDI's pattern match value */ - unsigned short IDIFiltrLow[8]; /* IDI's filter value low signal */ - unsigned short IDIFiltrHigh[8]; /* IDI's filter value high signal */ -}; - /* ============================================================================== */ @@ -476,260 +370,6 @@ static int pci_dio_insn_bits_do_w(struct comedi_device *dev, return insn->n; } -/* -============================================================================== -*/ -static int pci1760_unchecked_mbxrequest(struct comedi_device *dev, - unsigned char *omb, unsigned char *imb, - int repeats) -{ - int cnt, tout, ok = 0; - - for (cnt = 0; cnt < repeats; cnt++) { - outb(omb[0], dev->iobase + OMB0); - outb(omb[1], dev->iobase + OMB1); - outb(omb[2], dev->iobase + OMB2); - outb(omb[3], dev->iobase + OMB3); - for (tout = 0; tout < 251; tout++) { - imb[2] = inb(dev->iobase + IMB2); - if (imb[2] == omb[2]) { - imb[0] = inb(dev->iobase + IMB0); - imb[1] = inb(dev->iobase + IMB1); - imb[3] = inb(dev->iobase + IMB3); - ok = 1; - break; - } - udelay(1); - } - if (ok) - return 0; - } - - dev_err(dev->class_dev, "PCI-1760 mailbox request timeout!\n"); - return -ETIME; -} - -static int pci1760_clear_imb2(struct comedi_device *dev) -{ - unsigned char omb[4] = { 0x0, 0x0, CMD_ClearIMB2, 0x0 }; - unsigned char imb[4]; - /* check if imb2 is already clear */ - if (inb(dev->iobase + IMB2) == CMD_ClearIMB2) - return 0; - return pci1760_unchecked_mbxrequest(dev, omb, imb, OMBCMD_RETRY); -} - -static int pci1760_mbxrequest(struct comedi_device *dev, - unsigned char *omb, unsigned char *imb) -{ - if (omb[2] == CMD_ClearIMB2) { - dev_err(dev->class_dev, - "bug! this function should not be used for CMD_ClearIMB2 command\n"); - return -EINVAL; - } - if (inb(dev->iobase + IMB2) == omb[2]) { - int retval; - - retval = pci1760_clear_imb2(dev); - if (retval < 0) - return retval; - } - return pci1760_unchecked_mbxrequest(dev, omb, imb, OMBCMD_RETRY); -} - -/* -============================================================================== -*/ -static int pci1760_insn_bits_di(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - data[1] = inb(dev->iobase + IMB3); - - return insn->n; -} - -static int pci1760_insn_bits_do(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - int ret; - unsigned char omb[4] = { - 0x00, - 0x00, - CMD_SetRelaysOutput, - 0x00 - }; - unsigned char imb[4]; - - if (comedi_dio_update_state(s, data)) { - omb[0] = s->state; - ret = pci1760_mbxrequest(dev, omb, imb); - if (!ret) - return ret; - } - - data[1] = s->state; - - return insn->n; -} - -/* -============================================================================== -*/ -static int pci1760_insn_cnt_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - int ret, n; - unsigned char omb[4] = { - CR_CHAN(insn->chanspec) & 0x07, - 0x00, - CMD_GetIDICntCurValue, - 0x00 - }; - unsigned char imb[4]; - - for (n = 0; n < insn->n; n++) { - ret = pci1760_mbxrequest(dev, omb, imb); - if (!ret) - return ret; - data[n] = (imb[1] << 8) + imb[0]; - } - - return n; -} - -/* -============================================================================== -*/ -static int pci1760_insn_cnt_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct pci_dio_private *devpriv = dev->private; - int ret; - unsigned char chan = CR_CHAN(insn->chanspec) & 0x07; - unsigned char bitmask = 1 << chan; - unsigned char omb[4] = { - data[0] & 0xff, - (data[0] >> 8) & 0xff, - CMD_SetIDI0CntResetValue + chan, - 0x00 - }; - unsigned char imb[4]; - - /* Set reset value if different */ - if (devpriv->CntResValue[chan] != (data[0] & 0xffff)) { - ret = pci1760_mbxrequest(dev, omb, imb); - if (!ret) - return ret; - devpriv->CntResValue[chan] = data[0] & 0xffff; - } - - omb[0] = bitmask; /* reset counter to it reset value */ - omb[2] = CMD_ResetIDICounters; - ret = pci1760_mbxrequest(dev, omb, imb); - if (!ret) - return ret; - - /* start counter if it don't run */ - if (!(bitmask & devpriv->IDICntEnable)) { - omb[0] = bitmask; - omb[2] = CMD_EnableIDICounters; - ret = pci1760_mbxrequest(dev, omb, imb); - if (!ret) - return ret; - devpriv->IDICntEnable |= bitmask; - } - return 1; -} - -/* -============================================================================== -*/ -static int pci1760_reset(struct comedi_device *dev) -{ - struct pci_dio_private *devpriv = dev->private; - int i; - unsigned char omb[4] = { 0x00, 0x00, 0x00, 0x00 }; - unsigned char imb[4]; - - outb(0, dev->iobase + INTCSR0); /* disable IRQ */ - outb(0, dev->iobase + INTCSR1); - outb(0, dev->iobase + INTCSR2); - outb(0, dev->iobase + INTCSR3); - devpriv->GlobalIrqEnabled = 0; - - omb[0] = 0x00; - omb[2] = CMD_SetRelaysOutput; /* reset relay outputs */ - pci1760_mbxrequest(dev, omb, imb); - - omb[0] = 0x00; - omb[2] = CMD_EnableIDICounters; /* disable IDI up counters */ - pci1760_mbxrequest(dev, omb, imb); - devpriv->IDICntEnable = 0; - - omb[0] = 0x00; - omb[2] = CMD_OverflowIDICounters; /* disable counters overflow - * interrupts */ - pci1760_mbxrequest(dev, omb, imb); - devpriv->IDICntOverEnable = 0; - - omb[0] = 0x00; - omb[2] = CMD_MatchIntIDICounters; /* disable counters match value - * interrupts */ - pci1760_mbxrequest(dev, omb, imb); - devpriv->IDICntMatchEnable = 0; - - omb[0] = 0x00; - omb[1] = 0x80; - for (i = 0; i < 8; i++) { /* set IDI up counters match value */ - omb[2] = CMD_SetIDI0CntMatchValue + i; - pci1760_mbxrequest(dev, omb, imb); - devpriv->CntMatchValue[i] = 0x8000; - } - - omb[0] = 0x00; - omb[1] = 0x00; - for (i = 0; i < 8; i++) { /* set IDI up counters reset value */ - omb[2] = CMD_SetIDI0CntResetValue + i; - pci1760_mbxrequest(dev, omb, imb); - devpriv->CntResValue[i] = 0x0000; - } - - omb[0] = 0xff; - omb[2] = CMD_ResetIDICounters; /* reset IDI up counters to reset - * values */ - pci1760_mbxrequest(dev, omb, imb); - - omb[0] = 0x00; - omb[2] = CMD_EdgeIDICounters; /* set IDI up counters count edge */ - pci1760_mbxrequest(dev, omb, imb); - devpriv->IDICntEdge = 0x00; - - omb[0] = 0x00; - omb[2] = CMD_EnableIDIFilters; /* disable all digital in filters */ - pci1760_mbxrequest(dev, omb, imb); - devpriv->IDIFiltersEn = 0x00; - - omb[0] = 0x00; - omb[2] = CMD_EnableIDIPatternMatch; /* disable pattern matching */ - pci1760_mbxrequest(dev, omb, imb); - devpriv->IDIPatMatchEn = 0x00; - - omb[0] = 0x00; - omb[2] = CMD_SetIDIPatternMatch; /* set pattern match value */ - pci1760_mbxrequest(dev, omb, imb); - devpriv->IDIPatMatchValue = 0x00; - - return 0; -} - -/* -============================================================================== -*/ static int pci_dio_reset(struct comedi_device *dev) { const struct dio_boardtype *board = dev->board_ptr; @@ -821,9 +461,6 @@ static int pci_dio_reset(struct comedi_device *dev) outw(0, dev->iobase + PCI1756_IDO); /* clear outputs */ outw(0, dev->iobase + PCI1756_IDO + 2); break; - case TYPE_PCI1760: - pci1760_reset(dev); - break; case TYPE_PCI1762: outw(0x0101, dev->iobase + PCI1762_ICR); /* disable & clear * interrupts */ @@ -833,56 +470,6 @@ static int pci_dio_reset(struct comedi_device *dev) return 0; } -/* -============================================================================== -*/ -static int pci1760_attach(struct comedi_device *dev) -{ - struct comedi_subdevice *s; - - s = &dev->subdevices[0]; - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE; - s->n_chan = 8; - s->maxdata = 1; - s->len_chanlist = 8; - s->range_table = &range_digital; - s->insn_bits = pci1760_insn_bits_di; - - s = &dev->subdevices[1]; - s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = 8; - s->maxdata = 1; - s->len_chanlist = 8; - s->range_table = &range_digital; - s->state = 0; - s->insn_bits = pci1760_insn_bits_do; - - s = &dev->subdevices[2]; - s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITABLE | SDF_LSAMPL; - s->n_chan = 2; - s->maxdata = 0xffffffff; - s->len_chanlist = 2; -/* s->insn_config=pci1760_insn_pwm_cfg; */ - - s = &dev->subdevices[3]; - s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 8; - s->maxdata = 0xffff; - s->len_chanlist = 8; - s->insn_read = pci1760_insn_cnt_read; - s->insn_write = pci1760_insn_cnt_write; -/* s->insn_config=pci1760_insn_cnt_cfg; */ - - return 0; -} - -/* -============================================================================== -*/ static int pci_dio_add_di(struct comedi_device *dev, struct comedi_subdevice *s, const struct diosubd_data *d) @@ -979,7 +566,6 @@ static int pci_dio_auto_attach(struct comedi_device *dev, { struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct dio_boardtype *board = NULL; - struct pci_dio_private *devpriv; struct comedi_subdevice *s; int ret, subdev, i, j; @@ -990,10 +576,6 @@ static int pci_dio_auto_attach(struct comedi_device *dev, dev->board_ptr = board; dev->board_name = board->name; - devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); - if (!devpriv) - return -ENOMEM; - ret = comedi_pci_enable(dev); if (ret) return ret; @@ -1050,9 +632,6 @@ static int pci_dio_auto_attach(struct comedi_device *dev, subdev++; } - if (board->cardtype == TYPE_PCI1760) - pci1760_attach(dev); - pci_dio_reset(dev); return 0; @@ -1094,7 +673,6 @@ static const struct pci_device_id adv_pci_dio_pci_table[] = { { PCI_VDEVICE(ADVANTECH, 0x1753), TYPE_PCI1753 }, { PCI_VDEVICE(ADVANTECH, 0x1754), TYPE_PCI1754 }, { PCI_VDEVICE(ADVANTECH, 0x1756), TYPE_PCI1756 }, - { PCI_VDEVICE(ADVANTECH, 0x1760), TYPE_PCI1760 }, { PCI_VDEVICE(ADVANTECH, 0x1762), TYPE_PCI1762 }, { 0 } }; -- GitLab From 6fa60dd4a46cdb698cbda705015d7425d1a548bc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:04 -0700 Subject: [PATCH 1685/2855] staging: comedi: adv_pci1710: remove 'has_irq' boardinfo All the boards supported by this driver can use an interrupt. Remove the unnecessary boardinfo. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 45d7f42312ec3..032d1d41a1398 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -134,7 +134,6 @@ struct boardtype { const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ const char *rangecode_ai; /* range codes for programming */ unsigned int is_pci1713:1; - unsigned int has_irq:1; unsigned int has_large_fifo:1; /* 4K or 1K FIFO */ unsigned int has_diff_ai:1; unsigned int has_ao:1; @@ -148,7 +147,6 @@ static const struct boardtype boardtypes[] = { .n_aichan = 16, .rangelist_ai = &range_pci1710_3, .rangecode_ai = range_codes_pci1710_3, - .has_irq = 1, .has_large_fifo = 1, .has_diff_ai = 1, .has_ao = 1, @@ -160,7 +158,6 @@ static const struct boardtype boardtypes[] = { .n_aichan = 16, .rangelist_ai = &range_pci1710hg, .rangecode_ai = range_codes_pci1710hg, - .has_irq = 1, .has_large_fifo = 1, .has_diff_ai = 1, .has_ao = 1, @@ -172,7 +169,6 @@ static const struct boardtype boardtypes[] = { .n_aichan = 16, .rangelist_ai = &range_pci17x1, .rangecode_ai = range_codes_pci17x1, - .has_irq = 1, .has_ao = 1, .has_di_do = 1, .has_counter = 1, @@ -183,7 +179,6 @@ static const struct boardtype boardtypes[] = { .rangelist_ai = &range_pci1710_3, .rangecode_ai = range_codes_pci1710_3, .is_pci1713 = 1, - .has_irq = 1, .has_large_fifo = 1, .has_diff_ai = 1, }, @@ -192,7 +187,6 @@ static const struct boardtype boardtypes[] = { .n_aichan = 16, .rangelist_ai = &range_pci17x1, .rangecode_ai = range_codes_pci17x1, - .has_irq = 1, .has_di_do = 1, }, }; @@ -806,7 +800,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, pci1710_reset(dev); - if (board->has_irq && pcidev->irq) { + if (pcidev->irq) { ret = request_irq(pcidev->irq, interrupt_service_pci1710, IRQF_SHARED, dev->board_name, dev); if (ret == 0) -- GitLab From 8a8d0875a5ccf14a6772b3bbffa1717e668a0d8a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:05 -0700 Subject: [PATCH 1686/2855] staging: comedi: adv_pci1710: remove 'has_counter' boardinfo All the boards supported by this driver have a 8254 counter. Channels 1 and 2 are used to create the cascaded 32-bit analog input pacer. Counter 0 is available for the user on all the boards except the PCI-1713. Remove the 'has_counter' boardinfo and use the 'is_pci1713' boardinfo to determine if the user counter subdevice needs to be allocated and initialized. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 032d1d41a1398..62f9f478421c4 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -138,7 +138,6 @@ struct boardtype { unsigned int has_diff_ai:1; unsigned int has_ao:1; unsigned int has_di_do:1; - unsigned int has_counter:1; }; static const struct boardtype boardtypes[] = { @@ -151,7 +150,6 @@ static const struct boardtype boardtypes[] = { .has_diff_ai = 1, .has_ao = 1, .has_di_do = 1, - .has_counter = 1, }, [BOARD_PCI1710HG] = { .name = "pci1710hg", @@ -162,7 +160,6 @@ static const struct boardtype boardtypes[] = { .has_diff_ai = 1, .has_ao = 1, .has_di_do = 1, - .has_counter = 1, }, [BOARD_PCI1711] = { .name = "pci1711", @@ -171,7 +168,6 @@ static const struct boardtype boardtypes[] = { .rangecode_ai = range_codes_pci17x1, .has_ao = 1, .has_di_do = 1, - .has_counter = 1, }, [BOARD_PCI1713] = { .name = "pci1713", @@ -791,7 +787,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, n_subdevices++; if (board->has_di_do) n_subdevices += 2; - if (board->has_counter) + if (!board->is_pci1713) /* all other boards have a user counter */ n_subdevices++; ret = comedi_alloc_subdevices(dev, n_subdevices); @@ -866,8 +862,8 @@ static int pci1710_auto_attach(struct comedi_device *dev, subdev++; } - /* Counter subdevice (8254) */ - if (board->has_counter) { + if (!board->is_pci1713) { + /* Counter subdevice (8254) */ s = &dev->subdevices[subdev]; comedi_8254_subdevice_init(s, dev->pacer); -- GitLab From 19cbb8fb798f9e391df2876ea9522fbd6be88358 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:06 -0700 Subject: [PATCH 1687/2855] staging: comedi: adv_pci1710: don't "reset" board when detaching Currently this driver calls pci1710_reset() during the (*detach) of the driver. That function does the following: 1) program the control register to stop any operations 2) clears the analog input FIFO 3) clears any pending interrupts 4) sets all the analog output channels to unipolar 5V range and 0V output 5) sets all the digital outputs to 0V Before detaching the comedi core will (*cancel) any running async commands. This will handle 1-3 above. Depending on the application, it might not be safe to reset the analog and digital outputs when the driver is detached. Remove the board reset when detaching and just use comedi_pci_detach() directly for the driver (*detach). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 62f9f478421c4..e6d9db865d3b2 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -882,18 +882,11 @@ static int pci1710_auto_attach(struct comedi_device *dev, return 0; } -static void pci1710_detach(struct comedi_device *dev) -{ - if (dev->iobase) - pci1710_reset(dev); - comedi_pci_detach(dev); -} - static struct comedi_driver adv_pci1710_driver = { .driver_name = "adv_pci1710", .module = THIS_MODULE, .auto_attach = pci1710_auto_attach, - .detach = pci1710_detach, + .detach = comedi_pci_detach, }; static int adv_pci1710_pci_probe(struct pci_dev *dev, -- GitLab From 7603900fc7b41c71753d69487930eda707048b9d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:07 -0700 Subject: [PATCH 1688/2855] staging: comedi: adv_pci1710: refactor ai range programming The gain codes used to program the analog output range are currently stored in const char arrays. The values look a bit "magic" and it's not clear how they associate with the comedi_lrange without looking through user manuals. Refactor the ai range programming to clarify the driver and remove the magic numbers. Also, refine the bits in the range register that set the differential and unipolar modes. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 108 ++++++++++--------- 1 file changed, 55 insertions(+), 53 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index e6d9db865d3b2..8fa3db304a6f0 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -41,6 +41,9 @@ #define PCI171X_AD_DATA_REG 0x00 /* R: A/D data */ #define PCI171X_SOFTTRG_REG 0x00 /* W: soft trigger for A/D */ #define PCI171X_RANGE_REG 0x02 /* W: A/D gain/range register */ +#define PCI171X_RANGE_DIFF BIT(5) +#define PCI171X_RANGE_UNI BIT(4) +#define PCI171X_RANGE_GAIN(x) (((x) & 0x7) << 0) #define PCI171X_MUX_REG 0x04 /* W: A/D multiplexor control */ #define PCI171X_STATUS_REG 0x06 /* R: status register */ #define PCI171X_STATUS_IRQ BIT(11) /* 1=IRQ occurred */ @@ -63,56 +66,47 @@ #define PCI171X_DO_REG 0x10 /* W: digital outputs */ #define PCI171X_TIMER_BASE 0x18 /* R/W: 8254 timer */ -static const struct comedi_lrange range_pci1710_3 = { +static const struct comedi_lrange pci1710_ai_range = { 9, { - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - BIP_RANGE(0.625), - BIP_RANGE(10), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25) + BIP_RANGE(5), /* gain 1 (0x00) */ + BIP_RANGE(2.5), /* gain 2 (0x01) */ + BIP_RANGE(1.25), /* gain 4 (0x02) */ + BIP_RANGE(0.625), /* gain 8 (0x03) */ + BIP_RANGE(10), /* gain 0.5 (0x04) */ + UNI_RANGE(10), /* gain 1 (0x00 | UNI) */ + UNI_RANGE(5), /* gain 2 (0x01 | UNI) */ + UNI_RANGE(2.5), /* gain 4 (0x02 | UNI) */ + UNI_RANGE(1.25) /* gain 8 (0x03 | UNI) */ } }; -static const char range_codes_pci1710_3[] = { 0x00, 0x01, 0x02, 0x03, 0x04, - 0x10, 0x11, 0x12, 0x13 }; - -static const struct comedi_lrange range_pci1710hg = { +static const struct comedi_lrange pci1710hg_ai_range = { 12, { - BIP_RANGE(5), - BIP_RANGE(0.5), - BIP_RANGE(0.05), - BIP_RANGE(0.005), - BIP_RANGE(10), - BIP_RANGE(1), - BIP_RANGE(0.1), - BIP_RANGE(0.01), - UNI_RANGE(10), - UNI_RANGE(1), - UNI_RANGE(0.1), - UNI_RANGE(0.01) + BIP_RANGE(5), /* gain 1 (0x00) */ + BIP_RANGE(0.5), /* gain 10 (0x01) */ + BIP_RANGE(0.05), /* gain 100 (0x02) */ + BIP_RANGE(0.005), /* gain 1000 (0x03) */ + BIP_RANGE(10), /* gain 0.5 (0x04) */ + BIP_RANGE(1), /* gain 5 (0x05) */ + BIP_RANGE(0.1), /* gain 50 (0x06) */ + BIP_RANGE(0.01), /* gain 500 (0x07) */ + UNI_RANGE(10), /* gain 1 (0x00 | UNI) */ + UNI_RANGE(1), /* gain 10 (0x01 | UNI) */ + UNI_RANGE(0.1), /* gain 100 (0x02 | UNI) */ + UNI_RANGE(0.01) /* gain 1000 (0x03 | UNI) */ } }; -static const char range_codes_pci1710hg[] = { 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x06, 0x07, 0x10, 0x11, - 0x12, 0x13 }; - -static const struct comedi_lrange range_pci17x1 = { +static const struct comedi_lrange pci1711_ai_range = { 5, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - BIP_RANGE(0.625) + BIP_RANGE(10), /* gain 1 (0x00) */ + BIP_RANGE(5), /* gain 2 (0x01) */ + BIP_RANGE(2.5), /* gain 4 (0x02) */ + BIP_RANGE(1.25), /* gain 8 (0x03) */ + BIP_RANGE(0.625) /* gain 16 (0x04) */ } }; -static const char range_codes_pci17x1[] = { 0x00, 0x01, 0x02, 0x03, 0x04 }; - static const struct comedi_lrange pci171x_ao_range = { 2, { UNI_RANGE(5), @@ -132,7 +126,6 @@ struct boardtype { const char *name; /* board name */ int n_aichan; /* num of A/D chans */ const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ - const char *rangecode_ai; /* range codes for programming */ unsigned int is_pci1713:1; unsigned int has_large_fifo:1; /* 4K or 1K FIFO */ unsigned int has_diff_ai:1; @@ -144,8 +137,7 @@ static const struct boardtype boardtypes[] = { [BOARD_PCI1710] = { .name = "pci1710", .n_aichan = 16, - .rangelist_ai = &range_pci1710_3, - .rangecode_ai = range_codes_pci1710_3, + .rangelist_ai = &pci1710_ai_range, .has_large_fifo = 1, .has_diff_ai = 1, .has_ao = 1, @@ -154,8 +146,7 @@ static const struct boardtype boardtypes[] = { [BOARD_PCI1710HG] = { .name = "pci1710hg", .n_aichan = 16, - .rangelist_ai = &range_pci1710hg, - .rangecode_ai = range_codes_pci1710hg, + .rangelist_ai = &pci1710hg_ai_range, .has_large_fifo = 1, .has_diff_ai = 1, .has_ao = 1, @@ -164,16 +155,14 @@ static const struct boardtype boardtypes[] = { [BOARD_PCI1711] = { .name = "pci1711", .n_aichan = 16, - .rangelist_ai = &range_pci17x1, - .rangecode_ai = range_codes_pci17x1, + .rangelist_ai = &pci1711_ai_range, .has_ao = 1, .has_di_do = 1, }, [BOARD_PCI1713] = { .name = "pci1713", .n_aichan = 32, - .rangelist_ai = &range_pci1710_3, - .rangecode_ai = range_codes_pci1710_3, + .rangelist_ai = &pci1710_ai_range, .is_pci1713 = 1, .has_large_fifo = 1, .has_diff_ai = 1, @@ -181,8 +170,7 @@ static const struct boardtype boardtypes[] = { [BOARD_PCI1731] = { .name = "pci1731", .n_aichan = 16, - .rangelist_ai = &range_pci17x1, - .rangecode_ai = range_codes_pci17x1, + .rangelist_ai = &pci1711_ai_range, .has_di_do = 1, }, }; @@ -196,6 +184,7 @@ struct pci1710_private { unsigned int act_chanlist[32]; /* list of scanned channel */ unsigned char saved_seglen; /* len of the non-repeating chanlist */ unsigned char da_ranges; /* copy of D/A outpit range register */ + unsigned char unipolar_gain; /* adjust for unipolar gain codes */ }; static int pci171x_ai_check_chanlist(struct comedi_device *dev, @@ -270,7 +259,6 @@ static void pci171x_ai_setup_chanlist(struct comedi_device *dev, unsigned int n_chan, unsigned int seglen) { - const struct boardtype *board = dev->board_ptr; struct pci1710_private *devpriv = dev->private; unsigned int first_chan = CR_CHAN(chanlist[0]); unsigned int last_chan = CR_CHAN(chanlist[seglen - 1]); @@ -280,11 +268,15 @@ static void pci171x_ai_setup_chanlist(struct comedi_device *dev, unsigned int chan = CR_CHAN(chanlist[i]); unsigned int range = CR_RANGE(chanlist[i]); unsigned int aref = CR_AREF(chanlist[i]); - unsigned int rangeval; + unsigned int rangeval = 0; - rangeval = board->rangecode_ai[range]; if (aref == AREF_DIFF) - rangeval |= 0x0020; + rangeval |= PCI171X_RANGE_DIFF; + if (comedi_range_is_unipolar(s, range)) { + rangeval |= PCI171X_RANGE_UNI; + range -= devpriv->unipolar_gain; + } + rangeval |= PCI171X_RANGE_GAIN(range); /* select channel and set range */ outw(chan | (chan << 8), dev->iobase + PCI171X_MUX_REG); @@ -758,6 +750,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, struct pci1710_private *devpriv; struct comedi_subdevice *s; int ret, subdev, n_subdevices; + int i; if (context < ARRAY_SIZE(boardtypes)) board = &boardtypes[context]; @@ -823,6 +816,15 @@ static int pci1710_auto_attach(struct comedi_device *dev, s->do_cmd = pci171x_ai_cmd; s->cancel = pci171x_ai_cancel; } + + /* find the value needed to adjust for unipolar gain codes */ + for (i = 0; i < s->range_table->length; i++) { + if (comedi_range_is_unipolar(s, i)) { + devpriv->unipolar_gain = i; + break; + } + } + subdev++; } -- GitLab From 92c65e5553ed0a887735dfc1b86911541ca8be3e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:08 -0700 Subject: [PATCH 1689/2855] staging: comedi: adv_pci1710: define the mux control register bits For aesthetics, define some macros to set the bits in the mux control register. Also, rename the 'mux_ext' member of the private data. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 8fa3db304a6f0..ed6c9fb65efe0 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -45,6 +45,9 @@ #define PCI171X_RANGE_UNI BIT(4) #define PCI171X_RANGE_GAIN(x) (((x) & 0x7) << 0) #define PCI171X_MUX_REG 0x04 /* W: A/D multiplexor control */ +#define PCI171X_MUX_CHANH(x) (((x) & 0xf) << 8) +#define PCI171X_MUX_CHANL(x) (((x) & 0xf) << 0) +#define PCI171X_MUX_CHAN(x) (PCI171X_MUX_CHANH(x) | PCI171X_MUX_CHANL(x)) #define PCI171X_STATUS_REG 0x06 /* R: status register */ #define PCI171X_STATUS_IRQ BIT(11) /* 1=IRQ occurred */ #define PCI171X_STATUS_FF BIT(10) /* 1=FIFO is full, fatal error */ @@ -179,7 +182,7 @@ struct pci1710_private { unsigned int max_samples; unsigned int ctrl; /* control register value */ unsigned int ctrl_ext; /* used to switch from TRIG_EXT to TRIG_xxx */ - unsigned int mux_ext; /* used to set the channel interval to scan */ + unsigned int mux_scan; /* used to set the channel interval to scan */ unsigned char ai_et; unsigned int act_chanlist[32]; /* list of scanned channel */ unsigned char saved_seglen; /* len of the non-repeating chanlist */ @@ -279,7 +282,7 @@ static void pci171x_ai_setup_chanlist(struct comedi_device *dev, rangeval |= PCI171X_RANGE_GAIN(range); /* select channel and set range */ - outw(chan | (chan << 8), dev->iobase + PCI171X_MUX_REG); + outw(PCI171X_MUX_CHAN(chan), dev->iobase + PCI171X_MUX_REG); outw(rangeval, dev->iobase + PCI171X_RANGE_REG); devpriv->act_chanlist[i] = chan; @@ -288,8 +291,9 @@ static void pci171x_ai_setup_chanlist(struct comedi_device *dev, devpriv->act_chanlist[i] = CR_CHAN(chanlist[i]); /* select channel interval to scan */ - devpriv->mux_ext = first_chan | (last_chan << 8); - outw(devpriv->mux_ext, dev->iobase + PCI171X_MUX_REG); + devpriv->mux_scan = PCI171X_MUX_CHANL(first_chan) | + PCI171X_MUX_CHANH(last_chan); + outw(devpriv->mux_scan, dev->iobase + PCI171X_MUX_REG); } static int pci171x_ai_eoc(struct comedi_device *dev, @@ -551,7 +555,7 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d) outb(0, dev->iobase + PCI171X_CLRFIFO_REG); outb(0, dev->iobase + PCI171X_CLRINT_REG); /* no sample on this interrupt; reset the channel interval */ - outw(devpriv->mux_ext, dev->iobase + PCI171X_MUX_REG); + outw(devpriv->mux_scan, dev->iobase + PCI171X_MUX_REG); outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG); comedi_8254_pacer_enable(dev->pacer, 1, 2, true); return IRQ_HANDLED; -- GitLab From 0b458e730412b3d3d3d2e5c59924177acbbcf755 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:09 -0700 Subject: [PATCH 1690/2855] staging: comedi: adv_pci1710: remove 'n_aichan' boardinfo This member of the boardinfo isn't really necessary. All the boards have analog inputs, the pci1713 has 32 channels the rest have 16 channels. There is already a 'is_pci1713' member in the boardinfo so that can be used to determine the number of channels for the analog input subdevice. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 61 +++++++++----------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index ed6c9fb65efe0..8d205ae8f6964 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -127,7 +127,6 @@ enum pci1710_boardid { struct boardtype { const char *name; /* board name */ - int n_aichan; /* num of A/D chans */ const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ unsigned int is_pci1713:1; unsigned int has_large_fifo:1; /* 4K or 1K FIFO */ @@ -139,7 +138,6 @@ struct boardtype { static const struct boardtype boardtypes[] = { [BOARD_PCI1710] = { .name = "pci1710", - .n_aichan = 16, .rangelist_ai = &pci1710_ai_range, .has_large_fifo = 1, .has_diff_ai = 1, @@ -148,7 +146,6 @@ static const struct boardtype boardtypes[] = { }, [BOARD_PCI1710HG] = { .name = "pci1710hg", - .n_aichan = 16, .rangelist_ai = &pci1710hg_ai_range, .has_large_fifo = 1, .has_diff_ai = 1, @@ -157,14 +154,12 @@ static const struct boardtype boardtypes[] = { }, [BOARD_PCI1711] = { .name = "pci1711", - .n_aichan = 16, .rangelist_ai = &pci1711_ai_range, .has_ao = 1, .has_di_do = 1, }, [BOARD_PCI1713] = { .name = "pci1713", - .n_aichan = 32, .rangelist_ai = &pci1710_ai_range, .is_pci1713 = 1, .has_large_fifo = 1, @@ -172,7 +167,6 @@ static const struct boardtype boardtypes[] = { }, [BOARD_PCI1731] = { .name = "pci1731", - .n_aichan = 16, .rangelist_ai = &pci1711_ai_range, .has_di_do = 1, }, @@ -777,9 +771,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, if (!dev->pacer) return -ENOMEM; - n_subdevices = 0; - if (board->n_aichan) - n_subdevices++; + n_subdevices = 1; /* all boards have analog inputs */ if (board->has_ao) n_subdevices++; if (board->has_di_do) @@ -802,36 +794,35 @@ static int pci1710_auto_attach(struct comedi_device *dev, subdev = 0; - if (board->n_aichan) { - s = &dev->subdevices[subdev]; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND; - if (board->has_diff_ai) - s->subdev_flags |= SDF_DIFF; - s->n_chan = board->n_aichan; - s->maxdata = 0x0fff; - s->range_table = board->rangelist_ai; - s->insn_read = pci171x_ai_insn_read; - if (dev->irq) { - dev->read_subdev = s; - s->subdev_flags |= SDF_CMD_READ; - s->len_chanlist = s->n_chan; - s->do_cmdtest = pci171x_ai_cmdtest; - s->do_cmd = pci171x_ai_cmd; - s->cancel = pci171x_ai_cancel; - } + /* Analog Input subdevice */ + s = &dev->subdevices[subdev]; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND; + if (board->has_diff_ai) + s->subdev_flags |= SDF_DIFF; + s->n_chan = board->is_pci1713 ? 32 : 16; + s->maxdata = 0x0fff; + s->range_table = board->rangelist_ai; + s->insn_read = pci171x_ai_insn_read; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; + s->do_cmdtest = pci171x_ai_cmdtest; + s->do_cmd = pci171x_ai_cmd; + s->cancel = pci171x_ai_cancel; + } - /* find the value needed to adjust for unipolar gain codes */ - for (i = 0; i < s->range_table->length; i++) { - if (comedi_range_is_unipolar(s, i)) { - devpriv->unipolar_gain = i; - break; - } + /* find the value needed to adjust for unipolar gain codes */ + for (i = 0; i < s->range_table->length; i++) { + if (comedi_range_is_unipolar(s, i)) { + devpriv->unipolar_gain = i; + break; } - - subdev++; } + subdev++; + if (board->has_ao) { s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_AO; -- GitLab From 88601533ae91ce26fbd35441f11b57c3814eeb6a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:10 -0700 Subject: [PATCH 1691/2855] staging: comedi: adv_pci1710: remove 'has_di_do' boardinfo This member of the boardinfo isn't really necessary. All the boards except the pci1713 have 16 digital inputs and 16 digital outputs. There is already a 'is_pci1713' member in the boardinfo so that can be used to determine the subdevices for the digital inputs and outputs need to be allocated and initialized. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 22 +++++++++----------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 8d205ae8f6964..76f3793f7dc5a 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -132,7 +132,6 @@ struct boardtype { unsigned int has_large_fifo:1; /* 4K or 1K FIFO */ unsigned int has_diff_ai:1; unsigned int has_ao:1; - unsigned int has_di_do:1; }; static const struct boardtype boardtypes[] = { @@ -142,7 +141,6 @@ static const struct boardtype boardtypes[] = { .has_large_fifo = 1, .has_diff_ai = 1, .has_ao = 1, - .has_di_do = 1, }, [BOARD_PCI1710HG] = { .name = "pci1710hg", @@ -150,13 +148,11 @@ static const struct boardtype boardtypes[] = { .has_large_fifo = 1, .has_diff_ai = 1, .has_ao = 1, - .has_di_do = 1, }, [BOARD_PCI1711] = { .name = "pci1711", .rangelist_ai = &pci1711_ai_range, .has_ao = 1, - .has_di_do = 1, }, [BOARD_PCI1713] = { .name = "pci1713", @@ -168,7 +164,6 @@ static const struct boardtype boardtypes[] = { [BOARD_PCI1731] = { .name = "pci1731", .rangelist_ai = &pci1711_ai_range, - .has_di_do = 1, }, }; @@ -774,10 +769,13 @@ static int pci1710_auto_attach(struct comedi_device *dev, n_subdevices = 1; /* all boards have analog inputs */ if (board->has_ao) n_subdevices++; - if (board->has_di_do) - n_subdevices += 2; - if (!board->is_pci1713) /* all other boards have a user counter */ - n_subdevices++; + if (!board->is_pci1713) { + /* + * All other boards have digital inputs and outputs as + * well as a user counter. + */ + n_subdevices += 3; + } ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret) @@ -839,7 +837,8 @@ static int pci1710_auto_attach(struct comedi_device *dev, subdev++; } - if (board->has_di_do) { + if (!board->is_pci1713) { + /* Digital Input subdevice */ s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; @@ -849,6 +848,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, s->insn_bits = pci171x_di_insn_bits; subdev++; + /* Digital Output subdevice */ s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; @@ -857,9 +857,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, s->range_table = &range_digital; s->insn_bits = pci171x_do_insn_bits; subdev++; - } - if (!board->is_pci1713) { /* Counter subdevice (8254) */ s = &dev->subdevices[subdev]; comedi_8254_subdevice_init(s, dev->pacer); -- GitLab From dbdb6248229d1a9f2532cd86dcb8db270ea79034 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:11 -0700 Subject: [PATCH 1692/2855] staging: comedi: adv_pci1710: remove 'has_large_fifo' and 'has_diff_ai' boardinfo The pci1711/31 boards are the only ones that have a smaller FIFO (1K vs 4K) and single-ended analog inputs (no differential). Replace the 'has_large_fifo' and 'has_diff_ai' members of the boardinfo with 'is_pci1711' and use that to determine how to initialize the analog input subdev_flags as well as the private data 'max_samples'. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 76f3793f7dc5a..7088b76d34581 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -128,9 +128,8 @@ enum pci1710_boardid { struct boardtype { const char *name; /* board name */ const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ + unsigned int is_pci1711:1; unsigned int is_pci1713:1; - unsigned int has_large_fifo:1; /* 4K or 1K FIFO */ - unsigned int has_diff_ai:1; unsigned int has_ao:1; }; @@ -138,32 +137,28 @@ static const struct boardtype boardtypes[] = { [BOARD_PCI1710] = { .name = "pci1710", .rangelist_ai = &pci1710_ai_range, - .has_large_fifo = 1, - .has_diff_ai = 1, .has_ao = 1, }, [BOARD_PCI1710HG] = { .name = "pci1710hg", .rangelist_ai = &pci1710hg_ai_range, - .has_large_fifo = 1, - .has_diff_ai = 1, .has_ao = 1, }, [BOARD_PCI1711] = { .name = "pci1711", .rangelist_ai = &pci1711_ai_range, + .is_pci1711 = 1, .has_ao = 1, }, [BOARD_PCI1713] = { .name = "pci1713", .rangelist_ai = &pci1710_ai_range, .is_pci1713 = 1, - .has_large_fifo = 1, - .has_diff_ai = 1, }, [BOARD_PCI1731] = { .name = "pci1731", .rangelist_ai = &pci1711_ai_range, + .is_pci1711 = 1, }, }; @@ -796,7 +791,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND; - if (board->has_diff_ai) + if (!board->is_pci1711) s->subdev_flags |= SDF_DIFF; s->n_chan = board->is_pci1713 ? 32 : 16; s->maxdata = 0x0fff; @@ -872,7 +867,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, } /* max_samples is half the FIFO size (2 bytes/sample) */ - devpriv->max_samples = (board->has_large_fifo) ? 2048 : 512; + devpriv->max_samples = (board->is_pci1711) ? 512 : 2048; return 0; } -- GitLab From b5b147dcb48600f8372bdd8728bab8ef1840dac4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:12 -0700 Subject: [PATCH 1693/2855] staging: comedi: adv_pci1710: tidy up boardinfo definition Remove the unnecessary comments and rename the 'rangelist_ai' member for aesthetics. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 7088b76d34581..76371e03aec5b 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -126,8 +126,8 @@ enum pci1710_boardid { }; struct boardtype { - const char *name; /* board name */ - const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ + const char *name; + const struct comedi_lrange *ai_range; unsigned int is_pci1711:1; unsigned int is_pci1713:1; unsigned int has_ao:1; @@ -136,28 +136,28 @@ struct boardtype { static const struct boardtype boardtypes[] = { [BOARD_PCI1710] = { .name = "pci1710", - .rangelist_ai = &pci1710_ai_range, + .ai_range = &pci1710_ai_range, .has_ao = 1, }, [BOARD_PCI1710HG] = { .name = "pci1710hg", - .rangelist_ai = &pci1710hg_ai_range, + .ai_range = &pci1710hg_ai_range, .has_ao = 1, }, [BOARD_PCI1711] = { .name = "pci1711", - .rangelist_ai = &pci1711_ai_range, + .ai_range = &pci1711_ai_range, .is_pci1711 = 1, .has_ao = 1, }, [BOARD_PCI1713] = { .name = "pci1713", - .rangelist_ai = &pci1710_ai_range, + .ai_range = &pci1710_ai_range, .is_pci1713 = 1, }, [BOARD_PCI1731] = { .name = "pci1731", - .rangelist_ai = &pci1711_ai_range, + .ai_range = &pci1711_ai_range, .is_pci1711 = 1, }, }; @@ -795,7 +795,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, s->subdev_flags |= SDF_DIFF; s->n_chan = board->is_pci1713 ? 32 : 16; s->maxdata = 0x0fff; - s->range_table = board->rangelist_ai; + s->range_table = board->ai_range; s->insn_read = pci171x_ai_insn_read; if (dev->irq) { dev->read_subdev = s; -- GitLab From 96d57c15ab8acca8ca2ceeebee67c0962134ddcf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:13 -0700 Subject: [PATCH 1694/2855] staging: comedi: adv_pci1710: rename interrupt_service_pci1710() Rename this function so it has namespace associated with the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 76371e03aec5b..3c660ee2ae893 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -513,7 +513,7 @@ static void pci1710_handle_fifo(struct comedi_device *dev, outb(0, dev->iobase + PCI171X_CLRINT_REG); } -static irqreturn_t interrupt_service_pci1710(int irq, void *d) +static irqreturn_t pci1710_irq_handler(int irq, void *d) { struct comedi_device *dev = d; struct pci1710_private *devpriv = dev->private; @@ -779,7 +779,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, pci1710_reset(dev); if (pcidev->irq) { - ret = request_irq(pcidev->irq, interrupt_service_pci1710, + ret = request_irq(pcidev->irq, pci1710_irq_handler, IRQF_SHARED, dev->board_name, dev); if (ret == 0) dev->irq = pcidev->irq; -- GitLab From f1f4ce6462b65523edfaae2233046c93ca7c25a7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:14 -0700 Subject: [PATCH 1695/2855] staging: comedi: adv_pci1710: rename pci171x_insn_counter_config() Rename this function so it has namespace associated with the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 3c660ee2ae893..4a8604f09512d 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -668,7 +668,7 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, return 0; } -static int pci171x_insn_counter_config(struct comedi_device *dev, +static int pci1710_counter_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -857,7 +857,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, s = &dev->subdevices[subdev]; comedi_8254_subdevice_init(s, dev->pacer); - dev->pacer->insn_config = pci171x_insn_counter_config; + dev->pacer->insn_config = pci1710_counter_insn_config; /* counters 1 and 2 are used internally for the pacer */ comedi_8254_set_busy(dev->pacer, 1, true); -- GitLab From 6039278668cd162cacc95a883b59b933e39dc2f5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:15 -0700 Subject: [PATCH 1696/2855] staging: comedi: adv_pci1710: rename pci171x_d[io]_insn_bits Rename these functions so they have namespace associated with the driver. For aesthetics, move the functions so they are not located in the middle of the analog input/output support functions. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 50 ++++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 4a8604f09512d..45661228ed56d 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -387,29 +387,6 @@ static int pci171x_ao_insn_write(struct comedi_device *dev, return insn->n; } -static int pci171x_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - data[1] = inw(dev->iobase + PCI171X_DI_REG); - - return insn->n; -} - -static int pci171x_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - if (comedi_dio_update_state(s, data)) - outw(s->state, dev->iobase + PCI171X_DO_REG); - - data[1] = s->state; - - return insn->n; -} - static int pci171x_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -668,6 +645,29 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, return 0; } +static int pci1710_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + data[1] = inw(dev->iobase + PCI171X_DI_REG); + + return insn->n; +} + +static int pci1710_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + if (comedi_dio_update_state(s, data)) + outw(s->state, dev->iobase + PCI171X_DO_REG); + + data[1] = s->state; + + return insn->n; +} + static int pci1710_counter_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -840,7 +840,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; - s->insn_bits = pci171x_di_insn_bits; + s->insn_bits = pci1710_di_insn_bits; subdev++; /* Digital Output subdevice */ @@ -850,7 +850,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; - s->insn_bits = pci171x_do_insn_bits; + s->insn_bits = pci1710_do_insn_bits; subdev++; /* Counter subdevice (8254) */ -- GitLab From baacf6ca54291aec45babc4af079a39b64b02da3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:16 -0700 Subject: [PATCH 1697/2855] staging: comedi: adv_pci1710: rename pci171x_ao_insn_write() Rename this function so it has namespace associated with the driver. For aesthetics, move the function so it is located in the middle of the analog input support functions. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 52 ++++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 45661228ed56d..cc451f131857b 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -362,31 +362,6 @@ static int pci171x_ai_insn_read(struct comedi_device *dev, return ret ? ret : insn->n; } -static int pci171x_ao_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct pci1710_private *devpriv = dev->private; - unsigned int chan = CR_CHAN(insn->chanspec); - unsigned int range = CR_RANGE(insn->chanspec); - unsigned int val = s->readback[chan]; - int i; - - devpriv->da_ranges &= ~(1 << (chan << 1)); - devpriv->da_ranges |= (range << (chan << 1)); - outw(devpriv->da_ranges, dev->iobase + PCI171X_DAREF_REG); - - for (i = 0; i < insn->n; i++) { - val = data[i]; - outw(val, dev->iobase + PCI171X_DA_REG(chan)); - } - - s->readback[chan] = val; - - return insn->n; -} - static int pci171x_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -645,6 +620,31 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, return 0; } +static int pci1710_ao_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct pci1710_private *devpriv = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int range = CR_RANGE(insn->chanspec); + unsigned int val = s->readback[chan]; + int i; + + devpriv->da_ranges &= ~(1 << (chan << 1)); + devpriv->da_ranges |= (range << (chan << 1)); + outw(devpriv->da_ranges, dev->iobase + PCI171X_DAREF_REG); + + for (i = 0; i < insn->n; i++) { + val = data[i]; + outw(val, dev->iobase + PCI171X_DA_REG(chan)); + } + + s->readback[chan] = val; + + return insn->n; +} + static int pci1710_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -823,7 +823,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, s->n_chan = 2; s->maxdata = 0x0fff; s->range_table = &pci171x_ao_range; - s->insn_write = pci171x_ao_insn_write; + s->insn_write = pci1710_ao_insn_write; ret = comedi_alloc_subdev_readback(s); if (ret) -- GitLab From 976e893b61e628ff72adbf70ad84674650c8f053 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:17 -0700 Subject: [PATCH 1698/2855] staging: comedi: adv_pci1710: support external analog output reference The analog outputs can use an external reference to create the D/A output range. Add an entry to the comedi_lrange table for it and modify the (*insn_write) to support it. Note that the D/A output range is 0 to +Vref with a -Vref. The comedi_lrange does not include the sign of the range. It simmply allows the user to convert between the 12-bit samples values (0x0000 - 0x0fff) and a physical value (0.0 to 1.0) using the comedilib comedi_to_phys() and comedi_from_phys() functions. A physical value of 0.0 would actually be 0V with a -Vref and -V with a +Vref and 1.0 would be +V with a -Vref and 0V with a -Vref. Ths user will need to work this out but at least they can now use the external reference. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index cc451f131857b..aafcb8adb1dbb 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -65,6 +65,8 @@ #define PCI171X_CLRFIFO_REG 0x09 /* W: clear FIFO */ #define PCI171X_DA_REG(x) (0x0a + ((x) * 2)) /* W: D/A register */ #define PCI171X_DAREF_REG 0x0e /* W: D/A reference control */ +#define PCI171X_DAREF(c, r) (((r) & 0x3) << ((c) * 2)) +#define PCI171X_DAREF_MASK(c) PCI171X_DAREF((c), 0x3) #define PCI171X_DI_REG 0x10 /* R: digital inputs */ #define PCI171X_DO_REG 0x10 /* W: digital outputs */ #define PCI171X_TIMER_BASE 0x18 /* R/W: 8254 timer */ @@ -111,9 +113,10 @@ static const struct comedi_lrange pci1711_ai_range = { }; static const struct comedi_lrange pci171x_ao_range = { - 2, { - UNI_RANGE(5), - UNI_RANGE(10) + 3, { + UNI_RANGE(5), /* internal -5V ref */ + UNI_RANGE(10), /* internal -10V ref */ + RANGE_ext(0, 1) /* external -Vref (+/-10V max) */ } }; @@ -631,8 +634,8 @@ static int pci1710_ao_insn_write(struct comedi_device *dev, unsigned int val = s->readback[chan]; int i; - devpriv->da_ranges &= ~(1 << (chan << 1)); - devpriv->da_ranges |= (range << (chan << 1)); + devpriv->da_ranges &= ~PCI171X_DAREF_MASK(chan); + devpriv->da_ranges |= PCI171X_DAREF(chan, range); outw(devpriv->da_ranges, dev->iobase + PCI171X_DAREF_REG); for (i = 0; i < insn->n; i++) { -- GitLab From 1ef6e0a48e3b624beb6f6206db2875ca3367459e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:18 -0700 Subject: [PATCH 1699/2855] staging: comedi: adv_pci1710: tidy up analog output subdev_flags Remove the SDF_COMMON flag, the analog reference is not programmable and the default aref (AREF_GROUND -> SDF_GROUND) provides adequate information about the reference. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index aafcb8adb1dbb..91ab68b92086c 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -820,9 +820,10 @@ static int pci1710_auto_attach(struct comedi_device *dev, subdev++; if (board->has_ao) { + /* Analog Output subdevice */ s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND; s->n_chan = 2; s->maxdata = 0x0fff; s->range_table = &pci171x_ao_range; -- GitLab From 7387332558f050ace07334e945d2077af3c2ed96 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:19 -0700 Subject: [PATCH 1700/2855] staging: comedi: adv_pci1710: tidy up analog input subdev_flags Remove the SDF_COMMON flag, the analog reference is not programmable and the default aref (AREF_GROUND -> SDF_GROUND) provides adequate information about the reference. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 91ab68b92086c..f68cb1a6836ec 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -793,7 +793,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, /* Analog Input subdevice */ s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND; + s->subdev_flags = SDF_READABLE | SDF_GROUND; if (!board->is_pci1711) s->subdev_flags |= SDF_DIFF; s->n_chan = board->is_pci1713 ? 32 : 16; -- GitLab From d3e8ab48db7fdb7b4898d3685f49720a46925902 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:20 -0700 Subject: [PATCH 1701/2855] staging: comedi: adv_pci1710: post increment 'subdev' in (*auto_attach) For aesthetics, post-increment the 'subdev' index when used to get a comedi_subdevice pointer instead of incrementing it after the subdevice is initialized. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index f68cb1a6836ec..e36b54045eb4b 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -791,7 +791,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, subdev = 0; /* Analog Input subdevice */ - s = &dev->subdevices[subdev]; + s = &dev->subdevices[subdev++]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND; if (!board->is_pci1711) @@ -817,11 +817,9 @@ static int pci1710_auto_attach(struct comedi_device *dev, } } - subdev++; - if (board->has_ao) { /* Analog Output subdevice */ - s = &dev->subdevices[subdev]; + s = &dev->subdevices[subdev++]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND; s->n_chan = 2; @@ -832,33 +830,29 @@ static int pci1710_auto_attach(struct comedi_device *dev, ret = comedi_alloc_subdev_readback(s); if (ret) return ret; - - subdev++; } if (!board->is_pci1713) { /* Digital Input subdevice */ - s = &dev->subdevices[subdev]; + s = &dev->subdevices[subdev++]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = pci1710_di_insn_bits; - subdev++; /* Digital Output subdevice */ - s = &dev->subdevices[subdev]; + s = &dev->subdevices[subdev++]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = pci1710_do_insn_bits; - subdev++; /* Counter subdevice (8254) */ - s = &dev->subdevices[subdev]; + s = &dev->subdevices[subdev++]; comedi_8254_subdevice_init(s, dev->pacer); dev->pacer->insn_config = pci1710_counter_insn_config; @@ -866,8 +860,6 @@ static int pci1710_auto_attach(struct comedi_device *dev, /* counters 1 and 2 are used internally for the pacer */ comedi_8254_set_busy(dev->pacer, 1, true); comedi_8254_set_busy(dev->pacer, 2, true); - - subdev++; } /* max_samples is half the FIFO size (2 bytes/sample) */ -- GitLab From adbc9ec7fe38baa8af2a3d21e3f505c8a8da7c3b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:21 -0700 Subject: [PATCH 1702/2855] staging: comedi: adv_pci1710: ai (*cancel) should not enable software trigger The (*cancel) operation should do just that. Remove the setting of the SW bit which enables the software trigger. For aesthetics, rename the function so it has namespace associated with the driver and add a couple comments. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index e36b54045eb4b..737d40867d3b6 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -365,16 +365,19 @@ static int pci171x_ai_insn_read(struct comedi_device *dev, return ret ? ret : insn->n; } -static int pci171x_ai_cancel(struct comedi_device *dev, +static int pci1710_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { struct pci1710_private *devpriv = dev->private; - devpriv->ctrl &= PCI171X_CTRL_CNT0; - devpriv->ctrl |= PCI171X_CTRL_SW; - /* reset any operations */ + /* disable A/D triggers and interrupt sources */ + devpriv->ctrl &= PCI171X_CTRL_CNT0; /* preserve counter 0 clk src */ outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG); + + /* disable pacer */ comedi_8254_pacer_enable(dev->pacer, 1, 2, false); + + /* clear A/D FIFO and any pending interrutps */ outb(0, dev->iobase + PCI171X_CLRFIFO_REG); outb(0, dev->iobase + PCI171X_CLRINT_REG); @@ -806,7 +809,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, s->len_chanlist = s->n_chan; s->do_cmdtest = pci171x_ai_cmdtest; s->do_cmd = pci171x_ai_cmd; - s->cancel = pci171x_ai_cancel; + s->cancel = pci1710_ai_cancel; } /* find the value needed to adjust for unipolar gain codes */ -- GitLab From 0c917a93654557dc2489ebacbeadc3851186e3ce Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:22 -0700 Subject: [PATCH 1703/2855] staging: comedi: adv_pci1710: tidy up pci1710_reset() Change the return type to void, this function always succeeds and the caller does not check the return value anyway. Fix the initial programming of the control register. The SW bit enables the software trigger and should not be set here. Setting CNT0 selects the external clock source for counter 0 (the user counter). It makes more sense to select the internal 1 MHz clock. Remove the unnecessary initialization of the private data members. This function is only called during the (*auto_attach) after the private data was kzalloc'ed. Remove the redundant clearing of the A/D FIFO and pending interrupts. Just do it once. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 737d40867d3b6..8bd9edfca2f2c 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -711,29 +711,29 @@ static int pci1710_counter_insn_config(struct comedi_device *dev, return insn->n; } -static int pci1710_reset(struct comedi_device *dev) +static void pci1710_reset(struct comedi_device *dev) { const struct boardtype *board = dev->board_ptr; - struct pci1710_private *devpriv = dev->private; - /* Software trigger, CNT0=external */ - devpriv->ctrl = PCI171X_CTRL_SW | PCI171X_CTRL_CNT0; - /* reset any operations */ - outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG); + /* + * Disable A/D triggers and interrupt sources, set counter 0 + * to use internal 1 MHz clock. + */ + outw(0, dev->iobase + PCI171X_CTRL_REG); + + /* clear A/D FIFO and any pending interrutps */ outb(0, dev->iobase + PCI171X_CLRFIFO_REG); outb(0, dev->iobase + PCI171X_CLRINT_REG); - devpriv->da_ranges = 0; + if (board->has_ao) { /* set DACs to 0..5V and outputs to 0V */ - outb(devpriv->da_ranges, dev->iobase + PCI171X_DAREF_REG); + outb(0, dev->iobase + PCI171X_DAREF_REG); outw(0, dev->iobase + PCI171X_DA_REG(0)); outw(0, dev->iobase + PCI171X_DA_REG(1)); } - outw(0, dev->iobase + PCI171X_DO_REG); /* digital outputs to 0 */ - outb(0, dev->iobase + PCI171X_CLRFIFO_REG); - outb(0, dev->iobase + PCI171X_CLRINT_REG); - return 0; + /* set digital outputs to 0 */ + outw(0, dev->iobase + PCI171X_DO_REG); } static int pci1710_auto_attach(struct comedi_device *dev, -- GitLab From d0445303f86c6ace7dcaf6d2806445ea0208f151 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:23 -0700 Subject: [PATCH 1704/2855] staging: comedi: adv_pci1710: fix counter 0 internal clock source There are a number of descrepencies in the various manuals for the boards that this driver supports. Some show a 10 MHz clock for counters 1 and 2 others show a 1 MHz clock. Counter 0 can use either a div 10 of that clock or an external clock (up to 10 MHz). Currently this driver initializes counters 1 and 2 with a 10 MHz clock. For consistency, return 1 MHz (10 MHz/10) for counter 0 when the user queries the internal clock source with INSN_CONFIG_GET_CLOCK_SRC. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 8bd9edfca2f2c..5f1e86e767c80 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -701,7 +701,7 @@ static int pci1710_counter_insn_config(struct comedi_device *dev, data[2] = 0; } else { data[1] = 0; - data[2] = I8254_OSC_BASE_10MHZ; + data[2] = I8254_OSC_BASE_1MHZ; } break; default: -- GitLab From 5ce4385232255683f3fccca4d6772ae61769f2ad Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:24 -0700 Subject: [PATCH 1705/2855] staging: comedi: adv_pci1710: fix ai (*insn_read) An (*insn_read) can only happen if the subdevice is in a non-busy state, i.e. an async command is not running. The board reset and subdevice (*cancel) will ensure that the control bits (devpriv->ctrl) are already cleared. The (*insn_read) only needs to enable the software trigger before reading samples. It should also disable the software trigger when done. Fix the (*insn_read) to do this. For aesthetics, rename the function so it has namespace associated with the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 5f1e86e767c80..93b3e3fedbb6d 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -325,7 +325,7 @@ static int pci171x_ai_read_sample(struct comedi_device *dev, return 0; } -static int pci171x_ai_insn_read(struct comedi_device *dev, +static int pci1710_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -334,9 +334,10 @@ static int pci171x_ai_insn_read(struct comedi_device *dev, int ret = 0; int i; - devpriv->ctrl &= PCI171X_CTRL_CNT0; - devpriv->ctrl |= PCI171X_CTRL_SW; /* set software trigger */ + /* enable software trigger */ + devpriv->ctrl |= PCI171X_CTRL_SW; outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG); + outb(0, dev->iobase + PCI171X_CLRFIFO_REG); outb(0, dev->iobase + PCI171X_CLRINT_REG); @@ -359,6 +360,10 @@ static int pci171x_ai_insn_read(struct comedi_device *dev, data[i] = val; } + /* disable software trigger */ + devpriv->ctrl &= ~PCI171X_CTRL_SW; + outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG); + outb(0, dev->iobase + PCI171X_CLRFIFO_REG); outb(0, dev->iobase + PCI171X_CLRINT_REG); @@ -802,7 +807,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, s->n_chan = board->is_pci1713 ? 32 : 16; s->maxdata = 0x0fff; s->range_table = board->ai_range; - s->insn_read = pci171x_ai_insn_read; + s->insn_read = pci1710_ai_insn_read; if (dev->irq) { dev->read_subdev = s; s->subdev_flags |= SDF_CMD_READ; -- GitLab From 6f05ce9cce0c946ab4d5e21bdeb1eafcab0fc156 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:25 -0700 Subject: [PATCH 1706/2855] staging: comedi: adv_pci1710: rename pci171x_ai_{cmd,cmdtest}() Rename these functions so they have namespace associated with the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 93b3e3fedbb6d..b9edf27902228 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -518,7 +518,7 @@ static irqreturn_t pci1710_irq_handler(int irq, void *d) return IRQ_HANDLED; } -static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) +static int pci1710_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { struct pci1710_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; @@ -559,7 +559,7 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } -static int pci171x_ai_cmdtest(struct comedi_device *dev, +static int pci1710_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { @@ -812,8 +812,8 @@ static int pci1710_auto_attach(struct comedi_device *dev, dev->read_subdev = s; s->subdev_flags |= SDF_CMD_READ; s->len_chanlist = s->n_chan; - s->do_cmdtest = pci171x_ai_cmdtest; - s->do_cmd = pci171x_ai_cmd; + s->do_cmdtest = pci1710_ai_cmdtest; + s->do_cmd = pci1710_ai_cmd; s->cancel = pci1710_ai_cancel; } -- GitLab From e209f7cc205f51b089f9067f4d03922fa5f28490 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 13 Nov 2015 11:11:26 -0700 Subject: [PATCH 1707/2855] staging: comedi: adv_pci1710: rename pci171x_ai_*() Rename these functions so they have namespace associated with the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index b9edf27902228..2c1b6de30da8c 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -177,7 +177,7 @@ struct pci1710_private { unsigned char unipolar_gain; /* adjust for unipolar gain codes */ }; -static int pci171x_ai_check_chanlist(struct comedi_device *dev, +static int pci1710_ai_check_chanlist(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { @@ -243,7 +243,7 @@ static int pci171x_ai_check_chanlist(struct comedi_device *dev, return 0; } -static void pci171x_ai_setup_chanlist(struct comedi_device *dev, +static void pci1710_ai_setup_chanlist(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int *chanlist, unsigned int n_chan, @@ -283,7 +283,7 @@ static void pci171x_ai_setup_chanlist(struct comedi_device *dev, outw(devpriv->mux_scan, dev->iobase + PCI171X_MUX_REG); } -static int pci171x_ai_eoc(struct comedi_device *dev, +static int pci1710_ai_eoc(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned long context) @@ -296,7 +296,7 @@ static int pci171x_ai_eoc(struct comedi_device *dev, return -EBUSY; } -static int pci171x_ai_read_sample(struct comedi_device *dev, +static int pci1710_ai_read_sample(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int cur_chan, unsigned int *val) @@ -341,7 +341,7 @@ static int pci1710_ai_insn_read(struct comedi_device *dev, outb(0, dev->iobase + PCI171X_CLRFIFO_REG); outb(0, dev->iobase + PCI171X_CLRINT_REG); - pci171x_ai_setup_chanlist(dev, s, &insn->chanspec, 1, 1); + pci1710_ai_setup_chanlist(dev, s, &insn->chanspec, 1, 1); for (i = 0; i < insn->n; i++) { unsigned int val; @@ -349,11 +349,11 @@ static int pci1710_ai_insn_read(struct comedi_device *dev, /* start conversion */ outw(0, dev->iobase + PCI171X_SOFTTRG_REG); - ret = comedi_timeout(dev, s, insn, pci171x_ai_eoc, 0); + ret = comedi_timeout(dev, s, insn, pci1710_ai_eoc, 0); if (ret) break; - ret = pci171x_ai_read_sample(dev, s, 0, &val); + ret = pci1710_ai_read_sample(dev, s, 0, &val); if (ret) break; @@ -413,7 +413,7 @@ static void pci1710_handle_every_sample(struct comedi_device *dev, outb(0, dev->iobase + PCI171X_CLRINT_REG); for (; !(inw(dev->iobase + PCI171X_STATUS_REG) & PCI171X_STATUS_FE);) { - ret = pci171x_ai_read_sample(dev, s, s->async->cur_chan, &val); + ret = pci1710_ai_read_sample(dev, s, s->async->cur_chan, &val); if (ret) { s->async->events |= COMEDI_CB_ERROR; break; @@ -457,7 +457,7 @@ static void pci1710_handle_fifo(struct comedi_device *dev, unsigned int val; int ret; - ret = pci171x_ai_read_sample(dev, s, s->async->cur_chan, &val); + ret = pci1710_ai_read_sample(dev, s, s->async->cur_chan, &val); if (ret) { s->async->events |= COMEDI_CB_ERROR; break; @@ -523,7 +523,7 @@ static int pci1710_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) struct pci1710_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - pci171x_ai_setup_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len, + pci1710_ai_setup_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len, devpriv->saved_seglen); outb(0, dev->iobase + PCI171X_CLRFIFO_REG); @@ -623,7 +623,7 @@ static int pci1710_ai_cmdtest(struct comedi_device *dev, /* Step 5: check channel list */ - err |= pci171x_ai_check_chanlist(dev, s, cmd); + err |= pci1710_ai_check_chanlist(dev, s, cmd); if (err) return 5; -- GitLab From 80e1ca692107b0bc5b088fd9c4a20726fb1a66a2 Mon Sep 17 00:00:00 2001 From: Bayi Cheng Date: Fri, 18 Dec 2015 11:02:40 +0800 Subject: [PATCH 1708/2855] mtd: mtk-nor: adjust sequence of trigger function and assignment function Move write data register before excute command to avoid missing first byte write to nor flash Signed-off-by: Bayi Cheng Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/mtk-quadspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/mtk-quadspi.c b/drivers/mtd/spi-nor/mtk-quadspi.c index e1dd9fd16fbe0..d5f850d035bb9 100644 --- a/drivers/mtd/spi-nor/mtk-quadspi.c +++ b/drivers/mtd/spi-nor/mtk-quadspi.c @@ -272,10 +272,10 @@ static int mt8173_nor_write_single_byte(struct mt8173_nor *mt8173_nor, mt8173_nor_set_addr(mt8173_nor, addr); for (i = 0; i < length; i++) { + writeb(*data++, mt8173_nor->base + MTK_NOR_WDATA_REG); ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PIO_WR_CMD); if (ret < 0) return ret; - writeb(*data++, mt8173_nor->base + MTK_NOR_WDATA_REG); } return 0; } -- GitLab From fdd9d27c8a47ea81daeaddfe6c0156ae7cf68096 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Wed, 10 Jun 2015 18:31:32 +0200 Subject: [PATCH 1709/2855] mtd: cfi_cmdset_0002: use swap() in cfi_cmdset_0002() Use kernel.h macro definition. Thanks to Julia Lawall for Coccinelle scripting support. Signed-off-by: Fabian Frederick Signed-off-by: Brian Norris --- drivers/mtd/chips/cfi_cmdset_0002.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index c3624eb571d16..9dca881bb3780 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -615,11 +615,9 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) for (i=0; icfiq->NumEraseRegions / 2; i++) { int j = (cfi->cfiq->NumEraseRegions-1)-i; - __u32 swap; - swap = cfi->cfiq->EraseRegionInfo[i]; - cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j]; - cfi->cfiq->EraseRegionInfo[j] = swap; + swap(cfi->cfiq->EraseRegionInfo[i], + cfi->cfiq->EraseRegionInfo[j]); } } /* Set the default CFI lock/unlock addresses */ -- GitLab From 6166a76f5ef7619faa28b38d7817e5fe0e509942 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Wed, 10 Jun 2015 18:31:06 +0200 Subject: [PATCH 1710/2855] mtd: ftl: use swap() in copy_erase_unit() Use kernel.h macro definition. Thanks to Julia Lawall for Coccinelle scripting support. Signed-off-by: Fabian Frederick Signed-off-by: Brian Norris --- drivers/mtd/ftl.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c index dabf08450d0b3..9fb3b0dcdac20 100644 --- a/drivers/mtd/ftl.c +++ b/drivers/mtd/ftl.c @@ -571,12 +571,8 @@ static int copy_erase_unit(partition_t *part, uint16_t srcunit, /* Update the maps and usage stats*/ - i = xfer->EraseCount; - xfer->EraseCount = eun->EraseCount; - eun->EraseCount = i; - i = xfer->Offset; - xfer->Offset = eun->Offset; - eun->Offset = i; + swap(xfer->EraseCount, eun->EraseCount); + swap(xfer->Offset, eun->Offset); part->FreeTotal -= eun->Free; part->FreeTotal += free; eun->Free = free; -- GitLab From 052876f8e5aec887d22c4d06e54aa5531ffcec75 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Fri, 18 Dec 2015 17:20:09 -0800 Subject: [PATCH 1711/2855] Input: uinput - add new UINPUT_DEV_SETUP and UI_ABS_SETUP ioctl This adds two new ioctls, UINPUT_DEV_SETUP and UI_ABS_SETUP, that replaces the old device setup method (by write()'ing "struct uinput_user_dev" to the node). The old method is not easily extendable and requires huge payloads. Furthermore, overloading write() without properly versioned objects is error-prone. Therefore, we introduce two new ioctls to replace the old method. These ioctls support all features of the old method, plus a "resolution" field for absinfo. Furthermore, it's properly forward-compatible to new ABS codes and a growing "struct input_absinfo" structure. UI_ABS_SETUP also allows user-space to skip unknown axes if not set. There is no need to copy the whole array temporarily into the kernel, but instead the caller issues several ioctl where we copy each value manually. Signed-off-by: David Herrmann Signed-off-by: Benjamin Tissoires Reviewed-by: David Herrmann Signed-off-by: Dmitry Torokhov --- drivers/input/misc/uinput.c | 86 +++++++++++++++++++++++++++++++++++-- include/linux/uinput.h | 5 +++ include/uapi/linux/uinput.h | 83 +++++++++++++++++++++++++++++++++-- 3 files changed, 168 insertions(+), 6 deletions(-) diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 5adbcedcb81cf..a16fc4a4bb1f1 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -370,8 +370,78 @@ static int uinput_allocate_device(struct uinput_device *udev) return 0; } -static int uinput_setup_device(struct uinput_device *udev, - const char __user *buffer, size_t count) +static int uinput_dev_setup(struct uinput_device *udev, + struct uinput_setup __user *arg) +{ + struct uinput_setup setup; + struct input_dev *dev; + int retval; + + if (udev->state == UIST_CREATED) + return -EINVAL; + + if (copy_from_user(&setup, arg, sizeof(setup))) + return -EFAULT; + + if (!setup.name[0]) + return -EINVAL; + + dev = udev->dev; + dev->id = setup.id; + udev->ff_effects_max = setup.ff_effects_max; + + kfree(dev->name); + dev->name = kstrndup(setup.name, UINPUT_MAX_NAME_SIZE, GFP_KERNEL); + if (!dev->name) + return -ENOMEM; + + retval = uinput_validate_absbits(dev); + if (retval < 0) + return retval; + + udev->state = UIST_SETUP_COMPLETE; + return 0; +} + +static int uinput_abs_setup(struct uinput_device *udev, + struct uinput_setup __user *arg, size_t size) +{ + struct uinput_abs_setup setup = {}; + struct input_dev *dev; + + if (size > sizeof(setup)) + return -E2BIG; + + if (udev->state == UIST_CREATED) + return -EINVAL; + + if (copy_from_user(&setup, arg, size)) + return -EFAULT; + + if (setup.code > ABS_MAX) + return -ERANGE; + + dev = udev->dev; + + input_alloc_absinfo(dev); + if (!dev->absinfo) + return -ENOMEM; + + set_bit(setup.code, dev->absbit); + dev->absinfo[setup.code] = setup.absinfo; + + /* + * We restore the state to UIST_NEW_DEVICE because the user has to call + * UI_DEV_SETUP in the last place before UI_DEV_CREATE to check the + * validity of the absbits. + */ + udev->state = UIST_NEW_DEVICE; + return 0; +} + +/* legacy setup via write() */ +static int uinput_setup_device_legacy(struct uinput_device *udev, + const char __user *buffer, size_t count) { struct uinput_user_dev *user_dev; struct input_dev *dev; @@ -474,7 +544,7 @@ static ssize_t uinput_write(struct file *file, const char __user *buffer, retval = udev->state == UIST_CREATED ? uinput_inject_events(udev, buffer, count) : - uinput_setup_device(udev, buffer, count); + uinput_setup_device_legacy(udev, buffer, count); mutex_unlock(&udev->mutex); @@ -735,6 +805,12 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd, uinput_destroy_device(udev); goto out; + case UI_DEV_SETUP: + retval = uinput_dev_setup(udev, p); + goto out; + + /* UI_ABS_SETUP is handled in the variable size ioctls */ + case UI_SET_EVBIT: retval = uinput_set_bit(arg, evbit, EV_MAX); goto out; @@ -879,6 +955,10 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd, name = dev_name(&udev->dev->dev); retval = uinput_str_to_user(p, name, size); goto out; + + case UI_ABS_SETUP & ~IOCSIZE_MASK: + retval = uinput_abs_setup(udev, p, size); + goto out; } retval = -EINVAL; diff --git a/include/linux/uinput.h b/include/linux/uinput.h index 0994c0d01a092..75de43da23015 100644 --- a/include/linux/uinput.h +++ b/include/linux/uinput.h @@ -20,6 +20,11 @@ * Author: Aristeu Sergio Rozanski Filho * * Changes/Revisions: + * 0.5 08/13/2015 (David Herrmann & + * Benjamin Tissoires ) + * - add UI_DEV_SETUP ioctl + * - add UI_ABS_SETUP ioctl + * - add UI_GET_VERSION ioctl * 0.4 01/09/2014 (Benjamin Tissoires ) * - add UI_GET_SYSNAME ioctl * 0.3 24/05/2006 (Anssi Hannula ) diff --git a/include/uapi/linux/uinput.h b/include/uapi/linux/uinput.h index 013c9d8db3720..77b8cf73a178d 100644 --- a/include/uapi/linux/uinput.h +++ b/include/uapi/linux/uinput.h @@ -20,6 +20,11 @@ * Author: Aristeu Sergio Rozanski Filho * * Changes/Revisions: + * 0.5 08/13/2015 (David Herrmann & + * Benjamin Tissoires ) + * - add UI_DEV_SETUP ioctl + * - add UI_ABS_SETUP ioctl + * - add UI_GET_VERSION ioctl * 0.4 01/09/2014 (Benjamin Tissoires ) * - add UI_GET_SYSNAME ioctl * 0.3 24/05/2006 (Anssi Hannula ) @@ -37,8 +42,8 @@ #include #include -#define UINPUT_VERSION 4 - +#define UINPUT_VERSION 5 +#define UINPUT_MAX_NAME_SIZE 80 struct uinput_ff_upload { __u32 request_id; @@ -58,6 +63,79 @@ struct uinput_ff_erase { #define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1) #define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2) +struct uinput_setup { + struct input_id id; + char name[UINPUT_MAX_NAME_SIZE]; + __u32 ff_effects_max; +}; + +/** + * UI_DEV_SETUP - Set device parameters for setup + * + * This ioctl sets parameters for the input device to be created. It must be + * issued *before* calling UI_DEV_CREATE or it will fail. This ioctl supersedes + * the old "struct uinput_user_dev" method, which wrote this data via write(). + * To actually set the absolute axes, you also need to call the ioctl + * UI_ABS_SETUP *before* calling this ioctl. + * + * This ioctl takes a "struct uinput_setup" object as argument. The fields of + * this object are as follows: + * id: See the description of "struct input_id". This field is + * copied unchanged into the new device. + * name: This is used unchanged as name for the new device. + * ff_effects_max: This limits the maximum numbers of force-feedback effects. + * See below for a description of FF with uinput. + * + * This ioctl can be called multiple times and will overwrite previous values. + * If this ioctl fails with -EINVAL, you're recommended to use the old + * "uinput_user_dev" method via write() as fallback, in case you run on an old + * kernel that does not support this ioctl. + * + * This ioctl may fail with -EINVAL if it is not supported or if you passed + * incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the + * passed uinput_setup object cannot be read/written. + * If this call fails, partial data may have already been applied to the + * internal device. + */ +#define UI_DEV_SETUP _IOW(UINPUT_IOCTL_BASE, 3, struct uinput_setup) + +struct uinput_abs_setup { + __u16 code; /* axis code */ + /* __u16 filler; */ + struct input_absinfo absinfo; +}; + +/** + * UI_ABS_SETUP - Set absolute axis information for the device to setup + * + * This ioctl sets one absolute axis information for the input device to be + * created. It must be issued *before* calling UI_DEV_SETUP and UI_DEV_CREATE + * for every absolute axis the device exports. + * This ioctl supersedes the old "struct uinput_user_dev" method, which wrote + * part of this data and the content of UI_DEV_SETUP via write(). + * + * This ioctl takes a "struct uinput_abs_setup" object as argument. The fields + * of this object are as follows: + * code: The corresponding input code associated with this axis + * (ABS_X, ABS_Y, etc...) + * absinfo: See "struct input_absinfo" for a description of this field. + * This field is copied unchanged into the kernel for the + * specified axis. If the axis is not enabled via + * UI_SET_ABSBIT, this ioctl will enable it. + * + * This ioctl can be called multiple times and will overwrite previous values. + * If this ioctl fails with -EINVAL, you're recommended to use the old + * "uinput_user_dev" method via write() as fallback, in case you run on an old + * kernel that does not support this ioctl. + * + * This ioctl may fail with -EINVAL if it is not supported or if you passed + * incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the + * passed uinput_setup object cannot be read/written. + * If this call fails, partial data may have already been applied to the + * internal device. + */ +#define UI_ABS_SETUP _IOW(UINPUT_IOCTL_BASE, 4, struct uinput_abs_setup) + #define UI_SET_EVBIT _IOW(UINPUT_IOCTL_BASE, 100, int) #define UI_SET_KEYBIT _IOW(UINPUT_IOCTL_BASE, 101, int) #define UI_SET_RELBIT _IOW(UINPUT_IOCTL_BASE, 102, int) @@ -144,7 +222,6 @@ struct uinput_ff_erase { #define UI_FF_UPLOAD 1 #define UI_FF_ERASE 2 -#define UINPUT_MAX_NAME_SIZE 80 struct uinput_user_dev { char name[UINPUT_MAX_NAME_SIZE]; struct input_id id; -- GitLab From fbae10db094046dba1d59e1c2ee5140835045f14 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 25 Oct 2015 10:34:13 +0100 Subject: [PATCH 1712/2855] Input: uinput - rework ABS validation Rework the uinput ABS validation to check passed absinfo data immediately, but do ABS initialization as last step in UI_DEV_CREATE. The behavior observed by user-space is not changed, as ABS initialization was never checked for errors. With this in place, the order of device initialization and abs configuration is no longer fixed. Userspace can initialize the device and afterwards set absinfo just fine. Signed-off-by: David Herrmann Reviewed-by: Benjamin Tissoires Tested-by: Benjamin Tissoires Signed-off-by: Dmitry Torokhov --- drivers/input/misc/uinput.c | 89 +++++++++++++++++++------------------ include/uapi/linux/uinput.h | 29 ++++++------ 2 files changed, 58 insertions(+), 60 deletions(-) diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index a16fc4a4bb1f1..782df415e4d5c 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -256,13 +256,22 @@ static void uinput_destroy_device(struct uinput_device *udev) static int uinput_create_device(struct uinput_device *udev) { struct input_dev *dev = udev->dev; - int error; + int error, nslot; if (udev->state != UIST_SETUP_COMPLETE) { printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME); return -EINVAL; } + if (test_bit(ABS_MT_SLOT, dev->absbit)) { + nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; + error = input_mt_init_slots(dev, nslot, 0); + if (error) + goto fail1; + } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { + input_set_events_per_packet(dev, 60); + } + if (udev->ff_effects_max) { error = input_ff_create(dev, udev->ff_effects_max); if (error) @@ -308,10 +317,35 @@ static int uinput_open(struct inode *inode, struct file *file) return 0; } +static int uinput_validate_absinfo(struct input_dev *dev, unsigned int code, + const struct input_absinfo *abs) +{ + int min, max; + + min = abs->minimum; + max = abs->maximum; + + if ((min != 0 || max != 0) && max <= min) { + printk(KERN_DEBUG + "%s: invalid abs[%02x] min:%d max:%d\n", + UINPUT_NAME, code, min, max); + return -EINVAL; + } + + if (abs->flat > max - min) { + printk(KERN_DEBUG + "%s: abs_flat #%02x out of range: %d (min:%d/max:%d)\n", + UINPUT_NAME, code, abs->flat, min, max); + return -EINVAL; + } + + return 0; +} + static int uinput_validate_absbits(struct input_dev *dev) { unsigned int cnt; - int nslot; + int error; if (!test_bit(EV_ABS, dev->evbit)) return 0; @@ -321,38 +355,12 @@ static int uinput_validate_absbits(struct input_dev *dev) */ for_each_set_bit(cnt, dev->absbit, ABS_CNT) { - int min, max; - - min = input_abs_get_min(dev, cnt); - max = input_abs_get_max(dev, cnt); - - if ((min != 0 || max != 0) && max <= min) { - printk(KERN_DEBUG - "%s: invalid abs[%02x] min:%d max:%d\n", - UINPUT_NAME, cnt, - input_abs_get_min(dev, cnt), - input_abs_get_max(dev, cnt)); + if (!dev->absinfo) return -EINVAL; - } - - if (input_abs_get_flat(dev, cnt) > - input_abs_get_max(dev, cnt) - input_abs_get_min(dev, cnt)) { - printk(KERN_DEBUG - "%s: abs_flat #%02x out of range: %d " - "(min:%d/max:%d)\n", - UINPUT_NAME, cnt, - input_abs_get_flat(dev, cnt), - input_abs_get_min(dev, cnt), - input_abs_get_max(dev, cnt)); - return -EINVAL; - } - } - if (test_bit(ABS_MT_SLOT, dev->absbit)) { - nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; - input_mt_init_slots(dev, nslot, 0); - } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { - input_set_events_per_packet(dev, 60); + error = uinput_validate_absinfo(dev, cnt, &dev->absinfo[cnt]); + if (error) + return error; } return 0; @@ -375,7 +383,6 @@ static int uinput_dev_setup(struct uinput_device *udev, { struct uinput_setup setup; struct input_dev *dev; - int retval; if (udev->state == UIST_CREATED) return -EINVAL; @@ -395,10 +402,6 @@ static int uinput_dev_setup(struct uinput_device *udev, if (!dev->name) return -ENOMEM; - retval = uinput_validate_absbits(dev); - if (retval < 0) - return retval; - udev->state = UIST_SETUP_COMPLETE; return 0; } @@ -408,6 +411,7 @@ static int uinput_abs_setup(struct uinput_device *udev, { struct uinput_abs_setup setup = {}; struct input_dev *dev; + int error; if (size > sizeof(setup)) return -E2BIG; @@ -423,19 +427,16 @@ static int uinput_abs_setup(struct uinput_device *udev, dev = udev->dev; + error = uinput_validate_absinfo(dev, setup.code, &setup.absinfo); + if (error) + return error; + input_alloc_absinfo(dev); if (!dev->absinfo) return -ENOMEM; set_bit(setup.code, dev->absbit); dev->absinfo[setup.code] = setup.absinfo; - - /* - * We restore the state to UIST_NEW_DEVICE because the user has to call - * UI_DEV_SETUP in the last place before UI_DEV_CREATE to check the - * validity of the absbits. - */ - udev->state = UIST_NEW_DEVICE; return 0; } diff --git a/include/uapi/linux/uinput.h b/include/uapi/linux/uinput.h index 77b8cf73a178d..dc652e224b67c 100644 --- a/include/uapi/linux/uinput.h +++ b/include/uapi/linux/uinput.h @@ -72,13 +72,12 @@ struct uinput_setup { /** * UI_DEV_SETUP - Set device parameters for setup * - * This ioctl sets parameters for the input device to be created. It must be - * issued *before* calling UI_DEV_CREATE or it will fail. This ioctl supersedes - * the old "struct uinput_user_dev" method, which wrote this data via write(). - * To actually set the absolute axes, you also need to call the ioctl - * UI_ABS_SETUP *before* calling this ioctl. + * This ioctl sets parameters for the input device to be created. It + * supersedes the old "struct uinput_user_dev" method, which wrote this data + * via write(). To actually set the absolute axes UI_ABS_SETUP should be + * used. * - * This ioctl takes a "struct uinput_setup" object as argument. The fields of + * The ioctl takes a "struct uinput_setup" object as argument. The fields of * this object are as follows: * id: See the description of "struct input_id". This field is * copied unchanged into the new device. @@ -87,9 +86,9 @@ struct uinput_setup { * See below for a description of FF with uinput. * * This ioctl can be called multiple times and will overwrite previous values. - * If this ioctl fails with -EINVAL, you're recommended to use the old - * "uinput_user_dev" method via write() as fallback, in case you run on an old - * kernel that does not support this ioctl. + * If this ioctl fails with -EINVAL, it is recommended to use the old + * "uinput_user_dev" method via write() as a fallback, in case you run on an + * old kernel that does not support this ioctl. * * This ioctl may fail with -EINVAL if it is not supported or if you passed * incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the @@ -109,12 +108,10 @@ struct uinput_abs_setup { * UI_ABS_SETUP - Set absolute axis information for the device to setup * * This ioctl sets one absolute axis information for the input device to be - * created. It must be issued *before* calling UI_DEV_SETUP and UI_DEV_CREATE - * for every absolute axis the device exports. - * This ioctl supersedes the old "struct uinput_user_dev" method, which wrote + * created. It supersedes the old "struct uinput_user_dev" method, which wrote * part of this data and the content of UI_DEV_SETUP via write(). * - * This ioctl takes a "struct uinput_abs_setup" object as argument. The fields + * The ioctl takes a "struct uinput_abs_setup" object as argument. The fields * of this object are as follows: * code: The corresponding input code associated with this axis * (ABS_X, ABS_Y, etc...) @@ -124,9 +121,9 @@ struct uinput_abs_setup { * UI_SET_ABSBIT, this ioctl will enable it. * * This ioctl can be called multiple times and will overwrite previous values. - * If this ioctl fails with -EINVAL, you're recommended to use the old - * "uinput_user_dev" method via write() as fallback, in case you run on an old - * kernel that does not support this ioctl. + * If this ioctl fails with -EINVAL, it is recommended to use the old + * "uinput_user_dev" method via write() as a fallback, in case you run on an + * old kernel that does not support this ioctl. * * This ioctl may fail with -EINVAL if it is not supported or if you passed * incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the -- GitLab From daf6cd0c1829c48cba197bd87d57fc8bf3f65faa Mon Sep 17 00:00:00 2001 From: Elias Vanderstuyft Date: Fri, 18 Dec 2015 17:32:19 -0800 Subject: [PATCH 1713/2855] Input: uinput - sanity check on ff_effects_max and EV_FF Currently the user can set ff_effects_max to zero with the EV_FF bit (and the FF_GAIN and/or FF_AUTOCENTER bits) set, in this case the uninitialized methods ff->set_gain and/or ff->set_autocenter can be dereferenced, resulting in a kernel oops. Check in uinput_create_device() and print a helpful message and return -EINVAL in case the check fails. Signed-off-by: Elias Vanderstuyft Signed-off-by: Dmitry Torokhov --- drivers/input/misc/uinput.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 782df415e4d5c..4eb9e4d94f469 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -272,6 +272,13 @@ static int uinput_create_device(struct uinput_device *udev) input_set_events_per_packet(dev, 60); } + if (test_bit(EV_FF, dev->evbit) && !udev->ff_effects_max) { + printk(KERN_DEBUG "%s: ff_effects_max should be non-zero when FF_BIT is set\n", + UINPUT_NAME); + error = -EINVAL; + goto fail1; + } + if (udev->ff_effects_max) { error = input_ff_create(dev, udev->ff_effects_max); if (error) -- GitLab From 44991b3d19cd71eabe68019ae7cb91df0c929614 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 9 Apr 2014 11:13:24 +0200 Subject: [PATCH 1714/2855] mtd: nand: Disable subpage writes for drivers without ecc->hwctl nand_write_subpage_hwecc causes a crash if the driver did not register ecc->hwctl or ecc->calculate. Fix this by disabling subpage writes if ecc->hwctl or ecc->calculate is not provided by the driver. This behavior was introduced in commit 837a6ba4f3b6d23026674e6af6b6849a4634fff9 "mtd: nand: subpage write support for hardware based ECC schemes". This fixes a crash with fsl_elbc_nand and maybe others: Unable to handle kernel paging request for instruction fetch Faulting instruction address: 0x00000000 Oops: Kernel access of bad area, sig: 11 [#1] SMP NR_CPUS=2 P1020 RDB Modules linked in: ath9k ath9k_common pppoe ppp_async option iptable_nat ath9k_hw ath usb_wwan pppox ppp_generic nf_nat_ipv4 nf_conntrack_ipv4 mac80211 ipt_MASQUERADE cfg80211 xt_time xt_tcpudp xt_state xt_quota xt_policy xt_pkttype xt_owner xt_nat xt_multiport xt_mh CPU: 1 PID: 2161 Comm: ubiformat Not tainted 3.10.26 #6 task: efbc2700 ti: c7950000 task.ti: c7950000 NIP: 00000000 LR: c01a495c CTR: 00000000 REGS: c7951cb0 TRAP: 0400 Not tainted (3.10.26) MSR: 00029000 CR: 24002028 XER: 00000000 GPR00: c01a4b6c c7951d60 efbc2700 ef84b000 00000001 00000000 000001ff c7800500 GPR08: 00000000 00000000 efae5e40 c01a4ae4 24002022 10023418 c7951e5c c7800500 GPR16: c017b6a8 00000000 0000003f c053404c 00000000 00000004 00000000 00000003 GPR24: 00000010 00000200 ef84b000 c7800d00 c7800000 c7800500 ef84b1c8 00000000 NIP [00000000] (null) LR [c01a495c] nand_write_subpage_hwecc+0x74/0x174 Call Trace: [c7951d60] [c7951d64] 0xc7951d64 (unreliable) [c7951da0] [c01a4b6c] nand_write_page+0x88/0x198 [c7951dd0] [c01a5f7c] nand_do_write_ops+0x2f4/0x39c [c7951e40] [c01a61e0] nand_write+0x58/0x84 [c7951e80] [c019e29c] mtdchar_write+0x1dc/0x28c [c7951ef0] [c00aba84] vfs_write+0xcc/0x1ac [c7951f10] [c00ac04c] SyS_write+0x4c/0x90 [c7951f40] [c000cd84] ret_from_syscall+0x0/0x3c --- Exception: c01 at 0x48050ed8 LR = 0x100071b8 Instruction dump: XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX ---[ end trace 161d3c65a2a15cb8 ]--- Kernel panic - not syncing: Fatal exception [Brian: editorial note - we've applied a previous fix for the driver in question (fsl_elbc_nand) long ago: commit f034d87def51 ("mtd: eLBC NAND: fix subpage write support") but this still makes sense, and it could solve issues on some other unforseen driver.] Cc: Pekon Gupta Cc: Artem Bityutskiy Cc: David Woodhouse Signed-off-by: Helmut Schaa Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 8bb8ebd62aaac..928081bbdafd5 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -4167,7 +4167,7 @@ int nand_scan_tail(struct mtd_info *mtd) ecc->write_oob = nand_write_oob_std; if (!ecc->read_subpage) ecc->read_subpage = nand_read_subpage; - if (!ecc->write_subpage) + if (!ecc->write_subpage && ecc->hwctl && ecc->calculate) ecc->write_subpage = nand_write_subpage_hwecc; case NAND_ECC_HW_SYNDROME: -- GitLab From 0ed6ca3a22f871fdb7335194f6488d14b2dad96a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 16 Dec 2015 14:00:09 +0900 Subject: [PATCH 1715/2855] mtd: denali: make MTD_NAND_DENALI_DT dependent on OF The build passes even if CONFIG_OF is undefined, but it makes sense to let it depend on OF. Signed-off-by: Masahiro Yamada Signed-off-by: Brian Norris --- drivers/mtd/nand/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 6c71f623a932b..95b8d2b8a7afd 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -55,7 +55,7 @@ config MTD_NAND_DENALI_PCI config MTD_NAND_DENALI_DT tristate "Support Denali NAND controller as a DT device" select MTD_NAND_DENALI - depends on HAS_DMA && HAVE_CLK + depends on HAS_DMA && HAVE_CLK && OF help Enable the driver for NAND flash on platforms using a Denali NAND controller as a DT device. -- GitLab From 1873315fb156cbc8e46f28e8b128f17ff6c31728 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 8 Dec 2015 16:38:12 +0100 Subject: [PATCH 1716/2855] mtd: sh_flctl: pass FIFO as physical address By convention, the FIFO address we pass using dmaengine_slave_config is a physical address in the form that is understood by the DMA engine, as a dma_addr_t, phys_addr_t or resource_size_t. The sh_flctl driver however passes a virtual __iomem address that gets cast to dma_addr_t in the slave driver. This happens to work on shmobile because that platform sets up an identity mapping for its MMIO regions, but such code is not portable to other platforms, and prevents us from ever changing the platform mapping or reusing the driver on other architectures like ARM64 that might not have the mapping. We also get a warning about a type mismatch for the case that dma_addr_t is wider than a pointer, i.e. when CONFIG_LPAE is set: drivers/mtd/nand/sh_flctl.c: In function 'flctl_setup_dma': drivers/mtd/nand/sh_flctl.c:163:17: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] cfg.dst_addr = (dma_addr_t)FLDTFIFO(flctl); This changes the driver to instead pass the physical address of the FIFO that is extracted from the MMIO resource, making the code more portable and avoiding the warning. Signed-off-by: Arnd Bergmann Signed-off-by: Brian Norris --- drivers/mtd/nand/sh_flctl.c | 5 +++-- include/linux/mtd/sh_flctl.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index c7126b75fb014..4814402902f96 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c @@ -160,7 +160,7 @@ static void flctl_setup_dma(struct sh_flctl *flctl) memset(&cfg, 0, sizeof(cfg)); cfg.direction = DMA_MEM_TO_DEV; - cfg.dst_addr = (dma_addr_t)FLDTFIFO(flctl); + cfg.dst_addr = flctl->fifo; cfg.src_addr = 0; ret = dmaengine_slave_config(flctl->chan_fifo0_tx, &cfg); if (ret < 0) @@ -176,7 +176,7 @@ static void flctl_setup_dma(struct sh_flctl *flctl) cfg.direction = DMA_DEV_TO_MEM; cfg.dst_addr = 0; - cfg.src_addr = (dma_addr_t)FLDTFIFO(flctl); + cfg.src_addr = flctl->fifo; ret = dmaengine_slave_config(flctl->chan_fifo0_rx, &cfg); if (ret < 0) goto err; @@ -1095,6 +1095,7 @@ static int flctl_probe(struct platform_device *pdev) flctl->reg = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(flctl->reg)) return PTR_ERR(flctl->reg); + flctl->fifo = res->start + 0x24; /* FLDTFIFO */ irq = platform_get_irq(pdev, 0); if (irq < 0) { diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h index 76e3e88bedfeb..2251add65fa7e 100644 --- a/include/linux/mtd/sh_flctl.h +++ b/include/linux/mtd/sh_flctl.h @@ -147,6 +147,7 @@ struct sh_flctl { struct platform_device *pdev; struct dev_pm_qos_request pm_qos; void __iomem *reg; + resource_size_t fifo; uint8_t done_buff[2048 + 64]; /* max size 2048 + 64 */ int read_bytes; -- GitLab From 3b91d09c1ca69a69c470efe5fbf346e3e90181d5 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 9 Dec 2015 11:12:03 -0800 Subject: [PATCH 1717/2855] scsi_transport_sas: add is_sas_attached() function Adds a function designed to be callable any time (regardless of whether the transport attributes are configured or not) which returns true if the device is attached over a SAS transport. The design of this function is that transport specific functions can be embedded within a if (is_sas_attached(sdev)) { ... } which would be compiled out (and thus eliminate the symbols) if SAS is not configured. Reviewed-by: Hannes Reinecke Signed-off-by: James Bottomley --- drivers/scsi/scsi_transport_sas.c | 16 ++++++++++++++++ include/scsi/scsi_transport_sas.h | 9 +++++++++ 2 files changed, 25 insertions(+) diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 30d26e345dcc7..b17f763a73b24 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -340,6 +340,22 @@ static int do_sas_phy_delete(struct device *dev, void *data) return 0; } +/** + * is_sas_attached - check if device is SAS attached + * @sdev: scsi device to check + * + * returns true if the device is SAS attached + */ +int is_sas_attached(struct scsi_device *sdev) +{ + struct Scsi_Host *shost = sdev->host; + + return shost->transportt->host_attrs.ac.class == + &sas_host_class.class; +} +EXPORT_SYMBOL(is_sas_attached); + + /** * sas_remove_children - tear down a devices SAS data structures * @dev: device belonging to the sas object diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index 0bd71e2702e31..a8fdd10fc9c53 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h @@ -10,6 +10,15 @@ struct scsi_transport_template; struct sas_rphy; struct request; +#if !IS_ENABLED(CONFIG_SCSI_SAS_ATTRS) +static inline int is_sas_attached(struct scsi_device *sdev) +{ + return 0; +} +#else +extern int is_sas_attached(struct scsi_device *sdev); +#endif + static inline int sas_protocol_ata(enum sas_protocol proto) { return ((proto & SAS_PROTOCOL_SATA) || -- GitLab From bcf508c13385e74972f5cc06d8471d5c100395b0 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 9 Dec 2015 11:13:35 -0800 Subject: [PATCH 1718/2855] scsi_transport_sas: add function to get SAS endpoint address For a device known to be SAS connected, this will return the endpoint address. This is useful for getting the SAS address of SATA devices. Reviewed-by: Hannes Reinecke Signed-off-by: James Bottomley --- drivers/scsi/scsi_transport_sas.c | 14 ++++++++++++++ include/scsi/scsi_transport_sas.h | 1 + 2 files changed, 15 insertions(+) diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index b17f763a73b24..80520e2f0fa2b 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -382,6 +382,20 @@ void sas_remove_host(struct Scsi_Host *shost) } EXPORT_SYMBOL(sas_remove_host); +/** + * sas_get_address - return the SAS address of the device + * @sdev: scsi device + * + * Returns the SAS address of the scsi device + */ +u64 sas_get_address(struct scsi_device *sdev) +{ + struct sas_end_device *rdev = sas_sdev_to_rdev(sdev); + + return rdev->rphy.identify.sas_address; +} +EXPORT_SYMBOL(sas_get_address); + /** * sas_tlr_supported - checking TLR bit in vpd 0x90 * @sdev: scsi device struct diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index a8fdd10fc9c53..13c0b2ba1b6c0 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h @@ -189,6 +189,7 @@ extern int sas_phy_add(struct sas_phy *); extern void sas_phy_delete(struct sas_phy *); extern int scsi_is_sas_phy(const struct device *); +u64 sas_get_address(struct scsi_device *); unsigned int sas_tlr_supported(struct scsi_device *); unsigned int sas_is_tlr_enabled(struct scsi_device *); void sas_disable_tlr(struct scsi_device *); -- GitLab From 3f8d6f2a0797e8c650a47e5c1b5c2601a46f4293 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 9 Dec 2015 12:56:07 -0800 Subject: [PATCH 1719/2855] ses: fix discovery of SATA devices in SAS enclosures The current discovery routines use the VPD 0x83 inquiry page to find the device SAS address and match it to the end point in the enclosure. This doesn't work for SATA devices because expanders (or hosts) simply make up an endpoint address for STP and thus the address returned by the VPD page never matches. Instead of doing this, for SAS attached devices, match by the direct endpoint address instead. Signed-off-by: James Bottomley --- drivers/scsi/Kconfig | 1 + drivers/scsi/ses.c | 22 ++++------------------ 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 64eed87d34a87..90cd7cd6d130b 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -194,6 +194,7 @@ config CHR_DEV_SCH config SCSI_ENCLOSURE tristate "SCSI Enclosure Support" depends on SCSI && ENCLOSURE_SERVICES + depends on m || SCSI_SAS_ATTRS != m help Enclosures are devices sitting on or in SCSI backplanes that manage devices. If you have a disk cage, the chances are that diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 044d06410d4c8..53ef1cb6418e3 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -34,6 +34,8 @@ #include #include +#include + struct ses_device { unsigned char *page1; unsigned char *page1_types; @@ -579,31 +581,15 @@ static void ses_enclosure_data_process(struct enclosure_device *edev, static void ses_match_to_enclosure(struct enclosure_device *edev, struct scsi_device *sdev) { - unsigned char *desc; struct efd efd = { .addr = 0, }; ses_enclosure_data_process(edev, to_scsi_device(edev->edev.parent), 0); - if (!sdev->vpd_pg83_len) - return; - - desc = sdev->vpd_pg83 + 4; - while (desc < sdev->vpd_pg83 + sdev->vpd_pg83_len) { - enum scsi_protocol proto = desc[0] >> 4; - u8 code_set = desc[0] & 0x0f; - u8 piv = desc[1] & 0x80; - u8 assoc = (desc[1] & 0x30) >> 4; - u8 type = desc[1] & 0x0f; - u8 len = desc[3]; - - if (piv && code_set == 1 && assoc == 1 - && proto == SCSI_PROTOCOL_SAS && type == 3 && len == 8) - efd.addr = get_unaligned_be64(&desc[4]); + if (is_sas_attached(sdev)) + efd.addr = sas_get_address(sdev); - desc += len + 4; - } if (efd.addr) { efd.dev = &sdev->sdev_gendev; -- GitLab From c395465da68bfc3a238d5bc15f862e33e6e9ecec Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Wed, 28 Oct 2015 15:54:06 +1100 Subject: [PATCH 1720/2855] powerpc: Add function to copy mm_context_t to the paca This adds a function to copy the mm->context to the paca. This is only a basic conversion for now but will be used more extensively in the next patch. This also adds #ifdef CONFIG_PPC_BOOK3S around this code since it's not used elsewhere. Signed-off-by: Michael Neuling Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/paca.h | 11 +++++++++++ arch/powerpc/kernel/asm-offsets.c | 2 ++ arch/powerpc/mm/hash_utils_64.c | 5 +++-- arch/powerpc/mm/slb.c | 2 +- arch/powerpc/mm/slice.c | 3 +-- 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index 70bd4381f8e6a..1cc6e08289076 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -131,7 +131,9 @@ struct paca_struct { struct tlb_core_data tcd; #endif /* CONFIG_PPC_BOOK3E */ +#ifdef CONFIG_PPC_BOOK3S mm_context_t context; +#endif /* * then miscellaneous read-write fields @@ -194,6 +196,15 @@ struct paca_struct { #endif }; +#ifdef CONFIG_PPC_BOOK3S +static inline void copy_mm_to_paca(mm_context_t *context) +{ + get_paca()->context = *context; +} +#else +static inline void copy_mm_to_paca(mm_context_t *context){} +#endif + extern struct paca_struct *paca; extern void initialise_paca(struct paca_struct *new_paca, int cpu); extern void setup_paca(struct paca_struct *new_paca); diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 221d584d089f9..9db7be292bf36 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -185,6 +185,7 @@ int main(void) DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr)); DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled)); DEFINE(PACAIRQHAPPENED, offsetof(struct paca_struct, irq_happened)); +#ifdef CONFIG_PPC_BOOK3S DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id)); #ifdef CONFIG_PPC_MM_SLICES DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct, @@ -193,6 +194,7 @@ int main(void) context.high_slices_psize)); DEFINE(MMUPSIZEDEFSIZE, sizeof(struct mmu_psize_def)); #endif /* CONFIG_PPC_MM_SLICES */ +#endif #ifdef CONFIG_PPC_BOOK3E DEFINE(PACAPGD, offsetof(struct paca_struct, pgd)); diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 4233dcccbaf77..03279eac09571 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -882,7 +882,8 @@ void demote_segment_4k(struct mm_struct *mm, unsigned long addr) slice_set_range_psize(mm, addr, 1, MMU_PAGE_4K); copro_flush_all_slbs(mm); if ((get_paca_psize(addr) != MMU_PAGE_4K) && (current->mm == mm)) { - get_paca()->context = mm->context; + + copy_mm_to_paca(&mm->context); slb_flush_and_rebolt(); } } @@ -949,7 +950,7 @@ static void check_paca_psize(unsigned long ea, struct mm_struct *mm, { if (user_region) { if (psize != get_paca_psize(ea)) { - get_paca()->context = mm->context; + copy_mm_to_paca(&mm->context); slb_flush_and_rebolt(); } } else if (get_paca()->vmalloc_sllp != diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index 515730e499fe6..825b6873391f9 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c @@ -228,7 +228,7 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm) asm volatile("slbie %0" : : "r" (slbie_data)); get_paca()->slb_cache_ptr = 0; - get_paca()->context = mm->context; + copy_mm_to_paca(&mm->context); /* * preload some userspace segments into the SLB. diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c index 0f432a702870f..42954f0b47ace 100644 --- a/arch/powerpc/mm/slice.c +++ b/arch/powerpc/mm/slice.c @@ -185,8 +185,7 @@ static void slice_flush_segments(void *parm) if (mm != current->active_mm) return; - /* update the paca copy of the context struct */ - get_paca()->context = current->active_mm->context; + copy_mm_to_paca(¤t->active_mm->context); local_irq_save(flags); slb_flush_and_rebolt(); -- GitLab From 75e1a3a789e1f7437e4d369a5ba45ebd5dd24490 Mon Sep 17 00:00:00 2001 From: Marc Titinger Date: Tue, 15 Dec 2015 16:26:22 +0100 Subject: [PATCH 1721/2855] iio: ina2xx: fix channel order in software buffer POWER and CURRENT were swapped out in the buffer: was current2 and power3, correct order is power2 and current3. Signed-off-by: Marc Titinger Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ina2xx-adc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index 4c18c4cc89394..bd56adaeec05a 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -428,8 +428,8 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev, static const struct iio_chan_spec ina2xx_channels[] = { INA2XX_CHAN_VOLTAGE(0, INA2XX_SHUNT_VOLTAGE), INA2XX_CHAN_VOLTAGE(1, INA2XX_BUS_VOLTAGE), - INA2XX_CHAN(IIO_CURRENT, 2, INA2XX_CURRENT), - INA2XX_CHAN(IIO_POWER, 3, INA2XX_POWER), + INA2XX_CHAN(IIO_POWER, 2, INA2XX_POWER), + INA2XX_CHAN(IIO_CURRENT, 3, INA2XX_CURRENT), IIO_CHAN_SOFT_TIMESTAMP(4), }; -- GitLab From 6e17c98a004c921e07bdecdb8cc2320488f88759 Mon Sep 17 00:00:00 2001 From: Marc Titinger Date: Mon, 14 Dec 2015 12:01:10 +0100 Subject: [PATCH 1722/2855] iio: ina2xx: add ABI documentation entry sysfs-bus-iio-ina2xx-adc Documentation for attributes: * in_allow_async_readout * in_shunt_resistor Signed-off-by: Marc Titinger Signed-off-by: Jonathan Cameron --- .../ABI/testing/sysfs-bus-iio-ina2xx-adc | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-ina2xx-adc diff --git a/Documentation/ABI/testing/sysfs-bus-iio-ina2xx-adc b/Documentation/ABI/testing/sysfs-bus-iio-ina2xx-adc new file mode 100644 index 0000000000000..8916f7ec65074 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-ina2xx-adc @@ -0,0 +1,24 @@ +What: /sys/bus/iio/devices/iio:deviceX/in_allow_async_readout +Date: December 2015 +KernelVersion: 4.4 +Contact: linux-iio@vger.kernel.org +Description: + By default (value '0'), the capture thread checks for the Conversion + Ready Flag to being set prior to committing a new value to the sample + buffer. This synchronizes the in-chip conversion rate with the + in-driver readout rate at the cost of an additional register read. + + Writing '1' will remove the polling for the Conversion Ready Flags to + save the additional i2c transaction, which will improve the bandwidth + available for reading data. However, samples can be occasionally skipped + or repeated, depending on the beat between the capture and conversion + rates. + +What: /sys/bus/iio/devices/iio:deviceX/in_shunt_resistor +Date: December 2015 +KernelVersion: 4.4 +Contact: linux-iio@vger.kernel.org +Description: + The value of the shunt resistor may be known only at runtime fom an + eeprom content read by a client application. This attribute allows to + set its value in ohms. -- GitLab From 34708a0ce860fc70112c285cfde717b1d1aed708 Mon Sep 17 00:00:00 2001 From: Bhaktipriya Shridhar Date: Sun, 13 Dec 2015 18:15:13 +0300 Subject: [PATCH 1723/2855] Staging: iio: accel: sca3000: Fixed NULL comparison style The variable u8 **rx_p, is a pointer-to-pointer and hence the check should be "if (!*rx_p)" and not "if (!rx_p)". In the earlier version, checkpatch.pl gave the following check, which was incorrect: CHECK: Comparison to NULL could be written "!rx_p" + if (*rx_p == NULL) { Signed-off-by: Bhaktipriya Shridhar Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/sca3000_ring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c index 20b878d35ea2e..1920dc60cf3d2 100644 --- a/drivers/staging/iio/accel/sca3000_ring.c +++ b/drivers/staging/iio/accel/sca3000_ring.c @@ -48,7 +48,7 @@ static int sca3000_read_data(struct sca3000_state *st, } }; *rx_p = kmalloc(len, GFP_KERNEL); - if (*rx_p == NULL) { + if (!*rx_p) { ret = -ENOMEM; goto error_ret; } -- GitLab From 8e34f2c8d2688a84f516d698aa8a8438a668265f Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Tue, 15 Dec 2015 17:44:59 +0100 Subject: [PATCH 1724/2855] iio: mma8452: remove unused register description Signed-off-by: Martin Kepplinger Signed-off-by: Christoph Muellner Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma8452.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 116a6e401a6aa..162bbef8139f4 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -58,7 +58,6 @@ #define MMA8452_FF_MT_COUNT 0x18 #define MMA8452_TRANSIENT_CFG 0x1d #define MMA8452_TRANSIENT_CFG_HPF_BYP BIT(0) -#define MMA8452_TRANSIENT_CFG_CHAN(chan) BIT(chan + 1) #define MMA8452_TRANSIENT_CFG_ELE BIT(4) #define MMA8452_TRANSIENT_SRC 0x1e #define MMA8452_TRANSIENT_SRC_XTRANSE BIT(1) -- GitLab From e60378c17c7eebf8636fb6831bff1efc9a434521 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Tue, 15 Dec 2015 17:45:00 +0100 Subject: [PATCH 1725/2855] iio: mma8452: use enum for channel index This gets rid of some magic numbers by adding an enum. Signed-off-by: Martin Kepplinger Signed-off-by: Christoph Muellner Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma8452.c | 39 ++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 162bbef8139f4..ccc632a7cf019 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -143,6 +143,13 @@ struct mma_chip_info { u8 ev_count; }; +enum { + idx_x, + idx_y, + idx_z, + idx_ts, +}; + static int mma8452_drdy(struct mma8452_data *data) { int tries = 150; @@ -816,31 +823,31 @@ static struct attribute_group mma8452_event_attribute_group = { } static const struct iio_chan_spec mma8452_channels[] = { - MMA8452_CHANNEL(X, 0, 12), - MMA8452_CHANNEL(Y, 1, 12), - MMA8452_CHANNEL(Z, 2, 12), - IIO_CHAN_SOFT_TIMESTAMP(3), + MMA8452_CHANNEL(X, idx_x, 12), + MMA8452_CHANNEL(Y, idx_y, 12), + MMA8452_CHANNEL(Z, idx_z, 12), + IIO_CHAN_SOFT_TIMESTAMP(idx_ts), }; static const struct iio_chan_spec mma8453_channels[] = { - MMA8452_CHANNEL(X, 0, 10), - MMA8452_CHANNEL(Y, 1, 10), - MMA8452_CHANNEL(Z, 2, 10), - IIO_CHAN_SOFT_TIMESTAMP(3), + MMA8452_CHANNEL(X, idx_x, 10), + MMA8452_CHANNEL(Y, idx_y, 10), + MMA8452_CHANNEL(Z, idx_z, 10), + IIO_CHAN_SOFT_TIMESTAMP(idx_ts), }; static const struct iio_chan_spec mma8652_channels[] = { - MMA8652_CHANNEL(X, 0, 12), - MMA8652_CHANNEL(Y, 1, 12), - MMA8652_CHANNEL(Z, 2, 12), - IIO_CHAN_SOFT_TIMESTAMP(3), + MMA8652_CHANNEL(X, idx_x, 12), + MMA8652_CHANNEL(Y, idx_y, 12), + MMA8652_CHANNEL(Z, idx_z, 12), + IIO_CHAN_SOFT_TIMESTAMP(idx_ts), }; static const struct iio_chan_spec mma8653_channels[] = { - MMA8652_CHANNEL(X, 0, 10), - MMA8652_CHANNEL(Y, 1, 10), - MMA8652_CHANNEL(Z, 2, 10), - IIO_CHAN_SOFT_TIMESTAMP(3), + MMA8652_CHANNEL(X, idx_x, 10), + MMA8652_CHANNEL(Y, idx_y, 10), + MMA8652_CHANNEL(Z, idx_z, 10), + IIO_CHAN_SOFT_TIMESTAMP(idx_ts), }; enum { -- GitLab From 8dcb3c7628f19192dd568fbee9094a2d4b14b6af Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 19 Dec 2015 09:22:21 -0800 Subject: [PATCH 1726/2855] Input: egalax_ts_serial - fix potential NULL dereference on error We didn't check input_allocate_device() for failures so it could lead to a NULL deref. Fixes: 6b0f8f9c52ef ('Input: add eGalaxTouch serial touchscreen driver') Signed-off-by: Dan Carpenter Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/egalax_ts_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/egalax_ts_serial.c b/drivers/input/touchscreen/egalax_ts_serial.c index a078c1c2c3f91..657bbae608c8d 100644 --- a/drivers/input/touchscreen/egalax_ts_serial.c +++ b/drivers/input/touchscreen/egalax_ts_serial.c @@ -105,7 +105,7 @@ static int egalax_connect(struct serio *serio, struct serio_driver *drv) egalax = kzalloc(sizeof(struct egalax), GFP_KERNEL); input_dev = input_allocate_device(); - if (!egalax) { + if (!egalax || !input_dev) { error = -ENOMEM; goto err_free_mem; } -- GitLab From f3b5a8d9b50d71b8c9fb72aa9c8ea948ad1a4ef9 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 30 Nov 2015 10:44:30 +0900 Subject: [PATCH 1727/2855] phy: rcar-gen3-usb2: Add R-Car Gen3 USB2 PHY driver This patch adds support for R-Car generation 3 USB2 PHY driver. This SoC has 3 EHCI/OHCI channels, and the channel 0 is shared with the HSUSB (USB2.0 peripheral) device. And each channel has independent registers about the PHYs. So, the purpose of this driver is: 1) initializes some registers of SoC specific to use the {ehci,ohci}-platform driver. 2) detects id pin to select host or peripheral on the channel 0. For now, this driver only supports 1) above. Signed-off-by: Yoshihiro Shimoda Acked-by: Rob Herring Signed-off-by: Kishon Vijay Abraham I --- .../bindings/phy/rcar-gen3-phy-usb2.txt | 37 +++ drivers/phy/Kconfig | 7 + drivers/phy/Makefile | 1 + drivers/phy/phy-rcar-gen3-usb2.c | 217 ++++++++++++++++++ 4 files changed, 262 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt create mode 100644 drivers/phy/phy-rcar-gen3-usb2.c diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt new file mode 100644 index 0000000000000..affa0f72658bc --- /dev/null +++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt @@ -0,0 +1,37 @@ +* Renesas R-Car generation 3 USB 2.0 PHY + +This file provides information on what the device node for the R-Car generation +3 USB 2.0 PHY contains. + +Required properties: +- compatible: "renesas,usb2-phy-r8a7795" if the device is a part of an R8A7795 + SoC. +- reg: offset and length of the partial USB 2.0 Host register block. +- reg-names: must be "usb2_host". +- clocks: clock phandle and specifier pair(s). +- #phy-cells: see phy-bindings.txt in the same directory, must be <0>. + +Optional properties: +To use a USB channel where USB 2.0 Host and HSUSB (USB 2.0 Peripheral) are +combined, the device tree node should set HSUSB properties to reg and reg-names +properties. This is because HSUSB has registers to select USB 2.0 host or +peripheral at that channel: +- reg: offset and length of the partial HSUSB register block. +- reg-names: must be "hsusb". + +Example (R-Car H3): + + usb-phy@ee080200 { + compatible = "renesas,usb2-phy-r8a7795"; + reg = <0 0xee080200 0 0x700>, <0 0xe6590100 0 0x100>; + reg-names = "usb2_host", "hsusb"; + clocks = <&mstp7_clks R8A7795_CLK_EHCI0>, + <&mstp7_clks R8A7795_CLK_HSUSB>; + }; + + usb-phy@ee0a0200 { + compatible = "renesas,usb2-phy-r8a7795"; + reg = <0 0xee0a0200 0 0x700>; + reg-names = "usb2_host"; + clocks = <&mstp7_clks R8A7795_CLK_EHCI0>; + }; diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 03cb3ea2d2c03..f90b7660dd3ec 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -118,6 +118,13 @@ config PHY_RCAR_GEN2 help Support for USB PHY found on Renesas R-Car generation 2 SoCs. +config PHY_RCAR_GEN3_USB2 + tristate "Renesas R-Car generation 3 USB 2.0 PHY driver" + depends on OF && ARCH_SHMOBILE + select GENERIC_PHY + help + Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs. + config OMAP_CONTROL_PHY tristate "OMAP CONTROL PHY Driver" depends on ARCH_OMAP2PLUS || COMPILE_TEST diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 075db1a81aa5c..91d7a62c6794d 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o obj-$(CONFIG_PHY_MIPHY28LP) += phy-miphy28lp.o obj-$(CONFIG_PHY_MIPHY365X) += phy-miphy365x.o obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o +obj-$(CONFIG_PHY_RCAR_GEN3_USB2) += phy-rcar-gen3-usb2.o obj-$(CONFIG_OMAP_CONTROL_PHY) += phy-omap-control.o obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o obj-$(CONFIG_TI_PIPE3) += phy-ti-pipe3.o diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c new file mode 100644 index 0000000000000..269615228b1b0 --- /dev/null +++ b/drivers/phy/phy-rcar-gen3-usb2.c @@ -0,0 +1,217 @@ +/* + * Renesas R-Car Gen3 for USB2.0 PHY driver + * + * Copyright (C) 2015 Renesas Electronics Corporation + * + * This is based on the phy-rcar-gen2 driver: + * Copyright (C) 2014 Renesas Solutions Corp. + * Copyright (C) 2014 Cogent Embedded, Inc. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +/******* USB2.0 Host registers (original offset is +0x200) *******/ +#define USB2_INT_ENABLE 0x000 +#define USB2_USBCTR 0x00c +#define USB2_SPD_RSM_TIMSET 0x10c +#define USB2_OC_TIMSET 0x110 + +/* INT_ENABLE */ +#define USB2_INT_ENABLE_USBH_INTB_EN BIT(2) +#define USB2_INT_ENABLE_USBH_INTA_EN BIT(1) +#define USB2_INT_ENABLE_INIT (USB2_INT_ENABLE_USBH_INTB_EN | \ + USB2_INT_ENABLE_USBH_INTA_EN) + +/* USBCTR */ +#define USB2_USBCTR_DIRPD BIT(2) +#define USB2_USBCTR_PLL_RST BIT(1) + +/* SPD_RSM_TIMSET */ +#define USB2_SPD_RSM_TIMSET_INIT 0x014e029b + +/* OC_TIMSET */ +#define USB2_OC_TIMSET_INIT 0x000209ab + +/******* HSUSB registers (original offset is +0x100) *******/ +#define HSUSB_LPSTS 0x02 +#define HSUSB_UGCTRL2 0x84 + +/* Low Power Status register (LPSTS) */ +#define HSUSB_LPSTS_SUSPM 0x4000 + +/* USB General control register 2 (UGCTRL2) */ +#define HSUSB_UGCTRL2_MASK 0x00000031 /* bit[31:6] should be 0 */ +#define HSUSB_UGCTRL2_USB0SEL 0x00000030 +#define HSUSB_UGCTRL2_USB0SEL_HOST 0x00000010 +#define HSUSB_UGCTRL2_USB0SEL_HS_USB 0x00000020 +#define HSUSB_UGCTRL2_USB0SEL_OTG 0x00000030 + +struct rcar_gen3_data { + void __iomem *base; + struct clk *clk; +}; + +struct rcar_gen3_chan { + struct rcar_gen3_data usb2; + struct rcar_gen3_data hsusb; + struct phy *phy; +}; + +static int rcar_gen3_phy_usb2_init(struct phy *p) +{ + struct rcar_gen3_chan *channel = phy_get_drvdata(p); + void __iomem *usb2_base = channel->usb2.base; + void __iomem *hsusb_base = channel->hsusb.base; + u32 val; + + /* Initialize USB2 part */ + writel(USB2_INT_ENABLE_INIT, usb2_base + USB2_INT_ENABLE); + writel(USB2_SPD_RSM_TIMSET_INIT, usb2_base + USB2_SPD_RSM_TIMSET); + writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET); + + /* Initialize HSUSB part */ + if (hsusb_base) { + /* TODO: support "OTG" mode */ + val = readl(hsusb_base + HSUSB_UGCTRL2); + val = (val & ~HSUSB_UGCTRL2_USB0SEL) | + HSUSB_UGCTRL2_USB0SEL_HOST; + writel(val & HSUSB_UGCTRL2_MASK, hsusb_base + HSUSB_UGCTRL2); + } + + return 0; +} + +static int rcar_gen3_phy_usb2_exit(struct phy *p) +{ + struct rcar_gen3_chan *channel = phy_get_drvdata(p); + + writel(0, channel->usb2.base + USB2_INT_ENABLE); + + return 0; +} + +static int rcar_gen3_phy_usb2_power_on(struct phy *p) +{ + struct rcar_gen3_chan *channel = phy_get_drvdata(p); + void __iomem *usb2_base = channel->usb2.base; + void __iomem *hsusb_base = channel->hsusb.base; + u32 val; + + val = readl(usb2_base + USB2_USBCTR); + val |= USB2_USBCTR_PLL_RST; + writel(val, usb2_base + USB2_USBCTR); + val &= ~USB2_USBCTR_PLL_RST; + writel(val, usb2_base + USB2_USBCTR); + + /* + * TODO: To reduce power consuming, this driver should set the SUSPM + * after the PHY detects ID pin as peripheral. + */ + if (hsusb_base) { + /* Power on HSUSB PHY */ + val = readw(hsusb_base + HSUSB_LPSTS); + val |= HSUSB_LPSTS_SUSPM; + writew(val, hsusb_base + HSUSB_LPSTS); + } + + return 0; +} + +static int rcar_gen3_phy_usb2_power_off(struct phy *p) +{ + struct rcar_gen3_chan *channel = phy_get_drvdata(p); + void __iomem *hsusb_base = channel->hsusb.base; + u32 val; + + if (hsusb_base) { + /* Power off HSUSB PHY */ + val = readw(hsusb_base + HSUSB_LPSTS); + val &= ~HSUSB_LPSTS_SUSPM; + writew(val, hsusb_base + HSUSB_LPSTS); + } + + return 0; +} + +static struct phy_ops rcar_gen3_phy_usb2_ops = { + .init = rcar_gen3_phy_usb2_init, + .exit = rcar_gen3_phy_usb2_exit, + .power_on = rcar_gen3_phy_usb2_power_on, + .power_off = rcar_gen3_phy_usb2_power_off, + .owner = THIS_MODULE, +}; + +static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = { + { .compatible = "renesas,usb2-phy-r8a7795" }, + { } +}; +MODULE_DEVICE_TABLE(of, rcar_gen3_phy_usb2_match_table); + +static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rcar_gen3_chan *channel; + struct phy_provider *provider; + struct resource *res; + + if (!dev->of_node) { + dev_err(dev, "This driver needs device tree\n"); + return -EINVAL; + } + + channel = devm_kzalloc(dev, sizeof(*channel), GFP_KERNEL); + if (!channel) + return -ENOMEM; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "usb2_host"); + channel->usb2.base = devm_ioremap_resource(dev, res); + if (IS_ERR(channel->usb2.base)) + return PTR_ERR(channel->usb2.base); + + /* "hsusb" memory resource is optional */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hsusb"); + + /* To avoid error message by devm_ioremap_resource() */ + if (res) { + channel->hsusb.base = devm_ioremap_resource(dev, res); + if (IS_ERR(channel->hsusb.base)) + channel->hsusb.base = NULL; + } + + /* devm_phy_create() will call pm_runtime_enable(dev); */ + channel->phy = devm_phy_create(dev, NULL, &rcar_gen3_phy_usb2_ops); + if (IS_ERR(channel->phy)) { + dev_err(dev, "Failed to create USB2 PHY\n"); + return PTR_ERR(channel->phy); + } + + phy_set_drvdata(channel->phy, channel); + + provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + if (IS_ERR(provider)) + dev_err(dev, "Failed to register PHY provider\n"); + + return PTR_ERR_OR_ZERO(provider); +} + +static struct platform_driver rcar_gen3_phy_usb2_driver = { + .driver = { + .name = "phy_rcar_gen3_usb2", + .of_match_table = rcar_gen3_phy_usb2_match_table, + }, + .probe = rcar_gen3_phy_usb2_probe, +}; +module_platform_driver(rcar_gen3_phy_usb2_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Renesas R-Car Gen3 USB 2.0 PHY"); +MODULE_AUTHOR("Yoshihiro Shimoda "); -- GitLab From 1114e2d3173190be3e7339449c45ef11302d905a Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 30 Nov 2015 10:44:31 +0900 Subject: [PATCH 1728/2855] phy: rcar-gen3-usb2: change the mode to OTG on the combined channel To use the channel 0 of R-Car gen3 as periperal mode, This patch changes the mode to OTG instead of HOST. Then, this driver needs to set some registers to enable host mode and detects ID pin and VBUS pin at phy_init() timing. For now, the channel 0 can be used as host mode only. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-rcar-gen3-usb2.c | 124 ++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 2 deletions(-) diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c index 269615228b1b0..2b5d890554ad7 100644 --- a/drivers/phy/phy-rcar-gen3-usb2.c +++ b/drivers/phy/phy-rcar-gen3-usb2.c @@ -24,6 +24,10 @@ #define USB2_USBCTR 0x00c #define USB2_SPD_RSM_TIMSET 0x10c #define USB2_OC_TIMSET 0x110 +#define USB2_COMMCTRL 0x600 +#define USB2_VBCTRL 0x60c +#define USB2_LINECTRL1 0x610 +#define USB2_ADPCTRL 0x630 /* INT_ENABLE */ #define USB2_INT_ENABLE_USBH_INTB_EN BIT(2) @@ -41,6 +45,24 @@ /* OC_TIMSET */ #define USB2_OC_TIMSET_INIT 0x000209ab +/* COMMCTRL */ +#define USB2_COMMCTRL_OTG_PERI BIT(31) /* 1 = Peripheral mode */ + +/* VBCTRL */ +#define USB2_VBCTRL_DRVVBUSSEL BIT(8) + +/* LINECTRL1 */ +#define USB2_LINECTRL1_DPRPD_EN BIT(19) +#define USB2_LINECTRL1_DP_RPD BIT(18) +#define USB2_LINECTRL1_DMRPD_EN BIT(17) +#define USB2_LINECTRL1_DM_RPD BIT(16) + +/* ADPCTRL */ +#define USB2_ADPCTRL_OTGSESSVLD BIT(20) +#define USB2_ADPCTRL_IDDIG BIT(19) +#define USB2_ADPCTRL_IDPULLUP BIT(5) /* 1 = ID sampling is enabled */ +#define USB2_ADPCTRL_DRVVBUS BIT(4) + /******* HSUSB registers (original offset is +0x100) *******/ #define HSUSB_LPSTS 0x02 #define HSUSB_UGCTRL2 0x84 @@ -66,6 +88,102 @@ struct rcar_gen3_chan { struct phy *phy; }; +static void rcar_gen3_set_host_mode(struct rcar_gen3_chan *ch, int host) +{ + void __iomem *usb2_base = ch->usb2.base; + u32 val = readl(usb2_base + USB2_COMMCTRL); + + dev_vdbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, val, host); + if (host) + val &= ~USB2_COMMCTRL_OTG_PERI; + else + val |= USB2_COMMCTRL_OTG_PERI; + writel(val, usb2_base + USB2_COMMCTRL); +} + +static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm) +{ + void __iomem *usb2_base = ch->usb2.base; + u32 val = readl(usb2_base + USB2_LINECTRL1); + + dev_vdbg(&ch->phy->dev, "%s: %08x, %d, %d\n", __func__, val, dp, dm); + val &= ~(USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD); + if (dp) + val |= USB2_LINECTRL1_DP_RPD; + if (dm) + val |= USB2_LINECTRL1_DM_RPD; + writel(val, usb2_base + USB2_LINECTRL1); +} + +static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus) +{ + void __iomem *usb2_base = ch->usb2.base; + u32 val = readl(usb2_base + USB2_ADPCTRL); + + dev_vdbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, val, vbus); + if (vbus) + val |= USB2_ADPCTRL_DRVVBUS; + else + val &= ~USB2_ADPCTRL_DRVVBUS; + writel(val, usb2_base + USB2_ADPCTRL); +} + +static void rcar_gen3_init_for_host(struct rcar_gen3_chan *ch) +{ + rcar_gen3_set_linectrl(ch, 1, 1); + rcar_gen3_set_host_mode(ch, 1); + rcar_gen3_enable_vbus_ctrl(ch, 1); +} + +static void rcar_gen3_init_for_peri(struct rcar_gen3_chan *ch) +{ + rcar_gen3_set_linectrl(ch, 0, 1); + rcar_gen3_set_host_mode(ch, 0); + rcar_gen3_enable_vbus_ctrl(ch, 0); +} + +static bool rcar_gen3_check_vbus(struct rcar_gen3_chan *ch) +{ + return !!(readl(ch->usb2.base + USB2_ADPCTRL) & + USB2_ADPCTRL_OTGSESSVLD); +} + +static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch) +{ + return !!(readl(ch->usb2.base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG); +} + +static void rcar_gen3_device_recognition(struct rcar_gen3_chan *ch) +{ + bool is_host = true; + + /* B-device? */ + if (rcar_gen3_check_id(ch) && rcar_gen3_check_vbus(ch)) + is_host = false; + + if (is_host) + rcar_gen3_init_for_host(ch); + else + rcar_gen3_init_for_peri(ch); +} + +static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch) +{ + void __iomem *usb2_base = ch->usb2.base; + u32 val; + + val = readl(usb2_base + USB2_VBCTRL); + writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL); + val = readl(usb2_base + USB2_ADPCTRL); + writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL); + val = readl(usb2_base + USB2_LINECTRL1); + rcar_gen3_set_linectrl(ch, 0, 0); + writel(val | USB2_LINECTRL1_DPRPD_EN | USB2_LINECTRL1_DMRPD_EN, + usb2_base + USB2_LINECTRL1); + + rcar_gen3_device_recognition(ch); +} + static int rcar_gen3_phy_usb2_init(struct phy *p) { struct rcar_gen3_chan *channel = phy_get_drvdata(p); @@ -80,11 +198,13 @@ static int rcar_gen3_phy_usb2_init(struct phy *p) /* Initialize HSUSB part */ if (hsusb_base) { - /* TODO: support "OTG" mode */ val = readl(hsusb_base + HSUSB_UGCTRL2); val = (val & ~HSUSB_UGCTRL2_USB0SEL) | - HSUSB_UGCTRL2_USB0SEL_HOST; + HSUSB_UGCTRL2_USB0SEL_OTG; writel(val & HSUSB_UGCTRL2_MASK, hsusb_base + HSUSB_UGCTRL2); + + /* Initialize otg part */ + rcar_gen3_init_otg(channel); } return 0; -- GitLab From 9f391c574efc15f00a6c7e3e120c8b84fc9e792f Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 30 Nov 2015 10:44:32 +0900 Subject: [PATCH 1729/2855] phy: rcar-gen3-usb2: add runtime ID/VBUS pin detection This patch adds support for runtime ID/VBUS pin detection if the channel 0 of R-Car gen3 is used. So, we are able to use the channel as both host and peripheral. Signed-off-by: Yoshihiro Shimoda Acked-by: Rob Herring Signed-off-by: Kishon Vijay Abraham I --- .../bindings/phy/rcar-gen3-phy-usb2.txt | 2 + drivers/phy/phy-rcar-gen3-usb2.c | 43 ++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt index affa0f72658bc..2390e4e9c84c6 100644 --- a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt +++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt @@ -18,6 +18,7 @@ properties. This is because HSUSB has registers to select USB 2.0 host or peripheral at that channel: - reg: offset and length of the partial HSUSB register block. - reg-names: must be "hsusb". +- interrupts: interrupt specifier for the PHY. Example (R-Car H3): @@ -25,6 +26,7 @@ Example (R-Car H3): compatible = "renesas,usb2-phy-r8a7795"; reg = <0 0xee080200 0 0x700>, <0 0xe6590100 0 0x100>; reg-names = "usb2_host", "hsusb"; + interrupts = ; clocks = <&mstp7_clks R8A7795_CLK_EHCI0>, <&mstp7_clks R8A7795_CLK_HSUSB>; }; diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c index 2b5d890554ad7..ef332ef4abc71 100644 --- a/drivers/phy/phy-rcar-gen3-usb2.c +++ b/drivers/phy/phy-rcar-gen3-usb2.c @@ -12,6 +12,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include @@ -25,14 +26,18 @@ #define USB2_SPD_RSM_TIMSET 0x10c #define USB2_OC_TIMSET 0x110 #define USB2_COMMCTRL 0x600 +#define USB2_OBINTSTA 0x604 +#define USB2_OBINTEN 0x608 #define USB2_VBCTRL 0x60c #define USB2_LINECTRL1 0x610 #define USB2_ADPCTRL 0x630 /* INT_ENABLE */ +#define USB2_INT_ENABLE_UCOM_INTEN BIT(3) #define USB2_INT_ENABLE_USBH_INTB_EN BIT(2) #define USB2_INT_ENABLE_USBH_INTA_EN BIT(1) -#define USB2_INT_ENABLE_INIT (USB2_INT_ENABLE_USBH_INTB_EN | \ +#define USB2_INT_ENABLE_INIT (USB2_INT_ENABLE_UCOM_INTEN | \ + USB2_INT_ENABLE_USBH_INTB_EN | \ USB2_INT_ENABLE_USBH_INTA_EN) /* USBCTR */ @@ -48,6 +53,12 @@ /* COMMCTRL */ #define USB2_COMMCTRL_OTG_PERI BIT(31) /* 1 = Peripheral mode */ +/* OBINTSTA and OBINTEN */ +#define USB2_OBINT_SESSVLDCHG BIT(12) +#define USB2_OBINT_IDDIGCHG BIT(11) +#define USB2_OBINT_BITS (USB2_OBINT_SESSVLDCHG | \ + USB2_OBINT_IDDIGCHG) + /* VBCTRL */ #define USB2_VBCTRL_DRVVBUSSEL BIT(8) @@ -174,6 +185,9 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch) val = readl(usb2_base + USB2_VBCTRL); writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL); + writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA); + val = readl(usb2_base + USB2_OBINTEN); + writel(val | USB2_OBINT_BITS, usb2_base + USB2_OBINTEN); val = readl(usb2_base + USB2_ADPCTRL); writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL); val = readl(usb2_base + USB2_LINECTRL1); @@ -270,6 +284,23 @@ static struct phy_ops rcar_gen3_phy_usb2_ops = { .owner = THIS_MODULE, }; +static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch) +{ + struct rcar_gen3_chan *ch = _ch; + void __iomem *usb2_base = ch->usb2.base; + u32 status = readl(usb2_base + USB2_OBINTSTA); + irqreturn_t ret = IRQ_NONE; + + if (status & USB2_OBINT_BITS) { + dev_vdbg(&ch->phy->dev, "%s: %08x\n", __func__, status); + writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA); + rcar_gen3_device_recognition(ch); + ret = IRQ_HANDLED; + } + + return ret; +} + static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = { { .compatible = "renesas,usb2-phy-r8a7795" }, { } @@ -302,9 +333,19 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) /* To avoid error message by devm_ioremap_resource() */ if (res) { + int irq; + channel->hsusb.base = devm_ioremap_resource(dev, res); if (IS_ERR(channel->hsusb.base)) channel->hsusb.base = NULL; + /* call request_irq for OTG */ + irq = platform_get_irq(pdev, 0); + if (irq >= 0) + irq = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq, + IRQF_SHARED, dev_name(dev), + channel); + if (irq < 0) + dev_err(dev, "No irq handler (%d)\n", irq); } /* devm_phy_create() will call pm_runtime_enable(dev); */ -- GitLab From 3e46c3973cbafbd4974f7ab0d32071427afb7c1c Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 30 Nov 2015 10:44:33 +0900 Subject: [PATCH 1730/2855] MAINTAINERS: add Renesas usb2 phy driver Add Renesas usb2 phy driver to maintainer entry. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Kishon Vijay Abraham I --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index e9caa4b288284..ac1e3019ec924 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8928,6 +8928,12 @@ F: drivers/rpmsg/ F: Documentation/rpmsg.txt F: include/linux/rpmsg.h +RENESAS USB2 PHY DRIVER +M: Yoshihiro Shimoda +L: linux-sh@vger.kernel.org +S: Maintained +F: drivers/phy/phy-rcar-gen3-usb2.c + RESET CONTROLLER FRAMEWORK M: Philipp Zabel S: Maintained -- GitLab From 43f53b19074e846f236ef230d1eb4b14b601e965 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 4 Dec 2015 10:08:56 +0800 Subject: [PATCH 1731/2855] phy: phy-mt65xx-usb3: fix test fail of HS receiver sensitivity when use the default value 8 of RG_USB20_SQTH, the HS receiver sensitivity test of HQA will fail, set it as 2 to fix up the issue. Signed-off-by: Chunfeng Yun Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-mt65xx-usb3.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/phy/phy-mt65xx-usb3.c b/drivers/phy/phy-mt65xx-usb3.c index e427c3b788ff3..2afbf9f36d832 100644 --- a/drivers/phy/phy-mt65xx-usb3.c +++ b/drivers/phy/phy-mt65xx-usb3.c @@ -49,6 +49,8 @@ #define PA6_RG_U2_ISO_EN BIT(31) #define PA6_RG_U2_BC11_SW_EN BIT(23) #define PA6_RG_U2_OTG_VBUSCMP_EN BIT(20) +#define PA6_RG_U2_SQTH GENMASK(3, 0) +#define PA6_RG_U2_SQTH_VAL(x) (0xf & (x)) #define U3P_U2PHYACR4 (SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0020) #define P2C_RG_USB20_GPIO_CTL BIT(9) @@ -165,9 +167,10 @@ static void phy_instance_init(struct mt65xx_u3phy *u3phy, writel(tmp, port_base + U3P_U2PHYDTM0); } - /* DP/DM BC1.1 path Disable */ tmp = readl(port_base + U3P_USBPHYACR6); - tmp &= ~PA6_RG_U2_BC11_SW_EN; + tmp &= ~PA6_RG_U2_BC11_SW_EN; /* DP/DM BC1.1 path Disable */ + tmp &= ~PA6_RG_U2_SQTH; + tmp |= PA6_RG_U2_SQTH_VAL(2); writel(tmp, port_base + U3P_USBPHYACR6); tmp = readl(port_base + U3P_U3PHYA_DA_REG0); -- GitLab From 75f072f9eab72e10a45886d84a9a762b1c65071d Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 4 Dec 2015 10:11:05 +0800 Subject: [PATCH 1732/2855] phy: phy-mt65xx-usb3: improve HS eye diagram calibrate HS slew rate and switch 100uA current to SSUSB to improve HS eye diagram of HQA test. Signed-off-by: Chunfeng Yun Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-mt65xx-usb3.c | 99 +++++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 3 deletions(-) diff --git a/drivers/phy/phy-mt65xx-usb3.c b/drivers/phy/phy-mt65xx-usb3.c index 2afbf9f36d832..c0e7b4b0cf5c6 100644 --- a/drivers/phy/phy-mt65xx-usb3.c +++ b/drivers/phy/phy-mt65xx-usb3.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ * relative to USB3_SIF2_BASE base address */ #define SSUSB_SIFSLV_SPLLC 0x0000 +#define SSUSB_SIFSLV_U2FREQ 0x0100 /* offsets of sub-segment in each port registers */ #define SSUSB_SIFSLV_U2PHY_COM_BASE 0x0000 @@ -41,6 +43,7 @@ #define PA2_RG_SIF_U2PLL_FORCE_EN BIT(18) #define U3P_USBPHYACR5 (SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0014) +#define PA5_RG_U2_HSTX_SRCAL_EN BIT(15) #define PA5_RG_U2_HSTX_SRCTRL GENMASK(14, 12) #define PA5_RG_U2_HSTX_SRCTRL_VAL(x) ((0x7 & (x)) << 12) #define PA5_RG_U2_HS_100U_U3_EN BIT(11) @@ -113,6 +116,24 @@ #define XC3_RG_U3_XTAL_RX_PWD BIT(9) #define XC3_RG_U3_FRC_XTAL_RX_PWD BIT(8) +#define U3P_U2FREQ_FMCR0 (SSUSB_SIFSLV_U2FREQ + 0x00) +#define P2F_RG_MONCLK_SEL GENMASK(27, 26) +#define P2F_RG_MONCLK_SEL_VAL(x) ((0x3 & (x)) << 26) +#define P2F_RG_FREQDET_EN BIT(24) +#define P2F_RG_CYCLECNT GENMASK(23, 0) +#define P2F_RG_CYCLECNT_VAL(x) ((P2F_RG_CYCLECNT) & (x)) + +#define U3P_U2FREQ_VALUE (SSUSB_SIFSLV_U2FREQ + 0x0c) + +#define U3P_U2FREQ_FMMONR1 (SSUSB_SIFSLV_U2FREQ + 0x10) +#define P2F_USB_FM_VALID BIT(0) +#define P2F_RG_FRCK_EN BIT(8) + +#define U3P_REF_CLK 26 /* MHZ */ +#define U3P_SLEW_RATE_COEF 28 +#define U3P_SR_COEF_DIVISOR 1000 +#define U3P_FM_DET_CYCLE_CNT 1024 + struct mt65xx_phy_instance { struct phy *phy; void __iomem *port_base; @@ -128,6 +149,77 @@ struct mt65xx_u3phy { int nphys; }; +static void hs_slew_rate_calibrate(struct mt65xx_u3phy *u3phy, + struct mt65xx_phy_instance *instance) +{ + void __iomem *sif_base = u3phy->sif_base; + int calibration_val; + int fm_out; + u32 tmp; + + /* enable USB ring oscillator */ + tmp = readl(instance->port_base + U3P_USBPHYACR5); + tmp |= PA5_RG_U2_HSTX_SRCAL_EN; + writel(tmp, instance->port_base + U3P_USBPHYACR5); + udelay(1); + + /*enable free run clock */ + tmp = readl(sif_base + U3P_U2FREQ_FMMONR1); + tmp |= P2F_RG_FRCK_EN; + writel(tmp, sif_base + U3P_U2FREQ_FMMONR1); + + /* set cycle count as 1024, and select u2 channel */ + tmp = readl(sif_base + U3P_U2FREQ_FMCR0); + tmp &= ~(P2F_RG_CYCLECNT | P2F_RG_MONCLK_SEL); + tmp |= P2F_RG_CYCLECNT_VAL(U3P_FM_DET_CYCLE_CNT); + tmp |= P2F_RG_MONCLK_SEL_VAL(instance->index); + writel(tmp, sif_base + U3P_U2FREQ_FMCR0); + + /* enable frequency meter */ + tmp = readl(sif_base + U3P_U2FREQ_FMCR0); + tmp |= P2F_RG_FREQDET_EN; + writel(tmp, sif_base + U3P_U2FREQ_FMCR0); + + /* ignore return value */ + readl_poll_timeout(sif_base + U3P_U2FREQ_FMMONR1, tmp, + (tmp & P2F_USB_FM_VALID), 10, 200); + + fm_out = readl(sif_base + U3P_U2FREQ_VALUE); + + /* disable frequency meter */ + tmp = readl(sif_base + U3P_U2FREQ_FMCR0); + tmp &= ~P2F_RG_FREQDET_EN; + writel(tmp, sif_base + U3P_U2FREQ_FMCR0); + + /*disable free run clock */ + tmp = readl(sif_base + U3P_U2FREQ_FMMONR1); + tmp &= ~P2F_RG_FRCK_EN; + writel(tmp, sif_base + U3P_U2FREQ_FMMONR1); + + if (fm_out) { + /* ( 1024 / FM_OUT ) x reference clock frequency x 0.028 */ + tmp = U3P_FM_DET_CYCLE_CNT * U3P_REF_CLK * U3P_SLEW_RATE_COEF; + tmp /= fm_out; + calibration_val = DIV_ROUND_CLOSEST(tmp, U3P_SR_COEF_DIVISOR); + } else { + /* if FM detection fail, set default value */ + calibration_val = 4; + } + dev_dbg(u3phy->dev, "phy:%d, fm_out:%d, calib:%d\n", + instance->index, fm_out, calibration_val); + + /* set HS slew rate */ + tmp = readl(instance->port_base + U3P_USBPHYACR5); + tmp &= ~PA5_RG_U2_HSTX_SRCTRL; + tmp |= PA5_RG_U2_HSTX_SRCTRL_VAL(calibration_val); + writel(tmp, instance->port_base + U3P_USBPHYACR5); + + /* disable USB ring oscillator */ + tmp = readl(instance->port_base + U3P_USBPHYACR5); + tmp &= ~PA5_RG_U2_HSTX_SRCAL_EN; + writel(tmp, instance->port_base + U3P_USBPHYACR5); +} + static void phy_instance_init(struct mt65xx_u3phy *u3phy, struct mt65xx_phy_instance *instance) { @@ -226,9 +318,9 @@ static void phy_instance_power_on(struct mt65xx_u3phy *u3phy, tmp |= XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD; writel(tmp, u3phy->sif_base + U3P_XTALCTL3); - /* [mt8173]disable Change 100uA current from SSUSB */ + /* [mt8173]switch 100uA current to SSUSB */ tmp = readl(port_base + U3P_USBPHYACR5); - tmp &= ~PA5_RG_U2_HS_100U_U3_EN; + tmp |= PA5_RG_U2_HS_100U_U3_EN; writel(tmp, port_base + U3P_USBPHYACR5); } @@ -273,7 +365,7 @@ static void phy_instance_power_off(struct mt65xx_u3phy *u3phy, writel(tmp, port_base + U3P_USBPHYACR6); if (!index) { - /* (also disable)Change 100uA current switch to USB2.0 */ + /* switch 100uA current back to USB2.0 */ tmp = readl(port_base + U3P_USBPHYACR5); tmp &= ~PA5_RG_U2_HS_100U_U3_EN; writel(tmp, port_base + U3P_USBPHYACR5); @@ -343,6 +435,7 @@ static int mt65xx_phy_power_on(struct phy *phy) struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent); phy_instance_power_on(u3phy, instance); + hs_slew_rate_calibrate(u3phy, instance); return 0; } -- GitLab From 68dbc2ce77bbe18a0475a497f4d6adde7c5d0b0c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 11 Dec 2015 16:32:17 +0100 Subject: [PATCH 1733/2855] phy-sun4i-usb: Use of_match_node to get model specific config data Use of_match_node instead of calling of_device_is_compatible a ton of times to get model specific config data. Signed-off-by: Hans de Goede Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-sun4i-usb.c | 121 +++++++++++++++++++++++------------- 1 file changed, 79 insertions(+), 42 deletions(-) diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c index b12964b70625f..35b1fa3b71fec 100644 --- a/drivers/phy/phy-sun4i-usb.c +++ b/drivers/phy/phy-sun4i-usb.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -88,12 +89,23 @@ #define DEBOUNCE_TIME msecs_to_jiffies(50) #define POLL_TIME msecs_to_jiffies(250) +enum sun4i_usb_phy_type { + sun4i_a10_phy, + sun8i_a33_phy, +}; + +struct sun4i_usb_phy_cfg { + int num_phys; + enum sun4i_usb_phy_type type; + u32 disc_thresh; + u8 phyctl_offset; + bool dedicated_clocks; +}; + struct sun4i_usb_phy_data { void __iomem *base; + const struct sun4i_usb_phy_cfg *cfg; struct mutex mutex; - int num_phys; - u32 disc_thresh; - bool has_a33_phyctl; struct sun4i_usb_phy { struct phy *phy; void __iomem *pmu; @@ -159,17 +171,14 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data, { struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy); u32 temp, usbc_bit = BIT(phy->index * 2); - void *phyctl; + void *phyctl = phy_data->base + phy_data->cfg->phyctl_offset; int i; mutex_lock(&phy_data->mutex); - if (phy_data->has_a33_phyctl) { - phyctl = phy_data->base + REG_PHYCTL_A33; + if (phy_data->cfg->type == sun8i_a33_phy) { /* A33 needs us to set phyctl to 0 explicitly */ writel(0, phyctl); - } else { - phyctl = phy_data->base + REG_PHYCTL_A10; } for (i = 0; i < len; i++) { @@ -249,7 +258,8 @@ static int sun4i_usb_phy_init(struct phy *_phy) sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5); /* Disconnect threshold adjustment */ - sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, data->disc_thresh, 2); + sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, + data->cfg->disc_thresh, 2); sun4i_usb_phy_passby(phy, 1); @@ -476,7 +486,7 @@ static struct phy *sun4i_usb_phy_xlate(struct device *dev, { struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); - if (args->args[0] >= data->num_phys) + if (args->args[0] >= data->cfg->num_phys) return ERR_PTR(-ENODEV); return data->phys[args->args[0]].phy; @@ -511,7 +521,6 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct phy_provider *phy_provider; - bool dedicated_clocks; struct resource *res; int i, ret; @@ -522,29 +531,9 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) mutex_init(&data->mutex); INIT_DELAYED_WORK(&data->detect, sun4i_usb_phy0_id_vbus_det_scan); dev_set_drvdata(dev, data); - - if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy") || - of_device_is_compatible(np, "allwinner,sun8i-a23-usb-phy") || - of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy")) - data->num_phys = 2; - else - data->num_phys = 3; - - if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy") || - of_device_is_compatible(np, "allwinner,sun7i-a20-usb-phy")) - data->disc_thresh = 2; - else - data->disc_thresh = 3; - - if (of_device_is_compatible(np, "allwinner,sun6i-a31-usb-phy") || - of_device_is_compatible(np, "allwinner,sun8i-a23-usb-phy") || - of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy")) - dedicated_clocks = true; - else - dedicated_clocks = false; - - if (of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy")) - data->has_a33_phyctl = true; + data->cfg = of_device_get_match_data(dev); + if (!data->cfg) + return -EINVAL; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_ctrl"); data->base = devm_ioremap_resource(dev, res); @@ -590,7 +579,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) } } - for (i = 0; i < data->num_phys; i++) { + for (i = 0; i < data->cfg->num_phys; i++) { struct sun4i_usb_phy *phy = data->phys + i; char name[16]; @@ -602,7 +591,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) phy->vbus = NULL; } - if (dedicated_clocks) + if (data->cfg->dedicated_clocks) snprintf(name, sizeof(name), "usb%d_phy", i); else strlcpy(name, "usb_phy", sizeof(name)); @@ -689,13 +678,61 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) return 0; } +static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = { + .num_phys = 3, + .type = sun4i_a10_phy, + .disc_thresh = 3, + .phyctl_offset = REG_PHYCTL_A10, + .dedicated_clocks = false, +}; + +static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = { + .num_phys = 2, + .type = sun4i_a10_phy, + .disc_thresh = 2, + .phyctl_offset = REG_PHYCTL_A10, + .dedicated_clocks = false, +}; + +static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = { + .num_phys = 3, + .type = sun4i_a10_phy, + .disc_thresh = 3, + .phyctl_offset = REG_PHYCTL_A10, + .dedicated_clocks = true, +}; + +static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = { + .num_phys = 3, + .type = sun4i_a10_phy, + .disc_thresh = 2, + .phyctl_offset = REG_PHYCTL_A10, + .dedicated_clocks = false, +}; + +static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = { + .num_phys = 2, + .type = sun4i_a10_phy, + .disc_thresh = 3, + .phyctl_offset = REG_PHYCTL_A10, + .dedicated_clocks = true, +}; + +static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = { + .num_phys = 2, + .type = sun8i_a33_phy, + .disc_thresh = 3, + .phyctl_offset = REG_PHYCTL_A33, + .dedicated_clocks = true, +}; + static const struct of_device_id sun4i_usb_phy_of_match[] = { - { .compatible = "allwinner,sun4i-a10-usb-phy" }, - { .compatible = "allwinner,sun5i-a13-usb-phy" }, - { .compatible = "allwinner,sun6i-a31-usb-phy" }, - { .compatible = "allwinner,sun7i-a20-usb-phy" }, - { .compatible = "allwinner,sun8i-a23-usb-phy" }, - { .compatible = "allwinner,sun8i-a33-usb-phy" }, + { .compatible = "allwinner,sun4i-a10-usb-phy", .data = &sun4i_a10_cfg }, + { .compatible = "allwinner,sun5i-a13-usb-phy", .data = &sun5i_a13_cfg }, + { .compatible = "allwinner,sun6i-a31-usb-phy", .data = &sun6i_a31_cfg }, + { .compatible = "allwinner,sun7i-a20-usb-phy", .data = &sun7i_a20_cfg }, + { .compatible = "allwinner,sun8i-a23-usb-phy", .data = &sun8i_a23_cfg }, + { .compatible = "allwinner,sun8i-a33-usb-phy", .data = &sun8i_a33_cfg }, { }, }; MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match); -- GitLab From 626a630e003c10c800a816cb994b3f9e505a88a9 Mon Sep 17 00:00:00 2001 From: Reinder de Haan Date: Fri, 11 Dec 2015 16:32:18 +0100 Subject: [PATCH 1734/2855] phy-sun4i-usb: Add support for the host usb-phys found on the H3 SoC Note this commit only adds support for phys 1-3, phy 0, the otg phy, is not yet (fully) supported after this commit. Signed-off-by: Reinder de Haan Signed-off-by: Hans de Goede Acked-by: Rob Herring Signed-off-by: Kishon Vijay Abraham I --- .../devicetree/bindings/phy/sun4i-usb-phy.txt | 1 + drivers/phy/phy-sun4i-usb.c | 41 +++++++++++++++---- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt index 0cebf74545176..95736d77fbb71 100644 --- a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt @@ -9,6 +9,7 @@ Required properties: * allwinner,sun7i-a20-usb-phy * allwinner,sun8i-a23-usb-phy * allwinner,sun8i-a33-usb-phy + * allwinner,sun8i-h3-usb-phy - reg : a list of offset + length pairs - reg-names : * "phy_ctrl" diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c index 35b1fa3b71fec..bae54f7a1f487 100644 --- a/drivers/phy/phy-sun4i-usb.c +++ b/drivers/phy/phy-sun4i-usb.c @@ -47,6 +47,9 @@ #define REG_PHYBIST 0x08 #define REG_PHYTUNE 0x0c #define REG_PHYCTL_A33 0x10 +#define REG_PHY_UNK_H3 0x20 + +#define REG_PMU_UNK_H3 0x10 #define PHYCTL_DATA BIT(7) @@ -80,7 +83,7 @@ #define PHY_DISCON_TH_SEL 0x2a #define PHY_SQUELCH_DETECT 0x3c -#define MAX_PHYS 3 +#define MAX_PHYS 4 /* * Note do not raise the debounce time, we must report Vusb high within 100ms @@ -92,6 +95,7 @@ enum sun4i_usb_phy_type { sun4i_a10_phy, sun8i_a33_phy, + sun8i_h3_phy, }; struct sun4i_usb_phy_cfg { @@ -239,6 +243,7 @@ static int sun4i_usb_phy_init(struct phy *_phy) struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); int ret; + u32 val; ret = clk_prepare_enable(phy->clk); if (ret) @@ -250,16 +255,26 @@ static int sun4i_usb_phy_init(struct phy *_phy) return ret; } - /* Enable USB 45 Ohm resistor calibration */ - if (phy->index == 0) - sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1); + if (data->cfg->type == sun8i_h3_phy) { + if (phy->index == 0) { + val = readl(data->base + REG_PHY_UNK_H3); + writel(val & ~1, data->base + REG_PHY_UNK_H3); + } + + val = readl(phy->pmu + REG_PMU_UNK_H3); + writel(val & ~2, phy->pmu + REG_PMU_UNK_H3); + } else { + /* Enable USB 45 Ohm resistor calibration */ + if (phy->index == 0) + sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1); - /* Adjust PHY's magnitude and rate */ - sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5); + /* Adjust PHY's magnitude and rate */ + sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5); - /* Disconnect threshold adjustment */ - sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, - data->cfg->disc_thresh, 2); + /* Disconnect threshold adjustment */ + sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, + data->cfg->disc_thresh, 2); + } sun4i_usb_phy_passby(phy, 1); @@ -726,6 +741,13 @@ static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = { .dedicated_clocks = true, }; +static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = { + .num_phys = 4, + .type = sun8i_h3_phy, + .disc_thresh = 3, + .dedicated_clocks = true, +}; + static const struct of_device_id sun4i_usb_phy_of_match[] = { { .compatible = "allwinner,sun4i-a10-usb-phy", .data = &sun4i_a10_cfg }, { .compatible = "allwinner,sun5i-a13-usb-phy", .data = &sun5i_a13_cfg }, @@ -733,6 +755,7 @@ static const struct of_device_id sun4i_usb_phy_of_match[] = { { .compatible = "allwinner,sun7i-a20-usb-phy", .data = &sun7i_a20_cfg }, { .compatible = "allwinner,sun8i-a23-usb-phy", .data = &sun8i_a23_cfg }, { .compatible = "allwinner,sun8i-a33-usb-phy", .data = &sun8i_a33_cfg }, + { .compatible = "allwinner,sun8i-h3-usb-phy", .data = &sun8i_h3_cfg }, { }, }; MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match); -- GitLab From 30e9a0b2147c8405109ad98ae670829dd92e4516 Mon Sep 17 00:00:00 2001 From: Zhangfei Gao Date: Mon, 23 Nov 2015 11:46:27 +0800 Subject: [PATCH 1735/2855] phy: add phy-hi6220-usb Support hi6220 use phy for HiKey board Acked-by: Rob Herring Signed-off-by: Zhangfei Gao Signed-off-by: Kishon Vijay Abraham I --- .../bindings/phy/phy-hi6220-usb.txt | 16 ++ drivers/phy/Kconfig | 9 + drivers/phy/Makefile | 1 + drivers/phy/phy-hi6220-usb.c | 168 ++++++++++++++++++ 4 files changed, 194 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/phy-hi6220-usb.txt create mode 100644 drivers/phy/phy-hi6220-usb.c diff --git a/Documentation/devicetree/bindings/phy/phy-hi6220-usb.txt b/Documentation/devicetree/bindings/phy/phy-hi6220-usb.txt new file mode 100644 index 0000000000000..f17a56e2152f0 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/phy-hi6220-usb.txt @@ -0,0 +1,16 @@ +Hisilicon hi6220 usb PHY +----------------------- + +Required properties: +- compatible: should be "hisilicon,hi6220-usb-phy" +- #phy-cells: must be 0 +- hisilicon,peripheral-syscon: phandle of syscon used to control phy. +Refer to phy/phy-bindings.txt for the generic PHY binding properties + +Example: + usb_phy: usbphy { + compatible = "hisilicon,hi6220-usb-phy"; + #phy-cells = <0>; + phy-supply = <&fixed_5v_hub>; + hisilicon,peripheral-syscon = <&sys_ctrl>; + }; diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index f90b7660dd3ec..90eec60d7ba54 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -222,6 +222,15 @@ config PHY_MT65XX_USB3 for mt65xx SoCs. it supports two usb2.0 ports and one usb3.0 port. +config PHY_HI6220_USB + tristate "hi6220 USB PHY support" + select GENERIC_PHY + select MFD_SYSCON + help + Enable this to support the HISILICON HI6220 USB PHY. + + To compile this driver as a module, choose M here. + config PHY_SUN4I_USB tristate "Allwinner sunxi SoC USB PHY driver" depends on ARCH_SUNXI && HAS_IOMEM && OF diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 91d7a62c6794d..c80f09df3bb85 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_TI_PIPE3) += phy-ti-pipe3.o obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o obj-$(CONFIG_PHY_HIX5HD2_SATA) += phy-hix5hd2-sata.o +obj-$(CONFIG_PHY_HI6220_USB) += phy-hi6220-usb.o obj-$(CONFIG_PHY_MT65XX_USB3) += phy-mt65xx-usb3.o obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o obj-$(CONFIG_PHY_SUN9I_USB) += phy-sun9i-usb.o diff --git a/drivers/phy/phy-hi6220-usb.c b/drivers/phy/phy-hi6220-usb.c new file mode 100644 index 0000000000000..b2141cbd4cf6c --- /dev/null +++ b/drivers/phy/phy-hi6220-usb.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2015 Linaro Ltd. + * Copyright (c) 2015 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include + +#define SC_PERIPH_CTRL4 0x00c + +#define CTRL4_PICO_SIDDQ BIT(6) +#define CTRL4_PICO_OGDISABLE BIT(8) +#define CTRL4_PICO_VBUSVLDEXT BIT(10) +#define CTRL4_PICO_VBUSVLDEXTSEL BIT(11) +#define CTRL4_OTG_PHY_SEL BIT(21) + +#define SC_PERIPH_CTRL5 0x010 + +#define CTRL5_USBOTG_RES_SEL BIT(3) +#define CTRL5_PICOPHY_ACAENB BIT(4) +#define CTRL5_PICOPHY_BC_MODE BIT(5) +#define CTRL5_PICOPHY_CHRGSEL BIT(6) +#define CTRL5_PICOPHY_VDATSRCEND BIT(7) +#define CTRL5_PICOPHY_VDATDETENB BIT(8) +#define CTRL5_PICOPHY_DCDENB BIT(9) +#define CTRL5_PICOPHY_IDDIG BIT(10) + +#define SC_PERIPH_CTRL8 0x018 +#define SC_PERIPH_RSTEN0 0x300 +#define SC_PERIPH_RSTDIS0 0x304 + +#define RST0_USBOTG_BUS BIT(4) +#define RST0_POR_PICOPHY BIT(5) +#define RST0_USBOTG BIT(6) +#define RST0_USBOTG_32K BIT(7) + +#define EYE_PATTERN_PARA 0x7053348c + +struct hi6220_priv { + struct regmap *reg; + struct device *dev; +}; + +static void hi6220_phy_init(struct hi6220_priv *priv) +{ + struct regmap *reg = priv->reg; + u32 val, mask; + + val = RST0_USBOTG_BUS | RST0_POR_PICOPHY | + RST0_USBOTG | RST0_USBOTG_32K; + mask = val; + regmap_update_bits(reg, SC_PERIPH_RSTEN0, mask, val); + regmap_update_bits(reg, SC_PERIPH_RSTDIS0, mask, val); +} + +static int hi6220_phy_setup(struct hi6220_priv *priv, bool on) +{ + struct regmap *reg = priv->reg; + u32 val, mask; + int ret; + + if (on) { + val = CTRL5_USBOTG_RES_SEL | CTRL5_PICOPHY_ACAENB; + mask = val | CTRL5_PICOPHY_BC_MODE; + ret = regmap_update_bits(reg, SC_PERIPH_CTRL5, mask, val); + if (ret) + goto out; + + val = CTRL4_PICO_VBUSVLDEXT | CTRL4_PICO_VBUSVLDEXTSEL | + CTRL4_OTG_PHY_SEL; + mask = val | CTRL4_PICO_SIDDQ | CTRL4_PICO_OGDISABLE; + ret = regmap_update_bits(reg, SC_PERIPH_CTRL4, mask, val); + if (ret) + goto out; + + ret = regmap_write(reg, SC_PERIPH_CTRL8, EYE_PATTERN_PARA); + if (ret) + goto out; + } else { + val = CTRL4_PICO_SIDDQ; + mask = val; + ret = regmap_update_bits(reg, SC_PERIPH_CTRL4, mask, val); + if (ret) + goto out; + } + + return 0; +out: + dev_err(priv->dev, "failed to setup phy ret: %d\n", ret); + return ret; +} + +static int hi6220_phy_start(struct phy *phy) +{ + struct hi6220_priv *priv = phy_get_drvdata(phy); + + return hi6220_phy_setup(priv, true); +} + +static int hi6220_phy_exit(struct phy *phy) +{ + struct hi6220_priv *priv = phy_get_drvdata(phy); + + return hi6220_phy_setup(priv, false); +} + +static struct phy_ops hi6220_phy_ops = { + .init = hi6220_phy_start, + .exit = hi6220_phy_exit, + .owner = THIS_MODULE, +}; + +static int hi6220_phy_probe(struct platform_device *pdev) +{ + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + struct phy *phy; + struct hi6220_priv *priv; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + priv->reg = syscon_regmap_lookup_by_phandle(dev->of_node, + "hisilicon,peripheral-syscon"); + if (IS_ERR(priv->reg)) { + dev_err(dev, "no hisilicon,peripheral-syscon\n"); + return PTR_ERR(priv->reg); + } + + hi6220_phy_init(priv); + + phy = devm_phy_create(dev, NULL, &hi6220_phy_ops); + if (IS_ERR(phy)) + return PTR_ERR(phy); + + phy_set_drvdata(phy, priv); + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + return PTR_ERR_OR_ZERO(phy_provider); +} + +static const struct of_device_id hi6220_phy_of_match[] = { + {.compatible = "hisilicon,hi6220-usb-phy",}, + { }, +}; +MODULE_DEVICE_TABLE(of, hi6220_phy_of_match); + +static struct platform_driver hi6220_phy_driver = { + .probe = hi6220_phy_probe, + .driver = { + .name = "hi6220-usb-phy", + .of_match_table = hi6220_phy_of_match, + } +}; +module_platform_driver(hi6220_phy_driver); + +MODULE_DESCRIPTION("HISILICON HI6220 USB PHY driver"); +MODULE_ALIAS("platform:hi6220-usb-phy"); +MODULE_LICENSE("GPL"); -- GitLab From 75d390fecf9e69eebca7f15de40d761e33fcfd7b Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 19 Nov 2015 22:22:22 +0100 Subject: [PATCH 1736/2855] phy: rockchip-usb: fix clock get-put mismatch Currently the phy driver only gets the optional clock reference but never puts it again, neither during error handling nor on remove. Fix that by moving the clk_put to a devm-action that gets called at the right time when all other devm actions are done. Signed-off-by: Heiko Stuebner Reviewed-by: Douglas Anderson Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-rockchip-usb.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c index 62c43c4351943..e941444072bad 100644 --- a/drivers/phy/phy-rockchip-usb.c +++ b/drivers/phy/phy-rockchip-usb.c @@ -90,6 +90,14 @@ static const struct phy_ops ops = { .owner = THIS_MODULE, }; +static void rockchip_usb_phy_action(void *data) +{ + struct rockchip_usb_phy *rk_phy = data; + + if (rk_phy->clk) + clk_put(rk_phy->clk); +} + static int rockchip_usb_phy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -123,6 +131,10 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev) rk_phy->reg_offset = reg_offset; rk_phy->reg_base = grf; + err = devm_add_action(dev, rockchip_usb_phy_action, rk_phy); + if (err) + return err; + rk_phy->clk = of_clk_get_by_name(child, "phyclk"); if (IS_ERR(rk_phy->clk)) rk_phy->clk = NULL; -- GitLab From 5fdbb97dec0ca6106c5595c2db667a7957ad8c0f Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 19 Nov 2015 22:22:23 +0100 Subject: [PATCH 1737/2855] phy: rockchip-usb: introduce a common data-struct for the device This introduces a common struct that holds data belonging to the umbrella device that contains all the phys and that we want to use later. Signed-off-by: Heiko Stuebner Reviewed-by: Douglas Anderson Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-rockchip-usb.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c index e941444072bad..2b4802a7497d8 100644 --- a/drivers/phy/phy-rockchip-usb.c +++ b/drivers/phy/phy-rockchip-usb.c @@ -36,9 +36,14 @@ #define SIDDQ_ON BIT(13) #define SIDDQ_OFF (0 << 13) +struct rockchip_usb_phy_base { + struct device *dev; + struct regmap *reg_base; +}; + struct rockchip_usb_phy { + struct rockchip_usb_phy_base *base; unsigned int reg_offset; - struct regmap *reg_base; struct clk *clk; struct phy *phy; }; @@ -46,7 +51,7 @@ struct rockchip_usb_phy { static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy, bool siddq) { - return regmap_write(phy->reg_base, phy->reg_offset, + return regmap_write(phy->base->reg_base, phy->reg_offset, SIDDQ_WRITE_ENA | (siddq ? SIDDQ_ON : SIDDQ_OFF)); } @@ -101,17 +106,23 @@ static void rockchip_usb_phy_action(void *data) static int rockchip_usb_phy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct rockchip_usb_phy_base *phy_base; struct rockchip_usb_phy *rk_phy; struct phy_provider *phy_provider; struct device_node *child; - struct regmap *grf; unsigned int reg_offset; int err; - grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); - if (IS_ERR(grf)) { + phy_base = devm_kzalloc(dev, sizeof(*phy_base), GFP_KERNEL); + if (!phy_base) + return -ENOMEM; + + phy_base->dev = dev; + phy_base->reg_base = syscon_regmap_lookup_by_phandle(dev->of_node, + "rockchip,grf"); + if (IS_ERR(phy_base->reg_base)) { dev_err(&pdev->dev, "Missing rockchip,grf property\n"); - return PTR_ERR(grf); + return PTR_ERR(phy_base->reg_base); } for_each_available_child_of_node(dev->of_node, child) { @@ -121,6 +132,8 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev) goto put_child; } + rk_phy->base = phy_base; + if (of_property_read_u32(child, "reg", ®_offset)) { dev_err(dev, "missing reg property in node %s\n", child->name); @@ -129,7 +142,6 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev) } rk_phy->reg_offset = reg_offset; - rk_phy->reg_base = grf; err = devm_add_action(dev, rockchip_usb_phy_action, rk_phy); if (err) -- GitLab From 97dd9101091bb13b1ca3fe42edacf2bd7cf10924 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 19 Nov 2015 22:22:24 +0100 Subject: [PATCH 1738/2855] phy: rockchip-usb: move per-phy init into a separate function This unclutters the loop in probe a lot and makes current (and future) error handling easier to read. Signed-off-by: Heiko Stuebner Reviewed-by: Douglas Anderson Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-rockchip-usb.c | 83 ++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 40 deletions(-) diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c index 2b4802a7497d8..ff3ac3379c611 100644 --- a/drivers/phy/phy-rockchip-usb.c +++ b/drivers/phy/phy-rockchip-usb.c @@ -103,14 +103,52 @@ static void rockchip_usb_phy_action(void *data) clk_put(rk_phy->clk); } +static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base, + struct device_node *child) +{ + struct rockchip_usb_phy *rk_phy; + unsigned int reg_offset; + int err; + + rk_phy = devm_kzalloc(base->dev, sizeof(*rk_phy), GFP_KERNEL); + if (!rk_phy) + return -ENOMEM; + + rk_phy->base = base; + + if (of_property_read_u32(child, "reg", ®_offset)) { + dev_err(base->dev, "missing reg property in node %s\n", + child->name); + return -EINVAL; + } + + rk_phy->reg_offset = reg_offset; + + err = devm_add_action(base->dev, rockchip_usb_phy_action, rk_phy); + if (err) + return err; + + rk_phy->clk = of_clk_get_by_name(child, "phyclk"); + if (IS_ERR(rk_phy->clk)) + rk_phy->clk = NULL; + + rk_phy->phy = devm_phy_create(base->dev, child, &ops); + if (IS_ERR(rk_phy->phy)) { + dev_err(base->dev, "failed to create PHY\n"); + return PTR_ERR(rk_phy->phy); + } + phy_set_drvdata(rk_phy->phy, rk_phy); + + /* only power up usb phy when it use, so disable it when init*/ + return rockchip_usb_phy_power(rk_phy, 1); +} + static int rockchip_usb_phy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rockchip_usb_phy_base *phy_base; - struct rockchip_usb_phy *rk_phy; struct phy_provider *phy_provider; struct device_node *child; - unsigned int reg_offset; int err; phy_base = devm_kzalloc(dev, sizeof(*phy_base), GFP_KERNEL); @@ -126,50 +164,15 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev) } for_each_available_child_of_node(dev->of_node, child) { - rk_phy = devm_kzalloc(dev, sizeof(*rk_phy), GFP_KERNEL); - if (!rk_phy) { - err = -ENOMEM; - goto put_child; - } - - rk_phy->base = phy_base; - - if (of_property_read_u32(child, "reg", ®_offset)) { - dev_err(dev, "missing reg property in node %s\n", - child->name); - err = -EINVAL; - goto put_child; - } - - rk_phy->reg_offset = reg_offset; - - err = devm_add_action(dev, rockchip_usb_phy_action, rk_phy); - if (err) + err = rockchip_usb_phy_init(phy_base, child); + if (err) { + of_node_put(child); return err; - - rk_phy->clk = of_clk_get_by_name(child, "phyclk"); - if (IS_ERR(rk_phy->clk)) - rk_phy->clk = NULL; - - rk_phy->phy = devm_phy_create(dev, child, &ops); - if (IS_ERR(rk_phy->phy)) { - dev_err(dev, "failed to create PHY\n"); - err = PTR_ERR(rk_phy->phy); - goto put_child; } - phy_set_drvdata(rk_phy->phy, rk_phy); - - /* only power up usb phy when it use, so disable it when init*/ - err = rockchip_usb_phy_power(rk_phy, 1); - if (err) - goto put_child; } phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); return PTR_ERR_OR_ZERO(phy_provider); -put_child: - of_node_put(child); - return err; } static const struct of_device_id rockchip_usb_phy_dt_ids[] = { -- GitLab From c2bfc3b88813ab8711317a19f5c9cd74aeaf536c Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 19 Nov 2015 22:22:25 +0100 Subject: [PATCH 1739/2855] phy: rockchip-usb: add compatible values for rk3066a and rk3188 We need custom handling for these two socs in the driver shortly, so add the necessary compatible values to binding and driver. Signed-off-by: Heiko Stuebner Signed-off-by: Kishon Vijay Abraham I --- Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt | 5 ++++- drivers/phy/phy-rockchip-usb.c | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt index 826454ac43bb6..9b37242fb8d3e 100644 --- a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt @@ -1,7 +1,10 @@ ROCKCHIP USB2 PHY Required properties: - - compatible: rockchip,rk3288-usb-phy + - compatible: matching the soc type, one of + "rockchip,rk3066a-usb-phy" + "rockchip,rk3188-usb-phy" + "rockchip,rk3288-usb-phy" - rockchip,grf : phandle to the syscon managing the "general register files" - #address-cells: should be 1 diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c index ff3ac3379c611..16cd533b21f0a 100644 --- a/drivers/phy/phy-rockchip-usb.c +++ b/drivers/phy/phy-rockchip-usb.c @@ -176,6 +176,8 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev) } static const struct of_device_id rockchip_usb_phy_dt_ids[] = { + { .compatible = "rockchip,rk3066a-usb-phy" }, + { .compatible = "rockchip,rk3188-usb-phy" }, { .compatible = "rockchip,rk3288-usb-phy" }, {} }; -- GitLab From b74fe7c7617fd267c10d53e525984df81a5f317f Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 19 Nov 2015 22:22:26 +0100 Subject: [PATCH 1740/2855] phy: rockchip-usb: expose the phy-internal PLLs The USB phys on Rockchip SoCs contain their own internal PLLs to create the 480MHz needed. Additionally this PLL output is also fed back into the core clock-controller as possible source for clocks like the GPU or others. Until now this was modelled incorrectly with a "virtual" factor clock in the clock controller. The one big caveat is that if we turn off the usb phy via the siddq signal, all analog components get turned off, including the PLLs. It is therefore possible that a source clock gets disabled without the clock driver ever knowing, possibly making the system hang. Therefore register the phy-plls as real clocks that the clock driver can then reference again normally, making the clock hirarchy finally reflect the actual hardware. The phy-ops get converted to simply turning that new clock on and off which in turn controls the siddq signal of the phy. Through this the driver gains handling for platform-specific data, to handle the phy->clock name association. Signed-off-by: Heiko Stuebner Reviewed-by: Douglas Anderson Signed-off-by: Kishon Vijay Abraham I --- .../bindings/phy/rockchip-usb-phy.txt | 1 + drivers/phy/phy-rockchip-usb.c | 188 +++++++++++++++--- 2 files changed, 162 insertions(+), 27 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt index 9b37242fb8d3e..68498d5603540 100644 --- a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt @@ -24,6 +24,7 @@ required properties: Optional Properties: - clocks : phandle + clock specifier for the phy clocks - clock-names: string, clock name, must be "phyclk" +- #clock-cells: for users of the phy-pll, should be 0 Example: diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c index 16cd533b21f0a..33a80eba1cb44 100644 --- a/drivers/phy/phy-rockchip-usb.c +++ b/drivers/phy/phy-rockchip-usb.c @@ -15,12 +15,14 @@ */ #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -36,15 +38,28 @@ #define SIDDQ_ON BIT(13) #define SIDDQ_OFF (0 << 13) +struct rockchip_usb_phys { + int reg; + const char *pll_name; +}; + +struct rockchip_usb_phy_pdata { + struct rockchip_usb_phys *phys; +}; + struct rockchip_usb_phy_base { struct device *dev; struct regmap *reg_base; + const struct rockchip_usb_phy_pdata *pdata; }; struct rockchip_usb_phy { struct rockchip_usb_phy_base *base; + struct device_node *np; unsigned int reg_offset; struct clk *clk; + struct clk *clk480m; + struct clk_hw clk480m_hw; struct phy *phy; }; @@ -55,17 +70,59 @@ static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy, SIDDQ_WRITE_ENA | (siddq ? SIDDQ_ON : SIDDQ_OFF)); } -static int rockchip_usb_phy_power_off(struct phy *_phy) +static unsigned long rockchip_usb_phy480m_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) { - struct rockchip_usb_phy *phy = phy_get_drvdata(_phy); - int ret = 0; + return 480000000; +} + +static void rockchip_usb_phy480m_disable(struct clk_hw *hw) +{ + struct rockchip_usb_phy *phy = container_of(hw, + struct rockchip_usb_phy, + clk480m_hw); /* Power down usb phy analog blocks by set siddq 1 */ - ret = rockchip_usb_phy_power(phy, 1); - if (ret) + rockchip_usb_phy_power(phy, 1); +} + +static int rockchip_usb_phy480m_enable(struct clk_hw *hw) +{ + struct rockchip_usb_phy *phy = container_of(hw, + struct rockchip_usb_phy, + clk480m_hw); + + /* Power up usb phy analog blocks by set siddq 0 */ + return rockchip_usb_phy_power(phy, 0); +} + +static int rockchip_usb_phy480m_is_enabled(struct clk_hw *hw) +{ + struct rockchip_usb_phy *phy = container_of(hw, + struct rockchip_usb_phy, + clk480m_hw); + int ret; + u32 val; + + ret = regmap_read(phy->base->reg_base, phy->reg_offset, &val); + if (ret < 0) return ret; - clk_disable_unprepare(phy->clk); + return (val & SIDDQ_ON) ? 0 : 1; +} + +static const struct clk_ops rockchip_usb_phy480m_ops = { + .enable = rockchip_usb_phy480m_enable, + .disable = rockchip_usb_phy480m_disable, + .is_enabled = rockchip_usb_phy480m_is_enabled, + .recalc_rate = rockchip_usb_phy480m_recalc_rate, +}; + +static int rockchip_usb_phy_power_off(struct phy *_phy) +{ + struct rockchip_usb_phy *phy = phy_get_drvdata(_phy); + + clk_disable_unprepare(phy->clk480m); return 0; } @@ -73,20 +130,8 @@ static int rockchip_usb_phy_power_off(struct phy *_phy) static int rockchip_usb_phy_power_on(struct phy *_phy) { struct rockchip_usb_phy *phy = phy_get_drvdata(_phy); - int ret = 0; - ret = clk_prepare_enable(phy->clk); - if (ret) - return ret; - - /* Power up usb phy analog blocks by set siddq 0 */ - ret = rockchip_usb_phy_power(phy, 0); - if (ret) { - clk_disable_unprepare(phy->clk); - return ret; - } - - return 0; + return clk_prepare_enable(phy->clk480m); } static const struct phy_ops ops = { @@ -99,6 +144,9 @@ static void rockchip_usb_phy_action(void *data) { struct rockchip_usb_phy *rk_phy = data; + of_clk_del_provider(rk_phy->np); + clk_unregister(rk_phy->clk480m); + if (rk_phy->clk) clk_put(rk_phy->clk); } @@ -108,13 +156,16 @@ static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base, { struct rockchip_usb_phy *rk_phy; unsigned int reg_offset; - int err; + const char *clk_name; + struct clk_init_data init; + int err, i; rk_phy = devm_kzalloc(base->dev, sizeof(*rk_phy), GFP_KERNEL); if (!rk_phy) return -ENOMEM; rk_phy->base = base; + rk_phy->np = child; if (of_property_read_u32(child, "reg", ®_offset)) { dev_err(base->dev, "missing reg property in node %s\n", @@ -124,14 +175,54 @@ static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base, rk_phy->reg_offset = reg_offset; - err = devm_add_action(base->dev, rockchip_usb_phy_action, rk_phy); - if (err) - return err; - rk_phy->clk = of_clk_get_by_name(child, "phyclk"); if (IS_ERR(rk_phy->clk)) rk_phy->clk = NULL; + i = 0; + init.name = NULL; + while (base->pdata->phys[i].reg) { + if (base->pdata->phys[i].reg == reg_offset) { + init.name = base->pdata->phys[i].pll_name; + break; + } + i++; + } + + if (!init.name) { + dev_err(base->dev, "phy data not found\n"); + return -EINVAL; + } + + if (rk_phy->clk) { + clk_name = __clk_get_name(rk_phy->clk); + init.flags = 0; + init.parent_names = &clk_name; + init.num_parents = 1; + } else { + init.flags = CLK_IS_ROOT; + init.parent_names = NULL; + init.num_parents = 0; + } + + init.ops = &rockchip_usb_phy480m_ops; + rk_phy->clk480m_hw.init = &init; + + rk_phy->clk480m = clk_register(base->dev, &rk_phy->clk480m_hw); + if (IS_ERR(rk_phy->clk480m)) { + err = PTR_ERR(rk_phy->clk480m); + goto err_clk; + } + + err = of_clk_add_provider(child, of_clk_src_simple_get, + rk_phy->clk480m); + if (err < 0) + goto err_clk_prov; + + err = devm_add_action(base->dev, rockchip_usb_phy_action, rk_phy); + if (err) + goto err_devm_action; + rk_phy->phy = devm_phy_create(base->dev, child, &ops); if (IS_ERR(rk_phy->phy)) { dev_err(base->dev, "failed to create PHY\n"); @@ -141,13 +232,48 @@ static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base, /* only power up usb phy when it use, so disable it when init*/ return rockchip_usb_phy_power(rk_phy, 1); + +err_devm_action: + of_clk_del_provider(child); +err_clk_prov: + clk_unregister(rk_phy->clk480m); +err_clk: + if (rk_phy->clk) + clk_put(rk_phy->clk); + return err; } +static const struct rockchip_usb_phy_pdata rk3066a_pdata = { + .phys = (struct rockchip_usb_phys[]){ + { .reg = 0x17c, .pll_name = "sclk_otgphy0_480m" }, + { .reg = 0x188, .pll_name = "sclk_otgphy1_480m" }, + { /* sentinel */ } + }, +}; + +static const struct rockchip_usb_phy_pdata rk3188_pdata = { + .phys = (struct rockchip_usb_phys[]){ + { .reg = 0x10c, .pll_name = "sclk_otgphy0_480m" }, + { .reg = 0x11c, .pll_name = "sclk_otgphy1_480m" }, + { /* sentinel */ } + }, +}; + +static const struct rockchip_usb_phy_pdata rk3288_pdata = { + .phys = (struct rockchip_usb_phys[]){ + { .reg = 0x320, .pll_name = "sclk_otgphy0_480m" }, + { .reg = 0x334, .pll_name = "sclk_otgphy1_480m" }, + { .reg = 0x348, .pll_name = "sclk_otgphy2_480m" }, + { /* sentinel */ } + }, +}; + static int rockchip_usb_phy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rockchip_usb_phy_base *phy_base; struct phy_provider *phy_provider; + const struct of_device_id *match; struct device_node *child; int err; @@ -155,6 +281,14 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev) if (!phy_base) return -ENOMEM; + match = of_match_device(dev->driver->of_match_table, dev); + if (!match || !match->data) { + dev_err(dev, "missing phy data\n"); + return -EINVAL; + } + + phy_base->pdata = match->data; + phy_base->dev = dev; phy_base->reg_base = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); @@ -176,9 +310,9 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev) } static const struct of_device_id rockchip_usb_phy_dt_ids[] = { - { .compatible = "rockchip,rk3066a-usb-phy" }, - { .compatible = "rockchip,rk3188-usb-phy" }, - { .compatible = "rockchip,rk3288-usb-phy" }, + { .compatible = "rockchip,rk3066a-usb-phy", .data = &rk3066a_pdata }, + { .compatible = "rockchip,rk3188-usb-phy", .data = &rk3188_pdata }, + { .compatible = "rockchip,rk3288-usb-phy", .data = &rk3288_pdata }, {} }; -- GitLab From 1dc3a8582c3b99bd88b47f7aafd07ceb934024dc Mon Sep 17 00:00:00 2001 From: Jaedon Shin Date: Thu, 26 Nov 2015 11:56:33 +0900 Subject: [PATCH 1741/2855] phy: phy_brcmstb_sata: remove duplicate definitions Remove duplicate definitions. Signed-off-by: Jaedon Shin Acked-by: Florian Fainelli Acked-by: Brian Norris Tested-by: Florian Fainelli Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-brcmstb-sata.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/phy/phy-brcmstb-sata.c b/drivers/phy/phy-brcmstb-sata.c index cd9dba8205668..ddb9b9e8270d7 100644 --- a/drivers/phy/phy-brcmstb-sata.c +++ b/drivers/phy/phy-brcmstb-sata.c @@ -26,8 +26,6 @@ #define SATA_MDIO_BANK_OFFSET 0x23c #define SATA_MDIO_REG_OFFSET(ofs) ((ofs) * 4) -#define SATA_MDIO_REG_SPACE_SIZE 0x1000 -#define SATA_MDIO_REG_LENGTH 0x1f00 #define MAX_PORTS 2 -- GitLab From 810c6f169fd1d8a37df884c0942727863f00319a Mon Sep 17 00:00:00 2001 From: Jaedon Shin Date: Thu, 26 Nov 2015 11:56:34 +0900 Subject: [PATCH 1742/2855] phy: phy_brcmstb_sata: add data for phy version Add data for phy version, and the default value of version is using the BRCM_SATA_PHY_28NM. Signed-off-by: Jaedon Shin Tested-by: Florian Fainelli Acked-by: Brian Norris Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-brcmstb-sata.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/phy/phy-brcmstb-sata.c b/drivers/phy/phy-brcmstb-sata.c index ddb9b9e8270d7..555fb2de11d4d 100644 --- a/drivers/phy/phy-brcmstb-sata.c +++ b/drivers/phy/phy-brcmstb-sata.c @@ -30,7 +30,11 @@ #define MAX_PORTS 2 /* Register offset between PHYs in PCB space */ -#define SATA_MDIO_REG_SPACE_SIZE 0x1000 +#define SATA_MDIO_REG_28NM_SPACE_SIZE 0x1000 + +enum brcm_sata_phy_version { + BRCM_SATA_PHY_28NM, +}; struct brcm_sata_port { int portnum; @@ -42,6 +46,7 @@ struct brcm_sata_port { struct brcm_sata_phy { struct device *dev; void __iomem *phy_base; + enum brcm_sata_phy_version version; struct brcm_sata_port phys[MAX_PORTS]; }; @@ -64,8 +69,12 @@ enum sata_mdio_phy_regs_28nm { static inline void __iomem *brcm_sata_phy_base(struct brcm_sata_port *port) { struct brcm_sata_phy *priv = port->phy_priv; + u32 offset; - return priv->phy_base + (port->portnum * SATA_MDIO_REG_SPACE_SIZE); + if (priv->version == BRCM_SATA_PHY_28NM) + offset = SATA_MDIO_REG_28NM_SPACE_SIZE; + + return priv->phy_base + (port->portnum * offset); } static void brcm_sata_mdio_wr(void __iomem *addr, u32 bank, u32 ofs, @@ -126,7 +135,8 @@ static const struct phy_ops phy_ops_28nm = { }; static const struct of_device_id brcm_sata_phy_of_match[] = { - { .compatible = "brcm,bcm7445-sata-phy" }, + { .compatible = "brcm,bcm7445-sata-phy", + .data = (void *)BRCM_SATA_PHY_28NM }, {}, }; MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match); @@ -135,6 +145,7 @@ static int brcm_sata_phy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *dn = dev->of_node, *child; + const struct of_device_id *of_id; struct brcm_sata_phy *priv; struct resource *res; struct phy_provider *provider; @@ -154,6 +165,12 @@ static int brcm_sata_phy_probe(struct platform_device *pdev) if (IS_ERR(priv->phy_base)) return PTR_ERR(priv->phy_base); + of_id = of_match_node(brcm_sata_phy_of_match, dn); + if (of_id) + priv->version = (enum brcm_sata_phy_version)of_id->data; + else + priv->version = BRCM_SATA_PHY_28NM; + for_each_available_child_of_node(dn, child) { unsigned int id; struct brcm_sata_port *port; -- GitLab From c1602a1a0fbe12ab8e67deedf32e5a85f8553a07 Mon Sep 17 00:00:00 2001 From: Jaedon Shin Date: Thu, 26 Nov 2015 11:56:35 +0900 Subject: [PATCH 1743/2855] phy: phy_brcmstb_sata: add support for MIPS-based platforms The BCM7xxx ARM-based and MIPS-based platforms share a similar hardware block for AHCI SATA3. This new compatible string, "brcm,bcm7425-sata-phy", may be used for most MIPS-based platforms of 40nm process technology. Signed-off-by: Jaedon Shin Acked-by: Rob Herring Tested-by: Florian Fainelli Acked-by: Brian Norris Signed-off-by: Kishon Vijay Abraham I --- .../bindings/phy/brcm,brcmstb-sata-phy.txt | 1 + drivers/phy/Kconfig | 4 ++-- drivers/phy/phy-brcmstb-sata.c | 24 ++++++++++++++----- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/brcm,brcmstb-sata-phy.txt b/Documentation/devicetree/bindings/phy/brcm,brcmstb-sata-phy.txt index 7f81ef90146ab..d87ab7c127b8a 100644 --- a/Documentation/devicetree/bindings/phy/brcm,brcmstb-sata-phy.txt +++ b/Documentation/devicetree/bindings/phy/brcm,brcmstb-sata-phy.txt @@ -2,6 +2,7 @@ Required properties: - compatible: should be one or more of + "brcm,bcm7425-sata-phy" "brcm,bcm7445-sata-phy" "brcm,phy-sata3" - address-cells: should be 1 diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 90eec60d7ba54..e7e117d5dbbe4 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -390,11 +390,11 @@ config PHY_TUSB1210 config PHY_BRCMSTB_SATA tristate "Broadcom STB SATA PHY driver" - depends on ARCH_BRCMSTB + depends on ARCH_BRCMSTB || BMIPS_GENERIC depends on OF select GENERIC_PHY help - Enable this to support the SATA3 PHY on 28nm Broadcom STB SoCs. + Enable this to support the SATA3 PHY on 28nm or 40nm Broadcom STB SoCs. Likely useful only with CONFIG_SATA_BRCMSTB enabled. config PHY_CYGNUS_PCIE diff --git a/drivers/phy/phy-brcmstb-sata.c b/drivers/phy/phy-brcmstb-sata.c index 555fb2de11d4d..a23172ff40e31 100644 --- a/drivers/phy/phy-brcmstb-sata.c +++ b/drivers/phy/phy-brcmstb-sata.c @@ -32,8 +32,14 @@ /* Register offset between PHYs in PCB space */ #define SATA_MDIO_REG_28NM_SPACE_SIZE 0x1000 +/* The older SATA PHY registers duplicated per port registers within the map, + * rather than having a separate map per port. + */ +#define SATA_MDIO_REG_40NM_SPACE_SIZE 0x10 + enum brcm_sata_phy_version { BRCM_SATA_PHY_28NM, + BRCM_SATA_PHY_40NM, }; struct brcm_sata_port { @@ -51,7 +57,7 @@ struct brcm_sata_phy { struct brcm_sata_port phys[MAX_PORTS]; }; -enum sata_mdio_phy_regs_28nm { +enum sata_mdio_phy_regs { PLL_REG_BANK_0 = 0x50, PLL_REG_BANK_0_PLLCONTROL_0 = 0x81, @@ -69,10 +75,14 @@ enum sata_mdio_phy_regs_28nm { static inline void __iomem *brcm_sata_phy_base(struct brcm_sata_port *port) { struct brcm_sata_phy *priv = port->phy_priv; - u32 offset; + u32 offset = 0; if (priv->version == BRCM_SATA_PHY_28NM) offset = SATA_MDIO_REG_28NM_SPACE_SIZE; + else if (priv->version == BRCM_SATA_PHY_40NM) + offset = SATA_MDIO_REG_40NM_SPACE_SIZE; + else + dev_err(priv->dev, "invalid phy version\n"); return priv->phy_base + (port->portnum * offset); } @@ -93,7 +103,7 @@ static void brcm_sata_mdio_wr(void __iomem *addr, u32 bank, u32 ofs, #define FMAX_VAL_DEFAULT 0x3df #define FMAX_VAL_SSC 0x83 -static void brcm_sata_cfg_ssc_28nm(struct brcm_sata_port *port) +static void brcm_sata_cfg_ssc(struct brcm_sata_port *port) { void __iomem *base = brcm_sata_phy_base(port); struct brcm_sata_phy *priv = port->phy_priv; @@ -124,12 +134,12 @@ static int brcm_sata_phy_init(struct phy *phy) { struct brcm_sata_port *port = phy_get_drvdata(phy); - brcm_sata_cfg_ssc_28nm(port); + brcm_sata_cfg_ssc(port); return 0; } -static const struct phy_ops phy_ops_28nm = { +static const struct phy_ops phy_ops = { .init = brcm_sata_phy_init, .owner = THIS_MODULE, }; @@ -137,6 +147,8 @@ static const struct phy_ops phy_ops_28nm = { static const struct of_device_id brcm_sata_phy_of_match[] = { { .compatible = "brcm,bcm7445-sata-phy", .data = (void *)BRCM_SATA_PHY_28NM }, + { .compatible = "brcm,bcm7425-sata-phy", + .data = (void *)BRCM_SATA_PHY_40NM }, {}, }; MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match); @@ -196,7 +208,7 @@ static int brcm_sata_phy_probe(struct platform_device *pdev) port = &priv->phys[id]; port->portnum = id; port->phy_priv = priv; - port->phy = devm_phy_create(dev, child, &phy_ops_28nm); + port->phy = devm_phy_create(dev, child, &phy_ops); port->ssc_en = of_property_read_bool(child, "brcm,enable-ssc"); if (IS_ERR(port->phy)) { dev_err(dev, "failed to create PHY\n"); -- GitLab From c7a0b20ed42c0f4e1f80e7a9dfa6502894a82e22 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 4 Dec 2015 21:57:00 +0800 Subject: [PATCH 1744/2855] phy: berlin-usb: remove non-necessary header files We don't need gpio related header files, so remove them. Signed-off-by: Jisheng Zhang Acked-by: Antoine Tenart Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-berlin-usb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/phy/phy-berlin-usb.c b/drivers/phy/phy-berlin-usb.c index 797ba17c404f7..7bbb47389fb05 100644 --- a/drivers/phy/phy-berlin-usb.c +++ b/drivers/phy/phy-berlin-usb.c @@ -9,11 +9,9 @@ * warranty of any kind, whether express or implied. */ -#include #include #include #include -#include #include #include #include -- GitLab From c3ab642f2f08349c41f7d837f224ce1e63b58197 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 4 Dec 2015 21:57:01 +0800 Subject: [PATCH 1745/2855] phy: berlin-usb: don't set device's driver_data After commit 739ae3452d0e ("phy: berlin-usb: Set drvdata for phy and use it"), we get the address of priv by phy_get_drvdata(), so there's no need to set device's driver_data any more. This patch removes the call of platform_set_drvdata(). Signed-off-by: Jisheng Zhang Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-berlin-usb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/phy/phy-berlin-usb.c b/drivers/phy/phy-berlin-usb.c index 7bbb47389fb05..2017751ede263 100644 --- a/drivers/phy/phy-berlin-usb.c +++ b/drivers/phy/phy-berlin-usb.c @@ -193,7 +193,6 @@ static int phy_berlin_usb_probe(struct platform_device *pdev) return PTR_ERR(phy); } - platform_set_drvdata(pdev, priv); phy_set_drvdata(phy, priv); phy_provider = -- GitLab From 08a0a4f987a4b5827e4111eccc97a9271d24633e Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 19 Dec 2015 08:17:41 +0900 Subject: [PATCH 1746/2855] extcon: add Maxim MAX3355 driver Maxim Integrated MAX3355E chip integrates a charge pump and comparators to enable a system with an integrated USB OTG dual-role transceiver to function as an USB OTG dual-role device. In addition to sensing/controlling Vbus, the chip also passes thru the ID signal from the USB OTG connector. On some Renesas boards, this signal is just fed into the SoC thru a GPIO pin -- there's no real OTG controller, only host and gadget USB controllers sharing the same USB bus; however, we'd like to allow host or gadget drivers to be loaded depending on the cable type, hence the need for the MAX3355 extcon driver. The Vbus status signals are also wired to GPIOs (however, we aren't currently interested in them), the OFFVBUS# signal is controlled by the host controllers, there's also the SHDN# signal wired to a GPIO, it should be driven high for the normal operation. Signed-off-by: Sergei Shtylyov Acked-by: Chanwoo Choi Acked-by: Rob Herring [cw00.choi: Add the GPIOLIB dependency] Signed-off-by: Chanwoo Choi --- .../bindings/extcon/extcon-max3355.txt | 21 +++ drivers/extcon/Kconfig | 9 ++ drivers/extcon/Makefile | 1 + drivers/extcon/extcon-max3355.c | 146 ++++++++++++++++++ 4 files changed, 177 insertions(+) create mode 100644 Documentation/devicetree/bindings/extcon/extcon-max3355.txt create mode 100644 drivers/extcon/extcon-max3355.c diff --git a/Documentation/devicetree/bindings/extcon/extcon-max3355.txt b/Documentation/devicetree/bindings/extcon/extcon-max3355.txt new file mode 100644 index 0000000000000..f2288ea9eb828 --- /dev/null +++ b/Documentation/devicetree/bindings/extcon/extcon-max3355.txt @@ -0,0 +1,21 @@ +Maxim Integrated MAX3355 USB OTG chip +------------------------------------- + +MAX3355 integrates a charge pump and comparators to enable a system with an +integrated USB OTG dual-role transceiver to function as a USB OTG dual-role +device. + +Required properties: +- compatible: should be "maxim,max3355"; +- maxim,shdn-gpios: should contain a phandle and GPIO specifier for the GPIO pin + connected to the MAX3355's SHDN# pin; +- id-gpios: should contain a phandle and GPIO specifier for the GPIO pin + connected to the MAX3355's ID_OUT pin. + +Example: + + usb-otg { + compatible = "maxim,max3355"; + maxim,shdn-gpios = <&gpio2 4 GPIO_ACTIVE_LOW>; + id-gpios = <&gpio5 31 GPIO_ACTIVE_HIGH>; + }; diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig index 0cebbf668886a..3d89e60a3e715 100644 --- a/drivers/extcon/Kconfig +++ b/drivers/extcon/Kconfig @@ -52,6 +52,15 @@ config EXTCON_MAX14577 Maxim MAX14577/77836. The MAX14577/77836 MUIC is a USB port accessory detector and switch. +config EXTCON_MAX3355 + tristate "Maxim MAX3355 USB OTG EXTCON Support" + depends on GPIOLIB || COMPILE_TEST + help + If you say yes here you get support for the USB OTG role detection by + MAX3355. The MAX3355 chip integrates a charge pump and comparators to + enable a system with an integrated USB OTG dual-role transceiver to + function as an USB OTG dual-role device. + config EXTCON_MAX77693 tristate "Maxim MAX77693 EXTCON Support" depends on MFD_MAX77693 && INPUT diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile index ba787d04295b7..2a0e4f45d5b20 100644 --- a/drivers/extcon/Makefile +++ b/drivers/extcon/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_EXTCON_ARIZONA) += extcon-arizona.o obj-$(CONFIG_EXTCON_AXP288) += extcon-axp288.o obj-$(CONFIG_EXTCON_GPIO) += extcon-gpio.o obj-$(CONFIG_EXTCON_MAX14577) += extcon-max14577.o +obj-$(CONFIG_EXTCON_MAX3355) += extcon-max3355.o obj-$(CONFIG_EXTCON_MAX77693) += extcon-max77693.o obj-$(CONFIG_EXTCON_MAX77843) += extcon-max77843.o obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o diff --git a/drivers/extcon/extcon-max3355.c b/drivers/extcon/extcon-max3355.c new file mode 100644 index 0000000000000..c24abec5d06cf --- /dev/null +++ b/drivers/extcon/extcon-max3355.c @@ -0,0 +1,146 @@ +/* + * Maxim Integrated MAX3355 USB OTG chip extcon driver + * + * Copyright (C) 2014-2015 Cogent Embedded, Inc. + * Author: Sergei Shtylyov + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + */ + +#include +#include +#include +#include +#include +#include + +struct max3355_data { + struct extcon_dev *edev; + struct gpio_desc *id_gpiod; + struct gpio_desc *shdn_gpiod; +}; + +static const unsigned int max3355_cable[] = { + EXTCON_USB, + EXTCON_USB_HOST, + EXTCON_NONE, +}; + +static irqreturn_t max3355_id_irq(int irq, void *dev_id) +{ + struct max3355_data *data = dev_id; + int id = gpiod_get_value_cansleep(data->id_gpiod); + + if (id) { + /* + * ID = 1 means USB HOST cable detached. + * As we don't have event for USB peripheral cable attached, + * we simulate USB peripheral attach here. + */ + extcon_set_cable_state_(data->edev, EXTCON_USB_HOST, false); + extcon_set_cable_state_(data->edev, EXTCON_USB, true); + } else { + /* + * ID = 0 means USB HOST cable attached. + * As we don't have event for USB peripheral cable detached, + * we simulate USB peripheral detach here. + */ + extcon_set_cable_state_(data->edev, EXTCON_USB, false); + extcon_set_cable_state_(data->edev, EXTCON_USB_HOST, true); + } + + return IRQ_HANDLED; +} + +static int max3355_probe(struct platform_device *pdev) +{ + struct max3355_data *data; + struct gpio_desc *gpiod; + int irq, err; + + data = devm_kzalloc(&pdev->dev, sizeof(struct max3355_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + gpiod = devm_gpiod_get(&pdev->dev, "id", GPIOD_IN); + if (IS_ERR(gpiod)) { + dev_err(&pdev->dev, "failed to get ID_OUT GPIO\n"); + return PTR_ERR(gpiod); + } + data->id_gpiod = gpiod; + + gpiod = devm_gpiod_get(&pdev->dev, "maxim,shdn", GPIOD_OUT_HIGH); + if (IS_ERR(gpiod)) { + dev_err(&pdev->dev, "failed to get SHDN# GPIO\n"); + return PTR_ERR(gpiod); + } + data->shdn_gpiod = gpiod; + + data->edev = devm_extcon_dev_allocate(&pdev->dev, max3355_cable); + if (IS_ERR(data->edev)) { + dev_err(&pdev->dev, "failed to allocate extcon device\n"); + return PTR_ERR(data->edev); + } + + err = devm_extcon_dev_register(&pdev->dev, data->edev); + if (err < 0) { + dev_err(&pdev->dev, "failed to register extcon device\n"); + return err; + } + + irq = gpiod_to_irq(data->id_gpiod); + if (irq < 0) { + dev_err(&pdev->dev, "failed to translate ID_OUT GPIO to IRQ\n"); + return irq; + } + + err = devm_request_threaded_irq(&pdev->dev, irq, NULL, max3355_id_irq, + IRQF_ONESHOT | IRQF_NO_SUSPEND | + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING, + pdev->name, data); + if (err < 0) { + dev_err(&pdev->dev, "failed to request ID_OUT IRQ\n"); + return err; + } + + platform_set_drvdata(pdev, data); + + /* Perform initial detection */ + max3355_id_irq(irq, data); + + return 0; +} + +static int max3355_remove(struct platform_device *pdev) +{ + struct max3355_data *data = platform_get_drvdata(pdev); + + gpiod_set_value_cansleep(data->shdn_gpiod, 0); + + return 0; +} + +static const struct of_device_id max3355_match_table[] = { + { .compatible = "maxim,max3355", }, + { } +}; +MODULE_DEVICE_TABLE(of, max3355_match_table); + +static struct platform_driver max3355_driver = { + .probe = max3355_probe, + .remove = max3355_remove, + .driver = { + .name = "extcon-max3355", + .of_match_table = max3355_match_table, + }, +}; + +module_platform_driver(max3355_driver); + +MODULE_AUTHOR("Sergei Shtylyov "); +MODULE_DESCRIPTION("Maxim MAX3355 extcon driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From d65ff52eb8ed5c8480fbff9ef720e2b56d9a6fb2 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Mon, 21 Dec 2015 14:24:05 +0530 Subject: [PATCH 1747/2855] phy: ti-pipe3: introduce local struct device* in probe No functional change. Introduce local struct device pointer in probe and replace using &pdev->dev/phy->dev with the local device pointer. This is in preparation to split ti_pipe3_probe and add separate functions for getting mem resource, getting sysctrl and getting clocks. Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-ti-pipe3.c | 54 +++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index 93bc1120af128..c5111057d241a 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c @@ -319,40 +319,41 @@ static int ti_pipe3_probe(struct platform_device *pdev) struct platform_device *control_pdev; const struct of_device_id *match; struct clk *clk; + struct device *dev = &pdev->dev; - phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); if (!phy) return -ENOMEM; - phy->dev = &pdev->dev; + phy->dev = dev; if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { - match = of_match_device(ti_pipe3_id_table, &pdev->dev); + match = of_match_device(ti_pipe3_id_table, dev); if (!match) return -EINVAL; phy->dpll_map = (struct pipe3_dpll_map *)match->data; if (!phy->dpll_map) { - dev_err(&pdev->dev, "no DPLL data\n"); + dev_err(dev, "no DPLL data\n"); return -EINVAL; } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl"); - phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res); + phy->pll_ctrl_base = devm_ioremap_resource(dev, res); if (IS_ERR(phy->pll_ctrl_base)) return PTR_ERR(phy->pll_ctrl_base); - phy->sys_clk = devm_clk_get(phy->dev, "sysclk"); + phy->sys_clk = devm_clk_get(dev, "sysclk"); if (IS_ERR(phy->sys_clk)) { - dev_err(&pdev->dev, "unable to get sysclk\n"); + dev_err(dev, "unable to get sysclk\n"); return -EINVAL; } } - phy->refclk = devm_clk_get(phy->dev, "refclk"); + phy->refclk = devm_clk_get(dev, "refclk"); if (IS_ERR(phy->refclk)) { - dev_err(&pdev->dev, "unable to get refclk\n"); + dev_err(dev, "unable to get refclk\n"); /* older DTBs have missing refclk in SATA PHY * so don't bail out in case of SATA PHY. */ @@ -361,9 +362,9 @@ static int ti_pipe3_probe(struct platform_device *pdev) } if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) { - phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); + phy->wkupclk = devm_clk_get(dev, "wkupclk"); if (IS_ERR(phy->wkupclk)) { - dev_err(&pdev->dev, "unable to get wkupclk\n"); + dev_err(dev, "unable to get wkupclk\n"); return PTR_ERR(phy->wkupclk); } } else { @@ -371,14 +372,14 @@ static int ti_pipe3_probe(struct platform_device *pdev) phy->dpll_reset_syscon = syscon_regmap_lookup_by_phandle(node, "syscon-pllreset"); if (IS_ERR(phy->dpll_reset_syscon)) { - dev_info(&pdev->dev, + dev_info(dev, "can't get syscon-pllreset, sata dpll won't idle\n"); phy->dpll_reset_syscon = NULL; } else { if (of_property_read_u32_index(node, "syscon-pllreset", 1, &phy->dpll_reset_reg)) { - dev_err(&pdev->dev, + dev_err(dev, "couldn't get pllreset reg. offset\n"); return -EINVAL; } @@ -387,30 +388,30 @@ static int ti_pipe3_probe(struct platform_device *pdev) if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { - clk = devm_clk_get(phy->dev, "dpll_ref"); + clk = devm_clk_get(dev, "dpll_ref"); if (IS_ERR(clk)) { - dev_err(&pdev->dev, "unable to get dpll ref clk\n"); + dev_err(dev, "unable to get dpll ref clk\n"); return PTR_ERR(clk); } clk_set_rate(clk, 1500000000); - clk = devm_clk_get(phy->dev, "dpll_ref_m2"); + clk = devm_clk_get(dev, "dpll_ref_m2"); if (IS_ERR(clk)) { - dev_err(&pdev->dev, "unable to get dpll ref m2 clk\n"); + dev_err(dev, "unable to get dpll ref m2 clk\n"); return PTR_ERR(clk); } clk_set_rate(clk, 100000000); - clk = devm_clk_get(phy->dev, "phy-div"); + clk = devm_clk_get(dev, "phy-div"); if (IS_ERR(clk)) { - dev_err(&pdev->dev, "unable to get phy-div clk\n"); + dev_err(dev, "unable to get phy-div clk\n"); return PTR_ERR(clk); } clk_set_rate(clk, 100000000); - phy->div_clk = devm_clk_get(phy->dev, "div-clk"); + phy->div_clk = devm_clk_get(dev, "div-clk"); if (IS_ERR(phy->div_clk)) { - dev_err(&pdev->dev, "unable to get div-clk\n"); + dev_err(dev, "unable to get div-clk\n"); return PTR_ERR(phy->div_clk); } } else { @@ -419,13 +420,13 @@ static int ti_pipe3_probe(struct platform_device *pdev) control_node = of_parse_phandle(node, "ctrl-module", 0); if (!control_node) { - dev_err(&pdev->dev, "Failed to get control device phandle\n"); + dev_err(dev, "Failed to get control device phandle\n"); return -EINVAL; } control_pdev = of_find_device_by_node(control_node); if (!control_pdev) { - dev_err(&pdev->dev, "Failed to get control device\n"); + dev_err(dev, "Failed to get control device\n"); return -EINVAL; } @@ -434,7 +435,7 @@ static int ti_pipe3_probe(struct platform_device *pdev) omap_control_phy_power(phy->control_dev, 0); platform_set_drvdata(pdev, phy); - pm_runtime_enable(phy->dev); + pm_runtime_enable(dev); /* * Prevent auto-disable of refclk for SATA PHY due to Errata i783 @@ -446,13 +447,12 @@ static int ti_pipe3_probe(struct platform_device *pdev) } } - generic_phy = devm_phy_create(phy->dev, NULL, &ops); + generic_phy = devm_phy_create(dev, NULL, &ops); if (IS_ERR(generic_phy)) return PTR_ERR(generic_phy); phy_set_drvdata(generic_phy, phy); - phy_provider = devm_of_phy_provider_register(phy->dev, - of_phy_simple_xlate); + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); if (IS_ERR(phy_provider)) return PTR_ERR(phy_provider); -- GitLab From 234738ea33903a185530a997f9ddff68709929b9 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Mon, 21 Dec 2015 14:24:06 +0530 Subject: [PATCH 1748/2855] phy: ti-pipe3: move clk initialization to a separate function No functional change. Moved clock initialization done in probe to a separate function as part of cleaning up ti_pipe3_probe. Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-ti-pipe3.c | 127 +++++++++++++++++++++---------------- 1 file changed, 72 insertions(+), 55 deletions(-) diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index c5111057d241a..3379a4deeb16b 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c @@ -308,48 +308,11 @@ static const struct phy_ops ops = { static const struct of_device_id ti_pipe3_id_table[]; -static int ti_pipe3_probe(struct platform_device *pdev) +static int ti_pipe3_get_clk(struct ti_pipe3 *phy) { - struct ti_pipe3 *phy; - struct phy *generic_phy; - struct phy_provider *phy_provider; - struct resource *res; - struct device_node *node = pdev->dev.of_node; - struct device_node *control_node; - struct platform_device *control_pdev; - const struct of_device_id *match; struct clk *clk; - struct device *dev = &pdev->dev; - - phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); - if (!phy) - return -ENOMEM; - - phy->dev = dev; - - if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { - match = of_match_device(ti_pipe3_id_table, dev); - if (!match) - return -EINVAL; - - phy->dpll_map = (struct pipe3_dpll_map *)match->data; - if (!phy->dpll_map) { - dev_err(dev, "no DPLL data\n"); - return -EINVAL; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "pll_ctrl"); - phy->pll_ctrl_base = devm_ioremap_resource(dev, res); - if (IS_ERR(phy->pll_ctrl_base)) - return PTR_ERR(phy->pll_ctrl_base); - - phy->sys_clk = devm_clk_get(dev, "sysclk"); - if (IS_ERR(phy->sys_clk)) { - dev_err(dev, "unable to get sysclk\n"); - return -EINVAL; - } - } + struct device *dev = phy->dev; + struct device_node *node = dev->of_node; phy->refclk = devm_clk_get(dev, "refclk"); if (IS_ERR(phy->refclk)) { @@ -369,25 +332,17 @@ static int ti_pipe3_probe(struct platform_device *pdev) } } else { phy->wkupclk = ERR_PTR(-ENODEV); - phy->dpll_reset_syscon = syscon_regmap_lookup_by_phandle(node, - "syscon-pllreset"); - if (IS_ERR(phy->dpll_reset_syscon)) { - dev_info(dev, - "can't get syscon-pllreset, sata dpll won't idle\n"); - phy->dpll_reset_syscon = NULL; - } else { - if (of_property_read_u32_index(node, - "syscon-pllreset", 1, - &phy->dpll_reset_reg)) { - dev_err(dev, - "couldn't get pllreset reg. offset\n"); - return -EINVAL; - } + } + + if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { + phy->sys_clk = devm_clk_get(dev, "sysclk"); + if (IS_ERR(phy->sys_clk)) { + dev_err(dev, "unable to get sysclk\n"); + return -EINVAL; } } if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { - clk = devm_clk_get(dev, "dpll_ref"); if (IS_ERR(clk)) { dev_err(dev, "unable to get dpll ref clk\n"); @@ -418,6 +373,68 @@ static int ti_pipe3_probe(struct platform_device *pdev) phy->div_clk = ERR_PTR(-ENODEV); } + return 0; +} + +static int ti_pipe3_probe(struct platform_device *pdev) +{ + struct ti_pipe3 *phy; + struct phy *generic_phy; + struct phy_provider *phy_provider; + struct resource *res; + struct device_node *node = pdev->dev.of_node; + struct device_node *control_node; + struct platform_device *control_pdev; + const struct of_device_id *match; + struct device *dev = &pdev->dev; + int ret; + + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); + if (!phy) + return -ENOMEM; + + phy->dev = dev; + + if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { + match = of_match_device(ti_pipe3_id_table, dev); + if (!match) + return -EINVAL; + + phy->dpll_map = (struct pipe3_dpll_map *)match->data; + if (!phy->dpll_map) { + dev_err(dev, "no DPLL data\n"); + return -EINVAL; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "pll_ctrl"); + phy->pll_ctrl_base = devm_ioremap_resource(dev, res); + if (IS_ERR(phy->pll_ctrl_base)) + return PTR_ERR(phy->pll_ctrl_base); + } + + if (of_device_is_compatible(node, "ti,phy-pipe3-sata")) { + phy->dpll_reset_syscon = syscon_regmap_lookup_by_phandle(node, + "syscon-pllreset"); + if (IS_ERR(phy->dpll_reset_syscon)) { + dev_info(dev, + "can't get syscon-pllreset, sata dpll won't idle\n"); + phy->dpll_reset_syscon = NULL; + } else { + if (of_property_read_u32_index(node, + "syscon-pllreset", 1, + &phy->dpll_reset_reg)) { + dev_err(dev, + "couldn't get pllreset reg. offset\n"); + return -EINVAL; + } + } + } + + ret = ti_pipe3_get_clk(phy); + if (ret) + return ret; + control_node = of_parse_phandle(node, "ctrl-module", 0); if (!control_node) { dev_err(dev, "Failed to get control device phandle\n"); -- GitLab From 73bbc78e57c96aba9c7d6473ee4ea8374ae257ee Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Mon, 21 Dec 2015 14:24:07 +0530 Subject: [PATCH 1749/2855] phy: ti-pipe3: move sysctrl initialization to a separate function No functional change. Moved sysctrl initialization done in probe to a separate function as part of cleaning up ti_pipe3_probe. Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-ti-pipe3.c | 78 ++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index 3379a4deeb16b..3154da08ff373 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c @@ -376,6 +376,48 @@ static int ti_pipe3_get_clk(struct ti_pipe3 *phy) return 0; } +static int ti_pipe3_get_sysctrl(struct ti_pipe3 *phy) +{ + struct device *dev = phy->dev; + struct device_node *node = dev->of_node; + struct device_node *control_node; + struct platform_device *control_pdev; + + control_node = of_parse_phandle(node, "ctrl-module", 0); + if (!control_node) { + dev_err(dev, "Failed to get control device phandle\n"); + return -EINVAL; + } + + control_pdev = of_find_device_by_node(control_node); + if (!control_pdev) { + dev_err(dev, "Failed to get control device\n"); + return -EINVAL; + } + + phy->control_dev = &control_pdev->dev; + + if (of_device_is_compatible(node, "ti,phy-pipe3-sata")) { + phy->dpll_reset_syscon = syscon_regmap_lookup_by_phandle(node, + "syscon-pllreset"); + if (IS_ERR(phy->dpll_reset_syscon)) { + dev_info(dev, + "can't get syscon-pllreset, sata dpll won't idle\n"); + phy->dpll_reset_syscon = NULL; + } else { + if (of_property_read_u32_index(node, + "syscon-pllreset", 1, + &phy->dpll_reset_reg)) { + dev_err(dev, + "couldn't get pllreset reg. offset\n"); + return -EINVAL; + } + } + } + + return 0; +} + static int ti_pipe3_probe(struct platform_device *pdev) { struct ti_pipe3 *phy; @@ -383,8 +425,6 @@ static int ti_pipe3_probe(struct platform_device *pdev) struct phy_provider *phy_provider; struct resource *res; struct device_node *node = pdev->dev.of_node; - struct device_node *control_node; - struct platform_device *control_pdev; const struct of_device_id *match; struct device *dev = &pdev->dev; int ret; @@ -413,42 +453,14 @@ static int ti_pipe3_probe(struct platform_device *pdev) return PTR_ERR(phy->pll_ctrl_base); } - if (of_device_is_compatible(node, "ti,phy-pipe3-sata")) { - phy->dpll_reset_syscon = syscon_regmap_lookup_by_phandle(node, - "syscon-pllreset"); - if (IS_ERR(phy->dpll_reset_syscon)) { - dev_info(dev, - "can't get syscon-pllreset, sata dpll won't idle\n"); - phy->dpll_reset_syscon = NULL; - } else { - if (of_property_read_u32_index(node, - "syscon-pllreset", 1, - &phy->dpll_reset_reg)) { - dev_err(dev, - "couldn't get pllreset reg. offset\n"); - return -EINVAL; - } - } - } + ret = ti_pipe3_get_sysctrl(phy); + if (ret) + return ret; ret = ti_pipe3_get_clk(phy); if (ret) return ret; - control_node = of_parse_phandle(node, "ctrl-module", 0); - if (!control_node) { - dev_err(dev, "Failed to get control device phandle\n"); - return -EINVAL; - } - - control_pdev = of_find_device_by_node(control_node); - if (!control_pdev) { - dev_err(dev, "Failed to get control device\n"); - return -EINVAL; - } - - phy->control_dev = &control_pdev->dev; - omap_control_phy_power(phy->control_dev, 0); platform_set_drvdata(pdev, phy); -- GitLab From 1fe521225a830e159449cba9f7b365ba207e22c9 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Mon, 21 Dec 2015 14:24:08 +0530 Subject: [PATCH 1750/2855] phy: ti-pipe3: move mem resource initialization to a separate function No functional change. Moved mem resource initialization done in probe to a separate function as part of cleaning up ti_pipe3_probe. Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-ti-pipe3.c | 52 ++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index 3154da08ff373..1991efdd7d2a5 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c @@ -418,14 +418,42 @@ static int ti_pipe3_get_sysctrl(struct ti_pipe3 *phy) return 0; } +static int ti_pipe3_get_pll_base(struct ti_pipe3 *phy) +{ + struct resource *res; + const struct of_device_id *match; + struct device *dev = phy->dev; + struct device_node *node = dev->of_node; + struct platform_device *pdev = to_platform_device(dev); + + if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) + return 0; + + match = of_match_device(ti_pipe3_id_table, dev); + if (!match) + return -EINVAL; + + phy->dpll_map = (struct pipe3_dpll_map *)match->data; + if (!phy->dpll_map) { + dev_err(dev, "no DPLL data\n"); + return -EINVAL; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "pll_ctrl"); + phy->pll_ctrl_base = devm_ioremap_resource(dev, res); + if (IS_ERR(phy->pll_ctrl_base)) + return PTR_ERR(phy->pll_ctrl_base); + + return 0; +} + static int ti_pipe3_probe(struct platform_device *pdev) { struct ti_pipe3 *phy; struct phy *generic_phy; struct phy_provider *phy_provider; - struct resource *res; struct device_node *node = pdev->dev.of_node; - const struct of_device_id *match; struct device *dev = &pdev->dev; int ret; @@ -435,23 +463,9 @@ static int ti_pipe3_probe(struct platform_device *pdev) phy->dev = dev; - if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { - match = of_match_device(ti_pipe3_id_table, dev); - if (!match) - return -EINVAL; - - phy->dpll_map = (struct pipe3_dpll_map *)match->data; - if (!phy->dpll_map) { - dev_err(dev, "no DPLL data\n"); - return -EINVAL; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "pll_ctrl"); - phy->pll_ctrl_base = devm_ioremap_resource(dev, res); - if (IS_ERR(phy->pll_ctrl_base)) - return PTR_ERR(phy->pll_ctrl_base); - } + ret = ti_pipe3_get_pll_base(phy); + if (ret) + return ret; ret = ti_pipe3_get_sysctrl(phy); if (ret) -- GitLab From cc34ace73dfa24d9cda2fd2c4666e38a515a9052 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Mon, 21 Dec 2015 14:24:09 +0530 Subject: [PATCH 1751/2855] phy: ti-pipe3: use ti_pipe3_power_off to power off the PHY during probe No functional change. Previously omap_control_phy_power() was used to power off the PHY during probe. But once PIPE3 driver is adapted to use syscon, omap_control_phy_power() cannot be used. Hence used ti_pipe3_power_off to power off the PHY. Signed-off-by: Kishon Vijay Abraham I Acked-by: Roger Quadros --- drivers/phy/phy-ti-pipe3.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index 1991efdd7d2a5..0ce4194e09a55 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c @@ -475,8 +475,6 @@ static int ti_pipe3_probe(struct platform_device *pdev) if (ret) return ret; - omap_control_phy_power(phy->control_dev, 0); - platform_set_drvdata(pdev, phy); pm_runtime_enable(dev); @@ -495,6 +493,9 @@ static int ti_pipe3_probe(struct platform_device *pdev) return PTR_ERR(generic_phy); phy_set_drvdata(generic_phy, phy); + + ti_pipe3_power_off(generic_phy); + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); if (IS_ERR(phy_provider)) return PTR_ERR(phy_provider); -- GitLab From c396a1c7ee1b3b460cf01824b03e0627a7db5b01 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Mon, 21 Dec 2015 14:24:10 +0530 Subject: [PATCH 1752/2855] phy: ti-pipe3: use *syscon* framework API to power on/off the PHY Deprecate using phy-omap-control driver to power on/off the PHY and use *syscon* framework to do the same. Signed-off-by: Kishon Vijay Abraham I Acked-by: Rob Herring --- .../devicetree/bindings/phy/ti-phy.txt | 10 ++- drivers/phy/phy-ti-pipe3.c | 88 +++++++++++++++---- 2 files changed, 81 insertions(+), 17 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/ti-phy.txt b/Documentation/devicetree/bindings/phy/ti-phy.txt index 9cf9446eaf2ea..e06f980fa2ba6 100644 --- a/Documentation/devicetree/bindings/phy/ti-phy.txt +++ b/Documentation/devicetree/bindings/phy/ti-phy.txt @@ -77,8 +77,6 @@ Required properties: * "div-clk" - apll clock Optional properties: - - ctrl-module : phandle of the control module used by PHY driver to power on - the PHY. - id: If there are multiple instance of the same type, in order to differentiate between each instance "id" can be used (e.g., multi-lane PCIe PHY). If "id" is not provided, it is set to default value of '1'. @@ -86,6 +84,14 @@ Optional properties: CTRL_CORE_SMA_SW_0 register and register offset to the CTRL_CORE_SMA_SW_0 register that contains the SATA_PLL_SOFT_RESET bit. Only valid for sata_phy. +Deprecated properties: + - ctrl-module : phandle of the control module used by PHY driver to power on + the PHY. + +Recommended properies: + - syscon-phy-power : phandle/offset pair. Phandle to the system control + module and the register offset to power on/off the PHY. + This is usually a subnode of ocp2scp to which it is connected. usb3phy@4a084400 { diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index 0ce4194e09a55..a47b1902a36fd 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c @@ -56,6 +56,15 @@ #define SATA_PLL_SOFT_RESET BIT(18) +#define PIPE3_PHY_PWRCTL_CLK_CMD_MASK 0x003FC000 +#define PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT 14 + +#define PIPE3_PHY_PWRCTL_CLK_FREQ_MASK 0xFFC00000 +#define PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT 22 + +#define PIPE3_PHY_TX_RX_POWERON 0x3 +#define PIPE3_PHY_TX_RX_POWEROFF 0x0 + /* * This is an Empirical value that works, need to confirm the actual * value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status @@ -86,8 +95,10 @@ struct ti_pipe3 { struct clk *refclk; struct clk *div_clk; struct pipe3_dpll_map *dpll_map; + struct regmap *phy_power_syscon; /* ctrl. reg. acces */ struct regmap *dpll_reset_syscon; /* ctrl. reg. acces */ unsigned int dpll_reset_reg; /* reg. index within syscon */ + unsigned int power_reg; /* power reg. index within syscon */ bool sata_refclk_enabled; }; @@ -144,20 +155,49 @@ static void ti_pipe3_disable_clocks(struct ti_pipe3 *phy); static int ti_pipe3_power_off(struct phy *x) { + u32 val; + int ret; struct ti_pipe3 *phy = phy_get_drvdata(x); - omap_control_phy_power(phy->control_dev, 0); + if (!phy->phy_power_syscon) { + omap_control_phy_power(phy->control_dev, 0); + return 0; + } - return 0; + val = PIPE3_PHY_TX_RX_POWEROFF << PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT; + + ret = regmap_update_bits(phy->phy_power_syscon, phy->power_reg, + PIPE3_PHY_PWRCTL_CLK_CMD_MASK, val); + return ret; } static int ti_pipe3_power_on(struct phy *x) { + u32 val; + u32 mask; + int ret; + unsigned long rate; struct ti_pipe3 *phy = phy_get_drvdata(x); - omap_control_phy_power(phy->control_dev, 1); + if (!phy->phy_power_syscon) { + omap_control_phy_power(phy->control_dev, 1); + return 0; + } - return 0; + rate = clk_get_rate(phy->sys_clk); + if (!rate) { + dev_err(phy->dev, "Invalid clock rate\n"); + return -EINVAL; + } + rate = rate / 1000000; + mask = OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK | + OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK; + val = PIPE3_PHY_TX_RX_POWERON << PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT; + val |= rate << OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT; + + ret = regmap_update_bits(phy->phy_power_syscon, phy->power_reg, + mask, val); + return ret; } static int ti_pipe3_dpll_wait_lock(struct ti_pipe3 *phy) @@ -334,7 +374,8 @@ static int ti_pipe3_get_clk(struct ti_pipe3 *phy) phy->wkupclk = ERR_PTR(-ENODEV); } - if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { + if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie") || + phy->phy_power_syscon) { phy->sys_clk = devm_clk_get(dev, "sysclk"); if (IS_ERR(phy->sys_clk)) { dev_err(dev, "unable to get sysclk\n"); @@ -383,19 +424,36 @@ static int ti_pipe3_get_sysctrl(struct ti_pipe3 *phy) struct device_node *control_node; struct platform_device *control_pdev; - control_node = of_parse_phandle(node, "ctrl-module", 0); - if (!control_node) { - dev_err(dev, "Failed to get control device phandle\n"); - return -EINVAL; + phy->phy_power_syscon = syscon_regmap_lookup_by_phandle(node, + "syscon-phy-power"); + if (IS_ERR(phy->phy_power_syscon)) { + dev_dbg(dev, + "can't get syscon-phy-power, using control device\n"); + phy->phy_power_syscon = NULL; + } else { + if (of_property_read_u32_index(node, + "syscon-phy-power", 1, + &phy->power_reg)) { + dev_err(dev, "couldn't get power reg. offset\n"); + return -EINVAL; + } } - control_pdev = of_find_device_by_node(control_node); - if (!control_pdev) { - dev_err(dev, "Failed to get control device\n"); - return -EINVAL; - } + if (!phy->phy_power_syscon) { + control_node = of_parse_phandle(node, "ctrl-module", 0); + if (!control_node) { + dev_err(dev, "Failed to get control device phandle\n"); + return -EINVAL; + } - phy->control_dev = &control_pdev->dev; + control_pdev = of_find_device_by_node(control_node); + if (!control_pdev) { + dev_err(dev, "Failed to get control device\n"); + return -EINVAL; + } + + phy->control_dev = &control_pdev->dev; + } if (of_device_is_compatible(node, "ti,phy-pipe3-sata")) { phy->dpll_reset_syscon = syscon_regmap_lookup_by_phandle(node, -- GitLab From 3f2362c56f7ab0bf2ca1281227ca61f77c0c63fd Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Mon, 21 Dec 2015 14:24:11 +0530 Subject: [PATCH 1753/2855] phy: ti-pipe3: use *syscon* framework API to set PCS value of the PHY Deprecate using phy-omap-control driver to set PCS value of the PHY and start using *syscon* API to do the same. Signed-off-by: Kishon Vijay Abraham I Acked-by: Roger Quadros Acked-by: Rob Herring --- .../devicetree/bindings/phy/ti-phy.txt | 2 ++ drivers/phy/phy-ti-pipe3.c | 34 +++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/ti-phy.txt b/Documentation/devicetree/bindings/phy/ti-phy.txt index e06f980fa2ba6..49e5b0c6ed877 100644 --- a/Documentation/devicetree/bindings/phy/ti-phy.txt +++ b/Documentation/devicetree/bindings/phy/ti-phy.txt @@ -83,6 +83,8 @@ Optional properties: - syscon-pllreset: Handle to system control region that contains the CTRL_CORE_SMA_SW_0 register and register offset to the CTRL_CORE_SMA_SW_0 register that contains the SATA_PLL_SOFT_RESET bit. Only valid for sata_phy. + - syscon-pcs : phandle/offset pair. Phandle to the system control module and the + register offset to write the PCS delay value. Deprecated properties: - ctrl-module : phandle of the control module used by PHY driver to power on diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index a47b1902a36fd..0a477d24cf763 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c @@ -65,6 +65,9 @@ #define PIPE3_PHY_TX_RX_POWERON 0x3 #define PIPE3_PHY_TX_RX_POWEROFF 0x0 +#define PCIE_PCS_MASK 0xFF0000 +#define PCIE_PCS_DELAY_COUNT_SHIFT 0x10 + /* * This is an Empirical value that works, need to confirm the actual * value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status @@ -96,9 +99,11 @@ struct ti_pipe3 { struct clk *div_clk; struct pipe3_dpll_map *dpll_map; struct regmap *phy_power_syscon; /* ctrl. reg. acces */ + struct regmap *pcs_syscon; /* ctrl. reg. acces */ struct regmap *dpll_reset_syscon; /* ctrl. reg. acces */ unsigned int dpll_reset_reg; /* reg. index within syscon */ unsigned int power_reg; /* power reg. index within syscon */ + unsigned int pcie_pcs_reg; /* pcs reg. index in syscon */ bool sata_refclk_enabled; }; @@ -269,8 +274,15 @@ static int ti_pipe3_init(struct phy *x) * 18-1804. */ if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) { - omap_control_pcie_pcs(phy->control_dev, 0x96); - return 0; + if (!phy->pcs_syscon) { + omap_control_pcie_pcs(phy->control_dev, 0x96); + return 0; + } + + val = 0x96 << OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT; + ret = regmap_update_bits(phy->pcs_syscon, phy->pcie_pcs_reg, + PCIE_PCS_MASK, val); + return ret; } /* Bring it out of IDLE if it is IDLE */ @@ -455,6 +467,24 @@ static int ti_pipe3_get_sysctrl(struct ti_pipe3 *phy) phy->control_dev = &control_pdev->dev; } + if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { + phy->pcs_syscon = syscon_regmap_lookup_by_phandle(node, + "syscon-pcs"); + if (IS_ERR(phy->pcs_syscon)) { + dev_dbg(dev, + "can't get syscon-pcs, using omap control\n"); + phy->pcs_syscon = NULL; + } else { + if (of_property_read_u32_index(node, + "syscon-pcs", 1, + &phy->pcie_pcs_reg)) { + dev_err(dev, + "couldn't get pcie pcs reg. offset\n"); + return -EINVAL; + } + } + } + if (of_device_is_compatible(node, "ti,phy-pipe3-sata")) { phy->dpll_reset_syscon = syscon_regmap_lookup_by_phandle(node, "syscon-pllreset"); -- GitLab From 86c574e4bc9d840b8501cf604ea08d98fbd2c23c Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Mon, 21 Dec 2015 14:24:12 +0530 Subject: [PATCH 1754/2855] phy: omap-usb2: use omap_usb_power_off to power off the PHY during probe No functional change. Previously omap_control_phy_power() was used to power off the PHY during probe. But once phy-omap-usb2 driver is adapted to use syscon, omap_control_phy_power() cannot be used. Hence used omap_usb_power_off to power off the PHY. Signed-off-by: Kishon Vijay Abraham I Acked-by: Roger Quadros --- drivers/phy/phy-omap-usb2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c index 0fe80589ffbea..c79633efd7fcf 100644 --- a/drivers/phy/phy-omap-usb2.c +++ b/drivers/phy/phy-omap-usb2.c @@ -241,7 +241,6 @@ static int omap_usb2_probe(struct platform_device *pdev) } phy->control_dev = &control_pdev->dev; - omap_control_phy_power(phy->control_dev, 0); otg->set_host = omap_usb_set_host; otg->set_peripheral = omap_usb_set_peripheral; @@ -261,6 +260,7 @@ static int omap_usb2_probe(struct platform_device *pdev) } phy_set_drvdata(generic_phy, phy); + omap_usb_power_off(generic_phy); phy_provider = devm_of_phy_provider_register(phy->dev, of_phy_simple_xlate); -- GitLab From 9955a7835bf376e12482583958b2661f501b868b Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Mon, 21 Dec 2015 14:24:13 +0530 Subject: [PATCH 1755/2855] phy: omap-usb2: use *syscon* framework API to power on/off the PHY Deprecate using phy-omap-control driver to power on/off the PHY, and use *syscon* framework to do the same. This handles powering on/off the PHY for the USB2 PHYs used in various TI SoCs. Signed-off-by: Kishon Vijay Abraham I --- .../devicetree/bindings/phy/ti-phy.txt | 8 +- drivers/phy/phy-omap-usb2.c | 92 +++++++++++++++---- include/linux/phy/omap_usb.h | 23 +++++ 3 files changed, 105 insertions(+), 18 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/ti-phy.txt b/Documentation/devicetree/bindings/phy/ti-phy.txt index 49e5b0c6ed877..a3b394587874d 100644 --- a/Documentation/devicetree/bindings/phy/ti-phy.txt +++ b/Documentation/devicetree/bindings/phy/ti-phy.txt @@ -31,6 +31,8 @@ OMAP USB2 PHY Required properties: - compatible: Should be "ti,omap-usb2" + Should be "ti,dra7x-usb2-phy2" for the 2nd instance of USB2 PHY + in DRA7x - reg : Address and length of the register set for the device. - #phy-cells: determine the number of cells that should be given in the phandle while referencing this phy. @@ -40,10 +42,14 @@ Required properties: * "wkupclk" - wakeup clock. * "refclk" - reference clock (optional). -Optional properties: +Deprecated properties: - ctrl-module : phandle of the control module used by PHY driver to power on the PHY. +Recommended properies: +- syscon-phy-power : phandle/offset pair. Phandle to the system control + module and the register offset to power on/off the PHY. + This is usually a subnode of ocp2scp to which it is connected. usb2phy@4a0ad080 { diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c index c79633efd7fcf..c134989052f5e 100644 --- a/drivers/phy/phy-omap-usb2.c +++ b/drivers/phy/phy-omap-usb2.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #define USB2PHY_DISCON_BYP_LATCH (1 << 31) @@ -97,22 +99,38 @@ static int omap_usb_set_peripheral(struct usb_otg *otg, return 0; } +static int omap_usb_phy_power(struct omap_usb *phy, int on) +{ + u32 val; + int ret; + + if (!phy->syscon_phy_power) { + omap_control_phy_power(phy->control_dev, on); + return 0; + } + + if (on) + val = phy->power_on; + else + val = phy->power_off; + + ret = regmap_update_bits(phy->syscon_phy_power, phy->power_reg, + phy->mask, val); + return ret; +} + static int omap_usb_power_off(struct phy *x) { struct omap_usb *phy = phy_get_drvdata(x); - omap_control_phy_power(phy->control_dev, 0); - - return 0; + return omap_usb_phy_power(phy, false); } static int omap_usb_power_on(struct phy *x) { struct omap_usb *phy = phy_get_drvdata(x); - omap_control_phy_power(phy->control_dev, 1); - - return 0; + return omap_usb_phy_power(phy, true); } static int omap_usb_init(struct phy *x) @@ -147,21 +165,38 @@ static const struct phy_ops ops = { static const struct usb_phy_data omap_usb2_data = { .label = "omap_usb2", .flags = OMAP_USB2_HAS_START_SRP | OMAP_USB2_HAS_SET_VBUS, + .mask = OMAP_DEV_PHY_PD, + .power_off = OMAP_DEV_PHY_PD, }; static const struct usb_phy_data omap5_usb2_data = { .label = "omap5_usb2", .flags = 0, + .mask = OMAP_DEV_PHY_PD, + .power_off = OMAP_DEV_PHY_PD, }; static const struct usb_phy_data dra7x_usb2_data = { .label = "dra7x_usb2", .flags = OMAP_USB2_CALIBRATE_FALSE_DISCONNECT, + .mask = OMAP_DEV_PHY_PD, + .power_off = OMAP_DEV_PHY_PD, +}; + +static const struct usb_phy_data dra7x_usb2_phy2_data = { + .label = "dra7x_usb2_phy2", + .flags = OMAP_USB2_CALIBRATE_FALSE_DISCONNECT, + .mask = OMAP_USB2_PHY_PD, + .power_off = OMAP_USB2_PHY_PD, }; static const struct usb_phy_data am437x_usb2_data = { .label = "am437x_usb2", .flags = 0, + .mask = AM437X_USB2_PHY_PD | AM437X_USB2_OTG_PD | + AM437X_USB2_OTGVDET_EN | AM437X_USB2_OTGSESSEND_EN, + .power_on = AM437X_USB2_OTGVDET_EN | AM437X_USB2_OTGSESSEND_EN, + .power_off = AM437X_USB2_PHY_PD | AM437X_USB2_OTG_PD, }; static const struct of_device_id omap_usb2_id_table[] = { @@ -177,6 +212,10 @@ static const struct of_device_id omap_usb2_id_table[] = { .compatible = "ti,dra7x-usb2", .data = &dra7x_usb2_data, }, + { + .compatible = "ti,dra7x-usb2-phy2", + .data = &dra7x_usb2_phy2_data, + }, { .compatible = "ti,am437x-usb2", .data = &am437x_usb2_data, @@ -219,6 +258,9 @@ static int omap_usb2_probe(struct platform_device *pdev) phy->phy.label = phy_data->label; phy->phy.otg = otg; phy->phy.type = USB_PHY_TYPE_USB2; + phy->mask = phy_data->mask; + phy->power_on = phy_data->power_on; + phy->power_off = phy_data->power_off; if (phy_data->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) { res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -228,20 +270,36 @@ static int omap_usb2_probe(struct platform_device *pdev) phy->flags |= OMAP_USB2_CALIBRATE_FALSE_DISCONNECT; } - control_node = of_parse_phandle(node, "ctrl-module", 0); - if (!control_node) { - dev_err(&pdev->dev, "Failed to get control device phandle\n"); - return -EINVAL; - } + phy->syscon_phy_power = syscon_regmap_lookup_by_phandle(node, + "syscon-phy-power"); + if (IS_ERR(phy->syscon_phy_power)) { + dev_dbg(&pdev->dev, + "can't get syscon-phy-power, using control device\n"); + phy->syscon_phy_power = NULL; + + control_node = of_parse_phandle(node, "ctrl-module", 0); + if (!control_node) { + dev_err(&pdev->dev, + "Failed to get control device phandle\n"); + return -EINVAL; + } - control_pdev = of_find_device_by_node(control_node); - if (!control_pdev) { - dev_err(&pdev->dev, "Failed to get control device\n"); - return -EINVAL; + control_pdev = of_find_device_by_node(control_node); + if (!control_pdev) { + dev_err(&pdev->dev, "Failed to get control device\n"); + return -EINVAL; + } + phy->control_dev = &control_pdev->dev; + } else { + if (of_property_read_u32_index(node, + "syscon-phy-power", 1, + &phy->power_reg)) { + dev_err(&pdev->dev, + "couldn't get power reg. offset\n"); + return -EINVAL; + } } - phy->control_dev = &control_pdev->dev; - otg->set_host = omap_usb_set_host; otg->set_peripheral = omap_usb_set_peripheral; if (phy_data->flags & OMAP_USB2_HAS_SET_VBUS) diff --git a/include/linux/phy/omap_usb.h b/include/linux/phy/omap_usb.h index dc2c541a619b8..2e5fb870efa9f 100644 --- a/include/linux/phy/omap_usb.h +++ b/include/linux/phy/omap_usb.h @@ -30,6 +30,12 @@ struct usb_dpll_params { u32 mf; }; +enum omap_usb_phy_type { + TYPE_USB2, /* USB2_PHY, power down in CONTROL_DEV_CONF */ + TYPE_DRA7USB2, /* USB2 PHY, power and power_aux e.g. DRA7 */ + TYPE_AM437USB2, /* USB2 PHY, power e.g. AM437x */ +}; + struct omap_usb { struct usb_phy phy; struct phy_companion *comparator; @@ -40,11 +46,20 @@ struct omap_usb { struct clk *wkupclk; struct clk *optclk; u8 flags; + enum omap_usb_phy_type type; + struct regmap *syscon_phy_power; /* ctrl. reg. acces */ + unsigned int power_reg; /* power reg. index within syscon */ + u32 mask; + u32 power_on; + u32 power_off; }; struct usb_phy_data { const char *label; u8 flags; + u32 mask; + u32 power_on; + u32 power_off; }; /* Driver Flags */ @@ -52,6 +67,14 @@ struct usb_phy_data { #define OMAP_USB2_HAS_SET_VBUS (1 << 1) #define OMAP_USB2_CALIBRATE_FALSE_DISCONNECT (1 << 2) +#define OMAP_DEV_PHY_PD BIT(0) +#define OMAP_USB2_PHY_PD BIT(28) + +#define AM437X_USB2_PHY_PD BIT(0) +#define AM437X_USB2_OTG_PD BIT(1) +#define AM437X_USB2_OTGVDET_EN BIT(19) +#define AM437X_USB2_OTGSESSEND_EN BIT(20) + #define phy_to_omapusb(x) container_of((x), struct omap_usb, phy) #if defined(CONFIG_OMAP_USB2) || defined(CONFIG_OMAP_USB2_MODULE) -- GitLab From 2048157ad02e65f6327118dd4a7b9c9f1fd12f77 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 21 Dec 2015 12:21:22 -0800 Subject: [PATCH 1756/2855] Drivers: hv: vmbus: fix the building warning with hyperv-keyboard With the recent change af3ff643ea91ba64dd8d0b1cbed54d44512f96cd (Drivers: hv: vmbus: Use uuid_le type consistently), we always get this warning: CC [M] drivers/input/serio/hyperv-keyboard.o drivers/input/serio/hyperv-keyboard.c:427:2: warning: missing braces around initializer [-Wmissing-braces] { HV_KBD_GUID, }, ^ drivers/input/serio/hyperv-keyboard.c:427:2: warning: (near initialization for .id_table[0].guid.b.) [-Wmissing-braces] The patch fixes the warning. Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/input/serio/hyperv-keyboard.c | 10 ---------- include/linux/hyperv.h | 8 ++++++++ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c index e74e5d6e5f9f6..c948866edf870 100644 --- a/drivers/input/serio/hyperv-keyboard.c +++ b/drivers/input/serio/hyperv-keyboard.c @@ -412,16 +412,6 @@ static int hv_kbd_remove(struct hv_device *hv_dev) return 0; } -/* - * Keyboard GUID - * {f912ad6d-2b17-48ea-bd65-f927a61c7684} - */ -#define HV_KBD_GUID \ - .guid = { \ - 0x6d, 0xad, 0x12, 0xf9, 0x17, 0x2b, 0xea, 0x48, \ - 0xbd, 0x65, 0xf9, 0x27, 0xa6, 0x1c, 0x76, 0x84 \ - } - static const struct hv_vmbus_device_id id_table[] = { /* Keyboard guid */ { HV_KBD_GUID, }, diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 179ff330af597..753dbad0bf943 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1078,6 +1078,14 @@ u64 hv_do_hypercall(u64 control, void *input, void *output); .guid = UUID_LE(0xcfa8b69e, 0x5b4a, 0x4cc0, 0xb9, 0x8b, \ 0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a) +/* + * Keyboard GUID + * {f912ad6d-2b17-48ea-bd65-f927a61c7684} + */ +#define HV_KBD_GUID \ + .guid = UUID_LE(0xf912ad6d, 0x2b17, 0x48ea, 0xbd, 0x65, \ + 0xf9, 0x27, 0xa6, 0x1c, 0x76, 0x84) + /* * VSS (Backup/Restore) GUID */ -- GitLab From 77b744a598d604de49df79cf161bbd1809a6948a Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Tue, 15 Dec 2015 16:27:26 -0800 Subject: [PATCH 1757/2855] Drivers: hv: utils: fix hvt_op_poll() return value on transport destroy The return type of hvt_op_poll() is unsigned int and -EBADF is inappropriate, poll functions return POLL* statuses. Reported-by: Dexuan Cui Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_utils_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hv/hv_utils_transport.c b/drivers/hv/hv_utils_transport.c index ee20b50742385..4f42c0e20c20f 100644 --- a/drivers/hv/hv_utils_transport.c +++ b/drivers/hv/hv_utils_transport.c @@ -109,7 +109,7 @@ static unsigned int hvt_op_poll(struct file *file, poll_table *wait) poll_wait(file, &hvt->outmsg_q, wait); if (hvt->mode == HVUTIL_TRANSPORT_DESTROY) - return -EBADF; + return POLLERR | POLLHUP; if (hvt->outmsg_len > 0) return POLLIN | POLLRDNORM; -- GitLab From 879a650a273bc3efb9d472886b8ced12630ea8ed Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 15 Dec 2015 16:27:27 -0800 Subject: [PATCH 1758/2855] Drivers: hv: vmbus: Treat Fibre Channel devices as performance critical For performance critical devices, we distribute the incoming channel interrupt load across available CPUs in the guest. Include Fibre channel devices in the set of devices for which we would distribute the interrupt load. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel_mgmt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index d0131717c1d5d..1c1ad47042c5d 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -361,6 +361,7 @@ err_free_chan: enum { IDE = 0, SCSI, + FC, NIC, ND_NIC, PCIE, @@ -377,6 +378,8 @@ static const struct hv_vmbus_device_id hp_devs[] = { { HV_IDE_GUID, }, /* Storage - SCSI */ { HV_SCSI_GUID, }, + /* Storage - FC */ + { HV_SYNTHFC_GUID, }, /* Network */ { HV_NIC_GUID, }, /* NetworkDirect Guest RDMA */ -- GitLab From c6e3a5b3ef16b9e1498daa41645c728ee6e5285c Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:05 +0900 Subject: [PATCH 1759/2855] staging: wilc1000: remove define COMPLEMENT_BOOT This patch removes define COMPLEMENT_BOOT in Makefile. The feature was removed by commit b46d68825c2d ('staging: wilc1000: remove COMPLEMENT_BOOT') but the define was not removed. So remove completely. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile index 198d536da57c5..c55fdd2fa734b 100644 --- a/drivers/staging/wilc1000/Makefile +++ b/drivers/staging/wilc1000/Makefile @@ -1,7 +1,5 @@ obj-$(CONFIG_WILC1000) += wilc1000.o -ccflags-$(CONFIG_WILC1000_SDIO) += -DCOMPLEMENT_BOOT - ccflags-y += -DSTA_FIRMWARE=\"atmel/wilc1000_fw.bin\" \ -DAP_FIRMWARE=\"atmel/wilc1000_ap_fw.bin\" \ -DP2P_CONCURRENCY_FIRMWARE=\"atmel/wilc1000_p2p_fw.bin\" -- GitLab From a5038d56f86011af0d1dcaac56e8507ef5c8f6cf Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:06 +0900 Subject: [PATCH 1760/2855] staging: wilc1000: remove wilc memory allocation config This patch remove memory allocation options in Kconfig. It was used a long time ago to aquire memory, which we will not use this config anymore. Remove it's config, related define and codes as well. We will take PREALLOCATE_AT_LOADING_DRIVER as it is default. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/Kconfig | 22 -------------- drivers/staging/wilc1000/Makefile | 6 ---- drivers/staging/wilc1000/linux_wlan_common.h | 2 -- drivers/staging/wilc1000/wilc_wlan.c | 30 -------------------- 4 files changed, 60 deletions(-) diff --git a/drivers/staging/wilc1000/Kconfig b/drivers/staging/wilc1000/Kconfig index 2923122346eff..dce9cee9134a7 100644 --- a/drivers/staging/wilc1000/Kconfig +++ b/drivers/staging/wilc1000/Kconfig @@ -31,28 +31,6 @@ config WILC1000_SPI immediately following reset when pin 9 (SDIO_SPI_CFG) is tied to VDDIO. Select this if your platform is using the SPI bus. -choice - prompt "WILC1000 Memory Allocation" - depends on WILC1000 - default WILC1000_PREALLOCATE_AT_LOADING_DRIVER - -config WILC1000_PREALLOCATE_AT_LOADING_DRIVER - bool "Preallocate memory at loading driver" - ---help--- - This choice supports static allocation of the memory - for the receive buffer. The driver will allocate the RX buffer - during initial time. The driver will also free the buffer - by calling network device stop. - -config WILC1000_DYNAMICALLY_ALLOCATE_MEMROY - bool "Dynamically allocate memory in real time" - ---help--- - This choice supports dynamic allocation of the memory - for the receive buffer. The driver will allocate the RX buffer - when it is required. -endchoice - - config WILC1000_HW_OOB_INTR bool "WILC1000 out of band interrupt" depends on WILC1000_SDIO diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile index c55fdd2fa734b..cd71be9ebc8c9 100644 --- a/drivers/staging/wilc1000/Makefile +++ b/drivers/staging/wilc1000/Makefile @@ -7,12 +7,6 @@ ccflags-y += -DSTA_FIRMWARE=\"atmel/wilc1000_fw.bin\" \ ccflags-y += -I$(src)/ -D__CHECK_ENDIAN__ -DWILC_ASIC_A0 -DWILC_DEBUGFS #ccflags-y += -DTCP_ACK_FILTER -ccflags-$(CONFIG_WILC1000_PREALLOCATE_AT_LOADING_DRIVER) += -DMEMORY_STATIC \ - -DWILC_PREALLOC_AT_INSMOD - -ccflags-$(CONFIG_WILC1000_DYNAMICALLY_ALLOCATE_MEMROY) += -DWILC_NORMAL_ALLOC - - wilc1000-objs := wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \ wilc_msgqueue.o \ coreconfigurator.o host_interface.o \ diff --git a/drivers/staging/wilc1000/linux_wlan_common.h b/drivers/staging/wilc1000/linux_wlan_common.h index 72b524a98cbad..5d40f05124c1c 100644 --- a/drivers/staging/wilc1000/linux_wlan_common.h +++ b/drivers/staging/wilc1000/linux_wlan_common.h @@ -124,9 +124,7 @@ extern atomic_t WILC_DEBUG_LEVEL; #define FN_IN /* PRINT_D(">>> \n") */ #define FN_OUT /* PRINT_D("<<<\n") */ -#ifdef MEMORY_STATIC #define LINUX_RX_SIZE (96 * 1024) -#endif #define LINUX_TX_SIZE (64 * 1024) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index a73e99f64f27c..10def3f1c773f 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -12,10 +12,8 @@ typedef struct { u32 cfg_frame_offset; int cfg_seq_no; - #ifdef MEMORY_STATIC u8 *rx_buffer; u32 rx_buffer_offset; - #endif u8 *tx_buffer; u32 tx_buffer_offset; @@ -1050,9 +1048,6 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) if (offset >= size) break; } while (1); -#ifndef MEMORY_STATIC - kfree(buffer); -#endif kfree(rqe); if (has_packet) @@ -1097,9 +1092,7 @@ static void wilc_sleeptimer_isr_ext(struct wilc *wilc, u32 int_stats1) static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) { wilc_wlan_dev_t *p = &g_wlan; -#ifdef MEMORY_STATIC u32 offset = p->rx_buffer_offset; -#endif u8 *buffer = NULL; u32 size; u32 retries = 0; @@ -1118,7 +1111,6 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) } if (size > 0) { -#ifdef MEMORY_STATIC if (LINUX_RX_SIZE - offset < size) offset = 0; @@ -1129,13 +1121,6 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) goto _end_; } -#else - buffer = kmalloc(size, GFP_KERNEL); - if (!buffer) { - usleep_range(100 * 1000, 100 * 1000); - goto _end_; - } -#endif p->hif_func.hif_clear_int_ext(wilc, DATA_INT_CLR | ENABLE_RX_VMM); ret = p->hif_func.hif_block_rx_ext(wilc, 0, buffer, size); @@ -1146,10 +1131,8 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) } _end_: if (ret) { -#ifdef MEMORY_STATIC offset += size; p->rx_buffer_offset = offset; -#endif rqe = kmalloc(sizeof(*rqe), GFP_KERNEL); if (rqe) { rqe->buffer = buffer; @@ -1157,10 +1140,6 @@ _end_: PRINT_D(RX_DBG, "rxq entery Size= %d - Address = %p\n", rqe->buffer_size, rqe->buffer); wilc_wlan_rxq_add(wilc, rqe); } - } else { -#ifndef MEMORY_STATIC - kfree(buffer); -#endif } } wilc_wlan_handle_rxq(wilc); @@ -1442,16 +1421,11 @@ void wilc_wlan_cleanup(struct net_device *dev) rqe = wilc_wlan_rxq_remove(wilc); if (!rqe) break; -#ifndef MEMORY_STATIC - kfree(rqe->buffer); -#endif kfree(rqe); } while (1); - #ifdef MEMORY_STATIC kfree(p->rx_buffer); p->rx_buffer = NULL; - #endif kfree(p->tx_buffer); acquire_bus(wilc, ACQUIRE_AND_WAKEUP); @@ -1691,7 +1665,6 @@ int wilc_wlan_init(struct net_device *dev) goto _fail_; } -#if defined(MEMORY_STATIC) if (!g_wlan.rx_buffer) g_wlan.rx_buffer = kmalloc(LINUX_RX_SIZE, GFP_KERNEL); PRINT_D(TX_DBG, "g_wlan.rx_buffer =%p\n", g_wlan.rx_buffer); @@ -1700,7 +1673,6 @@ int wilc_wlan_init(struct net_device *dev) PRINT_ER("Can't allocate Rx Buffer"); goto _fail_; } -#endif if (!init_chip(dev)) { ret = -EIO; @@ -1714,10 +1686,8 @@ int wilc_wlan_init(struct net_device *dev) _fail_: - #ifdef MEMORY_STATIC kfree(g_wlan.rx_buffer); g_wlan.rx_buffer = NULL; - #endif kfree(g_wlan.tx_buffer); g_wlan.tx_buffer = NULL; -- GitLab From b719302da6da3480e9086121f9c27362382c0efe Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:07 +0900 Subject: [PATCH 1761/2855] staging: wilc1000: rename index to tcp_pending_ack_idx This patch renames "index" of struct txq_entry_t to tcp_pending_ack_idx since this name could be confused index of txq_entry_t. It is index of tcp pending ack. It fixes 8e55639d066f ("staging: wilc1000: rename tcp_PendingAck_index of struct txq_entry_t") Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 12 ++++++------ drivers/staging/wilc1000/wilc_wlan.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 10def3f1c773f..27a44ee576cb3 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -249,7 +249,7 @@ static inline int add_tcp_pending_ack(u32 ack, u32 session_index, pending_acks_info[pending_base + pending_acks].ack_num = ack; pending_acks_info[pending_base + pending_acks].txqe = txqe; pending_acks_info[pending_base + pending_acks].session_index = session_index; - txqe->index = pending_base + pending_acks; + txqe->tcp_pending_ack_idx = pending_base + pending_acks; pending_acks++; } return 0; @@ -421,7 +421,7 @@ static int wilc_wlan_txq_add_cfg_pkt(struct wilc *wilc, u8 *buffer, u32 buffer_s tqe->tx_complete_func = NULL; tqe->priv = NULL; #ifdef TCP_ACK_FILTER - tqe->index = NOT_TCP_ACK; + tqe->tcp_pending_ack_idx = NOT_TCP_ACK; #endif PRINT_D(TX_DBG, "Adding the config packet at the Queue tail\n"); @@ -451,7 +451,7 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, PRINT_D(TX_DBG, "Adding mgmt packet at the Queue tail\n"); #ifdef TCP_ACK_FILTER - tqe->index = NOT_TCP_ACK; + tqe->tcp_pending_ack_idx = NOT_TCP_ACK; if (is_tcp_ack_filter_enabled()) tcp_process(dev, tqe); #endif @@ -478,7 +478,7 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, tqe->tx_complete_func = func; tqe->priv = priv; #ifdef TCP_ACK_FILTER - tqe->index = NOT_TCP_ACK; + tqe->tcp_pending_ack_idx = NOT_TCP_ACK; #endif PRINT_D(TX_DBG, "Adding Network packet at the Queue tail\n"); wilc_wlan_txq_add_to_tail(dev, tqe); @@ -923,8 +923,8 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) tqe->tx_complete_func(tqe->priv, tqe->status); #ifdef TCP_ACK_FILTER - if (tqe->index != NOT_TCP_ACK) - pending_acks_info[tqe->index].txqe = NULL; + if (tqe->tcp_pending_ack_idx != NOT_TCP_ACK) + pending_acks_info[tqe->tcp_pending_ack_idx].txqe = NULL; #endif kfree(tqe); } else { diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 2ac63a3e092a1..27c7bbb17b33c 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -216,7 +216,7 @@ struct txq_entry_t { struct txq_entry_t *next; struct txq_entry_t *prev; int type; - int index; + int tcp_pending_ack_idx; u8 *buffer; int buffer_size; void *priv; -- GitLab From 9e6627ac727c0d8646085908d9d6c33c08390111 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:08 +0900 Subject: [PATCH 1762/2855] staging: wilc1000: use kernel define byte order macros This patch removes define BIG_ENDIAN and use kernel define byte order macros instead of swap itself. Remove unused BYTE_SWAP macro and __CHECK_ENDIAN__ in Makefile also. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/Makefile | 2 +- drivers/staging/wilc1000/wilc_sdio.c | 8 ++------ drivers/staging/wilc1000/wilc_spi.c | 16 ++++------------ drivers/staging/wilc1000/wilc_wlan.c | 22 ++++++---------------- drivers/staging/wilc1000/wilc_wlan.h | 11 ----------- drivers/staging/wilc1000/wilc_wlan_cfg.c | 16 +++------------- 6 files changed, 16 insertions(+), 59 deletions(-) diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile index cd71be9ebc8c9..207674376553e 100644 --- a/drivers/staging/wilc1000/Makefile +++ b/drivers/staging/wilc1000/Makefile @@ -4,7 +4,7 @@ ccflags-y += -DSTA_FIRMWARE=\"atmel/wilc1000_fw.bin\" \ -DAP_FIRMWARE=\"atmel/wilc1000_ap_fw.bin\" \ -DP2P_CONCURRENCY_FIRMWARE=\"atmel/wilc1000_p2p_fw.bin\" -ccflags-y += -I$(src)/ -D__CHECK_ENDIAN__ -DWILC_ASIC_A0 -DWILC_DEBUGFS +ccflags-y += -I$(src)/ -DWILC_ASIC_A0 -DWILC_DEBUGFS #ccflags-y += -DTCP_ACK_FILTER wilc1000-objs := wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \ diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index ff7990a0b5ec9..a9ad49f70d395 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -163,9 +163,7 @@ static int sdio_clear_int(struct wilc *wilc) ********************************************/ static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) { -#ifdef BIG_ENDIAN - data = BYTE_SWAP(data); -#endif + data = cpu_to_le32(data); if ((addr >= 0xf0) && (addr <= 0xff)) { sdio_cmd52_t cmd; @@ -330,9 +328,7 @@ static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) } } -#ifdef BIG_ENDIAN - *data = BYTE_SWAP(*data); -#endif + *data = cpu_to_le32(*data); return 1; diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index d6f412117fd87..c94d86f6cbeaa 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -529,9 +529,7 @@ static int spi_internal_write(struct wilc *wilc, u32 adr, u32 dat) { int result; -#ifdef BIG_ENDIAN - dat = BYTE_SWAP(dat); -#endif + dat = cpu_to_le32(dat); result = spi_cmd_complete(wilc, CMD_INTERNAL_WRITE, adr, (u8 *)&dat, 4, 0); if (result != N_OK) { @@ -552,9 +550,7 @@ static int spi_internal_read(struct wilc *wilc, u32 adr, u32 *data) return 0; } -#ifdef BIG_ENDIAN - *data = BYTE_SWAP(*data); -#endif + *data = cpu_to_le32(*data); return 1; } @@ -571,9 +567,7 @@ static int wilc_spi_write_reg(struct wilc *wilc, u32 addr, u32 data) u8 cmd = CMD_SINGLE_WRITE; u8 clockless = 0; -#ifdef BIG_ENDIAN - data = BYTE_SWAP(data); -#endif + data = cpu_to_le32(data); if (addr < 0x30) { /* Clockless register*/ cmd = CMD_INTERNAL_WRITE; @@ -635,9 +629,7 @@ static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data) return 0; } -#ifdef BIG_ENDIAN - *data = BYTE_SWAP(*data); -#endif + *data = cpu_to_le32(*data); return 1; } diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 27a44ee576cb3..a74a95e3830e4 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -759,9 +759,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) vmm_table[i] |= BIT(10); PRINT_D(TX_DBG, "VMMTable entry changed for CFG packet = %d\n", vmm_table[i]); } -#ifdef BIG_ENDIAN - vmm_table[i] = BYTE_SWAP(vmm_table[i]); -#endif + vmm_table[i] = cpu_to_le32(vmm_table[i]); i++; sum += vmm_sz; @@ -886,9 +884,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) if (tqe && (vmm_table[i] != 0)) { u32 header, buffer_offset; -#ifdef BIG_ENDIAN - vmm_table[i] = BYTE_SWAP(vmm_table[i]); -#endif + vmm_table[i] = cpu_to_le32(vmm_table[i]); vmm_sz = (vmm_table[i] & 0x3ff); vmm_sz *= 4; header = (tqe->type << 31) | @@ -899,9 +895,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) else header &= ~BIT(30); -#ifdef BIG_ENDIAN - header = BYTE_SWAP(header); -#endif + header = cpu_to_le32(header); memcpy(&txb[offset], &header, 4); if (tqe->type == WILC_CFG_PKT) { buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET; @@ -993,9 +987,7 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) PRINT_D(RX_DBG, "In the 2nd do-while\n"); memcpy(&header, &buffer[offset], 4); -#ifdef BIG_ENDIAN - header = BYTE_SWAP(header); -#endif + header = cpu_to_le32(header); PRINT_D(RX_DBG, "Header = %04x - Offset = %d\n", header, offset); @@ -1194,10 +1186,8 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, u32 buffer_ do { memcpy(&addr, &buffer[offset], 4); memcpy(&size, &buffer[offset + 4], 4); -#ifdef BIG_ENDIAN - addr = BYTE_SWAP(addr); - size = BYTE_SWAP(size); -#endif + addr = cpu_to_le32(addr); + size = cpu_to_le32(size); acquire_bus(wilc, ACQUIRE_ONLY); offset += 8; while (((int)size) && (offset < buffer_size)) { diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 27c7bbb17b33c..366645318ad27 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -35,17 +35,6 @@ #define ETH_CONFIG_PKT_HDR_OFFSET (ETH_ETHERNET_HDR_OFFSET + \ ETH_CONFIG_PKT_HDR_LEN) -/******************************************** - * - * Endian Conversion - * - ********************************************/ - -#define BYTE_SWAP(val) (((val & 0x000000FF) << 24) + \ - ((val & 0x0000FF00) << 8) + \ - ((val & 0x00FF0000) >> 8) + \ - ((val & 0xFF000000) >> 24)) - /******************************************** * * Register Defines diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.c b/drivers/staging/wilc1000/wilc_wlan_cfg.c index 274052f36400c..f62c0e696a018 100644 --- a/drivers/staging/wilc1000/wilc_wlan_cfg.c +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.c @@ -275,9 +275,7 @@ static void wilc_wlan_parse_response_frame(u8 *info, int size) while (size > 0) { i = 0; wid = info[0] | (info[1] << 8); -#ifdef BIG_ENDIAN - wid = BYTE_SWAP(wid); -#endif + wid = cpu_to_le32(wid); PRINT_INFO(GENERIC_DBG, "Processing response for %d seq %d\n", wid, seq++); switch ((wid >> 12) & 0x7) { case WID_CHAR: @@ -300,11 +298,7 @@ static void wilc_wlan_parse_response_frame(u8 *info, int size) break; if (g_cfg_hword[i].id == wid) { -#ifdef BIG_ENDIAN - g_cfg_hword[i].val = (info[3] << 8) | (info[4]); -#else - g_cfg_hword[i].val = info[3] | (info[4] << 8); -#endif + g_cfg_hword[i].val = cpu_to_le16(info[3] | (info[4] << 8)); break; } i++; @@ -318,11 +312,7 @@ static void wilc_wlan_parse_response_frame(u8 *info, int size) break; if (g_cfg_word[i].id == wid) { -#ifdef BIG_ENDIAN - g_cfg_word[i].val = (info[3] << 24) | (info[4] << 16) | (info[5] << 8) | (info[6]); -#else - g_cfg_word[i].val = info[3] | (info[4] << 8) | (info[5] << 16) | (info[6] << 24); -#endif + g_cfg_word[i].val = cpu_to_le32(info[3] | (info[4] << 8) | (info[5] << 16) | (info[6] << 24)); break; } i++; -- GitLab From af9ae09ae0704e2bea199e0d47f0734e06f232fa Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:09 +0900 Subject: [PATCH 1763/2855] staging: wilc1000: wilc_wlan.c: remove hif_func of wilc_wlan_dev_t hif_func of wilc_wlan_dev_t is duplicate because we have same struct wilc_hif_func ops of struct wilc which is available in wilc_wlan.c. Rename ops of struct wilc with hif_func and remove hif_func of wilc_wlan_dev_t, and use wilc->hif_func instead of g_wlan.hif_func in all functions. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 18 +- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 2 +- drivers/staging/wilc1000/wilc_wlan.c | 161 +++++++++--------- 3 files changed, 87 insertions(+), 94 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index d1c3e4c10d02e..92ca0723c8b6b 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -750,9 +750,9 @@ void wilc1000_wlan_deinit(struct net_device *dev) PRINT_D(INIT_DBG, "Disabling IRQ\n"); if (!wl->dev_irq_num && - wl->ops->disable_interrupt) { + wl->hif_func->disable_interrupt) { mutex_lock(&wl->hif_cs); - wl->ops->disable_interrupt(wl); + wl->hif_func->disable_interrupt(wl); mutex_unlock(&wl->hif_cs); } if (&wl->txq_event) @@ -770,12 +770,12 @@ void wilc1000_wlan_deinit(struct net_device *dev) wilc_wlan_cleanup(dev); #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31) if (!wl->dev_irq_num && - wl->ops->disable_interrupt) { + wl->hif_func->disable_interrupt) { PRINT_D(INIT_DBG, "Disabling IRQ 2\n"); mutex_lock(&wl->hif_cs); - wl->ops->disable_interrupt(wl); + wl->hif_func->disable_interrupt(wl); mutex_unlock(&wl->hif_cs); } #endif @@ -911,8 +911,8 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) } if (!wl->dev_irq_num && - wl->ops->enable_interrupt && - wl->ops->enable_interrupt(wl)) { + wl->hif_func->enable_interrupt && + wl->hif_func->enable_interrupt(wl)) { PRINT_ER("couldn't initialize IRQ\n"); ret = -EIO; goto _fail_irq_init_; @@ -964,8 +964,8 @@ _fail_fw_start_: _fail_irq_enable_: if (!wl->dev_irq_num && - wl->ops->disable_interrupt) - wl->ops->disable_interrupt(wl); + wl->hif_func->disable_interrupt) + wl->hif_func->disable_interrupt(wl); _fail_irq_init_: if (wl->dev_irq_num) deinit_irq(dev); @@ -1438,7 +1438,7 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, *wilc = wl; wl->io_type = io_type; wl->gpio = gpio; - wl->ops = ops; + wl->hif_func = ops; register_inetaddr_notifier(&g_dev_notifier); diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 212d607748e98..b593b64611600 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -156,7 +156,7 @@ struct wilc_vif { }; struct wilc { - const struct wilc_hif_func *ops; + const struct wilc_hif_func *hif_func; int io_type; int mac_status; int gpio; diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index a74a95e3830e4..b9bedc8010fc8 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -6,7 +6,6 @@ typedef struct { int quit; int io_type; - struct wilc_hif_func hif_func; int cfg_frame_in_use; struct wilc_cfg_frame cfg_frame; u32 cfg_frame_offset; @@ -564,9 +563,9 @@ static inline void chip_allow_sleep(struct wilc *wilc) { u32 reg = 0; - g_wlan.hif_func.hif_read_reg(wilc, 0xf0, ®); + wilc->hif_func->hif_read_reg(wilc, 0xf0, ®); - g_wlan.hif_func.hif_write_reg(wilc, 0xf0, reg & ~BIT(0)); + wilc->hif_func->hif_write_reg(wilc, 0xf0, reg & ~BIT(0)); } static inline void chip_wakeup(struct wilc *wilc) @@ -576,9 +575,9 @@ static inline void chip_wakeup(struct wilc *wilc) if ((g_wlan.io_type & 0x1) == HIF_SPI) { do { - g_wlan.hif_func.hif_read_reg(wilc, 1, ®); - g_wlan.hif_func.hif_write_reg(wilc, 1, reg | BIT(1)); - g_wlan.hif_func.hif_write_reg(wilc, 1, reg & ~BIT(1)); + wilc->hif_func->hif_read_reg(wilc, 1, ®); + wilc->hif_func->hif_write_reg(wilc, 1, reg | BIT(1)); + wilc->hif_func->hif_write_reg(wilc, 1, reg & ~BIT(1)); do { usleep_range(2 * 1000, 2 * 1000); @@ -589,44 +588,44 @@ static inline void chip_wakeup(struct wilc *wilc) } while (wilc_get_chipid(wilc, true) == 0); } else if ((g_wlan.io_type & 0x1) == HIF_SDIO) { - g_wlan.hif_func.hif_read_reg(wilc, 0xf0, ®); + wilc->hif_func->hif_read_reg(wilc, 0xf0, ®); do { - g_wlan.hif_func.hif_write_reg(wilc, 0xf0, + wilc->hif_func->hif_write_reg(wilc, 0xf0, reg | BIT(0)); - g_wlan.hif_func.hif_read_reg(wilc, 0xf1, + wilc->hif_func->hif_read_reg(wilc, 0xf1, &clk_status_reg); while (((clk_status_reg & 0x1) == 0) && (((++trials) % 3) == 0)) { usleep_range(2 * 1000, 2 * 1000); - g_wlan.hif_func.hif_read_reg(wilc, 0xf1, + wilc->hif_func->hif_read_reg(wilc, 0xf1, &clk_status_reg); if ((clk_status_reg & 0x1) == 0) wilc_debug(N_ERR, "clocks still OFF. Wake up failed\n"); } if ((clk_status_reg & 0x1) == 0) { - g_wlan.hif_func.hif_write_reg(wilc, 0xf0, + wilc->hif_func->hif_write_reg(wilc, 0xf0, reg & (~BIT(0))); } } while ((clk_status_reg & 0x1) == 0); } if (chip_ps_state == CHIP_SLEEPING_MANUAL) { - g_wlan.hif_func.hif_read_reg(wilc, 0x1C0C, ®); + wilc->hif_func->hif_read_reg(wilc, 0x1C0C, ®); reg &= ~BIT(0); - g_wlan.hif_func.hif_write_reg(wilc, 0x1C0C, reg); + wilc->hif_func->hif_write_reg(wilc, 0x1C0C, reg); if (wilc_get_chipid(wilc, false) >= 0x1002b0) { u32 val32; - g_wlan.hif_func.hif_read_reg(wilc, 0x1e1c, &val32); + wilc->hif_func->hif_read_reg(wilc, 0x1e1c, &val32); val32 |= BIT(6); - g_wlan.hif_func.hif_write_reg(wilc, 0x1e1c, val32); + wilc->hif_func->hif_write_reg(wilc, 0x1e1c, val32); - g_wlan.hif_func.hif_read_reg(wilc, 0x1e9c, &val32); + wilc->hif_func->hif_read_reg(wilc, 0x1e9c, &val32); val32 |= BIT(6); - g_wlan.hif_func.hif_write_reg(wilc, 0x1e9c, val32); + wilc->hif_func->hif_write_reg(wilc, 0x1e9c, val32); } } chip_ps_state = CHIP_WAKEDUP; @@ -638,17 +637,17 @@ static inline void chip_wakeup(struct wilc *wilc) do { if ((g_wlan.io_type & 0x1) == HIF_SPI) { - g_wlan.hif_func.hif_read_reg(wilc, 1, ®); - g_wlan.hif_func.hif_write_reg(wilc, 1, reg & ~BIT(1)); - g_wlan.hif_func.hif_write_reg(wilc, 1, reg | BIT(1)); - g_wlan.hif_func.hif_write_reg(wilc, 1, reg & ~BIT(1)); + wilc->hif_func->hif_read_reg(wilc, 1, ®); + wilc->hif_func->hif_write_reg(wilc, 1, reg & ~BIT(1)); + wilc->hif_func->hif_write_reg(wilc, 1, reg | BIT(1)); + wilc->hif_func->hif_write_reg(wilc, 1, reg & ~BIT(1)); } else if ((g_wlan.io_type & 0x1) == HIF_SDIO) { - g_wlan.hif_func.hif_read_reg(wilc, 0xf0, ®); - g_wlan.hif_func.hif_write_reg(wilc, 0xf0, + wilc->hif_func->hif_read_reg(wilc, 0xf0, ®); + wilc->hif_func->hif_write_reg(wilc, 0xf0, reg & ~BIT(0)); - g_wlan.hif_func.hif_write_reg(wilc, 0xf0, + wilc->hif_func->hif_write_reg(wilc, 0xf0, reg | BIT(0)); - g_wlan.hif_func.hif_write_reg(wilc, 0xf0, + wilc->hif_func->hif_write_reg(wilc, 0xf0, reg & ~BIT(0)); } @@ -663,20 +662,20 @@ static inline void chip_wakeup(struct wilc *wilc) } while (wilc_get_chipid(wilc, true) == 0); if (chip_ps_state == CHIP_SLEEPING_MANUAL) { - g_wlan.hif_func.hif_read_reg(wilc, 0x1C0C, ®); + wilc->hif_func->hif_read_reg(wilc, 0x1C0C, ®); reg &= ~BIT(0); - g_wlan.hif_func.hif_write_reg(wilc, 0x1C0C, reg); + wilc->hif_func->hif_write_reg(wilc, 0x1C0C, reg); if (wilc_get_chipid(wilc, false) >= 0x1002b0) { u32 val32; - g_wlan.hif_func.hif_read_reg(wilc, 0x1e1c, &val32); + wilc->hif_func->hif_read_reg(wilc, 0x1e1c, &val32); val32 |= BIT(6); - g_wlan.hif_func.hif_write_reg(wilc, 0x1e1c, val32); + wilc->hif_func->hif_write_reg(wilc, 0x1e1c, val32); - g_wlan.hif_func.hif_read_reg(wilc, 0x1e9c, &val32); + wilc->hif_func->hif_read_reg(wilc, 0x1e9c, &val32); val32 |= BIT(6); - g_wlan.hif_func.hif_write_reg(wilc, 0x1e9c, val32); + wilc->hif_func->hif_write_reg(wilc, 0x1e9c, val32); } } chip_ps_state = CHIP_WAKEDUP; @@ -691,7 +690,7 @@ void wilc_chip_sleep_manually(struct wilc *wilc) #ifdef WILC_OPTIMIZE_SLEEP_INT chip_allow_sleep(wilc); #endif - g_wlan.hif_func.hif_write_reg(wilc, 0x10a8, 1); + wilc->hif_func->hif_write_reg(wilc, 0x10a8, 1); chip_ps_state = CHIP_SLEEPING_MANUAL; release_bus(wilc, RELEASE_ONLY); @@ -780,7 +779,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) acquire_bus(wilc, ACQUIRE_AND_WAKEUP); counter = 0; do { - ret = p->hif_func.hif_read_reg(wilc, WILC_HOST_TX_CTRL, + ret = wilc->hif_func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, ®); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't read reg vmm_tbl_entry..\n"); @@ -795,7 +794,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) if (counter > 200) { counter = 0; PRINT_D(TX_DBG, "Looping in tx ctrl , forcce quit\n"); - ret = p->hif_func.hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0); + ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0); break; } PRINT_WRN(GENERIC_DBG, "[wilc txq]: warn, vmm table not clear yet, wait...\n"); @@ -810,13 +809,13 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) timeout = 200; do { - ret = p->hif_func.hif_block_tx(wilc, WILC_VMM_TBL_RX_SHADOW_BASE, (u8 *)vmm_table, ((i + 1) * 4)); + ret = wilc->hif_func->hif_block_tx(wilc, WILC_VMM_TBL_RX_SHADOW_BASE, (u8 *)vmm_table, ((i + 1) * 4)); if (!ret) { wilc_debug(N_ERR, "ERR block TX of VMM table.\n"); break; } - ret = p->hif_func.hif_write_reg(wilc, WILC_HOST_VMM_CTL, + ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x2); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't write reg host_vmm_ctl..\n"); @@ -824,7 +823,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) } do { - ret = p->hif_func.hif_read_reg(wilc, WILC_HOST_VMM_CTL, ®); + ret = wilc->hif_func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, ®); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't read reg host_vmm_ctl..\n"); break; @@ -840,7 +839,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) } } while (--timeout); if (timeout <= 0) { - ret = p->hif_func.hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0); + ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0); break; } @@ -850,13 +849,13 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) if (entries == 0) { PRINT_WRN(GENERIC_DBG, "[wilc txq]: no more buffer in the chip (reg: %08x), retry later [[ %d, %x ]]\n", reg, i, vmm_table[i - 1]); - ret = p->hif_func.hif_read_reg(wilc, WILC_HOST_TX_CTRL, ®); + ret = wilc->hif_func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, ®); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't read reg WILC_HOST_TX_CTRL..\n"); break; } reg &= ~BIT(0); - ret = p->hif_func.hif_write_reg(wilc, WILC_HOST_TX_CTRL, reg); + ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, reg); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't write reg WILC_HOST_TX_CTRL..\n"); break; @@ -928,13 +927,13 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) acquire_bus(wilc, ACQUIRE_AND_WAKEUP); - ret = p->hif_func.hif_clear_int_ext(wilc, ENABLE_TX_VMM); + ret = wilc->hif_func->hif_clear_int_ext(wilc, ENABLE_TX_VMM); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't start tx VMM ...\n"); goto _end_; } - ret = p->hif_func.hif_block_tx_ext(wilc, 0, txb, offset); + ret = wilc->hif_func->hif_block_tx_ext(wilc, 0, txb, offset); if (!ret) { wilc_debug(N_ERR, "[wilc txq]: fail can't block tx ext...\n"); goto _end_; @@ -1053,14 +1052,14 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) static void wilc_unknown_isr_ext(struct wilc *wilc) { - g_wlan.hif_func.hif_clear_int_ext(wilc, 0); + wilc->hif_func->hif_clear_int_ext(wilc, 0); } static void wilc_pllupdate_isr_ext(struct wilc *wilc, u32 int_stats) { int trials = 10; - g_wlan.hif_func.hif_clear_int_ext(wilc, PLL_INT_CLR); + wilc->hif_func->hif_clear_int_ext(wilc, PLL_INT_CLR); if (g_wlan.io_type == HIF_SDIO) mdelay(WILC_PLL_TO_SDIO); @@ -1075,7 +1074,7 @@ static void wilc_pllupdate_isr_ext(struct wilc *wilc, u32 int_stats) static void wilc_sleeptimer_isr_ext(struct wilc *wilc, u32 int_stats1) { - g_wlan.hif_func.hif_clear_int_ext(wilc, SLEEP_INT_CLR); + wilc->hif_func->hif_clear_int_ext(wilc, SLEEP_INT_CLR); #ifndef WILC_OPTIMIZE_SLEEP_INT chip_ps_state = CHIP_SLEEPING_AUTO; #endif @@ -1097,7 +1096,7 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) u32 time = 0; wilc_debug(N_ERR, "RX Size equal zero ... Trying to read it again for %d time\n", time++); - p->hif_func.hif_read_size(wilc, &size); + wilc->hif_func->hif_read_size(wilc, &size); size = ((size & 0x7fff) << 2); retries++; } @@ -1113,9 +1112,9 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) goto _end_; } - p->hif_func.hif_clear_int_ext(wilc, + wilc->hif_func->hif_clear_int_ext(wilc, DATA_INT_CLR | ENABLE_RX_VMM); - ret = p->hif_func.hif_block_rx_ext(wilc, 0, buffer, size); + ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size); if (!ret) { wilc_debug(N_ERR, "[wilc isr]: fail block rx...\n"); @@ -1142,7 +1141,7 @@ void wilc_handle_isr(struct wilc *wilc) u32 int_status; acquire_bus(wilc, ACQUIRE_AND_WAKEUP); - g_wlan.hif_func.hif_read_int(wilc, &int_status); + wilc->hif_func->hif_read_int(wilc, &int_status); if (int_status & PLL_INT_EXT) wilc_pllupdate_isr_ext(wilc, int_status); @@ -1165,7 +1164,6 @@ EXPORT_SYMBOL_GPL(wilc_handle_isr); int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, u32 buffer_size) { - wilc_wlan_dev_t *p = &g_wlan; u32 offset; u32 addr, size, size2, blksz; u8 *dma_buffer; @@ -1197,7 +1195,7 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, u32 buffer_ size2 = blksz; memcpy(dma_buffer, &buffer[offset], size2); - ret = p->hif_func.hif_block_tx(wilc, addr, dma_buffer, + ret = wilc->hif_func->hif_block_tx(wilc, addr, dma_buffer, size2); if (!ret) break; @@ -1239,7 +1237,7 @@ int wilc_wlan_start(struct wilc *wilc) reg = 1; } acquire_bus(wilc, ACQUIRE_ONLY); - ret = p->hif_func.hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg); + ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail write reg vmm_core_cfg...\n"); release_bus(wilc, RELEASE_ONLY); @@ -1273,7 +1271,7 @@ int wilc_wlan_start(struct wilc *wilc) reg |= WILC_HAVE_DISABLE_WILC_UART; #endif - ret = p->hif_func.hif_write_reg(wilc, WILC_GP_REG_1, reg); + ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail write WILC_GP_REG_1 ...\n"); release_bus(wilc, RELEASE_ONLY); @@ -1281,9 +1279,9 @@ int wilc_wlan_start(struct wilc *wilc) return ret; } - p->hif_func.hif_sync_ext(wilc, NUM_INT_EXT); + wilc->hif_func->hif_sync_ext(wilc, NUM_INT_EXT); - ret = p->hif_func.hif_read_reg(wilc, 0x1000, &chipid); + ret = wilc->hif_func->hif_read_reg(wilc, 0x1000, &chipid); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail read reg 0x1000 ...\n"); release_bus(wilc, RELEASE_ONLY); @@ -1291,16 +1289,16 @@ int wilc_wlan_start(struct wilc *wilc) return ret; } - p->hif_func.hif_read_reg(wilc, WILC_GLB_RESET_0, ®); + wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®); if ((reg & BIT(10)) == BIT(10)) { reg &= ~BIT(10); - p->hif_func.hif_write_reg(wilc, WILC_GLB_RESET_0, reg); - p->hif_func.hif_read_reg(wilc, WILC_GLB_RESET_0, ®); + wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg); + wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®); } reg |= BIT(10); - ret = p->hif_func.hif_write_reg(wilc, WILC_GLB_RESET_0, reg); - p->hif_func.hif_read_reg(wilc, WILC_GLB_RESET_0, ®); + ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg); + wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®); release_bus(wilc, RELEASE_ONLY); return (ret < 0) ? ret : 0; @@ -1308,22 +1306,18 @@ int wilc_wlan_start(struct wilc *wilc) void wilc_wlan_global_reset(struct wilc *wilc) { - - wilc_wlan_dev_t *p = &g_wlan; - acquire_bus(wilc, ACQUIRE_AND_WAKEUP); - p->hif_func.hif_write_reg(wilc, WILC_GLB_RESET_0, 0x0); + wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, 0x0); release_bus(wilc, RELEASE_ONLY); } int wilc_wlan_stop(struct wilc *wilc) { - wilc_wlan_dev_t *p = &g_wlan; u32 reg = 0; int ret; u8 timeout = 10; acquire_bus(wilc, ACQUIRE_AND_WAKEUP); - ret = p->hif_func.hif_read_reg(wilc, WILC_GLB_RESET_0, ®); + ret = wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®); if (!ret) { PRINT_ER("Error while reading reg\n"); release_bus(wilc, RELEASE_ALLOW_SLEEP); @@ -1331,7 +1325,7 @@ int wilc_wlan_stop(struct wilc *wilc) } reg &= ~BIT(10); - ret = p->hif_func.hif_write_reg(wilc, WILC_GLB_RESET_0, reg); + ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg); if (!ret) { PRINT_ER("Error while writing reg\n"); release_bus(wilc, RELEASE_ALLOW_SLEEP); @@ -1339,7 +1333,7 @@ int wilc_wlan_stop(struct wilc *wilc) } do { - ret = p->hif_func.hif_read_reg(wilc, WILC_GLB_RESET_0, ®); + ret = wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®); if (!ret) { PRINT_ER("Error while reading reg\n"); release_bus(wilc, RELEASE_ALLOW_SLEEP); @@ -1352,13 +1346,13 @@ int wilc_wlan_stop(struct wilc *wilc) PRINT_D(GENERIC_DBG, "Bit 10 not reset : Retry %d\n", timeout); reg &= ~BIT(10); - ret = p->hif_func.hif_write_reg(wilc, WILC_GLB_RESET_0, + ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg); timeout--; } else { PRINT_D(GENERIC_DBG, "Bit 10 reset after : Retry %d\n", timeout); - ret = p->hif_func.hif_read_reg(wilc, WILC_GLB_RESET_0, + ret = wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®); if (!ret) { PRINT_ER("Error while reading reg\n"); @@ -1374,10 +1368,10 @@ int wilc_wlan_stop(struct wilc *wilc) reg = (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(8) | BIT(9) | BIT(26) | BIT(29) | BIT(30) | BIT(31)); - p->hif_func.hif_write_reg(wilc, WILC_GLB_RESET_0, reg); + wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg); reg = (u32)~BIT(10); - ret = p->hif_func.hif_write_reg(wilc, WILC_GLB_RESET_0, reg); + ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg); release_bus(wilc, RELEASE_ALLOW_SLEEP); @@ -1420,20 +1414,20 @@ void wilc_wlan_cleanup(struct net_device *dev) acquire_bus(wilc, ACQUIRE_AND_WAKEUP); - ret = p->hif_func.hif_read_reg(wilc, WILC_GP_REG_0, ®); + ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, ®); if (!ret) { PRINT_ER("Error while reading reg\n"); release_bus(wilc, RELEASE_ALLOW_SLEEP); } PRINT_ER("Writing ABORT reg\n"); - ret = p->hif_func.hif_write_reg(wilc, WILC_GP_REG_0, + ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0, (reg | ABORT_INT)); if (!ret) { PRINT_ER("Error while writing reg\n"); release_bus(wilc, RELEASE_ALLOW_SLEEP); } release_bus(wilc, RELEASE_ALLOW_SLEEP); - p->hif_func.hif_deinit(NULL); + wilc->hif_func->hif_deinit(NULL); } static int wilc_wlan_cfg_commit(struct wilc *wilc, int type, u32 drv_handler) @@ -1566,18 +1560,18 @@ static u32 init_chip(struct net_device *dev) chipid = wilc_get_chipid(wilc, true); if ((chipid & 0xfff) != 0xa0) { - ret = g_wlan.hif_func.hif_read_reg(wilc, 0x1118, ®); + ret = wilc->hif_func->hif_read_reg(wilc, 0x1118, ®); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail read reg 0x1118 ...\n"); return ret; } reg |= BIT(0); - ret = g_wlan.hif_func.hif_write_reg(wilc, 0x1118, reg); + ret = wilc->hif_func->hif_write_reg(wilc, 0x1118, reg); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail write reg 0x1118 ...\n"); return ret; } - ret = g_wlan.hif_func.hif_write_reg(wilc, 0xc0000, 0x71); + ret = wilc->hif_func->hif_write_reg(wilc, 0xc0000, 0x71); if (!ret) { wilc_debug(N_ERR, "[wilc start]: fail write reg 0xc0000 ...\n"); return ret; @@ -1596,8 +1590,8 @@ u32 wilc_get_chipid(struct wilc *wilc, u8 update) u32 rfrevid; if (chipid == 0 || update != 0) { - g_wlan.hif_func.hif_read_reg(wilc, 0x1000, &tempchipid); - g_wlan.hif_func.hif_read_reg(wilc, 0x13f4, &rfrevid); + wilc->hif_func->hif_read_reg(wilc, 0x1000, &tempchipid); + wilc->hif_func->hif_read_reg(wilc, 0x13f4, &rfrevid); if (!ISWILC1000(tempchipid)) { chipid = 0; goto _fail_; @@ -1634,8 +1628,7 @@ int wilc_wlan_init(struct net_device *dev) memset((void *)&g_wlan, 0, sizeof(wilc_wlan_dev_t)); g_wlan.io_type = wilc->io_type; - g_wlan.hif_func = *wilc->ops; - if (!g_wlan.hif_func.hif_init(wilc, wilc_debug)) { + if (!wilc->hif_func->hif_init(wilc, wilc_debug)) { ret = -EIO; goto _fail_; } @@ -1695,7 +1688,7 @@ u16 wilc_set_machw_change_vir_if(struct net_device *dev, bool value) wilc = nic->wilc; mutex_lock(&wilc->hif_cs); - ret = (&g_wlan)->hif_func.hif_read_reg(wilc, WILC_CHANGING_VIR_IF, + ret = wilc->hif_func->hif_read_reg(wilc, WILC_CHANGING_VIR_IF, ®); if (!ret) PRINT_ER("Error while Reading reg WILC_CHANGING_VIR_IF\n"); @@ -1705,7 +1698,7 @@ u16 wilc_set_machw_change_vir_if(struct net_device *dev, bool value) else reg &= ~BIT(31); - ret = (&g_wlan)->hif_func.hif_write_reg(wilc, WILC_CHANGING_VIR_IF, + ret = wilc->hif_func->hif_write_reg(wilc, WILC_CHANGING_VIR_IF, reg); if (!ret) -- GitLab From a3629a9ee36a6f8fcbc764e811a2fe0e492f739f Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:10 +0900 Subject: [PATCH 1764/2855] staging: wilc1000: remove io_type of wilc_wlan_dev_t io_type of wilc_wlan_dev_t is unneeded, we can use io_type of struct wilc. Remove io_type of wilc_wlan_dev_t and use io_type of wilc. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index b9bedc8010fc8..37879cd40b49e 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -5,7 +5,6 @@ typedef struct { int quit; - int io_type; int cfg_frame_in_use; struct wilc_cfg_frame cfg_frame; u32 cfg_frame_offset; @@ -573,7 +572,7 @@ static inline void chip_wakeup(struct wilc *wilc) u32 reg, clk_status_reg, trials = 0; u32 sleep_time; - if ((g_wlan.io_type & 0x1) == HIF_SPI) { + if ((wilc->io_type & 0x1) == HIF_SPI) { do { wilc->hif_func->hif_read_reg(wilc, 1, ®); wilc->hif_func->hif_write_reg(wilc, 1, reg | BIT(1)); @@ -587,7 +586,7 @@ static inline void chip_wakeup(struct wilc *wilc) } while ((wilc_get_chipid(wilc, true) == 0) && ((++trials % 3) == 0)); } while (wilc_get_chipid(wilc, true) == 0); - } else if ((g_wlan.io_type & 0x1) == HIF_SDIO) { + } else if ((wilc->io_type & 0x1) == HIF_SDIO) { wilc->hif_func->hif_read_reg(wilc, 0xf0, ®); do { wilc->hif_func->hif_write_reg(wilc, 0xf0, @@ -636,12 +635,12 @@ static inline void chip_wakeup(struct wilc *wilc) u32 reg, trials = 0; do { - if ((g_wlan.io_type & 0x1) == HIF_SPI) { + if ((wilc->io_type & 0x1) == HIF_SPI) { wilc->hif_func->hif_read_reg(wilc, 1, ®); wilc->hif_func->hif_write_reg(wilc, 1, reg & ~BIT(1)); wilc->hif_func->hif_write_reg(wilc, 1, reg | BIT(1)); wilc->hif_func->hif_write_reg(wilc, 1, reg & ~BIT(1)); - } else if ((g_wlan.io_type & 0x1) == HIF_SDIO) { + } else if ((wilc->io_type & 0x1) == HIF_SDIO) { wilc->hif_func->hif_read_reg(wilc, 0xf0, ®); wilc->hif_func->hif_write_reg(wilc, 0xf0, reg & ~BIT(0)); @@ -1061,7 +1060,7 @@ static void wilc_pllupdate_isr_ext(struct wilc *wilc, u32 int_stats) wilc->hif_func->hif_clear_int_ext(wilc, PLL_INT_CLR); - if (g_wlan.io_type == HIF_SDIO) + if (wilc->io_type == HIF_SDIO) mdelay(WILC_PLL_TO_SDIO); else mdelay(WILC_PLL_TO_SPI); @@ -1225,15 +1224,14 @@ _fail_1: int wilc_wlan_start(struct wilc *wilc) { - wilc_wlan_dev_t *p = &g_wlan; u32 reg = 0; int ret; u32 chipid; - if (p->io_type == HIF_SDIO) { + if (wilc->io_type == HIF_SDIO) { reg = 0; reg |= BIT(3); - } else if (p->io_type == HIF_SPI) { + } else if (wilc->io_type == HIF_SPI) { reg = 1; } acquire_bus(wilc, ACQUIRE_ONLY); @@ -1245,7 +1243,7 @@ int wilc_wlan_start(struct wilc *wilc) return ret; } reg = 0; - if (p->io_type == HIF_SDIO && wilc->dev_irq_num) + if (wilc->io_type == HIF_SDIO && wilc->dev_irq_num) reg |= WILC_HAVE_SDIO_IRQ_GPIO; #ifdef WILC_DISABLE_PMU @@ -1627,7 +1625,6 @@ int wilc_wlan_init(struct net_device *dev) PRINT_D(INIT_DBG, "Initializing WILC_Wlan ...\n"); memset((void *)&g_wlan, 0, sizeof(wilc_wlan_dev_t)); - g_wlan.io_type = wilc->io_type; if (!wilc->hif_func->hif_init(wilc, wilc_debug)) { ret = -EIO; goto _fail_; -- GitLab From 21ee5092cab9f6512d8b73afe79a74433d2363fb Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:11 +0900 Subject: [PATCH 1765/2855] staging: wilc1000: remove unused varialbe tx_buffer_offset This patch removes unused variable tx_buffer_offset of wilc_wlan_dev_t. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 37879cd40b49e..502b49976290b 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -13,7 +13,6 @@ typedef struct { u8 *rx_buffer; u32 rx_buffer_offset; u8 *tx_buffer; - u32 tx_buffer_offset; unsigned long txq_spinlock_flags; -- GitLab From 67e2a07ed8008b81fdb98a998ceab66dc7af5999 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:12 +0900 Subject: [PATCH 1766/2855] staging: wilc1000: move all of wilc_wlan_dev_t to struct wilc linux_wlan.c and wilc_wlan.c was separated into two part at the beginning to support various platforms. They are in charge of send/receive control and packet data, so they will be merged into one file wlan.c later. First of all, wilc_wlan_dev_t which is used as global variable of wilc_wlan.c will be moved into struct wilc. This patch moves all members of wilc_wlan_dev_t to struct wilc and use wilc instead of g_wlan. Finally remove wilc_wlan_dev_t and g_wlan. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 22 ++ drivers/staging/wilc1000/wilc_wlan.c | 271 ++++++++---------- 2 files changed, 139 insertions(+), 154 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index b593b64611600..68a159f36f148 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -181,6 +181,28 @@ struct wilc { struct task_struct *txq_thread; + int quit; + int cfg_frame_in_use; + struct wilc_cfg_frame cfg_frame; + u32 cfg_frame_offset; + int cfg_seq_no; + + u8 *rx_buffer; + u32 rx_buffer_offset; + u8 *tx_buffer; + + unsigned long txq_spinlock_flags; + + struct txq_entry_t *txq_head; + struct txq_entry_t *txq_tail; + int txq_entries; + int txq_exit; + + struct rxq_entry_t *rxq_head; + struct rxq_entry_t *rxq_tail; + int rxq_entries; + int rxq_exit; + unsigned char eth_src_address[NUM_CONCURRENT_IFC][6]; const struct firmware *firmware; diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 502b49976290b..0427349354f4b 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -3,32 +3,6 @@ #include "wilc_wfi_netdevice.h" #include "wilc_wlan_cfg.h" -typedef struct { - int quit; - int cfg_frame_in_use; - struct wilc_cfg_frame cfg_frame; - u32 cfg_frame_offset; - int cfg_seq_no; - - u8 *rx_buffer; - u32 rx_buffer_offset; - u8 *tx_buffer; - - unsigned long txq_spinlock_flags; - - struct txq_entry_t *txq_head; - struct txq_entry_t *txq_tail; - int txq_entries; - int txq_exit; - - struct rxq_entry_t *rxq_head; - struct rxq_entry_t *rxq_tail; - int rxq_entries; - int rxq_exit; -} wilc_wlan_dev_t; - -static wilc_wlan_dev_t g_wlan; - #ifdef WILC_OPTIMIZE_SLEEP_INT static inline void chip_allow_sleep(struct wilc *wilc); #endif @@ -76,21 +50,20 @@ static inline void release_bus(struct wilc *wilc, BUS_RELEASE_T release) #ifdef TCP_ACK_FILTER static void wilc_wlan_txq_remove(struct txq_entry_t *tqe) { - wilc_wlan_dev_t *p = &g_wlan; - - if (tqe == p->txq_head) { - p->txq_head = tqe->next; - if (p->txq_head) - p->txq_head->prev = NULL; - } else if (tqe == p->txq_tail) { - p->txq_tail = (tqe->prev); - if (p->txq_tail) - p->txq_tail->next = NULL; + + if (tqe == wilc->txq_head) { + wilc->txq_head = tqe->next; + if (wilc->txq_head) + wilc->txq_head->prev = NULL; + } else if (tqe == wilc->txq_tail) { + wilc->txq_tail = (tqe->prev); + if (wilc->txq_tail) + wilc->txq_tail->next = NULL; } else { tqe->prev->next = tqe->next; tqe->next->prev = tqe->prev; } - p->txq_entries -= 1; + wilc->txq_entries -= 1; } #endif @@ -98,7 +71,6 @@ static struct txq_entry_t * wilc_wlan_txq_remove_from_head(struct net_device *dev) { struct txq_entry_t *tqe; - wilc_wlan_dev_t *p = &g_wlan; unsigned long flags; perInterface_wlan_t *nic; struct wilc *wilc; @@ -107,13 +79,13 @@ wilc_wlan_txq_remove_from_head(struct net_device *dev) wilc = nic->wilc; spin_lock_irqsave(&wilc->txq_spinlock, flags); - if (p->txq_head) { - tqe = p->txq_head; - p->txq_head = tqe->next; - if (p->txq_head) - p->txq_head->prev = NULL; + if (wilc->txq_head) { + tqe = wilc->txq_head; + wilc->txq_head = tqe->next; + if (wilc->txq_head) + wilc->txq_head->prev = NULL; - p->txq_entries -= 1; + wilc->txq_entries -= 1; } else { tqe = NULL; } @@ -124,7 +96,6 @@ wilc_wlan_txq_remove_from_head(struct net_device *dev) static void wilc_wlan_txq_add_to_tail(struct net_device *dev, struct txq_entry_t *tqe) { - wilc_wlan_dev_t *p = &g_wlan; unsigned long flags; perInterface_wlan_t *nic; struct wilc *wilc; @@ -134,19 +105,19 @@ static void wilc_wlan_txq_add_to_tail(struct net_device *dev, spin_lock_irqsave(&wilc->txq_spinlock, flags); - if (!p->txq_head) { + if (!wilc->txq_head) { tqe->next = NULL; tqe->prev = NULL; - p->txq_head = tqe; - p->txq_tail = tqe; + wilc->txq_head = tqe; + wilc->txq_tail = tqe; } else { tqe->next = NULL; - tqe->prev = p->txq_tail; - p->txq_tail->next = tqe; - p->txq_tail = tqe; + tqe->prev = wilc->txq_tail; + wilc->txq_tail->next = tqe; + wilc->txq_tail = tqe; } - p->txq_entries += 1; - PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", p->txq_entries); + wilc->txq_entries += 1; + PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", wilc->txq_entries); spin_unlock_irqrestore(&wilc->txq_spinlock, flags); @@ -157,7 +128,6 @@ static void wilc_wlan_txq_add_to_tail(struct net_device *dev, static int wilc_wlan_txq_add_to_head(struct wilc *wilc, struct txq_entry_t *tqe) { - wilc_wlan_dev_t *p = &g_wlan; unsigned long flags; if (wilc_lock_timeout(wilc, &wilc->txq_add_to_head_cs, CFG_PKTS_TIMEOUT)) @@ -165,19 +135,19 @@ static int wilc_wlan_txq_add_to_head(struct wilc *wilc, struct txq_entry_t *tqe) spin_lock_irqsave(&wilc->txq_spinlock, flags); - if (!p->txq_head) { + if (!wilc->txq_head) { tqe->next = NULL; tqe->prev = NULL; - p->txq_head = tqe; - p->txq_tail = tqe; + wilc->txq_head = tqe; + wilc->txq_tail = tqe; } else { - tqe->next = p->txq_head; + tqe->next = wilc->txq_head; tqe->prev = NULL; - p->txq_head->prev = tqe; - p->txq_head = tqe; + wilc->txq_head->prev = tqe; + wilc->txq_head = tqe; } - p->txq_entries += 1; - PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", p->txq_entries); + wilc->txq_entries += 1; + PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", wilc->txq_entries); spin_unlock_irqrestore(&wilc->txq_spinlock, flags); up(&wilc->txq_add_to_head_cs); @@ -253,7 +223,6 @@ static inline int add_tcp_pending_ack(u32 ack, u32 session_index, } static inline int remove_TCP_related(struct wilc *wilc) { - wilc_wlan_dev_t *p = &g_wlan; unsigned long flags; spin_lock_irqsave(&wilc->txq_spinlock, flags); @@ -269,7 +238,6 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) u8 *buffer = tqe->buffer; unsigned short h_proto; int i; - wilc_wlan_dev_t *p = &g_wlan; unsigned long flags; perInterface_wlan_t *nic; struct wilc *wilc; @@ -337,12 +305,11 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) struct wilc *wilc; u32 i = 0; u32 dropped = 0; - wilc_wlan_dev_t *p = &g_wlan; nic = netdev_priv(dev); wilc = nic->wilc; - spin_lock_irqsave(&wilc->txq_spinlock, p->txq_spinlock_flags); + spin_lock_irqsave(&wilc->txq_spinlock, wilc->txq_spinlock_flags); for (i = pending_base; i < (pending_base + pending_acks); i++) { if (pending_acks_info[i].ack_num < ack_session_info[pending_acks_info[i].session_index].bigger_ack_num) { struct txq_entry_t *tqe; @@ -369,7 +336,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) else pending_base = 0; - spin_unlock_irqrestore(&wilc->txq_spinlock, p->txq_spinlock_flags); + spin_unlock_irqrestore(&wilc->txq_spinlock, wilc->txq_spinlock_flags); while (dropped > 0) { wilc_lock_timeout(wilc, &wilc->txq_event, 1); @@ -396,11 +363,10 @@ static bool is_tcp_ack_filter_enabled(void) static int wilc_wlan_txq_add_cfg_pkt(struct wilc *wilc, u8 *buffer, u32 buffer_size) { - wilc_wlan_dev_t *p = &g_wlan; struct txq_entry_t *tqe; PRINT_D(TX_DBG, "Adding config packet ...\n"); - if (p->quit) { + if (wilc->quit) { PRINT_D(TX_DBG, "Return due to clear function\n"); up(&wilc->cfg_event); return 0; @@ -430,10 +396,13 @@ static int wilc_wlan_txq_add_cfg_pkt(struct wilc *wilc, u8 *buffer, u32 buffer_s int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func) { - wilc_wlan_dev_t *p = &g_wlan; struct txq_entry_t *tqe; + perInterface_wlan_t *nic = netdev_priv(dev); + struct wilc *wilc; + + wilc = nic->wilc; - if (p->quit) + if (wilc->quit) return 0; tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC); @@ -453,16 +422,19 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, tcp_process(dev, tqe); #endif wilc_wlan_txq_add_to_tail(dev, tqe); - return p->txq_entries; + return wilc->txq_entries; } int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func) { - wilc_wlan_dev_t *p = &g_wlan; struct txq_entry_t *tqe; + perInterface_wlan_t *nic = netdev_priv(dev); + struct wilc *wilc; + + wilc = nic->wilc; - if (p->quit) + if (wilc->quit) return 0; tqe = kmalloc(sizeof(*tqe), GFP_KERNEL); @@ -484,13 +456,12 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, static struct txq_entry_t *wilc_wlan_txq_get_first(struct wilc *wilc) { - wilc_wlan_dev_t *p = &g_wlan; struct txq_entry_t *tqe; unsigned long flags; spin_lock_irqsave(&wilc->txq_spinlock, flags); - tqe = p->txq_head; + tqe = wilc->txq_head; spin_unlock_irqrestore(&wilc->txq_spinlock, flags); @@ -512,41 +483,39 @@ static struct txq_entry_t *wilc_wlan_txq_get_next(struct wilc *wilc, static int wilc_wlan_rxq_add(struct wilc *wilc, struct rxq_entry_t *rqe) { - wilc_wlan_dev_t *p = &g_wlan; - if (p->quit) + if (wilc->quit) return 0; mutex_lock(&wilc->rxq_cs); - if (!p->rxq_head) { + if (!wilc->rxq_head) { PRINT_D(RX_DBG, "Add to Queue head\n"); rqe->next = NULL; - p->rxq_head = rqe; - p->rxq_tail = rqe; + wilc->rxq_head = rqe; + wilc->rxq_tail = rqe; } else { PRINT_D(RX_DBG, "Add to Queue tail\n"); - p->rxq_tail->next = rqe; + wilc->rxq_tail->next = rqe; rqe->next = NULL; - p->rxq_tail = rqe; + wilc->rxq_tail = rqe; } - p->rxq_entries += 1; - PRINT_D(RX_DBG, "Number of queue entries: %d\n", p->rxq_entries); + wilc->rxq_entries += 1; + PRINT_D(RX_DBG, "Number of queue entries: %d\n", wilc->rxq_entries); mutex_unlock(&wilc->rxq_cs); - return p->rxq_entries; + return wilc->rxq_entries; } static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc) { - wilc_wlan_dev_t *p = &g_wlan; PRINT_D(RX_DBG, "Getting rxQ element\n"); - if (p->rxq_head) { + if (wilc->rxq_head) { struct rxq_entry_t *rqe; mutex_lock(&wilc->rxq_cs); - rqe = p->rxq_head; - p->rxq_head = p->rxq_head->next; - p->rxq_entries -= 1; + rqe = wilc->rxq_head; + wilc->rxq_head = wilc->rxq_head->next; + wilc->rxq_entries -= 1; PRINT_D(RX_DBG, "RXQ entries decreased\n"); mutex_unlock(&wilc->rxq_cs); return rqe; @@ -696,11 +665,10 @@ void wilc_chip_sleep_manually(struct wilc *wilc) int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) { - wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; int i, entries = 0; u32 sum; u32 reg; - u8 *txb = p->tx_buffer; + u8 *txb; u32 offset = 0; int vmm_sz = 0; struct txq_entry_t *tqe; @@ -714,9 +682,10 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) nic = netdev_priv(dev); wilc = nic->wilc; - p->txq_exit = 0; + txb = wilc->tx_buffer; + wilc->txq_exit = 0; do { - if (p->quit) + if (wilc->quit) break; wilc_lock_timeout(wilc, &wilc->txq_add_to_head_cs, @@ -800,7 +769,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) usleep_range(3000, 3000); acquire_bus(wilc, ACQUIRE_AND_WAKEUP); } - } while (!p->quit); + } while (!wilc->quit); if (!ret) goto _end_; @@ -945,23 +914,22 @@ _end_: } while (0); up(&wilc->txq_add_to_head_cs); - p->txq_exit = 1; + wilc->txq_exit = 1; PRINT_D(TX_DBG, "THREAD: Exiting txq\n"); - *txq_count = p->txq_entries; + *txq_count = wilc->txq_entries; return ret; } static void wilc_wlan_handle_rxq(struct wilc *wilc) { - wilc_wlan_dev_t *p = &g_wlan; int offset = 0, size, has_packet = 0; u8 *buffer; struct rxq_entry_t *rqe; - p->rxq_exit = 0; + wilc->rxq_exit = 0; do { - if (p->quit) { + if (wilc->quit) { PRINT_D(RX_DBG, "exit 1st do-while due to Clean_UP function\n"); up(&wilc->cfg_event); break; @@ -1022,8 +990,8 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) wilc_wlan_cfg_indicate_rx(&buffer[pkt_offset + offset], pkt_len, &rsp); if (rsp.type == WILC_CFG_RSP) { - PRINT_D(RX_DBG, "p->cfg_seq_no = %d - rsp.seq_no = %d\n", p->cfg_seq_no, rsp.seq_no); - if (p->cfg_seq_no == rsp.seq_no) + PRINT_D(RX_DBG, "wilc->cfg_seq_no = %d - rsp.seq_no = %d\n", wilc->cfg_seq_no, rsp.seq_no); + if (wilc->cfg_seq_no == rsp.seq_no) up(&wilc->cfg_event); } else if (rsp.type == WILC_CFG_RSP_STATUS) { wilc_mac_indicate(wilc, WILC_MAC_INDICATE_STATUS); @@ -1044,7 +1012,7 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) } while (1); - p->rxq_exit = 1; + wilc->rxq_exit = 1; PRINT_D(RX_DBG, "THREAD: Exiting RX thread\n"); } @@ -1080,8 +1048,7 @@ static void wilc_sleeptimer_isr_ext(struct wilc *wilc, u32 int_stats1) static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) { - wilc_wlan_dev_t *p = &g_wlan; - u32 offset = p->rx_buffer_offset; + u32 offset = wilc->rx_buffer_offset; u8 *buffer = NULL; u32 size; u32 retries = 0; @@ -1103,8 +1070,8 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) if (LINUX_RX_SIZE - offset < size) offset = 0; - if (p->rx_buffer) { - buffer = &p->rx_buffer[offset]; + if (wilc->rx_buffer) { + buffer = &wilc->rx_buffer[offset]; } else { wilc_debug(N_ERR, "[wilc isr]: fail Rx Buffer is NULL...drop the packets (%d)\n", size); goto _end_; @@ -1121,7 +1088,7 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) _end_: if (ret) { offset += size; - p->rx_buffer_offset = offset; + wilc->rx_buffer_offset = offset; rqe = kmalloc(sizeof(*rqe), GFP_KERNEL); if (rqe) { rqe->buffer = buffer; @@ -1377,7 +1344,6 @@ int wilc_wlan_stop(struct wilc *wilc) void wilc_wlan_cleanup(struct net_device *dev) { - wilc_wlan_dev_t *p = &g_wlan; struct txq_entry_t *tqe; struct rxq_entry_t *rqe; u32 reg = 0; @@ -1388,7 +1354,7 @@ void wilc_wlan_cleanup(struct net_device *dev) nic = netdev_priv(dev); wilc = nic->wilc; - p->quit = 1; + wilc->quit = 1; do { tqe = wilc_wlan_txq_remove_from_head(dev); if (!tqe) @@ -1405,9 +1371,9 @@ void wilc_wlan_cleanup(struct net_device *dev) kfree(rqe); } while (1); - kfree(p->rx_buffer); - p->rx_buffer = NULL; - kfree(p->tx_buffer); + kfree(wilc->rx_buffer); + wilc->rx_buffer = NULL; + kfree(wilc->tx_buffer); acquire_bus(wilc, ACQUIRE_AND_WAKEUP); @@ -1429,10 +1395,9 @@ void wilc_wlan_cleanup(struct net_device *dev) static int wilc_wlan_cfg_commit(struct wilc *wilc, int type, u32 drv_handler) { - wilc_wlan_dev_t *p = &g_wlan; - struct wilc_cfg_frame *cfg = &p->cfg_frame; - int total_len = p->cfg_frame_offset + 4 + DRIVER_HANDLER_SIZE; - int seq_no = p->cfg_seq_no % 256; + struct wilc_cfg_frame *cfg = &wilc->cfg_frame; + int total_len = wilc->cfg_frame_offset + 4 + DRIVER_HANDLER_SIZE; + int seq_no = wilc->cfg_seq_no % 256; int driver_handler = (u32)drv_handler; if (type == WILC_CFG_SET) @@ -1446,7 +1411,7 @@ static int wilc_wlan_cfg_commit(struct wilc *wilc, int type, u32 drv_handler) cfg->wid_header[5] = (u8)(driver_handler >> 8); cfg->wid_header[6] = (u8)(driver_handler >> 16); cfg->wid_header[7] = (u8)(driver_handler >> 24); - p->cfg_seq_no = seq_no; + wilc->cfg_seq_no = seq_no; if (!wilc_wlan_txq_add_cfg_pkt(wilc, &cfg->wid_header[0], total_len)) return -1; @@ -1457,27 +1422,26 @@ static int wilc_wlan_cfg_commit(struct wilc *wilc, int type, u32 drv_handler) int wilc_wlan_cfg_set(struct wilc *wilc, int start, u32 wid, u8 *buffer, u32 buffer_size, int commit, u32 drv_handler) { - wilc_wlan_dev_t *p = &g_wlan; u32 offset; int ret_size; - if (p->cfg_frame_in_use) + if (wilc->cfg_frame_in_use) return 0; if (start) - p->cfg_frame_offset = 0; + wilc->cfg_frame_offset = 0; - offset = p->cfg_frame_offset; - ret_size = wilc_wlan_cfg_set_wid(p->cfg_frame.frame, offset, (u16)wid, - buffer, buffer_size); + offset = wilc->cfg_frame_offset; + ret_size = wilc_wlan_cfg_set_wid(wilc->cfg_frame.frame, offset, + (u16)wid, buffer, buffer_size); offset += ret_size; - p->cfg_frame_offset = offset; + wilc->cfg_frame_offset = offset; if (commit) { PRINT_D(TX_DBG, "[WILC]PACKET Commit with sequence number %d\n", - p->cfg_seq_no); + wilc->cfg_seq_no); PRINT_D(RX_DBG, "Processing cfg_set()\n"); - p->cfg_frame_in_use = 1; + wilc->cfg_frame_in_use = 1; if (wilc_wlan_cfg_commit(wilc, WILC_CFG_SET, drv_handler)) ret_size = 0; @@ -1487,9 +1451,9 @@ int wilc_wlan_cfg_set(struct wilc *wilc, int start, u32 wid, u8 *buffer, PRINT_D(TX_DBG, "Set Timed Out\n"); ret_size = 0; } - p->cfg_frame_in_use = 0; - p->cfg_frame_offset = 0; - p->cfg_seq_no += 1; + wilc->cfg_frame_in_use = 0; + wilc->cfg_frame_offset = 0; + wilc->cfg_seq_no += 1; } return ret_size; @@ -1498,23 +1462,23 @@ int wilc_wlan_cfg_set(struct wilc *wilc, int start, u32 wid, u8 *buffer, int wilc_wlan_cfg_get(struct wilc *wilc, int start, u32 wid, int commit, u32 drv_handler) { - wilc_wlan_dev_t *p = &g_wlan; u32 offset; int ret_size; - if (p->cfg_frame_in_use) + if (wilc->cfg_frame_in_use) return 0; if (start) - p->cfg_frame_offset = 0; + wilc->cfg_frame_offset = 0; - offset = p->cfg_frame_offset; - ret_size = wilc_wlan_cfg_get_wid(p->cfg_frame.frame, offset, (u16)wid); + offset = wilc->cfg_frame_offset; + ret_size = wilc_wlan_cfg_get_wid(wilc->cfg_frame.frame, offset, + (u16)wid); offset += ret_size; - p->cfg_frame_offset = offset; + wilc->cfg_frame_offset = offset; if (commit) { - p->cfg_frame_in_use = 1; + wilc->cfg_frame_in_use = 1; if (wilc_wlan_cfg_commit(wilc, WILC_CFG_QUERY, drv_handler)) ret_size = 0; @@ -1525,9 +1489,9 @@ int wilc_wlan_cfg_get(struct wilc *wilc, int start, u32 wid, int commit, ret_size = 0; } PRINT_D(GENERIC_DBG, "[WILC]Get Response received\n"); - p->cfg_frame_in_use = 0; - p->cfg_frame_offset = 0; - p->cfg_seq_no += 1; + wilc->cfg_frame_in_use = 0; + wilc->cfg_frame_offset = 0; + wilc->cfg_seq_no += 1; } return ret_size; @@ -1623,7 +1587,6 @@ int wilc_wlan_init(struct net_device *dev) PRINT_D(INIT_DBG, "Initializing WILC_Wlan ...\n"); - memset((void *)&g_wlan, 0, sizeof(wilc_wlan_dev_t)); if (!wilc->hif_func->hif_init(wilc, wilc_debug)) { ret = -EIO; goto _fail_; @@ -1634,20 +1597,20 @@ int wilc_wlan_init(struct net_device *dev) goto _fail_; } - if (!g_wlan.tx_buffer) - g_wlan.tx_buffer = kmalloc(LINUX_TX_SIZE, GFP_KERNEL); - PRINT_D(TX_DBG, "g_wlan.tx_buffer = %p\n", g_wlan.tx_buffer); + if (!wilc->tx_buffer) + wilc->tx_buffer = kmalloc(LINUX_TX_SIZE, GFP_KERNEL); + PRINT_D(TX_DBG, "wilc->tx_buffer = %p\n", wilc->tx_buffer); - if (!g_wlan.tx_buffer) { + if (!wilc->tx_buffer) { ret = -ENOBUFS; PRINT_ER("Can't allocate Tx Buffer"); goto _fail_; } - if (!g_wlan.rx_buffer) - g_wlan.rx_buffer = kmalloc(LINUX_RX_SIZE, GFP_KERNEL); - PRINT_D(TX_DBG, "g_wlan.rx_buffer =%p\n", g_wlan.rx_buffer); - if (!g_wlan.rx_buffer) { + if (!wilc->rx_buffer) + wilc->rx_buffer = kmalloc(LINUX_RX_SIZE, GFP_KERNEL); + PRINT_D(TX_DBG, "wilc->rx_buffer =%p\n", wilc->rx_buffer); + if (!wilc->rx_buffer) { ret = -ENOBUFS; PRINT_ER("Can't allocate Rx Buffer"); goto _fail_; @@ -1665,10 +1628,10 @@ int wilc_wlan_init(struct net_device *dev) _fail_: - kfree(g_wlan.rx_buffer); - g_wlan.rx_buffer = NULL; - kfree(g_wlan.tx_buffer); - g_wlan.tx_buffer = NULL; + kfree(wilc->rx_buffer); + wilc->rx_buffer = NULL; + kfree(wilc->tx_buffer); + wilc->tx_buffer = NULL; return ret; } -- GitLab From ac1da162e488e90be001ebb4057aaf01e565dd28 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:13 +0900 Subject: [PATCH 1767/2855] staging: wilc1000: sdio/spi: use device print api instead of custom one This patch use device print api instead of driver defined print. Remove varialbe dPrint as well. String "[wilc sdio]" and "[wilc spi]" are also removed from all the print statment if exist because it shows which device the message is related to. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_sdio.c | 18 +-- drivers/staging/wilc1000/linux_wlan_spi.c | 24 ++-- drivers/staging/wilc1000/wilc_sdio.c | 151 ++++++++++++++------- drivers/staging/wilc1000/wilc_spi.c | 142 +++++++++++-------- 4 files changed, 213 insertions(+), 122 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index ae31f7d896938..66cdca23b1b4a 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -52,7 +52,7 @@ int wilc_sdio_cmd52(struct wilc *wilc, sdio_cmd52_t *cmd) sdio_release_host(func); if (ret < 0) { - PRINT_ER("wilc_sdio_cmd52..failed, err(%d)\n", ret); + dev_err(&func->dev, "wilc_sdio_cmd52..failed, err(%d)\n", ret); return 0; } return 1; @@ -83,7 +83,7 @@ int wilc_sdio_cmd53(struct wilc *wilc, sdio_cmd53_t *cmd) if (ret < 0) { - PRINT_ER("wilc_sdio_cmd53..failed, err(%d)\n", ret); + dev_err(&func->dev, "wilc_sdio_cmd53..failed, err(%d)\n", ret); return 0; } @@ -102,16 +102,16 @@ static int linux_sdio_probe(struct sdio_func *func, const struct sdio_device_id gpio = GPIO_NUM; } - PRINT_D(INIT_DBG, "Initializing netdev\n"); + dev_dbg(&func->dev, "Initializing netdev\n"); if (wilc_netdev_init(&wilc, &func->dev, HIF_SDIO, gpio, &wilc_hif_sdio)) { - PRINT_ER("Couldn't initialize netdev\n"); + dev_err(&func->dev, "Couldn't initialize netdev\n"); return -1; } sdio_set_drvdata(func, wilc); wilc->dev = &func->dev; - printk("Driver Initializing success\n"); + dev_info(&func->dev, "Driver Initializing success\n"); return 0; } @@ -139,7 +139,7 @@ int wilc_sdio_enable_interrupt(struct wilc *dev) sdio_release_host(func); if (ret < 0) { - PRINT_ER("can't claim sdio_irq, err(%d)\n", ret); + dev_err(&func->dev, "can't claim sdio_irq, err(%d)\n", ret); ret = -EIO; } return ret; @@ -150,16 +150,16 @@ void wilc_sdio_disable_interrupt(struct wilc *dev) struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev); int ret; - PRINT_D(INIT_DBG, "wilc_sdio_disable_interrupt IN\n"); + dev_dbg(&func->dev, "wilc_sdio_disable_interrupt IN\n"); sdio_claim_host(func); ret = sdio_release_irq(func); if (ret < 0) { - PRINT_ER("can't release sdio_irq, err(%d)\n", ret); + dev_err(&func->dev, "can't release sdio_irq, err(%d)\n", ret); } sdio_release_host(func); - PRINT_D(INIT_DBG, "wilc_sdio_disable_interrupt OUT\n"); + dev_info(&func->dev, "wilc_sdio_disable_interrupt OUT\n"); } int wilc_sdio_init(void) diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index f3ffc9e6d6262..01fa6fa0cc1df 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -83,7 +83,7 @@ int wilc_spi_write(struct wilc *wilc, u8 *b, u32 len) return -ENOMEM; tr.rx_buf = r_buffer; - PRINT_D(BUS_DBG, "Request writing %d bytes\n", len); + dev_dbg(&spi->dev, "Request writing %d bytes\n", len); memset(&msg, 0, sizeof(msg)); spi_message_init(&msg); @@ -95,13 +95,17 @@ int wilc_spi_write(struct wilc *wilc, u8 *b, u32 len) ret = spi_sync(spi, &msg); if (ret < 0) { - PRINT_ER("SPI transaction failed\n"); + dev_err(&spi->dev, "SPI transaction failed\n"); } kfree(r_buffer); } else { - PRINT_ER("can't write data with the following length: %d\n", len); - PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len); + dev_err(&spi->dev, + "can't write data with the following length: %d\n", + len); + dev_err(&spi->dev, + "FAILED due to NULL buffer or ZERO length check the following length: %d\n", + len); ret = -1; } @@ -141,11 +145,13 @@ int wilc_spi_read(struct wilc *wilc, u8 *rb, u32 rlen) ret = spi_sync(spi, &msg); if (ret < 0) { - PRINT_ER("SPI transaction failed\n"); + dev_err(&spi->dev, "SPI transaction failed\n"); } kfree(t_buffer); } else { - PRINT_ER("can't read data with the following length: %u\n", rlen); + dev_err(&spi->dev, + "can't read data with the following length: %u\n", + rlen); ret = -1; } /* change return value to match WILC interface */ @@ -178,10 +184,12 @@ int wilc_spi_write_read(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen) spi_message_add_tail(&tr, &msg); ret = spi_sync(spi, &msg); if (ret < 0) { - PRINT_ER("SPI transaction failed\n"); + dev_err(&spi->dev, "SPI transaction failed\n"); } } else { - PRINT_ER("can't read data with the following length: %u\n", rlen); + dev_err(&spi->dev, + "can't read data with the following length: %u\n", + rlen); ret = -1; } /* change return value to match WILC interface */ diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index a9ad49f70d395..dfa3d3a7fcacd 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -18,7 +18,6 @@ typedef struct { bool irq_gpio; u32 block_size; - wilc_debug_func dPrint; int nint; #define MAX_NUN_INT_THRPT_ENH2 (5) /* Max num interrupts allowed in registers 0xf7, 0xf8 */ int has_thrpt_enh3; @@ -37,6 +36,7 @@ static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data); static int sdio_set_func0_csa_address(struct wilc *wilc, u32 adr) { + struct sdio_func *func = dev_to_sdio_func(wilc->dev); sdio_cmd52_t cmd; /** @@ -48,21 +48,21 @@ static int sdio_set_func0_csa_address(struct wilc *wilc, u32 adr) cmd.address = 0x10c; cmd.data = (u8)adr; if (!wilc_sdio_cmd52(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10c data...\n"); + dev_err(&func->dev, "Failed cmd52, set 0x10c data...\n"); goto _fail_; } cmd.address = 0x10d; cmd.data = (u8)(adr >> 8); if (!wilc_sdio_cmd52(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10d data...\n"); + dev_err(&func->dev, "Failed cmd52, set 0x10d data...\n"); goto _fail_; } cmd.address = 0x10e; cmd.data = (u8)(adr >> 16); if (!wilc_sdio_cmd52(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10e data...\n"); + dev_err(&func->dev, "Failed cmd52, set 0x10e data...\n"); goto _fail_; } @@ -73,6 +73,7 @@ _fail_: static int sdio_set_func0_block_size(struct wilc *wilc, u32 block_size) { + struct sdio_func *func = dev_to_sdio_func(wilc->dev); sdio_cmd52_t cmd; cmd.read_write = 1; @@ -81,14 +82,14 @@ static int sdio_set_func0_block_size(struct wilc *wilc, u32 block_size) cmd.address = 0x10; cmd.data = (u8)block_size; if (!wilc_sdio_cmd52(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10 data...\n"); + dev_err(&func->dev, "Failed cmd52, set 0x10 data...\n"); goto _fail_; } cmd.address = 0x11; cmd.data = (u8)(block_size >> 8); if (!wilc_sdio_cmd52(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x11 data...\n"); + dev_err(&func->dev, "Failed cmd52, set 0x11 data...\n"); goto _fail_; } @@ -105,6 +106,7 @@ _fail_: static int sdio_set_func1_block_size(struct wilc *wilc, u32 block_size) { + struct sdio_func *func = dev_to_sdio_func(wilc->dev); sdio_cmd52_t cmd; cmd.read_write = 1; @@ -113,13 +115,13 @@ static int sdio_set_func1_block_size(struct wilc *wilc, u32 block_size) cmd.address = 0x110; cmd.data = (u8)block_size; if (!wilc_sdio_cmd52(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x110 data...\n"); + dev_err(&func->dev, "Failed cmd52, set 0x110 data...\n"); goto _fail_; } cmd.address = 0x111; cmd.data = (u8)(block_size >> 8); if (!wilc_sdio_cmd52(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x111 data...\n"); + dev_err(&func->dev, "Failed cmd52, set 0x111 data...\n"); goto _fail_; } @@ -130,6 +132,8 @@ _fail_: static int sdio_clear_int(struct wilc *wilc) { + struct sdio_func *func = dev_to_sdio_func(wilc->dev); + if (!g_sdio.irq_gpio) { /* u32 sts; */ sdio_cmd52_t cmd; @@ -146,7 +150,8 @@ static int sdio_clear_int(struct wilc *wilc) u32 reg; if (!sdio_read_reg(wilc, WILC_HOST_RX_CTRL_0, ®)) { - g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0); + dev_err(&func->dev, "Failed read reg (%08x)...\n", + WILC_HOST_RX_CTRL_0); return 0; } reg &= ~0x1; @@ -163,6 +168,8 @@ static int sdio_clear_int(struct wilc *wilc) ********************************************/ static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) { + struct sdio_func *func = dev_to_sdio_func(wilc->dev); + data = cpu_to_le32(data); if ((addr >= 0xf0) && (addr <= 0xff)) { @@ -174,7 +181,8 @@ static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) cmd.address = addr; cmd.data = data; if (!wilc_sdio_cmd52(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr); + dev_err(&func->dev, + "Failed cmd 52, read reg (%08x) ...\n", addr); goto _fail_; } } else { @@ -196,7 +204,8 @@ static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */ if (!wilc_sdio_cmd53(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, write reg (%08x)...\n", addr); + dev_err(&func->dev, + "Failed cmd53, write reg (%08x)...\n", addr); goto _fail_; } } @@ -210,6 +219,7 @@ _fail_: static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { + struct sdio_func *func = dev_to_sdio_func(wilc->dev); u32 block_size = g_sdio.block_size; sdio_cmd53_t cmd; int nblk, nleft; @@ -259,7 +269,8 @@ static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) goto _fail_; } if (!wilc_sdio_cmd53(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block send...\n", addr); + dev_err(&func->dev, + "Failed cmd53 [%x], block send...\n", addr); goto _fail_; } if (addr > 0) @@ -280,7 +291,8 @@ static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) goto _fail_; } if (!wilc_sdio_cmd53(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes send...\n", addr); + dev_err(&func->dev, + "Failed cmd53 [%x], bytes send...\n", addr); goto _fail_; } } @@ -294,6 +306,8 @@ _fail_: static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) { + struct sdio_func *func = dev_to_sdio_func(wilc->dev); + if ((addr >= 0xf0) && (addr <= 0xff)) { sdio_cmd52_t cmd; @@ -302,7 +316,8 @@ static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) cmd.raw = 0; cmd.address = addr; if (!wilc_sdio_cmd52(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr); + dev_err(&func->dev, + "Failed cmd 52, read reg (%08x) ...\n", addr); goto _fail_; } *data = cmd.data; @@ -323,7 +338,8 @@ static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */ if (!wilc_sdio_cmd53(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, read reg (%08x)...\n", addr); + dev_err(&func->dev, + "Failed cmd53, read reg (%08x)...\n", addr); goto _fail_; } } @@ -339,6 +355,7 @@ _fail_: static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { + struct sdio_func *func = dev_to_sdio_func(wilc->dev); u32 block_size = g_sdio.block_size; sdio_cmd53_t cmd; int nblk, nleft; @@ -388,7 +405,8 @@ static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) goto _fail_; } if (!wilc_sdio_cmd53(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block read...\n", addr); + dev_err(&func->dev, + "Failed cmd53 [%x], block read...\n", addr); goto _fail_; } if (addr > 0) @@ -409,7 +427,8 @@ static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) goto _fail_; } if (!wilc_sdio_cmd53(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes read...\n", addr); + dev_err(&func->dev, + "Failed cmd53 [%x], bytes read...\n", addr); goto _fail_; } } @@ -434,19 +453,20 @@ static int sdio_deinit(struct wilc *wilc) static int sdio_sync(struct wilc *wilc) { + struct sdio_func *func = dev_to_sdio_func(wilc->dev); u32 reg; /** * Disable power sequencer **/ if (!sdio_read_reg(wilc, WILC_MISC, ®)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read misc reg...\n"); + dev_err(&func->dev, "Failed read misc reg...\n"); return 0; } reg &= ~BIT(8); if (!sdio_write_reg(wilc, WILC_MISC, reg)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write misc reg...\n"); + dev_err(&func->dev, "Failed write misc reg...\n"); return 0; } @@ -459,13 +479,15 @@ static int sdio_sync(struct wilc *wilc) **/ ret = sdio_read_reg(wilc, WILC_PIN_MUX_0, ®); if (!ret) { - g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); + dev_err(&func->dev, "Failed read reg (%08x)...\n", + WILC_PIN_MUX_0); return 0; } reg |= BIT(8); ret = sdio_write_reg(wilc, WILC_PIN_MUX_0, reg); if (!ret) { - g_sdio.dPrint(N_ERR, "[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); + dev_err(&func->dev, "Failed write reg (%08x)...\n", + WILC_PIN_MUX_0); return 0; } @@ -474,13 +496,15 @@ static int sdio_sync(struct wilc *wilc) **/ ret = sdio_read_reg(wilc, WILC_INTR_ENABLE, ®); if (!ret) { - g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); + dev_err(&func->dev, "Failed read reg (%08x)...\n", + WILC_INTR_ENABLE); return 0; } reg |= BIT(16); ret = sdio_write_reg(wilc, WILC_INTR_ENABLE, reg); if (!ret) { - g_sdio.dPrint(N_ERR, "[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); + dev_err(&func->dev, "Failed write reg (%08x)...\n", + WILC_INTR_ENABLE); return 0; } } @@ -488,19 +512,19 @@ static int sdio_sync(struct wilc *wilc) return 1; } -static int sdio_init(struct wilc *wilc, wilc_debug_func func) +static int sdio_init(struct wilc *wilc, wilc_debug_func debug_func) { + struct sdio_func *func = dev_to_sdio_func(wilc->dev); sdio_cmd52_t cmd; int loop; u32 chipid; memset(&g_sdio, 0, sizeof(wilc_sdio_t)); - g_sdio.dPrint = func; g_sdio.irq_gpio = (wilc->dev_irq_num); if (!wilc_sdio_init()) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed io init bus...\n"); + dev_err(&func->dev, "Failed io init bus...\n"); return 0; } else { return 0; @@ -515,7 +539,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) cmd.address = 0x100; cmd.data = 0x80; if (!wilc_sdio_cmd52(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, enable csa...\n"); + dev_err(&func->dev, "Fail cmd 52, enable csa...\n"); goto _fail_; } @@ -523,7 +547,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) * function 0 block size **/ if (!sdio_set_func0_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set func 0 block size...\n"); + dev_err(&func->dev, "Fail cmd 52, set func 0 block size...\n"); goto _fail_; } g_sdio.block_size = WILC_SDIO_BLOCK_SIZE; @@ -537,7 +561,8 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) cmd.address = 0x2; cmd.data = 0x2; if (!wilc_sdio_cmd52(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio] Fail cmd 52, set IOE register...\n"); + dev_err(&func->dev, + "Fail cmd 52, set IOE register...\n"); goto _fail_; } @@ -552,7 +577,8 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) do { cmd.data = 0; if (!wilc_sdio_cmd52(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get IOR register...\n"); + dev_err(&func->dev, + "Fail cmd 52, get IOR register...\n"); goto _fail_; } if (cmd.data == 0x2) @@ -560,7 +586,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) } while (loop--); if (loop <= 0) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail func 1 is not ready...\n"); + dev_err(&func->dev, "Fail func 1 is not ready...\n"); goto _fail_; } @@ -568,7 +594,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) * func 1 is ready, set func 1 block size **/ if (!sdio_set_func1_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail set func 1 block size...\n"); + dev_err(&func->dev, "Fail set func 1 block size...\n"); goto _fail_; } @@ -581,7 +607,7 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) cmd.address = 0x4; cmd.data = 0x3; if (!wilc_sdio_cmd52(wilc, &cmd)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set IEN register...\n"); + dev_err(&func->dev, "Fail cmd 52, set IEN register...\n"); goto _fail_; } @@ -589,15 +615,15 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func) * make sure can read back chip id correctly **/ if (!sdio_read_reg(wilc, 0x1000, &chipid)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd read chip id...\n"); + dev_err(&func->dev, "Fail cmd read chip id...\n"); goto _fail_; } - g_sdio.dPrint(N_ERR, "[wilc sdio]: chipid (%08x)\n", chipid); + dev_err(&func->dev, "chipid (%08x)\n", chipid); if ((chipid & 0xfff) > 0x2a0) g_sdio.has_thrpt_enh3 = 1; else g_sdio.has_thrpt_enh3 = 0; - g_sdio.dPrint(N_ERR, "[wilc sdio]: has_thrpt_enh3 = %d...\n", g_sdio.has_thrpt_enh3); + dev_info(&func->dev, "has_thrpt_enh3 = %d...\n", g_sdio.has_thrpt_enh3); return 1; @@ -637,7 +663,7 @@ static int sdio_read_size(struct wilc *wilc, u32 *size) static int sdio_read_int(struct wilc *wilc, u32 *int_status) { - + struct sdio_func *func = dev_to_sdio_func(wilc->dev); u32 tmp; sdio_cmd52_t cmd; @@ -668,7 +694,9 @@ static int sdio_read_int(struct wilc *wilc, u32 *int_status) tmp |= INT_5; for (i = g_sdio.nint; i < MAX_NUM_INT; i++) { if ((tmp >> (IRG_FLAGS_OFFSET + i)) & 0x1) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Unexpected interrupt (1) : tmp=%x, data=%x\n", tmp, cmd.data); + dev_err(&func->dev, + "Unexpected interrupt (1) : tmp=%x, data=%x\n", + tmp, cmd.data); break; } } @@ -692,6 +720,7 @@ static int sdio_read_int(struct wilc *wilc, u32 *int_status) static int sdio_clear_int_ext(struct wilc *wilc, u32 val) { + struct sdio_func *func = dev_to_sdio_func(wilc->dev); int ret; if (g_sdio.has_thrpt_enh3) { @@ -725,7 +754,9 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val) ret = wilc_sdio_cmd52(wilc, &cmd); if (!ret) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__); + dev_err(&func->dev, + "Failed cmd52, set 0xf8 data (%d) ...\n", + __LINE__); goto _fail_; } @@ -753,7 +784,9 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val) ret = wilc_sdio_cmd52(wilc, &cmd); if (!ret) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__); + dev_err(&func->dev, + "Failed cmd52, set 0xf8 data (%d) ...\n", + __LINE__); goto _fail_; } @@ -766,7 +799,9 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val) goto _fail_; for (i = g_sdio.nint; i < MAX_NUM_INT; i++) { if (flags & 1) - g_sdio.dPrint(N_ERR, "[wilc sdio]: Unexpected interrupt cleared %d...\n", i); + dev_err(&func->dev, + "Unexpected interrupt cleared %d...\n", + i); flags >>= 1; } } @@ -796,7 +831,9 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val) cmd.data = vmm_ctl; ret = wilc_sdio_cmd52(wilc, &cmd); if (!ret) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf6 data (%d) ...\n", __LINE__); + dev_err(&func->dev, + "Failed cmd52, set 0xf6 data (%d) ...\n", + __LINE__); goto _fail_; } } @@ -810,14 +847,16 @@ _fail_: static int sdio_sync_ext(struct wilc *wilc, int nint) { + struct sdio_func *func = dev_to_sdio_func(wilc->dev); u32 reg; if (nint > MAX_NUM_INT) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Too many interupts (%d)...\n", nint); + dev_err(&func->dev, "Too many interupts (%d)...\n", nint); return 0; } if (nint > MAX_NUN_INT_THRPT_ENH2) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Error: Cannot support more than 5 interrupts when has_thrpt_enh2=1.\n"); + dev_err(&func->dev, + "Cannot support more than 5 interrupts when has_thrpt_enh2=1.\n"); return 0; } @@ -827,13 +866,13 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) * Disable power sequencer **/ if (!sdio_read_reg(wilc, WILC_MISC, ®)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read misc reg...\n"); + dev_err(&func->dev, "Failed read misc reg...\n"); return 0; } reg &= ~BIT(8); if (!sdio_write_reg(wilc, WILC_MISC, reg)) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write misc reg...\n"); + dev_err(&func->dev, "Failed write misc reg...\n"); return 0; } @@ -846,13 +885,15 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) **/ ret = sdio_read_reg(wilc, WILC_PIN_MUX_0, ®); if (!ret) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); + dev_err(&func->dev, "Failed read reg (%08x)...\n", + WILC_PIN_MUX_0); return 0; } reg |= BIT(8); ret = sdio_write_reg(wilc, WILC_PIN_MUX_0, reg); if (!ret) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); + dev_err(&func->dev, "Failed write reg (%08x)...\n", + WILC_PIN_MUX_0); return 0; } @@ -861,7 +902,8 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) **/ ret = sdio_read_reg(wilc, WILC_INTR_ENABLE, ®); if (!ret) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); + dev_err(&func->dev, "Failed read reg (%08x)...\n", + WILC_INTR_ENABLE); return 0; } @@ -869,13 +911,16 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) reg |= BIT((27 + i)); ret = sdio_write_reg(wilc, WILC_INTR_ENABLE, reg); if (!ret) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); + dev_err(&func->dev, "Failed write reg (%08x)...\n", + WILC_INTR_ENABLE); return 0; } if (nint) { ret = sdio_read_reg(wilc, WILC_INTR2_ENABLE, ®); if (!ret) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_INTR2_ENABLE); + dev_err(&func->dev, + "Failed read reg (%08x)...\n", + WILC_INTR2_ENABLE); return 0; } @@ -884,7 +929,9 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) ret = sdio_read_reg(wilc, WILC_INTR2_ENABLE, ®); if (!ret) { - g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_INTR2_ENABLE); + dev_err(&func->dev, + "Failed write reg (%08x)...\n", + WILC_INTR2_ENABLE); return 0; } } diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index c94d86f6cbeaa..806012599bb33 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -14,7 +14,6 @@ #include "wilc_wfi_netdevice.h" typedef struct { - wilc_debug_func dPrint; int crc_off; int nint; int has_thrpt_enh; @@ -111,6 +110,7 @@ static u8 crc7(u8 crc, const u8 *buffer, u32 len) static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless) { + struct spi_device *spi = to_spi_device(wilc->dev); u8 wb[32], rb[32]; u8 wix, rix; u32 len2; @@ -239,7 +239,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, #undef NUM_DUMMY_BYTES if (len2 > ARRAY_SIZE(wb)) { - PRINT_ER("[wilc spi]: spi buffer size too small (%d) (%zu)\n", + dev_err(&spi->dev, "spi buffer size too small (%d) (%zu)\n", len2, ARRAY_SIZE(wb)); result = N_FAIL; return result; @@ -251,7 +251,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, rix = len; if (!wilc_spi_write_read(wilc, wb, rb, len2)) { - PRINT_ER("[wilc spi]: Failed cmd write, bus error...\n"); + dev_err(&spi->dev, "Failed cmd write, bus error...\n"); result = N_FAIL; return result; } @@ -271,7 +271,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, /* } while(&rptr[1] <= &rb[len2]); */ if (rsp != cmd) { - PRINT_ER("[wilc spi]: Failed cmd response, cmd (%02x)" + dev_err(&spi->dev, "Failed cmd response, cmd (%02x)" ", resp (%02x)\n", cmd, rsp); result = N_FAIL; return result; @@ -282,8 +282,8 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, **/ rsp = rb[rix++]; if (rsp != 0x00) { - PRINT_ER("[wilc spi]: Failed cmd state response " - "state (%02x)\n", rsp); + dev_err(&spi->dev, "Failed cmd state response state (%02x)\n", + rsp); result = N_FAIL; return result; } @@ -310,8 +310,8 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, } while (retry--); if (retry <= 0) { - PRINT_ER("[wilc spi]: Error, data read " - "response (%02x)\n", rsp); + dev_err(&spi->dev, + "Error, data read response (%02x)\n", rsp); result = N_RESET; return result; } @@ -326,7 +326,8 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, b[2] = rb[rix++]; b[3] = rb[rix++]; } else { - PRINT_ER("[wilc spi]: buffer overrun when reading data.\n"); + dev_err(&spi->dev, + "buffer overrun when reading data.\n"); result = N_FAIL; return result; } @@ -339,7 +340,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, crc[0] = rb[rix++]; crc[1] = rb[rix++]; } else { - PRINT_ER("[wilc spi]: buffer overrun when reading crc.\n"); + dev_err(&spi->dev,"buffer overrun when reading crc.\n"); result = N_FAIL; return result; } @@ -366,7 +367,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, * Read bytes **/ if (!wilc_spi_read(wilc, &b[ix], nbytes)) { - PRINT_ER("[wilc spi]: Failed data block read, bus error...\n"); + dev_err(&spi->dev, "Failed data block read, bus error...\n"); result = N_FAIL; goto _error_; } @@ -376,7 +377,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, **/ if (!g_spi.crc_off) { if (!wilc_spi_read(wilc, crc, 2)) { - PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n"); + dev_err(&spi->dev, "Failed data block crc read, bus error...\n"); result = N_FAIL; goto _error_; } @@ -407,7 +408,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, retry = 10; do { if (!wilc_spi_read(wilc, &rsp, 1)) { - PRINT_ER("[wilc spi]: Failed data response read, bus error...\n"); + dev_err(&spi->dev, "Failed data response read, bus error...\n"); result = N_FAIL; break; } @@ -423,7 +424,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, * Read bytes **/ if (!wilc_spi_read(wilc, &b[ix], nbytes)) { - PRINT_ER("[wilc spi]: Failed data block read, bus error...\n"); + dev_err(&spi->dev, "Failed data block read, bus error...\n"); result = N_FAIL; break; } @@ -433,7 +434,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, **/ if (!g_spi.crc_off) { if (!wilc_spi_read(wilc, crc, 2)) { - PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n"); + dev_err(&spi->dev, "Failed data block crc read, bus error...\n"); result = N_FAIL; break; } @@ -450,6 +451,7 @@ _error_: static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz) { + struct spi_device *spi = to_spi_device(wilc->dev); int ix, nbytes; int result = 1; u8 cmd, order, crc[2] = {0}; @@ -483,7 +485,8 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz) } cmd |= order; if (!wilc_spi_write(wilc, &cmd, 1)) { - PRINT_ER("[wilc spi]: Failed data block cmd write, bus error...\n"); + dev_err(&spi->dev, + "Failed data block cmd write, bus error...\n"); result = N_FAIL; break; } @@ -492,7 +495,8 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz) * Write data **/ if (!wilc_spi_write(wilc, &b[ix], nbytes)) { - PRINT_ER("[wilc spi]: Failed data block write, bus error...\n"); + dev_err(&spi->dev, + "Failed data block write, bus error...\n"); result = N_FAIL; break; } @@ -502,7 +506,7 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz) **/ if (!g_spi.crc_off) { if (!wilc_spi_write(wilc, crc, 2)) { - PRINT_ER("[wilc spi]: Failed data block crc write, bus error...\n"); + dev_err(&spi->dev,"Failed data block crc write, bus error...\n"); result = N_FAIL; break; } @@ -527,13 +531,14 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz) static int spi_internal_write(struct wilc *wilc, u32 adr, u32 dat) { + struct spi_device *spi = to_spi_device(wilc->dev); int result; dat = cpu_to_le32(dat); result = spi_cmd_complete(wilc, CMD_INTERNAL_WRITE, adr, (u8 *)&dat, 4, 0); if (result != N_OK) { - PRINT_ER("[wilc spi]: Failed internal write cmd...\n"); + dev_err(&spi->dev, "Failed internal write cmd...\n"); } return result; @@ -541,12 +546,13 @@ static int spi_internal_write(struct wilc *wilc, u32 adr, u32 dat) static int spi_internal_read(struct wilc *wilc, u32 adr, u32 *data) { + struct spi_device *spi = to_spi_device(wilc->dev); int result; result = spi_cmd_complete(wilc, CMD_INTERNAL_READ, adr, (u8 *)data, 4, 0); if (result != N_OK) { - PRINT_ER("[wilc spi]: Failed internal read cmd...\n"); + dev_err(&spi->dev, "Failed internal read cmd...\n"); return 0; } @@ -563,6 +569,7 @@ static int spi_internal_read(struct wilc *wilc, u32 adr, u32 *data) static int wilc_spi_write_reg(struct wilc *wilc, u32 addr, u32 data) { + struct spi_device *spi = to_spi_device(wilc->dev); int result = N_OK; u8 cmd = CMD_SINGLE_WRITE; u8 clockless = 0; @@ -576,7 +583,7 @@ static int wilc_spi_write_reg(struct wilc *wilc, u32 addr, u32 data) result = spi_cmd_complete(wilc, cmd, addr, (u8 *)&data, 4, clockless); if (result != N_OK) { - PRINT_ER("[wilc spi]: Failed cmd, write reg (%08x)...\n", addr); + dev_err(&spi->dev, "Failed cmd, write reg (%08x)...\n", addr); } return result; @@ -584,6 +591,7 @@ static int wilc_spi_write_reg(struct wilc *wilc, u32 addr, u32 data) static int _wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { + struct spi_device *spi = to_spi_device(wilc->dev); int result; u8 cmd = CMD_DMA_EXT_WRITE; @@ -595,7 +603,8 @@ static int _wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) result = spi_cmd_complete(wilc, cmd, addr, NULL, size, 0); if (result != N_OK) { - PRINT_ER("[wilc spi]: Failed cmd, write block (%08x)...\n", addr); + dev_err(&spi->dev, + "Failed cmd, write block (%08x)...\n", addr); return 0; } @@ -604,7 +613,7 @@ static int _wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) **/ result = spi_data_write(wilc, buf, size); if (result != N_OK) { - PRINT_ER("[wilc spi]: Failed block data write...\n"); + dev_err(&spi->dev, "Failed block data write...\n"); } return 1; @@ -612,12 +621,13 @@ static int _wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data) { + struct spi_device *spi = to_spi_device(wilc->dev); int result = N_OK; u8 cmd = CMD_SINGLE_READ; u8 clockless = 0; if (addr < 0x30) { - /* PRINT_ER("***** read addr %d\n\n", addr); */ + /* dev_err(&spi->dev, "***** read addr %d\n\n", addr); */ /* Clockless register*/ cmd = CMD_INTERNAL_READ; clockless = 1; @@ -625,7 +635,7 @@ static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data) result = spi_cmd_complete(wilc, cmd, addr, (u8 *)data, 4, clockless); if (result != N_OK) { - PRINT_ER("[wilc spi]: Failed cmd, read reg (%08x)...\n", addr); + dev_err(&spi->dev, "Failed cmd, read reg (%08x)...\n", addr); return 0; } @@ -636,6 +646,7 @@ static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data) static int _wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { + struct spi_device *spi = to_spi_device(wilc->dev); u8 cmd = CMD_DMA_EXT_READ; int result; @@ -644,7 +655,7 @@ static int _wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) result = spi_cmd_complete(wilc, cmd, addr, buf, size, 0); if (result != N_OK) { - PRINT_ER("[wilc spi]: Failed cmd, read block (%08x)...\n", addr); + dev_err(&spi->dev, "Failed cmd, read block (%08x)...\n", addr); return 0; } @@ -659,10 +670,12 @@ static int _wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) static int wilc_spi_clear_int(struct wilc *wilc) { + struct spi_device *spi = to_spi_device(wilc->dev); u32 reg; if (!wilc_spi_read_reg(wilc, WILC_HOST_RX_CTRL_0, ®)) { - PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0); + dev_err(&spi->dev, "Failed read reg (%08x)...\n", + WILC_HOST_RX_CTRL_0); return 0; } reg &= ~0x1; @@ -680,6 +693,7 @@ static int _wilc_spi_deinit(struct wilc *wilc) static int wilc_spi_sync(struct wilc *wilc) { + struct spi_device *spi = to_spi_device(wilc->dev); u32 reg; int ret; @@ -688,13 +702,15 @@ static int wilc_spi_sync(struct wilc *wilc) **/ ret = wilc_spi_read_reg(wilc, WILC_PIN_MUX_0, ®); if (!ret) { - PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); + dev_err(&spi->dev,"Failed read reg (%08x)...\n", + WILC_PIN_MUX_0); return 0; } reg |= BIT(8); ret = wilc_spi_write_reg(wilc, WILC_PIN_MUX_0, reg); if (!ret) { - PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); + dev_err(&spi->dev, "Failed write reg (%08x)...\n", + WILC_PIN_MUX_0); return 0; } @@ -703,13 +719,15 @@ static int wilc_spi_sync(struct wilc *wilc) **/ ret = wilc_spi_read_reg(wilc, WILC_INTR_ENABLE, ®); if (!ret) { - PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); + dev_err(&spi->dev, "Failed read reg (%08x)...\n", + WILC_INTR_ENABLE); return 0; } reg |= BIT(16); ret = wilc_spi_write_reg(wilc, WILC_INTR_ENABLE, reg); if (!ret) { - PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); + dev_err(&spi->dev, "Failed write reg (%08x)...\n", + WILC_INTR_ENABLE); return 0; } @@ -718,6 +736,7 @@ static int wilc_spi_sync(struct wilc *wilc) static int _wilc_spi_init(struct wilc *wilc, wilc_debug_func func) { + struct spi_device *spi = to_spi_device(wilc->dev); u32 reg; u32 chipid; @@ -726,7 +745,7 @@ static int _wilc_spi_init(struct wilc *wilc, wilc_debug_func func) if (isinit) { if (!wilc_spi_read_reg(wilc, 0x1000, &chipid)) { - PRINT_ER("[wilc spi]: Fail cmd read chip id...\n"); + dev_err(&spi->dev, "Fail cmd read chip id...\n"); return 0; } return 1; @@ -734,9 +753,8 @@ static int _wilc_spi_init(struct wilc *wilc, wilc_debug_func func) memset(&g_spi, 0, sizeof(wilc_spi_t)); - g_spi.dPrint = func; if (!wilc_spi_init()) { - PRINT_ER("[wilc spi]: Failed io init bus...\n"); + dev_err(&spi->dev, "Failed io init bus...\n"); return 0; } else { return 0; @@ -753,10 +771,11 @@ static int _wilc_spi_init(struct wilc *wilc, wilc_debug_func func) /* Read failed. Try with CRC off. This might happen when module * is removed but chip isn't reset*/ g_spi.crc_off = 1; - PRINT_ER("[wilc spi]: Failed internal read protocol with CRC on, retyring with CRC off...\n"); + dev_err(&spi->dev, "Failed internal read protocol with CRC on, retyring with CRC off...\n"); if (!spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, ®)) { /* Reaad failed with both CRC on and off, something went bad */ - PRINT_ER("[wilc spi]: Failed internal read protocol...\n"); + dev_err(&spi->dev, + "Failed internal read protocol...\n"); return 0; } } @@ -765,7 +784,7 @@ static int _wilc_spi_init(struct wilc *wilc, wilc_debug_func func) reg &= ~0x70; reg |= (0x5 << 4); if (!spi_internal_write(wilc, WILC_SPI_PROTOCOL_OFFSET, reg)) { - PRINT_ER("[wilc spi %d]: Failed internal write protocol reg...\n", __LINE__); + dev_err(&spi->dev, "[wilc spi %d]: Failed internal write protocol reg...\n", __LINE__); return 0; } g_spi.crc_off = 1; @@ -776,10 +795,10 @@ static int _wilc_spi_init(struct wilc *wilc, wilc_debug_func func) * make sure can read back chip id correctly **/ if (!wilc_spi_read_reg(wilc, 0x1000, &chipid)) { - PRINT_ER("[wilc spi]: Fail cmd read chip id...\n"); + dev_err(&spi->dev, "Fail cmd read chip id...\n"); return 0; } - /* PRINT_ER("[wilc spi]: chipid (%08x)\n", chipid); */ + /* dev_err(&spi->dev, "chipid (%08x)\n", chipid); */ g_spi.has_thrpt_enh = 1; @@ -790,6 +809,7 @@ static int _wilc_spi_init(struct wilc *wilc, wilc_debug_func func) static int wilc_spi_read_size(struct wilc *wilc, u32 *size) { + struct spi_device *spi = to_spi_device(wilc->dev); int ret; if (g_spi.has_thrpt_enh) { @@ -803,7 +823,8 @@ static int wilc_spi_read_size(struct wilc *wilc, u32 *size) ret = wilc_spi_read_reg(wilc, WILC_VMM_TO_HOST_SIZE, &byte_cnt); if (!ret) { - PRINT_ER("[wilc spi]: Failed read WILC_VMM_TO_HOST_SIZE ...\n"); + dev_err(&spi->dev, + "Failed read WILC_VMM_TO_HOST_SIZE ...\n"); goto _fail_; } tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK; @@ -820,6 +841,7 @@ _fail_: static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status) { + struct spi_device *spi = to_spi_device(wilc->dev); int ret; if (g_spi.has_thrpt_enh) { @@ -832,7 +854,8 @@ static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status) ret = wilc_spi_read_reg(wilc, WILC_VMM_TO_HOST_SIZE, &byte_cnt); if (!ret) { - PRINT_ER("[wilc spi]: Failed read WILC_VMM_TO_HOST_SIZE ...\n"); + dev_err(&spi->dev, + "Failed read WILC_VMM_TO_HOST_SIZE ...\n"); goto _fail_; } tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK; @@ -861,7 +884,7 @@ static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status) unkmown_mask = ~((1ul << g_spi.nint) - 1); if ((tmp >> IRG_FLAGS_OFFSET) & unkmown_mask) { - PRINT_ER("[wilc spi]: Unexpected interrupt (2): j=%d, tmp=%x, mask=%x\n", j, tmp, unkmown_mask); + dev_err(&spi->dev, "Unexpected interrupt (2): j=%d, tmp=%x, mask=%x\n", j, tmp, unkmown_mask); happended = 1; } } @@ -879,6 +902,7 @@ _fail_: static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val) { + struct spi_device *spi = to_spi_device(wilc->dev); int ret; if (g_spi.has_thrpt_enh) { @@ -901,12 +925,16 @@ static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val) flags >>= 1; } if (!ret) { - PRINT_ER("[wilc spi]: Failed wilc_spi_write_reg, set reg %x ...\n", 0x10c8 + i * 4); + dev_err(&spi->dev, + "Failed wilc_spi_write_reg, set reg %x ...\n", + 0x10c8 + i * 4); goto _fail_; } for (i = g_spi.nint; i < MAX_NUM_INT; i++) { if (flags & 1) - PRINT_ER("[wilc spi]: Unexpected interrupt cleared %d...\n", i); + dev_err(&spi->dev, + "Unexpected interrupt cleared %d...\n", + i); flags >>= 1; } } @@ -925,7 +953,8 @@ static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val) ret = wilc_spi_write_reg(wilc, WILC_VMM_TBL_CTL, tbl_ctl); if (!ret) { - PRINT_ER("[wilc spi]: fail write reg vmm_tbl_ctl...\n"); + dev_err(&spi->dev, + "fail write reg vmm_tbl_ctl...\n"); goto _fail_; } @@ -936,7 +965,7 @@ static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val) ret = wilc_spi_write_reg(wilc, WILC_VMM_CORE_CTL, 1); if (!ret) { - PRINT_ER("[wilc spi]: fail write reg vmm_core_ctl...\n"); + dev_err(&spi->dev,"fail write reg vmm_core_ctl...\n"); goto _fail_; } } @@ -948,11 +977,12 @@ _fail_: static int wilc_spi_sync_ext(struct wilc *wilc, int nint) { + struct spi_device *spi = to_spi_device(wilc->dev); u32 reg; int ret, i; if (nint > MAX_NUM_INT) { - PRINT_ER("[wilc spi]: Too many interupts (%d)...\n", nint); + dev_err(&spi->dev, "Too many interupts (%d)...\n", nint); return 0; } @@ -963,13 +993,15 @@ static int wilc_spi_sync_ext(struct wilc *wilc, int nint) **/ ret = wilc_spi_read_reg(wilc, WILC_PIN_MUX_0, ®); if (!ret) { - PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); + dev_err(&spi->dev, "Failed read reg (%08x)...\n", + WILC_PIN_MUX_0); return 0; } reg |= BIT(8); ret = wilc_spi_write_reg(wilc, WILC_PIN_MUX_0, reg); if (!ret) { - PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); + dev_err(&spi->dev, "Failed write reg (%08x)...\n", + WILC_PIN_MUX_0); return 0; } @@ -978,7 +1010,8 @@ static int wilc_spi_sync_ext(struct wilc *wilc, int nint) **/ ret = wilc_spi_read_reg(wilc, WILC_INTR_ENABLE, ®); if (!ret) { - PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); + dev_err(&spi->dev, "Failed read reg (%08x)...\n", + WILC_INTR_ENABLE); return 0; } @@ -987,13 +1020,15 @@ static int wilc_spi_sync_ext(struct wilc *wilc, int nint) } ret = wilc_spi_write_reg(wilc, WILC_INTR_ENABLE, reg); if (!ret) { - PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); + dev_err(&spi->dev, "Failed write reg (%08x)...\n", + WILC_INTR_ENABLE); return 0; } if (nint) { ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, ®); if (!ret) { - PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR2_ENABLE); + dev_err(&spi->dev, "Failed read reg (%08x)...\n", + WILC_INTR2_ENABLE); return 0; } @@ -1003,7 +1038,8 @@ static int wilc_spi_sync_ext(struct wilc *wilc, int nint) ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, ®); if (!ret) { - PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR2_ENABLE); + dev_err(&spi->dev, "Failed write reg (%08x)...\n", + WILC_INTR2_ENABLE); return 0; } } -- GitLab From 28b01ff59443155dff491e5ce94ecfeb898e8c9a Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:14 +0900 Subject: [PATCH 1768/2855] staging: wilc1000: remove wilc_debug_func of hif_init This patch removes wilc_debug_func of hif_init and remove it's related functions as well because it is not used anymore. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_sdio.c | 2 +- drivers/staging/wilc1000/wilc_spi.c | 2 +- drivers/staging/wilc1000/wilc_wlan.c | 2 +- drivers/staging/wilc1000/wilc_wlan.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index dfa3d3a7fcacd..efa337965e68b 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -512,7 +512,7 @@ static int sdio_sync(struct wilc *wilc) return 1; } -static int sdio_init(struct wilc *wilc, wilc_debug_func debug_func) +static int sdio_init(struct wilc *wilc) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); sdio_cmd52_t cmd; diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 806012599bb33..478a356de2874 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -734,7 +734,7 @@ static int wilc_spi_sync(struct wilc *wilc) return 1; } -static int _wilc_spi_init(struct wilc *wilc, wilc_debug_func func) +static int _wilc_spi_init(struct wilc *wilc) { struct spi_device *spi = to_spi_device(wilc->dev); u32 reg; diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 0427349354f4b..32ecc2df91aa3 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1587,7 +1587,7 @@ int wilc_wlan_init(struct net_device *dev) PRINT_D(INIT_DBG, "Initializing WILC_Wlan ...\n"); - if (!wilc->hif_func->hif_init(wilc, wilc_debug)) { + if (!wilc->hif_func->hif_init(wilc)) { ret = -EIO; goto _fail_; } diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 366645318ad27..580e1d60221be 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -226,7 +226,7 @@ struct rxq_entry_t { ********************************************/ struct wilc; struct wilc_hif_func { - int (*hif_init)(struct wilc *, wilc_debug_func); + int (*hif_init)(struct wilc *); int (*hif_deinit)(struct wilc *); int (*hif_read_reg)(struct wilc *, u32, u32 *); int (*hif_write_reg)(struct wilc *, u32, u32); -- GitLab From 491a2ed74d7e8152ea16430b4259d38ded59fb4c Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:15 +0900 Subject: [PATCH 1769/2855] staging: wilc1000: remove unused functions This patch removes unused function pointer hif_sync and hif_clear_int, and removes it's related functions sdio_clear_int, sdio_sync, wilc_spi_clear_int and wilc_spi_sync. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_sdio.c | 94 ---------------------------- drivers/staging/wilc1000/wilc_spi.c | 60 ------------------ drivers/staging/wilc1000/wilc_wlan.h | 2 - 3 files changed, 156 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index efa337965e68b..325e274a64d26 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -130,37 +130,6 @@ _fail_: return 0; } -static int sdio_clear_int(struct wilc *wilc) -{ - struct sdio_func *func = dev_to_sdio_func(wilc->dev); - - if (!g_sdio.irq_gpio) { - /* u32 sts; */ - sdio_cmd52_t cmd; - - cmd.read_write = 0; - cmd.function = 1; - cmd.raw = 0; - cmd.address = 0x4; - cmd.data = 0; - wilc_sdio_cmd52(wilc, &cmd); - - return cmd.data; - } else { - u32 reg; - - if (!sdio_read_reg(wilc, WILC_HOST_RX_CTRL_0, ®)) { - dev_err(&func->dev, "Failed read reg (%08x)...\n", - WILC_HOST_RX_CTRL_0); - return 0; - } - reg &= ~0x1; - sdio_write_reg(wilc, WILC_HOST_RX_CTRL_0, reg); - return 1; - } - -} - /******************************************** * * Sdio interfaces @@ -451,67 +420,6 @@ static int sdio_deinit(struct wilc *wilc) return 1; } -static int sdio_sync(struct wilc *wilc) -{ - struct sdio_func *func = dev_to_sdio_func(wilc->dev); - u32 reg; - - /** - * Disable power sequencer - **/ - if (!sdio_read_reg(wilc, WILC_MISC, ®)) { - dev_err(&func->dev, "Failed read misc reg...\n"); - return 0; - } - - reg &= ~BIT(8); - if (!sdio_write_reg(wilc, WILC_MISC, reg)) { - dev_err(&func->dev, "Failed write misc reg...\n"); - return 0; - } - - if (g_sdio.irq_gpio) { - u32 reg; - int ret; - - /** - * interrupt pin mux select - **/ - ret = sdio_read_reg(wilc, WILC_PIN_MUX_0, ®); - if (!ret) { - dev_err(&func->dev, "Failed read reg (%08x)...\n", - WILC_PIN_MUX_0); - return 0; - } - reg |= BIT(8); - ret = sdio_write_reg(wilc, WILC_PIN_MUX_0, reg); - if (!ret) { - dev_err(&func->dev, "Failed write reg (%08x)...\n", - WILC_PIN_MUX_0); - return 0; - } - - /** - * interrupt enable - **/ - ret = sdio_read_reg(wilc, WILC_INTR_ENABLE, ®); - if (!ret) { - dev_err(&func->dev, "Failed read reg (%08x)...\n", - WILC_INTR_ENABLE); - return 0; - } - reg |= BIT(16); - ret = sdio_write_reg(wilc, WILC_INTR_ENABLE, reg); - if (!ret) { - dev_err(&func->dev, "Failed write reg (%08x)...\n", - WILC_INTR_ENABLE); - return 0; - } - } - - return 1; -} - static int sdio_init(struct wilc *wilc) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); @@ -952,8 +860,6 @@ const struct wilc_hif_func wilc_hif_sdio = { .hif_write_reg = sdio_write_reg, .hif_block_rx = sdio_read, .hif_block_tx = sdio_write, - .hif_sync = sdio_sync, - .hif_clear_int = sdio_clear_int, .hif_read_int = sdio_read_int, .hif_clear_int_ext = sdio_clear_int_ext, .hif_read_size = sdio_read_size, diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 478a356de2874..faaeaf7cba865 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -668,21 +668,6 @@ static int _wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) * ********************************************/ -static int wilc_spi_clear_int(struct wilc *wilc) -{ - struct spi_device *spi = to_spi_device(wilc->dev); - u32 reg; - - if (!wilc_spi_read_reg(wilc, WILC_HOST_RX_CTRL_0, ®)) { - dev_err(&spi->dev, "Failed read reg (%08x)...\n", - WILC_HOST_RX_CTRL_0); - return 0; - } - reg &= ~0x1; - wilc_spi_write_reg(wilc, WILC_HOST_RX_CTRL_0, reg); - return 1; -} - static int _wilc_spi_deinit(struct wilc *wilc) { /** @@ -691,49 +676,6 @@ static int _wilc_spi_deinit(struct wilc *wilc) return 1; } -static int wilc_spi_sync(struct wilc *wilc) -{ - struct spi_device *spi = to_spi_device(wilc->dev); - u32 reg; - int ret; - - /** - * interrupt pin mux select - **/ - ret = wilc_spi_read_reg(wilc, WILC_PIN_MUX_0, ®); - if (!ret) { - dev_err(&spi->dev,"Failed read reg (%08x)...\n", - WILC_PIN_MUX_0); - return 0; - } - reg |= BIT(8); - ret = wilc_spi_write_reg(wilc, WILC_PIN_MUX_0, reg); - if (!ret) { - dev_err(&spi->dev, "Failed write reg (%08x)...\n", - WILC_PIN_MUX_0); - return 0; - } - - /** - * interrupt enable - **/ - ret = wilc_spi_read_reg(wilc, WILC_INTR_ENABLE, ®); - if (!ret) { - dev_err(&spi->dev, "Failed read reg (%08x)...\n", - WILC_INTR_ENABLE); - return 0; - } - reg |= BIT(16); - ret = wilc_spi_write_reg(wilc, WILC_INTR_ENABLE, reg); - if (!ret) { - dev_err(&spi->dev, "Failed write reg (%08x)...\n", - WILC_INTR_ENABLE); - return 0; - } - - return 1; -} - static int _wilc_spi_init(struct wilc *wilc) { struct spi_device *spi = to_spi_device(wilc->dev); @@ -1058,8 +1000,6 @@ const struct wilc_hif_func wilc_hif_spi = { .hif_write_reg = wilc_spi_write_reg, .hif_block_rx = _wilc_spi_read, .hif_block_tx = _wilc_spi_write, - .hif_sync = wilc_spi_sync, - .hif_clear_int = wilc_spi_clear_int, .hif_read_int = wilc_spi_read_int, .hif_clear_int_ext = wilc_spi_clear_int_ext, .hif_read_size = wilc_spi_read_size, diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 580e1d60221be..2edd7445f4a33 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -232,8 +232,6 @@ struct wilc_hif_func { int (*hif_write_reg)(struct wilc *, u32, u32); int (*hif_block_rx)(struct wilc *, u32, u8 *, u32); int (*hif_block_tx)(struct wilc *, u32, u8 *, u32); - int (*hif_sync)(struct wilc *); - int (*hif_clear_int)(struct wilc *); int (*hif_read_int)(struct wilc *, u32 *); int (*hif_clear_int_ext)(struct wilc *, u32); int (*hif_read_size)(struct wilc *, u32 *); -- GitLab From 3cf9c9a7ffb7a6b67683259cf21c0c4fde1301d6 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:16 +0900 Subject: [PATCH 1770/2855] staging: wilc1000: linux_wlan_sdio.c: fix checkpatch warning line over 80 This patch fixes checkpatch warning line over 80 characters. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_sdio.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index 66cdca23b1b4a..78e6808e7e94d 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -74,9 +74,11 @@ int wilc_sdio_cmd53(struct wilc *wilc, sdio_cmd53_t *cmd) size = cmd->count; if (cmd->read_write) { /* write */ - ret = sdio_memcpy_toio(func, cmd->address, (void *)cmd->buffer, size); + ret = sdio_memcpy_toio(func, cmd->address, + (void *)cmd->buffer, size); } else { /* read */ - ret = sdio_memcpy_fromio(func, (void *)cmd->buffer, cmd->address, size); + ret = sdio_memcpy_fromio(func, (void *)cmd->buffer, + cmd->address, size); } sdio_release_host(func); @@ -90,7 +92,8 @@ int wilc_sdio_cmd53(struct wilc *wilc, sdio_cmd53_t *cmd) return 1; } -static int linux_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) +static int linux_sdio_probe(struct sdio_func *func, + const struct sdio_device_id *id) { struct wilc *wilc; int gpio; @@ -126,7 +129,9 @@ static struct sdio_driver wilc1000_sdio_driver = { .probe = linux_sdio_probe, .remove = linux_sdio_remove, }; -module_driver(wilc1000_sdio_driver, sdio_register_driver, sdio_unregister_driver); +module_driver(wilc1000_sdio_driver, + sdio_register_driver, + sdio_unregister_driver); MODULE_LICENSE("GPL"); int wilc_sdio_enable_interrupt(struct wilc *dev) -- GitLab From 58ed46f795141a6579df88bd506c3458ce6c4918 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:17 +0900 Subject: [PATCH 1771/2855] staging: wilc1000: linux_wlan_sdio.c: remove braces This patch fixes checkpatch warning braces{} are not necessary for single statment blocks. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_sdio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index 78e6808e7e94d..64fb81b331bd6 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -159,9 +159,8 @@ void wilc_sdio_disable_interrupt(struct wilc *dev) sdio_claim_host(func); ret = sdio_release_irq(func); - if (ret < 0) { + if (ret < 0) dev_err(&func->dev, "can't release sdio_irq, err(%d)\n", ret); - } sdio_release_host(func); dev_info(&func->dev, "wilc_sdio_disable_interrupt OUT\n"); -- GitLab From 6f8bded28878ce8c750f33b53a50382ed767eb6c Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:18 +0900 Subject: [PATCH 1772/2855] staging: wilc1000: wilc_sdio_cmd53: return linux error value This patch changes return value with linux error value, not 1 or 0. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_sdio.c | 7 ++---- drivers/staging/wilc1000/wilc_sdio.c | 26 +++++++++++++--------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index 64fb81b331bd6..a918de942cb4a 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -83,13 +83,10 @@ int wilc_sdio_cmd53(struct wilc *wilc, sdio_cmd53_t *cmd) sdio_release_host(func); - - if (ret < 0) { + if (ret) dev_err(&func->dev, "wilc_sdio_cmd53..failed, err(%d)\n", ret); - return 0; - } - return 1; + return ret; } static int linux_sdio_probe(struct sdio_func *func, diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index 325e274a64d26..d1b023ad4afea 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -138,6 +138,7 @@ _fail_: static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); + int ret; data = cpu_to_le32(data); @@ -171,8 +172,8 @@ static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) cmd.count = 4; cmd.buffer = (u8 *)&data; cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */ - - if (!wilc_sdio_cmd53(wilc, &cmd)) { + ret = wilc_sdio_cmd53(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Failed cmd53, write reg (%08x)...\n", addr); goto _fail_; @@ -191,7 +192,7 @@ static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) struct sdio_func *func = dev_to_sdio_func(wilc->dev); u32 block_size = g_sdio.block_size; sdio_cmd53_t cmd; - int nblk, nleft; + int nblk, nleft, ret; cmd.read_write = 1; if (addr > 0) { @@ -237,7 +238,8 @@ static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) if (!sdio_set_func0_csa_address(wilc, addr)) goto _fail_; } - if (!wilc_sdio_cmd53(wilc, &cmd)) { + ret = wilc_sdio_cmd53(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Failed cmd53 [%x], block send...\n", addr); goto _fail_; @@ -259,7 +261,8 @@ static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) if (!sdio_set_func0_csa_address(wilc, addr)) goto _fail_; } - if (!wilc_sdio_cmd53(wilc, &cmd)) { + ret = wilc_sdio_cmd53(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Failed cmd53 [%x], bytes send...\n", addr); goto _fail_; @@ -276,6 +279,7 @@ _fail_: static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); + int ret; if ((addr >= 0xf0) && (addr <= 0xff)) { sdio_cmd52_t cmd; @@ -305,8 +309,8 @@ static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) cmd.buffer = (u8 *)data; cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */ - - if (!wilc_sdio_cmd53(wilc, &cmd)) { + ret = wilc_sdio_cmd53(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Failed cmd53, read reg (%08x)...\n", addr); goto _fail_; @@ -327,7 +331,7 @@ static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) struct sdio_func *func = dev_to_sdio_func(wilc->dev); u32 block_size = g_sdio.block_size; sdio_cmd53_t cmd; - int nblk, nleft; + int nblk, nleft, ret; cmd.read_write = 0; if (addr > 0) { @@ -373,7 +377,8 @@ static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) if (!sdio_set_func0_csa_address(wilc, addr)) goto _fail_; } - if (!wilc_sdio_cmd53(wilc, &cmd)) { + ret = wilc_sdio_cmd53(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Failed cmd53 [%x], block read...\n", addr); goto _fail_; @@ -395,7 +400,8 @@ static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) if (!sdio_set_func0_csa_address(wilc, addr)) goto _fail_; } - if (!wilc_sdio_cmd53(wilc, &cmd)) { + ret = wilc_sdio_cmd53(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Failed cmd53 [%x], bytes read...\n", addr); goto _fail_; -- GitLab From 28e9ad2aca609370e5c7a42e926652dd98ff7ed2 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:19 +0900 Subject: [PATCH 1773/2855] staging: wilc1000: wilc_sdio_cmd52: return linux error value This patch changes return value with linux error value, not 1 or 0. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_sdio.c | 6 +-- drivers/staging/wilc1000/wilc_sdio.c | 51 ++++++++++++++-------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index a918de942cb4a..e25811d2c5b59 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -51,11 +51,9 @@ int wilc_sdio_cmd52(struct wilc *wilc, sdio_cmd52_t *cmd) sdio_release_host(func); - if (ret < 0) { + if (ret) dev_err(&func->dev, "wilc_sdio_cmd52..failed, err(%d)\n", ret); - return 0; - } - return 1; + return ret; } diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index d1b023ad4afea..fa1adcf3b683f 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -38,6 +38,7 @@ static int sdio_set_func0_csa_address(struct wilc *wilc, u32 adr) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); sdio_cmd52_t cmd; + int ret; /** * Review: BIG ENDIAN @@ -47,21 +48,24 @@ static int sdio_set_func0_csa_address(struct wilc *wilc, u32 adr) cmd.raw = 0; cmd.address = 0x10c; cmd.data = (u8)adr; - if (!wilc_sdio_cmd52(wilc, &cmd)) { + ret = wilc_sdio_cmd52(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Failed cmd52, set 0x10c data...\n"); goto _fail_; } cmd.address = 0x10d; cmd.data = (u8)(adr >> 8); - if (!wilc_sdio_cmd52(wilc, &cmd)) { + ret = wilc_sdio_cmd52(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Failed cmd52, set 0x10d data...\n"); goto _fail_; } cmd.address = 0x10e; cmd.data = (u8)(adr >> 16); - if (!wilc_sdio_cmd52(wilc, &cmd)) { + ret = wilc_sdio_cmd52(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Failed cmd52, set 0x10e data...\n"); goto _fail_; } @@ -75,20 +79,23 @@ static int sdio_set_func0_block_size(struct wilc *wilc, u32 block_size) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); sdio_cmd52_t cmd; + int ret; cmd.read_write = 1; cmd.function = 0; cmd.raw = 0; cmd.address = 0x10; cmd.data = (u8)block_size; - if (!wilc_sdio_cmd52(wilc, &cmd)) { + ret = wilc_sdio_cmd52(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Failed cmd52, set 0x10 data...\n"); goto _fail_; } cmd.address = 0x11; cmd.data = (u8)(block_size >> 8); - if (!wilc_sdio_cmd52(wilc, &cmd)) { + ret = wilc_sdio_cmd52(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Failed cmd52, set 0x11 data...\n"); goto _fail_; } @@ -108,19 +115,22 @@ static int sdio_set_func1_block_size(struct wilc *wilc, u32 block_size) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); sdio_cmd52_t cmd; + int ret; cmd.read_write = 1; cmd.function = 0; cmd.raw = 0; cmd.address = 0x110; cmd.data = (u8)block_size; - if (!wilc_sdio_cmd52(wilc, &cmd)) { + ret = wilc_sdio_cmd52(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Failed cmd52, set 0x110 data...\n"); goto _fail_; } cmd.address = 0x111; cmd.data = (u8)(block_size >> 8); - if (!wilc_sdio_cmd52(wilc, &cmd)) { + ret = wilc_sdio_cmd52(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Failed cmd52, set 0x111 data...\n"); goto _fail_; } @@ -150,7 +160,8 @@ static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) cmd.raw = 0; cmd.address = addr; cmd.data = data; - if (!wilc_sdio_cmd52(wilc, &cmd)) { + ret = wilc_sdio_cmd52(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Failed cmd 52, read reg (%08x) ...\n", addr); goto _fail_; @@ -288,7 +299,8 @@ static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) cmd.function = 0; cmd.raw = 0; cmd.address = addr; - if (!wilc_sdio_cmd52(wilc, &cmd)) { + ret = wilc_sdio_cmd52(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Failed cmd 52, read reg (%08x) ...\n", addr); goto _fail_; @@ -430,7 +442,7 @@ static int sdio_init(struct wilc *wilc) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); sdio_cmd52_t cmd; - int loop; + int loop, ret; u32 chipid; memset(&g_sdio, 0, sizeof(wilc_sdio_t)); @@ -452,7 +464,8 @@ static int sdio_init(struct wilc *wilc) cmd.raw = 1; cmd.address = 0x100; cmd.data = 0x80; - if (!wilc_sdio_cmd52(wilc, &cmd)) { + ret = wilc_sdio_cmd52(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Fail cmd 52, enable csa...\n"); goto _fail_; } @@ -474,7 +487,8 @@ static int sdio_init(struct wilc *wilc) cmd.raw = 1; cmd.address = 0x2; cmd.data = 0x2; - if (!wilc_sdio_cmd52(wilc, &cmd)) { + ret = wilc_sdio_cmd52(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Fail cmd 52, set IOE register...\n"); goto _fail_; @@ -490,7 +504,8 @@ static int sdio_init(struct wilc *wilc) loop = 3; do { cmd.data = 0; - if (!wilc_sdio_cmd52(wilc, &cmd)) { + ret = wilc_sdio_cmd52(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Fail cmd 52, get IOR register...\n"); goto _fail_; @@ -520,7 +535,8 @@ static int sdio_init(struct wilc *wilc) cmd.raw = 1; cmd.address = 0x4; cmd.data = 0x3; - if (!wilc_sdio_cmd52(wilc, &cmd)) { + ret = wilc_sdio_cmd52(wilc, &cmd); + if (ret) { dev_err(&func->dev, "Fail cmd 52, set IEN register...\n"); goto _fail_; } @@ -548,7 +564,6 @@ _fail_: static int sdio_read_size(struct wilc *wilc, u32 *size) { - u32 tmp; sdio_cmd52_t cmd; @@ -667,7 +682,7 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val) cmd.data = reg; ret = wilc_sdio_cmd52(wilc, &cmd); - if (!ret) { + if (ret) { dev_err(&func->dev, "Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__); @@ -697,7 +712,7 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val) cmd.data = BIT(i); ret = wilc_sdio_cmd52(wilc, &cmd); - if (!ret) { + if (ret) { dev_err(&func->dev, "Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__); @@ -744,7 +759,7 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val) cmd.address = 0xf6; cmd.data = vmm_ctl; ret = wilc_sdio_cmd52(wilc, &cmd); - if (!ret) { + if (ret) { dev_err(&func->dev, "Failed cmd52, set 0xf6 data (%d) ...\n", __LINE__); -- GitLab From 5b46e16702e2413e3e885f4acf122505ecdaa03c Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:20 +0900 Subject: [PATCH 1774/2855] staging: wilc1000: linux_wlan_spi.c: remove braces for single statement This patches fixes checkpatch warning: braces {} are not necessary for single statement blocks. Remove some comments also. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_spi.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index 01fa6fa0cc1df..6fcf7b39880ec 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -15,7 +15,7 @@ #include "linux_wlan_common.h" #include "wilc_wlan_if.h" -#define USE_SPI_DMA 0 /* johnny add */ +#define USE_SPI_DMA 0 static const struct wilc1000_ops wilc1000_spi_ops; @@ -87,16 +87,13 @@ int wilc_spi_write(struct wilc *wilc, u8 *b, u32 len) memset(&msg, 0, sizeof(msg)); spi_message_init(&msg); -/* [[johnny add */ msg.spi = spi; msg.is_dma_mapped = USE_SPI_DMA; -/* ]] */ spi_message_add_tail(&tr, &msg); ret = spi_sync(spi, &msg); - if (ret < 0) { + if (ret < 0) dev_err(&spi->dev, "SPI transaction failed\n"); - } kfree(r_buffer); } else { @@ -137,16 +134,13 @@ int wilc_spi_read(struct wilc *wilc, u8 *rb, u32 rlen) memset(&msg, 0, sizeof(msg)); spi_message_init(&msg); -/* [[ johnny add */ msg.spi = spi; msg.is_dma_mapped = USE_SPI_DMA; -/* ]] */ spi_message_add_tail(&tr, &msg); ret = spi_sync(spi, &msg); - if (ret < 0) { + if (ret < 0) dev_err(&spi->dev, "SPI transaction failed\n"); - } kfree(t_buffer); } else { dev_err(&spi->dev, @@ -183,9 +177,8 @@ int wilc_spi_write_read(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen) spi_message_add_tail(&tr, &msg); ret = spi_sync(spi, &msg); - if (ret < 0) { + if (ret < 0) dev_err(&spi->dev, "SPI transaction failed\n"); - } } else { dev_err(&spi->dev, "can't read data with the following length: %u\n", -- GitLab From d8506598003ba874317e7dc632339fc9052043a8 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:21 +0900 Subject: [PATCH 1775/2855] staging: wilc1000: linux_wlan_spi.c: add a blank This patch fixes checkpatch warning: missing a blank like after declarations. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_spi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index 6fcf7b39880ec..190243afb8ce2 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -79,6 +79,7 @@ int wilc_spi_write(struct wilc *wilc, u8 *b, u32 len) .delay_usecs = 0, }; char *r_buffer = kzalloc(len, GFP_KERNEL); + if (!r_buffer) return -ENOMEM; @@ -127,6 +128,7 @@ int wilc_spi_read(struct wilc *wilc, u8 *rb, u32 rlen) }; char *t_buffer = kzalloc(rlen, GFP_KERNEL); + if (!t_buffer) return -ENOMEM; -- GitLab From 3bac1c51dc2d61038155b298792e3663b356c0c4 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:22 +0900 Subject: [PATCH 1776/2855] staging: wilc1000: linux_wlan_spi.c: fix NULL comparison style This patch fixes checkpatch CHECK:comparison to NULL could be written "b". Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index 190243afb8ce2..61114057b8f7f 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -72,7 +72,7 @@ int wilc_spi_write(struct wilc *wilc, u8 *b, u32 len) int ret; struct spi_message msg; - if (len > 0 && b != NULL) { + if (len > 0 && b) { struct spi_transfer tr = { .tx_buf = b, .len = len, -- GitLab From 369a1d3bd3b357f9c7cc6ccb320c6b2e7680f9f5 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Mon, 21 Dec 2015 14:18:23 +0900 Subject: [PATCH 1777/2855] staging: wilc1000: replace explicit NULL comparisons with ! This patch replace explicit NULL comparison with ! operator to simplify code. Reported by checkpatch.pl for Comparison to NULL could be written !XXX" or "XXX". Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 71038b1c202df..bdc4537d87604 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -463,7 +463,7 @@ static void CfgScanResult(enum scan_event scan_event, down(&(priv->hSemScanReq)); - if (priv->pstrScanReq != NULL) { + if (priv->pstrScanReq) { cfg80211_scan_done(priv->pstrScanReq, false); priv->u32RcvdChCount = 0; priv->bCfgScanning = false; @@ -474,7 +474,7 @@ static void CfgScanResult(enum scan_event scan_event, down(&(priv->hSemScanReq)); PRINT_D(CFG80211_DBG, "Scan Aborted\n"); - if (priv->pstrScanReq != NULL) { + if (priv->pstrScanReq) { update_scan_time(); refresh_scan(priv, 1, false); @@ -645,7 +645,8 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) for (i = 0; i < request->n_ssids; i++) { - if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) { + if (request->ssids[i].ssid && + request->ssids[i].ssid_len != 0) { strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL); memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len); strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len; @@ -716,7 +717,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, sme->ssid, sme->ssid_len) == 0) { PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid); - if (sme->bssid == NULL) { + if (!sme->bssid) { PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n"); break; } else { @@ -1009,12 +1010,12 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, case WLAN_CIPHER_SUITE_TKIP: case WLAN_CIPHER_SUITE_CCMP: if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) { - if (priv->wilc_gtk[key_index] == NULL) { + if (!priv->wilc_gtk[key_index]) { priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL); priv->wilc_gtk[key_index]->key = NULL; priv->wilc_gtk[key_index]->seq = NULL; } - if (priv->wilc_ptk[key_index] == NULL) { + if (!priv->wilc_ptk[key_index]) { priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL); priv->wilc_ptk[key_index]->key = NULL; priv->wilc_ptk[key_index]->seq = NULL; @@ -1828,12 +1829,12 @@ static int mgmt_tx(struct wiphy *wiphy, if (ieee80211_is_mgmt(mgmt->frame_control)) { mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL); - if (mgmt_tx == NULL) { + if (!mgmt_tx) { PRINT_ER("Failed to allocate memory for mgmt_tx structure\n"); return -EFAULT; } mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL); - if (mgmt_tx->buff == NULL) { + if (!mgmt_tx->buff) { PRINT_ER("Failed to allocate memory for mgmt_tx buff\n"); kfree(mgmt_tx); return -EFAULT; @@ -2037,11 +2038,11 @@ static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout); - if (wiphy == NULL) + if (!wiphy) return -ENOENT; priv = wiphy_priv(wiphy); - if (priv->hWILCWFIDrv == NULL) { + if (!priv->hWILCWFIDrv) { PRINT_ER("Driver is NULL\n"); return -EIO; } @@ -2451,7 +2452,7 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n", strStaParams.rates_len); - if (params->ht_capa == NULL) { + if (!params->ht_capa) { strStaParams.ht_supported = false; } else { strStaParams.ht_supported = true; @@ -2511,7 +2512,7 @@ static int del_station(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "Deleting station\n"); - if (mac == NULL) { + if (!mac) { PRINT_D(HOSTAPD_DBG, "All associated stations\n"); s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss); } else { @@ -2557,7 +2558,7 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n", strStaParams.rates_len); - if (params->ht_capa == NULL) { + if (!params->ht_capa) { strStaParams.ht_supported = false; } else { strStaParams.ht_supported = true; @@ -2622,7 +2623,7 @@ static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy, PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n"); PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev); new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev); - if (new_ifc != NULL) { + if (new_ifc) { PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n"); nic = netdev_priv(priv->wdev->netdev); nic->monitor_flag = 1; @@ -2748,7 +2749,7 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *de PRINT_D(CFG80211_DBG, "Registering wifi device\n"); wdev = WILC_WFI_CfgAlloc(); - if (wdev == NULL) { + if (!wdev) { PRINT_ER("CfgAlloc Failed\n"); return NULL; } -- GitLab From 653bb46301617e39e720e60fa2e0a01f946c9a6e Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Mon, 21 Dec 2015 14:18:24 +0900 Subject: [PATCH 1778/2855] staging: wilc1000: fixes potential null dereference 'wid.val' This patch fixes the error reported by smatch. - Handle_ListenStateExpired() error: potential null dereference 'wid.val' If kmalloc failed, referenced to a NULL pointer. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index d1707f6f0dccd..2289ba3443007 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2635,8 +2635,10 @@ static u32 Handle_ListenStateExpired(struct host_if_drv *hif_drv, wid.size = 2; wid.val = kmalloc(wid.size, GFP_KERNEL); - if (!wid.val) + if (!wid.val) { PRINT_ER("Failed to allocate memory\n"); + return -ENOMEM; + } wid.val[0] = u8remain_on_chan_flag; wid.val[1] = FALSE_FRMWR_CHANNEL; -- GitLab From cb3b05c3845815e1fdeff94fcd5e8a57ceff702e Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Mon, 21 Dec 2015 14:18:25 +0900 Subject: [PATCH 1779/2855] staging: wilc1000: wilc_init(): fixes inconsistent returns This patch fixes the warning reported by smatch. - wilc_init() warn: inconsistent returns 'sem:&hif_drv->sem_cfg_values' No need to up the sema here since down was not called before get here. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 2289ba3443007..6dd3076a78e17 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3873,7 +3873,6 @@ s32 wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) return result; _fail_timer_2: - up(&hif_drv->sem_cfg_values); del_timer_sync(&hif_drv->connect_timer); del_timer_sync(&hif_drv->scan_timer); kthread_stop(hif_thread_handler); -- GitLab From 6d04d7a0d9b63dfb8942eb5e0855b9be40bc5893 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Mon, 21 Dec 2015 14:18:26 +0900 Subject: [PATCH 1780/2855] staging: wilc1000: wilc_deinit(): fixes inconsistent returns This patch fixes the warning reported by smatch. - wilc_deinit() warn: inconsistent returns 'sem:&hif_drv->sem_cfg_values' This semaphore protect a cfg_values variable but cfg_values variables was not used here. So, just remove this line. Signed-off-by: Leo Kim Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 6dd3076a78e17..c8b4d86dc7b77 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3940,8 +3940,6 @@ s32 wilc_deinit(struct host_if_drv *hif_drv) wilc_mq_destroy(&hif_msg_q); } - down(&hif_drv->sem_cfg_values); - ret = remove_handler_in_list(hif_drv); if (ret) result = -ENOENT; -- GitLab From 0f34e924f6cfb0730fc33d9b58a5d91c88239792 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:27 +0900 Subject: [PATCH 1781/2855] staging: wilc1000: linux_wlan_spi.c: return linux error value return linux error value instead of 0 or 1 and use -EINVAL. Related codes also changed together. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_spi.c | 14 +++----------- drivers/staging/wilc1000/wilc_spi.c | 18 +++++++++--------- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index 61114057b8f7f..c7d25425cc54c 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -104,13 +104,9 @@ int wilc_spi_write(struct wilc *wilc, u8 *b, u32 len) dev_err(&spi->dev, "FAILED due to NULL buffer or ZERO length check the following length: %d\n", len); - ret = -1; + ret = -EINVAL; } - /* change return value to match WILC interface */ - (ret < 0) ? (ret = 0) : (ret = 1); - - return ret; } @@ -148,10 +144,8 @@ int wilc_spi_read(struct wilc *wilc, u8 *rb, u32 rlen) dev_err(&spi->dev, "can't read data with the following length: %u\n", rlen); - ret = -1; + ret = -EINVAL; } - /* change return value to match WILC interface */ - (ret < 0) ? (ret = 0) : (ret = 1); return ret; } @@ -185,10 +179,8 @@ int wilc_spi_write_read(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen) dev_err(&spi->dev, "can't read data with the following length: %u\n", rlen); - ret = -1; + ret = -EINVAL; } - /* change return value to match WILC interface */ - (ret < 0) ? (ret = 0) : (ret = 1); return ret; } diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index faaeaf7cba865..bd61aac6d7af3 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -250,7 +250,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, } rix = len; - if (!wilc_spi_write_read(wilc, wb, rb, len2)) { + if (wilc_spi_write_read(wilc, wb, rb, len2)) { dev_err(&spi->dev, "Failed cmd write, bus error...\n"); result = N_FAIL; return result; @@ -366,7 +366,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, /** * Read bytes **/ - if (!wilc_spi_read(wilc, &b[ix], nbytes)) { + if (wilc_spi_read(wilc, &b[ix], nbytes)) { dev_err(&spi->dev, "Failed data block read, bus error...\n"); result = N_FAIL; goto _error_; @@ -376,7 +376,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, * Read Crc **/ if (!g_spi.crc_off) { - if (!wilc_spi_read(wilc, crc, 2)) { + if (wilc_spi_read(wilc, crc, 2)) { dev_err(&spi->dev, "Failed data block crc read, bus error...\n"); result = N_FAIL; goto _error_; @@ -407,7 +407,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, **/ retry = 10; do { - if (!wilc_spi_read(wilc, &rsp, 1)) { + if (wilc_spi_read(wilc, &rsp, 1)) { dev_err(&spi->dev, "Failed data response read, bus error...\n"); result = N_FAIL; break; @@ -423,7 +423,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, /** * Read bytes **/ - if (!wilc_spi_read(wilc, &b[ix], nbytes)) { + if (wilc_spi_read(wilc, &b[ix], nbytes)) { dev_err(&spi->dev, "Failed data block read, bus error...\n"); result = N_FAIL; break; @@ -433,7 +433,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, * Read Crc **/ if (!g_spi.crc_off) { - if (!wilc_spi_read(wilc, crc, 2)) { + if (wilc_spi_read(wilc, crc, 2)) { dev_err(&spi->dev, "Failed data block crc read, bus error...\n"); result = N_FAIL; break; @@ -484,7 +484,7 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz) order = 0x2; } cmd |= order; - if (!wilc_spi_write(wilc, &cmd, 1)) { + if (wilc_spi_write(wilc, &cmd, 1)) { dev_err(&spi->dev, "Failed data block cmd write, bus error...\n"); result = N_FAIL; @@ -494,7 +494,7 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz) /** * Write data **/ - if (!wilc_spi_write(wilc, &b[ix], nbytes)) { + if (wilc_spi_write(wilc, &b[ix], nbytes)) { dev_err(&spi->dev, "Failed data block write, bus error...\n"); result = N_FAIL; @@ -505,7 +505,7 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz) * Write Crc **/ if (!g_spi.crc_off) { - if (!wilc_spi_write(wilc, crc, 2)) { + if (wilc_spi_write(wilc, crc, 2)) { dev_err(&spi->dev,"Failed data block crc write, bus error...\n"); result = N_FAIL; break; -- GitLab From 51d002931b170ea6f056a4c12ae0a9f7233202e5 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:28 +0900 Subject: [PATCH 1782/2855] staging: wilc1000: linux_sdio_probe: use return value Return ret from wilc_netdev_init instead of -1 for proper error handling. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_sdio.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index e25811d2c5b59..4b9cb55620387 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -91,7 +91,7 @@ static int linux_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { struct wilc *wilc; - int gpio; + int gpio, ret; gpio = -1; if (IS_ENABLED(CONFIG_WILC1000_HW_OOB_INTR)) { @@ -101,10 +101,11 @@ static int linux_sdio_probe(struct sdio_func *func, } dev_dbg(&func->dev, "Initializing netdev\n"); - if (wilc_netdev_init(&wilc, &func->dev, HIF_SDIO, gpio, - &wilc_hif_sdio)) { + ret = wilc_netdev_init(&wilc, &func->dev, HIF_SDIO, gpio, + &wilc_hif_sdio); + if (ret) { dev_err(&func->dev, "Couldn't initialize netdev\n"); - return -1; + return ret; } sdio_set_drvdata(func, wilc); wilc->dev = &func->dev; -- GitLab From 35a4569e72eec439a2d7e6c860ed42c518aa8f76 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:29 +0900 Subject: [PATCH 1783/2855] staging: wilc1000: linux_wlan_sdio.c: move all the codes to wilc_sdio.c To Combine linux_wlan_sdio.c and wilc_sdio.c as one file, move all the codes in linux_wlan_sdio.c to wilc_sdio.c, and make functions static only. No Modification has not been made except static, just moved them. Function declaration in linux_wlan_sdio.h is needless, so just remove them. linux_wlan_sdio.[ch] will be deleted in the next patch. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_sdio.c | 160 -------------------- drivers/staging/wilc1000/linux_wlan_sdio.h | 7 - drivers/staging/wilc1000/wilc_sdio.c | 164 ++++++++++++++++++++- 3 files changed, 163 insertions(+), 168 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c index 4b9cb55620387..67d99e9d28394 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -8,163 +8,3 @@ #include #include "linux_wlan_sdio.h" - -#define SDIO_MODALIAS "wilc1000_sdio" - -#define SDIO_VENDOR_ID_WILC 0x0296 -#define SDIO_DEVICE_ID_WILC 0x5347 - -static const struct sdio_device_id wilc_sdio_ids[] = { - { SDIO_DEVICE(SDIO_VENDOR_ID_WILC, SDIO_DEVICE_ID_WILC) }, - { }, -}; - - -static void wilc_sdio_interrupt(struct sdio_func *func) -{ - sdio_release_host(func); - wilc_handle_isr(sdio_get_drvdata(func)); - sdio_claim_host(func); -} - -int wilc_sdio_cmd52(struct wilc *wilc, sdio_cmd52_t *cmd) -{ - struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev); - int ret; - u8 data; - - sdio_claim_host(func); - - func->num = cmd->function; - if (cmd->read_write) { /* write */ - if (cmd->raw) { - sdio_writeb(func, cmd->data, cmd->address, &ret); - data = sdio_readb(func, cmd->address, &ret); - cmd->data = data; - } else { - sdio_writeb(func, cmd->data, cmd->address, &ret); - } - } else { /* read */ - data = sdio_readb(func, cmd->address, &ret); - cmd->data = data; - } - - sdio_release_host(func); - - if (ret) - dev_err(&func->dev, "wilc_sdio_cmd52..failed, err(%d)\n", ret); - return ret; -} - - -int wilc_sdio_cmd53(struct wilc *wilc, sdio_cmd53_t *cmd) -{ - struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev); - int size, ret; - - sdio_claim_host(func); - - func->num = cmd->function; - func->cur_blksize = cmd->block_size; - if (cmd->block_mode) - size = cmd->count * cmd->block_size; - else - size = cmd->count; - - if (cmd->read_write) { /* write */ - ret = sdio_memcpy_toio(func, cmd->address, - (void *)cmd->buffer, size); - } else { /* read */ - ret = sdio_memcpy_fromio(func, (void *)cmd->buffer, - cmd->address, size); - } - - sdio_release_host(func); - - if (ret) - dev_err(&func->dev, "wilc_sdio_cmd53..failed, err(%d)\n", ret); - - return ret; -} - -static int linux_sdio_probe(struct sdio_func *func, - const struct sdio_device_id *id) -{ - struct wilc *wilc; - int gpio, ret; - - gpio = -1; - if (IS_ENABLED(CONFIG_WILC1000_HW_OOB_INTR)) { - gpio = of_get_gpio(func->dev.of_node, 0); - if (gpio < 0) - gpio = GPIO_NUM; - } - - dev_dbg(&func->dev, "Initializing netdev\n"); - ret = wilc_netdev_init(&wilc, &func->dev, HIF_SDIO, gpio, - &wilc_hif_sdio); - if (ret) { - dev_err(&func->dev, "Couldn't initialize netdev\n"); - return ret; - } - sdio_set_drvdata(func, wilc); - wilc->dev = &func->dev; - - dev_info(&func->dev, "Driver Initializing success\n"); - return 0; -} - -static void linux_sdio_remove(struct sdio_func *func) -{ - wilc_netdev_cleanup(sdio_get_drvdata(func)); -} - -static struct sdio_driver wilc1000_sdio_driver = { - .name = SDIO_MODALIAS, - .id_table = wilc_sdio_ids, - .probe = linux_sdio_probe, - .remove = linux_sdio_remove, -}; -module_driver(wilc1000_sdio_driver, - sdio_register_driver, - sdio_unregister_driver); -MODULE_LICENSE("GPL"); - -int wilc_sdio_enable_interrupt(struct wilc *dev) -{ - struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev); - int ret = 0; - - sdio_claim_host(func); - ret = sdio_claim_irq(func, wilc_sdio_interrupt); - sdio_release_host(func); - - if (ret < 0) { - dev_err(&func->dev, "can't claim sdio_irq, err(%d)\n", ret); - ret = -EIO; - } - return ret; -} - -void wilc_sdio_disable_interrupt(struct wilc *dev) -{ - struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev); - int ret; - - dev_dbg(&func->dev, "wilc_sdio_disable_interrupt IN\n"); - - sdio_claim_host(func); - ret = sdio_release_irq(func); - if (ret < 0) - dev_err(&func->dev, "can't release sdio_irq, err(%d)\n", ret); - sdio_release_host(func); - - dev_info(&func->dev, "wilc_sdio_disable_interrupt OUT\n"); -} - -int wilc_sdio_init(void) -{ - return 1; -} - -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.h b/drivers/staging/wilc1000/linux_wlan_sdio.h index 8d276c61cdcc8..abb23126ca83e 100644 --- a/drivers/staging/wilc1000/linux_wlan_sdio.h +++ b/drivers/staging/wilc1000/linux_wlan_sdio.h @@ -1,8 +1 @@ #include - -int wilc_sdio_init(void); -int wilc_sdio_cmd52(struct wilc *wilc, sdio_cmd52_t *cmd); -int wilc_sdio_cmd53(struct wilc *wilc, sdio_cmd53_t *cmd); - -int wilc_sdio_enable_interrupt(struct wilc *); -void wilc_sdio_disable_interrupt(struct wilc *); diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index fa1adcf3b683f..e961b50049028 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -10,8 +10,23 @@ #include #include "wilc_wlan_if.h" #include "wilc_wlan.h" -#include "linux_wlan_sdio.h" #include "wilc_wfi_netdevice.h" +#include +#include +#include +#include +#include +#include + +#define SDIO_MODALIAS "wilc1000_sdio" + +#define SDIO_VENDOR_ID_WILC 0x0296 +#define SDIO_DEVICE_ID_WILC 0x5347 + +static const struct sdio_device_id wilc_sdio_ids[] = { + { SDIO_DEVICE(SDIO_VENDOR_ID_WILC, SDIO_DEVICE_ID_WILC) }, + { }, +}; #define WILC_SDIO_BLOCK_SIZE 512 @@ -28,6 +43,153 @@ static wilc_sdio_t g_sdio; static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data); static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data); +static void wilc_sdio_interrupt(struct sdio_func *func) +{ + sdio_release_host(func); + wilc_handle_isr(sdio_get_drvdata(func)); + sdio_claim_host(func); +} + +static int wilc_sdio_cmd52(struct wilc *wilc, sdio_cmd52_t *cmd) +{ + struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev); + int ret; + u8 data; + + sdio_claim_host(func); + + func->num = cmd->function; + if (cmd->read_write) { /* write */ + if (cmd->raw) { + sdio_writeb(func, cmd->data, cmd->address, &ret); + data = sdio_readb(func, cmd->address, &ret); + cmd->data = data; + } else { + sdio_writeb(func, cmd->data, cmd->address, &ret); + } + } else { /* read */ + data = sdio_readb(func, cmd->address, &ret); + cmd->data = data; + } + + sdio_release_host(func); + + if (ret) + dev_err(&func->dev, "wilc_sdio_cmd52..failed, err(%d)\n", ret); + return ret; +} + + +static int wilc_sdio_cmd53(struct wilc *wilc, sdio_cmd53_t *cmd) +{ + struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev); + int size, ret; + + sdio_claim_host(func); + + func->num = cmd->function; + func->cur_blksize = cmd->block_size; + if (cmd->block_mode) + size = cmd->count * cmd->block_size; + else + size = cmd->count; + + if (cmd->read_write) { /* write */ + ret = sdio_memcpy_toio(func, cmd->address, + (void *)cmd->buffer, size); + } else { /* read */ + ret = sdio_memcpy_fromio(func, (void *)cmd->buffer, + cmd->address, size); + } + + sdio_release_host(func); + + if (ret) + dev_err(&func->dev, "wilc_sdio_cmd53..failed, err(%d)\n", ret); + + return ret; +} + +static int linux_sdio_probe(struct sdio_func *func, + const struct sdio_device_id *id) +{ + struct wilc *wilc; + int gpio, ret; + + gpio = -1; + if (IS_ENABLED(CONFIG_WILC1000_HW_OOB_INTR)) { + gpio = of_get_gpio(func->dev.of_node, 0); + if (gpio < 0) + gpio = GPIO_NUM; + } + + dev_dbg(&func->dev, "Initializing netdev\n"); + ret = wilc_netdev_init(&wilc, &func->dev, HIF_SDIO, gpio, + &wilc_hif_sdio); + if (ret) { + dev_err(&func->dev, "Couldn't initialize netdev\n"); + return ret; + } + sdio_set_drvdata(func, wilc); + wilc->dev = &func->dev; + + dev_info(&func->dev, "Driver Initializing success\n"); + return 0; +} + +static void linux_sdio_remove(struct sdio_func *func) +{ + wilc_netdev_cleanup(sdio_get_drvdata(func)); +} + +static struct sdio_driver wilc1000_sdio_driver = { + .name = SDIO_MODALIAS, + .id_table = wilc_sdio_ids, + .probe = linux_sdio_probe, + .remove = linux_sdio_remove, +}; +module_driver(wilc1000_sdio_driver, + sdio_register_driver, + sdio_unregister_driver); +MODULE_LICENSE("GPL"); + +static int wilc_sdio_enable_interrupt(struct wilc *dev) +{ + struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev); + int ret = 0; + + sdio_claim_host(func); + ret = sdio_claim_irq(func, wilc_sdio_interrupt); + sdio_release_host(func); + + if (ret < 0) { + dev_err(&func->dev, "can't claim sdio_irq, err(%d)\n", ret); + ret = -EIO; + } + return ret; +} + +static void wilc_sdio_disable_interrupt(struct wilc *dev) +{ + struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev); + int ret; + + dev_dbg(&func->dev, "wilc_sdio_disable_interrupt IN\n"); + + sdio_claim_host(func); + ret = sdio_release_irq(func); + if (ret < 0) + dev_err(&func->dev, "can't release sdio_irq, err(%d)\n", ret); + sdio_release_host(func); + + dev_info(&func->dev, "wilc_sdio_disable_interrupt OUT\n"); +} + +static int wilc_sdio_init(void) +{ + return 1; +} + /******************************************** * * Function 0 -- GitLab From 895e5eafadb339030a7a039cb29e4f116a87cc22 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:30 +0900 Subject: [PATCH 1784/2855] staging: wilc1000: remove unused files This patch removes linux_wlan_sdio.[ch] which is not used anymore. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/Makefile | 2 +- drivers/staging/wilc1000/linux_wlan_sdio.c | 10 ---------- drivers/staging/wilc1000/linux_wlan_sdio.h | 1 - 3 files changed, 1 insertion(+), 12 deletions(-) delete mode 100644 drivers/staging/wilc1000/linux_wlan_sdio.c delete mode 100644 drivers/staging/wilc1000/linux_wlan_sdio.h diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile index 207674376553e..09f0ddbb6774a 100644 --- a/drivers/staging/wilc1000/Makefile +++ b/drivers/staging/wilc1000/Makefile @@ -14,7 +14,7 @@ wilc1000-objs := wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \ wilc_wlan.o obj-$(CONFIG_WILC1000_SDIO) += wilc1000-sdio.o -wilc1000-sdio-objs += linux_wlan_sdio.o wilc_sdio.o +wilc1000-sdio-objs += wilc_sdio.o obj-$(CONFIG_WILC1000_SPI) += wilc1000-spi.o wilc1000-spi-objs += linux_wlan_spi.o wilc_spi.o diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c deleted file mode 100644 index 67d99e9d28394..0000000000000 --- a/drivers/staging/wilc1000/linux_wlan_sdio.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "wilc_wfi_netdevice.h" - -#include -#include -#include -#include -#include -#include - -#include "linux_wlan_sdio.h" diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.h b/drivers/staging/wilc1000/linux_wlan_sdio.h deleted file mode 100644 index abb23126ca83e..0000000000000 --- a/drivers/staging/wilc1000/linux_wlan_sdio.h +++ /dev/null @@ -1 +0,0 @@ -#include -- GitLab From d4312b6fc8522d21832dbd1fa3f1dfb843e5b568 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:31 +0900 Subject: [PATCH 1785/2855] staging: wilc1000: rename spi function names There are several similar function names, such as wilc_spi_write and _wilc_spi_write. It is likely to be confused after merging linux_wlan_spi.c and wilc_spi.c, so rename following functions properly. Rename wilc_spi_write to wilc_spi_tx, wilc_spi_read to wilc_spi_rx, wilc_spi_write_read to wilc_spi_tx_rx, _wilc_spi_write to wilc_spi_write, _wilc_spi_read to wilc_spi_read. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_spi.c | 6 ++-- drivers/staging/wilc1000/linux_wlan_spi.h | 6 ++-- drivers/staging/wilc1000/wilc_spi.c | 34 +++++++++++------------ 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index c7d25425cc54c..e9ad33f62021b 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -66,7 +66,7 @@ int wilc_spi_init(void) return 1; } -int wilc_spi_write(struct wilc *wilc, u8 *b, u32 len) +int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len) { struct spi_device *spi = to_spi_device(wilc->dev); int ret; @@ -110,7 +110,7 @@ int wilc_spi_write(struct wilc *wilc, u8 *b, u32 len) return ret; } -int wilc_spi_read(struct wilc *wilc, u8 *rb, u32 rlen) +int wilc_spi_rx(struct wilc *wilc, u8 *rb, u32 rlen) { struct spi_device *spi = to_spi_device(wilc->dev); int ret; @@ -150,7 +150,7 @@ int wilc_spi_read(struct wilc *wilc, u8 *rb, u32 rlen) return ret; } -int wilc_spi_write_read(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen) +int wilc_spi_tx_rx(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen) { struct spi_device *spi = to_spi_device(wilc->dev); int ret; diff --git a/drivers/staging/wilc1000/linux_wlan_spi.h b/drivers/staging/wilc1000/linux_wlan_spi.h index 00733aba91790..5ff070b9ace52 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.h +++ b/drivers/staging/wilc1000/linux_wlan_spi.h @@ -5,7 +5,7 @@ #include "wilc_wfi_netdevice.h" int wilc_spi_init(void); -int wilc_spi_write(struct wilc *wilc, u8 *b, u32 len); -int wilc_spi_read(struct wilc *wilc, u8 *rb, u32 rlen); -int wilc_spi_write_read(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen); +int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len); +int wilc_spi_rx(struct wilc *wilc, u8 *rb, u32 rlen); +int wilc_spi_tx_rx(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen); #endif diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index bd61aac6d7af3..ce12d29bf41a5 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -21,8 +21,8 @@ typedef struct { static wilc_spi_t g_spi; -static int _wilc_spi_read(struct wilc *wilc, u32, u8 *, u32); -static int _wilc_spi_write(struct wilc *wilc, u32, u8 *, u32); +static int wilc_spi_read(struct wilc *wilc, u32, u8 *, u32); +static int wilc_spi_write(struct wilc *wilc, u32, u8 *, u32); /******************************************** * @@ -250,7 +250,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, } rix = len; - if (wilc_spi_write_read(wilc, wb, rb, len2)) { + if (wilc_spi_tx_rx(wilc, wb, rb, len2)) { dev_err(&spi->dev, "Failed cmd write, bus error...\n"); result = N_FAIL; return result; @@ -366,7 +366,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, /** * Read bytes **/ - if (wilc_spi_read(wilc, &b[ix], nbytes)) { + if (wilc_spi_rx(wilc, &b[ix], nbytes)) { dev_err(&spi->dev, "Failed data block read, bus error...\n"); result = N_FAIL; goto _error_; @@ -376,7 +376,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, * Read Crc **/ if (!g_spi.crc_off) { - if (wilc_spi_read(wilc, crc, 2)) { + if (wilc_spi_rx(wilc, crc, 2)) { dev_err(&spi->dev, "Failed data block crc read, bus error...\n"); result = N_FAIL; goto _error_; @@ -407,7 +407,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, **/ retry = 10; do { - if (wilc_spi_read(wilc, &rsp, 1)) { + if (wilc_spi_rx(wilc, &rsp, 1)) { dev_err(&spi->dev, "Failed data response read, bus error...\n"); result = N_FAIL; break; @@ -423,7 +423,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, /** * Read bytes **/ - if (wilc_spi_read(wilc, &b[ix], nbytes)) { + if (wilc_spi_rx(wilc, &b[ix], nbytes)) { dev_err(&spi->dev, "Failed data block read, bus error...\n"); result = N_FAIL; break; @@ -433,7 +433,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, * Read Crc **/ if (!g_spi.crc_off) { - if (wilc_spi_read(wilc, crc, 2)) { + if (wilc_spi_rx(wilc, crc, 2)) { dev_err(&spi->dev, "Failed data block crc read, bus error...\n"); result = N_FAIL; break; @@ -484,7 +484,7 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz) order = 0x2; } cmd |= order; - if (wilc_spi_write(wilc, &cmd, 1)) { + if (wilc_spi_tx(wilc, &cmd, 1)) { dev_err(&spi->dev, "Failed data block cmd write, bus error...\n"); result = N_FAIL; @@ -494,7 +494,7 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz) /** * Write data **/ - if (wilc_spi_write(wilc, &b[ix], nbytes)) { + if (wilc_spi_tx(wilc, &b[ix], nbytes)) { dev_err(&spi->dev, "Failed data block write, bus error...\n"); result = N_FAIL; @@ -505,7 +505,7 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz) * Write Crc **/ if (!g_spi.crc_off) { - if (wilc_spi_write(wilc, crc, 2)) { + if (wilc_spi_tx(wilc, crc, 2)) { dev_err(&spi->dev,"Failed data block crc write, bus error...\n"); result = N_FAIL; break; @@ -589,7 +589,7 @@ static int wilc_spi_write_reg(struct wilc *wilc, u32 addr, u32 data) return result; } -static int _wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) +static int wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { struct spi_device *spi = to_spi_device(wilc->dev); int result; @@ -644,7 +644,7 @@ static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data) return 1; } -static int _wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) +static int wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { struct spi_device *spi = to_spi_device(wilc->dev); u8 cmd = CMD_DMA_EXT_READ; @@ -998,12 +998,12 @@ const struct wilc_hif_func wilc_hif_spi = { .hif_deinit = _wilc_spi_deinit, .hif_read_reg = wilc_spi_read_reg, .hif_write_reg = wilc_spi_write_reg, - .hif_block_rx = _wilc_spi_read, - .hif_block_tx = _wilc_spi_write, + .hif_block_rx = wilc_spi_read, + .hif_block_tx = wilc_spi_write, .hif_read_int = wilc_spi_read_int, .hif_clear_int_ext = wilc_spi_clear_int_ext, .hif_read_size = wilc_spi_read_size, - .hif_block_tx_ext = _wilc_spi_write, - .hif_block_rx_ext = _wilc_spi_read, + .hif_block_tx_ext = wilc_spi_write, + .hif_block_rx_ext = wilc_spi_read, .hif_sync_ext = wilc_spi_sync_ext, }; -- GitLab From 2769d9422e631559bc672dda9cdb7a5916db4527 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:32 +0900 Subject: [PATCH 1786/2855] staging: wilc1000: remove unneeded function wilc_spi_init in linux_wlan_spi.c is unneeded. It just return true. Rename _wilc_spi_init in wlan_spi.c to wilc_spi_init. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_spi.c | 5 ----- drivers/staging/wilc1000/linux_wlan_spi.h | 1 - drivers/staging/wilc1000/wilc_spi.c | 11 ++--------- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index e9ad33f62021b..06935cfb3eff9 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -61,11 +61,6 @@ struct spi_driver wilc1000_spi_driver = { module_spi_driver(wilc1000_spi_driver); MODULE_LICENSE("GPL"); -int wilc_spi_init(void) -{ - return 1; -} - int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len) { struct spi_device *spi = to_spi_device(wilc->dev); diff --git a/drivers/staging/wilc1000/linux_wlan_spi.h b/drivers/staging/wilc1000/linux_wlan_spi.h index 5ff070b9ace52..d41c16a136b48 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.h +++ b/drivers/staging/wilc1000/linux_wlan_spi.h @@ -4,7 +4,6 @@ #include #include "wilc_wfi_netdevice.h" -int wilc_spi_init(void); int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len); int wilc_spi_rx(struct wilc *wilc, u8 *rb, u32 rlen); int wilc_spi_tx_rx(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen); diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index ce12d29bf41a5..0f730cd7fcf3e 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -676,7 +676,7 @@ static int _wilc_spi_deinit(struct wilc *wilc) return 1; } -static int _wilc_spi_init(struct wilc *wilc) +static int wilc_spi_init(struct wilc *wilc) { struct spi_device *spi = to_spi_device(wilc->dev); u32 reg; @@ -695,13 +695,6 @@ static int _wilc_spi_init(struct wilc *wilc) memset(&g_spi, 0, sizeof(wilc_spi_t)); - if (!wilc_spi_init()) { - dev_err(&spi->dev, "Failed io init bus...\n"); - return 0; - } else { - return 0; - } - /** * configure protocol **/ @@ -994,7 +987,7 @@ static int wilc_spi_sync_ext(struct wilc *wilc, int nint) * ********************************************/ const struct wilc_hif_func wilc_hif_spi = { - .hif_init = _wilc_spi_init, + .hif_init = wilc_spi_init, .hif_deinit = _wilc_spi_deinit, .hif_read_reg = wilc_spi_read_reg, .hif_write_reg = wilc_spi_write_reg, -- GitLab From 43a7622935c72a6724d62d7fb5da35fbe7328f0e Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:33 +0900 Subject: [PATCH 1787/2855] staging: wilc1000: linux_wlan_spi.c: move all the codes to wilc_spi.c This patch moves all the codes in linux_wlan_spi.c to wilc_spi.c to make one spi module. Make wilc_spi_tx, wilc_spi_rx and wilc_spi_tx_rx static functions. Remove function declaration in linux_wlan_spi.h, which is unnedded now. No modification has been made inside the codes. linux_wlan_spi.[ch] will be remove in the next patch. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan_spi.c | 165 -------------------- drivers/staging/wilc1000/linux_wlan_spi.h | 4 - drivers/staging/wilc1000/wilc_spi.c | 180 +++++++++++++++++++++- 3 files changed, 178 insertions(+), 171 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c index 06935cfb3eff9..c4315f5585974 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -14,168 +14,3 @@ #include "wilc_wfi_netdevice.h" #include "linux_wlan_common.h" #include "wilc_wlan_if.h" - -#define USE_SPI_DMA 0 - -static const struct wilc1000_ops wilc1000_spi_ops; - -static int wilc_bus_probe(struct spi_device *spi) -{ - int ret, gpio; - struct wilc *wilc; - - gpio = of_get_gpio(spi->dev.of_node, 0); - if (gpio < 0) - gpio = GPIO_NUM; - - ret = wilc_netdev_init(&wilc, NULL, HIF_SPI, GPIO_NUM, &wilc_hif_spi); - if (ret) - return ret; - - spi_set_drvdata(spi, wilc); - wilc->dev = &spi->dev; - - return 0; -} - -static int wilc_bus_remove(struct spi_device *spi) -{ - wilc_netdev_cleanup(spi_get_drvdata(spi)); - return 0; -} - -static const struct of_device_id wilc1000_of_match[] = { - { .compatible = "atmel,wilc_spi", }, - {} -}; -MODULE_DEVICE_TABLE(of, wilc1000_of_match); - -struct spi_driver wilc1000_spi_driver = { - .driver = { - .name = MODALIAS, - .of_match_table = wilc1000_of_match, - }, - .probe = wilc_bus_probe, - .remove = wilc_bus_remove, -}; -module_spi_driver(wilc1000_spi_driver); -MODULE_LICENSE("GPL"); - -int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len) -{ - struct spi_device *spi = to_spi_device(wilc->dev); - int ret; - struct spi_message msg; - - if (len > 0 && b) { - struct spi_transfer tr = { - .tx_buf = b, - .len = len, - .delay_usecs = 0, - }; - char *r_buffer = kzalloc(len, GFP_KERNEL); - - if (!r_buffer) - return -ENOMEM; - - tr.rx_buf = r_buffer; - dev_dbg(&spi->dev, "Request writing %d bytes\n", len); - - memset(&msg, 0, sizeof(msg)); - spi_message_init(&msg); - msg.spi = spi; - msg.is_dma_mapped = USE_SPI_DMA; - spi_message_add_tail(&tr, &msg); - - ret = spi_sync(spi, &msg); - if (ret < 0) - dev_err(&spi->dev, "SPI transaction failed\n"); - - kfree(r_buffer); - } else { - dev_err(&spi->dev, - "can't write data with the following length: %d\n", - len); - dev_err(&spi->dev, - "FAILED due to NULL buffer or ZERO length check the following length: %d\n", - len); - ret = -EINVAL; - } - - return ret; -} - -int wilc_spi_rx(struct wilc *wilc, u8 *rb, u32 rlen) -{ - struct spi_device *spi = to_spi_device(wilc->dev); - int ret; - - if (rlen > 0) { - struct spi_message msg; - struct spi_transfer tr = { - .rx_buf = rb, - .len = rlen, - .delay_usecs = 0, - - }; - char *t_buffer = kzalloc(rlen, GFP_KERNEL); - - if (!t_buffer) - return -ENOMEM; - - tr.tx_buf = t_buffer; - - memset(&msg, 0, sizeof(msg)); - spi_message_init(&msg); - msg.spi = spi; - msg.is_dma_mapped = USE_SPI_DMA; - spi_message_add_tail(&tr, &msg); - - ret = spi_sync(spi, &msg); - if (ret < 0) - dev_err(&spi->dev, "SPI transaction failed\n"); - kfree(t_buffer); - } else { - dev_err(&spi->dev, - "can't read data with the following length: %u\n", - rlen); - ret = -EINVAL; - } - - return ret; -} - -int wilc_spi_tx_rx(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen) -{ - struct spi_device *spi = to_spi_device(wilc->dev); - int ret; - - if (rlen > 0) { - struct spi_message msg; - struct spi_transfer tr = { - .rx_buf = rb, - .tx_buf = wb, - .len = rlen, - .bits_per_word = 8, - .delay_usecs = 0, - - }; - - memset(&msg, 0, sizeof(msg)); - spi_message_init(&msg); - msg.spi = spi; - msg.is_dma_mapped = USE_SPI_DMA; - - spi_message_add_tail(&tr, &msg); - ret = spi_sync(spi, &msg); - if (ret < 0) - dev_err(&spi->dev, "SPI transaction failed\n"); - } else { - dev_err(&spi->dev, - "can't read data with the following length: %u\n", - rlen); - ret = -EINVAL; - } - - return ret; -} diff --git a/drivers/staging/wilc1000/linux_wlan_spi.h b/drivers/staging/wilc1000/linux_wlan_spi.h index d41c16a136b48..32e39267c4c3a 100644 --- a/drivers/staging/wilc1000/linux_wlan_spi.h +++ b/drivers/staging/wilc1000/linux_wlan_spi.h @@ -3,8 +3,4 @@ #include #include "wilc_wfi_netdevice.h" - -int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len); -int wilc_spi_rx(struct wilc *wilc, u8 *rb, u32 rlen); -int wilc_spi_tx_rx(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen); #endif diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 0f730cd7fcf3e..86de50c9f7f5f 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -6,11 +6,22 @@ /* */ /* */ /* //////////////////////////////////////////////////////////////////////////// */ - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "linux_wlan_common.h" #include #include "wilc_wlan_if.h" #include "wilc_wlan.h" -#include "linux_wlan_spi.h" #include "wilc_wfi_netdevice.h" typedef struct { @@ -107,6 +118,171 @@ static u8 crc7(u8 crc, const u8 *buffer, u32 len) #define DATA_PKT_SZ_8K (8 * 1024) #define DATA_PKT_SZ DATA_PKT_SZ_8K +#define USE_SPI_DMA 0 + +static const struct wilc1000_ops wilc1000_spi_ops; + +static int wilc_bus_probe(struct spi_device *spi) +{ + int ret, gpio; + struct wilc *wilc; + + gpio = of_get_gpio(spi->dev.of_node, 0); + if (gpio < 0) + gpio = GPIO_NUM; + + ret = wilc_netdev_init(&wilc, NULL, HIF_SPI, GPIO_NUM, &wilc_hif_spi); + if (ret) + return ret; + + spi_set_drvdata(spi, wilc); + wilc->dev = &spi->dev; + + return 0; +} + +static int wilc_bus_remove(struct spi_device *spi) +{ + wilc_netdev_cleanup(spi_get_drvdata(spi)); + return 0; +} + +static const struct of_device_id wilc1000_of_match[] = { + { .compatible = "atmel,wilc_spi", }, + {} +}; +MODULE_DEVICE_TABLE(of, wilc1000_of_match); + +struct spi_driver wilc1000_spi_driver = { + .driver = { + .name = MODALIAS, + .of_match_table = wilc1000_of_match, + }, + .probe = wilc_bus_probe, + .remove = wilc_bus_remove, +}; +module_spi_driver(wilc1000_spi_driver); +MODULE_LICENSE("GPL"); + +static int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len) +{ + struct spi_device *spi = to_spi_device(wilc->dev); + int ret; + struct spi_message msg; + + if (len > 0 && b) { + struct spi_transfer tr = { + .tx_buf = b, + .len = len, + .delay_usecs = 0, + }; + char *r_buffer = kzalloc(len, GFP_KERNEL); + + if (!r_buffer) + return -ENOMEM; + + tr.rx_buf = r_buffer; + dev_dbg(&spi->dev, "Request writing %d bytes\n", len); + + memset(&msg, 0, sizeof(msg)); + spi_message_init(&msg); + msg.spi = spi; + msg.is_dma_mapped = USE_SPI_DMA; + spi_message_add_tail(&tr, &msg); + + ret = spi_sync(spi, &msg); + if (ret < 0) + dev_err(&spi->dev, "SPI transaction failed\n"); + + kfree(r_buffer); + } else { + dev_err(&spi->dev, + "can't write data with the following length: %d\n", + len); + dev_err(&spi->dev, + "FAILED due to NULL buffer or ZERO length check the following length: %d\n", + len); + ret = -EINVAL; + } + + return ret; +} + +static int wilc_spi_rx(struct wilc *wilc, u8 *rb, u32 rlen) +{ + struct spi_device *spi = to_spi_device(wilc->dev); + int ret; + + if (rlen > 0) { + struct spi_message msg; + struct spi_transfer tr = { + .rx_buf = rb, + .len = rlen, + .delay_usecs = 0, + + }; + char *t_buffer = kzalloc(rlen, GFP_KERNEL); + + if (!t_buffer) + return -ENOMEM; + + tr.tx_buf = t_buffer; + + memset(&msg, 0, sizeof(msg)); + spi_message_init(&msg); + msg.spi = spi; + msg.is_dma_mapped = USE_SPI_DMA; + spi_message_add_tail(&tr, &msg); + + ret = spi_sync(spi, &msg); + if (ret < 0) + dev_err(&spi->dev, "SPI transaction failed\n"); + kfree(t_buffer); + } else { + dev_err(&spi->dev, + "can't read data with the following length: %u\n", + rlen); + ret = -EINVAL; + } + + return ret; +} + +static int wilc_spi_tx_rx(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen) +{ + struct spi_device *spi = to_spi_device(wilc->dev); + int ret; + + if (rlen > 0) { + struct spi_message msg; + struct spi_transfer tr = { + .rx_buf = rb, + .tx_buf = wb, + .len = rlen, + .bits_per_word = 8, + .delay_usecs = 0, + + }; + + memset(&msg, 0, sizeof(msg)); + spi_message_init(&msg); + msg.spi = spi; + msg.is_dma_mapped = USE_SPI_DMA; + + spi_message_add_tail(&tr, &msg); + ret = spi_sync(spi, &msg); + if (ret < 0) + dev_err(&spi->dev, "SPI transaction failed\n"); + } else { + dev_err(&spi->dev, + "can't read data with the following length: %u\n", + rlen); + ret = -EINVAL; + } + + return ret; +} + static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless) { -- GitLab From 523fc23f1179606492aa8f0252ef7f631f27346f Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:34 +0900 Subject: [PATCH 1788/2855] staging: wilc1000: remove unused files This patch removes linux_wlan_spi.[ch] which are not used anymore. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/Makefile | 2 +- drivers/staging/wilc1000/linux_wlan_spi.c | 16 ---------------- drivers/staging/wilc1000/linux_wlan_spi.h | 6 ------ 3 files changed, 1 insertion(+), 23 deletions(-) delete mode 100644 drivers/staging/wilc1000/linux_wlan_spi.c delete mode 100644 drivers/staging/wilc1000/linux_wlan_spi.h diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile index 09f0ddbb6774a..20a5cb9d4f4c8 100644 --- a/drivers/staging/wilc1000/Makefile +++ b/drivers/staging/wilc1000/Makefile @@ -17,4 +17,4 @@ obj-$(CONFIG_WILC1000_SDIO) += wilc1000-sdio.o wilc1000-sdio-objs += wilc_sdio.o obj-$(CONFIG_WILC1000_SPI) += wilc1000-spi.o -wilc1000-spi-objs += linux_wlan_spi.o wilc_spi.o +wilc1000-spi-objs += wilc_spi.o diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c deleted file mode 100644 index c4315f5585974..0000000000000 --- a/drivers/staging/wilc1000/linux_wlan_spi.c +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "linux_wlan_spi.h" -#include "wilc_wfi_netdevice.h" -#include "linux_wlan_common.h" -#include "wilc_wlan_if.h" diff --git a/drivers/staging/wilc1000/linux_wlan_spi.h b/drivers/staging/wilc1000/linux_wlan_spi.h deleted file mode 100644 index 32e39267c4c3a..0000000000000 --- a/drivers/staging/wilc1000/linux_wlan_spi.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef LINUX_WLAN_SPI_H -#define LINUX_WLAN_SPI_H - -#include -#include "wilc_wfi_netdevice.h" -#endif -- GitLab From 320edd03fb7549f3908b37b1c91dae32f5132305 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:35 +0900 Subject: [PATCH 1789/2855] staging: wilc1000: remove unneeded extern variable This patch removes unnedded extern variable WILC_WFI_devs[] which is not used. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 68a159f36f148..b9961f079e274 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -227,7 +227,6 @@ struct WILC_WFI_mon_priv { int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic); -extern struct net_device *WILC_WFI_devs[]; void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset); void wilc_mac_indicate(struct wilc *wilc, int flag); void wilc_rx_complete(struct wilc *wilc); -- GitLab From a4cac4810104b010572ebcb7de419effef3ff33b Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:36 +0900 Subject: [PATCH 1790/2855] staging: wilc1000: move perInterface_wlan_t to wilc_vif perInterface_wlan_t and wilc_vif are all about interface control informations. We will combine those two structures and maintain as one network interface control information. Move all the members of perInterface_wlan_t to wilc_vif and remove the structure. Rename perInterace_wlan_t to wilc_vif and rename variable name nic to vif which is proper name for it. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 +- drivers/staging/wilc1000/linux_wlan.c | 251 +++++++++--------- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 148 +++++------ drivers/staging/wilc1000/wilc_wfi_netdevice.h | 21 +- drivers/staging/wilc1000/wilc_wlan.c | 60 ++--- 5 files changed, 241 insertions(+), 245 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index c8b4d86dc7b77..23bd8d306c8b3 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3779,11 +3779,11 @@ s32 wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) s32 result = 0; struct host_if_drv *hif_drv; int err; - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; - nic = netdev_priv(dev); - wilc = nic->wilc; + vif = netdev_priv(dev); + wilc = vif->wilc; PRINT_D(HOSTINF_DBG, "Initializing host interface for client %d\n", clients_count + 1); diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 92ca0723c8b6b..263d9d84c8cf5 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -64,7 +64,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event struct host_if_drv *hif_drv; struct net_device *dev; u8 *ip_addr_buf; - perInterface_wlan_t *nic; + struct wilc_vif *vif; u8 null_ip[4] = {0}; char wlan_dev_name[5] = "wlan0"; @@ -90,8 +90,8 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event return NOTIFY_DONE; } hif_drv = (struct host_if_drv *)priv->hWILCWFIDrv; - nic = netdev_priv(dev); - if (!nic || !hif_drv) { + vif = netdev_priv(dev); + if (!vif || !hif_drv) { PRINT_D(GENERIC_DBG, "No Wireless Priv\n"); return NOTIFY_DONE; } @@ -104,7 +104,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Obtained ===============\n\n"); - if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) { + if (vif->iftype == STATION_MODE || vif->iftype == CLIENT_MODE) { hif_drv->IFC_UP = 1; wilc_optaining_ip = false; del_timer(&wilc_during_ip_timer); @@ -120,7 +120,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n", ip_addr_buf[0], ip_addr_buf[1], ip_addr_buf[2], ip_addr_buf[3]); - wilc_setup_ipaddress(hif_drv, ip_addr_buf, nic->u8IfIdx); + wilc_setup_ipaddress(hif_drv, ip_addr_buf, vif->u8IfIdx); break; @@ -128,7 +128,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_DOWN %p\n", dev); PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Released ===============\n\n"); - if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) { + if (vif->iftype == STATION_MODE || vif->iftype == CLIENT_MODE) { hif_drv->IFC_UP = 0; wilc_optaining_ip = false; } @@ -145,7 +145,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event ip_addr_buf[0], ip_addr_buf[1], ip_addr_buf[2], ip_addr_buf[3]); - wilc_setup_ipaddress(hif_drv, ip_addr_buf, nic->u8IfIdx); + wilc_setup_ipaddress(hif_drv, ip_addr_buf, vif->u8IfIdx); break; @@ -161,12 +161,12 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event static irqreturn_t isr_uh_routine(int irq, void *user_data) { - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; struct net_device *dev = (struct net_device *)user_data; - nic = netdev_priv(dev); - wilc = nic->wilc; + vif = netdev_priv(dev); + wilc = vif->wilc; PRINT_D(INT_DBG, "Interrupt received UH\n"); if (wilc->close) { @@ -178,11 +178,11 @@ static irqreturn_t isr_uh_routine(int irq, void *user_data) static irqreturn_t isr_bh_routine(int irq, void *userdata) { - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; - nic = netdev_priv(userdata); - wilc = nic->wilc; + vif = netdev_priv(userdata); + wilc = vif->wilc; if (wilc->close) { PRINT_ER("Driver is CLOSING: Can't handle BH interrupt\n"); @@ -198,11 +198,11 @@ static irqreturn_t isr_bh_routine(int irq, void *userdata) static int init_irq(struct net_device *dev) { int ret = 0; - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wl; - nic = netdev_priv(dev); - wl = nic->wilc; + vif = netdev_priv(dev); + wl = vif->wilc; if ((gpio_request(wl->gpio, "WILC_INTR") == 0) && (gpio_direction_input(wl->gpio) == 0)) { @@ -230,11 +230,11 @@ static int init_irq(struct net_device *dev) static void deinit_irq(struct net_device *dev) { - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; - nic = netdev_priv(dev); - wilc = nic->wilc; + vif = netdev_priv(dev); + wilc = vif->wilc; /* Deintialize IRQ */ if (wilc->dev_irq_num) { @@ -311,11 +311,11 @@ int wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid) { int i = 0; int ret = -1; - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; - nic = netdev_priv(wilc_netdev); - wilc = nic->wilc; + vif = netdev_priv(wilc_netdev); + wilc = vif->wilc; for (i = 0; i < wilc->vif_num; i++) if (wilc->vif[i].ndev == wilc_netdev) { @@ -345,7 +345,7 @@ int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc) static int linux_wlan_txq_task(void *vp) { int ret, txq_count; - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wl; struct net_device *dev = vp; #if defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS @@ -357,8 +357,8 @@ static int linux_wlan_txq_task(void *vp) int backoff_weight = TX_BACKOFF_WEIGHT_MIN; #endif - nic = netdev_priv(dev); - wl = nic->wilc; + vif = netdev_priv(dev); + wl = vif->wilc; up(&wl->txq_thread_started); while (1) { @@ -417,31 +417,31 @@ void wilc_rx_complete(struct wilc *nic) int wilc_wlan_get_firmware(struct net_device *dev) { - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; int ret = 0; const struct firmware *wilc_firmware; char *firmware; - nic = netdev_priv(dev); - wilc = nic->wilc; + vif = netdev_priv(dev); + wilc = vif->wilc; - if (nic->iftype == AP_MODE) { + if (vif->iftype == AP_MODE) { firmware = AP_FIRMWARE; - } else if (nic->iftype == STATION_MODE) { + } else if (vif->iftype == STATION_MODE) { firmware = STA_FIRMWARE; } else { PRINT_D(INIT_DBG, "Get P2P_CONCURRENCY_FIRMWARE\n"); firmware = P2P_CONCURRENCY_FIRMWARE; } - if (!nic) { - PRINT_ER("NIC is NULL\n"); + if (!vif) { + PRINT_ER("vif is NULL\n"); goto _fail_; } - if (!(&nic->wilc_netdev->dev)) { - PRINT_ER("&nic->wilc_netdev->dev is NULL\n"); + if (!(&vif->wilc_netdev->dev)) { + PRINT_ER("&vif->wilc_netdev->dev is NULL\n"); goto _fail_; } @@ -459,12 +459,12 @@ _fail_: static int linux_wlan_start_firmware(struct net_device *dev) { - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; int ret = 0; - nic = netdev_priv(dev); - wilc = nic->wilc; + vif = netdev_priv(dev); + wilc = vif->wilc; PRINT_D(INIT_DBG, "Starting Firmware ...\n"); ret = wilc_wlan_start(wilc); @@ -486,12 +486,12 @@ static int linux_wlan_start_firmware(struct net_device *dev) static int wilc1000_firmware_download(struct net_device *dev) { - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; int ret = 0; - nic = netdev_priv(dev); - wilc = nic->wilc; + vif = netdev_priv(dev); + wilc = vif->wilc; if (!wilc->firmware) { PRINT_ER("Firmware buffer is NULL\n"); @@ -734,11 +734,11 @@ _fail_: void wilc1000_wlan_deinit(struct net_device *dev) { - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wl; - nic = netdev_priv(dev); - wl = nic->wilc; + vif = netdev_priv(dev); + wl = vif->wilc; if (!wl) { netdev_err(dev, "wl is NULL\n"); @@ -794,11 +794,11 @@ void wilc1000_wlan_deinit(struct net_device *dev) static int wlan_init_locks(struct net_device *dev) { - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wl; - nic = netdev_priv(dev); - wl = nic->wilc; + vif = netdev_priv(dev); + wl = vif->wilc; PRINT_D(INIT_DBG, "Initializing Locks ...\n"); @@ -820,11 +820,11 @@ static int wlan_init_locks(struct net_device *dev) static int wlan_deinit_locks(struct net_device *dev) { - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; - nic = netdev_priv(dev); - wilc = nic->wilc; + vif = netdev_priv(dev); + wilc = vif->wilc; PRINT_D(INIT_DBG, "De-Initializing Locks\n"); @@ -839,11 +839,11 @@ static int wlan_deinit_locks(struct net_device *dev) static int wlan_initialize_threads(struct net_device *dev) { - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; - nic = netdev_priv(dev); - wilc = nic->wilc; + vif = netdev_priv(dev); + wilc = vif->wilc; PRINT_D(INIT_DBG, "Initializing Threads ...\n"); PRINT_D(INIT_DBG, "Creating kthread for transmission\n"); @@ -861,10 +861,10 @@ static int wlan_initialize_threads(struct net_device *dev) static void wlan_deinitialize_threads(struct net_device *dev) { - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wl; - nic = netdev_priv(dev); - wl = nic->wilc; + vif = netdev_priv(dev); + wl = vif->wilc; wl->close = 1; PRINT_D(INIT_DBG, "Deinitializing Threads\n"); @@ -878,11 +878,10 @@ static void wlan_deinitialize_threads(struct net_device *dev) } } -int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) +int wilc1000_wlan_init(struct net_device *dev, struct wilc_vif *vif) { - perInterface_wlan_t *nic = p_nic; int ret = 0; - struct wilc *wl = nic->wilc; + struct wilc *wl = vif->wilc; if (!wl->initialized) { wl->mac_status = WILC_MAC_STATUS_INIT; @@ -992,7 +991,7 @@ static int mac_init_fn(struct net_device *ndev) int wilc_mac_open(struct net_device *ndev) { - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; unsigned char mac_add[ETH_ALEN] = {0}; @@ -1001,17 +1000,17 @@ int wilc_mac_open(struct net_device *ndev) struct wilc_priv *priv; struct wilc *wl; - nic = netdev_priv(ndev); - wl = nic->wilc; + vif = netdev_priv(ndev); + wl = vif->wilc; if (!wl|| !wl->dev) { netdev_err(ndev, "wilc1000: SPI device not ready\n"); return -ENODEV; } - nic = netdev_priv(ndev); - wilc = nic->wilc; - priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy); + vif = netdev_priv(ndev); + wilc = vif->wilc; + priv = wiphy_priv(vif->wilc_netdev->ieee80211_ptr->wiphy); PRINT_D(INIT_DBG, "MAC OPEN[%p]\n", ndev); ret = wilc_init_host_int(ndev); @@ -1022,7 +1021,7 @@ int wilc_mac_open(struct net_device *ndev) } PRINT_D(INIT_DBG, "*** re-init ***\n"); - ret = wilc1000_wlan_init(ndev, nic); + ret = wilc1000_wlan_init(ndev, vif); if (ret < 0) { PRINT_ER("Failed to initialize wilc1000\n"); wilc_deinit_host_int(ndev); @@ -1051,25 +1050,25 @@ int wilc_mac_open(struct net_device *ndev) return -EINVAL; } - wilc_mgmt_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, - nic->wilc_netdev->ieee80211_ptr, - nic->g_struct_frame_reg[0].frame_type, - nic->g_struct_frame_reg[0].reg); - wilc_mgmt_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, - nic->wilc_netdev->ieee80211_ptr, - nic->g_struct_frame_reg[1].frame_type, - nic->g_struct_frame_reg[1].reg); + wilc_mgmt_frame_register(vif->wilc_netdev->ieee80211_ptr->wiphy, + vif->wilc_netdev->ieee80211_ptr, + vif->g_struct_frame_reg[0].frame_type, + vif->g_struct_frame_reg[0].reg); + wilc_mgmt_frame_register(vif->wilc_netdev->ieee80211_ptr->wiphy, + vif->wilc_netdev->ieee80211_ptr, + vif->g_struct_frame_reg[1].frame_type, + vif->g_struct_frame_reg[1].reg); netif_wake_queue(ndev); wl->open_ifcs++; - nic->mac_opened = 1; + vif->mac_opened = 1; return 0; } static struct net_device_stats *mac_stats(struct net_device *dev) { - perInterface_wlan_t *nic = netdev_priv(dev); + struct wilc_vif *vif= netdev_priv(dev); - return &nic->netstats; + return &vif->netstats; } static void wilc_set_multicast_list(struct net_device *dev) @@ -1137,7 +1136,7 @@ static void linux_wlan_tx_complete(void *priv, int status) int wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev) { - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct tx_complete_data *tx_data = NULL; int queue_count; char *udp_buf; @@ -1145,8 +1144,8 @@ int wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev) struct ethhdr *eth_h; struct wilc *wilc; - nic = netdev_priv(ndev); - wilc = nic->wilc; + vif = netdev_priv(ndev); + wilc = vif->wilc; PRINT_D(TX_DBG, "Sending packet just received from TCP/IP\n"); @@ -1181,9 +1180,9 @@ int wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev) PRINT_D(TX_DBG, "Sending packet - Size = %d - Address = %p - SKB = %p\n", tx_data->size, tx_data->buff, tx_data->skb); PRINT_D(TX_DBG, "Adding tx packet to TX Queue\n"); - nic->netstats.tx_packets++; - nic->netstats.tx_bytes += tx_data->size; - tx_data->pBssid = wilc->vif[nic->u8IfIdx].bssid; + vif->netstats.tx_packets++; + vif->netstats.tx_bytes += tx_data->size; + tx_data->pBssid = wilc->vif[vif->u8IfIdx].bssid; queue_count = wilc_wlan_txq_add_net_pkt(ndev, (void *)tx_data, tx_data->buff, tx_data->size, linux_wlan_tx_complete); @@ -1199,20 +1198,20 @@ int wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev) int wilc_mac_close(struct net_device *ndev) { struct wilc_priv *priv; - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct host_if_drv *hif_drv; struct wilc *wl; - nic = netdev_priv(ndev); + vif = netdev_priv(ndev); - if (!nic || !nic->wilc_netdev || !nic->wilc_netdev->ieee80211_ptr || - !nic->wilc_netdev->ieee80211_ptr->wiphy) { - PRINT_ER("nic = NULL\n"); + if (!vif || !vif->wilc_netdev || !vif->wilc_netdev->ieee80211_ptr || + !vif->wilc_netdev->ieee80211_ptr->wiphy) { + PRINT_ER("vif = NULL\n"); return 0; } - priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy); - wl = nic->wilc; + priv = wiphy_priv(vif->wilc_netdev->ieee80211_ptr->wiphy); + wl = vif->wilc; if (!priv) { PRINT_ER("priv = NULL\n"); @@ -1240,10 +1239,10 @@ int wilc_mac_close(struct net_device *ndev) return 0; } - if (nic->wilc_netdev) { - netif_stop_queue(nic->wilc_netdev); + if (vif->wilc_netdev) { + netif_stop_queue(vif->wilc_netdev); - wilc_deinit_host_int(nic->wilc_netdev); + wilc_deinit_host_int(vif->wilc_netdev); } if (wl->open_ifcs == 0) { @@ -1254,7 +1253,7 @@ int wilc_mac_close(struct net_device *ndev) } up(&close_exit_sync); - nic->mac_opened = 0; + vif->mac_opened = 0; return 0; } @@ -1264,13 +1263,13 @@ static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) u8 *buff = NULL; s8 rssi; u32 size = 0, length = 0; - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc_priv *priv; s32 ret = 0; struct wilc *wilc; - nic = netdev_priv(ndev); - wilc = nic->wilc; + vif = netdev_priv(ndev); + wilc = vif->wilc; if (!wilc->initialized) return 0; @@ -1289,7 +1288,7 @@ static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) return PTR_ERR(buff); if (strncasecmp(buff, "RSSI", length) == 0) { - priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy); + priv = wiphy_priv(vif->wilc_netdev->ieee80211_ptr->wiphy); ret = wilc_get_rssi(priv->hWILCWFIDrv, &rssi); if (ret) PRINT_ER("Failed to send get rssi param's message queue "); @@ -1331,14 +1330,14 @@ void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset) unsigned char *buff_to_send = NULL; struct sk_buff *skb; struct net_device *wilc_netdev; - perInterface_wlan_t *nic; + struct wilc_vif *vif; wilc_netdev = get_if_handler(wilc, buff); if (!wilc_netdev) return; buff += pkt_offset; - nic = netdev_priv(wilc_netdev); + vif = netdev_priv(wilc_netdev); if (size > 0) { frame_len = size; @@ -1360,8 +1359,8 @@ void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset) memcpy(skb_put(skb, frame_len), buff_to_send, frame_len); skb->protocol = eth_type_trans(skb, wilc_netdev); - nic->netstats.rx_packets++; - nic->netstats.rx_bytes += frame_len; + vif->netstats.rx_packets++; + vif->netstats.rx_bytes += frame_len; skb->ip_summed = CHECKSUM_UNNECESSARY; stats = netif_rx(skb); PRINT_D(RX_DBG, "netif_rx ret value is: %d\n", stats); @@ -1371,32 +1370,32 @@ void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset) void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size) { int i = 0; - perInterface_wlan_t *nic; + struct wilc_vif *vif; for (i = 0; i < wilc->vif_num; i++) { - nic = netdev_priv(wilc->vif[i].ndev); - if (nic->monitor_flag) { + vif = netdev_priv(wilc->vif[i].ndev); + if (vif->monitor_flag) { WILC_WFI_monitor_rx(buff, size); return; } } - nic = netdev_priv(wilc->vif[1].ndev); - if ((buff[0] == nic->g_struct_frame_reg[0].frame_type && nic->g_struct_frame_reg[0].reg) || - (buff[0] == nic->g_struct_frame_reg[1].frame_type && nic->g_struct_frame_reg[1].reg)) + vif = netdev_priv(wilc->vif[1].ndev); + if ((buff[0] == vif->g_struct_frame_reg[0].frame_type && vif->g_struct_frame_reg[0].reg) || + (buff[0] == vif->g_struct_frame_reg[1].frame_type && vif->g_struct_frame_reg[1].reg)) WILC_WFI_p2p_rx(wilc->vif[1].ndev, buff, size); } void wilc_netdev_cleanup(struct wilc *wilc) { int i = 0; - perInterface_wlan_t *nic[NUM_CONCURRENT_IFC]; + struct wilc_vif *vif[NUM_CONCURRENT_IFC]; if (wilc && (wilc->vif[0].ndev || wilc->vif[1].ndev)) { unregister_inetaddr_notifier(&g_dev_notifier); for (i = 0; i < NUM_CONCURRENT_IFC; i++) - nic[i] = netdev_priv(wilc->vif[i].ndev); + vif[i] = netdev_priv(wilc->vif[i].ndev); } if (wilc && wilc->firmware) @@ -1407,7 +1406,7 @@ void wilc_netdev_cleanup(struct wilc *wilc) for (i = 0; i < NUM_CONCURRENT_IFC; i++) if (wilc->vif[i].ndev) - if (nic[i]->mac_opened) + if (vif[i]->mac_opened) wilc_mac_close(wilc->vif[i].ndev); for (i = 0; i < NUM_CONCURRENT_IFC; i++) { @@ -1425,7 +1424,7 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, int gpio, const struct wilc_hif_func *ops) { int i; - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct net_device *ndev; struct wilc *wl; @@ -1443,23 +1442,23 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, register_inetaddr_notifier(&g_dev_notifier); for (i = 0; i < NUM_CONCURRENT_IFC; i++) { - ndev = alloc_etherdev(sizeof(perInterface_wlan_t)); + ndev = alloc_etherdev(sizeof(struct wilc_vif)); if (!ndev) { PRINT_ER("Failed to allocate ethernet dev\n"); return -1; } - nic = netdev_priv(ndev); - memset(nic, 0, sizeof(perInterface_wlan_t)); + vif = netdev_priv(ndev); + memset(vif, 0, sizeof(struct wilc_vif)); if (i == 0) strcpy(ndev->name, "wlan%d"); else strcpy(ndev->name, "p2p%d"); - nic->u8IfIdx = wl->vif_num; - nic->wilc_netdev = ndev; - nic->wilc = *wilc; + vif->u8IfIdx = wl->vif_num; + vif->wilc_netdev = ndev; + vif->wilc = *wilc; wl->vif[wl->vif_num].ndev = ndev; wl->vif_num++; ndev->netdev_ops = &wilc_netdev_ops; @@ -1476,13 +1475,13 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, return -1; } - nic->wilc_netdev->ieee80211_ptr = wdev; - nic->wilc_netdev->ml_priv = nic; - wdev->netdev = nic->wilc_netdev; - nic->netstats.rx_packets = 0; - nic->netstats.tx_packets = 0; - nic->netstats.rx_bytes = 0; - nic->netstats.tx_bytes = 0; + vif->wilc_netdev->ieee80211_ptr = wdev; + vif->wilc_netdev->ml_priv = vif; + wdev->netdev = vif->wilc_netdev; + vif->netstats.rx_packets = 0; + vif->netstats.tx_packets = 0; + vif->netstats.rx_bytes = 0; + vif->netstats.tx_bytes = 0; } if (register_netdev(ndev)) { @@ -1491,8 +1490,8 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, return -1; } - nic->iftype = STATION_MODE; - nic->mac_opened = 0; + vif->iftype = STATION_MODE; + vif->mac_opened = 0; } return 0; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index bdc4537d87604..8ec12f8ea81df 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -500,14 +500,14 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, struct host_if_drv *pstrWFIDrv; u8 NullBssid[ETH_ALEN] = {0}; struct wilc *wl; - perInterface_wlan_t *nic; + struct wilc_vif *vif; wilc_connecting = 0; priv = (struct wilc_priv *)pUserVoid; dev = priv->dev; - nic = netdev_priv(dev); - wl = nic->wilc; + vif = netdev_priv(dev); + wl = vif->wilc; pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv; if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) { @@ -952,11 +952,11 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, u8 u8pmode = NO_ENCRYPT; enum AUTHTYPE tenuAuth_type = ANY; struct wilc *wl; - perInterface_wlan_t *nic; + struct wilc_vif *vif; priv = wiphy_priv(wiphy); - nic = netdev_priv(netdev); - wl = nic->wilc; + vif = netdev_priv(netdev); + wl = vif->wilc; PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher); @@ -1203,11 +1203,11 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev, { struct wilc_priv *priv; struct wilc *wl; - perInterface_wlan_t *nic; + struct wilc_vif *vif; priv = wiphy_priv(wiphy); - nic = netdev_priv(netdev); - wl = nic->wilc; + vif = netdev_priv(netdev); + wl = vif->wilc; if (netdev == wl->vif[0].ndev) { g_ptk_keys_saved = false; @@ -1322,14 +1322,14 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac, struct station_info *sinfo) { struct wilc_priv *priv; - perInterface_wlan_t *nic; + struct wilc_vif *vif; u32 i = 0; u32 associatedsta = 0; u32 inactive_time = 0; priv = wiphy_priv(wiphy); - nic = netdev_priv(dev); + vif = netdev_priv(dev); - if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) { + if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) { PRINT_D(HOSTAPD_DBG, "Getting station parameters\n"); PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]); @@ -1353,7 +1353,7 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time); } - if (nic->iftype == STATION_MODE) { + if (vif->iftype == STATION_MODE) { struct rf_info strStatistics; wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics); @@ -1816,10 +1816,10 @@ static int mgmt_tx(struct wiphy *wiphy, struct wilc_priv *priv; struct host_if_drv *pstrWFIDrv; u32 i; - perInterface_wlan_t *nic; + struct wilc_vif *vif; u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random); - nic = netdev_priv(wdev->netdev); + vif = netdev_priv(wdev->netdev); priv = wiphy_priv(wiphy); pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv; @@ -1890,9 +1890,9 @@ static int mgmt_tx(struct wiphy *wiphy, for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) { if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) { if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP) - WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype); + WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype); else - WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype); + WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype); break; } } @@ -1966,12 +1966,12 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, u16 frame_type, bool reg) { struct wilc_priv *priv; - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wl; priv = wiphy_priv(wiphy); - nic = netdev_priv(priv->wdev->netdev); - wl = nic->wilc; + vif = netdev_priv(priv->wdev->netdev); + wl = vif->wilc; if (!frame_type) return; @@ -1980,15 +1980,15 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, switch (frame_type) { case PROBE_REQ: { - nic->g_struct_frame_reg[0].frame_type = frame_type; - nic->g_struct_frame_reg[0].reg = reg; + vif->g_struct_frame_reg[0].frame_type = frame_type; + vif->g_struct_frame_reg[0].reg = reg; } break; case ACTION: { - nic->g_struct_frame_reg[1].frame_type = frame_type; - nic->g_struct_frame_reg[1].reg = reg; + vif->g_struct_frame_reg[1].frame_type = frame_type; + vif->g_struct_frame_reg[1].reg = reg; } break; @@ -2058,15 +2058,15 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, enum nl80211_iftype type, u32 *flags, struct vif_params *params) { struct wilc_priv *priv; - perInterface_wlan_t *nic; + struct wilc_vif *vif; u8 interface_type; u16 TID = 0; u8 i; struct wilc *wl; - nic = netdev_priv(dev); + vif = netdev_priv(dev); priv = wiphy_priv(wiphy); - wl = nic->wilc; + wl = vif->wilc; PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n"); PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name); @@ -2088,12 +2088,12 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, dev->ieee80211_ptr->iftype = type; priv->wdev->iftype = type; - nic->monitor_flag = 0; - nic->iftype = STATION_MODE; + vif->monitor_flag = 0; + vif->iftype = STATION_MODE; memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN); - interface_type = nic->iftype; - nic->iftype = STATION_MODE; + interface_type = vif->iftype; + vif->iftype = STATION_MODE; if (wl->initialized) { wilc_del_all_rx_ba_session(priv->hWILCWFIDrv, @@ -2103,9 +2103,9 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, up(&wl->cfg_event); wilc1000_wlan_deinit(dev); - wilc1000_wlan_init(dev, nic); + wilc1000_wlan_init(dev, vif); wilc_initialized = 1; - nic->iftype = interface_type; + vif->iftype = interface_type; wilc_set_wfi_drv_handler(wl->vif[0].hif_drv); wilc_set_mac_address(wl->vif[0].hif_drv, @@ -2147,11 +2147,11 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, if (wl->initialized) { for (i = 0; i < num_reg_frame; i++) { - PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type, - nic->g_struct_frame_reg[i].reg); + PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type, + vif->g_struct_frame_reg[i].reg); wilc_frame_register(priv->hWILCWFIDrv, - nic->g_struct_frame_reg[i].frame_type, - nic->g_struct_frame_reg[i].reg); + vif->g_struct_frame_reg[i].frame_type, + vif->g_struct_frame_reg[i].reg); } } @@ -2171,17 +2171,17 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, dev->ieee80211_ptr->iftype = type; priv->wdev->iftype = type; - nic->monitor_flag = 0; + vif->monitor_flag = 0; PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n"); - nic->iftype = CLIENT_MODE; + vif->iftype = CLIENT_MODE; if (wl->initialized) { wilc_wait_msg_queue_idle(); wilc1000_wlan_deinit(dev); - wilc1000_wlan_init(dev, nic); + wilc1000_wlan_init(dev, vif); wilc_initialized = 1; wilc_set_wfi_drv_handler(wl->vif[0].hif_drv); @@ -2227,11 +2227,11 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, if (wl->initialized) { for (i = 0; i < num_reg_frame; i++) { - PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type, - nic->g_struct_frame_reg[i].reg); + PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type, + vif->g_struct_frame_reg[i].reg); wilc_frame_register(priv->hWILCWFIDrv, - nic->g_struct_frame_reg[i].frame_type, - nic->g_struct_frame_reg[i].reg); + vif->g_struct_frame_reg[i].frame_type, + vif->g_struct_frame_reg[i].reg); } } } @@ -2242,23 +2242,23 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type); dev->ieee80211_ptr->iftype = type; priv->wdev->iftype = type; - nic->iftype = AP_MODE; + vif->iftype = AP_MODE; PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv); PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n"); wilc_wlan_get_firmware(dev); if (wl->initialized) { - nic->iftype = AP_MODE; + vif->iftype = AP_MODE; wilc_mac_close(dev); wilc_mac_open(dev); for (i = 0; i < num_reg_frame; i++) { - PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type, - nic->g_struct_frame_reg[i].reg); + PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type, + vif->g_struct_frame_reg[i].reg); wilc_frame_register(priv->hWILCWFIDrv, - nic->g_struct_frame_reg[i].frame_type, - nic->g_struct_frame_reg[i].reg); + vif->g_struct_frame_reg[i].frame_type, + vif->g_struct_frame_reg[i].reg); } } break; @@ -2282,11 +2282,11 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n"); - nic->iftype = GO_MODE; + vif->iftype = GO_MODE; wilc_wait_msg_queue_idle(); wilc1000_wlan_deinit(dev); - wilc1000_wlan_init(dev, nic); + wilc1000_wlan_init(dev, vif); wilc_initialized = 1; wilc_set_wfi_drv_handler(wl->vif[0].hif_drv); @@ -2331,11 +2331,11 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, if (wl->initialized) { for (i = 0; i < num_reg_frame; i++) { - PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type, - nic->g_struct_frame_reg[i].reg); + PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type, + vif->g_struct_frame_reg[i].reg); wilc_frame_register(priv->hWILCWFIDrv, - nic->g_struct_frame_reg[i].frame_type, - nic->g_struct_frame_reg[i].reg); + vif->g_struct_frame_reg[i].frame_type, + vif->g_struct_frame_reg[i].reg); } } break; @@ -2355,11 +2355,11 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev, struct wilc_priv *priv; s32 s32Error = 0; struct wilc *wl; - perInterface_wlan_t *nic; + struct wilc_vif *vif; priv = wiphy_priv(wiphy); - nic = netdev_priv(dev); - wl = nic->wilc; + vif = netdev_priv(dev); + wl = vif ->wilc; PRINT_D(HOSTAPD_DBG, "Starting ap\n"); PRINT_D(HOSTAPD_DBG, "Interval = %d\n DTIM period = %d\n Head length = %zu Tail length = %zu\n", @@ -2429,15 +2429,15 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, s32 s32Error = 0; struct wilc_priv *priv; struct add_sta_param strStaParams = { {0} }; - perInterface_wlan_t *nic; + struct wilc_vif *vif; if (!wiphy) return -EFAULT; priv = wiphy_priv(wiphy); - nic = netdev_priv(dev); + vif = netdev_priv(dev); - if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) { + if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) { memcpy(strStaParams.bssid, mac, ETH_ALEN); memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN); strStaParams.aid = params->aid; @@ -2500,15 +2500,15 @@ static int del_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac = params->mac; s32 s32Error = 0; struct wilc_priv *priv; - perInterface_wlan_t *nic; + struct wilc_vif *vif; if (!wiphy) return -EFAULT; priv = wiphy_priv(wiphy); - nic = netdev_priv(dev); + vif = netdev_priv(dev); - if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) { + if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) { PRINT_D(HOSTAPD_DBG, "Deleting station\n"); @@ -2533,7 +2533,7 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, s32 s32Error = 0; struct wilc_priv *priv; struct add_sta_param strStaParams = { {0} }; - perInterface_wlan_t *nic; + struct wilc_vif *vif; PRINT_D(HOSTAPD_DBG, "Change station paramters\n"); @@ -2542,9 +2542,9 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, return -EFAULT; priv = wiphy_priv(wiphy); - nic = netdev_priv(dev); + vif = netdev_priv(dev); - if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) { + if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) { memcpy(strStaParams.bssid, mac, ETH_ALEN); strStaParams.aid = params->aid; strStaParams.rates_len = params->supported_rates_len; @@ -2606,7 +2606,7 @@ static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy, u32 *flags, struct vif_params *params) { - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc_priv *priv; struct net_device *new_ifc = NULL; @@ -2616,17 +2616,17 @@ static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy, PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev); - nic = netdev_priv(priv->wdev->netdev); + vif = netdev_priv(priv->wdev->netdev); if (type == NL80211_IFTYPE_MONITOR) { PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n"); - PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev); - new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev); + PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", vif->wilc_netdev); + new_ifc = WILC_WFI_init_mon_interface(name, vif->wilc_netdev); if (new_ifc) { PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n"); - nic = netdev_priv(priv->wdev->netdev); - nic->monitor_flag = 1; + vif = netdev_priv(priv->wdev->netdev); + vif->monitor_flag = 1; } else PRINT_ER("Error in initializing monitor interface\n "); } diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index b9961f079e274..0d0449706de12 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -149,6 +149,14 @@ typedef struct { } struct_frame_reg; struct wilc_vif { + u8 u8IfIdx; + u8 iftype; + int monitor_flag; + int mac_opened; + struct_frame_reg g_struct_frame_reg[num_reg_frame]; + struct net_device *wilc_netdev; + struct net_device_stats netstats; + struct wilc *wilc; u8 src_addr[ETH_ALEN]; u8 bssid[ETH_ALEN]; struct host_if_drv *hif_drv; @@ -210,22 +218,11 @@ struct wilc { struct device *dev; }; -typedef struct { - u8 u8IfIdx; - u8 iftype; - int monitor_flag; - int mac_opened; - struct_frame_reg g_struct_frame_reg[num_reg_frame]; - struct net_device *wilc_netdev; - struct net_device_stats netstats; - struct wilc *wilc; -} perInterface_wlan_t; - struct WILC_WFI_mon_priv { struct net_device *real_ndev; }; -int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic); +int wilc1000_wlan_init(struct net_device *dev, struct wilc_vif *vif); void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset); void wilc_mac_indicate(struct wilc *wilc, int flag); diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 32ecc2df91aa3..768a42c22dd4d 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -72,11 +72,11 @@ wilc_wlan_txq_remove_from_head(struct net_device *dev) { struct txq_entry_t *tqe; unsigned long flags; - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; - nic = netdev_priv(dev); - wilc = nic->wilc; + vif = netdev_priv(dev); + wilc = vif->wilc; spin_lock_irqsave(&wilc->txq_spinlock, flags); if (wilc->txq_head) { @@ -97,11 +97,11 @@ static void wilc_wlan_txq_add_to_tail(struct net_device *dev, struct txq_entry_t *tqe) { unsigned long flags; - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; - nic = netdev_priv(dev); - wilc = nic->wilc; + vif = netdev_priv(dev); + wilc = vif->wilc; spin_lock_irqsave(&wilc->txq_spinlock, flags); @@ -239,11 +239,11 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) unsigned short h_proto; int i; unsigned long flags; - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; - nic = netdev_priv(dev); - wilc = nic->wilc; + vif = netdev_priv(dev); + wilc = vif->wilc; eth_hdr_ptr = &buffer[0]; @@ -301,13 +301,13 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe) static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) { - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; u32 i = 0; u32 dropped = 0; - nic = netdev_priv(dev); - wilc = nic->wilc; + vif = netdev_priv(dev); + wilc = vif->wilc; spin_lock_irqsave(&wilc->txq_spinlock, wilc->txq_spinlock_flags); for (i = pending_base; i < (pending_base + pending_acks); i++) { @@ -397,10 +397,10 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func) { struct txq_entry_t *tqe; - perInterface_wlan_t *nic = netdev_priv(dev); + struct wilc_vif *vif = netdev_priv(dev); struct wilc *wilc; - wilc = nic->wilc; + wilc = vif->wilc; if (wilc->quit) return 0; @@ -429,10 +429,10 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func) { struct txq_entry_t *tqe; - perInterface_wlan_t *nic = netdev_priv(dev); + struct wilc_vif *vif = netdev_priv(dev); struct wilc *wilc; - wilc = nic->wilc; + wilc = vif->wilc; if (wilc->quit) return 0; @@ -676,11 +676,11 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) int counter; int timeout; u32 vmm_table[WILC_VMM_TBL_SIZE]; - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; - nic = netdev_priv(dev); - wilc = nic->wilc; + vif = netdev_priv(dev); + wilc = vif->wilc; txb = wilc->tx_buffer; wilc->txq_exit = 0; @@ -1348,11 +1348,11 @@ void wilc_wlan_cleanup(struct net_device *dev) struct rxq_entry_t *rqe; u32 reg = 0; int ret; - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; - nic = netdev_priv(dev); - wilc = nic->wilc; + vif = netdev_priv(dev); + wilc = vif->wilc; wilc->quit = 1; do { @@ -1510,11 +1510,11 @@ static u32 init_chip(struct net_device *dev) { u32 chipid; u32 reg, ret = 0; - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; - nic = netdev_priv(dev); - wilc = nic->wilc; + vif = netdev_priv(dev); + wilc = vif->wilc; acquire_bus(wilc, ACQUIRE_ONLY); @@ -1580,10 +1580,10 @@ _fail_: int wilc_wlan_init(struct net_device *dev) { int ret = 0; - perInterface_wlan_t *nic = netdev_priv(dev); + struct wilc_vif *vif = netdev_priv(dev); struct wilc *wilc; - wilc = nic->wilc; + wilc = vif->wilc; PRINT_D(INIT_DBG, "Initializing WILC_Wlan ...\n"); @@ -1640,11 +1640,11 @@ u16 wilc_set_machw_change_vir_if(struct net_device *dev, bool value) { u16 ret; u32 reg; - perInterface_wlan_t *nic; + struct wilc_vif *vif; struct wilc *wilc; - nic = netdev_priv(dev); - wilc = nic->wilc; + vif = netdev_priv(dev); + wilc = vif->wilc; mutex_lock(&wilc->hif_cs); ret = wilc->hif_func->hif_read_reg(wilc, WILC_CHANGING_VIR_IF, -- GitLab From 1f435d2ef4cdb9c451f768d6c2e827351a55c64b Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:37 +0900 Subject: [PATCH 1791/2855] staging: wilc1000: change vif to pointer to refence real private data vif of struct has it's own memory which is not necessary because we have allocated vif from netdev_priv. Change vif to pointer type and assign vif which is netdev private data. Change it's operator on related codes as well. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 65 ++++++++--------- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 72 +++++++++---------- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 2 +- 3 files changed, 70 insertions(+), 69 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 263d9d84c8cf5..810d7ce374685 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -289,9 +289,9 @@ static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header) bssid1 = mac_header + 4; for (i = 0; i < wilc->vif_num; i++) - if (!memcmp(bssid1, wilc->vif[i].bssid, ETH_ALEN) || - !memcmp(bssid, wilc->vif[i].bssid, ETH_ALEN)) - return wilc->vif[i].ndev; + if (!memcmp(bssid1, wilc->vif[i]->bssid, ETH_ALEN) || + !memcmp(bssid, wilc->vif[i]->bssid, ETH_ALEN)) + return wilc->vif[i]->ndev; PRINT_INFO(INIT_DBG, "Invalide handle\n"); for (i = 0; i < 25; i++) @@ -299,9 +299,9 @@ static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header) bssid = mac_header + 18; bssid1 = mac_header + 12; for (i = 0; i < wilc->vif_num; i++) - if (!memcmp(bssid1, wilc->vif[i].bssid, ETH_ALEN) || - !memcmp(bssid, wilc->vif[i].bssid, ETH_ALEN)) - return wilc->vif[i].ndev; + if (!memcmp(bssid1, wilc->vif[i]->bssid, ETH_ALEN) || + !memcmp(bssid, wilc->vif[i]->bssid, ETH_ALEN)) + return wilc->vif[i]->ndev; PRINT_INFO(INIT_DBG, "\n"); return NULL; @@ -318,8 +318,8 @@ int wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid) wilc = vif->wilc; for (i = 0; i < wilc->vif_num; i++) - if (wilc->vif[i].ndev == wilc_netdev) { - memcpy(wilc->vif[i].bssid, bssid, 6); + if (wilc->vif[i]->ndev == wilc_netdev) { + memcpy(wilc->vif[i]->bssid, bssid, 6); ret = 0; break; } @@ -334,7 +334,7 @@ int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc) u8 ret_val = 0; for (i = 0; i < wilc->vif_num; i++) - if (memcmp(wilc->vif[i].bssid, null_bssid, 6)) + if (memcmp(wilc->vif[i]->bssid, null_bssid, 6)) ret_val++; return ret_val; @@ -384,10 +384,10 @@ static int linux_wlan_txq_task(void *vp) if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD) { PRINT_D(TX_DBG, "Waking up queue\n"); - if (netif_queue_stopped(wl->vif[0].ndev)) - netif_wake_queue(wl->vif[0].ndev); - if (netif_queue_stopped(wl->vif[1].ndev)) - netif_wake_queue(wl->vif[1].ndev); + if (netif_queue_stopped(wl->vif[0]->ndev)) + netif_wake_queue(wl->vif[0]->ndev); + if (netif_queue_stopped(wl->vif[1]->ndev)) + netif_wake_queue(wl->vif[1]->ndev); } if (ret == WILC_TX_ERR_NO_BUF) { @@ -1034,14 +1034,14 @@ int wilc_mac_open(struct net_device *ndev) PRINT_D(INIT_DBG, "Mac address: %pM\n", mac_add); for (i = 0; i < wl->vif_num; i++) { - if (ndev == wl->vif[i].ndev) { - memcpy(wl->vif[i].src_addr, mac_add, ETH_ALEN); - wl->vif[i].hif_drv = priv->hWILCWFIDrv; + if (ndev == wl->vif[i]->ndev) { + memcpy(wl->vif[i]->src_addr, mac_add, ETH_ALEN); + wl->vif[i]->hif_drv = priv->hWILCWFIDrv; break; } } - memcpy(ndev->dev_addr, wl->vif[i].src_addr, ETH_ALEN); + memcpy(ndev->dev_addr, wl->vif[i]->src_addr, ETH_ALEN); if (!is_valid_ether_addr(ndev->dev_addr)) { PRINT_ER("Error: Wrong MAC address\n"); @@ -1182,14 +1182,14 @@ int wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev) PRINT_D(TX_DBG, "Adding tx packet to TX Queue\n"); vif->netstats.tx_packets++; vif->netstats.tx_bytes += tx_data->size; - tx_data->pBssid = wilc->vif[vif->u8IfIdx].bssid; + tx_data->pBssid = wilc->vif[vif->u8IfIdx]->bssid; queue_count = wilc_wlan_txq_add_net_pkt(ndev, (void *)tx_data, tx_data->buff, tx_data->size, linux_wlan_tx_complete); if (queue_count > FLOW_CONTROL_UPPER_THRESHOLD) { - netif_stop_queue(wilc->vif[0].ndev); - netif_stop_queue(wilc->vif[1].ndev); + netif_stop_queue(wilc->vif[0]->ndev); + netif_stop_queue(wilc->vif[1]->ndev); } return 0; @@ -1373,17 +1373,17 @@ void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size) struct wilc_vif *vif; for (i = 0; i < wilc->vif_num; i++) { - vif = netdev_priv(wilc->vif[i].ndev); + vif = netdev_priv(wilc->vif[i]->ndev); if (vif->monitor_flag) { WILC_WFI_monitor_rx(buff, size); return; } } - vif = netdev_priv(wilc->vif[1].ndev); + vif = netdev_priv(wilc->vif[1]->ndev); if ((buff[0] == vif->g_struct_frame_reg[0].frame_type && vif->g_struct_frame_reg[0].reg) || (buff[0] == vif->g_struct_frame_reg[1].frame_type && vif->g_struct_frame_reg[1].reg)) - WILC_WFI_p2p_rx(wilc->vif[1].ndev, buff, size); + WILC_WFI_p2p_rx(wilc->vif[1]->ndev, buff, size); } void wilc_netdev_cleanup(struct wilc *wilc) @@ -1391,28 +1391,28 @@ void wilc_netdev_cleanup(struct wilc *wilc) int i = 0; struct wilc_vif *vif[NUM_CONCURRENT_IFC]; - if (wilc && (wilc->vif[0].ndev || wilc->vif[1].ndev)) { + if (wilc && (wilc->vif[0]->ndev || wilc->vif[1]->ndev)) { unregister_inetaddr_notifier(&g_dev_notifier); for (i = 0; i < NUM_CONCURRENT_IFC; i++) - vif[i] = netdev_priv(wilc->vif[i].ndev); + vif[i] = netdev_priv(wilc->vif[i]->ndev); } if (wilc && wilc->firmware) release_firmware(wilc->firmware); - if (wilc && (wilc->vif[0].ndev || wilc->vif[1].ndev)) { + if (wilc && (wilc->vif[0]->ndev || wilc->vif[1]->ndev)) { wilc_lock_timeout(wilc, &close_exit_sync, 12 * 1000); for (i = 0; i < NUM_CONCURRENT_IFC; i++) - if (wilc->vif[i].ndev) + if (wilc->vif[i]->ndev) if (vif[i]->mac_opened) - wilc_mac_close(wilc->vif[i].ndev); + wilc_mac_close(wilc->vif[i]->ndev); for (i = 0; i < NUM_CONCURRENT_IFC; i++) { - unregister_netdev(wilc->vif[i].ndev); - wilc_free_wiphy(wilc->vif[i].ndev); - free_netdev(wilc->vif[i].ndev); + unregister_netdev(wilc->vif[i]->ndev); + wilc_free_wiphy(wilc->vif[i]->ndev); + free_netdev(wilc->vif[i]->ndev); } } @@ -1459,7 +1459,8 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, vif->u8IfIdx = wl->vif_num; vif->wilc_netdev = ndev; vif->wilc = *wilc; - wl->vif[wl->vif_num].ndev = ndev; + wl->vif[i] = vif; + wl->vif[wl->vif_num]->ndev = ndev; wl->vif_num++; ndev->netdev_ops = &wilc_netdev_ops; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 8ec12f8ea81df..d128fb69002e2 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -578,9 +578,9 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, if (!pstrWFIDrv->p2p_connect) wlan_channel = INVALID_CHANNEL; - if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) { + if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) { pstrDisconnectNotifInfo->u16reason = 3; - } else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) { + } else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) { pstrDisconnectNotifInfo->u16reason = 1; } cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie, @@ -1118,7 +1118,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, KeyLen = params->key_len - 16; } - if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) { + if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) { g_add_gtk_key_params.key_idx = key_index; g_add_gtk_key_params.pairwise = pairwise; if (!mac_addr) { @@ -1152,7 +1152,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, KeyLen = params->key_len - 16; } - if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) { + if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) { g_add_ptk_key_params.key_idx = key_index; g_add_ptk_key_params.pairwise = pairwise; if (!mac_addr) { @@ -1209,7 +1209,7 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev, vif = netdev_priv(netdev); wl = vif->wilc; - if (netdev == wl->vif[0].ndev) { + if (netdev == wl->vif[0]->ndev) { g_ptk_keys_saved = false; g_gtk_keys_saved = false; g_wep_keys_saved = false; @@ -2097,7 +2097,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, if (wl->initialized) { wilc_del_all_rx_ba_session(priv->hWILCWFIDrv, - wl->vif[0].bssid, TID); + wl->vif[0]->bssid, TID); wilc_wait_msg_queue_idle(); up(&wl->cfg_event); @@ -2107,15 +2107,15 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, wilc_initialized = 1; vif->iftype = interface_type; - wilc_set_wfi_drv_handler(wl->vif[0].hif_drv); - wilc_set_mac_address(wl->vif[0].hif_drv, - wl->vif[0].src_addr); + wilc_set_wfi_drv_handler(wl->vif[0]->hif_drv); + wilc_set_mac_address(wl->vif[0]->hif_drv, + wl->vif[0]->src_addr); wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE); if (g_wep_keys_saved) { - wilc_set_wep_default_keyid(wl->vif[0].hif_drv, + wilc_set_wep_default_keyid(wl->vif[0]->hif_drv, g_key_wep_params.key_idx); - wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv, + wilc_add_wep_key_bss_sta(wl->vif[0]->hif_drv, g_key_wep_params.key, g_key_wep_params.key_len, g_key_wep_params.key_idx); @@ -2130,15 +2130,15 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0], g_key_gtk_params.key[1], g_key_gtk_params.key[2]); - add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy, - wl->vif[0].ndev, + add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy, + wl->vif[0]->ndev, g_add_ptk_key_params.key_idx, g_add_ptk_key_params.pairwise, g_add_ptk_key_params.mac_addr, (struct key_params *)(&g_key_ptk_params)); - add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy, - wl->vif[0].ndev, + add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy, + wl->vif[0]->ndev, g_add_gtk_key_params.key_idx, g_add_gtk_key_params.pairwise, g_add_gtk_key_params.mac_addr, @@ -2167,7 +2167,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n"); wilc_del_all_rx_ba_session(priv->hWILCWFIDrv, - wl->vif[0].bssid, TID); + wl->vif[0]->bssid, TID); dev->ieee80211_ptr->iftype = type; priv->wdev->iftype = type; @@ -2184,15 +2184,15 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, wilc1000_wlan_init(dev, vif); wilc_initialized = 1; - wilc_set_wfi_drv_handler(wl->vif[0].hif_drv); - wilc_set_mac_address(wl->vif[0].hif_drv, - wl->vif[0].src_addr); + wilc_set_wfi_drv_handler(wl->vif[0]->hif_drv); + wilc_set_mac_address(wl->vif[0]->hif_drv, + wl->vif[0]->src_addr); wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE); if (g_wep_keys_saved) { - wilc_set_wep_default_keyid(wl->vif[0].hif_drv, + wilc_set_wep_default_keyid(wl->vif[0]->hif_drv, g_key_wep_params.key_idx); - wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv, + wilc_add_wep_key_bss_sta(wl->vif[0]->hif_drv, g_key_wep_params.key, g_key_wep_params.key_len, g_key_wep_params.key_idx); @@ -2207,15 +2207,15 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0], g_key_gtk_params.key[1], g_key_gtk_params.key[2]); - add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy, - wl->vif[0].ndev, + add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy, + wl->vif[0]->ndev, g_add_ptk_key_params.key_idx, g_add_ptk_key_params.pairwise, g_add_ptk_key_params.mac_addr, (struct key_params *)(&g_key_ptk_params)); - add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy, - wl->vif[0].ndev, + add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy, + wl->vif[0]->ndev, g_add_gtk_key_params.key_idx, g_add_gtk_key_params.pairwise, g_add_gtk_key_params.mac_addr, @@ -2271,7 +2271,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, jiffies + msecs_to_jiffies(during_ip_time)); wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0); wilc_del_all_rx_ba_session(priv->hWILCWFIDrv, - wl->vif[0].bssid, TID); + wl->vif[0]->bssid, TID); wilc_enable_ps = false; PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n"); dev->ieee80211_ptr->iftype = type; @@ -2289,15 +2289,15 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, wilc1000_wlan_init(dev, vif); wilc_initialized = 1; - wilc_set_wfi_drv_handler(wl->vif[0].hif_drv); - wilc_set_mac_address(wl->vif[0].hif_drv, - wl->vif[0].src_addr); + wilc_set_wfi_drv_handler(wl->vif[0]->hif_drv); + wilc_set_mac_address(wl->vif[0]->hif_drv, + wl->vif[0]->src_addr); wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE); if (g_wep_keys_saved) { - wilc_set_wep_default_keyid(wl->vif[0].hif_drv, + wilc_set_wep_default_keyid(wl->vif[0]->hif_drv, g_key_wep_params.key_idx); - wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv, + wilc_add_wep_key_bss_sta(wl->vif[0]->hif_drv, g_key_wep_params.key, g_key_wep_params.key_len, g_key_wep_params.key_idx); @@ -2314,15 +2314,15 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, g_key_gtk_params.key[1], g_key_gtk_params.key[2], g_key_gtk_params.cipher); - add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy, - wl->vif[0].ndev, + add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy, + wl->vif[0]->ndev, g_add_ptk_key_params.key_idx, g_add_ptk_key_params.pairwise, g_add_ptk_key_params.mac_addr, (struct key_params *)(&g_key_ptk_params)); - add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy, - wl->vif[0].ndev, + add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy, + wl->vif[0]->ndev, g_add_gtk_key_params.key_idx, g_add_gtk_key_params.pairwise, g_add_gtk_key_params.mac_addr, @@ -2370,7 +2370,7 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev, if (s32Error != 0) PRINT_ER("Error in setting channel\n"); - wilc_wlan_set_bssid(dev, wl->vif[0].src_addr); + wilc_wlan_set_bssid(dev, wl->vif[0]->src_addr); s32Error = wilc_add_beacon(priv->hWILCWFIDrv, settings->beacon_interval, diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 0d0449706de12..9f5eac8acd075 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -172,7 +172,7 @@ struct wilc { int dev_irq_num; int close; u8 vif_num; - struct wilc_vif vif[NUM_CONCURRENT_IFC]; + struct wilc_vif *vif[NUM_CONCURRENT_IFC]; u8 open_ifcs; struct semaphore txq_add_to_head_cs; -- GitLab From 1006b5c71cbd8f4f89a67a6b4c4648aa9154199b Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:38 +0900 Subject: [PATCH 1792/2855] staging: wilc1000: remove duplicate netdev There are two net_device pointer which is the same because two structures are merged into wilc_vif in previous patch. Remove wilc_netdev and change with ndev. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 35 +++++++++---------- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 4 +-- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 1 - 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 810d7ce374685..bb3ff49e8e672 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -440,8 +440,8 @@ int wilc_wlan_get_firmware(struct net_device *dev) goto _fail_; } - if (!(&vif->wilc_netdev->dev)) { - PRINT_ER("&vif->wilc_netdev->dev is NULL\n"); + if (!(&vif->ndev->dev)) { + PRINT_ER("&vif->ndev->dev is NULL\n"); goto _fail_; } @@ -1010,7 +1010,7 @@ int wilc_mac_open(struct net_device *ndev) vif = netdev_priv(ndev); wilc = vif->wilc; - priv = wiphy_priv(vif->wilc_netdev->ieee80211_ptr->wiphy); + priv = wiphy_priv(vif->ndev->ieee80211_ptr->wiphy); PRINT_D(INIT_DBG, "MAC OPEN[%p]\n", ndev); ret = wilc_init_host_int(ndev); @@ -1050,12 +1050,12 @@ int wilc_mac_open(struct net_device *ndev) return -EINVAL; } - wilc_mgmt_frame_register(vif->wilc_netdev->ieee80211_ptr->wiphy, - vif->wilc_netdev->ieee80211_ptr, + wilc_mgmt_frame_register(vif->ndev->ieee80211_ptr->wiphy, + vif->ndev->ieee80211_ptr, vif->g_struct_frame_reg[0].frame_type, vif->g_struct_frame_reg[0].reg); - wilc_mgmt_frame_register(vif->wilc_netdev->ieee80211_ptr->wiphy, - vif->wilc_netdev->ieee80211_ptr, + wilc_mgmt_frame_register(vif->ndev->ieee80211_ptr->wiphy, + vif->ndev->ieee80211_ptr, vif->g_struct_frame_reg[1].frame_type, vif->g_struct_frame_reg[1].reg); netif_wake_queue(ndev); @@ -1204,13 +1204,13 @@ int wilc_mac_close(struct net_device *ndev) vif = netdev_priv(ndev); - if (!vif || !vif->wilc_netdev || !vif->wilc_netdev->ieee80211_ptr || - !vif->wilc_netdev->ieee80211_ptr->wiphy) { + if (!vif || !vif->ndev || !vif->ndev->ieee80211_ptr || + !vif->ndev->ieee80211_ptr->wiphy) { PRINT_ER("vif = NULL\n"); return 0; } - priv = wiphy_priv(vif->wilc_netdev->ieee80211_ptr->wiphy); + priv = wiphy_priv(vif->ndev->ieee80211_ptr->wiphy); wl = vif->wilc; if (!priv) { @@ -1239,10 +1239,10 @@ int wilc_mac_close(struct net_device *ndev) return 0; } - if (vif->wilc_netdev) { - netif_stop_queue(vif->wilc_netdev); + if (vif->ndev) { + netif_stop_queue(vif->ndev); - wilc_deinit_host_int(vif->wilc_netdev); + wilc_deinit_host_int(vif->ndev); } if (wl->open_ifcs == 0) { @@ -1288,7 +1288,7 @@ static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) return PTR_ERR(buff); if (strncasecmp(buff, "RSSI", length) == 0) { - priv = wiphy_priv(vif->wilc_netdev->ieee80211_ptr->wiphy); + priv = wiphy_priv(vif->ndev->ieee80211_ptr->wiphy); ret = wilc_get_rssi(priv->hWILCWFIDrv, &rssi); if (ret) PRINT_ER("Failed to send get rssi param's message queue "); @@ -1457,7 +1457,6 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, strcpy(ndev->name, "p2p%d"); vif->u8IfIdx = wl->vif_num; - vif->wilc_netdev = ndev; vif->wilc = *wilc; wl->vif[i] = vif; wl->vif[wl->vif_num]->ndev = ndev; @@ -1476,9 +1475,9 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, return -1; } - vif->wilc_netdev->ieee80211_ptr = wdev; - vif->wilc_netdev->ml_priv = vif; - wdev->netdev = vif->wilc_netdev; + vif->ndev->ieee80211_ptr = wdev; + vif->ndev->ml_priv = vif; + wdev->netdev = vif->ndev; vif->netstats.rx_packets = 0; vif->netstats.tx_packets = 0; vif->netstats.rx_bytes = 0; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index d128fb69002e2..87f8d0db35795 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -2621,8 +2621,8 @@ static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy, if (type == NL80211_IFTYPE_MONITOR) { PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n"); - PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", vif->wilc_netdev); - new_ifc = WILC_WFI_init_mon_interface(name, vif->wilc_netdev); + PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", vif->ndev); + new_ifc = WILC_WFI_init_mon_interface(name, vif->ndev); if (new_ifc) { PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n"); vif = netdev_priv(priv->wdev->netdev); diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 9f5eac8acd075..98ac8ed04a06c 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -154,7 +154,6 @@ struct wilc_vif { int monitor_flag; int mac_opened; struct_frame_reg g_struct_frame_reg[num_reg_frame]; - struct net_device *wilc_netdev; struct net_device_stats netstats; struct wilc *wilc; u8 src_addr[ETH_ALEN]; -- GitLab From cf60106bfc2fa17d6f1346991e74af92b8f53055 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:39 +0900 Subject: [PATCH 1793/2855] staging: wilc1000: pass vif to hostIFthread We will pass vif, which is currently being used as net_device, instead of hif_dev. This is the first step to use index of vif to pass to the driver. Add new argument vif to all the functions that send message to hostIFthread and set vif to msg.vif. As a result, hostIfthread will get vif. In later patch, we will remove drv of host_if_msg and use vif instead of it. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 234 +++++++++++------- drivers/staging/wilc1000/host_interface.h | 165 ++++++------ drivers/staging/wilc1000/linux_wlan.c | 22 +- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 166 +++++++------ 4 files changed, 341 insertions(+), 246 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 23bd8d306c8b3..3dd2833f7e724 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -194,6 +194,7 @@ struct host_if_msg { u16 id; union message_body body; struct host_if_drv *drv; + struct wilc_vif *vif; }; struct join_bss_param { @@ -389,9 +390,13 @@ static s32 handle_set_operation_mode(struct host_if_drv *hif_drv, return result; } -static s32 host_int_get_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx); +static s32 host_int_get_ipaddress(struct wilc_vif *vif, + struct host_if_drv *hif_drv, + u8 *u16ipadd, u8 idx); -static s32 handle_set_ip_address(struct host_if_drv *hif_drv, u8 *ip_addr, u8 idx) +static s32 handle_set_ip_address(struct wilc_vif *vif, + struct host_if_drv *hif_drv, u8 *ip_addr, + u8 idx) { s32 result = 0; struct wid wid; @@ -413,7 +418,7 @@ static s32 handle_set_ip_address(struct host_if_drv *hif_drv, u8 *ip_addr, u8 id result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, get_id_from_handler(hif_drv)); - host_int_get_ipaddress(hif_drv, firmware_ip_addr, idx); + host_int_get_ipaddress(vif, hif_drv, firmware_ip_addr, idx); if (result) { PRINT_ER("Failed to set IP address\n"); @@ -425,7 +430,8 @@ static s32 handle_set_ip_address(struct host_if_drv *hif_drv, u8 *ip_addr, u8 id return result; } -static s32 handle_get_ip_address(struct host_if_drv *hif_drv, u8 idx) +static s32 handle_get_ip_address(struct wilc_vif *vif, + struct host_if_drv *hif_drv, u8 idx) { s32 result = 0; struct wid wid; @@ -445,7 +451,7 @@ static s32 handle_get_ip_address(struct host_if_drv *hif_drv, u8 idx) kfree(wid.val); if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0) - wilc_setup_ipaddress(hif_drv, set_ip[idx], idx); + wilc_setup_ipaddress(vif, hif_drv, set_ip[idx], idx); if (result != 0) { PRINT_ER("Failed to get IP address\n"); @@ -1493,7 +1499,8 @@ static s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv, u32 u32MaxAssocRespInfoLen, u32 *pu32RcvdAssocRespInfoLen); -static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, +static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif, + struct host_if_drv *hif_drv, struct rcvd_async_info *pstrRcvdGnrlAsyncInfo) { s32 result = 0; @@ -1622,7 +1629,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, if ((u8MacStatus == MAC_CONNECTED) && (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) { - wilc_set_power_mgmt(hif_drv, 0, 0); + wilc_set_power_mgmt(vif, hif_drv, 0, 0); PRINT_D(HOSTINF_DBG, "MAC status : CONNECTED and Connect Status : Successful\n"); hif_drv->hif_state = HOST_IF_CONNECTED; @@ -1668,7 +1675,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, if (hif_drv->usr_conn_req.conn_result) { wilc_optaining_ip = false; - wilc_set_power_mgmt(hif_drv, 0, 0); + wilc_set_power_mgmt(vif, hif_drv, 0, 0); hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL, @@ -1993,7 +2000,8 @@ _WPAPtk_end_case_: return result; } -static void Handle_Disconnect(struct host_if_drv *hif_drv) +static void Handle_Disconnect(struct wilc_vif *vif, + struct host_if_drv *hif_drv) { struct wid wid; @@ -2008,7 +2016,7 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) PRINT_D(HOSTINF_DBG, "Sending disconnect request\n"); wilc_optaining_ip = false; - wilc_set_power_mgmt(hif_drv, 0, 0); + wilc_set_power_mgmt(vif, hif_drv, 0, 0); eth_zero_addr(wilc_connected_ssid); @@ -2079,14 +2087,15 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv) up(&hif_drv->sem_test_disconn_block); } -void wilc_resolve_disconnect_aberration(struct host_if_drv *hif_drv) +void wilc_resolve_disconnect_aberration(struct wilc_vif *vif, + struct host_if_drv *hif_drv) { if (!hif_drv) return; if ((hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) || (hif_drv->hif_state == HOST_IF_CONNECTING)) { PRINT_D(HOSTINF_DBG, "\n\n<< correcting Supplicant state machine >>\n\n"); - wilc_disconnect(hif_drv, 1); + wilc_disconnect(vif, hif_drv, 1); } } @@ -2792,12 +2801,14 @@ static int hostIFthread(void *pvArg) struct host_if_msg msg; struct host_if_drv *hif_drv; struct wilc *wilc = (struct wilc*)pvArg; + struct wilc_vif *vif; memset(&msg, 0, sizeof(struct host_if_msg)); while (1) { wilc_mq_recv(&hif_msg_q, &msg, sizeof(struct host_if_msg), &u32Ret); hif_drv = (struct host_if_drv *)msg.drv; + vif = msg.vif; if (msg.id == HOST_IF_MSG_EXIT) { PRINT_D(GENERIC_DBG, "THREAD: Exiting HostIfThread\n"); break; @@ -2840,7 +2851,8 @@ static int hostIFthread(void *pvArg) break; case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO: - Handle_RcvdGnrlAsyncInfo(msg.drv, &msg.body.async_info); + Handle_RcvdGnrlAsyncInfo(vif, msg.drv, + &msg.body.async_info); break; case HOST_IF_MSG_KEY: @@ -2856,7 +2868,7 @@ static int hostIFthread(void *pvArg) break; case HOST_IF_MSG_DISCONNECT: - Handle_Disconnect(msg.drv); + Handle_Disconnect(vif, msg.drv); break; case HOST_IF_MSG_RCVD_SCAN_COMPLETE: @@ -2938,14 +2950,15 @@ static int hostIFthread(void *pvArg) case HOST_IF_MSG_SET_IPADDRESS: PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n"); - handle_set_ip_address(msg.drv, + handle_set_ip_address(vif, msg.drv, msg.body.ip_info.ip_addr, msg.body.ip_info.idx); break; case HOST_IF_MSG_GET_IPADDRESS: PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n"); - handle_get_ip_address(msg.drv, msg.body.ip_info.idx); + handle_get_ip_address(vif, msg.drv, + msg.body.ip_info.idx); break; case HOST_IF_MSG_SET_MAC_ADDRESS: @@ -3032,7 +3045,8 @@ s32 wilc_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress) return 0; } -int wilc_remove_wep_key(struct host_if_drv *hif_drv, u8 index) +int wilc_remove_wep_key(struct wilc_vif *vif, + struct host_if_drv *hif_drv, u8 index) { int result = 0; struct host_if_msg msg; @@ -3049,6 +3063,7 @@ int wilc_remove_wep_key(struct host_if_drv *hif_drv, u8 index) msg.body.key_info.type = WEP; msg.body.key_info.action = REMOVEKEY; msg.drv = hif_drv; + msg.vif = vif; msg.body.key_info.attr.wep.index = index; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -3059,7 +3074,8 @@ int wilc_remove_wep_key(struct host_if_drv *hif_drv, u8 index) return result; } -int wilc_set_wep_default_keyid(struct host_if_drv *hif_drv, u8 index) +int wilc_set_wep_default_keyid(struct wilc_vif *vif, + struct host_if_drv *hif_drv, u8 index) { int result = 0; struct host_if_msg msg; @@ -3076,6 +3092,7 @@ int wilc_set_wep_default_keyid(struct host_if_drv *hif_drv, u8 index) msg.body.key_info.type = WEP; msg.body.key_info.action = DEFAULTKEY; msg.drv = hif_drv; + msg.vif = vif; msg.body.key_info.attr.wep.index = index; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -3086,10 +3103,8 @@ int wilc_set_wep_default_keyid(struct host_if_drv *hif_drv, u8 index) return result; } -int wilc_add_wep_key_bss_sta(struct host_if_drv *hif_drv, - const u8 *key, - u8 len, - u8 index) +int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, struct host_if_drv *hif_drv, + const u8 *key, u8 len, u8 index) { int result = 0; struct host_if_msg msg; @@ -3105,6 +3120,7 @@ int wilc_add_wep_key_bss_sta(struct host_if_drv *hif_drv, msg.body.key_info.type = WEP; msg.body.key_info.action = ADDKEY; msg.drv = hif_drv; + msg.vif = vif; msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL); if (!msg.body.key_info.attr.wep.key) return -ENOMEM; @@ -3120,11 +3136,8 @@ int wilc_add_wep_key_bss_sta(struct host_if_drv *hif_drv, return result; } -int wilc_add_wep_key_bss_ap(struct host_if_drv *hif_drv, - const u8 *key, - u8 len, - u8 index, - u8 mode, +int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, struct host_if_drv *hif_drv, + const u8 *key, u8 len, u8 index, u8 mode, enum AUTHTYPE auth_type) { int result = 0; @@ -3146,6 +3159,7 @@ int wilc_add_wep_key_bss_ap(struct host_if_drv *hif_drv, msg.body.key_info.type = WEP; msg.body.key_info.action = ADDKEY_AP; msg.drv = hif_drv; + msg.vif = vif; msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL); if (!msg.body.key_info.attr.wep.key) return -ENOMEM; @@ -3164,10 +3178,10 @@ int wilc_add_wep_key_bss_ap(struct host_if_drv *hif_drv, return result; } -int wilc_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, - u8 ptk_key_len, const u8 *mac_addr, - const u8 *rx_mic, const u8 *tx_mic, - u8 mode, u8 cipher_mode, u8 index) +int wilc_add_ptk(struct wilc_vif *vif, struct host_if_drv *hif_drv, + const u8 *ptk, u8 ptk_key_len, const u8 *mac_addr, + const u8 *rx_mic, const u8 *tx_mic, u8 mode, u8 cipher_mode, + u8 index) { int result = 0; struct host_if_msg msg; @@ -3219,6 +3233,7 @@ int wilc_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, msg.body.key_info.attr.wpa.mac_addr = mac_addr; msg.body.key_info.attr.wpa.mode = cipher_mode; msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -3230,11 +3245,10 @@ int wilc_add_ptk(struct host_if_drv *hif_drv, const u8 *ptk, return result; } -int wilc_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, - u8 gtk_key_len, u8 index, - u32 key_rsc_len, const u8 *key_rsc, - const u8 *rx_mic, const u8 *tx_mic, - u8 mode, u8 cipher_mode) +int wilc_add_rx_gtk(struct wilc_vif *vif, struct host_if_drv *hif_drv, + const u8 *rx_gtk, u8 gtk_key_len, u8 index, + u32 key_rsc_len, const u8 *key_rsc, const u8 *rx_mic, + const u8 *tx_mic, u8 mode, u8 cipher_mode) { int result = 0; struct host_if_msg msg; @@ -3263,6 +3277,7 @@ int wilc_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, msg.id = HOST_IF_MSG_KEY; msg.body.key_info.type = WPA_RX_GTK; msg.drv = hif_drv; + msg.vif = vif; if (mode == AP_MODE) { msg.body.key_info.action = ADDKEY_AP; @@ -3298,7 +3313,8 @@ int wilc_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *rx_gtk, return result; } -s32 wilc_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_attr *pu8PmkidInfoArray) +s32 wilc_set_pmkid_info(struct wilc_vif *vif, struct host_if_drv *hif_drv, + struct host_if_pmkid_attr *pu8PmkidInfoArray) { s32 result = 0; struct host_if_msg msg; @@ -3315,6 +3331,7 @@ s32 wilc_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_attr * msg.body.key_info.type = PMKSA; msg.body.key_info.action = ADDKEY; msg.drv = hif_drv; + msg.vif = vif; for (i = 0; i < pu8PmkidInfoArray->numpmkid; i++) { memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid, @@ -3330,7 +3347,8 @@ s32 wilc_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_attr * return result; } -s32 wilc_get_mac_address(struct host_if_drv *hif_drv, u8 *pu8MacAddress) +s32 wilc_get_mac_address(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u8 *pu8MacAddress) { s32 result = 0; struct host_if_msg msg; @@ -3340,6 +3358,7 @@ s32 wilc_get_mac_address(struct host_if_drv *hif_drv, u8 *pu8MacAddress) msg.id = HOST_IF_MSG_GET_MAC_ADDRESS; msg.body.get_mac_info.mac_addr = pu8MacAddress; msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) { @@ -3351,7 +3370,8 @@ s32 wilc_get_mac_address(struct host_if_drv *hif_drv, u8 *pu8MacAddress) return result; } -s32 wilc_set_mac_address(struct host_if_drv *hif_drv, u8 *pu8MacAddress) +s32 wilc_set_mac_address(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u8 *pu8MacAddress) { s32 result = 0; struct host_if_msg msg; @@ -3362,6 +3382,7 @@ s32 wilc_set_mac_address(struct host_if_drv *hif_drv, u8 *pu8MacAddress) msg.id = HOST_IF_MSG_SET_MAC_ADDRESS; memcpy(msg.body.set_mac_info.mac_addr, pu8MacAddress, ETH_ALEN); msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) @@ -3370,12 +3391,12 @@ s32 wilc_set_mac_address(struct host_if_drv *hif_drv, u8 *pu8MacAddress) return result; } -s32 wilc_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid, - const u8 *pu8ssid, size_t ssidLen, - const u8 *pu8IEs, size_t IEsLen, - wilc_connect_result pfConnectResult, void *pvUserArg, - u8 u8security, enum AUTHTYPE tenuAuth_type, - u8 u8channel, void *pJoinParams) +s32 wilc_set_join_req(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u8 *pu8bssid, const u8 *pu8ssid, size_t ssidLen, + const u8 *pu8IEs, size_t IEsLen, + wilc_connect_result pfConnectResult, void *pvUserArg, + u8 u8security, enum AUTHTYPE tenuAuth_type, + u8 u8channel, void *pJoinParams) { s32 result = 0; struct host_if_msg msg; @@ -3401,6 +3422,7 @@ s32 wilc_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid, msg.body.con_info.arg = pvUserArg; msg.body.con_info.params = pJoinParams; msg.drv = hif_drv ; + msg.vif = vif; if (pu8bssid) { msg.body.con_info.bssid = kmalloc(6, GFP_KERNEL); @@ -3437,7 +3459,7 @@ s32 wilc_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid, return result; } -s32 wilc_flush_join_req(struct host_if_drv *hif_drv) +s32 wilc_flush_join_req(struct wilc_vif *vif, struct host_if_drv *hif_drv) { s32 result = 0; struct host_if_msg msg; @@ -3452,6 +3474,7 @@ s32 wilc_flush_join_req(struct host_if_drv *hif_drv) msg.id = HOST_IF_MSG_FLUSH_CONNECT; msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) { @@ -3462,7 +3485,8 @@ s32 wilc_flush_join_req(struct host_if_drv *hif_drv) return result; } -s32 wilc_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode) +s32 wilc_disconnect(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u16 u16ReasonCode) { s32 result = 0; struct host_if_msg msg; @@ -3476,6 +3500,7 @@ s32 wilc_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode) msg.id = HOST_IF_MSG_DISCONNECT; msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) @@ -3517,7 +3542,8 @@ static s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv, return result; } -int wilc_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel) +int wilc_set_mac_chnl_num(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u8 channel) { int result; struct host_if_msg msg; @@ -3531,6 +3557,7 @@ int wilc_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel) msg.id = HOST_IF_MSG_SET_CHANNEL; msg.body.channel_info.set_ch = channel; msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) { @@ -3559,7 +3586,7 @@ int wilc_wait_msg_queue_idle(void) return result; } -int wilc_set_wfi_drv_handler(struct host_if_drv *hif_drv) +int wilc_set_wfi_drv_handler(struct wilc_vif *vif, struct host_if_drv *hif_drv) { int result = 0; struct host_if_msg msg; @@ -3568,6 +3595,7 @@ int wilc_set_wfi_drv_handler(struct host_if_drv *hif_drv) msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER; msg.body.drv.handler = get_id_from_handler(hif_drv); msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) { @@ -3578,7 +3606,8 @@ int wilc_set_wfi_drv_handler(struct host_if_drv *hif_drv) return result; } -int wilc_set_operation_mode(struct host_if_drv *hif_drv, u32 mode) +int wilc_set_operation_mode(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u32 mode) { int result = 0; struct host_if_msg msg; @@ -3587,6 +3616,7 @@ int wilc_set_operation_mode(struct host_if_drv *hif_drv, u32 mode) msg.id = HOST_IF_MSG_SET_OPERATION_MODE; msg.body.mode.mode = mode; msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) { @@ -3597,7 +3627,7 @@ int wilc_set_operation_mode(struct host_if_drv *hif_drv, u32 mode) return result; } -s32 wilc_get_inactive_time(struct host_if_drv *hif_drv, +s32 wilc_get_inactive_time(struct wilc_vif *vif, struct host_if_drv *hif_drv, const u8 *mac, u32 *pu32InactiveTime) { s32 result = 0; @@ -3613,6 +3643,7 @@ s32 wilc_get_inactive_time(struct host_if_drv *hif_drv, msg.id = HOST_IF_MSG_GET_INACTIVETIME; msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) @@ -3625,7 +3656,8 @@ s32 wilc_get_inactive_time(struct host_if_drv *hif_drv, return result; } -s32 wilc_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi) +s32 wilc_get_rssi(struct wilc_vif *vif, struct host_if_drv *hif_drv, + s8 *ps8Rssi) { s32 result = 0; struct host_if_msg msg; @@ -3633,6 +3665,7 @@ s32 wilc_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi) memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_GET_RSSI; msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) { @@ -3652,7 +3685,8 @@ s32 wilc_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi) return result; } -s32 wilc_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics) +s32 wilc_get_statistics(struct wilc_vif *vif, struct host_if_drv *hif_drv, + struct rf_info *pstrStatistics) { s32 result = 0; struct host_if_msg msg; @@ -3661,6 +3695,7 @@ s32 wilc_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatist msg.id = HOST_IF_MSG_GET_STATISTICS; msg.body.data = (char *)pstrStatistics; msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) { @@ -3672,11 +3707,11 @@ s32 wilc_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatist return result; } -s32 wilc_scan(struct host_if_drv *hif_drv, u8 u8ScanSource, - u8 u8ScanType, u8 *pu8ChnlFreqList, - u8 u8ChnlListLen, const u8 *pu8IEs, - size_t IEsLen, wilc_scan_result ScanResult, - void *pvUserArg, struct hidden_network *pstrHiddenNetwork) +s32 wilc_scan(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u8 u8ScanSource, u8 u8ScanType, u8 *pu8ChnlFreqList, + u8 u8ChnlListLen, const u8 *pu8IEs, + size_t IEsLen, wilc_scan_result ScanResult, + void *pvUserArg, struct hidden_network *pstrHiddenNetwork) { s32 result = 0; struct host_if_msg msg; @@ -3698,6 +3733,7 @@ s32 wilc_scan(struct host_if_drv *hif_drv, u8 u8ScanSource, PRINT_D(HOSTINF_DBG, "pstrHiddenNetwork IS EQUAL TO NULL\n"); msg.drv = hif_drv; + msg.vif = vif; msg.body.scan_info.src = u8ScanSource; msg.body.scan_info.type = u8ScanType; msg.body.scan_info.result = ScanResult; @@ -3725,7 +3761,7 @@ s32 wilc_scan(struct host_if_drv *hif_drv, u8 u8ScanSource, return result; } -s32 wilc_hif_set_cfg(struct host_if_drv *hif_drv, +s32 wilc_hif_set_cfg(struct wilc_vif *vif, struct host_if_drv *hif_drv, struct cfg_param_val *pstrCfgParamVal) { s32 result = 0; @@ -3740,6 +3776,7 @@ s32 wilc_hif_set_cfg(struct host_if_drv *hif_drv, msg.id = HOST_IF_MSG_CFG_PARAMS; msg.body.cfg_info.cfg_attr_info = *pstrCfgParamVal; msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -3882,7 +3919,7 @@ _fail_: return result; } -s32 wilc_deinit(struct host_if_drv *hif_drv) +s32 wilc_deinit(struct wilc_vif *vif, struct host_if_drv *hif_drv) { s32 result = 0; struct host_if_msg msg; @@ -3909,7 +3946,7 @@ s32 wilc_deinit(struct host_if_drv *hif_drv) del_timer_sync(&hif_drv->remain_on_ch_timer); - wilc_set_wfi_drv_handler(NULL); + wilc_set_wfi_drv_handler(vif, NULL); down(&hif_sema_driver); if (hif_drv->usr_scan_req.scan_result) { @@ -3930,6 +3967,7 @@ s32 wilc_deinit(struct host_if_drv *hif_drv) msg.id = HOST_IF_MSG_EXIT; msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result != 0) @@ -4051,11 +4089,11 @@ void wilc_scan_complete_received(u8 *pu8Buffer, u32 u32Length) return; } -s32 wilc_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID, - u32 u32duration, u16 chan, - wilc_remain_on_chan_expired RemainOnChanExpired, - wilc_remain_on_chan_ready RemainOnChanReady, - void *pvUserArg) +s32 wilc_remain_on_channel(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u32 u32SessionID, u32 u32duration, u16 chan, + wilc_remain_on_chan_expired RemainOnChanExpired, + wilc_remain_on_chan_ready RemainOnChanReady, + void *pvUserArg) { s32 result = 0; struct host_if_msg msg; @@ -4075,6 +4113,7 @@ s32 wilc_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID, msg.body.remain_on_ch.u32duration = u32duration; msg.body.remain_on_ch.id = u32SessionID; msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) @@ -4083,7 +4122,8 @@ s32 wilc_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID, return result; } -s32 wilc_listen_state_expired(struct host_if_drv *hif_drv, u32 u32SessionID) +s32 wilc_listen_state_expired(struct wilc_vif *vif, + struct host_if_drv *hif_drv, u32 u32SessionID) { s32 result = 0; struct host_if_msg msg; @@ -4098,6 +4138,7 @@ s32 wilc_listen_state_expired(struct host_if_drv *hif_drv, u32 u32SessionID) memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED; msg.drv = hif_drv; + msg.vif = vif; msg.body.remain_on_ch.id = u32SessionID; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -4107,7 +4148,8 @@ s32 wilc_listen_state_expired(struct host_if_drv *hif_drv, u32 u32SessionID) return result; } -s32 wilc_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool bReg) +s32 wilc_frame_register(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u16 u16FrameType, bool bReg) { s32 result = 0; struct host_if_msg msg; @@ -4138,6 +4180,7 @@ s32 wilc_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool bReg msg.body.reg_frame.frame_type = u16FrameType; msg.body.reg_frame.reg = bReg; msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) @@ -4146,9 +4189,10 @@ s32 wilc_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool bReg return result; } -s32 wilc_add_beacon(struct host_if_drv *hif_drv, u32 u32Interval, - u32 u32DTIMPeriod, u32 u32HeadLen, u8 *pu8Head, - u32 u32TailLen, u8 *pu8Tail) +s32 wilc_add_beacon(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u32 u32Interval, + u32 u32DTIMPeriod, u32 u32HeadLen, u8 *pu8Head, + u32 u32TailLen, u8 *pu8Tail) { s32 result = 0; struct host_if_msg msg; @@ -4165,6 +4209,7 @@ s32 wilc_add_beacon(struct host_if_drv *hif_drv, u32 u32Interval, msg.id = HOST_IF_MSG_ADD_BEACON; msg.drv = hif_drv; + msg.vif = vif; pstrSetBeaconParam->interval = u32Interval; pstrSetBeaconParam->dtim_period = u32DTIMPeriod; pstrSetBeaconParam->head_len = u32HeadLen; @@ -4200,7 +4245,7 @@ ERRORHANDLER: return result; } -int wilc_del_beacon(struct host_if_drv *hif_drv) +int wilc_del_beacon(struct wilc_vif *vif, struct host_if_drv *hif_drv) { int result = 0; struct host_if_msg msg; @@ -4212,6 +4257,7 @@ int wilc_del_beacon(struct host_if_drv *hif_drv) msg.id = HOST_IF_MSG_DEL_BEACON; msg.drv = hif_drv; + msg.vif = vif; PRINT_D(HOSTINF_DBG, "Setting deleting beacon message queue params\n"); result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -4221,7 +4267,7 @@ int wilc_del_beacon(struct host_if_drv *hif_drv) return result; } -int wilc_add_station(struct host_if_drv *hif_drv, +int wilc_add_station(struct wilc_vif *vif, struct host_if_drv *hif_drv, struct add_sta_param *sta_param) { int result = 0; @@ -4239,6 +4285,7 @@ int wilc_add_station(struct host_if_drv *hif_drv, msg.id = HOST_IF_MSG_ADD_STATION; msg.drv = hif_drv; + msg.vif = vif; memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param)); if (add_sta_info->rates_len > 0) { @@ -4255,7 +4302,8 @@ int wilc_add_station(struct host_if_drv *hif_drv, return result; } -int wilc_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr) +int wilc_del_station(struct wilc_vif *vif, struct host_if_drv *hif_drv, + const u8 *mac_addr) { int result = 0; struct host_if_msg msg; @@ -4272,6 +4320,7 @@ int wilc_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr) msg.id = HOST_IF_MSG_DEL_STATION; msg.drv = hif_drv; + msg.vif = vif; if (!mac_addr) eth_broadcast_addr(del_sta_info->mac_addr); @@ -4284,7 +4333,7 @@ int wilc_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr) return result; } -s32 wilc_del_allstation(struct host_if_drv *hif_drv, +s32 wilc_del_allstation(struct wilc_vif *vif, struct host_if_drv *hif_drv, u8 pu8MacAddr[][ETH_ALEN]) { s32 result = 0; @@ -4305,6 +4354,7 @@ s32 wilc_del_allstation(struct host_if_drv *hif_drv, msg.id = HOST_IF_MSG_DEL_ALL_STA; msg.drv = hif_drv; + msg.vif = vif; for (i = 0; i < MAX_NUM_STA; i++) { if (memcmp(pu8MacAddr[i], au8Zero_Buff, ETH_ALEN)) { @@ -4335,7 +4385,7 @@ s32 wilc_del_allstation(struct host_if_drv *hif_drv, return result; } -s32 wilc_edit_station(struct host_if_drv *hif_drv, +s32 wilc_edit_station(struct wilc_vif *vif, struct host_if_drv *hif_drv, struct add_sta_param *pstrStaParams) { s32 result = 0; @@ -4353,6 +4403,7 @@ s32 wilc_edit_station(struct host_if_drv *hif_drv, msg.id = HOST_IF_MSG_EDIT_STATION; msg.drv = hif_drv; + msg.vif = vif; memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param)); if (pstrAddStationMsg->rates_len > 0) { @@ -4373,9 +4424,8 @@ s32 wilc_edit_station(struct host_if_drv *hif_drv, return result; } -s32 wilc_set_power_mgmt(struct host_if_drv *hif_drv, - bool bIsEnabled, - u32 u32Timeout) +s32 wilc_set_power_mgmt(struct wilc_vif *vif, struct host_if_drv *hif_drv, + bool bIsEnabled, u32 u32Timeout) { s32 result = 0; struct host_if_msg msg; @@ -4394,6 +4444,7 @@ s32 wilc_set_power_mgmt(struct host_if_drv *hif_drv, msg.id = HOST_IF_MSG_POWER_MGMT; msg.drv = hif_drv; + msg.vif = vif; pstrPowerMgmtParam->enabled = bIsEnabled; pstrPowerMgmtParam->timeout = u32Timeout; @@ -4404,9 +4455,10 @@ s32 wilc_set_power_mgmt(struct host_if_drv *hif_drv, return result; } -s32 wilc_setup_multicast_filter(struct host_if_drv *hif_drv, - bool bIsEnabled, - u32 u32count) +s32 wilc_setup_multicast_filter(struct wilc_vif *vif, + struct host_if_drv *hif_drv, + bool bIsEnabled, + u32 u32count) { s32 result = 0; struct host_if_msg msg; @@ -4423,6 +4475,7 @@ s32 wilc_setup_multicast_filter(struct host_if_drv *hif_drv, msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER; msg.drv = hif_drv; + msg.vif = vif; pstrMulticastFilterParam->enabled = bIsEnabled; pstrMulticastFilterParam->cnt = u32count; @@ -4598,9 +4651,10 @@ void wilc_free_join_params(void *pJoinParams) PRINT_ER("Unable to FREE null pointer\n"); } -s32 wilc_del_all_rx_ba_session(struct host_if_drv *hif_drv, - char *pBSSID, - char TID) +s32 wilc_del_all_rx_ba_session(struct wilc_vif *vif, + struct host_if_drv *hif_drv, + char *pBSSID, + char TID) { s32 result = 0; struct host_if_msg msg; @@ -4618,6 +4672,7 @@ s32 wilc_del_all_rx_ba_session(struct host_if_drv *hif_drv, memcpy(pBASessionInfo->bssid, pBSSID, ETH_ALEN); pBASessionInfo->tid = TID; msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) @@ -4628,7 +4683,8 @@ s32 wilc_del_all_rx_ba_session(struct host_if_drv *hif_drv, return result; } -s32 wilc_setup_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx) +s32 wilc_setup_ipaddress(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u8 *u16ipadd, u8 idx) { s32 result = 0; struct host_if_msg msg; @@ -4646,6 +4702,7 @@ s32 wilc_setup_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx) msg.body.ip_info.ip_addr = u16ipadd; msg.drv = hif_drv; + msg.vif = vif; msg.body.ip_info.idx = idx; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -4655,7 +4712,9 @@ s32 wilc_setup_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx) return result; } -static s32 host_int_get_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx) +static s32 host_int_get_ipaddress(struct wilc_vif *vif, + struct host_if_drv *hif_drv, + u8 *u16ipadd, u8 idx) { s32 result = 0; struct host_if_msg msg; @@ -4671,6 +4730,7 @@ static s32 host_int_get_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 msg.body.ip_info.ip_addr = u16ipadd; msg.drv = hif_drv; + msg.vif = vif; msg.body.ip_info.idx = idx; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 4f5300d096eb2..ccbbe73c7ee5d 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -305,97 +305,104 @@ struct add_sta_param { u16 flags_set; }; +struct wilc_vif; s32 wilc_remove_key(struct host_if_drv *hWFIDrv, const u8 *pu8StaAddress); -int wilc_remove_wep_key(struct host_if_drv *wfi_drv, u8 index); -int wilc_set_wep_default_keyid(struct host_if_drv *hif_drv, u8 index); -int wilc_add_wep_key_bss_sta(struct host_if_drv *hif_drv, - const u8 *key, u8 len, u8 index); -int wilc_add_wep_key_bss_ap(struct host_if_drv *hif_drv, - const u8 *key, u8 len, u8 index, u8 mode, - enum AUTHTYPE auth_type); -s32 wilc_add_ptk(struct host_if_drv *hWFIDrv, const u8 *pu8Ptk, - u8 u8PtkKeylen, const u8 *mac_addr, - const u8 *pu8RxMic, const u8 *pu8TxMic, - u8 mode, u8 u8Ciphermode, u8 u8Idx); -s32 wilc_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac, - u32 *pu32InactiveTime); -s32 wilc_add_rx_gtk(struct host_if_drv *hWFIDrv, const u8 *pu8RxGtk, - u8 u8GtkKeylen, u8 u8KeyIdx, - u32 u32KeyRSClen, const u8 *KeyRSC, - const u8 *pu8RxMic, const u8 *pu8TxMic, - u8 mode, u8 u8Ciphermode); +int wilc_remove_wep_key(struct wilc_vif *vif, + struct host_if_drv *hif_drv, u8 index); +int wilc_set_wep_default_keyid(struct wilc_vif *vif, + struct host_if_drv *hif_drv, u8 index); +int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, struct host_if_drv *hif_drv, + const u8 *key, u8 len, u8 index); +int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, struct host_if_drv *hif_drv, + const u8 *key, u8 len, u8 index, u8 mode, + enum AUTHTYPE auth_type); +s32 wilc_add_ptk(struct wilc_vif *vif, struct host_if_drv *hif_drv, + const u8 *pu8Ptk, u8 u8PtkKeylen, const u8 *mac_addr, + const u8 *pu8RxMic, const u8 *pu8TxMic, + u8 mode, u8 u8Ciphermode, u8 u8Idx); +s32 wilc_get_inactive_time(struct wilc_vif *vif, struct host_if_drv *hif_drv, + const u8 *mac, u32 *pu32InactiveTime); +s32 wilc_add_rx_gtk(struct wilc_vif *vif, struct host_if_drv *hif_drv, + const u8 *pu8RxGtk, u8 u8GtkKeylen, u8 u8KeyIdx, + u32 u32KeyRSClen, const u8 *KeyRSC, + const u8 *pu8RxMic, const u8 *pu8TxMic, + u8 mode, u8 u8Ciphermode); s32 wilc_add_tx_gtk(struct host_if_drv *hWFIDrv, u8 u8KeyLen, u8 *pu8TxGtk, u8 u8KeyIdx); -s32 wilc_set_pmkid_info(struct host_if_drv *hWFIDrv, - struct host_if_pmkid_attr *pu8PmkidInfoArray); -s32 wilc_get_mac_address(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); -s32 wilc_set_mac_address(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress); +s32 wilc_set_pmkid_info(struct wilc_vif *vif, struct host_if_drv *hif_drv, + struct host_if_pmkid_attr *pu8PmkidInfoArray); +s32 wilc_get_mac_address(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u8 *pu8MacAddress); +s32 wilc_set_mac_address(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u8 *pu8MacAddress); int wilc_wait_msg_queue_idle(void); s32 wilc_set_start_scan_req(struct host_if_drv *hWFIDrv, u8 scanSource); -s32 wilc_set_join_req(struct host_if_drv *hWFIDrv, u8 *pu8bssid, - const u8 *pu8ssid, size_t ssidLen, - const u8 *pu8IEs, size_t IEsLen, - wilc_connect_result pfConnectResult, void *pvUserArg, - u8 u8security, enum AUTHTYPE tenuAuth_type, - u8 u8channel, void *pJoinParams); -s32 wilc_flush_join_req(struct host_if_drv *hWFIDrv); -s32 wilc_disconnect(struct host_if_drv *hWFIDrv, u16 u16ReasonCode); -int wilc_set_mac_chnl_num(struct host_if_drv *wfi_drv, u8 channel); -s32 wilc_get_rssi(struct host_if_drv *hWFIDrv, s8 *ps8Rssi); -s32 wilc_scan(struct host_if_drv *hWFIDrv, u8 u8ScanSource, - u8 u8ScanType, u8 *pu8ChnlFreqList, - u8 u8ChnlListLen, const u8 *pu8IEs, - size_t IEsLen, wilc_scan_result ScanResult, - void *pvUserArg, struct hidden_network *pstrHiddenNetwork); -s32 wilc_hif_set_cfg(struct host_if_drv *hWFIDrv, +s32 wilc_set_join_req(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u8 *pu8bssid, const u8 *pu8ssid, size_t ssidLen, + const u8 *pu8IEs, size_t IEsLen, + wilc_connect_result pfConnectResult, void *pvUserArg, + u8 u8security, enum AUTHTYPE tenuAuth_type, + u8 u8channel, void *pJoinParams); +s32 wilc_flush_join_req(struct wilc_vif *vif, struct host_if_drv *hif_drv); +s32 wilc_disconnect(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u16 u16ReasonCode); +int wilc_set_mac_chnl_num(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u8 channel); +s32 wilc_get_rssi(struct wilc_vif *vif, struct host_if_drv *hif_drv, + s8 *ps8Rssi); +s32 wilc_scan(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u8 u8ScanSource, u8 u8ScanType, u8 *pu8ChnlFreqList, + u8 u8ChnlListLen, const u8 *pu8IEs, + size_t IEsLen, wilc_scan_result ScanResult, + void *pvUserArg, struct hidden_network *pstrHiddenNetwork); +s32 wilc_hif_set_cfg(struct wilc_vif *vif, struct host_if_drv *hif_drv, struct cfg_param_val *pstrCfgParamVal); s32 wilc_init(struct net_device *dev, struct host_if_drv **phWFIDrv); -s32 wilc_deinit(struct host_if_drv *hWFIDrv); -s32 wilc_add_beacon(struct host_if_drv *hWFIDrv, u32 u32Interval, - u32 u32DTIMPeriod, - u32 u32HeadLen, - u8 *pu8Head, - u32 u32TailLen, - u8 *pu8tail); -int wilc_del_beacon(struct host_if_drv *hif_drv); -int wilc_add_station(struct host_if_drv *hif_drv, - struct add_sta_param *sta_param); -s32 wilc_del_allstation(struct host_if_drv *hWFIDrv, +s32 wilc_deinit(struct wilc_vif *vif, struct host_if_drv *hif_drv); +s32 wilc_add_beacon(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u32 u32Interval, + u32 u32DTIMPeriod, u32 u32HeadLen, u8 *pu8Head, + u32 u32TailLen, u8 *pu8Tail); +int wilc_del_beacon(struct wilc_vif *vif, struct host_if_drv *hif_drv); +int wilc_add_station(struct wilc_vif *vif, struct host_if_drv *hif_drv, + struct add_sta_param *sta_param); +s32 wilc_del_allstation(struct wilc_vif *vif, struct host_if_drv *hif_drv, u8 pu8MacAddr[][ETH_ALEN]); -int wilc_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr); -s32 wilc_edit_station(struct host_if_drv *hWFIDrv, +int wilc_del_station(struct wilc_vif *vif, struct host_if_drv *hif_drv, + const u8 *mac_addr); +s32 wilc_edit_station(struct wilc_vif *vif, struct host_if_drv *hif_drv, struct add_sta_param *pstrStaParams); -s32 wilc_set_power_mgmt(struct host_if_drv *hWFIDrv, - bool bIsEnabled, - u32 u32Timeout); -s32 wilc_setup_multicast_filter(struct host_if_drv *hWFIDrv, - bool bIsEnabled, - u32 u32count); -s32 wilc_setup_ipaddress(struct host_if_drv *hWFIDrv, - u8 *pu8IPAddr, - u8 idx); -s32 wilc_del_all_rx_ba_session(struct host_if_drv *hWFIDrv, - char *pBSSID, - char TID); -s32 wilc_remain_on_channel(struct host_if_drv *hWFIDrv, - u32 u32SessionID, - u32 u32duration, - u16 chan, - wilc_remain_on_chan_expired RemainOnChanExpired, - wilc_remain_on_chan_ready RemainOnChanReady, - void *pvUserArg); -s32 wilc_listen_state_expired(struct host_if_drv *hWFIDrv, u32 u32SessionID); -s32 wilc_frame_register(struct host_if_drv *hWFIDrv, - u16 u16FrameType, - bool bReg); -int wilc_set_wfi_drv_handler(struct host_if_drv *address); -int wilc_set_operation_mode(struct host_if_drv *wfi_drv, u32 mode); +s32 wilc_set_power_mgmt(struct wilc_vif *vif, struct host_if_drv *hif_drv, + bool bIsEnabled, u32 u32Timeout); +s32 wilc_setup_multicast_filter(struct wilc_vif *vif, + struct host_if_drv *hif_drv, + bool bIsEnabled, + u32 u32count); +s32 wilc_setup_ipaddress(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u8 *u16ipadd, u8 idx); +s32 wilc_del_all_rx_ba_session(struct wilc_vif *vif, + struct host_if_drv *hif_drv, + char *pBSSID, + char TID); +s32 wilc_remain_on_channel(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u32 u32SessionID, u32 u32duration, u16 chan, + wilc_remain_on_chan_expired RemainOnChanExpired, + wilc_remain_on_chan_ready RemainOnChanReady, + void *pvUserArg); +s32 wilc_listen_state_expired(struct wilc_vif *vif, + struct host_if_drv *hif_drv, u32 u32SessionID); +s32 wilc_frame_register(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u16 u16FrameType, bool bReg); +int wilc_set_wfi_drv_handler(struct wilc_vif *vif, struct host_if_drv *hif_drv); +int wilc_set_operation_mode(struct wilc_vif *vif, struct host_if_drv *hif_drv, + u32 mode); void wilc_free_join_params(void *pJoinParams); -s32 wilc_get_statistics(struct host_if_drv *hWFIDrv, - struct rf_info *pstrStatistics); -void wilc_resolve_disconnect_aberration(struct host_if_drv *hif_drv); +s32 wilc_get_statistics(struct wilc_vif *vif, struct host_if_drv *hif_drv, + struct rf_info *pstrStatistics); +void wilc_resolve_disconnect_aberration(struct wilc_vif *vif, + struct host_if_drv *hif_drv); extern bool wilc_optaining_ip; extern u8 wilc_connected_ssid[6]; diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index bb3ff49e8e672..60749962ed5a6 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -112,7 +112,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event } if (wilc_enable_ps) - wilc_set_power_mgmt(hif_drv, 1, 0); + wilc_set_power_mgmt(vif, hif_drv, 1, 0); PRINT_D(GENERIC_DBG, "[%s] Up IP\n", dev_iface->ifa_label); @@ -120,7 +120,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n", ip_addr_buf[0], ip_addr_buf[1], ip_addr_buf[2], ip_addr_buf[3]); - wilc_setup_ipaddress(hif_drv, ip_addr_buf, vif->u8IfIdx); + wilc_setup_ipaddress(vif, hif_drv, ip_addr_buf, vif->u8IfIdx); break; @@ -134,9 +134,9 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event } if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0) - wilc_set_power_mgmt(hif_drv, 0, 0); + wilc_set_power_mgmt(vif, hif_drv, 0, 0); - wilc_resolve_disconnect_aberration(hif_drv); + wilc_resolve_disconnect_aberration(vif, hif_drv); PRINT_D(GENERIC_DBG, "[%s] Down IP\n", dev_iface->ifa_label); @@ -145,7 +145,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event ip_addr_buf[0], ip_addr_buf[1], ip_addr_buf[2], ip_addr_buf[3]); - wilc_setup_ipaddress(hif_drv, ip_addr_buf, vif->u8IfIdx); + wilc_setup_ipaddress(vif, hif_drv, ip_addr_buf, vif->u8IfIdx); break; @@ -1030,7 +1030,7 @@ int wilc_mac_open(struct net_device *ndev) wilc_set_machw_change_vir_if(ndev, false); - wilc_get_mac_address(priv->hWILCWFIDrv, mac_add); + wilc_get_mac_address(vif, priv->hWILCWFIDrv, mac_add); PRINT_D(INIT_DBG, "Mac address: %pM\n", mac_add); for (i = 0; i < wl->vif_num; i++) { @@ -1076,9 +1076,11 @@ static void wilc_set_multicast_list(struct net_device *dev) struct netdev_hw_addr *ha; struct wilc_priv *priv; struct host_if_drv *hif_drv; + struct wilc_vif *vif; int i = 0; priv = wiphy_priv(dev->ieee80211_ptr->wiphy); + vif = netdev_priv(dev); hif_drv = (struct host_if_drv *)priv->hWILCWFIDrv; if (!dev) @@ -1095,13 +1097,13 @@ static void wilc_set_multicast_list(struct net_device *dev) if ((dev->flags & IFF_ALLMULTI) || (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) { PRINT_D(INIT_DBG, "Disable multicast filter, retrive all multicast packets\n"); - wilc_setup_multicast_filter(hif_drv, false, 0); + wilc_setup_multicast_filter(vif, hif_drv, false, 0); return; } if ((dev->mc.count) == 0) { PRINT_D(INIT_DBG, "Enable multicast filter, retrive directed packets only.\n"); - wilc_setup_multicast_filter(hif_drv, true, 0); + wilc_setup_multicast_filter(vif, hif_drv, true, 0); return; } @@ -1117,7 +1119,7 @@ static void wilc_set_multicast_list(struct net_device *dev) i++; } - wilc_setup_multicast_filter(hif_drv, true, (dev->mc.count)); + wilc_setup_multicast_filter(vif, hif_drv, true, (dev->mc.count)); return; } @@ -1289,7 +1291,7 @@ static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) if (strncasecmp(buff, "RSSI", length) == 0) { priv = wiphy_priv(vif->ndev->ieee80211_ptr->wiphy); - ret = wilc_get_rssi(priv->hWILCWFIDrv, &rssi); + ret = wilc_get_rssi(vif, priv->hWILCWFIDrv, &rssi); if (ret) PRINT_ER("Failed to send get rssi param's message queue "); PRINT_INFO(GENERIC_DBG, "RSSI :%d\n", rssi); diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 87f8d0db35795..309a0cc6446e7 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -595,14 +595,16 @@ static int set_channel(struct wiphy *wiphy, u32 channelnum = 0; struct wilc_priv *priv; int result = 0; + struct wilc_vif *vif; priv = wiphy_priv(wiphy); + vif = netdev_priv(priv->dev); channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq); PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq); curr_channel = channelnum; - result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum); + result = wilc_set_mac_chnl_num(vif, priv->hWILCWFIDrv, channelnum); if (result != 0) PRINT_ER("Error in setting channel %d\n", channelnum); @@ -617,14 +619,16 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) s32 s32Error = 0; u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS]; struct hidden_network strHiddenNetwork; + struct wilc_vif *vif; priv = wiphy_priv(wiphy); + vif = netdev_priv(priv->dev); priv->pstrScanReq = request; priv->u32RcvdChCount = 0; - wilc_set_wfi_drv_handler(priv->hWILCWFIDrv); + wilc_set_wfi_drv_handler(vif, priv->hWILCWFIDrv); reset_shadow_found(); priv->bCfgScanning = true; @@ -656,13 +660,13 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) } } PRINT_D(CFG80211_DBG, "Trigger Scan Request\n"); - s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN, + s32Error = wilc_scan(vif, priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN, au8ScanChanList, request->n_channels, (const u8 *)request->ie, request->ie_len, CfgScanResult, (void *)priv, &strHiddenNetwork); } else { PRINT_D(CFG80211_DBG, "Trigger Scan Request\n"); - s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN, + s32Error = wilc_scan(vif, priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN, au8ScanChanList, request->n_channels, (const u8 *)request->ie, request->ie_len, CfgScanResult, (void *)priv, NULL); @@ -694,13 +698,14 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, struct wilc_priv *priv; struct host_if_drv *pstrWFIDrv; tstrNetworkInfo *pstrNetworkInfo = NULL; - + struct wilc_vif *vif; wilc_connecting = 1; priv = wiphy_priv(wiphy); + vif = netdev_priv(priv->dev); pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv); - wilc_set_wfi_drv_handler(priv->hWILCWFIDrv); + wilc_set_wfi_drv_handler(vif, priv->hWILCWFIDrv); PRINT_D(CFG80211_DBG, "Connecting to SSID [%s] on netdev [%p] host if [%p]\n", sme->ssid, dev, priv->hWILCWFIDrv); if (!(strncmp(sme->ssid, "DIRECT-", 7))) { @@ -787,8 +792,8 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, g_key_wep_params.key_idx = sme->key_idx; g_wep_keys_saved = true; - wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx); - wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx); + wilc_set_wep_default_keyid(vif, priv->hWILCWFIDrv, sme->key_idx); + wilc_add_wep_key_bss_sta(vif, priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx); } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) { u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED; pcgroup_encrypt_val = "WEP104"; @@ -804,8 +809,8 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, g_key_wep_params.key_idx = sme->key_idx; g_wep_keys_saved = true; - wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx); - wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx); + wilc_set_wep_default_keyid(vif, priv->hWILCWFIDrv, sme->key_idx); + wilc_add_wep_key_bss_sta(vif, priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx); } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) { if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) { u8security = ENCRYPT_ENABLED | WPA2 | TKIP; @@ -890,7 +895,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid); - s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid, + s32Error = wilc_set_join_req(vif, priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid, sme->ssid_len, sme->ie, sme->ie_len, CfgConnectResult, (void *)priv, u8security, tenuAuth_type, pstrNetworkInfo->u8channel, @@ -911,10 +916,12 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_co s32 s32Error = 0; struct wilc_priv *priv; struct host_if_drv *pstrWFIDrv; + struct wilc_vif *vif; u8 NullBssid[ETH_ALEN] = {0}; wilc_connecting = 0; priv = wiphy_priv(wiphy); + vif = netdev_priv(priv->dev); pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv; if (!pstrWFIDrv->p2p_connect) @@ -928,7 +935,7 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_co wilc_ie = false; pstrWFIDrv->p2p_timeout = 0; - s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code); + s32Error = wilc_disconnect(vif, priv->hWILCWFIDrv, reason_code); if (s32Error != 0) { PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error); s32Error = -EINVAL; @@ -988,7 +995,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, else u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED; - wilc_add_wep_key_bss_ap(priv->hWILCWFIDrv, params->key, params->key_len, key_index, u8mode, tenuAuth_type); + wilc_add_wep_key_bss_ap(vif, priv->hWILCWFIDrv, params->key, params->key_len, key_index, u8mode, tenuAuth_type); break; } if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) { @@ -1002,7 +1009,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, for (i = 0; i < params->key_len; i++) PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]); } - wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index); + wilc_add_wep_key_bss_sta(vif, priv->hWILCWFIDrv, params->key, params->key_len, key_index); } break; @@ -1059,7 +1066,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, } - wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen, + wilc_add_rx_gtk(vif, priv->hWILCWFIDrv, params->key, KeyLen, key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode); } else { @@ -1103,7 +1110,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, priv->wilc_ptk[key_index]->key_len = params->key_len; priv->wilc_ptk[key_index]->seq_len = params->seq_len; - wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr, + wilc_add_ptk(vif, priv->hWILCWFIDrv, params->key, KeyLen, mac_addr, pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index); } break; @@ -1143,7 +1150,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, g_gtk_keys_saved = true; } - wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen, + wilc_add_rx_gtk(vif, priv->hWILCWFIDrv, params->key, KeyLen, key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode); } else { if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) { @@ -1177,7 +1184,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, g_ptk_keys_saved = true; } - wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr, + wilc_add_ptk(vif, priv->hWILCWFIDrv, params->key, KeyLen, mac_addr, pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index); PRINT_D(CFG80211_DBG, "Adding pairwise key\n"); if (INFO) { @@ -1254,7 +1261,7 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev, priv->WILC_WFI_wep_key_len[key_index] = 0; PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index); - wilc_remove_wep_key(priv->hWILCWFIDrv, key_index); + wilc_remove_wep_key(vif, priv->hWILCWFIDrv, key_index); } else { PRINT_D(CFG80211_DBG, "Removing all installed keys\n"); wilc_remove_key(priv->hWILCWFIDrv, mac_addr); @@ -1305,14 +1312,15 @@ static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 ke bool unicast, bool multicast) { struct wilc_priv *priv; - + struct wilc_vif *vif; priv = wiphy_priv(wiphy); + vif = netdev_priv(priv->dev); PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index); if (key_index != priv->WILC_WFI_wep_default) { - wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index); + wilc_set_wep_default_keyid(vif, priv->hWILCWFIDrv, key_index); } return 0; @@ -1348,7 +1356,7 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME); - wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time)); + wilc_get_inactive_time(vif, priv->hWILCWFIDrv, mac, &(inactive_time)); sinfo->inactive_time = 1000 * inactive_time; PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time); } @@ -1356,7 +1364,7 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, if (vif->iftype == STATION_MODE) { struct rf_info strStatistics; - wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics); + wilc_get_statistics(vif, priv->hWILCWFIDrv, &strStatistics); sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) | BIT(NL80211_STA_INFO_RX_PACKETS) | @@ -1394,8 +1402,10 @@ static int set_wiphy_params(struct wiphy *wiphy, u32 changed) s32 s32Error = 0; struct cfg_param_val pstrCfgParamVal; struct wilc_priv *priv; + struct wilc_vif *vif; priv = wiphy_priv(wiphy); + vif = netdev_priv(priv->dev); pstrCfgParamVal.flag = 0; PRINT_D(CFG80211_DBG, "Setting Wiphy params\n"); @@ -1425,7 +1435,7 @@ static int set_wiphy_params(struct wiphy *wiphy, u32 changed) } PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n"); - s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal); + s32Error = wilc_hif_set_cfg(vif, priv->hWILCWFIDrv, &pstrCfgParamVal); if (s32Error) PRINT_ER("Error in setting WIPHY PARAMS\n"); @@ -1439,9 +1449,10 @@ static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev, u32 i; s32 s32Error = 0; u8 flag = 0; - + struct wilc_vif *vif; struct wilc_priv *priv = wiphy_priv(wiphy); + vif = netdev_priv(priv->dev); PRINT_D(CFG80211_DBG, "Setting PMKSA\n"); @@ -1468,7 +1479,7 @@ static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev, if (!s32Error) { PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n"); - s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list); + s32Error = wilc_set_pmkid_info(vif, priv->hWILCWFIDrv, &priv->pmkid_list); } return s32Error; } @@ -1758,8 +1769,10 @@ static int remain_on_channel(struct wiphy *wiphy, { s32 s32Error = 0; struct wilc_priv *priv; + struct wilc_vif *vif; priv = wiphy_priv(wiphy); + vif = netdev_priv(priv->dev); PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value); @@ -1776,7 +1789,7 @@ static int remain_on_channel(struct wiphy *wiphy, priv->strRemainOnChanParams.u32ListenDuration = duration; priv->strRemainOnChanParams.u32ListenSessionID++; - s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv + s32Error = wilc_remain_on_channel(vif, priv->hWILCWFIDrv , priv->strRemainOnChanParams.u32ListenSessionID , duration , chan->hw_value @@ -1793,12 +1806,14 @@ static int cancel_remain_on_channel(struct wiphy *wiphy, { s32 s32Error = 0; struct wilc_priv *priv; + struct wilc_vif *vif; priv = wiphy_priv(wiphy); + vif = netdev_priv(priv->dev); PRINT_D(CFG80211_DBG, "Cancel remain on channel\n"); - s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID); + s32Error = wilc_listen_state_expired(vif, priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID); return s32Error; } @@ -1846,7 +1861,7 @@ static int mgmt_tx(struct wiphy *wiphy, if (ieee80211_is_probe_resp(mgmt->frame_control)) { PRINT_D(GENERIC_DBG, "TX: Probe Response\n"); PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value); - wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value); + wilc_set_mac_chnl_num(vif, priv->hWILCWFIDrv, chan->hw_value); curr_channel = chan->hw_value; } else if (ieee80211_is_action(mgmt->frame_control)) { PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control); @@ -1856,7 +1871,7 @@ static int mgmt_tx(struct wiphy *wiphy, if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC || buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) { PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value); - wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value); + wilc_set_mac_chnl_num(vif, priv->hWILCWFIDrv, chan->hw_value); curr_channel = chan->hw_value; } switch (buf[ACTION_SUBTYPE_ID]) { @@ -2002,7 +2017,7 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, PRINT_D(GENERIC_DBG, "Return since mac is closed\n"); return; } - wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg); + wilc_frame_register(vif, priv->hWILCWFIDrv, frame_type, reg); } static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev, @@ -2016,6 +2031,7 @@ static int dump_station(struct wiphy *wiphy, struct net_device *dev, int idx, u8 *mac, struct station_info *sinfo) { struct wilc_priv *priv; + struct wilc_vif *vif; PRINT_D(CFG80211_DBG, "Dumping station information\n"); @@ -2023,10 +2039,11 @@ static int dump_station(struct wiphy *wiphy, struct net_device *dev, return -ENOENT; priv = wiphy_priv(wiphy); + vif = netdev_priv(priv->dev); sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); - wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal)); + wilc_get_rssi(vif, priv->hWILCWFIDrv, &(sinfo->signal)); return 0; } @@ -2035,6 +2052,7 @@ static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout) { struct wilc_priv *priv; + struct wilc_vif *vif; PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout); @@ -2042,13 +2060,14 @@ static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, return -ENOENT; priv = wiphy_priv(wiphy); + vif = netdev_priv(priv->dev); if (!priv->hWILCWFIDrv) { PRINT_ER("Driver is NULL\n"); return -EIO; } if (wilc_enable_ps) - wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout); + wilc_set_power_mgmt(vif, priv->hWILCWFIDrv, enabled, timeout); return 0; @@ -2096,7 +2115,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, vif->iftype = STATION_MODE; if (wl->initialized) { - wilc_del_all_rx_ba_session(priv->hWILCWFIDrv, + wilc_del_all_rx_ba_session(vif, priv->hWILCWFIDrv, wl->vif[0]->bssid, TID); wilc_wait_msg_queue_idle(); @@ -2107,21 +2126,21 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, wilc_initialized = 1; vif->iftype = interface_type; - wilc_set_wfi_drv_handler(wl->vif[0]->hif_drv); - wilc_set_mac_address(wl->vif[0]->hif_drv, + wilc_set_wfi_drv_handler(vif, wl->vif[0]->hif_drv); + wilc_set_mac_address(vif, wl->vif[0]->hif_drv, wl->vif[0]->src_addr); - wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE); + wilc_set_operation_mode(vif, priv->hWILCWFIDrv, STATION_MODE); if (g_wep_keys_saved) { - wilc_set_wep_default_keyid(wl->vif[0]->hif_drv, + wilc_set_wep_default_keyid(vif, wl->vif[0]->hif_drv, g_key_wep_params.key_idx); - wilc_add_wep_key_bss_sta(wl->vif[0]->hif_drv, + wilc_add_wep_key_bss_sta(vif, wl->vif[0]->hif_drv, g_key_wep_params.key, g_key_wep_params.key_len, g_key_wep_params.key_idx); } - wilc_flush_join_req(priv->hWILCWFIDrv); + wilc_flush_join_req(vif, priv->hWILCWFIDrv); if (g_ptk_keys_saved && g_gtk_keys_saved) { PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0], @@ -2149,24 +2168,24 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, for (i = 0; i < num_reg_frame; i++) { PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type, vif->g_struct_frame_reg[i].reg); - wilc_frame_register(priv->hWILCWFIDrv, + wilc_frame_register(vif, priv->hWILCWFIDrv, vif->g_struct_frame_reg[i].frame_type, vif->g_struct_frame_reg[i].reg); } } wilc_enable_ps = true; - wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0); + wilc_set_power_mgmt(vif, priv->hWILCWFIDrv, 1, 0); } break; case NL80211_IFTYPE_P2P_CLIENT: wilc_enable_ps = false; - wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0); + wilc_set_power_mgmt(vif, priv->hWILCWFIDrv, 0, 0); wilc_connecting = 0; PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n"); - wilc_del_all_rx_ba_session(priv->hWILCWFIDrv, + wilc_del_all_rx_ba_session(vif, priv->hWILCWFIDrv, wl->vif[0]->bssid, TID); dev->ieee80211_ptr->iftype = type; @@ -2184,21 +2203,21 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, wilc1000_wlan_init(dev, vif); wilc_initialized = 1; - wilc_set_wfi_drv_handler(wl->vif[0]->hif_drv); - wilc_set_mac_address(wl->vif[0]->hif_drv, + wilc_set_wfi_drv_handler(vif, wl->vif[0]->hif_drv); + wilc_set_mac_address(vif, wl->vif[0]->hif_drv, wl->vif[0]->src_addr); - wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE); + wilc_set_operation_mode(vif, priv->hWILCWFIDrv, STATION_MODE); if (g_wep_keys_saved) { - wilc_set_wep_default_keyid(wl->vif[0]->hif_drv, + wilc_set_wep_default_keyid(vif, wl->vif[0]->hif_drv, g_key_wep_params.key_idx); - wilc_add_wep_key_bss_sta(wl->vif[0]->hif_drv, + wilc_add_wep_key_bss_sta(vif, wl->vif[0]->hif_drv, g_key_wep_params.key, g_key_wep_params.key_len, g_key_wep_params.key_idx); } - wilc_flush_join_req(priv->hWILCWFIDrv); + wilc_flush_join_req(vif, priv->hWILCWFIDrv); if (g_ptk_keys_saved && g_gtk_keys_saved) { PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0], @@ -2229,7 +2248,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, for (i = 0; i < num_reg_frame; i++) { PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type, vif->g_struct_frame_reg[i].reg); - wilc_frame_register(priv->hWILCWFIDrv, + wilc_frame_register(vif, priv->hWILCWFIDrv, vif->g_struct_frame_reg[i].frame_type, vif->g_struct_frame_reg[i].reg); } @@ -2256,7 +2275,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, for (i = 0; i < num_reg_frame; i++) { PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type, vif->g_struct_frame_reg[i].reg); - wilc_frame_register(priv->hWILCWFIDrv, + wilc_frame_register(vif, priv->hWILCWFIDrv, vif->g_struct_frame_reg[i].frame_type, vif->g_struct_frame_reg[i].reg); } @@ -2269,8 +2288,8 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, wilc_optaining_ip = true; mod_timer(&wilc_during_ip_timer, jiffies + msecs_to_jiffies(during_ip_time)); - wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0); - wilc_del_all_rx_ba_session(priv->hWILCWFIDrv, + wilc_set_power_mgmt(vif, priv->hWILCWFIDrv, 0, 0); + wilc_del_all_rx_ba_session(vif, priv->hWILCWFIDrv, wl->vif[0]->bssid, TID); wilc_enable_ps = false; PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n"); @@ -2289,21 +2308,21 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, wilc1000_wlan_init(dev, vif); wilc_initialized = 1; - wilc_set_wfi_drv_handler(wl->vif[0]->hif_drv); - wilc_set_mac_address(wl->vif[0]->hif_drv, + wilc_set_wfi_drv_handler(vif, wl->vif[0]->hif_drv); + wilc_set_mac_address(vif, wl->vif[0]->hif_drv, wl->vif[0]->src_addr); - wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE); + wilc_set_operation_mode(vif, priv->hWILCWFIDrv, AP_MODE); if (g_wep_keys_saved) { - wilc_set_wep_default_keyid(wl->vif[0]->hif_drv, + wilc_set_wep_default_keyid(vif, wl->vif[0]->hif_drv, g_key_wep_params.key_idx); - wilc_add_wep_key_bss_sta(wl->vif[0]->hif_drv, + wilc_add_wep_key_bss_sta(vif, wl->vif[0]->hif_drv, g_key_wep_params.key, g_key_wep_params.key_len, g_key_wep_params.key_idx); } - wilc_flush_join_req(priv->hWILCWFIDrv); + wilc_flush_join_req(vif, priv->hWILCWFIDrv); if (g_ptk_keys_saved && g_gtk_keys_saved) { PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0], @@ -2333,7 +2352,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, for (i = 0; i < num_reg_frame; i++) { PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type, vif->g_struct_frame_reg[i].reg); - wilc_frame_register(priv->hWILCWFIDrv, + wilc_frame_register(vif, priv->hWILCWFIDrv, vif->g_struct_frame_reg[i].frame_type, vif->g_struct_frame_reg[i].reg); } @@ -2372,7 +2391,7 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev, wilc_wlan_set_bssid(dev, wl->vif[0]->src_addr); - s32Error = wilc_add_beacon(priv->hWILCWFIDrv, + s32Error = wilc_add_beacon(vif, priv->hWILCWFIDrv, settings->beacon_interval, settings->dtim_period, beacon->head_len, (u8 *)beacon->head, @@ -2385,13 +2404,15 @@ static int change_beacon(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_beacon_data *beacon) { struct wilc_priv *priv; + struct wilc_vif *vif; s32 s32Error = 0; priv = wiphy_priv(wiphy); + vif = netdev_priv(priv->dev); PRINT_D(HOSTAPD_DBG, "Setting beacon\n"); - s32Error = wilc_add_beacon(priv->hWILCWFIDrv, + s32Error = wilc_add_beacon(vif, priv->hWILCWFIDrv, 0, 0, beacon->head_len, (u8 *)beacon->head, @@ -2404,18 +2425,20 @@ static int stop_ap(struct wiphy *wiphy, struct net_device *dev) { s32 s32Error = 0; struct wilc_priv *priv; + struct wilc_vif *vif; u8 NullBssid[ETH_ALEN] = {0}; if (!wiphy) return -EFAULT; priv = wiphy_priv(wiphy); + vif = netdev_priv(priv->dev); PRINT_D(HOSTAPD_DBG, "Deleting beacon\n"); wilc_wlan_set_bssid(dev, NullBssid); - s32Error = wilc_del_beacon(priv->hWILCWFIDrv); + s32Error = wilc_del_beacon(vif, priv->hWILCWFIDrv); if (s32Error) PRINT_ER("Host delete beacon fail\n"); @@ -2486,7 +2509,8 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.flags_set); - s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams); + s32Error = wilc_add_station(vif, priv->hWILCWFIDrv, + &strStaParams); if (s32Error) PRINT_ER("Host add station fail\n"); } @@ -2514,12 +2538,12 @@ static int del_station(struct wiphy *wiphy, struct net_device *dev, if (!mac) { PRINT_D(HOSTAPD_DBG, "All associated stations\n"); - s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss); + s32Error = wilc_del_allstation(vif, priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss); } else { PRINT_D(HOSTAPD_DBG, "With mac address: %x%x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } - s32Error = wilc_del_station(priv->hWILCWFIDrv, mac); + s32Error = wilc_del_station(vif, priv->hWILCWFIDrv, mac); if (s32Error) PRINT_ER("Host delete station fail\n"); @@ -2592,7 +2616,8 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.flags_set); - s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams); + s32Error = wilc_edit_station(vif, priv->hWILCWFIDrv, + &strStaParams); if (s32Error) PRINT_ER("Host edit station fail\n"); } @@ -2825,10 +2850,11 @@ int wilc_init_host_int(struct net_device *net) int wilc_deinit_host_int(struct net_device *net) { int s32Error = 0; - + struct wilc_vif *vif; struct wilc_priv *priv; priv = wdev_priv(net->ieee80211_ptr); + vif = netdev_priv(priv->dev); priv->gbAutoRateAdjusted = false; @@ -2836,7 +2862,7 @@ int wilc_deinit_host_int(struct net_device *net) op_ifcs--; - s32Error = wilc_deinit(priv->hWILCWFIDrv); + s32Error = wilc_deinit(vif, priv->hWILCWFIDrv); clear_shadow_scan(); if (op_ifcs == 0) { -- GitLab From fbf5379bfc2511acadb90e672badb827667a8ec8 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:40 +0900 Subject: [PATCH 1794/2855] staging: wilc1000: remove argument hif_drv In previous patch we add new argument vif which has hif_drv in it's member. Therefore, no need to pass hif_drv in those functions. Remove argument struct host_if_drv and use hif_drv of vif. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 177 +++++++------- drivers/staging/wilc1000/host_interface.h | 127 ++++------ drivers/staging/wilc1000/linux_wlan.c | 20 +- .../staging/wilc1000/wilc_wfi_cfgoperations.c | 223 +++++++++--------- 4 files changed, 265 insertions(+), 282 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 3dd2833f7e724..421ce0de80f47 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -451,7 +451,7 @@ static s32 handle_get_ip_address(struct wilc_vif *vif, kfree(wid.val); if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0) - wilc_setup_ipaddress(vif, hif_drv, set_ip[idx], idx); + wilc_setup_ipaddress(vif, set_ip[idx], idx); if (result != 0) { PRINT_ER("Failed to get IP address\n"); @@ -1629,7 +1629,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif, if ((u8MacStatus == MAC_CONNECTED) && (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) { - wilc_set_power_mgmt(vif, hif_drv, 0, 0); + wilc_set_power_mgmt(vif, 0, 0); PRINT_D(HOSTINF_DBG, "MAC status : CONNECTED and Connect Status : Successful\n"); hif_drv->hif_state = HOST_IF_CONNECTED; @@ -1675,7 +1675,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif, if (hif_drv->usr_conn_req.conn_result) { wilc_optaining_ip = false; - wilc_set_power_mgmt(vif, hif_drv, 0, 0); + wilc_set_power_mgmt(vif, 0, 0); hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL, @@ -2016,7 +2016,7 @@ static void Handle_Disconnect(struct wilc_vif *vif, PRINT_D(HOSTINF_DBG, "Sending disconnect request\n"); wilc_optaining_ip = false; - wilc_set_power_mgmt(vif, hif_drv, 0, 0); + wilc_set_power_mgmt(vif, 0, 0); eth_zero_addr(wilc_connected_ssid); @@ -2087,15 +2087,14 @@ static void Handle_Disconnect(struct wilc_vif *vif, up(&hif_drv->sem_test_disconn_block); } -void wilc_resolve_disconnect_aberration(struct wilc_vif *vif, - struct host_if_drv *hif_drv) +void wilc_resolve_disconnect_aberration(struct wilc_vif *vif) { - if (!hif_drv) + if (!vif->hif_drv) return; - if ((hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) || - (hif_drv->hif_state == HOST_IF_CONNECTING)) { + if ((vif->hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) || + (vif->hif_drv->hif_state == HOST_IF_CONNECTING)) { PRINT_D(HOSTINF_DBG, "\n\n<< correcting Supplicant state machine >>\n\n"); - wilc_disconnect(vif, hif_drv, 1); + wilc_disconnect(vif, 1); } } @@ -3045,11 +3044,11 @@ s32 wilc_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress) return 0; } -int wilc_remove_wep_key(struct wilc_vif *vif, - struct host_if_drv *hif_drv, u8 index) +int wilc_remove_wep_key(struct wilc_vif *vif, u8 index) { int result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { result = -EFAULT; @@ -3074,11 +3073,11 @@ int wilc_remove_wep_key(struct wilc_vif *vif, return result; } -int wilc_set_wep_default_keyid(struct wilc_vif *vif, - struct host_if_drv *hif_drv, u8 index) +int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index) { int result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { result = -EFAULT; @@ -3103,11 +3102,12 @@ int wilc_set_wep_default_keyid(struct wilc_vif *vif, return result; } -int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, struct host_if_drv *hif_drv, - const u8 *key, u8 len, u8 index) +int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len, + u8 index) { int result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("driver is null\n"); @@ -3136,12 +3136,12 @@ int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, struct host_if_drv *hif_drv, - const u8 *key, u8 len, u8 index, u8 mode, - enum AUTHTYPE auth_type) +int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len, + u8 index, u8 mode, enum AUTHTYPE auth_type) { int result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; int i; if (!hif_drv) { @@ -3178,13 +3178,13 @@ int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -int wilc_add_ptk(struct wilc_vif *vif, struct host_if_drv *hif_drv, - const u8 *ptk, u8 ptk_key_len, const u8 *mac_addr, - const u8 *rx_mic, const u8 *tx_mic, u8 mode, u8 cipher_mode, - u8 index) +int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len, + const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic, + u8 mode, u8 cipher_mode, u8 index) { int result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; u8 key_len = ptk_key_len; int i; @@ -3245,13 +3245,14 @@ int wilc_add_ptk(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -int wilc_add_rx_gtk(struct wilc_vif *vif, struct host_if_drv *hif_drv, - const u8 *rx_gtk, u8 gtk_key_len, u8 index, - u32 key_rsc_len, const u8 *key_rsc, const u8 *rx_mic, - const u8 *tx_mic, u8 mode, u8 cipher_mode) +int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len, + u8 index, u32 key_rsc_len, const u8 *key_rsc, + const u8 *rx_mic, const u8 *tx_mic, u8 mode, + u8 cipher_mode) { int result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; u8 key_len = gtk_key_len; if (!hif_drv) { @@ -3313,11 +3314,12 @@ int wilc_add_rx_gtk(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -s32 wilc_set_pmkid_info(struct wilc_vif *vif, struct host_if_drv *hif_drv, +s32 wilc_set_pmkid_info(struct wilc_vif *vif, struct host_if_pmkid_attr *pu8PmkidInfoArray) { s32 result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; u32 i; if (!hif_drv) { @@ -3347,11 +3349,11 @@ s32 wilc_set_pmkid_info(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -s32 wilc_get_mac_address(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u8 *pu8MacAddress) +s32 wilc_get_mac_address(struct wilc_vif *vif, u8 *pu8MacAddress) { s32 result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; memset(&msg, 0, sizeof(struct host_if_msg)); @@ -3370,11 +3372,11 @@ s32 wilc_get_mac_address(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -s32 wilc_set_mac_address(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u8 *pu8MacAddress) +s32 wilc_set_mac_address(struct wilc_vif *vif, u8 *pu8MacAddress) { s32 result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; PRINT_D(GENERIC_DBG, "mac addr = %x:%x:%x\n", pu8MacAddress[0], pu8MacAddress[1], pu8MacAddress[2]); @@ -3391,15 +3393,15 @@ s32 wilc_set_mac_address(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -s32 wilc_set_join_req(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u8 *pu8bssid, const u8 *pu8ssid, size_t ssidLen, - const u8 *pu8IEs, size_t IEsLen, +s32 wilc_set_join_req(struct wilc_vif *vif, u8 *pu8bssid, const u8 *pu8ssid, + size_t ssidLen, const u8 *pu8IEs, size_t IEsLen, wilc_connect_result pfConnectResult, void *pvUserArg, u8 u8security, enum AUTHTYPE tenuAuth_type, u8 u8channel, void *pJoinParams) { s32 result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv || !pfConnectResult) { PRINT_ER("Driver is null\n"); @@ -3459,10 +3461,11 @@ s32 wilc_set_join_req(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -s32 wilc_flush_join_req(struct wilc_vif *vif, struct host_if_drv *hif_drv) +s32 wilc_flush_join_req(struct wilc_vif *vif) { s32 result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; if (!join_req) return -EFAULT; @@ -3485,11 +3488,11 @@ s32 wilc_flush_join_req(struct wilc_vif *vif, struct host_if_drv *hif_drv) return result; } -s32 wilc_disconnect(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u16 u16ReasonCode) +s32 wilc_disconnect(struct wilc_vif *vif, u16 u16ReasonCode) { s32 result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("Driver is null\n"); @@ -3542,11 +3545,11 @@ static s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv, return result; } -int wilc_set_mac_chnl_num(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u8 channel) +int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel) { int result; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("driver is null\n"); @@ -3606,11 +3609,11 @@ int wilc_set_wfi_drv_handler(struct wilc_vif *vif, struct host_if_drv *hif_drv) return result; } -int wilc_set_operation_mode(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u32 mode) +int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode) { int result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_SET_OPERATION_MODE; @@ -3627,11 +3630,12 @@ int wilc_set_operation_mode(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -s32 wilc_get_inactive_time(struct wilc_vif *vif, struct host_if_drv *hif_drv, - const u8 *mac, u32 *pu32InactiveTime) +s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac, + u32 *pu32InactiveTime) { s32 result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("driver is null\n"); @@ -3656,11 +3660,11 @@ s32 wilc_get_inactive_time(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -s32 wilc_get_rssi(struct wilc_vif *vif, struct host_if_drv *hif_drv, - s8 *ps8Rssi) +s32 wilc_get_rssi(struct wilc_vif *vif, s8 *ps8Rssi) { s32 result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_GET_RSSI; @@ -3685,11 +3689,11 @@ s32 wilc_get_rssi(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -s32 wilc_get_statistics(struct wilc_vif *vif, struct host_if_drv *hif_drv, - struct rf_info *pstrStatistics) +s32 wilc_get_statistics(struct wilc_vif *vif, struct rf_info *pstrStatistics) { s32 result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_GET_STATISTICS; @@ -3707,14 +3711,14 @@ s32 wilc_get_statistics(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -s32 wilc_scan(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u8 u8ScanSource, u8 u8ScanType, u8 *pu8ChnlFreqList, - u8 u8ChnlListLen, const u8 *pu8IEs, - size_t IEsLen, wilc_scan_result ScanResult, - void *pvUserArg, struct hidden_network *pstrHiddenNetwork) +s32 wilc_scan(struct wilc_vif *vif, u8 u8ScanSource, u8 u8ScanType, + u8 *pu8ChnlFreqList, u8 u8ChnlListLen, const u8 *pu8IEs, + size_t IEsLen, wilc_scan_result ScanResult, void *pvUserArg, + struct hidden_network *pstrHiddenNetwork) { s32 result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv || !ScanResult) { PRINT_ER("hif_drv or ScanResult = NULL\n"); @@ -3761,11 +3765,12 @@ s32 wilc_scan(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -s32 wilc_hif_set_cfg(struct wilc_vif *vif, struct host_if_drv *hif_drv, - struct cfg_param_val *pstrCfgParamVal) +s32 wilc_hif_set_cfg(struct wilc_vif *vif, + struct cfg_param_val *pstrCfgParamVal) { s32 result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("hif_drv NULL\n"); @@ -3919,10 +3924,11 @@ _fail_: return result; } -s32 wilc_deinit(struct wilc_vif *vif, struct host_if_drv *hif_drv) +s32 wilc_deinit(struct wilc_vif *vif) { s32 result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; int ret; if (!hif_drv) { @@ -4089,14 +4095,15 @@ void wilc_scan_complete_received(u8 *pu8Buffer, u32 u32Length) return; } -s32 wilc_remain_on_channel(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u32 u32SessionID, u32 u32duration, u16 chan, +s32 wilc_remain_on_channel(struct wilc_vif *vif, u32 u32SessionID, + u32 u32duration, u16 chan, wilc_remain_on_chan_expired RemainOnChanExpired, wilc_remain_on_chan_ready RemainOnChanReady, void *pvUserArg) { s32 result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("driver is null\n"); @@ -4122,11 +4129,11 @@ s32 wilc_remain_on_channel(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -s32 wilc_listen_state_expired(struct wilc_vif *vif, - struct host_if_drv *hif_drv, u32 u32SessionID) +s32 wilc_listen_state_expired(struct wilc_vif *vif, u32 u32SessionID) { s32 result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("driver is null\n"); @@ -4148,11 +4155,11 @@ s32 wilc_listen_state_expired(struct wilc_vif *vif, return result; } -s32 wilc_frame_register(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u16 u16FrameType, bool bReg) +s32 wilc_frame_register(struct wilc_vif *vif, u16 u16FrameType, bool bReg) { s32 result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("driver is null\n"); @@ -4189,14 +4196,13 @@ s32 wilc_frame_register(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -s32 wilc_add_beacon(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u32 u32Interval, - u32 u32DTIMPeriod, u32 u32HeadLen, u8 *pu8Head, - u32 u32TailLen, u8 *pu8Tail) +s32 wilc_add_beacon(struct wilc_vif *vif, u32 u32Interval, u32 u32DTIMPeriod, + u32 u32HeadLen, u8 *pu8Head, u32 u32TailLen, u8 *pu8Tail) { s32 result = 0; struct host_if_msg msg; struct beacon_attr *pstrSetBeaconParam = &msg.body.beacon_info; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("driver is null\n"); @@ -4245,10 +4251,11 @@ ERRORHANDLER: return result; } -int wilc_del_beacon(struct wilc_vif *vif, struct host_if_drv *hif_drv) +int wilc_del_beacon(struct wilc_vif *vif) { int result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("driver is null\n"); @@ -4267,12 +4274,12 @@ int wilc_del_beacon(struct wilc_vif *vif, struct host_if_drv *hif_drv) return result; } -int wilc_add_station(struct wilc_vif *vif, struct host_if_drv *hif_drv, - struct add_sta_param *sta_param) +int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param) { int result = 0; struct host_if_msg msg; struct add_sta_param *add_sta_info = &msg.body.add_sta_info; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("driver is null\n"); @@ -4302,12 +4309,12 @@ int wilc_add_station(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -int wilc_del_station(struct wilc_vif *vif, struct host_if_drv *hif_drv, - const u8 *mac_addr) +int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr) { int result = 0; struct host_if_msg msg; struct del_sta *del_sta_info = &msg.body.del_sta_info; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("driver is null\n"); @@ -4333,12 +4340,12 @@ int wilc_del_station(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -s32 wilc_del_allstation(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u8 pu8MacAddr[][ETH_ALEN]) +s32 wilc_del_allstation(struct wilc_vif *vif, u8 pu8MacAddr[][ETH_ALEN]) { s32 result = 0; struct host_if_msg msg; struct del_all_sta *pstrDelAllStationMsg = &msg.body.del_all_sta_info; + struct host_if_drv *hif_drv = vif->hif_drv; u8 au8Zero_Buff[ETH_ALEN] = {0}; u32 i; u8 u8AssocNumb = 0; @@ -4385,12 +4392,13 @@ s32 wilc_del_allstation(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -s32 wilc_edit_station(struct wilc_vif *vif, struct host_if_drv *hif_drv, - struct add_sta_param *pstrStaParams) +s32 wilc_edit_station(struct wilc_vif *vif, + struct add_sta_param *pstrStaParams) { s32 result = 0; struct host_if_msg msg; struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("driver is null\n"); @@ -4424,12 +4432,12 @@ s32 wilc_edit_station(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -s32 wilc_set_power_mgmt(struct wilc_vif *vif, struct host_if_drv *hif_drv, - bool bIsEnabled, u32 u32Timeout) +s32 wilc_set_power_mgmt(struct wilc_vif *vif, bool bIsEnabled, u32 u32Timeout) { s32 result = 0; struct host_if_msg msg; struct power_mgmt_param *pstrPowerMgmtParam = &msg.body.pwr_mgmt_info; + struct host_if_drv *hif_drv = vif->hif_drv; PRINT_INFO(HOSTINF_DBG, "\n\n>> Setting PS to %d <<\n\n", bIsEnabled); @@ -4455,14 +4463,13 @@ s32 wilc_set_power_mgmt(struct wilc_vif *vif, struct host_if_drv *hif_drv, return result; } -s32 wilc_setup_multicast_filter(struct wilc_vif *vif, - struct host_if_drv *hif_drv, - bool bIsEnabled, +s32 wilc_setup_multicast_filter(struct wilc_vif *vif, bool bIsEnabled, u32 u32count) { s32 result = 0; struct host_if_msg msg; struct set_multicast *pstrMulticastFilterParam = &msg.body.multicast_info; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("driver is null\n"); @@ -4651,14 +4658,12 @@ void wilc_free_join_params(void *pJoinParams) PRINT_ER("Unable to FREE null pointer\n"); } -s32 wilc_del_all_rx_ba_session(struct wilc_vif *vif, - struct host_if_drv *hif_drv, - char *pBSSID, - char TID) +s32 wilc_del_all_rx_ba_session(struct wilc_vif *vif, char *pBSSID, char TID) { s32 result = 0; struct host_if_msg msg; struct ba_session_info *pBASessionInfo = &msg.body.session_info; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("driver is null\n"); @@ -4683,11 +4688,11 @@ s32 wilc_del_all_rx_ba_session(struct wilc_vif *vif, return result; } -s32 wilc_setup_ipaddress(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u8 *u16ipadd, u8 idx) +s32 wilc_setup_ipaddress(struct wilc_vif *vif, u8 *u16ipadd, u8 idx) { s32 result = 0; struct host_if_msg msg; + struct host_if_drv *hif_drv = vif->hif_drv; return 0; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index ccbbe73c7ee5d..9716bc859dca3 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -307,102 +307,73 @@ struct add_sta_param { struct wilc_vif; s32 wilc_remove_key(struct host_if_drv *hWFIDrv, const u8 *pu8StaAddress); -int wilc_remove_wep_key(struct wilc_vif *vif, - struct host_if_drv *hif_drv, u8 index); -int wilc_set_wep_default_keyid(struct wilc_vif *vif, - struct host_if_drv *hif_drv, u8 index); -int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, struct host_if_drv *hif_drv, - const u8 *key, u8 len, u8 index); -int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, struct host_if_drv *hif_drv, - const u8 *key, u8 len, u8 index, u8 mode, - enum AUTHTYPE auth_type); -s32 wilc_add_ptk(struct wilc_vif *vif, struct host_if_drv *hif_drv, - const u8 *pu8Ptk, u8 u8PtkKeylen, const u8 *mac_addr, - const u8 *pu8RxMic, const u8 *pu8TxMic, +int wilc_remove_wep_key(struct wilc_vif *vif, u8 index); +int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index); +int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len, + u8 index); +int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len, + u8 index, u8 mode, enum AUTHTYPE auth_type); +s32 wilc_add_ptk(struct wilc_vif *vif, const u8 *pu8Ptk, u8 u8PtkKeylen, + const u8 *mac_addr, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode, u8 u8Idx); -s32 wilc_get_inactive_time(struct wilc_vif *vif, struct host_if_drv *hif_drv, - const u8 *mac, u32 *pu32InactiveTime); -s32 wilc_add_rx_gtk(struct wilc_vif *vif, struct host_if_drv *hif_drv, - const u8 *pu8RxGtk, u8 u8GtkKeylen, u8 u8KeyIdx, - u32 u32KeyRSClen, const u8 *KeyRSC, - const u8 *pu8RxMic, const u8 *pu8TxMic, - u8 mode, u8 u8Ciphermode); +s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac, + u32 *pu32InactiveTime); +s32 wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *pu8RxGtk, u8 u8GtkKeylen, + u8 u8KeyIdx, u32 u32KeyRSClen, const u8 *KeyRSC, + const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, + u8 u8Ciphermode); s32 wilc_add_tx_gtk(struct host_if_drv *hWFIDrv, u8 u8KeyLen, u8 *pu8TxGtk, u8 u8KeyIdx); -s32 wilc_set_pmkid_info(struct wilc_vif *vif, struct host_if_drv *hif_drv, +s32 wilc_set_pmkid_info(struct wilc_vif *vif, struct host_if_pmkid_attr *pu8PmkidInfoArray); -s32 wilc_get_mac_address(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u8 *pu8MacAddress); -s32 wilc_set_mac_address(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u8 *pu8MacAddress); +s32 wilc_get_mac_address(struct wilc_vif *vif, u8 *pu8MacAddress); +s32 wilc_set_mac_address(struct wilc_vif *vif, u8 *pu8MacAddress); int wilc_wait_msg_queue_idle(void); s32 wilc_set_start_scan_req(struct host_if_drv *hWFIDrv, u8 scanSource); -s32 wilc_set_join_req(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u8 *pu8bssid, const u8 *pu8ssid, size_t ssidLen, - const u8 *pu8IEs, size_t IEsLen, +s32 wilc_set_join_req(struct wilc_vif *vif, u8 *pu8bssid, const u8 *pu8ssid, + size_t ssidLen, const u8 *pu8IEs, size_t IEsLen, wilc_connect_result pfConnectResult, void *pvUserArg, u8 u8security, enum AUTHTYPE tenuAuth_type, u8 u8channel, void *pJoinParams); -s32 wilc_flush_join_req(struct wilc_vif *vif, struct host_if_drv *hif_drv); -s32 wilc_disconnect(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u16 u16ReasonCode); -int wilc_set_mac_chnl_num(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u8 channel); -s32 wilc_get_rssi(struct wilc_vif *vif, struct host_if_drv *hif_drv, - s8 *ps8Rssi); -s32 wilc_scan(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u8 u8ScanSource, u8 u8ScanType, u8 *pu8ChnlFreqList, - u8 u8ChnlListLen, const u8 *pu8IEs, - size_t IEsLen, wilc_scan_result ScanResult, - void *pvUserArg, struct hidden_network *pstrHiddenNetwork); -s32 wilc_hif_set_cfg(struct wilc_vif *vif, struct host_if_drv *hif_drv, - struct cfg_param_val *pstrCfgParamVal); +s32 wilc_flush_join_req(struct wilc_vif *vif); +s32 wilc_disconnect(struct wilc_vif *vif, u16 u16ReasonCode); +int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel); +s32 wilc_get_rssi(struct wilc_vif *vif, s8 *ps8Rssi); +s32 wilc_scan(struct wilc_vif *vif, u8 u8ScanSource, u8 u8ScanType, + u8 *pu8ChnlFreqList, u8 u8ChnlListLen, const u8 *pu8IEs, + size_t IEsLen, wilc_scan_result ScanResult, void *pvUserArg, + struct hidden_network *pstrHiddenNetwork); +s32 wilc_hif_set_cfg(struct wilc_vif *vif, + struct cfg_param_val *pstrCfgParamVal); s32 wilc_init(struct net_device *dev, struct host_if_drv **phWFIDrv); -s32 wilc_deinit(struct wilc_vif *vif, struct host_if_drv *hif_drv); -s32 wilc_add_beacon(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u32 u32Interval, - u32 u32DTIMPeriod, u32 u32HeadLen, u8 *pu8Head, - u32 u32TailLen, u8 *pu8Tail); -int wilc_del_beacon(struct wilc_vif *vif, struct host_if_drv *hif_drv); -int wilc_add_station(struct wilc_vif *vif, struct host_if_drv *hif_drv, - struct add_sta_param *sta_param); -s32 wilc_del_allstation(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u8 pu8MacAddr[][ETH_ALEN]); -int wilc_del_station(struct wilc_vif *vif, struct host_if_drv *hif_drv, - const u8 *mac_addr); -s32 wilc_edit_station(struct wilc_vif *vif, struct host_if_drv *hif_drv, - struct add_sta_param *pstrStaParams); -s32 wilc_set_power_mgmt(struct wilc_vif *vif, struct host_if_drv *hif_drv, - bool bIsEnabled, u32 u32Timeout); -s32 wilc_setup_multicast_filter(struct wilc_vif *vif, - struct host_if_drv *hif_drv, - bool bIsEnabled, +s32 wilc_deinit(struct wilc_vif *vif); +s32 wilc_add_beacon(struct wilc_vif *vif, u32 u32Interval, u32 u32DTIMPeriod, + u32 u32HeadLen, u8 *pu8Head, u32 u32TailLen, u8 *pu8Tail); +int wilc_del_beacon(struct wilc_vif *vif); +int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param); +s32 wilc_del_allstation(struct wilc_vif *vif, u8 pu8MacAddr[][ETH_ALEN]); +int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr); +s32 wilc_edit_station(struct wilc_vif *vif, + struct add_sta_param *pstrStaParams); +s32 wilc_set_power_mgmt(struct wilc_vif *vif, bool bIsEnabled, u32 u32Timeout); +s32 wilc_setup_multicast_filter(struct wilc_vif *vif, bool bIsEnabled, u32 u32count); -s32 wilc_setup_ipaddress(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u8 *u16ipadd, u8 idx); -s32 wilc_del_all_rx_ba_session(struct wilc_vif *vif, - struct host_if_drv *hif_drv, - char *pBSSID, - char TID); -s32 wilc_remain_on_channel(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u32 u32SessionID, u32 u32duration, u16 chan, +s32 wilc_setup_ipaddress(struct wilc_vif *vif, u8 *u16ipadd, u8 idx); +s32 wilc_del_all_rx_ba_session(struct wilc_vif *vif, char *pBSSID, char TID); +s32 wilc_remain_on_channel(struct wilc_vif *vif, u32 u32SessionID, + u32 u32duration, u16 chan, wilc_remain_on_chan_expired RemainOnChanExpired, wilc_remain_on_chan_ready RemainOnChanReady, void *pvUserArg); -s32 wilc_listen_state_expired(struct wilc_vif *vif, - struct host_if_drv *hif_drv, u32 u32SessionID); -s32 wilc_frame_register(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u16 u16FrameType, bool bReg); +s32 wilc_listen_state_expired(struct wilc_vif *vif, u32 u32SessionID); +s32 wilc_frame_register(struct wilc_vif *vif, u16 u16FrameType, bool bReg); int wilc_set_wfi_drv_handler(struct wilc_vif *vif, struct host_if_drv *hif_drv); -int wilc_set_operation_mode(struct wilc_vif *vif, struct host_if_drv *hif_drv, - u32 mode); +int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode); void wilc_free_join_params(void *pJoinParams); -s32 wilc_get_statistics(struct wilc_vif *vif, struct host_if_drv *hif_drv, - struct rf_info *pstrStatistics); -void wilc_resolve_disconnect_aberration(struct wilc_vif *vif, - struct host_if_drv *hif_drv); +s32 wilc_get_statistics(struct wilc_vif *vif, struct rf_info *pstrStatistics); +void wilc_resolve_disconnect_aberration(struct wilc_vif *vif); extern bool wilc_optaining_ip; extern u8 wilc_connected_ssid[6]; diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 60749962ed5a6..a50e3ffcbb8d5 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -112,7 +112,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event } if (wilc_enable_ps) - wilc_set_power_mgmt(vif, hif_drv, 1, 0); + wilc_set_power_mgmt(vif, 1, 0); PRINT_D(GENERIC_DBG, "[%s] Up IP\n", dev_iface->ifa_label); @@ -120,7 +120,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n", ip_addr_buf[0], ip_addr_buf[1], ip_addr_buf[2], ip_addr_buf[3]); - wilc_setup_ipaddress(vif, hif_drv, ip_addr_buf, vif->u8IfIdx); + wilc_setup_ipaddress(vif, ip_addr_buf, vif->u8IfIdx); break; @@ -134,9 +134,9 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event } if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0) - wilc_set_power_mgmt(vif, hif_drv, 0, 0); + wilc_set_power_mgmt(vif, 0, 0); - wilc_resolve_disconnect_aberration(vif, hif_drv); + wilc_resolve_disconnect_aberration(vif); PRINT_D(GENERIC_DBG, "[%s] Down IP\n", dev_iface->ifa_label); @@ -145,7 +145,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event ip_addr_buf[0], ip_addr_buf[1], ip_addr_buf[2], ip_addr_buf[3]); - wilc_setup_ipaddress(vif, hif_drv, ip_addr_buf, vif->u8IfIdx); + wilc_setup_ipaddress(vif, ip_addr_buf, vif->u8IfIdx); break; @@ -1030,7 +1030,7 @@ int wilc_mac_open(struct net_device *ndev) wilc_set_machw_change_vir_if(ndev, false); - wilc_get_mac_address(vif, priv->hWILCWFIDrv, mac_add); + wilc_get_mac_address(vif, mac_add); PRINT_D(INIT_DBG, "Mac address: %pM\n", mac_add); for (i = 0; i < wl->vif_num; i++) { @@ -1097,13 +1097,13 @@ static void wilc_set_multicast_list(struct net_device *dev) if ((dev->flags & IFF_ALLMULTI) || (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) { PRINT_D(INIT_DBG, "Disable multicast filter, retrive all multicast packets\n"); - wilc_setup_multicast_filter(vif, hif_drv, false, 0); + wilc_setup_multicast_filter(vif, false, 0); return; } if ((dev->mc.count) == 0) { PRINT_D(INIT_DBG, "Enable multicast filter, retrive directed packets only.\n"); - wilc_setup_multicast_filter(vif, hif_drv, true, 0); + wilc_setup_multicast_filter(vif, true, 0); return; } @@ -1119,7 +1119,7 @@ static void wilc_set_multicast_list(struct net_device *dev) i++; } - wilc_setup_multicast_filter(vif, hif_drv, true, (dev->mc.count)); + wilc_setup_multicast_filter(vif, true, (dev->mc.count)); return; } @@ -1291,7 +1291,7 @@ static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) if (strncasecmp(buff, "RSSI", length) == 0) { priv = wiphy_priv(vif->ndev->ieee80211_ptr->wiphy); - ret = wilc_get_rssi(vif, priv->hWILCWFIDrv, &rssi); + ret = wilc_get_rssi(vif, &rssi); if (ret) PRINT_ER("Failed to send get rssi param's message queue "); PRINT_INFO(GENERIC_DBG, "RSSI :%d\n", rssi); diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 309a0cc6446e7..da4c4adefeeda 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -604,7 +604,7 @@ static int set_channel(struct wiphy *wiphy, PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq); curr_channel = channelnum; - result = wilc_set_mac_chnl_num(vif, priv->hWILCWFIDrv, channelnum); + result = wilc_set_mac_chnl_num(vif, channelnum); if (result != 0) PRINT_ER("Error in setting channel %d\n", channelnum); @@ -660,16 +660,20 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) } } PRINT_D(CFG80211_DBG, "Trigger Scan Request\n"); - s32Error = wilc_scan(vif, priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN, - au8ScanChanList, request->n_channels, - (const u8 *)request->ie, request->ie_len, - CfgScanResult, (void *)priv, &strHiddenNetwork); + s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN, + au8ScanChanList, + request->n_channels, + (const u8 *)request->ie, + request->ie_len, CfgScanResult, + (void *)priv, &strHiddenNetwork); } else { PRINT_D(CFG80211_DBG, "Trigger Scan Request\n"); - s32Error = wilc_scan(vif, priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN, - au8ScanChanList, request->n_channels, - (const u8 *)request->ie, request->ie_len, - CfgScanResult, (void *)priv, NULL); + s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN, + au8ScanChanList, + request->n_channels, + (const u8 *)request->ie, + request->ie_len, CfgScanResult, + (void *)priv, NULL); } } else { PRINT_ER("Requested num of scanned channels is greater than the max, supported" @@ -792,8 +796,9 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, g_key_wep_params.key_idx = sme->key_idx; g_wep_keys_saved = true; - wilc_set_wep_default_keyid(vif, priv->hWILCWFIDrv, sme->key_idx); - wilc_add_wep_key_bss_sta(vif, priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx); + wilc_set_wep_default_keyid(vif, sme->key_idx); + wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len, + sme->key_idx); } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) { u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED; pcgroup_encrypt_val = "WEP104"; @@ -809,8 +814,9 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, g_key_wep_params.key_idx = sme->key_idx; g_wep_keys_saved = true; - wilc_set_wep_default_keyid(vif, priv->hWILCWFIDrv, sme->key_idx); - wilc_add_wep_key_bss_sta(vif, priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx); + wilc_set_wep_default_keyid(vif, sme->key_idx); + wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len, + sme->key_idx); } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) { if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) { u8security = ENCRYPT_ENABLED | WPA2 | TKIP; @@ -895,11 +901,12 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid); - s32Error = wilc_set_join_req(vif, priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid, - sme->ssid_len, sme->ie, sme->ie_len, - CfgConnectResult, (void *)priv, u8security, - tenuAuth_type, pstrNetworkInfo->u8channel, - pstrNetworkInfo->pJoinParams); + s32Error = wilc_set_join_req(vif, pstrNetworkInfo->au8bssid, sme->ssid, + sme->ssid_len, sme->ie, sme->ie_len, + CfgConnectResult, (void *)priv, + u8security, tenuAuth_type, + pstrNetworkInfo->u8channel, + pstrNetworkInfo->pJoinParams); if (s32Error != 0) { PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error); s32Error = -ENOENT; @@ -935,7 +942,7 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_co wilc_ie = false; pstrWFIDrv->p2p_timeout = 0; - s32Error = wilc_disconnect(vif, priv->hWILCWFIDrv, reason_code); + s32Error = wilc_disconnect(vif, reason_code); if (s32Error != 0) { PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error); s32Error = -EINVAL; @@ -995,7 +1002,9 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, else u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED; - wilc_add_wep_key_bss_ap(vif, priv->hWILCWFIDrv, params->key, params->key_len, key_index, u8mode, tenuAuth_type); + wilc_add_wep_key_bss_ap(vif, params->key, + params->key_len, key_index, + u8mode, tenuAuth_type); break; } if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) { @@ -1009,7 +1018,8 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, for (i = 0; i < params->key_len; i++) PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]); } - wilc_add_wep_key_bss_sta(vif, priv->hWILCWFIDrv, params->key, params->key_len, key_index); + wilc_add_wep_key_bss_sta(vif, params->key, + params->key_len, key_index); } break; @@ -1066,8 +1076,10 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, } - wilc_add_rx_gtk(vif, priv->hWILCWFIDrv, params->key, KeyLen, - key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode); + wilc_add_rx_gtk(vif, params->key, KeyLen, + key_index, params->seq_len, + params->seq, pu8RxMic, + pu8TxMic, AP_MODE, u8gmode); } else { PRINT_INFO(CFG80211_DBG, "STA Address: %x%x%x%x%x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4]); @@ -1110,8 +1122,9 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, priv->wilc_ptk[key_index]->key_len = params->key_len; priv->wilc_ptk[key_index]->seq_len = params->seq_len; - wilc_add_ptk(vif, priv->hWILCWFIDrv, params->key, KeyLen, mac_addr, - pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index); + wilc_add_ptk(vif, params->key, KeyLen, + mac_addr, pu8RxMic, pu8TxMic, + AP_MODE, u8pmode, key_index); } break; } @@ -1150,8 +1163,11 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, g_gtk_keys_saved = true; } - wilc_add_rx_gtk(vif, priv->hWILCWFIDrv, params->key, KeyLen, - key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode); + wilc_add_rx_gtk(vif, params->key, KeyLen, + key_index, params->seq_len, + params->seq, pu8RxMic, + pu8TxMic, STATION_MODE, + u8mode); } else { if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) { pu8RxMic = params->key + 24; @@ -1184,8 +1200,9 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, g_ptk_keys_saved = true; } - wilc_add_ptk(vif, priv->hWILCWFIDrv, params->key, KeyLen, mac_addr, - pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index); + wilc_add_ptk(vif, params->key, KeyLen, + mac_addr, pu8RxMic, pu8TxMic, + STATION_MODE, u8mode, key_index); PRINT_D(CFG80211_DBG, "Adding pairwise key\n"); if (INFO) { for (i = 0; i < params->key_len; i++) @@ -1261,7 +1278,7 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev, priv->WILC_WFI_wep_key_len[key_index] = 0; PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index); - wilc_remove_wep_key(vif, priv->hWILCWFIDrv, key_index); + wilc_remove_wep_key(vif, key_index); } else { PRINT_D(CFG80211_DBG, "Removing all installed keys\n"); wilc_remove_key(priv->hWILCWFIDrv, mac_addr); @@ -1320,7 +1337,7 @@ static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 ke PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index); if (key_index != priv->WILC_WFI_wep_default) { - wilc_set_wep_default_keyid(vif, priv->hWILCWFIDrv, key_index); + wilc_set_wep_default_keyid(vif, key_index); } return 0; @@ -1356,7 +1373,7 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME); - wilc_get_inactive_time(vif, priv->hWILCWFIDrv, mac, &(inactive_time)); + wilc_get_inactive_time(vif, mac, &inactive_time); sinfo->inactive_time = 1000 * inactive_time; PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time); } @@ -1364,7 +1381,7 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, if (vif->iftype == STATION_MODE) { struct rf_info strStatistics; - wilc_get_statistics(vif, priv->hWILCWFIDrv, &strStatistics); + wilc_get_statistics(vif, &strStatistics); sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) | BIT(NL80211_STA_INFO_RX_PACKETS) | @@ -1435,7 +1452,7 @@ static int set_wiphy_params(struct wiphy *wiphy, u32 changed) } PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n"); - s32Error = wilc_hif_set_cfg(vif, priv->hWILCWFIDrv, &pstrCfgParamVal); + s32Error = wilc_hif_set_cfg(vif, &pstrCfgParamVal); if (s32Error) PRINT_ER("Error in setting WIPHY PARAMS\n"); @@ -1479,7 +1496,7 @@ static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev, if (!s32Error) { PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n"); - s32Error = wilc_set_pmkid_info(vif, priv->hWILCWFIDrv, &priv->pmkid_list); + s32Error = wilc_set_pmkid_info(vif, &priv->pmkid_list); } return s32Error; } @@ -1789,13 +1806,11 @@ static int remain_on_channel(struct wiphy *wiphy, priv->strRemainOnChanParams.u32ListenDuration = duration; priv->strRemainOnChanParams.u32ListenSessionID++; - s32Error = wilc_remain_on_channel(vif, priv->hWILCWFIDrv - , priv->strRemainOnChanParams.u32ListenSessionID - , duration - , chan->hw_value - , WILC_WFI_RemainOnChannelExpired - , WILC_WFI_RemainOnChannelReady - , (void *)priv); + s32Error = wilc_remain_on_channel(vif, + priv->strRemainOnChanParams.u32ListenSessionID, + duration, chan->hw_value, + WILC_WFI_RemainOnChannelExpired, + WILC_WFI_RemainOnChannelReady, (void *)priv); return s32Error; } @@ -1813,7 +1828,7 @@ static int cancel_remain_on_channel(struct wiphy *wiphy, PRINT_D(CFG80211_DBG, "Cancel remain on channel\n"); - s32Error = wilc_listen_state_expired(vif, priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID); + s32Error = wilc_listen_state_expired(vif, priv->strRemainOnChanParams.u32ListenSessionID); return s32Error; } @@ -1861,7 +1876,7 @@ static int mgmt_tx(struct wiphy *wiphy, if (ieee80211_is_probe_resp(mgmt->frame_control)) { PRINT_D(GENERIC_DBG, "TX: Probe Response\n"); PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value); - wilc_set_mac_chnl_num(vif, priv->hWILCWFIDrv, chan->hw_value); + wilc_set_mac_chnl_num(vif, chan->hw_value); curr_channel = chan->hw_value; } else if (ieee80211_is_action(mgmt->frame_control)) { PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control); @@ -1871,7 +1886,8 @@ static int mgmt_tx(struct wiphy *wiphy, if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC || buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) { PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value); - wilc_set_mac_chnl_num(vif, priv->hWILCWFIDrv, chan->hw_value); + wilc_set_mac_chnl_num(vif, + chan->hw_value); curr_channel = chan->hw_value; } switch (buf[ACTION_SUBTYPE_ID]) { @@ -2017,7 +2033,7 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, PRINT_D(GENERIC_DBG, "Return since mac is closed\n"); return; } - wilc_frame_register(vif, priv->hWILCWFIDrv, frame_type, reg); + wilc_frame_register(vif, frame_type, reg); } static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev, @@ -2043,7 +2059,7 @@ static int dump_station(struct wiphy *wiphy, struct net_device *dev, sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); - wilc_get_rssi(vif, priv->hWILCWFIDrv, &(sinfo->signal)); + wilc_get_rssi(vif, &sinfo->signal); return 0; } @@ -2067,7 +2083,7 @@ static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, } if (wilc_enable_ps) - wilc_set_power_mgmt(vif, priv->hWILCWFIDrv, enabled, timeout); + wilc_set_power_mgmt(vif, enabled, timeout); return 0; @@ -2115,8 +2131,8 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, vif->iftype = STATION_MODE; if (wl->initialized) { - wilc_del_all_rx_ba_session(vif, priv->hWILCWFIDrv, - wl->vif[0]->bssid, TID); + wilc_del_all_rx_ba_session(vif, wl->vif[0]->bssid, + TID); wilc_wait_msg_queue_idle(); up(&wl->cfg_event); @@ -2127,20 +2143,19 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, vif->iftype = interface_type; wilc_set_wfi_drv_handler(vif, wl->vif[0]->hif_drv); - wilc_set_mac_address(vif, wl->vif[0]->hif_drv, - wl->vif[0]->src_addr); - wilc_set_operation_mode(vif, priv->hWILCWFIDrv, STATION_MODE); + wilc_set_mac_address(wl->vif[0], wl->vif[0]->src_addr); + wilc_set_operation_mode(vif, STATION_MODE); if (g_wep_keys_saved) { - wilc_set_wep_default_keyid(vif, wl->vif[0]->hif_drv, - g_key_wep_params.key_idx); - wilc_add_wep_key_bss_sta(vif, wl->vif[0]->hif_drv, - g_key_wep_params.key, - g_key_wep_params.key_len, - g_key_wep_params.key_idx); + wilc_set_wep_default_keyid(wl->vif[0], + g_key_wep_params.key_idx); + wilc_add_wep_key_bss_sta(wl->vif[0], + g_key_wep_params.key, + g_key_wep_params.key_len, + g_key_wep_params.key_idx); } - wilc_flush_join_req(vif, priv->hWILCWFIDrv); + wilc_flush_join_req(vif); if (g_ptk_keys_saved && g_gtk_keys_saved) { PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0], @@ -2168,25 +2183,24 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, for (i = 0; i < num_reg_frame; i++) { PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type, vif->g_struct_frame_reg[i].reg); - wilc_frame_register(vif, priv->hWILCWFIDrv, + wilc_frame_register(vif, vif->g_struct_frame_reg[i].frame_type, vif->g_struct_frame_reg[i].reg); } } wilc_enable_ps = true; - wilc_set_power_mgmt(vif, priv->hWILCWFIDrv, 1, 0); + wilc_set_power_mgmt(vif, 1, 0); } break; case NL80211_IFTYPE_P2P_CLIENT: wilc_enable_ps = false; - wilc_set_power_mgmt(vif, priv->hWILCWFIDrv, 0, 0); + wilc_set_power_mgmt(vif, 0, 0); wilc_connecting = 0; PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n"); - wilc_del_all_rx_ba_session(vif, priv->hWILCWFIDrv, - wl->vif[0]->bssid, TID); + wilc_del_all_rx_ba_session(vif, wl->vif[0]->bssid, TID); dev->ieee80211_ptr->iftype = type; priv->wdev->iftype = type; @@ -2204,20 +2218,19 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, wilc_initialized = 1; wilc_set_wfi_drv_handler(vif, wl->vif[0]->hif_drv); - wilc_set_mac_address(vif, wl->vif[0]->hif_drv, - wl->vif[0]->src_addr); - wilc_set_operation_mode(vif, priv->hWILCWFIDrv, STATION_MODE); + wilc_set_mac_address(wl->vif[0], wl->vif[0]->src_addr); + wilc_set_operation_mode(vif, STATION_MODE); if (g_wep_keys_saved) { - wilc_set_wep_default_keyid(vif, wl->vif[0]->hif_drv, - g_key_wep_params.key_idx); - wilc_add_wep_key_bss_sta(vif, wl->vif[0]->hif_drv, - g_key_wep_params.key, - g_key_wep_params.key_len, - g_key_wep_params.key_idx); + wilc_set_wep_default_keyid(wl->vif[0], + g_key_wep_params.key_idx); + wilc_add_wep_key_bss_sta(wl->vif[0], + g_key_wep_params.key, + g_key_wep_params.key_len, + g_key_wep_params.key_idx); } - wilc_flush_join_req(vif, priv->hWILCWFIDrv); + wilc_flush_join_req(vif); if (g_ptk_keys_saved && g_gtk_keys_saved) { PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0], @@ -2248,7 +2261,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, for (i = 0; i < num_reg_frame; i++) { PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type, vif->g_struct_frame_reg[i].reg); - wilc_frame_register(vif, priv->hWILCWFIDrv, + wilc_frame_register(vif, vif->g_struct_frame_reg[i].frame_type, vif->g_struct_frame_reg[i].reg); } @@ -2275,7 +2288,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, for (i = 0; i < num_reg_frame; i++) { PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type, vif->g_struct_frame_reg[i].reg); - wilc_frame_register(vif, priv->hWILCWFIDrv, + wilc_frame_register(vif, vif->g_struct_frame_reg[i].frame_type, vif->g_struct_frame_reg[i].reg); } @@ -2288,9 +2301,8 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, wilc_optaining_ip = true; mod_timer(&wilc_during_ip_timer, jiffies + msecs_to_jiffies(during_ip_time)); - wilc_set_power_mgmt(vif, priv->hWILCWFIDrv, 0, 0); - wilc_del_all_rx_ba_session(vif, priv->hWILCWFIDrv, - wl->vif[0]->bssid, TID); + wilc_set_power_mgmt(vif, 0, 0); + wilc_del_all_rx_ba_session(vif, wl->vif[0]->bssid, TID); wilc_enable_ps = false; PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n"); dev->ieee80211_ptr->iftype = type; @@ -2309,20 +2321,19 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, wilc_initialized = 1; wilc_set_wfi_drv_handler(vif, wl->vif[0]->hif_drv); - wilc_set_mac_address(vif, wl->vif[0]->hif_drv, - wl->vif[0]->src_addr); - wilc_set_operation_mode(vif, priv->hWILCWFIDrv, AP_MODE); + wilc_set_mac_address(wl->vif[0], wl->vif[0]->src_addr); + wilc_set_operation_mode(vif, AP_MODE); if (g_wep_keys_saved) { - wilc_set_wep_default_keyid(vif, wl->vif[0]->hif_drv, + wilc_set_wep_default_keyid(wl->vif[0], g_key_wep_params.key_idx); - wilc_add_wep_key_bss_sta(vif, wl->vif[0]->hif_drv, - g_key_wep_params.key, - g_key_wep_params.key_len, - g_key_wep_params.key_idx); + wilc_add_wep_key_bss_sta(wl->vif[0], + g_key_wep_params.key, + g_key_wep_params.key_len, + g_key_wep_params.key_idx); } - wilc_flush_join_req(vif, priv->hWILCWFIDrv); + wilc_flush_join_req(vif); if (g_ptk_keys_saved && g_gtk_keys_saved) { PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0], @@ -2352,7 +2363,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, for (i = 0; i < num_reg_frame; i++) { PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type, vif->g_struct_frame_reg[i].reg); - wilc_frame_register(vif, priv->hWILCWFIDrv, + wilc_frame_register(vif, vif->g_struct_frame_reg[i].frame_type, vif->g_struct_frame_reg[i].reg); } @@ -2391,11 +2402,10 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev, wilc_wlan_set_bssid(dev, wl->vif[0]->src_addr); - s32Error = wilc_add_beacon(vif, priv->hWILCWFIDrv, - settings->beacon_interval, - settings->dtim_period, - beacon->head_len, (u8 *)beacon->head, - beacon->tail_len, (u8 *)beacon->tail); + s32Error = wilc_add_beacon(vif, settings->beacon_interval, + settings->dtim_period, beacon->head_len, + (u8 *)beacon->head, beacon->tail_len, + (u8 *)beacon->tail); return s32Error; } @@ -2412,11 +2422,9 @@ static int change_beacon(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "Setting beacon\n"); - s32Error = wilc_add_beacon(vif, priv->hWILCWFIDrv, - 0, - 0, - beacon->head_len, (u8 *)beacon->head, - beacon->tail_len, (u8 *)beacon->tail); + s32Error = wilc_add_beacon(vif, 0, 0, beacon->head_len, + (u8 *)beacon->head, beacon->tail_len, + (u8 *)beacon->tail); return s32Error; } @@ -2438,7 +2446,7 @@ static int stop_ap(struct wiphy *wiphy, struct net_device *dev) wilc_wlan_set_bssid(dev, NullBssid); - s32Error = wilc_del_beacon(vif, priv->hWILCWFIDrv); + s32Error = wilc_del_beacon(vif); if (s32Error) PRINT_ER("Host delete beacon fail\n"); @@ -2509,8 +2517,7 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.flags_set); - s32Error = wilc_add_station(vif, priv->hWILCWFIDrv, - &strStaParams); + s32Error = wilc_add_station(vif, &strStaParams); if (s32Error) PRINT_ER("Host add station fail\n"); } @@ -2538,12 +2545,13 @@ static int del_station(struct wiphy *wiphy, struct net_device *dev, if (!mac) { PRINT_D(HOSTAPD_DBG, "All associated stations\n"); - s32Error = wilc_del_allstation(vif, priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss); + s32Error = wilc_del_allstation(vif, + priv->assoc_stainfo.au8Sta_AssociatedBss); } else { PRINT_D(HOSTAPD_DBG, "With mac address: %x%x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } - s32Error = wilc_del_station(vif, priv->hWILCWFIDrv, mac); + s32Error = wilc_del_station(vif, mac); if (s32Error) PRINT_ER("Host delete station fail\n"); @@ -2616,8 +2624,7 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.flags_set); - s32Error = wilc_edit_station(vif, priv->hWILCWFIDrv, - &strStaParams); + s32Error = wilc_edit_station(vif, &strStaParams); if (s32Error) PRINT_ER("Host edit station fail\n"); } @@ -2862,7 +2869,7 @@ int wilc_deinit_host_int(struct net_device *net) op_ifcs--; - s32Error = wilc_deinit(vif, priv->hWILCWFIDrv); + s32Error = wilc_deinit(vif); clear_shadow_scan(); if (op_ifcs == 0) { -- GitLab From 71130e812af74afbf22b4308c517c8b6f3adacf2 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:41 +0900 Subject: [PATCH 1795/2855] staging: wilc1000: take vif instead of drv in hostIFthread In the first patch, we sent vif to hostIFthread. we can use vif instead of drv in the all functions which handle the commands from cfg operations. Change first argument host_if_drv with wilc_vif and use hif_drv of wilc_vif. Pass vif to the functions as well. In case of timer callback functions, set vif to the data and use vif instead of hif_drv. Lastly, initialize u32RcvdAssocRespInfoLen since changing hif_drv with vif causes one uninitialied build warning. Now we have vif that currently being used so we can use interface index of wilc_vif to send to wilc device. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 238 ++++++++++++---------- 1 file changed, 135 insertions(+), 103 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 421ce0de80f47..007b9a0f95fcc 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -316,11 +316,12 @@ static struct host_if_drv *get_handler_from_id(int id) return wfidrv_list[id]; } -static s32 handle_set_channel(struct host_if_drv *hif_drv, +static s32 handle_set_channel(struct wilc_vif *vif, struct channel_attr *hif_set_ch) { s32 result = 0; struct wid wid; + struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_CURRENT_CHANNEL; wid.type = WID_CHAR; @@ -340,11 +341,12 @@ static s32 handle_set_channel(struct host_if_drv *hif_drv, return result; } -static s32 handle_set_wfi_drv_handler(struct host_if_drv *hif_drv, +static s32 handle_set_wfi_drv_handler(struct wilc_vif *vif, struct drv_handler *hif_drv_handler) { s32 result = 0; struct wid wid; + struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_SET_DRV_HANDLER; wid.type = WID_INT; @@ -365,11 +367,12 @@ static s32 handle_set_wfi_drv_handler(struct host_if_drv *hif_drv, return result; } -static s32 handle_set_operation_mode(struct host_if_drv *hif_drv, +static s32 handle_set_operation_mode(struct wilc_vif *vif, struct op_mode *hif_op_mode) { s32 result = 0; struct wid wid; + struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_SET_OPERATION_MODE; wid.type = WID_INT; @@ -394,13 +397,12 @@ static s32 host_int_get_ipaddress(struct wilc_vif *vif, struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx); -static s32 handle_set_ip_address(struct wilc_vif *vif, - struct host_if_drv *hif_drv, u8 *ip_addr, - u8 idx) +static s32 handle_set_ip_address(struct wilc_vif *vif, u8 *ip_addr, u8 idx) { s32 result = 0; struct wid wid; char firmware_ip_addr[4] = {0}; + struct host_if_drv *hif_drv = vif->hif_drv; if (ip_addr[0] < 192) ip_addr[0] = 0; @@ -430,11 +432,11 @@ static s32 handle_set_ip_address(struct wilc_vif *vif, return result; } -static s32 handle_get_ip_address(struct wilc_vif *vif, - struct host_if_drv *hif_drv, u8 idx) +static s32 handle_get_ip_address(struct wilc_vif *vif, u8 idx) { s32 result = 0; struct wid wid; + struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_IP_ADDRESS; wid.type = WID_STR; @@ -465,11 +467,12 @@ static s32 handle_get_ip_address(struct wilc_vif *vif, return result; } -static s32 handle_set_mac_address(struct host_if_drv *hif_drv, +static s32 handle_set_mac_address(struct wilc_vif *vif, struct set_mac_addr *set_mac_addr) { s32 result = 0; struct wid wid; + struct host_if_drv *hif_drv = vif->hif_drv; u8 *mac_buf = kmalloc(ETH_ALEN, GFP_KERNEL); if (!mac_buf) { @@ -495,11 +498,12 @@ static s32 handle_set_mac_address(struct host_if_drv *hif_drv, return result; } -static s32 handle_get_mac_address(struct host_if_drv *hif_drv, +static s32 handle_get_mac_address(struct wilc_vif *vif, struct get_mac_addr *get_mac_addr) { s32 result = 0; struct wid wid; + struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_MAC_ADDR; wid.type = WID_STR; @@ -518,11 +522,12 @@ static s32 handle_get_mac_address(struct host_if_drv *hif_drv, return result; } -static s32 handle_cfg_param(struct host_if_drv *hif_drv, +static s32 handle_cfg_param(struct wilc_vif *vif, struct cfg_param_attr *cfg_param_attr) { s32 result = 0; struct wid wid_list[32]; + struct host_if_drv *hif_drv = vif->hif_drv; u8 wid_cnt = 0; down(&hif_drv->sem_cfg_values); @@ -818,10 +823,10 @@ static void Handle_wait_msg_q_empty(void) up(&hif_sema_wait_response); } -static s32 Handle_ScanDone(struct host_if_drv *hif_drv, +static s32 Handle_ScanDone(struct wilc_vif *vif, enum scan_event enuEvent); -static s32 Handle_Scan(struct host_if_drv *hif_drv, +static s32 Handle_Scan(struct wilc_vif *vif, struct scan_attr *pstrHostIFscanAttr) { s32 result = 0; @@ -831,6 +836,7 @@ static s32 Handle_Scan(struct host_if_drv *hif_drv, u8 *pu8Buffer; u8 valuesize = 0; u8 *pu8HdnNtwrksWidVal = NULL; + struct host_if_drv *hif_drv = vif->hif_drv; PRINT_D(HOSTINF_DBG, "Setting SCAN params\n"); PRINT_D(HOSTINF_DBG, "Scanning: In [%d] state\n", hif_drv->hif_state); @@ -936,7 +942,7 @@ static s32 Handle_Scan(struct host_if_drv *hif_drv, ERRORHANDLER: if (result) { del_timer(&hif_drv->scan_timer); - Handle_ScanDone(hif_drv, SCAN_EVENT_ABORTED); + Handle_ScanDone(vif, SCAN_EVENT_ABORTED); } kfree(pstrHostIFscanAttr->ch_freq_list); @@ -952,12 +958,13 @@ ERRORHANDLER: return result; } -static s32 Handle_ScanDone(struct host_if_drv *hif_drv, +static s32 Handle_ScanDone(struct wilc_vif *vif, enum scan_event enuEvent) { s32 result = 0; u8 u8abort_running_scan; struct wid wid; + struct host_if_drv *hif_drv = vif->hif_drv; PRINT_D(HOSTINF_DBG, "in Handle_ScanDone()\n"); @@ -993,7 +1000,7 @@ static s32 Handle_ScanDone(struct host_if_drv *hif_drv, } u8 wilc_connected_ssid[6] = {0}; -static s32 Handle_Connect(struct host_if_drv *hif_drv, +static s32 Handle_Connect(struct wilc_vif *vif, struct connect_attr *pstrHostIFconnectAttr) { s32 result = 0; @@ -1001,6 +1008,7 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv, u32 u32WidsCount = 0, dummyval = 0; u8 *pu8CurrByte = NULL; struct join_bss_param *ptstrJoinBssParam; + struct host_if_drv *hif_drv = vif->hif_drv; PRINT_D(GENERIC_DBG, "Handling connect request\n"); @@ -1286,12 +1294,13 @@ ERRORHANDLER: return result; } -static s32 Handle_FlushConnect(struct host_if_drv *hif_drv) +static s32 Handle_FlushConnect(struct wilc_vif *vif) { s32 result = 0; struct wid strWIDList[5]; u32 u32WidsCount = 0; u8 *pu8CurrByte = NULL; + struct host_if_drv *hif_drv = vif->hif_drv; strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE; strWIDList[u32WidsCount].type = WID_BIN_DATA; @@ -1333,12 +1342,13 @@ static s32 Handle_FlushConnect(struct host_if_drv *hif_drv) return result; } -static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv) +static s32 Handle_ConnectTimeout(struct wilc_vif *vif) { s32 result = 0; tstrConnectInfo strConnectInfo; struct wid wid; u16 u16DummyReasonCode = 0; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("Driver handler is NULL\n"); @@ -1413,7 +1423,7 @@ static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv) return result; } -static s32 Handle_RcvdNtwrkInfo(struct host_if_drv *hif_drv, +static s32 Handle_RcvdNtwrkInfo(struct wilc_vif *vif, struct rcvd_net_info *pstrRcvdNetworkInfo) { u32 i; @@ -1421,6 +1431,7 @@ static s32 Handle_RcvdNtwrkInfo(struct host_if_drv *hif_drv, s32 result = 0; tstrNetworkInfo *pstrNetworkInfo = NULL; void *pJoinParams = NULL; + struct host_if_drv *hif_drv = vif->hif_drv; bNewNtwrkFound = true; PRINT_INFO(HOSTINF_DBG, "Handling received network info\n"); @@ -1494,13 +1505,12 @@ done: return result; } -static s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv, +static s32 host_int_get_assoc_res_info(struct wilc_vif *vif, u8 *pu8AssocRespInfo, u32 u32MaxAssocRespInfoLen, u32 *pu32RcvdAssocRespInfoLen); static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif, - struct host_if_drv *hif_drv, struct rcvd_async_info *pstrRcvdGnrlAsyncInfo) { s32 result = 0; @@ -1515,6 +1525,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif, tstrConnectInfo strConnectInfo; tstrDisconnectNotifInfo strDisconnectNotifInfo; s32 s32Err = 0; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("Driver handler is NULL\n"); @@ -1548,7 +1559,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif, u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->buffer[9]; PRINT_INFO(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Info = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo); if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) { - u32 u32RcvdAssocRespInfoLen; + u32 u32RcvdAssocRespInfoLen = 0; tstrConnectRespInfo *pstrConnectRespInfo = NULL; PRINT_D(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Code = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo); @@ -1558,7 +1569,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif, if (u8MacStatus == MAC_CONNECTED) { memset(rcv_assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE); - host_int_get_assoc_res_info(hif_drv, + host_int_get_assoc_res_info(vif, rcv_assoc_resp, MAX_ASSOC_RESP_FRAME_SIZE, &u32RcvdAssocRespInfoLen); @@ -1666,7 +1677,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif, if (hif_drv->usr_scan_req.scan_result) { PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running OBSS Scan >>\n\n"); del_timer(&hif_drv->scan_timer); - Handle_ScanDone((void *)hif_drv, SCAN_EVENT_ABORTED); + Handle_ScanDone(vif, SCAN_EVENT_ABORTED); } strDisconnectNotifInfo.u16reason = 0; @@ -1717,7 +1728,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif, del_timer(&hif_drv->scan_timer); if (hif_drv->usr_scan_req.scan_result) - Handle_ScanDone(hif_drv, SCAN_EVENT_ABORTED); + Handle_ScanDone(vif, SCAN_EVENT_ABORTED); } } @@ -1727,7 +1738,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif, return result; } -static int Handle_Key(struct host_if_drv *hif_drv, +static int Handle_Key(struct wilc_vif *vif, struct key_attr *pstrHostIFkeyAttr) { s32 result = 0; @@ -1737,6 +1748,7 @@ static int Handle_Key(struct host_if_drv *hif_drv, u8 *pu8keybuf; s8 s8idxarray[1]; s8 ret = 0; + struct host_if_drv *hif_drv = vif->hif_drv; switch (pstrHostIFkeyAttr->type) { case WEP: @@ -2000,10 +2012,10 @@ _WPAPtk_end_case_: return result; } -static void Handle_Disconnect(struct wilc_vif *vif, - struct host_if_drv *hif_drv) +static void Handle_Disconnect(struct wilc_vif *vif) { struct wid wid; + struct host_if_drv *hif_drv = vif->hif_drv; s32 result = 0; u16 u16DummyReasonCode = 0; @@ -2098,10 +2110,11 @@ void wilc_resolve_disconnect_aberration(struct wilc_vif *vif) } } -static s32 Handle_GetChnl(struct host_if_drv *hif_drv) +static s32 Handle_GetChnl(struct wilc_vif *vif) { s32 result = 0; struct wid wid; + struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_CURRENT_CHANNEL; wid.type = WID_CHAR; @@ -2123,7 +2136,7 @@ static s32 Handle_GetChnl(struct host_if_drv *hif_drv) return result; } -static void Handle_GetRssi(struct host_if_drv *hif_drv) +static void Handle_GetRssi(struct wilc_vif *vif) { s32 result = 0; struct wid wid; @@ -2135,20 +2148,21 @@ static void Handle_GetRssi(struct host_if_drv *hif_drv) PRINT_D(HOSTINF_DBG, "Getting RSSI value\n"); - result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + result = wilc_send_config_pkt(vif->hif_drv->wilc, GET_CFG, &wid, 1, + get_id_from_handler(vif->hif_drv)); if (result) { PRINT_ER("Failed to get RSSI value\n"); result = -EFAULT; } - up(&hif_drv->sem_get_rssi); + up(&vif->hif_drv->sem_get_rssi); } -static void Handle_GetLinkspeed(struct host_if_drv *hif_drv) +static void Handle_GetLinkspeed(struct wilc_vif *vif) { s32 result = 0; struct wid wid; + struct host_if_drv *hif_drv = vif->hif_drv; link_speed = 0; @@ -2169,10 +2183,12 @@ static void Handle_GetLinkspeed(struct host_if_drv *hif_drv) up(&hif_drv->sem_get_link_speed); } -static s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics) +static s32 Handle_GetStatistics(struct wilc_vif *vif, + struct rf_info *pstrStatistics) { struct wid strWIDList[5]; u32 u32WidsCount = 0, result = 0; + struct host_if_drv *hif_drv = vif->hif_drv; strWIDList[u32WidsCount].id = WID_LINKSPEED; strWIDList[u32WidsCount].type = WID_CHAR; @@ -2215,12 +2231,13 @@ static s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pst return 0; } -static s32 Handle_Get_InActiveTime(struct host_if_drv *hif_drv, +static s32 Handle_Get_InActiveTime(struct wilc_vif *vif, struct sta_inactive_t *strHostIfStaInactiveT) { s32 result = 0; u8 *stamac; struct wid wid; + struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_SET_STA_MAC_INACTIVE_TIME; wid.type = WID_STR; @@ -2260,12 +2277,13 @@ static s32 Handle_Get_InActiveTime(struct host_if_drv *hif_drv, return result; } -static void Handle_AddBeacon(struct host_if_drv *hif_drv, +static void Handle_AddBeacon(struct wilc_vif *vif, struct beacon_attr *pstrSetBeaconParam) { s32 result = 0; struct wid wid; u8 *pu8CurrByte; + struct host_if_drv *hif_drv = vif->hif_drv; PRINT_D(HOSTINF_DBG, "Adding BEACON\n"); @@ -2315,11 +2333,12 @@ ERRORHANDLER: kfree(pstrSetBeaconParam->tail); } -static void Handle_DelBeacon(struct host_if_drv *hif_drv) +static void Handle_DelBeacon(struct wilc_vif *vif) { s32 result = 0; struct wid wid; u8 *pu8CurrByte; + struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_DEL_BEACON; wid.type = WID_CHAR; @@ -2387,12 +2406,13 @@ static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer, return pu8CurrByte - pu8Buffer; } -static void Handle_AddStation(struct host_if_drv *hif_drv, +static void Handle_AddStation(struct wilc_vif *vif, struct add_sta_param *pstrStationParam) { s32 result = 0; struct wid wid; u8 *pu8CurrByte; + struct host_if_drv *hif_drv = vif->hif_drv; PRINT_D(HOSTINF_DBG, "Handling add station\n"); wid.id = (u16)WID_ADD_STA; @@ -2416,7 +2436,7 @@ ERRORHANDLER: kfree(wid.val); } -static void Handle_DelAllSta(struct host_if_drv *hif_drv, +static void Handle_DelAllSta(struct wilc_vif *vif, struct del_all_sta *pstrDelAllStaParam) { s32 result = 0; @@ -2424,6 +2444,7 @@ static void Handle_DelAllSta(struct host_if_drv *hif_drv, u8 *pu8CurrByte; u8 i; u8 au8Zero_Buff[6] = {0}; + struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_DEL_ALL_STA; wid.type = WID_STR; @@ -2459,12 +2480,13 @@ ERRORHANDLER: up(&hif_sema_wait_response); } -static void Handle_DelStation(struct host_if_drv *hif_drv, +static void Handle_DelStation(struct wilc_vif *vif, struct del_sta *pstrDelStaParam) { s32 result = 0; struct wid wid; u8 *pu8CurrByte; + struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_REMOVE_STA; wid.type = WID_BIN; @@ -2489,12 +2511,13 @@ ERRORHANDLER: kfree(wid.val); } -static void Handle_EditStation(struct host_if_drv *hif_drv, +static void Handle_EditStation(struct wilc_vif *vif, struct add_sta_param *pstrStationParam) { s32 result = 0; struct wid wid; u8 *pu8CurrByte; + struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_EDIT_STA; wid.type = WID_BIN; @@ -2518,12 +2541,13 @@ ERRORHANDLER: kfree(wid.val); } -static int Handle_RemainOnChan(struct host_if_drv *hif_drv, +static int Handle_RemainOnChan(struct wilc_vif *vif, struct remain_ch *pstrHostIfRemainOnChan) { s32 result = 0; u8 u8remain_on_chan_flag; struct wid wid; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv->remain_on_ch_pending) { hif_drv->remain_on_ch.arg = pstrHostIfRemainOnChan->arg; @@ -2577,7 +2601,7 @@ static int Handle_RemainOnChan(struct host_if_drv *hif_drv, ERRORHANDLER: { P2P_LISTEN_STATE = 1; - hif_drv->remain_on_ch_timer.data = (unsigned long)hif_drv; + hif_drv->remain_on_ch_timer.data = (unsigned long)vif; mod_timer(&hif_drv->remain_on_ch_timer, jiffies + msecs_to_jiffies(pstrHostIfRemainOnChan->u32duration)); @@ -2592,12 +2616,13 @@ ERRORHANDLER: return result; } -static int Handle_RegisterFrame(struct host_if_drv *hif_drv, +static int Handle_RegisterFrame(struct wilc_vif *vif, struct reg_frame *pstrHostIfRegisterFrame) { s32 result = 0; struct wid wid; u8 *pu8CurrByte; + struct host_if_drv *hif_drv = vif->hif_drv; PRINT_D(HOSTINF_DBG, "Handling frame register : %d FrameType: %d\n", pstrHostIfRegisterFrame->reg, @@ -2627,12 +2652,13 @@ static int Handle_RegisterFrame(struct host_if_drv *hif_drv, return result; } -static u32 Handle_ListenStateExpired(struct host_if_drv *hif_drv, +static u32 Handle_ListenStateExpired(struct wilc_vif *vif, struct remain_ch *pstrHostIfRemainOnChan) { u8 u8remain_on_chan_flag; struct wid wid; s32 result = 0; + struct host_if_drv *hif_drv = vif->hif_drv; PRINT_D(HOSTINF_DBG, "CANCEL REMAIN ON CHAN\n"); @@ -2676,26 +2702,27 @@ static void ListenTimerCB(unsigned long arg) { s32 result = 0; struct host_if_msg msg; - struct host_if_drv *hif_drv = (struct host_if_drv *)arg; + struct wilc_vif *vif = (struct wilc_vif *)arg; - del_timer(&hif_drv->remain_on_ch_timer); + del_timer(&vif->hif_drv->remain_on_ch_timer); memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED; - msg.drv = hif_drv; - msg.body.remain_on_ch.id = hif_drv->remain_on_ch.id; + msg.vif = vif; + msg.body.remain_on_ch.id = vif->hif_drv->remain_on_ch.id; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) PRINT_ER("wilc_mq_send fail\n"); } -static void Handle_PowerManagement(struct host_if_drv *hif_drv, +static void Handle_PowerManagement(struct wilc_vif *vif, struct power_mgmt_param *strPowerMgmtParam) { s32 result = 0; struct wid wid; s8 s8PowerMode; + struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_POWER_MANAGEMENT; @@ -2715,12 +2742,13 @@ static void Handle_PowerManagement(struct host_if_drv *hif_drv, PRINT_ER("Failed to send power management config packet\n"); } -static void Handle_SetMulticastFilter(struct host_if_drv *hif_drv, +static void Handle_SetMulticastFilter(struct wilc_vif *vif, struct set_multicast *strHostIfSetMulti) { s32 result = 0; struct wid wid; u8 *pu8CurrByte; + struct host_if_drv *hif_drv = vif->hif_drv; PRINT_D(HOSTINF_DBG, "Setup Multicast Filter\n"); @@ -2755,12 +2783,13 @@ ERRORHANDLER: kfree(wid.val); } -static s32 Handle_DelAllRxBASessions(struct host_if_drv *hif_drv, +static s32 Handle_DelAllRxBASessions(struct wilc_vif *vif, struct ba_session_info *strHostIfBASessionInfo) { s32 result = 0; struct wid wid; char *ptr = NULL; + struct host_if_drv *hif_drv = vif->hif_drv; PRINT_D(GENERIC_DBG, "Delete Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\n", strHostIfBASessionInfo->bssid[0], @@ -2834,40 +2863,40 @@ static int hostIFthread(void *pvArg) break; case HOST_IF_MSG_SCAN: - Handle_Scan(msg.drv, &msg.body.scan_info); + Handle_Scan(msg.vif, &msg.body.scan_info); break; case HOST_IF_MSG_CONNECT: - Handle_Connect(msg.drv, &msg.body.con_info); + Handle_Connect(msg.vif, &msg.body.con_info); break; case HOST_IF_MSG_FLUSH_CONNECT: - Handle_FlushConnect(msg.drv); + Handle_FlushConnect(msg.vif); break; case HOST_IF_MSG_RCVD_NTWRK_INFO: - Handle_RcvdNtwrkInfo(msg.drv, &msg.body.net_info); + Handle_RcvdNtwrkInfo(msg.vif, &msg.body.net_info); break; case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO: - Handle_RcvdGnrlAsyncInfo(vif, msg.drv, + Handle_RcvdGnrlAsyncInfo(vif, &msg.body.async_info); break; case HOST_IF_MSG_KEY: - Handle_Key(msg.drv, &msg.body.key_info); + Handle_Key(msg.vif, &msg.body.key_info); break; case HOST_IF_MSG_CFG_PARAMS: - handle_cfg_param(msg.drv, &msg.body.cfg_info); + handle_cfg_param(msg.vif, &msg.body.cfg_info); break; case HOST_IF_MSG_SET_CHANNEL: - handle_set_channel(msg.drv, &msg.body.channel_info); + handle_set_channel(msg.vif, &msg.body.channel_info); break; case HOST_IF_MSG_DISCONNECT: - Handle_Disconnect(vif, msg.drv); + Handle_Disconnect(msg.vif); break; case HOST_IF_MSG_RCVD_SCAN_COMPLETE: @@ -2877,124 +2906,126 @@ static int hostIFthread(void *pvArg) if (!wilc_wlan_get_num_conn_ifcs(wilc)) wilc_chip_sleep_manually(wilc); - Handle_ScanDone(msg.drv, SCAN_EVENT_DONE); + Handle_ScanDone(msg.vif, SCAN_EVENT_DONE); if (hif_drv->remain_on_ch_pending) - Handle_RemainOnChan(msg.drv, &msg.body.remain_on_ch); + Handle_RemainOnChan(msg.vif, + &msg.body.remain_on_ch); break; case HOST_IF_MSG_GET_RSSI: - Handle_GetRssi(msg.drv); + Handle_GetRssi(msg.vif); break; case HOST_IF_MSG_GET_LINKSPEED: - Handle_GetLinkspeed(msg.drv); + Handle_GetLinkspeed(msg.vif); break; case HOST_IF_MSG_GET_STATISTICS: - Handle_GetStatistics(msg.drv, (struct rf_info *)msg.body.data); + Handle_GetStatistics(msg.vif, + (struct rf_info *)msg.body.data); break; case HOST_IF_MSG_GET_CHNL: - Handle_GetChnl(msg.drv); + Handle_GetChnl(msg.vif); break; case HOST_IF_MSG_ADD_BEACON: - Handle_AddBeacon(msg.drv, &msg.body.beacon_info); + Handle_AddBeacon(msg.vif, &msg.body.beacon_info); break; case HOST_IF_MSG_DEL_BEACON: - Handle_DelBeacon(msg.drv); + Handle_DelBeacon(msg.vif); break; case HOST_IF_MSG_ADD_STATION: - Handle_AddStation(msg.drv, &msg.body.add_sta_info); + Handle_AddStation(msg.vif, &msg.body.add_sta_info); break; case HOST_IF_MSG_DEL_STATION: - Handle_DelStation(msg.drv, &msg.body.del_sta_info); + Handle_DelStation(msg.vif, &msg.body.del_sta_info); break; case HOST_IF_MSG_EDIT_STATION: - Handle_EditStation(msg.drv, &msg.body.edit_sta_info); + Handle_EditStation(msg.vif, &msg.body.edit_sta_info); break; case HOST_IF_MSG_GET_INACTIVETIME: - Handle_Get_InActiveTime(msg.drv, &msg.body.mac_info); + Handle_Get_InActiveTime(msg.vif, &msg.body.mac_info); break; case HOST_IF_MSG_SCAN_TIMER_FIRED: PRINT_D(HOSTINF_DBG, "Scan Timeout\n"); - Handle_ScanDone(msg.drv, SCAN_EVENT_ABORTED); + Handle_ScanDone(msg.vif, SCAN_EVENT_ABORTED); break; case HOST_IF_MSG_CONNECT_TIMER_FIRED: PRINT_D(HOSTINF_DBG, "Connect Timeout\n"); - Handle_ConnectTimeout(msg.drv); + Handle_ConnectTimeout(msg.vif); break; case HOST_IF_MSG_POWER_MGMT: - Handle_PowerManagement(msg.drv, &msg.body.pwr_mgmt_info); + Handle_PowerManagement(msg.vif, + &msg.body.pwr_mgmt_info); break; case HOST_IF_MSG_SET_WFIDRV_HANDLER: - handle_set_wfi_drv_handler(msg.drv, &msg.body.drv); + handle_set_wfi_drv_handler(msg.vif, &msg.body.drv); break; case HOST_IF_MSG_SET_OPERATION_MODE: - handle_set_operation_mode(msg.drv, &msg.body.mode); + handle_set_operation_mode(msg.vif, &msg.body.mode); break; case HOST_IF_MSG_SET_IPADDRESS: PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n"); - handle_set_ip_address(vif, msg.drv, + handle_set_ip_address(vif, msg.body.ip_info.ip_addr, msg.body.ip_info.idx); break; case HOST_IF_MSG_GET_IPADDRESS: PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n"); - handle_get_ip_address(vif, msg.drv, - msg.body.ip_info.idx); + handle_get_ip_address(vif, msg.body.ip_info.idx); break; case HOST_IF_MSG_SET_MAC_ADDRESS: - handle_set_mac_address(msg.drv, + handle_set_mac_address(msg.vif, &msg.body.set_mac_info); break; case HOST_IF_MSG_GET_MAC_ADDRESS: - handle_get_mac_address(msg.drv, + handle_get_mac_address(msg.vif, &msg.body.get_mac_info); break; case HOST_IF_MSG_REMAIN_ON_CHAN: PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REMAIN_ON_CHAN\n"); - Handle_RemainOnChan(msg.drv, &msg.body.remain_on_ch); + Handle_RemainOnChan(msg.vif, &msg.body.remain_on_ch); break; case HOST_IF_MSG_REGISTER_FRAME: PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REGISTER_FRAME\n"); - Handle_RegisterFrame(msg.drv, &msg.body.reg_frame); + Handle_RegisterFrame(msg.vif, &msg.body.reg_frame); break; case HOST_IF_MSG_LISTEN_TIMER_FIRED: - Handle_ListenStateExpired(msg.drv, &msg.body.remain_on_ch); + Handle_ListenStateExpired(msg.vif, &msg.body.remain_on_ch); break; case HOST_IF_MSG_SET_MULTICAST_FILTER: PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_MULTICAST_FILTER\n"); - Handle_SetMulticastFilter(msg.drv, &msg.body.multicast_info); + Handle_SetMulticastFilter(msg.vif, &msg.body.multicast_info); break; case HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS: - Handle_DelAllRxBASessions(msg.drv, &msg.body.session_info); + Handle_DelAllRxBASessions(msg.vif, &msg.body.session_info); break; case HOST_IF_MSG_DEL_ALL_STA: - Handle_DelAllSta(msg.drv, &msg.body.del_all_sta_info); + Handle_DelAllSta(msg.vif, &msg.body.del_all_sta_info); break; default: @@ -3010,11 +3041,11 @@ static int hostIFthread(void *pvArg) static void TimerCB_Scan(unsigned long arg) { - void *pvArg = (void *)arg; + struct wilc_vif *vif = (struct wilc_vif *)arg; struct host_if_msg msg; memset(&msg, 0, sizeof(struct host_if_msg)); - msg.drv = pvArg; + msg.vif = vif; msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED; wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -3022,11 +3053,11 @@ static void TimerCB_Scan(unsigned long arg) static void TimerCB_Connect(unsigned long arg) { - void *pvArg = (void *)arg; + struct wilc_vif *vif = (struct wilc_vif *)arg; struct host_if_msg msg; memset(&msg, 0, sizeof(struct host_if_msg)); - msg.drv = pvArg; + msg.vif = vif; msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED; wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -3454,7 +3485,7 @@ s32 wilc_set_join_req(struct wilc_vif *vif, u8 *pu8bssid, const u8 *pu8ssid, return -EFAULT; } - hif_drv->connect_timer.data = (unsigned long)hif_drv; + hif_drv->connect_timer.data = (unsigned long)vif; mod_timer(&hif_drv->connect_timer, jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT)); @@ -3514,13 +3545,14 @@ s32 wilc_disconnect(struct wilc_vif *vif, u16 u16ReasonCode) return result; } -static s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv, +static s32 host_int_get_assoc_res_info(struct wilc_vif *vif, u8 *pu8AssocRespInfo, u32 u32MaxAssocRespInfoLen, u32 *pu32RcvdAssocRespInfoLen) { s32 result = 0; struct wid wid; + struct host_if_drv *hif_drv = vif->hif_drv; if (!hif_drv) { PRINT_ER("Driver is null\n"); @@ -3758,7 +3790,7 @@ s32 wilc_scan(struct wilc_vif *vif, u8 u8ScanSource, u8 u8ScanType, } PRINT_D(HOSTINF_DBG, ">> Starting the SCAN timer\n"); - hif_drv->scan_timer.data = (unsigned long)hif_drv; + hif_drv->scan_timer.data = (unsigned long)vif; mod_timer(&hif_drv->scan_timer, jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT)); @@ -3790,21 +3822,21 @@ s32 wilc_hif_set_cfg(struct wilc_vif *vif, static void GetPeriodicRSSI(unsigned long arg) { - struct host_if_drv *hif_drv = (struct host_if_drv *)arg; + struct wilc_vif *vif = (struct wilc_vif *)arg; - if (!hif_drv) { + if (!vif->hif_drv) { PRINT_ER("Driver handler is NULL\n"); return; } - if (hif_drv->hif_state == HOST_IF_CONNECTED) { + if (vif->hif_drv->hif_state == HOST_IF_CONNECTED) { s32 result = 0; struct host_if_msg msg; memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_GET_RSSI; - msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) { @@ -3812,7 +3844,7 @@ static void GetPeriodicRSSI(unsigned long arg) return; } } - periodic_rssi.data = (unsigned long)hif_drv; + periodic_rssi.data = (unsigned long)vif; mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000)); } @@ -3881,7 +3913,7 @@ s32 wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) goto _fail_mq_; } setup_timer(&periodic_rssi, GetPeriodicRSSI, - (unsigned long)hif_drv); + (unsigned long)vif); mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000)); } -- GitLab From cd04d221dd6c9ceb5732d2c22c9e3bb7f8830a6a Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:42 +0900 Subject: [PATCH 1796/2855] staging: wilc1000: pass struct wilc Pass struct wilc to the following functions. The functions need wilc to get proper vif using id from wilc device. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/coreconfigurator.h | 11 ++++++----- drivers/staging/wilc1000/host_interface.c | 9 ++++++--- drivers/staging/wilc1000/wilc_wlan.c | 2 +- drivers/staging/wilc1000/wilc_wlan_cfg.c | 9 +++++---- drivers/staging/wilc1000/wilc_wlan_cfg.h | 4 +++- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/staging/wilc1000/coreconfigurator.h b/drivers/staging/wilc1000/coreconfigurator.h index 3f2a7d3c3a174..fc43d04ca1dab 100644 --- a/drivers/staging/wilc1000/coreconfigurator.h +++ b/drivers/staging/wilc1000/coreconfigurator.h @@ -135,9 +135,10 @@ s32 wilc_dealloc_network_info(tstrNetworkInfo *pstrNetworkInfo); s32 wilc_parse_assoc_resp_info(u8 *pu8Buffer, u32 u32BufferLen, tstrConnectRespInfo **ppstrConnectRespInfo); s32 wilc_dealloc_assoc_resp_info(tstrConnectRespInfo *pstrConnectRespInfo); - -void wilc_network_info_received(u8 *pu8Buffer, u32 u32Length); -void wilc_gnrl_async_info_received(u8 *pu8Buffer, u32 u32Length); -void wilc_scan_complete_received(u8 *pu8Buffer, u32 u32Length); - +void wilc_scan_complete_received(struct wilc *wilc, u8 *pu8Buffer, + u32 u32Length); +void wilc_network_info_received(struct wilc *wilc, u8 *pu8Buffer, + u32 u32Length); +void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *pu8Buffer, + u32 u32Length); #endif diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 007b9a0f95fcc..123887cf8ec99 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -4028,7 +4028,8 @@ s32 wilc_deinit(struct wilc_vif *vif) return result; } -void wilc_network_info_received(u8 *pu8Buffer, u32 u32Length) +void wilc_network_info_received(struct wilc *wilc, u8 *pu8Buffer, + u32 u32Length) { s32 result = 0; struct host_if_msg msg; @@ -4057,7 +4058,8 @@ void wilc_network_info_received(u8 *pu8Buffer, u32 u32Length) PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n", result); } -void wilc_gnrl_async_info_received(u8 *pu8Buffer, u32 u32Length) +void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *pu8Buffer, + u32 u32Length) { s32 result = 0; struct host_if_msg msg; @@ -4098,7 +4100,8 @@ void wilc_gnrl_async_info_received(u8 *pu8Buffer, u32 u32Length) up(&hif_sema_deinit); } -void wilc_scan_complete_received(u8 *pu8Buffer, u32 u32Length) +void wilc_scan_complete_received(struct wilc *wilc, u8 *pu8Buffer, + u32 u32Length) { s32 result = 0; struct host_if_msg msg; diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 768a42c22dd4d..00f346454e004 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -988,7 +988,7 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) } else { struct wilc_cfg_rsp rsp; - wilc_wlan_cfg_indicate_rx(&buffer[pkt_offset + offset], pkt_len, &rsp); + wilc_wlan_cfg_indicate_rx(wilc, &buffer[pkt_offset + offset], pkt_len, &rsp); if (rsp.type == WILC_CFG_RSP) { PRINT_D(RX_DBG, "wilc->cfg_seq_no = %d - rsp.seq_no = %d\n", wilc->cfg_seq_no, rsp.seq_no); if (wilc->cfg_seq_no == rsp.seq_no) diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.c b/drivers/staging/wilc1000/wilc_wlan_cfg.c index f62c0e696a018..b72c77bb35f11 100644 --- a/drivers/staging/wilc1000/wilc_wlan_cfg.c +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.c @@ -495,7 +495,8 @@ int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size) return ret; } -int wilc_wlan_cfg_indicate_rx(u8 *frame, int size, struct wilc_cfg_rsp *rsp) +int wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size, + struct wilc_cfg_rsp *rsp) { int ret = 1; u8 msg_type; @@ -522,17 +523,17 @@ int wilc_wlan_cfg_indicate_rx(u8 *frame, int size, struct wilc_cfg_rsp *rsp) rsp->seq_no = msg_id; /*call host interface info parse as well*/ PRINT_INFO(RX_DBG, "Info message received\n"); - wilc_gnrl_async_info_received(frame - 4, size + 4); + wilc_gnrl_async_info_received(wilc, frame - 4, size + 4); break; case 'N': - wilc_network_info_received(frame - 4, size + 4); + wilc_network_info_received(wilc, frame - 4, size + 4); rsp->type = 0; break; case 'S': PRINT_INFO(RX_DBG, "Scan Notification Received\n"); - wilc_scan_complete_received(frame - 4, size + 4); + wilc_scan_complete_received(wilc, frame - 4, size + 4); break; default: diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.h b/drivers/staging/wilc1000/wilc_wlan_cfg.h index 443b2d5b6db85..5f74eb83562fa 100644 --- a/drivers/staging/wilc1000/wilc_wlan_cfg.h +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.h @@ -30,10 +30,12 @@ typedef struct { u8 *str; } wilc_cfg_str_t; +struct wilc; int wilc_wlan_cfg_set_wid(u8 *frame, u32 offset, u16 id, u8 *buf, int size); int wilc_wlan_cfg_get_wid(u8 *frame, u32 offset, u16 id); int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size); -int wilc_wlan_cfg_indicate_rx(u8 *frame, int size, struct wilc_cfg_rsp *rsp); +int wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size, + struct wilc_cfg_rsp *rsp); int wilc_wlan_cfg_init(wilc_debug_func func); #endif -- GitLab From eb9939b76007ab6dfa14f6664e6cf4deda9c56cd Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:43 +0900 Subject: [PATCH 1797/2855] staging: wilc1000: use vif index to communicate with wilc device We now have vif index in all functions related with host interface thread. wilc_get_vif_idx and wilc_get_vif_from_idx are added to get id and vif respectively. Relace get_id_from_handler with wilc_get_vif_idx and get_handler_from_id with wilc_get_vif_from_idx. Remove unused function get_handler_from_id as well. We get vif where wilc_get_vif_from_idx is called, so pass vif to msg.vif. There are two get_id_from_handler left. They will be removed in later patch. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 127 ++++++++++++++-------- 1 file changed, 81 insertions(+), 46 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 123887cf8ec99..0a9060c9c837e 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -309,11 +309,28 @@ static int get_id_from_handler(struct host_if_drv *handler) return 0; } -static struct host_if_drv *get_handler_from_id(int id) +/* The u8IfIdx starts from 0 to NUM_CONCURRENT_IFC -1, but 0 index used as + * special purpose in wilc device, so we add 1 to the index to starts from 1. + * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC. + */ +static int wilc_get_vif_idx(struct wilc_vif *vif) { - if (id <= 0 || id >= ARRAY_SIZE(wfidrv_list)) + return vif->u8IfIdx + 1; +} + +/* We need to minus 1 from idx which is from wilc device to get real index + * of wilc->vif[], because we add 1 when pass to wilc device in the function + * wilc_get_vif_idx. + * As a result, the index should be between 0 and NUM_CONCURRENT_IFC -1. + */ +static struct wilc_vif *wilc_get_vif_from_idx(struct wilc *wilc, int idx) +{ + int index = idx - 1; + + if (index < 0 || index >= NUM_CONCURRENT_IFC) return NULL; - return wfidrv_list[id]; + + return wilc->vif[index]; } static s32 handle_set_channel(struct wilc_vif *vif, @@ -331,7 +348,7 @@ static s32 handle_set_channel(struct wilc_vif *vif, PRINT_D(HOSTINF_DBG, "Setting channel\n"); result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) { PRINT_ER("Failed to set channel\n"); @@ -380,7 +397,7 @@ static s32 handle_set_operation_mode(struct wilc_vif *vif, wid.size = sizeof(u32); result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if ((hif_op_mode->mode) == IDLE_MODE) up(&hif_sema_driver); @@ -418,7 +435,7 @@ static s32 handle_set_ip_address(struct wilc_vif *vif, u8 *ip_addr, u8 idx) wid.size = IP_ALEN; result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); host_int_get_ipaddress(vif, hif_drv, firmware_ip_addr, idx); @@ -444,7 +461,7 @@ static s32 handle_get_ip_address(struct wilc_vif *vif, u8 idx) wid.size = IP_ALEN; result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); PRINT_INFO(HOSTINF_DBG, "%pI4\n", wid.val); @@ -488,7 +505,7 @@ static s32 handle_set_mac_address(struct wilc_vif *vif, PRINT_D(GENERIC_DBG, "mac addr = :%pM\n", wid.val); result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) { PRINT_ER("Failed to set mac address\n"); result = -EFAULT; @@ -511,7 +528,7 @@ static s32 handle_get_mac_address(struct wilc_vif *vif, wid.size = ETH_ALEN; result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) { PRINT_ER("Failed to get mac address\n"); @@ -807,7 +824,7 @@ static s32 handle_cfg_param(struct wilc_vif *vif, } result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, wid_list, - wid_cnt, get_id_from_handler(hif_drv)); + wid_cnt, wilc_get_vif_idx(vif)); if (result) PRINT_ER("Error in setting CFG params\n"); @@ -932,7 +949,7 @@ static s32 Handle_Scan(struct wilc_vif *vif, result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, strWIDList, u32WidsCount, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send scan paramters config packet\n"); @@ -977,7 +994,7 @@ static s32 Handle_ScanDone(struct wilc_vif *vif, wid.size = sizeof(char); result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) { PRINT_ER("Failed to set abort running scan\n"); @@ -1234,7 +1251,7 @@ static s32 Handle_Connect(struct wilc_vif *vif, result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, strWIDList, u32WidsCount, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) { PRINT_ER("failed to send config packet\n"); result = -EFAULT; @@ -1395,7 +1412,7 @@ static s32 Handle_ConnectTimeout(struct wilc_vif *vif) PRINT_D(HOSTINF_DBG, "Sending disconnect request\n"); result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send dissconect config packet\n"); @@ -1790,7 +1807,7 @@ static int Handle_Key(struct wilc_vif *vif, result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, strWIDList, 4, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); kfree(pu8keybuf); } else if (pstrHostIFkeyAttr->action & ADDKEY) { PRINT_D(HOSTINF_DBG, "Handling WEP key\n"); @@ -1812,7 +1829,7 @@ static int Handle_Key(struct wilc_vif *vif, result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); kfree(pu8keybuf); } else if (pstrHostIFkeyAttr->action & REMOVEKEY) { PRINT_D(HOSTINF_DBG, "Removing key\n"); @@ -1825,7 +1842,7 @@ static int Handle_Key(struct wilc_vif *vif, result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); } else { wid.id = (u16)WID_KEY_ID; wid.type = WID_CHAR; @@ -1836,7 +1853,7 @@ static int Handle_Key(struct wilc_vif *vif, result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); } up(&hif_drv->sem_test_key_block); break; @@ -1870,7 +1887,7 @@ static int Handle_Key(struct wilc_vif *vif, result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, strWIDList, 2, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); kfree(pu8keybuf); up(&hif_drv->sem_test_key_block); @@ -1902,7 +1919,7 @@ static int Handle_Key(struct wilc_vif *vif, result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); kfree(pu8keybuf); up(&hif_drv->sem_test_key_block); @@ -1942,7 +1959,7 @@ _WPARxGtk_end_case_: result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, strWIDList, 2, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); kfree(pu8keybuf); up(&hif_drv->sem_test_key_block); } else if (pstrHostIFkeyAttr->action & ADDKEY) { @@ -1965,7 +1982,7 @@ _WPARxGtk_end_case_: result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); kfree(pu8keybuf); up(&hif_drv->sem_test_key_block); } @@ -2000,7 +2017,7 @@ _WPAPtk_end_case_: wid.size = (pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1; result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); kfree(pu8keybuf); break; @@ -2033,7 +2050,7 @@ static void Handle_Disconnect(struct wilc_vif *vif) eth_zero_addr(wilc_connected_ssid); result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) { PRINT_ER("Failed to send dissconect config packet\n"); @@ -2124,7 +2141,7 @@ static s32 Handle_GetChnl(struct wilc_vif *vif) PRINT_D(HOSTINF_DBG, "Getting channel value\n"); result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) { PRINT_ER("Failed to get channel number\n"); @@ -2149,7 +2166,7 @@ static void Handle_GetRssi(struct wilc_vif *vif) PRINT_D(HOSTINF_DBG, "Getting RSSI value\n"); result = wilc_send_config_pkt(vif->hif_drv->wilc, GET_CFG, &wid, 1, - get_id_from_handler(vif->hif_drv)); + wilc_get_vif_idx(vif)); if (result) { PRINT_ER("Failed to get RSSI value\n"); result = -EFAULT; @@ -2174,7 +2191,7 @@ static void Handle_GetLinkspeed(struct wilc_vif *vif) PRINT_D(HOSTINF_DBG, "Getting LINKSPEED value\n"); result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) { PRINT_ER("Failed to get LINKSPEED value\n"); result = -EFAULT; @@ -2222,7 +2239,7 @@ static s32 Handle_GetStatistics(struct wilc_vif *vif, result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, strWIDList, u32WidsCount, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send scan paramters config packet\n"); @@ -2250,7 +2267,7 @@ static s32 Handle_Get_InActiveTime(struct wilc_vif *vif, PRINT_D(CFG80211_DBG, "SETING STA inactive time\n"); result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) { PRINT_ER("Failed to SET incative time\n"); @@ -2263,7 +2280,7 @@ static s32 Handle_Get_InActiveTime(struct wilc_vif *vif, wid.size = sizeof(u32); result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) { PRINT_ER("Failed to get incative time\n"); @@ -2323,7 +2340,7 @@ static void Handle_AddBeacon(struct wilc_vif *vif, pu8CurrByte += pstrSetBeaconParam->tail_len; result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send add beacon config packet\n"); @@ -2353,7 +2370,7 @@ static void Handle_DelBeacon(struct wilc_vif *vif) PRINT_D(HOSTINF_DBG, "Deleting BEACON\n"); result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send delete beacon config packet\n"); } @@ -2427,7 +2444,7 @@ static void Handle_AddStation(struct wilc_vif *vif, pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam); result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result != 0) PRINT_ER("Failed to send add station config packet\n"); @@ -2470,7 +2487,7 @@ static void Handle_DelAllSta(struct wilc_vif *vif, } result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send add station config packet\n"); @@ -2503,7 +2520,7 @@ static void Handle_DelStation(struct wilc_vif *vif, memcpy(pu8CurrByte, pstrDelStaParam->mac_addr, ETH_ALEN); result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send add station config packet\n"); @@ -2532,7 +2549,7 @@ static void Handle_EditStation(struct wilc_vif *vif, pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam); result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send edit station config packet\n"); @@ -2594,7 +2611,7 @@ static int Handle_RemainOnChan(struct wilc_vif *vif, wid.val[1] = (s8)pstrHostIfRemainOnChan->ch; result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result != 0) PRINT_ER("Failed to set remain on channel\n"); @@ -2643,7 +2660,7 @@ static int Handle_RegisterFrame(struct wilc_vif *vif, wid.size = sizeof(u16) + 2; result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) { PRINT_ER("Failed to frame register config packet\n"); result = -EINVAL; @@ -2678,7 +2695,7 @@ static u32 Handle_ListenStateExpired(struct wilc_vif *vif, wid.val[1] = FALSE_FRMWR_CHANNEL; result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result != 0) { PRINT_ER("Failed to set remain on channel\n"); goto _done_; @@ -2737,7 +2754,7 @@ static void Handle_PowerManagement(struct wilc_vif *vif, PRINT_D(HOSTINF_DBG, "Handling Power Management\n"); result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send power management config packet\n"); } @@ -2775,7 +2792,7 @@ static void Handle_SetMulticastFilter(struct wilc_vif *vif, ((strHostIfSetMulti->cnt) * ETH_ALEN)); result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send setup multicast config packet\n"); @@ -2812,7 +2829,7 @@ static s32 Handle_DelAllRxBASessions(struct wilc_vif *vif, *ptr++ = 32; result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n"); @@ -3565,7 +3582,7 @@ static s32 host_int_get_assoc_res_info(struct wilc_vif *vif, wid.size = u32MaxAssocRespInfoLen; result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, - get_id_from_handler(hif_drv)); + wilc_get_vif_idx(vif)); if (result) { *pu32RcvdAssocRespInfoLen = 0; PRINT_ER("Failed to send association response config packet\n"); @@ -4035,9 +4052,13 @@ void wilc_network_info_received(struct wilc *wilc, u8 *pu8Buffer, struct host_if_msg msg; int id; struct host_if_drv *hif_drv = NULL; + struct wilc_vif *vif; id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24)); - hif_drv = get_handler_from_id(id); + vif = wilc_get_vif_from_idx(wilc, id); + if (!vif) + return; + hif_drv = vif->hif_drv; if (!hif_drv || hif_drv == terminated_handle) { PRINT_ER("NetworkInfo received but driver not init[%p]\n", hif_drv); @@ -4048,6 +4069,7 @@ void wilc_network_info_received(struct wilc *wilc, u8 *pu8Buffer, msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO; msg.drv = hif_drv; + msg.vif = vif; msg.body.net_info.len = u32Length; msg.body.net_info.buffer = kmalloc(u32Length, GFP_KERNEL); @@ -4065,11 +4087,18 @@ void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *pu8Buffer, struct host_if_msg msg; int id; struct host_if_drv *hif_drv = NULL; + struct wilc_vif *vif; down(&hif_sema_deinit); id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24)); - hif_drv = get_handler_from_id(id); + vif = wilc_get_vif_from_idx(wilc, id); + if (!vif) { + up(&hif_sema_deinit); + return; + } + + hif_drv = vif->hif_drv; PRINT_D(HOSTINF_DBG, "General asynchronous info packet received\n"); if (!hif_drv || hif_drv == terminated_handle) { @@ -4088,6 +4117,7 @@ void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *pu8Buffer, msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO; msg.drv = hif_drv; + msg.vif = vif; msg.body.async_info.len = u32Length; msg.body.async_info.buffer = kmalloc(u32Length, GFP_KERNEL); @@ -4107,9 +4137,13 @@ void wilc_scan_complete_received(struct wilc *wilc, u8 *pu8Buffer, struct host_if_msg msg; int id; struct host_if_drv *hif_drv = NULL; + struct wilc_vif *vif; id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24)); - hif_drv = get_handler_from_id(id); + vif = wilc_get_vif_from_idx(wilc, id); + if (!vif) + return; + hif_drv = vif->hif_drv; PRINT_D(GENERIC_DBG, "Scan notification received %p\n", hif_drv); @@ -4121,6 +4155,7 @@ void wilc_scan_complete_received(struct wilc *wilc, u8 *pu8Buffer, msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE; msg.drv = hif_drv; + msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) -- GitLab From 31f0f697dddd739a0581ca373d53b648ba50c00b Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:44 +0900 Subject: [PATCH 1798/2855] staging: wilc1000: wilc_set_wfi_drv_handler: pass vif index Pass index of vif instead of hif_drv. wilc_get_vif_idx is used to get correct index of vif. In the handler function handle_set_wfi_drv_handler, use vif instead of hif_drv, and use hif_drv_handler->handler instead of hif_drv when deinitialize wilc device. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 14 ++++++-------- drivers/staging/wilc1000/host_interface.h | 3 ++- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 12 +++++++----- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 0a9060c9c837e..be88237f2352b 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -313,7 +313,7 @@ static int get_id_from_handler(struct host_if_drv *handler) * special purpose in wilc device, so we add 1 to the index to starts from 1. * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC. */ -static int wilc_get_vif_idx(struct wilc_vif *vif) +int wilc_get_vif_idx(struct wilc_vif *vif) { return vif->u8IfIdx + 1; } @@ -363,17 +363,16 @@ static s32 handle_set_wfi_drv_handler(struct wilc_vif *vif, { s32 result = 0; struct wid wid; - struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_SET_DRV_HANDLER; wid.type = WID_INT; wid.val = (s8 *)&hif_drv_handler->handler; wid.size = sizeof(u32); - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, hif_drv_handler->handler); - if (!hif_drv) + if (!hif_drv_handler->handler) up(&hif_sema_driver); if (result) { @@ -3638,15 +3637,14 @@ int wilc_wait_msg_queue_idle(void) return result; } -int wilc_set_wfi_drv_handler(struct wilc_vif *vif, struct host_if_drv *hif_drv) +int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index) { int result = 0; struct host_if_msg msg; memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER; - msg.body.drv.handler = get_id_from_handler(hif_drv); - msg.drv = hif_drv; + msg.body.drv.handler = index; msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -4001,7 +3999,7 @@ s32 wilc_deinit(struct wilc_vif *vif) del_timer_sync(&hif_drv->remain_on_ch_timer); - wilc_set_wfi_drv_handler(vif, NULL); + wilc_set_wfi_drv_handler(vif, 0); down(&hif_sema_driver); if (hif_drv->usr_scan_req.scan_result) { diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 9716bc859dca3..8922f291a68ea 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -367,13 +367,14 @@ s32 wilc_remain_on_channel(struct wilc_vif *vif, u32 u32SessionID, void *pvUserArg); s32 wilc_listen_state_expired(struct wilc_vif *vif, u32 u32SessionID); s32 wilc_frame_register(struct wilc_vif *vif, u16 u16FrameType, bool bReg); -int wilc_set_wfi_drv_handler(struct wilc_vif *vif, struct host_if_drv *hif_drv); +int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index); int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode); void wilc_free_join_params(void *pJoinParams); s32 wilc_get_statistics(struct wilc_vif *vif, struct rf_info *pstrStatistics); void wilc_resolve_disconnect_aberration(struct wilc_vif *vif); +int wilc_get_vif_idx(struct wilc_vif *vif); extern bool wilc_optaining_ip; extern u8 wilc_connected_ssid[6]; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index da4c4adefeeda..53fb2d4bb0bd1 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -628,7 +628,7 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) priv->u32RcvdChCount = 0; - wilc_set_wfi_drv_handler(vif, priv->hWILCWFIDrv); + wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif)); reset_shadow_found(); priv->bCfgScanning = true; @@ -709,7 +709,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, vif = netdev_priv(priv->dev); pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv); - wilc_set_wfi_drv_handler(vif, priv->hWILCWFIDrv); + wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif)); PRINT_D(CFG80211_DBG, "Connecting to SSID [%s] on netdev [%p] host if [%p]\n", sme->ssid, dev, priv->hWILCWFIDrv); if (!(strncmp(sme->ssid, "DIRECT-", 7))) { @@ -2142,7 +2142,8 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, wilc_initialized = 1; vif->iftype = interface_type; - wilc_set_wfi_drv_handler(vif, wl->vif[0]->hif_drv); + wilc_set_wfi_drv_handler(vif, + wilc_get_vif_idx(wl->vif[0])); wilc_set_mac_address(wl->vif[0], wl->vif[0]->src_addr); wilc_set_operation_mode(vif, STATION_MODE); @@ -2217,7 +2218,8 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, wilc1000_wlan_init(dev, vif); wilc_initialized = 1; - wilc_set_wfi_drv_handler(vif, wl->vif[0]->hif_drv); + wilc_set_wfi_drv_handler(vif, + wilc_get_vif_idx(wl->vif[0])); wilc_set_mac_address(wl->vif[0], wl->vif[0]->src_addr); wilc_set_operation_mode(vif, STATION_MODE); @@ -2320,7 +2322,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, wilc1000_wlan_init(dev, vif); wilc_initialized = 1; - wilc_set_wfi_drv_handler(vif, wl->vif[0]->hif_drv); + wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(wl->vif[0])); wilc_set_mac_address(wl->vif[0], wl->vif[0]->src_addr); wilc_set_operation_mode(vif, AP_MODE); -- GitLab From 7036c6244d0d26fd603cff81f07faa30c5f97022 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:45 +0900 Subject: [PATCH 1799/2855] staging: wilc1000: change join_req_drv type and it's name To use wilc_get_vif_idx instead of the last get_id_from_handler, join_req_drv needs to be changed it's type with wilc_vif and name as well. As a result, get_id_from_handler is not used anymore, so remove it. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 33 +++++++---------------- 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index be88237f2352b..e9a206c496ebe 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -259,7 +259,7 @@ static u8 mode_11i; static u8 auth_type; static u32 join_req_size; static u32 info_element_size; -static struct host_if_drv *join_req_drv; +static struct wilc_vif *join_req_vif; #define REAL_JOIN_REQ 0 #define FLUSHED_JOIN_REQ 1 #define FLUSHED_BYTE_POS 79 @@ -294,21 +294,6 @@ static int remove_handler_in_list(struct host_if_drv *handler) return -EINVAL; } -static int get_id_from_handler(struct host_if_drv *handler) -{ - int i; - - if (!handler) - return 0; - - for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) { - if (wfidrv_list[i] == handler) - return i; - } - - return 0; -} - /* The u8IfIdx starts from 0 to NUM_CONCURRENT_IFC -1, but 0 index used as * special purpose in wilc device, so we add 1 to the index to starts from 1. * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC. @@ -1235,7 +1220,7 @@ static s32 Handle_Connect(struct wilc_vif *vif, if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) { memcpy(join_req, pu8CurrByte, join_req_size); - join_req_drv = hif_drv; + join_req_vif = vif; } PRINT_D(GENERIC_DBG, "send HOST_IF_WAITING_CONN_RESP\n"); @@ -1349,7 +1334,7 @@ static s32 Handle_FlushConnect(struct wilc_vif *vif) result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, strWIDList, u32WidsCount, - get_id_from_handler(join_req_drv)); + wilc_get_vif_idx(join_req_vif)); if (result) { PRINT_ER("failed to send config packet\n"); result = -EINVAL; @@ -1426,12 +1411,12 @@ static s32 Handle_ConnectTimeout(struct wilc_vif *vif) eth_zero_addr(wilc_connected_ssid); - if (join_req && join_req_drv == hif_drv) { + if (join_req && join_req_vif == vif) { kfree(join_req); join_req = NULL; } - if (info_element && join_req_drv == hif_drv) { + if (info_element && join_req_vif == vif) { kfree(info_element); info_element = NULL; } @@ -1724,12 +1709,12 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif, kfree(hif_drv->usr_conn_req.ies); hif_drv->usr_conn_req.ies = NULL; - if (join_req && join_req_drv == hif_drv) { + if (join_req && join_req_vif == vif) { kfree(join_req); join_req = NULL; } - if (info_element && join_req_drv == hif_drv) { + if (info_element && join_req_vif == vif) { kfree(info_element); info_element = NULL; } @@ -2101,12 +2086,12 @@ static void Handle_Disconnect(struct wilc_vif *vif) kfree(hif_drv->usr_conn_req.ies); hif_drv->usr_conn_req.ies = NULL; - if (join_req && join_req_drv == hif_drv) { + if (join_req && join_req_vif == vif) { kfree(join_req); join_req = NULL; } - if (info_element && join_req_drv == hif_drv) { + if (info_element && join_req_vif == vif) { kfree(info_element); info_element = NULL; } -- GitLab From e79dcf7eaac60aad96df102f01340a161a7e9f39 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:46 +0900 Subject: [PATCH 1800/2855] staging: wilc1000: remove used functions This patch remove unused functions add_handler_in_list and remove_handler_in_list, and it's related global variable wfidrv_list and codes. label fail_timer_2 and it's codes are removed since label is not used anymore. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 44 ----------------------- 1 file changed, 44 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index e9a206c496ebe..46e009edb5cf4 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -226,7 +226,6 @@ struct join_bss_param { u8 start_time[4]; }; -static struct host_if_drv *wfidrv_list[NUM_CONCURRENT_IFC + 1]; struct host_if_drv *terminated_handle; bool wilc_optaining_ip; static u8 P2P_LISTEN_STATE; @@ -266,34 +265,6 @@ static struct wilc_vif *join_req_vif; static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo); -static int add_handler_in_list(struct host_if_drv *handler) -{ - int i; - - for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) { - if (!wfidrv_list[i]) { - wfidrv_list[i] = handler; - return 0; - } - } - - return -ENOBUFS; -} - -static int remove_handler_in_list(struct host_if_drv *handler) -{ - int i; - - for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) { - if (wfidrv_list[i] == handler) { - wfidrv_list[i] = NULL; - return 0; - } - } - - return -EINVAL; -} - /* The u8IfIdx starts from 0 to NUM_CONCURRENT_IFC -1, but 0 index used as * special purpose in wilc device, so we add 1 to the index to starts from 1. * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC. @@ -3852,7 +3823,6 @@ s32 wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) { s32 result = 0; struct host_if_drv *hif_drv; - int err; struct wilc_vif *vif; struct wilc *wilc; @@ -3872,11 +3842,6 @@ s32 wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) } hif_drv->wilc = wilc; *hif_drv_handler = hif_drv; - err = add_handler_in_list(hif_drv); - if (err) { - result = -EFAULT; - goto _fail_timer_2; - } wilc_optaining_ip = false; @@ -3946,10 +3911,6 @@ s32 wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) return result; -_fail_timer_2: - del_timer_sync(&hif_drv->connect_timer); - del_timer_sync(&hif_drv->scan_timer); - kthread_stop(hif_thread_handler); _fail_mq_: wilc_mq_destroy(&hif_msg_q); _fail_: @@ -3961,7 +3922,6 @@ s32 wilc_deinit(struct wilc_vif *vif) s32 result = 0; struct host_if_msg msg; struct host_if_drv *hif_drv = vif->hif_drv; - int ret; if (!hif_drv) { PRINT_ER("hif_drv = NULL\n"); @@ -4016,10 +3976,6 @@ s32 wilc_deinit(struct wilc_vif *vif) wilc_mq_destroy(&hif_msg_q); } - ret = remove_handler_in_list(hif_drv); - if (ret) - result = -ENOENT; - kfree(hif_drv); clients_count--; -- GitLab From b13584a899bf07f3ef693f8ebd1774d57f88906e Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:47 +0900 Subject: [PATCH 1801/2855] staging: wilc1000: remove drv of struct host_if_msg This patch remove drv of struct host_if msg and it's related codes. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 50 ++--------------------- 1 file changed, 3 insertions(+), 47 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 46e009edb5cf4..45e4bb7860967 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -193,7 +193,6 @@ union message_body { struct host_if_msg { u16 id; union message_body body; - struct host_if_drv *drv; struct wilc_vif *vif; }; @@ -2799,7 +2798,6 @@ static int hostIFthread(void *pvArg) { u32 u32Ret; struct host_if_msg msg; - struct host_if_drv *hif_drv; struct wilc *wilc = (struct wilc*)pvArg; struct wilc_vif *vif; @@ -2807,7 +2805,6 @@ static int hostIFthread(void *pvArg) while (1) { wilc_mq_recv(&hif_msg_q, &msg, sizeof(struct host_if_msg), &u32Ret); - hif_drv = (struct host_if_drv *)msg.drv; vif = msg.vif; if (msg.id == HOST_IF_MSG_EXIT) { PRINT_D(GENERIC_DBG, "THREAD: Exiting HostIfThread\n"); @@ -2822,7 +2819,7 @@ static int hostIFthread(void *pvArg) } if (msg.id == HOST_IF_MSG_CONNECT && - hif_drv->usr_scan_req.scan_result) { + vif->hif_drv->usr_scan_req.scan_result) { PRINT_D(HOSTINF_DBG, "Requeue connect request till scan done received\n"); wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); usleep_range(2 * 1000, 2 * 1000); @@ -2872,7 +2869,7 @@ static int hostIFthread(void *pvArg) break; case HOST_IF_MSG_RCVD_SCAN_COMPLETE: - del_timer(&hif_drv->scan_timer); + del_timer(&vif->hif_drv->scan_timer); PRINT_D(HOSTINF_DBG, "scan completed successfully\n"); if (!wilc_wlan_get_num_conn_ifcs(wilc)) @@ -2880,7 +2877,7 @@ static int hostIFthread(void *pvArg) Handle_ScanDone(msg.vif, SCAN_EVENT_DONE); - if (hif_drv->remain_on_ch_pending) + if (vif->hif_drv->remain_on_ch_pending) Handle_RemainOnChan(msg.vif, &msg.body.remain_on_ch); @@ -3064,7 +3061,6 @@ int wilc_remove_wep_key(struct wilc_vif *vif, u8 index) msg.id = HOST_IF_MSG_KEY; msg.body.key_info.type = WEP; msg.body.key_info.action = REMOVEKEY; - msg.drv = hif_drv; msg.vif = vif; msg.body.key_info.attr.wep.index = index; @@ -3093,7 +3089,6 @@ int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index) msg.id = HOST_IF_MSG_KEY; msg.body.key_info.type = WEP; msg.body.key_info.action = DEFAULTKEY; - msg.drv = hif_drv; msg.vif = vif; msg.body.key_info.attr.wep.index = index; @@ -3122,7 +3117,6 @@ int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len, msg.id = HOST_IF_MSG_KEY; msg.body.key_info.type = WEP; msg.body.key_info.action = ADDKEY; - msg.drv = hif_drv; msg.vif = vif; msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL); if (!msg.body.key_info.attr.wep.key) @@ -3161,7 +3155,6 @@ int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len, msg.id = HOST_IF_MSG_KEY; msg.body.key_info.type = WEP; msg.body.key_info.action = ADDKEY_AP; - msg.drv = hif_drv; msg.vif = vif; msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL); if (!msg.body.key_info.attr.wep.key) @@ -3235,7 +3228,6 @@ int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len, msg.body.key_info.attr.wpa.key_len = key_len; msg.body.key_info.attr.wpa.mac_addr = mac_addr; msg.body.key_info.attr.wpa.mode = cipher_mode; - msg.drv = hif_drv; msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -3280,7 +3272,6 @@ int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len, msg.id = HOST_IF_MSG_KEY; msg.body.key_info.type = WPA_RX_GTK; - msg.drv = hif_drv; msg.vif = vif; if (mode == AP_MODE) { @@ -3335,7 +3326,6 @@ s32 wilc_set_pmkid_info(struct wilc_vif *vif, msg.id = HOST_IF_MSG_KEY; msg.body.key_info.type = PMKSA; msg.body.key_info.action = ADDKEY; - msg.drv = hif_drv; msg.vif = vif; for (i = 0; i < pu8PmkidInfoArray->numpmkid; i++) { @@ -3356,13 +3346,11 @@ s32 wilc_get_mac_address(struct wilc_vif *vif, u8 *pu8MacAddress) { s32 result = 0; struct host_if_msg msg; - struct host_if_drv *hif_drv = vif->hif_drv; memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_GET_MAC_ADDRESS; msg.body.get_mac_info.mac_addr = pu8MacAddress; - msg.drv = hif_drv; msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -3379,14 +3367,12 @@ s32 wilc_set_mac_address(struct wilc_vif *vif, u8 *pu8MacAddress) { s32 result = 0; struct host_if_msg msg; - struct host_if_drv *hif_drv = vif->hif_drv; PRINT_D(GENERIC_DBG, "mac addr = %x:%x:%x\n", pu8MacAddress[0], pu8MacAddress[1], pu8MacAddress[2]); memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_SET_MAC_ADDRESS; memcpy(msg.body.set_mac_info.mac_addr, pu8MacAddress, ETH_ALEN); - msg.drv = hif_drv; msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -3426,7 +3412,6 @@ s32 wilc_set_join_req(struct wilc_vif *vif, u8 *pu8bssid, const u8 *pu8ssid, msg.body.con_info.result = pfConnectResult; msg.body.con_info.arg = pvUserArg; msg.body.con_info.params = pJoinParams; - msg.drv = hif_drv ; msg.vif = vif; if (pu8bssid) { @@ -3479,7 +3464,6 @@ s32 wilc_flush_join_req(struct wilc_vif *vif) } msg.id = HOST_IF_MSG_FLUSH_CONNECT; - msg.drv = hif_drv; msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -3505,7 +3489,6 @@ s32 wilc_disconnect(struct wilc_vif *vif, u16 u16ReasonCode) memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_DISCONNECT; - msg.drv = hif_drv; msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -3563,7 +3546,6 @@ int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel) memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_SET_CHANNEL; msg.body.channel_info.set_ch = channel; - msg.drv = hif_drv; msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -3616,12 +3598,10 @@ int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode) { int result = 0; struct host_if_msg msg; - struct host_if_drv *hif_drv = vif->hif_drv; memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_SET_OPERATION_MODE; msg.body.mode.mode = mode; - msg.drv = hif_drv; msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -3649,7 +3629,6 @@ s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac, memcpy(msg.body.mac_info.mac, mac, ETH_ALEN); msg.id = HOST_IF_MSG_GET_INACTIVETIME; - msg.drv = hif_drv; msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -3671,7 +3650,6 @@ s32 wilc_get_rssi(struct wilc_vif *vif, s8 *ps8Rssi) memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_GET_RSSI; - msg.drv = hif_drv; msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -3696,12 +3674,10 @@ s32 wilc_get_statistics(struct wilc_vif *vif, struct rf_info *pstrStatistics) { s32 result = 0; struct host_if_msg msg; - struct host_if_drv *hif_drv = vif->hif_drv; memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_GET_STATISTICS; msg.body.data = (char *)pstrStatistics; - msg.drv = hif_drv; msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -3739,7 +3715,6 @@ s32 wilc_scan(struct wilc_vif *vif, u8 u8ScanSource, u8 u8ScanType, } else PRINT_D(HOSTINF_DBG, "pstrHiddenNetwork IS EQUAL TO NULL\n"); - msg.drv = hif_drv; msg.vif = vif; msg.body.scan_info.src = u8ScanSource; msg.body.scan_info.type = u8ScanType; @@ -3783,7 +3758,6 @@ s32 wilc_hif_set_cfg(struct wilc_vif *vif, memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_CFG_PARAMS; msg.body.cfg_info.cfg_attr_info = *pstrCfgParamVal; - msg.drv = hif_drv; msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -3964,7 +3938,6 @@ s32 wilc_deinit(struct wilc_vif *vif) PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n"); msg.id = HOST_IF_MSG_EXIT; - msg.drv = hif_drv; msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -4007,7 +3980,6 @@ void wilc_network_info_received(struct wilc *wilc, u8 *pu8Buffer, memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO; - msg.drv = hif_drv; msg.vif = vif; msg.body.net_info.len = u32Length; @@ -4055,7 +4027,6 @@ void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *pu8Buffer, memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO; - msg.drv = hif_drv; msg.vif = vif; msg.body.async_info.len = u32Length; @@ -4093,7 +4064,6 @@ void wilc_scan_complete_received(struct wilc *wilc, u8 *pu8Buffer, memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE; - msg.drv = hif_drv; msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -4128,7 +4098,6 @@ s32 wilc_remain_on_channel(struct wilc_vif *vif, u32 u32SessionID, msg.body.remain_on_ch.arg = pvUserArg; msg.body.remain_on_ch.u32duration = u32duration; msg.body.remain_on_ch.id = u32SessionID; - msg.drv = hif_drv; msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -4153,7 +4122,6 @@ s32 wilc_listen_state_expired(struct wilc_vif *vif, u32 u32SessionID) memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED; - msg.drv = hif_drv; msg.vif = vif; msg.body.remain_on_ch.id = u32SessionID; @@ -4195,7 +4163,6 @@ s32 wilc_frame_register(struct wilc_vif *vif, u16 u16FrameType, bool bReg) } msg.body.reg_frame.frame_type = u16FrameType; msg.body.reg_frame.reg = bReg; - msg.drv = hif_drv; msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -4223,7 +4190,6 @@ s32 wilc_add_beacon(struct wilc_vif *vif, u32 u32Interval, u32 u32DTIMPeriod, PRINT_D(HOSTINF_DBG, "Setting adding beacon message queue params\n"); msg.id = HOST_IF_MSG_ADD_BEACON; - msg.drv = hif_drv; msg.vif = vif; pstrSetBeaconParam->interval = u32Interval; pstrSetBeaconParam->dtim_period = u32DTIMPeriod; @@ -4272,7 +4238,6 @@ int wilc_del_beacon(struct wilc_vif *vif) } msg.id = HOST_IF_MSG_DEL_BEACON; - msg.drv = hif_drv; msg.vif = vif; PRINT_D(HOSTINF_DBG, "Setting deleting beacon message queue params\n"); @@ -4300,7 +4265,6 @@ int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param) PRINT_D(HOSTINF_DBG, "Setting adding station message queue params\n"); msg.id = HOST_IF_MSG_ADD_STATION; - msg.drv = hif_drv; msg.vif = vif; memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param)); @@ -4335,7 +4299,6 @@ int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr) PRINT_D(HOSTINF_DBG, "Setting deleting station message queue params\n"); msg.id = HOST_IF_MSG_DEL_STATION; - msg.drv = hif_drv; msg.vif = vif; if (!mac_addr) @@ -4369,7 +4332,6 @@ s32 wilc_del_allstation(struct wilc_vif *vif, u8 pu8MacAddr[][ETH_ALEN]) PRINT_D(HOSTINF_DBG, "Setting deauthenticating station message queue params\n"); msg.id = HOST_IF_MSG_DEL_ALL_STA; - msg.drv = hif_drv; msg.vif = vif; for (i = 0; i < MAX_NUM_STA; i++) { @@ -4419,7 +4381,6 @@ s32 wilc_edit_station(struct wilc_vif *vif, memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_EDIT_STATION; - msg.drv = hif_drv; msg.vif = vif; memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param)); @@ -4460,7 +4421,6 @@ s32 wilc_set_power_mgmt(struct wilc_vif *vif, bool bIsEnabled, u32 u32Timeout) memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_POWER_MGMT; - msg.drv = hif_drv; msg.vif = vif; pstrPowerMgmtParam->enabled = bIsEnabled; @@ -4490,7 +4450,6 @@ s32 wilc_setup_multicast_filter(struct wilc_vif *vif, bool bIsEnabled, memset(&msg, 0, sizeof(struct host_if_msg)); msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER; - msg.drv = hif_drv; msg.vif = vif; pstrMulticastFilterParam->enabled = bIsEnabled; @@ -4685,7 +4644,6 @@ s32 wilc_del_all_rx_ba_session(struct wilc_vif *vif, char *pBSSID, char TID) memcpy(pBASessionInfo->bssid, pBSSID, ETH_ALEN); pBASessionInfo->tid = TID; - msg.drv = hif_drv; msg.vif = vif; result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); @@ -4715,7 +4673,6 @@ s32 wilc_setup_ipaddress(struct wilc_vif *vif, u8 *u16ipadd, u8 idx) msg.id = HOST_IF_MSG_SET_IPADDRESS; msg.body.ip_info.ip_addr = u16ipadd; - msg.drv = hif_drv; msg.vif = vif; msg.body.ip_info.idx = idx; @@ -4743,7 +4700,6 @@ static s32 host_int_get_ipaddress(struct wilc_vif *vif, msg.id = HOST_IF_MSG_GET_IPADDRESS; msg.body.ip_info.ip_addr = u16ipadd; - msg.drv = hif_drv; msg.vif = vif; msg.body.ip_info.idx = idx; -- GitLab From cd2920a50c3a484d67745f15fc9c99c3fd96ac6f Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:48 +0900 Subject: [PATCH 1802/2855] staging: wilc1000: remove wilc of struct host_if_drv vif has wilc in it's members so no need to have wilc in host_if_drv. It is redundant so just remove it and use wilc of vif. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 100 +++++++++------------- drivers/staging/wilc1000/host_interface.h | 1 - 2 files changed, 41 insertions(+), 60 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 45e4bb7860967..d6b23cdc745c1 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -293,7 +293,6 @@ static s32 handle_set_channel(struct wilc_vif *vif, { s32 result = 0; struct wid wid; - struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_CURRENT_CHANNEL; wid.type = WID_CHAR; @@ -302,7 +301,7 @@ static s32 handle_set_channel(struct wilc_vif *vif, PRINT_D(HOSTINF_DBG, "Setting channel\n"); - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) { @@ -343,14 +342,13 @@ static s32 handle_set_operation_mode(struct wilc_vif *vif, { s32 result = 0; struct wid wid; - struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_SET_OPERATION_MODE; wid.type = WID_INT; wid.val = (s8 *)&hif_op_mode->mode; wid.size = sizeof(u32); - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if ((hif_op_mode->mode) == IDLE_MODE) @@ -388,7 +386,7 @@ static s32 handle_set_ip_address(struct wilc_vif *vif, u8 *ip_addr, u8 idx) wid.val = (u8 *)ip_addr; wid.size = IP_ALEN; - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); host_int_get_ipaddress(vif, hif_drv, firmware_ip_addr, idx); @@ -407,14 +405,13 @@ static s32 handle_get_ip_address(struct wilc_vif *vif, u8 idx) { s32 result = 0; struct wid wid; - struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_IP_ADDRESS; wid.type = WID_STR; wid.val = kmalloc(IP_ALEN, GFP_KERNEL); wid.size = IP_ALEN; - result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, GET_CFG, &wid, 1, wilc_get_vif_idx(vif)); PRINT_INFO(HOSTINF_DBG, "%pI4\n", wid.val); @@ -443,7 +440,6 @@ static s32 handle_set_mac_address(struct wilc_vif *vif, { s32 result = 0; struct wid wid; - struct host_if_drv *hif_drv = vif->hif_drv; u8 *mac_buf = kmalloc(ETH_ALEN, GFP_KERNEL); if (!mac_buf) { @@ -458,7 +454,7 @@ static s32 handle_set_mac_address(struct wilc_vif *vif, wid.size = ETH_ALEN; PRINT_D(GENERIC_DBG, "mac addr = :%pM\n", wid.val); - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) { PRINT_ER("Failed to set mac address\n"); @@ -474,14 +470,13 @@ static s32 handle_get_mac_address(struct wilc_vif *vif, { s32 result = 0; struct wid wid; - struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_MAC_ADDR; wid.type = WID_STR; wid.val = get_mac_addr->mac_addr; wid.size = ETH_ALEN; - result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, GET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) { @@ -777,7 +772,7 @@ static s32 handle_cfg_param(struct wilc_vif *vif, wid_cnt++; } - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, wid_list, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, wid_list, wid_cnt, wilc_get_vif_idx(vif)); if (result) @@ -901,7 +896,7 @@ static s32 Handle_Scan(struct wilc_vif *vif, else if (hif_drv->hif_state == HOST_IF_IDLE) scan_while_connected = false; - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, strWIDList, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, strWIDList, u32WidsCount, wilc_get_vif_idx(vif)); @@ -947,7 +942,7 @@ static s32 Handle_ScanDone(struct wilc_vif *vif, wid.val = (s8 *)&u8abort_running_scan; wid.size = sizeof(char); - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) { @@ -1203,7 +1198,7 @@ static s32 Handle_Connect(struct wilc_vif *vif, PRINT_D(GENERIC_DBG, "save bssid = %pM\n", wilc_connected_ssid); } - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, strWIDList, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, strWIDList, u32WidsCount, wilc_get_vif_idx(vif)); if (result) { @@ -1271,7 +1266,6 @@ static s32 Handle_FlushConnect(struct wilc_vif *vif) struct wid strWIDList[5]; u32 u32WidsCount = 0; u8 *pu8CurrByte = NULL; - struct host_if_drv *hif_drv = vif->hif_drv; strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE; strWIDList[u32WidsCount].type = WID_BIN_DATA; @@ -1302,7 +1296,7 @@ static s32 Handle_FlushConnect(struct wilc_vif *vif) u32WidsCount++; - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, strWIDList, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, strWIDList, u32WidsCount, wilc_get_vif_idx(join_req_vif)); if (result) { @@ -1365,7 +1359,7 @@ static s32 Handle_ConnectTimeout(struct wilc_vif *vif) PRINT_D(HOSTINF_DBG, "Sending disconnect request\n"); - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send dissconect config packet\n"); @@ -1759,7 +1753,7 @@ static int Handle_Key(struct wilc_vif *vif, strWIDList[3].size = pstrHostIFkeyAttr->attr.wep.key_len; strWIDList[3].val = (s8 *)pu8keybuf; - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, strWIDList, 4, wilc_get_vif_idx(vif)); kfree(pu8keybuf); @@ -1781,7 +1775,7 @@ static int Handle_Key(struct wilc_vif *vif, wid.val = (s8 *)pu8keybuf; wid.size = pstrHostIFkeyAttr->attr.wep.key_len + 2; - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); kfree(pu8keybuf); @@ -1794,7 +1788,7 @@ static int Handle_Key(struct wilc_vif *vif, wid.val = s8idxarray; wid.size = 1; - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); } else { @@ -1805,7 +1799,7 @@ static int Handle_Key(struct wilc_vif *vif, PRINT_D(HOSTINF_DBG, "Setting default key index\n"); - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); } @@ -1839,7 +1833,7 @@ static int Handle_Key(struct wilc_vif *vif, strWIDList[1].val = (s8 *)pu8keybuf; strWIDList[1].size = RX_MIC_KEY_MSG_LEN; - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, strWIDList, 2, wilc_get_vif_idx(vif)); @@ -1871,7 +1865,7 @@ static int Handle_Key(struct wilc_vif *vif, wid.val = (s8 *)pu8keybuf; wid.size = RX_MIC_KEY_MSG_LEN; - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); @@ -1911,7 +1905,7 @@ _WPARxGtk_end_case_: strWIDList[1].val = (s8 *)pu8keybuf; strWIDList[1].size = PTK_KEY_MSG_LEN + 1; - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, strWIDList, 2, wilc_get_vif_idx(vif)); kfree(pu8keybuf); @@ -1934,7 +1928,7 @@ _WPARxGtk_end_case_: wid.val = (s8 *)pu8keybuf; wid.size = PTK_KEY_MSG_LEN; - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); kfree(pu8keybuf); @@ -1970,7 +1964,7 @@ _WPAPtk_end_case_: wid.val = (s8 *)pu8keybuf; wid.size = (pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1; - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); kfree(pu8keybuf); @@ -2003,7 +1997,7 @@ static void Handle_Disconnect(struct wilc_vif *vif) eth_zero_addr(wilc_connected_ssid); - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) { @@ -2094,7 +2088,7 @@ static s32 Handle_GetChnl(struct wilc_vif *vif) PRINT_D(HOSTINF_DBG, "Getting channel value\n"); - result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, GET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) { @@ -2119,7 +2113,7 @@ static void Handle_GetRssi(struct wilc_vif *vif) PRINT_D(HOSTINF_DBG, "Getting RSSI value\n"); - result = wilc_send_config_pkt(vif->hif_drv->wilc, GET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, GET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) { PRINT_ER("Failed to get RSSI value\n"); @@ -2144,7 +2138,7 @@ static void Handle_GetLinkspeed(struct wilc_vif *vif) PRINT_D(HOSTINF_DBG, "Getting LINKSPEED value\n"); - result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, GET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) { PRINT_ER("Failed to get LINKSPEED value\n"); @@ -2159,7 +2153,6 @@ static s32 Handle_GetStatistics(struct wilc_vif *vif, { struct wid strWIDList[5]; u32 u32WidsCount = 0, result = 0; - struct host_if_drv *hif_drv = vif->hif_drv; strWIDList[u32WidsCount].id = WID_LINKSPEED; strWIDList[u32WidsCount].type = WID_CHAR; @@ -2191,7 +2184,7 @@ static s32 Handle_GetStatistics(struct wilc_vif *vif, strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_fail_cnt; u32WidsCount++; - result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, strWIDList, + result = wilc_send_config_pkt(vif->wilc, GET_CFG, strWIDList, u32WidsCount, wilc_get_vif_idx(vif)); @@ -2220,7 +2213,7 @@ static s32 Handle_Get_InActiveTime(struct wilc_vif *vif, PRINT_D(CFG80211_DBG, "SETING STA inactive time\n"); - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) { @@ -2233,7 +2226,7 @@ static s32 Handle_Get_InActiveTime(struct wilc_vif *vif, wid.val = (s8 *)&inactive_time; wid.size = sizeof(u32); - result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, GET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) { @@ -2254,7 +2247,6 @@ static void Handle_AddBeacon(struct wilc_vif *vif, s32 result = 0; struct wid wid; u8 *pu8CurrByte; - struct host_if_drv *hif_drv = vif->hif_drv; PRINT_D(HOSTINF_DBG, "Adding BEACON\n"); @@ -2293,7 +2285,7 @@ static void Handle_AddBeacon(struct wilc_vif *vif, memcpy(pu8CurrByte, pstrSetBeaconParam->tail, pstrSetBeaconParam->tail_len); pu8CurrByte += pstrSetBeaconParam->tail_len; - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send add beacon config packet\n"); @@ -2309,7 +2301,6 @@ static void Handle_DelBeacon(struct wilc_vif *vif) s32 result = 0; struct wid wid; u8 *pu8CurrByte; - struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_DEL_BEACON; wid.type = WID_CHAR; @@ -2323,7 +2314,7 @@ static void Handle_DelBeacon(struct wilc_vif *vif) PRINT_D(HOSTINF_DBG, "Deleting BEACON\n"); - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send delete beacon config packet\n"); @@ -2383,7 +2374,6 @@ static void Handle_AddStation(struct wilc_vif *vif, s32 result = 0; struct wid wid; u8 *pu8CurrByte; - struct host_if_drv *hif_drv = vif->hif_drv; PRINT_D(HOSTINF_DBG, "Handling add station\n"); wid.id = (u16)WID_ADD_STA; @@ -2397,7 +2387,7 @@ static void Handle_AddStation(struct wilc_vif *vif, pu8CurrByte = wid.val; pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam); - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result != 0) PRINT_ER("Failed to send add station config packet\n"); @@ -2415,7 +2405,6 @@ static void Handle_DelAllSta(struct wilc_vif *vif, u8 *pu8CurrByte; u8 i; u8 au8Zero_Buff[6] = {0}; - struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_DEL_ALL_STA; wid.type = WID_STR; @@ -2440,7 +2429,7 @@ static void Handle_DelAllSta(struct wilc_vif *vif, pu8CurrByte += ETH_ALEN; } - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send add station config packet\n"); @@ -2457,7 +2446,6 @@ static void Handle_DelStation(struct wilc_vif *vif, s32 result = 0; struct wid wid; u8 *pu8CurrByte; - struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_REMOVE_STA; wid.type = WID_BIN; @@ -2473,7 +2461,7 @@ static void Handle_DelStation(struct wilc_vif *vif, memcpy(pu8CurrByte, pstrDelStaParam->mac_addr, ETH_ALEN); - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send add station config packet\n"); @@ -2488,7 +2476,6 @@ static void Handle_EditStation(struct wilc_vif *vif, s32 result = 0; struct wid wid; u8 *pu8CurrByte; - struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_EDIT_STA; wid.type = WID_BIN; @@ -2502,7 +2489,7 @@ static void Handle_EditStation(struct wilc_vif *vif, pu8CurrByte = wid.val; pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam); - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send edit station config packet\n"); @@ -2564,7 +2551,7 @@ static int Handle_RemainOnChan(struct wilc_vif *vif, wid.val[0] = u8remain_on_chan_flag; wid.val[1] = (s8)pstrHostIfRemainOnChan->ch; - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result != 0) PRINT_ER("Failed to set remain on channel\n"); @@ -2593,7 +2580,6 @@ static int Handle_RegisterFrame(struct wilc_vif *vif, s32 result = 0; struct wid wid; u8 *pu8CurrByte; - struct host_if_drv *hif_drv = vif->hif_drv; PRINT_D(HOSTINF_DBG, "Handling frame register : %d FrameType: %d\n", pstrHostIfRegisterFrame->reg, @@ -2613,7 +2599,7 @@ static int Handle_RegisterFrame(struct wilc_vif *vif, wid.size = sizeof(u16) + 2; - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) { PRINT_ER("Failed to frame register config packet\n"); @@ -2648,7 +2634,7 @@ static u32 Handle_ListenStateExpired(struct wilc_vif *vif, wid.val[0] = u8remain_on_chan_flag; wid.val[1] = FALSE_FRMWR_CHANNEL; - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result != 0) { PRINT_ER("Failed to set remain on channel\n"); @@ -2693,7 +2679,6 @@ static void Handle_PowerManagement(struct wilc_vif *vif, s32 result = 0; struct wid wid; s8 s8PowerMode; - struct host_if_drv *hif_drv = vif->hif_drv; wid.id = (u16)WID_POWER_MANAGEMENT; @@ -2707,7 +2692,7 @@ static void Handle_PowerManagement(struct wilc_vif *vif, PRINT_D(HOSTINF_DBG, "Handling Power Management\n"); - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send power management config packet\n"); @@ -2719,7 +2704,6 @@ static void Handle_SetMulticastFilter(struct wilc_vif *vif, s32 result = 0; struct wid wid; u8 *pu8CurrByte; - struct host_if_drv *hif_drv = vif->hif_drv; PRINT_D(HOSTINF_DBG, "Setup Multicast Filter\n"); @@ -2745,7 +2729,7 @@ static void Handle_SetMulticastFilter(struct wilc_vif *vif, memcpy(pu8CurrByte, wilc_multicast_mac_addr_list, ((strHostIfSetMulti->cnt) * ETH_ALEN)); - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) PRINT_ER("Failed to send setup multicast config packet\n"); @@ -2760,7 +2744,6 @@ static s32 Handle_DelAllRxBASessions(struct wilc_vif *vif, s32 result = 0; struct wid wid; char *ptr = NULL; - struct host_if_drv *hif_drv = vif->hif_drv; PRINT_D(GENERIC_DBG, "Delete Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\n", strHostIfBASessionInfo->bssid[0], @@ -2782,7 +2765,7 @@ static s32 Handle_DelAllRxBASessions(struct wilc_vif *vif, *ptr++ = 0; *ptr++ = 32; - result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n"); @@ -3519,7 +3502,7 @@ static s32 host_int_get_assoc_res_info(struct wilc_vif *vif, wid.val = pu8AssocRespInfo; wid.size = u32MaxAssocRespInfoLen; - result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1, + result = wilc_send_config_pkt(vif->wilc, GET_CFG, &wid, 1, wilc_get_vif_idx(vif)); if (result) { *pu32RcvdAssocRespInfoLen = 0; @@ -3814,7 +3797,6 @@ s32 wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) result = -ENOMEM; goto _fail_; } - hif_drv->wilc = wilc; *hif_drv_handler = hif_drv; wilc_optaining_ip = false; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 8922f291a68ea..8faac27002e99 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -261,7 +261,6 @@ enum p2p_listen_state { struct wilc; struct host_if_drv { - struct wilc *wilc; struct user_scan_req usr_scan_req; struct user_conn_req usr_conn_req; struct remain_ch remain_on_ch; -- GitLab From 03efae328ddcda7826a3bedb2ac15eb9598eabb4 Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:49 +0900 Subject: [PATCH 1803/2855] staging: wilc1000: set hif_drv before it is used We are using hif_drv of vif, so it needs to be set before it is used. Set hif_drv to vif->hifdrv soon after it is allocated. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 ++++++ drivers/staging/wilc1000/linux_wlan.c | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index d6b23cdc745c1..8c7752034032b 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3782,6 +3782,7 @@ s32 wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) struct host_if_drv *hif_drv; struct wilc_vif *vif; struct wilc *wilc; + int i; vif = netdev_priv(dev); wilc = vif->wilc; @@ -3798,6 +3799,11 @@ s32 wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) goto _fail_; } *hif_drv_handler = hif_drv; + for (i = 0; i < wilc->vif_num; i++) + if (dev == wilc->vif[i]->ndev) { + wilc->vif[i]->hif_drv = hif_drv; + break; + } wilc_optaining_ip = false; diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index a50e3ffcbb8d5..54fe9d74b7808 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1036,7 +1036,6 @@ int wilc_mac_open(struct net_device *ndev) for (i = 0; i < wl->vif_num; i++) { if (ndev == wl->vif[i]->ndev) { memcpy(wl->vif[i]->src_addr, mac_add, ETH_ALEN); - wl->vif[i]->hif_drv = priv->hWILCWFIDrv; break; } } -- GitLab From 608b0515b75292a3f890356f976849050c519d6a Mon Sep 17 00:00:00 2001 From: Glen Lee Date: Mon, 21 Dec 2015 14:18:50 +0900 Subject: [PATCH 1804/2855] staging: wilc1000: bug fix on memory free Set tx_buffer to NULL not to free again the memory that is already freed, which could cause system crash when device is failed. Signed-off-by: Glen Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 00f346454e004..83af51bb83e8b 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1374,6 +1374,7 @@ void wilc_wlan_cleanup(struct net_device *dev) kfree(wilc->rx_buffer); wilc->rx_buffer = NULL; kfree(wilc->tx_buffer); + wilc->tx_buffer = NULL; acquire_bus(wilc, ACQUIRE_AND_WAKEUP); -- GitLab From fadf3a44e974b030e7145218ad1ab25e3ef91738 Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Thu, 17 Dec 2015 08:47:02 -0700 Subject: [PATCH 1805/2855] coresight: checking for NULL string in coresight_name_match() Connection child names associated to ports can sometimes be NULL, which is the case when booting a system on QEMU or when the Coresight power domain isn't switched on. This patch is adding a check to make sure a NULL string isn't fed to strcmp(), something that avoid crashing the system. Cc: # v3.18+ Reported-by: Tyler Baker Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index e25492137d8be..93738dfbf6313 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -548,7 +548,7 @@ static int coresight_name_match(struct device *dev, void *data) to_match = data; i_csdev = to_coresight_device(dev); - if (!strcmp(to_match, dev_name(&i_csdev->dev))) + if (to_match && !strcmp(to_match, dev_name(&i_csdev->dev))) return 1; return 0; -- GitLab From b9884d3b79f60846cdf04be262d13bca8996f99a Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Thu, 17 Dec 2015 08:47:02 -0700 Subject: [PATCH 1806/2855] coresight: Fix a typo in Kconfig Signed-off-by: Andrew F. Davis Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig index 6c8921140f024..c85935f3525a8 100644 --- a/drivers/hwtracing/coresight/Kconfig +++ b/drivers/hwtracing/coresight/Kconfig @@ -8,7 +8,7 @@ menuconfig CORESIGHT This framework provides a kernel interface for the CoreSight debug and trace drivers to register themselves with. It's intended to build a topological view of the CoreSight components based on a DT - specification and configure the right serie of components when a + specification and configure the right series of components when a trace source gets enabled. if CORESIGHT -- GitLab From d9c0e6c10dfed44bb35d6db4293b18af51e752ac Mon Sep 17 00:00:00 2001 From: Chen Feng Date: Mon, 12 Oct 2015 15:00:15 +0800 Subject: [PATCH 1807/2855] docs: dts: Add documentation for hi6220 SoC ION node Documentation for hi6220 SoC ION node Signed-off-by: Chen Feng Signed-off-by: Yu Dongbin Signed-off-by: Greg Kroah-Hartman --- .../bindings/staging/ion/hi6220-ion.txt | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Documentation/devicetree/bindings/staging/ion/hi6220-ion.txt diff --git a/Documentation/devicetree/bindings/staging/ion/hi6220-ion.txt b/Documentation/devicetree/bindings/staging/ion/hi6220-ion.txt new file mode 100644 index 0000000000000..c59e27c632c17 --- /dev/null +++ b/Documentation/devicetree/bindings/staging/ion/hi6220-ion.txt @@ -0,0 +1,31 @@ +Hi6220 SoC ION +=================================================================== +Required properties: +- compatible : "hisilicon,hi6220-ion" +- list of the ION heaps + - heap name : maybe heap_sys_user@0 + - heap id : id should be unique in the system. + - heap base : base ddr address of the heap,0 means that + it is dynamic. + - heap size : memory size and 0 means it is dynamic. + - heap type : the heap type of the heap, please also + see the define in ion.h(drivers/staging/android/uapi/ion.h) +------------------------------------------------------------------- +Example: + hi6220-ion { + compatible = "hisilicon,hi6220-ion"; + heap_sys_user@0 { + heap-name = "sys_user"; + heap-id = <0x0>; + heap-base = <0x0>; + heap-size = <0x0>; + heap-type = "ion_system"; + }; + heap_sys_contig@0 { + heap-name = "sys_contig"; + heap-id = <0x1>; + heap-base = <0x0>; + heap-size = <0x0>; + heap-type = "ion_system_contig"; + }; + }; -- GitLab From 2b40182a19bc238465688fb989fb33b99e953121 Mon Sep 17 00:00:00 2001 From: Chen Feng Date: Mon, 12 Oct 2015 15:00:16 +0800 Subject: [PATCH 1808/2855] staging: android: ion: Add ion driver for Hi6220 SoC platform Add ion support for hi6220 SoC platform. Signed-off-by: Chen Feng Signed-off-by: Yu Dongbin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ion/Kconfig | 7 + drivers/staging/android/ion/Makefile | 1 + drivers/staging/android/ion/hisilicon/Kconfig | 5 + .../staging/android/ion/hisilicon/Makefile | 1 + .../android/ion/hisilicon/hi6220_ion.c | 223 ++++++++++++++++++ 5 files changed, 237 insertions(+) create mode 100644 drivers/staging/android/ion/hisilicon/Kconfig create mode 100644 drivers/staging/android/ion/hisilicon/Makefile create mode 100644 drivers/staging/android/ion/hisilicon/hi6220_ion.c diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig index 3452346244922..19c1572f1525e 100644 --- a/drivers/staging/android/ion/Kconfig +++ b/drivers/staging/android/ion/Kconfig @@ -33,3 +33,10 @@ config ION_TEGRA help Choose this option if you wish to use ion on an nVidia Tegra. +config ION_HISI + tristate "Ion for Hisilicon" + depends on ARCH_HISI && ION + help + Choose this option if you wish to use ion on Hisilicon Platform. + +source "drivers/staging/android/ion/hisilicon/Kconfig" diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile index b56fd2bf2b4f4..18cc2aa593c2c 100644 --- a/drivers/staging/android/ion/Makefile +++ b/drivers/staging/android/ion/Makefile @@ -7,4 +7,5 @@ endif obj-$(CONFIG_ION_DUMMY) += ion_dummy_driver.o obj-$(CONFIG_ION_TEGRA) += tegra/ +obj-$(CONFIG_ION_HISI) += hisilicon/ diff --git a/drivers/staging/android/ion/hisilicon/Kconfig b/drivers/staging/android/ion/hisilicon/Kconfig new file mode 100644 index 0000000000000..2b4bd07982900 --- /dev/null +++ b/drivers/staging/android/ion/hisilicon/Kconfig @@ -0,0 +1,5 @@ +config HI6220_ION + bool "Hi6220 ION Driver" + depends on ARCH_HISI && ION + help + Build the Hisilicon Hi6220 ion driver. diff --git a/drivers/staging/android/ion/hisilicon/Makefile b/drivers/staging/android/ion/hisilicon/Makefile new file mode 100644 index 0000000000000..2a89414280ac1 --- /dev/null +++ b/drivers/staging/android/ion/hisilicon/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_HI6220_ION) += hi6220_ion.o diff --git a/drivers/staging/android/ion/hisilicon/hi6220_ion.c b/drivers/staging/android/ion/hisilicon/hi6220_ion.c new file mode 100644 index 0000000000000..e3c07b2ba00e2 --- /dev/null +++ b/drivers/staging/android/ion/hisilicon/hi6220_ion.c @@ -0,0 +1,223 @@ +/* + * Hisilicon Hi6220 ION Driver + * + * Copyright (c) 2015 Hisilicon Limited. + * + * Author: Chen Feng + * + * 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. + */ + +#define pr_fmt(fmt) "Ion: " fmt + +#include +#include +#include +#include +#include +#include "../ion_priv.h" +#include "../ion.h" + +struct hi6220_ion_type_table { + const char *name; + enum ion_heap_type type; +}; + +static struct hi6220_ion_type_table ion_type_table[] = { + {"ion_system", ION_HEAP_TYPE_SYSTEM}, + {"ion_system_contig", ION_HEAP_TYPE_SYSTEM_CONTIG}, + {"ion_carveout", ION_HEAP_TYPE_CARVEOUT}, + {"ion_chunk", ION_HEAP_TYPE_CHUNK}, + {"ion_dma", ION_HEAP_TYPE_DMA}, + {"ion_custom", ION_HEAP_TYPE_CUSTOM}, +}; + +static struct ion_device *idev; +static int num_heaps; +static struct ion_heap **heaps; +static struct ion_platform_heap **heaps_data; + +static int get_type_by_name(const char *name, enum ion_heap_type *type) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ion_type_table); i++) { + if (strncmp(name, ion_type_table[i].name, strlen(name))) + continue; + + *type = ion_type_table[i].type; + return 0; + } + + return -EINVAL; +} + +static int hi6220_set_platform_data(struct platform_device *pdev) +{ + unsigned int base; + unsigned int size; + unsigned int id; + const char *heap_name; + const char *type_name; + enum ion_heap_type type; + int ret; + struct device_node *np; + struct ion_platform_heap *p_data; + const struct device_node *dt_node = pdev->dev.of_node; + int index = 0; + + for_each_child_of_node(dt_node, np) + num_heaps++; + + heaps_data = devm_kzalloc(&pdev->dev, + sizeof(struct ion_platform_heap *) * + num_heaps, + GFP_KERNEL); + if (!heaps_data) + return -ENOMEM; + + for_each_child_of_node(dt_node, np) { + ret = of_property_read_string(np, "heap-name", &heap_name); + if (ret < 0) { + pr_err("check the name of node %s\n", np->name); + continue; + } + + ret = of_property_read_u32(np, "heap-id", &id); + if (ret < 0) { + pr_err("check the id %s\n", np->name); + continue; + } + + ret = of_property_read_u32(np, "heap-base", &base); + if (ret < 0) { + pr_err("check the base of node %s\n", np->name); + continue; + } + + ret = of_property_read_u32(np, "heap-size", &size); + if (ret < 0) { + pr_err("check the size of node %s\n", np->name); + continue; + } + + ret = of_property_read_string(np, "heap-type", &type_name); + if (ret < 0) { + pr_err("check the type of node %s\n", np->name); + continue; + } + + ret = get_type_by_name(type_name, &type); + if (ret < 0) { + pr_err("type name error %s!\n", type_name); + continue; + } + pr_info("heap index %d : name %s base 0x%x size 0x%x id %d type %d\n", + index, heap_name, base, size, id, type); + + p_data = devm_kzalloc(&pdev->dev, + sizeof(struct ion_platform_heap), + GFP_KERNEL); + if (!p_data) + return -ENOMEM; + + p_data->name = heap_name; + p_data->base = base; + p_data->size = size; + p_data->id = id; + p_data->type = type; + + heaps_data[index] = p_data; + index++; + } + return 0; +} + +static int hi6220_ion_probe(struct platform_device *pdev) +{ + int i; + int err; + static struct ion_platform_heap *p_heap; + + idev = ion_device_create(NULL); + err = hi6220_set_platform_data(pdev); + if (err) { + pr_err("ion set platform data error!\n"); + goto err_free_idev; + } + heaps = devm_kzalloc(&pdev->dev, + sizeof(struct ion_heap *) * num_heaps, + GFP_KERNEL); + if (!heaps) { + err = -ENOMEM; + goto err_free_idev; + } + + /* + * create the heaps as specified in the dts file + */ + for (i = 0; i < num_heaps; i++) { + p_heap = heaps_data[i]; + heaps[i] = ion_heap_create(p_heap); + if (IS_ERR_OR_NULL(heaps[i])) { + err = PTR_ERR(heaps[i]); + goto err_free_heaps; + } + + ion_device_add_heap(idev, heaps[i]); + + pr_info("%s: adding heap %s of type %d with %lx@%lx\n", + __func__, p_heap->name, p_heap->type, + p_heap->base, (unsigned long)p_heap->size); + } + return err; + +err_free_heaps: + for (i = 0; i < num_heaps; ++i) { + ion_heap_destroy(heaps[i]); + heaps[i] = NULL; + } +err_free_idev: + ion_device_destroy(idev); + + return err; +} + +static int hi6220_ion_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < num_heaps; i++) { + ion_heap_destroy(heaps[i]); + heaps[i] = NULL; + } + ion_device_destroy(idev); + + return 0; +} + +static const struct of_device_id hi6220_ion_match_table[] = { + {.compatible = "hisilicon,hi6220-ion"}, + {}, +}; + +static struct platform_driver hi6220_ion_driver = { + .probe = hi6220_ion_probe, + .remove = hi6220_ion_remove, + .driver = { + .name = "ion-hi6220", + .of_match_table = hi6220_ion_match_table, + }, +}; + +static int __init hi6220_ion_init(void) +{ + int ret; + + ret = platform_driver_register(&hi6220_ion_driver); + return ret; +} + +subsys_initcall(hi6220_ion_init); -- GitLab From 59dfafd03fc67d38307d2ba30bbfdd1224b8a75d Mon Sep 17 00:00:00 2001 From: Chen Feng Date: Mon, 12 Oct 2015 15:00:17 +0800 Subject: [PATCH 1809/2855] arm64: dts: Add dts files to enable ION on Hi6220 SoC. Add ION node to enable ION on hi6220 SoC platform Signed-off-by: Chen Feng Signed-off-by: Yu Dongbin Signed-off-by: Greg Kroah-Hartman --- .../arm64/boot/dts/hisilicon/hi6220-hikey.dts | 1 + arch/arm64/boot/dts/hisilicon/hi6220-ion.dtsi | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 arch/arm64/boot/dts/hisilicon/hi6220-ion.dtsi diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts index 8d43a0fce5226..496a920eced4a 100644 --- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts +++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts @@ -11,6 +11,7 @@ /memreserve/ 0x05e00000 0x00100000; #include "hi6220.dtsi" +#include "hi6220-ion.dtsi" / { model = "HiKey Development Board"; diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-ion.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220-ion.dtsi new file mode 100644 index 0000000000000..c79f2cea314c5 --- /dev/null +++ b/arch/arm64/boot/dts/hisilicon/hi6220-ion.dtsi @@ -0,0 +1,20 @@ +/ { + hi6220-ion { + compatible = "hisilicon,hi6220-ion"; + heap_sys_user@0 { + heap-name = "sys_user"; + heap-id = <0x0>; + heap-base = <0x0>; + heap-size = <0x0>; + heap-type = "ion_system"; + }; + heap_sys_contig@0 { + heap-name = "sys_contig"; + heap-id = <0x1>; + heap-base = <0x0>; + heap-size = <0x0>; + heap-type = "ion_system_contig"; + }; + }; + +}; -- GitLab From a2df4e33d71ff819c9afcdf34392030cee349f47 Mon Sep 17 00:00:00 2001 From: Wenwei Tao Date: Wed, 9 Dec 2015 00:15:52 +0800 Subject: [PATCH 1810/2855] staging: android: ashmem.c: destroy slabs when init fails when ashmem init fails, destroy the slabs, leave no garbage. Signed-off-by: Wenwei Tao Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ashmem.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 3f2a3d611e4be..5bb1283d19cd2 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -831,14 +831,14 @@ static struct miscdevice ashmem_misc = { static int __init ashmem_init(void) { - int ret; + int ret = -ENOMEM; ashmem_area_cachep = kmem_cache_create("ashmem_area_cache", sizeof(struct ashmem_area), 0, 0, NULL); if (unlikely(!ashmem_area_cachep)) { pr_err("failed to create slab cache\n"); - return -ENOMEM; + goto out; } ashmem_range_cachep = kmem_cache_create("ashmem_range_cache", @@ -846,13 +846,13 @@ static int __init ashmem_init(void) 0, 0, NULL); if (unlikely(!ashmem_range_cachep)) { pr_err("failed to create slab cache\n"); - return -ENOMEM; + goto out_free1; } ret = misc_register(&ashmem_misc); if (unlikely(ret)) { pr_err("failed to register misc device!\n"); - return ret; + goto out_free2; } register_shrinker(&ashmem_shrinker); @@ -860,5 +860,12 @@ static int __init ashmem_init(void) pr_info("initialized\n"); return 0; + +out_free2: + kmem_cache_destroy(ashmem_range_cachep); +out_free1: + kmem_cache_destroy(ashmem_area_cachep); +out: + return ret; } device_initcall(ashmem_init); -- GitLab From 73465f1c08258637dc8c49c2c8d1a1233d9861c7 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Fri, 11 Dec 2015 13:11:49 +0000 Subject: [PATCH 1811/2855] staging/android/sync: Support sync points created from dma-fences MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Debug output assumes all sync points are built on top of Android sync points and when we start creating them from dma-fences will NULL ptr deref unless taught about this. v4: Corrected patch ownership. Signed-off-by: Maarten Lankhorst Signed-off-by: Tvrtko Ursulin Cc: Maarten Lankhorst Cc: devel@driverdev.osuosl.org Cc: Riley Andrews Cc: Arve Hjønnevåg Reviewed-by: Jesse Barnes Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync_debug.c | 42 +++++++++++++++------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/drivers/staging/android/sync_debug.c b/drivers/staging/android/sync_debug.c index 91ed2c4cff45b..f45d13cdd42b9 100644 --- a/drivers/staging/android/sync_debug.c +++ b/drivers/staging/android/sync_debug.c @@ -82,36 +82,42 @@ static const char *sync_status_str(int status) return "error"; } -static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence) +static void sync_print_pt(struct seq_file *s, struct fence *pt, bool fence) { int status = 1; - struct sync_timeline *parent = sync_pt_parent(pt); - if (fence_is_signaled_locked(&pt->base)) - status = pt->base.status; + if (fence_is_signaled_locked(pt)) + status = pt->status; seq_printf(s, " %s%spt %s", - fence ? parent->name : "", + fence && pt->ops->get_timeline_name ? + pt->ops->get_timeline_name(pt) : "", fence ? "_" : "", sync_status_str(status)); if (status <= 0) { struct timespec64 ts64 = - ktime_to_timespec64(pt->base.timestamp); + ktime_to_timespec64(pt->timestamp); seq_printf(s, "@%lld.%09ld", (s64)ts64.tv_sec, ts64.tv_nsec); } - if (parent->ops->timeline_value_str && - parent->ops->pt_value_str) { + if ((!fence || pt->ops->timeline_value_str) && + pt->ops->fence_value_str) { char value[64]; + bool success; - parent->ops->pt_value_str(pt, value, sizeof(value)); - seq_printf(s, ": %s", value); - if (fence) { - parent->ops->timeline_value_str(parent, value, - sizeof(value)); - seq_printf(s, " / %s", value); + pt->ops->fence_value_str(pt, value, sizeof(value)); + success = strlen(value); + + if (success) + seq_printf(s, ": %s", value); + + if (success && fence) { + pt->ops->timeline_value_str(pt, value, sizeof(value)); + + if (strlen(value)) + seq_printf(s, " / %s", value); } } @@ -138,7 +144,7 @@ static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj) list_for_each(pos, &obj->child_list_head) { struct sync_pt *pt = container_of(pos, struct sync_pt, child_list); - sync_print_pt(s, pt, false); + sync_print_pt(s, &pt->base, false); } spin_unlock_irqrestore(&obj->child_list_lock, flags); } @@ -153,11 +159,7 @@ static void sync_print_fence(struct seq_file *s, struct sync_fence *fence) sync_status_str(atomic_read(&fence->status))); for (i = 0; i < fence->num_fences; ++i) { - struct sync_pt *pt = - container_of(fence->cbs[i].sync_pt, - struct sync_pt, base); - - sync_print_pt(s, pt, true); + sync_print_pt(s, fence->cbs[i].sync_pt, true); } spin_lock_irqsave(&fence->wq.lock, flags); -- GitLab From 0f477c6dea709465550aa0922fd0c5b686e6e8eb Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Fri, 11 Dec 2015 13:11:50 +0000 Subject: [PATCH 1812/2855] staging/android/sync: add sync_fence_create_dma MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows users of dma fences to create a android fence. v2: Added kerneldoc. (Tvrtko Ursulin). v4: Updated comments from review feedback my Maarten. Signed-off-by: Maarten Lankhorst Signed-off-by: Tvrtko Ursulin Cc: Maarten Lankhorst Cc: Daniel Vetter Cc: devel@driverdev.osuosl.org Cc: Riley Andrews Cc: Arve Hjønnevåg Reviewed-by: Jesse Barnes Tested-by: Jesse Barnes Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 13 +++++++++---- drivers/staging/android/sync.h | 10 ++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index e0c1acb2ba69c..78c62dfb39787 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -188,7 +188,7 @@ static void fence_check_cb_func(struct fence *f, struct fence_cb *cb) } /* TODO: implement a create which takes more that one sync_pt */ -struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt) +struct sync_fence *sync_fence_create_dma(const char *name, struct fence *pt) { struct sync_fence *fence; @@ -199,16 +199,21 @@ struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt) fence->num_fences = 1; atomic_set(&fence->status, 1); - fence->cbs[0].sync_pt = &pt->base; + fence->cbs[0].sync_pt = pt; fence->cbs[0].fence = fence; - if (fence_add_callback(&pt->base, &fence->cbs[0].cb, - fence_check_cb_func)) + if (fence_add_callback(pt, &fence->cbs[0].cb, fence_check_cb_func)) atomic_dec(&fence->status); sync_fence_debug_add(fence); return fence; } +EXPORT_SYMBOL(sync_fence_create_dma); + +struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt) +{ + return sync_fence_create_dma(name, &pt->base); +} EXPORT_SYMBOL(sync_fence_create); struct sync_fence *sync_fence_fdget(int fd) diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h index 61f8a3aede96e..afa0752275a72 100644 --- a/drivers/staging/android/sync.h +++ b/drivers/staging/android/sync.h @@ -254,6 +254,16 @@ void sync_pt_free(struct sync_pt *pt); */ struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt); +/** + * sync_fence_create_dma() - creates a sync fence from dma-fence + * @name: name of fence to create + * @pt: dma-fence to add to the fence + * + * Creates a fence containg @pt. Once this is called, the fence takes + * ownership of @pt. + */ +struct sync_fence *sync_fence_create_dma(const char *name, struct fence *pt); + /* * API for sync_fence consumers */ -- GitLab From 699f685569434510d944e419f4048c4e3ba8d631 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 14 Dec 2015 17:34:08 -0800 Subject: [PATCH 1813/2855] android: unconditionally remove callbacks in sync_fence_free() Using fence->status to determine whether or not there are callbacks remaining on the sync_fence is racy since fence->status may have been decremented to 0 on another CPU before fence_check_cb_func() has completed. By unconditionally calling fence_remove_callback() for each fence in the sync_fence, we guarantee that each callback has either completed (since fence_remove_callback() grabs the fence lock) or been removed. Signed-off-by: Andrew Bresticker Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 78c62dfb39787..ed43796b5b582 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -524,12 +524,10 @@ static const struct fence_ops android_fence_ops = { static void sync_fence_free(struct kref *kref) { struct sync_fence *fence = container_of(kref, struct sync_fence, kref); - int i, status = atomic_read(&fence->status); + int i; for (i = 0; i < fence->num_fences; ++i) { - if (status) - fence_remove_callback(fence->cbs[i].sync_pt, - &fence->cbs[i].cb); + fence_remove_callback(fence->cbs[i].sync_pt, &fence->cbs[i].cb); fence_put(fence->cbs[i].sync_pt); } -- GitLab From 323fd785e396f4252b014665df8a831d91c2f117 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Mon, 16 Nov 2015 21:59:24 -0500 Subject: [PATCH 1814/2855] staging/rdma/hfi1: Fix downgrade race A link downgrade can race with link up. Avoid the race in two ways. First, by having the downgrade application logic take the link state mutex for all of its checking. Second, by waiting for the link to move out of the going up state. Reviewed-by: Dennis Dalessandro Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index dc6915947c78d..017d439b327a9 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -3907,18 +3907,32 @@ void handle_verify_cap(struct work_struct *work) */ void apply_link_downgrade_policy(struct hfi1_pportdata *ppd, int refresh_widths) { - int skip = 1; int do_bounce = 0; - u16 lwde = ppd->link_width_downgrade_enabled; + int tries; + u16 lwde; u16 tx, rx; + /* use the hls lock to avoid a race with actual link up */ + tries = 0; +retry: mutex_lock(&ppd->hls_lock); /* only apply if the link is up */ - if (ppd->host_link_state & HLS_UP) - skip = 0; - mutex_unlock(&ppd->hls_lock); - if (skip) - return; + if (!(ppd->host_link_state & HLS_UP)) { + /* still going up..wait and retry */ + if (ppd->host_link_state & HLS_GOING_UP) { + if (++tries < 1000) { + mutex_unlock(&ppd->hls_lock); + usleep_range(100, 120); /* arbitrary */ + goto retry; + } + dd_dev_err(ppd->dd, + "%s: giving up waiting for link state change\n", + __func__); + } + goto done; + } + + lwde = ppd->link_width_downgrade_enabled; if (refresh_widths) { get_link_widths(ppd->dd, &tx, &rx); @@ -3956,6 +3970,9 @@ void apply_link_downgrade_policy(struct hfi1_pportdata *ppd, int refresh_widths) do_bounce = 1; } +done: + mutex_unlock(&ppd->hls_lock); + if (do_bounce) { set_link_down_reason(ppd, OPA_LINKDOWN_REASON_WIDTH_POLICY, 0, OPA_LINKDOWN_REASON_WIDTH_POLICY); -- GitLab From 3d305dbdb272c32455d35b2dadda5ca04548a997 Mon Sep 17 00:00:00 2001 From: Vennila Megavannan Date: Mon, 16 Nov 2015 21:59:25 -0500 Subject: [PATCH 1815/2855] staging/rdma/hfi1: remove RxCtxRHQS from hfi1stats Removed the RxCtxRHQS counter being dumped into dev_cntrs Reviewed-by: Dennis Dalessandro Signed-off-by: Vennila Megavannan Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 2 -- drivers/staging/rdma/hfi1/chip.h | 1 - drivers/staging/rdma/hfi1/chip_registers.h | 1 - 3 files changed, 4 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index 017d439b327a9..0817776d35285 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -1587,8 +1587,6 @@ static struct cntr_entry dev_cntrs[DEV_CNTR_LAST] = { [C_RX_TID_FLGMS] = RXE32_DEV_CNTR_ELEM(RxTidFLGMs, RCV_TID_FLOW_GEN_MISMATCH_CNT, CNTR_NORMAL), -[C_RX_CTX_RHQS] = RXE32_DEV_CNTR_ELEM(RxCtxRHQS, RCV_CONTEXT_RHQ_STALL, - CNTR_NORMAL), [C_RX_CTX_EGRS] = RXE32_DEV_CNTR_ELEM(RxCtxEgrS, RCV_CONTEXT_EGR_STALL, CNTR_NORMAL), [C_RCV_TID_FLSMS] = RXE32_DEV_CNTR_ELEM(RxTidFLSMs, diff --git a/drivers/staging/rdma/hfi1/chip.h b/drivers/staging/rdma/hfi1/chip.h index d74aed8ccc18d..54fc2cd3254fa 100644 --- a/drivers/staging/rdma/hfi1/chip.h +++ b/drivers/staging/rdma/hfi1/chip.h @@ -722,7 +722,6 @@ enum { C_RX_TID_FULL, C_RX_TID_INVALID, C_RX_TID_FLGMS, - C_RX_CTX_RHQS, C_RX_CTX_EGRS, C_RCV_TID_FLSMS, C_CCE_PCI_CR_ST, diff --git a/drivers/staging/rdma/hfi1/chip_registers.h b/drivers/staging/rdma/hfi1/chip_registers.h index bf45de29d8bd7..5056c848af357 100644 --- a/drivers/staging/rdma/hfi1/chip_registers.h +++ b/drivers/staging/rdma/hfi1/chip_registers.h @@ -379,7 +379,6 @@ #define DC_LCB_STS_ROUND_TRIP_LTP_CNT (DC_LCB_CSRS + 0x0000000004B0) #define RCV_BUF_OVFL_CNT 10 #define RCV_CONTEXT_EGR_STALL 22 -#define RCV_CONTEXT_RHQ_STALL 21 #define RCV_DATA_PKT_CNT 0 #define RCV_DWORD_CNT 1 #define RCV_TID_FLOW_GEN_MISMATCH_CNT 20 -- GitLab From db00a055613915f9309a58700517379018e3093f Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Mon, 16 Nov 2015 21:59:26 -0500 Subject: [PATCH 1816/2855] staging/rdma/hfi1: Remove rcv bubbles code Rcv bubbles were improperly calculated for HFIs, fix that here. Reviewed-by: Mike Marciniszyn Reviewed-by: Arthur Kepner Signed-off-by: Ira Weiny Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/mad.c | 64 ++------------------------------- 1 file changed, 2 insertions(+), 62 deletions(-) diff --git a/drivers/staging/rdma/hfi1/mad.c b/drivers/staging/rdma/hfi1/mad.c index a1225651005c1..4bc003f036c09 100644 --- a/drivers/staging/rdma/hfi1/mad.c +++ b/drivers/staging/rdma/hfi1/mad.c @@ -2271,34 +2271,8 @@ static void a0_portstatus(struct hfi1_pportdata *ppd, { if (!is_bx(ppd->dd)) { unsigned long vl; - int vfi = 0; u64 max_vl_xmit_wait = 0, tmp; u32 vl_all_mask = VL_MASK_ALL; - u64 rcv_data, rcv_bubble; - - rcv_data = be64_to_cpu(rsp->port_rcv_data); - rcv_bubble = be64_to_cpu(rsp->port_rcv_bubble); - /* In the measured time period, calculate the total number - * of flits that were received. Subtract out one false - * rcv_bubble increment for every 32 received flits but - * don't let the number go negative. - */ - if (rcv_bubble >= (rcv_data>>5)) { - rcv_bubble -= (rcv_data>>5); - rsp->port_rcv_bubble = cpu_to_be64(rcv_bubble); - } - for_each_set_bit(vl, (unsigned long *)&(vl_select_mask), - 8 * sizeof(vl_select_mask)) { - rcv_data = be64_to_cpu(rsp->vls[vfi].port_vl_rcv_data); - rcv_bubble = - be64_to_cpu(rsp->vls[vfi].port_vl_rcv_bubble); - if (rcv_bubble >= (rcv_data>>5)) { - rcv_bubble -= (rcv_data>>5); - rsp->vls[vfi].port_vl_rcv_bubble = - cpu_to_be64(rcv_bubble); - } - vfi++; - } for_each_set_bit(vl, (unsigned long *)&(vl_all_mask), 8 * sizeof(vl_all_mask)) { @@ -2363,8 +2337,6 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp, CNTR_INVALID_VL)); rsp->port_rcv_data = cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FLITS, CNTR_INVALID_VL)); - rsp->port_rcv_bubble = - cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_BBL, CNTR_INVALID_VL)); rsp->port_xmit_pkts = cpu_to_be64(read_dev_cntr(dd, C_DC_XMIT_PKTS, CNTR_INVALID_VL)); rsp->port_rcv_pkts = cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_PKTS, @@ -2434,9 +2406,6 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp, tmp = read_dev_cntr(dd, C_DC_RX_FLIT_VL, idx_from_vl(vl)); rsp->vls[vfi].port_vl_rcv_data = cpu_to_be64(tmp); - rsp->vls[vfi].port_vl_rcv_bubble = - cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_BBL_VL, - idx_from_vl(vl))); rsp->vls[vfi].port_vl_rcv_pkts = cpu_to_be64(read_dev_cntr(dd, C_DC_RX_PKT_VL, @@ -2519,32 +2488,8 @@ static void a0_datacounters(struct hfi1_devdata *dd, struct _port_dctrs *rsp, if (!is_bx(dd)) { unsigned long vl; int vfi = 0; - u64 rcv_data, rcv_bubble, sum_vl_xmit_wait = 0; - - rcv_data = be64_to_cpu(rsp->port_rcv_data); - rcv_bubble = be64_to_cpu(rsp->port_rcv_bubble); - /* In the measured time period, calculate the total number - * of flits that were received. Subtract out one false - * rcv_bubble increment for every 32 received flits but - * don't let the number go negative. - */ - if (rcv_bubble >= (rcv_data>>5)) { - rcv_bubble -= (rcv_data>>5); - rsp->port_rcv_bubble = cpu_to_be64(rcv_bubble); - } - for_each_set_bit(vl, (unsigned long *)&(vl_select_mask), - 8 * sizeof(vl_select_mask)) { - rcv_data = be64_to_cpu(rsp->vls[vfi].port_vl_rcv_data); - rcv_bubble = - be64_to_cpu(rsp->vls[vfi].port_vl_rcv_bubble); - if (rcv_bubble >= (rcv_data>>5)) { - rcv_bubble -= (rcv_data>>5); - rsp->vls[vfi].port_vl_rcv_bubble = - cpu_to_be64(rcv_bubble); - } - vfi++; - } - vfi = 0; + u64 sum_vl_xmit_wait = 0; + for_each_set_bit(vl, (unsigned long *)&(vl_select_mask), 8 * sizeof(vl_select_mask)) { u64 tmp = sum_vl_xmit_wait + @@ -2635,8 +2580,6 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp, CNTR_INVALID_VL)); rsp->port_rcv_data = cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FLITS, CNTR_INVALID_VL)); - rsp->port_rcv_bubble = - cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_BBL, CNTR_INVALID_VL)); rsp->port_xmit_pkts = cpu_to_be64(read_dev_cntr(dd, C_DC_XMIT_PKTS, CNTR_INVALID_VL)); rsp->port_rcv_pkts = cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_PKTS, @@ -2675,9 +2618,6 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp, rsp->vls[vfi].port_vl_rcv_data = cpu_to_be64(read_dev_cntr(dd, C_DC_RX_FLIT_VL, idx_from_vl(vl))); - rsp->vls[vfi].port_vl_rcv_bubble = - cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_BBL_VL, - idx_from_vl(vl))); rsp->vls[vfi].port_vl_xmit_pkts = cpu_to_be64(read_port_cntr(ppd, C_TX_PKT_VL, -- GitLab From 9805071e76de29914ecb6ce17136ff83647e7744 Mon Sep 17 00:00:00 2001 From: Jubin John Date: Mon, 16 Nov 2015 21:59:27 -0500 Subject: [PATCH 1817/2855] staging/rdma/hfi1: Add space between concatenated string elements Space between concantenated string elements is more human readable and fixes the checkpatch issue: CHECK: Concatenated strings should use spaces between elements Reviewed-by: Mike Marciniszyn Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 10 +++++----- drivers/staging/rdma/hfi1/driver.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index 0817776d35285..f89f38d8a2b7f 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -8903,8 +8903,8 @@ static int request_intx_irq(struct hfi1_devdata *dd) { int ret; - snprintf(dd->intx_name, sizeof(dd->intx_name), DRIVER_NAME"_%d", - dd->unit); + snprintf(dd->intx_name, sizeof(dd->intx_name), DRIVER_NAME "_%d", + dd->unit); ret = request_irq(dd->pcidev->irq, general_interrupt, IRQF_SHARED, dd->intx_name, dd); if (ret) @@ -9003,7 +9003,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd) handler = general_interrupt; arg = dd; snprintf(me->name, sizeof(me->name), - DRIVER_NAME"_%d", dd->unit); + DRIVER_NAME "_%d", dd->unit); err_info = "general"; } else if (first_sdma <= i && i < last_sdma) { idx = i - first_sdma; @@ -9011,7 +9011,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd) handler = sdma_interrupt; arg = sde; snprintf(me->name, sizeof(me->name), - DRIVER_NAME"_%d sdma%d", dd->unit, idx); + DRIVER_NAME "_%d sdma%d", dd->unit, idx); err_info = "sdma"; remap_sdma_interrupts(dd, idx, i); } else if (first_rx <= i && i < last_rx) { @@ -9031,7 +9031,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd) thread = receive_context_thread; arg = rcd; snprintf(me->name, sizeof(me->name), - DRIVER_NAME"_%d kctxt%d", dd->unit, idx); + DRIVER_NAME "_%d kctxt%d", dd->unit, idx); err_info = "receive context"; remap_intr(dd, IS_RCVAVAIL_START + idx, i); } else { diff --git a/drivers/staging/rdma/hfi1/driver.c b/drivers/staging/rdma/hfi1/driver.c index 4c52e785de68e..745817ea42e24 100644 --- a/drivers/staging/rdma/hfi1/driver.c +++ b/drivers/staging/rdma/hfi1/driver.c @@ -158,7 +158,7 @@ const char *get_unit_name(int unit) { static char iname[16]; - snprintf(iname, sizeof(iname), DRIVER_NAME"_%u", unit); + snprintf(iname, sizeof(iname), DRIVER_NAME "_%u", unit); return iname; } -- GitLab From 995deafaff78e898a9d9867ac11c3a81e554f1d1 Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Mon, 16 Nov 2015 21:59:29 -0500 Subject: [PATCH 1818/2855] staging/rdma/hfi1: rework is_a0() and is_bx() The current is_bx() will incorrectly match on other steppings. is_a0() is removed in favor of is_ax(). Reviewed-by: Mark Debbage Signed-off-by: Mike Marciniszyn Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 44 ++++++++++++---------------- drivers/staging/rdma/hfi1/chip.h | 1 - drivers/staging/rdma/hfi1/firmware.c | 2 +- drivers/staging/rdma/hfi1/hfi.h | 4 +-- drivers/staging/rdma/hfi1/init.c | 2 +- drivers/staging/rdma/hfi1/pcie.c | 4 +-- 6 files changed, 24 insertions(+), 33 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index f89f38d8a2b7f..3235324659ba2 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -1871,13 +1871,6 @@ static struct cntr_entry port_cntrs[PORT_CNTR_LAST] = { /* ======================================================================== */ -/* return true if this is chip revision revision a0 */ -int is_a0(struct hfi1_devdata *dd) -{ - return ((dd->revision >> CCE_REVISION_CHIP_REV_MINOR_SHIFT) - & CCE_REVISION_CHIP_REV_MINOR_MASK) == 0; -} - /* return true if this is chip revision revision a */ int is_ax(struct hfi1_devdata *dd) { @@ -1893,7 +1886,7 @@ int is_bx(struct hfi1_devdata *dd) u8 chip_rev_minor = dd->revision >> CCE_REVISION_CHIP_REV_MINOR_SHIFT & CCE_REVISION_CHIP_REV_MINOR_MASK; - return !!(chip_rev_minor & 0x10); + return (chip_rev_minor & 0xF0) == 0x10; } /* @@ -2188,9 +2181,8 @@ static void handle_cce_err(struct hfi1_devdata *dd, u32 unused, u64 reg) dd_dev_info(dd, "CCE Error: %s\n", cce_err_status_string(buf, sizeof(buf), reg)); - if ((reg & CCE_ERR_STATUS_CCE_CLI2_ASYNC_FIFO_PARITY_ERR_SMASK) - && is_a0(dd) - && (dd->icode != ICODE_FUNCTIONAL_SIMULATOR)) { + if ((reg & CCE_ERR_STATUS_CCE_CLI2_ASYNC_FIFO_PARITY_ERR_SMASK) && + is_ax(dd) && (dd->icode != ICODE_FUNCTIONAL_SIMULATOR)) { /* this error requires a manual drop into SPC freeze mode */ /* then a fix up */ start_freeze_handling(dd->pport, FREEZE_SELF); @@ -2250,7 +2242,7 @@ static void handle_rxe_err(struct hfi1_devdata *dd, u32 unused, u64 reg) * Freeze mode recovery is disabled for the errors * in RXE_FREEZE_ABORT_MASK */ - if (is_a0(dd) && (reg & RXE_FREEZE_ABORT_MASK)) + if (is_ax(dd) && (reg & RXE_FREEZE_ABORT_MASK)) flags = FREEZE_ABORT; start_freeze_handling(dd->pport, flags); @@ -2353,7 +2345,7 @@ static void handle_egress_err(struct hfi1_devdata *dd, u32 unused, u64 reg) if (reg & ALL_TXE_EGRESS_FREEZE_ERR) start_freeze_handling(dd->pport, 0); - if (is_a0(dd) && (reg & + if (is_ax(dd) && (reg & SEND_EGRESS_ERR_STATUS_TX_CREDIT_RETURN_VL_ERR_SMASK) && (dd->icode != ICODE_FUNCTIONAL_SIMULATOR)) start_freeze_handling(dd->pport, 0); @@ -3048,7 +3040,7 @@ static void adjust_lcb_for_fpga_serdes(struct hfi1_devdata *dd) /* else this is _p */ version = emulator_rev(dd); - if (!is_a0(dd)) + if (!is_ax(dd)) version = 0x2d; /* all B0 use 0x2d or higher settings */ if (version <= 0x12) { @@ -3334,7 +3326,7 @@ void handle_freeze(struct work_struct *work) write_csr(dd, CCE_CTRL, CCE_CTRL_SPC_UNFREEZE_SMASK); wait_for_freeze_status(dd, 0); - if (is_a0(dd)) { + if (is_ax(dd)) { write_csr(dd, CCE_CTRL, CCE_CTRL_SPC_FREEZE_SMASK); wait_for_freeze_status(dd, 1); write_csr(dd, CCE_CTRL, CCE_CTRL_SPC_UNFREEZE_SMASK); @@ -3862,7 +3854,7 @@ void handle_verify_cap(struct work_struct *work) * REPLAY_BUF_MBE_SMASK * FLIT_INPUT_BUF_MBE_SMASK */ - if (is_a0(dd)) { /* fixed in B0 */ + if (is_ax(dd)) { /* fixed in B0 */ reg = read_csr(dd, DC_LCB_CFG_LINK_KILL_EN); reg |= DC_LCB_CFG_LINK_KILL_EN_REPLAY_BUF_MBE_SMASK | DC_LCB_CFG_LINK_KILL_EN_FLIT_INPUT_BUF_MBE_SMASK; @@ -7329,8 +7321,8 @@ static int set_buffer_control(struct hfi1_devdata *dd, */ use_all_mask = 0; if ((be16_to_cpu(new_bc->overall_shared_limit) < - be16_to_cpu(cur_bc.overall_shared_limit)) - || (is_a0(dd) && any_shared_limit_changing)) { + be16_to_cpu(cur_bc.overall_shared_limit)) || + (is_ax(dd) && any_shared_limit_changing)) { set_global_shared(dd, 0); cur_bc.overall_shared_limit = 0; use_all_mask = 1; @@ -7504,7 +7496,7 @@ int fm_set_table(struct hfi1_pportdata *ppd, int which, void *t) */ static int disable_data_vls(struct hfi1_devdata *dd) { - if (is_a0(dd)) + if (is_ax(dd)) return 1; pio_send_control(dd, PSC_DATA_VL_DISABLE); @@ -7522,7 +7514,7 @@ static int disable_data_vls(struct hfi1_devdata *dd) */ int open_fill_data_vls(struct hfi1_devdata *dd) { - if (is_a0(dd)) + if (is_ax(dd)) return 1; pio_send_control(dd, PSC_DATA_VL_ENABLE); @@ -9972,7 +9964,7 @@ static void init_chip(struct hfi1_devdata *dd) /* restore command and BARs */ restore_pci_variables(dd); - if (is_a0(dd)) { + if (is_ax(dd)) { dd_dev_info(dd, "Resetting CSRs with FLR\n"); hfi1_pcie_flr(dd); restore_pci_variables(dd); @@ -9991,7 +9983,7 @@ static void init_chip(struct hfi1_devdata *dd) write_csr(dd, CCE_DC_CTRL, 0); /* Set the LED off */ - if (is_a0(dd)) + if (is_ax(dd)) setextled(dd, 0); /* * Clear the QSFP reset. @@ -10014,7 +10006,7 @@ static void init_early_variables(struct hfi1_devdata *dd) /* assign link credit variables */ dd->vau = CM_VAU; dd->link_credits = CM_GLOBAL_CREDITS; - if (is_a0(dd)) + if (is_ax(dd)) dd->link_credits--; dd->vcu = cu_to_vcu(hfi1_cu); /* enough room for 8 MAD packets plus header - 17K */ @@ -10122,7 +10114,7 @@ static void init_qos(struct hfi1_devdata *dd, u32 first_ctxt) unsigned qpns_per_vl, ctxt, i, qpn, n = 1, m; u64 *rsmmap; u64 reg; - u8 rxcontext = is_a0(dd) ? 0 : 0xff; /* 0 is default if a0 ver. */ + u8 rxcontext = is_ax(dd) ? 0 : 0xff; /* 0 is default if a0 ver. */ /* validate */ if (dd->n_krcv_queues <= MIN_KERNEL_KCTXTS || @@ -10327,7 +10319,7 @@ int hfi1_set_ctxt_jkey(struct hfi1_devdata *dd, unsigned ctxt, u16 jkey) * Enable send-side J_KEY integrity check, unless this is A0 h/w * (due to A0 erratum). */ - if (!is_a0(dd)) { + if (!is_ax(dd)) { reg = read_kctxt_csr(dd, sctxt, SEND_CTXT_CHECK_ENABLE); reg |= SEND_CTXT_CHECK_ENABLE_CHECK_JOB_KEY_SMASK; write_kctxt_csr(dd, sctxt, SEND_CTXT_CHECK_ENABLE, reg); @@ -10360,7 +10352,7 @@ int hfi1_clear_ctxt_jkey(struct hfi1_devdata *dd, unsigned ctxt) * This check would not have been enabled for A0 h/w, see * set_ctxt_jkey(). */ - if (!is_a0(dd)) { + if (!is_ax(dd)) { reg = read_kctxt_csr(dd, sctxt, SEND_CTXT_CHECK_ENABLE); reg &= ~SEND_CTXT_CHECK_ENABLE_CHECK_JOB_KEY_SMASK; write_kctxt_csr(dd, sctxt, SEND_CTXT_CHECK_ENABLE, reg); diff --git a/drivers/staging/rdma/hfi1/chip.h b/drivers/staging/rdma/hfi1/chip.h index 54fc2cd3254fa..177862b9230b7 100644 --- a/drivers/staging/rdma/hfi1/chip.h +++ b/drivers/staging/rdma/hfi1/chip.h @@ -664,7 +664,6 @@ void get_linkup_link_widths(struct hfi1_pportdata *ppd); void read_ltp_rtt(struct hfi1_devdata *dd); void clear_linkup_counters(struct hfi1_devdata *dd); u32 hdrqempty(struct hfi1_ctxtdata *rcd); -int is_a0(struct hfi1_devdata *dd); int is_ax(struct hfi1_devdata *dd); int is_bx(struct hfi1_devdata *dd); u32 read_physical_state(struct hfi1_devdata *dd); diff --git a/drivers/staging/rdma/hfi1/firmware.c b/drivers/staging/rdma/hfi1/firmware.c index f3112821cf475..938b97c040e6a 100644 --- a/drivers/staging/rdma/hfi1/firmware.c +++ b/drivers/staging/rdma/hfi1/firmware.c @@ -951,7 +951,7 @@ void sbus_request(struct hfi1_devdata *dd, static void turn_off_spicos(struct hfi1_devdata *dd, int flags) { /* only needed on A0 */ - if (!is_a0(dd)) + if (!is_ax(dd)) return; dd_dev_info(dd, "Turning off spicos:%s%s\n", diff --git a/drivers/staging/rdma/hfi1/hfi.h b/drivers/staging/rdma/hfi1/hfi.h index 54ed6b36c1a78..98db0fe4d0f0e 100644 --- a/drivers/staging/rdma/hfi1/hfi.h +++ b/drivers/staging/rdma/hfi1/hfi.h @@ -1693,7 +1693,7 @@ static inline u64 hfi1_pkt_default_send_ctxt_mask(struct hfi1_devdata *dd, else base_sc_integrity |= HFI1_PKT_KERNEL_SC_INTEGRITY; - if (is_a0(dd)) + if (is_ax(dd)) /* turn off send-side job key checks - A0 erratum */ return base_sc_integrity & ~SEND_CTXT_CHECK_ENABLE_CHECK_JOB_KEY_SMASK; @@ -1720,7 +1720,7 @@ static inline u64 hfi1_pkt_base_sdma_integrity(struct hfi1_devdata *dd) | SEND_DMA_CHECK_ENABLE_CHECK_VL_SMASK | SEND_DMA_CHECK_ENABLE_CHECK_ENABLE_SMASK; - if (is_a0(dd)) + if (is_ax(dd)) /* turn off send-side job key checks - A0 erratum */ return base_sdma_integrity & ~SEND_DMA_CHECK_ENABLE_CHECK_JOB_KEY_SMASK; diff --git a/drivers/staging/rdma/hfi1/init.c b/drivers/staging/rdma/hfi1/init.c index 1c8286f4c00ca..52fa86f47186f 100644 --- a/drivers/staging/rdma/hfi1/init.c +++ b/drivers/staging/rdma/hfi1/init.c @@ -678,7 +678,7 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit) dd->process_dma_send = hfi1_verbs_send_dma; dd->pio_inline_send = pio_copy; - if (is_a0(dd)) { + if (is_ax(dd)) { atomic_set(&dd->drop_packet, DROP_PACKET_ON); dd->do_drop = 1; } else { diff --git a/drivers/staging/rdma/hfi1/pcie.c b/drivers/staging/rdma/hfi1/pcie.c index 0b7eafb0fc705..8317b07d722a5 100644 --- a/drivers/staging/rdma/hfi1/pcie.c +++ b/drivers/staging/rdma/hfi1/pcie.c @@ -917,7 +917,7 @@ int do_pcie_gen3_transition(struct hfi1_devdata *dd) /* * A0 needs an additional SBR */ - if (is_a0(dd)) + if (is_ax(dd)) nsbr++; /* @@ -1193,7 +1193,7 @@ retry: write_csr(dd, CCE_DC_CTRL, 0); /* Set the LED off */ - if (is_a0(dd)) + if (is_ax(dd)) setextled(dd, 0); /* check for any per-lane errors */ -- GitLab From 5d9157aafb16bed45e3bf167baa16f1fbe1090cd Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Mon, 16 Nov 2015 21:59:34 -0500 Subject: [PATCH 1819/2855] staging/rdma/hfi1: Read EFI variable for device description Read an EFI variable for the device description. Create the infrastructure for additional variable reads. Reviewed-by: Easwar Hariharan Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/Makefile | 2 +- drivers/staging/rdma/hfi1/chip.c | 38 +++++-- drivers/staging/rdma/hfi1/efivar.c | 169 +++++++++++++++++++++++++++++ drivers/staging/rdma/hfi1/efivar.h | 60 ++++++++++ 4 files changed, 260 insertions(+), 9 deletions(-) create mode 100644 drivers/staging/rdma/hfi1/efivar.c create mode 100644 drivers/staging/rdma/hfi1/efivar.h diff --git a/drivers/staging/rdma/hfi1/Makefile b/drivers/staging/rdma/hfi1/Makefile index 2e5daa6cdcc26..68c5a315e557f 100644 --- a/drivers/staging/rdma/hfi1/Makefile +++ b/drivers/staging/rdma/hfi1/Makefile @@ -7,7 +7,7 @@ # obj-$(CONFIG_INFINIBAND_HFI1) += hfi1.o -hfi1-y := chip.o cq.o device.o diag.o dma.o driver.o eprom.o file_ops.o firmware.o \ +hfi1-y := chip.o cq.o device.o diag.o dma.o driver.o efivar.o eprom.o file_ops.o firmware.o \ init.o intr.o keys.o mad.o mmap.o mr.o pcie.o pio.o pio_copy.o \ qp.o qsfp.o rc.o ruc.o sdma.o srq.o sysfs.o trace.o twsi.o \ uc.o ud.o user_pages.o user_sdma.o verbs_mcast.o verbs.o diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index 3235324659ba2..bcbd831d2b73c 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -63,6 +63,7 @@ #include "pio.h" #include "sdma.h" #include "eprom.h" +#include "efivar.h" #define NUM_IB_PORTS 1 @@ -10461,6 +10462,32 @@ static void asic_should_init(struct hfi1_devdata *dd) spin_unlock_irqrestore(&hfi1_devs_lock, flags); } +/* + * Set dd->boardname. Use a generic name if a name is not returned from + * EFI variable space. + * + * Return 0 on success, -ENOMEM if space could not be allocated. + */ +static int obtain_boardname(struct hfi1_devdata *dd) +{ + /* generic board description */ + const char generic[] = + "Intel Omni-Path Host Fabric Interface Adapter 100 Series"; + unsigned long size; + int ret; + + ret = read_hfi1_efi_var(dd, "description", &size, + (void **)&dd->boardname); + if (ret) { + dd_dev_err(dd, "Board description not found\n"); + /* use generic description */ + dd->boardname = kstrdup(generic, GFP_KERNEL); + if (!dd->boardname) + return -ENOMEM; + } + return 0; +} + /** * Allocate and initialize the device structure for the hfi. * @dev: the pci_dev for hfi1_ib device @@ -10658,18 +10685,13 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev, parse_platform_config(dd); - /* add board names as they are defined */ - dd->boardname = kmalloc(64, GFP_KERNEL); - if (!dd->boardname) + ret = obtain_boardname(dd); + if (ret) goto bail_cleanup; - snprintf(dd->boardname, 64, "Board ID 0x%llx", - dd->revision >> CCE_REVISION_BOARD_ID_LOWER_NIBBLE_SHIFT - & CCE_REVISION_BOARD_ID_LOWER_NIBBLE_MASK); snprintf(dd->boardversion, BOARD_VERS_MAX, - "ChipABI %u.%u, %s, ChipRev %u.%u, SW Compat %llu\n", + "ChipABI %u.%u, ChipRev %u.%u, SW Compat %llu\n", HFI1_CHIP_VERS_MAJ, HFI1_CHIP_VERS_MIN, - dd->boardname, (u32)dd->majrev, (u32)dd->minrev, (dd->revision >> CCE_REVISION_SW_SHIFT) diff --git a/drivers/staging/rdma/hfi1/efivar.c b/drivers/staging/rdma/hfi1/efivar.c new file mode 100644 index 0000000000000..7dc5bae220e08 --- /dev/null +++ b/drivers/staging/rdma/hfi1/efivar.c @@ -0,0 +1,169 @@ +/* + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2015 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * BSD LICENSE + * + * Copyright(c) 2015 Intel Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "efivar.h" + +/* GUID for HFI1 variables in EFI */ +#define HFI1_EFIVAR_GUID EFI_GUID(0xc50a953e, 0xa8b2, 0x42a6, \ + 0xbf, 0x89, 0xd3, 0x33, 0xa6, 0xe9, 0xe6, 0xd4) +/* largest EFI data size we expect */ +#define EFI_DATA_SIZE 4096 + +/* + * Read the named EFI variable. Return the size of the actual data in *size + * and a kmalloc'ed buffer in *return_data. The caller must free the + * data. It is guaranteed that *return_data will be NULL and *size = 0 + * if this routine fails. + * + * Return 0 on success, -errno on failure. + */ +static int read_efi_var(const char *name, unsigned long *size, + void **return_data) +{ + efi_status_t status; + efi_char16_t *uni_name; + efi_guid_t guid; + unsigned long temp_size; + void *temp_buffer; + void *data; + int i; + int ret; + + /* set failure return values */ + *size = 0; + *return_data = NULL; + + if (!efi_enabled(EFI_RUNTIME_SERVICES)) + return -EOPNOTSUPP; + + uni_name = kzalloc(sizeof(efi_char16_t) * (strlen(name) + 1), + GFP_KERNEL); + temp_buffer = kzalloc(EFI_DATA_SIZE, GFP_KERNEL); + + if (!uni_name || !temp_buffer) { + ret = -ENOMEM; + goto fail; + } + + /* input: the size of the buffer */ + temp_size = EFI_DATA_SIZE; + + /* convert ASCII to unicode - it is a 1:1 mapping */ + for (i = 0; name[i]; i++) + uni_name[i] = name[i]; + + /* need a variable for our GUID */ + guid = HFI1_EFIVAR_GUID; + + /* call into EFI runtime services */ + status = efi.get_variable( + uni_name, + &guid, + NULL, + &temp_size, + temp_buffer); + + /* + * It would be nice to call efi_status_to_err() here, but that + * is in the EFIVAR_FS code and may not be compiled in. + * However, even that is insufficient since it does not cover + * EFI_BUFFER_TOO_SMALL which could be an important return. + * For now, just split out succces or not found. + */ + ret = status == EFI_SUCCESS ? 0 : + status == EFI_NOT_FOUND ? -ENOENT : + -EINVAL; + if (ret) + goto fail; + + /* + * We have successfully read the EFI variable into our + * temporary buffer. Now allocate a correctly sized + * buffer. + */ + data = kmalloc(temp_size, GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto fail; + } + + memcpy(data, temp_buffer, temp_size); + *size = temp_size; + *return_data = data; + +fail: + kfree(uni_name); + kfree(temp_buffer); + + return ret; +} + +/* + * Read an HFI1 EFI variable of the form: + * - + * Return an kalloc'ed array and size of the data. + * + * Returns 0 on success, -errno on failure. + */ +int read_hfi1_efi_var(struct hfi1_devdata *dd, const char *kind, + unsigned long *size, void **return_data) +{ + char name[64]; + + /* create a common prefix */ + snprintf(name, sizeof(name), "%04x:%02x:%02x.%x-%s", + pci_domain_nr(dd->pcidev->bus), + dd->pcidev->bus->number, + PCI_SLOT(dd->pcidev->devfn), + PCI_FUNC(dd->pcidev->devfn), + kind); + + return read_efi_var(name, size, return_data); +} diff --git a/drivers/staging/rdma/hfi1/efivar.h b/drivers/staging/rdma/hfi1/efivar.h new file mode 100644 index 0000000000000..070706225c514 --- /dev/null +++ b/drivers/staging/rdma/hfi1/efivar.h @@ -0,0 +1,60 @@ +/* + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2015 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * BSD LICENSE + * + * Copyright(c) 2015 Intel Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef _HFI1_EFIVAR_H +#define _HFI1_EFIVAR_H + +#include + +#include "hfi.h" + +int read_hfi1_efi_var(struct hfi1_devdata *dd, const char *kind, + unsigned long *size, void **return_data); + +#endif /* _HFI1_EFIVAR_H */ -- GitLab From cd371e0959a3f2d5df69d50000750f7eefc94659 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Mon, 16 Nov 2015 21:59:35 -0500 Subject: [PATCH 1820/2855] staging/rdma/hfi1: Adjust EPROM partitions, add EPROM commands Add a new EPROM partition, adjusting partition placement. Add EPROM range commands as a supserset of the partition commands. Remove old partition commands. Enhance EPROM erase, creating a range function and using the largest erase (sub) commands when possible. Reviewed-by: Dennis Dalessandro Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/eprom.c | 119 +++++++++++++++------------ drivers/staging/rdma/hfi1/file_ops.c | 18 ++-- include/uapi/rdma/hfi/hfi1_user.h | 10 +-- 3 files changed, 77 insertions(+), 70 deletions(-) diff --git a/drivers/staging/rdma/hfi1/eprom.c b/drivers/staging/rdma/hfi1/eprom.c index b61d3ae93ed13..fb620c97f592d 100644 --- a/drivers/staging/rdma/hfi1/eprom.c +++ b/drivers/staging/rdma/hfi1/eprom.c @@ -53,17 +53,26 @@ #include "eprom.h" /* - * The EPROM is logically divided into two partitions: + * The EPROM is logically divided into three partitions: * partition 0: the first 128K, visible from PCI ROM BAR - * partition 1: the rest + * partition 1: 4K config file (sector size) + * partition 2: the rest */ #define P0_SIZE (128 * 1024) +#define P1_SIZE (4 * 1024) #define P1_START P0_SIZE +#define P2_START (P0_SIZE + P1_SIZE) + +/* erase sizes supported by the controller */ +#define SIZE_4KB (4 * 1024) +#define MASK_4KB (SIZE_4KB - 1) -/* largest erase size supported by the controller */ #define SIZE_32KB (32 * 1024) #define MASK_32KB (SIZE_32KB - 1) +#define SIZE_64KB (64 * 1024) +#define MASK_64KB (SIZE_64KB - 1) + /* controller page size, in bytes */ #define EP_PAGE_SIZE 256 #define EEP_PAGE_MASK (EP_PAGE_SIZE - 1) @@ -75,10 +84,12 @@ #define CMD_READ_DATA(addr) ((0x03 << CMD_SHIFT) | addr) #define CMD_READ_SR1 ((0x05 << CMD_SHIFT)) #define CMD_WRITE_ENABLE ((0x06 << CMD_SHIFT)) +#define CMD_SECTOR_ERASE_4KB(addr) ((0x20 << CMD_SHIFT) | addr) #define CMD_SECTOR_ERASE_32KB(addr) ((0x52 << CMD_SHIFT) | addr) #define CMD_CHIP_ERASE ((0x60 << CMD_SHIFT)) #define CMD_READ_MANUF_DEV_ID ((0x90 << CMD_SHIFT)) #define CMD_RELEASE_POWERDOWN_NOID ((0xab << CMD_SHIFT)) +#define CMD_SECTOR_ERASE_64KB(addr) ((0xd8 << CMD_SHIFT) | addr) /* controller interface speeds */ #define EP_SPEED_FULL 0x2 /* full speed */ @@ -188,28 +199,43 @@ static int erase_chip(struct hfi1_devdata *dd) } /* - * Erase a range using the 32KB erase command. + * Erase a range. */ -static int erase_32kb_range(struct hfi1_devdata *dd, u32 start, u32 end) +static int erase_range(struct hfi1_devdata *dd, u32 start, u32 len) { + u32 end = start + len; int ret = 0; if (end < start) return -EINVAL; - if ((start & MASK_32KB) || (end & MASK_32KB)) { + /* check the end points for the minimum erase */ + if ((start & MASK_4KB) || (end & MASK_4KB)) { dd_dev_err(dd, - "%s: non-aligned range (0x%x,0x%x) for a 32KB erase\n", + "%s: non-aligned range (0x%x,0x%x) for a 4KB erase\n", __func__, start, end); return -EINVAL; } write_enable(dd); - for (; start < end; start += SIZE_32KB) { + while (start < end) { write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_WRITE_ENABLE); - write_csr(dd, ASIC_EEP_ADDR_CMD, - CMD_SECTOR_ERASE_32KB(start)); + /* check in order of largest to smallest */ + if (((start & MASK_64KB) == 0) && (start + SIZE_64KB <= end)) { + write_csr(dd, ASIC_EEP_ADDR_CMD, + CMD_SECTOR_ERASE_64KB(start)); + start += SIZE_64KB; + } else if (((start & MASK_32KB) == 0) && + (start + SIZE_32KB <= end)) { + write_csr(dd, ASIC_EEP_ADDR_CMD, + CMD_SECTOR_ERASE_32KB(start)); + start += SIZE_32KB; + } else { /* 4KB will work */ + write_csr(dd, ASIC_EEP_ADDR_CMD, + CMD_SECTOR_ERASE_4KB(start)); + start += SIZE_4KB; + } ret = wait_for_not_busy(dd); if (ret) goto done; @@ -309,6 +335,18 @@ done: return ret; } +/* convert an range composite to a length, in bytes */ +static inline u32 extract_rlen(u32 composite) +{ + return (composite & 0xffff) * EP_PAGE_SIZE; +} + +/* convert an range composite to a start, in bytes */ +static inline u32 extract_rstart(u32 composite) +{ + return (composite >> 16) * EP_PAGE_SIZE; +} + /* * Perform the given operation on the EPROM. Called from user space. The * user credentials have already been checked. @@ -319,6 +357,8 @@ int handle_eprom_command(const struct hfi1_cmd *cmd) { struct hfi1_devdata *dd; u32 dev_id; + u32 rlen; /* range length */ + u32 rstart; /* range start */ int ret = 0; /* @@ -364,54 +404,29 @@ int handle_eprom_command(const struct hfi1_cmd *cmd) sizeof(u32))) ret = -EFAULT; break; + case HFI1_CMD_EP_ERASE_CHIP: ret = erase_chip(dd); break; - case HFI1_CMD_EP_ERASE_P0: - if (cmd->len != P0_SIZE) { - ret = -ERANGE; - break; - } - ret = erase_32kb_range(dd, 0, cmd->len); - break; - case HFI1_CMD_EP_ERASE_P1: - /* check for overflow */ - if (P1_START + cmd->len > ASIC_EEP_ADDR_CMD_EP_ADDR_MASK) { - ret = -ERANGE; - break; - } - ret = erase_32kb_range(dd, P1_START, P1_START + cmd->len); - break; - case HFI1_CMD_EP_READ_P0: - if (cmd->len != P0_SIZE) { - ret = -ERANGE; - break; - } - ret = read_length(dd, 0, cmd->len, cmd->addr); - break; - case HFI1_CMD_EP_READ_P1: - /* check for overflow */ - if (P1_START + cmd->len > ASIC_EEP_ADDR_CMD_EP_ADDR_MASK) { - ret = -ERANGE; - break; - } - ret = read_length(dd, P1_START, cmd->len, cmd->addr); + + case HFI1_CMD_EP_ERASE_RANGE: + rlen = extract_rlen(cmd->len); + rstart = extract_rstart(cmd->len); + ret = erase_range(dd, rstart, rlen); break; - case HFI1_CMD_EP_WRITE_P0: - if (cmd->len > P0_SIZE) { - ret = -ERANGE; - break; - } - ret = write_length(dd, 0, cmd->len, cmd->addr); + + case HFI1_CMD_EP_READ_RANGE: + rlen = extract_rlen(cmd->len); + rstart = extract_rstart(cmd->len); + ret = read_length(dd, rstart, rlen, cmd->addr); break; - case HFI1_CMD_EP_WRITE_P1: - /* check for overflow */ - if (P1_START + cmd->len > ASIC_EEP_ADDR_CMD_EP_ADDR_MASK) { - ret = -ERANGE; - break; - } - ret = write_length(dd, P1_START, cmd->len, cmd->addr); + + case HFI1_CMD_EP_WRITE_RANGE: + rlen = extract_rlen(cmd->len); + rstart = extract_rstart(cmd->len); + ret = write_length(dd, rstart, rlen, cmd->addr); break; + default: dd_dev_err(dd, "%s: unexpected command %d\n", __func__, cmd->type); diff --git a/drivers/staging/rdma/hfi1/file_ops.c b/drivers/staging/rdma/hfi1/file_ops.c index 22037ce984c83..874305f0a9256 100644 --- a/drivers/staging/rdma/hfi1/file_ops.c +++ b/drivers/staging/rdma/hfi1/file_ops.c @@ -234,12 +234,9 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data, break; case HFI1_CMD_EP_INFO: case HFI1_CMD_EP_ERASE_CHIP: - case HFI1_CMD_EP_ERASE_P0: - case HFI1_CMD_EP_ERASE_P1: - case HFI1_CMD_EP_READ_P0: - case HFI1_CMD_EP_READ_P1: - case HFI1_CMD_EP_WRITE_P0: - case HFI1_CMD_EP_WRITE_P1: + case HFI1_CMD_EP_ERASE_RANGE: + case HFI1_CMD_EP_READ_RANGE: + case HFI1_CMD_EP_WRITE_RANGE: uctxt_required = 0; /* assigned user context not required */ must_be_root = 1; /* validate user */ copy = 0; @@ -393,12 +390,9 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data, } case HFI1_CMD_EP_INFO: case HFI1_CMD_EP_ERASE_CHIP: - case HFI1_CMD_EP_ERASE_P0: - case HFI1_CMD_EP_ERASE_P1: - case HFI1_CMD_EP_READ_P0: - case HFI1_CMD_EP_READ_P1: - case HFI1_CMD_EP_WRITE_P0: - case HFI1_CMD_EP_WRITE_P1: + case HFI1_CMD_EP_ERASE_RANGE: + case HFI1_CMD_EP_READ_RANGE: + case HFI1_CMD_EP_WRITE_RANGE: ret = handle_eprom_command(&cmd); break; } diff --git a/include/uapi/rdma/hfi/hfi1_user.h b/include/uapi/rdma/hfi/hfi1_user.h index a2fc6cbfe4141..288694e422fba 100644 --- a/include/uapi/rdma/hfi/hfi1_user.h +++ b/include/uapi/rdma/hfi/hfi1_user.h @@ -137,12 +137,10 @@ /* separate EPROM commands from normal PSM commands */ #define HFI1_CMD_EP_INFO 64 /* read EPROM device ID */ #define HFI1_CMD_EP_ERASE_CHIP 65 /* erase whole EPROM */ -#define HFI1_CMD_EP_ERASE_P0 66 /* erase EPROM partition 0 */ -#define HFI1_CMD_EP_ERASE_P1 67 /* erase EPROM partition 1 */ -#define HFI1_CMD_EP_READ_P0 68 /* read EPROM partition 0 */ -#define HFI1_CMD_EP_READ_P1 69 /* read EPROM partition 1 */ -#define HFI1_CMD_EP_WRITE_P0 70 /* write EPROM partition 0 */ -#define HFI1_CMD_EP_WRITE_P1 71 /* write EPROM partition 1 */ +/* range 66-74 no longer used */ +#define HFI1_CMD_EP_ERASE_RANGE 75 /* erase EPROM range */ +#define HFI1_CMD_EP_READ_RANGE 76 /* read EPROM range */ +#define HFI1_CMD_EP_WRITE_RANGE 77 /* write EPROM range */ #define _HFI1_EVENT_FROZEN_BIT 0 #define _HFI1_EVENT_LINKDOWN_BIT 1 -- GitLab From 9d2f53ef42c15f6e47b48246beb0a32c4ff3b3ed Mon Sep 17 00:00:00 2001 From: Jubin John Date: Fri, 20 Nov 2015 18:13:08 -0500 Subject: [PATCH 1821/2855] staging/rdma/hfi1: Fix error in hfi1 driver build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hfi1 driver build fails with the following error: In function ‘handle_receive_interrupt’: error: implicit declaration of function ‘skip_rcv_packet’ [-Werror=implicit-function-declaration] last = skip_rcv_packet(&packet, thread); ^ This is due to the inclusion of the skip_rcv_packet() in the CONFIG_PRESCAN_RXQ ifdef block. This function is independent of CONFIG_PRESCAN_RXQ and should be outside this block. Fixes: 82c2611daaf0 ("staging/rdma/hfi1: Handle packets with invalid RHF on context 0") Reviewed-by: Mike Marciniszyn Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rdma/hfi1/driver.c b/drivers/staging/rdma/hfi1/driver.c index 745817ea42e24..8485de1fce086 100644 --- a/drivers/staging/rdma/hfi1/driver.c +++ b/drivers/staging/rdma/hfi1/driver.c @@ -633,6 +633,7 @@ next: update_ps_mdata(&mdata, rcd); } } +#endif /* CONFIG_PRESCAN_RXQ */ static inline int skip_rcv_packet(struct hfi1_packet *packet, int thread) { @@ -659,7 +660,6 @@ static inline int skip_rcv_packet(struct hfi1_packet *packet, int thread) return ret; } -#endif /* CONFIG_PRESCAN_RXQ */ static inline int process_rcv_packet(struct hfi1_packet *packet, int thread) { -- GitLab From 4be81991ec5f21a9dcf4b951689d81cc1b03ca25 Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Fri, 20 Nov 2015 19:43:47 -0500 Subject: [PATCH 1822/2855] staging/rdma/hfi1: Eliminate WARN_ON when VL is invalid sdma_select_engine_vl only needs to protect itself from an invalid VL. Something higher up the stack should be warning the user when they try to use an SL which maps to an invalid VL. Reviewed-by: Dean Luick Reviewed-by: Mike Marciniszyn Reviewed-by: Kaike Wan Signed-off-by: Ira Weiny Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/sdma.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rdma/hfi1/sdma.c b/drivers/staging/rdma/hfi1/sdma.c index 90b7072a99698..0710e2ab767c6 100644 --- a/drivers/staging/rdma/hfi1/sdma.c +++ b/drivers/staging/rdma/hfi1/sdma.c @@ -765,8 +765,14 @@ struct sdma_engine *sdma_select_engine_vl( struct sdma_map_elem *e; struct sdma_engine *rval; - if (WARN_ON(vl > 8)) - return &dd->per_sdma[0]; + /* NOTE This should only happen if SC->VL changed after the initial + * checks on the QP/AH + * Default will return engine 0 below + */ + if (vl >= num_vls) { + rval = NULL; + goto done; + } rcu_read_lock(); m = rcu_dereference(dd->sdma_map); @@ -778,6 +784,7 @@ struct sdma_engine *sdma_select_engine_vl( rval = e->sde[selector & e->mask]; rcu_read_unlock(); +done: rval = !rval ? &dd->per_sdma[0] : rval; trace_hfi1_sdma_engine_select(dd, selector, vl, rval->this_idx); return rval; -- GitLab From b3de842eed283f40aa769403a2d38fc0912dba2b Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Tue, 1 Dec 2015 15:38:10 -0500 Subject: [PATCH 1823/2855] staging/rdma/hfi1: Support alternate firmware names Add support for an automatic fallback for firmware names to support debug-signed and production-signed firmware images. Reviewed-by: Dennis Dalessandro Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/firmware.c | 189 ++++++++++++++++++++++----- 1 file changed, 157 insertions(+), 32 deletions(-) diff --git a/drivers/staging/rdma/hfi1/firmware.c b/drivers/staging/rdma/hfi1/firmware.c index 938b97c040e6a..28ae42faa0187 100644 --- a/drivers/staging/rdma/hfi1/firmware.c +++ b/drivers/staging/rdma/hfi1/firmware.c @@ -68,6 +68,10 @@ #define DEFAULT_FW_SBUS_NAME "hfi1_sbus.fw" #define DEFAULT_FW_PCIE_NAME "hfi1_pcie.fw" #define DEFAULT_PLATFORM_CONFIG_NAME "hfi1_platform.dat" +#define ALT_FW_8051_NAME_ASIC "hfi1_dc8051_d.fw" +#define ALT_FW_FABRIC_NAME "hfi1_fabric_d.fw" +#define ALT_FW_SBUS_NAME "hfi1_sbus_d.fw" +#define ALT_FW_PCIE_NAME "hfi1_pcie_d.fw" static uint fw_8051_load = 1; static uint fw_fabric_serdes_load = 1; @@ -158,7 +162,8 @@ struct firmware_details { static DEFINE_MUTEX(fw_mutex); enum fw_state { FW_EMPTY, - FW_ACQUIRED, + FW_TRY, + FW_FINAL, FW_ERR }; static enum fw_state fw_state = FW_EMPTY; @@ -428,8 +433,8 @@ static int obtain_one_firmware(struct hfi1_devdata *dd, const char *name, ret = request_firmware(&fdet->fw, name, &dd->pcidev->dev); if (ret) { - dd_dev_err(dd, "cannot load firmware \"%s\", err %d\n", - name, ret); + dd_dev_err(dd, "cannot find firmware \"%s\", err %d\n", + name, ret); return ret; } @@ -539,28 +544,53 @@ done: static void dispose_one_firmware(struct firmware_details *fdet) { release_firmware(fdet->fw); - fdet->fw = NULL; + /* erase all previous information */ + memset(fdet, 0, sizeof(*fdet)); } /* - * Called by all HFIs when loading their firmware - i.e. device probe time. - * The first one will do the actual firmware load. Use a mutex to resolve - * any possible race condition. + * Obtain the 4 firmwares from the OS. All must be obtained at once or not + * at all. If called with the firmware state in FW_TRY, use alternate names. + * On exit, this routine will have set the firmware state to one of FW_TRY, + * FW_FINAL, or FW_ERR. * - * The call to this routine cannot be moved to driver load because the kernel - * call request_firmware() requires a device which is only available after - * the first device probe. + * Must be holding fw_mutex. */ -static int obtain_firmware(struct hfi1_devdata *dd) +static void __obtain_firmware(struct hfi1_devdata *dd) { int err = 0; - mutex_lock(&fw_mutex); - if (fw_state == FW_ACQUIRED) { - goto done; /* already acquired */ - } else if (fw_state == FW_ERR) { - err = fw_err; - goto done; /* already tried and failed */ + if (fw_state == FW_FINAL) /* nothing more to obtain */ + return; + if (fw_state == FW_ERR) /* already in error */ + return; + + /* fw_state is FW_EMPTY or FW_TRY */ +retry: + if (fw_state == FW_TRY) { + /* + * We tried the original and it failed. Move to the + * alternate. + */ + dd_dev_info(dd, "using alternate firmware names\n"); + /* + * Let others run. Some systems, when missing firmware, does + * something that holds for 30 seconds. If we do that twice + * in a row it triggers task blocked warning. + */ + cond_resched(); + if (fw_8051_load) + dispose_one_firmware(&fw_8051); + if (fw_fabric_serdes_load) + dispose_one_firmware(&fw_fabric); + if (fw_sbus_load) + dispose_one_firmware(&fw_sbus); + if (fw_pcie_serdes_load) + dispose_one_firmware(&fw_pcie); + fw_8051_name = ALT_FW_8051_NAME_ASIC; + fw_fabric_serdes_name = ALT_FW_FABRIC_NAME; + fw_sbus_name = ALT_FW_SBUS_NAME; + fw_pcie_serdes_name = ALT_FW_PCIE_NAME; } if (fw_8051_load) { @@ -588,27 +618,82 @@ static int obtain_firmware(struct hfi1_devdata *dd) goto done; } +done: + if (err) { + /* oops, had problems obtaining a firmware */ + if (fw_state == FW_EMPTY) { + /* retry with alternate */ + fw_state = FW_TRY; + goto retry; + } + fw_state = FW_ERR; + fw_err = -ENOENT; + } else { + /* success */ + if (fw_state == FW_EMPTY) + fw_state = FW_TRY; /* may retry later */ + else + fw_state = FW_FINAL; /* cannot try again */ + } +} + +/* + * Called by all HFIs when loading their firmware - i.e. device probe time. + * The first one will do the actual firmware load. Use a mutex to resolve + * any possible race condition. + * + * The call to this routine cannot be moved to driver load because the kernel + * call request_firmware() requires a device which is only available after + * the first device probe. + */ +static int obtain_firmware(struct hfi1_devdata *dd) +{ + unsigned long timeout; + int err = 0; + + mutex_lock(&fw_mutex); + + /* 40s delay due to long delay on missing firmware on some systems */ + timeout = jiffies + msecs_to_jiffies(40000); + while (fw_state == FW_TRY) { + /* + * Another device is trying the firmware. Wait until it + * decides what works (or not). + */ + if (time_after(jiffies, timeout)) { + /* waited too long */ + dd_dev_err(dd, "Timeout waiting for firmware try"); + fw_state = FW_ERR; + fw_err = -ETIMEDOUT; + break; + } + mutex_unlock(&fw_mutex); + msleep(20); /* arbitrary delay */ + mutex_lock(&fw_mutex); + } + /* not in FW_TRY state */ + + if (fw_state == FW_FINAL) + goto done; /* already acquired */ + else if (fw_state == FW_ERR) + goto done; /* already tried and failed */ + /* fw_state is FW_EMPTY */ + + /* set fw_state to FW_TRY, FW_FINAL, or FW_ERR, and fw_err */ + __obtain_firmware(dd); + if (platform_config_load) { platform_config = NULL; err = request_firmware(&platform_config, platform_config_name, &dd->pcidev->dev); - if (err) { - err = 0; + if (err) platform_config = NULL; - } } - /* success */ - fw_state = FW_ACQUIRED; - done: - if (err) { - fw_err = err; - fw_state = FW_ERR; - } mutex_unlock(&fw_mutex); - return err; + return fw_err; } /* @@ -637,6 +722,38 @@ void dispose_firmware(void) fw_state = FW_EMPTY; } +/* + * Called with the result of a firmware download. + * + * Return 1 to retry loading the firmware, 0 to stop. + */ +static int retry_firmware(struct hfi1_devdata *dd, int load_result) +{ + int retry; + + mutex_lock(&fw_mutex); + + if (load_result == 0) { + /* + * The load succeeded, so expect all others to do the same. + * Do not retry again. + */ + if (fw_state == FW_TRY) + fw_state = FW_FINAL; + retry = 0; /* do NOT retry */ + } else if (fw_state == FW_TRY) { + /* load failed, obtain alternate firmware */ + __obtain_firmware(dd); + retry = (fw_state == FW_FINAL); + } else { + /* else in FW_FINAL or FW_ERR, no retry in either case */ + retry = 0; + } + + mutex_unlock(&fw_mutex); + return retry; +} + /* * Write a block of data to a given array CSR. All calls will be in * multiples of 8 bytes. @@ -1248,7 +1365,9 @@ int load_firmware(struct hfi1_devdata *dd) fabric_serdes_addrs[dd->hfi1_id], NUM_FABRIC_SERDES); turn_off_spicos(dd, SPICO_FABRIC); - ret = load_fabric_serdes_firmware(dd, &fw_fabric); + do { + ret = load_fabric_serdes_firmware(dd, &fw_fabric); + } while (retry_firmware(dd, ret)); clear_sbus_fast_mode(dd); release_hw_mutex(dd); @@ -1257,7 +1376,9 @@ int load_firmware(struct hfi1_devdata *dd) } if (fw_8051_load) { - ret = load_8051_firmware(dd, &fw_8051); + do { + ret = load_8051_firmware(dd, &fw_8051); + } while (retry_firmware(dd, ret)); if (ret) return ret; } @@ -1570,7 +1691,9 @@ int load_pcie_firmware(struct hfi1_devdata *dd) if (fw_sbus_load) { turn_off_spicos(dd, SPICO_SBUS); - ret = load_sbus_firmware(dd, &fw_sbus); + do { + ret = load_sbus_firmware(dd, &fw_sbus); + } while (retry_firmware(dd, ret)); if (ret) goto done; } @@ -1581,7 +1704,9 @@ int load_pcie_firmware(struct hfi1_devdata *dd) pcie_serdes_broadcast[dd->hfi1_id], pcie_serdes_addrs[dd->hfi1_id], NUM_PCIE_SERDES); - ret = load_pcie_serdes_firmware(dd, &fw_pcie); + do { + ret = load_pcie_serdes_firmware(dd, &fw_pcie); + } while (retry_firmware(dd, ret)); if (ret) goto done; } -- GitLab From 93990be3023c11f054f7ac3bcbc2a1c4edda6bec Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Tue, 1 Dec 2015 15:38:11 -0500 Subject: [PATCH 1824/2855] staging/rdma/hfi1: Decode CNP opcode Add CNP opcode decode. Prior to this patch the trace appeared like: -0 [001] d.h. 94062.578932: input_ibhdr: [0000:05:00.0] vl 0 lver 0 sl 0 lnh 2,LRH_BTH dlid 0003 len 6 slid 0001 op 0x80,0x80 se 0 m 0 pad 0 tver 0 pkey 0x8001 f 0 b 0 qpn 0x001234 a 0 psn 0x00000000 Note the "op 0x80,0x80". With this patch: -0 [000] d.h. 233975.912059: input_ibhdr: [0000:05:00.0] vl 0 lver 0 sl 0 lnh 2,LRH_BTH dlid 0015 len 6 slid 0014 op 0x80,CNP se 0 m 0 pad 0 tver 0 pkey 0x8001 f 0 b 0 qpn 0x001234 a 0 psn 0x00000000 Note the "op 0x80,CNP" Reviewed-by: Mike Marciniszyn Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/trace.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rdma/hfi1/trace.h b/drivers/staging/rdma/hfi1/trace.h index 57430295c4040..86c12ebfd4f0b 100644 --- a/drivers/staging/rdma/hfi1/trace.h +++ b/drivers/staging/rdma/hfi1/trace.h @@ -417,7 +417,8 @@ __print_symbolic(opcode, \ ib_opcode_name(UC_RDMA_WRITE_ONLY), \ ib_opcode_name(UC_RDMA_WRITE_ONLY_WITH_IMMEDIATE), \ ib_opcode_name(UD_SEND_ONLY), \ - ib_opcode_name(UD_SEND_ONLY_WITH_IMMEDIATE)) + ib_opcode_name(UD_SEND_ONLY_WITH_IMMEDIATE), \ + ib_opcode_name(CNP)) #define LRH_PRN "vl %d lver %d sl %d lnh %d,%s dlid %.4x len %d slid %.4x" -- GitLab From 3802f7eb886582735112b6867286e1acc3991f55 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Tue, 1 Dec 2015 15:38:12 -0500 Subject: [PATCH 1825/2855] staging/rdma/hfi1: Add aeth name syndrome decode Add aeth name syndrome decode to enhance debugging. The IBTA RC ACK contains an ACK extended transport header. Part of that header is the syndrome field that qualifies the RC ACK as an ACK, NAK, or RNR NAK. Without the patch here is the syndrome decode: aeth syn 0x00 Here is the decode with the fix: aeth syn 0x00 ACK Reviewed-by: Mike Marciniszyn Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/trace.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/drivers/staging/rdma/hfi1/trace.c b/drivers/staging/rdma/hfi1/trace.c index f55b75194847d..10122e84cb2fa 100644 --- a/drivers/staging/rdma/hfi1/trace.c +++ b/drivers/staging/rdma/hfi1/trace.c @@ -67,7 +67,7 @@ u8 ibhdr_exhdr_len(struct hfi1_ib_header *hdr) #define IMM_PRN "imm %d" #define RETH_PRN "reth vaddr 0x%.16llx rkey 0x%.8x dlen 0x%.8x" -#define AETH_PRN "aeth syn 0x%.2x msn 0x%.8x" +#define AETH_PRN "aeth syn 0x%.2x %s msn 0x%.8x" #define DETH_PRN "deth qkey 0x%.8x sqpn 0x%.6x" #define ATOMICACKETH_PRN "origdata %lld" #define ATOMICETH_PRN "vaddr 0x%llx rkey 0x%.8x sdata %lld cdata %lld" @@ -79,6 +79,19 @@ static u64 ib_u64_get(__be32 *p) return ((u64)be32_to_cpu(p[0]) << 32) | be32_to_cpu(p[1]); } +static const char *parse_syndrome(u8 syndrome) +{ + switch (syndrome >> 5) { + case 0: + return "ACK"; + case 1: + return "RNRNAK"; + case 3: + return "NAK"; + } + return ""; +} + const char *parse_everbs_hdrs( struct trace_seq *p, u8 opcode, @@ -124,16 +137,18 @@ const char *parse_everbs_hdrs( case OP(RC, RDMA_READ_RESPONSE_LAST): case OP(RC, RDMA_READ_RESPONSE_ONLY): case OP(RC, ACKNOWLEDGE): - trace_seq_printf(p, AETH_PRN, - be32_to_cpu(eh->aeth) >> 24, - be32_to_cpu(eh->aeth) & HFI1_MSN_MASK); + trace_seq_printf(p, AETH_PRN, be32_to_cpu(eh->aeth) >> 24, + parse_syndrome(be32_to_cpu(eh->aeth) >> 24), + be32_to_cpu(eh->aeth) & HFI1_MSN_MASK); break; /* aeth + atomicacketh */ case OP(RC, ATOMIC_ACKNOWLEDGE): trace_seq_printf(p, AETH_PRN " " ATOMICACKETH_PRN, - (be32_to_cpu(eh->at.aeth) >> 24) & 0xff, - be32_to_cpu(eh->at.aeth) & HFI1_MSN_MASK, - (unsigned long long)ib_u64_get(eh->at.atomic_ack_eth)); + be32_to_cpu(eh->at.aeth) >> 24, + parse_syndrome(be32_to_cpu(eh->at.aeth) >> 24), + be32_to_cpu(eh->at.aeth) & HFI1_MSN_MASK, + (unsigned long long) + ib_u64_get(eh->at.atomic_ack_eth)); break; /* atomiceth */ case OP(RC, COMPARE_SWAP): -- GitLab From 92d207f31532d48bb86a1a14f9a92df11c9a315c Mon Sep 17 00:00:00 2001 From: Kaike Wan Date: Tue, 1 Dec 2015 15:38:13 -0500 Subject: [PATCH 1826/2855] staging/rdma/hfi1: Fix qp.h comments This patch fixes a few incorrect header file comments in qp.h Reviewed-by: Mike Marciniszyn Signed-off-by: Kaike Wan Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/qp.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rdma/hfi1/qp.h b/drivers/staging/rdma/hfi1/qp.h index 94fd748a00a61..62a94c5d7dcaa 100644 --- a/drivers/staging/rdma/hfi1/qp.h +++ b/drivers/staging/rdma/hfi1/qp.h @@ -211,7 +211,7 @@ int hfi1_qp_init(struct hfi1_ibdev *dev); void hfi1_qp_exit(struct hfi1_ibdev *dev); /** - * hfi1_qp_waitup - wake up on the indicated event + * hfi1_qp_wakeup - wake up on the indicated event * @qp: the QP * @flag: flag the qp on which the qp is stalled */ @@ -222,19 +222,19 @@ struct sdma_engine *qp_to_sdma_engine(struct hfi1_qp *qp, u8 sc5); struct qp_iter; /** - * qp_iter_init - wake up on the indicated event + * qp_iter_init - initialize the iterator for the qp hash list * @dev: the hfi1_ibdev */ struct qp_iter *qp_iter_init(struct hfi1_ibdev *dev); /** - * qp_iter_next - wakeup on the indicated event + * qp_iter_next - Find the next qp in the hash list * @iter: the iterator for the qp hash list */ int qp_iter_next(struct qp_iter *iter); /** - * qp_iter_next - wake up on the indicated event + * qp_iter_print - print the qp information to seq_file * @s: the seq_file to emit the qp information on * @iter: the iterator for the qp hash list */ -- GitLab From bbdeb33d2774ddc7475aab7868a5c447503a256e Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Tue, 1 Dec 2015 15:38:15 -0500 Subject: [PATCH 1827/2855] staging/rdma/hfi1: Add one-time LCB reset Add one-time LCB reset on driver load to pre-emptively work around any LCB power cycle issues. Reviewed-by: Easwar Hariharan Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 20 ++++++++++++++++++++ drivers/staging/rdma/hfi1/chip_registers.h | 3 +++ 2 files changed, 23 insertions(+) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index bcbd831d2b73c..62813052fc997 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -5896,6 +5896,23 @@ void init_qsfp(struct hfi1_pportdata *ppd) } } +/* + * Do a one-time initialize of the LCB block. + */ +static void init_lcb(struct hfi1_devdata *dd) +{ + /* the DC has been reset earlier in the driver load */ + + /* set LCB for cclk loopback on the port */ + write_csr(dd, DC_LCB_CFG_TX_FIFOS_RESET, 0x01); + write_csr(dd, DC_LCB_CFG_LANE_WIDTH, 0x00); + write_csr(dd, DC_LCB_CFG_REINIT_AS_SLAVE, 0x00); + write_csr(dd, DC_LCB_CFG_CNT_FOR_SKIP_STALL, 0x110); + write_csr(dd, DC_LCB_CFG_CLK_CNTR, 0x08); + write_csr(dd, DC_LCB_CFG_LOOPBACK, 0x02); + write_csr(dd, DC_LCB_CFG_TX_FIFOS_RESET, 0x00); +} + int bringup_serdes(struct hfi1_pportdata *ppd) { struct hfi1_devdata *dd = ppd->dd; @@ -5917,6 +5934,9 @@ int bringup_serdes(struct hfi1_pportdata *ppd) /* Set linkinit_reason on power up per OPA spec */ ppd->linkinit_reason = OPA_LINKINIT_REASON_LINKUP; + /* one-time init of the LCB */ + init_lcb(dd); + if (loopback) { ret = init_loopback(dd); if (ret < 0) diff --git a/drivers/staging/rdma/hfi1/chip_registers.h b/drivers/staging/rdma/hfi1/chip_registers.h index 5056c848af357..701e9e1012a6c 100644 --- a/drivers/staging/rdma/hfi1/chip_registers.h +++ b/drivers/staging/rdma/hfi1/chip_registers.h @@ -318,6 +318,9 @@ #define DC_LCB_CFG_TX_FIFOS_RADR_RST_VAL_SHIFT 0 #define DC_LCB_CFG_TX_FIFOS_RESET (DC_LCB_CSRS + 0x000000000008) #define DC_LCB_CFG_TX_FIFOS_RESET_VAL_SHIFT 0 +#define DC_LCB_CFG_REINIT_AS_SLAVE (DC_LCB_CSRS + 0x000000000030) +#define DC_LCB_CFG_CNT_FOR_SKIP_STALL (DC_LCB_CSRS + 0x000000000040) +#define DC_LCB_CFG_CLK_CNTR (DC_LCB_CSRS + 0x000000000110) #define DC_LCB_ERR_CLR (DC_LCB_CSRS + 0x000000000308) #define DC_LCB_ERR_EN (DC_LCB_CSRS + 0x000000000310) #define DC_LCB_ERR_FLG (DC_LCB_CSRS + 0x000000000300) -- GitLab From 05087f3b224ad42086c019ff11679298faeb50f2 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Tue, 1 Dec 2015 15:38:16 -0500 Subject: [PATCH 1828/2855] staging/rdma/hfi1: Extend quiet timeout The longest quiet timeout is now 6s. Extend the driver wait to 6s. The driver wasn't following our internal specification: 6 seconds. This patch corrects that issue. Reviewed-by: Dennis Dalessandro Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index 62813052fc997..03a665f0254ee 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -6379,9 +6379,10 @@ static int goto_offline(struct hfi1_pportdata *ppd, u8 rem_reason) * depending on how the link went down. The 8051 firmware * will observe the needed wait time and only move to ready * when that is completed. The largest of the quiet timeouts - * is 2.5s, so wait that long and then a bit more. + * is 6s, so wait that long and then at least 0.5s more for + * other transitions, and another 0.5s for a buffer. */ - ret = wait_fm_ready(dd, 3000); + ret = wait_fm_ready(dd, 7000); if (ret) { dd_dev_err(dd, "After going offline, timed out waiting for the 8051 to become ready to accept host requests\n"); -- GitLab From d22f9d6bf5622bc3ffb709fb229715167a8bd533 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Tue, 1 Dec 2015 15:38:17 -0500 Subject: [PATCH 1829/2855] staging/rdma/hfi1: Add a credit push on diagpkt allocate fail When sending a diagnostic packet, if the send context does not have enough room, force a credit return and try again. Reviewed-by: Dennis Dalessandro Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/diag.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/staging/rdma/hfi1/diag.c b/drivers/staging/rdma/hfi1/diag.c index 0aaad7412842b..e4cd333bba83c 100644 --- a/drivers/staging/rdma/hfi1/diag.c +++ b/drivers/staging/rdma/hfi1/diag.c @@ -379,6 +379,7 @@ static ssize_t diagpkt_send(struct diag_pkt *dp) pio_release_cb credit_cb = NULL; void *credit_arg = NULL; struct diagpkt_wait *wait = NULL; + int trycount = 0; dd = hfi1_lookup(dp->unit); if (!dd || !(dd->flags & HFI1_PRESENT) || !dd->kregbase) { @@ -493,8 +494,15 @@ static ssize_t diagpkt_send(struct diag_pkt *dp) credit_arg = wait; } +retry: pbuf = sc_buffer_alloc(sc, total_len, credit_cb, credit_arg); if (!pbuf) { + if (trycount == 0) { + /* force a credit return and try again */ + sc_return_credits(sc); + trycount = 1; + goto retry; + } /* * No send buffer means no credit callback. Undo * the wait set-up that was done above. We free wait -- GitLab From 11a5909b26942683d5ec7e6810054a36d5a6ee67 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Tue, 1 Dec 2015 15:38:18 -0500 Subject: [PATCH 1830/2855] staging/rdma/hfi1: Correctly limit VLs against SDMA engines Correctly reduce the number of VLs when limited by the number of SDMA engines. The hardware has multiple egress mechanisms, SDMA and pio, and multiples of those. These mechanisms are chosen using the VL (8) The fix corrects a panic issue with one of the platforms that doesn't have enough SDMA (4) mechanisms for the typical number of VLs. Reviewed-by: Mike Marciniszyn Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index 03a665f0254ee..0c27cc09c9185 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -10645,9 +10645,9 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev, /* insure num_vls isn't larger than number of sdma engines */ if (HFI1_CAP_IS_KSET(SDMA) && num_vls > dd->chip_sdma_engines) { dd_dev_err(dd, "num_vls %u too large, using %u VLs\n", - num_vls, HFI1_MAX_VLS_SUPPORTED); - ppd->vls_supported = num_vls = HFI1_MAX_VLS_SUPPORTED; - ppd->vls_operational = ppd->vls_supported; + num_vls, dd->chip_sdma_engines); + num_vls = dd->chip_sdma_engines; + ppd->vls_supported = dd->chip_sdma_engines; } /* -- GitLab From 2c5b521ae688a6943d79e3f1210502084b375ced Mon Sep 17 00:00:00 2001 From: Joel Rosenzweig Date: Tue, 1 Dec 2015 15:38:19 -0500 Subject: [PATCH 1831/2855] staging/rdma/hfi1: Adds software counters for bitfields within various error status fields Provides error status counters for CceErrStatus, Send*ErrStatus, RcvErrStatus and MISC_ERR_STATUS Reviewed-by: Mitko Haralanov Reviewed-by: Mike Marciniszyn Signed-off-by: Joel Rosenzweig Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 3185 +++++++++++++++++++++++++++++- drivers/staging/rdma/hfi1/chip.h | 269 +++ drivers/staging/rdma/hfi1/hfi.h | 34 + 3 files changed, 3487 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index 0c27cc09c9185..3cf6fea0bf35d 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -664,7 +664,7 @@ static struct flag_table egress_err_info_flags[] = { */ #define SES(name) SEND_ERR_STATUS_SEND_##name##_ERR_SMASK static struct flag_table send_err_status_flags[] = { -/* 0*/ FLAG_ENTRY0("SDmaRpyTagErr", SES(CSR_PARITY)), +/* 0*/ FLAG_ENTRY0("SendCsrParityErr", SES(CSR_PARITY)), /* 1*/ FLAG_ENTRY0("SendCsrReadBadAddrErr", SES(CSR_READ_BAD_ADDR)), /* 2*/ FLAG_ENTRY0("SendCsrWriteBadAddrErr", SES(CSR_WRITE_BAD_ADDR)) }; @@ -1539,6 +1539,2336 @@ static u64 access_sw_send_schedule(const struct cntr_entry *entry, return dd->verbs_dev.n_send_schedule; } +/* Software counters for the error status bits within MISC_ERR_STATUS */ +static u64 access_misc_pll_lock_fail_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->misc_err_status_cnt[12]; +} + +static u64 access_misc_mbist_fail_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->misc_err_status_cnt[11]; +} + +static u64 access_misc_invalid_eep_cmd_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->misc_err_status_cnt[10]; +} + +static u64 access_misc_efuse_done_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->misc_err_status_cnt[9]; +} + +static u64 access_misc_efuse_write_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->misc_err_status_cnt[8]; +} + +static u64 access_misc_efuse_read_bad_addr_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->misc_err_status_cnt[7]; +} + +static u64 access_misc_efuse_csr_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->misc_err_status_cnt[6]; +} + +static u64 access_misc_fw_auth_failed_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->misc_err_status_cnt[5]; +} + +static u64 access_misc_key_mismatch_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->misc_err_status_cnt[4]; +} + +static u64 access_misc_sbus_write_failed_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->misc_err_status_cnt[3]; +} + +static u64 access_misc_csr_write_bad_addr_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->misc_err_status_cnt[2]; +} + +static u64 access_misc_csr_read_bad_addr_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->misc_err_status_cnt[1]; +} + +static u64 access_misc_csr_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->misc_err_status_cnt[0]; +} + +/* + * Software counter for the aggregate of + * individual CceErrStatus counters + */ +static u64 access_sw_cce_err_status_aggregated_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_cce_err_status_aggregate; +} + +/* + * Software counters corresponding to each of the + * error status bits within CceErrStatus + */ +static u64 access_cce_msix_csr_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[40]; +} + +static u64 access_cce_int_map_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[39]; +} + +static u64 access_cce_int_map_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[38]; +} + +static u64 access_cce_msix_table_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[37]; +} + +static u64 access_cce_msix_table_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[36]; +} + +static u64 access_cce_rxdma_conv_fifo_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[35]; +} + +static u64 access_cce_rcpl_async_fifo_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[34]; +} + +static u64 access_cce_seg_write_bad_addr_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[33]; +} + +static u64 access_cce_seg_read_bad_addr_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[32]; +} + +static u64 access_la_triggered_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[31]; +} + +static u64 access_cce_trgt_cpl_timeout_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[30]; +} + +static u64 access_pcic_receive_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[29]; +} + +static u64 access_pcic_transmit_back_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[28]; +} + +static u64 access_pcic_transmit_front_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[27]; +} + +static u64 access_pcic_cpl_dat_q_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[26]; +} + +static u64 access_pcic_cpl_hd_q_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[25]; +} + +static u64 access_pcic_post_dat_q_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[24]; +} + +static u64 access_pcic_post_hd_q_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[23]; +} + +static u64 access_pcic_retry_sot_mem_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[22]; +} + +static u64 access_pcic_retry_mem_unc_err(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[21]; +} + +static u64 access_pcic_n_post_dat_q_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[20]; +} + +static u64 access_pcic_n_post_h_q_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[19]; +} + +static u64 access_pcic_cpl_dat_q_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[18]; +} + +static u64 access_pcic_cpl_hd_q_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[17]; +} + +static u64 access_pcic_post_dat_q_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[16]; +} + +static u64 access_pcic_post_hd_q_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[15]; +} + +static u64 access_pcic_retry_sot_mem_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[14]; +} + +static u64 access_pcic_retry_mem_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[13]; +} + +static u64 access_cce_cli1_async_fifo_dbg_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[12]; +} + +static u64 access_cce_cli1_async_fifo_rxdma_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[11]; +} + +static u64 access_cce_cli1_async_fifo_sdma_hd_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[10]; +} + +static u64 access_cce_cl1_async_fifo_pio_crdt_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[9]; +} + +static u64 access_cce_cli2_async_fifo_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[8]; +} + +static u64 access_cce_csr_cfg_bus_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[7]; +} + +static u64 access_cce_cli0_async_fifo_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[6]; +} + +static u64 access_cce_rspd_data_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[5]; +} + +static u64 access_cce_trgt_access_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[4]; +} + +static u64 access_cce_trgt_async_fifo_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[3]; +} + +static u64 access_cce_csr_write_bad_addr_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[2]; +} + +static u64 access_cce_csr_read_bad_addr_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[1]; +} + +static u64 access_ccs_csr_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->cce_err_status_cnt[0]; +} + +/* + * Software counters corresponding to each of the + * error status bits within RcvErrStatus + */ +static u64 access_rx_csr_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[63]; +} + +static u64 access_rx_csr_write_bad_addr_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[62]; +} + +static u64 access_rx_csr_read_bad_addr_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[61]; +} + +static u64 access_rx_dma_csr_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[60]; +} + +static u64 access_rx_dma_dq_fsm_encoding_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[59]; +} + +static u64 access_rx_dma_eq_fsm_encoding_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[58]; +} + +static u64 access_rx_dma_csr_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[57]; +} + +static u64 access_rx_rbuf_data_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[56]; +} + +static u64 access_rx_rbuf_data_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[55]; +} + +static u64 access_rx_dma_data_fifo_rd_cor_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[54]; +} + +static u64 access_rx_dma_data_fifo_rd_unc_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[53]; +} + +static u64 access_rx_dma_hdr_fifo_rd_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[52]; +} + +static u64 access_rx_dma_hdr_fifo_rd_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[51]; +} + +static u64 access_rx_rbuf_desc_part2_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[50]; +} + +static u64 access_rx_rbuf_desc_part2_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[49]; +} + +static u64 access_rx_rbuf_desc_part1_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[48]; +} + +static u64 access_rx_rbuf_desc_part1_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[47]; +} + +static u64 access_rx_hq_intr_fsm_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[46]; +} + +static u64 access_rx_hq_intr_csr_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[45]; +} + +static u64 access_rx_lookup_csr_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[44]; +} + +static u64 access_rx_lookup_rcv_array_cor_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[43]; +} + +static u64 access_rx_lookup_rcv_array_unc_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[42]; +} + +static u64 access_rx_lookup_des_part2_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[41]; +} + +static u64 access_rx_lookup_des_part1_unc_cor_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[40]; +} + +static u64 access_rx_lookup_des_part1_unc_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[39]; +} + +static u64 access_rx_rbuf_next_free_buf_cor_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[38]; +} + +static u64 access_rx_rbuf_next_free_buf_unc_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[37]; +} + +static u64 access_rbuf_fl_init_wr_addr_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[36]; +} + +static u64 access_rx_rbuf_fl_initdone_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[35]; +} + +static u64 access_rx_rbuf_fl_write_addr_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[34]; +} + +static u64 access_rx_rbuf_fl_rd_addr_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[33]; +} + +static u64 access_rx_rbuf_empty_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[32]; +} + +static u64 access_rx_rbuf_full_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[31]; +} + +static u64 access_rbuf_bad_lookup_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[30]; +} + +static u64 access_rbuf_ctx_id_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[29]; +} + +static u64 access_rbuf_csr_qeopdw_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[28]; +} + +static u64 access_rx_rbuf_csr_q_num_of_pkt_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[27]; +} + +static u64 access_rx_rbuf_csr_q_t1_ptr_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[26]; +} + +static u64 access_rx_rbuf_csr_q_hd_ptr_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[25]; +} + +static u64 access_rx_rbuf_csr_q_vld_bit_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[24]; +} + +static u64 access_rx_rbuf_csr_q_next_buf_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[23]; +} + +static u64 access_rx_rbuf_csr_q_ent_cnt_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[22]; +} + +static u64 access_rx_rbuf_csr_q_head_buf_num_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[21]; +} + +static u64 access_rx_rbuf_block_list_read_cor_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[20]; +} + +static u64 access_rx_rbuf_block_list_read_unc_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[19]; +} + +static u64 access_rx_rbuf_lookup_des_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[18]; +} + +static u64 access_rx_rbuf_lookup_des_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[17]; +} + +static u64 access_rx_rbuf_lookup_des_reg_unc_cor_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[16]; +} + +static u64 access_rx_rbuf_lookup_des_reg_unc_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[15]; +} + +static u64 access_rx_rbuf_free_list_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[14]; +} + +static u64 access_rx_rbuf_free_list_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[13]; +} + +static u64 access_rx_rcv_fsm_encoding_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[12]; +} + +static u64 access_rx_dma_flag_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[11]; +} + +static u64 access_rx_dma_flag_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[10]; +} + +static u64 access_rx_dc_sop_eop_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[9]; +} + +static u64 access_rx_rcv_csr_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[8]; +} + +static u64 access_rx_rcv_qp_map_table_cor_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[7]; +} + +static u64 access_rx_rcv_qp_map_table_unc_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[6]; +} + +static u64 access_rx_rcv_data_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[5]; +} + +static u64 access_rx_rcv_data_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[4]; +} + +static u64 access_rx_rcv_hdr_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[3]; +} + +static u64 access_rx_rcv_hdr_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[2]; +} + +static u64 access_rx_dc_intf_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[1]; +} + +static u64 access_rx_dma_csr_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->rcv_err_status_cnt[0]; +} + +/* + * Software counters corresponding to each of the + * error status bits within SendPioErrStatus + */ +static u64 access_pio_pec_sop_head_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[35]; +} + +static u64 access_pio_pcc_sop_head_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[34]; +} + +static u64 access_pio_last_returned_cnt_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[33]; +} + +static u64 access_pio_current_free_cnt_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[32]; +} + +static u64 access_pio_reserved_31_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[31]; +} + +static u64 access_pio_reserved_30_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[30]; +} + +static u64 access_pio_ppmc_sop_len_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[29]; +} + +static u64 access_pio_ppmc_bqc_mem_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[28]; +} + +static u64 access_pio_vl_fifo_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[27]; +} + +static u64 access_pio_vlf_sop_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[26]; +} + +static u64 access_pio_vlf_v1_len_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[25]; +} + +static u64 access_pio_block_qw_count_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[24]; +} + +static u64 access_pio_write_qw_valid_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[23]; +} + +static u64 access_pio_state_machine_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[22]; +} + +static u64 access_pio_write_data_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[21]; +} + +static u64 access_pio_host_addr_mem_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[20]; +} + +static u64 access_pio_host_addr_mem_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[19]; +} + +static u64 access_pio_pkt_evict_sm_or_arb_sm_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[18]; +} + +static u64 access_pio_init_sm_in_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[17]; +} + +static u64 access_pio_ppmc_pbl_fifo_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[16]; +} + +static u64 access_pio_credit_ret_fifo_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[15]; +} + +static u64 access_pio_v1_len_mem_bank1_cor_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[14]; +} + +static u64 access_pio_v1_len_mem_bank0_cor_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[13]; +} + +static u64 access_pio_v1_len_mem_bank1_unc_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[12]; +} + +static u64 access_pio_v1_len_mem_bank0_unc_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[11]; +} + +static u64 access_pio_sm_pkt_reset_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[10]; +} + +static u64 access_pio_pkt_evict_fifo_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[9]; +} + +static u64 access_pio_sbrdctrl_crrel_fifo_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[8]; +} + +static u64 access_pio_sbrdctl_crrel_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[7]; +} + +static u64 access_pio_pec_fifo_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[6]; +} + +static u64 access_pio_pcc_fifo_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[5]; +} + +static u64 access_pio_sb_mem_fifo1_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[4]; +} + +static u64 access_pio_sb_mem_fifo0_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[3]; +} + +static u64 access_pio_csr_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[2]; +} + +static u64 access_pio_write_addr_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[1]; +} + +static u64 access_pio_write_bad_ctxt_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_pio_err_status_cnt[0]; +} + +/* + * Software counters corresponding to each of the + * error status bits within SendDmaErrStatus + */ +static u64 access_sdma_pcie_req_tracking_cor_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_dma_err_status_cnt[3]; +} + +static u64 access_sdma_pcie_req_tracking_unc_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_dma_err_status_cnt[2]; +} + +static u64 access_sdma_csr_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_dma_err_status_cnt[1]; +} + +static u64 access_sdma_rpy_tag_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_dma_err_status_cnt[0]; +} + +/* + * Software counters corresponding to each of the + * error status bits within SendEgressErrStatus + */ +static u64 access_tx_read_pio_memory_csr_unc_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[63]; +} + +static u64 access_tx_read_sdma_memory_csr_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[62]; +} + +static u64 access_tx_egress_fifo_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[61]; +} + +static u64 access_tx_read_pio_memory_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[60]; +} + +static u64 access_tx_read_sdma_memory_cor_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[59]; +} + +static u64 access_tx_sb_hdr_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[58]; +} + +static u64 access_tx_credit_overrun_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[57]; +} + +static u64 access_tx_launch_fifo8_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[56]; +} + +static u64 access_tx_launch_fifo7_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[55]; +} + +static u64 access_tx_launch_fifo6_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[54]; +} + +static u64 access_tx_launch_fifo5_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[53]; +} + +static u64 access_tx_launch_fifo4_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[52]; +} + +static u64 access_tx_launch_fifo3_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[51]; +} + +static u64 access_tx_launch_fifo2_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[50]; +} + +static u64 access_tx_launch_fifo1_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[49]; +} + +static u64 access_tx_launch_fifo0_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[48]; +} + +static u64 access_tx_credit_return_vl_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[47]; +} + +static u64 access_tx_hcrc_insertion_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[46]; +} + +static u64 access_tx_egress_fifo_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[45]; +} + +static u64 access_tx_read_pio_memory_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[44]; +} + +static u64 access_tx_read_sdma_memory_unc_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[43]; +} + +static u64 access_tx_sb_hdr_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[42]; +} + +static u64 access_tx_credit_return_partiy_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[41]; +} + +static u64 access_tx_launch_fifo8_unc_or_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[40]; +} + +static u64 access_tx_launch_fifo7_unc_or_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[39]; +} + +static u64 access_tx_launch_fifo6_unc_or_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[38]; +} + +static u64 access_tx_launch_fifo5_unc_or_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[37]; +} + +static u64 access_tx_launch_fifo4_unc_or_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[36]; +} + +static u64 access_tx_launch_fifo3_unc_or_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[35]; +} + +static u64 access_tx_launch_fifo2_unc_or_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[34]; +} + +static u64 access_tx_launch_fifo1_unc_or_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[33]; +} + +static u64 access_tx_launch_fifo0_unc_or_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[32]; +} + +static u64 access_tx_sdma15_disallowed_packet_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[31]; +} + +static u64 access_tx_sdma14_disallowed_packet_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[30]; +} + +static u64 access_tx_sdma13_disallowed_packet_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[29]; +} + +static u64 access_tx_sdma12_disallowed_packet_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[28]; +} + +static u64 access_tx_sdma11_disallowed_packet_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[27]; +} + +static u64 access_tx_sdma10_disallowed_packet_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[26]; +} + +static u64 access_tx_sdma9_disallowed_packet_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[25]; +} + +static u64 access_tx_sdma8_disallowed_packet_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[24]; +} + +static u64 access_tx_sdma7_disallowed_packet_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[23]; +} + +static u64 access_tx_sdma6_disallowed_packet_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[22]; +} + +static u64 access_tx_sdma5_disallowed_packet_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[21]; +} + +static u64 access_tx_sdma4_disallowed_packet_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[20]; +} + +static u64 access_tx_sdma3_disallowed_packet_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[19]; +} + +static u64 access_tx_sdma2_disallowed_packet_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[18]; +} + +static u64 access_tx_sdma1_disallowed_packet_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[17]; +} + +static u64 access_tx_sdma0_disallowed_packet_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[16]; +} + +static u64 access_tx_config_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[15]; +} + +static u64 access_tx_sbrd_ctl_csr_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[14]; +} + +static u64 access_tx_launch_csr_parity_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[13]; +} + +static u64 access_tx_illegal_vl_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[12]; +} + +static u64 access_tx_sbrd_ctl_state_machine_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[11]; +} + +static u64 access_egress_reserved_10_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[10]; +} + +static u64 access_egress_reserved_9_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[9]; +} + +static u64 access_tx_sdma_launch_intf_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[8]; +} + +static u64 access_tx_pio_launch_intf_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[7]; +} + +static u64 access_egress_reserved_6_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[6]; +} + +static u64 access_tx_incorrect_link_state_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[5]; +} + +static u64 access_tx_linkdown_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[4]; +} + +static u64 access_tx_egress_fifi_underrun_or_parity_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[3]; +} + +static u64 access_egress_reserved_2_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[2]; +} + +static u64 access_tx_pkt_integrity_mem_unc_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[1]; +} + +static u64 access_tx_pkt_integrity_mem_cor_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_egress_err_status_cnt[0]; +} + +/* + * Software counters corresponding to each of the + * error status bits within SendErrStatus + */ +static u64 access_send_csr_write_bad_addr_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_err_status_cnt[2]; +} + +static u64 access_send_csr_read_bad_addr_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_err_status_cnt[1]; +} + +static u64 access_send_csr_parity_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->send_err_status_cnt[0]; +} + +/* + * Software counters corresponding to each of the + * error status bits within SendCtxtErrStatus + */ +static u64 access_pio_write_out_of_bounds_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_ctxt_err_status_cnt[4]; +} + +static u64 access_pio_write_overflow_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_ctxt_err_status_cnt[3]; +} + +static u64 access_pio_write_crosses_boundary_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_ctxt_err_status_cnt[2]; +} + +static u64 access_pio_disallowed_packet_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_ctxt_err_status_cnt[1]; +} + +static u64 access_pio_inconsistent_sop_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_ctxt_err_status_cnt[0]; +} + +/* + * Software counters corresponding to each of the + * error status bits within SendDmaEngErrStatus + */ +static u64 access_sdma_header_request_fifo_cor_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[23]; +} + +static u64 access_sdma_header_storage_cor_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[22]; +} + +static u64 access_sdma_packet_tracking_cor_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[21]; +} + +static u64 access_sdma_assembly_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[20]; +} + +static u64 access_sdma_desc_table_cor_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[19]; +} + +static u64 access_sdma_header_request_fifo_unc_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[18]; +} + +static u64 access_sdma_header_storage_unc_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[17]; +} + +static u64 access_sdma_packet_tracking_unc_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[16]; +} + +static u64 access_sdma_assembly_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[15]; +} + +static u64 access_sdma_desc_table_unc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[14]; +} + +static u64 access_sdma_timeout_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[13]; +} + +static u64 access_sdma_header_length_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[12]; +} + +static u64 access_sdma_header_address_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[11]; +} + +static u64 access_sdma_header_select_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[10]; +} + +static u64 access_sdma_reserved_9_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[9]; +} + +static u64 access_sdma_packet_desc_overflow_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[8]; +} + +static u64 access_sdma_length_mismatch_err_cnt(const struct cntr_entry *entry, + void *context, int vl, + int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[7]; +} + +static u64 access_sdma_halt_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[6]; +} + +static u64 access_sdma_mem_read_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[5]; +} + +static u64 access_sdma_first_desc_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[4]; +} + +static u64 access_sdma_tail_out_of_bounds_err_cnt( + const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[3]; +} + +static u64 access_sdma_too_long_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[2]; +} + +static u64 access_sdma_gen_mismatch_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[1]; +} + +static u64 access_sdma_wrong_dw_err_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + + return dd->sw_send_dma_eng_err_status_cnt[0]; +} + #define def_access_sw_cpu(cntr) \ static u64 access_sw_cpu_##cntr(const struct cntr_entry *entry, \ void *context, int vl, int mode, u64 data) \ @@ -1729,6 +4059,794 @@ static struct cntr_entry dev_cntrs[DEV_CNTR_LAST] = { access_sw_kmem_wait), [C_SW_SEND_SCHED] = CNTR_ELEM("SendSched", 0, 0, CNTR_NORMAL, access_sw_send_schedule), +/* MISC_ERR_STATUS */ +[C_MISC_PLL_LOCK_FAIL_ERR] = CNTR_ELEM("MISC_PLL_LOCK_FAIL_ERR", 0, 0, + CNTR_NORMAL, + access_misc_pll_lock_fail_err_cnt), +[C_MISC_MBIST_FAIL_ERR] = CNTR_ELEM("MISC_MBIST_FAIL_ERR", 0, 0, + CNTR_NORMAL, + access_misc_mbist_fail_err_cnt), +[C_MISC_INVALID_EEP_CMD_ERR] = CNTR_ELEM("MISC_INVALID_EEP_CMD_ERR", 0, 0, + CNTR_NORMAL, + access_misc_invalid_eep_cmd_err_cnt), +[C_MISC_EFUSE_DONE_PARITY_ERR] = CNTR_ELEM("MISC_EFUSE_DONE_PARITY_ERR", 0, 0, + CNTR_NORMAL, + access_misc_efuse_done_parity_err_cnt), +[C_MISC_EFUSE_WRITE_ERR] = CNTR_ELEM("MISC_EFUSE_WRITE_ERR", 0, 0, + CNTR_NORMAL, + access_misc_efuse_write_err_cnt), +[C_MISC_EFUSE_READ_BAD_ADDR_ERR] = CNTR_ELEM("MISC_EFUSE_READ_BAD_ADDR_ERR", 0, + 0, CNTR_NORMAL, + access_misc_efuse_read_bad_addr_err_cnt), +[C_MISC_EFUSE_CSR_PARITY_ERR] = CNTR_ELEM("MISC_EFUSE_CSR_PARITY_ERR", 0, 0, + CNTR_NORMAL, + access_misc_efuse_csr_parity_err_cnt), +[C_MISC_FW_AUTH_FAILED_ERR] = CNTR_ELEM("MISC_FW_AUTH_FAILED_ERR", 0, 0, + CNTR_NORMAL, + access_misc_fw_auth_failed_err_cnt), +[C_MISC_KEY_MISMATCH_ERR] = CNTR_ELEM("MISC_KEY_MISMATCH_ERR", 0, 0, + CNTR_NORMAL, + access_misc_key_mismatch_err_cnt), +[C_MISC_SBUS_WRITE_FAILED_ERR] = CNTR_ELEM("MISC_SBUS_WRITE_FAILED_ERR", 0, 0, + CNTR_NORMAL, + access_misc_sbus_write_failed_err_cnt), +[C_MISC_CSR_WRITE_BAD_ADDR_ERR] = CNTR_ELEM("MISC_CSR_WRITE_BAD_ADDR_ERR", 0, 0, + CNTR_NORMAL, + access_misc_csr_write_bad_addr_err_cnt), +[C_MISC_CSR_READ_BAD_ADDR_ERR] = CNTR_ELEM("MISC_CSR_READ_BAD_ADDR_ERR", 0, 0, + CNTR_NORMAL, + access_misc_csr_read_bad_addr_err_cnt), +[C_MISC_CSR_PARITY_ERR] = CNTR_ELEM("MISC_CSR_PARITY_ERR", 0, 0, + CNTR_NORMAL, + access_misc_csr_parity_err_cnt), +/* CceErrStatus */ +[C_CCE_ERR_STATUS_AGGREGATED_CNT] = CNTR_ELEM("CceErrStatusAggregatedCnt", 0, 0, + CNTR_NORMAL, + access_sw_cce_err_status_aggregated_cnt), +[C_CCE_MSIX_CSR_PARITY_ERR] = CNTR_ELEM("CceMsixCsrParityErr", 0, 0, + CNTR_NORMAL, + access_cce_msix_csr_parity_err_cnt), +[C_CCE_INT_MAP_UNC_ERR] = CNTR_ELEM("CceIntMapUncErr", 0, 0, + CNTR_NORMAL, + access_cce_int_map_unc_err_cnt), +[C_CCE_INT_MAP_COR_ERR] = CNTR_ELEM("CceIntMapCorErr", 0, 0, + CNTR_NORMAL, + access_cce_int_map_cor_err_cnt), +[C_CCE_MSIX_TABLE_UNC_ERR] = CNTR_ELEM("CceMsixTableUncErr", 0, 0, + CNTR_NORMAL, + access_cce_msix_table_unc_err_cnt), +[C_CCE_MSIX_TABLE_COR_ERR] = CNTR_ELEM("CceMsixTableCorErr", 0, 0, + CNTR_NORMAL, + access_cce_msix_table_cor_err_cnt), +[C_CCE_RXDMA_CONV_FIFO_PARITY_ERR] = CNTR_ELEM("CceRxdmaConvFifoParityErr", 0, + 0, CNTR_NORMAL, + access_cce_rxdma_conv_fifo_parity_err_cnt), +[C_CCE_RCPL_ASYNC_FIFO_PARITY_ERR] = CNTR_ELEM("CceRcplAsyncFifoParityErr", 0, + 0, CNTR_NORMAL, + access_cce_rcpl_async_fifo_parity_err_cnt), +[C_CCE_SEG_WRITE_BAD_ADDR_ERR] = CNTR_ELEM("CceSegWriteBadAddrErr", 0, 0, + CNTR_NORMAL, + access_cce_seg_write_bad_addr_err_cnt), +[C_CCE_SEG_READ_BAD_ADDR_ERR] = CNTR_ELEM("CceSegReadBadAddrErr", 0, 0, + CNTR_NORMAL, + access_cce_seg_read_bad_addr_err_cnt), +[C_LA_TRIGGERED] = CNTR_ELEM("Cce LATriggered", 0, 0, + CNTR_NORMAL, + access_la_triggered_cnt), +[C_CCE_TRGT_CPL_TIMEOUT_ERR] = CNTR_ELEM("CceTrgtCplTimeoutErr", 0, 0, + CNTR_NORMAL, + access_cce_trgt_cpl_timeout_err_cnt), +[C_PCIC_RECEIVE_PARITY_ERR] = CNTR_ELEM("PcicReceiveParityErr", 0, 0, + CNTR_NORMAL, + access_pcic_receive_parity_err_cnt), +[C_PCIC_TRANSMIT_BACK_PARITY_ERR] = CNTR_ELEM("PcicTransmitBackParityErr", 0, 0, + CNTR_NORMAL, + access_pcic_transmit_back_parity_err_cnt), +[C_PCIC_TRANSMIT_FRONT_PARITY_ERR] = CNTR_ELEM("PcicTransmitFrontParityErr", 0, + 0, CNTR_NORMAL, + access_pcic_transmit_front_parity_err_cnt), +[C_PCIC_CPL_DAT_Q_UNC_ERR] = CNTR_ELEM("PcicCplDatQUncErr", 0, 0, + CNTR_NORMAL, + access_pcic_cpl_dat_q_unc_err_cnt), +[C_PCIC_CPL_HD_Q_UNC_ERR] = CNTR_ELEM("PcicCplHdQUncErr", 0, 0, + CNTR_NORMAL, + access_pcic_cpl_hd_q_unc_err_cnt), +[C_PCIC_POST_DAT_Q_UNC_ERR] = CNTR_ELEM("PcicPostDatQUncErr", 0, 0, + CNTR_NORMAL, + access_pcic_post_dat_q_unc_err_cnt), +[C_PCIC_POST_HD_Q_UNC_ERR] = CNTR_ELEM("PcicPostHdQUncErr", 0, 0, + CNTR_NORMAL, + access_pcic_post_hd_q_unc_err_cnt), +[C_PCIC_RETRY_SOT_MEM_UNC_ERR] = CNTR_ELEM("PcicRetrySotMemUncErr", 0, 0, + CNTR_NORMAL, + access_pcic_retry_sot_mem_unc_err_cnt), +[C_PCIC_RETRY_MEM_UNC_ERR] = CNTR_ELEM("PcicRetryMemUncErr", 0, 0, + CNTR_NORMAL, + access_pcic_retry_mem_unc_err), +[C_PCIC_N_POST_DAT_Q_PARITY_ERR] = CNTR_ELEM("PcicNPostDatQParityErr", 0, 0, + CNTR_NORMAL, + access_pcic_n_post_dat_q_parity_err_cnt), +[C_PCIC_N_POST_H_Q_PARITY_ERR] = CNTR_ELEM("PcicNPostHQParityErr", 0, 0, + CNTR_NORMAL, + access_pcic_n_post_h_q_parity_err_cnt), +[C_PCIC_CPL_DAT_Q_COR_ERR] = CNTR_ELEM("PcicCplDatQCorErr", 0, 0, + CNTR_NORMAL, + access_pcic_cpl_dat_q_cor_err_cnt), +[C_PCIC_CPL_HD_Q_COR_ERR] = CNTR_ELEM("PcicCplHdQCorErr", 0, 0, + CNTR_NORMAL, + access_pcic_cpl_hd_q_cor_err_cnt), +[C_PCIC_POST_DAT_Q_COR_ERR] = CNTR_ELEM("PcicPostDatQCorErr", 0, 0, + CNTR_NORMAL, + access_pcic_post_dat_q_cor_err_cnt), +[C_PCIC_POST_HD_Q_COR_ERR] = CNTR_ELEM("PcicPostHdQCorErr", 0, 0, + CNTR_NORMAL, + access_pcic_post_hd_q_cor_err_cnt), +[C_PCIC_RETRY_SOT_MEM_COR_ERR] = CNTR_ELEM("PcicRetrySotMemCorErr", 0, 0, + CNTR_NORMAL, + access_pcic_retry_sot_mem_cor_err_cnt), +[C_PCIC_RETRY_MEM_COR_ERR] = CNTR_ELEM("PcicRetryMemCorErr", 0, 0, + CNTR_NORMAL, + access_pcic_retry_mem_cor_err_cnt), +[C_CCE_CLI1_ASYNC_FIFO_DBG_PARITY_ERR] = CNTR_ELEM( + "CceCli1AsyncFifoDbgParityError", 0, 0, + CNTR_NORMAL, + access_cce_cli1_async_fifo_dbg_parity_err_cnt), +[C_CCE_CLI1_ASYNC_FIFO_RXDMA_PARITY_ERR] = CNTR_ELEM( + "CceCli1AsyncFifoRxdmaParityError", 0, 0, + CNTR_NORMAL, + access_cce_cli1_async_fifo_rxdma_parity_err_cnt + ), +[C_CCE_CLI1_ASYNC_FIFO_SDMA_HD_PARITY_ERR] = CNTR_ELEM( + "CceCli1AsyncFifoSdmaHdParityErr", 0, 0, + CNTR_NORMAL, + access_cce_cli1_async_fifo_sdma_hd_parity_err_cnt), +[C_CCE_CLI1_ASYNC_FIFO_PIO_CRDT_PARITY_ERR] = CNTR_ELEM( + "CceCli1AsyncFifoPioCrdtParityErr", 0, 0, + CNTR_NORMAL, + access_cce_cl1_async_fifo_pio_crdt_parity_err_cnt), +[C_CCE_CLI2_ASYNC_FIFO_PARITY_ERR] = CNTR_ELEM("CceCli2AsyncFifoParityErr", 0, + 0, CNTR_NORMAL, + access_cce_cli2_async_fifo_parity_err_cnt), +[C_CCE_CSR_CFG_BUS_PARITY_ERR] = CNTR_ELEM("CceCsrCfgBusParityErr", 0, 0, + CNTR_NORMAL, + access_cce_csr_cfg_bus_parity_err_cnt), +[C_CCE_CLI0_ASYNC_FIFO_PARTIY_ERR] = CNTR_ELEM("CceCli0AsyncFifoParityErr", 0, + 0, CNTR_NORMAL, + access_cce_cli0_async_fifo_parity_err_cnt), +[C_CCE_RSPD_DATA_PARITY_ERR] = CNTR_ELEM("CceRspdDataParityErr", 0, 0, + CNTR_NORMAL, + access_cce_rspd_data_parity_err_cnt), +[C_CCE_TRGT_ACCESS_ERR] = CNTR_ELEM("CceTrgtAccessErr", 0, 0, + CNTR_NORMAL, + access_cce_trgt_access_err_cnt), +[C_CCE_TRGT_ASYNC_FIFO_PARITY_ERR] = CNTR_ELEM("CceTrgtAsyncFifoParityErr", 0, + 0, CNTR_NORMAL, + access_cce_trgt_async_fifo_parity_err_cnt), +[C_CCE_CSR_WRITE_BAD_ADDR_ERR] = CNTR_ELEM("CceCsrWriteBadAddrErr", 0, 0, + CNTR_NORMAL, + access_cce_csr_write_bad_addr_err_cnt), +[C_CCE_CSR_READ_BAD_ADDR_ERR] = CNTR_ELEM("CceCsrReadBadAddrErr", 0, 0, + CNTR_NORMAL, + access_cce_csr_read_bad_addr_err_cnt), +[C_CCE_CSR_PARITY_ERR] = CNTR_ELEM("CceCsrParityErr", 0, 0, + CNTR_NORMAL, + access_ccs_csr_parity_err_cnt), + +/* RcvErrStatus */ +[C_RX_CSR_PARITY_ERR] = CNTR_ELEM("RxCsrParityErr", 0, 0, + CNTR_NORMAL, + access_rx_csr_parity_err_cnt), +[C_RX_CSR_WRITE_BAD_ADDR_ERR] = CNTR_ELEM("RxCsrWriteBadAddrErr", 0, 0, + CNTR_NORMAL, + access_rx_csr_write_bad_addr_err_cnt), +[C_RX_CSR_READ_BAD_ADDR_ERR] = CNTR_ELEM("RxCsrReadBadAddrErr", 0, 0, + CNTR_NORMAL, + access_rx_csr_read_bad_addr_err_cnt), +[C_RX_DMA_CSR_UNC_ERR] = CNTR_ELEM("RxDmaCsrUncErr", 0, 0, + CNTR_NORMAL, + access_rx_dma_csr_unc_err_cnt), +[C_RX_DMA_DQ_FSM_ENCODING_ERR] = CNTR_ELEM("RxDmaDqFsmEncodingErr", 0, 0, + CNTR_NORMAL, + access_rx_dma_dq_fsm_encoding_err_cnt), +[C_RX_DMA_EQ_FSM_ENCODING_ERR] = CNTR_ELEM("RxDmaEqFsmEncodingErr", 0, 0, + CNTR_NORMAL, + access_rx_dma_eq_fsm_encoding_err_cnt), +[C_RX_DMA_CSR_PARITY_ERR] = CNTR_ELEM("RxDmaCsrParityErr", 0, 0, + CNTR_NORMAL, + access_rx_dma_csr_parity_err_cnt), +[C_RX_RBUF_DATA_COR_ERR] = CNTR_ELEM("RxRbufDataCorErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_data_cor_err_cnt), +[C_RX_RBUF_DATA_UNC_ERR] = CNTR_ELEM("RxRbufDataUncErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_data_unc_err_cnt), +[C_RX_DMA_DATA_FIFO_RD_COR_ERR] = CNTR_ELEM("RxDmaDataFifoRdCorErr", 0, 0, + CNTR_NORMAL, + access_rx_dma_data_fifo_rd_cor_err_cnt), +[C_RX_DMA_DATA_FIFO_RD_UNC_ERR] = CNTR_ELEM("RxDmaDataFifoRdUncErr", 0, 0, + CNTR_NORMAL, + access_rx_dma_data_fifo_rd_unc_err_cnt), +[C_RX_DMA_HDR_FIFO_RD_COR_ERR] = CNTR_ELEM("RxDmaHdrFifoRdCorErr", 0, 0, + CNTR_NORMAL, + access_rx_dma_hdr_fifo_rd_cor_err_cnt), +[C_RX_DMA_HDR_FIFO_RD_UNC_ERR] = CNTR_ELEM("RxDmaHdrFifoRdUncErr", 0, 0, + CNTR_NORMAL, + access_rx_dma_hdr_fifo_rd_unc_err_cnt), +[C_RX_RBUF_DESC_PART2_COR_ERR] = CNTR_ELEM("RxRbufDescPart2CorErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_desc_part2_cor_err_cnt), +[C_RX_RBUF_DESC_PART2_UNC_ERR] = CNTR_ELEM("RxRbufDescPart2UncErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_desc_part2_unc_err_cnt), +[C_RX_RBUF_DESC_PART1_COR_ERR] = CNTR_ELEM("RxRbufDescPart1CorErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_desc_part1_cor_err_cnt), +[C_RX_RBUF_DESC_PART1_UNC_ERR] = CNTR_ELEM("RxRbufDescPart1UncErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_desc_part1_unc_err_cnt), +[C_RX_HQ_INTR_FSM_ERR] = CNTR_ELEM("RxHqIntrFsmErr", 0, 0, + CNTR_NORMAL, + access_rx_hq_intr_fsm_err_cnt), +[C_RX_HQ_INTR_CSR_PARITY_ERR] = CNTR_ELEM("RxHqIntrCsrParityErr", 0, 0, + CNTR_NORMAL, + access_rx_hq_intr_csr_parity_err_cnt), +[C_RX_LOOKUP_CSR_PARITY_ERR] = CNTR_ELEM("RxLookupCsrParityErr", 0, 0, + CNTR_NORMAL, + access_rx_lookup_csr_parity_err_cnt), +[C_RX_LOOKUP_RCV_ARRAY_COR_ERR] = CNTR_ELEM("RxLookupRcvArrayCorErr", 0, 0, + CNTR_NORMAL, + access_rx_lookup_rcv_array_cor_err_cnt), +[C_RX_LOOKUP_RCV_ARRAY_UNC_ERR] = CNTR_ELEM("RxLookupRcvArrayUncErr", 0, 0, + CNTR_NORMAL, + access_rx_lookup_rcv_array_unc_err_cnt), +[C_RX_LOOKUP_DES_PART2_PARITY_ERR] = CNTR_ELEM("RxLookupDesPart2ParityErr", 0, + 0, CNTR_NORMAL, + access_rx_lookup_des_part2_parity_err_cnt), +[C_RX_LOOKUP_DES_PART1_UNC_COR_ERR] = CNTR_ELEM("RxLookupDesPart1UncCorErr", 0, + 0, CNTR_NORMAL, + access_rx_lookup_des_part1_unc_cor_err_cnt), +[C_RX_LOOKUP_DES_PART1_UNC_ERR] = CNTR_ELEM("RxLookupDesPart1UncErr", 0, 0, + CNTR_NORMAL, + access_rx_lookup_des_part1_unc_err_cnt), +[C_RX_RBUF_NEXT_FREE_BUF_COR_ERR] = CNTR_ELEM("RxRbufNextFreeBufCorErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_next_free_buf_cor_err_cnt), +[C_RX_RBUF_NEXT_FREE_BUF_UNC_ERR] = CNTR_ELEM("RxRbufNextFreeBufUncErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_next_free_buf_unc_err_cnt), +[C_RX_RBUF_FL_INIT_WR_ADDR_PARITY_ERR] = CNTR_ELEM( + "RxRbufFlInitWrAddrParityErr", 0, 0, + CNTR_NORMAL, + access_rbuf_fl_init_wr_addr_parity_err_cnt), +[C_RX_RBUF_FL_INITDONE_PARITY_ERR] = CNTR_ELEM("RxRbufFlInitdoneParityErr", 0, + 0, CNTR_NORMAL, + access_rx_rbuf_fl_initdone_parity_err_cnt), +[C_RX_RBUF_FL_WRITE_ADDR_PARITY_ERR] = CNTR_ELEM("RxRbufFlWrAddrParityErr", 0, + 0, CNTR_NORMAL, + access_rx_rbuf_fl_write_addr_parity_err_cnt), +[C_RX_RBUF_FL_RD_ADDR_PARITY_ERR] = CNTR_ELEM("RxRbufFlRdAddrParityErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_fl_rd_addr_parity_err_cnt), +[C_RX_RBUF_EMPTY_ERR] = CNTR_ELEM("RxRbufEmptyErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_empty_err_cnt), +[C_RX_RBUF_FULL_ERR] = CNTR_ELEM("RxRbufFullErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_full_err_cnt), +[C_RX_RBUF_BAD_LOOKUP_ERR] = CNTR_ELEM("RxRBufBadLookupErr", 0, 0, + CNTR_NORMAL, + access_rbuf_bad_lookup_err_cnt), +[C_RX_RBUF_CTX_ID_PARITY_ERR] = CNTR_ELEM("RxRbufCtxIdParityErr", 0, 0, + CNTR_NORMAL, + access_rbuf_ctx_id_parity_err_cnt), +[C_RX_RBUF_CSR_QEOPDW_PARITY_ERR] = CNTR_ELEM("RxRbufCsrQEOPDWParityErr", 0, 0, + CNTR_NORMAL, + access_rbuf_csr_qeopdw_parity_err_cnt), +[C_RX_RBUF_CSR_Q_NUM_OF_PKT_PARITY_ERR] = CNTR_ELEM( + "RxRbufCsrQNumOfPktParityErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_csr_q_num_of_pkt_parity_err_cnt), +[C_RX_RBUF_CSR_Q_T1_PTR_PARITY_ERR] = CNTR_ELEM( + "RxRbufCsrQTlPtrParityErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_csr_q_t1_ptr_parity_err_cnt), +[C_RX_RBUF_CSR_Q_HD_PTR_PARITY_ERR] = CNTR_ELEM("RxRbufCsrQHdPtrParityErr", 0, + 0, CNTR_NORMAL, + access_rx_rbuf_csr_q_hd_ptr_parity_err_cnt), +[C_RX_RBUF_CSR_Q_VLD_BIT_PARITY_ERR] = CNTR_ELEM("RxRbufCsrQVldBitParityErr", 0, + 0, CNTR_NORMAL, + access_rx_rbuf_csr_q_vld_bit_parity_err_cnt), +[C_RX_RBUF_CSR_Q_NEXT_BUF_PARITY_ERR] = CNTR_ELEM("RxRbufCsrQNextBufParityErr", + 0, 0, CNTR_NORMAL, + access_rx_rbuf_csr_q_next_buf_parity_err_cnt), +[C_RX_RBUF_CSR_Q_ENT_CNT_PARITY_ERR] = CNTR_ELEM("RxRbufCsrQEntCntParityErr", 0, + 0, CNTR_NORMAL, + access_rx_rbuf_csr_q_ent_cnt_parity_err_cnt), +[C_RX_RBUF_CSR_Q_HEAD_BUF_NUM_PARITY_ERR] = CNTR_ELEM( + "RxRbufCsrQHeadBufNumParityErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_csr_q_head_buf_num_parity_err_cnt), +[C_RX_RBUF_BLOCK_LIST_READ_COR_ERR] = CNTR_ELEM("RxRbufBlockListReadCorErr", 0, + 0, CNTR_NORMAL, + access_rx_rbuf_block_list_read_cor_err_cnt), +[C_RX_RBUF_BLOCK_LIST_READ_UNC_ERR] = CNTR_ELEM("RxRbufBlockListReadUncErr", 0, + 0, CNTR_NORMAL, + access_rx_rbuf_block_list_read_unc_err_cnt), +[C_RX_RBUF_LOOKUP_DES_COR_ERR] = CNTR_ELEM("RxRbufLookupDesCorErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_lookup_des_cor_err_cnt), +[C_RX_RBUF_LOOKUP_DES_UNC_ERR] = CNTR_ELEM("RxRbufLookupDesUncErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_lookup_des_unc_err_cnt), +[C_RX_RBUF_LOOKUP_DES_REG_UNC_COR_ERR] = CNTR_ELEM( + "RxRbufLookupDesRegUncCorErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_lookup_des_reg_unc_cor_err_cnt), +[C_RX_RBUF_LOOKUP_DES_REG_UNC_ERR] = CNTR_ELEM("RxRbufLookupDesRegUncErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_lookup_des_reg_unc_err_cnt), +[C_RX_RBUF_FREE_LIST_COR_ERR] = CNTR_ELEM("RxRbufFreeListCorErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_free_list_cor_err_cnt), +[C_RX_RBUF_FREE_LIST_UNC_ERR] = CNTR_ELEM("RxRbufFreeListUncErr", 0, 0, + CNTR_NORMAL, + access_rx_rbuf_free_list_unc_err_cnt), +[C_RX_RCV_FSM_ENCODING_ERR] = CNTR_ELEM("RxRcvFsmEncodingErr", 0, 0, + CNTR_NORMAL, + access_rx_rcv_fsm_encoding_err_cnt), +[C_RX_DMA_FLAG_COR_ERR] = CNTR_ELEM("RxDmaFlagCorErr", 0, 0, + CNTR_NORMAL, + access_rx_dma_flag_cor_err_cnt), +[C_RX_DMA_FLAG_UNC_ERR] = CNTR_ELEM("RxDmaFlagUncErr", 0, 0, + CNTR_NORMAL, + access_rx_dma_flag_unc_err_cnt), +[C_RX_DC_SOP_EOP_PARITY_ERR] = CNTR_ELEM("RxDcSopEopParityErr", 0, 0, + CNTR_NORMAL, + access_rx_dc_sop_eop_parity_err_cnt), +[C_RX_RCV_CSR_PARITY_ERR] = CNTR_ELEM("RxRcvCsrParityErr", 0, 0, + CNTR_NORMAL, + access_rx_rcv_csr_parity_err_cnt), +[C_RX_RCV_QP_MAP_TABLE_COR_ERR] = CNTR_ELEM("RxRcvQpMapTableCorErr", 0, 0, + CNTR_NORMAL, + access_rx_rcv_qp_map_table_cor_err_cnt), +[C_RX_RCV_QP_MAP_TABLE_UNC_ERR] = CNTR_ELEM("RxRcvQpMapTableUncErr", 0, 0, + CNTR_NORMAL, + access_rx_rcv_qp_map_table_unc_err_cnt), +[C_RX_RCV_DATA_COR_ERR] = CNTR_ELEM("RxRcvDataCorErr", 0, 0, + CNTR_NORMAL, + access_rx_rcv_data_cor_err_cnt), +[C_RX_RCV_DATA_UNC_ERR] = CNTR_ELEM("RxRcvDataUncErr", 0, 0, + CNTR_NORMAL, + access_rx_rcv_data_unc_err_cnt), +[C_RX_RCV_HDR_COR_ERR] = CNTR_ELEM("RxRcvHdrCorErr", 0, 0, + CNTR_NORMAL, + access_rx_rcv_hdr_cor_err_cnt), +[C_RX_RCV_HDR_UNC_ERR] = CNTR_ELEM("RxRcvHdrUncErr", 0, 0, + CNTR_NORMAL, + access_rx_rcv_hdr_unc_err_cnt), +[C_RX_DC_INTF_PARITY_ERR] = CNTR_ELEM("RxDcIntfParityErr", 0, 0, + CNTR_NORMAL, + access_rx_dc_intf_parity_err_cnt), +[C_RX_DMA_CSR_COR_ERR] = CNTR_ELEM("RxDmaCsrCorErr", 0, 0, + CNTR_NORMAL, + access_rx_dma_csr_cor_err_cnt), +/* SendPioErrStatus */ +[C_PIO_PEC_SOP_HEAD_PARITY_ERR] = CNTR_ELEM("PioPecSopHeadParityErr", 0, 0, + CNTR_NORMAL, + access_pio_pec_sop_head_parity_err_cnt), +[C_PIO_PCC_SOP_HEAD_PARITY_ERR] = CNTR_ELEM("PioPccSopHeadParityErr", 0, 0, + CNTR_NORMAL, + access_pio_pcc_sop_head_parity_err_cnt), +[C_PIO_LAST_RETURNED_CNT_PARITY_ERR] = CNTR_ELEM("PioLastReturnedCntParityErr", + 0, 0, CNTR_NORMAL, + access_pio_last_returned_cnt_parity_err_cnt), +[C_PIO_CURRENT_FREE_CNT_PARITY_ERR] = CNTR_ELEM("PioCurrentFreeCntParityErr", 0, + 0, CNTR_NORMAL, + access_pio_current_free_cnt_parity_err_cnt), +[C_PIO_RSVD_31_ERR] = CNTR_ELEM("Pio Reserved 31", 0, 0, + CNTR_NORMAL, + access_pio_reserved_31_err_cnt), +[C_PIO_RSVD_30_ERR] = CNTR_ELEM("Pio Reserved 30", 0, 0, + CNTR_NORMAL, + access_pio_reserved_30_err_cnt), +[C_PIO_PPMC_SOP_LEN_ERR] = CNTR_ELEM("PioPpmcSopLenErr", 0, 0, + CNTR_NORMAL, + access_pio_ppmc_sop_len_err_cnt), +[C_PIO_PPMC_BQC_MEM_PARITY_ERR] = CNTR_ELEM("PioPpmcBqcMemParityErr", 0, 0, + CNTR_NORMAL, + access_pio_ppmc_bqc_mem_parity_err_cnt), +[C_PIO_VL_FIFO_PARITY_ERR] = CNTR_ELEM("PioVlFifoParityErr", 0, 0, + CNTR_NORMAL, + access_pio_vl_fifo_parity_err_cnt), +[C_PIO_VLF_SOP_PARITY_ERR] = CNTR_ELEM("PioVlfSopParityErr", 0, 0, + CNTR_NORMAL, + access_pio_vlf_sop_parity_err_cnt), +[C_PIO_VLF_V1_LEN_PARITY_ERR] = CNTR_ELEM("PioVlfVlLenParityErr", 0, 0, + CNTR_NORMAL, + access_pio_vlf_v1_len_parity_err_cnt), +[C_PIO_BLOCK_QW_COUNT_PARITY_ERR] = CNTR_ELEM("PioBlockQwCountParityErr", 0, 0, + CNTR_NORMAL, + access_pio_block_qw_count_parity_err_cnt), +[C_PIO_WRITE_QW_VALID_PARITY_ERR] = CNTR_ELEM("PioWriteQwValidParityErr", 0, 0, + CNTR_NORMAL, + access_pio_write_qw_valid_parity_err_cnt), +[C_PIO_STATE_MACHINE_ERR] = CNTR_ELEM("PioStateMachineErr", 0, 0, + CNTR_NORMAL, + access_pio_state_machine_err_cnt), +[C_PIO_WRITE_DATA_PARITY_ERR] = CNTR_ELEM("PioWriteDataParityErr", 0, 0, + CNTR_NORMAL, + access_pio_write_data_parity_err_cnt), +[C_PIO_HOST_ADDR_MEM_COR_ERR] = CNTR_ELEM("PioHostAddrMemCorErr", 0, 0, + CNTR_NORMAL, + access_pio_host_addr_mem_cor_err_cnt), +[C_PIO_HOST_ADDR_MEM_UNC_ERR] = CNTR_ELEM("PioHostAddrMemUncErr", 0, 0, + CNTR_NORMAL, + access_pio_host_addr_mem_unc_err_cnt), +[C_PIO_PKT_EVICT_SM_OR_ARM_SM_ERR] = CNTR_ELEM("PioPktEvictSmOrArbSmErr", 0, 0, + CNTR_NORMAL, + access_pio_pkt_evict_sm_or_arb_sm_err_cnt), +[C_PIO_INIT_SM_IN_ERR] = CNTR_ELEM("PioInitSmInErr", 0, 0, + CNTR_NORMAL, + access_pio_init_sm_in_err_cnt), +[C_PIO_PPMC_PBL_FIFO_ERR] = CNTR_ELEM("PioPpmcPblFifoErr", 0, 0, + CNTR_NORMAL, + access_pio_ppmc_pbl_fifo_err_cnt), +[C_PIO_CREDIT_RET_FIFO_PARITY_ERR] = CNTR_ELEM("PioCreditRetFifoParityErr", 0, + 0, CNTR_NORMAL, + access_pio_credit_ret_fifo_parity_err_cnt), +[C_PIO_V1_LEN_MEM_BANK1_COR_ERR] = CNTR_ELEM("PioVlLenMemBank1CorErr", 0, 0, + CNTR_NORMAL, + access_pio_v1_len_mem_bank1_cor_err_cnt), +[C_PIO_V1_LEN_MEM_BANK0_COR_ERR] = CNTR_ELEM("PioVlLenMemBank0CorErr", 0, 0, + CNTR_NORMAL, + access_pio_v1_len_mem_bank0_cor_err_cnt), +[C_PIO_V1_LEN_MEM_BANK1_UNC_ERR] = CNTR_ELEM("PioVlLenMemBank1UncErr", 0, 0, + CNTR_NORMAL, + access_pio_v1_len_mem_bank1_unc_err_cnt), +[C_PIO_V1_LEN_MEM_BANK0_UNC_ERR] = CNTR_ELEM("PioVlLenMemBank0UncErr", 0, 0, + CNTR_NORMAL, + access_pio_v1_len_mem_bank0_unc_err_cnt), +[C_PIO_SM_PKT_RESET_PARITY_ERR] = CNTR_ELEM("PioSmPktResetParityErr", 0, 0, + CNTR_NORMAL, + access_pio_sm_pkt_reset_parity_err_cnt), +[C_PIO_PKT_EVICT_FIFO_PARITY_ERR] = CNTR_ELEM("PioPktEvictFifoParityErr", 0, 0, + CNTR_NORMAL, + access_pio_pkt_evict_fifo_parity_err_cnt), +[C_PIO_SBRDCTRL_CRREL_FIFO_PARITY_ERR] = CNTR_ELEM( + "PioSbrdctrlCrrelFifoParityErr", 0, 0, + CNTR_NORMAL, + access_pio_sbrdctrl_crrel_fifo_parity_err_cnt), +[C_PIO_SBRDCTL_CRREL_PARITY_ERR] = CNTR_ELEM("PioSbrdctlCrrelParityErr", 0, 0, + CNTR_NORMAL, + access_pio_sbrdctl_crrel_parity_err_cnt), +[C_PIO_PEC_FIFO_PARITY_ERR] = CNTR_ELEM("PioPecFifoParityErr", 0, 0, + CNTR_NORMAL, + access_pio_pec_fifo_parity_err_cnt), +[C_PIO_PCC_FIFO_PARITY_ERR] = CNTR_ELEM("PioPccFifoParityErr", 0, 0, + CNTR_NORMAL, + access_pio_pcc_fifo_parity_err_cnt), +[C_PIO_SB_MEM_FIFO1_ERR] = CNTR_ELEM("PioSbMemFifo1Err", 0, 0, + CNTR_NORMAL, + access_pio_sb_mem_fifo1_err_cnt), +[C_PIO_SB_MEM_FIFO0_ERR] = CNTR_ELEM("PioSbMemFifo0Err", 0, 0, + CNTR_NORMAL, + access_pio_sb_mem_fifo0_err_cnt), +[C_PIO_CSR_PARITY_ERR] = CNTR_ELEM("PioCsrParityErr", 0, 0, + CNTR_NORMAL, + access_pio_csr_parity_err_cnt), +[C_PIO_WRITE_ADDR_PARITY_ERR] = CNTR_ELEM("PioWriteAddrParityErr", 0, 0, + CNTR_NORMAL, + access_pio_write_addr_parity_err_cnt), +[C_PIO_WRITE_BAD_CTXT_ERR] = CNTR_ELEM("PioWriteBadCtxtErr", 0, 0, + CNTR_NORMAL, + access_pio_write_bad_ctxt_err_cnt), +/* SendDmaErrStatus */ +[C_SDMA_PCIE_REQ_TRACKING_COR_ERR] = CNTR_ELEM("SDmaPcieReqTrackingCorErr", 0, + 0, CNTR_NORMAL, + access_sdma_pcie_req_tracking_cor_err_cnt), +[C_SDMA_PCIE_REQ_TRACKING_UNC_ERR] = CNTR_ELEM("SDmaPcieReqTrackingUncErr", 0, + 0, CNTR_NORMAL, + access_sdma_pcie_req_tracking_unc_err_cnt), +[C_SDMA_CSR_PARITY_ERR] = CNTR_ELEM("SDmaCsrParityErr", 0, 0, + CNTR_NORMAL, + access_sdma_csr_parity_err_cnt), +[C_SDMA_RPY_TAG_ERR] = CNTR_ELEM("SDmaRpyTagErr", 0, 0, + CNTR_NORMAL, + access_sdma_rpy_tag_err_cnt), +/* SendEgressErrStatus */ +[C_TX_READ_PIO_MEMORY_CSR_UNC_ERR] = CNTR_ELEM("TxReadPioMemoryCsrUncErr", 0, 0, + CNTR_NORMAL, + access_tx_read_pio_memory_csr_unc_err_cnt), +[C_TX_READ_SDMA_MEMORY_CSR_UNC_ERR] = CNTR_ELEM("TxReadSdmaMemoryCsrUncErr", 0, + 0, CNTR_NORMAL, + access_tx_read_sdma_memory_csr_err_cnt), +[C_TX_EGRESS_FIFO_COR_ERR] = CNTR_ELEM("TxEgressFifoCorErr", 0, 0, + CNTR_NORMAL, + access_tx_egress_fifo_cor_err_cnt), +[C_TX_READ_PIO_MEMORY_COR_ERR] = CNTR_ELEM("TxReadPioMemoryCorErr", 0, 0, + CNTR_NORMAL, + access_tx_read_pio_memory_cor_err_cnt), +[C_TX_READ_SDMA_MEMORY_COR_ERR] = CNTR_ELEM("TxReadSdmaMemoryCorErr", 0, 0, + CNTR_NORMAL, + access_tx_read_sdma_memory_cor_err_cnt), +[C_TX_SB_HDR_COR_ERR] = CNTR_ELEM("TxSbHdrCorErr", 0, 0, + CNTR_NORMAL, + access_tx_sb_hdr_cor_err_cnt), +[C_TX_CREDIT_OVERRUN_ERR] = CNTR_ELEM("TxCreditOverrunErr", 0, 0, + CNTR_NORMAL, + access_tx_credit_overrun_err_cnt), +[C_TX_LAUNCH_FIFO8_COR_ERR] = CNTR_ELEM("TxLaunchFifo8CorErr", 0, 0, + CNTR_NORMAL, + access_tx_launch_fifo8_cor_err_cnt), +[C_TX_LAUNCH_FIFO7_COR_ERR] = CNTR_ELEM("TxLaunchFifo7CorErr", 0, 0, + CNTR_NORMAL, + access_tx_launch_fifo7_cor_err_cnt), +[C_TX_LAUNCH_FIFO6_COR_ERR] = CNTR_ELEM("TxLaunchFifo6CorErr", 0, 0, + CNTR_NORMAL, + access_tx_launch_fifo6_cor_err_cnt), +[C_TX_LAUNCH_FIFO5_COR_ERR] = CNTR_ELEM("TxLaunchFifo5CorErr", 0, 0, + CNTR_NORMAL, + access_tx_launch_fifo5_cor_err_cnt), +[C_TX_LAUNCH_FIFO4_COR_ERR] = CNTR_ELEM("TxLaunchFifo4CorErr", 0, 0, + CNTR_NORMAL, + access_tx_launch_fifo4_cor_err_cnt), +[C_TX_LAUNCH_FIFO3_COR_ERR] = CNTR_ELEM("TxLaunchFifo3CorErr", 0, 0, + CNTR_NORMAL, + access_tx_launch_fifo3_cor_err_cnt), +[C_TX_LAUNCH_FIFO2_COR_ERR] = CNTR_ELEM("TxLaunchFifo2CorErr", 0, 0, + CNTR_NORMAL, + access_tx_launch_fifo2_cor_err_cnt), +[C_TX_LAUNCH_FIFO1_COR_ERR] = CNTR_ELEM("TxLaunchFifo1CorErr", 0, 0, + CNTR_NORMAL, + access_tx_launch_fifo1_cor_err_cnt), +[C_TX_LAUNCH_FIFO0_COR_ERR] = CNTR_ELEM("TxLaunchFifo0CorErr", 0, 0, + CNTR_NORMAL, + access_tx_launch_fifo0_cor_err_cnt), +[C_TX_CREDIT_RETURN_VL_ERR] = CNTR_ELEM("TxCreditReturnVLErr", 0, 0, + CNTR_NORMAL, + access_tx_credit_return_vl_err_cnt), +[C_TX_HCRC_INSERTION_ERR] = CNTR_ELEM("TxHcrcInsertionErr", 0, 0, + CNTR_NORMAL, + access_tx_hcrc_insertion_err_cnt), +[C_TX_EGRESS_FIFI_UNC_ERR] = CNTR_ELEM("TxEgressFifoUncErr", 0, 0, + CNTR_NORMAL, + access_tx_egress_fifo_unc_err_cnt), +[C_TX_READ_PIO_MEMORY_UNC_ERR] = CNTR_ELEM("TxReadPioMemoryUncErr", 0, 0, + CNTR_NORMAL, + access_tx_read_pio_memory_unc_err_cnt), +[C_TX_READ_SDMA_MEMORY_UNC_ERR] = CNTR_ELEM("TxReadSdmaMemoryUncErr", 0, 0, + CNTR_NORMAL, + access_tx_read_sdma_memory_unc_err_cnt), +[C_TX_SB_HDR_UNC_ERR] = CNTR_ELEM("TxSbHdrUncErr", 0, 0, + CNTR_NORMAL, + access_tx_sb_hdr_unc_err_cnt), +[C_TX_CREDIT_RETURN_PARITY_ERR] = CNTR_ELEM("TxCreditReturnParityErr", 0, 0, + CNTR_NORMAL, + access_tx_credit_return_partiy_err_cnt), +[C_TX_LAUNCH_FIFO8_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo8UncOrParityErr", + 0, 0, CNTR_NORMAL, + access_tx_launch_fifo8_unc_or_parity_err_cnt), +[C_TX_LAUNCH_FIFO7_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo7UncOrParityErr", + 0, 0, CNTR_NORMAL, + access_tx_launch_fifo7_unc_or_parity_err_cnt), +[C_TX_LAUNCH_FIFO6_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo6UncOrParityErr", + 0, 0, CNTR_NORMAL, + access_tx_launch_fifo6_unc_or_parity_err_cnt), +[C_TX_LAUNCH_FIFO5_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo5UncOrParityErr", + 0, 0, CNTR_NORMAL, + access_tx_launch_fifo5_unc_or_parity_err_cnt), +[C_TX_LAUNCH_FIFO4_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo4UncOrParityErr", + 0, 0, CNTR_NORMAL, + access_tx_launch_fifo4_unc_or_parity_err_cnt), +[C_TX_LAUNCH_FIFO3_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo3UncOrParityErr", + 0, 0, CNTR_NORMAL, + access_tx_launch_fifo3_unc_or_parity_err_cnt), +[C_TX_LAUNCH_FIFO2_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo2UncOrParityErr", + 0, 0, CNTR_NORMAL, + access_tx_launch_fifo2_unc_or_parity_err_cnt), +[C_TX_LAUNCH_FIFO1_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo1UncOrParityErr", + 0, 0, CNTR_NORMAL, + access_tx_launch_fifo1_unc_or_parity_err_cnt), +[C_TX_LAUNCH_FIFO0_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo0UncOrParityErr", + 0, 0, CNTR_NORMAL, + access_tx_launch_fifo0_unc_or_parity_err_cnt), +[C_TX_SDMA15_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma15DisallowedPacketErr", + 0, 0, CNTR_NORMAL, + access_tx_sdma15_disallowed_packet_err_cnt), +[C_TX_SDMA14_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma14DisallowedPacketErr", + 0, 0, CNTR_NORMAL, + access_tx_sdma14_disallowed_packet_err_cnt), +[C_TX_SDMA13_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma13DisallowedPacketErr", + 0, 0, CNTR_NORMAL, + access_tx_sdma13_disallowed_packet_err_cnt), +[C_TX_SDMA12_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma12DisallowedPacketErr", + 0, 0, CNTR_NORMAL, + access_tx_sdma12_disallowed_packet_err_cnt), +[C_TX_SDMA11_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma11DisallowedPacketErr", + 0, 0, CNTR_NORMAL, + access_tx_sdma11_disallowed_packet_err_cnt), +[C_TX_SDMA10_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma10DisallowedPacketErr", + 0, 0, CNTR_NORMAL, + access_tx_sdma10_disallowed_packet_err_cnt), +[C_TX_SDMA9_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma9DisallowedPacketErr", + 0, 0, CNTR_NORMAL, + access_tx_sdma9_disallowed_packet_err_cnt), +[C_TX_SDMA8_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma8DisallowedPacketErr", + 0, 0, CNTR_NORMAL, + access_tx_sdma8_disallowed_packet_err_cnt), +[C_TX_SDMA7_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma7DisallowedPacketErr", + 0, 0, CNTR_NORMAL, + access_tx_sdma7_disallowed_packet_err_cnt), +[C_TX_SDMA6_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma6DisallowedPacketErr", + 0, 0, CNTR_NORMAL, + access_tx_sdma6_disallowed_packet_err_cnt), +[C_TX_SDMA5_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma5DisallowedPacketErr", + 0, 0, CNTR_NORMAL, + access_tx_sdma5_disallowed_packet_err_cnt), +[C_TX_SDMA4_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma4DisallowedPacketErr", + 0, 0, CNTR_NORMAL, + access_tx_sdma4_disallowed_packet_err_cnt), +[C_TX_SDMA3_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma3DisallowedPacketErr", + 0, 0, CNTR_NORMAL, + access_tx_sdma3_disallowed_packet_err_cnt), +[C_TX_SDMA2_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma2DisallowedPacketErr", + 0, 0, CNTR_NORMAL, + access_tx_sdma2_disallowed_packet_err_cnt), +[C_TX_SDMA1_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma1DisallowedPacketErr", + 0, 0, CNTR_NORMAL, + access_tx_sdma1_disallowed_packet_err_cnt), +[C_TX_SDMA0_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma0DisallowedPacketErr", + 0, 0, CNTR_NORMAL, + access_tx_sdma0_disallowed_packet_err_cnt), +[C_TX_CONFIG_PARITY_ERR] = CNTR_ELEM("TxConfigParityErr", 0, 0, + CNTR_NORMAL, + access_tx_config_parity_err_cnt), +[C_TX_SBRD_CTL_CSR_PARITY_ERR] = CNTR_ELEM("TxSbrdCtlCsrParityErr", 0, 0, + CNTR_NORMAL, + access_tx_sbrd_ctl_csr_parity_err_cnt), +[C_TX_LAUNCH_CSR_PARITY_ERR] = CNTR_ELEM("TxLaunchCsrParityErr", 0, 0, + CNTR_NORMAL, + access_tx_launch_csr_parity_err_cnt), +[C_TX_ILLEGAL_CL_ERR] = CNTR_ELEM("TxIllegalVLErr", 0, 0, + CNTR_NORMAL, + access_tx_illegal_vl_err_cnt), +[C_TX_SBRD_CTL_STATE_MACHINE_PARITY_ERR] = CNTR_ELEM( + "TxSbrdCtlStateMachineParityErr", 0, 0, + CNTR_NORMAL, + access_tx_sbrd_ctl_state_machine_parity_err_cnt), +[C_TX_RESERVED_10] = CNTR_ELEM("Tx Egress Reserved 10", 0, 0, + CNTR_NORMAL, + access_egress_reserved_10_err_cnt), +[C_TX_RESERVED_9] = CNTR_ELEM("Tx Egress Reserved 9", 0, 0, + CNTR_NORMAL, + access_egress_reserved_9_err_cnt), +[C_TX_SDMA_LAUNCH_INTF_PARITY_ERR] = CNTR_ELEM("TxSdmaLaunchIntfParityErr", + 0, 0, CNTR_NORMAL, + access_tx_sdma_launch_intf_parity_err_cnt), +[C_TX_PIO_LAUNCH_INTF_PARITY_ERR] = CNTR_ELEM("TxPioLaunchIntfParityErr", 0, 0, + CNTR_NORMAL, + access_tx_pio_launch_intf_parity_err_cnt), +[C_TX_RESERVED_6] = CNTR_ELEM("Tx Egress Reserved 6", 0, 0, + CNTR_NORMAL, + access_egress_reserved_6_err_cnt), +[C_TX_INCORRECT_LINK_STATE_ERR] = CNTR_ELEM("TxIncorrectLinkStateErr", 0, 0, + CNTR_NORMAL, + access_tx_incorrect_link_state_err_cnt), +[C_TX_LINK_DOWN_ERR] = CNTR_ELEM("TxLinkdownErr", 0, 0, + CNTR_NORMAL, + access_tx_linkdown_err_cnt), +[C_TX_EGRESS_FIFO_UNDERRUN_OR_PARITY_ERR] = CNTR_ELEM( + "EgressFifoUnderrunOrParityErr", 0, 0, + CNTR_NORMAL, + access_tx_egress_fifi_underrun_or_parity_err_cnt), +[C_TX_RESERVED_2] = CNTR_ELEM("Tx Egress Reserved 2", 0, 0, + CNTR_NORMAL, + access_egress_reserved_2_err_cnt), +[C_TX_PKT_INTEGRITY_MEM_UNC_ERR] = CNTR_ELEM("TxPktIntegrityMemUncErr", 0, 0, + CNTR_NORMAL, + access_tx_pkt_integrity_mem_unc_err_cnt), +[C_TX_PKT_INTEGRITY_MEM_COR_ERR] = CNTR_ELEM("TxPktIntegrityMemCorErr", 0, 0, + CNTR_NORMAL, + access_tx_pkt_integrity_mem_cor_err_cnt), +/* SendErrStatus */ +[C_SEND_CSR_WRITE_BAD_ADDR_ERR] = CNTR_ELEM("SendCsrWriteBadAddrErr", 0, 0, + CNTR_NORMAL, + access_send_csr_write_bad_addr_err_cnt), +[C_SEND_CSR_READ_BAD_ADD_ERR] = CNTR_ELEM("SendCsrReadBadAddrErr", 0, 0, + CNTR_NORMAL, + access_send_csr_read_bad_addr_err_cnt), +[C_SEND_CSR_PARITY_ERR] = CNTR_ELEM("SendCsrParityErr", 0, 0, + CNTR_NORMAL, + access_send_csr_parity_cnt), +/* SendCtxtErrStatus */ +[C_PIO_WRITE_OUT_OF_BOUNDS_ERR] = CNTR_ELEM("PioWriteOutOfBoundsErr", 0, 0, + CNTR_NORMAL, + access_pio_write_out_of_bounds_err_cnt), +[C_PIO_WRITE_OVERFLOW_ERR] = CNTR_ELEM("PioWriteOverflowErr", 0, 0, + CNTR_NORMAL, + access_pio_write_overflow_err_cnt), +[C_PIO_WRITE_CROSSES_BOUNDARY_ERR] = CNTR_ELEM("PioWriteCrossesBoundaryErr", + 0, 0, CNTR_NORMAL, + access_pio_write_crosses_boundary_err_cnt), +[C_PIO_DISALLOWED_PACKET_ERR] = CNTR_ELEM("PioDisallowedPacketErr", 0, 0, + CNTR_NORMAL, + access_pio_disallowed_packet_err_cnt), +[C_PIO_INCONSISTENT_SOP_ERR] = CNTR_ELEM("PioInconsistentSopErr", 0, 0, + CNTR_NORMAL, + access_pio_inconsistent_sop_err_cnt), +/* SendDmaEngErrStatus */ +[C_SDMA_HEADER_REQUEST_FIFO_COR_ERR] = CNTR_ELEM("SDmaHeaderRequestFifoCorErr", + 0, 0, CNTR_NORMAL, + access_sdma_header_request_fifo_cor_err_cnt), +[C_SDMA_HEADER_STORAGE_COR_ERR] = CNTR_ELEM("SDmaHeaderStorageCorErr", 0, 0, + CNTR_NORMAL, + access_sdma_header_storage_cor_err_cnt), +[C_SDMA_PACKET_TRACKING_COR_ERR] = CNTR_ELEM("SDmaPacketTrackingCorErr", 0, 0, + CNTR_NORMAL, + access_sdma_packet_tracking_cor_err_cnt), +[C_SDMA_ASSEMBLY_COR_ERR] = CNTR_ELEM("SDmaAssemblyCorErr", 0, 0, + CNTR_NORMAL, + access_sdma_assembly_cor_err_cnt), +[C_SDMA_DESC_TABLE_COR_ERR] = CNTR_ELEM("SDmaDescTableCorErr", 0, 0, + CNTR_NORMAL, + access_sdma_desc_table_cor_err_cnt), +[C_SDMA_HEADER_REQUEST_FIFO_UNC_ERR] = CNTR_ELEM("SDmaHeaderRequestFifoUncErr", + 0, 0, CNTR_NORMAL, + access_sdma_header_request_fifo_unc_err_cnt), +[C_SDMA_HEADER_STORAGE_UNC_ERR] = CNTR_ELEM("SDmaHeaderStorageUncErr", 0, 0, + CNTR_NORMAL, + access_sdma_header_storage_unc_err_cnt), +[C_SDMA_PACKET_TRACKING_UNC_ERR] = CNTR_ELEM("SDmaPacketTrackingUncErr", 0, 0, + CNTR_NORMAL, + access_sdma_packet_tracking_unc_err_cnt), +[C_SDMA_ASSEMBLY_UNC_ERR] = CNTR_ELEM("SDmaAssemblyUncErr", 0, 0, + CNTR_NORMAL, + access_sdma_assembly_unc_err_cnt), +[C_SDMA_DESC_TABLE_UNC_ERR] = CNTR_ELEM("SDmaDescTableUncErr", 0, 0, + CNTR_NORMAL, + access_sdma_desc_table_unc_err_cnt), +[C_SDMA_TIMEOUT_ERR] = CNTR_ELEM("SDmaTimeoutErr", 0, 0, + CNTR_NORMAL, + access_sdma_timeout_err_cnt), +[C_SDMA_HEADER_LENGTH_ERR] = CNTR_ELEM("SDmaHeaderLengthErr", 0, 0, + CNTR_NORMAL, + access_sdma_header_length_err_cnt), +[C_SDMA_HEADER_ADDRESS_ERR] = CNTR_ELEM("SDmaHeaderAddressErr", 0, 0, + CNTR_NORMAL, + access_sdma_header_address_err_cnt), +[C_SDMA_HEADER_SELECT_ERR] = CNTR_ELEM("SDmaHeaderSelectErr", 0, 0, + CNTR_NORMAL, + access_sdma_header_select_err_cnt), +[C_SMDA_RESERVED_9] = CNTR_ELEM("SDma Reserved 9", 0, 0, + CNTR_NORMAL, + access_sdma_reserved_9_err_cnt), +[C_SDMA_PACKET_DESC_OVERFLOW_ERR] = CNTR_ELEM("SDmaPacketDescOverflowErr", 0, 0, + CNTR_NORMAL, + access_sdma_packet_desc_overflow_err_cnt), +[C_SDMA_LENGTH_MISMATCH_ERR] = CNTR_ELEM("SDmaLengthMismatchErr", 0, 0, + CNTR_NORMAL, + access_sdma_length_mismatch_err_cnt), +[C_SDMA_HALT_ERR] = CNTR_ELEM("SDmaHaltErr", 0, 0, + CNTR_NORMAL, + access_sdma_halt_err_cnt), +[C_SDMA_MEM_READ_ERR] = CNTR_ELEM("SDmaMemReadErr", 0, 0, + CNTR_NORMAL, + access_sdma_mem_read_err_cnt), +[C_SDMA_FIRST_DESC_ERR] = CNTR_ELEM("SDmaFirstDescErr", 0, 0, + CNTR_NORMAL, + access_sdma_first_desc_err_cnt), +[C_SDMA_TAIL_OUT_OF_BOUNDS_ERR] = CNTR_ELEM("SDmaTailOutOfBoundsErr", 0, 0, + CNTR_NORMAL, + access_sdma_tail_out_of_bounds_err_cnt), +[C_SDMA_TOO_LONG_ERR] = CNTR_ELEM("SDmaTooLongErr", 0, 0, + CNTR_NORMAL, + access_sdma_too_long_err_cnt), +[C_SDMA_GEN_MISMATCH_ERR] = CNTR_ELEM("SDmaGenMismatchErr", 0, 0, + CNTR_NORMAL, + access_sdma_gen_mismatch_err_cnt), +[C_SDMA_WRONG_DW_ERR] = CNTR_ELEM("SDmaWrongDwErr", 0, 0, + CNTR_NORMAL, + access_sdma_wrong_dw_err_cnt), }; static struct cntr_entry port_cntrs[PORT_CNTR_LAST] = { @@ -2174,6 +5292,7 @@ static char *send_err_status_string(char *buf, int buf_len, u64 flags) static void handle_cce_err(struct hfi1_devdata *dd, u32 unused, u64 reg) { char buf[96]; + int i = 0; /* * For most these errors, there is nothing that can be done except @@ -2188,6 +5307,14 @@ static void handle_cce_err(struct hfi1_devdata *dd, u32 unused, u64 reg) /* then a fix up */ start_freeze_handling(dd->pport, FREEZE_SELF); } + + for (i = 0; i < NUM_CCE_ERR_STATUS_COUNTERS; i++) { + if (reg & (1ull << i)) { + incr_cntr64(&dd->cce_err_status_cnt[i]); + /* maintain a counter over all cce_err_status errors */ + incr_cntr64(&dd->sw_cce_err_status_aggregate); + } + } } /* @@ -2232,6 +5359,7 @@ static void free_rcverr(struct hfi1_devdata *dd) static void handle_rxe_err(struct hfi1_devdata *dd, u32 unused, u64 reg) { char buf[96]; + int i = 0; dd_dev_info(dd, "Receive Error: %s\n", rxe_err_status_string(buf, sizeof(buf), reg)); @@ -2248,36 +5376,58 @@ static void handle_rxe_err(struct hfi1_devdata *dd, u32 unused, u64 reg) start_freeze_handling(dd->pport, flags); } + + for (i = 0; i < NUM_RCV_ERR_STATUS_COUNTERS; i++) { + if (reg & (1ull << i)) + incr_cntr64(&dd->rcv_err_status_cnt[i]); + } } static void handle_misc_err(struct hfi1_devdata *dd, u32 unused, u64 reg) { char buf[96]; + int i = 0; dd_dev_info(dd, "Misc Error: %s", misc_err_status_string(buf, sizeof(buf), reg)); + for (i = 0; i < NUM_MISC_ERR_STATUS_COUNTERS; i++) { + if (reg & (1ull << i)) + incr_cntr64(&dd->misc_err_status_cnt[i]); + } } static void handle_pio_err(struct hfi1_devdata *dd, u32 unused, u64 reg) { char buf[96]; + int i = 0; dd_dev_info(dd, "PIO Error: %s\n", pio_err_status_string(buf, sizeof(buf), reg)); if (reg & ALL_PIO_FREEZE_ERR) start_freeze_handling(dd->pport, 0); + + for (i = 0; i < NUM_SEND_PIO_ERR_STATUS_COUNTERS; i++) { + if (reg & (1ull << i)) + incr_cntr64(&dd->send_pio_err_status_cnt[i]); + } } static void handle_sdma_err(struct hfi1_devdata *dd, u32 unused, u64 reg) { char buf[96]; + int i = 0; dd_dev_info(dd, "SDMA Error: %s\n", sdma_err_status_string(buf, sizeof(buf), reg)); if (reg & ALL_SDMA_FREEZE_ERR) start_freeze_handling(dd->pport, 0); + + for (i = 0; i < NUM_SEND_DMA_ERR_STATUS_COUNTERS; i++) { + if (reg & (1ull << i)) + incr_cntr64(&dd->send_dma_err_status_cnt[i]); + } } static void count_port_inactive(struct hfi1_devdata *dd) @@ -2343,6 +5493,7 @@ static void handle_egress_err(struct hfi1_devdata *dd, u32 unused, u64 reg) { u64 reg_copy = reg, handled = 0; char buf[96]; + int i = 0; if (reg & ALL_TXE_EGRESS_FREEZE_ERR) start_freeze_handling(dd->pport, 0); @@ -2374,15 +5525,25 @@ static void handle_egress_err(struct hfi1_devdata *dd, u32 unused, u64 reg) if (reg) dd_dev_info(dd, "Egress Error: %s\n", egress_err_status_string(buf, sizeof(buf), reg)); + + for (i = 0; i < NUM_SEND_EGRESS_ERR_STATUS_COUNTERS; i++) { + if (reg & (1ull << i)) + incr_cntr64(&dd->send_egress_err_status_cnt[i]); + } } static void handle_txe_err(struct hfi1_devdata *dd, u32 unused, u64 reg) { char buf[96]; + int i = 0; dd_dev_info(dd, "Send Error: %s\n", send_err_status_string(buf, sizeof(buf), reg)); + for (i = 0; i < NUM_SEND_ERR_STATUS_COUNTERS; i++) { + if (reg & (1ull << i)) + incr_cntr64(&dd->send_err_status_cnt[i]); + } } /* @@ -2474,6 +5635,7 @@ static void is_sendctxt_err_int(struct hfi1_devdata *dd, char flags[96]; u64 status; u32 sw_index; + int i = 0; sw_index = dd->hw_to_sw[hw_context]; if (sw_index >= dd->num_send_contexts) { @@ -2507,12 +5669,23 @@ static void is_sendctxt_err_int(struct hfi1_devdata *dd, */ if (sc->type != SC_USER) queue_work(dd->pport->hfi1_wq, &sc->halt_work); + + /* + * Update the counters for the corresponding status bits. + * Note that these particular counters are aggregated over all + * 160 contexts. + */ + for (i = 0; i < NUM_SEND_CTXT_ERR_STATUS_COUNTERS; i++) { + if (status & (1ull << i)) + incr_cntr64(&dd->sw_ctxt_err_status_cnt[i]); + } } static void handle_sdma_eng_err(struct hfi1_devdata *dd, unsigned int source, u64 status) { struct sdma_engine *sde; + int i = 0; sde = &dd->per_sdma[source]; #ifdef CONFIG_SDMA_VERBOSITY @@ -2522,6 +5695,16 @@ static void handle_sdma_eng_err(struct hfi1_devdata *dd, sde->this_idx, source, (unsigned long long)status); #endif sdma_engine_error(sde, status); + + /* + * Update the counters for the corresponding status bits. + * Note that these particular counters are aggregated over + * all 16 DMA engines. + */ + for (i = 0; i < NUM_SEND_DMA_ENG_ERR_STATUS_COUNTERS; i++) { + if (status & (1ull << i)) + incr_cntr64(&dd->sw_send_dma_eng_err_status_cnt[i]); + } } /* diff --git a/drivers/staging/rdma/hfi1/chip.h b/drivers/staging/rdma/hfi1/chip.h index 177862b9230b7..ceed637a76349 100644 --- a/drivers/staging/rdma/hfi1/chip.h +++ b/drivers/staging/rdma/hfi1/chip.h @@ -787,6 +787,275 @@ enum { C_SW_PIO_WAIT, C_SW_KMEM_WAIT, C_SW_SEND_SCHED, +/* MISC_ERR_STATUS */ + C_MISC_PLL_LOCK_FAIL_ERR, + C_MISC_MBIST_FAIL_ERR, + C_MISC_INVALID_EEP_CMD_ERR, + C_MISC_EFUSE_DONE_PARITY_ERR, + C_MISC_EFUSE_WRITE_ERR, + C_MISC_EFUSE_READ_BAD_ADDR_ERR, + C_MISC_EFUSE_CSR_PARITY_ERR, + C_MISC_FW_AUTH_FAILED_ERR, + C_MISC_KEY_MISMATCH_ERR, + C_MISC_SBUS_WRITE_FAILED_ERR, + C_MISC_CSR_WRITE_BAD_ADDR_ERR, + C_MISC_CSR_READ_BAD_ADDR_ERR, + C_MISC_CSR_PARITY_ERR, +/* CceErrStatus */ + /* + * A special counter that is the aggregate count + * of all the cce_err_status errors. The remainder + * are actual bits in the CceErrStatus register. + */ + C_CCE_ERR_STATUS_AGGREGATED_CNT, + C_CCE_MSIX_CSR_PARITY_ERR, + C_CCE_INT_MAP_UNC_ERR, + C_CCE_INT_MAP_COR_ERR, + C_CCE_MSIX_TABLE_UNC_ERR, + C_CCE_MSIX_TABLE_COR_ERR, + C_CCE_RXDMA_CONV_FIFO_PARITY_ERR, + C_CCE_RCPL_ASYNC_FIFO_PARITY_ERR, + C_CCE_SEG_WRITE_BAD_ADDR_ERR, + C_CCE_SEG_READ_BAD_ADDR_ERR, + C_LA_TRIGGERED, + C_CCE_TRGT_CPL_TIMEOUT_ERR, + C_PCIC_RECEIVE_PARITY_ERR, + C_PCIC_TRANSMIT_BACK_PARITY_ERR, + C_PCIC_TRANSMIT_FRONT_PARITY_ERR, + C_PCIC_CPL_DAT_Q_UNC_ERR, + C_PCIC_CPL_HD_Q_UNC_ERR, + C_PCIC_POST_DAT_Q_UNC_ERR, + C_PCIC_POST_HD_Q_UNC_ERR, + C_PCIC_RETRY_SOT_MEM_UNC_ERR, + C_PCIC_RETRY_MEM_UNC_ERR, + C_PCIC_N_POST_DAT_Q_PARITY_ERR, + C_PCIC_N_POST_H_Q_PARITY_ERR, + C_PCIC_CPL_DAT_Q_COR_ERR, + C_PCIC_CPL_HD_Q_COR_ERR, + C_PCIC_POST_DAT_Q_COR_ERR, + C_PCIC_POST_HD_Q_COR_ERR, + C_PCIC_RETRY_SOT_MEM_COR_ERR, + C_PCIC_RETRY_MEM_COR_ERR, + C_CCE_CLI1_ASYNC_FIFO_DBG_PARITY_ERR, + C_CCE_CLI1_ASYNC_FIFO_RXDMA_PARITY_ERR, + C_CCE_CLI1_ASYNC_FIFO_SDMA_HD_PARITY_ERR, + C_CCE_CLI1_ASYNC_FIFO_PIO_CRDT_PARITY_ERR, + C_CCE_CLI2_ASYNC_FIFO_PARITY_ERR, + C_CCE_CSR_CFG_BUS_PARITY_ERR, + C_CCE_CLI0_ASYNC_FIFO_PARTIY_ERR, + C_CCE_RSPD_DATA_PARITY_ERR, + C_CCE_TRGT_ACCESS_ERR, + C_CCE_TRGT_ASYNC_FIFO_PARITY_ERR, + C_CCE_CSR_WRITE_BAD_ADDR_ERR, + C_CCE_CSR_READ_BAD_ADDR_ERR, + C_CCE_CSR_PARITY_ERR, +/* RcvErrStatus */ + C_RX_CSR_PARITY_ERR, + C_RX_CSR_WRITE_BAD_ADDR_ERR, + C_RX_CSR_READ_BAD_ADDR_ERR, + C_RX_DMA_CSR_UNC_ERR, + C_RX_DMA_DQ_FSM_ENCODING_ERR, + C_RX_DMA_EQ_FSM_ENCODING_ERR, + C_RX_DMA_CSR_PARITY_ERR, + C_RX_RBUF_DATA_COR_ERR, + C_RX_RBUF_DATA_UNC_ERR, + C_RX_DMA_DATA_FIFO_RD_COR_ERR, + C_RX_DMA_DATA_FIFO_RD_UNC_ERR, + C_RX_DMA_HDR_FIFO_RD_COR_ERR, + C_RX_DMA_HDR_FIFO_RD_UNC_ERR, + C_RX_RBUF_DESC_PART2_COR_ERR, + C_RX_RBUF_DESC_PART2_UNC_ERR, + C_RX_RBUF_DESC_PART1_COR_ERR, + C_RX_RBUF_DESC_PART1_UNC_ERR, + C_RX_HQ_INTR_FSM_ERR, + C_RX_HQ_INTR_CSR_PARITY_ERR, + C_RX_LOOKUP_CSR_PARITY_ERR, + C_RX_LOOKUP_RCV_ARRAY_COR_ERR, + C_RX_LOOKUP_RCV_ARRAY_UNC_ERR, + C_RX_LOOKUP_DES_PART2_PARITY_ERR, + C_RX_LOOKUP_DES_PART1_UNC_COR_ERR, + C_RX_LOOKUP_DES_PART1_UNC_ERR, + C_RX_RBUF_NEXT_FREE_BUF_COR_ERR, + C_RX_RBUF_NEXT_FREE_BUF_UNC_ERR, + C_RX_RBUF_FL_INIT_WR_ADDR_PARITY_ERR, + C_RX_RBUF_FL_INITDONE_PARITY_ERR, + C_RX_RBUF_FL_WRITE_ADDR_PARITY_ERR, + C_RX_RBUF_FL_RD_ADDR_PARITY_ERR, + C_RX_RBUF_EMPTY_ERR, + C_RX_RBUF_FULL_ERR, + C_RX_RBUF_BAD_LOOKUP_ERR, + C_RX_RBUF_CTX_ID_PARITY_ERR, + C_RX_RBUF_CSR_QEOPDW_PARITY_ERR, + C_RX_RBUF_CSR_Q_NUM_OF_PKT_PARITY_ERR, + C_RX_RBUF_CSR_Q_T1_PTR_PARITY_ERR, + C_RX_RBUF_CSR_Q_HD_PTR_PARITY_ERR, + C_RX_RBUF_CSR_Q_VLD_BIT_PARITY_ERR, + C_RX_RBUF_CSR_Q_NEXT_BUF_PARITY_ERR, + C_RX_RBUF_CSR_Q_ENT_CNT_PARITY_ERR, + C_RX_RBUF_CSR_Q_HEAD_BUF_NUM_PARITY_ERR, + C_RX_RBUF_BLOCK_LIST_READ_COR_ERR, + C_RX_RBUF_BLOCK_LIST_READ_UNC_ERR, + C_RX_RBUF_LOOKUP_DES_COR_ERR, + C_RX_RBUF_LOOKUP_DES_UNC_ERR, + C_RX_RBUF_LOOKUP_DES_REG_UNC_COR_ERR, + C_RX_RBUF_LOOKUP_DES_REG_UNC_ERR, + C_RX_RBUF_FREE_LIST_COR_ERR, + C_RX_RBUF_FREE_LIST_UNC_ERR, + C_RX_RCV_FSM_ENCODING_ERR, + C_RX_DMA_FLAG_COR_ERR, + C_RX_DMA_FLAG_UNC_ERR, + C_RX_DC_SOP_EOP_PARITY_ERR, + C_RX_RCV_CSR_PARITY_ERR, + C_RX_RCV_QP_MAP_TABLE_COR_ERR, + C_RX_RCV_QP_MAP_TABLE_UNC_ERR, + C_RX_RCV_DATA_COR_ERR, + C_RX_RCV_DATA_UNC_ERR, + C_RX_RCV_HDR_COR_ERR, + C_RX_RCV_HDR_UNC_ERR, + C_RX_DC_INTF_PARITY_ERR, + C_RX_DMA_CSR_COR_ERR, +/* SendPioErrStatus */ + C_PIO_PEC_SOP_HEAD_PARITY_ERR, + C_PIO_PCC_SOP_HEAD_PARITY_ERR, + C_PIO_LAST_RETURNED_CNT_PARITY_ERR, + C_PIO_CURRENT_FREE_CNT_PARITY_ERR, + C_PIO_RSVD_31_ERR, + C_PIO_RSVD_30_ERR, + C_PIO_PPMC_SOP_LEN_ERR, + C_PIO_PPMC_BQC_MEM_PARITY_ERR, + C_PIO_VL_FIFO_PARITY_ERR, + C_PIO_VLF_SOP_PARITY_ERR, + C_PIO_VLF_V1_LEN_PARITY_ERR, + C_PIO_BLOCK_QW_COUNT_PARITY_ERR, + C_PIO_WRITE_QW_VALID_PARITY_ERR, + C_PIO_STATE_MACHINE_ERR, + C_PIO_WRITE_DATA_PARITY_ERR, + C_PIO_HOST_ADDR_MEM_COR_ERR, + C_PIO_HOST_ADDR_MEM_UNC_ERR, + C_PIO_PKT_EVICT_SM_OR_ARM_SM_ERR, + C_PIO_INIT_SM_IN_ERR, + C_PIO_PPMC_PBL_FIFO_ERR, + C_PIO_CREDIT_RET_FIFO_PARITY_ERR, + C_PIO_V1_LEN_MEM_BANK1_COR_ERR, + C_PIO_V1_LEN_MEM_BANK0_COR_ERR, + C_PIO_V1_LEN_MEM_BANK1_UNC_ERR, + C_PIO_V1_LEN_MEM_BANK0_UNC_ERR, + C_PIO_SM_PKT_RESET_PARITY_ERR, + C_PIO_PKT_EVICT_FIFO_PARITY_ERR, + C_PIO_SBRDCTRL_CRREL_FIFO_PARITY_ERR, + C_PIO_SBRDCTL_CRREL_PARITY_ERR, + C_PIO_PEC_FIFO_PARITY_ERR, + C_PIO_PCC_FIFO_PARITY_ERR, + C_PIO_SB_MEM_FIFO1_ERR, + C_PIO_SB_MEM_FIFO0_ERR, + C_PIO_CSR_PARITY_ERR, + C_PIO_WRITE_ADDR_PARITY_ERR, + C_PIO_WRITE_BAD_CTXT_ERR, +/* SendDmaErrStatus */ + C_SDMA_PCIE_REQ_TRACKING_COR_ERR, + C_SDMA_PCIE_REQ_TRACKING_UNC_ERR, + C_SDMA_CSR_PARITY_ERR, + C_SDMA_RPY_TAG_ERR, +/* SendEgressErrStatus */ + C_TX_READ_PIO_MEMORY_CSR_UNC_ERR, + C_TX_READ_SDMA_MEMORY_CSR_UNC_ERR, + C_TX_EGRESS_FIFO_COR_ERR, + C_TX_READ_PIO_MEMORY_COR_ERR, + C_TX_READ_SDMA_MEMORY_COR_ERR, + C_TX_SB_HDR_COR_ERR, + C_TX_CREDIT_OVERRUN_ERR, + C_TX_LAUNCH_FIFO8_COR_ERR, + C_TX_LAUNCH_FIFO7_COR_ERR, + C_TX_LAUNCH_FIFO6_COR_ERR, + C_TX_LAUNCH_FIFO5_COR_ERR, + C_TX_LAUNCH_FIFO4_COR_ERR, + C_TX_LAUNCH_FIFO3_COR_ERR, + C_TX_LAUNCH_FIFO2_COR_ERR, + C_TX_LAUNCH_FIFO1_COR_ERR, + C_TX_LAUNCH_FIFO0_COR_ERR, + C_TX_CREDIT_RETURN_VL_ERR, + C_TX_HCRC_INSERTION_ERR, + C_TX_EGRESS_FIFI_UNC_ERR, + C_TX_READ_PIO_MEMORY_UNC_ERR, + C_TX_READ_SDMA_MEMORY_UNC_ERR, + C_TX_SB_HDR_UNC_ERR, + C_TX_CREDIT_RETURN_PARITY_ERR, + C_TX_LAUNCH_FIFO8_UNC_OR_PARITY_ERR, + C_TX_LAUNCH_FIFO7_UNC_OR_PARITY_ERR, + C_TX_LAUNCH_FIFO6_UNC_OR_PARITY_ERR, + C_TX_LAUNCH_FIFO5_UNC_OR_PARITY_ERR, + C_TX_LAUNCH_FIFO4_UNC_OR_PARITY_ERR, + C_TX_LAUNCH_FIFO3_UNC_OR_PARITY_ERR, + C_TX_LAUNCH_FIFO2_UNC_OR_PARITY_ERR, + C_TX_LAUNCH_FIFO1_UNC_OR_PARITY_ERR, + C_TX_LAUNCH_FIFO0_UNC_OR_PARITY_ERR, + C_TX_SDMA15_DISALLOWED_PACKET_ERR, + C_TX_SDMA14_DISALLOWED_PACKET_ERR, + C_TX_SDMA13_DISALLOWED_PACKET_ERR, + C_TX_SDMA12_DISALLOWED_PACKET_ERR, + C_TX_SDMA11_DISALLOWED_PACKET_ERR, + C_TX_SDMA10_DISALLOWED_PACKET_ERR, + C_TX_SDMA9_DISALLOWED_PACKET_ERR, + C_TX_SDMA8_DISALLOWED_PACKET_ERR, + C_TX_SDMA7_DISALLOWED_PACKET_ERR, + C_TX_SDMA6_DISALLOWED_PACKET_ERR, + C_TX_SDMA5_DISALLOWED_PACKET_ERR, + C_TX_SDMA4_DISALLOWED_PACKET_ERR, + C_TX_SDMA3_DISALLOWED_PACKET_ERR, + C_TX_SDMA2_DISALLOWED_PACKET_ERR, + C_TX_SDMA1_DISALLOWED_PACKET_ERR, + C_TX_SDMA0_DISALLOWED_PACKET_ERR, + C_TX_CONFIG_PARITY_ERR, + C_TX_SBRD_CTL_CSR_PARITY_ERR, + C_TX_LAUNCH_CSR_PARITY_ERR, + C_TX_ILLEGAL_CL_ERR, + C_TX_SBRD_CTL_STATE_MACHINE_PARITY_ERR, + C_TX_RESERVED_10, + C_TX_RESERVED_9, + C_TX_SDMA_LAUNCH_INTF_PARITY_ERR, + C_TX_PIO_LAUNCH_INTF_PARITY_ERR, + C_TX_RESERVED_6, + C_TX_INCORRECT_LINK_STATE_ERR, + C_TX_LINK_DOWN_ERR, + C_TX_EGRESS_FIFO_UNDERRUN_OR_PARITY_ERR, + C_TX_RESERVED_2, + C_TX_PKT_INTEGRITY_MEM_UNC_ERR, + C_TX_PKT_INTEGRITY_MEM_COR_ERR, +/* SendErrStatus */ + C_SEND_CSR_WRITE_BAD_ADDR_ERR, + C_SEND_CSR_READ_BAD_ADD_ERR, + C_SEND_CSR_PARITY_ERR, +/* SendCtxtErrStatus */ + C_PIO_WRITE_OUT_OF_BOUNDS_ERR, + C_PIO_WRITE_OVERFLOW_ERR, + C_PIO_WRITE_CROSSES_BOUNDARY_ERR, + C_PIO_DISALLOWED_PACKET_ERR, + C_PIO_INCONSISTENT_SOP_ERR, +/*SendDmaEngErrStatus */ + C_SDMA_HEADER_REQUEST_FIFO_COR_ERR, + C_SDMA_HEADER_STORAGE_COR_ERR, + C_SDMA_PACKET_TRACKING_COR_ERR, + C_SDMA_ASSEMBLY_COR_ERR, + C_SDMA_DESC_TABLE_COR_ERR, + C_SDMA_HEADER_REQUEST_FIFO_UNC_ERR, + C_SDMA_HEADER_STORAGE_UNC_ERR, + C_SDMA_PACKET_TRACKING_UNC_ERR, + C_SDMA_ASSEMBLY_UNC_ERR, + C_SDMA_DESC_TABLE_UNC_ERR, + C_SDMA_TIMEOUT_ERR, + C_SDMA_HEADER_LENGTH_ERR, + C_SDMA_HEADER_ADDRESS_ERR, + C_SDMA_HEADER_SELECT_ERR, + C_SMDA_RESERVED_9, + C_SDMA_PACKET_DESC_OVERFLOW_ERR, + C_SDMA_LENGTH_MISMATCH_ERR, + C_SDMA_HALT_ERR, + C_SDMA_MEM_READ_ERR, + C_SDMA_FIRST_DESC_ERR, + C_SDMA_TAIL_OUT_OF_BOUNDS_ERR, + C_SDMA_TOO_LONG_ERR, + C_SDMA_GEN_MISMATCH_ERR, + C_SDMA_WRONG_DW_ERR, DEV_CNTR_LAST /* Must be kept last */ }; diff --git a/drivers/staging/rdma/hfi1/hfi.h b/drivers/staging/rdma/hfi1/hfi.h index 98db0fe4d0f0e..9ee3951af1285 100644 --- a/drivers/staging/rdma/hfi1/hfi.h +++ b/drivers/staging/rdma/hfi1/hfi.h @@ -105,6 +105,20 @@ extern unsigned long hfi1_cap_mask; */ #define HFI1_CTRL_CTXT 0 +/* + * Driver context will store software counters for each of the events + * associated with these status registers + */ +#define NUM_CCE_ERR_STATUS_COUNTERS 41 +#define NUM_RCV_ERR_STATUS_COUNTERS 64 +#define NUM_MISC_ERR_STATUS_COUNTERS 13 +#define NUM_SEND_PIO_ERR_STATUS_COUNTERS 36 +#define NUM_SEND_DMA_ERR_STATUS_COUNTERS 4 +#define NUM_SEND_EGRESS_ERR_STATUS_COUNTERS 64 +#define NUM_SEND_ERR_STATUS_COUNTERS 3 +#define NUM_SEND_CTXT_ERR_STATUS_COUNTERS 5 +#define NUM_SEND_DMA_ENG_ERR_STATUS_COUNTERS 24 + /* * per driver stats, either not device nor port-specific, or * summed over all of the devices and ports. @@ -1046,6 +1060,26 @@ struct hfi1_devdata { atomic_t drop_packet; u8 do_drop; + /* + * Software counters for the status bits defined by the + * associated error status registers + */ + u64 cce_err_status_cnt[NUM_CCE_ERR_STATUS_COUNTERS]; + u64 rcv_err_status_cnt[NUM_RCV_ERR_STATUS_COUNTERS]; + u64 misc_err_status_cnt[NUM_MISC_ERR_STATUS_COUNTERS]; + u64 send_pio_err_status_cnt[NUM_SEND_PIO_ERR_STATUS_COUNTERS]; + u64 send_dma_err_status_cnt[NUM_SEND_DMA_ERR_STATUS_COUNTERS]; + u64 send_egress_err_status_cnt[NUM_SEND_EGRESS_ERR_STATUS_COUNTERS]; + u64 send_err_status_cnt[NUM_SEND_ERR_STATUS_COUNTERS]; + + /* Software counter that spans all contexts */ + u64 sw_ctxt_err_status_cnt[NUM_SEND_CTXT_ERR_STATUS_COUNTERS]; + /* Software counter that spans all DMA engines */ + u64 sw_send_dma_eng_err_status_cnt[ + NUM_SEND_DMA_ENG_ERR_STATUS_COUNTERS]; + /* Software counter that aggregates all cce_err_status errors */ + u64 sw_cce_err_status_aggregate; + /* receive interrupt functions */ rhf_rcv_function_ptr *rhf_rcv_function_map; rhf_rcv_function_ptr normal_rhf_rcv_functions[8]; -- GitLab From e8597eb01456f11f978f316c41ea54c935eb2f50 Mon Sep 17 00:00:00 2001 From: Harish Chegondi Date: Tue, 1 Dec 2015 15:38:20 -0500 Subject: [PATCH 1832/2855] staging/rdma/hfi1: Destroy workqueues if hfi1_register_ib_device() call returns error Currently, if hfi1_register_ib_device() call is unsuccessful, workqueues are not being destroyed before bailing out. This patch fixes this issue. Reviewed-by: Dennis Dalessandro Signed-off-by: Harish Chegondi Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/init.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rdma/hfi1/init.c b/drivers/staging/rdma/hfi1/init.c index 52fa86f47186f..2d52f91c03dc3 100644 --- a/drivers/staging/rdma/hfi1/init.c +++ b/drivers/staging/rdma/hfi1/init.c @@ -1336,6 +1336,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { int ret = 0, j, pidx, initfail; struct hfi1_devdata *dd = NULL; + struct hfi1_pportdata *ppd; /* First, lock the non-writable module parameters */ HFI1_CAP_LOCK(); @@ -1431,8 +1432,14 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (initfail || ret) { stop_timers(dd); flush_workqueue(ib_wq); - for (pidx = 0; pidx < dd->num_pports; ++pidx) + for (pidx = 0; pidx < dd->num_pports; ++pidx) { hfi1_quiet_serdes(dd->pport + pidx); + ppd = dd->pport + pidx; + if (ppd->hfi1_wq) { + destroy_workqueue(ppd->hfi1_wq); + ppd->hfi1_wq = NULL; + } + } if (!j) hfi1_device_remove(dd); if (!ret) -- GitLab From 8764522e5251b76666aa39e207069c43f742801d Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Tue, 1 Dec 2015 15:38:21 -0500 Subject: [PATCH 1833/2855] staging/rdma/hfi1: Unexpected link up pkey values are not an error Only warn when link up pkeys are not what we expect. Also, allow for the pkey to already be initialized. Reviewed-by: Arthur Kepner Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index 3cf6fea0bf35d..e201c80c7644f 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -6716,10 +6716,10 @@ static void add_full_mgmt_pkey(struct hfi1_pportdata *ppd) { struct hfi1_devdata *dd = ppd->dd; - /* Sanity check - ppd->pkeys[2] should be 0 */ - if (ppd->pkeys[2] != 0) - dd_dev_err(dd, "%s pkey[2] already set to 0x%x, resetting it to 0x%x\n", - __func__, ppd->pkeys[2], FULL_MGMT_P_KEY); + /* Sanity check - ppd->pkeys[2] should be 0, or already initalized */ + if (!((ppd->pkeys[2] == 0) || (ppd->pkeys[2] == FULL_MGMT_P_KEY))) + dd_dev_warn(dd, "%s pkey[2] already set to 0x%x, resetting it to 0x%x\n", + __func__, ppd->pkeys[2], FULL_MGMT_P_KEY); ppd->pkeys[2] = FULL_MGMT_P_KEY; (void)hfi1_set_ib_cfg(ppd, HFI1_IB_CFG_PKEYS, 0); } -- GitLab From 56af5543f8cf078da18a0912b8fa04baf724b210 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Tue, 1 Dec 2015 15:38:22 -0500 Subject: [PATCH 1834/2855] staging/rdma/hfi1: remove SPC freeze error messages An SPC freeze is not an error. Remove the messages. Reviewed-by: Dennis Dalessandro Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index e201c80c7644f..719e3f1e4499d 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -6487,7 +6487,6 @@ void handle_freeze(struct work_struct *work) struct hfi1_devdata *dd = ppd->dd; /* wait for freeze indicators on all affected blocks */ - dd_dev_info(dd, "Entering SPC freeze\n"); wait_for_freeze_status(dd, 1); /* SPC is now frozen */ @@ -6545,7 +6544,6 @@ void handle_freeze(struct work_struct *work) wake_up(&dd->event_queue); /* no longer frozen */ - dd_dev_err(dd, "Exiting SPC freeze\n"); } /* -- GitLab From 6d0145308252ebcc1d373e6c3acd8f1ce7fec377 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Tue, 1 Dec 2015 15:38:23 -0500 Subject: [PATCH 1835/2855] staging/rdma/hfi1: unknown frame messages are not errors Change reported unknown frame messages into a counter. These are informational, no errors. Reviewed-by: Dennis Dalessandro Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 18 ++++++++++++++++++ drivers/staging/rdma/hfi1/chip.h | 1 + drivers/staging/rdma/hfi1/hfi.h | 2 ++ 3 files changed, 21 insertions(+) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index 719e3f1e4499d..cb73243c497a2 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -1418,6 +1418,17 @@ static u64 access_sw_link_up_cnt(const struct cntr_entry *entry, void *context, return read_write_sw(ppd->dd, &ppd->link_up, mode, data); } +static u64 access_sw_unknown_frame_cnt(const struct cntr_entry *entry, + void *context, int vl, int mode, + u64 data) +{ + struct hfi1_pportdata *ppd = (struct hfi1_pportdata *)context; + + if (vl != CNTR_INVALID_VL) + return 0; + return read_write_sw(ppd->dd, &ppd->unknown_frame_count, mode, data); +} + static u64 access_sw_xmit_discards(const struct cntr_entry *entry, void *context, int vl, int mode, u64 data) { @@ -4879,6 +4890,8 @@ static struct cntr_entry port_cntrs[PORT_CNTR_LAST] = { access_sw_link_dn_cnt), [C_SW_LINK_UP] = CNTR_ELEM("SwLinkUp", 0, 0, CNTR_SYNTH | CNTR_32BIT, access_sw_link_up_cnt), +[C_SW_UNKNOWN_FRAME] = CNTR_ELEM("UnknownFrame", 0, 0, CNTR_NORMAL, + access_sw_unknown_frame_cnt), [C_SW_XMIT_DSCD] = CNTR_ELEM("XmitDscd", 0, 0, CNTR_SYNTH | CNTR_32BIT, access_sw_xmit_discards), [C_SW_XMIT_DSCD_VL] = CNTR_ELEM("XmitDscdVl", 0, 0, @@ -7235,6 +7248,11 @@ static void handle_8051_interrupt(struct hfi1_devdata *dd, u32 unused, u64 reg) } err &= ~(u64)FAILED_LNI; } + /* unknown frames can happen durning LNI, just count */ + if (err & UNKNOWN_FRAME) { + ppd->unknown_frame_count++; + err &= ~(u64)UNKNOWN_FRAME; + } if (err) { /* report remaining errors, but do not do anything */ dd_dev_err(dd, "8051 info error: %s\n", diff --git a/drivers/staging/rdma/hfi1/chip.h b/drivers/staging/rdma/hfi1/chip.h index ceed637a76349..5b375ddc345d8 100644 --- a/drivers/staging/rdma/hfi1/chip.h +++ b/drivers/staging/rdma/hfi1/chip.h @@ -1078,6 +1078,7 @@ enum { C_RX_WORDS, C_SW_LINK_DOWN, C_SW_LINK_UP, + C_SW_UNKNOWN_FRAME, C_SW_XMIT_DSCD, C_SW_XMIT_DSCD_VL, C_SW_XMIT_CSTR_ERR, diff --git a/drivers/staging/rdma/hfi1/hfi.h b/drivers/staging/rdma/hfi1/hfi.h index 9ee3951af1285..7f8cafa841b5c 100644 --- a/drivers/staging/rdma/hfi1/hfi.h +++ b/drivers/staging/rdma/hfi1/hfi.h @@ -713,6 +713,8 @@ struct hfi1_pportdata { u64 link_downed; /* number of times link retrained successfully */ u64 link_up; + /* number of times a link unknown frame was reported */ + u64 unknown_frame_count; /* port_ltp_crc_mode is returned in 'portinfo' MADs */ u16 port_ltp_crc_mode; /* port_crc_mode_enabled is the crc we support */ -- GitLab From 6cc6ad2eb886e8cb47e8b15e9d4132fe8275021f Mon Sep 17 00:00:00 2001 From: Harish Chegondi Date: Tue, 1 Dec 2015 15:38:24 -0500 Subject: [PATCH 1836/2855] staging/rdma/hfi1: Consider VL15 MTU also when calculating the maximum VL MTU Currently, only MTUs of VLs 0-7 are checked when calculating the maximum VL MTU which is used to set the port MTU capability in DCC_CFG_PORT_CONFIG CSR This can cause a port MTU capability to be set to 0 if MTUs of VLs 0-7 is 0 This would affect the VL15 traffic. Reviewed-by: Dean Luick Reviewed-by: Arthur Kepner Signed-off-by: Harish Chegondi Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index cb73243c497a2..d88945a802506 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -9407,7 +9407,8 @@ u32 lrh_max_header_bytes(struct hfi1_devdata *dd) static void set_send_length(struct hfi1_pportdata *ppd) { struct hfi1_devdata *dd = ppd->dd; - u32 max_hb = lrh_max_header_bytes(dd), maxvlmtu = 0, dcmtu; + u32 max_hb = lrh_max_header_bytes(dd), dcmtu; + u32 maxvlmtu = dd->vld[15].mtu; u64 len1 = 0, len2 = (((dd->vld[15].mtu + max_hb) >> 2) & SEND_LEN_CHECK1_LEN_VL15_MASK) << SEND_LEN_CHECK1_LEN_VL15_SHIFT; -- GitLab From f0852922507c386257891e694315a56c2ba09224 Mon Sep 17 00:00:00 2001 From: Andrea Lowe Date: Tue, 1 Dec 2015 15:38:26 -0500 Subject: [PATCH 1837/2855] staging/rdma/hfi1: Adding counter resolutions for DataPortCounters Changing the 32-bit reserved field in opa_port_data_counters_msg to the new 'resolution' field. PMA will use resolutions to right- shift values for LocalLinkIntegrity and LinkErrorRecovery when computing the ErrorCounterSummary for a DataPortCounters request. Reviewed-by: Mike Marciniszyn Signed-off-by: Andrea Lowe Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/mad.c | 38 ++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/drivers/staging/rdma/hfi1/mad.c b/drivers/staging/rdma/hfi1/mad.c index 4bc003f036c09..a785664371d03 100644 --- a/drivers/staging/rdma/hfi1/mad.c +++ b/drivers/staging/rdma/hfi1/mad.c @@ -2076,13 +2076,20 @@ struct opa_aggregate { u8 data[0]; }; -/* Request contains first two fields, response contains those plus the rest */ +#define MSK_LLI 0x000000f0 +#define MSK_LLI_SFT 4 +#define MSK_LER 0x0000000f +#define MSK_LER_SFT 0 +#define ADD_LLI 8 +#define ADD_LER 2 + +/* Request contains first three fields, response contains those plus the rest */ struct opa_port_data_counters_msg { __be64 port_select_mask[4]; __be32 vl_select_mask; + __be32 resolution; /* Response fields follow */ - __be32 reserved1; struct _port_dctrs { u8 port_number; u8 reserved2[3]; @@ -2443,7 +2450,8 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp, return reply((struct ib_mad_hdr *)pmp); } -static u64 get_error_counter_summary(struct ib_device *ibdev, u8 port) +static u64 get_error_counter_summary(struct ib_device *ibdev, u8 port, + u8 res_lli, u8 res_ler) { struct hfi1_devdata *dd = dd_from_ibdev(ibdev); struct hfi1_ibport *ibp = to_iport(ibdev, port); @@ -2459,14 +2467,14 @@ static u64 get_error_counter_summary(struct ib_device *ibdev, u8 port) CNTR_INVALID_VL); error_counter_summary += read_dev_cntr(dd, C_DC_RMT_PHY_ERR, CNTR_INVALID_VL); - error_counter_summary += read_dev_cntr(dd, C_DC_TX_REPLAY, - CNTR_INVALID_VL); - error_counter_summary += read_dev_cntr(dd, C_DC_RX_REPLAY, - CNTR_INVALID_VL); - error_counter_summary += read_dev_cntr(dd, C_DC_SEQ_CRC_CNT, - CNTR_INVALID_VL); - error_counter_summary += read_dev_cntr(dd, C_DC_REINIT_FROM_PEER_CNT, - CNTR_INVALID_VL); + /* local link integrity must be right-shifted by the lli resolution */ + tmp = read_dev_cntr(dd, C_DC_RX_REPLAY, CNTR_INVALID_VL); + tmp += read_dev_cntr(dd, C_DC_TX_REPLAY, CNTR_INVALID_VL); + error_counter_summary += (tmp >> res_lli); + /* link error recovery must b right-shifted by the ler resolution */ + tmp = read_dev_cntr(dd, C_DC_SEQ_CRC_CNT, CNTR_INVALID_VL); + tmp += read_dev_cntr(dd, C_DC_REINIT_FROM_PEER_CNT, CNTR_INVALID_VL); + error_counter_summary += (tmp >> res_ler); error_counter_summary += read_dev_cntr(dd, C_DC_RCV_ERR, CNTR_INVALID_VL); error_counter_summary += read_dev_cntr(dd, C_RCV_OVF, CNTR_INVALID_VL); @@ -2520,6 +2528,7 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp, u32 num_ports; u8 num_pslm; u8 lq, num_vls; + u8 res_lli, res_ler; u64 port_mask; unsigned long port_num; unsigned long vl; @@ -2530,6 +2539,10 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp, num_pslm = hweight64(be64_to_cpu(req->port_select_mask[3])); num_vls = hweight32(be32_to_cpu(req->vl_select_mask)); vl_select_mask = be32_to_cpu(req->vl_select_mask); + res_lli = (u8)(be32_to_cpu(req->resolution) & MSK_LLI) >> MSK_LLI_SFT; + res_lli = res_lli ? res_lli + ADD_LLI : 0; + res_ler = (u8)(be32_to_cpu(req->resolution) & MSK_LER) >> MSK_LER_SFT; + res_ler = res_ler ? res_ler + ADD_LER : 0; if (num_ports != 1 || (vl_select_mask & ~VL_MASK_ALL)) { pmp->mad_hdr.status |= IB_SMP_INVALID_FIELD; @@ -2598,7 +2611,8 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp, cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_BCN, CNTR_INVALID_VL)); rsp->port_error_counter_summary = - cpu_to_be64(get_error_counter_summary(ibdev, port)); + cpu_to_be64(get_error_counter_summary(ibdev, port, + res_lli, res_ler)); vlinfo = &(rsp->vls[0]); vfi = 0; -- GitLab From 799d904bf84c23531cf85c1a505aaed0e264babe Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Wed, 2 Dec 2015 00:43:26 -0500 Subject: [PATCH 1838/2855] staging/rdma/hfi1: diag.c use BIT macros Use BIT macros rather than shifts. Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/diag.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rdma/hfi1/diag.c b/drivers/staging/rdma/hfi1/diag.c index e4cd333bba83c..3e08165104ba1 100644 --- a/drivers/staging/rdma/hfi1/diag.c +++ b/drivers/staging/rdma/hfi1/diag.c @@ -78,8 +78,8 @@ hfi1_cdbg(SNOOP, fmt, ##__VA_ARGS__) /* Snoop option mask */ -#define SNOOP_DROP_SEND (1 << 0) -#define SNOOP_USE_METADATA (1 << 1) +#define SNOOP_DROP_SEND BIT(0) +#define SNOOP_USE_METADATA BIT(1) static u8 snoop_flags; -- GitLab From cce6bd86cbef8f0c2e5e24aaf31858f309d32a3f Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Wed, 2 Dec 2015 00:43:27 -0500 Subject: [PATCH 1839/2855] staging/rdma/hfi1: diag.c fix alignment Fix line alignment in various places as caught by checkpatch --strict. Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/diag.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/rdma/hfi1/diag.c b/drivers/staging/rdma/hfi1/diag.c index 3e08165104ba1..06c5cc649ff13 100644 --- a/drivers/staging/rdma/hfi1/diag.c +++ b/drivers/staging/rdma/hfi1/diag.c @@ -135,7 +135,7 @@ static struct cdev diagpkt_cdev; static struct device *diagpkt_device; static ssize_t diagpkt_write(struct file *fp, const char __user *data, - size_t count, loff_t *off); + size_t count, loff_t *off); static const struct file_operations diagpkt_file_ops = { .owner = THIS_MODULE, @@ -202,12 +202,12 @@ struct hfi1_link_info { static int hfi1_snoop_open(struct inode *in, struct file *fp); static ssize_t hfi1_snoop_read(struct file *fp, char __user *data, - size_t pkt_len, loff_t *off); + size_t pkt_len, loff_t *off); static ssize_t hfi1_snoop_write(struct file *fp, const char __user *data, - size_t count, loff_t *off); + size_t count, loff_t *off); static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg); static unsigned int hfi1_snoop_poll(struct file *fp, - struct poll_table_struct *wait); + struct poll_table_struct *wait); static int hfi1_snoop_release(struct inode *in, struct file *fp); struct hfi1_packet_filter_command { @@ -394,7 +394,7 @@ static ssize_t diagpkt_send(struct diag_pkt *dp) if (dp->version != _DIAG_PKT_VERS) { dd_dev_err(dd, "Invalid version %u for diagpkt_write\n", - dp->version); + dp->version); ret = -EINVAL; goto bail; } @@ -553,7 +553,7 @@ bail: } static ssize_t diagpkt_write(struct file *fp, const char __user *data, - size_t count, loff_t *off) + size_t count, loff_t *off) { struct hfi1_devdata *dd; struct send_context *sc; @@ -606,7 +606,7 @@ static int hfi1_snoop_add(struct hfi1_devdata *dd, const char *name) if (ret) { dd_dev_err(dd, "Couldn't create %s device: %d", name, ret); hfi1_cdev_cleanup(&dd->hfi1_snoop.cdev, - &dd->hfi1_snoop.class_dev); + &dd->hfi1_snoop.class_dev); } return ret; @@ -954,7 +954,7 @@ static ssize_t hfi1_snoop_read(struct file *fp, char __user *data, spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); if (pkt_len >= packet->total_len) { if (copy_to_user(data, packet->data, - packet->total_len)) + packet->total_len)) ret = -EFAULT; else ret = packet->total_len; -- GitLab From f398ab17b2d702620431ad71bc05265e936cc9f1 Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Wed, 2 Dec 2015 00:43:28 -0500 Subject: [PATCH 1840/2855] staging/rdma/hfi1: diag.c fix logical continuations Place logical operators at the end of the previous line when using a multi-line statement. Found by checkpatch --strict Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/diag.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rdma/hfi1/diag.c b/drivers/staging/rdma/hfi1/diag.c index 06c5cc649ff13..94368403e3ef7 100644 --- a/drivers/staging/rdma/hfi1/diag.c +++ b/drivers/staging/rdma/hfi1/diag.c @@ -538,9 +538,9 @@ retry: * NOTE: PRC_FILL_ERR is at best informational and cannot * be depended on. */ - if (!ret && (((wait->code & PRC_STATUS_ERR) - || (wait->code & PRC_FILL_ERR) - || (wait->code & PRC_SC_DISABLE)))) + if (!ret && (((wait->code & PRC_STATUS_ERR) || + (wait->code & PRC_FILL_ERR) || + (wait->code & PRC_SC_DISABLE)))) ret = -EIO; put_diagpkt_wait(wait); /* finished with the structure */ -- GitLab From be98b87ff7d197dfc2e6cf4fea685f682f5d1cc7 Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Wed, 2 Dec 2015 00:43:29 -0500 Subject: [PATCH 1841/2855] staging/rdma/hfi1: diag.c fix white space errors Add or remove whitespace according to checkpatch --strict Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/diag.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/drivers/staging/rdma/hfi1/diag.c b/drivers/staging/rdma/hfi1/diag.c index 94368403e3ef7..a9dc5e9cbc383 100644 --- a/drivers/staging/rdma/hfi1/diag.c +++ b/drivers/staging/rdma/hfi1/diag.c @@ -177,27 +177,27 @@ struct hfi1_link_info { #define HFI1_SNOOP_IOCGETLINKSTATE \ _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ) #define HFI1_SNOOP_IOCSETLINKSTATE \ - _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ+1) + _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 1) #define HFI1_SNOOP_IOCCLEARQUEUE \ - _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ+2) + _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 2) #define HFI1_SNOOP_IOCCLEARFILTER \ - _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ+3) + _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 3) #define HFI1_SNOOP_IOCSETFILTER \ - _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ+4) + _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 4) #define HFI1_SNOOP_IOCGETVERSION \ - _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ+5) + _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 5) #define HFI1_SNOOP_IOCSET_OPTS \ - _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ+6) + _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 6) /* * These offsets +6/+7 could change, but these are already known and used * IOCTL numbers so don't change them without a good reason. */ #define HFI1_SNOOP_IOCGETLINKSTATE_EXTRA \ - _IOWR(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ+6, \ + _IOWR(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 6, \ struct hfi1_link_info) #define HFI1_SNOOP_IOCSETLINKSTATE_EXTRA \ - _IOWR(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ+7, \ + _IOWR(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 7, \ struct hfi1_link_info) static int hfi1_snoop_open(struct inode *in, struct file *fp); @@ -323,14 +323,12 @@ static void hfi1_snoop_remove(struct hfi1_devdata *dd) void hfi1_diag_remove(struct hfi1_devdata *dd) { - hfi1_snoop_remove(dd); if (atomic_dec_and_test(&diagpkt_count)) hfi1_cdev_cleanup(&diagpkt_cdev, &diagpkt_device); hfi1_cdev_cleanup(&dd->diag_cdev, &dd->diag_device); } - /* * Allocated structure shared between the credit return mechanism and * diagpkt_send(). @@ -441,7 +439,7 @@ static ssize_t diagpkt_send(struct diag_pkt *dp) } if (copy_from_user(tmpbuf, - (const void __user *) (unsigned long) dp->data, + (const void __user *)(unsigned long)dp->data, dp->len)) { ret = -EFAULT; goto bail; @@ -619,7 +617,6 @@ static struct hfi1_devdata *hfi1_dd_from_sc_inode(struct inode *in) dd = hfi1_lookup(unit); return dd; - } /* clear or restore send context integrity checks */ @@ -813,7 +810,6 @@ static unsigned int hfi1_snoop_poll(struct file *fp, spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); return ret; - } static ssize_t hfi1_snoop_write(struct file *fp, const char __user *data, @@ -855,7 +851,7 @@ static ssize_t hfi1_snoop_write(struct file *fp, const char __user *data, if (copy_from_user(&byte_one, data, 1)) return -EINVAL; - if (copy_from_user(&byte_two, data+1, 1)) + if (copy_from_user(&byte_two, data + 1, 1)) return -EINVAL; sc4 = (byte_one >> 4) & 0xf; @@ -1329,7 +1325,6 @@ static int hfi1_filter_mad_mgmt_class(void *ibhdr, void *packet_data, static int hfi1_filter_qp_number(void *ibhdr, void *packet_data, void *value) { - struct hfi1_ib_header *hdr; struct hfi1_other_headers *ohdr = NULL; int ret; @@ -1412,7 +1407,6 @@ static int hfi1_filter_ib_service_level(void *ibhdr, void *packet_data, static int hfi1_filter_ib_pkey(void *ibhdr, void *packet_data, void *value) { - u32 lnh = 0; struct hfi1_ib_header *hdr; struct hfi1_other_headers *ohdr = NULL; @@ -1484,7 +1478,6 @@ static struct snoop_packet *allocate_snoop_packet(u32 hdr_len, u32 data_len, u32 md_len) { - struct snoop_packet *packet; packet = kzalloc(sizeof(struct snoop_packet) + hdr_len + data_len @@ -1493,7 +1486,6 @@ static struct snoop_packet *allocate_snoop_packet(u32 hdr_len, if (likely(packet)) INIT_LIST_HEAD(&packet->list); - return packet; } @@ -1550,7 +1542,6 @@ int snoop_recv_handler(struct hfi1_packet *packet) unlikely(snoop_flags & SNOOP_USE_METADATA)) md_len = sizeof(struct capture_md); - s_packet = allocate_snoop_packet(header_size, tlen - header_size, md_len); @@ -1877,5 +1868,4 @@ void snoop_inline_pio_send(struct hfi1_devdata *dd, struct pio_buf *pbuf, inline_pio_out: pio_copy(dd, pbuf, pbc, from, count); - } -- GitLab From 47bc16971939367a8e6b5c38637ba8afb3b8908d Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Wed, 2 Dec 2015 00:43:30 -0500 Subject: [PATCH 1842/2855] staging/rdma/hfi1: diag.c change null comparisons Use !foo rather than (foo == NULL) as recommended by checkpatch --strict Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/diag.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/rdma/hfi1/diag.c b/drivers/staging/rdma/hfi1/diag.c index a9dc5e9cbc383..f687ddfe264d5 100644 --- a/drivers/staging/rdma/hfi1/diag.c +++ b/drivers/staging/rdma/hfi1/diag.c @@ -571,7 +571,7 @@ static ssize_t diagpkt_write(struct file *fp, const char __user *data, */ if (dp.pbc) { dd = hfi1_lookup(dp.unit); - if (dd == NULL) + if (!dd) return -ENODEV; vl = (dp.pbc >> PBC_VL_SHIFT) & PBC_VL_MASK; sc = dd->vld[vl].sc; @@ -657,7 +657,7 @@ static int hfi1_snoop_open(struct inode *in, struct file *fp) mutex_lock(&hfi1_mutex); dd = hfi1_dd_from_sc_inode(in); - if (dd == NULL) { + if (!dd) { ret = -ENODEV; goto bail; } @@ -744,7 +744,7 @@ static int hfi1_snoop_release(struct inode *in, struct file *fp) int mode_flag; dd = hfi1_dd_from_sc_inode(in); - if (dd == NULL) + if (!dd) return -ENODEV; spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); @@ -799,7 +799,7 @@ static unsigned int hfi1_snoop_poll(struct file *fp, struct hfi1_devdata *dd; dd = hfi1_dd_from_sc_inode(fp->f_inode); - if (dd == NULL) + if (!dd) return -ENODEV; spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); @@ -826,7 +826,7 @@ static ssize_t hfi1_snoop_write(struct file *fp, const char __user *data, struct hfi1_pportdata *ppd; dd = hfi1_dd_from_sc_inode(fp->f_inode); - if (dd == NULL) + if (!dd) return -ENODEV; ppd = dd->pport; @@ -924,7 +924,7 @@ static ssize_t hfi1_snoop_read(struct file *fp, char __user *data, struct hfi1_devdata *dd; dd = hfi1_dd_from_sc_inode(fp->f_inode); - if (dd == NULL) + if (!dd) return -ENODEV; spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); @@ -982,7 +982,7 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) struct hfi1_link_info link_info; dd = hfi1_dd_from_sc_inode(fp->f_inode); - if (dd == NULL) + if (!dd) return -ENODEV; spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); @@ -1546,7 +1546,7 @@ int snoop_recv_handler(struct hfi1_packet *packet) tlen - header_size, md_len); - if (unlikely(s_packet == NULL)) { + if (unlikely(!s_packet)) { dd_dev_warn_ratelimited(ppd->dd, "Unable to allocate snoop/capture packet\n"); break; } @@ -1667,7 +1667,7 @@ int snoop_send_pio_handler(struct hfi1_qp *qp, struct hfi1_pkt_state *ps, /* not using ss->total_len as arg 2 b/c that does not count CRC */ s_packet = allocate_snoop_packet(hdr_len, tlen - hdr_len, md_len); - if (unlikely(s_packet == NULL)) { + if (unlikely(!s_packet)) { dd_dev_warn_ratelimited(ppd->dd, "Unable to allocate snoop/capture packet\n"); goto out; } @@ -1836,7 +1836,7 @@ void snoop_inline_pio_send(struct hfi1_devdata *dd, struct pio_buf *pbuf, s_packet = allocate_snoop_packet(packet_len, 0, md_len); - if (unlikely(s_packet == NULL)) { + if (unlikely(!s_packet)) { dd_dev_warn_ratelimited(dd, "Unable to allocate snoop/capture packet\n"); goto inline_pio_out; } -- GitLab From 9d2b75f696d9a3988e0aab00fca8f931ece35d9c Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Wed, 2 Dec 2015 00:43:31 -0500 Subject: [PATCH 1843/2855] staging/rdma/hfi1: diag.c add missing braces Else statements should continue using braces even if there is only 1 line in the block. Found by checkpatch --strict Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/diag.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rdma/hfi1/diag.c b/drivers/staging/rdma/hfi1/diag.c index f687ddfe264d5..ed9cfccc860b4 100644 --- a/drivers/staging/rdma/hfi1/diag.c +++ b/drivers/staging/rdma/hfi1/diag.c @@ -954,12 +954,14 @@ static ssize_t hfi1_snoop_read(struct file *fp, char __user *data, ret = -EFAULT; else ret = packet->total_len; - } else + } else { ret = -EINVAL; + } kfree(packet); - } else + } else { spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); + } return ret; } -- GitLab From c0d4c2582fc20bff48e7287997f1cf7201f191d2 Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Wed, 2 Dec 2015 00:43:32 -0500 Subject: [PATCH 1844/2855] staging/rdma/hfi1: diag.c correct sizeof parameter sizeof should use the variable rather than the struct definition to ensure that type changes are properly accounted for. Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/diag.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rdma/hfi1/diag.c b/drivers/staging/rdma/hfi1/diag.c index ed9cfccc860b4..70a2614db7713 100644 --- a/drivers/staging/rdma/hfi1/diag.c +++ b/drivers/staging/rdma/hfi1/diag.c @@ -1482,7 +1482,7 @@ static struct snoop_packet *allocate_snoop_packet(u32 hdr_len, { struct snoop_packet *packet; - packet = kzalloc(sizeof(struct snoop_packet) + hdr_len + data_len + packet = kzalloc(sizeof(*packet) + hdr_len + data_len + md_len, GFP_ATOMIC | __GFP_NOWARN); if (likely(packet)) -- GitLab From ae1724dffcbcbf0f38320e4295367ff4ea8f513c Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Wed, 2 Dec 2015 00:43:33 -0500 Subject: [PATCH 1845/2855] staging/rdma/hfi1: Fix camel case variables physState, linkState, and devState should be phys_state, link_state, and dev_state Signed-off-by: Dennis Dalessandro Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/diag.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/rdma/hfi1/diag.c b/drivers/staging/rdma/hfi1/diag.c index 70a2614db7713..75b4bf48d8007 100644 --- a/drivers/staging/rdma/hfi1/diag.c +++ b/drivers/staging/rdma/hfi1/diag.c @@ -972,9 +972,9 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) void *filter_value = NULL; long ret = 0; int value = 0; - u8 physState = 0; - u8 linkState = 0; - u16 devState = 0; + u8 phys_state = 0; + u8 link_state = 0; + u16 dev_state = 0; unsigned long flags = 0; unsigned long *argp = NULL; struct hfi1_packet_filter_command filter_cmd = {0}; @@ -1038,31 +1038,31 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) } /* What we want to transition to */ - physState = (value >> 4) & 0xF; - linkState = value & 0xF; + phys_state = (value >> 4) & 0xF; + link_state = value & 0xF; snoop_dbg("Setting link state 0x%x", value); - switch (linkState) { + switch (link_state) { case IB_PORT_NOP: - if (physState == 0) + if (phys_state == 0) break; /* fall through */ case IB_PORT_DOWN: - switch (physState) { + switch (phys_state) { case 0: - devState = HLS_DN_DOWNDEF; + dev_state = HLS_DN_DOWNDEF; break; case 2: - devState = HLS_DN_POLL; + dev_state = HLS_DN_POLL; break; case 3: - devState = HLS_DN_DISABLE; + dev_state = HLS_DN_DISABLE; break; default: ret = -EINVAL; goto done; } - ret = set_link_state(ppd, devState); + ret = set_link_state(ppd, dev_state); break; case IB_PORT_ARMED: ret = set_link_state(ppd, HLS_UP_ARMED); -- GitLab From 845e30e62b19e2db68d36828bf9c540a5e390efe Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Wed, 2 Dec 2015 00:43:34 -0500 Subject: [PATCH 1846/2855] staging/rdma/hfi1: Return early from hfi1_ioctl parameter errors Rather than have a switch in a large else clause make the parameter checks return immediately. Signed-off-by: Dennis Dalessandro Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/diag.c | 348 +++++++++++++++---------------- 1 file changed, 173 insertions(+), 175 deletions(-) diff --git a/drivers/staging/rdma/hfi1/diag.c b/drivers/staging/rdma/hfi1/diag.c index 75b4bf48d8007..205fc837d9c0d 100644 --- a/drivers/staging/rdma/hfi1/diag.c +++ b/drivers/staging/rdma/hfi1/diag.c @@ -987,17 +987,15 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) if (!dd) return -ENODEV; - spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); - mode_flag = dd->hfi1_snoop.mode_flag; if (((_IOC_DIR(cmd) & _IOC_READ) && !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd))) || ((_IOC_DIR(cmd) & _IOC_WRITE) && !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)))) { - ret = -EFAULT; + return -EFAULT; } else if (!capable(CAP_SYS_ADMIN)) { - ret = -EPERM; + return -EPERM; } else if ((mode_flag & HFI1_PORT_CAPTURE_MODE) && (cmd != HFI1_SNOOP_IOCCLEARQUEUE) && (cmd != HFI1_SNOOP_IOCCLEARFILTER) && @@ -1008,208 +1006,208 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) * 3.Set capture filter * Other are invalid. */ + return -EINVAL; + } + + spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); + + switch (cmd) { + case HFI1_SNOOP_IOCSETLINKSTATE: + snoop_dbg("HFI1_SNOOP_IOCSETLINKSTATE is not valid"); ret = -EINVAL; - } else { - switch (cmd) { - case HFI1_SNOOP_IOCSETLINKSTATE: - snoop_dbg("HFI1_SNOOP_IOCSETLINKSTATE is not valid"); + break; + + case HFI1_SNOOP_IOCSETLINKSTATE_EXTRA: + memset(&link_info, 0, sizeof(link_info)); + + if (copy_from_user(&link_info, + (struct hfi1_link_info __user *)arg, + sizeof(link_info))) + ret = -EFAULT; + + value = link_info.port_state; + index = link_info.port_number; + if (index > dd->num_pports - 1) { ret = -EINVAL; break; + } - case HFI1_SNOOP_IOCSETLINKSTATE_EXTRA: - memset(&link_info, 0, sizeof(link_info)); + ppd = &dd->pport[index]; + if (!ppd) { + ret = -EINVAL; + break; + } - if (copy_from_user(&link_info, - (struct hfi1_link_info __user *)arg, - sizeof(link_info))) - ret = -EFAULT; + /* What we want to transition to */ + phys_state = (value >> 4) & 0xF; + link_state = value & 0xF; + snoop_dbg("Setting link state 0x%x", value); - value = link_info.port_state; - index = link_info.port_number; - if (index > dd->num_pports - 1) { - ret = -EINVAL; + switch (link_state) { + case IB_PORT_NOP: + if (phys_state == 0) break; - } - - ppd = &dd->pport[index]; - if (!ppd) { - ret = -EINVAL; - break; - } - - /* What we want to transition to */ - phys_state = (value >> 4) & 0xF; - link_state = value & 0xF; - snoop_dbg("Setting link state 0x%x", value); - - switch (link_state) { - case IB_PORT_NOP: - if (phys_state == 0) - break; - /* fall through */ - case IB_PORT_DOWN: - switch (phys_state) { - case 0: - dev_state = HLS_DN_DOWNDEF; - break; - case 2: - dev_state = HLS_DN_POLL; - break; - case 3: - dev_state = HLS_DN_DISABLE; - break; - default: - ret = -EINVAL; - goto done; - } - ret = set_link_state(ppd, dev_state); + /* fall through */ + case IB_PORT_DOWN: + switch (phys_state) { + case 0: + dev_state = HLS_DN_DOWNDEF; break; - case IB_PORT_ARMED: - ret = set_link_state(ppd, HLS_UP_ARMED); - if (!ret) - send_idle_sma(dd, SMA_IDLE_ARM); + case 2: + dev_state = HLS_DN_POLL; break; - case IB_PORT_ACTIVE: - ret = set_link_state(ppd, HLS_UP_ACTIVE); - if (!ret) - send_idle_sma(dd, SMA_IDLE_ACTIVE); + case 3: + dev_state = HLS_DN_DISABLE; break; default: ret = -EINVAL; - break; - } - - if (ret) - break; - /* fall through */ - case HFI1_SNOOP_IOCGETLINKSTATE: - case HFI1_SNOOP_IOCGETLINKSTATE_EXTRA: - if (cmd == HFI1_SNOOP_IOCGETLINKSTATE_EXTRA) { - memset(&link_info, 0, sizeof(link_info)); - if (copy_from_user(&link_info, - (struct hfi1_link_info __user *)arg, - sizeof(link_info))) - ret = -EFAULT; - index = link_info.port_number; - } else { - ret = __get_user(index, (int __user *) arg); - if (ret != 0) - break; - } - - if (index > dd->num_pports - 1) { - ret = -EINVAL; - break; - } - - ppd = &dd->pport[index]; - if (!ppd) { - ret = -EINVAL; - break; - } - value = hfi1_ibphys_portstate(ppd); - value <<= 4; - value |= driver_lstate(ppd); - - snoop_dbg("Link port | Link State: %d", value); - - if ((cmd == HFI1_SNOOP_IOCGETLINKSTATE_EXTRA) || - (cmd == HFI1_SNOOP_IOCSETLINKSTATE_EXTRA)) { - link_info.port_state = value; - link_info.node_guid = cpu_to_be64(ppd->guid); - link_info.link_speed_active = - ppd->link_speed_active; - link_info.link_width_active = - ppd->link_width_active; - if (copy_to_user( - (struct hfi1_link_info __user *)arg, - &link_info, sizeof(link_info))) - ret = -EFAULT; - } else { - ret = __put_user(value, (int __user *)arg); + goto done; } + ret = set_link_state(ppd, dev_state); break; - - case HFI1_SNOOP_IOCCLEARQUEUE: - snoop_dbg("Clearing snoop queue"); - drain_snoop_list(&dd->hfi1_snoop.queue); + case IB_PORT_ARMED: + ret = set_link_state(ppd, HLS_UP_ARMED); + if (!ret) + send_idle_sma(dd, SMA_IDLE_ARM); break; - - case HFI1_SNOOP_IOCCLEARFILTER: - snoop_dbg("Clearing filter"); - if (dd->hfi1_snoop.filter_callback) { - /* Drain packets first */ - drain_snoop_list(&dd->hfi1_snoop.queue); - dd->hfi1_snoop.filter_callback = NULL; - } - kfree(dd->hfi1_snoop.filter_value); - dd->hfi1_snoop.filter_value = NULL; + case IB_PORT_ACTIVE: + ret = set_link_state(ppd, HLS_UP_ACTIVE); + if (!ret) + send_idle_sma(dd, SMA_IDLE_ACTIVE); + break; + default: + ret = -EINVAL; break; + } - case HFI1_SNOOP_IOCSETFILTER: - snoop_dbg("Setting filter"); - /* just copy command structure */ - argp = (unsigned long *)arg; - if (copy_from_user(&filter_cmd, (void __user *)argp, - sizeof(filter_cmd))) { + if (ret) + break; + /* fall through */ + case HFI1_SNOOP_IOCGETLINKSTATE: + case HFI1_SNOOP_IOCGETLINKSTATE_EXTRA: + if (cmd == HFI1_SNOOP_IOCGETLINKSTATE_EXTRA) { + memset(&link_info, 0, sizeof(link_info)); + if (copy_from_user(&link_info, + (struct hfi1_link_info __user *)arg, + sizeof(link_info))) ret = -EFAULT; + index = link_info.port_number; + } else { + ret = __get_user(index, (int __user *)arg); + if (ret != 0) break; - } - if (filter_cmd.opcode >= HFI1_MAX_FILTERS) { - pr_alert("Invalid opcode in request\n"); - ret = -EINVAL; - break; - } + } - snoop_dbg("Opcode %d Len %d Ptr %p", - filter_cmd.opcode, filter_cmd.length, - filter_cmd.value_ptr); + if (index > dd->num_pports - 1) { + ret = -EINVAL; + break; + } - filter_value = kcalloc(filter_cmd.length, sizeof(u8), - GFP_KERNEL); - if (!filter_value) { - pr_alert("Not enough memory\n"); - ret = -ENOMEM; - break; - } - /* copy remaining data from userspace */ - if (copy_from_user((u8 *)filter_value, - (void __user *)filter_cmd.value_ptr, - filter_cmd.length)) { - kfree(filter_value); + ppd = &dd->pport[index]; + if (!ppd) { + ret = -EINVAL; + break; + } + value = hfi1_ibphys_portstate(ppd); + value <<= 4; + value |= driver_lstate(ppd); + + snoop_dbg("Link port | Link State: %d", value); + + if ((cmd == HFI1_SNOOP_IOCGETLINKSTATE_EXTRA) || + (cmd == HFI1_SNOOP_IOCSETLINKSTATE_EXTRA)) { + link_info.port_state = value; + link_info.node_guid = cpu_to_be64(ppd->guid); + link_info.link_speed_active = + ppd->link_speed_active; + link_info.link_width_active = + ppd->link_width_active; + if (copy_to_user((struct hfi1_link_info __user *)arg, + &link_info, sizeof(link_info))) ret = -EFAULT; - break; - } + } else { + ret = __put_user(value, (int __user *)arg); + } + break; + + case HFI1_SNOOP_IOCCLEARQUEUE: + snoop_dbg("Clearing snoop queue"); + drain_snoop_list(&dd->hfi1_snoop.queue); + break; + + case HFI1_SNOOP_IOCCLEARFILTER: + snoop_dbg("Clearing filter"); + if (dd->hfi1_snoop.filter_callback) { /* Drain packets first */ drain_snoop_list(&dd->hfi1_snoop.queue); - dd->hfi1_snoop.filter_callback = - hfi1_filters[filter_cmd.opcode].filter; - /* just in case we see back to back sets */ - kfree(dd->hfi1_snoop.filter_value); - dd->hfi1_snoop.filter_value = filter_value; + dd->hfi1_snoop.filter_callback = NULL; + } + kfree(dd->hfi1_snoop.filter_value); + dd->hfi1_snoop.filter_value = NULL; + break; + case HFI1_SNOOP_IOCSETFILTER: + snoop_dbg("Setting filter"); + /* just copy command structure */ + argp = (unsigned long *)arg; + if (copy_from_user(&filter_cmd, (void __user *)argp, + sizeof(filter_cmd))) { + ret = -EFAULT; break; - case HFI1_SNOOP_IOCGETVERSION: - value = SNOOP_CAPTURE_VERSION; - snoop_dbg("Getting version: %d", value); - ret = __put_user(value, (int __user *)arg); + } + if (filter_cmd.opcode >= HFI1_MAX_FILTERS) { + pr_alert("Invalid opcode in request\n"); + ret = -EINVAL; break; - case HFI1_SNOOP_IOCSET_OPTS: - snoop_flags = 0; - ret = __get_user(value, (int __user *) arg); - if (ret != 0) - break; + } - snoop_dbg("Setting snoop option %d", value); - if (value & SNOOP_DROP_SEND) - snoop_flags |= SNOOP_DROP_SEND; - if (value & SNOOP_USE_METADATA) - snoop_flags |= SNOOP_USE_METADATA; + snoop_dbg("Opcode %d Len %d Ptr %p", + filter_cmd.opcode, filter_cmd.length, + filter_cmd.value_ptr); + + filter_value = kcalloc(filter_cmd.length, sizeof(u8), + GFP_KERNEL); + if (!filter_value) { + ret = -ENOMEM; break; - default: - ret = -ENOTTY; + } + /* copy remaining data from userspace */ + if (copy_from_user((u8 *)filter_value, + (void __user *)filter_cmd.value_ptr, + filter_cmd.length)) { + kfree(filter_value); + ret = -EFAULT; break; } + /* Drain packets first */ + drain_snoop_list(&dd->hfi1_snoop.queue); + dd->hfi1_snoop.filter_callback = + hfi1_filters[filter_cmd.opcode].filter; + /* just in case we see back to back sets */ + kfree(dd->hfi1_snoop.filter_value); + dd->hfi1_snoop.filter_value = filter_value; + + break; + case HFI1_SNOOP_IOCGETVERSION: + value = SNOOP_CAPTURE_VERSION; + snoop_dbg("Getting version: %d", value); + ret = __put_user(value, (int __user *)arg); + break; + case HFI1_SNOOP_IOCSET_OPTS: + snoop_flags = 0; + ret = __get_user(value, (int __user *)arg); + if (ret != 0) + break; + + snoop_dbg("Setting snoop option %d", value); + if (value & SNOOP_DROP_SEND) + snoop_flags |= SNOOP_DROP_SEND; + if (value & SNOOP_USE_METADATA) + snoop_flags |= SNOOP_USE_METADATA; + break; + default: + ret = -ENOTTY; + break; } done: spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); -- GitLab From d8e499ffe4090ad1e53700a2d0f00599ac69727e Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Wed, 2 Dec 2015 00:43:35 -0500 Subject: [PATCH 1847/2855] staging/rdma/hfi1: hfi1_ioctl remove setlink state Set link state is not supported remove from the switch statement and allow the default to return -ENOTTY Signed-off-by: Dennis Dalessandro Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/diag.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/rdma/hfi1/diag.c b/drivers/staging/rdma/hfi1/diag.c index 205fc837d9c0d..d82a712b29eff 100644 --- a/drivers/staging/rdma/hfi1/diag.c +++ b/drivers/staging/rdma/hfi1/diag.c @@ -1012,11 +1012,6 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); switch (cmd) { - case HFI1_SNOOP_IOCSETLINKSTATE: - snoop_dbg("HFI1_SNOOP_IOCSETLINKSTATE is not valid"); - ret = -EINVAL; - break; - case HFI1_SNOOP_IOCSETLINKSTATE_EXTRA: memset(&link_info, 0, sizeof(link_info)); -- GitLab From f1811cf632bd00947c3a2f7e538148c99d794daf Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Wed, 2 Dec 2015 00:43:36 -0500 Subject: [PATCH 1848/2855] staging/rdma/hfi1: Further clean up hfi1_ioctl parameter checks Final clean up of the if/then/else clause for the parameter checks of hfi1_ioctl Signed-off-by: Dennis Dalessandro Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/diag.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/staging/rdma/hfi1/diag.c b/drivers/staging/rdma/hfi1/diag.c index d82a712b29eff..ccc5aeccb44dd 100644 --- a/drivers/staging/rdma/hfi1/diag.c +++ b/drivers/staging/rdma/hfi1/diag.c @@ -982,24 +982,28 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) struct hfi1_pportdata *ppd = NULL; unsigned int index; struct hfi1_link_info link_info; + int read_cmd, write_cmd, read_ok, write_ok; dd = hfi1_dd_from_sc_inode(fp->f_inode); if (!dd) return -ENODEV; mode_flag = dd->hfi1_snoop.mode_flag; + read_cmd = _IOC_DIR(cmd) & _IOC_READ; + write_cmd = _IOC_DIR(cmd) & _IOC_WRITE; + write_ok = access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); + read_ok = access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); - if (((_IOC_DIR(cmd) & _IOC_READ) - && !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd))) - || ((_IOC_DIR(cmd) & _IOC_WRITE) - && !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)))) { + if ((read_cmd && !write_ok) || (write_cmd && !read_ok)) return -EFAULT; - } else if (!capable(CAP_SYS_ADMIN)) { + + if (!capable(CAP_SYS_ADMIN)) return -EPERM; - } else if ((mode_flag & HFI1_PORT_CAPTURE_MODE) && - (cmd != HFI1_SNOOP_IOCCLEARQUEUE) && - (cmd != HFI1_SNOOP_IOCCLEARFILTER) && - (cmd != HFI1_SNOOP_IOCSETFILTER)) { + + if ((mode_flag & HFI1_PORT_CAPTURE_MODE) && + (cmd != HFI1_SNOOP_IOCCLEARQUEUE) && + (cmd != HFI1_SNOOP_IOCCLEARFILTER) && + (cmd != HFI1_SNOOP_IOCSETFILTER)) /* Capture devices are allowed only 3 operations * 1.Clear capture queue * 2.Clear capture filter @@ -1007,7 +1011,6 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) * Other are invalid. */ return -EINVAL; - } spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); -- GitLab From 33ab349037db079aec7d60608fe4fb1114be6b91 Mon Sep 17 00:00:00 2001 From: Dennis Dalessandro Date: Wed, 2 Dec 2015 00:43:37 -0500 Subject: [PATCH 1849/2855] staging/rdma/hfi1: Reduce snoop locking scope in IOCTL handler. This patch avoids issues while calling into copy from/to user while holding the lock by only taking the lock when it is absolutely required. The only commands which require the snoop lock are: *Set Filter *Clear Filter *Clear Queue Reviewed-by: Mike Marciniszyn Signed-off-by: Dennis Dalessandro Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/diag.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rdma/hfi1/diag.c b/drivers/staging/rdma/hfi1/diag.c index ccc5aeccb44dd..b0b7e28ebfc2d 100644 --- a/drivers/staging/rdma/hfi1/diag.c +++ b/drivers/staging/rdma/hfi1/diag.c @@ -1012,8 +1012,6 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) */ return -EINVAL; - spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); - switch (cmd) { case HFI1_SNOOP_IOCSETLINKSTATE_EXTRA: memset(&link_info, 0, sizeof(link_info)); @@ -1130,11 +1128,14 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) case HFI1_SNOOP_IOCCLEARQUEUE: snoop_dbg("Clearing snoop queue"); + spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); drain_snoop_list(&dd->hfi1_snoop.queue); + spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); break; case HFI1_SNOOP_IOCCLEARFILTER: snoop_dbg("Clearing filter"); + spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); if (dd->hfi1_snoop.filter_callback) { /* Drain packets first */ drain_snoop_list(&dd->hfi1_snoop.queue); @@ -1142,6 +1143,7 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) } kfree(dd->hfi1_snoop.filter_value); dd->hfi1_snoop.filter_value = NULL; + spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); break; case HFI1_SNOOP_IOCSETFILTER: @@ -1178,13 +1180,14 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) break; } /* Drain packets first */ + spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); drain_snoop_list(&dd->hfi1_snoop.queue); dd->hfi1_snoop.filter_callback = hfi1_filters[filter_cmd.opcode].filter; /* just in case we see back to back sets */ kfree(dd->hfi1_snoop.filter_value); dd->hfi1_snoop.filter_value = filter_value; - + spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); break; case HFI1_SNOOP_IOCGETVERSION: value = SNOOP_CAPTURE_VERSION; @@ -1208,7 +1211,6 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) break; } done: - spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); return ret; } -- GitLab From 2d1900f131f015ff335c53b655edfb4e10e57ee7 Mon Sep 17 00:00:00 2001 From: Dennis Dalessandro Date: Wed, 2 Dec 2015 00:43:38 -0500 Subject: [PATCH 1850/2855] staging/rdma/hfi1: Return immediately on error Now that the spinlock is not taken throughout hfi1_ioctl it is safe to return early rather than setting a variable and falling through the switch. Reviewed-by: Mike Marciniszyn Signed-off-by: Dennis Dalessandro Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/diag.c | 62 +++++++++++++------------------- 1 file changed, 24 insertions(+), 38 deletions(-) diff --git a/drivers/staging/rdma/hfi1/diag.c b/drivers/staging/rdma/hfi1/diag.c index b0b7e28ebfc2d..0c8831705664c 100644 --- a/drivers/staging/rdma/hfi1/diag.c +++ b/drivers/staging/rdma/hfi1/diag.c @@ -1019,20 +1019,16 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) if (copy_from_user(&link_info, (struct hfi1_link_info __user *)arg, sizeof(link_info))) - ret = -EFAULT; + return -EFAULT; value = link_info.port_state; index = link_info.port_number; - if (index > dd->num_pports - 1) { - ret = -EINVAL; - break; - } + if (index > dd->num_pports - 1) + return -EINVAL; ppd = &dd->pport[index]; - if (!ppd) { - ret = -EINVAL; - break; - } + if (!ppd) + return -EINVAL; /* What we want to transition to */ phys_state = (value >> 4) & 0xF; @@ -1056,8 +1052,7 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) dev_state = HLS_DN_DISABLE; break; default: - ret = -EINVAL; - goto done; + return -EINVAL; } ret = set_link_state(ppd, dev_state); break; @@ -1072,8 +1067,7 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) send_idle_sma(dd, SMA_IDLE_ACTIVE); break; default: - ret = -EINVAL; - break; + return -EINVAL; } if (ret) @@ -1086,7 +1080,7 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) if (copy_from_user(&link_info, (struct hfi1_link_info __user *)arg, sizeof(link_info))) - ret = -EFAULT; + return -EFAULT; index = link_info.port_number; } else { ret = __get_user(index, (int __user *)arg); @@ -1094,16 +1088,13 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) break; } - if (index > dd->num_pports - 1) { - ret = -EINVAL; - break; - } + if (index > dd->num_pports - 1) + return -EINVAL; ppd = &dd->pport[index]; - if (!ppd) { - ret = -EINVAL; - break; - } + if (!ppd) + return -EINVAL; + value = hfi1_ibphys_portstate(ppd); value <<= 4; value |= driver_lstate(ppd); @@ -1120,7 +1111,7 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) ppd->link_width_active; if (copy_to_user((struct hfi1_link_info __user *)arg, &link_info, sizeof(link_info))) - ret = -EFAULT; + return -EFAULT; } else { ret = __put_user(value, (int __user *)arg); } @@ -1151,14 +1142,12 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) /* just copy command structure */ argp = (unsigned long *)arg; if (copy_from_user(&filter_cmd, (void __user *)argp, - sizeof(filter_cmd))) { - ret = -EFAULT; - break; - } + sizeof(filter_cmd))) + return -EFAULT; + if (filter_cmd.opcode >= HFI1_MAX_FILTERS) { pr_alert("Invalid opcode in request\n"); - ret = -EINVAL; - break; + return -EINVAL; } snoop_dbg("Opcode %d Len %d Ptr %p", @@ -1167,17 +1156,15 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) filter_value = kcalloc(filter_cmd.length, sizeof(u8), GFP_KERNEL); - if (!filter_value) { - ret = -ENOMEM; - break; - } + if (!filter_value) + return -ENOMEM; + /* copy remaining data from userspace */ if (copy_from_user((u8 *)filter_value, (void __user *)filter_cmd.value_ptr, filter_cmd.length)) { kfree(filter_value); - ret = -EFAULT; - break; + return -EFAULT; } /* Drain packets first */ spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); @@ -1207,10 +1194,9 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) snoop_flags |= SNOOP_USE_METADATA; break; default: - ret = -ENOTTY; - break; + return -ENOTTY; } -done: + return ret; } -- GitLab From 483119a760639858ce2369a314d1bd93a3db3062 Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Tue, 8 Dec 2015 17:10:10 -0500 Subject: [PATCH 1851/2855] staging/rdma/hfi1: Unconditionally clean-up SDMA queues There is no need to cleck if the packet queue is allocated when cleaning up a user context. The hfi1_user_sdma_free_queues() function already does all the required checks. Reviewed-by: Ira Weiny Signed-off-by: Mitko Haralanov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/file_ops.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/rdma/hfi1/file_ops.c b/drivers/staging/rdma/hfi1/file_ops.c index 874305f0a9256..1bdc073fa881a 100644 --- a/drivers/staging/rdma/hfi1/file_ops.c +++ b/drivers/staging/rdma/hfi1/file_ops.c @@ -731,8 +731,7 @@ static int hfi1_file_close(struct inode *inode, struct file *fp) flush_wc(); /* drain user sdma queue */ - if (fdata->pq) - hfi1_user_sdma_free_queues(fdata); + hfi1_user_sdma_free_queues(fdata); /* * Clear any left over, unhandled events so the next process that -- GitLab From def8228452f87d05bd43ac21aeaf894ca081bca4 Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Tue, 8 Dec 2015 17:10:09 -0500 Subject: [PATCH 1852/2855] staging/rdma/hfi1: Convert to use get_user_pages_fast Convert hfi1_get_user_pages() to use get_user_pages_fast(), which is much fatster. The mm semaphore is still taken to update the pinned page count but is for a much shorter amount of time. Reviewed-by: Ira Weiny Signed-off-by: Mitko Haralanov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/file_ops.c | 8 +-- drivers/staging/rdma/hfi1/hfi.h | 4 +- drivers/staging/rdma/hfi1/user_pages.c | 97 +++++++------------------- 3 files changed, 32 insertions(+), 77 deletions(-) diff --git a/drivers/staging/rdma/hfi1/file_ops.c b/drivers/staging/rdma/hfi1/file_ops.c index 1bdc073fa881a..d57d549052c8f 100644 --- a/drivers/staging/rdma/hfi1/file_ops.c +++ b/drivers/staging/rdma/hfi1/file_ops.c @@ -1663,8 +1663,8 @@ static int exp_tid_setup(struct file *fp, struct hfi1_tid_info *tinfo) * Now that we know how many free RcvArray entries we have, * we can pin that many user pages. */ - ret = hfi1_get_user_pages(vaddr + (mapped * PAGE_SIZE), - pinned, pages); + ret = hfi1_acquire_user_pages(vaddr + (mapped * PAGE_SIZE), + pinned, true, pages); if (ret) { /* * We can't continue because the pages array won't be @@ -1833,7 +1833,7 @@ static int exp_tid_free(struct file *fp, struct hfi1_tid_info *tinfo) } } flush_wc(); - hfi1_release_user_pages(pshadow, pcount); + hfi1_release_user_pages(pshadow, pcount, true); clear_bit(bitidx, &uctxt->tidusemap[idx]); map &= ~(1ULL<physshadow[tid] = 0; uctxt->tid_pg_list[tid] = NULL; pci_unmap_page(dd->pcidev, phys, PAGE_SIZE, PCI_DMA_FROMDEVICE); - hfi1_release_user_pages(&p, 1); + hfi1_release_user_pages(&p, 1, true); } } diff --git a/drivers/staging/rdma/hfi1/hfi.h b/drivers/staging/rdma/hfi1/hfi.h index 7f8cafa841b5c..7aea874b3dfce 100644 --- a/drivers/staging/rdma/hfi1/hfi.h +++ b/drivers/staging/rdma/hfi1/hfi.h @@ -1587,8 +1587,8 @@ void hfi1_set_led_override(struct hfi1_pportdata *ppd, unsigned int val); */ #define DEFAULT_RCVHDR_ENTSIZE 32 -int hfi1_get_user_pages(unsigned long, size_t, struct page **); -void hfi1_release_user_pages(struct page **, size_t); +int hfi1_acquire_user_pages(unsigned long, size_t, bool, struct page **); +void hfi1_release_user_pages(struct page **, size_t, bool); static inline void clear_rcvhdrtail(const struct hfi1_ctxtdata *rcd) { diff --git a/drivers/staging/rdma/hfi1/user_pages.c b/drivers/staging/rdma/hfi1/user_pages.c index 9071afbd7bf44..692de658f0dce 100644 --- a/drivers/staging/rdma/hfi1/user_pages.c +++ b/drivers/staging/rdma/hfi1/user_pages.c @@ -49,59 +49,11 @@ */ #include +#include #include #include "hfi.h" -static void __hfi1_release_user_pages(struct page **p, size_t num_pages, - int dirty) -{ - size_t i; - - for (i = 0; i < num_pages; i++) { - if (dirty) - set_page_dirty_lock(p[i]); - put_page(p[i]); - } -} - -/* - * Call with current->mm->mmap_sem held. - */ -static int __hfi1_get_user_pages(unsigned long start_page, size_t num_pages, - struct page **p) -{ - unsigned long lock_limit; - size_t got; - int ret; - - lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; - - if (num_pages > lock_limit && !capable(CAP_IPC_LOCK)) { - ret = -ENOMEM; - goto bail; - } - - for (got = 0; got < num_pages; got += ret) { - ret = get_user_pages(current, current->mm, - start_page + got * PAGE_SIZE, - num_pages - got, 1, 1, - p + got, NULL); - if (ret < 0) - goto bail_release; - } - - current->mm->pinned_vm += num_pages; - - ret = 0; - goto bail; - -bail_release: - __hfi1_release_user_pages(p, got, 0); -bail: - return ret; -} - /** * hfi1_map_page - a safety wrapper around pci_map_page() * @@ -116,41 +68,44 @@ dma_addr_t hfi1_map_page(struct pci_dev *hwdev, struct page *page, return phys; } -/** - * hfi1_get_user_pages - lock user pages into memory - * @start_page: the start page - * @num_pages: the number of pages - * @p: the output page structures - * - * This function takes a given start page (page aligned user virtual - * address) and pins it and the following specified number of pages. For - * now, num_pages is always 1, but that will probably change at some point - * (because caller is doing expected sends on a single virtually contiguous - * buffer, so we can do all pages at once). - */ -int hfi1_get_user_pages(unsigned long start_page, size_t num_pages, - struct page **p) +int hfi1_acquire_user_pages(unsigned long vaddr, size_t npages, bool writable, + struct page **pages) { + unsigned long pinned, lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; + bool can_lock = capable(CAP_IPC_LOCK); int ret; - down_write(¤t->mm->mmap_sem); + down_read(¤t->mm->mmap_sem); + pinned = current->mm->pinned_vm; + up_read(¤t->mm->mmap_sem); - ret = __hfi1_get_user_pages(start_page, num_pages, p); + if (pinned + npages > lock_limit && !can_lock) + return -ENOMEM; + ret = get_user_pages_fast(vaddr, npages, writable, pages); + if (ret < 0) + return ret; + + down_write(¤t->mm->mmap_sem); + current->mm->pinned_vm += ret; up_write(¤t->mm->mmap_sem); return ret; } -void hfi1_release_user_pages(struct page **p, size_t num_pages) +void hfi1_release_user_pages(struct page **p, size_t npages, bool dirty) { - if (current->mm) /* during close after signal, mm can be NULL */ - down_write(¤t->mm->mmap_sem); + size_t i; - __hfi1_release_user_pages(p, num_pages, 1); + for (i = 0; i < npages; i++) { + if (dirty) + set_page_dirty_lock(p[i]); + put_page(p[i]); + } - if (current->mm) { - current->mm->pinned_vm -= num_pages; + if (current->mm) { /* during close after signal, mm can be NULL */ + down_write(¤t->mm->mmap_sem); + current->mm->pinned_vm -= npages; up_write(¤t->mm->mmap_sem); } } -- GitLab From a0d406934a460b2b8dac8cf15996ec8591e33e2e Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Tue, 8 Dec 2015 17:10:13 -0500 Subject: [PATCH 1853/2855] staging/rdma/hfi1: Add page lock limit check for SDMA requests The driver pins pages on behalf of user processes in two separate instances - when the process has submitted a SDMA transfer and when the process programs an expected receive buffer. When pinning pages, the driver is required to observe the locked page limit set by the system administrator and refuse to lock more pages than allowed. Such a check was done for expected receives but was missing from the SDMA transfer code path. This commit adds the missing check for SDMA transfers. As of this commit, user SDMA or expected receive requests will be rejected if the number of pages required to be pinned will exceed the set limit. Due to the fact that the driver needs to take the MM semaphore in order to update the locked page count (which can sleep), this cannot be done by the callback function as it [the callback] is executed in interrupt context. Therefore, it is necessary to put all the completed SDMA tx requests onto a separate list (txcmp) and offload the actual clean-up and unpinning work to a workqueue. Reviewed-by: Dennis Dalessandro Reviewed-by: Ira Weiny Signed-off-by: Mitko Haralanov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/user_sdma.c | 276 ++++++++++++++++---------- drivers/staging/rdma/hfi1/user_sdma.h | 2 + 2 files changed, 169 insertions(+), 109 deletions(-) diff --git a/drivers/staging/rdma/hfi1/user_sdma.c b/drivers/staging/rdma/hfi1/user_sdma.c index 41408f82afe87..55fe02ef37cbc 100644 --- a/drivers/staging/rdma/hfi1/user_sdma.c +++ b/drivers/staging/rdma/hfi1/user_sdma.c @@ -213,12 +213,6 @@ struct user_sdma_request { * to 0. */ u8 omfactor; - /* - * pointer to the user's task_struct. We are going to - * get a reference to it so we can process io vectors - * at a later time. - */ - struct task_struct *user_proc; /* * pointer to the user's mm_struct. We are going to * get a reference to it so it doesn't get freed @@ -245,9 +239,13 @@ struct user_sdma_request { u16 tididx; u32 sent; u64 seqnum; - spinlock_t list_lock; struct list_head txps; + spinlock_t txcmp_lock; /* protect txcmp list */ + struct list_head txcmp; unsigned long flags; + /* status of the last txreq completed */ + int status; + struct work_struct worker; }; /* @@ -260,6 +258,7 @@ struct user_sdma_txreq { /* Packet header for the txreq */ struct hfi1_pkt_header hdr; struct sdma_txreq txreq; + struct list_head list; struct user_sdma_request *req; struct { struct user_sdma_iovec *vec; @@ -282,10 +281,12 @@ struct user_sdma_txreq { static int user_sdma_send_pkts(struct user_sdma_request *, unsigned); static int num_user_pages(const struct iovec *); static void user_sdma_txreq_cb(struct sdma_txreq *, int, int); +static void user_sdma_delayed_completion(struct work_struct *); static void user_sdma_free_request(struct user_sdma_request *); static int pin_vector_pages(struct user_sdma_request *, struct user_sdma_iovec *); -static void unpin_vector_pages(struct user_sdma_iovec *); +static void unpin_vector_pages(struct user_sdma_request *, + struct user_sdma_iovec *); static int check_header_template(struct user_sdma_request *, struct hfi1_pkt_header *, u32, u32); static int set_txreq_header(struct user_sdma_request *, @@ -391,6 +392,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, struct file *fp) pq->n_max_reqs = hfi1_sdma_comp_ring_size; pq->state = SDMA_PKT_Q_INACTIVE; atomic_set(&pq->n_reqs, 0); + init_waitqueue_head(&pq->wait); iowait_init(&pq->busy, 0, NULL, defer_packet_queue, activate_packet_queue); @@ -451,26 +453,16 @@ int hfi1_user_sdma_free_queues(struct hfi1_filedata *fd) uctxt->ctxt, fd->subctxt); pq = fd->pq; if (pq) { - u16 i, j; - spin_lock_irqsave(&uctxt->sdma_qlock, flags); if (!list_empty(&pq->list)) list_del_init(&pq->list); spin_unlock_irqrestore(&uctxt->sdma_qlock, flags); iowait_sdma_drain(&pq->busy); - if (pq->reqs) { - for (i = 0, j = 0; i < atomic_read(&pq->n_reqs) && - j < pq->n_max_reqs; j++) { - struct user_sdma_request *req = &pq->reqs[j]; - - if (test_bit(SDMA_REQ_IN_USE, &req->flags)) { - set_comp_state(req, ERROR, -ECOMM); - user_sdma_free_request(req); - i++; - } - } - kfree(pq->reqs); - } + /* Wait until all requests have been freed. */ + wait_event_interruptible( + pq->wait, + (ACCESS_ONCE(pq->state) == SDMA_PKT_Q_INACTIVE)); + kfree(pq->reqs); kmem_cache_destroy(pq->txreq_cache); kfree(pq); fd->pq = NULL; @@ -544,8 +536,12 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, req->data_iovs = req_iovcnt(info.ctrl) - 1; req->pq = pq; req->cq = cq; + req->status = -1; INIT_LIST_HEAD(&req->txps); - spin_lock_init(&req->list_lock); + INIT_LIST_HEAD(&req->txcmp); + INIT_WORK(&req->worker, user_sdma_delayed_completion); + + spin_lock_init(&req->txcmp_lock); memcpy(&req->info, &info, sizeof(info)); if (req_opcode(info.ctrl) == EXPECTED) @@ -685,18 +681,16 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, sent = user_sdma_send_pkts(req, pcount); if (unlikely(sent < 0)) { if (sent != -EBUSY) { - ret = sent; - goto send_err; + req->status = sent; + set_comp_state(req, ERROR, req->status); + return sent; } else sent = 0; } atomic_inc(&pq->n_reqs); + xchg(&pq->state, SDMA_PKT_Q_ACTIVE); if (sent < req->info.npkts) { - /* Take the references to the user's task and mm_struct */ - get_task_struct(current); - req->user_proc = current; - /* * This is a somewhat blocking send implementation. * The driver will block the caller until all packets of the @@ -706,8 +700,10 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, while (!test_bit(SDMA_REQ_SEND_DONE, &req->flags)) { ret = user_sdma_send_pkts(req, pcount); if (ret < 0) { - if (ret != -EBUSY) - goto send_err; + if (ret != -EBUSY) { + req->status = ret; + return ret; + } wait_event_interruptible_timeout( pq->busy.wait_dma, (pq->state == SDMA_PKT_Q_ACTIVE), @@ -717,14 +713,10 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, } } - ret = 0; *count += idx; - goto done; -send_err: - set_comp_state(req, ERROR, ret); + return 0; free_req: user_sdma_free_request(req); -done: return ret; } @@ -825,6 +817,7 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts) tx->req = req; tx->busycount = 0; tx->idx = -1; + INIT_LIST_HEAD(&tx->list); memset(tx->iovecs, 0, sizeof(tx->iovecs)); if (req->seqnum == req->info.npkts - 1) @@ -949,9 +942,8 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts) if (ret) { int i; - dd_dev_err(pq->dd, - "SDMA txreq add page failed %d\n", - ret); + SDMA_DBG(req, "SDMA txreq add page failed %d\n", + ret); /* Mark all assigned vectors as complete so they * are unpinned in the callback. */ for (i = tx->idx; i >= 0; i--) { @@ -1045,52 +1037,58 @@ static inline int num_user_pages(const struct iovec *iov) static int pin_vector_pages(struct user_sdma_request *req, struct user_sdma_iovec *iovec) { - int ret = 0; - unsigned pinned; + int pinned, npages; - iovec->npages = num_user_pages(&iovec->iov); - iovec->pages = kcalloc(iovec->npages, sizeof(*iovec->pages), - GFP_KERNEL); + npages = num_user_pages(&iovec->iov); + iovec->pages = kcalloc(npages, sizeof(*iovec->pages), GFP_KERNEL); if (!iovec->pages) { SDMA_DBG(req, "Failed page array alloc"); - ret = -ENOMEM; - goto done; + return -ENOMEM; } - /* If called by the kernel thread, use the user's mm */ - if (current->flags & PF_KTHREAD) - use_mm(req->user_proc->mm); - pinned = get_user_pages_fast( - (unsigned long)iovec->iov.iov_base, - iovec->npages, 0, iovec->pages); - /* If called by the kernel thread, unuse the user's mm */ - if (current->flags & PF_KTHREAD) - unuse_mm(req->user_proc->mm); - if (pinned != iovec->npages) { - SDMA_DBG(req, "Failed to pin pages (%u/%u)", pinned, - iovec->npages); - ret = -EFAULT; - goto pfree; + + /* + * Get a reference to the process's mm so we can use it when + * unpinning the io vectors. + */ + req->pq->user_mm = get_task_mm(current); + + pinned = hfi1_acquire_user_pages((unsigned long)iovec->iov.iov_base, + npages, 0, iovec->pages); + + if (pinned < 0) + return pinned; + + iovec->npages = pinned; + if (pinned != npages) { + SDMA_DBG(req, "Failed to pin pages (%d/%u)", pinned, npages); + unpin_vector_pages(req, iovec); + return -EFAULT; } - goto done; -pfree: - unpin_vector_pages(iovec); -done: - return ret; + return 0; } -static void unpin_vector_pages(struct user_sdma_iovec *iovec) +static void unpin_vector_pages(struct user_sdma_request *req, + struct user_sdma_iovec *iovec) { - unsigned i; + /* + * Unpinning is done through the workqueue so use the + * process's mm if we have a reference to it. + */ + if ((current->flags & PF_KTHREAD) && req->pq->user_mm) + use_mm(req->pq->user_mm); - if (ACCESS_ONCE(iovec->offset) != iovec->iov.iov_len) { - hfi1_cdbg(SDMA, - "the complete vector has not been sent yet %llu %zu", - iovec->offset, iovec->iov.iov_len); - return; + hfi1_release_user_pages(iovec->pages, iovec->npages, 0); + + /* + * Unuse the user's mm (see above) and release the + * reference to it. + */ + if (req->pq->user_mm) { + if (current->flags & PF_KTHREAD) + unuse_mm(req->pq->user_mm); + mmput(req->pq->user_mm); } - for (i = 0; i < iovec->npages; i++) - if (iovec->pages[i]) - put_page(iovec->pages[i]); + kfree(iovec->pages); iovec->pages = NULL; iovec->npages = 0; @@ -1358,54 +1356,116 @@ static int set_txreq_header_ahg(struct user_sdma_request *req, return diff; } +/* + * SDMA tx request completion callback. Called when the SDMA progress + * state machine gets notification that the SDMA descriptors for this + * tx request have been processed by the DMA engine. Called in + * interrupt context. + */ static void user_sdma_txreq_cb(struct sdma_txreq *txreq, int status, int drain) { struct user_sdma_txreq *tx = container_of(txreq, struct user_sdma_txreq, txreq); - struct user_sdma_request *req = tx->req; - struct hfi1_user_sdma_pkt_q *pq = req ? req->pq : NULL; - u64 tx_seqnum; + struct user_sdma_request *req; + bool defer; + int i; - if (unlikely(!req || !pq)) + if (!tx->req) return; - /* If we have any io vectors associated with this txreq, - * check whether they need to be 'freed'. */ - if (tx->idx != -1) { - int i; + req = tx->req; + /* + * If this is the callback for the last packet of the request, + * queue up the request for clean up. + */ + defer = (tx->seqnum == req->info.npkts - 1); - for (i = tx->idx; i >= 0; i--) { - if (tx->iovecs[i].flags & TXREQ_FLAGS_IOVEC_LAST_PKT) - unpin_vector_pages(tx->iovecs[i].vec); + /* + * If we have any io vectors associated with this txreq, + * check whether they need to be 'freed'. We can't free them + * here because the unpin function needs to be able to sleep. + */ + for (i = tx->idx; i >= 0; i--) { + if (tx->iovecs[i].flags & TXREQ_FLAGS_IOVEC_LAST_PKT) { + defer = true; + break; } } - tx_seqnum = tx->seqnum; - kmem_cache_free(pq->txreq_cache, tx); - + req->status = status; if (status != SDMA_TXREQ_S_OK) { - dd_dev_err(pq->dd, "SDMA completion with error %d", status); - set_comp_state(req, ERROR, status); + SDMA_DBG(req, "SDMA completion with error %d", + status); set_bit(SDMA_REQ_HAS_ERROR, &req->flags); - /* Do not free the request until the sender loop has ack'ed - * the error and we've seen all txreqs. */ - if (tx_seqnum == ACCESS_ONCE(req->seqnum) && - test_bit(SDMA_REQ_DONE_ERROR, &req->flags)) { - atomic_dec(&pq->n_reqs); - user_sdma_free_request(req); - } + defer = true; + } + + /* + * Defer the clean up of the iovectors and the request until later + * so it can be done outside of interrupt context. + */ + if (defer) { + spin_lock(&req->txcmp_lock); + list_add_tail(&tx->list, &req->txcmp); + spin_unlock(&req->txcmp_lock); + schedule_work(&req->worker); } else { - if (tx_seqnum == req->info.npkts - 1) { - /* We've sent and completed all packets in this - * request. Signal completion to the user */ - atomic_dec(&pq->n_reqs); - set_comp_state(req, COMPLETE, 0); - user_sdma_free_request(req); + kmem_cache_free(req->pq->txreq_cache, tx); + } +} + +static void user_sdma_delayed_completion(struct work_struct *work) +{ + struct user_sdma_request *req = + container_of(work, struct user_sdma_request, worker); + struct hfi1_user_sdma_pkt_q *pq = req->pq; + struct user_sdma_txreq *tx = NULL; + unsigned long flags; + u64 seqnum; + int i; + + while (1) { + spin_lock_irqsave(&req->txcmp_lock, flags); + if (!list_empty(&req->txcmp)) { + tx = list_first_entry(&req->txcmp, + struct user_sdma_txreq, list); + list_del(&tx->list); + } + spin_unlock_irqrestore(&req->txcmp_lock, flags); + if (!tx) + break; + + for (i = tx->idx; i >= 0; i--) + if (tx->iovecs[i].flags & TXREQ_FLAGS_IOVEC_LAST_PKT) + unpin_vector_pages(req, tx->iovecs[i].vec); + + seqnum = tx->seqnum; + kmem_cache_free(pq->txreq_cache, tx); + tx = NULL; + + if (req->status != SDMA_TXREQ_S_OK) { + if (seqnum == ACCESS_ONCE(req->seqnum) && + test_bit(SDMA_REQ_DONE_ERROR, &req->flags)) { + atomic_dec(&pq->n_reqs); + set_comp_state(req, ERROR, req->status); + user_sdma_free_request(req); + break; + } + } else { + if (seqnum == req->info.npkts - 1) { + atomic_dec(&pq->n_reqs); + set_comp_state(req, COMPLETE, 0); + user_sdma_free_request(req); + break; + } } } - if (!atomic_read(&pq->n_reqs)) + + if (!atomic_read(&pq->n_reqs)) { xchg(&pq->state, SDMA_PKT_Q_INACTIVE); + wake_up(&pq->wait); + } } static void user_sdma_free_request(struct user_sdma_request *req) @@ -1426,10 +1486,8 @@ static void user_sdma_free_request(struct user_sdma_request *req) for (i = 0; i < req->data_iovs; i++) if (req->iovs[i].npages && req->iovs[i].pages) - unpin_vector_pages(&req->iovs[i]); + unpin_vector_pages(req, &req->iovs[i]); } - if (req->user_proc) - put_task_struct(req->user_proc); kfree(req->tids); clear_bit(SDMA_REQ_IN_USE, &req->flags); } diff --git a/drivers/staging/rdma/hfi1/user_sdma.h b/drivers/staging/rdma/hfi1/user_sdma.h index 0046ffa774fef..0afa28508a8a3 100644 --- a/drivers/staging/rdma/hfi1/user_sdma.h +++ b/drivers/staging/rdma/hfi1/user_sdma.h @@ -68,6 +68,8 @@ struct hfi1_user_sdma_pkt_q { struct user_sdma_request *reqs; struct iowait busy; unsigned state; + wait_queue_head_t wait; + struct mm_struct *user_mm; }; struct hfi1_user_sdma_comp_q { -- GitLab From faa98b862011a1ad92e66633220371fa3b799fc4 Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Tue, 8 Dec 2015 17:10:11 -0500 Subject: [PATCH 1854/2855] staging/rdma/hfi1: Clean-up unnecessary goto statements Clean-up unnecessary goto statements based on feedback from the mailing list on previous patch submissions. Reviewed-by: Ira Weiny Signed-off-by: Mitko Haralanov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/user_sdma.c | 37 ++++++++++----------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/drivers/staging/rdma/hfi1/user_sdma.c b/drivers/staging/rdma/hfi1/user_sdma.c index 55fe02ef37cbc..d03c810b62067 100644 --- a/drivers/staging/rdma/hfi1/user_sdma.c +++ b/drivers/staging/rdma/hfi1/user_sdma.c @@ -497,15 +497,13 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, "[%u:%u:%u] First vector not big enough for header %lu/%lu", dd->unit, uctxt->ctxt, fd->subctxt, iovec[idx].iov_len, sizeof(info) + sizeof(req->hdr)); - ret = -EINVAL; - goto done; + return -EINVAL; } ret = copy_from_user(&info, iovec[idx].iov_base, sizeof(info)); if (ret) { hfi1_cdbg(SDMA, "[%u:%u:%u] Failed to copy info QW (%d)", dd->unit, uctxt->ctxt, fd->subctxt, ret); - ret = -EFAULT; - goto done; + return -EFAULT; } trace_hfi1_sdma_user_reqinfo(dd, uctxt->ctxt, fd->subctxt, (u16 *)&info); @@ -513,15 +511,13 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, hfi1_cdbg(SDMA, "[%u:%u:%u] Entry %u is in QUEUED state", dd->unit, uctxt->ctxt, fd->subctxt, info.comp_idx); - ret = -EBADSLT; - goto done; + return -EBADSLT; } if (!info.fragsize) { hfi1_cdbg(SDMA, "[%u:%u:%u:%u] Request does not specify fragsize", dd->unit, uctxt->ctxt, fd->subctxt, info.comp_idx); - ret = -EINVAL; - goto done; + return -EINVAL; } /* * We've done all the safety checks that we can up to this point, @@ -550,8 +546,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, if (!info.npkts || req->data_iovs > MAX_VECTORS_PER_REQ) { SDMA_DBG(req, "Too many vectors (%u/%u)", req->data_iovs, MAX_VECTORS_PER_REQ); - ret = -EINVAL; - goto done; + return -EINVAL; } /* Copy the header from the user buffer */ ret = copy_from_user(&req->hdr, iovec[idx].iov_base + sizeof(info), @@ -774,10 +769,8 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts) struct hfi1_user_sdma_pkt_q *pq = NULL; struct user_sdma_iovec *iovec = NULL; - if (!req->pq) { - ret = -EINVAL; - goto done; - } + if (!req->pq) + return -EINVAL; pq = req->pq; @@ -787,7 +780,7 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts) if (unlikely(req->seqnum == req->info.npkts)) { if (!list_empty(&req->txps)) goto dosend; - goto done; + return ret; } if (!maxpkts || maxpkts > req->info.npkts - req->seqnum) @@ -804,15 +797,13 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts) */ if (test_bit(SDMA_REQ_HAS_ERROR, &req->flags)) { set_bit(SDMA_REQ_DONE_ERROR, &req->flags); - ret = -EFAULT; - goto done; + return -EFAULT; } tx = kmem_cache_alloc(pq->txreq_cache, GFP_KERNEL); - if (!tx) { - ret = -ENOMEM; - goto done; - } + if (!tx) + return -ENOMEM; + tx->flags = 0; tx->req = req; tx->busycount = 0; @@ -1013,12 +1004,12 @@ dosend: if (test_bit(SDMA_REQ_HAVE_AHG, &req->flags)) sdma_ahg_free(req->sde, req->ahg_idx); } - goto done; + return ret; + free_txreq: sdma_txclean(pq->dd, &tx->txreq); free_tx: kmem_cache_free(pq->txreq_cache, tx); -done: return ret; } -- GitLab From 6a5464f2248594bcf92bd05beb341650f9e0f357 Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Tue, 8 Dec 2015 17:10:12 -0500 Subject: [PATCH 1855/2855] staging/rdma/hfi1: Detect SDMA transmission error early It is possible for an SDMA transmission error to happen during the processing of an user SDMA transfer. In that case it is better to detect it early and abort any further attempts to send more packets. Reviewed-by: Ira Weiny Signed-off-by: Mitko Haralanov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/user_sdma.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/staging/rdma/hfi1/user_sdma.c b/drivers/staging/rdma/hfi1/user_sdma.c index d03c810b62067..d3de771a07708 100644 --- a/drivers/staging/rdma/hfi1/user_sdma.c +++ b/drivers/staging/rdma/hfi1/user_sdma.c @@ -774,6 +774,12 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts) pq = req->pq; + /* If tx completion has reported an error, we are done. */ + if (test_bit(SDMA_REQ_HAS_ERROR, &req->flags)) { + set_bit(SDMA_REQ_DONE_ERROR, &req->flags); + return -EFAULT; + } + /* * Check if we might have sent the entire request already */ -- GitLab From e607a2213a962d2ff7ca77f6a30e72096f0b9341 Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Thu, 3 Dec 2015 14:34:18 -0500 Subject: [PATCH 1856/2855] staging/rdma/hfi1: fix pio progress routine race with allocator The allocation code assumes that the shadow ring cannot be overrun because the credits will limit the allocation. Unfortuately, the progress mechanism in sc_release_update() updates the free count prior to processing the shadow ring, allowing the shadow ring to be overrun by an allocation. Reviewed-by: Mark Debbage Signed-off-by: Mike Marciniszyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/pio.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rdma/hfi1/pio.c b/drivers/staging/rdma/hfi1/pio.c index eab58c12d9159..8e10857d5b7da 100644 --- a/drivers/staging/rdma/hfi1/pio.c +++ b/drivers/staging/rdma/hfi1/pio.c @@ -1565,6 +1565,7 @@ void sc_release_update(struct send_context *sc) u64 hw_free; u32 head, tail; unsigned long old_free; + unsigned long free; unsigned long extra; unsigned long flags; int code; @@ -1579,7 +1580,7 @@ void sc_release_update(struct send_context *sc) extra = (((hw_free & CR_COUNTER_SMASK) >> CR_COUNTER_SHIFT) - (old_free & CR_COUNTER_MASK)) & CR_COUNTER_MASK; - sc->free = old_free + extra; + free = old_free + extra; trace_hfi1_piofree(sc, extra); /* call sent buffer callbacks */ @@ -1589,7 +1590,7 @@ void sc_release_update(struct send_context *sc) while (head != tail) { pbuf = &sc->sr[tail].pbuf; - if (sent_before(sc->free, pbuf->sent_at)) { + if (sent_before(free, pbuf->sent_at)) { /* not sent yet */ break; } @@ -1603,8 +1604,10 @@ void sc_release_update(struct send_context *sc) if (tail >= sc->sr_size) tail = 0; } - /* update tail, in case we moved it */ sc->sr_tail = tail; + /* make sure tail is updated before free */ + smp_wmb(); + sc->free = free; spin_unlock_irqrestore(&sc->release_lock, flags); sc_piobufavail(sc); } -- GitLab From a5a9e8ccab4d24c7d9e1da8222f373688745ca6a Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Thu, 3 Dec 2015 16:41:05 -0500 Subject: [PATCH 1857/2855] staging/rdma/hfi1: fix sdma build failures to always clean up There are holes in the sdma build support routines that do not clean any partially built sdma descriptors after mapping or allocate failures. This patch corrects these issues. Reviewed-by: Dennis Dalessandro Signed-off-by: Mike Marciniszyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/sdma.c | 10 ++++++---- drivers/staging/rdma/hfi1/sdma.h | 7 +++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rdma/hfi1/sdma.c b/drivers/staging/rdma/hfi1/sdma.c index 0710e2ab767c6..9a15f1f32b45d 100644 --- a/drivers/staging/rdma/hfi1/sdma.c +++ b/drivers/staging/rdma/hfi1/sdma.c @@ -2731,22 +2731,21 @@ static int _extend_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx) tx->coalesce_buf = kmalloc(tx->tlen + sizeof(u32), GFP_ATOMIC); if (!tx->coalesce_buf) - return -ENOMEM; - + goto enomem; tx->coalesce_idx = 0; } return 0; } if (unlikely(tx->num_desc == MAX_DESC)) - return -ENOMEM; + goto enomem; tx->descp = kmalloc_array( MAX_DESC, sizeof(struct sdma_desc), GFP_ATOMIC); if (!tx->descp) - return -ENOMEM; + goto enomem; /* reserve last descriptor for coalescing */ tx->desc_limit = MAX_DESC - 1; @@ -2754,6 +2753,9 @@ static int _extend_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx) for (i = 0; i < tx->num_desc; i++) tx->descp[i] = tx->descs[i]; return 0; +enomem: + sdma_txclean(dd, tx); + return -ENOMEM; } /* diff --git a/drivers/staging/rdma/hfi1/sdma.h b/drivers/staging/rdma/hfi1/sdma.h index 85701eed15858..da89e64581624 100644 --- a/drivers/staging/rdma/hfi1/sdma.h +++ b/drivers/staging/rdma/hfi1/sdma.h @@ -774,10 +774,13 @@ static inline int _sdma_txadd_daddr( tx->tlen -= len; /* special cases for last */ if (!tx->tlen) { - if (tx->packet_len & (sizeof(u32) - 1)) + if (tx->packet_len & (sizeof(u32) - 1)) { rval = _pad_sdma_tx_descs(dd, tx); - else + if (rval) + return rval; + } else { _sdma_close_tx(dd, tx); + } } tx->num_desc++; return rval; -- GitLab From a054374f15428cbc1d9cb9cba17ce870eaa7d60f Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Mon, 7 Dec 2015 15:39:22 -0500 Subject: [PATCH 1858/2855] staging/rdma/hfi1: convert buffers allocated atomic to per cpu Profiling has shown the the atomic is a performance issue for the pio hot path. If multiple cpus allocated an sc's buffer, the cacheline containing the atomic will bounce from L0 to L0. Convert the atomic to a percpu variable. Reviewed-by: Jubin John Signed-off-by: Mike Marciniszyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/pio.c | 40 ++++++++++++++++++++++++---- drivers/staging/rdma/hfi1/pio.h | 2 +- drivers/staging/rdma/hfi1/pio_copy.c | 6 +++-- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/drivers/staging/rdma/hfi1/pio.c b/drivers/staging/rdma/hfi1/pio.c index 8e10857d5b7da..b51a4416312b8 100644 --- a/drivers/staging/rdma/hfi1/pio.c +++ b/drivers/staging/rdma/hfi1/pio.c @@ -660,6 +660,24 @@ void set_pio_integrity(struct send_context *sc) write_kctxt_csr(dd, hw_context, SC(CHECK_ENABLE), reg); } +static u32 get_buffers_allocated(struct send_context *sc) +{ + int cpu; + u32 ret = 0; + + for_each_possible_cpu(cpu) + ret += *per_cpu_ptr(sc->buffers_allocated, cpu); + return ret; +} + +static void reset_buffers_allocated(struct send_context *sc) +{ + int cpu; + + for_each_possible_cpu(cpu) + (*per_cpu_ptr(sc->buffers_allocated, cpu)) = 0; +} + /* * Allocate a NUMA relative send context structure of the given type along * with a HW context. @@ -668,7 +686,7 @@ struct send_context *sc_alloc(struct hfi1_devdata *dd, int type, uint hdrqentsize, int numa) { struct send_context_info *sci; - struct send_context *sc; + struct send_context *sc = NULL; dma_addr_t pa; unsigned long flags; u64 reg; @@ -686,10 +704,20 @@ struct send_context *sc_alloc(struct hfi1_devdata *dd, int type, if (!sc) return NULL; + sc->buffers_allocated = alloc_percpu(u32); + if (!sc->buffers_allocated) { + kfree(sc); + dd_dev_err(dd, + "Cannot allocate buffers_allocated per cpu counters\n" + ); + return NULL; + } + spin_lock_irqsave(&dd->sc_lock, flags); ret = sc_hw_alloc(dd, type, &sw_index, &hw_context); if (ret) { spin_unlock_irqrestore(&dd->sc_lock, flags); + free_percpu(sc->buffers_allocated); kfree(sc); return NULL; } @@ -705,7 +733,6 @@ struct send_context *sc_alloc(struct hfi1_devdata *dd, int type, spin_lock_init(&sc->credit_ctrl_lock); INIT_LIST_HEAD(&sc->piowait); INIT_WORK(&sc->halt_work, sc_halted); - atomic_set(&sc->buffers_allocated, 0); init_waitqueue_head(&sc->halt_wait); /* grouping is always single context for now */ @@ -866,6 +893,7 @@ void sc_free(struct send_context *sc) spin_unlock_irqrestore(&dd->sc_lock, flags); kfree(sc->sr); + free_percpu(sc->buffers_allocated); kfree(sc); } @@ -1029,7 +1057,7 @@ int sc_restart(struct send_context *sc) /* kernel context */ loop = 0; while (1) { - count = atomic_read(&sc->buffers_allocated); + count = get_buffers_allocated(sc); if (count == 0) break; if (loop > 100) { @@ -1197,7 +1225,8 @@ int sc_enable(struct send_context *sc) sc->sr_head = 0; sc->sr_tail = 0; sc->flags = 0; - atomic_set(&sc->buffers_allocated, 0); + /* the alloc lock insures no fast path allocation */ + reset_buffers_allocated(sc); /* * Clear all per-context errors. Some of these will be set when @@ -1373,7 +1402,8 @@ retry: /* there is enough room */ - atomic_inc(&sc->buffers_allocated); + preempt_disable(); + this_cpu_inc(*sc->buffers_allocated); /* read this once */ head = sc->sr_head; diff --git a/drivers/staging/rdma/hfi1/pio.h b/drivers/staging/rdma/hfi1/pio.h index 0bb885ca3cfb9..53d3e0a793757 100644 --- a/drivers/staging/rdma/hfi1/pio.h +++ b/drivers/staging/rdma/hfi1/pio.h @@ -130,7 +130,7 @@ struct send_context { spinlock_t credit_ctrl_lock ____cacheline_aligned_in_smp; u64 credit_ctrl; /* cache for credit control */ u32 credit_intr_count; /* count of credit intr users */ - atomic_t buffers_allocated; /* count of buffers allocated */ + u32 __percpu *buffers_allocated;/* count of buffers allocated */ wait_queue_head_t halt_wait; /* wait until kernel sees interrupt */ }; diff --git a/drivers/staging/rdma/hfi1/pio_copy.c b/drivers/staging/rdma/hfi1/pio_copy.c index 8972bbc020385..ebb0bafc68cb0 100644 --- a/drivers/staging/rdma/hfi1/pio_copy.c +++ b/drivers/staging/rdma/hfi1/pio_copy.c @@ -160,7 +160,8 @@ void pio_copy(struct hfi1_devdata *dd, struct pio_buf *pbuf, u64 pbc, } /* finished with this buffer */ - atomic_dec(&pbuf->sc->buffers_allocated); + this_cpu_dec(*pbuf->sc->buffers_allocated); + preempt_enable(); } /* USE_SHIFTS is faster in user-space tests on a Xeon X5570 @ 2.93GHz */ @@ -854,5 +855,6 @@ void seg_pio_copy_end(struct pio_buf *pbuf) } /* finished with this buffer */ - atomic_dec(&pbuf->sc->buffers_allocated); + this_cpu_dec(*pbuf->sc->buffers_allocated); + preempt_enable(); } -- GitLab From 7438370a5150d6090957ab3e461d5b3a31f2181a Mon Sep 17 00:00:00 2001 From: Yash Shah Date: Tue, 8 Dec 2015 10:24:17 +0000 Subject: [PATCH 1859/2855] Staging: rdma:Delete unnecessary NULL check before calling function "kmem_cache_destroy" The kmem_cache_destroy() function tests whether its argument is NULL and then returns immediately. Thus the NULL check before calling this function is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Yash Shah Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/ehca/ehca_av.c | 3 +-- drivers/staging/rdma/ehca/ehca_cq.c | 3 +-- drivers/staging/rdma/ehca/ehca_main.c | 3 +-- drivers/staging/rdma/ehca/ehca_mrmw.c | 6 ++---- drivers/staging/rdma/ehca/ehca_pd.c | 3 +-- drivers/staging/rdma/ehca/ehca_qp.c | 3 +-- 6 files changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/staging/rdma/ehca/ehca_av.c b/drivers/staging/rdma/ehca/ehca_av.c index fd7b6d044ec10..94e088c2d989a 100644 --- a/drivers/staging/rdma/ehca/ehca_av.c +++ b/drivers/staging/rdma/ehca/ehca_av.c @@ -275,6 +275,5 @@ int ehca_init_av_cache(void) void ehca_cleanup_av_cache(void) { - if (av_cache) - kmem_cache_destroy(av_cache); + kmem_cache_destroy(av_cache); } diff --git a/drivers/staging/rdma/ehca/ehca_cq.c b/drivers/staging/rdma/ehca/ehca_cq.c index ea1b5c1203b4e..1aa7931fe860f 100644 --- a/drivers/staging/rdma/ehca/ehca_cq.c +++ b/drivers/staging/rdma/ehca/ehca_cq.c @@ -393,6 +393,5 @@ int ehca_init_cq_cache(void) void ehca_cleanup_cq_cache(void) { - if (cq_cache) - kmem_cache_destroy(cq_cache); + kmem_cache_destroy(cq_cache); } diff --git a/drivers/staging/rdma/ehca/ehca_main.c b/drivers/staging/rdma/ehca/ehca_main.c index 8246418cd4e08..860b974e9faab 100644 --- a/drivers/staging/rdma/ehca/ehca_main.c +++ b/drivers/staging/rdma/ehca/ehca_main.c @@ -245,8 +245,7 @@ static void ehca_destroy_slab_caches(void) ehca_cleanup_cq_cache(); ehca_cleanup_pd_cache(); #ifdef CONFIG_PPC_64K_PAGES - if (ctblk_cache) - kmem_cache_destroy(ctblk_cache); + kmem_cache_destroy(ctblk_cache); #endif } diff --git a/drivers/staging/rdma/ehca/ehca_mrmw.c b/drivers/staging/rdma/ehca/ehca_mrmw.c index f914b30999f8d..553e883a5718e 100644 --- a/drivers/staging/rdma/ehca/ehca_mrmw.c +++ b/drivers/staging/rdma/ehca/ehca_mrmw.c @@ -2251,10 +2251,8 @@ int ehca_init_mrmw_cache(void) void ehca_cleanup_mrmw_cache(void) { - if (mr_cache) - kmem_cache_destroy(mr_cache); - if (mw_cache) - kmem_cache_destroy(mw_cache); + kmem_cache_destroy(mr_cache); + kmem_cache_destroy(mw_cache); } static inline int ehca_init_top_bmap(struct ehca_top_bmap *ehca_top_bmap, diff --git a/drivers/staging/rdma/ehca/ehca_pd.c b/drivers/staging/rdma/ehca/ehca_pd.c index 351577a6670a5..2a8aae411941f 100644 --- a/drivers/staging/rdma/ehca/ehca_pd.c +++ b/drivers/staging/rdma/ehca/ehca_pd.c @@ -119,6 +119,5 @@ int ehca_init_pd_cache(void) void ehca_cleanup_pd_cache(void) { - if (pd_cache) - kmem_cache_destroy(pd_cache); + kmem_cache_destroy(pd_cache); } diff --git a/drivers/staging/rdma/ehca/ehca_qp.c b/drivers/staging/rdma/ehca/ehca_qp.c index 2e89356c46faf..896c01f810f6f 100644 --- a/drivers/staging/rdma/ehca/ehca_qp.c +++ b/drivers/staging/rdma/ehca/ehca_qp.c @@ -2252,6 +2252,5 @@ int ehca_init_qp_cache(void) void ehca_cleanup_qp_cache(void) { - if (qp_cache) - kmem_cache_destroy(qp_cache); + kmem_cache_destroy(qp_cache); } -- GitLab From 71a1d624f97acbf2dea889c5c5d8c59b3afc2526 Mon Sep 17 00:00:00 2001 From: Jubin John Date: Thu, 10 Dec 2015 09:59:34 -0500 Subject: [PATCH 1860/2855] staging/rdma/hfi1: add definitions for OPA traps These new definitions will be used by follow-on patches for formating and sending OPA traps. Reviewed-by: Ira Weiny Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/mad.h | 114 ++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/drivers/staging/rdma/hfi1/mad.h b/drivers/staging/rdma/hfi1/mad.h index 47457501c0440..f0317750e2fc9 100644 --- a/drivers/staging/rdma/hfi1/mad.h +++ b/drivers/staging/rdma/hfi1/mad.h @@ -60,7 +60,121 @@ #endif #include "opa_compat.h" +/* + * OPA Traps + */ +#define OPA_TRAP_GID_NOW_IN_SERVICE cpu_to_be16(64) +#define OPA_TRAP_GID_OUT_OF_SERVICE cpu_to_be16(65) +#define OPA_TRAP_ADD_MULTICAST_GROUP cpu_to_be16(66) +#define OPA_TRAL_DEL_MULTICAST_GROUP cpu_to_be16(67) +#define OPA_TRAP_UNPATH cpu_to_be16(68) +#define OPA_TRAP_REPATH cpu_to_be16(69) +#define OPA_TRAP_PORT_CHANGE_STATE cpu_to_be16(128) +#define OPA_TRAP_LINK_INTEGRITY cpu_to_be16(129) +#define OPA_TRAP_EXCESSIVE_BUFFER_OVERRUN cpu_to_be16(130) +#define OPA_TRAP_FLOW_WATCHDOG cpu_to_be16(131) +#define OPA_TRAP_CHANGE_CAPABILITY cpu_to_be16(144) +#define OPA_TRAP_CHANGE_SYSGUID cpu_to_be16(145) +#define OPA_TRAP_BAD_M_KEY cpu_to_be16(256) +#define OPA_TRAP_BAD_P_KEY cpu_to_be16(257) +#define OPA_TRAP_BAD_Q_KEY cpu_to_be16(258) +#define OPA_TRAP_SWITCH_BAD_PKEY cpu_to_be16(259) +#define OPA_SMA_TRAP_DATA_LINK_WIDTH cpu_to_be16(2048) +/* + * Generic trap/notice other local changes flags (trap 144). + */ +#define OPA_NOTICE_TRAP_LWDE_CHG 0x08 /* Link Width Downgrade Enable + * changed + */ +#define OPA_NOTICE_TRAP_LSE_CHG 0x04 /* Link Speed Enable changed */ +#define OPA_NOTICE_TRAP_LWE_CHG 0x02 /* Link Width Enable changed */ +#define OPA_NOTICE_TRAP_NODE_DESC_CHG 0x01 + +struct opa_mad_notice_attr { + u8 generic_type; + u8 prod_type_msb; + __be16 prod_type_lsb; + __be16 trap_num; + __be16 toggle_count; + __be32 issuer_lid; + __be32 reserved1; + union ib_gid issuer_gid; + + union { + struct { + u8 details[64]; + } raw_data; + + struct { + union ib_gid gid; + } __packed ntc_64_65_66_67; + + struct { + __be32 lid; + } __packed ntc_128; + + struct { + __be32 lid; /* where violation happened */ + u8 port_num; /* where violation happened */ + } __packed ntc_129_130_131; + + struct { + __be32 lid; /* LID where change occurred */ + __be32 new_cap_mask; /* new capability mask */ + __be16 reserved2; + __be16 cap_mask; + __be16 change_flags; /* low 4 bits only */ + } __packed ntc_144; + + struct { + __be64 new_sys_guid; + __be32 lid; /* lid where sys guid changed */ + } __packed ntc_145; + + struct { + __be32 lid; + __be32 dr_slid; + u8 method; + u8 dr_trunc_hop; + __be16 attr_id; + __be32 attr_mod; + __be64 mkey; + u8 dr_rtn_path[30]; + } __packed ntc_256; + + struct { + __be32 lid1; + __be32 lid2; + __be32 key; + u8 sl; /* SL: high 5 bits */ + u8 reserved3[3]; + union ib_gid gid1; + union ib_gid gid2; + __be32 qp1; /* high 8 bits reserved */ + __be32 qp2; /* high 8 bits reserved */ + } __packed ntc_257_258; + + struct { + __be16 flags; /* low 8 bits reserved */ + __be16 pkey; + __be32 lid1; + __be32 lid2; + u8 sl; /* SL: high 5 bits */ + u8 reserved4[3]; + union ib_gid gid1; + union ib_gid gid2; + __be32 qp1; /* high 8 bits reserved */ + __be32 qp2; /* high 8 bits reserved */ + } __packed ntc_259; + + struct { + __be32 lid; + } __packed ntc_2048; + + }; + u8 class_data[0]; +}; #define IB_VLARB_LOWPRI_0_31 1 #define IB_VLARB_LOWPRI_32_63 2 -- GitLab From 5cd24119d437910d15c510218dcd32f57355a3d3 Mon Sep 17 00:00:00 2001 From: "Erik E. Kahn" Date: Thu, 10 Dec 2015 09:59:40 -0500 Subject: [PATCH 1861/2855] staging/rdma/hfi1: HFI now sends OPA Traps instead of IBTA send_trap() was still using old ib_smp instead of opa_smp for formatting and sending traps. Reviewed-by: Arthur Kepner Reviewed-by: Ira Weiny Reviewed-by: Dennis Dalessandro Signed-off-by: Jubin John Signed-off-by: Erik E. Kahn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/mad.c | 121 +++++++++++++++--------------- drivers/staging/rdma/hfi1/ruc.c | 10 ++- drivers/staging/rdma/hfi1/ud.c | 21 +++--- drivers/staging/rdma/hfi1/verbs.h | 2 +- 4 files changed, 79 insertions(+), 75 deletions(-) diff --git a/drivers/staging/rdma/hfi1/mad.c b/drivers/staging/rdma/hfi1/mad.c index a785664371d03..4f5dbd14b5de8 100644 --- a/drivers/staging/rdma/hfi1/mad.c +++ b/drivers/staging/rdma/hfi1/mad.c @@ -84,7 +84,7 @@ static void send_trap(struct hfi1_ibport *ibp, void *data, unsigned len) { struct ib_mad_send_buf *send_buf; struct ib_mad_agent *agent; - struct ib_smp *smp; + struct opa_smp *smp; int ret; unsigned long flags; unsigned long timeout; @@ -117,15 +117,15 @@ static void send_trap(struct hfi1_ibport *ibp, void *data, unsigned len) return; smp = send_buf->mad; - smp->base_version = IB_MGMT_BASE_VERSION; + smp->base_version = OPA_MGMT_BASE_VERSION; smp->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; - smp->class_version = 1; + smp->class_version = OPA_SMI_CLASS_VERSION; smp->method = IB_MGMT_METHOD_TRAP; ibp->tid++; smp->tid = cpu_to_be64(ibp->tid); smp->attr_id = IB_SMP_ATTR_NOTICE; /* o14-1: smp->mkey = 0; */ - memcpy(smp->data, data, len); + memcpy(smp->route.lid.data, data, len); spin_lock_irqsave(&ibp->lock, flags); if (!ibp->sm_ah) { @@ -164,11 +164,16 @@ static void send_trap(struct hfi1_ibport *ibp, void *data, unsigned len) * Send a bad [PQ]_Key trap (ch. 14.3.8). */ void hfi1_bad_pqkey(struct hfi1_ibport *ibp, __be16 trap_num, u32 key, u32 sl, - u32 qp1, u32 qp2, __be16 lid1, __be16 lid2) + u32 qp1, u32 qp2, u16 lid1, u16 lid2) { - struct ib_mad_notice_attr data; + struct opa_mad_notice_attr data; + u32 lid = ppd_from_ibp(ibp)->lid; + u32 _lid1 = lid1; + u32 _lid2 = lid2; - if (trap_num == IB_NOTICE_TRAP_BAD_PKEY) + memset(&data, 0, sizeof(data)); + + if (trap_num == OPA_TRAP_BAD_P_KEY) ibp->pkey_violations++; else ibp->qkey_violations++; @@ -176,17 +181,15 @@ void hfi1_bad_pqkey(struct hfi1_ibport *ibp, __be16 trap_num, u32 key, u32 sl, /* Send violation trap */ data.generic_type = IB_NOTICE_TYPE_SECURITY; - data.prod_type_msb = 0; data.prod_type_lsb = IB_NOTICE_PROD_CA; data.trap_num = trap_num; - data.issuer_lid = cpu_to_be16(ppd_from_ibp(ibp)->lid); - data.toggle_count = 0; - memset(&data.details, 0, sizeof(data.details)); - data.details.ntc_257_258.lid1 = lid1; - data.details.ntc_257_258.lid2 = lid2; - data.details.ntc_257_258.key = cpu_to_be32(key); - data.details.ntc_257_258.sl_qp1 = cpu_to_be32((sl << 28) | qp1); - data.details.ntc_257_258.qp2 = cpu_to_be32(qp2); + data.issuer_lid = cpu_to_be32(lid); + data.ntc_257_258.lid1 = cpu_to_be32(_lid1); + data.ntc_257_258.lid2 = cpu_to_be32(_lid2); + data.ntc_257_258.key = cpu_to_be32(key); + data.ntc_257_258.sl = sl << 3; + data.ntc_257_258.qp1 = cpu_to_be32(qp1); + data.ntc_257_258.qp2 = cpu_to_be32(qp2); send_trap(ibp, &data, sizeof(data)); } @@ -197,32 +200,30 @@ void hfi1_bad_pqkey(struct hfi1_ibport *ibp, __be16 trap_num, u32 key, u32 sl, static void bad_mkey(struct hfi1_ibport *ibp, struct ib_mad_hdr *mad, __be64 mkey, __be32 dr_slid, u8 return_path[], u8 hop_cnt) { - struct ib_mad_notice_attr data; + struct opa_mad_notice_attr data; + u32 lid = ppd_from_ibp(ibp)->lid; + memset(&data, 0, sizeof(data)); /* Send violation trap */ data.generic_type = IB_NOTICE_TYPE_SECURITY; - data.prod_type_msb = 0; data.prod_type_lsb = IB_NOTICE_PROD_CA; - data.trap_num = IB_NOTICE_TRAP_BAD_MKEY; - data.issuer_lid = cpu_to_be16(ppd_from_ibp(ibp)->lid); - data.toggle_count = 0; - memset(&data.details, 0, sizeof(data.details)); - data.details.ntc_256.lid = data.issuer_lid; - data.details.ntc_256.method = mad->method; - data.details.ntc_256.attr_id = mad->attr_id; - data.details.ntc_256.attr_mod = mad->attr_mod; - data.details.ntc_256.mkey = mkey; + data.trap_num = OPA_TRAP_BAD_M_KEY; + data.issuer_lid = cpu_to_be32(lid); + data.ntc_256.lid = data.issuer_lid; + data.ntc_256.method = mad->method; + data.ntc_256.attr_id = mad->attr_id; + data.ntc_256.attr_mod = mad->attr_mod; + data.ntc_256.mkey = mkey; if (mad->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) { - - data.details.ntc_256.dr_slid = (__force __be16)dr_slid; - data.details.ntc_256.dr_trunc_hop = IB_NOTICE_TRAP_DR_NOTICE; - if (hop_cnt > ARRAY_SIZE(data.details.ntc_256.dr_rtn_path)) { - data.details.ntc_256.dr_trunc_hop |= + data.ntc_256.dr_slid = dr_slid; + data.ntc_256.dr_trunc_hop = IB_NOTICE_TRAP_DR_NOTICE; + if (hop_cnt > ARRAY_SIZE(data.ntc_256.dr_rtn_path)) { + data.ntc_256.dr_trunc_hop |= IB_NOTICE_TRAP_DR_TRUNC; - hop_cnt = ARRAY_SIZE(data.details.ntc_256.dr_rtn_path); + hop_cnt = ARRAY_SIZE(data.ntc_256.dr_rtn_path); } - data.details.ntc_256.dr_trunc_hop |= hop_cnt; - memcpy(data.details.ntc_256.dr_rtn_path, return_path, + data.ntc_256.dr_trunc_hop |= hop_cnt; + memcpy(data.ntc_256.dr_rtn_path, return_path, hop_cnt); } @@ -234,17 +235,17 @@ static void bad_mkey(struct hfi1_ibport *ibp, struct ib_mad_hdr *mad, */ void hfi1_cap_mask_chg(struct hfi1_ibport *ibp) { - struct ib_mad_notice_attr data; + struct opa_mad_notice_attr data; + u32 lid = ppd_from_ibp(ibp)->lid; + + memset(&data, 0, sizeof(data)); data.generic_type = IB_NOTICE_TYPE_INFO; - data.prod_type_msb = 0; data.prod_type_lsb = IB_NOTICE_PROD_CA; - data.trap_num = IB_NOTICE_TRAP_CAP_MASK_CHG; - data.issuer_lid = cpu_to_be16(ppd_from_ibp(ibp)->lid); - data.toggle_count = 0; - memset(&data.details, 0, sizeof(data.details)); - data.details.ntc_144.lid = data.issuer_lid; - data.details.ntc_144.new_cap_mask = cpu_to_be32(ibp->port_cap_flags); + data.trap_num = OPA_TRAP_CHANGE_CAPABILITY; + data.issuer_lid = cpu_to_be32(lid); + data.ntc_144.lid = data.issuer_lid; + data.ntc_144.new_cap_mask = cpu_to_be32(ibp->port_cap_flags); send_trap(ibp, &data, sizeof(data)); } @@ -254,17 +255,17 @@ void hfi1_cap_mask_chg(struct hfi1_ibport *ibp) */ void hfi1_sys_guid_chg(struct hfi1_ibport *ibp) { - struct ib_mad_notice_attr data; + struct opa_mad_notice_attr data; + u32 lid = ppd_from_ibp(ibp)->lid; + + memset(&data, 0, sizeof(data)); data.generic_type = IB_NOTICE_TYPE_INFO; - data.prod_type_msb = 0; data.prod_type_lsb = IB_NOTICE_PROD_CA; - data.trap_num = IB_NOTICE_TRAP_SYS_GUID_CHG; - data.issuer_lid = cpu_to_be16(ppd_from_ibp(ibp)->lid); - data.toggle_count = 0; - memset(&data.details, 0, sizeof(data.details)); - data.details.ntc_145.lid = data.issuer_lid; - data.details.ntc_145.new_sys_guid = ib_hfi1_sys_image_guid; + data.trap_num = OPA_TRAP_CHANGE_SYSGUID; + data.issuer_lid = cpu_to_be32(lid); + data.ntc_145.new_sys_guid = ib_hfi1_sys_image_guid; + data.ntc_145.lid = data.issuer_lid; send_trap(ibp, &data, sizeof(data)); } @@ -274,18 +275,18 @@ void hfi1_sys_guid_chg(struct hfi1_ibport *ibp) */ void hfi1_node_desc_chg(struct hfi1_ibport *ibp) { - struct ib_mad_notice_attr data; + struct opa_mad_notice_attr data; + u32 lid = ppd_from_ibp(ibp)->lid; + + memset(&data, 0, sizeof(data)); data.generic_type = IB_NOTICE_TYPE_INFO; - data.prod_type_msb = 0; data.prod_type_lsb = IB_NOTICE_PROD_CA; - data.trap_num = IB_NOTICE_TRAP_CAP_MASK_CHG; - data.issuer_lid = cpu_to_be16(ppd_from_ibp(ibp)->lid); - data.toggle_count = 0; - memset(&data.details, 0, sizeof(data.details)); - data.details.ntc_144.lid = data.issuer_lid; - data.details.ntc_144.local_changes = 1; - data.details.ntc_144.change_flags = IB_NOTICE_TRAP_NODE_DESC_CHG; + data.trap_num = OPA_TRAP_CHANGE_CAPABILITY; + data.issuer_lid = cpu_to_be32(lid); + data.ntc_144.lid = data.issuer_lid; + data.ntc_144.change_flags = + cpu_to_be16(OPA_NOTICE_TRAP_NODE_DESC_CHG); send_trap(ibp, &data, sizeof(data)); } diff --git a/drivers/staging/rdma/hfi1/ruc.c b/drivers/staging/rdma/hfi1/ruc.c index 317bf6ff46a86..4a91975b68d7e 100644 --- a/drivers/staging/rdma/hfi1/ruc.c +++ b/drivers/staging/rdma/hfi1/ruc.c @@ -288,11 +288,12 @@ int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct hfi1_ib_header *hdr, } if (unlikely(rcv_pkey_check(ppd_from_ibp(ibp), (u16)bth0, sc5, be16_to_cpu(hdr->lrh[3])))) { - hfi1_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY, + hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_P_KEY, (u16)bth0, (be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF, 0, qp->ibqp.qp_num, - hdr->lrh[3], hdr->lrh[1]); + be16_to_cpu(hdr->lrh[3]), + be16_to_cpu(hdr->lrh[1])); goto err; } /* Validate the SLID. See Ch. 9.6.1.5 and 17.2.8 */ @@ -320,11 +321,12 @@ int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct hfi1_ib_header *hdr, } if (unlikely(rcv_pkey_check(ppd_from_ibp(ibp), (u16)bth0, sc5, be16_to_cpu(hdr->lrh[3])))) { - hfi1_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY, + hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_P_KEY, (u16)bth0, (be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF, 0, qp->ibqp.qp_num, - hdr->lrh[3], hdr->lrh[1]); + be16_to_cpu(hdr->lrh[3]), + be16_to_cpu(hdr->lrh[1])); goto err; } /* Validate the SLID. See Ch. 9.6.1.5 */ diff --git a/drivers/staging/rdma/hfi1/ud.c b/drivers/staging/rdma/hfi1/ud.c index 54ff1f5416d49..bd1b402c1e149 100644 --- a/drivers/staging/rdma/hfi1/ud.c +++ b/drivers/staging/rdma/hfi1/ud.c @@ -111,11 +111,10 @@ static void ud_loopback(struct hfi1_qp *sqp, struct hfi1_swqe *swqe) ((1 << ppd->lmc) - 1)); if (unlikely(ingress_pkey_check(ppd, pkey, sc5, qp->s_pkey_index, slid))) { - hfi1_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY, pkey, + hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_P_KEY, pkey, ah_attr->sl, sqp->ibqp.qp_num, qp->ibqp.qp_num, - cpu_to_be16(slid), - cpu_to_be16(ah_attr->dlid)); + slid, ah_attr->dlid); goto drop; } } @@ -135,11 +134,11 @@ static void ud_loopback(struct hfi1_qp *sqp, struct hfi1_swqe *swqe) lid = ppd->lid | (ah_attr->src_path_bits & ((1 << ppd->lmc) - 1)); - hfi1_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_QKEY, qkey, + hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_Q_KEY, qkey, ah_attr->sl, sqp->ibqp.qp_num, qp->ibqp.qp_num, - cpu_to_be16(lid), - cpu_to_be16(ah_attr->dlid)); + lid, + ah_attr->dlid); goto drop; } } @@ -737,12 +736,13 @@ void hfi1_ud_rcv(struct hfi1_packet *packet) * for invalid pkeys is optional according to * IB spec (release 1.3, section 10.9.4) */ - hfi1_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY, + hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_P_KEY, pkey, (be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF, src_qp, qp->ibqp.qp_num, - hdr->lrh[3], hdr->lrh[1]); + be16_to_cpu(hdr->lrh[3]), + be16_to_cpu(hdr->lrh[1])); return; } } else { @@ -753,10 +753,11 @@ void hfi1_ud_rcv(struct hfi1_packet *packet) } if (unlikely(qkey != qp->qkey)) { - hfi1_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_QKEY, qkey, + hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_Q_KEY, qkey, (be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF, src_qp, qp->ibqp.qp_num, - hdr->lrh[3], hdr->lrh[1]); + be16_to_cpu(hdr->lrh[3]), + be16_to_cpu(hdr->lrh[1])); return; } /* Drop invalid MAD packets (see 13.5.3.1). */ diff --git a/drivers/staging/rdma/hfi1/verbs.h b/drivers/staging/rdma/hfi1/verbs.h index 7e27531c430a3..72106e5362b98 100644 --- a/drivers/staging/rdma/hfi1/verbs.h +++ b/drivers/staging/rdma/hfi1/verbs.h @@ -861,7 +861,7 @@ static inline int hfi1_send_ok(struct hfi1_qp *qp) * This must be called with s_lock held. */ void hfi1_bad_pqkey(struct hfi1_ibport *ibp, __be16 trap_num, u32 key, u32 sl, - u32 qp1, u32 qp2, __be16 lid1, __be16 lid2); + u32 qp1, u32 qp2, u16 lid1, u16 lid2); void hfi1_cap_mask_chg(struct hfi1_ibport *ibp); void hfi1_sys_guid_chg(struct hfi1_ibport *ibp); void hfi1_node_desc_chg(struct hfi1_ibport *ibp); -- GitLab From 859bcad9c2c5487dd74d4cfbdcbdd6c63a0ca955 Mon Sep 17 00:00:00 2001 From: Easwar Hariharan Date: Thu, 10 Dec 2015 11:13:38 -0500 Subject: [PATCH 1862/2855] staging/rdma/hfi1: Fix a possible null pointer dereference A code inspection pointed out that kmalloc_array may return NULL and memset doesn't check the input pointer for NULL, resulting in a possible NULL dereference. This patch fixes this. Reviewed-by: Mike Marciniszyn Signed-off-by: Easwar Hariharan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index d88945a802506..371f13fec68da 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -13358,6 +13358,8 @@ static void init_qos(struct hfi1_devdata *dd, u32 first_ctxt) if (num_vls * qpns_per_vl > dd->chip_rcv_contexts) goto bail; rsmmap = kmalloc_array(NUM_MAP_REGS, sizeof(u64), GFP_KERNEL); + if (!rsmmap) + goto bail; memset(rsmmap, rxcontext, NUM_MAP_REGS * sizeof(u64)); /* init the local copy of the table */ for (i = 0, ctxt = first_ctxt; i < num_vls; i++) { -- GitLab From 07859def5de0d909334a2e45e5e428f393e8cc9e Mon Sep 17 00:00:00 2001 From: Sebastian Sanchez Date: Thu, 10 Dec 2015 16:02:49 -0500 Subject: [PATCH 1863/2855] staging/rdma/hfi1: Fix for module parameter hdrq_entsize when it's 0 If driver is loaded with parameter hdrq_entsize=0, then there's a NULL dereference when the driver gets unloaded. This causes a kernel Oops and prevents the module from being unloaded. This patch fixes this issue by making sure -EINVAL gets returned when hdrq_entsize=0. Reviewed-by: Chegondi, Harish Reviewed-by: Haralanov, Mitko Signed-off-by: Sebastian Sanchez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/rdma/hfi1/init.c b/drivers/staging/rdma/hfi1/init.c index 2d52f91c03dc3..467ff26bcab0e 100644 --- a/drivers/staging/rdma/hfi1/init.c +++ b/drivers/staging/rdma/hfi1/init.c @@ -1351,6 +1351,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (!encode_rcv_header_entry_size(hfi1_hdrq_entsize)) { hfi1_early_err(&pdev->dev, "Invalid HdrQ Entry size %u\n", hfi1_hdrq_entsize); + ret = -EINVAL; goto bail; } -- GitLab From 2ce6bf2292742e0a4e71f08717ce314ce6332151 Mon Sep 17 00:00:00 2001 From: Sebastian Sanchez Date: Fri, 11 Dec 2015 08:44:48 -0500 Subject: [PATCH 1864/2855] staging/rdma/hfi1: Change num_rcv_contexts to num_user_contexts and its meaning num_rcv_contexts sets the number of user contexts, both receive and send. Renaming it to num_user_contexts makes sense to reflect its true meaning. When num_rcv_contexts is 0, the default behavior is the number of CPU cores instead of 0 contexts. This commit changes the variable num_rcv_contexts to num_user_contexts, and it also makes any negative value for this variable default to the number of CPU cores, so if num_user_contexts is set >= 0, the value will number of contexts. Reviewed-by: Mike Marciniszyn Signed-off-by: Sebastian Sanchez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 9 +++------ drivers/staging/rdma/hfi1/hfi.h | 2 +- drivers/staging/rdma/hfi1/init.c | 6 +++--- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index 371f13fec68da..ec4bac00dbdad 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -12426,7 +12426,6 @@ fail: static int set_up_context_variables(struct hfi1_devdata *dd) { int num_kernel_contexts; - int num_user_contexts; int total_contexts; int ret; unsigned ngroups; @@ -12463,12 +12462,10 @@ static int set_up_context_variables(struct hfi1_devdata *dd) } /* * User contexts: (to be fixed later) - * - set to num_rcv_contexts if non-zero - * - default to 1 user context per CPU + * - default to 1 user context per CPU if num_user_contexts is + * negative */ - if (num_rcv_contexts) - num_user_contexts = num_rcv_contexts; - else + if (num_user_contexts < 0) num_user_contexts = num_online_cpus(); total_contexts = num_kernel_contexts + num_user_contexts; diff --git a/drivers/staging/rdma/hfi1/hfi.h b/drivers/staging/rdma/hfi1/hfi.h index 7aea874b3dfce..2611bb2e764d8 100644 --- a/drivers/staging/rdma/hfi1/hfi.h +++ b/drivers/staging/rdma/hfi1/hfi.h @@ -1665,7 +1665,7 @@ void update_sge(struct hfi1_sge_state *ss, u32 length); extern unsigned int hfi1_max_mtu; extern unsigned int hfi1_cu; extern unsigned int user_credit_return_threshold; -extern uint num_rcv_contexts; +extern int num_user_contexts; extern unsigned n_krcvqs; extern u8 krcvqs[]; extern int krcvqsset; diff --git a/drivers/staging/rdma/hfi1/init.c b/drivers/staging/rdma/hfi1/init.c index 467ff26bcab0e..7ad9eb1825142 100644 --- a/drivers/staging/rdma/hfi1/init.c +++ b/drivers/staging/rdma/hfi1/init.c @@ -82,10 +82,10 @@ * Number of user receive contexts we are configured to use (to allow for more * pio buffers per ctxt, etc.) Zero means use one user context per CPU. */ -uint num_rcv_contexts; -module_param_named(num_rcv_contexts, num_rcv_contexts, uint, S_IRUGO); +int num_user_contexts = -1; +module_param_named(num_user_contexts, num_user_contexts, uint, S_IRUGO); MODULE_PARM_DESC( - num_rcv_contexts, "Set max number of user receive contexts to use"); + num_user_contexts, "Set max number of user contexts to use"); u8 krcvqs[RXE_NUM_DATA_VL]; int krcvqsset; -- GitLab From bff14bb66c583376ff8c5dd6294796f6fc3c1dde Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Thu, 17 Dec 2015 19:24:13 -0500 Subject: [PATCH 1865/2855] staging/rdma/hfi1: Remove incorrect link credit check Remove an invalid sanity check that compares the local link credits with the peer link credits. The two have no dependency on each other. Reviewed-by: Dennis Dalessandro Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/chip.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c index ec4bac00dbdad..bbe5ad85cec07 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/staging/rdma/hfi1/chip.c @@ -10496,8 +10496,7 @@ static int set_buffer_control(struct hfi1_devdata *dd, new_bc->vl[i].shared = 0; } new_total += be16_to_cpu(new_bc->overall_shared_limit); - if (new_total > (u32)dd->link_credits) - return -EINVAL; + /* fetch the current values */ get_buffer_control(dd, &cur_bc, &cur_total); -- GitLab From ecb95a027b94a99c3c0fc255c55dd9be6e404ae0 Mon Sep 17 00:00:00 2001 From: Jubin John Date: Thu, 17 Dec 2015 19:24:14 -0500 Subject: [PATCH 1866/2855] staging/rdma/hfi1: Fix module parameter spelling Fix the spelling of user_credit_return_threshold, it was incorrectly spelled as user_credit_return_theshold causing two module parameters, one with typo, to be shown in modinfo Reviewed-by: Ira Weiny Reviewed-by: Mike Marciniszyn Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rdma/hfi1/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rdma/hfi1/init.c b/drivers/staging/rdma/hfi1/init.c index 7ad9eb1825142..4dd8051aba7ef 100644 --- a/drivers/staging/rdma/hfi1/init.c +++ b/drivers/staging/rdma/hfi1/init.c @@ -113,7 +113,7 @@ MODULE_PARM_DESC(hdrq_entsize, "Size of header queue entries: 2 - 8B, 16 - 64B ( unsigned int user_credit_return_threshold = 33; /* default is 33% */ module_param(user_credit_return_threshold, uint, S_IRUGO); -MODULE_PARM_DESC(user_credit_return_theshold, "Credit return threshold for user send contexts, return when unreturned credits passes this many blocks (in percent of allocated blocks, 0 is off)"); +MODULE_PARM_DESC(user_credit_return_threshold, "Credit return threshold for user send contexts, return when unreturned credits passes this many blocks (in percent of allocated blocks, 0 is off)"); static inline u64 encode_rcv_header_entry_size(u16); -- GitLab From 967628827f404b3063016c138ccc7b06c54350f8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 17 Dec 2015 15:27:07 +0300 Subject: [PATCH 1867/2855] VFIO: platform: reset: fix a warning message condition This loop ends with count set to -1 and not zero so the warning message isn't printed when it should be. I've fixed this by change the postop to a preop. Fixes: 0990822c9866 ('VFIO: platform: reset: AMD xgbe reset module') Signed-off-by: Dan Carpenter Reviewed-by: Eric Auger Signed-off-by: Alex Williamson --- drivers/vfio/platform/reset/vfio_platform_amdxgbe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vfio/platform/reset/vfio_platform_amdxgbe.c b/drivers/vfio/platform/reset/vfio_platform_amdxgbe.c index da5356f48d0b0..d4030d0c38e9c 100644 --- a/drivers/vfio/platform/reset/vfio_platform_amdxgbe.c +++ b/drivers/vfio/platform/reset/vfio_platform_amdxgbe.c @@ -110,7 +110,7 @@ int vfio_platform_amdxgbe_reset(struct vfio_platform_device *vdev) usleep_range(10, 15); count = 2000; - while (count-- && (ioread32(xgmac_regs->ioaddr + DMA_MR) & 1)) + while (--count && (ioread32(xgmac_regs->ioaddr + DMA_MR) & 1)) usleep_range(500, 600); if (!count) -- GitLab From 77d6bd47cc2824af016086c2bd4650685b159e22 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Fri, 18 Dec 2015 12:35:47 +1100 Subject: [PATCH 1868/2855] vfio: Add explicit alignments in vfio_iommu_spapr_tce_create The vfio_iommu_spapr_tce_create struct has 4x32bit and 2x64bit fields which should have resulted in sizeof(fio_iommu_spapr_tce_create) equal to 32 bytes. However due to the gcc's default alignment, the actual size of this struct is 40 bytes. This fills gaps with __resv1/2 fields. This should not cause any change in behavior. Signed-off-by: Alexey Kardashevskiy Acked-by: David Gibson Signed-off-by: Alex Williamson --- include/uapi/linux/vfio.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index 9fd7b5d8df2fa..d1172331ca622 100644 --- a/include/uapi/linux/vfio.h +++ b/include/uapi/linux/vfio.h @@ -568,8 +568,10 @@ struct vfio_iommu_spapr_tce_create { __u32 flags; /* in */ __u32 page_shift; + __u32 __resv1; __u64 window_size; __u32 levels; + __u32 __resv2; /* out */ __u64 start_addr; }; -- GitLab From 03a76b60f8ba27974e2d252bc555d2c103420e15 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Mon, 21 Dec 2015 15:13:33 -0700 Subject: [PATCH 1869/2855] vfio: Include No-IOMMU mode There is really no way to safely give a user full access to a DMA capable device without an IOMMU to protect the host system. There is also no way to provide DMA translation, for use cases such as device assignment to virtual machines. However, there are still those users that want userspace drivers even under those conditions. The UIO driver exists for this use case, but does not provide the degree of device access and programming that VFIO has. In an effort to avoid code duplication, this introduces a No-IOMMU mode for VFIO. This mode requires building VFIO with CONFIG_VFIO_NOIOMMU and enabling the "enable_unsafe_noiommu_mode" option on the vfio driver. This should make it very clear that this mode is not safe. Additionally, CAP_SYS_RAWIO privileges are necessary to work with groups and containers using this mode. Groups making use of this support are named /dev/vfio/noiommu-$GROUP and can only make use of the special VFIO_NOIOMMU_IOMMU for the container. Use of this mode, specifically binding a device without a native IOMMU group to a VFIO bus driver will taint the kernel and should therefore not be considered supported. This patch includes no-iommu support for the vfio-pci bus driver only. Signed-off-by: Alex Williamson Acked-by: Michael S. Tsirkin --- drivers/vfio/Kconfig | 15 +++ drivers/vfio/pci/vfio_pci.c | 8 +- drivers/vfio/vfio.c | 184 +++++++++++++++++++++++++++++++++++- include/linux/vfio.h | 3 + include/uapi/linux/vfio.h | 7 ++ 5 files changed, 210 insertions(+), 7 deletions(-) diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig index 850d86ca685b2..da6e2ce77495b 100644 --- a/drivers/vfio/Kconfig +++ b/drivers/vfio/Kconfig @@ -31,6 +31,21 @@ menuconfig VFIO If you don't know what to do here, say N. +menuconfig VFIO_NOIOMMU + bool "VFIO No-IOMMU support" + depends on VFIO + help + VFIO is built on the ability to isolate devices using the IOMMU. + Only with an IOMMU can userspace access to DMA capable devices be + considered secure. VFIO No-IOMMU mode enables IOMMU groups for + devices without IOMMU backing for the purpose of re-using the VFIO + infrastructure in a non-secure mode. Use of this mode will result + in an unsupportable kernel and will therefore taint the kernel. + Device assignment to virtual machines is also not possible with + this mode since there is no IOMMU to provide DMA translation. + + If you don't know what to do here, say N. + source "drivers/vfio/pci/Kconfig" source "drivers/vfio/platform/Kconfig" source "virt/lib/Kconfig" diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 56bf6dbb93db7..2760a7ba3f309 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -940,13 +940,13 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL) return -EINVAL; - group = iommu_group_get(&pdev->dev); + group = vfio_iommu_group_get(&pdev->dev); if (!group) return -EINVAL; vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); if (!vdev) { - iommu_group_put(group); + vfio_iommu_group_put(group, &pdev->dev); return -ENOMEM; } @@ -957,7 +957,7 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ret = vfio_add_group_dev(&pdev->dev, &vfio_pci_ops, vdev); if (ret) { - iommu_group_put(group); + vfio_iommu_group_put(group, &pdev->dev); kfree(vdev); return ret; } @@ -993,7 +993,7 @@ static void vfio_pci_remove(struct pci_dev *pdev) if (!vdev) return; - iommu_group_put(pdev->dev.iommu_group); + vfio_iommu_group_put(pdev->dev.iommu_group, &pdev->dev); kfree(vdev); if (vfio_pci_is_vga(pdev)) { diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 6070b793cbcb2..82f25cc1c460d 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -62,6 +62,7 @@ struct vfio_container { struct rw_semaphore group_lock; struct vfio_iommu_driver *iommu_driver; void *iommu_data; + bool noiommu; }; struct vfio_unbound_dev { @@ -84,6 +85,7 @@ struct vfio_group { struct list_head unbound_list; struct mutex unbound_lock; atomic_t opened; + bool noiommu; }; struct vfio_device { @@ -95,6 +97,128 @@ struct vfio_device { void *device_data; }; +#ifdef CONFIG_VFIO_NOIOMMU +static bool noiommu __read_mostly; +module_param_named(enable_unsafe_noiommu_mode, + noiommu, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(enable_unsafe_noiommu_mode, "Enable UNSAFE, no-IOMMU mode. This mode provides no device isolation, no DMA translation, no host kernel protection, cannot be used for device assignment to virtual machines, requires RAWIO permissions, and will taint the kernel. If you do not know what this is for, step away. (default: false)"); +#endif + +/* + * vfio_iommu_group_{get,put} are only intended for VFIO bus driver probe + * and remove functions, any use cases other than acquiring the first + * reference for the purpose of calling vfio_add_group_dev() or removing + * that symmetric reference after vfio_del_group_dev() should use the raw + * iommu_group_{get,put} functions. In particular, vfio_iommu_group_put() + * removes the device from the dummy group and cannot be nested. + */ +struct iommu_group *vfio_iommu_group_get(struct device *dev) +{ + struct iommu_group *group; + int __maybe_unused ret; + + group = iommu_group_get(dev); + +#ifdef CONFIG_VFIO_NOIOMMU + /* + * With noiommu enabled, an IOMMU group will be created for a device + * that doesn't already have one and doesn't have an iommu_ops on their + * bus. We use iommu_present() again in the main code to detect these + * fake groups. + */ + if (group || !noiommu || iommu_present(dev->bus)) + return group; + + group = iommu_group_alloc(); + if (IS_ERR(group)) + return NULL; + + iommu_group_set_name(group, "vfio-noiommu"); + ret = iommu_group_add_device(group, dev); + iommu_group_put(group); + if (ret) + return NULL; + + /* + * Where to taint? At this point we've added an IOMMU group for a + * device that is not backed by iommu_ops, therefore any iommu_ + * callback using iommu_ops can legitimately Oops. So, while we may + * be about to give a DMA capable device to a user without IOMMU + * protection, which is clearly taint-worthy, let's go ahead and do + * it here. + */ + add_taint(TAINT_USER, LOCKDEP_STILL_OK); + dev_warn(dev, "Adding kernel taint for vfio-noiommu group on device\n"); +#endif + + return group; +} +EXPORT_SYMBOL_GPL(vfio_iommu_group_get); + +void vfio_iommu_group_put(struct iommu_group *group, struct device *dev) +{ +#ifdef CONFIG_VFIO_NOIOMMU + if (!iommu_present(dev->bus)) + iommu_group_remove_device(dev); +#endif + + iommu_group_put(group); +} +EXPORT_SYMBOL_GPL(vfio_iommu_group_put); + +#ifdef CONFIG_VFIO_NOIOMMU +static void *vfio_noiommu_open(unsigned long arg) +{ + if (arg != VFIO_NOIOMMU_IOMMU) + return ERR_PTR(-EINVAL); + if (!capable(CAP_SYS_RAWIO)) + return ERR_PTR(-EPERM); + + return NULL; +} + +static void vfio_noiommu_release(void *iommu_data) +{ +} + +static long vfio_noiommu_ioctl(void *iommu_data, + unsigned int cmd, unsigned long arg) +{ + if (cmd == VFIO_CHECK_EXTENSION) + return noiommu && (arg == VFIO_NOIOMMU_IOMMU) ? 1 : 0; + + return -ENOTTY; +} + +static int vfio_iommu_present(struct device *dev, void *unused) +{ + return iommu_present(dev->bus) ? 1 : 0; +} + +static int vfio_noiommu_attach_group(void *iommu_data, + struct iommu_group *iommu_group) +{ + return iommu_group_for_each_dev(iommu_group, NULL, + vfio_iommu_present) ? -EINVAL : 0; +} + +static void vfio_noiommu_detach_group(void *iommu_data, + struct iommu_group *iommu_group) +{ +} + +static const struct vfio_iommu_driver_ops vfio_noiommu_ops = { + .name = "vfio-noiommu", + .owner = THIS_MODULE, + .open = vfio_noiommu_open, + .release = vfio_noiommu_release, + .ioctl = vfio_noiommu_ioctl, + .attach_group = vfio_noiommu_attach_group, + .detach_group = vfio_noiommu_detach_group, +}; +#endif + + /** * IOMMU driver registration */ @@ -199,7 +323,8 @@ static void vfio_group_unlock_and_free(struct vfio_group *group) /** * Group objects - create, release, get, put, search */ -static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group) +static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group, + bool iommu_present) { struct vfio_group *group, *tmp; struct device *dev; @@ -217,6 +342,7 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group) atomic_set(&group->container_users, 0); atomic_set(&group->opened, 0); group->iommu_group = iommu_group; + group->noiommu = !iommu_present; group->nb.notifier_call = vfio_iommu_group_notifier; @@ -252,7 +378,8 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group) dev = device_create(vfio.class, NULL, MKDEV(MAJOR(vfio.group_devt), minor), - group, "%d", iommu_group_id(iommu_group)); + group, "%s%d", group->noiommu ? "noiommu-" : "", + iommu_group_id(iommu_group)); if (IS_ERR(dev)) { vfio_free_group_minor(minor); vfio_group_unlock_and_free(group); @@ -640,7 +767,7 @@ int vfio_add_group_dev(struct device *dev, group = vfio_group_get_from_iommu(iommu_group); if (!group) { - group = vfio_create_group(iommu_group); + group = vfio_create_group(iommu_group, iommu_present(dev->bus)); if (IS_ERR(group)) { iommu_group_put(iommu_group); return PTR_ERR(group); @@ -854,6 +981,14 @@ static long vfio_ioctl_check_extension(struct vfio_container *container, mutex_lock(&vfio.iommu_drivers_lock); list_for_each_entry(driver, &vfio.iommu_drivers_list, vfio_next) { + +#ifdef CONFIG_VFIO_NOIOMMU + if (!list_empty(&container->group_list) && + (container->noiommu != + (driver->ops == &vfio_noiommu_ops))) + continue; +#endif + if (!try_module_get(driver->ops->owner)) continue; @@ -925,6 +1060,15 @@ static long vfio_ioctl_set_iommu(struct vfio_container *container, list_for_each_entry(driver, &vfio.iommu_drivers_list, vfio_next) { void *data; +#ifdef CONFIG_VFIO_NOIOMMU + /* + * Only noiommu containers can use vfio-noiommu and noiommu + * containers can only use vfio-noiommu. + */ + if (container->noiommu != (driver->ops == &vfio_noiommu_ops)) + continue; +#endif + if (!try_module_get(driver->ops->owner)) continue; @@ -1187,6 +1331,9 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd) if (atomic_read(&group->container_users)) return -EINVAL; + if (group->noiommu && !capable(CAP_SYS_RAWIO)) + return -EPERM; + f = fdget(container_fd); if (!f.file) return -EBADF; @@ -1202,6 +1349,13 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd) down_write(&container->group_lock); + /* Real groups and fake groups cannot mix */ + if (!list_empty(&container->group_list) && + container->noiommu != group->noiommu) { + ret = -EPERM; + goto unlock_out; + } + driver = container->iommu_driver; if (driver) { ret = driver->ops->attach_group(container->iommu_data, @@ -1211,6 +1365,7 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd) } group->container = container; + container->noiommu = group->noiommu; list_add(&group->container_next, &container->group_list); /* Get a reference on the container and mark a user within the group */ @@ -1241,6 +1396,9 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) !group->container->iommu_driver || !vfio_group_viable(group)) return -EINVAL; + if (group->noiommu && !capable(CAP_SYS_RAWIO)) + return -EPERM; + device = vfio_device_get_from_name(group, buf); if (!device) return -ENODEV; @@ -1283,6 +1441,10 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) fd_install(ret, filep); + if (group->noiommu) + dev_warn(device->dev, "vfio-noiommu device opened by user " + "(%s:%d)\n", current->comm, task_pid_nr(current)); + return ret; } @@ -1371,6 +1533,11 @@ static int vfio_group_fops_open(struct inode *inode, struct file *filep) if (!group) return -ENODEV; + if (group->noiommu && !capable(CAP_SYS_RAWIO)) { + vfio_group_put(group); + return -EPERM; + } + /* Do we need multiple instances of the group open? Seems not. */ opened = atomic_cmpxchg(&group->opened, 0, 1); if (opened) { @@ -1533,6 +1700,11 @@ struct vfio_group *vfio_group_get_external_user(struct file *filep) if (!atomic_inc_not_zero(&group->container_users)) return ERR_PTR(-EINVAL); + if (group->noiommu) { + atomic_dec(&group->container_users); + return ERR_PTR(-EPERM); + } + if (!group->container->iommu_driver || !vfio_group_viable(group)) { atomic_dec(&group->container_users); @@ -1625,6 +1797,9 @@ static int __init vfio_init(void) request_module_nowait("vfio_iommu_type1"); request_module_nowait("vfio_iommu_spapr_tce"); +#ifdef CONFIG_VFIO_NOIOMMU + vfio_register_iommu_driver(&vfio_noiommu_ops); +#endif return 0; err_cdev_add: @@ -1641,6 +1816,9 @@ static void __exit vfio_cleanup(void) { WARN_ON(!list_empty(&vfio.group_list)); +#ifdef CONFIG_VFIO_NOIOMMU + vfio_unregister_iommu_driver(&vfio_noiommu_ops); +#endif idr_destroy(&vfio.group_idr); cdev_del(&vfio.group_cdev); unregister_chrdev_region(vfio.group_devt, MINORMASK); diff --git a/include/linux/vfio.h b/include/linux/vfio.h index ddb4409753824..610a86a892b88 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -44,6 +44,9 @@ struct vfio_device_ops { void (*request)(void *device_data, unsigned int count); }; +extern struct iommu_group *vfio_iommu_group_get(struct device *dev); +extern void vfio_iommu_group_put(struct iommu_group *group, struct device *dev); + extern int vfio_add_group_dev(struct device *dev, const struct vfio_device_ops *ops, void *device_data); diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index d1172331ca622..7d7a4c6f20906 100644 --- a/include/uapi/linux/vfio.h +++ b/include/uapi/linux/vfio.h @@ -38,6 +38,13 @@ #define VFIO_SPAPR_TCE_v2_IOMMU 7 +/* + * The No-IOMMU IOMMU offers no translation or isolation for devices and + * supports no ioctls outside of VFIO_CHECK_EXTENSION. Use of VFIO's No-IOMMU + * code will taint the host kernel and should be used with extreme caution. + */ +#define VFIO_NOIOMMU_IOMMU 8 + /* * The IOCTL interface is designed for extensibility by embedding the * structure length (argsz) and flags into structures passed between -- GitLab From 464e5947d119ba02b308859861e1644d90d19191 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Sat, 7 Nov 2015 13:32:07 +0530 Subject: [PATCH 1870/2855] Staging: lustre: rw: Remove wrapper stride_page_count Remove the function stride_page_count() and replace its calls with the function stride_pg_count() that it wraps. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/rw.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index f79193fa2fb77..8184d9d1da527 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -880,14 +880,6 @@ static void ras_update_stride_detector(struct ll_readahead_state *ras, return; } -static unsigned long -stride_page_count(struct ll_readahead_state *ras, unsigned long len) -{ - return stride_pg_count(ras->ras_stride_offset, ras->ras_stride_length, - ras->ras_stride_pages, ras->ras_stride_offset, - len); -} - /* Stride Read-ahead window will be increased inc_len according to * stride I/O pattern */ static void ras_stride_increase_window(struct ll_readahead_state *ras, @@ -921,7 +913,9 @@ static void ras_stride_increase_window(struct ll_readahead_state *ras, window_len += step * ras->ras_stride_length + left; - if (stride_page_count(ras, window_len) <= ra->ra_max_pages_per_file) + if (stride_pg_count(ras->ras_stride_offset, ras->ras_stride_length, + ras->ras_stride_pages, ras->ras_stride_offset, + window_len) <= ra->ra_max_pages_per_file) ras->ras_window_len = window_len; RAS_CDEBUG(ras); -- GitLab From 8cdce48509a73cc45a79937237614ddc6e2181e2 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Sat, 7 Nov 2015 15:14:24 +0530 Subject: [PATCH 1871/2855] Staging: lustre: lustre_mds: Remove unused md_should_create md_should_create has been defined in header file but not used. Thus remove it. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/lustre_mds.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lustre_mds.h b/drivers/staging/lustre/lustre/include/lustre_mds.h index a16eb8b611789..95d27ddecfb39 100644 --- a/drivers/staging/lustre/lustre/include/lustre_mds.h +++ b/drivers/staging/lustre/lustre/include/lustre_mds.h @@ -62,12 +62,6 @@ struct mds_group_info { #define MDD_OBD_NAME "mdd_obd" #define MDD_OBD_UUID "mdd_obd_uuid" -static inline int md_should_create(__u64 flags) -{ - return !(flags & MDS_OPEN_DELAY_CREATE || - !(flags & FMODE_WRITE)); -} - /* these are local flags, used only on the client, private */ #define M_CHECK_STALE 0200000000 -- GitLab From b0d14255a1db03572d325a2d4897856f3b6f552f Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Sat, 7 Nov 2015 15:20:21 +0530 Subject: [PATCH 1872/2855] Staging: lustre: statahead: Remove ll_sa_entry_unhashed wrapper Remove the function ll_sa_entry_unhashed() and replace all its calls with the function list_empty() that it wrapped. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/statahead.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c index 18f5f2b7e9020..8085557ff67e1 100644 --- a/drivers/staging/lustre/lustre/llite/statahead.c +++ b/drivers/staging/lustre/lustre/llite/statahead.c @@ -87,11 +87,6 @@ struct ll_sa_entry { static unsigned int sai_generation; static DEFINE_SPINLOCK(sai_generation_lock); -static inline int ll_sa_entry_unhashed(struct ll_sa_entry *entry) -{ - return list_empty(&entry->se_hash); -} - /* * The entry only can be released by the caller, it is necessary to hold lock. */ @@ -331,7 +326,7 @@ static void ll_sa_entry_put(struct ll_statahead_info *sai, LASSERT(list_empty(&entry->se_link)); LASSERT(list_empty(&entry->se_list)); - LASSERT(ll_sa_entry_unhashed(entry)); + LASSERT(list_empty(&entry->se_hash)); ll_sa_entry_cleanup(sai, entry); iput(entry->se_inode); @@ -346,7 +341,7 @@ do_sa_entry_fini(struct ll_statahead_info *sai, struct ll_sa_entry *entry) { struct ll_inode_info *lli = ll_i2info(sai->sai_inode); - LASSERT(!ll_sa_entry_unhashed(entry)); + LASSERT(!list_empty(&entry->se_hash)); LASSERT(!list_empty(&entry->se_link)); ll_sa_entry_unhash(sai, entry); -- GitLab From 13ce3246573a6c9b785516c957f09108bf325b32 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Sat, 7 Nov 2015 15:20:59 +0530 Subject: [PATCH 1873/2855] Staging: lustre: statahead: Remove sa_first_received_entry wrapper Remove the function sa_first_received_entry() and replace all its calls with the function list_entry() that it wraps. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/statahead.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c index 8085557ff67e1..d80ca9319c9fe 100644 --- a/drivers/staging/lustre/lustre/llite/statahead.c +++ b/drivers/staging/lustre/lustre/llite/statahead.c @@ -133,13 +133,6 @@ static inline int agl_should_run(struct ll_statahead_info *sai, return (inode != NULL && S_ISREG(inode->i_mode) && sai->sai_agl_valid); } -static inline struct ll_sa_entry * -sa_first_received_entry(struct ll_statahead_info *sai) -{ - return list_entry(sai->sai_entries_received.next, - struct ll_sa_entry, se_list); -} - static inline struct ll_inode_info * agl_first_entry(struct ll_statahead_info *sai) { @@ -620,7 +613,8 @@ static void ll_post_statahead(struct ll_statahead_info *sai) spin_unlock(&lli->lli_sa_lock); return; } - entry = sa_first_received_entry(sai); + entry = list_entry(sai->sai_entries_received.next, + struct ll_sa_entry, se_list); atomic_inc(&entry->se_refcount); list_del_init(&entry->se_list); spin_unlock(&lli->lli_sa_lock); -- GitLab From 6c3d0ea63e69527eb3b1c8117462f96cff0e4b48 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Sat, 7 Nov 2015 15:21:39 +0530 Subject: [PATCH 1874/2855] Staging: lustre: statahead: Remove agl_first_entry wrapper Remove the wrapper function agl_first_entry() and replace its calls with the function list_entry() that it wraps. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/llite/statahead.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c index d80ca9319c9fe..fbc34afa5c73a 100644 --- a/drivers/staging/lustre/lustre/llite/statahead.c +++ b/drivers/staging/lustre/lustre/llite/statahead.c @@ -133,13 +133,6 @@ static inline int agl_should_run(struct ll_statahead_info *sai, return (inode != NULL && S_ISREG(inode->i_mode) && sai->sai_agl_valid); } -static inline struct ll_inode_info * -agl_first_entry(struct ll_statahead_info *sai) -{ - return list_entry(sai->sai_entries_agl.next, - struct ll_inode_info, lli_agl_list); -} - static inline int sa_sent_full(struct ll_statahead_info *sai) { return atomic_read(&sai->sai_cache_count) >= sai->sai_max; @@ -973,7 +966,8 @@ static int ll_agl_thread(void *arg) /* The statahead thread maybe help to process AGL entries, * so check whether list empty again. */ if (!agl_list_empty(sai)) { - clli = agl_first_entry(sai); + clli = list_entry(sai->sai_entries_agl.next, + struct ll_inode_info, lli_agl_list); list_del_init(&clli->lli_agl_list); spin_unlock(&plli->lli_agl_lock); ll_agl_trigger(&clli->lli_vfs_inode, sai); @@ -985,7 +979,8 @@ static int ll_agl_thread(void *arg) spin_lock(&plli->lli_agl_lock); sai->sai_agl_valid = 0; while (!agl_list_empty(sai)) { - clli = agl_first_entry(sai); + clli = list_entry(sai->sai_entries_agl.next, + struct ll_inode_info, lli_agl_list); list_del_init(&clli->lli_agl_list); spin_unlock(&plli->lli_agl_lock); clli->lli_agl_index = 0; @@ -1146,7 +1141,8 @@ interpret_it: if (sa_sent_full(sai)) { spin_lock(&plli->lli_agl_lock); while (!agl_list_empty(sai)) { - clli = agl_first_entry(sai); + clli = list_entry(sai->sai_entries_agl.next, + struct ll_inode_info, lli_agl_list); list_del_init(&clli->lli_agl_list); spin_unlock(&plli->lli_agl_lock); ll_agl_trigger(&clli->lli_vfs_inode, @@ -1204,7 +1200,8 @@ do_it: spin_lock(&plli->lli_agl_lock); while (!agl_list_empty(sai) && thread_is_running(thread)) { - clli = agl_first_entry(sai); + clli = list_entry(sai->sai_entries_agl.next, + struct ll_inode_info, lli_agl_list); list_del_init(&clli->lli_agl_list); spin_unlock(&plli->lli_agl_lock); ll_agl_trigger(&clli->lli_vfs_inode, sai); -- GitLab From 615f9a68b9735d1690b9ada3d7d60f864b3161e5 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Sat, 7 Nov 2015 15:22:18 +0530 Subject: [PATCH 1875/2855] Staging: lustre: statahead: Remove sa_received_empty wrapper Remove the wrapper sa_received_empty() and replace its calls with the function it wrapped. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/llite/statahead.c | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c index fbc34afa5c73a..3a1d2943121b1 100644 --- a/drivers/staging/lustre/lustre/llite/statahead.c +++ b/drivers/staging/lustre/lustre/llite/statahead.c @@ -518,7 +518,7 @@ static void ll_sai_put(struct ll_statahead_info *sai) do_sa_entry_fini(sai, entry); LASSERT(list_empty(&sai->sai_entries)); - LASSERT(sa_received_empty(sai)); + LASSERT(list_empty(&sai->sai_entries_received)); LASSERT(list_empty(&sai->sai_entries_stated)); LASSERT(atomic_read(&sai->sai_cache_count) == 0); @@ -602,7 +602,7 @@ static void ll_post_statahead(struct ll_statahead_info *sai) int rc = 0; spin_lock(&lli->lli_sa_lock); - if (unlikely(sa_received_empty(sai))) { + if (unlikely(list_empty(&sai->sai_entries_received))) { spin_unlock(&lli->lli_sa_lock); return; } @@ -738,7 +738,7 @@ static int ll_statahead_interpret(struct ptlrpc_request *req, * for readpage and other tries to enqueue lock on child * with parent's lock held, for example: unlink. */ entry->se_handle = handle; - wakeup = sa_received_empty(sai); + wakeup = list_empty(&sai->sai_entries_received); list_add_tail(&entry->se_list, &sai->sai_entries_received); } @@ -1120,13 +1120,13 @@ static int ll_statahead_thread(void *arg) keep_it: l_wait_event(thread->t_ctl_waitq, !sa_sent_full(sai) || - !sa_received_empty(sai) || + !list_empty(&sai->sai_entries_received) || !agl_list_empty(sai) || !thread_is_running(thread), &lwi); interpret_it: - while (!sa_received_empty(sai)) + while (!list_empty(&sai->sai_entries_received)) ll_post_statahead(sai); if (unlikely(!thread_is_running(thread))) { @@ -1148,7 +1148,7 @@ interpret_it: ll_agl_trigger(&clli->lli_vfs_inode, sai); - if (!sa_received_empty(sai)) + if (!list_empty(&sai->sai_entries_received)) goto interpret_it; if (unlikely( @@ -1179,12 +1179,12 @@ do_it: ll_release_page(page, 0); while (1) { l_wait_event(thread->t_ctl_waitq, - !sa_received_empty(sai) || + !list_empty(&sai->sai_entries_received) || sai->sai_sent == sai->sai_replied || !thread_is_running(thread), &lwi); - while (!sa_received_empty(sai)) + while (!list_empty(&sai->sai_entries_received)) ll_post_statahead(sai); if (unlikely(!thread_is_running(thread))) { @@ -1193,7 +1193,7 @@ do_it: } if (sai->sai_sent == sai->sai_replied && - sa_received_empty(sai)) + list_empty(&sai->sai_entries_received)) break; } @@ -1246,12 +1246,12 @@ out: } ll_dir_chain_fini(&chain); spin_lock(&plli->lli_sa_lock); - if (!sa_received_empty(sai)) { + if (!list_empty(&sai->sai_entries_received)) { thread_set_flags(thread, SVC_STOPPING); spin_unlock(&plli->lli_sa_lock); /* To release the resources held by received entries. */ - while (!sa_received_empty(sai)) + while (!list_empty(&sai->sai_entries_received)) ll_post_statahead(sai); spin_lock(&plli->lli_sa_lock); -- GitLab From 24a85e887b4e44e39425f1d8e0a9e56b690b80b1 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Sat, 7 Nov 2015 15:23:11 +0530 Subject: [PATCH 1876/2855] Staging: lustre: statahead: Remove agl_list_empty wrapper Remove the function agl_list_empty() and replace its calls with the function it wrapped. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/statahead.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c index 3a1d2943121b1..caee0a6f8b849 100644 --- a/drivers/staging/lustre/lustre/llite/statahead.c +++ b/drivers/staging/lustre/lustre/llite/statahead.c @@ -428,7 +428,7 @@ static void ll_agl_add(struct ll_statahead_info *sai, igrab(inode); spin_lock(&parent->lli_agl_lock); - if (agl_list_empty(sai)) + if (list_empty(&sai->sai_entries_agl)) added = 1; list_add_tail(&child->lli_agl_list, &sai->sai_entries_agl); spin_unlock(&parent->lli_agl_lock); @@ -522,7 +522,7 @@ static void ll_sai_put(struct ll_statahead_info *sai) LASSERT(list_empty(&sai->sai_entries_stated)); LASSERT(atomic_read(&sai->sai_cache_count) == 0); - LASSERT(agl_list_empty(sai)); + LASSERT(list_empty(&sai->sai_entries_agl)); iput(inode); kfree(sai); @@ -955,7 +955,7 @@ static int ll_agl_thread(void *arg) while (1) { l_wait_event(thread->t_ctl_waitq, - !agl_list_empty(sai) || + !list_empty(&sai->sai_entries_agl) || !thread_is_running(thread), &lwi); @@ -965,7 +965,7 @@ static int ll_agl_thread(void *arg) spin_lock(&plli->lli_agl_lock); /* The statahead thread maybe help to process AGL entries, * so check whether list empty again. */ - if (!agl_list_empty(sai)) { + if (!list_empty(&sai->sai_entries_agl)) { clli = list_entry(sai->sai_entries_agl.next, struct ll_inode_info, lli_agl_list); list_del_init(&clli->lli_agl_list); @@ -978,7 +978,7 @@ static int ll_agl_thread(void *arg) spin_lock(&plli->lli_agl_lock); sai->sai_agl_valid = 0; - while (!agl_list_empty(sai)) { + while (!list_empty(&sai->sai_entries_agl)) { clli = list_entry(sai->sai_entries_agl.next, struct ll_inode_info, lli_agl_list); list_del_init(&clli->lli_agl_list); @@ -1121,7 +1121,7 @@ keep_it: l_wait_event(thread->t_ctl_waitq, !sa_sent_full(sai) || !list_empty(&sai->sai_entries_received) || - !agl_list_empty(sai) || + !list_empty(&sai->sai_entries_agl) || !thread_is_running(thread), &lwi); @@ -1140,7 +1140,7 @@ interpret_it: * to process the AGL entries. */ if (sa_sent_full(sai)) { spin_lock(&plli->lli_agl_lock); - while (!agl_list_empty(sai)) { + while (!list_empty(&sai->sai_entries_agl)) { clli = list_entry(sai->sai_entries_agl.next, struct ll_inode_info, lli_agl_list); list_del_init(&clli->lli_agl_list); @@ -1198,7 +1198,7 @@ do_it: } spin_lock(&plli->lli_agl_lock); - while (!agl_list_empty(sai) && + while (!list_empty(&sai->sai_entries_agl) && thread_is_running(thread)) { clli = list_entry(sai->sai_entries_agl.next, struct ll_inode_info, lli_agl_list); -- GitLab From d11f8cc4bb7ff4ee8cc89d2799cdda206da0f434 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Sun, 8 Nov 2015 14:47:10 +0530 Subject: [PATCH 1877/2855] staging: lustre: workitem: Remove cfs_wi_sched_lock wrapper Remove the wrapper function cfs_wi_sched_lock() and replace all its calls with the function it wrapped. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/libcfs/workitem.c | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/workitem.c b/drivers/staging/lustre/lustre/libcfs/workitem.c index b57acbfb061b1..e8bac9b2b6f11 100644 --- a/drivers/staging/lustre/lustre/libcfs/workitem.c +++ b/drivers/staging/lustre/lustre/libcfs/workitem.c @@ -86,12 +86,6 @@ static struct cfs_workitem_data { int wi_stopping; } cfs_wi_data; -static inline void -cfs_wi_sched_lock(struct cfs_wi_sched *sched) -{ - spin_lock(&sched->ws_lock); -} - static inline void cfs_wi_sched_unlock(struct cfs_wi_sched *sched) { @@ -101,7 +95,7 @@ cfs_wi_sched_unlock(struct cfs_wi_sched *sched) static inline int cfs_wi_sched_cansleep(struct cfs_wi_sched *sched) { - cfs_wi_sched_lock(sched); + spin_lock(&sched->ws_lock); if (sched->ws_stopping) { cfs_wi_sched_unlock(sched); return 0; @@ -125,7 +119,7 @@ cfs_wi_exit(struct cfs_wi_sched *sched, cfs_workitem_t *wi) LASSERT(!in_interrupt()); /* because we use plain spinlock */ LASSERT(!sched->ws_stopping); - cfs_wi_sched_lock(sched); + spin_lock(&sched->ws_lock); LASSERT(wi->wi_running); if (wi->wi_scheduled) { /* cancel pending schedules */ @@ -161,7 +155,7 @@ cfs_wi_deschedule(struct cfs_wi_sched *sched, cfs_workitem_t *wi) * means the workitem will not be scheduled and will not have * any race with wi_action. */ - cfs_wi_sched_lock(sched); + spin_lock(&sched->ws_lock); rc = !(wi->wi_running); @@ -195,7 +189,7 @@ cfs_wi_schedule(struct cfs_wi_sched *sched, cfs_workitem_t *wi) LASSERT(!in_interrupt()); /* because we use plain spinlock */ LASSERT(!sched->ws_stopping); - cfs_wi_sched_lock(sched); + spin_lock(&sched->ws_lock); if (!wi->wi_scheduled) { LASSERT (list_empty(&wi->wi_list)); @@ -237,7 +231,7 @@ cfs_wi_scheduler (void *arg) spin_unlock(&cfs_wi_data.wi_glock); - cfs_wi_sched_lock(sched); + spin_lock(&sched->ws_lock); while (!sched->ws_stopping) { int nloops = 0; @@ -263,7 +257,7 @@ cfs_wi_scheduler (void *arg) rc = (*wi->wi_action) (wi); - cfs_wi_sched_lock(sched); + spin_lock(&sched->ws_lock); if (rc != 0) /* WI should be dead, even be freed! */ continue; @@ -282,14 +276,14 @@ cfs_wi_scheduler (void *arg) /* don't sleep because some workitems still * expect me to come back soon */ cond_resched(); - cfs_wi_sched_lock(sched); + spin_lock(&sched->ws_lock); continue; } cfs_wi_sched_unlock(sched); rc = wait_event_interruptible_exclusive(sched->ws_waitq, !cfs_wi_sched_cansleep(sched)); - cfs_wi_sched_lock(sched); + spin_lock(&sched->ws_lock); } cfs_wi_sched_unlock(sched); -- GitLab From 8eefa1c028f5b16f33ce1b3c7bbabdf74efc63b1 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Sun, 8 Nov 2015 14:47:34 +0530 Subject: [PATCH 1878/2855] staging: lustre: workitem: Remove cfs_wi_sched_unlock wrapper Remove the wrapper function cfs_wi_sched_unlock() and replace all its calls with the function it wrapped. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/libcfs/workitem.c | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/workitem.c b/drivers/staging/lustre/lustre/libcfs/workitem.c index e8bac9b2b6f11..60bb88a00b416 100644 --- a/drivers/staging/lustre/lustre/libcfs/workitem.c +++ b/drivers/staging/lustre/lustre/libcfs/workitem.c @@ -86,26 +86,20 @@ static struct cfs_workitem_data { int wi_stopping; } cfs_wi_data; -static inline void -cfs_wi_sched_unlock(struct cfs_wi_sched *sched) -{ - spin_unlock(&sched->ws_lock); -} - static inline int cfs_wi_sched_cansleep(struct cfs_wi_sched *sched) { spin_lock(&sched->ws_lock); if (sched->ws_stopping) { - cfs_wi_sched_unlock(sched); + spin_unlock(&sched->ws_lock); return 0; } if (!list_empty(&sched->ws_runq)) { - cfs_wi_sched_unlock(sched); + spin_unlock(&sched->ws_lock); return 0; } - cfs_wi_sched_unlock(sched); + spin_unlock(&sched->ws_lock); return 1; } @@ -133,7 +127,7 @@ cfs_wi_exit(struct cfs_wi_sched *sched, cfs_workitem_t *wi) LASSERT(list_empty(&wi->wi_list)); wi->wi_scheduled = 1; /* LBUG future schedule attempts */ - cfs_wi_sched_unlock(sched); + spin_unlock(&sched->ws_lock); return; } @@ -171,7 +165,7 @@ cfs_wi_deschedule(struct cfs_wi_sched *sched, cfs_workitem_t *wi) LASSERT (list_empty(&wi->wi_list)); - cfs_wi_sched_unlock(sched); + spin_unlock(&sched->ws_lock); return rc; } EXPORT_SYMBOL(cfs_wi_deschedule); @@ -205,7 +199,7 @@ cfs_wi_schedule(struct cfs_wi_sched *sched, cfs_workitem_t *wi) } LASSERT (!list_empty(&wi->wi_list)); - cfs_wi_sched_unlock(sched); + spin_unlock(&sched->ws_lock); return; } EXPORT_SYMBOL(cfs_wi_schedule); @@ -252,7 +246,7 @@ cfs_wi_scheduler (void *arg) wi->wi_running = 1; wi->wi_scheduled = 0; - cfs_wi_sched_unlock(sched); + spin_unlock(&sched->ws_lock); nloops++; rc = (*wi->wi_action) (wi); @@ -272,7 +266,7 @@ cfs_wi_scheduler (void *arg) } if (!list_empty(&sched->ws_runq)) { - cfs_wi_sched_unlock(sched); + spin_unlock(&sched->ws_lock); /* don't sleep because some workitems still * expect me to come back soon */ cond_resched(); @@ -280,13 +274,13 @@ cfs_wi_scheduler (void *arg) continue; } - cfs_wi_sched_unlock(sched); + spin_unlock(&sched->ws_lock); rc = wait_event_interruptible_exclusive(sched->ws_waitq, !cfs_wi_sched_cansleep(sched)); spin_lock(&sched->ws_lock); } - cfs_wi_sched_unlock(sched); + spin_unlock(&sched->ws_lock); spin_lock(&cfs_wi_data.wi_glock); sched->ws_nthreads--; -- GitLab From dd40ca4629faa656148803fbfded4c804a25a21b Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Sun, 8 Nov 2015 22:22:58 +0530 Subject: [PATCH 1879/2855] staging: lustre: mdc_request: Remove mdc_kuc_reregister wrapper Remove the wrapper function mdc_kuc_reregister() and replace its call with the function it wrapped. Also, comment has been added for clarity. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/mdc_request.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 294c05084b976..e172be1bc1c6e 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -2037,17 +2037,6 @@ static int mdc_hsm_ct_reregister(__u32 data, void *cb_arg) return ((rc != 0) && (rc != -EEXIST)) ? rc : 0; } -/** - * Re-establish all kuc contexts with MDT - * after MDT shutdown/recovery. - */ -static int mdc_kuc_reregister(struct obd_import *imp) -{ - /* re-register HSM agents */ - return libcfs_kkuc_group_foreach(KUC_GRP_HSM, mdc_hsm_ct_reregister, - (void *)imp); -} - static int mdc_set_info_async(const struct lu_env *env, struct obd_export *exp, u32 keylen, void *key, @@ -2210,7 +2199,10 @@ static int mdc_import_event(struct obd_device *obd, struct obd_import *imp, rc = obd_notify_observer(obd, obd, OBD_NOTIFY_ACTIVE, NULL); /* redo the kuc registration after reconnecting */ if (rc == 0) - rc = mdc_kuc_reregister(imp); + /* re-register HSM agents */ + rc = libcfs_kkuc_group_foreach(KUC_GRP_HSM, + mdc_hsm_ct_reregister, + (void *)imp); break; case IMP_EVENT_OCD: rc = obd_notify_observer(obd, obd, OBD_NOTIFY_OCD, NULL); -- GitLab From 524576d174c2b3321671fa87bcd6eac24f001485 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Sun, 8 Nov 2015 14:17:06 -0500 Subject: [PATCH 1880/2855] staging: lustre: remove hsm_nl proc file Remove the file /proc/fs/lustre/mdc/*/hsm_nl which was introduced "for testing purposes." Signed-off-by: John L. Hammond Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-2489 Reviewed-on: http://review.whamcloud.com/6656 Reviewed-by: jacques-Charles Lafoucriere Reviewed-by: Aurelien Degremont Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/lproc_mdc.c | 77 ------------------- 1 file changed, 77 deletions(-) diff --git a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c index 1c95f87a0e2ae..84e586223588e 100644 --- a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c +++ b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c @@ -82,82 +82,6 @@ static ssize_t max_rpcs_in_flight_store(struct kobject *kobj, } LUSTRE_RW_ATTR(max_rpcs_in_flight); -static int mdc_kuc_open(struct inode *inode, struct file *file) -{ - return single_open(file, NULL, inode->i_private); -} - -/* temporary for testing */ -static ssize_t mdc_kuc_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) -{ - struct obd_device *obd = - ((struct seq_file *)file->private_data)->private; - struct kuc_hdr *lh; - struct hsm_action_list *hal; - struct hsm_action_item *hai; - int len; - int fd, rc; - - rc = lprocfs_write_helper(buffer, count, &fd); - if (rc) - return rc; - - if (fd < 0) - return -ERANGE; - CWARN("message to fd %d\n", fd); - - len = sizeof(*lh) + sizeof(*hal) + MTI_NAME_MAXLEN + - /* for mockup below */ 2 * cfs_size_round(sizeof(*hai)); - - lh = kzalloc(len, GFP_NOFS); - if (!lh) - return -ENOMEM; - - lh->kuc_magic = KUC_MAGIC; - lh->kuc_transport = KUC_TRANSPORT_HSM; - lh->kuc_msgtype = HMT_ACTION_LIST; - lh->kuc_msglen = len; - - hal = (struct hsm_action_list *)(lh + 1); - hal->hal_version = HAL_VERSION; - hal->hal_archive_id = 1; - hal->hal_flags = 0; - obd_uuid2fsname(hal->hal_fsname, obd->obd_name, MTI_NAME_MAXLEN); - - /* mock up an action list */ - hal->hal_count = 2; - hai = hai_zero(hal); - hai->hai_action = HSMA_ARCHIVE; - hai->hai_fid.f_oid = 5; - hai->hai_len = sizeof(*hai); - hai = hai_next(hai); - hai->hai_action = HSMA_RESTORE; - hai->hai_fid.f_oid = 10; - hai->hai_len = sizeof(*hai); - - /* This works for either broadcast or unicast to a single fd */ - if (fd == 0) { - rc = libcfs_kkuc_group_put(KUC_GRP_HSM, lh); - } else { - struct file *fp = fget(fd); - - rc = libcfs_kkuc_msg_put(fp, lh); - fput(fp); - } - kfree(lh); - if (rc < 0) - return rc; - return count; -} - -static struct file_operations mdc_kuc_fops = { - .open = mdc_kuc_open, - .write = mdc_kuc_write, - .release = single_release, -}; - LPROC_SEQ_FOPS_WR_ONLY(mdc, ping); LPROC_SEQ_FOPS_RO_TYPE(mdc, connect_flags); @@ -196,7 +120,6 @@ static struct lprocfs_vars lprocfs_mdc_obd_vars[] = { { "timeouts", &mdc_timeouts_fops, NULL, 0 }, { "import", &mdc_import_fops, NULL, 0 }, { "state", &mdc_state_fops, NULL, 0 }, - { "hsm_nl", &mdc_kuc_fops, NULL, 0200 }, { "pinger_recov", &mdc_pinger_recov_fops, NULL, 0 }, { NULL } }; -- GitLab From 82224549f33a2cf983edb82692311ccee805a21b Mon Sep 17 00:00:00 2001 From: frank zago Date: Sun, 8 Nov 2015 18:09:36 -0500 Subject: [PATCH 1881/2855] staging: lustre: remove unnecessary EXPORT_SYMBOL for lnet layer A lot of symbols don't need to be exported at all because they are only used in the module they belong to. Signed-off-by: frank zago Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5829 Reviewed-on: http://review.whamcloud.com/13320 Reviewed-by: James Simmons Reviewed-by: Isaac Huang Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/lnet/api-ni.c | 3 --- drivers/staging/lustre/lnet/lnet/lib-move.c | 1 - drivers/staging/lustre/lnet/selftest/conctl.c | 2 -- 3 files changed, 6 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 284150f53f7db..9f78dc8d7a267 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -354,7 +354,6 @@ lnet_counters_reset(void) lnet_net_unlock(LNET_LOCK_EX); } -EXPORT_SYMBOL(lnet_counters_reset); static char * lnet_res_type2str(int type) @@ -1153,7 +1152,6 @@ lnet_init(void) lnet_register_lnd(&the_lolnd); return 0; } -EXPORT_SYMBOL(lnet_init); /** * Finalize LNet library. @@ -1177,7 +1175,6 @@ lnet_fini(void) the_lnet.ln_init = 0; } -EXPORT_SYMBOL(lnet_fini); /** * Set LNet PID and start LNet interfaces, routing, and forwarding. diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 5631f60a39bc8..03a721e1bb3da 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1645,7 +1645,6 @@ lnet_msgtyp2str(int type) return ""; } } -EXPORT_SYMBOL(lnet_msgtyp2str); void lnet_print_hdr(lnet_hdr_t *hdr) diff --git a/drivers/staging/lustre/lnet/selftest/conctl.c b/drivers/staging/lustre/lnet/selftest/conctl.c index 556c837cf62cd..a534665403e57 100644 --- a/drivers/staging/lustre/lnet/selftest/conctl.c +++ b/drivers/staging/lustre/lnet/selftest/conctl.c @@ -925,5 +925,3 @@ out: return rc; } - -EXPORT_SYMBOL(lstcon_ioctl_entry); -- GitLab From 1dc563a682597b21f39e2ef9c0a87698935ad4fb Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sun, 8 Nov 2015 18:09:37 -0500 Subject: [PATCH 1882/2855] staging: lustre: update Intel copyright messages 2015 Update copyright messages in files modified by Intel employees in 2015 by non-trivial patches. Exclude patches that are only deleting code, renaming functions, or adding or removing whitespace. Signed-off-by: Andreas Dilger Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-7243 Reviewed-on: http://review.whamcloud.com/16758 Reviewed-by: James Nunez Reviewed-by: James Simmons Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs.h | 2 +- drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h | 3 ++- drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h | 2 +- drivers/staging/lustre/include/linux/lnet/lib-lnet.h | 2 +- drivers/staging/lustre/include/linux/lnet/lib-types.h | 2 +- drivers/staging/lustre/include/linux/lnet/nidstr.h | 2 +- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 +- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 2 +- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 2 +- drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c | 2 +- drivers/staging/lustre/lnet/lnet/acceptor.c | 2 +- drivers/staging/lustre/lnet/lnet/api-ni.c | 2 +- drivers/staging/lustre/lnet/lnet/config.c | 2 +- drivers/staging/lustre/lnet/lnet/lib-move.c | 2 +- drivers/staging/lustre/lnet/lnet/lib-ptl.c | 2 +- drivers/staging/lustre/lnet/lnet/lib-socket.c | 2 +- drivers/staging/lustre/lnet/lnet/module.c | 2 +- drivers/staging/lustre/lnet/lnet/router.c | 2 +- drivers/staging/lustre/lnet/selftest/brw_test.c | 2 +- drivers/staging/lustre/lnet/selftest/rpc.c | 2 +- drivers/staging/lustre/lustre/fid/fid_request.c | 2 +- drivers/staging/lustre/lustre/fid/lproc_fid.c | 2 +- drivers/staging/lustre/lustre/fld/fld_internal.h | 2 +- drivers/staging/lustre/lustre/fld/fld_request.c | 2 +- drivers/staging/lustre/lustre/fld/lproc_fld.c | 2 +- drivers/staging/lustre/lustre/include/cl_object.h | 2 +- drivers/staging/lustre/lustre/include/lprocfs_status.h | 2 +- drivers/staging/lustre/lustre/include/lu_object.h | 2 +- drivers/staging/lustre/lustre/include/lustre/ll_fiemap.h | 2 ++ drivers/staging/lustre/lustre/include/lustre/lustre_idl.h | 2 +- drivers/staging/lustre/lustre/include/lustre/lustre_user.h | 2 +- drivers/staging/lustre/lustre/include/lustre_dlm.h | 2 +- drivers/staging/lustre/lustre/include/lustre_export.h | 2 +- drivers/staging/lustre/lustre/include/lustre_fid.h | 2 +- drivers/staging/lustre/lustre/include/lustre_fld.h | 2 +- drivers/staging/lustre/lustre/include/lustre_ha.h | 2 +- drivers/staging/lustre/lustre/include/lustre_log.h | 2 +- drivers/staging/lustre/lustre/include/lustre_net.h | 2 +- drivers/staging/lustre/lustre/include/lustre_param.h | 2 +- drivers/staging/lustre/lustre/include/lustre_req_layout.h | 2 +- drivers/staging/lustre/lustre/include/obd.h | 2 +- drivers/staging/lustre/lustre/include/obd_class.h | 2 +- drivers/staging/lustre/lustre/include/obd_support.h | 2 +- drivers/staging/lustre/lustre/lclient/lcommon_cl.c | 2 +- drivers/staging/lustre/lustre/ldlm/ldlm_internal.h | 2 +- drivers/staging/lustre/lustre/ldlm/ldlm_lib.c | 2 +- drivers/staging/lustre/lustre/ldlm/ldlm_lock.c | 2 +- drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c | 2 +- drivers/staging/lustre/lustre/ldlm/ldlm_pool.c | 2 +- drivers/staging/lustre/lustre/ldlm/ldlm_request.c | 2 +- drivers/staging/lustre/lustre/ldlm/ldlm_resource.c | 2 +- drivers/staging/lustre/lustre/libcfs/fail.c | 2 +- drivers/staging/lustre/lustre/libcfs/libcfs_lock.c | 2 +- drivers/staging/lustre/lustre/libcfs/libcfs_string.c | 2 +- drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c | 3 ++- drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c | 2 +- drivers/staging/lustre/lustre/libcfs/module.c | 2 +- drivers/staging/lustre/lustre/llite/dcache.c | 2 +- drivers/staging/lustre/lustre/llite/dir.c | 2 +- drivers/staging/lustre/lustre/llite/file.c | 2 +- drivers/staging/lustre/lustre/llite/llite_internal.h | 2 +- drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- drivers/staging/lustre/lustre/llite/llite_mmap.c | 2 +- drivers/staging/lustre/lustre/llite/lproc_llite.c | 2 +- drivers/staging/lustre/lustre/llite/namei.c | 2 +- drivers/staging/lustre/lustre/llite/rw.c | 2 +- drivers/staging/lustre/lustre/llite/statahead.c | 2 +- drivers/staging/lustre/lustre/llite/vvp_dev.c | 2 +- drivers/staging/lustre/lustre/llite/vvp_internal.h | 2 ++ drivers/staging/lustre/lustre/llite/vvp_io.c | 2 +- drivers/staging/lustre/lustre/llite/vvp_lock.c | 2 ++ drivers/staging/lustre/lustre/llite/vvp_object.c | 2 +- drivers/staging/lustre/lustre/llite/vvp_page.c | 2 +- drivers/staging/lustre/lustre/llite/xattr.c | 2 +- drivers/staging/lustre/lustre/llite/xattr_cache.c | 2 ++ drivers/staging/lustre/lustre/lmv/lmv_intent.c | 2 +- drivers/staging/lustre/lustre/lmv/lmv_internal.h | 2 +- drivers/staging/lustre/lustre/lmv/lmv_obd.c | 2 +- drivers/staging/lustre/lustre/lov/lov_cl_internal.h | 2 +- drivers/staging/lustre/lustre/lov/lov_dev.c | 2 +- drivers/staging/lustre/lustre/lov/lov_ea.c | 2 +- drivers/staging/lustre/lustre/lov/lov_internal.h | 2 +- drivers/staging/lustre/lustre/lov/lov_io.c | 2 +- drivers/staging/lustre/lustre/lov/lov_merge.c | 2 +- drivers/staging/lustre/lustre/lov/lov_obd.c | 2 +- drivers/staging/lustre/lustre/lov/lov_object.c | 2 +- drivers/staging/lustre/lustre/lov/lov_offset.c | 2 +- drivers/staging/lustre/lustre/lov/lov_pack.c | 2 +- drivers/staging/lustre/lustre/lov/lov_page.c | 2 +- drivers/staging/lustre/lustre/lov/lov_request.c | 2 +- drivers/staging/lustre/lustre/lov/lovsub_dev.c | 2 ++ drivers/staging/lustre/lustre/lov/lovsub_object.c | 2 +- drivers/staging/lustre/lustre/lov/lproc_lov.c | 2 +- drivers/staging/lustre/lustre/mdc/lproc_mdc.c | 2 +- drivers/staging/lustre/lustre/mdc/mdc_internal.h | 2 +- drivers/staging/lustre/lustre/mdc/mdc_lib.c | 2 +- drivers/staging/lustre/lustre/mdc/mdc_locks.c | 2 +- drivers/staging/lustre/lustre/mdc/mdc_reint.c | 2 +- drivers/staging/lustre/lustre/mdc/mdc_request.c | 2 +- drivers/staging/lustre/lustre/mgc/mgc_request.c | 2 +- drivers/staging/lustre/lustre/obdclass/cl_io.c | 2 +- drivers/staging/lustre/lustre/obdclass/cl_object.c | 2 +- drivers/staging/lustre/lustre/obdclass/cl_page.c | 2 +- drivers/staging/lustre/lustre/obdclass/class_obd.c | 2 +- drivers/staging/lustre/lustre/obdclass/genops.c | 2 +- drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c | 2 +- drivers/staging/lustre/lustre/obdclass/llog.c | 2 +- drivers/staging/lustre/lustre/obdclass/llog_cat.c | 2 +- drivers/staging/lustre/lustre/obdclass/llog_internal.h | 2 +- drivers/staging/lustre/lustre/obdclass/llog_obd.c | 2 +- drivers/staging/lustre/lustre/obdclass/llog_swab.c | 2 +- drivers/staging/lustre/lustre/obdclass/lprocfs_status.c | 2 +- drivers/staging/lustre/lustre/obdclass/lu_object.c | 2 +- drivers/staging/lustre/lustre/obdclass/obd_config.c | 2 +- drivers/staging/lustre/lustre/obdclass/obd_mount.c | 2 +- drivers/staging/lustre/lustre/obdecho/echo_client.c | 2 +- drivers/staging/lustre/lustre/osc/lproc_osc.c | 2 +- drivers/staging/lustre/lustre/osc/osc_cache.c | 2 +- drivers/staging/lustre/lustre/osc/osc_cl_internal.h | 2 +- drivers/staging/lustre/lustre/osc/osc_dev.c | 2 +- drivers/staging/lustre/lustre/osc/osc_internal.h | 2 +- drivers/staging/lustre/lustre/osc/osc_io.c | 2 +- drivers/staging/lustre/lustre/osc/osc_lock.c | 2 +- drivers/staging/lustre/lustre/osc/osc_object.c | 2 +- drivers/staging/lustre/lustre/osc/osc_page.c | 2 +- drivers/staging/lustre/lustre/osc/osc_quota.c | 2 +- drivers/staging/lustre/lustre/osc/osc_request.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/client.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/events.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/import.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/layout.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/llog_client.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/niobuf.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/pers.c | 2 ++ drivers/staging/lustre/lustre/ptlrpc/pinger.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h | 2 +- drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/recover.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/sec_config.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/sec_plain.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/service.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/wiretest.c | 2 +- 144 files changed, 152 insertions(+), 138 deletions(-) diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h index 4d74e8af5088d..049f6a9a638b0 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h index 7878678474837..1530b0458a614 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h @@ -22,7 +22,8 @@ */ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, Intel Corporation. + * + * Copyright (c) 2012, 2015 Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h index f14db92346bae..c3f2332fa043b 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015 Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index b61d5045a5666..b67a6607bb3b3 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -23,7 +23,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012 - 2015, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index d792c4adb0ca4..3bb9468e0b9d5 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -23,7 +23,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012 - 2015, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/include/linux/lnet/nidstr.h b/drivers/staging/lustre/include/linux/lnet/nidstr.h index 46ad9147ad2a4..4fc9ddce829d1 100644 --- a/drivers/staging/lustre/include/linux/lnet/nidstr.h +++ b/drivers/staging/lustre/include/linux/lnet/nidstr.h @@ -23,7 +23,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011 - 2015, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ #ifndef _LNET_NIDSTRINGS_H #define _LNET_NIDSTRINGS_H diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index de0f85f8a2f97..72af486b65df7 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h index 263db37de7c80..025faa9f86b35 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index 260750354a417..c7b9ccb13f1c7 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index ebde0369edc81..05aa90ea597a7 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c index 92ca1dd64076f..fed57d90028de 100644 --- a/drivers/staging/lustre/lnet/lnet/acceptor.c +++ b/drivers/staging/lustre/lnet/lnet/acceptor.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 9f78dc8d7a267..362282fa00bf2 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 5390ee9963ab4..284a3c271bc60 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 03a721e1bb3da..fb8f7be043ecc 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c index b4f573ab62ccc..bd7b071b28732 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c @@ -21,7 +21,7 @@ * GPL HEADER END */ /* - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lnet/lnet/lib-socket.c b/drivers/staging/lustre/lnet/lnet/lib-socket.c index 6f7ef4c737cdc..589ecc84d1b87 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-socket.c +++ b/drivers/staging/lustre/lnet/lnet/lib-socket.c @@ -23,7 +23,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, 2015 Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lnet/lnet/module.c b/drivers/staging/lustre/lnet/lnet/module.c index ac2fdf05a5fd9..c93c00752a4cc 100644 --- a/drivers/staging/lustre/lnet/lnet/module.c +++ b/drivers/staging/lustre/lnet/lnet/module.c @@ -27,7 +27,7 @@ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 4ea651c6db3a4..f5faa414d2508 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. * * This file is part of Portals * http://sourceforge.net/projects/sandiaportals/ diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c index 0f262267e01ed..1f04cc1fc31c3 100644 --- a/drivers/staging/lustre/lnet/selftest/brw_test.c +++ b/drivers/staging/lustre/lnet/selftest/brw_test.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c index 86de68033f85b..2acf6ec717beb 100644 --- a/drivers/staging/lustre/lnet/selftest/rpc.c +++ b/drivers/staging/lustre/lnet/selftest/rpc.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/fid/fid_request.c b/drivers/staging/lustre/lustre/fid/fid_request.c index fe7c39afd1d9e..ff8f38dc10ce0 100644 --- a/drivers/staging/lustre/lustre/fid/fid_request.c +++ b/drivers/staging/lustre/lustre/fid/fid_request.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2013, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/fid/lproc_fid.c b/drivers/staging/lustre/lustre/fid/lproc_fid.c index ce90c1c54a637..39f2aa32e9846 100644 --- a/drivers/staging/lustre/lustre/fid/lproc_fid.c +++ b/drivers/staging/lustre/lustre/fid/lproc_fid.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/fld/fld_internal.h b/drivers/staging/lustre/lustre/fld/fld_internal.h index 959b8e6bba951..12eb1647b4bf3 100644 --- a/drivers/staging/lustre/lustre/fld/fld_internal.h +++ b/drivers/staging/lustre/lustre/fld/fld_internal.h @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, 2013, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/fld/fld_request.c b/drivers/staging/lustre/lustre/fld/fld_request.c index 469df685f392d..d92c01b748658 100644 --- a/drivers/staging/lustre/lustre/fld/fld_request.c +++ b/drivers/staging/lustre/lustre/fld/fld_request.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2013, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/fld/lproc_fld.c b/drivers/staging/lustre/lustre/fld/lproc_fld.c index 603f56e6095ba..41ceaa8198a7f 100644 --- a/drivers/staging/lustre/lustre/fld/lproc_fld.c +++ b/drivers/staging/lustre/lustre/fld/lproc_fld.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, 2013, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index 73564f8e38845..1e7391ac81cce 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h index f18c0c75ef1ec..0ac8e0edcc484 100644 --- a/drivers/staging/lustre/lustre/include/lprocfs_status.h +++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/lu_object.h b/drivers/staging/lustre/lustre/include/lu_object.h index fa78689748a9e..1d79341a495d1 100644 --- a/drivers/staging/lustre/lustre/include/lu_object.h +++ b/drivers/staging/lustre/lustre/include/lu_object.h @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/lustre/ll_fiemap.h b/drivers/staging/lustre/lustre/include/lustre/ll_fiemap.h index 06ce8c9ae9ad4..09088f40ba88b 100644 --- a/drivers/staging/lustre/lustre/include/lustre/ll_fiemap.h +++ b/drivers/staging/lustre/lustre/include/lustre/ll_fiemap.h @@ -26,6 +26,8 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2014, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h index 0b721c65c2a3e..b064b5821e3fb 100644 --- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h +++ b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h index 80f8ec5294248..2b4dd656d5f58 100644 --- a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h +++ b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2010, 2012, Intel Corporation. + * Copyright (c) 2010, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h index 138479a9edc1f..9b319f1df0257 100644 --- a/drivers/staging/lustre/lustre/include/lustre_dlm.h +++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2010, 2012, Intel Corporation. + * Copyright (c) 2010, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/lustre_export.h b/drivers/staging/lustre/lustre/include/lustre_export.h index 1daf4c572415c..311e5aa9b0dbf 100644 --- a/drivers/staging/lustre/lustre/include/lustre_export.h +++ b/drivers/staging/lustre/lustre/include/lustre_export.h @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/lustre_fid.h b/drivers/staging/lustre/lustre/include/lustre_fid.h index 47c3f37502409..9b1a9c6951139 100644 --- a/drivers/staging/lustre/lustre/include/lustre_fid.h +++ b/drivers/staging/lustre/lustre/include/lustre_fid.h @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/lustre_fld.h b/drivers/staging/lustre/lustre/include/lustre_fld.h index d8b3db9cdebaa..5511626249746 100644 --- a/drivers/staging/lustre/lustre/include/lustre_fld.h +++ b/drivers/staging/lustre/lustre/include/lustre_fld.h @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2013, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/lustre_ha.h b/drivers/staging/lustre/lustre/include/lustre_ha.h index 49dfbb14f381a..5488a698dabd0 100644 --- a/drivers/staging/lustre/lustre/include/lustre_ha.h +++ b/drivers/staging/lustre/lustre/include/lustre_ha.h @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/lustre_log.h b/drivers/staging/lustre/lustre/include/lustre_log.h index 1de0c4d6f7f77..53af4cd1adcce 100644 --- a/drivers/staging/lustre/lustre/include/lustre_log.h +++ b/drivers/staging/lustre/lustre/include/lustre_log.h @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h index 0127f45ca0c3f..d834ddd8183bc 100644 --- a/drivers/staging/lustre/lustre/include/lustre_net.h +++ b/drivers/staging/lustre/lustre/include/lustre_net.h @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2010, 2012, Intel Corporation. + * Copyright (c) 2010, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/lustre_param.h b/drivers/staging/lustre/lustre/include/lustre_param.h index 8f6c0b26cfaba..383fe6febe4ba 100644 --- a/drivers/staging/lustre/lustre/include/lustre_param.h +++ b/drivers/staging/lustre/lustre/include/lustre_param.h @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/lustre_req_layout.h b/drivers/staging/lustre/lustre/include/lustre_req_layout.h index df292f6d4a85e..46a662f89322f 100644 --- a/drivers/staging/lustre/lustre/include/lustre_req_layout.h +++ b/drivers/staging/lustre/lustre/include/lustre_req_layout.h @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index 5c90b59cf0db5..bcbe61301713c 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index 0b7e90ac7818d..97d80397503c6 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/include/obd_support.h b/drivers/staging/lustre/lustre/include/obd_support.h index a22a5308fb48d..d031437c0528e 100644 --- a/drivers/staging/lustre/lustre/include/obd_support.h +++ b/drivers/staging/lustre/lustre/include/obd_support.h @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c index 12c7f0e669d40..34dde7dede74d 100644 --- a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h index db3c9b7af7d50..849cc98df7ddc 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c index ccce1e5031202..3c8d4413d9768 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2010, 2012, Intel Corporation. + * Copyright (c) 2010, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c index 7f8c70056ffde..cf9ec0cfe2478 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2010, 2012, Intel Corporation. + * Copyright (c) 2010, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c index ca115119501ae..79aeb2bf6c8e8 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2010, 2012, Intel Corporation. + * Copyright (c) 2010, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c index e59b2864180fd..3d7c137d223a4 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2010, 2012, Intel Corporation. + * Copyright (c) 2010, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c index fdf81b87aad7b..b9eb37762434a 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2010, 2012, Intel Corporation. + * Copyright (c) 2010, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c index b55a4f0eb1d5a..0ae610015b7c9 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2010, 2012, Intel Corporation. + * Copyright (c) 2010, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/libcfs/fail.c b/drivers/staging/lustre/lustre/libcfs/fail.c index ea059b012a669..27831432d69a4 100644 --- a/drivers/staging/lustre/lustre/libcfs/fail.c +++ b/drivers/staging/lustre/lustre/libcfs/fail.c @@ -26,7 +26,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/libcfs/libcfs_lock.c b/drivers/staging/lustre/lustre/libcfs/libcfs_lock.c index 94bc007850005..15782d9e6aa96 100644 --- a/drivers/staging/lustre/lustre/libcfs/libcfs_lock.c +++ b/drivers/staging/lustre/lustre/libcfs/libcfs_lock.c @@ -21,7 +21,7 @@ * GPL HEADER END */ /* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015 Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/libcfs/libcfs_string.c b/drivers/staging/lustre/lustre/libcfs/libcfs_string.c index d40be53967694..205a3ed435a88 100644 --- a/drivers/staging/lustre/lustre/libcfs/libcfs_string.c +++ b/drivers/staging/lustre/lustre/libcfs/libcfs_string.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015 Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c index 58a4034be1b85..e52afe35e7eae 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c @@ -22,7 +22,8 @@ */ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, Intel Corporation. + * + * Copyright (c) 2012, 2015 Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c index c74c80915dca8..68515d9130c15 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/libcfs/module.c b/drivers/staging/lustre/lustre/libcfs/module.c index 75247e920994e..329d78ce272d4 100644 --- a/drivers/staging/lustre/lustre/libcfs/module.c +++ b/drivers/staging/lustre/lustre/libcfs/module.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015 Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/dcache.c b/drivers/staging/lustre/lustre/llite/dcache.c index 80cba04484994..3d6745e63fe37 100644 --- a/drivers/staging/lustre/lustre/llite/dcache.c +++ b/drivers/staging/lustre/lustre/llite/dcache.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index 5c2ef92809e64..7b355319079c3 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index 02f27593013e3..baffd5281af35 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 157c32840e063..eb8d6a7520fd7 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 4a8c759fef42c..1db93af62badd 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/llite_mmap.c b/drivers/staging/lustre/lustre/llite/llite_mmap.c index 7df978371c9a3..bbae95c9feed5 100644 --- a/drivers/staging/lustre/lustre/llite/llite_mmap.c +++ b/drivers/staging/lustre/lustre/llite/llite_mmap.c @@ -27,7 +27,7 @@ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c index 190fc44114e1c..f134ad9d23f0c 100644 --- a/drivers/staging/lustre/lustre/llite/lproc_llite.c +++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 2ca22001a534d..14370b97fe5c9 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index 8184d9d1da527..95cdb0c58b04d 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c index caee0a6f8b849..88ffd8e3abdb6 100644 --- a/drivers/staging/lustre/lustre/llite/statahead.c +++ b/drivers/staging/lustre/lustre/llite/statahead.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c index d16d6cfce81a6..fdca4ec0555de 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_dev.c +++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index b5a6661d47d5e..2e39533a45f8d 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -26,6 +26,8 @@ /* * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2013, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index 37773c181729e..346b8a19dacde 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/vvp_lock.c b/drivers/staging/lustre/lustre/llite/vvp_lock.c index f7b1144aadeea..ff0948043c7aa 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_lock.c +++ b/drivers/staging/lustre/lustre/llite/vvp_lock.c @@ -26,6 +26,8 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2014, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/vvp_object.c b/drivers/staging/lustre/lustre/llite/vvp_object.c index e13afb7e8dca9..c82714ea898e5 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_object.c +++ b/drivers/staging/lustre/lustre/llite/vvp_object.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c index 92f60c350f35b..99c0d7aee921d 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_page.c +++ b/drivers/staging/lustre/lustre/llite/vvp_page.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/xattr.c b/drivers/staging/lustre/lustre/llite/xattr.c index 4b7eb33f7d017..92f579e51cf2e 100644 --- a/drivers/staging/lustre/lustre/llite/xattr.c +++ b/drivers/staging/lustre/lustre/llite/xattr.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/llite/xattr_cache.c b/drivers/staging/lustre/lustre/llite/xattr_cache.c index e1e599ceb173c..d1402762a0b28 100644 --- a/drivers/staging/lustre/lustre/llite/xattr_cache.c +++ b/drivers/staging/lustre/lustre/llite/xattr_cache.c @@ -1,6 +1,8 @@ /* * Copyright 2012 Xyratex Technology Limited * + * Copyright (c) 2013, 2015, Intel Corporation. + * * Author: Andrew Perepechko * */ diff --git a/drivers/staging/lustre/lustre/lmv/lmv_intent.c b/drivers/staging/lustre/lustre/lmv/lmv_intent.c index 3c585aea5bb83..66de27f1d289b 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_intent.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_intent.c @@ -27,7 +27,7 @@ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lmv/lmv_internal.h b/drivers/staging/lustre/lustre/lmv/lmv_internal.h index 467cfb3e7fca4..eb8e673cbc3f3 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_internal.h +++ b/drivers/staging/lustre/lustre/lmv/lmv_internal.h @@ -27,7 +27,7 @@ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c index a4de9a3fd847c..bbafe0a710d8a 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c @@ -27,7 +27,7 @@ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h index 1c0fe65243e15..66a2492c1cc38 100644 --- a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h +++ b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015 Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lov/lov_dev.c b/drivers/staging/lustre/lustre/lov/lov_dev.c index 2e8b566458f6d..3733fdc88c8c8 100644 --- a/drivers/staging/lustre/lustre/lov/lov_dev.c +++ b/drivers/staging/lustre/lustre/lov/lov_dev.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lov/lov_ea.c b/drivers/staging/lustre/lustre/lov/lov_ea.c index 34c1346f0dc76..b3c9c85aab9d1 100644 --- a/drivers/staging/lustre/lustre/lov/lov_ea.c +++ b/drivers/staging/lustre/lustre/lov/lov_ea.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lov/lov_internal.h b/drivers/staging/lustre/lustre/lov/lov_internal.h index b8028735e5683..2d00bad58e351 100644 --- a/drivers/staging/lustre/lustre/lov/lov_internal.h +++ b/drivers/staging/lustre/lustre/lov/lov_internal.h @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lov/lov_io.c b/drivers/staging/lustre/lustre/lov/lov_io.c index 5e6228b9ca011..93fe69eb2560f 100644 --- a/drivers/staging/lustre/lustre/lov/lov_io.c +++ b/drivers/staging/lustre/lustre/lov/lov_io.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lov/lov_merge.c b/drivers/staging/lustre/lustre/lov/lov_merge.c index dd1cf3d2d039d..97115bec7ccab 100644 --- a/drivers/staging/lustre/lustre/lov/lov_merge.c +++ b/drivers/staging/lustre/lustre/lov/lov_merge.c @@ -27,7 +27,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c index b52609aead4cf..6c2bdfe9cdcf7 100644 --- a/drivers/staging/lustre/lustre/lov/lov_obd.c +++ b/drivers/staging/lustre/lustre/lov/lov_obd.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lov/lov_object.c b/drivers/staging/lustre/lustre/lov/lov_object.c index c7ff817bb6fb0..3b79ebc8eccf6 100644 --- a/drivers/staging/lustre/lustre/lov/lov_object.c +++ b/drivers/staging/lustre/lustre/lov/lov_object.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lov/lov_offset.c b/drivers/staging/lustre/lustre/lov/lov_offset.c index 9c8c77c05a8a7..aa520aa76e091 100644 --- a/drivers/staging/lustre/lustre/lov/lov_offset.c +++ b/drivers/staging/lustre/lustre/lov/lov_offset.c @@ -27,7 +27,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lov/lov_pack.c b/drivers/staging/lustre/lustre/lov/lov_pack.c index 2fb1e974cc70b..198523139b3b5 100644 --- a/drivers/staging/lustre/lustre/lov/lov_pack.c +++ b/drivers/staging/lustre/lustre/lov/lov_pack.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lov/lov_page.c b/drivers/staging/lustre/lustre/lov/lov_page.c index 463cadbd9d40d..037ae91b74e7d 100644 --- a/drivers/staging/lustre/lustre/lov/lov_page.c +++ b/drivers/staging/lustre/lustre/lov/lov_page.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lov/lov_request.c b/drivers/staging/lustre/lustre/lov/lov_request.c index bb1a03fef60d9..42deda71f577c 100644 --- a/drivers/staging/lustre/lustre/lov/lov_request.c +++ b/drivers/staging/lustre/lustre/lov/lov_request.c @@ -27,7 +27,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lov/lovsub_dev.c b/drivers/staging/lustre/lustre/lov/lovsub_dev.c index 8bc04c8d3d600..f1795c3e2db52 100644 --- a/drivers/staging/lustre/lustre/lov/lovsub_dev.c +++ b/drivers/staging/lustre/lustre/lov/lovsub_dev.c @@ -26,6 +26,8 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2013, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lov/lovsub_object.c b/drivers/staging/lustre/lustre/lov/lovsub_object.c index d775e28d40973..5ba5ee1b86818 100644 --- a/drivers/staging/lustre/lustre/lov/lovsub_object.c +++ b/drivers/staging/lustre/lustre/lov/lovsub_object.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015 Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/lov/lproc_lov.c b/drivers/staging/lustre/lustre/lov/lproc_lov.c index a0be15c6b55ac..337241d84980a 100644 --- a/drivers/staging/lustre/lustre/lov/lproc_lov.c +++ b/drivers/staging/lustre/lustre/lov/lproc_lov.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015 Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c index 84e586223588e..38f267a60f59a 100644 --- a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c +++ b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/mdc/mdc_internal.h b/drivers/staging/lustre/lustre/mdc/mdc_internal.h index df50bdbcde19f..3d2997a161b61 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_internal.h +++ b/drivers/staging/lustre/lustre/mdc/mdc_internal.h @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, Intel Corporation. + * Copyright (c) 2011, 2015 Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/mdc/mdc_lib.c b/drivers/staging/lustre/lustre/mdc/mdc_lib.c index 227fc9ee0dcfb..7218532ffea31 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c index d4bf34b61f3a6..ef9a1e124ea48 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/mdc/mdc_reint.c b/drivers/staging/lustre/lustre/mdc/mdc_reint.c index c87c7d8efa074..ac7695a107530 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_reint.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_reint.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index e172be1bc1c6e..8baf726a983fa 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -27,7 +27,7 @@ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c index 2c48847276260..06dc2c3d36c29 100644 --- a/drivers/staging/lustre/lustre/mgc/mgc_request.c +++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c index e67cea7584052..ab7e110413399 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c index a1a6024220ffd..73ea8458af18b 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c index 2f569edd08114..61f28ebfc0589 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c index beb59f009cbe8..0975e443057c0 100644 --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c @@ -27,7 +27,7 @@ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c index 26f54f9503508..228c44c37c4a0 100644 --- a/drivers/staging/lustre/lustre/obdclass/genops.c +++ b/drivers/staging/lustre/lustre/obdclass/genops.c @@ -27,7 +27,7 @@ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c index 518288df4d53d..42fc26f4ae257 100644 --- a/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c +++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c @@ -27,7 +27,7 @@ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/obdclass/llog.c b/drivers/staging/lustre/lustre/obdclass/llog.c index 7cb55ef79737b..f956d7ed67854 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog.c +++ b/drivers/staging/lustre/lustre/obdclass/llog.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/obdclass/llog_cat.c b/drivers/staging/lustre/lustre/obdclass/llog_cat.c index c442cae5fd375..0f05e9c4a5b26 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog_cat.c +++ b/drivers/staging/lustre/lustre/obdclass/llog_cat.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/obdclass/llog_internal.h b/drivers/staging/lustre/lustre/obdclass/llog_internal.h index b9fe4b01c690a..7fb48dda355e9 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog_internal.h +++ b/drivers/staging/lustre/lustre/obdclass/llog_internal.h @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/obdclass/llog_obd.c b/drivers/staging/lustre/lustre/obdclass/llog_obd.c index 3900b9d4007e7..9bc51998c05c8 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog_obd.c +++ b/drivers/staging/lustre/lustre/obdclass/llog_obd.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/obdclass/llog_swab.c b/drivers/staging/lustre/lustre/obdclass/llog_swab.c index 9354f75b5cab7..3aa7393b20c36 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog_swab.c +++ b/drivers/staging/lustre/lustre/obdclass/llog_swab.c @@ -27,7 +27,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c index dda5ad105f2e3..51fe15f5d6870 100644 --- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c +++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c index 0193608a930ad..76ad9dc0447aa 100644 --- a/drivers/staging/lustre/lustre/obdclass/lu_object.c +++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/obdclass/obd_config.c b/drivers/staging/lustre/lustre/obdclass/obd_config.c index c231e0da0e2ae..49cdc647910c7 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_config.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_config.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/obdclass/obd_mount.c b/drivers/staging/lustre/lustre/obdclass/obd_mount.c index 7617c57d16e0c..b5aa8168dbffa 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_mount.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_mount.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c index 46822183b9f5c..b3463040c1ed2 100644 --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/osc/lproc_osc.c b/drivers/staging/lustre/lustre/osc/lproc_osc.c index c4d44e70f1d71..1091536fc90d3 100644 --- a/drivers/staging/lustre/lustre/osc/lproc_osc.c +++ b/drivers/staging/lustre/lustre/osc/lproc_osc.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index b1d1a87f05e33..46cfde4b139fc 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. * */ /* diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h index d2d68452d3827..415c27e4ab660 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/osc/osc_dev.c b/drivers/staging/lustre/lustre/osc/osc_dev.c index 69b523c0f5702..7078cc57d8b9a 100644 --- a/drivers/staging/lustre/lustre/osc/osc_dev.c +++ b/drivers/staging/lustre/lustre/osc/osc_dev.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h b/drivers/staging/lustre/lustre/osc/osc_internal.h index db2ee9c23b42d..a4c61463b1c72 100644 --- a/drivers/staging/lustre/lustre/osc/osc_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_internal.h @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/osc/osc_io.c b/drivers/staging/lustre/lustre/osc/osc_io.c index d413496c0f632..abd0beb483fef 100644 --- a/drivers/staging/lustre/lustre/osc/osc_io.c +++ b/drivers/staging/lustre/lustre/osc/osc_io.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c index 194490dcaca9e..71f2810d18b97 100644 --- a/drivers/staging/lustre/lustre/osc/osc_lock.c +++ b/drivers/staging/lustre/lustre/osc/osc_lock.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/osc/osc_object.c b/drivers/staging/lustre/lustre/osc/osc_object.c index ba57f8df5c7f7..c29a0d45ffed2 100644 --- a/drivers/staging/lustre/lustre/osc/osc_object.c +++ b/drivers/staging/lustre/lustre/osc/osc_object.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c index 61eaf7172fdf8..2439d804fe75c 100644 --- a/drivers/staging/lustre/lustre/osc/osc_page.c +++ b/drivers/staging/lustre/lustre/osc/osc_page.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/osc/osc_quota.c b/drivers/staging/lustre/lustre/osc/osc_quota.c index 199783103f711..e70e7961d7630 100644 --- a/drivers/staging/lustre/lustre/osc/osc_quota.c +++ b/drivers/staging/lustre/lustre/osc/osc_quota.c @@ -23,7 +23,7 @@ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. * * Code originally extracted from quota directory */ diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index d6c1447f6bd95..b2642a7988570 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c index a9f1bf536da9b..efdda09507bf1 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/client.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/events.c b/drivers/staging/lustre/lustre/ptlrpc/events.c index 9c2fd34e2eb9b..990156986986c 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/events.c +++ b/drivers/staging/lustre/lustre/ptlrpc/events.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015 Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c index bfa410f7e773f..f752c789bda01 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/import.c +++ b/drivers/staging/lustre/lustre/ptlrpc/import.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/layout.c b/drivers/staging/lustre/lustre/ptlrpc/layout.c index d7c4f47808bd1..c0e613c23854c 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/layout.c +++ b/drivers/staging/lustre/lustre/ptlrpc/layout.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/llog_client.c b/drivers/staging/lustre/lustre/ptlrpc/llog_client.c index 5122205cbb99c..e87702073f1fe 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/llog_client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/llog_client.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c index 2aecab21e3e1a..cc55b7973721e 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c +++ b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c index 09ddeef6ba484..c5d7ff5cbd732 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c +++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/pers.c b/drivers/staging/lustre/lustre/ptlrpc/pers.c index 2a2a9fb6549ce..ec3af109a1d7c 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pers.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pers.c @@ -26,6 +26,8 @@ /* * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2014, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c index 5c719f175657c..fb2d5236a971d 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h index 833ed944125e1..8f67e0562b732 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c index ac87aa12bd7e7..60fb0ced7137c 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/recover.c b/drivers/staging/lustre/lustre/ptlrpc/recover.c index 7b1d72947330a..db6626cab6f2f 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/recover.c +++ b/drivers/staging/lustre/lustre/ptlrpc/recover.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c index cd8a9987f7ac9..6152c1b766c3d 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_config.c b/drivers/staging/lustre/lustre/ptlrpc/sec_config.c index 7a206705865b7..4b0b81c115ee9 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_config.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_config.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c index f448b4567af0e..905a41451ca34 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c index f45898f17793b..8598300a61d1a 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/service.c +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2010, 2012, Intel Corporation. + * Copyright (c) 2010, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/wiretest.c b/drivers/staging/lustre/lustre/ptlrpc/wiretest.c index 40f720ca3b140..61d9ca93c53ad 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/wiretest.c +++ b/drivers/staging/lustre/lustre/ptlrpc/wiretest.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ -- GitLab From f11e1de21a26ed30171f770e894a9cf0bfa31ffd Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Sun, 8 Nov 2015 23:27:15 -0500 Subject: [PATCH 1883/2855] staging: lustre: remove {linux,posix}-tracefile.h Move the definition of the trace buffer type enum in libcfs/libcfs/tracefile.h. Remove the then unneeded headers libcfs/libcfs/linux/linux-tracefile.h and libcfs/libcfs/posix/posix-tracefile.h. Signed-off-by: John L. Hammond Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-2675 Reviewed-on: http://review.whamcloud.com/11983 Reviewed-by: Bob Glossman Reviewed-by: James Simmons Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/libcfs/linux/linux-tracefile.h | 48 ------------------- .../staging/lustre/lustre/libcfs/tracefile.h | 7 ++- 2 files changed, 6 insertions(+), 49 deletions(-) delete mode 100644 drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.h diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.h b/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.h deleted file mode 100644 index ba84e4ffddd1e..0000000000000 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - */ - -#ifndef __LIBCFS_LINUX_TRACEFILE_H__ -#define __LIBCFS_LINUX_TRACEFILE_H__ - -/** - * three types of trace_data in linux - */ -typedef enum { - CFS_TCD_TYPE_PROC = 0, - CFS_TCD_TYPE_SOFTIRQ, - CFS_TCD_TYPE_IRQ, - CFS_TCD_TYPE_MAX -} cfs_trace_buf_type_t; - -#endif diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.h b/drivers/staging/lustre/lustre/libcfs/tracefile.h index 6b37798336f23..b71b94fd7c351 100644 --- a/drivers/staging/lustre/lustre/libcfs/tracefile.h +++ b/drivers/staging/lustre/lustre/libcfs/tracefile.h @@ -39,7 +39,12 @@ #include "../../include/linux/libcfs/libcfs.h" -#include "linux/linux-tracefile.h" +typedef enum { + CFS_TCD_TYPE_PROC = 0, + CFS_TCD_TYPE_SOFTIRQ, + CFS_TCD_TYPE_IRQ, + CFS_TCD_TYPE_MAX +} cfs_trace_buf_type_t; /* trace file lock routines */ -- GitLab From bc2105370e6efdcc7648390246df4131a13e5016 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Sun, 8 Nov 2015 23:27:16 -0500 Subject: [PATCH 1884/2855] staging: lustre: remove obsolete comment in tracefile.h Remove comment about tracefile handling for user land version of libcfs that no longer exist. Broken out of patch http://review.whamcloud.com/11983. Signed-off-by: John L. Hammond Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-2675 Reviewed-on: http://review.whamcloud.com/11983 Reviewed-by: Bob Glossman Reviewed-by: James Simmons Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/tracefile.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.h b/drivers/staging/lustre/lustre/libcfs/tracefile.h index b71b94fd7c351..7bf1471a54fb2 100644 --- a/drivers/staging/lustre/lustre/libcfs/tracefile.h +++ b/drivers/staging/lustre/lustre/libcfs/tracefile.h @@ -256,13 +256,6 @@ void cfs_print_to_console(struct ptldebug_header *hdr, int mask, int cfs_trace_lock_tcd(struct cfs_trace_cpu_data *tcd, int walking); void cfs_trace_unlock_tcd(struct cfs_trace_cpu_data *tcd, int walking); -/** - * trace_buf_type_t, trace_buf_idx_get() and trace_console_buffers[][] - * are not public libcfs API; they should be defined in - * platform-specific tracefile include files - * (see, for example, linux-tracefile.h). - */ - extern char *cfs_trace_console_buffers[NR_CPUS][CFS_TCD_TYPE_MAX]; cfs_trace_buf_type_t cfs_trace_buf_idx_get(void); -- GitLab From 97c2bb7bc5faf5e264c73bbe03517f2eac34b292 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Tue, 10 Nov 2015 00:24:17 +0530 Subject: [PATCH 1885/2855] staging: lustre: acl: Remove lustre_posix_acl_xattr_free wrapper Remove the wrapper function lustre_posix_acl_xattr_free() and replace its call in the file xattr with the function kfree() that it wrapped. Also, its prototype from the header lustre_eacl is removed as it is no longer of any use. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/lustre_eacl.h | 2 -- drivers/staging/lustre/lustre/llite/xattr.c | 5 ++++- drivers/staging/lustre/lustre/obdclass/acl.c | 9 --------- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lustre_eacl.h b/drivers/staging/lustre/lustre/include/lustre_eacl.h index fee4d2c75506d..0b66593a95263 100644 --- a/drivers/staging/lustre/lustre/include/lustre_eacl.h +++ b/drivers/staging/lustre/lustre/include/lustre_eacl.h @@ -76,8 +76,6 @@ extern int lustre_posix_acl_xattr_filter(posix_acl_xattr_header *header, size_t size, posix_acl_xattr_header **out); extern void -lustre_posix_acl_xattr_free(posix_acl_xattr_header *header, int size); -extern void lustre_ext_acl_xattr_free(ext_acl_xattr_header *header); extern ext_acl_xattr_header * lustre_acl_xattr_merge2ext(posix_acl_xattr_header *posix_header, int size, diff --git a/drivers/staging/lustre/lustre/llite/xattr.c b/drivers/staging/lustre/lustre/llite/xattr.c index 92f579e51cf2e..4d91538668acf 100644 --- a/drivers/staging/lustre/lustre/llite/xattr.c +++ b/drivers/staging/lustre/lustre/llite/xattr.c @@ -193,7 +193,10 @@ int ll_setxattr_common(struct inode *inode, const char *name, ll_i2suppgid(inode), &req); #ifdef CONFIG_FS_POSIX_ACL if (new_value != NULL) - lustre_posix_acl_xattr_free(new_value, size); + /* + * Release the posix ACL space. + */ + kfree(new_value); if (acl != NULL) lustre_ext_acl_xattr_free(acl); #endif diff --git a/drivers/staging/lustre/lustre/obdclass/acl.c b/drivers/staging/lustre/lustre/obdclass/acl.c index 2e20cf635b277..49ba8851c8ac7 100644 --- a/drivers/staging/lustre/lustre/obdclass/acl.c +++ b/drivers/staging/lustre/lustre/obdclass/acl.c @@ -235,15 +235,6 @@ _out: } EXPORT_SYMBOL(lustre_posix_acl_xattr_filter); -/* - * Release the posix ACL space. - */ -void lustre_posix_acl_xattr_free(posix_acl_xattr_header *header, int size) -{ - kfree(header); -} -EXPORT_SYMBOL(lustre_posix_acl_xattr_free); - /* * Release the extended ACL space. */ -- GitLab From c328ae39e5d66be956fbdfbb7fba544ed1552fe2 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Wed, 11 Nov 2015 14:29:07 +0530 Subject: [PATCH 1886/2855] staging: lustre: cl_io: Remove cl_lock_descr_fid wrapper Remove unnecessary wrapper function cl_lock_descr_fid() and replace all its calls with the function it wrapped. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/obdclass/cl_io.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c index ab7e110413399..08723a3f2880e 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c @@ -236,16 +236,11 @@ int cl_io_rw_init(const struct lu_env *env, struct cl_io *io, } EXPORT_SYMBOL(cl_io_rw_init); -static inline const struct lu_fid * -cl_lock_descr_fid(const struct cl_lock_descr *descr) -{ - return lu_object_fid(&descr->cld_obj->co_lu); -} - static int cl_lock_descr_sort(const struct cl_lock_descr *d0, const struct cl_lock_descr *d1) { - return lu_fid_cmp(cl_lock_descr_fid(d0), cl_lock_descr_fid(d1)) ?: + return lu_fid_cmp(lu_object_fid(&d0->cld_obj->co_lu), + lu_object_fid(&d1->cld_obj->co_lu)) ?: __diff_normalize(d0->cld_start, d1->cld_start); } @@ -254,7 +249,8 @@ static int cl_lock_descr_cmp(const struct cl_lock_descr *d0, { int ret; - ret = lu_fid_cmp(cl_lock_descr_fid(d0), cl_lock_descr_fid(d1)); + ret = lu_fid_cmp(lu_object_fid(&d0->cld_obj->co_lu), + lu_object_fid(&d1->cld_obj->co_lu)); if (ret) return ret; if (d0->cld_end < d1->cld_start) -- GitLab From 53f1a12768a55e53b2c40e00a8804b1edfa739b3 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Wed, 11 Nov 2015 15:43:28 +0530 Subject: [PATCH 1887/2855] staging: lustre: Remove cl_2queue_add wrapper Remove the wrapper function cl_2queue_add() and replace all its calls in different files with the function it wrapped. Also, comments are added wherever necessary to make the working of function clear. Prototype of the function is also removed from the header file as it is no longer needed. Signed-off-by: Shivani Bhardwaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/cl_object.h | 1 - drivers/staging/lustre/lustre/llite/rw26.c | 5 ++++- drivers/staging/lustre/lustre/llite/vvp_io.c | 2 +- drivers/staging/lustre/lustre/obdclass/cl_io.c | 14 ++++---------- .../staging/lustre/lustre/obdecho/echo_client.c | 6 ++++-- 5 files changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index 1e7391ac81cce..bd7acc2a12193 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -3127,7 +3127,6 @@ void cl_page_list_disown (const struct lu_env *env, struct cl_io *io, struct cl_page_list *plist); void cl_2queue_init (struct cl_2queue *queue); -void cl_2queue_add (struct cl_2queue *queue, struct cl_page *page); void cl_2queue_disown (const struct lu_env *env, struct cl_io *io, struct cl_2queue *queue); void cl_2queue_discard (const struct lu_env *env, diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index 3da4c01e21596..39fa13b74cbda 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -298,7 +298,10 @@ ssize_t ll_direct_rw_pages(const struct lu_env *env, struct cl_io *io, } if (likely(do_io)) { - cl_2queue_add(queue, clp); + /* + * Add a page to the incoming page list of 2-queue. + */ + cl_page_list_add(&queue->c2_qin, clp); /* * Set page clip to tell transfer formation engine diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index 346b8a19dacde..f68e972886cae 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -849,7 +849,7 @@ static int vvp_io_read_page(const struct lu_env *env, * Add page into the queue even when it is marked uptodate above. * this will unlock it automatically as part of cl_page_list_disown(). */ - cl_2queue_add(queue, page); + cl_page_list_add(&queue->c2_qin, page); if (sbi->ll_ra_info.ra_max_pages_per_file && sbi->ll_ra_info.ra_max_pages) ll_readahead(env, io, ras, diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c index 08723a3f2880e..63246ba36798d 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c @@ -1211,15 +1211,6 @@ void cl_2queue_init(struct cl_2queue *queue) } EXPORT_SYMBOL(cl_2queue_init); -/** - * Add a page to the incoming page list of 2-queue. - */ -void cl_2queue_add(struct cl_2queue *queue, struct cl_page *page) -{ - cl_page_list_add(&queue->c2_qin, page); -} -EXPORT_SYMBOL(cl_2queue_add); - /** * Disown pages in both lists of a 2-queue. */ @@ -1258,7 +1249,10 @@ EXPORT_SYMBOL(cl_2queue_fini); void cl_2queue_init_page(struct cl_2queue *queue, struct cl_page *page) { cl_2queue_init(queue); - cl_2queue_add(queue, page); + /* + * Add a page to the incoming page list of 2-queue. + */ + cl_page_list_add(&queue->c2_qin, page); } EXPORT_SYMBOL(cl_2queue_init_page); diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c index b3463040c1ed2..7b53f7dd1797c 100644 --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c @@ -1228,8 +1228,10 @@ static int cl_echo_object_brw(struct echo_object *eco, int rw, u64 offset, cl_page_put(env, clp); break; } - - cl_2queue_add(queue, clp); + /* + * Add a page to the incoming page list of 2-queue. + */ + cl_page_list_add(&queue->c2_qin, clp); /* drop the reference count for cl_page_find, so that the page * will be freed in cl_2queue_fini. */ -- GitLab From d2d32738ded3825a6608e0d34e276c30c96e63b2 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 14 Nov 2015 13:30:34 +0100 Subject: [PATCH 1888/2855] lustre: constify inode_operations structures The inode_operations structures are never modified, so declare them as const, like all the other inode_operations structures. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/file.c | 2 +- drivers/staging/lustre/lustre/llite/llite_internal.h | 4 ++-- drivers/staging/lustre/lustre/llite/symlink.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index baffd5281af35..c92d58b770ec2 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -3139,7 +3139,7 @@ struct file_operations ll_file_operations_noflock = { .lock = ll_file_noflock }; -struct inode_operations ll_file_inode_operations = { +const struct inode_operations ll_file_inode_operations = { .setattr = ll_setattr, .getattr = ll_getattr, .permission = ll_inode_permission, diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index eb8d6a7520fd7..ee8a1d67d1911 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -705,7 +705,7 @@ extern const struct address_space_operations ll_aops; extern struct file_operations ll_file_operations; extern struct file_operations ll_file_operations_flock; extern struct file_operations ll_file_operations_noflock; -extern struct inode_operations ll_file_inode_operations; +extern const struct inode_operations ll_file_inode_operations; int ll_have_md_lock(struct inode *inode, __u64 *bits, ldlm_mode_t l_req_mode); ldlm_mode_t ll_take_md_lock(struct inode *inode, __u64 bits, @@ -805,7 +805,7 @@ struct inode *search_inode_for_lustre(struct super_block *sb, const struct lu_fid *fid); /* llite/symlink.c */ -extern struct inode_operations ll_fast_symlink_inode_operations; +extern const struct inode_operations ll_fast_symlink_inode_operations; /* llite/llite_close.c */ struct ll_close_queue { diff --git a/drivers/staging/lustre/lustre/llite/symlink.c b/drivers/staging/lustre/lustre/llite/symlink.c index 69b203651905e..32c4cf48b3183 100644 --- a/drivers/staging/lustre/lustre/llite/symlink.c +++ b/drivers/staging/lustre/lustre/llite/symlink.c @@ -146,7 +146,7 @@ static void ll_put_link(struct inode *unused, void *cookie) ptlrpc_req_finished(cookie); } -struct inode_operations ll_fast_symlink_inode_operations = { +const struct inode_operations ll_fast_symlink_inode_operations = { .readlink = generic_readlink, .setattr = ll_setattr, .follow_link = ll_follow_link, -- GitLab From 71872e9cc2af4dca1903ebc57daa15f08c795d86 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Tue, 17 Nov 2015 22:06:40 +0200 Subject: [PATCH 1889/2855] staging: lustre: hash.c: Replace IS_PO2 by is_power_of_2 Replaces IS_PO2 by is_power_of_2. It is more accurate to use is_power_of_2 since it returns 1 for numbers that are powers of 2 only whereas IS_PO2 returns 1 for 0 and numbers that are powers of 2. Reviewed-by: Andreas Dilger Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/hash.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/libcfs/hash.c b/drivers/staging/lustre/lustre/libcfs/hash.c index d285117af3ada..4d50510434be5 100644 --- a/drivers/staging/lustre/lustre/libcfs/hash.c +++ b/drivers/staging/lustre/lustre/libcfs/hash.c @@ -107,6 +107,7 @@ * table. Also, user can break the iteration by return 1 in callback. */ #include +#include #include "../../include/linux/libcfs/libcfs.h" @@ -1777,7 +1778,7 @@ cfs_hash_rehash_cancel_locked(struct cfs_hash *hs) for (i = 2; cfs_hash_is_rehashing(hs); i++) { cfs_hash_unlock(hs, 1); /* raise console warning while waiting too long */ - CDEBUG(IS_PO2(i >> 3) ? D_WARNING : D_INFO, + CDEBUG(is_power_of_2(i >> 3) ? D_WARNING : D_INFO, "hash %s is still rehashing, rescheded %d\n", hs->hs_name, i - 1); cond_resched(); -- GitLab From d4891039904fa25edf1ca793a0469633ed81df3f Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Tue, 17 Nov 2015 22:07:07 +0200 Subject: [PATCH 1890/2855] staging: lustre: libcfs.h: remove IS_PO2 and __is_po2 Removes IS_PO2 and __is_po2 since the uses of IS_PO2 have been replaced by is_power_of_2 Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h index 049f6a9a638b0..0d8a91ee5ffc4 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h @@ -42,13 +42,6 @@ #include "curproc.h" -static inline int __is_po2(unsigned long long val) -{ - return !(val & (val - 1)); -} - -#define IS_PO2(val) __is_po2((unsigned long long)(val)) - #define LOWEST_BIT_SET(x) ((x) & ~((x) - 1)) /* -- GitLab From f916774259d60e8ecd2cdd90e712e4c2fc64b947 Mon Sep 17 00:00:00 2001 From: Anjali Menon Date: Fri, 20 Nov 2015 11:25:22 +0530 Subject: [PATCH 1891/2855] staging: lustre: lustre: fld: Removed a blank line Removed a blank line after the open brace to remove the check detected by the checkpatch.pl. CHECK: Blank lines aren't necessary after an open brace '{' Signed-off-by: Anjali Menon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/fld/fld_cache.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/fld/fld_cache.c b/drivers/staging/lustre/lustre/fld/fld_cache.c index baa04074a61f6..d9459e58e2ce7 100644 --- a/drivers/staging/lustre/lustre/fld/fld_cache.c +++ b/drivers/staging/lustre/lustre/fld/fld_cache.c @@ -227,7 +227,6 @@ static int fld_cache_shrink(struct fld_cache *cache) while (cache->fci_cache_count + cache->fci_threshold > cache->fci_cache_size && curr != &cache->fci_lru) { - flde = list_entry(curr, struct fld_cache_entry, fce_lru); curr = curr->prev; fld_cache_entry_delete(cache, flde); -- GitLab From 20b0236628a8a420bfbf8a3d39576e2ed606fce7 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Sun, 6 Dec 2015 01:41:31 +0100 Subject: [PATCH 1892/2855] staging: lustre: fix %.2X versus signed char issue When char is signed and one of the bytes in lmm happens to have a byte value above 127, the result of printing that with %.2X will be 8 hex chars, the first 6 of which are 'F'. Worst case, we'll overrun our 'carefully' allocated buffer. I didn't have the tenacity to work through the gazillion and seven layers of macros behind CERROR, but I assume it'll all end at some function implemented in terms of the kernel's vsnprintf. Use %*phN for a hexdump. That'll cap the number of dumped bytes at 64. If that's a problem, the loop could be replaced by "bin2hex(buffer, lmm, lmm_bytes);". Signed-off-by: Rasmus Villemoes Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/lov/lov_pack.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/staging/lustre/lustre/lov/lov_pack.c b/drivers/staging/lustre/lustre/lov/lov_pack.c index 198523139b3b5..6b2d1007192b8 100644 --- a/drivers/staging/lustre/lustre/lov/lov_pack.c +++ b/drivers/staging/lustre/lustre/lov/lov_pack.c @@ -258,22 +258,9 @@ static int lov_verify_lmm(void *lmm, int lmm_bytes, __u16 *stripe_count) int rc; if (lsm_op_find(le32_to_cpu(*(__u32 *)lmm)) == NULL) { - char *buffer; - int sz; - CERROR("bad disk LOV MAGIC: 0x%08X; dumping LMM (size=%d):\n", le32_to_cpu(*(__u32 *)lmm), lmm_bytes); - sz = lmm_bytes * 2 + 1; - buffer = libcfs_kvzalloc(sz, GFP_NOFS); - if (buffer != NULL) { - int i; - - for (i = 0; i < lmm_bytes; i++) - sprintf(buffer+2*i, "%.2X", ((char *)lmm)[i]); - buffer[sz - 1] = '\0'; - CERROR("%s\n", buffer); - kvfree(buffer); - } + CERROR("%*phN\n", lmm_bytes, lmm); return -EINVAL; } rc = lsm_op_find(le32_to_cpu(*(__u32 *)lmm))->lsm_lmm_verify(lmm, -- GitLab From 4e8d4e1b79896332205e5f505877b1bc6cff1d10 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Wed, 16 Dec 2015 23:10:15 +0530 Subject: [PATCH 1893/2855] Staging: lustre: include: Remove unused llog_backup declaration Function llog_backup is declared in header file but not used. Thus remove it. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/lustre_log.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lustre_log.h b/drivers/staging/lustre/lustre/include/lustre_log.h index 53af4cd1adcce..e4fc8b5e13363 100644 --- a/drivers/staging/lustre/lustre/include/lustre_log.h +++ b/drivers/staging/lustre/lustre/include/lustre_log.h @@ -94,9 +94,6 @@ int llog_open(const struct lu_env *env, struct llog_ctxt *ctxt, struct llog_handle **lgh, struct llog_logid *logid, char *name, enum llog_open_param open_param); int llog_close(const struct lu_env *env, struct llog_handle *cathandle); -int llog_backup(const struct lu_env *env, struct obd_device *obd, - struct llog_ctxt *ctxt, struct llog_ctxt *bak_ctxt, - char *name, char *backup); /* llog_process flags */ #define LLOG_FLAG_NODEAMON 0x0001 -- GitLab From 4f05f8ae0a20f692f5138e0383d4cee486ae7127 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Wed, 16 Dec 2015 23:10:17 +0530 Subject: [PATCH 1894/2855] Staging: lustre: lnet: Remove functions LNetEQWait and LNetEQGet Functions LNetEQWait and LNetEQGet are defined but not used. Thus remove it. Also remove corresponding declarations from header file. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/include/linux/lnet/api.h | 6 ------ drivers/staging/lustre/lnet/lnet/lib-eq.c | 18 ------------------ 2 files changed, 24 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/api.h b/drivers/staging/lustre/include/linux/lnet/api.h index 9493d5e236c52..75285fde15e8c 100644 --- a/drivers/staging/lustre/include/linux/lnet/api.h +++ b/drivers/staging/lustre/include/linux/lnet/api.h @@ -161,12 +161,6 @@ int LNetEQAlloc(unsigned int count_in, int LNetEQFree(lnet_handle_eq_t eventq_in); -int LNetEQGet(lnet_handle_eq_t eventq_in, - lnet_event_t *event_out); - -int LNetEQWait(lnet_handle_eq_t eventq_in, - lnet_event_t *event_out); - int LNetEQPoll(lnet_handle_eq_t *eventqs_in, int neq_in, int timeout_ms, diff --git a/drivers/staging/lustre/lnet/lnet/lib-eq.c b/drivers/staging/lustre/lnet/lnet/lib-eq.c index 60889ebd2f2bb..64f94a6900814 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-eq.c +++ b/drivers/staging/lustre/lnet/lnet/lib-eq.c @@ -282,15 +282,6 @@ lnet_eq_dequeue_event(lnet_eq_t *eq, lnet_event_t *ev) * at least one event between this event and the last event obtained from the * EQ has been dropped due to limited space in the EQ. */ -int -LNetEQGet(lnet_handle_eq_t eventq, lnet_event_t *event) -{ - int which; - - return LNetEQPoll(&eventq, 1, 0, - event, &which); -} -EXPORT_SYMBOL(LNetEQGet); /** * Block the calling process until there is an event in the EQ. @@ -308,15 +299,6 @@ EXPORT_SYMBOL(LNetEQGet); * at least one event between this event and the last event obtained from the * EQ has been dropped due to limited space in the EQ. */ -int -LNetEQWait(lnet_handle_eq_t eventq, lnet_event_t *event) -{ - int which; - - return LNetEQPoll(&eventq, 1, LNET_TIME_FOREVER, - event, &which); -} -EXPORT_SYMBOL(LNetEQWait); static int lnet_eq_wait_locked(int *timeout_ms) -- GitLab From 9569ea54ebadbb01746b7d6a5e79a16f78eaa1ae Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Fri, 18 Dec 2015 02:40:26 +0530 Subject: [PATCH 1895/2855] Staging: lustre: obdclass: Declare cl_env_peek as static Declare cl_env_peek as static since it is used only in this file. Also remove the EXPORT SYMBOL. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/obdclass/cl_object.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c index 73ea8458af18b..57c8d5412bbd1 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c @@ -704,7 +704,7 @@ static inline struct cl_env *cl_env_container(struct lu_env *env) return container_of(env, struct cl_env, ce_lu); } -struct lu_env *cl_env_peek(int *refcheck) +static struct lu_env *cl_env_peek(int *refcheck) { struct lu_env *env; struct cl_env *cle; @@ -724,7 +724,6 @@ struct lu_env *cl_env_peek(int *refcheck) CDEBUG(D_OTHER, "%d@%p\n", cle ? cle->ce_ref : 0, cle); return env; } -EXPORT_SYMBOL(cl_env_peek); /** * Returns lu_env: if there already is an environment associated with the -- GitLab From 62dc2f66a9267388722a0b1a0c0c253299a3dfc1 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Fri, 18 Dec 2015 02:40:27 +0530 Subject: [PATCH 1896/2855] Staging: lustre: libcfs: Remove unused libcfs_debug_set_level Function libcfs_debug_set_level is defined but not used. Thus remove it. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/debug.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/debug.c b/drivers/staging/lustre/lustre/libcfs/debug.c index e56785a482425..0b38dad135465 100644 --- a/drivers/staging/lustre/lustre/libcfs/debug.c +++ b/drivers/staging/lustre/lustre/libcfs/debug.c @@ -557,10 +557,3 @@ int libcfs_debug_mark_buffer(const char *text) #undef DEBUG_SUBSYSTEM #define DEBUG_SUBSYSTEM S_LNET - -void libcfs_debug_set_level(unsigned int debug_level) -{ - pr_warn("Lustre: Setting portals debug level to %08x\n", - debug_level); - libcfs_debug = debug_level; -} -- GitLab From 6ef3f3c736bd7f4864db5d49e7ff53aeedc75ca3 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Fri, 18 Dec 2015 02:40:28 +0530 Subject: [PATCH 1897/2855] Staging: lustre: osc: Declare as static Declare osc_extent_find and osc_unreserve_grant as static since they are used only in this particular file. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/osc/osc_cache.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index 46cfde4b139fc..2229419b71845 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -619,9 +619,9 @@ static inline int overlapped(struct osc_extent *ex1, struct osc_extent *ex2) * Find or create an extent which includes @index, core function to manage * extent tree. */ -struct osc_extent *osc_extent_find(const struct lu_env *env, - struct osc_object *obj, pgoff_t index, - int *grants) +static struct osc_extent *osc_extent_find(const struct lu_env *env, + struct osc_object *obj, pgoff_t index, + int *grants) { struct client_obd *cli = osc_cli(obj); @@ -1420,8 +1420,8 @@ static void __osc_unreserve_grant(struct client_obd *cli, } } -void osc_unreserve_grant(struct client_obd *cli, - unsigned int reserved, unsigned int unused) +static void osc_unreserve_grant(struct client_obd *cli, + unsigned int reserved, unsigned int unused) { client_obd_list_lock(&cli->cl_loi_list_lock); __osc_unreserve_grant(cli, reserved, unused); -- GitLab From 61db1bc4970ac896a1e08fc2214d707b68605d41 Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Fri, 18 Dec 2015 02:40:29 +0530 Subject: [PATCH 1898/2855] Staging: lustre: osc: Declare osc_attr_set as static osc_attr_set is used only in this particular file. Thus declare it as static. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/osc/osc_object.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/osc/osc_object.c b/drivers/staging/lustre/lustre/osc/osc_object.c index c29a0d45ffed2..fdd6219aacf69 100644 --- a/drivers/staging/lustre/lustre/osc/osc_object.c +++ b/drivers/staging/lustre/lustre/osc/osc_object.c @@ -158,8 +158,8 @@ static int osc_attr_get(const struct lu_env *env, struct cl_object *obj, return 0; } -int osc_attr_set(const struct lu_env *env, struct cl_object *obj, - const struct cl_attr *attr, unsigned valid) +static int osc_attr_set(const struct lu_env *env, struct cl_object *obj, + const struct cl_attr *attr, unsigned valid) { struct lov_oinfo *oinfo = cl2osc(obj)->oo_oinfo; struct ost_lvb *lvb = &oinfo->loi_lvb; -- GitLab From fb7a02014b6bb4d56864424cd13dbd6417c3cd7d Mon Sep 17 00:00:00 2001 From: Shraddha Barke Date: Fri, 18 Dec 2015 02:40:30 +0530 Subject: [PATCH 1899/2855] Staging: lustre: obdclass: Declare lu_site_hash_ops as static lu_site_hash_ops is used only in this particular file. Thus declare it as static. Signed-off-by: Shraddha Barke Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/obdclass/lu_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c index 76ad9dc0447aa..ce248f4072c26 100644 --- a/drivers/staging/lustre/lustre/obdclass/lu_object.c +++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c @@ -916,7 +916,7 @@ static void lu_obj_hop_put_locked(struct cfs_hash *hs, struct hlist_node *hnode) LBUG(); /* we should never called it */ } -struct cfs_hash_ops lu_site_hash_ops = { +static struct cfs_hash_ops lu_site_hash_ops = { .hs_hash = lu_obj_hop_hash, .hs_key = lu_obj_hop_key, .hs_keycmp = lu_obj_hop_keycmp, -- GitLab From 3af7370ca16e33f80ebcfd0fe5be59ed6094c95a Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 21 Dec 2015 18:15:45 +0100 Subject: [PATCH 1900/2855] staging: lustre: Delete unnecessary goto statements in six functions Six goto statements referred to a source code position directly behind them. Thus omit such unnecessary jumps. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/namei.c | 1 - drivers/staging/lustre/lustre/mdc/mdc_request.c | 7 ------- 2 files changed, 8 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 14370b97fe5c9..8d8220f3db83f 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -556,7 +556,6 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry, retval = NULL; else retval = dentry; - goto out; out: if (req) ptlrpc_req_finished(req); diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 8baf726a983fa..57e0fc1e8549d 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -1181,7 +1181,6 @@ static int mdc_ioc_hsm_progress(struct obd_export *exp, ptlrpc_request_set_replen(req); rc = mdc_queue_wait(req); - goto out; out: ptlrpc_req_finished(req); return rc; @@ -1216,7 +1215,6 @@ static int mdc_ioc_hsm_ct_register(struct obd_import *imp, __u32 archives) ptlrpc_request_set_replen(req); rc = mdc_queue_wait(req); - goto out; out: ptlrpc_req_finished(req); return rc; @@ -1282,7 +1280,6 @@ static int mdc_ioc_hsm_ct_unregister(struct obd_import *imp) ptlrpc_request_set_replen(req); rc = mdc_queue_wait(req); - goto out; out: ptlrpc_req_finished(req); return rc; @@ -1362,8 +1359,6 @@ static int mdc_ioc_hsm_state_set(struct obd_export *exp, ptlrpc_request_set_replen(req); rc = mdc_queue_wait(req); - goto out; - out: ptlrpc_req_finished(req); return rc; @@ -1427,8 +1422,6 @@ static int mdc_ioc_hsm_request(struct obd_export *exp, ptlrpc_request_set_replen(req); rc = mdc_queue_wait(req); - goto out; - out: ptlrpc_req_finished(req); return rc; -- GitLab From 24a386334f62b1f4e5f6209e8bbc0168168ba441 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 21 Dec 2015 18:24:45 +0100 Subject: [PATCH 1901/2855] staging: lustre: Delete an unnecessary variable initialisation in mgc_process_recover_log() The variable "mne_swab" will eventually be set to an appropriate value from a call of the ptlrpc_rep_need_swab() function. Thus let us omit the explicit initialisation at the beginning. Signed-off-by: Markus Elfring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mgc/mgc_request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c index 06dc2c3d36c29..ab4800c20a95a 100644 --- a/drivers/staging/lustre/lustre/mgc/mgc_request.c +++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c @@ -1293,7 +1293,7 @@ static int mgc_process_recover_log(struct obd_device *obd, struct page **pages; int nrpages; bool eof = true; - bool mne_swab = false; + bool mne_swab; int i; int ealen; int rc; -- GitLab From c71d264543f759fea147734cb63de36397817534 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 21 Dec 2015 19:30:42 +0100 Subject: [PATCH 1902/2855] staging: lustre: Fix a jump label position in osc_get_info() The script "checkpatch.pl" pointed out that labels should not be indented. Thus delete a horizontal tab before the jump label "out" in the function "osc_get_info". Signed-off-by: Markus Elfring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/osc/osc_request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index b2642a7988570..7034f0a942c52 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -2727,7 +2727,7 @@ static int osc_get_info(const struct lu_env *env, struct obd_export *exp, } *((u64 *)val) = *reply; - out: +out: ptlrpc_req_finished(req); return rc; } else if (KEY_IS(KEY_FIEMAP)) { -- GitLab From 5bff5d9f2b557f63015925b1b076f98010533c52 Mon Sep 17 00:00:00 2001 From: Bogicevic Sasa Date: Fri, 13 Nov 2015 15:07:21 +0100 Subject: [PATCH 1903/2855] driver:staging:dgnc Fix spaces preferred around that ... This fixes all "spaces preferred around that ..." messages from checkpatch.pl Signed-off-by: Bogicevic Sasa Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_neo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index 8106f5234bf51..15c255d184dce 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -1628,7 +1628,7 @@ static void neo_uart_init(struct channel_t *ch) /* Clear out UART and FIFO */ readb(&ch->ch_neo_uart->txrx); - writeb((UART_FCR_ENABLE_FIFO|UART_FCR_CLEAR_RCVR|UART_FCR_CLEAR_XMIT), &ch->ch_neo_uart->isr_fcr); + writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), &ch->ch_neo_uart->isr_fcr); readb(&ch->ch_neo_uart->lsr); readb(&ch->ch_neo_uart->msr); @@ -1779,8 +1779,8 @@ static void neo_vpd(struct dgnc_board *brd) /* Store the VPD into our buffer */ for (i = 0; i < NEO_VPD_IMAGESIZE; i++) { a = neo_read_eeprom(brd->re_map_membase, i); - brd->vpd[i*2] = a & 0xff; - brd->vpd[(i*2)+1] = (a >> 8) & 0xff; + brd->vpd[i * 2] = a & 0xff; + brd->vpd[(i * 2) + 1] = (a >> 8) & 0xff; } if (((brd->vpd[0x08] != 0x82) /* long resource name tag */ -- GitLab From 013514946cbd85dea2a12e8848f2cfb775eecd52 Mon Sep 17 00:00:00 2001 From: Nizam Haider Date: Sat, 14 Nov 2015 20:10:45 +0530 Subject: [PATCH 1904/2855] Staging: dgnc: dgnc_neo.c Braces {} should be used on all arms of this statement Fix Checlpatch warning HECK: braces {} should be used on all arms of this statement Signed-off-by: Nizam Haider Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_neo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index 15c255d184dce..39c76e78e56aa 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -1108,9 +1108,9 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) * On the other hand, if the UART IS in FIFO mode, then ask * the UART to give us an approximation of data it has RX'ed. */ - if (!(ch->ch_flags & CH_FIFO_ENABLED)) + if (!(ch->ch_flags & CH_FIFO_ENABLED)) { total = 0; - else { + } else { total = readb(&ch->ch_neo_uart->rfifo); /* -- GitLab From f7f2b10a82e8774eab3bd90061caccf8931a8bf4 Mon Sep 17 00:00:00 2001 From: Nizam Haider Date: Sat, 14 Nov 2015 20:10:46 +0530 Subject: [PATCH 1905/2855] Staging: dgnc: dgnc_tty: Typo error dgnc_wmove comment Fix Typo errror in the comment section of dgnc_wmove Signed-off-by: Nizam Haider Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 48e4b90578c17..b79eab084c023 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -448,7 +448,7 @@ void dgnc_tty_uninit(struct dgnc_board *brd) * dgnc_wmove - Write data to transmit queue. * * ch - Pointer to channel structure. - * buf - Poiter to characters to be moved. + * buf - Pointer to characters to be moved. * n - Number of characters to move. * *=======================================================================*/ -- GitLab From 6e411751f00faf00379f6aa94701ab360b068cff Mon Sep 17 00:00:00 2001 From: Jitendra Kumar Khasdev Date: Tue, 24 Nov 2015 23:01:13 +0530 Subject: [PATCH 1906/2855] staging: dgnc: dgnc_cls.c: Replaced udelay by usleep_range This patch is to file dgnc_cls.c that fixes up udelay function by usleep_range. It is safe to use according to the following documentation Documentation/timers/timers-howto.txt. So that is why I have given an appropriate time range. Signed-off-by: Jitendra Kumar Khasdev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_cls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c index 75040daa40ce8..72f0aaa6911f5 100644 --- a/drivers/staging/dgnc/dgnc_cls.c +++ b/drivers/staging/dgnc/dgnc_cls.c @@ -934,7 +934,7 @@ static void cls_flush_uart_write(struct channel_t *ch) writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT), &ch->ch_cls_uart->isr_fcr); - udelay(10); + usleep_range(10, 20); ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); } -- GitLab From 04226e40592c4b27cc2250105b4505901d467102 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Tue, 10 Nov 2015 22:41:34 +0800 Subject: [PATCH 1907/2855] staging: comedi: use kmalloc_array instead of kmalloc Use kmalloc_array instead of kmalloc to allocate memory for an array. Signed-off-by: Geliang Tang Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 11 +++++++---- drivers/staging/comedi/drivers/ni_670x.c | 5 +++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index b2f7679a01161..cac011fdd375d 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1022,14 +1022,17 @@ pci224_auto_attach(struct comedi_device *dev, unsigned long context_model) irq = pci_dev->irq; /* Allocate buffer to hold values for AO channel scan. */ - devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) * - board->ao_chans, GFP_KERNEL); + devpriv->ao_scan_vals = kmalloc_array(board->ao_chans, + sizeof(devpriv->ao_scan_vals[0]), + GFP_KERNEL); if (!devpriv->ao_scan_vals) return -ENOMEM; /* Allocate buffer to hold AO channel scan order. */ - devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) * - board->ao_chans, GFP_KERNEL); + devpriv->ao_scan_order = + kmalloc_array(board->ao_chans, + sizeof(devpriv->ao_scan_order[0]), + GFP_KERNEL); if (!devpriv->ao_scan_order) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index f4c580f65a896..3e72718801a9e 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -214,8 +214,9 @@ static int ni_670x_auto_attach(struct comedi_device *dev, if (s->n_chan == 32) { const struct comedi_lrange **range_table_list; - range_table_list = kmalloc(sizeof(struct comedi_lrange *) * 32, - GFP_KERNEL); + range_table_list = kmalloc_array(32, + sizeof(struct comedi_lrange *), + GFP_KERNEL); if (!range_table_list) return -ENOMEM; s->range_table_list = range_table_list; -- GitLab From 5e1a02bd93fb64fd195951a723ad768106120562 Mon Sep 17 00:00:00 2001 From: Ranjith Thangavel Date: Wed, 11 Nov 2015 21:24:01 +0530 Subject: [PATCH 1908/2855] comedi: comedi_parport: Fix coding style - use BIT macro BIT macro is used for defining BIT location instead of shifting operator - coding style issue Signed-off-by: Ranjith Thangavel Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_parport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index 15a4093efda13..1bf8ddc6f07cb 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -75,8 +75,8 @@ #define PARPORT_DATA_REG 0x00 #define PARPORT_STATUS_REG 0x01 #define PARPORT_CTRL_REG 0x02 -#define PARPORT_CTRL_IRQ_ENA (1 << 4) -#define PARPORT_CTRL_BIDIR_ENA (1 << 5) +#define PARPORT_CTRL_IRQ_ENA BIT(4) +#define PARPORT_CTRL_BIDIR_ENA BIT(5) static int parport_data_reg_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, -- GitLab From ecbbf6d33005b287fc4a753de0011f5f261b5869 Mon Sep 17 00:00:00 2001 From: Ranjith Thangavel Date: Wed, 11 Nov 2015 21:52:02 +0530 Subject: [PATCH 1909/2855] comedi: ni_65xx: Fix coding style - use BIT macro BIT macro is used for defining BIT location instead of shifting operator - coding style issue Signed-off-by: Ranjith Thangavel Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_65xx.c | 54 ++++++++++++------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 800d574260704..251117be1205f 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -68,25 +68,25 @@ /* Non-recurring Registers (8-bit except where noted) */ #define NI_65XX_ID_REG 0x00 #define NI_65XX_CLR_REG 0x01 -#define NI_65XX_CLR_WDOG_INT (1 << 6) -#define NI_65XX_CLR_WDOG_PING (1 << 5) -#define NI_65XX_CLR_WDOG_EXP (1 << 4) -#define NI_65XX_CLR_EDGE_INT (1 << 3) -#define NI_65XX_CLR_OVERFLOW_INT (1 << 2) +#define NI_65XX_CLR_WDOG_INT BIT(6) +#define NI_65XX_CLR_WDOG_PING BIT(5) +#define NI_65XX_CLR_WDOG_EXP BIT(4) +#define NI_65XX_CLR_EDGE_INT BIT(3) +#define NI_65XX_CLR_OVERFLOW_INT BIT(2) #define NI_65XX_STATUS_REG 0x02 -#define NI_65XX_STATUS_WDOG_INT (1 << 5) -#define NI_65XX_STATUS_FALL_EDGE (1 << 4) -#define NI_65XX_STATUS_RISE_EDGE (1 << 3) -#define NI_65XX_STATUS_INT (1 << 2) -#define NI_65XX_STATUS_OVERFLOW_INT (1 << 1) -#define NI_65XX_STATUS_EDGE_INT (1 << 0) +#define NI_65XX_STATUS_WDOG_INT BIT(5) +#define NI_65XX_STATUS_FALL_EDGE BIT(4) +#define NI_65XX_STATUS_RISE_EDGE BIT(3) +#define NI_65XX_STATUS_INT BIT(2) +#define NI_65XX_STATUS_OVERFLOW_INT BIT(1) +#define NI_65XX_STATUS_EDGE_INT BIT(0) #define NI_65XX_CTRL_REG 0x03 -#define NI_65XX_CTRL_WDOG_ENA (1 << 5) -#define NI_65XX_CTRL_FALL_EDGE_ENA (1 << 4) -#define NI_65XX_CTRL_RISE_EDGE_ENA (1 << 3) -#define NI_65XX_CTRL_INT_ENA (1 << 2) -#define NI_65XX_CTRL_OVERFLOW_ENA (1 << 1) -#define NI_65XX_CTRL_EDGE_ENA (1 << 0) +#define NI_65XX_CTRL_WDOG_ENA BIT(5) +#define NI_65XX_CTRL_FALL_EDGE_ENA BIT(4) +#define NI_65XX_CTRL_RISE_EDGE_ENA BIT(3) +#define NI_65XX_CTRL_INT_ENA BIT(2) +#define NI_65XX_CTRL_OVERFLOW_ENA BIT(1) +#define NI_65XX_CTRL_EDGE_ENA BIT(0) #define NI_65XX_REV_REG 0x04 /* 32-bit */ #define NI_65XX_FILTER_REG 0x08 /* 32-bit */ #define NI_65XX_RTSI_ROUTE_REG 0x0c /* 16-bit */ @@ -94,24 +94,24 @@ #define NI_65XX_RTSI_WDOG_REG 0x10 /* 16-bit */ #define NI_65XX_RTSI_TRIG_REG 0x12 /* 16-bit */ #define NI_65XX_AUTO_CLK_SEL_REG 0x14 /* PXI-6528 only */ -#define NI_65XX_AUTO_CLK_SEL_STATUS (1 << 1) -#define NI_65XX_AUTO_CLK_SEL_DISABLE (1 << 0) +#define NI_65XX_AUTO_CLK_SEL_STATUS BIT(1) +#define NI_65XX_AUTO_CLK_SEL_DISABLE BIT(0) #define NI_65XX_WDOG_CTRL_REG 0x15 -#define NI_65XX_WDOG_CTRL_ENA (1 << 0) +#define NI_65XX_WDOG_CTRL_ENA BIT(0) #define NI_65XX_RTSI_CFG_REG 0x16 -#define NI_65XX_RTSI_CFG_RISE_SENSE (1 << 2) -#define NI_65XX_RTSI_CFG_FALL_SENSE (1 << 1) -#define NI_65XX_RTSI_CFG_SYNC_DETECT (1 << 0) +#define NI_65XX_RTSI_CFG_RISE_SENSE BIT(2) +#define NI_65XX_RTSI_CFG_FALL_SENSE BIT(1) +#define NI_65XX_RTSI_CFG_SYNC_DETECT BIT(0) #define NI_65XX_WDOG_STATUS_REG 0x17 -#define NI_65XX_WDOG_STATUS_EXP (1 << 0) +#define NI_65XX_WDOG_STATUS_EXP BIT(0) #define NI_65XX_WDOG_INTERVAL_REG 0x18 /* 32-bit */ /* Recurring port registers (8-bit) */ #define NI_65XX_PORT(x) ((x) * 0x10) #define NI_65XX_IO_DATA_REG(x) (0x40 + NI_65XX_PORT(x)) #define NI_65XX_IO_SEL_REG(x) (0x41 + NI_65XX_PORT(x)) -#define NI_65XX_IO_SEL_OUTPUT (0 << 0) -#define NI_65XX_IO_SEL_INPUT (1 << 0) +#define NI_65XX_IO_SEL_OUTPUT 0 +#define NI_65XX_IO_SEL_INPUT BIT(0) #define NI_65XX_RISE_EDGE_ENA_REG(x) (0x42 + NI_65XX_PORT(x)) #define NI_65XX_FALL_EDGE_ENA_REG(x) (0x43 + NI_65XX_PORT(x)) #define NI_65XX_FILTER_ENA(x) (0x44 + NI_65XX_PORT(x)) @@ -613,7 +613,7 @@ static int ni_65xx_intr_insn_config(struct comedi_device *dev, /* ripped from mite.h and mite_setup2() to avoid mite dependency */ #define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */ -#define WENAB (1 << 7) /* window enable */ +#define WENAB BIT(7) /* window enable */ static int ni_65xx_mite_init(struct pci_dev *pcidev) { -- GitLab From 1a549cb61afa7fc18d92ef87061c8a8d47f535cf Mon Sep 17 00:00:00 2001 From: Ranjith Thangavel Date: Wed, 11 Nov 2015 21:57:51 +0530 Subject: [PATCH 1910/2855] comedi: cb_pcidda: Fix coding style - use BIT macro BIT macro is used for defining BIT location instead of shifting operator - coding style issue Signed-off-by: Ranjith Thangavel Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index b00a36a5cb360..ccb37d1f0f8ee 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -51,13 +51,13 @@ /* DAC registers */ #define CB_DDA_DA_CTRL_REG 0x00 /* D/A Control Register */ -#define CB_DDA_DA_CTRL_SU (1 << 0) /* Simultaneous update */ -#define CB_DDA_DA_CTRL_EN (1 << 1) /* Enable specified DAC */ +#define CB_DDA_DA_CTRL_SU BIT(0) /* Simultaneous update */ +#define CB_DDA_DA_CTRL_EN BIT(1) /* Enable specified DAC */ #define CB_DDA_DA_CTRL_DAC(x) ((x) << 2) /* Specify DAC channel */ #define CB_DDA_DA_CTRL_RANGE2V5 (0 << 6) /* 2.5V range */ #define CB_DDA_DA_CTRL_RANGE5V (2 << 6) /* 5V range */ #define CB_DDA_DA_CTRL_RANGE10V (3 << 6) /* 10V range */ -#define CB_DDA_DA_CTRL_UNIP (1 << 8) /* Unipolar range */ +#define CB_DDA_DA_CTRL_UNIP BIT(8) /* Unipolar range */ #define DACALIBRATION1 4 /* D/A CALIBRATION REGISTER 1 */ /* write bits */ -- GitLab From af904c49422be93dd182d45d0c9c3d1862ab72b0 Mon Sep 17 00:00:00 2001 From: "Daniel H. Hemmingsen" Date: Thu, 12 Nov 2015 17:03:18 +0100 Subject: [PATCH 1911/2855] Staging: comedi: Fixed multiple commenting and spacing codig style issues. Fixed multiple comment blocks that didn't comply with the kernels coding style, and fixed a few spacing issues as well. Signed-off-by: Daniel H. Hemmingsen Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi.h | 307 ++++++++++++++++++-------------- 1 file changed, 177 insertions(+), 130 deletions(-) diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 66edda190b75c..83bd309d011b9 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -1,20 +1,20 @@ /* - include/comedi.h (installed as /usr/include/comedi.h) - header file for comedi - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 1998-2001 David A. Schleef - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ + * include/comedi.h (installed as /usr/include/comedi.h) + * header file for comedi + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 1998-2001 David A. Schleef + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #ifndef _COMEDI_H #define _COMEDI_H @@ -28,9 +28,9 @@ #define COMEDI_MAJOR 98 /* - maximum number of minor devices. This can be increased, although - kernel structures are currently statically allocated, thus you - don't want this to be much more than you actually use. + * maximum number of minor devices. This can be increased, although + * kernel structures are currently statically allocated, thus you + * don't want this to be much more than you actually use. */ #define COMEDI_NDEVICES 16 @@ -63,21 +63,21 @@ /* packs and unpacks a channel/range number */ #define CR_PACK(chan, rng, aref) \ - ((((aref)&0x3)<<24) | (((rng)&0xff)<<16) | (chan)) + ((((aref) & 0x3) << 24) | (((rng) & 0xff) << 16) | (chan)) #define CR_PACK_FLAGS(chan, range, aref, flags) \ (CR_PACK(chan, range, aref) | ((flags) & CR_FLAGS_MASK)) -#define CR_CHAN(a) ((a)&0xffff) -#define CR_RANGE(a) (((a)>>16)&0xff) -#define CR_AREF(a) (((a)>>24)&0x03) +#define CR_CHAN(a) ((a) & 0xffff) +#define CR_RANGE(a) (((a) >> 16) & 0xff) +#define CR_AREF(a) (((a) >> 24) & 0x03) #define CR_FLAGS_MASK 0xfc000000 -#define CR_ALT_FILTER (1<<26) +#define CR_ALT_FILTER (1 << 26) #define CR_DITHER CR_ALT_FILTER #define CR_DEGLITCH CR_ALT_FILTER -#define CR_ALT_SOURCE (1<<27) -#define CR_EDGE (1<<30) -#define CR_INVERT (1<<31) +#define CR_ALT_SOURCE (1 << 27) +#define CR_EDGE (1 << 30) +#define CR_INVERT (1 << 31) #define AREF_GROUND 0x00 /* analog ref = analog ground */ #define AREF_COMMON 0x01 /* analog ref = analog common */ @@ -114,11 +114,11 @@ #define INSN_READ (0 | INSN_MASK_READ) #define INSN_WRITE (1 | INSN_MASK_WRITE) -#define INSN_BITS (2 | INSN_MASK_READ|INSN_MASK_WRITE) -#define INSN_CONFIG (3 | INSN_MASK_READ|INSN_MASK_WRITE) -#define INSN_GTOD (4 | INSN_MASK_READ|INSN_MASK_SPECIAL) -#define INSN_WAIT (5 | INSN_MASK_WRITE|INSN_MASK_SPECIAL) -#define INSN_INTTRIG (6 | INSN_MASK_WRITE|INSN_MASK_SPECIAL) +#define INSN_BITS (2 | INSN_MASK_READ | INSN_MASK_WRITE) +#define INSN_CONFIG (3 | INSN_MASK_READ | INSN_MASK_WRITE) +#define INSN_GTOD (4 | INSN_MASK_READ | INSN_MASK_SPECIAL) +#define INSN_WAIT (5 | INSN_MASK_WRITE | INSN_MASK_SPECIAL) +#define INSN_INTTRIG (6 | INSN_MASK_WRITE | INSN_MASK_SPECIAL) /* trigger flags */ /* These flags are used in comedi_trig structures */ @@ -279,7 +279,8 @@ enum configuration_ids { INSN_CONFIG_SET_OTHER_SRC = 2005, /* Set other source */ /* INSN_CONFIG_GET_OTHER_SRC = 2006,*//* Get other source */ /* Get size in bytes of subdevice's on-board fifos used during - * streaming input/output */ + * streaming input/output + */ INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006, INSN_CONFIG_SET_COUNTER_MODE = 4097, /* INSN_CONFIG_8254_SET_MODE is deprecated */ @@ -292,7 +293,8 @@ enum configuration_ids { INSN_CONFIG_PWM_GET_PERIOD = 5001, /* gets frequency */ INSN_CONFIG_GET_PWM_STATUS = 5002, /* is it running? */ /* sets H bridge: duty cycle and sign bit for a relay at the - * same time */ + * same time + */ INSN_CONFIG_PWM_SET_H_BRIDGE = 5003, /* gets H bridge data: duty cycle and the sign bit */ INSN_CONFIG_PWM_GET_H_BRIDGE = 5004 @@ -502,13 +504,13 @@ struct comedi_bufinfo { /* range stuff */ -#define __RANGE(a, b) ((((a)&0xffff)<<16)|((b)&0xffff)) +#define __RANGE(a, b) ((((a) & 0xffff) << 16) | ((b) & 0xffff)) -#define RANGE_OFFSET(a) (((a)>>16)&0xffff) -#define RANGE_LENGTH(b) ((b)&0xffff) +#define RANGE_OFFSET(a) (((a) >> 16) & 0xffff) +#define RANGE_LENGTH(b) ((b) & 0xffff) -#define RF_UNIT(flags) ((flags)&0xff) -#define RF_EXTERNAL (1<<8) +#define RF_UNIT(flags) ((flags) & 0xff) +#define RF_EXTERNAL (1 << 8) #define UNIT_volt 0 #define UNIT_mA 1 @@ -521,23 +523,22 @@ struct comedi_bufinfo { /**********************************************************/ /* - 8254 specific configuration. - - It supports two config commands: - - 0 ID: INSN_CONFIG_SET_COUNTER_MODE - 1 8254 Mode - I8254_MODE0, I8254_MODE1, ..., I8254_MODE5 - OR'ed with: - I8254_BCD, I8254_BINARY - - 0 ID: INSN_CONFIG_8254_READ_STATUS - 1 <-- Status byte returned here. - B7 = Output - B6 = NULL Count - B5 - B0 Current mode. - -*/ + * 8254 specific configuration. + * + * It supports two config commands: + * + * 0 ID: INSN_CONFIG_SET_COUNTER_MODE + * 1 8254 Mode + * I8254_MODE0, I8254_MODE1, ..., I8254_MODE5 + * OR'ed with: + * I8254_BCD, I8254_BINARY + * + * 0 ID: INSN_CONFIG_8254_READ_STATUS + * 1 <-- Status byte returned here. + * B7 = Output + * B6 = NULL Count + * B5 - B0 Current mode. + */ enum i8254_mode { I8254_MODE0 = (0 << 1), /* Interrupt on terminal count */ @@ -545,18 +546,20 @@ enum i8254_mode { I8254_MODE2 = (2 << 1), /* Rate generator */ I8254_MODE3 = (3 << 1), /* Square wave mode */ I8254_MODE4 = (4 << 1), /* Software triggered strobe */ - I8254_MODE5 = (5 << 1), /* Hardware triggered strobe - * (retriggerable) */ - I8254_BCD = 1, /* use binary-coded decimal instead of binary - * (pretty useless) */ + /* Hardware triggered strobe (retriggerable) */ + I8254_MODE5 = (5 << 1), + /* Use binary-coded decimal instead of binary (pretty useless) */ + I8254_BCD = 1, I8254_BINARY = 0 }; #define NI_USUAL_PFI_SELECT(x) (((x) < 10) ? (0x1 + (x)) : (0xb + (x))) #define NI_USUAL_RTSI_SELECT(x) (((x) < 7) ? (0xb + (x)) : 0x1b) -/* mode bits for NI general-purpose counters, set with - * INSN_CONFIG_SET_COUNTER_MODE */ +/* + * mode bits for NI general-purpose counters, set with + * INSN_CONFIG_SET_COUNTER_MODE + */ #define NI_GPCT_COUNTING_MODE_SHIFT 16 #define NI_GPCT_INDEX_PHASE_BITSHIFT 20 #define NI_GPCT_COUNTING_DIRECTION_SHIFT 24 @@ -624,8 +627,10 @@ enum ni_gpct_mode_bits { NI_GPCT_INVERT_OUTPUT_BIT = 0x20000000 }; -/* Bits for setting a clock source with - * INSN_CONFIG_SET_CLOCK_SRC when using NI general-purpose counters. */ +/* + * Bits for setting a clock source with + * INSN_CONFIG_SET_CLOCK_SRC when using NI general-purpose counters. + */ enum ni_gpct_clock_source_bits { NI_GPCT_CLOCK_SRC_SELECT_MASK = 0x3f, NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS = 0x0, @@ -656,9 +661,11 @@ enum ni_gpct_clock_source_bits { /* no pfi on NI 660x */ #define NI_GPCT_PFI_CLOCK_SRC_BITS(x) (0x20 + (x)) -/* Possibilities for setting a gate source with -INSN_CONFIG_SET_GATE_SRC when using NI general-purpose counters. -May be bitwise-or'd with CR_EDGE or CR_INVERT. */ +/* + * Possibilities for setting a gate source with + * INSN_CONFIG_SET_GATE_SRC when using NI general-purpose counters. + * May be bitwise-or'd with CR_EDGE or CR_INVERT. + */ enum ni_gpct_gate_select { /* m-series gates */ NI_GPCT_TIMESTAMP_MUX_GATE_SELECT = 0x0, @@ -675,9 +682,11 @@ enum ni_gpct_gate_select { /* more gates for 660x "second gate" */ NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT = 0x201, NI_GPCT_SELECTED_GATE_GATE_SELECT = 0x21e, - /* m-series "second gate" sources are unknown, + /* + * m-series "second gate" sources are unknown, * we should add them here with an offset of 0x300 when - * known. */ + * known. + */ NI_GPCT_DISABLED_GATE_SELECT = 0x8000, }; @@ -686,8 +695,10 @@ enum ni_gpct_gate_select { #define NI_GPCT_PFI_GATE_SELECT(x) NI_USUAL_PFI_SELECT(x) #define NI_GPCT_UP_DOWN_PIN_GATE_SELECT(x) (0x202 + (x)) -/* Possibilities for setting a source with -INSN_CONFIG_SET_OTHER_SRC when using NI general-purpose counters. */ +/* + * Possibilities for setting a source with + * INSN_CONFIG_SET_OTHER_SRC when using NI general-purpose counters. + */ enum ni_gpct_other_index { NI_GPCT_SOURCE_ENCODER_A, NI_GPCT_SOURCE_ENCODER_B, @@ -702,18 +713,24 @@ enum ni_gpct_other_select { #define NI_GPCT_PFI_OTHER_SELECT(x) NI_USUAL_PFI_SELECT(x) -/* start sources for ni general-purpose counters for use with -INSN_CONFIG_ARM */ +/* + * start sources for ni general-purpose counters for use with + * INSN_CONFIG_ARM + */ enum ni_gpct_arm_source { NI_GPCT_ARM_IMMEDIATE = 0x0, - NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1, /* Start both the counter - * and the adjacent paired - * counter simultaneously */ - /* NI doesn't document bits for selecting hardware arm triggers. + /* + * Start both the counter and the adjacent pared + * counter simultaneously + */ + NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1, + /* + * NI doesn't document bits for selecting hardware arm triggers. * If the NI_GPCT_ARM_UNKNOWN bit is set, we will pass the least * significant bits (3 bits for 660x or 5 bits for m-series) * through to the hardware. This will at least allow someone to - * figure out what the bits do later. */ + * figure out what the bits do later. + */ NI_GPCT_ARM_UNKNOWN = 0x1000, }; @@ -728,8 +745,10 @@ enum ni_gpct_filter_select { NI_GPCT_FILTER_2x_TIMEBASE_3 = 0x6 }; -/* PFI digital filtering options for ni m-series for use with - * INSN_CONFIG_FILTER. */ +/* + * PFI digital filtering options for ni m-series for use with + * INSN_CONFIG_FILTER. + */ enum ni_pfi_filter_select { NI_PFI_FILTER_OFF = 0x0, NI_PFI_FILTER_125ns = 0x1, @@ -740,9 +759,11 @@ enum ni_pfi_filter_select { /* master clock sources for ni mio boards and INSN_CONFIG_SET_CLOCK_SRC */ enum ni_mio_clock_source { NI_MIO_INTERNAL_CLOCK = 0, - NI_MIO_RTSI_CLOCK = 1, /* doesn't work for m-series, use - NI_MIO_PLL_RTSI_CLOCK() */ - /* the NI_MIO_PLL_* sources are m-series only */ + /* + * Doesn't work for m-series, use NI_MIO_PLL_RTSI_CLOCK() + * the NI_MIO_PLL_* sources are m-series only + */ + NI_MIO_RTSI_CLOCK = 1, NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK = 2, NI_MIO_PLL_PXI10_CLOCK = 3, NI_MIO_PLL_RTSI0_CLOCK = 4 @@ -750,9 +771,11 @@ enum ni_mio_clock_source { #define NI_MIO_PLL_RTSI_CLOCK(x) (NI_MIO_PLL_RTSI0_CLOCK + (x)) -/* Signals which can be routed to an NI RTSI pin with INSN_CONFIG_SET_ROUTING. - The numbers assigned are not arbitrary, they correspond to the bits required - to program the board. */ +/* + * Signals which can be routed to an NI RTSI pin with INSN_CONFIG_SET_ROUTING. + * The numbers assigned are not arbitrary, they correspond to the bits required + * to program the board. + */ enum ni_rtsi_routing { NI_RTSI_OUTPUT_ADR_START1 = 0, NI_RTSI_OUTPUT_ADR_START2 = 1, @@ -763,17 +786,19 @@ enum ni_rtsi_routing { NI_RTSI_OUTPUT_G_GATE0 = 6, NI_RTSI_OUTPUT_RGOUT0 = 7, NI_RTSI_OUTPUT_RTSI_BRD_0 = 8, - NI_RTSI_OUTPUT_RTSI_OSC = 12 /* pre-m-series always have RTSI - * clock on line 7 */ + /* Pre-m-series always have RTSI clock on line 7 */ + NI_RTSI_OUTPUT_RTSI_OSC = 12 }; #define NI_RTSI_OUTPUT_RTSI_BRD(x) (NI_RTSI_OUTPUT_RTSI_BRD_0 + (x)) -/* Signals which can be routed to an NI PFI pin on an m-series board with +/* + * Signals which can be routed to an NI PFI pin on an m-series board with * INSN_CONFIG_SET_ROUTING. These numbers are also returned by * INSN_CONFIG_GET_ROUTING on pre-m-series boards, even though their routing * cannot be changed. The numbers assigned are not arbitrary, they correspond - * to the bits required to program the board. */ + * to the bits required to program the board. + */ enum ni_pfi_routing { NI_PFI_OUTPUT_PFI_DEFAULT = 0, NI_PFI_OUTPUT_AI_START1 = 1, @@ -803,20 +828,24 @@ enum ni_pfi_routing { #define NI_PFI_OUTPUT_RTSI(x) (NI_PFI_OUTPUT_RTSI0 + (x)) -/* Signals which can be routed to output on a NI PFI pin on a 660x board - with INSN_CONFIG_SET_ROUTING. The numbers assigned are - not arbitrary, they correspond to the bits required - to program the board. Lines 0 to 7 can only be set to - NI_660X_PFI_OUTPUT_DIO. Lines 32 to 39 can only be set to - NI_660X_PFI_OUTPUT_COUNTER. */ +/* + * Signals which can be routed to output on a NI PFI pin on a 660x board + * with INSN_CONFIG_SET_ROUTING. The numbers assigned are + * not arbitrary, they correspond to the bits required + * to program the board. Lines 0 to 7 can only be set to + * NI_660X_PFI_OUTPUT_DIO. Lines 32 to 39 can only be set to + * NI_660X_PFI_OUTPUT_COUNTER. + */ enum ni_660x_pfi_routing { NI_660X_PFI_OUTPUT_COUNTER = 1, /* counter */ NI_660X_PFI_OUTPUT_DIO = 2, /* static digital output */ }; -/* NI External Trigger lines. These values are not arbitrary, but are related +/* + * NI External Trigger lines. These values are not arbitrary, but are related * to the bits required to program the board (offset by 1 for historical - * reasons). */ + * reasons). + */ #define NI_EXT_PFI(x) (NI_USUAL_PFI_SELECT(x) - 1) #define NI_EXT_RTSI(x) (NI_USUAL_RTSI_SELECT(x) - 1) @@ -827,9 +856,11 @@ enum comedi_counter_status_flags { COMEDI_COUNTER_TERMINAL_COUNT = 0x4, }; -/* Clock sources for CDIO subdevice on NI m-series boards. Used as the +/* + * Clock sources for CDIO subdevice on NI m-series boards. Used as the * scan_begin_arg for a comedi_command. These sources may also be bitwise-or'd - * with CR_INVERT to change polarity. */ + * with CR_INVERT to change polarity. + */ enum ni_m_series_cdio_scan_begin_src { NI_CDIO_SCAN_BEGIN_SRC_GROUND = 0, NI_CDIO_SCAN_BEGIN_SRC_AI_START = 18, @@ -846,38 +877,50 @@ enum ni_m_series_cdio_scan_begin_src { #define NI_CDIO_SCAN_BEGIN_SRC_PFI(x) NI_USUAL_PFI_SELECT(x) #define NI_CDIO_SCAN_BEGIN_SRC_RTSI(x) NI_USUAL_RTSI_SELECT(x) -/* scan_begin_src for scan_begin_arg==TRIG_EXT with analog output command on NI +/* + * scan_begin_src for scan_begin_arg==TRIG_EXT with analog output command on NI * boards. These scan begin sources can also be bitwise-or'd with CR_INVERT to - * change polarity. */ + * change polarity. + */ #define NI_AO_SCAN_BEGIN_SRC_PFI(x) NI_USUAL_PFI_SELECT(x) #define NI_AO_SCAN_BEGIN_SRC_RTSI(x) NI_USUAL_RTSI_SELECT(x) -/* Bits for setting a clock source with - * INSN_CONFIG_SET_CLOCK_SRC when using NI frequency output subdevice. */ +/* + * Bits for setting a clock source with + * INSN_CONFIG_SET_CLOCK_SRC when using NI frequency output subdevice. + */ enum ni_freq_out_clock_source_bits { NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC, /* 10 MHz */ NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC /* 100 KHz */ }; -/* Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for - * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */ +/* + * Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for + * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). + */ enum amplc_dio_clock_source { - AMPLC_DIO_CLK_CLKN, /* per channel external clock - input/output pin (pin is only an - input when clock source set to this - value, otherwise it is an output) */ + /* + * Per channel external clock + * input/output pin (pin is only an + * input when clock source set to this value, + * otherwise it is an output) + */ + AMPLC_DIO_CLK_CLKN, AMPLC_DIO_CLK_10MHZ, /* 10 MHz internal clock */ AMPLC_DIO_CLK_1MHZ, /* 1 MHz internal clock */ AMPLC_DIO_CLK_100KHZ, /* 100 kHz internal clock */ AMPLC_DIO_CLK_10KHZ, /* 10 kHz internal clock */ AMPLC_DIO_CLK_1KHZ, /* 1 kHz internal clock */ - AMPLC_DIO_CLK_OUTNM1, /* output of preceding counter channel - (for channel 0, preceding counter - channel is channel 2 on preceding - counter subdevice, for first counter - subdevice, preceding counter - subdevice is the last counter - subdevice) */ + /* + * Output of preceding counter channel + * (for channel 0, preceding counter + * channel is channel 2 on preceding + * counter subdevice, for first counter + * subdevice, preceding counter + * subdevice is the last counter + * subdevice) + */ + AMPLC_DIO_CLK_OUTNM1, AMPLC_DIO_CLK_EXT, /* per chip external input pin */ /* the following are "enhanced" clock sources for PCIe models */ AMPLC_DIO_CLK_VCC, /* clock input HIGH */ @@ -886,35 +929,39 @@ enum amplc_dio_clock_source { AMPLC_DIO_CLK_20MHZ /* 20 MHz internal clock */ }; -/* Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for - * timer subdevice on some Amplicon DIO PCIe boards (amplc_dio200 driver). */ +/* + * Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for + * timer subdevice on some Amplicon DIO PCIe boards (amplc_dio200 driver). + */ enum amplc_dio_ts_clock_src { AMPLC_DIO_TS_CLK_1GHZ, /* 1 ns period with 20 ns granularity */ AMPLC_DIO_TS_CLK_1MHZ, /* 1 us period */ AMPLC_DIO_TS_CLK_1KHZ /* 1 ms period */ }; -/* Values for setting a gate source with INSN_CONFIG_SET_GATE_SRC for - * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */ +/* + * Values for setting a gate source with INSN_CONFIG_SET_GATE_SRC for + * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). + */ enum amplc_dio_gate_source { AMPLC_DIO_GAT_VCC, /* internal high logic level */ AMPLC_DIO_GAT_GND, /* internal low logic level */ AMPLC_DIO_GAT_GATN, /* per channel external gate input */ - AMPLC_DIO_GAT_NOUTNM2, /* negated output of counter channel - minus 2 (for channels 0 or 1, - channel minus 2 is channel 1 or 2 on - the preceding counter subdevice, for - the first counter subdevice the - preceding counter subdevice is the - last counter subdevice) */ + /* + * negated output of counter channel minus 2 + * (for channels 0 or 1, channel minus 2 is channel 1 or 2 on + * the preceding counter subdevice, for the first counter subdevice + * the preceding counter subdevice is the last counter subdevice) + */ + AMPLC_DIO_GAT_NOUTNM2, AMPLC_DIO_GAT_RESERVED4, AMPLC_DIO_GAT_RESERVED5, AMPLC_DIO_GAT_RESERVED6, AMPLC_DIO_GAT_RESERVED7, /* the following are "enhanced" gate sources for PCIe models */ AMPLC_DIO_GAT_NGATN = 6, /* negated per channel gate input */ - AMPLC_DIO_GAT_OUTNM2, /* non-negated output of counter - channel minus 2 */ + /* non-negated output of counter channel minus 2 */ + AMPLC_DIO_GAT_OUTNM2, AMPLC_DIO_GAT_PAT_PRESENT, /* "pattern present" signal */ AMPLC_DIO_GAT_PAT_OCCURRED, /* "pattern occurred" latched */ AMPLC_DIO_GAT_PAT_GONE, /* "pattern gone away" latched */ -- GitLab From c9e5ec256c7af7f1558290b66dd145326c403a18 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Sat, 14 Nov 2015 19:19:10 +0100 Subject: [PATCH 1912/2855] staging: comedi: ni_mio_common: add "no_channel" versions of some functions ni_release_ai_mite_channel(), ni_release_ao_mite_channel(), ni_release_gpct_mite_channel() and ni_release_cdo_mite_channel() call functions which interpret -1 as a special value meaning "no channel". This patch adds explicit "no_channel" versions instead. On the other hand, after "no_channel" versions are used, ni_set_ai_dma_channel(), ni_set_ao_dma_channel(), ni_set_gpct_dma_channel(), ni_set_cdo_dma_channel() are called with actual "channel" parameter being always unsigned, so their signatures are changed accordingly. A side benefit of the changes is suppressesing 4 sparse warnings: "warning: shift too big (4294967295) for type int". Signed-off-by: Andrzej Pietrasiewicz Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/ni_mio_common.c | 82 +++++++++++-------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index cbb44fc6940bc..5e8130a7d6708 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -579,48 +579,54 @@ static inline unsigned ni_stc_dma_channel_select_bitfield(unsigned channel) return 0; } -/* negative channel means no channel */ -static inline void ni_set_ai_dma_channel(struct comedi_device *dev, int channel) +static inline void ni_set_ai_dma_channel(struct comedi_device *dev, + unsigned channel) { - unsigned bits = 0; - - if (channel >= 0) - bits = ni_stc_dma_channel_select_bitfield(channel); + unsigned bits = ni_stc_dma_channel_select_bitfield(channel); ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG, NI_E_DMA_AI_SEL_MASK, NI_E_DMA_AI_SEL(bits)); } -/* negative channel means no channel */ -static inline void ni_set_ao_dma_channel(struct comedi_device *dev, int channel) +static inline void ni_set_ai_dma_no_channel(struct comedi_device *dev) { - unsigned bits = 0; + ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG, NI_E_DMA_AI_SEL_MASK, 0); +} - if (channel >= 0) - bits = ni_stc_dma_channel_select_bitfield(channel); +static inline void ni_set_ao_dma_channel(struct comedi_device *dev, + unsigned channel) +{ + unsigned bits = ni_stc_dma_channel_select_bitfield(channel); ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG, NI_E_DMA_AO_SEL_MASK, NI_E_DMA_AO_SEL(bits)); } -/* negative channel means no channel */ +static inline void ni_set_ao_dma_no_channel(struct comedi_device *dev) +{ + ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG, NI_E_DMA_AO_SEL_MASK, 0); +} + static inline void ni_set_gpct_dma_channel(struct comedi_device *dev, unsigned gpct_index, - int channel) + unsigned channel) { - unsigned bits = 0; - - if (channel >= 0) - bits = ni_stc_dma_channel_select_bitfield(channel); + unsigned bits = ni_stc_dma_channel_select_bitfield(channel); ni_set_bitfield(dev, NI_E_DMA_G0_G1_SEL_REG, NI_E_DMA_G0_G1_SEL_MASK(gpct_index), NI_E_DMA_G0_G1_SEL(gpct_index, bits)); } -/* negative mite_channel means no channel */ +static inline void ni_set_gpct_dma_no_channel(struct comedi_device *dev, + unsigned gpct_index) +{ + ni_set_bitfield(dev, NI_E_DMA_G0_G1_SEL_REG, + NI_E_DMA_G0_G1_SEL_MASK(gpct_index), 0); +} + static inline void ni_set_cdo_dma_channel(struct comedi_device *dev, - int mite_channel) + unsigned mite_channel) { struct ni_private *devpriv = dev->private; unsigned long flags; @@ -628,16 +634,26 @@ static inline void ni_set_cdo_dma_channel(struct comedi_device *dev, spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); devpriv->cdio_dma_select_reg &= ~NI_M_CDIO_DMA_SEL_CDO_MASK; - if (mite_channel >= 0) { - /* - * XXX just guessing ni_stc_dma_channel_select_bitfield() - * returns the right bits, under the assumption the cdio dma - * selection works just like ai/ao/gpct. - * Definitely works for dma channels 0 and 1. - */ - bits = ni_stc_dma_channel_select_bitfield(mite_channel); - devpriv->cdio_dma_select_reg |= NI_M_CDIO_DMA_SEL_CDO(bits); - } + /* + * XXX just guessing ni_stc_dma_channel_select_bitfield() + * returns the right bits, under the assumption the cdio dma + * selection works just like ai/ao/gpct. + * Definitely works for dma channels 0 and 1. + */ + bits = ni_stc_dma_channel_select_bitfield(mite_channel); + devpriv->cdio_dma_select_reg |= NI_M_CDIO_DMA_SEL_CDO(bits); + ni_writeb(dev, devpriv->cdio_dma_select_reg, NI_M_CDIO_DMA_SEL_REG); + mmiowb(); + spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags); +} + +static inline void ni_set_cdo_dma_no_channel(struct comedi_device *dev) +{ + struct ni_private *devpriv = dev->private; + unsigned long flags; + + spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); + devpriv->cdio_dma_select_reg &= ~NI_M_CDIO_DMA_SEL_CDO_MASK; ni_writeb(dev, devpriv->cdio_dma_select_reg, NI_M_CDIO_DMA_SEL_REG); mmiowb(); spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags); @@ -745,7 +761,7 @@ static void ni_release_ai_mite_channel(struct comedi_device *dev) spin_lock_irqsave(&devpriv->mite_channel_lock, flags); if (devpriv->ai_mite_chan) { - ni_set_ai_dma_channel(dev, -1); + ni_set_ai_dma_no_channel(dev); mite_release_channel(devpriv->ai_mite_chan); devpriv->ai_mite_chan = NULL; } @@ -761,7 +777,7 @@ static void ni_release_ao_mite_channel(struct comedi_device *dev) spin_lock_irqsave(&devpriv->mite_channel_lock, flags); if (devpriv->ao_mite_chan) { - ni_set_ao_dma_channel(dev, -1); + ni_set_ao_dma_no_channel(dev); mite_release_channel(devpriv->ao_mite_chan); devpriv->ao_mite_chan = NULL; } @@ -781,7 +797,7 @@ static void ni_release_gpct_mite_channel(struct comedi_device *dev, struct mite_channel *mite_chan = devpriv->counter_dev->counters[gpct_index].mite_chan; - ni_set_gpct_dma_channel(dev, gpct_index, -1); + ni_set_gpct_dma_no_channel(dev, gpct_index); ni_tio_set_mite_channel(&devpriv-> counter_dev->counters[gpct_index], NULL); @@ -799,7 +815,7 @@ static void ni_release_cdo_mite_channel(struct comedi_device *dev) spin_lock_irqsave(&devpriv->mite_channel_lock, flags); if (devpriv->cdo_mite_chan) { - ni_set_cdo_dma_channel(dev, -1); + ni_set_cdo_dma_no_channel(dev); mite_release_channel(devpriv->cdo_mite_chan); devpriv->cdo_mite_chan = NULL; } -- GitLab From cff93d73f7d9a8ec6fff057e0ee8ccd89a1ed6ec Mon Sep 17 00:00:00 2001 From: Ranjith Thangavel Date: Mon, 16 Nov 2015 22:26:15 +0530 Subject: [PATCH 1913/2855] comedi: ni_6527: Fix coding style - use BIT macro BIT macro is used for defining BIT location instead of shifting operator - coding style issue Signed-off-by: Ranjith Thangavel Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_6527.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 62a817e4cd645..84c62e2560943 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -42,24 +42,24 @@ #define NI6527_DO_REG(x) (0x03 + (x)) #define NI6527_ID_REG 0x06 #define NI6527_CLR_REG 0x07 -#define NI6527_CLR_EDGE (1 << 3) -#define NI6527_CLR_OVERFLOW (1 << 2) -#define NI6527_CLR_FILT (1 << 1) -#define NI6527_CLR_INTERVAL (1 << 0) +#define NI6527_CLR_EDGE BIT(3) +#define NI6527_CLR_OVERFLOW BIT(2) +#define NI6527_CLR_FILT BIT(1) +#define NI6527_CLR_INTERVAL BIT(0) #define NI6527_CLR_IRQS (NI6527_CLR_EDGE | NI6527_CLR_OVERFLOW) #define NI6527_CLR_RESET_FILT (NI6527_CLR_FILT | NI6527_CLR_INTERVAL) #define NI6527_FILT_INTERVAL_REG(x) (0x08 + (x)) #define NI6527_FILT_ENA_REG(x) (0x0c + (x)) #define NI6527_STATUS_REG 0x14 -#define NI6527_STATUS_IRQ (1 << 2) -#define NI6527_STATUS_OVERFLOW (1 << 1) -#define NI6527_STATUS_EDGE (1 << 0) +#define NI6527_STATUS_IRQ BIT(2) +#define NI6527_STATUS_OVERFLOW BIT(1) +#define NI6527_STATUS_EDGE BIT(0) #define NI6527_CTRL_REG 0x15 -#define NI6527_CTRL_FALLING (1 << 4) -#define NI6527_CTRL_RISING (1 << 3) -#define NI6527_CTRL_IRQ (1 << 2) -#define NI6527_CTRL_OVERFLOW (1 << 1) -#define NI6527_CTRL_EDGE (1 << 0) +#define NI6527_CTRL_FALLING BIT(4) +#define NI6527_CTRL_RISING BIT(3) +#define NI6527_CTRL_IRQ BIT(2) +#define NI6527_CTRL_OVERFLOW BIT(1) +#define NI6527_CTRL_EDGE BIT(0) #define NI6527_CTRL_DISABLE_IRQS 0 #define NI6527_CTRL_ENABLE_IRQS (NI6527_CTRL_FALLING | \ NI6527_CTRL_RISING | \ -- GitLab From e29641c21ef24e9e515e02ffcb213f4d51fd097e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:02 -0700 Subject: [PATCH 1914/2855] staging: comedi: adv_pci_dio: remove unnecessary function separation comments These are not necessary and just add cruft. Remove them. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 81b2cf27182c4..28ed1cd3e9faf 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -298,9 +298,6 @@ static const struct dio_boardtype boardtypes[] = { }, }; -/* -============================================================================== -*/ static int pci_dio_insn_bits_di_b(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -315,9 +312,6 @@ static int pci_dio_insn_bits_di_b(struct comedi_device *dev, return insn->n; } -/* -============================================================================== -*/ static int pci_dio_insn_bits_di_w(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -497,9 +491,6 @@ static int pci_dio_add_di(struct comedi_device *dev, return 0; } -/* -============================================================================== -*/ static int pci_dio_add_do(struct comedi_device *dev, struct comedi_subdevice *s, const struct diosubd_data *d) -- GitLab From 744099055fd51cfb8db49784be23032751a3a228 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:03 -0700 Subject: [PATCH 1915/2855] staging: comedi: adv_pci_dio: tidy up comedi driver block comment Reformat the bolck comment in the kernel CodingStyle. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 40 +++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 28ed1cd3e9faf..9794502a8565c 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -4,30 +4,24 @@ * Author: Michal Dobes * * Hardware driver for Advantech PCI DIO cards. -*/ + */ + /* -Driver: adv_pci_dio -Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1735U, - PCI-1736UP, PCI-1739U, PCI-1750, PCI-1751, PCI-1752, - PCI-1753/E, PCI-1754, PCI-1756, PCI-1762 -Author: Michal Dobes -Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733, - PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U, PCI-1750, - PCI-1751, PCI-1752, PCI-1753, - PCI-1753+PCI-1753E, PCI-1754, PCI-1756, - PCI-1762 -Status: untested -Updated: Mon, 09 Jan 2012 12:40:46 +0000 - -This driver supports now only insn interface for DI/DO/DIO. - -Configuration options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first available PCI - device will be used. - -*/ + * Driver: adv_pci_dio + * Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1735U, + * PCI-1736UP, PCI-1739U, PCI-1750, PCI-1751, PCI-1752, + * PCI-1753/E, PCI-1754, PCI-1756, PCI-1762 + * Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733, + * PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U, PCI-1750, + * PCI-1751, PCI-1752, PCI-1753, + * PCI-1753+PCI-1753E, PCI-1754, PCI-1756, + * PCI-1762 + * Author: Michal Dobes + * Updated: Mon, 09 Jan 2012 12:40:46 +0000 + * Status: untested + * + * Configuration Options: not applicable, uses PCI auto config + */ #include #include -- GitLab From c1e07ea22a46c39cbd632233f716ec3a591d94ed Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:04 -0700 Subject: [PATCH 1916/2855] staging: comedi: adv_pci_dio: remove 'main_pci_region' boardinfo All the boards use PCI BAR2 for the dev->iobase except for the pci1736 which uses PCI BAR0. Just use the board->cardtype to determine which PCI BAR to use. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 30 +++++--------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 9794502a8565c..b1f966e7f392c 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -53,8 +53,6 @@ enum hw_io_access { #define MAX_DIO_SUBDEVG 2 /* max number of DIO subdevices group per * card */ -#define PCIDIO_MAINREG 2 /* main I/O region for all Advantech cards? */ - /* Register offset definitions */ /* Advantech PCI-1730/3/4 */ #define PCI1730_IDI 0 /* R: Isolated digital input 0-15 */ @@ -83,7 +81,6 @@ enum hw_io_access { * interrupts */ #define PCI1736_3_INT_CLR 0x10 /* R/W: clear interrupts */ #define PCI1736_BOARDID 4 /* R: Board I/D switch for 1736UP */ -#define PCI1736_MAINREG 0 /* Normal register (2) doesn't work */ /* Advantech PCI-1739U */ #define PCI1739_DIO 0 /* R/W: begin of 8255 registers block */ @@ -144,7 +141,6 @@ struct diosubd_data { struct dio_boardtype { const char *name; /* board name */ - int main_pci_region; /* main I/O PCI region */ enum hw_cards_id cardtype; int nsubdevs; struct diosubd_data sdi[MAX_DI_SUBDEVS]; /* DI chans */ @@ -158,7 +154,6 @@ struct dio_boardtype { static const struct dio_boardtype boardtypes[] = { [TYPE_PCI1730] = { .name = "pci1730", - .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1730, .nsubdevs = 5, .sdi[0] = { 16, PCI1730_DI, 2, 0, }, @@ -170,7 +165,6 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1733] = { .name = "pci1733", - .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1733, .nsubdevs = 2, .sdi[1] = { 32, PCI1733_IDI, 4, 0, }, @@ -179,7 +173,6 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1734] = { .name = "pci1734", - .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1734, .nsubdevs = 2, .sdo[1] = { 32, PCI1734_IDO, 4, 0, }, @@ -188,7 +181,6 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1735] = { .name = "pci1735", - .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1735, .nsubdevs = 4, .sdi[0] = { 32, PCI1735_DI, 4, 0, }, @@ -199,7 +191,6 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1736] = { .name = "pci1736", - .main_pci_region = PCI1736_MAINREG, .cardtype = TYPE_PCI1736, .nsubdevs = 3, .sdi[1] = { 16, PCI1736_IDI, 2, 0, }, @@ -209,7 +200,6 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1739] = { .name = "pci1739", - .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1739, .nsubdevs = 2, .sdio[0] = { 48, PCI1739_DIO, 2, 0, }, @@ -217,7 +207,6 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1750] = { .name = "pci1750", - .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1750, .nsubdevs = 2, .sdi[1] = { 16, PCI1750_IDI, 2, 0, }, @@ -226,7 +215,6 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1751] = { .name = "pci1751", - .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1751, .nsubdevs = 3, .sdio[0] = { 48, PCI1751_DIO, 2, 0, }, @@ -235,7 +223,6 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1752] = { .name = "pci1752", - .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1752, .nsubdevs = 3, .sdo[0] = { 32, PCI1752_IDO, 2, 0, }, @@ -245,7 +232,6 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1753] = { .name = "pci1753", - .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1753, .nsubdevs = 4, .sdio[0] = { 96, PCI1753_DIO, 4, 0, }, @@ -253,7 +239,6 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1753E] = { .name = "pci1753e", - .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1753E, .nsubdevs = 8, .sdio[0] = { 96, PCI1753_DIO, 4, 0, }, @@ -262,7 +247,6 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1754] = { .name = "pci1754", - .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1754, .nsubdevs = 3, .sdi[0] = { 32, PCI1754_IDI, 2, 0, }, @@ -272,7 +256,6 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1756] = { .name = "pci1756", - .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1756, .nsubdevs = 3, .sdi[1] = { 32, PCI1756_IDI, 2, 0, }, @@ -282,7 +265,6 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1762] = { .name = "pci1762", - .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1762, .nsubdevs = 3, .sdi[1] = { 16, PCI1762_IDI, 1, 0, }, @@ -525,14 +507,13 @@ static unsigned long pci_dio_override_cardtype(struct pci_dev *pcidev, return cardtype; if (pci_enable_device(pcidev) < 0) return cardtype; - if (pci_request_region(pcidev, PCIDIO_MAINREG, "adv_pci_dio") == 0) { + if (pci_request_region(pcidev, 2, "adv_pci_dio") == 0) { /* * This test is based on Advantech's "advdaq" driver source * (which declares its module licence as "GPL" although the * driver source does not include a "COPYING" file). */ - unsigned long reg = - pci_resource_start(pcidev, PCIDIO_MAINREG) + 53; + unsigned long reg = pci_resource_start(pcidev, 2) + 53; outb(0x05, reg); if ((inb(reg) & 0x07) == 0x02) { @@ -540,7 +521,7 @@ static unsigned long pci_dio_override_cardtype(struct pci_dev *pcidev, if ((inb(reg) & 0x07) == 0x05) cardtype = TYPE_PCI1753E; } - pci_release_region(pcidev, PCIDIO_MAINREG); + pci_release_region(pcidev, 2); } pci_disable_device(pcidev); return cardtype; @@ -564,7 +545,10 @@ static int pci_dio_auto_attach(struct comedi_device *dev, ret = comedi_pci_enable(dev); if (ret) return ret; - dev->iobase = pci_resource_start(pcidev, board->main_pci_region); + if (board->cardtype == TYPE_PCI1736) + dev->iobase = pci_resource_start(pcidev, 0); + else + dev->iobase = pci_resource_start(pcidev, 2); ret = comedi_alloc_subdevices(dev, board->nsubdevs); if (ret) -- GitLab From afe5c118bd07edcb00503bd0f4ab83a6e56ae9d8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:05 -0700 Subject: [PATCH 1917/2855] staging: comedi: adv_pci_dio: post increment 'subdev' in (*auto_attach) For aesthetics, post-increment the 'subdev' index when used to get a comedi_subdevice pointer instead of incrementing it after the subdevice is initialized. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index b1f966e7f392c..4d4b38c1d0fcc 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -557,38 +557,34 @@ static int pci_dio_auto_attach(struct comedi_device *dev, subdev = 0; for (i = 0; i < MAX_DI_SUBDEVS; i++) if (board->sdi[i].chans) { - s = &dev->subdevices[subdev]; + s = &dev->subdevices[subdev++]; pci_dio_add_di(dev, s, &board->sdi[i]); - subdev++; } for (i = 0; i < MAX_DO_SUBDEVS; i++) if (board->sdo[i].chans) { - s = &dev->subdevices[subdev]; + s = &dev->subdevices[subdev++]; pci_dio_add_do(dev, s, &board->sdo[i]); - subdev++; } for (i = 0; i < MAX_DIO_SUBDEVG; i++) for (j = 0; j < board->sdio[i].regs; j++) { - s = &dev->subdevices[subdev]; + s = &dev->subdevices[subdev++]; ret = subdev_8255_init(dev, s, NULL, board->sdio[i].addr + j * I8255_SIZE); if (ret) return ret; - subdev++; } if (board->boardid.chans) { - s = &dev->subdevices[subdev]; + s = &dev->subdevices[subdev++]; s->type = COMEDI_SUBD_DI; pci_dio_add_di(dev, s, &board->boardid); - subdev++; } if (board->timer_regbase) { - s = &dev->subdevices[subdev]; + s = &dev->subdevices[subdev++]; dev->pacer = comedi_8254_init(dev->iobase + board->timer_regbase, @@ -597,8 +593,6 @@ static int pci_dio_auto_attach(struct comedi_device *dev, return -ENOMEM; comedi_8254_subdevice_init(s, dev->pacer); - - subdev++; } pci_dio_reset(dev); -- GitLab From a1132fc1bb6914940aeaa68f32a79ca846e2090f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:06 -0700 Subject: [PATCH 1918/2855] staging: comedi: adv_pci_dio: use a const pointer to the diosubd_data For aesthetics, use a const pointer to access the diosubd_data in the boardinfo when doing the (*auto_attach).. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 31 ++++++++++++-------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 4d4b38c1d0fcc..5da1e623b01fa 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -532,6 +532,7 @@ static int pci_dio_auto_attach(struct comedi_device *dev, { struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct dio_boardtype *board = NULL; + const struct diosubd_data *d; struct comedi_subdevice *s; int ret, subdev, i, j; @@ -555,32 +556,38 @@ static int pci_dio_auto_attach(struct comedi_device *dev, return ret; subdev = 0; - for (i = 0; i < MAX_DI_SUBDEVS; i++) - if (board->sdi[i].chans) { + for (i = 0; i < MAX_DI_SUBDEVS; i++) { + d = &board->sdi[i]; + if (d->chans) { s = &dev->subdevices[subdev++]; - pci_dio_add_di(dev, s, &board->sdi[i]); + pci_dio_add_di(dev, s, d); } + } - for (i = 0; i < MAX_DO_SUBDEVS; i++) - if (board->sdo[i].chans) { + for (i = 0; i < MAX_DO_SUBDEVS; i++) { + d = &board->sdo[i]; + if (d->chans) { s = &dev->subdevices[subdev++]; - pci_dio_add_do(dev, s, &board->sdo[i]); + pci_dio_add_do(dev, s, d); } + } - for (i = 0; i < MAX_DIO_SUBDEVG; i++) - for (j = 0; j < board->sdio[i].regs; j++) { + for (i = 0; i < MAX_DIO_SUBDEVG; i++) { + d = &board->sdio[i]; + for (j = 0; j < d->regs; j++) { s = &dev->subdevices[subdev++]; ret = subdev_8255_init(dev, s, NULL, - board->sdio[i].addr + - j * I8255_SIZE); + d->addr + j * I8255_SIZE); if (ret) return ret; } + } - if (board->boardid.chans) { + d = &board->boardid; + if (d->chans) { s = &dev->subdevices[subdev++]; s->type = COMEDI_SUBD_DI; - pci_dio_add_di(dev, s, &board->boardid); + pci_dio_add_di(dev, s, d); } if (board->timer_regbase) { -- GitLab From ac93d19adcd3ac4eecb246bdb6bc458c73865199 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:07 -0700 Subject: [PATCH 1919/2855] staging: comedi: adv_pci_dio: absorb pci_dio_add_do() This function initializes a digitial output subdevice. For aesthetics, absorb it into the (*auto_attach). Remove the improper initialization of the SDF_LSAMPL subdev_flag and len_chanlist. These are only used by subdevices that support async commands. Also remove the unnecessary initilaization of the subdevice 'state'. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 43 +++++++------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 5da1e623b01fa..deac3a8b9bb8a 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -467,34 +467,6 @@ static int pci_dio_add_di(struct comedi_device *dev, return 0; } -static int pci_dio_add_do(struct comedi_device *dev, - struct comedi_subdevice *s, - const struct diosubd_data *d) -{ - const struct dio_boardtype *board = dev->board_ptr; - - s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE; - if (d->chans > 16) - s->subdev_flags |= SDF_LSAMPL; - s->n_chan = d->chans; - s->maxdata = 1; - s->len_chanlist = d->chans; - s->range_table = &range_digital; - s->state = 0; - switch (board->io_access) { - case IO_8b: - s->insn_bits = pci_dio_insn_bits_do_b; - break; - case IO_16b: - s->insn_bits = pci_dio_insn_bits_do_w; - break; - } - s->private = (void *)d; - - return 0; -} - static unsigned long pci_dio_override_cardtype(struct pci_dev *pcidev, unsigned long cardtype) { @@ -568,7 +540,20 @@ static int pci_dio_auto_attach(struct comedi_device *dev, d = &board->sdo[i]; if (d->chans) { s = &dev->subdevices[subdev++]; - pci_dio_add_do(dev, s, d); + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = d->chans; + s->maxdata = 1; + s->range_table = &range_digital; + switch (board->io_access) { + case IO_8b: + s->insn_bits = pci_dio_insn_bits_do_b; + break; + case IO_16b: + s->insn_bits = pci_dio_insn_bits_do_w; + break; + } + s->private = (void *)d; } } -- GitLab From f5ceac9baacb7c83db4aba5ec059bc1a4f36273a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:08 -0700 Subject: [PATCH 1920/2855] staging: comedi: adv_pci_dio: absorb pci_dio_add_di() This function initializes a digitial input subdevices. For aesthetics, absorb it into the (*auto_attach). Remove the improper initialization of the SDF_LSAMPL subdev_flag and len_chanlist. These are only used by subdevices that support async commands. Also, remove the unnecessary 'specflags' from the diosubd_data. Only the boardid subdevice uses it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 127 +++++++++---------- 1 file changed, 62 insertions(+), 65 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index deac3a8b9bb8a..b0bbc7322cd5b 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -136,7 +136,6 @@ struct diosubd_data { int addr; /* PCI address ofset */ int regs; /* number of registers to read or 8255 subdevices */ - unsigned int specflags; /* addon subdevice flags */ }; struct dio_boardtype { @@ -156,36 +155,36 @@ static const struct dio_boardtype boardtypes[] = { .name = "pci1730", .cardtype = TYPE_PCI1730, .nsubdevs = 5, - .sdi[0] = { 16, PCI1730_DI, 2, 0, }, - .sdi[1] = { 16, PCI1730_IDI, 2, 0, }, - .sdo[0] = { 16, PCI1730_DO, 2, 0, }, - .sdo[1] = { 16, PCI1730_IDO, 2, 0, }, - .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, }, + .sdi[0] = { 16, PCI1730_DI, 2, }, + .sdi[1] = { 16, PCI1730_IDI, 2, }, + .sdo[0] = { 16, PCI1730_DO, 2, }, + .sdo[1] = { 16, PCI1730_IDO, 2, }, + .boardid = { 4, PCI173x_BOARDID, 1, }, .io_access = IO_8b, }, [TYPE_PCI1733] = { .name = "pci1733", .cardtype = TYPE_PCI1733, .nsubdevs = 2, - .sdi[1] = { 32, PCI1733_IDI, 4, 0, }, - .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, }, + .sdi[1] = { 32, PCI1733_IDI, 4, }, + .boardid = { 4, PCI173x_BOARDID, 1, }, .io_access = IO_8b, }, [TYPE_PCI1734] = { .name = "pci1734", .cardtype = TYPE_PCI1734, .nsubdevs = 2, - .sdo[1] = { 32, PCI1734_IDO, 4, 0, }, - .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, }, + .sdo[1] = { 32, PCI1734_IDO, 4, }, + .boardid = { 4, PCI173x_BOARDID, 1, }, .io_access = IO_8b, }, [TYPE_PCI1735] = { .name = "pci1735", .cardtype = TYPE_PCI1735, .nsubdevs = 4, - .sdi[0] = { 32, PCI1735_DI, 4, 0, }, - .sdo[0] = { 32, PCI1735_DO, 4, 0, }, - .boardid = { 4, PCI1735_BOARDID, 1, SDF_INTERNAL, }, + .sdi[0] = { 32, PCI1735_DI, 4, }, + .sdo[0] = { 32, PCI1735_DO, 4, }, + .boardid = { 4, PCI1735_BOARDID, 1, }, .timer_regbase = PCI1735_C8254, .io_access = IO_8b, }, @@ -193,31 +192,31 @@ static const struct dio_boardtype boardtypes[] = { .name = "pci1736", .cardtype = TYPE_PCI1736, .nsubdevs = 3, - .sdi[1] = { 16, PCI1736_IDI, 2, 0, }, - .sdo[1] = { 16, PCI1736_IDO, 2, 0, }, - .boardid = { 4, PCI1736_BOARDID, 1, SDF_INTERNAL, }, + .sdi[1] = { 16, PCI1736_IDI, 2, }, + .sdo[1] = { 16, PCI1736_IDO, 2, }, + .boardid = { 4, PCI1736_BOARDID, 1, }, .io_access = IO_8b, }, [TYPE_PCI1739] = { .name = "pci1739", .cardtype = TYPE_PCI1739, .nsubdevs = 2, - .sdio[0] = { 48, PCI1739_DIO, 2, 0, }, + .sdio[0] = { 48, PCI1739_DIO, 2, }, .io_access = IO_8b, }, [TYPE_PCI1750] = { .name = "pci1750", .cardtype = TYPE_PCI1750, .nsubdevs = 2, - .sdi[1] = { 16, PCI1750_IDI, 2, 0, }, - .sdo[1] = { 16, PCI1750_IDO, 2, 0, }, + .sdi[1] = { 16, PCI1750_IDI, 2, }, + .sdo[1] = { 16, PCI1750_IDO, 2, }, .io_access = IO_8b, }, [TYPE_PCI1751] = { .name = "pci1751", .cardtype = TYPE_PCI1751, .nsubdevs = 3, - .sdio[0] = { 48, PCI1751_DIO, 2, 0, }, + .sdio[0] = { 48, PCI1751_DIO, 2, }, .timer_regbase = PCI1751_CNT, .io_access = IO_8b, }, @@ -225,51 +224,51 @@ static const struct dio_boardtype boardtypes[] = { .name = "pci1752", .cardtype = TYPE_PCI1752, .nsubdevs = 3, - .sdo[0] = { 32, PCI1752_IDO, 2, 0, }, - .sdo[1] = { 32, PCI1752_IDO2, 2, 0, }, - .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, + .sdo[0] = { 32, PCI1752_IDO, 2, }, + .sdo[1] = { 32, PCI1752_IDO2, 2, }, + .boardid = { 4, PCI175x_BOARDID, 1, }, .io_access = IO_16b, }, [TYPE_PCI1753] = { .name = "pci1753", .cardtype = TYPE_PCI1753, .nsubdevs = 4, - .sdio[0] = { 96, PCI1753_DIO, 4, 0, }, + .sdio[0] = { 96, PCI1753_DIO, 4, }, .io_access = IO_8b, }, [TYPE_PCI1753E] = { .name = "pci1753e", .cardtype = TYPE_PCI1753E, .nsubdevs = 8, - .sdio[0] = { 96, PCI1753_DIO, 4, 0, }, - .sdio[1] = { 96, PCI1753E_DIO, 4, 0, }, + .sdio[0] = { 96, PCI1753_DIO, 4, }, + .sdio[1] = { 96, PCI1753E_DIO, 4, }, .io_access = IO_8b, }, [TYPE_PCI1754] = { .name = "pci1754", .cardtype = TYPE_PCI1754, .nsubdevs = 3, - .sdi[0] = { 32, PCI1754_IDI, 2, 0, }, - .sdi[1] = { 32, PCI1754_IDI2, 2, 0, }, - .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, + .sdi[0] = { 32, PCI1754_IDI, 2, }, + .sdi[1] = { 32, PCI1754_IDI2, 2, }, + .boardid = { 4, PCI175x_BOARDID, 1, }, .io_access = IO_16b, }, [TYPE_PCI1756] = { .name = "pci1756", .cardtype = TYPE_PCI1756, .nsubdevs = 3, - .sdi[1] = { 32, PCI1756_IDI, 2, 0, }, - .sdo[1] = { 32, PCI1756_IDO, 2, 0, }, - .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, + .sdi[1] = { 32, PCI1756_IDI, 2, }, + .sdo[1] = { 32, PCI1756_IDO, 2, }, + .boardid = { 4, PCI175x_BOARDID, 1, }, .io_access = IO_16b, }, [TYPE_PCI1762] = { .name = "pci1762", .cardtype = TYPE_PCI1762, .nsubdevs = 3, - .sdi[1] = { 16, PCI1762_IDI, 1, 0, }, - .sdo[1] = { 16, PCI1762_RO, 1, 0, }, - .boardid = { 4, PCI1762_BOARDID, 1, SDF_INTERNAL, }, + .sdi[1] = { 16, PCI1762_IDI, 1, }, + .sdo[1] = { 16, PCI1762_RO, 1, }, + .boardid = { 4, PCI1762_BOARDID, 1, }, .io_access = IO_16b, }, }; @@ -440,33 +439,6 @@ static int pci_dio_reset(struct comedi_device *dev) return 0; } -static int pci_dio_add_di(struct comedi_device *dev, - struct comedi_subdevice *s, - const struct diosubd_data *d) -{ - const struct dio_boardtype *board = dev->board_ptr; - - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | d->specflags; - if (d->chans > 16) - s->subdev_flags |= SDF_LSAMPL; - s->n_chan = d->chans; - s->maxdata = 1; - s->len_chanlist = d->chans; - s->range_table = &range_digital; - switch (board->io_access) { - case IO_8b: - s->insn_bits = pci_dio_insn_bits_di_b; - break; - case IO_16b: - s->insn_bits = pci_dio_insn_bits_di_w; - break; - } - s->private = (void *)d; - - return 0; -} - static unsigned long pci_dio_override_cardtype(struct pci_dev *pcidev, unsigned long cardtype) { @@ -532,7 +504,20 @@ static int pci_dio_auto_attach(struct comedi_device *dev, d = &board->sdi[i]; if (d->chans) { s = &dev->subdevices[subdev++]; - pci_dio_add_di(dev, s, d); + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = d->chans; + s->maxdata = 1; + s->range_table = &range_digital; + switch (board->io_access) { + case IO_8b: + s->insn_bits = pci_dio_insn_bits_di_b; + break; + case IO_16b: + s->insn_bits = pci_dio_insn_bits_di_w; + break; + } + s->private = (void *)d; } } @@ -571,8 +556,20 @@ static int pci_dio_auto_attach(struct comedi_device *dev, d = &board->boardid; if (d->chans) { s = &dev->subdevices[subdev++]; - s->type = COMEDI_SUBD_DI; - pci_dio_add_di(dev, s, d); + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE | SDF_INTERNAL; + s->n_chan = d->chans; + s->maxdata = 1; + s->range_table = &range_digital; + switch (board->io_access) { + case IO_8b: + s->insn_bits = pci_dio_insn_bits_di_b; + break; + case IO_16b: + s->insn_bits = pci_dio_insn_bits_di_w; + break; + } + s->private = (void *)d; } if (board->timer_regbase) { -- GitLab From 3cdddd6338749da4102788467584c8d9a2ee2699 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:09 -0700 Subject: [PATCH 1921/2855] staging: comedi: adv_pci_dio: refactor 'io_access' boardinfo The boards supported by this driver either use 8-bit or 16-bit I/O. The 'io_access' member of the boardinfo is used by the (*auto_attach) to determine which (*insn_bits) function to use. Simplify the boardinfo a bit by refactoring the 'io_access' member into a bit-field flag 'is_16bit'. Use the new flag and remove the switch () code in the (*auto_attach). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 57 +++++--------------- 1 file changed, 13 insertions(+), 44 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index b0bbc7322cd5b..ba3cb3b338e2b 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -43,11 +43,6 @@ enum hw_cards_id { TYPE_PCI1762 }; -/* which I/O instructions to use */ -enum hw_io_access { - IO_8b, IO_16b -}; - #define MAX_DI_SUBDEVS 2 /* max number of DI subdevices per card */ #define MAX_DO_SUBDEVS 2 /* max number of DO subdevices per card */ #define MAX_DIO_SUBDEVG 2 /* max number of DIO subdevices group per @@ -147,7 +142,7 @@ struct dio_boardtype { struct diosubd_data sdio[MAX_DIO_SUBDEVG]; /* DIO 8255 chans */ struct diosubd_data boardid; /* card supports board ID switch */ unsigned long timer_regbase; - enum hw_io_access io_access; + unsigned int is_16bit:1; }; static const struct dio_boardtype boardtypes[] = { @@ -160,7 +155,6 @@ static const struct dio_boardtype boardtypes[] = { .sdo[0] = { 16, PCI1730_DO, 2, }, .sdo[1] = { 16, PCI1730_IDO, 2, }, .boardid = { 4, PCI173x_BOARDID, 1, }, - .io_access = IO_8b, }, [TYPE_PCI1733] = { .name = "pci1733", @@ -168,7 +162,6 @@ static const struct dio_boardtype boardtypes[] = { .nsubdevs = 2, .sdi[1] = { 32, PCI1733_IDI, 4, }, .boardid = { 4, PCI173x_BOARDID, 1, }, - .io_access = IO_8b, }, [TYPE_PCI1734] = { .name = "pci1734", @@ -176,7 +169,6 @@ static const struct dio_boardtype boardtypes[] = { .nsubdevs = 2, .sdo[1] = { 32, PCI1734_IDO, 4, }, .boardid = { 4, PCI173x_BOARDID, 1, }, - .io_access = IO_8b, }, [TYPE_PCI1735] = { .name = "pci1735", @@ -186,7 +178,6 @@ static const struct dio_boardtype boardtypes[] = { .sdo[0] = { 32, PCI1735_DO, 4, }, .boardid = { 4, PCI1735_BOARDID, 1, }, .timer_regbase = PCI1735_C8254, - .io_access = IO_8b, }, [TYPE_PCI1736] = { .name = "pci1736", @@ -195,14 +186,12 @@ static const struct dio_boardtype boardtypes[] = { .sdi[1] = { 16, PCI1736_IDI, 2, }, .sdo[1] = { 16, PCI1736_IDO, 2, }, .boardid = { 4, PCI1736_BOARDID, 1, }, - .io_access = IO_8b, }, [TYPE_PCI1739] = { .name = "pci1739", .cardtype = TYPE_PCI1739, .nsubdevs = 2, .sdio[0] = { 48, PCI1739_DIO, 2, }, - .io_access = IO_8b, }, [TYPE_PCI1750] = { .name = "pci1750", @@ -210,7 +199,6 @@ static const struct dio_boardtype boardtypes[] = { .nsubdevs = 2, .sdi[1] = { 16, PCI1750_IDI, 2, }, .sdo[1] = { 16, PCI1750_IDO, 2, }, - .io_access = IO_8b, }, [TYPE_PCI1751] = { .name = "pci1751", @@ -218,7 +206,6 @@ static const struct dio_boardtype boardtypes[] = { .nsubdevs = 3, .sdio[0] = { 48, PCI1751_DIO, 2, }, .timer_regbase = PCI1751_CNT, - .io_access = IO_8b, }, [TYPE_PCI1752] = { .name = "pci1752", @@ -227,14 +214,13 @@ static const struct dio_boardtype boardtypes[] = { .sdo[0] = { 32, PCI1752_IDO, 2, }, .sdo[1] = { 32, PCI1752_IDO2, 2, }, .boardid = { 4, PCI175x_BOARDID, 1, }, - .io_access = IO_16b, + .is_16bit = 1, }, [TYPE_PCI1753] = { .name = "pci1753", .cardtype = TYPE_PCI1753, .nsubdevs = 4, .sdio[0] = { 96, PCI1753_DIO, 4, }, - .io_access = IO_8b, }, [TYPE_PCI1753E] = { .name = "pci1753e", @@ -242,7 +228,6 @@ static const struct dio_boardtype boardtypes[] = { .nsubdevs = 8, .sdio[0] = { 96, PCI1753_DIO, 4, }, .sdio[1] = { 96, PCI1753E_DIO, 4, }, - .io_access = IO_8b, }, [TYPE_PCI1754] = { .name = "pci1754", @@ -251,7 +236,7 @@ static const struct dio_boardtype boardtypes[] = { .sdi[0] = { 32, PCI1754_IDI, 2, }, .sdi[1] = { 32, PCI1754_IDI2, 2, }, .boardid = { 4, PCI175x_BOARDID, 1, }, - .io_access = IO_16b, + .is_16bit = 1, }, [TYPE_PCI1756] = { .name = "pci1756", @@ -260,7 +245,7 @@ static const struct dio_boardtype boardtypes[] = { .sdi[1] = { 32, PCI1756_IDI, 2, }, .sdo[1] = { 32, PCI1756_IDO, 2, }, .boardid = { 4, PCI175x_BOARDID, 1, }, - .io_access = IO_16b, + .is_16bit = 1, }, [TYPE_PCI1762] = { .name = "pci1762", @@ -269,7 +254,7 @@ static const struct dio_boardtype boardtypes[] = { .sdi[1] = { 16, PCI1762_IDI, 1, }, .sdo[1] = { 16, PCI1762_RO, 1, }, .boardid = { 4, PCI1762_BOARDID, 1, }, - .io_access = IO_16b, + .is_16bit = 1, }, }; @@ -509,14 +494,9 @@ static int pci_dio_auto_attach(struct comedi_device *dev, s->n_chan = d->chans; s->maxdata = 1; s->range_table = &range_digital; - switch (board->io_access) { - case IO_8b: - s->insn_bits = pci_dio_insn_bits_di_b; - break; - case IO_16b: - s->insn_bits = pci_dio_insn_bits_di_w; - break; - } + s->insn_bits = board->is_16bit + ? pci_dio_insn_bits_di_w + : pci_dio_insn_bits_di_b; s->private = (void *)d; } } @@ -530,14 +510,9 @@ static int pci_dio_auto_attach(struct comedi_device *dev, s->n_chan = d->chans; s->maxdata = 1; s->range_table = &range_digital; - switch (board->io_access) { - case IO_8b: - s->insn_bits = pci_dio_insn_bits_do_b; - break; - case IO_16b: - s->insn_bits = pci_dio_insn_bits_do_w; - break; - } + s->insn_bits = board->is_16bit + ? pci_dio_insn_bits_do_w + : pci_dio_insn_bits_do_b; s->private = (void *)d; } } @@ -561,14 +536,8 @@ static int pci_dio_auto_attach(struct comedi_device *dev, s->n_chan = d->chans; s->maxdata = 1; s->range_table = &range_digital; - switch (board->io_access) { - case IO_8b: - s->insn_bits = pci_dio_insn_bits_di_b; - break; - case IO_16b: - s->insn_bits = pci_dio_insn_bits_di_w; - break; - } + s->insn_bits = board->is_16bit ? pci_dio_insn_bits_di_w + : pci_dio_insn_bits_di_b; s->private = (void *)d; } -- GitLab From 039c5c1b27e786cd92c130559800f88625988dee Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:10 -0700 Subject: [PATCH 1922/2855] staging: comedi: adv_pci_dio: remove need for diosubd_data 'regs' member Currently the (*insn_bits) functions used the 'regs' member to determine how many registers need to be read or written to update the subdevice. We can use the subdevice 'n_chan' to determine this and make the code a bit clearer. The (*auto_attach) also uses this member to determine how many 8255 devices need to be initialized. These subdevices do not use the 'chans' member of diosubd_data. Move the 'regs' value to the 'chans' to allow removing the 'regs' member completely. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 120 ++++++++++--------- 1 file changed, 64 insertions(+), 56 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index ba3cb3b338e2b..e620e34c70bc6 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -127,10 +127,8 @@ enum hw_cards_id { #define PCI1762_ISR 6 /* R: Interrupt status register */ struct diosubd_data { - int chans; /* num of chans */ + int chans; /* num of chans or 8255 devices */ int addr; /* PCI address ofset */ - int regs; /* number of registers to read or 8255 - subdevices */ }; struct dio_boardtype { @@ -150,138 +148,144 @@ static const struct dio_boardtype boardtypes[] = { .name = "pci1730", .cardtype = TYPE_PCI1730, .nsubdevs = 5, - .sdi[0] = { 16, PCI1730_DI, 2, }, - .sdi[1] = { 16, PCI1730_IDI, 2, }, - .sdo[0] = { 16, PCI1730_DO, 2, }, - .sdo[1] = { 16, PCI1730_IDO, 2, }, - .boardid = { 4, PCI173x_BOARDID, 1, }, + .sdi[0] = { 16, PCI1730_DI, }, + .sdi[1] = { 16, PCI1730_IDI, }, + .sdo[0] = { 16, PCI1730_DO, }, + .sdo[1] = { 16, PCI1730_IDO, }, + .boardid = { 4, PCI173x_BOARDID, }, }, [TYPE_PCI1733] = { .name = "pci1733", .cardtype = TYPE_PCI1733, .nsubdevs = 2, - .sdi[1] = { 32, PCI1733_IDI, 4, }, - .boardid = { 4, PCI173x_BOARDID, 1, }, + .sdi[1] = { 32, PCI1733_IDI, }, + .boardid = { 4, PCI173x_BOARDID, }, }, [TYPE_PCI1734] = { .name = "pci1734", .cardtype = TYPE_PCI1734, .nsubdevs = 2, - .sdo[1] = { 32, PCI1734_IDO, 4, }, - .boardid = { 4, PCI173x_BOARDID, 1, }, + .sdo[1] = { 32, PCI1734_IDO, }, + .boardid = { 4, PCI173x_BOARDID, }, }, [TYPE_PCI1735] = { .name = "pci1735", .cardtype = TYPE_PCI1735, .nsubdevs = 4, - .sdi[0] = { 32, PCI1735_DI, 4, }, - .sdo[0] = { 32, PCI1735_DO, 4, }, - .boardid = { 4, PCI1735_BOARDID, 1, }, + .sdi[0] = { 32, PCI1735_DI, }, + .sdo[0] = { 32, PCI1735_DO, }, + .boardid = { 4, PCI1735_BOARDID, }, .timer_regbase = PCI1735_C8254, }, [TYPE_PCI1736] = { .name = "pci1736", .cardtype = TYPE_PCI1736, .nsubdevs = 3, - .sdi[1] = { 16, PCI1736_IDI, 2, }, - .sdo[1] = { 16, PCI1736_IDO, 2, }, - .boardid = { 4, PCI1736_BOARDID, 1, }, + .sdi[1] = { 16, PCI1736_IDI, }, + .sdo[1] = { 16, PCI1736_IDO, }, + .boardid = { 4, PCI1736_BOARDID, }, }, [TYPE_PCI1739] = { .name = "pci1739", .cardtype = TYPE_PCI1739, .nsubdevs = 2, - .sdio[0] = { 48, PCI1739_DIO, 2, }, + .sdio[0] = { 2, PCI1739_DIO, }, }, [TYPE_PCI1750] = { .name = "pci1750", .cardtype = TYPE_PCI1750, .nsubdevs = 2, - .sdi[1] = { 16, PCI1750_IDI, 2, }, - .sdo[1] = { 16, PCI1750_IDO, 2, }, + .sdi[1] = { 16, PCI1750_IDI, }, + .sdo[1] = { 16, PCI1750_IDO, }, }, [TYPE_PCI1751] = { .name = "pci1751", .cardtype = TYPE_PCI1751, .nsubdevs = 3, - .sdio[0] = { 48, PCI1751_DIO, 2, }, + .sdio[0] = { 2, PCI1751_DIO, }, .timer_regbase = PCI1751_CNT, }, [TYPE_PCI1752] = { .name = "pci1752", .cardtype = TYPE_PCI1752, .nsubdevs = 3, - .sdo[0] = { 32, PCI1752_IDO, 2, }, - .sdo[1] = { 32, PCI1752_IDO2, 2, }, - .boardid = { 4, PCI175x_BOARDID, 1, }, + .sdo[0] = { 32, PCI1752_IDO, }, + .sdo[1] = { 32, PCI1752_IDO2, }, + .boardid = { 4, PCI175x_BOARDID, }, .is_16bit = 1, }, [TYPE_PCI1753] = { .name = "pci1753", .cardtype = TYPE_PCI1753, .nsubdevs = 4, - .sdio[0] = { 96, PCI1753_DIO, 4, }, + .sdio[0] = { 4, PCI1753_DIO, }, }, [TYPE_PCI1753E] = { .name = "pci1753e", .cardtype = TYPE_PCI1753E, .nsubdevs = 8, - .sdio[0] = { 96, PCI1753_DIO, 4, }, - .sdio[1] = { 96, PCI1753E_DIO, 4, }, + .sdio[0] = { 4, PCI1753_DIO, }, + .sdio[1] = { 4, PCI1753E_DIO, }, }, [TYPE_PCI1754] = { .name = "pci1754", .cardtype = TYPE_PCI1754, .nsubdevs = 3, - .sdi[0] = { 32, PCI1754_IDI, 2, }, - .sdi[1] = { 32, PCI1754_IDI2, 2, }, - .boardid = { 4, PCI175x_BOARDID, 1, }, + .sdi[0] = { 32, PCI1754_IDI, }, + .sdi[1] = { 32, PCI1754_IDI2, }, + .boardid = { 4, PCI175x_BOARDID, }, .is_16bit = 1, }, [TYPE_PCI1756] = { .name = "pci1756", .cardtype = TYPE_PCI1756, .nsubdevs = 3, - .sdi[1] = { 32, PCI1756_IDI, 2, }, - .sdo[1] = { 32, PCI1756_IDO, 2, }, - .boardid = { 4, PCI175x_BOARDID, 1, }, + .sdi[1] = { 32, PCI1756_IDI, }, + .sdo[1] = { 32, PCI1756_IDO, }, + .boardid = { 4, PCI175x_BOARDID, }, .is_16bit = 1, }, [TYPE_PCI1762] = { .name = "pci1762", .cardtype = TYPE_PCI1762, .nsubdevs = 3, - .sdi[1] = { 16, PCI1762_IDI, 1, }, - .sdo[1] = { 16, PCI1762_RO, 1, }, - .boardid = { 4, PCI1762_BOARDID, 1, }, + .sdi[1] = { 16, PCI1762_IDI, }, + .sdo[1] = { 16, PCI1762_RO, }, + .boardid = { 4, PCI1762_BOARDID, }, .is_16bit = 1, }, }; static int pci_dio_insn_bits_di_b(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { const struct diosubd_data *d = (const struct diosubd_data *)s->private; - int i; + unsigned long iobase = dev->iobase + d->addr; - data[1] = 0; - for (i = 0; i < d->regs; i++) - data[1] |= inb(dev->iobase + d->addr + i) << (8 * i); + data[1] = inb(iobase); + if (s->n_chan > 8) + data[1] |= (inb(iobase + 1) << 8); + if (s->n_chan > 16) + data[1] |= (inb(iobase + 2) << 16); + if (s->n_chan > 24) + data[1] |= (inb(iobase + 3) << 24); return insn->n; } static int pci_dio_insn_bits_di_w(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { const struct diosubd_data *d = (const struct diosubd_data *)s->private; - int i; + unsigned long iobase = dev->iobase + d->addr; - data[1] = 0; - for (i = 0; i < d->regs; i++) - data[1] |= inw(dev->iobase + d->addr + 2 * i) << (16 * i); + data[1] = inw(iobase); + if (s->n_chan > 16) + data[1] |= (inw(iobase + 2) << 16); return insn->n; } @@ -292,12 +296,16 @@ static int pci_dio_insn_bits_do_b(struct comedi_device *dev, unsigned int *data) { const struct diosubd_data *d = (const struct diosubd_data *)s->private; - int i; + unsigned long iobase = dev->iobase + d->addr; if (comedi_dio_update_state(s, data)) { - for (i = 0; i < d->regs; i++) - outb((s->state >> (8 * i)) & 0xff, - dev->iobase + d->addr + i); + outb(s->state & 0xff, iobase); + if (s->n_chan > 8) + outb((s->state >> 8) & 0xff, iobase + 1); + if (s->n_chan > 16) + outb((s->state >> 16) & 0xff, iobase + 2); + if (s->n_chan > 24) + outb((s->state >> 24) & 0xff, iobase + 3); } data[1] = s->state; @@ -311,12 +319,12 @@ static int pci_dio_insn_bits_do_w(struct comedi_device *dev, unsigned int *data) { const struct diosubd_data *d = (const struct diosubd_data *)s->private; - int i; + unsigned long iobase = dev->iobase + d->addr; if (comedi_dio_update_state(s, data)) { - for (i = 0; i < d->regs; i++) - outw((s->state >> (16 * i)) & 0xffff, - dev->iobase + d->addr + 2 * i); + outw(s->state & 0xffff, iobase); + if (s->n_chan > 16) + outw((s->state >> 16) & 0xffff, iobase + 2); } data[1] = s->state; @@ -519,7 +527,7 @@ static int pci_dio_auto_attach(struct comedi_device *dev, for (i = 0; i < MAX_DIO_SUBDEVG; i++) { d = &board->sdio[i]; - for (j = 0; j < d->regs; j++) { + for (j = 0; j < d->chans; j++) { s = &dev->subdevices[subdev++]; ret = subdev_8255_init(dev, s, NULL, d->addr + j * I8255_SIZE); -- GitLab From 66f516e6a31e24972b1768453c2bd1abac273ff1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:11 -0700 Subject: [PATCH 1923/2855] staging: comedi: adv_pci_dio: use the diosubd_data 'addr' for di/do s->private Currently the di/do subdevices store a pointer to the diosubd_data in s->private. The (*insn_bits) functions then use that to get to the 'addr' needed to access the registers. The only member of diosubd_data that is needed by the (*insn_bits) functions is the 'addr'. For aesthetics, just store the 'addr' in s->private. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index e620e34c70bc6..51611c72f742b 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -128,7 +128,7 @@ enum hw_cards_id { struct diosubd_data { int chans; /* num of chans or 8255 devices */ - int addr; /* PCI address ofset */ + unsigned long addr; /* PCI address ofset */ }; struct dio_boardtype { @@ -261,8 +261,8 @@ static int pci_dio_insn_bits_di_b(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - const struct diosubd_data *d = (const struct diosubd_data *)s->private; - unsigned long iobase = dev->iobase + d->addr; + unsigned long reg = (unsigned long)s->private; + unsigned long iobase = dev->iobase + reg; data[1] = inb(iobase); if (s->n_chan > 8) @@ -280,8 +280,8 @@ static int pci_dio_insn_bits_di_w(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - const struct diosubd_data *d = (const struct diosubd_data *)s->private; - unsigned long iobase = dev->iobase + d->addr; + unsigned long reg = (unsigned long)s->private; + unsigned long iobase = dev->iobase + reg; data[1] = inw(iobase); if (s->n_chan > 16) @@ -295,8 +295,8 @@ static int pci_dio_insn_bits_do_b(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - const struct diosubd_data *d = (const struct diosubd_data *)s->private; - unsigned long iobase = dev->iobase + d->addr; + unsigned long reg = (unsigned long)s->private; + unsigned long iobase = dev->iobase + reg; if (comedi_dio_update_state(s, data)) { outb(s->state & 0xff, iobase); @@ -318,8 +318,8 @@ static int pci_dio_insn_bits_do_w(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - const struct diosubd_data *d = (const struct diosubd_data *)s->private; - unsigned long iobase = dev->iobase + d->addr; + unsigned long reg = (unsigned long)s->private; + unsigned long iobase = dev->iobase + reg; if (comedi_dio_update_state(s, data)) { outw(s->state & 0xffff, iobase); @@ -505,7 +505,7 @@ static int pci_dio_auto_attach(struct comedi_device *dev, s->insn_bits = board->is_16bit ? pci_dio_insn_bits_di_w : pci_dio_insn_bits_di_b; - s->private = (void *)d; + s->private = (void *)d->addr; } } @@ -521,7 +521,7 @@ static int pci_dio_auto_attach(struct comedi_device *dev, s->insn_bits = board->is_16bit ? pci_dio_insn_bits_do_w : pci_dio_insn_bits_do_b; - s->private = (void *)d; + s->private = (void *)d->addr; } } @@ -546,7 +546,7 @@ static int pci_dio_auto_attach(struct comedi_device *dev, s->range_table = &range_digital; s->insn_bits = board->is_16bit ? pci_dio_insn_bits_di_w : pci_dio_insn_bits_di_b; - s->private = (void *)d; + s->private = (void *)d->addr; } if (board->timer_regbase) { -- GitLab From 2001807e25d9a645cfaa28e893a0a5968f6b38a0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:12 -0700 Subject: [PATCH 1924/2855] staging: comedi: adv_pci_dio: simplify the 'boardid' boardinfo The "board id" register is always 4-bits (4 di channels) and the register used to read the bits is always > 0. Simplify the 'boardid' boardinfo by replacing it with a 'id_reg' member and open-coding the subdevice n_chan. For aesthetics, remove all the *_BOARDID defines and just open-code the register values in the boardinfo. Add the missing boardinfo for the pci1739 board id register and increase the nsubdevs to handle it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 36 ++++++++------------ 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 51611c72f742b..d24134f1d4a22 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -60,13 +60,11 @@ enum hw_cards_id { * interrupts */ #define PCI1730_3_INT_CLR 0x10 /* R/W: clear interrupts */ #define PCI1734_IDO 0 /* W: Isolated digital output 0-31 */ -#define PCI173x_BOARDID 4 /* R: Board I/D switch for 1730/3/4 */ /* Advantech PCI-1735U */ #define PCI1735_DI 0 /* R: Digital input 0-31 */ #define PCI1735_DO 0 /* W: Digital output 0-31 */ #define PCI1735_C8254 4 /* R/W: 8254 counter */ -#define PCI1735_BOARDID 8 /* R: Board I/D switch for 1735U */ /* Advantech PCI-1736UP */ #define PCI1736_IDI 0 /* R: Isolated digital input 0-15 */ @@ -75,13 +73,11 @@ enum hw_cards_id { #define PCI1736_3_INT_RF 0x0c /* R/W: set falling/raising edge for * interrupts */ #define PCI1736_3_INT_CLR 0x10 /* R/W: clear interrupts */ -#define PCI1736_BOARDID 4 /* R: Board I/D switch for 1736UP */ /* Advantech PCI-1739U */ #define PCI1739_DIO 0 /* R/W: begin of 8255 registers block */ #define PCI1739_ICR 32 /* W: Interrupt control register */ #define PCI1739_ISR 32 /* R: Interrupt status register */ -#define PCI1739_BOARDID 8 /* R: Board I/D switch for 1739U */ /* Advantech PCI-1750 */ #define PCI1750_IDI 0 /* R: Isolated digital input 0-15 */ @@ -117,12 +113,10 @@ enum hw_cards_id { #define PCI1754_ICR2 0x0c /* R/W: Interrupt control register group 2 */ #define PCI1754_ICR3 0x0e /* R/W: Interrupt control register group 3 */ #define PCI1752_6_CFC 0x12 /* R/W: set/read channel freeze function */ -#define PCI175x_BOARDID 0x10 /* R: Board I/D switch for 1752/4/6 */ /* Advantech PCI-1762 registers */ #define PCI1762_RO 0 /* R/W: Relays status/output */ #define PCI1762_IDI 2 /* R: Isolated input status */ -#define PCI1762_BOARDID 4 /* R: Board I/D switch */ #define PCI1762_ICR 6 /* W: Interrupt control register */ #define PCI1762_ISR 6 /* R: Interrupt status register */ @@ -138,7 +132,7 @@ struct dio_boardtype { struct diosubd_data sdi[MAX_DI_SUBDEVS]; /* DI chans */ struct diosubd_data sdo[MAX_DO_SUBDEVS]; /* DO chans */ struct diosubd_data sdio[MAX_DIO_SUBDEVG]; /* DIO 8255 chans */ - struct diosubd_data boardid; /* card supports board ID switch */ + unsigned long id_reg; unsigned long timer_regbase; unsigned int is_16bit:1; }; @@ -152,21 +146,21 @@ static const struct dio_boardtype boardtypes[] = { .sdi[1] = { 16, PCI1730_IDI, }, .sdo[0] = { 16, PCI1730_DO, }, .sdo[1] = { 16, PCI1730_IDO, }, - .boardid = { 4, PCI173x_BOARDID, }, + .id_reg = 0x04, }, [TYPE_PCI1733] = { .name = "pci1733", .cardtype = TYPE_PCI1733, .nsubdevs = 2, .sdi[1] = { 32, PCI1733_IDI, }, - .boardid = { 4, PCI173x_BOARDID, }, + .id_reg = 0x04, }, [TYPE_PCI1734] = { .name = "pci1734", .cardtype = TYPE_PCI1734, .nsubdevs = 2, .sdo[1] = { 32, PCI1734_IDO, }, - .boardid = { 4, PCI173x_BOARDID, }, + .id_reg = 0x04, }, [TYPE_PCI1735] = { .name = "pci1735", @@ -174,7 +168,7 @@ static const struct dio_boardtype boardtypes[] = { .nsubdevs = 4, .sdi[0] = { 32, PCI1735_DI, }, .sdo[0] = { 32, PCI1735_DO, }, - .boardid = { 4, PCI1735_BOARDID, }, + .id_reg = 0x08, .timer_regbase = PCI1735_C8254, }, [TYPE_PCI1736] = { @@ -183,13 +177,14 @@ static const struct dio_boardtype boardtypes[] = { .nsubdevs = 3, .sdi[1] = { 16, PCI1736_IDI, }, .sdo[1] = { 16, PCI1736_IDO, }, - .boardid = { 4, PCI1736_BOARDID, }, + .id_reg = 0x04, }, [TYPE_PCI1739] = { .name = "pci1739", .cardtype = TYPE_PCI1739, - .nsubdevs = 2, + .nsubdevs = 3, .sdio[0] = { 2, PCI1739_DIO, }, + .id_reg = 0x08, }, [TYPE_PCI1750] = { .name = "pci1750", @@ -211,7 +206,7 @@ static const struct dio_boardtype boardtypes[] = { .nsubdevs = 3, .sdo[0] = { 32, PCI1752_IDO, }, .sdo[1] = { 32, PCI1752_IDO2, }, - .boardid = { 4, PCI175x_BOARDID, }, + .id_reg = 0x10, .is_16bit = 1, }, [TYPE_PCI1753] = { @@ -233,7 +228,7 @@ static const struct dio_boardtype boardtypes[] = { .nsubdevs = 3, .sdi[0] = { 32, PCI1754_IDI, }, .sdi[1] = { 32, PCI1754_IDI2, }, - .boardid = { 4, PCI175x_BOARDID, }, + .id_reg = 0x10, .is_16bit = 1, }, [TYPE_PCI1756] = { @@ -242,7 +237,7 @@ static const struct dio_boardtype boardtypes[] = { .nsubdevs = 3, .sdi[1] = { 32, PCI1756_IDI, }, .sdo[1] = { 32, PCI1756_IDO, }, - .boardid = { 4, PCI175x_BOARDID, }, + .id_reg = 0x10, .is_16bit = 1, }, [TYPE_PCI1762] = { @@ -251,7 +246,7 @@ static const struct dio_boardtype boardtypes[] = { .nsubdevs = 3, .sdi[1] = { 16, PCI1762_IDI, }, .sdo[1] = { 16, PCI1762_RO, }, - .boardid = { 4, PCI1762_BOARDID, }, + .id_reg = 0x04, .is_16bit = 1, }, }; @@ -536,17 +531,16 @@ static int pci_dio_auto_attach(struct comedi_device *dev, } } - d = &board->boardid; - if (d->chans) { + if (board->id_reg) { s = &dev->subdevices[subdev++]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_INTERNAL; - s->n_chan = d->chans; + s->n_chan = 4; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = board->is_16bit ? pci_dio_insn_bits_di_w : pci_dio_insn_bits_di_b; - s->private = (void *)d->addr; + s->private = (void *)board->id_reg; } if (board->timer_regbase) { -- GitLab From d9d238d898903d1f6f965a11ffb6aeb844eca5d5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:13 -0700 Subject: [PATCH 1925/2855] staging: comedi: adv_pci_dio: remove defines used for the 'timer_regbase' These defines are only used to initialize the 'timer_regbase' boardinfo. For aesthetics, just open-code the values and remove the defines. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index d24134f1d4a22..fdb6063b6da49 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -64,7 +64,6 @@ enum hw_cards_id { /* Advantech PCI-1735U */ #define PCI1735_DI 0 /* R: Digital input 0-31 */ #define PCI1735_DO 0 /* W: Digital output 0-31 */ -#define PCI1735_C8254 4 /* R/W: 8254 counter */ /* Advantech PCI-1736UP */ #define PCI1736_IDI 0 /* R: Isolated digital input 0-15 */ @@ -87,7 +86,6 @@ enum hw_cards_id { /* Advantech PCI-1751/3/3E */ #define PCI1751_DIO 0 /* R/W: begin of 8255 registers block */ -#define PCI1751_CNT 24 /* R/W: begin of 8254 registers block */ #define PCI1751_ICR 32 /* W: Interrupt control register */ #define PCI1751_ISR 32 /* R: Interrupt status register */ #define PCI1753_DIO 0 /* R/W: begin of 8255 registers block */ @@ -169,7 +167,7 @@ static const struct dio_boardtype boardtypes[] = { .sdi[0] = { 32, PCI1735_DI, }, .sdo[0] = { 32, PCI1735_DO, }, .id_reg = 0x08, - .timer_regbase = PCI1735_C8254, + .timer_regbase = 0x04, }, [TYPE_PCI1736] = { .name = "pci1736", @@ -198,7 +196,7 @@ static const struct dio_boardtype boardtypes[] = { .cardtype = TYPE_PCI1751, .nsubdevs = 3, .sdio[0] = { 2, PCI1751_DIO, }, - .timer_regbase = PCI1751_CNT, + .timer_regbase = 0x18, }, [TYPE_PCI1752] = { .name = "pci1752", -- GitLab From e01b70bc13cecc917ae8a0dd23c5ddac38d0813b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:14 -0700 Subject: [PATCH 1926/2855] staging: comedi: adv_pci_dio: remove defines used for the di registers These defines are only used to initialize the diosubd_data 'addr' members in the boardinfo. For aesthetics, just open-code the values and remove the defines. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 30 +++++++------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index fdb6063b6da49..3c4335ec31d61 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -50,11 +50,8 @@ enum hw_cards_id { /* Register offset definitions */ /* Advantech PCI-1730/3/4 */ -#define PCI1730_IDI 0 /* R: Isolated digital input 0-15 */ #define PCI1730_IDO 0 /* W: Isolated digital output 0-15 */ -#define PCI1730_DI 2 /* R: Digital input 0-15 */ #define PCI1730_DO 2 /* W: Digital output 0-15 */ -#define PCI1733_IDI 0 /* R: Isolated digital input 0-31 */ #define PCI1730_3_INT_EN 0x08 /* R/W: enable/disable interrupts */ #define PCI1730_3_INT_RF 0x0c /* R/W: set falling/raising edge for * interrupts */ @@ -62,11 +59,9 @@ enum hw_cards_id { #define PCI1734_IDO 0 /* W: Isolated digital output 0-31 */ /* Advantech PCI-1735U */ -#define PCI1735_DI 0 /* R: Digital input 0-31 */ #define PCI1735_DO 0 /* W: Digital output 0-31 */ /* Advantech PCI-1736UP */ -#define PCI1736_IDI 0 /* R: Isolated digital input 0-15 */ #define PCI1736_IDO 0 /* W: Isolated digital output 0-15 */ #define PCI1736_3_INT_EN 0x08 /* R/W: enable/disable interrupts */ #define PCI1736_3_INT_RF 0x0c /* R/W: set falling/raising edge for @@ -79,7 +74,6 @@ enum hw_cards_id { #define PCI1739_ISR 32 /* R: Interrupt status register */ /* Advantech PCI-1750 */ -#define PCI1750_IDI 0 /* R: Isolated digital input 0-15 */ #define PCI1750_IDO 0 /* W: Isolated digital output 0-15 */ #define PCI1750_ICR 32 /* W: Interrupt control register */ #define PCI1750_ISR 32 /* R: Interrupt status register */ @@ -102,9 +96,6 @@ enum hw_cards_id { /* Advantech PCI-1752/4/6 */ #define PCI1752_IDO 0 /* R/W: Digital output 0-31 */ #define PCI1752_IDO2 4 /* R/W: Digital output 32-63 */ -#define PCI1754_IDI 0 /* R: Digital input 0-31 */ -#define PCI1754_IDI2 4 /* R: Digital input 32-64 */ -#define PCI1756_IDI 0 /* R: Digital input 0-31 */ #define PCI1756_IDO 4 /* R/W: Digital output 0-31 */ #define PCI1754_6_ICR0 0x08 /* R/W: Interrupt control register group 0 */ #define PCI1754_6_ICR1 0x0a /* R/W: Interrupt control register group 1 */ @@ -114,7 +105,6 @@ enum hw_cards_id { /* Advantech PCI-1762 registers */ #define PCI1762_RO 0 /* R/W: Relays status/output */ -#define PCI1762_IDI 2 /* R: Isolated input status */ #define PCI1762_ICR 6 /* W: Interrupt control register */ #define PCI1762_ISR 6 /* R: Interrupt status register */ @@ -140,8 +130,8 @@ static const struct dio_boardtype boardtypes[] = { .name = "pci1730", .cardtype = TYPE_PCI1730, .nsubdevs = 5, - .sdi[0] = { 16, PCI1730_DI, }, - .sdi[1] = { 16, PCI1730_IDI, }, + .sdi[0] = { 16, 0x02, }, /* DI 0-15 */ + .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */ .sdo[0] = { 16, PCI1730_DO, }, .sdo[1] = { 16, PCI1730_IDO, }, .id_reg = 0x04, @@ -150,7 +140,7 @@ static const struct dio_boardtype boardtypes[] = { .name = "pci1733", .cardtype = TYPE_PCI1733, .nsubdevs = 2, - .sdi[1] = { 32, PCI1733_IDI, }, + .sdi[1] = { 32, 0x00, }, /* ISO DI 0-31 */ .id_reg = 0x04, }, [TYPE_PCI1734] = { @@ -164,7 +154,7 @@ static const struct dio_boardtype boardtypes[] = { .name = "pci1735", .cardtype = TYPE_PCI1735, .nsubdevs = 4, - .sdi[0] = { 32, PCI1735_DI, }, + .sdi[0] = { 32, 0x00, }, /* DI 0-31 */ .sdo[0] = { 32, PCI1735_DO, }, .id_reg = 0x08, .timer_regbase = 0x04, @@ -173,7 +163,7 @@ static const struct dio_boardtype boardtypes[] = { .name = "pci1736", .cardtype = TYPE_PCI1736, .nsubdevs = 3, - .sdi[1] = { 16, PCI1736_IDI, }, + .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */ .sdo[1] = { 16, PCI1736_IDO, }, .id_reg = 0x04, }, @@ -188,7 +178,7 @@ static const struct dio_boardtype boardtypes[] = { .name = "pci1750", .cardtype = TYPE_PCI1750, .nsubdevs = 2, - .sdi[1] = { 16, PCI1750_IDI, }, + .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */ .sdo[1] = { 16, PCI1750_IDO, }, }, [TYPE_PCI1751] = { @@ -224,8 +214,8 @@ static const struct dio_boardtype boardtypes[] = { .name = "pci1754", .cardtype = TYPE_PCI1754, .nsubdevs = 3, - .sdi[0] = { 32, PCI1754_IDI, }, - .sdi[1] = { 32, PCI1754_IDI2, }, + .sdi[0] = { 32, 0x00, }, /* DI 0-31 */ + .sdi[1] = { 32, 0x04, }, /* DI 32-63 */ .id_reg = 0x10, .is_16bit = 1, }, @@ -233,7 +223,7 @@ static const struct dio_boardtype boardtypes[] = { .name = "pci1756", .cardtype = TYPE_PCI1756, .nsubdevs = 3, - .sdi[1] = { 32, PCI1756_IDI, }, + .sdi[1] = { 32, 0x00, }, /* DI 0-31 */ .sdo[1] = { 32, PCI1756_IDO, }, .id_reg = 0x10, .is_16bit = 1, @@ -242,7 +232,7 @@ static const struct dio_boardtype boardtypes[] = { .name = "pci1762", .cardtype = TYPE_PCI1762, .nsubdevs = 3, - .sdi[1] = { 16, PCI1762_IDI, }, + .sdi[1] = { 16, 0x02, }, /* ISO DI 0-15 */ .sdo[1] = { 16, PCI1762_RO, }, .id_reg = 0x04, .is_16bit = 1, -- GitLab From 4190c22008ef241cd9ae791bd9934e16c563fbc4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:15 -0700 Subject: [PATCH 1927/2855] staging: comedi: adv_pci_dio: remove board reset during (*detach) The board reset function disables and clears all interrupts. It also resets all the digital output channels to 0. Interrupts are not used by this driver so the disable/clear during the (*detach) is not necessary. Reseting all the digital outputs to 0 might not be desired depending on what the outputs are connected to. Remove the board reset and just use comedi_pci_detach() directly for the driver (*detach). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 3c4335ec31d61..83591a6c3f93f 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -548,18 +548,11 @@ static int pci_dio_auto_attach(struct comedi_device *dev, return 0; } -static void pci_dio_detach(struct comedi_device *dev) -{ - if (dev->iobase) - pci_dio_reset(dev); - comedi_pci_detach(dev); -} - static struct comedi_driver adv_pci_dio_driver = { .driver_name = "adv_pci_dio", .module = THIS_MODULE, .auto_attach = pci_dio_auto_attach, - .detach = pci_dio_detach, + .detach = comedi_pci_detach, }; static int adv_pci_dio_pci_probe(struct pci_dev *dev, -- GitLab From 42100e306c0a33f56a079645148d6ceed17d2c40 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:16 -0700 Subject: [PATCH 1928/2855] staging: comedi: adv_pci_dio: do board reset early in (*auto_attach) The board reset function disables and clears all interrupts. It also resets all the digital output channels to 0. Interrupts are not currently used by this driver. For asthetics, do the board reset early in the (*auto_attach) to make sure the interrupts are disabled in case this feature is added. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 83591a6c3f93f..55ca8f936dcd0 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -471,6 +471,8 @@ static int pci_dio_auto_attach(struct comedi_device *dev, else dev->iobase = pci_resource_start(pcidev, 2); + pci_dio_reset(dev); + ret = comedi_alloc_subdevices(dev, board->nsubdevs); if (ret) return ret; @@ -543,8 +545,6 @@ static int pci_dio_auto_attach(struct comedi_device *dev, comedi_8254_subdevice_init(s, dev->pacer); } - pci_dio_reset(dev); - return 0; } -- GitLab From d06ddc1967566c0dcca243cfc9a60457d9644115 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:17 -0700 Subject: [PATCH 1929/2855] staging: comedi: adv_pci_dio: reset digital outputs in subdevice init Currently the board reset function also resets the digital output channels to 0. This works but it makes the reset function a bit messy and each board type has to be handled special. Move the digital output reset into the subdevice init where it can be handle based on the subdevice setup. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 36 ++++++++------------ 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 55ca8f936dcd0..578c646619054 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -321,11 +321,6 @@ static int pci_dio_reset(struct comedi_device *dev) switch (board->cardtype) { case TYPE_PCI1730: - outb(0, dev->iobase + PCI1730_DO); /* clear outputs */ - outb(0, dev->iobase + PCI1730_DO + 1); - outb(0, dev->iobase + PCI1730_IDO); - outb(0, dev->iobase + PCI1730_IDO + 1); - /* fallthrough */ case TYPE_PCI1733: /* disable interrupts */ outb(0, dev->iobase + PCI1730_3_INT_EN); @@ -335,21 +330,11 @@ static int pci_dio_reset(struct comedi_device *dev) outb(0, dev->iobase + PCI1730_3_INT_RF); break; case TYPE_PCI1734: - outb(0, dev->iobase + PCI1734_IDO); /* clear outputs */ - outb(0, dev->iobase + PCI1734_IDO + 1); - outb(0, dev->iobase + PCI1734_IDO + 2); - outb(0, dev->iobase + PCI1734_IDO + 3); break; case TYPE_PCI1735: - outb(0, dev->iobase + PCI1735_DO); /* clear outputs */ - outb(0, dev->iobase + PCI1735_DO + 1); - outb(0, dev->iobase + PCI1735_DO + 2); - outb(0, dev->iobase + PCI1735_DO + 3); break; case TYPE_PCI1736: - outb(0, dev->iobase + PCI1736_IDO); - outb(0, dev->iobase + PCI1736_IDO + 1); /* disable interrupts */ outb(0, dev->iobase + PCI1736_3_INT_EN); /* clear interrupts */ @@ -371,10 +356,6 @@ static int pci_dio_reset(struct comedi_device *dev) case TYPE_PCI1752: outw(0, dev->iobase + PCI1752_6_CFC); /* disable channel freeze * function */ - outw(0, dev->iobase + PCI1752_IDO); /* clear outputs */ - outw(0, dev->iobase + PCI1752_IDO + 2); - outw(0, dev->iobase + PCI1752_IDO2); - outw(0, dev->iobase + PCI1752_IDO2 + 2); break; case TYPE_PCI1753E: outb(0x88, dev->iobase + PCI1753E_ICR0); /* disable & clear @@ -403,8 +384,6 @@ static int pci_dio_reset(struct comedi_device *dev) outw(0x08, dev->iobase + PCI1754_6_ICR0); /* disable and clear * interrupts */ outw(0x08, dev->iobase + PCI1754_6_ICR1); - outw(0, dev->iobase + PCI1756_IDO); /* clear outputs */ - outw(0, dev->iobase + PCI1756_IDO + 2); break; case TYPE_PCI1762: outw(0x0101, dev->iobase + PCI1762_ICR); /* disable & clear @@ -507,6 +486,21 @@ static int pci_dio_auto_attach(struct comedi_device *dev, ? pci_dio_insn_bits_do_w : pci_dio_insn_bits_do_b; s->private = (void *)d->addr; + + /* reset all outputs to 0 */ + if (board->is_16bit) { + outw(0, dev->iobase + d->addr); + if (s->n_chan > 16) + outw(0, dev->iobase + d->addr + 2); + } else { + outb(0, dev->iobase + d->addr); + if (s->n_chan > 8) + outb(0, dev->iobase + d->addr + 1); + if (s->n_chan > 16) + outb(0, dev->iobase + d->addr + 2); + if (s->n_chan > 24) + outb(0, dev->iobase + d->addr + 3); + } } } -- GitLab From 7f442292fac6b8b251eebf311efead4c3c59923e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:18 -0700 Subject: [PATCH 1930/2855] staging: comedi: adv_pci_dio: remove defines used for the do registers These defines are only used to initialize the diosubd_data 'addr' members in the boardinfo. For aesthetics, just open-code the values and remove the defines. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 32 ++++++-------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 578c646619054..a72b04e82ebec 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -50,19 +50,12 @@ enum hw_cards_id { /* Register offset definitions */ /* Advantech PCI-1730/3/4 */ -#define PCI1730_IDO 0 /* W: Isolated digital output 0-15 */ -#define PCI1730_DO 2 /* W: Digital output 0-15 */ #define PCI1730_3_INT_EN 0x08 /* R/W: enable/disable interrupts */ #define PCI1730_3_INT_RF 0x0c /* R/W: set falling/raising edge for * interrupts */ #define PCI1730_3_INT_CLR 0x10 /* R/W: clear interrupts */ -#define PCI1734_IDO 0 /* W: Isolated digital output 0-31 */ - -/* Advantech PCI-1735U */ -#define PCI1735_DO 0 /* W: Digital output 0-31 */ /* Advantech PCI-1736UP */ -#define PCI1736_IDO 0 /* W: Isolated digital output 0-15 */ #define PCI1736_3_INT_EN 0x08 /* R/W: enable/disable interrupts */ #define PCI1736_3_INT_RF 0x0c /* R/W: set falling/raising edge for * interrupts */ @@ -74,7 +67,6 @@ enum hw_cards_id { #define PCI1739_ISR 32 /* R: Interrupt status register */ /* Advantech PCI-1750 */ -#define PCI1750_IDO 0 /* W: Isolated digital output 0-15 */ #define PCI1750_ICR 32 /* W: Interrupt control register */ #define PCI1750_ISR 32 /* R: Interrupt status register */ @@ -94,9 +86,6 @@ enum hw_cards_id { #define PCI1753E_ICR3 51 /* R/W: Interrupt control register group 3 */ /* Advantech PCI-1752/4/6 */ -#define PCI1752_IDO 0 /* R/W: Digital output 0-31 */ -#define PCI1752_IDO2 4 /* R/W: Digital output 32-63 */ -#define PCI1756_IDO 4 /* R/W: Digital output 0-31 */ #define PCI1754_6_ICR0 0x08 /* R/W: Interrupt control register group 0 */ #define PCI1754_6_ICR1 0x0a /* R/W: Interrupt control register group 1 */ #define PCI1754_ICR2 0x0c /* R/W: Interrupt control register group 2 */ @@ -104,7 +93,6 @@ enum hw_cards_id { #define PCI1752_6_CFC 0x12 /* R/W: set/read channel freeze function */ /* Advantech PCI-1762 registers */ -#define PCI1762_RO 0 /* R/W: Relays status/output */ #define PCI1762_ICR 6 /* W: Interrupt control register */ #define PCI1762_ISR 6 /* R: Interrupt status register */ @@ -132,8 +120,8 @@ static const struct dio_boardtype boardtypes[] = { .nsubdevs = 5, .sdi[0] = { 16, 0x02, }, /* DI 0-15 */ .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */ - .sdo[0] = { 16, PCI1730_DO, }, - .sdo[1] = { 16, PCI1730_IDO, }, + .sdo[0] = { 16, 0x02, }, /* DO 0-15 */ + .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */ .id_reg = 0x04, }, [TYPE_PCI1733] = { @@ -147,7 +135,7 @@ static const struct dio_boardtype boardtypes[] = { .name = "pci1734", .cardtype = TYPE_PCI1734, .nsubdevs = 2, - .sdo[1] = { 32, PCI1734_IDO, }, + .sdo[1] = { 32, 0x00, }, /* ISO DO 0-31 */ .id_reg = 0x04, }, [TYPE_PCI1735] = { @@ -155,7 +143,7 @@ static const struct dio_boardtype boardtypes[] = { .cardtype = TYPE_PCI1735, .nsubdevs = 4, .sdi[0] = { 32, 0x00, }, /* DI 0-31 */ - .sdo[0] = { 32, PCI1735_DO, }, + .sdo[0] = { 32, 0x00, }, /* DO 0-31 */ .id_reg = 0x08, .timer_regbase = 0x04, }, @@ -164,7 +152,7 @@ static const struct dio_boardtype boardtypes[] = { .cardtype = TYPE_PCI1736, .nsubdevs = 3, .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */ - .sdo[1] = { 16, PCI1736_IDO, }, + .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */ .id_reg = 0x04, }, [TYPE_PCI1739] = { @@ -179,7 +167,7 @@ static const struct dio_boardtype boardtypes[] = { .cardtype = TYPE_PCI1750, .nsubdevs = 2, .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */ - .sdo[1] = { 16, PCI1750_IDO, }, + .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */ }, [TYPE_PCI1751] = { .name = "pci1751", @@ -192,8 +180,8 @@ static const struct dio_boardtype boardtypes[] = { .name = "pci1752", .cardtype = TYPE_PCI1752, .nsubdevs = 3, - .sdo[0] = { 32, PCI1752_IDO, }, - .sdo[1] = { 32, PCI1752_IDO2, }, + .sdo[0] = { 32, 0x00, }, /* DO 0-31 */ + .sdo[1] = { 32, 0x04, }, /* DO 32-63 */ .id_reg = 0x10, .is_16bit = 1, }, @@ -224,7 +212,7 @@ static const struct dio_boardtype boardtypes[] = { .cardtype = TYPE_PCI1756, .nsubdevs = 3, .sdi[1] = { 32, 0x00, }, /* DI 0-31 */ - .sdo[1] = { 32, PCI1756_IDO, }, + .sdo[1] = { 32, 0x04, }, /* DO 0-31 */ .id_reg = 0x10, .is_16bit = 1, }, @@ -233,7 +221,7 @@ static const struct dio_boardtype boardtypes[] = { .cardtype = TYPE_PCI1762, .nsubdevs = 3, .sdi[1] = { 16, 0x02, }, /* ISO DI 0-15 */ - .sdo[1] = { 16, PCI1762_RO, }, + .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */ .id_reg = 0x04, .is_16bit = 1, }, -- GitLab From 4cabeb10be65f2ee95e281ad3bc01291e4653213 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:19 -0700 Subject: [PATCH 1931/2855] staging: comedi: adv_pci_dio: remove defines used for the dio (8255) registers These defines are only used to initialize the diosubd_data 'addr' members in the boardinfo. For aesthetics, just open-code the values and remove the defines. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index a72b04e82ebec..c564b69acd3fb 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -62,7 +62,6 @@ enum hw_cards_id { #define PCI1736_3_INT_CLR 0x10 /* R/W: clear interrupts */ /* Advantech PCI-1739U */ -#define PCI1739_DIO 0 /* R/W: begin of 8255 registers block */ #define PCI1739_ICR 32 /* W: Interrupt control register */ #define PCI1739_ISR 32 /* R: Interrupt status register */ @@ -71,15 +70,12 @@ enum hw_cards_id { #define PCI1750_ISR 32 /* R: Interrupt status register */ /* Advantech PCI-1751/3/3E */ -#define PCI1751_DIO 0 /* R/W: begin of 8255 registers block */ #define PCI1751_ICR 32 /* W: Interrupt control register */ #define PCI1751_ISR 32 /* R: Interrupt status register */ -#define PCI1753_DIO 0 /* R/W: begin of 8255 registers block */ #define PCI1753_ICR0 16 /* R/W: Interrupt control register group 0 */ #define PCI1753_ICR1 17 /* R/W: Interrupt control register group 1 */ #define PCI1753_ICR2 18 /* R/W: Interrupt control register group 2 */ #define PCI1753_ICR3 19 /* R/W: Interrupt control register group 3 */ -#define PCI1753E_DIO 32 /* R/W: begin of 8255 registers block */ #define PCI1753E_ICR0 48 /* R/W: Interrupt control register group 0 */ #define PCI1753E_ICR1 49 /* R/W: Interrupt control register group 1 */ #define PCI1753E_ICR2 50 /* R/W: Interrupt control register group 2 */ @@ -159,7 +155,7 @@ static const struct dio_boardtype boardtypes[] = { .name = "pci1739", .cardtype = TYPE_PCI1739, .nsubdevs = 3, - .sdio[0] = { 2, PCI1739_DIO, }, + .sdio[0] = { 2, 0x00, }, /* 8255 DIO */ .id_reg = 0x08, }, [TYPE_PCI1750] = { @@ -173,7 +169,7 @@ static const struct dio_boardtype boardtypes[] = { .name = "pci1751", .cardtype = TYPE_PCI1751, .nsubdevs = 3, - .sdio[0] = { 2, PCI1751_DIO, }, + .sdio[0] = { 2, 0x00, }, /* 8255 DIO */ .timer_regbase = 0x18, }, [TYPE_PCI1752] = { @@ -189,14 +185,14 @@ static const struct dio_boardtype boardtypes[] = { .name = "pci1753", .cardtype = TYPE_PCI1753, .nsubdevs = 4, - .sdio[0] = { 4, PCI1753_DIO, }, + .sdio[0] = { 4, 0x00, }, /* 8255 DIO */ }, [TYPE_PCI1753E] = { .name = "pci1753e", .cardtype = TYPE_PCI1753E, .nsubdevs = 8, - .sdio[0] = { 4, PCI1753_DIO, }, - .sdio[1] = { 4, PCI1753E_DIO, }, + .sdio[0] = { 4, 0x00, }, /* 8255 DIO */ + .sdio[1] = { 4, 0x20, }, /* 8255 DIO */ }, [TYPE_PCI1754] = { .name = "pci1754", -- GitLab From eaf1e647efd70fc4579e77313a96371e317fae38 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:20 -0700 Subject: [PATCH 1932/2855] staging: comedi: adv_pci_dio: use a default case in pci_dio_reset() For aesthetics, use a default case in the switch (board->cardtype) used to reset the various boards. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index c564b69acd3fb..231fa73c0e87e 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -313,11 +313,6 @@ static int pci_dio_reset(struct comedi_device *dev) /* set rising edge trigger */ outb(0, dev->iobase + PCI1730_3_INT_RF); break; - case TYPE_PCI1734: - break; - case TYPE_PCI1735: - break; - case TYPE_PCI1736: /* disable interrupts */ outb(0, dev->iobase + PCI1736_3_INT_EN); @@ -326,12 +321,10 @@ static int pci_dio_reset(struct comedi_device *dev) /* set rising edge trigger */ outb(0, dev->iobase + PCI1736_3_INT_RF); break; - case TYPE_PCI1739: /* disable & clear interrupts */ outb(0x88, dev->iobase + PCI1739_ICR); break; - case TYPE_PCI1750: case TYPE_PCI1751: /* disable & clear interrupts */ @@ -373,6 +366,8 @@ static int pci_dio_reset(struct comedi_device *dev) outw(0x0101, dev->iobase + PCI1762_ICR); /* disable & clear * interrupts */ break; + default: + break; } return 0; -- GitLab From c94a5991bf86cc0fddc854daceff96342d299c60 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:21 -0700 Subject: [PATCH 1933/2855] staging: comedi: adv_pci_dio: disable channel freeze outside of switch For aesthetics, move the disable of the channel freeze for the PCI-1752 and PCI-1756 boards out of the switch used to disable and clear interrupts. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 231fa73c0e87e..80c34aa89268b 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -303,6 +303,10 @@ static int pci_dio_reset(struct comedi_device *dev) { const struct dio_boardtype *board = dev->board_ptr; + /* disable channel freeze function on the PCI-1752/1756 boards */ + if (board->cardtype == TYPE_PCI1752 || board->cardtype == TYPE_PCI1756) + outw(0, dev->iobase + PCI1752_6_CFC); + switch (board->cardtype) { case TYPE_PCI1730: case TYPE_PCI1733: @@ -330,10 +334,6 @@ static int pci_dio_reset(struct comedi_device *dev) /* disable & clear interrupts */ outb(0x88, dev->iobase + PCI1750_ICR); break; - case TYPE_PCI1752: - outw(0, dev->iobase + PCI1752_6_CFC); /* disable channel freeze - * function */ - break; case TYPE_PCI1753E: outb(0x88, dev->iobase + PCI1753E_ICR0); /* disable & clear * interrupts */ @@ -356,8 +356,6 @@ static int pci_dio_reset(struct comedi_device *dev) outw(0x08, dev->iobase + PCI1754_ICR3); break; case TYPE_PCI1756: - outw(0, dev->iobase + PCI1752_6_CFC); /* disable channel freeze - * function */ outw(0x08, dev->iobase + PCI1754_6_ICR0); /* disable and clear * interrupts */ outw(0x08, dev->iobase + PCI1754_6_ICR1); -- GitLab From ac67a3b9ba6c87bbea813e90f3f290ed7b304d85 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:22 -0700 Subject: [PATCH 1934/2855] staging: comedi: adv_pci_dio: cleanup "disable and clear interrupts" comments For aesthetics, use a common comment for the switch() that disables and clears interrupts. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 24 +++++--------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 80c34aa89268b..8fb03e258b31a 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -307,62 +307,50 @@ static int pci_dio_reset(struct comedi_device *dev) if (board->cardtype == TYPE_PCI1752 || board->cardtype == TYPE_PCI1756) outw(0, dev->iobase + PCI1752_6_CFC); + /* disable and clear interrupts */ switch (board->cardtype) { case TYPE_PCI1730: case TYPE_PCI1733: - /* disable interrupts */ outb(0, dev->iobase + PCI1730_3_INT_EN); - /* clear interrupts */ outb(0x0f, dev->iobase + PCI1730_3_INT_CLR); - /* set rising edge trigger */ outb(0, dev->iobase + PCI1730_3_INT_RF); break; case TYPE_PCI1736: - /* disable interrupts */ outb(0, dev->iobase + PCI1736_3_INT_EN); - /* clear interrupts */ outb(0x0f, dev->iobase + PCI1736_3_INT_CLR); - /* set rising edge trigger */ outb(0, dev->iobase + PCI1736_3_INT_RF); break; case TYPE_PCI1739: - /* disable & clear interrupts */ outb(0x88, dev->iobase + PCI1739_ICR); break; case TYPE_PCI1750: case TYPE_PCI1751: - /* disable & clear interrupts */ outb(0x88, dev->iobase + PCI1750_ICR); break; case TYPE_PCI1753E: - outb(0x88, dev->iobase + PCI1753E_ICR0); /* disable & clear - * interrupts */ + outb(0x88, dev->iobase + PCI1753E_ICR0); outb(0x80, dev->iobase + PCI1753E_ICR1); outb(0x80, dev->iobase + PCI1753E_ICR2); outb(0x80, dev->iobase + PCI1753E_ICR3); /* fallthrough */ case TYPE_PCI1753: - outb(0x88, dev->iobase + PCI1753_ICR0); /* disable & clear - * interrupts */ + outb(0x88, dev->iobase + PCI1753_ICR0); outb(0x80, dev->iobase + PCI1753_ICR1); outb(0x80, dev->iobase + PCI1753_ICR2); outb(0x80, dev->iobase + PCI1753_ICR3); break; case TYPE_PCI1754: - outw(0x08, dev->iobase + PCI1754_6_ICR0); /* disable and clear - * interrupts */ + outw(0x08, dev->iobase + PCI1754_6_ICR0); outw(0x08, dev->iobase + PCI1754_6_ICR1); outw(0x08, dev->iobase + PCI1754_ICR2); outw(0x08, dev->iobase + PCI1754_ICR3); break; case TYPE_PCI1756: - outw(0x08, dev->iobase + PCI1754_6_ICR0); /* disable and clear - * interrupts */ + outw(0x08, dev->iobase + PCI1754_6_ICR0); outw(0x08, dev->iobase + PCI1754_6_ICR1); break; case TYPE_PCI1762: - outw(0x0101, dev->iobase + PCI1762_ICR); /* disable & clear - * interrupts */ + outw(0x0101, dev->iobase + PCI1762_ICR); break; default: break; -- GitLab From 86065e4d60a4a961600822654a4e6e2f232eff97 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:23 -0700 Subject: [PATCH 1935/2855] staging: comedi: adv_pci_dio: use common defines for PCI-173[036] registers These boards use the same offsets for the interrupt control registers. For aesthetics, remove the current defines and use common ones. Fix the switch() in pci_dio_reset() to use common code. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 30 +++++++------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 8fb03e258b31a..fae0a0b29c031 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -48,18 +48,14 @@ enum hw_cards_id { #define MAX_DIO_SUBDEVG 2 /* max number of DIO subdevices group per * card */ -/* Register offset definitions */ -/* Advantech PCI-1730/3/4 */ -#define PCI1730_3_INT_EN 0x08 /* R/W: enable/disable interrupts */ -#define PCI1730_3_INT_RF 0x0c /* R/W: set falling/raising edge for - * interrupts */ -#define PCI1730_3_INT_CLR 0x10 /* R/W: clear interrupts */ - -/* Advantech PCI-1736UP */ -#define PCI1736_3_INT_EN 0x08 /* R/W: enable/disable interrupts */ -#define PCI1736_3_INT_RF 0x0c /* R/W: set falling/raising edge for - * interrupts */ -#define PCI1736_3_INT_CLR 0x10 /* R/W: clear interrupts */ +/* + * Register offset definitions + */ + +/* PCI-1730, PCI-1733, PCI-1736 interrupt control registers */ +#define PCI173X_INT_EN_REG 0x08 /* R/W: enable/disable */ +#define PCI173X_INT_RF_REG 0x0c /* R/W: falling/rising edge */ +#define PCI173X_INT_CLR_REG 0x10 /* R/W: clear */ /* Advantech PCI-1739U */ #define PCI1739_ICR 32 /* W: Interrupt control register */ @@ -311,14 +307,10 @@ static int pci_dio_reset(struct comedi_device *dev) switch (board->cardtype) { case TYPE_PCI1730: case TYPE_PCI1733: - outb(0, dev->iobase + PCI1730_3_INT_EN); - outb(0x0f, dev->iobase + PCI1730_3_INT_CLR); - outb(0, dev->iobase + PCI1730_3_INT_RF); - break; case TYPE_PCI1736: - outb(0, dev->iobase + PCI1736_3_INT_EN); - outb(0x0f, dev->iobase + PCI1736_3_INT_CLR); - outb(0, dev->iobase + PCI1736_3_INT_RF); + outb(0, dev->iobase + PCI173X_INT_EN_REG); + outb(0x0f, dev->iobase + PCI173X_INT_CLR_REG); + outb(0, dev->iobase + PCI173X_INT_RF_REG); break; case TYPE_PCI1739: outb(0x88, dev->iobase + PCI1739_ICR); -- GitLab From db2c830d467db6e10e30729f16401ecd4b6480aa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:24 -0700 Subject: [PATCH 1936/2855] staging: comedi: adv_pci_dio: use common defines for PCI-1739/175[01] registers These boards use the same offsets for the interrupt control registers. For aesthetics, remove the current defines and use common ones. Fix the switch() in pci_dio_reset() to use common code. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index fae0a0b29c031..c216f39af595b 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -57,17 +57,10 @@ enum hw_cards_id { #define PCI173X_INT_RF_REG 0x0c /* R/W: falling/rising edge */ #define PCI173X_INT_CLR_REG 0x10 /* R/W: clear */ -/* Advantech PCI-1739U */ -#define PCI1739_ICR 32 /* W: Interrupt control register */ -#define PCI1739_ISR 32 /* R: Interrupt status register */ - -/* Advantech PCI-1750 */ -#define PCI1750_ICR 32 /* W: Interrupt control register */ -#define PCI1750_ISR 32 /* R: Interrupt status register */ +/* PCI-1739U, PCI-1750, PCI1751 interrupt control registers */ +#define PCI1750_INT_REG 0x20 /* R/W: status/control */ /* Advantech PCI-1751/3/3E */ -#define PCI1751_ICR 32 /* W: Interrupt control register */ -#define PCI1751_ISR 32 /* R: Interrupt status register */ #define PCI1753_ICR0 16 /* R/W: Interrupt control register group 0 */ #define PCI1753_ICR1 17 /* R/W: Interrupt control register group 1 */ #define PCI1753_ICR2 18 /* R/W: Interrupt control register group 2 */ @@ -313,11 +306,9 @@ static int pci_dio_reset(struct comedi_device *dev) outb(0, dev->iobase + PCI173X_INT_RF_REG); break; case TYPE_PCI1739: - outb(0x88, dev->iobase + PCI1739_ICR); - break; case TYPE_PCI1750: case TYPE_PCI1751: - outb(0x88, dev->iobase + PCI1750_ICR); + outb(0x88, dev->iobase + PCI1750_INT_REG); break; case TYPE_PCI1753E: outb(0x88, dev->iobase + PCI1753E_ICR0); -- GitLab From 774a8c57b14646c74c439097e1e6d06b50c21b85 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:25 -0700 Subject: [PATCH 1937/2855] staging: comedi: adv_pci_dio: cleanup PCI-1753 interrupt register defines For aesthetics, replace these defines with some macros. Refactor the switch in pci_dio_reset() to not require the fallthrough comment. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 33 +++++++++----------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index c216f39af595b..df60503d5154f 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -60,15 +60,9 @@ enum hw_cards_id { /* PCI-1739U, PCI-1750, PCI1751 interrupt control registers */ #define PCI1750_INT_REG 0x20 /* R/W: status/control */ -/* Advantech PCI-1751/3/3E */ -#define PCI1753_ICR0 16 /* R/W: Interrupt control register group 0 */ -#define PCI1753_ICR1 17 /* R/W: Interrupt control register group 1 */ -#define PCI1753_ICR2 18 /* R/W: Interrupt control register group 2 */ -#define PCI1753_ICR3 19 /* R/W: Interrupt control register group 3 */ -#define PCI1753E_ICR0 48 /* R/W: Interrupt control register group 0 */ -#define PCI1753E_ICR1 49 /* R/W: Interrupt control register group 1 */ -#define PCI1753E_ICR2 50 /* R/W: Interrupt control register group 2 */ -#define PCI1753E_ICR3 51 /* R/W: Interrupt control register group 3 */ +/* PCI-1753, PCI-1753E interrupt control registers */ +#define PCI1753_INT_REG(x) (0x10 + (x)) /* R/W: control group 0 to 3 */ +#define PCI1753E_INT_REG(x) (0x30 + (x)) /* R/W: control group 0 to 3 */ /* Advantech PCI-1752/4/6 */ #define PCI1754_6_ICR0 0x08 /* R/W: Interrupt control register group 0 */ @@ -310,17 +304,18 @@ static int pci_dio_reset(struct comedi_device *dev) case TYPE_PCI1751: outb(0x88, dev->iobase + PCI1750_INT_REG); break; - case TYPE_PCI1753E: - outb(0x88, dev->iobase + PCI1753E_ICR0); - outb(0x80, dev->iobase + PCI1753E_ICR1); - outb(0x80, dev->iobase + PCI1753E_ICR2); - outb(0x80, dev->iobase + PCI1753E_ICR3); - /* fallthrough */ case TYPE_PCI1753: - outb(0x88, dev->iobase + PCI1753_ICR0); - outb(0x80, dev->iobase + PCI1753_ICR1); - outb(0x80, dev->iobase + PCI1753_ICR2); - outb(0x80, dev->iobase + PCI1753_ICR3); + case TYPE_PCI1753E: + outb(0x88, dev->iobase + PCI1753_INT_REG(0)); + outb(0x80, dev->iobase + PCI1753_INT_REG(1)); + outb(0x80, dev->iobase + PCI1753_INT_REG(2)); + outb(0x80, dev->iobase + PCI1753_INT_REG(3)); + if (board->cardtype == TYPE_PCI1753E) { + outb(0x88, dev->iobase + PCI1753E_INT_REG(0)); + outb(0x80, dev->iobase + PCI1753E_INT_REG(1)); + outb(0x80, dev->iobase + PCI1753E_INT_REG(2)); + outb(0x80, dev->iobase + PCI1753E_INT_REG(3)); + } break; case TYPE_PCI1754: outw(0x08, dev->iobase + PCI1754_6_ICR0); -- GitLab From 008342ebfda46239ccecb6d4059d511ce5b125c1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:26 -0700 Subject: [PATCH 1938/2855] staging: comedi: adv_pci_dio: cleanup PCI-175[46] interrupt registers For aesthetics, replace these defines with a macro. Refactor the switch in pci_dio_reset() to use common code. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 21 +++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index df60503d5154f..f7466f43c95c8 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -64,11 +64,9 @@ enum hw_cards_id { #define PCI1753_INT_REG(x) (0x10 + (x)) /* R/W: control group 0 to 3 */ #define PCI1753E_INT_REG(x) (0x30 + (x)) /* R/W: control group 0 to 3 */ -/* Advantech PCI-1752/4/6 */ -#define PCI1754_6_ICR0 0x08 /* R/W: Interrupt control register group 0 */ -#define PCI1754_6_ICR1 0x0a /* R/W: Interrupt control register group 1 */ -#define PCI1754_ICR2 0x0c /* R/W: Interrupt control register group 2 */ -#define PCI1754_ICR3 0x0e /* R/W: Interrupt control register group 3 */ +/* PCI-1754, PCI-1756 interrupt control registers */ +#define PCI1754_INT_REG(x) (0x08 + (x) * 2) /* R/W: control group 0 to 3 */ + #define PCI1752_6_CFC 0x12 /* R/W: set/read channel freeze function */ /* Advantech PCI-1762 registers */ @@ -318,14 +316,13 @@ static int pci_dio_reset(struct comedi_device *dev) } break; case TYPE_PCI1754: - outw(0x08, dev->iobase + PCI1754_6_ICR0); - outw(0x08, dev->iobase + PCI1754_6_ICR1); - outw(0x08, dev->iobase + PCI1754_ICR2); - outw(0x08, dev->iobase + PCI1754_ICR3); - break; case TYPE_PCI1756: - outw(0x08, dev->iobase + PCI1754_6_ICR0); - outw(0x08, dev->iobase + PCI1754_6_ICR1); + outw(0x08, dev->iobase + PCI1754_INT_REG(0)); + outw(0x08, dev->iobase + PCI1754_INT_REG(1)); + if (board->cardtype == TYPE_PCI1754) { + outw(0x08, dev->iobase + PCI1754_INT_REG(2)); + outw(0x08, dev->iobase + PCI1754_INT_REG(3)); + } break; case TYPE_PCI1762: outw(0x0101, dev->iobase + PCI1762_ICR); -- GitLab From 6a1c0149a4dd96e2a689f6e279727d04ef2fd81a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:27 -0700 Subject: [PATCH 1939/2855] staging: comedi: adv_pci_dio: rename PCI1752_6_CFC define For aesthetics, rename this define and fix the alignment. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index f7466f43c95c8..5aba40e9b3502 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -67,7 +67,8 @@ enum hw_cards_id { /* PCI-1754, PCI-1756 interrupt control registers */ #define PCI1754_INT_REG(x) (0x08 + (x) * 2) /* R/W: control group 0 to 3 */ -#define PCI1752_6_CFC 0x12 /* R/W: set/read channel freeze function */ +/* PCI-1752, PCI-1756 special registers */ +#define PCI1752_CFC_REG 0x12 /* R/W: channel freeze function */ /* Advantech PCI-1762 registers */ #define PCI1762_ICR 6 /* W: Interrupt control register */ @@ -286,7 +287,7 @@ static int pci_dio_reset(struct comedi_device *dev) /* disable channel freeze function on the PCI-1752/1756 boards */ if (board->cardtype == TYPE_PCI1752 || board->cardtype == TYPE_PCI1756) - outw(0, dev->iobase + PCI1752_6_CFC); + outw(0, dev->iobase + PCI1752_CFC_REG); /* disable and clear interrupts */ switch (board->cardtype) { -- GitLab From d0b5860c273ae04ac1b747572aca04354f6515e1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:28 -0700 Subject: [PATCH 1940/2855] staging: comedi: adv_pci_dio: cleanup PCI-1762 interrupt registers For aesthetics, use a common define for the interrupt control and status registers. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 5aba40e9b3502..6fafc2402d427 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -70,9 +70,8 @@ enum hw_cards_id { /* PCI-1752, PCI-1756 special registers */ #define PCI1752_CFC_REG 0x12 /* R/W: channel freeze function */ -/* Advantech PCI-1762 registers */ -#define PCI1762_ICR 6 /* W: Interrupt control register */ -#define PCI1762_ISR 6 /* R: Interrupt status register */ +/* PCI-1762 interrupt control registers */ +#define PCI1762_INT_REG 0x06 /* R/W: status/control */ struct diosubd_data { int chans; /* num of chans or 8255 devices */ @@ -326,7 +325,7 @@ static int pci_dio_reset(struct comedi_device *dev) } break; case TYPE_PCI1762: - outw(0x0101, dev->iobase + PCI1762_ICR); + outw(0x0101, dev->iobase + PCI1762_INT_REG); break; default: break; -- GitLab From bcae0adaf4f2fd9105ca11ca9df10a5f3881ea26 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:29 -0700 Subject: [PATCH 1941/2855] staging: comedi: adv_pci_dio: remove boardinfo 'cardtype' This member of the boardinfo is identical to the offset of the boardinfo in the boardtypes array. It's also passed as the 'context' to the driver (*auto_attach). The 'cardtype' is only needed by the (*auto_attach) to determine which PCI BAR to use and in pci_dio_reset() to handle the board specific code. Remove the 'cardtype' member and use the 'context' value instead. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 31 +++++--------------- 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 6fafc2402d427..21df123191074 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -80,7 +80,6 @@ struct diosubd_data { struct dio_boardtype { const char *name; /* board name */ - enum hw_cards_id cardtype; int nsubdevs; struct diosubd_data sdi[MAX_DI_SUBDEVS]; /* DI chans */ struct diosubd_data sdo[MAX_DO_SUBDEVS]; /* DO chans */ @@ -93,7 +92,6 @@ struct dio_boardtype { static const struct dio_boardtype boardtypes[] = { [TYPE_PCI1730] = { .name = "pci1730", - .cardtype = TYPE_PCI1730, .nsubdevs = 5, .sdi[0] = { 16, 0x02, }, /* DI 0-15 */ .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */ @@ -103,21 +101,18 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1733] = { .name = "pci1733", - .cardtype = TYPE_PCI1733, .nsubdevs = 2, .sdi[1] = { 32, 0x00, }, /* ISO DI 0-31 */ .id_reg = 0x04, }, [TYPE_PCI1734] = { .name = "pci1734", - .cardtype = TYPE_PCI1734, .nsubdevs = 2, .sdo[1] = { 32, 0x00, }, /* ISO DO 0-31 */ .id_reg = 0x04, }, [TYPE_PCI1735] = { .name = "pci1735", - .cardtype = TYPE_PCI1735, .nsubdevs = 4, .sdi[0] = { 32, 0x00, }, /* DI 0-31 */ .sdo[0] = { 32, 0x00, }, /* DO 0-31 */ @@ -126,7 +121,6 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1736] = { .name = "pci1736", - .cardtype = TYPE_PCI1736, .nsubdevs = 3, .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */ .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */ @@ -134,28 +128,24 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1739] = { .name = "pci1739", - .cardtype = TYPE_PCI1739, .nsubdevs = 3, .sdio[0] = { 2, 0x00, }, /* 8255 DIO */ .id_reg = 0x08, }, [TYPE_PCI1750] = { .name = "pci1750", - .cardtype = TYPE_PCI1750, .nsubdevs = 2, .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */ .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */ }, [TYPE_PCI1751] = { .name = "pci1751", - .cardtype = TYPE_PCI1751, .nsubdevs = 3, .sdio[0] = { 2, 0x00, }, /* 8255 DIO */ .timer_regbase = 0x18, }, [TYPE_PCI1752] = { .name = "pci1752", - .cardtype = TYPE_PCI1752, .nsubdevs = 3, .sdo[0] = { 32, 0x00, }, /* DO 0-31 */ .sdo[1] = { 32, 0x04, }, /* DO 32-63 */ @@ -164,20 +154,17 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1753] = { .name = "pci1753", - .cardtype = TYPE_PCI1753, .nsubdevs = 4, .sdio[0] = { 4, 0x00, }, /* 8255 DIO */ }, [TYPE_PCI1753E] = { .name = "pci1753e", - .cardtype = TYPE_PCI1753E, .nsubdevs = 8, .sdio[0] = { 4, 0x00, }, /* 8255 DIO */ .sdio[1] = { 4, 0x20, }, /* 8255 DIO */ }, [TYPE_PCI1754] = { .name = "pci1754", - .cardtype = TYPE_PCI1754, .nsubdevs = 3, .sdi[0] = { 32, 0x00, }, /* DI 0-31 */ .sdi[1] = { 32, 0x04, }, /* DI 32-63 */ @@ -186,7 +173,6 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1756] = { .name = "pci1756", - .cardtype = TYPE_PCI1756, .nsubdevs = 3, .sdi[1] = { 32, 0x00, }, /* DI 0-31 */ .sdo[1] = { 32, 0x04, }, /* DO 0-31 */ @@ -195,7 +181,6 @@ static const struct dio_boardtype boardtypes[] = { }, [TYPE_PCI1762] = { .name = "pci1762", - .cardtype = TYPE_PCI1762, .nsubdevs = 3, .sdi[1] = { 16, 0x02, }, /* ISO DI 0-15 */ .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */ @@ -280,16 +265,14 @@ static int pci_dio_insn_bits_do_w(struct comedi_device *dev, return insn->n; } -static int pci_dio_reset(struct comedi_device *dev) +static int pci_dio_reset(struct comedi_device *dev, unsigned long cardtype) { - const struct dio_boardtype *board = dev->board_ptr; - /* disable channel freeze function on the PCI-1752/1756 boards */ - if (board->cardtype == TYPE_PCI1752 || board->cardtype == TYPE_PCI1756) + if (cardtype == TYPE_PCI1752 || cardtype == TYPE_PCI1756) outw(0, dev->iobase + PCI1752_CFC_REG); /* disable and clear interrupts */ - switch (board->cardtype) { + switch (cardtype) { case TYPE_PCI1730: case TYPE_PCI1733: case TYPE_PCI1736: @@ -308,7 +291,7 @@ static int pci_dio_reset(struct comedi_device *dev) outb(0x80, dev->iobase + PCI1753_INT_REG(1)); outb(0x80, dev->iobase + PCI1753_INT_REG(2)); outb(0x80, dev->iobase + PCI1753_INT_REG(3)); - if (board->cardtype == TYPE_PCI1753E) { + if (cardtype == TYPE_PCI1753E) { outb(0x88, dev->iobase + PCI1753E_INT_REG(0)); outb(0x80, dev->iobase + PCI1753E_INT_REG(1)); outb(0x80, dev->iobase + PCI1753E_INT_REG(2)); @@ -319,7 +302,7 @@ static int pci_dio_reset(struct comedi_device *dev) case TYPE_PCI1756: outw(0x08, dev->iobase + PCI1754_INT_REG(0)); outw(0x08, dev->iobase + PCI1754_INT_REG(1)); - if (board->cardtype == TYPE_PCI1754) { + if (cardtype == TYPE_PCI1754) { outw(0x08, dev->iobase + PCI1754_INT_REG(2)); outw(0x08, dev->iobase + PCI1754_INT_REG(3)); } @@ -385,12 +368,12 @@ static int pci_dio_auto_attach(struct comedi_device *dev, ret = comedi_pci_enable(dev); if (ret) return ret; - if (board->cardtype == TYPE_PCI1736) + if (context == TYPE_PCI1736) dev->iobase = pci_resource_start(pcidev, 0); else dev->iobase = pci_resource_start(pcidev, 2); - pci_dio_reset(dev); + pci_dio_reset(dev, context); ret = comedi_alloc_subdevices(dev, board->nsubdevs); if (ret) -- GitLab From 2b60bbde040f1ad542bfc7d94b6b9b4b71140f5f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:30 -0700 Subject: [PATCH 1942/2855] staging: comedi: adv_pci_dio: move and rename enum hw_cards_id For aesthetics, move this enum after the register defines and rename it to have namespace associated with the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 29 ++++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 21df123191074..2f89cbec670c6 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -31,18 +31,6 @@ #include "8255.h" #include "comedi_8254.h" -/* hardware types of the cards */ -enum hw_cards_id { - TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1735, TYPE_PCI1736, - TYPE_PCI1739, - TYPE_PCI1750, - TYPE_PCI1751, - TYPE_PCI1752, - TYPE_PCI1753, TYPE_PCI1753E, - TYPE_PCI1754, TYPE_PCI1756, - TYPE_PCI1762 -}; - #define MAX_DI_SUBDEVS 2 /* max number of DI subdevices per card */ #define MAX_DO_SUBDEVS 2 /* max number of DO subdevices per card */ #define MAX_DIO_SUBDEVG 2 /* max number of DIO subdevices group per @@ -73,6 +61,23 @@ enum hw_cards_id { /* PCI-1762 interrupt control registers */ #define PCI1762_INT_REG 0x06 /* R/W: status/control */ +enum pci_dio_boardid { + TYPE_PCI1730, + TYPE_PCI1733, + TYPE_PCI1734, + TYPE_PCI1735, + TYPE_PCI1736, + TYPE_PCI1739, + TYPE_PCI1750, + TYPE_PCI1751, + TYPE_PCI1752, + TYPE_PCI1753, + TYPE_PCI1753E, + TYPE_PCI1754, + TYPE_PCI1756, + TYPE_PCI1762 +}; + struct diosubd_data { int chans; /* num of chans or 8255 devices */ unsigned long addr; /* PCI address ofset */ -- GitLab From a54b6e60f32841e482d6d5ad5edb136fd68697ad Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:31 -0700 Subject: [PATCH 1943/2855] staging: comedi: adv_pci_dio: move and rename the MAX_*_SUBDEV[SG] defines For aesthetics, move these defines after the register defines and rename them to have namespace associated with the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 2f89cbec670c6..f3c9628c7d953 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -31,11 +31,6 @@ #include "8255.h" #include "comedi_8254.h" -#define MAX_DI_SUBDEVS 2 /* max number of DI subdevices per card */ -#define MAX_DO_SUBDEVS 2 /* max number of DO subdevices per card */ -#define MAX_DIO_SUBDEVG 2 /* max number of DIO subdevices group per - * card */ - /* * Register offset definitions */ @@ -61,6 +56,11 @@ /* PCI-1762 interrupt control registers */ #define PCI1762_INT_REG 0x06 /* R/W: status/control */ +/* maximum number of subdevice descriptions in the boardinfo */ +#define PCI_DIO_MAX_DI_SUBDEVS 2 /* 2 x 8/16/32 input channels max */ +#define PCI_DIO_MAX_DO_SUBDEVS 2 /* 2 x 8/16/32 output channels max */ +#define PCI_DIO_MAX_DIO_SUBDEVG 2 /* 2 x any number of 8255 devices max */ + enum pci_dio_boardid { TYPE_PCI1730, TYPE_PCI1733, @@ -86,9 +86,9 @@ struct diosubd_data { struct dio_boardtype { const char *name; /* board name */ int nsubdevs; - struct diosubd_data sdi[MAX_DI_SUBDEVS]; /* DI chans */ - struct diosubd_data sdo[MAX_DO_SUBDEVS]; /* DO chans */ - struct diosubd_data sdio[MAX_DIO_SUBDEVG]; /* DIO 8255 chans */ + struct diosubd_data sdi[PCI_DIO_MAX_DI_SUBDEVS]; + struct diosubd_data sdo[PCI_DIO_MAX_DO_SUBDEVS]; + struct diosubd_data sdio[PCI_DIO_MAX_DIO_SUBDEVG]; unsigned long id_reg; unsigned long timer_regbase; unsigned int is_16bit:1; @@ -385,7 +385,7 @@ static int pci_dio_auto_attach(struct comedi_device *dev, return ret; subdev = 0; - for (i = 0; i < MAX_DI_SUBDEVS; i++) { + for (i = 0; i < PCI_DIO_MAX_DI_SUBDEVS; i++) { d = &board->sdi[i]; if (d->chans) { s = &dev->subdevices[subdev++]; @@ -401,7 +401,7 @@ static int pci_dio_auto_attach(struct comedi_device *dev, } } - for (i = 0; i < MAX_DO_SUBDEVS; i++) { + for (i = 0; i < PCI_DIO_MAX_DO_SUBDEVS; i++) { d = &board->sdo[i]; if (d->chans) { s = &dev->subdevices[subdev++]; @@ -432,7 +432,7 @@ static int pci_dio_auto_attach(struct comedi_device *dev, } } - for (i = 0; i < MAX_DIO_SUBDEVG; i++) { + for (i = 0; i < PCI_DIO_MAX_DIO_SUBDEVG; i++) { d = &board->sdio[i]; for (j = 0; j < d->chans; j++) { s = &dev->subdevices[subdev++]; -- GitLab From d97e1552fd71e7ba512c626f5c90afa331c48cec Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:32 -0700 Subject: [PATCH 1944/2855] staging: comedi: adv_pci_dio: move pci_dio_override_cardtype() This function is called as part of the pci_driver (*probe) before doing the (*auto_attach) of the comedi driver. For aesthetics, move the function to a more logical place in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 64 ++++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index f3c9628c7d953..b7f13bca2b728 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -322,38 +322,6 @@ static int pci_dio_reset(struct comedi_device *dev, unsigned long cardtype) return 0; } -static unsigned long pci_dio_override_cardtype(struct pci_dev *pcidev, - unsigned long cardtype) -{ - /* - * Change cardtype from TYPE_PCI1753 to TYPE_PCI1753E if expansion - * board available. Need to enable PCI device and request the main - * registers PCI BAR temporarily to perform the test. - */ - if (cardtype != TYPE_PCI1753) - return cardtype; - if (pci_enable_device(pcidev) < 0) - return cardtype; - if (pci_request_region(pcidev, 2, "adv_pci_dio") == 0) { - /* - * This test is based on Advantech's "advdaq" driver source - * (which declares its module licence as "GPL" although the - * driver source does not include a "COPYING" file). - */ - unsigned long reg = pci_resource_start(pcidev, 2) + 53; - - outb(0x05, reg); - if ((inb(reg) & 0x07) == 0x02) { - outb(0x02, reg); - if ((inb(reg) & 0x07) == 0x05) - cardtype = TYPE_PCI1753E; - } - pci_release_region(pcidev, 2); - } - pci_disable_device(pcidev); - return cardtype; -} - static int pci_dio_auto_attach(struct comedi_device *dev, unsigned long context) { @@ -477,6 +445,38 @@ static struct comedi_driver adv_pci_dio_driver = { .detach = comedi_pci_detach, }; +static unsigned long pci_dio_override_cardtype(struct pci_dev *pcidev, + unsigned long cardtype) +{ + /* + * Change cardtype from TYPE_PCI1753 to TYPE_PCI1753E if expansion + * board available. Need to enable PCI device and request the main + * registers PCI BAR temporarily to perform the test. + */ + if (cardtype != TYPE_PCI1753) + return cardtype; + if (pci_enable_device(pcidev) < 0) + return cardtype; + if (pci_request_region(pcidev, 2, "adv_pci_dio") == 0) { + /* + * This test is based on Advantech's "advdaq" driver source + * (which declares its module licence as "GPL" although the + * driver source does not include a "COPYING" file). + */ + unsigned long reg = pci_resource_start(pcidev, 2) + 53; + + outb(0x05, reg); + if ((inb(reg) & 0x07) == 0x02) { + outb(0x02, reg); + if ((inb(reg) & 0x07) == 0x05) + cardtype = TYPE_PCI1753E; + } + pci_release_region(pcidev, 2); + } + pci_disable_device(pcidev); + return cardtype; +} + static int adv_pci_dio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { -- GitLab From bb263fd5d33f4060fb813f99b3558dff1a11d4c1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:33 -0700 Subject: [PATCH 1945/2855] staging: comedi: adv_pci_dio: tidy up the comedi comment block The Description is a bit long winded and the same information is in the Devices. Shorten the Description and tidy up the Devices. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index b7f13bca2b728..f8e9bf903a670 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -8,14 +8,11 @@ /* * Driver: adv_pci_dio - * Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1735U, - * PCI-1736UP, PCI-1739U, PCI-1750, PCI-1751, PCI-1752, - * PCI-1753/E, PCI-1754, PCI-1756, PCI-1762 + * Description: Advantech Digital I/O Cards * Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733, * PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U, PCI-1750, - * PCI-1751, PCI-1752, PCI-1753, - * PCI-1753+PCI-1753E, PCI-1754, PCI-1756, - * PCI-1762 + * PCI-1751, PCI-1752, PCI-1753, PCI-1753+PCI-1753E, + * PCI-1754, PCI-1756, PCI-1762 * Author: Michal Dobes * Updated: Mon, 09 Jan 2012 12:40:46 +0000 * Status: untested -- GitLab From b4717ff608c180115ace1d307e7f452e114ca29c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 18 Nov 2015 10:07:34 -0700 Subject: [PATCH 1946/2855] staging: comedi: adv_pci_dio: update the MODULE_DESCRIPTION Change the MODULE_DESCRIPTION to something more useful than the generic "Comedi low-level driver". Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index f8e9bf903a670..620cec13d74cd 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -510,5 +510,5 @@ static struct pci_driver adv_pci_dio_pci_driver = { module_comedi_pci_driver(adv_pci_dio_driver, adv_pci_dio_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); +MODULE_DESCRIPTION("Comedi driver for Advantech Digital I/O Cards"); MODULE_LICENSE("GPL"); -- GitLab From 06181de14ff09b274b699ee2dd39fe5e37efb419 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 18 Nov 2015 17:55:04 +0000 Subject: [PATCH 1947/2855] staging: comedi: rearrange comedi_write() code Rearrange the code in `comedi_write()` to reduce the amount of indentation. The code never reiterates the `while` loop once `count` has become non-zero, so we can check that in the `while` condition to save an indentation level. (Note that `nbytes` has been checked to be non-zero before entering the loop, so we can remove that check.) Move the code that makes the subdevice "become non-busy" outside the `while` loop, using a new flag variable `become_nonbusy` to decide whether it needs to be done. This simplifies the wait queue handling so there is a single place where the task is removed from the wait queue, and we can remove the `on_wait_queue` flag variable. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 71 ++++++++++++---------------- 1 file changed, 30 insertions(+), 41 deletions(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 7b4af519e17e1..c9da6f39b1c6c 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2307,7 +2307,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, DECLARE_WAITQUEUE(wait, current); struct comedi_file *cfp = file->private_data; struct comedi_device *dev = cfp->dev; - bool on_wait_queue = false; + bool become_nonbusy = false; bool attach_locked; unsigned int old_detach_count; @@ -2342,48 +2342,16 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, } add_wait_queue(&async->wait_head, &wait); - on_wait_queue = true; - while (nbytes > 0 && !retval) { + while (count == 0 && !retval) { unsigned runflags; set_current_state(TASK_INTERRUPTIBLE); runflags = comedi_get_subdevice_runflags(s); if (!comedi_is_runflags_running(runflags)) { - if (count == 0) { - struct comedi_subdevice *new_s; - - if (comedi_is_runflags_in_error(runflags)) - retval = -EPIPE; - else - retval = 0; - /* - * To avoid deadlock, cannot acquire dev->mutex - * while dev->attach_lock is held. Need to - * remove task from the async wait queue before - * releasing dev->attach_lock, as it might not - * be valid afterwards. - */ - remove_wait_queue(&async->wait_head, &wait); - on_wait_queue = false; - up_read(&dev->attach_lock); - attach_locked = false; - mutex_lock(&dev->mutex); - /* - * Become non-busy unless things have changed - * behind our back. Checking dev->detach_count - * is unchanged ought to be sufficient (unless - * there have been 2**32 detaches in the - * meantime!), but check the subdevice pointer - * as well just in case. - */ - new_s = comedi_file_write_subdevice(file); - if (dev->attached && - old_detach_count == dev->detach_count && - s == new_s && new_s->async == async) - do_become_nonbusy(dev, s); - mutex_unlock(&dev->mutex); - } + if (comedi_is_runflags_in_error(runflags)) + retval = -EPIPE; + become_nonbusy = true; break; } @@ -2433,12 +2401,33 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, nbytes -= n; buf += n; - break; /* makes device work like a pipe */ } -out: - if (on_wait_queue) - remove_wait_queue(&async->wait_head, &wait); + remove_wait_queue(&async->wait_head, &wait); set_current_state(TASK_RUNNING); + if (become_nonbusy && count == 0) { + struct comedi_subdevice *new_s; + + /* + * To avoid deadlock, cannot acquire dev->mutex + * while dev->attach_lock is held. + */ + up_read(&dev->attach_lock); + attach_locked = false; + mutex_lock(&dev->mutex); + /* + * Check device hasn't become detached behind our back. + * Checking dev->detach_count is unchanged ought to be + * sufficient (unless there have been 2**32 detaches in the + * meantime!), but check the subdevice pointer as well just in + * case. + */ + new_s = comedi_file_write_subdevice(file); + if (dev->attached && old_detach_count == dev->detach_count && + s == new_s && new_s->async == async) + do_become_nonbusy(dev, s); + mutex_unlock(&dev->mutex); + } +out: if (attach_locked) up_read(&dev->attach_lock); -- GitLab From ed65bba31bdf038bada04415065b8d9b218b6066 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 18 Nov 2015 17:55:05 +0000 Subject: [PATCH 1948/2855] staging: comedi: do extra checks for becoming non-busy for "write" `comedi_write()` is the handler for the "write" file operation for COMEDI devices. It mostly runs without using the main mutex of the COMEDI device, but uses the `attach_lock` rw_semaphore to protect against the COMEDI device becoming "detached". A file object can write data for a COMEDI asynchonous command if it initiated the command. The COMEDI subdevice is marked as busy when the command is started. At some point, the "write" handler detects that the command has terminated and so marks the subdevice as non-busy. In order to mark the subdevice as non-busy, the "write" handler needs to release the `attach_lock` rw_semaphore and `acquire the main `mutex`. There is a vulnerable point between the two, so it checks that the device is still attached after acquiring the mutex. However, it does not currently check that the conditions for becoming non-busy still hold. Add some more checks that the subdevice is still busy with a command initiated by the same file object, and that the command is in the correct direction (in case the subdevice supports both "read" and "write"). Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index c9da6f39b1c6c..94c23484284fa 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2420,10 +2420,15 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, * sufficient (unless there have been 2**32 detaches in the * meantime!), but check the subdevice pointer as well just in * case. + * + * Also check the subdevice is still in a suitable state to + * become non-busy in case it changed behind our back. */ new_s = comedi_file_write_subdevice(file); if (dev->attached && old_detach_count == dev->detach_count && - s == new_s && new_s->async == async) + s == new_s && new_s->async == async && s->busy == file && + (async->cmd.flags & CMDF_WRITE) && + !comedi_is_subdevice_running(s)) do_become_nonbusy(dev, s); mutex_unlock(&dev->mutex); } -- GitLab From 84a185ec429fe64e5b0d81d7ac815c91578ee569 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 18 Nov 2015 17:55:06 +0000 Subject: [PATCH 1949/2855] staging: comedi: make some variables unsigned in comedi_write() In `comedi_write()`, the `n` and `m` variables are of type `int`. Change them to `unsigned int` as they are used to measure a positive number of bytes. The `count` variable is also of type `int` and holds the returned number of bytes written. Change it to type `ssize_t` to match the function's return type. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 94c23484284fa..188a12a02ce73 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2303,7 +2303,9 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, { struct comedi_subdevice *s; struct comedi_async *async; - int n, m, count = 0, retval = 0; + unsigned int n, m; + ssize_t count = 0; + int retval = 0; DECLARE_WAITQUEUE(wait, current); struct comedi_file *cfp = file->private_data; struct comedi_device *dev = cfp->dev; -- GitLab From 591c5f8a599a58c7c3773027010e537fc1d7a7d5 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 18 Nov 2015 17:55:07 +0000 Subject: [PATCH 1950/2855] staging: comedi: avoid bad truncation of a size_t in comedi_write() At one point in `comedi_write()`, the variable `n` gets assigned to the minimum of the parameter `nbytes` and the amount of writeable buffer space. The way that is done currently is unsafe in the unlikely case that `nbytes` exceeds `UINT_MAX`, so fix it. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 188a12a02ce73..8c784c483c3e7 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2357,16 +2357,13 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, break; } - n = nbytes; - - m = n; + /* Allocate all free buffer space. */ + comedi_buf_write_alloc(s, async->prealloc_bufsz); + m = comedi_buf_write_n_allocated(s); + /* Avoid buffer wraparound. */ if (async->buf_write_ptr + m > async->prealloc_bufsz) m = async->prealloc_bufsz - async->buf_write_ptr; - comedi_buf_write_alloc(s, async->prealloc_bufsz); - if (m > comedi_buf_write_n_allocated(s)) - m = comedi_buf_write_n_allocated(s); - if (m < n) - n = m; + n = min_t(size_t, m, nbytes); if (n == 0) { if (file->f_flags & O_NONBLOCK) { -- GitLab From 35a7475dc818320915e89ed0217872ff1ab66ec2 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 18 Nov 2015 17:55:08 +0000 Subject: [PATCH 1951/2855] staging: comedi: allow buffer wraparound in comedi_write() `comedi_write()` copies data from the user buffer to the acquisition data buffer, which is cyclic, using a single call to `copy_from_user()`. It currently avoids having to deal with wraparound of the cyclic buffer by limiting the amount it copies (and the amount returned to the user). Change it to deal with the wraparound using two calls to `copy_from_user()` if necessary. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 8c784c483c3e7..4dd42890c6414 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2346,6 +2346,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, add_wait_queue(&async->wait_head, &wait); while (count == 0 && !retval) { unsigned runflags; + unsigned int wp, n1, n2; set_current_state(TASK_INTERRUPTIBLE); @@ -2360,9 +2361,6 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, /* Allocate all free buffer space. */ comedi_buf_write_alloc(s, async->prealloc_bufsz); m = comedi_buf_write_n_allocated(s); - /* Avoid buffer wraparound. */ - if (async->buf_write_ptr + m > async->prealloc_bufsz) - m = async->prealloc_bufsz - async->buf_write_ptr; n = min_t(size_t, m, nbytes); if (n == 0) { @@ -2388,8 +2386,14 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, continue; } - m = copy_from_user(async->prealloc_buf + async->buf_write_ptr, - buf, n); + wp = async->buf_write_ptr; + n1 = min(n, async->prealloc_bufsz - wp); + n2 = n - n1; + m = copy_from_user(async->prealloc_buf + wp, buf, n1); + if (m) + m += n2; + else if (n2) + m = copy_from_user(async->prealloc_buf, buf + n1, n2); if (m) { n -= m; retval = -EFAULT; -- GitLab From 40d0e80e08012ac99b187cbaaeb8aab92b71714d Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 18 Nov 2015 17:55:09 +0000 Subject: [PATCH 1952/2855] staging: comedi: return error on "write" if no command set up The "write" file operation handler, `comedi_write()` returns an error for pretty much any condition that prevents a "write" going ahead. One of the conditions that prevents a "write" going ahead is that no asynchronous command has been set up, but that currently results in a return value of 0 (unless COMEDI instructions are being processed or an asynchronous command has been set up by a different file object). Change it to return `-EINVAL` in this case. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 4dd42890c6414..2a2b5a06ed0e9 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2331,9 +2331,12 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, } async = s->async; - - if (!s->busy || !nbytes) + if (!nbytes) + goto out; + if (!s->busy) { + retval = -EINVAL; goto out; + } if (s->busy != file) { retval = -EACCES; goto out; @@ -2373,8 +2376,10 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, retval = -ERESTARTSYS; break; } - if (!s->busy) + if (!s->busy) { + retval = -EINVAL; break; + } if (s->busy != file) { retval = -EACCES; break; -- GitLab From 3318c7add8b43a071498a973548dd24b55c587d4 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 18 Nov 2015 17:55:10 +0000 Subject: [PATCH 1953/2855] staging: comedi: simplify returned errors for comedi_write() In order to perform a "write" file operation, an asynchronous COMEDI command in the "write" direction needs to have been set up by the current file object on the COMEDI "write" subdevice associated with the file object. If there is a "write" subdevice, but a command has not been set up by the file object (or is has been set-up in the wrong direction), `comedi_write()` currently returns one of two error values `-EINVAL` or `-EACCES`. `-EACCES` is returned if the command was set up by a different subdevice, or somewhat randomly, if a COMEDI "instruction" is currently being processed. `-EINVAL` is returned in other cases. Simplify it by returning `-EINVAL` for all these cases. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 2a2b5a06ed0e9..5a9c9d9782f37 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2333,15 +2333,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, async = s->async; if (!nbytes) goto out; - if (!s->busy) { - retval = -EINVAL; - goto out; - } - if (s->busy != file) { - retval = -EACCES; - goto out; - } - if (!(async->cmd.flags & CMDF_WRITE)) { + if (s->busy != file || !(async->cmd.flags & CMDF_WRITE)) { retval = -EINVAL; goto out; } @@ -2376,15 +2368,8 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, retval = -ERESTARTSYS; break; } - if (!s->busy) { - retval = -EINVAL; - break; - } - if (s->busy != file) { - retval = -EACCES; - break; - } - if (!(async->cmd.flags & CMDF_WRITE)) { + if (s->busy != file || + !(async->cmd.flags & CMDF_WRITE)) { retval = -EINVAL; break; } -- GitLab From 28a60c456bc52bbe949ad54c6b23917a651fc342 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 18 Nov 2015 17:55:11 +0000 Subject: [PATCH 1954/2855] staging: comedi: check for more errors for zero-length write If the "write" file operation handler, `comedi_write()` is passed 0 for the amount to write, some error conditions are currently skipped and the function just returns 0. Change it to check those error conditions and return an error value if appropriate. The trickiest case is the check for when the previously set up asynchronous command has terminated with an error. In that case, `-EPIPE` is returned (as it is for a write of non-zero length) and the subdevice gets marked as non-busy. A zero-length write that returns 0 has no other effects, in particular, it does not cause the subdevice to be marked as non-busy. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 5a9c9d9782f37..d57fadef47fcf 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2331,8 +2331,6 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, } async = s->async; - if (!nbytes) - goto out; if (s->busy != file || !(async->cmd.flags & CMDF_WRITE)) { retval = -EINVAL; goto out; @@ -2349,9 +2347,12 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, if (!comedi_is_runflags_running(runflags)) { if (comedi_is_runflags_in_error(runflags)) retval = -EPIPE; - become_nonbusy = true; + if (retval || nbytes) + become_nonbusy = true; break; } + if (nbytes == 0) + break; /* Allocate all free buffer space. */ comedi_buf_write_alloc(s, async->prealloc_bufsz); -- GitLab From 479bd5edab3ca840ba60a89d3172029039ddc2a6 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 19 Nov 2015 14:49:07 +0000 Subject: [PATCH 1955/2855] staging: comedi: s526: replace counter mode bitfield struct The driver uses `struct counter_mode_register_t` to describe the 16-bit counter mode register as a sequence of bitfield members. The struct appears as the type of one of the members of `union cmReg`, the other member of which is of type `unsigned short`, so the driver can manipulate the register value as a whole, or as individual fields. Although this is fairly convenient, it's not that conventional. The code also needs to define the bitfield members in ascending or descending order of the physical bits, depending on whether bitfields are little- or big-endian. Rip all that out and replace it with a bunch of macros to set and mask out bits of the register value, as that's the more conventional way to do it. A bonus is that we get rid of a load of CamelCase definitions in the process. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s526.c | 156 +++++++++++++++----------- 1 file changed, 93 insertions(+), 63 deletions(-) diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index d70c979476274..a8165dfe6f5f8 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -37,7 +37,6 @@ #include #include "../comedidev.h" -#include /* * Register I/O map @@ -84,6 +83,62 @@ #define S526_GPCT_LSB_REG(x) (0x12 + ((x) * 8)) #define S526_GPCT_MSB_REG(x) (0x14 + ((x) * 8)) #define S526_GPCT_MODE_REG(x) (0x16 + ((x) * 8)) +#define S526_GPCT_MODE_COUT_SRC(x) ((x) << 0) +#define S526_GPCT_MODE_COUT_SRC_MASK S526_GPCT_MODE_COUT_SRC(0x1) +#define S526_GPCT_MODE_COUT_SRC_RCAP S526_GPCT_MODE_COUT_SRC(0) +#define S526_GPCT_MODE_COUT_SRC_RTGL S526_GPCT_MODE_COUT_SRC(1) +#define S526_GPCT_MODE_COUT_POL(x) ((x) << 1) +#define S526_GPCT_MODE_COUT_POL_MASK S526_GPCT_MODE_COUT_POL(0x1) +#define S526_GPCT_MODE_COUT_POL_NORM S526_GPCT_MODE_COUT_POL(0) +#define S526_GPCT_MODE_COUT_POL_INV S526_GPCT_MODE_COUT_POL(1) +#define S526_GPCT_MODE_AUTOLOAD(x) ((x) << 2) +#define S526_GPCT_MODE_AUTOLOAD_MASK S526_GPCT_MODE_AUTOLOAD(0x7) +#define S526_GPCT_MODE_AUTOLOAD_NONE S526_GPCT_MODE_AUTOLOAD(0) +/* these 3 bits can be OR'ed */ +#define S526_GPCT_MODE_AUTOLOAD_RO S526_GPCT_MODE_AUTOLOAD(0x1) +#define S526_GPCT_MODE_AUTOLOAD_IXFALL S526_GPCT_MODE_AUTOLOAD(0x2) +#define S526_GPCT_MODE_AUTOLOAD_IXRISE S526_GPCT_MODE_AUTOLOAD(0x4) +#define S526_GPCT_MODE_HWCTEN_SRC(x) ((x) << 5) +#define S526_GPCT_MODE_HWCTEN_SRC_MASK S526_GPCT_MODE_HWCTEN_SRC(0x3) +#define S526_GPCT_MODE_HWCTEN_SRC_CEN S526_GPCT_MODE_HWCTEN_SRC(0) +#define S526_GPCT_MODE_HWCTEN_SRC_IX S526_GPCT_MODE_HWCTEN_SRC(1) +#define S526_GPCT_MODE_HWCTEN_SRC_IXRF S526_GPCT_MODE_HWCTEN_SRC(2) +#define S526_GPCT_MODE_HWCTEN_SRC_NRCAP S526_GPCT_MODE_HWCTEN_SRC(3) +#define S526_GPCT_MODE_CTEN_CTRL(x) ((x) << 7) +#define S526_GPCT_MODE_CTEN_CTRL_MASK S526_GPCT_MODE_CTEN_CTRL(0x3) +#define S526_GPCT_MODE_CTEN_CTRL_DIS S526_GPCT_MODE_CTEN_CTRL(0) +#define S526_GPCT_MODE_CTEN_CTRL_ENA S526_GPCT_MODE_CTEN_CTRL(1) +#define S526_GPCT_MODE_CTEN_CTRL_HW S526_GPCT_MODE_CTEN_CTRL(2) +#define S526_GPCT_MODE_CTEN_CTRL_INVHW S526_GPCT_MODE_CTEN_CTRL(3) +#define S526_GPCT_MODE_CLK_SRC(x) ((x) << 9) +#define S526_GPCT_MODE_CLK_SRC_MASK S526_GPCT_MODE_CLK_SRC(0x3) +/* if count direction control set to quadrature */ +#define S526_GPCT_MODE_CLK_SRC_QUADX1 S526_GPCT_MODE_CLK_SRC(0) +#define S526_GPCT_MODE_CLK_SRC_QUADX2 S526_GPCT_MODE_CLK_SRC(1) +#define S526_GPCT_MODE_CLK_SRC_QUADX4 S526_GPCT_MODE_CLK_SRC(2) +#define S526_GPCT_MODE_CLK_SRC_QUADX4_ S526_GPCT_MODE_CLK_SRC(3) +/* if count direction control set to software control */ +#define S526_GPCT_MODE_CLK_SRC_ARISE S526_GPCT_MODE_CLK_SRC(0) +#define S526_GPCT_MODE_CLK_SRC_AFALL S526_GPCT_MODE_CLK_SRC(1) +#define S526_GPCT_MODE_CLK_SRC_INT S526_GPCT_MODE_CLK_SRC(2) +#define S526_GPCT_MODE_CLK_SRC_INTHALF S526_GPCT_MODE_CLK_SRC(3) +#define S526_GPCT_MODE_CT_DIR(x) ((x) << 11) +#define S526_GPCT_MODE_CT_DIR_MASK S526_GPCT_MODE_CT_DIR(0x1) +/* if count direction control set to software control */ +#define S526_GPCT_MODE_CT_DIR_UP S526_GPCT_MODE_CT_DIR(0) +#define S526_GPCT_MODE_CT_DIR_DOWN S526_GPCT_MODE_CT_DIR(1) +#define S526_GPCT_MODE_CTDIR_CTRL(x) ((x) << 12) +#define S526_GPCT_MODE_CTDIR_CTRL_MASK S526_GPCT_MODE_CTDIR_CTRL(0x1) +#define S526_GPCT_MODE_CTDIR_CTRL_QUAD S526_GPCT_MODE_CTDIR_CTRL(0) +#define S526_GPCT_MODE_CTDIR_CTRL_SOFT S526_GPCT_MODE_CTDIR_CTRL(1) +#define S526_GPCT_MODE_LATCH_CTRL(x) ((x) << 13) +#define S526_GPCT_MODE_LATCH_CTRL_MASK S526_GPCT_MODE_LATCH_CTRL(0x1) +#define S526_GPCT_MODE_LATCH_CTRL_READ S526_GPCT_MODE_LATCH_CTRL(0) +#define S526_GPCT_MODE_LATCH_CTRL_EVENT S526_GPCT_MODE_LATCH_CTRL(1) +#define S526_GPCT_MODE_PR_SELECT(x) ((x) << 14) +#define S526_GPCT_MODE_PR_SELECT_MASK S526_GPCT_MODE_PR_SELECT(0x1) +#define S526_GPCT_MODE_PR_SELECT_PR0 S526_GPCT_MODE_PR_SELECT(0) +#define S526_GPCT_MODE_PR_SELECT_PR1 S526_GPCT_MODE_PR_SELECT(1) #define S526_GPCT_CTRL_REG(x) (0x18 + ((x) * 8)) #define S526_EEPROM_DATA_REG 0x32 #define S526_EEPROM_CTRL_REG 0x34 @@ -92,41 +147,6 @@ #define S526_EEPROM_CTRL_READ S526_EEPROM_CTRL(2) #define S526_EEPROM_CTRL_START BIT(0) -struct counter_mode_register_t { -#if defined(__LITTLE_ENDIAN_BITFIELD) - unsigned short coutSource:1; - unsigned short coutPolarity:1; - unsigned short autoLoadResetRcap:3; - unsigned short hwCtEnableSource:2; - unsigned short ctEnableCtrl:2; - unsigned short clockSource:2; - unsigned short countDir:1; - unsigned short countDirCtrl:1; - unsigned short outputRegLatchCtrl:1; - unsigned short preloadRegSel:1; - unsigned short reserved:1; - #elif defined(__BIG_ENDIAN_BITFIELD) - unsigned short reserved:1; - unsigned short preloadRegSel:1; - unsigned short outputRegLatchCtrl:1; - unsigned short countDirCtrl:1; - unsigned short countDir:1; - unsigned short clockSource:2; - unsigned short ctEnableCtrl:2; - unsigned short hwCtEnableSource:2; - unsigned short autoLoadResetRcap:3; - unsigned short coutPolarity:1; - unsigned short coutSource:1; -#else -#error Unknown bit field order -#endif -}; - -union cmReg { - struct counter_mode_register_t reg; - unsigned short value; -}; - struct s526_private { unsigned int gpct_config[4]; unsigned short ai_ctrl; @@ -174,7 +194,6 @@ static int s526_gpct_insn_config(struct comedi_device *dev, struct s526_private *devpriv = dev->private; unsigned int chan = CR_CHAN(insn->chanspec); unsigned int val; - union cmReg cmReg; /* * Check what type of Counter the user requested @@ -192,28 +211,29 @@ static int s526_gpct_insn_config(struct comedi_device *dev, #if 1 /* Set Counter Mode Register */ - cmReg.value = data[1] & 0xffff; - outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan)); + val = data[1] & 0xffff; + outw(val, dev->iobase + S526_GPCT_MODE_REG(chan)); /* Reset the counter if it is software preload */ - if (cmReg.reg.autoLoadResetRcap == 0) { + if ((val & S526_GPCT_MODE_AUTOLOAD_MASK) == + S526_GPCT_MODE_AUTOLOAD_NONE) { /* Reset the counter */ outw(0x8000, dev->iobase + S526_GPCT_CTRL_REG(chan)); - /* Load the counter from PR0 + /* + * Load the counter from PR0 * outw(0x4000, dev->iobase + S526_GPCT_CTRL_REG(chan)); */ } #else - /* 0 quadrature, 1 software control */ - cmReg.reg.countDirCtrl = 0; + val = S526_GPCT_MODE_CTDIR_CTRL_QUAD; /* data[1] contains GPCT_X1, GPCT_X2 or GPCT_X4 */ if (data[1] == GPCT_X2) - cmReg.reg.clockSource = 1; + val |= S526_GPCT_MODE_CLK_SRC_QUADX2; else if (data[1] == GPCT_X4) - cmReg.reg.clockSource = 2; + val |= S526_GPCT_MODE_CLK_SRC_QUADX4; else - cmReg.reg.clockSource = 0; + val |= S526_GPCT_MODE_CLK_SRC_QUADX1; /* When to take into account the indexpulse: */ /* @@ -224,13 +244,14 @@ static int s526_gpct_insn_config(struct comedi_device *dev, * } */ /* Take into account the index pulse? */ - if (data[3] == GPCT_RESET_COUNTER_ON_INDEX) + if (data[3] == GPCT_RESET_COUNTER_ON_INDEX) { /* Auto load with INDEX^ */ - cmReg.reg.autoLoadResetRcap = 4; + val |= S526_GPCT_MODE_AUTOLOAD_IXRISE; + } /* Set Counter Mode Register */ - cmReg.value = data[1] & 0xffff; - outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan)); + val = data[1] & 0xffff; + outw(val, dev->iobase + S526_GPCT_MODE_REG(chan)); /* Load the pre-load register */ s526_gpct_write(dev, chan, data[2]); @@ -241,7 +262,8 @@ static int s526_gpct_insn_config(struct comedi_device *dev, dev->iobase + S526_GPCT_CTRL_REG(chan)); /* Reset the counter if it is software preload */ - if (cmReg.reg.autoLoadResetRcap == 0) { + if ((val & S526_GPCT_MODE_AUTOLOAD_MASK) == + S526_GPCT_MODE_AUTOLOAD_NONE) { /* Reset the counter */ outw(0x8000, dev->iobase + S526_GPCT_CTRL_REG(chan)); /* Load the counter from PR0 */ @@ -261,17 +283,21 @@ static int s526_gpct_insn_config(struct comedi_device *dev, devpriv->gpct_config[chan] = data[0]; /* Set Counter Mode Register */ - cmReg.value = data[1] & 0xffff; - cmReg.reg.preloadRegSel = 0; /* PR0 */ - outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan)); + val = data[1] & 0xffff; + /* Select PR0 */ + val &= ~S526_GPCT_MODE_PR_SELECT_MASK; + val |= S526_GPCT_MODE_PR_SELECT_PR0; + outw(val, dev->iobase + S526_GPCT_MODE_REG(chan)); /* Load the pre-load register 0 */ s526_gpct_write(dev, chan, data[2]); /* Set Counter Mode Register */ - cmReg.value = data[1] & 0xffff; - cmReg.reg.preloadRegSel = 1; /* PR1 */ - outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan)); + val = data[1] & 0xffff; + /* Select PR1 */ + val &= ~S526_GPCT_MODE_PR_SELECT_MASK; + val |= S526_GPCT_MODE_PR_SELECT_PR1; + outw(val, dev->iobase + S526_GPCT_MODE_REG(chan)); /* Load the pre-load register 1 */ s526_gpct_write(dev, chan, data[3]); @@ -294,17 +320,21 @@ static int s526_gpct_insn_config(struct comedi_device *dev, devpriv->gpct_config[chan] = data[0]; /* Set Counter Mode Register */ - cmReg.value = data[1] & 0xffff; - cmReg.reg.preloadRegSel = 0; /* PR0 */ - outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan)); + val = data[1] & 0xffff; + /* Select PR0 */ + val &= ~S526_GPCT_MODE_PR_SELECT_MASK; + val |= S526_GPCT_MODE_PR_SELECT_PR0; + outw(val, dev->iobase + S526_GPCT_MODE_REG(chan)); /* Load the pre-load register 0 */ s526_gpct_write(dev, chan, data[2]); /* Set Counter Mode Register */ - cmReg.value = data[1] & 0xffff; - cmReg.reg.preloadRegSel = 1; /* PR1 */ - outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan)); + val = data[1] & 0xffff; + /* Select PR1 */ + val &= ~S526_GPCT_MODE_PR_SELECT_MASK; + val |= S526_GPCT_MODE_PR_SELECT_PR1; + outw(val, dev->iobase + S526_GPCT_MODE_REG(chan)); /* Load the pre-load register 1 */ s526_gpct_write(dev, chan, data[3]); -- GitLab From e5417e49965a47f690fe33ab5b27011c86ef89b5 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 19 Nov 2015 14:49:08 +0000 Subject: [PATCH 1956/2855] staging: comedi: s526: add macros for counter control reg values The driver writes a couple of literal values to the counter control/status register, 0x8000 to reset the counter, and 0x4000 to load the counter from preload register 0. Add a bunch of macros to define these values and other values for the register, based on the Sensoray 526 manual. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s526.c | 41 ++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index a8165dfe6f5f8..c80527db9c194 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -139,7 +139,36 @@ #define S526_GPCT_MODE_PR_SELECT_MASK S526_GPCT_MODE_PR_SELECT(0x1) #define S526_GPCT_MODE_PR_SELECT_PR0 S526_GPCT_MODE_PR_SELECT(0) #define S526_GPCT_MODE_PR_SELECT_PR1 S526_GPCT_MODE_PR_SELECT(1) +/* Control/Status - R = readable, W = writeable, C = write 1 to clear */ #define S526_GPCT_CTRL_REG(x) (0x18 + ((x) * 8)) +#define S526_GPCT_CTRL_EV_STATUS(x) ((x) << 0) /* RC */ +#define S526_GPCT_CTRL_EV_STATUS_MASK S526_GPCT_EV_STATUS(0xf) +#define S526_GPCT_CTRL_EV_STATUS_NONE S526_GPCT_EV_STATUS(0) +/* these 4 bits can be OR'ed */ +#define S526_GPCT_CTRL_EV_STATUS_ECAP S526_GPCT_EV_STATUS(0x1) +#define S526_GPCT_CTRL_EV_STATUS_ICAPN S526_GPCT_EV_STATUS(0x2) +#define S526_GPCT_CTRL_EV_STATUS_ICAPP S526_GPCT_EV_STATUS(0x4) +#define S526_GPCT_CTRL_EV_STATUS_RCAP S526_GPCT_EV_STATUS(0x8) +#define S526_GPCT_CTRL_COUT_STATUS BIT(4) /* R */ +#define S526_GPCT_CTRL_INDEX_STATUS BIT(5) /* R */ +#define S525_GPCT_CTRL_INTEN(x) ((x) << 6) /* W */ +#define S525_GPCT_CTRL_INTEN_MASK S526_GPCT_CTRL_INTEN(0xf) +#define S525_GPCT_CTRL_INTEN_NONE S526_GPCT_CTRL_INTEN(0) +/* these 4 bits can be OR'ed */ +#define S525_GPCT_CTRL_INTEN_ERROR S526_GPCT_CTRL_INTEN(0x1) +#define S525_GPCT_CTRL_INTEN_IXFALL S526_GPCT_CTRL_INTEN(0x2) +#define S525_GPCT_CTRL_INTEN_IXRISE S526_GPCT_CTRL_INTEN(0x4) +#define S525_GPCT_CTRL_INTEN_RO S526_GPCT_CTRL_INTEN(0x8) +#define S525_GPCT_CTRL_LATCH_SEL(x) ((x) << 10) /* W */ +#define S525_GPCT_CTRL_LATCH_SEL_MASK S526_GPCT_CTRL_LATCH_SEL(0x7) +#define S525_GPCT_CTRL_LATCH_SEL_NONE S526_GPCT_CTRL_LATCH_SEL(0) +/* these 3 bits can be OR'ed */ +#define S525_GPCT_CTRL_LATCH_SEL_IXFALL S526_GPCT_CTRL_LATCH_SEL(0x1) +#define S525_GPCT_CTRL_LATCH_SEL_IXRISE S526_GPCT_CTRL_LATCH_SEL(0x2) +#define S525_GPCT_CTRL_LATCH_SEL_ITIMER S526_GPCT_CTRL_LATCH_SEL(0x4) +#define S525_GPCT_CTRL_CT_ARM BIT(13) /* W */ +#define S525_GPCT_CTRL_CT_LOAD BIT(14) /* W */ +#define S526_GPCT_CTRL_CT_RESET BIT(15) /* W */ #define S526_EEPROM_DATA_REG 0x32 #define S526_EEPROM_CTRL_REG 0x34 #define S526_EEPROM_CTRL_ADDR(x) (((x) & 0x3f) << 3) @@ -218,10 +247,12 @@ static int s526_gpct_insn_config(struct comedi_device *dev, if ((val & S526_GPCT_MODE_AUTOLOAD_MASK) == S526_GPCT_MODE_AUTOLOAD_NONE) { /* Reset the counter */ - outw(0x8000, dev->iobase + S526_GPCT_CTRL_REG(chan)); + outw(S526_GPCT_CTRL_CT_RESET, + dev->iobase + S526_GPCT_CTRL_REG(chan)); /* * Load the counter from PR0 - * outw(0x4000, dev->iobase + S526_GPCT_CTRL_REG(chan)); + * outw(S526_GPCT_CTRL_CT_LOAD, + * dev->iobase + S526_GPCT_CTRL_REG(chan)); */ } #else @@ -265,9 +296,11 @@ static int s526_gpct_insn_config(struct comedi_device *dev, if ((val & S526_GPCT_MODE_AUTOLOAD_MASK) == S526_GPCT_MODE_AUTOLOAD_NONE) { /* Reset the counter */ - outw(0x8000, dev->iobase + S526_GPCT_CTRL_REG(chan)); + outw(S526_GPCT_CTRL_CT_RESET, + dev->iobase + S526_GPCT_CTRL_REG(chan)); /* Load the counter from PR0 */ - outw(0x4000, dev->iobase + S526_GPCT_CTRL_REG(chan)); + outw(S526_GPCT_CTRL_CT_LOAD, + dev->iobase + S526_GPCT_CTRL_REG(chan)); } #endif break; -- GitLab From 2acc980bc623bd8cf3959e85e01fe98c6ede74f5 Mon Sep 17 00:00:00 2001 From: Jitendra Kumar Khasdev Date: Tue, 24 Nov 2015 17:52:28 +0530 Subject: [PATCH 1957/2855] staging: comedi: comedilib.h: Coding style warning fix for block comments This patch is to comedilib.h file that fixes up following warnings reported by checkpatch.pl : I) Block comments use * on subsequent lines. Apart from it I have remove header file path by base file name as suggested by community. Signed-off-by: Jitendra Kumar Khasdev Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedilib.h | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/staging/comedi/comedilib.h b/drivers/staging/comedi/comedilib.h index 56baf852ecf5d..f9b56396e161c 100644 --- a/drivers/staging/comedi/comedilib.h +++ b/drivers/staging/comedi/comedilib.h @@ -1,20 +1,20 @@ /* - linux/include/comedilib.h - header file for kcomedilib - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 1998-2001 David A. Schleef - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ + * comedilib.h + * Header file for kcomedilib + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 1998-2001 David A. Schleef + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #ifndef _LINUX_COMEDILIB_H #define _LINUX_COMEDILIB_H -- GitLab From e554840c947c2d25be24c790cf8db9579b2dfb4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20K=C3=B6nig?= Date: Thu, 17 Dec 2015 16:53:10 +0100 Subject: [PATCH 1958/2855] STAGING: COMEDI: Fixed format of comments in plx9080.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes the format of comments in plx9080.h. Signed-off-by: Moritz König Signed-off-by: Fabian Lang Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/plx9080.h | 122 +++++++++++++++-------- 1 file changed, 78 insertions(+), 44 deletions(-) diff --git a/drivers/staging/comedi/drivers/plx9080.h b/drivers/staging/comedi/drivers/plx9080.h index 25706531b8854..8d3caf6b4e866 100644 --- a/drivers/staging/comedi/drivers/plx9080.h +++ b/drivers/staging/comedi/drivers/plx9080.h @@ -1,4 +1,5 @@ -/* plx9080.h +/* + * plx9080.h * * Copyright (C) 2002,2003 Frank Mori Hess * @@ -33,8 +34,10 @@ struct plx_dma_desc { __le32 local_start_addr; /* transfer_size is in bytes, only first 23 bits of register are used */ __le32 transfer_size; - /* address of next descriptor (quad word aligned), plus some - * additional bits (see PLX_DMA0_DESCRIPTOR_REG) */ + /* + * address of next descriptor (quad word aligned), plus some + * additional bits (see PLX_DMA0_DESCRIPTOR_REG) + */ __le32 next; }; @@ -46,23 +49,31 @@ struct plx_dma_desc { ** **********************************************************************/ -#define PLX_LAS0RNG_REG 0x0000 /* L, Local Addr Space 0 Range Register */ -#define PLX_LAS1RNG_REG 0x00f0 /* L, Local Addr Space 1 Range Register */ +/* L, Local Addr Space 0 Range Register */ +#define PLX_LAS0RNG_REG 0x0000 +/* L, Local Addr Space 1 Range Register */ +#define PLX_LAS1RNG_REG 0x00f0 #define LRNG_IO 0x00000001 /* Map to: 1=I/O, 0=Mem */ #define LRNG_ANY32 0x00000000 /* Locate anywhere in 32 bit */ #define LRNG_LT1MB 0x00000002 /* Locate in 1st meg */ #define LRNG_ANY64 0x00000004 /* Locate anywhere in 64 bit */ -#define LRNG_MEM_MASK 0xfffffff0 /* bits that specify range for memory io */ -#define LRNG_IO_MASK 0xfffffffa /* bits that specify range for normal io */ - -#define PLX_LAS0MAP_REG 0x0004 /* L, Local Addr Space 0 Remap Register */ -#define PLX_LAS1MAP_REG 0x00f4 /* L, Local Addr Space 1 Remap Register */ +/* bits that specify range for memory io */ +#define LRNG_MEM_MASK 0xfffffff0 +/* bits that specify range for normal io */ +#define LRNG_IO_MASK 0xfffffffa +/* L, Local Addr Space 0 Remap Register */ +#define PLX_LAS0MAP_REG 0x0004 +/* L, Local Addr Space 1 Remap Register */ +#define PLX_LAS1MAP_REG 0x00f4 #define LMAP_EN 0x00000001 /* Enable slave decode */ -#define LMAP_MEM_MASK 0xfffffff0 /* bits that specify decode for memory io */ -#define LMAP_IO_MASK 0xfffffffa /* bits that specify decode bits for normal io */ +/* bits that specify decode for memory io */ +#define LMAP_MEM_MASK 0xfffffff0 +/* bits that specify decode bits for normal io */ +#define LMAP_IO_MASK 0xfffffffa -/* Mode/Arbitration Register. -*/ +/* + * Mode/Arbitration Register. + */ #define PLX_MARB_REG 0x8 /* L, Local Arbitration Register */ #define PLX_DMAARB_REG 0xac enum marb_bits { @@ -72,35 +83,45 @@ enum marb_bits { MARB_LPEN = 0x00020000, /* Pause Timer Enable */ MARB_BREQ = 0x00040000, /* Local Bus BREQ Enable */ MARB_DMA_PRIORITY_MASK = 0x00180000, - MARB_LBDS_GIVE_UP_BUS_MODE = 0x00200000, /* local bus direct slave give up bus mode */ - MARB_DS_LLOCK_ENABLE = 0x00400000, /* direct slave LLOCKo# enable */ + /* local bus direct slave give up bus mode */ + MARB_LBDS_GIVE_UP_BUS_MODE = 0x00200000, + /* direct slave LLOCKo# enable */ + MARB_DS_LLOCK_ENABLE = 0x00400000, MARB_PCI_REQUEST_MODE = 0x00800000, MARB_PCIv21_MODE = 0x01000000, /* pci specification v2.1 mode */ MARB_PCI_READ_NO_WRITE_MODE = 0x02000000, MARB_PCI_READ_WITH_WRITE_FLUSH_MODE = 0x04000000, - MARB_GATE_TIMER_WITH_BREQ = 0x08000000, /* gate local bus latency timer with BREQ */ + /* gate local bus latency timer with BREQ */ + MARB_GATE_TIMER_WITH_BREQ = 0x08000000, MARB_PCI_READ_NO_FLUSH_MODE = 0x10000000, MARB_USE_SUBSYSTEM_IDS = 0x20000000, }; #define PLX_BIGEND_REG 0xc enum bigend_bits { - BIGEND_CONFIG = 0x1, /* use big endian ordering for configuration register accesses */ + /* use big endian ordering for configuration register accesses */ + BIGEND_CONFIG = 0x1, BIGEND_DIRECT_MASTER = 0x2, BIGEND_DIRECT_SLAVE_LOCAL0 = 0x4, BIGEND_ROM = 0x8, - BIGEND_BYTE_LANE = 0x10, /* use byte lane consisting of most significant bits instead of least significant */ + /* + * use byte lane consisting of most significant bits instead of + * least significant + */ + BIGEND_BYTE_LANE = 0x10, BIGEND_DIRECT_SLAVE_LOCAL1 = 0x20, BIGEND_DMA1 = 0x40, BIGEND_DMA0 = 0x80, }; -/* Note: The Expansion ROM stuff is only relevant to the PC environment. +/* +** Note: The Expansion ROM stuff is only relevant to the PC environment. ** This expansion ROM code is executed by the host CPU at boot time. ** For this reason no bit definitions are provided here. -*/ + */ #define PLX_ROMRNG_REG 0x0010 /* L, Expn ROM Space Range Register */ -#define PLX_ROMMAP_REG 0x0014 /* L, Local Addr Space Range Register */ +/* L, Local Addr Space Range Register */ +#define PLX_ROMMAP_REG 0x0014 #define PLX_REGION0_REG 0x0018 /* L, Local Bus Region 0 Descriptor */ #define RGN_WIDTH 0x00000002 /* Local bus width bits */ @@ -190,7 +211,8 @@ enum bigend_bits { #define ICS_TA_DMA0 0x02000000 /* Target Abort - DMA #0 */ #define ICS_TA_DMA1 0x04000000 /* Target Abort - DMA #1 */ #define ICS_TA_RA 0x08000000 /* Target Abort - Retry Timeout */ -#define ICS_MBIA(x) (0x10000000 << ((x) & 0x3)) /* mailbox x is active */ +/* mailbox x is active */ +#define ICS_MBIA(x) (0x10000000 << ((x) & 0x3)) #define PLX_CONTROL_REG 0x006C /* L, EEPROM Cntl & PCI Cmd Codes */ #define CTL_RDMA 0x0000000E /* DMA Read Command */ @@ -221,28 +243,38 @@ enum bigend_bits { #define PLX_EN_BTERM_BIT 0x80 /* enable BTERM# input */ #define PLX_DMA_LOCAL_BURST_EN_BIT 0x100 /* enable local burst mode */ #define PLX_EN_CHAIN_BIT 0x200 /* enables chaining */ -#define PLX_EN_DMA_DONE_INTR_BIT 0x400 /* enables interrupt on dma done */ -#define PLX_LOCAL_ADDR_CONST_BIT 0x800 /* hold local address constant (don't increment) */ -#define PLX_DEMAND_MODE_BIT 0x1000 /* enables demand-mode for dma transfer */ +/* enables interrupt on dma done */ +#define PLX_EN_DMA_DONE_INTR_BIT 0x400 +/* hold local address constant (don't increment) */ +#define PLX_LOCAL_ADDR_CONST_BIT 0x800 +/* enables demand-mode for dma transfer */ +#define PLX_DEMAND_MODE_BIT 0x1000 #define PLX_EOT_ENABLE_BIT 0x4000 #define PLX_STOP_MODE_BIT 0x8000 -#define PLX_DMA_INTR_PCI_BIT 0x20000 /* routes dma interrupt to pci bus (instead of local bus) */ +/* routes dma interrupt to pci bus (instead of local bus) */ +#define PLX_DMA_INTR_PCI_BIT 0x20000 -#define PLX_DMA0_PCI_ADDRESS_REG 0x84 /* pci address that dma transfers start at */ +/* pci address that dma transfers start at */ +#define PLX_DMA0_PCI_ADDRESS_REG 0x84 #define PLX_DMA1_PCI_ADDRESS_REG 0x98 -#define PLX_DMA0_LOCAL_ADDRESS_REG 0x88 /* local address that dma transfers start at */ +/* local address that dma transfers start at */ +#define PLX_DMA0_LOCAL_ADDRESS_REG 0x88 #define PLX_DMA1_LOCAL_ADDRESS_REG 0x9c -#define PLX_DMA0_TRANSFER_SIZE_REG 0x8c /* number of bytes to transfer (first 23 bits) */ +/* number of bytes to transfer (first 23 bits) */ +#define PLX_DMA0_TRANSFER_SIZE_REG 0x8c #define PLX_DMA1_TRANSFER_SIZE_REG 0xa0 #define PLX_DMA0_DESCRIPTOR_REG 0x90 /* descriptor pointer register */ #define PLX_DMA1_DESCRIPTOR_REG 0xa4 -#define PLX_DESC_IN_PCI_BIT 0x1 /* descriptor is located in pci space (not local space) */ +/* descriptor is located in pci space (not local space) */ +#define PLX_DESC_IN_PCI_BIT 0x1 #define PLX_END_OF_CHAIN_BIT 0x2 /* end of chain bit */ -#define PLX_INTR_TERM_COUNT 0x4 /* interrupt when this descriptor's transfer is finished */ -#define PLX_XFER_LOCAL_TO_PCI 0x8 /* transfer from local to pci bus (not pci to local) */ +/* interrupt when this descriptor's transfer is finished */ +#define PLX_INTR_TERM_COUNT 0x4 +/* transfer from local to pci bus (not pci to local) */ +#define PLX_XFER_LOCAL_TO_PCI 0x8 #define PLX_DMA0_CS_REG 0xa8 /* command status register */ #define PLX_DMA1_CS_REG 0xa9 @@ -288,10 +320,11 @@ enum bigend_bits { #define MBX_STS_PCIRESET 0x00000100 /* Host issued PCI reset request */ #define MBX_STS_BUSY 0x00000080 /* PUTS is in progress */ #define MBX_STS_ERROR 0x00000040 /* PUTS has failed */ -#define MBX_STS_RESERVED 0x000000c0 /* Undefined -> status in transition. - We are in process of changing - bits; we SET Error bit before - RESET of Busy bit */ +/* + * Undefined -> status in transition. We are in process of changing bits; + * we SET Error bit before RESET of Busy bit + */ +#define MBX_STS_RESERVED 0x000000c0 #define MBX_RESERVED_5 0x00000020 /* FYI: reserved/unused bit */ #define MBX_RESERVED_4 0x00000010 /* FYI: reserved/unused bit */ @@ -320,12 +353,12 @@ enum bigend_bits { #define MBX_CMD_BSWAP_0 0x8c000000 /* use scheme 0 */ #define MBX_CMD_BSWAP_1 0x8c000001 /* use scheme 1 */ -#define MBX_CMD_SETHMS 0x8d000000 /* setup host memory access window - size */ -#define MBX_CMD_SETHBA 0x8e000000 /* setup host memory access base - address */ -#define MBX_CMD_MGO 0x8f000000 /* perform memory setup and continue - (IE. Done) */ +/* setup host memory access window size */ +#define MBX_CMD_SETHMS 0x8d000000 +/* setup host memory access base address */ +#define MBX_CMD_SETHBA 0x8e000000 +/* perform memory setup and continue (IE. Done) */ +#define MBX_CMD_MGO 0x8f000000 #define MBX_CMD_NOOP 0xFF000000 /* dummy, illegal command */ /*****************************************/ @@ -348,7 +381,8 @@ enum bigend_bits { /***************************************/ #define MBX_BTYPE_MASK 0x0000ffff /* PUTS Board Type Register */ -#define MBX_BTYPE_FAMILY_MASK 0x0000ff00 /* PUTS Board Family Register */ +/* PUTS Board Family Register */ +#define MBX_BTYPE_FAMILY_MASK 0x0000ff00 #define MBX_BTYPE_SUBTYPE_MASK 0x000000ff /* PUTS Board Subtype */ #define MBX_BTYPE_PLX9060 0x00000100 /* PLX family type */ -- GitLab From e0bcce6b3a6a8c2ac8f5b8be8fb7be0d4e682072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20K=C3=B6nig?= Date: Thu, 17 Dec 2015 16:53:11 +0100 Subject: [PATCH 1959/2855] STAGING: COMEDI: Added spaces around binary operators in plx9080.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds spaces around binary operators in plx9080.h. Signed-off-by: Moritz König Signed-off-by: Fabian Lang Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/plx9080.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/plx9080.h b/drivers/staging/comedi/drivers/plx9080.h index 8d3caf6b4e866..c4920f8654d0e 100644 --- a/drivers/staging/comedi/drivers/plx9080.h +++ b/drivers/staging/comedi/drivers/plx9080.h @@ -412,7 +412,7 @@ enum bigend_bits { /* system allocates this many bytes for address mapping mailbox space */ #define MBX_ADDR_SPACE_360 0x80 /* wanXL100s/200/400 */ -#define MBX_ADDR_MASK_360 (MBX_ADDR_SPACE_360-1) +#define MBX_ADDR_MASK_360 (MBX_ADDR_SPACE_360 - 1) static inline int plx9080_abort_dma(void __iomem *iobase, unsigned int channel) { -- GitLab From f6e9b914332f5c60249a911c687eea1aa0cd37d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20K=C3=B6nig?= Date: Thu, 17 Dec 2015 16:53:12 +0100 Subject: [PATCH 1960/2855] STAGING: COMEDI: Using kernel types in plx9080.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch makes plx9080.h use kernel types. Signed-off-by: Moritz König Signed-off-by: Fabian Lang Reviewed-by: Ian Abbott Acked-by: Moritz Fischer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/plx9080.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/plx9080.h b/drivers/staging/comedi/drivers/plx9080.h index c4920f8654d0e..f5cd6d5004bdd 100644 --- a/drivers/staging/comedi/drivers/plx9080.h +++ b/drivers/staging/comedi/drivers/plx9080.h @@ -417,7 +417,7 @@ enum bigend_bits { static inline int plx9080_abort_dma(void __iomem *iobase, unsigned int channel) { void __iomem *dma_cs_addr; - uint8_t dma_status; + u8 dma_status; const int timeout = 10000; unsigned int i; -- GitLab From e7cfb3907d1c88cea8977fa267149cb2297fb07e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 18 Nov 2015 22:02:39 +0100 Subject: [PATCH 1961/2855] staging/emxx_udc: fix 64-bit warnings ARCH_SHMOBILE is coming to arm64, which creates new warnings in allmodconfig: drivers/staging/emxx_udc/emxx_udc.c: In function '_nbu2ss_out_dma': drivers/staging/emxx_udc/emxx_udc.c:843:45: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] _nbu2ss_writel(&preg->EP_DCR[num].EP_TADR, (u32)pBuffer); This is clearly a mistake from confusing a dma_addr_t with a pointer, so the fix is to use the correct types in two places. The third warning of this kind is a check for an unaligned pointer, which should be done by casting the pointer to uintptr_t, not int. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/emxx_udc/emxx_udc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index 4e6c16af40fc5..c168845cbb91e 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -823,7 +823,7 @@ static int _nbu2ss_out_dma( u32 length ) { - u8 *pBuffer; + dma_addr_t pBuffer; u32 mpkt; u32 lmpkt; u32 dmacnt; @@ -836,7 +836,7 @@ static int _nbu2ss_out_dma( return 1; /* DMA is forwarded */ req->dma_flag = TRUE; - pBuffer = (u8 *)req->req.dma; + pBuffer = req->req.dma; pBuffer += req->req.actual; /* DMA Address */ @@ -1034,7 +1034,7 @@ static int _nbu2ss_in_dma( u32 length ) { - u8 *pBuffer; + dma_addr_t pBuffer; u32 mpkt; /* MaxPacketSize */ u32 lmpkt; /* Last Packet Data Size */ u32 dmacnt; /* IN Data Size */ @@ -1080,7 +1080,7 @@ static int _nbu2ss_in_dma( _nbu2ss_writel(&preg->EP_DCR[num].EP_DCR2, data); /* Address setting */ - pBuffer = (u8 *)req->req.dma; + pBuffer = req->req.dma; pBuffer += req->req.actual; _nbu2ss_writel(&preg->EP_DCR[num].EP_TADR, (u32)pBuffer); @@ -2728,7 +2728,7 @@ static int nbu2ss_ep_queue( spin_lock_irqsave(&udc->lock, flags); #ifdef USE_DMA - if ((u32)req->req.buf & 0x3) + if ((uintptr_t)req->req.buf & 0x3) req->unaligned = TRUE; else req->unaligned = FALSE; -- GitLab From e59ac747946693b1356d576f843ce8ac1e283927 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Mon, 16 Nov 2015 21:54:46 +0800 Subject: [PATCH 1962/2855] staging: emxx_udc: use list_first_entry_or_null() Simplify the code with list_first_entry_or_null(). Signed-off-by: Geliang Tang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/emxx_udc/emxx_udc.c | 30 +++++------------------------ 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index c168845cbb91e..beb9411658ba9 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -1285,11 +1285,7 @@ static void _nbu2ss_restert_transfer(struct nbu2ss_ep *ep) bool bflag = FALSE; struct nbu2ss_req *req; - if (list_empty(&ep->queue)) - req = NULL; - else - req = list_entry(ep->queue.next, struct nbu2ss_req, queue); - + req = list_first_entry_or_null(&ep->queue, struct nbu2ss_req, queue); if (!req) return; @@ -1784,11 +1780,7 @@ static inline int _nbu2ss_ep0_in_data_stage(struct nbu2ss_udc *udc) struct nbu2ss_req *req; struct nbu2ss_ep *ep = &udc->ep[0]; - if (list_empty(&ep->queue)) - req = NULL; - else - req = list_entry(ep->queue.next, struct nbu2ss_req, queue); - + req = list_first_entry_or_null(&ep->queue, struct nbu2ss_req, queue); if (!req) req = &udc->ep0_req; @@ -1811,11 +1803,7 @@ static inline int _nbu2ss_ep0_out_data_stage(struct nbu2ss_udc *udc) struct nbu2ss_req *req; struct nbu2ss_ep *ep = &udc->ep[0]; - if (list_empty(&ep->queue)) - req = NULL; - else - req = list_entry(ep->queue.next, struct nbu2ss_req, queue); - + req = list_first_entry_or_null(&ep->queue, struct nbu2ss_req, queue); if (!req) req = &udc->ep0_req; @@ -1838,11 +1826,7 @@ static inline int _nbu2ss_ep0_status_stage(struct nbu2ss_udc *udc) struct nbu2ss_req *req; struct nbu2ss_ep *ep = &udc->ep[0]; - if (list_empty(&ep->queue)) - req = NULL; - else - req = list_entry(ep->queue.next, struct nbu2ss_req, queue); - + req = list_first_entry_or_null(&ep->queue, struct nbu2ss_req, queue); if (!req) { req = &udc->ep0_req; if (req->req.complete) @@ -2145,11 +2129,7 @@ static inline void _nbu2ss_epn_int(struct nbu2ss_udc *udc, u32 epnum) /* Interrupt Clear */ _nbu2ss_writel(&udc->p_regs->EP_REGS[num].EP_STATUS, ~(u32)status); - if (list_empty(&ep->queue)) - req = NULL; - else - req = list_entry(ep->queue.next, struct nbu2ss_req, queue); - + req = list_first_entry_or_null(&ep->queue, struct nbu2ss_req, queue); if (!req) { /* pr_warn("=== %s(%d) req == NULL\n", __func__, epnum); */ return; -- GitLab From f5cb5304eb26d307c9b30269fb0e007e0b262b7d Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:11:52 -0500 Subject: [PATCH 1963/2855] lpfc: Fix FCF Infinite loop in lpfc_sli4_fcf_rr_next_index_get. Fix FCF Infinite loop in lpfc_sli4_fcf_rr_next_index_get. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_sli.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index f9585cdd89333..6aae828208e26 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -16173,7 +16173,7 @@ fail_fcf_read: } /** - * lpfc_check_next_fcf_pri + * lpfc_check_next_fcf_pri_level * phba pointer to the lpfc_hba struct for this port. * This routine is called from the lpfc_sli4_fcf_rr_next_index_get * routine when the rr_bmask is empty. The FCF indecies are put into the @@ -16329,8 +16329,12 @@ next_priority: if (next_fcf_index < LPFC_SLI4_FCF_TBL_INDX_MAX && phba->fcf.fcf_pri[next_fcf_index].fcf_rec.flag & - LPFC_FCF_FLOGI_FAILED) + LPFC_FCF_FLOGI_FAILED) { + if (list_is_singular(&phba->fcf.fcf_pri_list)) + return LPFC_FCOE_FCF_NEXT_NONE; + goto next_priority; + } lpfc_printf_log(phba, KERN_INFO, LOG_FIP, "2845 Get next roundrobin failover FCF (x%x)\n", -- GitLab From d6de08cc46269899988b4f40acc7337279693d4b Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:11:53 -0500 Subject: [PATCH 1964/2855] lpfc: Fix the FLOGI discovery logic to comply with T11 standards Fix the FLOGI discovery logic to comply with T11 standards We weren't properly setting fabric parameters, such as R_A_TOV and E_D_TOV, when we registered the vfi object in default configs and pt2pt configs. Revise to now pass service params with the values to the firmware and ensure they are reset on link bounce. Required reworking the call sequence in the discovery threads. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_crtn.h | 1 + drivers/scsi/lpfc/lpfc_els.c | 342 +++++++++++++---------------- drivers/scsi/lpfc/lpfc_hbadisc.c | 12 +- drivers/scsi/lpfc/lpfc_nportdisc.c | 124 ++++++----- 4 files changed, 240 insertions(+), 239 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index b0e6fe46448d0..80d3c740a8a84 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -72,6 +72,7 @@ void lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *); void lpfc_retry_pport_discovery(struct lpfc_hba *); void lpfc_release_rpi(struct lpfc_hba *, struct lpfc_vport *, uint16_t); +void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index b6fa257ea3e0b..f6dd15b22383c 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -455,9 +455,9 @@ int lpfc_issue_reg_vfi(struct lpfc_vport *vport) { struct lpfc_hba *phba = vport->phba; - LPFC_MBOXQ_t *mboxq; + LPFC_MBOXQ_t *mboxq = NULL; struct lpfc_nodelist *ndlp; - struct lpfc_dmabuf *dmabuf; + struct lpfc_dmabuf *dmabuf = NULL; int rc = 0; /* move forward in case of SLI4 FC port loopback test and pt2pt mode */ @@ -471,25 +471,33 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport) } } - dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); - if (!dmabuf) { + mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mboxq) { rc = -ENOMEM; goto fail; } - dmabuf->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &dmabuf->phys); - if (!dmabuf->virt) { - rc = -ENOMEM; - goto fail_free_dmabuf; - } - mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (!mboxq) { - rc = -ENOMEM; - goto fail_free_coherent; + /* Supply CSP's only if we are fabric connect or pt-to-pt connect */ + if ((vport->fc_flag & FC_FABRIC) || (vport->fc_flag & FC_PT2PT)) { + dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); + if (!dmabuf) { + rc = -ENOMEM; + goto fail; + } + dmabuf->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &dmabuf->phys); + if (!dmabuf->virt) { + rc = -ENOMEM; + goto fail; + } + memcpy(dmabuf->virt, &phba->fc_fabparam, + sizeof(struct serv_parm)); } + vport->port_state = LPFC_FABRIC_CFG_LINK; - memcpy(dmabuf->virt, &phba->fc_fabparam, sizeof(vport->fc_sparam)); - lpfc_reg_vfi(mboxq, vport, dmabuf->phys); + if (dmabuf) + lpfc_reg_vfi(mboxq, vport, dmabuf->phys); + else + lpfc_reg_vfi(mboxq, vport, 0); mboxq->mbox_cmpl = lpfc_mbx_cmpl_reg_vfi; mboxq->vport = vport; @@ -497,17 +505,19 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport) rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); if (rc == MBX_NOT_FINISHED) { rc = -ENXIO; - goto fail_free_mbox; + goto fail; } return 0; -fail_free_mbox: - mempool_free(mboxq, phba->mbox_mem_pool); -fail_free_coherent: - lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys); -fail_free_dmabuf: - kfree(dmabuf); fail: + if (mboxq) + mempool_free(mboxq, phba->mbox_mem_pool); + if (dmabuf) { + if (dmabuf->virt) + lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys); + kfree(dmabuf); + } + lpfc_vport_set_state(vport, FC_VPORT_FAILED); lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, "0289 Issue Register VFI failed: Err %d\n", rc); @@ -711,9 +721,10 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, * For FC we need to do some special processing because of the SLI * Port's default settings of the Common Service Parameters. */ - if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC) { + if ((phba->sli_rev == LPFC_SLI_REV4) && + (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC)) { /* If physical FC port changed, unreg VFI and ALL VPIs / RPIs */ - if ((phba->sli_rev == LPFC_SLI_REV4) && fabric_param_changed) + if (fabric_param_changed) lpfc_unregister_fcf_prep(phba); /* This should just update the VFI CSPs*/ @@ -824,13 +835,21 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, spin_lock_irq(shost->host_lock); vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); + vport->fc_flag |= FC_PT2PT; spin_unlock_irq(shost->host_lock); - phba->fc_edtov = FF_DEF_EDTOV; - phba->fc_ratov = FF_DEF_RATOV; + /* If physical FC port changed, unreg VFI and ALL VPIs / RPIs */ + if ((phba->sli_rev == LPFC_SLI_REV4) && phba->fc_topology_changed) { + lpfc_unregister_fcf_prep(phba); + + spin_lock_irq(shost->host_lock); + vport->fc_flag &= ~FC_VFI_REGISTERED; + spin_unlock_irq(shost->host_lock); + phba->fc_topology_changed = 0; + } + rc = memcmp(&vport->fc_portname, &sp->portName, sizeof(vport->fc_portname)); - memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm)); if (rc >= 0) { /* This side will initiate the PLOGI */ @@ -839,38 +858,14 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, spin_unlock_irq(shost->host_lock); /* - * N_Port ID cannot be 0, set our to LocalID the other - * side will be RemoteID. + * N_Port ID cannot be 0, set our Id to LocalID + * the other side will be RemoteID. */ /* not equal */ if (rc) vport->fc_myDID = PT2PT_LocalID; - mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (!mbox) - goto fail; - - lpfc_config_link(phba, mbox); - - mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - mbox->vport = vport; - rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); - if (rc == MBX_NOT_FINISHED) { - mempool_free(mbox, phba->mbox_mem_pool); - goto fail; - } - - /* - * For SLI4, the VFI/VPI are registered AFTER the - * Nport with the higher WWPN sends the PLOGI with - * an assigned NPortId. - */ - - /* not equal */ - if ((phba->sli_rev == LPFC_SLI_REV4) && rc) - lpfc_issue_reg_vfi(vport); - /* Decrement ndlp reference count indicating that ndlp can be * safely released when other references to it are done. */ @@ -912,29 +907,20 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, /* If we are pt2pt with another NPort, force NPIV off! */ phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED; - spin_lock_irq(shost->host_lock); - vport->fc_flag |= FC_PT2PT; - spin_unlock_irq(shost->host_lock); - /* If physical FC port changed, unreg VFI and ALL VPIs / RPIs */ - if ((phba->sli_rev == LPFC_SLI_REV4) && phba->fc_topology_changed) { - lpfc_unregister_fcf_prep(phba); + mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mbox) + goto fail; - /* The FC_VFI_REGISTERED flag will get clear in the cmpl - * handler for unreg_vfi, but if we don't force the - * FC_VFI_REGISTERED flag then the reg_vfi mailbox could be - * built with the update bit set instead of just the vp bit to - * change the Nport ID. We need to have the vp set and the - * Upd cleared on topology changes. - */ - spin_lock_irq(shost->host_lock); - vport->fc_flag &= ~FC_VFI_REGISTERED; - spin_unlock_irq(shost->host_lock); - phba->fc_topology_changed = 0; - lpfc_issue_reg_vfi(vport); + lpfc_config_link(phba, mbox); + + mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; + mbox->vport = vport; + rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); + if (rc == MBX_NOT_FINISHED) { + mempool_free(mbox, phba->mbox_mem_pool); + goto fail; } - /* Start discovery - this should just do CLEAR_LA */ - lpfc_disc_start(vport); return 0; fail: return -ENXIO; @@ -1157,6 +1143,7 @@ flogifail: spin_lock_irq(&phba->hbalock); phba->fcf.fcf_flag &= ~FCF_DISCOVERY; spin_unlock_irq(&phba->hbalock); + lpfc_nlp_put(ndlp); if (!lpfc_error_lost_link(irsp)) { @@ -3898,6 +3885,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, IOCB_t *oldcmd; struct lpfc_iocbq *elsiocb; uint8_t *pcmd; + struct serv_parm *sp; uint16_t cmdsize; int rc; ELS_PKT *els_pkt_ptr; @@ -3927,6 +3915,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, "Issue ACC: did:x%x flg:x%x", ndlp->nlp_DID, ndlp->nlp_flag, 0); break; + case ELS_CMD_FLOGI: case ELS_CMD_PLOGI: cmdsize = (sizeof(struct serv_parm) + sizeof(uint32_t)); elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, @@ -3944,10 +3933,34 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, *((uint32_t *) (pcmd)) = ELS_CMD_ACC; pcmd += sizeof(uint32_t); - memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm)); + sp = (struct serv_parm *)pcmd; + + if (flag == ELS_CMD_FLOGI) { + /* Copy the received service parameters back */ + memcpy(sp, &phba->fc_fabparam, + sizeof(struct serv_parm)); + + /* Clear the F_Port bit */ + sp->cmn.fPort = 0; + + /* Mark all class service parameters as invalid */ + sp->cls1.classValid = 0; + sp->cls2.classValid = 0; + sp->cls3.classValid = 0; + sp->cls4.classValid = 0; + + /* Copy our worldwide names */ + memcpy(&sp->portName, &vport->fc_sparam.portName, + sizeof(struct lpfc_name)); + memcpy(&sp->nodeName, &vport->fc_sparam.nodeName, + sizeof(struct lpfc_name)); + } else { + memcpy(pcmd, &vport->fc_sparam, + sizeof(struct serv_parm)); + } lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, - "Issue ACC PLOGI: did:x%x flg:x%x", + "Issue ACC FLOGI/PLOGI: did:x%x flg:x%x", ndlp->nlp_DID, ndlp->nlp_flag, 0); break; case ELS_CMD_PRLO: @@ -5739,7 +5752,6 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, IOCB_t *icmd = &cmdiocb->iocb; struct serv_parm *sp; LPFC_MBOXQ_t *mbox; - struct ls_rjt stat; uint32_t cmd, did; int rc; uint32_t fc_flag = 0; @@ -5765,135 +5777,92 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, return 1; } - if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1))) { - /* For a FLOGI we accept, then if our portname is greater - * then the remote portname we initiate Nport login. - */ + (void) lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1); - rc = memcmp(&vport->fc_portname, &sp->portName, - sizeof(struct lpfc_name)); - if (!rc) { - if (phba->sli_rev < LPFC_SLI_REV4) { - mbox = mempool_alloc(phba->mbox_mem_pool, - GFP_KERNEL); - if (!mbox) - return 1; - lpfc_linkdown(phba); - lpfc_init_link(phba, mbox, - phba->cfg_topology, - phba->cfg_link_speed); - mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0; - mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - mbox->vport = vport; - rc = lpfc_sli_issue_mbox(phba, mbox, - MBX_NOWAIT); - lpfc_set_loopback_flag(phba); - if (rc == MBX_NOT_FINISHED) - mempool_free(mbox, phba->mbox_mem_pool); - return 1; - } else { - /* abort the flogi coming back to ourselves - * due to external loopback on the port. - */ - lpfc_els_abort_flogi(phba); - return 0; - } - } else if (rc > 0) { /* greater than */ - spin_lock_irq(shost->host_lock); - vport->fc_flag |= FC_PT2PT_PLOGI; - spin_unlock_irq(shost->host_lock); + /* + * If our portname is greater than the remote portname, + * then we initiate Nport login. + */ - /* If we have the high WWPN we can assign our own - * myDID; otherwise, we have to WAIT for a PLOGI - * from the remote NPort to find out what it - * will be. - */ - vport->fc_myDID = PT2PT_LocalID; - } else - vport->fc_myDID = PT2PT_RemoteID; + rc = memcmp(&vport->fc_portname, &sp->portName, + sizeof(struct lpfc_name)); - /* - * The vport state should go to LPFC_FLOGI only - * AFTER we issue a FLOGI, not receive one. + if (!rc) { + if (phba->sli_rev < LPFC_SLI_REV4) { + mbox = mempool_alloc(phba->mbox_mem_pool, + GFP_KERNEL); + if (!mbox) + return 1; + lpfc_linkdown(phba); + lpfc_init_link(phba, mbox, + phba->cfg_topology, + phba->cfg_link_speed); + mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0; + mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; + mbox->vport = vport; + rc = lpfc_sli_issue_mbox(phba, mbox, + MBX_NOWAIT); + lpfc_set_loopback_flag(phba); + if (rc == MBX_NOT_FINISHED) + mempool_free(mbox, phba->mbox_mem_pool); + return 1; + } + + /* abort the flogi coming back to ourselves + * due to external loopback on the port. */ + lpfc_els_abort_flogi(phba); + return 0; + + } else if (rc > 0) { /* greater than */ spin_lock_irq(shost->host_lock); - fc_flag = vport->fc_flag; - port_state = vport->port_state; - vport->fc_flag |= FC_PT2PT; - vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); + vport->fc_flag |= FC_PT2PT_PLOGI; spin_unlock_irq(shost->host_lock); - lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, - "3311 Rcv Flogi PS x%x new PS x%x " - "fc_flag x%x new fc_flag x%x\n", - port_state, vport->port_state, - fc_flag, vport->fc_flag); - /* - * We temporarily set fc_myDID to make it look like we are - * a Fabric. This is done just so we end up with the right - * did / sid on the FLOGI ACC rsp. + /* If we have the high WWPN we can assign our own + * myDID; otherwise, we have to WAIT for a PLOGI + * from the remote NPort to find out what it + * will be. */ - did = vport->fc_myDID; - vport->fc_myDID = Fabric_DID; - + vport->fc_myDID = PT2PT_LocalID; } else { - /* Reject this request because invalid parameters */ - stat.un.b.lsRjtRsvd0 = 0; - stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; - stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; - stat.un.b.vendorUnique = 0; - - /* - * We temporarily set fc_myDID to make it look like we are - * a Fabric. This is done just so we end up with the right - * did / sid on the FLOGI LS_RJT rsp. - */ - did = vport->fc_myDID; - vport->fc_myDID = Fabric_DID; - - lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, - NULL); + vport->fc_myDID = PT2PT_RemoteID; + } - /* Now lets put fc_myDID back to what its supposed to be */ - vport->fc_myDID = did; + /* + * The vport state should go to LPFC_FLOGI only + * AFTER we issue a FLOGI, not receive one. + */ + spin_lock_irq(shost->host_lock); + fc_flag = vport->fc_flag; + port_state = vport->port_state; + vport->fc_flag |= FC_PT2PT; + vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); + spin_unlock_irq(shost->host_lock); + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "3311 Rcv Flogi PS x%x new PS x%x " + "fc_flag x%x new fc_flag x%x\n", + port_state, vport->port_state, + fc_flag, vport->fc_flag); - return 1; - } + /* + * We temporarily set fc_myDID to make it look like we are + * a Fabric. This is done just so we end up with the right + * did / sid on the FLOGI ACC rsp. + */ + did = vport->fc_myDID; + vport->fc_myDID = Fabric_DID; - /* send our FLOGI first */ - if (vport->port_state < LPFC_FLOGI) { - vport->fc_myDID = 0; - lpfc_initial_flogi(vport); - vport->fc_myDID = Fabric_DID; - } + memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm)); /* Send back ACC */ - lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL); + lpfc_els_rsp_acc(vport, ELS_CMD_FLOGI, cmdiocb, ndlp, NULL); /* Now lets put fc_myDID back to what its supposed to be */ vport->fc_myDID = did; - if (!(vport->fc_flag & FC_PT2PT_PLOGI)) { - - mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (!mbox) - goto fail; - - lpfc_config_link(phba, mbox); - - mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - mbox->vport = vport; - rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); - if (rc == MBX_NOT_FINISHED) { - mempool_free(mbox, phba->mbox_mem_pool); - goto fail; - } - } - return 0; -fail: - return 1; } /** @@ -7345,7 +7314,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, /* reject till our FLOGI completes */ if ((vport->port_state < LPFC_FABRIC_CFG_LINK) && - (cmd != ELS_CMD_FLOGI)) { + (cmd != ELS_CMD_FLOGI)) { rjt_err = LSRJT_UNABLE_TPC; rjt_exp = LSEXP_NOTHING_MORE; goto lsrjt; @@ -7381,6 +7350,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, rjt_exp = LSEXP_NOTHING_MORE; break; } + if (vport->port_state < LPFC_DISC_AUTH) { if (!(phba->pport->fc_flag & FC_PT2PT) || (phba->pport->fc_flag & FC_PT2PT_PLOGI)) { diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index bfc2442dd74a5..c96532cc5af07 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1083,7 +1083,7 @@ out: } -static void +void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) { struct lpfc_vport *vport = pmb->vport; @@ -1113,8 +1113,10 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) /* Start discovery by sending a FLOGI. port_state is identically * LPFC_FLOGI while waiting for FLOGI cmpl */ - if (vport->port_state != LPFC_FLOGI || vport->fc_flag & FC_PT2PT_PLOGI) + if (vport->port_state != LPFC_FLOGI) lpfc_initial_flogi(vport); + else if (vport->fc_flag & FC_PT2PT) + lpfc_disc_start(vport); return; out: @@ -2963,8 +2965,10 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) out_free_mem: mempool_free(mboxq, phba->mbox_mem_pool); - lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys); - kfree(dmabuf); + if (dmabuf) { + lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys); + kfree(dmabuf); + } return; } diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index ed9a2c80c4aad..daeda6d7fb252 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -280,38 +280,12 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, uint32_t *lp; IOCB_t *icmd; struct serv_parm *sp; + uint32_t ed_tov; LPFC_MBOXQ_t *mbox; struct ls_rjt stat; int rc; memset(&stat, 0, sizeof (struct ls_rjt)); - if (vport->port_state <= LPFC_FDISC) { - /* Before responding to PLOGI, check for pt2pt mode. - * If we are pt2pt, with an outstanding FLOGI, abort - * the FLOGI and resend it first. - */ - if (vport->fc_flag & FC_PT2PT) { - lpfc_els_abort_flogi(phba); - if (!(vport->fc_flag & FC_PT2PT_PLOGI)) { - /* If the other side is supposed to initiate - * the PLOGI anyway, just ACC it now and - * move on with discovery. - */ - phba->fc_edtov = FF_DEF_EDTOV; - phba->fc_ratov = FF_DEF_RATOV; - /* Start discovery - this should just do - CLEAR_LA */ - lpfc_disc_start(vport); - } else - lpfc_initial_flogi(vport); - } else { - stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY; - stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; - lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, - ndlp, NULL); - return 0; - } - } pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; lp = (uint32_t *) pcmd->virt; sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); @@ -404,30 +378,46 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, /* Check for Nport to NPort pt2pt protocol */ if ((vport->fc_flag & FC_PT2PT) && !(vport->fc_flag & FC_PT2PT_PLOGI)) { - /* rcv'ed PLOGI decides what our NPortId will be */ vport->fc_myDID = icmd->un.rcvels.parmRo; - mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (mbox == NULL) - goto out; - lpfc_config_link(phba, mbox); - mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - mbox->vport = vport; - rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); - if (rc == MBX_NOT_FINISHED) { - mempool_free(mbox, phba->mbox_mem_pool); - goto out; + + ed_tov = be32_to_cpu(sp->cmn.e_d_tov); + if (sp->cmn.edtovResolution) { + /* E_D_TOV ticks are in nanoseconds */ + ed_tov = (phba->fc_edtov + 999999) / 1000000; } + /* - * For SLI4, the VFI/VPI are registered AFTER the - * Nport with the higher WWPN sends us a PLOGI with - * our assigned NPortId. + * For pt-to-pt, use the larger EDTOV + * RATOV = 2 * EDTOV */ + if (ed_tov > phba->fc_edtov) + phba->fc_edtov = ed_tov; + phba->fc_ratov = (2 * phba->fc_edtov) / 1000; + + memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm)); + + /* Issue config_link / reg_vfi to account for updated TOV's */ + if (phba->sli_rev == LPFC_SLI_REV4) lpfc_issue_reg_vfi(vport); + else { + mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (mbox == NULL) + goto out; + lpfc_config_link(phba, mbox); + mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; + mbox->vport = vport; + rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); + if (rc == MBX_NOT_FINISHED) { + mempool_free(mbox, phba->mbox_mem_pool); + goto out; + } + } lpfc_can_disctmo(vport); } + mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!mbox) goto out; @@ -1038,7 +1028,9 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, uint32_t *lp; IOCB_t *irsp; struct serv_parm *sp; + uint32_t ed_tov; LPFC_MBOXQ_t *mbox; + int rc; cmdiocb = (struct lpfc_iocbq *) arg; rspiocb = cmdiocb->context_un.rsp_iocb; @@ -1053,6 +1045,16 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, if (irsp->ulpStatus) goto out; + mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mbox) { + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0133 PLOGI: no memory for reg_login " + "Data: x%x x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_state, + ndlp->nlp_flag, ndlp->nlp_rpi); + goto out; + } + pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list); @@ -1094,14 +1096,38 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, ndlp->nlp_maxframe = ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb; - mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (!mbox) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, - "0133 PLOGI: no memory for reg_login " - "Data: x%x x%x x%x x%x\n", - ndlp->nlp_DID, ndlp->nlp_state, - ndlp->nlp_flag, ndlp->nlp_rpi); - goto out; + if ((vport->fc_flag & FC_PT2PT) && + (vport->fc_flag & FC_PT2PT_PLOGI)) { + ed_tov = be32_to_cpu(sp->cmn.e_d_tov); + if (sp->cmn.edtovResolution) { + /* E_D_TOV ticks are in nanoseconds */ + ed_tov = (phba->fc_edtov + 999999) / 1000000; + } + + /* + * Use the larger EDTOV + * RATOV = 2 * EDTOV for pt-to-pt + */ + if (ed_tov > phba->fc_edtov) + phba->fc_edtov = ed_tov; + phba->fc_ratov = (2 * phba->fc_edtov) / 1000; + + memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm)); + + /* Issue config_link / reg_vfi to account for updated TOV's */ + if (phba->sli_rev == LPFC_SLI_REV4) { + lpfc_issue_reg_vfi(vport); + } else { + lpfc_config_link(phba, mbox); + + mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; + mbox->vport = vport; + rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); + if (rc == MBX_NOT_FINISHED) { + mempool_free(mbox, phba->mbox_mem_pool); + goto out; + } + } } lpfc_unreg_rpi(vport, ndlp); -- GitLab From 4b7789b71c916f79a3366da080101014473234c3 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:11:55 -0500 Subject: [PATCH 1965/2855] lpfc: Fix RegLogin failed error seen on Lancer FC during port bounce Fix RegLogin failed error seen on Lancer FC during port bounce Fix the statemachine and ref counting. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 14 +++++++++----- drivers/scsi/lpfc/lpfc_hbadisc.c | 8 ++++---- drivers/scsi/lpfc/lpfc_nportdisc.c | 3 +++ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index f6dd15b22383c..d508378510f10 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -3779,14 +3779,17 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE); } + + ndlp->nlp_flag |= NLP_REG_LOGIN_SEND; if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) != MBX_NOT_FINISHED) goto out; - else - /* Decrement the ndlp reference count we - * set for this failed mailbox command. - */ - lpfc_nlp_put(ndlp); + + /* Decrement the ndlp reference count we + * set for this failed mailbox command. + */ + lpfc_nlp_put(ndlp); + ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND; /* ELS rsp: Cannot issue reg_login for */ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, @@ -3843,6 +3846,7 @@ out: * the routine lpfc_els_free_iocb. */ cmdiocb->context1 = NULL; + } lpfc_els_free_iocb(phba, cmdiocb); diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index c96532cc5af07..d3668aa555d53 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -3452,10 +3452,10 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) spin_lock_irq(shost->host_lock); ndlp->nlp_flag &= ~NLP_IGNR_REG_CMPL; spin_unlock_irq(shost->host_lock); - } else - /* Good status, call state machine */ - lpfc_disc_state_machine(vport, ndlp, pmb, - NLP_EVT_CMPL_REG_LOGIN); + } + + /* Call state machine */ + lpfc_disc_state_machine(vport, ndlp, pmb, NLP_EVT_CMPL_REG_LOGIN); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index daeda6d7fb252..9e571dd416877 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -2325,6 +2325,9 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_vport *vport, if (vport->phba->sli_rev < LPFC_SLI_REV4) ndlp->nlp_rpi = mb->un.varWords[0]; ndlp->nlp_flag |= NLP_RPI_REGISTERED; + if (ndlp->nlp_flag & NLP_LOGO_ACC) { + lpfc_unreg_rpi(vport, ndlp); + } } else { if (ndlp->nlp_flag & NLP_NODEV_REMOVE) { lpfc_drop_node(vport, ndlp); -- GitLab From 6690e0d4fc5cccf74534abe0c9f9a69032bc02f0 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:11:56 -0500 Subject: [PATCH 1966/2855] lpfc: Fix driver crash when module parameter lpfc_fcp_io_channel set to 16 Fix driver crash when module parameter lpfc_fcp_io_channel set to 16 Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index db9446c612dad..5915407d19aa9 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -8833,9 +8833,12 @@ found: * already mapped to this phys_id. */ if (cpup->irq != LPFC_VECTOR_MAP_EMPTY) { - chann[saved_chann] = - cpup->channel_id; - saved_chann++; + if (saved_chann <= + LPFC_FCP_IO_CHAN_MAX) { + chann[saved_chann] = + cpup->channel_id; + saved_chann++; + } goto out; } -- GitLab From c90261dcd86e4eb5c9c1627fde037e902db8aefa Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:11:57 -0500 Subject: [PATCH 1967/2855] lpfc: Fix crash in fcp command completion path. Fix crash in fcp command completion path. Missed null check. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_scsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 4679ed4444a73..ab446f83fba6f 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -3908,9 +3908,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, uint32_t logit = LOG_FCP; /* Sanity check on return of outstanding command */ - if (!(lpfc_cmd->pCmd)) - return; cmd = lpfc_cmd->pCmd; + if (!cmd) + return; shost = cmd->device->host; lpfc_cmd->result = (pIocbOut->iocb.un.ulpWord[4] & IOERR_PARAM_MASK); -- GitLab From 4258e98ee3862ca7036654b43c839ab7668043e0 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:11:58 -0500 Subject: [PATCH 1968/2855] lpfc: Modularize and cleanup FDMI code in driver Modularize, cleanup, add comments - for FDMI code in driver Note: I don't like the comments with leading # - but as we have a lot if present, I'm deferring to handle it in one big fix later. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc.h | 16 +- drivers/scsi/lpfc/lpfc_attr.c | 46 +- drivers/scsi/lpfc/lpfc_crtn.h | 5 +- drivers/scsi/lpfc/lpfc_ct.c | 1794 +++++++++++++++++++----------- drivers/scsi/lpfc/lpfc_els.c | 99 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 16 +- drivers/scsi/lpfc/lpfc_hw.h | 184 ++- drivers/scsi/lpfc/lpfc_init.c | 27 +- drivers/scsi/lpfc/lpfc_vport.c | 8 + 9 files changed, 1450 insertions(+), 745 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index ceee9a3fd9e52..90a3ca5a4dbd6 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -386,7 +386,6 @@ struct lpfc_vport { uint32_t work_port_events; /* Timeout to be handled */ #define WORKER_DISC_TMO 0x1 /* vport: Discovery timeout */ #define WORKER_ELS_TMO 0x2 /* vport: ELS timeout */ -#define WORKER_FDMI_TMO 0x4 /* vport: FDMI timeout */ #define WORKER_DELAYED_DISC_TMO 0x8 /* vport: delayed discovery */ #define WORKER_MBOX_TMO 0x100 /* hba: MBOX timeout */ @@ -396,7 +395,6 @@ struct lpfc_vport { #define WORKER_RAMP_UP_QUEUE 0x1000 /* hba: Increase Q depth */ #define WORKER_SERVICE_TXQ 0x2000 /* hba: IOCBs on the txq */ - struct timer_list fc_fdmitmo; struct timer_list els_tmofunc; struct timer_list delayed_disc_tmo; @@ -405,6 +403,7 @@ struct lpfc_vport { uint8_t load_flag; #define FC_LOADING 0x1 /* HBA in process of loading drvr */ #define FC_UNLOADING 0x2 /* HBA in process of unloading drvr */ +#define FC_ALLOW_FDMI 0x4 /* port is ready for FDMI requests */ /* Vport Config Parameters */ uint32_t cfg_scan_down; uint32_t cfg_lun_queue_depth; @@ -414,10 +413,6 @@ struct lpfc_vport { uint32_t cfg_peer_port_login; uint32_t cfg_fcp_class; uint32_t cfg_use_adisc; - uint32_t cfg_fdmi_on; -#define LPFC_FDMI_SUPPORT 1 /* bit 0 - FDMI supported? */ -#define LPFC_FDMI_REG_DELAY 2 /* bit 1 - 60 sec registration delay */ -#define LPFC_FDMI_ALL_ATTRIB 4 /* bit 2 - register ALL attributes? */ uint32_t cfg_discovery_threads; uint32_t cfg_log_verbose; uint32_t cfg_max_luns; @@ -443,6 +438,10 @@ struct lpfc_vport { unsigned long rcv_buffer_time_stamp; uint32_t vport_flag; #define STATIC_VPORT 1 + + uint16_t fdmi_num_disc; + uint32_t fdmi_hba_mask; + uint32_t fdmi_port_mask; }; struct hbq_s { @@ -755,6 +754,11 @@ struct lpfc_hba { #define LPFC_DELAY_INIT_LINK 1 /* layered driver hold off */ #define LPFC_DELAY_INIT_LINK_INDEFINITELY 2 /* wait, manual intervention */ uint32_t cfg_enable_dss; + uint32_t cfg_fdmi_on; +#define LPFC_FDMI_NO_SUPPORT 0 /* FDMI not supported */ +#define LPFC_FDMI_SUPPORT 1 /* FDMI supported? */ +#define LPFC_FDMI_SMART_SAN 2 /* SmartSAN supported */ + uint32_t cfg_enable_SmartSAN; lpfc_vpd_t vpd; /* vital product data */ struct pci_dev *pcidev; diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index f6446d759d7f9..5739c260038ac 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -4572,19 +4572,27 @@ LPFC_ATTR_R(multi_ring_type, FC_TYPE_IP, 1, 255, "Identifies TYPE for additional ring configuration"); /* -# lpfc_fdmi_on: controls FDMI support. -# Set NOT Set -# bit 0 = FDMI support no FDMI support -# LPFC_FDMI_SUPPORT just turns basic support on/off -# bit 1 = Register delay no register delay (60 seconds) -# LPFC_FDMI_REG_DELAY 60 sec registration delay after FDMI login -# bit 2 = All attributes Use a attribute subset -# LPFC_FDMI_ALL_ATTRIB applies to both port and HBA attributes -# Port attrutes subset: 1 thru 6 OR all: 1 thru 0xd 0x101 0x102 0x103 -# HBA attributes subset: 1 thru 0xb OR all: 1 thru 0xc -# Value range [0,7]. Default value is 0. +# lpfc_enable_SmartSAN: Sets up FDMI support for SmartSAN +# 0 = SmartSAN functionality disabled (default) +# 1 = SmartSAN functionality enabled +# This parameter will override the value of lpfc_fdmi_on module parameter. +# Value range is [0,1]. Default value is 0. */ -LPFC_VPORT_ATTR_RW(fdmi_on, 0, 0, 7, "Enable FDMI support"); +LPFC_ATTR_R(enable_SmartSAN, 0, 0, 1, "Enable SmartSAN functionality"); + +/* +# lpfc_fdmi_on: Controls FDMI support. +# 0 No FDMI support (default) +# 1 Traditional FDMI support +# 2 Smart SAN support +# If lpfc_enable_SmartSAN is set 1, the driver sets lpfc_fdmi_on to value 2 +# overwriting the current value. If lpfc_enable_SmartSAN is set 0, the +# driver uses the current value of lpfc_fdmi_on provided it has value 0 or 1. +# A value of 2 with lpfc_enable_SmartSAN set to 0 causes the driver to +# set lpfc_fdmi_on back to 1. +# Value range [0,2]. Default value is 0. +*/ +LPFC_ATTR_R(fdmi_on, 0, 0, 2, "Enable FDMI support"); /* # Specifies the maximum number of ELS cmds we can have outstanding (for @@ -4815,6 +4823,7 @@ struct device_attribute *lpfc_hba_attrs[] = { &dev_attr_lpfc_multi_ring_rctl, &dev_attr_lpfc_multi_ring_type, &dev_attr_lpfc_fdmi_on, + &dev_attr_lpfc_enable_SmartSAN, &dev_attr_lpfc_max_luns, &dev_attr_lpfc_enable_npiv, &dev_attr_lpfc_fcf_failover_policy, @@ -4887,7 +4896,6 @@ struct device_attribute *lpfc_vport_attrs[] = { &dev_attr_lpfc_fcp_class, &dev_attr_lpfc_use_adisc, &dev_attr_lpfc_first_burst_size, - &dev_attr_lpfc_fdmi_on, &dev_attr_lpfc_max_luns, &dev_attr_nport_evt_cnt, &dev_attr_npiv_info, @@ -5826,6 +5834,8 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) lpfc_enable_npiv_init(phba, lpfc_enable_npiv); lpfc_fcf_failover_policy_init(phba, lpfc_fcf_failover_policy); lpfc_enable_rrq_init(phba, lpfc_enable_rrq); + lpfc_fdmi_on_init(phba, lpfc_fdmi_on); + lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN); lpfc_use_msi_init(phba, lpfc_use_msi); lpfc_fcp_imax_init(phba, lpfc_fcp_imax); lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map); @@ -5846,6 +5856,15 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) phba->cfg_poll = 0; else phba->cfg_poll = lpfc_poll; + + /* Ensure fdmi_on and enable_SmartSAN don't conflict */ + if (phba->cfg_enable_SmartSAN) { + phba->cfg_fdmi_on = LPFC_FDMI_SMART_SAN; + } else { + if (phba->cfg_fdmi_on == LPFC_FDMI_SMART_SAN) + phba->cfg_fdmi_on = LPFC_FDMI_SUPPORT; + } + phba->cfg_soft_wwnn = 0L; phba->cfg_soft_wwpn = 0L; lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt); @@ -5879,7 +5898,6 @@ lpfc_get_vport_cfgparam(struct lpfc_vport *vport) lpfc_use_adisc_init(vport, lpfc_use_adisc); lpfc_first_burst_size_init(vport, lpfc_first_burst_size); lpfc_max_scsicmpl_time_init(vport, lpfc_max_scsicmpl_time); - lpfc_fdmi_on_init(vport, lpfc_fdmi_on); lpfc_discovery_threads_init(vport, lpfc_discovery_threads); lpfc_max_luns_init(vport, lpfc_max_luns); lpfc_scan_down_init(vport, lpfc_scan_down); diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 80d3c740a8a84..4e55b35180a4c 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -168,9 +168,8 @@ void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_iocbq *); int lpfc_ct_handle_unsol_abort(struct lpfc_hba *, struct hbq_dmabuf *); int lpfc_ns_cmd(struct lpfc_vport *, int, uint8_t, uint32_t); -int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int); -void lpfc_fdmi_tmo(unsigned long); -void lpfc_fdmi_timeout_handler(struct lpfc_vport *); +int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int, uint32_t); +void lpfc_fdmi_num_disc_check(struct lpfc_vport *); void lpfc_delayed_disc_tmo(unsigned long); void lpfc_delayed_disc_timeout_handler(struct lpfc_vport *); diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 8fded1f7605f7..ac6e087f6857c 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -287,6 +287,17 @@ lpfc_ct_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocb) return 0; } +/** + * lpfc_gen_req - Build and issue a GEN_REQUEST command to the SLI Layer + * @vport: pointer to a host virtual N_Port data structure. + * @bmp: Pointer to BPL for SLI command + * @inp: Pointer to data buffer for response data. + * @outp: Pointer to data buffer that hold the CT command. + * @cmpl: completion routine to call when command completes + * @ndlp: Destination NPort nodelist entry + * + * This function as the final part for issuing a CT command. + */ static int lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, struct lpfc_dmabuf *inp, struct lpfc_dmabuf *outp, @@ -311,7 +322,7 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, icmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys); icmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys); icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64; - icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof (struct ulp_bde64)); + icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof(struct ulp_bde64)); if (usr_flg) geniocb->context3 = NULL; @@ -370,6 +381,16 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, return 0; } +/** + * lpfc_ct_cmd - Build and issue a CT command + * @vport: pointer to a host virtual N_Port data structure. + * @inmp: Pointer to data buffer for response data. + * @bmp: Pointer to BPL for SLI command + * @ndlp: Destination NPort nodelist entry + * @cmpl: completion routine to call when command completes + * + * This function is called for issuing a CT command. + */ static int lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp, struct lpfc_dmabuf *bmp, struct lpfc_nodelist *ndlp, @@ -453,7 +474,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) Cnt -= 16; /* subtract length of CT header */ /* Loop through entire NameServer list of DIDs */ - while (Cnt >= sizeof (uint32_t)) { + while (Cnt >= sizeof(uint32_t)) { /* Get next DID from NameServer List */ CTentry = *ctptr++; Did = ((be32_to_cpu(CTentry)) & Mask_DID); @@ -558,7 +579,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) } if (CTentry & (cpu_to_be32(SLI_CT_LAST_ENTRY))) goto nsout1; - Cnt -= sizeof (uint32_t); + Cnt -= sizeof(uint32_t); } ctptr = NULL; @@ -1146,7 +1167,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, /* fill in BDEs for command */ /* Allocate buffer for command payload */ - mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); + mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); if (!mp) { rc=2; goto ns_cmd_exit; @@ -1160,7 +1181,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, } /* Allocate buffer for Buffer ptr list */ - bmp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); + bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); if (!bmp) { rc=4; goto ns_cmd_free_mpvirt; @@ -1204,7 +1225,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, bpl->tus.w = le32_to_cpu(bpl->tus.w); CtReq = (struct lpfc_sli_ct_request *) mp->virt; - memset(CtReq, 0, sizeof (struct lpfc_sli_ct_request)); + memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request)); CtReq->RevisionId.bits.Revision = SLI_CT_REVISION; CtReq->RevisionId.bits.InId = 0; CtReq->FsType = SLI_CT_DIRECTORY_SERVICE; @@ -1244,7 +1265,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, cpu_to_be16(SLI_CTNS_RNN_ID); CtReq->un.rnn.PortId = cpu_to_be32(vport->fc_myDID); memcpy(CtReq->un.rnn.wwnn, &vport->fc_nodename, - sizeof (struct lpfc_name)); + sizeof(struct lpfc_name)); cmpl = lpfc_cmpl_ct_cmd_rnn_id; break; @@ -1264,7 +1285,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, CtReq->CommandResponse.bits.CmdRsp = cpu_to_be16(SLI_CTNS_RSNN_NN); memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename, - sizeof (struct lpfc_name)); + sizeof(struct lpfc_name)); size = sizeof(CtReq->un.rsnn.symbname); CtReq->un.rsnn.len = lpfc_vport_symbolic_node_name(vport, @@ -1319,20 +1340,29 @@ ns_cmd_exit: return 1; } +/** + * lpfc_cmpl_ct_disc_fdmi - Handle a discovery FDMI completion + * @phba: Pointer to HBA context object. + * @cmdiocb: Pointer to the command IOCBQ. + * @rspiocb: Pointer to the response IOCBQ. + * + * This function to handle the completion of a driver initiated FDMI + * CT command issued during discovery. + */ static void -lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, - struct lpfc_iocbq * rspiocb) +lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + struct lpfc_iocbq *rspiocb) { + struct lpfc_vport *vport = cmdiocb->vport; struct lpfc_dmabuf *inp = cmdiocb->context1; struct lpfc_dmabuf *outp = cmdiocb->context2; - struct lpfc_sli_ct_request *CTrsp = outp->virt; struct lpfc_sli_ct_request *CTcmd = inp->virt; - struct lpfc_nodelist *ndlp; + struct lpfc_sli_ct_request *CTrsp = outp->virt; uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp; uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp; - struct lpfc_vport *vport = cmdiocb->vport; IOCB_t *irsp = &rspiocb->iocb; - uint32_t latt; + struct lpfc_nodelist *ndlp; + uint32_t latt, cmd, err; latt = lpfc_els_chk_latt(vport); lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, @@ -1340,91 +1370,1076 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, irsp->ulpStatus, irsp->un.ulpWord[4], latt); if (latt || irsp->ulpStatus) { + + /* Look for a retryable error */ + if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { + switch ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK)) { + case IOERR_SLI_ABORTED: + case IOERR_ABORT_IN_PROGRESS: + case IOERR_SEQUENCE_TIMEOUT: + case IOERR_ILLEGAL_FRAME: + case IOERR_NO_RESOURCES: + case IOERR_ILLEGAL_COMMAND: + cmdiocb->retry++; + if (cmdiocb->retry >= LPFC_FDMI_MAX_RETRY) + break; + + /* Retry the same FDMI command */ + err = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, + cmdiocb, 0); + if (err == IOCB_ERROR) + break; + return; + default: + break; + } + } + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "0229 FDMI cmd %04x failed, latt = %d " "ulpStatus: x%x, rid x%x\n", be16_to_cpu(fdmi_cmd), latt, irsp->ulpStatus, irsp->un.ulpWord[4]); - goto fail_out; } + lpfc_ct_free_iocb(phba, cmdiocb); ndlp = lpfc_findnode_did(vport, FDMI_DID); if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) - goto fail_out; + return; + /* Check for a CT LS_RJT response */ + cmd = be16_to_cpu(fdmi_cmd); if (fdmi_rsp == cpu_to_be16(SLI_CT_RESPONSE_FS_RJT)) { /* FDMI rsp failed */ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, - "0220 FDMI rsp failed Data: x%x\n", - be16_to_cpu(fdmi_cmd)); + "0220 FDMI cmd failed FS_RJT Data: x%x", cmd); + + /* Should we fallback to FDMI-2 / FDMI-1 ? */ + switch (cmd) { + case SLI_MGMT_RHBA: + if (vport->fdmi_hba_mask == LPFC_FDMI2_HBA_ATTR) { + /* Fallback to FDMI-1 */ + vport->fdmi_hba_mask = LPFC_FDMI1_HBA_ATTR; + vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR; + /* Start over */ + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0); + } + return; + + case SLI_MGMT_RPRT: + if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) { + /* Fallback to FDMI-1 */ + vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR; + /* Start over */ + lpfc_fdmi_cmd(vport, ndlp, cmd, 0); + } + if (vport->fdmi_port_mask == LPFC_FDMI2_SMART_ATTR) { + vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR; + /* Retry the same command */ + lpfc_fdmi_cmd(vport, ndlp, cmd, 0); + } + return; + + case SLI_MGMT_RPA: + if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) { + /* Fallback to FDMI-1 */ + vport->fdmi_hba_mask = LPFC_FDMI1_HBA_ATTR; + vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR; + /* Start over */ + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0); + } + if (vport->fdmi_port_mask == LPFC_FDMI2_SMART_ATTR) { + vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR; + /* Retry the same command */ + lpfc_fdmi_cmd(vport, ndlp, cmd, 0); + } + return; + } } -fail_out: - lpfc_ct_free_iocb(phba, cmdiocb); + /* + * On success, need to cycle thru FDMI registration for discovery + * DHBA -> DPRT -> RHBA -> RPA (physical port) + * DPRT -> RPRT (vports) + */ + switch (cmd) { + case SLI_MGMT_RHBA: + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA, 0); + break; + + case SLI_MGMT_DHBA: + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT, 0); + break; + + case SLI_MGMT_DPRT: + if (vport->port_type == LPFC_PHYSICAL_PORT) + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA, 0); + else + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT, 0); + break; + } + return; } -static void -lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, - struct lpfc_iocbq *rspiocb) + +/** + * lpfc_fdmi_num_disc_check - Check how many mapped NPorts we are connected to + * @vport: pointer to a host virtual N_Port data structure. + * + * Called from hbeat timeout routine to check if the number of discovered + * ports has changed. If so, re-register thar port Attribute. + */ +void +lpfc_fdmi_num_disc_check(struct lpfc_vport *vport) { - struct lpfc_vport *vport = cmdiocb->vport; - struct lpfc_dmabuf *inp = cmdiocb->context1; - struct lpfc_sli_ct_request *CTcmd = inp->virt; - uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp; + struct lpfc_hba *phba = vport->phba; struct lpfc_nodelist *ndlp; + uint16_t cnt; - lpfc_cmpl_ct_cmd_fdmi(phba, cmdiocb, rspiocb); + if (!lpfc_is_link_up(phba)) + return; + + if (!(vport->fdmi_port_mask & LPFC_FDMI_PORT_ATTR_num_disc)) + return; + + cnt = lpfc_find_map_node(vport); + if (cnt == vport->fdmi_num_disc) + return; ndlp = lpfc_findnode_did(vport, FDMI_DID); if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) return; - /* - * Need to cycle thru FDMI registration for discovery - * DHBA -> DPRT -> RHBA -> RPA - */ - switch (be16_to_cpu(fdmi_cmd)) { - case SLI_MGMT_RHBA: - lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA); - break; + if (vport->port_type == LPFC_PHYSICAL_PORT) { + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA, + LPFC_FDMI_PORT_ATTR_num_disc); + } else { + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT, + LPFC_FDMI_PORT_ATTR_num_disc); + } +} - case SLI_MGMT_DHBA: - lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT); - break; +/* Routines for all individual HBA attributes */ +int +lpfc_fdmi_hba_attr_wwnn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; - case SLI_MGMT_DPRT: - lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(struct lpfc_name)); + + memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName, + sizeof(struct lpfc_name)); + size = FOURBYTES + sizeof(struct lpfc_name); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_NODENAME); + return size; +} +int +lpfc_fdmi_hba_attr_manufacturer(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, + "Emulex Corporation", + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_MANUFACTURER); + return size; +} + +int +lpfc_fdmi_hba_attr_sn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, phba->SerialNumber, + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_SERIAL_NUMBER); + return size; +} + +int +lpfc_fdmi_hba_attr_model(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, phba->ModelName, + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_MODEL); + return size; +} + +int +lpfc_fdmi_hba_attr_description(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, phba->ModelDesc, + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_MODEL_DESCRIPTION); + return size; +} + +int +lpfc_fdmi_hba_attr_hdw_ver(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + lpfc_vpd_t *vp = &phba->vpd; + struct lpfc_fdmi_attr_entry *ae; + uint32_t i, j, incr, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + /* Convert JEDEC ID to ascii for hardware version */ + incr = vp->rev.biuRev; + for (i = 0; i < 8; i++) { + j = (incr & 0xf); + if (j <= 9) + ae->un.AttrString[7 - i] = + (char)((uint8_t) 0x30 + + (uint8_t) j); + else + ae->un.AttrString[7 - i] = + (char)((uint8_t) 0x61 + + (uint8_t) (j - 10)); + incr = (incr >> 4); + } + size = FOURBYTES + 8; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_HARDWARE_VERSION); + return size; +} + +int +lpfc_fdmi_hba_attr_drvr_ver(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, lpfc_release_version, + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_DRIVER_VERSION); + return size; +} + +int +lpfc_fdmi_hba_attr_rom_ver(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + if (phba->sli_rev == LPFC_SLI_REV4) + lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1); + else + strncpy(ae->un.AttrString, phba->OptionROMVersion, + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_OPTION_ROM_VERSION); + return size; +} + +int +lpfc_fdmi_hba_attr_fmw_ver(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_FIRMWARE_VERSION); + return size; +} + +int +lpfc_fdmi_hba_attr_os_ver(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s %s %s", + init_utsname()->sysname, + init_utsname()->release, + init_utsname()->version); + + len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_OS_NAME_VERSION); + return size; +} + +int +lpfc_fdmi_hba_attr_ct_len(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + + ae->un.AttrInt = cpu_to_be32(LPFC_MAX_CT_SIZE); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_MAX_CT_PAYLOAD_LEN); + return size; +} + +int +lpfc_fdmi_hba_attr_symbolic_name(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + len = lpfc_vport_symbolic_node_name(vport, + ae->un.AttrString, 256); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_SYM_NODENAME); + return size; +} + +int +lpfc_fdmi_hba_attr_vendor_info(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + + /* Nothing is defined for this currently */ + ae->un.AttrInt = cpu_to_be32(0); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_VENDOR_INFO); + return size; +} + +int +lpfc_fdmi_hba_attr_num_ports(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + + /* Each driver instance corresponds to a single port */ + ae->un.AttrInt = cpu_to_be32(1); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_NUM_PORTS); + return size; +} + +int +lpfc_fdmi_hba_attr_fabric_wwnn(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(struct lpfc_name)); + + memcpy(&ae->un.AttrWWN, &vport->fabric_nodename, + sizeof(struct lpfc_name)); + size = FOURBYTES + sizeof(struct lpfc_name); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_FABRIC_WWNN); + return size; +} + +int +lpfc_fdmi_hba_attr_bios_ver(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_BIOS_VERSION); + return size; +} + +int +lpfc_fdmi_hba_attr_bios_state(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + + /* Driver doesn't have access to this information */ + ae->un.AttrInt = cpu_to_be32(0); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_BIOS_STATE); + return size; +} + +int +lpfc_fdmi_hba_attr_vendor_id(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, "EMULEX", + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_VENDOR_ID); + return size; +} + +/* Routines for all individual PORT attributes */ +int +lpfc_fdmi_port_attr_fc4type(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 32); + + ae->un.AttrTypes[3] = 0x02; /* Type 1 - ELS */ + ae->un.AttrTypes[2] = 0x01; /* Type 8 - FCP */ + ae->un.AttrTypes[7] = 0x01; /* Type 32 - CT */ + size = FOURBYTES + 32; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_FC4_TYPES); + return size; +} + +int +lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + + ae->un.AttrInt = 0; + if (phba->lmt & LMT_32Gb) + ae->un.AttrInt |= HBA_PORTSPEED_32GBIT; + if (phba->lmt & LMT_16Gb) + ae->un.AttrInt |= HBA_PORTSPEED_16GBIT; + if (phba->lmt & LMT_10Gb) + ae->un.AttrInt |= HBA_PORTSPEED_10GBIT; + if (phba->lmt & LMT_8Gb) + ae->un.AttrInt |= HBA_PORTSPEED_8GBIT; + if (phba->lmt & LMT_4Gb) + ae->un.AttrInt |= HBA_PORTSPEED_4GBIT; + if (phba->lmt & LMT_2Gb) + ae->un.AttrInt |= HBA_PORTSPEED_2GBIT; + if (phba->lmt & LMT_1Gb) + ae->un.AttrInt |= HBA_PORTSPEED_1GBIT; + ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_SPEED); + return size; +} + +int +lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + + switch (phba->fc_linkspeed) { + case LPFC_LINK_SPEED_1GHZ: + ae->un.AttrInt = HBA_PORTSPEED_1GBIT; + break; + case LPFC_LINK_SPEED_2GHZ: + ae->un.AttrInt = HBA_PORTSPEED_2GBIT; + break; + case LPFC_LINK_SPEED_4GHZ: + ae->un.AttrInt = HBA_PORTSPEED_4GBIT; + break; + case LPFC_LINK_SPEED_8GHZ: + ae->un.AttrInt = HBA_PORTSPEED_8GBIT; + break; + case LPFC_LINK_SPEED_10GHZ: + ae->un.AttrInt = HBA_PORTSPEED_10GBIT; + break; + case LPFC_LINK_SPEED_16GHZ: + ae->un.AttrInt = HBA_PORTSPEED_16GBIT; + break; + case LPFC_LINK_SPEED_32GHZ: + ae->un.AttrInt = HBA_PORTSPEED_32GBIT; + break; + default: + ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN; break; } + ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_PORT_SPEED); + return size; +} + +int +lpfc_fdmi_port_attr_max_frame(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct serv_parm *hsp; + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + + hsp = (struct serv_parm *)&vport->fc_sparam; + ae->un.AttrInt = (((uint32_t) hsp->cmn.bbRcvSizeMsb) << 8) | + (uint32_t) hsp->cmn.bbRcvSizeLsb; + ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_MAX_FRAME_SIZE); + return size; +} + +int +lpfc_fdmi_port_attr_os_devname(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct Scsi_Host *shost = lpfc_shost_from_vport(vport); + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), + "/sys/class/scsi_host/host%d", shost->host_no); + len = strnlen((char *)ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_OS_DEVICE_NAME); + return size; +} + +int +lpfc_fdmi_port_attr_host_name(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s", + init_utsname()->nodename); + + len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_HOST_NAME); + return size; +} + +int +lpfc_fdmi_port_attr_wwnn(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(struct lpfc_name)); + + memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName, + sizeof(struct lpfc_name)); + size = FOURBYTES + sizeof(struct lpfc_name); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_NODENAME); + return size; +} + +int +lpfc_fdmi_port_attr_wwpn(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(struct lpfc_name)); + + memcpy(&ae->un.AttrWWN, &vport->fc_sparam.portName, + sizeof(struct lpfc_name)); + size = FOURBYTES + sizeof(struct lpfc_name); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_PORTNAME); + return size; +} + +int +lpfc_fdmi_port_attr_symbolic_name(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + len = lpfc_vport_symbolic_port_name(vport, ae->un.AttrString, 256); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SYM_PORTNAME); + return size; +} + +int +lpfc_fdmi_port_attr_port_type(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) + ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTTYPE_NLPORT); + else + ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTTYPE_NPORT); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_PORT_TYPE); + return size; +} + +int +lpfc_fdmi_port_attr_class(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae->un.AttrInt = cpu_to_be32(FC_COS_CLASS2 | FC_COS_CLASS3); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_CLASS); + return size; +} + +int +lpfc_fdmi_port_attr_fabric_wwpn(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(struct lpfc_name)); + + memcpy(&ae->un.AttrWWN, &vport->fabric_portname, + sizeof(struct lpfc_name)); + size = FOURBYTES + sizeof(struct lpfc_name); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_FABRICNAME); + return size; +} + +int +lpfc_fdmi_port_attr_active_fc4type(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 32); + + ae->un.AttrTypes[3] = 0x02; /* Type 1 - ELS */ + ae->un.AttrTypes[2] = 0x01; /* Type 8 - FCP */ + ae->un.AttrTypes[7] = 0x01; /* Type 32 - CT */ + size = FOURBYTES + 32; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_ACTIVE_FC4_TYPES); + return size; +} + +int +lpfc_fdmi_port_attr_port_state(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + /* Link Up - operational */ + ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTSTATE_ONLINE); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_PORT_STATE); + return size; +} + +int +lpfc_fdmi_port_attr_num_disc(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + vport->fdmi_num_disc = lpfc_find_map_node(vport); + ae->un.AttrInt = cpu_to_be32(vport->fdmi_num_disc); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_DISC_PORT); + return size; +} + +int +lpfc_fdmi_port_attr_nportid(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae->un.AttrInt = cpu_to_be32(vport->fc_myDID); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_PORT_ID); + return size; +} + +int +lpfc_fdmi_smart_attr_service(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, "Smart SAN Initiator", + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SMART_SERVICE); + return size; +} + +int +lpfc_fdmi_smart_attr_guid(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + memcpy(&ae->un.AttrString, &vport->fc_sparam.nodeName, + sizeof(struct lpfc_name)); + memcpy((((uint8_t *)&ae->un.AttrString) + + sizeof(struct lpfc_name)), + &vport->fc_sparam.portName, sizeof(struct lpfc_name)); + size = FOURBYTES + (2 * sizeof(struct lpfc_name)); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SMART_GUID); + return size; +} + +int +lpfc_fdmi_smart_attr_version(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, "Smart SAN Version 1.0", + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SMART_VERSION); + return size; +} + +int +lpfc_fdmi_smart_attr_model(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, phba->ModelName, + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SMART_MODEL); + return size; +} + +int +lpfc_fdmi_smart_attr_port_info(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + + /* SRIOV (type 3) is not supported */ + if (vport->vpi) + ae->un.AttrInt = cpu_to_be32(2); /* NPIV */ + else + ae->un.AttrInt = cpu_to_be32(1); /* Physical */ + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SMART_PORT_INFO); + return size; +} + +int +lpfc_fdmi_smart_attr_qos(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae->un.AttrInt = cpu_to_be32(0); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SMART_QOS); + return size; +} + +int +lpfc_fdmi_smart_attr_security(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae->un.AttrInt = cpu_to_be32(0); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SMART_SECURITY); + return size; } +/* RHBA attribute jump table */ +int (*lpfc_fdmi_hba_action[]) + (struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = { + /* Action routine Mask bit Attribute type */ + lpfc_fdmi_hba_attr_wwnn, /* bit0 RHBA_NODENAME */ + lpfc_fdmi_hba_attr_manufacturer, /* bit1 RHBA_MANUFACTURER */ + lpfc_fdmi_hba_attr_sn, /* bit2 RHBA_SERIAL_NUMBER */ + lpfc_fdmi_hba_attr_model, /* bit3 RHBA_MODEL */ + lpfc_fdmi_hba_attr_description, /* bit4 RHBA_MODEL_DESCRIPTION */ + lpfc_fdmi_hba_attr_hdw_ver, /* bit5 RHBA_HARDWARE_VERSION */ + lpfc_fdmi_hba_attr_drvr_ver, /* bit6 RHBA_DRIVER_VERSION */ + lpfc_fdmi_hba_attr_rom_ver, /* bit7 RHBA_OPTION_ROM_VERSION */ + lpfc_fdmi_hba_attr_fmw_ver, /* bit8 RHBA_FIRMWARE_VERSION */ + lpfc_fdmi_hba_attr_os_ver, /* bit9 RHBA_OS_NAME_VERSION */ + lpfc_fdmi_hba_attr_ct_len, /* bit10 RHBA_MAX_CT_PAYLOAD_LEN */ + lpfc_fdmi_hba_attr_symbolic_name, /* bit11 RHBA_SYM_NODENAME */ + lpfc_fdmi_hba_attr_vendor_info, /* bit12 RHBA_VENDOR_INFO */ + lpfc_fdmi_hba_attr_num_ports, /* bit13 RHBA_NUM_PORTS */ + lpfc_fdmi_hba_attr_fabric_wwnn, /* bit14 RHBA_FABRIC_WWNN */ + lpfc_fdmi_hba_attr_bios_ver, /* bit15 RHBA_BIOS_VERSION */ + lpfc_fdmi_hba_attr_bios_state, /* bit16 RHBA_BIOS_STATE */ + lpfc_fdmi_hba_attr_vendor_id, /* bit17 RHBA_VENDOR_ID */ +}; + +/* RPA / RPRT attribute jump table */ +int (*lpfc_fdmi_port_action[]) + (struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = { + /* Action routine Mask bit Attribute type */ + lpfc_fdmi_port_attr_fc4type, /* bit0 RPRT_SUPPORT_FC4_TYPES */ + lpfc_fdmi_port_attr_support_speed, /* bit1 RPRT_SUPPORTED_SPEED */ + lpfc_fdmi_port_attr_speed, /* bit2 RPRT_PORT_SPEED */ + lpfc_fdmi_port_attr_max_frame, /* bit3 RPRT_MAX_FRAME_SIZE */ + lpfc_fdmi_port_attr_os_devname, /* bit4 RPRT_OS_DEVICE_NAME */ + lpfc_fdmi_port_attr_host_name, /* bit5 RPRT_HOST_NAME */ + lpfc_fdmi_port_attr_wwnn, /* bit6 RPRT_NODENAME */ + lpfc_fdmi_port_attr_wwpn, /* bit7 RPRT_PORTNAME */ + lpfc_fdmi_port_attr_symbolic_name, /* bit8 RPRT_SYM_PORTNAME */ + lpfc_fdmi_port_attr_port_type, /* bit9 RPRT_PORT_TYPE */ + lpfc_fdmi_port_attr_class, /* bit10 RPRT_SUPPORTED_CLASS */ + lpfc_fdmi_port_attr_fabric_wwpn, /* bit11 RPRT_FABRICNAME */ + lpfc_fdmi_port_attr_active_fc4type, /* bit12 RPRT_ACTIVE_FC4_TYPES */ + lpfc_fdmi_port_attr_port_state, /* bit13 RPRT_PORT_STATE */ + lpfc_fdmi_port_attr_num_disc, /* bit14 RPRT_DISC_PORT */ + lpfc_fdmi_port_attr_nportid, /* bit15 RPRT_PORT_ID */ + lpfc_fdmi_smart_attr_service, /* bit16 RPRT_SMART_SERVICE */ + lpfc_fdmi_smart_attr_guid, /* bit17 RPRT_SMART_GUID */ + lpfc_fdmi_smart_attr_version, /* bit18 RPRT_SMART_VERSION */ + lpfc_fdmi_smart_attr_model, /* bit19 RPRT_SMART_MODEL */ + lpfc_fdmi_smart_attr_port_info, /* bit20 RPRT_SMART_PORT_INFO */ + lpfc_fdmi_smart_attr_qos, /* bit21 RPRT_SMART_QOS */ + lpfc_fdmi_smart_attr_security, /* bit22 RPRT_SMART_SECURITY */ +}; +/** + * lpfc_fdmi_cmd - Build and send a FDMI cmd to the specified NPort + * @vport: pointer to a host virtual N_Port data structure. + * @ndlp: ndlp to send FDMI cmd to (if NULL use FDMI_DID) + * cmdcode: FDMI command to send + * mask: Mask of HBA or PORT Attributes to send + * + * Builds and sends a FDMI command using the CT subsystem. + */ int -lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode) +lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, + int cmdcode, uint32_t new_mask) { struct lpfc_hba *phba = vport->phba; struct lpfc_dmabuf *mp, *bmp; struct lpfc_sli_ct_request *CtReq; struct ulp_bde64 *bpl; + uint32_t bit_pos; uint32_t size; uint32_t rsp_size; + uint32_t mask; struct lpfc_fdmi_reg_hba *rh; struct lpfc_fdmi_port_entry *pe; struct lpfc_fdmi_reg_portattr *pab = NULL; struct lpfc_fdmi_attr_block *ab = NULL; - struct lpfc_fdmi_attr_entry *ae; - struct lpfc_fdmi_attr_def *ad; - void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, - struct lpfc_iocbq *); + int (*func)(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad); + void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *, + struct lpfc_iocbq *); - if (ndlp == NULL) { - ndlp = lpfc_findnode_did(vport, FDMI_DID); - if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) - return 0; - cmpl = lpfc_cmpl_ct_cmd_fdmi; /* cmd interface */ - } else { - cmpl = lpfc_cmpl_ct_disc_fdmi; /* called from discovery */ - } + if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) + return 0; + + cmpl = lpfc_cmpl_ct_disc_fdmi; /* called from discovery */ /* fill in BDEs for command */ /* Allocate buffer for command payload */ @@ -1470,573 +2485,99 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode) switch (cmdcode) { case SLI_MGMT_RHAT: case SLI_MGMT_RHBA: - { - lpfc_vpd_t *vp = &phba->vpd; - uint32_t i, j, incr; - int len = 0; + rh = (struct lpfc_fdmi_reg_hba *)&CtReq->un.PortID; + /* HBA Identifier */ + memcpy(&rh->hi.PortName, &phba->pport->fc_sparam.portName, + sizeof(struct lpfc_name)); - rh = (struct lpfc_fdmi_reg_hba *)&CtReq->un.PortID; - /* HBA Identifier */ - memcpy(&rh->hi.PortName, &vport->fc_sparam.portName, + if (cmdcode == SLI_MGMT_RHBA) { + /* Registered Port List */ + /* One entry (port) per adapter */ + rh->rpl.EntryCnt = cpu_to_be32(1); + memcpy(&rh->rpl.pe, &phba->pport->fc_sparam.portName, sizeof(struct lpfc_name)); - if (cmdcode == SLI_MGMT_RHBA) { - /* Registered Port List */ - /* One entry (port) per adapter */ - rh->rpl.EntryCnt = cpu_to_be32(1); - memcpy(&rh->rpl.pe, &vport->fc_sparam.portName, - sizeof(struct lpfc_name)); - - /* point to the HBA attribute block */ - size = 2 * sizeof(struct lpfc_name) + - FOURBYTES; - } else { - size = sizeof(struct lpfc_name); - } - ab = (struct lpfc_fdmi_attr_block *) - ((uint8_t *)rh + size); - ab->EntryCnt = 0; - size += FOURBYTES; - - /* - * Point to beginning of first HBA attribute entry - */ - /* #1 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(struct lpfc_name)); - ad->AttrType = cpu_to_be16(RHBA_NODENAME); - ad->AttrLen = cpu_to_be16(FOURBYTES - + sizeof(struct lpfc_name)); - memcpy(&ae->un.NodeName, &vport->fc_sparam.nodeName, - sizeof(struct lpfc_name)); - ab->EntryCnt++; - size += FOURBYTES + sizeof(struct lpfc_name); - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #2 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.Manufacturer)); - ad->AttrType = cpu_to_be16(RHBA_MANUFACTURER); - strncpy(ae->un.Manufacturer, "Emulex Corporation", - sizeof(ae->un.Manufacturer)); - len = strnlen(ae->un.Manufacturer, - sizeof(ae->un.Manufacturer)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #3 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.SerialNumber)); - ad->AttrType = cpu_to_be16(RHBA_SERIAL_NUMBER); - strncpy(ae->un.SerialNumber, phba->SerialNumber, - sizeof(ae->un.SerialNumber)); - len = strnlen(ae->un.SerialNumber, - sizeof(ae->un.SerialNumber)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #4 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.Model)); - ad->AttrType = cpu_to_be16(RHBA_MODEL); - strncpy(ae->un.Model, phba->ModelName, - sizeof(ae->un.Model)); - len = strnlen(ae->un.Model, sizeof(ae->un.Model)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #5 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.ModelDescription)); - ad->AttrType = cpu_to_be16(RHBA_MODEL_DESCRIPTION); - strncpy(ae->un.ModelDescription, phba->ModelDesc, - sizeof(ae->un.ModelDescription)); - len = strnlen(ae->un.ModelDescription, - sizeof(ae->un.ModelDescription)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; - if ((size + 8) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #6 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 8); - ad->AttrType = cpu_to_be16(RHBA_HARDWARE_VERSION); - ad->AttrLen = cpu_to_be16(FOURBYTES + 8); - /* Convert JEDEC ID to ascii for hardware version */ - incr = vp->rev.biuRev; - for (i = 0; i < 8; i++) { - j = (incr & 0xf); - if (j <= 9) - ae->un.HardwareVersion[7 - i] = - (char)((uint8_t)0x30 + - (uint8_t)j); - else - ae->un.HardwareVersion[7 - i] = - (char)((uint8_t)0x61 + - (uint8_t)(j - 10)); - incr = (incr >> 4); + /* point to the HBA attribute block */ + size = 2 * sizeof(struct lpfc_name) + + FOURBYTES; + } else { + size = sizeof(struct lpfc_name); + } + ab = (struct lpfc_fdmi_attr_block *)((uint8_t *)rh + size); + ab->EntryCnt = 0; + size += FOURBYTES; + bit_pos = 0; + if (new_mask) + mask = new_mask; + else + mask = vport->fdmi_hba_mask; + + /* Mask will dictate what attributes to build in the request */ + while (mask) { + if (mask & 0x1) { + func = lpfc_fdmi_hba_action[bit_pos]; + size += func(vport, + (struct lpfc_fdmi_attr_def *) + ((uint8_t *)rh + size)); + ab->EntryCnt++; + if ((size + 256) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto hba_out; } - ab->EntryCnt++; - size += FOURBYTES + 8; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #7 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.DriverVersion)); - ad->AttrType = cpu_to_be16(RHBA_DRIVER_VERSION); - strncpy(ae->un.DriverVersion, lpfc_release_version, - sizeof(ae->un.DriverVersion)); - len = strnlen(ae->un.DriverVersion, - sizeof(ae->un.DriverVersion)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #8 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.OptionROMVersion)); - ad->AttrType = cpu_to_be16(RHBA_OPTION_ROM_VERSION); - strncpy(ae->un.OptionROMVersion, phba->OptionROMVersion, - sizeof(ae->un.OptionROMVersion)); - len = strnlen(ae->un.OptionROMVersion, - sizeof(ae->un.OptionROMVersion)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #9 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.FirmwareVersion)); - ad->AttrType = cpu_to_be16(RHBA_FIRMWARE_VERSION); - lpfc_decode_firmware_rev(phba, ae->un.FirmwareVersion, - 1); - len = strnlen(ae->un.FirmwareVersion, - sizeof(ae->un.FirmwareVersion)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #10 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.OsNameVersion)); - ad->AttrType = cpu_to_be16(RHBA_OS_NAME_VERSION); - snprintf(ae->un.OsNameVersion, - sizeof(ae->un.OsNameVersion), - "%s %s %s", - init_utsname()->sysname, - init_utsname()->release, - init_utsname()->version); - len = strnlen(ae->un.OsNameVersion, - sizeof(ae->un.OsNameVersion)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #11 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = - cpu_to_be16(RHBA_MAX_CT_PAYLOAD_LEN); - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - ae->un.MaxCTPayloadLen = cpu_to_be32(LPFC_MAX_CT_SIZE); - ab->EntryCnt++; - size += FOURBYTES + 4; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* - * Currently switches don't seem to support the - * following extended HBA attributes. - */ - if (!(vport->cfg_fdmi_on & LPFC_FDMI_ALL_ATTRIB)) - goto hba_out; - - /* #12 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.NodeSymName)); - ad->AttrType = cpu_to_be16(RHBA_SYM_NODENAME); - len = lpfc_vport_symbolic_node_name(vport, - ae->un.NodeSymName, sizeof(ae->un.NodeSymName)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; -hba_out: - ab->EntryCnt = cpu_to_be32(ab->EntryCnt); - /* Total size */ - size = GID_REQUEST_SZ - 4 + size; + mask = mask >> 1; + bit_pos++; } +hba_out: + ab->EntryCnt = cpu_to_be32(ab->EntryCnt); + /* Total size */ + size = GID_REQUEST_SZ - 4 + size; break; case SLI_MGMT_RPRT: case SLI_MGMT_RPA: - { - struct serv_parm *hsp; - int len = 0; - - if (cmdcode == SLI_MGMT_RPRT) { - rh = (struct lpfc_fdmi_reg_hba *) - &CtReq->un.PortID; - /* HBA Identifier */ - memcpy(&rh->hi.PortName, - &vport->fc_sparam.portName, - sizeof(struct lpfc_name)); - pab = (struct lpfc_fdmi_reg_portattr *) - &rh->rpl.EntryCnt; - } else - pab = (struct lpfc_fdmi_reg_portattr *) - &CtReq->un.PortID; - size = sizeof(struct lpfc_name) + FOURBYTES; - memcpy((uint8_t *)&pab->PortName, - (uint8_t *)&vport->fc_sparam.portName, + pab = (struct lpfc_fdmi_reg_portattr *)&CtReq->un.PortID; + if (cmdcode == SLI_MGMT_RPRT) { + rh = (struct lpfc_fdmi_reg_hba *)pab; + /* HBA Identifier */ + memcpy(&rh->hi.PortName, + &phba->pport->fc_sparam.portName, sizeof(struct lpfc_name)); - pab->ab.EntryCnt = 0; - - /* #1 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.FC4Types)); - ad->AttrType = - cpu_to_be16(RPRT_SUPPORTED_FC4_TYPES); - ad->AttrLen = cpu_to_be16(FOURBYTES + 32); - ae->un.FC4Types[0] = 0x40; /* Type 1 - ELS */ - ae->un.FC4Types[1] = 0x80; /* Type 8 - FCP */ - ae->un.FC4Types[4] = 0x80; /* Type 32 - CT */ - pab->ab.EntryCnt++; - size += FOURBYTES + 32; - - /* #2 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_SPEED); - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - ae->un.SupportSpeed = 0; - if (phba->lmt & LMT_32Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_32GBIT; - if (phba->lmt & LMT_16Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_16GBIT; - if (phba->lmt & LMT_10Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_10GBIT; - if (phba->lmt & LMT_8Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_8GBIT; - if (phba->lmt & LMT_4Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_4GBIT; - if (phba->lmt & LMT_2Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_2GBIT; - if (phba->lmt & LMT_1Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_1GBIT; - ae->un.SupportSpeed = - cpu_to_be32(ae->un.SupportSpeed); - - pab->ab.EntryCnt++; - size += FOURBYTES + 4; - - /* #3 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = cpu_to_be16(RPRT_PORT_SPEED); - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - switch (phba->fc_linkspeed) { - case LPFC_LINK_SPEED_1GHZ: - ae->un.PortSpeed = HBA_PORTSPEED_1GBIT; - break; - case LPFC_LINK_SPEED_2GHZ: - ae->un.PortSpeed = HBA_PORTSPEED_2GBIT; - break; - case LPFC_LINK_SPEED_4GHZ: - ae->un.PortSpeed = HBA_PORTSPEED_4GBIT; - break; - case LPFC_LINK_SPEED_8GHZ: - ae->un.PortSpeed = HBA_PORTSPEED_8GBIT; - break; - case LPFC_LINK_SPEED_10GHZ: - ae->un.PortSpeed = HBA_PORTSPEED_10GBIT; - break; - case LPFC_LINK_SPEED_16GHZ: - ae->un.PortSpeed = HBA_PORTSPEED_16GBIT; - break; - case LPFC_LINK_SPEED_32GHZ: - ae->un.PortSpeed = HBA_PORTSPEED_32GBIT; - break; - default: - ae->un.PortSpeed = HBA_PORTSPEED_UNKNOWN; - break; - } - ae->un.PortSpeed = cpu_to_be32(ae->un.PortSpeed); - pab->ab.EntryCnt++; - size += FOURBYTES + 4; - - /* #4 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = cpu_to_be16(RPRT_MAX_FRAME_SIZE); - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - hsp = (struct serv_parm *)&vport->fc_sparam; - ae->un.MaxFrameSize = - (((uint32_t)hsp->cmn. - bbRcvSizeMsb) << 8) | (uint32_t)hsp->cmn. - bbRcvSizeLsb; - ae->un.MaxFrameSize = - cpu_to_be32(ae->un.MaxFrameSize); - pab->ab.EntryCnt++; - size += FOURBYTES + 4; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #5 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.OsDeviceName)); - ad->AttrType = cpu_to_be16(RPRT_OS_DEVICE_NAME); - strncpy((char *)ae->un.OsDeviceName, LPFC_DRIVER_NAME, - sizeof(ae->un.OsDeviceName)); - len = strnlen((char *)ae->un.OsDeviceName, - sizeof(ae->un.OsDeviceName)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - pab->ab.EntryCnt++; - size += FOURBYTES + len; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #6 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.HostName)); - snprintf(ae->un.HostName, sizeof(ae->un.HostName), "%s", - init_utsname()->nodename); - ad->AttrType = cpu_to_be16(RPRT_HOST_NAME); - len = strnlen(ae->un.HostName, - sizeof(ae->un.HostName)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = - cpu_to_be16(FOURBYTES + len); - pab->ab.EntryCnt++; - size += FOURBYTES + len; - if ((size + sizeof(struct lpfc_name)) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; + pab = (struct lpfc_fdmi_reg_portattr *) + ((uint8_t *)pab + sizeof(struct lpfc_name)); + } - /* - * Currently switches don't seem to support the - * following extended Port attributes. - */ - if (!(vport->cfg_fdmi_on & LPFC_FDMI_ALL_ATTRIB)) - goto port_out; - - /* #7 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(struct lpfc_name)); - ad->AttrType = cpu_to_be16(RPRT_NODENAME); - ad->AttrLen = cpu_to_be16(FOURBYTES - + sizeof(struct lpfc_name)); - memcpy(&ae->un.NodeName, &vport->fc_sparam.nodeName, - sizeof(struct lpfc_name)); - pab->ab.EntryCnt++; - size += FOURBYTES + sizeof(struct lpfc_name); - if ((size + sizeof(struct lpfc_name)) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #8 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(struct lpfc_name)); - ad->AttrType = cpu_to_be16(RPRT_PORTNAME); - ad->AttrLen = cpu_to_be16(FOURBYTES - + sizeof(struct lpfc_name)); - memcpy(&ae->un.PortName, &vport->fc_sparam.portName, - sizeof(struct lpfc_name)); - pab->ab.EntryCnt++; - size += FOURBYTES + sizeof(struct lpfc_name); - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #9 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.NodeSymName)); - ad->AttrType = cpu_to_be16(RPRT_SYM_PORTNAME); - len = lpfc_vport_symbolic_port_name(vport, - ae->un.NodeSymName, sizeof(ae->un.NodeSymName)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - pab->ab.EntryCnt++; - size += FOURBYTES + len; - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #10 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = cpu_to_be16(RPRT_PORT_TYPE); - ae->un.PortState = 0; - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - pab->ab.EntryCnt++; - size += FOURBYTES + 4; - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #11 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_CLASS); - ae->un.SupportClass = - cpu_to_be32(FC_COS_CLASS2 | FC_COS_CLASS3); - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - pab->ab.EntryCnt++; - size += FOURBYTES + 4; - if ((size + sizeof(struct lpfc_name)) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #12 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(struct lpfc_name)); - ad->AttrType = cpu_to_be16(RPRT_FABRICNAME); - ad->AttrLen = cpu_to_be16(FOURBYTES - + sizeof(struct lpfc_name)); - memcpy(&ae->un.FabricName, &vport->fabric_nodename, - sizeof(struct lpfc_name)); - pab->ab.EntryCnt++; - size += FOURBYTES + sizeof(struct lpfc_name); - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #13 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.FC4Types)); - ad->AttrType = - cpu_to_be16(RPRT_ACTIVE_FC4_TYPES); - ad->AttrLen = cpu_to_be16(FOURBYTES + 32); - ae->un.FC4Types[0] = 0x40; /* Type 1 - ELS */ - ae->un.FC4Types[1] = 0x80; /* Type 8 - FCP */ - ae->un.FC4Types[4] = 0x80; /* Type 32 - CT */ - pab->ab.EntryCnt++; - size += FOURBYTES + 32; - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #257 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = cpu_to_be16(RPRT_PORT_STATE); - ae->un.PortState = 0; - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - pab->ab.EntryCnt++; - size += FOURBYTES + 4; - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #258 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = cpu_to_be16(RPRT_DISC_PORT); - ae->un.PortState = lpfc_find_map_node(vport); - ae->un.PortState = cpu_to_be32(ae->un.PortState); - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - pab->ab.EntryCnt++; - size += FOURBYTES + 4; - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #259 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = cpu_to_be16(RPRT_PORT_ID); - ae->un.PortId = cpu_to_be32(vport->fc_myDID); - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - pab->ab.EntryCnt++; - size += FOURBYTES + 4; -port_out: - pab->ab.EntryCnt = cpu_to_be32(pab->ab.EntryCnt); - /* Total size */ - size = GID_REQUEST_SZ - 4 + size; + memcpy((uint8_t *)&pab->PortName, + (uint8_t *)&vport->fc_sparam.portName, + sizeof(struct lpfc_name)); + size += sizeof(struct lpfc_name) + FOURBYTES; + pab->ab.EntryCnt = 0; + bit_pos = 0; + if (new_mask) + mask = new_mask; + else + mask = vport->fdmi_port_mask; + + /* Mask will dictate what attributes to build in the request */ + while (mask) { + if (mask & 0x1) { + func = lpfc_fdmi_port_action[bit_pos]; + size += func(vport, + (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size)); + pab->ab.EntryCnt++; + if ((size + 256) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto port_out; + } + mask = mask >> 1; + bit_pos++; } +port_out: + pab->ab.EntryCnt = cpu_to_be32(pab->ab.EntryCnt); + /* Total size */ + if (cmdcode == SLI_MGMT_RPRT) + size += sizeof(struct lpfc_name); + size = GID_REQUEST_SZ - 4 + size; break; case SLI_MGMT_GHAT: @@ -2157,41 +2698,6 @@ lpfc_delayed_disc_timeout_handler(struct lpfc_vport *vport) lpfc_do_scr_ns_plogi(vport->phba, vport); } -void -lpfc_fdmi_tmo(unsigned long ptr) -{ - struct lpfc_vport *vport = (struct lpfc_vport *)ptr; - struct lpfc_hba *phba = vport->phba; - uint32_t tmo_posted; - unsigned long iflag; - - spin_lock_irqsave(&vport->work_port_lock, iflag); - tmo_posted = vport->work_port_events & WORKER_FDMI_TMO; - if (!tmo_posted) - vport->work_port_events |= WORKER_FDMI_TMO; - spin_unlock_irqrestore(&vport->work_port_lock, iflag); - - if (!tmo_posted) - lpfc_worker_wake_up(phba); - return; -} - -void -lpfc_fdmi_timeout_handler(struct lpfc_vport *vport) -{ - struct lpfc_nodelist *ndlp; - - ndlp = lpfc_findnode_did(vport, FDMI_DID); - if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { - if (init_utsname()->nodename[0] != '\0') - lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA); - else - mod_timer(&vport->fc_fdmitmo, jiffies + - msecs_to_jiffies(1000 * 60)); - } - return; -} - void lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag) { diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index d508378510f10..3394648d80ff9 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -688,6 +688,21 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, sp->cmn.bbRcvSizeLsb; fabric_param_changed = lpfc_check_clean_addr_bit(vport, sp); + if (fabric_param_changed) { + /* Reset FDMI attribute masks based on config parameter */ + if (phba->cfg_fdmi_on == LPFC_FDMI_NO_SUPPORT) { + vport->fdmi_hba_mask = 0; + vport->fdmi_port_mask = 0; + } else { + /* Setup appropriate attribute masks */ + vport->fdmi_hba_mask = LPFC_FDMI2_HBA_ATTR; + if (phba->cfg_fdmi_on == LPFC_FDMI_SMART_SAN) + vport->fdmi_port_mask = LPFC_FDMI2_SMART_ATTR; + else + vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR; + } + + } memcpy(&vport->fabric_portname, &sp->portName, sizeof(struct lpfc_name)); memcpy(&vport->fabric_nodename, &sp->nodeName, @@ -4690,6 +4705,23 @@ lpfc_rdp_res_link_error(struct fc_rdp_link_error_status_desc *desc, desc->length = cpu_to_be32(sizeof(desc->info)); } +int +lpfc_rdp_res_fec_desc(struct fc_fec_rdp_desc *desc, READ_LNK_VAR *stat) +{ + if (bf_get(lpfc_read_link_stat_gec2, stat) == 0) + return 0; + desc->tag = cpu_to_be32(RDP_FEC_DESC_TAG); + + desc->info.CorrectedBlocks = + cpu_to_be32(stat->fecCorrBlkCount); + desc->info.UncorrectableBlocks = + cpu_to_be32(stat->fecUncorrBlkCount); + + desc->length = cpu_to_be32(sizeof(desc->info)); + + return sizeof(struct fc_fec_rdp_desc); +} + void lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba) { @@ -4800,7 +4832,7 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context, struct ls_rjt *stat; struct fc_rdp_res_frame *rdp_res; uint32_t cmdsize; - int rc; + int rc, fec_size; if (status != SUCCESS) goto error; @@ -4840,8 +4872,9 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context, lpfc_rdp_res_diag_port_names(&rdp_res->diag_port_names_desc, phba); lpfc_rdp_res_attach_port_names(&rdp_res->attached_port_names_desc, vport, ndlp); - rdp_res->length = cpu_to_be32(RDP_DESC_PAYLOAD_SIZE); - + fec_size = lpfc_rdp_res_fec_desc(&rdp_res->fec_desc, + &rdp_context->link_stat); + rdp_res->length = cpu_to_be32(fec_size + RDP_DESC_PAYLOAD_SIZE); elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; phba->fc_stat.elsXmitACC++; @@ -7704,6 +7737,35 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, } } +void +lpfc_start_fdmi(struct lpfc_vport *vport) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_nodelist *ndlp; + + /* If this is the first time, allocate an ndlp and initialize + * it. Otherwise, make sure the node is enabled and then do the + * login. + */ + ndlp = lpfc_findnode_did(vport, FDMI_DID); + if (!ndlp) { + ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); + if (ndlp) { + lpfc_nlp_init(vport, ndlp, FDMI_DID); + ndlp->nlp_type |= NLP_FABRIC; + } else { + return; + } + } + if (!NLP_CHK_NODE_ACT(ndlp)) + ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_NPR_NODE); + + if (ndlp) { + lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); + lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); + } +} + /** * lpfc_do_scr_ns_plogi - Issue a plogi to the name server for scr * @phba: pointer to lpfc hba data structure. @@ -7720,7 +7782,7 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, void lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) { - struct lpfc_nodelist *ndlp, *ndlp_fdmi; + struct lpfc_nodelist *ndlp; struct Scsi_Host *shost = lpfc_shost_from_vport(vport); /* @@ -7778,32 +7840,9 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) return; } - if (vport->cfg_fdmi_on & LPFC_FDMI_SUPPORT) { - /* If this is the first time, allocate an ndlp and initialize - * it. Otherwise, make sure the node is enabled and then do the - * login. - */ - ndlp_fdmi = lpfc_findnode_did(vport, FDMI_DID); - if (!ndlp_fdmi) { - ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool, - GFP_KERNEL); - if (ndlp_fdmi) { - lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID); - ndlp_fdmi->nlp_type |= NLP_FABRIC; - } else - return; - } - if (!NLP_CHK_NODE_ACT(ndlp_fdmi)) - ndlp_fdmi = lpfc_enable_node(vport, - ndlp_fdmi, - NLP_STE_NPR_NODE); - - if (ndlp_fdmi) { - lpfc_nlp_set_state(vport, ndlp_fdmi, - NLP_STE_PLOGI_ISSUE); - lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID, 0); - } - } + if ((phba->cfg_fdmi_on > LPFC_FDMI_NO_SUPPORT) && + (vport->load_flag & FC_ALLOW_FDMI)) + lpfc_start_fdmi(vport); } /** diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index d3668aa555d53..1bad678c34477 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -674,8 +674,6 @@ lpfc_work_done(struct lpfc_hba *phba) lpfc_mbox_timeout_handler(phba); if (work_port_events & WORKER_FABRIC_BLOCK_TMO) lpfc_unblock_fabric_iocbs(phba); - if (work_port_events & WORKER_FDMI_TMO) - lpfc_fdmi_timeout_handler(vport); if (work_port_events & WORKER_RAMP_DOWN_QUEUE) lpfc_ramp_down_queue_handler(phba); if (work_port_events & WORKER_DELAYED_DISC_TMO) @@ -5554,15 +5552,15 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ndlp->nlp_usg_map, ndlp); /* * Start issuing Fabric-Device Management Interface (FDMI) command to - * 0xfffffa (FDMI well known port) or Delay issuing FDMI command if - * fdmi-on=2 (supporting RPA/hostnmae) + * 0xfffffa (FDMI well known port). + * DHBA -> DPRT -> RHBA -> RPA (physical port) + * DPRT -> RPRT (vports) */ - - if (vport->cfg_fdmi_on & LPFC_FDMI_REG_DELAY) - mod_timer(&vport->fc_fdmitmo, - jiffies + msecs_to_jiffies(1000 * 60)); + if (vport->port_type == LPFC_PHYSICAL_PORT) + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0); else - lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA); + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT, 0); + /* decrement the node reference count held for this callback * function. diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 2cce88e967ce1..dd20412c7e4c5 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -1097,6 +1097,18 @@ struct fc_rdp_port_name_desc { }; +struct fc_rdp_fec_info { + uint32_t CorrectedBlocks; + uint32_t UncorrectableBlocks; +}; + +#define RDP_FEC_DESC_TAG 0x00010005 +struct fc_fec_rdp_desc { + uint32_t tag; + uint32_t length; + struct fc_rdp_fec_info info; +}; + struct fc_rdp_link_error_status_payload_info { struct fc_link_status link_status; /* 24 bytes */ uint32_t port_type; /* bits 31-30 only */ @@ -1196,14 +1208,15 @@ struct fc_rdp_res_frame { struct fc_rdp_link_error_status_desc link_error_desc; /* Word 13-21 */ struct fc_rdp_port_name_desc diag_port_names_desc; /* Word 22-27 */ struct fc_rdp_port_name_desc attached_port_names_desc;/* Word 28-33 */ + struct fc_fec_rdp_desc fec_desc; /* FC Word 34 - 37 */ }; #define RDP_DESC_PAYLOAD_SIZE (sizeof(struct fc_rdp_link_service_desc) \ - + sizeof(struct fc_rdp_sfp_desc) \ - + sizeof(struct fc_rdp_port_speed_desc) \ - + sizeof(struct fc_rdp_link_error_status_desc) \ - + (sizeof(struct fc_rdp_port_name_desc) * 2)) + + sizeof(struct fc_rdp_sfp_desc) \ + + sizeof(struct fc_rdp_port_speed_desc) \ + + sizeof(struct fc_rdp_link_error_status_desc) \ + + (sizeof(struct fc_rdp_port_name_desc) * 2)) /******** FDMI ********/ @@ -1233,31 +1246,10 @@ struct lpfc_fdmi_attr_def { /* Defined in TLV format */ /* Attribute Entry */ struct lpfc_fdmi_attr_entry { union { - uint32_t VendorSpecific; - uint32_t SupportClass; - uint32_t SupportSpeed; - uint32_t PortSpeed; - uint32_t MaxFrameSize; - uint32_t MaxCTPayloadLen; - uint32_t PortState; - uint32_t PortId; - struct lpfc_name NodeName; - struct lpfc_name PortName; - struct lpfc_name FabricName; - uint8_t FC4Types[32]; - uint8_t Manufacturer[64]; - uint8_t SerialNumber[64]; - uint8_t Model[256]; - uint8_t ModelDescription[256]; - uint8_t HardwareVersion[256]; - uint8_t DriverVersion[256]; - uint8_t OptionROMVersion[256]; - uint8_t FirmwareVersion[256]; - uint8_t OsHostName[256]; - uint8_t NodeSymName[256]; - uint8_t OsDeviceName[256]; - uint8_t OsNameVersion[256]; - uint8_t HostName[256]; + uint32_t AttrInt; + uint8_t AttrTypes[32]; + uint8_t AttrString[256]; + struct lpfc_name AttrWWN; } un; }; @@ -1327,6 +1319,8 @@ struct lpfc_fdmi_reg_portattr { #define SLI_MGMT_DPRT 0x310 /* De-register Port */ #define SLI_MGMT_DPA 0x311 /* De-register Port attributes */ +#define LPFC_FDMI_MAX_RETRY 3 /* Max retries for a FDMI command */ + /* * HBA Attribute Types */ @@ -1342,6 +1336,39 @@ struct lpfc_fdmi_reg_portattr { #define RHBA_OS_NAME_VERSION 0xa /* 4 to 256 byte ASCII string */ #define RHBA_MAX_CT_PAYLOAD_LEN 0xb /* 32-bit unsigned int */ #define RHBA_SYM_NODENAME 0xc /* 4 to 256 byte ASCII string */ +#define RHBA_VENDOR_INFO 0xd /* 32-bit unsigned int */ +#define RHBA_NUM_PORTS 0xe /* 32-bit unsigned int */ +#define RHBA_FABRIC_WWNN 0xf /* 8 byte WWNN */ +#define RHBA_BIOS_VERSION 0x10 /* 4 to 256 byte ASCII string */ +#define RHBA_BIOS_STATE 0x11 /* 32-bit unsigned int */ +#define RHBA_VENDOR_ID 0xe0 /* 8 byte ASCII string */ + +/* Bit mask for all individual HBA attributes */ +#define LPFC_FDMI_HBA_ATTR_wwnn 0x00000001 +#define LPFC_FDMI_HBA_ATTR_manufacturer 0x00000002 +#define LPFC_FDMI_HBA_ATTR_sn 0x00000004 +#define LPFC_FDMI_HBA_ATTR_model 0x00000008 +#define LPFC_FDMI_HBA_ATTR_description 0x00000010 +#define LPFC_FDMI_HBA_ATTR_hdw_ver 0x00000020 +#define LPFC_FDMI_HBA_ATTR_drvr_ver 0x00000040 +#define LPFC_FDMI_HBA_ATTR_rom_ver 0x00000080 +#define LPFC_FDMI_HBA_ATTR_fmw_ver 0x00000100 +#define LPFC_FDMI_HBA_ATTR_os_ver 0x00000200 +#define LPFC_FDMI_HBA_ATTR_ct_len 0x00000400 +#define LPFC_FDMI_HBA_ATTR_symbolic_name 0x00000800 +#define LPFC_FDMI_HBA_ATTR_vendor_info 0x00001000 /* Not used */ +#define LPFC_FDMI_HBA_ATTR_num_ports 0x00002000 +#define LPFC_FDMI_HBA_ATTR_fabric_wwnn 0x00004000 +#define LPFC_FDMI_HBA_ATTR_bios_ver 0x00008000 +#define LPFC_FDMI_HBA_ATTR_bios_state 0x00010000 /* Not used */ +#define LPFC_FDMI_HBA_ATTR_vendor_id 0x00020000 + +/* Bit mask for FDMI-1 defined HBA attributes */ +#define LPFC_FDMI1_HBA_ATTR 0x000007ff + +/* Bit mask for FDMI-2 defined HBA attributes */ +/* Skip vendor_info and bios_state */ +#define LPFC_FDMI2_HBA_ATTR 0x0002efff /* * Port Attrubute Types @@ -1353,15 +1380,65 @@ struct lpfc_fdmi_reg_portattr { #define RPRT_OS_DEVICE_NAME 0x5 /* 4 to 256 byte ASCII string */ #define RPRT_HOST_NAME 0x6 /* 4 to 256 byte ASCII string */ #define RPRT_NODENAME 0x7 /* 8 byte WWNN */ -#define RPRT_PORTNAME 0x8 /* 8 byte WWNN */ +#define RPRT_PORTNAME 0x8 /* 8 byte WWPN */ #define RPRT_SYM_PORTNAME 0x9 /* 4 to 256 byte ASCII string */ #define RPRT_PORT_TYPE 0xa /* 32-bit unsigned int */ #define RPRT_SUPPORTED_CLASS 0xb /* 32-bit unsigned int */ -#define RPRT_FABRICNAME 0xc /* 8 byte Fabric WWNN */ +#define RPRT_FABRICNAME 0xc /* 8 byte Fabric WWPN */ #define RPRT_ACTIVE_FC4_TYPES 0xd /* 32 byte binary array */ #define RPRT_PORT_STATE 0x101 /* 32-bit unsigned int */ #define RPRT_DISC_PORT 0x102 /* 32-bit unsigned int */ #define RPRT_PORT_ID 0x103 /* 32-bit unsigned int */ +#define RPRT_SMART_SERVICE 0xf100 /* 4 to 256 byte ASCII string */ +#define RPRT_SMART_GUID 0xf101 /* 8 byte WWNN + 8 byte WWPN */ +#define RPRT_SMART_VERSION 0xf102 /* 4 to 256 byte ASCII string */ +#define RPRT_SMART_MODEL 0xf103 /* 4 to 256 byte ASCII string */ +#define RPRT_SMART_PORT_INFO 0xf104 /* 32-bit unsigned int */ +#define RPRT_SMART_QOS 0xf105 /* 32-bit unsigned int */ +#define RPRT_SMART_SECURITY 0xf106 /* 32-bit unsigned int */ + +/* Bit mask for all individual PORT attributes */ +#define LPFC_FDMI_PORT_ATTR_fc4type 0x00000001 +#define LPFC_FDMI_PORT_ATTR_support_speed 0x00000002 +#define LPFC_FDMI_PORT_ATTR_speed 0x00000004 +#define LPFC_FDMI_PORT_ATTR_max_frame 0x00000008 +#define LPFC_FDMI_PORT_ATTR_os_devname 0x00000010 +#define LPFC_FDMI_PORT_ATTR_host_name 0x00000020 +#define LPFC_FDMI_PORT_ATTR_wwnn 0x00000040 +#define LPFC_FDMI_PORT_ATTR_wwpn 0x00000080 +#define LPFC_FDMI_PORT_ATTR_symbolic_name 0x00000100 +#define LPFC_FDMI_PORT_ATTR_port_type 0x00000200 +#define LPFC_FDMI_PORT_ATTR_class 0x00000400 +#define LPFC_FDMI_PORT_ATTR_fabric_wwpn 0x00000800 +#define LPFC_FDMI_PORT_ATTR_port_state 0x00001000 +#define LPFC_FDMI_PORT_ATTR_active_fc4type 0x00002000 +#define LPFC_FDMI_PORT_ATTR_num_disc 0x00004000 +#define LPFC_FDMI_PORT_ATTR_nportid 0x00008000 +#define LPFC_FDMI_SMART_ATTR_service 0x00010000 /* Vendor specific */ +#define LPFC_FDMI_SMART_ATTR_guid 0x00020000 /* Vendor specific */ +#define LPFC_FDMI_SMART_ATTR_version 0x00040000 /* Vendor specific */ +#define LPFC_FDMI_SMART_ATTR_model 0x00080000 /* Vendor specific */ +#define LPFC_FDMI_SMART_ATTR_port_info 0x00100000 /* Vendor specific */ +#define LPFC_FDMI_SMART_ATTR_qos 0x00200000 /* Vendor specific */ +#define LPFC_FDMI_SMART_ATTR_security 0x00400000 /* Vendor specific */ + +/* Bit mask for FDMI-1 defined PORT attributes */ +#define LPFC_FDMI1_PORT_ATTR 0x0000003f + +/* Bit mask for FDMI-2 defined PORT attributes */ +#define LPFC_FDMI2_PORT_ATTR 0x0000ffff + +/* Bit mask for Smart SAN defined PORT attributes */ +#define LPFC_FDMI2_SMART_ATTR 0x007fffff + +/* Defines for PORT port state attribute */ +#define LPFC_FDMI_PORTSTATE_UNKNOWN 1 +#define LPFC_FDMI_PORTSTATE_ONLINE 2 + +/* Defines for PORT port type attribute */ +#define LPFC_FDMI_PORTTYPE_UNKNOWN 0 +#define LPFC_FDMI_PORTTYPE_NPORT 1 +#define LPFC_FDMI_PORTTYPE_NLPORT 2 /* * Begin HBA configuration parameters. @@ -2498,10 +2575,38 @@ typedef struct { /* Structure for MB Command READ_LINK_STAT (18) */ typedef struct { - uint32_t rsvd1; + uint32_t word0; + +#define lpfc_read_link_stat_rec_SHIFT 0 +#define lpfc_read_link_stat_rec_MASK 0x1 +#define lpfc_read_link_stat_rec_WORD word0 + +#define lpfc_read_link_stat_gec_SHIFT 1 +#define lpfc_read_link_stat_gec_MASK 0x1 +#define lpfc_read_link_stat_gec_WORD word0 + +#define lpfc_read_link_stat_w02oftow23of_SHIFT 2 +#define lpfc_read_link_stat_w02oftow23of_MASK 0x3FFFFF +#define lpfc_read_link_stat_w02oftow23of_WORD word0 + +#define lpfc_read_link_stat_rsvd_SHIFT 24 +#define lpfc_read_link_stat_rsvd_MASK 0x1F +#define lpfc_read_link_stat_rsvd_WORD word0 + +#define lpfc_read_link_stat_gec2_SHIFT 29 +#define lpfc_read_link_stat_gec2_MASK 0x1 +#define lpfc_read_link_stat_gec2_WORD word0 + +#define lpfc_read_link_stat_clrc_SHIFT 30 +#define lpfc_read_link_stat_clrc_MASK 0x1 +#define lpfc_read_link_stat_clrc_WORD word0 + +#define lpfc_read_link_stat_clof_SHIFT 31 +#define lpfc_read_link_stat_clof_MASK 0x1 +#define lpfc_read_link_stat_clof_WORD word0 + uint32_t linkFailureCnt; uint32_t lossSyncCnt; - uint32_t lossSignalCnt; uint32_t primSeqErrCnt; uint32_t invalidXmitWord; @@ -2509,6 +2614,19 @@ typedef struct { uint32_t primSeqTimeout; uint32_t elasticOverrun; uint32_t arbTimeout; + uint32_t advRecBufCredit; + uint32_t curRecBufCredit; + uint32_t advTransBufCredit; + uint32_t curTransBufCredit; + uint32_t recEofCount; + uint32_t recEofdtiCount; + uint32_t recEofniCount; + uint32_t recSofcount; + uint32_t rsvd1; + uint32_t rsvd2; + uint32_t recDrpXriCount; + uint32_t fecCorrBlkCount; + uint32_t fecUncorrBlkCount; } READ_LNK_VAR; /* Structure for MB Command REG_LOGIN (19) */ diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 5915407d19aa9..d9753e3e97375 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1184,8 +1184,10 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) vports = lpfc_create_vport_work_array(phba); if (vports != NULL) - for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) + for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { lpfc_rcv_seq_check_edtov(vports[i]); + lpfc_fdmi_num_disc_check(vports[i]); + } lpfc_destroy_vport_work_array(phba, vports); if ((phba->link_state == LPFC_HBA_ERROR) || @@ -1290,6 +1292,10 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) jiffies + msecs_to_jiffies(1000 * LPFC_HB_MBOX_TIMEOUT)); } + } else { + mod_timer(&phba->hb_tmofunc, + jiffies + + msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL)); } } @@ -2621,7 +2627,6 @@ void lpfc_stop_vport_timers(struct lpfc_vport *vport) { del_timer_sync(&vport->els_tmofunc); - del_timer_sync(&vport->fc_fdmitmo); del_timer_sync(&vport->delayed_disc_tmo); lpfc_can_disctmo(vport); return; @@ -3340,10 +3345,6 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) vport->fc_disctmo.function = lpfc_disc_timeout; vport->fc_disctmo.data = (unsigned long)vport; - init_timer(&vport->fc_fdmitmo); - vport->fc_fdmitmo.function = lpfc_fdmi_tmo; - vport->fc_fdmitmo.data = (unsigned long)vport; - init_timer(&vport->els_tmofunc); vport->els_tmofunc.function = lpfc_els_timeout; vport->els_tmofunc.data = (unsigned long)vport; @@ -6159,6 +6160,20 @@ lpfc_create_shost(struct lpfc_hba *phba) /* Put reference to SCSI host to driver's device private data */ pci_set_drvdata(phba->pcidev, shost); + /* + * At this point we are fully registered with PSA. In addition, + * any initial discovery should be completed. + */ + vport->load_flag |= FC_ALLOW_FDMI; + if (phba->cfg_fdmi_on > LPFC_FDMI_NO_SUPPORT) { + + /* Setup appropriate attribute masks */ + vport->fdmi_hba_mask = LPFC_FDMI2_HBA_ATTR; + if (phba->cfg_fdmi_on == LPFC_FDMI_SMART_SAN) + vport->fdmi_port_mask = LPFC_FDMI2_SMART_ATTR; + else + vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR; + } return 0; } diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 769012663a8f5..b3f85def18ccc 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -393,6 +393,14 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) *(struct lpfc_vport **)fc_vport->dd_data = vport; vport->fc_vport = fc_vport; + /* At this point we are fully registered with SCSI Layer. */ + vport->load_flag |= FC_ALLOW_FDMI; + if (phba->cfg_fdmi_on > LPFC_FDMI_NO_SUPPORT) { + /* Setup appropriate attribute masks */ + vport->fdmi_hba_mask = phba->pport->fdmi_hba_mask; + vport->fdmi_port_mask = phba->pport->fdmi_port_mask; + } + /* * In SLI4, the vpi must be activated before it can be used * by the port. -- GitLab From 81e7517723fc17396ba91f59312b3177266ddbda Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:11:59 -0500 Subject: [PATCH 1969/2855] lpfc: Fix RDP Speed reporting. Fix RDP Speed reporting. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 3394648d80ff9..f7a29676dc75e 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -4730,28 +4730,25 @@ lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba) desc->tag = cpu_to_be32(RDP_PORT_SPEED_DESC_TAG); - switch (phba->sli4_hba.link_state.speed) { - case LPFC_FC_LA_SPEED_1G: + switch (phba->fc_linkspeed) { + case LPFC_LINK_SPEED_1GHZ: rdp_speed = RDP_PS_1GB; break; - case LPFC_FC_LA_SPEED_2G: + case LPFC_LINK_SPEED_2GHZ: rdp_speed = RDP_PS_2GB; break; - case LPFC_FC_LA_SPEED_4G: + case LPFC_LINK_SPEED_4GHZ: rdp_speed = RDP_PS_4GB; break; - case LPFC_FC_LA_SPEED_8G: + case LPFC_LINK_SPEED_8GHZ: rdp_speed = RDP_PS_8GB; break; - case LPFC_FC_LA_SPEED_10G: + case LPFC_LINK_SPEED_10GHZ: rdp_speed = RDP_PS_10GB; break; - case LPFC_FC_LA_SPEED_16G: + case LPFC_LINK_SPEED_16GHZ: rdp_speed = RDP_PS_16GB; break; - case LPFC_FC_LA_SPEED_32G: - rdp_speed = RDP_PS_32GB; - break; default: rdp_speed = RDP_PS_UNKNOWN; break; -- GitLab From eb8d68c9930f7f9c8f3f4a6059b051b32077a735 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:12:00 -0500 Subject: [PATCH 1970/2855] lpfc: Fix RDP ACC being too long. Fix RDP ACC being too long. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index f7a29676dc75e..817cdfcd51a84 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -4824,6 +4824,7 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context, struct lpfc_nodelist *ndlp = rdp_context->ndlp; struct lpfc_vport *vport = ndlp->vport; struct lpfc_iocbq *elsiocb; + struct ulp_bde64 *bpl; IOCB_t *icmd; uint8_t *pcmd; struct ls_rjt *stat; @@ -4833,6 +4834,8 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context, if (status != SUCCESS) goto error; + + /* This will change once we know the true size of the RDP payload */ cmdsize = sizeof(struct fc_rdp_res_frame); elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, @@ -4874,6 +4877,13 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context, rdp_res->length = cpu_to_be32(fec_size + RDP_DESC_PAYLOAD_SIZE); elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; + /* Now that we know the true size of the payload, update the BPL */ + bpl = (struct ulp_bde64 *) + (((struct lpfc_dmabuf *)(elsiocb->context3))->virt); + bpl->tus.f.bdeSize = (fec_size + RDP_DESC_PAYLOAD_SIZE + 8); + bpl->tus.f.bdeFlags = 0; + bpl->tus.w = le32_to_cpu(bpl->tus.w); + phba->fc_stat.elsXmitACC++; rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); if (rc == IOCB_ERROR) -- GitLab From 5afab6bbf3f026b7d50451acbfdc12300c5f4353 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:12:01 -0500 Subject: [PATCH 1971/2855] lpfc: Make write check error processing more resilient Make write check error processing more resilient. Checks to catch writes that fw reports weren't fully complete yet SCSI status indicated fine needed correction. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_scsi.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index ab446f83fba6f..964a996dea2cc 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -3676,6 +3676,7 @@ static void lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_iocbq *rsp_iocb) { + struct lpfc_hba *phba = vport->phba; struct scsi_cmnd *cmnd = lpfc_cmd->pCmd; struct fcp_cmnd *fcpcmd = lpfc_cmd->fcp_cmnd; struct fcp_rsp *fcprsp = lpfc_cmd->fcp_rsp; @@ -3685,6 +3686,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, uint32_t *lp; uint32_t host_status = DID_OK; uint32_t rsplen = 0; + uint32_t fcpDl; uint32_t logit = LOG_FCP | LOG_FCP_ERROR; @@ -3755,13 +3757,14 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, fcprsp->rspInfo3); scsi_set_resid(cmnd, 0); + fcpDl = be32_to_cpu(fcpcmd->fcpDl); if (resp_info & RESID_UNDER) { scsi_set_resid(cmnd, be32_to_cpu(fcprsp->rspResId)); lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP_UNDER, "9025 FCP Read Underrun, expected %d, " "residual %d Data: x%x x%x x%x\n", - be32_to_cpu(fcpcmd->fcpDl), + fcpDl, scsi_get_resid(cmnd), fcpi_parm, cmnd->cmnd[0], cmnd->underflow); @@ -3777,7 +3780,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, LOG_FCP | LOG_FCP_ERROR, "9026 FCP Read Check Error " "and Underrun Data: x%x x%x x%x x%x\n", - be32_to_cpu(fcpcmd->fcpDl), + fcpDl, scsi_get_resid(cmnd), fcpi_parm, cmnd->cmnd[0]); scsi_set_resid(cmnd, scsi_bufflen(cmnd)); @@ -3812,13 +3815,25 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, * Check SLI validation that all the transfer was actually done * (fcpi_parm should be zero). Apply check only to reads. */ - } else if (fcpi_parm && (cmnd->sc_data_direction == DMA_FROM_DEVICE)) { + } else if (fcpi_parm) { lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP | LOG_FCP_ERROR, - "9029 FCP Read Check Error Data: " + "9029 FCP %s Check Error xri x%x Data: " "x%x x%x x%x x%x x%x\n", - be32_to_cpu(fcpcmd->fcpDl), - be32_to_cpu(fcprsp->rspResId), + ((cmnd->sc_data_direction == DMA_FROM_DEVICE) ? + "Read" : "Write"), + ((phba->sli_rev == LPFC_SLI_REV4) ? + lpfc_cmd->cur_iocbq.sli4_xritag : + rsp_iocb->iocb.ulpContext), + fcpDl, be32_to_cpu(fcprsp->rspResId), fcpi_parm, cmnd->cmnd[0], scsi_status); + + /* There is some issue with the LPe12000 that causes it + * to miscalculate the fcpi_parm and falsely trip this + * recovery logic. Detect this case and don't error when true. + */ + if (fcpi_parm > fcpDl) + goto out; + switch (scsi_status) { case SAM_STAT_GOOD: case SAM_STAT_CHECK_CONDITION: -- GitLab From a085e87c814567c94e5d375e7362f9f25030aac1 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:12:02 -0500 Subject: [PATCH 1972/2855] lpfc: Use new FDMI speed definitions for 10G, 25G and 40G FCoE. Use new FDMI speed definitions for 10G, 25G and 40G FCoE. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_attr.c | 2 +- drivers/scsi/lpfc/lpfc_ct.c | 146 +++++++++++++++++++++---------- drivers/scsi/lpfc/lpfc_els.c | 3 + drivers/scsi/lpfc/lpfc_hbadisc.c | 29 +++--- drivers/scsi/lpfc/lpfc_hw4.h | 1 + drivers/scsi/lpfc/lpfc_init.c | 95 +++++++------------- drivers/scsi/lpfc/lpfc_scsi.c | 10 +-- 7 files changed, 150 insertions(+), 136 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 5739c260038ac..343ae9482891c 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -5255,7 +5255,7 @@ lpfc_get_host_speed(struct Scsi_Host *shost) spin_lock_irq(shost->host_lock); - if (lpfc_is_link_up(phba)) { + if ((lpfc_is_link_up(phba)) && (!(phba->hba_flag & HBA_FCOE_MODE))) { switch(phba->fc_linkspeed) { case LPFC_LINK_SPEED_1GHZ: fc_host_speed(shost) = FC_PORTSPEED_1GBIT; diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index ac6e087f6857c..79e261d2a0c87 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -48,15 +48,26 @@ #include "lpfc_vport.h" #include "lpfc_debugfs.h" -/* FDMI Port Speed definitions */ -#define HBA_PORTSPEED_1GBIT 0x0001 /* 1 GBit/sec */ -#define HBA_PORTSPEED_2GBIT 0x0002 /* 2 GBit/sec */ -#define HBA_PORTSPEED_4GBIT 0x0008 /* 4 GBit/sec */ -#define HBA_PORTSPEED_10GBIT 0x0004 /* 10 GBit/sec */ -#define HBA_PORTSPEED_8GBIT 0x0010 /* 8 GBit/sec */ -#define HBA_PORTSPEED_16GBIT 0x0020 /* 16 GBit/sec */ -#define HBA_PORTSPEED_32GBIT 0x0040 /* 32 GBit/sec */ -#define HBA_PORTSPEED_UNKNOWN 0x0800 /* Unknown */ +/* FDMI Port Speed definitions - FC-GS-7 */ +#define HBA_PORTSPEED_1GFC 0x00000001 /* 1G FC */ +#define HBA_PORTSPEED_2GFC 0x00000002 /* 2G FC */ +#define HBA_PORTSPEED_4GFC 0x00000008 /* 4G FC */ +#define HBA_PORTSPEED_10GFC 0x00000004 /* 10G FC */ +#define HBA_PORTSPEED_8GFC 0x00000010 /* 8G FC */ +#define HBA_PORTSPEED_16GFC 0x00000020 /* 16G FC */ +#define HBA_PORTSPEED_32GFC 0x00000040 /* 32G FC */ +#define HBA_PORTSPEED_20GFC 0x00000080 /* 20G FC */ +#define HBA_PORTSPEED_40GFC 0x00000100 /* 40G FC */ +#define HBA_PORTSPEED_128GFC 0x00000200 /* 128G FC */ +#define HBA_PORTSPEED_64GFC 0x00000400 /* 64G FC */ +#define HBA_PORTSPEED_256GFC 0x00000800 /* 256G FC */ +#define HBA_PORTSPEED_UNKNOWN 0x00008000 /* Unknown */ +#define HBA_PORTSPEED_10GE 0x00010000 /* 10G E */ +#define HBA_PORTSPEED_40GE 0x00020000 /* 40G E */ +#define HBA_PORTSPEED_100GE 0x00040000 /* 100G E */ +#define HBA_PORTSPEED_25GE 0x00080000 /* 25G E */ +#define HBA_PORTSPEED_50GE 0x00100000 /* 50G E */ +#define HBA_PORTSPEED_400GE 0x00200000 /* 400G E */ #define FOURBYTES 4 @@ -1921,20 +1932,38 @@ lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport, ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; ae->un.AttrInt = 0; - if (phba->lmt & LMT_32Gb) - ae->un.AttrInt |= HBA_PORTSPEED_32GBIT; - if (phba->lmt & LMT_16Gb) - ae->un.AttrInt |= HBA_PORTSPEED_16GBIT; - if (phba->lmt & LMT_10Gb) - ae->un.AttrInt |= HBA_PORTSPEED_10GBIT; - if (phba->lmt & LMT_8Gb) - ae->un.AttrInt |= HBA_PORTSPEED_8GBIT; - if (phba->lmt & LMT_4Gb) - ae->un.AttrInt |= HBA_PORTSPEED_4GBIT; - if (phba->lmt & LMT_2Gb) - ae->un.AttrInt |= HBA_PORTSPEED_2GBIT; - if (phba->lmt & LMT_1Gb) - ae->un.AttrInt |= HBA_PORTSPEED_1GBIT; + if (!(phba->hba_flag & HBA_FCOE_MODE)) { + if (phba->lmt & LMT_32Gb) + ae->un.AttrInt |= HBA_PORTSPEED_32GFC; + if (phba->lmt & LMT_16Gb) + ae->un.AttrInt |= HBA_PORTSPEED_16GFC; + if (phba->lmt & LMT_10Gb) + ae->un.AttrInt |= HBA_PORTSPEED_10GFC; + if (phba->lmt & LMT_8Gb) + ae->un.AttrInt |= HBA_PORTSPEED_8GFC; + if (phba->lmt & LMT_4Gb) + ae->un.AttrInt |= HBA_PORTSPEED_4GFC; + if (phba->lmt & LMT_2Gb) + ae->un.AttrInt |= HBA_PORTSPEED_2GFC; + if (phba->lmt & LMT_1Gb) + ae->un.AttrInt |= HBA_PORTSPEED_1GFC; + } else { + /* FCoE links support only one speed */ + switch (phba->fc_linkspeed) { + case LPFC_ASYNC_LINK_SPEED_10GBPS: + ae->un.AttrInt = HBA_PORTSPEED_10GE; + break; + case LPFC_ASYNC_LINK_SPEED_25GBPS: + ae->un.AttrInt = HBA_PORTSPEED_25GE; + break; + case LPFC_ASYNC_LINK_SPEED_40GBPS: + ae->un.AttrInt = HBA_PORTSPEED_40GE; + break; + case LPFC_ASYNC_LINK_SPEED_100GBPS: + ae->un.AttrInt = HBA_PORTSPEED_100GE; + break; + } + } ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); size = FOURBYTES + sizeof(uint32_t); ad->AttrLen = cpu_to_be16(size); @@ -1952,32 +1981,53 @@ lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport, ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - switch (phba->fc_linkspeed) { - case LPFC_LINK_SPEED_1GHZ: - ae->un.AttrInt = HBA_PORTSPEED_1GBIT; - break; - case LPFC_LINK_SPEED_2GHZ: - ae->un.AttrInt = HBA_PORTSPEED_2GBIT; - break; - case LPFC_LINK_SPEED_4GHZ: - ae->un.AttrInt = HBA_PORTSPEED_4GBIT; - break; - case LPFC_LINK_SPEED_8GHZ: - ae->un.AttrInt = HBA_PORTSPEED_8GBIT; - break; - case LPFC_LINK_SPEED_10GHZ: - ae->un.AttrInt = HBA_PORTSPEED_10GBIT; - break; - case LPFC_LINK_SPEED_16GHZ: - ae->un.AttrInt = HBA_PORTSPEED_16GBIT; - break; - case LPFC_LINK_SPEED_32GHZ: - ae->un.AttrInt = HBA_PORTSPEED_32GBIT; - break; - default: - ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN; - break; + if (!(phba->hba_flag & HBA_FCOE_MODE)) { + switch (phba->fc_linkspeed) { + case LPFC_LINK_SPEED_1GHZ: + ae->un.AttrInt = HBA_PORTSPEED_1GFC; + break; + case LPFC_LINK_SPEED_2GHZ: + ae->un.AttrInt = HBA_PORTSPEED_2GFC; + break; + case LPFC_LINK_SPEED_4GHZ: + ae->un.AttrInt = HBA_PORTSPEED_4GFC; + break; + case LPFC_LINK_SPEED_8GHZ: + ae->un.AttrInt = HBA_PORTSPEED_8GFC; + break; + case LPFC_LINK_SPEED_10GHZ: + ae->un.AttrInt = HBA_PORTSPEED_10GFC; + break; + case LPFC_LINK_SPEED_16GHZ: + ae->un.AttrInt = HBA_PORTSPEED_16GFC; + break; + case LPFC_LINK_SPEED_32GHZ: + ae->un.AttrInt = HBA_PORTSPEED_32GFC; + break; + default: + ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN; + break; + } + } else { + switch (phba->fc_linkspeed) { + case LPFC_ASYNC_LINK_SPEED_10GBPS: + ae->un.AttrInt = HBA_PORTSPEED_10GE; + break; + case LPFC_ASYNC_LINK_SPEED_25GBPS: + ae->un.AttrInt = HBA_PORTSPEED_25GE; + break; + case LPFC_ASYNC_LINK_SPEED_40GBPS: + ae->un.AttrInt = HBA_PORTSPEED_40GE; + break; + case LPFC_ASYNC_LINK_SPEED_100GBPS: + ae->un.AttrInt = HBA_PORTSPEED_100GE; + break; + default: + ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN; + break; + } } + ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); size = FOURBYTES + sizeof(uint32_t); ad->AttrLen = cpu_to_be16(size); diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 817cdfcd51a84..273a1db5c5aab 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -4749,6 +4749,9 @@ lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba) case LPFC_LINK_SPEED_16GHZ: rdp_speed = RDP_PS_16GB; break; + case LPFC_LINK_SPEED_32GHZ: + rdp_speed = RDP_PS_32GB; + break; default: rdp_speed = RDP_PS_UNKNOWN; break; diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 1bad678c34477..c37d72effbffe 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -3037,19 +3037,22 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) uint32_t fc_flags = 0; spin_lock_irq(&phba->hbalock); - switch (bf_get(lpfc_mbx_read_top_link_spd, la)) { - case LPFC_LINK_SPEED_1GHZ: - case LPFC_LINK_SPEED_2GHZ: - case LPFC_LINK_SPEED_4GHZ: - case LPFC_LINK_SPEED_8GHZ: - case LPFC_LINK_SPEED_10GHZ: - case LPFC_LINK_SPEED_16GHZ: - case LPFC_LINK_SPEED_32GHZ: - phba->fc_linkspeed = bf_get(lpfc_mbx_read_top_link_spd, la); - break; - default: - phba->fc_linkspeed = LPFC_LINK_SPEED_UNKNOWN; - break; + phba->fc_linkspeed = bf_get(lpfc_mbx_read_top_link_spd, la); + + if (!(phba->hba_flag & HBA_FCOE_MODE)) { + switch (bf_get(lpfc_mbx_read_top_link_spd, la)) { + case LPFC_LINK_SPEED_1GHZ: + case LPFC_LINK_SPEED_2GHZ: + case LPFC_LINK_SPEED_4GHZ: + case LPFC_LINK_SPEED_8GHZ: + case LPFC_LINK_SPEED_10GHZ: + case LPFC_LINK_SPEED_16GHZ: + case LPFC_LINK_SPEED_32GHZ: + break; + default: + phba->fc_linkspeed = LPFC_LINK_SPEED_UNKNOWN; + break; + } } if (phba->fc_topology && diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 33ec4fa39ccb4..f13a76ad2c9c0 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -3317,6 +3317,7 @@ struct lpfc_acqe_link { #define LPFC_ASYNC_LINK_SPEED_20GBPS 0x5 #define LPFC_ASYNC_LINK_SPEED_25GBPS 0x6 #define LPFC_ASYNC_LINK_SPEED_40GBPS 0x7 +#define LPFC_ASYNC_LINK_SPEED_100GBPS 0x8 #define lpfc_acqe_link_duplex_SHIFT 16 #define lpfc_acqe_link_duplex_MASK 0x000000FF #define lpfc_acqe_link_duplex_WORD word0 diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index d9753e3e97375..614f357dfb8af 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -3709,49 +3709,6 @@ lpfc_sli4_parse_latt_type(struct lpfc_hba *phba, return att_type; } -/** - * lpfc_sli4_parse_latt_link_speed - Parse sli4 link-attention link speed - * @phba: pointer to lpfc hba data structure. - * @acqe_link: pointer to the async link completion queue entry. - * - * This routine is to parse the SLI4 link-attention link speed and translate - * it into the base driver's link-attention link speed coding. - * - * Return: Link-attention link speed in terms of base driver's coding. - **/ -static uint8_t -lpfc_sli4_parse_latt_link_speed(struct lpfc_hba *phba, - struct lpfc_acqe_link *acqe_link) -{ - uint8_t link_speed; - - switch (bf_get(lpfc_acqe_link_speed, acqe_link)) { - case LPFC_ASYNC_LINK_SPEED_ZERO: - case LPFC_ASYNC_LINK_SPEED_10MBPS: - case LPFC_ASYNC_LINK_SPEED_100MBPS: - link_speed = LPFC_LINK_SPEED_UNKNOWN; - break; - case LPFC_ASYNC_LINK_SPEED_1GBPS: - link_speed = LPFC_LINK_SPEED_1GHZ; - break; - case LPFC_ASYNC_LINK_SPEED_10GBPS: - link_speed = LPFC_LINK_SPEED_10GHZ; - break; - case LPFC_ASYNC_LINK_SPEED_20GBPS: - case LPFC_ASYNC_LINK_SPEED_25GBPS: - case LPFC_ASYNC_LINK_SPEED_40GBPS: - link_speed = LPFC_LINK_SPEED_UNKNOWN; - break; - default: - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0483 Invalid link-attention link speed: x%x\n", - bf_get(lpfc_acqe_link_speed, acqe_link)); - link_speed = LPFC_LINK_SPEED_UNKNOWN; - break; - } - return link_speed; -} - /** * lpfc_sli_port_speed_get - Get sli3 link speed code to link speed * @phba: pointer to lpfc hba data structure. @@ -3768,27 +3725,35 @@ lpfc_sli_port_speed_get(struct lpfc_hba *phba) if (!lpfc_is_link_up(phba)) return 0; - switch (phba->fc_linkspeed) { - case LPFC_LINK_SPEED_1GHZ: - link_speed = 1000; - break; - case LPFC_LINK_SPEED_2GHZ: - link_speed = 2000; - break; - case LPFC_LINK_SPEED_4GHZ: - link_speed = 4000; - break; - case LPFC_LINK_SPEED_8GHZ: - link_speed = 8000; - break; - case LPFC_LINK_SPEED_10GHZ: - link_speed = 10000; - break; - case LPFC_LINK_SPEED_16GHZ: - link_speed = 16000; - break; - default: - link_speed = 0; + if (phba->sli_rev <= LPFC_SLI_REV3) { + switch (phba->fc_linkspeed) { + case LPFC_LINK_SPEED_1GHZ: + link_speed = 1000; + break; + case LPFC_LINK_SPEED_2GHZ: + link_speed = 2000; + break; + case LPFC_LINK_SPEED_4GHZ: + link_speed = 4000; + break; + case LPFC_LINK_SPEED_8GHZ: + link_speed = 8000; + break; + case LPFC_LINK_SPEED_10GHZ: + link_speed = 10000; + break; + case LPFC_LINK_SPEED_16GHZ: + link_speed = 16000; + break; + default: + link_speed = 0; + } + } else { + if (phba->sli4_hba.link_state.logical_speed) + link_speed = + phba->sli4_hba.link_state.logical_speed; + else + link_speed = phba->sli4_hba.link_state.speed; } return link_speed; } @@ -3984,7 +3949,7 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba, la->eventTag = acqe_link->event_tag; bf_set(lpfc_mbx_read_top_att_type, la, att_type); bf_set(lpfc_mbx_read_top_link_spd, la, - lpfc_sli4_parse_latt_link_speed(phba, acqe_link)); + (bf_get(lpfc_acqe_link_speed, acqe_link))); /* Fake the the following irrelvant fields */ bf_set(lpfc_mbx_read_top_topology, la, LPFC_TOPOLOGY_PT_PT); diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 964a996dea2cc..152b3c8a5428f 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -4461,15 +4461,7 @@ lpfc_info(struct Scsi_Host *host) phba->Port); } len = strlen(lpfcinfobuf); - if (phba->sli_rev <= LPFC_SLI_REV3) { - link_speed = lpfc_sli_port_speed_get(phba); - } else { - if (phba->sli4_hba.link_state.logical_speed) - link_speed = - phba->sli4_hba.link_state.logical_speed; - else - link_speed = phba->sli4_hba.link_state.speed; - } + link_speed = lpfc_sli_port_speed_get(phba); if (link_speed != 0) snprintf(lpfcinfobuf + len, 384-len, " Logical Link Speed: %d Mbps", link_speed); -- GitLab From 01c73bbcd7cc4f31f45a1b0caeacdba46acd9c9c Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:12:03 -0500 Subject: [PATCH 1973/2855] lpfc: Fix mbox reuse in PLOGI completion Fix mbox reuse in PLOGI completion. Moved allocations so that buffer properly init'd. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_nportdisc.c | 31 ++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 9e571dd416877..193733e8c8235 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -1045,16 +1045,6 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, if (irsp->ulpStatus) goto out; - mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (!mbox) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, - "0133 PLOGI: no memory for reg_login " - "Data: x%x x%x x%x x%x\n", - ndlp->nlp_DID, ndlp->nlp_state, - ndlp->nlp_flag, ndlp->nlp_rpi); - goto out; - } - pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list); @@ -1118,6 +1108,17 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, if (phba->sli_rev == LPFC_SLI_REV4) { lpfc_issue_reg_vfi(vport); } else { + mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mbox) { + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0133 PLOGI: no memory " + "for config_link " + "Data: x%x x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_state, + ndlp->nlp_flag, ndlp->nlp_rpi); + goto out; + } + lpfc_config_link(phba, mbox); mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; @@ -1132,6 +1133,16 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, lpfc_unreg_rpi(vport, ndlp); + mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mbox) { + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0018 PLOGI: no memory for reg_login " + "Data: x%x x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_state, + ndlp->nlp_flag, ndlp->nlp_rpi); + goto out; + } + if (lpfc_reg_rpi(phba, vport->vpi, irsp->un.elsreq64.remoteID, (uint8_t *) sp, mbox, ndlp->nlp_rpi) == 0) { switch (ndlp->nlp_DID) { -- GitLab From 4360ca9c24388e44cb0e14861a62fff43cf225c0 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:12:04 -0500 Subject: [PATCH 1974/2855] lpfc: Fix external loopback failure. Fix external loopback failure. Rx sequence reassembly was incorrect. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_sli.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 6aae828208e26..92dfd6a5178ce 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -14842,10 +14842,12 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) struct lpfc_dmabuf *h_buf; struct hbq_dmabuf *seq_dmabuf = NULL; struct hbq_dmabuf *temp_dmabuf = NULL; + uint8_t found = 0; INIT_LIST_HEAD(&dmabuf->dbuf.list); dmabuf->time_stamp = jiffies; new_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt; + /* Use the hdr_buf to find the sequence that this frame belongs to */ list_for_each_entry(h_buf, &vport->rcv_buffer_list, list) { temp_hdr = (struct fc_frame_header *)h_buf->virt; @@ -14885,7 +14887,8 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) return seq_dmabuf; } /* find the correct place in the sequence to insert this frame */ - list_for_each_entry_reverse(d_buf, &seq_dmabuf->dbuf.list, list) { + d_buf = list_entry(seq_dmabuf->dbuf.list.prev, typeof(*d_buf), list); + while (!found) { temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); temp_hdr = (struct fc_frame_header *)temp_dmabuf->hbuf.virt; /* @@ -14895,9 +14898,17 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) if (be16_to_cpu(new_hdr->fh_seq_cnt) > be16_to_cpu(temp_hdr->fh_seq_cnt)) { list_add(&dmabuf->dbuf.list, &temp_dmabuf->dbuf.list); - return seq_dmabuf; + found = 1; + break; } + + if (&d_buf->list == &seq_dmabuf->dbuf.list) + break; + d_buf = list_entry(d_buf->list.prev, typeof(*d_buf), list); } + + if (found) + return seq_dmabuf; return NULL; } -- GitLab From 448193b5b5e2471fc90ea11e78c39bcfd167efb6 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:12:05 -0500 Subject: [PATCH 1975/2855] lpfc: Add logging for misconfigured optics. Add logging for misconfigured optics acqe reported by fw. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_hw4.h | 51 +++++++++++++++++++------- drivers/scsi/lpfc/lpfc_init.c | 67 ++++++++++++++++++++++++----------- drivers/scsi/lpfc/lpfc_sli4.h | 1 + 3 files changed, 87 insertions(+), 32 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index f13a76ad2c9c0..608f9415fb08d 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -3448,23 +3448,50 @@ struct lpfc_acqe_fc_la { struct lpfc_acqe_misconfigured_event { struct { uint32_t word0; -#define lpfc_sli_misconfigured_port0_SHIFT 0 -#define lpfc_sli_misconfigured_port0_MASK 0x000000FF -#define lpfc_sli_misconfigured_port0_WORD word0 -#define lpfc_sli_misconfigured_port1_SHIFT 8 -#define lpfc_sli_misconfigured_port1_MASK 0x000000FF -#define lpfc_sli_misconfigured_port1_WORD word0 -#define lpfc_sli_misconfigured_port2_SHIFT 16 -#define lpfc_sli_misconfigured_port2_MASK 0x000000FF -#define lpfc_sli_misconfigured_port2_WORD word0 -#define lpfc_sli_misconfigured_port3_SHIFT 24 -#define lpfc_sli_misconfigured_port3_MASK 0x000000FF -#define lpfc_sli_misconfigured_port3_WORD word0 +#define lpfc_sli_misconfigured_port0_state_SHIFT 0 +#define lpfc_sli_misconfigured_port0_state_MASK 0x000000FF +#define lpfc_sli_misconfigured_port0_state_WORD word0 +#define lpfc_sli_misconfigured_port1_state_SHIFT 8 +#define lpfc_sli_misconfigured_port1_state_MASK 0x000000FF +#define lpfc_sli_misconfigured_port1_state_WORD word0 +#define lpfc_sli_misconfigured_port2_state_SHIFT 16 +#define lpfc_sli_misconfigured_port2_state_MASK 0x000000FF +#define lpfc_sli_misconfigured_port2_state_WORD word0 +#define lpfc_sli_misconfigured_port3_state_SHIFT 24 +#define lpfc_sli_misconfigured_port3_state_MASK 0x000000FF +#define lpfc_sli_misconfigured_port3_state_WORD word0 + uint32_t word1; +#define lpfc_sli_misconfigured_port0_op_SHIFT 0 +#define lpfc_sli_misconfigured_port0_op_MASK 0x00000001 +#define lpfc_sli_misconfigured_port0_op_WORD word1 +#define lpfc_sli_misconfigured_port0_severity_SHIFT 1 +#define lpfc_sli_misconfigured_port0_severity_MASK 0x00000003 +#define lpfc_sli_misconfigured_port0_severity_WORD word1 +#define lpfc_sli_misconfigured_port1_op_SHIFT 8 +#define lpfc_sli_misconfigured_port1_op_MASK 0x00000001 +#define lpfc_sli_misconfigured_port1_op_WORD word1 +#define lpfc_sli_misconfigured_port1_severity_SHIFT 9 +#define lpfc_sli_misconfigured_port1_severity_MASK 0x00000003 +#define lpfc_sli_misconfigured_port1_severity_WORD word1 +#define lpfc_sli_misconfigured_port2_op_SHIFT 16 +#define lpfc_sli_misconfigured_port2_op_MASK 0x00000001 +#define lpfc_sli_misconfigured_port2_op_WORD word1 +#define lpfc_sli_misconfigured_port2_severity_SHIFT 17 +#define lpfc_sli_misconfigured_port2_severity_MASK 0x00000003 +#define lpfc_sli_misconfigured_port2_severity_WORD word1 +#define lpfc_sli_misconfigured_port3_op_SHIFT 24 +#define lpfc_sli_misconfigured_port3_op_MASK 0x00000001 +#define lpfc_sli_misconfigured_port3_op_WORD word1 +#define lpfc_sli_misconfigured_port3_severity_SHIFT 25 +#define lpfc_sli_misconfigured_port3_severity_MASK 0x00000003 +#define lpfc_sli_misconfigured_port3_severity_WORD word1 } theEvent; #define LPFC_SLI_EVENT_STATUS_VALID 0x00 #define LPFC_SLI_EVENT_STATUS_NOT_PRESENT 0x01 #define LPFC_SLI_EVENT_STATUS_WRONG_TYPE 0x02 #define LPFC_SLI_EVENT_STATUS_UNSUPPORTED 0x03 +#define LPFC_SLI_EVENT_STATUS_UNQUALIFIED 0x04 +#define LPFC_SLI_EVENT_STATUS_UNCERTIFIED 0x05 }; struct lpfc_acqe_sli { diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 614f357dfb8af..a544366a367e3 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -4079,22 +4079,18 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli) char message[128]; uint8_t status; uint8_t evt_type; + uint8_t operational = 0; struct temp_event temp_event_data; struct lpfc_acqe_misconfigured_event *misconfigured; struct Scsi_Host *shost; evt_type = bf_get(lpfc_trailer_type, acqe_sli); - /* Special case Lancer */ - if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != - LPFC_SLI_INTF_IF_TYPE_2) { - lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "2901 Async SLI event - Event Data1:x%08x Event Data2:" - "x%08x SLI Event Type:%d\n", - acqe_sli->event_data1, acqe_sli->event_data2, - evt_type); - return; - } + lpfc_printf_log(phba, KERN_INFO, LOG_SLI, + "2901 Async SLI event - Event Data1:x%08x Event Data2:" + "x%08x SLI Event Type:%d\n", + acqe_sli->event_data1, acqe_sli->event_data2, + evt_type); port_name = phba->Port[0]; if (port_name == 0x00) @@ -4140,29 +4136,46 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli) /* fetch the status for this port */ switch (phba->sli4_hba.lnk_info.lnk_no) { case LPFC_LINK_NUMBER_0: - status = bf_get(lpfc_sli_misconfigured_port0, + status = bf_get(lpfc_sli_misconfigured_port0_state, + &misconfigured->theEvent); + operational = bf_get(lpfc_sli_misconfigured_port0_op, &misconfigured->theEvent); break; case LPFC_LINK_NUMBER_1: - status = bf_get(lpfc_sli_misconfigured_port1, + status = bf_get(lpfc_sli_misconfigured_port1_state, + &misconfigured->theEvent); + operational = bf_get(lpfc_sli_misconfigured_port1_op, &misconfigured->theEvent); break; case LPFC_LINK_NUMBER_2: - status = bf_get(lpfc_sli_misconfigured_port2, + status = bf_get(lpfc_sli_misconfigured_port2_state, + &misconfigured->theEvent); + operational = bf_get(lpfc_sli_misconfigured_port2_op, &misconfigured->theEvent); break; case LPFC_LINK_NUMBER_3: - status = bf_get(lpfc_sli_misconfigured_port3, + status = bf_get(lpfc_sli_misconfigured_port3_state, + &misconfigured->theEvent); + operational = bf_get(lpfc_sli_misconfigured_port3_op, &misconfigured->theEvent); break; default: - status = ~LPFC_SLI_EVENT_STATUS_VALID; - break; + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, + "3296 " + "LPFC_SLI_EVENT_TYPE_MISCONFIGURED " + "event: Invalid link %d", + phba->sli4_hba.lnk_info.lnk_no); + return; } + /* Skip if optic state unchanged */ + if (phba->sli4_hba.lnk_info.optic_state == status) + return; + switch (status) { case LPFC_SLI_EVENT_STATUS_VALID: - return; /* no message if the sfp is okay */ + sprintf(message, "Physical Link is functional"); + break; case LPFC_SLI_EVENT_STATUS_NOT_PRESENT: sprintf(message, "Optics faulted/incorrectly " "installed/not installed - Reseat optics, " @@ -4177,15 +4190,26 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli) sprintf(message, "Incompatible optics - Replace with " "compatible optics for card to function."); break; + case LPFC_SLI_EVENT_STATUS_UNQUALIFIED: + sprintf(message, "Unqualified optics - Replace with " + "Avago optics for Warranty and Technical " + "Support - Link is%s operational", + (operational) ? "" : " not"); + break; + case LPFC_SLI_EVENT_STATUS_UNCERTIFIED: + sprintf(message, "Uncertified optics - Replace with " + "Avago-certified optics to enable link " + "operation - Link is%s operational", + (operational) ? "" : " not"); + break; default: /* firmware is reporting a status we don't know about */ sprintf(message, "Unknown event status x%02x", status); break; } - + phba->sli4_hba.lnk_info.optic_state = status; lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "3176 Misconfigured Physical Port - " - "Port Name %c %s\n", port_name, message); + "3176 Port Name %c %s\n", port_name, message); break; case LPFC_SLI_EVENT_TYPE_REMOTE_DPORT: lpfc_printf_log(phba, KERN_INFO, LOG_SLI, @@ -5259,6 +5283,9 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) INIT_LIST_HEAD(&phba->sli4_hba.lpfc_vfi_blk_list); INIT_LIST_HEAD(&phba->lpfc_vpi_blk_list); + /* initialize optic_state to 0xFF */ + phba->sli4_hba.lnk_info.optic_state = 0xff; + /* Initialize the driver internal SLI layer lists. */ lpfc_sli_setup(phba); lpfc_sli_queue_setup(phba); diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 1e916e16ce989..cd780c29495aa 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -442,6 +442,7 @@ struct lpfc_sli4_lnk_info { #define LPFC_LNK_GE 0x0 /* FCoE */ #define LPFC_LNK_FC 0x1 /* FC */ uint8_t lnk_no; + uint8_t optic_state; }; #define LPFC_SLI4_HANDLER_CNT (LPFC_FCP_IO_CHAN_MAX+ \ -- GitLab From 9be321819c43417432a8376428b90fe3fe3a3510 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 16 Dec 2015 18:12:06 -0500 Subject: [PATCH 1976/2855] lpfc: Delete unnecessary checks before the function call "mempool_destroy" The mempool_destroy() function tests whether its argument is NULL and then returns immediately. Thus the test around the calls is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Reviewed-by: Sebastian Herbszt Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_mem.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 3fa65338d3f55..4fb3581d4614c 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c @@ -231,15 +231,13 @@ lpfc_mem_free(struct lpfc_hba *phba) if (phba->lpfc_hbq_pool) pci_pool_destroy(phba->lpfc_hbq_pool); phba->lpfc_hbq_pool = NULL; - - if (phba->rrq_pool) - mempool_destroy(phba->rrq_pool); + mempool_destroy(phba->rrq_pool); phba->rrq_pool = NULL; /* Free NLP memory pool */ mempool_destroy(phba->nlp_mem_pool); phba->nlp_mem_pool = NULL; - if (phba->sli_rev == LPFC_SLI_REV4 && phba->active_rrq_pool) { + if (phba->sli_rev == LPFC_SLI_REV4) { mempool_destroy(phba->active_rrq_pool); phba->active_rrq_pool = NULL; } -- GitLab From 699acd6220ea5b20b25d5eec0ab448827d745357 Mon Sep 17 00:00:00 2001 From: Punit Vara Date: Wed, 16 Dec 2015 18:12:07 -0500 Subject: [PATCH 1977/2855] lpfc: Use kzalloc instead of kmalloc This patch is to the lpfc_els.c which resolves following warning reported by coccicheck: WARNING: kzalloc should be used for rdp_context, instead of kmalloc/memset Signed-off-by: Punit Vara Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Reviewed-by: Matthew R. Ochs Reviewed-by: Sebastian Herbszt Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 273a1db5c5aab..7f5abb8f52bc8 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -5016,13 +5016,12 @@ lpfc_els_rcv_rdp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, if (RDP_NPORT_ID_SIZE != be32_to_cpu(rdp_req->nport_id_desc.length)) goto rjt_logerr; - rdp_context = kmalloc(sizeof(struct lpfc_rdp_context), GFP_KERNEL); + rdp_context = kzalloc(sizeof(struct lpfc_rdp_context), GFP_KERNEL); if (!rdp_context) { rjt_err = LSRJT_UNABLE_TPC; goto error; } - memset(rdp_context, 0, sizeof(struct lpfc_rdp_context)); cmd = &cmdiocb->iocb; rdp_context->ndlp = lpfc_nlp_get(ndlp); rdp_context->ox_id = cmd->unsli3.rcvsli3.ox_id; -- GitLab From b034573c7eb39aa58cd4a08e487869fea6d4ad2d Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:12:08 -0500 Subject: [PATCH 1978/2855] lpfc: Update version to 11.0.0.10 for upstream patch set Update version to 11.0.0.10 for upstream patch set Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index ea53aa664759b..4dc22562aaf16 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "11.0.0.0." +#define LPFC_DRIVER_VERSION "11.0.0.10." #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */ -- GitLab From 32c5844abb302e3fb1637ba6afe3d8132c64e57f Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 16 Dec 2015 17:53:51 -0500 Subject: [PATCH 1979/2855] scsi_debug: Increase the reported optimal transfer length The OPTIMAL TRANSFER LENGTH reported by scsi_debug is 64 blocks which translates to 32KB with the default logical block size. That's much lower than what real storage devices typically report (256KB to 1MB). Bump the optimal transfer length to 1024 blocks. Acked-by: Douglas Gilbert Reviewed-by: Ewan Milne Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 1bea1adc16a8f..237b691c8e0a8 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -129,7 +129,7 @@ static const char *scsi_debug_version_date = "20141022"; #define DEF_NO_LUN_0 0 #define DEF_NUM_PARTS 0 #define DEF_OPTS 0 -#define DEF_OPT_BLKS 64 +#define DEF_OPT_BLKS 1024 #define DEF_PHYSBLK_EXP 0 #define DEF_PTYPE 0 #define DEF_REMOVABLE false @@ -4139,7 +4139,7 @@ MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)"); MODULE_PARM_DESC(no_uld, "stop ULD (e.g. sd driver) attaching (def=0))"); MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); MODULE_PARM_DESC(num_tgts, "number of targets per host to simulate(def=1)"); -MODULE_PARM_DESC(opt_blks, "optimal transfer length in block (def=64)"); +MODULE_PARM_DESC(opt_blks, "optimal transfer length in blocks (def=1024)"); MODULE_PARM_DESC(opts, "1->noise, 2->medium_err, 4->timeout, 8->recovered_err... (def=0)"); MODULE_PARM_DESC(physblk_exp, "physical block exponent (def=0)"); MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])"); -- GitLab From 7d2c2acac577959dbbddefefa91d1ba1b80460b3 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Mon, 14 Dec 2015 16:35:57 -0600 Subject: [PATCH 1980/2855] iio: Make IIO value formating function globally available. Make IIO value formating function globally available to allow IIO drivers to output values as the core does. Signed-off-by: Andrew F. Davis Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-core.c | 1 + include/linux/iio/iio.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index d0a84febd435a..a45eb2c53d0fd 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -470,6 +470,7 @@ ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals) return 0; } } +EXPORT_SYMBOL_GPL(iio_format_value); static ssize_t iio_read_channel_info(struct device *dev, struct device_attribute *attr, diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 19c94c9acc816..b5894118755fb 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -636,6 +636,8 @@ static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev) } #endif +ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals); + int iio_str_to_fixpoint(const char *str, int fract_mult, int *integer, int *fract); -- GitLab From a5beaaf39455e4388251e95ef2ce6849cabf3393 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Sat, 21 Nov 2015 15:44:53 +0800 Subject: [PATCH 1981/2855] usb: gadget: Add the console support for usb-to-serial port It dose not work when we want to use the usb-to-serial port based on one usb gadget as a console. Thus this patch adds the console initialization to support this request. To avoid the re-entrance when transferring data with usb endpoint, it introduces a kthread to do the IO transmission. Signed-off-by: Baolin Wang Signed-off-by: Felipe Balbi --- drivers/usb/gadget/Kconfig | 6 + drivers/usb/gadget/function/u_serial.c | 258 +++++++++++++++++++++++++ 2 files changed, 264 insertions(+) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 33834aa09ed43..be5aab9c13f2d 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -127,6 +127,12 @@ config USB_GADGET_STORAGE_NUM_BUFFERS a module parameter as well. If unsure, say 2. +config U_SERIAL_CONSOLE + bool "Serial gadget console support" + depends on USB_G_SERIAL + help + It supports the serial gadget can be used as a console. + source "drivers/usb/gadget/udc/Kconfig" # diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index f7771d86ad6c8..6af145f2a99dd 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include "u_serial.h" @@ -79,6 +81,7 @@ */ #define QUEUE_SIZE 16 #define WRITE_BUF_SIZE 8192 /* TX only */ +#define GS_CONSOLE_BUF_SIZE 8192 /* circular buffer */ struct gs_buf { @@ -88,6 +91,17 @@ struct gs_buf { char *buf_put; }; +/* console info */ +struct gscons_info { + struct gs_port *port; + struct task_struct *console_thread; + struct gs_buf con_buf; + /* protect the buf and busy flag */ + spinlock_t con_lock; + int req_busy; + struct usb_request *console_req; +}; + /* * The port structure holds info for each port, one for each minor number * (and thus for each /dev/ node). @@ -1023,6 +1037,246 @@ static const struct tty_operations gs_tty_ops = { static struct tty_driver *gs_tty_driver; +#ifdef CONFIG_U_SERIAL_CONSOLE + +static struct gscons_info gscons_info; +static struct console gserial_cons; + +static struct usb_request *gs_request_new(struct usb_ep *ep) +{ + struct usb_request *req = usb_ep_alloc_request(ep, GFP_ATOMIC); + if (!req) + return NULL; + + req->buf = kmalloc(ep->maxpacket, GFP_ATOMIC); + if (!req->buf) { + usb_ep_free_request(ep, req); + return NULL; + } + + return req; +} + +static void gs_request_free(struct usb_request *req, struct usb_ep *ep) +{ + if (!req) + return; + + kfree(req->buf); + usb_ep_free_request(ep, req); +} + +static void gs_complete_out(struct usb_ep *ep, struct usb_request *req) +{ + struct gscons_info *info = &gscons_info; + + switch (req->status) { + default: + pr_warn("%s: unexpected %s status %d\n", + __func__, ep->name, req->status); + case 0: + /* normal completion */ + spin_lock(&info->con_lock); + info->req_busy = 0; + spin_unlock(&info->con_lock); + + wake_up_process(info->console_thread); + break; + case -ESHUTDOWN: + /* disconnect */ + pr_vdebug("%s: %s shutdown\n", __func__, ep->name); + break; + } +} + +static int gs_console_connect(int port_num) +{ + struct gscons_info *info = &gscons_info; + struct gs_port *port; + struct usb_ep *ep; + + if (port_num != gserial_cons.index) { + pr_err("%s: port num [%d] is not support console\n", + __func__, port_num); + return -ENXIO; + } + + port = ports[port_num].port; + ep = port->port_usb->in; + if (!info->console_req) { + info->console_req = gs_request_new(ep); + if (!info->console_req) + return -ENOMEM; + info->console_req->complete = gs_complete_out; + } + + info->port = port; + spin_lock(&info->con_lock); + info->req_busy = 0; + spin_unlock(&info->con_lock); + pr_vdebug("port[%d] console connect!\n", port_num); + return 0; +} + +static void gs_console_disconnect(struct usb_ep *ep) +{ + struct gscons_info *info = &gscons_info; + struct usb_request *req = info->console_req; + + gs_request_free(req, ep); + info->console_req = NULL; +} + +static int gs_console_thread(void *data) +{ + struct gscons_info *info = &gscons_info; + struct gs_port *port; + struct usb_request *req; + struct usb_ep *ep; + int xfer, ret, count, size; + + do { + port = info->port; + set_current_state(TASK_INTERRUPTIBLE); + if (!port || !port->port_usb + || !port->port_usb->in || !info->console_req) + goto sched; + + req = info->console_req; + ep = port->port_usb->in; + + spin_lock_irq(&info->con_lock); + count = gs_buf_data_avail(&info->con_buf); + size = ep->maxpacket; + + if (count > 0 && !info->req_busy) { + set_current_state(TASK_RUNNING); + if (count < size) + size = count; + + xfer = gs_buf_get(&info->con_buf, req->buf, size); + req->length = xfer; + + spin_unlock(&info->con_lock); + ret = usb_ep_queue(ep, req, GFP_ATOMIC); + spin_lock(&info->con_lock); + if (ret < 0) + info->req_busy = 0; + else + info->req_busy = 1; + + spin_unlock_irq(&info->con_lock); + } else { + spin_unlock_irq(&info->con_lock); +sched: + if (kthread_should_stop()) { + set_current_state(TASK_RUNNING); + break; + } + schedule(); + } + } while (1); + + return 0; +} + +static int gs_console_setup(struct console *co, char *options) +{ + struct gscons_info *info = &gscons_info; + int status; + + info->port = NULL; + info->console_req = NULL; + info->req_busy = 0; + spin_lock_init(&info->con_lock); + + status = gs_buf_alloc(&info->con_buf, GS_CONSOLE_BUF_SIZE); + if (status) { + pr_err("%s: allocate console buffer failed\n", __func__); + return status; + } + + info->console_thread = kthread_create(gs_console_thread, + co, "gs_console"); + if (IS_ERR(info->console_thread)) { + pr_err("%s: cannot create console thread\n", __func__); + gs_buf_free(&info->con_buf); + return PTR_ERR(info->console_thread); + } + wake_up_process(info->console_thread); + + return 0; +} + +static void gs_console_write(struct console *co, + const char *buf, unsigned count) +{ + struct gscons_info *info = &gscons_info; + unsigned long flags; + + spin_lock_irqsave(&info->con_lock, flags); + gs_buf_put(&info->con_buf, buf, count); + spin_unlock_irqrestore(&info->con_lock, flags); + + wake_up_process(info->console_thread); +} + +static struct tty_driver *gs_console_device(struct console *co, int *index) +{ + struct tty_driver **p = (struct tty_driver **)co->data; + + if (!*p) + return NULL; + + *index = co->index; + return *p; +} + +static struct console gserial_cons = { + .name = "ttyGS", + .write = gs_console_write, + .device = gs_console_device, + .setup = gs_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &gs_tty_driver, +}; + +static void gserial_console_init(void) +{ + register_console(&gserial_cons); +} + +static void gserial_console_exit(void) +{ + struct gscons_info *info = &gscons_info; + + unregister_console(&gserial_cons); + kthread_stop(info->console_thread); + gs_buf_free(&info->con_buf); +} + +#else + +static int gs_console_connect(int port_num) +{ + return 0; +} + +static void gs_console_disconnect(struct usb_ep *ep) +{ +} + +static void gserial_console_init(void) +{ +} + +static void gserial_console_exit(void) +{ +} + +#endif + static int gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding) { @@ -1096,6 +1350,7 @@ void gserial_free_line(unsigned char port_num) gserial_free_port(port); tty_unregister_device(gs_tty_driver, port_num); + gserial_console_exit(); } EXPORT_SYMBOL_GPL(gserial_free_line); @@ -1138,6 +1393,7 @@ int gserial_alloc_line(unsigned char *line_num) goto err; } *line_num = port_num; + gserial_console_init(); err: return ret; } @@ -1219,6 +1475,7 @@ int gserial_connect(struct gserial *gser, u8 port_num) gser->disconnect(gser); } + status = gs_console_connect(port_num); spin_unlock_irqrestore(&port->port_lock, flags); return status; @@ -1277,6 +1534,7 @@ void gserial_disconnect(struct gserial *gser) port->read_allocated = port->read_started = port->write_allocated = port->write_started = 0; + gs_console_disconnect(gser->in); spin_unlock_irqrestore(&port->port_lock, flags); } EXPORT_SYMBOL_GPL(gserial_disconnect); -- GitLab From 0676c7e734e3807f4e91f5d0edcaeed1f5ff412a Mon Sep 17 00:00:00 2001 From: "Du, Changbin" Date: Fri, 4 Dec 2015 15:38:23 +0800 Subject: [PATCH 1982/2855] usb: dwc2: fix transfer stop programming for out endpoint To stop an out endpoint, software should set sets the Global OUT NAK, but not the Global Non-periodic IN NAK. This driver bug leads the out-ep failed be in disabled state with below error. dwc2_hsotg_ep_stop_xfr: timeout DOEPCTL.EPDisable Acked-by: John Youn Signed-off-by: Du, Changbin Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 0abf73c91beb0..92a182feb936b 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2911,15 +2911,15 @@ static void dwc2_hsotg_ep_stop_xfr(struct dwc2_hsotg *hsotg, "%s: timeout DIEPINT.NAKEFF\n", __func__); } else { /* Clear any pending nak effect interrupt */ - dwc2_writel(GINTSTS_GINNAKEFF, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_GOUTNAKEFF, hsotg->regs + GINTSTS); - __orr32(hsotg->regs + DCTL, DCTL_SGNPINNAK); + __orr32(hsotg->regs + DCTL, DCTL_SGOUTNAK); /* Wait for global nak to take effect */ if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS, - GINTSTS_GINNAKEFF, 100)) + GINTSTS_GOUTNAKEFF, 100)) dev_warn(hsotg->dev, - "%s: timeout GINTSTS.GINNAKEFF\n", __func__); + "%s: timeout GINTSTS.GOUTNAKEFF\n", __func__); } /* Disable ep */ @@ -2944,7 +2944,7 @@ static void dwc2_hsotg_ep_stop_xfr(struct dwc2_hsotg *hsotg, /* TODO: Flush shared tx fifo */ } else { /* Remove global NAKs */ - __bic32(hsotg->regs + DCTL, DCTL_SGNPINNAK); + __bic32(hsotg->regs + DCTL, DCTL_SGOUTNAK); } } -- GitLab From 3be99cd0e882dd2127b8cfe3942f5e464915aeba Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Mon, 7 Dec 2015 12:07:31 +0100 Subject: [PATCH 1983/2855] usb: dwc2: gadget: don't overwrite DCTL register on NAKEFF interrupts When receiving GINTSTS_GINNAKEFF or GINTSTS_GOUTNAKEFF interrupt, DCTL will be overwritten with DCTL_CGOUTNAK or DCTL_CGNPINNAK values. Instead of overwriting it, write only needed bits. It could cause an issue if GINTSTS_GINNAKEFF or GINTSTS_GOUTNAKEFF interrupt is received after dwc2 disabled pullup by writing DCTL_SFTDISCON bit. Pullup will then be re-enabled whereas it should not. Acked-by: John Youn Signed-off-by: Gregory Herrero Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 92a182feb936b..3a24cbf355a9e 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2585,7 +2585,7 @@ irq_retry: if (gintsts & GINTSTS_GOUTNAKEFF) { dev_info(hsotg->dev, "GOUTNakEff triggered\n"); - dwc2_writel(DCTL_CGOUTNAK, hsotg->regs + DCTL); + __orr32(hsotg->regs + DCTL, DCTL_CGOUTNAK); dwc2_hsotg_dump(hsotg); } @@ -2593,7 +2593,7 @@ irq_retry: if (gintsts & GINTSTS_GINNAKEFF) { dev_info(hsotg->dev, "GINNakEff triggered\n"); - dwc2_writel(DCTL_CGNPINNAK, hsotg->regs + DCTL); + __orr32(hsotg->regs + DCTL, DCTL_CGNPINNAK); dwc2_hsotg_dump(hsotg); } -- GitLab From 991824677fe0a555394d8093b64647dbd08b89b0 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Thu, 17 Dec 2015 11:14:12 -0800 Subject: [PATCH 1984/2855] usb: dwc2: Restore GUSBCFG in dwc2_get_hwparams() Previously dwc2_get_hwparams() was changing GUSBCFG and not putting it back the way it was (specifically it set and cleared FORCEHOSTMODE). Since we want to move dwc2_core_reset() _before_ dwc2_get_hwparams() we should make sure dwc2_get_hwparams() isn't messing with things in a permanent way. Since we're now looking at GUSBCFG, it's obvious that we shouldn't need all the extra delays if FORCEHOSTMODE was already set. This will avoid some delays for any ports that have forced host mode. Signed-off-by: Douglas Anderson Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 0a9ebe00fbcca..0bc1c0ed12ebe 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -3129,18 +3129,20 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) /* Force host mode to get HPTXFSIZ / GNPTXFSIZ exact power on value */ gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); - gusbcfg |= GUSBCFG_FORCEHOSTMODE; - dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); - usleep_range(100000, 150000); + if (!(gusbcfg & GUSBCFG_FORCEHOSTMODE)) { + dwc2_writel(gusbcfg | GUSBCFG_FORCEHOSTMODE, + hsotg->regs + GUSBCFG); + usleep_range(100000, 150000); + } gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ); hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ); dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz); dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hptxfsiz); - gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); - gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; - dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); - usleep_range(100000, 150000); + if (!(gusbcfg & GUSBCFG_FORCEHOSTMODE)) { + dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); + usleep_range(100000, 150000); + } /* hwcfg2 */ hw->op_mode = (hwcfg2 & GHWCFG2_OP_MODE_MASK) >> -- GitLab From cebfdbf329ae929ccb71632888a7c2100c3d1eeb Mon Sep 17 00:00:00 2001 From: Yunzhi Li Date: Thu, 17 Dec 2015 11:14:26 -0800 Subject: [PATCH 1985/2855] usb: dwc2: reset dwc2 core before dwc2_get_hwparams() We initiate dwc2 usb controller in BIOS, dwc2_core_reset() should be called before dwc2_get_hwparams() to reset core registers to default value. Without this the FIFO setting might be incorrect because calculating FIFO size need power-on value of GRXFSIZ/GNPTXFSIZ/HPTXFSIZ registers. This patch could avoid warnning massage like in rk3288 platform: [ 2.074764] dwc2 ff580000.usb: 256 invalid for host_perio_tx_fifo_size. Check HW configuration. Signed-off-by: Yunzhi Li Signed-off-by: Douglas Anderson Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 2 +- drivers/usb/dwc2/core.h | 1 + drivers/usb/dwc2/platform.c | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 0bc1c0ed12ebe..0a584ecb233f8 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -481,7 +481,7 @@ static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg) * Do core a soft reset of the core. Be careful with this because it * resets all the internal state machines of the core. */ -static int dwc2_core_reset(struct dwc2_hsotg *hsotg) +int dwc2_core_reset(struct dwc2_hsotg *hsotg) { u32 greset; int count = 0; diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 05f01785de05d..d1d855af63e67 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -880,6 +880,7 @@ enum dwc2_halt_status { * The following functions support initialization of the core driver component * and the DWC_otg controller */ +extern int dwc2_core_reset(struct dwc2_hsotg *hsotg); extern void dwc2_core_host_init(struct dwc2_hsotg *hsotg); extern int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg); extern int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore); diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 5df2adf6f4e7d..a72302d740dde 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -456,6 +456,12 @@ static int dwc2_driver_probe(struct platform_device *dev) if (retval) return retval; + /* + * Reset before dwc2_get_hwparams() then it could get power-on real + * reset value form registers. + */ + dwc2_core_reset(hsotg); + /* Detect config values from hardware */ retval = dwc2_get_hwparams(hsotg); if (retval) -- GitLab From 0fe239bc190453fe82252c6d41a74e685730cd93 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Thu, 17 Dec 2015 11:14:40 -0800 Subject: [PATCH 1986/2855] usb: dwc2: Avoid double-reset at boot time In (usb: dwc2: reset dwc2 core before dwc2_get_hwparams()) we added an extra reset to the probe path for the dwc2 USB controllers. This allowed proper detection of parameters even if the firmware had already used the USB part. Unfortunately, this extra reset is quite slow and is affecting boot speed. We can avoid the double-reset by skipping the extra reset that would happen just after the one we added. Logic that explains why this is safe: * As of the CL mentioned above, we now always call dwc2_core_reset() in dwc2_driver_probe() before dwc2_hcd_init(). * The only caller of dwc2_hcd_init() is dwc2_driver_probe(), so we're guaranteed that dwc2_core_reset() was called before dwc2_hdc_init(). * dwc2_hdc_init() is the only caller that passes an irq other than -1 to dwc2_core_init(). Thus if dwc2_core_init() is called with an irq other than -1 we're guaranteed that dwc2_core_reset was called before dwc2_core_init(). ...this allows us to remove the dwc2_core_reset() in dwc2_core_init() if irq is not < 0. Note that since "irq" wasn't used in the function dwc2_core_init() anyway and since select_phy was always set at exactly the same times we could avoid the reset, we remove "irq" and rename "select_phy" to "initial_setup" and adjust the callers accordingly. Signed-off-by: Douglas Anderson Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 29 ++++++++++++++++++----------- drivers/usb/dwc2/core.h | 2 +- drivers/usb/dwc2/hcd.c | 6 +++--- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 0a584ecb233f8..af12778b0e96e 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -765,11 +765,10 @@ static void dwc2_gusbcfg_init(struct dwc2_hsotg *hsotg) * dwc2_core_init() - Initializes the DWC_otg controller registers and * prepares the core for device mode or host mode operation * - * @hsotg: Programming view of the DWC_otg controller - * @select_phy: If true then also set the Phy type - * @irq: If >= 0, the irq to register + * @hsotg: Programming view of the DWC_otg controller + * @initial_setup: If true then this is the first init for this instance. */ -int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq) +int dwc2_core_init(struct dwc2_hsotg *hsotg, bool initial_setup) { u32 usbcfg, otgctl; int retval; @@ -791,18 +790,26 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq) dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); - /* Reset the Controller */ - retval = dwc2_core_reset(hsotg); - if (retval) { - dev_err(hsotg->dev, "%s(): Reset failed, aborting\n", - __func__); - return retval; + /* + * Reset the Controller + * + * We only need to reset the controller if this is a re-init. + * For the first init we know for sure that earlier code reset us (it + * needed to in order to properly detect various parameters). + */ + if (!initial_setup) { + retval = dwc2_core_reset(hsotg); + if (retval) { + dev_err(hsotg->dev, "%s(): Reset failed, aborting\n", + __func__); + return retval; + } } /* * This needs to happen in FS mode before any other programming occurs */ - retval = dwc2_phy_init(hsotg, select_phy); + retval = dwc2_phy_init(hsotg, initial_setup); if (retval) return retval; diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index d1d855af63e67..cbece3a68c30e 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -918,7 +918,7 @@ extern void dwc2_read_packet(struct dwc2_hsotg *hsotg, u8 *dest, u16 bytes); extern void dwc2_flush_tx_fifo(struct dwc2_hsotg *hsotg, const int num); extern void dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg); -extern int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq); +extern int dwc2_core_init(struct dwc2_hsotg *hsotg, bool initial_setup); extern void dwc2_enable_global_interrupts(struct dwc2_hsotg *hcd); extern void dwc2_disable_global_interrupts(struct dwc2_hsotg *hcd); diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 880b549f737ae..8847c72e55f67 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1420,7 +1420,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work) dev_err(hsotg->dev, "Connection id status change timed out\n"); hsotg->op_state = OTG_STATE_B_PERIPHERAL; - dwc2_core_init(hsotg, false, -1); + dwc2_core_init(hsotg, false); dwc2_enable_global_interrupts(hsotg); spin_lock_irqsave(&hsotg->lock, flags); dwc2_hsotg_core_init_disconnected(hsotg, false); @@ -1443,7 +1443,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work) hsotg->op_state = OTG_STATE_A_HOST; /* Initialize the Core for Host mode */ - dwc2_core_init(hsotg, false, -1); + dwc2_core_init(hsotg, false); dwc2_enable_global_interrupts(hsotg); dwc2_hcd_start(hsotg); } @@ -3120,7 +3120,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq) dwc2_disable_global_interrupts(hsotg); /* Initialize the DWC_otg core, and select the Phy type */ - retval = dwc2_core_init(hsotg, true, irq); + retval = dwc2_core_init(hsotg, true); if (retval) goto error2; -- GitLab From f619473140df4e1a10f4c10f693d214807ebdb03 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Thu, 17 Dec 2015 11:14:54 -0800 Subject: [PATCH 1987/2855] usb: dwc2: Speed dwc2_get_hwparams() on some host-only ports On some host-only DWC2 ports (like the one in rk3288) when we set GUSBCFG_FORCEHOSTMODE in GUSBCFG and then read back, we don't see the bit set. Presumably that's because the port is always forced to HOST mode so there's no reason to implement these status bits. Since we know dwc2_core_reset() is always called before dwc2_get_hwparams() and we know dwc2_core_reset() should have set GUSBCFG_FORCEHOSTMODE whenever hsotg->dr_mode == USB_DR_MODE_HOST, we can just check hsotg->dr_mode to decide that we can skip the delays in dwc2_get_hwparams(). Signed-off-by: Douglas Anderson Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index af12778b0e96e..c143ac444bba9 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -3102,7 +3102,7 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) unsigned width; u32 hwcfg1, hwcfg2, hwcfg3, hwcfg4; u32 hptxfsiz, grxfsiz, gnptxfsiz; - u32 gusbcfg; + u32 gusbcfg = 0; /* * Attempt to ensure this device is really a DWC_otg Controller. @@ -3135,8 +3135,8 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "grxfsiz=%08x\n", grxfsiz); /* Force host mode to get HPTXFSIZ / GNPTXFSIZ exact power on value */ - gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); - if (!(gusbcfg & GUSBCFG_FORCEHOSTMODE)) { + if (hsotg->dr_mode != USB_DR_MODE_HOST) { + gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); dwc2_writel(gusbcfg | GUSBCFG_FORCEHOSTMODE, hsotg->regs + GUSBCFG); usleep_range(100000, 150000); @@ -3146,7 +3146,7 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ); dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz); dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hptxfsiz); - if (!(gusbcfg & GUSBCFG_FORCEHOSTMODE)) { + if (hsotg->dr_mode != USB_DR_MODE_HOST) { dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); usleep_range(100000, 150000); } -- GitLab From 20bde643434d541bc5f662c5836a05e9e276eca3 Mon Sep 17 00:00:00 2001 From: Yunzhi Li Date: Thu, 17 Dec 2015 11:15:08 -0800 Subject: [PATCH 1988/2855] usb: dwc2: reduce dwc2 driver probe time I found that the probe function of dwc2 driver takes much time when kernel boot up. There are many long delays in the probe function these take almost 1 second. This patch trying to reduce unnecessary delay time. In dwc2_core_reset() I see it use two at least 20ms delays to wait AHB idle and core soft reset, but dwc2 data book said that dwc2 core soft reset and AHB idle just need a few clocks (I think it refers to AHB clock, and AHB clock run at 150MHz in my RK3288 board), so 20ms is too long, delay 1us for wait AHB idle and soft reset is enough. And in dwc2_get_hwparams() it takes 150ms to wait ForceHostMode and ForceDeviceMode valid but in data book it said software must wait at least 25ms before the change to take effect, so I reduce this time to 25ms~50ms. By the way, is there any state bit show that the force mode take effect ? Could we poll curmod bit for figuring out if the change take effect ? It seems that usleep_range() at boot time will pick the longest value in the range. In dwc2_core_reset() there is a very long delay takes 200ms, and this function run twice when probe, could any one tell me is this delay time resonable ? I have tried this patch in my RK3288-evb board. It works well. Signed-off-by: Yunzhi Li Signed-off-by: Douglas Anderson Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index c143ac444bba9..9659dbd33c8c5 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -491,7 +491,7 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg) /* Wait for AHB master IDLE state */ do { - usleep_range(20000, 40000); + udelay(1); greset = dwc2_readl(hsotg->regs + GRSTCTL); if (++count > 50) { dev_warn(hsotg->dev, @@ -506,7 +506,7 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg) greset |= GRSTCTL_CSFTRST; dwc2_writel(greset, hsotg->regs + GRSTCTL); do { - usleep_range(20000, 40000); + udelay(1); greset = dwc2_readl(hsotg->regs + GRSTCTL); if (++count > 50) { dev_warn(hsotg->dev, @@ -537,7 +537,7 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg) * NOTE: This long sleep is _very_ important, otherwise the core will * not stay in host mode after a connector ID change! */ - usleep_range(150000, 200000); + usleep_range(150000, 160000); return 0; } @@ -3139,7 +3139,7 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); dwc2_writel(gusbcfg | GUSBCFG_FORCEHOSTMODE, hsotg->regs + GUSBCFG); - usleep_range(100000, 150000); + usleep_range(25000, 50000); } gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ); @@ -3148,7 +3148,7 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hptxfsiz); if (hsotg->dr_mode != USB_DR_MODE_HOST) { dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); - usleep_range(100000, 150000); + usleep_range(25000, 50000); } /* hwcfg2 */ -- GitLab From 7d56cc2620f523eba7a831daa22186c8ae5bbdfe Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Thu, 17 Dec 2015 11:15:21 -0800 Subject: [PATCH 1989/2855] usb: dwc2: Avoid more calls to dwc2_core_reset() Calls to dwc2_core_reset() are currently very slow, taking at least 150ms (possibly more). It behooves us to take as many of these calls out as possible. It turns out that the calls in dwc2_fs_phy_init() and dwc2_hs_phy_init() should (as documented in the code) only be needed if we need to do a PHY SELECT. That means that if we see that we can avoid the PHY SELECT then we can avoid the reset. This patch appears to successfully bypass two resets (one per USB device) on rk3288-based ARM Chromebooks. Signed-off-by: Douglas Anderson Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 9659dbd33c8c5..c8f66ad48a55c 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -553,16 +553,20 @@ static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) */ if (select_phy) { dev_dbg(hsotg->dev, "FS PHY selected\n"); + usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); - usbcfg |= GUSBCFG_PHYSEL; - dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); + if (!(usbcfg & GUSBCFG_PHYSEL)) { + usbcfg |= GUSBCFG_PHYSEL; + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); - /* Reset after a PHY select */ - retval = dwc2_core_reset(hsotg); - if (retval) { - dev_err(hsotg->dev, "%s() Reset failed, aborting", - __func__); - return retval; + /* Reset after a PHY select */ + retval = dwc2_core_reset(hsotg); + + if (retval) { + dev_err(hsotg->dev, + "%s: Reset failed, aborting", __func__); + return retval; + } } } @@ -597,13 +601,13 @@ static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) { - u32 usbcfg; + u32 usbcfg, usbcfg_old; int retval = 0; if (!select_phy) return 0; - usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); + usbcfg = usbcfg_old = dwc2_readl(hsotg->regs + GUSBCFG); /* * HS PHY parameters. These parameters are preserved during soft reset @@ -631,14 +635,16 @@ static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) break; } - dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); + if (usbcfg != usbcfg_old) { + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); - /* Reset after setting the PHY parameters */ - retval = dwc2_core_reset(hsotg); - if (retval) { - dev_err(hsotg->dev, "%s() Reset failed, aborting", - __func__); - return retval; + /* Reset after setting the PHY parameters */ + retval = dwc2_core_reset(hsotg); + if (retval) { + dev_err(hsotg->dev, + "%s: Reset failed, aborting", __func__); + return retval; + } } return retval; -- GitLab From b8ccc593eeeacde0e6794c4dcec0a57eba7356e6 Mon Sep 17 00:00:00 2001 From: John Youn Date: Thu, 17 Dec 2015 11:15:35 -0800 Subject: [PATCH 1990/2855] usb: dwc2: Reorder AHBIDLE and CSFTRST in dwc2_core_reset() According to the databook, the core soft reset should be done before checking for AHBIDLE. The gadget version of core reset had it correct but the hcd version did not. This fixes the hcd version. Signed-off-by: John Youn Reviewed-by: Douglas Anderson Tested-by: Douglas Anderson Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index c8f66ad48a55c..62505068abf2e 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -489,32 +489,33 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg) dev_vdbg(hsotg->dev, "%s()\n", __func__); - /* Wait for AHB master IDLE state */ + /* Core Soft Reset */ + greset = dwc2_readl(hsotg->regs + GRSTCTL); + greset |= GRSTCTL_CSFTRST; + dwc2_writel(greset, hsotg->regs + GRSTCTL); do { udelay(1); greset = dwc2_readl(hsotg->regs + GRSTCTL); if (++count > 50) { dev_warn(hsotg->dev, - "%s() HANG! AHB Idle GRSTCTL=%0x\n", + "%s() HANG! Soft Reset GRSTCTL=%0x\n", __func__, greset); return -EBUSY; } - } while (!(greset & GRSTCTL_AHBIDLE)); + } while (greset & GRSTCTL_CSFTRST); - /* Core Soft Reset */ + /* Wait for AHB master IDLE state */ count = 0; - greset |= GRSTCTL_CSFTRST; - dwc2_writel(greset, hsotg->regs + GRSTCTL); do { udelay(1); greset = dwc2_readl(hsotg->regs + GRSTCTL); if (++count > 50) { dev_warn(hsotg->dev, - "%s() HANG! Soft Reset GRSTCTL=%0x\n", + "%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__, greset); return -EBUSY; } - } while (greset & GRSTCTL_CSFTRST); + } while (!(greset & GRSTCTL_AHBIDLE)); if (hsotg->dr_mode == USB_DR_MODE_HOST) { gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); -- GitLab From 6d58f346a61ff50eda740e6216e9829e572d75c8 Mon Sep 17 00:00:00 2001 From: John Youn Date: Thu, 17 Dec 2015 11:15:49 -0800 Subject: [PATCH 1991/2855] usb: dwc2: Rename dwc2_core_reset() Renamed dwc2_core_reset() to dwc2_core_reset_and_force_dr_mode(). This describes what it is doing more accurately. This is in preparation of introducing a plain dwc2_core_reset() function that only performs the reset and doesn't force the mode. Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 8 ++++---- drivers/usb/dwc2/core.h | 2 +- drivers/usb/dwc2/platform.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 62505068abf2e..eb291c9e3c169 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -481,7 +481,7 @@ static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg) * Do core a soft reset of the core. Be careful with this because it * resets all the internal state machines of the core. */ -int dwc2_core_reset(struct dwc2_hsotg *hsotg) +int dwc2_core_reset_and_force_dr_mode(struct dwc2_hsotg *hsotg) { u32 greset; int count = 0; @@ -561,7 +561,7 @@ static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); /* Reset after a PHY select */ - retval = dwc2_core_reset(hsotg); + retval = dwc2_core_reset_and_force_dr_mode(hsotg); if (retval) { dev_err(hsotg->dev, @@ -640,7 +640,7 @@ static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); /* Reset after setting the PHY parameters */ - retval = dwc2_core_reset(hsotg); + retval = dwc2_core_reset_and_force_dr_mode(hsotg); if (retval) { dev_err(hsotg->dev, "%s: Reset failed, aborting", __func__); @@ -805,7 +805,7 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool initial_setup) * needed to in order to properly detect various parameters). */ if (!initial_setup) { - retval = dwc2_core_reset(hsotg); + retval = dwc2_core_reset_and_force_dr_mode(hsotg); if (retval) { dev_err(hsotg->dev, "%s(): Reset failed, aborting\n", __func__); diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index cbece3a68c30e..d1989c68c728a 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -880,7 +880,7 @@ enum dwc2_halt_status { * The following functions support initialization of the core driver component * and the DWC_otg controller */ -extern int dwc2_core_reset(struct dwc2_hsotg *hsotg); +extern int dwc2_core_reset_and_force_dr_mode(struct dwc2_hsotg *hsotg); extern void dwc2_core_host_init(struct dwc2_hsotg *hsotg); extern int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg); extern int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore); diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index a72302d740dde..8bd7315a06c90 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -460,7 +460,7 @@ static int dwc2_driver_probe(struct platform_device *dev) * Reset before dwc2_get_hwparams() then it could get power-on real * reset value form registers. */ - dwc2_core_reset(hsotg); + dwc2_core_reset_and_force_dr_mode(hsotg); /* Detect config values from hardware */ retval = dwc2_get_hwparams(hsotg); -- GitLab From b5d308abef1c5c0f24128845e41d414a8f8438f6 Mon Sep 17 00:00:00 2001 From: John Youn Date: Thu, 17 Dec 2015 11:16:03 -0800 Subject: [PATCH 1992/2855] usb: dwc2: Add dwc2_core_reset() dwc2_core_reset() was previously renamed to dwc2_core_reset_and_dr_force_mode(). Now add back dwc2_core_reset() which performs only a basic core reset without forcing the mode. Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 22 ++++++++++++++++++++-- drivers/usb/dwc2/core.h | 1 + 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index eb291c9e3c169..15f359fe76d3b 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -481,11 +481,10 @@ static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg) * Do core a soft reset of the core. Be careful with this because it * resets all the internal state machines of the core. */ -int dwc2_core_reset_and_force_dr_mode(struct dwc2_hsotg *hsotg) +int dwc2_core_reset(struct dwc2_hsotg *hsotg) { u32 greset; int count = 0; - u32 gusbcfg; dev_vdbg(hsotg->dev, "%s()\n", __func__); @@ -517,6 +516,25 @@ int dwc2_core_reset_and_force_dr_mode(struct dwc2_hsotg *hsotg) } } while (!(greset & GRSTCTL_AHBIDLE)); + return 0; +} + +/* + * Do core a soft reset of the core. Be careful with this because it + * resets all the internal state machines of the core. + * + * Additionally this will apply force mode as per the hsotg->dr_mode + * parameter. + */ +int dwc2_core_reset_and_force_dr_mode(struct dwc2_hsotg *hsotg) +{ + int retval; + u32 gusbcfg; + + retval = dwc2_core_reset(hsotg); + if (retval) + return retval; + if (hsotg->dr_mode == USB_DR_MODE_HOST) { gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); gusbcfg &= ~GUSBCFG_FORCEDEVMODE; diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index d1989c68c728a..15e27bb509b5b 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -880,6 +880,7 @@ enum dwc2_halt_status { * The following functions support initialization of the core driver component * and the DWC_otg controller */ +extern int dwc2_core_reset(struct dwc2_hsotg *hsotg); extern int dwc2_core_reset_and_force_dr_mode(struct dwc2_hsotg *hsotg); extern void dwc2_core_host_init(struct dwc2_hsotg *hsotg); extern int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg); -- GitLab From 6bea962053e76a4407f0d138184a8737eea960ee Mon Sep 17 00:00:00 2001 From: John Youn Date: Thu, 17 Dec 2015 11:16:17 -0800 Subject: [PATCH 1993/2855] usb: dwc2: Add functions to check the HW OTG config Added functions to query the GHWCFG2.OTG_MODE. This tells us whether the controller hardware is configured for OTG, device-only, or host-only. Signed-off-by: John Youn Tested-by: Douglas Anderson Reviewed-by: Douglas Anderson Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 37 +++++++++++++++++++++++++++++++++++++ drivers/usb/dwc2/core.h | 13 +++++++++++++ 2 files changed, 50 insertions(+) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 15f359fe76d3b..b700a47e026a6 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -3342,6 +3342,43 @@ void dwc2_disable_global_interrupts(struct dwc2_hsotg *hsotg) dwc2_writel(ahbcfg, hsotg->regs + GAHBCFG); } +/* Returns the controller's GHWCFG2.OTG_MODE. */ +unsigned dwc2_op_mode(struct dwc2_hsotg *hsotg) +{ + u32 ghwcfg2 = dwc2_readl(hsotg->regs + GHWCFG2); + + return (ghwcfg2 & GHWCFG2_OP_MODE_MASK) >> + GHWCFG2_OP_MODE_SHIFT; +} + +/* Returns true if the controller is capable of DRD. */ +bool dwc2_hw_is_otg(struct dwc2_hsotg *hsotg) +{ + unsigned op_mode = dwc2_op_mode(hsotg); + + return (op_mode == GHWCFG2_OP_MODE_HNP_SRP_CAPABLE) || + (op_mode == GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE) || + (op_mode == GHWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE); +} + +/* Returns true if the controller is host-only. */ +bool dwc2_hw_is_host(struct dwc2_hsotg *hsotg) +{ + unsigned op_mode = dwc2_op_mode(hsotg); + + return (op_mode == GHWCFG2_OP_MODE_SRP_CAPABLE_HOST) || + (op_mode == GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST); +} + +/* Returns true if the controller is device-only. */ +bool dwc2_hw_is_device(struct dwc2_hsotg *hsotg) +{ + unsigned op_mode = dwc2_op_mode(hsotg); + + return (op_mode == GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) || + (op_mode == GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE); +} + MODULE_DESCRIPTION("DESIGNWARE HS OTG Core"); MODULE_AUTHOR("Synopsys, Inc."); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 15e27bb509b5b..1fd434510a43b 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -1137,6 +1137,19 @@ extern int dwc2_get_hwparams(struct dwc2_hsotg *hsotg); extern int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg); extern int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg); +/* + * The following functions check the controller's OTG operation mode + * capability (GHWCFG2.OTG_MODE). + * + * These functions can be used before the internal hsotg->hw_params + * are read in and cached so they always read directly from the + * GHWCFG2 register. + */ +unsigned dwc2_op_mode(struct dwc2_hsotg *hsotg); +bool dwc2_hw_is_otg(struct dwc2_hsotg *hsotg); +bool dwc2_hw_is_host(struct dwc2_hsotg *hsotg); +bool dwc2_hw_is_device(struct dwc2_hsotg *hsotg); + /* * Dump core registers and SPRAM */ -- GitLab From 5268ed9d2e3b52f703f3661eef14cecbb2b572d4 Mon Sep 17 00:00:00 2001 From: John Youn Date: Thu, 17 Dec 2015 11:16:31 -0800 Subject: [PATCH 1994/2855] usb: dwc2: Fix dr_mode validation The dr_mode parameter was being checked against how the dwc2 module was being configured at compile time. But it wasn't checked against the hardware capabilities, nor were the hardware capabilities checked against the compilation parameters. This commit adds those checks and adjusts dr_mode to an appropriate value, if needed. If the hardware capabilities and module compilation do not match then we fail as it wouldn't be possible to run properly. The hardware, module, and dr_mode, can each be set to host, device, or otg. Check that all these values are compatible and adjust the value of dr_mode if possible. The following table summarizes the behavior: actual HW MOD dr_mode dr_mode ------------------------------ HST HST any : HST HST DEV any : --- HST OTG any : HST DEV HST any : --- DEV DEV any : DEV DEV OTG any : DEV OTG HST any : HST OTG DEV any : DEV OTG OTG any : dr_mode Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/platform.c | 82 +++++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 13 deletions(-) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 8bd7315a06c90..f4366513acb6b 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -149,6 +149,71 @@ static const struct dwc2_core_params params_rk3066 = { .hibernation = -1, }; +/* + * Check the dr_mode against the module configuration and hardware + * capabilities. + * + * The hardware, module, and dr_mode, can each be set to host, device, + * or otg. Check that all these values are compatible and adjust the + * value of dr_mode if possible. + * + * actual + * HW MOD dr_mode dr_mode + * ------------------------------ + * HST HST any : HST + * HST DEV any : --- + * HST OTG any : HST + * + * DEV HST any : --- + * DEV DEV any : DEV + * DEV OTG any : DEV + * + * OTG HST any : HST + * OTG DEV any : DEV + * OTG OTG any : dr_mode + */ +static int dwc2_get_dr_mode(struct dwc2_hsotg *hsotg) +{ + enum usb_dr_mode mode; + + hsotg->dr_mode = usb_get_dr_mode(hsotg->dev); + if (hsotg->dr_mode == USB_DR_MODE_UNKNOWN) + hsotg->dr_mode = USB_DR_MODE_OTG; + + mode = hsotg->dr_mode; + + if (dwc2_hw_is_device(hsotg)) { + if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) { + dev_err(hsotg->dev, + "Controller does not support host mode.\n"); + return -EINVAL; + } + mode = USB_DR_MODE_PERIPHERAL; + } else if (dwc2_hw_is_host(hsotg)) { + if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL)) { + dev_err(hsotg->dev, + "Controller does not support device mode.\n"); + return -EINVAL; + } + mode = USB_DR_MODE_HOST; + } else { + if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) + mode = USB_DR_MODE_HOST; + else if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL)) + mode = USB_DR_MODE_PERIPHERAL; + } + + if (mode != hsotg->dr_mode) { + dev_warn(hsotg->dev, + "Configuration mismatch. dr_mode forced to %s\n", + mode == USB_DR_MODE_HOST ? "host" : "device"); + + hsotg->dr_mode = mode; + } + + return 0; +} + static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg) { struct platform_device *pdev = to_platform_device(hsotg->dev); @@ -412,19 +477,6 @@ static int dwc2_driver_probe(struct platform_device *dev) dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n", (unsigned long)res->start, hsotg->regs); - hsotg->dr_mode = usb_get_dr_mode(&dev->dev); - if (IS_ENABLED(CONFIG_USB_DWC2_HOST) && - hsotg->dr_mode != USB_DR_MODE_HOST) { - hsotg->dr_mode = USB_DR_MODE_HOST; - dev_warn(hsotg->dev, - "Configuration mismatch. Forcing host mode\n"); - } else if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) && - hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) { - hsotg->dr_mode = USB_DR_MODE_PERIPHERAL; - dev_warn(hsotg->dev, - "Configuration mismatch. Forcing peripheral mode\n"); - } - retval = dwc2_lowlevel_hw_init(hsotg); if (retval) return retval; @@ -456,6 +508,10 @@ static int dwc2_driver_probe(struct platform_device *dev) if (retval) return retval; + retval = dwc2_get_dr_mode(hsotg); + if (retval) + return retval; + /* * Reset before dwc2_get_hwparams() then it could get power-on real * reset value form registers. -- GitLab From 1696d5ab99ef885ae62da5ad58f9eff16da7ff78 Mon Sep 17 00:00:00 2001 From: John Youn Date: Thu, 17 Dec 2015 11:16:45 -0800 Subject: [PATCH 1995/2855] usb: dwc2: Move mode querying functions into core.h These functions should go in core.h where they can be called from core, device, or host. Signed-off-by: John Youn Reviewed-by: Douglas Anderson Tested-by: Douglas Anderson Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.h | 12 ++++++++++++ drivers/usb/dwc2/hcd.h | 12 ------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 1fd434510a43b..263a9da9edb20 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -1150,6 +1150,18 @@ bool dwc2_hw_is_otg(struct dwc2_hsotg *hsotg); bool dwc2_hw_is_host(struct dwc2_hsotg *hsotg); bool dwc2_hw_is_device(struct dwc2_hsotg *hsotg); +/* + * Returns the mode of operation, host or device + */ +static inline int dwc2_is_host_mode(struct dwc2_hsotg *hsotg) +{ + return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) != 0; +} +static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg) +{ + return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) == 0; +} + /* * Dump core registers and SPRAM */ diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h index 6e822661a69e3..8f0a29cefdf78 100644 --- a/drivers/usb/dwc2/hcd.h +++ b/drivers/usb/dwc2/hcd.h @@ -383,18 +383,6 @@ static inline void disable_hc_int(struct dwc2_hsotg *hsotg, int chnum, u32 intr) dwc2_writel(mask, hsotg->regs + HCINTMSK(chnum)); } -/* - * Returns the mode of operation, host or device - */ -static inline int dwc2_is_host_mode(struct dwc2_hsotg *hsotg) -{ - return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) != 0; -} -static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg) -{ - return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) == 0; -} - /* * Reads HPRT0 in preparation to modify. It keeps the WC bits 0 so that if they * are read as 1, they won't clear when written back. -- GitLab From 263b7fb557f797d9d4d1dcf93fb6bb2efc3f1d46 Mon Sep 17 00:00:00 2001 From: John Youn Date: Thu, 17 Dec 2015 11:16:58 -0800 Subject: [PATCH 1996/2855] usb: dwc2: Move reset into dwc2_get_hwparams() The reset is required to get reset values of the hardware parameters but the force mode is not. Move the base reset into dwc2_get_hwparams() and do the reset and force mode afterwards. Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 8 ++++++++ drivers/usb/dwc2/platform.c | 10 +++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index b700a47e026a6..3b55635c878ca 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -3120,6 +3120,9 @@ void dwc2_set_parameters(struct dwc2_hsotg *hsotg, /** * During device initialization, read various hardware configuration * registers and interpret the contents. + * + * This should be called during driver probe. It will perform a core + * soft reset in order to get the reset values of the parameters. */ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) { @@ -3128,6 +3131,7 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) u32 hwcfg1, hwcfg2, hwcfg3, hwcfg4; u32 hptxfsiz, grxfsiz, gnptxfsiz; u32 gusbcfg = 0; + int retval; /* * Attempt to ensure this device is really a DWC_otg Controller. @@ -3147,6 +3151,10 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) hw->snpsid >> 12 & 0xf, hw->snpsid >> 8 & 0xf, hw->snpsid >> 4 & 0xf, hw->snpsid & 0xf, hw->snpsid); + retval = dwc2_core_reset(hsotg); + if (retval) + return retval; + hwcfg1 = dwc2_readl(hsotg->regs + GHWCFG1); hwcfg2 = dwc2_readl(hsotg->regs + GHWCFG2); hwcfg3 = dwc2_readl(hsotg->regs + GHWCFG3); diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index f4366513acb6b..bfa4a6a8a1f34 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -512,13 +512,7 @@ static int dwc2_driver_probe(struct platform_device *dev) if (retval) return retval; - /* - * Reset before dwc2_get_hwparams() then it could get power-on real - * reset value form registers. - */ - dwc2_core_reset_and_force_dr_mode(hsotg); - - /* Detect config values from hardware */ + /* Reset the controller and detect hardware config values */ retval = dwc2_get_hwparams(hsotg); if (retval) goto error; @@ -526,6 +520,8 @@ static int dwc2_driver_probe(struct platform_device *dev) /* Validate parameter values */ dwc2_set_parameters(hsotg, params); + dwc2_core_reset_and_force_dr_mode(hsotg); + if (hsotg->dr_mode != USB_DR_MODE_HOST) { retval = dwc2_gadget_init(hsotg, irq); if (retval) -- GitLab From 09c96980dc723462ed2eeacc945fed5bcb278f85 Mon Sep 17 00:00:00 2001 From: John Youn Date: Thu, 17 Dec 2015 11:17:12 -0800 Subject: [PATCH 1997/2855] usb: dwc2: Add functions to set and clear force mode Added functions to set force mode for host and device. These functions will check the current mode and only force if needed thus avoiding unnecessary force mode delays. However clearing the mode is currently done unconditionally and with the delay in place. This is needed during the connector ID status change interrupt in order to ensure that the mode has changed properly. This preserves the old behavior only for this case. The warning comment about this is moved into the clear mode condition. Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 149 +++++++++++++++++++++++++++++++++------- drivers/usb/dwc2/core.h | 2 + 2 files changed, 127 insertions(+), 24 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 3b55635c878ca..436e7d1ef3c8e 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -519,6 +519,114 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg) return 0; } +/* + * Force the mode of the controller. + * + * Forcing the mode is needed for two cases: + * + * 1) If the dr_mode is set to either HOST or PERIPHERAL we force the + * controller to stay in a particular mode regardless of ID pin + * changes. We do this usually after a core reset. + * + * 2) During probe we want to read reset values of the hw + * configuration registers that are only available in either host or + * device mode. We may need to force the mode if the current mode does + * not allow us to access the register in the mode that we want. + * + * In either case it only makes sense to force the mode if the + * controller hardware is OTG capable. + * + * Checks are done in this function to determine whether doing a force + * would be valid or not. + * + * If a force is done, it requires a 25ms delay to take effect. + * + * Returns true if the mode was forced. + */ +static bool dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host) +{ + u32 gusbcfg; + u32 set; + u32 clear; + + dev_dbg(hsotg->dev, "Forcing mode to %s\n", host ? "host" : "device"); + + /* + * Force mode has no effect if the hardware is not OTG. + */ + if (!dwc2_hw_is_otg(hsotg)) + return false; + + /* + * If dr_mode is either peripheral or host only, there is no + * need to ever force the mode to the opposite mode. + */ + if (WARN_ON(host && hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)) + return false; + + if (WARN_ON(!host && hsotg->dr_mode == USB_DR_MODE_HOST)) + return false; + + gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); + + set = host ? GUSBCFG_FORCEHOSTMODE : GUSBCFG_FORCEDEVMODE; + clear = host ? GUSBCFG_FORCEDEVMODE : GUSBCFG_FORCEHOSTMODE; + + /* + * If the force mode bit is already set, don't set it. + */ + if ((gusbcfg & set) && !(gusbcfg & clear)) + return false; + + gusbcfg &= ~clear; + gusbcfg |= set; + dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); + + msleep(25); + return true; +} + +/* + * Clears the force mode bits. + */ +static void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg) +{ + u32 gusbcfg; + + gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); + gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; + gusbcfg &= ~GUSBCFG_FORCEDEVMODE; + dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); + + /* + * NOTE: This long sleep is _very_ important, otherwise the core will + * not stay in host mode after a connector ID change! + */ + usleep_range(150000, 160000); +} + +/* + * Sets or clears force mode based on the dr_mode parameter. + */ +void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg) +{ + switch (hsotg->dr_mode) { + case USB_DR_MODE_HOST: + dwc2_force_mode(hsotg, true); + break; + case USB_DR_MODE_PERIPHERAL: + dwc2_force_mode(hsotg, false); + break; + case USB_DR_MODE_OTG: + dwc2_clear_force_mode(hsotg); + break; + default: + dev_warn(hsotg->dev, "%s() Invalid dr_mode=%d\n", + __func__, hsotg->dr_mode); + break; + } +} + /* * Do core a soft reset of the core. Be careful with this because it * resets all the internal state machines of the core. @@ -529,35 +637,12 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg) int dwc2_core_reset_and_force_dr_mode(struct dwc2_hsotg *hsotg) { int retval; - u32 gusbcfg; retval = dwc2_core_reset(hsotg); if (retval) return retval; - if (hsotg->dr_mode == USB_DR_MODE_HOST) { - gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); - gusbcfg &= ~GUSBCFG_FORCEDEVMODE; - gusbcfg |= GUSBCFG_FORCEHOSTMODE; - dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); - } else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) { - gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); - gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; - gusbcfg |= GUSBCFG_FORCEDEVMODE; - dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); - } else if (hsotg->dr_mode == USB_DR_MODE_OTG) { - gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); - gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; - gusbcfg &= ~GUSBCFG_FORCEDEVMODE; - dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); - } - - /* - * NOTE: This long sleep is _very_ important, otherwise the core will - * not stay in host mode after a connector ID change! - */ - usleep_range(150000, 160000); - + dwc2_force_dr_mode(hsotg); return 0; } @@ -3117,6 +3202,22 @@ void dwc2_set_parameters(struct dwc2_hsotg *hsotg, dwc2_set_param_hibernation(hsotg, params->hibernation); } +/* + * Forces either host or device mode if the controller is not + * currently in that mode. + * + * Returns true if the mode was forced. + */ +static bool dwc2_force_mode_if_needed(struct dwc2_hsotg *hsotg, bool host) +{ + if (host && dwc2_is_host_mode(hsotg)) + return false; + else if (!host && dwc2_is_device_mode(hsotg)) + return false; + + return dwc2_force_mode(hsotg, host); +} + /** * During device initialization, read various hardware configuration * registers and interpret the contents. diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 263a9da9edb20..efdbe455697f5 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -886,6 +886,8 @@ extern void dwc2_core_host_init(struct dwc2_hsotg *hsotg); extern int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg); extern int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore); +void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg); + /* * Host core Functions. * The following functions support managing the DWC_otg controller in host -- GitLab From 55e1040e424b59063da627fb580ec953f4c01de7 Mon Sep 17 00:00:00 2001 From: John Youn Date: Thu, 17 Dec 2015 11:17:31 -0800 Subject: [PATCH 1998/2855] usb: dwc2: Improve handling of host and device hwparams Adds separate functions to get the host and device specific hardware parameters. The functions check whether the parameters need to be read at all, depending on dr_mode, and forces the mode only if necessary. This saves some delays during probe. This also adds two device mode parameters that will be used by the gadget. Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 88 +++++++++++++++++++++++++++++++---------- drivers/usb/dwc2/core.h | 3 ++ 2 files changed, 70 insertions(+), 21 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 436e7d1ef3c8e..9dca83544b5e4 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -3218,6 +3218,63 @@ static bool dwc2_force_mode_if_needed(struct dwc2_hsotg *hsotg, bool host) return dwc2_force_mode(hsotg, host); } +/* + * Gets host hardware parameters. Forces host mode if not currently in + * host mode. Should be called immediately after a core soft reset in + * order to get the reset values. + */ +static void dwc2_get_host_hwparams(struct dwc2_hsotg *hsotg) +{ + struct dwc2_hw_params *hw = &hsotg->hw_params; + u32 gnptxfsiz; + u32 hptxfsiz; + bool forced; + + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + return; + + forced = dwc2_force_mode_if_needed(hsotg, true); + + gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ); + hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ); + dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz); + dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hptxfsiz); + + if (forced) + dwc2_clear_force_mode(hsotg); + + hw->host_nperio_tx_fifo_size = (gnptxfsiz & FIFOSIZE_DEPTH_MASK) >> + FIFOSIZE_DEPTH_SHIFT; + hw->host_perio_tx_fifo_size = (hptxfsiz & FIFOSIZE_DEPTH_MASK) >> + FIFOSIZE_DEPTH_SHIFT; +} + +/* + * Gets device hardware parameters. Forces device mode if not + * currently in device mode. Should be called immediately after a core + * soft reset in order to get the reset values. + */ +static void dwc2_get_dev_hwparams(struct dwc2_hsotg *hsotg) +{ + struct dwc2_hw_params *hw = &hsotg->hw_params; + bool forced; + u32 gnptxfsiz; + + if (hsotg->dr_mode == USB_DR_MODE_HOST) + return; + + forced = dwc2_force_mode_if_needed(hsotg, false); + + gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ); + dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz); + + if (forced) + dwc2_clear_force_mode(hsotg); + + hw->dev_nperio_tx_fifo_size = (gnptxfsiz & FIFOSIZE_DEPTH_MASK) >> + FIFOSIZE_DEPTH_SHIFT; +} + /** * During device initialization, read various hardware configuration * registers and interpret the contents. @@ -3230,8 +3287,7 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) struct dwc2_hw_params *hw = &hsotg->hw_params; unsigned width; u32 hwcfg1, hwcfg2, hwcfg3, hwcfg4; - u32 hptxfsiz, grxfsiz, gnptxfsiz; - u32 gusbcfg = 0; + u32 grxfsiz; int retval; /* @@ -3268,22 +3324,16 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "hwcfg4=%08x\n", hwcfg4); dev_dbg(hsotg->dev, "grxfsiz=%08x\n", grxfsiz); - /* Force host mode to get HPTXFSIZ / GNPTXFSIZ exact power on value */ - if (hsotg->dr_mode != USB_DR_MODE_HOST) { - gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); - dwc2_writel(gusbcfg | GUSBCFG_FORCEHOSTMODE, - hsotg->regs + GUSBCFG); - usleep_range(25000, 50000); - } + /* + * Host specific hardware parameters. Reading these parameters + * requires the controller to be in host mode. The mode will + * be forced, if necessary, to read these values. + */ + dwc2_get_host_hwparams(hsotg); + dwc2_get_dev_hwparams(hsotg); - gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ); - hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ); - dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz); - dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hptxfsiz); - if (hsotg->dr_mode != USB_DR_MODE_HOST) { - dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); - usleep_range(25000, 50000); - } + /* hwcfg1 */ + hw->dev_ep_dirs = hwcfg1; /* hwcfg2 */ hw->op_mode = (hwcfg2 & GHWCFG2_OP_MODE_MASK) >> @@ -3339,10 +3389,6 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) /* fifo sizes */ hw->host_rx_fifo_size = (grxfsiz & GRXFSIZ_DEPTH_MASK) >> GRXFSIZ_DEPTH_SHIFT; - hw->host_nperio_tx_fifo_size = (gnptxfsiz & FIFOSIZE_DEPTH_MASK) >> - FIFOSIZE_DEPTH_SHIFT; - hw->host_perio_tx_fifo_size = (hptxfsiz & FIFOSIZE_DEPTH_MASK) >> - FIFOSIZE_DEPTH_SHIFT; dev_dbg(hsotg->dev, "Detected values from hardware:\n"); dev_dbg(hsotg->dev, " op_mode=%d\n", diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index efdbe455697f5..7fb6434f46397 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -459,6 +459,7 @@ struct dwc2_core_params { * 1 - 16 bits * 2 - 8 or 16 bits * @snpsid: Value from SNPSID register + * @dev_ep_dirs: Direction of device endpoints (GHWCFG1) */ struct dwc2_hw_params { unsigned op_mode:3; @@ -469,6 +470,7 @@ struct dwc2_hw_params { unsigned en_multiple_tx_fifo:1; unsigned host_rx_fifo_size:16; unsigned host_nperio_tx_fifo_size:16; + unsigned dev_nperio_tx_fifo_size:16; unsigned host_perio_tx_fifo_size:16; unsigned nperio_tx_q_depth:3; unsigned host_perio_tx_q_depth:3; @@ -485,6 +487,7 @@ struct dwc2_hw_params { unsigned power_optimized:1; unsigned utmi_phy_data_width:2; u32 snpsid; + u32 dev_ep_dirs; }; /* Size of control and EP0 buffers */ -- GitLab From 58e9042f5f130bf3f9043cf75aa2632fc12140e6 Mon Sep 17 00:00:00 2001 From: Adriana Reus Date: Mon, 14 Dec 2015 14:24:45 +0200 Subject: [PATCH 1999/2855] iio: light: us5182d: Fix enable status inconcistency When setting als only or proximity only modes make sure that we mark the other component as disabled. This fix is in preparation of adding event support because that will make it possible to switch between one-shot and continuous modes and not tracking these correctly may cause faulty behaviour (e.g wrongfully considering px enabled and not setting an appropriate mode in the chip). Signed-off-by: Adriana Reus Signed-off-by: Jonathan Cameron --- drivers/iio/light/us5182d.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c index 256c4bc12d219..f24b687bd152c 100644 --- a/drivers/iio/light/us5182d.c +++ b/drivers/iio/light/us5182d.c @@ -238,8 +238,12 @@ static int us5182d_als_enable(struct us5182d_data *data) int ret; u8 mode; - if (data->power_mode == US5182D_ONESHOT) - return us5182d_set_opmode(data, US5182D_ALS_ONLY); + if (data->power_mode == US5182D_ONESHOT) { + ret = us5182d_set_opmode(data, US5182D_ALS_ONLY); + if (ret < 0) + return ret; + data->px_enabled = false; + } if (data->als_enabled) return 0; @@ -260,8 +264,12 @@ static int us5182d_px_enable(struct us5182d_data *data) int ret; u8 mode; - if (data->power_mode == US5182D_ONESHOT) - return us5182d_set_opmode(data, US5182D_PX_ONLY); + if (data->power_mode == US5182D_ONESHOT) { + ret = us5182d_set_opmode(data, US5182D_PX_ONLY); + if (ret < 0) + return ret; + data->als_enabled = false; + } if (data->px_enabled) return 0; -- GitLab From 43e9034904dd37db7ed87fa8f5039c561c4004cd Mon Sep 17 00:00:00 2001 From: John Youn Date: Thu, 17 Dec 2015 11:17:45 -0800 Subject: [PATCH 2000/2855] usb: dwc2: gadget: Use hw params from core Use the previously cached hw params in the gadget. This saves a reset and force mode in the gadget initialization during probe and makes getting the hardware parameters consistent between gadget and host. Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 41 +++++++++++++++------------------------ 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 3a24cbf355a9e..5f63058f854ea 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3403,8 +3403,8 @@ static int dwc2_hsotg_hw_cfg(struct dwc2_hsotg *hsotg) /* check hardware configuration */ - cfg = dwc2_readl(hsotg->regs + GHWCFG2); - hsotg->num_of_eps = (cfg >> GHWCFG2_NUM_DEV_EP_SHIFT) & 0xF; + hsotg->num_of_eps = hsotg->hw_params.num_dev_ep; + /* Add ep0 */ hsotg->num_of_eps++; @@ -3415,7 +3415,7 @@ static int dwc2_hsotg_hw_cfg(struct dwc2_hsotg *hsotg) /* Same dwc2_hsotg_ep is used in both directions for ep0 */ hsotg->eps_out[0] = hsotg->eps_in[0]; - cfg = dwc2_readl(hsotg->regs + GHWCFG1); + cfg = hsotg->hw_params.dev_ep_dirs; for (i = 1, cfg >>= 2; i < hsotg->num_of_eps; i++, cfg >>= 2) { ep_type = cfg & 3; /* Direction in or both */ @@ -3434,11 +3434,8 @@ static int dwc2_hsotg_hw_cfg(struct dwc2_hsotg *hsotg) } } - cfg = dwc2_readl(hsotg->regs + GHWCFG3); - hsotg->fifo_mem = (cfg >> GHWCFG3_DFIFO_DEPTH_SHIFT); - - cfg = dwc2_readl(hsotg->regs + GHWCFG4); - hsotg->dedicated_fifos = (cfg >> GHWCFG4_DED_FIFO_SHIFT) & 1; + hsotg->fifo_mem = hsotg->hw_params.total_fifo_size; + hsotg->dedicated_fifos = hsotg->hw_params.en_multiple_tx_fifo; dev_info(hsotg->dev, "EPs: %d, %s fifos, %d entries in SPRAM\n", hsotg->num_of_eps, @@ -3563,6 +3560,17 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) memcpy(&hsotg->g_tx_fifo_sz[1], p_tx_fifo, sizeof(p_tx_fifo)); /* Device tree specific probe */ dwc2_hsotg_of_probe(hsotg); + + /* Check against largest possible value. */ + if (hsotg->g_np_g_tx_fifo_sz > + hsotg->hw_params.dev_nperio_tx_fifo_size) { + dev_warn(dev, "Specified GNPTXFDEP=%d > %d\n", + hsotg->g_np_g_tx_fifo_sz, + hsotg->hw_params.dev_nperio_tx_fifo_size); + hsotg->g_np_g_tx_fifo_sz = + hsotg->hw_params.dev_nperio_tx_fifo_size; + } + /* Dump fifo information */ dev_dbg(dev, "NonPeriodic TXFIFO size: %d\n", hsotg->g_np_g_tx_fifo_sz); @@ -3579,20 +3587,6 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) hsotg->op_state = OTG_STATE_B_PERIPHERAL; - /* - * Force Device mode before initialization. - * This allows correctly configuring fifo for device mode. - */ - __bic32(hsotg->regs + GUSBCFG, GUSBCFG_FORCEHOSTMODE); - __orr32(hsotg->regs + GUSBCFG, GUSBCFG_FORCEDEVMODE); - - /* - * According to Synopsys databook, this sleep is needed for the force - * device mode to take effect. - */ - msleep(25); - - dwc2_hsotg_corereset(hsotg); ret = dwc2_hsotg_hw_cfg(hsotg); if (ret) { dev_err(hsotg->dev, "Hardware configuration failed: %d\n", ret); @@ -3601,9 +3595,6 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) dwc2_hsotg_init(hsotg); - /* Switch back to default configuration */ - __bic32(hsotg->regs + GUSBCFG, GUSBCFG_FORCEDEVMODE); - hsotg->ctrl_buff = devm_kzalloc(hsotg->dev, DWC2_CTRL_BUFF_SIZE, GFP_KERNEL); if (!hsotg->ctrl_buff) { -- GitLab From 241729baa932a69cd203dbaa81abbb8af5b77b65 Mon Sep 17 00:00:00 2001 From: John Youn Date: Thu, 17 Dec 2015 11:17:59 -0800 Subject: [PATCH 2001/2855] usb: dwc2: gadget: Replace dwc2_hsotg_corereset() The dwc2_core_reset() function exists in the core so use that one instead. Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 50 +-------------------------------------- 1 file changed, 1 insertion(+), 49 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 5f63058f854ea..628ba74d8e50a 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2243,54 +2243,6 @@ static void dwc2_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic) GINTSTS_PTXFEMP | \ GINTSTS_RXFLVL) -/** - * dwc2_hsotg_corereset - issue softreset to the core - * @hsotg: The device state - * - * Issue a soft reset to the core, and await the core finishing it. - */ -static int dwc2_hsotg_corereset(struct dwc2_hsotg *hsotg) -{ - int timeout; - u32 grstctl; - - dev_dbg(hsotg->dev, "resetting core\n"); - - /* issue soft reset */ - dwc2_writel(GRSTCTL_CSFTRST, hsotg->regs + GRSTCTL); - - timeout = 10000; - do { - grstctl = dwc2_readl(hsotg->regs + GRSTCTL); - } while ((grstctl & GRSTCTL_CSFTRST) && timeout-- > 0); - - if (grstctl & GRSTCTL_CSFTRST) { - dev_err(hsotg->dev, "Failed to get CSftRst asserted\n"); - return -EINVAL; - } - - timeout = 10000; - - while (1) { - u32 grstctl = dwc2_readl(hsotg->regs + GRSTCTL); - - if (timeout-- < 0) { - dev_info(hsotg->dev, - "%s: reset failed, GRSTCTL=%08x\n", - __func__, grstctl); - return -ETIMEDOUT; - } - - if (!(grstctl & GRSTCTL_AHBIDLE)) - continue; - - break; /* reset done */ - } - - dev_dbg(hsotg->dev, "reset successful\n"); - return 0; -} - /** * dwc2_hsotg_core_init - issue softreset to the core * @hsotg: The device state @@ -2307,7 +2259,7 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); if (!is_usb_reset) - if (dwc2_hsotg_corereset(hsotg)) + if (dwc2_core_reset(hsotg)) return; /* -- GitLab From 97e463886b873f62bea2293e7edf81fdb884b84f Mon Sep 17 00:00:00 2001 From: John Youn Date: Thu, 17 Dec 2015 11:18:13 -0800 Subject: [PATCH 2002/2855] usb: dwc2: Reduce delay when forcing mode in reset The delay for force mode is only 25ms according to the databook. Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 9dca83544b5e4..39a0fa8a4c0ae 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -602,7 +602,7 @@ static void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg) * NOTE: This long sleep is _very_ important, otherwise the core will * not stay in host mode after a connector ID change! */ - usleep_range(150000, 160000); + msleep(25); } /* -- GitLab From 25362d318371e1e271dda24995ceabb8457b3b7c Mon Sep 17 00:00:00 2001 From: John Youn Date: Thu, 17 Dec 2015 11:18:27 -0800 Subject: [PATCH 2003/2855] usb: dwc2: Remove redundant reset in probe Reset already happens before this so just force the dr_mode. Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index bfa4a6a8a1f34..1e7cb99d21008 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -520,7 +520,7 @@ static int dwc2_driver_probe(struct platform_device *dev) /* Validate parameter values */ dwc2_set_parameters(hsotg, params); - dwc2_core_reset_and_force_dr_mode(hsotg); + dwc2_force_dr_mode(hsotg); if (hsotg->dr_mode != USB_DR_MODE_HOST) { retval = dwc2_gadget_init(hsotg, irq); -- GitLab From 60c0288c72c980fb37ed4e48f68c9743a53b662c Mon Sep 17 00:00:00 2001 From: John Youn Date: Thu, 17 Dec 2015 11:18:41 -0800 Subject: [PATCH 2004/2855] usb: dwc2: gadget: Remove call to dwc2_hsotg_init() Remove call to dwc2_hsotg_init() from dwc2_gadget_init(). The gadget_init function should not access any device registers because the mode isn't guaranteed here. Also, this is already called elsewhere before anything starts on the gadget so it is not necessary here. Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 628ba74d8e50a..8ab7a9e0e5475 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3545,8 +3545,6 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) return ret; } - dwc2_hsotg_init(hsotg); - hsotg->ctrl_buff = devm_kzalloc(hsotg->dev, DWC2_CTRL_BUFF_SIZE, GFP_KERNEL); if (!hsotg->ctrl_buff) { -- GitLab From 6d76c92c2fcbee4fd1f6d7b375d71057c7a615b1 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 18 Dec 2015 03:26:17 +0100 Subject: [PATCH 2005/2855] usb: dwc2: gadget: Repair DSTS register decoding The "enumspd" field is located in register DSTS[2:1], but the code which checks the bitfield does not shift the value accordingly. This in turn causes incorrect detection of gadget link partner speed in dwc2_hsotg_irq_enumdone() . Shift the value accordingly to fix the problem with speed detection. Acked-by: John Youn Signed-off-by: Marek Vasut Cc: Felipe Balbi Cc: Greg Kroah-Hartman Cc: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 8ab7a9e0e5475..422ab7da4eb51 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2095,7 +2095,7 @@ static void dwc2_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg) */ /* catch both EnumSpd_FS and EnumSpd_FS48 */ - switch (dsts & DSTS_ENUMSPD_MASK) { + switch ((dsts & DSTS_ENUMSPD_MASK) >> DSTS_ENUMSPD_SHIFT) { case DSTS_ENUMSPD_FS: case DSTS_ENUMSPD_FS48: hsotg->gadget.speed = USB_SPEED_FULL; -- GitLab From 8a0859b65b06ea07461271ce4f1fe25b48d1ec55 Mon Sep 17 00:00:00 2001 From: "Du, Changbin" Date: Fri, 18 Dec 2015 15:36:40 +0800 Subject: [PATCH 2006/2855] usb: gadget: forbid queuing request to a disabled ep Queue a request to disabled ep doesn't make sense, and induce caller make mistakes. Here is a example for the android mtp gadget function driver. A mem corruption can happen on below senario. 1) On disconnect, mtp driver disable its EPs, 2) During send_file_work and receive_file_work, mtp queues a request to ep. (The mtp driver need improve its synchronization logic!) 3) mtp_function_unbind is invoked and all mtp requests are freed. 4) when udc process the request queued on step 2, will cause kernel NULL pointer dereference exception. Signed-off-by: Du, Changbin Signed-off-by: Felipe Balbi --- include/linux/usb/gadget.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 92467eea76def..d82d0068872b2 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -402,6 +402,9 @@ static inline void usb_ep_free_request(struct usb_ep *ep, static inline int usb_ep_queue(struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags) { + if (WARN_ON_ONCE(!ep->enabled && ep->address)) + return -ESHUTDOWN; + return ep->ops->queue(ep, req, gfp_flags); } -- GitLab From 39cee200c23eb3e28056011a1dec053beba4a18a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Dec 2015 12:02:04 +0100 Subject: [PATCH 2007/2855] usb: musb: core: call init and shutdown for the usb phy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The phy's init routine must be called before it can be used. Do so in musb_init_controller and the matching shutdown in musb_remove. Signed-off-by: Uwe Kleine-König Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 04548423094b8..c3791a01ab316 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2136,6 +2136,10 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) pm_runtime_get_sync(musb->controller); + status = usb_phy_init(musb->xceiv); + if (status < 0) + goto err_usb_phy_init; + if (use_dma && dev->dma_mask) { musb->dma_controller = musb_dma_controller_create(musb, musb->mregs); @@ -2256,7 +2260,11 @@ fail3: cancel_delayed_work_sync(&musb->deassert_reset_work); if (musb->dma_controller) musb_dma_controller_destroy(musb->dma_controller); + fail2_5: + usb_phy_shutdown(musb->xceiv); + +err_usb_phy_init: pm_runtime_put_sync(musb->controller); fail2: @@ -2317,6 +2325,8 @@ static int musb_remove(struct platform_device *pdev) if (musb->dma_controller) musb_dma_controller_destroy(musb->dma_controller); + usb_phy_shutdown(musb->xceiv); + cancel_work_sync(&musb->irq_work); cancel_delayed_work_sync(&musb->finish_resume_work); cancel_delayed_work_sync(&musb->deassert_reset_work); -- GitLab From b6695254f800698faee4f30a8f0b199459ebeafe Mon Sep 17 00:00:00 2001 From: Adriana Reus Date: Mon, 14 Dec 2015 14:24:46 +0200 Subject: [PATCH 2008/2855] iio: light: us5182d: Add interrupt support and events Add interrupt support for proximity. Add two threshold events to signal rising and falling directions. Signed-off-by: Adriana Reus Signed-off-by: Jonathan Cameron --- drivers/iio/light/us5182d.c | 271 +++++++++++++++++++++++++++++++++++- 1 file changed, 270 insertions(+), 1 deletion(-) diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c index f24b687bd152c..213f7785095fd 100644 --- a/drivers/iio/light/us5182d.c +++ b/drivers/iio/light/us5182d.c @@ -20,7 +20,10 @@ #include #include #include +#include #include +#include +#include #include #include #include @@ -30,6 +33,8 @@ #define US5182D_CFG0_ONESHOT_EN BIT(6) #define US5182D_CFG0_SHUTDOWN_EN BIT(7) #define US5182D_CFG0_WORD_ENABLE BIT(0) +#define US5182D_CFG0_PROX BIT(3) +#define US5182D_CFG0_PX_IRQ BIT(2) #define US5182D_REG_CFG1 0x01 #define US5182D_CFG1_ALS_RES16 BIT(4) @@ -41,6 +46,7 @@ #define US5182D_REG_CFG3 0x03 #define US5182D_CFG3_LED_CURRENT100 (BIT(4) | BIT(5)) +#define US5182D_CFG3_INT_SOURCE_PX BIT(3) #define US5182D_REG_CFG4 0x10 @@ -55,6 +61,13 @@ #define US5182D_REG_AUTO_LDARK_GAIN 0x29 #define US5182D_REG_AUTO_HDARK_GAIN 0x2a +/* Thresholds for events: px low (0x08-l, 0x09-h), px high (0x0a-l 0x0b-h) */ +#define US5182D_REG_PXL_TH 0x08 +#define US5182D_REG_PXH_TH 0x0a + +#define US5182D_REG_PXL_TH_DEFAULT 1000 +#define US5182D_REG_PXH_TH_DEFAULT 30000 + #define US5182D_OPMODE_ALS 0x01 #define US5182D_OPMODE_PX 0x02 #define US5182D_OPMODE_SHIFT 4 @@ -84,6 +97,8 @@ #define US5182D_READ_WORD 2 #define US5182D_OPSTORE_SLEEP_TIME 20 /* ms */ #define US5182D_SLEEP_MS 3000 /* ms */ +#define US5182D_PXH_TH_DISABLE 0xffff +#define US5182D_PXL_TH_DISABLE 0x0000 /* Available ranges: [12354, 7065, 3998, 2202, 1285, 498, 256, 138] lux */ static const int us5182d_scales[] = {188500, 107800, 61000, 33600, 19600, 7600, @@ -119,6 +134,12 @@ struct us5182d_data { u8 upper_dark_gain; u16 *us5182d_dark_ths; + u16 px_low_th; + u16 px_high_th; + + int rising_en; + int falling_en; + u8 opmode; u8 power_mode; @@ -148,10 +169,26 @@ static const struct { {US5182D_REG_CFG1, US5182D_CFG1_ALS_RES16}, {US5182D_REG_CFG2, (US5182D_CFG2_PX_RES16 | US5182D_CFG2_PXGAIN_DEFAULT)}, - {US5182D_REG_CFG3, US5182D_CFG3_LED_CURRENT100}, + {US5182D_REG_CFG3, US5182D_CFG3_LED_CURRENT100 | + US5182D_CFG3_INT_SOURCE_PX}, {US5182D_REG_CFG4, 0x00}, }; +static const struct iio_event_spec us5182d_events[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_RISING, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_FALLING, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, +}; + static const struct iio_chan_spec us5182d_channels[] = { { .type = IIO_LIGHT, @@ -161,6 +198,8 @@ static const struct iio_chan_spec us5182d_channels[] = { { .type = IIO_PROXIMITY, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .event_spec = us5182d_events, + .num_event_specs = ARRAY_SIZE(us5182d_events), } }; @@ -487,11 +526,201 @@ static int us5182d_write_raw(struct iio_dev *indio_dev, return -EINVAL; } +static int us5182d_setup_prox(struct iio_dev *indio_dev, + enum iio_event_direction dir, u16 val) +{ + struct us5182d_data *data = iio_priv(indio_dev); + + if (dir == IIO_EV_DIR_FALLING) + return i2c_smbus_write_word_data(data->client, + US5182D_REG_PXL_TH, val); + else if (dir == IIO_EV_DIR_RISING) + return i2c_smbus_write_word_data(data->client, + US5182D_REG_PXH_TH, val); + + return 0; +} + +static int us5182d_read_thresh(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 us5182d_data *data = iio_priv(indio_dev); + + switch (dir) { + case IIO_EV_DIR_RISING: + mutex_lock(&data->lock); + *val = data->px_high_th; + mutex_unlock(&data->lock); + break; + case IIO_EV_DIR_FALLING: + mutex_lock(&data->lock); + *val = data->px_low_th; + mutex_unlock(&data->lock); + break; + default: + return -EINVAL; + } + + return IIO_VAL_INT; +} + +static int us5182d_write_thresh(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 us5182d_data *data = iio_priv(indio_dev); + int ret; + + if (val < 0 || val > USHRT_MAX || val2 != 0) + return -EINVAL; + + switch (dir) { + case IIO_EV_DIR_RISING: + mutex_lock(&data->lock); + if (data->rising_en) { + ret = us5182d_setup_prox(indio_dev, dir, val); + if (ret < 0) + goto err; + } + data->px_high_th = val; + mutex_unlock(&data->lock); + break; + case IIO_EV_DIR_FALLING: + mutex_lock(&data->lock); + if (data->falling_en) { + ret = us5182d_setup_prox(indio_dev, dir, val); + if (ret < 0) + goto err; + } + data->px_low_th = val; + mutex_unlock(&data->lock); + break; + default: + return -EINVAL; + } + + return 0; +err: + mutex_unlock(&data->lock); + return ret; +} + +static int us5182d_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 us5182d_data *data = iio_priv(indio_dev); + int ret; + + switch (dir) { + case IIO_EV_DIR_RISING: + mutex_lock(&data->lock); + ret = data->rising_en; + mutex_unlock(&data->lock); + break; + case IIO_EV_DIR_FALLING: + mutex_lock(&data->lock); + ret = data->falling_en; + mutex_unlock(&data->lock); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int us5182d_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 us5182d_data *data = iio_priv(indio_dev); + int ret; + u16 new_th; + + mutex_lock(&data->lock); + + switch (dir) { + case IIO_EV_DIR_RISING: + if (data->rising_en == state) { + mutex_unlock(&data->lock); + return 0; + } + new_th = US5182D_PXH_TH_DISABLE; + if (state) { + data->power_mode = US5182D_CONTINUOUS; + ret = us5182d_set_power_state(data, true); + if (ret < 0) + goto err; + ret = us5182d_px_enable(data); + if (ret < 0) + goto err_poweroff; + new_th = data->px_high_th; + } + ret = us5182d_setup_prox(indio_dev, dir, new_th); + if (ret < 0) + goto err_poweroff; + data->rising_en = state; + break; + case IIO_EV_DIR_FALLING: + if (data->falling_en == state) { + mutex_unlock(&data->lock); + return 0; + } + new_th = US5182D_PXL_TH_DISABLE; + if (state) { + data->power_mode = US5182D_CONTINUOUS; + ret = us5182d_set_power_state(data, true); + if (ret < 0) + goto err; + ret = us5182d_px_enable(data); + if (ret < 0) + goto err_poweroff; + new_th = data->px_low_th; + } + ret = us5182d_setup_prox(indio_dev, dir, new_th); + if (ret < 0) + goto err_poweroff; + data->falling_en = state; + break; + default: + ret = -EINVAL; + goto err; + } + + if (!state) { + ret = us5182d_set_power_state(data, false); + if (ret < 0) + goto err; + } + + if (!data->falling_en && !data->rising_en && !data->default_continuous) + data->power_mode = US5182D_ONESHOT; + + mutex_unlock(&data->lock); + return 0; + +err_poweroff: + if (state) + us5182d_set_power_state(data, false); +err: + mutex_unlock(&data->lock); + return ret; +} + static const struct iio_info us5182d_info = { .driver_module = THIS_MODULE, .read_raw = us5182d_read_raw, .write_raw = us5182d_write_raw, .attrs = &us5182d_attr_group, + .read_event_value = &us5182d_read_thresh, + .write_event_value = &us5182d_write_thresh, + .read_event_config = &us5182d_read_event_config, + .write_event_config = &us5182d_write_event_config, }; static int us5182d_reset(struct iio_dev *indio_dev) @@ -513,6 +742,9 @@ static int us5182d_init(struct iio_dev *indio_dev) data->opmode = 0; data->power_mode = US5182D_CONTINUOUS; + data->px_low_th = US5182D_REG_PXL_TH_DEFAULT; + data->px_high_th = US5182D_REG_PXH_TH_DEFAULT; + for (i = 0; i < ARRAY_SIZE(us5182d_regvals); i++) { ret = i2c_smbus_write_byte_data(data->client, us5182d_regvals[i].reg, @@ -583,6 +815,33 @@ static int us5182d_dark_gain_config(struct iio_dev *indio_dev) US5182D_REG_DARK_AUTO_EN_DEFAULT); } +static irqreturn_t us5182d_irq_thread_handler(int irq, void *private) +{ + struct iio_dev *indio_dev = private; + struct us5182d_data *data = iio_priv(indio_dev); + enum iio_event_direction dir; + int ret; + u64 ev; + + ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0); + if (ret < 0) { + dev_err(&data->client->dev, "i2c transfer error in irq\n"); + return IRQ_HANDLED; + } + + dir = ret & US5182D_CFG0_PROX ? IIO_EV_DIR_RISING : IIO_EV_DIR_FALLING; + ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1, IIO_EV_TYPE_THRESH, dir); + + iio_push_event(indio_dev, ev, iio_get_time_ns()); + + ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, + ret & ~US5182D_CFG0_PX_IRQ); + if (ret < 0) + dev_err(&data->client->dev, "i2c transfer error in irq\n"); + + return IRQ_HANDLED; +} + static int us5182d_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -614,6 +873,16 @@ static int us5182d_probe(struct i2c_client *client, return (ret < 0) ? ret : -ENODEV; } + if (client->irq > 0) { + ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, + us5182d_irq_thread_handler, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "us5182d-irq", indio_dev); + if (ret < 0) + return ret; + } else + dev_warn(&client->dev, "no valid irq found\n"); + us5182d_get_platform_data(indio_dev); ret = us5182d_init(indio_dev); if (ret < 0) -- GitLab From 9b1de75b5deea3e56bfb76d19d71ec599fcc803b Mon Sep 17 00:00:00 2001 From: Adriana Reus Date: Mon, 14 Dec 2015 14:24:47 +0200 Subject: [PATCH 2009/2855] iio: light: us5182d: Refactor read_raw function A bit of refactoring for better readability. Moved and slightly reorganized all the activity necessary for reading als and proximity into a different function. This way the switch in read raw becomes clearer and more compact. Signed-off-by: Adriana Reus Signed-off-by: Jonathan Cameron --- drivers/iio/light/us5182d.c | 155 ++++++++++++++++++------------------ 1 file changed, 78 insertions(+), 77 deletions(-) diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c index 213f7785095fd..45bc2f742f46a 100644 --- a/drivers/iio/light/us5182d.c +++ b/drivers/iio/light/us5182d.c @@ -203,23 +203,6 @@ static const struct iio_chan_spec us5182d_channels[] = { } }; -static int us5182d_get_als(struct us5182d_data *data) -{ - int ret; - unsigned long result; - - ret = i2c_smbus_read_word_data(data->client, - US5182D_REG_ADL); - if (ret < 0) - return ret; - - result = ret * data->ga / US5182D_GA_RESOLUTION; - if (result > 0xffff) - result = 0xffff; - - return result; -} - static int us5182d_oneshot_en(struct us5182d_data *data) { int ret; @@ -324,6 +307,39 @@ static int us5182d_px_enable(struct us5182d_data *data) return 0; } +static int us5182d_get_als(struct us5182d_data *data) +{ + int ret; + unsigned long result; + + ret = us5182d_als_enable(data); + if (ret < 0) + return ret; + + ret = i2c_smbus_read_word_data(data->client, + US5182D_REG_ADL); + if (ret < 0) + return ret; + + result = ret * data->ga / US5182D_GA_RESOLUTION; + if (result > 0xffff) + result = 0xffff; + + return result; +} + +static int us5182d_get_px(struct us5182d_data *data) +{ + int ret; + + ret = us5182d_px_enable(data); + if (ret < 0) + return ret; + + return i2c_smbus_read_word_data(data->client, + US5182D_REG_PDL); +} + static int us5182d_shutdown_en(struct us5182d_data *data, u8 state) { int ret; @@ -370,6 +386,46 @@ static int us5182d_set_power_state(struct us5182d_data *data, bool on) return ret; } +static int us5182d_read_value(struct us5182d_data *data, + struct iio_chan_spec const *chan) +{ + int ret, value; + + mutex_lock(&data->lock); + + if (data->power_mode == US5182D_ONESHOT) { + ret = us5182d_oneshot_en(data); + if (ret < 0) + goto out_err; + } + + ret = us5182d_set_power_state(data, true); + if (ret < 0) + goto out_err; + + if (chan->type == IIO_LIGHT) + ret = us5182d_get_als(data); + else + ret = us5182d_get_px(data); + if (ret < 0) + goto out_poweroff; + + value = ret; + + ret = us5182d_set_power_state(data, false); + if (ret < 0) + goto out_err; + + mutex_unlock(&data->lock); + return value; + +out_poweroff: + us5182d_set_power_state(data, false); +out_err: + mutex_unlock(&data->lock); + return ret; +} + static int us5182d_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -379,76 +435,21 @@ static int us5182d_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - switch (chan->type) { - case IIO_LIGHT: - mutex_lock(&data->lock); - if (data->power_mode == US5182D_ONESHOT) { - ret = us5182d_oneshot_en(data); - if (ret < 0) - goto out_err; - } - ret = us5182d_set_power_state(data, true); - if (ret < 0) - goto out_err; - ret = us5182d_als_enable(data); - if (ret < 0) - goto out_poweroff; - ret = us5182d_get_als(data); - if (ret < 0) - goto out_poweroff; - *val = ret; - ret = us5182d_set_power_state(data, false); - if (ret < 0) - goto out_err; - mutex_unlock(&data->lock); - return IIO_VAL_INT; - case IIO_PROXIMITY: - mutex_lock(&data->lock); - if (data->power_mode == US5182D_ONESHOT) { - ret = us5182d_oneshot_en(data); - if (ret < 0) - goto out_err; - } - ret = us5182d_set_power_state(data, true); - if (ret < 0) - goto out_err; - ret = us5182d_px_enable(data); - if (ret < 0) - goto out_poweroff; - ret = i2c_smbus_read_word_data(data->client, - US5182D_REG_PDL); - if (ret < 0) - goto out_poweroff; - *val = ret; - ret = us5182d_set_power_state(data, false); - if (ret < 0) - goto out_err; - mutex_unlock(&data->lock); - return IIO_VAL_INT; - default: - return -EINVAL; - } - + ret = us5182d_read_value(data, chan); + if (ret < 0) + return ret; + *val = ret; + return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG1); if (ret < 0) return ret; - *val = 0; *val2 = us5182d_scales[ret & US5182D_AGAIN_MASK]; - return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; } - - return -EINVAL; - -out_poweroff: - us5182d_set_power_state(data, false); -out_err: - mutex_unlock(&data->lock); - return ret; } /** -- GitLab From ea4a8cb1c2b47570e77f4489659e2c653ca66f9e Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Sat, 19 Dec 2015 00:34:34 +0800 Subject: [PATCH 2010/2855] usb: gadget: bcm63xx_udc: use list_for_each_entry_safe Use list_for_each_entry_safe() instead of list_for_each_safe() to simplify the code. Signed-off-by: Geliang Tang Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/bcm63xx_udc.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/udc/bcm63xx_udc.c b/drivers/usb/gadget/udc/bcm63xx_udc.c index 8cbb00325824a..f5fccb3e41524 100644 --- a/drivers/usb/gadget/udc/bcm63xx_udc.c +++ b/drivers/usb/gadget/udc/bcm63xx_udc.c @@ -1083,7 +1083,7 @@ static int bcm63xx_ep_disable(struct usb_ep *ep) struct bcm63xx_ep *bep = our_ep(ep); struct bcm63xx_udc *udc = bep->udc; struct iudma_ch *iudma = bep->iudma; - struct list_head *pos, *n; + struct bcm63xx_req *breq, *n; unsigned long flags; if (!ep || !ep->desc) @@ -1099,10 +1099,7 @@ static int bcm63xx_ep_disable(struct usb_ep *ep) iudma_reset_channel(udc, iudma); if (!list_empty(&bep->queue)) { - list_for_each_safe(pos, n, &bep->queue) { - struct bcm63xx_req *breq = - list_entry(pos, struct bcm63xx_req, queue); - + list_for_each_entry_safe(breq, n, &bep->queue, queue) { usb_gadget_unmap_request(&udc->gadget, &breq->req, iudma->is_tx); list_del(&breq->queue); -- GitLab From a40a00318c7fcdd23e73cfffac0e33430a43a3e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Fri, 18 Dec 2015 19:30:59 +0100 Subject: [PATCH 2011/2855] usb: dwc2: add shutdown callback to platform variant In specific conditions (involving usb hubs) dwc2 devices can create a lot of interrupts, even to the point of overwhelming devices running at low frequencies. Some devices need to do special clock handling at shutdown-time which may bring the system clock below the threshold of being able to handle the dwc2 interrupts. Disabling dwc2-irqs in a shutdown callbacks prevents reboots/poweroffs from getting stuck in such cases. The hsotg struct already contains an unused irq element, so we can just use it to store the irq number for the shutdown callback. Reviewed-by: Douglas Anderson Acked-by: John Youn Signed-off-by: Heiko Stuebner Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/platform.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 1e7cb99d21008..510f787434b3d 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -405,6 +405,25 @@ static int dwc2_driver_remove(struct platform_device *dev) return 0; } +/** + * dwc2_driver_shutdown() - Called on device shutdown + * + * @dev: Platform device + * + * In specific conditions (involving usb hubs) dwc2 devices can create a + * lot of interrupts, even to the point of overwhelming devices running + * at low frequencies. Some devices need to do special clock handling + * at shutdown-time which may bring the system clock below the threshold + * of being able to handle the dwc2 interrupts. Disabling dwc2-irqs + * prevents reboots/poweroffs from getting stuck in such cases. + */ +static void dwc2_driver_shutdown(struct platform_device *dev) +{ + struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); + + disable_irq(hsotg->irq); +} + static const struct of_device_id dwc2_of_match_table[] = { { .compatible = "brcm,bcm2835-usb", .data = ¶ms_bcm2835 }, { .compatible = "hisilicon,hi6220-usb", .data = ¶ms_hi6220 }, @@ -435,7 +454,6 @@ static int dwc2_driver_probe(struct platform_device *dev) struct dwc2_hsotg *hsotg; struct resource *res; int retval; - int irq; match = of_match_device(dwc2_of_match_table, &dev->dev); if (match && match->data) { @@ -490,15 +508,15 @@ static int dwc2_driver_probe(struct platform_device *dev) dwc2_set_all_params(hsotg->core_params, -1); - irq = platform_get_irq(dev, 0); - if (irq < 0) { + hsotg->irq = platform_get_irq(dev, 0); + if (hsotg->irq < 0) { dev_err(&dev->dev, "missing IRQ resource\n"); - return irq; + return hsotg->irq; } dev_dbg(hsotg->dev, "registering common handler for irq%d\n", - irq); - retval = devm_request_irq(hsotg->dev, irq, + hsotg->irq); + retval = devm_request_irq(hsotg->dev, hsotg->irq, dwc2_handle_common_intr, IRQF_SHARED, dev_name(hsotg->dev), hsotg); if (retval) @@ -523,14 +541,14 @@ static int dwc2_driver_probe(struct platform_device *dev) dwc2_force_dr_mode(hsotg); if (hsotg->dr_mode != USB_DR_MODE_HOST) { - retval = dwc2_gadget_init(hsotg, irq); + retval = dwc2_gadget_init(hsotg, hsotg->irq); if (retval) goto error; hsotg->gadget_enabled = 1; } if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) { - retval = dwc2_hcd_init(hsotg, irq); + retval = dwc2_hcd_init(hsotg, hsotg->irq); if (retval) { if (hsotg->gadget_enabled) dwc2_hsotg_remove(hsotg); @@ -597,6 +615,7 @@ static struct platform_driver dwc2_platform_driver = { }, .probe = dwc2_driver_probe, .remove = dwc2_driver_remove, + .shutdown = dwc2_driver_shutdown, }; module_platform_driver(dwc2_platform_driver); -- GitLab From 7441ccef339f87abc27afc4ccfc24c014d7360c9 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 21 Dec 2015 19:20:15 -0800 Subject: [PATCH 2012/2855] f2fs: use atomic variable for total_extent_tree It would be better to use atomic variable for total_extent_tree. Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/debug.c | 5 +++-- fs/f2fs/extent_cache.c | 8 ++++---- fs/f2fs/f2fs.h | 2 +- fs/f2fs/node.c | 3 ++- fs/f2fs/shrinker.c | 3 ++- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index bb307e642fdde..ed5dfcc8886f0 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -38,7 +38,7 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->hit_rbtree = atomic64_read(&sbi->read_hit_rbtree); si->hit_total = si->hit_largest + si->hit_cached + si->hit_rbtree; si->total_ext = atomic64_read(&sbi->total_hit_ext); - si->ext_tree = sbi->total_ext_tree; + si->ext_tree = atomic_read(&sbi->total_ext_tree); si->ext_node = atomic_read(&sbi->total_ext_node); si->ndirty_node = get_pages(sbi, F2FS_DIRTY_NODES); si->ndirty_dent = get_pages(sbi, F2FS_DIRTY_DENTS); @@ -193,7 +193,8 @@ get_cache: si->cache_mem += si->inmem_pages * sizeof(struct inmem_pages); for (i = 0; i <= UPDATE_INO; i++) si->cache_mem += sbi->im[i].ino_num * sizeof(struct ino_entry); - si->cache_mem += sbi->total_ext_tree * sizeof(struct extent_tree); + si->cache_mem += atomic_read(&sbi->total_ext_tree) * + sizeof(struct extent_tree); si->cache_mem += atomic_read(&sbi->total_ext_node) * sizeof(struct extent_node); diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index e86e9f1e0733a..0e97d6af98858 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -70,7 +70,7 @@ static struct extent_tree *__grab_extent_tree(struct inode *inode) rwlock_init(&et->lock); atomic_set(&et->refcount, 0); et->count = 0; - sbi->total_ext_tree++; + atomic_inc(&sbi->total_ext_tree); } atomic_inc(&et->refcount); up_write(&sbi->extent_tree_lock); @@ -570,7 +570,7 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) radix_tree_delete(root, et->ino); kmem_cache_free(extent_tree_slab, et); - sbi->total_ext_tree--; + atomic_dec(&sbi->total_ext_tree); tree_cnt++; if (node_cnt + tree_cnt >= nr_shrink) @@ -663,7 +663,7 @@ void f2fs_destroy_extent_tree(struct inode *inode) f2fs_bug_on(sbi, atomic_read(&et->refcount) || et->count); radix_tree_delete(&sbi->extent_tree_root, inode->i_ino); kmem_cache_free(extent_tree_slab, et); - sbi->total_ext_tree--; + atomic_dec(&sbi->total_ext_tree); up_write(&sbi->extent_tree_lock); F2FS_I(inode)->extent_tree = NULL; @@ -715,7 +715,7 @@ void init_extent_cache_info(struct f2fs_sb_info *sbi) init_rwsem(&sbi->extent_tree_lock); INIT_LIST_HEAD(&sbi->extent_list); spin_lock_init(&sbi->extent_lock); - sbi->total_ext_tree = 0; + atomic_set(&sbi->total_ext_tree, 0); atomic_set(&sbi->total_ext_node, 0); } diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 19beabefd8395..a7f619182cece 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -762,7 +762,7 @@ struct f2fs_sb_info { struct rw_semaphore extent_tree_lock; /* locking extent radix tree */ struct list_head extent_list; /* lru list for shrinker */ spinlock_t extent_lock; /* locking extent lru list */ - int total_ext_tree; /* extent tree count */ + atomic_t total_ext_tree; /* extent tree count */ atomic_t total_ext_node; /* extent info count */ /* basic filesystem units */ diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index d842b199cd024..6cc8ac7e185a2 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -65,7 +65,8 @@ bool available_free_memory(struct f2fs_sb_info *sbi, int type) sizeof(struct ino_entry)) >> PAGE_CACHE_SHIFT; res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 1); } else if (type == EXTENT_CACHE) { - mem_size = (sbi->total_ext_tree * sizeof(struct extent_tree) + + mem_size = (atomic_read(&sbi->total_ext_tree) * + sizeof(struct extent_tree) + atomic_read(&sbi->total_ext_node) * sizeof(struct extent_node)) >> PAGE_CACHE_SHIFT; res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 1); diff --git a/fs/f2fs/shrinker.c b/fs/f2fs/shrinker.c index da0d8e0b55a5d..a11e099cbddc6 100644 --- a/fs/f2fs/shrinker.c +++ b/fs/f2fs/shrinker.c @@ -32,7 +32,8 @@ static unsigned long __count_free_nids(struct f2fs_sb_info *sbi) static unsigned long __count_extent_cache(struct f2fs_sb_info *sbi) { - return sbi->total_ext_tree + atomic_read(&sbi->total_ext_node); + return atomic_read(&sbi->total_ext_tree) + + atomic_read(&sbi->total_ext_node); } unsigned long f2fs_shrink_count(struct shrinker *shrink, -- GitLab From e8aab48b34d3bd069dfcf4ccb8f13ba8c98f7845 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 22 Dec 2015 18:51:27 +0000 Subject: [PATCH 2013/2855] iio: adc: ina2xx: Fix incorrect report of data endianness to userspace. This was extracted from a reposting of the driver after it had been applied to the IIO tree. I have fast tracked it as the driver will be in 4.5 and it would be nice to fix this trivial issue before it is. Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ina2xx-adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index bd56adaeec05a..d803e5018a426 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -400,7 +400,7 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev, .sign = 'u', \ .realbits = 16, \ .storagebits = 16, \ - .endianness = IIO_LE, \ + .endianness = IIO_CPU, \ } \ } -- GitLab From de2dd0eb30af55d3893979d5641c50c7a8969c99 Mon Sep 17 00:00:00 2001 From: Zhao Qiang Date: Mon, 30 Nov 2015 10:48:52 +0800 Subject: [PATCH 2014/2855] genalloc:support memory-allocation with bytes-alignment to genalloc Bytes alignment is required to manage some special RAM, so add gen_pool_first_fit_align to genalloc, meanwhile add gen_pool_alloc_algo to pass algo in case user layer using more than one algo, and pass data to gen_pool_first_fit_align(modify gen_pool_alloc as a wrapper) Signed-off-by: Zhao Qiang Signed-off-by: Scott Wood --- include/linux/genalloc.h | 27 +++++++++++++++--- lib/genalloc.c | 61 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 78 insertions(+), 10 deletions(-) diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 7ff168d06967c..3c676ce46ee09 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -30,10 +30,12 @@ #ifndef __GENALLOC_H__ #define __GENALLOC_H__ +#include #include struct device; struct device_node; +struct gen_pool; /** * Allocation callback function type definition @@ -47,7 +49,7 @@ typedef unsigned long (*genpool_algo_t)(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, - void *data); + void *data, struct gen_pool *pool); /* * General purpose special memory pool descriptor. @@ -75,6 +77,13 @@ struct gen_pool_chunk { unsigned long bits[0]; /* bitmap for allocating memory chunk */ }; +/* + * gen_pool data descriptor for gen_pool_first_fit_align. + */ +struct genpool_data_align { + int align; /* alignment by bytes for starting address */ +}; + extern struct gen_pool *gen_pool_create(int, int); extern phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long); extern int gen_pool_add_virt(struct gen_pool *, unsigned long, phys_addr_t, @@ -98,6 +107,8 @@ static inline int gen_pool_add(struct gen_pool *pool, unsigned long addr, } extern void gen_pool_destroy(struct gen_pool *); extern unsigned long gen_pool_alloc(struct gen_pool *, size_t); +extern unsigned long gen_pool_alloc_algo(struct gen_pool *, size_t, + genpool_algo_t algo, void *data); extern void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, dma_addr_t *dma); extern void gen_pool_free(struct gen_pool *, unsigned long, size_t); @@ -110,14 +121,22 @@ extern void gen_pool_set_algo(struct gen_pool *pool, genpool_algo_t algo, void *data); extern unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, - unsigned long start, unsigned int nr, void *data); + unsigned long start, unsigned int nr, void *data, + struct gen_pool *pool); + +extern unsigned long gen_pool_first_fit_align(unsigned long *map, + unsigned long size, unsigned long start, unsigned int nr, + void *data, struct gen_pool *pool); + extern unsigned long gen_pool_first_fit_order_align(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, - void *data); + void *data, struct gen_pool *pool); extern unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, - unsigned long start, unsigned int nr, void *data); + unsigned long start, unsigned int nr, void *data, + struct gen_pool *pool); + extern struct gen_pool *devm_gen_pool_create(struct device *dev, int min_alloc_order, int nid, const char *name); diff --git a/lib/genalloc.c b/lib/genalloc.c index 116a166b096f0..b8cf89d9e17d4 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -269,6 +269,25 @@ EXPORT_SYMBOL(gen_pool_destroy); * NMI-safe cmpxchg implementation. */ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) +{ + return gen_pool_alloc_algo(pool, size, pool->algo, pool->data); +} +EXPORT_SYMBOL(gen_pool_alloc); + +/** + * gen_pool_alloc_algo - allocate special memory from the pool + * @pool: pool to allocate from + * @size: number of bytes to allocate from the pool + * @algo: algorithm passed from caller + * @data: data passed to algorithm + * + * Allocate the requested number of bytes from the specified pool. + * Uses the pool allocation function (with first-fit algorithm by default). + * Can not be used in NMI handler on architectures without + * NMI-safe cmpxchg implementation. + */ +unsigned long gen_pool_alloc_algo(struct gen_pool *pool, size_t size, + genpool_algo_t algo, void *data) { struct gen_pool_chunk *chunk; unsigned long addr = 0; @@ -290,8 +309,8 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) end_bit = chunk_size(chunk) >> order; retry: - start_bit = pool->algo(chunk->bits, end_bit, start_bit, nbits, - pool->data); + start_bit = algo(chunk->bits, end_bit, start_bit, + nbits, data, pool); if (start_bit >= end_bit) continue; remain = bitmap_set_ll(chunk->bits, start_bit, nbits); @@ -310,7 +329,7 @@ retry: rcu_read_unlock(); return addr; } -EXPORT_SYMBOL(gen_pool_alloc); +EXPORT_SYMBOL(gen_pool_alloc_algo); /** * gen_pool_dma_alloc - allocate special memory from the pool for DMA usage @@ -501,14 +520,41 @@ EXPORT_SYMBOL(gen_pool_set_algo); * @start: The bitnumber to start searching at * @nr: The number of zeroed bits we're looking for * @data: additional data - unused + * @pool: pool to find the fit region memory from */ unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, - unsigned long start, unsigned int nr, void *data) + unsigned long start, unsigned int nr, void *data, + struct gen_pool *pool) { return bitmap_find_next_zero_area(map, size, start, nr, 0); } EXPORT_SYMBOL(gen_pool_first_fit); +/** + * gen_pool_first_fit_align - find the first available region + * of memory matching the size requirement (alignment constraint) + * @map: The address to base the search on + * @size: The bitmap size in bits + * @start: The bitnumber to start searching at + * @nr: The number of zeroed bits we're looking for + * @data: data for alignment + * @pool: pool to get order from + */ +unsigned long gen_pool_first_fit_align(unsigned long *map, unsigned long size, + unsigned long start, unsigned int nr, void *data, + struct gen_pool *pool) +{ + struct genpool_data_align *alignment; + unsigned long align_mask; + int order; + + alignment = data; + order = pool->min_alloc_order; + align_mask = ((alignment->align + (1UL << order) - 1) >> order) - 1; + return bitmap_find_next_zero_area(map, size, start, nr, align_mask); +} +EXPORT_SYMBOL(gen_pool_first_fit_align); + /** * gen_pool_first_fit_order_align - find the first available region * of memory matching the size requirement. The region will be aligned @@ -518,10 +564,11 @@ EXPORT_SYMBOL(gen_pool_first_fit); * @start: The bitnumber to start searching at * @nr: The number of zeroed bits we're looking for * @data: additional data - unused + * @pool: pool to find the fit region memory from */ unsigned long gen_pool_first_fit_order_align(unsigned long *map, unsigned long size, unsigned long start, - unsigned int nr, void *data) + unsigned int nr, void *data, struct gen_pool *pool) { unsigned long align_mask = roundup_pow_of_two(nr) - 1; @@ -537,12 +584,14 @@ EXPORT_SYMBOL(gen_pool_first_fit_order_align); * @start: The bitnumber to start searching at * @nr: The number of zeroed bits we're looking for * @data: additional data - unused + * @pool: pool to find the fit region memory from * * Iterate over the bitmap to find the smallest free region * which we can allocate the memory. */ unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, - unsigned long start, unsigned int nr, void *data) + unsigned long start, unsigned int nr, void *data, + struct gen_pool *pool) { unsigned long start_bit = size; unsigned long len = size + 1; -- GitLab From b26981c8f743d3cb64a6907eb1f5c6c4ba6ca672 Mon Sep 17 00:00:00 2001 From: Zhao Qiang Date: Mon, 30 Nov 2015 10:48:53 +0800 Subject: [PATCH 2015/2855] genalloc:support allocating specific region Add new algo for genalloc, it reserve a specific region of memory Signed-off-by: Zhao Qiang Signed-off-by: Scott Wood --- include/linux/genalloc.h | 11 +++++++++++ lib/genalloc.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 3c676ce46ee09..29d4385903d45 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -84,6 +84,13 @@ struct genpool_data_align { int align; /* alignment by bytes for starting address */ }; +/* + * gen_pool data descriptor for gen_pool_fixed_alloc. + */ +struct genpool_data_fixed { + unsigned long offset; /* The offset of the specific region */ +}; + extern struct gen_pool *gen_pool_create(int, int); extern phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long); extern int gen_pool_add_virt(struct gen_pool *, unsigned long, phys_addr_t, @@ -124,6 +131,10 @@ extern unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, void *data, struct gen_pool *pool); +extern unsigned long gen_pool_fixed_alloc(unsigned long *map, + unsigned long size, unsigned long start, unsigned int nr, + void *data, struct gen_pool *pool); + extern unsigned long gen_pool_first_fit_align(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, void *data, struct gen_pool *pool); diff --git a/lib/genalloc.c b/lib/genalloc.c index b8cf89d9e17d4..5ec83cd932847 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -555,6 +555,38 @@ unsigned long gen_pool_first_fit_align(unsigned long *map, unsigned long size, } EXPORT_SYMBOL(gen_pool_first_fit_align); +/** + * gen_pool_fixed_alloc - reserve a specific region + * @map: The address to base the search on + * @size: The bitmap size in bits + * @start: The bitnumber to start searching at + * @nr: The number of zeroed bits we're looking for + * @data: data for alignment + * @pool: pool to get order from + */ +unsigned long gen_pool_fixed_alloc(unsigned long *map, unsigned long size, + unsigned long start, unsigned int nr, void *data, + struct gen_pool *pool) +{ + struct genpool_data_fixed *fixed_data; + int order; + unsigned long offset_bit; + unsigned long start_bit; + + fixed_data = data; + order = pool->min_alloc_order; + offset_bit = fixed_data->offset >> order; + if (WARN_ON(fixed_data->offset & (1UL << order - 1))) + return size; + + start_bit = bitmap_find_next_zero_area(map, size, + start + offset_bit, nr, 0); + if (start_bit != offset_bit) + start_bit = size; + return start_bit; +} +EXPORT_SYMBOL(gen_pool_fixed_alloc); + /** * gen_pool_first_fit_order_align - find the first available region * of memory matching the size requirement. The region will be aligned -- GitLab From 0e6e01ff694ee222acc5a9184211678473c948e3 Mon Sep 17 00:00:00 2001 From: Zhao Qiang Date: Mon, 30 Nov 2015 10:48:54 +0800 Subject: [PATCH 2016/2855] CPM/QE: use genalloc to manage CPM/QE muram Use genalloc to manage CPM/QE muram instead of rheap. Signed-off-by: Zhao Qiang Signed-off-by: Scott Wood --- arch/powerpc/include/asm/cpm.h | 3 + arch/powerpc/platforms/Kconfig | 4 +- arch/powerpc/sysdev/cpm_common.c | 126 +++++++++++++++++++++---------- lib/genalloc.c | 2 +- 4 files changed, 94 insertions(+), 41 deletions(-) diff --git a/arch/powerpc/include/asm/cpm.h b/arch/powerpc/include/asm/cpm.h index 4398a6cdcf53c..46e86b50abf30 100644 --- a/arch/powerpc/include/asm/cpm.h +++ b/arch/powerpc/include/asm/cpm.h @@ -2,6 +2,7 @@ #define __CPM_H #include +#include #include #include #include @@ -161,6 +162,8 @@ int cpm_muram_init(void); unsigned long cpm_muram_alloc(unsigned long size, unsigned long align); int cpm_muram_free(unsigned long offset); unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size); +unsigned long cpm_muram_alloc_common(unsigned long size, genpool_algo_t algo, + void *data); void __iomem *cpm_muram_addr(unsigned long offset); unsigned long cpm_muram_offset(void __iomem *addr); dma_addr_t cpm_muram_dma(void __iomem *addr); diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index b7f9c408bf24f..57069eb8f093d 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -275,7 +275,7 @@ config TAU_AVERAGE config QUICC_ENGINE bool "Freescale QUICC Engine (QE) Support" depends on FSL_SOC && PPC32 - select PPC_LIB_RHEAP + select GENERIC_ALLOCATOR select CRC32 help The QUICC Engine (QE) is a new generation of communications @@ -295,7 +295,6 @@ config CPM2 bool "Enable support for the CPM2 (Communications Processor Module)" depends on (FSL_SOC_BOOKE && PPC32) || 8260 select CPM - select PPC_LIB_RHEAP select PPC_PCI_CHOICE select ARCH_REQUIRE_GPIOLIB help @@ -325,6 +324,7 @@ config FSL_ULI1575 config CPM bool + select GENERIC_ALLOCATOR config OF_RTC bool diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index e00a5ee58fd71..fcc83cd9cc2f9 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c @@ -17,6 +17,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include @@ -27,7 +28,6 @@ #include #include -#include #include #include @@ -65,14 +65,22 @@ void __init udbg_init_cpm(void) } #endif +static struct gen_pool *muram_pool; static spinlock_t cpm_muram_lock; -static rh_block_t cpm_boot_muram_rh_block[16]; -static rh_info_t cpm_muram_info; static u8 __iomem *muram_vbase; static phys_addr_t muram_pbase; -/* Max address size we deal with */ +struct muram_block { + struct list_head head; + unsigned long start; + int size; +}; + +static LIST_HEAD(muram_block_list); + +/* max address size we deal with */ #define OF_MAX_ADDR_CELLS 4 +#define GENPOOL_OFFSET (4096 * 8) int cpm_muram_init(void) { @@ -87,50 +95,51 @@ int cpm_muram_init(void) return 0; spin_lock_init(&cpm_muram_lock); - /* initialize the info header */ - rh_init(&cpm_muram_info, 1, - sizeof(cpm_boot_muram_rh_block) / - sizeof(cpm_boot_muram_rh_block[0]), - cpm_boot_muram_rh_block); - np = of_find_compatible_node(NULL, NULL, "fsl,cpm-muram-data"); if (!np) { /* try legacy bindings */ np = of_find_node_by_name(NULL, "data-only"); if (!np) { - printk(KERN_ERR "Cannot find CPM muram data node"); + pr_err("Cannot find CPM muram data node"); ret = -ENODEV; - goto out; + goto out_muram; } } + muram_pool = gen_pool_create(0, -1); muram_pbase = of_translate_address(np, zero); if (muram_pbase == (phys_addr_t)OF_BAD_ADDR) { - printk(KERN_ERR "Cannot translate zero through CPM muram node"); + pr_err("Cannot translate zero through CPM muram node"); ret = -ENODEV; - goto out; + goto out_pool; } while (of_address_to_resource(np, i++, &r) == 0) { if (r.end > max) max = r.end; - - rh_attach_region(&cpm_muram_info, r.start - muram_pbase, - resource_size(&r)); + ret = gen_pool_add(muram_pool, r.start - muram_pbase + + GENPOOL_OFFSET, resource_size(&r), -1); + if (ret) { + pr_err("QE: couldn't add muram to pool!\n"); + goto out_pool; + } } muram_vbase = ioremap(muram_pbase, max - muram_pbase + 1); if (!muram_vbase) { - printk(KERN_ERR "Cannot map CPM muram"); + pr_err("Cannot map QE muram"); ret = -ENOMEM; + goto out_pool; } - -out: + goto out_muram; +out_pool: + gen_pool_destroy(muram_pool); +out_muram: of_node_put(np); return ret; } -/** +/* * cpm_muram_alloc - allocate the requested size worth of multi-user ram * @size: number of bytes to allocate * @align: requested alignment, in bytes @@ -143,14 +152,13 @@ unsigned long cpm_muram_alloc(unsigned long size, unsigned long align) { unsigned long start; unsigned long flags; + struct genpool_data_align muram_pool_data; spin_lock_irqsave(&cpm_muram_lock, flags); - cpm_muram_info.alignment = align; - start = rh_alloc(&cpm_muram_info, size, "commproc"); - if (!IS_ERR_VALUE(start)) - memset_io(cpm_muram_addr(start), 0, size); + muram_pool_data.align = align; + start = cpm_muram_alloc_common(size, gen_pool_first_fit_align, + &muram_pool_data); spin_unlock_irqrestore(&cpm_muram_lock, flags); - return start; } EXPORT_SYMBOL(cpm_muram_alloc); @@ -161,23 +169,31 @@ EXPORT_SYMBOL(cpm_muram_alloc); */ int cpm_muram_free(unsigned long offset) { - int ret; unsigned long flags; + int size; + struct muram_block *tmp; + size = 0; spin_lock_irqsave(&cpm_muram_lock, flags); - ret = rh_free(&cpm_muram_info, offset); + list_for_each_entry(tmp, &muram_block_list, head) { + if (tmp->start == offset) { + size = tmp->size; + list_del(&tmp->head); + kfree(tmp); + break; + } + } + gen_pool_free(muram_pool, offset + GENPOOL_OFFSET, size); spin_unlock_irqrestore(&cpm_muram_lock, flags); - - return ret; + return size; } EXPORT_SYMBOL(cpm_muram_free); -/** +/* * cpm_muram_alloc_fixed - reserve a specific region of multi-user ram - * @offset: the offset into the muram area to reserve - * @size: the number of bytes to reserve - * - * This function returns "start" on success, -ENOMEM on failure. + * @offset: offset of allocation start address + * @size: number of bytes to allocate + * This function returns an offset into the muram area * Use cpm_dpram_addr() to get the virtual address of the area. * Use cpm_muram_free() to free the allocation. */ @@ -185,16 +201,50 @@ unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size) { unsigned long start; unsigned long flags; + struct genpool_data_fixed muram_pool_data_fixed; spin_lock_irqsave(&cpm_muram_lock, flags); - cpm_muram_info.alignment = 1; - start = rh_alloc_fixed(&cpm_muram_info, offset, size, "commproc"); + muram_pool_data_fixed.offset = offset + GENPOOL_OFFSET; + start = cpm_muram_alloc_common(size, gen_pool_fixed_alloc, + &muram_pool_data_fixed); spin_unlock_irqrestore(&cpm_muram_lock, flags); - return start; } EXPORT_SYMBOL(cpm_muram_alloc_fixed); +/* + * cpm_muram_alloc_common - cpm_muram_alloc common code + * @size: number of bytes to allocate + * @algo: algorithm for alloc. + * @data: data for genalloc's algorithm. + * + * This function returns an offset into the muram area. + */ +unsigned long cpm_muram_alloc_common(unsigned long size, genpool_algo_t algo, + void *data) +{ + struct muram_block *entry; + unsigned long start; + + start = gen_pool_alloc_algo(muram_pool, size, algo, data); + if (!start) + goto out2; + start = start - GENPOOL_OFFSET; + memset_io(cpm_muram_addr(start), 0, size); + entry = kmalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + goto out1; + entry->start = start; + entry->size = size; + list_add(&entry->head, &muram_block_list); + + return start; +out1: + gen_pool_free(muram_pool, start, size); +out2: + return (unsigned long)-ENOMEM; +} + /** * cpm_muram_addr - turn a muram offset into a virtual address * @offset: muram offset to convert diff --git a/lib/genalloc.c b/lib/genalloc.c index 5ec83cd932847..0a1139644d328 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -576,7 +576,7 @@ unsigned long gen_pool_fixed_alloc(unsigned long *map, unsigned long size, fixed_data = data; order = pool->min_alloc_order; offset_bit = fixed_data->offset >> order; - if (WARN_ON(fixed_data->offset & (1UL << order - 1))) + if (WARN_ON(fixed_data->offset & ((1UL << order) - 1))) return size; start_bit = bitmap_find_next_zero_area(map, size, -- GitLab From 1291e49e893703e04e129fe2e17e87af40757bf1 Mon Sep 17 00:00:00 2001 From: Zhao Qiang Date: Mon, 30 Nov 2015 10:48:55 +0800 Subject: [PATCH 2017/2855] QE/CPM: move muram management functions to qe_common QE and CPM have the same muram, they use the same management functions. Now QE support both ARM and PowerPC, it is necessary to move QE to "driver/soc", so move the muram management functions from cpm_common to qe_common for preparing to move QE code to "driver/soc" Signed-off-by: Zhao Qiang Signed-off-by: Scott Wood --- arch/powerpc/include/asm/cpm.h | 47 +---- arch/powerpc/include/asm/qe.h | 50 ++++++ arch/powerpc/sysdev/Makefile | 1 + arch/powerpc/sysdev/cpm_common.c | 208 +--------------------- arch/powerpc/sysdev/qe_lib/Makefile | 4 +- arch/powerpc/sysdev/qe_lib/qe_common.c | 235 +++++++++++++++++++++++++ 6 files changed, 290 insertions(+), 255 deletions(-) create mode 100644 arch/powerpc/sysdev/qe_lib/qe_common.c diff --git a/arch/powerpc/include/asm/cpm.h b/arch/powerpc/include/asm/cpm.h index 46e86b50abf30..0958028cf31a0 100644 --- a/arch/powerpc/include/asm/cpm.h +++ b/arch/powerpc/include/asm/cpm.h @@ -2,10 +2,10 @@ #define __CPM_H #include -#include #include #include #include +#include /* * SPI Parameter RAM common to QE and CPM. @@ -156,51 +156,6 @@ typedef struct cpm_buf_desc { */ #define BD_I2C_START (0x0400) -int cpm_muram_init(void); - -#if defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) -unsigned long cpm_muram_alloc(unsigned long size, unsigned long align); -int cpm_muram_free(unsigned long offset); -unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size); -unsigned long cpm_muram_alloc_common(unsigned long size, genpool_algo_t algo, - void *data); -void __iomem *cpm_muram_addr(unsigned long offset); -unsigned long cpm_muram_offset(void __iomem *addr); -dma_addr_t cpm_muram_dma(void __iomem *addr); -#else -static inline unsigned long cpm_muram_alloc(unsigned long size, - unsigned long align) -{ - return -ENOSYS; -} - -static inline int cpm_muram_free(unsigned long offset) -{ - return -ENOSYS; -} - -static inline unsigned long cpm_muram_alloc_fixed(unsigned long offset, - unsigned long size) -{ - return -ENOSYS; -} - -static inline void __iomem *cpm_muram_addr(unsigned long offset) -{ - return NULL; -} - -static inline unsigned long cpm_muram_offset(void __iomem *addr) -{ - return -ENOSYS; -} - -static inline dma_addr_t cpm_muram_dma(void __iomem *addr) -{ - return 0; -} -#endif /* defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) */ - #ifdef CONFIG_CPM int cpm_command(u32 command, u8 opcode); #else diff --git a/arch/powerpc/include/asm/qe.h b/arch/powerpc/include/asm/qe.h index 32b9bfa0c9bd3..ceeaf91854b56 100644 --- a/arch/powerpc/include/asm/qe.h +++ b/arch/powerpc/include/asm/qe.h @@ -16,11 +16,16 @@ #define _ASM_POWERPC_QE_H #ifdef __KERNEL__ +#include +#include #include #include #include #include #include +#include +#include +#include #define QE_NUM_OF_SNUM 256 /* There are 256 serial number in QE */ #define QE_NUM_OF_BRGS 16 @@ -92,6 +97,51 @@ extern void qe_reset(void); static inline void qe_reset(void) {} #endif +int cpm_muram_init(void); + +#if defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) +unsigned long cpm_muram_alloc(unsigned long size, unsigned long align); +int cpm_muram_free(unsigned long offset); +unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size); +unsigned long cpm_muram_alloc_common(unsigned long size, genpool_algo_t algo, + void *data); +void __iomem *cpm_muram_addr(unsigned long offset); +unsigned long cpm_muram_offset(void __iomem *addr); +dma_addr_t cpm_muram_dma(void __iomem *addr); +#else +static inline unsigned long cpm_muram_alloc(unsigned long size, + unsigned long align) +{ + return -ENOSYS; +} + +static inline int cpm_muram_free(unsigned long offset) +{ + return -ENOSYS; +} + +static inline unsigned long cpm_muram_alloc_fixed(unsigned long offset, + unsigned long size) +{ + return -ENOSYS; +} + +static inline void __iomem *cpm_muram_addr(unsigned long offset) +{ + return NULL; +} + +static inline unsigned long cpm_muram_offset(void __iomem *addr) +{ + return -ENOSYS; +} + +static inline dma_addr_t cpm_muram_dma(void __iomem *addr) +{ + return 0; +} +#endif /* defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) */ + /* QE PIO */ #define QE_PIO_PINS 32 diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 5b492a6438ffa..f1d47498ddf24 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o obj-$(CONFIG_FSL_RIO) += fsl_rio.o fsl_rmu.o obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ +obj-$(CONFIG_CPM) += qe_lib/ mv64x60-$(CONFIG_PCI) += mv64x60_pci.o obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o \ mv64x60_udbg.o diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index fcc83cd9cc2f9..6993aa8e72427 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c @@ -17,7 +17,6 @@ * published by the Free Software Foundation. */ -#include #include #include #include @@ -29,6 +28,7 @@ #include #include #include +#include #include @@ -65,212 +65,6 @@ void __init udbg_init_cpm(void) } #endif -static struct gen_pool *muram_pool; -static spinlock_t cpm_muram_lock; -static u8 __iomem *muram_vbase; -static phys_addr_t muram_pbase; - -struct muram_block { - struct list_head head; - unsigned long start; - int size; -}; - -static LIST_HEAD(muram_block_list); - -/* max address size we deal with */ -#define OF_MAX_ADDR_CELLS 4 -#define GENPOOL_OFFSET (4096 * 8) - -int cpm_muram_init(void) -{ - struct device_node *np; - struct resource r; - u32 zero[OF_MAX_ADDR_CELLS] = {}; - resource_size_t max = 0; - int i = 0; - int ret = 0; - - if (muram_pbase) - return 0; - - spin_lock_init(&cpm_muram_lock); - np = of_find_compatible_node(NULL, NULL, "fsl,cpm-muram-data"); - if (!np) { - /* try legacy bindings */ - np = of_find_node_by_name(NULL, "data-only"); - if (!np) { - pr_err("Cannot find CPM muram data node"); - ret = -ENODEV; - goto out_muram; - } - } - - muram_pool = gen_pool_create(0, -1); - muram_pbase = of_translate_address(np, zero); - if (muram_pbase == (phys_addr_t)OF_BAD_ADDR) { - pr_err("Cannot translate zero through CPM muram node"); - ret = -ENODEV; - goto out_pool; - } - - while (of_address_to_resource(np, i++, &r) == 0) { - if (r.end > max) - max = r.end; - ret = gen_pool_add(muram_pool, r.start - muram_pbase + - GENPOOL_OFFSET, resource_size(&r), -1); - if (ret) { - pr_err("QE: couldn't add muram to pool!\n"); - goto out_pool; - } - } - - muram_vbase = ioremap(muram_pbase, max - muram_pbase + 1); - if (!muram_vbase) { - pr_err("Cannot map QE muram"); - ret = -ENOMEM; - goto out_pool; - } - goto out_muram; -out_pool: - gen_pool_destroy(muram_pool); -out_muram: - of_node_put(np); - return ret; -} - -/* - * cpm_muram_alloc - allocate the requested size worth of multi-user ram - * @size: number of bytes to allocate - * @align: requested alignment, in bytes - * - * This function returns an offset into the muram area. - * Use cpm_dpram_addr() to get the virtual address of the area. - * Use cpm_muram_free() to free the allocation. - */ -unsigned long cpm_muram_alloc(unsigned long size, unsigned long align) -{ - unsigned long start; - unsigned long flags; - struct genpool_data_align muram_pool_data; - - spin_lock_irqsave(&cpm_muram_lock, flags); - muram_pool_data.align = align; - start = cpm_muram_alloc_common(size, gen_pool_first_fit_align, - &muram_pool_data); - spin_unlock_irqrestore(&cpm_muram_lock, flags); - return start; -} -EXPORT_SYMBOL(cpm_muram_alloc); - -/** - * cpm_muram_free - free a chunk of multi-user ram - * @offset: The beginning of the chunk as returned by cpm_muram_alloc(). - */ -int cpm_muram_free(unsigned long offset) -{ - unsigned long flags; - int size; - struct muram_block *tmp; - - size = 0; - spin_lock_irqsave(&cpm_muram_lock, flags); - list_for_each_entry(tmp, &muram_block_list, head) { - if (tmp->start == offset) { - size = tmp->size; - list_del(&tmp->head); - kfree(tmp); - break; - } - } - gen_pool_free(muram_pool, offset + GENPOOL_OFFSET, size); - spin_unlock_irqrestore(&cpm_muram_lock, flags); - return size; -} -EXPORT_SYMBOL(cpm_muram_free); - -/* - * cpm_muram_alloc_fixed - reserve a specific region of multi-user ram - * @offset: offset of allocation start address - * @size: number of bytes to allocate - * This function returns an offset into the muram area - * Use cpm_dpram_addr() to get the virtual address of the area. - * Use cpm_muram_free() to free the allocation. - */ -unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size) -{ - unsigned long start; - unsigned long flags; - struct genpool_data_fixed muram_pool_data_fixed; - - spin_lock_irqsave(&cpm_muram_lock, flags); - muram_pool_data_fixed.offset = offset + GENPOOL_OFFSET; - start = cpm_muram_alloc_common(size, gen_pool_fixed_alloc, - &muram_pool_data_fixed); - spin_unlock_irqrestore(&cpm_muram_lock, flags); - return start; -} -EXPORT_SYMBOL(cpm_muram_alloc_fixed); - -/* - * cpm_muram_alloc_common - cpm_muram_alloc common code - * @size: number of bytes to allocate - * @algo: algorithm for alloc. - * @data: data for genalloc's algorithm. - * - * This function returns an offset into the muram area. - */ -unsigned long cpm_muram_alloc_common(unsigned long size, genpool_algo_t algo, - void *data) -{ - struct muram_block *entry; - unsigned long start; - - start = gen_pool_alloc_algo(muram_pool, size, algo, data); - if (!start) - goto out2; - start = start - GENPOOL_OFFSET; - memset_io(cpm_muram_addr(start), 0, size); - entry = kmalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) - goto out1; - entry->start = start; - entry->size = size; - list_add(&entry->head, &muram_block_list); - - return start; -out1: - gen_pool_free(muram_pool, start, size); -out2: - return (unsigned long)-ENOMEM; -} - -/** - * cpm_muram_addr - turn a muram offset into a virtual address - * @offset: muram offset to convert - */ -void __iomem *cpm_muram_addr(unsigned long offset) -{ - return muram_vbase + offset; -} -EXPORT_SYMBOL(cpm_muram_addr); - -unsigned long cpm_muram_offset(void __iomem *addr) -{ - return addr - (void __iomem *)muram_vbase; -} -EXPORT_SYMBOL(cpm_muram_offset); - -/** - * cpm_muram_dma - turn a muram virtual address into a DMA address - * @offset: virtual address from cpm_muram_addr() to convert - */ -dma_addr_t cpm_muram_dma(void __iomem *addr) -{ - return muram_pbase + ((u8 __iomem *)addr - muram_vbase); -} -EXPORT_SYMBOL(cpm_muram_dma); - #if defined(CONFIG_CPM2) || defined(CONFIG_8xx_GPIO) struct cpm2_ioports { diff --git a/arch/powerpc/sysdev/qe_lib/Makefile b/arch/powerpc/sysdev/qe_lib/Makefile index f1855c185291a..ffac5410c5c7f 100644 --- a/arch/powerpc/sysdev/qe_lib/Makefile +++ b/arch/powerpc/sysdev/qe_lib/Makefile @@ -1,8 +1,8 @@ # # Makefile for the linux ppc-specific parts of QE # -obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_ic.o qe_io.o - +obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_common.o qe_ic.o qe_io.o +obj-$(CONFIG_CPM) += qe_common.o obj-$(CONFIG_UCC) += ucc.o obj-$(CONFIG_UCC_SLOW) += ucc_slow.o obj-$(CONFIG_UCC_FAST) += ucc_fast.o diff --git a/arch/powerpc/sysdev/qe_lib/qe_common.c b/arch/powerpc/sysdev/qe_lib/qe_common.c new file mode 100644 index 0000000000000..b90043f1503b6 --- /dev/null +++ b/arch/powerpc/sysdev/qe_lib/qe_common.c @@ -0,0 +1,235 @@ +/* + * Common CPM code + * + * Author: Scott Wood + * + * Copyright 2007-2008,2010 Freescale Semiconductor, Inc. + * + * Some parts derived from commproc.c/cpm2_common.c, which is: + * Copyright (c) 1997 Dan error_act (dmalek@jlc.net) + * Copyright (c) 1999-2001 Dan Malek + * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com) + * 2006 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct gen_pool *muram_pool; +static spinlock_t cpm_muram_lock; +static u8 __iomem *muram_vbase; +static phys_addr_t muram_pbase; + +struct muram_block { + struct list_head head; + unsigned long start; + int size; +}; + +static LIST_HEAD(muram_block_list); + +/* max address size we deal with */ +#define OF_MAX_ADDR_CELLS 4 +#define GENPOOL_OFFSET (4096 * 8) + +int cpm_muram_init(void) +{ + struct device_node *np; + struct resource r; + u32 zero[OF_MAX_ADDR_CELLS] = {}; + resource_size_t max = 0; + int i = 0; + int ret = 0; + + if (muram_pbase) + return 0; + + spin_lock_init(&cpm_muram_lock); + np = of_find_compatible_node(NULL, NULL, "fsl,cpm-muram-data"); + if (!np) { + /* try legacy bindings */ + np = of_find_node_by_name(NULL, "data-only"); + if (!np) { + pr_err("Cannot find CPM muram data node"); + ret = -ENODEV; + goto out_muram; + } + } + + muram_pool = gen_pool_create(0, -1); + muram_pbase = of_translate_address(np, zero); + if (muram_pbase == (phys_addr_t)OF_BAD_ADDR) { + pr_err("Cannot translate zero through CPM muram node"); + ret = -ENODEV; + goto out_pool; + } + + while (of_address_to_resource(np, i++, &r) == 0) { + if (r.end > max) + max = r.end; + ret = gen_pool_add(muram_pool, r.start - muram_pbase + + GENPOOL_OFFSET, resource_size(&r), -1); + if (ret) { + pr_err("QE: couldn't add muram to pool!\n"); + goto out_pool; + } + } + + muram_vbase = ioremap(muram_pbase, max - muram_pbase + 1); + if (!muram_vbase) { + pr_err("Cannot map QE muram"); + ret = -ENOMEM; + goto out_pool; + } + goto out_muram; +out_pool: + gen_pool_destroy(muram_pool); +out_muram: + of_node_put(np); + return ret; +} + +/* + * cpm_muram_alloc - allocate the requested size worth of multi-user ram + * @size: number of bytes to allocate + * @align: requested alignment, in bytes + * + * This function returns an offset into the muram area. + * Use cpm_dpram_addr() to get the virtual address of the area. + * Use cpm_muram_free() to free the allocation. + */ +unsigned long cpm_muram_alloc(unsigned long size, unsigned long align) +{ + unsigned long start; + unsigned long flags; + struct genpool_data_align muram_pool_data; + + spin_lock_irqsave(&cpm_muram_lock, flags); + muram_pool_data.align = align; + start = cpm_muram_alloc_common(size, gen_pool_first_fit_align, + &muram_pool_data); + spin_unlock_irqrestore(&cpm_muram_lock, flags); + return start; +} +EXPORT_SYMBOL(cpm_muram_alloc); + +/** + * cpm_muram_free - free a chunk of multi-user ram + * @offset: The beginning of the chunk as returned by cpm_muram_alloc(). + */ +int cpm_muram_free(unsigned long offset) +{ + unsigned long flags; + int size; + struct muram_block *tmp; + + size = 0; + spin_lock_irqsave(&cpm_muram_lock, flags); + list_for_each_entry(tmp, &muram_block_list, head) { + if (tmp->start == offset) { + size = tmp->size; + list_del(&tmp->head); + kfree(tmp); + break; + } + } + gen_pool_free(muram_pool, offset + GENPOOL_OFFSET, size); + spin_unlock_irqrestore(&cpm_muram_lock, flags); + return size; +} +EXPORT_SYMBOL(cpm_muram_free); + +/* + * cpm_muram_alloc_fixed - reserve a specific region of multi-user ram + * @offset: offset of allocation start address + * @size: number of bytes to allocate + * This function returns an offset into the muram area + * Use cpm_dpram_addr() to get the virtual address of the area. + * Use cpm_muram_free() to free the allocation. + */ +unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size) +{ + unsigned long start; + unsigned long flags; + struct genpool_data_fixed muram_pool_data_fixed; + + spin_lock_irqsave(&cpm_muram_lock, flags); + muram_pool_data_fixed.offset = offset + GENPOOL_OFFSET; + start = cpm_muram_alloc_common(size, gen_pool_fixed_alloc, + &muram_pool_data_fixed); + spin_unlock_irqrestore(&cpm_muram_lock, flags); + return start; +} +EXPORT_SYMBOL(cpm_muram_alloc_fixed); + +/* + * cpm_muram_alloc_common - cpm_muram_alloc common code + * @size: number of bytes to allocate + * @algo: algorithm for alloc. + * @data: data for genalloc's algorithm. + * + * This function returns an offset into the muram area. + */ +unsigned long cpm_muram_alloc_common(unsigned long size, genpool_algo_t algo, + void *data) +{ + struct muram_block *entry; + unsigned long start; + + start = gen_pool_alloc_algo(muram_pool, size, algo, data); + if (!start) + goto out2; + start = start - GENPOOL_OFFSET; + memset_io(cpm_muram_addr(start), 0, size); + entry = kmalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + goto out1; + entry->start = start; + entry->size = size; + list_add(&entry->head, &muram_block_list); + + return start; +out1: + gen_pool_free(muram_pool, start, size); +out2: + return (unsigned long)-ENOMEM; +} + +/** + * cpm_muram_addr - turn a muram offset into a virtual address + * @offset: muram offset to convert + */ +void __iomem *cpm_muram_addr(unsigned long offset) +{ + return muram_vbase + offset; +} +EXPORT_SYMBOL(cpm_muram_addr); + +unsigned long cpm_muram_offset(void __iomem *addr) +{ + return addr - (void __iomem *)muram_vbase; +} +EXPORT_SYMBOL(cpm_muram_offset); + +/** + * cpm_muram_dma - turn a muram virtual address into a DMA address + * @offset: virtual address from cpm_muram_addr() to convert + */ +dma_addr_t cpm_muram_dma(void __iomem *addr) +{ + return muram_pbase + ((u8 __iomem *)addr - muram_vbase); +} +EXPORT_SYMBOL(cpm_muram_dma); -- GitLab From 302c059f2e7bac7342f912bc77ff5bd6490c8edd Mon Sep 17 00:00:00 2001 From: Zhao Qiang Date: Mon, 30 Nov 2015 10:48:56 +0800 Subject: [PATCH 2018/2855] QE: use subsys_initcall to init qe Use subsys_initcall to init qe to adapt ARM architecture. Remove qe_reset from PowerPC platform file. Signed-off-by: Zhao Qiang Signed-off-by: Scott Wood --- arch/powerpc/platforms/83xx/km83xx.c | 2 -- arch/powerpc/platforms/83xx/mpc832x_mds.c | 2 -- arch/powerpc/platforms/83xx/mpc832x_rdb.c | 2 -- arch/powerpc/platforms/83xx/mpc836x_mds.c | 2 -- arch/powerpc/platforms/83xx/mpc836x_rdk.c | 3 --- arch/powerpc/platforms/85xx/common.c | 1 - arch/powerpc/sysdev/qe_lib/qe.c | 13 +++++++++++++ 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c index bf4c4473abb96..ae11158138444 100644 --- a/arch/powerpc/platforms/83xx/km83xx.c +++ b/arch/powerpc/platforms/83xx/km83xx.c @@ -136,8 +136,6 @@ static void __init mpc83xx_km_setup_arch(void) mpc83xx_setup_pci(); #ifdef CONFIG_QUICC_ENGINE - qe_reset(); - np = of_find_node_by_name(NULL, "par_io"); if (np != NULL) { par_io_init(np); diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c index 8d762203eeffa..aacc43f642462 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c @@ -74,8 +74,6 @@ static void __init mpc832x_sys_setup_arch(void) mpc83xx_setup_pci(); #ifdef CONFIG_QUICC_ENGINE - qe_reset(); - if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) { par_io_init(np); of_node_put(np); diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c index eff5baabc3fbf..0c7a43e1c3902 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c @@ -203,8 +203,6 @@ static void __init mpc832x_rdb_setup_arch(void) mpc83xx_setup_pci(); #ifdef CONFIG_QUICC_ENGINE - qe_reset(); - if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) { par_io_init(np); of_node_put(np); diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c index 1a26d2f834019..eb24abdf1ae75 100644 --- a/arch/powerpc/platforms/83xx/mpc836x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c @@ -82,8 +82,6 @@ static void __init mpc836x_mds_setup_arch(void) mpc83xx_setup_pci(); #ifdef CONFIG_QUICC_ENGINE - qe_reset(); - if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) { par_io_init(np); of_node_put(np); diff --git a/arch/powerpc/platforms/83xx/mpc836x_rdk.c b/arch/powerpc/platforms/83xx/mpc836x_rdk.c index b63b42d11d6c9..823e370ed212a 100644 --- a/arch/powerpc/platforms/83xx/mpc836x_rdk.c +++ b/arch/powerpc/platforms/83xx/mpc836x_rdk.c @@ -35,9 +35,6 @@ static void __init mpc836x_rdk_setup_arch(void) ppc_md.progress("mpc836x_rdk_setup_arch()", 0); mpc83xx_setup_pci(); -#ifdef CONFIG_QUICC_ENGINE - qe_reset(); -#endif } /* diff --git a/arch/powerpc/platforms/85xx/common.c b/arch/powerpc/platforms/85xx/common.c index 23791de7b688f..18bca203e01af 100644 --- a/arch/powerpc/platforms/85xx/common.c +++ b/arch/powerpc/platforms/85xx/common.c @@ -105,7 +105,6 @@ void __init mpc85xx_qe_init(void) return; } - qe_reset(); of_node_put(np); } diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index c2518cdb7ddb6..88ae5c7ff4bb9 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -671,6 +671,19 @@ unsigned int qe_get_num_of_snums(void) } EXPORT_SYMBOL(qe_get_num_of_snums); +static int __init qe_init(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, "fsl,qe"); + if (!np) + return -ENODEV; + qe_reset(); + of_node_put(np); + return 0; +} +subsys_initcall(qe_init); + #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) static int qe_resume(struct platform_device *ofdev) { -- GitLab From 7aa1aa6ecec2af19d9aa85430ce3e56119e21626 Mon Sep 17 00:00:00 2001 From: Zhao Qiang Date: Mon, 30 Nov 2015 10:48:57 +0800 Subject: [PATCH 2019/2855] QE: Move QE from arch/powerpc to drivers/soc ls1 has qe and ls1 has arm cpu. move qe from arch/powerpc to drivers/soc/fsl to adapt to powerpc and arm Signed-off-by: Zhao Qiang Signed-off-by: Scott Wood --- MAINTAINERS | 5 +++-- arch/powerpc/Kconfig | 2 -- arch/powerpc/include/asm/cpm.h | 2 +- arch/powerpc/platforms/83xx/km83xx.c | 4 ++-- arch/powerpc/platforms/83xx/misc.c | 2 +- arch/powerpc/platforms/83xx/mpc832x_mds.c | 4 ++-- arch/powerpc/platforms/83xx/mpc832x_rdb.c | 4 ++-- arch/powerpc/platforms/83xx/mpc836x_mds.c | 4 ++-- arch/powerpc/platforms/83xx/mpc836x_rdk.c | 4 ++-- arch/powerpc/platforms/85xx/common.c | 2 +- arch/powerpc/platforms/85xx/corenet_generic.c | 2 +- arch/powerpc/platforms/85xx/mpc85xx_mds.c | 4 ++-- arch/powerpc/platforms/85xx/mpc85xx_rdb.c | 4 ++-- arch/powerpc/platforms/85xx/twr_p102x.c | 4 ++-- arch/powerpc/platforms/Kconfig | 11 ----------- arch/powerpc/sysdev/Makefile | 2 -- arch/powerpc/sysdev/cpm_common.c | 2 +- drivers/net/ethernet/freescale/fsl_pq_mdio.c | 2 +- drivers/net/ethernet/freescale/ucc_geth.c | 8 ++++---- drivers/net/ethernet/freescale/ucc_geth.h | 8 ++++---- drivers/soc/Kconfig | 1 + drivers/soc/Makefile | 1 + drivers/soc/fsl/Makefile | 6 ++++++ .../sysdev/qe_lib => drivers/soc/fsl/qe}/Kconfig | 11 +++++++++++ .../sysdev/qe_lib => drivers/soc/fsl/qe}/Makefile | 0 .../sysdev/qe_lib => drivers/soc/fsl/qe}/gpio.c | 2 +- .../powerpc/sysdev/qe_lib => drivers/soc/fsl/qe}/qe.c | 4 ++-- .../sysdev/qe_lib => drivers/soc/fsl/qe}/qe_common.c | 2 +- .../sysdev/qe_lib => drivers/soc/fsl/qe}/qe_ic.c | 5 +++-- .../sysdev/qe_lib => drivers/soc/fsl/qe}/qe_ic.h | 4 ++-- .../sysdev/qe_lib => drivers/soc/fsl/qe}/qe_io.c | 2 +- .../sysdev/qe_lib => drivers/soc/fsl/qe}/ucc.c | 6 +++--- .../sysdev/qe_lib => drivers/soc/fsl/qe}/ucc_fast.c | 8 ++++---- .../sysdev/qe_lib => drivers/soc/fsl/qe}/ucc_slow.c | 8 ++++---- .../sysdev/qe_lib => drivers/soc/fsl/qe}/usb.c | 4 ++-- drivers/spi/spi-fsl-cpm.c | 2 +- drivers/tty/serial/ucc_uart.c | 2 +- drivers/usb/gadget/udc/fsl_qe_udc.c | 2 +- drivers/usb/host/fhci-hcd.c | 2 +- drivers/usb/host/fhci-hub.c | 2 +- drivers/usb/host/fhci-sched.c | 2 +- drivers/usb/host/fhci.h | 4 ++-- .../include/asm => include/soc/fsl/qe}/immap_qe.h | 0 {arch/powerpc/include/asm => include/soc/fsl/qe}/qe.h | 2 +- .../include/asm => include/soc/fsl/qe}/qe_ic.h | 0 .../powerpc/include/asm => include/soc/fsl/qe}/ucc.h | 4 ++-- .../include/asm => include/soc/fsl/qe}/ucc_fast.h | 6 +++--- .../include/asm => include/soc/fsl/qe}/ucc_slow.h | 6 +++--- 48 files changed, 92 insertions(+), 86 deletions(-) create mode 100644 drivers/soc/fsl/Makefile rename {arch/powerpc/sysdev/qe_lib => drivers/soc/fsl/qe}/Kconfig (54%) rename {arch/powerpc/sysdev/qe_lib => drivers/soc/fsl/qe}/Makefile (100%) rename {arch/powerpc/sysdev/qe_lib => drivers/soc/fsl/qe}/gpio.c (99%) rename {arch/powerpc/sysdev/qe_lib => drivers/soc/fsl/qe}/qe.c (99%) rename {arch/powerpc/sysdev/qe_lib => drivers/soc/fsl/qe}/qe_common.c (99%) rename {arch/powerpc/sysdev/qe_lib => drivers/soc/fsl/qe}/qe_ic.c (99%) rename {arch/powerpc/sysdev/qe_lib => drivers/soc/fsl/qe}/qe_ic.h (97%) rename {arch/powerpc/sysdev/qe_lib => drivers/soc/fsl/qe}/qe_io.c (99%) rename {arch/powerpc/sysdev/qe_lib => drivers/soc/fsl/qe}/ucc.c (98%) rename {arch/powerpc/sysdev/qe_lib => drivers/soc/fsl/qe}/ucc_fast.c (98%) rename {arch/powerpc/sysdev/qe_lib => drivers/soc/fsl/qe}/ucc_slow.c (98%) rename {arch/powerpc/sysdev/qe_lib => drivers/soc/fsl/qe}/usb.c (96%) rename {arch/powerpc/include/asm => include/soc/fsl/qe}/immap_qe.h (100%) rename {arch/powerpc/include/asm => include/soc/fsl/qe}/qe.h (99%) rename {arch/powerpc/include/asm => include/soc/fsl/qe}/qe_ic.h (100%) rename {arch/powerpc/include/asm => include/soc/fsl/qe}/ucc.h (96%) rename {arch/powerpc/include/asm => include/soc/fsl/qe}/ucc_fast.h (98%) rename {arch/powerpc/include/asm => include/soc/fsl/qe}/ucc_slow.h (99%) diff --git a/MAINTAINERS b/MAINTAINERS index 050d0e77a2cf0..8099527abccf6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4489,8 +4489,9 @@ F: include/linux/fs_enet_pd.h FREESCALE QUICC ENGINE LIBRARY L: linuxppc-dev@lists.ozlabs.org S: Orphan -F: arch/powerpc/sysdev/qe_lib/ -F: arch/powerpc/include/asm/*qe.h +F: drivers/soc/fsl/qe/ +F: include/soc/fsl/*qe*.h +F: include/soc/fsl/*ucc*.h FREESCALE USB PERIPHERAL DRIVERS M: Li Yang diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 6e03f85b11cd5..405ce42c8ff79 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -1076,8 +1076,6 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "arch/powerpc/sysdev/qe_lib/Kconfig" - source "lib/Kconfig" source "arch/powerpc/Kconfig.debug" diff --git a/arch/powerpc/include/asm/cpm.h b/arch/powerpc/include/asm/cpm.h index 0958028cf31a0..2c5c5b4768040 100644 --- a/arch/powerpc/include/asm/cpm.h +++ b/arch/powerpc/include/asm/cpm.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include /* * SPI Parameter RAM common to QE and CPM. diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c index ae11158138444..4bc6bbbe9ada5 100644 --- a/arch/powerpc/platforms/83xx/km83xx.c +++ b/arch/powerpc/platforms/83xx/km83xx.c @@ -37,8 +37,8 @@ #include #include #include -#include -#include +#include +#include #include "mpc83xx.h" diff --git a/arch/powerpc/platforms/83xx/misc.c b/arch/powerpc/platforms/83xx/misc.c index ef9d01a049c16..7e923cad56cf6 100644 --- a/arch/powerpc/platforms/83xx/misc.c +++ b/arch/powerpc/platforms/83xx/misc.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c index aacc43f642462..a973b2ae5df6c 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c @@ -36,8 +36,8 @@ #include #include #include -#include -#include +#include +#include #include "mpc83xx.h" diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c index 0c7a43e1c3902..ea2b87d202cad 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c @@ -25,8 +25,8 @@ #include #include #include -#include -#include +#include +#include #include #include diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c index eb24abdf1ae75..dd70b85f56d41 100644 --- a/arch/powerpc/platforms/83xx/mpc836x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c @@ -44,8 +44,8 @@ #include #include #include -#include -#include +#include +#include #include "mpc83xx.h" diff --git a/arch/powerpc/platforms/83xx/mpc836x_rdk.c b/arch/powerpc/platforms/83xx/mpc836x_rdk.c index 823e370ed212a..4cd7153a6c889 100644 --- a/arch/powerpc/platforms/83xx/mpc836x_rdk.c +++ b/arch/powerpc/platforms/83xx/mpc836x_rdk.c @@ -20,8 +20,8 @@ #include #include #include -#include -#include +#include +#include #include #include diff --git a/arch/powerpc/platforms/85xx/common.c b/arch/powerpc/platforms/85xx/common.c index 18bca203e01af..949f22c86e61c 100644 --- a/arch/powerpc/platforms/85xx/common.c +++ b/arch/powerpc/platforms/85xx/common.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include "mpc85xx.h" diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c index 46d05c94add60..a2b0bc859de0c 100644 --- a/arch/powerpc/platforms/85xx/corenet_generic.c +++ b/arch/powerpc/platforms/85xx/corenet_generic.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index f0be439ceaaad..f61cbe235581a 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -48,8 +48,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include "smp.h" diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c index 50dcc00a0f5a0..3f4dad1333388 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c @@ -26,8 +26,8 @@ #include #include #include -#include -#include +#include +#include #include #include diff --git a/arch/powerpc/platforms/85xx/twr_p102x.c b/arch/powerpc/platforms/85xx/twr_p102x.c index 892e613519cc1..71bc255b43242 100644 --- a/arch/powerpc/platforms/85xx/twr_p102x.c +++ b/arch/powerpc/platforms/85xx/twr_p102x.c @@ -22,8 +22,8 @@ #include #include #include -#include -#include +#include +#include #include #include diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index 57069eb8f093d..46a3533d3acb2 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -272,17 +272,6 @@ config TAU_AVERAGE If in doubt, say N here. -config QUICC_ENGINE - bool "Freescale QUICC Engine (QE) Support" - depends on FSL_SOC && PPC32 - select GENERIC_ALLOCATOR - select CRC32 - help - The QUICC Engine (QE) is a new generation of communications - coprocessors on Freescale embedded CPUs (akin to CPM in older chips). - Selecting this option means that you wish to build a kernel - for a machine with a QE coprocessor. - config QE_GPIO bool "QE GPIO support" depends on QUICC_ENGINE diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index f1d47498ddf24..bd6bd729969c8 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -26,8 +26,6 @@ obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o obj-$(CONFIG_FSL_RIO) += fsl_rio.o fsl_rmu.o obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o -obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ -obj-$(CONFIG_CPM) += qe_lib/ mv64x60-$(CONFIG_PCI) += mv64x60_pci.o obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o \ mv64x60_udbg.o diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index 6993aa8e72427..9d32465eddb13 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c index 55c36230e1763..d0a6fa6d4f3ed 100644 --- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c +++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c @@ -29,7 +29,7 @@ #include #if IS_ENABLED(CONFIG_UCC_GETH) -#include /* for ucc_set_qe_mux_mii_mng() */ +#include #endif #include "gianfar.h" diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index 650f7888e32be..c30b72e02a1a0 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c @@ -40,10 +40,10 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include "ucc_geth.h" diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h index 75f337163ce3c..5da19b440a6a8 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.h +++ b/drivers/net/ethernet/freescale/ucc_geth.h @@ -22,11 +22,11 @@ #include #include -#include -#include +#include +#include -#include -#include +#include +#include #define DRV_DESC "QE UCC Gigabit Ethernet Controller" #define DRV_NAME "ucc_geth" diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index 4e853ed2c82b9..ad0df75fab6ed 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -1,6 +1,7 @@ menu "SOC (System On Chip) specific Drivers" source "drivers/soc/brcmstb/Kconfig" +source "drivers/soc/fsl/qe/Kconfig" source "drivers/soc/mediatek/Kconfig" source "drivers/soc/qcom/Kconfig" source "drivers/soc/rockchip/Kconfig" diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index f2ba2e932ae10..9536b804424a8 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_SOC_BRCMSTB) += brcmstb/ obj-$(CONFIG_MACH_DOVE) += dove/ +obj-y += fsl/ obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ obj-$(CONFIG_ARCH_QCOM) += qcom/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile new file mode 100644 index 0000000000000..203307fd92c15 --- /dev/null +++ b/drivers/soc/fsl/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the Linux Kernel SOC fsl specific device drivers +# + +obj-$(CONFIG_QUICC_ENGINE) += qe/ +obj-$(CONFIG_CPM) += qe/ diff --git a/arch/powerpc/sysdev/qe_lib/Kconfig b/drivers/soc/fsl/qe/Kconfig similarity index 54% rename from arch/powerpc/sysdev/qe_lib/Kconfig rename to drivers/soc/fsl/qe/Kconfig index 3c251993bacd5..20978f2058a67 100644 --- a/arch/powerpc/sysdev/qe_lib/Kconfig +++ b/drivers/soc/fsl/qe/Kconfig @@ -2,6 +2,17 @@ # QE Communication options # +config QUICC_ENGINE + bool "Freescale QUICC Engine (QE) Support" + depends on FSL_SOC && PPC32 + select GENERIC_ALLOCATOR + select CRC32 + help + The QUICC Engine (QE) is a new generation of communications + coprocessors on Freescale embedded CPUs (akin to CPM in older chips). + Selecting this option means that you wish to build a kernel + for a machine with a QE coprocessor. + config UCC_SLOW bool default y if SERIAL_QE diff --git a/arch/powerpc/sysdev/qe_lib/Makefile b/drivers/soc/fsl/qe/Makefile similarity index 100% rename from arch/powerpc/sysdev/qe_lib/Makefile rename to drivers/soc/fsl/qe/Makefile diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/drivers/soc/fsl/qe/gpio.c similarity index 99% rename from arch/powerpc/sysdev/qe_lib/gpio.c rename to drivers/soc/fsl/qe/gpio.c index 521e67a49dc40..aa5c11acf212d 100644 --- a/arch/powerpc/sysdev/qe_lib/gpio.c +++ b/drivers/soc/fsl/qe/gpio.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include struct qe_gpio_chip { struct of_mm_gpio_chip mm_gc; diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/drivers/soc/fsl/qe/qe.c similarity index 99% rename from arch/powerpc/sysdev/qe_lib/qe.c rename to drivers/soc/fsl/qe/qe.c index 88ae5c7ff4bb9..709fc63809e5c 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/drivers/soc/fsl/qe/qe.c @@ -31,8 +31,8 @@ #include #include #include -#include -#include +#include +#include #include #include diff --git a/arch/powerpc/sysdev/qe_lib/qe_common.c b/drivers/soc/fsl/qe/qe_common.c similarity index 99% rename from arch/powerpc/sysdev/qe_lib/qe_common.c rename to drivers/soc/fsl/qe/qe_common.c index b90043f1503b6..419fa5b7be4d6 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_common.c +++ b/drivers/soc/fsl/qe/qe_common.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include static struct gen_pool *muram_pool; static spinlock_t cpm_muram_lock; diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/drivers/soc/fsl/qe/qe_ic.c similarity index 99% rename from arch/powerpc/sysdev/qe_lib/qe_ic.c rename to drivers/soc/fsl/qe/qe_ic.c index ef36f16f9f6fb..b77d01ff8330d 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_ic.c +++ b/drivers/soc/fsl/qe/qe_ic.c @@ -14,6 +14,8 @@ * option) any later version. */ +#include +#include #include #include #include @@ -26,8 +28,7 @@ #include #include #include -#include -#include +#include #include "qe_ic.h" diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.h b/drivers/soc/fsl/qe/qe_ic.h similarity index 97% rename from arch/powerpc/sysdev/qe_lib/qe_ic.h rename to drivers/soc/fsl/qe/qe_ic.h index efef7ab9b753e..926a2ed423193 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_ic.h +++ b/drivers/soc/fsl/qe/qe_ic.h @@ -1,5 +1,5 @@ /* - * arch/powerpc/sysdev/qe_lib/qe_ic.h + * drivers/soc/fsl/qe/qe_ic.h * * QUICC ENGINE Interrupt Controller Header * @@ -16,7 +16,7 @@ #ifndef _POWERPC_SYSDEV_QE_IC_H #define _POWERPC_SYSDEV_QE_IC_H -#include +#include #define NR_QE_IC_INTS 64 diff --git a/arch/powerpc/sysdev/qe_lib/qe_io.c b/drivers/soc/fsl/qe/qe_io.c similarity index 99% rename from arch/powerpc/sysdev/qe_lib/qe_io.c rename to drivers/soc/fsl/qe/qe_io.c index 7ea0174f6d3d7..7ae59abc78637 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_io.c +++ b/drivers/soc/fsl/qe/qe_io.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/drivers/soc/fsl/qe/ucc.c similarity index 98% rename from arch/powerpc/sysdev/qe_lib/ucc.c rename to drivers/soc/fsl/qe/ucc.c index 621575b7e84aa..b59d3358f9bd3 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc.c +++ b/drivers/soc/fsl/qe/ucc.c @@ -21,9 +21,9 @@ #include #include -#include -#include -#include +#include +#include +#include int ucc_set_qe_mux_mii_mng(unsigned int ucc_num) { diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/drivers/soc/fsl/qe/ucc_fast.c similarity index 98% rename from arch/powerpc/sysdev/qe_lib/ucc_fast.c rename to drivers/soc/fsl/qe/ucc_fast.c index 65aaf15032aee..a7689310fe409 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc_fast.c +++ b/drivers/soc/fsl/qe/ucc_fast.c @@ -21,11 +21,11 @@ #include #include -#include -#include +#include +#include -#include -#include +#include +#include void ucc_fast_dump_regs(struct ucc_fast_private * uccf) { diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/drivers/soc/fsl/qe/ucc_slow.c similarity index 98% rename from arch/powerpc/sysdev/qe_lib/ucc_slow.c rename to drivers/soc/fsl/qe/ucc_slow.c index 5f91628209eb5..9334bdbd9b309 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc_slow.c +++ b/drivers/soc/fsl/qe/ucc_slow.c @@ -21,11 +21,11 @@ #include #include -#include -#include +#include +#include -#include -#include +#include +#include u32 ucc_slow_get_qe_cr_subblock(int uccs_num) { diff --git a/arch/powerpc/sysdev/qe_lib/usb.c b/drivers/soc/fsl/qe/usb.c similarity index 96% rename from arch/powerpc/sysdev/qe_lib/usb.c rename to drivers/soc/fsl/qe/usb.c index 27f23bd15eb65..111f7ab80f048 100644 --- a/arch/powerpc/sysdev/qe_lib/usb.c +++ b/drivers/soc/fsl/qe/usb.c @@ -17,8 +17,8 @@ #include #include #include -#include -#include +#include +#include int qe_usb_clock_set(enum qe_clock clk, int rate) { diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c index 896add8cfd3b6..8f7b26ec181e2 100644 --- a/drivers/spi/spi-fsl-cpm.c +++ b/drivers/spi/spi-fsl-cpm.c @@ -16,7 +16,7 @@ * option) any later version. */ #include -#include +#include #include #include #include diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 73190f5d28327..1a7dc3c590b19 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index 5fb6f8b4f0b48..53c0692f1b096 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index c6cebb96fd215..0960f41f945ab 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include "fhci.h" diff --git a/drivers/usb/host/fhci-hub.c b/drivers/usb/host/fhci-hub.c index 3bacdd7befe9b..60d55eb3de0dc 100644 --- a/drivers/usb/host/fhci-hub.c +++ b/drivers/usb/host/fhci-hub.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include "fhci.h" /* virtual root hub specific descriptor */ diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c index 95ca5986e672d..a9609a336efef 100644 --- a/drivers/usb/host/fhci-sched.c +++ b/drivers/usb/host/fhci-sched.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include "fhci.h" diff --git a/drivers/usb/host/fhci.h b/drivers/usb/host/fhci.h index 154e6a0077271..3fc82c1c3c73e 100644 --- a/drivers/usb/host/fhci.h +++ b/drivers/usb/host/fhci.h @@ -27,8 +27,8 @@ #include #include #include -#include -#include +#include +#include #define USB_CLOCK 48000000 diff --git a/arch/powerpc/include/asm/immap_qe.h b/include/soc/fsl/qe/immap_qe.h similarity index 100% rename from arch/powerpc/include/asm/immap_qe.h rename to include/soc/fsl/qe/immap_qe.h diff --git a/arch/powerpc/include/asm/qe.h b/include/soc/fsl/qe/qe.h similarity index 99% rename from arch/powerpc/include/asm/qe.h rename to include/soc/fsl/qe/qe.h index ceeaf91854b56..c7fa36c335c97 100644 --- a/arch/powerpc/include/asm/qe.h +++ b/include/soc/fsl/qe/qe.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/powerpc/include/asm/qe_ic.h b/include/soc/fsl/qe/qe_ic.h similarity index 100% rename from arch/powerpc/include/asm/qe_ic.h rename to include/soc/fsl/qe/qe_ic.h diff --git a/arch/powerpc/include/asm/ucc.h b/include/soc/fsl/qe/ucc.h similarity index 96% rename from arch/powerpc/include/asm/ucc.h rename to include/soc/fsl/qe/ucc.h index 6927ac26516ea..894f14cbb0445 100644 --- a/arch/powerpc/include/asm/ucc.h +++ b/include/soc/fsl/qe/ucc.h @@ -15,8 +15,8 @@ #ifndef __UCC_H__ #define __UCC_H__ -#include -#include +#include +#include #define STATISTICS diff --git a/arch/powerpc/include/asm/ucc_fast.h b/include/soc/fsl/qe/ucc_fast.h similarity index 98% rename from arch/powerpc/include/asm/ucc_fast.h rename to include/soc/fsl/qe/ucc_fast.h index 72ea9bab07df4..df8ea7958c637 100644 --- a/arch/powerpc/include/asm/ucc_fast.h +++ b/include/soc/fsl/qe/ucc_fast.h @@ -16,10 +16,10 @@ #include -#include -#include +#include +#include -#include +#include /* Receive BD's status */ #define R_E 0x80000000 /* buffer empty */ diff --git a/arch/powerpc/include/asm/ucc_slow.h b/include/soc/fsl/qe/ucc_slow.h similarity index 99% rename from arch/powerpc/include/asm/ucc_slow.h rename to include/soc/fsl/qe/ucc_slow.h index 233ef5fe5fde8..6c0573a0825c9 100644 --- a/arch/powerpc/include/asm/ucc_slow.h +++ b/include/soc/fsl/qe/ucc_slow.h @@ -17,10 +17,10 @@ #include -#include -#include +#include +#include -#include +#include /* transmit BD's status */ #define T_R 0x80000000 /* ready bit */ -- GitLab From 71242b49a075a580980d9b7845f2c25450018601 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 19 Dec 2015 16:07:09 +0100 Subject: [PATCH 2020/2855] regulator: da9*: constify regulator_ops structures The regulator_ops structures are never modified, so declare them as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Mark Brown --- drivers/regulator/da903x.c | 10 +++++----- drivers/regulator/da9052-regulator.c | 4 ++-- drivers/regulator/da9055-regulator.c | 4 ++-- drivers/regulator/da9062-regulator.c | 4 ++-- drivers/regulator/da9063-regulator.c | 4 ++-- drivers/regulator/da9210-regulator.c | 2 +- drivers/regulator/da9211-regulator.c | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index affa1b191314c..33e8f3b8d2bdd 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c @@ -257,7 +257,7 @@ static const struct regulator_linear_range da9034_ldo12_ranges[] = { REGULATOR_LINEAR_RANGE(2700000, 8, 15, 50000), }; -static struct regulator_ops da903x_regulator_ldo_ops = { +static const struct regulator_ops da903x_regulator_ldo_ops = { .set_voltage_sel = da903x_set_voltage_sel, .get_voltage_sel = da903x_get_voltage_sel, .list_voltage = regulator_list_voltage_linear, @@ -268,7 +268,7 @@ static struct regulator_ops da903x_regulator_ldo_ops = { }; /* NOTE: this is dedicated for the insane DA9030 LDO14 */ -static struct regulator_ops da9030_regulator_ldo14_ops = { +static const struct regulator_ops da9030_regulator_ldo14_ops = { .set_voltage_sel = da903x_set_voltage_sel, .get_voltage_sel = da903x_get_voltage_sel, .list_voltage = da9030_list_ldo14_voltage, @@ -279,7 +279,7 @@ static struct regulator_ops da9030_regulator_ldo14_ops = { }; /* NOTE: this is dedicated for the DA9030 LDO1 and LDO15 that have locks */ -static struct regulator_ops da9030_regulator_ldo1_15_ops = { +static const struct regulator_ops da9030_regulator_ldo1_15_ops = { .set_voltage_sel = da9030_set_ldo1_15_voltage_sel, .get_voltage_sel = da903x_get_voltage_sel, .list_voltage = regulator_list_voltage_linear, @@ -289,7 +289,7 @@ static struct regulator_ops da9030_regulator_ldo1_15_ops = { .is_enabled = da903x_is_enabled, }; -static struct regulator_ops da9034_regulator_dvc_ops = { +static const struct regulator_ops da9034_regulator_dvc_ops = { .set_voltage_sel = da9034_set_dvc_voltage_sel, .get_voltage_sel = da903x_get_voltage_sel, .list_voltage = regulator_list_voltage_linear, @@ -300,7 +300,7 @@ static struct regulator_ops da9034_regulator_dvc_ops = { }; /* NOTE: this is dedicated for the insane LDO12 */ -static struct regulator_ops da9034_regulator_ldo12_ops = { +static const struct regulator_ops da9034_regulator_ldo12_ops = { .set_voltage_sel = da903x_set_voltage_sel, .get_voltage_sel = da903x_get_voltage_sel, .list_voltage = regulator_list_voltage_linear_range, diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index 12a25b40e4730..1050cb77561a1 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c @@ -265,7 +265,7 @@ static int da9052_regulator_set_voltage_time_sel(struct regulator_dev *rdev, return ret; } -static struct regulator_ops da9052_dcdc_ops = { +static const struct regulator_ops da9052_dcdc_ops = { .get_current_limit = da9052_dcdc_get_current_limit, .set_current_limit = da9052_dcdc_set_current_limit, @@ -279,7 +279,7 @@ static struct regulator_ops da9052_dcdc_ops = { .disable = regulator_disable_regmap, }; -static struct regulator_ops da9052_ldo_ops = { +static const struct regulator_ops da9052_ldo_ops = { .list_voltage = da9052_list_voltage, .map_voltage = da9052_map_voltage, .get_voltage_sel = regulator_get_voltage_sel_regmap, diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c index cafdafbffcafb..d029c941a1e10 100644 --- a/drivers/regulator/da9055-regulator.c +++ b/drivers/regulator/da9055-regulator.c @@ -324,7 +324,7 @@ static int da9055_suspend_disable(struct regulator_dev *rdev) return 0; } -static struct regulator_ops da9055_buck_ops = { +static const struct regulator_ops da9055_buck_ops = { .get_mode = da9055_buck_get_mode, .set_mode = da9055_buck_set_mode, @@ -345,7 +345,7 @@ static struct regulator_ops da9055_buck_ops = { .set_suspend_mode = da9055_buck_set_mode, }; -static struct regulator_ops da9055_ldo_ops = { +static const struct regulator_ops da9055_ldo_ops = { .get_mode = da9055_ldo_get_mode, .set_mode = da9055_ldo_set_mode, diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-regulator.c index 5638fe8d759d7..0638c8b405215 100644 --- a/drivers/regulator/da9062-regulator.c +++ b/drivers/regulator/da9062-regulator.c @@ -371,7 +371,7 @@ static int da9062_ldo_set_suspend_mode(struct regulator_dev *rdev, return regmap_field_write(regl->suspend_sleep, val); } -static struct regulator_ops da9062_buck_ops = { +static const struct regulator_ops da9062_buck_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -389,7 +389,7 @@ static struct regulator_ops da9062_buck_ops = { .set_suspend_mode = da9062_buck_set_suspend_mode, }; -static struct regulator_ops da9062_ldo_ops = { +static const struct regulator_ops da9062_ldo_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index 536e931eb9217..ed9e7e96f8777 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c @@ -427,7 +427,7 @@ static int da9063_ldo_set_suspend_mode(struct regulator_dev *rdev, unsigned mode return regmap_field_write(regl->suspend_sleep, val); } -static struct regulator_ops da9063_buck_ops = { +static const struct regulator_ops da9063_buck_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -445,7 +445,7 @@ static struct regulator_ops da9063_buck_ops = { .set_suspend_mode = da9063_buck_set_suspend_mode, }; -static struct regulator_ops da9063_ldo_ops = { +static const struct regulator_ops da9063_ldo_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, diff --git a/drivers/regulator/da9210-regulator.c b/drivers/regulator/da9210-regulator.c index b3517830edb6f..8b3cc9f0cd64c 100644 --- a/drivers/regulator/da9210-regulator.c +++ b/drivers/regulator/da9210-regulator.c @@ -46,7 +46,7 @@ static int da9210_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA); static int da9210_get_current_limit(struct regulator_dev *rdev); -static struct regulator_ops da9210_buck_ops = { +static const struct regulator_ops da9210_buck_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index 04ef65b7eb3d2..236abf473db5d 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c @@ -219,7 +219,7 @@ static int da9211_get_current_limit(struct regulator_dev *rdev) return current_limits[data]; } -static struct regulator_ops da9211_buck_ops = { +static const struct regulator_ops da9211_buck_ops = { .get_mode = da9211_buck_get_mode, .set_mode = da9211_buck_set_mode, .enable = regulator_enable_regmap, -- GitLab From b0d6dd3ba3c3f41bface6623a18d08439cb195bb Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 19 Dec 2015 16:31:24 +0100 Subject: [PATCH 2021/2855] regulator: wm8*: constify regulator_ops structures The regulator_ops structures are never modified, so declare them as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Acked-by: Charles Keepax Signed-off-by: Mark Brown --- drivers/regulator/wm831x-dcdc.c | 8 ++++---- drivers/regulator/wm831x-isink.c | 2 +- drivers/regulator/wm831x-ldo.c | 6 +++--- drivers/regulator/wm8350-regulator.c | 8 ++++---- drivers/regulator/wm8400-regulator.c | 4 ++-- drivers/regulator/wm8994-regulator.c | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 8cbb82ceec405..fb30aeeee32bc 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -365,7 +365,7 @@ static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev) return wm831x_dcdc_ilim[val]; } -static struct regulator_ops wm831x_buckv_ops = { +static const struct regulator_ops wm831x_buckv_ops = { .set_voltage_sel = wm831x_buckv_set_voltage_sel, .get_voltage_sel = wm831x_buckv_get_voltage_sel, .list_voltage = wm831x_buckv_list_voltage, @@ -585,7 +585,7 @@ static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev, int uV) return wm831x_set_bits(wm831x, reg, WM831X_DC3_ON_VSEL_MASK, sel); } -static struct regulator_ops wm831x_buckp_ops = { +static const struct regulator_ops wm831x_buckp_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, @@ -725,7 +725,7 @@ static int wm831x_boostp_get_status(struct regulator_dev *rdev) return REGULATOR_STATUS_OFF; } -static struct regulator_ops wm831x_boostp_ops = { +static const struct regulator_ops wm831x_boostp_ops = { .get_status = wm831x_boostp_get_status, .is_enabled = regulator_is_enabled_regmap, @@ -818,7 +818,7 @@ static struct platform_driver wm831x_boostp_driver = { #define WM831X_EPE_BASE 6 -static struct regulator_ops wm831x_epe_ops = { +static const struct regulator_ops wm831x_epe_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c index 1442828fcd9af..6dd891d7eee3b 100644 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c @@ -128,7 +128,7 @@ static int wm831x_isink_get_current(struct regulator_dev *rdev) return wm831x_isinkv_values[ret]; } -static struct regulator_ops wm831x_isink_ops = { +static const struct regulator_ops wm831x_isink_ops = { .is_enabled = wm831x_isink_is_enabled, .enable = wm831x_isink_enable, .disable = wm831x_isink_disable, diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index 5a7b65e8a529c..18461cf262b45 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -198,7 +198,7 @@ static unsigned int wm831x_gp_ldo_get_optimum_mode(struct regulator_dev *rdev, } -static struct regulator_ops wm831x_gp_ldo_ops = { +static const struct regulator_ops wm831x_gp_ldo_ops = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .get_voltage_sel = regulator_get_voltage_sel_regmap, @@ -409,7 +409,7 @@ static int wm831x_aldo_get_status(struct regulator_dev *rdev) return regulator_mode_to_status(ret); } -static struct regulator_ops wm831x_aldo_ops = { +static const struct regulator_ops wm831x_aldo_ops = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .get_voltage_sel = regulator_get_voltage_sel_regmap, @@ -557,7 +557,7 @@ static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev) return REGULATOR_STATUS_OFF; } -static struct regulator_ops wm831x_alive_ldo_ops = { +static const struct regulator_ops wm831x_alive_ldo_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 95f6b040186ee..da9106bd21097 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -941,7 +941,7 @@ static unsigned int wm8350_dcdc_get_optimum_mode(struct regulator_dev *rdev, return mode; } -static struct regulator_ops wm8350_dcdc_ops = { +static const struct regulator_ops wm8350_dcdc_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, @@ -958,7 +958,7 @@ static struct regulator_ops wm8350_dcdc_ops = { .set_suspend_mode = wm8350_dcdc_set_suspend_mode, }; -static struct regulator_ops wm8350_dcdc2_5_ops = { +static const struct regulator_ops wm8350_dcdc2_5_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -966,7 +966,7 @@ static struct regulator_ops wm8350_dcdc2_5_ops = { .set_suspend_disable = wm8350_dcdc25_set_suspend_disable, }; -static struct regulator_ops wm8350_ldo_ops = { +static const struct regulator_ops wm8350_ldo_ops = { .map_voltage = regulator_map_voltage_linear_range, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, @@ -980,7 +980,7 @@ static struct regulator_ops wm8350_ldo_ops = { .set_suspend_disable = wm8350_ldo_set_suspend_disable, }; -static struct regulator_ops wm8350_isink_ops = { +static const struct regulator_ops wm8350_isink_ops = { .set_current_limit = wm8350_isink_set_current, .get_current_limit = wm8350_isink_get_current, .enable = wm8350_isink_enable, diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c index 82d8290008519..fb1837657b64c 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c @@ -24,7 +24,7 @@ static const struct regulator_linear_range wm8400_ldo_ranges[] = { REGULATOR_LINEAR_RANGE(1700000, 15, 31, 100000), }; -static struct regulator_ops wm8400_ldo_ops = { +static const struct regulator_ops wm8400_ldo_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -106,7 +106,7 @@ static unsigned int wm8400_dcdc_get_optimum_mode(struct regulator_dev *dev, return REGULATOR_MODE_NORMAL; } -static struct regulator_ops wm8400_dcdc_ops = { +static const struct regulator_ops wm8400_dcdc_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index 750e0bd61f9fa..7a4ce6df4f22a 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c @@ -36,7 +36,7 @@ struct wm8994_ldo { #define WM8994_LDO1_MAX_SELECTOR 0x7 #define WM8994_LDO2_MAX_SELECTOR 0x3 -static struct regulator_ops wm8994_ldo1_ops = { +static const struct regulator_ops wm8994_ldo1_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, @@ -69,7 +69,7 @@ static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev, } } -static struct regulator_ops wm8994_ldo2_ops = { +static const struct regulator_ops wm8994_ldo2_ops = { .list_voltage = wm8994_ldo2_list_voltage, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, -- GitLab From 95dfead1ddb8e529b24a6a98e026d1886f3c0bdf Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 19 Dec 2015 16:43:22 +0100 Subject: [PATCH 2022/2855] regulator: lp8788: constify regulator_ops structures The regulator_ops structures are never modified, so declare them as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Acked-by: Milo Kim Signed-off-by: Mark Brown --- drivers/regulator/lp8788-buck.c | 4 ++-- drivers/regulator/lp8788-ldo.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/regulator/lp8788-buck.c b/drivers/regulator/lp8788-buck.c index a97bed90d39b9..ec46290b647ee 100644 --- a/drivers/regulator/lp8788-buck.c +++ b/drivers/regulator/lp8788-buck.c @@ -344,7 +344,7 @@ static unsigned int lp8788_buck_get_mode(struct regulator_dev *rdev) REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; } -static struct regulator_ops lp8788_buck12_ops = { +static const struct regulator_ops lp8788_buck12_ops = { .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_ascend, .set_voltage_sel = lp8788_buck12_set_voltage_sel, @@ -357,7 +357,7 @@ static struct regulator_ops lp8788_buck12_ops = { .get_mode = lp8788_buck_get_mode, }; -static struct regulator_ops lp8788_buck34_ops = { +static const struct regulator_ops lp8788_buck34_ops = { .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_ascend, .set_voltage_sel = regulator_set_voltage_sel_regmap, diff --git a/drivers/regulator/lp8788-ldo.c b/drivers/regulator/lp8788-ldo.c index 30e28b1311260..cbfd358735757 100644 --- a/drivers/regulator/lp8788-ldo.c +++ b/drivers/regulator/lp8788-ldo.c @@ -170,7 +170,7 @@ static int lp8788_ldo_enable_time(struct regulator_dev *rdev) return ENABLE_TIME_USEC * val; } -static struct regulator_ops lp8788_ldo_voltage_table_ops = { +static const struct regulator_ops lp8788_ldo_voltage_table_ops = { .list_voltage = regulator_list_voltage_table, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, @@ -180,7 +180,7 @@ static struct regulator_ops lp8788_ldo_voltage_table_ops = { .enable_time = lp8788_ldo_enable_time, }; -static struct regulator_ops lp8788_ldo_voltage_fixed_ops = { +static const struct regulator_ops lp8788_ldo_voltage_fixed_ops = { .list_voltage = regulator_list_voltage_linear, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, -- GitLab From 3cb99e2ea99a454c8837a55aac88753ef05fc1eb Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 22 Dec 2015 17:08:06 +0800 Subject: [PATCH 2023/2855] regulator: axp20x: Fix GPIO LDO enable value for AXP22x The enable/disable values for GPIO LDOs are reversed. It seems no one noticed as AXP22x support was introduced recently, and no one was using the GPIO LDOs, either because no designs actually use them or board support hasn't caught up. Fixes: 1b82b4e4f954 ("regulator: axp20x: Add support for AXP22X regulators") Signed-off-by: Chen-Yu Tsai Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/regulator/axp20x-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index 35de22fdb7a06..f2e1a39ce0f35 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c @@ -27,8 +27,8 @@ #define AXP20X_IO_ENABLED 0x03 #define AXP20X_IO_DISABLED 0x07 -#define AXP22X_IO_ENABLED 0x04 -#define AXP22X_IO_DISABLED 0x03 +#define AXP22X_IO_ENABLED 0x03 +#define AXP22X_IO_DISABLED 0x04 #define AXP20X_WORKMODE_DCDC2_MASK BIT(2) #define AXP20X_WORKMODE_DCDC3_MASK BIT(1) -- GitLab From 230dd6059a97965de8464db293c3e852da395986 Mon Sep 17 00:00:00 2001 From: Harninder Rai Date: Thu, 5 Nov 2015 11:15:59 +0800 Subject: [PATCH 2024/2855] powerpc/fsl: Add PCI node in device tree of bsc9132qds Signed-off-by: Harninder Rai Signed-off-by: Minghuan Lian Signed-off-by: Hou Zhiqiang Signed-off-by: Scott Wood --- arch/powerpc/boot/dts/fsl/bsc9132qds.dts | 15 ++++++++++ arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi | 28 +++++++++++++++++++ arch/powerpc/boot/dts/fsl/bsc9132si-pre.dtsi | 1 + 3 files changed, 44 insertions(+) diff --git a/arch/powerpc/boot/dts/fsl/bsc9132qds.dts b/arch/powerpc/boot/dts/fsl/bsc9132qds.dts index 70882ade606d4..56e6f1337e963 100644 --- a/arch/powerpc/boot/dts/fsl/bsc9132qds.dts +++ b/arch/powerpc/boot/dts/fsl/bsc9132qds.dts @@ -29,6 +29,21 @@ soc: soc@ff700000 { ranges = <0x0 0x0 0xff700000 0x100000>; }; + + pci0: pcie@ff70a000 { + reg = <0 0xff70a000 0 0x1000>; + ranges = <0x2000000 0x0 0x90000000 0 0x90000000 0x0 0x20000000 + 0x1000000 0x0 0x00000000 0 0xc0010000 0x0 0x10000>; + pcie@0 { + ranges = <0x2000000 0x0 0x90000000 + 0x2000000 0x0 0x90000000 + 0x0 0x20000000 + + 0x1000000 0x0 0x0 + 0x1000000 0x0 0x0 + 0x0 0x100000>; + }; + }; }; /include/ "bsc9132qds.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi b/arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi index c723071981405..b5f071574e831 100644 --- a/arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi @@ -40,6 +40,34 @@ interrupts = <16 2 0 0 20 2 0 0>; }; +/* controller at 0xa000 */ +&pci0 { + compatible = "fsl,bsc9132-pcie", "fsl,qoriq-pcie-v2.2"; + device_type = "pci"; + #size-cells = <2>; + #address-cells = <3>; + bus-range = <0 255>; + interrupts = <16 2 0 0>; + + pcie@0 { + reg = <0 0 0 0 0>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + interrupts = <16 2 0 0>; + interrupt-map-mask = <0xf800 0 0 7>; + + interrupt-map = < + /* IDSEL 0x0 */ + 0000 0x0 0x0 0x1 &mpic 0x0 0x2 0x0 0x0 + 0000 0x0 0x0 0x2 &mpic 0x1 0x2 0x0 0x0 + 0000 0x0 0x0 0x3 &mpic 0x2 0x2 0x0 0x0 + 0000 0x0 0x0 0x4 &mpic 0x3 0x2 0x0 0x0 + >; + }; +}; + &soc { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/powerpc/boot/dts/fsl/bsc9132si-pre.dtsi b/arch/powerpc/boot/dts/fsl/bsc9132si-pre.dtsi index 301a9dba57906..90f7949fe3128 100644 --- a/arch/powerpc/boot/dts/fsl/bsc9132si-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/bsc9132si-pre.dtsi @@ -45,6 +45,7 @@ serial0 = &serial0; ethernet0 = &enet0; ethernet1 = &enet1; + pci0 = &pci0; }; cpus { -- GitLab From 720d7aebcdffda29aa71e12f3b806dbf3aa20761 Mon Sep 17 00:00:00 2001 From: Harninder Rai Date: Thu, 5 Nov 2015 11:16:00 +0800 Subject: [PATCH 2025/2855] powerpc/85xx: Add PCIe controller support for bsc9132qds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Use machine_arch_initcall to hook mpc85xx_common_publish_devices This can ensure before pcibios_init() is called, pci controllers have been probed and added to the hose_list. 2. Add a workaround for errata A-005434 For the BSC9132, PEX_PEXIWARn[TRGT] for all windows defaults to 0xF, which is mapped to CCSRBAR. However, for other products, 0xF is mapped to the local memory. Therefore, for the BSC9132, any default PCI Express access to the local memory (DDR) will now access the CCSRBAR. This patch changes the mapping of targets of inbound windows PEX_PEXIWARn[TRGT] to the Local address space – 0x0 (from 0xF). Signed-off-by: Harninder Rai Signed-off-by: Minghuan Lian Signed-off-by: Hou Zhiqiang Signed-off-by: Scott Wood --- arch/powerpc/platforms/85xx/bsc913x_qds.c | 8 +++++++- arch/powerpc/sysdev/fsl_pci.c | 13 +++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/85xx/bsc913x_qds.c b/arch/powerpc/platforms/85xx/bsc913x_qds.c index f0927e58af257..dcfafd6b91ee1 100644 --- a/arch/powerpc/platforms/85xx/bsc913x_qds.c +++ b/arch/powerpc/platforms/85xx/bsc913x_qds.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "mpc85xx.h" @@ -46,10 +47,12 @@ static void __init bsc913x_qds_setup_arch(void) mpc85xx_smp_init(); #endif + fsl_pci_assign_primary(); + pr_info("bsc913x board from Freescale Semiconductor\n"); } -machine_device_initcall(bsc9132_qds, mpc85xx_common_publish_devices); +machine_arch_initcall(bsc9132_qds, mpc85xx_common_publish_devices); /* * Called very early, device-tree isn't unflattened @@ -67,6 +70,9 @@ define_machine(bsc9132_qds) { .probe = bsc9132_qds_probe, .setup_arch = bsc913x_qds_setup_arch, .init_IRQ = bsc913x_qds_pic_init, +#ifdef CONFIG_PCI + .pcibios_fixup_bus = fsl_pcibios_fixup_bus, +#endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, .calibrate_decr = generic_calibrate_decr, diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 610f472f91d14..79976e51b8ad8 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -216,6 +216,19 @@ static void setup_pci_atmu(struct pci_controller *hose) */ setup_inbound = !is_kdump(); + if (of_device_is_compatible(hose->dn, "fsl,bsc9132-pcie")) { + /* + * BSC9132 Rev1.0 has an issue where all the PEX inbound + * windows have implemented the default target value as 0xf + * for CCSR space.In all Freescale legacy devices the target + * of 0xf is reserved for local memory space. 9132 Rev1.0 + * now has local mempry space mapped to target 0x0 instead of + * 0xf. Hence adding a workaround to remove the target 0xf + * defined for memory space from Inbound window attributes. + */ + piwar &= ~PIWAR_TGI_LOCAL; + } + if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) { win_idx = 2; -- GitLab From 4e9de5e9701f4f9206fc25249729881f8394850d Mon Sep 17 00:00:00 2001 From: Igal Liberman Date: Thu, 5 Nov 2015 12:23:06 +0200 Subject: [PATCH 2026/2855] powerpc/mpc85xx: Update B4 FMan MURAM size FMan V3H has 2 different MURAM sizes: In B4860/4420 the MURAM size is 512KB. In T4240 and T2080 the MURAM size is 384KB. The MURAM size in FMan V3H device tree is 384KB. This patch updates the MURAM size for B4 to 512KB. Signed-off-by: Igal Liberman Signed-off-by: Scott Wood --- arch/powerpc/boot/dts/fsl/b4si-post.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/powerpc/boot/dts/fsl/b4si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi index 74866ac52f39b..1b33f5157c8af 100644 --- a/arch/powerpc/boot/dts/fsl/b4si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi @@ -474,6 +474,11 @@ fman@400000 { interrupts = <96 2 0 0>, <16 2 1 30>; + muram@0 { + compatible = "fsl,fman-muram"; + reg = <0x0 0x80000>; + }; + enet0: ethernet@e0000 { }; -- GitLab From 433c858a61ac4192f821b71cd1370886e8395863 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 5 Nov 2015 16:31:21 -0800 Subject: [PATCH 2027/2855] powerpc/85xx: mpc85xx ADS: remove pci exclude This code was reworked in commit, 905e75c46dba5f3061049277e4eb7110beedba43 This change removed the fsl_add_bridge() which originally was above the addition of the pci_exclude_device function. I think the assumption was that the pci_exclude_device would prevent changes to the bridge PCI config after it's been added. It seems it wasn't fully tested on MPC85xx ADS because if you move the fsl_add_bridge() the pci_exclude_device is set in the machine description then you can never update the PCI Config since the exclude prevents it. This disrupts things like DMA. This issue was extensively debugged by David Beazley. Cc: xe-kernel@external.cisco.com Cc: dbeazley@cisco.com Cc: dwalker@fifo99.com Signed-off-by: Daniel Walker Signed-off-by: Scott Wood --- arch/powerpc/platforms/85xx/mpc85xx_ads.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c index 7d12a19aa7eec..de72a5f464b1e 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c @@ -36,17 +36,6 @@ #include "mpc85xx.h" -#ifdef CONFIG_PCI -static int mpc85xx_exclude_device(struct pci_controller *hose, - u_char bus, u_char devfn) -{ - if (bus == 0 && PCI_SLOT(devfn) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - else - return PCIBIOS_SUCCESSFUL; -} -#endif /* CONFIG_PCI */ - static void __init mpc85xx_ads_pic_init(void) { struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN, @@ -145,10 +134,6 @@ static void __init mpc85xx_ads_setup_arch(void) init_ioports(); #endif -#ifdef CONFIG_PCI - ppc_md.pci_exclude_device = mpc85xx_exclude_device; -#endif - fsl_pci_assign_primary(); } -- GitLab From 9d68e7accf28d0ffe5bf44aae4e64d744fa97337 Mon Sep 17 00:00:00 2001 From: li pengbo Date: Thu, 19 Nov 2015 10:52:04 +0800 Subject: [PATCH 2028/2855] powerpc/85xx: Enable TWR_P102x in mpc85xx_basic_defconfig Enable TWR_P102x option by default in mpc85xx_basic_defconfig to support p1025twr board. Signed-off-by: Pengbo Li Signed-off-by: Scott Wood --- arch/powerpc/configs/mpc85xx_basic_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/configs/mpc85xx_basic_defconfig b/arch/powerpc/configs/mpc85xx_basic_defconfig index 850bd195d0e81..b1593fe6f70bc 100644 --- a/arch/powerpc/configs/mpc85xx_basic_defconfig +++ b/arch/powerpc/configs/mpc85xx_basic_defconfig @@ -12,6 +12,7 @@ CONFIG_P1010_RDB=y CONFIG_P1022_DS=y CONFIG_P1022_RDK=y CONFIG_P1023_RDB=y +CONFIG_TWR_P102x=y CONFIG_SBC8548=y CONFIG_SOCRATES=y CONFIG_STX_GP3=y -- GitLab From 2749539b4bf8231b3a20ad759ec8c559ec29292c Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Fri, 4 Dec 2015 16:31:13 -0600 Subject: [PATCH 2029/2855] powerpc/e6500: add locking to hugetlb e6500 has threads but does not have TLB write conditional. Thus, the hugetlb code needs to take the same lock that the normal TLB miss handlers take, to ensure that the tlbsx and tlbwe are atomic. Signed-off-by: Scott Wood --- arch/powerpc/mm/hugetlbpage-book3e.c | 46 ++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/arch/powerpc/mm/hugetlbpage-book3e.c b/arch/powerpc/mm/hugetlbpage-book3e.c index ba47aaf33a4bf..7e6d0880813fe 100644 --- a/arch/powerpc/mm/hugetlbpage-book3e.c +++ b/arch/powerpc/mm/hugetlbpage-book3e.c @@ -51,6 +51,48 @@ static inline int mmu_get_tsize(int psize) return mmu_psize_defs[psize].enc; } +#if defined(CONFIG_PPC_FSL_BOOK3E) && defined(CONFIG_PPC64) +#include + +static inline void book3e_tlb_lock(void) +{ + struct paca_struct *paca = get_paca(); + unsigned long tmp; + int token = smp_processor_id() + 1; + + asm volatile("1: lbarx %0, 0, %1;" + "cmpwi %0, 0;" + "bne 2f;" + "stbcx. %2, 0, %1;" + "bne 1b;" + "b 3f;" + "2: lbzx %0, 0, %1;" + "cmpwi %0, 0;" + "bne 2b;" + "b 1b;" + "3:" + : "=&r" (tmp) + : "r" (&paca->tcd_ptr->lock), "r" (token) + : "memory"); +} + +static inline void book3e_tlb_unlock(void) +{ + struct paca_struct *paca = get_paca(); + + isync(); + paca->tcd_ptr->lock = 0; +} +#else +static inline void book3e_tlb_lock(void) +{ +} + +static inline void book3e_tlb_unlock(void) +{ +} +#endif + static inline int book3e_tlb_exists(unsigned long ea, unsigned long pid) { int found = 0; @@ -109,7 +151,10 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea, */ local_irq_save(flags); + book3e_tlb_lock(); + if (unlikely(book3e_tlb_exists(ea, mm->context.id))) { + book3e_tlb_unlock(); local_irq_restore(flags); return; } @@ -141,6 +186,7 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea, asm volatile ("tlbwe"); + book3e_tlb_unlock(); local_irq_restore(flags); } -- GitLab From b0417a2870eff30cc102fbc34982b6ce06ce8c6f Mon Sep 17 00:00:00 2001 From: Zhao Qiang Date: Tue, 15 Dec 2015 10:41:18 +0800 Subject: [PATCH 2030/2855] powerpc/p1010rdb: Update dts for pcie interrupt-map p1010rdb uses the irq[4:5] for inta and intb to pcie, it is active-high, so set it. Signed-off-by: Zhao Qiang Signed-off-by: Scott Wood --- arch/powerpc/boot/dts/fsl/p1010rdb.dtsi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi index 0f0ced69835a0..14b6295050389 100644 --- a/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi @@ -215,3 +215,19 @@ phy-connection-type = "sgmii"; }; }; + +&pci0 { + pcie@0 { + interrupt-map = < + /* IDSEL 0x0 */ + /* + *irq[4:5] are active-high + *irq[6:7] are active-low + */ + 0000 0x0 0x0 0x1 &mpic 0x4 0x2 0x0 0x0 + 0000 0x0 0x0 0x2 &mpic 0x5 0x2 0x0 0x0 + 0000 0x0 0x0 0x3 &mpic 0x6 0x1 0x0 0x0 + 0000 0x0 0x0 0x4 &mpic 0x7 0x1 0x0 0x0 + >; + }; +}; -- GitLab From 746bfe63bba37ad55956b7377c9af494e7e28929 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 21 Dec 2015 18:40:04 +0900 Subject: [PATCH 2031/2855] usb: gadget: renesas_usb3: add support for Renesas USB3.0 peripheral controller R-Car H3 has USB3.0 peripheral controllers. This controller's has the following features: - Supports super, high and full speed - Contains 30 pipes for bulk or interrupt transfer - Contains dedicated DMA controller This driver doesn't support the dedicated DMAC for now. Acked-by: Rob Herring Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- .../devicetree/bindings/usb/renesas_usb3.txt | 23 + drivers/usb/gadget/udc/Kconfig | 11 + drivers/usb/gadget/udc/Makefile | 1 + drivers/usb/gadget/udc/renesas_usb3.c | 1975 +++++++++++++++++ 4 files changed, 2010 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/renesas_usb3.txt create mode 100644 drivers/usb/gadget/udc/renesas_usb3.c diff --git a/Documentation/devicetree/bindings/usb/renesas_usb3.txt b/Documentation/devicetree/bindings/usb/renesas_usb3.txt new file mode 100644 index 0000000000000..8d52766f07b90 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/renesas_usb3.txt @@ -0,0 +1,23 @@ +Renesas Electronics USB3.0 Peripheral driver + +Required properties: + - compatible: Must contain one of the following: + - "renesas,r8a7795-usb3-peri" + - reg: Base address and length of the register for the USB3.0 Peripheral + - interrupts: Interrupt specifier for the USB3.0 Peripheral + - clocks: clock phandle and specifier pair + +Example: + usb3_peri0: usb@ee020000 { + compatible = "renesas,r8a7795-usb3-peri"; + reg = <0 0xee020000 0 0x400>; + interrupts = ; + clocks = <&cpg CPG_MOD 328>; + }; + + usb3_peri1: usb@ee060000 { + compatible = "renesas,r8a7795-usb3-peri"; + reg = <0 0xee060000 0 0x400>; + interrupts = ; + clocks = <&cpg CPG_MOD 327>; + }; diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index cdbff54e07acc..753c29bd11ad7 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -174,6 +174,17 @@ config USB_RENESAS_USBHS_UDC dynamically linked module called "renesas_usbhs" and force all gadget drivers to also be dynamically linked. +config USB_RENESAS_USB3 + tristate 'Renesas USB3.0 Peripheral controller' + depends on ARCH_SHMOBILE || COMPILE_TEST + help + Renesas USB3.0 Peripheral controller is a USB peripheral controller + that supports super, high, and full speed USB 3.0 data transfers. + + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "renesas_usb3" and force all + gadget drivers to also be dynamically linked. + config USB_PXA27X tristate "PXA 27x" help diff --git a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile index fba2049bf985e..dfee534463198 100644 --- a/drivers/usb/gadget/udc/Makefile +++ b/drivers/usb/gadget/udc/Makefile @@ -19,6 +19,7 @@ fsl_usb2_udc-y := fsl_udc_core.o fsl_usb2_udc-$(CONFIG_ARCH_MXC) += fsl_mxc_udc.o obj-$(CONFIG_USB_M66592) += m66592-udc.o obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o +obj-$(CONFIG_USB_RENESAS_USB3) += renesas_usb3.o obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o obj-$(CONFIG_USB_S3C_HSUDC) += s3c-hsudc.o obj-$(CONFIG_USB_LPC32XX) += lpc32xx_udc.o diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c new file mode 100644 index 0000000000000..93a3bec81df78 --- /dev/null +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -0,0 +1,1975 @@ +/* + * Renesas USB3.0 Peripheral driver (USB gadget) + * + * Copyright (C) 2015 Renesas Electronics Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* register definitions */ +#define USB3_AXI_INT_STA 0x008 +#define USB3_AXI_INT_ENA 0x00c +#define USB3_DMA_INT_STA 0x010 +#define USB3_DMA_INT_ENA 0x014 +#define USB3_USB_COM_CON 0x200 +#define USB3_USB20_CON 0x204 +#define USB3_USB30_CON 0x208 +#define USB3_USB_STA 0x210 +#define USB3_DRD_CON 0x218 +#define USB3_USB_INT_STA_1 0x220 +#define USB3_USB_INT_STA_2 0x224 +#define USB3_USB_INT_ENA_1 0x228 +#define USB3_USB_INT_ENA_2 0x22c +#define USB3_STUP_DAT_0 0x230 +#define USB3_STUP_DAT_1 0x234 +#define USB3_P0_MOD 0x280 +#define USB3_P0_CON 0x288 +#define USB3_P0_STA 0x28c +#define USB3_P0_INT_STA 0x290 +#define USB3_P0_INT_ENA 0x294 +#define USB3_P0_LNG 0x2a0 +#define USB3_P0_READ 0x2a4 +#define USB3_P0_WRITE 0x2a8 +#define USB3_PIPE_COM 0x2b0 +#define USB3_PN_MOD 0x2c0 +#define USB3_PN_RAMMAP 0x2c4 +#define USB3_PN_CON 0x2c8 +#define USB3_PN_STA 0x2cc +#define USB3_PN_INT_STA 0x2d0 +#define USB3_PN_INT_ENA 0x2d4 +#define USB3_PN_LNG 0x2e0 +#define USB3_PN_READ 0x2e4 +#define USB3_PN_WRITE 0x2e8 +#define USB3_SSIFCMD 0x340 + +/* AXI_INT_ENA and AXI_INT_STA */ +#define AXI_INT_DMAINT BIT(31) +#define AXI_INT_EPCINT BIT(30) + +/* LCLKSEL */ +#define LCLKSEL_LSEL BIT(18) + +/* USB_COM_CON */ +#define USB_COM_CON_CONF BIT(24) +#define USB_COM_CON_SPD_MODE BIT(17) +#define USB_COM_CON_EP0_EN BIT(16) +#define USB_COM_CON_DEV_ADDR_SHIFT 8 +#define USB_COM_CON_DEV_ADDR_MASK GENMASK(14, USB_COM_CON_DEV_ADDR_SHIFT) +#define USB_COM_CON_DEV_ADDR(n) (((n) << USB_COM_CON_DEV_ADDR_SHIFT) & \ + USB_COM_CON_DEV_ADDR_MASK) +#define USB_COM_CON_RX_DETECTION BIT(1) +#define USB_COM_CON_PIPE_CLR BIT(0) + +/* USB20_CON */ +#define USB20_CON_B2_PUE BIT(31) +#define USB20_CON_B2_SUSPEND BIT(24) +#define USB20_CON_B2_CONNECT BIT(17) +#define USB20_CON_B2_TSTMOD_SHIFT 8 +#define USB20_CON_B2_TSTMOD_MASK GENMASK(10, USB20_CON_B2_TSTMOD_SHIFT) +#define USB20_CON_B2_TSTMOD(n) (((n) << USB20_CON_B2_TSTMOD_SHIFT) & \ + USB20_CON_B2_TSTMOD_MASK) +#define USB20_CON_B2_TSTMOD_EN BIT(0) + +/* USB30_CON */ +#define USB30_CON_POW_SEL_SHIFT 24 +#define USB30_CON_POW_SEL_MASK GENMASK(26, USB30_CON_POW_SEL_SHIFT) +#define USB30_CON_POW_SEL_IN_U3 BIT(26) +#define USB30_CON_POW_SEL_IN_DISCON 0 +#define USB30_CON_POW_SEL_P2_TO_P0 BIT(25) +#define USB30_CON_POW_SEL_P0_TO_P3 BIT(24) +#define USB30_CON_POW_SEL_P0_TO_P2 0 +#define USB30_CON_B3_PLLWAKE BIT(23) +#define USB30_CON_B3_CONNECT BIT(17) +#define USB30_CON_B3_HOTRST_CMP BIT(1) + +/* USB_STA */ +#define USB_STA_SPEED_MASK (BIT(2) | BIT(1)) +#define USB_STA_SPEED_HS BIT(2) +#define USB_STA_SPEED_FS BIT(1) +#define USB_STA_SPEED_SS 0 +#define USB_STA_VBUS_STA BIT(0) + +/* DRD_CON */ +#define DRD_CON_PERI_CON BIT(24) + +/* USB_INT_ENA_1 and USB_INT_STA_1 */ +#define USB_INT_1_B3_PLLWKUP BIT(31) +#define USB_INT_1_B3_LUPSUCS BIT(30) +#define USB_INT_1_B3_DISABLE BIT(27) +#define USB_INT_1_B3_WRMRST BIT(21) +#define USB_INT_1_B3_HOTRST BIT(20) +#define USB_INT_1_B2_USBRST BIT(12) +#define USB_INT_1_B2_L1SPND BIT(11) +#define USB_INT_1_B2_SPND BIT(9) +#define USB_INT_1_B2_RSUM BIT(8) +#define USB_INT_1_SPEED BIT(1) +#define USB_INT_1_VBUS_CNG BIT(0) + +/* USB_INT_ENA_2 and USB_INT_STA_2 */ +#define USB_INT_2_PIPE(n) BIT(n) + +/* P0_MOD */ +#define P0_MOD_DIR BIT(6) + +/* P0_CON and PN_CON */ +#define PX_CON_BYTE_EN_MASK (BIT(10) | BIT(9)) +#define PX_CON_BYTE_EN_SHIFT 9 +#define PX_CON_BYTE_EN_BYTES(n) (((n) << PX_CON_BYTE_EN_SHIFT) & \ + PX_CON_BYTE_EN_MASK) +#define PX_CON_SEND BIT(8) + +/* P0_CON */ +#define P0_CON_ST_RES_MASK (BIT(27) | BIT(26)) +#define P0_CON_ST_RES_FORCE_STALL BIT(27) +#define P0_CON_ST_RES_NORMAL BIT(26) +#define P0_CON_ST_RES_FORCE_NRDY 0 +#define P0_CON_OT_RES_MASK (BIT(25) | BIT(24)) +#define P0_CON_OT_RES_FORCE_STALL BIT(25) +#define P0_CON_OT_RES_NORMAL BIT(24) +#define P0_CON_OT_RES_FORCE_NRDY 0 +#define P0_CON_IN_RES_MASK (BIT(17) | BIT(16)) +#define P0_CON_IN_RES_FORCE_STALL BIT(17) +#define P0_CON_IN_RES_NORMAL BIT(16) +#define P0_CON_IN_RES_FORCE_NRDY 0 +#define P0_CON_RES_WEN BIT(7) +#define P0_CON_BCLR BIT(1) + +/* P0_STA and PN_STA */ +#define PX_STA_BUFSTS BIT(0) + +/* P0_INT_ENA and P0_INT_STA */ +#define P0_INT_STSED BIT(18) +#define P0_INT_STSST BIT(17) +#define P0_INT_SETUP BIT(16) +#define P0_INT_RCVNL BIT(8) +#define P0_INT_ERDY BIT(7) +#define P0_INT_FLOW BIT(6) +#define P0_INT_STALL BIT(2) +#define P0_INT_NRDY BIT(1) +#define P0_INT_BFRDY BIT(0) +#define P0_INT_ALL_BITS (P0_INT_STSED | P0_INT_SETUP | P0_INT_BFRDY) + +/* PN_MOD */ +#define PN_MOD_DIR BIT(6) +#define PN_MOD_TYPE_SHIFT 4 +#define PN_MOD_TYPE_MASK GENMASK(5, PN_MOD_TYPE_SHIFT) +#define PN_MOD_TYPE(n) (((n) << PN_MOD_TYPE_SHIFT) & \ + PN_MOD_TYPE_MASK) +#define PN_MOD_EPNUM_MASK GENMASK(3, 0) +#define PN_MOD_EPNUM(n) ((n) & PN_MOD_EPNUM_MASK) + +/* PN_RAMMAP */ +#define PN_RAMMAP_RAMAREA_SHIFT 29 +#define PN_RAMMAP_RAMAREA_MASK GENMASK(31, PN_RAMMAP_RAMAREA_SHIFT) +#define PN_RAMMAP_RAMAREA_16KB BIT(31) +#define PN_RAMMAP_RAMAREA_8KB (BIT(30) | BIT(29)) +#define PN_RAMMAP_RAMAREA_4KB BIT(30) +#define PN_RAMMAP_RAMAREA_2KB BIT(29) +#define PN_RAMMAP_RAMAREA_1KB 0 +#define PN_RAMMAP_MPKT_SHIFT 16 +#define PN_RAMMAP_MPKT_MASK GENMASK(26, PN_RAMMAP_MPKT_SHIFT) +#define PN_RAMMAP_MPKT(n) (((n) << PN_RAMMAP_MPKT_SHIFT) & \ + PN_RAMMAP_MPKT_MASK) +#define PN_RAMMAP_RAMIF_SHIFT 14 +#define PN_RAMMAP_RAMIF_MASK GENMASK(15, PN_RAMMAP_RAMIF_SHIFT) +#define PN_RAMMAP_RAMIF(n) (((n) << PN_RAMMAP_RAMIF_SHIFT) & \ + PN_RAMMAP_RAMIF_MASK) +#define PN_RAMMAP_BASEAD_MASK GENMASK(13, 0) +#define PN_RAMMAP_BASEAD(offs) (((offs) >> 3) & PN_RAMMAP_BASEAD_MASK) +#define PN_RAMMAP_DATA(area, ramif, basead) ((PN_RAMMAP_##area) | \ + (PN_RAMMAP_RAMIF(ramif)) | \ + (PN_RAMMAP_BASEAD(basead))) + +/* PN_CON */ +#define PN_CON_EN BIT(31) +#define PN_CON_DATAIF_EN BIT(30) +#define PN_CON_RES_MASK (BIT(17) | BIT(16)) +#define PN_CON_RES_FORCE_STALL BIT(17) +#define PN_CON_RES_NORMAL BIT(16) +#define PN_CON_RES_FORCE_NRDY 0 +#define PN_CON_LAST BIT(11) +#define PN_CON_RES_WEN BIT(7) +#define PN_CON_CLR BIT(0) + +/* PN_INT_STA and PN_INT_ENA */ +#define PN_INT_LSTTR BIT(4) +#define PN_INT_BFRDY BIT(0) + +/* USB3_SSIFCMD */ +#define SSIFCMD_URES_U2 BIT(9) +#define SSIFCMD_URES_U1 BIT(8) +#define SSIFCMD_UDIR_U2 BIT(7) +#define SSIFCMD_UDIR_U1 BIT(6) +#define SSIFCMD_UREQ_U2 BIT(5) +#define SSIFCMD_UREQ_U1 BIT(4) + +#define USB3_EP0_SS_MAX_PACKET_SIZE 512 +#define USB3_EP0_HSFS_MAX_PACKET_SIZE 64 +#define USB3_EP0_BUF_SIZE 8 +#define USB3_MAX_NUM_PIPES 30 +#define USB3_WAIT_US 3 + +struct renesas_usb3; +struct renesas_usb3_request { + struct usb_request req; + struct list_head queue; +}; + +#define USB3_EP_NAME_SIZE 8 +struct renesas_usb3_ep { + struct usb_ep ep; + struct renesas_usb3 *usb3; + int num; + char ep_name[USB3_EP_NAME_SIZE]; + struct list_head queue; + u32 rammap_val; + bool dir_in; + bool halt; + bool wedge; + bool started; +}; + +struct renesas_usb3_priv { + int ramsize_per_ramif; /* unit = bytes */ + int num_ramif; + int ramsize_per_pipe; /* unit = bytes */ + bool workaround_for_vbus; /* if true, don't check vbus signal */ +}; + +struct renesas_usb3 { + void __iomem *reg; + + struct usb_gadget gadget; + struct usb_gadget_driver *driver; + + struct renesas_usb3_ep *usb3_ep; + int num_usb3_eps; + + spinlock_t lock; + int disabled_count; + + struct usb_request *ep0_req; + u16 test_mode; + u8 ep0_buf[USB3_EP0_BUF_SIZE]; + bool softconnect; + bool workaround_for_vbus; +}; + +#define gadget_to_renesas_usb3(_gadget) \ + container_of(_gadget, struct renesas_usb3, gadget) +#define renesas_usb3_to_gadget(renesas_usb3) (&renesas_usb3->gadget) +#define usb3_to_dev(_usb3) (_usb3->gadget.dev.parent) + +#define usb_ep_to_usb3_ep(_ep) container_of(_ep, struct renesas_usb3_ep, ep) +#define usb3_ep_to_usb3(_usb3_ep) (_usb3_ep->usb3) +#define usb_req_to_usb3_req(_req) container_of(_req, \ + struct renesas_usb3_request, req) + +#define usb3_get_ep(usb3, n) ((usb3)->usb3_ep + (n)) +#define usb3_for_each_ep(usb3_ep, usb3, i) \ + for ((i) = 0, usb3_ep = usb3_get_ep(usb3, (i)); \ + (i) < (usb3)->num_usb3_eps; \ + (i)++, usb3_ep = usb3_get_ep(usb3, (i))) + +static const char udc_name[] = "renesas_usb3"; + +static void usb3_write(struct renesas_usb3 *usb3, u32 data, u32 offs) +{ + iowrite32(data, usb3->reg + offs); +} + +static u32 usb3_read(struct renesas_usb3 *usb3, u32 offs) +{ + return ioread32(usb3->reg + offs); +} + +static void usb3_set_bit(struct renesas_usb3 *usb3, u32 bits, u32 offs) +{ + u32 val = usb3_read(usb3, offs); + + val |= bits; + usb3_write(usb3, val, offs); +} + +static void usb3_clear_bit(struct renesas_usb3 *usb3, u32 bits, u32 offs) +{ + u32 val = usb3_read(usb3, offs); + + val &= ~bits; + usb3_write(usb3, val, offs); +} + +static int usb3_wait(struct renesas_usb3 *usb3, u32 reg, u32 mask, + u32 expected) +{ + int i; + + for (i = 0; i < USB3_WAIT_US; i++) { + if ((usb3_read(usb3, reg) & mask) == expected) + return 0; + udelay(1); + } + + dev_dbg(usb3_to_dev(usb3), "%s: timed out (%8x, %08x, %08x)\n", + __func__, reg, mask, expected); + + return -EBUSY; +} + +static void usb3_enable_irq_1(struct renesas_usb3 *usb3, u32 bits) +{ + usb3_set_bit(usb3, bits, USB3_USB_INT_ENA_1); +} + +static void usb3_disable_irq_1(struct renesas_usb3 *usb3, u32 bits) +{ + usb3_clear_bit(usb3, bits, USB3_USB_INT_ENA_1); +} + +static void usb3_enable_pipe_irq(struct renesas_usb3 *usb3, int num) +{ + usb3_set_bit(usb3, USB_INT_2_PIPE(num), USB3_USB_INT_ENA_2); +} + +static void usb3_disable_pipe_irq(struct renesas_usb3 *usb3, int num) +{ + usb3_clear_bit(usb3, USB_INT_2_PIPE(num), USB3_USB_INT_ENA_2); +} + +static void usb3_init_axi_bridge(struct renesas_usb3 *usb3) +{ + /* Set AXI_INT */ + usb3_write(usb3, ~0, USB3_DMA_INT_STA); + usb3_write(usb3, 0, USB3_DMA_INT_ENA); + usb3_set_bit(usb3, AXI_INT_DMAINT | AXI_INT_EPCINT, USB3_AXI_INT_ENA); +} + +static void usb3_init_epc_registers(struct renesas_usb3 *usb3) +{ + /* FIXME: How to change host / peripheral mode as well? */ + usb3_set_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON); + + usb3_write(usb3, ~0, USB3_USB_INT_STA_1); + usb3_enable_irq_1(usb3, USB_INT_1_VBUS_CNG); +} + +static bool usb3_wakeup_usb2_phy(struct renesas_usb3 *usb3) +{ + if (!(usb3_read(usb3, USB3_USB20_CON) & USB20_CON_B2_SUSPEND)) + return true; /* already waked it up */ + + usb3_clear_bit(usb3, USB20_CON_B2_SUSPEND, USB3_USB20_CON); + usb3_enable_irq_1(usb3, USB_INT_1_B2_RSUM); + + return false; +} + +static void usb3_usb2_pullup(struct renesas_usb3 *usb3, int pullup) +{ + u32 bits = USB20_CON_B2_PUE | USB20_CON_B2_CONNECT; + + if (usb3->softconnect && pullup) + usb3_set_bit(usb3, bits, USB3_USB20_CON); + else + usb3_clear_bit(usb3, bits, USB3_USB20_CON); +} + +static void usb3_set_test_mode(struct renesas_usb3 *usb3) +{ + u32 val = usb3_read(usb3, USB3_USB20_CON); + + val &= ~USB20_CON_B2_TSTMOD_MASK; + val |= USB20_CON_B2_TSTMOD(usb3->test_mode); + usb3_write(usb3, val | USB20_CON_B2_TSTMOD_EN, USB3_USB20_CON); + if (!usb3->test_mode) + usb3_clear_bit(usb3, USB20_CON_B2_TSTMOD_EN, USB3_USB20_CON); +} + +static void usb3_start_usb2_connection(struct renesas_usb3 *usb3) +{ + usb3->disabled_count++; + usb3_set_bit(usb3, USB_COM_CON_EP0_EN, USB3_USB_COM_CON); + usb3_set_bit(usb3, USB_COM_CON_SPD_MODE, USB3_USB_COM_CON); + usb3_usb2_pullup(usb3, 1); +} + +static int usb3_is_usb3_phy_in_u3(struct renesas_usb3 *usb3) +{ + return usb3_read(usb3, USB3_USB30_CON) & USB30_CON_POW_SEL_IN_U3; +} + +static bool usb3_wakeup_usb3_phy(struct renesas_usb3 *usb3) +{ + if (!usb3_is_usb3_phy_in_u3(usb3)) + return true; /* already waked it up */ + + usb3_set_bit(usb3, USB30_CON_B3_PLLWAKE, USB3_USB30_CON); + usb3_enable_irq_1(usb3, USB_INT_1_B3_PLLWKUP); + + return false; +} + +static u16 usb3_feature_get_un_enabled(struct renesas_usb3 *usb3) +{ + u32 mask_u2 = SSIFCMD_UDIR_U2 | SSIFCMD_UREQ_U2; + u32 mask_u1 = SSIFCMD_UDIR_U1 | SSIFCMD_UREQ_U1; + u32 val = usb3_read(usb3, USB3_SSIFCMD); + u16 ret = 0; + + /* Enables {U2,U1} if the bits of UDIR and UREQ are set to 0 */ + if (!(val & mask_u2)) + ret |= 1 << USB_DEV_STAT_U2_ENABLED; + if (!(val & mask_u1)) + ret |= 1 << USB_DEV_STAT_U1_ENABLED; + + return ret; +} + +static void usb3_feature_u2_enable(struct renesas_usb3 *usb3, bool enable) +{ + u32 bits = SSIFCMD_UDIR_U2 | SSIFCMD_UREQ_U2; + + /* Enables U2 if the bits of UDIR and UREQ are set to 0 */ + if (enable) + usb3_clear_bit(usb3, bits, USB3_SSIFCMD); + else + usb3_set_bit(usb3, bits, USB3_SSIFCMD); +} + +static void usb3_feature_u1_enable(struct renesas_usb3 *usb3, bool enable) +{ + u32 bits = SSIFCMD_UDIR_U1 | SSIFCMD_UREQ_U1; + + /* Enables U1 if the bits of UDIR and UREQ are set to 0 */ + if (enable) + usb3_clear_bit(usb3, bits, USB3_SSIFCMD); + else + usb3_set_bit(usb3, bits, USB3_SSIFCMD); +} + +static void usb3_start_operation_for_usb3(struct renesas_usb3 *usb3) +{ + usb3_set_bit(usb3, USB_COM_CON_EP0_EN, USB3_USB_COM_CON); + usb3_clear_bit(usb3, USB_COM_CON_SPD_MODE, USB3_USB_COM_CON); + usb3_set_bit(usb3, USB30_CON_B3_CONNECT, USB3_USB30_CON); +} + +static void usb3_start_usb3_connection(struct renesas_usb3 *usb3) +{ + usb3_start_operation_for_usb3(usb3); + usb3_set_bit(usb3, USB_COM_CON_RX_DETECTION, USB3_USB_COM_CON); + + usb3_enable_irq_1(usb3, USB_INT_1_B3_LUPSUCS | USB_INT_1_B3_DISABLE | + USB_INT_1_SPEED); +} + +static void usb3_stop_usb3_connection(struct renesas_usb3 *usb3) +{ + usb3_clear_bit(usb3, USB30_CON_B3_CONNECT, USB3_USB30_CON); +} + +static void usb3_transition_to_default_state(struct renesas_usb3 *usb3, + bool is_usb3) +{ + usb3_set_bit(usb3, USB_INT_2_PIPE(0), USB3_USB_INT_ENA_2); + usb3_write(usb3, P0_INT_ALL_BITS, USB3_P0_INT_STA); + usb3_set_bit(usb3, P0_INT_ALL_BITS, USB3_P0_INT_ENA); + + if (is_usb3) + usb3_enable_irq_1(usb3, USB_INT_1_B3_WRMRST | + USB_INT_1_B3_HOTRST); + else + usb3_enable_irq_1(usb3, USB_INT_1_B2_SPND | + USB_INT_1_B2_L1SPND | USB_INT_1_B2_USBRST); +} + +static void usb3_connect(struct renesas_usb3 *usb3) +{ + if (usb3_wakeup_usb3_phy(usb3)) + usb3_start_usb3_connection(usb3); +} + +static void usb3_reset_epc(struct renesas_usb3 *usb3) +{ + usb3_clear_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON); + usb3_clear_bit(usb3, USB_COM_CON_EP0_EN, USB3_USB_COM_CON); + usb3_set_bit(usb3, USB_COM_CON_PIPE_CLR, USB3_USB_COM_CON); + usb3->test_mode = 0; + usb3_set_test_mode(usb3); +} + +static void usb3_disconnect(struct renesas_usb3 *usb3) +{ + usb3->disabled_count = 0; + usb3_usb2_pullup(usb3, 0); + usb3_clear_bit(usb3, USB30_CON_B3_CONNECT, USB3_USB30_CON); + usb3_reset_epc(usb3); + + if (usb3->driver) + usb3->driver->disconnect(&usb3->gadget); +} + +static void usb3_check_vbus(struct renesas_usb3 *usb3) +{ + if (usb3->workaround_for_vbus) { + usb3_connect(usb3); + } else { + if (usb3_read(usb3, USB3_USB_STA) & USB_STA_VBUS_STA) + usb3_connect(usb3); + else + usb3_disconnect(usb3); + } +} + +static void renesas_usb3_init_controller(struct renesas_usb3 *usb3) +{ + usb3_init_axi_bridge(usb3); + usb3_init_epc_registers(usb3); + + usb3_check_vbus(usb3); +} + +static void renesas_usb3_stop_controller(struct renesas_usb3 *usb3) +{ + usb3_disconnect(usb3); + usb3_write(usb3, 0, USB3_P0_INT_ENA); + usb3_write(usb3, 0, USB3_PN_INT_ENA); + usb3_write(usb3, 0, USB3_USB_INT_ENA_1); + usb3_write(usb3, 0, USB3_USB_INT_ENA_2); + usb3_write(usb3, 0, USB3_AXI_INT_ENA); +} + +static void usb3_irq_epc_int_1_pll_wakeup(struct renesas_usb3 *usb3) +{ + usb3_disable_irq_1(usb3, USB_INT_1_B3_PLLWKUP); + usb3_clear_bit(usb3, USB30_CON_B3_PLLWAKE, USB3_USB30_CON); + usb3_start_usb3_connection(usb3); +} + +static void usb3_irq_epc_int_1_linkup_success(struct renesas_usb3 *usb3) +{ + usb3_transition_to_default_state(usb3, true); +} + +static void usb3_irq_epc_int_1_resume(struct renesas_usb3 *usb3) +{ + usb3_disable_irq_1(usb3, USB_INT_1_B2_RSUM); + usb3_start_usb2_connection(usb3); + usb3_transition_to_default_state(usb3, false); +} + +static void usb3_irq_epc_int_1_disable(struct renesas_usb3 *usb3) +{ + usb3_stop_usb3_connection(usb3); + if (usb3_wakeup_usb2_phy(usb3)) + usb3_irq_epc_int_1_resume(usb3); +} + +static void usb3_irq_epc_int_1_bus_reset(struct renesas_usb3 *usb3) +{ + usb3_reset_epc(usb3); + if (usb3->disabled_count < 3) + usb3_start_usb3_connection(usb3); + else + usb3_start_usb2_connection(usb3); +} + +static void usb3_irq_epc_int_1_vbus_change(struct renesas_usb3 *usb3) +{ + usb3_check_vbus(usb3); +} + +static void usb3_irq_epc_int_1_hot_reset(struct renesas_usb3 *usb3) +{ + usb3_reset_epc(usb3); + usb3_set_bit(usb3, USB_COM_CON_EP0_EN, USB3_USB_COM_CON); + + /* This bit shall be set within 12ms from the start of HotReset */ + usb3_set_bit(usb3, USB30_CON_B3_HOTRST_CMP, USB3_USB30_CON); +} + +static void usb3_irq_epc_int_1_warm_reset(struct renesas_usb3 *usb3) +{ + usb3_reset_epc(usb3); + usb3_set_bit(usb3, USB_COM_CON_EP0_EN, USB3_USB_COM_CON); + + usb3_start_operation_for_usb3(usb3); + usb3_enable_irq_1(usb3, USB_INT_1_SPEED); +} + +static void usb3_irq_epc_int_1_speed(struct renesas_usb3 *usb3) +{ + u32 speed = usb3_read(usb3, USB3_USB_STA) & USB_STA_SPEED_MASK; + + switch (speed) { + case USB_STA_SPEED_SS: + usb3->gadget.speed = USB_SPEED_SUPER; + break; + case USB_STA_SPEED_HS: + usb3->gadget.speed = USB_SPEED_HIGH; + break; + case USB_STA_SPEED_FS: + usb3->gadget.speed = USB_SPEED_FULL; + break; + default: + usb3->gadget.speed = USB_SPEED_UNKNOWN; + break; + } +} + +static void usb3_irq_epc_int_1(struct renesas_usb3 *usb3, u32 int_sta_1) +{ + if (int_sta_1 & USB_INT_1_B3_PLLWKUP) + usb3_irq_epc_int_1_pll_wakeup(usb3); + + if (int_sta_1 & USB_INT_1_B3_LUPSUCS) + usb3_irq_epc_int_1_linkup_success(usb3); + + if (int_sta_1 & USB_INT_1_B3_HOTRST) + usb3_irq_epc_int_1_hot_reset(usb3); + + if (int_sta_1 & USB_INT_1_B3_WRMRST) + usb3_irq_epc_int_1_warm_reset(usb3); + + if (int_sta_1 & USB_INT_1_B3_DISABLE) + usb3_irq_epc_int_1_disable(usb3); + + if (int_sta_1 & USB_INT_1_B2_USBRST) + usb3_irq_epc_int_1_bus_reset(usb3); + + if (int_sta_1 & USB_INT_1_B2_RSUM) + usb3_irq_epc_int_1_resume(usb3); + + if (int_sta_1 & USB_INT_1_SPEED) + usb3_irq_epc_int_1_speed(usb3); + + if (int_sta_1 & USB_INT_1_VBUS_CNG) + usb3_irq_epc_int_1_vbus_change(usb3); +} + +static struct renesas_usb3_request *__usb3_get_request(struct renesas_usb3_ep + *usb3_ep) +{ + return list_first_entry_or_null(&usb3_ep->queue, + struct renesas_usb3_request, queue); +} + +static struct renesas_usb3_request *usb3_get_request(struct renesas_usb3_ep + *usb3_ep) +{ + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + struct renesas_usb3_request *usb3_req; + unsigned long flags; + + spin_lock_irqsave(&usb3->lock, flags); + usb3_req = __usb3_get_request(usb3_ep); + spin_unlock_irqrestore(&usb3->lock, flags); + + return usb3_req; +} + +static void usb3_request_done(struct renesas_usb3_ep *usb3_ep, + struct renesas_usb3_request *usb3_req, int status) +{ + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + unsigned long flags; + + dev_dbg(usb3_to_dev(usb3), "giveback: ep%2d, %u, %u, %d\n", + usb3_ep->num, usb3_req->req.length, usb3_req->req.actual, + status); + usb3_req->req.status = status; + spin_lock_irqsave(&usb3->lock, flags); + usb3_ep->started = false; + list_del_init(&usb3_req->queue); + spin_unlock_irqrestore(&usb3->lock, flags); + usb_gadget_giveback_request(&usb3_ep->ep, &usb3_req->req); +} + +static void usb3_irq_epc_pipe0_status_end(struct renesas_usb3 *usb3) +{ + struct renesas_usb3_ep *usb3_ep = usb3_get_ep(usb3, 0); + struct renesas_usb3_request *usb3_req = usb3_get_request(usb3_ep); + + if (usb3_req) + usb3_request_done(usb3_ep, usb3_req, 0); + if (usb3->test_mode) + usb3_set_test_mode(usb3); +} + +static void usb3_get_setup_data(struct renesas_usb3 *usb3, + struct usb_ctrlrequest *ctrl) +{ + struct renesas_usb3_ep *usb3_ep = usb3_get_ep(usb3, 0); + u32 *data = (u32 *)ctrl; + + *data++ = usb3_read(usb3, USB3_STUP_DAT_0); + *data = usb3_read(usb3, USB3_STUP_DAT_1); + + /* update this driver's flag */ + usb3_ep->dir_in = !!(ctrl->bRequestType & USB_DIR_IN); +} + +static void usb3_set_p0_con_update_res(struct renesas_usb3 *usb3, u32 res) +{ + u32 val = usb3_read(usb3, USB3_P0_CON); + + val &= ~(P0_CON_ST_RES_MASK | P0_CON_OT_RES_MASK | P0_CON_IN_RES_MASK); + val |= res | P0_CON_RES_WEN; + usb3_write(usb3, val, USB3_P0_CON); +} + +static void usb3_set_p0_con_for_ctrl_read_data(struct renesas_usb3 *usb3) +{ + usb3_set_p0_con_update_res(usb3, P0_CON_ST_RES_FORCE_NRDY | + P0_CON_OT_RES_FORCE_STALL | + P0_CON_IN_RES_NORMAL); +} + +static void usb3_set_p0_con_for_ctrl_read_status(struct renesas_usb3 *usb3) +{ + usb3_set_p0_con_update_res(usb3, P0_CON_ST_RES_NORMAL | + P0_CON_OT_RES_FORCE_STALL | + P0_CON_IN_RES_NORMAL); +} + +static void usb3_set_p0_con_for_ctrl_write_data(struct renesas_usb3 *usb3) +{ + usb3_set_p0_con_update_res(usb3, P0_CON_ST_RES_FORCE_NRDY | + P0_CON_OT_RES_NORMAL | + P0_CON_IN_RES_FORCE_STALL); +} + +static void usb3_set_p0_con_for_ctrl_write_status(struct renesas_usb3 *usb3) +{ + usb3_set_p0_con_update_res(usb3, P0_CON_ST_RES_NORMAL | + P0_CON_OT_RES_NORMAL | + P0_CON_IN_RES_FORCE_STALL); +} + +static void usb3_set_p0_con_for_no_data(struct renesas_usb3 *usb3) +{ + usb3_set_p0_con_update_res(usb3, P0_CON_ST_RES_NORMAL | + P0_CON_OT_RES_FORCE_STALL | + P0_CON_IN_RES_FORCE_STALL); +} + +static void usb3_set_p0_con_stall(struct renesas_usb3 *usb3) +{ + usb3_set_p0_con_update_res(usb3, P0_CON_ST_RES_FORCE_STALL | + P0_CON_OT_RES_FORCE_STALL | + P0_CON_IN_RES_FORCE_STALL); +} + +static void usb3_set_p0_con_stop(struct renesas_usb3 *usb3) +{ + usb3_set_p0_con_update_res(usb3, P0_CON_ST_RES_FORCE_NRDY | + P0_CON_OT_RES_FORCE_NRDY | + P0_CON_IN_RES_FORCE_NRDY); +} + +static int usb3_pn_change(struct renesas_usb3 *usb3, int num) +{ + if (num == 0 || num > usb3->num_usb3_eps) + return -ENXIO; + + usb3_write(usb3, num, USB3_PIPE_COM); + + return 0; +} + +static void usb3_set_pn_con_update_res(struct renesas_usb3 *usb3, u32 res) +{ + u32 val = usb3_read(usb3, USB3_PN_CON); + + val &= ~PN_CON_RES_MASK; + val |= res & PN_CON_RES_MASK; + val |= PN_CON_RES_WEN; + usb3_write(usb3, val, USB3_PN_CON); +} + +static void usb3_pn_start(struct renesas_usb3 *usb3) +{ + usb3_set_pn_con_update_res(usb3, PN_CON_RES_NORMAL); +} + +static void usb3_pn_stop(struct renesas_usb3 *usb3) +{ + usb3_set_pn_con_update_res(usb3, PN_CON_RES_FORCE_NRDY); +} + +static void usb3_pn_stall(struct renesas_usb3 *usb3) +{ + usb3_set_pn_con_update_res(usb3, PN_CON_RES_FORCE_STALL); +} + +static int usb3_pn_con_clear(struct renesas_usb3 *usb3) +{ + usb3_set_bit(usb3, PN_CON_CLR, USB3_PN_CON); + + return usb3_wait(usb3, USB3_PN_CON, PN_CON_CLR, 0); +} + +static bool usb3_is_transfer_complete(struct renesas_usb3_ep *usb3_ep, + struct renesas_usb3_request *usb3_req) +{ + struct usb_request *req = &usb3_req->req; + + if ((!req->zero && req->actual == req->length) || + (req->actual % usb3_ep->ep.maxpacket) || (req->length == 0)) + return true; + else + return false; +} + +static int usb3_wait_pipe_status(struct renesas_usb3_ep *usb3_ep, u32 mask) +{ + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + u32 sta_reg = usb3_ep->num ? USB3_PN_STA : USB3_P0_STA; + + return usb3_wait(usb3, sta_reg, mask, mask); +} + +static void usb3_set_px_con_send(struct renesas_usb3_ep *usb3_ep, int bytes, + bool last) +{ + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + u32 con_reg = usb3_ep->num ? USB3_PN_CON : USB3_P0_CON; + u32 val = usb3_read(usb3, con_reg); + + val |= PX_CON_SEND | PX_CON_BYTE_EN_BYTES(bytes); + val |= (usb3_ep->num && last) ? PN_CON_LAST : 0; + usb3_write(usb3, val, con_reg); +} + +static int usb3_write_pipe(struct renesas_usb3_ep *usb3_ep, + struct renesas_usb3_request *usb3_req, + u32 fifo_reg) +{ + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + int i; + int len = min_t(unsigned, usb3_req->req.length - usb3_req->req.actual, + usb3_ep->ep.maxpacket); + u8 *buf = usb3_req->req.buf + usb3_req->req.actual; + u32 tmp = 0; + bool is_last; + + if (usb3_wait_pipe_status(usb3_ep, PX_STA_BUFSTS) < 0) + return -EBUSY; + + /* Update gadget driver parameter */ + usb3_req->req.actual += len; + + /* Write data to the register */ + if (len >= 4) { + iowrite32_rep(usb3->reg + fifo_reg, buf, len / 4); + buf += (len / 4) * 4; + len %= 4; /* update len to use usb3_set_pX_con_send() */ + } + + if (len) { + for (i = 0; i < len; i++) + tmp |= buf[i] << (8 * i); + usb3_write(usb3, tmp, fifo_reg); + } + + is_last = usb3_is_transfer_complete(usb3_ep, usb3_req); + /* Send the data */ + usb3_set_px_con_send(usb3_ep, len, is_last); + + return is_last ? 0 : -EAGAIN; +} + +static u32 usb3_get_received_length(struct renesas_usb3_ep *usb3_ep) +{ + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + u32 lng_reg = usb3_ep->num ? USB3_PN_LNG : USB3_P0_LNG; + + return usb3_read(usb3, lng_reg); +} + +static int usb3_read_pipe(struct renesas_usb3_ep *usb3_ep, + struct renesas_usb3_request *usb3_req, u32 fifo_reg) +{ + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + int i; + int len = min_t(unsigned, usb3_req->req.length - usb3_req->req.actual, + usb3_get_received_length(usb3_ep)); + u8 *buf = usb3_req->req.buf + usb3_req->req.actual; + u32 tmp = 0; + + if (!len) + return 0; + + /* Update gadget driver parameter */ + usb3_req->req.actual += len; + + /* Read data from the register */ + if (len >= 4) { + ioread32_rep(usb3->reg + fifo_reg, buf, len / 4); + buf += (len / 4) * 4; + len %= 4; + } + + if (len) { + tmp = usb3_read(usb3, fifo_reg); + for (i = 0; i < len; i++) + buf[i] = (tmp >> (8 * i)) & 0xff; + } + + return usb3_is_transfer_complete(usb3_ep, usb3_req) ? 0 : -EAGAIN; +} + +static void usb3_set_status_stage(struct renesas_usb3_ep *usb3_ep, + struct renesas_usb3_request *usb3_req) +{ + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + + if (usb3_ep->dir_in) { + usb3_set_p0_con_for_ctrl_read_status(usb3); + } else { + if (!usb3_req->req.length) + usb3_set_p0_con_for_no_data(usb3); + else + usb3_set_p0_con_for_ctrl_write_status(usb3); + } +} + +static void usb3_p0_xfer(struct renesas_usb3_ep *usb3_ep, + struct renesas_usb3_request *usb3_req) +{ + int ret = -EAGAIN; + + if (usb3_ep->dir_in) + ret = usb3_write_pipe(usb3_ep, usb3_req, USB3_P0_WRITE); + else + ret = usb3_read_pipe(usb3_ep, usb3_req, USB3_P0_READ); + + if (!ret) + usb3_set_status_stage(usb3_ep, usb3_req); +} + +static void usb3_start_pipe0(struct renesas_usb3_ep *usb3_ep, + struct renesas_usb3_request *usb3_req) +{ + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + + if (usb3_ep->started) + return; + + usb3_ep->started = true; + + if (usb3_ep->dir_in) { + usb3_set_bit(usb3, P0_MOD_DIR, USB3_P0_MOD); + usb3_set_p0_con_for_ctrl_read_data(usb3); + } else { + usb3_clear_bit(usb3, P0_MOD_DIR, USB3_P0_MOD); + usb3_set_p0_con_for_ctrl_write_data(usb3); + } + + usb3_p0_xfer(usb3_ep, usb3_req); +} + +static void usb3_start_pipen(struct renesas_usb3_ep *usb3_ep, + struct renesas_usb3_request *usb3_req) +{ + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + struct renesas_usb3_request *usb3_req_first = usb3_get_request(usb3_ep); + unsigned long flags; + int ret = -EAGAIN; + u32 enable_bits = 0; + + if (usb3_ep->halt || usb3_ep->started) + return; + if (usb3_req != usb3_req_first) + return; + + spin_lock_irqsave(&usb3->lock, flags); + if (usb3_pn_change(usb3, usb3_ep->num) < 0) + goto out; + + usb3_ep->started = true; + usb3_pn_start(usb3); + + if (usb3_ep->dir_in) { + ret = usb3_write_pipe(usb3_ep, usb3_req, USB3_PN_WRITE); + enable_bits |= PN_INT_LSTTR; + } + + if (ret < 0) + enable_bits |= PN_INT_BFRDY; + + if (enable_bits) { + usb3_set_bit(usb3, enable_bits, USB3_PN_INT_ENA); + usb3_enable_pipe_irq(usb3, usb3_ep->num); + } +out: + spin_unlock_irqrestore(&usb3->lock, flags); +} + +static int renesas_usb3_ep_queue(struct usb_ep *_ep, struct usb_request *_req, + gfp_t gfp_flags) +{ + struct renesas_usb3_ep *usb3_ep = usb_ep_to_usb3_ep(_ep); + struct renesas_usb3_request *usb3_req = usb_req_to_usb3_req(_req); + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + unsigned long flags; + + dev_dbg(usb3_to_dev(usb3), "ep_queue: ep%2d, %u\n", usb3_ep->num, + _req->length); + + _req->status = -EINPROGRESS; + _req->actual = 0; + spin_lock_irqsave(&usb3->lock, flags); + list_add_tail(&usb3_req->queue, &usb3_ep->queue); + spin_unlock_irqrestore(&usb3->lock, flags); + + if (!usb3_ep->num) + usb3_start_pipe0(usb3_ep, usb3_req); + else + usb3_start_pipen(usb3_ep, usb3_req); + + return 0; +} + +static void usb3_set_device_address(struct renesas_usb3 *usb3, u16 addr) +{ + /* DEV_ADDR bit field is cleared by WarmReset, HotReset and BusReset */ + usb3_set_bit(usb3, USB_COM_CON_DEV_ADDR(addr), USB3_USB_COM_CON); +} + +static bool usb3_std_req_set_address(struct renesas_usb3 *usb3, + struct usb_ctrlrequest *ctrl) +{ + if (ctrl->wValue >= 128) + return true; /* stall */ + + usb3_set_device_address(usb3, ctrl->wValue); + usb3_set_p0_con_for_no_data(usb3); + + return false; +} + +static void usb3_pipe0_internal_xfer(struct renesas_usb3 *usb3, + void *tx_data, size_t len, + void (*complete)(struct usb_ep *ep, + struct usb_request *req)) +{ + struct renesas_usb3_ep *usb3_ep = usb3_get_ep(usb3, 0); + + if (tx_data) + memcpy(usb3->ep0_buf, tx_data, + min_t(size_t, len, USB3_EP0_BUF_SIZE)); + + usb3->ep0_req->buf = &usb3->ep0_buf; + usb3->ep0_req->length = len; + usb3->ep0_req->complete = complete; + renesas_usb3_ep_queue(&usb3_ep->ep, usb3->ep0_req, GFP_ATOMIC); +} + +static void usb3_pipe0_get_status_completion(struct usb_ep *ep, + struct usb_request *req) +{ +} + +static bool usb3_std_req_get_status(struct renesas_usb3 *usb3, + struct usb_ctrlrequest *ctrl) +{ + bool stall = false; + struct renesas_usb3_ep *usb3_ep; + int num; + u16 status = 0; + + switch (ctrl->bRequestType & USB_RECIP_MASK) { + case USB_RECIP_DEVICE: + if (usb3->gadget.is_selfpowered) + status |= 1 << USB_DEVICE_SELF_POWERED; + if (usb3->gadget.speed == USB_SPEED_SUPER) + status |= usb3_feature_get_un_enabled(usb3); + break; + case USB_RECIP_INTERFACE: + break; + case USB_RECIP_ENDPOINT: + num = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK; + usb3_ep = usb3_get_ep(usb3, num); + if (usb3_ep->halt) + status |= 1 << USB_ENDPOINT_HALT; + break; + default: + stall = true; + break; + } + + if (!stall) { + status = cpu_to_le16(status); + dev_dbg(usb3_to_dev(usb3), "get_status: req = %p\n", + usb_req_to_usb3_req(usb3->ep0_req)); + usb3_pipe0_internal_xfer(usb3, &status, sizeof(status), + usb3_pipe0_get_status_completion); + } + + return stall; +} + +static bool usb3_std_req_feature_device(struct renesas_usb3 *usb3, + struct usb_ctrlrequest *ctrl, bool set) +{ + bool stall = true; + u16 w_value = le16_to_cpu(ctrl->wValue); + + switch (w_value) { + case USB_DEVICE_TEST_MODE: + if (!set) + break; + usb3->test_mode = le16_to_cpu(ctrl->wIndex) >> 8; + stall = false; + break; + case USB_DEVICE_U1_ENABLE: + case USB_DEVICE_U2_ENABLE: + if (usb3->gadget.speed != USB_SPEED_SUPER) + break; + if (w_value == USB_DEVICE_U1_ENABLE) + usb3_feature_u1_enable(usb3, set); + if (w_value == USB_DEVICE_U2_ENABLE) + usb3_feature_u2_enable(usb3, set); + stall = false; + break; + default: + break; + } + + return stall; +} + +static int usb3_set_halt_p0(struct renesas_usb3_ep *usb3_ep, bool halt) +{ + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + + if (unlikely(usb3_ep->num)) + return -EINVAL; + + usb3_ep->halt = halt; + if (halt) + usb3_set_p0_con_stall(usb3); + else + usb3_set_p0_con_stop(usb3); + + return 0; +} + +static int usb3_set_halt_pn(struct renesas_usb3_ep *usb3_ep, bool halt, + bool is_clear_feature) +{ + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + unsigned long flags; + + spin_lock_irqsave(&usb3->lock, flags); + if (!usb3_pn_change(usb3, usb3_ep->num)) { + usb3_ep->halt = halt; + if (halt) { + usb3_pn_stall(usb3); + } else if (!is_clear_feature || !usb3_ep->wedge) { + usb3_pn_con_clear(usb3); + usb3_set_bit(usb3, PN_CON_EN, USB3_PN_CON); + usb3_pn_stop(usb3); + } + } + spin_unlock_irqrestore(&usb3->lock, flags); + + return 0; +} + +static int usb3_set_halt(struct renesas_usb3_ep *usb3_ep, bool halt, + bool is_clear_feature) +{ + int ret = 0; + + if (halt && usb3_ep->started) + return -EAGAIN; + + if (usb3_ep->num) + ret = usb3_set_halt_pn(usb3_ep, halt, is_clear_feature); + else + ret = usb3_set_halt_p0(usb3_ep, halt); + + return ret; +} + +static bool usb3_std_req_feature_endpoint(struct renesas_usb3 *usb3, + struct usb_ctrlrequest *ctrl, + bool set) +{ + int num = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK; + struct renesas_usb3_ep *usb3_ep; + struct renesas_usb3_request *usb3_req; + + if (le16_to_cpu(ctrl->wValue) != USB_ENDPOINT_HALT) + return true; /* stall */ + + usb3_ep = usb3_get_ep(usb3, num); + usb3_set_halt(usb3_ep, set, true); + + /* Restarts a queue if clear feature */ + if (!set) { + usb3_ep->started = false; + usb3_req = usb3_get_request(usb3_ep); + if (usb3_req) + usb3_start_pipen(usb3_ep, usb3_req); + } + + return false; +} + +static bool usb3_std_req_feature(struct renesas_usb3 *usb3, + struct usb_ctrlrequest *ctrl, bool set) +{ + bool stall = false; + + switch (ctrl->bRequestType & USB_RECIP_MASK) { + case USB_RECIP_DEVICE: + stall = usb3_std_req_feature_device(usb3, ctrl, set); + break; + case USB_RECIP_INTERFACE: + break; + case USB_RECIP_ENDPOINT: + stall = usb3_std_req_feature_endpoint(usb3, ctrl, set); + break; + default: + stall = true; + break; + } + + if (!stall) + usb3_set_p0_con_for_no_data(usb3); + + return stall; +} + +static void usb3_pipe0_set_sel_completion(struct usb_ep *ep, + struct usb_request *req) +{ + /* TODO */ +} + +static bool usb3_std_req_set_sel(struct renesas_usb3 *usb3, + struct usb_ctrlrequest *ctrl) +{ + u16 w_length = le16_to_cpu(ctrl->wLength); + + if (w_length != 6) + return true; /* stall */ + + dev_dbg(usb3_to_dev(usb3), "set_sel: req = %p\n", + usb_req_to_usb3_req(usb3->ep0_req)); + usb3_pipe0_internal_xfer(usb3, NULL, 6, usb3_pipe0_set_sel_completion); + + return false; +} + +static bool usb3_std_req_set_configuration(struct renesas_usb3 *usb3, + struct usb_ctrlrequest *ctrl) +{ + if (ctrl->wValue > 0) + usb3_set_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON); + else + usb3_clear_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON); + + return false; +} + +/** + * usb3_handle_standard_request - handle some standard requests + * @usb3: the renesas_usb3 pointer + * @ctrl: a pointer of setup data + * + * Returns true if this function handled a standard request + */ +static bool usb3_handle_standard_request(struct renesas_usb3 *usb3, + struct usb_ctrlrequest *ctrl) +{ + bool ret = false; + bool stall = false; + + if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { + switch (ctrl->bRequest) { + case USB_REQ_SET_ADDRESS: + stall = usb3_std_req_set_address(usb3, ctrl); + ret = true; + break; + case USB_REQ_GET_STATUS: + stall = usb3_std_req_get_status(usb3, ctrl); + ret = true; + break; + case USB_REQ_CLEAR_FEATURE: + stall = usb3_std_req_feature(usb3, ctrl, false); + ret = true; + break; + case USB_REQ_SET_FEATURE: + stall = usb3_std_req_feature(usb3, ctrl, true); + ret = true; + break; + case USB_REQ_SET_SEL: + stall = usb3_std_req_set_sel(usb3, ctrl); + ret = true; + break; + case USB_REQ_SET_ISOCH_DELAY: + /* This hardware doesn't support Isochronous xfer */ + stall = true; + ret = true; + break; + case USB_REQ_SET_CONFIGURATION: + usb3_std_req_set_configuration(usb3, ctrl); + break; + default: + break; + } + } + + if (stall) + usb3_set_p0_con_stall(usb3); + + return ret; +} + +static int usb3_p0_con_clear_buffer(struct renesas_usb3 *usb3) +{ + usb3_set_bit(usb3, P0_CON_BCLR, USB3_P0_CON); + + return usb3_wait(usb3, USB3_P0_CON, P0_CON_BCLR, 0); +} + +static void usb3_irq_epc_pipe0_setup(struct renesas_usb3 *usb3) +{ + struct usb_ctrlrequest ctrl; + struct renesas_usb3_ep *usb3_ep = usb3_get_ep(usb3, 0); + + /* Call giveback function if previous transfer is not completed */ + if (usb3_ep->started) + usb3_request_done(usb3_ep, usb3_get_request(usb3_ep), + -ECONNRESET); + + usb3_p0_con_clear_buffer(usb3); + usb3_get_setup_data(usb3, &ctrl); + if (!usb3_handle_standard_request(usb3, &ctrl)) + if (usb3->driver->setup(&usb3->gadget, &ctrl) < 0) + usb3_set_p0_con_stall(usb3); +} + +static void usb3_irq_epc_pipe0_bfrdy(struct renesas_usb3 *usb3) +{ + struct renesas_usb3_ep *usb3_ep = usb3_get_ep(usb3, 0); + struct renesas_usb3_request *usb3_req = usb3_get_request(usb3_ep); + + if (!usb3_req) + return; + + usb3_p0_xfer(usb3_ep, usb3_req); +} + +static void usb3_irq_epc_pipe0(struct renesas_usb3 *usb3) +{ + u32 p0_int_sta = usb3_read(usb3, USB3_P0_INT_STA); + + p0_int_sta &= usb3_read(usb3, USB3_P0_INT_ENA); + usb3_write(usb3, p0_int_sta, USB3_P0_INT_STA); + if (p0_int_sta & P0_INT_STSED) + usb3_irq_epc_pipe0_status_end(usb3); + if (p0_int_sta & P0_INT_SETUP) + usb3_irq_epc_pipe0_setup(usb3); + if (p0_int_sta & P0_INT_BFRDY) + usb3_irq_epc_pipe0_bfrdy(usb3); +} + +static void usb3_request_done_pipen(struct renesas_usb3 *usb3, + struct renesas_usb3_ep *usb3_ep, + struct renesas_usb3_request *usb3_req, + int status) +{ + usb3_pn_stop(usb3); + usb3_disable_pipe_irq(usb3, usb3_ep->num); + usb3_request_done(usb3_ep, usb3_req, status); + + /* get next usb3_req */ + usb3_req = usb3_get_request(usb3_ep); + if (usb3_req) + usb3_start_pipen(usb3_ep, usb3_req); +} + +static void usb3_irq_epc_pipen_lsttr(struct renesas_usb3 *usb3, int num) +{ + struct renesas_usb3_ep *usb3_ep = usb3_get_ep(usb3, num); + struct renesas_usb3_request *usb3_req = usb3_get_request(usb3_ep); + + if (!usb3_req) + return; + + if (usb3_ep->dir_in) { + dev_dbg(usb3_to_dev(usb3), "%s: len = %u, actual = %u\n", + __func__, usb3_req->req.length, usb3_req->req.actual); + usb3_request_done_pipen(usb3, usb3_ep, usb3_req, 0); + } +} + +static void usb3_irq_epc_pipen_bfrdy(struct renesas_usb3 *usb3, int num) +{ + struct renesas_usb3_ep *usb3_ep = usb3_get_ep(usb3, num); + struct renesas_usb3_request *usb3_req = usb3_get_request(usb3_ep); + + if (!usb3_req) + return; + + if (usb3_ep->dir_in) { + /* Do not stop the IN pipe here to detect LSTTR interrupt */ + if (!usb3_write_pipe(usb3_ep, usb3_req, USB3_PN_WRITE)) + usb3_clear_bit(usb3, PN_INT_BFRDY, USB3_PN_INT_ENA); + } else { + if (!usb3_read_pipe(usb3_ep, usb3_req, USB3_PN_READ)) + usb3_request_done_pipen(usb3, usb3_ep, usb3_req, 0); + } +} + +static void usb3_irq_epc_pipen(struct renesas_usb3 *usb3, int num) +{ + u32 pn_int_sta; + + if (usb3_pn_change(usb3, num) < 0) + return; + + pn_int_sta = usb3_read(usb3, USB3_PN_INT_STA); + pn_int_sta &= usb3_read(usb3, USB3_PN_INT_ENA); + usb3_write(usb3, pn_int_sta, USB3_PN_INT_STA); + if (pn_int_sta & PN_INT_LSTTR) + usb3_irq_epc_pipen_lsttr(usb3, num); + if (pn_int_sta & PN_INT_BFRDY) + usb3_irq_epc_pipen_bfrdy(usb3, num); +} + +static void usb3_irq_epc_int_2(struct renesas_usb3 *usb3, u32 int_sta_2) +{ + int i; + + for (i = 0; i < usb3->num_usb3_eps; i++) { + if (int_sta_2 & USB_INT_2_PIPE(i)) { + if (!i) + usb3_irq_epc_pipe0(usb3); + else + usb3_irq_epc_pipen(usb3, i); + } + } +} + +static void usb3_irq_epc(struct renesas_usb3 *usb3) +{ + u32 int_sta_1 = usb3_read(usb3, USB3_USB_INT_STA_1); + u32 int_sta_2 = usb3_read(usb3, USB3_USB_INT_STA_2); + + int_sta_1 &= usb3_read(usb3, USB3_USB_INT_ENA_1); + if (int_sta_1) { + usb3_write(usb3, int_sta_1, USB3_USB_INT_STA_1); + usb3_irq_epc_int_1(usb3, int_sta_1); + } + + int_sta_2 &= usb3_read(usb3, USB3_USB_INT_ENA_2); + if (int_sta_2) + usb3_irq_epc_int_2(usb3, int_sta_2); +} + +static irqreturn_t renesas_usb3_irq(int irq, void *_usb3) +{ + struct renesas_usb3 *usb3 = _usb3; + irqreturn_t ret = IRQ_NONE; + u32 axi_int_sta = usb3_read(usb3, USB3_AXI_INT_STA); + + if (axi_int_sta & AXI_INT_EPCINT) { + usb3_irq_epc(usb3); + ret = IRQ_HANDLED; + } + + return ret; +} + +static void usb3_write_pn_mod(struct renesas_usb3_ep *usb3_ep, + const struct usb_endpoint_descriptor *desc) +{ + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + u32 val = 0; + + val |= usb3_ep->dir_in ? PN_MOD_DIR : 0; + val |= PN_MOD_TYPE(usb_endpoint_type(desc)); + val |= PN_MOD_EPNUM(usb_endpoint_num(desc)); + usb3_write(usb3, val, USB3_PN_MOD); +} + +static u32 usb3_calc_ramarea(int ram_size) +{ + WARN_ON(ram_size > SZ_16K); + + if (ram_size <= SZ_1K) + return PN_RAMMAP_RAMAREA_1KB; + else if (ram_size <= SZ_2K) + return PN_RAMMAP_RAMAREA_2KB; + else if (ram_size <= SZ_4K) + return PN_RAMMAP_RAMAREA_4KB; + else if (ram_size <= SZ_8K) + return PN_RAMMAP_RAMAREA_8KB; + else + return PN_RAMMAP_RAMAREA_16KB; +} + +static u32 usb3_calc_rammap_val(struct renesas_usb3_ep *usb3_ep, + const struct usb_endpoint_descriptor *desc) +{ + return usb3_ep->rammap_val | PN_RAMMAP_MPKT(usb_endpoint_maxp(desc)); +} + +static int usb3_enable_pipe_n(struct renesas_usb3_ep *usb3_ep, + const struct usb_endpoint_descriptor *desc) +{ + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + unsigned long flags; + + usb3_ep->dir_in = usb_endpoint_dir_in(desc); + + spin_lock_irqsave(&usb3->lock, flags); + if (!usb3_pn_change(usb3, usb3_ep->num)) { + usb3_write_pn_mod(usb3_ep, desc); + usb3_write(usb3, usb3_calc_rammap_val(usb3_ep, desc), + USB3_PN_RAMMAP); + usb3_pn_con_clear(usb3); + usb3_set_bit(usb3, PN_CON_EN, USB3_PN_CON); + } + spin_unlock_irqrestore(&usb3->lock, flags); + + return 0; +} + +static int usb3_disable_pipe_n(struct renesas_usb3_ep *usb3_ep) +{ + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + unsigned long flags; + + usb3_ep->halt = false; + + spin_lock_irqsave(&usb3->lock, flags); + if (!usb3_pn_change(usb3, usb3_ep->num)) { + usb3_write(usb3, 0, USB3_PN_RAMMAP); + usb3_clear_bit(usb3, PN_CON_EN, USB3_PN_CON); + } + spin_unlock_irqrestore(&usb3->lock, flags); + + return 0; +} + +/*------- usb_ep_ops -----------------------------------------------------*/ +static int renesas_usb3_ep_enable(struct usb_ep *_ep, + const struct usb_endpoint_descriptor *desc) +{ + struct renesas_usb3_ep *usb3_ep = usb_ep_to_usb3_ep(_ep); + + return usb3_enable_pipe_n(usb3_ep, desc); +} + +static int renesas_usb3_ep_disable(struct usb_ep *_ep) +{ + struct renesas_usb3_ep *usb3_ep = usb_ep_to_usb3_ep(_ep); + struct renesas_usb3_request *usb3_req; + + do { + usb3_req = usb3_get_request(usb3_ep); + if (!usb3_req) + break; + usb3_request_done(usb3_ep, usb3_req, -ESHUTDOWN); + } while (1); + + return usb3_disable_pipe_n(usb3_ep); +} + +static struct usb_request *__renesas_usb3_ep_alloc_request(gfp_t gfp_flags) +{ + struct renesas_usb3_request *usb3_req; + + usb3_req = kzalloc(sizeof(struct renesas_usb3_request), gfp_flags); + if (!usb3_req) + return NULL; + + INIT_LIST_HEAD(&usb3_req->queue); + + return &usb3_req->req; +} + +static void __renesas_usb3_ep_free_request(struct usb_request *_req) +{ + struct renesas_usb3_request *usb3_req = usb_req_to_usb3_req(_req); + + kfree(usb3_req); +} + +static struct usb_request *renesas_usb3_ep_alloc_request(struct usb_ep *_ep, + gfp_t gfp_flags) +{ + return __renesas_usb3_ep_alloc_request(gfp_flags); +} + +static void renesas_usb3_ep_free_request(struct usb_ep *_ep, + struct usb_request *_req) +{ + __renesas_usb3_ep_free_request(_req); +} + +static int renesas_usb3_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) +{ + struct renesas_usb3_ep *usb3_ep = usb_ep_to_usb3_ep(_ep); + struct renesas_usb3_request *usb3_req = usb_req_to_usb3_req(_req); + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + + dev_dbg(usb3_to_dev(usb3), "ep_dequeue: ep%2d, %u\n", usb3_ep->num, + _req->length); + + usb3_request_done_pipen(usb3, usb3_ep, usb3_req, -ECONNRESET); + + return 0; +} + +static int renesas_usb3_ep_set_halt(struct usb_ep *_ep, int value) +{ + return usb3_set_halt(usb_ep_to_usb3_ep(_ep), !!value, false); +} + +static int renesas_usb3_ep_set_wedge(struct usb_ep *_ep) +{ + struct renesas_usb3_ep *usb3_ep = usb_ep_to_usb3_ep(_ep); + + usb3_ep->wedge = true; + return usb3_set_halt(usb3_ep, true, false); +} + +static void renesas_usb3_ep_fifo_flush(struct usb_ep *_ep) +{ + struct renesas_usb3_ep *usb3_ep = usb_ep_to_usb3_ep(_ep); + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + unsigned long flags; + + if (usb3_ep->num) { + spin_lock_irqsave(&usb3->lock, flags); + if (!usb3_pn_change(usb3, usb3_ep->num)) { + usb3_pn_con_clear(usb3); + usb3_set_bit(usb3, PN_CON_EN, USB3_PN_CON); + } + spin_unlock_irqrestore(&usb3->lock, flags); + } else { + usb3_p0_con_clear_buffer(usb3); + } +} + +static struct usb_ep_ops renesas_usb3_ep_ops = { + .enable = renesas_usb3_ep_enable, + .disable = renesas_usb3_ep_disable, + + .alloc_request = renesas_usb3_ep_alloc_request, + .free_request = renesas_usb3_ep_free_request, + + .queue = renesas_usb3_ep_queue, + .dequeue = renesas_usb3_ep_dequeue, + + .set_halt = renesas_usb3_ep_set_halt, + .set_wedge = renesas_usb3_ep_set_wedge, + .fifo_flush = renesas_usb3_ep_fifo_flush, +}; + +/*------- usb_gadget_ops -------------------------------------------------*/ +static int renesas_usb3_start(struct usb_gadget *gadget, + struct usb_gadget_driver *driver) +{ + struct renesas_usb3 *usb3; + + if (!driver || driver->max_speed < USB_SPEED_FULL || + !driver->setup) + return -EINVAL; + + usb3 = gadget_to_renesas_usb3(gadget); + + /* hook up the driver */ + usb3->driver = driver; + + renesas_usb3_init_controller(usb3); + + return 0; +} + +static int renesas_usb3_stop(struct usb_gadget *gadget) +{ + struct renesas_usb3 *usb3 = gadget_to_renesas_usb3(gadget); + unsigned long flags; + + spin_lock_irqsave(&usb3->lock, flags); + usb3->softconnect = false; + usb3->gadget.speed = USB_SPEED_UNKNOWN; + usb3->driver = NULL; + renesas_usb3_stop_controller(usb3); + spin_unlock_irqrestore(&usb3->lock, flags); + + return 0; +} + +static int renesas_usb3_get_frame(struct usb_gadget *_gadget) +{ + return -EOPNOTSUPP; +} + +static int renesas_usb3_pullup(struct usb_gadget *gadget, int is_on) +{ + struct renesas_usb3 *usb3 = gadget_to_renesas_usb3(gadget); + + usb3->softconnect = !!is_on; + + return 0; +} + +static int renesas_usb3_set_selfpowered(struct usb_gadget *gadget, int is_self) +{ + gadget->is_selfpowered = !!is_self; + + return 0; +} + +static const struct usb_gadget_ops renesas_usb3_gadget_ops = { + .get_frame = renesas_usb3_get_frame, + .udc_start = renesas_usb3_start, + .udc_stop = renesas_usb3_stop, + .pullup = renesas_usb3_pullup, + .set_selfpowered = renesas_usb3_set_selfpowered, +}; + +/*------- platform_driver ------------------------------------------------*/ +static int renesas_usb3_remove(struct platform_device *pdev) +{ + struct renesas_usb3 *usb3 = platform_get_drvdata(pdev); + + pm_runtime_put(&pdev->dev); + pm_runtime_disable(&pdev->dev); + + usb_del_gadget_udc(&usb3->gadget); + + __renesas_usb3_ep_free_request(usb3->ep0_req); + + return 0; +} + +static int renesas_usb3_init_ep(struct renesas_usb3 *usb3, struct device *dev, + const struct renesas_usb3_priv *priv) +{ + struct renesas_usb3_ep *usb3_ep; + int i; + + /* calculate num_usb3_eps from renesas_usb3_priv */ + usb3->num_usb3_eps = priv->ramsize_per_ramif * priv->num_ramif * 2 / + priv->ramsize_per_pipe + 1; + + if (usb3->num_usb3_eps > USB3_MAX_NUM_PIPES) + usb3->num_usb3_eps = USB3_MAX_NUM_PIPES; + + usb3->usb3_ep = devm_kzalloc(dev, sizeof(*usb3_ep) * usb3->num_usb3_eps, + GFP_KERNEL); + if (!usb3->usb3_ep) + return -ENOMEM; + + dev_dbg(dev, "%s: num_usb3_eps = %d\n", __func__, usb3->num_usb3_eps); + /* + * This driver prepares pipes as the followings: + * - odd pipes = IN pipe + * - even pipes = OUT pipe (except pipe 0) + */ + usb3_for_each_ep(usb3_ep, usb3, i) { + snprintf(usb3_ep->ep_name, sizeof(usb3_ep->ep_name), "ep%d", i); + usb3_ep->usb3 = usb3; + usb3_ep->num = i; + usb3_ep->ep.name = usb3_ep->ep_name; + usb3_ep->ep.ops = &renesas_usb3_ep_ops; + INIT_LIST_HEAD(&usb3_ep->queue); + INIT_LIST_HEAD(&usb3_ep->ep.ep_list); + if (!i) { + /* for control pipe */ + usb3->gadget.ep0 = &usb3_ep->ep; + usb_ep_set_maxpacket_limit(&usb3_ep->ep, + USB3_EP0_HSFS_MAX_PACKET_SIZE); + usb3_ep->ep.caps.type_control = true; + usb3_ep->ep.caps.dir_in = true; + usb3_ep->ep.caps.dir_out = true; + continue; + } + + /* for bulk or interrupt pipe */ + usb_ep_set_maxpacket_limit(&usb3_ep->ep, ~0); + list_add_tail(&usb3_ep->ep.ep_list, &usb3->gadget.ep_list); + usb3_ep->ep.caps.type_bulk = true; + usb3_ep->ep.caps.type_int = true; + if (i & 1) + usb3_ep->ep.caps.dir_in = true; + else + usb3_ep->ep.caps.dir_out = true; + } + + return 0; +} + +static void renesas_usb3_init_ram(struct renesas_usb3 *usb3, struct device *dev, + const struct renesas_usb3_priv *priv) +{ + struct renesas_usb3_ep *usb3_ep; + int i; + u32 ramif[2], basead[2]; /* index 0 = for IN pipes */ + u32 *cur_ramif, *cur_basead; + u32 val; + + memset(ramif, 0, sizeof(ramif)); + memset(basead, 0, sizeof(basead)); + + /* + * This driver prepares pipes as the followings: + * - all pipes = the same size as "ramsize_per_pipe" + * Please refer to the "Method of Specifying RAM Mapping" + */ + usb3_for_each_ep(usb3_ep, usb3, i) { + if (!i) + continue; /* out of scope if ep num = 0 */ + if (usb3_ep->ep.caps.dir_in) { + cur_ramif = &ramif[0]; + cur_basead = &basead[0]; + } else { + cur_ramif = &ramif[1]; + cur_basead = &basead[1]; + } + + if (*cur_basead > priv->ramsize_per_ramif) + continue; /* out of memory for IN or OUT pipe */ + + /* calculate rammap_val */ + val = PN_RAMMAP_RAMIF(*cur_ramif); + val |= usb3_calc_ramarea(priv->ramsize_per_pipe); + val |= PN_RAMMAP_BASEAD(*cur_basead); + usb3_ep->rammap_val = val; + + dev_dbg(dev, "ep%2d: val = %08x, ramif = %d, base = %x\n", + i, val, *cur_ramif, *cur_basead); + + /* update current ramif */ + if (*cur_ramif + 1 == priv->num_ramif) { + *cur_ramif = 0; + *cur_basead += priv->ramsize_per_pipe; + } else { + (*cur_ramif)++; + } + } +} + +static const struct renesas_usb3_priv renesas_usb3_priv_r8a7795 = { + .ramsize_per_ramif = SZ_16K, + .num_ramif = 2, + .ramsize_per_pipe = SZ_4K, + .workaround_for_vbus = true, +}; + +static const struct of_device_id usb3_of_match[] = { + { + .compatible = "renesas,r8a7795-usb3-peri", + .data = &renesas_usb3_priv_r8a7795, + }, + { }, +}; +MODULE_DEVICE_TABLE(of, usb3_of_match); + +static int renesas_usb3_probe(struct platform_device *pdev) +{ + struct renesas_usb3 *usb3; + struct resource *res; + const struct of_device_id *match; + int irq, ret; + const struct renesas_usb3_priv *priv; + + match = of_match_node(usb3_of_match, pdev->dev.of_node); + if (!match) + return -ENODEV; + priv = match->data; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return -ENODEV; + + usb3 = devm_kzalloc(&pdev->dev, sizeof(*usb3), GFP_KERNEL); + if (!usb3) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + usb3->reg = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(usb3->reg)) + return PTR_ERR(usb3->reg); + + platform_set_drvdata(pdev, usb3); + spin_lock_init(&usb3->lock); + + usb3->gadget.ops = &renesas_usb3_gadget_ops; + usb3->gadget.name = udc_name; + usb3->gadget.max_speed = USB_SPEED_SUPER; + INIT_LIST_HEAD(&usb3->gadget.ep_list); + ret = renesas_usb3_init_ep(usb3, &pdev->dev, priv); + if (ret < 0) + return ret; + renesas_usb3_init_ram(usb3, &pdev->dev, priv); + + ret = devm_request_irq(&pdev->dev, irq, renesas_usb3_irq, 0, + dev_name(&pdev->dev), usb3); + if (ret < 0) + return ret; + + /* for ep0 handling */ + usb3->ep0_req = __renesas_usb3_ep_alloc_request(GFP_KERNEL); + if (!usb3->ep0_req) + return -ENOMEM; + + ret = usb_add_gadget_udc(&pdev->dev, &usb3->gadget); + if (ret < 0) + goto err_add_udc; + + usb3->workaround_for_vbus = priv->workaround_for_vbus; + + pm_runtime_enable(&pdev->dev); + pm_runtime_get_sync(&pdev->dev); + + dev_info(&pdev->dev, "probed\n"); + + return 0; + +err_add_udc: + __renesas_usb3_ep_free_request(usb3->ep0_req); + + return ret; +} + +static struct platform_driver renesas_usb3_driver = { + .probe = renesas_usb3_probe, + .remove = renesas_usb3_remove, + .driver = { + .name = (char *)udc_name, + .of_match_table = of_match_ptr(usb3_of_match), + }, +}; +module_platform_driver(renesas_usb3_driver); + +MODULE_DESCRIPTION("Renesas USB3.0 Peripheral driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Yoshihiro Shimoda "); +MODULE_ALIAS("platform:renesas_usb3"); -- GitLab From d9261898a4b2c143c28568dc686a1becfc637a99 Mon Sep 17 00:00:00 2001 From: John Youn Date: Tue, 22 Dec 2015 12:23:20 -0800 Subject: [PATCH 2032/2855] usb: dwc3: gadget: don't send extra ZLP If the request->length is zero, a ZLP should already be sent due to that and another ZLP is not needed to terminate the transfer. Fixes: 04c03d10e507 ("usb: dwc3: gadget: handle request->zero") Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 64b2a8303d33d..af023a81a0b02 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1203,7 +1203,8 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, * extra usb_request ourselves so that it gets handled the same way as * any other request. */ - if (ret == 0 && request->zero && (request->length % ep->maxpacket == 0)) + if (ret == 0 && request->zero && request->length && + (request->length % ep->maxpacket == 0)) ret = __dwc3_gadget_ep_queue_zlp(dwc, dep); spin_unlock_irqrestore(&dwc->lock, flags); -- GitLab From 5072cfc40a80cea3749fd3413b3896630d8c787e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 22 Dec 2015 21:56:10 -0600 Subject: [PATCH 2033/2855] usb: dwc3: of-simple: fix build warning on !PM if we have a !PM kernel build, our runtime suspend/resume callbacks will be left defined but unused. Add a ifdef CONFIG_PM guard. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-of-simple.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index 60c4c5a443072..9c9f741550664 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -122,6 +122,7 @@ static int dwc3_of_simple_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM static int dwc3_of_simple_runtime_suspend(struct device *dev) { struct dwc3_of_simple *simple = dev_get_drvdata(dev); @@ -150,6 +151,7 @@ static int dwc3_of_simple_runtime_resume(struct device *dev) return 0; } +#endif static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = { SET_RUNTIME_PM_OPS(dwc3_of_simple_runtime_suspend, -- GitLab From b0918d9f476a8434b055e362b83fa4fd1d462c3f Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Fri, 11 Dec 2015 15:54:16 +0100 Subject: [PATCH 2034/2855] udf: limit the maximum number of indirect extents in a row udf_next_aext() just follows extent pointers while extents are marked as indirect. This can loop forever for corrupted filesystem. Limit number the of indirect extents we are willing to follow in a row. [JK: Updated changelog, limit, style] Signed-off-by: Vegard Nossum Cc: stable@vger.kernel.org Cc: Jan Kara Cc: Quentin Casasnovas Cc: Andrew Morton Signed-off-by: Jan Kara --- fs/udf/inode.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 8d0b3ade0ff0e..566df9b5a6cb6 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -2047,14 +2047,29 @@ void udf_write_aext(struct inode *inode, struct extent_position *epos, epos->offset += adsize; } +/* + * Only 1 indirect extent in a row really makes sense but allow upto 16 in case + * someone does some weird stuff. + */ +#define UDF_MAX_INDIR_EXTS 16 + int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, struct kernel_lb_addr *eloc, uint32_t *elen, int inc) { int8_t etype; + unsigned int indirections = 0; while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) { int block; + + if (++indirections > UDF_MAX_INDIR_EXTS) { + udf_err(inode->i_sb, + "too many indirect extents in inode %lu\n", + inode->i_ino); + return -1; + } + epos->block = *eloc; epos->offset = sizeof(struct allocExtDesc); brelse(epos->bh); -- GitLab From 6096828e68cc15c0ddc5895036f07c62558b604c Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Wed, 23 Dec 2015 19:05:39 +0800 Subject: [PATCH 2035/2855] spi: dw: Use SPI_TMOD_TR rather than magic const 0 to set tmode The TMODE available value is well defined and documented in the header file. Use it and remove the comment. Signed-off-by: Jisheng Zhang Signed-off-by: Mark Brown --- drivers/spi/spi-dw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 882cd6618cd5d..c09bb745693a0 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -425,7 +425,7 @@ static int dw_spi_setup(struct spi_device *spi) chip->type = chip_info->type; } - chip->tmode = 0; /* Tx & Rx */ + chip->tmode = SPI_TMOD_TR; if (gpio_is_valid(spi->cs_gpio)) { ret = gpio_direction_output(spi->cs_gpio, -- GitLab From 1f97fe4777217123428e3212a95a67c0de7a0132 Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Wed, 23 Dec 2015 11:58:34 +0100 Subject: [PATCH 2036/2855] regulator: lp872x: Add missing of_match in regulators descriptions In order to select the regulators via of_find_regulator_by_node (and thus use them in devicetree), defining of_match for each regulator is required. Signed-off-by: Paul Kocialkowski Signed-off-by: Mark Brown --- drivers/regulator/lp872x.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index e5af07208f9d3..9412353da622a 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c @@ -520,6 +520,7 @@ static struct regulator_ops lp8725_buck_ops = { static struct regulator_desc lp8720_regulator_desc[] = { { .name = "ldo1", + .of_match = of_match_ptr("ldo1"), .id = LP8720_ID_LDO1, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -533,6 +534,7 @@ static struct regulator_desc lp8720_regulator_desc[] = { }, { .name = "ldo2", + .of_match = of_match_ptr("ldo2"), .id = LP8720_ID_LDO2, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -546,6 +548,7 @@ static struct regulator_desc lp8720_regulator_desc[] = { }, { .name = "ldo3", + .of_match = of_match_ptr("ldo3"), .id = LP8720_ID_LDO3, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -559,6 +562,7 @@ static struct regulator_desc lp8720_regulator_desc[] = { }, { .name = "ldo4", + .of_match = of_match_ptr("ldo4"), .id = LP8720_ID_LDO4, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp8720_ldo4_vtbl), @@ -572,6 +576,7 @@ static struct regulator_desc lp8720_regulator_desc[] = { }, { .name = "ldo5", + .of_match = of_match_ptr("ldo5"), .id = LP8720_ID_LDO5, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -585,6 +590,7 @@ static struct regulator_desc lp8720_regulator_desc[] = { }, { .name = "buck", + .of_match = of_match_ptr("buck"), .id = LP8720_ID_BUCK, .ops = &lp8720_buck_ops, .n_voltages = ARRAY_SIZE(lp8720_buck_vtbl), @@ -599,6 +605,7 @@ static struct regulator_desc lp8720_regulator_desc[] = { static struct regulator_desc lp8725_regulator_desc[] = { { .name = "ldo1", + .of_match = of_match_ptr("ldo1"), .id = LP8725_ID_LDO1, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -612,6 +619,7 @@ static struct regulator_desc lp8725_regulator_desc[] = { }, { .name = "ldo2", + .of_match = of_match_ptr("ldo2"), .id = LP8725_ID_LDO2, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -625,6 +633,7 @@ static struct regulator_desc lp8725_regulator_desc[] = { }, { .name = "ldo3", + .of_match = of_match_ptr("ldo3"), .id = LP8725_ID_LDO3, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -638,6 +647,7 @@ static struct regulator_desc lp8725_regulator_desc[] = { }, { .name = "ldo4", + .of_match = of_match_ptr("ldo4"), .id = LP8725_ID_LDO4, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -651,6 +661,7 @@ static struct regulator_desc lp8725_regulator_desc[] = { }, { .name = "ldo5", + .of_match = of_match_ptr("ldo5"), .id = LP8725_ID_LDO5, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -664,6 +675,7 @@ static struct regulator_desc lp8725_regulator_desc[] = { }, { .name = "lilo1", + .of_match = of_match_ptr("lilo1"), .id = LP8725_ID_LILO1, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp8725_lilo_vtbl), @@ -677,6 +689,7 @@ static struct regulator_desc lp8725_regulator_desc[] = { }, { .name = "lilo2", + .of_match = of_match_ptr("lilo2"), .id = LP8725_ID_LILO2, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp8725_lilo_vtbl), @@ -690,6 +703,7 @@ static struct regulator_desc lp8725_regulator_desc[] = { }, { .name = "buck1", + .of_match = of_match_ptr("buck1"), .id = LP8725_ID_BUCK1, .ops = &lp8725_buck_ops, .n_voltages = ARRAY_SIZE(lp8725_buck_vtbl), @@ -701,6 +715,7 @@ static struct regulator_desc lp8725_regulator_desc[] = { }, { .name = "buck2", + .of_match = of_match_ptr("buck2"), .id = LP8725_ID_BUCK2, .ops = &lp8725_buck_ops, .n_voltages = ARRAY_SIZE(lp8725_buck_vtbl), -- GitLab From 8a99cc6ff5710780e3d9bfc41027c142725089e5 Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Wed, 23 Dec 2015 11:58:35 +0100 Subject: [PATCH 2037/2855] regulator: lp872x: Get rid of duplicate reference to DVS GPIO The lp872x structure holds a reference to the DVS GPIO, but it is never actually used anywhere, since a first reference exists from the lp872x_dvs structure. Signed-off-by: Paul Kocialkowski Signed-off-by: Mark Brown --- drivers/regulator/lp872x.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index 9412353da622a..19d7584865531 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c @@ -108,7 +108,6 @@ struct lp872x { struct lp872x_platform_data *pdata; int num_regulators; enum lp872x_dvs_state dvs_pin; - int dvs_gpio; }; /* LP8720/LP8725 shared voltage table for LDOs */ @@ -752,7 +751,6 @@ static int lp872x_init_dvs(struct lp872x *lp) } lp->dvs_pin = pinstate; - lp->dvs_gpio = gpio; return 0; -- GitLab From d1eba93bd0fcd3f699cb8d666bc97788ee85d557 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Wed, 23 Dec 2015 00:18:41 +0800 Subject: [PATCH 2038/2855] spi: use to_spi_device Use to_spi_device() instead of open-coding it. Signed-off-by: Geliang Tang Signed-off-by: Mark Brown --- drivers/spi/spi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index e2415be209d5a..70828521e6bb6 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -84,8 +84,7 @@ static ssize_t spi_device_##field##_show(struct device *dev, \ struct device_attribute *attr, \ char *buf) \ { \ - struct spi_device *spi = container_of(dev, \ - struct spi_device, dev); \ + struct spi_device *spi = to_spi_device(dev); \ return spi_statistics_##field##_show(&spi->statistics, buf); \ } \ static struct device_attribute dev_attr_spi_device_##field = { \ -- GitLab From d4f72cb7fa4a3705f6675f2740f9713dc3400dd3 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Tue, 24 Nov 2015 15:43:03 -0700 Subject: [PATCH 2039/2855] nfsd: don't base cl_cb_status on stale information The rpc client we use to send callbacks may change occasionally. (In the 4.0 case, the client can use setclientid/setclientid_confirm to update the callback parameters. In the 4.1+ case, sessions and connections can come and go.) The update is done from the callback thread by nfsd4_process_cb_update, which shuts down the old rpc client and then creates a new one. The client shutdown kills any ongoing rpc calls. There won't be any new ones till the new one's created and the callback thread moves on. When an rpc encounters a problem that may suggest callback rpc's aren't working any longer, it normally sets NFSD4_CB_DOWN, so the server can tell the client something's wrong. But if the rpc notices CB_UPDATE is set, then the failure may just be a normal result of shutting down the callback client. Or it could just be a coincidence, but in any case, it means we're runing with the old about-to-be-discarded client, so the failure's not interesting. Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4callback.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 081709c3fa4fd..7389cb1d7409c 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -792,12 +792,16 @@ static void warn_no_callback_path(struct nfs4_client *clp, int reason) static void nfsd4_mark_cb_down(struct nfs4_client *clp, int reason) { + if (test_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_flags)) + return; clp->cl_cb_state = NFSD4_CB_DOWN; warn_no_callback_path(clp, reason); } static void nfsd4_mark_cb_fault(struct nfs4_client *clp, int reason) { + if (test_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_flags)) + return; clp->cl_cb_state = NFSD4_CB_FAULT; warn_no_callback_path(clp, reason); } -- GitLab From c3d4879e01bec484f50a78c108341f039d470e96 Mon Sep 17 00:00:00 2001 From: Scott Mayhew Date: Fri, 11 Dec 2015 16:45:58 -0500 Subject: [PATCH 2040/2855] sunrpc: Add a function to close temporary transports immediately Add a function svc_age_temp_xprts_now() to close temporary transports whose xpt_local matches the address passed in server_addr immediately instead of waiting for them to be closed by the timer function. The function is intended to be used by notifier_blocks that will be added to nfsd and lockd that will run when an ip address is deleted. This will eliminate the ACK storms and client hangs that occur in HA-NFS configurations where nfsd & lockd is left running on the cluster nodes all the time and the NFS 'service' is migrated back and forth within a short timeframe. Signed-off-by: Scott Mayhew Signed-off-by: J. Bruce Fields --- include/linux/sunrpc/svc_xprt.h | 1 + net/sunrpc/svc_xprt.c | 45 +++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h index 78512cfe1fe68..b7dabc4baafd8 100644 --- a/include/linux/sunrpc/svc_xprt.h +++ b/include/linux/sunrpc/svc_xprt.h @@ -128,6 +128,7 @@ struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name, const unsigned short port); int svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen); void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *xprt); +void svc_age_temp_xprts_now(struct svc_serv *, struct sockaddr *); static inline void svc_xprt_get(struct svc_xprt *xprt) { diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index a6cbb2104667d..7422f28818b24 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -10,11 +10,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #define RPCDBG_FACILITY RPCDBG_SVCXPRT @@ -938,6 +940,49 @@ static void svc_age_temp_xprts(unsigned long closure) mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ); } +/* Close temporary transports whose xpt_local matches server_addr immediately + * instead of waiting for them to be picked up by the timer. + * + * This is meant to be called from a notifier_block that runs when an ip + * address is deleted. + */ +void svc_age_temp_xprts_now(struct svc_serv *serv, struct sockaddr *server_addr) +{ + struct svc_xprt *xprt; + struct svc_sock *svsk; + struct socket *sock; + struct list_head *le, *next; + LIST_HEAD(to_be_closed); + struct linger no_linger = { + .l_onoff = 1, + .l_linger = 0, + }; + + spin_lock_bh(&serv->sv_lock); + list_for_each_safe(le, next, &serv->sv_tempsocks) { + xprt = list_entry(le, struct svc_xprt, xpt_list); + if (rpc_cmp_addr(server_addr, (struct sockaddr *) + &xprt->xpt_local)) { + dprintk("svc_age_temp_xprts_now: found %p\n", xprt); + list_move(le, &to_be_closed); + } + } + spin_unlock_bh(&serv->sv_lock); + + while (!list_empty(&to_be_closed)) { + le = to_be_closed.next; + list_del_init(le); + xprt = list_entry(le, struct svc_xprt, xpt_list); + dprintk("svc_age_temp_xprts_now: closing %p\n", xprt); + svsk = container_of(xprt, struct svc_sock, sk_xprt); + sock = svsk->sk_sock; + kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER, + (char *)&no_linger, sizeof(no_linger)); + svc_close_xprt(xprt); + } +} +EXPORT_SYMBOL_GPL(svc_age_temp_xprts_now); + static void call_xpt_users(struct svc_xprt *xprt) { struct svc_xpt_user *u; -- GitLab From 366849966f20a3d996a2160778861e348cc6a7c6 Mon Sep 17 00:00:00 2001 From: Scott Mayhew Date: Fri, 11 Dec 2015 16:45:59 -0500 Subject: [PATCH 2041/2855] nfsd: Register callbacks on the inetaddr_chain and inet6addr_chain Register callbacks on inetaddr_chain and inet6addr_chain to trigger cleanup of nfsd transport sockets when an ip address is deleted. Signed-off-by: Scott Mayhew Signed-off-by: J. Bruce Fields --- fs/nfsd/nfssvc.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index ad4e2377dd636..3779a5fbeb424 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -14,9 +14,13 @@ #include #include +#include #include #include #include +#include +#include +#include #include #include "nfsd.h" #include "cache.h" @@ -306,10 +310,70 @@ static void nfsd_shutdown_net(struct net *net) nfsd_shutdown_generic(); } +static int nfsd_inetaddr_event(struct notifier_block *this, unsigned long event, + void *ptr) +{ + struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; + struct net_device *dev = ifa->ifa_dev->dev; + struct net *net = dev_net(dev); + struct nfsd_net *nn = net_generic(net, nfsd_net_id); + struct sockaddr_in sin; + + if (event != NETDEV_DOWN) + goto out; + + if (nn->nfsd_serv) { + dprintk("nfsd_inetaddr_event: removed %pI4\n", &ifa->ifa_local); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = ifa->ifa_local; + svc_age_temp_xprts_now(nn->nfsd_serv, (struct sockaddr *)&sin); + } + +out: + return NOTIFY_DONE; +} + +static struct notifier_block nfsd_inetaddr_notifier = { + .notifier_call = nfsd_inetaddr_event, +}; + +#if IS_ENABLED(CONFIG_IPV6) +static int nfsd_inet6addr_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; + struct net_device *dev = ifa->idev->dev; + struct net *net = dev_net(dev); + struct nfsd_net *nn = net_generic(net, nfsd_net_id); + struct sockaddr_in6 sin6; + + if (event != NETDEV_DOWN) + goto out; + + if (nn->nfsd_serv) { + dprintk("nfsd_inet6addr_event: removed %pI6\n", &ifa->addr); + sin6.sin6_family = AF_INET6; + sin6.sin6_addr = ifa->addr; + svc_age_temp_xprts_now(nn->nfsd_serv, (struct sockaddr *)&sin6); + } + +out: + return NOTIFY_DONE; +} + +static struct notifier_block nfsd_inet6addr_notifier = { + .notifier_call = nfsd_inet6addr_event, +}; +#endif + static void nfsd_last_thread(struct svc_serv *serv, struct net *net) { struct nfsd_net *nn = net_generic(net, nfsd_net_id); + unregister_inetaddr_notifier(&nfsd_inetaddr_notifier); +#if IS_ENABLED(CONFIG_IPV6) + unregister_inet6addr_notifier(&nfsd_inet6addr_notifier); +#endif /* * write_ports can create the server without actually starting * any threads--if we get shut down before any threads are @@ -425,6 +489,10 @@ int nfsd_create_serv(struct net *net) } set_max_drc(); + register_inetaddr_notifier(&nfsd_inetaddr_notifier); +#if IS_ENABLED(CONFIG_IPV6) + register_inet6addr_notifier(&nfsd_inet6addr_notifier); +#endif do_gettimeofday(&nn->nfssvc_boot); /* record boot time */ return 0; } -- GitLab From 0751ddf77b6af2efe1041efb81141badd64efb65 Mon Sep 17 00:00:00 2001 From: Scott Mayhew Date: Fri, 11 Dec 2015 16:46:00 -0500 Subject: [PATCH 2042/2855] lockd: Register callbacks on the inetaddr_chain and inet6addr_chain Register callbacks on inetaddr_chain and inet6addr_chain to trigger cleanup of lockd transport sockets when an ip address is deleted. Signed-off-by: Scott Mayhew Signed-off-by: J. Bruce Fields --- fs/lockd/svc.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 5f31ebd96c068..44d18ad4d364c 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -25,13 +25,17 @@ #include #include #include +#include #include #include #include #include #include +#include #include +#include +#include #include #include @@ -279,6 +283,68 @@ static void lockd_down_net(struct svc_serv *serv, struct net *net) } } +static int lockd_inetaddr_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; + struct sockaddr_in sin; + + if (event != NETDEV_DOWN) + goto out; + + if (nlmsvc_rqst) { + dprintk("lockd_inetaddr_event: removed %pI4\n", + &ifa->ifa_local); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = ifa->ifa_local; + svc_age_temp_xprts_now(nlmsvc_rqst->rq_server, + (struct sockaddr *)&sin); + } + +out: + return NOTIFY_DONE; +} + +static struct notifier_block lockd_inetaddr_notifier = { + .notifier_call = lockd_inetaddr_event, +}; + +#if IS_ENABLED(CONFIG_IPV6) +static int lockd_inet6addr_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; + struct sockaddr_in6 sin6; + + if (event != NETDEV_DOWN) + goto out; + + if (nlmsvc_rqst) { + dprintk("lockd_inet6addr_event: removed %pI6\n", &ifa->addr); + sin6.sin6_family = AF_INET6; + sin6.sin6_addr = ifa->addr; + svc_age_temp_xprts_now(nlmsvc_rqst->rq_server, + (struct sockaddr *)&sin6); + } + +out: + return NOTIFY_DONE; +} + +static struct notifier_block lockd_inet6addr_notifier = { + .notifier_call = lockd_inet6addr_event, +}; +#endif + +static void lockd_svc_exit_thread(void) +{ + unregister_inetaddr_notifier(&lockd_inetaddr_notifier); +#if IS_ENABLED(CONFIG_IPV6) + unregister_inet6addr_notifier(&lockd_inet6addr_notifier); +#endif + svc_exit_thread(nlmsvc_rqst); +} + static int lockd_start_svc(struct svc_serv *serv) { int error; @@ -315,7 +381,7 @@ static int lockd_start_svc(struct svc_serv *serv) return 0; out_task: - svc_exit_thread(nlmsvc_rqst); + lockd_svc_exit_thread(); nlmsvc_task = NULL; out_rqst: nlmsvc_rqst = NULL; @@ -360,6 +426,10 @@ static struct svc_serv *lockd_create_svc(void) printk(KERN_WARNING "lockd_up: create service failed\n"); return ERR_PTR(-ENOMEM); } + register_inetaddr_notifier(&lockd_inetaddr_notifier); +#if IS_ENABLED(CONFIG_IPV6) + register_inet6addr_notifier(&lockd_inet6addr_notifier); +#endif dprintk("lockd_up: service created\n"); return serv; } @@ -428,7 +498,7 @@ lockd_down(struct net *net) } kthread_stop(nlmsvc_task); dprintk("lockd_down: service stopped\n"); - svc_exit_thread(nlmsvc_rqst); + lockd_svc_exit_thread(); dprintk("lockd_down: service destroyed\n"); nlmsvc_task = NULL; nlmsvc_rqst = NULL; -- GitLab From fcea62babc8100aee79c716c81203c6d105b2da0 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 23 Dec 2015 14:21:13 +0100 Subject: [PATCH 2043/2855] udf: Factor out code for creating indirect extent Factor out code for creating indirect extent from udf_add_aext(). It was mostly duplicated in two places. Also remove some opencoded versions of udf_write_aext(). Signed-off-by: Jan Kara --- fs/udf/balloc.c | 98 ++------------------- fs/udf/inode.c | 217 ++++++++++++++++++++++++++--------------------- fs/udf/udfdecl.h | 4 + 3 files changed, 130 insertions(+), 189 deletions(-) diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index 6d6a96b4e73fe..e0fd65fe73e82 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c @@ -447,9 +447,6 @@ static void udf_table_free_blocks(struct super_block *sb, */ int adsize; - struct short_ad *sad = NULL; - struct long_ad *lad = NULL; - struct allocExtDesc *aed; eloc.logicalBlockNum = start; elen = EXT_RECORDED_ALLOCATED | @@ -466,102 +463,17 @@ static void udf_table_free_blocks(struct super_block *sb, } if (epos.offset + (2 * adsize) > sb->s_blocksize) { - unsigned char *sptr, *dptr; - int loffset; - - brelse(oepos.bh); - oepos = epos; - /* Steal a block from the extent being free'd */ - epos.block.logicalBlockNum = eloc.logicalBlockNum; + udf_setup_indirect_aext(table, eloc.logicalBlockNum, + &epos); + eloc.logicalBlockNum++; elen -= sb->s_blocksize; - - epos.bh = udf_tread(sb, - udf_get_lb_pblock(sb, &epos.block, 0)); - if (!epos.bh) { - brelse(oepos.bh); - goto error_return; - } - aed = (struct allocExtDesc *)(epos.bh->b_data); - aed->previousAllocExtLocation = - cpu_to_le32(oepos.block.logicalBlockNum); - if (epos.offset + adsize > sb->s_blocksize) { - loffset = epos.offset; - aed->lengthAllocDescs = cpu_to_le32(adsize); - sptr = iinfo->i_ext.i_data + epos.offset - - adsize; - dptr = epos.bh->b_data + - sizeof(struct allocExtDesc); - memcpy(dptr, sptr, adsize); - epos.offset = sizeof(struct allocExtDesc) + - adsize; - } else { - loffset = epos.offset + adsize; - aed->lengthAllocDescs = cpu_to_le32(0); - if (oepos.bh) { - sptr = oepos.bh->b_data + epos.offset; - aed = (struct allocExtDesc *) - oepos.bh->b_data; - le32_add_cpu(&aed->lengthAllocDescs, - adsize); - } else { - sptr = iinfo->i_ext.i_data + - epos.offset; - iinfo->i_lenAlloc += adsize; - mark_inode_dirty(table); - } - epos.offset = sizeof(struct allocExtDesc); - } - if (sbi->s_udfrev >= 0x0200) - udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, - 3, 1, epos.block.logicalBlockNum, - sizeof(struct tag)); - else - udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, - 2, 1, epos.block.logicalBlockNum, - sizeof(struct tag)); - - switch (iinfo->i_alloc_type) { - case ICBTAG_FLAG_AD_SHORT: - sad = (struct short_ad *)sptr; - sad->extLength = cpu_to_le32( - EXT_NEXT_EXTENT_ALLOCDECS | - sb->s_blocksize); - sad->extPosition = - cpu_to_le32(epos.block.logicalBlockNum); - break; - case ICBTAG_FLAG_AD_LONG: - lad = (struct long_ad *)sptr; - lad->extLength = cpu_to_le32( - EXT_NEXT_EXTENT_ALLOCDECS | - sb->s_blocksize); - lad->extLocation = - cpu_to_lelb(epos.block); - break; - } - if (oepos.bh) { - udf_update_tag(oepos.bh->b_data, loffset); - mark_buffer_dirty(oepos.bh); - } else { - mark_inode_dirty(table); - } } /* It's possible that stealing the block emptied the extent */ - if (elen) { - udf_write_aext(table, &epos, &eloc, elen, 1); - - if (!epos.bh) { - iinfo->i_lenAlloc += adsize; - mark_inode_dirty(table); - } else { - aed = (struct allocExtDesc *)epos.bh->b_data; - le32_add_cpu(&aed->lengthAllocDescs, adsize); - udf_update_tag(epos.bh->b_data, epos.offset); - mark_buffer_dirty(epos.bh); - } - } + if (elen) + __udf_add_aext(table, &epos, &eloc, elen, 1); } brelse(epos.bh); diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 566df9b5a6cb6..34c2d2b795942 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1866,112 +1866,102 @@ struct inode *__udf_iget(struct super_block *sb, struct kernel_lb_addr *ino, return inode; } -int udf_add_aext(struct inode *inode, struct extent_position *epos, - struct kernel_lb_addr *eloc, uint32_t elen, int inc) +int udf_setup_indirect_aext(struct inode *inode, int block, + struct extent_position *epos) { - int adsize; - struct short_ad *sad = NULL; - struct long_ad *lad = NULL; + struct super_block *sb = inode->i_sb; + struct buffer_head *bh; struct allocExtDesc *aed; - uint8_t *ptr; - struct udf_inode_info *iinfo = UDF_I(inode); + struct extent_position nepos; + struct kernel_lb_addr neloc; + int ver, adsize; - if (!epos->bh) - ptr = iinfo->i_ext.i_data + epos->offset - - udf_file_entry_alloc_offset(inode) + - iinfo->i_lenEAttr; + if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_SHORT) + adsize = sizeof(struct short_ad); + else if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_LONG) + adsize = sizeof(struct long_ad); + + neloc.logicalBlockNum = block; + neloc.partitionReferenceNum = epos->block.partitionReferenceNum; + + bh = udf_tgetblk(sb, udf_get_lb_pblock(sb, &neloc, 0)); + if (!bh) + return -EIO; + lock_buffer(bh); + memset(bh->b_data, 0x00, sb->s_blocksize); + set_buffer_uptodate(bh); + unlock_buffer(bh); + mark_buffer_dirty_inode(bh, inode); + + aed = (struct allocExtDesc *)(bh->b_data); + if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT)) { + aed->previousAllocExtLocation = + cpu_to_le32(epos->block.logicalBlockNum); + } + aed->lengthAllocDescs = cpu_to_le32(0); + if (UDF_SB(sb)->s_udfrev >= 0x0200) + ver = 3; else - ptr = epos->bh->b_data + epos->offset; + ver = 2; + udf_new_tag(bh->b_data, TAG_IDENT_AED, ver, 1, block, + sizeof(struct tag)); + + nepos.block = neloc; + nepos.offset = sizeof(struct allocExtDesc); + nepos.bh = bh; + + /* + * Do we have to copy current last extent to make space for indirect + * one? + */ + if (epos->offset + adsize > sb->s_blocksize) { + struct kernel_lb_addr cp_loc; + uint32_t cp_len; + int cp_type; + + epos->offset -= adsize; + cp_type = udf_current_aext(inode, epos, &cp_loc, &cp_len, 0); + cp_len |= ((uint32_t)cp_type) << 30; + + __udf_add_aext(inode, &nepos, &cp_loc, cp_len, 1); + udf_write_aext(inode, epos, &nepos.block, + sb->s_blocksize | EXT_NEXT_EXTENT_ALLOCDECS, 0); + } else { + __udf_add_aext(inode, epos, &nepos.block, + sb->s_blocksize | EXT_NEXT_EXTENT_ALLOCDECS, 0); + } + + brelse(epos->bh); + *epos = nepos; + + return 0; +} + +/* + * Append extent at the given position - should be the first free one in inode + * / indirect extent. This function assumes there is enough space in the inode + * or indirect extent. Use udf_add_aext() if you didn't check for this before. + */ +int __udf_add_aext(struct inode *inode, struct extent_position *epos, + struct kernel_lb_addr *eloc, uint32_t elen, int inc) +{ + struct udf_inode_info *iinfo = UDF_I(inode); + struct allocExtDesc *aed; + int adsize; if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) adsize = sizeof(struct short_ad); else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) adsize = sizeof(struct long_ad); - else - return -EIO; - - if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) { - unsigned char *sptr, *dptr; - struct buffer_head *nbh; - int err, loffset; - struct kernel_lb_addr obloc = epos->block; - epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL, - obloc.partitionReferenceNum, - obloc.logicalBlockNum, &err); - if (!epos->block.logicalBlockNum) - return -ENOSPC; - nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, - &epos->block, - 0)); - if (!nbh) - return -EIO; - lock_buffer(nbh); - memset(nbh->b_data, 0x00, inode->i_sb->s_blocksize); - set_buffer_uptodate(nbh); - unlock_buffer(nbh); - mark_buffer_dirty_inode(nbh, inode); - - aed = (struct allocExtDesc *)(nbh->b_data); - if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) - aed->previousAllocExtLocation = - cpu_to_le32(obloc.logicalBlockNum); - if (epos->offset + adsize > inode->i_sb->s_blocksize) { - loffset = epos->offset; - aed->lengthAllocDescs = cpu_to_le32(adsize); - sptr = ptr - adsize; - dptr = nbh->b_data + sizeof(struct allocExtDesc); - memcpy(dptr, sptr, adsize); - epos->offset = sizeof(struct allocExtDesc) + adsize; - } else { - loffset = epos->offset + adsize; - aed->lengthAllocDescs = cpu_to_le32(0); - sptr = ptr; - epos->offset = sizeof(struct allocExtDesc); - - if (epos->bh) { - aed = (struct allocExtDesc *)epos->bh->b_data; - le32_add_cpu(&aed->lengthAllocDescs, adsize); - } else { - iinfo->i_lenAlloc += adsize; - mark_inode_dirty(inode); - } - } - if (UDF_SB(inode->i_sb)->s_udfrev >= 0x0200) - udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, - epos->block.logicalBlockNum, sizeof(struct tag)); - else - udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, - epos->block.logicalBlockNum, sizeof(struct tag)); - switch (iinfo->i_alloc_type) { - case ICBTAG_FLAG_AD_SHORT: - sad = (struct short_ad *)sptr; - sad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS | - inode->i_sb->s_blocksize); - sad->extPosition = - cpu_to_le32(epos->block.logicalBlockNum); - break; - case ICBTAG_FLAG_AD_LONG: - lad = (struct long_ad *)sptr; - lad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS | - inode->i_sb->s_blocksize); - lad->extLocation = cpu_to_lelb(epos->block); - memset(lad->impUse, 0x00, sizeof(lad->impUse)); - break; - } - if (epos->bh) { - if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || - UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) - udf_update_tag(epos->bh->b_data, loffset); - else - udf_update_tag(epos->bh->b_data, - sizeof(struct allocExtDesc)); - mark_buffer_dirty_inode(epos->bh, inode); - brelse(epos->bh); - } else { - mark_inode_dirty(inode); - } - epos->bh = nbh; + if (!epos->bh) { + WARN_ON(iinfo->i_lenAlloc != + epos->offset - udf_file_entry_alloc_offset(inode)); + } else { + aed = (struct allocExtDesc *)epos->bh->b_data; + WARN_ON(le32_to_cpu(aed->lengthAllocDescs) != + epos->offset - sizeof(struct allocExtDesc)); + WARN_ON(epos->offset + adsize > inode->i_sb->s_blocksize); } udf_write_aext(inode, epos, eloc, elen, inc); @@ -1995,6 +1985,41 @@ int udf_add_aext(struct inode *inode, struct extent_position *epos, return 0; } +/* + * Append extent at given position - should be the first free one in inode + * / indirect extent. Takes care of allocating and linking indirect blocks. + */ +int udf_add_aext(struct inode *inode, struct extent_position *epos, + struct kernel_lb_addr *eloc, uint32_t elen, int inc) +{ + int adsize; + struct super_block *sb = inode->i_sb; + + if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_SHORT) + adsize = sizeof(struct short_ad); + else if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_LONG) + adsize = sizeof(struct long_ad); + else + return -EIO; + + if (epos->offset + (2 * adsize) > sb->s_blocksize) { + int err; + int new_block; + + new_block = udf_new_block(sb, NULL, + epos->block.partitionReferenceNum, + epos->block.logicalBlockNum, &err); + if (!new_block) + return -ENOSPC; + + err = udf_setup_indirect_aext(inode, new_block, epos); + if (err) + return err; + } + + return __udf_add_aext(inode, epos, eloc, elen, inc); +} + void udf_write_aext(struct inode *inode, struct extent_position *epos, struct kernel_lb_addr *eloc, uint32_t elen, int inc) { diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 47bb3f5ca360d..269ad3fb2fab8 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -159,6 +159,10 @@ extern int udf_write_inode(struct inode *, struct writeback_control *wbc); extern long udf_block_map(struct inode *, sector_t); extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *, struct kernel_lb_addr *, uint32_t *, sector_t *); +extern int udf_setup_indirect_aext(struct inode *inode, int block, + struct extent_position *epos); +extern int __udf_add_aext(struct inode *inode, struct extent_position *epos, + struct kernel_lb_addr *eloc, uint32_t elen, int inc); extern int udf_add_aext(struct inode *, struct extent_position *, struct kernel_lb_addr *, uint32_t, int); extern void udf_write_aext(struct inode *, struct extent_position *, -- GitLab From 6c37157874aa2b153b722868bd984002fbcff6bb Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 23 Dec 2015 18:05:03 +0100 Subject: [PATCH 2044/2855] udf: Fix lost indirect extent block When inode ends with empty indirect extent block and we extended that file, udf_do_extend_file() ended up just overwriting pointer to it with another extent and thus effectively leaking the block and also corruptiong length of allocation descriptors. Fix the problem by properly following into next indirect extent when it is present. Signed-off-by: Jan Kara --- fs/udf/inode.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 34c2d2b795942..846294891925a 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -539,9 +539,18 @@ static int udf_do_extend_file(struct inode *inode, udf_add_aext(inode, last_pos, &last_ext->extLocation, last_ext->extLength, 1); count++; - } else + } else { + struct kernel_lb_addr tmploc; + uint32_t tmplen; + udf_write_aext(inode, last_pos, &last_ext->extLocation, last_ext->extLength, 1); + /* + * We've rewritten the last extent but there may be empty + * indirect extent after it - enter it. + */ + udf_next_aext(inode, last_pos, &tmploc, &tmplen, 0); + } /* Managed to do everything necessary? */ if (!blocks) -- GitLab From 479f6a7fc64722d82e24db15b2d6ae7f2882377a Mon Sep 17 00:00:00 2001 From: Raghav Dogra Date: Fri, 30 Oct 2015 11:52:02 +0530 Subject: [PATCH 2045/2855] powerpc/fsl_lbc: removal of dead code The condition check is not used. Signed-off-by: Raghav Dogra Signed-off-by: Scott Wood --- arch/powerpc/sysdev/fsl_lbc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c index 38138cf8d33e2..47f781059eeb6 100644 --- a/arch/powerpc/sysdev/fsl_lbc.c +++ b/arch/powerpc/sysdev/fsl_lbc.c @@ -243,8 +243,6 @@ static irqreturn_t fsl_lbc_ctrl_irq(int irqno, void *data) if (status & LTESR_CS) dev_err(ctrl->dev, "Chip select error: " "LTESR 0x%08X\n", status); - if (status & LTESR_UPM) - ; if (status & LTESR_FCT) { dev_err(ctrl->dev, "FCM command time-out: " "LTESR 0x%08X\n", status); -- GitLab From 2330770797afa822652b541d81a17f0e04bcf598 Mon Sep 17 00:00:00 2001 From: Hongtao Jia Date: Tue, 24 Nov 2015 14:52:44 +0800 Subject: [PATCH 2046/2855] dt-bindings: Add QorIQ TMU thermal bindings Add bindings documentation for TMU (Thermal Monitoring Unit) on QorIQ platform. Signed-off-by: Jia Hongtao Reviewed-by: Scott Wood Acked-by: Rob Herring Signed-off-by: Scott Wood --- .../bindings/thermal/qoriq-thermal.txt | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 Documentation/devicetree/bindings/thermal/qoriq-thermal.txt diff --git a/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt b/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt new file mode 100644 index 0000000000000..66223d561972c --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt @@ -0,0 +1,63 @@ +* Thermal Monitoring Unit (TMU) on Freescale QorIQ SoCs + +Required properties: +- compatible : Must include "fsl,qoriq-tmu". The version of the device is + determined by the TMU IP Block Revision Register (IPBRR0) at + offset 0x0BF8. + Table of correspondences between IPBRR0 values and example chips: + Value Device + ---------- ----- + 0x01900102 T1040 +- reg : Address range of TMU registers. +- interrupts : Contains the interrupt for TMU. +- fsl,tmu-range : The values to be programmed into TTRnCR, as specified by + the SoC reference manual. The first cell is TTR0CR, the second is + TTR1CR, etc. +- fsl,tmu-calibration : A list of cell pairs containing temperature + calibration data, as specified by the SoC reference manual. + The first cell of each pair is the value to be written to TTCFGR, + and the second is the value to be written to TSCFGR. + +Example: + +tmu@f0000 { + compatible = "fsl,qoriq-tmu"; + reg = <0xf0000 0x1000>; + interrupts = <18 2 0 0>; + fsl,tmu-range = <0x000a0000 0x00090026 0x0008004a 0x0001006a>; + fsl,tmu-calibration = <0x00000000 0x00000025 + 0x00000001 0x00000028 + 0x00000002 0x0000002d + 0x00000003 0x00000031 + 0x00000004 0x00000036 + 0x00000005 0x0000003a + 0x00000006 0x00000040 + 0x00000007 0x00000044 + 0x00000008 0x0000004a + 0x00000009 0x0000004f + 0x0000000a 0x00000054 + + 0x00010000 0x0000000d + 0x00010001 0x00000013 + 0x00010002 0x00000019 + 0x00010003 0x0000001f + 0x00010004 0x00000025 + 0x00010005 0x0000002d + 0x00010006 0x00000033 + 0x00010007 0x00000043 + 0x00010008 0x0000004b + 0x00010009 0x00000053 + + 0x00020000 0x00000010 + 0x00020001 0x00000017 + 0x00020002 0x0000001f + 0x00020003 0x00000029 + 0x00020004 0x00000031 + 0x00020005 0x0000003c + 0x00020006 0x00000042 + 0x00020007 0x0000004d + 0x00020008 0x00000056 + + 0x00030000 0x00000012 + 0x00030001 0x0000001d>; +}; -- GitLab From be489a3936349c5f68c8001f31580d697c474b98 Mon Sep 17 00:00:00 2001 From: Hongtao Jia Date: Tue, 24 Nov 2015 14:52:46 +0800 Subject: [PATCH 2047/2855] powerpc/mpc85xx: Add TMU device tree support for T1040/T1042 Also add nodes and properties for thermal management support. Meanwhile preprocessor support is needed using thermal of framework. Signed-off-by: Jia Hongtao Reviewed-by: Scott Wood Signed-off-by: Scott Wood --- arch/powerpc/boot/dts/fsl/t1040d4rdb.dts | 2 +- arch/powerpc/boot/dts/fsl/t1040qds.dts | 2 +- arch/powerpc/boot/dts/fsl/t1040rdb.dts | 2 +- arch/powerpc/boot/dts/fsl/t1040si-post.dtsi | 94 +++++++++++++++++++++ arch/powerpc/boot/dts/fsl/t1042d4rdb.dts | 2 +- arch/powerpc/boot/dts/fsl/t1042qds.dts | 2 +- arch/powerpc/boot/dts/fsl/t1042rdb.dts | 2 +- arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts | 2 +- arch/powerpc/boot/dts/fsl/t1042si-post.dtsi | 2 +- arch/powerpc/boot/dts/fsl/t104xsi-pre.dtsi | 4 + 10 files changed, 106 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/boot/dts/fsl/t1040d4rdb.dts b/arch/powerpc/boot/dts/fsl/t1040d4rdb.dts index 681746efd31dd..fb6bc02ebb606 100644 --- a/arch/powerpc/boot/dts/fsl/t1040d4rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t1040d4rdb.dts @@ -43,4 +43,4 @@ interrupt-parent = <&mpic>; }; -/include/ "t1040si-post.dtsi" +#include "t1040si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/t1040qds.dts b/arch/powerpc/boot/dts/fsl/t1040qds.dts index 4d298659468c7..5f76edc7838c1 100644 --- a/arch/powerpc/boot/dts/fsl/t1040qds.dts +++ b/arch/powerpc/boot/dts/fsl/t1040qds.dts @@ -43,4 +43,4 @@ interrupt-parent = <&mpic>; }; -/include/ "t1040si-post.dtsi" +#include "t1040si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/t1040rdb.dts b/arch/powerpc/boot/dts/fsl/t1040rdb.dts index 8f9e65b47515d..cf194154bbdce 100644 --- a/arch/powerpc/boot/dts/fsl/t1040rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t1040rdb.dts @@ -45,4 +45,4 @@ }; }; -/include/ "t1040si-post.dtsi" +#include "t1040si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi index d30b3de1cfc57..e0f4da5547740 100644 --- a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi @@ -32,6 +32,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include + &bman_fbpr { compatible = "fsl,bman-fbpr"; alloc-ranges = <0 0 0x10000 0>; @@ -484,6 +486,98 @@ reg = <0xea000 0x4000>; }; + tmu: tmu@f0000 { + compatible = "fsl,qoriq-tmu"; + reg = <0xf0000 0x1000>; + interrupts = <18 2 0 0>; + fsl,tmu-range = <0xa0000 0x90026 0x8004a 0x1006a>; + fsl,tmu-calibration = <0x00000000 0x00000025 + 0x00000001 0x00000028 + 0x00000002 0x0000002d + 0x00000003 0x00000031 + 0x00000004 0x00000036 + 0x00000005 0x0000003a + 0x00000006 0x00000040 + 0x00000007 0x00000044 + 0x00000008 0x0000004a + 0x00000009 0x0000004f + 0x0000000a 0x00000054 + + 0x00010000 0x0000000d + 0x00010001 0x00000013 + 0x00010002 0x00000019 + 0x00010003 0x0000001f + 0x00010004 0x00000025 + 0x00010005 0x0000002d + 0x00010006 0x00000033 + 0x00010007 0x00000043 + 0x00010008 0x0000004b + 0x00010009 0x00000053 + + 0x00020000 0x00000010 + 0x00020001 0x00000017 + 0x00020002 0x0000001f + 0x00020003 0x00000029 + 0x00020004 0x00000031 + 0x00020005 0x0000003c + 0x00020006 0x00000042 + 0x00020007 0x0000004d + 0x00020008 0x00000056 + + 0x00030000 0x00000012 + 0x00030001 0x0000001d>; + #thermal-sensor-cells = <0>; + }; + + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <1000>; + polling-delay = <5000>; + + thermal-sensors = <&tmu>; + + trips { + cpu_alert: cpu-alert { + temperature = <85000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu_crit: cpu-crit { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert>; + cooling-device = + <&cpu0 THERMAL_NO_LIMIT + THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu_alert>; + cooling-device = + <&cpu1 THERMAL_NO_LIMIT + THERMAL_NO_LIMIT>; + }; + map2 { + trip = <&cpu_alert>; + cooling-device = + <&cpu2 THERMAL_NO_LIMIT + THERMAL_NO_LIMIT>; + }; + map3 { + trip = <&cpu_alert>; + cooling-device = + <&cpu3 THERMAL_NO_LIMIT + THERMAL_NO_LIMIT>; + }; + }; + }; + }; + scfg: global-utilities@fc000 { compatible = "fsl,t1040-scfg"; reg = <0xfc000 0x1000>; diff --git a/arch/powerpc/boot/dts/fsl/t1042d4rdb.dts b/arch/powerpc/boot/dts/fsl/t1042d4rdb.dts index b245b31b8279e..2a5a90dd272e2 100644 --- a/arch/powerpc/boot/dts/fsl/t1042d4rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t1042d4rdb.dts @@ -50,4 +50,4 @@ }; }; -/include/ "t1040si-post.dtsi" +#include "t1042si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/t1042qds.dts b/arch/powerpc/boot/dts/fsl/t1042qds.dts index 4ab9bbe7c5c5b..90a4a73bb905d 100644 --- a/arch/powerpc/boot/dts/fsl/t1042qds.dts +++ b/arch/powerpc/boot/dts/fsl/t1042qds.dts @@ -43,4 +43,4 @@ interrupt-parent = <&mpic>; }; -/include/ "t1042si-post.dtsi" +#include "t1042si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/t1042rdb.dts b/arch/powerpc/boot/dts/fsl/t1042rdb.dts index 67af56bc5ee98..8d908e795e4db 100644 --- a/arch/powerpc/boot/dts/fsl/t1042rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t1042rdb.dts @@ -45,4 +45,4 @@ }; }; -/include/ "t1042si-post.dtsi" +#include "t1042si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts b/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts index 2f67677530a44..98c001019d6a3 100644 --- a/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts +++ b/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts @@ -54,4 +54,4 @@ }; }; -/include/ "t1042si-post.dtsi" +#include "t1042si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/t1042si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1042si-post.dtsi index 319b74f29724f..a5544f93689c7 100644 --- a/arch/powerpc/boot/dts/fsl/t1042si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/t1042si-post.dtsi @@ -32,6 +32,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/include/ "t1040si-post.dtsi" +#include "t1040si-post.dtsi" /* Place holder for ethernet related device tree nodes */ diff --git a/arch/powerpc/boot/dts/fsl/t104xsi-pre.dtsi b/arch/powerpc/boot/dts/fsl/t104xsi-pre.dtsi index fcfa38ae5e026..6db0ee8b1384f 100644 --- a/arch/powerpc/boot/dts/fsl/t104xsi-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/t104xsi-pre.dtsi @@ -76,6 +76,7 @@ reg = <0>; clocks = <&mux0>; next-level-cache = <&L2_1>; + #cooling-cells = <2>; L2_1: l2-cache { next-level-cache = <&cpc>; }; @@ -85,6 +86,7 @@ reg = <1>; clocks = <&mux1>; next-level-cache = <&L2_2>; + #cooling-cells = <2>; L2_2: l2-cache { next-level-cache = <&cpc>; }; @@ -94,6 +96,7 @@ reg = <2>; clocks = <&mux2>; next-level-cache = <&L2_3>; + #cooling-cells = <2>; L2_3: l2-cache { next-level-cache = <&cpc>; }; @@ -103,6 +106,7 @@ reg = <3>; clocks = <&mux3>; next-level-cache = <&L2_4>; + #cooling-cells = <2>; L2_4: l2-cache { next-level-cache = <&cpc>; }; -- GitLab From 3045e409e403b35ea4e30393a97cb913c745b38d Mon Sep 17 00:00:00 2001 From: Hongtao Jia Date: Tue, 24 Nov 2015 14:52:47 +0800 Subject: [PATCH 2048/2855] powerpc/mpc85xx: Add TMU device tree support for T1023/T1024 Also add nodes and properties for thermal management support. Meanwhile preprocessor support is needed using thermal of framework. Signed-off-by: Jia Hongtao Reviewed-by: Scott Wood Signed-off-by: Scott Wood --- arch/powerpc/boot/dts/fsl/t1023rdb.dts | 2 +- arch/powerpc/boot/dts/fsl/t1023si-post.dtsi | 86 +++++++++++++++++++++ arch/powerpc/boot/dts/fsl/t1024qds.dts | 2 +- arch/powerpc/boot/dts/fsl/t1024rdb.dts | 2 +- arch/powerpc/boot/dts/fsl/t1024si-post.dtsi | 2 +- arch/powerpc/boot/dts/fsl/t102xsi-pre.dtsi | 2 + 6 files changed, 92 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/boot/dts/fsl/t1023rdb.dts b/arch/powerpc/boot/dts/fsl/t1023rdb.dts index 2b2fff4a12a2f..6bd842beb1dcf 100644 --- a/arch/powerpc/boot/dts/fsl/t1023rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t1023rdb.dts @@ -159,4 +159,4 @@ }; }; -/include/ "t1023si-post.dtsi" +#include "t1023si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi index 518ddaa8da2de..99e421df79d4c 100644 --- a/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi @@ -32,6 +32,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include + &ifc { #address-cells = <2>; #size-cells = <1>; @@ -275,6 +277,90 @@ reg = <0xea000 0x4000>; }; + tmu: tmu@f0000 { + compatible = "fsl,qoriq-tmu"; + reg = <0xf0000 0x1000>; + interrupts = <18 2 0 0>; + fsl,tmu-range = <0xb0000 0xa0026 0x80048 0x30061>; + fsl,tmu-calibration = <0x00000000 0x0000000f + 0x00000001 0x00000017 + 0x00000002 0x0000001e + 0x00000003 0x00000026 + 0x00000004 0x0000002e + 0x00000005 0x00000035 + 0x00000006 0x0000003d + 0x00000007 0x00000044 + 0x00000008 0x0000004c + 0x00000009 0x00000053 + 0x0000000a 0x0000005b + 0x0000000b 0x00000064 + + 0x00010000 0x00000011 + 0x00010001 0x0000001c + 0x00010002 0x00000024 + 0x00010003 0x0000002b + 0x00010004 0x00000034 + 0x00010005 0x00000039 + 0x00010006 0x00000042 + 0x00010007 0x0000004c + 0x00010008 0x00000051 + 0x00010009 0x0000005a + 0x0001000a 0x00000063 + + 0x00020000 0x00000013 + 0x00020001 0x00000019 + 0x00020002 0x00000024 + 0x00020003 0x0000002c + 0x00020004 0x00000035 + 0x00020005 0x0000003d + 0x00020006 0x00000046 + 0x00020007 0x00000050 + 0x00020008 0x00000059 + + 0x00030000 0x00000002 + 0x00030001 0x0000000d + 0x00030002 0x00000019 + 0x00030003 0x00000024>; + #thermal-sensor-cells = <0>; + }; + + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <1000>; + polling-delay = <5000>; + + thermal-sensors = <&tmu>; + + trips { + cpu_alert: cpu-alert { + temperature = <85000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu_crit: cpu-crit { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert>; + cooling-device = + <&cpu0 THERMAL_NO_LIMIT + THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu_alert>; + cooling-device = + <&cpu1 THERMAL_NO_LIMIT + THERMAL_NO_LIMIT>; + }; + }; + }; + }; + scfg: global-utilities@fc000 { compatible = "fsl,t1023-scfg"; reg = <0xfc000 0x1000>; diff --git a/arch/powerpc/boot/dts/fsl/t1024qds.dts b/arch/powerpc/boot/dts/fsl/t1024qds.dts index 43cd5b50cd0aa..6a3581b8e1f85 100644 --- a/arch/powerpc/boot/dts/fsl/t1024qds.dts +++ b/arch/powerpc/boot/dts/fsl/t1024qds.dts @@ -248,4 +248,4 @@ }; }; -/include/ "t1024si-post.dtsi" +#include "t1024si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/t1024rdb.dts b/arch/powerpc/boot/dts/fsl/t1024rdb.dts index 429d8c73650a3..0ccc7d03335eb 100644 --- a/arch/powerpc/boot/dts/fsl/t1024rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t1024rdb.dts @@ -188,4 +188,4 @@ }; }; -/include/ "t1024si-post.dtsi" +#include "t1024si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/t1024si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1024si-post.dtsi index 95e3af8d768e3..bb480346a58d8 100644 --- a/arch/powerpc/boot/dts/fsl/t1024si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/t1024si-post.dtsi @@ -32,7 +32,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/include/ "t1023si-post.dtsi" +#include "t1023si-post.dtsi" / { aliases { diff --git a/arch/powerpc/boot/dts/fsl/t102xsi-pre.dtsi b/arch/powerpc/boot/dts/fsl/t102xsi-pre.dtsi index 3e1528abf3f47..9d08a363bab32 100644 --- a/arch/powerpc/boot/dts/fsl/t102xsi-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/t102xsi-pre.dtsi @@ -76,6 +76,7 @@ reg = <0>; clocks = <&mux0>; next-level-cache = <&L2_1>; + #cooling-cells = <2>; L2_1: l2-cache { next-level-cache = <&cpc>; }; @@ -85,6 +86,7 @@ reg = <1>; clocks = <&mux1>; next-level-cache = <&L2_2>; + #cooling-cells = <2>; L2_2: l2-cache { next-level-cache = <&cpc>; }; -- GitLab From e46fed9fb3a12b1070e2cc5ad03a21b84f94408d Mon Sep 17 00:00:00 2001 From: "Felipe F. Tonello" Date: Fri, 18 Sep 2015 18:30:19 +0100 Subject: [PATCH 2049/2855] usb: chipidea: udc: _ep_queue and _hw_queue cleanup Update comments to reflect current state of functions. Signed-off-by: Felipe F. Tonello Signed-off-by: Peter Chen --- drivers/usb/chipidea/udc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index b292b454c77ba..d917b3f27ddb1 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -403,9 +403,9 @@ static inline u8 _usb_addr(struct ci_hw_ep *ep) } /** - * _hardware_queue: configures a request at hardware level - * @gadget: gadget + * _hardware_enqueue: configures a request at hardware level * @hwep: endpoint + * @hwreq: request * * This function returns an error code */ @@ -787,8 +787,12 @@ static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req) /** * _ep_queue: queues (submits) an I/O request to an endpoint + * @ep: endpoint + * @req: request + * @gfp_flags: GFP flags (not used) * * Caller must hold lock + * This function returns an error code */ static int _ep_queue(struct usb_ep *ep, struct usb_request *req, gfp_t __maybe_unused gfp_flags) -- GitLab From 779debdf26d4b49598e61e0c28ac97146a2b96fe Mon Sep 17 00:00:00 2001 From: "Felipe F. Tonello" Date: Tue, 27 Oct 2015 10:36:32 +0000 Subject: [PATCH 2050/2855] usb: chipidea: udc: improve error handling on _hardware_enqueue _hardware_enqueue() didn't check for errors when using add_td_to_list() which can fail if dma_pool_alloc fails, thus causing a kernel panic when lastnode->ptr is NULL. Signed-off-by: Felipe F. Tonello Signed-off-by: Peter Chen --- drivers/usb/chipidea/udc.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index d917b3f27ddb1..b1e7b716e8c97 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -434,19 +434,28 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) if (hwreq->req.dma % PAGE_SIZE) pages--; - if (rest == 0) - add_td_to_list(hwep, hwreq, 0); + if (rest == 0) { + ret = add_td_to_list(hwep, hwreq, 0); + if (ret < 0) + goto done; + } while (rest > 0) { unsigned count = min(hwreq->req.length - hwreq->req.actual, (unsigned)(pages * CI_HDRC_PAGE_SIZE)); - add_td_to_list(hwep, hwreq, count); + ret = add_td_to_list(hwep, hwreq, count); + if (ret < 0) + goto done; + rest -= count; } if (hwreq->req.zero && hwreq->req.length && hwep->dir == TX - && (hwreq->req.length % hwep->ep.maxpacket == 0)) - add_td_to_list(hwep, hwreq, 0); + && (hwreq->req.length % hwep->ep.maxpacket == 0)) { + ret = add_td_to_list(hwep, hwreq, 0); + if (ret < 0) + goto done; + } firstnode = list_first_entry(&hwreq->tds, struct td_node, td); -- GitLab From 9d8c850d02b01f3e0157a8f9859fe3f04cab68fe Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 23 Oct 2015 10:33:58 +0800 Subject: [PATCH 2051/2855] usb: chipidea: support debugfs without CONFIG_USB_CHIPIDEA_DEBUG Since we need to mount debugfs to show/store the things we want to debug, it is duplicated to add another configuration to enable it. Meanwhile, with CONFIG_USB_CHIPIDEA_DEBUG, we can't support chipidea debugfs at runtime. Signed-off-by: Peter Chen Cc: Jun Li --- drivers/usb/chipidea/Makefile | 3 +-- drivers/usb/chipidea/ci.h | 3 +++ drivers/usb/chipidea/core.c | 1 - drivers/usb/chipidea/debug.c | 1 - drivers/usb/chipidea/debug.h | 30 ------------------------------ drivers/usb/chipidea/udc.c | 1 - 6 files changed, 4 insertions(+), 35 deletions(-) delete mode 100644 drivers/usb/chipidea/debug.h diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile index 4decb12f25786..c437d5f1a0d52 100644 --- a/drivers/usb/chipidea/Makefile +++ b/drivers/usb/chipidea/Makefile @@ -2,10 +2,9 @@ ccflags-$(CONFIG_USB_CHIPIDEA_DEBUG) := -DDEBUG obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc.o -ci_hdrc-y := core.o otg.o +ci_hdrc-y := core.o otg.o debug.o ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC) += udc.o ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST) += host.o -ci_hdrc-$(CONFIG_USB_CHIPIDEA_DEBUG) += debug.o ci_hdrc-$(CONFIG_USB_OTG_FSM) += otg_fsm.o # Glue/Bridge layers go here diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index 41d7cf6d63ba3..cd414559040f1 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -433,4 +433,7 @@ int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask, void ci_platform_configure(struct ci_hdrc *ci); +int dbg_create_files(struct ci_hdrc *ci); + +void dbg_remove_files(struct ci_hdrc *ci); #endif /* __DRIVERS_USB_CHIPIDEA_CI_H */ diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 965d0e240dcb2..18e77e02842b9 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -71,7 +71,6 @@ #include "udc.h" #include "bits.h" #include "host.h" -#include "debug.h" #include "otg.h" #include "otg_fsm.h" diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 58c8485a0715a..a4f7db2e18ddc 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -15,7 +15,6 @@ #include "ci.h" #include "udc.h" #include "bits.h" -#include "debug.h" #include "otg.h" /** diff --git a/drivers/usb/chipidea/debug.h b/drivers/usb/chipidea/debug.h deleted file mode 100644 index e16478c4a943a..0000000000000 --- a/drivers/usb/chipidea/debug.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * debug.h - ChipIdea USB driver debug interfaces - * - * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved. - * - * Author: David Lopo - * - * 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. - */ - -#ifndef __DRIVERS_USB_CHIPIDEA_DEBUG_H -#define __DRIVERS_USB_CHIPIDEA_DEBUG_H - -#ifdef CONFIG_USB_CHIPIDEA_DEBUG -int dbg_create_files(struct ci_hdrc *ci); -void dbg_remove_files(struct ci_hdrc *ci); -#else -static inline int dbg_create_files(struct ci_hdrc *ci) -{ - return 0; -} - -static inline void dbg_remove_files(struct ci_hdrc *ci) -{ -} -#endif - -#endif /* __DRIVERS_USB_CHIPIDEA_DEBUG_H */ diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index b1e7b716e8c97..3eafa2c9a2ba4 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -26,7 +26,6 @@ #include "ci.h" #include "udc.h" #include "bits.h" -#include "debug.h" #include "otg.h" #include "otg_fsm.h" -- GitLab From 383da2450c7150b4c470dab3759ab86532c65b78 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 27 Oct 2015 16:08:30 +0800 Subject: [PATCH 2052/2855] usb: chipidea: delete static debug support Since we have dynamic debug support, delete static debug for chipidea Signed-off-by: Peter Chen --- drivers/usb/chipidea/Kconfig | 5 ----- drivers/usb/chipidea/Makefile | 2 -- 2 files changed, 7 deletions(-) diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig index 5619b8ca3bf3f..3644a3500b700 100644 --- a/drivers/usb/chipidea/Kconfig +++ b/drivers/usb/chipidea/Kconfig @@ -37,9 +37,4 @@ config USB_CHIPIDEA_HOST Say Y here to enable host controller functionality of the ChipIdea driver. -config USB_CHIPIDEA_DEBUG - bool "ChipIdea driver debug" - help - Say Y here to enable debugging output of the ChipIdea driver. - endif diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile index c437d5f1a0d52..518e445476c3f 100644 --- a/drivers/usb/chipidea/Makefile +++ b/drivers/usb/chipidea/Makefile @@ -1,5 +1,3 @@ -ccflags-$(CONFIG_USB_CHIPIDEA_DEBUG) := -DDEBUG - obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc.o ci_hdrc-y := core.o otg.o debug.o -- GitLab From 3a35d59a69398b3b522d449404669624486d2b68 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 3 Nov 2015 16:21:20 +0800 Subject: [PATCH 2053/2855] usb: chipidea: clean up CONFIG_USB_CHIPIDEA_DEBUG reference Since this configuration option has deleted, cleans up all its references. Signed-off-by: Peter Chen Reported-by: Valentin Rothberg --- Documentation/usb/chipidea.txt | 4 ++-- drivers/usb/chipidea/core.c | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Documentation/usb/chipidea.txt b/Documentation/usb/chipidea.txt index 3f848c1f2940d..05f735a1b5a57 100644 --- a/Documentation/usb/chipidea.txt +++ b/Documentation/usb/chipidea.txt @@ -7,8 +7,8 @@ with 2 Freescale i.MX6Q sabre SD boards. --------------------------------------- Select CONFIG_USB_OTG_FSM, rebuild kernel Image and modules. If you want to check some internal variables for otg fsm, -select CONFIG_USB_CHIPIDEA_DEBUG, there are 2 files which -can show otg fsm variables and some controller registers value: +mount debugfs, there are 2 files which can show otg fsm +variables and some controller registers value: cat /sys/kernel/debug/ci_hdrc.0/otg cat /sys/kernel/debug/ci_hdrc.0/registers diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 18e77e02842b9..3a237d03260c4 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -23,7 +23,6 @@ * - BUS: bus glue code, bus abstraction layer * * Compile Options - * - CONFIG_USB_CHIPIDEA_DEBUG: enable debug facilities * - STALL_IN: non-empty bulk-in pipes cannot be halted * if defined mass storage compliance succeeds but with warnings * => case 4: Hi > Dn -- GitLab From b09b5224fe86b3c9adef1bd9f0bd81800e8ff0b3 Mon Sep 17 00:00:00 2001 From: Andreas Fenkart Date: Thu, 12 Nov 2015 14:14:40 +0100 Subject: [PATCH 2054/2855] usb: chipidea: implement platform shutdown callback disable wakeup irq during shutdown, otherwise kexec fails for kernels that setup irq handlers before resetting the hardware Signed-off-by: Andreas Fenkart Signed-off-by: Peter Chen --- drivers/usb/chipidea/ci_hdrc_imx.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 5a048b7b92e8f..f14f4ab47ebb8 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -345,6 +345,11 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev) return 0; } +static void ci_hdrc_imx_shutdown(struct platform_device *pdev) +{ + ci_hdrc_imx_remove(pdev); +} + #ifdef CONFIG_PM static int imx_controller_suspend(struct device *dev) { @@ -462,6 +467,7 @@ static const struct dev_pm_ops ci_hdrc_imx_pm_ops = { static struct platform_driver ci_hdrc_imx_driver = { .probe = ci_hdrc_imx_probe, .remove = ci_hdrc_imx_remove, + .shutdown = ci_hdrc_imx_shutdown, .driver = { .name = "imx_usb", .of_match_table = ci_hdrc_imx_dt_ids, -- GitLab From 4b19b78aa6f1f57a997d93fa05df6724792a85ba Mon Sep 17 00:00:00 2001 From: Saurabh Sengar Date: Wed, 18 Nov 2015 09:40:12 +0530 Subject: [PATCH 2055/2855] usb: chipidea: removing of_find_property call to of_find_property() before of_property_read_u32() is unnecessary. of_property_read_u32() anyway calls to of_find_property() only. Signed-off-by: Saurabh Sengar Signed-off-by: Peter Chen --- drivers/usb/chipidea/core.c | 57 ++++++++++++++----------------------- 1 file changed, 22 insertions(+), 35 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 3a237d03260c4..7404064b9bbcb 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -686,52 +686,39 @@ static int ci_get_platdata(struct device *dev, if (usb_get_maximum_speed(dev) == USB_SPEED_FULL) platdata->flags |= CI_HDRC_FORCE_FULLSPEED; - if (of_find_property(dev->of_node, "phy-clkgate-delay-us", NULL)) - of_property_read_u32(dev->of_node, "phy-clkgate-delay-us", + of_property_read_u32(dev->of_node, "phy-clkgate-delay-us", &platdata->phy_clkgate_delay_us); platdata->itc_setting = 1; - if (of_find_property(dev->of_node, "itc-setting", NULL)) { - ret = of_property_read_u32(dev->of_node, "itc-setting", - &platdata->itc_setting); - if (ret) { - dev_err(dev, - "failed to get itc-setting\n"); - return ret; - } - } - if (of_find_property(dev->of_node, "ahb-burst-config", NULL)) { - ret = of_property_read_u32(dev->of_node, "ahb-burst-config", - &platdata->ahb_burst_config); - if (ret) { - dev_err(dev, - "failed to get ahb-burst-config\n"); - return ret; - } + of_property_read_u32(dev->of_node, "itc-setting", + &platdata->itc_setting); + + ret = of_property_read_u32(dev->of_node, "ahb-burst-config", + &platdata->ahb_burst_config); + if (!ret) { platdata->flags |= CI_HDRC_OVERRIDE_AHB_BURST; + } else if (ret != -EINVAL) { + dev_err(dev, "failed to get ahb-burst-config\n"); + return ret; } - if (of_find_property(dev->of_node, "tx-burst-size-dword", NULL)) { - ret = of_property_read_u32(dev->of_node, "tx-burst-size-dword", - &platdata->tx_burst_size); - if (ret) { - dev_err(dev, - "failed to get tx-burst-size-dword\n"); - return ret; - } + ret = of_property_read_u32(dev->of_node, "tx-burst-size-dword", + &platdata->tx_burst_size); + if (!ret) { platdata->flags |= CI_HDRC_OVERRIDE_TX_BURST; + } else if (ret != -EINVAL) { + dev_err(dev, "failed to get tx-burst-size-dword\n"); + return ret; } - if (of_find_property(dev->of_node, "rx-burst-size-dword", NULL)) { - ret = of_property_read_u32(dev->of_node, "rx-burst-size-dword", - &platdata->rx_burst_size); - if (ret) { - dev_err(dev, - "failed to get rx-burst-size-dword\n"); - return ret; - } + ret = of_property_read_u32(dev->of_node, "rx-burst-size-dword", + &platdata->rx_burst_size); + if (!ret) { platdata->flags |= CI_HDRC_OVERRIDE_RX_BURST; + } else if (ret != -EINVAL) { + dev_err(dev, "failed to get rx-burst-size-dword\n"); + return ret; } ext_id = ERR_PTR(-ENODEV); -- GitLab From 43a404577a93d236913b67e41758adf5b9a8f45d Mon Sep 17 00:00:00 2001 From: Li Jun Date: Tue, 15 Dec 2015 17:47:47 +0800 Subject: [PATCH 2056/2855] usb: chipidea: host: set host to be null after hcd is freed Set ci->hcd and ci->otg.host to be null in host_stop since the hcd already freed. Signed-off-by: Li Jun Signed-off-by: Peter Chen --- drivers/usb/chipidea/host.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index 3d24304405b36..053bac9d983cb 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -190,6 +190,8 @@ static void host_stop(struct ci_hdrc *ci) (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON)) regulator_disable(ci->platdata->reg_vbus); } + ci->hcd = NULL; + ci->otg.host = NULL; } -- GitLab From 8c100e74409ad3bbcb8a1ccdff4540fc0aa7a0fc Mon Sep 17 00:00:00 2001 From: Li Jun Date: Tue, 15 Dec 2015 17:51:29 +0800 Subject: [PATCH 2057/2855] usb: chipidea: otg: use usb autosuspend to suspend bus for HNP Directly manipulate the controller regsiter to suspend the usb bus for HNP is not the proper way, this should be done through the usbcore by usb autosuspend. So to start HNP, autosuspend support should be added for OTG devices interface driver if it's not enabled. Signed-off-by: Li Jun Signed-off-by: Peter Chen --- drivers/usb/chipidea/otg_fsm.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index 00ab59d45da1b..ba90dc66703de 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -485,20 +485,30 @@ static void ci_otg_loc_conn(struct otg_fsm *fsm, int on) /* * Generate SOF by host. - * This is controlled through suspend/resume the port. * In host mode, controller will automatically send SOF. * Suspend will block the data on the port. + * + * This is controlled through usbcore by usb autosuspend, + * so the usb device class driver need support autosuspend, + * otherwise the bus suspend will not happen. */ static void ci_otg_loc_sof(struct otg_fsm *fsm, int on) { - struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm); + struct usb_device *udev; - if (on) - hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_FPR, - PORTSC_FPR); - else - hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_SUSP, - PORTSC_SUSP); + if (!fsm->otg->host) + return; + + udev = usb_hub_find_child(fsm->otg->host->root_hub, 1); + if (!udev) + return; + + if (on) { + usb_disable_autosuspend(udev); + } else { + pm_runtime_set_autosuspend_delay(&udev->dev, 0); + usb_enable_autosuspend(udev); + } } /* -- GitLab From 3fa962686568a1617d174e3d2f5d522e963077c5 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 13 Dec 2015 11:35:52 -0800 Subject: [PATCH 2058/2855] libnvdimm, pfn: fix nd_pfn_validate() return value handling The -ENODEV case indicates that the info-block needs to established. All other return codes cause nd_pfn_init() to abort. Signed-off-by: Dan Williams --- drivers/nvdimm/pmem.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index dc6866734f70f..ab689bca727d9 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -238,7 +238,9 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) nd_pfn->pfn_sb = pfn_sb; rc = nd_pfn_validate(nd_pfn); - if (rc == 0 || rc == -EBUSY) + if (rc == -ENODEV) + /* no info block, do init */; + else return rc; nd_region = to_nd_region(nd_pfn->dev.parent); -- GitLab From 9bfa84969dd52bf0aa635c4c8a67c81d75ffca37 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 11 Dec 2015 11:20:16 -0800 Subject: [PATCH 2059/2855] tools/testing/libnvdimm: cleanup mock resource lookup Push the locking around get_nfit_res() into get_nfit_res(). Signed-off-by: Dan Williams --- tools/testing/nvdimm/test/iomap.c | 69 +++++++++++-------------------- 1 file changed, 23 insertions(+), 46 deletions(-) diff --git a/tools/testing/nvdimm/test/iomap.c b/tools/testing/nvdimm/test/iomap.c index 79e110d4a81a1..7ec7df9e7fc73 100644 --- a/tools/testing/nvdimm/test/iomap.c +++ b/tools/testing/nvdimm/test/iomap.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "nfit_test.h" static LIST_HEAD(iomap_head); @@ -41,7 +42,7 @@ void nfit_test_teardown(void) } EXPORT_SYMBOL(nfit_test_teardown); -static struct nfit_test_resource *get_nfit_res(resource_size_t resource) +static struct nfit_test_resource *__get_nfit_res(resource_size_t resource) { struct iomap_ops *ops; @@ -51,14 +52,22 @@ static struct nfit_test_resource *get_nfit_res(resource_size_t resource) return NULL; } -void __iomem *__nfit_test_ioremap(resource_size_t offset, unsigned long size, - void __iomem *(*fallback_fn)(resource_size_t, unsigned long)) +static struct nfit_test_resource *get_nfit_res(resource_size_t resource) { - struct nfit_test_resource *nfit_res; + struct nfit_test_resource *res; rcu_read_lock(); - nfit_res = get_nfit_res(offset); + res = __get_nfit_res(resource); rcu_read_unlock(); + + return res; +} + +void __iomem *__nfit_test_ioremap(resource_size_t offset, unsigned long size, + void __iomem *(*fallback_fn)(resource_size_t, unsigned long)) +{ + struct nfit_test_resource *nfit_res = get_nfit_res(offset); + if (nfit_res) return (void __iomem *) nfit_res->buf + offset - nfit_res->res->start; @@ -68,11 +77,8 @@ void __iomem *__nfit_test_ioremap(resource_size_t offset, unsigned long size, void __iomem *__wrap_devm_ioremap_nocache(struct device *dev, resource_size_t offset, unsigned long size) { - struct nfit_test_resource *nfit_res; + struct nfit_test_resource *nfit_res = get_nfit_res(offset); - rcu_read_lock(); - nfit_res = get_nfit_res(offset); - rcu_read_unlock(); if (nfit_res) return (void __iomem *) nfit_res->buf + offset - nfit_res->res->start; @@ -83,11 +89,8 @@ EXPORT_SYMBOL(__wrap_devm_ioremap_nocache); void *__wrap_devm_memremap(struct device *dev, resource_size_t offset, size_t size, unsigned long flags) { - struct nfit_test_resource *nfit_res; + struct nfit_test_resource *nfit_res = get_nfit_res(offset); - rcu_read_lock(); - nfit_res = get_nfit_res(offset); - rcu_read_unlock(); if (nfit_res) return nfit_res->buf + offset - nfit_res->res->start; return devm_memremap(dev, offset, size, flags); @@ -102,11 +105,8 @@ void *__wrap_devm_memremap_pages(struct device *dev, struct resource *res, struct percpu_ref *ref, struct vmem_altmap *altmap) { resource_size_t offset = res->start; - struct nfit_test_resource *nfit_res; + struct nfit_test_resource *nfit_res = get_nfit_res(offset); - rcu_read_lock(); - nfit_res = get_nfit_res(offset); - rcu_read_unlock(); if (nfit_res) return nfit_res->buf + offset - nfit_res->res->start; return devm_memremap_pages(dev, res, ref, altmap); @@ -115,11 +115,8 @@ EXPORT_SYMBOL(__wrap_devm_memremap_pages); pfn_t __wrap_phys_to_pfn_t(dma_addr_t addr, unsigned long flags) { - struct nfit_test_resource *nfit_res; + struct nfit_test_resource *nfit_res = get_nfit_res(addr); - rcu_read_lock(); - nfit_res = get_nfit_res(addr); - rcu_read_unlock(); if (nfit_res) flags &= ~PFN_MAP; return phys_to_pfn_t(addr, flags); @@ -130,11 +127,8 @@ EXPORT_SYMBOL(__wrap_phys_to_pfn_t); void *__wrap_devm_memremap_pages(struct device *dev, struct resource *res) { resource_size_t offset = res->start; - struct nfit_test_resource *nfit_res; + struct nfit_test_resource *nfit_res = get_nfit_res(offset); - rcu_read_lock(); - nfit_res = get_nfit_res(offset); - rcu_read_unlock(); if (nfit_res) return nfit_res->buf + offset - nfit_res->res->start; return devm_memremap_pages(dev, res); @@ -145,11 +139,8 @@ EXPORT_SYMBOL(__wrap_devm_memremap_pages); void *__wrap_memremap(resource_size_t offset, size_t size, unsigned long flags) { - struct nfit_test_resource *nfit_res; + struct nfit_test_resource *nfit_res = get_nfit_res(offset); - rcu_read_lock(); - nfit_res = get_nfit_res(offset); - rcu_read_unlock(); if (nfit_res) return nfit_res->buf + offset - nfit_res->res->start; return memremap(offset, size, flags); @@ -158,11 +149,8 @@ EXPORT_SYMBOL(__wrap_memremap); void __wrap_devm_memunmap(struct device *dev, void *addr) { - struct nfit_test_resource *nfit_res; + struct nfit_test_resource *nfit_res = get_nfit_res((long) addr); - rcu_read_lock(); - nfit_res = get_nfit_res((unsigned long) addr); - rcu_read_unlock(); if (nfit_res) return; return devm_memunmap(dev, addr); @@ -183,11 +171,7 @@ EXPORT_SYMBOL(__wrap_ioremap_wc); void __wrap_iounmap(volatile void __iomem *addr) { - struct nfit_test_resource *nfit_res; - - rcu_read_lock(); - nfit_res = get_nfit_res((unsigned long) addr); - rcu_read_unlock(); + struct nfit_test_resource *nfit_res = get_nfit_res((long) addr); if (nfit_res) return; return iounmap(addr); @@ -196,11 +180,8 @@ EXPORT_SYMBOL(__wrap_iounmap); void __wrap_memunmap(void *addr) { - struct nfit_test_resource *nfit_res; + struct nfit_test_resource *nfit_res = get_nfit_res((long) addr); - rcu_read_lock(); - nfit_res = get_nfit_res((unsigned long) addr); - rcu_read_unlock(); if (nfit_res) return; return memunmap(addr); @@ -214,9 +195,7 @@ static struct resource *nfit_test_request_region(struct device *dev, struct nfit_test_resource *nfit_res; if (parent == &iomem_resource) { - rcu_read_lock(); nfit_res = get_nfit_res(start); - rcu_read_unlock(); if (nfit_res) { struct resource *res = nfit_res->res + 1; @@ -266,9 +245,7 @@ void __wrap___release_region(struct resource *parent, resource_size_t start, struct nfit_test_resource *nfit_res; if (parent == &iomem_resource) { - rcu_read_lock(); nfit_res = get_nfit_res(start); - rcu_read_unlock(); if (nfit_res) { struct resource *res = nfit_res->res + 1; -- GitLab From 0731de0dd95b251ed6cfb5f132486e52357fce53 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 14 Dec 2015 15:34:15 -0800 Subject: [PATCH 2060/2855] libnvdimm, pfn: move 'memory mode' indication to sysfs 'Memory mode' is defined as the capability of a DAX mapping to be the source/target of DMA and other "direct I/O" scenarios. While it currently requires allocating 'struct page' for each page frame of persistent memory in the namespace it will not always be the case. Work continues on reducing the kernel's dependency on 'struct page'. Let's not maintain a suffix that is expected to lose meaning over time. In other words a future 'raw mode' pmem namespace may be as capable as today's 'memory mode' namespace. Undo the encoding of the mode in the device name and leave it to other tooling to determine the mode of the namespace from its attributes. Reported-by: Matthew Wilcox Signed-off-by: Dan Williams --- drivers/nvdimm/namespace_devs.c | 41 ++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index ea8dd0cb28ca2..ee6dee41155a3 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -104,20 +104,10 @@ const char *nvdimm_namespace_disk_name(struct nd_namespace_common *ndns, struct nd_region *nd_region = to_nd_region(ndns->dev.parent); const char *suffix = NULL; - if (ndns->claim) { - if (is_nd_btt(ndns->claim)) - suffix = "s"; - else if (is_nd_pfn(ndns->claim)) - suffix = "m"; - else - dev_WARN_ONCE(&ndns->dev, 1, - "unknown claim type by %s\n", - dev_name(ndns->claim)); - } + if (ndns->claim && is_nd_btt(ndns->claim)) + suffix = "s"; if (is_namespace_pmem(&ndns->dev) || is_namespace_io(&ndns->dev)) { - if (!suffix && pmem_should_map_pages(&ndns->dev)) - suffix = "m"; sprintf(name, "pmem%d%s", nd_region->id, suffix ? suffix : ""); } else if (is_namespace_blk(&ndns->dev)) { struct nd_namespace_blk *nsblk; @@ -1224,6 +1214,29 @@ static ssize_t holder_show(struct device *dev, } static DEVICE_ATTR_RO(holder); +static ssize_t mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nd_namespace_common *ndns = to_ndns(dev); + struct device *claim; + char *mode; + ssize_t rc; + + device_lock(dev); + claim = ndns->claim; + if (pmem_should_map_pages(dev) || (claim && is_nd_pfn(claim))) + mode = "memory"; + else if (claim && is_nd_btt(claim)) + mode = "safe"; + else + mode = "raw"; + rc = sprintf(buf, "%s\n", mode); + device_unlock(dev); + + return rc; +} +static DEVICE_ATTR_RO(mode); + static ssize_t force_raw_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { @@ -1247,6 +1260,7 @@ static DEVICE_ATTR_RW(force_raw); static struct attribute *nd_namespace_attributes[] = { &dev_attr_nstype.attr, &dev_attr_size.attr, + &dev_attr_mode.attr, &dev_attr_uuid.attr, &dev_attr_holder.attr, &dev_attr_resource.attr, @@ -1280,7 +1294,8 @@ static umode_t namespace_visible(struct kobject *kobj, if (a == &dev_attr_nstype.attr || a == &dev_attr_size.attr || a == &dev_attr_holder.attr - || a == &dev_attr_force_raw.attr) + || a == &dev_attr_force_raw.attr + || a == &dev_attr_mode.attr) return a->mode; return 0; -- GitLab From 2bc29a1abc5c1b89576f8ae864cce9c07d18fd44 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 25 Nov 2015 16:09:10 +0100 Subject: [PATCH 2061/2855] staging: gdm72xx: Replace timeval with ktime_t struct sdu_stamp in the gdm_sdio.h is a timeval type. 'struct timeval now' is used for calculating elapsed time. 32-bit systems using 'struct timeval' will break in the year 2038, so we have to replace that code with more appropriate types. This patch changes the gdm72xx driver to use ktime_t. ktime_get() is better than using do_gettimeofday(), because it uses the monotonic clock. ktime_sub are used to subtract two ktime variables. Build tested this by saying Y to WIMAX_GDM72XX. Signed-off-by: Tapasweni Pathak Reviewed-by: Arnd Bergmann Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_sdio.c | 13 ++++++------- drivers/staging/gdm72xx/gdm_sdio.h | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_sdio.c b/drivers/staging/gdm72xx/gdm_sdio.c index b0521da3c7931..1f5a087723bae 100644 --- a/drivers/staging/gdm72xx/gdm_sdio.c +++ b/drivers/staging/gdm72xx/gdm_sdio.c @@ -36,7 +36,7 @@ #define RX_BUF_SIZE (25*1024) #define TX_HZ 2000 -#define TX_INTERVAL (1000000/TX_HZ) +#define TX_INTERVAL (NSEC_PER_SEC/TX_HZ) static struct sdio_tx *alloc_tx_struct(struct tx_cxt *tx) { @@ -303,7 +303,7 @@ static void send_sdu(struct sdio_func *func, struct tx_cxt *tx) put_tx_struct(t->tx_cxt, t); } - do_gettimeofday(&tx->sdu_stamp); + tx->sdu_stamp = ktime_get(); spin_unlock_irqrestore(&tx->lock, flags); } @@ -330,7 +330,7 @@ static void do_tx(struct work_struct *work) struct sdio_func *func = sdev->func; struct tx_cxt *tx = &sdev->tx; struct sdio_tx *t = NULL; - struct timeval now, *before; + ktime_t now, before; int is_sdu = 0; long diff; unsigned long flags; @@ -346,11 +346,10 @@ static void do_tx(struct work_struct *work) list_del(&t->list); is_sdu = 0; } else if (!tx->stop_sdu_tx && !list_empty(&tx->sdu_list)) { - do_gettimeofday(&now); - before = &tx->sdu_stamp; + now = ktime_get(); + before = tx->sdu_stamp; - diff = (now.tv_sec - before->tv_sec) * 1000000 + - (now.tv_usec - before->tv_usec); + diff = ktime_to_ns(ktime_sub(now, before)); if (diff >= 0 && diff < TX_INTERVAL) { schedule_work(&sdev->ws); spin_unlock_irqrestore(&tx->lock, flags); diff --git a/drivers/staging/gdm72xx/gdm_sdio.h b/drivers/staging/gdm72xx/gdm_sdio.h index 77ad9d686f8e2..aa7dad22a219d 100644 --- a/drivers/staging/gdm72xx/gdm_sdio.h +++ b/drivers/staging/gdm72xx/gdm_sdio.h @@ -15,7 +15,7 @@ #define __GDM72XX_GDM_SDIO_H__ #include -#include +#include #define MAX_NR_SDU_BUF 64 @@ -32,7 +32,7 @@ struct tx_cxt { struct list_head free_list; struct list_head sdu_list; struct list_head hci_list; - struct timeval sdu_stamp; + ktime_t sdu_stamp; u8 *sdu_buf; spinlock_t lock; int can_send; -- GitLab From d1052aa5692d08aa4a058507ff5721317d2bef75 Mon Sep 17 00:00:00 2001 From: Wim de With Date: Fri, 11 Dec 2015 10:25:13 +0100 Subject: [PATCH 2062/2855] staging: gdm72xx: add userspace data struct This fixes the sparse warnings about dereferencing a userspace pointer. Once I updated the sparse annotations, I noticed a bug in gdm_wimax_ioctl() where we pass a user space pointer to gdm_update_fsm() which dereferences it. I fixed this. Signed-off-by: Wim de With Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_wimax.c | 12 ++++++++---- drivers/staging/gdm72xx/wm_ioctl.h | 7 ++++++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c index b8eea21f26557..ba03f9386567a 100644 --- a/drivers/staging/gdm72xx/gdm_wimax.c +++ b/drivers/staging/gdm72xx/gdm_wimax.c @@ -363,7 +363,7 @@ static void kdelete(void **buf) } } -static int gdm_wimax_ioctl_get_data(struct data_s *dst, struct data_s *src) +static int gdm_wimax_ioctl_get_data(struct udata_s *dst, struct data_s *src) { int size; @@ -379,7 +379,7 @@ static int gdm_wimax_ioctl_get_data(struct data_s *dst, struct data_s *src) return 0; } -static int gdm_wimax_ioctl_set_data(struct data_s *dst, struct data_s *src) +static int gdm_wimax_ioctl_set_data(struct data_s *dst, struct udata_s *src) { if (!src->size) { dst->size = 0; @@ -455,6 +455,7 @@ static int gdm_wimax_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) struct wm_req_s *req = (struct wm_req_s *)ifr; struct nic *nic = netdev_priv(dev); int ret; + struct fsm_s fsm_buf; if (cmd != SIOCWMIOCTL) return -EOPNOTSUPP; @@ -477,8 +478,11 @@ static int gdm_wimax_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /* NOTE: gdm_update_fsm should be called * before gdm_wimax_ioctl_set_data is called. */ - gdm_update_fsm(dev, - req->data.buf); + if (copy_from_user(&fsm_buf, req->data.buf, + sizeof(struct fsm_s))) + return -EFAULT; + + gdm_update_fsm(dev, &fsm_buf); } ret = gdm_wimax_ioctl_set_data( &nic->sdk_data[req->data_id], &req->data); diff --git a/drivers/staging/gdm72xx/wm_ioctl.h b/drivers/staging/gdm72xx/wm_ioctl.h index ed8f649c00428..631cb1d23c7e6 100644 --- a/drivers/staging/gdm72xx/wm_ioctl.h +++ b/drivers/staging/gdm72xx/wm_ioctl.h @@ -78,13 +78,18 @@ struct data_s { void *buf; }; +struct udata_s { + int size; + void __user *buf; +}; + struct wm_req_s { union { char ifrn_name[IFNAMSIZ]; } ifr_ifrn; unsigned short cmd; unsigned short data_id; - struct data_s data; + struct udata_s data; /* NOTE: sizeof(struct wm_req_s) must be less than sizeof(struct ifreq). */ }; -- GitLab From e16a48845deefc417738b22a801e94486abd1d6f Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Tue, 15 Dec 2015 01:27:27 +0200 Subject: [PATCH 2063/2855] staging: gdm724x: constify tty_port_operations structs Constifies tty_port_operations structure in the tty code of the gdm724x driver since it is not modified after its initialization. Detected and found using Coccinelle. Suggested-by: Julia Lawall Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm724x/gdm_tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/gdm724x/gdm_tty.c b/drivers/staging/gdm724x/gdm_tty.c index e2c0f228f3693..eb7e2523c3545 100644 --- a/drivers/staging/gdm724x/gdm_tty.c +++ b/drivers/staging/gdm724x/gdm_tty.c @@ -64,7 +64,7 @@ static void gdm_port_destruct(struct tty_port *port) kfree(gdm); } -static struct tty_port_operations gdm_port_ops = { +static const struct tty_port_operations gdm_port_ops = { .destruct = gdm_port_destruct, }; -- GitLab From 2fc251a8dda56b71ec491bee4c6897e3e12c0739 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Fri, 11 Dec 2015 09:34:42 +1100 Subject: [PATCH 2064/2855] powerpc: Copy only required pieces of the mm_context_t to the paca Currently we copy the whole mm_context_t to the paca but only access a few bits of it. This is wasteful of space paca and also takes quite some time in the hot path of context switching. This patch pulls in only the required bits from the mm_context_t to the paca and on context switch, copies only those. Benchmarking this (On top of Anton's recent MSR context switching changes [1]) using processes and yield shows an improvement of almost 3% on POWER8: http://ozlabs.org/~anton/junkcode/context_switch2.c ./context_switch2 --test=yield --process 0 0 1. https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-October/135700.html Signed-off-by: Michael Neuling [mpe: Rename paca fields to be mm_ctx_foo rather than context_foo] Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/paca.h | 18 ++++++++++++++++-- arch/powerpc/kernel/asm-offsets.c | 8 ++++---- arch/powerpc/mm/hash_utils_64.c | 4 ++-- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index 1cc6e08289076..ef78c288c712c 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -16,6 +16,7 @@ #ifdef CONFIG_PPC64 +#include #include #include #include @@ -132,7 +133,13 @@ struct paca_struct { #endif /* CONFIG_PPC_BOOK3E */ #ifdef CONFIG_PPC_BOOK3S - mm_context_t context; + mm_context_id_t mm_ctx_id; +#ifdef CONFIG_PPC_MM_SLICES + u64 mm_ctx_low_slices_psize; + unsigned char mm_ctx_high_slices_psize[SLICE_ARRAY_SIZE]; +#else + u16 mm_ctx_sllp; +#endif #endif /* @@ -199,7 +206,14 @@ struct paca_struct { #ifdef CONFIG_PPC_BOOK3S static inline void copy_mm_to_paca(mm_context_t *context) { - get_paca()->context = *context; + get_paca()->mm_ctx_id = context->id; +#ifdef CONFIG_PPC_MM_SLICES + get_paca()->mm_ctx_low_slices_psize = context->low_slices_psize; + memcpy(&get_paca()->mm_ctx_high_slices_psize, + &context->high_slices_psize, SLICE_ARRAY_SIZE); +#else + get_paca()->mm_ctx_sllp = context->sllp; +#endif } #else static inline void copy_mm_to_paca(mm_context_t *context){} diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 9db7be292bf36..07cebc3514f34 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -186,12 +186,12 @@ int main(void) DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled)); DEFINE(PACAIRQHAPPENED, offsetof(struct paca_struct, irq_happened)); #ifdef CONFIG_PPC_BOOK3S - DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id)); + DEFINE(PACACONTEXTID, offsetof(struct paca_struct, mm_ctx_id)); #ifdef CONFIG_PPC_MM_SLICES DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct, - context.low_slices_psize)); + mm_ctx_low_slices_psize)); DEFINE(PACAHIGHSLICEPSIZE, offsetof(struct paca_struct, - context.high_slices_psize)); + mm_ctx_high_slices_psize)); DEFINE(MMUPSIZEDEFSIZE, sizeof(struct mmu_psize_def)); #endif /* CONFIG_PPC_MM_SLICES */ #endif @@ -224,7 +224,7 @@ int main(void) #ifdef CONFIG_PPC_MM_SLICES DEFINE(MMUPSIZESLLP, offsetof(struct mmu_psize_def, sllp)); #else - DEFINE(PACACONTEXTSLLP, offsetof(struct paca_struct, context.sllp)); + DEFINE(PACACONTEXTSLLP, offsetof(struct paca_struct, mm_ctx_sllp)); #endif /* CONFIG_PPC_MM_SLICES */ DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen)); DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc)); diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 03279eac09571..db744576d730e 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -853,11 +853,11 @@ static unsigned int get_paca_psize(unsigned long addr) unsigned long index, mask_index; if (addr < SLICE_LOW_TOP) { - lpsizes = get_paca()->context.low_slices_psize; + lpsizes = get_paca()->mm_ctx_low_slices_psize; index = GET_LOW_SLICE_INDEX(addr); return (lpsizes >> (index * 4)) & 0xF; } - hpsizes = get_paca()->context.high_slices_psize; + hpsizes = get_paca()->mm_ctx_high_slices_psize; index = GET_HIGH_SLICE_INDEX(addr); mask_index = index & 0x1; return (hpsizes[index >> 1] >> (mask_index * 4)) & 0xF; -- GitLab From affddff69c55eb68969448f35f59054a370bc7c1 Mon Sep 17 00:00:00 2001 From: Russell Currey Date: Fri, 27 Nov 2015 17:23:07 +1100 Subject: [PATCH 2065/2855] powerpc/powernv: Add a kmsg_dumper that flushes console output on panic On BMC machines, console output is controlled by the OPAL firmware and is only flushed when its pollers are called. When the kernel is in a panic state, it no longer calls these pollers and thus console output does not completely flush, causing some output from the panic to be lost. Output is only actually lost when the kernel is configured to not power off or reboot after panic (i.e. CONFIG_PANIC_TIMEOUT is set to 0) since OPAL flushes the console buffer as part of its power down routines. Before this patch, however, only partial output would be printed during the timeout wait. This patch adds a new kmsg_dumper which gets called at panic time to ensure panic output is not lost. It accomplishes this by calling OPAL_CONSOLE_FLUSH in the OPAL API, and if that is not available, the pollers are called enough times to (hopefully) completely flush the buffer. The flushing mechanism will only affect output printed at and before the kmsg_dump call in kernel/panic.c:panic(). As such, the "end Kernel panic" message may still be truncated as follows: >Call Trace: >[c000000f1f603b00] [c0000000008e9458] dump_stack+0x90/0xbc (unreliable) >[c000000f1f603b30] [c0000000008e7e78] panic+0xf8/0x2c4 >[c000000f1f603bc0] [c000000000be4860] mount_block_root+0x288/0x33c >[c000000f1f603c80] [c000000000be4d14] prepare_namespace+0x1f4/0x254 >[c000000f1f603d00] [c000000000be43e8] kernel_init_freeable+0x318/0x350 >[c000000f1f603dc0] [c00000000000bd74] kernel_init+0x24/0x130 >[c000000f1f603e30] [c0000000000095b0] ret_from_kernel_thread+0x5c/0xac >---[ end Kernel panic - not This functionality is implemented as a kmsg_dumper as it seems to be the most sensible way to introduce platform-specific functionality to the panic function. Signed-off-by: Russell Currey Reviewed-by: Andrew Donnellan Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/opal-api.h | 3 +- arch/powerpc/include/asm/opal.h | 3 + arch/powerpc/platforms/powernv/Makefile | 1 + arch/powerpc/platforms/powernv/opal-kmsg.c | 68 +++++++++++++++++++ .../powerpc/platforms/powernv/opal-wrappers.S | 1 + arch/powerpc/platforms/powernv/opal.c | 3 + 6 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/platforms/powernv/opal-kmsg.c diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index 8374afed9d0a9..f8faaaeeca1e1 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -157,7 +157,8 @@ #define OPAL_LEDS_GET_INDICATOR 114 #define OPAL_LEDS_SET_INDICATOR 115 #define OPAL_CEC_REBOOT2 116 -#define OPAL_LAST 116 +#define OPAL_CONSOLE_FLUSH 117 +#define OPAL_LAST 117 /* Device tree flags */ diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 800115910e43a..a5fd407213b6e 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -35,6 +35,7 @@ int64_t opal_console_read(int64_t term_number, __be64 *length, uint8_t *buffer); int64_t opal_console_write_buffer_space(int64_t term_number, __be64 *length); +void opal_console_flush(void); int64_t opal_rtc_read(__be32 *year_month_day, __be64 *hour_minute_second_millisecond); int64_t opal_rtc_write(uint32_t year_month_day, @@ -262,6 +263,8 @@ extern int opal_resync_timebase(void); extern void opal_lpc_init(void); +extern void opal_kmsg_init(void); + extern int opal_event_request(unsigned int opal_event_nr); struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr, diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index ee774e8a48375..f1516b5ecec94 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile @@ -2,6 +2,7 @@ obj-y += setup.o opal-wrappers.o opal.o opal-async.o idle.o obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o obj-y += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o +obj-y += opal-kmsg.o obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o npu-dma.o diff --git a/arch/powerpc/platforms/powernv/opal-kmsg.c b/arch/powerpc/platforms/powernv/opal-kmsg.c new file mode 100644 index 0000000000000..bd3b2ee1ba1d6 --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-kmsg.c @@ -0,0 +1,68 @@ +/* + * kmsg dumper that ensures the OPAL console fully flushes panic messages + * + * Author: Russell Currey + * + * Copyright 2015 IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include + +#include +#include + +/* + * Console output is controlled by OPAL firmware. The kernel regularly calls + * OPAL_POLL_EVENTS, which flushes some console output. In a panic state, + * however, the kernel no longer calls OPAL_POLL_EVENTS and the panic message + * may not be completely printed. This function does not actually dump the + * message, it just ensures that OPAL completely flushes the console buffer. + */ +static void force_opal_console_flush(struct kmsg_dumper *dumper, + enum kmsg_dump_reason reason) +{ + int i; + + /* + * Outside of a panic context the pollers will continue to run, + * so we don't need to do any special flushing. + */ + if (reason != KMSG_DUMP_PANIC) + return; + + if (opal_check_token(OPAL_CONSOLE_FLUSH)) { + opal_console_flush(); + } else { + /* + * If OPAL_CONSOLE_FLUSH is not implemented in the firmware, + * the console can still be flushed by calling the polling + * function enough times to flush the buffer. We don't know + * how much output still needs to be flushed, but we can be + * generous since the kernel is in panic and doesn't need + * to do much else. + */ + printk(KERN_NOTICE "opal: OPAL_CONSOLE_FLUSH missing.\n"); + for (i = 0; i < 1024; i++) { + opal_poll_events(NULL); + } + } +} + +static struct kmsg_dumper opal_kmsg_dumper = { + .dump = force_opal_console_flush +}; + +void __init opal_kmsg_init(void) +{ + int rc; + + /* Add our dumper to the list */ + rc = kmsg_dump_register(&opal_kmsg_dumper); + if (rc != 0) + pr_err("opal: kmsg_dump_register failed; returned %d\n", rc); +} diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index b7a464fef7a77..e45b88a5d7e0f 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S @@ -301,3 +301,4 @@ OPAL_CALL(opal_flash_erase, OPAL_FLASH_ERASE); OPAL_CALL(opal_prd_msg, OPAL_PRD_MSG); OPAL_CALL(opal_leds_get_ind, OPAL_LEDS_GET_INDICATOR); OPAL_CALL(opal_leds_set_ind, OPAL_LEDS_SET_INDICATOR); +OPAL_CALL(opal_console_flush, OPAL_CONSOLE_FLUSH); diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index aad0033d65d1e..b349dd3e76eac 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -748,6 +748,9 @@ static int __init opal_init(void) opal_pdev_init(opal_node, "ibm,opal-flash"); opal_pdev_init(opal_node, "ibm,opal-prd"); + /* Initialise OPAL kmsg dumper for flushing console on panic */ + opal_kmsg_init(); + return 0; } machine_subsys_initcall(powernv, opal_init); -- GitLab From 57a9039052aadf5833c40ab494d30d3755660a48 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Fri, 18 Dec 2015 21:46:04 +1100 Subject: [PATCH 2066/2855] powerpc/powernv: Only delay opal_rtc_read() retry when necessary Only delay opal_rtc_read() when busy and are going to retry. This has the advantage of possibly saving a massive 10ms off booting! Kudos to Stewart for noticing. Signed-off-by: Michael Neuling Reviewed-by: Stewart Smith Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/opal-rtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/opal-rtc.c b/arch/powerpc/platforms/powernv/opal-rtc.c index 1b149c92fca16..f8868864f373e 100644 --- a/arch/powerpc/platforms/powernv/opal-rtc.c +++ b/arch/powerpc/platforms/powernv/opal-rtc.c @@ -50,7 +50,7 @@ unsigned long __init opal_get_boot_time(void) rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms); if (rc == OPAL_BUSY_EVENT) opal_poll_events(NULL); - else + else if (rc == OPAL_BUSY) mdelay(10); } if (rc != OPAL_SUCCESS) -- GitLab From 759fb100b22473bebc46a0f10ca1af5acd79439d Mon Sep 17 00:00:00 2001 From: Andrew Donnellan Date: Mon, 21 Dec 2015 17:38:41 +1100 Subject: [PATCH 2067/2855] powerpc: Fix style of self-test config prompts A few of the config prompts for powerpc self-tests have periods at the end, which is inconsistent with the rest of the prompts. Remove the periods. Signed-off-by: Andrew Donnellan Signed-off-by: Michael Ellerman --- arch/powerpc/Kconfig.debug | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index 3a510f4a6b68c..77e2cefe47eb3 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug @@ -64,17 +64,17 @@ config PPC_EMULATED_STATS emulated. config CODE_PATCHING_SELFTEST - bool "Run self-tests of the code-patching code." + bool "Run self-tests of the code-patching code" depends on DEBUG_KERNEL default n config FTR_FIXUP_SELFTEST - bool "Run self-tests of the feature-fixup code." + bool "Run self-tests of the feature-fixup code" depends on DEBUG_KERNEL default n config MSI_BITMAP_SELFTEST - bool "Run self-tests of the MSI bitmap code." + bool "Run self-tests of the MSI bitmap code" depends on DEBUG_KERNEL default n -- GitLab From dc3799bb9ab2666fa19081121f05a4e573ecae12 Mon Sep 17 00:00:00 2001 From: Andrew Donnellan Date: Mon, 21 Dec 2015 18:28:37 +1100 Subject: [PATCH 2068/2855] powerpc/powernv: Fix minor off-by-one error in opal_mce_check_early_recovery() Fix off-by-one error in opal_mce_check_early_recovery() when checking whether the NIP falls within OPAL space. Signed-off-by: Andrew Donnellan Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/opal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index b349dd3e76eac..81f4a3ab8743d 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -548,7 +548,7 @@ bool opal_mce_check_early_recovery(struct pt_regs *regs) goto out; if ((regs->nip >= opal.base) && - (regs->nip <= (opal.base + opal.size))) + (regs->nip < (opal.base + opal.size))) recover_addr = find_recovery_address(regs->nip); /* -- GitLab From e3fed74894c725fb85d7315aa0c01df9b59b7a9d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 16 Dec 2015 16:56:39 +0800 Subject: [PATCH 2069/2855] HID: corsair: Convert to use module_hid_driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Axel Lin Acked-by: Clément Vuchener Signed-off-by: Jiri Kosina --- drivers/hid/hid-corsair.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/hid/hid-corsair.c b/drivers/hid/hid-corsair.c index bcefb9ebb0266..58551964ce869 100644 --- a/drivers/hid/hid-corsair.c +++ b/drivers/hid/hid-corsair.c @@ -655,18 +655,7 @@ static struct hid_driver corsair_driver = { .input_mapping = corsair_input_mapping, }; -static int __init corsair_init(void) -{ - return hid_register_driver(&corsair_driver); -} - -static void corsair_exit(void) -{ - hid_unregister_driver(&corsair_driver); -} - -module_init(corsair_init); -module_exit(corsair_exit); +module_hid_driver(corsair_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Clement Vuchener"); -- GitLab From 7775fb929d959eade7c705e27a0a759997463da8 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Wed, 23 Dec 2015 21:26:53 +0800 Subject: [PATCH 2070/2855] HID: usbhid: use to_usb_device Use to_usb_device() instead of open-coding it. Signed-off-by: Geliang Tang Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/usbhid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h index 807922b49aa49..fa47d666cfcf2 100644 --- a/drivers/hid/usbhid/usbhid.h +++ b/drivers/hid/usbhid/usbhid.h @@ -96,7 +96,7 @@ struct usbhid_device { }; #define hid_to_usb_dev(hid_dev) \ - container_of(hid_dev->dev.parent->parent, struct usb_device, dev) + to_usb_device(hid_dev->dev.parent->parent) #endif -- GitLab From d8ce9bf5551bfea431893bdd0a943f24a5170828 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Sun, 27 Dec 2015 17:25:20 +0800 Subject: [PATCH 2071/2855] HID: move to_hid_device() to hid.h to_hid_device() macro is defined in both hid-lg4ff.c and hid-logitech-hidpp.c. So I move it to include/linux/hid.h. Signed-off-by: Geliang Tang Signed-off-by: Jiri Kosina --- drivers/hid/hid-lg4ff.c | 2 -- drivers/hid/hid-logitech-hidpp.c | 2 -- include/linux/hid.h | 3 +++ 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index fbddcb37ae982..3e160ff5f218c 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c @@ -33,8 +33,6 @@ #include "hid-lg4ff.h" #include "hid-ids.h" -#define to_hid_device(pdev) container_of(pdev, struct hid_device, dev) - #define LG4FF_MMODE_IS_MULTIMODE 0 #define LG4FF_MMODE_SWITCHED 1 #define LG4FF_MMODE_NOT_MULTIMODE 2 diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index f2a481125522e..bd2ab476c65ef 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -1310,8 +1310,6 @@ struct g920_private_data { u16 range; }; -#define to_hid_device(pdev) container_of(pdev, struct hid_device, dev) - static ssize_t g920_range_show(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/include/linux/hid.h b/include/linux/hid.h index a6d7a3fc2cb30..1472026367ed0 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -565,6 +565,9 @@ struct hid_device { /* device report descriptor */ wait_queue_head_t debug_wait; }; +#define to_hid_device(pdev) \ + container_of(pdev, struct hid_device, dev) + static inline void *hid_get_drvdata(struct hid_device *hdev) { return dev_get_drvdata(&hdev->dev); -- GitLab From ee79a8f840a45d331bc33e55cbcc89bba417671c Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Sun, 27 Dec 2015 17:25:21 +0800 Subject: [PATCH 2072/2855] HID: use to_hid_device() Use to_hid_device() instead of container_of(). Signed-off-by: Geliang Tang Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 14 ++++++------- drivers/hid/hid-cp2112.c | 8 ++++---- drivers/hid/hid-gt683r.c | 8 +++----- drivers/hid/hid-lenovo.c | 36 +++++++++++++++++----------------- drivers/hid/hid-lg4ff.c | 4 ++-- drivers/hid/hid-multitouch.c | 4 ++-- drivers/hid/hid-ntrig.c | 32 +++++++++++++++--------------- drivers/hid/hid-picolcd_leds.c | 4 ++-- drivers/hid/hid-prodikeys.c | 12 ++++++------ drivers/hid/hid-sony.c | 6 +++--- drivers/hid/hid-steelseries.c | 8 ++++---- drivers/hid/hid-wiimote.h | 3 +-- drivers/hid/wacom_sys.c | 16 +++++++-------- 13 files changed, 76 insertions(+), 79 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 190260c52adc7..a6e24e00a37bb 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -625,7 +625,7 @@ static void hid_close_report(struct hid_device *device) static void hid_device_release(struct device *dev) { - struct hid_device *hid = container_of(dev, struct hid_device, dev); + struct hid_device *hid = to_hid_device(dev); hid_close_report(hid); kfree(hid->dev_rdesc); @@ -1572,7 +1572,7 @@ read_report_descriptor(struct file *filp, struct kobject *kobj, char *buf, loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); if (off >= hdev->rsize) return 0; @@ -1589,7 +1589,7 @@ static ssize_t show_country(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); return sprintf(buf, "%02x\n", hdev->country & 0xff); } @@ -2140,7 +2140,7 @@ static const struct hid_device_id *hid_match_device(struct hid_device *hdev, static int hid_bus_match(struct device *dev, struct device_driver *drv) { struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); return hid_match_device(hdev, hdrv) != NULL; } @@ -2149,7 +2149,7 @@ static int hid_device_probe(struct device *dev) { struct hid_driver *hdrv = container_of(dev->driver, struct hid_driver, driver); - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); const struct hid_device_id *id; int ret = 0; @@ -2191,7 +2191,7 @@ unlock_driver_lock: static int hid_device_remove(struct device *dev) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct hid_driver *hdrv; int ret = 0; @@ -2241,7 +2241,7 @@ ATTRIBUTE_GROUPS(hid_dev); static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); if (add_uevent_var(env, "HID_ID=%04X:%08X:%08X", hdev->bus, hdev->vendor, hdev->product)) diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c index 7afc3fcc122c4..7c38bfa05fac1 100644 --- a/drivers/hid/hid-cp2112.c +++ b/drivers/hid/hid-cp2112.c @@ -807,7 +807,7 @@ static ssize_t name##_store(struct device *kdev, \ struct device_attribute *attr, const char *buf, \ size_t count) \ { \ - struct hid_device *hdev = container_of(kdev, struct hid_device, dev); \ + struct hid_device *hdev = to_hid_device(kdev); \ struct cp2112_usb_config_report cfg; \ int ret = cp2112_get_usb_config(hdev, &cfg); \ if (ret) \ @@ -822,7 +822,7 @@ static ssize_t name##_store(struct device *kdev, \ static ssize_t name##_show(struct device *kdev, \ struct device_attribute *attr, char *buf) \ { \ - struct hid_device *hdev = container_of(kdev, struct hid_device, dev); \ + struct hid_device *hdev = to_hid_device(kdev); \ struct cp2112_usb_config_report cfg; \ int ret = cp2112_get_usb_config(hdev, &cfg); \ if (ret) \ @@ -887,7 +887,7 @@ static ssize_t pstr_store(struct device *kdev, struct device_attribute *kattr, const char *buf, size_t count) { - struct hid_device *hdev = container_of(kdev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(kdev); struct cp2112_pstring_attribute *attr = container_of(kattr, struct cp2112_pstring_attribute, attr); struct cp2112_string_report report; @@ -918,7 +918,7 @@ static ssize_t pstr_store(struct device *kdev, static ssize_t pstr_show(struct device *kdev, struct device_attribute *kattr, char *buf) { - struct hid_device *hdev = container_of(kdev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(kdev); struct cp2112_pstring_attribute *attr = container_of(kattr, struct cp2112_pstring_attribute, attr); struct cp2112_string_report report; diff --git a/drivers/hid/hid-gt683r.c b/drivers/hid/hid-gt683r.c index 0d6f135e266c2..a298fbd8db6b9 100644 --- a/drivers/hid/hid-gt683r.c +++ b/drivers/hid/hid-gt683r.c @@ -70,7 +70,7 @@ static void gt683r_brightness_set(struct led_classdev *led_cdev, { int i; struct device *dev = led_cdev->dev->parent; - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct gt683r_led *led = hid_get_drvdata(hdev); for (i = 0; i < GT683R_LED_COUNT; i++) { @@ -89,8 +89,7 @@ static ssize_t mode_show(struct device *dev, char *buf) { u8 sysfs_mode; - struct hid_device *hdev = container_of(dev->parent, - struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev->parent); struct gt683r_led *led = hid_get_drvdata(hdev); if (led->mode == GT683R_LED_NORMAL) @@ -108,8 +107,7 @@ static ssize_t mode_store(struct device *dev, const char *buf, size_t count) { u8 sysfs_mode; - struct hid_device *hdev = container_of(dev->parent, - struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev->parent); struct gt683r_led *led = hid_get_drvdata(hdev); diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index 8979f1fd5208f..0125e356bd8d2 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c @@ -220,7 +220,7 @@ static ssize_t attr_fn_lock_show_cptkbd(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); return snprintf(buf, PAGE_SIZE, "%u\n", cptkbd_data->fn_lock); @@ -231,7 +231,7 @@ static ssize_t attr_fn_lock_store_cptkbd(struct device *dev, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); int value; @@ -250,7 +250,7 @@ static ssize_t attr_sensitivity_show_cptkbd(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); return snprintf(buf, PAGE_SIZE, "%u\n", @@ -262,7 +262,7 @@ static ssize_t attr_sensitivity_store_cptkbd(struct device *dev, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); int value; @@ -387,7 +387,7 @@ static ssize_t attr_press_to_select_show_tpkbd(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->press_to_select); @@ -398,7 +398,7 @@ static ssize_t attr_press_to_select_store_tpkbd(struct device *dev, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); int value; @@ -417,7 +417,7 @@ static ssize_t attr_dragging_show_tpkbd(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->dragging); @@ -428,7 +428,7 @@ static ssize_t attr_dragging_store_tpkbd(struct device *dev, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); int value; @@ -447,7 +447,7 @@ static ssize_t attr_release_to_select_show_tpkbd(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->release_to_select); @@ -458,7 +458,7 @@ static ssize_t attr_release_to_select_store_tpkbd(struct device *dev, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); int value; @@ -477,7 +477,7 @@ static ssize_t attr_select_right_show_tpkbd(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->select_right); @@ -488,7 +488,7 @@ static ssize_t attr_select_right_store_tpkbd(struct device *dev, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); int value; @@ -507,7 +507,7 @@ static ssize_t attr_sensitivity_show_tpkbd(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); return snprintf(buf, PAGE_SIZE, "%u\n", @@ -519,7 +519,7 @@ static ssize_t attr_sensitivity_store_tpkbd(struct device *dev, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); int value; @@ -536,7 +536,7 @@ static ssize_t attr_press_speed_show_tpkbd(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); return snprintf(buf, PAGE_SIZE, "%u\n", @@ -548,7 +548,7 @@ static ssize_t attr_press_speed_store_tpkbd(struct device *dev, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); int value; @@ -609,7 +609,7 @@ static enum led_brightness lenovo_led_brightness_get_tpkbd( struct led_classdev *led_cdev) { struct device *dev = led_cdev->dev->parent; - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); int led_nr = 0; @@ -625,7 +625,7 @@ static void lenovo_led_brightness_set_tpkbd(struct led_classdev *led_cdev, enum led_brightness value) { struct device *dev = led_cdev->dev->parent; - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); struct hid_report *report; int led_nr = 0; diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index 3e160ff5f218c..af3a8ec8a7467 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c @@ -1018,7 +1018,7 @@ static void lg4ff_led_set_brightness(struct led_classdev *led_cdev, enum led_brightness value) { struct device *dev = led_cdev->dev->parent; - struct hid_device *hid = container_of(dev, struct hid_device, dev); + struct hid_device *hid = to_hid_device(dev); struct lg_drv_data *drv_data = hid_get_drvdata(hid); struct lg4ff_device_entry *entry; int i, state = 0; @@ -1053,7 +1053,7 @@ static void lg4ff_led_set_brightness(struct led_classdev *led_cdev, static enum led_brightness lg4ff_led_get_brightness(struct led_classdev *led_cdev) { struct device *dev = led_cdev->dev->parent; - struct hid_device *hid = container_of(dev, struct hid_device, dev); + struct hid_device *hid = to_hid_device(dev); struct lg_drv_data *drv_data = hid_get_drvdata(hid); struct lg4ff_device_entry *entry; int i, value = 0; diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 3d664d01305e5..96cf7512c3387 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -272,7 +272,7 @@ static ssize_t mt_show_quirks(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct mt_device *td = hid_get_drvdata(hdev); return sprintf(buf, "%u\n", td->mtclass.quirks); @@ -282,7 +282,7 @@ static ssize_t mt_set_quirks(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct mt_device *td = hid_get_drvdata(hdev); unsigned long val; diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 756d1ef9bd991..1b0084d4af2e4 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -173,7 +173,7 @@ static ssize_t show_phys_width(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct ntrig_data *nd = hid_get_drvdata(hdev); return sprintf(buf, "%d\n", nd->sensor_physical_width); @@ -185,7 +185,7 @@ static ssize_t show_phys_height(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct ntrig_data *nd = hid_get_drvdata(hdev); return sprintf(buf, "%d\n", nd->sensor_physical_height); @@ -197,7 +197,7 @@ static ssize_t show_log_width(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct ntrig_data *nd = hid_get_drvdata(hdev); return sprintf(buf, "%d\n", nd->sensor_logical_width); @@ -209,7 +209,7 @@ static ssize_t show_log_height(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct ntrig_data *nd = hid_get_drvdata(hdev); return sprintf(buf, "%d\n", nd->sensor_logical_height); @@ -221,7 +221,7 @@ static ssize_t show_min_width(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct ntrig_data *nd = hid_get_drvdata(hdev); return sprintf(buf, "%d\n", nd->min_width * @@ -233,7 +233,7 @@ static ssize_t set_min_width(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct ntrig_data *nd = hid_get_drvdata(hdev); unsigned long val; @@ -256,7 +256,7 @@ static ssize_t show_min_height(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct ntrig_data *nd = hid_get_drvdata(hdev); return sprintf(buf, "%d\n", nd->min_height * @@ -268,7 +268,7 @@ static ssize_t set_min_height(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct ntrig_data *nd = hid_get_drvdata(hdev); unsigned long val; @@ -292,7 +292,7 @@ static ssize_t show_activate_slack(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct ntrig_data *nd = hid_get_drvdata(hdev); return sprintf(buf, "%d\n", nd->activate_slack); @@ -302,7 +302,7 @@ static ssize_t set_activate_slack(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct ntrig_data *nd = hid_get_drvdata(hdev); unsigned long val; @@ -325,7 +325,7 @@ static ssize_t show_activation_width(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct ntrig_data *nd = hid_get_drvdata(hdev); return sprintf(buf, "%d\n", nd->activation_width * @@ -337,7 +337,7 @@ static ssize_t set_activation_width(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct ntrig_data *nd = hid_get_drvdata(hdev); unsigned long val; @@ -361,7 +361,7 @@ static ssize_t show_activation_height(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct ntrig_data *nd = hid_get_drvdata(hdev); return sprintf(buf, "%d\n", nd->activation_height * @@ -373,7 +373,7 @@ static ssize_t set_activation_height(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct ntrig_data *nd = hid_get_drvdata(hdev); unsigned long val; @@ -397,7 +397,7 @@ static ssize_t show_deactivate_slack(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct ntrig_data *nd = hid_get_drvdata(hdev); return sprintf(buf, "%d\n", -nd->deactivate_slack); @@ -407,7 +407,7 @@ static ssize_t set_deactivate_slack(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct ntrig_data *nd = hid_get_drvdata(hdev); unsigned long val; diff --git a/drivers/hid/hid-picolcd_leds.c b/drivers/hid/hid-picolcd_leds.c index e994f9c290128..a802b4f49c7b1 100644 --- a/drivers/hid/hid-picolcd_leds.c +++ b/drivers/hid/hid-picolcd_leds.c @@ -66,7 +66,7 @@ static void picolcd_led_set_brightness(struct led_classdev *led_cdev, int i, state = 0; dev = led_cdev->dev->parent; - hdev = container_of(dev, struct hid_device, dev); + hdev = to_hid_device(dev); data = hid_get_drvdata(hdev); if (!data) return; @@ -93,7 +93,7 @@ static enum led_brightness picolcd_led_get_brightness(struct led_classdev *led_c int i, value = 0; dev = led_cdev->dev->parent; - hdev = container_of(dev, struct hid_device, dev); + hdev = to_hid_device(dev); data = hid_get_drvdata(hdev); for (i = 0; i < 8; i++) if (led_cdev == data->led[i]) { diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c index 3a207c0ac0e39..f095bf8a3aa94 100644 --- a/drivers/hid/hid-prodikeys.c +++ b/drivers/hid/hid-prodikeys.c @@ -103,7 +103,7 @@ MODULE_PARM_DESC(enable, "Enable for the PC-MIDI virtual audio driver"); static ssize_t show_channel(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct pk_device *pk = hid_get_drvdata(hdev); dbg_hid("pcmidi sysfs read channel=%u\n", pk->pm->midi_channel); @@ -116,7 +116,7 @@ static ssize_t show_channel(struct device *dev, static ssize_t store_channel(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct pk_device *pk = hid_get_drvdata(hdev); unsigned channel = 0; @@ -140,7 +140,7 @@ static struct device_attribute *sysfs_device_attr_channel = { static ssize_t show_sustain(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct pk_device *pk = hid_get_drvdata(hdev); dbg_hid("pcmidi sysfs read sustain=%u\n", pk->pm->midi_sustain); @@ -153,7 +153,7 @@ static ssize_t show_sustain(struct device *dev, static ssize_t store_sustain(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct pk_device *pk = hid_get_drvdata(hdev); unsigned sustain = 0; @@ -179,7 +179,7 @@ static struct device_attribute *sysfs_device_attr_sustain = { static ssize_t show_octave(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct pk_device *pk = hid_get_drvdata(hdev); dbg_hid("pcmidi sysfs read octave=%d\n", pk->pm->midi_octave); @@ -192,7 +192,7 @@ static ssize_t show_octave(struct device *dev, static ssize_t store_octave(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct pk_device *pk = hid_get_drvdata(hdev); int octave = 0; diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 774cd22105665..9bbf5a7251394 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -1549,7 +1549,7 @@ static void sony_led_set_brightness(struct led_classdev *led, enum led_brightness value) { struct device *dev = led->dev->parent; - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct sony_sc *drv_data; int n; @@ -1591,7 +1591,7 @@ static void sony_led_set_brightness(struct led_classdev *led, static enum led_brightness sony_led_get_brightness(struct led_classdev *led) { struct device *dev = led->dev->parent; - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct sony_sc *drv_data; int n; @@ -1614,7 +1614,7 @@ static int sony_led_blink_set(struct led_classdev *led, unsigned long *delay_on, unsigned long *delay_off) { struct device *dev = led->dev->parent; - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct sony_sc *drv_data = hid_get_drvdata(hdev); int n; __u8 new_on, new_off; diff --git a/drivers/hid/hid-steelseries.c b/drivers/hid/hid-steelseries.c index 3edd4ac364942..ec18768b124ae 100644 --- a/drivers/hid/hid-steelseries.c +++ b/drivers/hid/hid-steelseries.c @@ -141,7 +141,7 @@ static void steelseries_srws1_led_all_set_brightness(struct led_classdev *led_cd enum led_brightness value) { struct device *dev = led_cdev->dev->parent; - struct hid_device *hid = container_of(dev, struct hid_device, dev); + struct hid_device *hid = to_hid_device(dev); struct steelseries_srws1_data *drv_data = hid_get_drvdata(hid); if (!drv_data) { @@ -160,7 +160,7 @@ static void steelseries_srws1_led_all_set_brightness(struct led_classdev *led_cd static enum led_brightness steelseries_srws1_led_all_get_brightness(struct led_classdev *led_cdev) { struct device *dev = led_cdev->dev->parent; - struct hid_device *hid = container_of(dev, struct hid_device, dev); + struct hid_device *hid = to_hid_device(dev); struct steelseries_srws1_data *drv_data; drv_data = hid_get_drvdata(hid); @@ -177,7 +177,7 @@ static void steelseries_srws1_led_set_brightness(struct led_classdev *led_cdev, enum led_brightness value) { struct device *dev = led_cdev->dev->parent; - struct hid_device *hid = container_of(dev, struct hid_device, dev); + struct hid_device *hid = to_hid_device(dev); struct steelseries_srws1_data *drv_data = hid_get_drvdata(hid); int i, state = 0; @@ -205,7 +205,7 @@ static void steelseries_srws1_led_set_brightness(struct led_classdev *led_cdev, static enum led_brightness steelseries_srws1_led_get_brightness(struct led_classdev *led_cdev) { struct device *dev = led_cdev->dev->parent; - struct hid_device *hid = container_of(dev, struct hid_device, dev); + struct hid_device *hid = to_hid_device(dev); struct steelseries_srws1_data *drv_data; int i, value = 0; diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h index 875694d43e4d9..510ca77fe14e1 100644 --- a/drivers/hid/hid-wiimote.h +++ b/drivers/hid/hid-wiimote.h @@ -256,8 +256,7 @@ enum wiiproto_reqs { WIIPROTO_REQ_MAX }; -#define dev_to_wii(pdev) hid_get_drvdata(container_of(pdev, struct hid_device, \ - dev)) +#define dev_to_wii(pdev) hid_get_drvdata(to_hid_device(pdev)) void __wiimote_schedule(struct wiimote_data *wdata); diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index e06af5b9f59e8..4b7feb3022c19 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -686,7 +686,7 @@ out: static ssize_t wacom_led_select_store(struct device *dev, int set_id, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct wacom *wacom = hid_get_drvdata(hdev); unsigned int id; int err; @@ -714,7 +714,7 @@ static ssize_t wacom_led##SET_ID##_select_store(struct device *dev, \ static ssize_t wacom_led##SET_ID##_select_show(struct device *dev, \ struct device_attribute *attr, char *buf) \ { \ - struct hid_device *hdev = container_of(dev, struct hid_device, dev);\ + struct hid_device *hdev = to_hid_device(dev);\ struct wacom *wacom = hid_get_drvdata(hdev); \ return scnprintf(buf, PAGE_SIZE, "%d\n", \ wacom->led.select[SET_ID]); \ @@ -750,7 +750,7 @@ static ssize_t wacom_luminance_store(struct wacom *wacom, u8 *dest, static ssize_t wacom_##name##_luminance_store(struct device *dev, \ struct device_attribute *attr, const char *buf, size_t count) \ { \ - struct hid_device *hdev = container_of(dev, struct hid_device, dev);\ + struct hid_device *hdev = to_hid_device(dev);\ struct wacom *wacom = hid_get_drvdata(hdev); \ \ return wacom_luminance_store(wacom, &wacom->led.field, \ @@ -773,7 +773,7 @@ DEVICE_LUMINANCE_ATTR(buttons, img_lum); static ssize_t wacom_button_image_store(struct device *dev, int button_id, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct wacom *wacom = hid_get_drvdata(hdev); int err; unsigned len; @@ -1097,7 +1097,7 @@ static ssize_t wacom_show_speed(struct device *dev, struct device_attribute *attr, char *buf) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct wacom *wacom = hid_get_drvdata(hdev); return snprintf(buf, PAGE_SIZE, "%i\n", wacom->wacom_wac.bt_high_speed); @@ -1107,7 +1107,7 @@ static ssize_t wacom_store_speed(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct wacom *wacom = hid_get_drvdata(hdev); u8 new_speed; @@ -1131,7 +1131,7 @@ static ssize_t wacom_show_remote_mode(struct kobject *kobj, char *buf, int index) { struct device *dev = container_of(kobj->parent, struct device, kobj); - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct wacom *wacom = hid_get_drvdata(hdev); u8 mode; @@ -1242,7 +1242,7 @@ static ssize_t wacom_store_unpair_remote(struct kobject *kobj, { unsigned char selector = 0; struct device *dev = container_of(kobj->parent, struct device, kobj); - struct hid_device *hdev = container_of(dev, struct hid_device, dev); + struct hid_device *hdev = to_hid_device(dev); struct wacom *wacom = hid_get_drvdata(hdev); int err; -- GitLab From ba91a96718d17160890e161f702db6e60747248a Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Sun, 27 Dec 2015 17:25:22 +0800 Subject: [PATCH 2073/2855] HID: add a new helper to_hid_driver() Add a new helper to_hid_driver() and use it in hid-core.c. Signed-off-by: Geliang Tang Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 7 +++---- include/linux/hid.h | 3 +++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index a6e24e00a37bb..9d75205a511ed 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2077,7 +2077,7 @@ struct hid_dynid { static ssize_t store_new_id(struct device_driver *drv, const char *buf, size_t count) { - struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); + struct hid_driver *hdrv = to_hid_driver(drv); struct hid_dynid *dynid; __u32 bus, vendor, product; unsigned long driver_data = 0; @@ -2139,7 +2139,7 @@ static const struct hid_device_id *hid_match_device(struct hid_device *hdev, static int hid_bus_match(struct device *dev, struct device_driver *drv) { - struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); + struct hid_driver *hdrv = to_hid_driver(drv); struct hid_device *hdev = to_hid_device(dev); return hid_match_device(hdev, hdrv) != NULL; @@ -2147,8 +2147,7 @@ static int hid_bus_match(struct device *dev, struct device_driver *drv) static int hid_device_probe(struct device *dev) { - struct hid_driver *hdrv = container_of(dev->driver, - struct hid_driver, driver); + struct hid_driver *hdrv = to_hid_driver(dev->driver); struct hid_device *hdev = to_hid_device(dev); const struct hid_device_id *id; int ret = 0; diff --git a/include/linux/hid.h b/include/linux/hid.h index 1472026367ed0..75b66eccc6927 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -717,6 +717,9 @@ struct hid_driver { struct device_driver driver; }; +#define to_hid_driver(pdrv) \ + container_of(pdrv, struct hid_driver, driver) + /** * hid_ll_driver - low level driver callbacks * @start: called on probe to start the device -- GitLab From d98ba98c4fbff91abb37eef628ccce0c218b4185 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Sun, 27 Dec 2015 17:25:23 +0800 Subject: [PATCH 2074/2855] HID: wiimote: use dev_to_wii() Use dev_to_wii() instead of open-coding it. Signed-off-by: Geliang Tang Signed-off-by: Jiri Kosina --- drivers/hid/hid-wiimote-modules.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c index 05e23c417d500..4390eee2ce849 100644 --- a/drivers/hid/hid-wiimote-modules.c +++ b/drivers/hid/hid-wiimote-modules.c @@ -296,14 +296,12 @@ static const struct wiimod_ops wiimod_battery = { static enum led_brightness wiimod_led_get(struct led_classdev *led_dev) { - struct wiimote_data *wdata; struct device *dev = led_dev->dev->parent; + struct wiimote_data *wdata = dev_to_wii(dev); int i; unsigned long flags; bool value = false; - wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev)); - for (i = 0; i < 4; ++i) { if (wdata->leds[i] == led_dev) { spin_lock_irqsave(&wdata->state.lock, flags); @@ -319,14 +317,12 @@ static enum led_brightness wiimod_led_get(struct led_classdev *led_dev) static void wiimod_led_set(struct led_classdev *led_dev, enum led_brightness value) { - struct wiimote_data *wdata; struct device *dev = led_dev->dev->parent; + struct wiimote_data *wdata = dev_to_wii(dev); int i; unsigned long flags; __u8 state, flag; - wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev)); - for (i = 0; i < 4; ++i) { if (wdata->leds[i] == led_dev) { flag = WIIPROTO_FLAG_LED(i + 1); -- GitLab From 2cf83833fc9cff04c50e402260b724b3f001d737 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Sun, 27 Dec 2015 17:25:24 +0800 Subject: [PATCH 2075/2855] HID: use kobj_to_dev() Use kobj_to_dev() instead of open-coding it. Signed-off-by: Geliang Tang Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 2 +- drivers/hid/hid-roccat-arvo.c | 6 ++---- drivers/hid/hid-roccat-common.c | 6 ++---- drivers/hid/hid-roccat-isku.c | 6 ++---- drivers/hid/hid-roccat-kone.c | 12 ++++-------- drivers/hid/hid-roccat-koneplus.c | 12 ++++-------- drivers/hid/hid-roccat-kovaplus.c | 12 ++++-------- drivers/hid/hid-roccat-lua.c | 4 ++-- drivers/hid/hid-roccat-pyra.c | 15 +++++---------- drivers/hid/wacom_sys.c | 4 ++-- 10 files changed, 28 insertions(+), 51 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 9d75205a511ed..e847fb7f5d5d6 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1571,7 +1571,7 @@ read_report_descriptor(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = container_of(kobj, struct device, kobj); + struct device *dev = kobj_to_dev(kobj); struct hid_device *hdev = to_hid_device(dev); if (off >= hdev->rsize) diff --git a/drivers/hid/hid-roccat-arvo.c b/drivers/hid/hid-roccat-arvo.c index 1948208fe0380..329c5d1270f94 100644 --- a/drivers/hid/hid-roccat-arvo.c +++ b/drivers/hid/hid-roccat-arvo.c @@ -191,8 +191,7 @@ static ssize_t arvo_sysfs_write(struct file *fp, struct kobject *kobj, void const *buf, loff_t off, size_t count, size_t real_size, uint command) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct arvo_device *arvo = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval; @@ -211,8 +210,7 @@ static ssize_t arvo_sysfs_read(struct file *fp, struct kobject *kobj, void *buf, loff_t off, size_t count, size_t real_size, uint command) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct arvo_device *arvo = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval; diff --git a/drivers/hid/hid-roccat-common.c b/drivers/hid/hid-roccat-common.c index 02e28e9f4ea7d..8155ac5fede25 100644 --- a/drivers/hid/hid-roccat-common.c +++ b/drivers/hid/hid-roccat-common.c @@ -134,8 +134,7 @@ ssize_t roccat_common2_sysfs_read(struct file *fp, struct kobject *kobj, char *buf, loff_t off, size_t count, size_t real_size, uint command) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct roccat_common2_device *roccat_dev = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval; @@ -158,8 +157,7 @@ ssize_t roccat_common2_sysfs_write(struct file *fp, struct kobject *kobj, void const *buf, loff_t off, size_t count, size_t real_size, uint command) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct roccat_common2_device *roccat_dev = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval; diff --git a/drivers/hid/hid-roccat-isku.c b/drivers/hid/hid-roccat-isku.c index bc62ed91e451c..02db537f8f3ea 100644 --- a/drivers/hid/hid-roccat-isku.c +++ b/drivers/hid/hid-roccat-isku.c @@ -121,8 +121,7 @@ static ssize_t isku_sysfs_read(struct file *fp, struct kobject *kobj, char *buf, loff_t off, size_t count, size_t real_size, uint command) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct isku_device *isku = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval; @@ -144,8 +143,7 @@ static ssize_t isku_sysfs_write(struct file *fp, struct kobject *kobj, void const *buf, loff_t off, size_t count, size_t real_size, uint command) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct isku_device *isku = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval; diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index c29265055ac1a..bf4675a273965 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c @@ -269,8 +269,7 @@ static int kone_get_firmware_version(struct usb_device *usb_dev, int *result) static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); if (off >= sizeof(struct kone_settings)) @@ -294,8 +293,7 @@ static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj, static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval = 0, difference, old_profile; @@ -332,8 +330,7 @@ static BIN_ATTR(settings, 0660, kone_sysfs_read_settings, static ssize_t kone_sysfs_read_profilex(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); if (off >= sizeof(struct kone_profile)) @@ -353,8 +350,7 @@ static ssize_t kone_sysfs_read_profilex(struct file *fp, static ssize_t kone_sysfs_write_profilex(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); struct kone_profile *profile; diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c index 5e99fcdc71b9c..09e8fc72aa1d4 100644 --- a/drivers/hid/hid-roccat-koneplus.c +++ b/drivers/hid/hid-roccat-koneplus.c @@ -87,8 +87,7 @@ static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, char *buf, loff_t off, size_t count, size_t real_size, uint command) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval; @@ -113,8 +112,7 @@ static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj, void const *buf, loff_t off, size_t count, size_t real_size, uint command) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval; @@ -193,8 +191,7 @@ static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); ssize_t retval; @@ -212,8 +209,7 @@ static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); ssize_t retval; diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c index 966047711fbfc..43617fb28b87f 100644 --- a/drivers/hid/hid-roccat-kovaplus.c +++ b/drivers/hid/hid-roccat-kovaplus.c @@ -128,8 +128,7 @@ static ssize_t kovaplus_sysfs_read(struct file *fp, struct kobject *kobj, char *buf, loff_t off, size_t count, size_t real_size, uint command) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval; @@ -154,8 +153,7 @@ static ssize_t kovaplus_sysfs_write(struct file *fp, struct kobject *kobj, void const *buf, loff_t off, size_t count, size_t real_size, uint command) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval; @@ -221,8 +219,7 @@ static ssize_t kovaplus_sysfs_read_profilex_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); ssize_t retval; @@ -240,8 +237,7 @@ static ssize_t kovaplus_sysfs_read_profilex_buttons(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); ssize_t retval; diff --git a/drivers/hid/hid-roccat-lua.c b/drivers/hid/hid-roccat-lua.c index 65e2e76bf2fe5..ac1a7313e2596 100644 --- a/drivers/hid/hid-roccat-lua.c +++ b/drivers/hid/hid-roccat-lua.c @@ -30,7 +30,7 @@ static ssize_t lua_sysfs_read(struct file *fp, struct kobject *kobj, char *buf, loff_t off, size_t count, size_t real_size, uint command) { - struct device *dev = container_of(kobj, struct device, kobj); + struct device *dev = kobj_to_dev(kobj); struct lua_device *lua = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval; @@ -52,7 +52,7 @@ static ssize_t lua_sysfs_write(struct file *fp, struct kobject *kobj, void const *buf, loff_t off, size_t count, size_t real_size, uint command) { - struct device *dev = container_of(kobj, struct device, kobj); + struct device *dev = kobj_to_dev(kobj); struct lua_device *lua = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval; diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c index 47d7e74231e5a..b30aa7b82bf87 100644 --- a/drivers/hid/hid-roccat-pyra.c +++ b/drivers/hid/hid-roccat-pyra.c @@ -90,8 +90,7 @@ static ssize_t pyra_sysfs_read(struct file *fp, struct kobject *kobj, char *buf, loff_t off, size_t count, size_t real_size, uint command) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval; @@ -116,8 +115,7 @@ static ssize_t pyra_sysfs_write(struct file *fp, struct kobject *kobj, void const *buf, loff_t off, size_t count, size_t real_size, uint command) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval; @@ -191,8 +189,7 @@ static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); ssize_t retval; @@ -210,8 +207,7 @@ static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); ssize_t retval; @@ -248,8 +244,7 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = kobj_to_dev(kobj)->parent->parent; struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval = 0; diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 4b7feb3022c19..a90de9b5d489b 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1130,7 +1130,7 @@ static ssize_t wacom_show_remote_mode(struct kobject *kobj, struct kobj_attribute *kattr, char *buf, int index) { - struct device *dev = container_of(kobj->parent, struct device, kobj); + struct device *dev = kobj_to_dev(kobj->parent); struct hid_device *hdev = to_hid_device(dev); struct wacom *wacom = hid_get_drvdata(hdev); u8 mode; @@ -1241,7 +1241,7 @@ static ssize_t wacom_store_unpair_remote(struct kobject *kobj, const char *buf, size_t count) { unsigned char selector = 0; - struct device *dev = container_of(kobj->parent, struct device, kobj); + struct device *dev = kobj_to_dev(kobj->parent); struct hid_device *hdev = to_hid_device(dev); struct wacom *wacom = hid_get_drvdata(hdev); int err; -- GitLab From 52618df95d0820be7add339068d3c42799393c09 Mon Sep 17 00:00:00 2001 From: Andrew Elble Date: Wed, 2 Dec 2015 09:19:43 -0500 Subject: [PATCH 2076/2855] nfs: fix missing assignment in nfs4_sequence_done tracepoint status_flags not set Signed-off-by: Andrew Elble Signed-off-by: Trond Myklebust --- fs/nfs/nfs4trace.h | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h index 671cf68fe56be..4c1015462a81d 100644 --- a/fs/nfs/nfs4trace.h +++ b/fs/nfs/nfs4trace.h @@ -321,6 +321,7 @@ TRACE_EVENT(nfs4_sequence_done, __entry->highest_slotid = res->sr_highest_slotid; __entry->target_highest_slotid = res->sr_target_highest_slotid; + __entry->status_flags = res->sr_status_flags; __entry->error = res->sr_status; ), TP_printk( -- GitLab From 361cad3c89070aeb37560860ea8bfc092d545adc Mon Sep 17 00:00:00 2001 From: Andrew Elble Date: Wed, 2 Dec 2015 09:20:57 -0500 Subject: [PATCH 2077/2855] nfs: Fix race in __update_open_stateid() We've seen this in a packet capture - I've intermixed what I think was going on. The fix here is to grab the so_lock sooner. 1964379 -> #1 open (for write) reply seqid=1 1964393 -> #2 open (for read) reply seqid=2 __nfs4_close(), state->n_wronly-- nfs4_state_set_mode_locked(), changes state->state = [R] state->flags is [RW] state->state is [R], state->n_wronly == 0, state->n_rdonly == 1 1964398 -> #3 open (for write) call -> because close is already running 1964399 -> downgrade (to read) call seqid=2 (close of #1) 1964402 -> #3 open (for write) reply seqid=3 __update_open_stateid() nfs_set_open_stateid_locked(), changes state->flags state->flags is [RW] state->state is [R], state->n_wronly == 0, state->n_rdonly == 1 new sequence number is exposed now via nfs4_stateid_copy() next step would be update_open_stateflags(), pending so_lock 1964403 -> downgrade reply seqid=2, fails with OLD_STATEID (close of #1) nfs4_close_prepare() gets so_lock and recalcs flags -> send close 1964405 -> downgrade (to read) call seqid=3 (close of #1 retry) __update_open_stateid() gets so_lock * update_open_stateflags() updates state->n_wronly. nfs4_state_set_mode_locked() updates state->state state->flags is [RW] state->state is [RW], state->n_wronly == 1, state->n_rdonly == 1 * should have suppressed the preceding nfs4_close_prepare() from sending open_downgrade 1964406 -> write call 1964408 -> downgrade (to read) reply seqid=4 (close of #1 retry) nfs_clear_open_stateid_locked() state->flags is [R] state->state is [RW], state->n_wronly == 1, state->n_rdonly == 1 1964409 -> write reply (fails, openmode) Signed-off-by: Andrew Elble Cc: stable@vger,kernel.org Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 89818036f035b..2f1714fda666b 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1385,6 +1385,7 @@ static void __update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_s * Protect the call to nfs4_state_set_mode_locked and * serialise the stateid update */ + spin_lock(&state->owner->so_lock); write_seqlock(&state->seqlock); if (deleg_stateid != NULL) { nfs4_stateid_copy(&state->stateid, deleg_stateid); @@ -1393,7 +1394,6 @@ static void __update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_s if (open_stateid != NULL) nfs_set_open_stateid_locked(state, open_stateid, fmode); write_sequnlock(&state->seqlock); - spin_lock(&state->owner->so_lock); update_open_stateflags(state, fmode); spin_unlock(&state->owner->so_lock); } -- GitLab From 68d264cf02b076a2457aa77c044f5e41b6fa8086 Mon Sep 17 00:00:00 2001 From: Peng Tao Date: Sun, 6 Dec 2015 20:55:09 -0500 Subject: [PATCH 2078/2855] NFS42: handle layoutstats stateid error When server returns layoutstats stateid error, we should invalidate client's layout so that next IO can trigger new layoutget. Signed-off-by: Peng Tao Signed-off-by: Trond Myklebust --- fs/nfs/nfs42proc.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 6b1ce9825430c..6e8174930a48e 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -204,6 +204,8 @@ static void nfs42_layoutstat_done(struct rpc_task *task, void *calldata) { struct nfs42_layoutstat_data *data = calldata; + struct inode *inode = data->inode; + struct pnfs_layout_hdr *lo; if (!nfs4_sequence_done(task, &data->res.seq_res)) return; @@ -211,12 +213,35 @@ nfs42_layoutstat_done(struct rpc_task *task, void *calldata) switch (task->tk_status) { case 0: break; + case -NFS4ERR_EXPIRED: + case -NFS4ERR_STALE_STATEID: + case -NFS4ERR_OLD_STATEID: + case -NFS4ERR_BAD_STATEID: + spin_lock(&inode->i_lock); + lo = NFS_I(inode)->layout; + if (lo && nfs4_stateid_match(&data->args.stateid, + &lo->plh_stateid)) { + LIST_HEAD(head); + + /* + * Mark the bad layout state as invalid, then retry + * with the current stateid. + */ + set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); + pnfs_mark_matching_lsegs_invalid(lo, &head, NULL); + spin_unlock(&inode->i_lock); + pnfs_free_lseg_list(&head); + } else + spin_unlock(&inode->i_lock); + break; case -ENOTSUPP: case -EOPNOTSUPP: - NFS_SERVER(data->inode)->caps &= ~NFS_CAP_LAYOUTSTATS; + NFS_SERVER(inode)->caps &= ~NFS_CAP_LAYOUTSTATS; default: - dprintk("%s server returns %d\n", __func__, task->tk_status); + break; } + + dprintk("%s server returns %d\n", __func__, task->tk_status); } static void -- GitLab From 95864c9154c1385c33e6782f4467c8f1422c1c90 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 26 Dec 2015 15:06:03 -0500 Subject: [PATCH 2079/2855] NFS: Allow the combination pNFS and labeled NFS Fix the nfs4_pnfs_open_bitmap so that it also allows for labeled NFS. Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 2f1714fda666b..1028d6dc40c03 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -208,6 +208,9 @@ static const u32 nfs4_pnfs_open_bitmap[3] = { | FATTR4_WORD1_TIME_METADATA | FATTR4_WORD1_TIME_MODIFY, FATTR4_WORD2_MDSTHRESHOLD +#ifdef CONFIG_NFS_V4_SECURITY_LABEL + | FATTR4_WORD2_SECURITY_LABEL +#endif }; static const u32 nfs4_open_noattr_bitmap[3] = { -- GitLab From 48c9579a1afe4315be4576ec4c0b24c2715da0e0 Mon Sep 17 00:00:00 2001 From: Olga Kornievskaia Date: Tue, 24 Nov 2015 13:29:41 -0500 Subject: [PATCH 2080/2855] Adding stateid information to tracepoints Operations to which stateid information is added: close, delegreturn, open, read, setattr, layoutget, layoutcommit, test_stateid, write, lock, locku, lockt Format is "stateid=:", also "openstateid=", "layoutstateid=", and "lockstateid=" for open_file, layoutget, set_lock tracepoints. New function is added to internal.h, nfs_stateid_hash(), to compute the hash trace_nfs4_setattr() is moved from nfs4_do_setattr() to _nfs4_do_setattr() to get access to stateid. trace_nfs4_setattr and trace_nfs4_delegreturn are changed from INODE_EVENT to new event type, INODE_STATEID_EVENT which is same as INODE_EVENT but adds stateid information for locking tracepoints, moved trace_nfs4_set_lock() into _nfs4_do_setlk() to get access to stateid information, and removed trace_nfs4_lock_reclaim(), trace_nfs4_lock_expired() as they call into _nfs4_do_setlk() and both were previously same LOCK_EVENT type. Signed-off-by: Olga Kornievskaia Signed-off-by: Trond Myklebust --- fs/nfs/internal.h | 9 ++ fs/nfs/nfs4proc.c | 13 ++- fs/nfs/nfs4trace.h | 255 ++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 245 insertions(+), 32 deletions(-) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 9dea85f7f918e..313d55402238f 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -696,9 +696,18 @@ static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh) { return ~crc32_le(0xFFFFFFFF, &fh->data[0], fh->size); } +static inline u32 nfs_stateid_hash(const nfs4_stateid *stateid) +{ + return ~crc32_le(0xFFFFFFFF, &stateid->other[0], + NFS4_STATEID_OTHER_SIZE); +} #else static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh) { return 0; } +static inline u32 nfs_stateid_hash(nfs4_stateid *stateid) +{ + return 0; +} #endif diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 89818036f035b..492d30303c4f3 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2703,6 +2703,7 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); if (status == 0 && state != NULL) renew_lease(server, timestamp); + trace_nfs4_setattr(inode, &arg.stateid, status); return status; } @@ -2719,7 +2720,6 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, int err; do { err = _nfs4_do_setattr(inode, cred, fattr, sattr, state, ilabel, olabel); - trace_nfs4_setattr(inode, err); switch (err) { case -NFS4ERR_OPENMODE: if (!(sattr->ia_valid & ATTR_SIZE)) { @@ -5426,7 +5426,7 @@ int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4 int err; do { err = _nfs4_proc_delegreturn(inode, cred, stateid, issync); - trace_nfs4_delegreturn(inode, err); + trace_nfs4_delegreturn(inode, stateid, err); switch (err) { case -NFS4ERR_STALE_STATEID: case -NFS4ERR_EXPIRED: @@ -5936,6 +5936,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f data->cancelled = 1; rpc_put_task(task); dprintk("%s: done, ret = %d!\n", __func__, ret); + trace_nfs4_set_lock(fl, state, &data->res.stateid, cmd, ret); return ret; } @@ -5952,7 +5953,6 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) return 0; err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_RECLAIM); - trace_nfs4_lock_reclaim(request, state, F_SETLK, err); if (err != -NFS4ERR_DELAY) break; nfs4_handle_exception(server, err, &exception); @@ -5979,7 +5979,6 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) return 0; err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_EXPIRED); - trace_nfs4_lock_expired(request, state, F_SETLK, err); switch (err) { default: goto out; @@ -6087,7 +6086,6 @@ static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock * do { err = _nfs4_proc_setlk(state, cmd, request); - trace_nfs4_set_lock(request, state, cmd, err); if (err == -NFS4ERR_DENIED) err = -EAGAIN; err = nfs4_handle_exception(NFS_SERVER(state->inode), @@ -7994,6 +7992,7 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) trace_nfs4_layoutget(lgp->args.ctx, &lgp->args.range, &lgp->res.range, + &lgp->res.stateid, status); /* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */ if (status == 0 && lgp->res.layoutp->len) @@ -8101,7 +8100,7 @@ int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool sync) return PTR_ERR(task); if (sync) status = task->tk_status; - trace_nfs4_layoutreturn(lrp->args.inode, status); + trace_nfs4_layoutreturn(lrp->args.inode, &lrp->args.stateid, status); dprintk("<-- %s status=%d\n", __func__, status); rpc_put_task(task); return status; @@ -8249,7 +8248,7 @@ nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, bool sync) return PTR_ERR(task); if (sync) status = task->tk_status; - trace_nfs4_layoutcommit(data->args.inode, status); + trace_nfs4_layoutcommit(data->args.inode, &data->args.stateid, status); dprintk("%s: status %d\n", __func__, status); rpc_put_task(task); return status; diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h index 671cf68fe56be..9058aecc248ef 100644 --- a/fs/nfs/nfs4trace.h +++ b/fs/nfs/nfs4trace.h @@ -399,6 +399,10 @@ DECLARE_EVENT_CLASS(nfs4_open_event, __field(u64, fileid) __field(u64, dir) __string(name, ctx->dentry->d_name.name) + __field(int, stateid_seq) + __field(u32, stateid_hash) + __field(int, openstateid_seq) + __field(u32, openstateid_hash) ), TP_fast_assign( @@ -409,8 +413,22 @@ DECLARE_EVENT_CLASS(nfs4_open_event, __entry->flags = flags; __entry->fmode = (__force unsigned int)ctx->mode; __entry->dev = ctx->dentry->d_sb->s_dev; - if (!IS_ERR_OR_NULL(state)) + if (!IS_ERR_OR_NULL(state)) { inode = state->inode; + __entry->stateid_seq = + be32_to_cpu(state->stateid.seqid); + __entry->stateid_hash = + nfs_stateid_hash(&state->stateid); + __entry->openstateid_seq = + be32_to_cpu(state->open_stateid.seqid); + __entry->openstateid_hash = + nfs_stateid_hash(&state->open_stateid); + } else { + __entry->stateid_seq = 0; + __entry->stateid_hash = 0; + __entry->openstateid_seq = 0; + __entry->openstateid_hash = 0; + } if (inode != NULL) { __entry->fileid = NFS_FILEID(inode); __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); @@ -425,7 +443,8 @@ DECLARE_EVENT_CLASS(nfs4_open_event, TP_printk( "error=%d (%s) flags=%d (%s) fmode=%s " "fileid=%02x:%02x:%llu fhandle=0x%08x " - "name=%02x:%02x:%llu/%s", + "name=%02x:%02x:%llu/%s stateid=%d:0x%08x " + "openstateid=%d:0x%08x", __entry->error, show_nfsv4_errors(__entry->error), __entry->flags, @@ -436,7 +455,9 @@ DECLARE_EVENT_CLASS(nfs4_open_event, __entry->fhandle, MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long long)__entry->dir, - __get_str(name) + __get_str(name), + __entry->stateid_seq, __entry->stateid_hash, + __entry->openstateid_seq, __entry->openstateid_hash ) ); @@ -468,6 +489,8 @@ TRACE_EVENT(nfs4_close, __field(u64, fileid) __field(unsigned int, fmode) __field(int, error) + __field(int, stateid_seq) + __field(u32, stateid_hash) ), TP_fast_assign( @@ -478,18 +501,23 @@ TRACE_EVENT(nfs4_close, __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); __entry->fmode = (__force unsigned int)state->state; __entry->error = error; + __entry->stateid_seq = + be32_to_cpu(args->stateid.seqid); + __entry->stateid_hash = + nfs_stateid_hash(&args->stateid); ), TP_printk( "error=%d (%s) fmode=%s fileid=%02x:%02x:%llu " - "fhandle=0x%08x", + "fhandle=0x%08x openstateid=%d:0x%08x", __entry->error, show_nfsv4_errors(__entry->error), __entry->fmode ? show_fmode_flags(__entry->fmode) : "closed", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long long)__entry->fileid, - __entry->fhandle + __entry->fhandle, + __entry->stateid_seq, __entry->stateid_hash ) ); @@ -523,6 +551,8 @@ DECLARE_EVENT_CLASS(nfs4_lock_event, __field(dev_t, dev) __field(u32, fhandle) __field(u64, fileid) + __field(int, stateid_seq) + __field(u32, stateid_hash) ), TP_fast_assign( @@ -536,11 +566,16 @@ DECLARE_EVENT_CLASS(nfs4_lock_event, __entry->dev = inode->i_sb->s_dev; __entry->fileid = NFS_FILEID(inode); __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); + __entry->stateid_seq = + be32_to_cpu(state->stateid.seqid); + __entry->stateid_hash = + nfs_stateid_hash(&state->stateid); ), TP_printk( "error=%d (%s) cmd=%s:%s range=%lld:%lld " - "fileid=%02x:%02x:%llu fhandle=0x%08x", + "fileid=%02x:%02x:%llu fhandle=0x%08x " + "stateid=%d:0x%08x", __entry->error, show_nfsv4_errors(__entry->error), show_lock_cmd(__entry->cmd), @@ -549,7 +584,8 @@ DECLARE_EVENT_CLASS(nfs4_lock_event, (long long)__entry->end, MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long long)__entry->fileid, - __entry->fhandle + __entry->fhandle, + __entry->stateid_seq, __entry->stateid_hash ) ); @@ -563,11 +599,73 @@ DECLARE_EVENT_CLASS(nfs4_lock_event, ), \ TP_ARGS(request, state, cmd, error)) DEFINE_NFS4_LOCK_EVENT(nfs4_get_lock); -DEFINE_NFS4_LOCK_EVENT(nfs4_set_lock); -DEFINE_NFS4_LOCK_EVENT(nfs4_lock_reclaim); -DEFINE_NFS4_LOCK_EVENT(nfs4_lock_expired); DEFINE_NFS4_LOCK_EVENT(nfs4_unlock); +TRACE_EVENT(nfs4_set_lock, + TP_PROTO( + const struct file_lock *request, + const struct nfs4_state *state, + const nfs4_stateid *lockstateid, + int cmd, + int error + ), + + TP_ARGS(request, state, lockstateid, cmd, error), + + TP_STRUCT__entry( + __field(int, error) + __field(int, cmd) + __field(char, type) + __field(loff_t, start) + __field(loff_t, end) + __field(dev_t, dev) + __field(u32, fhandle) + __field(u64, fileid) + __field(int, stateid_seq) + __field(u32, stateid_hash) + __field(int, lockstateid_seq) + __field(u32, lockstateid_hash) + ), + + TP_fast_assign( + const struct inode *inode = state->inode; + + __entry->error = error; + __entry->cmd = cmd; + __entry->type = request->fl_type; + __entry->start = request->fl_start; + __entry->end = request->fl_end; + __entry->dev = inode->i_sb->s_dev; + __entry->fileid = NFS_FILEID(inode); + __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); + __entry->stateid_seq = + be32_to_cpu(state->stateid.seqid); + __entry->stateid_hash = + nfs_stateid_hash(&state->stateid); + __entry->lockstateid_seq = + be32_to_cpu(lockstateid->seqid); + __entry->lockstateid_hash = + nfs_stateid_hash(lockstateid); + ), + + TP_printk( + "error=%d (%s) cmd=%s:%s range=%lld:%lld " + "fileid=%02x:%02x:%llu fhandle=0x%08x " + "stateid=%d:0x%08x lockstateid=%d:0x%08x", + __entry->error, + show_nfsv4_errors(__entry->error), + show_lock_cmd(__entry->cmd), + show_lock_type(__entry->type), + (long long)__entry->start, + (long long)__entry->end, + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long long)__entry->fileid, + __entry->fhandle, + __entry->stateid_seq, __entry->stateid_hash, + __entry->lockstateid_seq, __entry->lockstateid_hash + ) +); + DECLARE_EVENT_CLASS(nfs4_set_delegation_event, TP_PROTO( const struct inode *inode, @@ -621,20 +719,28 @@ TRACE_EVENT(nfs4_delegreturn_exit, __field(dev_t, dev) __field(u32, fhandle) __field(int, error) + __field(int, stateid_seq) + __field(u32, stateid_hash) ), TP_fast_assign( __entry->dev = res->server->s_dev; __entry->fhandle = nfs_fhandle_hash(args->fhandle); __entry->error = error; + __entry->stateid_seq = + be32_to_cpu(args->stateid->seqid); + __entry->stateid_hash = + nfs_stateid_hash(args->stateid); ), TP_printk( - "error=%d (%s) dev=%02x:%02x fhandle=0x%08x", + "error=%d (%s) dev=%02x:%02x fhandle=0x%08x " + "stateid=%d:0x%08x", __entry->error, show_nfsv4_errors(__entry->error), MAJOR(__entry->dev), MINOR(__entry->dev), - __entry->fhandle + __entry->fhandle, + __entry->stateid_seq, __entry->stateid_hash ) ); @@ -653,6 +759,8 @@ DECLARE_EVENT_CLASS(nfs4_test_stateid_event, __field(dev_t, dev) __field(u32, fhandle) __field(u64, fileid) + __field(int, stateid_seq) + __field(u32, stateid_hash) ), TP_fast_assign( @@ -662,15 +770,21 @@ DECLARE_EVENT_CLASS(nfs4_test_stateid_event, __entry->dev = inode->i_sb->s_dev; __entry->fileid = NFS_FILEID(inode); __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); + __entry->stateid_seq = + be32_to_cpu(state->stateid.seqid); + __entry->stateid_hash = + nfs_stateid_hash(&state->stateid); ), TP_printk( - "error=%d (%s) fileid=%02x:%02x:%llu fhandle=0x%08x", + "error=%d (%s) fileid=%02x:%02x:%llu fhandle=0x%08x " + "stateid=%d:0x%08x", __entry->error, show_nfsv4_errors(__entry->error), MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long long)__entry->fileid, - __entry->fhandle + __entry->fhandle, + __entry->stateid_seq, __entry->stateid_hash ) ); @@ -820,7 +934,6 @@ DECLARE_EVENT_CLASS(nfs4_inode_event, ), \ TP_ARGS(inode, error)) -DEFINE_NFS4_INODE_EVENT(nfs4_setattr); DEFINE_NFS4_INODE_EVENT(nfs4_access); DEFINE_NFS4_INODE_EVENT(nfs4_readlink); DEFINE_NFS4_INODE_EVENT(nfs4_readdir); @@ -831,7 +944,59 @@ DEFINE_NFS4_INODE_EVENT(nfs4_get_security_label); DEFINE_NFS4_INODE_EVENT(nfs4_set_security_label); #endif /* CONFIG_NFS_V4_SECURITY_LABEL */ DEFINE_NFS4_INODE_EVENT(nfs4_recall_delegation); -DEFINE_NFS4_INODE_EVENT(nfs4_delegreturn); + +DECLARE_EVENT_CLASS(nfs4_inode_stateid_event, + TP_PROTO( + const struct inode *inode, + const nfs4_stateid *stateid, + int error + ), + + TP_ARGS(inode, stateid, error), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(u32, fhandle) + __field(u64, fileid) + __field(int, error) + __field(int, stateid_seq) + __field(u32, stateid_hash) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->fileid = NFS_FILEID(inode); + __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); + __entry->error = error; + __entry->stateid_seq = + be32_to_cpu(stateid->seqid); + __entry->stateid_hash = + nfs_stateid_hash(stateid); + ), + + TP_printk( + "error=%d (%s) fileid=%02x:%02x:%llu fhandle=0x%08x " + "stateid=%d:0x%08x", + __entry->error, + show_nfsv4_errors(__entry->error), + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long long)__entry->fileid, + __entry->fhandle, + __entry->stateid_seq, __entry->stateid_hash + ) +); + +#define DEFINE_NFS4_INODE_STATEID_EVENT(name) \ + DEFINE_EVENT(nfs4_inode_stateid_event, name, \ + TP_PROTO( \ + const struct inode *inode, \ + const nfs4_stateid *stateid, \ + int error \ + ), \ + TP_ARGS(inode, stateid, error)) + +DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_setattr); +DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_delegreturn); DECLARE_EVENT_CLASS(nfs4_getattr_event, TP_PROTO( @@ -1005,28 +1170,37 @@ DECLARE_EVENT_CLASS(nfs4_read_event, __field(loff_t, offset) __field(size_t, count) __field(int, error) + __field(int, stateid_seq) + __field(u32, stateid_hash) ), TP_fast_assign( const struct inode *inode = hdr->inode; + const struct nfs4_state *state = + hdr->args.context->state; __entry->dev = inode->i_sb->s_dev; __entry->fileid = NFS_FILEID(inode); __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); __entry->offset = hdr->args.offset; __entry->count = hdr->args.count; __entry->error = error; + __entry->stateid_seq = + be32_to_cpu(state->stateid.seqid); + __entry->stateid_hash = + nfs_stateid_hash(&state->stateid); ), TP_printk( "error=%d (%s) fileid=%02x:%02x:%llu fhandle=0x%08x " - "offset=%lld count=%zu", + "offset=%lld count=%zu stateid=%d:0x%08x", __entry->error, show_nfsv4_errors(__entry->error), MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long long)__entry->fileid, __entry->fhandle, (long long)__entry->offset, - __entry->count + __entry->count, + __entry->stateid_seq, __entry->stateid_hash ) ); #define DEFINE_NFS4_READ_EVENT(name) \ @@ -1056,28 +1230,37 @@ DECLARE_EVENT_CLASS(nfs4_write_event, __field(loff_t, offset) __field(size_t, count) __field(int, error) + __field(int, stateid_seq) + __field(u32, stateid_hash) ), TP_fast_assign( const struct inode *inode = hdr->inode; + const struct nfs4_state *state = + hdr->args.context->state; __entry->dev = inode->i_sb->s_dev; __entry->fileid = NFS_FILEID(inode); __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); __entry->offset = hdr->args.offset; __entry->count = hdr->args.count; __entry->error = error; + __entry->stateid_seq = + be32_to_cpu(state->stateid.seqid); + __entry->stateid_hash = + nfs_stateid_hash(&state->stateid); ), TP_printk( "error=%d (%s) fileid=%02x:%02x:%llu fhandle=0x%08x " - "offset=%lld count=%zu", + "offset=%lld count=%zu stateid=%d:0x%08x", __entry->error, show_nfsv4_errors(__entry->error), MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long long)__entry->fileid, __entry->fhandle, (long long)__entry->offset, - __entry->count + __entry->count, + __entry->stateid_seq, __entry->stateid_hash ) ); @@ -1154,10 +1337,11 @@ TRACE_EVENT(nfs4_layoutget, const struct nfs_open_context *ctx, const struct pnfs_layout_range *args, const struct pnfs_layout_range *res, + const nfs4_stateid *layout_stateid, int error ), - TP_ARGS(ctx, args, res, error), + TP_ARGS(ctx, args, res, layout_stateid, error), TP_STRUCT__entry( __field(dev_t, dev) @@ -1167,10 +1351,15 @@ TRACE_EVENT(nfs4_layoutget, __field(u64, offset) __field(u64, count) __field(int, error) + __field(int, stateid_seq) + __field(u32, stateid_hash) + __field(int, layoutstateid_seq) + __field(u32, layoutstateid_hash) ), TP_fast_assign( const struct inode *inode = d_inode(ctx->dentry); + const struct nfs4_state *state = ctx->state; __entry->dev = inode->i_sb->s_dev; __entry->fileid = NFS_FILEID(inode); __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); @@ -1178,11 +1367,25 @@ TRACE_EVENT(nfs4_layoutget, __entry->offset = args->offset; __entry->count = args->length; __entry->error = error; + __entry->stateid_seq = + be32_to_cpu(state->stateid.seqid); + __entry->stateid_hash = + nfs_stateid_hash(&state->stateid); + if (!error) { + __entry->layoutstateid_seq = + be32_to_cpu(layout_stateid->seqid); + __entry->layoutstateid_hash = + nfs_stateid_hash(layout_stateid); + } else { + __entry->layoutstateid_seq = 0; + __entry->layoutstateid_hash = 0; + } ), TP_printk( "error=%d (%s) fileid=%02x:%02x:%llu fhandle=0x%08x " - "iomode=%s offset=%llu count=%llu", + "iomode=%s offset=%llu count=%llu stateid=%d:0x%08x " + "layoutstateid=%d:0x%08x", __entry->error, show_nfsv4_errors(__entry->error), MAJOR(__entry->dev), MINOR(__entry->dev), @@ -1190,12 +1393,14 @@ TRACE_EVENT(nfs4_layoutget, __entry->fhandle, show_pnfs_iomode(__entry->iomode), (unsigned long long)__entry->offset, - (unsigned long long)__entry->count + (unsigned long long)__entry->count, + __entry->stateid_seq, __entry->stateid_hash, + __entry->layoutstateid_seq, __entry->layoutstateid_hash ) ); -DEFINE_NFS4_INODE_EVENT(nfs4_layoutcommit); -DEFINE_NFS4_INODE_EVENT(nfs4_layoutreturn); +DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_layoutcommit); +DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_layoutreturn); DEFINE_NFS4_INODE_EVENT(nfs4_layoutreturn_on_close); #endif /* CONFIG_NFS_V4_1 */ -- GitLab From 9759b0fb1d202e6bc9bdab10612189abc9389df8 Mon Sep 17 00:00:00 2001 From: Olga Kornievskaia Date: Tue, 24 Nov 2015 13:29:42 -0500 Subject: [PATCH 2081/2855] Adding tracepoint to cached open Signed-off-by: Olga Kornievskaia Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 2 ++ fs/nfs/nfs4trace.h | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 492d30303c4f3..e941261527144 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1598,6 +1598,7 @@ _nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data) if (!data->rpc_done) { state = nfs4_try_open_cached(data); + trace_nfs4_cached_open(data->state); goto out; } @@ -2015,6 +2016,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) } return; unlock_no_action: + trace_nfs4_cached_open(data->state); rcu_read_unlock(); out_no_action: task->tk_action = NULL; diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h index 9058aecc248ef..8704372ac38fc 100644 --- a/fs/nfs/nfs4trace.h +++ b/fs/nfs/nfs4trace.h @@ -473,6 +473,45 @@ DEFINE_NFS4_OPEN_EVENT(nfs4_open_reclaim); DEFINE_NFS4_OPEN_EVENT(nfs4_open_expired); DEFINE_NFS4_OPEN_EVENT(nfs4_open_file); +TRACE_EVENT(nfs4_cached_open, + TP_PROTO( + const struct nfs4_state *state + ), + TP_ARGS(state), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(u32, fhandle) + __field(u64, fileid) + __field(unsigned int, fmode) + __field(int, stateid_seq) + __field(u32, stateid_hash) + ), + + TP_fast_assign( + const struct inode *inode = state->inode; + + __entry->dev = inode->i_sb->s_dev; + __entry->fileid = NFS_FILEID(inode); + __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); + __entry->fmode = (__force unsigned int)state->state; + __entry->stateid_seq = + be32_to_cpu(state->stateid.seqid); + __entry->stateid_hash = + nfs_stateid_hash(&state->stateid); + ), + + TP_printk( + "fmode=%s fileid=%02x:%02x:%llu " + "fhandle=0x%08x stateid=%d:0x%08x", + __entry->fmode ? show_fmode_flags(__entry->fmode) : + "closed", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long long)__entry->fileid, + __entry->fhandle, + __entry->stateid_seq, __entry->stateid_hash + ) +); + TRACE_EVENT(nfs4_close, TP_PROTO( const struct nfs4_state *state, -- GitLab From 9a4bf31d05a801e2358d96f69b39fb8ce2c69dd8 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Thu, 10 Dec 2015 10:41:58 -0500 Subject: [PATCH 2082/2855] nfs: add new tracepoint for pnfs_update_layout pnfs_update_layout is really the "nexus" of layout handling. If it returns NULL then we end up going through the MDS. This patch adds some tracepoints to that function that allow us to determine the cause when we end up going through the MDS unexpectedly. Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust --- fs/nfs/nfs4trace.h | 56 ++++++++++++++++++++++++++++++++++++++++++++ fs/nfs/pnfs.c | 38 +++++++++++++++++++++++++----- include/linux/nfs4.h | 14 +++++++++++ 3 files changed, 102 insertions(+), 6 deletions(-) diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h index 8704372ac38fc..238925c1aafdc 100644 --- a/fs/nfs/nfs4trace.h +++ b/fs/nfs/nfs4trace.h @@ -1442,6 +1442,62 @@ DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_layoutcommit); DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_layoutreturn); DEFINE_NFS4_INODE_EVENT(nfs4_layoutreturn_on_close); +#define show_pnfs_update_layout_reason(reason) \ + __print_symbolic(reason, \ + { PNFS_UPDATE_LAYOUT_UNKNOWN, "unknown" }, \ + { PNFS_UPDATE_LAYOUT_NO_PNFS, "no pnfs" }, \ + { PNFS_UPDATE_LAYOUT_RD_ZEROLEN, "read+zerolen" }, \ + { PNFS_UPDATE_LAYOUT_MDSTHRESH, "mdsthresh" }, \ + { PNFS_UPDATE_LAYOUT_NOMEM, "nomem" }, \ + { PNFS_UPDATE_LAYOUT_BULK_RECALL, "bulk recall" }, \ + { PNFS_UPDATE_LAYOUT_IO_TEST_FAIL, "io test fail" }, \ + { PNFS_UPDATE_LAYOUT_FOUND_CACHED, "found cached" }, \ + { PNFS_UPDATE_LAYOUT_RETURN, "layoutreturn" }, \ + { PNFS_UPDATE_LAYOUT_BLOCKED, "layouts blocked" }, \ + { PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET, "sent layoutget" }) + +TRACE_EVENT(pnfs_update_layout, + TP_PROTO(struct inode *inode, + loff_t pos, + u64 count, + enum pnfs_iomode iomode, + struct pnfs_layout_segment *lseg, + enum pnfs_update_layout_reason reason + ), + TP_ARGS(inode, pos, count, iomode, lseg, reason), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(u64, fileid) + __field(u32, fhandle) + __field(loff_t, pos) + __field(u64, count) + __field(enum pnfs_iomode, iomode) + __field(struct pnfs_layout_segment *, lseg) + __field(enum pnfs_update_layout_reason, reason) + ), + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->fileid = NFS_FILEID(inode); + __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); + __entry->pos = pos; + __entry->count = count; + __entry->iomode = iomode; + __entry->lseg = lseg; + __entry->reason = reason; + ), + TP_printk( + "fileid=%02x:%02x:%llu fhandle=0x%08x " + "iomode=%s pos=%llu count=%llu lseg=%p (%s)", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long long)__entry->fileid, + __entry->fhandle, + show_pnfs_iomode(__entry->iomode), + (unsigned long long)__entry->pos, + (unsigned long long)__entry->count, __entry->lseg, + show_pnfs_update_layout_reason(__entry->reason) + ) +); + #endif /* CONFIG_NFS_V4_1 */ #endif /* _TRACE_NFS4_H */ diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index bec0384499f76..1489065bb0514 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -1520,14 +1520,23 @@ pnfs_update_layout(struct inode *ino, struct pnfs_layout_segment *lseg = NULL; bool first; - if (!pnfs_enabled_sb(NFS_SERVER(ino))) + if (!pnfs_enabled_sb(NFS_SERVER(ino))) { + trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + PNFS_UPDATE_LAYOUT_NO_PNFS); goto out; + } - if (iomode == IOMODE_READ && i_size_read(ino) == 0) + if (iomode == IOMODE_READ && i_size_read(ino) == 0) { + trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + PNFS_UPDATE_LAYOUT_RD_ZEROLEN); goto out; + } - if (pnfs_within_mdsthreshold(ctx, ino, iomode)) + if (pnfs_within_mdsthreshold(ctx, ino, iomode)) { + trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + PNFS_UPDATE_LAYOUT_MDSTHRESH); goto out; + } lookup_again: first = false; @@ -1535,19 +1544,26 @@ lookup_again: lo = pnfs_find_alloc_layout(ino, ctx, gfp_flags); if (lo == NULL) { spin_unlock(&ino->i_lock); + trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + PNFS_UPDATE_LAYOUT_NOMEM); goto out; } /* Do we even need to bother with this? */ if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags)) { + trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + PNFS_UPDATE_LAYOUT_BULK_RECALL); dprintk("%s matches recall, use MDS\n", __func__); goto out_unlock; } /* if LAYOUTGET already failed once we don't try again */ if (pnfs_layout_io_test_failed(lo, iomode) && - !pnfs_should_retry_layoutget(lo)) + !pnfs_should_retry_layoutget(lo)) { + trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + PNFS_UPDATE_LAYOUT_IO_TEST_FAIL); goto out_unlock; + } first = list_empty(&lo->plh_segs); if (first) { @@ -1567,8 +1583,11 @@ lookup_again: * already exists */ lseg = pnfs_find_lseg(lo, &arg); - if (lseg) + if (lseg) { + trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + PNFS_UPDATE_LAYOUT_FOUND_CACHED); goto out_unlock; + } } /* @@ -1585,11 +1604,16 @@ lookup_again: dprintk("%s retrying\n", __func__); goto lookup_again; } + trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + PNFS_UPDATE_LAYOUT_RETURN); goto out_put_layout_hdr; } - if (pnfs_layoutgets_blocked(lo)) + if (pnfs_layoutgets_blocked(lo)) { + trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + PNFS_UPDATE_LAYOUT_BLOCKED); goto out_unlock; + } atomic_inc(&lo->plh_outstanding); spin_unlock(&ino->i_lock); @@ -1614,6 +1638,8 @@ lookup_again: lseg = send_layoutget(lo, ctx, &arg, gfp_flags); pnfs_clear_retry_layoutget(lo); atomic_dec(&lo->plh_outstanding); + trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET); out_put_layout_hdr: if (first) pnfs_clear_first_layoutget(lo); diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index e7e78537aea2c..0e30f2c5ff49e 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -592,4 +592,18 @@ enum data_content4 { NFS4_CONTENT_HOLE = 1, }; +enum pnfs_update_layout_reason { + PNFS_UPDATE_LAYOUT_UNKNOWN = 0, + PNFS_UPDATE_LAYOUT_NO_PNFS, + PNFS_UPDATE_LAYOUT_RD_ZEROLEN, + PNFS_UPDATE_LAYOUT_MDSTHRESH, + PNFS_UPDATE_LAYOUT_NOMEM, + PNFS_UPDATE_LAYOUT_BULK_RECALL, + PNFS_UPDATE_LAYOUT_IO_TEST_FAIL, + PNFS_UPDATE_LAYOUT_FOUND_CACHED, + PNFS_UPDATE_LAYOUT_RETURN, + PNFS_UPDATE_LAYOUT_BLOCKED, + PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET, +}; + #endif -- GitLab From f2dd436edb2b38b555f3ff7257308bb56fa4eea5 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 8 Oct 2015 11:33:17 -0400 Subject: [PATCH 2083/2855] NFSv4: Fix unused variable warnings in nfs4_init_*_client_string() Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index e941261527144..18d862db15b63 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -5050,7 +5050,6 @@ static void nfs4_init_boot_verifier(const struct nfs_client *clp, static int nfs4_init_nonuniform_client_string(struct nfs_client *clp) { - int result; size_t len; char *str; @@ -5078,7 +5077,7 @@ nfs4_init_nonuniform_client_string(struct nfs_client *clp) return -ENOMEM; rcu_read_lock(); - result = scnprintf(str, len, "Linux NFSv4.0 %s/%s %s", + scnprintf(str, len, "Linux NFSv4.0 %s/%s %s", clp->cl_ipaddr, rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR), rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_PROTO)); @@ -5091,7 +5090,6 @@ nfs4_init_nonuniform_client_string(struct nfs_client *clp) static int nfs4_init_uniquifier_client_string(struct nfs_client *clp) { - int result; size_t len; char *str; @@ -5111,7 +5109,7 @@ nfs4_init_uniquifier_client_string(struct nfs_client *clp) if (!str) return -ENOMEM; - result = scnprintf(str, len, "Linux NFSv%u.%u %s/%s", + scnprintf(str, len, "Linux NFSv%u.%u %s/%s", clp->rpc_ops->version, clp->cl_minorversion, nfs4_client_id_uniquifier, clp->cl_rpcclient->cl_nodename); @@ -5122,7 +5120,6 @@ nfs4_init_uniquifier_client_string(struct nfs_client *clp) static int nfs4_init_uniform_client_string(struct nfs_client *clp) { - int result; size_t len; char *str; @@ -5147,7 +5144,7 @@ nfs4_init_uniform_client_string(struct nfs_client *clp) if (!str) return -ENOMEM; - result = scnprintf(str, len, "Linux NFSv%u.%u %s", + scnprintf(str, len, "Linux NFSv%u.%u %s", clp->rpc_ops->version, clp->cl_minorversion, clp->cl_rpcclient->cl_nodename); clp->cl_owner_id = str; -- GitLab From f4848303ce125999886535323a64db26dba68293 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 26 Dec 2015 18:03:07 -0500 Subject: [PATCH 2084/2855] pNFS: Modify pnfs_update_layout tracepoints to use layout stateid Instead of displaying a layout segment pointer in these tracepoints, let's use the layout stateid, now that Olga gave us a set of tools for displaying them. Signed-off-by: Trond Myklebust --- fs/nfs/nfs4trace.c | 1 + fs/nfs/nfs4trace.h | 23 +++++++++++++++++------ fs/nfs/pnfs.c | 20 ++++++++++---------- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/fs/nfs/nfs4trace.c b/fs/nfs/nfs4trace.c index d774335cc8bca..2850bce192443 100644 --- a/fs/nfs/nfs4trace.c +++ b/fs/nfs/nfs4trace.c @@ -6,6 +6,7 @@ #include "internal.h" #include "nfs4session.h" #include "callback.h" +#include "pnfs.h" #define CREATE_TRACE_POINTS #include "nfs4trace.h" diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h index 238925c1aafdc..d08d0c84b7789 100644 --- a/fs/nfs/nfs4trace.h +++ b/fs/nfs/nfs4trace.h @@ -1461,10 +1461,10 @@ TRACE_EVENT(pnfs_update_layout, loff_t pos, u64 count, enum pnfs_iomode iomode, - struct pnfs_layout_segment *lseg, + struct pnfs_layout_hdr *lo, enum pnfs_update_layout_reason reason ), - TP_ARGS(inode, pos, count, iomode, lseg, reason), + TP_ARGS(inode, pos, count, iomode, lo, reason), TP_STRUCT__entry( __field(dev_t, dev) __field(u64, fileid) @@ -1472,7 +1472,8 @@ TRACE_EVENT(pnfs_update_layout, __field(loff_t, pos) __field(u64, count) __field(enum pnfs_iomode, iomode) - __field(struct pnfs_layout_segment *, lseg) + __field(int, layoutstateid_seq) + __field(u32, layoutstateid_hash) __field(enum pnfs_update_layout_reason, reason) ), TP_fast_assign( @@ -1482,18 +1483,28 @@ TRACE_EVENT(pnfs_update_layout, __entry->pos = pos; __entry->count = count; __entry->iomode = iomode; - __entry->lseg = lseg; __entry->reason = reason; + if (lo != NULL) { + __entry->layoutstateid_seq = + be32_to_cpu(lo->plh_stateid.seqid); + __entry->layoutstateid_hash = + nfs_stateid_hash(&lo->plh_stateid); + } else { + __entry->layoutstateid_seq = 0; + __entry->layoutstateid_hash = 0; + } ), TP_printk( "fileid=%02x:%02x:%llu fhandle=0x%08x " - "iomode=%s pos=%llu count=%llu lseg=%p (%s)", + "iomode=%s pos=%llu count=%llu " + "layoutstateid=%d:0x%08x (%s)", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long long)__entry->fileid, __entry->fhandle, show_pnfs_iomode(__entry->iomode), (unsigned long long)__entry->pos, - (unsigned long long)__entry->count, __entry->lseg, + (unsigned long long)__entry->count, + __entry->layoutstateid_seq, __entry->layoutstateid_hash, show_pnfs_update_layout_reason(__entry->reason) ) ); diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 1489065bb0514..6095a8d42766c 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -1521,19 +1521,19 @@ pnfs_update_layout(struct inode *ino, bool first; if (!pnfs_enabled_sb(NFS_SERVER(ino))) { - trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + trace_pnfs_update_layout(ino, pos, count, iomode, NULL, PNFS_UPDATE_LAYOUT_NO_PNFS); goto out; } if (iomode == IOMODE_READ && i_size_read(ino) == 0) { - trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + trace_pnfs_update_layout(ino, pos, count, iomode, NULL, PNFS_UPDATE_LAYOUT_RD_ZEROLEN); goto out; } if (pnfs_within_mdsthreshold(ctx, ino, iomode)) { - trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + trace_pnfs_update_layout(ino, pos, count, iomode, NULL, PNFS_UPDATE_LAYOUT_MDSTHRESH); goto out; } @@ -1544,14 +1544,14 @@ lookup_again: lo = pnfs_find_alloc_layout(ino, ctx, gfp_flags); if (lo == NULL) { spin_unlock(&ino->i_lock); - trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + trace_pnfs_update_layout(ino, pos, count, iomode, NULL, PNFS_UPDATE_LAYOUT_NOMEM); goto out; } /* Do we even need to bother with this? */ if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags)) { - trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + trace_pnfs_update_layout(ino, pos, count, iomode, lo, PNFS_UPDATE_LAYOUT_BULK_RECALL); dprintk("%s matches recall, use MDS\n", __func__); goto out_unlock; @@ -1560,7 +1560,7 @@ lookup_again: /* if LAYOUTGET already failed once we don't try again */ if (pnfs_layout_io_test_failed(lo, iomode) && !pnfs_should_retry_layoutget(lo)) { - trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + trace_pnfs_update_layout(ino, pos, count, iomode, lo, PNFS_UPDATE_LAYOUT_IO_TEST_FAIL); goto out_unlock; } @@ -1584,7 +1584,7 @@ lookup_again: */ lseg = pnfs_find_lseg(lo, &arg); if (lseg) { - trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + trace_pnfs_update_layout(ino, pos, count, iomode, lo, PNFS_UPDATE_LAYOUT_FOUND_CACHED); goto out_unlock; } @@ -1604,13 +1604,13 @@ lookup_again: dprintk("%s retrying\n", __func__); goto lookup_again; } - trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + trace_pnfs_update_layout(ino, pos, count, iomode, lo, PNFS_UPDATE_LAYOUT_RETURN); goto out_put_layout_hdr; } if (pnfs_layoutgets_blocked(lo)) { - trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + trace_pnfs_update_layout(ino, pos, count, iomode, lo, PNFS_UPDATE_LAYOUT_BLOCKED); goto out_unlock; } @@ -1638,7 +1638,7 @@ lookup_again: lseg = send_layoutget(lo, ctx, &arg, gfp_flags); pnfs_clear_retry_layoutget(lo); atomic_dec(&lo->plh_outstanding); - trace_pnfs_update_layout(ino, pos, count, iomode, lseg, + trace_pnfs_update_layout(ino, pos, count, iomode, lo, PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET); out_put_layout_hdr: if (first) -- GitLab From ed476752493bc997f1690516fdc0609ddcbaca82 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Fri, 4 Dec 2015 16:06:57 +0800 Subject: [PATCH 2085/2855] nfs: do not initialise statics to 0 This patch fixes the checkpatch.pl error to nfs4sysctl.c: ERROR: do not initialise statics to 0 Signed-off-by: Wei Tang Signed-off-by: Trond Myklebust --- fs/nfs/nfs4sysctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/nfs4sysctl.c b/fs/nfs/nfs4sysctl.c index 0fbd3ab1be222..8693d77c45ea4 100644 --- a/fs/nfs/nfs4sysctl.c +++ b/fs/nfs/nfs4sysctl.c @@ -12,7 +12,7 @@ #include "nfs4idmap.h" #include "callback.h" -static const int nfs_set_port_min = 0; +static const int nfs_set_port_min; static const int nfs_set_port_max = 65535; static struct ctl_table_header *nfs4_callback_sysctl_table; -- GitLab From 99ade3c71b1e40e7174d6527709399a87f3d05e0 Mon Sep 17 00:00:00 2001 From: Andrew Elble Date: Wed, 2 Dec 2015 09:39:51 -0500 Subject: [PATCH 2086/2855] nfs: machine credential support for additional operations Allow LAYOUTRETURN and DELEGRETURN to use machine credentials if the server supports it. Add request for OPEN_DOWNGRADE as the close path also uses that. Signed-off-by: Andrew Elble Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 20 ++++++++++++++++++++ include/linux/nfs_fs_sb.h | 1 + 2 files changed, 21 insertions(+) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 18d862db15b63..a7d564a836650 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -5383,6 +5383,11 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co if (data == NULL) return -ENOMEM; nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1); + + nfs4_state_protect(server->nfs_client, + NFS_SP4_MACH_CRED_CLEANUP, + &task_setup_data.rpc_client, &msg); + data->args.fhandle = &data->fh; data->args.stateid = &data->stateid; data->args.bitmask = server->cache_consistency_bitmask; @@ -6859,10 +6864,13 @@ static const struct nfs41_state_protection nfs4_sp4_mach_cred_request = { }, .allow.u.words = { [0] = 1 << (OP_CLOSE) | + 1 << (OP_OPEN_DOWNGRADE) | 1 << (OP_LOCKU) | + 1 << (OP_DELEGRETURN) | 1 << (OP_COMMIT), [1] = 1 << (OP_SECINFO - 32) | 1 << (OP_SECINFO_NO_NAME - 32) | + 1 << (OP_LAYOUTRETURN - 32) | 1 << (OP_TEST_STATEID - 32) | 1 << (OP_FREE_STATEID - 32) | 1 << (OP_WRITE - 32) @@ -6927,11 +6935,19 @@ static int nfs4_sp4_select_mode(struct nfs_client *clp, } if (test_bit(OP_CLOSE, sp->allow.u.longs) && + test_bit(OP_OPEN_DOWNGRADE, sp->allow.u.longs) && + test_bit(OP_DELEGRETURN, sp->allow.u.longs) && test_bit(OP_LOCKU, sp->allow.u.longs)) { dfprintk(MOUNT, " cleanup mode enabled\n"); set_bit(NFS_SP4_MACH_CRED_CLEANUP, &clp->cl_sp4_flags); } + if (test_bit(OP_LAYOUTRETURN, sp->allow.u.longs)) { + dfprintk(MOUNT, " pnfs cleanup mode enabled\n"); + set_bit(NFS_SP4_MACH_CRED_PNFS_CLEANUP, + &clp->cl_sp4_flags); + } + if (test_bit(OP_SECINFO, sp->allow.u.longs) && test_bit(OP_SECINFO_NO_NAME, sp->allow.u.longs)) { dfprintk(MOUNT, " secinfo mode enabled\n"); @@ -8084,6 +8100,10 @@ int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool sync) }; int status = 0; + nfs4_state_protect(NFS_SERVER(lrp->args.inode)->nfs_client, + NFS_SP4_MACH_CRED_PNFS_CLEANUP, + &task_setup_data.rpc_client, &msg); + dprintk("--> %s\n", __func__); if (!sync) { lrp->inode = nfs_igrab_and_active(lrp->args.inode); diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 2469ab0bb3a1f..7fcc13c8cf1f3 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -102,6 +102,7 @@ struct nfs_client { #define NFS_SP4_MACH_CRED_STATEID 4 /* TEST_STATEID and FREE_STATEID */ #define NFS_SP4_MACH_CRED_WRITE 5 /* WRITE */ #define NFS_SP4_MACH_CRED_COMMIT 6 /* COMMIT */ +#define NFS_SP4_MACH_CRED_PNFS_CLEANUP 7 /* LAYOUTRETURN */ #endif /* CONFIG_NFS_V4 */ /* Our own IP address, as a null-terminated string. -- GitLab From d1358917f2eb530bc6a097937302282a428806f8 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Wed, 2 Dec 2015 14:17:52 +0800 Subject: [PATCH 2087/2855] SUNRPC: drop unused xs_reclassify_socketX() helpers xs_reclassify_socket4() and friends used to be called directly. xs_reclassify_socket() is called instead nowadays. The xs_reclassify_socketX() helper functions are empty when CONFIG_DEBUG_LOCK_ALLOC is not defined. Drop them since they have no callers. Note that AF_LOCAL still calls xs_reclassify_socketu() directly but is easily converted to generic xs_reclassify_socket(). Signed-off-by: Stefan Hajnoczi Signed-off-by: Trond Myklebust --- net/sunrpc/xprtsock.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 2ffaf6a794994..70c13d675dc1b 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -1907,18 +1907,6 @@ static inline void xs_reclassify_socket(int family, struct socket *sock) } } #else -static inline void xs_reclassify_socketu(struct socket *sock) -{ -} - -static inline void xs_reclassify_socket4(struct socket *sock) -{ -} - -static inline void xs_reclassify_socket6(struct socket *sock) -{ -} - static inline void xs_reclassify_socket(int family, struct socket *sock) { } @@ -2008,7 +1996,7 @@ static int xs_local_setup_socket(struct sock_xprt *transport) "transport socket (%d).\n", -status); goto out; } - xs_reclassify_socketu(sock); + xs_reclassify_socket(AF_LOCAL, sock); dprintk("RPC: worker connecting xprt %p via AF_LOCAL to %s\n", xprt, xprt->address_strings[RPC_DISPLAY_ADDR]); -- GitLab From f7d7f59ab124748156ea551edf789994f05da342 Mon Sep 17 00:00:00 2001 From: Oliver Freyermuth Date: Mon, 28 Dec 2015 18:37:38 +0100 Subject: [PATCH 2088/2855] USB: cp210x: add ID for ELV Marble Sound Board 1 Add the USB device ID for ELV Marble Sound Board 1. Signed-off-by: Oliver Freyermuth Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 7d4f51a32e66f..59b2126b21a39 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -160,6 +160,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */ { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ + { USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */ { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ { USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */ { USB_DEVICE(0x1BA4, 0x0002) }, /* Silicon Labs 358x factory default */ -- GitLab From 762674f86d0328d5dc923c966e209e1ee59663f2 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 26 Dec 2015 21:54:58 -0500 Subject: [PATCH 2089/2855] NFSv4: Don't perform cached access checks before we've OPENed the file Donald Buczek reports that a nfs4 client incorrectly denies execute access based on outdated file mode (missing 'x' bit). After the mode on the server is 'fixed' (chmod +x) further execution attempts continue to fail, because the nfs ACCESS call updates the access parameter but not the mode parameter or the mode in the inode. The root cause is ultimately that the VFS is calling may_open() before the NFS client has a chance to OPEN the file and hence revalidate the access and attribute caches. Al Viro suggests: >>> Make nfs_permission() relax the checks when it sees MAY_OPEN, if you know >>> that things will be caught by server anyway? >> >> That can work as long as we're guaranteed that everything that calls >> inode_permission() with MAY_OPEN on a regular file will also follow up >> with a vfs_open() or dentry_open() on success. Is this always the >> case? > > 1) in do_tmpfile(), followed by do_dentry_open() (not reachable by NFS since > it doesn't have ->tmpfile() instance anyway) > > 2) in atomic_open(), after the call of ->atomic_open() has succeeded. > > 3) in do_last(), followed on success by vfs_open() > > That's all. All calls of inode_permission() that get MAY_OPEN come from > may_open(), and there's no other callers of that puppy. Reported-by: Donald Buczek Link: https://bugzilla.kernel.org/show_bug.cgi?id=109771 Link: http://lkml.kernel.org/r/1451046656-26319-1-git-send-email-buczek@molgen.mpg.de Cc: Al Viro Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index ce5a218610742..44e519c21e180 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -2449,6 +2449,9 @@ int nfs_permission(struct inode *inode, int mask) case S_IFLNK: goto out; case S_IFREG: + if ((mask & MAY_OPEN) && + nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN)) + return 0; break; case S_IFDIR: /* -- GitLab From 1a093ceb053832c25b92f3cf26b957543c7baf9b Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 28 Dec 2015 11:27:15 -0500 Subject: [PATCH 2090/2855] NFSv4.1/pnfs: Fixup an lo->plh_block_lgets imbalance in layoutreturn Since commit 2d8ae84fbc32, nothing is bumping lo->plh_block_lgets in the layoutreturn path, so it should not be touched in nfs4_layoutreturn_release either. Fixes: 2d8ae84fbc32 ("NFSv4.1/pnfs: Remove redundant lo->plh_block_lgets...") Cc: stable@vger.kernel.org # 4.3+ Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 1028d6dc40c03..5dd2cde79f7e7 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -8057,7 +8057,6 @@ static void nfs4_layoutreturn_release(void *calldata) pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); pnfs_mark_matching_lsegs_invalid(lo, &freeme, &lrp->args.range); pnfs_clear_layoutreturn_waitbit(lo); - lo->plh_block_lgets--; spin_unlock(&lo->plh_inode->i_lock); pnfs_free_lseg_list(&freeme); pnfs_put_layout_hdr(lrp->args.layout); -- GitLab From b0ac1bd2bbfd5e500432714e55a791c4d394047f Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 28 Dec 2015 13:30:42 -0500 Subject: [PATCH 2091/2855] NFS: Background flush should not be low priority Background flush is needed in order to satisfy the global page limits. Don't subvert by reducing the priority. This should also address a write starvation issue that was reported by Neil Brown. Signed-off-by: Trond Myklebust --- fs/nfs/write.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 7b93164069307..7a4fe7d82e65e 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -247,8 +247,6 @@ static int wb_priority(struct writeback_control *wbc) return FLUSH_HIGHPRI | FLUSH_STABLE; if (wbc->sync_mode == WB_SYNC_ALL) ret = FLUSH_COND_STABLE; - if (wbc->for_kupdate || wbc->for_background) - ret |= FLUSH_LOWPRI; return ret; } -- GitLab From 494f74a26c14d10bb26a45218b50feb75bdedeca Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 28 Dec 2015 13:34:59 -0500 Subject: [PATCH 2092/2855] NFS: Flush reclaim writes using FLUSH_COND_STABLE If there are already writes queued up for commit, then don't flush just this page even if it is a reclaim issue. Signed-off-by: Trond Myklebust --- fs/nfs/write.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 7a4fe7d82e65e..1ea35f88eadbc 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -244,7 +244,7 @@ static int wb_priority(struct writeback_control *wbc) { int ret = 0; if (wbc->for_reclaim) - return FLUSH_HIGHPRI | FLUSH_STABLE; + return FLUSH_HIGHPRI | FLUSH_COND_STABLE; if (wbc->sync_mode == WB_SYNC_ALL) ret = FLUSH_COND_STABLE; return ret; -- GitLab From d0379a5d066a998b0210a81dc52e266ce4daaa36 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 16 Nov 2015 11:26:07 -0500 Subject: [PATCH 2093/2855] pNFS/flexfiles: Support server-supplied layoutstats sampling period Some servers want to be able to control the frequency with which clients report layoutstats, for instance, in order to monitor QoS for a particular file or set of file. In order to support this, the flexfiles layout allows the server to pass this info as a hint in the layout payload. Signed-off-by: Trond Myklebust --- fs/nfs/flexfilelayout/flexfilelayout.c | 16 +++++++++++++--- fs/nfs/flexfilelayout/flexfilelayout.h | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index 03516c80855a0..616817a464106 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -505,9 +505,17 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh, } p = xdr_inline_decode(&stream, 4); - if (p) - fls->flags = be32_to_cpup(p); + if (!p) + goto out_sort_mirrors; + fls->flags = be32_to_cpup(p); + + p = xdr_inline_decode(&stream, 4); + if (!p) + goto out_sort_mirrors; + for (i=0; i < fls->mirror_array_cnt; i++) + fls->mirror_array[i]->report_interval = be32_to_cpup(p); +out_sort_mirrors: ff_layout_sort_mirrors(fls); rc = ff_layout_check_layout(lgr); if (rc) @@ -603,7 +611,9 @@ nfs4_ff_layoutstat_start_io(struct nfs4_ff_layout_mirror *mirror, mirror->start_time = now; if (ktime_equal(mirror->last_report_time, notime)) mirror->last_report_time = now; - if (layoutstats_timer != 0) + if (mirror->report_interval != 0) + report_interval = (s64)mirror->report_interval * 1000LL; + else if (layoutstats_timer != 0) report_interval = (s64)layoutstats_timer * 1000LL; if (ktime_to_ms(ktime_sub(now, mirror->last_report_time)) >= report_interval) { diff --git a/fs/nfs/flexfilelayout/flexfilelayout.h b/fs/nfs/flexfilelayout/flexfilelayout.h index 2bb08bc6aaf0c..dd353bb7dc0a0 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.h +++ b/fs/nfs/flexfilelayout/flexfilelayout.h @@ -85,6 +85,7 @@ struct nfs4_ff_layout_mirror { struct nfs4_ff_layoutstat write_stat; ktime_t start_time; ktime_t last_report_time; + u32 report_interval; }; struct nfs4_ff_layout_segment { -- GitLab From d600ad1f2bdbf97c4818dcc85b174f72c90c21bd Mon Sep 17 00:00:00 2001 From: Peng Tao Date: Fri, 4 Dec 2015 02:57:48 +0800 Subject: [PATCH 2094/2855] NFS41: pop some layoutget errors to application For ERESTARTSYS/EIO/EROFS/ENOSPC/E2BIG in layoutget, we should just bail out instead of hiding the error and retrying inband IO. Change all the call sites to pop the error all the way up. Signed-off-by: Peng Tao Signed-off-by: Trond Myklebust --- fs/nfs/direct.c | 15 ++++++++++++++- fs/nfs/filelayout/filelayout.c | 17 +++++++++++++++-- fs/nfs/flexfilelayout/flexfilelayout.c | 25 ++++++++++++++++++++++--- fs/nfs/pagelist.c | 9 ++++++++- fs/nfs/pnfs.c | 24 ++++++++++++++++++------ fs/nfs/read.c | 2 +- 6 files changed, 78 insertions(+), 14 deletions(-) diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 4b1d08f56aba7..2e7142bcb4c83 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -670,6 +670,10 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) req = nfs_list_entry(reqs.next); nfs_direct_setup_mirroring(dreq, &desc, req); + if (desc.pg_error < 0) { + list_splice_init(&reqs, &failed); + goto out_failed; + } list_for_each_entry_safe(req, tmp, &reqs, wb_list) { if (!nfs_pageio_add_request(&desc, req)) { @@ -677,13 +681,17 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) nfs_list_add_request(req, &failed); spin_lock(cinfo.lock); dreq->flags = 0; - dreq->error = -EIO; + if (desc.pg_error < 0) + dreq->error = desc.pg_error; + else + dreq->error = -EIO; spin_unlock(cinfo.lock); } nfs_release_request(req); } nfs_pageio_complete(&desc); +out_failed: while (!list_empty(&failed)) { req = nfs_list_entry(failed.next); nfs_list_remove_request(req); @@ -900,6 +908,11 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, } nfs_direct_setup_mirroring(dreq, &desc, req); + if (desc.pg_error < 0) { + nfs_free_request(req); + result = desc.pg_error; + break; + } nfs_lock_request(req); req->wb_index = pos >> PAGE_SHIFT; diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c index 02ec07973bc43..ae07b0f566591 100644 --- a/fs/nfs/filelayout/filelayout.c +++ b/fs/nfs/filelayout/filelayout.c @@ -883,13 +883,19 @@ static void filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) { - if (!pgio->pg_lseg) + if (!pgio->pg_lseg) { pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, req->wb_context, 0, NFS4_MAX_UINT64, IOMODE_READ, GFP_KERNEL); + if (IS_ERR(pgio->pg_lseg)) { + pgio->pg_error = PTR_ERR(pgio->pg_lseg); + pgio->pg_lseg = NULL; + return; + } + } /* If no lseg, fall back to read through mds */ if (pgio->pg_lseg == NULL) nfs_pageio_reset_read_mds(pgio); @@ -902,13 +908,20 @@ filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_commit_info cinfo; int status; - if (!pgio->pg_lseg) + if (!pgio->pg_lseg) { pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, req->wb_context, 0, NFS4_MAX_UINT64, IOMODE_RW, GFP_NOFS); + if (IS_ERR(pgio->pg_lseg)) { + pgio->pg_error = PTR_ERR(pgio->pg_lseg); + pgio->pg_lseg = NULL; + return; + } + } + /* If no lseg, fall back to write through mds */ if (pgio->pg_lseg == NULL) goto out_mds; diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index 616817a464106..57e4010e3cdeb 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -795,13 +795,19 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio, int ds_idx; /* Use full layout for now */ - if (!pgio->pg_lseg) + if (!pgio->pg_lseg) { pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, req->wb_context, 0, NFS4_MAX_UINT64, IOMODE_READ, GFP_KERNEL); + if (IS_ERR(pgio->pg_lseg)) { + pgio->pg_error = PTR_ERR(pgio->pg_lseg); + pgio->pg_lseg = NULL; + return; + } + } /* If no lseg, fall back to read through mds */ if (pgio->pg_lseg == NULL) goto out_mds; @@ -835,13 +841,19 @@ ff_layout_pg_init_write(struct nfs_pageio_descriptor *pgio, int i; int status; - if (!pgio->pg_lseg) + if (!pgio->pg_lseg) { pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, req->wb_context, 0, NFS4_MAX_UINT64, IOMODE_RW, GFP_NOFS); + if (IS_ERR(pgio->pg_lseg)) { + pgio->pg_error = PTR_ERR(pgio->pg_lseg); + pgio->pg_lseg = NULL; + return; + } + } /* If no lseg, fall back to write through mds */ if (pgio->pg_lseg == NULL) goto out_mds; @@ -877,18 +889,25 @@ static unsigned int ff_layout_pg_get_mirror_count_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) { - if (!pgio->pg_lseg) + if (!pgio->pg_lseg) { pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, req->wb_context, 0, NFS4_MAX_UINT64, IOMODE_RW, GFP_NOFS); + if (IS_ERR(pgio->pg_lseg)) { + pgio->pg_error = PTR_ERR(pgio->pg_lseg); + pgio->pg_lseg = NULL; + goto out; + } + } if (pgio->pg_lseg) return FF_LAYOUT_MIRROR_COUNT(pgio->pg_lseg); /* no lseg means that pnfs is not in use, so no mirroring here */ nfs_pageio_reset_write_mds(pgio); +out: return 1; } diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 452a011ba0d8a..728f65884cea5 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -874,6 +874,9 @@ static int nfs_pageio_setup_mirroring(struct nfs_pageio_descriptor *pgio, mirror_count = pgio->pg_ops->pg_get_mirror_count(pgio, req); + if (pgio->pg_error < 0) + return pgio->pg_error; + if (!mirror_count || mirror_count > NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX) return -EINVAL; @@ -982,6 +985,8 @@ static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc, } else { if (desc->pg_ops->pg_init) desc->pg_ops->pg_init(desc, req); + if (desc->pg_error < 0) + return 0; mirror->pg_base = req->wb_pgbase; } if (!nfs_can_coalesce_requests(prev, req, desc)) @@ -1147,6 +1152,8 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, bytes = req->wb_bytes; nfs_pageio_setup_mirroring(desc, req); + if (desc->pg_error < 0) + return 0; for (midx = 0; midx < desc->pg_mirror_count; midx++) { if (midx) { @@ -1232,7 +1239,7 @@ int nfs_pageio_resend(struct nfs_pageio_descriptor *desc, nfs_pageio_complete(desc); if (!list_empty(&failed)) { list_move(&failed, &hdr->pages); - return -EIO; + return desc->pg_error < 0 ? desc->pg_error : -EIO; } return 0; } diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 6095a8d42766c..b1acc4135c3cb 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -906,14 +906,15 @@ send_layoutget(struct pnfs_layout_hdr *lo, if (IS_ERR(lseg)) { switch (PTR_ERR(lseg)) { - case -ENOMEM: case -ERESTARTSYS: + case -EIO: + case -ENOSPC: + case -EROFS: + case -E2BIG: break; default: - /* remember that LAYOUTGET failed and suspend trying */ - pnfs_layout_io_set_failed(lo, range->iomode); + return NULL; } - return NULL; } else pnfs_layout_clear_fail_bit(lo, pnfs_iomode_to_fail_bit(range->iomode)); @@ -1649,7 +1650,7 @@ out: "(%s, offset: %llu, length: %llu)\n", __func__, ino->i_sb->s_id, (unsigned long long)NFS_FILEID(ino), - lseg == NULL ? "not found" : "found", + IS_ERR_OR_NULL(lseg) ? "not found" : "found", iomode==IOMODE_RW ? "read/write" : "read-only", (unsigned long long)pos, (unsigned long long)count); @@ -1828,6 +1829,11 @@ pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *r rd_size, IOMODE_READ, GFP_KERNEL); + if (IS_ERR(pgio->pg_lseg)) { + pgio->pg_error = PTR_ERR(pgio->pg_lseg); + pgio->pg_lseg = NULL; + return; + } } /* If no lseg, fall back to read through mds */ if (pgio->pg_lseg == NULL) @@ -1840,13 +1846,19 @@ void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req, u64 wb_size) { - if (pgio->pg_lseg == NULL) + if (pgio->pg_lseg == NULL) { pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, req->wb_context, req_offset(req), wb_size, IOMODE_RW, GFP_NOFS); + if (IS_ERR(pgio->pg_lseg)) { + pgio->pg_error = PTR_ERR(pgio->pg_lseg); + pgio->pg_lseg = NULL; + return; + } + } /* If no lseg, fall back to write through mds */ if (pgio->pg_lseg == NULL) nfs_pageio_reset_write_mds(pgio); diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 0a5e33f33b5c8..0bb580174cb3d 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -115,7 +115,7 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode, pgm = &pgio.pg_mirrors[0]; NFS_I(inode)->read_io += pgm->pg_bytes_written; - return 0; + return pgio.pg_error < 0 ? pgio.pg_error : 0; } static void nfs_readpage_release(struct nfs_page *req) -- GitLab From c18b96a1b8629db8cf5ac9f8974ccb4abcc209ab Mon Sep 17 00:00:00 2001 From: Peng Tao Date: Sat, 5 Dec 2015 01:59:56 +0800 Subject: [PATCH 2095/2855] nfs: clean up rest of reqs when failing to add one If we fail to set up things before sending anything over wire, we need to clean up the reqs that are still attached to the IO descriptor. Signed-off-by: Peng Tao Signed-off-by: Trond Myklebust --- fs/nfs/pagelist.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 728f65884cea5..13faa303eb3b5 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -1126,6 +1126,7 @@ static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc) static int nfs_pageio_add_request_mirror(struct nfs_pageio_descriptor *desc, struct nfs_page *req) { + struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc); int ret; do { @@ -1153,7 +1154,7 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, nfs_pageio_setup_mirroring(desc, req); if (desc->pg_error < 0) - return 0; + goto out_failed; for (midx = 0; midx < desc->pg_mirror_count; midx++) { if (midx) { @@ -1170,7 +1171,8 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, if (IS_ERR(dupreq)) { nfs_page_group_unlock(req); - return 0; + desc->pg_error = PTR_ERR(dupreq); + goto out_failed; } nfs_lock_request(dupreq); @@ -1183,10 +1185,19 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, if (nfs_pgio_has_mirroring(desc)) desc->pg_mirror_idx = midx; if (!nfs_pageio_add_request_mirror(desc, dupreq)) - return 0; + goto out_failed; } return 1; + +out_failed: + /* + * We might have failed before sending any reqs over wire. + * clean up rest of the reqs in mirror pg_list + */ + if (desc->pg_error) + desc->pg_completion_ops->error_cleanup(&mirror->pg_list); + return 0; } /* -- GitLab From 2bff2288579f1e4af2f05a7f7443c85b7766d5ac Mon Sep 17 00:00:00 2001 From: Peng Tao Date: Sat, 5 Dec 2015 02:03:17 +0800 Subject: [PATCH 2096/2855] nfs: centralize pgio error cleanup In case we fail during setting things up for read/write IO, set pg_error in IO descriptor and do the cleanup in nfs_pageio_add_request, where we clean up all pages that are still hanging around on the IO descriptor. Signed-off-by: Peng Tao Signed-off-by: Trond Myklebust --- fs/nfs/pagelist.c | 53 ++++++++++++++++++++++++++--------------------- fs/nfs/pnfs.c | 12 ++++------- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 13faa303eb3b5..7c71b71016b52 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -664,22 +664,11 @@ EXPORT_SYMBOL_GPL(nfs_initiate_pgio); * @desc: IO descriptor * @hdr: pageio header */ -static int nfs_pgio_error(struct nfs_pageio_descriptor *desc, - struct nfs_pgio_header *hdr) +static void nfs_pgio_error(struct nfs_pgio_header *hdr) { - struct nfs_pgio_mirror *mirror; - u32 midx; - set_bit(NFS_IOHDR_REDO, &hdr->flags); nfs_pgio_data_destroy(hdr); hdr->completion_ops->completion(hdr); - /* TODO: Make sure it's right to clean up all mirrors here - * and not just hdr->pgio_mirror_idx */ - for (midx = 0; midx < desc->pg_mirror_count; midx++) { - mirror = &desc->pg_mirrors[midx]; - desc->pg_completion_ops->error_cleanup(&mirror->pg_list); - } - return -ENOMEM; } /** @@ -800,8 +789,11 @@ int nfs_generic_pgio(struct nfs_pageio_descriptor *desc, unsigned int pagecount, pageused; pagecount = nfs_page_array_len(mirror->pg_base, mirror->pg_count); - if (!nfs_pgarray_set(&hdr->page_array, pagecount)) - return nfs_pgio_error(desc, hdr); + if (!nfs_pgarray_set(&hdr->page_array, pagecount)) { + nfs_pgio_error(hdr); + desc->pg_error = -ENOMEM; + return desc->pg_error; + } nfs_init_cinfo(&cinfo, desc->pg_inode, desc->pg_dreq); pages = hdr->page_array.pagevec; @@ -819,8 +811,11 @@ int nfs_generic_pgio(struct nfs_pageio_descriptor *desc, *pages++ = last_page = req->wb_page; } } - if (WARN_ON_ONCE(pageused != pagecount)) - return nfs_pgio_error(desc, hdr); + if (WARN_ON_ONCE(pageused != pagecount)) { + nfs_pgio_error(hdr); + desc->pg_error = -EINVAL; + return desc->pg_error; + } if ((desc->pg_ioflags & FLUSH_COND_STABLE) && (desc->pg_moreio || nfs_reqs_to_commit(&cinfo))) @@ -843,10 +838,8 @@ static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc) hdr = nfs_pgio_header_alloc(desc->pg_rw_ops); if (!hdr) { - /* TODO: make sure this is right with mirroring - or - * should it back out all mirrors? */ - desc->pg_completion_ops->error_cleanup(&mirror->pg_list); - return -ENOMEM; + desc->pg_error = -ENOMEM; + return desc->pg_error; } nfs_pgheader_init(desc, hdr, nfs_pgio_header_free); ret = nfs_generic_pgio(desc, hdr); @@ -1126,7 +1119,6 @@ static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc) static int nfs_pageio_add_request_mirror(struct nfs_pageio_descriptor *desc, struct nfs_page *req) { - struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc); int ret; do { @@ -1193,10 +1185,23 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, out_failed: /* * We might have failed before sending any reqs over wire. - * clean up rest of the reqs in mirror pg_list + * Clean up rest of the reqs in mirror pg_list. */ - if (desc->pg_error) - desc->pg_completion_ops->error_cleanup(&mirror->pg_list); + if (desc->pg_error) { + struct nfs_pgio_mirror *mirror; + void (*func)(struct list_head *); + + /* remember fatal errors */ + if (nfs_error_is_fatal(desc->pg_error)) + mapping_set_error(desc->pg_inode->i_mapping, + desc->pg_error); + + func = desc->pg_completion_ops->error_cleanup; + for (midx = 0; midx < desc->pg_mirror_count; midx++) { + mirror = &desc->pg_mirrors[midx]; + func(&mirror->pg_list); + } + } return 0; } diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index b1acc4135c3cb..0fb3552ccfbef 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -2026,15 +2026,13 @@ static void pnfs_writehdr_free(struct nfs_pgio_header *hdr) int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc) { - struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc); - struct nfs_pgio_header *hdr; int ret; hdr = nfs_pgio_header_alloc(desc->pg_rw_ops); if (!hdr) { - desc->pg_completion_ops->error_cleanup(&mirror->pg_list); - return -ENOMEM; + desc->pg_error = -ENOMEM; + return desc->pg_error; } nfs_pgheader_init(desc, hdr, pnfs_writehdr_free); @@ -2157,15 +2155,13 @@ static void pnfs_readhdr_free(struct nfs_pgio_header *hdr) int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc) { - struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc); - struct nfs_pgio_header *hdr; int ret; hdr = nfs_pgio_header_alloc(desc->pg_rw_ops); if (!hdr) { - desc->pg_completion_ops->error_cleanup(&mirror->pg_list); - return -ENOMEM; + desc->pg_error = -ENOMEM; + return desc->pg_error; } nfs_pgheader_init(desc, hdr, pnfs_readhdr_free); hdr->lseg = pnfs_get_lseg(desc->pg_lseg); -- GitLab From 0bcbf039f6b2bcefe4f5dada76079080edf9ecd0 Mon Sep 17 00:00:00 2001 From: Peng Tao Date: Sat, 5 Dec 2015 15:57:31 +0800 Subject: [PATCH 2097/2855] nfs: handle request add failure properly When we fail to queue a read page to IO descriptor, we need to clean it up otherwise it is hanging around preventing nfs module from being removed. When we fail to queue a write page to IO descriptor, we need to clean it up and also save the failure status to open context. Then at file close, we can try to write pages back again and drop the page if it fails to writeback in .launder_page, which will be done in the next patch. Signed-off-by: Peng Tao Signed-off-by: Trond Myklebust --- fs/nfs/inode.c | 6 ++++++ fs/nfs/internal.h | 14 ++++++++++++++ fs/nfs/pnfs.c | 15 +++------------ fs/nfs/read.c | 41 +++++++++++++++++++++++------------------ fs/nfs/write.c | 22 +++++++++++++++++++++- 5 files changed, 67 insertions(+), 31 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index c7e8b87da5b24..74fb1223c2f5b 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -912,6 +912,12 @@ void nfs_file_clear_open_context(struct file *filp) if (ctx) { struct inode *inode = d_inode(ctx->dentry); + /* + * We fatal error on write before. Try to writeback + * every page again. + */ + if (ctx->error < 0) + invalidate_inode_pages2(inode->i_mapping); filp->private_data = NULL; spin_lock(&inode->i_lock); list_move_tail(&ctx->list, &NFS_I(inode)->open_files); diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 313d55402238f..68f773dc226ec 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -711,3 +711,17 @@ static inline u32 nfs_stateid_hash(nfs4_stateid *stateid) return 0; } #endif + +static inline bool nfs_error_is_fatal(int err) +{ + switch (err) { + case -ERESTARTSYS: + case -EIO: + case -ENOSPC: + case -EROFS: + case -E2BIG: + return true; + default: + return false; + } +} diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 0fb3552ccfbef..580207bc52a5d 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -904,18 +904,9 @@ send_layoutget(struct pnfs_layout_hdr *lo, lseg = nfs4_proc_layoutget(lgp, gfp_flags); } while (lseg == ERR_PTR(-EAGAIN)); - if (IS_ERR(lseg)) { - switch (PTR_ERR(lseg)) { - case -ERESTARTSYS: - case -EIO: - case -ENOSPC: - case -EROFS: - case -E2BIG: - break; - default: - return NULL; - } - } else + if (IS_ERR(lseg) && !nfs_error_is_fatal(PTR_ERR(lseg))) + lseg = NULL; + else pnfs_layout_clear_fail_bit(lo, pnfs_iomode_to_fail_bit(range->iomode)); diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 0bb580174cb3d..eb31e23e7defa 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -85,6 +85,23 @@ void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio) } EXPORT_SYMBOL_GPL(nfs_pageio_reset_read_mds); +static void nfs_readpage_release(struct nfs_page *req) +{ + struct inode *inode = d_inode(req->wb_context->dentry); + + dprintk("NFS: read done (%s/%llu %d@%lld)\n", inode->i_sb->s_id, + (unsigned long long)NFS_FILEID(inode), req->wb_bytes, + (long long)req_offset(req)); + + if (nfs_page_group_sync_on_bit(req, PG_UNLOCKPAGE)) { + if (PageUptodate(req->wb_page)) + nfs_readpage_to_fscache(inode, req->wb_page, 0); + + unlock_page(req->wb_page); + } + nfs_release_request(req); +} + int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode, struct page *page) { @@ -106,7 +123,10 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode, nfs_pageio_init_read(&pgio, inode, false, &nfs_async_read_completion_ops); - nfs_pageio_add_request(&pgio, new); + if (!nfs_pageio_add_request(&pgio, new)) { + nfs_list_remove_request(new); + nfs_readpage_release(new); + } nfs_pageio_complete(&pgio); /* It doesn't make sense to do mirrored reads! */ @@ -118,23 +138,6 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode, return pgio.pg_error < 0 ? pgio.pg_error : 0; } -static void nfs_readpage_release(struct nfs_page *req) -{ - struct inode *inode = d_inode(req->wb_context->dentry); - - dprintk("NFS: read done (%s/%llu %d@%lld)\n", inode->i_sb->s_id, - (unsigned long long)NFS_FILEID(inode), req->wb_bytes, - (long long)req_offset(req)); - - if (nfs_page_group_sync_on_bit(req, PG_UNLOCKPAGE)) { - if (PageUptodate(req->wb_page)) - nfs_readpage_to_fscache(inode, req->wb_page, 0); - - unlock_page(req->wb_page); - } - nfs_release_request(req); -} - static void nfs_page_group_set_uptodate(struct nfs_page *req) { if (nfs_page_group_sync_on_bit(req, PG_UPTODATE)) @@ -361,6 +364,8 @@ readpage_async_filler(void *data, struct page *page) if (len < PAGE_CACHE_SIZE) zero_user_segment(page, len, PAGE_CACHE_SIZE); if (!nfs_pageio_add_request(desc->pgio, new)) { + nfs_list_remove_request(new); + nfs_readpage_release(new); error = desc->pgio->pg_error; goto out_unlock; } diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 7b93164069307..9dafb08ddae53 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -545,6 +545,15 @@ try_again: return head; } +static void nfs_write_error_remove_page(struct nfs_page *req) +{ + nfs_unlock_request(req); + nfs_end_page_writeback(req); + nfs_release_request(req); + generic_error_remove_page(page_file_mapping(req->wb_page), + req->wb_page); +} + /* * Find an associated nfs write request, and prepare to flush it out * May return an error if the user signalled nfs_wait_on_request(). @@ -567,8 +576,19 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, ret = 0; if (!nfs_pageio_add_request(pgio, req)) { - nfs_redirty_request(req); ret = pgio->pg_error; + /* + * Remove the problematic req upon fatal errors, + * while other dirty pages can still be around + * until they get flushed. + */ + if (nfs_error_is_fatal(ret)) { + nfs_context_set_write_error(req->wb_context, ret); + nfs_write_error_remove_page(req); + } else { + nfs_redirty_request(req); + ret = -EAGAIN; + } } else nfs_add_stats(page_file_mapping(page)->host, NFSIOS_WRITEPAGES, 1); -- GitLab From d6c843b96e1cb5199147e3281a724e3c0b69a9ab Mon Sep 17 00:00:00 2001 From: Peng Tao Date: Sat, 5 Dec 2015 16:20:43 +0800 Subject: [PATCH 2098/2855] nfs: only remove page from mapping if launder_page fails Instead of dropping pages when write fails, only do it when we get fatal failure in launder_page write back. Signed-off-by: Peng Tao Signed-off-by: Trond Myklebust --- fs/nfs/file.c | 2 +- fs/nfs/write.c | 39 +++++++++++++++++++++++---------------- include/linux/nfs_fs.h | 14 +++++++++++++- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 93e236429c5d7..f188dd071dfcf 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -545,7 +545,7 @@ static int nfs_launder_page(struct page *page) inode->i_ino, (long long)page_offset(page)); nfs_fscache_wait_on_page_write(nfsi, page); - return nfs_wb_page(inode, page); + return nfs_wb_launder_page(inode, page); } static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file, diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 9dafb08ddae53..4d254232d7283 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -559,7 +559,8 @@ static void nfs_write_error_remove_page(struct nfs_page *req) * May return an error if the user signalled nfs_wait_on_request(). */ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, - struct page *page, bool nonblock) + struct page *page, bool nonblock, + bool launder) { struct nfs_page *req; int ret = 0; @@ -578,17 +579,19 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, if (!nfs_pageio_add_request(pgio, req)) { ret = pgio->pg_error; /* - * Remove the problematic req upon fatal errors, - * while other dirty pages can still be around - * until they get flushed. + * Remove the problematic req upon fatal errors + * in launder case, while other dirty pages can + * still be around until they get flushed. */ if (nfs_error_is_fatal(ret)) { nfs_context_set_write_error(req->wb_context, ret); - nfs_write_error_remove_page(req); - } else { - nfs_redirty_request(req); - ret = -EAGAIN; + if (launder) { + nfs_write_error_remove_page(req); + goto out; + } } + nfs_redirty_request(req); + ret = -EAGAIN; } else nfs_add_stats(page_file_mapping(page)->host, NFSIOS_WRITEPAGES, 1); @@ -596,12 +599,14 @@ out: return ret; } -static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, struct nfs_pageio_descriptor *pgio) +static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, + struct nfs_pageio_descriptor *pgio, bool launder) { int ret; nfs_pageio_cond_complete(pgio, page_file_index(page)); - ret = nfs_page_async_flush(pgio, page, wbc->sync_mode == WB_SYNC_NONE); + ret = nfs_page_async_flush(pgio, page, wbc->sync_mode == WB_SYNC_NONE, + launder); if (ret == -EAGAIN) { redirty_page_for_writepage(wbc, page); ret = 0; @@ -612,7 +617,9 @@ static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, st /* * Write an mmapped page to the server. */ -static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc) +static int nfs_writepage_locked(struct page *page, + struct writeback_control *wbc, + bool launder) { struct nfs_pageio_descriptor pgio; struct inode *inode = page_file_mapping(page)->host; @@ -621,7 +628,7 @@ static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE); nfs_pageio_init_write(&pgio, inode, wb_priority(wbc), false, &nfs_async_write_completion_ops); - err = nfs_do_writepage(page, wbc, &pgio); + err = nfs_do_writepage(page, wbc, &pgio, launder); nfs_pageio_complete(&pgio); if (err < 0) return err; @@ -634,7 +641,7 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc) { int ret; - ret = nfs_writepage_locked(page, wbc); + ret = nfs_writepage_locked(page, wbc, false); unlock_page(page); return ret; } @@ -643,7 +650,7 @@ static int nfs_writepages_callback(struct page *page, struct writeback_control * { int ret; - ret = nfs_do_writepage(page, wbc, data); + ret = nfs_do_writepage(page, wbc, data, false); unlock_page(page); return ret; } @@ -1931,7 +1938,7 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page) /* * Write back all requests on one page - we do this before reading it. */ -int nfs_wb_page(struct inode *inode, struct page *page) +int nfs_wb_single_page(struct inode *inode, struct page *page, bool launder) { loff_t range_start = page_file_offset(page); loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1); @@ -1948,7 +1955,7 @@ int nfs_wb_page(struct inode *inode, struct page *page) for (;;) { wait_on_page_writeback(page); if (clear_page_dirty_for_io(page)) { - ret = nfs_writepage_locked(page, &wbc); + ret = nfs_writepage_locked(page, &wbc, launder); if (ret < 0) goto out_error; continue; diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index c0e961474a527..b88fc46cfbb81 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -517,12 +517,24 @@ extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned */ extern int nfs_sync_inode(struct inode *inode); extern int nfs_wb_all(struct inode *inode); -extern int nfs_wb_page(struct inode *inode, struct page* page); +extern int nfs_wb_single_page(struct inode *inode, struct page *page, bool launder); extern int nfs_wb_page_cancel(struct inode *inode, struct page* page); extern int nfs_commit_inode(struct inode *, int); extern struct nfs_commit_data *nfs_commitdata_alloc(void); extern void nfs_commit_free(struct nfs_commit_data *data); +static inline int +nfs_wb_launder_page(struct inode *inode, struct page *page) +{ + return nfs_wb_single_page(inode, page, true); +} + +static inline int +nfs_wb_page(struct inode *inode, struct page *page) +{ + return nfs_wb_single_page(inode, page, false); +} + static inline int nfs_have_writebacks(struct inode *inode) { -- GitLab From 7c1e6e58e2aa8b95d1b9888db1945eb0a388efb9 Mon Sep 17 00:00:00 2001 From: Peng Tao Date: Sat, 5 Dec 2015 17:01:01 +0800 Subject: [PATCH 2099/2855] NFS41: map NFS4ERR_LAYOUTUNAVAILABLE to ENODATA Instead of mapping it to EIO that is a fatal error and fails application. We'll go inband after getting NFS4ERR_LAYOUTUNAVAILABLE. Signed-off-by: Peng Tao Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 18d862db15b63..0065bbdc53c32 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -7795,6 +7795,15 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata) switch (task->tk_status) { case 0: goto out; + + /* + * NFS4ERR_LAYOUTUNAVAILABLE means we are not supposed to use pnfs + * on the file. set tk_status to -ENODATA to tell upper layer to + * retry go inband. + */ + case -NFS4ERR_LAYOUTUNAVAILABLE: + task->tk_status = -ENODATA; + goto out; /* * NFS4ERR_BADLAYOUT means the MDS cannot return a layout of * length lgp->args.minlength != 0 (see RFC5661 section 18.43.3). -- GitLab From c22eeb8697352bd696300aabaf08eaff99bdb635 Mon Sep 17 00:00:00 2001 From: Peng Tao Date: Mon, 7 Dec 2015 17:31:38 -0500 Subject: [PATCH 2100/2855] pnfs/flexfiles: do not mark delay-like status as DS failure We just need to delay and retry in these cases. Signed-off-by: Peng Tao Signed-off-by: Trond Myklebust --- fs/nfs/flexfilelayout/flexfilelayout.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index 57e4010e3cdeb..b392156e67432 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -1188,6 +1188,14 @@ static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg, } } + switch (status) { + case NFS4ERR_DELAY: + case NFS4ERR_GRACE: + return; + default: + break; + } + mirror = FF_LAYOUT_COMP(lseg, idx); err = ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout), mirror, offset, length, status, opnum, @@ -1399,7 +1407,6 @@ static int ff_layout_write_done_cb(struct rpc_task *task, ff_layout_reset_write(hdr, false); return task->tk_status; case -EAGAIN: - rpc_restart_call_prepare(task); return -EAGAIN; } -- GitLab From 141b9b59ed8ae2602b2c285149ec8d4f6b05c4d9 Mon Sep 17 00:00:00 2001 From: Peng Tao Date: Mon, 7 Dec 2015 18:33:14 -0500 Subject: [PATCH 2101/2855] pnfs/flexfiles: count io stat in rpc_count_stats callback If client ever restarts IO due to some errors, we'll endup mis-counting IO stats if we do the counting in .rpc_done callback. Move it to .rpc_count_stats callback that is only called when releasing RPC. Signed-off-by: Peng Tao Signed-off-by: Trond Myklebust --- fs/nfs/flexfilelayout/flexfilelayout.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index b392156e67432..5ede5c26c757b 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -1516,11 +1516,6 @@ static void ff_layout_write_call_done(struct rpc_task *task, void *data) { struct nfs_pgio_header *hdr = data; - nfs4_ff_layout_stat_io_end_write(task, - FF_LAYOUT_COMP(hdr->lseg, hdr->pgio_mirror_idx), - hdr->args.count, hdr->res.count, - hdr->res.verf->committed); - if (test_bit(NFS_IOHDR_REDO, &hdr->flags) && task->tk_status == 0) { nfs4_sequence_done(task, &hdr->res.seq_res); @@ -1535,6 +1530,11 @@ static void ff_layout_write_count_stats(struct rpc_task *task, void *data) { struct nfs_pgio_header *hdr = data; + nfs4_ff_layout_stat_io_end_write(task, + FF_LAYOUT_COMP(hdr->lseg, hdr->pgio_mirror_idx), + hdr->args.count, hdr->res.count, + hdr->res.verf->committed); + rpc_count_iostats_metrics(task, &NFS_CLIENT(hdr->inode)->cl_metrics[NFSPROC4_CLNT_WRITE]); } @@ -1566,6 +1566,11 @@ static void ff_layout_commit_prepare_v4(struct rpc_task *task, void *data) } static void ff_layout_commit_done(struct rpc_task *task, void *data) +{ + pnfs_generic_write_commit_done(task, data); +} + +static void ff_layout_commit_count_stats(struct rpc_task *task, void *data) { struct nfs_commit_data *cdata = data; struct nfs_page *req; @@ -1580,13 +1585,6 @@ static void ff_layout_commit_done(struct rpc_task *task, void *data) FF_LAYOUT_COMP(cdata->lseg, cdata->ds_commit_index), count, count, NFS_FILE_SYNC); - pnfs_generic_write_commit_done(task, data); -} - -static void ff_layout_commit_count_stats(struct rpc_task *task, void *data) -{ - struct nfs_commit_data *cdata = data; - rpc_count_iostats_metrics(task, &NFS_CLIENT(cdata->inode)->cl_metrics[NFSPROC4_CLNT_COMMIT]); } -- GitLab From 2e5b29f0448be9ea8da3ee0412a2043fee59e131 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 14 Dec 2015 16:25:11 -0500 Subject: [PATCH 2102/2855] pNFS/flexfiles: Don't prevent flexfiles client from retrying LAYOUTGET Fix a bug in which flexfiles clients are falling back to I/O through the MDS even when the FF_FLAGS_NO_IO_THRU_MDS flag is set. The flexfiles client will always report errors through the LAYOUTRETURN and/or LAYOUTERROR mechanisms, so it should normally be safe for it to retry the LAYOUTGET until it fails or succeeds. Signed-off-by: Trond Myklebust --- fs/nfs/flexfilelayout/flexfilelayout.c | 4 ---- fs/nfs/flexfilelayout/flexfilelayoutdev.c | 16 ++++------------ fs/nfs/pnfs.c | 18 ++---------------- fs/nfs/pnfs.h | 21 --------------------- 4 files changed, 6 insertions(+), 53 deletions(-) diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index 5ede5c26c757b..1da19d7094589 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -1399,11 +1399,9 @@ static int ff_layout_write_done_cb(struct rpc_task *task, switch (err) { case -NFS4ERR_RESET_TO_PNFS: - pnfs_set_retry_layoutget(hdr->lseg->pls_layout); ff_layout_reset_write(hdr, true); return task->tk_status; case -NFS4ERR_RESET_TO_MDS: - pnfs_clear_retry_layoutget(hdr->lseg->pls_layout); ff_layout_reset_write(hdr, false); return task->tk_status; case -EAGAIN: @@ -1438,11 +1436,9 @@ static int ff_layout_commit_done_cb(struct rpc_task *task, switch (err) { case -NFS4ERR_RESET_TO_PNFS: - pnfs_set_retry_layoutget(data->lseg->pls_layout); pnfs_generic_prepare_to_resend_writes(data); return -EAGAIN; case -NFS4ERR_RESET_TO_MDS: - pnfs_clear_retry_layoutget(data->lseg->pls_layout); pnfs_generic_prepare_to_resend_writes(data); return -EAGAIN; case -EAGAIN: diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c index e125e55de86da..bd0327541366c 100644 --- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c +++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c @@ -429,22 +429,14 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx, mirror, lseg->pls_range.offset, lseg->pls_range.length, NFS4ERR_NXIO, OP_ILLEGAL, GFP_NOIO); - if (fail_return) { - pnfs_error_mark_layout_for_return(ino, lseg); - if (ff_layout_has_available_ds(lseg)) - pnfs_set_retry_layoutget(lseg->pls_layout); - else - pnfs_clear_retry_layoutget(lseg->pls_layout); - - } else { + if (!fail_return) { if (ff_layout_has_available_ds(lseg)) set_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE, &lseg->pls_layout->plh_flags); - else { + else pnfs_error_mark_layout_for_return(ino, lseg); - pnfs_clear_retry_layoutget(lseg->pls_layout); - } - } + } else + pnfs_error_mark_layout_for_return(ino, lseg); } out_update_creds: if (ff_layout_update_mirror_cred(mirror, ds)) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 580207bc52a5d..6b42362cdbb04 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -618,7 +618,6 @@ pnfs_destroy_layout(struct nfs_inode *nfsi) pnfs_get_layout_hdr(lo); pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RO_FAILED); pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RW_FAILED); - pnfs_clear_retry_layoutget(lo); spin_unlock(&nfsi->vfs_inode.i_lock); pnfs_free_lseg_list(&tmp_list); pnfs_put_layout_hdr(lo); @@ -1094,7 +1093,6 @@ bool pnfs_roc(struct inode *ino) &lo->plh_flags)) layoutreturn = pnfs_prepare_layoutreturn(lo); - pnfs_clear_retry_layoutget(lo); list_for_each_entry_safe(lseg, tmp, &lo->plh_segs, pls_list) /* If we are sending layoutreturn, invalidate all valid lsegs */ if (layoutreturn || test_bit(NFS_LSEG_ROC, &lseg->pls_flags)) { @@ -1457,25 +1455,15 @@ static bool pnfs_within_mdsthreshold(struct nfs_open_context *ctx, return ret; } -/* stop waiting if someone clears NFS_LAYOUT_RETRY_LAYOUTGET bit. */ -static int pnfs_layoutget_retry_bit_wait(struct wait_bit_key *key, int mode) -{ - if (!test_bit(NFS_LAYOUT_RETRY_LAYOUTGET, key->flags)) - return 1; - return nfs_wait_bit_killable(key, mode); -} - static bool pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo) { - if (!pnfs_should_retry_layoutget(lo)) - return false; /* * send layoutcommit as it can hold up layoutreturn due to lseg * reference */ pnfs_layoutcommit_inode(lo->plh_inode, false); return !wait_on_bit_action(&lo->plh_flags, NFS_LAYOUT_RETURN, - pnfs_layoutget_retry_bit_wait, + nfs_wait_bit_killable, TASK_UNINTERRUPTIBLE); } @@ -1550,8 +1538,7 @@ lookup_again: } /* if LAYOUTGET already failed once we don't try again */ - if (pnfs_layout_io_test_failed(lo, iomode) && - !pnfs_should_retry_layoutget(lo)) { + if (pnfs_layout_io_test_failed(lo, iomode)) { trace_pnfs_update_layout(ino, pos, count, iomode, lo, PNFS_UPDATE_LAYOUT_IO_TEST_FAIL); goto out_unlock; @@ -1628,7 +1615,6 @@ lookup_again: arg.length = PAGE_CACHE_ALIGN(arg.length); lseg = send_layoutget(lo, ctx, &arg, gfp_flags); - pnfs_clear_retry_layoutget(lo); atomic_dec(&lo->plh_outstanding); trace_pnfs_update_layout(ino, pos, count, iomode, lo, PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET); diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index d1990e90e7a02..6916ff4e86f9b 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -98,7 +98,6 @@ enum { NFS_LAYOUT_RETURN_BEFORE_CLOSE, /* Return this layout before close */ NFS_LAYOUT_INVALID_STID, /* layout stateid id is invalid */ NFS_LAYOUT_FIRST_LAYOUTGET, /* Serialize first layoutget */ - NFS_LAYOUT_RETRY_LAYOUTGET, /* Retry layoutget */ }; enum layoutdriver_policy_flags { @@ -379,26 +378,6 @@ nfs4_get_deviceid(struct nfs4_deviceid_node *d) return d; } -static inline void pnfs_set_retry_layoutget(struct pnfs_layout_hdr *lo) -{ - if (!test_and_set_bit(NFS_LAYOUT_RETRY_LAYOUTGET, &lo->plh_flags)) - atomic_inc(&lo->plh_refcount); -} - -static inline void pnfs_clear_retry_layoutget(struct pnfs_layout_hdr *lo) -{ - if (test_and_clear_bit(NFS_LAYOUT_RETRY_LAYOUTGET, &lo->plh_flags)) { - atomic_dec(&lo->plh_refcount); - /* wake up waiters for LAYOUTRETURN as that is not needed */ - wake_up_bit(&lo->plh_flags, NFS_LAYOUT_RETURN); - } -} - -static inline bool pnfs_should_retry_layoutget(struct pnfs_layout_hdr *lo) -{ - return test_bit(NFS_LAYOUT_RETRY_LAYOUTGET, &lo->plh_flags); -} - static inline struct pnfs_layout_segment * pnfs_get_lseg(struct pnfs_layout_segment *lseg) { -- GitLab From b9fc773ef512dd3db71560463d0e5543c35fe976 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 15 Dec 2015 11:15:05 -0500 Subject: [PATCH 2103/2855] pNFS/flexfiles: Don't mark the entire layout as failed, when returning it In pNFS/flexfiles, we want to return the layout without necessarily marking it as having completely failed. We therefore move the call to pnfs_layout_io_set_failed() out of pnfs_error_mark_layout_for_return(), and then ensura that pNFS/files layout calls it separately. Signed-off-by: Trond Myklebust --- fs/nfs/filelayout/filelayout.c | 1 + fs/nfs/pnfs.c | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c index ae07b0f566591..bb1f4e7a3270e 100644 --- a/fs/nfs/filelayout/filelayout.c +++ b/fs/nfs/filelayout/filelayout.c @@ -202,6 +202,7 @@ static int filelayout_async_handle_error(struct rpc_task *task, task->tk_status); nfs4_mark_deviceid_unavailable(devid); pnfs_error_mark_layout_for_return(inode, lseg); + pnfs_set_lo_fail(lseg); rpc_wake_up(&tbl->slot_tbl_waitq); /* fall through */ default: diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 6b42362cdbb04..113c3b327e24e 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -1763,7 +1763,6 @@ void pnfs_error_mark_layout_for_return(struct inode *inode, struct pnfs_layout_segment *lseg) { struct pnfs_layout_hdr *lo = NFS_I(inode)->layout; - int iomode = pnfs_iomode_to_fail_bit(lseg->pls_range.iomode); struct pnfs_layout_range range = { .iomode = lseg->pls_range.iomode, .offset = 0, @@ -1772,8 +1771,6 @@ void pnfs_error_mark_layout_for_return(struct inode *inode, LIST_HEAD(free_me); spin_lock(&inode->i_lock); - /* set failure bit so that pnfs path will be retried later */ - pnfs_layout_set_fail_bit(lo, iomode); if (lo->plh_return_iomode == 0) lo->plh_return_iomode = range.iomode; else if (lo->plh_return_iomode != range.iomode) -- GitLab From 7eeea1679783e7c1c38074e8c562900b7e3d3dd7 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 17 Dec 2015 09:22:15 -0500 Subject: [PATCH 2104/2855] pNFS/flexfiles: Fix a statistics gathering imbalance When we replay a failed read, write or commit to the dataserver, we need to ensure that we call ff_layout_read_prepare_v3(), ff_layout_write_prepare_v3 or ff_layout_commit_prepare_v3() so that we reset the statistics. Signed-off-by: Trond Myklebust --- fs/nfs/flexfilelayout/flexfilelayout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index 1da19d7094589..14109a82ce84a 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -1130,7 +1130,7 @@ static int ff_layout_async_handle_error_v3(struct rpc_task *task, return -NFS4ERR_RESET_TO_PNFS; out_retry: task->tk_status = 0; - rpc_restart_call(task); + rpc_restart_call_prepare(task); rpc_delay(task, NFS_JUKEBOX_RETRY_TIME); return -EAGAIN; } -- GitLab From 37e9ed22b1552fa94ee7db2901a5e7d8bdf60b15 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 22 Dec 2015 12:30:24 -0500 Subject: [PATCH 2105/2855] pNFS: Add flag to track if we've called nfs4_ff_layout_stat_io_start_read/write Signed-off-by: Trond Myklebust --- fs/nfs/flexfilelayout/flexfilelayout.c | 95 +++++++++++++++++++------- include/linux/nfs_xdr.h | 2 + 2 files changed, 72 insertions(+), 25 deletions(-) diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index 14109a82ce84a..9257679a15bad 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -1279,14 +1279,31 @@ ff_layout_reset_to_mds(struct pnfs_layout_segment *lseg, int idx) return ff_layout_test_devid_unavailable(node); } -static int ff_layout_read_prepare_common(struct rpc_task *task, - struct nfs_pgio_header *hdr) +static void ff_layout_read_record_layoutstats_start(struct rpc_task *task, + struct nfs_pgio_header *hdr) { + if (test_and_set_bit(NFS_IOHDR_STAT, &hdr->flags)) + return; nfs4_ff_layout_stat_io_start_read(hdr->inode, FF_LAYOUT_COMP(hdr->lseg, hdr->pgio_mirror_idx), hdr->args.count, task->tk_start); +} + +static void ff_layout_read_record_layoutstats_done(struct rpc_task *task, + struct nfs_pgio_header *hdr) +{ + if (!test_and_clear_bit(NFS_IOHDR_STAT, &hdr->flags)) + return; + nfs4_ff_layout_stat_io_end_read(task, + FF_LAYOUT_COMP(hdr->lseg, hdr->pgio_mirror_idx), + hdr->args.count, + hdr->res.count); +} +static int ff_layout_read_prepare_common(struct rpc_task *task, + struct nfs_pgio_header *hdr) +{ if (unlikely(test_bit(NFS_CONTEXT_BAD, &hdr->args.context->flags))) { rpc_exit(task, -EIO); return -EIO; @@ -1302,6 +1319,7 @@ static int ff_layout_read_prepare_common(struct rpc_task *task, } hdr->pgio_done_cb = ff_layout_read_done_cb; + ff_layout_read_record_layoutstats_start(task, hdr); return 0; } @@ -1360,10 +1378,6 @@ static void ff_layout_read_call_done(struct rpc_task *task, void *data) dprintk("--> %s task->tk_status %d\n", __func__, task->tk_status); - nfs4_ff_layout_stat_io_end_read(task, - FF_LAYOUT_COMP(hdr->lseg, hdr->pgio_mirror_idx), - hdr->args.count, hdr->res.count); - if (test_bit(NFS_IOHDR_REDO, &hdr->flags) && task->tk_status == 0) { nfs4_sequence_done(task, &hdr->res.seq_res); @@ -1378,6 +1392,7 @@ static void ff_layout_read_count_stats(struct rpc_task *task, void *data) { struct nfs_pgio_header *hdr = data; + ff_layout_read_record_layoutstats_done(task, hdr); rpc_count_iostats_metrics(task, &NFS_CLIENT(hdr->inode)->cl_metrics[NFSPROC4_CLNT_READ]); } @@ -1453,14 +1468,31 @@ static int ff_layout_commit_done_cb(struct rpc_task *task, return 0; } -static int ff_layout_write_prepare_common(struct rpc_task *task, - struct nfs_pgio_header *hdr) +static void ff_layout_write_record_layoutstats_start(struct rpc_task *task, + struct nfs_pgio_header *hdr) { + if (test_and_set_bit(NFS_IOHDR_STAT, &hdr->flags)) + return; nfs4_ff_layout_stat_io_start_write(hdr->inode, FF_LAYOUT_COMP(hdr->lseg, hdr->pgio_mirror_idx), hdr->args.count, task->tk_start); +} + +static void ff_layout_write_record_layoutstats_done(struct rpc_task *task, + struct nfs_pgio_header *hdr) +{ + if (!test_and_clear_bit(NFS_IOHDR_STAT, &hdr->flags)) + return; + nfs4_ff_layout_stat_io_end_write(task, + FF_LAYOUT_COMP(hdr->lseg, hdr->pgio_mirror_idx), + hdr->args.count, hdr->res.count, + hdr->res.verf->committed); +} +static int ff_layout_write_prepare_common(struct rpc_task *task, + struct nfs_pgio_header *hdr) +{ if (unlikely(test_bit(NFS_CONTEXT_BAD, &hdr->args.context->flags))) { rpc_exit(task, -EIO); return -EIO; @@ -1477,6 +1509,7 @@ static int ff_layout_write_prepare_common(struct rpc_task *task, return -EAGAIN; } + ff_layout_write_record_layoutstats_start(task, hdr); return 0; } @@ -1526,23 +1559,45 @@ static void ff_layout_write_count_stats(struct rpc_task *task, void *data) { struct nfs_pgio_header *hdr = data; - nfs4_ff_layout_stat_io_end_write(task, - FF_LAYOUT_COMP(hdr->lseg, hdr->pgio_mirror_idx), - hdr->args.count, hdr->res.count, - hdr->res.verf->committed); - + ff_layout_write_record_layoutstats_done(task, hdr); rpc_count_iostats_metrics(task, &NFS_CLIENT(hdr->inode)->cl_metrics[NFSPROC4_CLNT_WRITE]); } -static void ff_layout_commit_prepare_common(struct rpc_task *task, +static void ff_layout_commit_record_layoutstats_start(struct rpc_task *task, struct nfs_commit_data *cdata) { + if (test_and_set_bit(NFS_IOHDR_STAT, &cdata->flags)) + return; nfs4_ff_layout_stat_io_start_write(cdata->inode, FF_LAYOUT_COMP(cdata->lseg, cdata->ds_commit_index), 0, task->tk_start); } +static void ff_layout_commit_record_layoutstats_done(struct rpc_task *task, + struct nfs_commit_data *cdata) +{ + struct nfs_page *req; + __u64 count = 0; + + if (!test_and_clear_bit(NFS_IOHDR_STAT, &cdata->flags)) + return; + + if (task->tk_status == 0) { + list_for_each_entry(req, &cdata->pages, wb_list) + count += req->wb_bytes; + } + nfs4_ff_layout_stat_io_end_write(task, + FF_LAYOUT_COMP(cdata->lseg, cdata->ds_commit_index), + count, count, NFS_FILE_SYNC); +} + +static void ff_layout_commit_prepare_common(struct rpc_task *task, + struct nfs_commit_data *cdata) +{ + ff_layout_commit_record_layoutstats_start(task, cdata); +} + static void ff_layout_commit_prepare_v3(struct rpc_task *task, void *data) { ff_layout_commit_prepare_common(task, data); @@ -1569,18 +1624,8 @@ static void ff_layout_commit_done(struct rpc_task *task, void *data) static void ff_layout_commit_count_stats(struct rpc_task *task, void *data) { struct nfs_commit_data *cdata = data; - struct nfs_page *req; - __u64 count = 0; - - if (task->tk_status == 0) { - list_for_each_entry(req, &cdata->pages, wb_list) - count += req->wb_bytes; - } - - nfs4_ff_layout_stat_io_end_write(task, - FF_LAYOUT_COMP(cdata->lseg, cdata->ds_commit_index), - count, count, NFS_FILE_SYNC); + ff_layout_commit_record_layoutstats_done(task, cdata); rpc_count_iostats_metrics(task, &NFS_CLIENT(cdata->inode)->cl_metrics[NFSPROC4_CLNT_COMMIT]); } diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 11bbae44f4cbf..7b30ac0c7def8 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1375,6 +1375,7 @@ enum { NFS_IOHDR_ERROR = 0, NFS_IOHDR_EOF, NFS_IOHDR_REDO, + NFS_IOHDR_STAT, }; struct nfs_pgio_header { @@ -1454,6 +1455,7 @@ struct nfs_commit_data { const struct rpc_call_ops *mds_ops; const struct nfs_commit_completion_ops *completion_ops; int (*commit_done_cb) (struct rpc_task *task, struct nfs_commit_data *data); + unsigned long flags; }; struct nfs_pgio_completion_ops { -- GitLab From 4d0ac22109740c36174c5aac630876b2af0f6943 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 22 Dec 2015 15:32:00 -0500 Subject: [PATCH 2106/2855] pNFS/flexfiles: Ensure we record layoutstats even if RPC is terminated early Currently, we will only record the layoutstats correctly if the RPC call successfully obtains a slot. If we exit before that happens, then we may find ourselves starting the busy timer through the call in ff_layout_(read|write)_prepare_layoutstats, but never stopping it. The same thing happens if we're doing DA-DS. The fix is to ensure that we catch these cases in the rpc_release() callback. Signed-off-by: Trond Myklebust --- fs/nfs/flexfilelayout/flexfilelayout.c | 37 +++++++++++++++++++++----- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index 9257679a15bad..2981cd190bfd4 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -1397,6 +1397,15 @@ static void ff_layout_read_count_stats(struct rpc_task *task, void *data) &NFS_CLIENT(hdr->inode)->cl_metrics[NFSPROC4_CLNT_READ]); } +static void ff_layout_read_release(void *data) +{ + struct nfs_pgio_header *hdr = data; + + ff_layout_read_record_layoutstats_done(&hdr->task, hdr); + pnfs_generic_rw_release(data); +} + + static int ff_layout_write_done_cb(struct rpc_task *task, struct nfs_pgio_header *hdr) { @@ -1564,6 +1573,14 @@ static void ff_layout_write_count_stats(struct rpc_task *task, void *data) &NFS_CLIENT(hdr->inode)->cl_metrics[NFSPROC4_CLNT_WRITE]); } +static void ff_layout_write_release(void *data) +{ + struct nfs_pgio_header *hdr = data; + + ff_layout_write_record_layoutstats_done(&hdr->task, hdr); + pnfs_generic_rw_release(data); +} + static void ff_layout_commit_record_layoutstats_start(struct rpc_task *task, struct nfs_commit_data *cdata) { @@ -1630,46 +1647,54 @@ static void ff_layout_commit_count_stats(struct rpc_task *task, void *data) &NFS_CLIENT(cdata->inode)->cl_metrics[NFSPROC4_CLNT_COMMIT]); } +static void ff_layout_commit_release(void *data) +{ + struct nfs_commit_data *cdata = data; + + ff_layout_commit_record_layoutstats_done(&cdata->task, cdata); + pnfs_generic_commit_release(data); +} + static const struct rpc_call_ops ff_layout_read_call_ops_v3 = { .rpc_call_prepare = ff_layout_read_prepare_v3, .rpc_call_done = ff_layout_read_call_done, .rpc_count_stats = ff_layout_read_count_stats, - .rpc_release = pnfs_generic_rw_release, + .rpc_release = ff_layout_read_release, }; static const struct rpc_call_ops ff_layout_read_call_ops_v4 = { .rpc_call_prepare = ff_layout_read_prepare_v4, .rpc_call_done = ff_layout_read_call_done, .rpc_count_stats = ff_layout_read_count_stats, - .rpc_release = pnfs_generic_rw_release, + .rpc_release = ff_layout_read_release, }; static const struct rpc_call_ops ff_layout_write_call_ops_v3 = { .rpc_call_prepare = ff_layout_write_prepare_v3, .rpc_call_done = ff_layout_write_call_done, .rpc_count_stats = ff_layout_write_count_stats, - .rpc_release = pnfs_generic_rw_release, + .rpc_release = ff_layout_write_release, }; static const struct rpc_call_ops ff_layout_write_call_ops_v4 = { .rpc_call_prepare = ff_layout_write_prepare_v4, .rpc_call_done = ff_layout_write_call_done, .rpc_count_stats = ff_layout_write_count_stats, - .rpc_release = pnfs_generic_rw_release, + .rpc_release = ff_layout_write_release, }; static const struct rpc_call_ops ff_layout_commit_call_ops_v3 = { .rpc_call_prepare = ff_layout_commit_prepare_v3, .rpc_call_done = ff_layout_commit_done, .rpc_count_stats = ff_layout_commit_count_stats, - .rpc_release = pnfs_generic_commit_release, + .rpc_release = ff_layout_commit_release, }; static const struct rpc_call_ops ff_layout_commit_call_ops_v4 = { .rpc_call_prepare = ff_layout_commit_prepare_v4, .rpc_call_done = ff_layout_commit_done, .rpc_count_stats = ff_layout_commit_count_stats, - .rpc_release = pnfs_generic_commit_release, + .rpc_release = ff_layout_commit_release, }; static enum pnfs_try_status -- GitLab From ab7d763e477c5be33ac9cffc68e808bbd69371f7 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 28 Dec 2015 10:32:11 -0500 Subject: [PATCH 2107/2855] pNFS: Ensure nfs4_layoutget_prepare returns the correct error If we're unable to perform the layoutget due to an invalid open stateid or a bulk recall, ensure that we return the error so that the caller can decide on an appropriate action. Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 18d862db15b63..fcd7a9039020d 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -7760,6 +7760,7 @@ nfs4_layoutget_prepare(struct rpc_task *task, void *calldata) struct nfs4_layoutget *lgp = calldata; struct nfs_server *server = NFS_SERVER(lgp->args.inode); struct nfs4_session *session = nfs4_get_session(server); + int ret; dprintk("--> %s\n", __func__); /* Note the is a race here, where a CB_LAYOUTRECALL can come in @@ -7770,12 +7771,12 @@ nfs4_layoutget_prepare(struct rpc_task *task, void *calldata) if (nfs41_setup_sequence(session, &lgp->args.seq_args, &lgp->res.seq_res, task)) return; - if (pnfs_choose_layoutget_stateid(&lgp->args.stateid, + ret = pnfs_choose_layoutget_stateid(&lgp->args.stateid, NFS_I(lgp->args.inode)->layout, &lgp->args.range, - lgp->args.ctx->state)) { - rpc_exit(task, NFS4_OK); - } + lgp->args.ctx->state); + if (ret < 0) + rpc_exit(task, ret); } static void nfs4_layoutget_done(struct rpc_task *task, void *calldata) -- GitLab From 0654cc726fc6eed6dca915fb65ba7975716ea080 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 28 Dec 2015 11:48:14 -0500 Subject: [PATCH 2108/2855] NFSv4.1/pNFS: Add a helper to mark the layout as returned This ensures that we don't reuse the stateid if a layout return or implied layout return means that we've returned all layout segments Signed-off-by: Trond Myklebust --- fs/nfs/callback_proc.c | 1 + fs/nfs/nfs4proc.c | 3 ++- fs/nfs/pnfs.c | 1 + fs/nfs/pnfs.h | 13 +++++++++++++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 807eb6ef4f916..716cbff244501 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -192,6 +192,7 @@ static u32 initiate_file_draining(struct nfs_client *clp, NFS_SERVER(ino)->pnfs_curr_ld->return_range(lo, &args->cbl_range); } + pnfs_mark_layout_returned_if_empty(lo); unlock: spin_unlock(&ino->i_lock); pnfs_free_lseg_list(&free_me_list); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index fcd7a9039020d..883da29b9acec 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -8049,9 +8049,10 @@ static void nfs4_layoutreturn_release(void *calldata) dprintk("--> %s\n", __func__); spin_lock(&lo->plh_inode->i_lock); + pnfs_mark_matching_lsegs_invalid(lo, &freeme, &lrp->args.range); + pnfs_mark_layout_returned_if_empty(lo); if (lrp->res.lrs_present) pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); - pnfs_mark_matching_lsegs_invalid(lo, &freeme, &lrp->args.range); pnfs_clear_layoutreturn_waitbit(lo); lo->plh_block_lgets--; spin_unlock(&lo->plh_inode->i_lock); diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 6095a8d42766c..b3fb6bb02275f 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -1149,6 +1149,7 @@ void pnfs_roc_set_barrier(struct inode *ino, u32 barrier) spin_lock(&ino->i_lock); lo = NFS_I(ino)->layout; + pnfs_mark_layout_returned_if_empty(lo); if (pnfs_seqid_is_newer(barrier, lo->plh_barrier)) lo->plh_barrier = barrier; spin_unlock(&ino->i_lock); diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index d1990e90e7a02..be24a759b6559 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -556,6 +556,19 @@ pnfs_calc_offset_length(u64 offset, u64 end) return 1 + end - offset; } +/** + * pnfs_mark_layout_returned_if_empty - marks the layout as returned + * @lo: layout header + * + * Note: Caller must hold inode->i_lock + */ +static inline void +pnfs_mark_layout_returned_if_empty(struct pnfs_layout_hdr *lo) +{ + if (list_empty(&lo->plh_segs)) + set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); +} + extern unsigned int layoutstats_timer; #ifdef NFS_DEBUG -- GitLab From fc7ff36747b991d1be0d68987066ea87eedbb43e Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 28 Dec 2015 10:28:59 -0500 Subject: [PATCH 2109/2855] pNFS: If we have to delay the layout callback, mark the layout for return If the client needs to delay the layout callback, then speed up the recall process by marking the remaining layout segments to be actively returned by the client. Signed-off-by: Trond Myklebust --- fs/nfs/callback_proc.c | 14 ++++++++++++-- fs/nfs/pnfs.c | 4 +++- fs/nfs/pnfs.h | 3 +++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 716cbff244501..34852ece4057f 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -181,9 +181,19 @@ static u32 initiate_file_draining(struct nfs_client *clp, pnfs_layoutcommit_inode(ino, false); spin_lock(&ino->i_lock); - if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) || - pnfs_mark_matching_lsegs_invalid(lo, &free_me_list, + /* + * Enforce RFC5661 Section 12.5.5.2.1.5 (Bulk Recall and Return) + */ + if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags)) { + rv = NFS4ERR_DELAY; + goto unlock; + } + + if (pnfs_mark_matching_lsegs_invalid(lo, &free_me_list, &args->cbl_range)) { + pnfs_mark_matching_lsegs_return(lo, + &free_me_list, + &args->cbl_range); rv = NFS4ERR_DELAY; goto unlock; } diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index b3fb6bb02275f..360fe95c97b5d 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -1756,7 +1756,7 @@ out_forget_reply: goto out; } -static void +void pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, struct list_head *tmp_list, struct pnfs_layout_range *return_range) @@ -1768,6 +1768,8 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, if (list_empty(&lo->plh_segs)) return; + assert_spin_locked(&lo->plh_inode->i_lock); + list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) if (should_free_lseg(&lseg->pls_range, return_range)) { dprintk("%s: marking lseg %p iomode %d " diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index be24a759b6559..d93c2ebc0fd35 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -266,6 +266,9 @@ int pnfs_choose_layoutget_stateid(nfs4_stateid *dst, int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, struct list_head *tmp_list, struct pnfs_layout_range *recall_range); +void pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, + struct list_head *tmp_list, + struct pnfs_layout_range *recall_range); bool pnfs_roc(struct inode *ino); void pnfs_roc_release(struct inode *ino); void pnfs_roc_set_barrier(struct inode *ino, u32 barrier); -- GitLab From 41c9127d6d588138c66b2614ac596ea63313acca Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 28 Dec 2015 12:57:53 -0500 Subject: [PATCH 2110/2855] NFSv4.1/pNFS: Ensure we enforce RFC5661 Section 12.5.5.2.1 The RFC requires us to check if the server is recalling a stateid that we haven't yet received. If so, tell it to wait. Signed-off-by: Trond Myklebust --- fs/nfs/callback_proc.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 34852ece4057f..1b24ad07d4f53 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -160,6 +160,22 @@ static struct pnfs_layout_hdr * get_layout_by_fh(struct nfs_client *clp, return lo; } +/* + * Enforce RFC5661 section 12.5.5.2.1. (Layout Recall and Return Sequencing) + */ +static bool pnfs_check_stateid_sequence(struct pnfs_layout_hdr *lo, + const nfs4_stateid *new) +{ + u32 oldseq, newseq; + + oldseq = be32_to_cpu(lo->plh_stateid.seqid); + newseq = be32_to_cpu(new->seqid); + + if (newseq > oldseq + 1) + return false; + return true; +} + static u32 initiate_file_draining(struct nfs_client *clp, struct cb_layoutrecallargs *args) { @@ -175,6 +191,10 @@ static u32 initiate_file_draining(struct nfs_client *clp, ino = lo->plh_inode; spin_lock(&ino->i_lock); + if (!pnfs_check_stateid_sequence(lo, &args->cbl_stateid)) { + rv = NFS4ERR_DELAY; + goto unlock; + } pnfs_set_layout_stateid(lo, &args->cbl_stateid, true); spin_unlock(&ino->i_lock); -- GitLab From e0d9243048fd18da695b8d3fe331176eac60866e Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 28 Dec 2015 12:21:50 -0500 Subject: [PATCH 2111/2855] NFSv4.1/pNFS: Don't return NFS4ERR_DELAY unnecessarily in CB_LAYOUTRECALL If the client is promising to return the layout ASAP, then there is no need to return DELAY and have the server retry. Instead default to the normal procedure described in RFC5661. Signed-off-by: Trond Myklebust --- fs/nfs/callback_proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 1b24ad07d4f53..724a9b756ab09 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -214,7 +214,7 @@ static u32 initiate_file_draining(struct nfs_client *clp, pnfs_mark_matching_lsegs_return(lo, &free_me_list, &args->cbl_range); - rv = NFS4ERR_DELAY; + rv = NFS4_OK; goto unlock; } -- GitLab From e07db907eb80525874b7707c62cc6f5e975ef130 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 28 Dec 2015 14:07:23 -0500 Subject: [PATCH 2112/2855] NFSv4: List stateid information in the callback tracepoints The stateid is extremely valuable when debugging. Signed-off-by: Trond Myklebust --- fs/nfs/callback_proc.c | 16 +++++++--- fs/nfs/nfs4trace.h | 69 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 724a9b756ab09..e4dbab5dce6e1 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -83,8 +83,11 @@ __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy, res = htonl(NFS4ERR_BADHANDLE); inode = nfs_delegation_find_inode(cps->clp, &args->fh); - if (inode == NULL) + if (inode == NULL) { + trace_nfs4_cb_recall(cps->clp, &args->fh, NULL, + &args->stateid, -ntohl(res)); goto out; + } /* Set up a helper thread to actually return the delegation */ switch (nfs_async_inode_return_delegation(inode, &args->stateid)) { case 0: @@ -96,7 +99,8 @@ __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy, default: res = htonl(NFS4ERR_RESOURCE); } - trace_nfs4_recall_delegation(inode, -ntohl(res)); + trace_nfs4_cb_recall(cps->clp, &args->fh, inode, + &args->stateid, -ntohl(res)); iput(inode); out: dprintk("%s: exit with status = %d\n", __func__, ntohl(res)); @@ -185,8 +189,11 @@ static u32 initiate_file_draining(struct nfs_client *clp, LIST_HEAD(free_me_list); lo = get_layout_by_fh(clp, &args->cbl_fh, &args->cbl_stateid); - if (!lo) + if (!lo) { + trace_nfs4_cb_layoutrecall_file(clp, &args->cbl_fh, NULL, + &args->cbl_stateid, -rv); goto out; + } ino = lo->plh_inode; @@ -227,7 +234,8 @@ unlock: spin_unlock(&ino->i_lock); pnfs_free_lseg_list(&free_me_list); pnfs_put_layout_hdr(lo); - trace_nfs4_cb_layoutrecall_inode(clp, &args->cbl_fh, ino, -rv); + trace_nfs4_cb_layoutrecall_file(clp, &args->cbl_fh, ino, + &args->cbl_stateid, -rv); iput(ino); out: return rv; diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h index d08d0c84b7789..88b6b14ce71b7 100644 --- a/fs/nfs/nfs4trace.h +++ b/fs/nfs/nfs4trace.h @@ -982,7 +982,6 @@ DEFINE_NFS4_INODE_EVENT(nfs4_set_acl); DEFINE_NFS4_INODE_EVENT(nfs4_get_security_label); DEFINE_NFS4_INODE_EVENT(nfs4_set_security_label); #endif /* CONFIG_NFS_V4_SECURITY_LABEL */ -DEFINE_NFS4_INODE_EVENT(nfs4_recall_delegation); DECLARE_EVENT_CLASS(nfs4_inode_stateid_event, TP_PROTO( @@ -1145,8 +1144,74 @@ DECLARE_EVENT_CLASS(nfs4_inode_callback_event, ), \ TP_ARGS(clp, fhandle, inode, error)) DEFINE_NFS4_INODE_CALLBACK_EVENT(nfs4_cb_getattr); -DEFINE_NFS4_INODE_CALLBACK_EVENT(nfs4_cb_layoutrecall_inode); +DECLARE_EVENT_CLASS(nfs4_inode_stateid_callback_event, + TP_PROTO( + const struct nfs_client *clp, + const struct nfs_fh *fhandle, + const struct inode *inode, + const nfs4_stateid *stateid, + int error + ), + + TP_ARGS(clp, fhandle, inode, stateid, error), + + TP_STRUCT__entry( + __field(int, error) + __field(dev_t, dev) + __field(u32, fhandle) + __field(u64, fileid) + __string(dstaddr, clp ? + rpc_peeraddr2str(clp->cl_rpcclient, + RPC_DISPLAY_ADDR) : "unknown") + __field(int, stateid_seq) + __field(u32, stateid_hash) + ), + + TP_fast_assign( + __entry->error = error; + __entry->fhandle = nfs_fhandle_hash(fhandle); + if (inode != NULL) { + __entry->fileid = NFS_FILEID(inode); + __entry->dev = inode->i_sb->s_dev; + } else { + __entry->fileid = 0; + __entry->dev = 0; + } + __assign_str(dstaddr, clp ? + rpc_peeraddr2str(clp->cl_rpcclient, + RPC_DISPLAY_ADDR) : "unknown") + __entry->stateid_seq = + be32_to_cpu(stateid->seqid); + __entry->stateid_hash = + nfs_stateid_hash(stateid); + ), + + TP_printk( + "error=%d (%s) fileid=%02x:%02x:%llu fhandle=0x%08x " + "stateid=%d:0x%08x dstaddr=%s", + __entry->error, + show_nfsv4_errors(__entry->error), + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long long)__entry->fileid, + __entry->fhandle, + __entry->stateid_seq, __entry->stateid_hash, + __get_str(dstaddr) + ) +); + +#define DEFINE_NFS4_INODE_STATEID_CALLBACK_EVENT(name) \ + DEFINE_EVENT(nfs4_inode_stateid_callback_event, name, \ + TP_PROTO( \ + const struct nfs_client *clp, \ + const struct nfs_fh *fhandle, \ + const struct inode *inode, \ + const nfs4_stateid *stateid, \ + int error \ + ), \ + TP_ARGS(clp, fhandle, inode, stateid, error)) +DEFINE_NFS4_INODE_STATEID_CALLBACK_EVENT(nfs4_cb_recall); +DEFINE_NFS4_INODE_STATEID_CALLBACK_EVENT(nfs4_cb_layoutrecall_file); DECLARE_EVENT_CLASS(nfs4_idmap_event, TP_PROTO( -- GitLab From 5c5fc09a1157a11dbe84e6421c3e0b37d05238cb Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 28 Dec 2015 19:30:05 -0500 Subject: [PATCH 2113/2855] NFS: Ensure we revalidate attributes before using execute_ok() Donald Buczek reports that NFS clients can also report incorrect results for access() due to lack of revalidation of attributes before calling execute_ok(). Looking closely, it seems chdir() is afflicted with the same problem. Fix is to ensure we call nfs_revalidate_inode_rcu() or nfs_revalidate_inode() as appropriate before deciding to trust execute_ok(). Reported-by: Donald Buczek Link: http://lkml.kernel.org/r/1451331530-3748-1-git-send-email-buczek@molgen.mpg.de Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 44e519c21e180..5bd2f5bfaf570 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -2432,6 +2432,20 @@ int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags) } EXPORT_SYMBOL_GPL(nfs_may_open); +static int nfs_execute_ok(struct inode *inode, int mask) +{ + struct nfs_server *server = NFS_SERVER(inode); + int ret; + + if (mask & MAY_NOT_BLOCK) + ret = nfs_revalidate_inode_rcu(server, inode); + else + ret = nfs_revalidate_inode(server, inode); + if (ret == 0 && !execute_ok(inode)) + ret = -EACCES; + return ret; +} + int nfs_permission(struct inode *inode, int mask) { struct rpc_cred *cred; @@ -2484,8 +2498,8 @@ force_lookup: res = PTR_ERR(cred); } out: - if (!res && (mask & MAY_EXEC) && !execute_ok(inode)) - res = -EACCES; + if (!res && (mask & MAY_EXEC)) + res = nfs_execute_ok(inode, mask); dfprintk(VFS, "NFS: permission(%s/%lu), mask=0x%x, res=%d\n", inode->i_sb->s_id, inode->i_ino, mask, res); -- GitLab From 0b2b093ad405b56a9e6f4f20a25da77ebfa9549c Mon Sep 17 00:00:00 2001 From: Mathieu OTHACEHE Date: Mon, 28 Dec 2015 21:21:25 +0100 Subject: [PATCH 2114/2855] USB: serial: add Moxa UPORT 11x0 driver Add a driver which supports : - UPort 1110 : 1 port RS-232 USB to Serial Hub. - UPort 1130 : 1 port RS-422/485 USB to Serial Hub. - UPort 1130I : 1 port RS-422/485 USB to Serial Hub with Isolation. - UPort 1150 : 1 port RS-232/422/485 USB to Serial Hub. - UPort 1150I : 1 port RS-232/422/485 USB to Serial Hub with Isolation. This driver is based on GPL MOXA driver written by Hen Huang and available on MOXA website. The original driver was based on io_ti serial driver. Signed-off-by: Mathieu OTHACEHE Signed-off-by: Johan Hovold --- drivers/usb/serial/Kconfig | 16 + drivers/usb/serial/Makefile | 1 + drivers/usb/serial/mxu11x0.c | 995 +++++++++++++++++++++++++++++++++++ 3 files changed, 1012 insertions(+) create mode 100644 drivers/usb/serial/mxu11x0.c diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 56ecb8b5115dd..f612dda9c9778 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -475,6 +475,22 @@ config USB_SERIAL_MOS7840 To compile this driver as a module, choose M here: the module will be called mos7840. If unsure, choose N. +config USB_SERIAL_MXUPORT11 + tristate "USB Moxa UPORT 11x0 Serial Driver" + ---help--- + Say Y here if you want to use a MOXA UPort 11x0 Serial hub. + + This driver supports: + + - UPort 1110 : 1 port RS-232 USB to Serial Hub. + - UPort 1130 : 1 port RS-422/485 USB to Serial Hub. + - UPort 1130I : 1 port RS-422/485 USB to Serial Hub with Isolation. + - UPort 1150 : 1 port RS-232/422/485 USB to Serial Hub. + - UPort 1150I : 1 port RS-232/422/485 USB to Serial Hub with Isolation. + + To compile this driver as a module, choose M here: the + module will be called mxu11x0. + config USB_SERIAL_MXUPORT tristate "USB Moxa UPORT Serial Driver" ---help--- diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 349d9df0895f5..f3fa5e53702d8 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_USB_SERIAL_METRO) += metro-usb.o obj-$(CONFIG_USB_SERIAL_MOS7720) += mos7720.o obj-$(CONFIG_USB_SERIAL_MOS7840) += mos7840.o obj-$(CONFIG_USB_SERIAL_MXUPORT) += mxuport.o +obj-$(CONFIG_USB_SERIAL_MXUPORT11) += mxu11x0.o obj-$(CONFIG_USB_SERIAL_NAVMAN) += navman.o obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o obj-$(CONFIG_USB_SERIAL_OPTICON) += opticon.o diff --git a/drivers/usb/serial/mxu11x0.c b/drivers/usb/serial/mxu11x0.c new file mode 100644 index 0000000000000..8884ca276e672 --- /dev/null +++ b/drivers/usb/serial/mxu11x0.c @@ -0,0 +1,995 @@ +/* + * + * USB Moxa UPORT 11x0 Serial Driver + * + * Copyright (C) 2007 MOXA Technologies Co., Ltd. + * Copyright (C) 2015 Mathieu Othacehe + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * + * Supports the following Moxa USB to serial converters: + * UPort 1110, 1 port RS-232 USB to Serial Hub. + * UPort 1130, 1 port RS-422/485 USB to Serial Hub. + * UPort 1130I, 1 port RS-422/485 USB to Serial Hub with isolation + * protection. + * UPort 1150, 1 port RS-232/422/485 USB to Serial Hub. + * UPort 1150I, 1 port RS-232/422/485 USB to Serial Hub with isolation + * protection. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Vendor and product ids */ +#define MXU1_VENDOR_ID 0x110a +#define MXU1_1110_PRODUCT_ID 0x1110 +#define MXU1_1130_PRODUCT_ID 0x1130 +#define MXU1_1150_PRODUCT_ID 0x1150 +#define MXU1_1151_PRODUCT_ID 0x1151 +#define MXU1_1131_PRODUCT_ID 0x1131 + +/* Commands */ +#define MXU1_GET_VERSION 0x01 +#define MXU1_GET_PORT_STATUS 0x02 +#define MXU1_GET_PORT_DEV_INFO 0x03 +#define MXU1_GET_CONFIG 0x04 +#define MXU1_SET_CONFIG 0x05 +#define MXU1_OPEN_PORT 0x06 +#define MXU1_CLOSE_PORT 0x07 +#define MXU1_START_PORT 0x08 +#define MXU1_STOP_PORT 0x09 +#define MXU1_TEST_PORT 0x0A +#define MXU1_PURGE_PORT 0x0B +#define MXU1_RESET_EXT_DEVICE 0x0C +#define MXU1_GET_OUTQUEUE 0x0D +#define MXU1_WRITE_DATA 0x80 +#define MXU1_READ_DATA 0x81 +#define MXU1_REQ_TYPE_CLASS 0x82 + +/* Module identifiers */ +#define MXU1_I2C_PORT 0x01 +#define MXU1_IEEE1284_PORT 0x02 +#define MXU1_UART1_PORT 0x03 +#define MXU1_UART2_PORT 0x04 +#define MXU1_RAM_PORT 0x05 + +/* Modem status */ +#define MXU1_MSR_DELTA_CTS 0x01 +#define MXU1_MSR_DELTA_DSR 0x02 +#define MXU1_MSR_DELTA_RI 0x04 +#define MXU1_MSR_DELTA_CD 0x08 +#define MXU1_MSR_CTS 0x10 +#define MXU1_MSR_DSR 0x20 +#define MXU1_MSR_RI 0x40 +#define MXU1_MSR_CD 0x80 +#define MXU1_MSR_DELTA_MASK 0x0F +#define MXU1_MSR_MASK 0xF0 + +/* Line status */ +#define MXU1_LSR_OVERRUN_ERROR 0x01 +#define MXU1_LSR_PARITY_ERROR 0x02 +#define MXU1_LSR_FRAMING_ERROR 0x04 +#define MXU1_LSR_BREAK 0x08 +#define MXU1_LSR_ERROR 0x0F +#define MXU1_LSR_RX_FULL 0x10 +#define MXU1_LSR_TX_EMPTY 0x20 + +/* Modem control */ +#define MXU1_MCR_LOOP 0x04 +#define MXU1_MCR_DTR 0x10 +#define MXU1_MCR_RTS 0x20 + +/* Mask settings */ +#define MXU1_UART_ENABLE_RTS_IN 0x0001 +#define MXU1_UART_DISABLE_RTS 0x0002 +#define MXU1_UART_ENABLE_PARITY_CHECKING 0x0008 +#define MXU1_UART_ENABLE_DSR_OUT 0x0010 +#define MXU1_UART_ENABLE_CTS_OUT 0x0020 +#define MXU1_UART_ENABLE_X_OUT 0x0040 +#define MXU1_UART_ENABLE_XA_OUT 0x0080 +#define MXU1_UART_ENABLE_X_IN 0x0100 +#define MXU1_UART_ENABLE_DTR_IN 0x0800 +#define MXU1_UART_DISABLE_DTR 0x1000 +#define MXU1_UART_ENABLE_MS_INTS 0x2000 +#define MXU1_UART_ENABLE_AUTO_START_DMA 0x4000 +#define MXU1_UART_SEND_BREAK_SIGNAL 0x8000 + +/* Parity */ +#define MXU1_UART_NO_PARITY 0x00 +#define MXU1_UART_ODD_PARITY 0x01 +#define MXU1_UART_EVEN_PARITY 0x02 +#define MXU1_UART_MARK_PARITY 0x03 +#define MXU1_UART_SPACE_PARITY 0x04 + +/* Stop bits */ +#define MXU1_UART_1_STOP_BITS 0x00 +#define MXU1_UART_1_5_STOP_BITS 0x01 +#define MXU1_UART_2_STOP_BITS 0x02 + +/* Bits per character */ +#define MXU1_UART_5_DATA_BITS 0x00 +#define MXU1_UART_6_DATA_BITS 0x01 +#define MXU1_UART_7_DATA_BITS 0x02 +#define MXU1_UART_8_DATA_BITS 0x03 + +/* Operation modes */ +#define MXU1_UART_232 0x00 +#define MXU1_UART_485_RECEIVER_DISABLED 0x01 +#define MXU1_UART_485_RECEIVER_ENABLED 0x02 + +/* Pipe transfer mode and timeout */ +#define MXU1_PIPE_MODE_CONTINUOUS 0x01 +#define MXU1_PIPE_MODE_MASK 0x03 +#define MXU1_PIPE_TIMEOUT_MASK 0x7C +#define MXU1_PIPE_TIMEOUT_ENABLE 0x80 + +/* Config struct */ +struct mxu1_uart_config { + __be16 wBaudRate; + __be16 wFlags; + u8 bDataBits; + u8 bParity; + u8 bStopBits; + char cXon; + char cXoff; + u8 bUartMode; +} __packed; + +/* Purge modes */ +#define MXU1_PURGE_OUTPUT 0x00 +#define MXU1_PURGE_INPUT 0x80 + +/* Read/Write data */ +#define MXU1_RW_DATA_ADDR_SFR 0x10 +#define MXU1_RW_DATA_ADDR_IDATA 0x20 +#define MXU1_RW_DATA_ADDR_XDATA 0x30 +#define MXU1_RW_DATA_ADDR_CODE 0x40 +#define MXU1_RW_DATA_ADDR_GPIO 0x50 +#define MXU1_RW_DATA_ADDR_I2C 0x60 +#define MXU1_RW_DATA_ADDR_FLASH 0x70 +#define MXU1_RW_DATA_ADDR_DSP 0x80 + +#define MXU1_RW_DATA_UNSPECIFIED 0x00 +#define MXU1_RW_DATA_BYTE 0x01 +#define MXU1_RW_DATA_WORD 0x02 +#define MXU1_RW_DATA_DOUBLE_WORD 0x04 + +struct mxu1_write_data_bytes { + u8 bAddrType; + u8 bDataType; + u8 bDataCounter; + __be16 wBaseAddrHi; + __be16 wBaseAddrLo; + u8 bData[0]; +} __packed; + +/* Interrupt codes */ +#define MXU1_CODE_HARDWARE_ERROR 0xFF +#define MXU1_CODE_DATA_ERROR 0x03 +#define MXU1_CODE_MODEM_STATUS 0x04 + +static inline int mxu1_get_func_from_code(unsigned char code) +{ + return code & 0x0f; +} + +/* Download firmware max packet size */ +#define MXU1_DOWNLOAD_MAX_PACKET_SIZE 64 + +/* Firmware image header */ +struct mxu1_firmware_header { + __le16 wLength; + u8 bCheckSum; +} __packed; + +#define MXU1_UART_BASE_ADDR 0xFFA0 +#define MXU1_UART_OFFSET_MCR 0x0004 + +#define MXU1_BAUD_BASE 923077 + +#define MXU1_TRANSFER_TIMEOUT 2 +#define MXU1_DOWNLOAD_TIMEOUT 1000 +#define MXU1_DEFAULT_CLOSING_WAIT 4000 /* in .01 secs */ + +struct mxu1_port { + u8 msr; + u8 mcr; + u8 uart_mode; + spinlock_t spinlock; /* Protects msr */ + struct mutex mutex; /* Protects mcr */ + bool send_break; +}; + +struct mxu1_device { + u16 mxd_model; +}; + +static const struct usb_device_id mxu1_idtable[] = { + { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1110_PRODUCT_ID) }, + { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1130_PRODUCT_ID) }, + { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1150_PRODUCT_ID) }, + { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1151_PRODUCT_ID) }, + { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1131_PRODUCT_ID) }, + { } +}; + +MODULE_DEVICE_TABLE(usb, mxu1_idtable); + +/* Write the given buffer out to the control pipe. */ +static int mxu1_send_ctrl_data_urb(struct usb_serial *serial, + u8 request, + u16 value, u16 index, + void *data, size_t size) +{ + int status; + + status = usb_control_msg(serial->dev, + usb_sndctrlpipe(serial->dev, 0), + request, + (USB_DIR_OUT | USB_TYPE_VENDOR | + USB_RECIP_DEVICE), value, index, + data, size, + USB_CTRL_SET_TIMEOUT); + if (status < 0) { + dev_err(&serial->interface->dev, + "%s - usb_control_msg failed: %d\n", + __func__, status); + return status; + } + + if (status != size) { + dev_err(&serial->interface->dev, + "%s - short write (%d / %zd)\n", + __func__, status, size); + return -EIO; + } + + return 0; +} + +/* Send a vendor request without any data */ +static int mxu1_send_ctrl_urb(struct usb_serial *serial, + u8 request, u16 value, u16 index) +{ + return mxu1_send_ctrl_data_urb(serial, request, value, index, + NULL, 0); +} + +static int mxu1_download_firmware(struct usb_serial *serial, + const struct firmware *fw_p) +{ + int status = 0; + int buffer_size; + int pos; + int len; + int done; + u8 cs = 0; + u8 *buffer; + struct usb_device *dev = serial->dev; + struct mxu1_firmware_header *header; + unsigned int pipe; + + pipe = usb_sndbulkpipe(dev, serial->port[0]->bulk_out_endpointAddress); + + buffer_size = fw_p->size + sizeof(*header); + buffer = kmalloc(buffer_size, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + memcpy(buffer, fw_p->data, fw_p->size); + memset(buffer + fw_p->size, 0xff, buffer_size - fw_p->size); + + for (pos = sizeof(*header); pos < buffer_size; pos++) + cs = (u8)(cs + buffer[pos]); + + header = (struct mxu1_firmware_header *)buffer; + header->wLength = cpu_to_le16(buffer_size - sizeof(*header)); + header->bCheckSum = cs; + + dev_dbg(&dev->dev, "%s - downloading firmware\n", __func__); + + for (pos = 0; pos < buffer_size; pos += done) { + len = min(buffer_size - pos, MXU1_DOWNLOAD_MAX_PACKET_SIZE); + + status = usb_bulk_msg(dev, pipe, buffer + pos, len, &done, + MXU1_DOWNLOAD_TIMEOUT); + if (status) + break; + } + + kfree(buffer); + + if (status) { + dev_err(&dev->dev, "failed to download firmware: %d\n", status); + return status; + } + + msleep_interruptible(100); + usb_reset_device(dev); + + dev_dbg(&dev->dev, "%s - download successful\n", __func__); + + return 0; +} + +static int mxu1_port_probe(struct usb_serial_port *port) +{ + struct mxu1_port *mxport; + struct mxu1_device *mxdev; + struct urb *urb; + + mxport = kzalloc(sizeof(struct mxu1_port), GFP_KERNEL); + if (!mxport) + return -ENOMEM; + + spin_lock_init(&mxport->spinlock); + mutex_init(&mxport->mutex); + + mxdev = usb_get_serial_data(port->serial); + + urb = port->interrupt_in_urb; + if (!urb) { + dev_err(&port->dev, "%s - no interrupt urb\n", __func__); + return -EINVAL; + } + + switch (mxdev->mxd_model) { + case MXU1_1110_PRODUCT_ID: + case MXU1_1150_PRODUCT_ID: + case MXU1_1151_PRODUCT_ID: + mxport->uart_mode = MXU1_UART_232; + break; + case MXU1_1130_PRODUCT_ID: + case MXU1_1131_PRODUCT_ID: + mxport->uart_mode = MXU1_UART_485_RECEIVER_DISABLED; + break; + } + + usb_set_serial_port_data(port, mxport); + + port->port.closing_wait = + msecs_to_jiffies(MXU1_DEFAULT_CLOSING_WAIT * 10); + port->port.drain_delay = 1; + + return 0; +} + +static int mxu1_startup(struct usb_serial *serial) +{ + struct mxu1_device *mxdev; + struct usb_device *dev = serial->dev; + struct usb_host_interface *cur_altsetting; + char fw_name[32]; + const struct firmware *fw_p = NULL; + int err; + int status = 0; + + dev_dbg(&serial->interface->dev, "%s - product 0x%04X, num configurations %d, configuration value %d\n", + __func__, le16_to_cpu(dev->descriptor.idProduct), + dev->descriptor.bNumConfigurations, + dev->actconfig->desc.bConfigurationValue); + + /* create device structure */ + mxdev = kzalloc(sizeof(struct mxu1_device), GFP_KERNEL); + if (!mxdev) + return -ENOMEM; + + usb_set_serial_data(serial, mxdev); + + mxdev->mxd_model = le16_to_cpu(dev->descriptor.idProduct); + + cur_altsetting = serial->interface->cur_altsetting; + + /* if we have only 1 configuration, download firmware */ + if (cur_altsetting->desc.bNumEndpoints == 1) { + + snprintf(fw_name, + sizeof(fw_name), + "moxa/moxa-%04x.fw", + mxdev->mxd_model); + + err = request_firmware(&fw_p, fw_name, &serial->interface->dev); + if (err) { + dev_err(&serial->interface->dev, "failed to request firmware: %d\n", + err); + kfree(mxdev); + return err; + } + + err = mxu1_download_firmware(serial, fw_p); + if (err) { + release_firmware(fw_p); + kfree(mxdev); + return err; + } + + status = -ENODEV; + release_firmware(fw_p); + } + + return status; +} + +static int mxu1_write_byte(struct usb_serial_port *port, u32 addr, + u8 mask, u8 byte) +{ + int status; + size_t size; + struct mxu1_write_data_bytes *data; + + dev_dbg(&port->dev, "%s - addr 0x%08X, mask 0x%02X, byte 0x%02X\n", + __func__, addr, mask, byte); + + size = sizeof(struct mxu1_write_data_bytes) + 2; + data = kzalloc(size, GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->bAddrType = MXU1_RW_DATA_ADDR_XDATA; + data->bDataType = MXU1_RW_DATA_BYTE; + data->bDataCounter = 1; + data->wBaseAddrHi = cpu_to_be16(addr >> 16); + data->wBaseAddrLo = cpu_to_be16(addr); + data->bData[0] = mask; + data->bData[1] = byte; + + status = mxu1_send_ctrl_data_urb(port->serial, MXU1_WRITE_DATA, 0, + MXU1_RAM_PORT, data, size); + if (status < 0) + dev_err(&port->dev, "%s - failed: %d\n", __func__, status); + + kfree(data); + + return status; +} + +static int mxu1_set_mcr(struct usb_serial_port *port, unsigned int mcr) +{ + int status; + + status = mxu1_write_byte(port, + MXU1_UART_BASE_ADDR + MXU1_UART_OFFSET_MCR, + MXU1_MCR_RTS | MXU1_MCR_DTR | MXU1_MCR_LOOP, + mcr); + return status; +} + +static void mxu1_set_termios(struct tty_struct *tty, + struct usb_serial_port *port, + struct ktermios *old_termios) +{ + struct mxu1_port *mxport = usb_get_serial_port_data(port); + struct mxu1_uart_config *config; + tcflag_t cflag, iflag; + speed_t baud; + int status; + unsigned int mcr; + + cflag = tty->termios.c_cflag; + iflag = tty->termios.c_iflag; + + if (old_termios && + !tty_termios_hw_change(&tty->termios, old_termios) && + tty->termios.c_iflag == old_termios->c_iflag) { + dev_dbg(&port->dev, "%s - nothing to change\n", __func__); + return; + } + + dev_dbg(&port->dev, + "%s - clfag %08x, iflag %08x\n", __func__, cflag, iflag); + + if (old_termios) { + dev_dbg(&port->dev, "%s - old clfag %08x, old iflag %08x\n", + __func__, + old_termios->c_cflag, + old_termios->c_iflag); + } + + config = kzalloc(sizeof(*config), GFP_KERNEL); + if (!config) + return; + + /* these flags must be set */ + config->wFlags |= MXU1_UART_ENABLE_MS_INTS; + config->wFlags |= MXU1_UART_ENABLE_AUTO_START_DMA; + if (mxport->send_break) + config->wFlags |= MXU1_UART_SEND_BREAK_SIGNAL; + config->bUartMode = mxport->uart_mode; + + switch (C_CSIZE(tty)) { + case CS5: + config->bDataBits = MXU1_UART_5_DATA_BITS; + break; + case CS6: + config->bDataBits = MXU1_UART_6_DATA_BITS; + break; + case CS7: + config->bDataBits = MXU1_UART_7_DATA_BITS; + break; + default: + case CS8: + config->bDataBits = MXU1_UART_8_DATA_BITS; + break; + } + + if (C_PARENB(tty)) { + config->wFlags |= MXU1_UART_ENABLE_PARITY_CHECKING; + if (C_CMSPAR(tty)) { + if (C_PARODD(tty)) + config->bParity = MXU1_UART_MARK_PARITY; + else + config->bParity = MXU1_UART_SPACE_PARITY; + } else { + if (C_PARODD(tty)) + config->bParity = MXU1_UART_ODD_PARITY; + else + config->bParity = MXU1_UART_EVEN_PARITY; + } + } else { + config->bParity = MXU1_UART_NO_PARITY; + } + + if (C_CSTOPB(tty)) + config->bStopBits = MXU1_UART_2_STOP_BITS; + else + config->bStopBits = MXU1_UART_1_STOP_BITS; + + if (C_CRTSCTS(tty)) { + /* RTS flow control must be off to drop RTS for baud rate B0 */ + if (C_BAUD(tty) != B0) + config->wFlags |= MXU1_UART_ENABLE_RTS_IN; + config->wFlags |= MXU1_UART_ENABLE_CTS_OUT; + } + + if (I_IXOFF(tty) || I_IXON(tty)) { + config->cXon = START_CHAR(tty); + config->cXoff = STOP_CHAR(tty); + + if (I_IXOFF(tty)) + config->wFlags |= MXU1_UART_ENABLE_X_IN; + + if (I_IXON(tty)) + config->wFlags |= MXU1_UART_ENABLE_X_OUT; + } + + baud = tty_get_baud_rate(tty); + if (!baud) + baud = 9600; + config->wBaudRate = MXU1_BAUD_BASE / baud; + + dev_dbg(&port->dev, "%s - BaudRate=%d, wBaudRate=%d, wFlags=0x%04X, bDataBits=%d, bParity=%d, bStopBits=%d, cXon=%d, cXoff=%d, bUartMode=%d\n", + __func__, baud, config->wBaudRate, config->wFlags, + config->bDataBits, config->bParity, config->bStopBits, + config->cXon, config->cXoff, config->bUartMode); + + cpu_to_be16s(&config->wBaudRate); + cpu_to_be16s(&config->wFlags); + + status = mxu1_send_ctrl_data_urb(port->serial, MXU1_SET_CONFIG, 0, + MXU1_UART1_PORT, config, + sizeof(*config)); + if (status) + dev_err(&port->dev, "cannot set config: %d\n", status); + + mutex_lock(&mxport->mutex); + mcr = mxport->mcr; + + if (C_BAUD(tty) == B0) + mcr &= ~(MXU1_MCR_DTR | MXU1_MCR_RTS); + else if (old_termios && (old_termios->c_cflag & CBAUD) == B0) + mcr |= ~(MXU1_MCR_DTR | MXU1_MCR_RTS); + + status = mxu1_set_mcr(port, mcr); + if (status) + dev_err(&port->dev, "cannot set modem control: %d\n", status); + else + mxport->mcr = mcr; + + mutex_unlock(&mxport->mutex); + + kfree(config); +} + +static int mxu1_get_serial_info(struct usb_serial_port *port, + struct serial_struct __user *ret_arg) +{ + struct serial_struct ret_serial; + unsigned cwait; + + if (!ret_arg) + return -EFAULT; + + cwait = port->port.closing_wait; + if (cwait != ASYNC_CLOSING_WAIT_NONE) + cwait = jiffies_to_msecs(cwait) / 10; + + memset(&ret_serial, 0, sizeof(ret_serial)); + + ret_serial.type = PORT_16550A; + ret_serial.line = port->minor; + ret_serial.port = 0; + ret_serial.xmit_fifo_size = port->bulk_out_size; + ret_serial.baud_base = MXU1_BAUD_BASE; + ret_serial.close_delay = 5*HZ; + ret_serial.closing_wait = cwait; + + if (copy_to_user(ret_arg, &ret_serial, sizeof(*ret_arg))) + return -EFAULT; + + return 0; +} + + +static int mxu1_set_serial_info(struct usb_serial_port *port, + struct serial_struct __user *new_arg) +{ + struct serial_struct new_serial; + unsigned cwait; + + if (copy_from_user(&new_serial, new_arg, sizeof(new_serial))) + return -EFAULT; + + cwait = new_serial.closing_wait; + if (cwait != ASYNC_CLOSING_WAIT_NONE) + cwait = msecs_to_jiffies(10 * new_serial.closing_wait); + + port->port.closing_wait = cwait; + + return 0; +} + +static int mxu1_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + struct usb_serial_port *port = tty->driver_data; + + switch (cmd) { + case TIOCGSERIAL: + return mxu1_get_serial_info(port, + (struct serial_struct __user *)arg); + case TIOCSSERIAL: + return mxu1_set_serial_info(port, + (struct serial_struct __user *)arg); + } + + return -ENOIOCTLCMD; +} + +static int mxu1_tiocmget(struct tty_struct *tty) +{ + struct usb_serial_port *port = tty->driver_data; + struct mxu1_port *mxport = usb_get_serial_port_data(port); + unsigned int result; + unsigned int msr; + unsigned int mcr; + unsigned long flags; + + mutex_lock(&mxport->mutex); + spin_lock_irqsave(&mxport->spinlock, flags); + + msr = mxport->msr; + mcr = mxport->mcr; + + spin_unlock_irqrestore(&mxport->spinlock, flags); + mutex_unlock(&mxport->mutex); + + result = ((mcr & MXU1_MCR_DTR) ? TIOCM_DTR : 0) | + ((mcr & MXU1_MCR_RTS) ? TIOCM_RTS : 0) | + ((mcr & MXU1_MCR_LOOP) ? TIOCM_LOOP : 0) | + ((msr & MXU1_MSR_CTS) ? TIOCM_CTS : 0) | + ((msr & MXU1_MSR_CD) ? TIOCM_CAR : 0) | + ((msr & MXU1_MSR_RI) ? TIOCM_RI : 0) | + ((msr & MXU1_MSR_DSR) ? TIOCM_DSR : 0); + + dev_dbg(&port->dev, "%s - 0x%04X\n", __func__, result); + + return result; +} + +static int mxu1_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + struct usb_serial_port *port = tty->driver_data; + struct mxu1_port *mxport = usb_get_serial_port_data(port); + int err; + unsigned int mcr; + + mutex_lock(&mxport->mutex); + mcr = mxport->mcr; + + if (set & TIOCM_RTS) + mcr |= MXU1_MCR_RTS; + if (set & TIOCM_DTR) + mcr |= MXU1_MCR_DTR; + if (set & TIOCM_LOOP) + mcr |= MXU1_MCR_LOOP; + + if (clear & TIOCM_RTS) + mcr &= ~MXU1_MCR_RTS; + if (clear & TIOCM_DTR) + mcr &= ~MXU1_MCR_DTR; + if (clear & TIOCM_LOOP) + mcr &= ~MXU1_MCR_LOOP; + + err = mxu1_set_mcr(port, mcr); + if (!err) + mxport->mcr = mcr; + + mutex_unlock(&mxport->mutex); + + return err; +} + +static void mxu1_break(struct tty_struct *tty, int break_state) +{ + struct usb_serial_port *port = tty->driver_data; + struct mxu1_port *mxport = usb_get_serial_port_data(port); + + if (break_state == -1) + mxport->send_break = true; + else + mxport->send_break = false; + + mxu1_set_termios(tty, port, NULL); +} + +static int mxu1_open(struct tty_struct *tty, struct usb_serial_port *port) +{ + struct mxu1_port *mxport = usb_get_serial_port_data(port); + struct usb_serial *serial = port->serial; + int status; + u16 open_settings; + + open_settings = (MXU1_PIPE_MODE_CONTINUOUS | + MXU1_PIPE_TIMEOUT_ENABLE | + (MXU1_TRANSFER_TIMEOUT << 2)); + + mxport->msr = 0; + + dev_dbg(&port->dev, "%s - start interrupt in urb\n", __func__); + status = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); + if (status) { + dev_err(&port->dev, "failed to submit interrupt urb: %d\n", + status); + return status; + } + + if (tty) + mxu1_set_termios(tty, port, NULL); + + status = mxu1_send_ctrl_urb(serial, MXU1_OPEN_PORT, + open_settings, MXU1_UART1_PORT); + if (status) { + dev_err(&port->dev, "%s - cannot send open command: %d\n", + __func__, status); + goto unlink_int_urb; + } + + status = mxu1_send_ctrl_urb(serial, MXU1_START_PORT, + 0, MXU1_UART1_PORT); + if (status) { + dev_err(&port->dev, "%s - cannot send start command: %d\n", + __func__, status); + goto unlink_int_urb; + } + + status = mxu1_send_ctrl_urb(serial, MXU1_PURGE_PORT, + MXU1_PURGE_INPUT, MXU1_UART1_PORT); + if (status) { + dev_err(&port->dev, "%s - cannot clear input buffers: %d\n", + __func__, status); + + goto unlink_int_urb; + } + + status = mxu1_send_ctrl_urb(serial, MXU1_PURGE_PORT, + MXU1_PURGE_OUTPUT, MXU1_UART1_PORT); + if (status) { + dev_err(&port->dev, "%s - cannot clear output buffers: %d\n", + __func__, status); + + goto unlink_int_urb; + } + + /* + * reset the data toggle on the bulk endpoints to work around bug in + * host controllers where things get out of sync some times + */ + usb_clear_halt(serial->dev, port->write_urb->pipe); + usb_clear_halt(serial->dev, port->read_urb->pipe); + + if (tty) + mxu1_set_termios(tty, port, NULL); + + status = mxu1_send_ctrl_urb(serial, MXU1_OPEN_PORT, + open_settings, MXU1_UART1_PORT); + if (status) { + dev_err(&port->dev, "%s - cannot send open command: %d\n", + __func__, status); + goto unlink_int_urb; + } + + status = mxu1_send_ctrl_urb(serial, MXU1_START_PORT, + 0, MXU1_UART1_PORT); + if (status) { + dev_err(&port->dev, "%s - cannot send start command: %d\n", + __func__, status); + goto unlink_int_urb; + } + + status = usb_serial_generic_open(tty, port); + if (status) { + dev_err(&port->dev, "%s - submit read urb failed: %d\n", + __func__, status); + goto unlink_int_urb; + } + + return status; + +unlink_int_urb: + usb_kill_urb(port->interrupt_in_urb); + + return status; +} + +static void mxu1_close(struct usb_serial_port *port) +{ + int status; + + usb_serial_generic_close(port); + usb_kill_urb(port->interrupt_in_urb); + + status = mxu1_send_ctrl_urb(port->serial, MXU1_CLOSE_PORT, + 0, MXU1_UART1_PORT); + if (status) + dev_err(&port->dev, "failed to send close port command: %d\n", + status); +} + +static void mxu1_handle_new_msr(struct usb_serial_port *port, u8 msr) +{ + struct async_icount *icount; + struct mxu1_port *mxport; + unsigned long flags; + + dev_dbg(&port->dev, "%s - msr 0x%02X\n", __func__, msr); + + mxport = usb_get_serial_port_data(port); + + spin_lock_irqsave(&mxport->spinlock, flags); + mxport->msr = msr & MXU1_MSR_MASK; + spin_unlock_irqrestore(&mxport->spinlock, flags); + + if (msr & MXU1_MSR_DELTA_MASK) { + icount = &port->icount; + if (msr & MXU1_MSR_DELTA_CTS) + icount->cts++; + if (msr & MXU1_MSR_DELTA_DSR) + icount->dsr++; + if (msr & MXU1_MSR_DELTA_CD) + icount->dcd++; + if (msr & MXU1_MSR_DELTA_RI) + icount->rng++; + + wake_up_interruptible(&port->port.delta_msr_wait); + } +} + +static void mxu1_interrupt_callback(struct urb *urb) +{ + struct usb_serial_port *port = urb->context; + unsigned char *data = urb->transfer_buffer; + int length = urb->actual_length; + int function; + int status; + u8 msr; + + switch (urb->status) { + case 0: + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + dev_dbg(&port->dev, "%s - urb shutting down: %d\n", + __func__, urb->status); + return; + default: + dev_dbg(&port->dev, "%s - nonzero urb status: %d\n", + __func__, urb->status); + goto exit; + } + + if (length != 2) { + dev_dbg(&port->dev, "%s - bad packet size: %d\n", + __func__, length); + goto exit; + } + + if (data[0] == MXU1_CODE_HARDWARE_ERROR) { + dev_err(&port->dev, "%s - hardware error: %d\n", + __func__, data[1]); + goto exit; + } + + function = mxu1_get_func_from_code(data[0]); + + dev_dbg(&port->dev, "%s - function %d, data 0x%02X\n", + __func__, function, data[1]); + + switch (function) { + case MXU1_CODE_DATA_ERROR: + dev_dbg(&port->dev, "%s - DATA ERROR, data 0x%02X\n", + __func__, data[1]); + break; + + case MXU1_CODE_MODEM_STATUS: + msr = data[1]; + mxu1_handle_new_msr(port, msr); + break; + + default: + dev_err(&port->dev, "%s - unknown interrupt code: 0x%02X\n", + __func__, data[1]); + break; + } + +exit: + status = usb_submit_urb(urb, GFP_ATOMIC); + if (status) + dev_err(&port->dev, "resubmit interrupt urb failed: %d\n", + status); +} + +static struct usb_serial_driver mxuport11_device = { + .driver = { + .owner = THIS_MODULE, + .name = "mxuport11", + }, + .description = "MOXA UPort 11x0", + .id_table = mxu1_idtable, + .num_ports = 1, + .port_probe = mxu1_port_probe, + .attach = mxu1_startup, + .open = mxu1_open, + .close = mxu1_close, + .ioctl = mxu1_ioctl, + .set_termios = mxu1_set_termios, + .tiocmget = mxu1_tiocmget, + .tiocmset = mxu1_tiocmset, + .tiocmiwait = usb_serial_generic_tiocmiwait, + .get_icount = usb_serial_generic_get_icount, + .break_ctl = mxu1_break, + .read_int_callback = mxu1_interrupt_callback, +}; + +static struct usb_serial_driver *const serial_drivers[] = { + &mxuport11_device, NULL +}; + +module_usb_serial_driver(serial_drivers, mxu1_idtable); + +MODULE_AUTHOR("Mathieu Othacehe "); +MODULE_DESCRIPTION("MOXA UPort 11x0 USB to Serial Hub Driver"); +MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("moxa/moxa-1110.fw"); +MODULE_FIRMWARE("moxa/moxa-1130.fw"); +MODULE_FIRMWARE("moxa/moxa-1131.fw"); +MODULE_FIRMWARE("moxa/moxa-1150.fw"); +MODULE_FIRMWARE("moxa/moxa-1151.fw"); -- GitLab From 924eccc73db2f64a24865d21ff11be8043b24375 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 Dec 2015 13:36:11 +0100 Subject: [PATCH 2115/2855] USB: mxu11x0: fix memory leak in port-probe error path Fix memory leak in port-probe error path by verifying the interrupt-in urb before allocating the private data. Signed-off-by: Johan Hovold --- drivers/usb/serial/mxu11x0.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/usb/serial/mxu11x0.c b/drivers/usb/serial/mxu11x0.c index 8884ca276e672..89426c3eba989 100644 --- a/drivers/usb/serial/mxu11x0.c +++ b/drivers/usb/serial/mxu11x0.c @@ -333,7 +333,11 @@ static int mxu1_port_probe(struct usb_serial_port *port) { struct mxu1_port *mxport; struct mxu1_device *mxdev; - struct urb *urb; + + if (!port->interrupt_in_urb) { + dev_err(&port->dev, "no interrupt urb\n"); + return -ENODEV; + } mxport = kzalloc(sizeof(struct mxu1_port), GFP_KERNEL); if (!mxport) @@ -344,12 +348,6 @@ static int mxu1_port_probe(struct usb_serial_port *port) mxdev = usb_get_serial_data(port->serial); - urb = port->interrupt_in_urb; - if (!urb) { - dev_err(&port->dev, "%s - no interrupt urb\n", __func__); - return -EINVAL; - } - switch (mxdev->mxd_model) { case MXU1_1110_PRODUCT_ID: case MXU1_1150_PRODUCT_ID: -- GitLab From e69f7a6724182e3f3a4f3d73e74c08dd8f657a9d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 Dec 2015 13:36:12 +0100 Subject: [PATCH 2116/2855] USB: mxu11x0: fix memory leak on firmware download Make sure to release the private data before returning -ENODEV after having downloaded the firmware during first probe. Clean up the error paths while at it. Signed-off-by: Johan Hovold --- drivers/usb/serial/mxu11x0.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/usb/serial/mxu11x0.c b/drivers/usb/serial/mxu11x0.c index 89426c3eba989..c6c4776997fcd 100644 --- a/drivers/usb/serial/mxu11x0.c +++ b/drivers/usb/serial/mxu11x0.c @@ -377,7 +377,6 @@ static int mxu1_startup(struct usb_serial *serial) char fw_name[32]; const struct firmware *fw_p = NULL; int err; - int status = 0; dev_dbg(&serial->interface->dev, "%s - product 0x%04X, num configurations %d, configuration value %d\n", __func__, le16_to_cpu(dev->descriptor.idProduct), @@ -407,22 +406,26 @@ static int mxu1_startup(struct usb_serial *serial) if (err) { dev_err(&serial->interface->dev, "failed to request firmware: %d\n", err); - kfree(mxdev); - return err; + goto err_free_mxdev; } err = mxu1_download_firmware(serial, fw_p); - if (err) { - release_firmware(fw_p); - kfree(mxdev); - return err; - } + if (err) + goto err_release_firmware; - status = -ENODEV; - release_firmware(fw_p); + /* device is being reset */ + err = -ENODEV; + goto err_release_firmware; } - return status; + return 0; + +err_release_firmware: + release_firmware(fw_p); +err_free_mxdev: + kfree(mxdev); + + return err; } static int mxu1_write_byte(struct usb_serial_port *port, u32 addr, -- GitLab From 9631595a253e62a2be7476f99a23ade786829d5f Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 Dec 2015 13:36:13 +0100 Subject: [PATCH 2117/2855] USB: mxu11x0: fix modem-control handling on B0-transitions Make sure to raise DTR and RTS on transitions from B0 and leave the other bits unchanged. Signed-off-by: Johan Hovold --- drivers/usb/serial/mxu11x0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/serial/mxu11x0.c b/drivers/usb/serial/mxu11x0.c index c6c4776997fcd..c408cd7b4dc65 100644 --- a/drivers/usb/serial/mxu11x0.c +++ b/drivers/usb/serial/mxu11x0.c @@ -595,7 +595,7 @@ static void mxu1_set_termios(struct tty_struct *tty, if (C_BAUD(tty) == B0) mcr &= ~(MXU1_MCR_DTR | MXU1_MCR_RTS); else if (old_termios && (old_termios->c_cflag & CBAUD) == B0) - mcr |= ~(MXU1_MCR_DTR | MXU1_MCR_RTS); + mcr |= MXU1_MCR_DTR | MXU1_MCR_RTS; status = mxu1_set_mcr(port, mcr); if (status) -- GitLab From 554eb0f205959081361965d04361ef03ca0e066d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 Dec 2015 13:36:14 +0100 Subject: [PATCH 2118/2855] USB: mxu11x0: rename usb-serial driver Rename the usb-serial driver "mxu11x0" to match the USB driver name. Signed-off-by: Johan Hovold --- drivers/usb/serial/mxu11x0.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/mxu11x0.c b/drivers/usb/serial/mxu11x0.c index c408cd7b4dc65..73cc8564a562f 100644 --- a/drivers/usb/serial/mxu11x0.c +++ b/drivers/usb/serial/mxu11x0.c @@ -958,10 +958,10 @@ exit: status); } -static struct usb_serial_driver mxuport11_device = { +static struct usb_serial_driver mxu11x0_device = { .driver = { .owner = THIS_MODULE, - .name = "mxuport11", + .name = "mxu11x0", }, .description = "MOXA UPort 11x0", .id_table = mxu1_idtable, @@ -981,7 +981,7 @@ static struct usb_serial_driver mxuport11_device = { }; static struct usb_serial_driver *const serial_drivers[] = { - &mxuport11_device, NULL + &mxu11x0_device, NULL }; module_usb_serial_driver(serial_drivers, mxu1_idtable); -- GitLab From 3645ea87b9cd50123054aa0fd2417f601c45566f Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 Dec 2015 13:36:15 +0100 Subject: [PATCH 2119/2855] USB: mxu11x0: fix debug-message typos Fix a couple of debug-message typos, and do some minor clean ups. Signed-off-by: Johan Hovold --- drivers/usb/serial/mxu11x0.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/usb/serial/mxu11x0.c b/drivers/usb/serial/mxu11x0.c index 73cc8564a562f..c8c9596798279 100644 --- a/drivers/usb/serial/mxu11x0.c +++ b/drivers/usb/serial/mxu11x0.c @@ -1,5 +1,4 @@ /* - * * USB Moxa UPORT 11x0 Serial Driver * * Copyright (C) 2007 MOXA Technologies Co., Ltd. @@ -494,10 +493,10 @@ static void mxu1_set_termios(struct tty_struct *tty, } dev_dbg(&port->dev, - "%s - clfag %08x, iflag %08x\n", __func__, cflag, iflag); + "%s - cflag 0x%08x, iflag 0x%08x\n", __func__, cflag, iflag); if (old_termios) { - dev_dbg(&port->dev, "%s - old clfag %08x, old iflag %08x\n", + dev_dbg(&port->dev, "%s - old cflag 0x%08x, old iflag 0x%08x\n", __func__, old_termios->c_cflag, old_termios->c_iflag); @@ -764,7 +763,6 @@ static int mxu1_open(struct tty_struct *tty, struct usb_serial_port *port) mxport->msr = 0; - dev_dbg(&port->dev, "%s - start interrupt in urb\n", __func__); status = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (status) { dev_err(&port->dev, "failed to submit interrupt urb: %d\n", @@ -842,7 +840,7 @@ static int mxu1_open(struct tty_struct *tty, struct usb_serial_port *port) goto unlink_int_urb; } - return status; + return 0; unlink_int_urb: usb_kill_urb(port->interrupt_in_urb); @@ -859,21 +857,20 @@ static void mxu1_close(struct usb_serial_port *port) status = mxu1_send_ctrl_urb(port->serial, MXU1_CLOSE_PORT, 0, MXU1_UART1_PORT); - if (status) + if (status) { dev_err(&port->dev, "failed to send close port command: %d\n", status); + } } static void mxu1_handle_new_msr(struct usb_serial_port *port, u8 msr) { + struct mxu1_port *mxport = usb_get_serial_port_data(port); struct async_icount *icount; - struct mxu1_port *mxport; unsigned long flags; dev_dbg(&port->dev, "%s - msr 0x%02X\n", __func__, msr); - mxport = usb_get_serial_port_data(port); - spin_lock_irqsave(&mxport->spinlock, flags); mxport->msr = msr & MXU1_MSR_MASK; spin_unlock_irqrestore(&mxport->spinlock, flags); @@ -953,9 +950,10 @@ static void mxu1_interrupt_callback(struct urb *urb) exit: status = usb_submit_urb(urb, GFP_ATOMIC); - if (status) + if (status) { dev_err(&port->dev, "resubmit interrupt urb failed: %d\n", status); + } } static struct usb_serial_driver mxu11x0_device = { -- GitLab From 6ff9d2761b8655991f48f113f7edaefea5c92905 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 Dec 2015 13:36:16 +0100 Subject: [PATCH 2120/2855] USB: mxu11x0: drop redundant function name from error messages Drop redundant function name from a few error messages. Drop redundant error message when generic open fails. Signed-off-by: Johan Hovold --- drivers/usb/serial/mxu11x0.c | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/drivers/usb/serial/mxu11x0.c b/drivers/usb/serial/mxu11x0.c index c8c9596798279..e3c3f57c2d828 100644 --- a/drivers/usb/serial/mxu11x0.c +++ b/drivers/usb/serial/mxu11x0.c @@ -776,24 +776,22 @@ static int mxu1_open(struct tty_struct *tty, struct usb_serial_port *port) status = mxu1_send_ctrl_urb(serial, MXU1_OPEN_PORT, open_settings, MXU1_UART1_PORT); if (status) { - dev_err(&port->dev, "%s - cannot send open command: %d\n", - __func__, status); + dev_err(&port->dev, "cannot send open command: %d\n", status); goto unlink_int_urb; } status = mxu1_send_ctrl_urb(serial, MXU1_START_PORT, 0, MXU1_UART1_PORT); if (status) { - dev_err(&port->dev, "%s - cannot send start command: %d\n", - __func__, status); + dev_err(&port->dev, "cannot send start command: %d\n", status); goto unlink_int_urb; } status = mxu1_send_ctrl_urb(serial, MXU1_PURGE_PORT, MXU1_PURGE_INPUT, MXU1_UART1_PORT); if (status) { - dev_err(&port->dev, "%s - cannot clear input buffers: %d\n", - __func__, status); + dev_err(&port->dev, "cannot clear input buffers: %d\n", + status); goto unlink_int_urb; } @@ -801,8 +799,8 @@ static int mxu1_open(struct tty_struct *tty, struct usb_serial_port *port) status = mxu1_send_ctrl_urb(serial, MXU1_PURGE_PORT, MXU1_PURGE_OUTPUT, MXU1_UART1_PORT); if (status) { - dev_err(&port->dev, "%s - cannot clear output buffers: %d\n", - __func__, status); + dev_err(&port->dev, "cannot clear output buffers: %d\n", + status); goto unlink_int_urb; } @@ -820,25 +818,20 @@ static int mxu1_open(struct tty_struct *tty, struct usb_serial_port *port) status = mxu1_send_ctrl_urb(serial, MXU1_OPEN_PORT, open_settings, MXU1_UART1_PORT); if (status) { - dev_err(&port->dev, "%s - cannot send open command: %d\n", - __func__, status); + dev_err(&port->dev, "cannot send open command: %d\n", status); goto unlink_int_urb; } status = mxu1_send_ctrl_urb(serial, MXU1_START_PORT, 0, MXU1_UART1_PORT); if (status) { - dev_err(&port->dev, "%s - cannot send start command: %d\n", - __func__, status); + dev_err(&port->dev, "cannot send start command: %d\n", status); goto unlink_int_urb; } status = usb_serial_generic_open(tty, port); - if (status) { - dev_err(&port->dev, "%s - submit read urb failed: %d\n", - __func__, status); + if (status) goto unlink_int_urb; - } return 0; @@ -921,8 +914,7 @@ static void mxu1_interrupt_callback(struct urb *urb) } if (data[0] == MXU1_CODE_HARDWARE_ERROR) { - dev_err(&port->dev, "%s - hardware error: %d\n", - __func__, data[1]); + dev_err(&port->dev, "hardware error: %d\n", data[1]); goto exit; } @@ -943,8 +935,8 @@ static void mxu1_interrupt_callback(struct urb *urb) break; default: - dev_err(&port->dev, "%s - unknown interrupt code: 0x%02X\n", - __func__, data[1]); + dev_err(&port->dev, "unknown interrupt code: 0x%02X\n", + data[1]); break; } -- GitLab From 8cb708f3d35e78f00528caf2f681900d2c7883b8 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 20 Dec 2015 12:15:52 +0100 Subject: [PATCH 2121/2855] s390/cio: add NULL test Add NULL test on call to kzalloc. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression x; identifier fld; @@ * x = kzalloc(...); ... when != x == NULL x->fld // Signed-off-by: Julia Lawall Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/char/con3215.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 0fc3fe5fd5b81..7d82bbcb12df4 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -922,6 +922,8 @@ static int __init con3215_init(void) spin_lock_init(&raw3215_freelist_lock); for (i = 0; i < NR_3215_REQ; i++) { req = kzalloc(sizeof(struct raw3215_req), GFP_KERNEL | GFP_DMA); + if (!req) + return -ENOMEM; req->next = raw3215_freelist; raw3215_freelist = req; } -- GitLab From c967e1df169d033b2da74e979e91b6e297e194fa Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Sun, 13 Dec 2015 20:51:49 +0200 Subject: [PATCH 2122/2855] s390/hmcdrv: constify hmcdrv_ftp_ops structs Constifies hmcdrv_ftp_ops structures in s390's char driver since they are not modified after their initialization. Detected and found using Coccinelle. Suggested-by: Julia Lawall Signed-off-by: Aya Mahfouz Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/char/hmcdrv_ftp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/s390/char/hmcdrv_ftp.c b/drivers/s390/char/hmcdrv_ftp.c index d4b61d9088fb7..8cb7d8fbadd62 100644 --- a/drivers/s390/char/hmcdrv_ftp.c +++ b/drivers/s390/char/hmcdrv_ftp.c @@ -37,7 +37,7 @@ struct hmcdrv_ftp_ops { static enum hmcdrv_ftp_cmdid hmcdrv_ftp_cmd_getid(const char *cmd, int len); static int hmcdrv_ftp_parse(char *cmd, struct hmcdrv_ftp_cmdspec *ftp); -static struct hmcdrv_ftp_ops *hmcdrv_ftp_funcs; /* current operations */ +static const struct hmcdrv_ftp_ops *hmcdrv_ftp_funcs; /* current operations */ static DEFINE_MUTEX(hmcdrv_ftp_mutex); /* mutex for hmcdrv_ftp_funcs */ static unsigned hmcdrv_ftp_refcnt; /* start/shutdown reference counter */ @@ -290,13 +290,13 @@ ssize_t hmcdrv_ftp_cmd(char __kernel *cmd, loff_t offset, */ int hmcdrv_ftp_startup(void) { - static struct hmcdrv_ftp_ops hmcdrv_ftp_zvm = { + static const struct hmcdrv_ftp_ops hmcdrv_ftp_zvm = { .startup = diag_ftp_startup, .shutdown = diag_ftp_shutdown, .transfer = diag_ftp_cmd }; - static struct hmcdrv_ftp_ops hmcdrv_ftp_lpar = { + static const struct hmcdrv_ftp_ops hmcdrv_ftp_lpar = { .startup = sclp_ftp_startup, .shutdown = sclp_ftp_shutdown, .transfer = sclp_ftp_cmd -- GitLab From cf61393f4aa30f4c2a11cf2437d49ff4de6eb4fb Mon Sep 17 00:00:00 2001 From: Pierre Morel Date: Mon, 21 Dec 2015 15:31:06 +0100 Subject: [PATCH 2123/2855] s390/con3270: testing return kzalloc retval Return value from kzalloc is not tested and using a null pointer would lead to crash. Even if this should not happen at this moment, we may let the system decide if there is a better choice. Signed-off-by: Pierre Morel Signed-off-by: Martin Schwidefsky --- drivers/s390/char/con3270.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index 7c511add5aa7d..4d7a9badfedee 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -606,6 +606,8 @@ con3270_init(void) return PTR_ERR(rp); condev = kzalloc(sizeof(struct con3270), GFP_KERNEL | GFP_DMA); + if (!condev) + return -ENOMEM; condev->view.dev = rp; condev->read = raw3270_request_alloc(0); -- GitLab From c6fc7b6f8ca5d3d59446ce4ee870569355cfb04a Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Tue, 22 Dec 2015 13:34:38 +0100 Subject: [PATCH 2124/2855] s390/dasd: fix failfast for disconnected devices Enabling failfast should let request fail immediately if either an error occurred or the device gets disconnected. For disconnected devices new requests are not fetches from the block queue and therefore failfast is not triggered. Fix by letting the DASD driver fetch requests for disconnected devices with failfast active. Signed-off-by: Stefan Haberland Signed-off-by: Martin Schwidefsky --- drivers/s390/block/dasd.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index a263c10359e15..41605dac83094 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -2556,8 +2556,12 @@ static void __dasd_process_request_queue(struct dasd_block *block) return; } - /* if device ist stopped do not fetch new requests */ - if (basedev->stopped) + /* + * if device is stopped do not fetch new requests + * except failfast is active which will let requests fail + * immediately in __dasd_block_start_head() + */ + if (basedev->stopped && !(basedev->features & DASD_FEATURE_FAILFAST)) return; /* Now we try to fetch requests from the request queue */ -- GitLab From c095a94932ceee19fe36942aa49df7276f9e30b5 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 28 Dec 2015 12:53:51 +0100 Subject: [PATCH 2125/2855] s390/Kconfig: remove pointless 64 bit dependencies s390 is always 64 bit. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 3a55f493c7da7..d66a7c47faf30 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -166,8 +166,7 @@ config SCHED_OMIT_FRAME_POINTER config PGTABLE_LEVELS int - default 4 if 64BIT - default 2 + default 4 source "init/Kconfig" @@ -403,7 +402,7 @@ config NODES_SPAN_OTHER_NODES config NUMA bool "NUMA support" - depends on SMP && 64BIT && SCHED_TOPOLOGY + depends on SMP && SCHED_TOPOLOGY default n help Enable NUMA support -- GitLab From 9236b4dd6bfabefcf2063544083a66cd5f3a738d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 28 Dec 2015 13:20:43 +0100 Subject: [PATCH 2126/2855] s390: get rid of CONFIG_SCHED_MC and CONFIG_SCHED_BOOK Use CONFIG_TOPOLOGY which selects CONFIG_SCHED_* all over the place to reduce the random usage of the previous config options. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 6 +++--- arch/s390/include/asm/topology.h | 6 +++--- arch/s390/kernel/Makefile | 2 +- arch/s390/kernel/sysinfo.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index d66a7c47faf30..6d0ae7d307244 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -389,9 +389,6 @@ config HOTPLUG_CPU can be controlled through /sys/devices/system/cpu/cpu#. Say N if you want to disable CPU hotplug. -config SCHED_SMT - def_bool n - # Some NUMA nodes have memory ranges that span # other nodes. Even though a pfn is valid and # between a node's start and end pfns, it may not @@ -462,6 +459,9 @@ config EMU_SIZE endmenu +config SCHED_SMT + def_bool n + config SCHED_MC def_bool n diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h index 94fc55fc72ce8..6b53962e807e0 100644 --- a/arch/s390/include/asm/topology.h +++ b/arch/s390/include/asm/topology.h @@ -7,7 +7,7 @@ struct sysinfo_15_1_x; struct cpu; -#ifdef CONFIG_SCHED_BOOK +#ifdef CONFIG_SCHED_TOPOLOGY struct cpu_topology_s390 { unsigned short thread_id; @@ -40,13 +40,13 @@ void store_topology(struct sysinfo_15_1_x *info); void topology_expect_change(void); const struct cpumask *cpu_coregroup_mask(int cpu); -#else /* CONFIG_SCHED_BOOK */ +#else /* CONFIG_SCHED_TOPOLOGY */ static inline void topology_schedule_update(void) { } static inline int topology_cpu_init(struct cpu *cpu) { return 0; } static inline void topology_expect_change(void) { } -#endif /* CONFIG_SCHED_BOOK */ +#endif /* CONFIG_SCHED_TOPOLOGY */ #define POLARIZATION_UNKNOWN (-1) #define POLARIZATION_HRZ (0) diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index e9a328d426105..2f5586ab8a6ac 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -52,7 +52,7 @@ extra-y += head.o head64.o vmlinux.lds obj-$(CONFIG_MODULES) += s390_ksyms.o module.o obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_SCHED_BOOK) += topology.o +obj-$(CONFIG_SCHED_TOPOLOGY) += topology.o obj-$(CONFIG_HIBERNATION) += suspend.o swsusp.o obj-$(CONFIG_AUDIT) += audit.o compat-obj-$(CONFIG_AUDIT) += compat_audit.o diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c index efacda2fc5683..0512f944eaf3f 100644 --- a/arch/s390/kernel/sysinfo.c +++ b/arch/s390/kernel/sysinfo.c @@ -122,7 +122,7 @@ static void stsi_15_1_x(struct seq_file *m, struct sysinfo_15_1_x *info) for (i = 0; i < TOPOLOGY_NR_MAG; i++) seq_printf(m, " %d", info->mag[i]); seq_putc(m, '\n'); -#ifdef CONFIG_SCHED_MC +#ifdef CONFIG_SCHED_TOPOLOGY store_topology(info); seq_printf(m, "CPU Topology SW: "); for (i = 0; i < TOPOLOGY_NR_MAG; i++) -- GitLab From ade14a7df796d4e86bd9d181193c883a57b13db0 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 29 Dec 2015 18:55:19 -0500 Subject: [PATCH 2127/2855] NFS: Fix attribute cache revalidation If a NFSv4 client uses the cache_consistency_bitmask in order to request only information about the change attribute, timestamps and size, then it has not revalidated all attributes, and hence the attribute timeout timestamp should not be updated. Reported-by: Donald Buczek Cc: stable@vger.kernel.org Signed-off-by: Trond Myklebust --- fs/nfs/inode.c | 54 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index c7e8b87da5b24..3e2071a177fd0 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1641,6 +1641,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) unsigned long invalid = 0; unsigned long now = jiffies; unsigned long save_cache_validity; + bool cache_revalidated = true; dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n", __func__, inode->i_sb->s_id, inode->i_ino, @@ -1702,22 +1703,28 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) nfs_force_lookup_revalidate(inode); inode->i_version = fattr->change_attr; } - } else + } else { nfsi->cache_validity |= save_cache_validity; + cache_revalidated = false; + } if (fattr->valid & NFS_ATTR_FATTR_MTIME) { memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); - } else if (server->caps & NFS_CAP_MTIME) + } else if (server->caps & NFS_CAP_MTIME) { nfsi->cache_validity |= save_cache_validity & (NFS_INO_INVALID_ATTR | NFS_INO_REVAL_FORCED); + cache_revalidated = false; + } if (fattr->valid & NFS_ATTR_FATTR_CTIME) { memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); - } else if (server->caps & NFS_CAP_CTIME) + } else if (server->caps & NFS_CAP_CTIME) { nfsi->cache_validity |= save_cache_validity & (NFS_INO_INVALID_ATTR | NFS_INO_REVAL_FORCED); + cache_revalidated = false; + } /* Check if our cached file size is stale */ if (fattr->valid & NFS_ATTR_FATTR_SIZE) { @@ -1737,19 +1744,23 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) (long long)cur_isize, (long long)new_isize); } - } else + } else { nfsi->cache_validity |= save_cache_validity & (NFS_INO_INVALID_ATTR | NFS_INO_REVAL_PAGECACHE | NFS_INO_REVAL_FORCED); + cache_revalidated = false; + } if (fattr->valid & NFS_ATTR_FATTR_ATIME) memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); - else if (server->caps & NFS_CAP_ATIME) + else if (server->caps & NFS_CAP_ATIME) { nfsi->cache_validity |= save_cache_validity & (NFS_INO_INVALID_ATIME | NFS_INO_REVAL_FORCED); + cache_revalidated = false; + } if (fattr->valid & NFS_ATTR_FATTR_MODE) { if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) { @@ -1758,36 +1769,42 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) inode->i_mode = newmode; invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; } - } else if (server->caps & NFS_CAP_MODE) + } else if (server->caps & NFS_CAP_MODE) { nfsi->cache_validity |= save_cache_validity & (NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL | NFS_INO_REVAL_FORCED); + cache_revalidated = false; + } if (fattr->valid & NFS_ATTR_FATTR_OWNER) { if (!uid_eq(inode->i_uid, fattr->uid)) { invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; inode->i_uid = fattr->uid; } - } else if (server->caps & NFS_CAP_OWNER) + } else if (server->caps & NFS_CAP_OWNER) { nfsi->cache_validity |= save_cache_validity & (NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL | NFS_INO_REVAL_FORCED); + cache_revalidated = false; + } if (fattr->valid & NFS_ATTR_FATTR_GROUP) { if (!gid_eq(inode->i_gid, fattr->gid)) { invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; inode->i_gid = fattr->gid; } - } else if (server->caps & NFS_CAP_OWNER_GROUP) + } else if (server->caps & NFS_CAP_OWNER_GROUP) { nfsi->cache_validity |= save_cache_validity & (NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL | NFS_INO_REVAL_FORCED); + cache_revalidated = false; + } if (fattr->valid & NFS_ATTR_FATTR_NLINK) { if (inode->i_nlink != fattr->nlink) { @@ -1796,19 +1813,22 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) invalid |= NFS_INO_INVALID_DATA; set_nlink(inode, fattr->nlink); } - } else if (server->caps & NFS_CAP_NLINK) + } else if (server->caps & NFS_CAP_NLINK) { nfsi->cache_validity |= save_cache_validity & (NFS_INO_INVALID_ATTR | NFS_INO_REVAL_FORCED); + cache_revalidated = false; + } if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { /* * report the blocks in 512byte units */ inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used); - } - if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED) + } else if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED) inode->i_blocks = fattr->du.nfs2.blocks; + else + cache_revalidated = false; /* Update attrtimeo value if we're out of the unstable period */ if (invalid & NFS_INO_INVALID_ATTR) { @@ -1818,9 +1838,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) /* Set barrier to be more recent than all outstanding updates */ nfsi->attr_gencount = nfs_inc_attr_generation_counter(); } else { - if (!time_in_range_open(now, nfsi->attrtimeo_timestamp, nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) { - if ((nfsi->attrtimeo <<= 1) > NFS_MAXATTRTIMEO(inode)) - nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode); + if (cache_revalidated) { + if (!time_in_range_open(now, nfsi->attrtimeo_timestamp, + nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) { + nfsi->attrtimeo <<= 1; + if (nfsi->attrtimeo > NFS_MAXATTRTIMEO(inode)) + nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode); + } nfsi->attrtimeo_timestamp = now; } /* Set the barrier to be more recent than this fattr */ @@ -1829,7 +1853,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) } /* Don't declare attrcache up to date if there were no attrs! */ - if (fattr->valid != 0) + if (cache_revalidated) invalid &= ~NFS_INO_INVALID_ATTR; /* Don't invalidate the data if we were to blame */ -- GitLab From 86fb449b07b8215443a30782dca5755d5b8b0577 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 30 Dec 2015 10:57:01 -0500 Subject: [PATCH 2128/2855] pNFS/flexfiles: Fix an Oopsable typo in ff_mirror_match_fh() Jeff reports seeing an Oops in ff_layout_alloc_lseg. Turns out copy+paste has played cruel tricks on a nested loop. Reported-by: Jeff Layton Cc: stable@vger.kernel.org # 4.3+ Signed-off-by: Trond Myklebust --- fs/nfs/flexfilelayout/flexfilelayout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index 03516c80855a0..405f46ba490e5 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -145,7 +145,7 @@ static bool ff_mirror_match_fh(const struct nfs4_ff_layout_mirror *m1, return false; for (i = 0; i < m1->fh_versions_cnt; i++) { bool found_fh = false; - for (j = 0; j < m2->fh_versions_cnt; i++) { + for (j = 0; j < m2->fh_versions_cnt; j++) { if (nfs_compare_fh(&m1->fh_versions[i], &m2->fh_versions[j]) == 0) { found_fh = true; -- GitLab From cc023478dc8a3ab07828620dd80303fcd81fb227 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Tue, 29 Dec 2015 18:34:40 +0100 Subject: [PATCH 2129/2855] spi: s3c64xx: Remove unused platform_device_id entries s5pv210 and exynos4 are now DT only platforms hence these entries can now be safely removed from the match table. Signed-off-by: Sylwester Nawrocki Signed-off-by: Mark Brown --- drivers/spi/spi-s3c64xx.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index b954c5444cca5..5a76a50063b56 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -1357,12 +1357,6 @@ static const struct platform_device_id s3c64xx_spi_driver_ids[] = { }, { .name = "s3c6410-spi", .driver_data = (kernel_ulong_t)&s3c6410_spi_port_config, - }, { - .name = "s5pv210-spi", - .driver_data = (kernel_ulong_t)&s5pv210_spi_port_config, - }, { - .name = "exynos4210-spi", - .driver_data = (kernel_ulong_t)&exynos4_spi_port_config, }, { }, }; -- GitLab From de327e4966cdbad2b7053c84a6f591fbdc54f7cb Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Sun, 27 Dec 2015 18:17:06 +0800 Subject: [PATCH 2130/2855] spi: mediatek: Prevent overflows in FIFO transfers In the case where transfer length is not a multiple of 4, KASAN reports 2 out-of-bounds memory accesses: - mtk_spi_interrupt: ioread32_rep writes past the end of trans->rx_buf. - mtk_spi_fifo_transfer: iowrite32_rep reads past the end of xfer->tx_buf. Fix this by using memcpy on the remainder of the bytes. Signed-off-by: Nicolas Boichat Signed-off-by: Mark Brown --- drivers/spi/spi-mt65xx.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index 563954a614242..375d412dbf052 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c @@ -323,7 +323,8 @@ static int mtk_spi_fifo_transfer(struct spi_master *master, struct spi_device *spi, struct spi_transfer *xfer) { - int cnt; + int cnt, remainder; + u32 reg_val; struct mtk_spi *mdata = spi_master_get_devdata(master); mdata->cur_transfer = xfer; @@ -331,12 +332,16 @@ static int mtk_spi_fifo_transfer(struct spi_master *master, mtk_spi_prepare_transfer(master, xfer); mtk_spi_setup_packet(master); - if (xfer->len % 4) - cnt = xfer->len / 4 + 1; - else - cnt = xfer->len / 4; + cnt = xfer->len / 4; iowrite32_rep(mdata->base + SPI_TX_DATA_REG, xfer->tx_buf, cnt); + remainder = xfer->len % 4; + if (remainder > 0) { + reg_val = 0; + memcpy(®_val, xfer->tx_buf + (cnt * 4), remainder); + writel(reg_val, mdata->base + SPI_TX_DATA_REG); + } + mtk_spi_enable_transfer(master); return 1; @@ -418,7 +423,7 @@ static int mtk_spi_setup(struct spi_device *spi) static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id) { - u32 cmd, reg_val, cnt; + u32 cmd, reg_val, cnt, remainder; struct spi_master *master = dev_id; struct mtk_spi *mdata = spi_master_get_devdata(master); struct spi_transfer *trans = mdata->cur_transfer; @@ -431,12 +436,15 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id) if (!master->can_dma(master, master->cur_msg->spi, trans)) { if (trans->rx_buf) { - if (mdata->xfer_len % 4) - cnt = mdata->xfer_len / 4 + 1; - else - cnt = mdata->xfer_len / 4; + cnt = mdata->xfer_len / 4; ioread32_rep(mdata->base + SPI_RX_DATA_REG, trans->rx_buf, cnt); + remainder = mdata->xfer_len % 4; + if (remainder > 0) { + reg_val = readl(mdata->base + SPI_RX_DATA_REG); + memcpy(trans->rx_buf + (cnt * 4), + ®_val, remainder); + } } spi_finalize_current_transfer(master); return IRQ_HANDLED; -- GitLab From 74fd8d9927ef08db30a85f131a124152aeba66c7 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 21 Dec 2015 19:25:50 -0800 Subject: [PATCH 2131/2855] f2fs: speed up shrinking extent tree entries If there is no candidates for shrinking slab entries, we don't need to traverse any trees at all. Reviewed-by: Chao Yu [Jaegeuk Kim: fix missing initialization reported by Yunlei He] Signed-off-by: Jaegeuk Kim --- fs/f2fs/extent_cache.c | 14 ++++++++++++++ fs/f2fs/f2fs.h | 1 + fs/f2fs/shrinker.c | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index 0e97d6af98858..5305a29f91a33 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -71,6 +71,8 @@ static struct extent_tree *__grab_extent_tree(struct inode *inode) atomic_set(&et->refcount, 0); et->count = 0; atomic_inc(&sbi->total_ext_tree); + } else { + atomic_dec(&sbi->total_zombie_tree); } atomic_inc(&et->refcount); up_write(&sbi->extent_tree_lock); @@ -547,10 +549,14 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) unsigned int found; unsigned int node_cnt = 0, tree_cnt = 0; int remained; + bool do_free = false; if (!test_opt(sbi, EXTENT_CACHE)) return 0; + if (!atomic_read(&sbi->total_zombie_tree)) + goto free_node; + if (!down_write_trylock(&sbi->extent_tree_lock)) goto out; @@ -571,6 +577,7 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) radix_tree_delete(root, et->ino); kmem_cache_free(extent_tree_slab, et); atomic_dec(&sbi->total_ext_tree); + atomic_dec(&sbi->total_zombie_tree); tree_cnt++; if (node_cnt + tree_cnt >= nr_shrink) @@ -580,6 +587,7 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) } up_write(&sbi->extent_tree_lock); +free_node: /* 2. remove LRU extent entries */ if (!down_write_trylock(&sbi->extent_tree_lock)) goto out; @@ -591,9 +599,13 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) if (!remained--) break; list_del_init(&en->list); + do_free = true; } spin_unlock(&sbi->extent_lock); + if (do_free == false) + goto unlock_out; + /* * reset ino for searching victims from beginning of global extent tree. */ @@ -651,6 +663,7 @@ void f2fs_destroy_extent_tree(struct inode *inode) if (inode->i_nlink && !is_bad_inode(inode) && et->count) { atomic_dec(&et->refcount); + atomic_inc(&sbi->total_zombie_tree); return; } @@ -716,6 +729,7 @@ void init_extent_cache_info(struct f2fs_sb_info *sbi) INIT_LIST_HEAD(&sbi->extent_list); spin_lock_init(&sbi->extent_lock); atomic_set(&sbi->total_ext_tree, 0); + atomic_set(&sbi->total_zombie_tree, 0); atomic_set(&sbi->total_ext_node, 0); } diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index a7f619182cece..90fb970e2b98d 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -763,6 +763,7 @@ struct f2fs_sb_info { struct list_head extent_list; /* lru list for shrinker */ spinlock_t extent_lock; /* locking extent lru list */ atomic_t total_ext_tree; /* extent tree count */ + atomic_t total_zombie_tree; /* extent zombie tree count */ atomic_t total_ext_node; /* extent info count */ /* basic filesystem units */ diff --git a/fs/f2fs/shrinker.c b/fs/f2fs/shrinker.c index a11e099cbddc6..93606f281bf9c 100644 --- a/fs/f2fs/shrinker.c +++ b/fs/f2fs/shrinker.c @@ -32,7 +32,7 @@ static unsigned long __count_free_nids(struct f2fs_sb_info *sbi) static unsigned long __count_extent_cache(struct f2fs_sb_info *sbi) { - return atomic_read(&sbi->total_ext_tree) + + return atomic_read(&sbi->total_zombie_tree) + atomic_read(&sbi->total_ext_node); } -- GitLab From b9d777b85ff1ff79a1173190317b25bebc404ab4 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 22 Dec 2015 11:09:35 -0800 Subject: [PATCH 2132/2855] f2fs: check inline_data flag at converting time We can check inode's inline_data flag when calling to convert it. Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 8 +++---- fs/f2fs/file.c | 58 +++++++++++++++++++----------------------------- fs/f2fs/inline.c | 3 +++ 3 files changed, 29 insertions(+), 40 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index e34b1bdfc9955..cf0c9dda0365c 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1573,11 +1573,9 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int err; /* we don't need to use inline_data strictly */ - if (f2fs_has_inline_data(inode)) { - err = f2fs_convert_inline_inode(inode); - if (err) - return err; - } + err = f2fs_convert_inline_inode(inode); + if (err) + return err; if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) return 0; diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 7f8ca47be0afd..f2effe18d3c5b 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -418,19 +418,18 @@ static loff_t f2fs_llseek(struct file *file, loff_t offset, int whence) static int f2fs_file_mmap(struct file *file, struct vm_area_struct *vma) { struct inode *inode = file_inode(file); + int err; if (f2fs_encrypted_inode(inode)) { - int err = f2fs_get_encryption_info(inode); + err = f2fs_get_encryption_info(inode); if (err) return 0; } /* we don't need to use inline_data strictly */ - if (f2fs_has_inline_data(inode)) { - int err = f2fs_convert_inline_inode(inode); - if (err) - return err; - } + err = f2fs_convert_inline_inode(inode); + if (err) + return err; file_accessed(file); vma->vm_ops = &f2fs_file_vm_ops; @@ -604,7 +603,7 @@ int f2fs_truncate(struct inode *inode, bool lock) trace_f2fs_truncate(inode); /* we should check inline_data size */ - if (f2fs_has_inline_data(inode) && !f2fs_may_inline_data(inode)) { + if (!f2fs_may_inline_data(inode)) { err = f2fs_convert_inline_inode(inode); if (err) return err; @@ -688,8 +687,7 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr) truncate_setsize(inode, attr->ia_size); /* should convert inline inode here */ - if (f2fs_has_inline_data(inode) && - !f2fs_may_inline_data(inode)) { + if (!f2fs_may_inline_data(inode)) { err = f2fs_convert_inline_inode(inode); if (err) return err; @@ -786,13 +784,11 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len) { pgoff_t pg_start, pg_end; loff_t off_start, off_end; - int ret = 0; + int ret; - if (f2fs_has_inline_data(inode)) { - ret = f2fs_convert_inline_inode(inode); - if (ret) - return ret; - } + ret = f2fs_convert_inline_inode(inode); + if (ret) + return ret; pg_start = ((unsigned long long) offset) >> PAGE_CACHE_SHIFT; pg_end = ((unsigned long long) offset + len) >> PAGE_CACHE_SHIFT; @@ -951,11 +947,9 @@ static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len) f2fs_balance_fs(F2FS_I_SB(inode)); - if (f2fs_has_inline_data(inode)) { - ret = f2fs_convert_inline_inode(inode); - if (ret) - return ret; - } + ret = f2fs_convert_inline_inode(inode); + if (ret) + return ret; pg_start = offset >> PAGE_CACHE_SHIFT; pg_end = (offset + len) >> PAGE_CACHE_SHIFT; @@ -1001,11 +995,9 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len, f2fs_balance_fs(sbi); - if (f2fs_has_inline_data(inode)) { - ret = f2fs_convert_inline_inode(inode); - if (ret) - return ret; - } + ret = f2fs_convert_inline_inode(inode); + if (ret) + return ret; ret = filemap_write_and_wait_range(mapping, offset, offset + len - 1); if (ret) @@ -1114,11 +1106,9 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len) f2fs_balance_fs(sbi); - if (f2fs_has_inline_data(inode)) { - ret = f2fs_convert_inline_inode(inode); - if (ret) - return ret; - } + ret = f2fs_convert_inline_inode(inode); + if (ret) + return ret; ret = truncate_blocks(inode, i_size_read(inode), true); if (ret) @@ -1168,11 +1158,9 @@ static int expand_inode_data(struct inode *inode, loff_t offset, if (ret) return ret; - if (f2fs_has_inline_data(inode)) { - ret = f2fs_convert_inline_inode(inode); - if (ret) - return ret; - } + ret = f2fs_convert_inline_inode(inode); + if (ret) + return ret; pg_start = ((unsigned long long) offset) >> PAGE_CACHE_SHIFT; pg_end = ((unsigned long long) offset + len) >> PAGE_CACHE_SHIFT; diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index bda7126466c09..8090854dd29ce 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -177,6 +177,9 @@ int f2fs_convert_inline_inode(struct inode *inode) struct page *ipage, *page; int err = 0; + if (!f2fs_has_inline_data(inode)) + return 0; + page = grab_cache_page(inode->i_mapping, 0); if (!page) return -ENOMEM; -- GitLab From 00623e6bcf40b03b39f612cef9a744453cf3e2a8 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 22 Dec 2015 11:56:08 -0800 Subject: [PATCH 2133/2855] f2fs: avoid unnecessary f2fs_gc for dir operations The f2fs_balance_fs doesn't need to cover f2fs_new_inode or f2fs_find_entry works. Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/namei.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 2c32110f9fc08..4e27c5c4b05cb 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -128,8 +128,6 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode, nid_t ino = 0; int err; - f2fs_balance_fs(sbi); - inode = f2fs_new_inode(dir, mode); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -142,6 +140,8 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode, inode->i_mapping->a_ops = &f2fs_dblock_aops; ino = inode->i_ino; + f2fs_balance_fs(sbi); + f2fs_lock_op(sbi); err = f2fs_add_link(dentry, inode); if (err) @@ -288,12 +288,13 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) int err = -ENOENT; trace_f2fs_unlink_enter(dir, dentry); - f2fs_balance_fs(sbi); de = f2fs_find_entry(dir, &dentry->d_name, &page); if (!de) goto fail; + f2fs_balance_fs(sbi); + f2fs_lock_op(sbi); err = acquire_orphan_inode(sbi); if (err) { @@ -341,8 +342,6 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, if (len > dir->i_sb->s_blocksize) return -ENAMETOOLONG; - f2fs_balance_fs(sbi); - inode = f2fs_new_inode(dir, S_IFLNK | S_IRWXUGO); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -353,6 +352,8 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, inode->i_op = &f2fs_symlink_inode_operations; inode->i_mapping->a_ops = &f2fs_dblock_aops; + f2fs_balance_fs(sbi); + f2fs_lock_op(sbi); err = f2fs_add_link(dentry, inode); if (err) @@ -433,8 +434,6 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) struct inode *inode; int err; - f2fs_balance_fs(sbi); - inode = f2fs_new_inode(dir, S_IFDIR | mode); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -444,6 +443,8 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) inode->i_mapping->a_ops = &f2fs_dblock_aops; mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_HIGH_ZERO); + f2fs_balance_fs(sbi); + set_inode_flag(F2FS_I(inode), FI_INC_LINK); f2fs_lock_op(sbi); err = f2fs_add_link(dentry, inode); @@ -481,8 +482,6 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry, struct inode *inode; int err = 0; - f2fs_balance_fs(sbi); - inode = f2fs_new_inode(dir, mode); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -490,6 +489,8 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry, init_special_inode(inode, inode->i_mode, rdev); inode->i_op = &f2fs_special_inode_operations; + f2fs_balance_fs(sbi); + f2fs_lock_op(sbi); err = f2fs_add_link(dentry, inode); if (err) @@ -516,9 +517,6 @@ static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry, struct inode *inode; int err; - if (!whiteout) - f2fs_balance_fs(sbi); - inode = f2fs_new_inode(dir, mode); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -532,6 +530,8 @@ static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry, inode->i_mapping->a_ops = &f2fs_dblock_aops; } + f2fs_balance_fs(sbi); + f2fs_lock_op(sbi); err = acquire_orphan_inode(sbi); if (err) @@ -604,8 +604,6 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, goto out; } - f2fs_balance_fs(sbi); - old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page); if (!old_entry) goto out; @@ -635,6 +633,8 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, if (!new_entry) goto out_whiteout; + f2fs_balance_fs(sbi); + f2fs_lock_op(sbi); err = acquire_orphan_inode(sbi); @@ -666,6 +666,8 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, update_inode_page(old_inode); update_inode_page(new_inode); } else { + f2fs_balance_fs(sbi); + f2fs_lock_op(sbi); err = f2fs_add_link(new_dentry, old_inode); @@ -763,8 +765,6 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry, new_inode))) return -EPERM; - f2fs_balance_fs(sbi); - old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page); if (!old_entry) goto out; @@ -807,6 +807,8 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry, goto out_new_dir; } + f2fs_balance_fs(sbi); + f2fs_lock_op(sbi); err = update_dent_inode(old_inode, new_inode, &new_dentry->d_name); -- GitLab From 93bae099eaa0ae784fbe4d9eddcdc54fb5812466 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 22 Dec 2015 12:59:54 -0800 Subject: [PATCH 2134/2855] f2fs: record node block allocation in dnode_of_data This patch introduces recording node block allocation in dnode_of_data. This information helps to figure out whether any node block is allocated during specific file operations. Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 1 + fs/f2fs/f2fs.h | 1 + fs/f2fs/node.c | 5 +++++ 3 files changed, 7 insertions(+) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index cf0c9dda0365c..a7a9a05d012a6 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -226,6 +226,7 @@ void set_data_blkaddr(struct dnode_of_data *dn) addr_array = blkaddr_in_node(rn); addr_array[ofs_in_node] = cpu_to_le32(dn->data_blkaddr); set_page_dirty(node_page); + dn->node_changed = true; } int reserve_new_block(struct dnode_of_data *dn) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 90fb970e2b98d..3e4a60da408f5 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -546,6 +546,7 @@ struct dnode_of_data { nid_t nid; /* node id of the direct node block */ unsigned int ofs_in_node; /* data offset in the node page */ bool inode_page_locked; /* inode page is locked or not */ + bool node_changed; /* is node block changed */ block_t data_blkaddr; /* block address of the node block */ }; diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 6cc8ac7e185a2..341de5d2353b3 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -542,6 +542,7 @@ int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode) set_nid(parent, offset[i - 1], nids[i], i == 1); alloc_nid_done(sbi, nids[i]); + dn->node_changed = true; done = true; } else if (mode == LOOKUP_NODE_RA && i == level && level > 1) { npage[i] = get_node_page_ra(parent, offset[i - 1]); @@ -678,6 +679,7 @@ static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs, if (ret < 0) goto out_err; set_nid(page, i, 0, false); + dn->node_changed = true; } } else { child_nofs = nofs + ofs * (NIDS_PER_BLOCK + 1) + 1; @@ -691,6 +693,7 @@ static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs, ret = truncate_nodes(&rdn, child_nofs, 0, depth - 1); if (ret == (NIDS_PER_BLOCK + 1)) { set_nid(page, i, 0, false); + dn->node_changed = true; child_nofs += ret; } else if (ret < 0 && ret != -ENOENT) { goto out_err; @@ -752,6 +755,7 @@ static int truncate_partial_nodes(struct dnode_of_data *dn, if (err < 0) goto fail; set_nid(pages[idx], i, 0, false); + dn->node_changed = true; } if (offset[idx + 1] == 0) { @@ -1153,6 +1157,7 @@ void sync_inode_page(struct dnode_of_data *dn) } else { update_inode_page(dn->inode); } + dn->node_changed = true; } int sync_node_pages(struct f2fs_sb_info *sbi, nid_t ino, -- GitLab From 3104af35eb6a2452ccc9912997e7728777100de2 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 23 Dec 2015 17:11:43 +0800 Subject: [PATCH 2135/2855] f2fs: reduce covered region of sbi->cp_rwsem in f2fs_map_blocks Only cover sbi->cp_rwsem on one dnode page's allocation and modification instead of multiple's in f2fs_map_blocks, it can reduce the covered region of cp_rwsem, then we can avoid potential long time delay for concurrent checkpointer. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index a7a9a05d012a6..82ecaa30fd772 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -590,7 +590,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, } if (create) - f2fs_lock_op(F2FS_I_SB(inode)); + f2fs_lock_op(sbi); /* When reading holes, we need its node page */ set_new_dnode(&dn, inode, NULL, NULL, 0); @@ -647,6 +647,11 @@ get_next: allocated = false; f2fs_put_dnode(&dn); + if (create) { + f2fs_unlock_op(sbi); + f2fs_lock_op(sbi); + } + set_new_dnode(&dn, inode, NULL, NULL, 0); err = get_dnode_of_data(&dn, pgofs, mode); if (err) { @@ -702,7 +707,7 @@ put_out: f2fs_put_dnode(&dn); unlock_out: if (create) - f2fs_unlock_op(F2FS_I_SB(inode)); + f2fs_unlock_op(sbi); out: trace_f2fs_map_blocks(inode, map, err); return err; -- GitLab From 2a3407607028f7c780f1c20faa4e922bf631d340 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 22 Dec 2015 13:23:35 -0800 Subject: [PATCH 2136/2855] f2fs: call f2fs_balance_fs only when node was changed If user tries to update or read data, we don't need to call f2fs_balance_fs which triggers f2fs_gc, which increases unnecessary long latency. Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 26 ++++++++++++++++++++++---- fs/f2fs/file.c | 26 +++++++++----------------- fs/f2fs/inline.c | 4 ++++ 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 82ecaa30fd772..958d8261b258a 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -509,7 +509,6 @@ static void __allocate_data_blocks(struct inode *inode, loff_t offset, u64 end_offset; while (len) { - f2fs_balance_fs(sbi); f2fs_lock_op(sbi); /* When reading holes, we need its node page */ @@ -542,6 +541,9 @@ static void __allocate_data_blocks(struct inode *inode, loff_t offset, f2fs_put_dnode(&dn); f2fs_unlock_op(sbi); + + if (dn.node_changed) + f2fs_balance_fs(sbi); } return; @@ -551,6 +553,8 @@ sync_out: f2fs_put_dnode(&dn); out: f2fs_unlock_op(sbi); + if (dn.node_changed) + f2fs_balance_fs(sbi); return; } @@ -649,6 +653,8 @@ get_next: if (create) { f2fs_unlock_op(sbi); + if (dn.node_changed) + f2fs_balance_fs(sbi); f2fs_lock_op(sbi); } @@ -706,8 +712,11 @@ sync_out: put_out: f2fs_put_dnode(&dn); unlock_out: - if (create) + if (create) { f2fs_unlock_op(sbi); + if (dn.node_changed) + f2fs_balance_fs(sbi); + } out: trace_f2fs_map_blocks(inode, map, err); return err; @@ -1415,8 +1424,6 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, trace_f2fs_write_begin(inode, pos, len, flags); - f2fs_balance_fs(sbi); - /* * We should check this at this moment to avoid deadlock on inode page * and #0 page. The locking rule for inline_data conversion should be: @@ -1466,6 +1473,17 @@ put_next: f2fs_put_dnode(&dn); f2fs_unlock_op(sbi); + if (dn.node_changed && has_not_enough_free_secs(sbi, 0)) { + unlock_page(page); + f2fs_balance_fs(sbi); + lock_page(page); + if (page->mapping != mapping) { + /* The page got truncated from under us */ + f2fs_put_page(page, 1); + goto repeat; + } + } + f2fs_wait_on_page_writeback(page, DATA); /* wait for GCed encrypted page writeback */ diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index f2effe18d3c5b..888ce47657790 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -40,8 +40,6 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, struct dnode_of_data dn; int err; - f2fs_balance_fs(sbi); - sb_start_pagefault(inode->i_sb); f2fs_bug_on(sbi, f2fs_has_inline_data(inode)); @@ -57,6 +55,9 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, f2fs_put_dnode(&dn); f2fs_unlock_op(sbi); + if (dn.node_changed) + f2fs_balance_fs(sbi); + file_update_time(vma->vm_file); lock_page(page); if (unlikely(page->mapping != inode->i_mapping || @@ -233,9 +234,6 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) goto out; } go_write: - /* guarantee free sections for fsync */ - f2fs_balance_fs(sbi); - /* * Both of fdatasync() and fsync() are able to be recovered from * sudden-power-off. @@ -267,6 +265,8 @@ sync_nodes: if (need_inode_block_update(sbi, ino)) { mark_inode_dirty_sync(inode); f2fs_write_inode(inode, NULL); + + f2fs_balance_fs(sbi); goto sync_nodes; } @@ -945,8 +945,6 @@ static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len) if (offset & (F2FS_BLKSIZE - 1) || len & (F2FS_BLKSIZE - 1)) return -EINVAL; - f2fs_balance_fs(F2FS_I_SB(inode)); - ret = f2fs_convert_inline_inode(inode); if (ret) return ret; @@ -993,8 +991,6 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len, if (ret) return ret; - f2fs_balance_fs(sbi); - ret = f2fs_convert_inline_inode(inode); if (ret) return ret; @@ -1104,12 +1100,12 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len) if (offset & (F2FS_BLKSIZE - 1) || len & (F2FS_BLKSIZE - 1)) return -EINVAL; - f2fs_balance_fs(sbi); - ret = f2fs_convert_inline_inode(inode); if (ret) return ret; + f2fs_balance_fs(sbi); + ret = truncate_blocks(inode, i_size_read(inode), true); if (ret) return ret; @@ -1152,8 +1148,6 @@ static int expand_inode_data(struct inode *inode, loff_t offset, loff_t off_start, off_end; int ret = 0; - f2fs_balance_fs(sbi); - ret = inode_newsize_ok(inode, (len + offset)); if (ret) return ret; @@ -1162,6 +1156,8 @@ static int expand_inode_data(struct inode *inode, loff_t offset, if (ret) return ret; + f2fs_balance_fs(sbi); + pg_start = ((unsigned long long) offset) >> PAGE_CACHE_SHIFT; pg_end = ((unsigned long long) offset + len) >> PAGE_CACHE_SHIFT; @@ -1349,8 +1345,6 @@ static int f2fs_ioc_start_atomic_write(struct file *filp) if (!inode_owner_or_capable(inode)) return -EACCES; - f2fs_balance_fs(F2FS_I_SB(inode)); - if (f2fs_is_atomic_file(inode)) return 0; @@ -1437,8 +1431,6 @@ static int f2fs_ioc_abort_volatile_write(struct file *filp) if (ret) return ret; - f2fs_balance_fs(F2FS_I_SB(inode)); - clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); clear_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); commit_inmem_pages(inode, true); diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 8090854dd29ce..c24e5d93720d4 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -202,6 +202,10 @@ out: f2fs_unlock_op(sbi); f2fs_put_page(page, 1); + + if (dn.node_changed) + f2fs_balance_fs(sbi); + return err; } -- GitLab From c34f42e2cb2d27650549306de5ff36839e9177d6 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 23 Dec 2015 17:50:30 +0800 Subject: [PATCH 2137/2855] f2fs: report error of do_checkpoint do_checkpoint and write_checkpoint can fail due to reasons like triggering in a readonly fs or encountering IO error of storage device. So it's better to report such error info to user, let user be aware of failure of doing checkpoint. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 29 +++++++++++++++++++---------- fs/f2fs/f2fs.h | 2 +- fs/f2fs/file.c | 5 +++-- fs/f2fs/recovery.c | 2 +- fs/f2fs/segment.c | 5 +++-- fs/f2fs/super.c | 5 +++-- 6 files changed, 30 insertions(+), 18 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index fdd43f71d2c6c..9cdb161973518 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -910,7 +910,7 @@ static void wait_on_all_pages_writeback(struct f2fs_sb_info *sbi) finish_wait(&sbi->cp_wait, &wait); } -static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) +static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) { struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_WARM_NODE); @@ -936,7 +936,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) while (get_pages(sbi, F2FS_DIRTY_META)) { sync_meta_pages(sbi, META, LONG_MAX); if (unlikely(f2fs_cp_error(sbi))) - return; + return -EIO; } next_free_nid(sbi, &last_nid); @@ -1021,7 +1021,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) /* need to wait for end_io results */ wait_on_all_pages_writeback(sbi); if (unlikely(f2fs_cp_error(sbi))) - return; + return -EIO; /* write out checkpoint buffer at block 0 */ update_meta_page(sbi, ckpt, start_blk++); @@ -1049,7 +1049,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) wait_on_all_pages_writeback(sbi); if (unlikely(f2fs_cp_error(sbi))) - return; + return -EIO; filemap_fdatawait_range(NODE_MAPPING(sbi), 0, LONG_MAX); filemap_fdatawait_range(META_MAPPING(sbi), 0, LONG_MAX); @@ -1075,19 +1075,22 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) release_ino_entry(sbi); if (unlikely(f2fs_cp_error(sbi))) - return; + return -EIO; clear_prefree_segments(sbi, cpc); clear_sbi_flag(sbi, SBI_IS_DIRTY); + + return 0; } /* * We guarantee that this checkpoint procedure will not fail. */ -void write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) +int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) { struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); unsigned long long ckpt_ver; + int err = 0; mutex_lock(&sbi->cp_mutex); @@ -1095,14 +1098,19 @@ void write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) (cpc->reason == CP_FASTBOOT || cpc->reason == CP_SYNC || (cpc->reason == CP_DISCARD && !sbi->discard_blks))) goto out; - if (unlikely(f2fs_cp_error(sbi))) + if (unlikely(f2fs_cp_error(sbi))) { + err = -EIO; goto out; - if (f2fs_readonly(sbi->sb)) + } + if (f2fs_readonly(sbi->sb)) { + err = -EROFS; goto out; + } trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "start block_ops"); - if (block_operations(sbi)) + err = block_operations(sbi); + if (err) goto out; trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish block_ops"); @@ -1124,7 +1132,7 @@ void write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) flush_sit_entries(sbi, cpc); /* unlock all the fs_lock[] in do_checkpoint() */ - do_checkpoint(sbi, cpc); + err = do_checkpoint(sbi, cpc); unblock_operations(sbi); stat_inc_cp_count(sbi->stat_info); @@ -1138,6 +1146,7 @@ void write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint"); out: mutex_unlock(&sbi->cp_mutex); + return err; } void init_ino_entry_info(struct f2fs_sb_info *sbi) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 3e4a60da408f5..79345e7ce6bb8 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1838,7 +1838,7 @@ void update_dirty_page(struct inode *, struct page *); void add_dirty_dir_inode(struct inode *); void remove_dirty_inode(struct inode *); void sync_dirty_inodes(struct f2fs_sb_info *, enum inode_type); -void write_checkpoint(struct f2fs_sb_info *, struct cp_control *); +int write_checkpoint(struct f2fs_sb_info *, struct cp_control *); void init_ino_entry_info(struct f2fs_sb_info *); int __init create_checkpoint_caches(void); void destroy_checkpoint_caches(void); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 888ce47657790..780db8bd2451e 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1618,6 +1618,7 @@ static int f2fs_ioc_write_checkpoint(struct file *filp, unsigned long arg) struct inode *inode = file_inode(filp); struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct cp_control cpc; + int err; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -1628,10 +1629,10 @@ static int f2fs_ioc_write_checkpoint(struct file *filp, unsigned long arg) cpc.reason = __get_cp_reason(sbi); mutex_lock(&sbi->gc_mutex); - write_checkpoint(sbi, &cpc); + err = write_checkpoint(sbi, &cpc); mutex_unlock(&sbi->gc_mutex); - return 0; + return err; } static int f2fs_defragment_range(struct f2fs_sb_info *sbi, diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 7fcb6e49defff..589b20b8677b8 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -623,7 +623,7 @@ out: .reason = CP_RECOVERY, }; mutex_unlock(&sbi->cp_mutex); - write_checkpoint(sbi, &cpc); + err = write_checkpoint(sbi, &cpc); } else { mutex_unlock(&sbi->cp_mutex); } diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index c2474509e5de5..a3474bad57702 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -1118,6 +1118,7 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) __u64 end = start + F2FS_BYTES_TO_BLK(range->len) - 1; unsigned int start_segno, end_segno; struct cp_control cpc; + int err = 0; if (start >= MAX_BLKADDR(sbi) || range->len < sbi->blocksize) return -EINVAL; @@ -1148,12 +1149,12 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) sbi->segs_per_sec) - 1, end_segno); mutex_lock(&sbi->gc_mutex); - write_checkpoint(sbi, &cpc); + err = write_checkpoint(sbi, &cpc); mutex_unlock(&sbi->gc_mutex); } out: range->len = F2FS_BLK_TO_BYTES(cpc.trimmed); - return 0; + return err; } static bool __has_curseg_space(struct f2fs_sb_info *sbi, int type) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index c3070c149c0ec..597b533634e00 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -579,6 +579,7 @@ static void f2fs_put_super(struct super_block *sb) int f2fs_sync_fs(struct super_block *sb, int sync) { struct f2fs_sb_info *sbi = F2FS_SB(sb); + int err = 0; trace_f2fs_sync_fs(sb, sync); @@ -588,14 +589,14 @@ int f2fs_sync_fs(struct super_block *sb, int sync) cpc.reason = __get_cp_reason(sbi); mutex_lock(&sbi->gc_mutex); - write_checkpoint(sbi, &cpc); + err = write_checkpoint(sbi, &cpc); mutex_unlock(&sbi->gc_mutex); } else { f2fs_balance_fs(sbi); } f2fs_trace_ios(NULL, 1); - return 0; + return err; } static int f2fs_freeze(struct super_block *sb) -- GitLab From fba48a8b14f405afc5c80a93ed64a12607dd52c4 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 23 Dec 2015 17:51:35 +0800 Subject: [PATCH 2138/2855] f2fs: don't convert inline inode when inline_data option is disable If inline_data option is disable, when truncating an inline inode with size which is not exceed maxinum inline size, we should not convert inline inode to regular one to avoid the overhead of synchronizing conversion. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/inline.c | 3 --- fs/f2fs/namei.c | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index c24e5d93720d4..5ffbd169b719a 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -16,9 +16,6 @@ bool f2fs_may_inline_data(struct inode *inode) { - if (!test_opt(F2FS_I_SB(inode), INLINE_DATA)) - return false; - if (f2fs_is_atomic_file(inode)) return false; diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 4e27c5c4b05cb..e439f32d31e6e 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -60,7 +60,7 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode) if (f2fs_encrypted_inode(dir) && f2fs_may_encrypt(inode)) f2fs_set_encrypted_inode(inode); - if (f2fs_may_inline_data(inode)) + if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode)) set_inode_flag(F2FS_I(inode), FI_INLINE_DATA); if (f2fs_may_inline_dentry(inode)) set_inode_flag(F2FS_I(inode), FI_INLINE_DENTRY); -- GitLab From 2aadac085cf0ca3e0295988d4d1dbdeafc15a9f6 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 23 Dec 2015 11:55:18 -0800 Subject: [PATCH 2139/2855] f2fs: introduce prepare_write_begin to clean up This patch adds prepare_write_begin to clean f2fs_write_begin. The major role of this function is to convert any inline_data and allocate or find block address. Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 92 +++++++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 38 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 958d8261b258a..d4839fc2b4ca3 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1410,6 +1410,51 @@ static void f2fs_write_failed(struct address_space *mapping, loff_t to) } } +static int prepare_write_begin(struct f2fs_sb_info *sbi, + struct page *page, loff_t pos, unsigned len, + block_t *blk_addr, bool *node_changed) +{ + struct inode *inode = page->mapping->host; + pgoff_t index = page->index; + struct dnode_of_data dn; + struct page *ipage; + int err = 0; + + f2fs_lock_op(sbi); + + /* check inline_data */ + ipage = get_node_page(sbi, inode->i_ino); + if (IS_ERR(ipage)) { + err = PTR_ERR(ipage); + goto unlock_out; + } + + set_new_dnode(&dn, inode, ipage, ipage, 0); + + if (f2fs_has_inline_data(inode)) { + if (pos + len <= MAX_INLINE_DATA) { + read_inline_data(page, ipage); + set_inode_flag(F2FS_I(inode), FI_DATA_EXIST); + sync_inode_page(&dn); + goto done; + } else { + err = f2fs_convert_inline_page(&dn, page); + if (err) + goto err_out; + } + } + err = f2fs_get_block(&dn, index); +done: + /* convert_inline_page can make node_changed */ + *blk_addr = dn.data_blkaddr; + *node_changed = dn.node_changed; +err_out: + f2fs_put_dnode(&dn); +unlock_out: + f2fs_unlock_op(sbi); + return err; +} + static int f2fs_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata) @@ -1417,9 +1462,9 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, struct inode *inode = mapping->host; struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct page *page = NULL; - struct page *ipage; pgoff_t index = ((unsigned long long) pos) >> PAGE_CACHE_SHIFT; - struct dnode_of_data dn; + bool need_balance = false; + block_t blkaddr = NULL_ADDR; int err = 0; trace_f2fs_write_begin(inode, pos, len, flags); @@ -1443,37 +1488,12 @@ repeat: *pagep = page; - f2fs_lock_op(sbi); - - /* check inline_data */ - ipage = get_node_page(sbi, inode->i_ino); - if (IS_ERR(ipage)) { - err = PTR_ERR(ipage); - goto unlock_fail; - } - - set_new_dnode(&dn, inode, ipage, ipage, 0); - - if (f2fs_has_inline_data(inode)) { - if (pos + len <= MAX_INLINE_DATA) { - read_inline_data(page, ipage); - set_inode_flag(F2FS_I(inode), FI_DATA_EXIST); - sync_inode_page(&dn); - goto put_next; - } - err = f2fs_convert_inline_page(&dn, page); - if (err) - goto put_fail; - } - - err = f2fs_get_block(&dn, index); + err = prepare_write_begin(sbi, page, pos, len, + &blkaddr, &need_balance); if (err) - goto put_fail; -put_next: - f2fs_put_dnode(&dn); - f2fs_unlock_op(sbi); + goto fail; - if (dn.node_changed && has_not_enough_free_secs(sbi, 0)) { + if (need_balance && has_not_enough_free_secs(sbi, 0)) { unlock_page(page); f2fs_balance_fs(sbi); lock_page(page); @@ -1488,7 +1508,7 @@ put_next: /* wait for GCed encrypted page writeback */ if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) - f2fs_wait_on_encrypted_page_writeback(sbi, dn.data_blkaddr); + f2fs_wait_on_encrypted_page_writeback(sbi, blkaddr); if (len == PAGE_CACHE_SIZE) goto out_update; @@ -1504,14 +1524,14 @@ put_next: goto out_update; } - if (dn.data_blkaddr == NEW_ADDR) { + if (blkaddr == NEW_ADDR) { zero_user_segment(page, 0, PAGE_CACHE_SIZE); } else { struct f2fs_io_info fio = { .sbi = sbi, .type = DATA, .rw = READ_SYNC, - .blk_addr = dn.data_blkaddr, + .blk_addr = blkaddr, .page = page, .encrypted_page = NULL, }; @@ -1542,10 +1562,6 @@ out_clear: clear_cold_data(page); return 0; -put_fail: - f2fs_put_dnode(&dn); -unlock_fail: - f2fs_unlock_op(sbi); fail: f2fs_put_page(page, 1); f2fs_write_failed(mapping, pos + len); -- GitLab From 4aa69d5667914dd0844d98ad84804b79a4845fa3 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 23 Dec 2015 14:17:47 -0800 Subject: [PATCH 2140/2855] f2fs: return early when trying to read null nid If get_node_page() gets zero nid, we can return early without getting a wrong page. For example, get_dnode_of_data() can try to do that. Signed-off-by: Jaegeuk Kim --- fs/f2fs/node.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 341de5d2353b3..929265d20c327 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1059,6 +1059,10 @@ struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid) { struct page *page; int err; + + if (!nid) + return ERR_PTR(-ENOENT); + f2fs_bug_on(sbi, check_nid_range(sbi, nid)); repeat: page = grab_cache_page(NODE_MAPPING(sbi), nid); if (!page) -- GitLab From b4d07a3e1a6e783132be7506aeb171dc5728f077 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 23 Dec 2015 13:48:58 -0800 Subject: [PATCH 2141/2855] f2fs: avoid f2fs_lock_op in f2fs_write_begin If f2fs_write_begin is to update data, we can bypass calling f2fs_lock_op() in order to avoid the checkpoint latency in the write syscall. Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index d4839fc2b4ca3..f2a023edfc1d2 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1418,10 +1418,16 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi, pgoff_t index = page->index; struct dnode_of_data dn; struct page *ipage; + bool locked = false; + struct extent_info ei; int err = 0; - f2fs_lock_op(sbi); - + if (f2fs_has_inline_data(inode) || + (pos & PAGE_CACHE_MASK) >= i_size_read(inode)) { + f2fs_lock_op(sbi); + locked = true; + } +restart: /* check inline_data */ ipage = get_node_page(sbi, inode->i_ino); if (IS_ERR(ipage)) { @@ -1436,22 +1442,42 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi, read_inline_data(page, ipage); set_inode_flag(F2FS_I(inode), FI_DATA_EXIST); sync_inode_page(&dn); - goto done; } else { err = f2fs_convert_inline_page(&dn, page); if (err) - goto err_out; + goto out; + if (dn.data_blkaddr == NULL_ADDR) + err = f2fs_get_block(&dn, index); + } + } else if (locked) { + err = f2fs_get_block(&dn, index); + } else { + if (f2fs_lookup_extent_cache(inode, index, &ei)) { + dn.data_blkaddr = ei.blk + index - ei.fofs; + } else { + bool restart = false; + + /* hole case */ + err = get_dnode_of_data(&dn, index, LOOKUP_NODE); + if (err || (!err && dn.data_blkaddr == NULL_ADDR)) + restart = true; + if (restart) { + f2fs_put_dnode(&dn); + f2fs_lock_op(sbi); + locked = true; + goto restart; + } } } - err = f2fs_get_block(&dn, index); -done: + /* convert_inline_page can make node_changed */ *blk_addr = dn.data_blkaddr; *node_changed = dn.node_changed; -err_out: +out: f2fs_put_dnode(&dn); unlock_out: - f2fs_unlock_op(sbi); + if (locked) + f2fs_unlock_op(sbi); return err; } -- GitLab From 06d6f2263913029ccd6199fd10e7dca525d348b1 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 23 Dec 2015 14:56:09 -0800 Subject: [PATCH 2142/2855] f2fs: declare static function The __f2fs_commit_super is static. Signed-off-by: Jaegeuk Kim --- fs/f2fs/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 597b533634e00..75704d9caae2c 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1195,7 +1195,7 @@ next: return 0; } -int __f2fs_commit_super(struct f2fs_sb_info *sbi, int block) +static int __f2fs_commit_super(struct f2fs_sb_info *sbi, int block) { struct f2fs_super_block *super = F2FS_RAW_SUPER(sbi); struct buffer_head *bh; -- GitLab From d53841740fd7feec170339203b198020ff100c58 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 24 Dec 2015 18:03:29 +0800 Subject: [PATCH 2143/2855] f2fs: add missing f2fs_balance_fs in __recover_dot_dentries __recover_do_dentries will try to grab free space in storage, so fix to add missing f2fs_balance_fs here. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/namei.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index e439f32d31e6e..fb41c80826964 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -214,6 +214,8 @@ static int __recover_dot_dentries(struct inode *dir, nid_t pino) struct page *page; int err = 0; + f2fs_balance_fs(sbi); + f2fs_lock_op(sbi); de = f2fs_find_entry(dir, &dot, &page); -- GitLab From 6d5a1495eebd441216dc96913a4270100b26e104 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 24 Dec 2015 18:04:56 +0800 Subject: [PATCH 2144/2855] f2fs: let user being aware of IO error Sometimes we keep dumb when IO error occur in lower layer device, so user will not receive any error return value for some operation, but actually, the operation did not succeed. This sould be avoided, so this patch reports such kind of error to user. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 17 +++++++---------- fs/f2fs/data.c | 23 +++++++++++++---------- fs/f2fs/f2fs.h | 2 +- fs/f2fs/file.c | 4 +++- fs/f2fs/gc.c | 4 +++- fs/f2fs/node.c | 5 +++++ 6 files changed, 32 insertions(+), 23 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 9cdb161973518..6b89ac69b7e47 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -798,7 +798,7 @@ void remove_dirty_inode(struct inode *inode) } } -void sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type) +int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type) { struct list_head *head; struct inode *inode; @@ -810,7 +810,7 @@ void sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type) F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA)); retry: if (unlikely(f2fs_cp_error(sbi))) - return; + return -EIO; spin_lock(&sbi->inode_lock[type]); @@ -820,7 +820,7 @@ retry: trace_f2fs_sync_dirty_inodes_exit(sbi->sb, is_dir, get_pages(sbi, is_dir ? F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA)); - return; + return 0; } fi = list_entry(head->next, struct f2fs_inode_info, dirty_list); inode = igrab(&fi->vfs_inode); @@ -859,11 +859,9 @@ retry_flush_dents: /* write all the dirty dentry pages */ if (get_pages(sbi, F2FS_DIRTY_DENTS)) { f2fs_unlock_all(sbi); - sync_dirty_inodes(sbi, DIR_INODE); - if (unlikely(f2fs_cp_error(sbi))) { - err = -EIO; + err = sync_dirty_inodes(sbi, DIR_INODE); + if (err) goto out; - } goto retry_flush_dents; } @@ -876,10 +874,9 @@ retry_flush_nodes: if (get_pages(sbi, F2FS_DIRTY_NODES)) { up_write(&sbi->node_write); - sync_node_pages(sbi, 0, &wbc); - if (unlikely(f2fs_cp_error(sbi))) { + err = sync_node_pages(sbi, 0, &wbc); + if (err) { f2fs_unlock_all(sbi); - err = -EIO; goto out; } goto retry_flush_nodes; diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index f2a023edfc1d2..5c43b2d606ec7 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -498,7 +498,7 @@ alloc: return 0; } -static void __allocate_data_blocks(struct inode *inode, loff_t offset, +static int __allocate_data_blocks(struct inode *inode, loff_t offset, size_t count) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); @@ -507,13 +507,15 @@ static void __allocate_data_blocks(struct inode *inode, loff_t offset, u64 len = F2FS_BYTES_TO_BLK(count); bool allocated; u64 end_offset; + int err = 0; while (len) { f2fs_lock_op(sbi); /* When reading holes, we need its node page */ set_new_dnode(&dn, inode, NULL, NULL, 0); - if (get_dnode_of_data(&dn, start, ALLOC_NODE)) + err = get_dnode_of_data(&dn, start, ALLOC_NODE); + if (err) goto out; allocated = false; @@ -522,12 +524,15 @@ static void __allocate_data_blocks(struct inode *inode, loff_t offset, while (dn.ofs_in_node < end_offset && len) { block_t blkaddr; - if (unlikely(f2fs_cp_error(sbi))) + if (unlikely(f2fs_cp_error(sbi))) { + err = -EIO; goto sync_out; + } blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); if (blkaddr == NULL_ADDR || blkaddr == NEW_ADDR) { - if (__allocate_data_block(&dn)) + err = __allocate_data_block(&dn); + if (err) goto sync_out; allocated = true; } @@ -545,7 +550,7 @@ static void __allocate_data_blocks(struct inode *inode, loff_t offset, if (dn.node_changed) f2fs_balance_fs(sbi); } - return; + return err; sync_out: if (allocated) @@ -555,7 +560,7 @@ out: f2fs_unlock_op(sbi); if (dn.node_changed) f2fs_balance_fs(sbi); - return; + return err; } /* @@ -1653,11 +1658,9 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, trace_f2fs_direct_IO_enter(inode, offset, count, iov_iter_rw(iter)); if (iov_iter_rw(iter) == WRITE) { - __allocate_data_blocks(inode, offset, count); - if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) { - err = -EIO; + err = __allocate_data_blocks(inode, offset, count); + if (err) goto out; - } } err = blockdev_direct_IO(iocb, inode, iter, offset, get_data_block_dio); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 79345e7ce6bb8..3406e9966064b 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1837,7 +1837,7 @@ int get_valid_checkpoint(struct f2fs_sb_info *); void update_dirty_page(struct inode *, struct page *); void add_dirty_dir_inode(struct inode *); void remove_dirty_inode(struct inode *); -void sync_dirty_inodes(struct f2fs_sb_info *, enum inode_type); +int sync_dirty_inodes(struct f2fs_sb_info *, enum inode_type); int write_checkpoint(struct f2fs_sb_info *, struct cp_control *); void init_ino_entry_info(struct f2fs_sb_info *); int __init create_checkpoint_caches(void); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 780db8bd2451e..2d87a3cf6768f 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -259,8 +259,10 @@ sync_nodes: sync_node_pages(sbi, ino, &wbc); /* if cp_error was enabled, we should avoid infinite loop */ - if (unlikely(f2fs_cp_error(sbi))) + if (unlikely(f2fs_cp_error(sbi))) { + ret = -EIO; goto out; + } if (need_inode_block_update(sbi, ino)) { mark_inode_dirty_sync(inode); diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index ce350c44b5cf4..c09be339569cf 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -832,8 +832,10 @@ gc_more: if (unlikely(!(sbi->sb->s_flags & MS_ACTIVE))) goto stop; - if (unlikely(f2fs_cp_error(sbi))) + if (unlikely(f2fs_cp_error(sbi))) { + ret = -EIO; goto stop; + } if (gc_type == BG_GC && has_not_enough_free_secs(sbi, sec_freed)) { gc_type = FG_GC; diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 929265d20c327..94d9753f8c532 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1189,6 +1189,11 @@ next_step: for (i = 0; i < nr_pages; i++) { struct page *page = pvec.pages[i]; + if (unlikely(f2fs_cp_error(sbi))) { + pagevec_release(&pvec); + return -EIO; + } + /* * flushing sequence with step: * 0. indirect nodes -- GitLab From 9a950d52b7f0e1c64c2cc70d350562fb18c8b451 Mon Sep 17 00:00:00 2001 From: Fan Li Date: Sat, 26 Dec 2015 18:07:41 +0800 Subject: [PATCH 2145/2855] f2fs: fix bugs and simplify codes of f2fs_fiemap fix bugs: 1. len could be updated incorrectly when start+len is beyond isize. 2. If there is a hole consisting of more than two blocks, it could fail to add FIEMAP_EXTENT_LAST flag for the last extent. 3. If there is an extent beyond isize, when we search extents in a range that ends at isize, it will also return the extent beyond isize, which is outside the range. Signed-off-by: Fan li Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 80 +++++++++++++++++--------------------------------- 1 file changed, 27 insertions(+), 53 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 5c43b2d606ec7..d67c599510d9b 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -783,7 +783,6 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, loff_t isize = i_size_read(inode); u64 logical = 0, phys = 0, size = 0; u32 flags = 0; - bool past_eof = false, whole_file = false; int ret = 0; ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC); @@ -797,17 +796,18 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, } mutex_lock(&inode->i_mutex); + if (start >= isize) + goto out; - if (len >= isize) { - whole_file = true; - len = isize; - } + if (start + len > isize) + len = isize - start; if (logical_to_blk(inode, len) == 0) len = blk_to_logical(inode, 1); start_blk = logical_to_blk(inode, start); last_blk = logical_to_blk(inode, start + len - 1); + next: memset(&map_bh, 0, sizeof(struct buffer_head)); map_bh.b_size = len; @@ -819,59 +819,33 @@ next: /* HOLE */ if (!buffer_mapped(&map_bh)) { - start_blk++; - - if (!past_eof && blk_to_logical(inode, start_blk) >= isize) - past_eof = 1; - - if (past_eof && size) { - flags |= FIEMAP_EXTENT_LAST; - ret = fiemap_fill_next_extent(fieinfo, logical, - phys, size, flags); - } else if (size) { - ret = fiemap_fill_next_extent(fieinfo, logical, - phys, size, flags); - size = 0; - } + /* Go through holes util pass the EOF */ + if (blk_to_logical(inode, start_blk++) < isize) + goto prep_next; + /* Found a hole beyond isize means no more extents. + * Note that the premise is that filesystems don't + * punch holes beyond isize and keep size unchanged. + */ + flags |= FIEMAP_EXTENT_LAST; + } - /* if we have holes up to/past EOF then we're done */ - if (start_blk > last_blk || past_eof || ret) - goto out; - } else { - if (start_blk > last_blk && !whole_file) { - ret = fiemap_fill_next_extent(fieinfo, logical, - phys, size, flags); - goto out; - } + if (size) + ret = fiemap_fill_next_extent(fieinfo, logical, + phys, size, flags); - /* - * if size != 0 then we know we already have an extent - * to add, so add it. - */ - if (size) { - ret = fiemap_fill_next_extent(fieinfo, logical, - phys, size, flags); - if (ret) - goto out; - } + if (start_blk > last_blk || ret) + goto out; - logical = blk_to_logical(inode, start_blk); - phys = blk_to_logical(inode, map_bh.b_blocknr); - size = map_bh.b_size; - flags = 0; - if (buffer_unwritten(&map_bh)) - flags = FIEMAP_EXTENT_UNWRITTEN; + logical = blk_to_logical(inode, start_blk); + phys = blk_to_logical(inode, map_bh.b_blocknr); + size = map_bh.b_size; + flags = 0; + if (buffer_unwritten(&map_bh)) + flags = FIEMAP_EXTENT_UNWRITTEN; - start_blk += logical_to_blk(inode, size); + start_blk += logical_to_blk(inode, size); - /* - * If we are past the EOF, then we need to make sure as - * soon as we find a hole that the last extent we found - * is marked with FIEMAP_EXTENT_LAST - */ - if (!past_eof && logical + size >= isize) - past_eof = true; - } +prep_next: cond_resched(); if (fatal_signal_pending(current)) ret = -EINTR; -- GitLab From 179448bfe4cd201e98e728391c6b01b25c849fe8 Mon Sep 17 00:00:00 2001 From: Yunlei He Date: Mon, 28 Dec 2015 21:48:32 +0800 Subject: [PATCH 2146/2855] f2fs: add a max block check for get_data_block_bmap This patch adds a max block check for get_data_block_bmap. Trinity test program will send a block number as parameter into ioctl_fibmap, which will be used in get_node_path(), when the block number large than f2fs max blocks, it will trigger kernel bug. Signed-off-by: Yunlei He Signed-off-by: Xue Liu [Jaegeuk Kim: fix missing condition, pointed by Chao Yu] Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 4 ++++ fs/f2fs/f2fs.h | 1 + fs/f2fs/super.c | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index d67c599510d9b..6fbfc70ac8a03 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -761,6 +761,10 @@ static int get_data_block_dio(struct inode *inode, sector_t iblock, static int get_data_block_bmap(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) { + /* Block number less than F2FS MAX BLOCKS */ + if (unlikely(iblock >= max_file_size(0))) + return -EFBIG; + return __get_data_block(inode, iblock, bh_result, create, F2FS_GET_BLOCK_BMAP); } diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 3406e9966064b..e04b2be6cd64d 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1726,6 +1726,7 @@ static inline int f2fs_add_link(struct dentry *dentry, struct inode *inode) * super.c */ int f2fs_commit_super(struct f2fs_sb_info *, bool); +loff_t max_file_size(unsigned bits); int f2fs_sync_fs(struct super_block *, int); extern __printf(3, 4) void f2fs_msg(struct super_block *, const char *, const char *, ...); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 75704d9caae2c..a2e3a8f893edd 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -907,7 +907,7 @@ static const struct export_operations f2fs_export_ops = { .get_parent = f2fs_get_parent, }; -static loff_t max_file_size(unsigned bits) +loff_t max_file_size(unsigned bits) { loff_t result = (DEF_ADDRS_PER_INODE - F2FS_INLINE_XATTR_ADDRS); loff_t leaf_count = ADDRS_PER_BLOCK; -- GitLab From e96248bb45d42375b23e1c083ec5a55151503e82 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 24 Dec 2015 18:11:32 +0800 Subject: [PATCH 2147/2855] f2fs: clean up f2fs_ioc_write_checkpoint Use f2fs_sync_fs to clean up codes in f2fs_ioc_write_checkpoint. Signed-off-by: Chao Yu [Jaegeuk Kim: remove unused err variable] Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 2d87a3cf6768f..91f576a7903cf 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1619,8 +1619,6 @@ static int f2fs_ioc_write_checkpoint(struct file *filp, unsigned long arg) { struct inode *inode = file_inode(filp); struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - struct cp_control cpc; - int err; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -1628,13 +1626,7 @@ static int f2fs_ioc_write_checkpoint(struct file *filp, unsigned long arg) if (f2fs_readonly(sbi->sb)) return -EROFS; - cpc.reason = __get_cp_reason(sbi); - - mutex_lock(&sbi->gc_mutex); - err = write_checkpoint(sbi, &cpc); - mutex_unlock(&sbi->gc_mutex); - - return err; + return f2fs_sync_fs(sbi->sb, 1); } static int f2fs_defragment_range(struct f2fs_sb_info *sbi, -- GitLab From 8dc0d6a11e7d985dd466ce0a8c71eaea50dd7cc6 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 24 Dec 2015 16:13:09 -0800 Subject: [PATCH 2148/2855] f2fs: early check broken symlink length in the encrypted case If link is broken, its len is zero, and we don't need to move forward. Signed-off-by: Jaegeuk Kim --- fs/f2fs/namei.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index fb41c80826964..6c4a94310b541 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -931,7 +931,7 @@ static const char *f2fs_encrypted_follow_link(struct dentry *dentry, void **cook { struct page *cpage = NULL; char *caddr, *paddr = NULL; - struct f2fs_str cstr; + struct f2fs_str cstr = FSTR_INIT(NULL, 0); struct f2fs_str pstr = FSTR_INIT(NULL, 0); struct inode *inode = d_inode(dentry); struct f2fs_encrypted_symlink_data *sd; @@ -952,6 +952,12 @@ static const char *f2fs_encrypted_follow_link(struct dentry *dentry, void **cook /* Symlink is encrypted */ sd = (struct f2fs_encrypted_symlink_data *)caddr; cstr.len = le16_to_cpu(sd->len); + + /* this is broken symlink case */ + if (unlikely(cstr.len == 0)) { + res = -ENOENT; + goto errout; + } cstr.name = kmalloc(cstr.len, GFP_NOFS); if (!cstr.name) { res = -ENOMEM; @@ -960,7 +966,7 @@ static const char *f2fs_encrypted_follow_link(struct dentry *dentry, void **cook memcpy(cstr.name, sd->encrypted_path, cstr.len); /* this is broken symlink case */ - if (cstr.name[0] == 0 && cstr.len == 0) { + if (unlikely(cstr.name[0] == 0)) { res = -ENOENT; goto errout; } -- GitLab From 819d9153d4c87329910a4cb01198610cd24ec62d Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 28 Dec 2015 13:48:11 -0800 Subject: [PATCH 2149/2855] f2fs: use i_size_read to get i_size We need to use i_size_read() to get inode->i_size. Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 6fbfc70ac8a03..14b40a9db5b39 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1386,10 +1386,11 @@ skip_write: static void f2fs_write_failed(struct address_space *mapping, loff_t to) { struct inode *inode = mapping->host; + loff_t i_size = i_size_read(inode); - if (to > inode->i_size) { - truncate_pagecache(inode, inode->i_size); - truncate_blocks(inode, inode->i_size, true); + if (to > i_size) { + truncate_pagecache(inode, i_size); + truncate_blocks(inode, i_size, true); } } -- GitLab From ed3d12561a731b99b58c6c95151291cebf0b3feb Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 28 Dec 2015 11:39:06 -0800 Subject: [PATCH 2150/2855] f2fs: load largest extent all the time Otherwise, we can get mismatched largest extent information. One example is: 1. mount f2fs w/ extent_cache 2. make a small extent 3. umount 4. mount f2fs w/o extent_cache 5. update the largest extent 6. umount 7. mount f2fs w/ extent_cache 8. get the old extent made by #2 Signed-off-by: Jaegeuk Kim --- fs/f2fs/extent_cache.c | 18 +++++++++++++----- fs/f2fs/f2fs.h | 2 +- fs/f2fs/inode.c | 3 ++- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index 5305a29f91a33..b37184f720e89 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -166,20 +166,27 @@ static void __drop_largest_extent(struct inode *inode, largest->len = 0; } -void f2fs_init_extent_tree(struct inode *inode, struct f2fs_extent *i_ext) +/* return true, if inode page is changed */ +bool f2fs_init_extent_tree(struct inode *inode, struct f2fs_extent *i_ext) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct extent_tree *et; struct extent_node *en; struct extent_info ei; - if (!f2fs_may_extent_tree(inode)) - return; + if (!f2fs_may_extent_tree(inode)) { + /* drop largest extent */ + if (i_ext && i_ext->len) { + i_ext->len = 0; + return true; + } + return false; + } et = __grab_extent_tree(inode); - if (!i_ext || le32_to_cpu(i_ext->len) < F2FS_MIN_EXTENT_LEN) - return; + if (!i_ext || !i_ext->len) + return false; set_extent_info(&ei, le32_to_cpu(i_ext->fofs), le32_to_cpu(i_ext->blk), le32_to_cpu(i_ext->len)); @@ -196,6 +203,7 @@ void f2fs_init_extent_tree(struct inode *inode, struct f2fs_extent *i_ext) } out: write_unlock(&et->lock); + return false; } static bool f2fs_lookup_extent_tree(struct inode *inode, pgoff_t pgofs, diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index e04b2be6cd64d..a3395088e0f0e 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -2083,7 +2083,7 @@ void f2fs_leave_shrinker(struct f2fs_sb_info *); * extent_cache.c */ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *, int); -void f2fs_init_extent_tree(struct inode *, struct f2fs_extent *); +bool f2fs_init_extent_tree(struct inode *, struct f2fs_extent *); unsigned int f2fs_destroy_extent_node(struct inode *); void f2fs_destroy_extent_tree(struct inode *); bool f2fs_lookup_extent_cache(struct inode *, pgoff_t, struct extent_info *); diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index ec3fb32c47262..e95500802daa6 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -138,7 +138,8 @@ static int do_read_inode(struct inode *inode) fi->i_pino = le32_to_cpu(ri->i_pino); fi->i_dir_level = ri->i_dir_level; - f2fs_init_extent_tree(inode, &ri->i_ext); + if (f2fs_init_extent_tree(inode, &ri->i_ext)) + set_page_dirty(node_page); get_inline_info(fi, ri); -- GitLab From 4e0d836d5fb26d2cdbb75b0d16d98bef6b798490 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 30 Dec 2015 17:40:31 +0800 Subject: [PATCH 2151/2855] f2fs: fix to skip recovering dot dentries in a readonly fs If filesystem is readonly, leave user message info instead of recovering inline dot inode. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/namei.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 6c4a94310b541..a629af5cb0ce6 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -214,6 +214,13 @@ static int __recover_dot_dentries(struct inode *dir, nid_t pino) struct page *page; int err = 0; + if (f2fs_readonly(sbi->sb)) { + f2fs_msg(sbi->sb, KERN_INFO, + "skip recovering inline_dots inode (ino:%lu, pino:%u) " + "in readonly mountpoint", dir->i_ino, pino); + return 0; + } + f2fs_balance_fs(sbi); f2fs_lock_op(sbi); -- GitLab From 732d56489f21c04f7bf60c675f7d152c9239a09c Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 29 Dec 2015 15:46:33 -0800 Subject: [PATCH 2152/2855] f2fs: fix f2fs_ioc_abort_volatile_write There are two rules to handle aborting volatile or atomic writes. 1. drop atomic writes - we don't need to keep any stale db data. 2. write journal data - we should keep the journal data with fsync for db recovery. Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 91f576a7903cf..b04ab40ddc737 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1433,9 +1433,14 @@ static int f2fs_ioc_abort_volatile_write(struct file *filp) if (ret) return ret; - clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); - clear_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); - commit_inmem_pages(inode, true); + if (f2fs_is_atomic_file(inode)) { + clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); + commit_inmem_pages(inode, true); + } + if (f2fs_is_volatile_file(inode)) { + clear_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); + ret = f2fs_sync_file(filp, 0, LLONG_MAX, 0); + } mnt_drop_write_file(filp); return ret; -- GitLab From 9a327405014f4ef4cdad67a0686db82b9f23c62c Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 21 Dec 2015 15:26:31 +0200 Subject: [PATCH 2153/2855] HID: i2c-hid: Prevent sending reports from racing with device reset When an i2c-hid device is resumed from system sleep the driver resets the device to be sure it is in known state. The device is expected to issue an interrupt when reset is complete. This reset might take few milliseconds to complete so if the HID driver on top (hid-rmi) starts to set up the device by sending feature reports etc. the device might not issue the reset complete interrupt anymore. Below is what happens to touchpad on Lenovo Yoga 900 during resume from system sleep: [ 24.790951] i2c_hid i2c-SYNA2B29:00: i2c_hid_hwreset [ 24.790973] i2c_hid i2c-SYNA2B29:00: i2c_hid_set_power [ 24.790982] i2c_hid i2c-SYNA2B29:00: __i2c_hid_command: cmd=22 00 00 08 [ 24.793011] i2c_hid i2c-SYNA2B29:00: resetting... [ 24.793016] i2c_hid i2c-SYNA2B29:00: __i2c_hid_command: cmd=22 00 00 01 Here i2c-hid sends reset command to the touchpad. [ 24.794012] i2c_hid i2c-SYNA2B29:00: input: 06 00 01 00 00 00 [ 24.794051] i2c_hid i2c-SYNA2B29:00: i2c_hid_set_or_send_report [ 24.794059] i2c_hid i2c-SYNA2B29:00: __i2c_hid_command: cmd=22 00 3f 03 0f 23 00 04 00 0f 01 Now hid-rmi puts the touchpad to correct mode by sending it a feature report. This makes the touchpad not to issue reset complete interrupt. [ 24.796092] i2c_hid i2c-SYNA2B29:00: __i2c_hid_command: waiting... i2c-hid starts to wait for the reset interrupt to trigger which never happens. [ 24.798304] i2c_hid i2c-SYNA2B29:00: i2c_hid_set_or_send_report [ 24.798313] i2c_hid i2c-SYNA2B29:00: __i2c_hid_command: cmd=25 00 17 00 09 01 42 00 2e 00 19 19 00 10 cc 06 74 04 0f 19 00 00 00 00 00 Yet another output report from hid-rmi driver. [ 29.795630] i2c_hid i2c-SYNA2B29:00: __i2c_hid_command: finished. [ 29.795637] i2c_hid i2c-SYNA2B29:00: failed to reset device. After 5 seconds i2c-hid driver times out. [ 29.795642] i2c_hid i2c-SYNA2B29:00: i2c_hid_set_power [ 29.795649] i2c_hid i2c-SYNA2B29:00: __i2c_hid_command: cmd=22 00 01 08 [ 29.797576] dpm_run_callback(): i2c_hid_resume+0x0/0xb0 returns -61 [ 29.797584] PM: Device i2c-SYNA2B29:00 failed to resume: error -61 After this the touchpad does not work anymore (and also resume itself gets slowed down because of the timeout). Prevent sending of feature/output reports while the device is being reset by adding a mutex which is held during that time. Reported-and-tested-by: Linus Torvalds Reported-by: Nish Aravamudan Suggested-by: Benjamin Tissoires Reviewed-by: Benjamin Tissoires Signed-off-by: Mika Westerberg Signed-off-by: Jiri Kosina --- drivers/hid/i2c-hid/i2c-hid.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 10bd8e6e4c9c8..fc5ef1c25ed4e 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -151,6 +151,7 @@ struct i2c_hid { struct i2c_hid_platform_data pdata; bool irq_wake_enabled; + struct mutex reset_lock; }; static int __i2c_hid_command(struct i2c_client *client, @@ -356,9 +357,16 @@ static int i2c_hid_hwreset(struct i2c_client *client) i2c_hid_dbg(ihid, "%s\n", __func__); + /* + * This prevents sending feature reports while the device is + * being reset. Otherwise we may lose the reset complete + * interrupt. + */ + mutex_lock(&ihid->reset_lock); + ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); if (ret) - return ret; + goto out_unlock; i2c_hid_dbg(ihid, "resetting...\n"); @@ -366,10 +374,11 @@ static int i2c_hid_hwreset(struct i2c_client *client) if (ret) { dev_err(&client->dev, "failed to reset device.\n"); i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); - return ret; } - return 0; +out_unlock: + mutex_unlock(&ihid->reset_lock); + return ret; } static void i2c_hid_get_input(struct i2c_hid *ihid) @@ -587,12 +596,15 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count, unsigned char report_type, bool use_data) { struct i2c_client *client = hid->driver_data; + struct i2c_hid *ihid = i2c_get_clientdata(client); int report_id = buf[0]; int ret; if (report_type == HID_INPUT_REPORT) return -EINVAL; + mutex_lock(&ihid->reset_lock); + if (report_id) { buf++; count--; @@ -605,6 +617,8 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf, if (report_id && ret >= 0) ret++; /* add report_id to the number of transfered bytes */ + mutex_unlock(&ihid->reset_lock); + return ret; } @@ -990,6 +1004,7 @@ static int i2c_hid_probe(struct i2c_client *client, ihid->wHIDDescRegister = cpu_to_le16(hidRegister); init_waitqueue_head(&ihid->wait); + mutex_init(&ihid->reset_lock); /* we need to allocate the command buffer without knowing the maximum * size of the reports. Let's use HID_MIN_BUFFER_SIZE, then we do the -- GitLab From 0b161e6330e27c191a0ff0d44082ff7832a8c8a1 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 30 Dec 2015 18:14:06 -0500 Subject: [PATCH 2154/2855] SUNRPC: Fix a missing break in rpc_anyaddr() The missing break means that we always return EAFNOSUPPORT when faced with a request for an IPv6 loopback address. Reported-by: coverity (CID 401987) Signed-off-by: Trond Myklebust --- net/sunrpc/clnt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 23608eb0ded2c..b7f21044f4d8c 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -1217,6 +1217,7 @@ static int rpc_anyaddr(int family, struct sockaddr *buf, size_t buflen) return -EINVAL; memcpy(buf, &rpc_in6addr_loopback, sizeof(rpc_in6addr_loopback)); + break; default: dprintk("RPC: %s: address family not supported\n", __func__); -- GitLab From dc602dd706cb64036132a7903ead1c67d9a7bcb9 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 31 Dec 2015 11:44:06 -0500 Subject: [PATCH 2155/2855] NFS/pNFS: Fix up pNFS write reschedule layering violations and bugs The flexfiles layout in particular, seems to want to poke around in the O_DIRECT flags when retransmitting. This patch sets up an interface to allow it to call back into O_DIRECT to handle retransmission correctly. It also fixes a potential bug whereby we could change the behaviour of O_DIRECT if an error is already pending. Signed-off-by: Trond Myklebust --- fs/nfs/direct.c | 21 +++++++++++++++------ fs/nfs/flexfilelayout/flexfilelayout.c | 13 +------------ fs/nfs/internal.h | 1 - fs/nfs/write.c | 6 ++++++ include/linux/nfs_xdr.h | 1 + 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 4b1d08f56aba7..e73693f75dee6 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -117,12 +117,6 @@ static inline int put_dreq(struct nfs_direct_req *dreq) return atomic_dec_and_test(&dreq->io_count); } -void nfs_direct_set_resched_writes(struct nfs_direct_req *dreq) -{ - dreq->flags = NFS_ODIRECT_RESCHED_WRITES; -} -EXPORT_SYMBOL_GPL(nfs_direct_set_resched_writes); - static void nfs_direct_good_bytes(struct nfs_direct_req *dreq, struct nfs_pgio_header *hdr) { @@ -839,10 +833,25 @@ static void nfs_write_sync_pgio_error(struct list_head *head) } } +static void nfs_direct_write_reschedule_io(struct nfs_pgio_header *hdr) +{ + struct nfs_direct_req *dreq = hdr->dreq; + + spin_lock(&dreq->lock); + if (dreq->error == 0) { + dreq->flags = NFS_ODIRECT_RESCHED_WRITES; + /* fake unstable write to let common nfs resend pages */ + hdr->verf.committed = NFS_UNSTABLE; + hdr->good_bytes = hdr->args.count; + } + spin_unlock(&dreq->lock); +} + static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops = { .error_cleanup = nfs_write_sync_pgio_error, .init_hdr = nfs_direct_pgio_init, .completion = nfs_direct_write_completion, + .reschedule_io = nfs_direct_write_reschedule_io, }; diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index 03516c80855a0..df475d42df776 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -912,18 +912,7 @@ static void ff_layout_reset_write(struct nfs_pgio_header *hdr, bool retry_pnfs) hdr->args.count, (unsigned long long)hdr->args.offset); - if (!hdr->dreq) { - struct nfs_open_context *ctx; - - ctx = nfs_list_entry(hdr->pages.next)->wb_context; - set_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags); - hdr->completion_ops->error_cleanup(&hdr->pages); - } else { - nfs_direct_set_resched_writes(hdr->dreq); - /* fake unstable write to let common nfs resend pages */ - hdr->verf.committed = NFS_UNSTABLE; - hdr->good_bytes = hdr->args.count; - } + hdr->completion_ops->reschedule_io(hdr); return; } diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 313d55402238f..99a2919047e9b 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -519,7 +519,6 @@ static inline void nfs_inode_dio_wait(struct inode *inode) inode_dio_wait(inode); } extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq); -extern void nfs_direct_set_resched_writes(struct nfs_direct_req *dreq); /* nfs4proc.c */ extern void __nfs4_read_done_cb(struct nfs_pgio_header *); diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 7b93164069307..0aa3e6b3db70a 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -1326,9 +1326,15 @@ static void nfs_async_write_error(struct list_head *head) } } +static void nfs_async_write_reschedule_io(struct nfs_pgio_header *hdr) +{ + nfs_async_write_error(&hdr->pages); +} + static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops = { .error_cleanup = nfs_async_write_error, .completion = nfs_write_completion, + .reschedule_io = nfs_async_write_reschedule_io, }; void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 11bbae44f4cbf..e89dbb14138c2 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1460,6 +1460,7 @@ struct nfs_pgio_completion_ops { void (*error_cleanup)(struct list_head *head); void (*init_hdr)(struct nfs_pgio_header *hdr); void (*completion)(struct nfs_pgio_header *hdr); + void (*reschedule_io)(struct nfs_pgio_header *hdr); }; struct nfs_unlinkdata { -- GitLab From af7cf057933f01dc7f33ddfb5e436ad598ed17ad Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 29 Sep 2015 20:34:05 -0400 Subject: [PATCH 2156/2855] NFS: Allow multiple commit requests in flight per file Allow synchronous RPC calls to wait for pending RPC calls to finish, but also allow asynchronous ones to just fire off another commit. With this patch, the xfstests generic/074 test completes in 226s instead of 242s Signed-off-by: Trond Myklebust --- fs/nfs/direct.c | 6 ---- fs/nfs/file.c | 2 +- fs/nfs/nfstrace.h | 1 - fs/nfs/pnfs_nfs.c | 5 +-- fs/nfs/write.c | 70 +++++++++++++++++++---------------------- include/linux/nfs_fs.h | 1 - include/linux/nfs_xdr.h | 1 - 7 files changed, 35 insertions(+), 51 deletions(-) diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index e73693f75dee6..14f77df79c258 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -721,14 +721,8 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) nfs_direct_write_complete(dreq, data->inode); } -static void nfs_direct_error_cleanup(struct nfs_inode *nfsi) -{ - /* There is no lock to clear */ -} - static const struct nfs_commit_completion_ops nfs_direct_commit_completion_ops = { .completion = nfs_direct_commit_complete, - .error_cleanup = nfs_direct_error_cleanup, }; static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 93e236429c5d7..e6ef80ec699c7 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -514,7 +514,7 @@ static void nfs_check_dirty_writeback(struct page *page, * so it will not block due to pages that will shortly be freeable. */ nfsi = NFS_I(mapping->host); - if (test_bit(NFS_INO_COMMIT, &nfsi->flags)) { + if (atomic_read(&nfsi->commit_info.rpcs_out)) { *writeback = true; return; } diff --git a/fs/nfs/nfstrace.h b/fs/nfs/nfstrace.h index 59f838cdc0093..9f80a086b612a 100644 --- a/fs/nfs/nfstrace.h +++ b/fs/nfs/nfstrace.h @@ -39,7 +39,6 @@ { 1 << NFS_INO_INVALIDATING, "INVALIDATING" }, \ { 1 << NFS_INO_FLUSHING, "FLUSHING" }, \ { 1 << NFS_INO_FSCACHE, "FSCACHE" }, \ - { 1 << NFS_INO_COMMIT, "COMMIT" }, \ { 1 << NFS_INO_LAYOUTCOMMIT, "NEED_LAYOUTCOMMIT" }, \ { 1 << NFS_INO_LAYOUTCOMMITTING, "LAYOUTCOMMIT" }) diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c index 24655b807d442..3c8e3a44e6ead 100644 --- a/fs/nfs/pnfs_nfs.c +++ b/fs/nfs/pnfs_nfs.c @@ -266,17 +266,14 @@ pnfs_generic_commit_pagelist(struct inode *inode, struct list_head *mds_pages, } else { nfs_retry_commit(mds_pages, NULL, cinfo, 0); pnfs_generic_retry_commit(cinfo, 0); - cinfo->completion_ops->error_cleanup(NFS_I(inode)); return -ENOMEM; } } nreq += pnfs_generic_alloc_ds_commits(cinfo, &list); - if (nreq == 0) { - cinfo->completion_ops->error_cleanup(NFS_I(inode)); + if (nreq == 0) goto out; - } atomic_add(nreq, &cinfo->mds->rpcs_out); diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 0aa3e6b3db70a..ae29f082c9c23 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include @@ -1535,27 +1537,29 @@ static void nfs_writeback_result(struct rpc_task *task, } } +static int nfs_wait_atomic_killable(atomic_t *key) +{ + if (fatal_signal_pending(current)) + return -ERESTARTSYS; + freezable_schedule_unsafe(); + return 0; +} -static int nfs_commit_set_lock(struct nfs_inode *nfsi, int may_wait) +static int wait_on_commit(struct nfs_mds_commit_info *cinfo) { - int ret; + return wait_on_atomic_t(&cinfo->rpcs_out, + nfs_wait_atomic_killable, TASK_KILLABLE); +} - if (!test_and_set_bit(NFS_INO_COMMIT, &nfsi->flags)) - return 1; - if (!may_wait) - return 0; - ret = out_of_line_wait_on_bit_lock(&nfsi->flags, - NFS_INO_COMMIT, - nfs_wait_bit_killable, - TASK_KILLABLE); - return (ret < 0) ? ret : 1; +static void nfs_commit_begin(struct nfs_mds_commit_info *cinfo) +{ + atomic_inc(&cinfo->rpcs_out); } -static void nfs_commit_clear_lock(struct nfs_inode *nfsi) +static void nfs_commit_end(struct nfs_mds_commit_info *cinfo) { - clear_bit(NFS_INO_COMMIT, &nfsi->flags); - smp_mb__after_atomic(); - wake_up_bit(&nfsi->flags, NFS_INO_COMMIT); + if (atomic_dec_and_test(&cinfo->rpcs_out)) + wake_up_atomic_t(&cinfo->rpcs_out); } void nfs_commitdata_release(struct nfs_commit_data *data) @@ -1693,7 +1697,6 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how, data->mds_ops, how, 0); out_bad: nfs_retry_commit(head, NULL, cinfo, 0); - cinfo->completion_ops->error_cleanup(NFS_I(inode)); return -ENOMEM; } @@ -1755,8 +1758,7 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data) clear_bdi_congested(&nfss->backing_dev_info, BLK_RW_ASYNC); nfs_init_cinfo(&cinfo, data->inode, data->dreq); - if (atomic_dec_and_test(&cinfo.mds->rpcs_out)) - nfs_commit_clear_lock(NFS_I(data->inode)); + nfs_commit_end(cinfo.mds); } static void nfs_commit_release(void *calldata) @@ -1775,7 +1777,6 @@ static const struct rpc_call_ops nfs_commit_ops = { static const struct nfs_commit_completion_ops nfs_commit_completion_ops = { .completion = nfs_commit_release_pages, - .error_cleanup = nfs_commit_clear_lock, }; int nfs_generic_commit_list(struct inode *inode, struct list_head *head, @@ -1794,30 +1795,25 @@ int nfs_commit_inode(struct inode *inode, int how) LIST_HEAD(head); struct nfs_commit_info cinfo; int may_wait = how & FLUSH_SYNC; + int error = 0; int res; - res = nfs_commit_set_lock(NFS_I(inode), may_wait); - if (res <= 0) - goto out_mark_dirty; nfs_init_cinfo_from_inode(&cinfo, inode); + nfs_commit_begin(cinfo.mds); res = nfs_scan_commit(inode, &head, &cinfo); - if (res) { - int error; - + if (res) error = nfs_generic_commit_list(inode, &head, how, &cinfo); - if (error < 0) - return error; - if (!may_wait) - goto out_mark_dirty; - error = wait_on_bit_action(&NFS_I(inode)->flags, - NFS_INO_COMMIT, - nfs_wait_bit_killable, - TASK_KILLABLE); - if (error < 0) - return error; - } else - nfs_commit_clear_lock(NFS_I(inode)); + nfs_commit_end(cinfo.mds); + if (error < 0) + goto out_error; + if (!may_wait) + goto out_mark_dirty; + error = wait_on_commit(cinfo.mds); + if (error < 0) + return error; return res; +out_error: + res = error; /* Note: If we exit without ensuring that the commit is complete, * we must mark the inode as dirty. Otherwise, future calls to * sync_inode() with the WB_SYNC_ALL flag set will fail to ensure diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index c0e961474a527..ebf0bd72a42bd 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -216,7 +216,6 @@ struct nfs_inode { #define NFS_INO_FLUSHING (4) /* inode is flushing out data */ #define NFS_INO_FSCACHE (5) /* inode can be cached by FS-Cache */ #define NFS_INO_FSCACHE_LOCK (6) /* FS-Cache cookie management lock */ -#define NFS_INO_COMMIT (7) /* inode is committing unstable writes */ #define NFS_INO_LAYOUTCOMMIT (9) /* layoutcommit required */ #define NFS_INO_LAYOUTCOMMITTING (10) /* layoutcommit inflight */ #define NFS_INO_LAYOUTSTATS (11) /* layoutstats inflight */ diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index e89dbb14138c2..a8905b7d4d7f7 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1423,7 +1423,6 @@ struct nfs_mds_commit_info { struct nfs_commit_data; struct nfs_inode; struct nfs_commit_completion_ops { - void (*error_cleanup) (struct nfs_inode *nfsi); void (*completion) (struct nfs_commit_data *data); }; -- GitLab From 44451d4d8f0e35153b3e7e3d40e198f2cf9ac36a Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Thu, 31 Dec 2015 12:57:26 -0600 Subject: [PATCH 2157/2855] MAINTAINERS: Update Scott Wood's e-mail address Freescale is now NXP. I still work there, but I won't be using their mail system for Linux development. Signed-off-by: Scott Wood --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 8099527abccf6..124dd3795475f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6429,7 +6429,7 @@ S: Maintained F: arch/powerpc/platforms/8xx/ LINUX FOR POWERPC EMBEDDED PPC83XX AND PPC85XX -M: Scott Wood +M: Scott Wood M: Kumar Gala W: http://www.penguinppc.org/ L: linuxppc-dev@lists.ozlabs.org -- GitLab From 1f6fa26199bb164157fbf81f850df1991d10c959 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 31 Dec 2015 10:28:52 -0800 Subject: [PATCH 2158/2855] f2fs: remove f2fs_bug_on in terms of max_depth There is no report on this bug_on case, but if malicious attacker changed this field intentionally, we can just reset it as a MAX value. Signed-off-by: Jaegeuk Kim --- fs/f2fs/dir.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 3da58265c0d40..29bb8dd76a46e 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -172,8 +172,6 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir, namehash = f2fs_dentry_hash(&name); - f2fs_bug_on(F2FS_I_SB(dir), level > MAX_DIR_HASH_DEPTH); - nbucket = dir_buckets(level, F2FS_I(dir)->i_dir_level); nblock = bucket_blocks(level); @@ -238,6 +236,14 @@ struct f2fs_dir_entry *f2fs_find_entry(struct inode *dir, goto out; max_depth = F2FS_I(dir)->i_current_depth; + if (unlikely(max_depth > MAX_DIR_HASH_DEPTH)) { + f2fs_msg(F2FS_I_SB(dir)->sb, KERN_WARNING, + "Corrupted max_depth of %lu: %u", + dir->i_ino, max_depth); + max_depth = MAX_DIR_HASH_DEPTH; + F2FS_I(dir)->i_current_depth = max_depth; + mark_inode_dirty(dir); + } for (level = 0; level < max_depth; level++) { de = find_in_level(dir, level, &fname, res_page); -- GitLab From b20135d0b2431900a3a5395970ffb7e4f3767c8b Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 31 Dec 2015 09:28:06 -0500 Subject: [PATCH 2159/2855] NFSv4.1/pNFS: Don't queue up a new commit if the layout segment is invalid If the layout segment is invalid, then we should not be adding more write requests to the commit list. Instead, those writes should be replayed after requesting a new layout. Signed-off-by: Trond Myklebust --- fs/nfs/callback_proc.c | 2 ++ fs/nfs/direct.c | 12 ++++++++++++ fs/nfs/pnfs.c | 3 +++ fs/nfs/pnfs.h | 6 ++++++ fs/nfs/pnfs_nfs.c | 5 +++++ fs/nfs/write.c | 9 +++++++++ include/linux/nfs_xdr.h | 2 ++ 7 files changed, 39 insertions(+) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index e4dbab5dce6e1..2be8b252e3b1b 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -233,6 +233,8 @@ static u32 initiate_file_draining(struct nfs_client *clp, unlock: spin_unlock(&ino->i_lock); pnfs_free_lseg_list(&free_me_list); + /* Free all lsegs that are attached to commit buckets */ + nfs_commit_inode(ino, 0); pnfs_put_layout_hdr(lo); trace_nfs4_cb_layoutrecall_file(clp, &args->cbl_fh, ino, &args->cbl_stateid, -rv); diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 14f77df79c258..a9a93927fe3e3 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -721,8 +721,20 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) nfs_direct_write_complete(dreq, data->inode); } +static void nfs_direct_resched_write(struct nfs_commit_info *cinfo, + struct nfs_page *req) +{ + struct nfs_direct_req *dreq = cinfo->dreq; + + spin_lock(&dreq->lock); + dreq->flags = NFS_ODIRECT_RESCHED_WRITES; + spin_unlock(&dreq->lock); + nfs_mark_request_commit(req, NULL, cinfo, 0); +} + static const struct nfs_commit_completion_ops nfs_direct_commit_completion_ops = { .completion = nfs_direct_commit_complete, + .resched_write = nfs_direct_resched_write, }; static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 360fe95c97b5d..6593be7c01291 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -703,6 +703,8 @@ pnfs_layout_free_bulk_destroy_list(struct list_head *layout_list, ret = -EAGAIN; spin_unlock(&inode->i_lock); pnfs_free_lseg_list(&lseg_list); + /* Free all lsegs that are attached to commit buckets */ + nfs_commit_inode(inode, 0); pnfs_put_layout_hdr(lo); iput(inode); } @@ -1811,6 +1813,7 @@ void pnfs_error_mark_layout_for_return(struct inode *inode, pnfs_mark_matching_lsegs_return(lo, &free_me, &range); spin_unlock(&inode->i_lock); pnfs_free_lseg_list(&free_me); + nfs_commit_inode(inode, 0); } EXPORT_SYMBOL_GPL(pnfs_error_mark_layout_for_return); diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index d93c2ebc0fd35..4bd7faf9ce507 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -412,6 +412,12 @@ pnfs_get_lseg(struct pnfs_layout_segment *lseg) return lseg; } +static inline bool +pnfs_is_valid_lseg(struct pnfs_layout_segment *lseg) +{ + return test_bit(NFS_LSEG_VALID, &lseg->pls_flags) != 0; +} + /* Return true if a layout driver is being used for this mountpoint */ static inline int pnfs_enabled_sb(struct nfs_server *nfss) { diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c index 3c8e3a44e6ead..81ac6480f9e77 100644 --- a/fs/nfs/pnfs_nfs.c +++ b/fs/nfs/pnfs_nfs.c @@ -868,6 +868,11 @@ pnfs_layout_mark_request_commit(struct nfs_page *req, buckets = cinfo->ds->buckets; list = &buckets[ds_commit_idx].written; if (list_empty(list)) { + if (!pnfs_is_valid_lseg(lseg)) { + spin_unlock(cinfo->lock); + cinfo->completion_ops->resched_write(cinfo, req); + return; + } /* Non-empty buckets hold a reference on the lseg. That ref * is normally transferred to the COMMIT call and released * there. It could also be released if the last req is pulled diff --git a/fs/nfs/write.c b/fs/nfs/write.c index ae29f082c9c23..0aa8d6f23b4cc 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -1676,6 +1676,13 @@ void nfs_retry_commit(struct list_head *page_list, } EXPORT_SYMBOL_GPL(nfs_retry_commit); +static void +nfs_commit_resched_write(struct nfs_commit_info *cinfo, + struct nfs_page *req) +{ + __set_page_dirty_nobuffers(req->wb_page); +} + /* * Commit dirty pages */ @@ -1777,6 +1784,7 @@ static const struct rpc_call_ops nfs_commit_ops = { static const struct nfs_commit_completion_ops nfs_commit_completion_ops = { .completion = nfs_commit_release_pages, + .resched_write = nfs_commit_resched_write, }; int nfs_generic_commit_list(struct inode *inode, struct list_head *head, @@ -1823,6 +1831,7 @@ out_mark_dirty: __mark_inode_dirty(inode, I_DIRTY_DATASYNC); return res; } +EXPORT_SYMBOL_GPL(nfs_commit_inode); int nfs_write_inode(struct inode *inode, struct writeback_control *wbc) { diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index a8905b7d4d7f7..bee3e60a7006d 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1420,10 +1420,12 @@ struct nfs_mds_commit_info { struct list_head list; }; +struct nfs_commit_info; struct nfs_commit_data; struct nfs_inode; struct nfs_commit_completion_ops { void (*completion) (struct nfs_commit_data *data); + void (*resched_write) (struct nfs_commit_info *, struct nfs_page *); }; struct nfs_commit_info { -- GitLab From 138a2935dc9783b131d9647c3bddb22ae5c84d77 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 1 Oct 2015 17:17:06 -0400 Subject: [PATCH 2160/2855] NFS: Relax requirements in nfs_flush_incompatible If two processes share the same credentials and NFSv4 open stateid, then allow them both to dirty the same page, even if their nfs_open_context differs. Signed-off-by: Trond Myklebust --- fs/nfs/internal.h | 6 ++++++ fs/nfs/pagelist.c | 6 ------ fs/nfs/write.c | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 99a2919047e9b..870e2ba7ba49e 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -264,6 +264,12 @@ static inline bool nfs_pgio_has_mirroring(struct nfs_pageio_descriptor *desc) return desc->pg_mirror_count > 1; } +static inline bool nfs_match_open_context(const struct nfs_open_context *ctx1, + const struct nfs_open_context *ctx2) +{ + return ctx1->cred == ctx2->cred && ctx1->state == ctx2->state; +} + /* nfs2xdr.c */ extern struct rpc_procinfo nfs_procedures[]; extern int nfs2_decode_dirent(struct xdr_stream *, diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 452a011ba0d8a..c3a78450a2395 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -903,12 +903,6 @@ static void nfs_pageio_cleanup_mirroring(struct nfs_pageio_descriptor *pgio) pgio->pg_mirrors_dynamic = NULL; } -static bool nfs_match_open_context(const struct nfs_open_context *ctx1, - const struct nfs_open_context *ctx2) -{ - return ctx1->cred == ctx2->cred && ctx1->state == ctx2->state; -} - static bool nfs_match_lock_context(const struct nfs_lock_context *l1, const struct nfs_lock_context *l2) { diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 0aa8d6f23b4cc..2c26e04d93968 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -1130,7 +1130,8 @@ int nfs_flush_incompatible(struct file *file, struct page *page) if (req == NULL) return 0; l_ctx = req->wb_lock_context; - do_flush = req->wb_page != page || req->wb_context != ctx; + do_flush = req->wb_page != page || + !nfs_match_open_context(req->wb_context, ctx); /* for now, flush if more than 1 request in page_group */ do_flush |= req->wb_this_page != req; if (l_ctx && flctx && -- GitLab From 8d4ea29b6426470456ee9daee64bac55a3b13289 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 31 Dec 2015 13:08:02 -0800 Subject: [PATCH 2161/2855] f2fs: write pending bios when cp_error is set When testing ioc_shutdown, put_super is able to be hanged by waiting for writebacking pages as follows. INFO: task umount:2723 blocked for more than 120 seconds. Tainted: G O 4.4.0-rc3+ #8 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. umount D ffff88000859f9d8 0 2723 2110 0x00000000 ffff88000859f9d8 0000000000000000 0000000000000000 ffffffff81e11540 ffff880078c225c0 ffff8800085a0000 ffff88007fc17440 7fffffffffffffff ffffffff818239f0 ffff88000859fb48 ffff88000859f9f0 ffffffff8182310c Call Trace: [] ? bit_wait+0x50/0x50 [] schedule+0x3c/0x90 [] schedule_timeout+0x2d9/0x430 [] ? mark_held_locks+0x6f/0xa0 [] ? ktime_get+0x7d/0x140 [] ? bit_wait+0x50/0x50 [] ? kvm_clock_get_cycles+0x25/0x30 [] ? ktime_get+0xac/0x140 [] ? bit_wait+0x50/0x50 [] io_schedule_timeout+0xa4/0x110 [] bit_wait_io+0x35/0x50 [] __wait_on_bit+0x5d/0x90 [] wait_on_page_bit+0xcb/0xf0 [] ? autoremove_wake_function+0x40/0x40 [] truncate_inode_pages_range+0x4bc/0x840 [] truncate_inode_pages_final+0x4d/0x60 [] f2fs_evict_inode+0x75/0x400 [f2fs] [] evict+0xbc/0x190 [] iput+0x229/0x2c0 [] f2fs_put_super+0x105/0x1a0 [f2fs] [] generic_shutdown_super+0x6a/0xf0 [] kill_block_super+0x27/0x70 [] kill_f2fs_super+0x20/0x30 [f2fs] [] deactivate_locked_super+0x43/0x70 [] deactivate_super+0x5c/0x60 [] cleanup_mnt+0x3f/0x90 [] __cleanup_mnt+0x12/0x20 [] task_work_run+0x73/0xa0 [] exit_to_usermode_loop+0xcc/0xd0 [] syscall_return_slowpath+0xcc/0xe0 [] int_ret_from_sys_call+0x25/0x9f Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 2 +- fs/f2fs/data.c | 2 +- fs/f2fs/node.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 6b89ac69b7e47..5dbafd5e83d9e 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -237,7 +237,7 @@ static int f2fs_write_meta_page(struct page *page, dec_page_count(sbi, F2FS_DIRTY_META); unlock_page(page); - if (wbc->for_reclaim) + if (wbc->for_reclaim || unlikely(f2fs_cp_error(sbi))) f2fs_submit_merged_bio(sbi, META, WRITE); return 0; diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 14b40a9db5b39..4851e84d02837 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1179,7 +1179,7 @@ out: unlock_page(page); if (need_balance_fs) f2fs_balance_fs(sbi); - if (wbc->for_reclaim) { + if (wbc->for_reclaim || unlikely(f2fs_cp_error(sbi))) { f2fs_submit_merged_bio(sbi, DATA, WRITE); remove_dirty_inode(inode); } diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 94d9753f8c532..669c44ef93034 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1368,7 +1368,7 @@ static int f2fs_write_node_page(struct page *page, up_read(&sbi->node_write); unlock_page(page); - if (wbc->for_reclaim) + if (wbc->for_reclaim || unlikely(f2fs_cp_error(sbi))) f2fs_submit_merged_bio(sbi, NODE, WRITE); return 0; -- GitLab From c46a155bdf3c8877719aa63d1bf1d6e79e2a9764 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 31 Dec 2015 13:49:17 -0800 Subject: [PATCH 2162/2855] f2fs: use IPU for fdatasync This patch fixes missing IPU condition when fdatasync is called. With this patch, fdatasync is able to avoid additional node writes for recovery. Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index b04ab40ddc737..e3d32f6b4b4f5 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -202,7 +202,7 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) trace_f2fs_sync_file_enter(inode); /* if fdatasync is triggered, let's do in-place-update */ - if (get_dirty_pages(inode) <= SM_I(sbi)->min_fsync_blocks) + if (datasync || get_dirty_pages(inode) <= SM_I(sbi)->min_fsync_blocks) set_inode_flag(fi, FI_NEED_IPU); ret = filemap_write_and_wait_range(inode->i_mapping, start, end); clear_inode_flag(fi, FI_NEED_IPU); -- GitLab From 5c5e09f623d5984532a74b90d3d24e1caa99bc9f Mon Sep 17 00:00:00 2001 From: Leilk Liu Date: Thu, 31 Dec 2015 10:59:03 +0800 Subject: [PATCH 2163/2855] spi: mtk: Add bindings for mediatek MT2701 soc platform This patch adds a DT binding documentation for the MT2701 soc. Signed-off-by: Leilk Liu Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/spi-mt65xx.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt index 60a183c16e6e8..e43f4cf4cf35c 100644 --- a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt +++ b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt @@ -2,9 +2,10 @@ Binding for MTK SPI controller Required properties: - compatible: should be one of the following. - - mediatek,mt8173-spi: for mt8173 platforms - - mediatek,mt8135-spi: for mt8135 platforms + - mediatek,mt2701-spi: for mt2701 platforms - mediatek,mt6589-spi: for mt6589 platforms + - mediatek,mt8135-spi: for mt8135 platforms + - mediatek,mt8173-spi: for mt8173 platforms - #address-cells: should be 1. -- GitLab From 4eaf6f730355ce3725dd8c98e62696ec4c507e9b Mon Sep 17 00:00:00 2001 From: Leilk Liu Date: Thu, 31 Dec 2015 10:59:00 +0800 Subject: [PATCH 2164/2855] spi: mediatek: merge all identical compat to mtk_common_compat This patch merge all identical compat into on mtk_common_compat and used for all compatible soc. Signed-off-by: Leilk Liu Reviewed-by: Matthias Brugger Signed-off-by: Mark Brown --- drivers/spi/spi-mt65xx.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index 00a36dacfe2fa..917c564edd4a7 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c @@ -95,8 +95,7 @@ struct mtk_spi { const struct mtk_spi_compatible *dev_comp; }; -static const struct mtk_spi_compatible mt6589_compat; -static const struct mtk_spi_compatible mt8135_compat; +static const struct mtk_spi_compatible mtk_common_compat; static const struct mtk_spi_compatible mt8173_compat = { .need_pad_sel = true, .must_tx = true, @@ -112,9 +111,15 @@ static const struct mtk_chip_config mtk_default_chip_info = { }; static const struct of_device_id mtk_spi_of_match[] = { - { .compatible = "mediatek,mt6589-spi", .data = (void *)&mt6589_compat }, - { .compatible = "mediatek,mt8135-spi", .data = (void *)&mt8135_compat }, - { .compatible = "mediatek,mt8173-spi", .data = (void *)&mt8173_compat }, + { .compatible = "mediatek,mt6589-spi", + .data = (void *)&mtk_common_compat, + }, + { .compatible = "mediatek,mt8135-spi", + .data = (void *)&mtk_common_compat, + }, + { .compatible = "mediatek,mt8173-spi", + .data = (void *)&mt8173_compat, + }, {} }; MODULE_DEVICE_TABLE(of, mtk_spi_of_match); -- GitLab From 15bcdefdc71a791ce0308989ed3fc43b4f973c7f Mon Sep 17 00:00:00 2001 From: Leilk Liu Date: Thu, 31 Dec 2015 10:59:01 +0800 Subject: [PATCH 2165/2855] spi: mediatek: Add spi support for mt2701 IC This patch adds spi support for mt2701 IC. Signed-off-by: Leilk Liu Signed-off-by: Mark Brown --- drivers/spi/spi-mt65xx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index 917c564edd4a7..dedc4dd9d78ac 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c @@ -111,6 +111,9 @@ static const struct mtk_chip_config mtk_default_chip_info = { }; static const struct of_device_id mtk_spi_of_match[] = { + { .compatible = "mediatek,mt2701-spi", + .data = (void *)&mtk_common_compat, + }, { .compatible = "mediatek,mt6589-spi", .data = (void *)&mtk_common_compat, }, -- GitLab From c00ba5548500a6f5dfd3c0e0300b338b584018ba Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 31 Dec 2015 15:24:14 -0800 Subject: [PATCH 2166/2855] f2fs: monitor zombie_tree count This patch adds an entry to show the number of zombie extent_tree. Signed-off-by: Jaegeuk Kim --- fs/f2fs/debug.c | 5 +++-- fs/f2fs/f2fs.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index ed5dfcc8886f0..b73e8e133c8b7 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -39,6 +39,7 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->hit_total = si->hit_largest + si->hit_cached + si->hit_rbtree; si->total_ext = atomic64_read(&sbi->total_hit_ext); si->ext_tree = atomic_read(&sbi->total_ext_tree); + si->zombie_tree = atomic_read(&sbi->total_zombie_tree); si->ext_node = atomic_read(&sbi->total_ext_node); si->ndirty_node = get_pages(sbi, F2FS_DIRTY_NODES); si->ndirty_dent = get_pages(sbi, F2FS_DIRTY_DENTS); @@ -292,8 +293,8 @@ static int stat_show(struct seq_file *s, void *v) !si->total_ext ? 0 : div64_u64(si->hit_total * 100, si->total_ext), si->hit_total, si->total_ext); - seq_printf(s, " - Inner Struct Count: tree: %d, node: %d\n", - si->ext_tree, si->ext_node); + seq_printf(s, " - Inner Struct Count: tree: %d(%d), node: %d\n", + si->ext_tree, si->zombie_tree, si->ext_node); seq_puts(s, "\nBalancing F2FS Async:\n"); seq_printf(s, " - inmem: %4d, wb: %4d\n", si->inmem_pages, si->wb_pages); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index a3395088e0f0e..d81bf5a437147 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1890,7 +1890,7 @@ struct f2fs_stat_info { int main_area_segs, main_area_sections, main_area_zones; unsigned long long hit_largest, hit_cached, hit_rbtree; unsigned long long hit_total, total_ext; - int ext_tree, ext_node; + int ext_tree, zombie_tree, ext_node; int ndirty_node, ndirty_meta; int ndirty_dent, ndirty_dirs, ndirty_data, ndirty_files; int nats, dirty_nats, sits, dirty_sits, fnids; -- GitLab From 137d09f002df7d4e52513d75f8910945a6c1bb08 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 31 Dec 2015 15:02:16 -0800 Subject: [PATCH 2167/2855] f2fs: introduce zombie list for fast shrinking extent trees This patch removes refcount, and instead, adds zombie_list to shrink directly without radix tree traverse. Signed-off-by: Jaegeuk Kim --- fs/f2fs/extent_cache.c | 49 ++++++++++++++++++------------------------ fs/f2fs/f2fs.h | 3 ++- 2 files changed, 23 insertions(+), 29 deletions(-) diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index b37184f720e89..4dee2be9a648c 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -68,13 +68,13 @@ static struct extent_tree *__grab_extent_tree(struct inode *inode) et->root = RB_ROOT; et->cached_en = NULL; rwlock_init(&et->lock); - atomic_set(&et->refcount, 0); + INIT_LIST_HEAD(&et->list); et->count = 0; atomic_inc(&sbi->total_ext_tree); } else { atomic_dec(&sbi->total_zombie_tree); + list_del_init(&et->list); } - atomic_inc(&et->refcount); up_write(&sbi->extent_tree_lock); /* never died until evict_inode */ @@ -551,9 +551,9 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode, unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) { struct extent_tree *treevec[EXT_TREE_VEC_SIZE]; + struct extent_tree *et, *next; struct extent_node *en, *tmp; unsigned long ino = F2FS_ROOT_INO(sbi); - struct radix_tree_root *root = &sbi->extent_tree_root; unsigned int found; unsigned int node_cnt = 0, tree_cnt = 0; int remained; @@ -569,29 +569,20 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) goto out; /* 1. remove unreferenced extent tree */ - while ((found = radix_tree_gang_lookup(root, - (void **)treevec, ino, EXT_TREE_VEC_SIZE))) { - unsigned i; - - ino = treevec[found - 1]->ino + 1; - for (i = 0; i < found; i++) { - struct extent_tree *et = treevec[i]; - - if (!atomic_read(&et->refcount)) { - write_lock(&et->lock); - node_cnt += __free_extent_tree(sbi, et, true); - write_unlock(&et->lock); + list_for_each_entry_safe(et, next, &sbi->zombie_list, list) { + write_lock(&et->lock); + node_cnt += __free_extent_tree(sbi, et, true); + write_unlock(&et->lock); - radix_tree_delete(root, et->ino); - kmem_cache_free(extent_tree_slab, et); - atomic_dec(&sbi->total_ext_tree); - atomic_dec(&sbi->total_zombie_tree); - tree_cnt++; + list_del_init(&et->list); + radix_tree_delete(&sbi->extent_tree_root, et->ino); + kmem_cache_free(extent_tree_slab, et); + atomic_dec(&sbi->total_ext_tree); + atomic_dec(&sbi->total_zombie_tree); + tree_cnt++; - if (node_cnt + tree_cnt >= nr_shrink) - goto unlock_out; - } - } + if (node_cnt + tree_cnt >= nr_shrink) + goto unlock_out; } up_write(&sbi->extent_tree_lock); @@ -619,7 +610,7 @@ free_node: */ ino = F2FS_ROOT_INO(sbi); - while ((found = radix_tree_gang_lookup(root, + while ((found = radix_tree_gang_lookup(&sbi->extent_tree_root, (void **)treevec, ino, EXT_TREE_VEC_SIZE))) { unsigned i; @@ -670,8 +661,10 @@ void f2fs_destroy_extent_tree(struct inode *inode) return; if (inode->i_nlink && !is_bad_inode(inode) && et->count) { - atomic_dec(&et->refcount); + down_write(&sbi->extent_tree_lock); + list_add_tail(&et->list, &sbi->zombie_list); atomic_inc(&sbi->total_zombie_tree); + up_write(&sbi->extent_tree_lock); return; } @@ -680,8 +673,7 @@ void f2fs_destroy_extent_tree(struct inode *inode) /* delete extent tree entry in radix tree */ down_write(&sbi->extent_tree_lock); - atomic_dec(&et->refcount); - f2fs_bug_on(sbi, atomic_read(&et->refcount) || et->count); + f2fs_bug_on(sbi, et->count); radix_tree_delete(&sbi->extent_tree_root, inode->i_ino); kmem_cache_free(extent_tree_slab, et); atomic_dec(&sbi->total_ext_tree); @@ -737,6 +729,7 @@ void init_extent_cache_info(struct f2fs_sb_info *sbi) INIT_LIST_HEAD(&sbi->extent_list); spin_lock_init(&sbi->extent_lock); atomic_set(&sbi->total_ext_tree, 0); + INIT_LIST_HEAD(&sbi->zombie_list); atomic_set(&sbi->total_zombie_tree, 0); atomic_set(&sbi->total_ext_node, 0); } diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index d81bf5a437147..e2990c9786614 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -359,8 +359,8 @@ struct extent_tree { struct rb_root root; /* root of extent info rb-tree */ struct extent_node *cached_en; /* recently accessed extent node */ struct extent_info largest; /* largested extent info */ + struct list_head list; /* to be used by sbi->zombie_list */ rwlock_t lock; /* protect extent info rb-tree */ - atomic_t refcount; /* reference count of rb-tree */ unsigned int count; /* # of extent node in rb-tree*/ }; @@ -764,6 +764,7 @@ struct f2fs_sb_info { struct list_head extent_list; /* lru list for shrinker */ spinlock_t extent_lock; /* locking extent lru list */ atomic_t total_ext_tree; /* extent tree count */ + struct list_head zombie_list; /* extent zombie tree list */ atomic_t total_zombie_tree; /* extent zombie tree count */ atomic_t total_ext_node; /* extent info count */ -- GitLab From 3a9e6433a367211a172cb7b4d5b727c720bd0de0 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 31 Dec 2015 18:20:10 +0800 Subject: [PATCH 2168/2855] f2fs crypto: check CONFIG_F2FS_FS_XATTR for encrypted symlink Add missed CONFIG_F2FS_FS_XATTR for encrypted symlink inode in order to avoid unneeded registry of ->{get,set,remove}xattr. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/namei.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index a629af5cb0ce6..0d61a6864ab10 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -1016,10 +1016,12 @@ const struct inode_operations f2fs_encrypted_symlink_inode_operations = { .put_link = kfree_put_link, .getattr = f2fs_getattr, .setattr = f2fs_setattr, +#ifdef CONFIG_F2FS_FS_XATTR .setxattr = generic_setxattr, .getxattr = generic_getxattr, .listxattr = f2fs_listxattr, .removexattr = generic_removexattr, +#endif }; #endif -- GitLab From c55ebe0e72737dd3d49f6fa3156313e1cab5dcab Mon Sep 17 00:00:00 2001 From: Sifan Naeem Date: Thu, 19 Nov 2015 09:35:13 +0000 Subject: [PATCH 2169/2855] i2c: img-scb: support I2C_M_IGNORE_NAK This commit adds support for the I2C_M_IGNORE_NAK protocol modification. Such behaviour can only be implemented in atomic mode. So, if a transaction contains a message with such flag the drivers switches to atomic mode. The implementation consists simply in treating NAKs as ACKs. Signed-off-by: Sifan Naeem Acked-by: James Hogan Reviewed-by: James Hartley Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-img-scb.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-img-scb.c b/drivers/i2c/busses/i2c-img-scb.c index 3795fe130ef27..c92bcf7c204fd 100644 --- a/drivers/i2c/busses/i2c-img-scb.c +++ b/drivers/i2c/busses/i2c-img-scb.c @@ -750,7 +750,9 @@ static unsigned int img_i2c_atomic(struct img_i2c *i2c, next_cmd = CMD_RET_ACK; break; case CMD_RET_ACK: - if (i2c->line_status & LINESTAT_ACK_DET) { + if (i2c->line_status & LINESTAT_ACK_DET || + (i2c->line_status & LINESTAT_NACK_DET && + i2c->msg.flags & I2C_M_IGNORE_NAK)) { if (i2c->msg.len == 0) { next_cmd = CMD_GEN_STOP; } else if (i2c->msg.flags & I2C_M_RD) { @@ -1017,20 +1019,23 @@ static int img_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, return -EIO; for (i = 0; i < num; i++) { - if (likely(msgs[i].len)) - continue; /* * 0 byte reads are not possible because the slave could try * and pull the data line low, preventing a stop bit. */ - if (unlikely(msgs[i].flags & I2C_M_RD)) + if (!msgs[i].len && msgs[i].flags & I2C_M_RD) return -EIO; /* * 0 byte writes are possible and used for probing, but we * cannot do them in automatic mode, so use atomic mode * instead. + * + * Also, the I2C_M_IGNORE_NAK mode can only be implemented + * in atomic mode. */ - atomic = true; + if (!msgs[i].len || + (msgs[i].flags & I2C_M_IGNORE_NAK)) + atomic = true; } ret = clk_prepare_enable(i2c->scb_clk); -- GitLab From a8c5a8d8c9caa150f0e1faab3884ba48d9cd99fe Mon Sep 17 00:00:00 2001 From: Sifan Naeem Date: Thu, 19 Nov 2015 09:35:14 +0000 Subject: [PATCH 2170/2855] i2c: img-scb: remove fifo EMPTYING interrupts handle Now that we are using the transaction halt interrupt to safely control repeated start transfers, we no longer need to handle the fifo emptying interrupts. Handling this interrupt along with Transaction Halt interrupt can cause erratic behaviour. Signed-off-by: Sifan Naeem Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-img-scb.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/i2c/busses/i2c-img-scb.c b/drivers/i2c/busses/i2c-img-scb.c index c92bcf7c204fd..0af554a16ae5e 100644 --- a/drivers/i2c/busses/i2c-img-scb.c +++ b/drivers/i2c/busses/i2c-img-scb.c @@ -154,7 +154,6 @@ #define INT_TIMING BIT(18) #define INT_FIFO_FULL_FILLING (INT_FIFO_FULL | INT_FIFO_FILLING) -#define INT_FIFO_EMPTY_EMPTYING (INT_FIFO_EMPTY | INT_FIFO_EMPTYING) /* Level interrupts need clearing after handling instead of before */ #define INT_LEVEL 0x01e00 @@ -176,8 +175,7 @@ INT_WRITE_ACK_ERR | \ INT_FIFO_FULL | \ INT_FIFO_FILLING | \ - INT_FIFO_EMPTY | \ - INT_FIFO_EMPTYING) + INT_FIFO_EMPTY) #define INT_ENABLE_MASK_WAITSTOP (INT_SLAVE_EVENT | \ INT_ADDR_ACK_ERR | \ @@ -874,16 +872,8 @@ static unsigned int img_i2c_auto(struct img_i2c *i2c, return ISR_WAITSTOP; } } else { - if (int_status & INT_FIFO_EMPTY_EMPTYING) { - /* - * The write fifo empty indicates that we're in the - * last byte so it's safe to start a new write - * transaction without losing any bytes from the - * previous one. - * see 2.3.7 Repeated Start Transactions. - */ - if ((int_status & INT_FIFO_EMPTY) && - i2c->msg.len == 0) + if (int_status & INT_FIFO_EMPTY) { + if (i2c->msg.len == 0) return ISR_WAITSTOP; img_i2c_write_fifo(i2c); } -- GitLab From dd29207e6ccf6ae705dc01c6db73f3a8cb641400 Mon Sep 17 00:00:00 2001 From: Sifan Naeem Date: Thu, 19 Nov 2015 09:35:15 +0000 Subject: [PATCH 2171/2855] i2c: img-scb: add handle for stop detected interrupt Stop Detected interrupt is triggered when a Stop bit is detected on the bus, which indicates the end of the current transfer. When the end of a transfer is indicated by the Stop Detected interrupt, drain the FIFO and signal completion for the transaction. Signed-off-by: Sifan Naeem Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-img-scb.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-img-scb.c b/drivers/i2c/busses/i2c-img-scb.c index 0af554a16ae5e..f416010a0b493 100644 --- a/drivers/i2c/busses/i2c-img-scb.c +++ b/drivers/i2c/busses/i2c-img-scb.c @@ -152,6 +152,7 @@ #define INT_TRANSACTION_DONE BIT(15) #define INT_SLAVE_EVENT BIT(16) #define INT_TIMING BIT(18) +#define INT_STOP_DETECTED BIT(19) #define INT_FIFO_FULL_FILLING (INT_FIFO_FULL | INT_FIFO_FILLING) @@ -175,7 +176,8 @@ INT_WRITE_ACK_ERR | \ INT_FIFO_FULL | \ INT_FIFO_FILLING | \ - INT_FIFO_EMPTY) + INT_FIFO_EMPTY | \ + INT_STOP_DETECTED) #define INT_ENABLE_MASK_WAITSTOP (INT_SLAVE_EVENT | \ INT_ADDR_ACK_ERR | \ @@ -865,6 +867,13 @@ static unsigned int img_i2c_auto(struct img_i2c *i2c, mod_timer(&i2c->check_timer, jiffies + msecs_to_jiffies(1)); + if (int_status & INT_STOP_DETECTED) { + /* Drain remaining data in FIFO and complete transaction */ + if (i2c->msg.flags & I2C_M_RD) + img_i2c_read_fifo(i2c); + return ISR_COMPLETE(0); + } + if (i2c->msg.flags & I2C_M_RD) { if (int_status & INT_FIFO_FULL_FILLING) { img_i2c_read_fifo(i2c); -- GitLab From c7b0a7c10752fa9a30f719848f4350fa02fdb8e5 Mon Sep 17 00:00:00 2001 From: Sifan Naeem Date: Thu, 19 Nov 2015 09:35:16 +0000 Subject: [PATCH 2172/2855] i2c: img-scb: add handle for Master halt interrupt Master halt is issued after each byte of a transaction is processed in IP version 3.3. Master halt will stall the bus by holding the SCK line low until the halt bit in the scb_general_control is cleared. After the last byte of a transfer is processed we can use the Master Halt interrupt to facilitate a repeated start transfer without issuing a stop bit. Signed-off-by: Sifan Naeem Reviewed-by: James Hartley Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-img-scb.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-img-scb.c b/drivers/i2c/busses/i2c-img-scb.c index f416010a0b493..991118f837be3 100644 --- a/drivers/i2c/busses/i2c-img-scb.c +++ b/drivers/i2c/busses/i2c-img-scb.c @@ -151,6 +151,7 @@ #define INT_FIFO_EMPTYING BIT(12) #define INT_TRANSACTION_DONE BIT(15) #define INT_SLAVE_EVENT BIT(16) +#define INT_MASTER_HALTED BIT(17) #define INT_TIMING BIT(18) #define INT_STOP_DETECTED BIT(19) @@ -177,6 +178,7 @@ INT_FIFO_FULL | \ INT_FIFO_FILLING | \ INT_FIFO_EMPTY | \ + INT_MASTER_HALTED | \ INT_STOP_DETECTED) #define INT_ENABLE_MASK_WAITSTOP (INT_SLAVE_EVENT | \ @@ -875,18 +877,27 @@ static unsigned int img_i2c_auto(struct img_i2c *i2c, } if (i2c->msg.flags & I2C_M_RD) { - if (int_status & INT_FIFO_FULL_FILLING) { + if (int_status & (INT_FIFO_FULL_FILLING | INT_MASTER_HALTED)) { img_i2c_read_fifo(i2c); if (i2c->msg.len == 0) return ISR_WAITSTOP; } } else { - if (int_status & INT_FIFO_EMPTY) { - if (i2c->msg.len == 0) + if (int_status & (INT_FIFO_EMPTY | INT_MASTER_HALTED)) { + if ((int_status & INT_FIFO_EMPTY) && + i2c->msg.len == 0) return ISR_WAITSTOP; img_i2c_write_fifo(i2c); } } + if (int_status & INT_MASTER_HALTED) { + /* + * Release and then enable transaction halt, to + * allow only a single byte to proceed. + */ + img_i2c_transaction_halt(i2c, false); + img_i2c_transaction_halt(i2c, !i2c->last_msg); + } return 0; } -- GitLab From c20821a7f0a55377eccd88c89bd76a2cca22a1b4 Mon Sep 17 00:00:00 2001 From: Sifan Naeem Date: Thu, 19 Nov 2015 09:35:17 +0000 Subject: [PATCH 2173/2855] i2c: img-scb: support repeated starts on IP v3.3 In version 3.3 of the IP when transaction halt is set, an interrupt will be generated after each byte of a transfer instead of after every transfer but before the stop bit. Due to this behaviour we have to be careful that every time we release the transaction halt we have to re-enable it straight away so that we only process a single byte, not doing so will result in all remaining bytes been processed and a stop bit being issued, which will prevent us having a repeated start. This change will have no effect on earlier versions of the IP. Signed-off-by: Sifan Naeem Acked-by: James Hogan Reviewed-by: James Hartley Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-img-scb.c | 45 +++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/busses/i2c-img-scb.c b/drivers/i2c/busses/i2c-img-scb.c index 991118f837be3..379ef9c316645 100644 --- a/drivers/i2c/busses/i2c-img-scb.c +++ b/drivers/i2c/busses/i2c-img-scb.c @@ -513,7 +513,17 @@ static void img_i2c_soft_reset(struct img_i2c *i2c) SCB_CONTROL_CLK_ENABLE | SCB_CONTROL_SOFT_RESET); } -/* enable or release transaction halt for control of repeated starts */ +/* + * Enable or release transaction halt for control of repeated starts. + * In version 3.3 of the IP when transaction halt is set, an interrupt + * will be generated after each byte of a transfer instead of after + * every transfer but before the stop bit. + * Due to this behaviour we have to be careful that every time we + * release the transaction halt we have to re-enable it straight away + * so that we only process a single byte, not doing so will result in + * all remaining bytes been processed and a stop bit being issued, + * which will prevent us having a repeated start. + */ static void img_i2c_transaction_halt(struct img_i2c *i2c, bool t_halt) { u32 val; @@ -582,7 +592,6 @@ static void img_i2c_read(struct img_i2c *i2c) img_i2c_writel(i2c, SCB_READ_ADDR_REG, i2c->msg.addr); img_i2c_writel(i2c, SCB_READ_COUNT_REG, i2c->msg.len); - img_i2c_transaction_halt(i2c, false); mod_timer(&i2c->check_timer, jiffies + msecs_to_jiffies(1)); } @@ -596,7 +605,6 @@ static void img_i2c_write(struct img_i2c *i2c) img_i2c_writel(i2c, SCB_WRITE_ADDR_REG, i2c->msg.addr); img_i2c_writel(i2c, SCB_WRITE_COUNT_REG, i2c->msg.len); - img_i2c_transaction_halt(i2c, false); mod_timer(&i2c->check_timer, jiffies + msecs_to_jiffies(1)); img_i2c_write_fifo(i2c); @@ -862,7 +870,7 @@ static unsigned int img_i2c_auto(struct img_i2c *i2c, /* Enable transaction halt on start bit */ if (!i2c->last_msg && line_status & LINESTAT_START_BIT_DET) { - img_i2c_transaction_halt(i2c, true); + img_i2c_transaction_halt(i2c, !i2c->last_msg); /* we're no longer interested in the slave event */ i2c->int_enable &= ~INT_SLAVE_EVENT; } @@ -1084,12 +1092,31 @@ static int img_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, img_i2c_writel(i2c, SCB_INT_CLEAR_REG, ~0); img_i2c_writel(i2c, SCB_CLEAR_REG, ~0); - if (atomic) + if (atomic) { img_i2c_atomic_start(i2c); - else if (msg->flags & I2C_M_RD) - img_i2c_read(i2c); - else - img_i2c_write(i2c); + } else { + /* + * Enable transaction halt if not the last message in + * the queue so that we can control repeated starts. + */ + img_i2c_transaction_halt(i2c, !i2c->last_msg); + + if (msg->flags & I2C_M_RD) + img_i2c_read(i2c); + else + img_i2c_write(i2c); + + /* + * Release and then enable transaction halt, to + * allow only a single byte to proceed. + * This doesn't have an effect on the initial transfer + * but will allow the following transfers to start + * processing if the previous transfer was marked as + * complete while the i2c block was halted. + */ + img_i2c_transaction_halt(i2c, false); + img_i2c_transaction_halt(i2c, !i2c->last_msg); + } spin_unlock_irqrestore(&i2c->lock, flags); time_left = wait_for_completion_timeout(&i2c->msg_complete, -- GitLab From 0c739738a0eea868655ef26263d5350e6ab8cc69 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 23 Dec 2015 17:56:32 +0100 Subject: [PATCH 2174/2855] i2c: document binding for multi-master case We need this binding because some I2C master drivers will need to adapt their PM settings for the arbitration circuitry. Acked-by: Geert Uytterhoeven Acked-by: Rob Herring Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/i2c/i2c.txt b/Documentation/devicetree/bindings/i2c/i2c.txt index a00219f5ee073..c8d977ed847f3 100644 --- a/Documentation/devicetree/bindings/i2c/i2c.txt +++ b/Documentation/devicetree/bindings/i2c/i2c.txt @@ -54,6 +54,11 @@ wants to support one of the below features, it should adapt the bindings below. "irq" and "wakeup" names are recognized by I2C core, other names are left to individual drivers. +- multi-master + states that there is another master active on this bus. The OS can use + this information to adapt power management to keep the arbitration awake + all the time, for example. + - wakeup-source device can be used as a wakeup source. -- GitLab From 42c0783b89ae4d41ab65e8b0f7ed8cf52e711554 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 23 Dec 2015 17:56:33 +0100 Subject: [PATCH 2175/2855] i2c: rcar: remove macros dealing with flags These macros don't really hide complexity, but C idioms. Removing them makes the code easier to read IMO and make a planned extension easier. Acked-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index b2389c492579c..79fd2aab8fa08 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -122,9 +122,6 @@ struct rcar_i2c_priv { #define rcar_i2c_priv_to_dev(p) ((p)->adap.dev.parent) #define rcar_i2c_is_recv(p) ((p)->msg->flags & I2C_M_RD) -#define rcar_i2c_flags_set(p, f) ((p)->flags |= (f)) -#define rcar_i2c_flags_has(p, f) ((p)->flags & (f)) - #define LOOP_TIMEOUT 1024 @@ -258,7 +255,7 @@ static void rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv) priv->pos = 0; if (priv->msgs_left == 1) - rcar_i2c_flags_set(priv, ID_LAST_MSG); + priv->flags |= ID_LAST_MSG; rcar_i2c_write(priv, ICMAR, (priv->msg->addr << 1) | read); /* @@ -266,7 +263,7 @@ static void rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv) * of ICMSR and ICMCR depends on whether we issue START or REP_START. Since * it didn't cause a drawback for me, let's rather be safe than sorry. */ - if (rcar_i2c_flags_has(priv, ID_FIRST_MSG)) { + if (priv->flags & ID_FIRST_MSG) { rcar_i2c_write(priv, ICMSR, 0); rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START); } else { @@ -438,7 +435,7 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) /* Arbitration lost */ if (msr & MAL) { - rcar_i2c_flags_set(priv, (ID_DONE | ID_ARBLOST)); + priv->flags |= ID_DONE | ID_ARBLOST; goto out; } @@ -446,14 +443,14 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) if (msr & MNR) { /* HW automatically sends STOP after received NACK */ rcar_i2c_write(priv, ICMIER, RCAR_IRQ_STOP); - rcar_i2c_flags_set(priv, ID_NACK); + priv->flags |= ID_NACK; goto out; } /* Stop */ if (msr & MST) { priv->msgs_left--; /* The last message also made it */ - rcar_i2c_flags_set(priv, ID_DONE); + priv->flags |= ID_DONE; goto out; } @@ -463,7 +460,7 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) rcar_i2c_irq_send(priv, msr); out: - if (rcar_i2c_flags_has(priv, ID_DONE)) { + if (priv->flags & ID_DONE) { rcar_i2c_write(priv, ICMIER, 0); rcar_i2c_write(priv, ICMSR, 0); wake_up(&priv->wait); @@ -501,15 +498,14 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, priv->flags = ID_FIRST_MSG; rcar_i2c_prepare_msg(priv); - time_left = wait_event_timeout(priv->wait, - rcar_i2c_flags_has(priv, ID_DONE), + time_left = wait_event_timeout(priv->wait, priv->flags & ID_DONE, num * adap->timeout); if (!time_left) { rcar_i2c_init(priv); ret = -ETIMEDOUT; - } else if (rcar_i2c_flags_has(priv, ID_NACK)) { + } else if (priv->flags & ID_NACK) { ret = -ENXIO; - } else if (rcar_i2c_flags_has(priv, ID_ARBLOST)) { + } else if (priv->flags & ID_ARBLOST) { ret = -EAGAIN; } else { ret = num - priv->msgs_left; /* The number of transfer */ -- GitLab From 7ee24eb508d61e5b74dcc80f644adfb5916f7580 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 23 Dec 2015 17:56:34 +0100 Subject: [PATCH 2176/2855] i2c: rcar: disable PM in multi-master mode In multi master mode, the IP core needs to be always active for arbitration reasons. Get the config from DT and set up PM depending on the config. Acked-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index 79fd2aab8fa08..e596ed9771bc6 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -96,6 +96,9 @@ #define ID_DONE (1 << 2) #define ID_ARBLOST (1 << 3) #define ID_NACK (1 << 4) +/* persistent flags */ +#define ID_P_PM_BLOCKED (1 << 31) +#define ID_P_MASK ID_P_PM_BLOCKED enum rcar_i2c_type { I2C_RCAR_GEN1, @@ -277,7 +280,7 @@ static void rcar_i2c_next_msg(struct rcar_i2c_priv *priv) { priv->msg++; priv->msgs_left--; - priv->flags = 0; + priv->flags &= ID_P_MASK; rcar_i2c_prepare_msg(priv); } @@ -495,7 +498,7 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, /* init first message */ priv->msg = msgs; priv->msgs_left = num; - priv->flags = ID_FIRST_MSG; + priv->flags = (priv->flags & ID_P_MASK) | ID_FIRST_MSG; rcar_i2c_prepare_msg(priv); time_left = wait_event_timeout(priv->wait, priv->flags & ID_DONE, @@ -630,7 +633,13 @@ static int rcar_i2c_probe(struct platform_device *pdev) goto out_pm_put; rcar_i2c_init(priv); - pm_runtime_put(dev); + + /* Don't suspend when multi-master to keep arbitration working */ + if (of_property_read_bool(dev->of_node, "multi-master")) + priv->flags |= ID_P_PM_BLOCKED; + else + pm_runtime_put(dev); + irq = platform_get_irq(pdev, 0); ret = devm_request_irq(dev, irq, rcar_i2c_irq, 0, dev_name(dev), priv); @@ -664,6 +673,8 @@ static int rcar_i2c_remove(struct platform_device *pdev) struct device *dev = &pdev->dev; i2c_del_adapter(&priv->adap); + if (priv->flags & ID_P_PM_BLOCKED) + pm_runtime_put(dev); pm_runtime_disable(dev); return 0; -- GitLab From dd0d0d4de582a6a61c032332c91f4f4cb2bab569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Francillon?= Date: Sat, 2 Jan 2016 20:39:54 -0800 Subject: [PATCH 2177/2855] Input: i8042 - add Fujitsu Lifebook U745 to the nomux list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without i8042.nomux=1 the Elantech touch pad is not working at all on a Fujitsu Lifebook U745. This patch does not seem necessary for all U745 (maybe because of different BIOS versions?). However, it was verified that the patch does not break those (see opensuse bug 883192: https://bugzilla.opensuse.org/show_bug.cgi?id=883192). Signed-off-by: Aurélien Francillon Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-x86ia64io.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index c11556563ef06..68f5f4a0f1e72 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -257,6 +257,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"), }, }, + { + /* Fujitsu Lifebook U745 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745"), + }, + }, { /* Fujitsu T70H */ .matches = { -- GitLab From 7ed5ff82c2f06965652f8d1a17c427ba8d363b92 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 2 Jan 2016 21:04:30 -0800 Subject: [PATCH 2178/2855] Input: bma150 - constify bma150_cfg structure The bma150_cfg structure is never modified, so declare it as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Dmitry Torokhov --- drivers/input/misc/bma150.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/misc/bma150.c b/drivers/input/misc/bma150.c index 1d0e61d7c1318..b0d445390ee44 100644 --- a/drivers/input/misc/bma150.c +++ b/drivers/input/misc/bma150.c @@ -147,7 +147,7 @@ struct bma150_data { * are stated and verified by Bosch Sensortec where they are configured * to provide a generic sensitivity performance. */ -static struct bma150_cfg default_cfg = { +static const struct bma150_cfg default_cfg = { .any_motion_int = 1, .hg_int = 1, .lg_int = 1, -- GitLab From fa68e2777cbc410fafb4e45e92222a63f6e60e57 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Sat, 2 Jan 2016 21:06:53 -0800 Subject: [PATCH 2179/2855] Input: pcap_ts - use to_delayed_work Use to_delayed_work() instead of open-coding it. Signed-off-by: Geliang Tang Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/pcap_ts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/pcap_ts.c b/drivers/input/touchscreen/pcap_ts.c index 23a354a392aed..0e3fc419a3cf8 100644 --- a/drivers/input/touchscreen/pcap_ts.c +++ b/drivers/input/touchscreen/pcap_ts.c @@ -87,7 +87,7 @@ static void pcap_ts_read_xy(void *data, u16 res[2]) static void pcap_ts_work(struct work_struct *work) { - struct delayed_work *dw = container_of(work, struct delayed_work, work); + struct delayed_work *dw = to_delayed_work(work); struct pcap_ts *pcap_ts = container_of(dw, struct pcap_ts, work); u8 ch[2]; -- GitLab From a5f650182bcf956b2b0341575e8bff01e402224f Mon Sep 17 00:00:00 2001 From: Gao Pan Date: Wed, 9 Dec 2015 11:08:22 +0800 Subject: [PATCH 2180/2855] i2c: imx: init bus recovery info before adding i2c adapter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During driver probe, i2c_imx_init_recovery_info() must come before i2c_add_numbered_adapter(), because the get/set_scl() functions are assigned in i2c_register_adapter() under the conditon that bus recover_info are initialized. Otherwise, get/set_scl() function pointers never get assigned. In such case, when i2c_generic_gpio_recovery() is used for bus recovery, there will be kernel crash because bri->set_scl is NULL. The solution to this bug is moving i2c_imx_init_recovery_info() before i2c_register_adapter(). Signed-off-by: Gao Pan Signed-off-by: Fugang Duan Acked-by: Uwe Kleine-König Signed-off-by: Wolfram Sang Cc: stable@kernel.org --- drivers/i2c/busses/i2c-imx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 9bb0b056b25f2..d4d853680ae47 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -1119,6 +1119,8 @@ static int i2c_imx_probe(struct platform_device *pdev) i2c_imx, IMX_I2C_I2CR); imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR); + i2c_imx_init_recovery_info(i2c_imx, pdev); + /* Add I2C adapter */ ret = i2c_add_numbered_adapter(&i2c_imx->adapter); if (ret < 0) { @@ -1126,8 +1128,6 @@ static int i2c_imx_probe(struct platform_device *pdev) goto clk_disable; } - i2c_imx_init_recovery_info(i2c_imx, pdev); - /* Set up platform driver data */ platform_set_drvdata(pdev, i2c_imx); clk_disable_unprepare(i2c_imx->clk); -- GitLab From 588eb93ea49f672cb3ff55d0a5c34df3e1afa7ec Mon Sep 17 00:00:00 2001 From: Gao Pan Date: Fri, 11 Dec 2015 10:24:09 +0800 Subject: [PATCH 2181/2855] i2c: imx: add runtime pm support to improve the performance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In our former i2c driver, i2c clk is enabled and disabled in xfer function, which contributes to power saving. However, the clk enable process brings a busy wait delay until the core is stable. As a result, the performance is sacrificed. To weigh the power consumption and i2c bus performance, runtime pm is the good solution for it. The clk is enabled when a i2c transfer starts, and disabled after a specifically defined delay. If CONFIG_PM is disabled the net result of this patch is that the clock is never disabled. Without the patch the test case (many eeprom reads) executes with approx: real 1m7.735s user 0m0.488s sys 0m20.040s With the patch the same test case (many eeprom reads) executes with approx: real 0m54.241s user 0m0.440s sys 0m5.920s Signed-off-by: Fugang Duan Signed-off-by: Gao Pan Acked-by: Uwe Kleine-König [wsa: sorted includes] Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-imx.c | 90 +++++++++++++++++++++++++++++++----- 1 file changed, 78 insertions(+), 12 deletions(-) diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index d4d853680ae47..3ffdcf4d7b61b 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -120,6 +121,8 @@ #define I2CR_IEN_OPCODE_0 0x0 #define I2CR_IEN_OPCODE_1 I2CR_IEN +#define I2C_PM_TIMEOUT 10 /* ms */ + /** Variables ****************************************************************** *******************************************************************************/ @@ -527,9 +530,6 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx) i2c_imx_set_clk(i2c_imx); - result = clk_prepare_enable(i2c_imx->clk); - if (result) - return result; imx_i2c_write_reg(i2c_imx->ifdr, i2c_imx, IMX_I2C_IFDR); /* Enable I2C controller */ imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR); @@ -582,7 +582,6 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx) /* Disable I2C controller */ temp = i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN, imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); - clk_disable_unprepare(i2c_imx->clk); } static irqreturn_t i2c_imx_isr(int irq, void *dev_id) @@ -901,6 +900,10 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter, dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); + result = pm_runtime_get_sync(i2c_imx->adapter.dev.parent); + if (result < 0) + goto out; + /* Start I2C transfer */ result = i2c_imx_start(i2c_imx); if (result) { @@ -964,6 +967,10 @@ fail0: /* Stop I2C transfer */ i2c_imx_stop(i2c_imx); + pm_runtime_mark_last_busy(i2c_imx->adapter.dev.parent); + pm_runtime_put_autosuspend(i2c_imx->adapter.dev.parent); + +out: dev_dbg(&i2c_imx->adapter.dev, "<%s> exit with: %s: %d\n", __func__, (result < 0) ? "error" : "success msg", (result < 0) ? result : num); @@ -1083,7 +1090,7 @@ static int i2c_imx_probe(struct platform_device *pdev) ret = clk_prepare_enable(i2c_imx->clk); if (ret) { - dev_err(&pdev->dev, "can't enable I2C clock\n"); + dev_err(&pdev->dev, "can't enable I2C clock, ret=%d\n", ret); return ret; } @@ -1107,6 +1114,18 @@ static int i2c_imx_probe(struct platform_device *pdev) /* Set up adapter data */ i2c_set_adapdata(&i2c_imx->adapter, i2c_imx); + /* Set up platform driver data */ + platform_set_drvdata(pdev, i2c_imx); + + pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_TIMEOUT); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + ret = pm_runtime_get_sync(&pdev->dev); + if (ret < 0) + goto rpm_disable; + /* Set up clock divider */ i2c_imx->bitrate = IMX_I2C_BIT_RATE; ret = of_property_read_u32(pdev->dev.of_node, @@ -1125,12 +1144,11 @@ static int i2c_imx_probe(struct platform_device *pdev) ret = i2c_add_numbered_adapter(&i2c_imx->adapter); if (ret < 0) { dev_err(&pdev->dev, "registration failed\n"); - goto clk_disable; + goto rpm_disable; } - /* Set up platform driver data */ - platform_set_drvdata(pdev, i2c_imx); - clk_disable_unprepare(i2c_imx->clk); + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_put_autosuspend(&pdev->dev); dev_dbg(&i2c_imx->adapter.dev, "claimed irq %d\n", irq); dev_dbg(&i2c_imx->adapter.dev, "device resources: %pR\n", res); @@ -1143,6 +1161,12 @@ static int i2c_imx_probe(struct platform_device *pdev) return 0; /* Return OK */ +rpm_disable: + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_dont_use_autosuspend(&pdev->dev); + clk_disable: clk_disable_unprepare(i2c_imx->clk); return ret; @@ -1151,6 +1175,11 @@ clk_disable: static int i2c_imx_remove(struct platform_device *pdev) { struct imx_i2c_struct *i2c_imx = platform_get_drvdata(pdev); + int ret; + + ret = pm_runtime_get_sync(&pdev->dev); + if (ret < 0) + return ret; /* remove adapter */ dev_dbg(&i2c_imx->adapter.dev, "adapter removed\n"); @@ -1165,17 +1194,54 @@ static int i2c_imx_remove(struct platform_device *pdev) imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2CR); imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2SR); + clk_disable_unprepare(i2c_imx->clk); + + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_disable(&pdev->dev); + + return 0; +} + +#ifdef CONFIG_PM +static int i2c_imx_runtime_suspend(struct device *dev) +{ + struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev); + + clk_disable_unprepare(i2c_imx->clk); + return 0; } +static int i2c_imx_runtime_resume(struct device *dev) +{ + struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev); + int ret; + + ret = clk_prepare_enable(i2c_imx->clk); + if (ret) + dev_err(dev, "can't enable I2C clock, ret=%d\n", ret); + + return ret; +} + +static const struct dev_pm_ops i2c_imx_pm_ops = { + SET_RUNTIME_PM_OPS(i2c_imx_runtime_suspend, + i2c_imx_runtime_resume, NULL) +}; +#define I2C_IMX_PM_OPS (&i2c_imx_pm_ops) +#else +#define I2C_IMX_PM_OPS NULL +#endif /* CONFIG_PM */ + static struct platform_driver i2c_imx_driver = { .probe = i2c_imx_probe, .remove = i2c_imx_remove, - .driver = { - .name = DRIVER_NAME, + .driver = { + .name = DRIVER_NAME, + .pm = I2C_IMX_PM_OPS, .of_match_table = i2c_imx_dt_ids, }, - .id_table = imx_i2c_devtype, + .id_table = imx_i2c_devtype, }; static int __init i2c_adap_imx_init(void) -- GitLab From 5b6615398906150dea92fe67a1613a0151ddd0ba Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 1 Nov 2015 14:22:51 -0200 Subject: [PATCH 2182/2855] i2c: imx: Improve message log when DMA is not used When DMA cannot be used, it is better to state that the I2C controller will operate in PIO mode. Signed-off-by: Fabio Estevam Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 3ffdcf4d7b61b..8f62e1f73a6fd 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -349,7 +349,7 @@ fail_tx: dma_release_channel(dma->chan_tx); fail_al: devm_kfree(dev, dma); - dev_info(dev, "can't use DMA\n"); + dev_info(dev, "can't use DMA, using PIO instead.\n"); } static void i2c_imx_dma_callback(void *arg) -- GitLab From e8e712916ceade419ab52900917ed568c7b3ec26 Mon Sep 17 00:00:00 2001 From: Gao Pan Date: Mon, 2 Nov 2015 17:05:30 +0800 Subject: [PATCH 2183/2855] i2c: imx: improve code readability Replace of_get_named_gpio_flags with of_get_named_gpio because the latter has less parameters, which improves code readability. Signed-off-by: Fugang Duan Signed-off-by: Gao Pan Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-imx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 8f62e1f73a6fd..dcea8d276c226 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -1004,10 +1004,8 @@ static void i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx, PINCTRL_STATE_DEFAULT); i2c_imx->pinctrl_pins_gpio = pinctrl_lookup_state(i2c_imx->pinctrl, "gpio"); - rinfo->sda_gpio = of_get_named_gpio_flags(pdev->dev.of_node, - "sda-gpios", 0, NULL); - rinfo->scl_gpio = of_get_named_gpio_flags(pdev->dev.of_node, - "scl-gpios", 0, NULL); + rinfo->sda_gpio = of_get_named_gpio(pdev->dev.of_node, "sda-gpios", 0); + rinfo->scl_gpio = of_get_named_gpio(pdev->dev.of_node, "scl-gpios", 0); if (!gpio_is_valid(rinfo->sda_gpio) || !gpio_is_valid(rinfo->scl_gpio) || -- GitLab From 8378d01f60a95d9205c6da47cb0cd2a594f7e07f Mon Sep 17 00:00:00 2001 From: Liguo Zhang Date: Tue, 15 Dec 2015 15:22:26 +0800 Subject: [PATCH 2184/2855] i2c: mediatek: fix i2c multi transfer issue in high speed mode For mt8173 platform with auto restart support, when doing i2c multi transfer in high speed, we should ignore the first restart irq after the master code, otherwise the first transfer will be discarded. Signed-off-by: Liguo Zhang Reviewed-by: Eddie Huang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mt65xx.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index dc4aac64ac2e9..aec8e6ce38a43 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -155,6 +155,7 @@ struct mtk_i2c { u16 timing_reg; u16 high_speed_reg; unsigned char auto_restart; + bool ignore_restart_irq; const struct mtk_i2c_compatible *dev_comp; }; @@ -539,6 +540,14 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, } } + if (i2c->auto_restart && num >= 2 && i2c->speed_hz > MAX_FS_MODE_SPEED) + /* ignore the first restart irq after the master code, + * otherwise the first transfer will be discarded. + */ + i2c->ignore_restart_irq = true; + else + i2c->ignore_restart_irq = false; + while (left_num--) { if (!msgs->buf) { dev_dbg(i2c->dev, "data buffer is NULL.\n"); @@ -592,8 +601,16 @@ static irqreturn_t mtk_i2c_irq(int irqno, void *dev_id) * i2c->irq_stat need keep the two interrupt value. */ i2c->irq_stat |= intr_stat; - if (i2c->irq_stat & (I2C_TRANSAC_COMP | restart_flag)) - complete(&i2c->msg_complete); + + if (i2c->ignore_restart_irq && (i2c->irq_stat & restart_flag)) { + i2c->ignore_restart_irq = false; + i2c->irq_stat = 0; + writew(I2C_RS_MUL_CNFG | I2C_RS_MUL_TRIG | I2C_TRANSAC_START, + i2c->base + OFFSET_START); + } else { + if (i2c->irq_stat & (I2C_TRANSAC_COMP | restart_flag)) + complete(&i2c->msg_complete); + } return IRQ_HANDLED; } -- GitLab From e2e5a2c618373b55bbb2eca2a6e535dddd04412c Mon Sep 17 00:00:00 2001 From: Kamal Dasu Date: Wed, 16 Dec 2015 15:49:09 -0500 Subject: [PATCH 2185/2855] i2c: brcmstb: Adding support for CM and DSL SoCs Broadcoms DSL, CM (cable modem)and STB I2C core implementation have 8 data in/out registers that can transfer 8 bytes or 32 bytes max. Cable and DSL "Peripheral" i2c cores use single byte per data register and the STB can use 4 byte per data register transfer. Adding support to take care of this difference. Accordingly added the compatible string for SoCs using the "Peripheral" I2C block. Signed-off-by: Kamal Dasu Reviewed-by: Florian Fainelli Signed-off-by: Wolfram Sang --- .../devicetree/bindings/i2c/i2c-brcmstb.txt | 2 +- drivers/i2c/busses/i2c-brcmstb.c | 80 +++++++++++++------ 2 files changed, 57 insertions(+), 25 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c-brcmstb.txt b/Documentation/devicetree/bindings/i2c/i2c-brcmstb.txt index d6f724efdcf21..aeceaceba3c51 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-brcmstb.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-brcmstb.txt @@ -2,7 +2,7 @@ Broadcom stb bsc iic master controller Required properties: -- compatible: should be "brcm,brcmstb-i2c" +- compatible: should be "brcm,brcmstb-i2c" or "brcm,brcmper-i2c" - clock-frequency: 32-bit decimal value of iic master clock freqency in Hz valid values are 375000, 390000, 187500, 200000 93750, 97500, 46875 and 50000 diff --git a/drivers/i2c/busses/i2c-brcmstb.c b/drivers/i2c/busses/i2c-brcmstb.c index 8e9637eea5125..3711df1d45262 100644 --- a/drivers/i2c/busses/i2c-brcmstb.c +++ b/drivers/i2c/busses/i2c-brcmstb.c @@ -25,13 +25,16 @@ #include #define N_DATA_REGS 8 -#define N_DATA_BYTES (N_DATA_REGS * 4) -/* BSC count register field definitions */ -#define BSC_CNT_REG1_MASK 0x0000003f -#define BSC_CNT_REG1_SHIFT 0 -#define BSC_CNT_REG2_MASK 0x00000fc0 -#define BSC_CNT_REG2_SHIFT 6 +/* + * PER_I2C/BSC count register mask depends on 1 byte/4 byte data register + * size. Cable modem and DSL SoCs with Peripheral i2c cores use 1 byte per + * data register whereas STB SoCs use 4 byte per data register transfer, + * account for this difference in total count per transaction and mask to + * use. + */ +#define BSC_CNT_REG1_MASK(nb) (nb == 1 ? GENMASK(3, 0) : GENMASK(5, 0)) +#define BSC_CNT_REG1_SHIFT 0 /* BSC CTL register field definitions */ #define BSC_CTL_REG_DTF_MASK 0x00000003 @@ -41,7 +44,7 @@ #define BSC_CTL_REG_INT_EN_SHIFT 6 #define BSC_CTL_REG_DIV_CLK_MASK 0x00000080 -/* BSC_IIC_ENABLE r/w enable and interrupt field defintions */ +/* BSC_IIC_ENABLE r/w enable and interrupt field definitions */ #define BSC_IIC_EN_RESTART_MASK 0x00000040 #define BSC_IIC_EN_NOSTART_MASK 0x00000020 #define BSC_IIC_EN_NOSTOP_MASK 0x00000010 @@ -169,6 +172,7 @@ struct brcmstb_i2c_dev { struct completion done; bool is_suspended; u32 clk_freq_hz; + int data_regsz; }; /* register accessors for both be and le cpu arch */ @@ -186,6 +190,16 @@ struct brcmstb_i2c_dev { #define bsc_writel(_dev, _val, _reg) \ __bsc_writel(_val, _dev->base + offsetof(struct bsc_regs, _reg)) +static inline int brcmstb_i2c_get_xfersz(struct brcmstb_i2c_dev *dev) +{ + return (N_DATA_REGS * dev->data_regsz); +} + +static inline int brcmstb_i2c_get_data_regsz(struct brcmstb_i2c_dev *dev) +{ + return dev->data_regsz; +} + static void brcmstb_i2c_enable_disable_irq(struct brcmstb_i2c_dev *dev, bool int_en) { @@ -323,14 +337,16 @@ static int brcmstb_i2c_xfer_bsc_data(struct brcmstb_i2c_dev *dev, u8 *buf, unsigned int len, struct i2c_msg *pmsg) { - int cnt, byte, rc; + int cnt, byte, i, rc; enum bsc_xfer_cmd cmd; u32 ctl_reg; struct bsc_regs *pi2creg = dev->bsc_regmap; int no_ack = pmsg->flags & I2C_M_IGNORE_NAK; + int data_regsz = brcmstb_i2c_get_data_regsz(dev); + int xfersz = brcmstb_i2c_get_xfersz(dev); /* see if the transaction needs to check NACK conditions */ - if (no_ack || len <= N_DATA_BYTES) { + if (no_ack || len <= xfersz) { cmd = (pmsg->flags & I2C_M_RD) ? CMD_RD_NOACK : CMD_WR_NOACK; pi2creg->ctlhi_reg |= BSC_CTLHI_REG_IGNORE_ACK_MASK; @@ -348,20 +364,22 @@ static int brcmstb_i2c_xfer_bsc_data(struct brcmstb_i2c_dev *dev, pi2creg->ctl_reg = ctl_reg | DTF_RD_MASK; /* set the read/write length */ - bsc_writel(dev, BSC_CNT_REG1_MASK & (len << BSC_CNT_REG1_SHIFT), - cnt_reg); + bsc_writel(dev, BSC_CNT_REG1_MASK(data_regsz) & + (len << BSC_CNT_REG1_SHIFT), cnt_reg); /* Write data into data_in register */ + if (cmd == CMD_WR || cmd == CMD_WR_NOACK) { - for (cnt = 0; cnt < len; cnt += 4) { + for (cnt = 0, i = 0; cnt < len; cnt += data_regsz, i++) { u32 word = 0; - for (byte = 0; byte < 4; byte++) { - word >>= 8; + for (byte = 0; byte < data_regsz; byte++) { + word >>= BITS_PER_BYTE; if ((cnt + byte) < len) - word |= buf[cnt + byte] << 24; + word |= buf[cnt + byte] << + (BITS_PER_BYTE * (data_regsz - 1)); } - bsc_writel(dev, word, data_in[cnt >> 2]); + bsc_writel(dev, word, data_in[i]); } } @@ -373,14 +391,15 @@ static int brcmstb_i2c_xfer_bsc_data(struct brcmstb_i2c_dev *dev, return rc; } + /* Read data from data_out register */ if (cmd == CMD_RD || cmd == CMD_RD_NOACK) { - for (cnt = 0; cnt < len; cnt += 4) { - u32 data = bsc_readl(dev, data_out[cnt >> 2]); + for (cnt = 0, i = 0; cnt < len; cnt += data_regsz, i++) { + u32 data = bsc_readl(dev, data_out[i]); - for (byte = 0; byte < 4 && + for (byte = 0; byte < data_regsz && (byte + cnt) < len; byte++) { buf[cnt + byte] = data & 0xff; - data >>= 8; + data >>= BITS_PER_BYTE; } } } @@ -448,6 +467,7 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter, int bytes_to_xfer; u8 *tmp_buf; int len = 0; + int xfersz = brcmstb_i2c_get_xfersz(dev); if (dev->is_suspended) return -EBUSY; @@ -482,9 +502,9 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter, /* Perform data transfer */ while (len) { - bytes_to_xfer = min(len, N_DATA_BYTES); + bytes_to_xfer = min(len, xfersz); - if (len <= N_DATA_BYTES && i == (num - 1)) + if (len <= xfersz && i == (num - 1)) brcmstb_set_i2c_start_stop(dev, ~(COND_START_STOP)); @@ -542,8 +562,12 @@ static void brcmstb_i2c_set_bus_speed(struct brcmstb_i2c_dev *dev) static void brcmstb_i2c_set_bsc_reg_defaults(struct brcmstb_i2c_dev *dev) { - /* 4 byte data register */ - dev->bsc_regmap->ctlhi_reg = BSC_CTLHI_REG_DATAREG_SIZE_MASK; + if (brcmstb_i2c_get_data_regsz(dev) == sizeof(u32)) + /* set 4 byte data in/out xfers */ + dev->bsc_regmap->ctlhi_reg = BSC_CTLHI_REG_DATAREG_SIZE_MASK; + else + dev->bsc_regmap->ctlhi_reg &= ~BSC_CTLHI_REG_DATAREG_SIZE_MASK; + bsc_writel(dev, dev->bsc_regmap->ctlhi_reg, ctlhi_reg); /* set bus speed */ brcmstb_i2c_set_bus_speed(dev); @@ -608,6 +632,13 @@ static int brcmstb_i2c_probe(struct platform_device *pdev) dev->clk_freq_hz = bsc_clk[0].hz; } + /* set the data in/out register size for compatible SoCs */ + if (of_device_is_compatible(dev->device->of_node, + "brcmstb,brcmper-i2c")) + dev->data_regsz = sizeof(u8); + else + dev->data_regsz = sizeof(u32); + brcmstb_i2c_set_bsc_reg_defaults(dev); /* Add the i2c adapter */ @@ -674,6 +705,7 @@ static SIMPLE_DEV_PM_OPS(brcmstb_i2c_pm, brcmstb_i2c_suspend, static const struct of_device_id brcmstb_i2c_of_match[] = { {.compatible = "brcm,brcmstb-i2c"}, + {.compatible = "brcm,brcmper-i2c"}, {}, }; MODULE_DEVICE_TABLE(of, brcmstb_i2c_of_match); -- GitLab From 238c44a70c0637765709c78eeaddb2a3d3674b88 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Sun, 27 Dec 2015 18:45:59 +0800 Subject: [PATCH 2186/2855] i2c: designware: use to_pci_dev() Use to_pci_dev() instead of open-coding it. Signed-off-by: Geliang Tang Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-pcidrv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c index 1543d35d228df..7368be000c960 100644 --- a/drivers/i2c/busses/i2c-designware-pcidrv.c +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c @@ -162,7 +162,7 @@ static struct dw_pci_controller dw_pci_controllers[] = { #ifdef CONFIG_PM static int i2c_dw_pci_suspend(struct device *dev) { - struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); + struct pci_dev *pdev = to_pci_dev(dev); i2c_dw_disable(pci_get_drvdata(pdev)); return 0; @@ -170,7 +170,7 @@ static int i2c_dw_pci_suspend(struct device *dev) static int i2c_dw_pci_resume(struct device *dev) { - struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); + struct pci_dev *pdev = to_pci_dev(dev); return i2c_dw_init(pci_get_drvdata(pdev)); } -- GitLab From 66e784130a48653fcc58ebd08b54ece4fbd86bbc Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Sun, 27 Dec 2015 21:15:42 +0800 Subject: [PATCH 2187/2855] i2c: st: use to_platform_device() Use to_platform_device() instead of open-coding it. Signed-off-by: Geliang Tang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-st.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-st.c b/drivers/i2c/busses/i2c-st.c index ea72dca32fdfd..2c3ad8eea1d53 100644 --- a/drivers/i2c/busses/i2c-st.c +++ b/drivers/i2c/busses/i2c-st.c @@ -708,8 +708,7 @@ static int st_i2c_xfer(struct i2c_adapter *i2c_adap, #ifdef CONFIG_PM_SLEEP static int st_i2c_suspend(struct device *dev) { - struct platform_device *pdev = - container_of(dev, struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); struct st_i2c_dev *i2c_dev = platform_get_drvdata(pdev); if (i2c_dev->busy) -- GitLab From e952736586098063fcb734550429b8a81a2c5d25 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Wed, 28 Oct 2015 14:41:30 +0530 Subject: [PATCH 2188/2855] parport: fix a trivial typo s/regsiter/register/ Signed-off-by: Geliang Tang Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/parport/share.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/parport/share.c b/drivers/parport/share.c index 5ce5ef211bdbd..89316965904f6 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -148,7 +148,7 @@ void parport_bus_exit(void) /* * iterates through all the drivers registered with the bus and sends the port * details to the match_port callback of the driver, so that the driver can - * know about the new port that just regsitered with the bus and decide if it + * know about the new port that just registered with the bus and decide if it * wants to use this new port. */ static int driver_check(struct device_driver *dev_drv, void *_port) -- GitLab From 657e24d35479b3edd84706db082f5e18a2270631 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 28 Oct 2015 14:41:31 +0530 Subject: [PATCH 2189/2855] parport: remove trailing white space Trailing white space is not accepted in kernel coding style. Remove them. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/parport/share.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/parport/share.c b/drivers/parport/share.c index 89316965904f6..b7fcb7fdb44ab 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -1,6 +1,6 @@ /* * Parallel-port resource manager code. - * + * * Authors: David Campbell * Tim Waugh * Jose Renau @@ -93,7 +93,7 @@ static struct parport_operations dead_ops = { .ecp_write_data = dead_write, /* ecp */ .ecp_read_data = dead_read, .ecp_write_addr = dead_write, - + .compat_write_data = dead_write, /* compat */ .nibble_read_data = dead_read, /* nibble */ .byte_read_data = dead_read, /* byte */ @@ -689,7 +689,7 @@ void parport_remove_port(struct parport *port) struct pardevice * parport_register_device(struct parport *port, const char *name, int (*pf)(void *), void (*kf)(void *), - void (*irq_func)(void *), + void (*irq_func)(void *), int flags, void *handle) { struct pardevice *tmp; @@ -730,7 +730,7 @@ parport_register_device(struct parport *port, const char *name, if (!try_module_get(port->ops->owner)) { return NULL; } - + parport_get_port (port); tmp = kmalloc(sizeof(struct pardevice), GFP_KERNEL); -- GitLab From 27c6db2655502978c670bd15a1639066ff13c78c Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 28 Oct 2015 14:41:32 +0530 Subject: [PATCH 2190/2855] parport: EXPORT_SYMBOL should follow function All symbols were exported at the end of the file but they are supposed to be exported just after the function. And checkpatch was complaining about it. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/parport/share.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/drivers/parport/share.c b/drivers/parport/share.c index b7fcb7fdb44ab..d85e566548b11 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -343,6 +343,7 @@ void parport_unregister_driver (struct parport_driver *drv) } mutex_unlock(®istration_lock); } +EXPORT_SYMBOL(parport_unregister_driver); static void free_port(struct device *dev) { @@ -378,6 +379,7 @@ struct parport *parport_get_port (struct parport *port) return to_parport_dev(dev); } +EXPORT_SYMBOL(parport_get_port); void parport_del_port(struct parport *port) { @@ -398,6 +400,7 @@ void parport_put_port (struct parport *port) { put_device(&port->bus_dev); } +EXPORT_SYMBOL(parport_put_port); /** * parport_register_port - register a parallel port @@ -508,6 +511,7 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, return tmp; } +EXPORT_SYMBOL(parport_register_port); /** * parport_announce_port - tell device drivers about a parallel port @@ -555,6 +559,7 @@ void parport_announce_port (struct parport *port) } mutex_unlock(®istration_lock); } +EXPORT_SYMBOL(parport_announce_port); /** * parport_remove_port - deregister a parallel port @@ -616,6 +621,7 @@ void parport_remove_port(struct parport *port) parport_put_port(slave); } } +EXPORT_SYMBOL(parport_remove_port); /** * parport_register_device - register a device on a parallel port @@ -810,6 +816,7 @@ parport_register_device(struct parport *port, const char *name, return NULL; } +EXPORT_SYMBOL(parport_register_device); static void free_pardevice(struct device *dev) { @@ -1025,6 +1032,7 @@ void parport_unregister_device(struct pardevice *dev) module_put(port->ops->owner); parport_put_port (port); } +EXPORT_SYMBOL(parport_unregister_device); /** * parport_find_number - find a parallel port by number @@ -1055,6 +1063,7 @@ struct parport *parport_find_number (int number) spin_unlock (&parportlist_lock); return result; } +EXPORT_SYMBOL(parport_find_number); /** * parport_find_base - find a parallel port by base address @@ -1085,6 +1094,7 @@ struct parport *parport_find_base (unsigned long base) spin_unlock (&parportlist_lock); return result; } +EXPORT_SYMBOL(parport_find_base); /** * parport_claim - claim access to a parallel port device @@ -1197,6 +1207,7 @@ blocked: write_unlock_irqrestore (&port->cad_lock, flags); return -EAGAIN; } +EXPORT_SYMBOL(parport_claim); /** * parport_claim_or_block - claim access to a parallel port device @@ -1259,6 +1270,7 @@ int parport_claim_or_block(struct pardevice *dev) dev->waiting = 0; return r; } +EXPORT_SYMBOL(parport_claim_or_block); /** * parport_release - give up access to a parallel port device @@ -1330,6 +1342,7 @@ void parport_release(struct pardevice *dev) pd->wakeup(pd->private); } } +EXPORT_SYMBOL(parport_release); irqreturn_t parport_irq_handler(int irq, void *dev_id) { @@ -1339,22 +1352,6 @@ irqreturn_t parport_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } - -/* Exported symbols for modules. */ - -EXPORT_SYMBOL(parport_claim); -EXPORT_SYMBOL(parport_claim_or_block); -EXPORT_SYMBOL(parport_release); -EXPORT_SYMBOL(parport_register_port); -EXPORT_SYMBOL(parport_announce_port); -EXPORT_SYMBOL(parport_remove_port); -EXPORT_SYMBOL(parport_unregister_driver); -EXPORT_SYMBOL(parport_register_device); -EXPORT_SYMBOL(parport_unregister_device); -EXPORT_SYMBOL(parport_get_port); -EXPORT_SYMBOL(parport_put_port); -EXPORT_SYMBOL(parport_find_number); -EXPORT_SYMBOL(parport_find_base); EXPORT_SYMBOL(parport_irq_handler); MODULE_LICENSE("GPL"); -- GitLab From 7b7a0a30c985145bf4474639d832c94cd63059fa Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 28 Oct 2015 14:41:33 +0530 Subject: [PATCH 2191/2855] parport: fix coding style The multi-line comments were not according to the kernel coding style. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/parport/share.c | 69 ++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/drivers/parport/share.c b/drivers/parport/share.c index d85e566548b11..840c73063a6a4 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -207,8 +207,10 @@ static void detach_driver_chain(struct parport *port) /* Ask kmod for some lowlevel drivers. */ static void get_lowlevel_driver (void) { - /* There is no actual module called this: you should set - * up an alias for modutils. */ + /* + * There is no actual module called this: you should set + * up an alias for modutils. + */ request_module ("parport_lowlevel"); } @@ -728,11 +730,12 @@ parport_register_device(struct parport *port, const char *name, } } - /* We up our own module reference count, and that of the port - on which a device is to be registered, to ensure that - neither of us gets unloaded while we sleep in (e.g.) - kmalloc. - */ + /* + * We up our own module reference count, and that of the port + * on which a device is to be registered, to ensure that + * neither of us gets unloaded while we sleep in (e.g.) + * kmalloc. + */ if (!try_module_get(port->ops->owner)) { return NULL; } @@ -783,9 +786,11 @@ parport_register_device(struct parport *port, const char *name, } tmp->next = port->physport->devices; - wmb(); /* Make sure that tmp->next is written before it's - added to the list; see comments marked 'no locking - required' */ + wmb(); /* + * Make sure that tmp->next is written before it's + * added to the list; see comments marked 'no locking + * required' + */ if (port->physport->devices) port->physport->devices->prev = tmp; port->physport->devices = tmp; @@ -1008,8 +1013,10 @@ void parport_unregister_device(struct pardevice *dev) spin_unlock(&port->pardevice_lock); - /* Make sure we haven't left any pointers around in the wait - * list. */ + /* + * Make sure we haven't left any pointers around in the wait + * list. + */ spin_lock_irq(&port->waitlist_lock); if (dev->waitprev || dev->waitnext || port->waithead == dev) { if (dev->waitprev) @@ -1131,8 +1138,10 @@ int parport_claim(struct pardevice *dev) goto blocked; if (port->cad != oldcad) { - /* I think we'll actually deadlock rather than - get here, but just in case.. */ + /* + * I think we'll actually deadlock rather than + * get here, but just in case.. + */ printk(KERN_WARNING "%s: %s released port when preempted!\n", port->name, oldcad->name); @@ -1185,9 +1194,11 @@ int parport_claim(struct pardevice *dev) return 0; blocked: - /* If this is the first time we tried to claim the port, register an - interest. This is only allowed for devices sleeping in - parport_claim_or_block(), or those with a wakeup function. */ + /* + * If this is the first time we tried to claim the port, register an + * interest. This is only allowed for devices sleeping in + * parport_claim_or_block(), or those with a wakeup function. + */ /* The cad_lock is still held for writing here */ if (dev->waiting & 2 || dev->wakeup) { @@ -1223,8 +1234,10 @@ int parport_claim_or_block(struct pardevice *dev) { int r; - /* Signal to parport_claim() that we can wait even without a - wakeup function. */ + /* + * Signal to parport_claim() that we can wait even without a + * wakeup function. + */ dev->waiting = 2; /* Try to claim the port. If this fails, we need to sleep. */ @@ -1242,8 +1255,10 @@ int parport_claim_or_block(struct pardevice *dev) * See also parport_release() */ - /* If dev->waiting is clear now, an interrupt - gave us the port and we would deadlock if we slept. */ + /* + * If dev->waiting is clear now, an interrupt + * gave us the port and we would deadlock if we slept. + */ if (dev->waiting) { wait_event_interruptible(dev->wait_q, !dev->waiting); @@ -1316,8 +1331,10 @@ void parport_release(struct pardevice *dev) /* Save control registers */ port->ops->save_state(port, dev->state); - /* If anybody is waiting, find out who's been there longest and - then wake them up. (Note: no locking required) */ + /* + * If anybody is waiting, find out who's been there longest and + * then wake them up. (Note: no locking required) + */ /* !!! LOCKING IS NEEDED HERE */ for (pd = port->waithead; pd; pd = pd->waitnext) { if (pd->waiting & 2) { /* sleeping in claim_or_block */ @@ -1334,8 +1351,10 @@ void parport_release(struct pardevice *dev) } } - /* Nobody was waiting, so walk the list to see if anyone is - interested in being woken up. (Note: no locking required) */ + /* + * Nobody was waiting, so walk the list to see if anyone is + * interested in being woken up. (Note: no locking required) + */ /* !!! LOCKING IS NEEDED HERE */ for (pd = port->devices; (port->cad == NULL) && pd; pd = pd->next) { if (pd->wakeup && pd != dev) -- GitLab From b075e6f0510e12b38dbbb66141c5188e8c11ab8b Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 28 Oct 2015 14:41:34 +0530 Subject: [PATCH 2192/2855] parport: code indent should use tabs Code should be indented using tabs and not by space. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/parport/share.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/parport/share.c b/drivers/parport/share.c index 840c73063a6a4..388c138304c11 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -455,7 +455,7 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, tmp->dma = dma; tmp->muxport = tmp->daisy = tmp->muxsel = -1; tmp->modes = 0; - INIT_LIST_HEAD(&tmp->list); + INIT_LIST_HEAD(&tmp->list); tmp->devices = tmp->cad = NULL; tmp->flags = 0; tmp->ops = ops; -- GitLab From a162188f9ca940b84a9ea61d88b50a8f408e0c0c Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 28 Oct 2015 14:41:35 +0530 Subject: [PATCH 2193/2855] parport: quoted strings should not be split user visible strings should not be split as that affects the ability to grep. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/parport/share.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/parport/share.c b/drivers/parport/share.c index 388c138304c11..dcad902f04a47 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -537,9 +537,8 @@ void parport_announce_port (struct parport *port) #endif if (!port->dev) - printk(KERN_WARNING "%s: fix this legacy " - "no-device port driver!\n", - port->name); + printk(KERN_WARNING "%s: fix this legacy no-device port driver!\n", + port->name); parport_proc_register(port); mutex_lock(®istration_lock); @@ -778,8 +777,8 @@ parport_register_device(struct parport *port, const char *name, if (port->physport->devices) { spin_unlock (&port->physport->pardevice_lock); printk (KERN_DEBUG - "%s: cannot grant exclusive access for " - "device %s\n", port->name, name); + "%s: cannot grant exclusive access for device %s\n", + port->name, name); goto out_free_all; } port->flags |= PARPORT_FLAG_EXCL; @@ -1276,9 +1275,8 @@ int parport_claim_or_block(struct pardevice *dev) #ifdef PARPORT_DEBUG_SHARING if (dev->port->physport->cad != dev) - printk(KERN_DEBUG "%s: exiting parport_claim_or_block " - "but %s owns port!\n", dev->name, - dev->port->physport->cad ? + printk(KERN_DEBUG "%s: exiting parport_claim_or_block but %s owns port!\n", + dev->name, dev->port->physport->cad ? dev->port->physport->cad->name:"nobody"); #endif } @@ -1306,8 +1304,8 @@ void parport_release(struct pardevice *dev) write_lock_irqsave(&port->cad_lock, flags); if (port->cad != dev) { write_unlock_irqrestore (&port->cad_lock, flags); - printk(KERN_WARNING "%s: %s tried to release parport " - "when not owner\n", port->name, dev->name); + printk(KERN_WARNING "%s: %s tried to release parport when not owner\n", + port->name, dev->name); return; } -- GitLab From 13efa75d4e5d467f685bd54df310919ae4dc8eac Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 28 Oct 2015 14:41:36 +0530 Subject: [PATCH 2194/2855] parport: remove braces checkpatch was complaining about braces for single statement block. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/parport/share.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/parport/share.c b/drivers/parport/share.c index dcad902f04a47..5dbd6f434a915 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -735,9 +735,8 @@ parport_register_device(struct parport *port, const char *name, * neither of us gets unloaded while we sleep in (e.g.) * kmalloc. */ - if (!try_module_get(port->ops->owner)) { + if (!try_module_get(port->ops->owner)) return NULL; - } parport_get_port (port); @@ -1261,9 +1260,8 @@ int parport_claim_or_block(struct pardevice *dev) if (dev->waiting) { wait_event_interruptible(dev->wait_q, !dev->waiting); - if (signal_pending (current)) { + if (signal_pending (current)) return -EINTR; - } r = 1; } else { r = 0; -- GitLab From 47ec57ec0e52839b92066567e6eb02fb1e60e603 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 28 Oct 2015 14:41:37 +0530 Subject: [PATCH 2195/2855] parport: remove unnecessary out of memory message If kmalloc() or kzalloc() fails we will get sufficient messages in the logs, no need to print these extra messages. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/parport/share.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/parport/share.c b/drivers/parport/share.c index 5dbd6f434a915..441333bd48394 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -444,10 +444,8 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, int ret; tmp = kzalloc(sizeof(struct parport), GFP_KERNEL); - if (!tmp) { - printk(KERN_WARNING "parport: memory squeeze\n"); + if (!tmp) return NULL; - } /* Init our structure */ tmp->base = base; @@ -473,7 +471,6 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, name = kmalloc(15, GFP_KERNEL); if (!name) { - printk(KERN_ERR "parport: memory squeeze\n"); kfree(tmp); return NULL; } @@ -741,16 +738,12 @@ parport_register_device(struct parport *port, const char *name, parport_get_port (port); tmp = kmalloc(sizeof(struct pardevice), GFP_KERNEL); - if (tmp == NULL) { - printk(KERN_WARNING "%s: memory squeeze, couldn't register %s.\n", port->name, name); + if (tmp == NULL) goto out; - } tmp->state = kmalloc(sizeof(struct parport_state), GFP_KERNEL); - if (tmp->state == NULL) { - printk(KERN_WARNING "%s: memory squeeze, couldn't register %s.\n", port->name, name); + if (tmp->state == NULL) goto out_free_pardevice; - } tmp->name = name; tmp->port = port; -- GitLab From b95b9d6cdecabfd99e074d6fda51dc962fd2a1cf Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 28 Oct 2015 14:41:38 +0530 Subject: [PATCH 2196/2855] parport: change style of NULL comparison checkpatch was complaining about NULL comparisons. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/parport/share.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/parport/share.c b/drivers/parport/share.c index 441333bd48394..ccd7df458ebc5 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -738,11 +738,11 @@ parport_register_device(struct parport *port, const char *name, parport_get_port (port); tmp = kmalloc(sizeof(struct pardevice), GFP_KERNEL); - if (tmp == NULL) + if (!tmp) goto out; tmp->state = kmalloc(sizeof(struct parport_state), GFP_KERNEL); - if (tmp->state == NULL) + if (!tmp->state) goto out_free_pardevice; tmp->name = name; @@ -971,7 +971,7 @@ void parport_unregister_device(struct pardevice *dev) struct parport *port; #ifdef PARPORT_PARANOID - if (dev == NULL) { + if (!dev) { printk(KERN_ERR "parport_unregister_device: passed NULL\n"); return; } @@ -1345,7 +1345,7 @@ void parport_release(struct pardevice *dev) * interested in being woken up. (Note: no locking required) */ /* !!! LOCKING IS NEEDED HERE */ - for (pd = port->devices; (port->cad == NULL) && pd; pd = pd->next) { + for (pd = port->devices; !port->cad && pd; pd = pd->next) { if (pd->wakeup && pd != dev) pd->wakeup(pd->private); } -- GitLab From e732b93c3276548bfa903d79c2083b2c8dc552af Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 28 Oct 2015 14:41:39 +0530 Subject: [PATCH 2197/2855] parport: remove unneeded space checkpatch complains that space is prohibited between function name and open parenthesis '('. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/parport/share.c | 94 ++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/drivers/parport/share.c b/drivers/parport/share.c index ccd7df458ebc5..b68f19480dcfd 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -54,16 +54,16 @@ static LIST_HEAD(drivers); static DEFINE_MUTEX(registration_lock); /* What you can do to a port that's gone away.. */ -static void dead_write_lines (struct parport *p, unsigned char b){} -static unsigned char dead_read_lines (struct parport *p) { return 0; } -static unsigned char dead_frob_lines (struct parport *p, unsigned char b, +static void dead_write_lines(struct parport *p, unsigned char b){} +static unsigned char dead_read_lines(struct parport *p) { return 0; } +static unsigned char dead_frob_lines(struct parport *p, unsigned char b, unsigned char c) { return 0; } -static void dead_onearg (struct parport *p){} -static void dead_initstate (struct pardevice *d, struct parport_state *s) { } -static void dead_state (struct parport *p, struct parport_state *s) { } -static size_t dead_write (struct parport *p, const void *b, size_t l, int f) +static void dead_onearg(struct parport *p){} +static void dead_initstate(struct pardevice *d, struct parport_state *s) { } +static void dead_state(struct parport *p, struct parport_state *s) { } +static size_t dead_write(struct parport *p, const void *b, size_t l, int f) { return 0; } -static size_t dead_read (struct parport *p, void *b, size_t l, int f) +static size_t dead_read(struct parport *p, void *b, size_t l, int f) { return 0; } static struct parport_operations dead_ops = { .write_data = dead_write_lines, /* data */ @@ -194,7 +194,7 @@ static void detach_driver_chain(struct parport *port) struct parport_driver *drv; /* caller has exclusive registration_lock */ list_for_each_entry(drv, &drivers, list) - drv->detach (port); + drv->detach(port); /* * call the detach function of the drivers registered in @@ -205,13 +205,13 @@ static void detach_driver_chain(struct parport *port) } /* Ask kmod for some lowlevel drivers. */ -static void get_lowlevel_driver (void) +static void get_lowlevel_driver(void) { /* * There is no actual module called this: you should set * up an alias for modutils. */ - request_module ("parport_lowlevel"); + request_module("parport_lowlevel"); } /* @@ -267,7 +267,7 @@ int __parport_register_driver(struct parport_driver *drv, struct module *owner, const char *mod_name) { if (list_empty(&portlist)) - get_lowlevel_driver (); + get_lowlevel_driver(); if (drv->devmodel) { /* using device model */ @@ -330,7 +330,7 @@ static int port_detach(struct device *dev, void *_drv) * finished by the time this function returns. **/ -void parport_unregister_driver (struct parport_driver *drv) +void parport_unregister_driver(struct parport_driver *drv) { struct parport *port; @@ -375,7 +375,7 @@ static void free_port(struct device *dev) * until the matching parport_put_port() call. **/ -struct parport *parport_get_port (struct parport *port) +struct parport *parport_get_port(struct parport *port) { struct device *dev = get_device(&port->bus_dev); @@ -398,7 +398,7 @@ EXPORT_SYMBOL(parport_del_port); * zero (port is no longer used), free_port is called. **/ -void parport_put_port (struct parport *port) +void parport_put_port(struct parport *port) { put_device(&port->bus_dev); } @@ -458,7 +458,7 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, tmp->flags = 0; tmp->ops = ops; tmp->physport = tmp; - memset (tmp->probe_info, 0, 5 * sizeof (struct parport_device_info)); + memset(tmp->probe_info, 0, 5 * sizeof(struct parport_device_info)); rwlock_init(&tmp->cad_lock); spin_lock_init(&tmp->waitlist_lock); spin_lock_init(&tmp->pardevice_lock); @@ -466,7 +466,7 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, tmp->ieee1284.phase = IEEE1284_PH_FWD_IDLE; sema_init(&tmp->ieee1284.irq, 0); tmp->spintime = parport_default_spintime; - atomic_set (&tmp->ref_count, 1); + atomic_set(&tmp->ref_count, 1); INIT_LIST_HEAD(&tmp->full_list); name = kmalloc(15, GFP_KERNEL); @@ -524,7 +524,7 @@ EXPORT_SYMBOL(parport_register_port); * functions will be called, with @port as the parameter. **/ -void parport_announce_port (struct parport *port) +void parport_announce_port(struct parport *port) { int i; @@ -549,7 +549,7 @@ void parport_announce_port (struct parport *port) spin_unlock_irq(&parportlist_lock); /* Let drivers know that new port(s) has arrived. */ - attach_driver_chain (port); + attach_driver_chain(port); for (i = 1; i < 3; i++) { struct parport *slave = port->slaves[i-1]; if (slave) @@ -585,7 +585,7 @@ void parport_remove_port(struct parport *port) mutex_lock(®istration_lock); /* Spread the word. */ - detach_driver_chain (port); + detach_driver_chain(port); #ifdef CONFIG_PARPORT_1284 /* Forget the IEEE1284.3 topology of the port. */ @@ -700,7 +700,7 @@ parport_register_device(struct parport *port, const char *name, if (port->physport->flags & PARPORT_FLAG_EXCL) { /* An exclusive device is registered. */ - printk (KERN_DEBUG "%s: no more devices allowed\n", + printk(KERN_DEBUG "%s: no more devices allowed\n", port->name); return NULL; } @@ -735,7 +735,7 @@ parport_register_device(struct parport *port, const char *name, if (!try_module_get(port->ops->owner)) return NULL; - parport_get_port (port); + parport_get_port(port); tmp = kmalloc(sizeof(struct pardevice), GFP_KERNEL); if (!tmp) @@ -767,8 +767,8 @@ parport_register_device(struct parport *port, const char *name, if (flags & PARPORT_DEV_EXCL) { if (port->physport->devices) { - spin_unlock (&port->physport->pardevice_lock); - printk (KERN_DEBUG + spin_unlock(&port->physport->pardevice_lock); + printk(KERN_DEBUG "%s: cannot grant exclusive access for device %s\n", port->name, name); goto out_free_all; @@ -807,7 +807,7 @@ parport_register_device(struct parport *port, const char *name, out_free_pardevice: kfree(tmp); out: - parport_put_port (port); + parport_put_port(port); module_put(port->ops->owner); return NULL; @@ -988,7 +988,7 @@ void parport_unregister_device(struct pardevice *dev) if (port->cad == dev) { printk(KERN_DEBUG "%s: %s forgot to release port\n", port->name, dev->name); - parport_release (dev); + parport_release(dev); } spin_lock(&port->pardevice_lock); @@ -1028,7 +1028,7 @@ void parport_unregister_device(struct pardevice *dev) kfree(dev); module_put(port->ops->owner); - parport_put_port (port); + parport_put_port(port); } EXPORT_SYMBOL(parport_unregister_device); @@ -1044,21 +1044,21 @@ EXPORT_SYMBOL(parport_unregister_device); * gives you, use parport_put_port(). */ -struct parport *parport_find_number (int number) +struct parport *parport_find_number(int number) { struct parport *port, *result = NULL; if (list_empty(&portlist)) - get_lowlevel_driver (); + get_lowlevel_driver(); - spin_lock (&parportlist_lock); + spin_lock(&parportlist_lock); list_for_each_entry(port, &portlist, list) { if (port->number == number) { - result = parport_get_port (port); + result = parport_get_port(port); break; } } - spin_unlock (&parportlist_lock); + spin_unlock(&parportlist_lock); return result; } EXPORT_SYMBOL(parport_find_number); @@ -1075,21 +1075,21 @@ EXPORT_SYMBOL(parport_find_number); * gives you, use parport_put_port(). */ -struct parport *parport_find_base (unsigned long base) +struct parport *parport_find_base(unsigned long base) { struct parport *port, *result = NULL; if (list_empty(&portlist)) - get_lowlevel_driver (); + get_lowlevel_driver(); - spin_lock (&parportlist_lock); + spin_lock(&parportlist_lock); list_for_each_entry(port, &portlist, list) { if (port->base == base) { - result = parport_get_port (port); + result = parport_get_port(port); break; } } - spin_unlock (&parportlist_lock); + spin_unlock(&parportlist_lock); return result; } EXPORT_SYMBOL(parport_find_base); @@ -1119,7 +1119,7 @@ int parport_claim(struct pardevice *dev) } /* Preempt any current device */ - write_lock_irqsave (&port->cad_lock, flags); + write_lock_irqsave(&port->cad_lock, flags); if ((oldcad = port->cad) != NULL) { if (oldcad->preempt) { if (oldcad->preempt(oldcad->private)) @@ -1146,7 +1146,7 @@ int parport_claim(struct pardevice *dev) dev->waiting = 0; /* Take ourselves out of the wait list again. */ - spin_lock_irq (&port->waitlist_lock); + spin_lock_irq(&port->waitlist_lock); if (dev->waitprev) dev->waitprev->waitnext = dev->waitnext; else @@ -1155,7 +1155,7 @@ int parport_claim(struct pardevice *dev) dev->waitnext->waitprev = dev->waitprev; else port->waittail = dev->waitprev; - spin_unlock_irq (&port->waitlist_lock); + spin_unlock_irq(&port->waitlist_lock); dev->waitprev = dev->waitnext = NULL; } @@ -1172,7 +1172,7 @@ int parport_claim(struct pardevice *dev) /* If it's a daisy chain device, select it. */ if (dev->daisy >= 0) { /* This could be lazier. */ - if (!parport_daisy_select (port, dev->daisy, + if (!parport_daisy_select(port, dev->daisy, IEEE1284_MODE_COMPAT)) port->daisy = dev->daisy; } @@ -1193,7 +1193,7 @@ blocked: /* The cad_lock is still held for writing here */ if (dev->waiting & 2 || dev->wakeup) { - spin_lock (&port->waitlist_lock); + spin_lock(&port->waitlist_lock); if (test_and_set_bit(0, &dev->waiting) == 0) { /* First add ourselves to the end of the wait list. */ dev->waitnext = NULL; @@ -1204,9 +1204,9 @@ blocked: } else port->waithead = port->waittail = dev; } - spin_unlock (&port->waitlist_lock); + spin_unlock(&port->waitlist_lock); } - write_unlock_irqrestore (&port->cad_lock, flags); + write_unlock_irqrestore(&port->cad_lock, flags); return -EAGAIN; } EXPORT_SYMBOL(parport_claim); @@ -1253,7 +1253,7 @@ int parport_claim_or_block(struct pardevice *dev) if (dev->waiting) { wait_event_interruptible(dev->wait_q, !dev->waiting); - if (signal_pending (current)) + if (signal_pending(current)) return -EINTR; r = 1; } else { @@ -1294,7 +1294,7 @@ void parport_release(struct pardevice *dev) /* Make sure that dev is the current device */ write_lock_irqsave(&port->cad_lock, flags); if (port->cad != dev) { - write_unlock_irqrestore (&port->cad_lock, flags); + write_unlock_irqrestore(&port->cad_lock, flags); printk(KERN_WARNING "%s: %s tried to release parport when not owner\n", port->name, dev->name); return; @@ -1309,7 +1309,7 @@ void parport_release(struct pardevice *dev) /* If this is a daisy device, deselect it. */ if (dev->daisy >= 0) { - parport_daisy_deselect_all (port); + parport_daisy_deselect_all(port); port->daisy = -1; } #endif -- GitLab From e0a7f1f04cd9bb13df7503ba7156ff0a37c9f460 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 28 Oct 2015 14:41:40 +0530 Subject: [PATCH 2198/2855] parport: avoid assignment in if It is not an usual practise to assign some value to a variable in the if test condition. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/parport/share.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/parport/share.c b/drivers/parport/share.c index b68f19480dcfd..3308427ed9f7a 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -1120,7 +1120,8 @@ int parport_claim(struct pardevice *dev) /* Preempt any current device */ write_lock_irqsave(&port->cad_lock, flags); - if ((oldcad = port->cad) != NULL) { + oldcad = port->cad; + if (oldcad) { if (oldcad->preempt) { if (oldcad->preempt(oldcad->private)) goto blocked; -- GitLab From 46c236dc7d1212d7417e6fb0317f91c44c719322 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 26 Dec 2015 22:57:44 +0100 Subject: [PATCH 2199/2855] USB: usbmon: remove assignment from IS_ERR argument The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression e1,e2; statement S1,S2; @@ +e1 = e2; if (IS_ERR( e1 - = e2 )) S1 else S2 // Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/usb/mon/mon_text.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 98e4f63e6823a..e59334b09c412 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c @@ -387,7 +387,8 @@ static ssize_t mon_text_read_t(struct file *file, char __user *buf, struct mon_event_text *ep; struct mon_text_ptr ptr; - if (IS_ERR(ep = mon_text_read_wait(rp, file))) + ep = mon_text_read_wait(rp, file); + if (IS_ERR(ep)) return PTR_ERR(ep); mutex_lock(&rp->printf_lock); ptr.cnt = 0; @@ -414,7 +415,8 @@ static ssize_t mon_text_read_u(struct file *file, char __user *buf, struct mon_event_text *ep; struct mon_text_ptr ptr; - if (IS_ERR(ep = mon_text_read_wait(rp, file))) + ep = mon_text_read_wait(rp, file); + if (IS_ERR(ep)) return PTR_ERR(ep); mutex_lock(&rp->printf_lock); ptr.cnt = 0; -- GitLab From 60d77b3d2229eaf29eddf0d7a7947c3c922b1a4d Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 25 Dec 2015 15:54:32 +0800 Subject: [PATCH 2200/2855] MAINTAINERS: change my email address Freescale has merged with NXP. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index f18cd5e41221e..560d298c58ab7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2759,7 +2759,7 @@ S: Maintained F: Documentation/zh_CN/ CHIPIDEA USB HIGH SPEED DUAL ROLE CONTROLLER -M: Peter Chen +M: Peter Chen T: git git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git L: linux-usb@vger.kernel.org S: Maintained @@ -11162,7 +11162,7 @@ F: Documentation/usb/ohci.txt F: drivers/usb/host/ohci* USB OTG FSM (Finite State Machine) -M: Peter Chen +M: Peter Chen T: git git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git L: linux-usb@vger.kernel.org S: Maintained -- GitLab From a70f9fe52daa839d3925ac7e2dbd0ca758434493 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Mon, 4 Jan 2016 15:55:10 +1100 Subject: [PATCH 2201/2855] xfs: detect and handle invalid iclog size set by mkfs XFS log records have separate fields for the record size and the iclog size used to write the record. mkfs.xfs zeroes the log and writes an unmount record to generate a clean log for the subsequent mount. The userspace record logging code has a bug where the iclog size (h_size) field of the log record is hardcoded to 32k, even if a log stripe unit is specified. The log record length is correctly extended to the stripe unit. Since the kernel log recovery code uses the h_size field to determine the log buffer size, this means that the kernel can attempt to read/process records larger than the buffer size and overrun the buffer. This has historically not been a problem because the kernel doesn't actually run through log recovery in the clean unmount case. Instead, the kernel detects that a single unmount record exists between the head and tail and pushes the tail forward such that the log is viewed as clean (head == tail). Once CRC verification is enabled, however, all records at the head of the log are verified for CRC errors and thus we are susceptible to overrun problems if the iclog field is not correct. While the core problem must be fixed in userspace, this is historical behavior that must be detected in the kernel to avoid severe side effects such as memory corruption and crashes. Update the log buffer size calculation code to detect this condition, warn the user and resize the log buffer based on the log stripe unit. Return a corruption error in cases where this does not look like a clean filesystem (i.e., the log record header indicates more than one operation). Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_log_recover.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index c5ecaacdd2183..4f880d6cfb93d 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4245,7 +4245,7 @@ xlog_do_recovery_pass( xfs_daddr_t blk_no; char *offset; xfs_buf_t *hbp, *dbp; - int error = 0, h_size; + int error = 0, h_size, h_len; int bblks, split_bblks; int hblks, split_hblks, wrapped_hblks; struct hlist_head rhash[XLOG_RHASH_SIZE]; @@ -4274,7 +4274,31 @@ xlog_do_recovery_pass( error = xlog_valid_rec_header(log, rhead, tail_blk); if (error) goto bread_err1; + + /* + * xfsprogs has a bug where record length is based on lsunit but + * h_size (iclog size) is hardcoded to 32k. Now that we + * unconditionally CRC verify the unmount record, this means the + * log buffer can be too small for the record and cause an + * overrun. + * + * Detect this condition here. Use lsunit for the buffer size as + * long as this looks like the mkfs case. Otherwise, return an + * error to avoid a buffer overrun. + */ h_size = be32_to_cpu(rhead->h_size); + h_len = be32_to_cpu(rhead->h_len); + if (h_len > h_size) { + if (h_len <= log->l_mp->m_logbsize && + be32_to_cpu(rhead->h_num_logops) == 1) { + xfs_warn(log->l_mp, + "invalid iclog size (%d bytes), using lsunit (%d bytes)", + h_size, log->l_mp->m_logbsize); + h_size = log->l_mp->m_logbsize; + } else + return -EFSCORRUPTED; + } + if ((be32_to_cpu(rhead->h_version) & XLOG_VERSION_2) && (h_size > XLOG_HEADER_CYCLE_SIZE)) { hblks = h_size / XLOG_HEADER_CYCLE_SIZE; -- GitLab From 9d94901f6e17c4c75d9aeb9efd4213a736c2ef9c Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Mon, 4 Jan 2016 15:55:10 +1100 Subject: [PATCH 2202/2855] xfs: refactor log record unpack and data processing xlog_do_recovery_pass() duplicates a couple function calls related to processing log records because the function must handle wrapping around the end of the log if the head is behind the tail. This is implemented as separate loops. CRC verification pass support will modify how records are processed in both of these loops. Rather than continue to duplicate code, factor the calls that process a log record into a new helper and call that helper from both loops. This patch contains no functional changes. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_log_recover.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 4f880d6cfb93d..236ebaf678f25 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4190,6 +4190,26 @@ xlog_unpack_data( return 0; } +/* + * Unpack and process a log record. + */ +STATIC int +xlog_recover_process( + struct xlog *log, + struct hlist_head rhash[], + struct xlog_rec_header *rhead, + char *dp, + int pass) +{ + int error; + + error = xlog_unpack_data(rhead, dp, log); + if (error) + return error; + + return xlog_recover_process_data(log, rhash, rhead, dp, pass); +} + STATIC int xlog_valid_rec_header( struct xlog *log, @@ -4432,12 +4452,8 @@ xlog_do_recovery_pass( goto bread_err2; } - error = xlog_unpack_data(rhead, offset, log); - if (error) - goto bread_err2; - - error = xlog_recover_process_data(log, rhash, - rhead, offset, pass); + error = xlog_recover_process(log, rhash, rhead, offset, + pass); if (error) goto bread_err2; blk_no += bblks; @@ -4465,12 +4481,7 @@ xlog_do_recovery_pass( if (error) goto bread_err2; - error = xlog_unpack_data(rhead, offset, log); - if (error) - goto bread_err2; - - error = xlog_recover_process_data(log, rhash, - rhead, offset, pass); + error = xlog_recover_process(log, rhash, rhead, offset, pass); if (error) goto bread_err2; blk_no += bblks + hblks; -- GitLab From b94fb2d1780d7cd9d55b21e2bb879a54ed3074cc Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Mon, 4 Jan 2016 15:55:10 +1100 Subject: [PATCH 2203/2855] xfs: refactor and open code log record crc check Log record CRC verification currently occurs during active log recovery, immediately before a log record is unpacked. Therefore, the CRC calculation code is buried within the data unpack function. CRC verification pass support only needs to go so far as check the CRC, but this is not easily allowed as the code is currently organized. Since we now have a new log record processing helper, pull the record CRC verification code out from the unpack helper and open-code it at the top of the new process helper. This facilitates the ability to modify how records are processed based on the type of the current pass. This patch contains no functional changes. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_log_recover.c | 72 +++++++++++++++------------------------- 1 file changed, 26 insertions(+), 46 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 236ebaf678f25..9ec4bbd28d55c 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4118,46 +4118,6 @@ xlog_recover_process_iunlinks( mp->m_dmevmask = mp_dmevmask; } -/* - * Upack the log buffer data and crc check it. If the check fails, issue a - * warning if and only if the CRC in the header is non-zero. This makes the - * check an advisory warning, and the zero CRC check will prevent failure - * warnings from being emitted when upgrading the kernel from one that does not - * add CRCs by default. - * - * When filesystems are CRC enabled, this CRC mismatch becomes a fatal log - * corruption failure - */ -STATIC int -xlog_unpack_data_crc( - struct xlog_rec_header *rhead, - char *dp, - struct xlog *log) -{ - __le32 crc; - - crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len)); - if (crc != rhead->h_crc) { - if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) { - xfs_alert(log->l_mp, - "log record CRC mismatch: found 0x%x, expected 0x%x.", - le32_to_cpu(rhead->h_crc), - le32_to_cpu(crc)); - xfs_hex_dump(dp, 32); - } - - /* - * If we've detected a log record corruption, then we can't - * recover past this point. Abort recovery if we are enforcing - * CRC protection by punting an error back up the stack. - */ - if (xfs_sb_version_hascrc(&log->l_mp->m_sb)) - return -EFSCORRUPTED; - } - - return 0; -} - STATIC int xlog_unpack_data( struct xlog_rec_header *rhead, @@ -4165,11 +4125,6 @@ xlog_unpack_data( struct xlog *log) { int i, j, k; - int error; - - error = xlog_unpack_data_crc(rhead, dp, log); - if (error) - return error; for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) && i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) { @@ -4191,7 +4146,7 @@ xlog_unpack_data( } /* - * Unpack and process a log record. + * CRC check, unpack and process a log record. */ STATIC int xlog_recover_process( @@ -4202,6 +4157,31 @@ xlog_recover_process( int pass) { int error; + __le32 crc; + + /* + * Check the CRC and issue a warning if and only if the CRC in the + * header is non-zero. This is an advisory warning and the zero CRC + * check prevents warnings from being emitted when upgrading the kernel + * from one that does not add CRCs by default. + */ + crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len)); + if (crc != le32_to_cpu(rhead->h_crc)) { + if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) { + xfs_alert(log->l_mp, + "log record CRC mismatch: found 0x%x, expected 0x%x.", + le32_to_cpu(rhead->h_crc), + le32_to_cpu(crc)); + xfs_hex_dump(dp, 32); + } + + /* + * If the filesystem is CRC enabled, this mismatch becomes a + * fatal log corruption failure. + */ + if (xfs_sb_version_hascrc(&log->l_mp->m_sb)) + return -EFSCORRUPTED; + } error = xlog_unpack_data(rhead, dp, log); if (error) -- GitLab From d7f37692e38798797d415153bc186afb2bbac645 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Mon, 4 Jan 2016 15:55:10 +1100 Subject: [PATCH 2204/2855] xfs: return start block of first bad log record during recovery Each log recovery pass walks from the tail block to the head block and processes records appropriately based on the associated log pass type. There are various failure conditions that can occur through this sequence, such as I/O errors, CRC errors, etc. Log torn write detection will perform CRC verification near the head of the log to detect torn writes and trim torn records from the log appropriately. As it is, xlog_do_recovery_pass() only returns an error code in the event of CRC failure, which isn't enough information to trim the head of the log. Update xlog_do_recovery_pass() to optionally return the start block of the associated record when an error occurs. This patch contains no functional changes. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_log_recover.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 9ec4bbd28d55c..e0318e8a0771a 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4239,10 +4239,12 @@ xlog_do_recovery_pass( struct xlog *log, xfs_daddr_t head_blk, xfs_daddr_t tail_blk, - int pass) + int pass, + xfs_daddr_t *first_bad) /* out: first bad log rec */ { xlog_rec_header_t *rhead; xfs_daddr_t blk_no; + xfs_daddr_t rhead_blk; char *offset; xfs_buf_t *hbp, *dbp; int error = 0, h_size, h_len; @@ -4251,6 +4253,7 @@ xlog_do_recovery_pass( struct hlist_head rhash[XLOG_RHASH_SIZE]; ASSERT(head_blk != tail_blk); + rhead_blk = 0; /* * Read the header of the tail block and get the iclog buffer size from @@ -4325,7 +4328,7 @@ xlog_do_recovery_pass( } memset(rhash, 0, sizeof(rhash)); - blk_no = tail_blk; + blk_no = rhead_blk = tail_blk; if (tail_blk > head_blk) { /* * Perform recovery around the end of the physical log. @@ -4436,11 +4439,14 @@ xlog_do_recovery_pass( pass); if (error) goto bread_err2; + blk_no += bblks; + rhead_blk = blk_no; } ASSERT(blk_no >= log->l_logBBsize); blk_no -= log->l_logBBsize; + rhead_blk = blk_no; } /* read first part of physical log */ @@ -4464,13 +4470,19 @@ xlog_do_recovery_pass( error = xlog_recover_process(log, rhash, rhead, offset, pass); if (error) goto bread_err2; + blk_no += bblks + hblks; + rhead_blk = blk_no; } bread_err2: xlog_put_bp(dbp); bread_err1: xlog_put_bp(hbp); + + if (error && first_bad) + *first_bad = rhead_blk; + return error; } @@ -4508,7 +4520,7 @@ xlog_do_log_recovery( INIT_LIST_HEAD(&log->l_buf_cancel_table[i]); error = xlog_do_recovery_pass(log, head_blk, tail_blk, - XLOG_RECOVER_PASS1); + XLOG_RECOVER_PASS1, NULL); if (error != 0) { kmem_free(log->l_buf_cancel_table); log->l_buf_cancel_table = NULL; @@ -4519,7 +4531,7 @@ xlog_do_log_recovery( * When it is complete free the table of buf cancel items. */ error = xlog_do_recovery_pass(log, head_blk, tail_blk, - XLOG_RECOVER_PASS2); + XLOG_RECOVER_PASS2, NULL); #ifdef DEBUG if (!error) { int i; -- GitLab From 6528250b712102a7481c28db535ef251459d1868 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Mon, 4 Jan 2016 15:55:10 +1100 Subject: [PATCH 2205/2855] xfs: support a crc verification only log record pass Log recovery torn write detection uses CRC verification over a range of the active log to identify torn writes. Since the generic log recovery pass code implements a superset of the functionality required for CRC verification, it can be easily modified to support a CRC verification only pass. Create a new CRC pass type and update the log record processing helper to skip everything beyond CRC verification when in this mode. This pass will be invoked in subsequent patches to implement torn write detection. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_log_recover.h | 1 + fs/xfs/xfs_log_recover.c | 24 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/fs/xfs/libxfs/xfs_log_recover.h b/fs/xfs/libxfs/xfs_log_recover.h index 1c55ccbb379d0..8e385f91d6602 100644 --- a/fs/xfs/libxfs/xfs_log_recover.h +++ b/fs/xfs/libxfs/xfs_log_recover.h @@ -60,6 +60,7 @@ typedef struct xlog_recover { */ #define XLOG_BC_TABLE_SIZE 64 +#define XLOG_RECOVER_CRCPASS 0 #define XLOG_RECOVER_PASS1 1 #define XLOG_RECOVER_PASS2 2 diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index e0318e8a0771a..1be2590440965 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4159,13 +4159,27 @@ xlog_recover_process( int error; __le32 crc; + crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len)); + /* - * Check the CRC and issue a warning if and only if the CRC in the - * header is non-zero. This is an advisory warning and the zero CRC - * check prevents warnings from being emitted when upgrading the kernel - * from one that does not add CRCs by default. + * Nothing else to do if this is a CRC verification pass. Just return + * if this a record with a non-zero crc. Unfortunately, mkfs always + * sets h_crc to 0 so we must consider this valid even on v5 supers. + * Otherwise, return EFSBADCRC on failure so the callers up the stack + * know precisely what failed. + */ + if (pass == XLOG_RECOVER_CRCPASS) { + if (rhead->h_crc && crc != le32_to_cpu(rhead->h_crc)) + return -EFSBADCRC; + return 0; + } + + /* + * We're in the normal recovery path. Issue a warning if and only if the + * CRC in the header is non-zero. This is an advisory warning and the + * zero CRC check prevents warnings from being emitted when upgrading + * the kernel from one that does not add CRCs by default. */ - crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len)); if (crc != le32_to_cpu(rhead->h_crc)) { if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) { xfs_alert(log->l_mp, -- GitLab From eed6b462fb2a2661a416c227be6498b0ea2a7aab Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Mon, 4 Jan 2016 15:55:10 +1100 Subject: [PATCH 2206/2855] xfs: refactor log record start detection into a new helper As part of the head/tail discovery process, log recovery locates the head block and then reverse seeks to find the start of the last active record in the log. This is non-trivial as the record itself could have wrapped around the end of the physical log. Log recovery torn write detection potentially needs to walk further behind the last record in the log, as multiple log I/Os can be in-flight at one time during a crash event. Therefore, refactor the reverse log record header search mechanism into a new helper that supports the ability to seek past an arbitrary number of log records (or until the tail is hit). Update the head/tail search mechanism to call the new helper, but otherwise there is no change in log recovery behavior. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_log_recover.c | 118 +++++++++++++++++++++++++++------------ 1 file changed, 83 insertions(+), 35 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 1be2590440965..423c36dbcdead 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -867,6 +867,79 @@ validate_head: return error; } +/* + * Seek backwards in the log for log record headers. + * + * Given a starting log block, walk backwards until we find the provided number + * of records or hit the provided tail block. The return value is the number of + * records encountered or a negative error code. The log block and buffer + * pointer of the last record seen are returned in rblk and rhead respectively. + */ +STATIC int +xlog_rseek_logrec_hdr( + struct xlog *log, + xfs_daddr_t head_blk, + xfs_daddr_t tail_blk, + int count, + struct xfs_buf *bp, + xfs_daddr_t *rblk, + struct xlog_rec_header **rhead, + bool *wrapped) +{ + int i; + int error; + int found = 0; + char *offset = NULL; + xfs_daddr_t end_blk; + + *wrapped = false; + + /* + * Walk backwards from the head block until we hit the tail or the first + * block in the log. + */ + end_blk = head_blk > tail_blk ? tail_blk : 0; + for (i = (int) head_blk - 1; i >= end_blk; i--) { + error = xlog_bread(log, i, 1, bp, &offset); + if (error) + goto out_error; + + if (*(__be32 *) offset == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { + *rblk = i; + *rhead = (struct xlog_rec_header *) offset; + if (++found == count) + break; + } + } + + /* + * If we haven't hit the tail block or the log record header count, + * start looking again from the end of the physical log. Note that + * callers can pass head == tail if the tail is not yet known. + */ + if (tail_blk >= head_blk && found != count) { + for (i = log->l_logBBsize - 1; i >= (int) tail_blk; i--) { + error = xlog_bread(log, i, 1, bp, &offset); + if (error) + goto out_error; + + if (*(__be32 *)offset == + cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { + *wrapped = true; + *rblk = i; + *rhead = (struct xlog_rec_header *) offset; + if (++found == count) + break; + } + } + } + + return found; + +out_error: + return error; +} + /* * Find the sync block number or the tail of the log. * @@ -898,8 +971,7 @@ xlog_find_tail( xfs_daddr_t after_umount_blk; xfs_lsn_t tail_lsn; int hblks; - - found = 0; + bool wrapped = false; /* * Find previous log record @@ -923,37 +995,16 @@ xlog_find_tail( } /* - * Search backwards looking for log record header block + * Search backwards through the log looking for the log record header + * block. This wraps all the way back around to the head so something is + * seriously wrong if we can't find it. */ ASSERT(*head_blk < INT_MAX); - for (i = (int)(*head_blk) - 1; i >= 0; i--) { - error = xlog_bread(log, i, 1, bp, &offset); - if (error) - goto done; - - if (*(__be32 *)offset == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { - found = 1; - break; - } - } - /* - * If we haven't found the log record header block, start looking - * again from the end of the physical log. XXXmiken: There should be - * a check here to make sure we didn't search more than N blocks in - * the previous code. - */ - if (!found) { - for (i = log->l_logBBsize - 1; i >= (int)(*head_blk); i--) { - error = xlog_bread(log, i, 1, bp, &offset); - if (error) - goto done; - - if (*(__be32 *)offset == - cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { - found = 2; - break; - } - } + found = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, bp, &i, + &rhead, &wrapped); + if (found < 0) { + error = found; + goto done; } if (!found) { xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__); @@ -961,9 +1012,6 @@ xlog_find_tail( ASSERT(0); return -EIO; } - - /* find blk_no of tail of log */ - rhead = (xlog_rec_header_t *)offset; *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn)); /* @@ -979,7 +1027,7 @@ xlog_find_tail( log->l_prev_block = i; log->l_curr_block = (int)*head_blk; log->l_curr_cycle = be32_to_cpu(rhead->h_cycle); - if (found == 2) + if (wrapped) log->l_curr_cycle++; atomic64_set(&log->l_tail_lsn, be64_to_cpu(rhead->h_tail_lsn)); atomic64_set(&log->l_last_sync_lsn, be64_to_cpu(rhead->h_lsn)); -- GitLab From 1d4292bfdc77f4f7c520064be15d0c46bd025fd2 Mon Sep 17 00:00:00 2001 From: Jia He Date: Mon, 4 Jan 2016 16:10:19 +1100 Subject: [PATCH 2207/2855] libxfs: Optimize the loop for xfs_bitmap_empty If there is any non zero bit in a long bitmap, it can jump out of the loop and finish the function as soon as possible. Signed-off-by: Jia He Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_bit.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bit.c b/fs/xfs/libxfs/xfs_bit.c index 0e8885a596463..0a94cce5ea356 100644 --- a/fs/xfs/libxfs/xfs_bit.c +++ b/fs/xfs/libxfs/xfs_bit.c @@ -32,13 +32,13 @@ int xfs_bitmap_empty(uint *map, uint size) { uint i; - uint ret = 0; for (i = 0; i < size; i++) { - ret |= map[i]; + if (map[i] != 0) + return 0; } - return (ret == 0); + return 1; } /* -- GitLab From 233135b763db7c64d07b728a9c66745fb0376275 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Mon, 4 Jan 2016 16:10:19 +1100 Subject: [PATCH 2208/2855] xfs: print name of verifier if it fails This adds a name to each buf_ops structure, so that if a verifier fails we can print the type of verifier that failed it. Should be a slight debugging aid, I hope. Signed-off-by: Eric Sandeen Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 2 ++ fs/xfs/libxfs/xfs_alloc_btree.c | 1 + fs/xfs/libxfs/xfs_attr_leaf.c | 1 + fs/xfs/libxfs/xfs_attr_remote.c | 1 + fs/xfs/libxfs/xfs_bmap_btree.c | 1 + fs/xfs/libxfs/xfs_da_btree.c | 1 + fs/xfs/libxfs/xfs_dir2_block.c | 1 + fs/xfs/libxfs/xfs_dir2_data.c | 2 ++ fs/xfs/libxfs/xfs_dir2_leaf.c | 2 ++ fs/xfs/libxfs/xfs_dir2_node.c | 1 + fs/xfs/libxfs/xfs_dquot_buf.c | 1 + fs/xfs/libxfs/xfs_ialloc.c | 1 + fs/xfs/libxfs/xfs_ialloc_btree.c | 1 + fs/xfs/libxfs/xfs_inode_buf.c | 2 ++ fs/xfs/libxfs/xfs_sb.c | 2 ++ fs/xfs/libxfs/xfs_symlink_remote.c | 1 + fs/xfs/xfs_buf.h | 1 + fs/xfs/xfs_error.c | 4 ++-- 18 files changed, 24 insertions(+), 2 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 3479294c1d586..e1e7fe3b5424c 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -535,6 +535,7 @@ xfs_agfl_write_verify( } const struct xfs_buf_ops xfs_agfl_buf_ops = { + .name = "xfs_agfl", .verify_read = xfs_agfl_read_verify, .verify_write = xfs_agfl_write_verify, }; @@ -2339,6 +2340,7 @@ xfs_agf_write_verify( } const struct xfs_buf_ops xfs_agf_buf_ops = { + .name = "xfs_agf", .verify_read = xfs_agf_read_verify, .verify_write = xfs_agf_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index 90de071dd4c2c..eb8bbfe85484e 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -379,6 +379,7 @@ xfs_allocbt_write_verify( } const struct xfs_buf_ops xfs_allocbt_buf_ops = { + .name = "xfs_allocbt", .verify_read = xfs_allocbt_read_verify, .verify_write = xfs_allocbt_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index aa187f7ba2dd3..01a5ecfedfcf1 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -328,6 +328,7 @@ xfs_attr3_leaf_read_verify( } const struct xfs_buf_ops xfs_attr3_leaf_buf_ops = { + .name = "xfs_attr3_leaf", .verify_read = xfs_attr3_leaf_read_verify, .verify_write = xfs_attr3_leaf_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 5ab95ffa4ae9f..f3ed9bf0b0655 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -201,6 +201,7 @@ xfs_attr3_rmt_write_verify( } const struct xfs_buf_ops xfs_attr3_rmt_buf_ops = { + .name = "xfs_attr3_rmt", .verify_read = xfs_attr3_rmt_read_verify, .verify_write = xfs_attr3_rmt_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 6b0cf6546a82f..1637c37bfbaa1 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -720,6 +720,7 @@ xfs_bmbt_write_verify( } const struct xfs_buf_ops xfs_bmbt_buf_ops = { + .name = "xfs_bmbt", .verify_read = xfs_bmbt_read_verify, .verify_write = xfs_bmbt_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index e89a0f8f827ce..097bf7717d805 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -245,6 +245,7 @@ xfs_da3_node_read_verify( } const struct xfs_buf_ops xfs_da3_node_buf_ops = { + .name = "xfs_da3_node", .verify_read = xfs_da3_node_read_verify, .verify_write = xfs_da3_node_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 9c10e2b8cfcb5..aa17cb788946b 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -123,6 +123,7 @@ xfs_dir3_block_write_verify( } const struct xfs_buf_ops xfs_dir3_block_buf_ops = { + .name = "xfs_dir3_block", .verify_read = xfs_dir3_block_read_verify, .verify_write = xfs_dir3_block_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index af71a84f343c3..725fc7841fdeb 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -305,11 +305,13 @@ xfs_dir3_data_write_verify( } const struct xfs_buf_ops xfs_dir3_data_buf_ops = { + .name = "xfs_dir3_data", .verify_read = xfs_dir3_data_read_verify, .verify_write = xfs_dir3_data_write_verify, }; static const struct xfs_buf_ops xfs_dir3_data_reada_buf_ops = { + .name = "xfs_dir3_data_reada", .verify_read = xfs_dir3_data_reada_verify, .verify_write = xfs_dir3_data_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index 3923e1f946976..b887fb2a2bcf5 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -245,11 +245,13 @@ xfs_dir3_leafn_write_verify( } const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops = { + .name = "xfs_dir3_leaf1", .verify_read = xfs_dir3_leaf1_read_verify, .verify_write = xfs_dir3_leaf1_write_verify, }; const struct xfs_buf_ops xfs_dir3_leafn_buf_ops = { + .name = "xfs_dir3_leafn", .verify_read = xfs_dir3_leafn_read_verify, .verify_write = xfs_dir3_leafn_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 70b0cb2fd5560..63ee03db796ca 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -150,6 +150,7 @@ xfs_dir3_free_write_verify( } const struct xfs_buf_ops xfs_dir3_free_buf_ops = { + .name = "xfs_dir3_free", .verify_read = xfs_dir3_free_read_verify, .verify_write = xfs_dir3_free_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_dquot_buf.c b/fs/xfs/libxfs/xfs_dquot_buf.c index 5331b7f0460c7..11cefb2a372a8 100644 --- a/fs/xfs/libxfs/xfs_dquot_buf.c +++ b/fs/xfs/libxfs/xfs_dquot_buf.c @@ -282,6 +282,7 @@ xfs_dquot_buf_write_verify( } const struct xfs_buf_ops xfs_dquot_buf_ops = { + .name = "xfs_dquot", .verify_read = xfs_dquot_buf_read_verify, .verify_write = xfs_dquot_buf_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 70c1db99f6a72..66d702e6b9ff3 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -2572,6 +2572,7 @@ xfs_agi_write_verify( } const struct xfs_buf_ops xfs_agi_buf_ops = { + .name = "xfs_agi", .verify_read = xfs_agi_read_verify, .verify_write = xfs_agi_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index f39b285beb19f..6dd44f9ea7270 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -304,6 +304,7 @@ xfs_inobt_write_verify( } const struct xfs_buf_ops xfs_inobt_buf_ops = { + .name = "xfs_inobt", .verify_read = xfs_inobt_read_verify, .verify_write = xfs_inobt_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index 268c00f4f83af..1b8d98a915c42 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -132,11 +132,13 @@ xfs_inode_buf_write_verify( } const struct xfs_buf_ops xfs_inode_buf_ops = { + .name = "xfs_inode", .verify_read = xfs_inode_buf_read_verify, .verify_write = xfs_inode_buf_write_verify, }; const struct xfs_buf_ops xfs_inode_buf_ra_ops = { + .name = "xxfs_inode_ra", .verify_read = xfs_inode_buf_readahead_verify, .verify_write = xfs_inode_buf_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index a0b071d881a02..8a53eaa349f44 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -679,11 +679,13 @@ xfs_sb_write_verify( } const struct xfs_buf_ops xfs_sb_buf_ops = { + .name = "xfs_sb", .verify_read = xfs_sb_read_verify, .verify_write = xfs_sb_write_verify, }; const struct xfs_buf_ops xfs_sb_quiet_buf_ops = { + .name = "xfs_sb_quiet", .verify_read = xfs_sb_quiet_read_verify, .verify_write = xfs_sb_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c index cb6fd20a4d3d1..2e2c6716b6239 100644 --- a/fs/xfs/libxfs/xfs_symlink_remote.c +++ b/fs/xfs/libxfs/xfs_symlink_remote.c @@ -168,6 +168,7 @@ xfs_symlink_write_verify( } const struct xfs_buf_ops xfs_symlink_buf_ops = { + .name = "xfs_symlink", .verify_read = xfs_symlink_read_verify, .verify_write = xfs_symlink_write_verify, }; diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index c79b717d9b882..c75721acd8679 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -132,6 +132,7 @@ struct xfs_buf_map { struct xfs_buf_map (map) = { .bm_bn = (blkno), .bm_len = (numblk) }; struct xfs_buf_ops { + char *name; void (*verify_read)(struct xfs_buf *); void (*verify_write)(struct xfs_buf *); }; diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c index 74d0e5966ebca..88693a98fac5e 100644 --- a/fs/xfs/xfs_error.c +++ b/fs/xfs/xfs_error.c @@ -164,9 +164,9 @@ xfs_verifier_error( { struct xfs_mount *mp = bp->b_target->bt_mount; - xfs_alert(mp, "Metadata %s detected at %pF, block 0x%llx", + xfs_alert(mp, "Metadata %s detected at %pF, %s block 0x%llx", bp->b_error == -EFSBADCRC ? "CRC error" : "corruption", - __return_address, bp->b_bn); + __return_address, bp->b_ops->name, bp->b_bn); xfs_alert(mp, "Unmount and run xfs_repair"); -- GitLab From f1f96c4946590616812711ac19eb7a84be160877 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Mon, 4 Jan 2016 16:10:42 +1100 Subject: [PATCH 2209/2855] xfs: get mp from bma->ip in xfs_bmap code In my earlier commit c29aad4 xfs: pass mp to XFS_WANT_CORRUPTED_GOTO I added some local mp variables with code which indicates that mp might be NULL. Coverity doesn't like this now, because the updated per-fs XFS_STATS macros dereference mp. I don't think this is actually a problem; from what I can tell, we cannot get to these functions with a null bma->tp, so my NULL check was probably pointless. Still, it's not super obvious. So switch this code to get mp from the inode on the xfs_bmalloca structure, with no conditional, because the functions are already using bmap->ip directly. Addresses-Coverity-Id: 1339552 Addresses-Coverity-Id: 1339553 Signed-off-by: Eric Sandeen Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_bmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 119c2422aac78..bb3c6590035e0 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1725,7 +1725,7 @@ xfs_bmap_add_extent_delay_real( int tmp_rval; /* partial logging flags */ struct xfs_mount *mp; - mp = bma->tp ? bma->tp->t_mountp : NULL; + mp = bma->ip->i_mount; ifp = XFS_IFORK_PTR(bma->ip, XFS_DATA_FORK); ASSERT(bma->idx >= 0); @@ -2939,7 +2939,7 @@ xfs_bmap_add_extent_hole_real( int state; /* state bits, accessed thru macros */ struct xfs_mount *mp; - mp = bma->tp ? bma->tp->t_mountp : NULL; + mp = bma->ip->i_mount; ifp = XFS_IFORK_PTR(bma->ip, whichfork); ASSERT(bma->idx >= 0); -- GitLab From ffc671f1eaa80ee5388693ad78f8332fdea71b80 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Mon, 4 Jan 2016 16:10:42 +1100 Subject: [PATCH 2210/2855] xfs: send warning of project quota to userspace via netlink Linux's quota subsystem has an ability to handle project quota. This commit just utilizes the ability from xfs side. dbus-monitor and quota_nld shipped as part of quota-tools can be used for testing. See the patch posting on the XFS list for details on testing. Signed-off-by: Masatake YAMATO Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/xfs_trans_dquot.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index ce78534a047ee..995170194df04 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -572,12 +572,16 @@ xfs_quota_warn( struct xfs_dquot *dqp, int type) { - /* no warnings for project quotas - we just return ENOSPC later */ + enum quota_type qtype; + if (dqp->dq_flags & XFS_DQ_PROJ) - return; - quota_send_warning(make_kqid(&init_user_ns, - (dqp->dq_flags & XFS_DQ_USER) ? - USRQUOTA : GRPQUOTA, + qtype = PRJQUOTA; + else if (dqp->dq_flags & XFS_DQ_USER) + qtype = USRQUOTA; + else + qtype = GRPQUOTA; + + quota_send_warning(make_kqid(&init_user_ns, qtype, be32_to_cpu(dqp->q_core.d_id)), mp->m_super->s_dev, type); } -- GitLab From 211fe1a4db74141d2ea4a6dae0dc862b1d88f6b9 Mon Sep 17 00:00:00 2001 From: Alexander Kuleshov Date: Mon, 4 Jan 2016 16:10:42 +1100 Subject: [PATCH 2211/2855] xfs: make xfs_buf_ioend_async() static There are no callers of the xfs_buf_ioend_async() function outside of the fs/xfs/xfs_buf.c. So, let's make it static. Signed-off-by: Alexander Kuleshov Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/xfs_buf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 3243cdf97f33f..45a8ea7cfdb20 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1045,7 +1045,7 @@ xfs_buf_ioend_work( xfs_buf_ioend(bp); } -void +static void xfs_buf_ioend_async( struct xfs_buf *bp) { -- GitLab From 2e9101da6047796d7fdee292e10a5c23d5c8b7ee Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 4 Jan 2016 16:10:42 +1100 Subject: [PATCH 2212/2855] libxfs: make xfs_alloc_fix_freelist non-static Since xfs_repair wants to use xfs_alloc_fix_freelist, remove the static designation. xfsprogs already has this; this simply brings the kernel up to date. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 2 +- fs/xfs/libxfs/xfs_alloc.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index e1e7fe3b5424c..a708e38b494c7 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -1927,7 +1927,7 @@ xfs_alloc_space_available( * Decide whether to use this allocation group for this allocation. * If so, fix up the btree freelist's size. */ -STATIC int /* error */ +int /* error */ xfs_alloc_fix_freelist( struct xfs_alloc_arg *args, /* allocation argument structure */ int flags) /* XFS_ALLOC_FLAG_... */ diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 0ecde4d5cac8f..135eb3d24db71 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -235,5 +235,6 @@ xfs_alloc_get_rec( int xfs_read_agf(struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, int flags, struct xfs_buf **bpp); +int xfs_alloc_fix_freelist(struct xfs_alloc_arg *args, int flags); #endif /* __XFS_ALLOC_H__ */ -- GitLab From 9b434a347c3d0aab5a14911fc65531e792da3ae6 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 4 Jan 2016 16:11:42 +1100 Subject: [PATCH 2213/2855] xfs: fix log ticket type printing Update the log ticket reservation type printing code to reflect all the types of log tickets, to avoid incorrect debug output and avoid running off the end of the array. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_log.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index f52c72a1a06f2..2aa187e311e37 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -2045,12 +2045,14 @@ xlog_print_tic_res( "QM_DQCLUSTER", "QM_QINOCREATE", "QM_QUOTAOFF_END", - "SB_UNIT", "FSYNC_TS", "GROWFSRT_ALLOC", "GROWFSRT_ZERO", "GROWFSRT_FREE", - "SWAPEXT" + "SWAPEXT", + "CHECKPOINT", + "ICREATE", + "CREATE_TMPFILE" }; xfs_warn(mp, "xlog_write: reservation summary:"); -- GitLab From 6d3eb1eca0e35cc1c0c80eacb7e7fe23c0dbfb07 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 4 Jan 2016 16:12:42 +1100 Subject: [PATCH 2214/2855] libxfs: use a convenience variable instead of open-coding the fork Use a convenience variable instead of open-coding the inode fork. This isn't really needed for now, but will become important when we add the copy-on-write fork later. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_bmap.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index bb3c6590035e0..73884953b21cc 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1723,10 +1723,11 @@ xfs_bmap_add_extent_delay_real( xfs_filblks_t temp=0; /* value for da_new calculations */ xfs_filblks_t temp2=0;/* value for da_new calculations */ int tmp_rval; /* partial logging flags */ + int whichfork = XFS_DATA_FORK; struct xfs_mount *mp; mp = bma->ip->i_mount; - ifp = XFS_IFORK_PTR(bma->ip, XFS_DATA_FORK); + ifp = XFS_IFORK_PTR(bma->ip, whichfork); ASSERT(bma->idx >= 0); ASSERT(bma->idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec)); @@ -1785,7 +1786,7 @@ xfs_bmap_add_extent_delay_real( * Don't set contiguous if the combined extent would be too large. * Also check for all-three-contiguous being too large. */ - if (bma->idx < bma->ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { + if (bma->idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { state |= BMAP_RIGHT_VALID; xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx + 1), &RIGHT); @@ -2016,10 +2017,10 @@ xfs_bmap_add_extent_delay_real( XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } - if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { + if (xfs_bmap_needs_btree(bma->ip, whichfork)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, bma->firstblock, bma->flist, - &bma->cur, 1, &tmp_rval, XFS_DATA_FORK); + &bma->cur, 1, &tmp_rval, whichfork); rval |= tmp_rval; if (error) goto done; @@ -2100,10 +2101,10 @@ xfs_bmap_add_extent_delay_real( XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } - if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { + if (xfs_bmap_needs_btree(bma->ip, whichfork)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, bma->firstblock, bma->flist, &bma->cur, 1, - &tmp_rval, XFS_DATA_FORK); + &tmp_rval, whichfork); rval |= tmp_rval; if (error) goto done; @@ -2169,10 +2170,10 @@ xfs_bmap_add_extent_delay_real( XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } - if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { + if (xfs_bmap_needs_btree(bma->ip, whichfork)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, bma->firstblock, bma->flist, &bma->cur, - 1, &tmp_rval, XFS_DATA_FORK); + 1, &tmp_rval, whichfork); rval |= tmp_rval; if (error) goto done; @@ -2215,13 +2216,13 @@ xfs_bmap_add_extent_delay_real( } /* convert to a btree if necessary */ - if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { + if (xfs_bmap_needs_btree(bma->ip, whichfork)) { int tmp_logflags; /* partial log flag return val */ ASSERT(bma->cur == NULL); error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, bma->firstblock, bma->flist, &bma->cur, - da_old > 0, &tmp_logflags, XFS_DATA_FORK); + da_old > 0, &tmp_logflags, whichfork); bma->logflags |= tmp_logflags; if (error) goto done; @@ -2242,7 +2243,7 @@ xfs_bmap_add_extent_delay_real( if (bma->cur) bma->cur->bc_private.b.allocated = 0; - xfs_bmap_check_leaf_extents(bma->cur, bma->ip, XFS_DATA_FORK); + xfs_bmap_check_leaf_extents(bma->cur, bma->ip, whichfork); done: bma->logflags |= rval; return error; -- GitLab From 96f859d52bcb1c6ea6f3388d39862bf7143e2f30 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 4 Jan 2016 16:13:21 +1100 Subject: [PATCH 2215/2855] libxfs: pack the agfl header structure so XFS_AGFL_SIZE is correct Because struct xfs_agfl is 36 bytes long and has a 64-bit integer inside it, gcc will quietly round the structure size up to the nearest 64 bits -- in this case, 40 bytes. This results in the XFS_AGFL_SIZE macro returning incorrect results for v5 filesystems on 64-bit machines (118 items instead of 119). As a result, a 32-bit xfs_repair will see garbage in AGFL item 119 and complain. Therefore, tell gcc not to pad the structure so that the AGFL size calculation is correct. cc: # 3.10 - 4.4 Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_format.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 8774498ce0ffa..e2536bb1c7600 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -786,7 +786,7 @@ typedef struct xfs_agfl { __be64 agfl_lsn; __be32 agfl_crc; __be32 agfl_bno[]; /* actually XFS_AGFL_SIZE(mp) */ -} xfs_agfl_t; +} __attribute__((packed)) xfs_agfl_t; #define XFS_AGFL_CRC_OFF offsetof(struct xfs_agfl, agfl_crc) -- GitLab From c5ab131ba0df8c1f1f52ffa6214d60aafeeddbd0 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 4 Jan 2016 16:13:21 +1100 Subject: [PATCH 2216/2855] libxfs: refactor short btree block verification Create xfs_btree_sblock_verify() to verify short-format btree blocks (i.e. the per-AG btrees with 32-bit block pointers) instead of open-coding them. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc_btree.c | 34 ++----------------- fs/xfs/libxfs/xfs_btree.c | 58 ++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_btree.h | 3 ++ fs/xfs/libxfs/xfs_ialloc_btree.c | 26 ++------------ 4 files changed, 67 insertions(+), 54 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index eb8bbfe85484e..444626ddbd1b9 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -293,14 +293,7 @@ xfs_allocbt_verify( level = be16_to_cpu(block->bb_level); switch (block->bb_magic) { case cpu_to_be32(XFS_ABTB_CRC_MAGIC): - if (!xfs_sb_version_hascrc(&mp->m_sb)) - return false; - if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid)) - return false; - if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) - return false; - if (pag && - be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + if (!xfs_btree_sblock_v5hdr_verify(bp)) return false; /* fall through */ case cpu_to_be32(XFS_ABTB_MAGIC): @@ -311,14 +304,7 @@ xfs_allocbt_verify( return false; break; case cpu_to_be32(XFS_ABTC_CRC_MAGIC): - if (!xfs_sb_version_hascrc(&mp->m_sb)) - return false; - if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid)) - return false; - if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) - return false; - if (pag && - be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + if (!xfs_btree_sblock_v5hdr_verify(bp)) return false; /* fall through */ case cpu_to_be32(XFS_ABTC_MAGIC): @@ -332,21 +318,7 @@ xfs_allocbt_verify( return false; } - /* numrecs verification */ - if (be16_to_cpu(block->bb_numrecs) > mp->m_alloc_mxr[level != 0]) - return false; - - /* sibling pointer verification */ - if (!block->bb_u.s.bb_leftsib || - (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks && - block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK))) - return false; - if (!block->bb_u.s.bb_rightsib || - (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks && - block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK))) - return false; - - return true; + return xfs_btree_sblock_verify(bp, mp->m_alloc_mxr[level != 0]); } static void diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index af1bbee5586e4..a0eb18ce3ad38 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -4080,3 +4080,61 @@ xfs_btree_change_owner( return 0; } + +/** + * xfs_btree_sblock_v5hdr_verify() -- verify the v5 fields of a short-format + * btree block + * + * @bp: buffer containing the btree block + * @max_recs: pointer to the m_*_mxr max records field in the xfs mount + * @pag_max_level: pointer to the per-ag max level field + */ +bool +xfs_btree_sblock_v5hdr_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); + struct xfs_perag *pag = bp->b_pag; + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return false; + if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid)) + return false; + if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) + return false; + if (pag && be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + return false; + return true; +} + +/** + * xfs_btree_sblock_verify() -- verify a short-format btree block + * + * @bp: buffer containing the btree block + * @max_recs: maximum records allowed in this btree node + */ +bool +xfs_btree_sblock_verify( + struct xfs_buf *bp, + unsigned int max_recs) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); + + /* numrecs verification */ + if (be16_to_cpu(block->bb_numrecs) > max_recs) + return false; + + /* sibling pointer verification */ + if (!block->bb_u.s.bb_leftsib || + (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks && + block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK))) + return false; + if (!block->bb_u.s.bb_rightsib || + (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks && + block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK))) + return false; + + return true; +} diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 992dec0638f33..2e874be702093 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -472,4 +472,7 @@ static inline int xfs_btree_get_level(struct xfs_btree_block *block) #define XFS_BTREE_TRACE_ARGR(c, r) #define XFS_BTREE_TRACE_CURSOR(c, t) +bool xfs_btree_sblock_v5hdr_verify(struct xfs_buf *bp); +bool xfs_btree_sblock_verify(struct xfs_buf *bp, unsigned int max_recs); + #endif /* __XFS_BTREE_H__ */ diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 6dd44f9ea7270..c679f3c05b63c 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -221,7 +221,6 @@ xfs_inobt_verify( { struct xfs_mount *mp = bp->b_target->bt_mount; struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); - struct xfs_perag *pag = bp->b_pag; unsigned int level; /* @@ -237,14 +236,7 @@ xfs_inobt_verify( switch (block->bb_magic) { case cpu_to_be32(XFS_IBT_CRC_MAGIC): case cpu_to_be32(XFS_FIBT_CRC_MAGIC): - if (!xfs_sb_version_hascrc(&mp->m_sb)) - return false; - if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid)) - return false; - if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) - return false; - if (pag && - be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + if (!xfs_btree_sblock_v5hdr_verify(bp)) return false; /* fall through */ case cpu_to_be32(XFS_IBT_MAGIC): @@ -254,24 +246,12 @@ xfs_inobt_verify( return 0; } - /* numrecs and level verification */ + /* level verification */ level = be16_to_cpu(block->bb_level); if (level >= mp->m_in_maxlevels) return false; - if (be16_to_cpu(block->bb_numrecs) > mp->m_inobt_mxr[level != 0]) - return false; - - /* sibling pointer verification */ - if (!block->bb_u.s.bb_leftsib || - (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks && - block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK))) - return false; - if (!block->bb_u.s.bb_rightsib || - (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks && - block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK))) - return false; - return true; + return xfs_btree_sblock_verify(bp, mp->m_inobt_mxr[level != 0]); } static void -- GitLab From a841b64df29b4c7e68ce564d752dfb2042db5404 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 4 Jan 2016 16:13:21 +1100 Subject: [PATCH 2217/2855] XFS: Use a signed return type for suffix_kstrtoint() The return type "unsigned long" was used by the suffix_kstrtoint() function even though it will eventually return a negative error code. Improve this implementation detail by using the type "int" instead. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Reviewed-by: Eric Sandeen Signed-off-by: Dave Chinner --- fs/xfs/xfs_super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 36bd8825bfb03..b35775752b745 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -137,7 +137,7 @@ static const match_table_t tokens = { }; -STATIC unsigned long +STATIC int suffix_kstrtoint(char *s, unsigned int base, int *res) { int last, shift_left_factor = 0, _res; -- GitLab From 3b0fe47805802216087259b07de691ef47ff6fbc Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 4 Jan 2016 16:22:45 +1100 Subject: [PATCH 2218/2855] xfs: Don't use reserved blocks for data blocks with DAX Commit 1ca1915 ("xfs: Don't use unwritten extents for DAX") enabled the DAX allocation call to dip into the reserve pool in case it was converting unwritten extents rather than allocating blocks. This was a direct copy of the unwritten extent conversion code, but had an unintended side effect of allowing normal data block allocation to use the reserve pool. Hence normal block allocation could deplete the reserve pool and prevent unwritten extent conversion at ENOSPC, hence violating fallocate guarantees on preallocated space. Fix it by checking whether the incoming map from __xfs_get_blocks() spans an unwritten extent and only use the reserve pool if the allocation covers an unwritten extent. Signed-off-by: Dave Chinner Tested-by: Ross Zwisler Signed-off-by: Dave Chinner --- fs/xfs/xfs_iomap.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index f4f5b43cf6471..9ed146b96856d 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -203,15 +203,20 @@ xfs_iomap_write_direct( * this outside the transaction context, but if we commit and then crash * we may not have zeroed the blocks and this will be exposed on * recovery of the allocation. Hence we must zero before commit. + * * Further, if we are mapping unwritten extents here, we need to zero * and convert them to written so that we don't need an unwritten extent * callback for DAX. This also means that we need to be able to dip into - * the reserve block pool if there is no space left but we need to do - * unwritten extent conversion. + * the reserve block pool for bmbt block allocation if there is no space + * left but we need to do unwritten extent conversion. */ + if (IS_DAX(VFS_I(ip))) { bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO; - tp->t_flags |= XFS_TRANS_RESERVE; + if (ISUNWRITTEN(imap)) { + tp->t_flags |= XFS_TRANS_RESERVE; + resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1; + } } error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, resblks, resrtextents); -- GitLab From a6d7636e8d0fd94fd1937db91d5b06a91fa85dde Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 4 Jan 2016 16:28:25 +1100 Subject: [PATCH 2219/2855] xfs: fix recursive splice read locking with DAX Doing a splice read (generic/249) generates a lockdep splat because we recursively lock the inode iolock in this path: SyS_sendfile64 do_sendfile do_splice_direct splice_direct_to_actor do_splice_to xfs_file_splice_read <<<<<< lock here default_file_splice_read vfs_readv do_readv_writev do_iter_readv_writev xfs_file_read_iter <<<<<< then here The issue here is that for DAX inodes we need to avoid the page cache path and hence simply push it into the normal read path. Unfortunately, we can't tell down at xfs_file_read_iter() whether we are being called from the splice path and hence we cannot avoid the locking at this layer. Hence we simply have to drop the inode locking at the higher splice layer for DAX. Signed-off-by: Dave Chinner Tested-by: Ross Zwisler Signed-off-by: Dave Chinner --- fs/xfs/xfs_file.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index f5392ab2def1a..ebe9b8290a705 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -402,19 +402,26 @@ xfs_file_splice_read( if (XFS_FORCED_SHUTDOWN(ip->i_mount)) return -EIO; - xfs_rw_ilock(ip, XFS_IOLOCK_SHARED); - trace_xfs_file_splice_read(ip, count, *ppos, ioflags); - /* for dax, we need to avoid the page cache */ - if (IS_DAX(VFS_I(ip))) - ret = default_file_splice_read(infilp, ppos, pipe, count, flags); - else - ret = generic_file_splice_read(infilp, ppos, pipe, count, flags); - if (ret > 0) - XFS_STATS_ADD(ip->i_mount, xs_read_bytes, ret); + /* + * DAX inodes cannot ues the page cache for splice, so we have to push + * them through the VFS IO path. This means it goes through + * ->read_iter, which for us takes the XFS_IOLOCK_SHARED. Hence we + * cannot lock the splice operation at this level for DAX inodes. + */ + if (IS_DAX(VFS_I(ip))) { + ret = default_file_splice_read(infilp, ppos, pipe, count, + flags); + goto out; + } + xfs_rw_ilock(ip, XFS_IOLOCK_SHARED); + ret = generic_file_splice_read(infilp, ppos, pipe, count, flags); xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); +out: + if (ret > 0) + XFS_STATS_ADD(ip->i_mount, xs_read_bytes, ret); return ret; } -- GitLab From e0afc4d6d0d3e7e5a99f691bc64ae7c74bea790e Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 31 Dec 2015 14:35:37 +0800 Subject: [PATCH 2220/2855] f2fs: introduce max_file_blocks in sbi Introduce max_file_blocks in sbi to store max block index of file in f2fs, it could be used to avoid unneeded calculation of max block index in runtime. Signed-off-by: Chao Yu [Jaegeuk Kim: fix overflow of sbi->max_file_blocks] Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 2 +- fs/f2fs/f2fs.h | 2 +- fs/f2fs/super.c | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 4851e84d02837..89a978c57da92 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -762,7 +762,7 @@ static int get_data_block_bmap(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) { /* Block number less than F2FS MAX BLOCKS */ - if (unlikely(iblock >= max_file_size(0))) + if (unlikely(iblock >= F2FS_I_SB(inode)->max_file_blocks)) return -EFBIG; return __get_data_block(inode, iblock, bh_result, create, diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index e2990c9786614..882babaa678e1 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -783,6 +783,7 @@ struct f2fs_sb_info { unsigned int total_node_count; /* total node block count */ unsigned int total_valid_node_count; /* valid node block count */ unsigned int total_valid_inode_count; /* valid inode count */ + loff_t max_file_blocks; /* max block index of file */ int active_logs; /* # of active logs */ int dir_level; /* directory level */ @@ -1727,7 +1728,6 @@ static inline int f2fs_add_link(struct dentry *dentry, struct inode *inode) * super.c */ int f2fs_commit_super(struct f2fs_sb_info *, bool); -loff_t max_file_size(unsigned bits); int f2fs_sync_fs(struct super_block *, int); extern __printf(3, 4) void f2fs_msg(struct super_block *, const char *, const char *, ...); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index a2e3a8f893edd..0bbd756821a7d 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -907,7 +907,7 @@ static const struct export_operations f2fs_export_ops = { .get_parent = f2fs_get_parent, }; -loff_t max_file_size(unsigned bits) +static loff_t max_file_blocks(void) { loff_t result = (DEF_ADDRS_PER_INODE - F2FS_INLINE_XATTR_ADDRS); loff_t leaf_count = ADDRS_PER_BLOCK; @@ -923,7 +923,6 @@ loff_t max_file_size(unsigned bits) leaf_count *= NIDS_PER_BLOCK; result += leaf_count; - result <<= bits; return result; } @@ -1278,7 +1277,9 @@ try_onemore: if (err) goto free_options; - sb->s_maxbytes = max_file_size(le32_to_cpu(raw_super->log_blocksize)); + sbi->max_file_blocks = max_file_blocks(); + sb->s_maxbytes = sbi->max_file_blocks << + le32_to_cpu(raw_super->log_blocksize); sb->s_max_links = F2FS_LINK_MAX; get_random_bytes(&sbi->s_next_generation, sizeof(u32)); -- GitLab From 4f1b1519f7bec44ded3c2c4d46a2594c01446dc8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 1 Jan 2016 15:21:54 +0100 Subject: [PATCH 2221/2855] udf: avoid uninitialized variable use A new warning has come up from a recent cleanup: fs/udf/inode.c: In function 'udf_setup_indirect_aext': fs/udf/inode.c:1927:28: warning: 'adsize' may be used uninitialized in this function [-Wmaybe-uninitialized] If the alloc_type is neither ICBTAG_FLAG_AD_SHORT nor ICBTAG_FLAG_AD_LONG, the value of adsize is undefined. Currently, callers of these functions make sure alloc_type is one of the two valid ones but for future proofing make sure we handle the case of invalid alloc type as well. This changes the code to return -EIOin that case. Signed-off-by: Arnd Bergmann Fixes: fcea62babc81 ("udf: Factor out code for creating indirect extent") Signed-off-by: Jan Kara --- fs/udf/inode.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 846294891925a..91d8fa9d87a4b 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1889,6 +1889,8 @@ int udf_setup_indirect_aext(struct inode *inode, int block, adsize = sizeof(struct short_ad); else if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_LONG) adsize = sizeof(struct long_ad); + else + return -EIO; neloc.logicalBlockNum = block; neloc.partitionReferenceNum = epos->block.partitionReferenceNum; @@ -1962,6 +1964,8 @@ int __udf_add_aext(struct inode *inode, struct extent_position *epos, adsize = sizeof(struct short_ad); else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) adsize = sizeof(struct long_ad); + else + return -EIO; if (!epos->bh) { WARN_ON(iinfo->i_lenAlloc != -- GitLab From d1b98c23f7547cc37c8f230acbedb26f0d47e9e1 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 1 Jan 2016 08:53:37 +0100 Subject: [PATCH 2222/2855] quota: constify qtree_fmt_operations structures The qtree_fmt_operations structures are never modified, so declare them as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Jan Kara --- fs/ocfs2/quota.h | 2 +- fs/ocfs2/quota_global.c | 2 +- fs/quota/quota_v2.c | 4 ++-- include/linux/dqblk_qtree.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/ocfs2/quota.h b/fs/ocfs2/quota.h index b6d51333ad026..d153e6e31529a 100644 --- a/fs/ocfs2/quota.h +++ b/fs/ocfs2/quota.h @@ -82,7 +82,7 @@ struct ocfs2_quota_chunk { extern struct kmem_cache *ocfs2_dquot_cachep; extern struct kmem_cache *ocfs2_qf_chunk_cachep; -extern struct qtree_fmt_operations ocfs2_global_ops; +extern const struct qtree_fmt_operations ocfs2_global_ops; struct ocfs2_quota_recovery *ocfs2_begin_quota_recovery( struct ocfs2_super *osb, int slot_num); diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index c93d672208875..fde9ef18cff3c 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c @@ -123,7 +123,7 @@ static int ocfs2_global_is_id(void *dp, struct dquot *dquot) dquot->dq_id); } -struct qtree_fmt_operations ocfs2_global_ops = { +const struct qtree_fmt_operations ocfs2_global_ops = { .mem2disk_dqblk = ocfs2_global_mem2diskdqb, .disk2mem_dqblk = ocfs2_global_disk2memdqb, .is_id = ocfs2_global_is_id, diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c index 2aa012a68e90e..ed85d4f35c04b 100644 --- a/fs/quota/quota_v2.c +++ b/fs/quota/quota_v2.c @@ -30,13 +30,13 @@ static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot); static void v2r1_disk2memdqb(struct dquot *dquot, void *dp); static int v2r1_is_id(void *dp, struct dquot *dquot); -static struct qtree_fmt_operations v2r0_qtree_ops = { +static const struct qtree_fmt_operations v2r0_qtree_ops = { .mem2disk_dqblk = v2r0_mem2diskdqb, .disk2mem_dqblk = v2r0_disk2memdqb, .is_id = v2r0_is_id, }; -static struct qtree_fmt_operations v2r1_qtree_ops = { +static const struct qtree_fmt_operations v2r1_qtree_ops = { .mem2disk_dqblk = v2r1_mem2diskdqb, .disk2mem_dqblk = v2r1_disk2memdqb, .is_id = v2r1_is_id, diff --git a/include/linux/dqblk_qtree.h b/include/linux/dqblk_qtree.h index 82a16527b367a..ff8b55359648c 100644 --- a/include/linux/dqblk_qtree.h +++ b/include/linux/dqblk_qtree.h @@ -34,7 +34,7 @@ struct qtree_mem_dqinfo { unsigned int dqi_entry_size; /* Size of quota entry in quota file */ unsigned int dqi_usable_bs; /* Space usable in block for quota data */ unsigned int dqi_qtree_depth; /* Precomputed depth of quota tree */ - struct qtree_fmt_operations *dqi_ops; /* Operations for entry manipulation */ + const struct qtree_fmt_operations *dqi_ops; /* Operations for entry manipulation */ }; int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot); -- GitLab From ad402b265ecf6fa22d04043b41444cdfcdf4f52d Mon Sep 17 00:00:00 2001 From: Andrew Gabbasov Date: Thu, 24 Dec 2015 10:25:32 -0600 Subject: [PATCH 2223/2855] udf: Prevent buffer overrun with multi-byte characters udf_CS0toUTF8 function stops the conversion when the output buffer length reaches UDF_NAME_LEN-2, which is correct maximum name length, but, when checking, it leaves the space for a single byte only, while multi-bytes output characters can take more space, causing buffer overflow. Similar error exists in udf_CS0toNLS function, that restricts the output length to UDF_NAME_LEN, while actual maximum allowed length is UDF_NAME_LEN-2. In these cases the output can override not only the current buffer length field, causing corruption of the name buffer itself, but also following allocation structures, causing kernel crash. Adjust the output length checks in both functions to prevent buffer overruns in case of multi-bytes UTF8 or NLS characters. CC: stable@vger.kernel.org Signed-off-by: Andrew Gabbasov Signed-off-by: Jan Kara --- fs/udf/unicode.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c index ab478e62baaeb..95a224b260480 100644 --- a/fs/udf/unicode.c +++ b/fs/udf/unicode.c @@ -128,11 +128,15 @@ int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i) if (c < 0x80U) utf_o->u_name[utf_o->u_len++] = (uint8_t)c; else if (c < 0x800U) { + if (utf_o->u_len > (UDF_NAME_LEN - 4)) + break; utf_o->u_name[utf_o->u_len++] = (uint8_t)(0xc0 | (c >> 6)); utf_o->u_name[utf_o->u_len++] = (uint8_t)(0x80 | (c & 0x3f)); } else { + if (utf_o->u_len > (UDF_NAME_LEN - 5)) + break; utf_o->u_name[utf_o->u_len++] = (uint8_t)(0xe0 | (c >> 12)); utf_o->u_name[utf_o->u_len++] = @@ -277,7 +281,7 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, c = (c << 8) | ocu[i++]; len = nls->uni2char(c, &utf_o->u_name[utf_o->u_len], - UDF_NAME_LEN - utf_o->u_len); + UDF_NAME_LEN - 2 - utf_o->u_len); /* Valid character? */ if (len >= 0) utf_o->u_len += len; -- GitLab From bb00c898ad1ce40c4bb422a8207ae562e9aea7ae Mon Sep 17 00:00:00 2001 From: Andrew Gabbasov Date: Thu, 24 Dec 2015 10:25:33 -0600 Subject: [PATCH 2224/2855] udf: Check output buffer length when converting name to CS0 If a name contains at least some characters with Unicode values exceeding single byte, the CS0 output should have 2 bytes per character. And if other input characters have single byte Unicode values, then the single input byte is converted to 2 output bytes, and the length of output becomes larger than the length of input. And if the input name is long enough, the output length may exceed the allocated buffer length. All this means that conversion from UTF8 or NLS to CS0 requires checking of output length in order to stop when it exceeds the given output buffer size. [JK: Make code return -ENAMETOOLONG instead of silently truncating the name] CC: stable@vger.kernel.org Signed-off-by: Andrew Gabbasov Signed-off-by: Jan Kara --- fs/udf/unicode.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c index 95a224b260480..e788a05aab836 100644 --- a/fs/udf/unicode.c +++ b/fs/udf/unicode.c @@ -177,17 +177,22 @@ int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i) static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length) { unsigned c, i, max_val, utf_char; - int utf_cnt, u_len; + int utf_cnt, u_len, u_ch; memset(ocu, 0, sizeof(dstring) * length); ocu[0] = 8; max_val = 0xffU; + u_ch = 1; try_again: u_len = 0U; utf_char = 0U; utf_cnt = 0U; for (i = 0U; i < utf->u_len; i++) { + /* Name didn't fit? */ + if (u_len + 1 + u_ch >= length) + return 0; + c = (uint8_t)utf->u_name[i]; /* Complete a multi-byte UTF-8 character */ @@ -229,6 +234,7 @@ try_again: if (max_val == 0xffU) { max_val = 0xffffU; ocu[0] = (uint8_t)0x10U; + u_ch = 2; goto try_again; } goto error_out; @@ -299,15 +305,19 @@ static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, int len; unsigned i, max_val; uint16_t uni_char; - int u_len; + int u_len, u_ch; memset(ocu, 0, sizeof(dstring) * length); ocu[0] = 8; max_val = 0xffU; + u_ch = 1; try_again: u_len = 0U; for (i = 0U; i < uni->u_len; i++) { + /* Name didn't fit? */ + if (u_len + 1 + u_ch >= length) + return 0; len = nls->char2uni(&uni->u_name[i], uni->u_len - i, &uni_char); if (!len) continue; @@ -320,6 +330,7 @@ try_again: if (uni_char > max_val) { max_val = 0xffffU; ocu[0] = (uint8_t)0x10U; + u_ch = 2; goto try_again; } -- GitLab From ed429d6b934d44e25f23f8102375a103c6fc3996 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 4 Jan 2016 12:30:55 -0500 Subject: [PATCH 2225/2855] NFSv4.1/pNFS: Don't pass stateids by value to pnfs_send_layoutreturn() A stateid is a structure, pass it as a pointer. Signed-off-by: Trond Myklebust --- fs/nfs/pnfs.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 6593be7c01291..7a452895169fb 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -53,7 +53,7 @@ static DEFINE_SPINLOCK(pnfs_spinlock); static LIST_HEAD(pnfs_modules_tbl); static int -pnfs_send_layoutreturn(struct pnfs_layout_hdr *lo, nfs4_stateid stateid, +pnfs_send_layoutreturn(struct pnfs_layout_hdr *lo, const nfs4_stateid *stateid, enum pnfs_iomode iomode, bool sync); /* Return the registered pnfs layout driver module matching given id */ @@ -391,7 +391,7 @@ static void pnfs_layoutreturn_before_put_lseg(struct pnfs_layout_segment *lseg, spin_unlock(&inode->i_lock); if (send) { /* Send an async layoutreturn so we dont deadlock */ - pnfs_send_layoutreturn(lo, stateid, iomode, false); + pnfs_send_layoutreturn(lo, &stateid, iomode, false); } } else spin_unlock(&inode->i_lock); @@ -947,7 +947,7 @@ void pnfs_clear_layoutreturn_waitbit(struct pnfs_layout_hdr *lo) } static int -pnfs_send_layoutreturn(struct pnfs_layout_hdr *lo, nfs4_stateid stateid, +pnfs_send_layoutreturn(struct pnfs_layout_hdr *lo, const nfs4_stateid *stateid, enum pnfs_iomode iomode, bool sync) { struct inode *ino = lo->plh_inode; @@ -964,7 +964,7 @@ pnfs_send_layoutreturn(struct pnfs_layout_hdr *lo, nfs4_stateid stateid, goto out; } - lrp->args.stateid = stateid; + nfs4_stateid_copy(&lrp->args.stateid, stateid); lrp->args.layout_type = NFS_SERVER(ino)->pnfs_curr_ld->id; lrp->args.inode = ino; lrp->args.range.iomode = iomode; @@ -1035,7 +1035,7 @@ _pnfs_return_layout(struct inode *ino) spin_unlock(&ino->i_lock); pnfs_free_lseg_list(&tmp_list); if (send) - status = pnfs_send_layoutreturn(lo, stateid, IOMODE_ANY, true); + status = pnfs_send_layoutreturn(lo, &stateid, IOMODE_ANY, true); out_put_layout_hdr: pnfs_put_layout_hdr(lo); out: @@ -1126,7 +1126,7 @@ out_noroc: pnfs_free_lseg_list(&tmp_list); pnfs_layoutcommit_inode(ino, true); if (layoutreturn) - pnfs_send_layoutreturn(lo, stateid, IOMODE_ANY, true); + pnfs_send_layoutreturn(lo, &stateid, IOMODE_ANY, true); return roc; } -- GitLab From 50f563ef5d418127a75ca9b7116232672bbd8aaf Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 4 Jan 2016 12:22:46 -0500 Subject: [PATCH 2226/2855] NFSv4.1/pNFS: Use nfs4_stateid_copy for copying stateids Signed-off-by: Trond Myklebust --- fs/nfs/pnfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 7a452895169fb..7e0f2b9a9b10e 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -385,7 +385,7 @@ static void pnfs_layoutreturn_before_put_lseg(struct pnfs_layout_segment *lseg, enum pnfs_iomode iomode; bool send; - stateid = lo->plh_stateid; + nfs4_stateid_copy(&stateid, &lo->plh_stateid); iomode = lo->plh_return_iomode; send = pnfs_prepare_layoutreturn(lo); spin_unlock(&inode->i_lock); @@ -1007,7 +1007,7 @@ _pnfs_return_layout(struct inode *ino) dprintk("NFS: %s no layout to return\n", __func__); goto out; } - stateid = nfsi->layout->plh_stateid; + nfs4_stateid_copy(&stateid, &nfsi->layout->plh_stateid); /* Reference matched in nfs4_layoutreturn_release */ pnfs_get_layout_hdr(lo); empty = list_empty(&lo->plh_segs); @@ -1098,7 +1098,7 @@ bool pnfs_roc(struct inode *ino) goto out_noroc; } - stateid = lo->plh_stateid; + nfs4_stateid_copy(&stateid, &lo->plh_stateid); /* always send layoutreturn if being marked so */ if (test_and_clear_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE, &lo->plh_flags)) -- GitLab From 5c97f5de2c7cd9e2a5f71bc7c53125d9a2833ca9 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 4 Jan 2016 11:53:04 -0500 Subject: [PATCH 2227/2855] NFSv4.1/pNFS: pnfs_mark_matching_lsegs_return() should set the iomode If pnfs_mark_matching_lsegs_return() needs to mark a layout segment for return, then it must also set the return iomode. Signed-off-by: Trond Myklebust --- fs/nfs/pnfs.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 7e0f2b9a9b10e..449c4782cab37 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -1758,6 +1758,16 @@ out_forget_reply: goto out; } +static void +pnfs_set_plh_return_iomode(struct pnfs_layout_hdr *lo, enum pnfs_iomode iomode) +{ + if (lo->plh_return_iomode == iomode) + return; + if (lo->plh_return_iomode != 0) + iomode = IOMODE_ANY; + lo->plh_return_iomode = iomode; +} + void pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, struct list_head *tmp_list, @@ -1780,6 +1790,7 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, lseg->pls_range.offset, lseg->pls_range.length); set_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags); + pnfs_set_plh_return_iomode(lo, return_range->iomode); mark_lseg_invalid(lseg, tmp_list); set_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE, &lo->plh_flags); @@ -1801,10 +1812,7 @@ void pnfs_error_mark_layout_for_return(struct inode *inode, spin_lock(&inode->i_lock); /* set failure bit so that pnfs path will be retried later */ pnfs_layout_set_fail_bit(lo, iomode); - if (lo->plh_return_iomode == 0) - lo->plh_return_iomode = range.iomode; - else if (lo->plh_return_iomode != range.iomode) - lo->plh_return_iomode = IOMODE_ANY; + pnfs_set_plh_return_iomode(lo, range.iomode); /* * mark all matching lsegs so that we are sure to have no live * segments at hand when sending layoutreturn. See pnfs_put_lseg() -- GitLab From 10335556c9e6ed2e1949fb595b7775f475299832 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 4 Jan 2016 11:23:52 -0500 Subject: [PATCH 2228/2855] NFSv4.1/pNFS: pnfs_error_mark_layout_for_return() must always return layout Fix a bug whereby if all the layout segments could be immediately freed, the call to pnfs_error_mark_layout_for_return() would never result in a layoutreturn. Signed-off-by: Trond Myklebust --- fs/nfs/pnfs.c | 26 ++++++++++++++++++++------ fs/nfs/pnfs.h | 2 +- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 449c4782cab37..8e1d4229bf2df 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -1768,17 +1768,18 @@ pnfs_set_plh_return_iomode(struct pnfs_layout_hdr *lo, enum pnfs_iomode iomode) lo->plh_return_iomode = iomode; } -void +int pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, struct list_head *tmp_list, struct pnfs_layout_range *return_range) { struct pnfs_layout_segment *lseg, *next; + int remaining = 0; dprintk("%s:Begin lo %p\n", __func__, lo); if (list_empty(&lo->plh_segs)) - return; + return 0; assert_spin_locked(&lo->plh_inode->i_lock); @@ -1791,10 +1792,12 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, lseg->pls_range.length); set_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags); pnfs_set_plh_return_iomode(lo, return_range->iomode); - mark_lseg_invalid(lseg, tmp_list); + if (!mark_lseg_invalid(lseg, tmp_list)) + remaining++; set_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE, &lo->plh_flags); } + return remaining; } void pnfs_error_mark_layout_for_return(struct inode *inode, @@ -1808,6 +1811,7 @@ void pnfs_error_mark_layout_for_return(struct inode *inode, .length = NFS4_MAX_UINT64, }; LIST_HEAD(free_me); + bool return_now = false; spin_lock(&inode->i_lock); /* set failure bit so that pnfs path will be retried later */ @@ -1818,10 +1822,20 @@ void pnfs_error_mark_layout_for_return(struct inode *inode, * segments at hand when sending layoutreturn. See pnfs_put_lseg() * for how it works. */ - pnfs_mark_matching_lsegs_return(lo, &free_me, &range); - spin_unlock(&inode->i_lock); + if (!pnfs_mark_matching_lsegs_return(lo, &free_me, &range)) { + nfs4_stateid stateid; + enum pnfs_iomode iomode = lo->plh_return_iomode; + + nfs4_stateid_copy(&stateid, &lo->plh_stateid); + return_now = pnfs_prepare_layoutreturn(lo); + spin_unlock(&inode->i_lock); + if (return_now) + pnfs_send_layoutreturn(lo, &stateid, iomode, false); + } else { + spin_unlock(&inode->i_lock); + nfs_commit_inode(inode, 0); + } pnfs_free_lseg_list(&free_me); - nfs_commit_inode(inode, 0); } EXPORT_SYMBOL_GPL(pnfs_error_mark_layout_for_return); diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 4bd7faf9ce507..3d0f513a4a77f 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -266,7 +266,7 @@ int pnfs_choose_layoutget_stateid(nfs4_stateid *dst, int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, struct list_head *tmp_list, struct pnfs_layout_range *recall_range); -void pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, +int pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, struct list_head *tmp_list, struct pnfs_layout_range *recall_range); bool pnfs_roc(struct inode *ino); -- GitLab From 4b0934baf9317e05c7568da1366a1d65f151d81f Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 4 Jan 2016 11:28:11 -0500 Subject: [PATCH 2229/2855] NFSv4.1/pNFS: Fix a race in initiate_file_draining() Peng Tao points out that the call to pnfs_mark_matching_lsegs_return() could race with pnfs_put_lseg(), in which case the layout segment is cleared, but no layoutreturn will be sent. Fix is to replace the call to pnfs_mark_matching_lsegs_invalid(). Reported-by: Peng Tao Signed-off-by: Trond Myklebust --- fs/nfs/callback_proc.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 2be8b252e3b1b..f0939d097406a 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -216,11 +216,8 @@ static u32 initiate_file_draining(struct nfs_client *clp, goto unlock; } - if (pnfs_mark_matching_lsegs_invalid(lo, &free_me_list, + if (pnfs_mark_matching_lsegs_return(lo, &free_me_list, &args->cbl_range)) { - pnfs_mark_matching_lsegs_return(lo, - &free_me_list, - &args->cbl_range); rv = NFS4_OK; goto unlock; } -- GitLab From 71b39854a500be0b80cb3bc05546a7962f387b5b Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 4 Jan 2016 12:41:15 -0500 Subject: [PATCH 2230/2855] NFSv4.1/pNFS: Cleanup pnfs_mark_matching_lsegs_invalid() Make it more obvious what we're returning... Signed-off-by: Trond Myklebust --- fs/nfs/pnfs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 8e1d4229bf2df..f86f060f853dd 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -569,7 +569,7 @@ pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, struct pnfs_layout_range *recall_range) { struct pnfs_layout_segment *lseg, *next; - int invalid = 0, removed = 0; + int remaining = 0; dprintk("%s:Begin lo %p\n", __func__, lo); @@ -582,11 +582,11 @@ pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, "offset %llu length %llu\n", __func__, lseg, lseg->pls_range.iomode, lseg->pls_range.offset, lseg->pls_range.length); - invalid++; - removed += mark_lseg_invalid(lseg, tmp_list); + if (!mark_lseg_invalid(lseg, tmp_list)) + remaining++; } - dprintk("%s:Return %i\n", __func__, invalid - removed); - return invalid - removed; + dprintk("%s:Return %i\n", __func__, remaining); + return remaining; } /* note free_me must contain lsegs from a single layout_hdr */ -- GitLab From e144e5391cf0881c9d64750dca8c592f6b5f0378 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 4 Jan 2016 12:52:53 -0500 Subject: [PATCH 2231/2855] NFSv4.1/pnfs: Cleanup copying of pnfs_layout_range structures Signed-off-by: Trond Myklebust --- fs/nfs/pnfs.c | 4 ++-- fs/nfs/pnfs.h | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index f86f060f853dd..ebf896b54d9d1 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -863,7 +863,7 @@ pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo, static struct pnfs_layout_segment * send_layoutget(struct pnfs_layout_hdr *lo, struct nfs_open_context *ctx, - struct pnfs_layout_range *range, + const struct pnfs_layout_range *range, gfp_t gfp_flags) { struct inode *ino = lo->plh_inode; @@ -896,7 +896,7 @@ send_layoutget(struct pnfs_layout_hdr *lo, lgp->args.minlength = i_size - range->offset; } lgp->args.maxcount = PNFS_LAYOUT_MAXSIZE; - lgp->args.range = *range; + pnfs_copy_range(&lgp->args.range, range); lgp->args.type = server->pnfs_curr_ld->id; lgp->args.inode = ino; lgp->args.ctx = get_nfs_open_context(ctx); diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 3d0f513a4a77f..dcc76335fd4bf 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -578,6 +578,13 @@ pnfs_mark_layout_returned_if_empty(struct pnfs_layout_hdr *lo) set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); } +static inline void +pnfs_copy_range(struct pnfs_layout_range *dst, + const struct pnfs_layout_range *src) +{ + memcpy(dst, src, sizeof(*dst)); +} + extern unsigned int layoutstats_timer; #ifdef NFS_DEBUG -- GitLab From 506c0d68269e90d354b3cbfc7523611b026c88d0 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 4 Jan 2016 13:04:47 -0500 Subject: [PATCH 2232/2855] NFSv4.1/pNFS: Cleanup constify struct pnfs_layout_range arguments Signed-off-by: Trond Myklebust --- fs/nfs/pnfs.c | 6 +++--- fs/nfs/pnfs.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index ebf896b54d9d1..04db6d951b997 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -566,7 +566,7 @@ static int mark_lseg_invalid(struct pnfs_layout_segment *lseg, int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, struct list_head *tmp_list, - struct pnfs_layout_range *recall_range) + const struct pnfs_layout_range *recall_range) { struct pnfs_layout_segment *lseg, *next; int remaining = 0; @@ -828,7 +828,7 @@ pnfs_layoutgets_blocked(const struct pnfs_layout_hdr *lo) int pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo, - struct pnfs_layout_range *range, + const struct pnfs_layout_range *range, struct nfs4_state *open_state) { int status = 0; @@ -1771,7 +1771,7 @@ pnfs_set_plh_return_iomode(struct pnfs_layout_hdr *lo, enum pnfs_iomode iomode) int pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, struct list_head *tmp_list, - struct pnfs_layout_range *return_range) + const struct pnfs_layout_range *return_range) { struct pnfs_layout_segment *lseg, *next; int remaining = 0; diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index dcc76335fd4bf..78df618a1596a 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -261,14 +261,14 @@ void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, bool update_barrier); int pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo, - struct pnfs_layout_range *range, + const struct pnfs_layout_range *range, struct nfs4_state *open_state); int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, struct list_head *tmp_list, - struct pnfs_layout_range *recall_range); + const struct pnfs_layout_range *recall_range); int pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, struct list_head *tmp_list, - struct pnfs_layout_range *recall_range); + const struct pnfs_layout_range *recall_range); bool pnfs_roc(struct inode *ino); void pnfs_roc_release(struct inode *ino); void pnfs_roc_set_barrier(struct inode *ino, u32 barrier); -- GitLab From 995e68a5ee6126a23dbfc1097b523c08a6b8bb65 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 4 Jan 2016 09:15:37 -0200 Subject: [PATCH 2233/2855] i2c: imx: Remove unneeded comments These multi-lines comments do not follow the standard kernel coding style. In fact, they are not useful comments, so get rid of them. Signed-off-by: Fabio Estevam Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-imx.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index dcea8d276c226..8b68dbf4786cc 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -29,9 +29,6 @@ * */ -/** Includes ******************************************************************* -*******************************************************************************/ - #include #include #include @@ -57,9 +54,6 @@ #include #include -/** Defines ******************************************************************** -*******************************************************************************/ - /* This will be the driver name the kernel reports */ #define DRIVER_NAME "imx-i2c" @@ -123,9 +117,6 @@ #define I2C_PM_TIMEOUT 10 /* ms */ -/** Variables ****************************************************************** -*******************************************************************************/ - /* * sorted list of clock divider, register value pairs * taken from table 26-5, p.26-9, Freescale i.MX @@ -419,9 +410,6 @@ static void i2c_imx_dma_free(struct imx_i2c_struct *i2c_imx) dma->chan_using = NULL; } -/** Functions for IMX I2C adapter driver *************************************** -*******************************************************************************/ - static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy) { unsigned long orig_jiffies = jiffies; -- GitLab From 90708ce22b4849194d195bad128e94a110426434 Mon Sep 17 00:00:00 2001 From: Suravee Suthikulpanit Date: Tue, 15 Dec 2015 15:55:53 -0600 Subject: [PATCH 2234/2855] i2c: designware: Add support for AMD Seattle I2C Add device HID AMDI0510 to match the I2C controlers on AMD Seattle platform Signed-off-by: Suravee Suthikulpanit Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-platdrv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 809579ecb5a44..8ffc36b8a6d39 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -117,6 +117,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = { { "80860F41", 0 }, { "808622C1", 0 }, { "AMD0010", 0 }, + { "AMDI0510", 0 }, { } }; MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match); -- GitLab From d4f50ee2f5b45fc4d9e4142a52edf8b7935a9275 Mon Sep 17 00:00:00 2001 From: Pierre Morel Date: Wed, 23 Dec 2015 13:08:05 +0100 Subject: [PATCH 2235/2855] vfio/iommu_type1: make use of info.flags The flags entry is there to tell the user that some optional information is available. Since we report the iova_pgsizes signal it to the user by setting the flags to VFIO_IOMMU_INFO_PGSIZES. Signed-off-by: Pierre Morel Signed-off-by: Alex Williamson --- drivers/vfio/vfio_iommu_type1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index 59d47cb638d5d..6f1ea3dddbad9 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -995,7 +995,7 @@ static long vfio_iommu_type1_ioctl(void *iommu_data, if (info.argsz < minsz) return -EINVAL; - info.flags = 0; + info.flags = VFIO_IOMMU_INFO_PGSIZES; info.iova_pgsizes = vfio_pgsize_bitmap(iommu); -- GitLab From 7088c4136fa1cba26531fde40bdcfcf3d2ccd533 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 5 Jan 2016 07:40:16 +1100 Subject: [PATCH 2236/2855] xfs: detect and trim torn writes during log recovery Certain types of storage, such as persistent memory, do not provide sector atomicity for writes. This means that if a crash occurs while XFS is writing log records, only part of those records might make it to the storage. This is problematic because log recovery uses the cycle value packed at the top of each log block to locate the head/tail of the log. This can lead to CRC verification failures during log recovery and an unmountable fs for a filesystem that is otherwise consistent. Update log recovery to incorporate log record CRC verification as part of the head/tail discovery process. Once the head is located via the traditional algorithm, run a CRC-only pass over the records up to the head of the log. If CRC verification fails, assume that the records are torn as a matter of policy and trim the head block back to the start of the first bad record. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_log_recover.c | 309 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 289 insertions(+), 20 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 423c36dbcdead..26e67b4450cc1 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -61,6 +61,9 @@ xlog_recover_check_summary( #else #define xlog_recover_check_summary(log) #endif +STATIC int +xlog_do_recovery_pass( + struct xlog *, xfs_daddr_t, xfs_daddr_t, int, xfs_daddr_t *); /* * This structure is used during recovery to record the buf log items which @@ -940,6 +943,278 @@ out_error: return error; } +/* + * Seek forward in the log for log record headers. + * + * Given head and tail blocks, walk forward from the tail block until we find + * the provided number of records or hit the head block. The return value is the + * number of records encountered or a negative error code. The log block and + * buffer pointer of the last record seen are returned in rblk and rhead + * respectively. + */ +STATIC int +xlog_seek_logrec_hdr( + struct xlog *log, + xfs_daddr_t head_blk, + xfs_daddr_t tail_blk, + int count, + struct xfs_buf *bp, + xfs_daddr_t *rblk, + struct xlog_rec_header **rhead, + bool *wrapped) +{ + int i; + int error; + int found = 0; + char *offset = NULL; + xfs_daddr_t end_blk; + + *wrapped = false; + + /* + * Walk forward from the tail block until we hit the head or the last + * block in the log. + */ + end_blk = head_blk > tail_blk ? head_blk : log->l_logBBsize - 1; + for (i = (int) tail_blk; i <= end_blk; i++) { + error = xlog_bread(log, i, 1, bp, &offset); + if (error) + goto out_error; + + if (*(__be32 *) offset == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { + *rblk = i; + *rhead = (struct xlog_rec_header *) offset; + if (++found == count) + break; + } + } + + /* + * If we haven't hit the head block or the log record header count, + * start looking again from the start of the physical log. + */ + if (tail_blk > head_blk && found != count) { + for (i = 0; i < (int) head_blk; i++) { + error = xlog_bread(log, i, 1, bp, &offset); + if (error) + goto out_error; + + if (*(__be32 *)offset == + cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { + *wrapped = true; + *rblk = i; + *rhead = (struct xlog_rec_header *) offset; + if (++found == count) + break; + } + } + } + + return found; + +out_error: + return error; +} + +/* + * Check the log tail for torn writes. This is required when torn writes are + * detected at the head and the head had to be walked back to a previous record. + * The tail of the previous record must now be verified to ensure the torn + * writes didn't corrupt the previous tail. + * + * Return an error if CRC verification fails as recovery cannot proceed. + */ +STATIC int +xlog_verify_tail( + struct xlog *log, + xfs_daddr_t head_blk, + xfs_daddr_t tail_blk) +{ + struct xlog_rec_header *thead; + struct xfs_buf *bp; + xfs_daddr_t first_bad; + int count; + int error = 0; + bool wrapped; + xfs_daddr_t tmp_head; + + bp = xlog_get_bp(log, 1); + if (!bp) + return -ENOMEM; + + /* + * Seek XLOG_MAX_ICLOGS + 1 records past the current tail record to get + * a temporary head block that points after the last possible + * concurrently written record of the tail. + */ + count = xlog_seek_logrec_hdr(log, head_blk, tail_blk, + XLOG_MAX_ICLOGS + 1, bp, &tmp_head, &thead, + &wrapped); + if (count < 0) { + error = count; + goto out; + } + + /* + * If the call above didn't find XLOG_MAX_ICLOGS + 1 records, we ran + * into the actual log head. tmp_head points to the start of the record + * so update it to the actual head block. + */ + if (count < XLOG_MAX_ICLOGS + 1) + tmp_head = head_blk; + + /* + * We now have a tail and temporary head block that covers at least + * XLOG_MAX_ICLOGS records from the tail. We need to verify that these + * records were completely written. Run a CRC verification pass from + * tail to head and return the result. + */ + error = xlog_do_recovery_pass(log, tmp_head, tail_blk, + XLOG_RECOVER_CRCPASS, &first_bad); + +out: + xlog_put_bp(bp); + return error; +} + +/* + * Detect and trim torn writes from the head of the log. + * + * Storage without sector atomicity guarantees can result in torn writes in the + * log in the event of a crash. Our only means to detect this scenario is via + * CRC verification. While we can't always be certain that CRC verification + * failure is due to a torn write vs. an unrelated corruption, we do know that + * only a certain number (XLOG_MAX_ICLOGS) of log records can be written out at + * one time. Therefore, CRC verify up to XLOG_MAX_ICLOGS records at the head of + * the log and treat failures in this range as torn writes as a matter of + * policy. In the event of CRC failure, the head is walked back to the last good + * record in the log and the tail is updated from that record and verified. + */ +STATIC int +xlog_verify_head( + struct xlog *log, + xfs_daddr_t *head_blk, /* in/out: unverified head */ + xfs_daddr_t *tail_blk, /* out: tail block */ + struct xfs_buf *bp, + xfs_daddr_t *rhead_blk, /* start blk of last record */ + struct xlog_rec_header **rhead, /* ptr to last record */ + bool *wrapped) /* last rec. wraps phys. log */ +{ + struct xlog_rec_header *tmp_rhead; + struct xfs_buf *tmp_bp; + xfs_daddr_t first_bad; + xfs_daddr_t tmp_rhead_blk; + int found; + int error; + bool tmp_wrapped; + + /* + * Search backwards through the log looking for the log record header + * block. This wraps all the way back around to the head so something is + * seriously wrong if we can't find it. + */ + found = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, bp, rhead_blk, + rhead, wrapped); + if (found < 0) + return found; + if (!found) { + xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__); + return -EIO; + } + + *tail_blk = BLOCK_LSN(be64_to_cpu((*rhead)->h_tail_lsn)); + + /* + * Now that we have a tail block, check the head of the log for torn + * writes. Search again until we hit the tail or the maximum number of + * log record I/Os that could have been in flight at one time. Use a + * temporary buffer so we don't trash the rhead/bp pointer from the + * call above. + */ + tmp_bp = xlog_get_bp(log, 1); + if (!tmp_bp) + return -ENOMEM; + error = xlog_rseek_logrec_hdr(log, *head_blk, *tail_blk, + XLOG_MAX_ICLOGS, tmp_bp, &tmp_rhead_blk, + &tmp_rhead, &tmp_wrapped); + xlog_put_bp(tmp_bp); + if (error < 0) + return error; + + /* + * Now run a CRC verification pass over the records starting at the + * block found above to the current head. If a CRC failure occurs, the + * log block of the first bad record is saved in first_bad. + */ + error = xlog_do_recovery_pass(log, *head_blk, tmp_rhead_blk, + XLOG_RECOVER_CRCPASS, &first_bad); + if (error == -EFSBADCRC) { + /* + * We've hit a potential torn write. Reset the error and warn + * about it. + */ + error = 0; + xfs_warn(log->l_mp, +"Torn write (CRC failure) detected at log block 0x%llx. Truncating head block from 0x%llx.", + first_bad, *head_blk); + + /* + * Get the header block and buffer pointer for the last good + * record before the bad record. + * + * Note that xlog_find_tail() clears the blocks at the new head + * (i.e., the records with invalid CRC) if the cycle number + * matches the the current cycle. + */ + found = xlog_rseek_logrec_hdr(log, first_bad, *tail_blk, 1, bp, + rhead_blk, rhead, wrapped); + if (found < 0) + return found; + if (found == 0) /* XXX: right thing to do here? */ + return -EIO; + + /* + * Reset the head block to the starting block of the first bad + * log record and set the tail block based on the last good + * record. + * + * Bail out if the updated head/tail match as this indicates + * possible corruption outside of the acceptable + * (XLOG_MAX_ICLOGS) range. This is a job for xfs_repair... + */ + *head_blk = first_bad; + *tail_blk = BLOCK_LSN(be64_to_cpu((*rhead)->h_tail_lsn)); + if (*head_blk == *tail_blk) { + ASSERT(0); + return 0; + } + + /* + * Now verify the tail based on the updated head. This is + * required because the torn writes trimmed from the head could + * have been written over the tail of a previous record. Return + * any errors since recovery cannot proceed if the tail is + * corrupt. + * + * XXX: This leaves a gap in truly robust protection from torn + * writes in the log. If the head is behind the tail, the tail + * pushes forward to create some space and then a crash occurs + * causing the writes into the previous record's tail region to + * tear, log recovery isn't able to recover. + * + * How likely is this to occur? If possible, can we do something + * more intelligent here? Is it safe to push the tail forward if + * we can determine that the tail is within the range of the + * torn write (e.g., the kernel can only overwrite the tail if + * it has actually been pushed forward)? Alternatively, could we + * somehow prevent this condition at runtime? + */ + error = xlog_verify_tail(log, *head_blk, *tail_blk); + } + + return error; +} + /* * Find the sync block number or the tail of the log. * @@ -966,9 +1241,10 @@ xlog_find_tail( xlog_op_header_t *op_head; char *offset = NULL; xfs_buf_t *bp; - int error, i, found; + int error; xfs_daddr_t umount_data_blk; xfs_daddr_t after_umount_blk; + xfs_daddr_t rhead_blk; xfs_lsn_t tail_lsn; int hblks; bool wrapped = false; @@ -995,24 +1271,16 @@ xlog_find_tail( } /* - * Search backwards through the log looking for the log record header - * block. This wraps all the way back around to the head so something is - * seriously wrong if we can't find it. + * Trim the head block back to skip over torn records. We can have + * multiple log I/Os in flight at any time, so we assume CRC failures + * back through the previous several records are torn writes and skip + * them. */ ASSERT(*head_blk < INT_MAX); - found = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, bp, &i, - &rhead, &wrapped); - if (found < 0) { - error = found; + error = xlog_verify_head(log, head_blk, tail_blk, bp, &rhead_blk, + &rhead, &wrapped); + if (error) goto done; - } - if (!found) { - xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__); - xlog_put_bp(bp); - ASSERT(0); - return -EIO; - } - *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn)); /* * Reset log values according to the state of the log when we @@ -1024,7 +1292,7 @@ xlog_find_tail( * written was complete and ended exactly on the end boundary * of the physical log. */ - log->l_prev_block = i; + log->l_prev_block = rhead_blk; log->l_curr_block = (int)*head_blk; log->l_curr_cycle = be32_to_cpu(rhead->h_cycle); if (wrapped) @@ -1062,12 +1330,13 @@ xlog_find_tail( } else { hblks = 1; } - after_umount_blk = (i + hblks + (int) - BTOBB(be32_to_cpu(rhead->h_len))) % log->l_logBBsize; + after_umount_blk = rhead_blk + hblks + BTOBB(be32_to_cpu(rhead->h_len)); + after_umount_blk = do_mod(after_umount_blk, log->l_logBBsize); tail_lsn = atomic64_read(&log->l_tail_lsn); if (*head_blk == after_umount_blk && be32_to_cpu(rhead->h_num_logops) == 1) { - umount_data_blk = (i + hblks) % log->l_logBBsize; + umount_data_blk = rhead_blk + hblks; + umount_data_blk = do_mod(umount_data_blk, log->l_logBBsize); error = xlog_bread(log, umount_data_blk, 1, bp, &offset); if (error) goto done; -- GitLab From 609adfc2ed5ba16700f125da0b656248bd9d4316 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 5 Jan 2016 07:41:16 +1100 Subject: [PATCH 2237/2855] xfs: debug mode log record crc error injection XFS now uses CRC verification over a limited section of the log to detect torn writes prior to a crash. This is difficult to test directly due to the timing and hardware requirements to cause a short write. Add a mechanism to inject CRC errors into log records to facilitate testing torn write detection during log recovery. This mechanism is dangerous and can result in filesystem corruption. Thus, it is only available in DEBUG mode for testing/development purposes. Set a non-zero value to the following sysfs entry to enable error injection: /sys/fs/xfs//log/log_badcrc_factor Once enabled, XFS intentionally writes an invalid CRC to a log record at some random point in the future based on the provided frequency. The filesystem immediately shuts down once the record has been written to the physical log to prevent metadata writeback (e.g., AIL insertion) once the log write completes. This helps reasonably simulate a torn write to the log as the affected record must be safe to discard. The next mount after the intentional shutdown requires log recovery and should detect and recover from the torn write. Note again that this _will_ result in data loss or worse. For testing and development purposes only! Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_log.c | 45 ++++++++++++++++++++++++++++++++++++------- fs/xfs/xfs_log_priv.h | 3 +++ fs/xfs/xfs_sysfs.c | 36 ++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 7 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index f52c72a1a06f2..887c44320909a 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1188,10 +1188,16 @@ xlog_iodone(xfs_buf_t *bp) int aborted = 0; /* - * Race to shutdown the filesystem if we see an error. + * Race to shutdown the filesystem if we see an error or the iclog is in + * IOABORT state. The IOABORT state is only set in DEBUG mode to inject + * CRC errors into log recovery. */ - if (XFS_TEST_ERROR(bp->b_error, l->l_mp, - XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) { + if (XFS_TEST_ERROR(bp->b_error, l->l_mp, XFS_ERRTAG_IODONE_IOERR, + XFS_RANDOM_IODONE_IOERR) || + iclog->ic_state & XLOG_STATE_IOABORT) { + if (iclog->ic_state & XLOG_STATE_IOABORT) + iclog->ic_state &= ~XLOG_STATE_IOABORT; + xfs_buf_ioerror_alert(bp, __func__); xfs_buf_stale(bp); xfs_force_shutdown(l->l_mp, SHUTDOWN_LOG_IO_ERROR); @@ -1838,6 +1844,23 @@ xlog_sync( /* calculcate the checksum */ iclog->ic_header.h_crc = xlog_cksum(log, &iclog->ic_header, iclog->ic_datap, size); +#ifdef DEBUG + /* + * Intentionally corrupt the log record CRC based on the error injection + * frequency, if defined. This facilitates testing log recovery in the + * event of torn writes. Hence, set the IOABORT state to abort the log + * write on I/O completion and shutdown the fs. The subsequent mount + * detects the bad CRC and attempts to recover. + */ + if (log->l_badcrc_factor && + (prandom_u32() % log->l_badcrc_factor == 0)) { + iclog->ic_header.h_crc &= 0xAAAAAAAA; + iclog->ic_state |= XLOG_STATE_IOABORT; + xfs_warn(log->l_mp, + "Intentionally corrupted log record at LSN 0x%llx. Shutdown imminent.", + be64_to_cpu(iclog->ic_header.h_lsn)); + } +#endif bp->b_io_length = BTOBB(count); bp->b_fspriv = iclog; @@ -2791,11 +2814,19 @@ xlog_state_do_callback( } } while (!ioerrors && loopdidcallbacks); +#ifdef DEBUG /* - * make one last gasp attempt to see if iclogs are being left in - * limbo.. + * Make one last gasp attempt to see if iclogs are being left in limbo. + * If the above loop finds an iclog earlier than the current iclog and + * in one of the syncing states, the current iclog is put into + * DO_CALLBACK and the callbacks are deferred to the completion of the + * earlier iclog. Walk the iclogs in order and make sure that no iclog + * is in DO_CALLBACK unless an earlier iclog is in one of the syncing + * states. + * + * Note that SYNCING|IOABORT is a valid state so we cannot just check + * for ic_state == SYNCING. */ -#ifdef DEBUG if (funcdidcallbacks) { first_iclog = iclog = log->l_iclog; do { @@ -2810,7 +2841,7 @@ xlog_state_do_callback( * IOERROR - give up hope all ye who enter here */ if (iclog->ic_state == XLOG_STATE_WANT_SYNC || - iclog->ic_state == XLOG_STATE_SYNCING || + iclog->ic_state & XLOG_STATE_SYNCING || iclog->ic_state == XLOG_STATE_DONE_SYNC || iclog->ic_state == XLOG_STATE_IOERROR ) break; diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 8daba7491b13f..ed8896310c00b 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -62,6 +62,7 @@ static inline uint xlog_get_client_id(__be32 i) #define XLOG_STATE_CALLBACK 0x0020 /* Callback functions now */ #define XLOG_STATE_DIRTY 0x0040 /* Dirty IC log, not ready for ACTIVE status*/ #define XLOG_STATE_IOERROR 0x0080 /* IO error happened in sync'ing log */ +#define XLOG_STATE_IOABORT 0x0100 /* force abort on I/O completion (debug) */ #define XLOG_STATE_ALL 0x7FFF /* All possible valid flags */ #define XLOG_STATE_NOTUSED 0x8000 /* This IC log not being used */ @@ -410,6 +411,8 @@ struct xlog { /* The following field are used for debugging; need to hold icloglock */ #ifdef DEBUG void *l_iclog_bak[XLOG_MAX_ICLOGS]; + /* log record crc error injection factor */ + uint32_t l_badcrc_factor; #endif }; diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c index ee70f5dec9dcc..641d625eb334c 100644 --- a/fs/xfs/xfs_sysfs.c +++ b/fs/xfs/xfs_sysfs.c @@ -255,11 +255,47 @@ write_grant_head_show( } XFS_SYSFS_ATTR_RO(write_grant_head); +#ifdef DEBUG +STATIC ssize_t +log_badcrc_factor_store( + struct kobject *kobject, + const char *buf, + size_t count) +{ + struct xlog *log = to_xlog(kobject); + int ret; + uint32_t val; + + ret = kstrtouint(buf, 0, &val); + if (ret) + return ret; + + log->l_badcrc_factor = val; + + return count; +} + +STATIC ssize_t +log_badcrc_factor_show( + struct kobject *kobject, + char *buf) +{ + struct xlog *log = to_xlog(kobject); + + return snprintf(buf, PAGE_SIZE, "%d\n", log->l_badcrc_factor); +} + +XFS_SYSFS_ATTR_RW(log_badcrc_factor); +#endif /* DEBUG */ + static struct attribute *xfs_log_attrs[] = { ATTR_LIST(log_head_lsn), ATTR_LIST(log_tail_lsn), ATTR_LIST(reserve_grant_head), ATTR_LIST(write_grant_head), +#ifdef DEBUG + ATTR_LIST(log_badcrc_factor), +#endif NULL, }; -- GitLab From a8036dfba94d2ddf70cc9d7e9c627b179f957299 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sun, 6 Dec 2015 22:19:40 +0000 Subject: [PATCH 2238/2855] cciss: print max outstanding commands as a hex value The max outstanding commands is being printed with a 0x prefix to suggest it is a hex value, when in fact the integer decimal %d format specifier is being used and this is a bit confusing. Use %x instead to match the proceeding 0x prefix. Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen --- drivers/block/cciss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 0422c47261c3a..2758982ac1936 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -3854,7 +3854,7 @@ static void print_cfg_table(ctlr_info_t *h) readl(&(tb->HostWrite.CoalIntDelay))); dev_dbg(&h->pdev->dev, " Coalesce Interrupt Count = 0x%x\n", readl(&(tb->HostWrite.CoalIntCount))); - dev_dbg(&h->pdev->dev, " Max outstanding commands = 0x%d\n", + dev_dbg(&h->pdev->dev, " Max outstanding commands = 0x%x\n", readl(&(tb->CmdsOutMax))); dev_dbg(&h->pdev->dev, " Bus Types = 0x%x\n", readl(&(tb->BusTypes))); -- GitLab From f199b2605c25a0076cdd5c6a9e7eece77f95ce61 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 16 Dec 2015 15:48:13 +1100 Subject: [PATCH 2239/2855] i2c: ibm_iic: rename i2c_timings struct due to clash with generic version Fixes: e1dba01ca620 ("i2c: add generic routine to parse DT for timing information") Signed-off-by: Stephen Rothwell Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-ibm_iic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index ab492301581a0..b6c0803342973 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -99,7 +99,7 @@ static void dump_iic_regs(const char* header, struct ibm_iic_private* dev) #endif /* Bus timings (in ns) for bit-banging */ -static struct i2c_timings { +static struct ibm_iic_timings { unsigned int hd_sta; unsigned int su_sto; unsigned int low; @@ -241,7 +241,7 @@ static int iic_dc_wait(volatile struct iic_regs __iomem *iic, u8 mask) static int iic_smbus_quick(struct ibm_iic_private* dev, const struct i2c_msg* p) { volatile struct iic_regs __iomem *iic = dev->vaddr; - const struct i2c_timings* t = &timings[dev->fast_mode ? 1 : 0]; + const struct ibm_iic_timings *t = &timings[dev->fast_mode ? 1 : 0]; u8 mask, v, sda; int i, res; -- GitLab From 7b8ad495d59280b634a7b546f4cdf58cf4d65f61 Mon Sep 17 00:00:00 2001 From: Vaibhav Jain Date: Tue, 24 Nov 2015 16:26:18 +0530 Subject: [PATCH 2240/2855] cxl: Fix DSI misses when the context owning task exits Presently when a user-space process issues CXL_IOCTL_START_WORK ioctl we store the pid of the current task_struct and use it to get pointer to the mm_struct of the process, while processing page or segment faults from the capi card. However this causes issues when the thread that had originally issued the start-work ioctl exits in which case the stored pid is no more valid and the cxl driver is unable to handle faults as the mm_struct corresponding to process is no more accessible. This patch fixes this issue by using the mm_struct of the next alive task in the thread group. This is done by iterating over all the tasks in the thread group starting from thread group leader and calling get_task_mm on each one of them. When a valid mm_struct is obtained the pid of the associated task is stored in the context replacing the exiting one for handling future faults. The patch introduces a new function named get_mem_context that checks if the current task pointed to by ctx->pid is dead? If yes it performs the steps described above. Also a new variable cxl_context.glpid is introduced which stores the pid of the thread group leader associated with the context owning task. Reported-by: Matthew R. Ochs Reported-by: Frank Haverkamp Suggested-by: Ian Munsie Signed-off-by: Vaibhav Jain Acked-by: Ian Munsie Reviewed-by: Frederic Barrat Reviewed-by: Matthew R. Ochs Signed-off-by: Michael Ellerman --- drivers/misc/cxl/api.c | 2 +- drivers/misc/cxl/context.c | 6 +- drivers/misc/cxl/cxl.h | 3 + drivers/misc/cxl/fault.c | 129 +++++++++++++++++++++++++++---------- drivers/misc/cxl/file.c | 6 +- 5 files changed, 109 insertions(+), 37 deletions(-) diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c index a6543aefa299d..ea3eeb7011e17 100644 --- a/drivers/misc/cxl/api.c +++ b/drivers/misc/cxl/api.c @@ -172,7 +172,7 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed, if (task) { ctx->pid = get_task_pid(task, PIDTYPE_PID); - get_pid(ctx->pid); + ctx->glpid = get_task_pid(task->group_leader, PIDTYPE_PID); kernel = false; } diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c index 6dde7a9d6a7e2..262b88eac414a 100644 --- a/drivers/misc/cxl/context.c +++ b/drivers/misc/cxl/context.c @@ -42,7 +42,7 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master, spin_lock_init(&ctx->sste_lock); ctx->afu = afu; ctx->master = master; - ctx->pid = NULL; /* Set in start work ioctl */ + ctx->pid = ctx->glpid = NULL; /* Set in start work ioctl */ mutex_init(&ctx->mapping_lock); ctx->mapping = mapping; @@ -217,7 +217,11 @@ int __detach_context(struct cxl_context *ctx) WARN_ON(cxl_detach_process(ctx) && cxl_adapter_link_ok(ctx->afu->adapter)); flush_work(&ctx->fault_work); /* Only needed for dedicated process */ + + /* release the reference to the group leader and mm handling pid */ put_pid(ctx->pid); + put_pid(ctx->glpid); + cxl_ctx_put(); return 0; } diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index 25ae57fa79b0f..a521bc72cec2d 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -445,6 +445,9 @@ struct cxl_context { unsigned int sst_size, sst_lru; wait_queue_head_t wq; + /* pid of the group leader associated with the pid */ + struct pid *glpid; + /* use mm context associated with this pid for ds faults */ struct pid *pid; spinlock_t lock; /* Protects pending_irq_mask, pending_fault and fault_addr */ /* Only used in PR mode */ diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c index 25a5418c55cb8..81c3f75b73308 100644 --- a/drivers/misc/cxl/fault.c +++ b/drivers/misc/cxl/fault.c @@ -166,13 +166,92 @@ static void cxl_handle_page_fault(struct cxl_context *ctx, cxl_ack_irq(ctx, CXL_PSL_TFC_An_R, 0); } +/* + * Returns the mm_struct corresponding to the context ctx via ctx->pid + * In case the task has exited we use the task group leader accessible + * via ctx->glpid to find the next task in the thread group that has a + * valid mm_struct associated with it. If a task with valid mm_struct + * is found the ctx->pid is updated to use the task struct for subsequent + * translations. In case no valid mm_struct is found in the task group to + * service the fault a NULL is returned. + */ +static struct mm_struct *get_mem_context(struct cxl_context *ctx) +{ + struct task_struct *task = NULL; + struct mm_struct *mm = NULL; + struct pid *old_pid = ctx->pid; + + if (old_pid == NULL) { + pr_warn("%s: Invalid context for pe=%d\n", + __func__, ctx->pe); + return NULL; + } + + task = get_pid_task(old_pid, PIDTYPE_PID); + + /* + * pid_alive may look racy but this saves us from costly + * get_task_mm when the task is a zombie. In worst case + * we may think a task is alive, which is about to die + * but get_task_mm will return NULL. + */ + if (task != NULL && pid_alive(task)) + mm = get_task_mm(task); + + /* release the task struct that was taken earlier */ + if (task) + put_task_struct(task); + else + pr_devel("%s: Context owning pid=%i for pe=%i dead\n", + __func__, pid_nr(old_pid), ctx->pe); + + /* + * If we couldn't find the mm context then use the group + * leader to iterate over the task group and find a task + * that gives us mm_struct. + */ + if (unlikely(mm == NULL && ctx->glpid != NULL)) { + + rcu_read_lock(); + task = pid_task(ctx->glpid, PIDTYPE_PID); + if (task) + do { + mm = get_task_mm(task); + if (mm) { + ctx->pid = get_task_pid(task, + PIDTYPE_PID); + break; + } + task = next_thread(task); + } while (task && !thread_group_leader(task)); + rcu_read_unlock(); + + /* check if we switched pid */ + if (ctx->pid != old_pid) { + if (mm) + pr_devel("%s:pe=%i switch pid %i->%i\n", + __func__, ctx->pe, pid_nr(old_pid), + pid_nr(ctx->pid)); + else + pr_devel("%s:Cannot find mm for pid=%i\n", + __func__, pid_nr(old_pid)); + + /* drop the reference to older pid */ + put_pid(old_pid); + } + } + + return mm; +} + + + void cxl_handle_fault(struct work_struct *fault_work) { struct cxl_context *ctx = container_of(fault_work, struct cxl_context, fault_work); u64 dsisr = ctx->dsisr; u64 dar = ctx->dar; - struct task_struct *task = NULL; struct mm_struct *mm = NULL; if (cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An) != dsisr || @@ -195,17 +274,17 @@ void cxl_handle_fault(struct work_struct *fault_work) "DSISR: %#llx DAR: %#llx\n", ctx->pe, dsisr, dar); if (!ctx->kernel) { - if (!(task = get_pid_task(ctx->pid, PIDTYPE_PID))) { - pr_devel("cxl_handle_fault unable to get task %i\n", - pid_nr(ctx->pid)); + + mm = get_mem_context(ctx); + /* indicates all the thread in task group have exited */ + if (mm == NULL) { + pr_devel("%s: unable to get mm for pe=%d pid=%i\n", + __func__, ctx->pe, pid_nr(ctx->pid)); cxl_ack_ae(ctx); return; - } - if (!(mm = get_task_mm(task))) { - pr_devel("cxl_handle_fault unable to get mm %i\n", - pid_nr(ctx->pid)); - cxl_ack_ae(ctx); - goto out; + } else { + pr_devel("Handling page fault for pe=%d pid=%i\n", + ctx->pe, pid_nr(ctx->pid)); } } @@ -218,33 +297,22 @@ void cxl_handle_fault(struct work_struct *fault_work) if (mm) mmput(mm); -out: - if (task) - put_task_struct(task); } static void cxl_prefault_one(struct cxl_context *ctx, u64 ea) { - int rc; - struct task_struct *task; struct mm_struct *mm; - if (!(task = get_pid_task(ctx->pid, PIDTYPE_PID))) { - pr_devel("cxl_prefault_one unable to get task %i\n", - pid_nr(ctx->pid)); - return; - } - if (!(mm = get_task_mm(task))) { + mm = get_mem_context(ctx); + if (mm == NULL) { pr_devel("cxl_prefault_one unable to get mm %i\n", pid_nr(ctx->pid)); - put_task_struct(task); return; } - rc = cxl_fault_segment(ctx, mm, ea); + cxl_fault_segment(ctx, mm, ea); mmput(mm); - put_task_struct(task); } static u64 next_segment(u64 ea, u64 vsid) @@ -263,18 +331,13 @@ static void cxl_prefault_vma(struct cxl_context *ctx) struct copro_slb slb; struct vm_area_struct *vma; int rc; - struct task_struct *task; struct mm_struct *mm; - if (!(task = get_pid_task(ctx->pid, PIDTYPE_PID))) { - pr_devel("cxl_prefault_vma unable to get task %i\n", - pid_nr(ctx->pid)); - return; - } - if (!(mm = get_task_mm(task))) { + mm = get_mem_context(ctx); + if (mm == NULL) { pr_devel("cxl_prefault_vm unable to get mm %i\n", pid_nr(ctx->pid)); - goto out1; + return; } down_read(&mm->mmap_sem); @@ -295,8 +358,6 @@ static void cxl_prefault_vma(struct cxl_context *ctx) up_read(&mm->mmap_sem); mmput(mm); -out1: - put_task_struct(task); } void cxl_prefault(struct cxl_context *ctx, u64 wed) diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c index 5cc14599837d1..783337d22f36a 100644 --- a/drivers/misc/cxl/file.c +++ b/drivers/misc/cxl/file.c @@ -201,8 +201,12 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, * where a process (master, some daemon, etc) has opened the chardev on * behalf of another process, so the AFU's mm gets bound to the process * that performs this ioctl and not the process that opened the file. + * Also we grab the PID of the group leader so that if the task that + * has performed the attach operation exits the mm context of the + * process is still accessible. */ - ctx->pid = get_pid(get_task_pid(current, PIDTYPE_PID)); + ctx->pid = get_task_pid(current, PIDTYPE_PID); + ctx->glpid = get_task_pid(current->group_leader, PIDTYPE_PID); trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr); -- GitLab From 9033a5f9ac83538502a2bddc62311b09d966799e Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Fri, 1 Jan 2016 20:28:59 +0800 Subject: [PATCH 2241/2855] spi: cadence: use to_platform_device() Use to_platform_device() instead of open-coding it. Signed-off-by: Geliang Tang Reviewed-by: Moritz Fischer Signed-off-by: Mark Brown --- drivers/spi/spi-cadence.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index 5a6749881ff9c..121a4135b5401 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c @@ -617,8 +617,7 @@ static int cdns_spi_remove(struct platform_device *pdev) */ static int __maybe_unused cdns_spi_suspend(struct device *dev) { - struct platform_device *pdev = container_of(dev, - struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); struct spi_master *master = platform_get_drvdata(pdev); struct cdns_spi *xspi = spi_master_get_devdata(master); @@ -641,8 +640,7 @@ static int __maybe_unused cdns_spi_suspend(struct device *dev) */ static int __maybe_unused cdns_spi_resume(struct device *dev) { - struct platform_device *pdev = container_of(dev, - struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); struct spi_master *master = platform_get_drvdata(pdev); struct cdns_spi *xspi = spi_master_get_devdata(master); int ret = 0; -- GitLab From 9d0c1c3332b49570454bb11e55d3c6c7993163da Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Fri, 1 Jan 2016 20:29:00 +0800 Subject: [PATCH 2242/2855] spi: zynq: use to_platform_device() Use to_platform_device() instead of open-coding it. Signed-off-by: Geliang Tang Reviewed-by: Moritz Fischer Signed-off-by: Mark Brown --- drivers/spi/spi-zynqmp-gqspi.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c index f23f36ebaf3dc..aab9b492c627a 100644 --- a/drivers/spi/spi-zynqmp-gqspi.c +++ b/drivers/spi/spi-zynqmp-gqspi.c @@ -917,9 +917,7 @@ static int zynqmp_qspi_start_transfer(struct spi_master *master, */ static int __maybe_unused zynqmp_qspi_suspend(struct device *dev) { - struct platform_device *pdev = container_of(dev, - struct platform_device, - dev); + struct platform_device *pdev = to_platform_device(dev); struct spi_master *master = platform_get_drvdata(pdev); spi_master_suspend(master); @@ -940,9 +938,7 @@ static int __maybe_unused zynqmp_qspi_suspend(struct device *dev) */ static int __maybe_unused zynqmp_qspi_resume(struct device *dev) { - struct platform_device *pdev = container_of(dev, - struct platform_device, - dev); + struct platform_device *pdev = to_platform_device(dev); struct spi_master *master = platform_get_drvdata(pdev); struct zynqmp_qspi *xqspi = spi_master_get_devdata(master); int ret = 0; -- GitLab From 83080a140874b6860b5191b375cfdad267eaa107 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Tue, 5 Jan 2016 22:07:55 +0800 Subject: [PATCH 2243/2855] regulator: core: use dev_to_rdev Use dev_to_rdev() instead of open-coding it. Signed-off-by: Geliang Tang Signed-off-by: Mark Brown --- drivers/regulator/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 73b7683355cd0..0853a80bf7fea 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -3708,7 +3708,7 @@ static umode_t regulator_attr_is_visible(struct kobject *kobj, struct attribute *attr, int idx) { struct device *dev = kobj_to_dev(kobj); - struct regulator_dev *rdev = container_of(dev, struct regulator_dev, dev); + struct regulator_dev *rdev = dev_to_rdev(dev); const struct regulator_ops *ops = rdev->desc->ops; umode_t mode = attr->mode; -- GitLab From d2329fb576d2c7eb0824028d9c6d3d48fb90b11a Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 4 Jan 2016 13:13:21 +0100 Subject: [PATCH 2244/2855] of/unittest: Show broken behaviour in the platform bus Add a single resource to the test bus device to exercise the platform bus code a little more. This isn't strictly a devicetree test, but it is a corner case that the devicetree runs into. Until we've got platform device unittests, it can live here. It doesn't need to be an explicit text because the kernel will oops when it is wrong. Cc: Pantelis Antoniou Cc: Rob Herring Cc: Greg Kroah-Hartman Cc: Ricardo Ribalda Delgado Signed-off-by: Grant Likely [wsa: added the comment provided by Grant, rebased, and tested] Signed-off-by: Wolfram Sang Signed-off-by: Rob Herring --- drivers/of/unittest.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index e16ea5717b7f7..bbff09dee1cf4 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -757,6 +757,11 @@ static void __init of_unittest_match_node(void) } } +static struct resource test_bus_res = { + .start = 0xfffffff8, + .end = 0xfffffff9, + .flags = IORESOURCE_MEM, +}; static const struct platform_device_info test_bus_info = { .name = "unittest-bus", }; @@ -800,6 +805,15 @@ static void __init of_unittest_platform_populate(void) return; test_bus->dev.of_node = np; + /* + * Add a dummy resource to the test bus node after it is + * registered to catch problems with un-inserted resources. The + * DT code doesn't insert the resources, and it has caused the + * kernel to oops in the past. This makes sure the same bug + * doesn't crop up again. + */ + platform_device_add_resources(test_bus, &test_bus_res, 1); + of_platform_populate(np, match, NULL, &test_bus->dev); for_each_child_of_node(np, child) { for_each_child_of_node(child, grandchild) -- GitLab From b80443c2211c7daaabd20fbbe9e7beb3fa3408e0 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 5 Jan 2016 11:17:53 +0900 Subject: [PATCH 2245/2855] of/platform: export of_default_bus_match_table Currently, drivers/bus/uniphier-system-bus.c is kept from being a module due to the unresolved reference to of_default_bus_match_table. Refer to commit 326ea45aa827 ("bus: uniphier: allow only built-in driver"). Signed-off-by: Masahiro Yamada Signed-off-by: Rob Herring --- drivers/of/platform.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/of/platform.c b/drivers/of/platform.c index af98343614d8e..8d103e4968be4 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -31,6 +31,7 @@ const struct of_device_id of_default_bus_match_table[] = { #endif /* CONFIG_ARM_AMBA */ {} /* Empty terminated list */ }; +EXPORT_SYMBOL(of_default_bus_match_table); static int of_dev_node_match(struct device *dev, void *data) { -- GitLab From 414ee536dfb51373c6c4c74dd7a7a65abdf5af51 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 15 Dec 2015 10:55:59 +0100 Subject: [PATCH 2246/2855] ARM: psci: Fix indentation in DT bindings Fix bogus indentation of the PSCI compatible values, reformat. Signed-off-by: Geert Uytterhoeven Acked-by: Lorenzo Pieralisi Acked-by: Mark Rutland Signed-off-by: Rob Herring --- .../devicetree/bindings/arm/psci.txt | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/psci.txt b/Documentation/devicetree/bindings/arm/psci.txt index a9adab84e2feb..a2c4f1d524929 100644 --- a/Documentation/devicetree/bindings/arm/psci.txt +++ b/Documentation/devicetree/bindings/arm/psci.txt @@ -23,17 +23,20 @@ Main node required properties: - compatible : should contain at least one of: - * "arm,psci" : for implementations complying to PSCI versions prior to - 0.2. For these cases function IDs must be provided. - - * "arm,psci-0.2" : for implementations complying to PSCI 0.2. Function - IDs are not required and should be ignored by an OS with PSCI 0.2 - support, but are permitted to be present for compatibility with - existing software when "arm,psci" is later in the compatible list. - - * "arm,psci-1.0" : for implementations complying to PSCI 1.0. PSCI 1.0 is - backward compatible with PSCI 0.2 with minor specification updates, - as defined in the PSCI specification[2]. + * "arm,psci" : For implementations complying to PSCI versions prior + to 0.2. + For these cases function IDs must be provided. + + * "arm,psci-0.2" : For implementations complying to PSCI 0.2. + Function IDs are not required and should be ignored by + an OS with PSCI 0.2 support, but are permitted to be + present for compatibility with existing software when + "arm,psci" is later in the compatible list. + + * "arm,psci-1.0" : For implementations complying to PSCI 1.0. + PSCI 1.0 is backward compatible with PSCI 0.2 with + minor specification updates, as defined in the PSCI + specification[2]. - method : The method of calling the PSCI firmware. Permitted values are: -- GitLab From dc17340e3041511850ff6ec7299551284d6c0eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sat, 26 Dec 2015 00:37:16 +0100 Subject: [PATCH 2247/2855] Fix documentation for adp1653 DT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Property names do not match real names needed by driver itself. This patch fix this problem. Signed-off-by: Pali Rohár Acked-by: Pavel Machek Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/media/i2c/adp1653.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/media/i2c/adp1653.txt b/Documentation/devicetree/bindings/media/i2c/adp1653.txt index 5ce66f2104e37..4cce0de40ee92 100644 --- a/Documentation/devicetree/bindings/media/i2c/adp1653.txt +++ b/Documentation/devicetree/bindings/media/i2c/adp1653.txt @@ -12,12 +12,13 @@ There are two LED outputs available - flash and indicator. One LED is represented by one child node, nodes need to be named "flash" and "indicator". Required properties of the LED child node: -- max-microamp : see Documentation/devicetree/bindings/leds/common.txt +- led-max-microamp : see Documentation/devicetree/bindings/leds/common.txt Required properties of the flash LED child node: - flash-max-microamp : see Documentation/devicetree/bindings/leds/common.txt - flash-timeout-us : see Documentation/devicetree/bindings/leds/common.txt +- led-max-microamp : see Documentation/devicetree/bindings/leds/common.txt Example: @@ -29,9 +30,9 @@ Example: flash { flash-timeout-us = <500000>; flash-max-microamp = <320000>; - max-microamp = <50000>; + led-max-microamp = <50000>; }; indicator { - max-microamp = <17500>; + led-max-microamp = <17500>; }; }; -- GitLab From 4acad4aae10d1fa79a075b38b5c73772c44f576c Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Wed, 2 Dec 2015 10:38:21 +0000 Subject: [PATCH 2248/2855] spi: expose master transfer size limitation. On some SPI controllers it is not feasible to transfer arbitrary amount of data at once. When the limit on transfer size is a few kilobytes at least it makes sense to use the SPI hardware rather than reverting to gpio driver. The protocol drivers need a way to check that they do not sent overly long messages, though. Signed-off-by: Michal Suchanek Signed-off-by: Mark Brown --- include/linux/spi/spi.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index cce80e6dc7d11..3eebc6c235fb2 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -425,6 +425,12 @@ struct spi_master { #define SPI_MASTER_MUST_RX BIT(3) /* requires rx */ #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ + /* + * on some hardware transfer size may be constrained + * the limit may depend on device transfer settings + */ + size_t (*max_transfer_size)(struct spi_device *spi); + /* lock and mutex for SPI bus locking */ spinlock_t bus_lock_spinlock; struct mutex bus_lock_mutex; @@ -832,6 +838,15 @@ extern int spi_async(struct spi_device *spi, struct spi_message *message); extern int spi_async_locked(struct spi_device *spi, struct spi_message *message); +static inline size_t +spi_max_transfer_size(struct spi_device *spi) +{ + struct spi_master *master = spi->master; + if (!master->max_transfer_size) + return SIZE_MAX; + return master->max_transfer_size(spi); +} + /*---------------------------------------------------------------------------*/ /* All these synchronous SPI transfer routines are utilities layered -- GitLab From b541eef125fa3ae0df84572459af4e7084cb6343 Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Wed, 2 Dec 2015 10:38:21 +0000 Subject: [PATCH 2249/2855] spi: fsl-espi: expose maximum transfer size limit The fsl-espi hardware can trasfer at most 64K data so report teh limitation. Based on patch by Heiner Kallweit CC: Heiner Kallweit Signed-off-by: Michal Suchanek Signed-off-by: Mark Brown --- drivers/spi/spi-fsl-espi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index c27124a5ec8ee..7fd6a4c009d25 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -643,6 +643,11 @@ static int fsl_espi_runtime_resume(struct device *dev) } #endif +static size_t fsl_espi_max_transfer_size(struct spi_device *spi) +{ + return SPCOM_TRANLEN_MAX; +} + static struct spi_master * fsl_espi_probe(struct device *dev, struct resource *mem, unsigned int irq) { @@ -670,6 +675,7 @@ static struct spi_master * fsl_espi_probe(struct device *dev, master->cleanup = fsl_espi_cleanup; master->transfer_one_message = fsl_espi_do_one_msg; master->auto_runtime_pm = true; + master->max_transfer_size = fsl_espi_max_transfer_size; mpc8xxx_spi = spi_master_get_devdata(master); -- GitLab From e6520a3c8877d02c471135afb371e79b04409ab8 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Tue, 22 Dec 2015 18:03:21 +0000 Subject: [PATCH 2250/2855] spi: loopback-test: write rx pattern also when running without tx_buf Currently the rx_buf does not get set with the SPI_TEST_PATTERN_UNWRITTEN when tx_buf == NULL in the transfer. Reorder code so that it gets done also under this specific condition. Signed-off-by: Martin Sperl Signed-off-by: Mark Brown --- drivers/spi/spi-loopback-test.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-loopback-test.c b/drivers/spi/spi-loopback-test.c index 7f497acc906ce..8af2e4070153b 100644 --- a/drivers/spi/spi-loopback-test.c +++ b/drivers/spi/spi-loopback-test.c @@ -591,6 +591,10 @@ static int spi_test_fill_tx(struct spi_device *spi, struct spi_test *test) /* fill all transfers with the pattern requested */ for (i = 0; i < test->transfer_count; i++) { + /* fill rx_buf with SPI_TEST_PATTERN_UNWRITTEN */ + if (xfers[i].rx_buf) + memset(xfers[i].rx_buf, SPI_TEST_PATTERN_UNWRITTEN, + xfers[i].len); /* if tx_buf is NULL then skip */ tx_buf = (u8 *)xfers[i].tx_buf; if (!tx_buf) @@ -648,10 +652,6 @@ static int spi_test_fill_tx(struct spi_device *spi, struct spi_test *test) return -EINVAL; } } - /* fill rx_buf with SPI_TEST_PATTERN_UNWRITTEN */ - if (xfers[i].rx_buf) - memset(xfers[i].rx_buf, SPI_TEST_PATTERN_UNWRITTEN, - xfers[i].len); } return 0; -- GitLab From 339ec3ce54e5c7137287dc807555ae69934b2d2a Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Tue, 22 Dec 2015 18:03:22 +0000 Subject: [PATCH 2251/2855] spi: loopback-test: rename method spi_test_fill_tx to spi_test_fill_pattern Rename method spi_test_fill_tx to spi_test_fill_pattern to better describe what it does. Signed-off-by: Martin Sperl Signed-off-by: Mark Brown --- drivers/spi/spi-loopback-test.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-loopback-test.c b/drivers/spi/spi-loopback-test.c index 8af2e4070153b..81fa9068df431 100644 --- a/drivers/spi/spi-loopback-test.c +++ b/drivers/spi/spi-loopback-test.c @@ -574,7 +574,8 @@ static int spi_test_translate(struct spi_device *spi, return -EINVAL; } -static int spi_test_fill_tx(struct spi_device *spi, struct spi_test *test) +static int spi_test_fill_pattern(struct spi_device *spi, + struct spi_test *test) { struct spi_transfer *xfers = test->transfers; u8 *tx_buf; @@ -691,8 +692,8 @@ static int _spi_test_run_iter(struct spi_device *spi, spi_message_add_tail(x, msg); } - /* fill in the transfer data */ - ret = spi_test_fill_tx(spi, test); + /* fill in the transfer buffers with pattern */ + ret = spi_test_fill_pattern(spi, test); if (ret) return ret; -- GitLab From 1e8db97f0e5205c0f6fd20c9a4f38cd871bc467f Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Tue, 22 Dec 2015 18:03:25 +0000 Subject: [PATCH 2252/2855] spi: loopback-test: spi_check_rx_ranges can get always done The spi_check_rx_ranges can always get executed independent of if we have a real loopback situation. Signed-off-by: Martin Sperl Signed-off-by: Mark Brown --- drivers/spi/spi-loopback-test.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-loopback-test.c b/drivers/spi/spi-loopback-test.c index 81fa9068df431..7f79a77c4b68a 100644 --- a/drivers/spi/spi-loopback-test.c +++ b/drivers/spi/spi-loopback-test.c @@ -489,7 +489,18 @@ static int spi_test_check_loopback_result(struct spi_device *spi, struct spi_transfer *xfer; u8 rxb, txb; size_t i; + int ret; + + /* checks rx_buffer pattern are valid with loopback or without */ + ret = spi_check_rx_ranges(spi, msg, rx); + if (ret) + return ret; + /* if we run without loopback, then return now */ + if (!loopback) + return 0; + + /* if applicable to transfer check that rx_buf is equal to tx_buf */ list_for_each_entry(xfer, &msg->transfers, transfer_list) { /* if there is no rx, then no check is needed */ if (!xfer->rx_buf) @@ -521,7 +532,7 @@ static int spi_test_check_loopback_result(struct spi_device *spi, } } - return spi_check_rx_ranges(spi, msg, rx); + return 0; mismatch_error: dev_err(&spi->dev, @@ -847,10 +858,8 @@ int spi_test_execute_msg(struct spi_device *spi, struct spi_test *test, goto exit; } - /* run rx-tests when in loopback mode */ - if (loopback) - ret = spi_test_check_loopback_result(spi, msg, - tx, rx); + /* run rx-buffer tests */ + ret = spi_test_check_loopback_result(spi, msg, tx, rx); } /* if requested or on error dump message (including data) */ -- GitLab From 887e9d3a1f3e93a1c64294649c0dd301035a7892 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 4 Jan 2016 10:32:54 -0800 Subject: [PATCH 2253/2855] mtd: nand: fix for drop unnecessary partition parser data From Stephen: Hi Brian, After merging the l2-mtd tree, today's linux-next build (powerpc ppc44x_defconfig) failed like this: drivers/mtd/nand/ndfc.c: In function 'ndfc_chip_init': drivers/mtd/nand/ndfc.c:177:2: error: 'ppdata' undeclared (first use in this function) ppdata.of_node = flash_np; ^ Caused by commit a61ae81a1907 ("mtd: nand: drop unnecessary partition parser data") The flash node is already correctly assigned using the new helper (nand_set_flash_node()) so the correct fix is indeed to simply drop this line. Fixes: a61ae81a1907 ("mtd: nand: drop unnecessary partition parser data") Signed-off-by: Stephen Rothwell Signed-off-by: Brian Norris --- drivers/mtd/nand/ndfc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 0709ea9dd8ede..7d72f4fe06a13 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -174,7 +174,6 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, return -ENODEV; nand_set_flash_node(chip, flash_np); - ppdata.of_node = flash_np; mtd->name = kasprintf(GFP_KERNEL, "%s.%s", dev_name(&ndfc->ofdev->dev), flash_np->name); if (!mtd->name) { -- GitLab From b46020aa3a8a0f9c7324fe0af4aec4227f947a10 Mon Sep 17 00:00:00 2001 From: Roman Gushchin Date: Mon, 21 Dec 2015 10:50:59 +1100 Subject: [PATCH 2254/2855] md/raid5: remove redundant check in stripe_add_to_batch_list() The stripe_add_to_batch_list() function is called only if stripe_can_batch() returned true, so there is no need for double check. Signed-off-by: Roman Gushchin Cc: Neil Brown Cc: linux-raid@vger.kernel.org Signed-off-by: NeilBrown --- drivers/md/raid5.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 704ef7fcfbf83..22362505f810f 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -772,8 +772,6 @@ static void stripe_add_to_batch_list(struct r5conf *conf, struct stripe_head *sh int hash; int dd_idx; - if (!stripe_can_batch(sh)) - return; /* Don't cross chunks, so stripe pd_idx/qd_idx is the same */ tmp_sec = sh->sector; if (!sector_div(tmp_sec, conf->chunk_sectors)) -- GitLab From ac277c6a8a39bc50f891a3477625330c276bd7f5 Mon Sep 17 00:00:00 2001 From: Goldwyn Rodrigues Date: Mon, 21 Dec 2015 10:50:59 +1100 Subject: [PATCH 2255/2855] md-cluster: Avoid the resync ping-pong If a RESYNCING message with (0,0) has been sent before, do not send it again. This avoids a resync ping pong between the nodes. We read the bitmap lockresource's LVB to figure out the previous value of the RESYNCING message. Signed-off-by: Goldwyn Rodrigues Signed-off-by: NeilBrown --- drivers/md/md-cluster.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index d6a1126d85ce1..e57bbfed16380 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -882,8 +882,16 @@ static int resync_start(struct mddev *mddev) static int resync_info_update(struct mddev *mddev, sector_t lo, sector_t hi) { struct md_cluster_info *cinfo = mddev->cluster_info; + struct resync_info ri; struct cluster_msg cmsg = {0}; + /* do not send zero again, if we have sent before */ + if (hi == 0) { + memcpy(&ri, cinfo->bitmap_lockres->lksb.sb_lvbptr, sizeof(struct resync_info)); + if (le64_to_cpu(ri.hi) == 0) + return 0; + } + add_resync_info(cinfo->bitmap_lockres, lo, hi); /* Re-acquire the lock to refresh LVB */ dlm_lock_sync(cinfo->bitmap_lockres, DLM_LOCK_PW); -- GitLab From 659b254fa7392e32b59a30d4b61fb12c4cd440ff Mon Sep 17 00:00:00 2001 From: Guoqing Jiang Date: Mon, 21 Dec 2015 10:50:59 +1100 Subject: [PATCH 2256/2855] md-cluster: remove a disk asynchronously from cluster environment For cluster raid, if one disk couldn't be reach in one node, then other nodes would receive the REMOVE message for the disk. In receiving node, we can't call md_kick_rdev_from_array to remove the disk from array synchronously since the disk might still be busy in this node. So let's set a ClusterRemove flag on the disk, then let the thread to do the removal job eventually. Signed-off-by: Guoqing Jiang Signed-off-by: Goldwyn Rodrigues Signed-off-by: NeilBrown --- drivers/md/md-cluster.c | 7 +++++-- drivers/md/md.c | 12 ++++++++++++ drivers/md/md.h | 1 + 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index e57bbfed16380..3fd7301fd7afc 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -440,8 +440,11 @@ static void process_remove_disk(struct mddev *mddev, struct cluster_msg *msg) struct md_rdev *rdev = md_find_rdev_nr_rcu(mddev, le32_to_cpu(msg->raid_slot)); - if (rdev) - md_kick_rdev_from_array(rdev); + if (rdev) { + set_bit(ClusterRemove, &rdev->flags); + set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); + md_wakeup_thread(mddev->thread); + } else pr_warn("%s: %d Could not find disk(%d) to REMOVE\n", __func__, __LINE__, le32_to_cpu(msg->raid_slot)); diff --git a/drivers/md/md.c b/drivers/md/md.c index 61aacab424cf1..198e29dffb985 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -8318,6 +8318,18 @@ void md_check_recovery(struct mddev *mddev) goto unlock; } + if (mddev_is_clustered(mddev)) { + struct md_rdev *rdev; + /* kick the device if another node issued a + * remove disk. + */ + rdev_for_each(rdev, mddev) { + if (test_and_clear_bit(ClusterRemove, &rdev->flags) && + rdev->raid_disk < 0) + md_kick_rdev_from_array(rdev); + } + } + if (!mddev->external) { int did_change = 0; spin_lock(&mddev->lock); diff --git a/drivers/md/md.h b/drivers/md/md.h index ca0b643fe3c18..f7b17aef837d7 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -183,6 +183,7 @@ enum flag_bits { * Usually, this device should be faster * than other devices in the array */ + ClusterRemove, }; #define BB_LEN_MASK (0x00000000000001FFULL) -- GitLab From 54a88392cdd84b4a739ce3a986bfabfaff67d9d2 Mon Sep 17 00:00:00 2001 From: Goldwyn Rodrigues Date: Mon, 21 Dec 2015 10:51:00 +1100 Subject: [PATCH 2257/2855] md-cluster: Fix the remove sequence with the new MD reload code The remove disk message does not need metadata_update_start(), but can be an independent message. Signed-off-by: Goldwyn Rodrigues Signed-off-by: Guoqing Jiang Signed-off-by: NeilBrown --- drivers/md/md-cluster.c | 2 +- drivers/md/md.c | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 3fd7301fd7afc..b58374daff32b 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -997,7 +997,7 @@ static int remove_disk(struct mddev *mddev, struct md_rdev *rdev) struct md_cluster_info *cinfo = mddev->cluster_info; cmsg.type = cpu_to_le32(REMOVE); cmsg.raid_slot = cpu_to_le32(rdev->desc_nr); - return __sendmsg(cinfo, &cmsg); + return sendmsg(cinfo, &cmsg); } static int gather_bitmaps(struct md_rdev *rdev) diff --git a/drivers/md/md.c b/drivers/md/md.c index 198e29dffb985..ab3995de0418c 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6134,15 +6134,11 @@ static int hot_remove_disk(struct mddev *mddev, dev_t dev) { char b[BDEVNAME_SIZE]; struct md_rdev *rdev; - int ret = -1; rdev = find_rdev(mddev, dev); if (!rdev) return -ENXIO; - if (mddev_is_clustered(mddev)) - ret = md_cluster_ops->metadata_update_start(mddev); - if (rdev->raid_disk < 0) goto kick_rdev; @@ -6153,7 +6149,7 @@ static int hot_remove_disk(struct mddev *mddev, dev_t dev) goto busy; kick_rdev: - if (mddev_is_clustered(mddev) && ret == 0) + if (mddev_is_clustered(mddev)) md_cluster_ops->remove_disk(mddev, rdev); md_kick_rdev_from_array(rdev); @@ -6162,9 +6158,6 @@ kick_rdev: return 0; busy: - if (mddev_is_clustered(mddev) && ret == 0) - md_cluster_ops->metadata_update_cancel(mddev); - printk(KERN_WARNING "md: cannot remove active disk %s from %s ...\n", bdevname(rdev->bdev,b), mdname(mddev)); return -EBUSY; -- GitLab From 09afd2a8d6ad2c40f3c1ae0b3f83784864cf4c15 Mon Sep 17 00:00:00 2001 From: Goldwyn Rodrigues Date: Mon, 21 Dec 2015 10:51:00 +1100 Subject: [PATCH 2258/2855] md-cluster: Allow spare devices to be marked as faulty If a spare device was marked faulty, it would not be reflected in receiving nodes because it would mark it as activated and continue. Continue the operation, so it may be set as faulty. Signed-off-by: Goldwyn Rodrigues Signed-off-by: NeilBrown --- drivers/md/md.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index ab3995de0418c..f2f855c203e56 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -9106,7 +9106,6 @@ static void check_sb_changes(struct mddev *mddev, struct md_rdev *rdev) ret = remove_and_add_spares(mddev, rdev2); pr_info("Activated spare: %s\n", bdevname(rdev2->bdev,b)); - continue; } /* device faulty * We just want to do the minimum to mark the disk -- GitLab From f6a2dc64ee74477c966f5220b1f560ed6308d010 Mon Sep 17 00:00:00 2001 From: Guoqing Jiang Date: Mon, 21 Dec 2015 10:51:00 +1100 Subject: [PATCH 2259/2855] md-cluster: append some actions when change bitmap from clustered to none For clustered raid, we need to do extra actions when change bitmap to none. 1. check if all the bitmap lock could be get or not, if yes then we can continue the change since cluster raid is only active in current node. Otherwise return fail and unlock the related bitmap locks 2. set nodes to 0 and then leave cluster environment. 3. release other nodes's bitmap lock. Signed-off-by: Guoqing Jiang Signed-off-by: NeilBrown --- drivers/md/md-cluster.c | 57 +++++++++++++++++++++++++++++++++++++++++ drivers/md/md-cluster.h | 2 ++ drivers/md/md.c | 13 ++++++++++ 3 files changed, 72 insertions(+) diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index b58374daff32b..db9375f501aba 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -55,6 +55,7 @@ struct md_cluster_info { int slot_number; struct completion completion; struct dlm_lock_resource *bitmap_lockres; + struct dlm_lock_resource **other_bitmap_lockres; struct dlm_lock_resource *resync_lockres; struct list_head suspend_list; spinlock_t suspend_lock; @@ -803,6 +804,7 @@ static void resync_bitmap(struct mddev *mddev) __func__, __LINE__, err); } +static void unlock_all_bitmaps(struct mddev *mddev); static int leave(struct mddev *mddev) { struct md_cluster_info *cinfo = mddev->cluster_info; @@ -823,6 +825,7 @@ static int leave(struct mddev *mddev) lockres_free(cinfo->ack_lockres); lockres_free(cinfo->no_new_dev_lockres); lockres_free(cinfo->bitmap_lockres); + unlock_all_bitmaps(mddev); dlm_release_lockspace(cinfo->lockspace, 2); return 0; } @@ -1000,6 +1003,58 @@ static int remove_disk(struct mddev *mddev, struct md_rdev *rdev) return sendmsg(cinfo, &cmsg); } +static int lock_all_bitmaps(struct mddev *mddev) +{ + int slot, my_slot, ret, held = 1, i = 0; + char str[64]; + struct md_cluster_info *cinfo = mddev->cluster_info; + + cinfo->other_bitmap_lockres = kzalloc((mddev->bitmap_info.nodes - 1) * + sizeof(struct dlm_lock_resource *), + GFP_KERNEL); + if (!cinfo->other_bitmap_lockres) { + pr_err("md: can't alloc mem for other bitmap locks\n"); + return 0; + } + + my_slot = slot_number(mddev); + for (slot = 0; slot < mddev->bitmap_info.nodes; slot++) { + if (slot == my_slot) + continue; + + memset(str, '\0', 64); + snprintf(str, 64, "bitmap%04d", slot); + cinfo->other_bitmap_lockres[i] = lockres_init(mddev, str, NULL, 1); + if (!cinfo->other_bitmap_lockres[i]) + return -ENOMEM; + + cinfo->other_bitmap_lockres[i]->flags |= DLM_LKF_NOQUEUE; + ret = dlm_lock_sync(cinfo->other_bitmap_lockres[i], DLM_LOCK_PW); + if (ret) + held = -1; + i++; + } + + return held; +} + +static void unlock_all_bitmaps(struct mddev *mddev) +{ + struct md_cluster_info *cinfo = mddev->cluster_info; + int i; + + /* release other node's bitmap lock if they are existed */ + if (cinfo->other_bitmap_lockres) { + for (i = 0; i < mddev->bitmap_info.nodes - 1; i++) { + if (cinfo->other_bitmap_lockres[i]) { + dlm_unlock_sync(cinfo->other_bitmap_lockres[i]); + lockres_free(cinfo->other_bitmap_lockres[i]); + } + } + kfree(cinfo->other_bitmap_lockres); + } +} + static int gather_bitmaps(struct md_rdev *rdev) { int sn, err; @@ -1045,6 +1100,8 @@ static struct md_cluster_operations cluster_ops = { .new_disk_ack = new_disk_ack, .remove_disk = remove_disk, .gather_bitmaps = gather_bitmaps, + .lock_all_bitmaps = lock_all_bitmaps, + .unlock_all_bitmaps = unlock_all_bitmaps, }; static int __init cluster_init(void) diff --git a/drivers/md/md-cluster.h b/drivers/md/md-cluster.h index e75ea26131845..45ce6c97d8bdb 100644 --- a/drivers/md/md-cluster.h +++ b/drivers/md/md-cluster.h @@ -24,6 +24,8 @@ struct md_cluster_operations { int (*new_disk_ack)(struct mddev *mddev, bool ack); int (*remove_disk)(struct mddev *mddev, struct md_rdev *rdev); int (*gather_bitmaps)(struct md_rdev *rdev); + int (*lock_all_bitmaps)(struct mddev *mddev); + void (*unlock_all_bitmaps)(struct mddev *mddev); }; #endif /* _MD_CLUSTER_H */ diff --git a/drivers/md/md.c b/drivers/md/md.c index f2f855c203e56..495d8aa0a0d25 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6599,6 +6599,19 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info) rv = -EINVAL; goto err; } + if (mddev->bitmap_info.nodes) { + /* hold PW on all the bitmap lock */ + if (md_cluster_ops->lock_all_bitmaps(mddev) <= 0) { + printk("md: can't change bitmap to none since the" + " array is in use by more than one node\n"); + rv = -EPERM; + md_cluster_ops->unlock_all_bitmaps(mddev); + goto err; + } + + mddev->bitmap_info.nodes = 0; + md_cluster_ops->leave(mddev); + } mddev->pers->quiesce(mddev, 1); bitmap_destroy(mddev); mddev->pers->quiesce(mddev, 0); -- GitLab From d323ef0f1a3e6d408eabacf0e91e2d741ffe1165 Mon Sep 17 00:00:00 2001 From: Guoqing Jiang Date: Mon, 21 Dec 2015 10:51:00 +1100 Subject: [PATCH 2260/2855] md-cluster: update the documentation Update design documentation based on recent development. original version comes from Neil. Signed-off-by: Goldwyn Rodrigues Signed-off-by: Guoqing Jiang Signed-off-by: NeilBrown --- Documentation/md-cluster.txt | 314 +++++++++++++++++++++++++---------- 1 file changed, 228 insertions(+), 86 deletions(-) diff --git a/Documentation/md-cluster.txt b/Documentation/md-cluster.txt index 1b794369e03a4..c100c71635070 100644 --- a/Documentation/md-cluster.txt +++ b/Documentation/md-cluster.txt @@ -3,7 +3,7 @@ The cluster MD is a shared-device RAID for a cluster. 1. On-disk format -Separate write-intent-bitmap are used for each cluster node. +Separate write-intent-bitmaps are used for each cluster node. The bitmaps record all writes that may have been started on that node, and may not yet have finished. The on-disk layout is: @@ -14,117 +14,161 @@ and may not yet have finished. The on-disk layout is: | bm super[2] + bits | bm bits [2, contd] | bm super[3] + bits | | bm bits [3, contd] | | | -During "normal" functioning we assume the filesystem ensures that only one -node writes to any given block at a time, so a write -request will +During "normal" functioning we assume the filesystem ensures that only +one node writes to any given block at a time, so a write request will + - set the appropriate bit (if not already set) - commit the write to all mirrors - schedule the bit to be cleared after a timeout. -Reads are just handled normally. It is up to the filesystem to -ensure one node doesn't read from a location where another node (or the same +Reads are just handled normally. It is up to the filesystem to ensure +one node doesn't read from a location where another node (or the same node) is writing. 2. DLM Locks for management -There are two locks for managing the device: +There are three groups of locks for managing the device: 2.1 Bitmap lock resource (bm_lockres) - The bm_lockres protects individual node bitmaps. They are named in the - form bitmap001 for node 1, bitmap002 for node and so on. When a node - joins the cluster, it acquires the lock in PW mode and it stays so - during the lifetime the node is part of the cluster. The lock resource - number is based on the slot number returned by the DLM subsystem. Since - DLM starts node count from one and bitmap slots start from zero, one is - subtracted from the DLM slot number to arrive at the bitmap slot number. + The bm_lockres protects individual node bitmaps. They are named in + the form bitmap000 for node 1, bitmap001 for node 2 and so on. When a + node joins the cluster, it acquires the lock in PW mode and it stays + so during the lifetime the node is part of the cluster. The lock + resource number is based on the slot number returned by the DLM + subsystem. Since DLM starts node count from one and bitmap slots + start from zero, one is subtracted from the DLM slot number to arrive + at the bitmap slot number. + + The LVB of the bitmap lock for a particular node records the range + of sectors that are being re-synced by that node. No other + node may write to those sectors. This is used when a new nodes + joins the cluster. + +2.2 Message passing locks + + Each node has to communicate with other nodes when starting or ending + resync, and for metadata superblock updates. This communication is + managed through three locks: "token", "message", and "ack", together + with the Lock Value Block (LVB) of one of the "message" lock. + +2.3 new-device management + + A single lock: "no-new-dev" is used to co-ordinate the addition of + new devices - this must be synchronized across the array. + Normally all nodes hold a concurrent-read lock on this device. 3. Communication -Each node has to communicate with other nodes when starting or ending -resync, and metadata superblock updates. + Messages can be broadcast to all nodes, and the sender waits for all + other nodes to acknowledge the message before proceeding. Only one + message can be processed at a time. 3.1 Message Types - There are 3 types, of messages which are passed + There are six types of messages which are passed: - 3.1.1 METADATA_UPDATED: informs other nodes that the metadata has been - updated, and the node must re-read the md superblock. This is performed - synchronously. + 3.1.1 METADATA_UPDATED: informs other nodes that the metadata has + been updated, and the node must re-read the md superblock. This is + performed synchronously. It is primarily used to signal device + failure. - 3.1.2 RESYNC: informs other nodes that a resync is initiated or ended - so that each node may suspend or resume the region. + 3.1.2 RESYNCING: informs other nodes that a resync is initiated or + ended so that each node may suspend or resume the region. Each + RESYNCING message identifies a range of the devices that the + sending node is about to resync. This over-rides any pervious + notification from that node: only one ranged can be resynced at a + time per-node. + + 3.1.3 NEWDISK: informs other nodes that a device is being added to + the array. Message contains an identifier for that device. See + below for further details. + + 3.1.4 REMOVE: A failed or spare device is being removed from the + array. The slot-number of the device is included in the message. + + 3.1.5 RE_ADD: A failed device is being re-activated - the assumption + is that it has been determined to be working again. + + 3.1.6 BITMAP_NEEDS_SYNC: if a node is stopped locally but the bitmap + isn't clean, then another node is informed to take the ownership of + resync. 3.2 Communication mechanism The DLM LVB is used to communicate within nodes of the cluster. There are three resources used for the purpose: - 3.2.1 Token: The resource which protects the entire communication + 3.2.1 token: The resource which protects the entire communication system. The node having the token resource is allowed to communicate. - 3.2.2 Message: The lock resource which carries the data to + 3.2.2 message: The lock resource which carries the data to communicate. - 3.2.3 Ack: The resource, acquiring which means the message has been + 3.2.3 ack: The resource, acquiring which means the message has been acknowledged by all nodes in the cluster. The BAST of the resource - is used to inform the receive node that a node wants to communicate. + is used to inform the receiving node that a node wants to + communicate. The algorithm is: - 1. receive status + 1. receive status - all nodes have concurrent-reader lock on "ack". - sender receiver receiver - ACK:CR ACK:CR ACK:CR + sender receiver receiver + "ack":CR "ack":CR "ack":CR - 2. sender get EX of TOKEN - sender get EX of MESSAGE + 2. sender get EX on "token" + sender get EX on "message" sender receiver receiver - TOKEN:EX ACK:CR ACK:CR - MESSAGE:EX - ACK:CR + "token":EX "ack":CR "ack":CR + "message":EX + "ack":CR - Sender checks that it still needs to send a message. Messages received - or other events that happened while waiting for the TOKEN may have made - this message inappropriate or redundant. + Sender checks that it still needs to send a message. Messages + received or other events that happened while waiting for the + "token" may have made this message inappropriate or redundant. - 3. sender write LVB. - sender down-convert MESSAGE from EX to CW - sender try to get EX of ACK - [ wait until all receiver has *processed* the MESSAGE ] + 3. sender writes LVB. + sender down-convert "message" from EX to CW + sender try to get EX of "ack" + [ wait until all receivers have *processed* the "message" ] - [ triggered by bast of ACK ] - receiver get CR of MESSAGE + [ triggered by bast of "ack" ] + receiver get CR on "message" receiver read LVB receiver processes the message [ wait finish ] - receiver release ACK - - sender receiver receiver - TOKEN:EX MESSAGE:CR MESSAGE:CR - MESSAGE:CR - ACK:EX - - 4. triggered by grant of EX on ACK (indicating all receivers have processed - message) - sender down-convert ACK from EX to CR - sender release MESSAGE - sender release TOKEN - receiver upconvert to PR of MESSAGE - receiver get CR of ACK - receiver release MESSAGE + receiver releases "ack" + receiver tries to get PR on "message" + + sender receiver receiver + "token":EX "message":CR "message":CR + "message":CW + "ack":EX + + 4. triggered by grant of EX on "ack" (indicating all receivers + have processed message) + sender down-converts "ack" from EX to CR + sender releases "message" + sender releases "token" + receiver upconvert to PR on "message" + receiver get CR of "ack" + receiver release "message" sender receiver receiver - ACK:CR ACK:CR ACK:CR + "ack":CR "ack":CR "ack":CR 4. Handling Failures 4.1 Node Failure - When a node fails, the DLM informs the cluster with the slot. The node - starts a cluster recovery thread. The cluster recovery thread: + + When a node fails, the DLM informs the cluster with the slot + number. The node starts a cluster recovery thread. The cluster + recovery thread: + - acquires the bitmap lock of the failed node - opens the bitmap - reads the bitmap of the failed node @@ -132,45 +176,143 @@ The algorithm is: - cleans the bitmap of the failed node - releases bitmap lock of the failed node - initiates resync of the bitmap on the current node + md_check_recovery is invoked within recover_bitmaps, + then md_check_recovery -> metadata_update_start/finish, + it will lock the communication by lock_comm. + Which means when one node is resyncing it blocks all + other nodes from writing anywhere on the array. - The resync process, is the regular md resync. However, in a clustered + The resync process is the regular md resync. However, in a clustered environment when a resync is performed, it needs to tell other nodes of the areas which are suspended. Before a resync starts, the node - send out RESYNC_START with the (lo,hi) range of the area which needs - to be suspended. Each node maintains a suspend_list, which contains - the list of ranges which are currently suspended. On receiving - RESYNC_START, the node adds the range to the suspend_list. Similarly, - when the node performing resync finishes, it send RESYNC_FINISHED - to other nodes and other nodes remove the corresponding entry from - the suspend_list. + send out RESYNCING with the (lo,hi) range of the area which needs to + be suspended. Each node maintains a suspend_list, which contains the + list of ranges which are currently suspended. On receiving RESYNCING, + the node adds the range to the suspend_list. Similarly, when the node + performing resync finishes, it sends RESYNCING with an empty range to + other nodes and other nodes remove the corresponding entry from the + suspend_list. - A helper function, should_suspend() can be used to check if a particular - I/O range should be suspended or not. + A helper function, ->area_resyncing() can be used to check if a + particular I/O range should be suspended or not. 4.2 Device Failure + Device failures are handled and communicated with the metadata update - routine. + routine. When a node detects a device failure it does not allow + any further writes to that device until the failure has been + acknowledged by all other nodes. 5. Adding a new Device -For adding a new device, it is necessary that all nodes "see" the new device -to be added. For this, the following algorithm is used: + + For adding a new device, it is necessary that all nodes "see" the new + device to be added. For this, the following algorithm is used: 1. Node 1 issues mdadm --manage /dev/mdX --add /dev/sdYY which issues - ioctl(ADD_NEW_DISC with disc.state set to MD_DISK_CLUSTER_ADD) - 2. Node 1 sends NEWDISK with uuid and slot number + ioctl(ADD_NEW_DISK with disc.state set to MD_DISK_CLUSTER_ADD) + 2. Node 1 sends a NEWDISK message with uuid and slot number 3. Other nodes issue kobject_uevent_env with uuid and slot number (Steps 4,5 could be a udev rule) 4. In userspace, the node searches for the disk, perhaps using blkid -t SUB_UUID="" - 5. Other nodes issue either of the following depending on whether the disk - was found: + 5. Other nodes issue either of the following depending on whether + the disk was found: ioctl(ADD_NEW_DISK with disc.state set to MD_DISK_CANDIDATE and - disc.number set to slot number) + disc.number set to slot number) ioctl(CLUSTERED_DISK_NACK) - 6. Other nodes drop lock on no-new-devs (CR) if device is found - 7. Node 1 attempts EX lock on no-new-devs - 8. If node 1 gets the lock, it sends METADATA_UPDATED after unmarking the disk - as SpareLocal - 9. If not (get no-new-dev lock), it fails the operation and sends METADATA_UPDATED - 10. Other nodes get the information whether a disk is added or not - by the following METADATA_UPDATED. + 6. Other nodes drop lock on "no-new-devs" (CR) if device is found + 7. Node 1 attempts EX lock on "no-new-dev" + 8. If node 1 gets the lock, it sends METADATA_UPDATED after + unmarking the disk as SpareLocal + 9. If not (get "no-new-dev" lock), it fails the operation and sends + METADATA_UPDATED. + 10. Other nodes get the information whether a disk is added or not + by the following METADATA_UPDATED. + +6. Module interface. + + There are 17 call-backs which the md core can make to the cluster + module. Understanding these can give a good overview of the whole + process. + +6.1 join(nodes) and leave() + + These are called when an array is started with a clustered bitmap, + and when the array is stopped. join() ensures the cluster is + available and initializes the various resources. + Only the first 'nodes' nodes in the cluster can use the array. + +6.2 slot_number() + + Reports the slot number advised by the cluster infrastructure. + Range is from 0 to nodes-1. + +6.3 resync_info_update() + + This updates the resync range that is stored in the bitmap lock. + The starting point is updated as the resync progresses. The + end point is always the end of the array. + It does *not* send a RESYNCING message. + +6.4 resync_start(), resync_finish() + + These are called when resync/recovery/reshape starts or stops. + They update the resyncing range in the bitmap lock and also + send a RESYNCING message. resync_start reports the whole + array as resyncing, resync_finish reports none of it. + + resync_finish() also sends a BITMAP_NEEDS_SYNC message which + allows some other node to take over. + +6.5 metadata_update_start(), metadata_update_finish(), + metadata_update_cancel(). + + metadata_update_start is used to get exclusive access to + the metadata. If a change is still needed once that access is + gained, metadata_update_finish() will send a METADATA_UPDATE + message to all other nodes, otherwise metadata_update_cancel() + can be used to release the lock. + +6.6 area_resyncing() + + This combines two elements of functionality. + + Firstly, it will check if any node is currently resyncing + anything in a given range of sectors. If any resync is found, + then the caller will avoid writing or read-balancing in that + range. + + Secondly, while node recovery is happening it reports that + all areas are resyncing for READ requests. This avoids races + between the cluster-filesystem and the cluster-RAID handling + a node failure. + +6.7 add_new_disk_start(), add_new_disk_finish(), new_disk_ack() + + These are used to manage the new-disk protocol described above. + When a new device is added, add_new_disk_start() is called before + it is bound to the array and, if that succeeds, add_new_disk_finish() + is called the device is fully added. + + When a device is added in acknowledgement to a previous + request, or when the device is declared "unavailable", + new_disk_ack() is called. + +6.8 remove_disk() + + This is called when a spare or failed device is removed from + the array. It causes a REMOVE message to be send to other nodes. + +6.9 gather_bitmaps() + + This sends a RE_ADD message to all other nodes and then + gathers bitmap information from all bitmaps. This combined + bitmap is then used to recovery the re-added device. + +6.10 lock_all_bitmaps() and unlock_all_bitmaps() + + These are called when change bitmap to none. If a node plans + to clear the cluster raid's bitmap, it need to make sure no other + nodes are using the raid which is achieved by lock all bitmap + locks within the cluster, and also those locks are unlocked + accordingly. -- GitLab From 15858fa5b00c1067a8a8e53ea32f4a65f8bebbb8 Mon Sep 17 00:00:00 2001 From: Guoqing Jiang Date: Mon, 21 Dec 2015 10:51:00 +1100 Subject: [PATCH 2261/2855] md-cluster: Defer MD reloading to mddev->thread Reloading of superblock must be performed under reconfig_mutex. However, this cannot be done with md_reload_sb because it would deadlock with the message DLM lock. So, we defer it in md_check_recovery() which is executed by mddev->thread. This introduces a new flag, MD_RELOAD_SB, which if set, will reload the superblock. And good_device_nr is also added to 'struct mddev' which is used to get the num of the good device within cluster raid. Signed-off-by: Goldwyn Rodrigues Signed-off-by: Guoqing Jiang Signed-off-by: NeilBrown --- drivers/md/md-cluster.c | 4 +++- drivers/md/md.c | 4 ++++ drivers/md/md.h | 4 ++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index db9375f501aba..b659ef7b8daff 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -432,8 +432,10 @@ static void process_add_new_disk(struct mddev *mddev, struct cluster_msg *cmsg) static void process_metadata_update(struct mddev *mddev, struct cluster_msg *msg) { struct md_cluster_info *cinfo = mddev->cluster_info; - md_reload_sb(mddev, le32_to_cpu(msg->raid_slot)); + mddev->good_device_nr = le32_to_cpu(msg->raid_slot); + set_bit(MD_RELOAD_SB, &mddev->flags); dlm_lock_sync(cinfo->no_new_dev_lockres, DLM_LOCK_CR); + md_wakeup_thread(mddev->thread); } static void process_remove_disk(struct mddev *mddev, struct cluster_msg *msg) diff --git a/drivers/md/md.c b/drivers/md/md.c index 495d8aa0a0d25..504ce5d068ce6 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -8286,6 +8286,7 @@ void md_check_recovery(struct mddev *mddev) (mddev->flags & MD_UPDATE_SB_FLAGS & ~ (1<recovery) || test_bit(MD_RECOVERY_DONE, &mddev->recovery) || + test_bit(MD_RELOAD_SB, &mddev->flags) || (mddev->external == 0 && mddev->safemode == 1) || (mddev->safemode == 2 && ! atomic_read(&mddev->writes_pending) && !mddev->in_sync && mddev->recovery_cp == MaxSector) @@ -8334,6 +8335,9 @@ void md_check_recovery(struct mddev *mddev) rdev->raid_disk < 0) md_kick_rdev_from_array(rdev); } + + if (test_and_clear_bit(MD_RELOAD_SB, &mddev->flags)) + md_reload_sb(mddev, mddev->good_device_nr); } if (!mddev->external) { diff --git a/drivers/md/md.h b/drivers/md/md.h index f7b17aef837d7..8817e623258ac 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -235,6 +235,9 @@ struct mddev { */ #define MD_JOURNAL_CLEAN 5 /* A raid with journal is already clean */ #define MD_HAS_JOURNAL 6 /* The raid array has journal feature set */ +#define MD_RELOAD_SB 7 /* Reload the superblock because another node + * updated it. + */ int suspended; atomic_t active_io; @@ -465,6 +468,7 @@ struct mddev { struct work_struct event_work; /* used by dm to report failure event */ void (*sync_super)(struct mddev *mddev, struct md_rdev *rdev); struct md_cluster_info *cluster_info; + unsigned int good_device_nr; /* good device num within cluster raid */ }; static inline int __must_check mddev_lock(struct mddev *mddev) -- GitLab From 8b9277c81450de9d8081ff6571ac5986e6c83f49 Mon Sep 17 00:00:00 2001 From: Guoqing Jiang Date: Mon, 21 Dec 2015 10:51:00 +1100 Subject: [PATCH 2262/2855] md-cluster: Protect communication with mutexes Communication can happen through multiple threads. It is possible that one thread steps over another threads sequence. So, we use mutexes to protect both the send and receive sequences. Send communication is locked through state bit, MD_CLUSTER_SEND_LOCK. Communication is locked with bit manipulation in order to allow "lock and hold" for the add operation. In case of an add operation, if the lock is held, MD_CLUSTER_SEND_LOCKED_ALREADY is set. When md_update_sb() calls metadata_update_start(), it checks (in a single statement to avoid races), if the communication is already locked. If yes, it merely returns zero, else it locks the token lockresource. Signed-off-by: Goldwyn Rodrigues Signed-off-by: NeilBrown --- drivers/md/md-cluster.c | 73 +++++++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 10 deletions(-) diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index b659ef7b8daff..ad3ec7df15471 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -48,12 +48,26 @@ struct resync_info { #define MD_CLUSTER_SUSPEND_READ_BALANCING 2 #define MD_CLUSTER_BEGIN_JOIN_CLUSTER 3 +/* Lock the send communication. This is done through + * bit manipulation as opposed to a mutex in order to + * accomodate lock and hold. See next comment. + */ +#define MD_CLUSTER_SEND_LOCK 4 +/* If cluster operations must lock the communication channel, + * so as to perform extra operations (and no other operation + * is allowed on the MD, such as adding a disk. Token needs + * to be locked and held until the operation completes with + * a md_update_sb(), which would eventually release the lock. + */ +#define MD_CLUSTER_SEND_LOCKED_ALREADY 5 + struct md_cluster_info { /* dlm lock space and resources for clustered raid. */ dlm_lockspace_t *lockspace; int slot_number; struct completion completion; + struct mutex recv_mutex; struct dlm_lock_resource *bitmap_lockres; struct dlm_lock_resource **other_bitmap_lockres; struct dlm_lock_resource *resync_lockres; @@ -68,6 +82,7 @@ struct md_cluster_info { struct dlm_lock_resource *no_new_dev_lockres; struct md_thread *recv_thread; struct completion newdisk_completion; + wait_queue_head_t wait; unsigned long state; }; @@ -508,9 +523,11 @@ static void recv_daemon(struct md_thread *thread) struct cluster_msg msg; int ret; + mutex_lock(&cinfo->recv_mutex); /*get CR on Message*/ if (dlm_lock_sync(message_lockres, DLM_LOCK_CR)) { pr_err("md/raid1:failed to get CR on MESSAGE\n"); + mutex_unlock(&cinfo->recv_mutex); return; } @@ -534,33 +551,45 @@ static void recv_daemon(struct md_thread *thread) ret = dlm_unlock_sync(message_lockres); if (unlikely(ret != 0)) pr_info("unlock msg failed return %d\n", ret); + mutex_unlock(&cinfo->recv_mutex); } -/* lock_comm() +/* lock_token() * Takes the lock on the TOKEN lock resource so no other * node can communicate while the operation is underway. - * If called again, and the TOKEN lock is alread in EX mode - * return success. However, care must be taken that unlock_comm() - * is called only once. */ -static int lock_comm(struct md_cluster_info *cinfo) +static int lock_token(struct md_cluster_info *cinfo) { int error; - if (cinfo->token_lockres->mode == DLM_LOCK_EX) - return 0; - error = dlm_lock_sync(cinfo->token_lockres, DLM_LOCK_EX); if (error) pr_err("md-cluster(%s:%d): failed to get EX on TOKEN (%d)\n", __func__, __LINE__, error); + + /* Lock the receive sequence */ + mutex_lock(&cinfo->recv_mutex); return error; } +/* lock_comm() + * Sets the MD_CLUSTER_SEND_LOCK bit to lock the send channel. + */ +static int lock_comm(struct md_cluster_info *cinfo) +{ + wait_event(cinfo->wait, + !test_and_set_bit(MD_CLUSTER_SEND_LOCK, &cinfo->state)); + + return lock_token(cinfo); +} + static void unlock_comm(struct md_cluster_info *cinfo) { WARN_ON(cinfo->token_lockres->mode != DLM_LOCK_EX); + mutex_unlock(&cinfo->recv_mutex); dlm_unlock_sync(cinfo->token_lockres); + clear_bit(MD_CLUSTER_SEND_LOCK, &cinfo->state); + wake_up(&cinfo->wait); } /* __sendmsg() @@ -713,6 +742,8 @@ static int join(struct mddev *mddev, int nodes) spin_lock_init(&cinfo->suspend_lock); init_completion(&cinfo->completion); set_bit(MD_CLUSTER_BEGIN_JOIN_CLUSTER, &cinfo->state); + init_waitqueue_head(&cinfo->wait); + mutex_init(&cinfo->recv_mutex); mddev->cluster_info = cinfo; @@ -843,9 +874,25 @@ static int slot_number(struct mddev *mddev) return cinfo->slot_number - 1; } +/* + * Check if the communication is already locked, else lock the communication + * channel. + * If it is already locked, token is in EX mode, and hence lock_token() + * should not be called. + */ static int metadata_update_start(struct mddev *mddev) { - return lock_comm(mddev->cluster_info); + struct md_cluster_info *cinfo = mddev->cluster_info; + + wait_event(cinfo->wait, + !test_and_set_bit(MD_CLUSTER_SEND_LOCK, &cinfo->state) || + test_and_clear_bit(MD_CLUSTER_SEND_LOCKED_ALREADY, &cinfo->state)); + + /* If token is already locked, return 0 */ + if (cinfo->token_lockres->mode == DLM_LOCK_EX) + return 0; + + return lock_token(cinfo); } static int metadata_update_finish(struct mddev *mddev) @@ -870,6 +917,7 @@ static int metadata_update_finish(struct mddev *mddev) ret = __sendmsg(cinfo, &cmsg); } else pr_warn("md-cluster: No good device id found to send\n"); + clear_bit(MD_CLUSTER_SEND_LOCKED_ALREADY, &cinfo->state); unlock_comm(cinfo); return ret; } @@ -877,6 +925,7 @@ static int metadata_update_finish(struct mddev *mddev) static void metadata_update_cancel(struct mddev *mddev) { struct md_cluster_info *cinfo = mddev->cluster_info; + clear_bit(MD_CLUSTER_SEND_LOCKED_ALREADY, &cinfo->state); unlock_comm(cinfo); } @@ -970,14 +1019,18 @@ static int add_new_disk(struct mddev *mddev, struct md_rdev *rdev) ret = -ENOENT; if (ret) unlock_comm(cinfo); - else + else { dlm_lock_sync(cinfo->no_new_dev_lockres, DLM_LOCK_CR); + set_bit(MD_CLUSTER_SEND_LOCKED_ALREADY, &cinfo->state); + wake_up(&cinfo->wait); + } return ret; } static void add_new_disk_cancel(struct mddev *mddev) { struct md_cluster_info *cinfo = mddev->cluster_info; + clear_bit(MD_CLUSTER_SEND_LOCKED_ALREADY, &cinfo->state); unlock_comm(cinfo); } -- GitLab From e19508fa4df896b115f5321c21ce7669559b0863 Mon Sep 17 00:00:00 2001 From: Guoqing Jiang Date: Mon, 21 Dec 2015 10:51:01 +1100 Subject: [PATCH 2263/2855] md-cluster: update comments for MD_CLUSTER_SEND_LOCKED_ALREADY 1. fix unbalanced parentheses. 2. add more description about that MD_CLUSTER_SEND_LOCKED_ALREADY will be cleared after set it in add_new_disk. Signed-off-by: Guoqing Jiang Signed-off-by: NeilBrown --- drivers/md/md-cluster.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index ad3ec7df15471..0ded8e97751d2 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -53,11 +53,12 @@ struct resync_info { * accomodate lock and hold. See next comment. */ #define MD_CLUSTER_SEND_LOCK 4 -/* If cluster operations must lock the communication channel, - * so as to perform extra operations (and no other operation - * is allowed on the MD, such as adding a disk. Token needs - * to be locked and held until the operation completes with - * a md_update_sb(), which would eventually release the lock. +/* If cluster operations (such as adding a disk) must lock the + * communication channel, so as to perform extra operations + * (update metadata) and no other operation is allowed on the + * MD. Token needs to be locked and held until the operation + * completes witha md_update_sb(), which would eventually release + * the lock. */ #define MD_CLUSTER_SEND_LOCKED_ALREADY 5 @@ -1021,6 +1022,18 @@ static int add_new_disk(struct mddev *mddev, struct md_rdev *rdev) unlock_comm(cinfo); else { dlm_lock_sync(cinfo->no_new_dev_lockres, DLM_LOCK_CR); + /* Since MD_CHANGE_DEVS will be set in add_bound_rdev which + * will run soon after add_new_disk, the below path will be + * invoked: + * md_wakeup_thread(mddev->thread) + * -> conf->thread (raid1d) + * -> md_check_recovery -> md_update_sb + * -> metadata_update_start/finish + * MD_CLUSTER_SEND_LOCKED_ALREADY will be cleared eventually. + * + * For other failure cases, metadata_update_cancel and + * add_new_disk_cancel also clear below bit as well. + * */ set_bit(MD_CLUSTER_SEND_LOCKED_ALREADY, &cinfo->state); wake_up(&cinfo->wait); } -- GitLab From abf3508d8faa281e01a780e022a6f43d1731fe0b Mon Sep 17 00:00:00 2001 From: Guoqing Jiang Date: Mon, 21 Dec 2015 10:51:01 +1100 Subject: [PATCH 2264/2855] md: update comment for md_allow_write MD_CHANGE_CLEAN had been replaced with MD_CHANGE_PENDING after commit 070dc6 ("md: resolve confusion of MD_CHANGE_CLEAN"), so make the change accordingly. Signed-off-by: Guoqing Jiang Signed-off-by: NeilBrown --- drivers/md/md.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 504ce5d068ce6..f71a81b37d08e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -7714,7 +7714,7 @@ EXPORT_SYMBOL(md_write_end); * attempting a GFP_KERNEL allocation while holding the mddev lock. * Must be called with mddev_lock held. * - * In the ->external case MD_CHANGE_CLEAN can not be cleared until mddev->lock + * In the ->external case MD_CHANGE_PENDING can not be cleared until mddev->lock * is dropped, so return -EAGAIN after notifying userspace. */ int md_allow_write(struct mddev *mddev) -- GitLab From 3848c0bcb09c7b78e6f4ae9f8fc8d6d9aecbd35a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 21 Dec 2015 10:51:01 +1100 Subject: [PATCH 2265/2855] raid5-cache: simplify r5l_move_io_unit_list It's only used for one kind of move, so make that explicit. Also clean up the code a bit by using list_for_each_safe. Signed-off-by: Christoph Hellwig Reviewed-by: Shaohua Li Signed-off-by: NeilBrown --- drivers/md/raid5-cache.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index b887e04d7e5c2..3699c4704ba85 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c @@ -156,21 +156,6 @@ static void r5l_free_io_unit(struct r5l_log *log, struct r5l_io_unit *io) kmem_cache_free(log->io_kc, io); } -static void r5l_move_io_unit_list(struct list_head *from, struct list_head *to, - enum r5l_io_unit_state state) -{ - struct r5l_io_unit *io; - - while (!list_empty(from)) { - io = list_first_entry(from, struct r5l_io_unit, log_sibling); - /* don't change list order */ - if (io->state >= state) - list_move_tail(&io->log_sibling, to); - else - break; - } -} - static void __r5l_set_io_unit_state(struct r5l_io_unit *io, enum r5l_io_unit_state state) { @@ -206,6 +191,20 @@ static void r5l_log_run_stripes(struct r5l_log *log) } } +static void r5l_move_to_end_ios(struct r5l_log *log) +{ + struct r5l_io_unit *io, *next; + + assert_spin_locked(&log->io_list_lock); + + list_for_each_entry_safe(io, next, &log->running_ios, log_sibling) { + /* don't change list order */ + if (io->state < IO_UNIT_IO_END) + break; + list_move_tail(&io->log_sibling, &log->io_end_ios); + } +} + static void r5l_log_endio(struct bio *bio) { struct r5l_io_unit *io = bio->bi_private; @@ -220,8 +219,7 @@ static void r5l_log_endio(struct bio *bio) spin_lock_irqsave(&log->io_list_lock, flags); __r5l_set_io_unit_state(io, IO_UNIT_IO_END); if (log->need_cache_flush) - r5l_move_io_unit_list(&log->running_ios, &log->io_end_ios, - IO_UNIT_IO_END); + r5l_move_to_end_ios(log); else r5l_log_run_stripes(log); spin_unlock_irqrestore(&log->io_list_lock, flags); -- GitLab From ad66d445ee5a5f548142b880e1642c711fbcacd1 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 21 Dec 2015 10:51:01 +1100 Subject: [PATCH 2266/2855] raid5-cache: free meta_page earlier Once the I/O completed we don't need the meta page anymore. As the iounits can live on for a long time this reduces memory pressure a bit. Signed-off-by: Christoph Hellwig Reviewed-by: Shaohua Li Signed-off-by: NeilBrown --- drivers/md/raid5-cache.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index 3699c4704ba85..668e973f07e66 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c @@ -150,12 +150,6 @@ static bool r5l_has_free_space(struct r5l_log *log, sector_t size) return log->device_size > used_size + size; } -static void r5l_free_io_unit(struct r5l_log *log, struct r5l_io_unit *io) -{ - __free_page(io->meta_page); - kmem_cache_free(log->io_kc, io); -} - static void __r5l_set_io_unit_state(struct r5l_io_unit *io, enum r5l_io_unit_state state) { @@ -215,6 +209,7 @@ static void r5l_log_endio(struct bio *bio) md_error(log->rdev->mddev, log->rdev); bio_put(bio); + __free_page(io->meta_page); spin_lock_irqsave(&log->io_list_lock, flags); __r5l_set_io_unit_state(io, IO_UNIT_IO_END); @@ -552,7 +547,7 @@ static bool r5l_complete_finished_ios(struct r5l_log *log) log->next_cp_seq = io->seq; list_del(&io->log_sibling); - r5l_free_io_unit(log, io); + kmem_cache_free(log->io_kc, io); found = true; } -- GitLab From 3312c951efaba55080958974047414576b9e5d63 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 21 Dec 2015 10:51:01 +1100 Subject: [PATCH 2267/2855] md: avoid warning for 32-bit sector_t When CONFIG_LBDAF is not set, sector_t is only 32-bits wide, which means we cannot have devices with more than 2TB, and the code that is trying to handle compatibility support for large devices in md version 0.90 is meaningless but also causes a compile-time warning: drivers/md/md.c: In function 'super_90_load': drivers/md/md.c:1029:19: warning: large integer implicitly truncated to unsigned type [-Woverflow] drivers/md/md.c: In function 'super_90_rdev_size_change': drivers/md/md.c:1323:17: warning: large integer implicitly truncated to unsigned type [-Woverflow] This adds a check for CONFIG_LBDAF to avoid even getting into this code path, and also adds an explicit cast to let the compiler know it doesn't have to warn about the truncation. Signed-off-by: Arnd Bergmann Signed-off-by: NeilBrown --- drivers/md/md.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index f71a81b37d08e..3d70d0d11b958 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1026,8 +1026,9 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor * (not needed for Linear and RAID0 as metadata doesn't * record this size) */ - if (rdev->sectors >= (2ULL << 32) && sb->level >= 1) - rdev->sectors = (2ULL << 32) - 2; + if (IS_ENABLED(CONFIG_LBDAF) && (u64)rdev->sectors >= (2ULL << 32) && + sb->level >= 1) + rdev->sectors = (sector_t)(2ULL << 32) - 2; if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) /* "this cannot possibly happen" ... */ @@ -1320,8 +1321,9 @@ super_90_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors) /* Limit to 4TB as metadata cannot record more than that. * 4TB == 2^32 KB, or 2*2^32 sectors. */ - if (num_sectors >= (2ULL << 32) && rdev->mddev->level >= 1) - num_sectors = (2ULL << 32) - 2; + if (IS_ENABLED(CONFIG_LBDAF) && (u64)num_sectors >= (2ULL << 32) && + rdev->mddev->level >= 1) + num_sectors = (sector_t)(2ULL << 32) - 2; md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, rdev->sb_page); md_super_wait(rdev->mddev); -- GitLab From 9ebc6ef188a0656f3620835f9be7fe22c1644c1c Mon Sep 17 00:00:00 2001 From: Deepa Dinamani Date: Mon, 21 Dec 2015 10:51:01 +1100 Subject: [PATCH 2268/2855] drivers: md: use ktime_get_real_seconds() get_seconds() API is not y2038 safe on 32 bit systems and the API is deprecated. Replace it with calls to ktime_get_real_seconds() API instead. Change mddev structure types to time64_t accordingly. 32 bit signed timestamps will overflow in the year 2038. Change the user interface mdu_array_info_s structure timestamps: ctime and utime values used in ioctls GET_ARRAY_INFO and SET_ARRAY_INFO to unsigned int. This will extend the field to last until the year 2106. The long term plan is to get rid of ctime and utime values in this structure as this information can be read from the on-disk meta data directly. Clamp the tim64_t timestamps to positive values with a max of U32_MAX when returning from GET_ARRAY_INFO ioctl to accommodate above changes in the data type of timestamps to unsigned int. v0.90 on disk meta data uses u32 for maintaining time stamps. So this will also last until year 2106. Assumption is that the usage of v0.90 will be deprecated by year 2106. Timestamp fields in the on disk meta data for v1.0 version already use 64 bit data types. Remove the truncation of the bits while writing to or reading from these from the disk. Signed-off-by: Deepa Dinamani Reviewed-by: Arnd Bergmann Signed-off-by: NeilBrown --- drivers/md/md.c | 18 +++++++++--------- drivers/md/md.h | 2 +- include/uapi/linux/raid/md_u.h | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 3d70d0d11b958..d0f0621bf9b0a 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1200,13 +1200,13 @@ static void super_90_sync(struct mddev *mddev, struct md_rdev *rdev) memcpy(&sb->set_uuid2, mddev->uuid+8, 4); memcpy(&sb->set_uuid3, mddev->uuid+12,4); - sb->ctime = mddev->ctime; + sb->ctime = clamp_t(time64_t, mddev->ctime, 0, U32_MAX); sb->level = mddev->level; sb->size = mddev->dev_sectors / 2; sb->raid_disks = mddev->raid_disks; sb->md_minor = mddev->md_minor; sb->not_persistent = 0; - sb->utime = mddev->utime; + sb->utime = clamp_t(time64_t, mddev->utime, 0, U32_MAX); sb->state = 0; sb->events_hi = (mddev->events>>32); sb->events_lo = (u32)mddev->events; @@ -1547,8 +1547,8 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev) mddev->patch_version = 0; mddev->external = 0; mddev->chunk_sectors = le32_to_cpu(sb->chunksize); - mddev->ctime = le64_to_cpu(sb->ctime) & ((1ULL << 32)-1); - mddev->utime = le64_to_cpu(sb->utime) & ((1ULL << 32)-1); + mddev->ctime = le64_to_cpu(sb->ctime); + mddev->utime = le64_to_cpu(sb->utime); mddev->level = le32_to_cpu(sb->level); mddev->clevel[0] = 0; mddev->layout = le32_to_cpu(sb->layout); @@ -2336,7 +2336,7 @@ repeat: spin_lock(&mddev->lock); - mddev->utime = get_seconds(); + mddev->utime = ktime_get_real_seconds(); if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags)) force_change = 1; @@ -5843,7 +5843,7 @@ static int get_array_info(struct mddev *mddev, void __user *arg) info.major_version = mddev->major_version; info.minor_version = mddev->minor_version; info.patch_version = MD_PATCHLEVEL_VERSION; - info.ctime = mddev->ctime; + info.ctime = clamp_t(time64_t, mddev->ctime, 0, U32_MAX); info.level = mddev->level; info.size = mddev->dev_sectors / 2; if (info.size != mddev->dev_sectors / 2) /* overflow */ @@ -5853,7 +5853,7 @@ static int get_array_info(struct mddev *mddev, void __user *arg) info.md_minor = mddev->md_minor; info.not_persistent= !mddev->persistent; - info.utime = mddev->utime; + info.utime = clamp_t(time64_t, mddev->utime, 0, U32_MAX); info.state = 0; if (mddev->in_sync) info.state = (1<ctime = get_seconds(); + mddev->ctime = ktime_get_real_seconds(); return 0; } mddev->major_version = MD_MAJOR_VERSION; mddev->minor_version = MD_MINOR_VERSION; mddev->patch_version = MD_PATCHLEVEL_VERSION; - mddev->ctime = get_seconds(); + mddev->ctime = ktime_get_real_seconds(); mddev->level = info->level; mddev->clevel[0] = 0; diff --git a/drivers/md/md.h b/drivers/md/md.h index 8817e623258ac..e16a17c374183 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -264,7 +264,7 @@ struct mddev { * managed externally */ char metadata_type[17]; /* externally set*/ int chunk_sectors; - time_t ctime, utime; + time64_t ctime, utime; int level, layout; char clevel[16]; int raid_disks; diff --git a/include/uapi/linux/raid/md_u.h b/include/uapi/linux/raid/md_u.h index 1cb8aa6850b59..36cd8210a5d1d 100644 --- a/include/uapi/linux/raid/md_u.h +++ b/include/uapi/linux/raid/md_u.h @@ -80,7 +80,7 @@ typedef struct mdu_array_info_s { int major_version; int minor_version; int patch_version; - int ctime; + unsigned int ctime; int level; int size; int nr_disks; @@ -91,7 +91,7 @@ typedef struct mdu_array_info_s { /* * Generic state information */ - int utime; /* 0 Superblock update time */ + unsigned int utime; /* 0 Superblock update time */ int state; /* 1 State bits (clean, ...) */ int active_disks; /* 2 Number of currently active disks */ int working_disks; /* 3 Number of working disks */ -- GitLab From f6b6ec5cfac306c1eea66f074050864efcb11851 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Mon, 21 Dec 2015 10:51:02 +1100 Subject: [PATCH 2269/2855] raid5-cache: add journal hot add/remove support Add support for journal disk hot add/remove. Mostly trival checks in md part. The raid5 part is a little tricky. For hot-remove, we can't wait pending write as it's called from raid5d. The wait will cause deadlock. We simplily fail the hot-remove. A hot-remove retry can success eventually since if journal disk is faulty all pending write will be failed and finish. For hot-add, since an array supporting journal but without journal disk will be marked read-only, we are safe to hot add journal without stopping IO (should be read IO, while journal only handles write IO). Signed-off-by: Shaohua Li Signed-off-by: NeilBrown --- drivers/md/md.c | 42 ++++++++++++++++++++++++++++------------ drivers/md/raid5-cache.c | 16 +++++++++++---- drivers/md/raid5.c | 34 ++++++++++++++++++++++++-------- 3 files changed, 68 insertions(+), 24 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index d0f0621bf9b0a..c0c3e6dec2484 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2055,8 +2055,9 @@ static int bind_rdev_to_array(struct md_rdev *rdev, struct mddev *mddev) return -EEXIST; /* make sure rdev->sectors exceeds mddev->dev_sectors */ - if (rdev->sectors && (mddev->dev_sectors == 0 || - rdev->sectors < mddev->dev_sectors)) { + if (!test_bit(Journal, &rdev->flags) && + rdev->sectors && + (mddev->dev_sectors == 0 || rdev->sectors < mddev->dev_sectors)) { if (mddev->pers) { /* Cannot change size, so fail * If mddev->level <= 0, then we don't care @@ -2087,7 +2088,8 @@ static int bind_rdev_to_array(struct md_rdev *rdev, struct mddev *mddev) } } rcu_read_unlock(); - if (mddev->max_disks && rdev->desc_nr >= mddev->max_disks) { + if (!test_bit(Journal, &rdev->flags) && + mddev->max_disks && rdev->desc_nr >= mddev->max_disks) { printk(KERN_WARNING "md: %s: array is limited to %d devices\n", mdname(mddev), mddev->max_disks); return -EBUSY; @@ -6044,8 +6046,23 @@ static int add_new_disk(struct mddev *mddev, mdu_disk_info_t *info) else clear_bit(WriteMostly, &rdev->flags); - if (info->state & (1<state & (1<flags)) { + has_journal = true; + break; + } + } + if (has_journal) { + export_rdev(rdev); + return -EBUSY; + } set_bit(Journal, &rdev->flags); + } /* * check whether the device shows up in other nodes */ @@ -8181,19 +8198,20 @@ static int remove_and_add_spares(struct mddev *mddev, continue; if (test_bit(Faulty, &rdev->flags)) continue; - if (test_bit(Journal, &rdev->flags)) - continue; - if (mddev->ro && - ! (rdev->saved_raid_disk >= 0 && - !test_bit(Bitmap_sync, &rdev->flags))) - continue; + if (!test_bit(Journal, &rdev->flags)) { + if (mddev->ro && + ! (rdev->saved_raid_disk >= 0 && + !test_bit(Bitmap_sync, &rdev->flags))) + continue; - rdev->recovery_offset = 0; + rdev->recovery_offset = 0; + } if (mddev->pers-> hot_add_disk(mddev, rdev) == 0) { if (sysfs_link_rdev(mddev, rdev)) /* failure here is OK */; - spares++; + if (!test_bit(Journal, &rdev->flags)) + spares++; md_new_event(mddev); set_bit(MD_CHANGE_DEVS, &mddev->flags); } diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index 668e973f07e66..c1c4d213a2c25 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c @@ -799,10 +799,18 @@ void r5l_quiesce(struct r5l_log *log, int state) bool r5l_log_disk_error(struct r5conf *conf) { + struct r5l_log *log; + bool ret; /* don't allow write if journal disk is missing */ - if (!conf->log) - return test_bit(MD_HAS_JOURNAL, &conf->mddev->flags); - return test_bit(Faulty, &conf->log->rdev->flags); + rcu_read_lock(); + log = rcu_dereference(conf->log); + + if (!log) + ret = test_bit(MD_HAS_JOURNAL, &conf->mddev->flags); + else + ret = test_bit(Faulty, &log->rdev->flags); + rcu_read_unlock(); + return ret; } struct r5l_recovery_ctx { @@ -1165,7 +1173,7 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev) if (r5l_load_log(log)) goto error; - conf->log = log; + rcu_assign_pointer(conf->log, log); return 0; error: md_unregister_thread(&log->reclaim_thread); diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 22362505f810f..a086014dcd499 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -7139,14 +7139,19 @@ static int raid5_remove_disk(struct mddev *mddev, struct md_rdev *rdev) struct disk_info *p = conf->disks + number; print_raid5_conf(conf); - if (test_bit(Journal, &rdev->flags)) { + if (test_bit(Journal, &rdev->flags) && conf->log) { + struct r5l_log *log; /* - * journal disk is not removable, but we need give a chance to - * update superblock of other disks. Otherwise journal disk - * will be considered as 'fresh' + * we can't wait pending write here, as this is called in + * raid5d, wait will deadlock. */ - set_bit(MD_CHANGE_DEVS, &mddev->flags); - return -EINVAL; + if (atomic_read(&mddev->writes_pending)) + return -EBUSY; + log = conf->log; + conf->log = NULL; + synchronize_rcu(); + r5l_exit_log(log); + return 0; } if (rdev == p->rdev) rdevp = &p->rdev; @@ -7210,8 +7215,21 @@ static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev) int first = 0; int last = conf->raid_disks - 1; - if (test_bit(Journal, &rdev->flags)) - return -EINVAL; + if (test_bit(Journal, &rdev->flags)) { + char b[BDEVNAME_SIZE]; + if (conf->log) + return -EBUSY; + + rdev->raid_disk = 0; + /* + * The array is in readonly mode if journal is missing, so no + * write requests running. We should be safe + */ + r5l_init_log(conf, rdev); + printk(KERN_INFO"md/raid:%s: using device %s as journal\n", + mdname(mddev), bdevname(rdev->bdev, b)); + return 0; + } if (mddev->recovery_disabled == conf->recovery_disabled) return -EBUSY; -- GitLab From c38d29b33bb3b3c792f3cca8a973422bb1897ebf Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 21 Dec 2015 10:51:02 +1100 Subject: [PATCH 2270/2855] raid5-cache: use a bio_set This allows us to make guaranteed forward progress. Signed-off-by: Christoph Hellwig Signed-off-by: NeilBrown --- drivers/md/raid5-cache.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index c1c4d213a2c25..2a644977d90cc 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c @@ -34,6 +34,12 @@ #define RECLAIM_MAX_FREE_SPACE (10 * 1024 * 1024 * 2) /* sector */ #define RECLAIM_MAX_FREE_SPACE_SHIFT (2) +/* + * We only need 2 bios per I/O unit to make progress, but ensure we + * have a few more available to not get too tight. + */ +#define R5L_POOL_SIZE 4 + struct r5l_log { struct md_rdev *rdev; @@ -70,6 +76,7 @@ struct r5l_log { struct bio flush_bio; struct kmem_cache *io_kc; + struct bio_set *bs; struct md_thread *reclaim_thread; unsigned long reclaim_target; /* number of space that need to be @@ -248,7 +255,7 @@ static void r5l_submit_current_io(struct r5l_log *log) static struct bio *r5l_bio_alloc(struct r5l_log *log) { - struct bio *bio = bio_kmalloc(GFP_NOIO | __GFP_NOFAIL, BIO_MAX_PAGES); + struct bio *bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_PAGES, log->bs); bio->bi_rw = WRITE; bio->bi_bdev = log->rdev->bdev; @@ -1161,6 +1168,10 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev) if (!log->io_kc) goto io_kc; + log->bs = bioset_create(R5L_POOL_SIZE, 0); + if (!log->bs) + goto io_bs; + log->reclaim_thread = md_register_thread(r5l_reclaim_thread, log->rdev->mddev, "reclaim"); if (!log->reclaim_thread) @@ -1178,6 +1189,8 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev) error: md_unregister_thread(&log->reclaim_thread); reclaim_thread: + bioset_free(log->bs); +io_bs: kmem_cache_destroy(log->io_kc); io_kc: kfree(log); @@ -1187,6 +1200,7 @@ io_kc: void r5l_exit_log(struct r5l_log *log) { md_unregister_thread(&log->reclaim_thread); + bioset_free(log->bs); kmem_cache_destroy(log->io_kc); kfree(log); } -- GitLab From e8deb6381051bf3ce9d817020e8ba972b405a070 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 21 Dec 2015 10:51:02 +1100 Subject: [PATCH 2271/2855] raid5-cache: use a mempool for the metadata block We only have a limited number in flight, so use a page based mempool. Signed-off-by: Christoph Hellwig Signed-off-by: NeilBrown --- drivers/md/raid5-cache.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index 2a644977d90cc..fa2d6321f3a4b 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c @@ -77,6 +77,7 @@ struct r5l_log { struct kmem_cache *io_kc; struct bio_set *bs; + mempool_t *meta_pool; struct md_thread *reclaim_thread; unsigned long reclaim_target; /* number of space that need to be @@ -216,7 +217,7 @@ static void r5l_log_endio(struct bio *bio) md_error(log->rdev->mddev, log->rdev); bio_put(bio); - __free_page(io->meta_page); + mempool_free(io->meta_page, log->meta_pool); spin_lock_irqsave(&log->io_list_lock, flags); __r5l_set_io_unit_state(io, IO_UNIT_IO_END); @@ -293,8 +294,9 @@ static struct r5l_io_unit *r5l_new_meta(struct r5l_log *log) INIT_LIST_HEAD(&io->stripe_list); io->state = IO_UNIT_RUNNING; - io->meta_page = alloc_page(GFP_NOIO | __GFP_NOFAIL | __GFP_ZERO); + io->meta_page = mempool_alloc(log->meta_pool, GFP_NOIO); block = page_address(io->meta_page); + clear_page(block); block->magic = cpu_to_le32(R5LOG_MAGIC); block->version = R5LOG_VERSION; block->seq = cpu_to_le64(log->seq); @@ -1172,6 +1174,10 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev) if (!log->bs) goto io_bs; + log->meta_pool = mempool_create_page_pool(R5L_POOL_SIZE, 0); + if (!log->meta_pool) + goto out_mempool; + log->reclaim_thread = md_register_thread(r5l_reclaim_thread, log->rdev->mddev, "reclaim"); if (!log->reclaim_thread) @@ -1186,9 +1192,12 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev) rcu_assign_pointer(conf->log, log); return 0; + error: md_unregister_thread(&log->reclaim_thread); reclaim_thread: + mempool_destroy(log->meta_pool); +out_mempool: bioset_free(log->bs); io_bs: kmem_cache_destroy(log->io_kc); @@ -1200,6 +1209,7 @@ io_kc: void r5l_exit_log(struct r5l_log *log) { md_unregister_thread(&log->reclaim_thread); + mempool_destroy(log->meta_pool); bioset_free(log->bs); kmem_cache_destroy(log->io_kc); kfree(log); -- GitLab From 5036c3902054358ee293b8cecfea13342d8019e8 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 21 Dec 2015 10:51:02 +1100 Subject: [PATCH 2272/2855] raid5: allow r5l_io_unit allocations to fail And propagate the error up the stack so we can add the stripe to no_stripes_list and retry our log operation later. This avoids blocking raid5d due to reclaim, an it allows to get rid of the deadlock-prone GFP_NOFAIL allocation. shli: add missing mempool_destroy() Signed-off-by: Christoph Hellwig Signed-off-by: NeilBrown --- drivers/md/raid5-cache.c | 67 ++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index fa2d6321f3a4b..6d2b4789a928a 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c @@ -75,7 +75,10 @@ struct r5l_log { struct list_head finished_ios; /* io_units which settle down in log disk */ struct bio flush_bio; + struct list_head no_mem_stripes; /* pending stripes, -ENOMEM */ + struct kmem_cache *io_kc; + mempool_t *io_pool; struct bio_set *bs; mempool_t *meta_pool; @@ -287,8 +290,11 @@ static struct r5l_io_unit *r5l_new_meta(struct r5l_log *log) struct r5l_io_unit *io; struct r5l_meta_block *block; - /* We can't handle memory allocate failure so far */ - io = kmem_cache_zalloc(log->io_kc, GFP_NOIO | __GFP_NOFAIL); + io = mempool_alloc(log->io_pool, GFP_ATOMIC); + if (!io) + return NULL; + memset(io, 0, sizeof(*io)); + io->log = log; INIT_LIST_HEAD(&io->log_sibling); INIT_LIST_HEAD(&io->stripe_list); @@ -326,8 +332,12 @@ static int r5l_get_meta(struct r5l_log *log, unsigned int payload_size) log->current_io->meta_offset + payload_size > PAGE_SIZE) r5l_submit_current_io(log); - if (!log->current_io) + if (!log->current_io) { log->current_io = r5l_new_meta(log); + if (!log->current_io) + return -ENOMEM; + } + return 0; } @@ -372,11 +382,12 @@ static void r5l_append_payload_page(struct r5l_log *log, struct page *page) r5_reserve_log_entry(log, io); } -static void r5l_log_stripe(struct r5l_log *log, struct stripe_head *sh, +static int r5l_log_stripe(struct r5l_log *log, struct stripe_head *sh, int data_pages, int parity_pages) { int i; int meta_size; + int ret; struct r5l_io_unit *io; meta_size = @@ -385,7 +396,10 @@ static void r5l_log_stripe(struct r5l_log *log, struct stripe_head *sh, sizeof(struct r5l_payload_data_parity) + sizeof(__le32) * parity_pages; - r5l_get_meta(log, meta_size); + ret = r5l_get_meta(log, meta_size); + if (ret) + return ret; + io = log->current_io; for (i = 0; i < sh->disks; i++) { @@ -415,6 +429,8 @@ static void r5l_log_stripe(struct r5l_log *log, struct stripe_head *sh, list_add_tail(&sh->log_list, &io->stripe_list); atomic_inc(&io->pending_stripe); sh->log_io = io; + + return 0; } static void r5l_wake_reclaim(struct r5l_log *log, sector_t space); @@ -429,6 +445,7 @@ int r5l_write_stripe(struct r5l_log *log, struct stripe_head *sh) int meta_size; int reserve; int i; + int ret = 0; if (!log) return -EAGAIN; @@ -477,17 +494,22 @@ int r5l_write_stripe(struct r5l_log *log, struct stripe_head *sh) mutex_lock(&log->io_mutex); /* meta + data */ reserve = (1 + write_disks) << (PAGE_SHIFT - 9); - if (r5l_has_free_space(log, reserve)) - r5l_log_stripe(log, sh, data_pages, parity_pages); - else { + if (!r5l_has_free_space(log, reserve)) { spin_lock(&log->no_space_stripes_lock); list_add_tail(&sh->log_list, &log->no_space_stripes); spin_unlock(&log->no_space_stripes_lock); r5l_wake_reclaim(log, reserve); + } else { + ret = r5l_log_stripe(log, sh, data_pages, parity_pages); + if (ret) { + spin_lock_irq(&log->io_list_lock); + list_add_tail(&sh->log_list, &log->no_mem_stripes); + spin_unlock_irq(&log->io_list_lock); + } } - mutex_unlock(&log->io_mutex); + mutex_unlock(&log->io_mutex); return 0; } @@ -540,6 +562,21 @@ static sector_t r5l_reclaimable_space(struct r5l_log *log) log->next_checkpoint); } +static void r5l_run_no_mem_stripe(struct r5l_log *log) +{ + struct stripe_head *sh; + + assert_spin_locked(&log->io_list_lock); + + if (!list_empty(&log->no_mem_stripes)) { + sh = list_first_entry(&log->no_mem_stripes, + struct stripe_head, log_list); + list_del_init(&sh->log_list); + set_bit(STRIPE_HANDLE, &sh->state); + raid5_release_stripe(sh); + } +} + static bool r5l_complete_finished_ios(struct r5l_log *log) { struct r5l_io_unit *io, *next; @@ -556,7 +593,8 @@ static bool r5l_complete_finished_ios(struct r5l_log *log) log->next_cp_seq = io->seq; list_del(&io->log_sibling); - kmem_cache_free(log->io_kc, io); + mempool_free(io, log->io_pool); + r5l_run_no_mem_stripe(log); found = true; } @@ -1170,6 +1208,10 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev) if (!log->io_kc) goto io_kc; + log->io_pool = mempool_create_slab_pool(R5L_POOL_SIZE, log->io_kc); + if (!log->io_pool) + goto io_pool; + log->bs = bioset_create(R5L_POOL_SIZE, 0); if (!log->bs) goto io_bs; @@ -1184,6 +1226,8 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev) goto reclaim_thread; init_waitqueue_head(&log->iounit_wait); + INIT_LIST_HEAD(&log->no_mem_stripes); + INIT_LIST_HEAD(&log->no_space_stripes); spin_lock_init(&log->no_space_stripes_lock); @@ -1200,6 +1244,8 @@ reclaim_thread: out_mempool: bioset_free(log->bs); io_bs: + mempool_destroy(log->io_pool); +io_pool: kmem_cache_destroy(log->io_kc); io_kc: kfree(log); @@ -1211,6 +1257,7 @@ void r5l_exit_log(struct r5l_log *log) md_unregister_thread(&log->reclaim_thread); mempool_destroy(log->meta_pool); bioset_free(log->bs); + mempool_destroy(log->io_pool); kmem_cache_destroy(log->io_kc); kfree(log); } -- GitLab From e07ecd76d4db7bda1e9495395b2110a3fe28845a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 5 Jan 2016 18:37:23 -0800 Subject: [PATCH 2273/2855] libnvdimm: fix namespace object confusion in is_uuid_busy() When btt devices were re-worked to be child devices of regions this routine was overlooked. It mistakenly attempts to_nd_namespace_pmem() or to_nd_namespace_blk() conversions on btt and pfn devices. By luck to date we have happened to be hitting valid memory leading to a uuid miscompare, but a recent change to struct nd_namespace_common causes: BUG: unable to handle kernel NULL pointer dereference at 0000000000000001 IP: [] memcmp+0xc/0x40 [..] Call Trace: [] is_uuid_busy+0xc1/0x2a0 [libnvdimm] [] ? to_nd_blk_region+0x50/0x50 [libnvdimm] [] device_for_each_child+0x50/0x90 Cc: Signed-off-by: Dan Williams --- drivers/nvdimm/namespace_devs.c | 53 +++++++++++++++++++++++++++++++ drivers/nvdimm/region_devs.c | 56 --------------------------------- 2 files changed, 53 insertions(+), 56 deletions(-) diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index ee6dee41155a3..8ebfcaae3f5a0 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -77,6 +77,59 @@ static bool is_namespace_io(struct device *dev) return dev ? dev->type == &namespace_io_device_type : false; } +static int is_uuid_busy(struct device *dev, void *data) +{ + u8 *uuid1 = data, *uuid2 = NULL; + + if (is_namespace_pmem(dev)) { + struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev); + + uuid2 = nspm->uuid; + } else if (is_namespace_blk(dev)) { + struct nd_namespace_blk *nsblk = to_nd_namespace_blk(dev); + + uuid2 = nsblk->uuid; + } else if (is_nd_btt(dev)) { + struct nd_btt *nd_btt = to_nd_btt(dev); + + uuid2 = nd_btt->uuid; + } else if (is_nd_pfn(dev)) { + struct nd_pfn *nd_pfn = to_nd_pfn(dev); + + uuid2 = nd_pfn->uuid; + } + + if (uuid2 && memcmp(uuid1, uuid2, NSLABEL_UUID_LEN) == 0) + return -EBUSY; + + return 0; +} + +static int is_namespace_uuid_busy(struct device *dev, void *data) +{ + if (is_nd_pmem(dev) || is_nd_blk(dev)) + return device_for_each_child(dev, data, is_uuid_busy); + return 0; +} + +/** + * nd_is_uuid_unique - verify that no other namespace has @uuid + * @dev: any device on a nvdimm_bus + * @uuid: uuid to check + */ +bool nd_is_uuid_unique(struct device *dev, u8 *uuid) +{ + struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); + + if (!nvdimm_bus) + return false; + WARN_ON_ONCE(!is_nvdimm_bus_locked(&nvdimm_bus->dev)); + if (device_for_each_child(&nvdimm_bus->dev, uuid, + is_namespace_uuid_busy) != 0) + return false; + return true; +} + bool pmem_should_map_pages(struct device *dev) { struct nd_region *nd_region = to_nd_region(dev->parent); diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index 9c632f73915e8..139bf71ca5491 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c @@ -134,62 +134,6 @@ int nd_region_to_nstype(struct nd_region *nd_region) } EXPORT_SYMBOL(nd_region_to_nstype); -static int is_uuid_busy(struct device *dev, void *data) -{ - struct nd_region *nd_region = to_nd_region(dev->parent); - u8 *uuid = data; - - switch (nd_region_to_nstype(nd_region)) { - case ND_DEVICE_NAMESPACE_PMEM: { - struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev); - - if (!nspm->uuid) - break; - if (memcmp(uuid, nspm->uuid, NSLABEL_UUID_LEN) == 0) - return -EBUSY; - break; - } - case ND_DEVICE_NAMESPACE_BLK: { - struct nd_namespace_blk *nsblk = to_nd_namespace_blk(dev); - - if (!nsblk->uuid) - break; - if (memcmp(uuid, nsblk->uuid, NSLABEL_UUID_LEN) == 0) - return -EBUSY; - break; - } - default: - break; - } - - return 0; -} - -static int is_namespace_uuid_busy(struct device *dev, void *data) -{ - if (is_nd_pmem(dev) || is_nd_blk(dev)) - return device_for_each_child(dev, data, is_uuid_busy); - return 0; -} - -/** - * nd_is_uuid_unique - verify that no other namespace has @uuid - * @dev: any device on a nvdimm_bus - * @uuid: uuid to check - */ -bool nd_is_uuid_unique(struct device *dev, u8 *uuid) -{ - struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); - - if (!nvdimm_bus) - return false; - WARN_ON_ONCE(!is_nvdimm_bus_locked(&nvdimm_bus->dev)); - if (device_for_each_child(&nvdimm_bus->dev, uuid, - is_namespace_uuid_busy) != 0) - return false; - return true; -} - static ssize_t size_show(struct device *dev, struct device_attribute *attr, char *buf) { -- GitLab From 7cbafa09e1cdedac707104fff659f90966a02da5 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 22 Dec 2015 11:43:27 +0100 Subject: [PATCH 2274/2855] dmaengine: mv_xor: remove mv_xor_chan->current_type field Since commit 3e4f52e2da9f6 ("dma: mv_xor: Simplify the DMA_MEMCPY operation"), this field is no longer used, so get rid of it. Signed-off-by: Thomas Petazzoni Reviewed-by: Maxime Ripard Signed-off-by: Vinod Koul --- drivers/dma/mv_xor.c | 1 - drivers/dma/mv_xor.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 1c2de9a834a9c..2d033790ea2dd 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -169,7 +169,6 @@ static void mv_chan_set_mode(struct mv_xor_chan *chan, #endif writel_relaxed(config, XOR_CONFIG(chan)); - chan->current_type = type; } static void mv_chan_set_mode_to_desc(struct mv_xor_chan *chan) diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h index b7455b42137b9..34389146bf136 100644 --- a/drivers/dma/mv_xor.h +++ b/drivers/dma/mv_xor.h @@ -110,7 +110,6 @@ struct mv_xor_chan { void __iomem *mmr_high_base; unsigned int idx; int irq; - enum dma_transaction_type current_type; struct list_head chain; struct list_head free_slots; struct list_head allocated_slots; -- GitLab From 81aafb3e0e16bcca060efa6b5e477e812e4154bc Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 22 Dec 2015 11:43:28 +0100 Subject: [PATCH 2275/2855] dmaengine: mv_xor: de-duplicate mv_chan_set_mode*() When commit 6f166312c6ea2 ("dmaengine: mv_xor: add support for a38x command in descriptor mode") added support for the descriptor mode available in Marvell Armada 38x and later SoCs, it added a new function mv_chan_set_mode_to_desc() which allows to configure a XOR channel to get the specific operation to be done from each individual DMA descriptor. However, this function was mainly a duplicate of the existing mv_chan_set_mode(), with just the operation being different. This commit re-organizes the code into a single mv_chan_set_mode() function, which takes the operation mode as argument, and the mv_xor_channel_add() function decides whether to use XOR_OPERATION_MODE_IN_DESC or XOR_OPERATION_MODE_XOR. Signed-off-by: Thomas Petazzoni Reviewed-by: Maxime Ripard Signed-off-by: Vinod Koul --- drivers/dma/mv_xor.c | 41 +++-------------------------------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 2d033790ea2dd..a95878cd36d93 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -139,45 +139,10 @@ static void mv_chan_clear_err_status(struct mv_xor_chan *chan) } static void mv_chan_set_mode(struct mv_xor_chan *chan, - enum dma_transaction_type type) + u32 op_mode) { - u32 op_mode; u32 config = readl_relaxed(XOR_CONFIG(chan)); - switch (type) { - case DMA_XOR: - op_mode = XOR_OPERATION_MODE_XOR; - break; - case DMA_MEMCPY: - op_mode = XOR_OPERATION_MODE_MEMCPY; - break; - default: - dev_err(mv_chan_to_devp(chan), - "error: unsupported operation %d\n", - type); - BUG(); - return; - } - - config &= ~0x7; - config |= op_mode; - -#if defined(__BIG_ENDIAN) - config |= XOR_DESCRIPTOR_SWAP; -#else - config &= ~XOR_DESCRIPTOR_SWAP; -#endif - - writel_relaxed(config, XOR_CONFIG(chan)); -} - -static void mv_chan_set_mode_to_desc(struct mv_xor_chan *chan) -{ - u32 op_mode; - u32 config = readl_relaxed(XOR_CONFIG(chan)); - - op_mode = XOR_OPERATION_MODE_IN_DESC; - config &= ~0x7; config |= op_mode; @@ -1042,9 +1007,9 @@ mv_xor_channel_add(struct mv_xor_device *xordev, mv_chan_unmask_interrupts(mv_chan); if (mv_chan->op_in_desc == XOR_MODE_IN_DESC) - mv_chan_set_mode_to_desc(mv_chan); + mv_chan_set_mode(mv_chan, XOR_OPERATION_MODE_IN_DESC); else - mv_chan_set_mode(mv_chan, DMA_XOR); + mv_chan_set_mode(mv_chan, XOR_OPERATION_MODE_XOR); spin_lock_init(&mv_chan->lock); INIT_LIST_HEAD(&mv_chan->chain); -- GitLab From 8b648436eb45c1f561164b24aafd35fb2bee9cfc Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 22 Dec 2015 11:43:29 +0100 Subject: [PATCH 2276/2855] dmaengine: mv_xor: add suspend/resume support This commit adds suspend/resume support to the mv_xor driver. The config and interrupt mask registers must be saved and restored, and upon resume, the MBus windows configuration must also be done again. Tested on Armada 388 GP, with a RAID 5 array, accessed before and after a suspend to RAM cycle. Based on work from Ofer Heifetz and Lior Amsalem. Signed-off-by: Thomas Petazzoni Signed-off-by: Vinod Koul --- drivers/dma/mv_xor.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ drivers/dma/mv_xor.h | 1 + 2 files changed, 54 insertions(+) diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index a95878cd36d93..14091f878f80a 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1085,6 +1085,57 @@ mv_xor_conf_mbus_windows(struct mv_xor_device *xordev, writel(0, base + WINDOW_OVERRIDE_CTRL(1)); } +/* + * Since this XOR driver is basically used only for RAID5, we don't + * need to care about synchronizing ->suspend with DMA activity, + * because the DMA engine will naturally be quiet due to the block + * devices being suspended. + */ +static int mv_xor_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct mv_xor_device *xordev = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) { + struct mv_xor_chan *mv_chan = xordev->channels[i]; + + if (!mv_chan) + continue; + + mv_chan->saved_config_reg = + readl_relaxed(XOR_CONFIG(mv_chan)); + mv_chan->saved_int_mask_reg = + readl_relaxed(XOR_INTR_MASK(mv_chan)); + } + + return 0; +} + +static int mv_xor_resume(struct platform_device *dev) +{ + struct mv_xor_device *xordev = platform_get_drvdata(dev); + const struct mbus_dram_target_info *dram; + int i; + + for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) { + struct mv_xor_chan *mv_chan = xordev->channels[i]; + + if (!mv_chan) + continue; + + writel_relaxed(mv_chan->saved_config_reg, + XOR_CONFIG(mv_chan)); + writel_relaxed(mv_chan->saved_int_mask_reg, + XOR_INTR_MASK(mv_chan)); + } + + dram = mv_mbus_dram_info(); + if (dram) + mv_xor_conf_mbus_windows(xordev, dram); + + return 0; +} + static const struct of_device_id mv_xor_dt_ids[] = { { .compatible = "marvell,orion-xor", .data = (void *)XOR_MODE_IN_REG }, { .compatible = "marvell,armada-380-xor", .data = (void *)XOR_MODE_IN_DESC }, @@ -1246,6 +1297,8 @@ err_channel_add: static struct platform_driver mv_xor_driver = { .probe = mv_xor_probe, + .suspend = mv_xor_suspend, + .resume = mv_xor_resume, .driver = { .name = MV_XOR_NAME, .of_match_table = of_match_ptr(mv_xor_dt_ids), diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h index 34389146bf136..c19fe30e5ae91 100644 --- a/drivers/dma/mv_xor.h +++ b/drivers/dma/mv_xor.h @@ -125,6 +125,7 @@ struct mv_xor_chan { char dummy_src[MV_XOR_MIN_BYTE_COUNT]; char dummy_dst[MV_XOR_MIN_BYTE_COUNT]; dma_addr_t dummy_src_addr, dummy_dst_addr; + u32 saved_config_reg, saved_int_mask_reg; }; /** -- GitLab From 13331a551ab4df87f7a027d2cab392da96aba1de Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 6 Jan 2016 08:57:06 -0500 Subject: [PATCH 2277/2855] SUNRPC: Fixup socket wait for memory We're seeing hangs in the NFS client code, with loops of the form: RPC: 30317 xmit incomplete (267368 left of 524448) RPC: 30317 call_status (status -11) RPC: 30317 call_transmit (status 0) RPC: 30317 xprt_prepare_transmit RPC: 30317 xprt_transmit(524448) RPC: xs_tcp_send_request(267368) = -11 RPC: 30317 xmit incomplete (267368 left of 524448) RPC: 30317 call_status (status -11) RPC: 30317 call_transmit (status 0) RPC: 30317 xprt_prepare_transmit RPC: 30317 xprt_transmit(524448) Turns out commit ceb5d58b2170 ("net: fix sock_wake_async() rcu protection") moved SOCKWQ_ASYNC_NOSPACE out of sock->flags and into sk->sk_wq->flags, however it never tried to fix up the code in net/sunrpc. The new idiom is to use the flags in the RCU protected struct socket_wq. While we're at it, clear out the now redundant places where we set/clear SOCKWQ_ASYNC_NOSPACE and SOCK_NOSPACE. In principle, sk_stream_wait_memory() is supposed to set these for us, so we only need to clear them in the particular case of our ->write_space() callback. Fixes: ceb5d58b2170 ("net: fix sock_wake_async() rcu protection") Cc: Eric Dumazet Cc: stable@vger.kernel.org # 4.4 Signed-off-by: Trond Myklebust --- net/sunrpc/xprtsock.c | 49 +++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 2ffaf6a794994..027c9ef8a263f 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -398,7 +398,6 @@ static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, if (unlikely(!sock)) return -ENOTSOCK; - clear_bit(SOCKWQ_ASYNC_NOSPACE, &sock->flags); if (base != 0) { addr = NULL; addrlen = 0; @@ -442,7 +441,6 @@ static void xs_nospace_callback(struct rpc_task *task) struct sock_xprt *transport = container_of(task->tk_rqstp->rq_xprt, struct sock_xprt, xprt); transport->inet->sk_write_pending--; - clear_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags); } /** @@ -467,20 +465,11 @@ static int xs_nospace(struct rpc_task *task) /* Don't race with disconnect */ if (xprt_connected(xprt)) { - if (test_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags)) { - /* - * Notify TCP that we're limited by the application - * window size - */ - set_bit(SOCK_NOSPACE, &transport->sock->flags); - sk->sk_write_pending++; - /* ...and wait for more buffer space */ - xprt_wait_for_buffer_space(task, xs_nospace_callback); - } - } else { - clear_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags); + /* wait for more buffer space */ + sk->sk_write_pending++; + xprt_wait_for_buffer_space(task, xs_nospace_callback); + } else ret = -ENOTCONN; - } spin_unlock_bh(&xprt->transport_lock); @@ -616,9 +605,6 @@ process_status: case -EAGAIN: status = xs_nospace(task); break; - default: - dprintk("RPC: sendmsg returned unrecognized error %d\n", - -status); case -ENETUNREACH: case -ENOBUFS: case -EPIPE: @@ -626,7 +612,10 @@ process_status: case -EPERM: /* When the server has died, an ICMP port unreachable message * prompts ECONNREFUSED. */ - clear_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags); + break; + default: + dprintk("RPC: sendmsg returned unrecognized error %d\n", + -status); } return status; @@ -706,16 +695,16 @@ static int xs_tcp_send_request(struct rpc_task *task) case -EAGAIN: status = xs_nospace(task); break; - default: - dprintk("RPC: sendmsg returned unrecognized error %d\n", - -status); case -ECONNRESET: case -ECONNREFUSED: case -ENOTCONN: case -EADDRINUSE: case -ENOBUFS: case -EPIPE: - clear_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags); + break; + default: + dprintk("RPC: sendmsg returned unrecognized error %d\n", + -status); } return status; @@ -1609,19 +1598,23 @@ static void xs_tcp_state_change(struct sock *sk) static void xs_write_space(struct sock *sk) { - struct socket *sock; + struct socket_wq *wq; struct rpc_xprt *xprt; - if (unlikely(!(sock = sk->sk_socket))) + if (!sk->sk_socket) return; - clear_bit(SOCK_NOSPACE, &sock->flags); + clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags); if (unlikely(!(xprt = xprt_from_sock(sk)))) return; - if (test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &sock->flags) == 0) - return; + rcu_read_lock(); + wq = rcu_dereference(sk->sk_wq); + if (!wq || test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags) == 0) + goto out; xprt_write_space(xprt); +out: + rcu_read_unlock(); } /** -- GitLab From 2708f2957ce70037d3eab8a45523d4445404ecb4 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Tue, 22 Dec 2015 10:36:36 -0600 Subject: [PATCH 2278/2855] hpsa: fix path_info_show Left off some changes from Rasmus Villemoes where he changed snprintf to scnprintf. Suggested-by: Rasmus Villemoes Reviewed-by: Justin Lindley Reviewed-by: Kevin Barnett Reviewed-by: Scott Teel Reviewed-by: Rasmus Villemoes Reviewed-by: Hannes Reinecke Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/hpsa.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 6a8f95808ee0f..9ad546e8e1484 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -795,7 +795,7 @@ static ssize_t path_info_show(struct device *dev, if (hdev->external || hdev->devtype == TYPE_RAID || is_logical_device(hdev)) { - output_len += snprintf(buf + output_len, + output_len += scnprintf(buf + output_len, PAGE_SIZE - output_len, "%s\n", active); continue; @@ -809,28 +809,28 @@ static ssize_t path_info_show(struct device *dev, if (phys_connector[1] < '0') phys_connector[1] = '0'; if (hdev->phys_connector[i] > 0) - output_len += snprintf(buf + output_len, + output_len += scnprintf(buf + output_len, PAGE_SIZE - output_len, "PORT: %.2s ", phys_connector); if (hdev->devtype == TYPE_DISK && hdev->expose_device) { if (box == 0 || box == 0xFF) { - output_len += snprintf(buf + output_len, + output_len += scnprintf(buf + output_len, PAGE_SIZE - output_len, "BAY: %hhu %s\n", bay, active); } else { - output_len += snprintf(buf + output_len, + output_len += scnprintf(buf + output_len, PAGE_SIZE - output_len, "BOX: %hhu BAY: %hhu %s\n", box, bay, active); } } else if (box != 0 && box != 0xFF) { - output_len += snprintf(buf + output_len, + output_len += scnprintf(buf + output_len, PAGE_SIZE - output_len, "BOX: %hhu %s\n", box, active); } else - output_len += snprintf(buf + output_len, + output_len += scnprintf(buf + output_len, PAGE_SIZE - output_len, "%s\n", active); } -- GitLab From 09371d623c9c3dc6ed7f53ec8ab01d25f0c6c697 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Tue, 22 Dec 2015 10:36:42 -0600 Subject: [PATCH 2279/2855] hpsa: Change SAS transport devices to bus 0. SAS transport places devices on bus 0 but driver was setting the bus to 3. Reviewed-by: Justin Lindley Reviewed-by: Kevin Barnett Reviewed-by: Scott Teel Reviewed-by: Matthew R. Ochs Reviewed-by: Hannes Reinecke Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/hpsa.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h index ae5beda1bdb51..fdd39fc0b199f 100644 --- a/drivers/scsi/hpsa.h +++ b/drivers/scsi/hpsa.h @@ -400,7 +400,7 @@ struct offline_device_entry { #define HPSA_PHYSICAL_DEVICE_BUS 0 #define HPSA_RAID_VOLUME_BUS 1 #define HPSA_EXTERNAL_RAID_VOLUME_BUS 2 -#define HPSA_HBA_BUS 3 +#define HPSA_HBA_BUS 0 /* Send the command to the hardware -- GitLab From cca8f13b4fdaf3583e103ae7f96fda948839b265 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Tue, 22 Dec 2015 10:36:48 -0600 Subject: [PATCH 2280/2855] hpsa: Add box and bay information for enclosure devices Adding a new method to display enclosure device information. Reviewed-by: Justin Lindley Reviewed-by: Kevin Barnett Reviewed-by: Scott Teel Reviewed-by: Hannes Reinecke Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/hpsa.c | 107 +++++++++++++++++++++++++++++++++++++--- drivers/scsi/hpsa_cmd.h | 13 +++++ 2 files changed, 113 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 9ad546e8e1484..17a39761b05d4 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -750,7 +750,6 @@ static ssize_t host_show_hp_ssd_smart_path_enabled(struct device *dev, } #define MAX_PATHS 8 - static ssize_t path_info_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -792,9 +791,7 @@ static ssize_t path_info_show(struct device *dev, hdev->bus, hdev->target, hdev->lun, scsi_device_type(hdev->devtype)); - if (hdev->external || - hdev->devtype == TYPE_RAID || - is_logical_device(hdev)) { + if (hdev->devtype == TYPE_RAID || is_logical_device(hdev)) { output_len += scnprintf(buf + output_len, PAGE_SIZE - output_len, "%s\n", active); @@ -808,8 +805,7 @@ static ssize_t path_info_show(struct device *dev, phys_connector[0] = '0'; if (phys_connector[1] < '0') phys_connector[1] = '0'; - if (hdev->phys_connector[i] > 0) - output_len += scnprintf(buf + output_len, + output_len += scnprintf(buf + output_len, PAGE_SIZE - output_len, "PORT: %.2s ", phys_connector); @@ -3191,6 +3187,87 @@ out: return rc; } +/* + * get enclosure information + * struct ReportExtendedLUNdata *rlep - Used for BMIC drive number + * struct hpsa_scsi_dev_t *encl_dev - device entry for enclosure + * Uses id_physical_device to determine the box_index. + */ +static void hpsa_get_enclosure_info(struct ctlr_info *h, + unsigned char *scsi3addr, + struct ReportExtendedLUNdata *rlep, int rle_index, + struct hpsa_scsi_dev_t *encl_dev) +{ + int rc = -1; + struct CommandList *c = NULL; + struct ErrorInfo *ei = NULL; + struct bmic_sense_storage_box_params *bssbp = NULL; + struct bmic_identify_physical_device *id_phys = NULL; + struct ext_report_lun_entry *rle = &rlep->LUN[rle_index]; + u16 bmic_device_index = 0; + + bmic_device_index = GET_BMIC_DRIVE_NUMBER(&rle->lunid[0]); + + if (bmic_device_index == 0xFF00) + goto out; + + bssbp = kzalloc(sizeof(*bssbp), GFP_KERNEL); + if (!bssbp) + goto out; + + id_phys = kzalloc(sizeof(*id_phys), GFP_KERNEL); + if (!id_phys) + goto out; + + rc = hpsa_bmic_id_physical_device(h, scsi3addr, bmic_device_index, + id_phys, sizeof(*id_phys)); + if (rc) { + dev_warn(&h->pdev->dev, "%s: id_phys failed %d bdi[0x%x]\n", + __func__, encl_dev->external, bmic_device_index); + goto out; + } + + c = cmd_alloc(h); + + rc = fill_cmd(c, BMIC_SENSE_STORAGE_BOX_PARAMS, h, bssbp, + sizeof(*bssbp), 0, RAID_CTLR_LUNID, TYPE_CMD); + + if (rc) + goto out; + + if (id_phys->phys_connector[1] == 'E') + c->Request.CDB[5] = id_phys->box_index; + else + c->Request.CDB[5] = 0; + + rc = hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE, + NO_TIMEOUT); + if (rc) + goto out; + + ei = c->err_info; + if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) { + rc = -1; + goto out; + } + + encl_dev->box[id_phys->active_path_number] = bssbp->phys_box_on_port; + memcpy(&encl_dev->phys_connector[id_phys->active_path_number], + bssbp->phys_connector, sizeof(bssbp->phys_connector)); + + rc = IO_OK; +out: + kfree(bssbp); + kfree(id_phys); + + if (c) + cmd_free(h, c); + + if (rc != IO_OK) + hpsa_show_dev_msg(KERN_INFO, h, encl_dev, + "Error, could not get enclosure information\n"); +} + static u64 hpsa_get_sas_address_from_report_physical(struct ctlr_info *h, unsigned char *scsi3addr) { @@ -4032,7 +4109,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h) /* skip masked non-disk devices */ if (MASKED_DEVICE(lunaddrbytes) && physical_device && - (physdev_list->LUN[phys_dev_index].device_flags & 0x01)) + (physdev_list->LUN[phys_dev_index].device_type != 0x06) && + (physdev_list->LUN[phys_dev_index].device_flags & 0x01)) continue; /* Get device type, vendor, model, device id */ @@ -4116,7 +4194,12 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h) break; case TYPE_TAPE: case TYPE_MEDIUM_CHANGER: + ncurrent++; + break; case TYPE_ENCLOSURE: + hpsa_get_enclosure_info(h, lunaddrbytes, + physdev_list, phys_dev_index, + this_device); ncurrent++; break; case TYPE_RAID: @@ -6629,6 +6712,16 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, c->Request.CDB[7] = (size >> 16) & 0xFF; c->Request.CDB[8] = (size >> 8) & 0XFF; break; + case BMIC_SENSE_STORAGE_BOX_PARAMS: + c->Request.CDBLen = 10; + c->Request.type_attr_dir = + TYPE_ATTR_DIR(cmd_type, ATTR_SIMPLE, XFER_READ); + c->Request.Timeout = 0; + c->Request.CDB[0] = BMIC_READ; + c->Request.CDB[6] = BMIC_SENSE_STORAGE_BOX_PARAMS; + c->Request.CDB[7] = (size >> 16) & 0xFF; + c->Request.CDB[8] = (size >> 8) & 0XFF; + break; case BMIC_IDENTIFY_CONTROLLER: c->Request.CDBLen = 10; c->Request.type_attr_dir = diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h index d92ef0d352b55..6a919ada96b30 100644 --- a/drivers/scsi/hpsa_cmd.h +++ b/drivers/scsi/hpsa_cmd.h @@ -291,6 +291,7 @@ struct SenseSubsystem_info { #define BMIC_SENSE_DIAG_OPTIONS 0xF5 #define HPSA_DIAG_OPTS_DISABLE_RLD_CACHING 0x40000000 #define BMIC_SENSE_SUBSYSTEM_INFORMATION 0x66 +#define BMIC_SENSE_STORAGE_BOX_PARAMS 0x65 /* Command List Structure */ union SCSI3Addr { @@ -842,5 +843,17 @@ struct bmic_sense_subsystem_info { u8 pad[332]; }; +struct bmic_sense_storage_box_params { + u8 reserved[36]; + u8 inquiry_valid; + u8 reserved_1[68]; + u8 phys_box_on_port; + u8 reserved_2[22]; + u16 connection_info; + u8 reserver_3[84]; + u8 phys_connector[2]; + u8 reserved_4[296]; +}; + #pragma pack() #endif /* HPSA_CMD_H */ -- GitLab From 5f985d88bac34e7f3b4403118eab072902a0b392 Mon Sep 17 00:00:00 2001 From: Tomas Henzl Date: Wed, 23 Dec 2015 14:21:47 +0100 Subject: [PATCH 2281/2855] mpt3sas: A correction in unmap_resources It might happen that we try to free an already freed pointer. Reported-by: Maurizio Lombardi Signed-off-by: Tomas Henzl Acked-by: Chaitra P B Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 11393ebf1a68e..83658acddd584 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -2020,8 +2020,10 @@ mpt3sas_base_unmap_resources(struct MPT3SAS_ADAPTER *ioc) _base_free_irq(ioc); _base_disable_msix(ioc); - if (ioc->msix96_vector) + if (ioc->msix96_vector) { kfree(ioc->replyPostRegisterIndex); + ioc->replyPostRegisterIndex = NULL; + } if (ioc->chip_phys) { iounmap(ioc->chip); -- GitLab From c56f5f1de3a6ab8ec985edbc358e1fd8d4e36a65 Mon Sep 17 00:00:00 2001 From: Wilfried Weissmann Date: Sun, 27 Dec 2015 20:21:19 +0100 Subject: [PATCH 2282/2855] mvsas: Add SGPIO support to Marvell 94xx Add SGPIO support to Marvell 94xx. Signed-off-by: Wilfried Weissmann Reviewed-by: James Bottomley Signed-off-by: Martin K. Petersen --- drivers/scsi/mvsas/mv_94xx.c | 134 +++++++++++++++++++++++++++++++++++ drivers/scsi/mvsas/mv_94xx.h | 71 +++++++++++++++++++ drivers/scsi/mvsas/mv_init.c | 2 + drivers/scsi/mvsas/mv_sas.c | 13 ++++ drivers/scsi/mvsas/mv_sas.h | 5 ++ 5 files changed, 225 insertions(+) diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c index 9270d15ff1a49..f6fc4a7059248 100644 --- a/drivers/scsi/mvsas/mv_94xx.c +++ b/drivers/scsi/mvsas/mv_94xx.c @@ -330,6 +330,51 @@ static void mvs_94xx_phy_enable(struct mvs_info *mvi, u32 phy_id) mvs_write_port_vsr_data(mvi, phy_id, tmp & 0xfd7fffff); } +static void mvs_94xx_sgpio_init(struct mvs_info *mvi) +{ + void __iomem *regs = mvi->regs_ex - 0x10200; + u32 tmp; + + tmp = mr32(MVS_HST_CHIP_CONFIG); + tmp |= 0x100; + mw32(MVS_HST_CHIP_CONFIG, tmp); + + mw32(MVS_SGPIO_CTRL + MVS_SGPIO_HOST_OFFSET * mvi->id, + MVS_SGPIO_CTRL_SDOUT_AUTO << MVS_SGPIO_CTRL_SDOUT_SHIFT); + + mw32(MVS_SGPIO_CFG1 + MVS_SGPIO_HOST_OFFSET * mvi->id, + 8 << MVS_SGPIO_CFG1_LOWA_SHIFT | + 8 << MVS_SGPIO_CFG1_HIA_SHIFT | + 4 << MVS_SGPIO_CFG1_LOWB_SHIFT | + 4 << MVS_SGPIO_CFG1_HIB_SHIFT | + 2 << MVS_SGPIO_CFG1_MAXACTON_SHIFT | + 1 << MVS_SGPIO_CFG1_FORCEACTOFF_SHIFT + ); + + mw32(MVS_SGPIO_CFG2 + MVS_SGPIO_HOST_OFFSET * mvi->id, + (300000 / 100) << MVS_SGPIO_CFG2_CLK_SHIFT | /* 100kHz clock */ + 66 << MVS_SGPIO_CFG2_BLINK_SHIFT /* (66 * 0,121 Hz?)*/ + ); + + mw32(MVS_SGPIO_CFG0 + MVS_SGPIO_HOST_OFFSET * mvi->id, + MVS_SGPIO_CFG0_ENABLE | + MVS_SGPIO_CFG0_BLINKA | + MVS_SGPIO_CFG0_BLINKB | + /* 3*4 data bits / PDU */ + (12 - 1) << MVS_SGPIO_CFG0_AUT_BITLEN_SHIFT + ); + + mw32(MVS_SGPIO_DCTRL + MVS_SGPIO_HOST_OFFSET * mvi->id, + DEFAULT_SGPIO_BITS); + + mw32(MVS_SGPIO_DSRC + MVS_SGPIO_HOST_OFFSET * mvi->id, + ((mvi->id * 4) + 3) << (8 * 3) | + ((mvi->id * 4) + 2) << (8 * 2) | + ((mvi->id * 4) + 1) << (8 * 1) | + ((mvi->id * 4) + 0) << (8 * 0)); + +} + static int mvs_94xx_init(struct mvs_info *mvi) { void __iomem *regs = mvi->regs; @@ -533,6 +578,8 @@ static int mvs_94xx_init(struct mvs_info *mvi) /* Enable SRS interrupt */ mw32(MVS_INT_MASK_SRS_0, 0xFFFF); + mvs_94xx_sgpio_init(mvi); + return 0; } @@ -1005,6 +1052,92 @@ static void mvs_94xx_tune_interrupt(struct mvs_info *mvi, u32 time) } +static int mvs_94xx_gpio_write(struct mvs_prv_info *mvs_prv, + u8 reg_type, u8 reg_index, + u8 reg_count, u8 *write_data) +{ + int i; + + switch (reg_type) { + + case SAS_GPIO_REG_TX_GP: + if (reg_index == 0) + return -EINVAL; + + if (reg_count > 1) + return -EINVAL; + + if (reg_count == 0) + return 0; + + /* maximum supported bits = hosts * 4 drives * 3 bits */ + for (i = 0; i < mvs_prv->n_host * 4 * 3; i++) { + + /* select host */ + struct mvs_info *mvi = mvs_prv->mvi[i/(4*3)]; + + void __iomem *regs = mvi->regs_ex - 0x10200; + + int drive = (i/3) & (4-1); /* drive number on host */ + u32 block = mr32(MVS_SGPIO_DCTRL + + MVS_SGPIO_HOST_OFFSET * mvi->id); + + + /* + * if bit is set then create a mask with the first + * bit of the drive set in the mask ... + */ + u32 bit = (write_data[i/8] & (1 << (i&(8-1)))) ? + 1<<(24-drive*8) : 0; + + /* + * ... and then shift it to the right position based + * on the led type (activity/id/fail) + */ + switch (i%3) { + case 0: /* activity */ + block &= ~((0x7 << MVS_SGPIO_DCTRL_ACT_SHIFT) + << (24-drive*8)); + /* hardwire activity bit to SOF */ + block |= LED_BLINKA_SOF << ( + MVS_SGPIO_DCTRL_ACT_SHIFT + + (24-drive*8)); + break; + case 1: /* id */ + block &= ~((0x3 << MVS_SGPIO_DCTRL_LOC_SHIFT) + << (24-drive*8)); + block |= bit << MVS_SGPIO_DCTRL_LOC_SHIFT; + break; + case 2: /* fail */ + block &= ~((0x7 << MVS_SGPIO_DCTRL_ERR_SHIFT) + << (24-drive*8)); + block |= bit << MVS_SGPIO_DCTRL_ERR_SHIFT; + break; + } + + mw32(MVS_SGPIO_DCTRL + MVS_SGPIO_HOST_OFFSET * mvi->id, + block); + + } + + return reg_count; + + case SAS_GPIO_REG_TX: + if (reg_index + reg_count > mvs_prv->n_host) + return -EINVAL; + + for (i = 0; i < reg_count; i++) { + struct mvs_info *mvi = mvs_prv->mvi[i+reg_index]; + void __iomem *regs = mvi->regs_ex - 0x10200; + + mw32(MVS_SGPIO_DCTRL + MVS_SGPIO_HOST_OFFSET * mvi->id, + be32_to_cpu(((u32 *) write_data)[i])); + } + return reg_count; + } + return -ENOSYS; +} + const struct mvs_dispatch mvs_94xx_dispatch = { "mv94xx", mvs_94xx_init, @@ -1057,5 +1190,6 @@ const struct mvs_dispatch mvs_94xx_dispatch = { mvs_94xx_fix_dma, mvs_94xx_tune_interrupt, mvs_94xx_non_spec_ncq_error, + mvs_94xx_gpio_write, }; diff --git a/drivers/scsi/mvsas/mv_94xx.h b/drivers/scsi/mvsas/mv_94xx.h index 14e197497b469..578960803a003 100644 --- a/drivers/scsi/mvsas/mv_94xx.h +++ b/drivers/scsi/mvsas/mv_94xx.h @@ -38,6 +38,10 @@ enum VANIR_REVISION_ID { VANIR_C2_REV = 0xC2, }; +enum host_registers { + MVS_HST_CHIP_CONFIG = 0x10104, /* chip configuration */ +}; + enum hw_registers { MVS_GBL_CTL = 0x04, /* global control */ MVS_GBL_INT_STAT = 0x00, /* global irq status */ @@ -239,6 +243,73 @@ struct mvs_prd { __le32 im_len; } __attribute__ ((packed)); +enum sgpio_registers { + MVS_SGPIO_HOST_OFFSET = 0x100, /* offset between hosts */ + + MVS_SGPIO_CFG0 = 0xc200, + MVS_SGPIO_CFG0_ENABLE = (1 << 0), /* enable pins */ + MVS_SGPIO_CFG0_BLINKB = (1 << 1), /* blink generators */ + MVS_SGPIO_CFG0_BLINKA = (1 << 2), + MVS_SGPIO_CFG0_INVSCLK = (1 << 3), /* invert signal? */ + MVS_SGPIO_CFG0_INVSLOAD = (1 << 4), + MVS_SGPIO_CFG0_INVSDOUT = (1 << 5), + MVS_SGPIO_CFG0_SLOAD_FALLEDGE = (1 << 6), /* rise/fall edge? */ + MVS_SGPIO_CFG0_SDOUT_FALLEDGE = (1 << 7), + MVS_SGPIO_CFG0_SDIN_RISEEDGE = (1 << 8), + MVS_SGPIO_CFG0_MAN_BITLEN_SHIFT = 18, /* bits/frame manual mode */ + MVS_SGPIO_CFG0_AUT_BITLEN_SHIFT = 24, /* bits/frame auto mode */ + + MVS_SGPIO_CFG1 = 0xc204, /* blink timing register */ + MVS_SGPIO_CFG1_LOWA_SHIFT = 0, /* A off time */ + MVS_SGPIO_CFG1_HIA_SHIFT = 4, /* A on time */ + MVS_SGPIO_CFG1_LOWB_SHIFT = 8, /* B off time */ + MVS_SGPIO_CFG1_HIB_SHIFT = 12, /* B on time */ + MVS_SGPIO_CFG1_MAXACTON_SHIFT = 16, /* max activity on time */ + + /* force activity off time */ + MVS_SGPIO_CFG1_FORCEACTOFF_SHIFT = 20, + /* stretch activity on time */ + MVS_SGPIO_CFG1_STRCHACTON_SHIFT = 24, + /* stretch activiity off time */ + MVS_SGPIO_CFG1_STRCHACTOFF_SHIFT = 28, + + + MVS_SGPIO_CFG2 = 0xc208, /* clock speed register */ + MVS_SGPIO_CFG2_CLK_SHIFT = 0, + MVS_SGPIO_CFG2_BLINK_SHIFT = 20, + + MVS_SGPIO_CTRL = 0xc20c, /* SDOUT/SDIN mode control */ + MVS_SGPIO_CTRL_SDOUT_AUTO = 2, + MVS_SGPIO_CTRL_SDOUT_SHIFT = 2, + + MVS_SGPIO_DSRC = 0xc220, /* map ODn bits to drives */ + + MVS_SGPIO_DCTRL = 0xc238, + MVS_SGPIO_DCTRL_ERR_SHIFT = 0, + MVS_SGPIO_DCTRL_LOC_SHIFT = 3, + MVS_SGPIO_DCTRL_ACT_SHIFT = 5, +}; + +enum sgpio_led_status { + LED_OFF = 0, + LED_ON = 1, + LED_BLINKA = 2, + LED_BLINKA_INV = 3, + LED_BLINKA_SOF = 4, + LED_BLINKA_EOF = 5, + LED_BLINKB = 6, + LED_BLINKB_INV = 7, +}; + +#define DEFAULT_SGPIO_BITS ((LED_BLINKA_SOF << \ + MVS_SGPIO_DCTRL_ACT_SHIFT) << (8 * 3) | \ + (LED_BLINKA_SOF << \ + MVS_SGPIO_DCTRL_ACT_SHIFT) << (8 * 2) | \ + (LED_BLINKA_SOF << \ + MVS_SGPIO_DCTRL_ACT_SHIFT) << (8 * 1) | \ + (LED_BLINKA_SOF << \ + MVS_SGPIO_DCTRL_ACT_SHIFT) << (8 * 0)) + /* * these registers are accessed through port vendor * specific address/data registers diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index 90fdf0e859e31..6110ef3bfa92e 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -84,6 +84,8 @@ static struct sas_domain_function_template mvs_transport_ops = { .lldd_port_formed = mvs_port_formed, .lldd_port_deformed = mvs_port_deformed, + .lldd_write_gpio = mvs_gpio_write, + }; static void mvs_phy_init(struct mvs_info *mvi, int phy_id) diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index e712fe7459556..83cd3ea2df41e 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c @@ -2105,3 +2105,16 @@ int mvs_int_rx(struct mvs_info *mvi, bool self_clear) return 0; } +int mvs_gpio_write(struct sas_ha_struct *sha, u8 reg_type, u8 reg_index, + u8 reg_count, u8 *write_data) +{ + struct mvs_prv_info *mvs_prv = sha->lldd_ha; + struct mvs_info *mvi = mvs_prv->mvi[0]; + + if (MVS_CHIP_DISP->gpio_write) { + return MVS_CHIP_DISP->gpio_write(mvs_prv, reg_type, + reg_index, reg_count, write_data); + } + + return -ENOSYS; +} diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h index dc409c04747ae..f9afd4cdd4c4e 100644 --- a/drivers/scsi/mvsas/mv_sas.h +++ b/drivers/scsi/mvsas/mv_sas.h @@ -103,6 +103,7 @@ enum dev_reset { }; struct mvs_info; +struct mvs_prv_info; struct mvs_dispatch { char *name; @@ -172,6 +173,8 @@ struct mvs_dispatch { int buf_len, int from, void *prd); void (*tune_interrupt)(struct mvs_info *mvi, u32 time); void (*non_spec_ncq_error)(struct mvs_info *mvi); + int (*gpio_write)(struct mvs_prv_info *mvs_prv, u8 reg_type, + u8 reg_index, u8 reg_count, u8 *write_data); }; @@ -476,5 +479,7 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events); void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st); int mvs_int_rx(struct mvs_info *mvi, bool self_clear); struct mvs_device *mvs_find_dev_by_reg_set(struct mvs_info *mvi, u8 reg_set); +int mvs_gpio_write(struct sas_ha_struct *, u8 reg_type, u8 reg_index, + u8 reg_count, u8 *write_data); #endif -- GitLab From 83d1e8b9b51b06d79653293d0bf34ff2c61abe46 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Dec 2015 13:15:48 -0800 Subject: [PATCH 2283/2855] storvsc: Fix a bug in the layout of the hv_fc_wwn_packet The hv_fc_wwn_packet is exchanged over vmbus. Make the definition in Linux match the Windows definition. Signed-off-by: K. Y. Srinivasan Reviewed-by: Johannes Thumshirn Reviewed-by: Long Li Reviewed-by: Hannes Reinecke Tested-by: Alex Ng Signed-off-by: Martin K. Petersen --- drivers/scsi/storvsc_drv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index c41f6748823a7..00bb4bdffe852 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -92,9 +92,8 @@ enum vstor_packet_operation { */ struct hv_fc_wwn_packet { - bool primary_active; - u8 reserved1; - u8 reserved2; + u8 primary_active; + u8 reserved1[3]; u8 primary_port_wwn[8]; u8 primary_node_wwn[8]; u8 secondary_port_wwn[8]; -- GitLab From dac582417bc449b1f7f572d3f1dd9d23eec15cc9 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Dec 2015 13:15:49 -0800 Subject: [PATCH 2284/2855] storvsc: Properly support Fibre Channel devices For FC devices managed by this driver, atttach the appropriate transport template. This will allow us to create the appropriate sysfs files for these devices. With this we can publish the wwn for both the port and the node. Signed-off-by: K. Y. Srinivasan Reviewed-by: Long Li Tested-by: Alex Ng Signed-off-by: Martin K. Petersen --- drivers/scsi/storvsc_drv.c | 181 +++++++++++++++++++++++++++---------- 1 file changed, 134 insertions(+), 47 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 00bb4bdffe852..cfbb2890b31f2 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -41,6 +41,7 @@ #include #include #include +#include /* * All wire protocol details (storage protocol between the guest and the host) @@ -397,6 +398,9 @@ static int storvsc_timeout = 180; static int msft_blist_flags = BLIST_TRY_VPD_PAGES; +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) +static struct scsi_transport_template *fc_transport_template; +#endif static void storvsc_on_channel_callback(void *context); @@ -456,6 +460,11 @@ struct storvsc_device { /* Used for vsc/vsp channel reset process */ struct storvsc_cmd_request init_request; struct storvsc_cmd_request reset_request; + /* + * Currently active port and node names for FC devices. + */ + u64 node_name; + u64 port_name; }; struct hv_host_device { @@ -695,7 +704,26 @@ static void handle_multichannel_storage(struct hv_device *device, int max_chns) vmbus_are_subchannels_present(device->channel); } -static int storvsc_channel_init(struct hv_device *device) +static void cache_wwn(struct storvsc_device *stor_device, + struct vstor_packet *vstor_packet) +{ + /* + * Cache the currently active port and node ww names. + */ + if (vstor_packet->wwn_packet.primary_active) { + stor_device->node_name = + wwn_to_u64(vstor_packet->wwn_packet.primary_node_wwn); + stor_device->port_name = + wwn_to_u64(vstor_packet->wwn_packet.primary_port_wwn); + } else { + stor_device->node_name = + wwn_to_u64(vstor_packet->wwn_packet.secondary_node_wwn); + stor_device->port_name = + wwn_to_u64(vstor_packet->wwn_packet.secondary_port_wwn); + } +} + +static int storvsc_channel_init(struct hv_device *device, bool is_fc) { struct storvsc_device *stor_device; struct storvsc_cmd_request *request; @@ -727,19 +755,15 @@ static int storvsc_channel_init(struct hv_device *device) VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) - goto cleanup; + return ret; t = wait_for_completion_timeout(&request->wait_event, 5*HZ); - if (t == 0) { - ret = -ETIMEDOUT; - goto cleanup; - } + if (t == 0) + return -ETIMEDOUT; if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || - vstor_packet->status != 0) { - ret = -EINVAL; - goto cleanup; - } + vstor_packet->status != 0) + return -EINVAL; for (i = 0; i < ARRAY_SIZE(vmstor_protocols); i++) { @@ -764,18 +788,14 @@ static int storvsc_channel_init(struct hv_device *device) VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) - goto cleanup; + return ret; t = wait_for_completion_timeout(&request->wait_event, 5*HZ); - if (t == 0) { - ret = -ETIMEDOUT; - goto cleanup; - } + if (t == 0) + return -ETIMEDOUT; - if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO) { - ret = -EINVAL; - goto cleanup; - } + if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO) + return -EINVAL; if (vstor_packet->status == 0) { vmstor_proto_version = @@ -791,10 +811,8 @@ static int storvsc_channel_init(struct hv_device *device) } } - if (vstor_packet->status != 0) { - ret = -EINVAL; - goto cleanup; - } + if (vstor_packet->status != 0) + return -EINVAL; memset(vstor_packet, 0, sizeof(struct vstor_packet)); @@ -809,19 +827,15 @@ static int storvsc_channel_init(struct hv_device *device) VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) - goto cleanup; + return ret; t = wait_for_completion_timeout(&request->wait_event, 5*HZ); - if (t == 0) { - ret = -ETIMEDOUT; - goto cleanup; - } + if (t == 0) + return -ETIMEDOUT; if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || - vstor_packet->status != 0) { - ret = -EINVAL; - goto cleanup; - } + vstor_packet->status != 0) + return -EINVAL; /* * Check to see if multi-channel support is there. @@ -837,6 +851,38 @@ static int storvsc_channel_init(struct hv_device *device) stor_device->max_transfer_bytes = vstor_packet->storage_channel_properties.max_transfer_bytes; + if (!is_fc) + goto done; + + memset(vstor_packet, 0, sizeof(struct vstor_packet)); + vstor_packet->operation = VSTOR_OPERATION_FCHBA_DATA; + vstor_packet->flags = REQUEST_COMPLETION_FLAG; + + ret = vmbus_sendpacket(device->channel, vstor_packet, + (sizeof(struct vstor_packet) - + vmscsi_size_delta), + (unsigned long)request, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + + if (ret != 0) + return ret; + + t = wait_for_completion_timeout(&request->wait_event, 5*HZ); + if (t == 0) + return -ETIMEDOUT; + + if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || + vstor_packet->status != 0) + return -EINVAL; + + /* + * Cache the currently active port and node ww names. + */ + cache_wwn(stor_device, vstor_packet); + +done: + memset(vstor_packet, 0, sizeof(struct vstor_packet)); vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; @@ -849,25 +895,19 @@ static int storvsc_channel_init(struct hv_device *device) VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) - goto cleanup; + return ret; t = wait_for_completion_timeout(&request->wait_event, 5*HZ); - if (t == 0) { - ret = -ETIMEDOUT; - goto cleanup; - } + if (t == 0) + return -ETIMEDOUT; if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || - vstor_packet->status != 0) { - ret = -EINVAL; - goto cleanup; - } + vstor_packet->status != 0) + return -EINVAL; if (process_sub_channels) handle_multichannel_storage(device, max_chns); - -cleanup: return ret; } @@ -1076,6 +1116,14 @@ static void storvsc_on_receive(struct hv_device *device, schedule_work(&work->work); break; + case VSTOR_OPERATION_FCHBA_DATA: + stor_device = get_in_stor_device(device); + cache_wwn(stor_device, vstor_packet); +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + fc_host_node_name(stor_device->host) = stor_device->node_name; + fc_host_port_name(stor_device->host) = stor_device->port_name; +#endif + break; default: break; } @@ -1131,7 +1179,8 @@ static void storvsc_on_channel_callback(void *context) return; } -static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size) +static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size, + bool is_fc) { struct vmstorage_channel_properties props; int ret; @@ -1148,7 +1197,7 @@ static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size) if (ret != 0) return ret; - ret = storvsc_channel_init(device); + ret = storvsc_channel_init(device, is_fc); return ret; } @@ -1573,6 +1622,7 @@ static int storvsc_probe(struct hv_device *device, struct Scsi_Host *host; struct hv_host_device *host_dev; bool dev_is_ide = ((dev_id->driver_data == IDE_GUID) ? true : false); + bool is_fc = ((dev_id->driver_data == SFC_GUID) ? true : false); int target = 0; struct storvsc_device *stor_device; int max_luns_per_target; @@ -1630,7 +1680,7 @@ static int storvsc_probe(struct hv_device *device, hv_set_drvdata(device, stor_device); stor_device->port_number = host->host_no; - ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size); + ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size, is_fc); if (ret) goto err_out1; @@ -1642,6 +1692,9 @@ static int storvsc_probe(struct hv_device *device, host->max_lun = STORVSC_FC_MAX_LUNS_PER_TARGET; host->max_id = STORVSC_FC_MAX_TARGETS; host->max_channel = STORVSC_FC_MAX_CHANNELS - 1; +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + host->transportt = fc_transport_template; +#endif break; case SCSI_GUID: @@ -1681,6 +1734,12 @@ static int storvsc_probe(struct hv_device *device, goto err_out2; } } +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + if (host->transportt == fc_transport_template) { + fc_host_node_name(host) = stor_device->node_name; + fc_host_port_name(host) = stor_device->port_name; + } +#endif return 0; err_out2: @@ -1706,6 +1765,10 @@ static int storvsc_remove(struct hv_device *dev) struct storvsc_device *stor_device = hv_get_drvdata(dev); struct Scsi_Host *host = stor_device->host; +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + if (host->transportt == fc_transport_template) + fc_remove_host(host); +#endif scsi_remove_host(host); storvsc_dev_remove(dev); scsi_host_put(host); @@ -1720,8 +1783,16 @@ static struct hv_driver storvsc_drv = { .remove = storvsc_remove, }; +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) +static struct fc_function_template fc_transport_functions = { + .show_host_node_name = 1, + .show_host_port_name = 1, +}; +#endif + static int __init storvsc_drv_init(void) { + int ret; /* * Divide the ring buffer data size (which is 1 page less @@ -1736,12 +1807,28 @@ static int __init storvsc_drv_init(void) vmscsi_size_delta, sizeof(u64))); - return vmbus_driver_register(&storvsc_drv); +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + fc_transport_template = fc_attach_transport(&fc_transport_functions); + if (!fc_transport_template) + return -ENODEV; +#endif + + ret = vmbus_driver_register(&storvsc_drv); + +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + if (ret) + fc_release_transport(fc_transport_template); +#endif + + return ret; } static void __exit storvsc_drv_exit(void) { vmbus_driver_unregister(&storvsc_drv); +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + fc_release_transport(fc_transport_template); +#endif } MODULE_LICENSE("GPL"); -- GitLab From 59635018f9b7ae8b3e304d7a5da6f628b5a1dcf6 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Dec 2015 13:15:50 -0800 Subject: [PATCH 2285/2855] storvsc: Refactor the code in storvsc_channel_init() The function storvsc_channel_init() repeatedly interacts with the host to extract various channel properties. Refactor this code to eliminate code repetition. Signed-off-by: K. Y. Srinivasan Reviewed-by: Long Li Reviewed-by: Johannes Thumshirn Reviewed-by: Hannes Reinecke Tested-by: Alex Ng Signed-off-by: Martin K. Petersen --- drivers/scsi/storvsc_drv.c | 126 ++++++++++++++----------------------- 1 file changed, 46 insertions(+), 80 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index cfbb2890b31f2..811f276baed83 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -723,29 +723,17 @@ static void cache_wwn(struct storvsc_device *stor_device, } } -static int storvsc_channel_init(struct hv_device *device, bool is_fc) + +static int storvsc_execute_vstor_op(struct hv_device *device, + struct storvsc_cmd_request *request, + bool status_check) { - struct storvsc_device *stor_device; - struct storvsc_cmd_request *request; struct vstor_packet *vstor_packet; - int ret, t, i; - int max_chns; - bool process_sub_channels = false; - - stor_device = get_out_stor_device(device); - if (!stor_device) - return -ENODEV; + int ret, t; - request = &stor_device->init_request; vstor_packet = &request->vstor_packet; - /* - * Now, initiate the vsc/vsp initialization protocol on the open - * channel - */ - memset(request, 0, sizeof(struct storvsc_cmd_request)); init_completion(&request->wait_event); - vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; ret = vmbus_sendpacket(device->channel, vstor_packet, @@ -761,17 +749,50 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) if (t == 0) return -ETIMEDOUT; + if (!status_check) + return ret; + if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || vstor_packet->status != 0) return -EINVAL; + return ret; +} + +static int storvsc_channel_init(struct hv_device *device, bool is_fc) +{ + struct storvsc_device *stor_device; + struct storvsc_cmd_request *request; + struct vstor_packet *vstor_packet; + int ret, i; + int max_chns; + bool process_sub_channels = false; + + stor_device = get_out_stor_device(device); + if (!stor_device) + return -ENODEV; + + request = &stor_device->init_request; + vstor_packet = &request->vstor_packet; + + /* + * Now, initiate the vsc/vsp initialization protocol on the open + * channel + */ + memset(request, 0, sizeof(struct storvsc_cmd_request)); + vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; + ret = storvsc_execute_vstor_op(device, request, true); + if (ret) + return ret; + /* + * Query host supported protocol version. + */ for (i = 0; i < ARRAY_SIZE(vmstor_protocols); i++) { /* reuse the packet for version range supported */ memset(vstor_packet, 0, sizeof(struct vstor_packet)); vstor_packet->operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION; - vstor_packet->flags = REQUEST_COMPLETION_FLAG; vstor_packet->version.major_minor = vmstor_protocols[i].protocol_version; @@ -780,20 +801,10 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) * The revision number is only used in Windows; set it to 0. */ vstor_packet->version.revision = 0; - - ret = vmbus_sendpacket(device->channel, vstor_packet, - (sizeof(struct vstor_packet) - - vmscsi_size_delta), - (unsigned long)request, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + ret = storvsc_execute_vstor_op(device, request, false); if (ret != 0) return ret; - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); - if (t == 0) - return -ETIMEDOUT; - if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO) return -EINVAL; @@ -817,26 +828,10 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) memset(vstor_packet, 0, sizeof(struct vstor_packet)); vstor_packet->operation = VSTOR_OPERATION_QUERY_PROPERTIES; - vstor_packet->flags = REQUEST_COMPLETION_FLAG; - - ret = vmbus_sendpacket(device->channel, vstor_packet, - (sizeof(struct vstor_packet) - - vmscsi_size_delta), - (unsigned long)request, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - + ret = storvsc_execute_vstor_op(device, request, true); if (ret != 0) return ret; - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); - if (t == 0) - return -ETIMEDOUT; - - if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || - vstor_packet->status != 0) - return -EINVAL; - /* * Check to see if multi-channel support is there. * Hosts that implement protocol version of 5.1 and above @@ -854,28 +849,15 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) if (!is_fc) goto done; + /* + * For FC devices retrieve FC HBA data. + */ memset(vstor_packet, 0, sizeof(struct vstor_packet)); vstor_packet->operation = VSTOR_OPERATION_FCHBA_DATA; - vstor_packet->flags = REQUEST_COMPLETION_FLAG; - - ret = vmbus_sendpacket(device->channel, vstor_packet, - (sizeof(struct vstor_packet) - - vmscsi_size_delta), - (unsigned long)request, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - + ret = storvsc_execute_vstor_op(device, request, true); if (ret != 0) return ret; - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); - if (t == 0) - return -ETIMEDOUT; - - if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || - vstor_packet->status != 0) - return -EINVAL; - /* * Cache the currently active port and node ww names. */ @@ -885,26 +867,10 @@ done: memset(vstor_packet, 0, sizeof(struct vstor_packet)); vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION; - vstor_packet->flags = REQUEST_COMPLETION_FLAG; - - ret = vmbus_sendpacket(device->channel, vstor_packet, - (sizeof(struct vstor_packet) - - vmscsi_size_delta), - (unsigned long)request, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - + ret = storvsc_execute_vstor_op(device, request, true); if (ret != 0) return ret; - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); - if (t == 0) - return -ETIMEDOUT; - - if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || - vstor_packet->status != 0) - return -EINVAL; - if (process_sub_channels) handle_multichannel_storage(device, max_chns); -- GitLab From 03996f2064a5c5b7c1bd942794d622179acf2d61 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Dec 2015 13:15:51 -0800 Subject: [PATCH 2286/2855] storvsc: Tighten up the interrupt path On the interrupt path, we repeatedly establish the pointer to the storvsc_device. While the compiler does inline get_in_stor_device() (and other static functions) in the call chain in the interrupt path, the compiler is repeatedly inlining the call to get_in_stor_device() each time it is invoked. The return value of get_in_stor_device() can be cached in the interrupt path since there is higher level serialization in place to ensure correct handling when the module unload races with the processing of an incoming message from the host. Optimize this code path by caching the pointer to storvsc_device and passing it as an argument. Signed-off-by: K. Y. Srinivasan Reviewed-by: Long Li Reviewed-by: Johannes Thumshirn Reviewed-by: Hannes Reinecke Tested-by: Alex Ng Signed-off-by: Martin K. Petersen --- drivers/scsi/storvsc_drv.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 811f276baed83..41c115c230d9b 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -945,19 +945,16 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, } -static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request) +static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request, + struct storvsc_device *stor_dev) { struct scsi_cmnd *scmnd = cmd_request->cmd; - struct hv_host_device *host_dev = shost_priv(scmnd->device->host); struct scsi_sense_hdr sense_hdr; struct vmscsi_request *vm_srb; struct Scsi_Host *host; - struct storvsc_device *stor_dev; - struct hv_device *dev = host_dev->dev; u32 payload_sz = cmd_request->payload_sz; void *payload = cmd_request->payload; - stor_dev = get_in_stor_device(dev); host = stor_dev->host; vm_srb = &cmd_request->vstor_packet.vm_srb; @@ -987,14 +984,13 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request) kfree(payload); } -static void storvsc_on_io_completion(struct hv_device *device, +static void storvsc_on_io_completion(struct storvsc_device *stor_device, struct vstor_packet *vstor_packet, struct storvsc_cmd_request *request) { - struct storvsc_device *stor_device; struct vstor_packet *stor_pkt; + struct hv_device *device = stor_device->device; - stor_device = hv_get_drvdata(device); stor_pkt = &request->vstor_packet; /* @@ -1049,7 +1045,7 @@ static void storvsc_on_io_completion(struct hv_device *device, stor_pkt->vm_srb.data_transfer_length = vstor_packet->vm_srb.data_transfer_length; - storvsc_command_completion(request); + storvsc_command_completion(request, stor_device); if (atomic_dec_and_test(&stor_device->num_outstanding_req) && stor_device->drain_notify) @@ -1058,21 +1054,19 @@ static void storvsc_on_io_completion(struct hv_device *device, } -static void storvsc_on_receive(struct hv_device *device, +static void storvsc_on_receive(struct storvsc_device *stor_device, struct vstor_packet *vstor_packet, struct storvsc_cmd_request *request) { struct storvsc_scan_work *work; - struct storvsc_device *stor_device; switch (vstor_packet->operation) { case VSTOR_OPERATION_COMPLETE_IO: - storvsc_on_io_completion(device, vstor_packet, request); + storvsc_on_io_completion(stor_device, vstor_packet, request); break; case VSTOR_OPERATION_REMOVE_DEVICE: case VSTOR_OPERATION_ENUMERATE_BUS: - stor_device = get_in_stor_device(device); work = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC); if (!work) return; @@ -1083,7 +1077,6 @@ static void storvsc_on_receive(struct hv_device *device, break; case VSTOR_OPERATION_FCHBA_DATA: - stor_device = get_in_stor_device(device); cache_wwn(stor_device, vstor_packet); #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) fc_host_node_name(stor_device->host) = stor_device->node_name; @@ -1133,7 +1126,7 @@ static void storvsc_on_channel_callback(void *context) vmscsi_size_delta)); complete(&request->wait_event); } else { - storvsc_on_receive(device, + storvsc_on_receive(stor_device, (struct vstor_packet *)packet, request); } -- GitLab From f7a8e38f07a17be90758559fe66fe7337096053f Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 5 Jan 2016 10:39:45 -0800 Subject: [PATCH 2287/2855] mtd: nand: assign reasonable default name for NAND drivers Commits such as commit 853f1c58c4b2 ("mtd: nand: omap2: show parent device structure in sysfs") attempt to rely on the core MTD code to set the MTD name based on the parent device. However, nand_base tries to set a different default name according to the flash name (e.g., extracted from the ONFI parameter page), which means NAND drivers will never make use of the MTD defaults. This is not the intention of commit 853f1c58c4b2. This results in problems when trying to use the cmdline partition parser, since the MTD name is different than expected. Let's fix this by providing a default NAND name, where possible. Note that this is not really a great default name in the long run, since this means that if there are multiple MTDs attached to the same controller device, they will have the same name. But that is an existing issue and requires future work on a better controller vs. flash chip abstraction to fix properly. Fixes: 853f1c58c4b2 ("mtd: nand: omap2: show parent device structure in sysfs") Reported-by: Heiko Schocher Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon Tested-by: Heiko Schocher Cc: Heiko Schocher Cc: Frans Klaver Cc: --- drivers/mtd/nand/nand_base.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 928081bbdafd5..50514f2501bb7 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3996,6 +3996,9 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, if (ret) return ret; + if (!mtd->name && mtd->dev.parent) + mtd->name = dev_name(mtd->dev.parent); + /* Set the default functions */ nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); -- GitLab From 43584c1d42acf54464907773b0b8b7596d7b0a29 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Fri, 1 Jan 2016 22:06:27 +0800 Subject: [PATCH 2288/2855] jffs2: use to_delayed_work Use to_delayed_work() instead of open-coding it. Signed-off-by: Geliang Tang Signed-off-by: Brian Norris --- fs/jffs2/wbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index f3a4857ff0718..5a3da3f52908f 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c @@ -1153,7 +1153,7 @@ static struct jffs2_sb_info *work_to_sb(struct work_struct *work) { struct delayed_work *dwork; - dwork = container_of(work, struct delayed_work, work); + dwork = to_delayed_work(work); return container_of(dwork, struct jffs2_sb_info, wbuf_dwork); } -- GitLab From 6e75632ac34d2f63ab586880f7e9747bd9b708a6 Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Thu, 31 Dec 2015 16:21:22 +0100 Subject: [PATCH 2289/2855] mtd: tests: consolidate kmalloc/memset 0 call to kzalloc This is an API consolidation only. The use of kmalloc + memset to 0 is equivalent to kzalloc. Signed-off-by: Nicholas Mc Guire Signed-off-by: Brian Norris --- drivers/mtd/tests/pagetest.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mtd/tests/pagetest.c b/drivers/mtd/tests/pagetest.c index ba1890d5632ce..ff1e0565b0204 100644 --- a/drivers/mtd/tests/pagetest.c +++ b/drivers/mtd/tests/pagetest.c @@ -127,13 +127,12 @@ static int crosstest(void) unsigned char *pp1, *pp2, *pp3, *pp4; pr_info("crosstest\n"); - pp1 = kmalloc(pgsize * 4, GFP_KERNEL); + pp1 = kzalloc(pgsize * 4, GFP_KERNEL); if (!pp1) return -ENOMEM; pp2 = pp1 + pgsize; pp3 = pp2 + pgsize; pp4 = pp3 + pgsize; - memset(pp1, 0, pgsize * 4); addr0 = 0; for (i = 0; i < ebcnt && bbt[i]; ++i) -- GitLab From bb9ef71646606e51adfebdc94231fbbc862dbe28 Mon Sep 17 00:00:00 2001 From: Guoqing Jiang Date: Mon, 28 Dec 2015 10:46:38 +0800 Subject: [PATCH 2290/2855] md: remove unnecesary md_new_event_inintr md_new_event had removed sysfs_notify since 'commit 72a23c211e45 ("Make sure all changes to md/sync_action are notified.")', so we can use md_new_event and delete md_new_event_inintr. Signed-off-by: Guoqing Jiang Signed-off-by: NeilBrown --- drivers/md/md.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index c0c3e6dec2484..43a140457e0cc 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -205,15 +205,6 @@ void md_new_event(struct mddev *mddev) } EXPORT_SYMBOL_GPL(md_new_event); -/* Alternate version that can be called from interrupts - * when calling sysfs_notify isn't needed. - */ -static void md_new_event_inintr(struct mddev *mddev) -{ - atomic_inc(&md_event_count); - wake_up(&md_event_waiters); -} - /* * Enables to iterate over all existing md arrays * all_mddevs_lock protects this list. @@ -7209,7 +7200,7 @@ void md_error(struct mddev *mddev, struct md_rdev *rdev) md_wakeup_thread(mddev->thread); if (mddev->event_work.func) queue_work(md_misc_wq, &mddev->event_work); - md_new_event_inintr(mddev); + md_new_event(mddev); } EXPORT_SYMBOL(md_error); -- GitLab From 274d8cbde1bc3bdfb31c5d6a58113dff5cee4f87 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 4 Jan 2016 16:16:58 +1100 Subject: [PATCH 2291/2855] md: Remove 'ready' field from mddev. This field is always set in tandem with ->pers, and when it is tested ->pers is also tested. So ->ready is not needed. It was needed once, but code rearrangement and locking changes have removed that needed. Signed-off-by: NeilBrown --- drivers/md/md.c | 5 +---- drivers/md/md.h | 2 -- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 43a140457e0cc..0d1d822eeda51 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -250,8 +250,7 @@ static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio) blk_queue_split(q, &bio, q->bio_split); - if (mddev == NULL || mddev->pers == NULL - || !mddev->ready) { + if (mddev == NULL || mddev->pers == NULL) { bio_io_error(bio); return BLK_QC_T_NONE; } @@ -5298,7 +5297,6 @@ int md_run(struct mddev *mddev) smp_wmb(); spin_lock(&mddev->lock); mddev->pers = pers; - mddev->ready = 1; spin_unlock(&mddev->lock); rdev_for_each(rdev, mddev) if (rdev->raid_disk >= 0) @@ -5498,7 +5496,6 @@ static void __md_stop(struct mddev *mddev) /* Ensure ->event_work is done */ flush_workqueue(md_misc_wq); spin_lock(&mddev->lock); - mddev->ready = 0; mddev->pers = NULL; spin_unlock(&mddev->lock); pers->free(mddev, mddev->private); diff --git a/drivers/md/md.h b/drivers/md/md.h index e16a17c374183..fc6f7bbc95444 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -246,8 +246,6 @@ struct mddev { * are happening, so run/ * takeover/stop are not safe */ - int ready; /* See when safe to pass - * IO requests down */ struct gendisk *gendisk; struct kobject kobj; -- GitLab From dae928ec3c29e7e16723c9c4c1299e00f4e9e949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 6 Jan 2016 15:50:08 -0800 Subject: [PATCH 2292/2855] Input: ALPS - detect trackstick presence for v7 protocol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds detection of trackstick for v7 protocol devices. Code in this patch is used in official Dell touchpad linux drivers for Dell models: Dell Latitude E5250/5250, E5450/5450, E5550/5550 Detection code and base reg for alps v3 rushmore and v7 devices is exacly same. Also user in bug https://bugzilla.kernel.org/show_bug.cgi?id=94801 reported that Toshiba Sattellite Z30-A-1DG has only alps v7 touchpad device without trackstick and kernel reports to userspace also redundant trackstick device. Signed-off-by: Pali Rohár Reviewed-by: Hans de Goede Tested-by: Alex Hung Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 41e6cb501e6a1..1aa1709870280 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -31,6 +31,7 @@ #define ALPS_CMD_NIBBLE_10 0x01f2 #define ALPS_REG_BASE_RUSHMORE 0xc2c0 +#define ALPS_REG_BASE_V7 0xc2c0 #define ALPS_REG_BASE_PINNACLE 0x0000 static const struct alps_nibble_commands alps_v3_nibble_commands[] = { @@ -2047,7 +2048,7 @@ static int alps_absolute_mode_v3(struct psmouse *psmouse) return 0; } -static int alps_probe_trackstick_v3(struct psmouse *psmouse, int reg_base) +static int alps_probe_trackstick_v3_v7(struct psmouse *psmouse, int reg_base) { int ret = -EIO, reg_val; @@ -2132,7 +2133,7 @@ static int alps_hw_init_v3(struct psmouse *psmouse) int reg_val; unsigned char param[4]; - reg_val = alps_probe_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE); + reg_val = alps_probe_trackstick_v3_v7(psmouse, ALPS_REG_BASE_PINNACLE); if (reg_val == -EIO) goto error; @@ -2625,8 +2626,8 @@ static int alps_set_protocol(struct psmouse *psmouse, priv->x_bits = 16; priv->y_bits = 12; - if (alps_probe_trackstick_v3(psmouse, - ALPS_REG_BASE_RUSHMORE) < 0) + if (alps_probe_trackstick_v3_v7(psmouse, + ALPS_REG_BASE_RUSHMORE) < 0) priv->flags &= ~ALPS_DUALPOINT; break; @@ -2676,6 +2677,9 @@ static int alps_set_protocol(struct psmouse *psmouse, if (priv->fw_ver[1] != 0xba) priv->flags |= ALPS_BUTTONPAD; + if (alps_probe_trackstick_v3_v7(psmouse, ALPS_REG_BASE_V7) < 0) + priv->flags &= ~ALPS_DUALPOINT; + break; case ALPS_PROTO_V8: -- GitLab From 4b1af853646ca893fa686701d1605998fffcc82c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 6 Jan 2016 15:58:56 -0800 Subject: [PATCH 2293/2855] Input: ALPS - report v3 pinnacle trackstick device only if is present MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch moves v3 pinnacle code for trackstick detection from alps_hw_init_v3() to alps_set_protocol() so ALPS_DUALPOINT flag can be cleared before registering trackstick input device in kernel. Signed-off-by: Pali Rohár Acked-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 1aa1709870280..936f07a4e35f4 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -2129,15 +2129,12 @@ error: static int alps_hw_init_v3(struct psmouse *psmouse) { + struct alps_data *priv = psmouse->private; struct ps2dev *ps2dev = &psmouse->ps2dev; int reg_val; unsigned char param[4]; - reg_val = alps_probe_trackstick_v3_v7(psmouse, ALPS_REG_BASE_PINNACLE); - if (reg_val == -EIO) - goto error; - - if (reg_val == 0 && + if ((priv->flags & ALPS_DUALPOINT) && alps_setup_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE) == -EIO) goto error; @@ -2614,6 +2611,11 @@ static int alps_set_protocol(struct psmouse *psmouse, priv->decode_fields = alps_decode_pinnacle; priv->nibble_commands = alps_v3_nibble_commands; priv->addr_command = PSMOUSE_CMD_RESET_WRAP; + + if (alps_probe_trackstick_v3_v7(psmouse, + ALPS_REG_BASE_PINNACLE) < 0) + priv->flags &= ~ALPS_DUALPOINT; + break; case ALPS_PROTO_V3_RUSHMORE: -- GitLab From 32321e950d8a237d7e8f3a9b76220007dfa87544 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ezequiel=20Garc=C3=ADa?= Date: Mon, 28 Dec 2015 17:54:51 -0300 Subject: [PATCH 2294/2855] mtd: spi-nor: wait until lock/unlock operations are ready On Micron and Numonyx devices, the status register write command (WRSR), raises a work-in-progress bit (WIP) on the status register. The datasheets for these devices specify that while the status register write is in progress, the status register WIP bit can still be read to check the end of the operation. This commit adds a wait_till_ready call on lock/unlock operations, which is required for Micron and Numonyx but should be harmless for others. This is needed to prevent applications from issuing erase or program operations before the unlock operation is completed. Reported-by: Stas Sergeev Signed-off-by: Ezequiel Garcia Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/spi-nor.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index f8f36d47575f1..ed0c19c558b5e 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -481,6 +481,7 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) int status_old, status_new; u8 mask = SR_BP2 | SR_BP1 | SR_BP0; u8 shift = ffs(mask) - 1, pow, val; + int ret; status_old = read_sr(nor); if (status_old < 0) @@ -519,7 +520,10 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) return -EINVAL; write_enable(nor); - return write_sr(nor, status_new); + ret = write_sr(nor, status_new); + if (ret) + return ret; + return spi_nor_wait_till_ready(nor); } /* @@ -533,6 +537,7 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) int status_old, status_new; u8 mask = SR_BP2 | SR_BP1 | SR_BP0; u8 shift = ffs(mask) - 1, pow, val; + int ret; status_old = read_sr(nor); if (status_old < 0) @@ -569,7 +574,10 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) return -EINVAL; write_enable(nor); - return write_sr(nor, status_new); + ret = write_sr(nor, status_new); + if (ret) + return ret; + return spi_nor_wait_till_ready(nor); } /* -- GitLab From 33853ebd746f0e6aa262745376fde5d4995e0a87 Mon Sep 17 00:00:00 2001 From: Insu Yun Date: Tue, 29 Dec 2015 13:45:09 -0500 Subject: [PATCH 2295/2855] mtd: cfi_cmdset_0001: fixing memory leak and handling failed kmalloc kmalloc needs to be handled when failing in memory pressure. Also, it has memory leak in error routine. Signed-off-by: Insu Yun Signed-off-by: Brian Norris --- drivers/mtd/chips/cfi_cmdset_0001.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 286b97a304cfc..5e1b68cbcd0ac 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -596,7 +596,7 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd) mtd->size = devsize * cfi->numchips; mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; - mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) + mtd->eraseregions = kzalloc(sizeof(struct mtd_erase_region_info) * mtd->numeraseregions, GFP_KERNEL); if (!mtd->eraseregions) goto setup_err; @@ -614,6 +614,8 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd) mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize; mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum; mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].lockmap = kmalloc(ernum / 8 + 1, GFP_KERNEL); + if (!mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].lockmap) + goto setup_err; } offset += (ersize * ernum); } @@ -650,6 +652,10 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd) return mtd; setup_err: + if (mtd->eraseregions) + for (i=0; icfiq->NumEraseRegions; i++) + for (j=0; jnumchips; j++) + kfree(mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].lockmap); kfree(mtd->eraseregions); kfree(mtd); kfree(cfi->cmdset_priv); -- GitLab From 6f357de854a6dfb9ce0d5d65f3971cf3d0a4af6f Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Mon, 4 Jan 2016 12:34:42 +0000 Subject: [PATCH 2296/2855] doc: dt: mtd: new binding for jz4780-{nand,bch} Add DT bindings for NAND devices connected to the NEMC on JZ4780 SoCs, as well as the hardware BCH controller, used by the jz4780_{nand,bch} drivers. Signed-off-by: Alex Smith Cc: Zubair Lutfullah Kakakhel Cc: David Woodhouse Cc: linux-mtd@lists.infradead.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Harvey Hunt Acked-by: Rob Herring Reviewed-by: Boris Brezillon Signed-off-by: Brian Norris --- .../bindings/mtd/ingenic,jz4780-nand.txt | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 Documentation/devicetree/bindings/mtd/ingenic,jz4780-nand.txt diff --git a/Documentation/devicetree/bindings/mtd/ingenic,jz4780-nand.txt b/Documentation/devicetree/bindings/mtd/ingenic,jz4780-nand.txt new file mode 100644 index 0000000000000..29ea5853ca914 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/ingenic,jz4780-nand.txt @@ -0,0 +1,86 @@ +* Ingenic JZ4780 NAND/BCH + +This file documents the device tree bindings for NAND flash devices on the +JZ4780. NAND devices are connected to the NEMC controller (described in +memory-controllers/ingenic,jz4780-nemc.txt), and thus NAND device nodes must +be children of the NEMC node. + +Required NAND controller device properties: +- compatible: Should be set to "ingenic,jz4780-nand". +- reg: For each bank with a NAND chip attached, should specify a bank number, + an offset of 0 and a size of 0x1000000 (i.e. the whole NEMC bank). + +Optional NAND controller device properties: +- ingenic,bch-controller: To make use of the hardware BCH controller, this + property must contain a phandle for the BCH controller node. The required + properties for this node are described below. If this is not specified, + software BCH will be used instead. + +Optional children nodes: +- Individual NAND chips are children of the NAND controller node. + +Required children node properties: +- reg: An integer ranging from 1 to 6 representing the CS line to use. + +Optional children node properties: +- nand-ecc-step-size: ECC block size in bytes. +- nand-ecc-strength: ECC strength (max number of correctable bits). +- nand-ecc-mode: String, operation mode of the NAND ecc mode. "hw" by default +- nand-on-flash-bbt: boolean to enable on flash bbt option, if not present false +- rb-gpios: GPIO specifier for the busy pin. +- wp-gpios: GPIO specifier for the write protect pin. + +Optional child node of NAND chip nodes: +- partitions: see Documentation/devicetree/bindings/mtd/partition.txt + +Example: + +nemc: nemc@13410000 { + ... + + nandc: nand-controller@1 { + compatible = "ingenic,jz4780-nand"; + reg = <1 0 0x1000000>; /* Bank 1 */ + + #address-cells = <1>; + #size-cells = <0>; + + ingenic,bch-controller = <&bch>; + + nand@1 { + reg = <1>; + + nand-ecc-step-size = <1024>; + nand-ecc-strength = <24>; + nand-ecc-mode = "hw"; + nand-on-flash-bbt; + + rb-gpios = <&gpa 20 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpf 22 GPIO_ACTIVE_LOW>; + + partitions { + #address-cells = <2>; + #size-cells = <2>; + ... + } + }; + }; +}; + +The BCH controller is a separate SoC component used for error correction on +NAND devices. The following is a description of the device properties for a +BCH controller. + +Required BCH properties: +- compatible: Should be set to "ingenic,jz4780-bch". +- reg: Should specify the BCH controller registers location and length. +- clocks: Clock for the BCH controller. + +Example: + +bch: bch@134d0000 { + compatible = "ingenic,jz4780-bch"; + reg = <0x134d0000 0x10000>; + + clocks = <&cgu JZ4780_CLK_BCH>; +}; -- GitLab From a9be294ecb3b9dc82b15625631b153f871181d16 Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Mon, 14 Dec 2015 14:55:09 -0600 Subject: [PATCH 2297/2855] cxlflash: Fix to escalate LINK_RESET also on port 1 The original fix to escalate a 'login timed out' error to a LINK_RESET was only made for one of the two ports on the card. This fix resolves the same issue for the second port (port 1). Signed-off-by: Manoj N. Kumar Acked-by: Matthew R. Ochs Reviewed-by: Uma Krishnan Signed-off-by: Martin K. Petersen --- drivers/scsi/cxlflash/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 1e5bf0ca81da1..09fe252ac19b4 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -1108,7 +1108,7 @@ static const struct asyc_intr_info ainfo[] = { {SISL_ASTATUS_FC1_OTHER, "other error", 1, CLR_FC_ERROR | LINK_RESET}, {SISL_ASTATUS_FC1_LOGO, "target initiated LOGO", 1, 0}, {SISL_ASTATUS_FC1_CRC_T, "CRC threshold exceeded", 1, LINK_RESET}, - {SISL_ASTATUS_FC1_LOGI_R, "login timed out, retrying", 1, 0}, + {SISL_ASTATUS_FC1_LOGI_R, "login timed out, retrying", 1, LINK_RESET}, {SISL_ASTATUS_FC1_LOGI_F, "login failed", 1, CLR_FC_ERROR}, {SISL_ASTATUS_FC1_LOGI_S, "login succeeded", 1, SCAN_HOST}, {SISL_ASTATUS_FC1_LINK_DN, "link down", 1, 0}, -- GitLab From d5e26bb1d812ba74f29b6bcbc88c3dbfb3eed824 Mon Sep 17 00:00:00 2001 From: "Matthew R. Ochs" Date: Mon, 14 Dec 2015 14:55:44 -0600 Subject: [PATCH 2298/2855] cxlflash: Fix to avoid virtual LUN failover failure Applications which use virtual LUN's that are backed by a physical LUN over both adapter ports may experience an I/O failure in the event of a link loss (e.g. cable pull). Virtual LUNs may be accessed through one or both ports of the adapter. This access is encoded in the translation entries that comprise the virtual LUN and used by the AFU for load-balancing I/O and handling failover scenarios. In a link loss scenario, even though the AFU is able to maintain connectivity to the LUN, it is up to the application to retry the failed I/O. When applications are unaware of the virtual LUN's underlying topology, they are unable to make a sound decision of when to retry an I/O and therefore are forced to make their reaction to a failed I/O absolute. The result is either a failure to retry I/O or increased latency for scenarios where a retry is pointless. To remedy this scenario, provide feedback back to the application on virtual LUN creation as to which ports the LUN may be accessed. LUN's spanning both ports are candidates for a retry in a presence of an I/O failure. Signed-off-by: Matthew R. Ochs Acked-by: Manoj Kumar Reviewed-by: Uma Krishnan Signed-off-by: Martin K. Petersen --- drivers/scsi/cxlflash/vlun.c | 2 ++ include/uapi/scsi/cxlflash_ioctl.h | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/drivers/scsi/cxlflash/vlun.c b/drivers/scsi/cxlflash/vlun.c index a53f583e2d7b1..50f8e93007704 100644 --- a/drivers/scsi/cxlflash/vlun.c +++ b/drivers/scsi/cxlflash/vlun.c @@ -1008,6 +1008,8 @@ int cxlflash_disk_virtual_open(struct scsi_device *sdev, void *arg) virt->last_lba = last_lba; virt->rsrc_handle = rsrc_handle; + if (lli->port_sel == BOTH_PORTS) + virt->hdr.return_flags |= DK_CXLFLASH_ALL_PORTS_ACTIVE; out: if (likely(ctxi)) put_context(ctxi); diff --git a/include/uapi/scsi/cxlflash_ioctl.h b/include/uapi/scsi/cxlflash_ioctl.h index 831351b2e6602..2302f3ce5f860 100644 --- a/include/uapi/scsi/cxlflash_ioctl.h +++ b/include/uapi/scsi/cxlflash_ioctl.h @@ -30,6 +30,16 @@ struct dk_cxlflash_hdr { __u64 return_flags; /* Returned flags */ }; +/* + * Return flag definitions available to all ioctls + * + * Similar to the input flags, these are grown from the bottom-up with the + * intention that ioctl-specific return flag definitions would grow from the + * top-down, allowing the two sets to co-exist. While not required/enforced + * at this time, this provides future flexibility. + */ +#define DK_CXLFLASH_ALL_PORTS_ACTIVE 0x0000000000000001ULL + /* * Notes: * ----- -- GitLab From 85599218914dadad3347eaa4337e71f09f39e78f Mon Sep 17 00:00:00 2001 From: Uma Krishnan Date: Mon, 14 Dec 2015 15:06:33 -0600 Subject: [PATCH 2299/2855] cxlflash: Removed driver date print Having a date for the driver requires it to be updated quite often. Removing the date which is not necessary. Also made use of the existing symbol to print the driver name. Signed-off-by: Uma Krishnan Reviewed-by: Andrew Donnellan Acked-by: Matthew R. Ochs Signed-off-by: Martin K. Petersen --- drivers/scsi/cxlflash/main.c | 3 +-- drivers/scsi/cxlflash/main.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 09fe252ac19b4..35a32024f1c0d 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -2585,8 +2585,7 @@ static struct pci_driver cxlflash_driver = { */ static int __init init_cxlflash(void) { - pr_info("%s: IBM Power CXL Flash Adapter: %s\n", - __func__, CXLFLASH_DRIVER_DATE); + pr_info("%s: %s\n", __func__, CXLFLASH_ADAPTER_NAME); cxlflash_list_init(); diff --git a/drivers/scsi/cxlflash/main.h b/drivers/scsi/cxlflash/main.h index 60324566c14f4..7e2d0e1bb82d1 100644 --- a/drivers/scsi/cxlflash/main.h +++ b/drivers/scsi/cxlflash/main.h @@ -22,7 +22,6 @@ #define CXLFLASH_NAME "cxlflash" #define CXLFLASH_ADAPTER_NAME "IBM POWER CXL Flash Adapter" -#define CXLFLASH_DRIVER_DATE "(August 13, 2015)" #define PCI_DEVICE_ID_IBM_CORSA 0x04F0 #define CXLFLASH_SUBS_DEV_ID 0x04F0 -- GitLab From ee91e332a6e6e9b939f60f6e1bd72fb2def5290d Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Mon, 14 Dec 2015 15:07:02 -0600 Subject: [PATCH 2300/2855] cxlflash: Fix to resolve cmd leak after host reset After a few iterations of resetting the card, either during EEH recovery, or a host_reset the following is seen in the logs. cxlflash 0008:00: cxlflash_queuecommand: could not get a free command At every reset of the card, the commands that are outstanding are being leaked. No effort is being made to reap these commands. A few more resets later, the above error message floods the logs and the card is rendered totally unusable as no free commands are available. Iterated through the 'cmd' queue and printed out the 'free' counter and found that on each reset certain commands were in-use and stayed in-use through subsequent resets. To resolve this issue, when the card is reset, reap all the commands that are active/outstanding. Signed-off-by: Manoj N. Kumar Acked-by: Matthew R. Ochs Reviewed-by: Andrew Donnellan Signed-off-by: Martin K. Petersen --- drivers/scsi/cxlflash/main.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 35a32024f1c0d..ac39856a74b49 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -632,15 +632,30 @@ static void free_mem(struct cxlflash_cfg *cfg) * @cfg: Internal structure associated with the host. * * Safe to call with AFU in a partially allocated/initialized state. + * + * Cleans up all state associated with the command queue, and unmaps + * the MMIO space. + * + * - complete() will take care of commands we initiated (they'll be checked + * in as part of the cleanup that occurs after the completion) + * + * - cmd_checkin() will take care of entries that we did not initiate and that + * have not (and will not) complete because they are sitting on a [now stale] + * hardware queue */ static void stop_afu(struct cxlflash_cfg *cfg) { int i; struct afu *afu = cfg->afu; + struct afu_cmd *cmd; if (likely(afu)) { - for (i = 0; i < CXLFLASH_NUM_CMDS; i++) - complete(&afu->cmd[i].cevent); + for (i = 0; i < CXLFLASH_NUM_CMDS; i++) { + cmd = &afu->cmd[i]; + complete(&cmd->cevent); + if (!atomic_read(&cmd->free)) + cmd_checkin(cmd); + } if (likely(afu->afu_map)) { cxl_psa_unmap((void __iomem *)afu->afu_map); -- GitLab From b45cdbaf9f7f0486847c52f60747fb108724652a Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Mon, 14 Dec 2015 15:07:23 -0600 Subject: [PATCH 2301/2855] cxlflash: Resolve oops in wait_port_offline If an async error interrupt is generated, and the error requires the FC link to be reset, it cannot be performed in the interrupt context. So a work element is scheduled to complete the link reset in a process context. If either an EEH event or an escalation occurs in between when the interrupt is generated and the scheduled work is started, the MMIO space may no longer be available. This will cause an oops in the worker thread. [ 606.806583] NIP kthread_data+0x28/0x40 [ 606.806633] LR wq_worker_sleeping+0x30/0x100 [ 606.806694] Call Trace: [ 606.806721] 0x50 (unreliable) [ 606.806796] wq_worker_sleeping+0x30/0x100 [ 606.806884] __schedule+0x69c/0x8a0 [ 606.806959] schedule+0x44/0xc0 [ 606.807034] do_exit+0x770/0xb90 [ 606.807109] die+0x300/0x460 [ 606.807185] bad_page_fault+0xd8/0x150 [ 606.807259] handle_page_fault+0x2c/0x30 [ 606.807338] wait_port_offline.constprop.12+0x60/0x130 [cxlflash] To prevent the problem space area from being unmapped, when there is pending work, a mapcount (using the kref mechanism) is held. The mapcount is released only when the work is completed. The last reference release is tied to the unmapping service. Signed-off-by: Manoj N. Kumar Acked-by: Matthew R. Ochs Reviewed-by: Uma Krishnan Signed-off-by: Martin K. Petersen --- drivers/scsi/cxlflash/common.h | 2 ++ drivers/scsi/cxlflash/main.c | 27 ++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/cxlflash/common.h b/drivers/scsi/cxlflash/common.h index c11cd193f8964..5ada9268a450d 100644 --- a/drivers/scsi/cxlflash/common.h +++ b/drivers/scsi/cxlflash/common.h @@ -165,6 +165,8 @@ struct afu { struct sisl_host_map __iomem *host_map; /* MC host map */ struct sisl_ctrl_map __iomem *ctrl_map; /* MC control map */ + struct kref mapcount; + ctx_hndl_t ctx_hndl; /* master's context handle */ u64 *hrrq_start; u64 *hrrq_end; diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index ac39856a74b49..30542ca9415b0 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -368,6 +368,7 @@ out: no_room: afu->read_room = true; + kref_get(&cfg->afu->mapcount); schedule_work(&cfg->work_q); rc = SCSI_MLQUEUE_HOST_BUSY; goto out; @@ -473,6 +474,16 @@ out: return rc; } +static void afu_unmap(struct kref *ref) +{ + struct afu *afu = container_of(ref, struct afu, mapcount); + + if (likely(afu->afu_map)) { + cxl_psa_unmap((void __iomem *)afu->afu_map); + afu->afu_map = NULL; + } +} + /** * cxlflash_driver_info() - information handler for this host driver * @host: SCSI host associated with device. @@ -503,6 +514,7 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp) ulong lock_flags; short lflag = 0; int rc = 0; + int kref_got = 0; dev_dbg_ratelimited(dev, "%s: (scp=%p) %d/%d/%d/%llu " "cdb=(%08X-%08X-%08X-%08X)\n", @@ -547,6 +559,9 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp) goto out; } + kref_get(&cfg->afu->mapcount); + kref_got = 1; + cmd->rcb.ctx_id = afu->ctx_hndl; cmd->rcb.port_sel = port_sel; cmd->rcb.lun_id = lun_to_lunid(scp->device->lun); @@ -587,6 +602,8 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp) } out: + if (kref_got) + kref_put(&afu->mapcount, afu_unmap); pr_devel("%s: returning rc=%d\n", __func__, rc); return rc; } @@ -661,6 +678,7 @@ static void stop_afu(struct cxlflash_cfg *cfg) cxl_psa_unmap((void __iomem *)afu->afu_map); afu->afu_map = NULL; } + kref_put(&afu->mapcount, afu_unmap); } } @@ -746,8 +764,8 @@ static void cxlflash_remove(struct pci_dev *pdev) scsi_remove_host(cfg->host); /* fall through */ case INIT_STATE_AFU: - term_afu(cfg); cancel_work_sync(&cfg->work_q); + term_afu(cfg); case INIT_STATE_PCI: pci_release_regions(cfg->dev); pci_disable_device(pdev); @@ -1331,6 +1349,7 @@ static irqreturn_t cxlflash_async_err_irq(int irq, void *data) __func__, port); cfg->lr_state = LINK_RESET_REQUIRED; cfg->lr_port = port; + kref_get(&cfg->afu->mapcount); schedule_work(&cfg->work_q); } @@ -1351,6 +1370,7 @@ static irqreturn_t cxlflash_async_err_irq(int irq, void *data) if (info->action & SCAN_HOST) { atomic_inc(&cfg->scan_host_needed); + kref_get(&cfg->afu->mapcount); schedule_work(&cfg->work_q); } } @@ -1746,6 +1766,7 @@ static int init_afu(struct cxlflash_cfg *cfg) rc = -ENOMEM; goto err1; } + kref_init(&afu->mapcount); /* No byte reverse on reading afu_version or string will be backwards */ reg = readq(&afu->afu_map->global.regs.afu_version); @@ -1780,8 +1801,7 @@ out: return rc; err2: - cxl_psa_unmap((void __iomem *)afu->afu_map); - afu->afu_map = NULL; + kref_put(&afu->mapcount, afu_unmap); err1: term_mc(cfg, UNDO_START); goto out; @@ -2354,6 +2374,7 @@ static void cxlflash_worker_thread(struct work_struct *work) if (atomic_dec_if_positive(&cfg->scan_host_needed) >= 0) scsi_scan_host(cfg->host); + kref_put(&afu->mapcount, afu_unmap); } /** -- GitLab From a2746fb16e41b7c8f02aa4d2605ecce97abbebbd Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Mon, 14 Dec 2015 15:07:43 -0600 Subject: [PATCH 2302/2855] cxlflash: Enable device id for future IBM CXL adapter This drop enables a future card with a device id of 0x0600 to be recognized by the cxlflash driver. As per the design, the Accelerator Function Unit (AFU) for this new IBM CXL Flash Adapter retains the same host interface as the previous generation. For the early prototypes of the new card, the driver with this change behaves exactly as the driver prior to this behaved with the earlier generation card. Therefore, no card specific programming has been added. These card specific changes can be staged in later if needed. Signed-off-by: Manoj N. Kumar Acked-by: Matthew R. Ochs Reviewed-by: Andrew Donnellan Signed-off-by: Martin K. Petersen --- drivers/scsi/cxlflash/main.c | 3 +++ drivers/scsi/cxlflash/main.h | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 30542ca9415b0..f6d90ce8f3b7e 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -2309,6 +2309,7 @@ static struct scsi_host_template driver_template = { * Device dependent values */ static struct dev_dependent_vals dev_corsa_vals = { CXLFLASH_MAX_SECTORS }; +static struct dev_dependent_vals dev_flash_gt_vals = { CXLFLASH_MAX_SECTORS }; /* * PCI device binding table @@ -2316,6 +2317,8 @@ static struct dev_dependent_vals dev_corsa_vals = { CXLFLASH_MAX_SECTORS }; static struct pci_device_id cxlflash_pci_table[] = { {PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CORSA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t)&dev_corsa_vals}, + {PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_FLASH_GT, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t)&dev_flash_gt_vals}, {} }; diff --git a/drivers/scsi/cxlflash/main.h b/drivers/scsi/cxlflash/main.h index 7e2d0e1bb82d1..0faed422c7f47 100644 --- a/drivers/scsi/cxlflash/main.h +++ b/drivers/scsi/cxlflash/main.h @@ -23,8 +23,8 @@ #define CXLFLASH_NAME "cxlflash" #define CXLFLASH_ADAPTER_NAME "IBM POWER CXL Flash Adapter" -#define PCI_DEVICE_ID_IBM_CORSA 0x04F0 -#define CXLFLASH_SUBS_DEV_ID 0x04F0 +#define PCI_DEVICE_ID_IBM_CORSA 0x04F0 +#define PCI_DEVICE_ID_IBM_FLASH_GT 0x0600 /* Since there is only one target, make it 0 */ #define CXLFLASH_TARGET 0 -- GitLab From 6e9411923b8f4c0e568cbae0f35b7ee4eb989914 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Wed, 30 Dec 2015 20:32:03 +0100 Subject: [PATCH 2303/2855] mtd: nand: return consistent error codes in ecc.correct() implementations The error code returned by the ecc.correct() are not consistent over the all implementations. Document the expected behavior in include/linux/mtd/nand.h and fix offending implementations. [Brian: this looks like a bugfix for the ECC reporting in the bf5xx_nand driver, but we haven't seen any testing results for it] Signed-off-by: Boris Brezillon Tested-by: Franklin S Cooper Jr. Signed-off-by: Brian Norris --- drivers/mtd/nand/atmel_nand.c | 2 +- drivers/mtd/nand/bf5xx_nand.c | 20 ++++++++++++++------ drivers/mtd/nand/davinci_nand.c | 6 +++--- drivers/mtd/nand/jz4740_nand.c | 4 ++-- drivers/mtd/nand/mxc_nand.c | 4 ++-- drivers/mtd/nand/nand_bch.c | 2 +- drivers/mtd/nand/nand_ecc.c | 2 +- drivers/mtd/nand/omap2.c | 6 +++--- drivers/mtd/nand/r852.c | 4 ++-- include/linux/mtd/nand.h | 8 +++++++- include/linux/mtd/nand_bch.h | 2 +- 11 files changed, 37 insertions(+), 23 deletions(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 18c4e14ec29f6..b216bf5213493 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -1445,7 +1445,7 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, * We can't correct so many errors */ dev_dbg(host->dev, "atmel_nand : multiple errors detected." " Unable to correct.\n"); - return -EIO; + return -EBADMSG; } /* if there's a single bit error : we can correct it */ diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index 9514e136542ff..89d9414c5593b 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c @@ -252,7 +252,7 @@ static int bf5xx_nand_correct_data_256(struct mtd_info *mtd, u_char *dat, */ if (hweight32(syndrome[0]) == 1) { dev_err(info->device, "ECC data was incorrect!\n"); - return 1; + return -EBADMSG; } syndrome[1] = (calced & 0x7FF) ^ (stored & 0x7FF); @@ -285,7 +285,7 @@ static int bf5xx_nand_correct_data_256(struct mtd_info *mtd, u_char *dat, data = data ^ (0x1 << failing_bit); *(dat + failing_byte) = data; - return 0; + return 1; } /* @@ -298,26 +298,34 @@ static int bf5xx_nand_correct_data_256(struct mtd_info *mtd, u_char *dat, dev_err(info->device, "Please discard data, mark bad block\n"); - return 1; + return -EBADMSG; } static int bf5xx_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) { struct nand_chip *chip = mtd_to_nand(mtd); - int ret; + int ret, bitflips = 0; ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc); + if (ret < 0) + return ret; + + bitflips = ret; /* If ecc size is 512, correct second 256 bytes */ if (chip->ecc.size == 512) { dat += 256; read_ecc += 3; calc_ecc += 3; - ret |= bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc); + ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc); + if (ret < 0) + return ret; + + bitflips += ret; } - return ret; + return bitflips; } static void bf5xx_nand_enable_hwecc(struct mtd_info *mtd, int mode) diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 3b49fe86625d2..ddb73c3319364 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -207,7 +207,7 @@ static int nand_davinci_correct_1bit(struct mtd_info *mtd, u_char *dat, dat[diff >> (12 + 3)] ^= BIT((diff >> 12) & 7); return 1; } else { - return -1; + return -EBADMSG; } } else if (!(diff & (diff - 1))) { /* Single bit ECC error in the ECC itself, @@ -215,7 +215,7 @@ static int nand_davinci_correct_1bit(struct mtd_info *mtd, u_char *dat, return 1; } else { /* Uncorrectable error */ - return -1; + return -EBADMSG; } } @@ -391,7 +391,7 @@ compare: return 0; case 1: /* five or more errors detected */ davinci_nand_readl(info, NAND_ERR_ERRVAL1_OFFSET); - return -EIO; + return -EBADMSG; case 2: /* error addresses computed */ case 3: num_errors = 1 + ((fsr >> 16) & 0x03); diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index a2363d33cecc5..adccae3da1207 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c @@ -254,7 +254,7 @@ static int jz_nand_correct_ecc_rs(struct mtd_info *mtd, uint8_t *dat, } while (!(status & JZ_NAND_STATUS_DEC_FINISH) && --timeout); if (timeout == 0) - return -1; + return -ETIMEDOUT; reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL); reg &= ~JZ_NAND_ECC_CTRL_ENABLE; @@ -262,7 +262,7 @@ static int jz_nand_correct_ecc_rs(struct mtd_info *mtd, uint8_t *dat, if (status & JZ_NAND_STATUS_ERROR) { if (status & JZ_NAND_STATUS_UNCOR_ERROR) - return -1; + return -EBADMSG; error_count = (status & JZ_NAND_STATUS_ERR_COUNT) >> 29; diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 95400992c3e9e..66e56bb22c0fb 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -674,7 +674,7 @@ static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat, if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) { pr_debug("MXC_NAND: HWECC uncorrectable 2-bit ECC error\n"); - return -1; + return -EBADMSG; } return 0; @@ -701,7 +701,7 @@ static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat, err = ecc_stat & ecc_bit_mask; if (err > err_limit) { printk(KERN_WARNING "UnCorrectable RS-ECC Error\n"); - return -1; + return -EBADMSG; } else { ret += err; } diff --git a/drivers/mtd/nand/nand_bch.c b/drivers/mtd/nand/nand_bch.c index e5758d885943e..a87c1b628dfc5 100644 --- a/drivers/mtd/nand/nand_bch.c +++ b/drivers/mtd/nand/nand_bch.c @@ -98,7 +98,7 @@ int nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf, } } else if (count < 0) { printk(KERN_ERR "ecc unrecoverable error\n"); - count = -1; + count = -EBADMSG; } return count; } diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c index e6129851bfd89..d1770b0663967 100644 --- a/drivers/mtd/nand/nand_ecc.c +++ b/drivers/mtd/nand/nand_ecc.c @@ -507,7 +507,7 @@ int __nand_correct_data(unsigned char *buf, return 1; /* error in ECC data; no action needed */ pr_err("%s: uncorrectable ECC error\n", __func__); - return -1; + return -EBADMSG; } EXPORT_SYMBOL(__nand_correct_data); diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index e9cbbc63c566f..c553f78ab83f9 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -826,12 +826,12 @@ static int omap_compare_ecc(u8 *ecc_data1, /* read from NAND memory */ case 1: /* Uncorrectable error */ pr_debug("ECC UNCORRECTED_ERROR 1\n"); - return -1; + return -EBADMSG; case 11: /* UN-Correctable error */ pr_debug("ECC UNCORRECTED_ERROR B\n"); - return -1; + return -EBADMSG; case 12: /* Correctable error */ @@ -861,7 +861,7 @@ static int omap_compare_ecc(u8 *ecc_data1, /* read from NAND memory */ return 0; } pr_debug("UNCORRECTED_ERROR default\n"); - return -1; + return -EBADMSG; } } diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index cb0bf09214d5c..5b15f2faee38d 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c @@ -477,7 +477,7 @@ static int r852_ecc_correct(struct mtd_info *mtd, uint8_t *dat, if (dev->dma_error) { dev->dma_error = 0; - return -1; + return -EIO; } r852_write_reg(dev, R852_CTL, dev->ctlreg | R852_CTL_ECC_ACCESS); @@ -491,7 +491,7 @@ static int r852_ecc_correct(struct mtd_info *mtd, uint8_t *dat, /* ecc uncorrectable error */ if (ecc_status & R852_ECC_FAIL) { dbg("ecc: unrecoverable error, in half %d", i); - error = -1; + error = -EBADMSG; goto exit; } diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 3e92be1d2d439..5189581151826 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -456,7 +456,13 @@ struct nand_hw_control { * @hwctl: function to control hardware ECC generator. Must only * be provided if an hardware ECC is available * @calculate: function for ECC calculation or readback from ECC hardware - * @correct: function for ECC correction, matching to ECC generator (sw/hw) + * @correct: function for ECC correction, matching to ECC generator (sw/hw). + * Should return a positive number representing the number of + * corrected bitflips, -EBADMSG if the number of bitflips exceed + * ECC strength, or any other error code if the error is not + * directly related to correction. + * If -EBADMSG is returned the input buffers should be left + * untouched. * @read_page_raw: function to read a raw page without ECC. This function * should hide the specific layout used by the ECC * controller and always return contiguous in-band and diff --git a/include/linux/mtd/nand_bch.h b/include/linux/mtd/nand_bch.h index 74acf5367556e..fb0bc3420a10c 100644 --- a/include/linux/mtd/nand_bch.h +++ b/include/linux/mtd/nand_bch.h @@ -55,7 +55,7 @@ static inline int nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf, unsigned char *read_ecc, unsigned char *calc_ecc) { - return -1; + return -ENOTSUPP; } static inline struct nand_bch_control * -- GitLab From 40cbe6eee97b706f27bcc4c6aa1018bbe4f1e577 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Wed, 30 Dec 2015 20:32:04 +0100 Subject: [PATCH 2304/2855] mtd: nand: use nand_check_erased_ecc_chunk in default ECC read functions The default NAND read functions are relying on the underlying controller driver to correct bitflips, but some of those controllers cannot properly fix bitflips in erased pages. Check for bitflips in erased pages in default core functions if the driver delegated the this check by setting the NAND_ECC_GENERIC_ERASED_CHECK flag. Signed-off-by: Boris Brezillon Tested-by: Franklin S Cooper Jr. Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_base.c | 53 +++++++++++++++++++++++++++++++----- include/linux/mtd/nand.h | 10 +++++++ 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 50514f2501bb7..f2c8ff398d6cb 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -1426,6 +1426,16 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, stat = chip->ecc.correct(mtd, p, &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]); + if (stat == -EBADMSG && + (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { + /* check for empty pages with bitflips */ + stat = nand_check_erased_ecc_chunk(p, chip->ecc.size, + &chip->buffers->ecccode[i], + chip->ecc.bytes, + NULL, 0, + chip->ecc.strength); + } + if (stat < 0) { mtd->ecc_stats.failed++; } else { @@ -1475,6 +1485,15 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, int stat; stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); + if (stat == -EBADMSG && + (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { + /* check for empty pages with bitflips */ + stat = nand_check_erased_ecc_chunk(p, eccsize, + &ecc_code[i], eccbytes, + NULL, 0, + chip->ecc.strength); + } + if (stat < 0) { mtd->ecc_stats.failed++; } else { @@ -1527,6 +1546,15 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd, chip->ecc.calculate(mtd, p, &ecc_calc[i]); stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL); + if (stat == -EBADMSG && + (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { + /* check for empty pages with bitflips */ + stat = nand_check_erased_ecc_chunk(p, eccsize, + &ecc_code[i], eccbytes, + NULL, 0, + chip->ecc.strength); + } + if (stat < 0) { mtd->ecc_stats.failed++; } else { @@ -1554,6 +1582,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, int i, eccsize = chip->ecc.size; int eccbytes = chip->ecc.bytes; int eccsteps = chip->ecc.steps; + int eccpadbytes = eccbytes + chip->ecc.prepad + chip->ecc.postpad; uint8_t *p = buf; uint8_t *oob = chip->oob_poi; unsigned int max_bitflips = 0; @@ -1573,19 +1602,29 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, chip->read_buf(mtd, oob, eccbytes); stat = chip->ecc.correct(mtd, p, oob, NULL); - if (stat < 0) { - mtd->ecc_stats.failed++; - } else { - mtd->ecc_stats.corrected += stat; - max_bitflips = max_t(unsigned int, max_bitflips, stat); - } - oob += eccbytes; if (chip->ecc.postpad) { chip->read_buf(mtd, oob, chip->ecc.postpad); oob += chip->ecc.postpad; } + + if (stat == -EBADMSG && + (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { + /* check for empty pages with bitflips */ + stat = nand_check_erased_ecc_chunk(p, chip->ecc.size, + oob - eccpadbytes, + eccpadbytes, + NULL, 0, + chip->ecc.strength); + } + + if (stat < 0) { + mtd->ecc_stats.failed++; + } else { + mtd->ecc_stats.corrected += stat; + max_bitflips = max_t(unsigned int, max_bitflips, stat); + } } /* Calculate remaining oob bytes */ diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 5189581151826..86487dbe73584 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -129,6 +129,14 @@ typedef enum { /* Enable Hardware ECC before syndrome is read back from flash */ #define NAND_ECC_READSYN 2 +/* + * Enable generic NAND 'page erased' check. This check is only done when + * ecc.correct() returns -EBADMSG. + * Set this flag if your implementation does not fix bitflips in erased + * pages and you want to rely on the default implementation. + */ +#define NAND_ECC_GENERIC_ERASED_CHECK BIT(0) + /* Bit mask for flags passed to do_nand_read_ecc */ #define NAND_GET_DEVICE 0x80 @@ -451,6 +459,7 @@ struct nand_hw_control { * @total: total number of ECC bytes per page * @prepad: padding information for syndrome based ECC generators * @postpad: padding information for syndrome based ECC generators + * @options: ECC specific options (see NAND_ECC_XXX flags defined above) * @layout: ECC layout control struct pointer * @priv: pointer to private ECC control data * @hwctl: function to control hardware ECC generator. Must only @@ -500,6 +509,7 @@ struct nand_ecc_ctrl { int strength; int prepad; int postpad; + unsigned int options; struct nand_ecclayout *layout; void *priv; void (*hwctl)(struct mtd_info *mtd, int mode); -- GitLab From bc29c95d2e51305ec611f29cc703c2fa0d2086de Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Wed, 30 Dec 2015 20:32:05 +0100 Subject: [PATCH 2305/2855] mtd: nand: davinci: remove custom 'erased check' implementation The davinci driver is manually checking for 'erased pages' while correcting ECC bytes. This logic can now done by the core infrastructure, and can thus be removed from this driver. Signed-off-by: Boris Brezillon Tested-by: Franklin S Cooper Jr. Signed-off-by: Brian Norris --- drivers/mtd/nand/davinci_nand.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index ddb73c3319364..8cb821b6686ef 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -317,14 +317,6 @@ static int nand_davinci_correct_4bit(struct mtd_info *mtd, unsigned num_errors, corrected; unsigned long timeo; - /* All bytes 0xff? It's an erased page; ignore its ECC. */ - for (i = 0; i < 10; i++) { - if (ecc_code[i] != 0xff) - goto compare; - } - return 0; - -compare: /* Unpack ten bytes into eight 10 bit values. We know we're * little-endian, and use type punning for less shifting/masking. */ @@ -749,6 +741,7 @@ static int nand_davinci_probe(struct platform_device *pdev) info->chip.ecc.correct = nand_davinci_correct_4bit; info->chip.ecc.hwctl = nand_davinci_hwctl_4bit; info->chip.ecc.bytes = 10; + info->chip.ecc.options = NAND_ECC_GENERIC_ERASED_CHECK; } else { info->chip.ecc.calculate = nand_davinci_calculate_1bit; info->chip.ecc.correct = nand_davinci_correct_1bit; -- GitLab From cc01e6075c7f5fee72746bb0ec763b84a46c3778 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Wed, 30 Dec 2015 20:39:52 +0100 Subject: [PATCH 2306/2855] mtd: nand: diskonchip: remove custom 'erased check' implementation The diskonchip driver is manually checking for 'erased pages' while correcting ECC bytes. This logic can now done by the core infrastructure, and can thus be removed from this driver. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/diskonchip.c | 38 +++-------------------------------- 1 file changed, 3 insertions(+), 35 deletions(-) diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index a5c046654233c..4f4aa3555a6fa 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -74,10 +74,6 @@ struct doc_priv { int (*late_init)(struct mtd_info *mtd); }; -/* This is the syndrome computed by the HW ecc generator upon reading an empty - page, one with all 0xff for data and stored ecc code. */ -static u_char empty_read_syndrome[6] = { 0x26, 0xff, 0x6d, 0x47, 0x73, 0x7a }; - /* This is the ecc value computed by the HW ecc generator upon writing an empty page, one with all 0xff for data. */ static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 }; @@ -912,7 +908,6 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, void __iomem *docptr = doc->virtadr; uint8_t calc_ecc[6]; volatile u_char dummy; - int emptymatch = 1; /* flush the pipeline */ if (DoC_is_2000(doc)) { @@ -936,37 +931,9 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, calc_ecc[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i); else calc_ecc[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i); - if (calc_ecc[i] != empty_read_syndrome[i]) - emptymatch = 0; - } - /* If emptymatch=1, the read syndrome is consistent with an - all-0xff data and stored ecc block. Check the stored ecc. */ - if (emptymatch) { - for (i = 0; i < 6; i++) { - if (read_ecc[i] == 0xff) - continue; - emptymatch = 0; - break; - } } - /* If emptymatch still =1, check the data block. */ - if (emptymatch) { - /* Note: this somewhat expensive test should not be triggered - often. It could be optimized away by examining the data in - the readbuf routine, and remembering the result. */ - for (i = 0; i < 512; i++) { - if (dat[i] == 0xff) - continue; - emptymatch = 0; - break; - } - } - /* If emptymatch still =1, this is almost certainly a freshly- - erased block, in which case the ECC will not come out right. - We'll suppress the error and tell the caller everything's - OK. Because it is. */ - if (!emptymatch) - ret = doc_ecc_decode(rs_decoder, dat, calc_ecc); + + ret = doc_ecc_decode(rs_decoder, dat, calc_ecc); if (ret > 0) printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret); } @@ -1586,6 +1553,7 @@ static int __init doc_probe(unsigned long physadr) nand->ecc.size = 512; nand->ecc.bytes = 6; nand->ecc.strength = 2; + nand->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK; nand->bbt_options = NAND_BBT_USE_FLASH; /* Skip the automatic BBT scan so we can run it manually */ nand->options |= NAND_SKIP_BBTSCAN; -- GitLab From 48bf35de3133996fbac2be16430cd4ea00fa8d38 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Wed, 30 Dec 2015 20:41:29 +0100 Subject: [PATCH 2307/2855] mtd: nand: jz4740: remove custom 'erased check' implementation The jz4740 driver is manually checking for 'erased pages' while correcting ECC bytes. This logic can now done by the core infrastructure, and can thus be removed from this driver. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/jz4740_nand.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index adccae3da1207..b19d2a9a5eb97 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c @@ -224,24 +224,6 @@ static int jz_nand_correct_ecc_rs(struct mtd_info *mtd, uint8_t *dat, uint32_t t; unsigned int timeout = 1000; - t = read_ecc[0]; - - if (t == 0xff) { - for (i = 1; i < 9; ++i) - t &= read_ecc[i]; - - t &= dat[0]; - t &= dat[nand->chip.ecc.size / 2]; - t &= dat[nand->chip.ecc.size - 1]; - - if (t == 0xff) { - for (i = 1; i < nand->chip.ecc.size - 1; ++i) - t &= dat[i]; - if (t == 0xff) - return 0; - } - } - for (i = 0; i < 9; ++i) writeb(read_ecc[i], nand->base + JZ_REG_NAND_PAR0 + i); @@ -443,6 +425,7 @@ static int jz_nand_probe(struct platform_device *pdev) chip->ecc.size = 512; chip->ecc.bytes = 9; chip->ecc.strength = 4; + chip->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK; if (pdata) chip->ecc.layout = pdata->ecc_layout; -- GitLab From a51311938e14c17f5a94d30baac9d7bec71f5858 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Sat, 2 Jan 2016 09:19:41 -0800 Subject: [PATCH 2308/2855] f2fs: cover more area with nat_tree_lock There was a subtle bug on nat cache management which incurs wrong nid allocation or wrong block addresses when try_to_free_nats is triggered heavily. This patch enlarges the previous coverage of nat_tree_lock to avoid data race. Signed-off-by: Jaegeuk Kim --- fs/f2fs/node.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 669c44ef93034..4dab09f141b79 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -262,13 +262,11 @@ static void cache_nat_entry(struct f2fs_nm_info *nm_i, nid_t nid, { struct nat_entry *e; - down_write(&nm_i->nat_tree_lock); e = __lookup_nat_cache(nm_i, nid); if (!e) { e = grab_nat_entry(nm_i, nid); node_info_from_raw_nat(&e->ni, ne); } - up_write(&nm_i->nat_tree_lock); } static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni, @@ -380,6 +378,8 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni) memset(&ne, 0, sizeof(struct f2fs_nat_entry)); + down_write(&nm_i->nat_tree_lock); + /* Check current segment summary */ mutex_lock(&curseg->curseg_mutex); i = lookup_journal_in_cursum(sum, NAT_JOURNAL, nid, 0); @@ -400,6 +400,7 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni) cache: /* cache nat entry */ cache_nat_entry(NM_I(sbi), nid, &ne); + up_write(&nm_i->nat_tree_lock); } /* @@ -1459,13 +1460,10 @@ static int add_free_nid(struct f2fs_sb_info *sbi, nid_t nid, bool build) if (build) { /* do not add allocated nids */ - down_read(&nm_i->nat_tree_lock); ne = __lookup_nat_cache(nm_i, nid); - if (ne && - (!get_nat_flag(ne, IS_CHECKPOINTED) || + if (ne && (!get_nat_flag(ne, IS_CHECKPOINTED) || nat_get_blkaddr(ne) != NULL_ADDR)) allocated = true; - up_read(&nm_i->nat_tree_lock); if (allocated) return 0; } @@ -1551,6 +1549,8 @@ static void build_free_nids(struct f2fs_sb_info *sbi) ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), FREE_NID_PAGES, META_NAT, true); + down_read(&nm_i->nat_tree_lock); + while (1) { struct page *page = get_current_nat_page(sbi, nid); @@ -1579,6 +1579,7 @@ static void build_free_nids(struct f2fs_sb_info *sbi) remove_free_nid(nm_i, nid); } mutex_unlock(&curseg->curseg_mutex); + up_read(&nm_i->nat_tree_lock); ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nm_i->next_scan_nid), nm_i->ra_nid_pages, META_NAT, false); @@ -1861,14 +1862,12 @@ static void remove_nats_in_journal(struct f2fs_sb_info *sbi) raw_ne = nat_in_journal(sum, i); - down_write(&nm_i->nat_tree_lock); ne = __lookup_nat_cache(nm_i, nid); if (!ne) { ne = grab_nat_entry(nm_i, nid); node_info_from_raw_nat(&ne->ni, &raw_ne); } __set_nat_cache_dirty(nm_i, ne); - up_write(&nm_i->nat_tree_lock); } update_nats_in_cursum(sum, -i); mutex_unlock(&curseg->curseg_mutex); @@ -1902,7 +1901,6 @@ static void __flush_nat_entry_set(struct f2fs_sb_info *sbi, struct f2fs_nat_block *nat_blk; struct nat_entry *ne, *cur; struct page *page = NULL; - struct f2fs_nm_info *nm_i = NM_I(sbi); /* * there are two steps to flush nat entries: @@ -1939,12 +1937,8 @@ static void __flush_nat_entry_set(struct f2fs_sb_info *sbi, raw_ne = &nat_blk->entries[nid - start_nid]; } raw_nat_from_node_info(raw_ne, &ne->ni); - - down_write(&NM_I(sbi)->nat_tree_lock); nat_reset_flag(ne); __clear_nat_cache_dirty(NM_I(sbi), ne); - up_write(&NM_I(sbi)->nat_tree_lock); - if (nat_get_blkaddr(ne) == NULL_ADDR) add_free_nid(sbi, nid, false); } @@ -1956,9 +1950,7 @@ static void __flush_nat_entry_set(struct f2fs_sb_info *sbi, f2fs_bug_on(sbi, set->entry_cnt); - down_write(&nm_i->nat_tree_lock); radix_tree_delete(&NM_I(sbi)->nat_set_root, set->set); - up_write(&nm_i->nat_tree_lock); kmem_cache_free(nat_entry_set_slab, set); } @@ -1978,6 +1970,9 @@ void flush_nat_entries(struct f2fs_sb_info *sbi) if (!nm_i->dirty_nat_cnt) return; + + down_write(&nm_i->nat_tree_lock); + /* * if there are no enough space in journal to store dirty nat * entries, remove all entries from journal and merge them @@ -1986,7 +1981,6 @@ void flush_nat_entries(struct f2fs_sb_info *sbi) if (!__has_cursum_space(sum, nm_i->dirty_nat_cnt, NAT_JOURNAL)) remove_nats_in_journal(sbi); - down_write(&nm_i->nat_tree_lock); while ((found = __gang_lookup_nat_set(nm_i, set_idx, SETVEC_SIZE, setvec))) { unsigned idx; @@ -1995,12 +1989,13 @@ void flush_nat_entries(struct f2fs_sb_info *sbi) __adjust_nat_entry_set(setvec[idx], &sets, MAX_NAT_JENTRIES(sum)); } - up_write(&nm_i->nat_tree_lock); /* flush dirty nats in nat entry set */ list_for_each_entry_safe(set, tmp, &sets, set_list) __flush_nat_entry_set(sbi, set); + up_write(&nm_i->nat_tree_lock); + f2fs_bug_on(sbi, nm_i->dirty_nat_cnt); } -- GitLab From 957efb0c2144cc5ff1795f43bf2d2ca430eaa227 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Sat, 2 Jan 2016 09:23:27 -0800 Subject: [PATCH 2309/2855] Revert "f2fs: check the node block address of newly allocated nid" Original issue is fixed by: f2fs: cover more area with nat_tree_lock This reverts commit 24928634f81b1592e83b37dcd89ed45c28f12feb. --- fs/f2fs/node.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 4dab09f141b79..6d5f548d20909 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1602,8 +1602,6 @@ retry: /* We should not use stale free nids created by build_free_nids */ if (nm_i->fcnt && !on_build_free_nids(nm_i)) { - struct node_info ni; - f2fs_bug_on(sbi, list_empty(&nm_i->free_nid_list)); list_for_each_entry(i, &nm_i->free_nid_list, list) if (i->state == NID_NEW) @@ -1614,13 +1612,6 @@ retry: i->state = NID_ALLOC; nm_i->fcnt--; spin_unlock(&nm_i->free_nid_list_lock); - - /* check nid is allocated already */ - get_node_info(sbi, *nid, &ni); - if (ni.blk_addr != NULL_ADDR) { - alloc_nid_done(sbi, *nid); - goto retry; - } return true; } spin_unlock(&nm_i->free_nid_list_lock); -- GitLab From de1475cc53b2d6442443dcf5d66ed0fc50ed3c7e Mon Sep 17 00:00:00 2001 From: Fan Li Date: Mon, 4 Jan 2016 15:56:50 +0800 Subject: [PATCH 2310/2855] f2fs: read isize while holding i_mutex in fiemap make sure the isize we read doesn't change during the process. Signed-off-by: Fan li Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 89a978c57da92..ac5bea0f5f09a 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -784,7 +784,7 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, { struct buffer_head map_bh; sector_t start_blk, last_blk; - loff_t isize = i_size_read(inode); + loff_t isize; u64 logical = 0, phys = 0, size = 0; u32 flags = 0; int ret = 0; @@ -800,6 +800,8 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, } mutex_lock(&inode->i_mutex); + + isize = i_size_read(inode); if (start >= isize) goto out; -- GitLab From cdf091ca2c3d6875e5f0fca28de4a6ca2f5273e6 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 4 Jan 2016 15:37:41 -0600 Subject: [PATCH 2311/2855] tty: amba-pl011: fix earlycon register offsets The REG_x macros are indices into a table, not register offsets. Since earlycon does not have access to the vendor data, we can currently only support standard ARM PL011 devices. Signed-off-by: Russell King Tested-by: Huang Shijie Signed-off-by: Timur Tabi Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 3b24aea343de1..a7d7ab05dc649 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -2301,10 +2301,10 @@ static struct console amba_console = { static void pl011_putc(struct uart_port *port, int c) { - while (readl(port->membase + REG_FR) & UART01x_FR_TXFF) + while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF) ; - writeb(c, port->membase + REG_DR); - while (readl(port->membase + REG_FR) & UART01x_FR_BUSY) + writeb(c, port->membase + UART01x_DR); + while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY) ; } -- GitLab From 3b78fae793c027140cfe635ef216bf60aa6498f4 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Mon, 4 Jan 2016 15:37:42 -0600 Subject: [PATCH 2312/2855] tty: amba-pl011: use iotype instead of access_32b to track 32-bit I/O Instead of defining a new field in the uart_amba_port structure, use the existing iotype field of the uart_port structure, which is intended for this purpose. If we need to use 32-bit register access, we set iotype to UPIO_MEM32, otherwise we set it to UPIO_MEM. For early console, specify the "mmio32" option on the kernel command-line. Example: earlycon=pl011,mmio32,0x3ced1000 Signed-off-by: Timur Tabi Signed-off-by: Greg Kroah-Hartman --- Documentation/kernel-parameters.txt | 5 ++++- drivers/tty/serial/amba-pl011.c | 16 +++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 054e11d33b6b0..654c547b9fc99 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1003,10 +1003,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted. unspecified, the h/w is not initialized. pl011, + pl011,mmio32, Start an early, polled-mode console on a pl011 serial port at the specified address. The pl011 serial port must already be setup and configured. Options are not - yet supported. + yet supported. If 'mmio32' is specified, then only + the driver will use only 32-bit accessors to read/write + the device registers. msm_serial, Start an early, polled-mode console on an msm serial diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index a7d7ab05dc649..c0da0ccbbcf54 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -238,7 +238,6 @@ struct uart_amba_port { unsigned int fifosize; /* vendor-specific */ unsigned int old_cr; /* state during shutdown */ bool autorts; - bool access_32b; unsigned int fixed_baud; /* vendor-set fixed baud rate */ char type[12]; #ifdef CONFIG_DMA_ENGINE @@ -262,7 +261,8 @@ static unsigned int pl011_read(const struct uart_amba_port *uap, { void __iomem *addr = uap->port.membase + pl011_reg_to_offset(uap, reg); - return uap->access_32b ? readl_relaxed(addr) : readw_relaxed(addr); + return (uap->port.iotype == UPIO_MEM32) ? + readl_relaxed(addr) : readw_relaxed(addr); } static void pl011_write(unsigned int val, const struct uart_amba_port *uap, @@ -270,7 +270,7 @@ static void pl011_write(unsigned int val, const struct uart_amba_port *uap, { void __iomem *addr = uap->port.membase + pl011_reg_to_offset(uap, reg); - if (uap->access_32b) + if (uap->port.iotype == UPIO_MEM32) writel_relaxed(val, addr); else writew_relaxed(val, addr); @@ -2303,7 +2303,10 @@ static void pl011_putc(struct uart_port *port, int c) { while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF) ; - writeb(c, port->membase + UART01x_DR); + if (port->iotype == UPIO_MEM32) + writel(c, port->membase + UART01x_DR); + else + writeb(c, port->membase + UART01x_DR); while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY) ; } @@ -2416,7 +2419,6 @@ static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap, uap->port.dev = dev; uap->port.mapbase = mmiobase->start; uap->port.membase = base; - uap->port.iotype = UPIO_MEM; uap->port.fifosize = uap->fifosize; uap->port.flags = UPF_BOOT_AUTOCONF; uap->port.line = index; @@ -2470,9 +2472,9 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) return PTR_ERR(uap->clk); uap->reg_offset = vendor->reg_offset; - uap->access_32b = vendor->access_32b; uap->vendor = vendor; uap->fifosize = vendor->get_fifosize(dev); + uap->port.iotype = vendor->access_32b ? UPIO_MEM32 : UPIO_MEM; uap->port.irq = dev->irq[0]; uap->port.ops = &amba_pl011_pops; @@ -2551,9 +2553,9 @@ static int sbsa_uart_probe(struct platform_device *pdev) return -ENOMEM; uap->reg_offset = vendor_sbsa.reg_offset; - uap->access_32b = vendor_sbsa.access_32b; uap->vendor = &vendor_sbsa; uap->fifosize = 32; + uap->port.iotype = vendor_sbsa.access_32b ? UPIO_MEM32 : UPIO_MEM; uap->port.irq = platform_get_irq(pdev, 0); uap->port.ops = &sbsa_uart_pops; uap->fixed_baud = baudrate; -- GitLab From 6bf6ded3008a407ccab5ad72eb59ab71b97cc290 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 21 Sep 2015 15:33:43 +0200 Subject: [PATCH 2313/2855] HSI: omap_ssi: fix handling ida_simple_get result The function can return negative value. The problem has been detected using proposed semantic patch scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci [1]. [1]: http://permalink.gmane.org/gmane.linux.kernel/2038576 Signed-off-by: Andrzej Hajda Signed-off-by: Sebastian Reichel --- drivers/hsi/controllers/omap_ssi.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/hsi/controllers/omap_ssi.c b/drivers/hsi/controllers/omap_ssi.c index f6d3100b7a328..27b91f14ba7a6 100644 --- a/drivers/hsi/controllers/omap_ssi.c +++ b/drivers/hsi/controllers/omap_ssi.c @@ -323,11 +323,10 @@ static int __init ssi_add_controller(struct hsi_controller *ssi, return -ENOMEM; } - ssi->id = ida_simple_get(&platform_omap_ssi_ida, 0, 0, GFP_KERNEL); - if (ssi->id < 0) { - err = ssi->id; + err = ida_simple_get(&platform_omap_ssi_ida, 0, 0, GFP_KERNEL); + if (err < 0) goto out_err; - } + ssi->id = err; ssi->owner = THIS_MODULE; ssi->device.parent = &pd->dev; -- GitLab From 525e1abc6b5a7d8bd9006de1da6e99722305ea2b Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 21 Sep 2015 15:33:44 +0200 Subject: [PATCH 2314/2855] HSI: omap_ssi_port: fix handling of_get_named_gpio result The function can return negative value. The problem has been detected using proposed semantic patch scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci [1]. [1]: http://permalink.gmane.org/gmane.linux.kernel/2038576 Signed-off-by: Andrzej Hajda Signed-off-by: Sebastian Reichel --- drivers/hsi/controllers/omap_ssi_port.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/hsi/controllers/omap_ssi_port.c b/drivers/hsi/controllers/omap_ssi_port.c index 02e66032ae736..e80a66e209986 100644 --- a/drivers/hsi/controllers/omap_ssi_port.c +++ b/drivers/hsi/controllers/omap_ssi_port.c @@ -1147,13 +1147,13 @@ static int __init ssi_port_probe(struct platform_device *pd) goto error; } - cawake_gpio = of_get_named_gpio(np, "ti,ssi-cawake-gpio", 0); - if (cawake_gpio < 0) { + err = of_get_named_gpio(np, "ti,ssi-cawake-gpio", 0); + if (err < 0) { dev_err(&pd->dev, "DT data is missing cawake gpio (err=%d)\n", - cawake_gpio); - err = -ENODEV; + err); goto error; } + cawake_gpio = err; err = devm_gpio_request_one(&port->device, cawake_gpio, GPIOF_DIR_IN, "cawake"); -- GitLab From 3daa020f9bf803c03c6b6c895921e2b09fcd494a Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Wed, 23 Dec 2015 15:08:08 -0500 Subject: [PATCH 2315/2855] Revert "svcrdma: Do not send XDR roundup bytes for a write chunk" This reverts commit 6f18dc893981e4daab29221d6a9771f3ce2dd8c5. Just as one example, it appears this code could do the wrong thing in the case of a two-byte NFS READ that crosses a page boundary. Chuck says: "In that case, nfsd would pass down an xdr_buf that has one byte in a page, one byte in another page, and a two-byte XDR pad. The logic introduced by this optimization would be fooled, and neither the second byte nor the XDR pad would be written to the client." Cc: Chuck Lever Signed-off-by: J. Bruce Fields --- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index bad5eaa9f812b..969a1ab75fc3c 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -342,13 +342,6 @@ static int send_write_chunks(struct svcxprt_rdma *xprt, arg_ch->rs_handle, arg_ch->rs_offset, write_len); - - /* Do not send XDR pad bytes */ - if (chunk_no && write_len < 4) { - chunk_no++; - break; - } - chunk_off = 0; while (write_len) { ret = send_write(xprt, rqstp, -- GitLab From 2e55f3ab45a0ef2e41548eae64e13b4bf39e5374 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Fri, 1 Jan 2016 22:06:28 +0800 Subject: [PATCH 2316/2855] nfsd: use to_delayed_work Use to_delayed_work() instead of open-coding it. Signed-off-by: Geliang Tang Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4state.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 113ecbfac25ce..086a81ce34fcf 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -4571,8 +4571,7 @@ static void laundromat_main(struct work_struct *laundry) { time_t t; - struct delayed_work *dwork = container_of(laundry, struct delayed_work, - work); + struct delayed_work *dwork = to_delayed_work(laundry); struct nfsd_net *nn = container_of(dwork, struct nfsd_net, laundromat_work); -- GitLab From ea44463f376236a0541288cb8d575ab6b50370d2 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Fri, 1 Jan 2016 22:06:29 +0800 Subject: [PATCH 2317/2855] lockd: use to_delayed_work Use to_delayed_work() instead of open-coding it. Signed-off-by: Geliang Tang Signed-off-by: J. Bruce Fields --- fs/lockd/svc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 44d18ad4d364c..b4006c720f553 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -94,8 +94,7 @@ static unsigned long get_lockd_grace_period(void) static void grace_ender(struct work_struct *grace) { - struct delayed_work *dwork = container_of(grace, struct delayed_work, - work); + struct delayed_work *dwork = to_delayed_work(grace); struct lockd_net *ln = container_of(dwork, struct lockd_net, grace_period_end); -- GitLab From 2a297450dd188a5d4e5e428c189b2de54f9073ba Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 23 Dec 2015 22:25:13 +0100 Subject: [PATCH 2318/2855] lockd: constify nlmsvc_binding structure The nlmsvc_binding structure is never modified, so declare it as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: J. Bruce Fields --- fs/lockd/svc.c | 2 +- fs/nfsd/lockd.c | 2 +- include/linux/lockd/bind.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index b4006c720f553..154a107cd3762 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -48,7 +48,7 @@ static struct svc_program nlmsvc_program; -struct nlmsvc_binding * nlmsvc_ops; +const struct nlmsvc_binding *nlmsvc_ops; EXPORT_SYMBOL_GPL(nlmsvc_ops); static DEFINE_MUTEX(nlmsvc_mutex); diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c index 77e7a5cca8884..1a03bc3059e84 100644 --- a/fs/nfsd/lockd.c +++ b/fs/nfsd/lockd.c @@ -58,7 +58,7 @@ nlm_fclose(struct file *filp) fput(filp); } -static struct nlmsvc_binding nfsd_nlm_ops = { +static const struct nlmsvc_binding nfsd_nlm_ops = { .fopen = nlm_fopen, /* open file for locking */ .fclose = nlm_fclose, /* close file */ }; diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h index 4d24d64578c4c..140edab644462 100644 --- a/include/linux/lockd/bind.h +++ b/include/linux/lockd/bind.h @@ -29,7 +29,7 @@ struct nlmsvc_binding { void (*fclose)(struct file *); }; -extern struct nlmsvc_binding * nlmsvc_ops; +extern const struct nlmsvc_binding *nlmsvc_ops; /* * Similar to nfs_client_initdata, but without the NFS-specific -- GitLab From 691412b4438da1b77ff3078de0546023d244d841 Mon Sep 17 00:00:00 2001 From: Kinglong Mee Date: Mon, 4 Jan 2016 11:15:21 +0800 Subject: [PATCH 2319/2855] nfsd: Fix nfsd leaks sunrpc module references Stefan Hajnoczi reports, nfsd leaks 3 references to the sunrpc module here: # echo -n "asdf 1234" >/proc/fs/nfsd/portlist bash: echo: write error: Protocol not supported Now stop nfsd and try unloading the kernel modules: # systemctl stop nfs-server # systemctl stop nfs # systemctl stop proc-fs-nfsd.mount # systemctl stop var-lib-nfs-rpc_pipefs.mount # rmmod nfsd # rmmod nfs_acl # rmmod lockd # rmmod auth_rpcgss # rmmod sunrpc rmmod: ERROR: Module sunrpc is in use # lsmod | grep rpc sunrpc 315392 3 It is caused by nfsd don't cleanup rpcb program for nfsd when destroying svc service after creating xprt fail. Reported-by: Stefan Hajnoczi Signed-off-by: Kinglong Mee Signed-off-by: J. Bruce Fields --- fs/nfsd/nfssvc.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 3779a5fbeb424..45007acaf3646 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -378,14 +378,13 @@ static void nfsd_last_thread(struct svc_serv *serv, struct net *net) * write_ports can create the server without actually starting * any threads--if we get shut down before any threads are * started, then nfsd_last_thread will be run before any of this - * other initialization has been done. + * other initialization has been done except the rpcb information. */ + svc_rpcb_cleanup(serv, net); if (!nn->nfsd_net_up) return; - nfsd_shutdown_net(net); - - svc_rpcb_cleanup(serv, net); + nfsd_shutdown_net(net); printk(KERN_WARNING "nfsd: last server has exited, flushing export " "cache\n"); nfsd_export_flush(net); -- GitLab From 549d7b317c761dbf4ed0c2945aec3acc9ca7ae14 Mon Sep 17 00:00:00 2001 From: "H. Nikolaus Schaller" Date: Thu, 17 Dec 2015 11:12:53 +0100 Subject: [PATCH 2320/2855] power: bq27xxx: fix reading for bq27000 and bq27010 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bug: the driver reports funny capacity values: root@letux:/sys/class/power_supply/bq27000-battery# cat uevent POWER_SUPPLY_NAME=bq27000-battery POWER_SUPPLY_STATUS=Charging POWER_SUPPLY_PRESENT=1 POWER_SUPPLY_VOLTAGE_NOW=3702000 POWER_SUPPLY_CURRENT_NOW=-464635 POWER_SUPPLY_CAPACITY=1536 <- over 100% is magic POWER_SUPPLY_CAPACITY_LEVEL=Normal POWER_SUPPLY_TEMP=311 POWER_SUPPLY_TIME_TO_FULL_NOW=10440 POWER_SUPPLY_TECHNOLOGY=Li-ion POWER_SUPPLY_CHARGE_FULL=805450 POWER_SUPPLY_CHARGE_NOW=1068 POWER_SUPPLY_CHARGE_FULL_DESIGN=8844998 <- battery has just 1200 mAh POWER_SUPPLY_CYCLE_COUNT=21 POWER_SUPPLY_ENERGY_NOW=0 POWER_SUPPLY_POWER_AVG=0 POWER_SUPPLY_HEALTH=Good POWER_SUPPLY_MANUFACTURER=Texas Instruments reason: the state of charge and the design capacity register are single byte only. The design capacity returns the higer order byte. tested: GTA04 with Openmoko/FIC HF08x battery (using hdq) Fixes: d74534c27775 ("power: bq27xxx_battery: Add support for additional bq27xxx family devices") Signed-off-by: H. Nikolaus Schaller Acked-by: Andrew F. Davis Reviewed-by: Pali Rohár Signed-off-by: Sebastian Reichel --- drivers/power/bq27xxx_battery.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c index 8d4ef9fd9b6e8..0b95542e286f3 100644 --- a/drivers/power/bq27xxx_battery.c +++ b/drivers/power/bq27xxx_battery.c @@ -428,7 +428,10 @@ static int bq27xxx_battery_read_soc(struct bq27xxx_device_info *di) { int soc; - soc = bq27xxx_read(di, BQ27XXX_REG_SOC, false); + if (di->chip == BQ27000 || di->chip == BQ27010) + soc = bq27xxx_read(di, BQ27XXX_REG_SOC, true); + else + soc = bq27xxx_read(di, BQ27XXX_REG_SOC, false); if (soc < 0) dev_dbg(di->dev, "error reading State-of-Charge\n"); @@ -493,7 +496,10 @@ static int bq27xxx_battery_read_dcap(struct bq27xxx_device_info *di) { int dcap; - dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, false); + if (di->chip == BQ27000 || di->chip == BQ27010) + dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, true); + else + dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, false); if (dcap < 0) { dev_dbg(di->dev, "error reading initial last measured discharge\n"); @@ -501,7 +507,7 @@ static int bq27xxx_battery_read_dcap(struct bq27xxx_device_info *di) } if (di->chip == BQ27000 || di->chip == BQ27010) - dcap *= BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS; + dcap = (dcap << 8) * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS; else dcap *= 1000; -- GitLab From 099867a16a0fa9fd5aafc32e3b1a6f8a90f17834 Mon Sep 17 00:00:00 2001 From: "H. Nikolaus Schaller" Date: Thu, 17 Dec 2015 11:12:54 +0100 Subject: [PATCH 2321/2855] power: bq27xxx: fix register numbers of bq27500 bug: according to data sheet some register numbers are wrong. tested: no Fixes: d74534c27775 ("power: bq27xxx_battery: Add support for additional bq27xxx family devices") Signed-off-by: H. Nikolaus Schaller Acked-by: Andrew F. Davis Signed-off-by: Sebastian Reichel --- drivers/power/bq27xxx_battery.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c index 0b95542e286f3..73b647b493ba6 100644 --- a/drivers/power/bq27xxx_battery.c +++ b/drivers/power/bq27xxx_battery.c @@ -155,10 +155,10 @@ static u8 bq27500_regs[] = { INVALID_REG_ADDR, /* TTECP - NA */ 0x0c, /* NAC */ 0x12, /* LMD(FCC) */ - 0x1e, /* CYCT */ + 0x2a, /* CYCT */ INVALID_REG_ADDR, /* AE - NA */ - 0x20, /* SOC(RSOC) */ - 0x2e, /* DCAP(ILMD) */ + 0x2c, /* SOC(RSOC) */ + 0x3c, /* DCAP(ILMD) */ INVALID_REG_ADDR, /* AP - NA */ }; -- GitLab From 88025632515adfb7fcfac15d087f155b719e78cd Mon Sep 17 00:00:00 2001 From: Ivaylo Dimitrov Date: Fri, 1 Jan 2016 13:03:29 +0200 Subject: [PATCH 2322/2855] power: isp1704_charger: Fix isp1704_write() definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All calls to isp1704_write() are using parameter sequence of isp1704_write(isp, reg, val) but the function is defined as isp1704_write(isp, val, reg). Fix isp1704_write function definition so that the driver to be functional. Signed-off-by: Ivaylo Dimitrov Reviewed-by: Pali Rohár Signed-off-by: Sebastian Reichel --- drivers/power/isp1704_charger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c index f2a7d970388f1..46a292aa182d1 100644 --- a/drivers/power/isp1704_charger.c +++ b/drivers/power/isp1704_charger.c @@ -76,7 +76,7 @@ static inline int isp1704_read(struct isp1704_charger *isp, u32 reg) return usb_phy_io_read(isp->phy, reg); } -static inline int isp1704_write(struct isp1704_charger *isp, u32 val, u32 reg) +static inline int isp1704_write(struct isp1704_charger *isp, u32 reg, u32 val) { return usb_phy_io_write(isp->phy, val, reg); } -- GitLab From 127d2868484b9769e08a8353e9e43023dcb8b9b3 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Fri, 1 Jan 2016 22:59:11 +0800 Subject: [PATCH 2323/2855] power: generic-adc-battery: use to_delayed_work Use to_delayed_work() instead of open-coding it. Signed-off-by: Geliang Tang Signed-off-by: Sebastian Reichel --- drivers/power/generic-adc-battery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/generic-adc-battery.c b/drivers/power/generic-adc-battery.c index fedc5818fab7b..edb36bf781b0c 100644 --- a/drivers/power/generic-adc-battery.c +++ b/drivers/power/generic-adc-battery.c @@ -206,7 +206,7 @@ static void gab_work(struct work_struct *work) bool is_plugged; int status; - delayed_work = container_of(work, struct delayed_work, work); + delayed_work = to_delayed_work(work); adc_bat = container_of(delayed_work, struct gab, bat_work); pdata = adc_bat->pdata; status = adc_bat->status; -- GitLab From 70dc6daff090afaab588e800fca3db59bfac694e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 7 Jan 2016 13:03:08 +0300 Subject: [PATCH 2324/2855] regulator: core: remove some dead code Originally queue_delayed_work() used to negative error codes or 0 and 1 on success depending if the work was queued or not. It caused a lot of bugs where people treated all non-zero returns as failures so we changed it to return bool instead in d4283e937861 ('workqueue: make queueing functions return bool'). Now it never returns failure. Checking for negative values causes a static checker warning since it is impossible based on the bool type. Signed-off-by: Dan Carpenter Signed-off-by: Mark Brown --- drivers/regulator/core.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 0853a80bf7fea..856fec528b8db 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2368,7 +2368,6 @@ static void regulator_disable_work(struct work_struct *work) int regulator_disable_deferred(struct regulator *regulator, int ms) { struct regulator_dev *rdev = regulator->rdev; - int ret; if (regulator->always_on) return 0; @@ -2380,13 +2379,9 @@ int regulator_disable_deferred(struct regulator *regulator, int ms) rdev->deferred_disables++; mutex_unlock(&rdev->mutex); - ret = queue_delayed_work(system_power_efficient_wq, - &rdev->disable_work, - msecs_to_jiffies(ms)); - if (ret < 0) - return ret; - else - return 0; + queue_delayed_work(system_power_efficient_wq, &rdev->disable_work, + msecs_to_jiffies(ms)); + return 0; } EXPORT_SYMBOL_GPL(regulator_disable_deferred); -- GitLab From 218e0b575ffe6de1c93249871b25bbf570fe1cb5 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Tue, 5 Jan 2016 21:46:20 +0100 Subject: [PATCH 2325/2855] spi: sun4i: Prevent chip-select from being activated twice before a transfer The SPI core calls set_cs before a transfer, but the SUN4I_CTL_CS_MANUAL flag is only set in transfer_one. This leads to the following pattern on the chip-select line (with runtime power-management on every transfer, without it only on the first one): activate, deactivate, activate, transfer, deactivate Moving the configuration of the SUN4I_CTL_CS_MANUAL flag from transfer_one to set_cs removes the double activation. Signed-off-by: Marcus Weseloh Acked-by: Maxime Ripard Signed-off-by: Mark Brown --- drivers/spi/spi-sun4i.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c index fbb0a4d74e91c..a6d936c68674c 100644 --- a/drivers/spi/spi-sun4i.c +++ b/drivers/spi/spi-sun4i.c @@ -140,6 +140,9 @@ static void sun4i_spi_set_cs(struct spi_device *spi, bool enable) reg &= ~SUN4I_CTL_CS_MASK; reg |= SUN4I_CTL_CS(spi->chip_select); + /* We want to control the chip select manually */ + reg |= SUN4I_CTL_CS_MANUAL; + if (enable) reg |= SUN4I_CTL_CS_LEVEL; else @@ -222,9 +225,6 @@ static int sun4i_spi_transfer_one(struct spi_master *master, else reg |= SUN4I_CTL_DHB; - /* We want to control the chip select manually */ - reg |= SUN4I_CTL_CS_MANUAL; - sun4i_spi_write(sspi, SUN4I_CTL_REG, reg); /* Ensure that we have a parent clock fast enough */ -- GitLab From ae02ab00aa3c282a362af8c4496496970747ddf4 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Mon, 4 Jan 2016 12:34:43 +0000 Subject: [PATCH 2326/2855] mtd: nand: jz4780: driver for NAND devices on JZ4780 SoCs Add a driver for NAND devices connected to the NEMC on JZ4780 SoCs, as well as the hardware BCH controller. DMA is not currently implemented. While older 47xx SoCs also have a BCH controller, they are incompatible with the one in the 4780 due to differing register/bit positions, which would make implementing a common driver for them quite messy. Signed-off-by: Alex Smith Cc: Zubair Lutfullah Kakakhel Cc: David Woodhouse Cc: linux-mtd@lists.infradead.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Harvey Hunt Reviewed-by: Boris Brezillon [Brian: fixed a few small mistakes] Signed-off-by: Brian Norris --- drivers/mtd/nand/Kconfig | 7 + drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/jz4780_bch.c | 381 +++++++++++++++++++++++++++++ drivers/mtd/nand/jz4780_bch.h | 43 ++++ drivers/mtd/nand/jz4780_nand.c | 425 +++++++++++++++++++++++++++++++++ 5 files changed, 857 insertions(+) create mode 100644 drivers/mtd/nand/jz4780_bch.c create mode 100644 drivers/mtd/nand/jz4780_bch.h create mode 100644 drivers/mtd/nand/jz4780_nand.c diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 95b8d2b8a7afd..20f01b3ec23d7 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -519,6 +519,13 @@ config MTD_NAND_JZ4740 help Enables support for NAND Flash on JZ4740 SoC based boards. +config MTD_NAND_JZ4780 + tristate "Support for NAND on JZ4780 SoC" + depends on MACH_JZ4780 && JZ4780_NEMC + help + Enables support for NAND Flash connected to the NEMC on JZ4780 SoC + based boards, using the BCH controller for hardware error correction. + config MTD_NAND_FSMC tristate "Support for NAND on ST Micros FSMC" depends on PLAT_SPEAR || ARCH_NOMADIK || ARCH_U8500 || MACH_U300 diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 2c7f014b349e5..9e36233085098 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -49,6 +49,7 @@ obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mpc5121_nfc.o obj-$(CONFIG_MTD_NAND_VF610_NFC) += vf610_nfc.o obj-$(CONFIG_MTD_NAND_RICOH) += r852.o obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o +obj-$(CONFIG_MTD_NAND_JZ4780) += jz4780_nand.o jz4780_bch.o obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/ obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/ diff --git a/drivers/mtd/nand/jz4780_bch.c b/drivers/mtd/nand/jz4780_bch.c new file mode 100644 index 0000000000000..5954fbfa29e94 --- /dev/null +++ b/drivers/mtd/nand/jz4780_bch.c @@ -0,0 +1,381 @@ +/* + * JZ4780 BCH controller + * + * Copyright (c) 2015 Imagination Technologies + * Author: Alex Smith + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "jz4780_bch.h" + +#define BCH_BHCR 0x0 +#define BCH_BHCCR 0x8 +#define BCH_BHCNT 0xc +#define BCH_BHDR 0x10 +#define BCH_BHPAR0 0x14 +#define BCH_BHERR0 0x84 +#define BCH_BHINT 0x184 +#define BCH_BHINTES 0x188 +#define BCH_BHINTEC 0x18c +#define BCH_BHINTE 0x190 + +#define BCH_BHCR_BSEL_SHIFT 4 +#define BCH_BHCR_BSEL_MASK (0x7f << BCH_BHCR_BSEL_SHIFT) +#define BCH_BHCR_ENCE BIT(2) +#define BCH_BHCR_INIT BIT(1) +#define BCH_BHCR_BCHE BIT(0) + +#define BCH_BHCNT_PARITYSIZE_SHIFT 16 +#define BCH_BHCNT_PARITYSIZE_MASK (0x7f << BCH_BHCNT_PARITYSIZE_SHIFT) +#define BCH_BHCNT_BLOCKSIZE_SHIFT 0 +#define BCH_BHCNT_BLOCKSIZE_MASK (0x7ff << BCH_BHCNT_BLOCKSIZE_SHIFT) + +#define BCH_BHERR_MASK_SHIFT 16 +#define BCH_BHERR_MASK_MASK (0xffff << BCH_BHERR_MASK_SHIFT) +#define BCH_BHERR_INDEX_SHIFT 0 +#define BCH_BHERR_INDEX_MASK (0x7ff << BCH_BHERR_INDEX_SHIFT) + +#define BCH_BHINT_ERRC_SHIFT 24 +#define BCH_BHINT_ERRC_MASK (0x7f << BCH_BHINT_ERRC_SHIFT) +#define BCH_BHINT_TERRC_SHIFT 16 +#define BCH_BHINT_TERRC_MASK (0x7f << BCH_BHINT_TERRC_SHIFT) +#define BCH_BHINT_DECF BIT(3) +#define BCH_BHINT_ENCF BIT(2) +#define BCH_BHINT_UNCOR BIT(1) +#define BCH_BHINT_ERR BIT(0) + +#define BCH_CLK_RATE (200 * 1000 * 1000) + +/* Timeout for BCH calculation/correction. */ +#define BCH_TIMEOUT_US 100000 + +struct jz4780_bch { + struct device *dev; + void __iomem *base; + struct clk *clk; + struct mutex lock; +}; + +static void jz4780_bch_init(struct jz4780_bch *bch, + struct jz4780_bch_params *params, bool encode) +{ + u32 reg; + + /* Clear interrupt status. */ + writel(readl(bch->base + BCH_BHINT), bch->base + BCH_BHINT); + + /* Set up BCH count register. */ + reg = params->size << BCH_BHCNT_BLOCKSIZE_SHIFT; + reg |= params->bytes << BCH_BHCNT_PARITYSIZE_SHIFT; + writel(reg, bch->base + BCH_BHCNT); + + /* Initialise and enable BCH. */ + reg = BCH_BHCR_BCHE | BCH_BHCR_INIT; + reg |= params->strength << BCH_BHCR_BSEL_SHIFT; + if (encode) + reg |= BCH_BHCR_ENCE; + writel(reg, bch->base + BCH_BHCR); +} + +static void jz4780_bch_disable(struct jz4780_bch *bch) +{ + writel(readl(bch->base + BCH_BHINT), bch->base + BCH_BHINT); + writel(BCH_BHCR_BCHE, bch->base + BCH_BHCCR); +} + +static void jz4780_bch_write_data(struct jz4780_bch *bch, const void *buf, + size_t size) +{ + size_t size32 = size / sizeof(u32); + size_t size8 = size % sizeof(u32); + const u32 *src32; + const u8 *src8; + + src32 = (const u32 *)buf; + while (size32--) + writel(*src32++, bch->base + BCH_BHDR); + + src8 = (const u8 *)src32; + while (size8--) + writeb(*src8++, bch->base + BCH_BHDR); +} + +static void jz4780_bch_read_parity(struct jz4780_bch *bch, void *buf, + size_t size) +{ + size_t size32 = size / sizeof(u32); + size_t size8 = size % sizeof(u32); + u32 *dest32; + u8 *dest8; + u32 val, offset = 0; + + dest32 = (u32 *)buf; + while (size32--) { + *dest32++ = readl(bch->base + BCH_BHPAR0 + offset); + offset += sizeof(u32); + } + + dest8 = (u8 *)dest32; + val = readl(bch->base + BCH_BHPAR0 + offset); + switch (size8) { + case 3: + dest8[2] = (val >> 16) & 0xff; + case 2: + dest8[1] = (val >> 8) & 0xff; + case 1: + dest8[0] = val & 0xff; + break; + } +} + +static bool jz4780_bch_wait_complete(struct jz4780_bch *bch, unsigned int irq, + u32 *status) +{ + u32 reg; + int ret; + + /* + * While we could use interrupts here and sleep until the operation + * completes, the controller works fairly quickly (usually a few + * microseconds) and so the overhead of sleeping until we get an + * interrupt quite noticeably decreases performance. + */ + ret = readl_poll_timeout(bch->base + BCH_BHINT, reg, + (reg & irq) == irq, 0, BCH_TIMEOUT_US); + if (ret) + return false; + + if (status) + *status = reg; + + writel(reg, bch->base + BCH_BHINT); + return true; +} + +/** + * jz4780_bch_calculate() - calculate ECC for a data buffer + * @bch: BCH device. + * @params: BCH parameters. + * @buf: input buffer with raw data. + * @ecc_code: output buffer with ECC. + * + * Return: 0 on success, -ETIMEDOUT if timed out while waiting for BCH + * controller. + */ +int jz4780_bch_calculate(struct jz4780_bch *bch, struct jz4780_bch_params *params, + const u8 *buf, u8 *ecc_code) +{ + int ret = 0; + + mutex_lock(&bch->lock); + jz4780_bch_init(bch, params, true); + jz4780_bch_write_data(bch, buf, params->size); + + if (jz4780_bch_wait_complete(bch, BCH_BHINT_ENCF, NULL)) { + jz4780_bch_read_parity(bch, ecc_code, params->bytes); + } else { + dev_err(bch->dev, "timed out while calculating ECC\n"); + ret = -ETIMEDOUT; + } + + jz4780_bch_disable(bch); + mutex_unlock(&bch->lock); + return ret; +} +EXPORT_SYMBOL(jz4780_bch_calculate); + +/** + * jz4780_bch_correct() - detect and correct bit errors + * @bch: BCH device. + * @params: BCH parameters. + * @buf: raw data read from the chip. + * @ecc_code: ECC read from the chip. + * + * Given the raw data and the ECC read from the NAND device, detects and + * corrects errors in the data. + * + * Return: the number of bit errors corrected, or -1 if there are too many + * errors to correct or we timed out waiting for the controller. + */ +int jz4780_bch_correct(struct jz4780_bch *bch, struct jz4780_bch_params *params, + u8 *buf, u8 *ecc_code) +{ + u32 reg, mask, index; + int i, ret, count; + + mutex_lock(&bch->lock); + + jz4780_bch_init(bch, params, false); + jz4780_bch_write_data(bch, buf, params->size); + jz4780_bch_write_data(bch, ecc_code, params->bytes); + + if (!jz4780_bch_wait_complete(bch, BCH_BHINT_DECF, ®)) { + dev_err(bch->dev, "timed out while correcting data\n"); + ret = -1; + goto out; + } + + if (reg & BCH_BHINT_UNCOR) { + dev_warn(bch->dev, "uncorrectable ECC error\n"); + ret = -1; + goto out; + } + + /* Correct any detected errors. */ + if (reg & BCH_BHINT_ERR) { + count = (reg & BCH_BHINT_ERRC_MASK) >> BCH_BHINT_ERRC_SHIFT; + ret = (reg & BCH_BHINT_TERRC_MASK) >> BCH_BHINT_TERRC_SHIFT; + + for (i = 0; i < count; i++) { + reg = readl(bch->base + BCH_BHERR0 + (i * 4)); + mask = (reg & BCH_BHERR_MASK_MASK) >> + BCH_BHERR_MASK_SHIFT; + index = (reg & BCH_BHERR_INDEX_MASK) >> + BCH_BHERR_INDEX_SHIFT; + buf[(index * 2) + 0] ^= mask; + buf[(index * 2) + 1] ^= mask >> 8; + } + } else { + ret = 0; + } + +out: + jz4780_bch_disable(bch); + mutex_unlock(&bch->lock); + return ret; +} +EXPORT_SYMBOL(jz4780_bch_correct); + +/** + * jz4780_bch_get() - get the BCH controller device + * @np: BCH device tree node. + * + * Gets the BCH controller device from the specified device tree node. The + * device must be released with jz4780_bch_release() when it is no longer being + * used. + * + * Return: a pointer to jz4780_bch, errors are encoded into the pointer. + * PTR_ERR(-EPROBE_DEFER) if the device hasn't been initialised yet. + */ +static struct jz4780_bch *jz4780_bch_get(struct device_node *np) +{ + struct platform_device *pdev; + struct jz4780_bch *bch; + + pdev = of_find_device_by_node(np); + if (!pdev || !platform_get_drvdata(pdev)) + return ERR_PTR(-EPROBE_DEFER); + + get_device(&pdev->dev); + + bch = platform_get_drvdata(pdev); + clk_prepare_enable(bch->clk); + + bch->dev = &pdev->dev; + return bch; +} + +/** + * of_jz4780_bch_get() - get the BCH controller from a DT node + * @of_node: the node that contains a bch-controller property. + * + * Get the bch-controller property from the given device tree + * node and pass it to jz4780_bch_get to do the work. + * + * Return: a pointer to jz4780_bch, errors are encoded into the pointer. + * PTR_ERR(-EPROBE_DEFER) if the device hasn't been initialised yet. + */ +struct jz4780_bch *of_jz4780_bch_get(struct device_node *of_node) +{ + struct jz4780_bch *bch = NULL; + struct device_node *np; + + np = of_parse_phandle(of_node, "ingenic,bch-controller", 0); + + if (np) { + bch = jz4780_bch_get(np); + of_node_put(np); + } + return bch; +} +EXPORT_SYMBOL(of_jz4780_bch_get); + +/** + * jz4780_bch_release() - release the BCH controller device + * @bch: BCH device. + */ +void jz4780_bch_release(struct jz4780_bch *bch) +{ + clk_disable_unprepare(bch->clk); + put_device(bch->dev); +} +EXPORT_SYMBOL(jz4780_bch_release); + +static int jz4780_bch_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct jz4780_bch *bch; + struct resource *res; + + bch = devm_kzalloc(dev, sizeof(*bch), GFP_KERNEL); + if (!bch) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + bch->base = devm_ioremap_resource(dev, res); + if (IS_ERR(bch->base)) + return PTR_ERR(bch->base); + + jz4780_bch_disable(bch); + + bch->clk = devm_clk_get(dev, NULL); + if (IS_ERR(bch->clk)) { + dev_err(dev, "failed to get clock: %ld\n", PTR_ERR(bch->clk)); + return PTR_ERR(bch->clk); + } + + clk_set_rate(bch->clk, BCH_CLK_RATE); + + mutex_init(&bch->lock); + + bch->dev = dev; + platform_set_drvdata(pdev, bch); + + return 0; +} + +static const struct of_device_id jz4780_bch_dt_match[] = { + { .compatible = "ingenic,jz4780-bch" }, + {}, +}; +MODULE_DEVICE_TABLE(of, jz4780_bch_dt_match); + +static struct platform_driver jz4780_bch_driver = { + .probe = jz4780_bch_probe, + .driver = { + .name = "jz4780-bch", + .of_match_table = of_match_ptr(jz4780_bch_dt_match), + }, +}; +module_platform_driver(jz4780_bch_driver); + +MODULE_AUTHOR("Alex Smith "); +MODULE_AUTHOR("Harvey Hunt "); +MODULE_DESCRIPTION("Ingenic JZ4780 BCH error correction driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/mtd/nand/jz4780_bch.h b/drivers/mtd/nand/jz4780_bch.h new file mode 100644 index 0000000000000..bf4718088a3ab --- /dev/null +++ b/drivers/mtd/nand/jz4780_bch.h @@ -0,0 +1,43 @@ +/* + * JZ4780 BCH controller + * + * Copyright (c) 2015 Imagination Technologies + * Author: Alex Smith + * + * 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. + */ + +#ifndef __DRIVERS_MTD_NAND_JZ4780_BCH_H__ +#define __DRIVERS_MTD_NAND_JZ4780_BCH_H__ + +#include + +struct device; +struct device_node; +struct jz4780_bch; + +/** + * struct jz4780_bch_params - BCH parameters + * @size: data bytes per ECC step. + * @bytes: ECC bytes per step. + * @strength: number of correctable bits per ECC step. + */ +struct jz4780_bch_params { + int size; + int bytes; + int strength; +}; + +int jz4780_bch_calculate(struct jz4780_bch *bch, + struct jz4780_bch_params *params, + const u8 *buf, u8 *ecc_code); +int jz4780_bch_correct(struct jz4780_bch *bch, + struct jz4780_bch_params *params, u8 *buf, + u8 *ecc_code); + +void jz4780_bch_release(struct jz4780_bch *bch); +struct jz4780_bch *of_jz4780_bch_get(struct device_node *np); + +#endif /* __DRIVERS_MTD_NAND_JZ4780_BCH_H__ */ diff --git a/drivers/mtd/nand/jz4780_nand.c b/drivers/mtd/nand/jz4780_nand.c new file mode 100644 index 0000000000000..17eb9f2641873 --- /dev/null +++ b/drivers/mtd/nand/jz4780_nand.c @@ -0,0 +1,425 @@ +/* + * JZ4780 NAND driver + * + * Copyright (c) 2015 Imagination Technologies + * Author: Alex Smith + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "jz4780_bch.h" + +#define DRV_NAME "jz4780-nand" + +#define OFFSET_DATA 0x00000000 +#define OFFSET_CMD 0x00400000 +#define OFFSET_ADDR 0x00800000 + +/* Command delay when there is no R/B pin. */ +#define RB_DELAY_US 100 + +struct jz4780_nand_cs { + unsigned int bank; + void __iomem *base; +}; + +struct jz4780_nand_controller { + struct device *dev; + struct jz4780_bch *bch; + struct nand_hw_control controller; + unsigned int num_banks; + struct list_head chips; + int selected; + struct jz4780_nand_cs cs[]; +}; + +struct jz4780_nand_chip { + struct nand_chip chip; + struct list_head chip_list; + + struct nand_ecclayout ecclayout; + + struct gpio_desc *busy_gpio; + struct gpio_desc *wp_gpio; + unsigned int reading: 1; +}; + +static inline struct jz4780_nand_chip *to_jz4780_nand_chip(struct mtd_info *mtd) +{ + return container_of(mtd_to_nand(mtd), struct jz4780_nand_chip, chip); +} + +static inline struct jz4780_nand_controller *to_jz4780_nand_controller(struct nand_hw_control *ctrl) +{ + return container_of(ctrl, struct jz4780_nand_controller, controller); +} + +static void jz4780_nand_select_chip(struct mtd_info *mtd, int chipnr) +{ + struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd); + struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(nand->chip.controller); + struct jz4780_nand_cs *cs; + + /* Ensure the currently selected chip is deasserted. */ + if (chipnr == -1 && nfc->selected >= 0) { + cs = &nfc->cs[nfc->selected]; + jz4780_nemc_assert(nfc->dev, cs->bank, false); + } + + nfc->selected = chipnr; +} + +static void jz4780_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, + unsigned int ctrl) +{ + struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd); + struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(nand->chip.controller); + struct jz4780_nand_cs *cs; + + if (WARN_ON(nfc->selected < 0)) + return; + + cs = &nfc->cs[nfc->selected]; + + jz4780_nemc_assert(nfc->dev, cs->bank, ctrl & NAND_NCE); + + if (cmd == NAND_CMD_NONE) + return; + + if (ctrl & NAND_ALE) + writeb(cmd, cs->base + OFFSET_ADDR); + else if (ctrl & NAND_CLE) + writeb(cmd, cs->base + OFFSET_CMD); +} + +static int jz4780_nand_dev_ready(struct mtd_info *mtd) +{ + struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd); + + return !gpiod_get_value_cansleep(nand->busy_gpio); +} + +static void jz4780_nand_ecc_hwctl(struct mtd_info *mtd, int mode) +{ + struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd); + + nand->reading = (mode == NAND_ECC_READ); +} + +static int jz4780_nand_ecc_calculate(struct mtd_info *mtd, const u8 *dat, + u8 *ecc_code) +{ + struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd); + struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(nand->chip.controller); + struct jz4780_bch_params params; + + /* + * Don't need to generate the ECC when reading, BCH does it for us as + * part of decoding/correction. + */ + if (nand->reading) + return 0; + + params.size = nand->chip.ecc.size; + params.bytes = nand->chip.ecc.bytes; + params.strength = nand->chip.ecc.strength; + + return jz4780_bch_calculate(nfc->bch, ¶ms, dat, ecc_code); +} + +static int jz4780_nand_ecc_correct(struct mtd_info *mtd, u8 *dat, + u8 *read_ecc, u8 *calc_ecc) +{ + struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd); + struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(nand->chip.controller); + struct jz4780_bch_params params; + + params.size = nand->chip.ecc.size; + params.bytes = nand->chip.ecc.bytes; + params.strength = nand->chip.ecc.strength; + + return jz4780_bch_correct(nfc->bch, ¶ms, dat, read_ecc); +} + +static int jz4780_nand_init_ecc(struct jz4780_nand_chip *nand, struct device *dev) +{ + struct nand_chip *chip = &nand->chip; + struct mtd_info *mtd = nand_to_mtd(chip); + struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(chip->controller); + struct nand_ecclayout *layout = &nand->ecclayout; + u32 start, i; + + chip->ecc.bytes = fls((1 + 8) * chip->ecc.size) * + (chip->ecc.strength / 8); + + if (nfc->bch && chip->ecc.mode == NAND_ECC_HW) { + chip->ecc.hwctl = jz4780_nand_ecc_hwctl; + chip->ecc.calculate = jz4780_nand_ecc_calculate; + chip->ecc.correct = jz4780_nand_ecc_correct; + } else if (!nfc->bch && chip->ecc.mode == NAND_ECC_HW) { + dev_err(dev, "HW BCH selected, but BCH controller not found\n"); + return -ENODEV; + } + + if (chip->ecc.mode == NAND_ECC_HW_SYNDROME) { + dev_err(dev, "ECC HW syndrome not supported\n"); + return -EINVAL; + } + + if (chip->ecc.mode != NAND_ECC_NONE) + dev_info(dev, "using %s (strength %d, size %d, bytes %d)\n", + (nfc->bch) ? "hardware BCH" : "software ECC", + chip->ecc.strength, chip->ecc.size, chip->ecc.bytes); + else + dev_info(dev, "not using ECC\n"); + + /* The NAND core will generate the ECC layout. */ + if (chip->ecc.mode == NAND_ECC_SOFT || chip->ecc.mode == NAND_ECC_SOFT_BCH) + return 0; + + /* Generate ECC layout. ECC codes are right aligned in the OOB area. */ + layout->eccbytes = mtd->writesize / chip->ecc.size * chip->ecc.bytes; + + if (layout->eccbytes > mtd->oobsize - 2) { + dev_err(dev, + "invalid ECC config: required %d ECC bytes, but only %d are available", + layout->eccbytes, mtd->oobsize - 2); + return -EINVAL; + } + + start = mtd->oobsize - layout->eccbytes; + for (i = 0; i < layout->eccbytes; i++) + layout->eccpos[i] = start + i; + + layout->oobfree[0].offset = 2; + layout->oobfree[0].length = mtd->oobsize - layout->eccbytes - 2; + + chip->ecc.layout = layout; + return 0; +} + +static int jz4780_nand_init_chip(struct platform_device *pdev, + struct jz4780_nand_controller *nfc, + struct device_node *np, + unsigned int chipnr) +{ + struct device *dev = &pdev->dev; + struct jz4780_nand_chip *nand; + struct jz4780_nand_cs *cs; + struct resource *res; + struct nand_chip *chip; + struct mtd_info *mtd; + const __be32 *reg; + int ret = 0; + + cs = &nfc->cs[chipnr]; + + reg = of_get_property(np, "reg", NULL); + if (!reg) + return -EINVAL; + + cs->bank = be32_to_cpu(*reg); + + jz4780_nemc_set_type(nfc->dev, cs->bank, JZ4780_NEMC_BANK_NAND); + + res = platform_get_resource(pdev, IORESOURCE_MEM, chipnr); + cs->base = devm_ioremap_resource(dev, res); + if (IS_ERR(cs->base)) + return PTR_ERR(cs->base); + + nand = devm_kzalloc(dev, sizeof(*nand), GFP_KERNEL); + if (!nand) + return -ENOMEM; + + nand->busy_gpio = devm_gpiod_get_optional(dev, "rb", GPIOD_IN); + + if (IS_ERR(nand->busy_gpio)) { + ret = PTR_ERR(nand->busy_gpio); + dev_err(dev, "failed to request busy GPIO: %d\n", ret); + return ret; + } else if (nand->busy_gpio) { + nand->chip.dev_ready = jz4780_nand_dev_ready; + } + + nand->wp_gpio = devm_gpiod_get_optional(dev, "wp", GPIOD_OUT_LOW); + + if (IS_ERR(nand->wp_gpio)) { + ret = PTR_ERR(nand->wp_gpio); + dev_err(dev, "failed to request WP GPIO: %d\n", ret); + return ret; + } + + chip = &nand->chip; + mtd = nand_to_mtd(chip); + mtd->priv = chip; + mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s.%d", dev_name(dev), + cs->bank); + if (!mtd->name) + return -ENOMEM; + mtd->dev.parent = dev; + + chip->IO_ADDR_R = cs->base + OFFSET_DATA; + chip->IO_ADDR_W = cs->base + OFFSET_DATA; + chip->chip_delay = RB_DELAY_US; + chip->options = NAND_NO_SUBPAGE_WRITE; + chip->select_chip = jz4780_nand_select_chip; + chip->cmd_ctrl = jz4780_nand_cmd_ctrl; + chip->ecc.mode = NAND_ECC_HW; + chip->controller = &nfc->controller; + nand_set_flash_node(chip, np); + + ret = nand_scan_ident(mtd, 1, NULL); + if (ret) + return ret; + + ret = jz4780_nand_init_ecc(nand, dev); + if (ret) + return ret; + + ret = nand_scan_tail(mtd); + if (ret) + return ret; + + ret = mtd_device_register(mtd, NULL, 0); + if (ret) { + nand_release(mtd); + return ret; + } + + list_add_tail(&nand->chip_list, &nfc->chips); + + return 0; +} + +static void jz4780_nand_cleanup_chips(struct jz4780_nand_controller *nfc) +{ + struct jz4780_nand_chip *chip; + + while (!list_empty(&nfc->chips)) { + chip = list_first_entry(&nfc->chips, struct jz4780_nand_chip, chip_list); + nand_release(nand_to_mtd(&chip->chip)); + list_del(&chip->chip_list); + } +} + +static int jz4780_nand_init_chips(struct jz4780_nand_controller *nfc, + struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np; + int i = 0; + int ret; + int num_chips = of_get_child_count(dev->of_node); + + if (num_chips > nfc->num_banks) { + dev_err(dev, "found %d chips but only %d banks\n", num_chips, nfc->num_banks); + return -EINVAL; + } + + for_each_child_of_node(dev->of_node, np) { + ret = jz4780_nand_init_chip(pdev, nfc, np, i); + if (ret) { + jz4780_nand_cleanup_chips(nfc); + return ret; + } + + i++; + } + + return 0; +} + +static int jz4780_nand_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + unsigned int num_banks; + struct jz4780_nand_controller *nfc; + int ret; + + num_banks = jz4780_nemc_num_banks(dev); + if (num_banks == 0) { + dev_err(dev, "no banks found\n"); + return -ENODEV; + } + + nfc = devm_kzalloc(dev, sizeof(*nfc) + (sizeof(nfc->cs[0]) * num_banks), GFP_KERNEL); + if (!nfc) + return -ENOMEM; + + /* + * Check for BCH HW before we call nand_scan_ident, to prevent us from + * having to call it again if the BCH driver returns -EPROBE_DEFER. + */ + nfc->bch = of_jz4780_bch_get(dev->of_node); + if (IS_ERR(nfc->bch)) + return PTR_ERR(nfc->bch); + + nfc->dev = dev; + nfc->num_banks = num_banks; + + spin_lock_init(&nfc->controller.lock); + INIT_LIST_HEAD(&nfc->chips); + init_waitqueue_head(&nfc->controller.wq); + + ret = jz4780_nand_init_chips(nfc, pdev); + if (ret) { + if (nfc->bch) + jz4780_bch_release(nfc->bch); + return ret; + } + + platform_set_drvdata(pdev, nfc); + return 0; +} + +static int jz4780_nand_remove(struct platform_device *pdev) +{ + struct jz4780_nand_controller *nfc = platform_get_drvdata(pdev); + + if (nfc->bch) + jz4780_bch_release(nfc->bch); + + jz4780_nand_cleanup_chips(nfc); + + return 0; +} + +static const struct of_device_id jz4780_nand_dt_match[] = { + { .compatible = "ingenic,jz4780-nand" }, + {}, +}; +MODULE_DEVICE_TABLE(of, jz4780_nand_dt_match); + +static struct platform_driver jz4780_nand_driver = { + .probe = jz4780_nand_probe, + .remove = jz4780_nand_remove, + .driver = { + .name = DRV_NAME, + .of_match_table = of_match_ptr(jz4780_nand_dt_match), + }, +}; +module_platform_driver(jz4780_nand_driver); + +MODULE_AUTHOR("Alex Smith "); +MODULE_AUTHOR("Harvey Hunt "); +MODULE_DESCRIPTION("Ingenic JZ4780 NAND driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 6b9140f39c2aaf76791197fbab0839c0e4af56e8 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Tue, 22 Dec 2015 12:43:36 -0500 Subject: [PATCH 2327/2855] power: test_power: correctly handle empty writes Writing 0 length data into test_power makes it access an invalid array location and kill the system. Fixes: f17ef9b2d ("power: Make test_power driver more dynamic.") Signed-off-by: Sasha Levin Signed-off-by: Sebastian Reichel --- drivers/power/test_power.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/power/test_power.c b/drivers/power/test_power.c index 83c42ea88f2b2..57246cdbd0426 100644 --- a/drivers/power/test_power.c +++ b/drivers/power/test_power.c @@ -301,6 +301,8 @@ static int map_get_value(struct battery_property_map *map, const char *key, buf[MAX_KEYLENGTH-1] = '\0'; cr = strnlen(buf, MAX_KEYLENGTH) - 1; + if (cr < 0) + return def_val; if (buf[cr] == '\n') buf[cr] = '\0'; -- GitLab From d39ddbd9ef70949bb78283a067e1b3366111dd90 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:39 +0100 Subject: [PATCH 2328/2855] mtd: nand: add helpers to access ->priv Add two helpers to access the field reserved for private controller data. This makes it clearer what this field is reserved for and ease future refactoring. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 86487dbe73584..bdd68e22b5a59 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -755,6 +755,16 @@ static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip) return &chip->mtd; } +static inline void *nand_get_controller_data(struct nand_chip *chip) +{ + return chip->priv; +} + +static inline void nand_set_controller_data(struct nand_chip *chip, void *priv) +{ + chip->priv = priv; +} + /* * NAND Flash Manufacturer ID Codes */ -- GitLab From 415a249f88fd263bed0f7cca86ecde8c57aba9dc Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 6 Jan 2016 14:44:02 -0800 Subject: [PATCH 2329/2855] Input: rohm_bu21023 - fix handling of retrying firmware update Because of the wrong condition we'd never retry firmware update. Acked-by: Yoichi Yuasa Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/rohm_bu21023.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/rohm_bu21023.c b/drivers/input/touchscreen/rohm_bu21023.c index ba6024f934696..611156a2ef80d 100644 --- a/drivers/input/touchscreen/rohm_bu21023.c +++ b/drivers/input/touchscreen/rohm_bu21023.c @@ -725,7 +725,7 @@ static int rohm_ts_load_firmware(struct i2c_client *client, break; error = -EIO; - } while (++retry >= FIRMWARE_RETRY_MAX); + } while (++retry <= FIRMWARE_RETRY_MAX); out: error2 = i2c_smbus_write_byte_data(client, INT_MASK, INT_ALL); -- GitLab From 7ae6cfe8d24681bea5a4a4b7a04915ac08c09ba5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 7 Jan 2016 09:55:14 -0800 Subject: [PATCH 2330/2855] Input: omap-keypad - set tasklet data earlier It feels like we should set the tasklet data before enabling it. Signed-off-by: Dan Carpenter Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/omap-keypad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index 7502e46165fac..75ad6661e1308 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c @@ -292,8 +292,8 @@ static int omap_kp_probe(struct platform_device *pdev) setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp); /* get the irq and init timer*/ - tasklet_enable(&kp_tasklet); kp_tasklet.data = (unsigned long) omap_kp; + tasklet_enable(&kp_tasklet); ret = device_create_file(&pdev->dev, &dev_attr_enable); if (ret < 0) -- GitLab From d9dccc68c5cae4ef7b4a617a93a87b11c6f0c53a Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:40 +0100 Subject: [PATCH 2331/2855] ARM: make use of nand_set/get_controller_data() helpers New helpers have been added to avoid directly accessing chip->field. Use them where appropriate. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- arch/arm/mach-ixp4xx/ixdp425-setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index 333b0f9ea635e..508c2d7786e2e 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -77,7 +77,7 @@ static void ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *this = mtd_to_nand(mtd); - int offset = (int)this->priv; + int offset = (int)nand_get_controller_data(this); if (ctrl & NAND_CTRL_CHANGE) { if (ctrl & NAND_NCE) { @@ -88,7 +88,7 @@ ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) offset = (ctrl & NAND_CLE) ? IXDP425_NAND_CMD_BYTE : 0; offset |= (ctrl & NAND_ALE) ? IXDP425_NAND_ADDR_BYTE : 0; - this->priv = (void *)offset; + nand_set_controller_data(this, (void *)offset); } if (cmd != NAND_CMD_NONE) -- GitLab From d699ed250c07384840263bbbf69cf7b90b45470c Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:41 +0100 Subject: [PATCH 2332/2855] mtd: nand: make use of nand_set/get_controller_data() helpers New helpers have been added to avoid directly accessing chip->field. Use them where appropriate. Signed-off-by: Boris Brezillon [Brian: fixed a few rebase conflicts] Signed-off-by: Brian Norris --- drivers/mtd/nand/ams-delta.c | 6 +- drivers/mtd/nand/atmel_nand.c | 55 +++++++-------- drivers/mtd/nand/bcm47xxnflash/main.c | 2 +- drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c | 16 ++--- drivers/mtd/nand/bf5xx_nand.c | 2 +- drivers/mtd/nand/brcmnand/brcmnand.c | 30 ++++----- drivers/mtd/nand/cafe_nand.c | 24 +++---- drivers/mtd/nand/diskonchip.c | 70 ++++++++++---------- drivers/mtd/nand/docg4.c | 40 +++++------ drivers/mtd/nand/fsl_elbc_nand.c | 22 +++--- drivers/mtd/nand/fsl_ifc_nand.c | 26 ++++---- drivers/mtd/nand/fsmc_nand.c | 2 +- drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 28 ++++---- drivers/mtd/nand/hisi504_nand.c | 20 +++--- drivers/mtd/nand/lpc32xx_mlc.c | 19 +++--- drivers/mtd/nand/lpc32xx_slc.c | 20 +++--- drivers/mtd/nand/mpc5121_nfc.c | 24 +++---- drivers/mtd/nand/mxc_nand.c | 36 +++++----- drivers/mtd/nand/nandsim.c | 4 +- drivers/mtd/nand/ndfc.c | 16 ++--- drivers/mtd/nand/orion_nand.c | 4 +- drivers/mtd/nand/pxa3xx_nand.c | 22 +++--- drivers/mtd/nand/r852.c | 6 +- drivers/mtd/nand/s3c2410.c | 4 +- drivers/mtd/nand/socrates_nand.c | 11 +-- drivers/mtd/nand/txx9ndfmc.c | 8 +-- 26 files changed, 260 insertions(+), 257 deletions(-) diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c index 1a18938565ac8..68b58c85789c3 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/ams-delta.c @@ -65,7 +65,7 @@ static struct mtd_partition partition_info[] = { static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte) { struct nand_chip *this = mtd_to_nand(mtd); - void __iomem *io_base = this->priv; + void __iomem *io_base = (void __iomem *)nand_get_controller_data(this); writew(0, io_base + OMAP_MPUIO_IO_CNTL); writew(byte, this->IO_ADDR_W); @@ -78,7 +78,7 @@ static u_char ams_delta_read_byte(struct mtd_info *mtd) { u_char res; struct nand_chip *this = mtd_to_nand(mtd); - void __iomem *io_base = this->priv; + void __iomem *io_base = (void __iomem *)nand_get_controller_data(this); gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NRE, 0); ndelay(40); @@ -206,7 +206,7 @@ static int ams_delta_init(struct platform_device *pdev) goto out_free; } - this->priv = io_base; + nand_set_controller_data(this, (void *)io_base); /* Set address of NAND IO lines */ this->IO_ADDR_R = io_base + OMAP_MPUIO_INPUT_LATCH; diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index b216bf5213493..bddcf83d6859a 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -182,7 +182,7 @@ static void atmel_nand_disable(struct atmel_nand_host *host) static void atmel_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(nand_chip); if (ctrl & NAND_CTRL_CHANGE) { if (ctrl & NAND_NCE) @@ -205,7 +205,7 @@ static void atmel_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl static int atmel_nand_device_ready(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(nand_chip); return gpio_get_value(host->board.rdy_pin) ^ !!host->board.rdy_pin_active_low; @@ -215,7 +215,7 @@ static int atmel_nand_device_ready(struct mtd_info *mtd) static int atmel_nand_set_enable_ready_pins(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(chip); int res = 0; if (gpio_is_valid(host->board.rdy_pin)) { @@ -267,7 +267,7 @@ static int atmel_nand_set_enable_ready_pins(struct mtd_info *mtd) static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(nand_chip); if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { memcpy(buf, host->nfc->data_in_sram, len); @@ -280,7 +280,7 @@ static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len) static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(nand_chip); if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { memcpy(buf, host->nfc->data_in_sram, len); @@ -354,7 +354,7 @@ static int atmel_nand_dma_op(struct mtd_info *mtd, void *buf, int len, struct dma_async_tx_descriptor *tx = NULL; dma_cookie_t cookie; struct nand_chip *chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(chip); void *p = buf; int err = -EIO; enum dma_data_direction dir = is_read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; @@ -427,7 +427,7 @@ err_buf: static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(chip); if (use_dma && len > mtd->oobsize) /* only use DMA for bigger than oob size: better performances */ @@ -443,7 +443,7 @@ static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len) static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(chip); if (use_dma && len > mtd->oobsize) /* only use DMA for bigger than oob size: better performances */ @@ -535,7 +535,7 @@ static int pmecc_data_alloc(struct atmel_nand_host *host) static void pmecc_gen_syndrome(struct mtd_info *mtd, int sector) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(nand_chip); int i; uint32_t value; @@ -552,7 +552,7 @@ static void pmecc_gen_syndrome(struct mtd_info *mtd, int sector) static void pmecc_substitute(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(nand_chip); int16_t __iomem *alpha_to = host->pmecc_alpha_to; int16_t __iomem *index_of = host->pmecc_index_of; int16_t *partial_syn = host->pmecc_partial_syn; @@ -594,7 +594,7 @@ static void pmecc_substitute(struct mtd_info *mtd) static void pmecc_get_sigma(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(nand_chip); int16_t *lmu = host->pmecc_lmu; int16_t *si = host->pmecc_si; @@ -752,7 +752,7 @@ static void pmecc_get_sigma(struct mtd_info *mtd) static int pmecc_err_location(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(nand_chip); unsigned long end_time; const int cap = host->pmecc_corr_cap; const int num = 2 * cap + 1; @@ -804,7 +804,7 @@ static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc, int sector_num, int extra_bytes, int err_nbr) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(nand_chip); int i = 0; int byte_pos, bit_pos, sector_size, pos; uint32_t tmp; @@ -850,7 +850,7 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf, u8 *ecc) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(nand_chip); int i, err_nbr; uint8_t *buf_pos; int max_bitflips = 0; @@ -920,7 +920,7 @@ static void pmecc_enable(struct atmel_nand_host *host, int ecc_op) static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - struct atmel_nand_host *host = chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(chip); int eccsize = chip->ecc.size * chip->ecc.steps; uint8_t *oob = chip->oob_poi; uint32_t *eccpos = chip->ecc.layout->eccpos; @@ -958,7 +958,7 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd, struct nand_chip *chip, const uint8_t *buf, int oob_required, int page) { - struct atmel_nand_host *host = chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(chip); uint32_t *eccpos = chip->ecc.layout->eccpos; int i, j; unsigned long end_time; @@ -994,7 +994,7 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd, static void atmel_pmecc_core_init(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(nand_chip); uint32_t val = 0; struct nand_ecclayout *ecc_layout; @@ -1310,7 +1310,7 @@ static int atmel_nand_calculate(struct mtd_info *mtd, const u_char *dat, unsigned char *ecc_code) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(nand_chip); unsigned int ecc_value; /* get the first 2 ECC bytes */ @@ -1356,7 +1356,7 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, * Workaround: Reset the parity registers before reading the * actual data. */ - struct atmel_nand_host *host = chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(chip); if (host->board.need_reset_workaround) ecc_writel(host->ecc, CR, ATMEL_ECC_RST); @@ -1414,7 +1414,7 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *isnull) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(nand_chip); unsigned int ecc_status; unsigned int ecc_word, ecc_bit; @@ -1480,7 +1480,7 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(nand_chip); if (host->board.need_reset_workaround) ecc_writel(host->ecc, CR, ATMEL_ECC_RST); @@ -1773,7 +1773,7 @@ static int nfc_device_ready(struct mtd_info *mtd) { u32 status, mask; struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(nand_chip); status = nfc_read_status(host); mask = nfc_readl(host->nfc->hsmc_regs, IMR); @@ -1789,7 +1789,7 @@ static int nfc_device_ready(struct mtd_info *mtd) static void nfc_select_chip(struct mtd_info *mtd, int chip) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(nand_chip); if (chip == -1) nfc_writel(host->nfc->hsmc_regs, CTRL, NFC_CTRL_DISABLE); @@ -1841,7 +1841,7 @@ static void nfc_nand_command(struct mtd_info *mtd, unsigned int command, int column, int page_addr) { struct nand_chip *chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(chip); unsigned long timeout; unsigned int nfc_addr_cmd = 0; @@ -1967,7 +1967,7 @@ static int nfc_sram_write_page(struct mtd_info *mtd, struct nand_chip *chip, { int cfg, len; int status = 0; - struct atmel_nand_host *host = chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(chip); void *sram = host->nfc->sram_bank0 + nfc_get_sram_off(host); /* Subpage write is not supported */ @@ -2028,7 +2028,7 @@ static int nfc_sram_write_page(struct mtd_info *mtd, struct nand_chip *chip, static int nfc_sram_init(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct atmel_nand_host *host = chip->priv; + struct atmel_nand_host *host = nand_get_controller_data(chip); int res = 0; /* Initialize the NFC CFG register */ @@ -2127,7 +2127,8 @@ static int atmel_nand_probe(struct platform_device *pdev) sizeof(struct atmel_nand_data)); } - nand_chip->priv = host; /* link the private data structures */ + /* link the private data structures */ + nand_set_controller_data(nand_chip, host); mtd->dev.parent = &pdev->dev; /* Set address of NAND IO lines */ diff --git a/drivers/mtd/nand/bcm47xxnflash/main.c b/drivers/mtd/nand/bcm47xxnflash/main.c index b44f821b1a3a9..fb31429b70a9a 100644 --- a/drivers/mtd/nand/bcm47xxnflash/main.c +++ b/drivers/mtd/nand/bcm47xxnflash/main.c @@ -34,7 +34,7 @@ static int bcm47xxnflash_probe(struct platform_device *pdev) if (!b47n) return -ENOMEM; - b47n->nand_chip.priv = b47n; + nand_set_controller_data(&b47n->nand_chip, b47n); mtd = nand_to_mtd(&b47n->nand_chip); mtd->dev.parent = &pdev->dev; b47n->cc = container_of(nflash, struct bcma_drv_cc, nflash); diff --git a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c index 652478035a7de..f1da4ea88f2c0 100644 --- a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c +++ b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c @@ -90,7 +90,7 @@ static void bcm47xxnflash_ops_bcm4706_read(struct mtd_info *mtd, uint8_t *buf, int len) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; + struct bcm47xxnflash *b47n = nand_get_controller_data(nand_chip); u32 ctlcode; u32 *dest = (u32 *)buf; @@ -140,7 +140,7 @@ static void bcm47xxnflash_ops_bcm4706_write(struct mtd_info *mtd, const uint8_t *buf, int len) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; + struct bcm47xxnflash *b47n = nand_get_controller_data(nand_chip); struct bcma_drv_cc *cc = b47n->cc; u32 ctlcode; @@ -174,7 +174,7 @@ static void bcm47xxnflash_ops_bcm4706_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; + struct bcm47xxnflash *b47n = nand_get_controller_data(nand_chip); u32 code = 0; if (cmd == NAND_CMD_NONE) @@ -200,7 +200,7 @@ static void bcm47xxnflash_ops_bcm4706_select_chip(struct mtd_info *mtd, static int bcm47xxnflash_ops_bcm4706_dev_ready(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; + struct bcm47xxnflash *b47n = nand_get_controller_data(nand_chip); return !!(bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_CTL) & NCTL_READY); } @@ -217,7 +217,7 @@ static void bcm47xxnflash_ops_bcm4706_cmdfunc(struct mtd_info *mtd, int page_addr) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; + struct bcm47xxnflash *b47n = nand_get_controller_data(nand_chip); struct bcma_drv_cc *cc = b47n->cc; u32 ctlcode; int i; @@ -313,7 +313,7 @@ static void bcm47xxnflash_ops_bcm4706_cmdfunc(struct mtd_info *mtd, static u8 bcm47xxnflash_ops_bcm4706_read_byte(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; + struct bcm47xxnflash *b47n = nand_get_controller_data(nand_chip); struct bcma_drv_cc *cc = b47n->cc; u32 tmp = 0; @@ -342,7 +342,7 @@ static void bcm47xxnflash_ops_bcm4706_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; + struct bcm47xxnflash *b47n = nand_get_controller_data(nand_chip); switch (b47n->curr_command) { case NAND_CMD_READ0: @@ -358,7 +358,7 @@ static void bcm47xxnflash_ops_bcm4706_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; + struct bcm47xxnflash *b47n = nand_get_controller_data(nand_chip); switch (b47n->curr_command) { case NAND_CMD_SEQIN: diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index 89d9414c5593b..7f6b30e615b7f 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c @@ -781,7 +781,7 @@ static int bf5xx_nand_probe(struct platform_device *pdev) chip->cmd_ctrl = bf5xx_nand_hwcontrol; chip->dev_ready = bf5xx_nand_devready; - chip->priv = mtd; + nand_set_controller_data(chip, mtd); chip->controller = &info->controller; chip->IO_ADDR_R = (void __iomem *) NFC_READ; diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index aea08816d3ac9..844fc07d22cd4 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -877,7 +877,7 @@ static struct nand_ecclayout *brcmstb_choose_ecc_layout( static void brcmnand_wp(struct mtd_info *mtd, int wp) { struct nand_chip *chip = mtd_to_nand(mtd); - struct brcmnand_host *host = chip->priv; + struct brcmnand_host *host = nand_get_controller_data(chip); struct brcmnand_controller *ctrl = host->ctrl; if ((ctrl->features & BRCMNAND_HAS_WP) && wp_on == 1) { @@ -1043,7 +1043,7 @@ static void brcmnand_cmd_ctrl(struct mtd_info *mtd, int dat, static int brcmnand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) { struct nand_chip *chip = mtd_to_nand(mtd); - struct brcmnand_host *host = chip->priv; + struct brcmnand_host *host = nand_get_controller_data(chip); struct brcmnand_controller *ctrl = host->ctrl; unsigned long timeo = msecs_to_jiffies(100); @@ -1117,7 +1117,7 @@ static void brcmnand_cmdfunc(struct mtd_info *mtd, unsigned command, int column, int page_addr) { struct nand_chip *chip = mtd_to_nand(mtd); - struct brcmnand_host *host = chip->priv; + struct brcmnand_host *host = nand_get_controller_data(chip); struct brcmnand_controller *ctrl = host->ctrl; u64 addr = (u64)page_addr << chip->page_shift; int native_cmd = 0; @@ -1223,7 +1223,7 @@ static void brcmnand_cmdfunc(struct mtd_info *mtd, unsigned command, static uint8_t brcmnand_read_byte(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct brcmnand_host *host = chip->priv; + struct brcmnand_host *host = nand_get_controller_data(chip); struct brcmnand_controller *ctrl = host->ctrl; uint8_t ret = 0; int addr, offs; @@ -1290,7 +1290,7 @@ static void brcmnand_write_buf(struct mtd_info *mtd, const uint8_t *buf, { int i; struct nand_chip *chip = mtd_to_nand(mtd); - struct brcmnand_host *host = chip->priv; + struct brcmnand_host *host = nand_get_controller_data(chip); switch (host->last_cmd) { case NAND_CMD_SET_FEATURES: @@ -1400,7 +1400,7 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip, u64 addr, unsigned int trans, u32 *buf, u8 *oob, u64 *err_addr) { - struct brcmnand_host *host = chip->priv; + struct brcmnand_host *host = nand_get_controller_data(chip); struct brcmnand_controller *ctrl = host->ctrl; int i, j, ret = 0; @@ -1463,7 +1463,7 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip, static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip, u64 addr, unsigned int trans, u32 *buf, u8 *oob) { - struct brcmnand_host *host = chip->priv; + struct brcmnand_host *host = nand_get_controller_data(chip); struct brcmnand_controller *ctrl = host->ctrl; u64 err_addr = 0; int err; @@ -1513,7 +1513,7 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip, static int brcmnand_read_page(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - struct brcmnand_host *host = chip->priv; + struct brcmnand_host *host = nand_get_controller_data(chip); u8 *oob = oob_required ? (u8 *)chip->oob_poi : NULL; return brcmnand_read(mtd, chip, host->last_addr, @@ -1523,7 +1523,7 @@ static int brcmnand_read_page(struct mtd_info *mtd, struct nand_chip *chip, static int brcmnand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - struct brcmnand_host *host = chip->priv; + struct brcmnand_host *host = nand_get_controller_data(chip); u8 *oob = oob_required ? (u8 *)chip->oob_poi : NULL; int ret; @@ -1545,7 +1545,7 @@ static int brcmnand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, static int brcmnand_read_oob_raw(struct mtd_info *mtd, struct nand_chip *chip, int page) { - struct brcmnand_host *host = chip->priv; + struct brcmnand_host *host = nand_get_controller_data(chip); brcmnand_set_ecc_enabled(host, 0); brcmnand_read(mtd, chip, (u64)page << chip->page_shift, @@ -1558,7 +1558,7 @@ static int brcmnand_read_oob_raw(struct mtd_info *mtd, struct nand_chip *chip, static int brcmnand_write(struct mtd_info *mtd, struct nand_chip *chip, u64 addr, const u32 *buf, u8 *oob) { - struct brcmnand_host *host = chip->priv; + struct brcmnand_host *host = nand_get_controller_data(chip); struct brcmnand_controller *ctrl = host->ctrl; unsigned int i, j, trans = mtd->writesize >> FC_SHIFT; int status, ret = 0; @@ -1629,7 +1629,7 @@ out: static int brcmnand_write_page(struct mtd_info *mtd, struct nand_chip *chip, const uint8_t *buf, int oob_required, int page) { - struct brcmnand_host *host = chip->priv; + struct brcmnand_host *host = nand_get_controller_data(chip); void *oob = oob_required ? chip->oob_poi : NULL; brcmnand_write(mtd, chip, host->last_addr, (const u32 *)buf, oob); @@ -1640,7 +1640,7 @@ static int brcmnand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, const uint8_t *buf, int oob_required, int page) { - struct brcmnand_host *host = chip->priv; + struct brcmnand_host *host = nand_get_controller_data(chip); void *oob = oob_required ? chip->oob_poi : NULL; brcmnand_set_ecc_enabled(host, 0); @@ -1659,7 +1659,7 @@ static int brcmnand_write_oob(struct mtd_info *mtd, struct nand_chip *chip, static int brcmnand_write_oob_raw(struct mtd_info *mtd, struct nand_chip *chip, int page) { - struct brcmnand_host *host = chip->priv; + struct brcmnand_host *host = nand_get_controller_data(chip); int ret; brcmnand_set_ecc_enabled(host, 0); @@ -1923,7 +1923,7 @@ static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn) chip = &host->chip; nand_set_flash_node(chip, dn); - chip->priv = host; + nand_set_controller_data(chip, host); mtd->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "brcmnand.%d", host->cs); mtd->owner = THIS_MODULE; diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 00c15e22d8277..aa1a616b9fb6a 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c @@ -102,7 +102,7 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; static int cafe_device_ready(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct cafe_priv *cafe = chip->priv; + struct cafe_priv *cafe = nand_get_controller_data(chip); int result = !!(cafe_readl(cafe, NAND_STATUS) & 0x40000000); uint32_t irqs = cafe_readl(cafe, NAND_IRQ); @@ -119,7 +119,7 @@ static int cafe_device_ready(struct mtd_info *mtd) static void cafe_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct cafe_priv *cafe = chip->priv; + struct cafe_priv *cafe = nand_get_controller_data(chip); if (usedma) memcpy(cafe->dmabuf + cafe->datalen, buf, len); @@ -135,7 +135,7 @@ static void cafe_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) static void cafe_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct cafe_priv *cafe = chip->priv; + struct cafe_priv *cafe = nand_get_controller_data(chip); if (usedma) memcpy(buf, cafe->dmabuf + cafe->datalen, len); @@ -150,7 +150,7 @@ static void cafe_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static uint8_t cafe_read_byte(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct cafe_priv *cafe = chip->priv; + struct cafe_priv *cafe = nand_get_controller_data(chip); uint8_t d; cafe_read_buf(mtd, &d, 1); @@ -163,7 +163,7 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command, int column, int page_addr) { struct nand_chip *chip = mtd_to_nand(mtd); - struct cafe_priv *cafe = chip->priv; + struct cafe_priv *cafe = nand_get_controller_data(chip); int adrbytes = 0; uint32_t ctl1; uint32_t doneint = 0x80000000; @@ -319,7 +319,7 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command, static void cafe_select_chip(struct mtd_info *mtd, int chipnr) { struct nand_chip *chip = mtd_to_nand(mtd); - struct cafe_priv *cafe = chip->priv; + struct cafe_priv *cafe = nand_get_controller_data(chip); cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr); @@ -335,7 +335,7 @@ static irqreturn_t cafe_nand_interrupt(int irq, void *id) { struct mtd_info *mtd = id; struct nand_chip *chip = mtd_to_nand(mtd); - struct cafe_priv *cafe = chip->priv; + struct cafe_priv *cafe = nand_get_controller_data(chip); uint32_t irqs = cafe_readl(cafe, NAND_IRQ); cafe_writel(cafe, irqs & ~0x90000000, NAND_IRQ); if (!irqs) @@ -384,7 +384,7 @@ static int cafe_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - struct cafe_priv *cafe = chip->priv; + struct cafe_priv *cafe = nand_get_controller_data(chip); unsigned int max_bitflips = 0; cafe_dev_dbg(&cafe->pdev->dev, "ECC result %08x SYN1,2 %08x\n", @@ -526,7 +526,7 @@ static int cafe_nand_write_page_lowlevel(struct mtd_info *mtd, const uint8_t *buf, int oob_required, int page) { - struct cafe_priv *cafe = chip->priv; + struct cafe_priv *cafe = nand_get_controller_data(chip); chip->write_buf(mtd, buf, mtd->writesize); chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); @@ -611,7 +611,7 @@ static int cafe_nand_probe(struct pci_dev *pdev, mtd = nand_to_mtd(&cafe->nand); mtd->dev.parent = &pdev->dev; - cafe->nand.priv = cafe; + nand_set_controller_data(&cafe->nand, cafe); cafe->pdev = pdev; cafe->mmio = pci_iomap(pdev, 0, 0); @@ -800,7 +800,7 @@ static void cafe_nand_remove(struct pci_dev *pdev) { struct mtd_info *mtd = pci_get_drvdata(pdev); struct nand_chip *chip = mtd_to_nand(mtd); - struct cafe_priv *cafe = chip->priv; + struct cafe_priv *cafe = nand_get_controller_data(chip); /* Disable NAND IRQ in global IRQ mask register */ cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK); @@ -828,7 +828,7 @@ static int cafe_nand_resume(struct pci_dev *pdev) uint32_t ctrl; struct mtd_info *mtd = pci_get_drvdata(pdev); struct nand_chip *chip = mtd_to_nand(mtd); - struct cafe_priv *cafe = chip->priv; + struct cafe_priv *cafe = nand_get_controller_data(chip); /* Start off by resetting the NAND controller completely */ cafe_writel(cafe, 1, NAND_RESET); diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index 4f4aa3555a6fa..f170f3c31b344 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -296,7 +296,7 @@ static inline int DoC_WaitReady(struct doc_priv *doc) static void doc2000_write_byte(struct mtd_info *mtd, u_char datum) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; if (debug) @@ -308,7 +308,7 @@ static void doc2000_write_byte(struct mtd_info *mtd, u_char datum) static u_char doc2000_read_byte(struct mtd_info *mtd) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; u_char ret; @@ -323,7 +323,7 @@ static u_char doc2000_read_byte(struct mtd_info *mtd) static void doc2000_writebuf(struct mtd_info *mtd, const u_char *buf, int len) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; int i; if (debug) @@ -340,7 +340,7 @@ static void doc2000_writebuf(struct mtd_info *mtd, const u_char *buf, int len) static void doc2000_readbuf(struct mtd_info *mtd, u_char *buf, int len) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; int i; @@ -355,7 +355,7 @@ static void doc2000_readbuf(struct mtd_info *mtd, u_char *buf, int len) static void doc2000_readbuf_dword(struct mtd_info *mtd, u_char *buf, int len) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; int i; @@ -376,7 +376,7 @@ static void doc2000_readbuf_dword(struct mtd_info *mtd, u_char *buf, int len) static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); uint16_t ret; doc200x_select_chip(mtd, nr); @@ -422,7 +422,7 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) static void __init doc2000_count_chips(struct mtd_info *mtd) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); uint16_t mfrid; int i; @@ -443,7 +443,7 @@ static void __init doc2000_count_chips(struct mtd_info *mtd) static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this) { - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); int status; @@ -458,7 +458,7 @@ static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this) static void doc2001_write_byte(struct mtd_info *mtd, u_char datum) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; WriteDOC(datum, docptr, CDSNSlowIO); @@ -469,7 +469,7 @@ static void doc2001_write_byte(struct mtd_info *mtd, u_char datum) static u_char doc2001_read_byte(struct mtd_info *mtd) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; //ReadDOC(docptr, CDSNSlowIO); @@ -483,7 +483,7 @@ static u_char doc2001_read_byte(struct mtd_info *mtd) static void doc2001_writebuf(struct mtd_info *mtd, const u_char *buf, int len) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; int i; @@ -496,7 +496,7 @@ static void doc2001_writebuf(struct mtd_info *mtd, const u_char *buf, int len) static void doc2001_readbuf(struct mtd_info *mtd, u_char *buf, int len) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; int i; @@ -513,7 +513,7 @@ static void doc2001_readbuf(struct mtd_info *mtd, u_char *buf, int len) static u_char doc2001plus_read_byte(struct mtd_info *mtd) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; u_char ret; @@ -528,7 +528,7 @@ static u_char doc2001plus_read_byte(struct mtd_info *mtd) static void doc2001plus_writebuf(struct mtd_info *mtd, const u_char *buf, int len) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; int i; @@ -546,7 +546,7 @@ static void doc2001plus_writebuf(struct mtd_info *mtd, const u_char *buf, int le static void doc2001plus_readbuf(struct mtd_info *mtd, u_char *buf, int len) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; int i; @@ -577,7 +577,7 @@ static void doc2001plus_readbuf(struct mtd_info *mtd, u_char *buf, int len) static void doc2001plus_select_chip(struct mtd_info *mtd, int chip) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; int floor = 0; @@ -604,7 +604,7 @@ static void doc2001plus_select_chip(struct mtd_info *mtd, int chip) static void doc200x_select_chip(struct mtd_info *mtd, int chip) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; int floor = 0; @@ -635,7 +635,7 @@ static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; if (ctrl & NAND_CTRL_CHANGE) { @@ -658,7 +658,7 @@ static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd, static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; /* @@ -764,7 +764,7 @@ static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int colu static int doc200x_dev_ready(struct mtd_info *mtd) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; if (DoC_is_MillenniumPlus(doc)) { @@ -804,7 +804,7 @@ static int doc200x_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; /* Prime the ECC engine */ @@ -823,7 +823,7 @@ static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode) static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; /* Prime the ECC engine */ @@ -843,7 +843,7 @@ static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode) static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat, unsigned char *ecc_code) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; int i; int emptymatch = 1; @@ -904,7 +904,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, { int i, ret = 0; struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); void __iomem *docptr = doc->virtadr; uint8_t calc_ecc[6]; volatile u_char dummy; @@ -975,7 +975,7 @@ static struct nand_ecclayout doc200x_oobinfo = { static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const char *id, int findmirror) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); unsigned offs; int ret; size_t retlen; @@ -1018,7 +1018,7 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const ch static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partition *parts) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); int ret = 0; u_char *buf; struct NFTLMediaHeader *mh; @@ -1120,7 +1120,7 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partitio static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partition *parts) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); int ret = 0; u_char *buf; struct INFTLMediaHeader *mh; @@ -1240,7 +1240,7 @@ static int __init nftl_scan_bbt(struct mtd_info *mtd) { int ret, numparts; struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); struct mtd_partition parts[2]; memset((char *)parts, 0, sizeof(parts)); @@ -1275,7 +1275,7 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd) { int ret, numparts; struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); struct mtd_partition parts[5]; if (this->numchips > doc->chips_per_floor) { @@ -1328,7 +1328,7 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd) static inline int __init doc2000_init(struct mtd_info *mtd) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); this->read_byte = doc2000_read_byte; this->write_buf = doc2000_writebuf; @@ -1344,7 +1344,7 @@ static inline int __init doc2000_init(struct mtd_info *mtd) static inline int __init doc2001_init(struct mtd_info *mtd) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); this->read_byte = doc2001_read_byte; this->write_buf = doc2001_writebuf; @@ -1374,7 +1374,7 @@ static inline int __init doc2001_init(struct mtd_info *mtd) static inline int __init doc2001plus_init(struct mtd_info *mtd) { struct nand_chip *this = mtd_to_nand(mtd); - struct doc_priv *doc = this->priv; + struct doc_priv *doc = nand_get_controller_data(this); this->read_byte = doc2001plus_read_byte; this->write_buf = doc2001plus_writebuf; @@ -1491,7 +1491,7 @@ static int __init doc_probe(unsigned long physadr) unsigned char oldval; unsigned char newval; nand = mtd_to_nand(mtd); - doc = nand->priv; + doc = nand_get_controller_data(nand); /* Use the alias resolution register to determine if this is in fact the same DOC aliased to a new address. If writes to one chip's alias resolution register change the value on @@ -1538,7 +1538,7 @@ static int __init doc_probe(unsigned long physadr) mtd->owner = THIS_MODULE; - nand->priv = doc; + nand_set_controller_data(nand, doc); nand->select_chip = doc200x_select_chip; nand->cmd_ctrl = doc200x_hwcontrol; nand->dev_ready = doc200x_dev_ready; @@ -1611,7 +1611,7 @@ static void release_nanddoc(void) for (mtd = doclist; mtd; mtd = nextmtd) { nand = mtd_to_nand(mtd); - doc = nand->priv; + doc = nand_get_controller_data(nand); nextmtd = doc->nextdoc; nand_release(mtd); diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c index 95cd139e8a407..df4165b02c62e 100644 --- a/drivers/mtd/nand/docg4.c +++ b/drivers/mtd/nand/docg4.c @@ -297,7 +297,7 @@ static int poll_status(struct docg4_priv *doc) static int docg4_wait(struct mtd_info *mtd, struct nand_chip *nand) { - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); int status = NAND_STATUS_WP; /* inverse logic?? */ dev_dbg(doc->dev, "%s...\n", __func__); @@ -319,7 +319,7 @@ static void docg4_select_chip(struct mtd_info *mtd, int chip) * not yet supported, so the only valid non-negative value is 0. */ struct nand_chip *nand = mtd_to_nand(mtd); - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); void __iomem *docptr = doc->virtadr; dev_dbg(doc->dev, "%s: chip %d\n", __func__, chip); @@ -338,7 +338,7 @@ static void reset(struct mtd_info *mtd) /* full device reset */ struct nand_chip *nand = mtd_to_nand(mtd); - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); void __iomem *docptr = doc->virtadr; writew(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN, @@ -376,7 +376,7 @@ static int correct_data(struct mtd_info *mtd, uint8_t *buf, int page) */ struct nand_chip *nand = mtd_to_nand(mtd); - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); void __iomem *docptr = doc->virtadr; int i, numerrs, errpos[4]; const uint8_t blank_read_hwecc[8] = { @@ -465,7 +465,7 @@ static int correct_data(struct mtd_info *mtd, uint8_t *buf, int page) static uint8_t docg4_read_byte(struct mtd_info *mtd) { struct nand_chip *nand = mtd_to_nand(mtd); - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); dev_dbg(doc->dev, "%s\n", __func__); @@ -546,7 +546,7 @@ static int pageprog(struct mtd_info *mtd) */ struct nand_chip *nand = mtd_to_nand(mtd); - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); void __iomem *docptr = doc->virtadr; int retval = 0; @@ -583,7 +583,7 @@ static void sequence_reset(struct mtd_info *mtd) /* common starting sequence for all operations */ struct nand_chip *nand = mtd_to_nand(mtd); - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); void __iomem *docptr = doc->virtadr; writew(DOC_CTRL_UNKNOWN | DOC_CTRL_CE, docptr + DOC_FLASHCONTROL); @@ -600,7 +600,7 @@ static void read_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr) /* first step in reading a page */ struct nand_chip *nand = mtd_to_nand(mtd); - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); void __iomem *docptr = doc->virtadr; dev_dbg(doc->dev, @@ -627,7 +627,7 @@ static void write_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr) /* first step in writing a page */ struct nand_chip *nand = mtd_to_nand(mtd); - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); void __iomem *docptr = doc->virtadr; dev_dbg(doc->dev, @@ -692,7 +692,7 @@ static void docg4_command(struct mtd_info *mtd, unsigned command, int column, /* handle standard nand commands */ struct nand_chip *nand = mtd_to_nand(mtd); - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); uint32_t g4_addr = mtd_to_docg4_address(page_addr, column); dev_dbg(doc->dev, "%s %x, page_addr=%x, column=%x\n", @@ -756,7 +756,7 @@ static void docg4_command(struct mtd_info *mtd, unsigned command, int column, static int read_page(struct mtd_info *mtd, struct nand_chip *nand, uint8_t *buf, int page, bool use_ecc) { - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); void __iomem *docptr = doc->virtadr; uint16_t status, edc_err, *buf16; int bits_corrected = 0; @@ -836,7 +836,7 @@ static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand, static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand, int page) { - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); void __iomem *docptr = doc->virtadr; uint16_t status; @@ -875,7 +875,7 @@ static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand, static int docg4_erase_block(struct mtd_info *mtd, int page) { struct nand_chip *nand = mtd_to_nand(mtd); - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); void __iomem *docptr = doc->virtadr; uint16_t g4_page; @@ -923,7 +923,7 @@ static int docg4_erase_block(struct mtd_info *mtd, int page) static int write_page(struct mtd_info *mtd, struct nand_chip *nand, const uint8_t *buf, bool use_ecc) { - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); void __iomem *docptr = doc->virtadr; uint8_t ecc_buf[8]; @@ -1003,7 +1003,7 @@ static int docg4_write_oob(struct mtd_info *mtd, struct nand_chip *nand, */ /* note that bytes 7..14 are hw generated hamming/ecc and overwritten */ - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); doc->oob_page = page; memcpy(doc->oob_buf, nand->oob_poi, 16); return 0; @@ -1017,7 +1017,7 @@ static int __init read_factory_bbt(struct mtd_info *mtd) */ struct nand_chip *nand = mtd_to_nand(mtd); - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0); uint8_t *buf; int i, block; @@ -1090,7 +1090,7 @@ static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs) int ret, i; uint8_t *buf; struct nand_chip *nand = mtd_to_nand(mtd); - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); struct nand_bbt_descr *bbtd = nand->badblock_pattern; int page = (int)(ofs >> nand->page_shift); uint32_t g4_addr = mtd_to_docg4_address(page, 0); @@ -1203,7 +1203,7 @@ static void __init init_mtd_structs(struct mtd_info *mtd) */ struct nand_chip *nand = mtd_to_nand(mtd); - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); mtd->size = DOCG4_CHIP_SIZE; mtd->name = "Msys_Diskonchip_G4"; @@ -1262,7 +1262,7 @@ static void __init init_mtd_structs(struct mtd_info *mtd) static int __init read_id_reg(struct mtd_info *mtd) { struct nand_chip *nand = mtd_to_nand(mtd); - struct docg4_priv *doc = nand->priv; + struct docg4_priv *doc = nand_get_controller_data(nand); void __iomem *docptr = doc->virtadr; uint16_t id1, id2; @@ -1314,7 +1314,7 @@ static int __init probe_docg4(struct platform_device *pdev) mtd = nand_to_mtd(nand); doc = (struct docg4_priv *) (nand + 1); - nand->priv = doc; + nand_set_controller_data(nand, doc); mtd->dev.parent = &pdev->dev; doc->virtadr = virtadr; doc->dev = dev; diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index e96d5bcc29221..059d5f7ec1248 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -144,7 +144,7 @@ static struct nand_bbt_descr bbt_mirror_descr = { static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) { struct nand_chip *chip = mtd_to_nand(mtd); - struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_lbc_ctrl *ctrl = priv->ctrl; struct fsl_lbc_regs __iomem *lbc = ctrl->regs; struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; @@ -195,7 +195,7 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) static int fsl_elbc_run_command(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_lbc_ctrl *ctrl = priv->ctrl; struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; struct fsl_lbc_regs __iomem *lbc = ctrl->regs; @@ -267,7 +267,7 @@ static int fsl_elbc_run_command(struct mtd_info *mtd) static void fsl_elbc_do_read(struct nand_chip *chip, int oob) { - struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_lbc_ctrl *ctrl = priv->ctrl; struct fsl_lbc_regs __iomem *lbc = ctrl->regs; @@ -300,7 +300,7 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, int column, int page_addr) { struct nand_chip *chip = mtd_to_nand(mtd); - struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_lbc_ctrl *ctrl = priv->ctrl; struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; struct fsl_lbc_regs __iomem *lbc = ctrl->regs; @@ -525,7 +525,7 @@ static void fsl_elbc_select_chip(struct mtd_info *mtd, int chip) static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; unsigned int bufsize = mtd->writesize + mtd->oobsize; @@ -563,7 +563,7 @@ static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) static u8 fsl_elbc_read_byte(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; /* If there are still bytes in the FCM, then use the next byte. */ @@ -580,7 +580,7 @@ static u8 fsl_elbc_read_byte(struct mtd_info *mtd) static void fsl_elbc_read_buf(struct mtd_info *mtd, u8 *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; int avail; @@ -604,7 +604,7 @@ static void fsl_elbc_read_buf(struct mtd_info *mtd, u8 *buf, int len) */ static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip) { - struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; if (elbc_fcm_ctrl->status != LTESR_CC) @@ -619,7 +619,7 @@ static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip) static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_lbc_ctrl *ctrl = priv->ctrl; struct fsl_lbc_regs __iomem *lbc = ctrl->regs; unsigned int al; @@ -696,7 +696,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) static int fsl_elbc_read_page(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_lbc_ctrl *ctrl = priv->ctrl; struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; @@ -770,7 +770,7 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) chip->bbt_options = NAND_BBT_USE_FLASH; chip->controller = &elbc_fcm_ctrl->controller; - chip->priv = priv; + nand_set_controller_data(chip, priv); chip->ecc.read_page = fsl_elbc_read_page; chip->ecc.write_page = fsl_elbc_write_page; diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 9d2b4ed06c81e..43f5a3a4873f2 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -230,7 +230,7 @@ static struct nand_bbt_descr bbt_mirror_descr = { static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) { struct nand_chip *chip = mtd_to_nand(mtd); - struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); struct fsl_ifc_ctrl *ctrl = priv->ctrl; struct fsl_ifc_regs __iomem *ifc = ctrl->regs; int buf_num; @@ -253,7 +253,7 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) static int is_blank(struct mtd_info *mtd, unsigned int bufnum) { struct nand_chip *chip = mtd_to_nand(mtd); - struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); u8 __iomem *addr = priv->vbase + bufnum * (mtd->writesize * 2); u32 __iomem *mainarea = (u32 __iomem *)addr; u8 __iomem *oob = addr + mtd->writesize; @@ -292,7 +292,7 @@ static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl, static void fsl_ifc_run_command(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); struct fsl_ifc_ctrl *ctrl = priv->ctrl; struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl; struct fsl_ifc_regs __iomem *ifc = ctrl->regs; @@ -369,7 +369,7 @@ static void fsl_ifc_do_read(struct nand_chip *chip, int oob, struct mtd_info *mtd) { - struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); struct fsl_ifc_ctrl *ctrl = priv->ctrl; struct fsl_ifc_regs __iomem *ifc = ctrl->regs; @@ -409,7 +409,7 @@ static void fsl_ifc_do_read(struct nand_chip *chip, static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command, int column, int page_addr) { struct nand_chip *chip = mtd_to_nand(mtd); - struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); struct fsl_ifc_ctrl *ctrl = priv->ctrl; struct fsl_ifc_regs __iomem *ifc = ctrl->regs; @@ -624,7 +624,7 @@ static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip) static void fsl_ifc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); unsigned int bufsize = mtd->writesize + mtd->oobsize; if (len <= 0) { @@ -650,7 +650,7 @@ static void fsl_ifc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) static uint8_t fsl_ifc_read_byte(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); unsigned int offset; /* @@ -673,7 +673,7 @@ static uint8_t fsl_ifc_read_byte(struct mtd_info *mtd) static uint8_t fsl_ifc_read_byte16(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); uint16_t data; /* @@ -696,7 +696,7 @@ static uint8_t fsl_ifc_read_byte16(struct mtd_info *mtd) static void fsl_ifc_read_buf(struct mtd_info *mtd, u8 *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); int avail; if (len < 0) { @@ -721,7 +721,7 @@ static void fsl_ifc_read_buf(struct mtd_info *mtd, u8 *buf, int len) */ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip) { - struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); struct fsl_ifc_ctrl *ctrl = priv->ctrl; struct fsl_ifc_regs __iomem *ifc = ctrl->regs; u32 nand_fsr; @@ -750,7 +750,7 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip) static int fsl_ifc_read_page(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); struct fsl_ifc_ctrl *ctrl = priv->ctrl; struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl; @@ -782,7 +782,7 @@ static int fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip, static int fsl_ifc_chip_init_tail(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); dev_dbg(priv->dev, "%s: nand->numchips = %d\n", __func__, chip->numchips); @@ -914,7 +914,7 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv) } chip->controller = &ifc_nand_ctrl->controller; - chip->priv = priv; + nand_set_controller_data(chip, priv); chip->ecc.read_page = fsl_ifc_read_page; chip->ecc.write_page = fsl_ifc_write_page; diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 9a7c1f5ffcaaf..1bdcd4fa26d4b 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -1009,7 +1009,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) /* Link all private pointers */ mtd = nand_to_mtd(&host->nand); nand = &host->nand; - nand->priv = host; + nand_set_controller_data(nand, host); nand_set_flash_node(nand, np); mtd->dev.parent = &pdev->dev; diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index df61f49d37709..235ddcb58f399 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -857,7 +857,7 @@ error_alloc: static void gpmi_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl) { struct nand_chip *chip = mtd_to_nand(mtd); - struct gpmi_nand_data *this = chip->priv; + struct gpmi_nand_data *this = nand_get_controller_data(chip); int ret; /* @@ -891,7 +891,7 @@ static void gpmi_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl) static int gpmi_dev_ready(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct gpmi_nand_data *this = chip->priv; + struct gpmi_nand_data *this = nand_get_controller_data(chip); return gpmi_is_ready(this, this->current_chip); } @@ -899,7 +899,7 @@ static int gpmi_dev_ready(struct mtd_info *mtd) static void gpmi_select_chip(struct mtd_info *mtd, int chipnr) { struct nand_chip *chip = mtd_to_nand(mtd); - struct gpmi_nand_data *this = chip->priv; + struct gpmi_nand_data *this = nand_get_controller_data(chip); if ((this->current_chip < 0) && (chipnr >= 0)) gpmi_begin(this); @@ -912,7 +912,7 @@ static void gpmi_select_chip(struct mtd_info *mtd, int chipnr) static void gpmi_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct gpmi_nand_data *this = chip->priv; + struct gpmi_nand_data *this = nand_get_controller_data(chip); dev_dbg(this->dev, "len is %d\n", len); this->upper_buf = buf; @@ -924,7 +924,7 @@ static void gpmi_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static void gpmi_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct gpmi_nand_data *this = chip->priv; + struct gpmi_nand_data *this = nand_get_controller_data(chip); dev_dbg(this->dev, "len is %d\n", len); this->upper_buf = (uint8_t *)buf; @@ -936,7 +936,7 @@ static void gpmi_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) static uint8_t gpmi_read_byte(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct gpmi_nand_data *this = chip->priv; + struct gpmi_nand_data *this = nand_get_controller_data(chip); uint8_t *buf = this->data_buffer_dma; gpmi_read_buf(mtd, buf, 1); @@ -994,7 +994,7 @@ static void block_mark_swapping(struct gpmi_nand_data *this, static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - struct gpmi_nand_data *this = chip->priv; + struct gpmi_nand_data *this = nand_get_controller_data(chip); struct bch_geometry *nfc_geo = &this->bch_geometry; void *payload_virt; dma_addr_t payload_phys; @@ -1074,7 +1074,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint32_t offs, uint32_t len, uint8_t *buf, int page) { - struct gpmi_nand_data *this = chip->priv; + struct gpmi_nand_data *this = nand_get_controller_data(chip); void __iomem *bch_regs = this->resources.bch_regs; struct bch_geometry old_geo = this->bch_geometry; struct bch_geometry *geo = &this->bch_geometry; @@ -1162,7 +1162,7 @@ static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip, const uint8_t *buf, int oob_required, int page) { - struct gpmi_nand_data *this = chip->priv; + struct gpmi_nand_data *this = nand_get_controller_data(chip); struct bch_geometry *nfc_geo = &this->bch_geometry; const void *payload_virt; dma_addr_t payload_phys; @@ -1298,7 +1298,7 @@ exit_auxiliary: static int gpmi_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *chip, int page) { - struct gpmi_nand_data *this = chip->priv; + struct gpmi_nand_data *this = nand_get_controller_data(chip); dev_dbg(this->dev, "page number is %d\n", page); /* clear the OOB buffer */ @@ -1359,7 +1359,7 @@ static int gpmi_ecc_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - struct gpmi_nand_data *this = chip->priv; + struct gpmi_nand_data *this = nand_get_controller_data(chip); struct bch_geometry *nfc_geo = &this->bch_geometry; int eccsize = nfc_geo->ecc_chunk_size; int eccbits = nfc_geo->ecc_strength * nfc_geo->gf_len; @@ -1448,7 +1448,7 @@ static int gpmi_ecc_write_page_raw(struct mtd_info *mtd, const uint8_t *buf, int oob_required, int page) { - struct gpmi_nand_data *this = chip->priv; + struct gpmi_nand_data *this = nand_get_controller_data(chip); struct bch_geometry *nfc_geo = &this->bch_geometry; int eccsize = nfc_geo->ecc_chunk_size; int eccbits = nfc_geo->ecc_strength * nfc_geo->gf_len; @@ -1539,7 +1539,7 @@ static int gpmi_ecc_write_oob_raw(struct mtd_info *mtd, struct nand_chip *chip, static int gpmi_block_markbad(struct mtd_info *mtd, loff_t ofs) { struct nand_chip *chip = mtd_to_nand(mtd); - struct gpmi_nand_data *this = chip->priv; + struct gpmi_nand_data *this = nand_get_controller_data(chip); int ret = 0; uint8_t *block_mark; int column, page, status, chipnr; @@ -1897,7 +1897,7 @@ static int gpmi_nand_init(struct gpmi_nand_data *this) mtd->dev.parent = this->dev; /* init the nand_chip{}, we don't support a 16-bit NAND Flash bus. */ - chip->priv = this; + nand_set_controller_data(chip, this); nand_set_flash_node(chip, this->pdev->dev.of_node); chip->select_chip = gpmi_select_chip; chip->cmd_ctrl = gpmi_cmd_ctrl; diff --git a/drivers/mtd/nand/hisi504_nand.c b/drivers/mtd/nand/hisi504_nand.c index 2aee212b6169c..f8d37f36a81c7 100644 --- a/drivers/mtd/nand/hisi504_nand.c +++ b/drivers/mtd/nand/hisi504_nand.c @@ -357,7 +357,7 @@ static int hisi_nfc_send_cmd_reset(struct hinfc_host *host, int chipselect) static void hisi_nfc_select_chip(struct mtd_info *mtd, int chipselect) { struct nand_chip *chip = mtd_to_nand(mtd); - struct hinfc_host *host = chip->priv; + struct hinfc_host *host = nand_get_controller_data(chip); if (chipselect < 0) return; @@ -368,7 +368,7 @@ static void hisi_nfc_select_chip(struct mtd_info *mtd, int chipselect) static uint8_t hisi_nfc_read_byte(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct hinfc_host *host = chip->priv; + struct hinfc_host *host = nand_get_controller_data(chip); if (host->command == NAND_CMD_STATUS) return *(uint8_t *)(host->mmio); @@ -384,7 +384,7 @@ static uint8_t hisi_nfc_read_byte(struct mtd_info *mtd) static u16 hisi_nfc_read_word(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct hinfc_host *host = chip->priv; + struct hinfc_host *host = nand_get_controller_data(chip); host->offset += 2; return *(u16 *)(host->buffer + host->offset - 2); @@ -394,7 +394,7 @@ static void hisi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct hinfc_host *host = chip->priv; + struct hinfc_host *host = nand_get_controller_data(chip); memcpy(host->buffer + host->offset, buf, len); host->offset += len; @@ -403,7 +403,7 @@ hisi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) static void hisi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct hinfc_host *host = chip->priv; + struct hinfc_host *host = nand_get_controller_data(chip); memcpy(buf, host->buffer + host->offset, len); host->offset += len; @@ -412,7 +412,7 @@ static void hisi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static void set_addr(struct mtd_info *mtd, int column, int page_addr) { struct nand_chip *chip = mtd_to_nand(mtd); - struct hinfc_host *host = chip->priv; + struct hinfc_host *host = nand_get_controller_data(chip); unsigned int command = host->command; host->addr_cycle = 0; @@ -448,7 +448,7 @@ static void hisi_nfc_cmdfunc(struct mtd_info *mtd, unsigned command, int column, int page_addr) { struct nand_chip *chip = mtd_to_nand(mtd); - struct hinfc_host *host = chip->priv; + struct hinfc_host *host = nand_get_controller_data(chip); int is_cache_invalid = 1; unsigned int flag = 0; @@ -542,7 +542,7 @@ static irqreturn_t hinfc_irq_handle(int irq, void *devid) static int hisi_nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - struct hinfc_host *host = chip->priv; + struct hinfc_host *host = nand_get_controller_data(chip); int max_bitflips = 0, stat = 0, stat_max = 0, status_ecc; int stat_1, stat_2; @@ -574,7 +574,7 @@ static int hisi_nand_read_page_hwecc(struct mtd_info *mtd, static int hisi_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, int page) { - struct hinfc_host *host = chip->priv; + struct hinfc_host *host = nand_get_controller_data(chip); chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); @@ -738,7 +738,7 @@ static int hisi_nfc_probe(struct platform_device *pdev) mtd->name = "hisi_nand"; mtd->dev.parent = &pdev->dev; - chip->priv = host; + nand_set_controller_data(chip, host); nand_set_flash_node(chip, np); chip->cmdfunc = hisi_nfc_cmdfunc; chip->select_chip = hisi_nfc_select_chip; diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c index db59fa28d5c86..9bc435d72a861 100644 --- a/drivers/mtd/nand/lpc32xx_mlc.c +++ b/drivers/mtd/nand/lpc32xx_mlc.c @@ -275,7 +275,7 @@ static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct lpc32xx_nand_host *host = nand_chip->priv; + struct lpc32xx_nand_host *host = nand_get_controller_data(nand_chip); if (cmd != NAND_CMD_NONE) { if (ctrl & NAND_CLE) @@ -291,7 +291,7 @@ static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, static int lpc32xx_nand_device_ready(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct lpc32xx_nand_host *host = nand_chip->priv; + struct lpc32xx_nand_host *host = nand_get_controller_data(nand_chip); if ((readb(MLC_ISR(host->io_base)) & (MLCISR_CONTROLLER_READY | MLCISR_NAND_READY)) == @@ -317,7 +317,7 @@ static irqreturn_t lpc3xxx_nand_irq(int irq, struct lpc32xx_nand_host *host) static int lpc32xx_waitfunc_nand(struct mtd_info *mtd, struct nand_chip *chip) { - struct lpc32xx_nand_host *host = chip->priv; + struct lpc32xx_nand_host *host = nand_get_controller_data(chip); if (readb(MLC_ISR(host->io_base)) & MLCISR_NAND_READY) goto exit; @@ -337,7 +337,7 @@ exit: static int lpc32xx_waitfunc_controller(struct mtd_info *mtd, struct nand_chip *chip) { - struct lpc32xx_nand_host *host = chip->priv; + struct lpc32xx_nand_host *host = nand_get_controller_data(chip); if (readb(MLC_ISR(host->io_base)) & MLCISR_CONTROLLER_READY) goto exit; @@ -389,7 +389,7 @@ static int lpc32xx_xmit_dma(struct mtd_info *mtd, void *mem, int len, enum dma_transfer_direction dir) { struct nand_chip *chip = mtd_to_nand(mtd); - struct lpc32xx_nand_host *host = chip->priv; + struct lpc32xx_nand_host *host = nand_get_controller_data(chip); struct dma_async_tx_descriptor *desc; int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; int res; @@ -430,7 +430,7 @@ out1: static int lpc32xx_read_page(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - struct lpc32xx_nand_host *host = chip->priv; + struct lpc32xx_nand_host *host = nand_get_controller_data(chip); int i, j; uint8_t *oobbuf = chip->oob_poi; uint32_t mlc_isr; @@ -497,7 +497,7 @@ static int lpc32xx_write_page_lowlevel(struct mtd_info *mtd, const uint8_t *buf, int oob_required, int page) { - struct lpc32xx_nand_host *host = chip->priv; + struct lpc32xx_nand_host *host = nand_get_controller_data(chip); const uint8_t *oobbuf = chip->oob_poi; uint8_t *dma_buf = (uint8_t *)buf; int res; @@ -542,7 +542,7 @@ static int lpc32xx_write_page_lowlevel(struct mtd_info *mtd, static int lpc32xx_read_oob(struct mtd_info *mtd, struct nand_chip *chip, int page) { - struct lpc32xx_nand_host *host = chip->priv; + struct lpc32xx_nand_host *host = nand_get_controller_data(chip); /* Read whole page - necessary with MLC controller! */ lpc32xx_read_page(mtd, chip, host->dummy_buf, 1, page); @@ -679,7 +679,8 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) host->pdata = dev_get_platdata(&pdev->dev); - nand_chip->priv = host; /* link the private data structures */ + /* link the private data structures */ + nand_set_controller_data(nand_chip, host); nand_set_flash_node(nand_chip, pdev->dev.of_node); mtd->dev.parent = &pdev->dev; diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c index ccd10b182a220..3b8f3735f3e86 100644 --- a/drivers/mtd/nand/lpc32xx_slc.c +++ b/drivers/mtd/nand/lpc32xx_slc.c @@ -260,7 +260,7 @@ static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, { uint32_t tmp; struct nand_chip *chip = mtd_to_nand(mtd); - struct lpc32xx_nand_host *host = chip->priv; + struct lpc32xx_nand_host *host = nand_get_controller_data(chip); /* Does CE state need to be changed? */ tmp = readl(SLC_CFG(host->io_base)); @@ -284,7 +284,7 @@ static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, static int lpc32xx_nand_device_ready(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct lpc32xx_nand_host *host = chip->priv; + struct lpc32xx_nand_host *host = nand_get_controller_data(chip); int rdy = 0; if ((readl(SLC_STAT(host->io_base)) & SLCSTAT_NAND_READY) != 0) @@ -339,7 +339,7 @@ static int lpc32xx_nand_ecc_calculate(struct mtd_info *mtd, static uint8_t lpc32xx_nand_read_byte(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct lpc32xx_nand_host *host = chip->priv; + struct lpc32xx_nand_host *host = nand_get_controller_data(chip); return (uint8_t)readl(SLC_DATA(host->io_base)); } @@ -350,7 +350,7 @@ static uint8_t lpc32xx_nand_read_byte(struct mtd_info *mtd) static void lpc32xx_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct lpc32xx_nand_host *host = chip->priv; + struct lpc32xx_nand_host *host = nand_get_controller_data(chip); /* Direct device read with no ECC */ while (len-- > 0) @@ -363,7 +363,7 @@ static void lpc32xx_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) static void lpc32xx_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct lpc32xx_nand_host *host = chip->priv; + struct lpc32xx_nand_host *host = nand_get_controller_data(chip); /* Direct device write with no ECC */ while (len-- > 0) @@ -428,7 +428,7 @@ static int lpc32xx_xmit_dma(struct mtd_info *mtd, dma_addr_t dma, void *mem, int len, enum dma_transfer_direction dir) { struct nand_chip *chip = mtd_to_nand(mtd); - struct lpc32xx_nand_host *host = chip->priv; + struct lpc32xx_nand_host *host = nand_get_controller_data(chip); struct dma_async_tx_descriptor *desc; int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; int res; @@ -488,7 +488,7 @@ static int lpc32xx_xfer(struct mtd_info *mtd, uint8_t *buf, int eccsubpages, int read) { struct nand_chip *chip = mtd_to_nand(mtd); - struct lpc32xx_nand_host *host = chip->priv; + struct lpc32xx_nand_host *host = nand_get_controller_data(chip); int i, status = 0; unsigned long timeout; int res; @@ -603,7 +603,7 @@ static int lpc32xx_nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - struct lpc32xx_nand_host *host = chip->priv; + struct lpc32xx_nand_host *host = nand_get_controller_data(chip); int stat, i, status; uint8_t *oobecc, tmpecc[LPC32XX_ECC_SAVE_SIZE]; @@ -665,7 +665,7 @@ static int lpc32xx_nand_write_page_syndrome(struct mtd_info *mtd, const uint8_t *buf, int oob_required, int page) { - struct lpc32xx_nand_host *host = chip->priv; + struct lpc32xx_nand_host *host = nand_get_controller_data(chip); uint8_t *pb = chip->oob_poi + chip->ecc.layout->eccpos[0]; int error; @@ -800,7 +800,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) chip = &host->nand_chip; mtd = nand_to_mtd(chip); - chip->priv = host; + nand_set_controller_data(chip, host); nand_set_flash_node(chip, pdev->dev.of_node); mtd->owner = THIS_MODULE; mtd->dev.parent = &pdev->dev; diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index 6d0ca33dd7abc..6b93e899d4e95 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c @@ -135,7 +135,7 @@ static void mpc5121_nfc_done(struct mtd_info *mtd); static inline u16 nfc_read(struct mtd_info *mtd, uint reg) { struct nand_chip *chip = mtd_to_nand(mtd); - struct mpc5121_nfc_prv *prv = chip->priv; + struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); return in_be16(prv->regs + reg); } @@ -144,7 +144,7 @@ static inline u16 nfc_read(struct mtd_info *mtd, uint reg) static inline void nfc_write(struct mtd_info *mtd, uint reg, u16 val) { struct nand_chip *chip = mtd_to_nand(mtd); - struct mpc5121_nfc_prv *prv = chip->priv; + struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); out_be16(prv->regs + reg, val); } @@ -214,7 +214,7 @@ static irqreturn_t mpc5121_nfc_irq(int irq, void *data) { struct mtd_info *mtd = data; struct nand_chip *chip = mtd_to_nand(mtd); - struct mpc5121_nfc_prv *prv = chip->priv; + struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); nfc_set(mtd, NFC_CONFIG1, NFC_INT_MASK); wake_up(&prv->irq_waitq); @@ -226,7 +226,7 @@ static irqreturn_t mpc5121_nfc_irq(int irq, void *data) static void mpc5121_nfc_done(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct mpc5121_nfc_prv *prv = chip->priv; + struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); int rv; if ((nfc_read(mtd, NFC_CONFIG2) & NFC_INT) == 0) { @@ -281,7 +281,7 @@ static void mpc5121_nfc_select_chip(struct mtd_info *mtd, int chip) static int ads5121_chipselect_init(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct mpc5121_nfc_prv *prv = chip->priv; + struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); struct device_node *dn; dn = of_find_compatible_node(NULL, NULL, "fsl,mpc5121ads-cpld"); @@ -303,7 +303,7 @@ static int ads5121_chipselect_init(struct mtd_info *mtd) static void ads5121_select_chip(struct mtd_info *mtd, int chip) { struct nand_chip *nand = mtd_to_nand(mtd); - struct mpc5121_nfc_prv *prv = nand->priv; + struct mpc5121_nfc_prv *prv = nand_get_controller_data(nand); u8 v; v = in_8(prv->csreg); @@ -333,7 +333,7 @@ static void mpc5121_nfc_command(struct mtd_info *mtd, unsigned command, int column, int page) { struct nand_chip *chip = mtd_to_nand(mtd); - struct mpc5121_nfc_prv *prv = chip->priv; + struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); prv->column = (column >= 0) ? column : 0; prv->spareonly = 0; @@ -406,7 +406,7 @@ static void mpc5121_nfc_copy_spare(struct mtd_info *mtd, uint offset, u8 *buffer, uint size, int wr) { struct nand_chip *nand = mtd_to_nand(mtd); - struct mpc5121_nfc_prv *prv = nand->priv; + struct mpc5121_nfc_prv *prv = nand_get_controller_data(nand); uint o, s, sbsize, blksize; /* @@ -458,7 +458,7 @@ static void mpc5121_nfc_buf_copy(struct mtd_info *mtd, u_char *buf, int len, int wr) { struct nand_chip *chip = mtd_to_nand(mtd); - struct mpc5121_nfc_prv *prv = chip->priv; + struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); uint c = prv->column; uint l; @@ -536,7 +536,7 @@ static u16 mpc5121_nfc_read_word(struct mtd_info *mtd) static int mpc5121_nfc_read_hw_config(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct mpc5121_nfc_prv *prv = chip->priv; + struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); struct mpc512x_reset_module *rm; struct device_node *rmnode; uint rcw_pagesize = 0; @@ -615,7 +615,7 @@ out: static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct mpc5121_nfc_prv *prv = chip->priv; + struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); if (prv->clk) clk_disable_unprepare(prv->clk); @@ -657,7 +657,7 @@ static int mpc5121_nfc_probe(struct platform_device *op) mtd = nand_to_mtd(chip); mtd->dev.parent = dev; - chip->priv = prv; + nand_set_controller_data(chip, prv); nand_set_flash_node(chip, dn); prv->dev = dev; diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 66e56bb22c0fb..854c832597aa6 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -532,7 +532,7 @@ static void send_addr_v1_v2(struct mxc_nand_host *host, uint16_t addr, int islas static void send_page_v3(struct mtd_info *mtd, unsigned int ops) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_chip->priv; + struct mxc_nand_host *host = nand_get_controller_data(nand_chip); uint32_t tmp; tmp = readl(NFC_V3_CONFIG1); @@ -548,7 +548,7 @@ static void send_page_v3(struct mtd_info *mtd, unsigned int ops) static void send_page_v2(struct mtd_info *mtd, unsigned int ops) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_chip->priv; + struct mxc_nand_host *host = nand_get_controller_data(nand_chip); /* NANDFC buffer 0 is used for page read/write */ writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); @@ -562,7 +562,7 @@ static void send_page_v2(struct mtd_info *mtd, unsigned int ops) static void send_page_v1(struct mtd_info *mtd, unsigned int ops) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_chip->priv; + struct mxc_nand_host *host = nand_get_controller_data(nand_chip); int bufs, i; if (mtd->writesize > 512) @@ -663,7 +663,7 @@ static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_chip->priv; + struct mxc_nand_host *host = nand_get_controller_data(nand_chip); /* * 1-Bit errors are automatically corrected in HW. No need for @@ -684,7 +684,7 @@ static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_chip->priv; + struct mxc_nand_host *host = nand_get_controller_data(nand_chip); u32 ecc_stat, err; int no_subpages = 1; int ret = 0; @@ -722,7 +722,7 @@ static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, static u_char mxc_nand_read_byte(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_chip->priv; + struct mxc_nand_host *host = nand_get_controller_data(nand_chip); uint8_t ret; /* Check for status request */ @@ -746,7 +746,7 @@ static u_char mxc_nand_read_byte(struct mtd_info *mtd) static uint16_t mxc_nand_read_word(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_chip->priv; + struct mxc_nand_host *host = nand_get_controller_data(nand_chip); uint16_t ret; ret = *(uint16_t *)(host->data_buf + host->buf_start); @@ -762,7 +762,7 @@ static void mxc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_chip->priv; + struct mxc_nand_host *host = nand_get_controller_data(nand_chip); u16 col = host->buf_start; int n = mtd->oobsize + mtd->writesize - col; @@ -780,7 +780,7 @@ static void mxc_nand_write_buf(struct mtd_info *mtd, static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_chip->priv; + struct mxc_nand_host *host = nand_get_controller_data(nand_chip); u16 col = host->buf_start; int n = mtd->oobsize + mtd->writesize - col; @@ -796,7 +796,7 @@ static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) static void mxc_nand_select_chip_v1_v3(struct mtd_info *mtd, int chip) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_chip->priv; + struct mxc_nand_host *host = nand_get_controller_data(nand_chip); if (chip == -1) { /* Disable the NFC clock */ @@ -817,7 +817,7 @@ static void mxc_nand_select_chip_v1_v3(struct mtd_info *mtd, int chip) static void mxc_nand_select_chip_v2(struct mtd_info *mtd, int chip) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_chip->priv; + struct mxc_nand_host *host = nand_get_controller_data(nand_chip); if (chip == -1) { /* Disable the NFC clock */ @@ -850,7 +850,7 @@ static void mxc_nand_select_chip_v2(struct mtd_info *mtd, int chip) static void copy_spare(struct mtd_info *mtd, bool bfrom) { struct nand_chip *this = mtd_to_nand(mtd); - struct mxc_nand_host *host = this->priv; + struct mxc_nand_host *host = nand_get_controller_data(this); u16 i, oob_chunk_size; u16 num_chunks = mtd->writesize / 512; @@ -893,7 +893,7 @@ static void copy_spare(struct mtd_info *mtd, bool bfrom) static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_chip->priv; + struct mxc_nand_host *host = nand_get_controller_data(nand_chip); /* Write out column address, if necessary */ if (column != -1) { @@ -979,7 +979,7 @@ static void ecc_8bit_layout_4k(struct nand_ecclayout *layout) static void preset_v1(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_chip->priv; + struct mxc_nand_host *host = nand_get_controller_data(nand_chip); uint16_t config1 = 0; if (nand_chip->ecc.mode == NAND_ECC_HW && mtd->writesize) @@ -1007,7 +1007,7 @@ static void preset_v1(struct mtd_info *mtd) static void preset_v2(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_chip->priv; + struct mxc_nand_host *host = nand_get_controller_data(nand_chip); uint16_t config1 = 0; config1 |= NFC_V2_CONFIG1_FP_INT; @@ -1053,7 +1053,7 @@ static void preset_v2(struct mtd_info *mtd) static void preset_v3(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = chip->priv; + struct mxc_nand_host *host = nand_get_controller_data(chip); uint32_t config2, config3; int i, addr_phases; @@ -1124,7 +1124,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_chip->priv; + struct mxc_nand_host *host = nand_get_controller_data(nand_chip); pr_debug("mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n", command, column, page_addr); @@ -1520,7 +1520,7 @@ static int mxcnd_probe(struct platform_device *pdev) /* 50 us command delay time */ this->chip_delay = 5; - this->priv = host; + nand_set_controller_data(this, host); nand_set_flash_node(this, pdev->dev.of_node), this->dev_ready = mxc_nand_dev_ready; this->cmdfunc = mxc_nand_command; diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 78de37ddf88b0..f57f461b5d727 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -667,7 +667,7 @@ static char *get_partition_name(int i) static int init_nandsim(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct nandsim *ns = chip->priv; + struct nandsim *ns = nand_get_controller_data(chip); int i, ret = 0; uint64_t remains; uint64_t next_offset; @@ -2244,7 +2244,7 @@ static int __init ns_init_module(void) } nsmtd = nand_to_mtd(chip); nand = (struct nandsim *)(chip + 1); - chip->priv = (void *)nand; + nand_set_controller_data(chip, (void *)nand); /* * Register simulator's callbacks. diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 7d72f4fe06a13..218c789ca7ab7 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -48,7 +48,7 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip) { uint32_t ccr; struct nand_chip *nchip = mtd_to_nand(mtd); - struct ndfc_controller *ndfc = nchip->priv; + struct ndfc_controller *ndfc = nand_get_controller_data(nchip); ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); if (chip >= 0) { @@ -62,7 +62,7 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip) static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *chip = mtd_to_nand(mtd); - struct ndfc_controller *ndfc = chip->priv; + struct ndfc_controller *ndfc = nand_get_controller_data(chip); if (cmd == NAND_CMD_NONE) return; @@ -76,7 +76,7 @@ static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) static int ndfc_ready(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct ndfc_controller *ndfc = chip->priv; + struct ndfc_controller *ndfc = nand_get_controller_data(chip); return in_be32(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY; } @@ -85,7 +85,7 @@ static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) { uint32_t ccr; struct nand_chip *chip = mtd_to_nand(mtd); - struct ndfc_controller *ndfc = chip->priv; + struct ndfc_controller *ndfc = nand_get_controller_data(chip); ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); ccr |= NDFC_CCR_RESET_ECC; @@ -97,7 +97,7 @@ static int ndfc_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) { struct nand_chip *chip = mtd_to_nand(mtd); - struct ndfc_controller *ndfc = chip->priv; + struct ndfc_controller *ndfc = nand_get_controller_data(chip); uint32_t ecc; uint8_t *p = (uint8_t *)&ecc; @@ -121,7 +121,7 @@ static int ndfc_calculate_ecc(struct mtd_info *mtd, static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct ndfc_controller *ndfc = chip->priv; + struct ndfc_controller *ndfc = nand_get_controller_data(chip); uint32_t *p = (uint32_t *) buf; for(;len > 0; len -= 4) @@ -131,7 +131,7 @@ static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct ndfc_controller *ndfc = chip->priv; + struct ndfc_controller *ndfc = nand_get_controller_data(chip); uint32_t *p = (uint32_t *) buf; for(;len > 0; len -= 4) @@ -165,7 +165,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, chip->ecc.size = 256; chip->ecc.bytes = 3; chip->ecc.strength = 1; - chip->priv = ndfc; + nand_set_controller_data(chip, ndfc); mtd->dev.parent = &ndfc->ofdev->dev; diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 2c2be612448e7..d4614bfbfed6c 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -26,7 +26,7 @@ static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *nc = mtd_to_nand(mtd); - struct orion_nand_data *board = nc->priv; + struct orion_nand_data *board = nand_get_controller_data(nc); u32 offs; if (cmd == NAND_CMD_NONE) @@ -124,7 +124,7 @@ static int __init orion_nand_probe(struct platform_device *pdev) mtd->dev.parent = &pdev->dev; - nc->priv = board; + nand_set_controller_data(nc, board); nand_set_flash_node(nc, pdev->dev.of_node); nc->IO_ADDR_R = nc->IO_ADDR_W = io_base; nc->cmd_ctrl = orion_nand_cmd_ctrl; diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 10704ae129fc2..86fc245dc71a2 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -1114,7 +1114,7 @@ static void nand_cmdfunc(struct mtd_info *mtd, unsigned command, int column, int page_addr) { struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = chip->priv; + struct pxa3xx_nand_host *host = nand_get_controller_data(chip); struct pxa3xx_nand_info *info = host->info_data; int exec_cmd; @@ -1163,7 +1163,7 @@ static void nand_cmdfunc_extended(struct mtd_info *mtd, int column, int page_addr) { struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = chip->priv; + struct pxa3xx_nand_host *host = nand_get_controller_data(chip); struct pxa3xx_nand_info *info = host->info_data; int exec_cmd, ext_cmd_type; @@ -1283,7 +1283,7 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - struct pxa3xx_nand_host *host = chip->priv; + struct pxa3xx_nand_host *host = nand_get_controller_data(chip); struct pxa3xx_nand_info *info = host->info_data; chip->read_buf(mtd, buf, mtd->writesize); @@ -1310,7 +1310,7 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = chip->priv; + struct pxa3xx_nand_host *host = nand_get_controller_data(chip); struct pxa3xx_nand_info *info = host->info_data; char retval = 0xFF; @@ -1324,7 +1324,7 @@ static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) static u16 pxa3xx_nand_read_word(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = chip->priv; + struct pxa3xx_nand_host *host = nand_get_controller_data(chip); struct pxa3xx_nand_info *info = host->info_data; u16 retval = 0xFFFF; @@ -1338,7 +1338,7 @@ static u16 pxa3xx_nand_read_word(struct mtd_info *mtd) static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = chip->priv; + struct pxa3xx_nand_host *host = nand_get_controller_data(chip); struct pxa3xx_nand_info *info = host->info_data; int real_len = min_t(size_t, len, info->buf_count - info->buf_start); @@ -1350,7 +1350,7 @@ static void pxa3xx_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = chip->priv; + struct pxa3xx_nand_host *host = nand_get_controller_data(chip); struct pxa3xx_nand_info *info = host->info_data; int real_len = min_t(size_t, len, info->buf_count - info->buf_start); @@ -1366,7 +1366,7 @@ static void pxa3xx_nand_select_chip(struct mtd_info *mtd, int chip) static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) { struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = chip->priv; + struct pxa3xx_nand_host *host = nand_get_controller_data(chip); struct pxa3xx_nand_info *info = host->info_data; if (info->need_wait) { @@ -1573,7 +1573,7 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info, static int pxa3xx_nand_scan(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = chip->priv; + struct pxa3xx_nand_host *host = nand_get_controller_data(chip); struct pxa3xx_nand_info *info = host->info_data; struct platform_device *pdev = info->pdev; struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); @@ -1704,7 +1704,7 @@ static int alloc_nand_resource(struct platform_device *pdev) for (cs = 0; cs < pdata->num_cs; cs++) { host = (void *)&info[1] + sizeof(*host) * cs; chip = &host->chip; - chip->priv = host; + nand_set_controller_data(chip, host); mtd = nand_to_mtd(chip); info->host[cs] = host; host->cs = cs; @@ -1713,7 +1713,7 @@ static int alloc_nand_resource(struct platform_device *pdev) /* FIXME: all chips use the same device tree partitions */ nand_set_flash_node(chip, np); - chip->priv = host; + nand_set_controller_data(chip, host); chip->ecc.read_page = pxa3xx_nand_read_page_hwecc; chip->ecc.write_page = pxa3xx_nand_write_page_hwecc; chip->controller = &info->controller; diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index 5b15f2faee38d..fc9287af46140 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c @@ -65,7 +65,7 @@ static inline void r852_write_reg_dword(struct r852_device *dev, static inline struct r852_device *r852_get_dev(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - return chip->priv; + return nand_get_controller_data(chip); } @@ -361,7 +361,7 @@ static void r852_cmdctl(struct mtd_info *mtd, int dat, unsigned int ctrl) */ static int r852_wait(struct mtd_info *mtd, struct nand_chip *chip) { - struct r852_device *dev = chip->priv; + struct r852_device *dev = nand_get_controller_data(chip); unsigned long timeout; int status; @@ -879,7 +879,7 @@ static int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) if (!dev) goto error5; - chip->priv = dev; + nand_set_controller_data(chip, dev); dev->chip = chip; dev->pci_dev = pci_dev; pci_set_drvdata(pci_dev, dev); diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index bc94c5db01bf1..01ac74fa3b952 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -385,7 +385,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) struct nand_chip *this = mtd_to_nand(mtd); unsigned long cur; - nmtd = this->priv; + nmtd = nand_get_controller_data(this); info = nmtd->info; if (chip != -1) @@ -794,7 +794,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, chip->read_buf = s3c2410_nand_read_buf; chip->select_chip = s3c2410_nand_select_chip; chip->chip_delay = 50; - chip->priv = nmtd; + nand_set_controller_data(chip, nmtd); chip->options = set->options; chip->controller = &info->controller; diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c index d7e9d4df8c282..e3305f9dd6fb9 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/socrates_nand.c @@ -45,7 +45,7 @@ static void socrates_nand_write_buf(struct mtd_info *mtd, { int i; struct nand_chip *this = mtd_to_nand(mtd); - struct socrates_nand_host *host = this->priv; + struct socrates_nand_host *host = nand_get_controller_data(this); for (i = 0; i < len; i++) { out_be32(host->io_base, FPGA_NAND_ENABLE | @@ -64,7 +64,7 @@ static void socrates_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { int i; struct nand_chip *this = mtd_to_nand(mtd); - struct socrates_nand_host *host = this->priv; + struct socrates_nand_host *host = nand_get_controller_data(this); uint32_t val; val = FPGA_NAND_ENABLE | FPGA_NAND_CMD_READ; @@ -105,7 +105,7 @@ static void socrates_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct socrates_nand_host *host = nand_chip->priv; + struct socrates_nand_host *host = nand_get_controller_data(nand_chip); uint32_t val; if (cmd == NAND_CMD_NONE) @@ -130,7 +130,7 @@ static void socrates_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, static int socrates_nand_device_ready(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct socrates_nand_host *host = nand_chip->priv; + struct socrates_nand_host *host = nand_get_controller_data(nand_chip); if (in_be32(host->io_base) & FPGA_NAND_BUSY) return 0; /* busy */ @@ -162,7 +162,8 @@ static int socrates_nand_probe(struct platform_device *ofdev) mtd = nand_to_mtd(nand_chip); host->dev = &ofdev->dev; - nand_chip->priv = host; /* link the private data structures */ + /* link the private data structures */ + nand_set_controller_data(nand_chip, host); nand_set_flash_node(nand_chip, ofdev->dev.of_node); mtd->name = "socrates_nand"; mtd->dev.parent = &ofdev->dev; diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c index 27488ee443864..04d63f56baa47 100644 --- a/drivers/mtd/nand/txx9ndfmc.c +++ b/drivers/mtd/nand/txx9ndfmc.c @@ -79,7 +79,7 @@ struct txx9ndfmc_drvdata { static struct platform_device *mtd_to_platdev(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct txx9ndfmc_priv *txx9_priv = chip->priv; + struct txx9ndfmc_priv *txx9_priv = nand_get_controller_data(chip); return txx9_priv->dev; } @@ -135,7 +135,7 @@ static void txx9ndfmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *chip = mtd_to_nand(mtd); - struct txx9ndfmc_priv *txx9_priv = chip->priv; + struct txx9ndfmc_priv *txx9_priv = nand_get_controller_data(chip); struct platform_device *dev = txx9_priv->dev; struct txx9ndfmc_platform_data *plat = dev_get_platdata(&dev->dev); @@ -340,7 +340,7 @@ static int __init txx9ndfmc_probe(struct platform_device *dev) chip->chip_delay = 100; chip->controller = &drvdata->hw_control; - chip->priv = txx9_priv; + nand_set_controller_data(chip, txx9_priv); txx9_priv->dev = dev; if (plat->ch_mask != 1) { @@ -389,7 +389,7 @@ static int __exit txx9ndfmc_remove(struct platform_device *dev) if (!mtd) continue; chip = mtd_to_nand(mtd); - txx9_priv = chip->priv; + txx9_priv = nand_get_controller_data(chip); nand_release(mtd); kfree(txx9_priv->mtdname); -- GitLab From f07dcb90e4a9ccab9663a50847f255c9b0e2ada1 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:42 +0100 Subject: [PATCH 2333/2855] staging: mt29f_spinand: make use of nand_set/get_controller_data() helpers New helpers have been added to avoid directly accessing chip->field. Use them where appropriate. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/staging/mt29f_spinand/mt29f_spinand.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c index b7d429d45dab7..197d1124733de 100644 --- a/drivers/staging/mt29f_spinand/mt29f_spinand.c +++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c @@ -32,7 +32,7 @@ static inline struct spinand_state *mtd_to_state(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); - struct spinand_info *info = (struct spinand_info *)chip->priv; + struct spinand_info *info = nand_get_controller_data(chip); struct spinand_state *state = (struct spinand_state *)info->priv; return state; @@ -633,7 +633,7 @@ static int spinand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, u8 *p = buf; int eccsize = chip->ecc.size; int eccsteps = chip->ecc.steps; - struct spinand_info *info = (struct spinand_info *)chip->priv; + struct spinand_info *info = nand_get_controller_data(chip); enable_read_hw_ecc = 1; @@ -679,7 +679,7 @@ static u8 spinand_read_byte(struct mtd_info *mtd) static int spinand_wait(struct mtd_info *mtd, struct nand_chip *chip) { - struct spinand_info *info = (struct spinand_info *)chip->priv; + struct spinand_info *info = nand_get_controller_data(chip); unsigned long timeo = jiffies; int retval, state = chip->state; @@ -745,7 +745,7 @@ static void spinand_cmdfunc(struct mtd_info *mtd, unsigned int command, int column, int page) { struct nand_chip *chip = mtd_to_nand(mtd); - struct spinand_info *info = (struct spinand_info *)chip->priv; + struct spinand_info *info = nand_get_controller_data(chip); struct spinand_state *state = (struct spinand_state *)info->priv; switch (command) { @@ -894,7 +894,7 @@ static int spinand_probe(struct spi_device *spi_nand) #endif nand_set_flash_node(chip, spi_nand->dev.of_node); - chip->priv = info; + nand_set_controller_data(chip, info); chip->read_buf = spinand_read_buf; chip->write_buf = spinand_write_buf; chip->read_byte = spinand_read_byte; -- GitLab From f118902490aa1c3a361e485dd38a7b28cd130d71 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Thu, 7 Jan 2016 10:02:59 -0800 Subject: [PATCH 2334/2855] mtd: jz4780_nand: remove useless mtd->priv = chip assignment As of commit 2d3b77bac34b ("mtd: nand: update mtd_to_nand()"), this assignment isn't necessary, since struct mtd_info is embedded in struct nand_chip. Signed-off-by: Brian Norris Cc: Harvey Hunt Cc: Alex Smith Reviewed-by: Boris Brezillon --- drivers/mtd/nand/jz4780_nand.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/nand/jz4780_nand.c b/drivers/mtd/nand/jz4780_nand.c index 17eb9f2641873..6156c554e1c27 100644 --- a/drivers/mtd/nand/jz4780_nand.c +++ b/drivers/mtd/nand/jz4780_nand.c @@ -270,7 +270,6 @@ static int jz4780_nand_init_chip(struct platform_device *pdev, chip = &nand->chip; mtd = nand_to_mtd(chip); - mtd->priv = chip; mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s.%d", dev_name(dev), cs->bank); if (!mtd->name) -- GitLab From c66b651ce60bb82d8f6fe8ca35e70f323e3a260c Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Thu, 7 Jan 2016 11:06:46 -0800 Subject: [PATCH 2335/2855] mtd: nandsim: use nand_get_controller_data() Commit d699ed250c07 ("mtd: nand: make use of nand_set/get_controller_data() helpers") overlooked some uses of nand_chip::priv. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- drivers/mtd/nand/nandsim.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index f57f461b5d727..1fd519503bb17 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -1908,7 +1908,8 @@ static void switch_state(struct nandsim *ns) static u_char ns_nand_read_byte(struct mtd_info *mtd) { - struct nandsim *ns = mtd_to_nand(mtd)->priv; + struct nand_chip *chip = mtd_to_nand(mtd); + struct nandsim *ns = nand_get_controller_data(chip); u_char outb = 0x00; /* Sanity and correctness checks */ @@ -1969,7 +1970,8 @@ static u_char ns_nand_read_byte(struct mtd_info *mtd) static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte) { - struct nandsim *ns = mtd_to_nand(mtd)->priv; + struct nand_chip *chip = mtd_to_nand(mtd); + struct nandsim *ns = nand_get_controller_data(chip); /* Sanity and correctness checks */ if (!ns->lines.ce) { @@ -2123,7 +2125,8 @@ static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte) static void ns_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int bitmask) { - struct nandsim *ns = mtd_to_nand(mtd)->priv; + struct nand_chip *chip = mtd_to_nand(mtd); + struct nandsim *ns = nand_get_controller_data(chip); ns->lines.cle = bitmask & NAND_CLE ? 1 : 0; ns->lines.ale = bitmask & NAND_ALE ? 1 : 0; @@ -2150,7 +2153,8 @@ static uint16_t ns_nand_read_word(struct mtd_info *mtd) static void ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) { - struct nandsim *ns = mtd_to_nand(mtd)->priv; + struct nand_chip *chip = mtd_to_nand(mtd); + struct nandsim *ns = nand_get_controller_data(chip); /* Check that chip is expecting data input */ if (!(ns->state & STATE_DATAIN_MASK)) { @@ -2177,7 +2181,8 @@ static void ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) static void ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) { - struct nandsim *ns = mtd_to_nand(mtd)->priv; + struct nand_chip *chip = mtd_to_nand(mtd); + struct nandsim *ns = nand_get_controller_data(chip); /* Sanity and correctness checks */ if (!ns->lines.ce) { @@ -2404,7 +2409,8 @@ module_init(ns_init_module); */ static void __exit ns_cleanup_module(void) { - struct nandsim *ns = mtd_to_nand(nsmtd)->priv; + struct nand_chip *chip = mtd_to_nand(nsmtd); + struct nandsim *ns = nand_get_controller_data(chip); int i; nandsim_debugfs_remove(ns); -- GitLab From c93a59938c11f447ff2964ab3c317311778edf66 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 18 Dec 2015 15:00:49 +0200 Subject: [PATCH 2336/2855] serial: 8250: of: Fix the driver and actually compile the 8250_of The 8250_of never compiled since in the Kconfig we have SERIAL_OF_PLATFORM but in the makefile we expect to have SERIAL_8250_OF... When the 8250_of.c is actually compiled we will have two errors: missing linux/nwpserial.h and 8250/8250.h. Fix those as well at the same time when enable the compilation of the driver. Signed-off-by: Peter Ujfalusi Fixes: afd7f88f1577 ("serial: 8250: move of_serial code to 8250 directory") Reported-by: Guenter Roeck CC: Arnd Bergmann Acked-by: Arnd Bergmann Acked-by: Jon Hunter Tested-by: Jon Hunter Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_of.c | 3 +-- drivers/tty/serial/8250/Makefile | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c index d66fd24f87cf3..33021c1f7d557 100644 --- a/drivers/tty/serial/8250/8250_of.c +++ b/drivers/tty/serial/8250/8250_of.c @@ -18,10 +18,9 @@ #include #include #include -#include #include -#include "8250/8250.h" +#include "8250.h" struct of_serial_info { struct clk *clk; diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index 4ecb80d3549ae..b9b9bca5b6c3d 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -28,6 +28,6 @@ obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o obj-$(CONFIG_SERIAL_8250_UNIPHIER) += 8250_uniphier.o obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o obj-$(CONFIG_SERIAL_8250_MID) += 8250_mid.o -obj-$(CONFIG_SERIAL_8250_OF) += 8250_of.o +obj-$(CONFIG_SERIAL_OF_PLATFORM) += 8250_of.o CFLAGS_8250_ingenic.o += -I$(srctree)/scripts/dtc/libfdt -- GitLab From 210c7c1750fdf769647d1d526c9ea34c412c9eee Mon Sep 17 00:00:00 2001 From: Benjamin Coddington Date: Wed, 6 Jan 2016 10:40:18 -0500 Subject: [PATCH 2337/2855] NFS: Use wait_on_atomic_t() for unlock after readahead The use of wait_on_atomic_t() for waiting on I/O to complete before unlocking allows us to git rid of the NFS_IO_INPROGRESS flag, and thus the nfs_iocounter's flags member, and finally the nfs_iocounter altogether. The count of I/O is moved to the lock context, and the counter increment/decrement functions become simple enough to open-code. Signed-off-by: Benjamin Coddington [Trond: Fix up conflict with existing function nfs_wait_atomic_killable()] Signed-off-by: Trond Myklebust --- fs/nfs/file.c | 2 +- fs/nfs/inode.c | 18 ++++++++++------ fs/nfs/internal.h | 9 ++------ fs/nfs/pagelist.c | 48 ++++++------------------------------------ fs/nfs/write.c | 8 ------- include/linux/nfs_fs.h | 8 +------ 6 files changed, 23 insertions(+), 70 deletions(-) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 178ec8da028f3..4ef8f5addcadf 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -756,7 +756,7 @@ do_unlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) l_ctx = nfs_get_lock_context(nfs_file_open_context(filp)); if (!IS_ERR(l_ctx)) { - status = nfs_iocounter_wait(&l_ctx->io_count); + status = nfs_iocounter_wait(l_ctx); nfs_put_lock_context(l_ctx); if (status < 0) return status; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 74fb1223c2f5b..4b63d1bd58201 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -71,19 +71,25 @@ nfs_fattr_to_ino_t(struct nfs_fattr *fattr) return nfs_fileid_to_ino_t(fattr->fileid); } -/** - * nfs_wait_bit_killable - helper for functions that are sleeping on bit locks - * @word: long word containing the bit lock - */ -int nfs_wait_bit_killable(struct wait_bit_key *key, int mode) +static int nfs_wait_killable(int mode) { freezable_schedule_unsafe(); if (signal_pending_state(mode, current)) return -ERESTARTSYS; return 0; } + +int nfs_wait_bit_killable(struct wait_bit_key *key, int mode) +{ + return nfs_wait_killable(mode); +} EXPORT_SYMBOL_GPL(nfs_wait_bit_killable); +int nfs_wait_atomic_killable(atomic_t *p) +{ + return nfs_wait_killable(TASK_KILLABLE); +} + /** * nfs_compat_user_ino64 - returns the user-visible inode number * @fileid: 64-bit fileid @@ -699,7 +705,7 @@ static void nfs_init_lock_context(struct nfs_lock_context *l_ctx) l_ctx->lockowner.l_owner = current->files; l_ctx->lockowner.l_pid = current->tgid; INIT_LIST_HEAD(&l_ctx->list); - nfs_iocounter_init(&l_ctx->io_count); + atomic_set(&l_ctx->io_count, 0); } static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context *ctx) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index ee81792d28862..4e8cc942336c8 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -238,7 +238,7 @@ extern void nfs_pgheader_init(struct nfs_pageio_descriptor *desc, struct nfs_pgio_header *hdr, void (*release)(struct nfs_pgio_header *hdr)); void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos); -int nfs_iocounter_wait(struct nfs_io_counter *c); +int nfs_iocounter_wait(struct nfs_lock_context *l_ctx); extern const struct nfs_pageio_ops nfs_pgio_rw_ops; struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *); @@ -252,12 +252,6 @@ void nfs_free_request(struct nfs_page *req); struct nfs_pgio_mirror * nfs_pgio_current_mirror(struct nfs_pageio_descriptor *desc); -static inline void nfs_iocounter_init(struct nfs_io_counter *c) -{ - c->flags = 0; - atomic_set(&c->io_count, 0); -} - static inline bool nfs_pgio_has_mirroring(struct nfs_pageio_descriptor *desc) { WARN_ON_ONCE(desc->pg_mirror_count < 1); @@ -386,6 +380,7 @@ extern void nfs_clear_inode(struct inode *); extern void nfs_evict_inode(struct inode *); void nfs_zap_acl_cache(struct inode *inode); extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode); +extern int nfs_wait_atomic_killable(atomic_t *p); /* super.c */ extern const struct super_operations nfs_sops; diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index eeddbf0bf4c49..cb7e73ba059ce 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -101,53 +101,18 @@ nfs_page_free(struct nfs_page *p) kmem_cache_free(nfs_page_cachep, p); } -static void -nfs_iocounter_inc(struct nfs_io_counter *c) -{ - atomic_inc(&c->io_count); -} - -static void -nfs_iocounter_dec(struct nfs_io_counter *c) -{ - if (atomic_dec_and_test(&c->io_count)) { - clear_bit(NFS_IO_INPROGRESS, &c->flags); - smp_mb__after_atomic(); - wake_up_bit(&c->flags, NFS_IO_INPROGRESS); - } -} - -static int -__nfs_iocounter_wait(struct nfs_io_counter *c) -{ - wait_queue_head_t *wq = bit_waitqueue(&c->flags, NFS_IO_INPROGRESS); - DEFINE_WAIT_BIT(q, &c->flags, NFS_IO_INPROGRESS); - int ret = 0; - - do { - prepare_to_wait(wq, &q.wait, TASK_KILLABLE); - set_bit(NFS_IO_INPROGRESS, &c->flags); - if (atomic_read(&c->io_count) == 0) - break; - ret = nfs_wait_bit_killable(&q.key, TASK_KILLABLE); - } while (atomic_read(&c->io_count) != 0 && !ret); - finish_wait(wq, &q.wait); - return ret; -} - /** * nfs_iocounter_wait - wait for i/o to complete - * @c: nfs_io_counter to use + * @l_ctx: nfs_lock_context with io_counter to use * * returns -ERESTARTSYS if interrupted by a fatal signal. * Otherwise returns 0 once the io_count hits 0. */ int -nfs_iocounter_wait(struct nfs_io_counter *c) +nfs_iocounter_wait(struct nfs_lock_context *l_ctx) { - if (atomic_read(&c->io_count) == 0) - return 0; - return __nfs_iocounter_wait(c); + return wait_on_atomic_t(&l_ctx->io_count, nfs_wait_atomic_killable, + TASK_KILLABLE); } /* @@ -370,7 +335,7 @@ nfs_create_request(struct nfs_open_context *ctx, struct page *page, return ERR_CAST(l_ctx); } req->wb_lock_context = l_ctx; - nfs_iocounter_inc(&l_ctx->io_count); + atomic_inc(&l_ctx->io_count); /* Initialize the request struct. Initially, we assume a * long write-back delay. This will be adjusted in @@ -431,7 +396,8 @@ static void nfs_clear_request(struct nfs_page *req) req->wb_page = NULL; } if (l_ctx != NULL) { - nfs_iocounter_dec(&l_ctx->io_count); + if (atomic_dec_and_test(&l_ctx->io_count)) + wake_up_atomic_t(&l_ctx->io_count); nfs_put_lock_context(l_ctx); req->wb_lock_context = NULL; } diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 94828b3f8c955..8ba4f717b4132 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -1565,14 +1565,6 @@ static void nfs_writeback_result(struct rpc_task *task, } } -static int nfs_wait_atomic_killable(atomic_t *key) -{ - if (fatal_signal_pending(current)) - return -ERESTARTSYS; - freezable_schedule_unsafe(); - return 0; -} - static int wait_on_commit(struct nfs_mds_commit_info *cinfo) { return wait_on_atomic_t(&cinfo->rpcs_out, diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 9eee972863a74..196aaceafda72 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -60,18 +60,12 @@ struct nfs_lockowner { pid_t l_pid; }; -#define NFS_IO_INPROGRESS 0 -struct nfs_io_counter { - unsigned long flags; - atomic_t io_count; -}; - struct nfs_lock_context { atomic_t count; struct list_head list; struct nfs_open_context *open_context; struct nfs_lockowner lockowner; - struct nfs_io_counter io_count; + atomic_t io_count; }; struct nfs4_state; -- GitLab From 121e213eabad66c0453904d76e3eda193958acbd Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Fri, 8 Jan 2016 11:28:35 +1100 Subject: [PATCH 2338/2855] xfs: add tracepoints to readpage calls This allows us to see page cache driven readahead in action as it passes through XFS. This helps to understand buffered read throughput problems such as readahead IO IO sizes being too small for the underlying device to reach max throughput. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/xfs_aops.c | 2 ++ fs/xfs/xfs_trace.h | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 29e7e5dd5178e..379c089fb0514 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1917,6 +1917,7 @@ xfs_vm_readpage( struct file *unused, struct page *page) { + trace_xfs_vm_readpage(page->mapping->host, 1); return mpage_readpage(page, xfs_get_blocks); } @@ -1927,6 +1928,7 @@ xfs_vm_readpages( struct list_head *pages, unsigned nr_pages) { + trace_xfs_vm_readpages(mapping->host, nr_pages); return mpage_readpages(mapping, pages, nr_pages, xfs_get_blocks); } diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 877079eb0f8f0..391d797cb53fe 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -1222,6 +1222,32 @@ DEFINE_PAGE_EVENT(xfs_writepage); DEFINE_PAGE_EVENT(xfs_releasepage); DEFINE_PAGE_EVENT(xfs_invalidatepage); +DECLARE_EVENT_CLASS(xfs_readpage_class, + TP_PROTO(struct inode *inode, int nr_pages), + TP_ARGS(inode, nr_pages), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(int, nr_pages) + ), + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->nr_pages = nr_pages; + ), + TP_printk("dev %d:%d ino 0x%llx nr_pages %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->nr_pages) +) + +#define DEFINE_READPAGE_EVENT(name) \ +DEFINE_EVENT(xfs_readpage_class, name, \ + TP_PROTO(struct inode *inode, int nr_pages), \ + TP_ARGS(inode, nr_pages)) +DEFINE_READPAGE_EVENT(xfs_vm_readpage); +DEFINE_READPAGE_EVENT(xfs_vm_readpages); + DECLARE_EVENT_CLASS(xfs_imap_class, TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count, int type, struct xfs_bmbt_irec *irec), -- GitLab From e35438196c6a1d8b206471d51e80c380e80e047b Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Fri, 8 Jan 2016 11:28:49 +1100 Subject: [PATCH 2339/2855] xfs: bmapbt checking on debug kernels too expensive For large sparse or fragmented files, checking every single entry in the bmapbt on every operation is prohibitively expensive. Especially as such checks rarely discover problems during normal operations on high extent coutn files. Our regression tests don't tend to exercise files with hundreds of thousands to millions of extents, so mostly this isn't noticed. However, trying to run things like xfs_mdrestore of large filesystem dumps on a debug kernel quickly becomes impossible as the CPU is completely burnt up repeatedly walking the sparse file bmapbt that is generated for every allocation that is made. Hence, if the file has more than 10,000 extents, just don't bother with walking the tree to check it exhaustively. The btree code has checks that ensure that the newly inserted/removed/modified record is correctly ordered, so the entrie tree walk in thses cases has limited additional value. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_bmap.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 73884953b21cc..bc7e7d5b8c975 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -325,9 +325,11 @@ xfs_check_block( /* * Check that the extents for the inode ip are in the right order in all - * btree leaves. + * btree leaves. THis becomes prohibitively expensive for large extent count + * files, so don't bother with inodes that have more than 10,000 extents in + * them. The btree record ordering checks will still be done, so for such large + * bmapbt constructs that is going to catch most corruptions. */ - STATIC void xfs_bmap_check_leaf_extents( xfs_btree_cur_t *cur, /* btree cursor or null */ @@ -352,6 +354,10 @@ xfs_bmap_check_leaf_extents( return; } + /* skip large extent count inodes */ + if (ip->i_d.di_nextents > 10000) + return; + bno = NULLFSBLOCK; mp = ip->i_mount; ifp = XFS_IFORK_PTR(ip, whichfork); -- GitLab From ed6dc538e5a36a331b6256d54f435c80f6715460 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 7 Jan 2016 14:46:38 +0200 Subject: [PATCH 2340/2855] mei: fix fasync return value on error fasync should return a negative value on error and not poll mask POLLERR. Cc: # 4.3+ Cc: Al Viro Reported-by: Al Viro Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index b2f2486b3d757..677d0362f334e 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -657,7 +657,9 @@ out: * @file: pointer to file structure * @band: band bitmap * - * Return: poll mask + * Return: negative on error, + * 0 if it did no changes, + * and positive a process was added or deleted */ static int mei_fasync(int fd, struct file *file, int band) { @@ -665,7 +667,7 @@ static int mei_fasync(int fd, struct file *file, int band) struct mei_cl *cl = file->private_data; if (!mei_cl_is_connected(cl)) - return POLLERR; + return -ENODEV; return fasync_helper(fd, file, band, &cl->ev_async); } -- GitLab From 3b7474ec0d7150044f91e3af460067f79d466522 Mon Sep 17 00:00:00 2001 From: Dave Gerlach Date: Thu, 7 Jan 2016 11:13:34 -0800 Subject: [PATCH 2341/2855] Input: ti_am335x_tsc - fix HWPEN interrupt handling Remove write to REG_IRQCLR and REG_IRQWAKEUP in interrupt handler for IRQENB_HW_PEN as the resume handler should and does clear REG_IRQWAKEUP. IRQENB_HW_PEN bit is set in irqclr so that all interrupts get cleared later so let IRQENB_HW_PEN be cleared by that. Without this patch wakeup events from TSC_ADC do not work because pending interrupts in TSC_ADC were causing HW_PEN interrupt, needed for wake from suspend modes, to get disabled immediately by IRQ handler after being enabled and preventing wake from happening. Signed-off-by: Dave Gerlach Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ti_am335x_tsc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c index 191a1b87895f6..a21a07c3ab6d7 100644 --- a/drivers/input/touchscreen/ti_am335x_tsc.c +++ b/drivers/input/touchscreen/ti_am335x_tsc.c @@ -273,8 +273,6 @@ static irqreturn_t titsc_irq(int irq, void *dev) status = titsc_readl(ts_dev, REG_RAWIRQSTATUS); if (status & IRQENB_HW_PEN) { ts_dev->pen_down = true; - titsc_writel(ts_dev, REG_IRQWAKEUP, 0x00); - titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN); irqclr |= IRQENB_HW_PEN; } -- GitLab From 35f8679f577ae5673a778598bcbe7b45cbec8923 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 7 Jan 2016 15:06:51 -0800 Subject: [PATCH 2342/2855] Input: omap-keypad - remove dead check Commit da1f026b532ce944d74461497dc6d8c16456466e ("Keyboard: omap-keypad: use matrix_keypad.h") switched the driver to use matrix keypad infrastructure, which made array of keycodes to be unsigned short, and caused the test for negativity never trigger. This leads to the following static checker warning: drivers/input/keyboard/omap-keypad.c:158 omap_kp_tasklet() warn: 'keycodes[]' is never negative. Given that we did not care about this check for a few years already let's simply remove it. Reported-by: Dan Carpenter Acked-by: Aaro Koskinen Acked-by: Tony Lindgren Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/omap-keypad.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index 75ad6661e1308..e0d72c8c01e42 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c @@ -155,14 +155,6 @@ static void omap_kp_tasklet(unsigned long data) "pressed" : "released"); #else key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; - if (key < 0) { - printk(KERN_WARNING - "omap-keypad: Spurious key event %d-%d\n", - col, row); - /* We scan again after a couple of seconds */ - spurious = 1; - continue; - } if (!(kp_cur_group == (key & GROUP_MASK) || kp_cur_group == -1)) -- GitLab From ff1cab374ad98f4b9f408525ca9c08992b4ed784 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 5 Jan 2016 19:36:37 +0100 Subject: [PATCH 2343/2855] serial: sh-sci: Remove cpufreq notifier to fix crash/deadlock The BSP team noticed that there is spin/mutex lock issue on sh-sci when CPUFREQ is used. The issue is that the notifier function may call mutex_lock() while the spinlock is held, which can lead to a BUG(). This may happen if CPUFREQ is changed while another CPU calls clk_get_rate(). Taking the spinlock was added to the notifier function in commit e552de2413edad1a ("sh-sci: add platform device private data"), to protect the list of serial ports against modification during traversal. At that time the Common Clock Framework didn't exist yet, and clk_get_rate() just returned clk->rate without taking a mutex. Note that since commit d535a2305facf9b4 ("serial: sh-sci: Require a device per port mapping."), there's no longer a list of serial ports to traverse, and taking the spinlock became superfluous. To fix the issue, just remove the cpufreq notifier: 1. The notifier doesn't work correctly: all it does is update stored clock rates; it does not update the divider in the hardware. The divider will only be updated when calling sci_set_termios(). I believe this was broken back in 2004, when the old drivers/char/sh-sci.c driver (where the notifier did update the divider) was replaced by drivers/serial/sh-sci.c (where the notifier just updated port->uartclk). Cfr. full-history-linux commits 6f8deaef2e9675d9 ("[PATCH] sh: port sh-sci driver to the new API") and 3f73fe878dc9210a ("[PATCH] Remove old sh-sci driver"). 2. On modern SoCs, the sh-sci parent clock rate is no longer related to the CPU clock rate anyway, so using a cpufreq notifier is futile. Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 42 ------------------------------------- 1 file changed, 42 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 5f2a03acb5d9f..4646a9f531ad8 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -124,8 +123,6 @@ struct sci_port { struct timer_list rx_timer; unsigned int rx_timeout; #endif - - struct notifier_block freq_transition; }; #define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS @@ -1666,32 +1663,6 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) return ret; } -/* - * Here we define a transition notifier so that we can update all of our - * ports' baud rate when the peripheral clock changes. - */ -static int sci_notifier(struct notifier_block *self, - unsigned long phase, void *p) -{ - struct sci_port *sci_port; - unsigned long flags; - unsigned int i; - - sci_port = container_of(self, struct sci_port, freq_transition); - - if (phase == CPUFREQ_POSTCHANGE) { - struct uart_port *port = &sci_port->port; - - spin_lock_irqsave(&port->lock, flags); - for (i = 0; i < SCI_NUM_CLKS; i++) - sci_port->clk_rates[i] = - clk_get_rate(sci_port->clks[i]); - spin_unlock_irqrestore(&port->lock, flags); - } - - return NOTIFY_OK; -} - static const struct sci_irq_desc { const char *desc; irq_handler_t handler; @@ -2811,9 +2782,6 @@ static int sci_remove(struct platform_device *dev) { struct sci_port *port = platform_get_drvdata(dev); - cpufreq_unregister_notifier(&port->freq_transition, - CPUFREQ_TRANSITION_NOTIFIER); - uart_remove_one_port(&sci_uart_driver, &port->port); sci_cleanup_single(port); @@ -2965,16 +2933,6 @@ static int sci_probe(struct platform_device *dev) if (ret) return ret; - sp->freq_transition.notifier_call = sci_notifier; - - ret = cpufreq_register_notifier(&sp->freq_transition, - CPUFREQ_TRANSITION_NOTIFIER); - if (unlikely(ret < 0)) { - uart_remove_one_port(&sci_uart_driver, &sp->port); - sci_cleanup_single(sp); - return ret; - } - #ifdef CONFIG_SH_STANDARD_BIOS sh_bios_gdb_detach(); #endif -- GitLab From 0bbfe28ad0fdc11dddae5fe6f6e4e91b7be06395 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Wed, 6 Jan 2016 13:25:53 -0800 Subject: [PATCH 2344/2855] HID: wacom: Use correct report to query pen ID from INTUOSHT2 devices Unlike other tablets which are compatible with the wacom_intuos_irq handler, INTUOSHT2 devices provide pen ID with report ID 8 instead of 5. To ensure wacom_intuos_schedule_prox_event works as intended for these tablets, we must be sure it uses the correct report ID in this case. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 6 +++++- drivers/hid/wacom_wac.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index f70660465a54f..3aeddc297652b 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -439,11 +439,15 @@ exit: static void wacom_intuos_schedule_prox_event(struct wacom_wac *wacom_wac) { struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); + struct wacom_features *features = &wacom_wac->features; struct hid_report *r; struct hid_report_enum *re; re = &(wacom->hdev->report_enum[HID_FEATURE_REPORT]); - r = re->report_id_hash[WACOM_REPORT_INTUOS_ID1]; + if (features->type == INTUOSHT2) + r = re->report_id_hash[WACOM_REPORT_INTUOSHT2_ID]; + else + r = re->report_id_hash[WACOM_REPORT_INTUOS_ID1]; if (r) { hid_hw_request(wacom->hdev, r, HID_REQ_GET_REPORT); } diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 3f60192e92726..25baa7f295997 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -70,6 +70,7 @@ #define WACOM_REPORT_DEVICE_LIST 16 #define WACOM_REPORT_INTUOS_PEN 16 #define WACOM_REPORT_REMOTE 17 +#define WACOM_REPORT_INTUOSHT2_ID 8 /* device quirks */ #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0001 -- GitLab From 84f6ea1d86bfe578d2690db1631b9863a904a0df Mon Sep 17 00:00:00 2001 From: Kristian Evensen Date: Wed, 6 Jan 2016 15:08:53 +0100 Subject: [PATCH 2345/2855] HID: Add new PID for Microchip Pick16F1454 There seems to be a new version of the Microchip Pick16F1454 with a different PID (0xf2f7). This device should also be ignored by the HID driver. The PID was observed with the second version of the Yepkit Ykush USB hub. Signed-off-by: Kristian Evensen Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index c6f7a694f67a1..ab3b86c327a35 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2408,6 +2408,7 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT2) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICK16F1454) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICK16F1454_V2) }, { HID_USB_DEVICE(USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY) }, { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100) }, { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 20) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 9024a3de40325..c39fbc4148896 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -669,6 +669,7 @@ #define USB_DEVICE_ID_PICOLCD 0xc002 #define USB_DEVICE_ID_PICOLCD_BOOTLOADER 0xf002 #define USB_DEVICE_ID_PICK16F1454 0x0042 +#define USB_DEVICE_ID_PICK16F1454_V2 0xf2f7 #define USB_VENDOR_ID_MICROSOFT 0x045e #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b -- GitLab From 76833559eb9d0c8f8e4481ec82216609a91956c7 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 28 Dec 2015 07:01:31 -0800 Subject: [PATCH 2346/2855] HID: sensor-hub: Add quirk for Lenovo Yoga 900 with ITE Chips This needs same quirk as applied to other YOGA sensor hubs. Refer to commit 21589ebda681 ("HID: sensor-hub: Add in quirk for Lenovo Yogas with ITE") Signed-off-by: Srinivas Pandruvada Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-sensor-hub.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index c39fbc4148896..dc8a95d3fa08e 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -515,6 +515,7 @@ #define USB_VENDOR_ID_ITE 0x048d #define USB_DEVICE_ID_ITE_LENOVO_YOGA 0x8386 #define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350 +#define USB_DEVICE_ID_ITE_LENOVO_YOGA900 0x8396 #define USB_VENDOR_ID_JABRA 0x0b0e #define USB_DEVICE_ID_JABRA_SPEAK_410 0x0412 diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 92870cdb52d94..58ed8f25ab215 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -794,6 +794,9 @@ static const struct hid_device_id sensor_hub_devices[] = { { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE_LENOVO_YOGA2), .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, + { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_ITE, + USB_DEVICE_ID_ITE_LENOVO_YOGA900), + .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, HID_ANY_ID) }, { } -- GitLab From 8caad1da223c361e2804b76d68405b1abe7886ff Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 8 Jan 2016 13:48:51 +0300 Subject: [PATCH 2347/2855] spi: loopback: fix typo in MODULE_PARM_DESC There should be an 's' on "dump_message" so it matches the module_param. Fixes: 84e0c4e5e2c4 ('spi: add loopback test driver to allow for spi_master regression tests') Signed-off-by: Dan Carpenter Signed-off-by: Mark Brown --- drivers/spi/spi-loopback-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-loopback-test.c b/drivers/spi/spi-loopback-test.c index 7f79a77c4b68a..894616f687b0f 100644 --- a/drivers/spi/spi-loopback-test.c +++ b/drivers/spi/spi-loopback-test.c @@ -37,7 +37,7 @@ MODULE_PARM_DESC(simulate_only, "if not 0 do not execute the spi message"); /* dump spi messages */ int dump_messages; module_param(dump_messages, int, 0); -MODULE_PARM_DESC(dump_message, +MODULE_PARM_DESC(dump_messages, "=1 dump the basic spi_message_structure, " \ "=2 dump the spi_message_structure including data, " \ "=3 dump the spi_message structure before and after execution"); -- GitLab From 926ea40a7ee294767994b67eebff9fa015562902 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 8 Jan 2016 08:11:54 -0500 Subject: [PATCH 2348/2855] NFSv4: Fix a compile warning about no prototype for nfs4_ioctl() Signed-off-by: Trond Myklebust --- fs/nfs/nfs4file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index db9b5fea5b3ef..42c40aab1952d 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -310,7 +310,7 @@ static long nfs42_ioctl_clone_range(struct file *dst_file, void __user *argp) args.dest_offset, args.src_length); } -long nfs4_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static long nfs4_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; -- GitLab From 44aab3e09ef947e546ee61c5082c41b86dd15e53 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 8 Jan 2016 08:12:47 -0500 Subject: [PATCH 2349/2855] NFS: Fix a compile warning about unused variable in nfs_generic_pg_pgios() Signed-off-by: Trond Myklebust --- fs/nfs/pagelist.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index cb7e73ba059ce..8ce4f61cbaa5f 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -796,12 +796,9 @@ EXPORT_SYMBOL_GPL(nfs_generic_pgio); static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc) { - struct nfs_pgio_mirror *mirror; struct nfs_pgio_header *hdr; int ret; - mirror = nfs_pgio_current_mirror(desc); - hdr = nfs_pgio_header_alloc(desc->pg_rw_ops); if (!hdr) { desc->pg_error = -ENOMEM; -- GitLab From 6c1207b5b8422cdddf467b9fbef922c4c374d382 Mon Sep 17 00:00:00 2001 From: Harvey Hunt Date: Fri, 8 Jan 2016 16:45:17 +0000 Subject: [PATCH 2350/2855] mtd: nand: jz4780: Update ecc correction error codes Update jz4780_bch_ecc_correct's return codes with appropriate values, as specified in /include/linux/mtd/nand.h. Signed-off-by: Harvey Hunt Cc: Alex Smith Cc: Boris Brezillon Cc: linux-kernel@vger.kernel.org Reviewed-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/jz4780_bch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/jz4780_bch.c b/drivers/mtd/nand/jz4780_bch.c index 5954fbfa29e94..755499c6650e4 100644 --- a/drivers/mtd/nand/jz4780_bch.c +++ b/drivers/mtd/nand/jz4780_bch.c @@ -210,8 +210,8 @@ EXPORT_SYMBOL(jz4780_bch_calculate); * Given the raw data and the ECC read from the NAND device, detects and * corrects errors in the data. * - * Return: the number of bit errors corrected, or -1 if there are too many - * errors to correct or we timed out waiting for the controller. + * Return: the number of bit errors corrected, -EBADMSG if there are too many + * errors to correct or -ETIMEDOUT if we timed out waiting for the controller. */ int jz4780_bch_correct(struct jz4780_bch *bch, struct jz4780_bch_params *params, u8 *buf, u8 *ecc_code) @@ -227,13 +227,13 @@ int jz4780_bch_correct(struct jz4780_bch *bch, struct jz4780_bch_params *params, if (!jz4780_bch_wait_complete(bch, BCH_BHINT_DECF, ®)) { dev_err(bch->dev, "timed out while correcting data\n"); - ret = -1; + ret = -ETIMEDOUT; goto out; } if (reg & BCH_BHINT_UNCOR) { dev_warn(bch->dev, "uncorrectable ECC error\n"); - ret = -1; + ret = -EBADMSG; goto out; } -- GitLab From 9146cbd52b11d4ade62dba8f238ec5e421c3fa2b Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Thu, 7 Jan 2016 09:53:08 -0800 Subject: [PATCH 2351/2855] mtd: jz4780_nand: replace if/else blocks with switch/case Using switch/case helps make this logic more clear and more robust. With this structure: * it's clear that this driver only support ECC_{HW,SOFT,SOFT_BCH}; and * we can sanely handle new ECC unsupported modes (right now, this code makes incorrect assumptions about the possible values in the nand_ecc_modes_t enum; e.g., what happens with NAND_ECC_HW_OOB_FIRST?) Signed-off-by: Brian Norris Cc: Alex Smith Reviewed-by: Boris Brezillon Tested-by: Harvey Hunt Acked-by: Harvey Hunt --- drivers/mtd/nand/jz4780_nand.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/mtd/nand/jz4780_nand.c b/drivers/mtd/nand/jz4780_nand.c index 6156c554e1c27..e1c016c9d32d2 100644 --- a/drivers/mtd/nand/jz4780_nand.c +++ b/drivers/mtd/nand/jz4780_nand.c @@ -171,29 +171,33 @@ static int jz4780_nand_init_ecc(struct jz4780_nand_chip *nand, struct device *de chip->ecc.bytes = fls((1 + 8) * chip->ecc.size) * (chip->ecc.strength / 8); - if (nfc->bch && chip->ecc.mode == NAND_ECC_HW) { + switch (chip->ecc.mode) { + case NAND_ECC_HW: + if (!nfc->bch) { + dev_err(dev, "HW BCH selected, but BCH controller not found\n"); + return -ENODEV; + } + chip->ecc.hwctl = jz4780_nand_ecc_hwctl; chip->ecc.calculate = jz4780_nand_ecc_calculate; chip->ecc.correct = jz4780_nand_ecc_correct; - } else if (!nfc->bch && chip->ecc.mode == NAND_ECC_HW) { - dev_err(dev, "HW BCH selected, but BCH controller not found\n"); - return -ENODEV; - } - - if (chip->ecc.mode == NAND_ECC_HW_SYNDROME) { - dev_err(dev, "ECC HW syndrome not supported\n"); - return -EINVAL; - } - - if (chip->ecc.mode != NAND_ECC_NONE) + /* fall through */ + case NAND_ECC_SOFT: + case NAND_ECC_SOFT_BCH: dev_info(dev, "using %s (strength %d, size %d, bytes %d)\n", (nfc->bch) ? "hardware BCH" : "software ECC", chip->ecc.strength, chip->ecc.size, chip->ecc.bytes); - else + break; + case NAND_ECC_NONE: dev_info(dev, "not using ECC\n"); + break; + default: + dev_err(dev, "ECC mode %d not supported\n", chip->ecc.mode); + return -EINVAL; + } - /* The NAND core will generate the ECC layout. */ - if (chip->ecc.mode == NAND_ECC_SOFT || chip->ecc.mode == NAND_ECC_SOFT_BCH) + /* The NAND core will generate the ECC layout for SW ECC */ + if (chip->ecc.mode != NAND_ECC_HW) return 0; /* Generate ECC layout. ECC codes are right aligned in the OOB area. */ -- GitLab From e84587250ab7e38b7d85e93a8c317e065e5c0a1f Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Fri, 8 Jan 2016 20:13:37 +0800 Subject: [PATCH 2352/2855] f2fs: check node id earily when readaheading node page Add node id check in ra_node_page and get_node_page_ra like get_node_page. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/node.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 6d5f548d20909..c1ddf3d88dd99 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1041,6 +1041,10 @@ void ra_node_page(struct f2fs_sb_info *sbi, nid_t nid) struct page *apage; int err; + if (!nid) + return; + f2fs_bug_on(sbi, check_nid_range(sbi, nid)); + apage = find_get_page(NODE_MAPPING(sbi), nid); if (apage && PageUptodate(apage)) { f2fs_put_page(apage, 0); @@ -1108,6 +1112,7 @@ struct page *get_node_page_ra(struct page *parent, int start) nid = get_nid(parent, start, false); if (!nid) return ERR_PTR(-ENOENT); + f2fs_bug_on(sbi, check_nid_range(sbi, nid)); repeat: page = grab_cache_page(NODE_MAPPING(sbi), nid); if (!page) @@ -1127,9 +1132,9 @@ repeat: end = start + MAX_RA_NODE; end = min(end, NIDS_PER_BLOCK); for (i = start + 1; i < end; i++) { - nid_t tnid = get_nid(parent, i, false); - if (!tnid) - continue; + nid_t tnid; + + tnid = get_nid(parent, i, false); ra_node_page(sbi, tnid); } -- GitLab From 0e022ea8fc49ed9c72ab9dcd9ca96414dc026184 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 5 Jan 2016 16:52:46 +0800 Subject: [PATCH 2353/2855] f2fs: introduce __get_node_page to reuse common code There are duplicated code in between get_node_page and get_node_page_ra, introduce __get_node_page to includes common parts of these two, and export get_node_page and get_node_page_ra by reusing __get_node_page. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/node.c | 88 ++++++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 53 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index c1ddf3d88dd99..5a2d800f4abca 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1060,56 +1060,35 @@ void ra_node_page(struct f2fs_sb_info *sbi, nid_t nid) f2fs_put_page(apage, err ? 1 : 0); } -struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid) +/* + * readahead MAX_RA_NODE number of node pages. + */ +void ra_node_pages(struct page *parent, int start) { - struct page *page; - int err; + struct f2fs_sb_info *sbi = F2FS_P_SB(parent); + struct blk_plug plug; + int i, end; + nid_t nid; - if (!nid) - return ERR_PTR(-ENOENT); - f2fs_bug_on(sbi, check_nid_range(sbi, nid)); -repeat: - page = grab_cache_page(NODE_MAPPING(sbi), nid); - if (!page) - return ERR_PTR(-ENOMEM); + blk_start_plug(&plug); - err = read_node_page(page, READ_SYNC); - if (err < 0) { - f2fs_put_page(page, 1); - return ERR_PTR(err); - } else if (err == LOCKED_PAGE) { - goto page_hit; + /* Then, try readahead for siblings of the desired node */ + end = start + MAX_RA_NODE; + end = min(end, NIDS_PER_BLOCK); + for (i = start; i < end; i++) { + nid = get_nid(parent, i, false); + ra_node_page(sbi, nid); } - lock_page(page); - - if (unlikely(!PageUptodate(page))) { - f2fs_put_page(page, 1); - return ERR_PTR(-EIO); - } - if (unlikely(page->mapping != NODE_MAPPING(sbi))) { - f2fs_put_page(page, 1); - goto repeat; - } -page_hit: - f2fs_bug_on(sbi, nid != nid_of_node(page)); - return page; + blk_finish_plug(&plug); } -/* - * Return a locked page for the desired node page. - * And, readahead MAX_RA_NODE number of node pages. - */ -struct page *get_node_page_ra(struct page *parent, int start) +struct page *__get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid, + struct page *parent, int start) { - struct f2fs_sb_info *sbi = F2FS_P_SB(parent); - struct blk_plug plug; struct page *page; - int err, i, end; - nid_t nid; + int err; - /* First, try getting the desired direct node. */ - nid = get_nid(parent, start, false); if (!nid) return ERR_PTR(-ENOENT); f2fs_bug_on(sbi, check_nid_range(sbi, nid)); @@ -1126,21 +1105,11 @@ repeat: goto page_hit; } - blk_start_plug(&plug); - - /* Then, try readahead for siblings of the desired node */ - end = start + MAX_RA_NODE; - end = min(end, NIDS_PER_BLOCK); - for (i = start + 1; i < end; i++) { - nid_t tnid; - - tnid = get_nid(parent, i, false); - ra_node_page(sbi, tnid); - } - - blk_finish_plug(&plug); + if (parent) + ra_node_pages(parent, start + 1); lock_page(page); + if (unlikely(!PageUptodate(page))) { f2fs_put_page(page, 1); return ERR_PTR(-EIO); @@ -1154,6 +1123,19 @@ page_hit: return page; } +struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid) +{ + return __get_node_page(sbi, nid, NULL, 0); +} + +struct page *get_node_page_ra(struct page *parent, int start) +{ + struct f2fs_sb_info *sbi = F2FS_P_SB(parent); + nid_t nid = get_nid(parent, start, false); + + return __get_node_page(sbi, nid, parent, start); +} + void sync_inode_page(struct dnode_of_data *dn) { if (IS_INODE(dn->node_page) || dn->inode_page == dn->node_page) { -- GitLab From 7612118ae8cdd36cbd74d873855d70252d2d49e3 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 1 Jan 2016 22:03:47 -0800 Subject: [PATCH 2354/2855] f2fs: check the page status filled from disk After reading a page, we need to check whether there is any error. Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index ac5bea0f5f09a..77c3bbb9bee05 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -413,7 +413,7 @@ struct page *get_new_data_page(struct inode *inode, struct page *page; struct dnode_of_data dn; int err; -repeat: + page = f2fs_grab_cache_page(mapping, index, true); if (!page) { /* @@ -442,12 +442,11 @@ repeat: } else { f2fs_put_page(page, 1); - page = get_read_data_page(inode, index, READ_SYNC, true); + /* if ipage exists, blkaddr should be NEW_ADDR */ + f2fs_bug_on(F2FS_I_SB(inode), ipage); + page = get_lock_data_page(inode, index, true); if (IS_ERR(page)) - goto repeat; - - /* wait for read completion */ - lock_page(page); + return page; } got_it: if (new_i_size && i_size_read(inode) < -- GitLab From 12719ae14e57980ebf0a7baa63bc80494c76b192 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 7 Jan 2016 13:23:12 -0800 Subject: [PATCH 2355/2855] f2fs: avoid unnecessary f2fs_balance_fs calls Only when node page is newly dirtied, it needs to check whether we need to do f2fs_gc. Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 4 ++-- fs/f2fs/f2fs.h | 4 ++-- fs/f2fs/inode.c | 19 ++++++++++--------- fs/f2fs/node.c | 26 ++++++++++++++------------ fs/f2fs/node.h | 4 ++-- fs/f2fs/super.c | 2 -- 6 files changed, 30 insertions(+), 29 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 77c3bbb9bee05..3cf86fda8138f 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -225,8 +225,8 @@ void set_data_blkaddr(struct dnode_of_data *dn) /* Get physical address of data block */ addr_array = blkaddr_in_node(rn); addr_array[ofs_in_node] = cpu_to_le32(dn->data_blkaddr); - set_page_dirty(node_page); - dn->node_changed = true; + if (set_page_dirty(node_page)) + dn->node_changed = true; } int reserve_new_block(struct dnode_of_data *dn) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 882babaa678e1..461b32923c147 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1674,8 +1674,8 @@ long f2fs_compat_ioctl(struct file *, unsigned int, unsigned long); void f2fs_set_inode_flags(struct inode *); struct inode *f2fs_iget(struct super_block *, unsigned long); int try_to_free_nats(struct f2fs_sb_info *, int); -void update_inode(struct inode *, struct page *); -void update_inode_page(struct inode *); +int update_inode(struct inode *, struct page *); +int update_inode_page(struct inode *); int f2fs_write_inode(struct inode *, struct writeback_control *); void f2fs_evict_inode(struct inode *); void handle_failed_inode(struct inode *); diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index e95500802daa6..cabc1ff108a13 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -222,7 +222,7 @@ bad_inode: return ERR_PTR(ret); } -void update_inode(struct inode *inode, struct page *node_page) +int update_inode(struct inode *inode, struct page *node_page) { struct f2fs_inode *ri; @@ -260,15 +260,16 @@ void update_inode(struct inode *inode, struct page *node_page) __set_inode_rdev(inode, ri); set_cold_node(inode, node_page); - set_page_dirty(node_page); - clear_inode_flag(F2FS_I(inode), FI_DIRTY_INODE); + + return set_page_dirty(node_page); } -void update_inode_page(struct inode *inode) +int update_inode_page(struct inode *inode) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct page *node_page; + int ret = 0; retry: node_page = get_node_page(sbi, inode->i_ino); if (IS_ERR(node_page)) { @@ -279,10 +280,11 @@ retry: } else if (err != -ENOENT) { f2fs_stop_checkpoint(sbi); } - return; + return 0; } - update_inode(inode, node_page); + ret = update_inode(inode, node_page); f2fs_put_page(node_page, 1); + return ret; } int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) @@ -300,9 +302,8 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) * We need to balance fs here to prevent from producing dirty node pages * during the urgent cleaning time when runing out of free sections. */ - update_inode_page(inode); - - f2fs_balance_fs(sbi); + if (update_inode_page(inode)) + f2fs_balance_fs(sbi); return 0; } diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 5a2d800f4abca..c091b757bda60 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -543,7 +543,6 @@ int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode) set_nid(parent, offset[i - 1], nids[i], i == 1); alloc_nid_done(sbi, nids[i]); - dn->node_changed = true; done = true; } else if (mode == LOOKUP_NODE_RA && i == level && level > 1) { npage[i] = get_node_page_ra(parent, offset[i - 1]); @@ -679,8 +678,8 @@ static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs, ret = truncate_dnode(&rdn); if (ret < 0) goto out_err; - set_nid(page, i, 0, false); - dn->node_changed = true; + if (set_nid(page, i, 0, false)) + dn->node_changed = true; } } else { child_nofs = nofs + ofs * (NIDS_PER_BLOCK + 1) + 1; @@ -693,8 +692,8 @@ static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs, rdn.nid = child_nid; ret = truncate_nodes(&rdn, child_nofs, 0, depth - 1); if (ret == (NIDS_PER_BLOCK + 1)) { - set_nid(page, i, 0, false); - dn->node_changed = true; + if (set_nid(page, i, 0, false)) + dn->node_changed = true; child_nofs += ret; } else if (ret < 0 && ret != -ENOENT) { goto out_err; @@ -755,8 +754,8 @@ static int truncate_partial_nodes(struct dnode_of_data *dn, err = truncate_dnode(dn); if (err < 0) goto fail; - set_nid(pages[idx], i, 0, false); - dn->node_changed = true; + if (set_nid(pages[idx], i, 0, false)) + dn->node_changed = true; } if (offset[idx + 1] == 0) { @@ -981,7 +980,8 @@ struct page *new_node_page(struct dnode_of_data *dn, fill_node_footer(page, dn->nid, dn->inode->i_ino, ofs, true); set_cold_node(dn->inode, page); SetPageUptodate(page); - set_page_dirty(page); + if (set_page_dirty(page)) + dn->node_changed = true; if (f2fs_has_xattr_block(ofs)) F2FS_I(dn->inode)->i_xattr_nid = dn->nid; @@ -1138,18 +1138,20 @@ struct page *get_node_page_ra(struct page *parent, int start) void sync_inode_page(struct dnode_of_data *dn) { + int ret = 0; + if (IS_INODE(dn->node_page) || dn->inode_page == dn->node_page) { - update_inode(dn->inode, dn->node_page); + ret = update_inode(dn->inode, dn->node_page); } else if (dn->inode_page) { if (!dn->inode_page_locked) lock_page(dn->inode_page); - update_inode(dn->inode, dn->inode_page); + ret = update_inode(dn->inode, dn->inode_page); if (!dn->inode_page_locked) unlock_page(dn->inode_page); } else { - update_inode_page(dn->inode); + ret = update_inode_page(dn->inode); } - dn->node_changed = true; + dn->node_changed = ret ? true: false; } int sync_node_pages(struct f2fs_sb_info *sbi, nid_t ino, diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index 2de759a7746f5..d4d1f636fe1c3 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h @@ -317,7 +317,7 @@ static inline bool IS_DNODE(struct page *node_page) return true; } -static inline void set_nid(struct page *p, int off, nid_t nid, bool i) +static inline int set_nid(struct page *p, int off, nid_t nid, bool i) { struct f2fs_node *rn = F2FS_NODE(p); @@ -327,7 +327,7 @@ static inline void set_nid(struct page *p, int off, nid_t nid, bool i) rn->i.i_nid[off - NODE_DIR1_BLOCK] = cpu_to_le32(nid); else rn->in.nid[off] = cpu_to_le32(nid); - set_page_dirty(p); + return set_page_dirty(p); } static inline nid_t get_nid(struct page *p, int off, bool i) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 0bbd756821a7d..f5cc790646e29 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -591,8 +591,6 @@ int f2fs_sync_fs(struct super_block *sb, int sync) mutex_lock(&sbi->gc_mutex); err = write_checkpoint(sbi, &cpc); mutex_unlock(&sbi->gc_mutex); - } else { - f2fs_balance_fs(sbi); } f2fs_trace_ios(NULL, 1); -- GitLab From 2a4b8e9fab9cea45d90179d9ee8e718c5ed26457 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 7 Jan 2016 13:52:34 -0800 Subject: [PATCH 2356/2855] f2fs: remove redundant calls This patch removes redundant calls. Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index e3d32f6b4b4f5..69bc65fd862c4 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -267,8 +267,6 @@ sync_nodes: if (need_inode_block_update(sbi, ino)) { mark_inode_dirty_sync(inode); f2fs_write_inode(inode, NULL); - - f2fs_balance_fs(sbi); goto sync_nodes; } @@ -484,7 +482,6 @@ int truncate_data_blocks_range(struct dnode_of_data *dn, int count) F2FS_I(dn->inode)) + ofs; f2fs_update_extent_cache_range(dn, fofs, 0, len); dec_valid_block_count(sbi, dn->inode, nr_free); - set_page_dirty(dn->node_page); sync_inode_page(dn); } dn->ofs_in_node = ofs; -- GitLab From 2c4db1a6f6b42e2a9fb611cbbeb71a3a9a358ee0 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 7 Jan 2016 14:15:04 -0800 Subject: [PATCH 2357/2855] f2fs: clean up f2fs_balance_fs This patch adds one parameter to clean up all the callers of f2fs_balance_fs. Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 17 ++++++----------- fs/f2fs/f2fs.h | 2 +- fs/f2fs/file.c | 17 ++++++++--------- fs/f2fs/inline.c | 3 +-- fs/f2fs/inode.c | 2 +- fs/f2fs/namei.c | 22 +++++++++++----------- fs/f2fs/segment.c | 6 ++++-- fs/f2fs/xattr.c | 2 +- 8 files changed, 33 insertions(+), 38 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 3cf86fda8138f..6fae75ddae6d1 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -546,8 +546,7 @@ static int __allocate_data_blocks(struct inode *inode, loff_t offset, f2fs_put_dnode(&dn); f2fs_unlock_op(sbi); - if (dn.node_changed) - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, dn.node_changed); } return err; @@ -557,8 +556,7 @@ sync_out: f2fs_put_dnode(&dn); out: f2fs_unlock_op(sbi); - if (dn.node_changed) - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, dn.node_changed); return err; } @@ -657,8 +655,7 @@ get_next: if (create) { f2fs_unlock_op(sbi); - if (dn.node_changed) - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, dn.node_changed); f2fs_lock_op(sbi); } @@ -718,8 +715,7 @@ put_out: unlock_out: if (create) { f2fs_unlock_op(sbi); - if (dn.node_changed) - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, dn.node_changed); } out: trace_f2fs_map_blocks(inode, map, err); @@ -1178,8 +1174,7 @@ out: if (err) ClearPageUptodate(page); unlock_page(page); - if (need_balance_fs) - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, need_balance_fs); if (wbc->for_reclaim || unlikely(f2fs_cp_error(sbi))) { f2fs_submit_merged_bio(sbi, DATA, WRITE); remove_dirty_inode(inode); @@ -1506,7 +1501,7 @@ repeat: if (need_balance && has_not_enough_free_secs(sbi, 0)) { unlock_page(page); - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); lock_page(page); if (page->mapping != mapping) { /* The page got truncated from under us */ diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 461b32923c147..412865482a0bc 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1780,7 +1780,7 @@ void destroy_node_manager_caches(void); */ void register_inmem_page(struct inode *, struct page *); int commit_inmem_pages(struct inode *, bool); -void f2fs_balance_fs(struct f2fs_sb_info *); +void f2fs_balance_fs(struct f2fs_sb_info *, bool); void f2fs_balance_fs_bg(struct f2fs_sb_info *); int f2fs_issue_flush(struct f2fs_sb_info *); int create_flush_cmd_control(struct f2fs_sb_info *); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 69bc65fd862c4..ff06827aa3695 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -55,8 +55,7 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, f2fs_put_dnode(&dn); f2fs_unlock_op(sbi); - if (dn.node_changed) - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, dn.node_changed); file_update_time(vma->vm_file); lock_page(page); @@ -677,7 +676,7 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr) err = f2fs_truncate(inode, true); if (err) return err; - f2fs_balance_fs(F2FS_I_SB(inode)); + f2fs_balance_fs(F2FS_I_SB(inode), true); } else { /* * do not trim all blocks after i_size if target size is @@ -732,7 +731,7 @@ static int fill_zero(struct inode *inode, pgoff_t index, if (!len) return 0; - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); f2fs_lock_op(sbi); page = get_new_data_page(inode, NULL, index, false); @@ -818,7 +817,7 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len) loff_t blk_start, blk_end; struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); blk_start = (loff_t)pg_start << PAGE_CACHE_SHIFT; blk_end = (loff_t)pg_end << PAGE_CACHE_SHIFT; @@ -921,7 +920,7 @@ static int f2fs_do_collapse(struct inode *inode, pgoff_t start, pgoff_t end) int ret = 0; for (; end < nrpages; start++, end++) { - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); f2fs_lock_op(sbi); ret = __exchange_data_block(inode, end, start, true); f2fs_unlock_op(sbi); @@ -1103,7 +1102,7 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len) if (ret) return ret; - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); ret = truncate_blocks(inode, i_size_read(inode), true); if (ret) @@ -1155,7 +1154,7 @@ static int expand_inode_data(struct inode *inode, loff_t offset, if (ret) return ret; - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); pg_start = ((unsigned long long) offset) >> PAGE_CACHE_SHIFT; pg_end = ((unsigned long long) offset + len) >> PAGE_CACHE_SHIFT; @@ -1653,7 +1652,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi, pg_start = range->start >> PAGE_CACHE_SHIFT; pg_end = (range->start + range->len) >> PAGE_CACHE_SHIFT; - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); mutex_lock(&inode->i_mutex); diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 5ffbd169b719a..c3f0b7d4cfca1 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -200,8 +200,7 @@ out: f2fs_put_page(page, 1); - if (dn.node_changed) - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, dn.node_changed); return err; } diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index cabc1ff108a13..2ac4b780e8b43 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -303,7 +303,7 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) * during the urgent cleaning time when runing out of free sections. */ if (update_inode_page(inode)) - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); return 0; } diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 0d61a6864ab10..53d6227f5581f 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -140,7 +140,7 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode, inode->i_mapping->a_ops = &f2fs_dblock_aops; ino = inode->i_ino; - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); f2fs_lock_op(sbi); err = f2fs_add_link(dentry, inode); @@ -172,7 +172,7 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir, !f2fs_is_child_context_consistent_with_parent(dir, inode)) return -EPERM; - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); inode->i_ctime = CURRENT_TIME; ihold(inode); @@ -221,7 +221,7 @@ static int __recover_dot_dentries(struct inode *dir, nid_t pino) return 0; } - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); f2fs_lock_op(sbi); @@ -302,7 +302,7 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) if (!de) goto fail; - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); f2fs_lock_op(sbi); err = acquire_orphan_inode(sbi); @@ -361,7 +361,7 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, inode->i_op = &f2fs_symlink_inode_operations; inode->i_mapping->a_ops = &f2fs_dblock_aops; - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); f2fs_lock_op(sbi); err = f2fs_add_link(dentry, inode); @@ -452,7 +452,7 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) inode->i_mapping->a_ops = &f2fs_dblock_aops; mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_HIGH_ZERO); - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); set_inode_flag(F2FS_I(inode), FI_INC_LINK); f2fs_lock_op(sbi); @@ -498,7 +498,7 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry, init_special_inode(inode, inode->i_mode, rdev); inode->i_op = &f2fs_special_inode_operations; - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); f2fs_lock_op(sbi); err = f2fs_add_link(dentry, inode); @@ -539,7 +539,7 @@ static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry, inode->i_mapping->a_ops = &f2fs_dblock_aops; } - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); f2fs_lock_op(sbi); err = acquire_orphan_inode(sbi); @@ -642,7 +642,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, if (!new_entry) goto out_whiteout; - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); f2fs_lock_op(sbi); @@ -675,7 +675,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, update_inode_page(old_inode); update_inode_page(new_inode); } else { - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); f2fs_lock_op(sbi); @@ -816,7 +816,7 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry, goto out_new_dir; } - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); f2fs_lock_op(sbi); diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index a3474bad57702..c7bbc915d9627 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -213,7 +213,7 @@ int commit_inmem_pages(struct inode *inode, bool abort) * inode becomes free by iget_locked in f2fs_iget. */ if (!abort) { - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); f2fs_lock_op(sbi); } @@ -262,8 +262,10 @@ int commit_inmem_pages(struct inode *inode, bool abort) * This function balances dirty node and dentry pages. * In addition, it controls garbage collection. */ -void f2fs_balance_fs(struct f2fs_sb_info *sbi) +void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need) { + if (!need) + return; /* * We should do GC or end up with checkpoint, if there are so many dirty * dir/node pages without enough free segments. diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index 862368a32e535..822a8af89c122 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -609,7 +609,7 @@ int f2fs_setxattr(struct inode *inode, int index, const char *name, if (ipage) return __f2fs_setxattr(inode, index, name, value, size, ipage, flags); - f2fs_balance_fs(sbi); + f2fs_balance_fs(sbi, true); f2fs_lock_op(sbi); /* protect xattr_ver */ -- GitLab From da5af127a1a17bac121c6889c88cc90f8a278a84 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Fri, 8 Jan 2016 20:19:27 +0800 Subject: [PATCH 2358/2855] f2fs: recognize encrypted data in f2fs_fiemap This patch fixes to teach f2fs_fiemap to recognize encrypted data. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 6fae75ddae6d1..a3bce12b0cce5 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -830,9 +830,13 @@ next: flags |= FIEMAP_EXTENT_LAST; } - if (size) + if (size) { + if (f2fs_encrypted_inode(inode)) + flags |= FIEMAP_EXTENT_DATA_ENCRYPTED; + ret = fiemap_fill_next_extent(fieinfo, logical, phys, size, flags); + } if (start_blk > last_blk || ret) goto out; -- GitLab From 68e353851002dc07555b067a0baff1cc2f709c04 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Fri, 8 Jan 2016 20:22:52 +0800 Subject: [PATCH 2359/2855] f2fs: use atomic type for node count in extent tree 1. rename field in struct extent_tree from count to node_cnt for readability. 2. alter to use atomic type for node_cnt. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/extent_cache.c | 17 +++++++++-------- fs/f2fs/f2fs.h | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index 4dee2be9a648c..9febbc622bf53 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -36,7 +36,7 @@ static struct extent_node *__attach_extent_node(struct f2fs_sb_info *sbi, rb_link_node(&en->rb_node, parent, p); rb_insert_color(&en->rb_node, &et->root); - et->count++; + atomic_inc(&et->node_cnt); atomic_inc(&sbi->total_ext_node); return en; } @@ -45,7 +45,7 @@ static void __detach_extent_node(struct f2fs_sb_info *sbi, struct extent_tree *et, struct extent_node *en) { rb_erase(&en->rb_node, &et->root); - et->count--; + atomic_dec(&et->node_cnt); atomic_dec(&sbi->total_ext_node); if (et->cached_en == en) @@ -69,7 +69,7 @@ static struct extent_tree *__grab_extent_tree(struct inode *inode) et->cached_en = NULL; rwlock_init(&et->lock); INIT_LIST_HEAD(&et->list); - et->count = 0; + atomic_set(&et->node_cnt, 0); atomic_inc(&sbi->total_ext_tree); } else { atomic_dec(&sbi->total_zombie_tree); @@ -133,7 +133,7 @@ static unsigned int __free_extent_tree(struct f2fs_sb_info *sbi, { struct rb_node *node, *next; struct extent_node *en; - unsigned int count = et->count; + unsigned int count = atomic_read(&et->node_cnt); node = rb_first(&et->root); while (node) { @@ -154,7 +154,7 @@ static unsigned int __free_extent_tree(struct f2fs_sb_info *sbi, node = next; } - return count - et->count; + return count - atomic_read(&et->node_cnt); } static void __drop_largest_extent(struct inode *inode, @@ -192,7 +192,7 @@ bool f2fs_init_extent_tree(struct inode *inode, struct f2fs_extent *i_ext) le32_to_cpu(i_ext->blk), le32_to_cpu(i_ext->len)); write_lock(&et->lock); - if (et->count) + if (atomic_read(&et->node_cnt)) goto out; en = __init_extent_tree(sbi, et, &ei); @@ -660,7 +660,8 @@ void f2fs_destroy_extent_tree(struct inode *inode) if (!et) return; - if (inode->i_nlink && !is_bad_inode(inode) && et->count) { + if (inode->i_nlink && !is_bad_inode(inode) && + atomic_read(&et->node_cnt)) { down_write(&sbi->extent_tree_lock); list_add_tail(&et->list, &sbi->zombie_list); atomic_inc(&sbi->total_zombie_tree); @@ -673,7 +674,7 @@ void f2fs_destroy_extent_tree(struct inode *inode) /* delete extent tree entry in radix tree */ down_write(&sbi->extent_tree_lock); - f2fs_bug_on(sbi, et->count); + f2fs_bug_on(sbi, atomic_read(&et->node_cnt)); radix_tree_delete(&sbi->extent_tree_root, inode->i_ino); kmem_cache_free(extent_tree_slab, et); atomic_dec(&sbi->total_ext_tree); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 412865482a0bc..ae0007df6c2cd 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -361,7 +361,7 @@ struct extent_tree { struct extent_info largest; /* largested extent info */ struct list_head list; /* to be used by sbi->zombie_list */ rwlock_t lock; /* protect extent info rb-tree */ - unsigned int count; /* # of extent node in rb-tree*/ + atomic_t node_cnt; /* # of extent node in rb-tree*/ }; /* -- GitLab From 9b72a388f5867f4a31113a41d24bbf1026611d7b Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Fri, 8 Jan 2016 20:24:00 +0800 Subject: [PATCH 2360/2855] f2fs: skip releasing nodes in chindless extent tree If there are no nodes in extent tree, let's skip releasing step to avoid any overhead of grabbing/releasing extent tree lock. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/extent_cache.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index 9febbc622bf53..ccd5c636d3fe0 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -570,9 +570,11 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) /* 1. remove unreferenced extent tree */ list_for_each_entry_safe(et, next, &sbi->zombie_list, list) { - write_lock(&et->lock); - node_cnt += __free_extent_tree(sbi, et, true); - write_unlock(&et->lock); + if (atomic_read(&et->node_cnt)) { + write_lock(&et->lock); + node_cnt += __free_extent_tree(sbi, et, true); + write_unlock(&et->lock); + } list_del_init(&et->list); radix_tree_delete(&sbi->extent_tree_root, et->ino); @@ -618,6 +620,9 @@ free_node: for (i = 0; i < found; i++) { struct extent_tree *et = treevec[i]; + if (!atomic_read(&et->node_cnt)) + continue; + if (write_trylock(&et->lock)) { node_cnt += __free_extent_tree(sbi, et, false); write_unlock(&et->lock); @@ -641,7 +646,7 @@ unsigned int f2fs_destroy_extent_node(struct inode *inode) struct extent_tree *et = F2FS_I(inode)->extent_tree; unsigned int node_cnt = 0; - if (!et) + if (!et || !atomic_read(&et->node_cnt)) return 0; write_lock(&et->lock); -- GitLab From c33e54fafacaf83b3e345aae0e241c1f152224a0 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Sat, 9 Jan 2016 08:25:01 +1100 Subject: [PATCH 2361/2855] powerpc: Fix build break due to paca mm_context_t changes Commit 2fc251a8dda5 ("powerpc: Copy only required pieces of the mm_context_t to the paca") broke the build for CONFIG_PPC_STD_MMU_64=y and CONFIG_PPC_MM_SLICES=n. That only happens for a kernel built with 4K pages and HUGETLB disabled, which is why we missed it. Fix it by adding a mm_ctx_user_psize member to the paca and populating it in the appropriate places. Fixes: 2fc251a8dda5 ("powerpc: Copy only required pieces of the mm_context_t to the paca") Signed-off-by: Stephen Rothwell Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/paca.h | 2 ++ arch/powerpc/mm/hash_utils_64.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index ef78c288c712c..546540b910959 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -138,6 +138,7 @@ struct paca_struct { u64 mm_ctx_low_slices_psize; unsigned char mm_ctx_high_slices_psize[SLICE_ARRAY_SIZE]; #else + u16 mm_ctx_user_psize; u16 mm_ctx_sllp; #endif #endif @@ -212,6 +213,7 @@ static inline void copy_mm_to_paca(mm_context_t *context) memcpy(&get_paca()->mm_ctx_high_slices_psize, &context->high_slices_psize, SLICE_ARRAY_SIZE); #else + get_paca()->mm_ctx_user_psize = context->user_psize; get_paca()->mm_ctx_sllp = context->sllp; #endif } diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index db744576d730e..ba59d5977f349 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -866,7 +866,7 @@ static unsigned int get_paca_psize(unsigned long addr) #else unsigned int get_paca_psize(unsigned long addr) { - return get_paca()->context.user_psize; + return get_paca()->mm_ctx_user_psize; } #endif -- GitLab From 6b9b21073d3b250e17812cd562fffc9006962b39 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 8 Dec 2015 07:23:48 -0500 Subject: [PATCH 2362/2855] nfsd: give up on CB_LAYOUTRECALLs after two lease periods Have the CB_LAYOUTRECALL code treat NFS4_OK and NFS4ERR_DELAY returns equivalently. Change the code to periodically resend CB_LAYOUTRECALLS until the ls_layouts list is empty or the client returns a different error code. If we go for two lease periods without the list being emptied or the client sending a hard error, then we give up and clean out the list anyway. Signed-off-by: Jeff Layton Tested-by: Christoph Hellwig Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4layouts.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c index fec49febb75b2..76c13b0228b18 100644 --- a/fs/nfsd/nfs4layouts.c +++ b/fs/nfsd/nfs4layouts.c @@ -623,24 +623,39 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task) { struct nfs4_layout_stateid *ls = container_of(cb, struct nfs4_layout_stateid, ls_recall); + struct nfsd_net *nn; + ktime_t now, cutoff; LIST_HEAD(reaplist); + switch (task->tk_status) { case 0: - return 1; + case -NFS4ERR_DELAY: + /* + * Anything left? If not, then call it done. Note that we don't + * take the spinlock since this is an optimization and nothing + * should get added until the cb counter goes to zero. + */ + if (list_empty(&ls->ls_layouts)) + return 1; + + /* Poll the client until it's done with the layout */ + now = ktime_get(); + nn = net_generic(ls->ls_stid.sc_client->net, nfsd_net_id); + + /* Client gets 2 lease periods to return it */ + cutoff = ktime_add_ns(task->tk_start, + nn->nfsd4_lease * NSEC_PER_SEC * 2); + + if (ktime_before(now, cutoff)) { + rpc_delay(task, HZ/100); /* 10 mili-seconds */ + return 0; + } + /* Fallthrough */ case -NFS4ERR_NOMATCHING_LAYOUT: trace_layout_recall_done(&ls->ls_stid.sc_stateid); task->tk_status = 0; return 1; - case -NFS4ERR_DELAY: - /* Poll the client until it's done with the layout */ - /* FIXME: cap number of retries. - * The pnfs standard states that we need to only expire - * the client after at-least "lease time" .eg lease-time * 2 - * when failing to communicate a recall - */ - rpc_delay(task, HZ/100); /* 10 mili-seconds */ - return 0; default: /* * Unknown error or non-responding client, we'll need to fence. -- GitLab From 841e3ed977e0284e3680d6345d880a64e8072573 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 8 Jan 2016 21:00:08 -0800 Subject: [PATCH 2363/2855] Revert "arm64: dts: Add dts files to enable ION on Hi6220 SoC." This reverts commit 59dfafd03fc67d38307d2ba30bbfdd1224b8a75d Mark Brown reports that the dts file should not be accepted at this time as it is not following the convention that has been agreed on for the ion drivers. Reported-by: Mark Brown Cc: Mark Rutland Cc: Chen Feng Cc: Yu Dongbin Signed-off-by: Greg Kroah-Hartman --- .../arm64/boot/dts/hisilicon/hi6220-hikey.dts | 1 - arch/arm64/boot/dts/hisilicon/hi6220-ion.dtsi | 20 ------------------- 2 files changed, 21 deletions(-) delete mode 100644 arch/arm64/boot/dts/hisilicon/hi6220-ion.dtsi diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts index 496a920eced4a..8d43a0fce5226 100644 --- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts +++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts @@ -11,7 +11,6 @@ /memreserve/ 0x05e00000 0x00100000; #include "hi6220.dtsi" -#include "hi6220-ion.dtsi" / { model = "HiKey Development Board"; diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-ion.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220-ion.dtsi deleted file mode 100644 index c79f2cea314c5..0000000000000 --- a/arch/arm64/boot/dts/hisilicon/hi6220-ion.dtsi +++ /dev/null @@ -1,20 +0,0 @@ -/ { - hi6220-ion { - compatible = "hisilicon,hi6220-ion"; - heap_sys_user@0 { - heap-name = "sys_user"; - heap-id = <0x0>; - heap-base = <0x0>; - heap-size = <0x0>; - heap-type = "ion_system"; - }; - heap_sys_contig@0 { - heap-name = "sys_contig"; - heap-id = <0x1>; - heap-base = <0x0>; - heap-size = <0x0>; - heap-type = "ion_system_contig"; - }; - }; - -}; -- GitLab From 041497eb721ddbdc1e690316976dd8ba7bc136a2 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 17 Dec 2015 10:05:46 -0500 Subject: [PATCH 2364/2855] drivers/tty/serial: delete unused MODULE_DEVICE_TABLE from atmel_serial.c In commit c39dfebc7798956fd2140ae6321786ff35da30c3 ("drivers/tty/serial: make serial/atmel_serial.c explicitly non-modular") we removed the code relating to modular support since it currently only supports built in. However, when redoing my build coverage for mips allmodconfig, which sets CONFIG_OF, I noticed a remaining line that needs to be removed, else we will get a build failure for an undefined module macro. Unfortunately this didn't appear for any of the other arch I tested more frequently, such as ARM. Since MODULE_DEVICE_TABLE is a no-op for non-modular code, we can just remove the offending line. Fixes: c39dfebc7798 ("drivers/tty/serial: make serial/atmel_serial.c explicitly non-modular") Cc: Nicolas Ferre Cc: Jiri Slaby Reported-by: Sudip Mukherjee Signed-off-by: Paul Gortmaker Acked-by: Nicolas Ferre Acked-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 50e785a0ea734..1c0884d8ef326 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -188,8 +188,6 @@ static const struct of_device_id atmel_serial_dt_ids[] = { { .compatible = "atmel,at91sam9260-usart" }, { /* sentinel */ } }; - -MODULE_DEVICE_TABLE(of, atmel_serial_dt_ids); #endif static inline struct atmel_uart_port * -- GitLab From 21266be9ed542f13436bd9c75316d43e1e84f6ae Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 19 Nov 2015 18:19:29 -0800 Subject: [PATCH 2365/2855] arch: consolidate CONFIG_STRICT_DEVM in lib/Kconfig.debug Let all the archs that implement devmem_is_allowed() opt-in to a common definition of CONFIG_STRICT_DEVM in lib/Kconfig.debug. Cc: Kees Cook Cc: Russell King Cc: Will Deacon Cc: Benjamin Herrenschmidt Cc: Martin Schwidefsky Cc: Thomas Gleixner Cc: "H. Peter Anvin" Cc: Andrew Morton Cc: Greg Kroah-Hartman Cc: "David S. Miller" Acked-by: Catalin Marinas Acked-by: Heiko Carstens [heiko: drop 'default y' for s390] Acked-by: Ingo Molnar Suggested-by: Arnd Bergmann Signed-off-by: Dan Williams --- arch/arm/Kconfig | 1 + arch/arm/Kconfig.debug | 14 -------------- arch/arm64/Kconfig | 1 + arch/arm64/Kconfig.debug | 14 -------------- arch/frv/Kconfig | 1 + arch/m32r/Kconfig | 1 + arch/powerpc/Kconfig | 1 + arch/powerpc/Kconfig.debug | 12 ------------ arch/s390/Kconfig | 1 + arch/s390/Kconfig.debug | 12 ------------ arch/tile/Kconfig | 4 +--- arch/unicore32/Kconfig | 1 + arch/unicore32/Kconfig.debug | 14 -------------- arch/x86/Kconfig | 1 + arch/x86/Kconfig.debug | 17 ----------------- lib/Kconfig.debug | 22 ++++++++++++++++++++++ 16 files changed, 31 insertions(+), 86 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 34e1569a11ee3..b8a47974c2d7e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -2,6 +2,7 @@ config ARM bool default y select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE + select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAVE_CUSTOM_GPIO_H diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 259c0ca9c99a8..e356357d86bb9 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -15,20 +15,6 @@ config ARM_PTDUMP kernel. If in doubt, say "N" -config STRICT_DEVMEM - bool "Filter access to /dev/mem" - depends on MMU - ---help--- - If this option is disabled, you allow userspace (root) access to all - of memory, including kernel and userspace memory. Accidental - access to this is obviously disastrous, but specific access can - be used by people debugging the kernel. - - If this option is switched on, the /dev/mem file only allows - userspace access to memory mapped peripherals. - - If in doubt, say Y. - # RMK wants arm kernels compiled with frame pointers or stack unwinding. # If you know what you are doing and are willing to live without stack # traces, you can get a slightly smaller kernel by setting this option to diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 871f21783866d..08f64b455aa8b 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -3,6 +3,7 @@ config ARM64 select ACPI_CCA_REQUIRED if ACPI select ACPI_GENERIC_GSI if ACPI select ACPI_REDUCED_HARDWARE_ONLY if ACPI + select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_GCOV_PROFILE_ALL diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug index 04fb73b973f15..e13c4bf84d9e1 100644 --- a/arch/arm64/Kconfig.debug +++ b/arch/arm64/Kconfig.debug @@ -14,20 +14,6 @@ config ARM64_PTDUMP kernel. If in doubt, say "N" -config STRICT_DEVMEM - bool "Filter access to /dev/mem" - depends on MMU - help - If this option is disabled, you allow userspace (root) access to all - of memory, including kernel and userspace memory. Accidental - access to this is obviously disastrous, but specific access can - be used by people debugging the kernel. - - If this option is switched on, the /dev/mem file only allows - userspace access to memory mapped peripherals. - - If in doubt, say Y. - config PID_IN_CONTEXTIDR bool "Write the current PID to the CONTEXTIDR register" help diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index 34aa19352dc1a..03bfd6bf03e7a 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -10,6 +10,7 @@ config FRV select HAVE_DEBUG_BUGVERBOSE select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_CPU_DEVICES + select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_WANT_IPC_PARSE_VERSION select OLD_SIGSUSPEND3 select OLD_SIGACTION diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index 9e44bbd8051ed..836ac5a963c83 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig @@ -13,6 +13,7 @@ config M32R select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW select GENERIC_ATOMIC64 + select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_USES_GETTIMEOFFSET select MODULES_USE_ELF_RELA select HAVE_DEBUG_STACKOVERFLOW diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index db49e0d796b1b..85eabc49de61a 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -159,6 +159,7 @@ config PPC select EDAC_SUPPORT select EDAC_ATOMIC_SCRUB select ARCH_HAS_DMA_SET_COHERENT_MASK + select ARCH_HAS_DEVMEM_IS_ALLOWED select HAVE_ARCH_SECCOMP_FILTER config GENERIC_CSUM diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index 3a510f4a6b68c..a0e44a9c456fc 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug @@ -335,18 +335,6 @@ config PPC_EARLY_DEBUG_CPM_ADDR platform probing is done, all platforms selected must share the same address. -config STRICT_DEVMEM - def_bool y - prompt "Filter access to /dev/mem" - help - This option restricts access to /dev/mem. If this option is - disabled, you allow userspace access to all memory, including - kernel and userspace memory. Accidental memory access is likely - to be disastrous. - Memory access is required for experts who want to debug the kernel. - - If you are unsure, say Y. - config FAIL_IOMMU bool "Fault-injection capability for IOMMU" depends on FAULT_INJECTION diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 3a55f493c7da7..779becb895bef 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -66,6 +66,7 @@ config S390 def_bool y select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS + select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_SG_CHAIN diff --git a/arch/s390/Kconfig.debug b/arch/s390/Kconfig.debug index c56878e1245fb..26c5d5beb4beb 100644 --- a/arch/s390/Kconfig.debug +++ b/arch/s390/Kconfig.debug @@ -5,18 +5,6 @@ config TRACE_IRQFLAGS_SUPPORT source "lib/Kconfig.debug" -config STRICT_DEVMEM - def_bool y - prompt "Filter access to /dev/mem" - ---help--- - This option restricts access to /dev/mem. If this option is - disabled, you allow userspace access to all memory, including - kernel and userspace memory. Accidental memory access is likely - to be disastrous. - Memory access is required for experts who want to debug the kernel. - - If you are unsure, say Y. - config S390_PTDUMP bool "Export kernel pagetable layout to userspace via debugfs" depends on DEBUG_KERNEL diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 106c21bd7f449..cf31168875093 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -19,6 +19,7 @@ config TILE select VIRT_TO_BUS select SYS_HYPERVISOR select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS + select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_CLOCKEVENTS select MODULES_USE_ELF_RELA @@ -116,9 +117,6 @@ config ARCH_DISCONTIGMEM_DEFAULT config TRACE_IRQFLAGS_SUPPORT def_bool y -config STRICT_DEVMEM - def_bool y - # SMP is required for Tilera Linux. config SMP def_bool y diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index c9faddc61100f..5dc4c0a43ccde 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig @@ -1,5 +1,6 @@ config UNICORE32 def_bool y + select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_MIGHT_HAVE_PC_SERIO select HAVE_MEMBLOCK diff --git a/arch/unicore32/Kconfig.debug b/arch/unicore32/Kconfig.debug index 1a36262398435..f075bbe1d46f4 100644 --- a/arch/unicore32/Kconfig.debug +++ b/arch/unicore32/Kconfig.debug @@ -2,20 +2,6 @@ menu "Kernel hacking" source "lib/Kconfig.debug" -config STRICT_DEVMEM - bool "Filter access to /dev/mem" - depends on MMU - ---help--- - If this option is disabled, you allow userspace (root) access to all - of memory, including kernel and userspace memory. Accidental - access to this is obviously disastrous, but specific access can - be used by people debugging the kernel. - - If this option is switched on, the /dev/mem file only allows - userspace access to memory mapped peripherals. - - If in doubt, say Y. - config EARLY_PRINTK def_bool DEBUG_OCD help diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index db3622f22b618..75fba1fc205d0 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -24,6 +24,7 @@ config X86 select ARCH_DISCARD_MEMBLOCK select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS + select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_FAST_MULTIPLIER select ARCH_HAS_GCOV_PROFILE_ALL diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 137dfa96aa14e..1116452fcfc23 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -5,23 +5,6 @@ config TRACE_IRQFLAGS_SUPPORT source "lib/Kconfig.debug" -config STRICT_DEVMEM - bool "Filter access to /dev/mem" - ---help--- - If this option is disabled, you allow userspace (root) access to all - of memory, including kernel and userspace memory. Accidental - access to this is obviously disastrous, but specific access can - be used by people debugging the kernel. Note that with PAT support - enabled, even in this case there are restrictions on /dev/mem - use due to the cache aliasing requirements. - - If this option is switched on, the /dev/mem file only allows - userspace access to PCI space and the BIOS code and data regions. - This is sufficient for dosemu and X and all common users of - /dev/mem. - - If in doubt, say Y. - config X86_VERBOSE_BOOTUP bool "Enable verbose x86 bootup info messages" default y diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 8c15b29d5adc6..289dfcbc14eb6 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1853,3 +1853,25 @@ source "samples/Kconfig" source "lib/Kconfig.kgdb" +config ARCH_HAS_DEVMEM_IS_ALLOWED + bool + +config STRICT_DEVMEM + bool "Filter access to /dev/mem" + depends on MMU + depends on ARCH_HAS_DEVMEM_IS_ALLOWED + default y if TILE || PPC + ---help--- + If this option is disabled, you allow userspace (root) access to all + of memory, including kernel and userspace memory. Accidental + access to this is obviously disastrous, but specific access can + be used by people debugging the kernel. Note that with PAT support + enabled, even in this case there are restrictions on /dev/mem + use due to the cache aliasing requirements. + + If this option is switched on, the /dev/mem file only allows + userspace access to PCI space and the BIOS code and data regions. + This is sufficient for dosemu and X and all common users of + /dev/mem. + + If in doubt, say Y. -- GitLab From 90a545e981267e917b9d698ce07affd69787db87 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 23 Nov 2015 15:49:03 -0800 Subject: [PATCH 2366/2855] restrict /dev/mem to idle io memory ranges This effectively promotes IORESOURCE_BUSY to IORESOURCE_EXCLUSIVE semantics by default. If userspace really believes it is safe to access the memory region it can also perform the extra step of disabling an active driver. This protects device address ranges with read side effects and otherwise directs userspace to use the driver. Persistent memory presents a large "mistake surface" to /dev/mem as now accidental writes can corrupt a filesystem. In general if a device driver is busily using a memory region it already informs other parts of the kernel to not touch it via request_mem_region(). /dev/mem should honor the same safety restriction by default. Debugging a device driver from userspace becomes more difficult with this enabled. Any application using /dev/mem or mmap of sysfs pci resources will now need to perform the extra step of either: 1/ Disabling the driver, for example: echo > /dev/bus//drivers//unbind 2/ Rebooting with "iomem=relaxed" on the command line 3/ Recompiling with CONFIG_IO_STRICT_DEVMEM=n Traditional users of /dev/mem like dosemu are unaffected because the first 1MB of memory is not subject to the IO_STRICT_DEVMEM restriction. Legacy X configurations use /dev/mem to talk to graphics hardware, but that functionality has since moved to kernel graphics drivers. Cc: Arnd Bergmann Cc: Russell King Cc: Andrew Morton Cc: Greg Kroah-Hartman Acked-by: Kees Cook Acked-by: Ingo Molnar Signed-off-by: Dan Williams --- kernel/resource.c | 11 +++++++++-- lib/Kconfig.debug | 23 ++++++++++++++++++++--- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/kernel/resource.c b/kernel/resource.c index f150dbbe6f62d..09c0597840b02 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -1498,8 +1498,15 @@ int iomem_is_exclusive(u64 addr) break; if (p->end < addr) continue; - if (p->flags & IORESOURCE_BUSY && - p->flags & IORESOURCE_EXCLUSIVE) { + /* + * A resource is exclusive if IORESOURCE_EXCLUSIVE is set + * or CONFIG_IO_STRICT_DEVMEM is enabled and the + * resource is busy. + */ + if ((p->flags & IORESOURCE_BUSY) == 0) + continue; + if (IS_ENABLED(CONFIG_IO_STRICT_DEVMEM) + || p->flags & IORESOURCE_EXCLUSIVE) { err = 1; break; } diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 289dfcbc14eb6..073496dea8482 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1869,9 +1869,26 @@ config STRICT_DEVMEM enabled, even in this case there are restrictions on /dev/mem use due to the cache aliasing requirements. + If this option is switched on, and IO_STRICT_DEVMEM=n, the /dev/mem + file only allows userspace access to PCI space and the BIOS code and + data regions. This is sufficient for dosemu and X and all common + users of /dev/mem. + + If in doubt, say Y. + +config IO_STRICT_DEVMEM + bool "Filter I/O access to /dev/mem" + depends on STRICT_DEVMEM + default STRICT_DEVMEM + ---help--- + If this option is disabled, you allow userspace (root) access to all + io-memory regardless of whether a driver is actively using that + range. Accidental access to this is obviously disastrous, but + specific access can be used by people debugging kernel drivers. + If this option is switched on, the /dev/mem file only allows - userspace access to PCI space and the BIOS code and data regions. - This is sufficient for dosemu and X and all common users of - /dev/mem. + userspace access to *idle* io-memory ranges (see /proc/iomem) This + may break traditional users of /dev/mem (dosemu, legacy X, etc...) + if the driver using a given range cannot be disabled. If in doubt, say Y. -- GitLab From 4ebb16ca9a06a54cdb2e7f2ce1e506fa4d432445 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 28 Oct 2015 07:48:19 +0900 Subject: [PATCH 2367/2855] block: introduce bdev_file_inode() Similar to the file_inode() helper, provide a helper to lookup the inode for a raw block device itself. Cc: Al Viro Suggested-by: Jan Kara Reviewed-by: Jan Kara Reviewed-by: Jeff Moyer Signed-off-by: Dan Williams --- fs/block_dev.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/fs/block_dev.c b/fs/block_dev.c index 44d4a1e9244e7..52248bce42d28 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -156,11 +156,16 @@ blkdev_get_block(struct inode *inode, sector_t iblock, return 0; } +static struct inode *bdev_file_inode(struct file *file) +{ + return file->f_mapping->host; +} + static ssize_t blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) { struct file *file = iocb->ki_filp; - struct inode *inode = file->f_mapping->host; + struct inode *inode = bdev_file_inode(file); if (IS_DAX(inode)) return dax_do_io(iocb, inode, iter, offset, blkdev_get_block, @@ -338,7 +343,7 @@ static int blkdev_write_end(struct file *file, struct address_space *mapping, */ static loff_t block_llseek(struct file *file, loff_t offset, int whence) { - struct inode *bd_inode = file->f_mapping->host; + struct inode *bd_inode = bdev_file_inode(file); loff_t retval; mutex_lock(&bd_inode->i_mutex); @@ -349,7 +354,7 @@ static loff_t block_llseek(struct file *file, loff_t offset, int whence) int blkdev_fsync(struct file *filp, loff_t start, loff_t end, int datasync) { - struct inode *bd_inode = filp->f_mapping->host; + struct inode *bd_inode = bdev_file_inode(filp); struct block_device *bdev = I_BDEV(bd_inode); int error; @@ -1605,14 +1610,14 @@ EXPORT_SYMBOL(blkdev_put); static int blkdev_close(struct inode * inode, struct file * filp) { - struct block_device *bdev = I_BDEV(filp->f_mapping->host); + struct block_device *bdev = I_BDEV(bdev_file_inode(filp)); blkdev_put(bdev, filp->f_mode); return 0; } static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) { - struct block_device *bdev = I_BDEV(file->f_mapping->host); + struct block_device *bdev = I_BDEV(bdev_file_inode(file)); fmode_t mode = file->f_mode; /* @@ -1637,7 +1642,7 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; - struct inode *bd_inode = file->f_mapping->host; + struct inode *bd_inode = bdev_file_inode(file); loff_t size = i_size_read(bd_inode); struct blk_plug plug; ssize_t ret; @@ -1669,7 +1674,7 @@ EXPORT_SYMBOL_GPL(blkdev_write_iter); ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to) { struct file *file = iocb->ki_filp; - struct inode *bd_inode = file->f_mapping->host; + struct inode *bd_inode = bdev_file_inode(file); loff_t size = i_size_read(bd_inode); loff_t pos = iocb->ki_pos; -- GitLab From 5a023cdba50c5f5f2bc351783b3131699deb3937 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 30 Nov 2015 10:20:29 -0800 Subject: [PATCH 2368/2855] block: enable dax for raw block devices If an application wants exclusive access to all of the persistent memory provided by an NVDIMM namespace it can use this raw-block-dax facility to forgo establishing a filesystem. This capability is targeted primarily to hypervisors wanting to provision persistent memory for guests. It can be disabled / enabled dynamically via the new BLKDAXSET ioctl. Cc: Jeff Moyer Cc: Christoph Hellwig Cc: Dave Chinner Cc: Andrew Morton Cc: Ross Zwisler Reported-by: kbuild test robot Reviewed-by: Jan Kara Signed-off-by: Dan Williams --- block/ioctl.c | 61 ++++++++++++++++++++++++ fs/block_dev.c | 103 ++++++++++++++++++++++++++++++++++++---- include/linux/fs.h | 11 +++++ include/uapi/linux/fs.h | 2 + 4 files changed, 169 insertions(+), 8 deletions(-) diff --git a/block/ioctl.c b/block/ioctl.c index 0918aed2d847e..7a964d842913f 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -406,6 +406,62 @@ static inline int is_unrecognized_ioctl(int ret) ret == -ENOIOCTLCMD; } +#ifdef CONFIG_FS_DAX +bool blkdev_dax_capable(struct block_device *bdev) +{ + struct gendisk *disk = bdev->bd_disk; + + if (!disk->fops->direct_access) + return false; + + /* + * If the partition is not aligned on a page boundary, we can't + * do dax I/O to it. + */ + if ((bdev->bd_part->start_sect % (PAGE_SIZE / 512)) + || (bdev->bd_part->nr_sects % (PAGE_SIZE / 512))) + return false; + + return true; +} + +static int blkdev_daxset(struct block_device *bdev, unsigned long argp) +{ + unsigned long arg; + int rc = 0; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if (get_user(arg, (int __user *)(argp))) + return -EFAULT; + arg = !!arg; + if (arg == !!(bdev->bd_inode->i_flags & S_DAX)) + return 0; + + if (arg) + arg = S_DAX; + + if (arg && !blkdev_dax_capable(bdev)) + return -ENOTTY; + + mutex_lock(&bdev->bd_inode->i_mutex); + if (bdev->bd_map_count == 0) + inode_set_flags(bdev->bd_inode, arg, S_DAX); + else + rc = -EBUSY; + mutex_unlock(&bdev->bd_inode->i_mutex); + return rc; +} +#else +static int blkdev_daxset(struct block_device *bdev, int arg) +{ + if (arg) + return -ENOTTY; + return 0; +} +#endif + static int blkdev_flushbuf(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) { @@ -568,6 +624,11 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, case BLKTRACESETUP: case BLKTRACETEARDOWN: return blk_trace_ioctl(bdev, cmd, argp); + case BLKDAXSET: + return blkdev_daxset(bdev, arg); + case BLKDAXGET: + return put_int(arg, !!(bdev->bd_inode->i_flags & S_DAX)); + break; case IOC_PR_REGISTER: return blkdev_pr_register(bdev, argp); case IOC_PR_RESERVE: diff --git a/fs/block_dev.c b/fs/block_dev.c index 52248bce42d28..5c0b2cba870ed 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1235,8 +1235,11 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) } } - if (!ret) + if (!ret) { bd_set_size(bdev,(loff_t)get_capacity(disk)<<9); + if (!blkdev_dax_capable(bdev)) + bdev->bd_inode->i_flags &= ~S_DAX; + } /* * If the device is invalidated, rescan partition @@ -1250,6 +1253,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) else if (ret == -ENOMEDIUM) invalidate_partitions(disk, bdev); } + if (ret) goto out_clear; } else { @@ -1270,12 +1274,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) goto out_clear; } bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9); - /* - * If the partition is not aligned on a page - * boundary, we can't do dax I/O to it. - */ - if ((bdev->bd_part->start_sect % (PAGE_SIZE / 512)) || - (bdev->bd_part->nr_sects % (PAGE_SIZE / 512))) + if (!blkdev_dax_capable(bdev)) bdev->bd_inode->i_flags &= ~S_DAX; } } else { @@ -1713,13 +1712,101 @@ static const struct address_space_operations def_blk_aops = { .is_dirty_writeback = buffer_check_dirty_writeback, }; +#ifdef CONFIG_FS_DAX +/* + * In the raw block case we do not need to contend with truncation nor + * unwritten file extents. Without those concerns there is no need for + * additional locking beyond the mmap_sem context that these routines + * are already executing under. + * + * Note, there is no protection if the block device is dynamically + * resized (partition grow/shrink) during a fault. A stable block device + * size is already not enforced in the blkdev_direct_IO path. + * + * For DAX, it is the responsibility of the block device driver to + * ensure the whole-disk device size is stable while requests are in + * flight. + * + * Finally, unlike the filemap_page_mkwrite() case there is no + * filesystem superblock to sync against freezing. We still include a + * pfn_mkwrite callback for dax drivers to receive write fault + * notifications. + */ +static int blkdev_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + return __dax_fault(vma, vmf, blkdev_get_block, NULL); +} + +static int blkdev_dax_pmd_fault(struct vm_area_struct *vma, unsigned long addr, + pmd_t *pmd, unsigned int flags) +{ + return __dax_pmd_fault(vma, addr, pmd, flags, blkdev_get_block, NULL); +} + +static void blkdev_vm_open(struct vm_area_struct *vma) +{ + struct inode *bd_inode = bdev_file_inode(vma->vm_file); + struct block_device *bdev = I_BDEV(bd_inode); + + mutex_lock(&bd_inode->i_mutex); + bdev->bd_map_count++; + mutex_unlock(&bd_inode->i_mutex); +} + +static void blkdev_vm_close(struct vm_area_struct *vma) +{ + struct inode *bd_inode = bdev_file_inode(vma->vm_file); + struct block_device *bdev = I_BDEV(bd_inode); + + mutex_lock(&bd_inode->i_mutex); + bdev->bd_map_count--; + mutex_unlock(&bd_inode->i_mutex); +} + +static const struct vm_operations_struct blkdev_dax_vm_ops = { + .open = blkdev_vm_open, + .close = blkdev_vm_close, + .fault = blkdev_dax_fault, + .pmd_fault = blkdev_dax_pmd_fault, + .pfn_mkwrite = blkdev_dax_fault, +}; + +static const struct vm_operations_struct blkdev_default_vm_ops = { + .open = blkdev_vm_open, + .close = blkdev_vm_close, + .fault = filemap_fault, + .map_pages = filemap_map_pages, +}; + +static int blkdev_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct inode *bd_inode = bdev_file_inode(file); + struct block_device *bdev = I_BDEV(bd_inode); + + file_accessed(file); + mutex_lock(&bd_inode->i_mutex); + bdev->bd_map_count++; + if (IS_DAX(bd_inode)) { + vma->vm_ops = &blkdev_dax_vm_ops; + vma->vm_flags |= VM_MIXEDMAP | VM_HUGEPAGE; + } else { + vma->vm_ops = &blkdev_default_vm_ops; + } + mutex_unlock(&bd_inode->i_mutex); + + return 0; +} +#else +#define blkdev_mmap generic_file_mmap +#endif + const struct file_operations def_blk_fops = { .open = blkdev_open, .release = blkdev_close, .llseek = block_llseek, .read_iter = blkdev_read_iter, .write_iter = blkdev_write_iter, - .mmap = generic_file_mmap, + .mmap = blkdev_mmap, .fsync = blkdev_fsync, .unlocked_ioctl = block_ioctl, #ifdef CONFIG_COMPAT diff --git a/include/linux/fs.h b/include/linux/fs.h index 3aa5142541614..96fabc93b583f 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -482,6 +482,9 @@ struct block_device { int bd_fsfreeze_count; /* Mutex for freeze */ struct mutex bd_fsfreeze_mutex; +#ifdef CONFIG_FS_DAX + int bd_map_count; +#endif }; /* @@ -2264,6 +2267,14 @@ extern struct super_block *freeze_bdev(struct block_device *); extern void emergency_thaw_all(void); extern int thaw_bdev(struct block_device *bdev, struct super_block *sb); extern int fsync_bdev(struct block_device *); +#ifdef CONFIG_FS_DAX +extern bool blkdev_dax_capable(struct block_device *bdev); +#else +static inline bool blkdev_dax_capable(struct block_device *bdev) +{ + return false; +} +#endif extern struct super_block *blockdev_superblock; diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index f15d980249b50..401c409e92398 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -152,6 +152,8 @@ struct inodes_stat_t { #define BLKSECDISCARD _IO(0x12,125) #define BLKROTATIONAL _IO(0x12,126) #define BLKZEROOUT _IO(0x12,127) +#define BLKDAXSET _IO(0x12,128) +#define BLKDAXGET _IO(0x12,129) #define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ #define FIBMAP _IO(0x00,1) /* bmap access */ -- GitLab From ac34f15e0c6d2fd58480052b6985f6991fb53bcc Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 29 Dec 2015 14:02:29 -0800 Subject: [PATCH 2369/2855] block: fix del_gendisk() vs blkdev_ioctl crash When tearing down a block device early in its lifetime, userspace may still be performing discovery actions like blkdev_ioctl() to re-read partitions. The nvdimm_revalidate_disk() implementation depends on disk->driverfs_dev to be valid at entry. However, it is set to NULL in del_gendisk() and fatally this is happening *before* the disk device is deleted from userspace view. There's no reason for del_gendisk() to clear ->driverfs_dev. That device is the parent of the disk. It is guaranteed to not be freed until the disk, as a child, drops its ->parent reference. We could also fix this issue locally in nvdimm_revalidate_disk() by using disk_to_dev(disk)->parent, but lets fix it globally since ->driverfs_dev follows the lifetime of the parent. Longer term we should probably just add a @parent parameter to add_disk(), and stop carrying this pointer in the gendisk. BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] nvdimm_revalidate_disk+0x18/0x90 [libnvdimm] CPU: 2 PID: 538 Comm: systemd-udevd Tainted: G O 4.4.0-rc5 #2257 [..] Call Trace: [] rescan_partitions+0x87/0x2c0 [] ? __lock_is_held+0x49/0x70 [] __blkdev_reread_part+0x72/0xb0 [] blkdev_reread_part+0x25/0x40 [] blkdev_ioctl+0x4fd/0x9c0 [] ? current_kernel_time64+0x69/0xd0 [] block_ioctl+0x3d/0x50 [] do_vfs_ioctl+0x308/0x560 [] ? __audit_syscall_entry+0xb1/0x100 [] ? do_audit_syscall_entry+0x66/0x70 [] SyS_ioctl+0x79/0x90 [] entry_SYSCALL_64_fastpath+0x12/0x76 Reported-by: Robert Hu Signed-off-by: Dan Williams --- block/genhd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/block/genhd.c b/block/genhd.c index e5cafa51567c9..1a971bebbbfea 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -664,7 +664,6 @@ void del_gendisk(struct gendisk *disk) kobject_put(disk->part0.holder_dir); kobject_put(disk->slave_dir); - disk->driverfs_dev = NULL; if (!sysfs_deprecated) sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); pm_runtime_set_memalloc_noio(disk_to_dev(disk), false); -- GitLab From 9e0e252a048b0ba5066f0dc15c3b2468ffe5c422 Mon Sep 17 00:00:00 2001 From: Vishal Verma Date: Thu, 24 Dec 2015 19:20:32 -0700 Subject: [PATCH 2370/2855] badblocks: Add core badblock management code Take the core badblocks implementation from md, and make it generally available. This follows the same style as kernel implementations of linked lists, rb-trees etc, where you can have a structure that can be embedded anywhere, and accessor functions to manipulate the data. The only changes in this copy of the code are ones to generalize function/variable names from md-specific ones. Also add init and free functions. Signed-off-by: Vishal Verma Signed-off-by: Dan Williams --- block/Makefile | 2 +- block/badblocks.c | 561 ++++++++++++++++++++++++++++++++++++++ include/linux/badblocks.h | 53 ++++ 3 files changed, 615 insertions(+), 1 deletion(-) create mode 100644 block/badblocks.c create mode 100644 include/linux/badblocks.h diff --git a/block/Makefile b/block/Makefile index 00ecc97629db7..db5f622c9d67e 100644 --- a/block/Makefile +++ b/block/Makefile @@ -8,7 +8,7 @@ obj-$(CONFIG_BLOCK) := bio.o elevator.o blk-core.o blk-tag.o blk-sysfs.o \ blk-iopoll.o blk-lib.o blk-mq.o blk-mq-tag.o \ blk-mq-sysfs.o blk-mq-cpu.o blk-mq-cpumap.o ioctl.o \ genhd.o scsi_ioctl.o partition-generic.o ioprio.o \ - partitions/ + badblocks.o partitions/ obj-$(CONFIG_BOUNCE) += bounce.o obj-$(CONFIG_BLK_DEV_BSG) += bsg.o diff --git a/block/badblocks.c b/block/badblocks.c new file mode 100644 index 0000000000000..96aeb9194a2ef --- /dev/null +++ b/block/badblocks.c @@ -0,0 +1,561 @@ +/* + * Bad block management + * + * - Heavily based on MD badblocks code from Neil Brown + * + * Copyright (c) 2015, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +/** + * badblocks_check() - check a given range for bad sectors + * @bb: the badblocks structure that holds all badblock information + * @s: sector (start) at which to check for badblocks + * @sectors: number of sectors to check for badblocks + * @first_bad: pointer to store location of the first badblock + * @bad_sectors: pointer to store number of badblocks after @first_bad + * + * We can record which blocks on each device are 'bad' and so just + * fail those blocks, or that stripe, rather than the whole device. + * Entries in the bad-block table are 64bits wide. This comprises: + * Length of bad-range, in sectors: 0-511 for lengths 1-512 + * Start of bad-range, sector offset, 54 bits (allows 8 exbibytes) + * A 'shift' can be set so that larger blocks are tracked and + * consequently larger devices can be covered. + * 'Acknowledged' flag - 1 bit. - the most significant bit. + * + * Locking of the bad-block table uses a seqlock so badblocks_check + * might need to retry if it is very unlucky. + * We will sometimes want to check for bad blocks in a bi_end_io function, + * so we use the write_seqlock_irq variant. + * + * When looking for a bad block we specify a range and want to + * know if any block in the range is bad. So we binary-search + * to the last range that starts at-or-before the given endpoint, + * (or "before the sector after the target range") + * then see if it ends after the given start. + * + * Return: + * 0: there are no known bad blocks in the range + * 1: there are known bad block which are all acknowledged + * -1: there are bad blocks which have not yet been acknowledged in metadata. + * plus the start/length of the first bad section we overlap. + */ +int badblocks_check(struct badblocks *bb, sector_t s, int sectors, + sector_t *first_bad, int *bad_sectors) +{ + int hi; + int lo; + u64 *p = bb->page; + int rv; + sector_t target = s + sectors; + unsigned seq; + + if (bb->shift > 0) { + /* round the start down, and the end up */ + s >>= bb->shift; + target += (1<shift) - 1; + target >>= bb->shift; + sectors = target - s; + } + /* 'target' is now the first block after the bad range */ + +retry: + seq = read_seqbegin(&bb->lock); + lo = 0; + rv = 0; + hi = bb->count; + + /* Binary search between lo and hi for 'target' + * i.e. for the last range that starts before 'target' + */ + /* INVARIANT: ranges before 'lo' and at-or-after 'hi' + * are known not to be the last range before target. + * VARIANT: hi-lo is the number of possible + * ranges, and decreases until it reaches 1 + */ + while (hi - lo > 1) { + int mid = (lo + hi) / 2; + sector_t a = BB_OFFSET(p[mid]); + + if (a < target) + /* This could still be the one, earlier ranges + * could not. + */ + lo = mid; + else + /* This and later ranges are definitely out. */ + hi = mid; + } + /* 'lo' might be the last that started before target, but 'hi' isn't */ + if (hi > lo) { + /* need to check all range that end after 's' to see if + * any are unacknowledged. + */ + while (lo >= 0 && + BB_OFFSET(p[lo]) + BB_LEN(p[lo]) > s) { + if (BB_OFFSET(p[lo]) < target) { + /* starts before the end, and finishes after + * the start, so they must overlap + */ + if (rv != -1 && BB_ACK(p[lo])) + rv = 1; + else + rv = -1; + *first_bad = BB_OFFSET(p[lo]); + *bad_sectors = BB_LEN(p[lo]); + } + lo--; + } + } + + if (read_seqretry(&bb->lock, seq)) + goto retry; + + return rv; +} +EXPORT_SYMBOL_GPL(badblocks_check); + +/** + * badblocks_set() - Add a range of bad blocks to the table. + * @bb: the badblocks structure that holds all badblock information + * @s: first sector to mark as bad + * @sectors: number of sectors to mark as bad + * @acknowledged: weather to mark the bad sectors as acknowledged + * + * This might extend the table, or might contract it if two adjacent ranges + * can be merged. We binary-search to find the 'insertion' point, then + * decide how best to handle it. + * + * Return: + * 0: success + * 1: failed to set badblocks (out of space) + */ +int badblocks_set(struct badblocks *bb, sector_t s, int sectors, + int acknowledged) +{ + u64 *p; + int lo, hi; + int rv = 0; + unsigned long flags; + + if (bb->shift < 0) + /* badblocks are disabled */ + return 0; + + if (bb->shift) { + /* round the start down, and the end up */ + sector_t next = s + sectors; + + s >>= bb->shift; + next += (1<shift) - 1; + next >>= bb->shift; + sectors = next - s; + } + + write_seqlock_irqsave(&bb->lock, flags); + + p = bb->page; + lo = 0; + hi = bb->count; + /* Find the last range that starts at-or-before 's' */ + while (hi - lo > 1) { + int mid = (lo + hi) / 2; + sector_t a = BB_OFFSET(p[mid]); + + if (a <= s) + lo = mid; + else + hi = mid; + } + if (hi > lo && BB_OFFSET(p[lo]) > s) + hi = lo; + + if (hi > lo) { + /* we found a range that might merge with the start + * of our new range + */ + sector_t a = BB_OFFSET(p[lo]); + sector_t e = a + BB_LEN(p[lo]); + int ack = BB_ACK(p[lo]); + + if (e >= s) { + /* Yes, we can merge with a previous range */ + if (s == a && s + sectors >= e) + /* new range covers old */ + ack = acknowledged; + else + ack = ack && acknowledged; + + if (e < s + sectors) + e = s + sectors; + if (e - a <= BB_MAX_LEN) { + p[lo] = BB_MAKE(a, e-a, ack); + s = e; + } else { + /* does not all fit in one range, + * make p[lo] maximal + */ + if (BB_LEN(p[lo]) != BB_MAX_LEN) + p[lo] = BB_MAKE(a, BB_MAX_LEN, ack); + s = a + BB_MAX_LEN; + } + sectors = e - s; + } + } + if (sectors && hi < bb->count) { + /* 'hi' points to the first range that starts after 's'. + * Maybe we can merge with the start of that range + */ + sector_t a = BB_OFFSET(p[hi]); + sector_t e = a + BB_LEN(p[hi]); + int ack = BB_ACK(p[hi]); + + if (a <= s + sectors) { + /* merging is possible */ + if (e <= s + sectors) { + /* full overlap */ + e = s + sectors; + ack = acknowledged; + } else + ack = ack && acknowledged; + + a = s; + if (e - a <= BB_MAX_LEN) { + p[hi] = BB_MAKE(a, e-a, ack); + s = e; + } else { + p[hi] = BB_MAKE(a, BB_MAX_LEN, ack); + s = a + BB_MAX_LEN; + } + sectors = e - s; + lo = hi; + hi++; + } + } + if (sectors == 0 && hi < bb->count) { + /* we might be able to combine lo and hi */ + /* Note: 's' is at the end of 'lo' */ + sector_t a = BB_OFFSET(p[hi]); + int lolen = BB_LEN(p[lo]); + int hilen = BB_LEN(p[hi]); + int newlen = lolen + hilen - (s - a); + + if (s >= a && newlen < BB_MAX_LEN) { + /* yes, we can combine them */ + int ack = BB_ACK(p[lo]) && BB_ACK(p[hi]); + + p[lo] = BB_MAKE(BB_OFFSET(p[lo]), newlen, ack); + memmove(p + hi, p + hi + 1, + (bb->count - hi - 1) * 8); + bb->count--; + } + } + while (sectors) { + /* didn't merge (it all). + * Need to add a range just before 'hi' + */ + if (bb->count >= MAX_BADBLOCKS) { + /* No room for more */ + rv = 1; + break; + } else { + int this_sectors = sectors; + + memmove(p + hi + 1, p + hi, + (bb->count - hi) * 8); + bb->count++; + + if (this_sectors > BB_MAX_LEN) + this_sectors = BB_MAX_LEN; + p[hi] = BB_MAKE(s, this_sectors, acknowledged); + sectors -= this_sectors; + s += this_sectors; + } + } + + bb->changed = 1; + if (!acknowledged) + bb->unacked_exist = 1; + write_sequnlock_irqrestore(&bb->lock, flags); + + return rv; +} +EXPORT_SYMBOL_GPL(badblocks_set); + +/** + * badblocks_clear() - Remove a range of bad blocks to the table. + * @bb: the badblocks structure that holds all badblock information + * @s: first sector to mark as bad + * @sectors: number of sectors to mark as bad + * + * This may involve extending the table if we spilt a region, + * but it must not fail. So if the table becomes full, we just + * drop the remove request. + * + * Return: + * 0: success + * 1: failed to clear badblocks + */ +int badblocks_clear(struct badblocks *bb, sector_t s, int sectors) +{ + u64 *p; + int lo, hi; + sector_t target = s + sectors; + int rv = 0; + + if (bb->shift > 0) { + /* When clearing we round the start up and the end down. + * This should not matter as the shift should align with + * the block size and no rounding should ever be needed. + * However it is better the think a block is bad when it + * isn't than to think a block is not bad when it is. + */ + s += (1<shift) - 1; + s >>= bb->shift; + target >>= bb->shift; + sectors = target - s; + } + + write_seqlock_irq(&bb->lock); + + p = bb->page; + lo = 0; + hi = bb->count; + /* Find the last range that starts before 'target' */ + while (hi - lo > 1) { + int mid = (lo + hi) / 2; + sector_t a = BB_OFFSET(p[mid]); + + if (a < target) + lo = mid; + else + hi = mid; + } + if (hi > lo) { + /* p[lo] is the last range that could overlap the + * current range. Earlier ranges could also overlap, + * but only this one can overlap the end of the range. + */ + if (BB_OFFSET(p[lo]) + BB_LEN(p[lo]) > target) { + /* Partial overlap, leave the tail of this range */ + int ack = BB_ACK(p[lo]); + sector_t a = BB_OFFSET(p[lo]); + sector_t end = a + BB_LEN(p[lo]); + + if (a < s) { + /* we need to split this range */ + if (bb->count >= MAX_BADBLOCKS) { + rv = -ENOSPC; + goto out; + } + memmove(p+lo+1, p+lo, (bb->count - lo) * 8); + bb->count++; + p[lo] = BB_MAKE(a, s-a, ack); + lo++; + } + p[lo] = BB_MAKE(target, end - target, ack); + /* there is no longer an overlap */ + hi = lo; + lo--; + } + while (lo >= 0 && + BB_OFFSET(p[lo]) + BB_LEN(p[lo]) > s) { + /* This range does overlap */ + if (BB_OFFSET(p[lo]) < s) { + /* Keep the early parts of this range. */ + int ack = BB_ACK(p[lo]); + sector_t start = BB_OFFSET(p[lo]); + + p[lo] = BB_MAKE(start, s - start, ack); + /* now low doesn't overlap, so.. */ + break; + } + lo--; + } + /* 'lo' is strictly before, 'hi' is strictly after, + * anything between needs to be discarded + */ + if (hi - lo > 1) { + memmove(p+lo+1, p+hi, (bb->count - hi) * 8); + bb->count -= (hi - lo - 1); + } + } + + bb->changed = 1; +out: + write_sequnlock_irq(&bb->lock); + return rv; +} +EXPORT_SYMBOL_GPL(badblocks_clear); + +/** + * ack_all_badblocks() - Acknowledge all bad blocks in a list. + * @bb: the badblocks structure that holds all badblock information + * + * This only succeeds if ->changed is clear. It is used by + * in-kernel metadata updates + */ +void ack_all_badblocks(struct badblocks *bb) +{ + if (bb->page == NULL || bb->changed) + /* no point even trying */ + return; + write_seqlock_irq(&bb->lock); + + if (bb->changed == 0 && bb->unacked_exist) { + u64 *p = bb->page; + int i; + + for (i = 0; i < bb->count ; i++) { + if (!BB_ACK(p[i])) { + sector_t start = BB_OFFSET(p[i]); + int len = BB_LEN(p[i]); + + p[i] = BB_MAKE(start, len, 1); + } + } + bb->unacked_exist = 0; + } + write_sequnlock_irq(&bb->lock); +} +EXPORT_SYMBOL_GPL(ack_all_badblocks); + +/** + * badblocks_show() - sysfs access to bad-blocks list + * @bb: the badblocks structure that holds all badblock information + * @page: buffer received from sysfs + * @unack: weather to show unacknowledged badblocks + * + * Return: + * Length of returned data + */ +ssize_t badblocks_show(struct badblocks *bb, char *page, int unack) +{ + size_t len; + int i; + u64 *p = bb->page; + unsigned seq; + + if (bb->shift < 0) + return 0; + +retry: + seq = read_seqbegin(&bb->lock); + + len = 0; + i = 0; + + while (len < PAGE_SIZE && i < bb->count) { + sector_t s = BB_OFFSET(p[i]); + unsigned int length = BB_LEN(p[i]); + int ack = BB_ACK(p[i]); + + i++; + + if (unack && ack) + continue; + + len += snprintf(page+len, PAGE_SIZE-len, "%llu %u\n", + (unsigned long long)s << bb->shift, + length << bb->shift); + } + if (unack && len == 0) + bb->unacked_exist = 0; + + if (read_seqretry(&bb->lock, seq)) + goto retry; + + return len; +} +EXPORT_SYMBOL_GPL(badblocks_show); + +/** + * badblocks_store() - sysfs access to bad-blocks list + * @bb: the badblocks structure that holds all badblock information + * @page: buffer received from sysfs + * @len: length of data received from sysfs + * @unack: weather to show unacknowledged badblocks + * + * Return: + * Length of the buffer processed or -ve error. + */ +ssize_t badblocks_store(struct badblocks *bb, const char *page, size_t len, + int unack) +{ + unsigned long long sector; + int length; + char newline; + + switch (sscanf(page, "%llu %d%c", §or, &length, &newline)) { + case 3: + if (newline != '\n') + return -EINVAL; + case 2: + if (length <= 0) + return -EINVAL; + break; + default: + return -EINVAL; + } + + if (badblocks_set(bb, sector, length, !unack)) + return -ENOSPC; + else + return len; +} +EXPORT_SYMBOL_GPL(badblocks_store); + +/** + * badblocks_init() - initialize the badblocks structure + * @bb: the badblocks structure that holds all badblock information + * @enable: weather to enable badblocks accounting + * + * Return: + * 0: success + * -ve errno: on error + */ +int badblocks_init(struct badblocks *bb, int enable) +{ + bb->count = 0; + if (enable) + bb->shift = 0; + else + bb->shift = -1; + bb->page = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (bb->page == (u64 *)0) { + bb->shift = -1; + return -ENOMEM; + } + seqlock_init(&bb->lock); + + return 0; +} +EXPORT_SYMBOL_GPL(badblocks_init); + +/** + * badblocks_free() - free the badblocks structure + * @bb: the badblocks structure that holds all badblock information + */ +void badblocks_free(struct badblocks *bb) +{ + kfree(bb->page); + bb->page = NULL; +} +EXPORT_SYMBOL_GPL(badblocks_free); diff --git a/include/linux/badblocks.h b/include/linux/badblocks.h new file mode 100644 index 0000000000000..929344630b51c --- /dev/null +++ b/include/linux/badblocks.h @@ -0,0 +1,53 @@ +#ifndef _LINUX_BADBLOCKS_H +#define _LINUX_BADBLOCKS_H + +#include +#include +#include +#include + +#define BB_LEN_MASK (0x00000000000001FFULL) +#define BB_OFFSET_MASK (0x7FFFFFFFFFFFFE00ULL) +#define BB_ACK_MASK (0x8000000000000000ULL) +#define BB_MAX_LEN 512 +#define BB_OFFSET(x) (((x) & BB_OFFSET_MASK) >> 9) +#define BB_LEN(x) (((x) & BB_LEN_MASK) + 1) +#define BB_ACK(x) (!!((x) & BB_ACK_MASK)) +#define BB_MAKE(a, l, ack) (((a)<<9) | ((l)-1) | ((u64)(!!(ack)) << 63)) + +/* Bad block numbers are stored sorted in a single page. + * 64bits is used for each block or extent. + * 54 bits are sector number, 9 bits are extent size, + * 1 bit is an 'acknowledged' flag. + */ +#define MAX_BADBLOCKS (PAGE_SIZE/8) + +struct badblocks { + int count; /* count of bad blocks */ + int unacked_exist; /* there probably are unacknowledged + * bad blocks. This is only cleared + * when a read discovers none + */ + int shift; /* shift from sectors to block size + * a -ve shift means badblocks are + * disabled.*/ + u64 *page; /* badblock list */ + int changed; + seqlock_t lock; + sector_t sector; + sector_t size; /* in sectors */ +}; + +int badblocks_check(struct badblocks *bb, sector_t s, int sectors, + sector_t *first_bad, int *bad_sectors); +int badblocks_set(struct badblocks *bb, sector_t s, int sectors, + int acknowledged); +int badblocks_clear(struct badblocks *bb, sector_t s, int sectors); +void ack_all_badblocks(struct badblocks *bb); +ssize_t badblocks_show(struct badblocks *bb, char *page, int unack); +ssize_t badblocks_store(struct badblocks *bb, const char *page, size_t len, + int unack); +int badblocks_init(struct badblocks *bb, int enable); +void badblocks_free(struct badblocks *bb); + +#endif -- GitLab From 99e6608c9e7414ae4f2168df8bf8fae3eb49e41f Mon Sep 17 00:00:00 2001 From: Vishal Verma Date: Sat, 9 Jan 2016 08:36:51 -0800 Subject: [PATCH 2371/2855] block: Add badblock management for gendisks NVDIMM devices, which can behave more like DRAM rather than block devices, may develop bad cache lines, or 'poison'. A block device exposed by the pmem driver can then consume poison via a read (or write), and cause a machine check. On platforms without machine check recovery features, this would mean a crash. The block device maintaining a runtime list of all known sectors that have poison can directly avoid this, and also provide a path forward to enable proper handling/recovery for DAX faults on such a device. Use the new badblock management interfaces to add a badblocks list to gendisks. Signed-off-by: Vishal Verma Signed-off-by: Dan Williams --- block/genhd.c | 76 +++++++++++++++++++++++++++++++++++++++++++ include/linux/genhd.h | 7 ++++ 2 files changed, 83 insertions(+) diff --git a/block/genhd.c b/block/genhd.c index 1a971bebbbfea..88579cf373b8b 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "blk.h" @@ -505,6 +506,16 @@ static int exact_lock(dev_t devt, void *data) return 0; } +int disk_alloc_badblocks(struct gendisk *disk) +{ + disk->bb = kzalloc(sizeof(*(disk->bb)), GFP_KERNEL); + if (!disk->bb) + return -ENOMEM; + + return badblocks_init(disk->bb, 1); +} +EXPORT_SYMBOL(disk_alloc_badblocks); + static void register_disk(struct gendisk *disk) { struct device *ddev = disk_to_dev(disk); @@ -659,6 +670,11 @@ void del_gendisk(struct gendisk *disk) blk_unregister_queue(disk); blk_unregister_region(disk_devt(disk), disk->minors); + if (disk->bb) { + badblocks_free(disk->bb); + kfree(disk->bb); + } + part_stat_set_all(&disk->part0, 0); disk->part0.stamp = 0; @@ -671,6 +687,63 @@ void del_gendisk(struct gendisk *disk) } EXPORT_SYMBOL(del_gendisk); +/* + * The gendisk usage of badblocks does not track acknowledgements for + * badblocks. We always assume they are acknowledged. + */ +int disk_check_badblocks(struct gendisk *disk, sector_t s, int sectors, + sector_t *first_bad, int *bad_sectors) +{ + if (!disk->bb) + return 0; + + return badblocks_check(disk->bb, s, sectors, first_bad, bad_sectors); +} +EXPORT_SYMBOL(disk_check_badblocks); + +int disk_set_badblocks(struct gendisk *disk, sector_t s, int sectors) +{ + if (!disk->bb) + return 0; + + return badblocks_set(disk->bb, s, sectors, 1); +} +EXPORT_SYMBOL(disk_set_badblocks); + +int disk_clear_badblocks(struct gendisk *disk, sector_t s, int sectors) +{ + if (!disk->bb) + return 0; + + return badblocks_clear(disk->bb, s, sectors); +} +EXPORT_SYMBOL(disk_clear_badblocks); + +/* sysfs access to bad-blocks list. */ +static ssize_t disk_badblocks_show(struct device *dev, + struct device_attribute *attr, + char *page) +{ + struct gendisk *disk = dev_to_disk(dev); + + if (!disk->bb) + return sprintf(page, "\n"); + + return badblocks_show(disk->bb, page, 0); +} + +static ssize_t disk_badblocks_store(struct device *dev, + struct device_attribute *attr, + const char *page, size_t len) +{ + struct gendisk *disk = dev_to_disk(dev); + + if (!disk->bb) + return -ENXIO; + + return badblocks_store(disk->bb, page, len, 0); +} + /** * get_gendisk - get partitioning information for a given device * @devt: device to get partitioning information for @@ -989,6 +1062,8 @@ static DEVICE_ATTR(discard_alignment, S_IRUGO, disk_discard_alignment_show, static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL); static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL); +static DEVICE_ATTR(badblocks, S_IRUGO | S_IWUSR, disk_badblocks_show, + disk_badblocks_store); #ifdef CONFIG_FAIL_MAKE_REQUEST static struct device_attribute dev_attr_fail = __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store); @@ -1010,6 +1085,7 @@ static struct attribute *disk_attrs[] = { &dev_attr_capability.attr, &dev_attr_stat.attr, &dev_attr_inflight.attr, + &dev_attr_badblocks.attr, #ifdef CONFIG_FAIL_MAKE_REQUEST &dev_attr_fail.attr, #endif diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 847cc1d916348..0bbec68800518 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -162,6 +162,7 @@ struct disk_part_tbl { }; struct disk_events; +struct badblocks; #if defined(CONFIG_BLK_DEV_INTEGRITY) @@ -213,6 +214,7 @@ struct gendisk { struct kobject integrity_kobj; #endif /* CONFIG_BLK_DEV_INTEGRITY */ int node_id; + struct badblocks *bb; }; static inline struct gendisk *part_to_disk(struct hd_struct *part) @@ -433,6 +435,11 @@ extern void add_disk(struct gendisk *disk); extern void del_gendisk(struct gendisk *gp); extern struct gendisk *get_gendisk(dev_t dev, int *partno); extern struct block_device *bdget_disk(struct gendisk *disk, int partno); +int disk_alloc_badblocks(struct gendisk *disk); +extern int disk_check_badblocks(struct gendisk *disk, sector_t s, int sectors, + sector_t *first_bad, int *bad_sectors); +extern int disk_set_badblocks(struct gendisk *disk, sector_t s, int sectors); +extern int disk_clear_badblocks(struct gendisk *disk, sector_t s, int sectors); extern void set_device_ro(struct block_device *bdev, int flag); extern void set_disk_ro(struct gendisk *disk, int flag); -- GitLab From fc974ee2bffdde47d1e4b220cf326952cc2c4794 Mon Sep 17 00:00:00 2001 From: Vishal Verma Date: Thu, 24 Dec 2015 19:20:34 -0700 Subject: [PATCH 2372/2855] md: convert to use the generic badblocks code Retain badblocks as part of rdev, but use the accessor functions from include/linux/badblocks for all manipulation. Signed-off-by: Vishal Verma Signed-off-by: Dan Williams --- drivers/md/md.c | 516 +++--------------------------------------------- drivers/md/md.h | 40 +--- 2 files changed, 28 insertions(+), 528 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 807095f4c793b..1e48aa9de352f 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -709,8 +710,7 @@ void md_rdev_clear(struct md_rdev *rdev) put_page(rdev->bb_page); rdev->bb_page = NULL; } - kfree(rdev->badblocks.page); - rdev->badblocks.page = NULL; + badblocks_free(&rdev->badblocks); } EXPORT_SYMBOL_GPL(md_rdev_clear); @@ -1360,8 +1360,6 @@ static __le32 calc_sb_1_csum(struct mdp_superblock_1 *sb) return cpu_to_le32(csum); } -static int md_set_badblocks(struct badblocks *bb, sector_t s, int sectors, - int acknowledged); static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_version) { struct mdp_superblock_1 *sb; @@ -1486,8 +1484,7 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_ count <<= sb->bblog_shift; if (bb + 1 == 0) break; - if (md_set_badblocks(&rdev->badblocks, - sector, count, 1) == 0) + if (badblocks_set(&rdev->badblocks, sector, count, 1)) return -EINVAL; } } else if (sb->bblog_offset != 0) @@ -2319,7 +2316,7 @@ repeat: rdev_for_each(rdev, mddev) { if (rdev->badblocks.changed) { rdev->badblocks.changed = 0; - md_ack_all_badblocks(&rdev->badblocks); + ack_all_badblocks(&rdev->badblocks); md_error(mddev, rdev); } clear_bit(Blocked, &rdev->flags); @@ -2445,7 +2442,7 @@ repeat: clear_bit(Blocked, &rdev->flags); if (any_badblocks_changed) - md_ack_all_badblocks(&rdev->badblocks); + ack_all_badblocks(&rdev->badblocks); clear_bit(BlockedBadBlocks, &rdev->flags); wake_up(&rdev->blocked_wait); } @@ -3046,11 +3043,17 @@ static ssize_t recovery_start_store(struct md_rdev *rdev, const char *buf, size_ static struct rdev_sysfs_entry rdev_recovery_start = __ATTR(recovery_start, S_IRUGO|S_IWUSR, recovery_start_show, recovery_start_store); -static ssize_t -badblocks_show(struct badblocks *bb, char *page, int unack); -static ssize_t -badblocks_store(struct badblocks *bb, const char *page, size_t len, int unack); - +/* sysfs access to bad-blocks list. + * We present two files. + * 'bad-blocks' lists sector numbers and lengths of ranges that + * are recorded as bad. The list is truncated to fit within + * the one-page limit of sysfs. + * Writing "sector length" to this file adds an acknowledged + * bad block list. + * 'unacknowledged-bad-blocks' lists bad blocks that have not yet + * been acknowledged. Writing to this file adds bad blocks + * without acknowledging them. This is largely for testing. + */ static ssize_t bb_show(struct md_rdev *rdev, char *page) { return badblocks_show(&rdev->badblocks, page, 0); @@ -3165,14 +3168,7 @@ int md_rdev_init(struct md_rdev *rdev) * This reserves the space even on arrays where it cannot * be used - I wonder if that matters */ - rdev->badblocks.count = 0; - rdev->badblocks.shift = -1; /* disabled until explicitly enabled */ - rdev->badblocks.page = kmalloc(PAGE_SIZE, GFP_KERNEL); - seqlock_init(&rdev->badblocks.lock); - if (rdev->badblocks.page == NULL) - return -ENOMEM; - - return 0; + return badblocks_init(&rdev->badblocks, 0); } EXPORT_SYMBOL_GPL(md_rdev_init); /* @@ -8478,254 +8474,9 @@ void md_finish_reshape(struct mddev *mddev) } EXPORT_SYMBOL(md_finish_reshape); -/* Bad block management. - * We can record which blocks on each device are 'bad' and so just - * fail those blocks, or that stripe, rather than the whole device. - * Entries in the bad-block table are 64bits wide. This comprises: - * Length of bad-range, in sectors: 0-511 for lengths 1-512 - * Start of bad-range, sector offset, 54 bits (allows 8 exbibytes) - * A 'shift' can be set so that larger blocks are tracked and - * consequently larger devices can be covered. - * 'Acknowledged' flag - 1 bit. - the most significant bit. - * - * Locking of the bad-block table uses a seqlock so md_is_badblock - * might need to retry if it is very unlucky. - * We will sometimes want to check for bad blocks in a bi_end_io function, - * so we use the write_seqlock_irq variant. - * - * When looking for a bad block we specify a range and want to - * know if any block in the range is bad. So we binary-search - * to the last range that starts at-or-before the given endpoint, - * (or "before the sector after the target range") - * then see if it ends after the given start. - * We return - * 0 if there are no known bad blocks in the range - * 1 if there are known bad block which are all acknowledged - * -1 if there are bad blocks which have not yet been acknowledged in metadata. - * plus the start/length of the first bad section we overlap. - */ -int md_is_badblock(struct badblocks *bb, sector_t s, int sectors, - sector_t *first_bad, int *bad_sectors) -{ - int hi; - int lo; - u64 *p = bb->page; - int rv; - sector_t target = s + sectors; - unsigned seq; - - if (bb->shift > 0) { - /* round the start down, and the end up */ - s >>= bb->shift; - target += (1<shift) - 1; - target >>= bb->shift; - sectors = target - s; - } - /* 'target' is now the first block after the bad range */ - -retry: - seq = read_seqbegin(&bb->lock); - lo = 0; - rv = 0; - hi = bb->count; - - /* Binary search between lo and hi for 'target' - * i.e. for the last range that starts before 'target' - */ - /* INVARIANT: ranges before 'lo' and at-or-after 'hi' - * are known not to be the last range before target. - * VARIANT: hi-lo is the number of possible - * ranges, and decreases until it reaches 1 - */ - while (hi - lo > 1) { - int mid = (lo + hi) / 2; - sector_t a = BB_OFFSET(p[mid]); - if (a < target) - /* This could still be the one, earlier ranges - * could not. */ - lo = mid; - else - /* This and later ranges are definitely out. */ - hi = mid; - } - /* 'lo' might be the last that started before target, but 'hi' isn't */ - if (hi > lo) { - /* need to check all range that end after 's' to see if - * any are unacknowledged. - */ - while (lo >= 0 && - BB_OFFSET(p[lo]) + BB_LEN(p[lo]) > s) { - if (BB_OFFSET(p[lo]) < target) { - /* starts before the end, and finishes after - * the start, so they must overlap - */ - if (rv != -1 && BB_ACK(p[lo])) - rv = 1; - else - rv = -1; - *first_bad = BB_OFFSET(p[lo]); - *bad_sectors = BB_LEN(p[lo]); - } - lo--; - } - } - - if (read_seqretry(&bb->lock, seq)) - goto retry; - - return rv; -} -EXPORT_SYMBOL_GPL(md_is_badblock); - -/* - * Add a range of bad blocks to the table. - * This might extend the table, or might contract it - * if two adjacent ranges can be merged. - * We binary-search to find the 'insertion' point, then - * decide how best to handle it. - */ -static int md_set_badblocks(struct badblocks *bb, sector_t s, int sectors, - int acknowledged) -{ - u64 *p; - int lo, hi; - int rv = 1; - unsigned long flags; - - if (bb->shift < 0) - /* badblocks are disabled */ - return 0; - - if (bb->shift) { - /* round the start down, and the end up */ - sector_t next = s + sectors; - s >>= bb->shift; - next += (1<shift) - 1; - next >>= bb->shift; - sectors = next - s; - } - - write_seqlock_irqsave(&bb->lock, flags); - - p = bb->page; - lo = 0; - hi = bb->count; - /* Find the last range that starts at-or-before 's' */ - while (hi - lo > 1) { - int mid = (lo + hi) / 2; - sector_t a = BB_OFFSET(p[mid]); - if (a <= s) - lo = mid; - else - hi = mid; - } - if (hi > lo && BB_OFFSET(p[lo]) > s) - hi = lo; - - if (hi > lo) { - /* we found a range that might merge with the start - * of our new range - */ - sector_t a = BB_OFFSET(p[lo]); - sector_t e = a + BB_LEN(p[lo]); - int ack = BB_ACK(p[lo]); - if (e >= s) { - /* Yes, we can merge with a previous range */ - if (s == a && s + sectors >= e) - /* new range covers old */ - ack = acknowledged; - else - ack = ack && acknowledged; - - if (e < s + sectors) - e = s + sectors; - if (e - a <= BB_MAX_LEN) { - p[lo] = BB_MAKE(a, e-a, ack); - s = e; - } else { - /* does not all fit in one range, - * make p[lo] maximal - */ - if (BB_LEN(p[lo]) != BB_MAX_LEN) - p[lo] = BB_MAKE(a, BB_MAX_LEN, ack); - s = a + BB_MAX_LEN; - } - sectors = e - s; - } - } - if (sectors && hi < bb->count) { - /* 'hi' points to the first range that starts after 's'. - * Maybe we can merge with the start of that range */ - sector_t a = BB_OFFSET(p[hi]); - sector_t e = a + BB_LEN(p[hi]); - int ack = BB_ACK(p[hi]); - if (a <= s + sectors) { - /* merging is possible */ - if (e <= s + sectors) { - /* full overlap */ - e = s + sectors; - ack = acknowledged; - } else - ack = ack && acknowledged; - - a = s; - if (e - a <= BB_MAX_LEN) { - p[hi] = BB_MAKE(a, e-a, ack); - s = e; - } else { - p[hi] = BB_MAKE(a, BB_MAX_LEN, ack); - s = a + BB_MAX_LEN; - } - sectors = e - s; - lo = hi; - hi++; - } - } - if (sectors == 0 && hi < bb->count) { - /* we might be able to combine lo and hi */ - /* Note: 's' is at the end of 'lo' */ - sector_t a = BB_OFFSET(p[hi]); - int lolen = BB_LEN(p[lo]); - int hilen = BB_LEN(p[hi]); - int newlen = lolen + hilen - (s - a); - if (s >= a && newlen < BB_MAX_LEN) { - /* yes, we can combine them */ - int ack = BB_ACK(p[lo]) && BB_ACK(p[hi]); - p[lo] = BB_MAKE(BB_OFFSET(p[lo]), newlen, ack); - memmove(p + hi, p + hi + 1, - (bb->count - hi - 1) * 8); - bb->count--; - } - } - while (sectors) { - /* didn't merge (it all). - * Need to add a range just before 'hi' */ - if (bb->count >= MD_MAX_BADBLOCKS) { - /* No room for more */ - rv = 0; - break; - } else { - int this_sectors = sectors; - memmove(p + hi + 1, p + hi, - (bb->count - hi) * 8); - bb->count++; - - if (this_sectors > BB_MAX_LEN) - this_sectors = BB_MAX_LEN; - p[hi] = BB_MAKE(s, this_sectors, acknowledged); - sectors -= this_sectors; - s += this_sectors; - } - } - - bb->changed = 1; - if (!acknowledged) - bb->unacked_exist = 1; - write_sequnlock_irqrestore(&bb->lock, flags); - - return rv; -} +/* Bad block management */ +/* Returns 1 on success, 0 on failure */ int rdev_set_badblocks(struct md_rdev *rdev, sector_t s, int sectors, int is_new) { @@ -8734,114 +8485,19 @@ int rdev_set_badblocks(struct md_rdev *rdev, sector_t s, int sectors, s += rdev->new_data_offset; else s += rdev->data_offset; - rv = md_set_badblocks(&rdev->badblocks, - s, sectors, 0); - if (rv) { + rv = badblocks_set(&rdev->badblocks, s, sectors, 0); + if (rv == 0) { /* Make sure they get written out promptly */ sysfs_notify_dirent_safe(rdev->sysfs_state); set_bit(MD_CHANGE_CLEAN, &rdev->mddev->flags); set_bit(MD_CHANGE_PENDING, &rdev->mddev->flags); md_wakeup_thread(rdev->mddev->thread); - } - return rv; + return 1; + } else + return 0; } EXPORT_SYMBOL_GPL(rdev_set_badblocks); -/* - * Remove a range of bad blocks from the table. - * This may involve extending the table if we spilt a region, - * but it must not fail. So if the table becomes full, we just - * drop the remove request. - */ -static int md_clear_badblocks(struct badblocks *bb, sector_t s, int sectors) -{ - u64 *p; - int lo, hi; - sector_t target = s + sectors; - int rv = 0; - - if (bb->shift > 0) { - /* When clearing we round the start up and the end down. - * This should not matter as the shift should align with - * the block size and no rounding should ever be needed. - * However it is better the think a block is bad when it - * isn't than to think a block is not bad when it is. - */ - s += (1<shift) - 1; - s >>= bb->shift; - target >>= bb->shift; - sectors = target - s; - } - - write_seqlock_irq(&bb->lock); - - p = bb->page; - lo = 0; - hi = bb->count; - /* Find the last range that starts before 'target' */ - while (hi - lo > 1) { - int mid = (lo + hi) / 2; - sector_t a = BB_OFFSET(p[mid]); - if (a < target) - lo = mid; - else - hi = mid; - } - if (hi > lo) { - /* p[lo] is the last range that could overlap the - * current range. Earlier ranges could also overlap, - * but only this one can overlap the end of the range. - */ - if (BB_OFFSET(p[lo]) + BB_LEN(p[lo]) > target) { - /* Partial overlap, leave the tail of this range */ - int ack = BB_ACK(p[lo]); - sector_t a = BB_OFFSET(p[lo]); - sector_t end = a + BB_LEN(p[lo]); - - if (a < s) { - /* we need to split this range */ - if (bb->count >= MD_MAX_BADBLOCKS) { - rv = -ENOSPC; - goto out; - } - memmove(p+lo+1, p+lo, (bb->count - lo) * 8); - bb->count++; - p[lo] = BB_MAKE(a, s-a, ack); - lo++; - } - p[lo] = BB_MAKE(target, end - target, ack); - /* there is no longer an overlap */ - hi = lo; - lo--; - } - while (lo >= 0 && - BB_OFFSET(p[lo]) + BB_LEN(p[lo]) > s) { - /* This range does overlap */ - if (BB_OFFSET(p[lo]) < s) { - /* Keep the early parts of this range. */ - int ack = BB_ACK(p[lo]); - sector_t start = BB_OFFSET(p[lo]); - p[lo] = BB_MAKE(start, s - start, ack); - /* now low doesn't overlap, so.. */ - break; - } - lo--; - } - /* 'lo' is strictly before, 'hi' is strictly after, - * anything between needs to be discarded - */ - if (hi - lo > 1) { - memmove(p+lo+1, p+hi, (bb->count - hi) * 8); - bb->count -= (hi - lo - 1); - } - } - - bb->changed = 1; -out: - write_sequnlock_irq(&bb->lock); - return rv; -} - int rdev_clear_badblocks(struct md_rdev *rdev, sector_t s, int sectors, int is_new) { @@ -8849,133 +8505,11 @@ int rdev_clear_badblocks(struct md_rdev *rdev, sector_t s, int sectors, s += rdev->new_data_offset; else s += rdev->data_offset; - return md_clear_badblocks(&rdev->badblocks, + return badblocks_clear(&rdev->badblocks, s, sectors); } EXPORT_SYMBOL_GPL(rdev_clear_badblocks); -/* - * Acknowledge all bad blocks in a list. - * This only succeeds if ->changed is clear. It is used by - * in-kernel metadata updates - */ -void md_ack_all_badblocks(struct badblocks *bb) -{ - if (bb->page == NULL || bb->changed) - /* no point even trying */ - return; - write_seqlock_irq(&bb->lock); - - if (bb->changed == 0 && bb->unacked_exist) { - u64 *p = bb->page; - int i; - for (i = 0; i < bb->count ; i++) { - if (!BB_ACK(p[i])) { - sector_t start = BB_OFFSET(p[i]); - int len = BB_LEN(p[i]); - p[i] = BB_MAKE(start, len, 1); - } - } - bb->unacked_exist = 0; - } - write_sequnlock_irq(&bb->lock); -} -EXPORT_SYMBOL_GPL(md_ack_all_badblocks); - -/* sysfs access to bad-blocks list. - * We present two files. - * 'bad-blocks' lists sector numbers and lengths of ranges that - * are recorded as bad. The list is truncated to fit within - * the one-page limit of sysfs. - * Writing "sector length" to this file adds an acknowledged - * bad block list. - * 'unacknowledged-bad-blocks' lists bad blocks that have not yet - * been acknowledged. Writing to this file adds bad blocks - * without acknowledging them. This is largely for testing. - */ - -static ssize_t -badblocks_show(struct badblocks *bb, char *page, int unack) -{ - size_t len; - int i; - u64 *p = bb->page; - unsigned seq; - - if (bb->shift < 0) - return 0; - -retry: - seq = read_seqbegin(&bb->lock); - - len = 0; - i = 0; - - while (len < PAGE_SIZE && i < bb->count) { - sector_t s = BB_OFFSET(p[i]); - unsigned int length = BB_LEN(p[i]); - int ack = BB_ACK(p[i]); - i++; - - if (unack && ack) - continue; - - len += snprintf(page+len, PAGE_SIZE-len, "%llu %u\n", - (unsigned long long)s << bb->shift, - length << bb->shift); - } - if (unack && len == 0) - bb->unacked_exist = 0; - - if (read_seqretry(&bb->lock, seq)) - goto retry; - - return len; -} - -#define DO_DEBUG 1 - -static ssize_t -badblocks_store(struct badblocks *bb, const char *page, size_t len, int unack) -{ - unsigned long long sector; - int length; - char newline; -#ifdef DO_DEBUG - /* Allow clearing via sysfs *only* for testing/debugging. - * Normally only a successful write may clear a badblock - */ - int clear = 0; - if (page[0] == '-') { - clear = 1; - page++; - } -#endif /* DO_DEBUG */ - - switch (sscanf(page, "%llu %d%c", §or, &length, &newline)) { - case 3: - if (newline != '\n') - return -EINVAL; - case 2: - if (length <= 0) - return -EINVAL; - break; - default: - return -EINVAL; - } - -#ifdef DO_DEBUG - if (clear) { - md_clear_badblocks(bb, sector, length); - return len; - } -#endif /* DO_DEBUG */ - if (md_set_badblocks(bb, sector, length, !unack)) - return len; - else - return -ENOSPC; -} - static int md_notify_reboot(struct notifier_block *this, unsigned long code, void *x) { diff --git a/drivers/md/md.h b/drivers/md/md.h index 2bea51edfab70..389afc420db63 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -28,13 +29,6 @@ #define MaxSector (~(sector_t)0) -/* Bad block numbers are stored sorted in a single page. - * 64bits is used for each block or extent. - * 54 bits are sector number, 9 bits are extent size, - * 1 bit is an 'acknowledged' flag. - */ -#define MD_MAX_BADBLOCKS (PAGE_SIZE/8) - /* * MD's 'extended' device */ @@ -117,22 +111,7 @@ struct md_rdev { struct kernfs_node *sysfs_state; /* handle for 'state' * sysfs entry */ - struct badblocks { - int count; /* count of bad blocks */ - int unacked_exist; /* there probably are unacknowledged - * bad blocks. This is only cleared - * when a read discovers none - */ - int shift; /* shift from sectors to block size - * a -ve shift means badblocks are - * disabled.*/ - u64 *page; /* badblock list */ - int changed; - seqlock_t lock; - - sector_t sector; - sector_t size; /* in sectors */ - } badblocks; + struct badblocks badblocks; }; enum flag_bits { Faulty, /* device is known to have a fault */ @@ -185,22 +164,11 @@ enum flag_bits { */ }; -#define BB_LEN_MASK (0x00000000000001FFULL) -#define BB_OFFSET_MASK (0x7FFFFFFFFFFFFE00ULL) -#define BB_ACK_MASK (0x8000000000000000ULL) -#define BB_MAX_LEN 512 -#define BB_OFFSET(x) (((x) & BB_OFFSET_MASK) >> 9) -#define BB_LEN(x) (((x) & BB_LEN_MASK) + 1) -#define BB_ACK(x) (!!((x) & BB_ACK_MASK)) -#define BB_MAKE(a, l, ack) (((a)<<9) | ((l)-1) | ((u64)(!!(ack)) << 63)) - -extern int md_is_badblock(struct badblocks *bb, sector_t s, int sectors, - sector_t *first_bad, int *bad_sectors); static inline int is_badblock(struct md_rdev *rdev, sector_t s, int sectors, sector_t *first_bad, int *bad_sectors) { if (unlikely(rdev->badblocks.count)) { - int rv = md_is_badblock(&rdev->badblocks, rdev->data_offset + s, + int rv = badblocks_check(&rdev->badblocks, rdev->data_offset + s, sectors, first_bad, bad_sectors); if (rv) @@ -213,8 +181,6 @@ extern int rdev_set_badblocks(struct md_rdev *rdev, sector_t s, int sectors, int is_new); extern int rdev_clear_badblocks(struct md_rdev *rdev, sector_t s, int sectors, int is_new); -extern void md_ack_all_badblocks(struct badblocks *bb); - struct md_cluster_info; struct mddev { -- GitLab From d26f73f083ed6fbea7fd3fdbacb527b7f3e75ac0 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 30 Dec 2015 15:01:19 -0800 Subject: [PATCH 2373/2855] nfit_test: Enable DSMs for all test NFITs In preparation for getting a poison list using ARS DSMs, enable DSMs for all manufactured NFITs supplied by the test framework. Also, supply valid response data for ars_status. Signed-off-by: Vishal Verma Signed-off-by: Dan Williams --- tools/testing/nvdimm/test/nfit.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c index 51cf8256c6cda..90bd2ea410323 100644 --- a/tools/testing/nvdimm/test/nfit.c +++ b/tools/testing/nvdimm/test/nfit.c @@ -248,6 +248,8 @@ static int nfit_test_cmd_ars_status(struct nd_cmd_ars_status *nd_cmd, nd_cmd->out_length = 256; nd_cmd->num_records = 0; + nd_cmd->address = 0; + nd_cmd->length = -1ULL; nd_cmd->status = 0; return 0; @@ -1088,6 +1090,8 @@ static void nfit_test1_setup(struct nfit_test *t) struct acpi_nfit_memory_map *memdev; struct acpi_nfit_control_region *dcr; struct acpi_nfit_system_address *spa; + struct nvdimm_bus_descriptor *nd_desc; + struct acpi_nfit_desc *acpi_desc; offset = 0; /* spa0 (flat range with no bdw aliasing) */ @@ -1135,6 +1139,13 @@ static void nfit_test1_setup(struct nfit_test *t) dcr->command_size = 0; dcr->status_offset = 0; dcr->status_size = 0; + + acpi_desc = &t->acpi_desc; + set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_dsm_force_en); + set_bit(ND_CMD_ARS_START, &acpi_desc->bus_dsm_force_en); + set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_dsm_force_en); + nd_desc = &acpi_desc->nd_desc; + nd_desc->ndctl = nfit_test_ctl; } static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa, -- GitLab From 0caeef63e6d2f866d85bb507bf63e0ce8ec91cef Mon Sep 17 00:00:00 2001 From: Vishal Verma Date: Thu, 24 Dec 2015 19:21:43 -0700 Subject: [PATCH 2374/2855] libnvdimm: Add a poison list and export badblocks During region creation, perform Address Range Scrubs (ARS) for the SPA (System Physical Address) ranges to retrieve known poison locations from firmware. Add a new data structure 'nd_poison' which is used as a list in nvdimm_bus to store these poison locations. When creating a pmem namespace, if there is any known poison associated with its physical address space, convert the poison ranges to bad sectors that are exposed using the badblocks interface. Signed-off-by: Vishal Verma Signed-off-by: Dan Williams --- drivers/acpi/nfit.c | 203 ++++++++++++++++++++++++++++++++++++++ drivers/nvdimm/core.c | 187 +++++++++++++++++++++++++++++++++++ drivers/nvdimm/nd-core.h | 3 + drivers/nvdimm/nd.h | 6 ++ drivers/nvdimm/pmem.c | 6 ++ include/linux/libnvdimm.h | 1 + 6 files changed, 406 insertions(+) diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c index e7ed39bab97d5..e1dbc8da09b7c 100644 --- a/drivers/acpi/nfit.c +++ b/drivers/acpi/nfit.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -1473,6 +1474,201 @@ static void acpi_nfit_blk_region_disable(struct nvdimm_bus *nvdimm_bus, /* devm will free nfit_blk */ } +static int ars_get_cap(struct nvdimm_bus_descriptor *nd_desc, + struct nd_cmd_ars_cap *cmd, u64 addr, u64 length) +{ + cmd->address = addr; + cmd->length = length; + + return nd_desc->ndctl(nd_desc, NULL, ND_CMD_ARS_CAP, cmd, + sizeof(*cmd)); +} + +static int ars_do_start(struct nvdimm_bus_descriptor *nd_desc, + struct nd_cmd_ars_start *cmd, u64 addr, u64 length) +{ + int rc; + + cmd->address = addr; + cmd->length = length; + cmd->type = ND_ARS_PERSISTENT; + + while (1) { + rc = nd_desc->ndctl(nd_desc, NULL, ND_CMD_ARS_START, cmd, + sizeof(*cmd)); + if (rc) + return rc; + switch (cmd->status) { + case 0: + return 0; + case 1: + /* ARS unsupported, but we should never get here */ + return 0; + case 2: + return -EINVAL; + case 3: + /* ARS is in progress */ + msleep(1000); + break; + default: + return -ENXIO; + } + } +} + +static int ars_get_status(struct nvdimm_bus_descriptor *nd_desc, + struct nd_cmd_ars_status *cmd) +{ + int rc; + + while (1) { + rc = nd_desc->ndctl(nd_desc, NULL, ND_CMD_ARS_STATUS, cmd, + sizeof(*cmd)); + if (rc || cmd->status & 0xffff) + return -ENXIO; + + /* Check extended status (Upper two bytes) */ + switch (cmd->status >> 16) { + case 0: + return 0; + case 1: + /* ARS is in progress */ + msleep(1000); + break; + case 2: + /* No ARS performed for the current boot */ + return 0; + default: + return -ENXIO; + } + } +} + +static int ars_status_process_records(struct nvdimm_bus *nvdimm_bus, + struct nd_cmd_ars_status *ars_status, u64 start) +{ + int rc; + u32 i; + + /* + * The address field returned by ars_status should be either + * less than or equal to the address we last started ARS for. + * The (start, length) returned by ars_status should also have + * non-zero overlap with the range we started ARS for. + * If this is not the case, bail. + */ + if (ars_status->address > start || + (ars_status->address + ars_status->length < start)) + return -ENXIO; + + for (i = 0; i < ars_status->num_records; i++) { + rc = nvdimm_bus_add_poison(nvdimm_bus, + ars_status->records[i].err_address, + ars_status->records[i].length); + if (rc) + return rc; + } + + return 0; +} + +static int acpi_nfit_find_poison(struct acpi_nfit_desc *acpi_desc, + struct nd_region_desc *ndr_desc) +{ + struct nvdimm_bus_descriptor *nd_desc = &acpi_desc->nd_desc; + struct nvdimm_bus *nvdimm_bus = acpi_desc->nvdimm_bus; + struct nd_cmd_ars_status *ars_status = NULL; + struct nd_cmd_ars_start *ars_start = NULL; + struct nd_cmd_ars_cap *ars_cap = NULL; + u64 start, len, cur, remaining; + int rc; + + ars_cap = kzalloc(sizeof(*ars_cap), GFP_KERNEL); + if (!ars_cap) + return -ENOMEM; + + start = ndr_desc->res->start; + len = ndr_desc->res->end - ndr_desc->res->start + 1; + + rc = ars_get_cap(nd_desc, ars_cap, start, len); + if (rc) + goto out; + + /* + * If ARS is unsupported, or if the 'Persistent Memory Scrub' flag in + * extended status is not set, skip this but continue initialization + */ + if ((ars_cap->status & 0xffff) || + !(ars_cap->status >> 16 & ND_ARS_PERSISTENT)) { + dev_warn(acpi_desc->dev, + "ARS unsupported (status: 0x%x), won't create an error list\n", + ars_cap->status); + goto out; + } + + /* + * Check if a full-range ARS has been run. If so, use those results + * without having to start a new ARS. + */ + ars_status = kzalloc(ars_cap->max_ars_out + sizeof(*ars_status), + GFP_KERNEL); + if (!ars_status) { + rc = -ENOMEM; + goto out; + } + + rc = ars_get_status(nd_desc, ars_status); + if (rc) + goto out; + + if (ars_status->address <= start && + (ars_status->address + ars_status->length >= start + len)) { + rc = ars_status_process_records(nvdimm_bus, ars_status, start); + goto out; + } + + /* + * ARS_STATUS can overflow if the number of poison entries found is + * greater than the maximum buffer size (ars_cap->max_ars_out) + * To detect overflow, check if the length field of ars_status + * is less than the length we supplied. If so, process the + * error entries we got, adjust the start point, and start again + */ + ars_start = kzalloc(sizeof(*ars_start), GFP_KERNEL); + if (!ars_start) + return -ENOMEM; + + cur = start; + remaining = len; + do { + u64 done, end; + + rc = ars_do_start(nd_desc, ars_start, cur, remaining); + if (rc) + goto out; + + rc = ars_get_status(nd_desc, ars_status); + if (rc) + goto out; + + rc = ars_status_process_records(nvdimm_bus, ars_status, cur); + if (rc) + goto out; + + end = min(cur + remaining, + ars_status->address + ars_status->length); + done = end - cur; + cur += done; + remaining -= done; + } while (remaining); + + out: + kfree(ars_cap); + kfree(ars_start); + kfree(ars_status); + return rc; +} + static int acpi_nfit_init_mapping(struct acpi_nfit_desc *acpi_desc, struct nd_mapping *nd_mapping, struct nd_region_desc *ndr_desc, struct acpi_nfit_memory_map *memdev, @@ -1585,6 +1781,13 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc, nvdimm_bus = acpi_desc->nvdimm_bus; if (nfit_spa_type(spa) == NFIT_SPA_PM) { + rc = acpi_nfit_find_poison(acpi_desc, ndr_desc); + if (rc) { + dev_err(acpi_desc->dev, + "error while performing ARS to find poison: %d\n", + rc); + return rc; + } if (!nvdimm_pmem_region_create(nvdimm_bus, ndr_desc)) return -ENOMEM; } else if (nfit_spa_type(spa) == NFIT_SPA_VOLATILE) { diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c index 82c49bb870555..21003b7f0b384 100644 --- a/drivers/nvdimm/core.c +++ b/drivers/nvdimm/core.c @@ -325,6 +325,7 @@ struct nvdimm_bus *__nvdimm_bus_register(struct device *parent, if (!nvdimm_bus) return NULL; INIT_LIST_HEAD(&nvdimm_bus->list); + INIT_LIST_HEAD(&nvdimm_bus->poison_list); init_waitqueue_head(&nvdimm_bus->probe_wait); nvdimm_bus->id = ida_simple_get(&nd_ida, 0, 0, GFP_KERNEL); mutex_init(&nvdimm_bus->reconfig_mutex); @@ -359,6 +360,191 @@ struct nvdimm_bus *__nvdimm_bus_register(struct device *parent, } EXPORT_SYMBOL_GPL(__nvdimm_bus_register); +/** + * __add_badblock_range() - Convert a physical address range to bad sectors + * @disk: the disk associated with the namespace + * @ns_offset: namespace offset where the error range begins (in bytes) + * @len: number of bytes of poison to be added + * + * This assumes that the range provided with (ns_offset, len) is within + * the bounds of physical addresses for this namespace, i.e. lies in the + * interval [ns_start, ns_start + ns_size) + */ +static int __add_badblock_range(struct gendisk *disk, u64 ns_offset, u64 len) +{ + unsigned int sector_size = queue_logical_block_size(disk->queue); + sector_t start_sector; + u64 num_sectors; + u32 rem; + int rc; + + start_sector = div_u64(ns_offset, sector_size); + num_sectors = div_u64_rem(len, sector_size, &rem); + if (rem) + num_sectors++; + + if (!disk->bb) { + rc = disk_alloc_badblocks(disk); + if (rc) + return rc; + } + + if (unlikely(num_sectors > (u64)INT_MAX)) { + u64 remaining = num_sectors; + sector_t s = start_sector; + + while (remaining) { + int done = min_t(u64, remaining, INT_MAX); + + rc = disk_set_badblocks(disk, s, done); + if (rc) + return rc; + remaining -= done; + s += done; + } + return 0; + } else + return disk_set_badblocks(disk, start_sector, num_sectors); +} + +/** + * nvdimm_namespace_add_poison() - Convert a list of poison ranges to badblocks + * @disk: the gendisk associated with the namespace where badblocks + * will be stored + * @offset: offset at the start of the namespace before 'sector 0' + * @ndns: the namespace containing poison ranges + * + * The poison list generated during NFIT initialization may contain multiple, + * possibly overlapping ranges in the SPA (System Physical Address) space. + * Compare each of these ranges to the namespace currently being initialized, + * and add badblocks to the gendisk for all matching sub-ranges + * + * Return: + * 0 - Success + */ +int nvdimm_namespace_add_poison(struct gendisk *disk, resource_size_t offset, + struct nd_namespace_common *ndns) +{ + struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev); + struct nd_region *nd_region = to_nd_region(ndns->dev.parent); + struct nvdimm_bus *nvdimm_bus; + struct list_head *poison_list; + u64 ns_start, ns_end, ns_size; + struct nd_poison *pl; + int rc; + + ns_size = nvdimm_namespace_capacity(ndns) - offset; + ns_start = nsio->res.start + offset; + ns_end = nsio->res.end; + + nvdimm_bus = to_nvdimm_bus(nd_region->dev.parent); + poison_list = &nvdimm_bus->poison_list; + if (list_empty(poison_list)) + return 0; + + list_for_each_entry(pl, poison_list, list) { + u64 pl_end = pl->start + pl->length - 1; + + /* Discard intervals with no intersection */ + if (pl_end < ns_start) + continue; + if (pl->start > ns_end) + continue; + /* Deal with any overlap after start of the namespace */ + if (pl->start >= ns_start) { + u64 start = pl->start; + u64 len; + + if (pl_end <= ns_end) + len = pl->length; + else + len = ns_start + ns_size - pl->start; + + rc = __add_badblock_range(disk, start - ns_start, len); + if (rc) + return rc; + dev_info(&nvdimm_bus->dev, + "Found a poison range (0x%llx, 0x%llx)\n", + start, len); + continue; + } + /* Deal with overlap for poison starting before the namespace */ + if (pl->start < ns_start) { + u64 len; + + if (pl_end < ns_end) + len = pl->start + pl->length - ns_start; + else + len = ns_size; + + rc = __add_badblock_range(disk, 0, len); + if (rc) + return rc; + dev_info(&nvdimm_bus->dev, + "Found a poison range (0x%llx, 0x%llx)\n", + pl->start, len); + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(nvdimm_namespace_add_poison); + +static int __add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length) +{ + struct nd_poison *pl; + + pl = kzalloc(sizeof(*pl), GFP_KERNEL); + if (!pl) + return -ENOMEM; + + pl->start = addr; + pl->length = length; + list_add_tail(&pl->list, &nvdimm_bus->poison_list); + + return 0; +} + +int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length) +{ + struct nd_poison *pl; + + if (list_empty(&nvdimm_bus->poison_list)) + return __add_poison(nvdimm_bus, addr, length); + + /* + * There is a chance this is a duplicate, check for those first. + * This will be the common case as ARS_STATUS returns all known + * errors in the SPA space, and we can't query it per region + */ + list_for_each_entry(pl, &nvdimm_bus->poison_list, list) + if (pl->start == addr) { + /* If length has changed, update this list entry */ + if (pl->length != length) + pl->length = length; + return 0; + } + + /* + * If not a duplicate or a simple length update, add the entry as is, + * as any overlapping ranges will get resolved when the list is consumed + * and converted to badblocks + */ + return __add_poison(nvdimm_bus, addr, length); +} +EXPORT_SYMBOL_GPL(nvdimm_bus_add_poison); + +static void free_poison_list(struct list_head *poison_list) +{ + struct nd_poison *pl, *next; + + list_for_each_entry_safe(pl, next, poison_list, list) { + list_del(&pl->list); + kfree(pl); + } + list_del_init(poison_list); +} + static int child_unregister(struct device *dev, void *data) { /* @@ -385,6 +571,7 @@ void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus) nd_synchronize(); device_for_each_child(&nvdimm_bus->dev, NULL, child_unregister); + free_poison_list(&nvdimm_bus->poison_list); nvdimm_bus_destroy_ndctl(nvdimm_bus); device_unregister(&nvdimm_bus->dev); diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h index 159aed5320424..d3b7ea78df96b 100644 --- a/drivers/nvdimm/nd-core.h +++ b/drivers/nvdimm/nd-core.h @@ -30,6 +30,7 @@ struct nvdimm_bus { struct list_head list; struct device dev; int id, probe_active; + struct list_head poison_list; struct mutex reconfig_mutex; }; @@ -89,4 +90,6 @@ bool __nd_attach_ndns(struct device *dev, struct nd_namespace_common *attach, ssize_t nd_namespace_store(struct device *dev, struct nd_namespace_common **_ndns, const char *buf, size_t len); +int nvdimm_namespace_add_poison(struct gendisk *disk, resource_size_t offset, + struct nd_namespace_common *ndns); #endif /* __ND_CORE_H__ */ diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h index 417e521d299cb..ba91fcd5818db 100644 --- a/drivers/nvdimm/nd.h +++ b/drivers/nvdimm/nd.h @@ -38,6 +38,12 @@ enum { #endif }; +struct nd_poison { + u64 start; + u64 length; + struct list_head list; +}; + struct nvdimm_drvdata { struct device *dev; int nsindex_size; diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 8ee79893d2f5f..5b95043443a39 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -27,6 +27,7 @@ #include #include #include +#include "nd-core.h" #include "pfn.h" #include "nd.h" @@ -168,6 +169,7 @@ static int pmem_attach_disk(struct device *dev, { int nid = dev_to_node(dev); struct gendisk *disk; + int ret; pmem->pmem_queue = blk_alloc_queue_node(GFP_KERNEL, nid); if (!pmem->pmem_queue) @@ -196,6 +198,10 @@ static int pmem_attach_disk(struct device *dev, set_capacity(disk, (pmem->size - pmem->data_offset) / 512); pmem->pmem_disk = disk; + ret = nvdimm_namespace_add_poison(disk, pmem->data_offset, ndns); + if (ret) + return ret; + add_disk(disk); revalidate_disk(disk); diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index 3f021dc5da8c3..bed40dff0e869 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h @@ -116,6 +116,7 @@ static inline struct nd_blk_region_desc *to_blk_region_desc( } +int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length); struct nvdimm_bus *__nvdimm_bus_register(struct device *parent, struct nvdimm_bus_descriptor *nfit_desc, struct module *module); #define nvdimm_bus_register(parent, desc) \ -- GitLab From ad9a8bde2cb19f6876f964fc48acc8b6a2f325ff Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 6 Jan 2016 12:03:41 -0800 Subject: [PATCH 2375/2855] libnvdimm, pmem: move definition of nvdimm_namespace_add_poison to nd.h nd-core.h is private to the libnvdimm core internals and should not be used by drivers. Signed-off-by: Dan Williams --- drivers/nvdimm/nd-core.h | 2 -- drivers/nvdimm/nd.h | 2 ++ drivers/nvdimm/pmem.c | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h index d3b7ea78df96b..29acdaa757e24 100644 --- a/drivers/nvdimm/nd-core.h +++ b/drivers/nvdimm/nd-core.h @@ -90,6 +90,4 @@ bool __nd_attach_ndns(struct device *dev, struct nd_namespace_common *attach, ssize_t nd_namespace_store(struct device *dev, struct nd_namespace_common **_ndns, const char *buf, size_t len); -int nvdimm_namespace_add_poison(struct gendisk *disk, resource_size_t offset, - struct nd_namespace_common *ndns); #endif /* __ND_CORE_H__ */ diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h index ba91fcd5818db..198933da83e5a 100644 --- a/drivers/nvdimm/nd.h +++ b/drivers/nvdimm/nd.h @@ -268,6 +268,8 @@ int nvdimm_namespace_attach_btt(struct nd_namespace_common *ndns); int nvdimm_namespace_detach_btt(struct nd_namespace_common *ndns); const char *nvdimm_namespace_disk_name(struct nd_namespace_common *ndns, char *name); +int nvdimm_namespace_add_poison(struct gendisk *disk, resource_size_t offset, + struct nd_namespace_common *ndns); int nd_blk_region_init(struct nd_region *nd_region); void __nd_iostat_start(struct bio *bio, unsigned long *start); static inline bool nd_iostat_start(struct bio *bio, unsigned long *start) diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 5b95043443a39..65b2056e75404 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -27,7 +27,6 @@ #include #include #include -#include "nd-core.h" #include "pfn.h" #include "nd.h" -- GitLab From d3b407fb3f782bd915db64e266010ea30a2d381e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 6 Jan 2016 12:19:22 -0800 Subject: [PATCH 2376/2855] badblocks: rename badblocks_free to badblocks_exit For symmetry with badblocks_init() make it clear that this path only destroys incremental allocations of a badblocks instance, and does not free the badblocks instance itself. Signed-off-by: Dan Williams --- block/badblocks.c | 6 +++--- block/genhd.c | 2 +- drivers/md/md.c | 2 +- include/linux/badblocks.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/block/badblocks.c b/block/badblocks.c index 96aeb9194a2ef..fabf6b64c2d17 100644 --- a/block/badblocks.c +++ b/block/badblocks.c @@ -550,12 +550,12 @@ int badblocks_init(struct badblocks *bb, int enable) EXPORT_SYMBOL_GPL(badblocks_init); /** - * badblocks_free() - free the badblocks structure + * badblocks_exit() - free the badblocks structure * @bb: the badblocks structure that holds all badblock information */ -void badblocks_free(struct badblocks *bb) +void badblocks_exit(struct badblocks *bb) { kfree(bb->page); bb->page = NULL; } -EXPORT_SYMBOL_GPL(badblocks_free); +EXPORT_SYMBOL_GPL(badblocks_exit); diff --git a/block/genhd.c b/block/genhd.c index 88579cf373b8b..f463c67e6ba26 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -671,7 +671,7 @@ void del_gendisk(struct gendisk *disk) blk_unregister_region(disk_devt(disk), disk->minors); if (disk->bb) { - badblocks_free(disk->bb); + badblocks_exit(disk->bb); kfree(disk->bb); } diff --git a/drivers/md/md.c b/drivers/md/md.c index 1e48aa9de352f..96a991821ae66 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -710,7 +710,7 @@ void md_rdev_clear(struct md_rdev *rdev) put_page(rdev->bb_page); rdev->bb_page = NULL; } - badblocks_free(&rdev->badblocks); + badblocks_exit(&rdev->badblocks); } EXPORT_SYMBOL_GPL(md_rdev_clear); diff --git a/include/linux/badblocks.h b/include/linux/badblocks.h index 929344630b51c..2d98c026c57f6 100644 --- a/include/linux/badblocks.h +++ b/include/linux/badblocks.h @@ -48,6 +48,6 @@ ssize_t badblocks_show(struct badblocks *bb, char *page, int unack); ssize_t badblocks_store(struct badblocks *bb, const char *page, size_t len, int unack); int badblocks_init(struct badblocks *bb, int enable); -void badblocks_free(struct badblocks *bb); +void badblocks_exit(struct badblocks *bb); #endif -- GitLab From 20a308f09e0d29ce6f5a4114cc476a998d569bfb Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 6 Jan 2016 12:03:41 -0800 Subject: [PATCH 2377/2855] block: clarify badblocks lifetime The badblocks list attached to a gendisk is allocated by the driver which equates to the driver owning the lifetime of the object. Do not automatically free it in del_gendisk(). This is in preparation for expanding the use of badblocks in libnvdimm drivers and introducing devm_init_badblocks(). Signed-off-by: Dan Williams --- block/badblocks.c | 2 ++ block/genhd.c | 5 ----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/block/badblocks.c b/block/badblocks.c index fabf6b64c2d17..37e5c0a2ef695 100644 --- a/block/badblocks.c +++ b/block/badblocks.c @@ -555,6 +555,8 @@ EXPORT_SYMBOL_GPL(badblocks_init); */ void badblocks_exit(struct badblocks *bb) { + if (!bb) + return; kfree(bb->page); bb->page = NULL; } diff --git a/block/genhd.c b/block/genhd.c index f463c67e6ba26..aa38cd0a66c76 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -670,11 +670,6 @@ void del_gendisk(struct gendisk *disk) blk_unregister_queue(disk); blk_unregister_region(disk_devt(disk), disk->minors); - if (disk->bb) { - badblocks_exit(disk->bb); - kfree(disk->bb); - } - part_stat_set_all(&disk->part0, 0); disk->part0.stamp = 0; -- GitLab From 16263ff6c72eb4cc00aa287230144dda12ccad12 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 4 Jan 2016 23:50:23 -0800 Subject: [PATCH 2378/2855] block, badblocks: introduce devm_init_badblocks Provide a devres interface for initializing a badblocks instance. The pmem driver has several scenarios where it will be beneficial to have this structure automatically freed when the device is disabled / fails probe. Signed-off-by: Dan Williams --- block/badblocks.c | 48 ++++++++++++++++++++++++++++----------- include/linux/badblocks.h | 14 +++++++++++- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/block/badblocks.c b/block/badblocks.c index 37e5c0a2ef695..7be53cb1cc3ce 100644 --- a/block/badblocks.c +++ b/block/badblocks.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -522,24 +523,20 @@ ssize_t badblocks_store(struct badblocks *bb, const char *page, size_t len, } EXPORT_SYMBOL_GPL(badblocks_store); -/** - * badblocks_init() - initialize the badblocks structure - * @bb: the badblocks structure that holds all badblock information - * @enable: weather to enable badblocks accounting - * - * Return: - * 0: success - * -ve errno: on error - */ -int badblocks_init(struct badblocks *bb, int enable) +static int __badblocks_init(struct device *dev, struct badblocks *bb, + int enable) { + bb->dev = dev; bb->count = 0; if (enable) bb->shift = 0; else bb->shift = -1; - bb->page = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (bb->page == (u64 *)0) { + if (dev) + bb->page = devm_kzalloc(dev, PAGE_SIZE, GFP_KERNEL); + else + bb->page = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!bb->page) { bb->shift = -1; return -ENOMEM; } @@ -547,8 +544,30 @@ int badblocks_init(struct badblocks *bb, int enable) return 0; } + +/** + * badblocks_init() - initialize the badblocks structure + * @bb: the badblocks structure that holds all badblock information + * @enable: weather to enable badblocks accounting + * + * Return: + * 0: success + * -ve errno: on error + */ +int badblocks_init(struct badblocks *bb, int enable) +{ + return __badblocks_init(NULL, bb, enable); +} EXPORT_SYMBOL_GPL(badblocks_init); +int devm_init_badblocks(struct device *dev, struct badblocks *bb) +{ + if (!bb) + return -EINVAL; + return __badblocks_init(dev, bb, 1); +} +EXPORT_SYMBOL_GPL(devm_init_badblocks); + /** * badblocks_exit() - free the badblocks structure * @bb: the badblocks structure that holds all badblock information @@ -557,7 +576,10 @@ void badblocks_exit(struct badblocks *bb) { if (!bb) return; - kfree(bb->page); + if (bb->dev) + devm_kfree(bb->dev, bb->page); + else + kfree(bb->page); bb->page = NULL; } EXPORT_SYMBOL_GPL(badblocks_exit); diff --git a/include/linux/badblocks.h b/include/linux/badblocks.h index 2d98c026c57f6..c3bdf8c594800 100644 --- a/include/linux/badblocks.h +++ b/include/linux/badblocks.h @@ -2,6 +2,7 @@ #define _LINUX_BADBLOCKS_H #include +#include #include #include #include @@ -23,6 +24,7 @@ #define MAX_BADBLOCKS (PAGE_SIZE/8) struct badblocks { + struct device *dev; /* set by devm_init_badblocks */ int count; /* count of bad blocks */ int unacked_exist; /* there probably are unacknowledged * bad blocks. This is only cleared @@ -49,5 +51,15 @@ ssize_t badblocks_store(struct badblocks *bb, const char *page, size_t len, int unack); int badblocks_init(struct badblocks *bb, int enable); void badblocks_exit(struct badblocks *bb); - +struct device; +int devm_init_badblocks(struct device *dev, struct badblocks *bb); +static inline void devm_exit_badblocks(struct device *dev, struct badblocks *bb) +{ + if (bb->dev != dev) { + dev_WARN_ONCE(dev, 1, "%s: badblocks instance not associated\n", + __func__); + return; + } + badblocks_exit(bb); +} #endif -- GitLab From 87ba05dff3510f9e058b35d3c3fa222b6f406ecc Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 9 Jan 2016 07:48:43 -0800 Subject: [PATCH 2379/2855] libnvdimm: don't fail init for full badblocks list If the badblocks list runs out of space it simply means that software is unable to intercept all errors. This is no different than the latent discovery of new badblocks case and should not be an initialization failure condition. Signed-off-by: Dan Williams --- drivers/nvdimm/core.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c index 21003b7f0b384..e419d661e2948 100644 --- a/drivers/nvdimm/core.c +++ b/drivers/nvdimm/core.c @@ -360,6 +360,18 @@ struct nvdimm_bus *__nvdimm_bus_register(struct device *parent, } EXPORT_SYMBOL_GPL(__nvdimm_bus_register); +static void set_badblock(struct gendisk *disk, sector_t s, int num) +{ + struct device *dev = disk->driverfs_dev; + + dev_dbg(dev, "Found a poison range (0x%llx, 0x%llx)\n", + (u64) s * 512, (u64) num * 512); + /* this isn't an error as the hardware will still throw an exception */ + if (disk_set_badblocks(disk, s, num)) + dev_info_once(dev, "%s: failed for sector %llx\n", + __func__, (u64) s); +} + /** * __add_badblock_range() - Convert a physical address range to bad sectors * @disk: the disk associated with the namespace @@ -396,15 +408,14 @@ static int __add_badblock_range(struct gendisk *disk, u64 ns_offset, u64 len) while (remaining) { int done = min_t(u64, remaining, INT_MAX); - rc = disk_set_badblocks(disk, s, done); - if (rc) - return rc; + set_badblock(disk, s, done); remaining -= done; s += done; } - return 0; } else - return disk_set_badblocks(disk, start_sector, num_sectors); + set_badblock(disk, start_sector, num_sectors); + + return 0; } /** @@ -463,9 +474,6 @@ int nvdimm_namespace_add_poison(struct gendisk *disk, resource_size_t offset, rc = __add_badblock_range(disk, start - ns_start, len); if (rc) return rc; - dev_info(&nvdimm_bus->dev, - "Found a poison range (0x%llx, 0x%llx)\n", - start, len); continue; } /* Deal with overlap for poison starting before the namespace */ @@ -480,9 +488,6 @@ int nvdimm_namespace_add_poison(struct gendisk *disk, resource_size_t offset, rc = __add_badblock_range(disk, 0, len); if (rc) return rc; - dev_info(&nvdimm_bus->dev, - "Found a poison range (0x%llx, 0x%llx)\n", - pl->start, len); } } -- GitLab From b95f5f4391fad65f1819c2404080b05ca95bdd92 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 4 Jan 2016 23:50:23 -0800 Subject: [PATCH 2380/2855] libnvdimm: convert to statically allocated badblocks If a device will ever have badblocks it should always have a badblocks instance available. So, similar to md, embed a badblocks instance in pmem_device. This reduces pointer chasing in the i/o fast path, and simplifies the init path. Reported-by: Vishal Verma Signed-off-by: Dan Williams --- drivers/nvdimm/core.c | 57 +++++++++++++------------------------------ drivers/nvdimm/nd.h | 4 +-- drivers/nvdimm/pmem.c | 10 ++++---- 3 files changed, 24 insertions(+), 47 deletions(-) diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c index e419d661e2948..2e2832b83c939 100644 --- a/drivers/nvdimm/core.c +++ b/drivers/nvdimm/core.c @@ -11,6 +11,7 @@ * General Public License for more details. */ #include +#include #include #include #include @@ -360,21 +361,19 @@ struct nvdimm_bus *__nvdimm_bus_register(struct device *parent, } EXPORT_SYMBOL_GPL(__nvdimm_bus_register); -static void set_badblock(struct gendisk *disk, sector_t s, int num) +static void set_badblock(struct badblocks *bb, sector_t s, int num) { - struct device *dev = disk->driverfs_dev; - - dev_dbg(dev, "Found a poison range (0x%llx, 0x%llx)\n", + dev_dbg(bb->dev, "Found a poison range (0x%llx, 0x%llx)\n", (u64) s * 512, (u64) num * 512); /* this isn't an error as the hardware will still throw an exception */ - if (disk_set_badblocks(disk, s, num)) - dev_info_once(dev, "%s: failed for sector %llx\n", + if (badblocks_set(bb, s, num, 1)) + dev_info_once(bb->dev, "%s: failed for sector %llx\n", __func__, (u64) s); } /** * __add_badblock_range() - Convert a physical address range to bad sectors - * @disk: the disk associated with the namespace + * @bb: badblocks instance to populate * @ns_offset: namespace offset where the error range begins (in bytes) * @len: number of bytes of poison to be added * @@ -382,25 +381,18 @@ static void set_badblock(struct gendisk *disk, sector_t s, int num) * the bounds of physical addresses for this namespace, i.e. lies in the * interval [ns_start, ns_start + ns_size) */ -static int __add_badblock_range(struct gendisk *disk, u64 ns_offset, u64 len) +static void __add_badblock_range(struct badblocks *bb, u64 ns_offset, u64 len) { - unsigned int sector_size = queue_logical_block_size(disk->queue); + const unsigned int sector_size = 512; sector_t start_sector; u64 num_sectors; u32 rem; - int rc; start_sector = div_u64(ns_offset, sector_size); num_sectors = div_u64_rem(len, sector_size, &rem); if (rem) num_sectors++; - if (!disk->bb) { - rc = disk_alloc_badblocks(disk); - if (rc) - return rc; - } - if (unlikely(num_sectors > (u64)INT_MAX)) { u64 remaining = num_sectors; sector_t s = start_sector; @@ -408,33 +400,27 @@ static int __add_badblock_range(struct gendisk *disk, u64 ns_offset, u64 len) while (remaining) { int done = min_t(u64, remaining, INT_MAX); - set_badblock(disk, s, done); + set_badblock(bb, s, done); remaining -= done; s += done; } } else - set_badblock(disk, start_sector, num_sectors); - - return 0; + set_badblock(bb, start_sector, num_sectors); } /** * nvdimm_namespace_add_poison() - Convert a list of poison ranges to badblocks - * @disk: the gendisk associated with the namespace where badblocks - * will be stored - * @offset: offset at the start of the namespace before 'sector 0' * @ndns: the namespace containing poison ranges + * @bb: badblocks instance to populate + * @offset: offset at the start of the namespace before 'sector 0' * * The poison list generated during NFIT initialization may contain multiple, * possibly overlapping ranges in the SPA (System Physical Address) space. * Compare each of these ranges to the namespace currently being initialized, * and add badblocks to the gendisk for all matching sub-ranges - * - * Return: - * 0 - Success */ -int nvdimm_namespace_add_poison(struct gendisk *disk, resource_size_t offset, - struct nd_namespace_common *ndns) +void nvdimm_namespace_add_poison(struct nd_namespace_common *ndns, + struct badblocks *bb, resource_size_t offset) { struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev); struct nd_region *nd_region = to_nd_region(ndns->dev.parent); @@ -442,7 +428,6 @@ int nvdimm_namespace_add_poison(struct gendisk *disk, resource_size_t offset, struct list_head *poison_list; u64 ns_start, ns_end, ns_size; struct nd_poison *pl; - int rc; ns_size = nvdimm_namespace_capacity(ndns) - offset; ns_start = nsio->res.start + offset; @@ -451,7 +436,7 @@ int nvdimm_namespace_add_poison(struct gendisk *disk, resource_size_t offset, nvdimm_bus = to_nvdimm_bus(nd_region->dev.parent); poison_list = &nvdimm_bus->poison_list; if (list_empty(poison_list)) - return 0; + return; list_for_each_entry(pl, poison_list, list) { u64 pl_end = pl->start + pl->length - 1; @@ -470,10 +455,7 @@ int nvdimm_namespace_add_poison(struct gendisk *disk, resource_size_t offset, len = pl->length; else len = ns_start + ns_size - pl->start; - - rc = __add_badblock_range(disk, start - ns_start, len); - if (rc) - return rc; + __add_badblock_range(bb, start - ns_start, len); continue; } /* Deal with overlap for poison starting before the namespace */ @@ -484,14 +466,9 @@ int nvdimm_namespace_add_poison(struct gendisk *disk, resource_size_t offset, len = pl->start + pl->length - ns_start; else len = ns_size; - - rc = __add_badblock_range(disk, 0, len); - if (rc) - return rc; + __add_badblock_range(bb, 0, len); } } - - return 0; } EXPORT_SYMBOL_GPL(nvdimm_namespace_add_poison); diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h index 198933da83e5a..288d96ec72336 100644 --- a/drivers/nvdimm/nd.h +++ b/drivers/nvdimm/nd.h @@ -268,8 +268,8 @@ int nvdimm_namespace_attach_btt(struct nd_namespace_common *ndns); int nvdimm_namespace_detach_btt(struct nd_namespace_common *ndns); const char *nvdimm_namespace_disk_name(struct nd_namespace_common *ndns, char *name); -int nvdimm_namespace_add_poison(struct gendisk *disk, resource_size_t offset, - struct nd_namespace_common *ndns); +void nvdimm_namespace_add_poison(struct nd_namespace_common *ndns, + struct badblocks *bb, resource_size_t offset); int nd_blk_region_init(struct nd_region *nd_region); void __nd_iostat_start(struct bio *bio, unsigned long *start); static inline bool nd_iostat_start(struct bio *bio, unsigned long *start) diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 65b2056e75404..2b1f3009f8270 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ struct pmem_device { phys_addr_t data_offset; void __pmem *virt_addr; size_t size; + struct badblocks bb; }; static int pmem_major; @@ -168,7 +170,6 @@ static int pmem_attach_disk(struct device *dev, { int nid = dev_to_node(dev); struct gendisk *disk; - int ret; pmem->pmem_queue = blk_alloc_queue_node(GFP_KERNEL, nid); if (!pmem->pmem_queue) @@ -196,10 +197,9 @@ static int pmem_attach_disk(struct device *dev, disk->driverfs_dev = dev; set_capacity(disk, (pmem->size - pmem->data_offset) / 512); pmem->pmem_disk = disk; - - ret = nvdimm_namespace_add_poison(disk, pmem->data_offset, ndns); - if (ret) - return ret; + if (devm_init_badblocks(dev, &pmem->bb)) + return -ENOMEM; + nvdimm_namespace_add_poison(ndns, &pmem->bb, pmem->data_offset); add_disk(disk); revalidate_disk(disk); -- GitLab From e10624f8c09710b3b0740ea3847627ea02f55c39 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 6 Jan 2016 12:03:41 -0800 Subject: [PATCH 2381/2855] pmem: fail io-requests to known bad blocks Check the sectors specified in a read bio to see if they hit a known bad block, and return an error code pmem_do_bvec(). Note that the ->rw_page() is not in a position to return errors. For now, copy the same layering violation present in zram_rw_page() to avoid crashes of the form: kernel BUG at mm/filemap.c:822! [..] Call Trace: [] page_endio+0x1e/0x60 [] mpage_end_io+0x39/0x60 [] bio_endio+0x3f/0x60 [] pmem_make_request+0x111/0x230 [nd_pmem] ...i.e. unlock a page that was already unlocked via pmem_rw_page() => page_endio(). Reported-by: Vishal Verma Signed-off-by: Dan Williams --- drivers/nvdimm/pmem.c | 46 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 2b1f3009f8270..d00c659d13049 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -47,7 +47,20 @@ struct pmem_device { static int pmem_major; -static void pmem_do_bvec(struct pmem_device *pmem, struct page *page, +static bool is_bad_pmem(struct badblocks *bb, sector_t sector, unsigned int len) +{ + if (bb->count) { + sector_t first_bad; + int num_bad; + + return !!badblocks_check(bb, sector, len / 512, &first_bad, + &num_bad); + } + + return false; +} + +static int pmem_do_bvec(struct pmem_device *pmem, struct page *page, unsigned int len, unsigned int off, int rw, sector_t sector) { @@ -56,6 +69,8 @@ static void pmem_do_bvec(struct pmem_device *pmem, struct page *page, void __pmem *pmem_addr = pmem->virt_addr + pmem_off; if (rw == READ) { + if (unlikely(is_bad_pmem(&pmem->bb, sector, len))) + return -EIO; memcpy_from_pmem(mem + off, pmem_addr, len); flush_dcache_page(page); } else { @@ -64,10 +79,12 @@ static void pmem_do_bvec(struct pmem_device *pmem, struct page *page, } kunmap_atomic(mem); + return 0; } static blk_qc_t pmem_make_request(struct request_queue *q, struct bio *bio) { + int rc = 0; bool do_acct; unsigned long start; struct bio_vec bvec; @@ -76,9 +93,15 @@ static blk_qc_t pmem_make_request(struct request_queue *q, struct bio *bio) struct pmem_device *pmem = bdev->bd_disk->private_data; do_acct = nd_iostat_start(bio, &start); - bio_for_each_segment(bvec, bio, iter) - pmem_do_bvec(pmem, bvec.bv_page, bvec.bv_len, bvec.bv_offset, - bio_data_dir(bio), iter.bi_sector); + bio_for_each_segment(bvec, bio, iter) { + rc = pmem_do_bvec(pmem, bvec.bv_page, bvec.bv_len, + bvec.bv_offset, bio_data_dir(bio), + iter.bi_sector); + if (rc) { + bio->bi_error = rc; + break; + } + } if (do_acct) nd_iostat_end(bio, start); @@ -93,13 +116,22 @@ static int pmem_rw_page(struct block_device *bdev, sector_t sector, struct page *page, int rw) { struct pmem_device *pmem = bdev->bd_disk->private_data; + int rc; - pmem_do_bvec(pmem, page, PAGE_CACHE_SIZE, 0, rw, sector); + rc = pmem_do_bvec(pmem, page, PAGE_CACHE_SIZE, 0, rw, sector); if (rw & WRITE) wmb_pmem(); - page_endio(page, rw & WRITE, 0); - return 0; + /* + * The ->rw_page interface is subtle and tricky. The core + * retries on any error, so we can only invoke page_endio() in + * the successful completion case. Otherwise, we'll see crashes + * caused by double completion. + */ + if (rc == 0) + page_endio(page, rw & WRITE, 0); + + return rc; } static long pmem_direct_access(struct block_device *bdev, sector_t sector, -- GitLab From 57f7f317abdd07954cb116280c88d18378afb33e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 6 Jan 2016 12:03:42 -0800 Subject: [PATCH 2382/2855] pmem, dax: disable dax in the presence of bad blocks Longer term teach dax to punch "error" holes in mapping requests and deliver SIGBUS to applications that consume a bad pmem page. For now, simply disable the dax performance optimization in the presence of known errors. Signed-off-by: Dan Williams --- block/ioctl.c | 10 ++++++++++ drivers/nvdimm/pmem.c | 1 + 2 files changed, 11 insertions(+) diff --git a/block/ioctl.c b/block/ioctl.c index 7a964d842913f..2c84683aada56 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -422,6 +423,15 @@ bool blkdev_dax_capable(struct block_device *bdev) || (bdev->bd_part->nr_sects % (PAGE_SIZE / 512))) return false; + /* + * If the device has known bad blocks, force all I/O through the + * driver / page cache. + * + * TODO: support finer grained dax error handling + */ + if (disk->bb && disk->bb->count) + return false; + return true; } diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index d00c659d13049..6a1832b3983ca 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -233,6 +233,7 @@ static int pmem_attach_disk(struct device *dev, return -ENOMEM; nvdimm_namespace_add_poison(ndns, &pmem->bb, pmem->data_offset); + disk->bb = &pmem->bb; add_disk(disk); revalidate_disk(disk); -- GitLab From 710d69cc99507803ed91b4ec7368fbd66d59f014 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 4 Jan 2016 23:31:24 -0800 Subject: [PATCH 2383/2855] libnvdimm, pmem: nvdimm_read_bytes() badblocks support Support badblock checking in all the pmem read paths that do not go through the block layer. This protects info block reads (btt or pfn) as well as data reads to a pmem namespace via a btt instance. Signed-off-by: Dan Williams --- drivers/nvdimm/pmem.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 6a1832b3983ca..a88762d0d086b 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -229,6 +229,7 @@ static int pmem_attach_disk(struct device *dev, disk->driverfs_dev = dev; set_capacity(disk, (pmem->size - pmem->data_offset) / 512); pmem->pmem_disk = disk; + devm_exit_badblocks(dev, &pmem->bb); if (devm_init_badblocks(dev, &pmem->bb)) return -ENOMEM; nvdimm_namespace_add_poison(ndns, &pmem->bb, pmem->data_offset); @@ -250,9 +251,13 @@ static int pmem_rw_bytes(struct nd_namespace_common *ndns, return -EFAULT; } - if (rw == READ) + if (rw == READ) { + unsigned int sz_align = ALIGN(size + (offset & (512 - 1)), 512); + + if (unlikely(is_bad_pmem(&pmem->bb, offset / 512, sz_align))) + return -EIO; memcpy_from_pmem(buf, pmem->virt_addr + offset, size); - else { + } else { memcpy_to_pmem(pmem->virt_addr + offset, buf, size); wmb_pmem(); } @@ -427,6 +432,9 @@ static int nd_pmem_probe(struct device *dev) pmem->ndns = ndns; dev_set_drvdata(dev, pmem); ndns->rw_bytes = pmem_rw_bytes; + if (devm_init_badblocks(dev, &pmem->bb)) + return -ENOMEM; + nvdimm_namespace_add_poison(ndns, &pmem->bb, 0); if (is_nd_btt(dev)) return nvdimm_namespace_attach_btt(ndns); -- GitLab From 55f5560d8c18fe33fc169f8d244a9247dcac7612 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 5 Jan 2016 00:28:18 -0800 Subject: [PATCH 2384/2855] block: kill disk_{check|set|clear|alloc}_badblocks These actions are completely managed by a block driver or can use the badblocks api directly. Signed-off-by: Dan Williams --- block/genhd.c | 42 ------------------------------------------ include/linux/genhd.h | 5 ----- 2 files changed, 47 deletions(-) diff --git a/block/genhd.c b/block/genhd.c index aa38cd0a66c76..5aaeb2ad0fd39 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -506,16 +506,6 @@ static int exact_lock(dev_t devt, void *data) return 0; } -int disk_alloc_badblocks(struct gendisk *disk) -{ - disk->bb = kzalloc(sizeof(*(disk->bb)), GFP_KERNEL); - if (!disk->bb) - return -ENOMEM; - - return badblocks_init(disk->bb, 1); -} -EXPORT_SYMBOL(disk_alloc_badblocks); - static void register_disk(struct gendisk *disk) { struct device *ddev = disk_to_dev(disk); @@ -682,38 +672,6 @@ void del_gendisk(struct gendisk *disk) } EXPORT_SYMBOL(del_gendisk); -/* - * The gendisk usage of badblocks does not track acknowledgements for - * badblocks. We always assume they are acknowledged. - */ -int disk_check_badblocks(struct gendisk *disk, sector_t s, int sectors, - sector_t *first_bad, int *bad_sectors) -{ - if (!disk->bb) - return 0; - - return badblocks_check(disk->bb, s, sectors, first_bad, bad_sectors); -} -EXPORT_SYMBOL(disk_check_badblocks); - -int disk_set_badblocks(struct gendisk *disk, sector_t s, int sectors) -{ - if (!disk->bb) - return 0; - - return badblocks_set(disk->bb, s, sectors, 1); -} -EXPORT_SYMBOL(disk_set_badblocks); - -int disk_clear_badblocks(struct gendisk *disk, sector_t s, int sectors) -{ - if (!disk->bb) - return 0; - - return badblocks_clear(disk->bb, s, sectors); -} -EXPORT_SYMBOL(disk_clear_badblocks); - /* sysfs access to bad-blocks list. */ static ssize_t disk_badblocks_show(struct device *dev, struct device_attribute *attr, diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 0bbec68800518..5c706765404a8 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -435,11 +435,6 @@ extern void add_disk(struct gendisk *disk); extern void del_gendisk(struct gendisk *gp); extern struct gendisk *get_gendisk(dev_t dev, int *partno); extern struct block_device *bdget_disk(struct gendisk *disk, int partno); -int disk_alloc_badblocks(struct gendisk *disk); -extern int disk_check_badblocks(struct gendisk *disk, sector_t s, int sectors, - sector_t *first_bad, int *bad_sectors); -extern int disk_set_badblocks(struct gendisk *disk, sector_t s, int sectors); -extern int disk_clear_badblocks(struct gendisk *disk, sector_t s, int sectors); extern void set_device_ro(struct block_device *bdev, int flag); extern void set_disk_ro(struct gendisk *disk, int flag); -- GitLab From 8d22f309384cc410da91543f1eb30fe5daf91c3b Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Wed, 23 Dec 2015 18:43:24 +0200 Subject: [PATCH 2385/2855] i2c: designware: retry transfer on transient failure Set the i2c_adapter retries field to a sensible value. This allows the i2c core to retry master_xfer() when it returns -EAGAIN. Currently the i2c-designware driver returns -EAGAIN only on Tx arbitration failure (DW_IC_TX_ARB_LOST). Reported-by: Rolland Chau Signed-off-by: Baruch Siach Acked-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 8c48b27ba0597..8055cbd4cba1a 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -854,6 +854,7 @@ int i2c_dw_probe(struct dw_i2c_dev *dev) snprintf(adap->name, sizeof(adap->name), "Synopsys DesignWare I2C adapter"); + adap->retries = 3; adap->algo = &i2c_dw_algo; adap->dev.parent = dev->dev; i2c_set_adapdata(adap, dev); -- GitLab From 9f924169c0358f630f9b6d26bb3de97360d8647b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 23 Dec 2015 18:19:28 +0100 Subject: [PATCH 2386/2855] i2c: always enable RuntimePM for the adapter device The adapter device is a logical device. Because of that, it already uses pm_runtime_no_callbacks() in the core. To ensure proper propagation from the children (i2c devices) to the parent of the adapter (the HW device), make sure RuntimePM is enabled in any case. Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 7349b00f41017..ffe715d346d88 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1564,6 +1564,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap) dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name); pm_runtime_no_callbacks(&adap->dev); + pm_runtime_enable(&adap->dev); #ifdef CONFIG_I2C_COMPAT res = class_compat_create_link(i2c_adapter_compat_class, &adap->dev, @@ -1818,6 +1819,8 @@ void i2c_del_adapter(struct i2c_adapter *adap) /* device name is gone after device_unregister */ dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); + pm_runtime_disable(&adap->dev); + /* wait until all references to the device are gone * * FIXME: This is old code and should ideally be replaced by an -- GitLab From 2fe3e5189206f725b054e23b06762e50a7ab6276 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 23 Dec 2015 18:19:29 +0100 Subject: [PATCH 2387/2855] i2c: s3c2410: remove superfluous runtime PM calls RuntimePM of the adapter device is now taken care of by the core. So, we can remove these calls. Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-s3c2410.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 5df819610d528..362a6de548336 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -784,7 +784,6 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap, int retry; int ret; - pm_runtime_get_sync(&adap->dev); ret = clk_enable(i2c->clk); if (ret) return ret; @@ -795,7 +794,6 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap, if (ret != -EAGAIN) { clk_disable(i2c->clk); - pm_runtime_put(&adap->dev); return ret; } @@ -805,7 +803,6 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap, } clk_disable(i2c->clk); - pm_runtime_put(&adap->dev); return -EREMOTEIO; } @@ -1256,8 +1253,6 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) return ret; } - pm_runtime_enable(&i2c->adap.dev); - dev_info(&pdev->dev, "%s: S3C I2C adapter\n", dev_name(&i2c->adap.dev)); return 0; } @@ -1273,7 +1268,6 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev) clk_unprepare(i2c->clk); - pm_runtime_disable(&i2c->adap.dev); pm_runtime_disable(&pdev->dev); s3c24xx_i2c_deregister_cpufreq(i2c); -- GitLab From fa5b0bfa26d54b9b94e5c2ff9c826d1e12d6ad3a Mon Sep 17 00:00:00 2001 From: Akshay Bhat Date: Wed, 23 Dec 2015 13:38:58 -0500 Subject: [PATCH 2388/2855] DT: i2c: trivial-devices: Add Epson RX8010 and MPL3115 Signed-off-by: Akshay Bhat Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/trivial-devices.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt index c50cf13c852e5..1f25fba604e85 100644 --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt @@ -49,11 +49,13 @@ dallas,ds4510 CPU Supervisor with Nonvolatile Memory and Programmable I/O dallas,ds75 Digital Thermometer and Thermostat dlg,da9053 DA9053: flexible system level PMIC with multicore support dlg,da9063 DA9063: system PMIC for quad-core application processors +epson,rx8010 I2C-BUS INTERFACE REAL TIME CLOCK MODULE epson,rx8025 High-Stability. I2C-Bus INTERFACE REAL TIME CLOCK MODULE epson,rx8581 I2C-BUS INTERFACE REAL TIME CLOCK MODULE fsl,mag3110 MAG3110: Xtrinsic High Accuracy, 3D Magnetometer fsl,mc13892 MC13892: Power Management Integrated Circuit (PMIC) for i.MX35/51 fsl,mma8450 MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer +fsl,mpl3115 MPL3115: Absolute Digital Pressure Sensor fsl,mpr121 MPR121: Proximity Capacitive Touch Sensor Controller fsl,sgtl5000 SGTL5000: Ultra Low-Power Audio Codec gmt,g751 G751: Digital Temperature Sensor and Thermal Watchdog with Two-Wire Interface -- GitLab From b33af11de236fd6e25f3716182f008039ec68e93 Mon Sep 17 00:00:00 2001 From: Suravee Suthikulpanit Date: Mon, 4 Jan 2016 09:17:35 -0600 Subject: [PATCH 2389/2855] i2c: designware: Do not require clock when SSCN and FFCN are provided The current driver uses input clock source frequency to calculate values for [SS|FS]_[HC|LC] registers. However, when booting ACPI, we do not currently have a good way to provide the frequency information. Instead, we can leverage the SSCN and FFCN ACPI methods, which can be used to directly provide these values. So, the clock information should no longer be required during probing. However, since clk can be invalid, additional checks must be done where we are making use of it. Signed-off-by: Mika Westerberg Signed-off-by: Suravee Suthikulpanit Tested-by: Loc Ho Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-core.c | 22 ++++++++++----- drivers/i2c/busses/i2c-designware-platdrv.c | 31 +++++++++++++-------- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 8055cbd4cba1a..5b6cb45da459f 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -271,6 +271,17 @@ static void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable) enable ? "en" : "dis"); } +static unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev) +{ + /* + * Clock is not necessary if we got LCNT/HCNT values directly from + * the platform code. + */ + if (WARN_ON_ONCE(!dev->get_clk_rate_khz)) + return 0; + return dev->get_clk_rate_khz(dev); +} + /** * i2c_dw_init() - initialize the designware i2c master hardware * @dev: device private data @@ -281,7 +292,6 @@ static void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable) */ int i2c_dw_init(struct dw_i2c_dev *dev) { - u32 input_clock_khz; u32 hcnt, lcnt; u32 reg; u32 sda_falling_time, scl_falling_time; @@ -295,8 +305,6 @@ int i2c_dw_init(struct dw_i2c_dev *dev) } } - input_clock_khz = dev->get_clk_rate_khz(dev); - reg = dw_readl(dev, DW_IC_COMP_TYPE); if (reg == ___constant_swab32(DW_IC_COMP_TYPE_VALUE)) { /* Configure register endianess access */ @@ -325,12 +333,12 @@ int i2c_dw_init(struct dw_i2c_dev *dev) hcnt = dev->ss_hcnt; lcnt = dev->ss_lcnt; } else { - hcnt = i2c_dw_scl_hcnt(input_clock_khz, + hcnt = i2c_dw_scl_hcnt(i2c_dw_clk_rate(dev), 4000, /* tHD;STA = tHIGH = 4.0 us */ sda_falling_time, 0, /* 0: DW default, 1: Ideal */ 0); /* No offset */ - lcnt = i2c_dw_scl_lcnt(input_clock_khz, + lcnt = i2c_dw_scl_lcnt(i2c_dw_clk_rate(dev), 4700, /* tLOW = 4.7 us */ scl_falling_time, 0); /* No offset */ @@ -344,12 +352,12 @@ int i2c_dw_init(struct dw_i2c_dev *dev) hcnt = dev->fs_hcnt; lcnt = dev->fs_lcnt; } else { - hcnt = i2c_dw_scl_hcnt(input_clock_khz, + hcnt = i2c_dw_scl_hcnt(i2c_dw_clk_rate(dev), 600, /* tHD;STA = tHIGH = 0.6 us */ sda_falling_time, 0, /* 0: DW default, 1: Ideal */ 0); /* No offset */ - lcnt = i2c_dw_scl_lcnt(input_clock_khz, + lcnt = i2c_dw_scl_lcnt(i2c_dw_clk_rate(dev), 1300, /* tLOW = 1.3 us */ scl_falling_time, 0); /* No offset */ diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 8ffc36b8a6d39..965512c3b1cfb 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -128,6 +128,18 @@ static inline int dw_i2c_acpi_configure(struct platform_device *pdev) } #endif +static int i2c_dw_plat_prepare_clk(struct dw_i2c_dev *i_dev, bool prepare) +{ + if (IS_ERR(i_dev->clk)) + return PTR_ERR(i_dev->clk); + + if (prepare) + return clk_prepare_enable(i_dev->clk); + + clk_disable_unprepare(i_dev->clk); + return 0; +} + static int dw_i2c_plat_probe(struct platform_device *pdev) { struct dw_i2c_dev *dev; @@ -205,16 +217,13 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST; dev->clk = devm_clk_get(&pdev->dev, NULL); - dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; - if (IS_ERR(dev->clk)) - return PTR_ERR(dev->clk); - clk_prepare_enable(dev->clk); + if (!i2c_dw_plat_prepare_clk(dev, true)) { + dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; - if (!dev->sda_hold_time && ht) { - u32 ic_clk = dev->get_clk_rate_khz(dev); - - dev->sda_hold_time = div_u64((u64)ic_clk * ht + 500000, - 1000000); + if (!dev->sda_hold_time && ht) + dev->sda_hold_time = div_u64( + (u64)dev->get_clk_rate_khz(dev) * ht + 500000, + 1000000); } if (!dev->tx_fifo_depth) { @@ -297,7 +306,7 @@ static int dw_i2c_plat_suspend(struct device *dev) struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev); i2c_dw_disable(i_dev); - clk_disable_unprepare(i_dev->clk); + i2c_dw_plat_prepare_clk(i_dev, false); return 0; } @@ -307,7 +316,7 @@ static int dw_i2c_plat_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev); - clk_prepare_enable(i_dev->clk); + i2c_dw_plat_prepare_clk(i_dev, true); if (!i_dev->pm_runtime_disabled) i2c_dw_init(i_dev); -- GitLab From f5e12d0d5bd4d2bc028bf3dda1732bde3824a008 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 7 Jan 2016 21:50:59 +0100 Subject: [PATCH 2390/2855] dt-bindings: move I2C eeprom descriptions to the proper file EEPROMs can have additional properties, so they are not suitable for trivial-devices.txt. Move most bindings to the designated eeprom.txt. Add the missing "atmel,24c08" while doing that. Note that the remaining ones in trivial-devices need to be dealt with separately because of improper manufacturer names. Signed-off-by: Wolfram Sang Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- .../devicetree/bindings/eeprom/eeprom.txt | 19 ++++++++++++++----- .../bindings/i2c/trivial-devices.txt | 13 ------------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/Documentation/devicetree/bindings/eeprom/eeprom.txt b/Documentation/devicetree/bindings/eeprom/eeprom.txt index 4342c10de1bf8..acb600399c3d9 100644 --- a/Documentation/devicetree/bindings/eeprom/eeprom.txt +++ b/Documentation/devicetree/bindings/eeprom/eeprom.txt @@ -2,11 +2,20 @@ EEPROMs (I2C) Required properties: - - compatible : should be "," - If there is no specific driver for , a generic - driver based on is selected. Possible types are: - 24c00, 24c01, 24c02, 24c04, 24c08, 24c16, 24c32, 24c64, - 24c128, 24c256, 24c512, 24c1024, spd + - compatible : should be ",", like these: + + "atmel,24c00", "atmel,24c01", "atmel,24c02", "atmel,24c04", + "atmel,24c08", "atmel,24c16", "atmel,24c32", "atmel,24c64", + "atmel,24c128", "atmel,24c256", "atmel,24c512", "atmel,24c1024" + + "catalyst,24c32" + + "ramtron,24c64" + + If there is no specific driver for , a generic + driver based on is selected. Possible types are: + "24c00", "24c01", "24c02", "24c04", "24c08", "24c16", "24c32", "24c64", + "24c128", "24c256", "24c512", "24c1024", "spd" - reg : the I2C address of the EEPROM diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt index 1f25fba604e85..f0568a6448c99 100644 --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt @@ -21,21 +21,9 @@ adi,adt7490 +/-1C TDM Extended Temp Range I.C adi,adxl345 Three-Axis Digital Accelerometer adi,adxl346 Three-Axis Digital Accelerometer (backward-compatibility value "adi,adxl345" must be listed too) at,24c08 i2c serial eeprom (24cxx) -atmel,24c00 i2c serial eeprom (24cxx) -atmel,24c01 i2c serial eeprom (24cxx) -atmel,24c02 i2c serial eeprom (24cxx) -atmel,24c04 i2c serial eeprom (24cxx) -atmel,24c16 i2c serial eeprom (24cxx) -atmel,24c32 i2c serial eeprom (24cxx) -atmel,24c64 i2c serial eeprom (24cxx) -atmel,24c128 i2c serial eeprom (24cxx) -atmel,24c256 i2c serial eeprom (24cxx) -atmel,24c512 i2c serial eeprom (24cxx) -atmel,24c1024 i2c serial eeprom (24cxx) atmel,at97sc3204t i2c trusted platform module (TPM) capella,cm32181 CM32181: Ambient Light Sensor capella,cm3232 CM3232: Ambient Light Sensor -catalyst,24c32 i2c serial eeprom cirrus,cs42l51 Cirrus Logic CS42L51 audio codec dallas,ds1307 64 x 8, Serial, I2C Real-Time Clock dallas,ds1338 I2C RTC with 56-Byte NV RAM @@ -82,7 +70,6 @@ ovti,ov5642 OV5642: Color CMOS QSXGA (5-megapixel) Image Sensor with OmniBSI an pericom,pt7c4338 Real-time Clock Module plx,pex8648 48-Lane, 12-Port PCI Express Gen 2 (5.0 GT/s) Switch pulsedlight,lidar-lite-v2 Pulsedlight LIDAR range-finding sensor -ramtron,24c64 i2c serial eeprom (24cxx) ricoh,r2025sd I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC ricoh,r2221tl I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC ricoh,rs5c372a I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC -- GitLab From a570a27af4d781619dfb5139f3b760e964373c29 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 7 Jan 2016 21:51:00 +0100 Subject: [PATCH 2391/2855] dt-bindings: i2c: eeprom: add another EEPROM device Signed-off-by: Wolfram Sang Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/eeprom/eeprom.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/eeprom/eeprom.txt b/Documentation/devicetree/bindings/eeprom/eeprom.txt index acb600399c3d9..735bc94444bbd 100644 --- a/Documentation/devicetree/bindings/eeprom/eeprom.txt +++ b/Documentation/devicetree/bindings/eeprom/eeprom.txt @@ -12,6 +12,8 @@ Required properties: "ramtron,24c64" + "renesas,r1ex24002" + If there is no specific driver for , a generic driver based on is selected. Possible types are: "24c00", "24c01", "24c02", "24c04", "24c08", "24c16", "24c32", "24c64", -- GitLab From c55281531282930de0aace46b2d6b22653937818 Mon Sep 17 00:00:00 2001 From: Gao Pan Date: Fri, 8 Jan 2016 13:33:15 +0800 Subject: [PATCH 2392/2855] i2c: imx: fix i2c resource leak with dma transfer In i2c_imx_dma_xfer(), when dmaengine_submit() returns error, the context goto label err_submit and then return. However, the memory allocated for txdesc has not been freed yet, which leads to resource leak. Signed-off-by: Gao Pan Signed-off-by: Fugang Duan Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-imx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 8b68dbf4786cc..a2b132cef7172 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -387,6 +387,7 @@ static int i2c_imx_dma_xfer(struct imx_i2c_struct *i2c_imx, return 0; err_submit: + dmaengine_terminate_all(dma->chan_using); err_desc: dma_unmap_single(chan_dev, dma->dma_buf, dma->dma_len, dma->dma_data_dir); -- GitLab From 8679ee4204cfd5cf78b996508ccadc1ec6130f1a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 6 Jan 2016 14:20:07 -0800 Subject: [PATCH 2393/2855] Input: gpio-keys - fix check for disabling unsupported keys Commit 4ea14a53d8f881034fa9e186653821c4e3d9a8fb ("Input: gpio-keys - report error when disabling unsupported key") tried let user know that they attempted to disable an unsupported key, unfortunately the check is wrong as it believes that all codes are invalid. Fix it by ensuring that keys that we try to disable are subset of keys (or switches) that device reports. Fixes: 4ea14a53d8f8 ("Input: gpio-keys - report error when disabling unsupported key") Reported-by: Ivaylo Dimitrov Tested-by: Ivaylo Dimitrov Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/gpio_keys.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index bef317ff7352f..b9f01bd1b7ef1 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -96,13 +96,29 @@ struct gpio_keys_drvdata { * Return value of this function can be used to allocate bitmap * large enough to hold all bits for given type. */ -static inline int get_n_events_by_type(int type) +static int get_n_events_by_type(int type) { BUG_ON(type != EV_SW && type != EV_KEY); return (type == EV_KEY) ? KEY_CNT : SW_CNT; } +/** + * get_bm_events_by_type() - returns bitmap of supported events per @type + * @input: input device from which bitmap is retrieved + * @type: type of button (%EV_KEY, %EV_SW) + * + * Return value of this function can be used to allocate bitmap + * large enough to hold all bits for given type. + */ +static const unsigned long *get_bm_events_by_type(struct input_dev *dev, + int type) +{ + BUG_ON(type != EV_SW && type != EV_KEY); + + return (type == EV_KEY) ? dev->keybit : dev->swbit; +} + /** * gpio_keys_disable_button() - disables given GPIO button * @bdata: button data for button to be disabled @@ -213,6 +229,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, const char *buf, unsigned int type) { int n_events = get_n_events_by_type(type); + const unsigned long *bitmap = get_bm_events_by_type(ddata->input, type); unsigned long *bits; ssize_t error; int i; @@ -226,6 +243,11 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, goto out; /* First validate */ + if (!bitmap_subset(bits, bitmap, n_events)) { + error = -EINVAL; + goto out; + } + for (i = 0; i < ddata->pdata->nbuttons; i++) { struct gpio_button_data *bdata = &ddata->data[i]; @@ -239,11 +261,6 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, } } - if (i == ddata->pdata->nbuttons) { - error = -EINVAL; - goto out; - } - mutex_lock(&ddata->disable_lock); for (i = 0; i < ddata->pdata->nbuttons; i++) { -- GitLab From f6106efae5f4144b32f6c10de0dc3e7efc9181e3 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Mon, 11 Jan 2016 11:34:01 +1100 Subject: [PATCH 2394/2855] xfs: eliminate committed arg from xfs_bmap_finish Calls to xfs_bmap_finish() and xfs_trans_ijoin(), and the associated comments were replicated several times across the attribute code, all dealing with what to do if the transaction was or wasn't committed. And in that replicated code, an ASSERT() test of an uninitialized variable occurs in several locations: error = xfs_attr_thing(&args); if (!error) { error = xfs_bmap_finish(&args.trans, args.flist, &committed); } if (error) { ASSERT(committed); If the first xfs_attr_thing() failed, we'd skip the xfs_bmap_finish, never set "committed", and then test it in the ASSERT. Fix this up by moving the committed state internal to xfs_bmap_finish, and add a new inode argument. If an inode is passed in, it is passed through to __xfs_trans_roll() and joined to the transaction there if the transaction was committed. xfs_qm_dqalloc() was a little unique in that it called bjoin rather than ijoin, but as Dave points out we can detect the committed state but checking whether (*tpp != tp). Addresses-Coverity-Id: 102360 Addresses-Coverity-Id: 102361 Addresses-Coverity-Id: 102363 Addresses-Coverity-Id: 102364 Signed-off-by: Eric Sandeen Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_attr.c | 141 ++++++-------------------------- fs/xfs/libxfs/xfs_attr_remote.c | 31 +------ fs/xfs/libxfs/xfs_bmap.c | 6 +- fs/xfs/libxfs/xfs_bmap.h | 2 +- fs/xfs/xfs_bmap_util.c | 43 ++++------ fs/xfs/xfs_dquot.c | 13 +-- fs/xfs/xfs_inode.c | 25 ++---- fs/xfs/xfs_iomap.c | 10 +-- fs/xfs/xfs_rtalloc.c | 3 +- fs/xfs/xfs_symlink.c | 12 +-- 10 files changed, 68 insertions(+), 218 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index f949818fa1c76..fa3b948ef9c25 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -207,7 +207,7 @@ xfs_attr_set( struct xfs_trans_res tres; xfs_fsblock_t firstblock; int rsvd = (flags & ATTR_ROOT) != 0; - int error, err2, committed, local; + int error, err2, local; XFS_STATS_INC(mp, xs_attr_set); @@ -334,24 +334,14 @@ xfs_attr_set( */ xfs_bmap_init(args.flist, args.firstblock); error = xfs_attr_shortform_to_leaf(&args); - if (!error) { - error = xfs_bmap_finish(&args.trans, args.flist, - &committed); - } + if (!error) + error = xfs_bmap_finish(&args.trans, args.flist, dp); if (error) { - ASSERT(committed); args.trans = NULL; xfs_bmap_cancel(&flist); goto out; } - /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args.trans, dp, 0); - /* * Commit the leaf transformation. We'll need another (linked) * transaction to add the new attribute to the leaf. @@ -568,7 +558,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) { xfs_inode_t *dp; struct xfs_buf *bp; - int retval, error, committed, forkoff; + int retval, error, forkoff; trace_xfs_attr_leaf_addname(args); @@ -628,24 +618,14 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) */ xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr3_leaf_to_node(args); - if (!error) { - error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } + if (!error) + error = xfs_bmap_finish(&args->trans, args->flist, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return error; } - /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); - /* * Commit the current trans (including the inode) and start * a new one. @@ -729,25 +709,14 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ - if (!error) { + if (!error) error = xfs_bmap_finish(&args->trans, - args->flist, - &committed); - } + args->flist, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return error; } - - /* - * bmap_finish() may have committed the last trans - * and started a new one. We need the inode to be - * in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); } /* @@ -775,7 +744,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) { xfs_inode_t *dp; struct xfs_buf *bp; - int error, committed, forkoff; + int error, forkoff; trace_xfs_attr_leaf_removename(args); @@ -803,23 +772,13 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ - if (!error) { - error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } + if (!error) + error = xfs_bmap_finish(&args->trans, args->flist, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return error; } - - /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); } return 0; } @@ -877,7 +836,7 @@ xfs_attr_node_addname(xfs_da_args_t *args) xfs_da_state_blk_t *blk; xfs_inode_t *dp; xfs_mount_t *mp; - int committed, retval, error; + int retval, error; trace_xfs_attr_node_addname(args); @@ -938,26 +897,15 @@ restart: state = NULL; xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr3_leaf_to_node(args); - if (!error) { + if (!error) error = xfs_bmap_finish(&args->trans, - args->flist, - &committed); - } + args->flist, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } - /* - * bmap_finish() may have committed the last trans - * and started a new one. We need the inode to be - * in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); - /* * Commit the node conversion and start the next * trans in the chain. @@ -977,23 +925,13 @@ restart: */ xfs_bmap_init(args->flist, args->firstblock); error = xfs_da3_split(state); - if (!error) { - error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } + if (!error) + error = xfs_bmap_finish(&args->trans, args->flist, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } - - /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); } else { /* * Addition succeeded, update Btree hashvals. @@ -1086,25 +1024,14 @@ restart: if (retval && (state->path.active > 1)) { xfs_bmap_init(args->flist, args->firstblock); error = xfs_da3_join(state); - if (!error) { + if (!error) error = xfs_bmap_finish(&args->trans, - args->flist, - &committed); - } + args->flist, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } - - /* - * bmap_finish() may have committed the last trans - * and started a new one. We need the inode to be - * in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); } /* @@ -1146,7 +1073,7 @@ xfs_attr_node_removename(xfs_da_args_t *args) xfs_da_state_blk_t *blk; xfs_inode_t *dp; struct xfs_buf *bp; - int retval, error, committed, forkoff; + int retval, error, forkoff; trace_xfs_attr_node_removename(args); @@ -1220,24 +1147,13 @@ xfs_attr_node_removename(xfs_da_args_t *args) if (retval && (state->path.active > 1)) { xfs_bmap_init(args->flist, args->firstblock); error = xfs_da3_join(state); - if (!error) { - error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } + if (!error) + error = xfs_bmap_finish(&args->trans, args->flist, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } - - /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); - /* * Commit the Btree join operation and start a new trans. */ @@ -1265,25 +1181,14 @@ xfs_attr_node_removename(xfs_da_args_t *args) xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ - if (!error) { + if (!error) error = xfs_bmap_finish(&args->trans, - args->flist, - &committed); - } + args->flist, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } - - /* - * bmap_finish() may have committed the last trans - * and started a new one. We need the inode to be - * in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); } else xfs_trans_brelse(args->trans, bp); } diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index f3ed9bf0b0655..a572532a55cdc 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -448,8 +448,6 @@ xfs_attr_rmtval_set( * Roll through the "value", allocating blocks on disk as required. */ while (blkcnt > 0) { - int committed; - /* * Allocate a single extent, up to the size of the value. * @@ -467,24 +465,14 @@ xfs_attr_rmtval_set( error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno, blkcnt, XFS_BMAPI_ATTRFORK, args->firstblock, args->total, &map, &nmap, args->flist); - if (!error) { - error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } + if (!error) + error = xfs_bmap_finish(&args->trans, args->flist, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return error; } - /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); - ASSERT(nmap == 1); ASSERT((map.br_startblock != DELAYSTARTBLOCK) && (map.br_startblock != HOLESTARTBLOCK)); @@ -615,30 +603,19 @@ xfs_attr_rmtval_remove( blkcnt = args->rmtblkcnt; done = 0; while (!done) { - int committed; - xfs_bmap_init(args->flist, args->firstblock); error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, XFS_BMAPI_ATTRFORK, 1, args->firstblock, args->flist, &done); - if (!error) { + if (!error) error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } + args->dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return error; } - /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, args->dp, 0); - /* * Close out trans and start the next one in the chain. */ diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index bc7e7d5b8c975..ef00156f4f961 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1117,7 +1117,6 @@ xfs_bmap_add_attrfork( xfs_trans_t *tp; /* transaction pointer */ int blks; /* space reservation */ int version = 1; /* superblock attr version */ - int committed; /* xaction was committed */ int logflags; /* logging flags */ int error; /* error return value */ @@ -1220,7 +1219,7 @@ xfs_bmap_add_attrfork( xfs_log_sb(tp); } - error = xfs_bmap_finish(&tp, &flist, &committed); + error = xfs_bmap_finish(&tp, &flist, NULL); if (error) goto bmap_cancel; error = xfs_trans_commit(tp); @@ -5957,7 +5956,6 @@ xfs_bmap_split_extent( struct xfs_trans *tp; struct xfs_bmap_free free_list; xfs_fsblock_t firstfsb; - int committed; int error; tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); @@ -5978,7 +5976,7 @@ xfs_bmap_split_extent( if (error) goto out; - error = xfs_bmap_finish(&tp, &free_list, &committed); + error = xfs_bmap_finish(&tp, &free_list, NULL); if (error) goto out; diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index a160f8a5a3fcd..423a34e832bdc 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -195,7 +195,7 @@ void xfs_bmap_add_free(xfs_fsblock_t bno, xfs_filblks_t len, struct xfs_bmap_free *flist, struct xfs_mount *mp); void xfs_bmap_cancel(struct xfs_bmap_free *flist); int xfs_bmap_finish(struct xfs_trans **tp, struct xfs_bmap_free *flist, - int *committed); + struct xfs_inode *ip); void xfs_bmap_compute_maxlevels(struct xfs_mount *mp, int whichfork); int xfs_bmap_first_unused(struct xfs_trans *tp, struct xfs_inode *ip, xfs_extlen_t len, xfs_fileoff_t *unused, int whichfork); diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index dbae6490a79a5..45ec9e40150c3 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -91,32 +91,32 @@ xfs_zero_extent( * last due to locking considerations. We never free any extents in * the first transaction. * - * Return 1 if the given transaction was committed and a new one - * started, and 0 otherwise in the committed parameter. + * If an inode *ip is provided, rejoin it to the transaction if + * the transaction was committed. */ int /* error */ xfs_bmap_finish( struct xfs_trans **tp, /* transaction pointer addr */ struct xfs_bmap_free *flist, /* i/o: list extents to free */ - int *committed)/* xact committed or not */ + struct xfs_inode *ip) { struct xfs_efd_log_item *efd; /* extent free data */ struct xfs_efi_log_item *efi; /* extent free intention */ int error; /* error return value */ + int committed;/* xact committed or not */ struct xfs_bmap_free_item *free; /* free extent item */ struct xfs_bmap_free_item *next; /* next item on free list */ ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); - if (flist->xbf_count == 0) { - *committed = 0; + if (flist->xbf_count == 0) return 0; - } + efi = xfs_trans_get_efi(*tp, flist->xbf_count); for (free = flist->xbf_first; free; free = free->xbfi_next) xfs_trans_log_efi_extent(*tp, efi, free->xbfi_startblock, free->xbfi_blockcount); - error = __xfs_trans_roll(tp, NULL, committed); + error = __xfs_trans_roll(tp, ip, &committed); if (error) { /* * If the transaction was committed, drop the EFD reference @@ -128,16 +128,13 @@ xfs_bmap_finish( * transaction so we should return committed=1 even though we're * returning an error. */ - if (*committed) { + if (committed) { xfs_efi_release(efi); xfs_force_shutdown((*tp)->t_mountp, (error == -EFSCORRUPTED) ? SHUTDOWN_CORRUPT_INCORE : SHUTDOWN_META_IO_ERROR); - } else { - *committed = 1; } - return error; } @@ -969,7 +966,6 @@ xfs_alloc_file_space( xfs_bmbt_irec_t imaps[1], *imapp; xfs_bmap_free_t free_list; uint qblocks, resblks, resrtextents; - int committed; int error; trace_xfs_alloc_file_space(ip); @@ -1064,23 +1060,20 @@ xfs_alloc_file_space( error = xfs_bmapi_write(tp, ip, startoffset_fsb, allocatesize_fsb, alloc_type, &firstfsb, resblks, imapp, &nimaps, &free_list); - if (error) { + if (error) goto error0; - } /* * Complete the transaction */ - error = xfs_bmap_finish(&tp, &free_list, &committed); - if (error) { + error = xfs_bmap_finish(&tp, &free_list, NULL); + if (error) goto error0; - } error = xfs_trans_commit(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); - if (error) { + if (error) break; - } allocated_fsb = imapp->br_blockcount; @@ -1206,7 +1199,6 @@ xfs_free_file_space( xfs_off_t offset, xfs_off_t len) { - int committed; int done; xfs_fileoff_t endoffset_fsb; int error; @@ -1346,17 +1338,15 @@ xfs_free_file_space( error = xfs_bunmapi(tp, ip, startoffset_fsb, endoffset_fsb - startoffset_fsb, 0, 2, &firstfsb, &free_list, &done); - if (error) { + if (error) goto error0; - } /* * complete the transaction */ - error = xfs_bmap_finish(&tp, &free_list, &committed); - if (error) { + error = xfs_bmap_finish(&tp, &free_list, NULL); + if (error) goto error0; - } error = xfs_trans_commit(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); @@ -1434,7 +1424,6 @@ xfs_shift_file_space( int error; struct xfs_bmap_free free_list; xfs_fsblock_t first_block; - int committed; xfs_fileoff_t stop_fsb; xfs_fileoff_t next_fsb; xfs_fileoff_t shift_fsb; @@ -1526,7 +1515,7 @@ xfs_shift_file_space( if (error) goto out_bmap_cancel; - error = xfs_bmap_finish(&tp, &free_list, &committed); + error = xfs_bmap_finish(&tp, &free_list, NULL); if (error) goto out_bmap_cancel; diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 7ac6c5c586cba..9c44d38dcd1f8 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -306,7 +306,7 @@ xfs_qm_dqalloc( xfs_fsblock_t firstblock; xfs_bmap_free_t flist; xfs_bmbt_irec_t map; - int nmaps, error, committed; + int nmaps, error; xfs_buf_t *bp; xfs_trans_t *tp = *tpp; @@ -379,11 +379,12 @@ xfs_qm_dqalloc( xfs_trans_bhold(tp, bp); - if ((error = xfs_bmap_finish(tpp, &flist, &committed))) { + error = xfs_bmap_finish(tpp, &flist, NULL); + if (error) goto error1; - } - if (committed) { + /* Transaction was committed? */ + if (*tpp != tp) { tp = *tpp; xfs_trans_bjoin(tp, bp); } else { @@ -393,9 +394,9 @@ xfs_qm_dqalloc( *O_bpp = bp; return 0; - error1: +error1: xfs_bmap_cancel(&flist); - error0: +error0: xfs_iunlock(quotip, XFS_ILOCK_EXCL); return error; diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 8ee393996b7d6..ae3758a90ed63 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1143,7 +1143,6 @@ xfs_create( xfs_bmap_free_t free_list; xfs_fsblock_t first_block; bool unlock_dp_on_error = false; - int committed; prid_t prid; struct xfs_dquot *udqp = NULL; struct xfs_dquot *gdqp = NULL; @@ -1226,7 +1225,7 @@ xfs_create( * pointing to itself. */ error = xfs_dir_ialloc(&tp, dp, mode, is_dir ? 2 : 1, rdev, - prid, resblks > 0, &ip, &committed); + prid, resblks > 0, &ip, NULL); if (error) goto out_trans_cancel; @@ -1275,7 +1274,7 @@ xfs_create( */ xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp); - error = xfs_bmap_finish(&tp, &free_list, &committed); + error = xfs_bmap_finish(&tp, &free_list, NULL); if (error) goto out_bmap_cancel; @@ -1427,7 +1426,6 @@ xfs_link( int error; xfs_bmap_free_t free_list; xfs_fsblock_t first_block; - int committed; int resblks; trace_xfs_link(tdp, target_name); @@ -1502,11 +1500,10 @@ xfs_link( * link transaction goes to disk before returning to * the user. */ - if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) { + if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) xfs_trans_set_sync(tp); - } - error = xfs_bmap_finish (&tp, &free_list, &committed); + error = xfs_bmap_finish(&tp, &free_list, NULL); if (error) { xfs_bmap_cancel(&free_list); goto error_return; @@ -1555,7 +1552,6 @@ xfs_itruncate_extents( xfs_fileoff_t first_unmap_block; xfs_fileoff_t last_block; xfs_filblks_t unmap_len; - int committed; int error = 0; int done = 0; @@ -1601,9 +1597,7 @@ xfs_itruncate_extents( * Duplicate the transaction that has the permanent * reservation and commit the old transaction. */ - error = xfs_bmap_finish(&tp, &free_list, &committed); - if (committed) - xfs_trans_ijoin(tp, ip, 0); + error = xfs_bmap_finish(&tp, &free_list, ip); if (error) goto out_bmap_cancel; @@ -1774,7 +1768,6 @@ xfs_inactive_ifree( { xfs_bmap_free_t free_list; xfs_fsblock_t first_block; - int committed; struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp; int error; @@ -1841,7 +1834,7 @@ xfs_inactive_ifree( * Just ignore errors at this point. There is nothing we can do except * to try to keep going. Make sure it's not a silent error. */ - error = xfs_bmap_finish(&tp, &free_list, &committed); + error = xfs_bmap_finish(&tp, &free_list, NULL); if (error) { xfs_notice(mp, "%s: xfs_bmap_finish returned error %d", __func__, error); @@ -2523,7 +2516,6 @@ xfs_remove( int error = 0; xfs_bmap_free_t free_list; xfs_fsblock_t first_block; - int committed; uint resblks; trace_xfs_remove(dp, name); @@ -2624,7 +2616,7 @@ xfs_remove( if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) xfs_trans_set_sync(tp); - error = xfs_bmap_finish(&tp, &free_list, &committed); + error = xfs_bmap_finish(&tp, &free_list, NULL); if (error) goto out_bmap_cancel; @@ -2701,7 +2693,6 @@ xfs_finish_rename( struct xfs_trans *tp, struct xfs_bmap_free *free_list) { - int committed = 0; int error; /* @@ -2711,7 +2702,7 @@ xfs_finish_rename( if (tp->t_mountp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) xfs_trans_set_sync(tp); - error = xfs_bmap_finish(&tp, free_list, &committed); + error = xfs_bmap_finish(&tp, free_list, NULL); if (error) { xfs_bmap_cancel(free_list); xfs_trans_cancel(tp); diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index f4f5b43cf6471..ffc7baf64cab3 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -129,7 +129,6 @@ xfs_iomap_write_direct( xfs_trans_t *tp; xfs_bmap_free_t free_list; uint qblocks, resblks, resrtextents; - int committed; int error; int lockmode; int bmapi_flags = XFS_BMAPI_PREALLOC; @@ -247,7 +246,7 @@ xfs_iomap_write_direct( /* * Complete the transaction */ - error = xfs_bmap_finish(&tp, &free_list, &committed); + error = xfs_bmap_finish(&tp, &free_list, NULL); if (error) goto out_bmap_cancel; @@ -693,7 +692,7 @@ xfs_iomap_write_allocate( xfs_bmap_free_t free_list; xfs_filblks_t count_fsb; xfs_trans_t *tp; - int nimaps, committed; + int nimaps; int error = 0; int nres; @@ -794,7 +793,7 @@ xfs_iomap_write_allocate( if (error) goto trans_cancel; - error = xfs_bmap_finish(&tp, &free_list, &committed); + error = xfs_bmap_finish(&tp, &free_list, NULL); if (error) goto trans_cancel; @@ -852,7 +851,6 @@ xfs_iomap_write_unwritten( xfs_bmap_free_t free_list; xfs_fsize_t i_size; uint resblks; - int committed; int error; trace_xfs_unwritten_convert(ip, offset, count); @@ -924,7 +922,7 @@ xfs_iomap_write_unwritten( xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); } - error = xfs_bmap_finish(&tp, &free_list, &committed); + error = xfs_bmap_finish(&tp, &free_list, NULL); if (error) goto error_on_bmapi_transaction; diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index ab1bac6a3a1c0..be02a68b2fe29 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -766,7 +766,6 @@ xfs_growfs_rt_alloc( { xfs_fileoff_t bno; /* block number in file */ struct xfs_buf *bp; /* temporary buffer for zeroing */ - int committed; /* transaction committed flag */ xfs_daddr_t d; /* disk block address */ int error; /* error return value */ xfs_fsblock_t firstblock;/* first block allocated in xaction */ @@ -811,7 +810,7 @@ xfs_growfs_rt_alloc( /* * Free any blocks freed up in the transaction, then commit. */ - error = xfs_bmap_finish(&tp, &flist, &committed); + error = xfs_bmap_finish(&tp, &flist, NULL); if (error) goto out_bmap_cancel; error = xfs_trans_commit(tp); diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 996481eeb4913..b44284c1adda1 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -178,7 +178,6 @@ xfs_symlink( struct xfs_bmap_free free_list; xfs_fsblock_t first_block; bool unlock_dp_on_error = false; - int committed; xfs_fileoff_t first_fsb; xfs_filblks_t fs_blocks; int nmaps; @@ -387,7 +386,7 @@ xfs_symlink( xfs_trans_set_sync(tp); } - error = xfs_bmap_finish(&tp, &free_list, &committed); + error = xfs_bmap_finish(&tp, &free_list, NULL); if (error) goto out_bmap_cancel; @@ -434,7 +433,6 @@ xfs_inactive_symlink_rmt( struct xfs_inode *ip) { xfs_buf_t *bp; - int committed; int done; int error; xfs_fsblock_t first_block; @@ -510,15 +508,9 @@ xfs_inactive_symlink_rmt( /* * Commit the first transaction. This logs the EFI and the inode. */ - error = xfs_bmap_finish(&tp, &free_list, &committed); + error = xfs_bmap_finish(&tp, &free_list, ip); if (error) goto error_bmap_cancel; - /* - * The transaction must have been committed, since there were - * actually extents freed by xfs_bunmapi. See xfs_bmap_finish. - * The new tp has the extent freeing and EFDs. - */ - ASSERT(committed); /* * The first xact was committed, so add the inode to the new one. * Mark it dirty so it will be logged and moved forward in the log as -- GitLab From 35de3b1aa16842214e0cd7c6036daf4619294314 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 8 Dec 2015 13:50:56 -0500 Subject: [PATCH 2395/2855] powerpc: Implement save_stack_trace_regs() to enable kprobe stack tracing It has come to my attention that kprobe event stack tracing does not work on powerpc. You can see with the following: # cd /sys/kernel/debug/tracing # echo stacktrace > trace_options # echo 'p kfree' > kprobe_events # echo 1 > events/kprobes/enable Will print the following warning: save_stack_trace_regs() not implemented yet. Although save_stack_trace() (which normal event stack traces use) is implemented, save_stack_trace_regs() which kprobe events use is not. This is a cheap attempt to implement that function. Note, This may have issues if a task tries to get a stack trace from another task with its regs, because it just passes in "current" to save_context_stack(). But this does solve the issue with stack tracing kprobe events. Reported-by: Chunyu Hu Signed-off-by: Steven Rostedt Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/stacktrace.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c index ea43a347a1044..4f24606afc3f5 100644 --- a/arch/powerpc/kernel/stacktrace.c +++ b/arch/powerpc/kernel/stacktrace.c @@ -61,3 +61,10 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) save_context_stack(trace, tsk->thread.ksp, tsk, 0); } EXPORT_SYMBOL_GPL(save_stack_trace_tsk); + +void +save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) +{ + save_context_stack(trace, regs->gpr[1], current, 0); +} +EXPORT_SYMBOL_GPL(save_stack_trace_regs); -- GitLab From b0eab5b29a55fd9f31fad28df520337545c813ef Mon Sep 17 00:00:00 2001 From: Russell Currey Date: Fri, 8 Jan 2016 16:16:47 +1100 Subject: [PATCH 2396/2855] powerpc/powernv: Remove misleading comment in pci.c PCI in powernv now supports quite a bit more than p5ioc2, so remove the outdated comment. Signed-off-by: Russell Currey Acked-by: Stewart Smith Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index ff4e42d9d2599..2f55c86df7035 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -1,8 +1,6 @@ /* * Support PCI/PCIe on PowerNV platforms * - * Currently supports only P5IOC2 - * * Copyright 2011 Benjamin Herrenschmidt, IBM Corp. * * This program is free software; you can redistribute it and/or -- GitLab From 86c68e2fb3eeb87ef716a0d61c5a346e9aee2ecb Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 23 Nov 2015 14:44:13 +0100 Subject: [PATCH 2397/2855] backlight: adp88x0: Fix uninitialized variable use gcc correctly warns about both the adp8860 and adp8870 backlight drivers using an uninitialized variable in their error handling path: drivers/video/backlight/adp8870_bl.c: In function 'adp8870_bl_ambient_light_zone_store': drivers/video/backlight/adp8870_bl.c:811:11: warning: 'reg_val' may be used uninitialized in this function This changes the code to only write back the data if it was correctly read to start with. As a side-note, the drivers are mostly identical, so I think they should really be merged into one file to avoid having to fix every bug twice. Signed-off-by: Arnd Bergmann Acked-by: Michael Hennerich Signed-off-by: Lee Jones --- drivers/video/backlight/adp8860_bl.c | 10 ++++++---- drivers/video/backlight/adp8870_bl.c | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c index 98ffe71e8af2d..f0d4c0324580a 100644 --- a/drivers/video/backlight/adp8860_bl.c +++ b/drivers/video/backlight/adp8860_bl.c @@ -621,10 +621,12 @@ static ssize_t adp8860_bl_ambient_light_zone_store(struct device *dev, /* Set user supplied ambient light zone */ mutex_lock(&data->lock); - adp8860_read(data->client, ADP8860_CFGR, ®_val); - reg_val &= ~(CFGR_BLV_MASK << CFGR_BLV_SHIFT); - reg_val |= (val - 1) << CFGR_BLV_SHIFT; - adp8860_write(data->client, ADP8860_CFGR, reg_val); + ret = adp8860_read(data->client, ADP8860_CFGR, ®_val); + if (!ret) { + reg_val &= ~(CFGR_BLV_MASK << CFGR_BLV_SHIFT); + reg_val |= (val - 1) << CFGR_BLV_SHIFT; + adp8860_write(data->client, ADP8860_CFGR, reg_val); + } mutex_unlock(&data->lock); } diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c index 9d738352d7d4b..21acac90fd773 100644 --- a/drivers/video/backlight/adp8870_bl.c +++ b/drivers/video/backlight/adp8870_bl.c @@ -807,10 +807,12 @@ static ssize_t adp8870_bl_ambient_light_zone_store(struct device *dev, /* Set user supplied ambient light zone */ mutex_lock(&data->lock); - adp8870_read(data->client, ADP8870_CFGR, ®_val); - reg_val &= ~(CFGR_BLV_MASK << CFGR_BLV_SHIFT); - reg_val |= (val - 1) << CFGR_BLV_SHIFT; - adp8870_write(data->client, ADP8870_CFGR, reg_val); + ret = adp8870_read(data->client, ADP8870_CFGR, ®_val); + if (!ret) { + reg_val &= ~(CFGR_BLV_MASK << CFGR_BLV_SHIFT); + reg_val |= (val - 1) << CFGR_BLV_SHIFT; + adp8870_write(data->client, ADP8870_CFGR, reg_val); + } mutex_unlock(&data->lock); } -- GitLab From 3698d7e7d221a5c90d4b55e96d0c8f98a8b4d7df Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 18 Nov 2015 18:12:25 +0100 Subject: [PATCH 2398/2855] backlight: pwm_bl: Avoid backlight flicker when probed from DT If the driver is probed from the device tree, and there is a phandle property set on it, and the enable GPIO is already configured as output, and the backlight is currently disabled, keep it disabled. If all these conditions are met, assume there will be some other driver that can enable the backlight at the appropriate time. Signed-off-by: Philipp Zabel Reviewed-by: Christian Gmeiner Tested-by: Heiko Stuebner Signed-off-by: Lee Jones --- drivers/video/backlight/pwm_bl.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index ae3c6b6fd5db1..3daf9cc9bc312 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -199,6 +199,8 @@ static int pwm_backlight_probe(struct platform_device *pdev) struct backlight_properties props; struct backlight_device *bl; struct pwm_bl_data *pb; + phandle phandle = pdev->dev.of_node->phandle; + int initial_blank = FB_BLANK_UNBLANK; int ret; if (!data) { @@ -242,7 +244,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->enabled = false; pb->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable", - GPIOD_OUT_HIGH); + GPIOD_ASIS); if (IS_ERR(pb->enable_gpio)) { ret = PTR_ERR(pb->enable_gpio); goto err_alloc; @@ -264,12 +266,30 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->enable_gpio = gpio_to_desc(data->enable_gpio); } + if (pb->enable_gpio) { + /* + * If the driver is probed from the device tree and there is a + * phandle link pointing to the backlight node, it is safe to + * assume that another driver will enable the backlight at the + * appropriate time. Therefore, if it is disabled, keep it so. + */ + if (phandle && + gpiod_get_direction(pb->enable_gpio) == GPIOF_DIR_OUT && + gpiod_get_value(pb->enable_gpio) == 0) + initial_blank = FB_BLANK_POWERDOWN; + else + gpiod_direction_output(pb->enable_gpio, 1); + } + pb->power_supply = devm_regulator_get(&pdev->dev, "power"); if (IS_ERR(pb->power_supply)) { ret = PTR_ERR(pb->power_supply); goto err_alloc; } + if (phandle && !regulator_is_enabled(pb->power_supply)) + initial_blank = FB_BLANK_POWERDOWN; + pb->pwm = devm_pwm_get(&pdev->dev, NULL); if (IS_ERR(pb->pwm) && PTR_ERR(pb->pwm) != -EPROBE_DEFER && !pdev->dev.of_node) { @@ -320,6 +340,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) } bl->props.brightness = data->dft_brightness; + bl->props.power = initial_blank; backlight_update_status(bl); platform_set_drvdata(pdev, bl); -- GitLab From 6d6e44a953161e4ce60d1fe805d165d8290ce9e8 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Wed, 25 Nov 2015 13:51:07 +0800 Subject: [PATCH 2399/2855] mfd: cros ec: Lock the SPI bus while holding chipselect cros_ec_cmd_xfer_spi and cros_ec_pkt_xfer_spi generally work like this: - Pull CS down (active), wait a bit, then send a command - Wait for response (multiple requests) - Wait a while, pull CS up (inactive) These operations, individually, lock the SPI bus, but there is nothing preventing the SPI framework from interleaving messages intended for other devices as the bus is unlocked in between. This is a problem as the EC expects CS to be held low for the whole duration. Solution: Lock the SPI bus during the whole transaction, to make sure that no other messages can be interleaved. Signed-off-by: Nicolas Boichat Reviewed-by: Gwendal Grignou Signed-off-by: Lee Jones --- drivers/mfd/cros_ec_spi.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/mfd/cros_ec_spi.c b/drivers/mfd/cros_ec_spi.c index 6a0f6ec67c6be..d6af52d18c069 100644 --- a/drivers/mfd/cros_ec_spi.c +++ b/drivers/mfd/cros_ec_spi.c @@ -113,7 +113,7 @@ static int terminate_request(struct cros_ec_device *ec_dev) trans.delay_usecs = ec_spi->end_of_msg_delay; spi_message_add_tail(&trans, &msg); - ret = spi_sync(ec_spi->spi, &msg); + ret = spi_sync_locked(ec_spi->spi, &msg); /* Reset end-of-response timer */ ec_spi->last_transfer_ns = ktime_get_ns(); @@ -147,7 +147,7 @@ static int receive_n_bytes(struct cros_ec_device *ec_dev, u8 *buf, int n) spi_message_init(&msg); spi_message_add_tail(&trans, &msg); - ret = spi_sync(ec_spi->spi, &msg); + ret = spi_sync_locked(ec_spi->spi, &msg); if (ret < 0) dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); @@ -391,10 +391,10 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev, } rx_buf = kzalloc(len, GFP_KERNEL); - if (!rx_buf) { - ret = -ENOMEM; - goto exit; - } + if (!rx_buf) + return -ENOMEM; + + spi_bus_lock(ec_spi->spi->master); /* * Leave a gap between CS assertion and clocking of data to allow the @@ -414,7 +414,7 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev, trans.len = len; trans.cs_change = 1; spi_message_add_tail(&trans, &msg); - ret = spi_sync(ec_spi->spi, &msg); + ret = spi_sync_locked(ec_spi->spi, &msg); /* Get the response */ if (!ret) { @@ -440,6 +440,9 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev, } final_ret = terminate_request(ec_dev); + + spi_bus_unlock(ec_spi->spi->master); + if (!ret) ret = final_ret; if (ret < 0) @@ -520,10 +523,10 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev, } rx_buf = kzalloc(len, GFP_KERNEL); - if (!rx_buf) { - ret = -ENOMEM; - goto exit; - } + if (!rx_buf) + return -ENOMEM; + + spi_bus_lock(ec_spi->spi->master); /* Transmit phase - send our message */ debug_packet(ec_dev->dev, "out", ec_dev->dout, len); @@ -534,7 +537,7 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev, trans.cs_change = 1; spi_message_init(&msg); spi_message_add_tail(&trans, &msg); - ret = spi_sync(ec_spi->spi, &msg); + ret = spi_sync_locked(ec_spi->spi, &msg); /* Get the response */ if (!ret) { @@ -560,6 +563,9 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev, } final_ret = terminate_request(ec_dev); + + spi_bus_unlock(ec_spi->spi->master); + if (!ret) ret = final_ret; if (ret < 0) -- GitLab From 32e9725d9a87549eb8b2a6455de0bce9dc8385de Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 26 Nov 2015 17:40:17 +0000 Subject: [PATCH 2400/2855] mfd: wm5110: Correct defaults for micbias control registers Signed-off-by: Charles Keepax Signed-off-by: Lee Jones --- drivers/mfd/wm5110-tables.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c index 2bb2d0467a92d..c18e11f42b3f1 100644 --- a/drivers/mfd/wm5110-tables.c +++ b/drivers/mfd/wm5110-tables.c @@ -762,9 +762,9 @@ static const struct reg_default wm5110_reg_default[] = { { 0x00000200, 0x0006 }, /* R512 - Mic Charge Pump 1 */ { 0x00000210, 0x0184 }, /* R528 - LDO1 Control 1 */ { 0x00000213, 0x03E4 }, /* R531 - LDO2 Control 1 */ - { 0x00000218, 0x01A6 }, /* R536 - Mic Bias Ctrl 1 */ - { 0x00000219, 0x01A6 }, /* R537 - Mic Bias Ctrl 2 */ - { 0x0000021A, 0x01A6 }, /* R538 - Mic Bias Ctrl 3 */ + { 0x00000218, 0x00E6 }, /* R536 - Mic Bias Ctrl 1 */ + { 0x00000219, 0x00E6 }, /* R537 - Mic Bias Ctrl 2 */ + { 0x0000021A, 0x00E6 }, /* R538 - Mic Bias Ctrl 3 */ { 0x00000293, 0x0000 }, /* R659 - Accessory Detect Mode 1 */ { 0x0000029B, 0x0028 }, /* R667 - Headphone Detect 1 */ { 0x000002A2, 0x0000 }, /* R674 - Micd clamp control */ -- GitLab From db2fb60cd35d2d03699e570906ced73b4c05586e Mon Sep 17 00:00:00 2001 From: Damien Riegel Date: Mon, 30 Nov 2015 10:59:47 -0500 Subject: [PATCH 2401/2855] mfd: syscon: Add a DT property to set value width Currently syscon has a fixed configuration of 32 bits for register and values widths. In some cases, it would be desirable to be able to customize the value width. For example, certain boards (like the ones manufactured by Technologic Systems) have a FPGA that is memory-mapped, but its registers are only 16-bit wide. This patch adds an optional "reg-io-width" DT binding for syscon that allows to change the width for the data bus (i.e. val_bits). If this property is provided, it will also set the register stride to reg-io-width's value. If not provided, the default configuration is used. Signed-off-by: Damien Riegel Acked-by: Rob Herring Acked-by: Arnd Bergmann Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/syscon.txt | 4 ++++ drivers/mfd/syscon.c | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/Documentation/devicetree/bindings/mfd/syscon.txt b/Documentation/devicetree/bindings/mfd/syscon.txt index fe8150bb3248e..408f768686f1e 100644 --- a/Documentation/devicetree/bindings/mfd/syscon.txt +++ b/Documentation/devicetree/bindings/mfd/syscon.txt @@ -13,6 +13,10 @@ Required properties: - compatible: Should contain "syscon". - reg: the register region can be accessed from syscon +Optional property: +- reg-io-width: the size (in bytes) of the IO accesses that should be + performed on the device. + Examples: gpr: iomuxc-gpr@020e0000 { compatible = "fsl,imx6q-iomuxc-gpr", "syscon"; diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index 176bf0fa2685e..b7aabeefab07a 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -47,6 +47,7 @@ static struct syscon *of_syscon_register(struct device_node *np) struct syscon *syscon; struct regmap *regmap; void __iomem *base; + u32 reg_io_width; int ret; struct regmap_config syscon_config = syscon_regmap_config; @@ -69,6 +70,18 @@ static struct syscon *of_syscon_register(struct device_node *np) else if (of_property_read_bool(np, "little-endian")) syscon_config.val_format_endian = REGMAP_ENDIAN_LITTLE; + /* + * search for reg-io-width property in DT. If it is not provided, + * default to 4 bytes. regmap_init_mmio will return an error if values + * are invalid so there is no need to check them here. + */ + ret = of_property_read_u32(np, "reg-io-width", ®_io_width); + if (ret) + reg_io_width = 4; + + syscon_config.reg_stride = reg_io_width; + syscon_config.val_bits = reg_io_width * 8; + regmap = regmap_init_mmio(NULL, base, &syscon_config); if (IS_ERR(regmap)) { pr_err("regmap init failed\n"); -- GitLab From a5656a708050bd3be5c3a3bc45297db21e88cecd Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Sun, 6 Dec 2015 00:39:39 +0100 Subject: [PATCH 2402/2855] mfd: wm831x: Fix broken wm831x_unique_id_show wm831x_unique_id_show currently displays an interesting pattern of '0' and '3' characters which isn't very useful (figuring out why is left as an exercise for the reader). Presumably "buf[i]" should have been "id[i] & 0xff". But while there, it is much simpler to simply use %phN and do all the formatting at once. Signed-off-by: Rasmus Villemoes Acked-by: Charles Keepax Signed-off-by: Lee Jones --- drivers/mfd/wm831x-otp.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/mfd/wm831x-otp.c b/drivers/mfd/wm831x-otp.c index b90f3e06b6c95..ebac0027f8e01 100644 --- a/drivers/mfd/wm831x-otp.c +++ b/drivers/mfd/wm831x-otp.c @@ -47,20 +47,14 @@ static ssize_t wm831x_unique_id_show(struct device *dev, struct device_attribute *attr, char *buf) { struct wm831x *wm831x = dev_get_drvdata(dev); - int i, rval; + int rval; char id[WM831X_UNIQUE_ID_LEN]; - ssize_t ret = 0; rval = wm831x_unique_id_read(wm831x, id); if (rval < 0) return 0; - for (i = 0; i < WM831X_UNIQUE_ID_LEN; i++) - ret += sprintf(&buf[ret], "%02x", buf[i]); - - ret += sprintf(&buf[ret], "\n"); - - return ret; + return sprintf(buf, "%*phN\n", WM831X_UNIQUE_ID_LEN, id); } static DEVICE_ATTR(unique_id, 0444, wm831x_unique_id_show, NULL); -- GitLab From 742dcd115cb523f4b518bfcda870e10a027a8024 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Tue, 17 Nov 2015 16:06:44 -0800 Subject: [PATCH 2403/2855] mfd: qcom-spmi-pmic: Don't access non-existing registers Revision ID registers are available only on devices with Slave IDs that are even, so don't make access to unavailable registers. Signed-off-by: Ivan T. Ivanov [sboyd@codeaurora.org: Consider all slave ids that are even] Signed-off-by: Stephen Boyd Signed-off-by: Lee Jones --- drivers/mfd/qcom-spmi-pmic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/qcom-spmi-pmic.c b/drivers/mfd/qcom-spmi-pmic.c index af6ac1c4b45c6..8653e8b9bb4fc 100644 --- a/drivers/mfd/qcom-spmi-pmic.c +++ b/drivers/mfd/qcom-spmi-pmic.c @@ -127,7 +127,9 @@ static int pmic_spmi_probe(struct spmi_device *sdev) if (IS_ERR(regmap)) return PTR_ERR(regmap); - pmic_spmi_show_revid(regmap, &sdev->dev); + /* Only the first slave id for a PMIC contains this information */ + if (sdev->usid % 2 == 0) + pmic_spmi_show_revid(regmap, &sdev->dev); return of_platform_populate(root, NULL, NULL, &sdev->dev); } -- GitLab From d91d76d84c3adf7ca04ef1932431d49f51edee5e Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 2 Dec 2015 17:28:11 +0100 Subject: [PATCH 2404/2855] mfd: sta2x11: Use platform_register/unregister_drivers() These new helpers simplify implementing multi-driver modules and properly handle failure to register one driver by unregistering all previously registered drivers. Signed-off-by: Thierry Reding Signed-off-by: Lee Jones --- drivers/mfd/sta2x11-mfd.c | 36 ++++++++++-------------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c index b3e5c6f45105f..9292202039ee9 100644 --- a/drivers/mfd/sta2x11-mfd.c +++ b/drivers/mfd/sta2x11-mfd.c @@ -372,12 +372,6 @@ static struct platform_driver sta2x11_sctl_platform_driver = { .probe = sta2x11_sctl_probe, }; -static int __init sta2x11_sctl_init(void) -{ - pr_info("%s\n", __func__); - return platform_driver_register(&sta2x11_sctl_platform_driver); -} - static struct platform_driver sta2x11_platform_driver = { .driver = { .name = STA2X11_MFD_APBREG_NAME, @@ -385,12 +379,6 @@ static struct platform_driver sta2x11_platform_driver = { .probe = sta2x11_apbreg_probe, }; -static int __init sta2x11_apbreg_init(void) -{ - pr_info("%s\n", __func__); - return platform_driver_register(&sta2x11_platform_driver); -} - static struct platform_driver sta2x11_apb_soc_regs_platform_driver = { .driver = { .name = STA2X11_MFD_APB_SOC_REGS_NAME, @@ -398,12 +386,6 @@ static struct platform_driver sta2x11_apb_soc_regs_platform_driver = { .probe = sta2x11_apb_soc_regs_probe, }; -static int __init sta2x11_apb_soc_regs_init(void) -{ - pr_info("%s\n", __func__); - return platform_driver_register(&sta2x11_apb_soc_regs_platform_driver); -} - static struct platform_driver sta2x11_scr_platform_driver = { .driver = { .name = STA2X11_MFD_SCR_NAME, @@ -411,13 +393,18 @@ static struct platform_driver sta2x11_scr_platform_driver = { .probe = sta2x11_scr_probe, }; -static int __init sta2x11_scr_init(void) +static struct platform_driver * const drivers[] = { + &sta2x11_platform_driver, + &sta2x11_sctl_platform_driver, + &sta2x11_apb_soc_regs_platform_driver, + &sta2x11_scr_platform_driver, +}; + +static int __init sta2x11_drivers_init(void) { - pr_info("%s\n", __func__); - return platform_driver_register(&sta2x11_scr_platform_driver); + return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); } - /* * What follows are the PCI devices that host the above pdevs. * Each logic block is 4kB and they are all consecutive: we use this info. @@ -664,10 +651,7 @@ static int __init sta2x11_mfd_init(void) * prepares platform drivers very early and probe the PCI device later, * but before other PCI devices. */ -subsys_initcall(sta2x11_apbreg_init); -subsys_initcall(sta2x11_sctl_init); -subsys_initcall(sta2x11_apb_soc_regs_init); -subsys_initcall(sta2x11_scr_init); +subsys_initcall(sta2x11_drivers_init); rootfs_initcall(sta2x11_mfd_init); MODULE_LICENSE("GPL v2"); -- GitLab From a7b956fd38dd217dd78e3058110929f5ac914df1 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 8 Dec 2015 16:21:05 +0100 Subject: [PATCH 2405/2855] mfd: as3722: Mark PM functions as __maybe_unused The newly introduced as3722_i2c_suspend/resume functions are built unconditionally, but only used when power management is enabled, so we get a warning otherwise: drivers/mfd/as3722.c:427:12: warning: 'as3722_i2c_suspend' defined but not used [-Wunused-function] drivers/mfd/as3722.c:438:12: warning: 'as3722_i2c_resume' defined but not used [-Wunused-function] This marks them both as __maybe_unused, which avoids an ugly #ifdef and gives us best compile-time coverage. When they are unused, the compiler will silently drop the functions from its output. Signed-off-by: Arnd Bergmann Fixes: 35deff7eb212 ("mfd: as3722: Handle interrupts on suspend") Signed-off-by: Lee Jones --- drivers/mfd/as3722.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/as3722.c b/drivers/mfd/as3722.c index 3b21eb4bc480e..e1f597f97f869 100644 --- a/drivers/mfd/as3722.c +++ b/drivers/mfd/as3722.c @@ -424,7 +424,7 @@ static int as3722_i2c_remove(struct i2c_client *i2c) return 0; } -static int as3722_i2c_suspend(struct device *dev) +static int __maybe_unused as3722_i2c_suspend(struct device *dev) { struct as3722 *as3722 = dev_get_drvdata(dev); @@ -435,7 +435,7 @@ static int as3722_i2c_suspend(struct device *dev) return 0; } -static int as3722_i2c_resume(struct device *dev) +static int __maybe_unused as3722_i2c_resume(struct device *dev) { struct as3722 *as3722 = dev_get_drvdata(dev); -- GitLab From fcf13f0b9e4b54c51dff8366fc9a96d85129ff4c Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Sun, 29 Nov 2015 17:29:46 +0100 Subject: [PATCH 2406/2855] backlight: tps65217_bl: Add MODULE_DEVICE_TABLE The device table is required to load modules based on modaliases. Signed-off-by: Enric Balletbo i Serra Signed-off-by: Lee Jones --- drivers/video/backlight/tps65217_bl.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/video/backlight/tps65217_bl.c b/drivers/video/backlight/tps65217_bl.c index 61d72bffd402f..fd524ad860a57 100644 --- a/drivers/video/backlight/tps65217_bl.c +++ b/drivers/video/backlight/tps65217_bl.c @@ -320,10 +320,19 @@ static int tps65217_bl_probe(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF +static const struct of_device_id tps65217_bl_of_match[] = { + { .compatible = "ti,tps65217-bl", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, tps65217_bl_of_match); +#endif + static struct platform_driver tps65217_bl_driver = { .probe = tps65217_bl_probe, .driver = { .name = "tps65217-bl", + .of_match_table = of_match_ptr(tps65217_bl_of_match), }, }; -- GitLab From 8777078015bb77f0561303b6dea23d40bd9f3053 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 10 Dec 2015 10:09:06 +0100 Subject: [PATCH 2407/2855] backlight: pwm_bl: Fix broken PWM backlight for non-dt platforms Commit ee65ad0e2a9e ("backlight: pwm_bl: Avoid backlight flicker when probed from DT") tries to dereference the device of_node pointer unconditionally, causing a NULL pointer dereference on non-dt platforms. Fix it by replacing the phandle variable with a node variable and by checking that for NULL before dereferencing it. Reported-by: Robert Jarzmik Signed-off-by: Philipp Zabel Acked-by: Thierry Reding Tested-by: Robert Jarzmik Signed-off-by: Lee Jones --- drivers/video/backlight/pwm_bl.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 3daf9cc9bc312..a22c1ec29de75 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -198,8 +198,8 @@ static int pwm_backlight_probe(struct platform_device *pdev) struct platform_pwm_backlight_data defdata; struct backlight_properties props; struct backlight_device *bl; + struct device_node *node = pdev->dev.of_node; struct pwm_bl_data *pb; - phandle phandle = pdev->dev.of_node->phandle; int initial_blank = FB_BLANK_UNBLANK; int ret; @@ -273,7 +273,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) * assume that another driver will enable the backlight at the * appropriate time. Therefore, if it is disabled, keep it so. */ - if (phandle && + if (node && node->phandle && gpiod_get_direction(pb->enable_gpio) == GPIOF_DIR_OUT && gpiod_get_value(pb->enable_gpio) == 0) initial_blank = FB_BLANK_POWERDOWN; @@ -287,12 +287,11 @@ static int pwm_backlight_probe(struct platform_device *pdev) goto err_alloc; } - if (phandle && !regulator_is_enabled(pb->power_supply)) + if (node && node->phandle && !regulator_is_enabled(pb->power_supply)) initial_blank = FB_BLANK_POWERDOWN; pb->pwm = devm_pwm_get(&pdev->dev, NULL); - if (IS_ERR(pb->pwm) && PTR_ERR(pb->pwm) != -EPROBE_DEFER - && !pdev->dev.of_node) { + if (IS_ERR(pb->pwm) && PTR_ERR(pb->pwm) != -EPROBE_DEFER && !node) { dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n"); pb->legacy = true; pb->pwm = pwm_request(data->pwm_id, "pwm-backlight"); -- GitLab From 7d07d15abb606f6e0c611e9bc9a2de4745456e5f Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Tue, 3 Nov 2015 15:08:34 +0000 Subject: [PATCH 2408/2855] gpio: arizona: Support Cirrus Logic CS47L24 and WM1831 The CS47L24 and WM1831 codecs only have two GPIO lines, but are otherwise similar to the WM8280. Signed-off-by: Richard Fitzgerald Acked-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/gpio/gpio-arizona.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpio/gpio-arizona.c b/drivers/gpio/gpio-arizona.c index ca002739616af..624ea5421995d 100644 --- a/drivers/gpio/gpio-arizona.c +++ b/drivers/gpio/gpio-arizona.c @@ -122,6 +122,10 @@ static int arizona_gpio_probe(struct platform_device *pdev) case WM1814: arizona_gpio->gpio_chip.ngpio = 5; break; + case WM1831: + case CS47L24: + arizona_gpio->gpio_chip.ngpio = 2; + break; default: dev_err(&pdev->dev, "Unknown chip variant %d\n", arizona->type); -- GitLab From 6c006b1b17f8841d83f09b2bc34227e2f9428872 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 16 Dec 2015 13:53:59 +0000 Subject: [PATCH 2409/2855] mfd: arizona: Request parent IRQ before we request child IRQs Currently the driver requests the boot done and control interface IRQs before it has requested its own IRQ line. This can cause problems on edge triggered IRQ systems as if an edge occurs before the parent IRQ is enabled it will be missed. Whilst we are changing the error handling remove an unused label as well. Signed-off-by: Charles Keepax Signed-off-by: Lee Jones --- drivers/mfd/arizona-irq.c | 57 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c index 682bc865fa8ba..5fef014920a30 100644 --- a/drivers/mfd/arizona-irq.c +++ b/drivers/mfd/arizona-irq.c @@ -310,7 +310,7 @@ int arizona_irq_init(struct arizona *arizona) if (ret != 0) { dev_err(arizona->dev, "Failed to add AOD IRQs: %d\n", ret); - goto err_domain; + goto err; } } @@ -323,30 +323,6 @@ int arizona_irq_init(struct arizona *arizona) goto err_aod; } - /* Make sure the boot done IRQ is unmasked for resumes */ - i = arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE); - ret = request_threaded_irq(i, NULL, arizona_boot_done, IRQF_ONESHOT, - "Boot done", arizona); - if (ret != 0) { - dev_err(arizona->dev, "Failed to request boot done %d: %d\n", - arizona->irq, ret); - goto err_boot_done; - } - - /* Handle control interface errors in the core */ - if (arizona->ctrlif_error) { - i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR); - ret = request_threaded_irq(i, NULL, arizona_ctrlif_err, - IRQF_ONESHOT, - "Control interface error", arizona); - if (ret != 0) { - dev_err(arizona->dev, - "Failed to request CTRLIF_ERR %d: %d\n", - arizona->irq, ret); - goto err_ctrlif; - } - } - /* Used to emulate edge trigger and to work around broken pinmux */ if (arizona->pdata.irq_gpio) { if (gpio_to_irq(arizona->pdata.irq_gpio) != arizona->irq) { @@ -376,21 +352,42 @@ int arizona_irq_init(struct arizona *arizona) goto err_main_irq; } + /* Make sure the boot done IRQ is unmasked for resumes */ + i = arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE); + ret = request_threaded_irq(i, NULL, arizona_boot_done, IRQF_ONESHOT, + "Boot done", arizona); + if (ret != 0) { + dev_err(arizona->dev, "Failed to request boot done %d: %d\n", + arizona->irq, ret); + goto err_boot_done; + } + + /* Handle control interface errors in the core */ + if (arizona->ctrlif_error) { + i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR); + ret = request_threaded_irq(i, NULL, arizona_ctrlif_err, + IRQF_ONESHOT, + "Control interface error", arizona); + if (ret != 0) { + dev_err(arizona->dev, + "Failed to request CTRLIF_ERR %d: %d\n", + arizona->irq, ret); + goto err_ctrlif; + } + } + return 0; -err_main_irq: - if (arizona->ctrlif_error) - free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR), - arizona); err_ctrlif: free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE), arizona); err_boot_done: + free_irq(arizona->irq, arizona); +err_main_irq: regmap_del_irq_chip(irq_create_mapping(arizona->virq, 1), arizona->irq_chip); err_aod: regmap_del_irq_chip(irq_create_mapping(arizona->virq, 0), arizona->aod_irq_chip); -err_domain: err: return ret; } -- GitLab From 8726cacc7f38e7e122e6910fb0b979dcd1ca89d3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 7 Dec 2015 17:16:43 +0100 Subject: [PATCH 2410/2855] mfd: da9063: Allow modular build Allow support for the DA9063 PMIC to be modular, cfr. DA9062, which allows to decrease size of multi-platform kernels (e.g. multi_v7_defconfig). Signed-off-by: Geert Uytterhoeven Acked-by: Steve Twiss Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 9581ebbfb4a09..9ca66de0c1c17 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -211,7 +211,7 @@ config MFD_DA9062 of the device. config MFD_DA9063 - bool "Dialog Semiconductor DA9063 PMIC Support" + tristate "Dialog Semiconductor DA9063 PMIC Support" select MFD_CORE select REGMAP_I2C select REGMAP_IRQ -- GitLab From f199d39349beabcb1a374cb02e0845a0ae84f3fd Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 14 Dec 2015 10:19:11 +0000 Subject: [PATCH 2411/2855] mfd: arizona: Add device tree binding to specify mono outputs Add device tree bindings to support specifying outputs from the chip as mono outputs. Whilst we are doing it change the out_mono pdata from a bool to an int, because Sparse gets upset about using ARRAY_SIZE on bools. Signed-off-by: Charles Keepax Signed-off-by: Lee Jones --- drivers/mfd/arizona-core.c | 10 ++++++++++ include/linux/mfd/arizona/pdata.h | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index b9489a0d7fabe..4bb486679110f 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -861,6 +861,16 @@ static int arizona_of_get_core_pdata(struct arizona *arizona) count++; } + count = 0; + of_property_for_each_u32(arizona->dev->of_node, "wlf,out-mono", prop, + cur, val) { + if (count == ARRAY_SIZE(pdata->out_mono)) + break; + + pdata->out_mono[count] = !!val; + count++; + } + return 0; } diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h index 57b45caaea80f..64faeeff698c2 100644 --- a/include/linux/mfd/arizona/pdata.h +++ b/include/linux/mfd/arizona/pdata.h @@ -171,7 +171,7 @@ struct arizona_pdata { int inmode[ARIZONA_MAX_INPUT]; /** Mode for outputs */ - bool out_mono[ARIZONA_MAX_OUTPUT]; + int out_mono[ARIZONA_MAX_OUTPUT]; /** PDM speaker mute setting */ unsigned int spk_mute[ARIZONA_MAX_PDM_SPK]; -- GitLab From a5dca7dc7e80f0cb4dcc9251983fb51745541f48 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 14 Dec 2015 10:19:12 +0000 Subject: [PATCH 2412/2855] mfd: arizona: Update binding docs for selecting mono/stereo outputs Update the device tree binding documentation to include the wlf,out-mono property that is used to specify whether each output is a mono or stereo output. Signed-off-by: Charles Keepax Acked-by: Rob Herring Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/arizona.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt b/Documentation/devicetree/bindings/mfd/arizona.txt index 2b6ccdb32bd91..069e31da18f01 100644 --- a/Documentation/devicetree/bindings/mfd/arizona.txt +++ b/Documentation/devicetree/bindings/mfd/arizona.txt @@ -65,6 +65,12 @@ Optional properties: that have not been specified are set to 0 by default. Entries are: (wm5102, wm5110, wm8280, wm8997) (wm8998, wm1814) + - wlf,out-mono : A list of boolean values indicating whether each output is + mono or stereo. Position within the list indicates the output affected + (eg. First entry in the list corresponds to output 1). A non-zero value + indicates a mono output. If present, the number of values should be less + than or equal to the number of outputs, if less values are supplied the + additional outputs will be treated as stereo. - wlf,dmic-ref : DMIC reference voltage source for each input, can be selected from either MICVDD or one of the MICBIAS's, defines -- GitLab From 0c7f3f92ffe8dc4e631b2f20c06543ec9f521f7c Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 22 Dec 2015 15:48:33 +0100 Subject: [PATCH 2413/2855] mfd: ucb1x00-core: Be sure to clamp return value As we want gpio_chip .get() calls to be able to return negative error codes and propagate to drivers, we need to go over all drivers and make sure their return values are clamped to [0,1]. We do this by using the ret = !!(val) design pattern. Cc: Lee Jones Signed-off-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/ucb1x00-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c index f691d7ecad526..e0dd83fb95d3b 100644 --- a/drivers/mfd/ucb1x00-core.c +++ b/drivers/mfd/ucb1x00-core.c @@ -133,7 +133,7 @@ static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset) val = ucb1x00_reg_read(ucb, UCB_IO_DATA); ucb1x00_disable(ucb); - return val & (1 << offset); + return !!(val & (1 << offset)); } static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -- GitLab From 2f4647a149943b1f87e46858e9f13e02010347f7 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 23 Oct 2015 16:44:43 -0700 Subject: [PATCH 2414/2855] backlight: gpio-backlight: Use default-on on GPIO request There are situations where the backlight should be on at boot time (e.g. if the boot loader already turned the display on). The DT bindings specify the "default-on" property for that purpose. Currently, the initial state of the GPIO at request time is always set to logical off (high or low depending on whether it is an active high or low GPIO). Since the GPIO is requested as an output, the GPIO will be driven low for a short period of time, which leads to a flickering display in the above use-case. Initialize the GPIO depending on the default-on property to be logical on or off. Signed-off-by: Stefan Agner Signed-off-by: Lee Jones --- drivers/video/backlight/gpio_backlight.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/video/backlight/gpio_backlight.c b/drivers/video/backlight/gpio_backlight.c index 5fbbc2ebdf937..18134416b154a 100644 --- a/drivers/video/backlight/gpio_backlight.c +++ b/drivers/video/backlight/gpio_backlight.c @@ -89,6 +89,7 @@ static int gpio_backlight_probe(struct platform_device *pdev) struct backlight_device *bl; struct gpio_backlight *gbl; struct device_node *np = pdev->dev.of_node; + unsigned long flags = GPIOF_DIR_OUT; int ret; if (!pdata && !np) { @@ -114,9 +115,12 @@ static int gpio_backlight_probe(struct platform_device *pdev) gbl->def_value = pdata->def_value; } - ret = devm_gpio_request_one(gbl->dev, gbl->gpio, GPIOF_DIR_OUT | - (gbl->active ? GPIOF_INIT_LOW - : GPIOF_INIT_HIGH), + if (gbl->active) + flags |= gbl->def_value ? GPIOF_INIT_HIGH : GPIOF_INIT_LOW; + else + flags |= gbl->def_value ? GPIOF_INIT_LOW : GPIOF_INIT_HIGH; + + ret = devm_gpio_request_one(gbl->dev, gbl->gpio, flags, pdata ? pdata->name : "backlight"); if (ret < 0) { dev_err(&pdev->dev, "unable to request GPIO\n"); -- GitLab From 02f22c004ff2ab0ce1f2fa3cc6a87cf20a4fed40 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 30 Nov 2015 12:24:23 +0100 Subject: [PATCH 2415/2855] backlight: adp8860: Fix another uninitialized variable use A recent patch I did fixed two potential uses of uninitialized variables in the adp8870 and adp8860 drivers. Unfortunately, I missed another one: drivers/video/backlight/adp8860_bl.c: In function 'adp8860_bl_ambient_light_level_show': drivers/video/backlight/adp8860_bl.c:570:11: warning: 'reg_val' may be used uninitialized in this function This does the same change as before in one additional function, and also changes the check for the return value in a way that avoids another false positive warning with a similar message. Signed-off-by: Arnd Bergmann Fixes: 6be3a5a9cd91 ("backlight: adp88x0: Fix uninitialized variable use") Acked-by: Michael Hennerich Acked-by: Jingoo Han Signed-off-by: Lee Jones --- drivers/video/backlight/adp8860_bl.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c index f0d4c0324580a..510e559c060e5 100644 --- a/drivers/video/backlight/adp8860_bl.c +++ b/drivers/video/backlight/adp8860_bl.c @@ -566,11 +566,13 @@ static ssize_t adp8860_bl_ambient_light_level_show(struct device *dev, mutex_lock(&data->lock); error = adp8860_read(data->client, ADP8860_PH1LEVL, ®_val); - ret_val = reg_val; - error |= adp8860_read(data->client, ADP8860_PH1LEVH, ®_val); + if (!error) { + ret_val = reg_val; + error = adp8860_read(data->client, ADP8860_PH1LEVH, ®_val); + } mutex_unlock(&data->lock); - if (error < 0) + if (error) return error; /* Return 13-bit conversion value for the first light sensor */ -- GitLab From 5f7e5445a2de848c66d2d80ba5479197e8287c33 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 11 Jan 2016 00:08:58 -0800 Subject: [PATCH 2416/2855] Input: wacom_w8001 - drop use of ABS_MT_TOOL_TYPE As of e0361b70175 ("Input: wacom_w8001 - split the touch and pen devices into two devices") the touch events aren't multiplexed over the same device anymore, the use of ABS_MT_TOOL_TYPE is superfluous. And even before then it only ever sent MT_TOOL_TYPE_FINGER anyway. Signed-off-by: Peter Hutterer Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wacom_w8001.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index fe983e781bca5..bab3c6acf6a22 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c @@ -155,7 +155,6 @@ static void parse_multi_touch(struct w8001 *w8001) bool touch = data[0] & (1 << i); input_mt_slot(dev, i); - input_mt_report_slot_state(dev, MT_TOOL_FINGER, touch); if (touch) { x = (data[6 * i + 1] << 7) | data[6 * i + 2]; y = (data[6 * i + 3] << 7) | data[6 * i + 4]; @@ -514,8 +513,6 @@ static int w8001_setup_touch(struct w8001 *w8001, char *basename, 0, touch.x, 0, 0); input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, touch.y, 0, 0); - input_set_abs_params(dev, ABS_MT_TOOL_TYPE, - 0, MT_TOOL_MAX, 0, 0); strlcat(basename, " 2FG", basename_sz); if (w8001->max_pen_x && w8001->max_pen_y) -- GitLab From 419dbd5e1ff0e45a6e1d28c1f7b74d121d2a56e7 Mon Sep 17 00:00:00 2001 From: Alistair Popple Date: Fri, 8 Jan 2016 11:35:09 +1100 Subject: [PATCH 2417/2855] powerpc/powernv: Fix update of NVLink DMA mask The emulated NVLink PCI devices share the same IODA2 TCE tables but only support a single TVT (instead of the normal two for PCI devices). This requires the kernel to manually replace windows with either the bypass or non-bypass window depending on what the driver has requested. Unfortunately an incorrect optimisation was made in pnv_pci_ioda_dma_set_mask() which caused updating of some NPU device PEs to be skipped in certain configurations due to an incorrect assumption that a NULL peer PE in the array indicated there were no more peers present. This patch fixes the problem by ensuring all peer PEs are updated. Fixes: 5d2aa710e697 ("powerpc/powernv: Add support for Nvlink NPUs") Signed-off-by: Alistair Popple Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci-ioda.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 323e1e58da93c..458133f3c020e 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -1612,7 +1612,10 @@ static int pnv_pci_ioda_dma_set_mask(struct pci_dev *pdev, u64 dma_mask) /* Update peer npu devices */ if (pe->flags & PNV_IODA_PE_PEER) - for (i = 0; pe->peers[i]; i++) { + for (i = 0; i < PNV_IODA_MAX_PEER_PES; i++) { + if (!pe->peers[i]) + continue; + linked_npu_dev = pe->peers[i]->pdev; if (dma_get_mask(&linked_npu_dev->dev) != dma_mask) dma_set_mask(&linked_npu_dev->dev, dma_mask); -- GitLab From b521549a09ddfac3bed38e261168cda92d04ce81 Mon Sep 17 00:00:00 2001 From: Alistair Popple Date: Mon, 11 Jan 2016 16:53:49 +1100 Subject: [PATCH 2418/2855] powerpc/powernv: Change NPU PE# assignment The P8+ hardware supports four partitionable endpoints (PEs) however the hardware reports all errors as occurring on PE#0. This means we need to reserve this PE for error handling (EEH) and not assign it to a NPU device, implying that some devices will need to share PEs. This patch changes the PE assignment for NPU devices such that NPU devices which connect to the same GPU are assigned to the same PE#. Signed-off-by: Alistair Popple Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci-ioda.c | 73 ++++++++++++++++++++--- 1 file changed, 66 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 458133f3c020e..0b625272f3ca9 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -1074,16 +1074,75 @@ static void pnv_ioda_setup_bus_PE(struct pci_bus *bus, bool all) pnv_ioda_link_pe_by_weight(phb, pe); } -static void pnv_ioda_setup_dev_PEs(struct pci_bus *bus) +static struct pnv_ioda_pe *pnv_ioda_setup_npu_PE(struct pci_dev *npu_pdev) +{ + int pe_num, found_pe = false, rc; + long rid; + struct pnv_ioda_pe *pe; + struct pci_dev *gpu_pdev; + struct pci_dn *npu_pdn; + struct pci_controller *hose = pci_bus_to_host(npu_pdev->bus); + struct pnv_phb *phb = hose->private_data; + + /* + * Due to a hardware errata PE#0 on the NPU is reserved for + * error handling. This means we only have three PEs remaining + * which need to be assigned to four links, implying some + * links must share PEs. + * + * To achieve this we assign PEs such that NPUs linking the + * same GPU get assigned the same PE. + */ + gpu_pdev = pnv_pci_get_gpu_dev(npu_pdev); + for (pe_num = 0; pe_num < phb->ioda.total_pe; pe_num++) { + pe = &phb->ioda.pe_array[pe_num]; + if (!pe->pdev) + continue; + + if (pnv_pci_get_gpu_dev(pe->pdev) == gpu_pdev) { + /* + * This device has the same peer GPU so should + * be assigned the same PE as the existing + * peer NPU. + */ + dev_info(&npu_pdev->dev, + "Associating to existing PE %d\n", pe_num); + pci_dev_get(npu_pdev); + npu_pdn = pci_get_pdn(npu_pdev); + rid = npu_pdev->bus->number << 8 | npu_pdn->devfn; + npu_pdn->pcidev = npu_pdev; + npu_pdn->pe_number = pe_num; + pe->dma_weight += pnv_ioda_dma_weight(npu_pdev); + phb->ioda.pe_rmap[rid] = pe->pe_number; + + /* Map the PE to this link */ + rc = opal_pci_set_pe(phb->opal_id, pe_num, rid, + OpalPciBusAll, + OPAL_COMPARE_RID_DEVICE_NUMBER, + OPAL_COMPARE_RID_FUNCTION_NUMBER, + OPAL_MAP_PE); + WARN_ON(rc != OPAL_SUCCESS); + found_pe = true; + break; + } + } + + if (!found_pe) + /* + * Could not find an existing PE so allocate a new + * one. + */ + return pnv_ioda_setup_dev_PE(npu_pdev); + else + return pe; +} + +static void pnv_ioda_setup_npu_PEs(struct pci_bus *bus) { - struct pci_bus *child; struct pci_dev *pdev; list_for_each_entry(pdev, &bus->devices, bus_list) - pnv_ioda_setup_dev_PE(pdev); - - list_for_each_entry(child, &bus->children, node) - pnv_ioda_setup_dev_PEs(child); + pnv_ioda_setup_npu_PE(pdev); } static void pnv_ioda_setup_PEs(struct pci_bus *bus) @@ -1128,7 +1187,7 @@ static void pnv_pci_ioda_setup_PEs(void) * remaining types of PHBs. */ if (phb->type == PNV_PHB_NPU) - pnv_ioda_setup_dev_PEs(hose->bus); + pnv_ioda_setup_npu_PEs(hose->bus); else pnv_ioda_setup_PEs(hose->bus); } -- GitLab From 08f48f3234a79bca86c2283a166aec83bf52b265 Mon Sep 17 00:00:00 2001 From: Alistair Popple Date: Mon, 11 Jan 2016 16:53:50 +1100 Subject: [PATCH 2419/2855] powerpc/powernv: Reserve PE#0 on NPU P8+ hardware reports all errors on PE#0. This patch ensures PE#0 is not assigned to NPU devices so that it can be used for EEH. Signed-off-by: Alistair Popple Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci-ioda.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 0b625272f3ca9..573ae1994097f 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -1186,9 +1186,11 @@ static void pnv_pci_ioda_setup_PEs(void) * functions. PCI bus dependent PEs are required for the * remaining types of PHBs. */ - if (phb->type == PNV_PHB_NPU) + if (phb->type == PNV_PHB_NPU) { + /* PE#0 is needed for error reporting */ + pnv_ioda_reserve_pe(phb, 0); pnv_ioda_setup_npu_PEs(hose->bus); - else + } else pnv_ioda_setup_PEs(hose->bus); } } -- GitLab From e708c24cd01ce80b1609d8baccee40ccc3608a01 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Mon, 11 Jan 2016 13:59:04 +1100 Subject: [PATCH 2420/2855] powerpc: Add HWCAP bits for Power9 In order to support Power9 we need two new HWCAP bits. We are merging these ahead of the cputable entry so that glibc can start referring to them. Signed-off-by: Michael Ellerman --- arch/powerpc/include/uapi/asm/cputable.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/include/uapi/asm/cputable.h b/arch/powerpc/include/uapi/asm/cputable.h index 43686043e2973..8dde19962a5b4 100644 --- a/arch/powerpc/include/uapi/asm/cputable.h +++ b/arch/powerpc/include/uapi/asm/cputable.h @@ -43,5 +43,7 @@ #define PPC_FEATURE2_TAR 0x04000000 #define PPC_FEATURE2_VEC_CRYPTO 0x02000000 #define PPC_FEATURE2_HTM_NOSC 0x01000000 +#define PPC_FEATURE2_ARCH_3_00 0x00800000 /* ISA 3.00 */ +#define PPC_FEATURE2_HAS_IEEE128 0x00400000 /* VSX IEEE Binary Float 128-bit */ #endif /* _UAPI__ASM_POWERPC_CPUTABLE_H */ -- GitLab From aa09545589ceeff884421d8eb38d04963190afbe Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 8 Jan 2016 10:30:09 -0800 Subject: [PATCH 2421/2855] cxl: fix build for GCC 4.6.x GCC 4.6.3 does not support -Wno-unused-const-variable. Instead, use the kbuild infrastructure that checks if this options exists. Fixes: 2cd55c68c0a4 ("cxl: Fix build failure due to -Wunused-variable behaviour change") Suggested-by: Michal Marek Suggested-by: Arnd Bergmann Signed-off-by: Brian Norris Signed-off-by: Michael Ellerman --- drivers/misc/cxl/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/cxl/Makefile b/drivers/misc/cxl/Makefile index 6982f603fadc5..ab6f392d35041 100644 --- a/drivers/misc/cxl/Makefile +++ b/drivers/misc/cxl/Makefile @@ -1,4 +1,4 @@ -ccflags-y := -Werror -Wno-unused-const-variable +ccflags-y := -Werror $(call cc-disable-warning, unused-const-variable) cxl-y += main.o file.o irq.o fault.o native.o cxl-y += context.o sysfs.o debugfs.o pci.o trace.o -- GitLab From 57f7c3932516b9f7908d9b0a24396112d0f4ca55 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 8 Jan 2016 10:30:10 -0800 Subject: [PATCH 2422/2855] cxl: use -Werror only with CONFIG_PPC_WERROR Some developers really like to have -Werror enabled for their code, as it helps to ensure warning free code. Others don't want -Werror, as it (for example) can cause problems when newer (or older) compilers have different sets of warnings, or new warnings can appear just when turning up the warning level (e.g., make W=1 or W=2). Thus, it seems prudent to have the use of -Werror be configurable. It so happens that cxl is only built on PowerPC, and PowerPC already has a nice set of Kconfig options for this, under CONFIG_PPC_WERROR. So let's use that, and the world is a happy place again! (Note that PPC_WERROR defaults to =y, so the common case compile should still be enforcing -Werror.) Fixes: d3d73f4b38a8 ("cxl: Compile with -Werror") Signed-off-by: Brian Norris Signed-off-by: Michael Ellerman --- drivers/misc/cxl/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/misc/cxl/Makefile b/drivers/misc/cxl/Makefile index ab6f392d35041..be2ac5ce349f0 100644 --- a/drivers/misc/cxl/Makefile +++ b/drivers/misc/cxl/Makefile @@ -1,4 +1,5 @@ -ccflags-y := -Werror $(call cc-disable-warning, unused-const-variable) +ccflags-y := $(call cc-disable-warning, unused-const-variable) +ccflags-$(CONFIG_PPC_WERROR) += -Werror cxl-y += main.o file.o irq.o fault.o native.o cxl-y += context.o sysfs.o debugfs.o pci.o trace.o -- GitLab From 68adb7bfd66504e97364651fb7dac3f9c8aa8561 Mon Sep 17 00:00:00 2001 From: Uma Krishnan Date: Mon, 7 Dec 2015 16:03:32 -0600 Subject: [PATCH 2423/2855] cxl: Enable PCI device ID for future IBM CXL adapter Add support for future IBM Coherent Accelerator (CXL) device with ID of 0x0601. Signed-off-by: Uma Krishnan Reviewed-by: Matthew R. Ochs Signed-off-by: Michael Ellerman --- drivers/misc/cxl/pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index 85761d7eb3331..4c1903f781fc1 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c @@ -138,6 +138,7 @@ static const struct pci_device_id cxl_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0477), }, { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x044b), }, { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x04cf), }, + { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0601), }, { PCI_DEVICE_CLASS(0x120000, ~0), }, { } -- GitLab From 60d613d6aef4ae49988eeb3ad38af948c561db1e Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Sun, 14 Jun 2015 17:32:14 +0300 Subject: [PATCH 2424/2855] backlight: pwm_bl: Free PWM requested by legacy API on error path If pwm is requested by legacy pwm_request() and if the following backlight_device_register() call fails, add pwm_free() clean-up. Signed-off-by: Vladimir Zapolskiy Signed-off-by: Lee Jones --- drivers/video/backlight/pwm_bl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index a22c1ec29de75..64f9e1b8655f4 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -328,6 +328,8 @@ static int pwm_backlight_probe(struct platform_device *pdev) if (IS_ERR(bl)) { dev_err(&pdev->dev, "failed to register backlight\n"); ret = PTR_ERR(bl); + if (pb->legacy) + pwm_free(pb->pwm); goto err_alloc; } -- GitLab From 71b3c126e61177eb693423f2e18a1914205b165e Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Wed, 6 Jan 2016 12:21:01 -0800 Subject: [PATCH 2425/2855] x86/mm: Add barriers and document switch_mm()-vs-flush synchronization When switch_mm() activates a new PGD, it also sets a bit that tells other CPUs that the PGD is in use so that TLB flush IPIs will be sent. In order for that to work correctly, the bit needs to be visible prior to loading the PGD and therefore starting to fill the local TLB. Document all the barriers that make this work correctly and add a couple that were missing. Signed-off-by: Andy Lutomirski Cc: Andrew Morton Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Dave Hansen Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Rik van Riel Cc: Thomas Gleixner Cc: linux-mm@kvack.org Cc: stable@vger.kernel.org Signed-off-by: Ingo Molnar --- arch/x86/include/asm/mmu_context.h | 33 +++++++++++++++++++++++++++++- arch/x86/mm/tlb.c | 29 +++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 379cd3658799f..1edc9cd198b85 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -116,8 +116,34 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, #endif cpumask_set_cpu(cpu, mm_cpumask(next)); - /* Re-load page tables */ + /* + * Re-load page tables. + * + * This logic has an ordering constraint: + * + * CPU 0: Write to a PTE for 'next' + * CPU 0: load bit 1 in mm_cpumask. if nonzero, send IPI. + * CPU 1: set bit 1 in next's mm_cpumask + * CPU 1: load from the PTE that CPU 0 writes (implicit) + * + * We need to prevent an outcome in which CPU 1 observes + * the new PTE value and CPU 0 observes bit 1 clear in + * mm_cpumask. (If that occurs, then the IPI will never + * be sent, and CPU 0's TLB will contain a stale entry.) + * + * The bad outcome can occur if either CPU's load is + * reordered before that CPU's store, so both CPUs much + * execute full barriers to prevent this from happening. + * + * Thus, switch_mm needs a full barrier between the + * store to mm_cpumask and any operation that could load + * from next->pgd. This barrier synchronizes with + * remote TLB flushers. Fortunately, load_cr3 is + * serializing and thus acts as a full barrier. + * + */ load_cr3(next->pgd); + trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL); /* Stop flush ipis for the previous mm */ @@ -156,10 +182,15 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, * schedule, protecting us from simultaneous changes. */ cpumask_set_cpu(cpu, mm_cpumask(next)); + /* * We were in lazy tlb mode and leave_mm disabled * tlb flush IPI delivery. We must reload CR3 * to make sure to use no freed page tables. + * + * As above, this is a barrier that forces + * TLB repopulation to be ordered after the + * store to mm_cpumask. */ load_cr3(next->pgd); trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL); diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 8ddb5d0d66fb6..8f4cc3dfac322 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -161,7 +161,10 @@ void flush_tlb_current_task(void) preempt_disable(); count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL); + + /* This is an implicit full barrier that synchronizes with switch_mm. */ local_flush_tlb(); + trace_tlb_flush(TLB_LOCAL_SHOOTDOWN, TLB_FLUSH_ALL); if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids) flush_tlb_others(mm_cpumask(mm), mm, 0UL, TLB_FLUSH_ALL); @@ -188,17 +191,29 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, unsigned long base_pages_to_flush = TLB_FLUSH_ALL; preempt_disable(); - if (current->active_mm != mm) + if (current->active_mm != mm) { + /* Synchronize with switch_mm. */ + smp_mb(); + goto out; + } if (!current->mm) { leave_mm(smp_processor_id()); + + /* Synchronize with switch_mm. */ + smp_mb(); + goto out; } if ((end != TLB_FLUSH_ALL) && !(vmflag & VM_HUGETLB)) base_pages_to_flush = (end - start) >> PAGE_SHIFT; + /* + * Both branches below are implicit full barriers (MOV to CR or + * INVLPG) that synchronize with switch_mm. + */ if (base_pages_to_flush > tlb_single_page_flush_ceiling) { base_pages_to_flush = TLB_FLUSH_ALL; count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL); @@ -228,10 +243,18 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long start) preempt_disable(); if (current->active_mm == mm) { - if (current->mm) + if (current->mm) { + /* + * Implicit full barrier (INVLPG) that synchronizes + * with switch_mm. + */ __flush_tlb_one(start); - else + } else { leave_mm(smp_processor_id()); + + /* Synchronize with switch_mm. */ + smp_mb(); + } } if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids) -- GitLab From 7022ec496005b47257b8c0a1c1a40df92df7c79f Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 30 Dec 2015 13:42:37 +0100 Subject: [PATCH 2426/2855] s390/sysinfo: add missing SYSIB 1.2.2 multithreading fields Add missing multithreading fields of SYSIB 1.2.2 (Basic-Machine CPUs) to the output of /proc/sysinfo. Also use bitfields for SYSIB 2.2.2 to simplify the C code a bit. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/sysinfo.h | 17 +++++++++++++---- arch/s390/kernel/sysinfo.c | 15 ++++++++------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/arch/s390/include/asm/sysinfo.h b/arch/s390/include/asm/sysinfo.h index f7054a892d9e9..2728114d5484e 100644 --- a/arch/s390/include/asm/sysinfo.h +++ b/arch/s390/include/asm/sysinfo.h @@ -56,7 +56,12 @@ struct sysinfo_1_2_2 { char format; char reserved_0[1]; unsigned short acc_offset; - char reserved_1[20]; + unsigned char mt_installed :1; + unsigned char :2; + unsigned char mt_stid :5; + unsigned char :3; + unsigned char mt_gtid :5; + char reserved_1[18]; unsigned int nominal_cap; unsigned int secondary_cap; unsigned int capability; @@ -92,9 +97,13 @@ struct sysinfo_2_2_2 { char name[8]; unsigned int caf; char reserved_2[8]; - unsigned char mt_installed; - unsigned char mt_general; - unsigned char mt_psmtid; + unsigned char mt_installed :1; + unsigned char :2; + unsigned char mt_stid :5; + unsigned char :3; + unsigned char mt_gtid :5; + unsigned char :3; + unsigned char mt_psmtid :5; char reserved_3[5]; unsigned short cpus_dedicated; unsigned short cpus_shared; diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c index 0512f944eaf3f..f7dba3887a545 100644 --- a/arch/s390/kernel/sysinfo.c +++ b/arch/s390/kernel/sysinfo.c @@ -144,6 +144,10 @@ static void stsi_1_2_2(struct seq_file *m, struct sysinfo_1_2_2 *info) seq_printf(m, "CPUs Configured: %d\n", info->cpus_configured); seq_printf(m, "CPUs Standby: %d\n", info->cpus_standby); seq_printf(m, "CPUs Reserved: %d\n", info->cpus_reserved); + if (info->mt_installed) { + seq_printf(m, "CPUs G-MTID: %d\n", info->mt_gtid); + seq_printf(m, "CPUs S-MTID: %d\n", info->mt_stid); + } /* * Sigh 2. According to the specification the alternate * capability field is a 32 bit floating point number @@ -193,13 +197,10 @@ static void stsi_2_2_2(struct seq_file *m, struct sysinfo_2_2_2 *info) seq_printf(m, "LPAR CPUs Reserved: %d\n", info->cpus_reserved); seq_printf(m, "LPAR CPUs Dedicated: %d\n", info->cpus_dedicated); seq_printf(m, "LPAR CPUs Shared: %d\n", info->cpus_shared); - if (info->mt_installed & 0x80) { - seq_printf(m, "LPAR CPUs G-MTID: %d\n", - info->mt_general & 0x1f); - seq_printf(m, "LPAR CPUs S-MTID: %d\n", - info->mt_installed & 0x1f); - seq_printf(m, "LPAR CPUs PS-MTID: %d\n", - info->mt_psmtid & 0x1f); + if (info->mt_installed) { + seq_printf(m, "LPAR CPUs G-MTID: %d\n", info->mt_gtid); + seq_printf(m, "LPAR CPUs S-MTID: %d\n", info->mt_stid); + seq_printf(m, "LPAR CPUs PS-MTID: %d\n", info->mt_psmtid); } } -- GitLab From cb951785a78c68bf802f5e3d9016b0205ddd24c2 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 31 Dec 2015 09:58:02 +0100 Subject: [PATCH 2427/2855] s390/ptrace: get rid of long longs in psw_bits The long longs were introduced by me in order to have a working definition of the struct psw_bits also in 31 bit mode. Since that is gone also get rid of the long longs. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/ptrace.h | 38 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index 37cbc50947f2a..f00cd35c8ac46 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h @@ -24,25 +24,25 @@ PSW_MASK_PSTATE | PSW_ASC_PRIMARY) struct psw_bits { - unsigned long long : 1; - unsigned long long r : 1; /* PER-Mask */ - unsigned long long : 3; - unsigned long long t : 1; /* DAT Mode */ - unsigned long long i : 1; /* Input/Output Mask */ - unsigned long long e : 1; /* External Mask */ - unsigned long long key : 4; /* PSW Key */ - unsigned long long : 1; - unsigned long long m : 1; /* Machine-Check Mask */ - unsigned long long w : 1; /* Wait State */ - unsigned long long p : 1; /* Problem State */ - unsigned long long as : 2; /* Address Space Control */ - unsigned long long cc : 2; /* Condition Code */ - unsigned long long pm : 4; /* Program Mask */ - unsigned long long ri : 1; /* Runtime Instrumentation */ - unsigned long long : 6; - unsigned long long eaba : 2; /* Addressing Mode */ - unsigned long long : 31; - unsigned long long ia : 64;/* Instruction Address */ + unsigned long : 1; + unsigned long r : 1; /* PER-Mask */ + unsigned long : 3; + unsigned long t : 1; /* DAT Mode */ + unsigned long i : 1; /* Input/Output Mask */ + unsigned long e : 1; /* External Mask */ + unsigned long key : 4; /* PSW Key */ + unsigned long : 1; + unsigned long m : 1; /* Machine-Check Mask */ + unsigned long w : 1; /* Wait State */ + unsigned long p : 1; /* Problem State */ + unsigned long as : 2; /* Address Space Control */ + unsigned long cc : 2; /* Condition Code */ + unsigned long pm : 4; /* Program Mask */ + unsigned long ri : 1; /* Runtime Instrumentation */ + unsigned long : 6; + unsigned long eaba : 2; /* Addressing Mode */ + unsigned long : 31; + unsigned long ia : 64; /* Instruction Address */ }; enum { -- GitLab From 423d5b364c108c00d98e3da9f72d598e8f2ef948 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 31 Dec 2015 10:07:21 +0100 Subject: [PATCH 2428/2855] s390/mem_detect: use unsigned longs The memory detection code historically had to use unsigned long long since the machine reported the true memory size (>4GB) even if the virtual machine was running in ESA/390 mode. Since the old code is gone use unsigned long everywhere and also get rid of an unused ADDR2G define. (this patch converts all long longs within sclp_info to longs) There are many more possible conversions, however that can be done if somebody touches the corresponding code. Since people started to convert unrelated long types to long longs because of the types within struct sclp_info convert this now. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/sclp.h | 8 ++++---- arch/s390/mm/mem_detect.c | 7 ++----- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index cb691602f295e..5e3da0414b477 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h @@ -57,12 +57,12 @@ struct sclp_info { unsigned int mtid; unsigned int mtid_cp; unsigned int mtid_prev; - unsigned long long rzm; - unsigned long long rnmax; - unsigned long long hamax; + unsigned long rzm; + unsigned long rnmax; + unsigned long hamax; unsigned int max_cores; unsigned long hsa_size; - unsigned long long facilities; + unsigned long facilities; }; extern struct sclp_info sclp; diff --git a/arch/s390/mm/mem_detect.c b/arch/s390/mm/mem_detect.c index e00f0d5d296d0..d612cc3eec6a3 100644 --- a/arch/s390/mm/mem_detect.c +++ b/arch/s390/mm/mem_detect.c @@ -14,8 +14,6 @@ #include #include -#define ADDR2G (1ULL << 31) - #define CHUNK_READ_WRITE 0 #define CHUNK_READ_ONLY 1 @@ -27,15 +25,14 @@ static inline void memblock_physmem_add(phys_addr_t start, phys_addr_t size) void __init detect_memory_memblock(void) { - unsigned long long memsize, rnmax, rzm; - unsigned long addr, size; + unsigned long memsize, rnmax, rzm, addr, size; int type; rzm = sclp.rzm; rnmax = sclp.rnmax; memsize = rzm * rnmax; if (!rzm) - rzm = 1ULL << 17; + rzm = 1UL << 17; max_physmem_end = memsize; addr = 0; /* keep memblock lists close to the kernel */ -- GitLab From c667aeacc16e0de9e205faa93f57121d6f691973 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 31 Dec 2015 10:29:00 +0100 Subject: [PATCH 2429/2855] s390: rename struct _lowcore to struct lowcore Finally get rid of the leading underscore. I tried this already two or three years ago, however Michael Holzheu objected since this would break the crash utility (again). However Michael integrated support for the new name into the crash utility back then, so it doesn't break if the name will be changed now. So finally get rid of the ever confusing leading underscore. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/lowcore.h | 6 +- arch/s390/include/asm/processor.h | 2 +- arch/s390/include/asm/vdso.h | 4 +- arch/s390/kernel/asm-offsets.c | 174 +++++++++++++++--------------- arch/s390/kernel/crash_dump.c | 4 +- arch/s390/kernel/ipl.c | 4 +- arch/s390/kernel/setup.c | 6 +- arch/s390/kernel/smp.c | 16 +-- arch/s390/kernel/vdso.c | 6 +- arch/s390/kvm/interrupt.c | 4 +- arch/s390/kvm/priv.c | 2 +- arch/s390/mm/maccess.c | 4 +- 12 files changed, 116 insertions(+), 116 deletions(-) diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index 5dbbf199ba2ed..d79ba7cf75b04 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h @@ -16,7 +16,7 @@ #define LC_ORDER 1 #define LC_PAGES 2 -struct _lowcore { +struct lowcore { __u8 pad_0x0000[0x0014-0x0000]; /* 0x0000 */ __u32 ipl_parmblock_ptr; /* 0x0014 */ __u8 pad_0x0018[0x0080-0x0018]; /* 0x0018 */ @@ -183,9 +183,9 @@ struct _lowcore { __u8 vector_save_area[1024]; /* 0x1c00 */ } __packed; -#define S390_lowcore (*((struct _lowcore *) 0)) +#define S390_lowcore (*((struct lowcore *) 0)) -extern struct _lowcore *lowcore_ptr[]; +extern struct lowcore *lowcore_ptr[]; static inline void set_prefix(__u32 address) { diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 5592c94ebe310..f16debf6a6129 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -60,7 +60,7 @@ static inline int test_cpu_flag(int flag) */ static inline int test_cpu_flag_of(int flag, int cpu) { - struct _lowcore *lc = lowcore_ptr[cpu]; + struct lowcore *lc = lowcore_ptr[cpu]; return !!(lc->cpu_flags & (1UL << flag)); } diff --git a/arch/s390/include/asm/vdso.h b/arch/s390/include/asm/vdso.h index 787acd4f9668a..f9b02d300d60b 100644 --- a/arch/s390/include/asm/vdso.h +++ b/arch/s390/include/asm/vdso.h @@ -42,8 +42,8 @@ struct vdso_per_cpu_data { extern struct vdso_data *vdso_data; -int vdso_alloc_per_cpu(struct _lowcore *lowcore); -void vdso_free_per_cpu(struct _lowcore *lowcore); +int vdso_alloc_per_cpu(struct lowcore *lowcore); +void vdso_free_per_cpu(struct lowcore *lowcore); #endif /* __ASSEMBLY__ */ #endif /* __S390_VDSO_H__ */ diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index d8d18f8d8b775..d5916ef9c619c 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -97,96 +97,96 @@ int main(void) OFFSET(__TIMER_IDLE_EXIT, s390_idle_data, timer_idle_exit); BLANK(); /* hardware defined lowcore locations 0x000 - 0x1ff */ - OFFSET(__LC_EXT_PARAMS, _lowcore, ext_params); - OFFSET(__LC_EXT_CPU_ADDR, _lowcore, ext_cpu_addr); - OFFSET(__LC_EXT_INT_CODE, _lowcore, ext_int_code); - OFFSET(__LC_SVC_ILC, _lowcore, svc_ilc); - OFFSET(__LC_SVC_INT_CODE, _lowcore, svc_code); - OFFSET(__LC_PGM_ILC, _lowcore, pgm_ilc); - OFFSET(__LC_PGM_INT_CODE, _lowcore, pgm_code); - OFFSET(__LC_DATA_EXC_CODE, _lowcore, data_exc_code); - OFFSET(__LC_MON_CLASS_NR, _lowcore, mon_class_num); - OFFSET(__LC_PER_CODE, _lowcore, per_code); - OFFSET(__LC_PER_ATMID, _lowcore, per_atmid); - OFFSET(__LC_PER_ADDRESS, _lowcore, per_address); - OFFSET(__LC_EXC_ACCESS_ID, _lowcore, exc_access_id); - OFFSET(__LC_PER_ACCESS_ID, _lowcore, per_access_id); - OFFSET(__LC_OP_ACCESS_ID, _lowcore, op_access_id); - OFFSET(__LC_AR_MODE_ID, _lowcore, ar_mode_id); - OFFSET(__LC_TRANS_EXC_CODE, _lowcore, trans_exc_code); - OFFSET(__LC_MON_CODE, _lowcore, monitor_code); - OFFSET(__LC_SUBCHANNEL_ID, _lowcore, subchannel_id); - OFFSET(__LC_SUBCHANNEL_NR, _lowcore, subchannel_nr); - OFFSET(__LC_IO_INT_PARM, _lowcore, io_int_parm); - OFFSET(__LC_IO_INT_WORD, _lowcore, io_int_word); - OFFSET(__LC_STFL_FAC_LIST, _lowcore, stfl_fac_list); - OFFSET(__LC_STFLE_FAC_LIST, _lowcore, stfle_fac_list); - OFFSET(__LC_MCCK_CODE, _lowcore, mcck_interruption_code); - OFFSET(__LC_MCCK_FAIL_STOR_ADDR, _lowcore, failing_storage_address); - OFFSET(__LC_LAST_BREAK, _lowcore, breaking_event_addr); - OFFSET(__LC_RST_OLD_PSW, _lowcore, restart_old_psw); - OFFSET(__LC_EXT_OLD_PSW, _lowcore, external_old_psw); - OFFSET(__LC_SVC_OLD_PSW, _lowcore, svc_old_psw); - OFFSET(__LC_PGM_OLD_PSW, _lowcore, program_old_psw); - OFFSET(__LC_MCK_OLD_PSW, _lowcore, mcck_old_psw); - OFFSET(__LC_IO_OLD_PSW, _lowcore, io_old_psw); - OFFSET(__LC_RST_NEW_PSW, _lowcore, restart_psw); - OFFSET(__LC_EXT_NEW_PSW, _lowcore, external_new_psw); - OFFSET(__LC_SVC_NEW_PSW, _lowcore, svc_new_psw); - OFFSET(__LC_PGM_NEW_PSW, _lowcore, program_new_psw); - OFFSET(__LC_MCK_NEW_PSW, _lowcore, mcck_new_psw); - OFFSET(__LC_IO_NEW_PSW, _lowcore, io_new_psw); + OFFSET(__LC_EXT_PARAMS, lowcore, ext_params); + OFFSET(__LC_EXT_CPU_ADDR, lowcore, ext_cpu_addr); + OFFSET(__LC_EXT_INT_CODE, lowcore, ext_int_code); + OFFSET(__LC_SVC_ILC, lowcore, svc_ilc); + OFFSET(__LC_SVC_INT_CODE, lowcore, svc_code); + OFFSET(__LC_PGM_ILC, lowcore, pgm_ilc); + OFFSET(__LC_PGM_INT_CODE, lowcore, pgm_code); + OFFSET(__LC_DATA_EXC_CODE, lowcore, data_exc_code); + OFFSET(__LC_MON_CLASS_NR, lowcore, mon_class_num); + OFFSET(__LC_PER_CODE, lowcore, per_code); + OFFSET(__LC_PER_ATMID, lowcore, per_atmid); + OFFSET(__LC_PER_ADDRESS, lowcore, per_address); + OFFSET(__LC_EXC_ACCESS_ID, lowcore, exc_access_id); + OFFSET(__LC_PER_ACCESS_ID, lowcore, per_access_id); + OFFSET(__LC_OP_ACCESS_ID, lowcore, op_access_id); + OFFSET(__LC_AR_MODE_ID, lowcore, ar_mode_id); + OFFSET(__LC_TRANS_EXC_CODE, lowcore, trans_exc_code); + OFFSET(__LC_MON_CODE, lowcore, monitor_code); + OFFSET(__LC_SUBCHANNEL_ID, lowcore, subchannel_id); + OFFSET(__LC_SUBCHANNEL_NR, lowcore, subchannel_nr); + OFFSET(__LC_IO_INT_PARM, lowcore, io_int_parm); + OFFSET(__LC_IO_INT_WORD, lowcore, io_int_word); + OFFSET(__LC_STFL_FAC_LIST, lowcore, stfl_fac_list); + OFFSET(__LC_STFLE_FAC_LIST, lowcore, stfle_fac_list); + OFFSET(__LC_MCCK_CODE, lowcore, mcck_interruption_code); + OFFSET(__LC_MCCK_FAIL_STOR_ADDR, lowcore, failing_storage_address); + OFFSET(__LC_LAST_BREAK, lowcore, breaking_event_addr); + OFFSET(__LC_RST_OLD_PSW, lowcore, restart_old_psw); + OFFSET(__LC_EXT_OLD_PSW, lowcore, external_old_psw); + OFFSET(__LC_SVC_OLD_PSW, lowcore, svc_old_psw); + OFFSET(__LC_PGM_OLD_PSW, lowcore, program_old_psw); + OFFSET(__LC_MCK_OLD_PSW, lowcore, mcck_old_psw); + OFFSET(__LC_IO_OLD_PSW, lowcore, io_old_psw); + OFFSET(__LC_RST_NEW_PSW, lowcore, restart_psw); + OFFSET(__LC_EXT_NEW_PSW, lowcore, external_new_psw); + OFFSET(__LC_SVC_NEW_PSW, lowcore, svc_new_psw); + OFFSET(__LC_PGM_NEW_PSW, lowcore, program_new_psw); + OFFSET(__LC_MCK_NEW_PSW, lowcore, mcck_new_psw); + OFFSET(__LC_IO_NEW_PSW, lowcore, io_new_psw); /* software defined lowcore locations 0x200 - 0xdff*/ - OFFSET(__LC_SAVE_AREA_SYNC, _lowcore, save_area_sync); - OFFSET(__LC_SAVE_AREA_ASYNC, _lowcore, save_area_async); - OFFSET(__LC_SAVE_AREA_RESTART, _lowcore, save_area_restart); - OFFSET(__LC_CPU_FLAGS, _lowcore, cpu_flags); - OFFSET(__LC_RETURN_PSW, _lowcore, return_psw); - OFFSET(__LC_RETURN_MCCK_PSW, _lowcore, return_mcck_psw); - OFFSET(__LC_SYNC_ENTER_TIMER, _lowcore, sync_enter_timer); - OFFSET(__LC_ASYNC_ENTER_TIMER, _lowcore, async_enter_timer); - OFFSET(__LC_MCCK_ENTER_TIMER, _lowcore, mcck_enter_timer); - OFFSET(__LC_EXIT_TIMER, _lowcore, exit_timer); - OFFSET(__LC_USER_TIMER, _lowcore, user_timer); - OFFSET(__LC_SYSTEM_TIMER, _lowcore, system_timer); - OFFSET(__LC_STEAL_TIMER, _lowcore, steal_timer); - OFFSET(__LC_LAST_UPDATE_TIMER, _lowcore, last_update_timer); - OFFSET(__LC_LAST_UPDATE_CLOCK, _lowcore, last_update_clock); - OFFSET(__LC_INT_CLOCK, _lowcore, int_clock); - OFFSET(__LC_MCCK_CLOCK, _lowcore, mcck_clock); - OFFSET(__LC_CURRENT, _lowcore, current_task); - OFFSET(__LC_THREAD_INFO, _lowcore, thread_info); - OFFSET(__LC_KERNEL_STACK, _lowcore, kernel_stack); - OFFSET(__LC_ASYNC_STACK, _lowcore, async_stack); - OFFSET(__LC_PANIC_STACK, _lowcore, panic_stack); - OFFSET(__LC_RESTART_STACK, _lowcore, restart_stack); - OFFSET(__LC_RESTART_FN, _lowcore, restart_fn); - OFFSET(__LC_RESTART_DATA, _lowcore, restart_data); - OFFSET(__LC_RESTART_SOURCE, _lowcore, restart_source); - OFFSET(__LC_USER_ASCE, _lowcore, user_asce); - OFFSET(__LC_LPP, _lowcore, lpp); - OFFSET(__LC_CURRENT_PID, _lowcore, current_pid); - OFFSET(__LC_PERCPU_OFFSET, _lowcore, percpu_offset); - OFFSET(__LC_VDSO_PER_CPU, _lowcore, vdso_per_cpu_data); - OFFSET(__LC_MACHINE_FLAGS, _lowcore, machine_flags); - OFFSET(__LC_GMAP, _lowcore, gmap); - OFFSET(__LC_PASTE, _lowcore, paste); + OFFSET(__LC_SAVE_AREA_SYNC, lowcore, save_area_sync); + OFFSET(__LC_SAVE_AREA_ASYNC, lowcore, save_area_async); + OFFSET(__LC_SAVE_AREA_RESTART, lowcore, save_area_restart); + OFFSET(__LC_CPU_FLAGS, lowcore, cpu_flags); + OFFSET(__LC_RETURN_PSW, lowcore, return_psw); + OFFSET(__LC_RETURN_MCCK_PSW, lowcore, return_mcck_psw); + OFFSET(__LC_SYNC_ENTER_TIMER, lowcore, sync_enter_timer); + OFFSET(__LC_ASYNC_ENTER_TIMER, lowcore, async_enter_timer); + OFFSET(__LC_MCCK_ENTER_TIMER, lowcore, mcck_enter_timer); + OFFSET(__LC_EXIT_TIMER, lowcore, exit_timer); + OFFSET(__LC_USER_TIMER, lowcore, user_timer); + OFFSET(__LC_SYSTEM_TIMER, lowcore, system_timer); + OFFSET(__LC_STEAL_TIMER, lowcore, steal_timer); + OFFSET(__LC_LAST_UPDATE_TIMER, lowcore, last_update_timer); + OFFSET(__LC_LAST_UPDATE_CLOCK, lowcore, last_update_clock); + OFFSET(__LC_INT_CLOCK, lowcore, int_clock); + OFFSET(__LC_MCCK_CLOCK, lowcore, mcck_clock); + OFFSET(__LC_CURRENT, lowcore, current_task); + OFFSET(__LC_THREAD_INFO, lowcore, thread_info); + OFFSET(__LC_KERNEL_STACK, lowcore, kernel_stack); + OFFSET(__LC_ASYNC_STACK, lowcore, async_stack); + OFFSET(__LC_PANIC_STACK, lowcore, panic_stack); + OFFSET(__LC_RESTART_STACK, lowcore, restart_stack); + OFFSET(__LC_RESTART_FN, lowcore, restart_fn); + OFFSET(__LC_RESTART_DATA, lowcore, restart_data); + OFFSET(__LC_RESTART_SOURCE, lowcore, restart_source); + OFFSET(__LC_USER_ASCE, lowcore, user_asce); + OFFSET(__LC_LPP, lowcore, lpp); + OFFSET(__LC_CURRENT_PID, lowcore, current_pid); + OFFSET(__LC_PERCPU_OFFSET, lowcore, percpu_offset); + OFFSET(__LC_VDSO_PER_CPU, lowcore, vdso_per_cpu_data); + OFFSET(__LC_MACHINE_FLAGS, lowcore, machine_flags); + OFFSET(__LC_GMAP, lowcore, gmap); + OFFSET(__LC_PASTE, lowcore, paste); /* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */ - OFFSET(__LC_DUMP_REIPL, _lowcore, ipib); + OFFSET(__LC_DUMP_REIPL, lowcore, ipib); /* hardware defined lowcore locations 0x1000 - 0x18ff */ - OFFSET(__LC_VX_SAVE_AREA_ADDR, _lowcore, vector_save_area_addr); - OFFSET(__LC_EXT_PARAMS2, _lowcore, ext_params2); - OFFSET(__LC_FPREGS_SAVE_AREA, _lowcore, floating_pt_save_area); - OFFSET(__LC_GPREGS_SAVE_AREA, _lowcore, gpregs_save_area); - OFFSET(__LC_PSW_SAVE_AREA, _lowcore, psw_save_area); - OFFSET(__LC_PREFIX_SAVE_AREA, _lowcore, prefixreg_save_area); - OFFSET(__LC_FP_CREG_SAVE_AREA, _lowcore, fpt_creg_save_area); - OFFSET(__LC_TOD_PROGREG_SAVE_AREA, _lowcore, tod_progreg_save_area); - OFFSET(__LC_CPU_TIMER_SAVE_AREA, _lowcore, cpu_timer_save_area); - OFFSET(__LC_CLOCK_COMP_SAVE_AREA, _lowcore, clock_comp_save_area); - OFFSET(__LC_AREGS_SAVE_AREA, _lowcore, access_regs_save_area); - OFFSET(__LC_CREGS_SAVE_AREA, _lowcore, cregs_save_area); - OFFSET(__LC_PGM_TDB, _lowcore, pgm_tdb); + OFFSET(__LC_VX_SAVE_AREA_ADDR, lowcore, vector_save_area_addr); + OFFSET(__LC_EXT_PARAMS2, lowcore, ext_params2); + OFFSET(__LC_FPREGS_SAVE_AREA, lowcore, floating_pt_save_area); + OFFSET(__LC_GPREGS_SAVE_AREA, lowcore, gpregs_save_area); + OFFSET(__LC_PSW_SAVE_AREA, lowcore, psw_save_area); + OFFSET(__LC_PREFIX_SAVE_AREA, lowcore, prefixreg_save_area); + OFFSET(__LC_FP_CREG_SAVE_AREA, lowcore, fpt_creg_save_area); + OFFSET(__LC_TOD_PROGREG_SAVE_AREA, lowcore, tod_progreg_save_area); + OFFSET(__LC_CPU_TIMER_SAVE_AREA, lowcore, cpu_timer_save_area); + OFFSET(__LC_CLOCK_COMP_SAVE_AREA, lowcore, clock_comp_save_area); + OFFSET(__LC_AREGS_SAVE_AREA, lowcore, access_regs_save_area); + OFFSET(__LC_CREGS_SAVE_AREA, lowcore, cregs_save_area); + OFFSET(__LC_PGM_TDB, lowcore, pgm_tdb); BLANK(); /* gmap/sie offsets */ OFFSET(__GMAP_ASCE, gmap, asce); diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index 823ed6ab53c84..a92b39fd0e63d 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -83,9 +83,9 @@ struct save_area * __init save_area_boot_cpu(void) */ void __init save_area_add_regs(struct save_area *sa, void *regs) { - struct _lowcore *lc; + struct lowcore *lc; - lc = (struct _lowcore *)(regs - __LC_FPREGS_SAVE_AREA); + lc = (struct lowcore *)(regs - __LC_FPREGS_SAVE_AREA); memcpy(&sa->psw, &lc->psw_save_area, sizeof(sa->psw)); memcpy(&sa->ctrs, &lc->cregs_save_area, sizeof(sa->ctrs)); memcpy(&sa->gprs, &lc->gpregs_save_area, sizeof(sa->gprs)); diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 26d58cf725738..0a5a6b661b938 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -2041,9 +2041,9 @@ static void do_reset_calls(void) void s390_reset_system(void) { - struct _lowcore *lc; + struct lowcore *lc; - lc = (struct _lowcore *)(unsigned long) store_prefix(); + lc = (struct lowcore *)(unsigned long) store_prefix(); /* Stack for interrupt/machine check handler */ lc->panic_stack = S390_lowcore.panic_stack; diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 22756bb0819e6..ea2454d5dcba6 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -97,7 +97,7 @@ unsigned long MODULES_VADDR; unsigned long MODULES_END; /* An array with a pointer to the lowcore of every CPU. */ -struct _lowcore *lowcore_ptr[NR_CPUS]; +struct lowcore *lowcore_ptr[NR_CPUS]; EXPORT_SYMBOL(lowcore_ptr); /* @@ -291,12 +291,12 @@ void *restart_stack __attribute__((__section__(".data"))); static void __init setup_lowcore(void) { - struct _lowcore *lc; + struct lowcore *lc; /* * Setup lowcore for boot cpu */ - BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096); + BUILD_BUG_ON(sizeof(struct lowcore) != LC_PAGES * 4096); lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0); lc->restart_psw.mask = PSW_KERNEL_BITS; lc->restart_psw.addr = diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 654c36ec0c603..a13468b9a9133 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -64,7 +64,7 @@ enum { static DEFINE_PER_CPU(struct cpu *, cpu_device); struct pcpu { - struct _lowcore *lowcore; /* lowcore page(s) for the cpu */ + struct lowcore *lowcore; /* lowcore page(s) for the cpu */ unsigned long ec_mask; /* bit mask for ec_xxx functions */ unsigned long ec_clk; /* sigp timestamp for ec_xxx */ signed char state; /* physical cpu state */ @@ -185,10 +185,10 @@ static void pcpu_ec_call(struct pcpu *pcpu, int ec_bit) static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu) { unsigned long async_stack, panic_stack; - struct _lowcore *lc; + struct lowcore *lc; if (pcpu != &pcpu_devices[0]) { - pcpu->lowcore = (struct _lowcore *) + pcpu->lowcore = (struct lowcore *) __get_free_pages(GFP_KERNEL | GFP_DMA, LC_ORDER); async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); panic_stack = __get_free_page(GFP_KERNEL); @@ -240,7 +240,7 @@ static void pcpu_free_lowcore(struct pcpu *pcpu) static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu) { - struct _lowcore *lc = pcpu->lowcore; + struct lowcore *lc = pcpu->lowcore; if (MACHINE_HAS_TLB_LC) cpumask_set_cpu(cpu, &init_mm.context.cpu_attach_mask); @@ -260,7 +260,7 @@ static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu) static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk) { - struct _lowcore *lc = pcpu->lowcore; + struct lowcore *lc = pcpu->lowcore; struct thread_info *ti = task_thread_info(tsk); lc->kernel_stack = (unsigned long) task_stack_page(tsk) @@ -276,7 +276,7 @@ static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk) static void pcpu_start_fn(struct pcpu *pcpu, void (*func)(void *), void *data) { - struct _lowcore *lc = pcpu->lowcore; + struct lowcore *lc = pcpu->lowcore; lc->restart_stack = lc->kernel_stack; lc->restart_fn = (unsigned long) func; @@ -291,7 +291,7 @@ static void pcpu_start_fn(struct pcpu *pcpu, void (*func)(void *), void *data) static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *), void *data, unsigned long stack) { - struct _lowcore *lc = lowcore_ptr[pcpu - pcpu_devices]; + struct lowcore *lc = lowcore_ptr[pcpu - pcpu_devices]; unsigned long source_cpu = stap(); __load_psw_mask(PSW_KERNEL_BITS); @@ -923,7 +923,7 @@ void __init smp_prepare_boot_cpu(void) pcpu->state = CPU_STATE_CONFIGURED; pcpu->address = stap(); - pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix(); + pcpu->lowcore = (struct lowcore *)(unsigned long) store_prefix(); S390_lowcore.percpu_offset = __per_cpu_offset[0]; smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN); set_cpu_present(0, true); diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index 59eddb0e1a3e8..4f07eaced9606 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c @@ -90,7 +90,7 @@ static void vdso_init_data(struct vdso_data *vd) */ #define SEGMENT_ORDER 2 -int vdso_alloc_per_cpu(struct _lowcore *lowcore) +int vdso_alloc_per_cpu(struct lowcore *lowcore) { unsigned long segment_table, page_table, page_frame; u32 *psal, *aste; @@ -138,7 +138,7 @@ out: return -ENOMEM; } -void vdso_free_per_cpu(struct _lowcore *lowcore) +void vdso_free_per_cpu(struct lowcore *lowcore) { unsigned long segment_table, page_table, page_frame; u32 *psal, *aste; @@ -163,7 +163,7 @@ static void vdso_init_cr5(void) if (!vdso_enabled) return; - cr5 = offsetof(struct _lowcore, paste); + cr5 = offsetof(struct lowcore, paste); __ctl_load(cr5, 5, 5); } diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 6a75352f453c1..cbad2e6d7dd72 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -399,9 +399,9 @@ static int __must_check __deliver_restart(struct kvm_vcpu *vcpu) trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_RESTART, 0, 0); rc = write_guest_lc(vcpu, - offsetof(struct _lowcore, restart_old_psw), + offsetof(struct lowcore, restart_old_psw), &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); - rc |= read_guest_lc(vcpu, offsetof(struct _lowcore, restart_psw), + rc |= read_guest_lc(vcpu, offsetof(struct lowcore, restart_psw), &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); clear_bit(IRQ_PEND_RESTART, &li->pending_irqs); return rc ? -EFAULT : 0; diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index d76b51cb4b620..ed74e86d9b9eb 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -355,7 +355,7 @@ static int handle_stfl(struct kvm_vcpu *vcpu) * into a u32 memory representation. They will remain bits 0-31. */ fac = *vcpu->kvm->arch.model.fac->list >> 32; - rc = write_guest_lc(vcpu, offsetof(struct _lowcore, stfl_fac_list), + rc = write_guest_lc(vcpu, offsetof(struct lowcore, stfl_fac_list), &fac, sizeof(fac)); if (rc) return rc; diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index 8a993a53fcd61..fec59c067d0dd 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c @@ -163,11 +163,11 @@ static int is_swapped(unsigned long addr) unsigned long lc; int cpu; - if (addr < sizeof(struct _lowcore)) + if (addr < sizeof(struct lowcore)) return 1; for_each_online_cpu(cpu) { lc = (unsigned long) lowcore_ptr[cpu]; - if (addr > lc + sizeof(struct _lowcore) - 1 || addr < lc) + if (addr > lc + sizeof(struct lowcore) - 1 || addr < lc) continue; return 1; } -- GitLab From 0dab3e0e59ac3692e2f95cb37ba17d5dfb3d1e5f Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 5 Jan 2016 18:17:53 +0200 Subject: [PATCH 2430/2855] s390: drop smp_mb in vdso_init The initial s390 vdso code is heavily influenced by the powerpc version which does have a smp_wmb in vdso_init right before the vdso_ready=1 assignment. s390 has no need for that. Signed-off-by: Michael S. Tsirkin Message-Id: <1452010645-25380-1-git-send-email-mst@redhat.com> Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/vdso.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index 4f07eaced9606..604f4a68b524e 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c @@ -299,8 +299,6 @@ static int __init vdso_init(void) get_page(virt_to_page(vdso_data)); - smp_mb(); - return 0; } early_initcall(vdso_init); -- GitLab From 8c31902cffc4d716450be549c66a67a8a3dd479c Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 4 Jan 2016 10:17:09 -0800 Subject: [PATCH 2431/2855] x86/boot: Double BOOT_HEAP_SIZE to 64KB When decompressing kernel image during x86 bootup, malloc memory for ELF program headers may run out of heap space, which leads to system halt. This patch doubles BOOT_HEAP_SIZE to 64KB. Tested with 32-bit kernel which failed to boot without this patch. Signed-off-by: H.J. Lu Acked-by: H. Peter Anvin Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-kernel@vger.kernel.org Cc: Signed-off-by: Ingo Molnar --- arch/x86/include/asm/boot.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h index 4fa687a47a62d..6b8d6e8cd4494 100644 --- a/arch/x86/include/asm/boot.h +++ b/arch/x86/include/asm/boot.h @@ -27,7 +27,7 @@ #define BOOT_HEAP_SIZE 0x400000 #else /* !CONFIG_KERNEL_BZIP2 */ -#define BOOT_HEAP_SIZE 0x8000 +#define BOOT_HEAP_SIZE 0x10000 #endif /* !CONFIG_KERNEL_BZIP2 */ -- GitLab From 249c543b97e1409b13fb9539b2f880e58ddd87cf Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Tue, 5 Jan 2016 13:29:38 +0100 Subject: [PATCH 2432/2855] s390/vdso: optimize getcpu system call Add the CPU number to the per-cpu vdso data page and add the __kernel_getcpu function to the vdso object to retrieve the CPU number in user space. Suggested-by: Heiko Carstens Reviewed-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/vdso.h | 2 ++ arch/s390/kernel/asm-offsets.c | 2 ++ arch/s390/kernel/vdso.c | 9 +++++- arch/s390/kernel/vdso32/Makefile | 2 +- arch/s390/kernel/vdso32/getcpu.S | 43 ++++++++++++++++++++++++++++ arch/s390/kernel/vdso32/vdso32.lds.S | 1 + arch/s390/kernel/vdso64/Makefile | 2 +- arch/s390/kernel/vdso64/getcpu.S | 42 +++++++++++++++++++++++++++ arch/s390/kernel/vdso64/vdso64.lds.S | 1 + 9 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 arch/s390/kernel/vdso32/getcpu.S create mode 100644 arch/s390/kernel/vdso64/getcpu.S diff --git a/arch/s390/include/asm/vdso.h b/arch/s390/include/asm/vdso.h index f9b02d300d60b..d0a2dbf2433d0 100644 --- a/arch/s390/include/asm/vdso.h +++ b/arch/s390/include/asm/vdso.h @@ -38,6 +38,8 @@ struct vdso_data { struct vdso_per_cpu_data { __u64 ectg_timer_base; __u64 ectg_user_time; + __u32 cpu_nr; + __u32 node_id; }; extern struct vdso_data *vdso_data; diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index d5916ef9c619c..53bbc9e8b281f 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -80,6 +80,8 @@ int main(void) OFFSET(__VDSO_TK_SHIFT, vdso_data, tk_shift); OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base); OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time); + OFFSET(__VDSO_CPU_NR, vdso_per_cpu_data, cpu_nr); + OFFSET(__VDSO_NODE_ID, vdso_per_cpu_data, node_id); BLANK(); /* constants used by the vdso */ DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME); diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index 604f4a68b524e..94495cac8be37 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c @@ -80,7 +80,7 @@ struct vdso_data *vdso_data = &vdso_data_store.data; /* * Setup vdso data page. */ -static void vdso_init_data(struct vdso_data *vd) +static void __init vdso_init_data(struct vdso_data *vd) { vd->ectg_available = test_facility(31); } @@ -93,6 +93,7 @@ static void vdso_init_data(struct vdso_data *vd) int vdso_alloc_per_cpu(struct lowcore *lowcore) { unsigned long segment_table, page_table, page_frame; + struct vdso_per_cpu_data *vd; u32 *psal, *aste; int i; @@ -107,6 +108,12 @@ int vdso_alloc_per_cpu(struct lowcore *lowcore) if (!segment_table || !page_table || !page_frame) goto out; + /* Initialize per-cpu vdso data page */ + vd = (struct vdso_per_cpu_data *) page_frame; + vd->cpu_nr = lowcore->cpu_nr; + vd->node_id = cpu_to_node(vd->cpu_nr); + + /* Set up access register mode page table */ clear_table((unsigned long *) segment_table, _SEGMENT_ENTRY_EMPTY, PAGE_SIZE << SEGMENT_ORDER); clear_table((unsigned long *) page_table, _PAGE_INVALID, diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile index ee8a18e50a250..f9c459586649a 100644 --- a/arch/s390/kernel/vdso32/Makefile +++ b/arch/s390/kernel/vdso32/Makefile @@ -1,6 +1,6 @@ # List of files in the vdso, has to be asm only for now -obj-vdso32 = gettimeofday.o clock_getres.o clock_gettime.o note.o +obj-vdso32 = gettimeofday.o clock_getres.o clock_gettime.o note.o getcpu.o # Build rules diff --git a/arch/s390/kernel/vdso32/getcpu.S b/arch/s390/kernel/vdso32/getcpu.S new file mode 100644 index 0000000000000..c1ed0b72030f5 --- /dev/null +++ b/arch/s390/kernel/vdso32/getcpu.S @@ -0,0 +1,43 @@ +/* + * Userland implementation of getcpu() for 32 bits processes in a + * s390 kernel for use in the vDSO + * + * Copyright IBM Corp. 2016 + * Author(s): Martin Schwidefsky + */ +#include +#include + + .text + .align 4 + .globl __kernel_getcpu + .type __kernel_getcpu,@function +__kernel_getcpu: + .cfi_startproc + ear %r1,%a4 + lhi %r4,1 + sll %r4,24 + sar %a4,%r4 + la %r4,0 + epsw %r0,0 + sacf 512 + l %r5,__VDSO_CPU_NR(%r4) + l %r4,__VDSO_NODE_ID(%r4) + tml %r0,0x4000 + jo 1f + tml %r0,0x8000 + jno 0f + sacf 256 + j 1f +0: sacf 0 +1: sar %a4,%r1 + ltr %r2,%r2 + jz 2f + st %r5,0(%r2) +2: ltr %r3,%r3 + jz 3f + st %r4,0(%r3) +3: lhi %r2,0 + br %r14 + .cfi_endproc + .size __kernel_getcpu,.-__kernel_getcpu diff --git a/arch/s390/kernel/vdso32/vdso32.lds.S b/arch/s390/kernel/vdso32/vdso32.lds.S index a8c379fa12478..8f048c2d6d138 100644 --- a/arch/s390/kernel/vdso32/vdso32.lds.S +++ b/arch/s390/kernel/vdso32/vdso32.lds.S @@ -132,6 +132,7 @@ VERSION __kernel_gettimeofday; __kernel_clock_gettime; __kernel_clock_getres; + __kernel_getcpu; local: *; }; diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile index c4b03f9ed2282..058659c1b8cff 100644 --- a/arch/s390/kernel/vdso64/Makefile +++ b/arch/s390/kernel/vdso64/Makefile @@ -1,6 +1,6 @@ # List of files in the vdso, has to be asm only for now -obj-vdso64 = gettimeofday.o clock_getres.o clock_gettime.o note.o +obj-vdso64 = gettimeofday.o clock_getres.o clock_gettime.o note.o getcpu.o # Build rules diff --git a/arch/s390/kernel/vdso64/getcpu.S b/arch/s390/kernel/vdso64/getcpu.S new file mode 100644 index 0000000000000..4cbe982919314 --- /dev/null +++ b/arch/s390/kernel/vdso64/getcpu.S @@ -0,0 +1,42 @@ +/* + * Userland implementation of getcpu() for 64 bits processes in a + * s390 kernel for use in the vDSO + * + * Copyright IBM Corp. 2016 + * Author(s): Martin Schwidefsky + */ +#include +#include + + .text + .align 4 + .globl __kernel_getcpu + .type __kernel_getcpu,@function +__kernel_getcpu: + .cfi_startproc + ear %r1,%a4 + llilh %r4,0x0100 + sar %a4,%r4 + la %r4,0 + epsw %r0,0 + sacf 512 + l %r5,__VDSO_CPU_NR(%r4) + l %r4,__VDSO_NODE_ID(%r4) + tml %r0,0x4000 + jo 1f + tml %r0,0x8000 + jno 0f + sacf 256 + j 1f +0: sacf 0 +1: sar %a4,%r1 + ltgr %r2,%r2 + jz 2f + st %r5,0(%r2) +2: ltgr %r3,%r3 + jz 3f + st %r4,0(%r3) +3: lghi %r2,0 + br %r14 + .cfi_endproc + .size __kernel_getcpu,.-__kernel_getcpu diff --git a/arch/s390/kernel/vdso64/vdso64.lds.S b/arch/s390/kernel/vdso64/vdso64.lds.S index 9f5979d102a90..f35455d497fef 100644 --- a/arch/s390/kernel/vdso64/vdso64.lds.S +++ b/arch/s390/kernel/vdso64/vdso64.lds.S @@ -132,6 +132,7 @@ VERSION __kernel_gettimeofday; __kernel_clock_gettime; __kernel_clock_getres; + __kernel_getcpu; local: *; }; -- GitLab From cb14def6a9cae973ba6f702443c8fc589998279c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 2 Jul 2015 17:30:31 +0200 Subject: [PATCH 2433/2855] s390/configs: update default configurations Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/configs/default_defconfig | 27 ++++++++++------------ arch/s390/configs/gcov_defconfig | 24 +++++++++----------- arch/s390/configs/performance_defconfig | 24 +++++++++----------- arch/s390/configs/zfcpdump_defconfig | 10 ++------- arch/s390/defconfig | 30 ++++++++++++++++++++++--- 5 files changed, 61 insertions(+), 54 deletions(-) diff --git a/arch/s390/configs/default_defconfig b/arch/s390/configs/default_defconfig index ed7da281df667..0ac42cc4f8807 100644 --- a/arch/s390/configs/default_defconfig +++ b/arch/s390/configs/default_defconfig @@ -10,28 +10,35 @@ CONFIG_TASKSTATS=y CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y -CONFIG_RCU_FAST_NO_HZ=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_NUMA_BALANCING=y CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_PIDS=y CONFIG_CGROUP_DEVICE=y CONFIG_CPUSETS=y CONFIG_CGROUP_CPUACCT=y +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +CONFIG_MEMCG_KMEM=y +CONFIG_CGROUP_HUGETLB=y CONFIG_CGROUP_PERF=y CONFIG_CFS_BANDWIDTH=y CONFIG_RT_GROUP_SCHED=y CONFIG_BLK_CGROUP=y CONFIG_NAMESPACES=y +CONFIG_USER_NS=y CONFIG_SCHED_AUTOGROUP=y CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y CONFIG_BPF_SYSCALL=y +CONFIG_USERFAULTFD=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y CONFIG_OPROFILE=m CONFIG_KPROBES=y CONFIG_JUMP_LABEL=y +CONFIG_STATIC_KEYS_SELFTEST=y CONFIG_MODULES=y CONFIG_MODULE_FORCE_LOAD=y CONFIG_MODULE_UNLOAD=y @@ -64,7 +71,6 @@ CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_S390=y CONFIG_CHSC_SCH=y CONFIG_CRASH_DUMP=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_MISC=m CONFIG_HIBERNATION=y CONFIG_NET=y @@ -106,7 +112,6 @@ CONFIG_TCP_CONG_LP=m CONFIG_TCP_CONG_VENO=m CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_ILLINOIS=m -CONFIG_IPV6=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m @@ -457,19 +462,9 @@ CONFIG_INFINIBAND=m CONFIG_INFINIBAND_USER_ACCESS=m CONFIG_MLX4_INFINIBAND=m CONFIG_VIRTIO_BALLOON=m -# CONFIG_IOMMU_SUPPORT is not set -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y -CONFIG_JBD_DEBUG=y CONFIG_JBD2_DEBUG=y CONFIG_JFS_FS=m CONFIG_JFS_POSIX_ACL=y @@ -490,7 +485,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QFMT_V1=m CONFIG_QFMT_V2=m CONFIG_AUTOFS4_FS=m -CONFIG_FUSE_FS=m +CONFIG_FUSE_FS=y CONFIG_CUSE=m CONFIG_FSCACHE=m CONFIG_CACHEFILES=m @@ -542,10 +537,11 @@ CONFIG_DLM=m CONFIG_PRINTK_TIME=y CONFIG_DYNAMIC_DEBUG=y CONFIG_DEBUG_INFO=y -# CONFIG_ENABLE_MUST_CHECK is not set CONFIG_FRAME_WARN=1024 CONFIG_READABLE_ASM=y CONFIG_UNUSED_SYMBOLS=y +CONFIG_HEADERS_CHECK=y +CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_PAGEALLOC=y CONFIG_DEBUG_OBJECTS=y @@ -588,6 +584,7 @@ CONFIG_FAILSLAB=y CONFIG_FAIL_PAGE_ALLOC=y CONFIG_FAIL_MAKE_REQUEST=y CONFIG_FAIL_IO_TIMEOUT=y +CONFIG_FAIL_FUTEX=y CONFIG_FAULT_INJECTION_DEBUG_FS=y CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y CONFIG_LATENCYTOP=y diff --git a/arch/s390/configs/gcov_defconfig b/arch/s390/configs/gcov_defconfig index 9858b14cde1ed..a31dcd56f7c06 100644 --- a/arch/s390/configs/gcov_defconfig +++ b/arch/s390/configs/gcov_defconfig @@ -10,21 +10,27 @@ CONFIG_TASKSTATS=y CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y -CONFIG_RCU_FAST_NO_HZ=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_NUMA_BALANCING=y CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_PIDS=y CONFIG_CGROUP_DEVICE=y CONFIG_CPUSETS=y CONFIG_CGROUP_CPUACCT=y +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +CONFIG_MEMCG_KMEM=y +CONFIG_CGROUP_HUGETLB=y CONFIG_CGROUP_PERF=y CONFIG_BLK_CGROUP=y CONFIG_NAMESPACES=y +CONFIG_USER_NS=y CONFIG_SCHED_AUTOGROUP=y CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y CONFIG_BPF_SYSCALL=y +CONFIG_USERFAULTFD=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y CONFIG_OPROFILE=m @@ -61,7 +67,6 @@ CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_S390=y CONFIG_CHSC_SCH=y CONFIG_CRASH_DUMP=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_MISC=m CONFIG_HIBERNATION=y CONFIG_NET=y @@ -103,7 +108,6 @@ CONFIG_TCP_CONG_LP=m CONFIG_TCP_CONG_VENO=m CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_ILLINOIS=m -CONFIG_IPV6=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m @@ -453,19 +457,9 @@ CONFIG_INFINIBAND=m CONFIG_INFINIBAND_USER_ACCESS=m CONFIG_MLX4_INFINIBAND=m CONFIG_VIRTIO_BALLOON=m -# CONFIG_IOMMU_SUPPORT is not set -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y -CONFIG_JBD_DEBUG=y CONFIG_JBD2_DEBUG=y CONFIG_JFS_FS=m CONFIG_JFS_POSIX_ACL=y @@ -485,7 +479,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QFMT_V1=m CONFIG_QFMT_V2=m CONFIG_AUTOFS4_FS=m -CONFIG_FUSE_FS=m +CONFIG_FUSE_FS=y CONFIG_CUSE=m CONFIG_FSCACHE=m CONFIG_CACHEFILES=m @@ -550,6 +544,7 @@ CONFIG_NOTIFIER_ERROR_INJECTION=m CONFIG_CPU_NOTIFIER_ERROR_INJECT=m CONFIG_PM_NOTIFIER_ERROR_INJECT=m CONFIG_LATENCYTOP=y +CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y CONFIG_BLK_DEV_IO_TRACE=y # CONFIG_KPROBE_EVENT is not set CONFIG_LKDTM=m @@ -557,6 +552,7 @@ CONFIG_RBTREE_TEST=m CONFIG_INTERVAL_TREE_TEST=m CONFIG_PERCPU_TEST=m CONFIG_ATOMIC64_SELFTEST=y +CONFIG_TEST_BPF=m # CONFIG_STRICT_DEVMEM is not set CONFIG_S390_PTDUMP=y CONFIG_ENCRYPTED_KEYS=m diff --git a/arch/s390/configs/performance_defconfig b/arch/s390/configs/performance_defconfig index 7f14f80717d49..7b73bf3533454 100644 --- a/arch/s390/configs/performance_defconfig +++ b/arch/s390/configs/performance_defconfig @@ -10,22 +10,28 @@ CONFIG_TASKSTATS=y CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y -CONFIG_RCU_FAST_NO_HZ=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_NUMA_BALANCING=y # CONFIG_NUMA_BALANCING_DEFAULT_ENABLED is not set CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_PIDS=y CONFIG_CGROUP_DEVICE=y CONFIG_CPUSETS=y CONFIG_CGROUP_CPUACCT=y +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +CONFIG_MEMCG_KMEM=y +CONFIG_CGROUP_HUGETLB=y CONFIG_CGROUP_PERF=y CONFIG_BLK_CGROUP=y CONFIG_NAMESPACES=y +CONFIG_USER_NS=y CONFIG_SCHED_AUTOGROUP=y CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y CONFIG_BPF_SYSCALL=y +CONFIG_USERFAULTFD=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y CONFIG_OPROFILE=m @@ -61,7 +67,6 @@ CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_S390=y CONFIG_CHSC_SCH=y CONFIG_CRASH_DUMP=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_MISC=m CONFIG_HIBERNATION=y CONFIG_NET=y @@ -103,7 +108,6 @@ CONFIG_TCP_CONG_LP=m CONFIG_TCP_CONG_VENO=m CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_ILLINOIS=m -CONFIG_IPV6=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m @@ -453,19 +457,9 @@ CONFIG_INFINIBAND=m CONFIG_INFINIBAND_USER_ACCESS=m CONFIG_MLX4_INFINIBAND=m CONFIG_VIRTIO_BALLOON=m -# CONFIG_IOMMU_SUPPORT is not set -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y -CONFIG_JBD_DEBUG=y CONFIG_JBD2_DEBUG=y CONFIG_JFS_FS=m CONFIG_JFS_POSIX_ACL=y @@ -485,7 +479,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QFMT_V1=m CONFIG_QFMT_V2=m CONFIG_AUTOFS4_FS=m -CONFIG_FUSE_FS=m +CONFIG_FUSE_FS=y CONFIG_CUSE=m CONFIG_FSCACHE=m CONFIG_CACHEFILES=m @@ -546,6 +540,7 @@ CONFIG_TIMER_STATS=y CONFIG_RCU_TORTURE_TEST=m CONFIG_RCU_CPU_STALL_TIMEOUT=60 CONFIG_LATENCYTOP=y +CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y CONFIG_SCHED_TRACER=y CONFIG_FTRACE_SYSCALLS=y CONFIG_STACK_TRACER=y @@ -554,6 +549,7 @@ CONFIG_UPROBE_EVENT=y CONFIG_LKDTM=m CONFIG_PERCPU_TEST=m CONFIG_ATOMIC64_SELFTEST=y +CONFIG_TEST_BPF=m # CONFIG_STRICT_DEVMEM is not set CONFIG_S390_PTDUMP=y CONFIG_ENCRYPTED_KEYS=m diff --git a/arch/s390/configs/zfcpdump_defconfig b/arch/s390/configs/zfcpdump_defconfig index 92805d6041735..1719843a55a2a 100644 --- a/arch/s390/configs/zfcpdump_defconfig +++ b/arch/s390/configs/zfcpdump_defconfig @@ -23,8 +23,6 @@ CONFIG_CRASH_DUMP=y # CONFIG_SECCOMP is not set CONFIG_NET=y # CONFIG_IUCV is not set -CONFIG_ATM=y -CONFIG_ATM_LANE=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set @@ -54,14 +52,10 @@ CONFIG_RAW_DRIVER=y # CONFIG_S390_VMUR is not set # CONFIG_HID is not set # CONFIG_IOMMU_SUPPORT is not set -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y +# CONFIG_DNOTIFY is not set # CONFIG_INOTIFY_USER is not set CONFIG_CONFIGFS_FS=y +# CONFIG_MISC_FILESYSTEMS is not set CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_FS=y diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 9256b48e7e439..e24f2af4c73b5 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -11,22 +11,31 @@ CONFIG_TASK_IO_ACCOUNTING=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_CGROUPS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_DEVICE=y CONFIG_CPUSETS=y CONFIG_CGROUP_CPUACCT=y CONFIG_MEMCG=y CONFIG_MEMCG_SWAP=y +CONFIG_MEMCG_KMEM=y +CONFIG_CGROUP_HUGETLB=y +CONFIG_CGROUP_PERF=y CONFIG_CGROUP_SCHED=y CONFIG_RT_GROUP_SCHED=y CONFIG_BLK_CGROUP=y CONFIG_NAMESPACES=y +CONFIG_USER_NS=y CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y CONFIG_BPF_SYSCALL=y +CONFIG_USERFAULTFD=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y CONFIG_OPROFILE=y CONFIG_KPROBES=y CONFIG_JUMP_LABEL=y +CONFIG_STATIC_KEYS_SELFTEST=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y @@ -37,6 +46,7 @@ CONFIG_DEFAULT_DEADLINE=y CONFIG_LIVEPATCH=y CONFIG_MARCH_Z196=y CONFIG_NR_CPUS=256 +CONFIG_NUMA=y CONFIG_HZ_100=y CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTREMOVE=y @@ -52,7 +62,6 @@ CONFIG_NET_KEY=y CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_INET_LRO is not set -CONFIG_IPV6=y CONFIG_L2TP=m CONFIG_L2TP_DEBUGFS=m CONFIG_VLAN_8021Q=y @@ -89,10 +98,26 @@ CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y -CONFIG_SCSI_SCAN_ASYNC=y CONFIG_SCSI_FC_ATTRS=y CONFIG_ZFCP=y CONFIG_SCSI_VIRTIO=y +CONFIG_MD=y +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_MULTIPATH=m +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_RAID=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_DM_UEVENT=y +CONFIG_DM_VERITY=m +CONFIG_DM_SWITCH=m CONFIG_NETDEVICES=y CONFIG_BONDING=m CONFIG_DUMMY=m @@ -137,7 +162,6 @@ CONFIG_DEBUG_PI_LIST=y CONFIG_DEBUG_SG=y CONFIG_DEBUG_NOTIFIERS=y CONFIG_RCU_CPU_STALL_TIMEOUT=60 -# CONFIG_RCU_CPU_STALL_INFO is not set CONFIG_RCU_TRACE=y CONFIG_LATENCYTOP=y CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y -- GitLab From bcb7825a77f41c7dd91da6f7ac10b928156a322e Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 1 Jan 2016 13:39:22 +0100 Subject: [PATCH 2434/2855] s390: fix normalization bug in exception table sorting The normalization pass in the sorting routine of the relative exception table serves two purposes: - it ensures that the address fields of the exception table entries are fully ordered, so that no ambiguities arise between entries with identical instruction offsets (i.e., when two instructions that are exactly 8 bytes apart each have an exception table entry associated with them) - it ensures that the offsets of both the instruction and the fixup fields of each entry are relative to their final location after sorting. Commit eb608fb366de ("s390/exceptions: switch to relative exception table entries") ported the relative exception table format from x86, but modified the sorting routine to only normalize the instruction offset field and not the fixup offset field. The result is that the fixup offset of each entry will be relative to the original location of the entry before sorting, likely leading to crashes when those entries are dereferenced. Fixes: eb608fb366de ("s390/exceptions: switch to relative exception table entries") Signed-off-by: Ard Biesheuvel Cc: Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/mm/extable.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/s390/mm/extable.c b/arch/s390/mm/extable.c index 4d1ee88864e8a..18c8b819b0aa9 100644 --- a/arch/s390/mm/extable.c +++ b/arch/s390/mm/extable.c @@ -52,12 +52,16 @@ void sort_extable(struct exception_table_entry *start, int i; /* Normalize entries to being relative to the start of the section */ - for (p = start, i = 0; p < finish; p++, i += 8) + for (p = start, i = 0; p < finish; p++, i += 8) { p->insn += i; + p->fixup += i + 4; + } sort(start, finish - start, sizeof(*start), cmp_ex, NULL); /* Denormalize all entries */ - for (p = start, i = 0; p < finish; p++, i += 8) + for (p = start, i = 0; p < finish; p++, i += 8) { p->insn -= i; + p->fixup -= i + 4; + } } #ifdef CONFIG_MODULES -- GitLab From c2ab7282f0fcd11eea4d0ba45d1c65d89428c314 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 7 Jan 2016 13:37:22 +0100 Subject: [PATCH 2435/2855] s390/sclp: fix possible control register corruption sclp_sync_wait() disables all external interrupt classes except for the service signal subclass. The static mask used for that however is wrong. It clears a couple of bits which shouldn't be cleared and on the other hand potentially does not clear bits which should be cleared. Fix this by using the same generic mask like we do it in our delay implementation. Signed-off-by: Heiko Carstens Reviewed-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky --- drivers/s390/char/sclp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index f58bf4c6c3ee5..272898225dbb4 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -579,9 +579,8 @@ sclp_sync_wait(void) old_tick = local_tick_disable(); trace_hardirqs_on(); __ctl_store(cr0, 0, 0); - cr0_sync = cr0; - cr0_sync &= 0xffff00a0; - cr0_sync |= 0x00000200; + cr0_sync = cr0 & ~CR0_IRQ_SUBCLASS_MASK; + cr0_sync |= 1UL << (63 - 54); __ctl_load(cr0_sync, 0, 0); __arch_local_irq_stosm(0x01); /* Loop until driver state indicates finished request */ -- GitLab From d062f91193dbd5a0c1d8469c8517ec8dd552c3f2 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Wed, 3 Jun 2015 12:12:53 -0300 Subject: [PATCH 2436/2855] [media] media: new media controller API for device resource support Add new media controller API to allocate media device as a device resource. When a media device is created on the main struct device which is the parent device for the interface device, it will be available to all drivers associated with that interface. For example, if a usb media device driver creates the media device on the main struct device which is common for all the drivers that control the media device, including the non-media ALSA driver, media controller API can be used to share access to the resources on the media device. This new interface provides the above described feature. A second interface that finds and returns the media device is added to allow drivers to find the media device created by any of the drivers associated with the device. Signed-off-by: Shuah Khan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 33 +++++++++++++++++++++++++++++++++ include/media/media-device.h | 2 ++ 2 files changed, 35 insertions(+) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 7b39440192d61..a4d5b2488c051 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -462,3 +462,36 @@ void media_device_unregister_entity(struct media_entity *entity) entity->parent = NULL; } EXPORT_SYMBOL_GPL(media_device_unregister_entity); + +static void media_device_release_devres(struct device *dev, void *res) +{ +} + +/* + * media_device_get_devres() - get media device as device resource + * creates if one doesn't exist +*/ +struct media_device *media_device_get_devres(struct device *dev) +{ + struct media_device *mdev; + + mdev = devres_find(dev, media_device_release_devres, NULL, NULL); + if (mdev) + return mdev; + + mdev = devres_alloc(media_device_release_devres, + sizeof(struct media_device), GFP_KERNEL); + if (!mdev) + return NULL; + return devres_get(dev, mdev, NULL, NULL); +} +EXPORT_SYMBOL_GPL(media_device_get_devres); + +/* + * media_device_find_devres() - find media device as device resource +*/ +struct media_device *media_device_find_devres(struct device *dev) +{ + return devres_find(dev, media_device_release_devres, NULL, NULL); +} +EXPORT_SYMBOL_GPL(media_device_find_devres); diff --git a/include/media/media-device.h b/include/media/media-device.h index 6e6db78f1ee2d..22792cd5b1d1a 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -95,6 +95,8 @@ void media_device_unregister(struct media_device *mdev); int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity); void media_device_unregister_entity(struct media_entity *entity); +struct media_device *media_device_get_devres(struct device *dev); +struct media_device *media_device_find_devres(struct device *dev); /* Iterate over all entities. */ #define media_device_for_each_entity(entity, mdev) \ -- GitLab From e576d60bb21e7add884f052ff0e5c28ebf7b7461 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Fri, 5 Jun 2015 17:11:54 -0300 Subject: [PATCH 2437/2855] [media] media: define Media Controller API when CONFIG_MEDIA_CONTROLLER enabled Change to define Media Controller API when CONFIG_MEDIA_CONTROLLER is enabled. Define stubs for CONFIG_MEDIA_CONTROLLER disabled case. This will help avoid drivers needing to enclose Media Controller code within ifdef CONFIG_MEDIA_CONTROLLER block. Signed-off-by: Shuah Khan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 4 ++++ include/media/media-device.h | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index a4d5b2488c051..c55ab5029323a 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -30,6 +30,8 @@ #include #include +#ifdef CONFIG_MEDIA_CONTROLLER + /* ----------------------------------------------------------------------------- * Userspace API */ @@ -495,3 +497,5 @@ struct media_device *media_device_find_devres(struct device *dev) return devres_find(dev, media_device_release_devres, NULL, NULL); } EXPORT_SYMBOL_GPL(media_device_find_devres); + +#endif /* CONFIG_MEDIA_CONTROLLER */ diff --git a/include/media/media-device.h b/include/media/media-device.h index 22792cd5b1d1a..a44f18fdf321d 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -80,6 +80,8 @@ struct media_device { unsigned int notification); }; +#ifdef CONFIG_MEDIA_CONTROLLER + /* Supported link_notify @notification values. */ #define MEDIA_DEV_NOTIFY_PRE_LINK_CH 0 #define MEDIA_DEV_NOTIFY_POST_LINK_CH 1 @@ -102,4 +104,29 @@ struct media_device *media_device_find_devres(struct device *dev); #define media_device_for_each_entity(entity, mdev) \ list_for_each_entry(entity, &(mdev)->entities, list) +#else +static inline int media_device_register(struct media_device *mdev) +{ + return 0; +} +static inline void media_device_unregister(struct media_device *mdev) +{ +} +static inline int media_device_register_entity(struct media_device *mdev, + struct media_entity *entity) +{ + return 0; +} +static inline void media_device_unregister_entity(struct media_entity *entity) +{ +} +static inline struct media_device *media_device_get_devres(struct device *dev) +{ + return NULL; +} +static inline struct media_device *media_device_find_devres(struct device *dev) +{ + return NULL; +} +#endif /* CONFIG_MEDIA_CONTROLLER */ #endif -- GitLab From bed6919665072b1e5bad31a013d53798394e097c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Louren=C3=A7o=20de=20Lima=20Chehab?= Date: Mon, 8 Jun 2015 22:20:46 -0300 Subject: [PATCH 2438/2855] [media] au0828: Add support for media controller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for analog and dvb tv using media controller. Signed-off-by: Rafael Lourenço de Lima Chehab Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/au8522_decoder.c | 17 ++++ drivers/media/dvb-frontends/au8522_priv.h | 12 +++ drivers/media/usb/au0828/au0828-core.c | 98 ++++++++++++++++++++ drivers/media/usb/au0828/au0828-dvb.c | 10 ++ drivers/media/usb/au0828/au0828-video.c | 83 +++++++++++++++++ drivers/media/usb/au0828/au0828.h | 6 ++ 6 files changed, 226 insertions(+) diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c index c8f13d8370e50..0a8882cb23c38 100644 --- a/drivers/media/dvb-frontends/au8522_decoder.c +++ b/drivers/media/dvb-frontends/au8522_decoder.c @@ -730,6 +730,9 @@ static int au8522_probe(struct i2c_client *client, struct v4l2_ctrl_handler *hdl; struct v4l2_subdev *sd; int instance; +#ifdef CONFIG_MEDIA_CONTROLLER + int ret; +#endif /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(client->adapter, @@ -758,6 +761,20 @@ static int au8522_probe(struct i2c_client *client, sd = &state->sd; v4l2_i2c_subdev_init(sd, client, &au8522_ops); +#if defined(CONFIG_MEDIA_CONTROLLER) + + state->pads[AU8522_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; + state->pads[AU8522_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; + state->pads[AU8522_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; + sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER; + + ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), + state->pads, 0); + if (ret < 0) { + v4l_info(client, "failed to initialize media entity!\n"); + return ret; + } +#endif hdl = &state->hdl; v4l2_ctrl_handler_init(hdl, 4); diff --git a/drivers/media/dvb-frontends/au8522_priv.h b/drivers/media/dvb-frontends/au8522_priv.h index ee330c61aa613..404a0cb0ed8d9 100644 --- a/drivers/media/dvb-frontends/au8522_priv.h +++ b/drivers/media/dvb-frontends/au8522_priv.h @@ -39,6 +39,14 @@ #define AU8522_DIGITAL_MODE 1 #define AU8522_SUSPEND_MODE 2 +enum au8522_media_pads { + AU8522_PAD_INPUT, + AU8522_PAD_VID_OUT, + AU8522_PAD_VBI_OUT, + + AU8522_NUM_PADS +}; + struct au8522_state { struct i2c_client *c; struct i2c_adapter *i2c; @@ -68,6 +76,10 @@ struct au8522_state { u32 id; u32 rev; struct v4l2_ctrl_handler hdl; + +#ifdef CONFIG_MEDIA_CONTROLLER + struct media_pad pads[AU8522_NUM_PADS]; +#endif }; /* These are routines shared by both the VSB/QAM demodulator and the analog diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 0934024fb89d3..0378a2c99ebb4 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -127,8 +127,22 @@ static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value, return status; } +static void au0828_unregister_media_device(struct au0828_dev *dev) +{ + +#ifdef CONFIG_MEDIA_CONTROLLER + if (dev->media_dev) { + media_device_unregister(dev->media_dev); + kfree(dev->media_dev); + dev->media_dev = NULL; + } +#endif +} + static void au0828_usb_release(struct au0828_dev *dev) { + au0828_unregister_media_device(dev); + /* I2C */ au0828_i2c_unregister(dev); @@ -161,6 +175,8 @@ static void au0828_usb_disconnect(struct usb_interface *interface) */ dev->dev_state = DEV_DISCONNECTED; + au0828_unregister_media_device(dev); + au0828_rc_unregister(dev); /* Digital TV */ au0828_dvb_unregister(dev); @@ -180,6 +196,81 @@ static void au0828_usb_disconnect(struct usb_interface *interface) au0828_usb_release(dev); } +static void au0828_media_device_register(struct au0828_dev *dev, + struct usb_device *udev) +{ +#ifdef CONFIG_MEDIA_CONTROLLER + struct media_device *mdev; + int ret; + + mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + if (!mdev) + return; + + mdev->dev = &udev->dev; + + if (!dev->board.name) + strlcpy(mdev->model, "unknown au0828", sizeof(mdev->model)); + else + strlcpy(mdev->model, dev->board.name, sizeof(mdev->model)); + if (udev->serial) + strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial)); + strcpy(mdev->bus_info, udev->devpath); + mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); + mdev->driver_version = LINUX_VERSION_CODE; + + ret = media_device_register(mdev); + if (ret) { + pr_err( + "Couldn't create a media device. Error: %d\n", + ret); + kfree(mdev); + return; + } + + dev->media_dev = mdev; +#endif +} + + +static void au0828_create_media_graph(struct au0828_dev *dev) +{ +#ifdef CONFIG_MEDIA_CONTROLLER + struct media_device *mdev = dev->media_dev; + struct media_entity *entity; + struct media_entity *tuner = NULL, *decoder = NULL; + + if (!mdev) + return; + + media_device_for_each_entity(entity, mdev) { + switch (entity->type) { + case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: + tuner = entity; + break; + case MEDIA_ENT_T_V4L2_SUBDEV_DECODER: + decoder = entity; + break; + } + } + + /* Analog setup, using tuner as a link */ + + if (!decoder) + return; + + if (tuner) + media_entity_create_link(tuner, 0, decoder, 0, + MEDIA_LNK_FL_ENABLED); + if (dev->vdev.entity.links) + media_entity_create_link(decoder, 1, &dev->vdev.entity, 0, + MEDIA_LNK_FL_ENABLED); + if (dev->vbi_dev.entity.links) + media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0, + MEDIA_LNK_FL_ENABLED); +#endif +} + static int au0828_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) { @@ -224,11 +315,16 @@ static int au0828_usb_probe(struct usb_interface *interface, dev->boardnr = id->driver_info; dev->board = au0828_boards[dev->boardnr]; + /* Register the media controller */ + au0828_media_device_register(dev, usbdev); #ifdef CONFIG_VIDEO_AU0828_V4L2 dev->v4l2_dev.release = au0828_usb_v4l2_release; /* Create the v4l2_device */ +#ifdef CONFIG_MEDIA_CONTROLLER + dev->v4l2_dev.mdev = dev->media_dev; +#endif retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); if (retval) { pr_err("%s() v4l2_device_register failed\n", @@ -287,6 +383,8 @@ static int au0828_usb_probe(struct usb_interface *interface, mutex_unlock(&dev->lock); + au0828_create_media_graph(dev); + return retval; } diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c index c267d76f5b3c5..c01772c4f9f07 100644 --- a/drivers/media/usb/au0828/au0828-dvb.c +++ b/drivers/media/usb/au0828/au0828-dvb.c @@ -415,6 +415,11 @@ static int dvb_register(struct au0828_dev *dev) result); goto fail_adapter; } + +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + dvb->adapter.mdev = dev->media_dev; +#endif + dvb->adapter.priv = dev; /* register frontend */ @@ -480,6 +485,11 @@ static int dvb_register(struct au0828_dev *dev) dvb->start_count = 0; dvb->stop_count = 0; + +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + dvb_create_media_graph(&dvb->adapter); +#endif + return 0; fail_fe_conn: diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 0a725a161dd6c..7aa7d509885bb 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -638,6 +638,75 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb) return rc; } +static int au0828_enable_analog_tuner(struct au0828_dev *dev) +{ +#ifdef CONFIG_MEDIA_CONTROLLER + struct media_device *mdev = dev->media_dev; + struct media_entity *entity, *decoder = NULL, *source; + struct media_link *link, *found_link = NULL; + int i, ret, active_links = 0; + + if (!mdev) + return 0; + + /* + * This will find the tuner that is connected into the decoder. + * Technically, this is not 100% correct, as the device may be + * using an analog input instead of the tuner. However, as we can't + * do DVB streaming while the DMA engine is being used for V4L2, + * this should be enough for the actual needs. + */ + media_device_for_each_entity(entity, mdev) { + if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_DECODER) { + decoder = entity; + break; + } + } + if (!decoder) + return 0; + + for (i = 0; i < decoder->num_links; i++) { + link = &decoder->links[i]; + if (link->sink->entity == decoder) { + found_link = link; + if (link->flags & MEDIA_LNK_FL_ENABLED) + active_links++; + break; + } + } + + if (active_links == 1 || !found_link) + return 0; + + source = found_link->source->entity; + for (i = 0; i < source->num_links; i++) { + struct media_entity *sink; + int flags = 0; + + link = &source->links[i]; + sink = link->sink->entity; + + if (sink == entity) + flags = MEDIA_LNK_FL_ENABLED; + + ret = media_entity_setup_link(link, flags); + if (ret) { + pr_err( + "Couldn't change link %s->%s to %s. Error %d\n", + source->name, sink->name, + flags ? "enabled" : "disabled", + ret); + return ret; + } else + au0828_isocdbg( + "link %s->%s was %s\n", + source->name, sink->name, + flags ? "ENABLED" : "disabled"); + } +#endif + return 0; +} + static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[]) @@ -650,6 +719,8 @@ static int queue_setup(struct vb2_queue *vq, *nplanes = 1; sizes[0] = size; + au0828_enable_analog_tuner(dev); + return 0; } @@ -1823,6 +1894,18 @@ int au0828_analog_register(struct au0828_dev *dev, dev->vbi_dev.queue->lock = &dev->vb_vbi_queue_lock; strcpy(dev->vbi_dev.name, "au0828a vbi"); +#if defined(CONFIG_MEDIA_CONTROLLER) + dev->video_pad.flags = MEDIA_PAD_FL_SINK; + ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad, 0); + if (ret < 0) + pr_err("failed to initialize video media entity!\n"); + + dev->vbi_pad.flags = MEDIA_PAD_FL_SINK; + ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad, 0); + if (ret < 0) + pr_err("failed to initialize vbi media entity!\n"); +#endif + /* initialize videobuf2 stuff */ retval = au0828_vb2_setup(dev); if (retval != 0) { diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h index 60b59391ea2ae..7d175d8b8a7af 100644 --- a/drivers/media/usb/au0828/au0828.h +++ b/drivers/media/usb/au0828/au0828.h @@ -33,6 +33,7 @@ #include #include #include +#include /* DVB */ #include "demux.h" @@ -276,6 +277,11 @@ struct au0828_dev { /* Preallocated transfer digital transfer buffers */ char *dig_transfer_buffer[URB_COUNT]; + +#ifdef CONFIG_MEDIA_CONTROLLER + struct media_device *media_dev; + struct media_pad video_pad, vbi_pad; +#endif }; -- GitLab From 0158e7b6a29f33a2c91cf045468958fbe8cb0b4c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 18 Jun 2015 13:06:38 -0300 Subject: [PATCH 2439/2855] [media] au0828: Cache the decoder info at au0828 dev structure Instead of seeking for the decoder every time analog stream is started, cache it. This simplifies the code a little bit. Requested-by: Hans Verkuil Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/au0828-cards.c | 4 ++++ drivers/media/usb/au0828/au0828-video.c | 19 +++++-------------- drivers/media/usb/au0828/au0828.h | 1 + 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-cards.c b/drivers/media/usb/au0828/au0828-cards.c index 6b469e8c4c6e2..ca861aea68a57 100644 --- a/drivers/media/usb/au0828/au0828-cards.c +++ b/drivers/media/usb/au0828/au0828-cards.c @@ -228,6 +228,10 @@ void au0828_card_analog_fe_setup(struct au0828_dev *dev) "au8522", 0x8e >> 1, NULL); if (sd == NULL) pr_err("analog subdev registration failed\n"); +#ifdef CONFIG_MEDIA_CONTROLLER + if (sd) + dev->decoder = &sd->entity; +#endif } /* Setup tuners */ diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 7aa7d509885bb..0b6e97d4fd949 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -642,11 +642,11 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev) { #ifdef CONFIG_MEDIA_CONTROLLER struct media_device *mdev = dev->media_dev; - struct media_entity *entity, *decoder = NULL, *source; + struct media_entity *entity, *source; struct media_link *link, *found_link = NULL; int i, ret, active_links = 0; - if (!mdev) + if (!mdev || !dev->decoder) return 0; /* @@ -656,18 +656,9 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev) * do DVB streaming while the DMA engine is being used for V4L2, * this should be enough for the actual needs. */ - media_device_for_each_entity(entity, mdev) { - if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_DECODER) { - decoder = entity; - break; - } - } - if (!decoder) - return 0; - - for (i = 0; i < decoder->num_links; i++) { - link = &decoder->links[i]; - if (link->sink->entity == decoder) { + for (i = 0; i < dev->decoder->num_links; i++) { + link = &dev->decoder->links[i]; + if (link->sink->entity == dev->decoder) { found_link = link; if (link->flags & MEDIA_LNK_FL_ENABLED) active_links++; diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h index 7d175d8b8a7af..3577b931157b4 100644 --- a/drivers/media/usb/au0828/au0828.h +++ b/drivers/media/usb/au0828/au0828.h @@ -281,6 +281,7 @@ struct au0828_dev { #ifdef CONFIG_MEDIA_CONTROLLER struct media_device *media_dev; struct media_pad video_pad, vbi_pad; + struct media_entity *decoder; #endif }; -- GitLab From 1809510715c4187fa7338204cac53e30326d5d04 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 6 Aug 2015 09:25:57 -0300 Subject: [PATCH 2440/2855] [media] media: get rid of unused "extra_links" param on media_entity_init() Currently, media_entity_init() creates an array with the links, allocated at init time. It provides a parameter (extra_links) that would allocate more links than the current needs, but this is not used by any driver. As we want to be able to do dynamic link allocation/removal, we'll need to change the implementation of the links. So, before doing that, let's first remove that extra unused parameter, in order to cleanup the interface first. Signed-off-by: Mauro Carvalho Chehab Acked-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- Documentation/media-framework.txt | 7 +++---- Documentation/video4linux/v4l2-framework.txt | 4 ++-- .../zh_CN/video4linux/v4l2-framework.txt | 4 ++-- drivers/media/dvb-core/dvbdev.c | 2 +- drivers/media/dvb-frontends/au8522_decoder.c | 2 +- drivers/media/i2c/ad9389b.c | 2 +- drivers/media/i2c/adp1653.c | 2 +- drivers/media/i2c/adv7180.c | 2 +- drivers/media/i2c/adv7511.c | 2 +- drivers/media/i2c/adv7604.c | 2 +- drivers/media/i2c/adv7842.c | 2 +- drivers/media/i2c/as3645a.c | 2 +- drivers/media/i2c/cx25840/cx25840-core.c | 2 +- drivers/media/i2c/lm3560.c | 2 +- drivers/media/i2c/lm3646.c | 2 +- drivers/media/i2c/m5mols/m5mols_core.c | 2 +- drivers/media/i2c/mt9m032.c | 2 +- drivers/media/i2c/mt9p031.c | 2 +- drivers/media/i2c/mt9t001.c | 2 +- drivers/media/i2c/mt9v032.c | 2 +- drivers/media/i2c/noon010pc30.c | 2 +- drivers/media/i2c/ov2659.c | 2 +- drivers/media/i2c/ov9650.c | 2 +- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 4 ++-- drivers/media/i2c/s5k4ecgx.c | 2 +- drivers/media/i2c/s5k5baf.c | 4 ++-- drivers/media/i2c/s5k6a3.c | 2 +- drivers/media/i2c/s5k6aa.c | 2 +- drivers/media/i2c/smiapp/smiapp-core.c | 4 ++-- drivers/media/i2c/tc358743.c | 2 +- drivers/media/i2c/tvp514x.c | 2 +- drivers/media/i2c/tvp7002.c | 2 +- drivers/media/media-entity.c | 18 ++++++++---------- .../media/platform/exynos4-is/fimc-capture.c | 4 ++-- .../media/platform/exynos4-is/fimc-isp-video.c | 2 +- drivers/media/platform/exynos4-is/fimc-isp.c | 2 +- drivers/media/platform/exynos4-is/fimc-lite.c | 4 ++-- drivers/media/platform/exynos4-is/fimc-m2m.c | 2 +- drivers/media/platform/exynos4-is/mipi-csis.c | 2 +- drivers/media/platform/omap3isp/ispccdc.c | 2 +- drivers/media/platform/omap3isp/ispccp2.c | 2 +- drivers/media/platform/omap3isp/ispcsi2.c | 2 +- drivers/media/platform/omap3isp/isppreview.c | 2 +- drivers/media/platform/omap3isp/ispresizer.c | 2 +- drivers/media/platform/omap3isp/ispstat.c | 2 +- drivers/media/platform/omap3isp/ispvideo.c | 2 +- .../media/platform/s3c-camif/camif-capture.c | 4 ++-- drivers/media/platform/vsp1/vsp1_entity.c | 2 +- drivers/media/platform/vsp1/vsp1_video.c | 2 +- drivers/media/platform/xilinx/xilinx-dma.c | 2 +- drivers/media/platform/xilinx/xilinx-tpg.c | 2 +- drivers/media/usb/au0828/au0828-video.c | 4 ++-- drivers/media/usb/cx231xx/cx231xx-video.c | 4 ++-- drivers/media/usb/uvc/uvc_entity.c | 4 ++-- drivers/media/v4l2-core/tuner-core.c | 2 +- drivers/media/v4l2-core/v4l2-flash-led-class.c | 2 +- .../staging/media/davinci_vpfe/dm365_ipipe.c | 2 +- .../staging/media/davinci_vpfe/dm365_ipipeif.c | 2 +- .../staging/media/davinci_vpfe/dm365_isif.c | 2 +- .../staging/media/davinci_vpfe/dm365_resizer.c | 6 +++--- .../staging/media/davinci_vpfe/vpfe_video.c | 2 +- drivers/staging/media/omap4iss/iss_csi2.c | 2 +- drivers/staging/media/omap4iss/iss_ipipe.c | 2 +- drivers/staging/media/omap4iss/iss_ipipeif.c | 2 +- drivers/staging/media/omap4iss/iss_resizer.c | 2 +- drivers/staging/media/omap4iss/iss_video.c | 2 +- include/media/media-entity.h | 2 +- 67 files changed, 89 insertions(+), 92 deletions(-) diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt index f552a75c0e70b..6903b25035774 100644 --- a/Documentation/media-framework.txt +++ b/Documentation/media-framework.txt @@ -104,7 +104,7 @@ although drivers can allocate entities directly. Drivers initialize entities by calling media_entity_init(struct media_entity *entity, u16 num_pads, - struct media_pad *pads, u16 extra_links); + struct media_pad *pads); The media_entity name, type, flags, revision and group_id fields can be initialized before or after calling media_entity_init. Entities embedded in @@ -120,9 +120,8 @@ media_entity_init. The function will initialize the other pads fields. Unlike the number of pads, the total number of links isn't always known in advance by the entity driver. As an initial estimate, media_entity_init -pre-allocates a number of links equal to the number of pads plus an optional -number of extra links. The links array will be reallocated if it grows beyond -the initial estimate. +pre-allocates a number of links equal to the number of pads. The links array +will be reallocated if it grows beyond the initial estimate. Drivers register entities with a media device by calling diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index 75d5c18d689aa..109cc37925344 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt @@ -300,7 +300,7 @@ calling media_entity_init(): struct media_pad *pads = &my_sd->pads; int err; - err = media_entity_init(&sd->entity, npads, pads, 0); + err = media_entity_init(&sd->entity, npads, pads); The pads array must have been previously initialized. There is no need to manually set the struct media_entity type and name fields, but the revision @@ -700,7 +700,7 @@ calling media_entity_init(): struct media_pad *pad = &my_vdev->pad; int err; - err = media_entity_init(&vdev->entity, 1, pad, 0); + err = media_entity_init(&vdev->entity, 1, pad); The pads array must have been previously initialized. There is no need to manually set the struct media_entity type and name fields. diff --git a/Documentation/zh_CN/video4linux/v4l2-framework.txt b/Documentation/zh_CN/video4linux/v4l2-framework.txt index 2b828e631e318..ff815cb920318 100644 --- a/Documentation/zh_CN/video4linux/v4l2-framework.txt +++ b/Documentation/zh_CN/video4linux/v4l2-framework.txt @@ -295,7 +295,7 @@ owner 域。若使用 i2c 辅助函数,这些都会帮你处理好。 struct media_pad *pads = &my_sd->pads; int err; - err = media_entity_init(&sd->entity, npads, pads, 0); + err = media_entity_init(&sd->entity, npads, pads); pads 数组必须预先初始化。无须手动设置 media_entity 的 type 和 name 域,但如有必要,revision 域必须初始化。 @@ -602,7 +602,7 @@ v4l2_file_operations 结构体是 file_operations 的一个子集。其主要 struct media_pad *pad = &my_vdev->pad; int err; - err = media_entity_init(&vdev->entity, 1, pad, 0); + err = media_entity_init(&vdev->entity, 1, pad); pads 数组必须预先初始化。没有必要手动设置 media_entity 的 type 和 name 域。 diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 13bb57f0457f7..2fdcbb5f000a9 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -249,7 +249,7 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, } if (npads) - ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads, 0); + ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads); if (!ret) ret = media_device_register_entity(dvbdev->adapter->mdev, dvbdev->entity); diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c index 0a8882cb23c38..580859c89da17 100644 --- a/drivers/media/dvb-frontends/au8522_decoder.c +++ b/drivers/media/dvb-frontends/au8522_decoder.c @@ -769,7 +769,7 @@ static int au8522_probe(struct i2c_client *client, sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER; ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), - state->pads, 0); + state->pads); if (ret < 0) { v4l_info(client, "failed to initialize media entity!\n"); return ret; diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c index 0494a7896aa21..a02dc4925707c 100644 --- a/drivers/media/i2c/ad9389b.c +++ b/drivers/media/i2c/ad9389b.c @@ -1158,7 +1158,7 @@ static int ad9389b_probe(struct i2c_client *client, const struct i2c_device_id * state->rgb_quantization_range_ctrl->is_private = true; state->pad.flags = MEDIA_PAD_FL_SINK; - err = media_entity_init(&sd->entity, 1, &state->pad, 0); + err = media_entity_init(&sd->entity, 1, &state->pad); if (err) goto err_hdl; diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c index f00745bbe471f..07e46b5b849cf 100644 --- a/drivers/media/i2c/adp1653.c +++ b/drivers/media/i2c/adp1653.c @@ -512,7 +512,7 @@ static int adp1653_probe(struct i2c_client *client, if (ret) goto free_and_quit; - ret = media_entity_init(&flash->subdev.entity, 0, NULL, 0); + ret = media_entity_init(&flash->subdev.entity, 0, NULL); if (ret < 0) goto free_and_quit; diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index 3c3c4bfe38664..0fca8677014c9 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c @@ -1214,7 +1214,7 @@ static int adv7180_probe(struct i2c_client *client, state->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER; - ret = media_entity_init(&sd->entity, 1, &state->pad, 0); + ret = media_entity_init(&sd->entity, 1, &state->pad); if (ret) goto err_free_ctrl; diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index eeb2cd823c4d1..cbcf81b1d29e5 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c @@ -1482,7 +1482,7 @@ static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id * state->rgb_quantization_range_ctrl->is_private = true; state->pad.flags = MEDIA_PAD_FL_SINK; - err = media_entity_init(&sd->entity, 1, &state->pad, 0); + err = media_entity_init(&sd->entity, 1, &state->pad); if (err) goto err_hdl; diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 7452862256558..c2df7e8053f3d 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -3209,7 +3209,7 @@ static int adv76xx_probe(struct i2c_client *client, state->pads[state->source_pad].flags = MEDIA_PAD_FL_SOURCE; err = media_entity_init(&sd->entity, state->source_pad + 1, - state->pads, 0); + state->pads); if (err) goto err_work_queues; diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 69378e4914b62..b5013a937254b 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -3309,7 +3309,7 @@ static int adv7842_probe(struct i2c_client *client, adv7842_delayed_work_enable_hotplug); state->pad.flags = MEDIA_PAD_FL_SOURCE; - err = media_entity_init(&sd->entity, 1, &state->pad, 0); + err = media_entity_init(&sd->entity, 1, &state->pad); if (err) goto err_work_queues; diff --git a/drivers/media/i2c/as3645a.c b/drivers/media/i2c/as3645a.c index 29a2e7034aa60..b83c7fc988aef 100644 --- a/drivers/media/i2c/as3645a.c +++ b/drivers/media/i2c/as3645a.c @@ -827,7 +827,7 @@ static int as3645a_probe(struct i2c_client *client, if (ret < 0) goto done; - ret = media_entity_init(&flash->subdev.entity, 0, NULL, 0); + ret = media_entity_init(&flash->subdev.entity, 0, NULL); if (ret < 0) goto done; diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index f2e2c34ddbbd2..022ad5ae88699 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -5214,7 +5214,7 @@ static int cx25840_probe(struct i2c_client *client, sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER; ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), - state->pads, 0); + state->pads); if (ret < 0) { v4l_info(client, "failed to initialize media entity!\n"); return ret; diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c index 19ecb88010647..91c1ed27a458a 100644 --- a/drivers/media/i2c/lm3560.c +++ b/drivers/media/i2c/lm3560.c @@ -365,7 +365,7 @@ static int lm3560_subdev_init(struct lm3560_flash *flash, rval = lm3560_init_controls(flash, led_no); if (rval) goto err_out; - rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL, 0); + rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL); if (rval < 0) goto err_out; flash->subdev_led[led_no].entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; diff --git a/drivers/media/i2c/lm3646.c b/drivers/media/i2c/lm3646.c index 7fbe6ff1c4f4f..a037616bbab0e 100644 --- a/drivers/media/i2c/lm3646.c +++ b/drivers/media/i2c/lm3646.c @@ -282,7 +282,7 @@ static int lm3646_subdev_init(struct lm3646_flash *flash) rval = lm3646_init_controls(flash); if (rval) goto err_out; - rval = media_entity_init(&flash->subdev_led.entity, 0, NULL, 0); + rval = media_entity_init(&flash->subdev_led.entity, 0, NULL); if (rval < 0) goto err_out; flash->subdev_led.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c index f8993933416e7..0788c1908f9c0 100644 --- a/drivers/media/i2c/m5mols/m5mols_core.c +++ b/drivers/media/i2c/m5mols/m5mols_core.c @@ -975,7 +975,7 @@ static int m5mols_probe(struct i2c_client *client, sd->internal_ops = &m5mols_subdev_internal_ops; info->pad.flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&sd->entity, 1, &info->pad, 0); + ret = media_entity_init(&sd->entity, 1, &info->pad); if (ret < 0) return ret; sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; diff --git a/drivers/media/i2c/mt9m032.c b/drivers/media/i2c/mt9m032.c index 101cb26f9330e..a2a450839ca12 100644 --- a/drivers/media/i2c/mt9m032.c +++ b/drivers/media/i2c/mt9m032.c @@ -799,7 +799,7 @@ static int mt9m032_probe(struct i2c_client *client, sensor->subdev.ctrl_handler = &sensor->ctrls; sensor->pad.flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&sensor->subdev.entity, 1, &sensor->pad, 0); + ret = media_entity_init(&sensor->subdev.entity, 1, &sensor->pad); if (ret < 0) goto error_ctrl; diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c index a3da0e977d0b3..165f29cddca6d 100644 --- a/drivers/media/i2c/mt9p031.c +++ b/drivers/media/i2c/mt9p031.c @@ -1112,7 +1112,7 @@ static int mt9p031_probe(struct i2c_client *client, mt9p031->subdev.internal_ops = &mt9p031_subdev_internal_ops; mt9p031->pad.flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&mt9p031->subdev.entity, 1, &mt9p031->pad, 0); + ret = media_entity_init(&mt9p031->subdev.entity, 1, &mt9p031->pad); if (ret < 0) goto done; diff --git a/drivers/media/i2c/mt9t001.c b/drivers/media/i2c/mt9t001.c index b28fdff1d3107..7d3df84651d88 100644 --- a/drivers/media/i2c/mt9t001.c +++ b/drivers/media/i2c/mt9t001.c @@ -933,7 +933,7 @@ static int mt9t001_probe(struct i2c_client *client, mt9t001->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; mt9t001->pad.flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&mt9t001->subdev.entity, 1, &mt9t001->pad, 0); + ret = media_entity_init(&mt9t001->subdev.entity, 1, &mt9t001->pad); done: if (ret < 0) { diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c index 1dbbd23fdfb03..b4f0f042c6c3b 100644 --- a/drivers/media/i2c/mt9v032.c +++ b/drivers/media/i2c/mt9v032.c @@ -1046,7 +1046,7 @@ static int mt9v032_probe(struct i2c_client *client, mt9v032->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0); + ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad); if (ret < 0) goto err; diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c index 69e4f3031d8b9..2e614ad473f1f 100644 --- a/drivers/media/i2c/noon010pc30.c +++ b/drivers/media/i2c/noon010pc30.c @@ -780,7 +780,7 @@ static int noon010_probe(struct i2c_client *client, info->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; - ret = media_entity_init(&sd->entity, 1, &info->pad, 0); + ret = media_entity_init(&sd->entity, 1, &info->pad); if (ret < 0) goto np_err; diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index 82c7ac1cc88e8..ea95f854a5195 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1446,7 +1446,7 @@ static int ov2659_probe(struct i2c_client *client, #if defined(CONFIG_MEDIA_CONTROLLER) ov2659->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; - ret = media_entity_init(&sd->entity, 1, &ov2659->pad, 0); + ret = media_entity_init(&sd->entity, 1, &ov2659->pad); if (ret < 0) { v4l2_ctrl_handler_free(&ov2659->ctrls); return ret; diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index 9fe9006474b2b..b4c408f2a2b0d 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -1501,7 +1501,7 @@ static int ov965x_probe(struct i2c_client *client, ov965x->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; - ret = media_entity_init(&sd->entity, 1, &ov965x->pad, 0); + ret = media_entity_init(&sd->entity, 1, &ov965x->pad); if (ret < 0) return ret; diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index 25f5e79dc9bc5..381f903831f47 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1691,7 +1691,7 @@ static int s5c73m3_probe(struct i2c_client *client, sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS, - state->sensor_pads, 0); + state->sensor_pads); if (ret < 0) return ret; @@ -1707,7 +1707,7 @@ static int s5c73m3_probe(struct i2c_client *client, oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; ret = media_entity_init(&oif_sd->entity, OIF_NUM_PADS, - state->oif_pads, 0); + state->oif_pads); if (ret < 0) return ret; diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c index 6757aca2cdabe..445a89e30949d 100644 --- a/drivers/media/i2c/s5k4ecgx.c +++ b/drivers/media/i2c/s5k4ecgx.c @@ -962,7 +962,7 @@ static int s5k4ecgx_probe(struct i2c_client *client, priv->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; - ret = media_entity_init(&sd->entity, 1, &priv->pad, 0); + ret = media_entity_init(&sd->entity, 1, &priv->pad); if (ret) return ret; diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 774e0d0c94cb3..30a9ca62e034d 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -1905,7 +1905,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state, state->cis_pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; - ret = media_entity_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad, 0); + ret = media_entity_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad); if (ret < 0) goto err; @@ -1920,7 +1920,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state, state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK; state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE; sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; - ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads, 0); + ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads); if (!ret) return 0; diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c index b1b1574dfb95d..2434a79447818 100644 --- a/drivers/media/i2c/s5k6a3.c +++ b/drivers/media/i2c/s5k6a3.c @@ -333,7 +333,7 @@ static int s5k6a3_probe(struct i2c_client *client, sensor->format.height = S5K6A3_DEFAULT_HEIGHT; sensor->pad.flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&sd->entity, 1, &sensor->pad, 0); + ret = media_entity_init(&sd->entity, 1, &sensor->pad); if (ret < 0) return ret; diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index 60aaff7190d24..31be29d250932 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c @@ -1578,7 +1578,7 @@ static int s5k6aa_probe(struct i2c_client *client, s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; - ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad, 0); + ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad); if (ret) return ret; diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index fb39dfd55e753..7ed0538ea8db2 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2488,7 +2488,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor) continue; rval = media_entity_init(&this->sd.entity, - this->npads, this->pads, 0); + this->npads, this->pads); if (rval) { dev_err(&client->dev, "media_entity_init failed\n"); @@ -3078,7 +3078,7 @@ static int smiapp_probe(struct i2c_client *client, sensor->src->pads[0].flags = MEDIA_PAD_FL_SOURCE; rval = media_entity_init(&sensor->src->sd.entity, 2, - sensor->src->pads, 0); + sensor->src->pads); if (rval < 0) return rval; diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 77b801152ea59..78e5b644d4006 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -1889,7 +1889,7 @@ static int tc358743_probe(struct i2c_client *client, } state->pad.flags = MEDIA_PAD_FL_SOURCE; - err = media_entity_init(&sd->entity, 1, &state->pad, 0); + err = media_entity_init(&sd->entity, 1, &state->pad); if (err < 0) goto err_hdl; diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index b5dba5b7ce3a6..11e426dbe8919 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c @@ -1097,7 +1097,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) decoder->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; decoder->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER; - ret = media_entity_init(&decoder->sd.entity, 1, &decoder->pad, 0); + ret = media_entity_init(&decoder->sd.entity, 1, &decoder->pad); if (ret < 0) { v4l2_err(sd, "%s decoder driver failed to register !!\n", sd->name); diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index 772a3043ae3b9..a5ee2b8df4294 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c @@ -1014,7 +1014,7 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id) device->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; device->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER; - error = media_entity_init(&device->sd.entity, 1, &device->pad, 0); + error = media_entity_init(&device->sd.entity, 1, &device->pad); if (error < 0) return error; #endif diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 767fe55ba08ee..eabcbacfe387c 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -30,32 +30,30 @@ * media_entity_init - Initialize a media entity * * @num_pads: Total number of sink and source pads. - * @extra_links: Initial estimate of the number of extra links. * @pads: Array of 'num_pads' pads. * * The total number of pads is an intrinsic property of entities known by the * entity driver, while the total number of links depends on hardware design * and is an extrinsic property unknown to the entity driver. However, in most - * use cases the entity driver can guess the number of links which can safely - * be assumed to be equal to or larger than the number of pads. + * use cases the number of links can safely be assumed to be equal to or + * larger than the number of pads. * - * For those reasons the links array can be preallocated based on the entity - * driver guess and will be reallocated later if extra links need to be - * created. + * For those reasons the links array can be preallocated based on the number + * of pads and will be reallocated later if extra links need to be created. * * This function allocates a links array with enough space to hold at least - * 'num_pads' + 'extra_links' elements. The media_entity::max_links field will - * be set to the number of allocated elements. + * 'num_pads' elements. The media_entity::max_links field will be set to the + * number of allocated elements. * * The pads array is managed by the entity driver and passed to * media_entity_init() where its pointer will be stored in the entity structure. */ int media_entity_init(struct media_entity *entity, u16 num_pads, - struct media_pad *pads, u16 extra_links) + struct media_pad *pads) { struct media_link *links; - unsigned int max_links = num_pads + extra_links; + unsigned int max_links = num_pads; unsigned int i; links = kzalloc(max_links * sizeof(links[0]), GFP_KERNEL); diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index 0d549a6c8a13c..8f5bee42783f1 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c @@ -1800,7 +1800,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc, vid_cap->wb_fmt.code = fmt->mbus_code; vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0); + ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad); if (ret) goto err_free_ctx; @@ -1893,7 +1893,7 @@ int fimc_initialize_capture_subdev(struct fimc_dev *fimc) fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK_FIFO].flags = MEDIA_PAD_FL_SINK; fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM, - fimc->vid_cap.sd_pads, 0); + fimc->vid_cap.sd_pads); if (ret) return ret; diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c index 0dd22ec666941..817226d52b742 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c @@ -617,7 +617,7 @@ int fimc_isp_video_device_register(struct fimc_isp *isp, vdev->lock = &isp->video_lock; iv->pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&vdev->entity, 1, &iv->pad, 0); + ret = media_entity_init(&vdev->entity, 1, &iv->pad); if (ret < 0) return ret; diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c index 5d78f5716f3b8..f52eebf765c17 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp.c +++ b/drivers/media/platform/exynos4-is/fimc-isp.c @@ -709,7 +709,7 @@ int fimc_isp_subdev_create(struct fimc_isp *isp) isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_FIFO].flags = MEDIA_PAD_FL_SOURCE; isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_DMA].flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_init(&sd->entity, FIMC_ISP_SD_PADS_NUM, - isp->subdev_pads, 0); + isp->subdev_pads); if (ret) return ret; diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index 639ee710499ed..2ce670425cd96 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -1316,7 +1316,7 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd) return ret; fimc->vd_pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0); + ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad); if (ret < 0) return ret; @@ -1431,7 +1431,7 @@ static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc) fimc->subdev_pads[FLITE_SD_PAD_SOURCE_DMA].flags = MEDIA_PAD_FL_SOURCE; fimc->subdev_pads[FLITE_SD_PAD_SOURCE_ISP].flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_init(&sd->entity, FLITE_SD_PADS_NUM, - fimc->subdev_pads, 0); + fimc->subdev_pads); if (ret) return ret; diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c index 5aa857c7b631e..8ff4e6f76b848 100644 --- a/drivers/media/platform/exynos4-is/fimc-m2m.c +++ b/drivers/media/platform/exynos4-is/fimc-m2m.c @@ -739,7 +739,7 @@ int fimc_register_m2m_device(struct fimc_dev *fimc, return PTR_ERR(fimc->m2m.m2m_dev); } - ret = media_entity_init(&vfd->entity, 0, NULL, 0); + ret = media_entity_init(&vfd->entity, 0, NULL); if (ret) goto err_me; diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index ff5dabf24694a..8847797b0d0b4 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c @@ -867,7 +867,7 @@ static int s5pcsis_probe(struct platform_device *pdev) state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK; state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_init(&state->sd.entity, - CSIS_PADS_NUM, state->pads, 0); + CSIS_PADS_NUM, state->pads); if (ret < 0) goto e_clkdis; diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index a6a61cce43dda..3b10304b580bd 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -2650,7 +2650,7 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc) pads[CCDC_PAD_SOURCE_OF].flags = MEDIA_PAD_FL_SOURCE; me->ops = &ccdc_media_ops; - ret = media_entity_init(me, CCDC_PADS_NUM, pads, 0); + ret = media_entity_init(me, CCDC_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index 38e6a974c5b1e..e1b5f5bea541f 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -1071,7 +1071,7 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2) pads[CCP2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; me->ops = &ccp2_media_ops; - ret = media_entity_init(me, CCP2_PADS_NUM, pads, 0); + ret = media_entity_init(me, CCP2_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index a78338d012b4d..6fff92f0813a0 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c @@ -1245,7 +1245,7 @@ static int csi2_init_entities(struct isp_csi2_device *csi2) | MEDIA_PAD_FL_MUST_CONNECT; me->ops = &csi2_media_ops; - ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0); + ret = media_entity_init(me, CSI2_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index 13803270d1045..b440c6342ca49 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c @@ -2282,7 +2282,7 @@ static int preview_init_entities(struct isp_prev_device *prev) pads[PREV_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; me->ops = &preview_media_ops; - ret = media_entity_init(me, PREV_PADS_NUM, pads, 0); + ret = media_entity_init(me, PREV_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c index 7cfb43dc0ffd7..3deb1ec4a973a 100644 --- a/drivers/media/platform/omap3isp/ispresizer.c +++ b/drivers/media/platform/omap3isp/ispresizer.c @@ -1728,7 +1728,7 @@ static int resizer_init_entities(struct isp_res_device *res) pads[RESZ_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; me->ops = &resizer_media_ops; - ret = media_entity_init(me, RESZ_PADS_NUM, pads, 0); + ret = media_entity_init(me, RESZ_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c index 94d4c295d3d00..f7a5eee9f11d5 100644 --- a/drivers/media/platform/omap3isp/ispstat.c +++ b/drivers/media/platform/omap3isp/ispstat.c @@ -1028,7 +1028,7 @@ static int isp_stat_init_entities(struct ispstat *stat, const char *name, stat->pad.flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT; me->ops = NULL; - return media_entity_init(me, 1, &stat->pad, 0); + return media_entity_init(me, 1, &stat->pad); } int omap3isp_stat_init(struct ispstat *stat, const char *name, diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index ecadca3e945b4..963cb9318873d 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -1367,7 +1367,7 @@ int omap3isp_video_init(struct isp_video *video, const char *name) if (IS_ERR(video->alloc_ctx)) return PTR_ERR(video->alloc_ctx); - ret = media_entity_init(&video->video.entity, 1, &video->pad, 0); + ret = media_entity_init(&video->video.entity, 1, &video->pad); if (ret < 0) { vb2_dma_contig_cleanup_ctx(video->alloc_ctx); return ret; diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index ec3abbed87d90..a87ac16273a04 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c @@ -1144,7 +1144,7 @@ int s3c_camif_register_video_node(struct camif_dev *camif, int idx) goto err_vd_rel; vp->pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&vfd->entity, 1, &vp->pad, 0); + ret = media_entity_init(&vfd->entity, 1, &vp->pad); if (ret) goto err_vd_rel; @@ -1560,7 +1560,7 @@ int s3c_camif_create_subdev(struct camif_dev *camif) camif->pads[CAMIF_SD_PAD_SOURCE_P].flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_init(&sd->entity, CAMIF_SD_PADS_NUM, - camif->pads, 0); + camif->pads); if (ret) return ret; diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c index fd95a75b04f4c..619942ff2058f 100644 --- a/drivers/media/platform/vsp1/vsp1_entity.c +++ b/drivers/media/platform/vsp1/vsp1_entity.c @@ -220,7 +220,7 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity, /* Initialize the media entity. */ return media_entity_init(&entity->subdev.entity, num_pads, - entity->pads, 0); + entity->pads); } void vsp1_entity_destroy(struct vsp1_entity *entity) diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 45eb65fa23dbb..fb52683b5c222 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -1193,7 +1193,7 @@ int vsp1_video_init(struct vsp1_video *video, struct vsp1_entity *rwpf) video->pipe.state = VSP1_PIPELINE_STOPPED; /* Initialize the media entity... */ - ret = media_entity_init(&video->video.entity, 1, &video->pad, 0); + ret = media_entity_init(&video->video.entity, 1, &video->pad); if (ret < 0) return ret; diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index 722758f339241..ce2d34df12ed8 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -677,7 +677,7 @@ int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma, dma->pad.flags = type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&dma->video.entity, 1, &dma->pad, 0); + ret = media_entity_init(&dma->video.entity, 1, &dma->pad); if (ret < 0) goto error; diff --git a/drivers/media/platform/xilinx/xilinx-tpg.c b/drivers/media/platform/xilinx/xilinx-tpg.c index 8bd7e37360195..c09ca513a9dc5 100644 --- a/drivers/media/platform/xilinx/xilinx-tpg.c +++ b/drivers/media/platform/xilinx/xilinx-tpg.c @@ -838,7 +838,7 @@ static int xtpg_probe(struct platform_device *pdev) subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; subdev->entity.ops = &xtpg_media_ops; - ret = media_entity_init(&subdev->entity, xtpg->npads, xtpg->pads, 0); + ret = media_entity_init(&subdev->entity, xtpg->npads, xtpg->pads); if (ret < 0) goto error; diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 0b6e97d4fd949..57d7b9b45123c 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1887,12 +1887,12 @@ int au0828_analog_register(struct au0828_dev *dev, #if defined(CONFIG_MEDIA_CONTROLLER) dev->video_pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad, 0); + ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad); if (ret < 0) pr_err("failed to initialize video media entity!\n"); dev->vbi_pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad, 0); + ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad); if (ret < 0) pr_err("failed to initialize vbi media entity!\n"); #endif diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index a70850fe6235a..cbb28c9123191 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -2177,7 +2177,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) cx231xx_vdev_init(dev, &dev->vdev, &cx231xx_video_template, "video"); #if defined(CONFIG_MEDIA_CONTROLLER) dev->video_pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad, 0); + ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad); if (ret < 0) dev_err(dev->dev, "failed to initialize video media entity!\n"); #endif @@ -2204,7 +2204,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) #if defined(CONFIG_MEDIA_CONTROLLER) dev->vbi_pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad, 0); + ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad); if (ret < 0) dev_err(dev->dev, "failed to initialize vbi media entity!\n"); #endif diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c index dc56a59ecadc4..2454454915161 100644 --- a/drivers/media/usb/uvc/uvc_entity.c +++ b/drivers/media/usb/uvc/uvc_entity.c @@ -89,10 +89,10 @@ static int uvc_mc_init_entity(struct uvc_entity *entity) sizeof(entity->subdev.name)); ret = media_entity_init(&entity->subdev.entity, - entity->num_pads, entity->pads, 0); + entity->num_pads, entity->pads); } else if (entity->vdev != NULL) { ret = media_entity_init(&entity->vdev->entity, - entity->num_pads, entity->pads, 0); + entity->num_pads, entity->pads); if (entity->flags & UVC_ENTITY_FLAG_DEFAULT) entity->vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT; } else diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index 581e21ad68015..100b8f0696409 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -699,7 +699,7 @@ register_client: t->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_TUNER; t->sd.entity.name = t->name; - ret = media_entity_init(&t->sd.entity, 1, &t->pad, 0); + ret = media_entity_init(&t->sd.entity, 1, &t->pad); if (ret < 0) { tuner_err("failed to initialize media entity!\n"); kfree(t); diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c index 5bdfb8d5263a0..34c489fed55e7 100644 --- a/drivers/media/v4l2-core/v4l2-flash-led-class.c +++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c @@ -651,7 +651,7 @@ struct v4l2_flash *v4l2_flash_init( sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; strlcpy(sd->name, config->dev_name, sizeof(sd->name)); - ret = media_entity_init(&sd->entity, 0, NULL, 0); + ret = media_entity_init(&sd->entity, 0, NULL); if (ret < 0) return ERR_PTR(ret); diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c index c492914768eaa..3badf169c419a 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c @@ -1840,7 +1840,7 @@ vpfe_ipipe_init(struct vpfe_ipipe_device *ipipe, struct platform_device *pdev) v4l2_ctrl_handler_setup(&ipipe->ctrls); sd->ctrl_handler = &ipipe->ctrls; - return media_entity_init(me, IPIPE_PADS_NUM, pads, 0); + return media_entity_init(me, IPIPE_PADS_NUM, pads); } /* diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c index 8b230541b1d16..8fb6761868986 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c @@ -1026,7 +1026,7 @@ int vpfe_ipipeif_init(struct vpfe_ipipeif_device *ipipeif, ipipeif->output = IPIPEIF_OUTPUT_NONE; me->ops = &ipipeif_media_ops; - ret = media_entity_init(me, IPIPEIF_NUM_PADS, pads, 0); + ret = media_entity_init(me, IPIPEIF_NUM_PADS, pads); if (ret) goto fail; diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c index 80907b4644129..b1f01adfa7c83 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_isif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c @@ -2052,7 +2052,7 @@ int vpfe_isif_init(struct vpfe_isif_device *isif, struct platform_device *pdev) isif->input = ISIF_INPUT_NONE; isif->output = ISIF_OUTPUT_NONE; me->ops = &isif_media_ops; - status = media_entity_init(me, ISIF_PADS_NUM, pads, 0); + status = media_entity_init(me, ISIF_PADS_NUM, pads); if (status) goto isif_fail; isif->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index d892fee3f52fd..7275cf3d6c20e 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c @@ -1910,7 +1910,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz, vpfe_rsz->crop_resizer.output2 = RESIZER_CROP_OUTPUT_NONE; vpfe_rsz->crop_resizer.rsz_device = vpfe_rsz; me->ops = &resizer_media_ops; - ret = media_entity_init(me, RESIZER_CROP_PADS_NUM, pads, 0); + ret = media_entity_init(me, RESIZER_CROP_PADS_NUM, pads); if (ret) return ret; @@ -1932,7 +1932,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz, vpfe_rsz->resizer_a.output = RESIZER_OUTPUT_NONE; vpfe_rsz->resizer_a.rsz_device = vpfe_rsz; me->ops = &resizer_media_ops; - ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0); + ret = media_entity_init(me, RESIZER_PADS_NUM, pads); if (ret) return ret; @@ -1954,7 +1954,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz, vpfe_rsz->resizer_b.output = RESIZER_OUTPUT_NONE; vpfe_rsz->resizer_b.rsz_device = vpfe_rsz; me->ops = &resizer_media_ops; - ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0); + ret = media_entity_init(me, RESIZER_PADS_NUM, pads); if (ret) return ret; diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index adb2bc8811aba..daae720eb82ca 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -1601,7 +1601,7 @@ int vpfe_video_init(struct vpfe_video_device *video, const char *name) spin_lock_init(&video->dma_queue_lock); mutex_init(&video->lock); ret = media_entity_init(&video->video_dev.entity, - 1, &video->pad, 0); + 1, &video->pad); if (ret < 0) return ret; diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c index b941035139ae8..86111e39a7283 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.c +++ b/drivers/staging/media/omap4iss/iss_csi2.c @@ -1271,7 +1271,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname) pads[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK; me->ops = &csi2_media_ops; - ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0); + ret = media_entity_init(me, CSI2_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/staging/media/omap4iss/iss_ipipe.c b/drivers/staging/media/omap4iss/iss_ipipe.c index dd0abeffd893f..44220765fb3aa 100644 --- a/drivers/staging/media/omap4iss/iss_ipipe.c +++ b/drivers/staging/media/omap4iss/iss_ipipe.c @@ -513,7 +513,7 @@ static int ipipe_init_entities(struct iss_ipipe_device *ipipe) pads[IPIPE_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE; me->ops = &ipipe_media_ops; - ret = media_entity_init(me, IPIPE_PADS_NUM, pads, 0); + ret = media_entity_init(me, IPIPE_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c index 5f9e449e70074..d031a5f22cdcb 100644 --- a/drivers/staging/media/omap4iss/iss_ipipeif.c +++ b/drivers/staging/media/omap4iss/iss_ipipeif.c @@ -743,7 +743,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif) pads[IPIPEIF_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE; me->ops = &ipipeif_media_ops; - ret = media_entity_init(me, IPIPEIF_PADS_NUM, pads, 0); + ret = media_entity_init(me, IPIPEIF_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c index 108961e05f539..11031d9de3ab4 100644 --- a/drivers/staging/media/omap4iss/iss_resizer.c +++ b/drivers/staging/media/omap4iss/iss_resizer.c @@ -785,7 +785,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer) pads[RESIZER_PAD_SOURCE_MEM].flags = MEDIA_PAD_FL_SOURCE; me->ops = &resizer_media_ops; - ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0); + ret = media_entity_init(me, RESIZER_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index e9aeca08986f9..194c41ef822c9 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -1102,7 +1102,7 @@ int omap4iss_video_init(struct iss_video *video, const char *name) return -EINVAL; } - ret = media_entity_init(&video->video.entity, 1, &video->pad, 0); + ret = media_entity_init(&video->video.entity, 1, &video->pad); if (ret < 0) return ret; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 197f937997539..b92366317aee0 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -134,7 +134,7 @@ struct media_entity_graph { }; int media_entity_init(struct media_entity *entity, u16 num_pads, - struct media_pad *pads, u16 extra_links); + struct media_pad *pads); void media_entity_cleanup(struct media_entity *entity); int media_entity_create_link(struct media_entity *source, u16 source_pad, -- GitLab From 21a0654200f24208aadd7bdc80fcdec65d2eb64b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 19 Aug 2015 06:57:59 -0300 Subject: [PATCH 2441/2855] [media] Kconfig: Re-enable Media controller support for DVB This was depending on broken because we're working at the Media Controller API, with has... issues. As this got fixed, we can re-enable it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 9264ea73b3be5..a8518fb3bca76 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -97,7 +97,6 @@ config MEDIA_CONTROLLER config MEDIA_CONTROLLER_DVB bool "Enable Media controller for DVB (EXPERIMENTAL)" depends on MEDIA_CONTROLLER - depends on BROKEN ---help--- Enable the media controller API support for DVB. -- GitLab From 20fe0319de9aca71ba45e2f93c4a2a73dabde4da Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Aug 2015 06:53:10 -0300 Subject: [PATCH 2442/2855] [media] au0828: Fix the logic that enables the analog demoder link This logic was broken on the original patch, likely due to a cut-and-paste mistake. Fix it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/au0828-video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 57d7b9b45123c..a1df4eb93b148 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -642,7 +642,7 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev) { #ifdef CONFIG_MEDIA_CONTROLLER struct media_device *mdev = dev->media_dev; - struct media_entity *entity, *source; + struct media_entity *source; struct media_link *link, *found_link = NULL; int i, ret, active_links = 0; @@ -677,7 +677,7 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev) link = &source->links[i]; sink = link->sink->entity; - if (sink == entity) + if (sink == dev->decoder) flags = MEDIA_LNK_FL_ENABLED; ret = media_entity_setup_link(link, flags); -- GitLab From fa762394fd85c838ade769990478bc4e01fd95e8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Aug 2015 10:42:05 -0300 Subject: [PATCH 2443/2855] [media] media: create a macro to get entity ID Instead of accessing directly entity.id, let's create a macro, as this field will be moved into a common struct later on. Acked-by: Hans Verkuil Reviewed-by: Javier Martinez Canillas Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 8 ++++---- drivers/media/media-entity.c | 8 ++++---- drivers/media/platform/vsp1/vsp1_video.c | 4 ++-- include/media/media-entity.h | 5 +++++ 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index c55ab5029323a..e429605ca2c37 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -77,8 +77,8 @@ static struct media_entity *find_entity(struct media_device *mdev, u32 id) spin_lock(&mdev->lock); media_device_for_each_entity(entity, mdev) { - if ((entity->id == id && !next) || - (entity->id > id && next)) { + if (((media_entity_id(entity) == id) && !next) || + ((media_entity_id(entity) > id) && next)) { spin_unlock(&mdev->lock); return entity; } @@ -104,7 +104,7 @@ static long media_device_enum_entities(struct media_device *mdev, if (ent == NULL) return -EINVAL; - u_ent.id = ent->id; + u_ent.id = media_entity_id(ent); if (ent->name) strlcpy(u_ent.name, ent->name, sizeof(u_ent.name)); u_ent.type = ent->type; @@ -122,7 +122,7 @@ static long media_device_enum_entities(struct media_device *mdev, static void media_device_kpad_to_upad(const struct media_pad *kpad, struct media_pad_desc *upad) { - upad->entity = kpad->entity->id; + upad->entity = media_entity_id(kpad->entity); upad->index = kpad->index; upad->flags = kpad->flags; } diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index eabcbacfe387c..0342be39cae22 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -140,10 +140,10 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph, graph->stack[graph->top].entity = NULL; bitmap_zero(graph->entities, MEDIA_ENTITY_ENUM_MAX_ID); - if (WARN_ON(entity->id >= MEDIA_ENTITY_ENUM_MAX_ID)) + if (WARN_ON(media_entity_id(entity) >= MEDIA_ENTITY_ENUM_MAX_ID)) return; - __set_bit(entity->id, graph->entities); + __set_bit(media_entity_id(entity), graph->entities); stack_push(graph, entity); } EXPORT_SYMBOL_GPL(media_entity_graph_walk_start); @@ -184,11 +184,11 @@ media_entity_graph_walk_next(struct media_entity_graph *graph) /* Get the entity in the other end of the link . */ next = media_entity_other(entity, link); - if (WARN_ON(next->id >= MEDIA_ENTITY_ENUM_MAX_ID)) + if (WARN_ON(media_entity_id(next) >= MEDIA_ENTITY_ENUM_MAX_ID)) return NULL; /* Has the entity already been visited? */ - if (__test_and_set_bit(next->id, graph->entities)) { + if (__test_and_set_bit(media_entity_id(next), graph->entities)) { link_top(graph)++; continue; } diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index fb52683b5c222..516595cff4083 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -323,10 +323,10 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe, break; /* Ensure the branch has no loop. */ - if (entities & (1 << entity->subdev.entity.id)) + if (entities & (1 << media_entity_id(&entity->subdev.entity))) return -EPIPE; - entities |= 1 << entity->subdev.entity.id; + entities |= 1 << media_entity_id(&entity->subdev.entity); /* UDS can't be chained. */ if (entity->type == VSP1_ENTITY_UDS) { diff --git a/include/media/media-entity.h b/include/media/media-entity.h index b92366317aee0..57881758927e0 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -113,6 +113,11 @@ static inline u32 media_entity_subtype(struct media_entity *entity) return entity->type & MEDIA_ENT_SUBTYPE_MASK; } +static inline u32 media_entity_id(struct media_entity *entity) +{ + return entity->id; +} + #define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 #define MEDIA_ENTITY_ENUM_MAX_ID 64 -- GitLab From 1302d39c4a7e31b9844638acb45c784633015cfd Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Wed, 19 Aug 2015 12:35:19 -0300 Subject: [PATCH 2444/2855] [media] staging: omap4iss: get entity ID using media_entity_id() Accessing media_entity ID should now use media_entity_id() macro to obtain the entity ID, as a next patch will remove the .id field from struct media_entity . So, get rid of it, otherwise the omap4iss driver will fail to build. Signed-off-by: Javier Martinez Canillas Acked-by: Hans Verkuil Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/omap4iss/iss.c | 2 +- drivers/staging/media/omap4iss/iss_video.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index e27a988540a6b..5fc3675b190f4 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -607,7 +607,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe, * crashed. Mark it as such, the ISS will be reset when * applications will release it. */ - iss->crashed |= 1U << subdev->entity.id; + iss->crashed |= 1U << media_entity_id(&subdev->entity); failure = -ETIMEDOUT; } } diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index 194c41ef822c9..dd8ff03912a71 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -782,7 +782,7 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) entity = &video->video.entity; media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) - pipe->entities |= 1 << entity->id; + pipe->entities |= 1 << media_entity_id(entity); /* Verify that the currently configured format matches the output of * the connected subdev. -- GitLab From e0077cfdee9d249d3f85b9c7efd9e49d218093c8 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Wed, 19 Aug 2015 12:35:20 -0300 Subject: [PATCH 2445/2855] [media] omap3isp: get entity ID using media_entity_id() Accessing media_entity ID should now use media_entity_id() macro to obtain the entity ID, as a next patch will remove the .id field from struct media_entity . So, get rid of it, otherwise the omap3isp driver will fail to build. Signed-off-by: Javier Martinez Canillas Acked-by: Hans Verkuil Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 7 +++++-- drivers/media/platform/omap3isp/ispccdc.c | 2 +- drivers/media/platform/omap3isp/ispvideo.c | 8 +++++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 56e683b19a73e..e08183f9d0f78 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -975,6 +975,7 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) struct v4l2_subdev *subdev; int failure = 0; int ret; + u32 id; /* * We need to stop all the modules after CCDC first or they'll @@ -1027,8 +1028,10 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) if (ret) { dev_info(isp->dev, "Unable to stop %s\n", subdev->name); isp->stop_failure = true; - if (subdev == &isp->isp_prev.subdev) - isp->crashed |= 1U << subdev->entity.id; + if (subdev == &isp->isp_prev.subdev) { + id = media_entity_id(&subdev->entity); + isp->crashed |= 1U << id; + } failure = -ETIMEDOUT; } } diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 3b10304b580bd..d96e3be5e252f 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -1608,7 +1608,7 @@ static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc) /* Wait for the CCDC to become idle. */ if (ccdc_sbl_wait_idle(ccdc, 1000)) { dev_info(isp->dev, "CCDC won't become idle!\n"); - isp->crashed |= 1U << ccdc->subdev.entity.id; + isp->crashed |= 1U << media_entity_id(&ccdc->subdev.entity); omap3isp_pipeline_cancel_stream(pipe); return 0; } diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index 963cb9318873d..0e129075e99ff 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -235,7 +235,7 @@ static int isp_video_get_graph_data(struct isp_video *video, while ((entity = media_entity_graph_walk_next(&graph))) { struct isp_video *__video; - pipe->entities |= 1 << entity->id; + pipe->entities |= 1 << media_entity_id(entity); if (far_end != NULL) continue; @@ -893,6 +893,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video, struct v4l2_ext_control ctrl; unsigned int i; int ret; + u32 id; /* Memory-to-memory pipelines have no external subdev. */ if (pipe->input != NULL) @@ -900,7 +901,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video, for (i = 0; i < ARRAY_SIZE(ents); i++) { /* Is the entity part of the pipeline? */ - if (!(pipe->entities & (1 << ents[i]->id))) + if (!(pipe->entities & (1 << media_entity_id(ents[i])))) continue; /* ISP entities have always sink pad == 0. Find source. */ @@ -952,7 +953,8 @@ static int isp_video_check_external_subdevs(struct isp_video *video, pipe->external_rate = ctrl.value64; - if (pipe->entities & (1 << isp->isp_ccdc.subdev.entity.id)) { + id = media_entity_id(&isp->isp_ccdc.subdev.entity); + if (pipe->entities & (1 << id)) { unsigned int rate = UINT_MAX; /* * Check that maximum allowed CCDC pixel rate isn't -- GitLab From ec6e4c950621a1d0db1e9b015ede4a3938fdfd18 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 25 Aug 2015 10:28:36 -0300 Subject: [PATCH 2446/2855] [media] media: add a common struct to be embed on media graph objects Due to the MC API proposed changes, we'll need to have an unique object ID for all graph objects, and have some shared fields that will be common on all media graph objects. Right now, the only common object is the object ID, but other fields will be added later on. Acked-by: Hans Verkuil Reviewed-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 32 +++++++++++++++++++ include/media/media-entity.h | 61 ++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 0342be39cae22..a76655c2ddef2 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -26,6 +26,38 @@ #include #include +/** + * media_gobj_init - Initialize a graph object + * + * @mdev: Pointer to the media_device that contains the object + * @type: Type of the object + * @gobj: Pointer to the object + * + * This routine initializes the embedded struct media_gobj inside a + * media graph object. It is called automatically if media_*_create() + * calls are used. However, if the object (entity, link, pad, interface) + * is embedded on some other object, this function should be called before + * registering the object at the media controller. + */ +void media_gobj_init(struct media_device *mdev, + enum media_gobj_type type, + struct media_gobj *gobj) +{ + /* For now, nothing to do */ +} + +/** + * media_gobj_remove - Stop using a graph object on a media device + * + * @graph_obj: Pointer to the object + * + * This should be called at media_device_unregister_*() routines + */ +void media_gobj_remove(struct media_gobj *gobj) +{ + /* For now, nothing to do */ +} + /** * media_entity_init - Initialize a media entity * diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 57881758927e0..96626356b8f37 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -28,6 +28,39 @@ #include #include +/* Enums used internally at the media controller to represent graphs */ + +/** + * enum media_gobj_type - type of a graph object + * + */ +enum media_gobj_type { + /* FIXME: add the types here, as we embed media_gobj */ + MEDIA_GRAPH_NONE +}; + +#define MEDIA_BITS_PER_TYPE 8 +#define MEDIA_BITS_PER_LOCAL_ID (32 - MEDIA_BITS_PER_TYPE) +#define MEDIA_LOCAL_ID_MASK GENMASK(MEDIA_BITS_PER_LOCAL_ID - 1, 0) + +/* Structs to represent the objects that belong to a media graph */ + +/** + * struct media_gobj - Define a graph object. + * + * @id: Non-zero object ID identifier. The ID should be unique + * inside a media_device, as it is composed by + * MEDIA_BITS_PER_TYPE to store the type plus + * MEDIA_BITS_PER_LOCAL_ID to store a per-type ID + * (called as "local ID"). + * + * All objects on the media graph should have this struct embedded + */ +struct media_gobj { + u32 id; +}; + + struct media_pipeline { }; @@ -118,6 +151,26 @@ static inline u32 media_entity_id(struct media_entity *entity) return entity->id; } +static inline enum media_gobj_type media_type(struct media_gobj *gobj) +{ + return gobj->id >> MEDIA_BITS_PER_LOCAL_ID; +} + +static inline u32 media_localid(struct media_gobj *gobj) +{ + return gobj->id & MEDIA_LOCAL_ID_MASK; +} + +static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id) +{ + u32 id; + + id = type << MEDIA_BITS_PER_LOCAL_ID; + id |= local_id & MEDIA_LOCAL_ID_MASK; + + return id; +} + #define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 #define MEDIA_ENTITY_ENUM_MAX_ID 64 @@ -138,6 +191,14 @@ struct media_entity_graph { int top; }; +#define gobj_to_entity(gobj) \ + container_of(gobj, struct media_entity, graph_obj) + +void media_gobj_init(struct media_device *mdev, + enum media_gobj_type type, + struct media_gobj *gobj); +void media_gobj_remove(struct media_gobj *gobj); + int media_entity_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads); void media_entity_cleanup(struct media_entity *entity); -- GitLab From bfab2aacccfc144e2cceccb71ec89f1eff1b8c51 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Aug 2015 12:47:48 -0300 Subject: [PATCH 2447/2855] [media] media: use media_gobj inside entities As entities are graph objects, let's embed media_gobj on it. That ensures an unique ID for entities that can be global along the entire media controller. For now, we'll keep the already existing entity ID. Such field need to be dropped at some point, but for now, let's not do this, to avoid needing to review all drivers and the userspace apps. Acked-by: Hans Verkuil Tested-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 8 +++----- drivers/media/media-entity.c | 7 ++++++- include/media/media-device.h | 3 ++- include/media/media-entity.h | 9 ++++----- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index e429605ca2c37..81d6a130efef5 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -379,7 +379,6 @@ int __must_check __media_device_register(struct media_device *mdev, if (WARN_ON(mdev->dev == NULL || mdev->model[0] == 0)) return -EINVAL; - mdev->entity_id = 1; INIT_LIST_HEAD(&mdev->entities); spin_lock_init(&mdev->lock); mutex_init(&mdev->graph_mutex); @@ -433,10 +432,8 @@ int __must_check media_device_register_entity(struct media_device *mdev, entity->parent = mdev; spin_lock(&mdev->lock); - if (entity->id == 0) - entity->id = mdev->entity_id++; - else - mdev->entity_id = max(entity->id + 1, mdev->entity_id); + /* Initialize media_gobj embedded at the entity */ + media_gobj_init(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); list_add_tail(&entity->list, &mdev->entities); spin_unlock(&mdev->lock); @@ -459,6 +456,7 @@ void media_device_unregister_entity(struct media_entity *entity) return; spin_lock(&mdev->lock); + media_gobj_remove(&entity->graph_obj); list_del(&entity->list); spin_unlock(&mdev->lock); entity->parent = NULL; diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index a76655c2ddef2..9f6f056eaeb01 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -43,7 +43,12 @@ void media_gobj_init(struct media_device *mdev, enum media_gobj_type type, struct media_gobj *gobj) { - /* For now, nothing to do */ + /* Create a per-type unique object ID */ + switch (type) { + case MEDIA_GRAPH_ENTITY: + gobj->id = media_gobj_gen_id(type, ++mdev->entity_id); + break; + } } /** diff --git a/include/media/media-device.h b/include/media/media-device.h index a44f18fdf321d..f6deef6e58206 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -41,7 +41,7 @@ struct device; * @bus_info: Unique and stable device location identifier * @hw_revision: Hardware device revision * @driver_version: Device driver version - * @entity_id: ID of the next entity to be registered + * @entity_id: Unique ID used on the last entity registered * @entities: List of registered entities * @lock: Entities list lock * @graph_mutex: Entities graph operation lock @@ -69,6 +69,7 @@ struct media_device { u32 driver_version; u32 entity_id; + struct list_head entities; /* Protects the entities list */ diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 96626356b8f37..4faa4d830da4b 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -33,10 +33,10 @@ /** * enum media_gobj_type - type of a graph object * + * @MEDIA_GRAPH_ENTITY: Identify a media entity */ enum media_gobj_type { - /* FIXME: add the types here, as we embed media_gobj */ - MEDIA_GRAPH_NONE + MEDIA_GRAPH_ENTITY, }; #define MEDIA_BITS_PER_TYPE 8 @@ -94,10 +94,9 @@ struct media_entity_operations { }; struct media_entity { + struct media_gobj graph_obj; struct list_head list; struct media_device *parent; /* Media device this entity belongs to*/ - u32 id; /* Entity ID, unique in the parent media - * device context */ const char *name; /* Entity name */ u32 type; /* Entity type (MEDIA_ENT_T_*) */ u32 revision; /* Entity revision, driver specific */ @@ -148,7 +147,7 @@ static inline u32 media_entity_subtype(struct media_entity *entity) static inline u32 media_entity_id(struct media_entity *entity) { - return entity->id; + return entity->graph_obj.id; } static inline enum media_gobj_type media_type(struct media_gobj *gobj) -- GitLab From 18710dc67a433ed2c3ecaaffefd8e34502e53262 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Aug 2015 12:50:08 -0300 Subject: [PATCH 2448/2855] [media] media: use media_gobj inside pads PADs also need unique object IDs that won't conflict with the entity object IDs. The pad objects are currently created via media_entity_init() and, once created, never change. While this will likely change in the future in order to support dynamic changes, for now we'll keep PADs as arrays and initialize the media_gobj embedded structs when registering the entity. Acked-by: Hans Verkuil Tested-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 11 +++++++++++ drivers/media/media-entity.c | 3 +++ include/media/media-device.h | 2 ++ include/media/media-entity.h | 3 +++ 4 files changed, 19 insertions(+) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 81d6a130efef5..3bdda16584fe9 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -427,6 +427,8 @@ EXPORT_SYMBOL_GPL(media_device_unregister); int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity) { + int i; + /* Warn if we apparently re-register an entity */ WARN_ON(entity->parent != NULL); entity->parent = mdev; @@ -435,6 +437,12 @@ int __must_check media_device_register_entity(struct media_device *mdev, /* Initialize media_gobj embedded at the entity */ media_gobj_init(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); list_add_tail(&entity->list, &mdev->entities); + + /* Initialize objects at the pads */ + for (i = 0; i < entity->num_pads; i++) + media_gobj_init(mdev, MEDIA_GRAPH_PAD, + &entity->pads[i].graph_obj); + spin_unlock(&mdev->lock); return 0; @@ -450,12 +458,15 @@ EXPORT_SYMBOL_GPL(media_device_register_entity); */ void media_device_unregister_entity(struct media_entity *entity) { + int i; struct media_device *mdev = entity->parent; if (mdev == NULL) return; spin_lock(&mdev->lock); + for (i = 0; i < entity->num_pads; i++) + media_gobj_remove(&entity->pads[i].graph_obj); media_gobj_remove(&entity->graph_obj); list_del(&entity->list); spin_unlock(&mdev->lock); diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 9f6f056eaeb01..2d94c859057b2 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -48,6 +48,9 @@ void media_gobj_init(struct media_device *mdev, case MEDIA_GRAPH_ENTITY: gobj->id = media_gobj_gen_id(type, ++mdev->entity_id); break; + case MEDIA_GRAPH_PAD: + gobj->id = media_gobj_gen_id(type, ++mdev->pad_id); + break; } } diff --git a/include/media/media-device.h b/include/media/media-device.h index f6deef6e58206..9493721f630ec 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -42,6 +42,7 @@ struct device; * @hw_revision: Hardware device revision * @driver_version: Device driver version * @entity_id: Unique ID used on the last entity registered + * @pad_id: Unique ID used on the last pad registered * @entities: List of registered entities * @lock: Entities list lock * @graph_mutex: Entities graph operation lock @@ -69,6 +70,7 @@ struct media_device { u32 driver_version; u32 entity_id; + u32 pad_id; struct list_head entities; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 4faa4d830da4b..b91c78d34f79b 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -34,9 +34,11 @@ * enum media_gobj_type - type of a graph object * * @MEDIA_GRAPH_ENTITY: Identify a media entity + * @MEDIA_GRAPH_PAD: Identify a media pad */ enum media_gobj_type { MEDIA_GRAPH_ENTITY, + MEDIA_GRAPH_PAD, }; #define MEDIA_BITS_PER_TYPE 8 @@ -72,6 +74,7 @@ struct media_link { }; struct media_pad { + struct media_gobj graph_obj; struct media_entity *entity; /* Entity this pad belongs to */ u16 index; /* Pad index in the entity pads array */ unsigned long flags; /* Pad flags (MEDIA_PAD_FL_*) */ -- GitLab From 6b6a42780597028135f82c96e42c6d2bcd83fbae Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Aug 2015 12:54:36 -0300 Subject: [PATCH 2449/2855] [media] media: use media_gobj inside links Just like entities and pads, links also need to have unique Object IDs along a given media controller. So, let's add a media_gobj inside it and initialize the object then a new link is created. Acked-by: Hans Verkuil Tested-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 9 +++++++++ drivers/media/media-entity.c | 9 +++++++++ include/media/media-device.h | 2 ++ include/media/media-entity.h | 3 +++ 4 files changed, 23 insertions(+) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 3bdda16584fe9..065f6f08da370 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -438,6 +438,13 @@ int __must_check media_device_register_entity(struct media_device *mdev, media_gobj_init(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); list_add_tail(&entity->list, &mdev->entities); + /* + * Initialize objects at the links + * in the case where links got created before entity register + */ + for (i = 0; i < entity->num_links; i++) + media_gobj_init(mdev, MEDIA_GRAPH_LINK, + &entity->links[i].graph_obj); /* Initialize objects at the pads */ for (i = 0; i < entity->num_pads; i++) media_gobj_init(mdev, MEDIA_GRAPH_PAD, @@ -465,6 +472,8 @@ void media_device_unregister_entity(struct media_entity *entity) return; spin_lock(&mdev->lock); + for (i = 0; i < entity->num_links; i++) + media_gobj_remove(&entity->links[i].graph_obj); for (i = 0; i < entity->num_pads; i++) media_gobj_remove(&entity->pads[i].graph_obj); media_gobj_remove(&entity->graph_obj); diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 2d94c859057b2..63fd293a3fb88 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -51,6 +51,9 @@ void media_gobj_init(struct media_device *mdev, case MEDIA_GRAPH_PAD: gobj->id = media_gobj_gen_id(type, ++mdev->pad_id); break; + case MEDIA_GRAPH_LINK: + gobj->id = media_gobj_gen_id(type, ++mdev->link_id); + break; } } @@ -491,6 +494,9 @@ media_entity_create_link(struct media_entity *source, u16 source_pad, link->sink = &sink->pads[sink_pad]; link->flags = flags; + /* Initialize graph object embedded at the new link */ + media_gobj_init(source->parent, MEDIA_GRAPH_LINK, &link->graph_obj); + /* Create the backlink. Backlinks are used to help graph traversal and * are not reported to userspace. */ @@ -504,6 +510,9 @@ media_entity_create_link(struct media_entity *source, u16 source_pad, backlink->sink = &sink->pads[sink_pad]; backlink->flags = flags; + /* Initialize graph object embedded at the new link */ + media_gobj_init(sink->parent, MEDIA_GRAPH_LINK, &backlink->graph_obj); + link->reverse = backlink; backlink->reverse = link; diff --git a/include/media/media-device.h b/include/media/media-device.h index 9493721f630ec..05414e351f8e3 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -43,6 +43,7 @@ struct device; * @driver_version: Device driver version * @entity_id: Unique ID used on the last entity registered * @pad_id: Unique ID used on the last pad registered + * @link_id: Unique ID used on the last link registered * @entities: List of registered entities * @lock: Entities list lock * @graph_mutex: Entities graph operation lock @@ -71,6 +72,7 @@ struct media_device { u32 entity_id; u32 pad_id; + u32 link_id; struct list_head entities; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index b91c78d34f79b..bf93c90e92188 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -35,10 +35,12 @@ * * @MEDIA_GRAPH_ENTITY: Identify a media entity * @MEDIA_GRAPH_PAD: Identify a media pad + * @MEDIA_GRAPH_LINK: Identify a media link */ enum media_gobj_type { MEDIA_GRAPH_ENTITY, MEDIA_GRAPH_PAD, + MEDIA_GRAPH_LINK, }; #define MEDIA_BITS_PER_TYPE 8 @@ -67,6 +69,7 @@ struct media_pipeline { }; struct media_link { + struct media_gobj graph_obj; struct media_pad *source; /* Source pad */ struct media_pad *sink; /* Sink pad */ struct media_link *reverse; /* Link in the reverse direction */ -- GitLab From 8f5a3188fbd13fdd5525fc6177cb19bf3996ee99 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Aug 2015 15:22:24 -0300 Subject: [PATCH 2450/2855] [media] media: add messages when media device gets (un)registered We can only free the media device after being sure that no graph object is used. In order to help tracking it, let's add debug messages that will print when the media controller gets registered or unregistered. Acked-by: Hans Verkuil Reviewed-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 065f6f08da370..0f3844470147e 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -359,6 +359,7 @@ static DEVICE_ATTR(model, S_IRUGO, show_model, NULL); static void media_device_release(struct media_devnode *mdev) { + dev_dbg(mdev->parent, "Media device released\n"); } /** @@ -397,6 +398,8 @@ int __must_check __media_device_register(struct media_device *mdev, return ret; } + dev_dbg(mdev->dev, "Media device registered\n"); + return 0; } EXPORT_SYMBOL_GPL(__media_device_register); @@ -416,6 +419,8 @@ void media_device_unregister(struct media_device *mdev) device_remove_file(&mdev->devnode.dev, &dev_attr_model); media_devnode_unregister(&mdev->devnode); + + dev_dbg(mdev->dev, "Media device unregistered\n"); } EXPORT_SYMBOL_GPL(media_device_unregister); -- GitLab From 39a956c4147e4f696f729916f677673e9a9dc7ab Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Aug 2015 14:42:42 -0300 Subject: [PATCH 2451/2855] [media] media: add a debug message to warn about gobj creation/removal It helps to check if the media controller is doing the right thing with the object creation and removal. No extra code/data will be produced if DEBUG or CONFIG_DYNAMIC_DEBUG is not enabled. Acked-by: Hans Verkuil Reviewed-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 68 +++++++++++++++++++++++++++++++++++- include/media/media-entity.h | 7 ++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 63fd293a3fb88..f5b4822a324fb 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -26,6 +26,69 @@ #include #include +/** + * dev_dbg_obj - Prints in debug mode a change on some object + * + * @event_name: Name of the event to report. Could be __func__ + * @gobj: Pointer to the object + * + * Enabled only if DEBUG or CONFIG_DYNAMIC_DEBUG. Otherwise, it + * won't produce any code. + */ +static inline const char *gobj_type(enum media_gobj_type type) +{ + switch (type) { + case MEDIA_GRAPH_ENTITY: + return "entity"; + case MEDIA_GRAPH_PAD: + return "pad"; + case MEDIA_GRAPH_LINK: + return "link"; + default: + return "unknown"; + } +} + +static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) +{ +#if defined(DEBUG) || defined (CONFIG_DYNAMIC_DEBUG) + switch (media_type(gobj)) { + case MEDIA_GRAPH_ENTITY: + dev_dbg(gobj->mdev->dev, + "%s: id 0x%08x entity#%d: '%s'\n", + event_name, gobj->id, media_localid(gobj), + gobj_to_entity(gobj)->name); + break; + case MEDIA_GRAPH_LINK: + { + struct media_link *link = gobj_to_link(gobj); + + dev_dbg(gobj->mdev->dev, + "%s: id 0x%08x link#%d: '%s' %s#%d ==> '%s' %s#%d\n", + event_name, gobj->id, media_localid(gobj), + + link->source->entity->name, + gobj_type(media_type(&link->source->graph_obj)), + media_localid(&link->source->graph_obj), + + link->sink->entity->name, + gobj_type(media_type(&link->sink->graph_obj)), + media_localid(&link->sink->graph_obj)); + break; + } + case MEDIA_GRAPH_PAD: + { + struct media_pad *pad = gobj_to_pad(gobj); + + dev_dbg(gobj->mdev->dev, + "%s: id 0x%08x pad#%d: '%s':%d\n", + event_name, gobj->id, media_localid(gobj), + pad->entity->name, pad->index); + } + } +#endif +} + /** * media_gobj_init - Initialize a graph object * @@ -43,6 +106,8 @@ void media_gobj_init(struct media_device *mdev, enum media_gobj_type type, struct media_gobj *gobj) { + gobj->mdev = mdev; + /* Create a per-type unique object ID */ switch (type) { case MEDIA_GRAPH_ENTITY: @@ -55,6 +120,7 @@ void media_gobj_init(struct media_device *mdev, gobj->id = media_gobj_gen_id(type, ++mdev->link_id); break; } + dev_dbg_obj(__func__, gobj); } /** @@ -66,7 +132,7 @@ void media_gobj_init(struct media_device *mdev, */ void media_gobj_remove(struct media_gobj *gobj) { - /* For now, nothing to do */ + dev_dbg_obj(__func__, gobj); } /** diff --git a/include/media/media-entity.h b/include/media/media-entity.h index bf93c90e92188..96a5d3e6f6f43 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -61,6 +61,7 @@ enum media_gobj_type { * All objects on the media graph should have this struct embedded */ struct media_gobj { + struct media_device *mdev; u32 id; }; @@ -199,6 +200,12 @@ struct media_entity_graph { #define gobj_to_entity(gobj) \ container_of(gobj, struct media_entity, graph_obj) +#define gobj_to_pad(gobj) \ + container_of(gobj, struct media_pad, graph_obj) + +#define gobj_to_link(gobj) \ + container_of(gobj, struct media_link, graph_obj) + void media_gobj_init(struct media_device *mdev, enum media_gobj_type type, struct media_gobj *gobj); -- GitLab From 8df00a15817e3a252510ac914870214859325189 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 7 Aug 2015 08:14:38 -0300 Subject: [PATCH 2452/2855] [media] media: rename the function that create pad links With the new API, a link can be either between two PADs or between an interface and an entity. So, we need to use a better name for the function that create links between two pads. So, rename the such function to media_create_pad_link(). No functional changes. This patch was created via this shell script: for i in $(find drivers/media -name '*.[ch]' -type f) $(find drivers/staging/media -name '*.[ch]' -type f) $(find include/ -name '*.h' -type f) ; do sed s,media_entity_create_link,media_create_pad_link,g <$i >a && mv a $i; done Acked-by: Hans Verkuil Tested-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- Documentation/media-framework.txt | 2 +- drivers/media/dvb-core/dvbdev.c | 8 ++++---- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 4 ++-- drivers/media/i2c/s5k5baf.c | 2 +- drivers/media/i2c/smiapp/smiapp-core.c | 4 ++-- drivers/media/media-entity.c | 4 ++-- drivers/media/platform/exynos4-is/media-dev.c | 16 ++++++++-------- drivers/media/platform/omap3isp/isp.c | 18 +++++++++--------- drivers/media/platform/omap3isp/ispccdc.c | 2 +- drivers/media/platform/omap3isp/ispccp2.c | 2 +- drivers/media/platform/omap3isp/ispcsi2.c | 2 +- drivers/media/platform/omap3isp/isppreview.c | 4 ++-- drivers/media/platform/omap3isp/ispresizer.c | 4 ++-- drivers/media/platform/s3c-camif/camif-core.c | 4 ++-- drivers/media/platform/vsp1/vsp1_drv.c | 4 ++-- drivers/media/platform/vsp1/vsp1_rpf.c | 2 +- drivers/media/platform/vsp1/vsp1_wpf.c | 2 +- drivers/media/platform/xilinx/xilinx-vipp.c | 4 ++-- drivers/media/usb/au0828/au0828-core.c | 6 +++--- drivers/media/usb/cx231xx/cx231xx-cards.c | 6 +++--- drivers/media/usb/uvc/uvc_entity.c | 2 +- .../staging/media/davinci_vpfe/dm365_ipipeif.c | 2 +- .../staging/media/davinci_vpfe/dm365_isif.c | 2 +- .../staging/media/davinci_vpfe/dm365_resizer.c | 8 ++++---- .../media/davinci_vpfe/vpfe_mc_capture.c | 10 +++++----- drivers/staging/media/omap4iss/iss.c | 12 ++++++------ drivers/staging/media/omap4iss/iss_csi2.c | 2 +- drivers/staging/media/omap4iss/iss_ipipeif.c | 2 +- drivers/staging/media/omap4iss/iss_resizer.c | 2 +- include/media/media-entity.h | 2 +- 30 files changed, 72 insertions(+), 72 deletions(-) diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt index 6903b25035774..b424de6c3bb33 100644 --- a/Documentation/media-framework.txt +++ b/Documentation/media-framework.txt @@ -199,7 +199,7 @@ pre-allocated and grows dynamically as needed. Drivers create links by calling - media_entity_create_link(struct media_entity *source, u16 source_pad, + media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags); diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 2fdcbb5f000a9..65f59f2124b46 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -412,16 +412,16 @@ void dvb_create_media_graph(struct dvb_adapter *adap) } if (tuner && fe) - media_entity_create_link(tuner, 0, fe, 0, 0); + media_create_pad_link(tuner, 0, fe, 0, 0); if (fe && demux) - media_entity_create_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED); + media_create_pad_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED); if (demux && dvr) - media_entity_create_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED); + media_create_pad_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED); if (demux && ca) - media_entity_create_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED); + media_create_pad_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED); } EXPORT_SYMBOL_GPL(dvb_create_media_graph); #endif diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index 381f903831f47..45c823b68f489 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1482,11 +1482,11 @@ static int s5c73m3_oif_registered(struct v4l2_subdev *sd) return ret; } - ret = media_entity_create_link(&state->sensor_sd.entity, + ret = media_create_pad_link(&state->sensor_sd.entity, S5C73M3_ISP_PAD, &state->oif_sd.entity, OIF_ISP_PAD, MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); - ret = media_entity_create_link(&state->sensor_sd.entity, + ret = media_create_pad_link(&state->sensor_sd.entity, S5C73M3_JPEG_PAD, &state->oif_sd.entity, OIF_JPEG_PAD, MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 30a9ca62e034d..d3bff30bcb6f8 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -1756,7 +1756,7 @@ static int s5k5baf_registered(struct v4l2_subdev *sd) v4l2_err(sd, "failed to register subdev %s\n", state->cis_sd.name); else - ret = media_entity_create_link(&state->cis_sd.entity, PAD_CIS, + ret = media_create_pad_link(&state->cis_sd.entity, PAD_CIS, &state->sd.entity, PAD_CIS, MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 7ed0538ea8db2..cf0cd507c2d0c 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2495,7 +2495,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor) return rval; } - rval = media_entity_create_link(&this->sd.entity, + rval = media_create_pad_link(&this->sd.entity, this->source_pad, &last->sd.entity, last->sink_pad, @@ -2503,7 +2503,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor) MEDIA_LNK_FL_IMMUTABLE); if (rval) { dev_err(&client->dev, - "media_entity_create_link failed\n"); + "media_create_pad_link failed\n"); return rval; } diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index f5b4822a324fb..e840da0325b71 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -542,7 +542,7 @@ static struct media_link *media_entity_add_link(struct media_entity *entity) } int -media_entity_create_link(struct media_entity *source, u16 source_pad, +media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags) { struct media_link *link; @@ -586,7 +586,7 @@ media_entity_create_link(struct media_entity *source, u16 source_pad, return 0; } -EXPORT_SYMBOL_GPL(media_entity_create_link); +EXPORT_SYMBOL_GPL(media_create_pad_link); void __media_entity_remove_links(struct media_entity *entity) { diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 9481ce3201a2c..4c524a02c59c6 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -729,7 +729,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd, flags = ((1 << i) & link_mask) ? MEDIA_LNK_FL_ENABLED : 0; sink = &fmd->fimc[i]->vid_cap.subdev.entity; - ret = media_entity_create_link(source, pad, sink, + ret = media_create_pad_link(source, pad, sink, FIMC_SD_PAD_SINK_CAM, flags); if (ret) return ret; @@ -749,7 +749,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd, continue; sink = &fmd->fimc_lite[i]->subdev.entity; - ret = media_entity_create_link(source, pad, sink, + ret = media_create_pad_link(source, pad, sink, FLITE_SD_PAD_SINK, 0); if (ret) return ret; @@ -781,13 +781,13 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd) source = &fimc->subdev.entity; sink = &fimc->ve.vdev.entity; /* FIMC-LITE's subdev and video node */ - ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_DMA, + ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_DMA, sink, 0, 0); if (ret) break; /* Link from FIMC-LITE to IS-ISP subdev */ sink = &fmd->fimc_is->isp.subdev.entity; - ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_ISP, + ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_ISP, sink, 0, 0); if (ret) break; @@ -811,7 +811,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd) /* Link from FIMC-IS-ISP subdev to FIMC */ sink = &fmd->fimc[i]->vid_cap.subdev.entity; - ret = media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_FIFO, + ret = media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_FIFO, sink, FIMC_SD_PAD_SINK_FIFO, 0); if (ret) return ret; @@ -824,7 +824,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd) if (sink->num_pads == 0) return 0; - return media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_DMA, + return media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_DMA, sink, 0, 0); } @@ -873,7 +873,7 @@ static int fimc_md_create_links(struct fimc_md *fmd) return -EINVAL; pad = sensor->entity.num_pads - 1; - ret = media_entity_create_link(&sensor->entity, pad, + ret = media_create_pad_link(&sensor->entity, pad, &csis->entity, CSIS_PAD_SINK, MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); @@ -927,7 +927,7 @@ static int fimc_md_create_links(struct fimc_md *fmd) source = &fmd->fimc[i]->vid_cap.subdev.entity; sink = &fmd->fimc[i]->vid_cap.ve.vdev.entity; - ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE, + ret = media_create_pad_link(source, FIMC_SD_PAD_SOURCE, sink, 0, flags); if (ret) break; diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index e08183f9d0f78..6351f35b0a656 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -1865,7 +1865,7 @@ static int isp_link_entity( return -EINVAL; } - return media_entity_create_link(entity, i, input, pad, flags); + return media_create_pad_link(entity, i, input, pad, flags); } static int isp_register_entities(struct isp_device *isp) @@ -2004,51 +2004,51 @@ static int isp_initialize_modules(struct isp_device *isp) } /* Connect the submodules. */ - ret = media_entity_create_link( + ret = media_create_pad_link( &isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE, &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0); if (ret < 0) goto error_link; - ret = media_entity_create_link( + ret = media_create_pad_link( &isp->isp_ccp2.subdev.entity, CCP2_PAD_SOURCE, &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0); if (ret < 0) goto error_link; - ret = media_entity_create_link( + ret = media_create_pad_link( &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP, &isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0); if (ret < 0) goto error_link; - ret = media_entity_create_link( + ret = media_create_pad_link( &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF, &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0); if (ret < 0) goto error_link; - ret = media_entity_create_link( + ret = media_create_pad_link( &isp->isp_prev.subdev.entity, PREV_PAD_SOURCE, &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0); if (ret < 0) goto error_link; - ret = media_entity_create_link( + ret = media_create_pad_link( &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP, &isp->isp_aewb.subdev.entity, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); if (ret < 0) goto error_link; - ret = media_entity_create_link( + ret = media_create_pad_link( &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP, &isp->isp_af.subdev.entity, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); if (ret < 0) goto error_link; - ret = media_entity_create_link( + ret = media_create_pad_link( &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP, &isp->isp_hist.subdev.entity, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index d96e3be5e252f..27555e4f4aa82 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -2667,7 +2667,7 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc) goto error_video; /* Connect the CCDC subdev to the video node. */ - ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF, + ret = media_create_pad_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF, &ccdc->video_out.video.entity, 0, 0); if (ret < 0) goto error_link; diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index e1b5f5bea541f..b215eb5049d65 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -1100,7 +1100,7 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2) goto error_video; /* Connect the video node to the ccp2 subdev. */ - ret = media_entity_create_link(&ccp2->video_in.video.entity, 0, + ret = media_create_pad_link(&ccp2->video_in.video.entity, 0, &ccp2->subdev.entity, CCP2_PAD_SINK, 0); if (ret < 0) goto error_link; diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index 6fff92f0813a0..fcefc1e74881f 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c @@ -1265,7 +1265,7 @@ static int csi2_init_entities(struct isp_csi2_device *csi2) goto error_video; /* Connect the CSI2 subdev to the video node. */ - ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE, + ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE, &csi2->video_out.video.entity, 0, 0); if (ret < 0) goto error_link; diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index b440c6342ca49..ad38d20c77702 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c @@ -2312,12 +2312,12 @@ static int preview_init_entities(struct isp_prev_device *prev) goto error_video_out; /* Connect the video nodes to the previewer subdev. */ - ret = media_entity_create_link(&prev->video_in.video.entity, 0, + ret = media_create_pad_link(&prev->video_in.video.entity, 0, &prev->subdev.entity, PREV_PAD_SINK, 0); if (ret < 0) goto error_link; - ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE, + ret = media_create_pad_link(&prev->subdev.entity, PREV_PAD_SOURCE, &prev->video_out.video.entity, 0, 0); if (ret < 0) goto error_link; diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c index 3deb1ec4a973a..b48ad4d4b8349 100644 --- a/drivers/media/platform/omap3isp/ispresizer.c +++ b/drivers/media/platform/omap3isp/ispresizer.c @@ -1756,12 +1756,12 @@ static int resizer_init_entities(struct isp_res_device *res) res->video_out.video.entity.flags |= MEDIA_ENT_FL_DEFAULT; /* Connect the video nodes to the resizer subdev. */ - ret = media_entity_create_link(&res->video_in.video.entity, 0, + ret = media_create_pad_link(&res->video_in.video.entity, 0, &res->subdev.entity, RESZ_PAD_SINK, 0); if (ret < 0) goto error_link; - ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE, + ret = media_create_pad_link(&res->subdev.entity, RESZ_PAD_SOURCE, &res->video_out.video.entity, 0, 0); if (ret < 0) goto error_link; diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c index 1ba9bb08f5da2..8649d4c0e90d5 100644 --- a/drivers/media/platform/s3c-camif/camif-core.c +++ b/drivers/media/platform/s3c-camif/camif-core.c @@ -263,7 +263,7 @@ static int camif_create_media_links(struct camif_dev *camif) { int i, ret; - ret = media_entity_create_link(&camif->sensor.sd->entity, 0, + ret = media_create_pad_link(&camif->sensor.sd->entity, 0, &camif->subdev.entity, CAMIF_SD_PAD_SINK, MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); @@ -271,7 +271,7 @@ static int camif_create_media_links(struct camif_dev *camif) return ret; for (i = 1; i < CAMIF_SD_PADS_NUM && !ret; i++) { - ret = media_entity_create_link(&camif->subdev.entity, i, + ret = media_create_pad_link(&camif->subdev.entity, i, &camif->vp[i - 1].vdev.entity, 0, MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 4e61886384e32..9cd94a76a9ed2 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -101,7 +101,7 @@ static int vsp1_create_links(struct vsp1_device *vsp1, struct vsp1_entity *sink) if (!(entity->pads[pad].flags & MEDIA_PAD_FL_SINK)) continue; - ret = media_entity_create_link(&source->subdev.entity, + ret = media_create_pad_link(&source->subdev.entity, source->source_pad, entity, pad, flags); if (ret < 0) @@ -262,7 +262,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) } if (vsp1->pdata.features & VSP1_HAS_LIF) { - ret = media_entity_create_link( + ret = media_create_pad_link( &vsp1->wpf[0]->entity.subdev.entity, RWPF_PAD_SOURCE, &vsp1->lif->entity.subdev.entity, LIF_PAD_SINK, 0); if (ret < 0) diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c index cd5248a9a2711..1bd51d22ff044 100644 --- a/drivers/media/platform/vsp1/vsp1_rpf.c +++ b/drivers/media/platform/vsp1/vsp1_rpf.c @@ -278,7 +278,7 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index) rpf->entity.video = video; /* Connect the video device to the RPF. */ - ret = media_entity_create_link(&rpf->video.video.entity, 0, + ret = media_create_pad_link(&rpf->video.video.entity, 0, &rpf->entity.subdev.entity, RWPF_PAD_SINK, MEDIA_LNK_FL_ENABLED | diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c index 95b62f4f77e78..ca19c534dac6d 100644 --- a/drivers/media/platform/vsp1/vsp1_wpf.c +++ b/drivers/media/platform/vsp1/vsp1_wpf.c @@ -284,7 +284,7 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index) if (!(vsp1->pdata.features & VSP1_HAS_LIF) || index != 0) flags |= MEDIA_LNK_FL_IMMUTABLE; - ret = media_entity_create_link(&wpf->entity.subdev.entity, + ret = media_create_pad_link(&wpf->entity.subdev.entity, RWPF_PAD_SOURCE, &wpf->video.video.entity, 0, flags); if (ret < 0) diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c index b9bf24fefa5a6..2352f7e5a6a3d 100644 --- a/drivers/media/platform/xilinx/xilinx-vipp.c +++ b/drivers/media/platform/xilinx/xilinx-vipp.c @@ -156,7 +156,7 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev, local->name, local_pad->index, remote->name, remote_pad->index); - ret = media_entity_create_link(local, local_pad->index, + ret = media_create_pad_link(local, local_pad->index, remote, remote_pad->index, link_flags); if (ret < 0) { @@ -270,7 +270,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev) source->name, source_pad->index, sink->name, sink_pad->index); - ret = media_entity_create_link(source, source_pad->index, + ret = media_create_pad_link(source, source_pad->index, sink, sink_pad->index, link_flags); if (ret < 0) { diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 0378a2c99ebb4..a55eb524ea21f 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -260,13 +260,13 @@ static void au0828_create_media_graph(struct au0828_dev *dev) return; if (tuner) - media_entity_create_link(tuner, 0, decoder, 0, + media_create_pad_link(tuner, 0, decoder, 0, MEDIA_LNK_FL_ENABLED); if (dev->vdev.entity.links) - media_entity_create_link(decoder, 1, &dev->vdev.entity, 0, + media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, MEDIA_LNK_FL_ENABLED); if (dev->vbi_dev.entity.links) - media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0, + media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0, MEDIA_LNK_FL_ENABLED); #endif } diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 89dc695c696e5..695f0c092c794 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1264,11 +1264,11 @@ static void cx231xx_create_media_graph(struct cx231xx *dev) return; if (tuner) - media_entity_create_link(tuner, 0, decoder, 0, + media_create_pad_link(tuner, 0, decoder, 0, MEDIA_LNK_FL_ENABLED); - media_entity_create_link(decoder, 1, &dev->vdev.entity, 0, + media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, MEDIA_LNK_FL_ENABLED); - media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0, + media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0, MEDIA_LNK_FL_ENABLED); #endif } diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c index 2454454915161..429e428ccd93f 100644 --- a/drivers/media/usb/uvc/uvc_entity.c +++ b/drivers/media/usb/uvc/uvc_entity.c @@ -56,7 +56,7 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain, continue; remote_pad = remote->num_pads - 1; - ret = media_entity_create_link(source, remote_pad, + ret = media_create_pad_link(source, remote_pad, sink, i, flags); if (ret < 0) return ret; diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c index 8fb6761868986..d96bdaaae50e5 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c @@ -971,7 +971,7 @@ vpfe_ipipeif_register_entities(struct vpfe_ipipeif_device *ipipeif, ipipeif->video_in.vpfe_dev = vpfe_dev; flags = 0; - ret = media_entity_create_link(&ipipeif->video_in.video_dev.entity, 0, + ret = media_create_pad_link(&ipipeif->video_in.video_dev.entity, 0, &ipipeif->subdev.entity, 0, flags); if (ret < 0) goto fail; diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c index b1f01adfa7c83..df77288b0ec02 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_isif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c @@ -1817,7 +1817,7 @@ int vpfe_isif_register_entities(struct vpfe_isif_device *isif, isif->video_out.vpfe_dev = vpfe_dev; flags = 0; /* connect isif to video node */ - ret = media_entity_create_link(&isif->subdev.entity, 1, + ret = media_create_pad_link(&isif->subdev.entity, 1, &isif->video_out.video_dev.entity, 0, flags); if (ret < 0) diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index 7275cf3d6c20e..50c8725c5aa60 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c @@ -1826,27 +1826,27 @@ int vpfe_resizer_register_entities(struct vpfe_resizer_device *resizer, resizer->resizer_b.video_out.vpfe_dev = vpfe_dev; /* create link between Resizer Crop----> Resizer A*/ - ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 1, + ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 1, &resizer->resizer_a.subdev.entity, 0, flags); if (ret < 0) goto out_create_link; /* create link between Resizer Crop----> Resizer B*/ - ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 2, + ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 2, &resizer->resizer_b.subdev.entity, 0, flags); if (ret < 0) goto out_create_link; /* create link between Resizer A ----> video out */ - ret = media_entity_create_link(&resizer->resizer_a.subdev.entity, 1, + ret = media_create_pad_link(&resizer->resizer_a.subdev.entity, 1, &resizer->resizer_a.video_out.video_dev.entity, 0, flags); if (ret < 0) goto out_create_link; /* create link between Resizer B ----> video out */ - ret = media_entity_create_link(&resizer->resizer_b.subdev.entity, 1, + ret = media_create_pad_link(&resizer->resizer_b.subdev.entity, 1, &resizer->resizer_b.video_out.video_dev.entity, 0, flags); if (ret < 0) goto out_create_link; diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c index 69b678ca40c06..ec46f366dd179 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c @@ -445,32 +445,32 @@ static int vpfe_register_entities(struct vpfe_device *vpfe_dev) /* if entity has no pads (ex: amplifier), cant establish link */ if (vpfe_dev->sd[i]->entity.num_pads) { - ret = media_entity_create_link(&vpfe_dev->sd[i]->entity, + ret = media_create_pad_link(&vpfe_dev->sd[i]->entity, 0, &vpfe_dev->vpfe_isif.subdev.entity, 0, flags); if (ret < 0) goto out_resizer_register; } - ret = media_entity_create_link(&vpfe_dev->vpfe_isif.subdev.entity, 1, + ret = media_create_pad_link(&vpfe_dev->vpfe_isif.subdev.entity, 1, &vpfe_dev->vpfe_ipipeif.subdev.entity, 0, flags); if (ret < 0) goto out_resizer_register; - ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1, + ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1, &vpfe_dev->vpfe_ipipe.subdev.entity, 0, flags); if (ret < 0) goto out_resizer_register; - ret = media_entity_create_link(&vpfe_dev->vpfe_ipipe.subdev.entity, + ret = media_create_pad_link(&vpfe_dev->vpfe_ipipe.subdev.entity, 1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity, 0, flags); if (ret < 0) goto out_resizer_register; - ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1, + ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity, 0, flags); if (ret < 0) diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index 5fc3675b190f4..60e67fadcac18 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -1259,7 +1259,7 @@ static int iss_register_entities(struct iss_device *iss) goto done; } - ret = media_entity_create_link(&sensor->entity, 0, input, pad, + ret = media_create_pad_link(&sensor->entity, 0, input, pad, flags); if (ret < 0) goto done; @@ -1317,31 +1317,31 @@ static int iss_initialize_modules(struct iss_device *iss) } /* Connect the submodules. */ - ret = media_entity_create_link( + ret = media_create_pad_link( &iss->csi2a.subdev.entity, CSI2_PAD_SOURCE, &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0); if (ret < 0) goto error_link; - ret = media_entity_create_link( + ret = media_create_pad_link( &iss->csi2b.subdev.entity, CSI2_PAD_SOURCE, &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0); if (ret < 0) goto error_link; - ret = media_entity_create_link( + ret = media_create_pad_link( &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP, &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0); if (ret < 0) goto error_link; - ret = media_entity_create_link( + ret = media_create_pad_link( &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP, &iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0); if (ret < 0) goto error_link; - ret = media_entity_create_link( + ret = media_create_pad_link( &iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP, &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0); if (ret < 0) diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c index 86111e39a7283..c6eb5a7a593f3 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.c +++ b/drivers/staging/media/omap4iss/iss_csi2.c @@ -1291,7 +1291,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname) goto error_video; /* Connect the CSI2 subdev to the video node. */ - ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE, + ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE, &csi2->video_out.video.entity, 0, 0); if (ret < 0) goto error_link; diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c index d031a5f22cdcb..b0c5f2431b626 100644 --- a/drivers/staging/media/omap4iss/iss_ipipeif.c +++ b/drivers/staging/media/omap4iss/iss_ipipeif.c @@ -762,7 +762,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif) return ret; /* Connect the IPIPEIF subdev to the video node. */ - ret = media_entity_create_link(&ipipeif->subdev.entity, + ret = media_create_pad_link(&ipipeif->subdev.entity, IPIPEIF_PAD_SOURCE_ISIF_SF, &ipipeif->video_out.video.entity, 0, 0); if (ret < 0) diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c index 11031d9de3ab4..a2cb57cb460da 100644 --- a/drivers/staging/media/omap4iss/iss_resizer.c +++ b/drivers/staging/media/omap4iss/iss_resizer.c @@ -804,7 +804,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer) return ret; /* Connect the RESIZER subdev to the video node. */ - ret = media_entity_create_link(&resizer->subdev.entity, + ret = media_create_pad_link(&resizer->subdev.entity, RESIZER_PAD_SOURCE_MEM, &resizer->video_out.video.entity, 0, 0); if (ret < 0) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 96a5d3e6f6f43..ad9e16e5e44dc 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -215,7 +215,7 @@ int media_entity_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads); void media_entity_cleanup(struct media_entity *entity); -int media_entity_create_link(struct media_entity *source, u16 source_pad, +int media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags); void __media_entity_remove_links(struct media_entity *entity); void media_entity_remove_links(struct media_entity *entity); -- GitLab From d10c98949d1a1fff14d750fe5162213bb5b39e11 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Wed, 19 Aug 2015 12:35:21 -0300 Subject: [PATCH 2453/2855] [media] media: use entity.graph_obj.mdev instead of .parent The struct media_entity has a .parent field that stores a pointer to the parent struct media_device. But recently a media_gobj was embedded into the entities and since struct media_gojb already has a pointer to a struct media_device in the .mdev field, the .parent field becomes redundant and can be removed. This patch replaces all the usage of .parent by .graph_obj.mdev so that field will become unused and can be removed on a later patch. No functional changes. The transformation was made using the following coccinelle spatch: @@ struct media_entity *me; @@ - me->parent + me->graph_obj.mdev @@ struct media_entity *link; @@ - link->source->entity->parent + link->source->entity->graph_obj.mdev @@ struct exynos_video_entity *ve; @@ - ve->vdev.entity.parent + ve->vdev.entity.graph_obj.mdev Suggested-by: Mauro Carvalho Chehab Signed-off-by: Javier Martinez Canillas Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 8 ++--- drivers/media/media-entity.c | 34 ++++++++++--------- .../platform/exynos4-is/fimc-isp-video.c | 6 ++-- drivers/media/platform/exynos4-is/fimc-lite.c | 8 ++--- drivers/media/platform/exynos4-is/media-dev.c | 2 +- drivers/media/platform/exynos4-is/media-dev.h | 8 ++--- drivers/media/platform/omap3isp/isp.c | 4 +-- drivers/media/platform/omap3isp/ispvideo.c | 2 +- drivers/media/platform/vsp1/vsp1_video.c | 2 +- drivers/media/platform/xilinx/xilinx-dma.c | 2 +- .../staging/media/davinci_vpfe/vpfe_video.c | 6 ++-- drivers/staging/media/omap4iss/iss.c | 4 +-- drivers/staging/media/omap4iss/iss_video.c | 2 +- 13 files changed, 45 insertions(+), 43 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 0f3844470147e..138b18416460d 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -435,8 +435,8 @@ int __must_check media_device_register_entity(struct media_device *mdev, int i; /* Warn if we apparently re-register an entity */ - WARN_ON(entity->parent != NULL); - entity->parent = mdev; + WARN_ON(entity->graph_obj.mdev != NULL); + entity->graph_obj.mdev = mdev; spin_lock(&mdev->lock); /* Initialize media_gobj embedded at the entity */ @@ -471,7 +471,7 @@ EXPORT_SYMBOL_GPL(media_device_register_entity); void media_device_unregister_entity(struct media_entity *entity) { int i; - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev; if (mdev == NULL) return; @@ -484,7 +484,7 @@ void media_device_unregister_entity(struct media_entity *entity) media_gobj_remove(&entity->graph_obj); list_del(&entity->list); spin_unlock(&mdev->lock); - entity->parent = NULL; + entity->graph_obj.mdev = NULL; } EXPORT_SYMBOL_GPL(media_device_unregister_entity); diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index e840da0325b71..6ed4a19b0be95 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -332,7 +332,7 @@ EXPORT_SYMBOL_GPL(media_entity_graph_walk_next); __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_pipeline *pipe) { - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev; struct media_entity_graph graph; struct media_entity *entity_err = entity; int ret; @@ -387,7 +387,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, ret = entity->ops->link_validate(link); if (ret < 0 && ret != -ENOIOCTLCMD) { - dev_dbg(entity->parent->dev, + dev_dbg(entity->graph_obj.mdev->dev, "link validation failed for \"%s\":%u -> \"%s\":%u, error %d\n", link->source->entity->name, link->source->index, @@ -401,7 +401,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, if (!bitmap_full(active, entity->num_pads)) { ret = -EPIPE; - dev_dbg(entity->parent->dev, + dev_dbg(entity->graph_obj.mdev->dev, "\"%s\":%u must be connected by an enabled link\n", entity->name, (unsigned)find_first_zero_bit( @@ -454,7 +454,7 @@ EXPORT_SYMBOL_GPL(media_entity_pipeline_start); */ void media_entity_pipeline_stop(struct media_entity *entity) { - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev; struct media_entity_graph graph; mutex_lock(&mdev->graph_mutex); @@ -490,8 +490,8 @@ struct media_entity *media_entity_get(struct media_entity *entity) if (entity == NULL) return NULL; - if (entity->parent->dev && - !try_module_get(entity->parent->dev->driver->owner)) + if (entity->graph_obj.mdev->dev && + !try_module_get(entity->graph_obj.mdev->dev->driver->owner)) return NULL; return entity; @@ -511,8 +511,8 @@ void media_entity_put(struct media_entity *entity) if (entity == NULL) return; - if (entity->parent->dev) - module_put(entity->parent->dev->driver->owner); + if (entity->graph_obj.mdev->dev) + module_put(entity->graph_obj.mdev->dev->driver->owner); } EXPORT_SYMBOL_GPL(media_entity_put); @@ -561,7 +561,8 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, link->flags = flags; /* Initialize graph object embedded at the new link */ - media_gobj_init(source->parent, MEDIA_GRAPH_LINK, &link->graph_obj); + media_gobj_init(source->graph_obj.mdev, MEDIA_GRAPH_LINK, + &link->graph_obj); /* Create the backlink. Backlinks are used to help graph traversal and * are not reported to userspace. @@ -577,7 +578,8 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, backlink->flags = flags; /* Initialize graph object embedded at the new link */ - media_gobj_init(sink->parent, MEDIA_GRAPH_LINK, &backlink->graph_obj); + media_gobj_init(sink->graph_obj.mdev, MEDIA_GRAPH_LINK, + &backlink->graph_obj); link->reverse = backlink; backlink->reverse = link; @@ -629,12 +631,12 @@ EXPORT_SYMBOL_GPL(__media_entity_remove_links); void media_entity_remove_links(struct media_entity *entity) { /* Do nothing if the entity is not registered. */ - if (entity->parent == NULL) + if (entity->graph_obj.mdev == NULL) return; - mutex_lock(&entity->parent->graph_mutex); + mutex_lock(&entity->graph_obj.mdev->graph_mutex); __media_entity_remove_links(entity); - mutex_unlock(&entity->parent->graph_mutex); + mutex_unlock(&entity->graph_obj.mdev->graph_mutex); } EXPORT_SYMBOL_GPL(media_entity_remove_links); @@ -703,7 +705,7 @@ int __media_entity_setup_link(struct media_link *link, u32 flags) (source->stream_count || sink->stream_count)) return -EBUSY; - mdev = source->parent; + mdev = source->graph_obj.mdev; if (mdev->link_notify) { ret = mdev->link_notify(link, flags, @@ -724,9 +726,9 @@ int media_entity_setup_link(struct media_link *link, u32 flags) { int ret; - mutex_lock(&link->source->entity->parent->graph_mutex); + mutex_lock(&link->source->entity->graph_obj.mdev->graph_mutex); ret = __media_entity_setup_link(link, flags); - mutex_unlock(&link->source->entity->parent->graph_mutex); + mutex_unlock(&link->source->entity->graph_obj.mdev->graph_mutex); return ret; } diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c index 817226d52b742..239df7d8bd306 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c @@ -287,7 +287,7 @@ static int isp_video_open(struct file *file) goto rel_fh; if (v4l2_fh_is_singular_file(file)) { - mutex_lock(&me->parent->graph_mutex); + mutex_lock(&me->graph_obj.mdev->graph_mutex); ret = fimc_pipeline_call(ve, open, me, true); @@ -295,7 +295,7 @@ static int isp_video_open(struct file *file) if (ret == 0) me->use_count++; - mutex_unlock(&me->parent->graph_mutex); + mutex_unlock(&me->graph_obj.mdev->graph_mutex); } if (!ret) goto unlock; @@ -311,7 +311,7 @@ static int isp_video_release(struct file *file) struct fimc_isp *isp = video_drvdata(file); struct fimc_is_video *ivc = &isp->video_capture; struct media_entity *entity = &ivc->ve.vdev.entity; - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev; mutex_lock(&isp->video_lock); diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index 2ce670425cd96..11d25712153dd 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -494,7 +494,7 @@ static int fimc_lite_open(struct file *file) atomic_read(&fimc->out_path) != FIMC_IO_DMA) goto unlock; - mutex_lock(&me->parent->graph_mutex); + mutex_lock(&me->graph_obj.mdev->graph_mutex); ret = fimc_pipeline_call(&fimc->ve, open, me, true); @@ -502,7 +502,7 @@ static int fimc_lite_open(struct file *file) if (ret == 0) me->use_count++; - mutex_unlock(&me->parent->graph_mutex); + mutex_unlock(&me->graph_obj.mdev->graph_mutex); if (!ret) { fimc_lite_clear_event_counters(fimc); @@ -535,9 +535,9 @@ static int fimc_lite_release(struct file *file) fimc_pipeline_call(&fimc->ve, close); clear_bit(ST_FLITE_IN_USE, &fimc->state); - mutex_lock(&entity->parent->graph_mutex); + mutex_lock(&entity->graph_obj.mdev->graph_mutex); entity->use_count--; - mutex_unlock(&entity->parent->graph_mutex); + mutex_unlock(&entity->graph_obj.mdev->graph_mutex); } _vb2_fop_release(file, NULL); diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 4c524a02c59c6..a67b98676dd92 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -1046,7 +1046,7 @@ static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable) return ret; } -/* Locking: called with entity->parent->graph_mutex mutex held. */ +/* Locking: called with entity->graph_obj.mdev->graph_mutex mutex held. */ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable) { struct media_entity *entity_err = entity; diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h index 93a96126929b5..e8845e1f5aabe 100644 --- a/drivers/media/platform/exynos4-is/media-dev.h +++ b/drivers/media/platform/exynos4-is/media-dev.h @@ -164,8 +164,8 @@ struct fimc_sensor_info *source_to_sensor_info(struct fimc_source_info *si) static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me) { - return me->parent == NULL ? NULL : - container_of(me->parent, struct fimc_md, media_dev); + return me->graph_obj.mdev == NULL ? NULL : + container_of(me->graph_obj.mdev, struct fimc_md, media_dev); } static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n) @@ -175,12 +175,12 @@ static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n) static inline void fimc_md_graph_lock(struct exynos_video_entity *ve) { - mutex_lock(&ve->vdev.entity.parent->graph_mutex); + mutex_lock(&ve->vdev.entity.graph_obj.mdev->graph_mutex); } static inline void fimc_md_graph_unlock(struct exynos_video_entity *ve) { - mutex_unlock(&ve->vdev.entity.parent->graph_mutex); + mutex_unlock(&ve->vdev.entity.graph_obj.mdev->graph_mutex); } int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on); diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 6351f35b0a656..aa13b17d19a0d 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -787,7 +787,7 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use) int change = use ? 1 : -1; int ret; - mutex_lock(&entity->parent->graph_mutex); + mutex_lock(&entity->graph_obj.mdev->graph_mutex); /* Apply use count to node. */ entity->use_count += change; @@ -798,7 +798,7 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use) if (ret < 0) entity->use_count -= change; - mutex_unlock(&entity->parent->graph_mutex); + mutex_unlock(&entity->graph_obj.mdev->graph_mutex); return ret; } diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index 0e129075e99ff..a2e53b34d95fb 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -226,7 +226,7 @@ static int isp_video_get_graph_data(struct isp_video *video, { struct media_entity_graph graph; struct media_entity *entity = &video->video.entity; - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev; struct isp_video *far_end = NULL; mutex_lock(&mdev->graph_mutex); diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 516595cff4083..c2b2281bb5306 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -380,7 +380,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe, { struct media_entity_graph graph; struct media_entity *entity = &video->video.entity; - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev; unsigned int i; int ret; diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index ce2d34df12ed8..4b84a0e54a0cd 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -181,7 +181,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe, { struct media_entity_graph graph; struct media_entity *entity = &start->video.entity; - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev; unsigned int num_inputs = 0; unsigned int num_outputs = 0; diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index daae720eb82ca..6e0d0375634d1 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -130,7 +130,7 @@ __vpfe_video_get_format(struct vpfe_video_device *video, static void vpfe_prepare_pipeline(struct vpfe_video_device *video) { struct media_entity *entity = &video->video_dev.entity; - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev; struct vpfe_pipeline *pipe = &video->pipe; struct vpfe_video_device *far_end = NULL; struct media_entity_graph graph; @@ -288,7 +288,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe) else entity = &pipe->inputs[0]->video_dev.entity; - mdev = entity->parent; + mdev = entity->graph_obj.mdev; mutex_lock(&mdev->graph_mutex); media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { @@ -328,7 +328,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe) else entity = &pipe->inputs[0]->video_dev.entity; - mdev = entity->parent; + mdev = entity->graph_obj.mdev; mutex_lock(&mdev->graph_mutex); media_entity_graph_walk_start(&graph, entity); diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index 60e67fadcac18..b405dc93d90ac 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -494,7 +494,7 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use) int change = use ? 1 : -1; int ret; - mutex_lock(&entity->parent->graph_mutex); + mutex_lock(&entity->graph_obj.mdev->graph_mutex); /* Apply use count to node. */ entity->use_count += change; @@ -505,7 +505,7 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use) if (ret < 0) entity->use_count -= change; - mutex_unlock(&entity->parent->graph_mutex); + mutex_unlock(&entity->graph_obj.mdev->graph_mutex); return ret; } diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index dd8ff03912a71..ea384630aab0e 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -206,7 +206,7 @@ iss_video_far_end(struct iss_video *video) { struct media_entity_graph graph; struct media_entity *entity = &video->video.entity; - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev; struct iss_video *far_end = NULL; mutex_lock(&mdev->graph_mutex); -- GitLab From b42ff142b8d880427e8c30b05de71b841a67aaad Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Wed, 19 Aug 2015 12:35:22 -0300 Subject: [PATCH 2454/2855] [media] media: remove media entity .parent field Now that the struct media_entity .parent field is unused, it can be safely removed. Since all the previous users were converted to use the .mdev field from the embedded struct media_gobj instead. Signed-off-by: Javier Martinez Canillas Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index ad9e16e5e44dc..a493dd9910f41 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -103,7 +103,6 @@ struct media_entity_operations { struct media_entity { struct media_gobj graph_obj; struct list_head list; - struct media_device *parent; /* Media device this entity belongs to*/ const char *name; /* Entity name */ u32 type; /* Entity type (MEDIA_ENT_T_*) */ u32 revision; /* Entity revision, driver specific */ -- GitLab From a1d2510ebd7a14f0d1a89c138101beaeac076dd2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Aug 2015 07:43:07 -0300 Subject: [PATCH 2455/2855] [media] uapi/media.h: Declare interface types for V4L2 and DVB Declare the interface types that will be used by the new G_TOPOLOGY ioctl that will be defined later on. For now, we need those types, as they'll be used on the internal structs associated with the new media_interface graph object defined on the next patch. Acked-by: Hans Verkuil Reviewed-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 4e816be3de39b..3ad3d6be293fb 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -167,6 +167,27 @@ struct media_links_enum { __u32 reserved[4]; }; +/* Interface type ranges */ + +#define MEDIA_INTF_T_DVB_BASE 0x00000100 +#define MEDIA_INTF_T_V4L_BASE 0x00000200 + +/* Interface types */ + +#define MEDIA_INTF_T_DVB_FE (MEDIA_INTF_T_DVB_BASE) +#define MEDIA_INTF_T_DVB_DEMUX (MEDIA_INTF_T_DVB_BASE + 1) +#define MEDIA_INTF_T_DVB_DVR (MEDIA_INTF_T_DVB_BASE + 2) +#define MEDIA_INTF_T_DVB_CA (MEDIA_INTF_T_DVB_BASE + 3) +#define MEDIA_INTF_T_DVB_NET (MEDIA_INTF_T_DVB_BASE + 4) + +#define MEDIA_INTF_T_V4L_VIDEO (MEDIA_INTF_T_V4L_BASE) +#define MEDIA_INTF_T_V4L_VBI (MEDIA_INTF_T_V4L_BASE + 1) +#define MEDIA_INTF_T_V4L_RADIO (MEDIA_INTF_T_V4L_BASE + 2) +#define MEDIA_INTF_T_V4L_SUBDEV (MEDIA_INTF_T_V4L_BASE + 3) +#define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4) + +/* TBD: declare the structs needed for the new G_TOPOLOGY ioctl */ + #define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info) #define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc) #define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum) -- GitLab From 27e543fa87deea308f0cc5224ab19e397b0a5ded Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Aug 2015 09:07:34 -0300 Subject: [PATCH 2456/2855] [media] media: add functions to allow creating interfaces Interfaces are different than entities: they represent a Kernel<->userspace interaction, while entities represent a piece of hardware/firmware/software that executes a function. Let's distinguish them by creating a separate structure to store the interfaces. Later patches should change the existing drivers and logic to split the current interface embedded inside the entity structure (device nodes) into a separate object of the graph. Acked-by: Hans Verkuil Reviewed-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 83 ++++++++++++++++++++++++++++++++++++ include/media/media-device.h | 2 + include/media/media-entity.h | 48 +++++++++++++++++++++ 3 files changed, 133 insertions(+) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 6ed4a19b0be95..160ce2cc0865f 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -44,11 +44,41 @@ static inline const char *gobj_type(enum media_gobj_type type) return "pad"; case MEDIA_GRAPH_LINK: return "link"; + case MEDIA_GRAPH_INTF_DEVNODE: + return "intf-devnode"; default: return "unknown"; } } +static inline const char *intf_type(struct media_interface *intf) +{ + switch (intf->type) { + case MEDIA_INTF_T_DVB_FE: + return "frontend"; + case MEDIA_INTF_T_DVB_DEMUX: + return "demux"; + case MEDIA_INTF_T_DVB_DVR: + return "DVR"; + case MEDIA_INTF_T_DVB_CA: + return "CA"; + case MEDIA_INTF_T_DVB_NET: + return "dvbnet"; + case MEDIA_INTF_T_V4L_VIDEO: + return "video"; + case MEDIA_INTF_T_V4L_VBI: + return "vbi"; + case MEDIA_INTF_T_V4L_RADIO: + return "radio"; + case MEDIA_INTF_T_V4L_SUBDEV: + return "v4l2-subdev"; + case MEDIA_INTF_T_V4L_SWRADIO: + return "swradio"; + default: + return "unknown-intf"; + } +}; + static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) { #if defined(DEBUG) || defined (CONFIG_DYNAMIC_DEBUG) @@ -84,6 +114,19 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) "%s: id 0x%08x pad#%d: '%s':%d\n", event_name, gobj->id, media_localid(gobj), pad->entity->name, pad->index); + break; + } + case MEDIA_GRAPH_INTF_DEVNODE: + { + struct media_interface *intf = gobj_to_intf(gobj); + struct media_intf_devnode *devnode = intf_to_devnode(intf); + + dev_dbg(gobj->mdev->dev, + "%s: id 0x%08x intf_devnode#%d: %s - major: %d, minor: %d\n", + event_name, gobj->id, media_localid(gobj), + intf_type(intf), + devnode->major, devnode->minor); + break; } } #endif @@ -119,6 +162,9 @@ void media_gobj_init(struct media_device *mdev, case MEDIA_GRAPH_LINK: gobj->id = media_gobj_gen_id(type, ++mdev->link_id); break; + case MEDIA_GRAPH_INTF_DEVNODE: + gobj->id = media_gobj_gen_id(type, ++mdev->intf_devnode_id); + break; } dev_dbg_obj(__func__, gobj); } @@ -793,3 +839,40 @@ struct media_pad *media_entity_remote_pad(struct media_pad *pad) } EXPORT_SYMBOL_GPL(media_entity_remote_pad); + + +/* Functions related to the media interface via device nodes */ + +struct media_intf_devnode *media_devnode_create(struct media_device *mdev, + u32 type, u32 flags, + u32 major, u32 minor, + gfp_t gfp_flags) +{ + struct media_intf_devnode *devnode; + struct media_interface *intf; + + devnode = kzalloc(sizeof(*devnode), gfp_flags); + if (!devnode) + return NULL; + + intf = &devnode->intf; + + intf->type = type; + intf->flags = flags; + + devnode->major = major; + devnode->minor = minor; + + media_gobj_init(mdev, MEDIA_GRAPH_INTF_DEVNODE, + &devnode->intf.graph_obj); + + return devnode; +} +EXPORT_SYMBOL_GPL(media_devnode_create); + +void media_devnode_remove(struct media_intf_devnode *devnode) +{ + media_gobj_remove(&devnode->intf.graph_obj); + kfree(devnode); +} +EXPORT_SYMBOL_GPL(media_devnode_remove); diff --git a/include/media/media-device.h b/include/media/media-device.h index 05414e351f8e3..3b14394d57010 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -44,6 +44,7 @@ struct device; * @entity_id: Unique ID used on the last entity registered * @pad_id: Unique ID used on the last pad registered * @link_id: Unique ID used on the last link registered + * @intf_devnode_id: Unique ID used on the last interface devnode registered * @entities: List of registered entities * @lock: Entities list lock * @graph_mutex: Entities graph operation lock @@ -73,6 +74,7 @@ struct media_device { u32 entity_id; u32 pad_id; u32 link_id; + u32 intf_devnode_id; struct list_head entities; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index a493dd9910f41..4d5fc91c4134b 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -36,11 +36,14 @@ * @MEDIA_GRAPH_ENTITY: Identify a media entity * @MEDIA_GRAPH_PAD: Identify a media pad * @MEDIA_GRAPH_LINK: Identify a media link + * @MEDIA_GRAPH_INTF_DEVNODE: Identify a media Kernel API interface via + * a device node */ enum media_gobj_type { MEDIA_GRAPH_ENTITY, MEDIA_GRAPH_PAD, MEDIA_GRAPH_LINK, + MEDIA_GRAPH_INTF_DEVNODE, }; #define MEDIA_BITS_PER_TYPE 8 @@ -141,6 +144,34 @@ struct media_entity { } info; }; +/** + * struct media_intf_devnode - Define a Kernel API interface + * + * @graph_obj: embedded graph object + * @type: Type of the interface as defined at the + * uapi/media/media.h header, e. g. + * MEDIA_INTF_T_* + * @flags: Interface flags as defined at uapi/media/media.h + */ +struct media_interface { + struct media_gobj graph_obj; + u32 type; + u32 flags; +}; + +/** + * struct media_intf_devnode - Define a Kernel API interface via a device node + * + * @intf: embedded interface object + * @major: Major number of a device node + * @minor: Minor number of a device node + */ +struct media_intf_devnode { + struct media_interface intf; + u32 major; + u32 minor; +}; + static inline u32 media_entity_type(struct media_entity *entity) { return entity->type & MEDIA_ENT_TYPE_MASK; @@ -205,6 +236,18 @@ struct media_entity_graph { #define gobj_to_link(gobj) \ container_of(gobj, struct media_link, graph_obj) +#define gobj_to_link(gobj) \ + container_of(gobj, struct media_link, graph_obj) + +#define gobj_to_pad(gobj) \ + container_of(gobj, struct media_pad, graph_obj) + +#define gobj_to_intf(gobj) \ + container_of(gobj, struct media_interface, graph_obj) + +#define intf_to_devnode(intf) \ + container_of(intf, struct media_intf_devnode, intf) + void media_gobj_init(struct media_device *mdev, enum media_gobj_type type, struct media_gobj *gobj); @@ -236,6 +279,11 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_pipeline *pipe); void media_entity_pipeline_stop(struct media_entity *entity); +struct media_intf_devnode *media_devnode_create(struct media_device *mdev, + u32 type, u32 flags, + u32 major, u32 minor, + gfp_t gfp_flags); +void media_devnode_remove(struct media_intf_devnode *devnode); #define media_entity_call(entity, operation, args...) \ (((entity)->ops && (entity)->ops->operation) ? \ (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD) -- GitLab From f2f6da0d77027d05bf8a06eb8b80fe139f9cc853 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Wed, 26 Aug 2015 09:24:45 -0300 Subject: [PATCH 2457/2855] [media] omap3isp: separate links creation from entities init The omap3isp driver initializes the entities and creates the pads links before the entities are registered with the media device. This does not work now that object IDs are used to create links so the media_device has to be set. Split out the pads links creation from the entity initialization so the links are created after the entities have been registered with the media device. Suggested-by: Mauro Carvalho Chehab Signed-off-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 152 ++++++++++++------- drivers/media/platform/omap3isp/ispccdc.c | 22 ++- drivers/media/platform/omap3isp/ispccdc.h | 1 + drivers/media/platform/omap3isp/ispccp2.c | 22 ++- drivers/media/platform/omap3isp/ispccp2.h | 1 + drivers/media/platform/omap3isp/ispcsi2.c | 22 ++- drivers/media/platform/omap3isp/ispcsi2.h | 1 + drivers/media/platform/omap3isp/isppreview.c | 33 ++-- drivers/media/platform/omap3isp/isppreview.h | 1 + drivers/media/platform/omap3isp/ispresizer.c | 33 ++-- drivers/media/platform/omap3isp/ispresizer.h | 1 + 11 files changed, 185 insertions(+), 104 deletions(-) diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index aa13b17d19a0d..b8f6f81d2db23 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -1933,6 +1933,100 @@ done: return ret; } +/* + * isp_create_pads_links - Pads links creation for the subdevices + * @isp : Pointer to ISP device + * return negative error code or zero on success + */ +static int isp_create_pads_links(struct isp_device *isp) +{ + int ret; + + ret = omap3isp_csi2_create_pads_links(isp); + if (ret < 0) { + dev_err(isp->dev, "CSI2 pads links creation failed\n"); + return ret; + } + + ret = omap3isp_ccp2_create_pads_links(isp); + if (ret < 0) { + dev_err(isp->dev, "CCP2 pads links creation failed\n"); + return ret; + } + + ret = omap3isp_ccdc_create_pads_links(isp); + if (ret < 0) { + dev_err(isp->dev, "CCDC pads links creation failed\n"); + return ret; + } + + ret = omap3isp_preview_create_pads_links(isp); + if (ret < 0) { + dev_err(isp->dev, "Preview pads links creation failed\n"); + return ret; + } + + ret = omap3isp_resizer_create_pads_links(isp); + if (ret < 0) { + dev_err(isp->dev, "Resizer pads links creation failed\n"); + return ret; + } + + /* Connect the submodules. */ + ret = media_create_pad_link( + &isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE, + &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0); + if (ret < 0) + return ret; + + ret = media_create_pad_link( + &isp->isp_ccp2.subdev.entity, CCP2_PAD_SOURCE, + &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0); + if (ret < 0) + return ret; + + ret = media_create_pad_link( + &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP, + &isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0); + if (ret < 0) + return ret; + + ret = media_create_pad_link( + &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF, + &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0); + if (ret < 0) + return ret; + + ret = media_create_pad_link( + &isp->isp_prev.subdev.entity, PREV_PAD_SOURCE, + &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0); + if (ret < 0) + return ret; + + ret = media_create_pad_link( + &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP, + &isp->isp_aewb.subdev.entity, 0, + MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); + if (ret < 0) + return ret; + + ret = media_create_pad_link( + &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP, + &isp->isp_af.subdev.entity, 0, + MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); + if (ret < 0) + return ret; + + ret = media_create_pad_link( + &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP, + &isp->isp_hist.subdev.entity, 0, + MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); + if (ret < 0) + return ret; + + return 0; +} + static void isp_cleanup_modules(struct isp_device *isp) { omap3isp_h3a_aewb_cleanup(isp); @@ -2003,62 +2097,8 @@ static int isp_initialize_modules(struct isp_device *isp) goto error_h3a_af; } - /* Connect the submodules. */ - ret = media_create_pad_link( - &isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE, - &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0); - if (ret < 0) - goto error_link; - - ret = media_create_pad_link( - &isp->isp_ccp2.subdev.entity, CCP2_PAD_SOURCE, - &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0); - if (ret < 0) - goto error_link; - - ret = media_create_pad_link( - &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP, - &isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0); - if (ret < 0) - goto error_link; - - ret = media_create_pad_link( - &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF, - &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0); - if (ret < 0) - goto error_link; - - ret = media_create_pad_link( - &isp->isp_prev.subdev.entity, PREV_PAD_SOURCE, - &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0); - if (ret < 0) - goto error_link; - - ret = media_create_pad_link( - &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP, - &isp->isp_aewb.subdev.entity, 0, - MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); - if (ret < 0) - goto error_link; - - ret = media_create_pad_link( - &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP, - &isp->isp_af.subdev.entity, 0, - MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); - if (ret < 0) - goto error_link; - - ret = media_create_pad_link( - &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP, - &isp->isp_hist.subdev.entity, 0, - MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); - if (ret < 0) - goto error_link; - return 0; -error_link: - omap3isp_h3a_af_cleanup(isp); error_h3a_af: omap3isp_h3a_aewb_cleanup(isp); error_h3a_aewb: @@ -2468,6 +2508,10 @@ static int isp_probe(struct platform_device *pdev) if (ret < 0) goto error_modules; + ret = isp_create_pads_links(isp); + if (ret < 0) + goto error_register_entities; + isp->notifier.bound = isp_subdev_notifier_bound; isp->notifier.complete = isp_subdev_notifier_complete; diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 27555e4f4aa82..9a811f5741fa2 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -2666,16 +2666,8 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc) if (ret < 0) goto error_video; - /* Connect the CCDC subdev to the video node. */ - ret = media_create_pad_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF, - &ccdc->video_out.video.entity, 0, 0); - if (ret < 0) - goto error_link; - return 0; -error_link: - omap3isp_video_cleanup(&ccdc->video_out); error_video: media_entity_cleanup(me); return ret; @@ -2720,6 +2712,20 @@ int omap3isp_ccdc_init(struct isp_device *isp) return 0; } +/* + * omap3isp_ccdc_create_pads_links - CCDC pads links creation + * @isp : Pointer to ISP device + * return negative error code or zero on success + */ +int omap3isp_ccdc_create_pads_links(struct isp_device *isp) +{ + struct isp_ccdc_device *ccdc = &isp->isp_ccdc; + + /* Connect the CCDC subdev to the video node. */ + return media_create_pad_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF, + &ccdc->video_out.video.entity, 0, 0); +} + /* * omap3isp_ccdc_cleanup - CCDC module cleanup. * @isp: Device pointer specific to the OMAP3 ISP. diff --git a/drivers/media/platform/omap3isp/ispccdc.h b/drivers/media/platform/omap3isp/ispccdc.h index 3440a70979400..2128203ef6fb3 100644 --- a/drivers/media/platform/omap3isp/ispccdc.h +++ b/drivers/media/platform/omap3isp/ispccdc.h @@ -163,6 +163,7 @@ struct isp_ccdc_device { struct isp_device; int omap3isp_ccdc_init(struct isp_device *isp); +int omap3isp_ccdc_create_pads_links(struct isp_device *isp); void omap3isp_ccdc_cleanup(struct isp_device *isp); int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc, struct v4l2_device *vdev); diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index b215eb5049d65..6ec7d104ab75f 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -1099,16 +1099,8 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2) if (ret < 0) goto error_video; - /* Connect the video node to the ccp2 subdev. */ - ret = media_create_pad_link(&ccp2->video_in.video.entity, 0, - &ccp2->subdev.entity, CCP2_PAD_SINK, 0); - if (ret < 0) - goto error_link; - return 0; -error_link: - omap3isp_video_cleanup(&ccp2->video_in); error_video: media_entity_cleanup(&ccp2->subdev.entity); return ret; @@ -1156,6 +1148,20 @@ int omap3isp_ccp2_init(struct isp_device *isp) return 0; } +/* + * omap3isp_ccp2_create_pads_links - CCP2 pads links creation + * @isp : Pointer to ISP device + * return negative error code or zero on success + */ +int omap3isp_ccp2_create_pads_links(struct isp_device *isp) +{ + struct isp_ccp2_device *ccp2 = &isp->isp_ccp2; + + /* Connect the video node to the ccp2 subdev. */ + return media_create_pad_link(&ccp2->video_in.video.entity, 0, + &ccp2->subdev.entity, CCP2_PAD_SINK, 0); +} + /* * omap3isp_ccp2_cleanup - CCP2 un-initialization * @isp : Pointer to ISP device diff --git a/drivers/media/platform/omap3isp/ispccp2.h b/drivers/media/platform/omap3isp/ispccp2.h index 4662bffa79e31..fb74bc67878b1 100644 --- a/drivers/media/platform/omap3isp/ispccp2.h +++ b/drivers/media/platform/omap3isp/ispccp2.h @@ -79,6 +79,7 @@ struct isp_ccp2_device { /* Function declarations */ int omap3isp_ccp2_init(struct isp_device *isp); +int omap3isp_ccp2_create_pads_links(struct isp_device *isp); void omap3isp_ccp2_cleanup(struct isp_device *isp); int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2, struct v4l2_device *vdev); diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index fcefc1e74881f..0fb057a74f69e 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c @@ -1264,16 +1264,8 @@ static int csi2_init_entities(struct isp_csi2_device *csi2) if (ret < 0) goto error_video; - /* Connect the CSI2 subdev to the video node. */ - ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE, - &csi2->video_out.video.entity, 0, 0); - if (ret < 0) - goto error_link; - return 0; -error_link: - omap3isp_video_cleanup(&csi2->video_out); error_video: media_entity_cleanup(&csi2->subdev.entity); return ret; @@ -1313,6 +1305,20 @@ int omap3isp_csi2_init(struct isp_device *isp) return 0; } +/* + * omap3isp_csi2_create_pads_links - CSI2 pads links creation + * @isp : Pointer to ISP device + * return negative error code or zero on success + */ +int omap3isp_csi2_create_pads_links(struct isp_device *isp) +{ + struct isp_csi2_device *csi2a = &isp->isp_csi2a; + + /* Connect the CSI2 subdev to the video node. */ + return media_create_pad_link(&csi2a->subdev.entity, CSI2_PAD_SOURCE, + &csi2a->video_out.video.entity, 0, 0); +} + /* * omap3isp_csi2_cleanup - Routine for module driver cleanup */ diff --git a/drivers/media/platform/omap3isp/ispcsi2.h b/drivers/media/platform/omap3isp/ispcsi2.h index 453ed62fe3946..452ee239c7d77 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.h +++ b/drivers/media/platform/omap3isp/ispcsi2.h @@ -148,6 +148,7 @@ struct isp_csi2_device { void omap3isp_csi2_isr(struct isp_csi2_device *csi2); int omap3isp_csi2_reset(struct isp_csi2_device *csi2); int omap3isp_csi2_init(struct isp_device *isp); +int omap3isp_csi2_create_pads_links(struct isp_device *isp); void omap3isp_csi2_cleanup(struct isp_device *isp); void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2); int omap3isp_csi2_register_entities(struct isp_csi2_device *csi2, diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index ad38d20c77702..6986d2f65c19c 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c @@ -2311,21 +2311,8 @@ static int preview_init_entities(struct isp_prev_device *prev) if (ret < 0) goto error_video_out; - /* Connect the video nodes to the previewer subdev. */ - ret = media_create_pad_link(&prev->video_in.video.entity, 0, - &prev->subdev.entity, PREV_PAD_SINK, 0); - if (ret < 0) - goto error_link; - - ret = media_create_pad_link(&prev->subdev.entity, PREV_PAD_SOURCE, - &prev->video_out.video.entity, 0, 0); - if (ret < 0) - goto error_link; - return 0; -error_link: - omap3isp_video_cleanup(&prev->video_out); error_video_out: omap3isp_video_cleanup(&prev->video_in); error_video_in: @@ -2349,6 +2336,26 @@ int omap3isp_preview_init(struct isp_device *isp) return preview_init_entities(prev); } +/* + * omap3isp_preview_create_pads_links - Previewer pads links creation + * @isp : Pointer to ISP device + * return negative error code or zero on success + */ +int omap3isp_preview_create_pads_links(struct isp_device *isp) +{ + struct isp_prev_device *prev = &isp->isp_prev; + int ret; + + /* Connect the video nodes to the previewer subdev. */ + ret = media_create_pad_link(&prev->video_in.video.entity, 0, + &prev->subdev.entity, PREV_PAD_SINK, 0); + if (ret < 0) + return ret; + + return media_create_pad_link(&prev->subdev.entity, PREV_PAD_SOURCE, + &prev->video_out.video.entity, 0, 0); +} + void omap3isp_preview_cleanup(struct isp_device *isp) { struct isp_prev_device *prev = &isp->isp_prev; diff --git a/drivers/media/platform/omap3isp/isppreview.h b/drivers/media/platform/omap3isp/isppreview.h index 16fdc03a3d43b..f3593b7cecc71 100644 --- a/drivers/media/platform/omap3isp/isppreview.h +++ b/drivers/media/platform/omap3isp/isppreview.h @@ -148,6 +148,7 @@ struct isp_prev_device { struct isp_device; int omap3isp_preview_init(struct isp_device *isp); +int omap3isp_preview_create_pads_links(struct isp_device *isp); void omap3isp_preview_cleanup(struct isp_device *isp); int omap3isp_preview_register_entities(struct isp_prev_device *prv, diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c index b48ad4d4b8349..249af7f524f90 100644 --- a/drivers/media/platform/omap3isp/ispresizer.c +++ b/drivers/media/platform/omap3isp/ispresizer.c @@ -1755,21 +1755,8 @@ static int resizer_init_entities(struct isp_res_device *res) res->video_out.video.entity.flags |= MEDIA_ENT_FL_DEFAULT; - /* Connect the video nodes to the resizer subdev. */ - ret = media_create_pad_link(&res->video_in.video.entity, 0, - &res->subdev.entity, RESZ_PAD_SINK, 0); - if (ret < 0) - goto error_link; - - ret = media_create_pad_link(&res->subdev.entity, RESZ_PAD_SOURCE, - &res->video_out.video.entity, 0, 0); - if (ret < 0) - goto error_link; - return 0; -error_link: - omap3isp_video_cleanup(&res->video_out); error_video_out: omap3isp_video_cleanup(&res->video_in); error_video_in: @@ -1793,6 +1780,26 @@ int omap3isp_resizer_init(struct isp_device *isp) return resizer_init_entities(res); } +/* + * omap3isp_resizer_create_pads_links - Resizer pads links creation + * @isp : Pointer to ISP device + * return negative error code or zero on success + */ +int omap3isp_resizer_create_pads_links(struct isp_device *isp) +{ + struct isp_res_device *res = &isp->isp_res; + int ret; + + /* Connect the video nodes to the resizer subdev. */ + ret = media_create_pad_link(&res->video_in.video.entity, 0, + &res->subdev.entity, RESZ_PAD_SINK, 0); + if (ret < 0) + return ret; + + return media_create_pad_link(&res->subdev.entity, RESZ_PAD_SOURCE, + &res->video_out.video.entity, 0, 0); +} + void omap3isp_resizer_cleanup(struct isp_device *isp) { struct isp_res_device *res = &isp->isp_res; diff --git a/drivers/media/platform/omap3isp/ispresizer.h b/drivers/media/platform/omap3isp/ispresizer.h index 5414542912e27..8b9fdcdab73d8 100644 --- a/drivers/media/platform/omap3isp/ispresizer.h +++ b/drivers/media/platform/omap3isp/ispresizer.h @@ -119,6 +119,7 @@ struct isp_res_device { struct isp_device; int omap3isp_resizer_init(struct isp_device *isp); +int omap3isp_resizer_create_pads_links(struct isp_device *isp); void omap3isp_resizer_cleanup(struct isp_device *isp); int omap3isp_resizer_register_entities(struct isp_res_device *res, -- GitLab From 68a57fa93a9f7776ab502db389469dd1ac6a1c66 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 28 Aug 2015 06:28:33 -0300 Subject: [PATCH 2458/2855] [media] omap3isp: create links after all subdevs have been bound The omap3isp driver parses the graph endpoints to know how many subdevices needs to be registered async and register notifiers callbacks for to know when these are bound and when the async registrations are completed. Currently the entities pad are linked with the correct ISP input interface when the subdevs are bound but it happens before entitities are registered with the media device so that won't work now that the entity links list is initialized on device registration. So instead creating the pad links when the subdevice is bound, create them on the complete callback once all the subdevices have been bound but only try to create for the ones that have a bus configuration set during bound. Signed-off-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index b8f6f81d2db23..69e7733d36cd0 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2321,26 +2321,33 @@ static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async, struct v4l2_subdev *subdev, struct v4l2_async_subdev *asd) { - struct isp_device *isp = container_of(async, struct isp_device, - notifier); struct isp_async_subdev *isd = container_of(asd, struct isp_async_subdev, asd); - int ret; - - ret = isp_link_entity(isp, &subdev->entity, isd->bus.interface); - if (ret < 0) - return ret; isd->sd = subdev; isd->sd->host_priv = &isd->bus; - return ret; + return 0; } static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async) { struct isp_device *isp = container_of(async, struct isp_device, notifier); + struct v4l2_device *v4l2_dev = &isp->v4l2_dev; + struct v4l2_subdev *sd; + struct isp_bus_cfg *bus; + int ret; + + list_for_each_entry(sd, &v4l2_dev->subdevs, list) { + /* Only try to link entities whose interface was set on bound */ + if (sd->host_priv) { + bus = (struct isp_bus_cfg *)sd->host_priv; + ret = isp_link_entity(isp, &sd->entity, bus->interface); + if (ret < 0) + return ret; + } + } return v4l2_device_register_subdev_nodes(&isp->v4l2_dev); } -- GitLab From 5837ceea11ca11339e49947aacbccb62f3646993 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Wed, 2 Sep 2015 11:28:08 -0300 Subject: [PATCH 2459/2855] [media] staging: omap4iss: separate links creation from entities init The omap4iss driver initializes the entities and creates the pads links before the entities are registered with the media device. This does not work now that object IDs are used to create links so the media_device has to be set. Split out the pads links creation from the entity initialization so are made after the entities registration. Signed-off-by: Javier Martinez Canillas Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/omap4iss/iss.c | 101 +++++++++++++------ drivers/staging/media/omap4iss/iss_csi2.c | 35 +++++-- drivers/staging/media/omap4iss/iss_csi2.h | 1 + drivers/staging/media/omap4iss/iss_ipipeif.c | 29 +++--- drivers/staging/media/omap4iss/iss_ipipeif.h | 1 + drivers/staging/media/omap4iss/iss_resizer.c | 29 +++--- drivers/staging/media/omap4iss/iss_resizer.h | 1 + 7 files changed, 132 insertions(+), 65 deletions(-) diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index b405dc93d90ac..fa761669fd863 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -1274,6 +1274,68 @@ done: return ret; } +/* + * iss_create_pads_links() - Pads links creation for the subdevices + * @iss : Pointer to ISS device + * + * return negative error code or zero on success + */ +static int iss_create_pads_links(struct iss_device *iss) +{ + int ret; + + ret = omap4iss_csi2_create_pads_links(iss); + if (ret < 0) { + dev_err(iss->dev, "CSI2 pads links creation failed\n"); + return ret; + } + + ret = omap4iss_ipipeif_create_pads_links(iss); + if (ret < 0) { + dev_err(iss->dev, "ISP IPIPEIF pads links creation failed\n"); + return ret; + } + + ret = omap4iss_resizer_create_pads_links(iss); + if (ret < 0) { + dev_err(iss->dev, "ISP RESIZER pads links creation failed\n"); + return ret; + } + + /* Connect the submodules. */ + ret = media_create_pad_link( + &iss->csi2a.subdev.entity, CSI2_PAD_SOURCE, + &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0); + if (ret < 0) + return ret; + + ret = media_create_pad_link( + &iss->csi2b.subdev.entity, CSI2_PAD_SOURCE, + &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0); + if (ret < 0) + return ret; + + ret = media_create_pad_link( + &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP, + &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0); + if (ret < 0) + return ret; + + ret = media_create_pad_link( + &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP, + &iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0); + if (ret < 0) + return ret; + + ret = media_create_pad_link( + &iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP, + &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0); + if (ret < 0) + return ret; + + return 0; +}; + static void iss_cleanup_modules(struct iss_device *iss) { omap4iss_csi2_cleanup(iss); @@ -1316,41 +1378,8 @@ static int iss_initialize_modules(struct iss_device *iss) goto error_resizer; } - /* Connect the submodules. */ - ret = media_create_pad_link( - &iss->csi2a.subdev.entity, CSI2_PAD_SOURCE, - &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0); - if (ret < 0) - goto error_link; - - ret = media_create_pad_link( - &iss->csi2b.subdev.entity, CSI2_PAD_SOURCE, - &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0); - if (ret < 0) - goto error_link; - - ret = media_create_pad_link( - &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP, - &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0); - if (ret < 0) - goto error_link; - - ret = media_create_pad_link( - &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP, - &iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0); - if (ret < 0) - goto error_link; - - ret = media_create_pad_link( - &iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP, - &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0); - if (ret < 0) - goto error_link; - return 0; -error_link: - omap4iss_resizer_cleanup(iss); error_resizer: omap4iss_ipipe_cleanup(iss); error_ipipe: @@ -1464,10 +1493,16 @@ static int iss_probe(struct platform_device *pdev) if (ret < 0) goto error_modules; + ret = iss_create_pads_links(iss); + if (ret < 0) + goto error_entities; + omap4iss_put(iss); return 0; +error_entities: + iss_unregister_entities(iss); error_modules: iss_cleanup_modules(iss); error_iss: diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c index c6eb5a7a593f3..13878a2752779 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.c +++ b/drivers/staging/media/omap4iss/iss_csi2.c @@ -1290,16 +1290,8 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname) if (ret < 0) goto error_video; - /* Connect the CSI2 subdev to the video node. */ - ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE, - &csi2->video_out.video.entity, 0, 0); - if (ret < 0) - goto error_link; - return 0; -error_link: - omap4iss_video_cleanup(&csi2->video_out); error_video: media_entity_cleanup(&csi2->subdev.entity); return ret; @@ -1341,6 +1333,33 @@ int omap4iss_csi2_init(struct iss_device *iss) return 0; } +/* + * omap4iss_csi2_create_pads_links() - CSI2 pads links creation + * @iss: Pointer to ISS device + * + * return negative error code or zero on success + */ +int omap4iss_csi2_create_pads_links(struct iss_device *iss) +{ + struct iss_csi2_device *csi2a = &iss->csi2a; + struct iss_csi2_device *csi2b = &iss->csi2b; + int ret; + + /* Connect the CSI2a subdev to the video node. */ + ret = media_create_pad_link(&csi2a->subdev.entity, CSI2_PAD_SOURCE, + &csi2a->video_out.video.entity, 0, 0); + if (ret < 0) + return ret; + + /* Connect the CSI2b subdev to the video node. */ + ret = media_create_pad_link(&csi2b->subdev.entity, CSI2_PAD_SOURCE, + &csi2b->video_out.video.entity, 0, 0); + if (ret < 0) + return ret; + + return 0; +} + /* * omap4iss_csi2_cleanup - Routine for module driver cleanup */ diff --git a/drivers/staging/media/omap4iss/iss_csi2.h b/drivers/staging/media/omap4iss/iss_csi2.h index f2f5343b4a800..1d5a0d8222a95 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.h +++ b/drivers/staging/media/omap4iss/iss_csi2.h @@ -151,6 +151,7 @@ struct iss_csi2_device { void omap4iss_csi2_isr(struct iss_csi2_device *csi2); int omap4iss_csi2_reset(struct iss_csi2_device *csi2); int omap4iss_csi2_init(struct iss_device *iss); +int omap4iss_csi2_create_pads_links(struct iss_device *iss); void omap4iss_csi2_cleanup(struct iss_device *iss); void omap4iss_csi2_unregister_entities(struct iss_csi2_device *csi2); int omap4iss_csi2_register_entities(struct iss_csi2_device *csi2, diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c index b0c5f2431b626..82608cbb1f5fa 100644 --- a/drivers/staging/media/omap4iss/iss_ipipeif.c +++ b/drivers/staging/media/omap4iss/iss_ipipeif.c @@ -757,18 +757,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif) ipipeif->video_out.bpl_zero_padding = 1; ipipeif->video_out.bpl_max = 0x1ffe0; - ret = omap4iss_video_init(&ipipeif->video_out, "ISP IPIPEIF"); - if (ret < 0) - return ret; - - /* Connect the IPIPEIF subdev to the video node. */ - ret = media_create_pad_link(&ipipeif->subdev.entity, - IPIPEIF_PAD_SOURCE_ISIF_SF, - &ipipeif->video_out.video.entity, 0, 0); - if (ret < 0) - return ret; - - return 0; + return omap4iss_video_init(&ipipeif->video_out, "ISP IPIPEIF"); } void omap4iss_ipipeif_unregister_entities(struct iss_ipipeif_device *ipipeif) @@ -820,6 +809,22 @@ int omap4iss_ipipeif_init(struct iss_device *iss) return ipipeif_init_entities(ipipeif); } +/* + * omap4iss_ipipeif_create_pads_links() - IPIPEIF pads links creation + * @iss: Pointer to ISS device + * + * return negative error code or zero on success + */ +int omap4iss_ipipeif_create_pads_links(struct iss_device *iss) +{ + struct iss_ipipeif_device *ipipeif = &iss->ipipeif; + + /* Connect the IPIPEIF subdev to the video node. */ + return media_create_pad_link(&ipipeif->subdev.entity, + IPIPEIF_PAD_SOURCE_ISIF_SF, + &ipipeif->video_out.video.entity, 0, 0); +} + /* * omap4iss_ipipeif_cleanup - IPIPEIF module cleanup. * @iss: Device pointer specific to the OMAP4 ISS. diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.h b/drivers/staging/media/omap4iss/iss_ipipeif.h index c6bd96d9656cf..dd906b41cf9be 100644 --- a/drivers/staging/media/omap4iss/iss_ipipeif.h +++ b/drivers/staging/media/omap4iss/iss_ipipeif.h @@ -78,6 +78,7 @@ struct iss_ipipeif_device { struct iss_device; int omap4iss_ipipeif_init(struct iss_device *iss); +int omap4iss_ipipeif_create_pads_links(struct iss_device *iss); void omap4iss_ipipeif_cleanup(struct iss_device *iss); int omap4iss_ipipeif_register_entities(struct iss_ipipeif_device *ipipeif, struct v4l2_device *vdev); diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c index a2cb57cb460da..4a474873a8df0 100644 --- a/drivers/staging/media/omap4iss/iss_resizer.c +++ b/drivers/staging/media/omap4iss/iss_resizer.c @@ -799,18 +799,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer) resizer->video_out.bpl_zero_padding = 1; resizer->video_out.bpl_max = 0x1ffe0; - ret = omap4iss_video_init(&resizer->video_out, "ISP resizer a"); - if (ret < 0) - return ret; - - /* Connect the RESIZER subdev to the video node. */ - ret = media_create_pad_link(&resizer->subdev.entity, - RESIZER_PAD_SOURCE_MEM, - &resizer->video_out.video.entity, 0, 0); - if (ret < 0) - return ret; - - return 0; + return omap4iss_video_init(&resizer->video_out, "ISP resizer a"); } void omap4iss_resizer_unregister_entities(struct iss_resizer_device *resizer) @@ -862,6 +851,22 @@ int omap4iss_resizer_init(struct iss_device *iss) return resizer_init_entities(resizer); } +/* + * omap4iss_resizer_create_pads_links() - RESIZER pads links creation + * @iss: Pointer to ISS device + * + * return negative error code or zero on success + */ +int omap4iss_resizer_create_pads_links(struct iss_device *iss) +{ + struct iss_resizer_device *resizer = &iss->resizer; + + /* Connect the RESIZER subdev to the video node. */ + return media_create_pad_link(&resizer->subdev.entity, + RESIZER_PAD_SOURCE_MEM, + &resizer->video_out.video.entity, 0, 0); +} + /* * omap4iss_resizer_cleanup - RESIZER module cleanup. * @iss: Device pointer specific to the OMAP4 ISS. diff --git a/drivers/staging/media/omap4iss/iss_resizer.h b/drivers/staging/media/omap4iss/iss_resizer.h index 1e145abafc656..98ab950253d0f 100644 --- a/drivers/staging/media/omap4iss/iss_resizer.h +++ b/drivers/staging/media/omap4iss/iss_resizer.h @@ -61,6 +61,7 @@ struct iss_resizer_device { struct iss_device; int omap4iss_resizer_init(struct iss_device *iss); +int omap4iss_resizer_create_pads_links(struct iss_device *iss); void omap4iss_resizer_cleanup(struct iss_device *iss); int omap4iss_resizer_register_entities(struct iss_resizer_device *resizer, struct v4l2_device *vdev); -- GitLab From 7213fe7eec174fb2b958ecc3ce04a6f811c2d4da Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 3 Sep 2015 11:20:34 -0300 Subject: [PATCH 2460/2855] [media] v4l: vsp1: create pad links after subdev registration The vsp1 driver creates the pads links before the media entities are registered with the media device. This doesn't work now that object IDs are used to create links so the media_device has to be set. Move entities registration logic before pads links creation. Signed-off-by: Javier Martinez Canillas Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_drv.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 9cd94a76a9ed2..2aa427d3ff397 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -250,6 +250,14 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) list_add_tail(&wpf->entity.list_dev, &vsp1->entities); } + /* Register all subdevs. */ + list_for_each_entry(entity, &vsp1->entities, list_dev) { + ret = v4l2_device_register_subdev(&vsp1->v4l2_dev, + &entity->subdev); + if (ret < 0) + goto done; + } + /* Create links. */ list_for_each_entry(entity, &vsp1->entities, list_dev) { if (entity->type == VSP1_ENTITY_LIF || @@ -269,14 +277,6 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) return ret; } - /* Register all subdevs. */ - list_for_each_entry(entity, &vsp1->entities, list_dev) { - ret = v4l2_device_register_subdev(&vsp1->v4l2_dev, - &entity->subdev); - if (ret < 0) - goto done; - } - ret = v4l2_device_register_subdev_nodes(&vsp1->v4l2_dev); done: -- GitLab From c7621b3044f705dd20019e82a8418491b8080327 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 3 Sep 2015 12:19:25 -0300 Subject: [PATCH 2461/2855] [media] v4l: vsp1: separate links creation from entities init The vsp1 driver initializes the entities and creates the pads links before the entities are registered with the media device. This doesn't work now that object IDs are used to create links so the media_device has to be set. Split out the pads links creation from the entity initialization so are made after the entities registration. Signed-off-by: Javier Martinez Canillas Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_drv.c | 14 +++++++-- drivers/media/platform/vsp1/vsp1_rpf.c | 29 ++++++++++++------ drivers/media/platform/vsp1/vsp1_rwpf.h | 5 ++++ drivers/media/platform/vsp1/vsp1_wpf.c | 40 +++++++++++++++---------- 4 files changed, 62 insertions(+), 26 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 2aa427d3ff397..8f995d2676467 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -260,9 +260,19 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) /* Create links. */ list_for_each_entry(entity, &vsp1->entities, list_dev) { - if (entity->type == VSP1_ENTITY_LIF || - entity->type == VSP1_ENTITY_RPF) + if (entity->type == VSP1_ENTITY_LIF) { + ret = vsp1_wpf_create_pads_links(vsp1, entity); + if (ret < 0) + goto done; + continue; + } + + if (entity->type == VSP1_ENTITY_RPF) { + ret = vsp1_rpf_create_pads_links(vsp1, entity); + if (ret < 0) + goto done; continue; + } ret = vsp1_create_links(vsp1, entity); if (ret < 0) diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c index 1bd51d22ff044..847fb6d01a5ad 100644 --- a/drivers/media/platform/vsp1/vsp1_rpf.c +++ b/drivers/media/platform/vsp1/vsp1_rpf.c @@ -277,18 +277,29 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index) rpf->entity.video = video; - /* Connect the video device to the RPF. */ - ret = media_create_pad_link(&rpf->video.video.entity, 0, - &rpf->entity.subdev.entity, - RWPF_PAD_SINK, - MEDIA_LNK_FL_ENABLED | - MEDIA_LNK_FL_IMMUTABLE); - if (ret < 0) - goto error; - return rpf; error: vsp1_entity_destroy(&rpf->entity); return ERR_PTR(ret); } + +/* + * vsp1_rpf_create_pads_links_create_pads_links() - RPF pads links creation + * @vsp1: Pointer to VSP1 device + * @entity: Pointer to VSP1 entity + * + * return negative error code or zero on success + */ +int vsp1_rpf_create_pads_links(struct vsp1_device *vsp1, + struct vsp1_entity *entity) +{ + struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev); + + /* Connect the video device to the RPF. */ + return media_create_pad_link(&rpf->video.video.entity, 0, + &rpf->entity.subdev.entity, + RWPF_PAD_SINK, + MEDIA_LNK_FL_ENABLED | + MEDIA_LNK_FL_IMMUTABLE); +} diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h index f452dce1a931d..6638b35873693 100644 --- a/drivers/media/platform/vsp1/vsp1_rwpf.h +++ b/drivers/media/platform/vsp1/vsp1_rwpf.h @@ -50,6 +50,11 @@ static inline struct vsp1_rwpf *to_rwpf(struct v4l2_subdev *subdev) struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index); struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index); +int vsp1_rpf_create_pads_links(struct vsp1_device *vsp1, + struct vsp1_entity *entity); +int vsp1_wpf_create_pads_links(struct vsp1_device *vsp1, + struct vsp1_entity *entity); + int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_mbus_code_enum *code); diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c index ca19c534dac6d..969278bc1d412 100644 --- a/drivers/media/platform/vsp1/vsp1_wpf.c +++ b/drivers/media/platform/vsp1/vsp1_wpf.c @@ -220,7 +220,6 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index) struct v4l2_subdev *subdev; struct vsp1_video *video; struct vsp1_rwpf *wpf; - unsigned int flags; int ret; wpf = devm_kzalloc(vsp1->dev, sizeof(*wpf), GFP_KERNEL); @@ -276,20 +275,6 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index) goto error; wpf->entity.video = video; - - /* Connect the video device to the WPF. All connections are immutable - * except for the WPF0 source link if a LIF is present. - */ - flags = MEDIA_LNK_FL_ENABLED; - if (!(vsp1->pdata.features & VSP1_HAS_LIF) || index != 0) - flags |= MEDIA_LNK_FL_IMMUTABLE; - - ret = media_create_pad_link(&wpf->entity.subdev.entity, - RWPF_PAD_SOURCE, - &wpf->video.video.entity, 0, flags); - if (ret < 0) - goto error; - wpf->entity.sink = &wpf->video.video.entity; return wpf; @@ -298,3 +283,28 @@ error: vsp1_entity_destroy(&wpf->entity); return ERR_PTR(ret); } + +/* + * vsp1_wpf_create_pads_links_create_pads_links() - RPF pads links creation + * @vsp1: Pointer to VSP1 device + * @entity: Pointer to VSP1 entity + * + * return negative error code or zero on success + */ +int vsp1_wpf_create_pads_links(struct vsp1_device *vsp1, + struct vsp1_entity *entity) +{ + struct vsp1_rwpf *wpf = to_rwpf(&entity->subdev); + unsigned int flags; + + /* Connect the video device to the WPF. All connections are immutable + * except for the WPF0 source link if a LIF is present. + */ + flags = MEDIA_LNK_FL_ENABLED; + if (!(vsp1->pdata.features & VSP1_HAS_LIF) || entity->index != 0) + flags |= MEDIA_LNK_FL_IMMUTABLE; + + return media_create_pad_link(&wpf->entity.subdev.entity, + RWPF_PAD_SOURCE, + &wpf->video.video.entity, 0, flags); +} -- GitLab From c5a98cac6ecd78ca647c41cb25e3ea1835579d70 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 3 Sep 2015 08:46:06 -0300 Subject: [PATCH 2462/2855] [media] uvcvideo: create pad links after subdev registration The uvc driver creates the pads links before the media entity is registered with the media device. This doesn't work now that obj IDs are used to create links so the media_device has to be set. Move entities registration logic before pads links creation. Signed-off-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_entity.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c index 429e428ccd93f..7f82b65b238e1 100644 --- a/drivers/media/usb/uvc/uvc_entity.c +++ b/drivers/media/usb/uvc/uvc_entity.c @@ -25,6 +25,15 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain, struct uvc_entity *entity) +{ + if (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING) + return 0; + + return v4l2_device_register_subdev(&chain->dev->vdev, &entity->subdev); +} + +static int uvc_mc_create_pads_links(struct uvc_video_chain *chain, + struct uvc_entity *entity) { const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE; struct media_entity *sink; @@ -62,10 +71,7 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain, return ret; } - if (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING) - return 0; - - return v4l2_device_register_subdev(&chain->dev->vdev, &entity->subdev); + return 0; } static struct v4l2_subdev_ops uvc_subdev_ops = { @@ -124,5 +130,14 @@ int uvc_mc_register_entities(struct uvc_video_chain *chain) } } + list_for_each_entry(entity, &chain->entities, chain) { + ret = uvc_mc_create_pads_links(chain, entity); + if (ret < 0) { + uvc_printk(KERN_INFO, "Failed to create pads links for " + "entity %u\n", entity->id); + return ret; + } + } + return 0; } -- GitLab From ada58ced508ffb75ff59f23b726ffc79ac2282fe Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 3 Sep 2015 09:00:27 -0300 Subject: [PATCH 2463/2855] [media] smiapp: create pad links after subdev registration The smiapp driver creates the pads links before the media entity is registered with the media device. This doesn't work now that object IDs are used to create links so the media_device has to be set. Move entity registration logic before pads links creation. Signed-off-by: Javier Martinez Canillas Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index cf0cd507c2d0c..df4f8824c344b 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2495,23 +2495,23 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor) return rval; } - rval = media_create_pad_link(&this->sd.entity, - this->source_pad, - &last->sd.entity, - last->sink_pad, - MEDIA_LNK_FL_ENABLED | - MEDIA_LNK_FL_IMMUTABLE); + rval = v4l2_device_register_subdev(sensor->src->sd.v4l2_dev, + &this->sd); if (rval) { dev_err(&client->dev, - "media_create_pad_link failed\n"); + "v4l2_device_register_subdev failed\n"); return rval; } - rval = v4l2_device_register_subdev(sensor->src->sd.v4l2_dev, - &this->sd); + rval = media_create_pad_link(&this->sd.entity, + this->source_pad, + &last->sd.entity, + last->sink_pad, + MEDIA_LNK_FL_ENABLED | + MEDIA_LNK_FL_IMMUTABLE); if (rval) { dev_err(&client->dev, - "v4l2_device_register_subdev failed\n"); + "media_create_pad_link failed\n"); return rval; } } -- GitLab From 8f6d368f726bb4fa069af5ef5806f15ba6da6ad8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 19 Aug 2015 20:18:35 -0300 Subject: [PATCH 2464/2855] [media] media: Don't accept early-created links Links are graph objects that represent the links of two already existing objects in the graph. While with the current implementation, it is possible to create the links earlier, It doesn't make any sense to allow linking two objects when they are not both created. So, remove the code that would be handling those early-created links and add a BUG_ON() to ensure that. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 7 ------- drivers/media/media-entity.c | 2 ++ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 138b18416460d..0d85c6c28004d 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -443,13 +443,6 @@ int __must_check media_device_register_entity(struct media_device *mdev, media_gobj_init(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); list_add_tail(&entity->list, &mdev->entities); - /* - * Initialize objects at the links - * in the case where links got created before entity register - */ - for (i = 0; i < entity->num_links; i++) - media_gobj_init(mdev, MEDIA_GRAPH_LINK, - &entity->links[i].graph_obj); /* Initialize objects at the pads */ for (i = 0; i < entity->num_pads; i++) media_gobj_init(mdev, MEDIA_GRAPH_PAD, diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 160ce2cc0865f..f85a711d49581 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -149,6 +149,8 @@ void media_gobj_init(struct media_device *mdev, enum media_gobj_type type, struct media_gobj *gobj) { + BUG_ON(!mdev); + gobj->mdev = mdev; /* Create a per-type unique object ID */ -- GitLab From 57208e5e25f263d27ea00e530c95f62071573cb7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 7 Aug 2015 06:55:40 -0300 Subject: [PATCH 2465/2855] [media] media: convert links from array to list The entire logic that represent graph links were developed on a time where there were no needs to dynamic remove links. So, although links are created/removed one by one via some functions, they're stored as an array inside the entity struct. As the array may grow, there's a logic inside the code that checks if the amount of space is not enough to store the needed links. If it isn't the core uses krealloc() to change the size of the link, with is bad, as it leaves the memory fragmented. So, convert links into a list. Also, currently, both source and sink entities need the link at the graph traversal logic inside media_entity. So there's a logic duplicating all links. That makes it to spend twice the memory needed. This is not a big deal for today's usage, where the number of links are not big. Yet, if during the MC workshop discussions, it was said that IIO graphs could have up to 4,000 entities. So, we may want to remove the duplication on some future. The problem is that it would require a separate linked list to store the backlinks inside the entity, or to use a more complex algorithm to do graph backlink traversal, with is something that the current graph traversal inside the core can't cope with. So, let's postpone a such change if/when it is actually needed. It should also be noticed that the media_link structure uses 44 bytes on 32-bit architectures and 84 bytes on 64-bit architecture. It will thus be allocated out of the 64-bytes and 96-bytes pools respectively. That's a 12.5% memory waste on 64-bit architectures and 31.25% on 32-bit architecture. A linked list is less efficient than an array in this case, but this could later be optimized if we can get rid of the reverse links (with would reduce memory allocation by 50%). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 9 +- drivers/media/media-device.c | 25 +++-- drivers/media/media-entity.c | 128 +++++++++++----------- drivers/media/usb/au0828/au0828-core.c | 12 +- drivers/media/usb/au0828/au0828-video.c | 8 +- drivers/media/usb/cx231xx/cx231xx-video.c | 8 +- include/media/media-entity.h | 10 +- 7 files changed, 97 insertions(+), 103 deletions(-) diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index b64f33776b740..42ab6aaeed7d1 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -622,7 +622,7 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe) struct media_device *mdev = adapter->mdev; struct media_entity *entity, *source; struct media_link *link, *found_link = NULL; - int i, ret, n_links = 0, active_links = 0; + int ret, n_links = 0, active_links = 0; fepriv->pipe_start_entity = NULL; @@ -632,8 +632,7 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe) entity = fepriv->dvbdev->entity; fepriv->pipe_start_entity = entity; - for (i = 0; i < entity->num_links; i++) { - link = &entity->links[i]; + list_for_each_entry(link, &entity->links, list) { if (link->sink->entity == entity) { found_link = link; n_links++; @@ -659,13 +658,11 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe) source = found_link->source->entity; fepriv->pipe_start_entity = source; - for (i = 0; i < source->num_links; i++) { + list_for_each_entry(link, &source->links, list) { struct media_entity *sink; int flags = 0; - link = &source->links[i]; sink = link->sink->entity; - if (sink == entity) flags = MEDIA_LNK_FL_ENABLED; diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 0d85c6c28004d..3e649cacfc075 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -150,22 +151,21 @@ static long __media_device_enum_links(struct media_device *mdev, } if (links->links) { - struct media_link_desc __user *ulink; - unsigned int l; + struct media_link *ent_link; + struct media_link_desc __user *ulink = links->links; - for (l = 0, ulink = links->links; l < entity->num_links; l++) { + list_for_each_entry(ent_link, &entity->links, list) { struct media_link_desc link; /* Ignore backlinks. */ - if (entity->links[l].source->entity != entity) + if (ent_link->source->entity != entity) continue; - memset(&link, 0, sizeof(link)); - media_device_kpad_to_upad(entity->links[l].source, + media_device_kpad_to_upad(ent_link->source, &link.source); - media_device_kpad_to_upad(entity->links[l].sink, + media_device_kpad_to_upad(ent_link->sink, &link.sink); - link.flags = entity->links[l].flags; + link.flags = ent_link->flags; if (copy_to_user(ulink, &link, sizeof(*ulink))) return -EFAULT; ulink++; @@ -437,6 +437,7 @@ int __must_check media_device_register_entity(struct media_device *mdev, /* Warn if we apparently re-register an entity */ WARN_ON(entity->graph_obj.mdev != NULL); entity->graph_obj.mdev = mdev; + INIT_LIST_HEAD(&entity->links); spin_lock(&mdev->lock); /* Initialize media_gobj embedded at the entity */ @@ -465,13 +466,17 @@ void media_device_unregister_entity(struct media_entity *entity) { int i; struct media_device *mdev = entity->graph_obj.mdev; + struct media_link *link, *tmp; if (mdev == NULL) return; spin_lock(&mdev->lock); - for (i = 0; i < entity->num_links; i++) - media_gobj_remove(&entity->links[i].graph_obj); + list_for_each_entry_safe(link, tmp, &entity->links, list) { + media_gobj_remove(&link->graph_obj); + list_del(&link->list); + kfree(link); + } for (i = 0; i < entity->num_pads; i++) media_gobj_remove(&entity->pads[i].graph_obj); media_gobj_remove(&entity->graph_obj); diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index f85a711d49581..df110acdb2f68 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -209,21 +209,13 @@ int media_entity_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads) { - struct media_link *links; - unsigned int max_links = num_pads; unsigned int i; - links = kzalloc(max_links * sizeof(links[0]), GFP_KERNEL); - if (links == NULL) - return -ENOMEM; - entity->group_id = 0; - entity->max_links = max_links; entity->num_links = 0; entity->num_backlinks = 0; entity->num_pads = num_pads; entity->pads = pads; - entity->links = links; for (i = 0; i < num_pads; i++) { pads[i].entity = entity; @@ -237,7 +229,13 @@ EXPORT_SYMBOL_GPL(media_entity_init); void media_entity_cleanup(struct media_entity *entity) { - kfree(entity->links); + struct media_link *link, *tmp; + + list_for_each_entry_safe(link, tmp, &entity->links, list) { + media_gobj_remove(&link->graph_obj); + list_del(&link->list); + kfree(link); + } } EXPORT_SYMBOL_GPL(media_entity_cleanup); @@ -263,7 +261,7 @@ static void stack_push(struct media_entity_graph *graph, return; } graph->top++; - graph->stack[graph->top].link = 0; + graph->stack[graph->top].link = (&entity->links)->next; graph->stack[graph->top].entity = entity; } @@ -305,6 +303,7 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph, } EXPORT_SYMBOL_GPL(media_entity_graph_walk_start); + /** * media_entity_graph_walk_next - Get the next entity in the graph * @graph: Media graph structure @@ -328,14 +327,16 @@ media_entity_graph_walk_next(struct media_entity_graph *graph) * top of the stack until no more entities on the level can be * found. */ - while (link_top(graph) < stack_top(graph)->num_links) { + while (link_top(graph) != &(stack_top(graph)->links)) { struct media_entity *entity = stack_top(graph); - struct media_link *link = &entity->links[link_top(graph)]; + struct media_link *link; struct media_entity *next; + link = list_entry(link_top(graph), typeof(*link), list); + /* The link is not enabled so we do not follow. */ if (!(link->flags & MEDIA_LNK_FL_ENABLED)) { - link_top(graph)++; + link_top(graph) = link_top(graph)->next; continue; } @@ -346,12 +347,12 @@ media_entity_graph_walk_next(struct media_entity_graph *graph) /* Has the entity already been visited? */ if (__test_and_set_bit(media_entity_id(next), graph->entities)) { - link_top(graph)++; + link_top(graph) = link_top(graph)->next; continue; } /* Push the new entity to stack and start over. */ - link_top(graph)++; + link_top(graph) = link_top(graph)->next; stack_push(graph, next); } @@ -383,6 +384,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_device *mdev = entity->graph_obj.mdev; struct media_entity_graph graph; struct media_entity *entity_err = entity; + struct media_link *link; int ret; mutex_lock(&mdev->graph_mutex); @@ -392,7 +394,6 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, while ((entity = media_entity_graph_walk_next(&graph))) { DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS); DECLARE_BITMAP(has_no_links, MEDIA_ENTITY_MAX_PADS); - unsigned int i; entity->stream_count++; WARN_ON(entity->pipe && entity->pipe != pipe); @@ -408,8 +409,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, bitmap_zero(active, entity->num_pads); bitmap_fill(has_no_links, entity->num_pads); - for (i = 0; i < entity->num_links; i++) { - struct media_link *link = &entity->links[i]; + list_for_each_entry(link, &entity->links, list) { struct media_pad *pad = link->sink->entity == entity ? link->sink : link->source; @@ -570,25 +570,20 @@ EXPORT_SYMBOL_GPL(media_entity_put); static struct media_link *media_entity_add_link(struct media_entity *entity) { - if (entity->num_links >= entity->max_links) { - struct media_link *links = entity->links; - unsigned int max_links = entity->max_links + 2; - unsigned int i; - - links = krealloc(links, max_links * sizeof(*links), GFP_KERNEL); - if (links == NULL) - return NULL; + struct media_link *link; - for (i = 0; i < entity->num_links; i++) - links[i].reverse->reverse = &links[i]; + link = kzalloc(sizeof(*link), GFP_KERNEL); + if (link == NULL) + return NULL; - entity->max_links = max_links; - entity->links = links; - } + list_add_tail(&link->list, &entity->links); - return &entity->links[entity->num_links++]; + return link; } +static void __media_entity_remove_link(struct media_entity *entity, + struct media_link *link); + int media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags) @@ -617,7 +612,7 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, */ backlink = media_entity_add_link(sink); if (backlink == NULL) { - source->num_links--; + __media_entity_remove_link(source, link); return -ENOMEM; } @@ -633,43 +628,51 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, backlink->reverse = link; sink->num_backlinks++; + sink->num_links++; + source->num_links++; return 0; } EXPORT_SYMBOL_GPL(media_create_pad_link); -void __media_entity_remove_links(struct media_entity *entity) +static void __media_entity_remove_link(struct media_entity *entity, + struct media_link *link) { - unsigned int i; + struct media_link *rlink, *tmp; + struct media_entity *remote; + unsigned int r = 0; + + if (link->source->entity == entity) + remote = link->sink->entity; + else + remote = link->source->entity; - for (i = 0; i < entity->num_links; i++) { - struct media_link *link = &entity->links[i]; - struct media_entity *remote; - unsigned int r = 0; + list_for_each_entry_safe(rlink, tmp, &remote->links, list) { + if (rlink != link->reverse) { + r++; + continue; + } if (link->source->entity == entity) - remote = link->sink->entity; - else - remote = link->source->entity; + remote->num_backlinks--; - while (r < remote->num_links) { - struct media_link *rlink = &remote->links[r]; - - if (rlink != link->reverse) { - r++; - continue; - } + if (--remote->num_links == 0) + break; - if (link->source->entity == entity) - remote->num_backlinks--; + /* Remove the remote link */ + list_del(&rlink->list); + kfree(rlink); + } + list_del(&link->list); + kfree(link); +} - if (--remote->num_links == 0) - break; +void __media_entity_remove_links(struct media_entity *entity) +{ + struct media_link *link, *tmp; - /* Insert last entry in place of the dropped link. */ - *rlink = remote->links[remote->num_links]; - } - } + list_for_each_entry_safe(link, tmp, &entity->links, list) + __media_entity_remove_link(entity, link); entity->num_links = 0; entity->num_backlinks = 0; @@ -794,11 +797,8 @@ struct media_link * media_entity_find_link(struct media_pad *source, struct media_pad *sink) { struct media_link *link; - unsigned int i; - - for (i = 0; i < source->entity->num_links; ++i) { - link = &source->entity->links[i]; + list_for_each_entry(link, &source->entity->links, list) { if (link->source->entity == source->entity && link->source->index == source->index && link->sink->entity == sink->entity && @@ -822,11 +822,9 @@ EXPORT_SYMBOL_GPL(media_entity_find_link); */ struct media_pad *media_entity_remote_pad(struct media_pad *pad) { - unsigned int i; - - for (i = 0; i < pad->entity->num_links; i++) { - struct media_link *link = &pad->entity->links[i]; + struct media_link *link; + list_for_each_entry(link, &pad->entity->links, list) { if (!(link->flags & MEDIA_LNK_FL_ENABLED)) continue; diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index a55eb524ea21f..7f645bcb74639 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -261,13 +261,11 @@ static void au0828_create_media_graph(struct au0828_dev *dev) if (tuner) media_create_pad_link(tuner, 0, decoder, 0, - MEDIA_LNK_FL_ENABLED); - if (dev->vdev.entity.links) - media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, - MEDIA_LNK_FL_ENABLED); - if (dev->vbi_dev.entity.links) - media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0, - MEDIA_LNK_FL_ENABLED); + MEDIA_LNK_FL_ENABLED); + media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, + MEDIA_LNK_FL_ENABLED); + media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0, + MEDIA_LNK_FL_ENABLED); #endif } diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index a1df4eb93b148..97df879c41996 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -644,7 +644,7 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev) struct media_device *mdev = dev->media_dev; struct media_entity *source; struct media_link *link, *found_link = NULL; - int i, ret, active_links = 0; + int ret, active_links = 0; if (!mdev || !dev->decoder) return 0; @@ -656,8 +656,7 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev) * do DVB streaming while the DMA engine is being used for V4L2, * this should be enough for the actual needs. */ - for (i = 0; i < dev->decoder->num_links; i++) { - link = &dev->decoder->links[i]; + list_for_each_entry(link, &dev->decoder->links, list) { if (link->sink->entity == dev->decoder) { found_link = link; if (link->flags & MEDIA_LNK_FL_ENABLED) @@ -670,11 +669,10 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev) return 0; source = found_link->source->entity; - for (i = 0; i < source->num_links; i++) { + list_for_each_entry(link, &source->links, list) { struct media_entity *sink; int flags = 0; - link = &source->links[i]; sink = link->sink->entity; if (sink == dev->decoder) diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index cbb28c9123191..b5eb9f6138725 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -106,7 +106,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev) struct media_device *mdev = dev->media_dev; struct media_entity *entity, *decoder = NULL, *source; struct media_link *link, *found_link = NULL; - int i, ret, active_links = 0; + int ret, active_links = 0; if (!mdev) return 0; @@ -127,8 +127,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev) if (!decoder) return 0; - for (i = 0; i < decoder->num_links; i++) { - link = &decoder->links[i]; + list_for_each_entry(link, &decoder->links, list) { if (link->sink->entity == decoder) { found_link = link; if (link->flags & MEDIA_LNK_FL_ENABLED) @@ -141,11 +140,10 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev) return 0; source = found_link->source->entity; - for (i = 0; i < source->num_links; i++) { + list_for_each_entry(link, &source->links, list) { struct media_entity *sink; int flags = 0; - link = &source->links[i]; sink = link->sink->entity; if (sink == entity) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 4d5fc91c4134b..2e5646cf36e7b 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -74,6 +74,7 @@ struct media_pipeline { struct media_link { struct media_gobj graph_obj; + struct list_head list; struct media_pad *source; /* Source pad */ struct media_pad *sink; /* Sink pad */ struct media_link *reverse; /* Link in the reverse direction */ @@ -116,10 +117,9 @@ struct media_entity { u16 num_links; /* Number of existing links, both * enabled and disabled */ u16 num_backlinks; /* Number of backlinks */ - u16 max_links; /* Maximum number of links */ - struct media_pad *pads; /* Pads array (num_pads elements) */ - struct media_link *links; /* Links array (max_links elements)*/ + struct media_pad *pads; /* Pads array (num_pads objects) */ + struct list_head links; /* Links list */ const struct media_entity_operations *ops; /* Entity operations */ @@ -220,7 +220,7 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id) struct media_entity_graph { struct { struct media_entity *entity; - int link; + struct list_head *link; } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH]; DECLARE_BITMAP(entities, MEDIA_ENTITY_ENUM_MAX_ID); @@ -254,7 +254,7 @@ void media_gobj_init(struct media_device *mdev, void media_gobj_remove(struct media_gobj *gobj); int media_entity_init(struct media_entity *entity, u16 num_pads, - struct media_pad *pads); + struct media_pad *pads); void media_entity_cleanup(struct media_entity *entity); int media_create_pad_link(struct media_entity *source, u16 source_pad, -- GitLab From 23615de5ee742f2f49833777ab015cf1a83fcbc3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Aug 2015 08:21:35 -0300 Subject: [PATCH 2466/2855] [media] media: make add link more generic The media_entity_add_link() function takes an entity as an argument just to get the list head. Make it more generic by changing the function argument to list_head. No functional changes. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index df110acdb2f68..e7ee666834a21 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -568,7 +568,7 @@ EXPORT_SYMBOL_GPL(media_entity_put); * Links management */ -static struct media_link *media_entity_add_link(struct media_entity *entity) +static struct media_link *media_add_link(struct list_head *head) { struct media_link *link; @@ -576,7 +576,7 @@ static struct media_link *media_entity_add_link(struct media_entity *entity) if (link == NULL) return NULL; - list_add_tail(&link->list, &entity->links); + list_add_tail(&link->list, head); return link; } @@ -595,7 +595,7 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, BUG_ON(source_pad >= source->num_pads); BUG_ON(sink_pad >= sink->num_pads); - link = media_entity_add_link(source); + link = media_add_link(&source->links); if (link == NULL) return -ENOMEM; @@ -610,7 +610,7 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, /* Create the backlink. Backlinks are used to help graph traversal and * are not reported to userspace. */ - backlink = media_entity_add_link(sink); + backlink = media_add_link(&sink->links); if (backlink == NULL) { __media_entity_remove_link(source, link); return -ENOMEM; -- GitLab From 4b8a3c08592ae0d530c87e2e1672ed8d9184dc09 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Aug 2015 09:10:07 -0300 Subject: [PATCH 2467/2855] [media] media: make media_link more generic to handle interace links By adding an union at media_link, we get for free a way to represent interface->entity links. No need to change anything at the code, just at the internal header file. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 2e5646cf36e7b..a7b21a7f4c640 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -75,14 +75,20 @@ struct media_pipeline { struct media_link { struct media_gobj graph_obj; struct list_head list; - struct media_pad *source; /* Source pad */ - struct media_pad *sink; /* Sink pad */ + union { + struct media_gobj *gobj0; + struct media_pad *source; + }; + union { + struct media_gobj *gobj1; + struct media_pad *sink; + }; struct media_link *reverse; /* Link in the reverse direction */ unsigned long flags; /* Link flags (MEDIA_LNK_FL_*) */ }; struct media_pad { - struct media_gobj graph_obj; + struct media_gobj graph_obj; /* must be first field in struct */ struct media_entity *entity; /* Entity this pad belongs to */ u16 index; /* Pad index in the entity pads array */ unsigned long flags; /* Pad flags (MEDIA_PAD_FL_*) */ @@ -105,7 +111,7 @@ struct media_entity_operations { }; struct media_entity { - struct media_gobj graph_obj; + struct media_gobj graph_obj; /* must be first field in struct */ struct list_head list; const char *name; /* Entity name */ u32 type; /* Entity type (MEDIA_ENT_T_*) */ @@ -119,7 +125,7 @@ struct media_entity { u16 num_backlinks; /* Number of backlinks */ struct media_pad *pads; /* Pads array (num_pads objects) */ - struct list_head links; /* Links list */ + struct list_head links; /* Pad-to-pad links list */ const struct media_entity_operations *ops; /* Entity operations */ -- GitLab From 3c0e266fba5897c02c4bd23521a3271d338650ad Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 21 Aug 2015 08:45:34 -0300 Subject: [PATCH 2468/2855] [media] media: make link debug printk more generic Remove entity name from the link as this exists only if the object type is PAD on both link ends. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index e7ee666834a21..e22954d2acbd6 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -94,16 +94,14 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) struct media_link *link = gobj_to_link(gobj); dev_dbg(gobj->mdev->dev, - "%s: id 0x%08x link#%d: '%s' %s#%d ==> '%s' %s#%d\n", + "%s: id 0x%08x link#%d: %s#%d ==> %s#%d\n", event_name, gobj->id, media_localid(gobj), - link->source->entity->name, - gobj_type(media_type(&link->source->graph_obj)), - media_localid(&link->source->graph_obj), + gobj_type(media_type(link->gobj0)), + media_localid(link->gobj0), - link->sink->entity->name, - gobj_type(media_type(&link->sink->graph_obj)), - media_localid(&link->sink->graph_obj)); + gobj_type(media_type(link->gobj1)), + media_localid(link->gobj1)); break; } case MEDIA_GRAPH_PAD: -- GitLab From 86e2662071d6f26704bb290317746149ce07be7a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 7 Aug 2015 10:36:25 -0300 Subject: [PATCH 2469/2855] [media] media: add support to link interfaces and entities Now that we have a new graph object called "interfaces", we need to be able to link them to the entities. Add a linked list to the interfaces to allow them to be linked to the entities. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 38 ++++++++++++++++++++++++++++++++++++ include/media/media-entity.h | 9 +++++++++ 2 files changed, 47 insertions(+) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index e22954d2acbd6..55cafb016fe8c 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -857,6 +857,7 @@ struct media_intf_devnode *media_devnode_create(struct media_device *mdev, intf->type = type; intf->flags = flags; + INIT_LIST_HEAD(&intf->links); devnode->major = major; devnode->minor = minor; @@ -874,3 +875,40 @@ void media_devnode_remove(struct media_intf_devnode *devnode) kfree(devnode); } EXPORT_SYMBOL_GPL(media_devnode_remove); + +struct media_link *media_create_intf_link(struct media_entity *entity, + struct media_interface *intf, + u32 flags) +{ + struct media_link *link; + + link = media_add_link(&intf->links); + if (link == NULL) + return NULL; + + link->intf = intf; + link->entity = entity; + link->flags = flags; + + /* Initialize graph object embedded at the new link */ + media_gobj_init(intf->graph_obj.mdev, MEDIA_GRAPH_LINK, + &link->graph_obj); + + return link; +} +EXPORT_SYMBOL_GPL(media_create_intf_link); + + +static void __media_remove_intf_link(struct media_link *link) +{ + media_gobj_remove(&link->graph_obj); + kfree(link); +} + +void media_remove_intf_link(struct media_link *link) +{ + mutex_lock(&link->graph_obj.mdev->graph_mutex); + __media_remove_intf_link(link); + mutex_unlock(&link->graph_obj.mdev->graph_mutex); +} +EXPORT_SYMBOL_GPL(media_remove_intf_link); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index a7b21a7f4c640..d64e8cb4de98e 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -78,10 +78,12 @@ struct media_link { union { struct media_gobj *gobj0; struct media_pad *source; + struct media_interface *intf; }; union { struct media_gobj *gobj1; struct media_pad *sink; + struct media_entity *entity; }; struct media_link *reverse; /* Link in the reverse direction */ unsigned long flags; /* Link flags (MEDIA_LNK_FL_*) */ @@ -154,6 +156,7 @@ struct media_entity { * struct media_intf_devnode - Define a Kernel API interface * * @graph_obj: embedded graph object + * @links: List of links pointing to graph entities * @type: Type of the interface as defined at the * uapi/media/media.h header, e. g. * MEDIA_INTF_T_* @@ -161,6 +164,7 @@ struct media_entity { */ struct media_interface { struct media_gobj graph_obj; + struct list_head links; u32 type; u32 flags; }; @@ -290,6 +294,11 @@ struct media_intf_devnode *media_devnode_create(struct media_device *mdev, u32 major, u32 minor, gfp_t gfp_flags); void media_devnode_remove(struct media_intf_devnode *devnode); +struct media_link *media_create_intf_link(struct media_entity *entity, + struct media_interface *intf, + u32 flags); +void media_remove_intf_link(struct media_link *link); + #define media_entity_call(entity, operation, args...) \ (((entity)->ops && (entity)->ops->operation) ? \ (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD) -- GitLab From 1283f849dce2e64690e610216cd8dc3df9789bae Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 28 Aug 2015 15:43:36 -0300 Subject: [PATCH 2470/2855] [media] media-entity: add a helper function to create interface As we'll be adding other interface types in the future, put the common interface create code on a separate function. Suggested-by: Hans Verkuil Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 55cafb016fe8c..d15797e8a1421 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -839,6 +839,18 @@ struct media_pad *media_entity_remote_pad(struct media_pad *pad) EXPORT_SYMBOL_GPL(media_entity_remote_pad); +static void media_interface_init(struct media_device *mdev, + struct media_interface *intf, + u32 gobj_type, + u32 intf_type, u32 flags) +{ + intf->type = intf_type; + intf->flags = flags; + INIT_LIST_HEAD(&intf->links); + + media_gobj_init(mdev, gobj_type, &intf->graph_obj); +} + /* Functions related to the media interface via device nodes */ struct media_intf_devnode *media_devnode_create(struct media_device *mdev, @@ -847,23 +859,16 @@ struct media_intf_devnode *media_devnode_create(struct media_device *mdev, gfp_t gfp_flags) { struct media_intf_devnode *devnode; - struct media_interface *intf; devnode = kzalloc(sizeof(*devnode), gfp_flags); if (!devnode) return NULL; - intf = &devnode->intf; - - intf->type = type; - intf->flags = flags; - INIT_LIST_HEAD(&intf->links); - devnode->major = major; devnode->minor = minor; - media_gobj_init(mdev, MEDIA_GRAPH_INTF_DEVNODE, - &devnode->intf.graph_obj); + media_interface_init(mdev, &devnode->intf, MEDIA_GRAPH_INTF_DEVNODE, + type, flags); return devnode; } -- GitLab From 8211b187ec6461e8d80a36304bd9fc087e3c490f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 21 Aug 2015 08:20:22 -0300 Subject: [PATCH 2471/2855] [media] dvbdev: add support for interfaces Now that the infrastruct for that is set, add support for interfaces. Please notice that we're missing two links: DVB FE intf -> tuner DVB demux intf -> dvr Those should be added latter, after having the entire graph set. With the current infrastructure, those should be added at dvb_create_media_graph(), but it would also require some extra core changes, to allow the function to enumerate the interfaces. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 102 ++++++++++++++++++++++++-------- drivers/media/dvb-core/dvbdev.h | 1 + 2 files changed, 79 insertions(+), 24 deletions(-) diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 65f59f2124b46..6bf61d42c017b 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -180,14 +180,36 @@ skip: return -ENFILE; } -static void dvb_register_media_device(struct dvb_device *dvbdev, - int type, int minor) +static void dvb_create_media_entity(struct dvb_device *dvbdev, + int type, int minor) { #if defined(CONFIG_MEDIA_CONTROLLER_DVB) int ret = 0, npads; - if (!dvbdev->adapter->mdev) + switch (type) { + case DVB_DEVICE_FRONTEND: + npads = 2; + break; + case DVB_DEVICE_DEMUX: + npads = 2; + break; + case DVB_DEVICE_CA: + npads = 2; + break; + case DVB_DEVICE_NET: + /* + * We should be creating entities for the MPE/ULE + * decapsulation hardware (or software implementation). + * + * However, the number of for the MPE/ULE decaps may not be + * fixed. As we don't have yet dynamic support for PADs at + * the Media Controller, let's not create the decap + * entities yet. + */ + return; + default: return; + } dvbdev->entity = kzalloc(sizeof(*dvbdev->entity), GFP_KERNEL); if (!dvbdev->entity) @@ -197,19 +219,6 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, dvbdev->entity->info.dev.minor = minor; dvbdev->entity->name = dvbdev->name; - switch (type) { - case DVB_DEVICE_CA: - case DVB_DEVICE_DEMUX: - case DVB_DEVICE_FRONTEND: - npads = 2; - break; - case DVB_DEVICE_NET: - npads = 0; - break; - default: - npads = 1; - } - if (npads) { dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads), GFP_KERNEL); @@ -230,18 +239,11 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; break; - case DVB_DEVICE_DVR: - dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_DVR; - dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; - break; case DVB_DEVICE_CA: dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_CA; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; break; - case DVB_DEVICE_NET: - dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_NET; - break; default: kfree(dvbdev->entity); dvbdev->entity = NULL; @@ -263,11 +265,63 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, return; } - printk(KERN_DEBUG "%s: media device '%s' registered.\n", + printk(KERN_DEBUG "%s: media entity '%s' registered.\n", __func__, dvbdev->entity->name); #endif } +static void dvb_register_media_device(struct dvb_device *dvbdev, + int type, int minor) +{ +#if defined(CONFIG_MEDIA_CONTROLLER_DVB) + u32 intf_type; + + if (!dvbdev->adapter->mdev) + return; + + dvb_create_media_entity(dvbdev, type, minor); + + switch (type) { + case DVB_DEVICE_FRONTEND: + intf_type = MEDIA_INTF_T_DVB_FE; + break; + case DVB_DEVICE_DEMUX: + intf_type = MEDIA_INTF_T_DVB_DEMUX; + break; + case DVB_DEVICE_DVR: + intf_type = MEDIA_INTF_T_DVB_DVR; + break; + case DVB_DEVICE_CA: + intf_type = MEDIA_INTF_T_DVB_CA; + break; + case DVB_DEVICE_NET: + intf_type = MEDIA_INTF_T_DVB_NET; + break; + default: + return; + } + + dvbdev->intf_devnode = media_devnode_create(dvbdev->adapter->mdev, + intf_type, 0, + DVB_MAJOR, minor, + GFP_KERNEL); + + /* + * Create the "obvious" link, e. g. the ones that represent + * a direct association between an interface and an entity. + * Other links should be created elsewhere, like: + * DVB FE intf -> tuner + * DVB demux intf -> dvr + */ + + if (!dvbdev->entity || !dvbdev->intf_devnode) + return; + + media_create_intf_link(dvbdev->entity, &dvbdev->intf_devnode->intf, 0); + +#endif +} + int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, const struct dvb_device *template, void *priv, int type) { diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index 1069a776bbdb8..8398c8fb02b03 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h @@ -149,6 +149,7 @@ struct dvb_device { /* Allocated and filled inside dvbdev.c */ struct media_entity *entity; + struct media_intf_devnode *intf_devnode; struct media_pad *pads; #endif -- GitLab From 57cf79b79b18d885c144889989b47149e23c8dc2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 21 Aug 2015 09:23:22 -0300 Subject: [PATCH 2472/2855] [media] media: add a linked list to track interfaces by mdev The media device should list the interface objects, so add a linked list for those interfaces in struct media_device. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 1 + drivers/media/media-entity.c | 3 +++ include/media/media-device.h | 2 ++ include/media/media-entity.h | 3 +++ 4 files changed, 9 insertions(+) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 3e649cacfc075..659507bce63f5 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -381,6 +381,7 @@ int __must_check __media_device_register(struct media_device *mdev, return -EINVAL; INIT_LIST_HEAD(&mdev->entities); + INIT_LIST_HEAD(&mdev->interfaces); spin_lock_init(&mdev->lock); mutex_init(&mdev->graph_mutex); diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index d15797e8a1421..8449274bb50c9 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -849,6 +849,8 @@ static void media_interface_init(struct media_device *mdev, INIT_LIST_HEAD(&intf->links); media_gobj_init(mdev, gobj_type, &intf->graph_obj); + + list_add_tail(&intf->list, &mdev->interfaces); } /* Functions related to the media interface via device nodes */ @@ -877,6 +879,7 @@ EXPORT_SYMBOL_GPL(media_devnode_create); void media_devnode_remove(struct media_intf_devnode *devnode) { media_gobj_remove(&devnode->intf.graph_obj); + list_del(&devnode->intf.list); kfree(devnode); } EXPORT_SYMBOL_GPL(media_devnode_remove); diff --git a/include/media/media-device.h b/include/media/media-device.h index 3b14394d57010..51807efa505b5 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -46,6 +46,7 @@ struct device; * @link_id: Unique ID used on the last link registered * @intf_devnode_id: Unique ID used on the last interface devnode registered * @entities: List of registered entities + * @interfaces: List of registered interfaces * @lock: Entities list lock * @graph_mutex: Entities graph operation lock * @link_notify: Link state change notification callback @@ -77,6 +78,7 @@ struct media_device { u32 intf_devnode_id; struct list_head entities; + struct list_head interfaces; /* Protects the entities list */ spinlock_t lock; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index d64e8cb4de98e..ca35e07d9348c 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -156,6 +156,8 @@ struct media_entity { * struct media_intf_devnode - Define a Kernel API interface * * @graph_obj: embedded graph object + * @list: Linked list used to find other interfaces that belong + * to the same media controller * @links: List of links pointing to graph entities * @type: Type of the interface as defined at the * uapi/media/media.h header, e. g. @@ -164,6 +166,7 @@ struct media_entity { */ struct media_interface { struct media_gobj graph_obj; + struct list_head list; struct list_head links; u32 type; u32 flags; -- GitLab From 8ddb90d2e5dc1b80c538d371bfe361e1bae29297 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 21 Aug 2015 09:32:38 -0300 Subject: [PATCH 2473/2855] [media] dvbdev: add support for indirect interface links Some interfaces indirectly control multiple entities. Add support for those. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 6bf61d42c017b..ada0738d26f26 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -441,6 +441,7 @@ void dvb_create_media_graph(struct dvb_adapter *adap) struct media_device *mdev = adap->mdev; struct media_entity *entity, *tuner = NULL, *fe = NULL; struct media_entity *demux = NULL, *dvr = NULL, *ca = NULL; + struct media_interface *intf; if (!mdev) return; @@ -476,6 +477,16 @@ void dvb_create_media_graph(struct dvb_adapter *adap) if (demux && ca) media_create_pad_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED); + + /* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */ + list_for_each_entry(intf, &mdev->interfaces, list) { + if (intf->type == MEDIA_INTF_T_DVB_CA && ca) + media_create_intf_link(ca, intf, 0); + if (intf->type == MEDIA_INTF_T_DVB_FE && tuner) + media_create_intf_link(tuner, intf, 0); + if (intf->type == MEDIA_INTF_T_DVB_DVR && demux) + media_create_intf_link(demux, intf, 0); + } } EXPORT_SYMBOL_GPL(dvb_create_media_graph); #endif -- GitLab From 32fdc0e1a87c1ed50f77a9e54413165282e99b8b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 21 Aug 2015 11:40:34 -0300 Subject: [PATCH 2474/2855] [media] uapi/media.h: Fix entity namespace Now that interfaces got created, we need to fix the entity namespace. So, let's create a consistent new namespace and add backward compatibility macros to keep the old namespace preserved. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 26 +++++------ include/uapi/linux/media.h | 76 ++++++++++++++++++++++++--------- 2 files changed, 70 insertions(+), 32 deletions(-) diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index ada0738d26f26..dadcf16550705 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -230,17 +230,17 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev, switch (type) { case DVB_DEVICE_FRONTEND: - dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_FE; + dvbdev->entity->type = MEDIA_ENT_T_DVB_DEMOD; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; break; case DVB_DEVICE_DEMUX: - dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_DEMUX; + dvbdev->entity->type = MEDIA_ENT_T_DVB_DEMUX; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; break; case DVB_DEVICE_CA: - dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_CA; + dvbdev->entity->type = MEDIA_ENT_T_DVB_CA; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; break; @@ -439,7 +439,7 @@ EXPORT_SYMBOL(dvb_unregister_device); void dvb_create_media_graph(struct dvb_adapter *adap) { struct media_device *mdev = adap->mdev; - struct media_entity *entity, *tuner = NULL, *fe = NULL; + struct media_entity *entity, *tuner = NULL, *demod = NULL; struct media_entity *demux = NULL, *dvr = NULL, *ca = NULL; struct media_interface *intf; @@ -451,26 +451,26 @@ void dvb_create_media_graph(struct dvb_adapter *adap) case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: tuner = entity; break; - case MEDIA_ENT_T_DEVNODE_DVB_FE: - fe = entity; + case MEDIA_ENT_T_DVB_DEMOD: + demod = entity; break; - case MEDIA_ENT_T_DEVNODE_DVB_DEMUX: + case MEDIA_ENT_T_DVB_DEMUX: demux = entity; break; - case MEDIA_ENT_T_DEVNODE_DVB_DVR: + case MEDIA_ENT_T_DVB_TSOUT: dvr = entity; break; - case MEDIA_ENT_T_DEVNODE_DVB_CA: + case MEDIA_ENT_T_DVB_CA: ca = entity; break; } } - if (tuner && fe) - media_create_pad_link(tuner, 0, fe, 0, 0); + if (tuner && demod) + media_create_pad_link(tuner, 0, demod, 0, 0); - if (fe && demux) - media_create_pad_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED); + if (demod && demux) + media_create_pad_link(demod, 1, demux, 0, MEDIA_LNK_FL_ENABLED); if (demux && dvr) media_create_pad_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED); diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 3ad3d6be293fb..8e9896820bee5 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -42,31 +42,69 @@ struct media_device_info { #define MEDIA_ENT_ID_FLAG_NEXT (1 << 31) +/* + * Base numbers for entity types + * + * Please notice that the huge gap of 16 bits for each base is overkill! + * 8 bits is more than enough to avoid starving entity types for each + * subsystem. + * + * However, It is kept this way just to avoid binary breakages with the + * namespace provided on legacy versions of this header. + */ +#define MEDIA_ENT_T_DVB_BASE 0x00000000 +#define MEDIA_ENT_T_V4L2_BASE 0x00010000 +#define MEDIA_ENT_T_V4L2_SUBDEV_BASE 0x00020000 + +/* + * V4L2 entities - Those are used for DMA (mmap/DMABUF) and + * read()/write() data I/O associated with the V4L2 devnodes. + */ +#define MEDIA_ENT_T_V4L2_VIDEO (MEDIA_ENT_T_V4L2_BASE + 1) + /* + * Please notice that numbers between MEDIA_ENT_T_V4L2_BASE + 2 and + * MEDIA_ENT_T_V4L2_BASE + 4 can't be used, as those values used + * to be declared for FB, ALSA and DVB entities. + * As those values were never actually used in practice, we're just + * adding them as backward compatibility macros and keeping the + * numberspace clean here. This way, we avoid breaking compilation, + * in the case of having some userspace application using the old + * symbols. + */ +#define MEDIA_ENT_T_V4L2_VBI (MEDIA_ENT_T_V4L2_BASE + 5) +#define MEDIA_ENT_T_V4L2_SWRADIO (MEDIA_ENT_T_V4L2_BASE + 6) + +/* V4L2 Sub-device entities */ +#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 1) +#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 2) +#define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 3) + /* A converter of analogue video to its digital representation. */ +#define MEDIA_ENT_T_V4L2_SUBDEV_DECODER (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 4) + /* Tuner entity is actually both V4L2 and DVB subdev */ +#define MEDIA_ENT_T_V4L2_SUBDEV_TUNER (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 5) + +/* DVB entities */ +#define MEDIA_ENT_T_DVB_DEMOD (MEDIA_ENT_T_DVB_BASE + 1) +#define MEDIA_ENT_T_DVB_DEMUX (MEDIA_ENT_T_DVB_BASE + 2) +#define MEDIA_ENT_T_DVB_TSOUT (MEDIA_ENT_T_DVB_BASE + 3) +#define MEDIA_ENT_T_DVB_CA (MEDIA_ENT_T_DVB_BASE + 4) +#define MEDIA_ENT_T_DVB_NET_DECAP (MEDIA_ENT_T_DVB_BASE + 5) + +/* Legacy symbols used to avoid userspace compilation breakages */ #define MEDIA_ENT_TYPE_SHIFT 16 #define MEDIA_ENT_TYPE_MASK 0x00ff0000 #define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff -#define MEDIA_ENT_T_DEVNODE (1 << MEDIA_ENT_TYPE_SHIFT) -#define MEDIA_ENT_T_DEVNODE_V4L (MEDIA_ENT_T_DEVNODE + 1) +#define MEDIA_ENT_T_DEVNODE MEDIA_ENT_T_V4L2_BASE +#define MEDIA_ENT_T_V4L2_SUBDEV MEDIA_ENT_T_V4L2_SUBDEV_BASE + +#define MEDIA_ENT_T_DEVNODE_V4L MEDIA_ENT_T_V4L2_VIDEO + #define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_T_DEVNODE + 2) #define MEDIA_ENT_T_DEVNODE_ALSA (MEDIA_ENT_T_DEVNODE + 3) -#define MEDIA_ENT_T_DEVNODE_DVB_FE (MEDIA_ENT_T_DEVNODE + 4) -#define MEDIA_ENT_T_DEVNODE_DVB_DEMUX (MEDIA_ENT_T_DEVNODE + 5) -#define MEDIA_ENT_T_DEVNODE_DVB_DVR (MEDIA_ENT_T_DEVNODE + 6) -#define MEDIA_ENT_T_DEVNODE_DVB_CA (MEDIA_ENT_T_DEVNODE + 7) -#define MEDIA_ENT_T_DEVNODE_DVB_NET (MEDIA_ENT_T_DEVNODE + 8) - -/* Legacy symbol. Use it to avoid userspace compilation breakages */ -#define MEDIA_ENT_T_DEVNODE_DVB MEDIA_ENT_T_DEVNODE_DVB_FE - -#define MEDIA_ENT_T_V4L2_SUBDEV (2 << MEDIA_ENT_TYPE_SHIFT) -#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV + 1) -#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV + 2) -#define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV + 3) -/* A converter of analogue video to its digital representation. */ -#define MEDIA_ENT_T_V4L2_SUBDEV_DECODER (MEDIA_ENT_T_V4L2_SUBDEV + 4) - -#define MEDIA_ENT_T_V4L2_SUBDEV_TUNER (MEDIA_ENT_T_V4L2_SUBDEV + 5) +#define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4) + +/* Entity types */ #define MEDIA_ENT_FL_DEFAULT (1 << 0) -- GitLab From cf49066152c5b46c0b90f44593beda27997ca58b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 21 Aug 2015 11:50:17 -0300 Subject: [PATCH 2475/2855] [media] replace all occurrences of MEDIA_ENT_T_DEVNODE_V4L Now that interfaces and entities are distinct, it makes no sense of keeping something named as MEDIA_ENT_T_DEVNODE. This change was done with this script: for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DEVNODE_V4L,MEDIA_ENT_T_V4L2_VIDEO, <$i >a && mv a $i; done Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml | 2 +- drivers/media/platform/xilinx/xilinx-dma.c | 2 +- drivers/media/v4l2-core/v4l2-dev.c | 2 +- drivers/media/v4l2-core/v4l2-subdev.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml index 5872f8bbf7747..910243d4edb83 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml @@ -183,7 +183,7 @@ Unknown device node - MEDIA_ENT_T_DEVNODE_V4L + MEDIA_ENT_T_V4L2_VIDEO V4L video, radio or vbi device node diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index 4b84a0e54a0cd..9c8b272542536 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -193,7 +193,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe, while ((entity = media_entity_graph_walk_next(&graph))) { struct xvip_dma *dma; - if (entity->type != MEDIA_ENT_T_DEVNODE_V4L) + if (entity->type != MEDIA_ENT_T_V4L2_VIDEO) continue; dma = to_xvip_dma(media_entity_to_video_device(entity)); diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 6b1eaeddbdb3c..2297571a0568a 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -922,7 +922,7 @@ int __video_register_device(struct video_device *vdev, int type, int nr, /* Part 5: Register the entity. */ if (vdev->v4l2_dev->mdev && vdev->vfl_type != VFL_TYPE_SUBDEV) { - vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L; + vdev->entity.type = MEDIA_ENT_T_V4L2_VIDEO; vdev->entity.name = vdev->name; vdev->entity.info.dev.major = VIDEO_MAJOR; vdev->entity.info.dev.minor = vdev->minor; diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 83615b8fb46ad..e6e1115d82150 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -535,7 +535,7 @@ v4l2_subdev_link_validate_get_format(struct media_pad *pad, return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt); } - WARN(pad->entity->type != MEDIA_ENT_T_DEVNODE_V4L, + WARN(pad->entity->type != MEDIA_ENT_T_V4L2_VIDEO, "Driver bug! Wrong media entity type 0x%08x, entity %s\n", pad->entity->type, pad->entity->name); -- GitLab From fef486a07d69cbcae81bf65a6817ff7383104a24 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 21 Aug 2015 11:54:40 -0300 Subject: [PATCH 2476/2855] [media] replace all occurrences of MEDIA_ENT_T_DEVNODE_DVB Now that interfaces and entities are distinct, it makes no sense of keeping something named as MEDIA_ENT_T_DEVNODE_DVB_foo. Made via this script: for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DEVNODE_DVB_,MEDIA_ENT_T_DVB_, <$i >a && mv a $i; done for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DVB_DVR,MEDIA_ENT_T_DVB_TSOUT, <$i >a && mv a $i; done for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DVB_FE,MEDIA_ENT_T_DVB_DEMOD, <$i >a && mv a $i; done for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DVB_NET,MEDIA_ENT_T_DVB_DEMOD_NET_DECAP, <$i >a && mv a $i; done Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../DocBook/media/v4l/media-ioc-enum-entities.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml index 910243d4edb83..32a7836356491 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml @@ -195,23 +195,23 @@ ALSA card - MEDIA_ENT_T_DEVNODE_DVB_FE + MEDIA_ENT_T_DVB_DEMOD DVB frontend devnode - MEDIA_ENT_T_DEVNODE_DVB_DEMUX + MEDIA_ENT_T_DVB_DEMUX DVB demux devnode - MEDIA_ENT_T_DEVNODE_DVB_DVR + MEDIA_ENT_T_DVB_TSOUT DVB DVR devnode - MEDIA_ENT_T_DEVNODE_DVB_CA + MEDIA_ENT_T_DVB_CA DVB CAM devnode - MEDIA_ENT_T_DEVNODE_DVB_NET + MEDIA_ENT_T_DVB_DEMOD_NET_DECAP DVB network devnode -- GitLab From fa17b46a6a01013f48c33934c09e02f51f099f2b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 21 Aug 2015 12:17:40 -0300 Subject: [PATCH 2477/2855] [media] media: add macros to check if subdev or V4L2 DMA As we'll be removing entity subtypes from the Kernel, we need to provide a way for drivers and core to check if a given entity is represented by a V4L2 subdev or if it is an V4L2 I/O entity (typically with DMA). Drivers that create entities that don't belong to any defined subdev category should use MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 34 ++++++++++++++++++++++++++++++++++ include/uapi/linux/media.h | 3 +++ 2 files changed, 37 insertions(+) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index ca35e07d9348c..2596878f4b9f1 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -220,6 +220,40 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id) return id; } +static inline bool is_media_entity_v4l2_io(struct media_entity *entity) +{ + if (!entity) + return false; + + switch (entity->type) { + case MEDIA_ENT_T_V4L2_VIDEO: + case MEDIA_ENT_T_V4L2_VBI: + case MEDIA_ENT_T_V4L2_SWRADIO: + return true; + default: + return false; + } +} + +static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) +{ + if (!entity) + return false; + + switch (entity->type) { + case MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN: + case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR: + case MEDIA_ENT_T_V4L2_SUBDEV_FLASH: + case MEDIA_ENT_T_V4L2_SUBDEV_LENS: + case MEDIA_ENT_T_V4L2_SUBDEV_DECODER: + case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: + return true; + + default: + return false; + } +} + #define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 #define MEDIA_ENTITY_ENUM_MAX_ID 64 diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 8e9896820bee5..c9314645d9330 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -75,6 +75,9 @@ struct media_device_info { #define MEDIA_ENT_T_V4L2_SWRADIO (MEDIA_ENT_T_V4L2_BASE + 6) /* V4L2 Sub-device entities */ + +#define MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN MEDIA_ENT_T_V4L2_SUBDEV_BASE + #define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 1) #define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 2) #define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 3) -- GitLab From 3efdf62c5f68007020ef935ad2887e7fc4e31c36 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 May 2015 22:12:32 -0300 Subject: [PATCH 2478/2855] [media] media: use macros to check for V4L2 subdev entities Instead of relying on media subtype, use the new macros to detect if an entity is a subdev or an A/V DMA entity. Please note that most drivers assume that there's just AV_DMA or V4L2 subdevs. This is not true anymore, as we've added MC support for DVB, and there are plans to add support for ALSA and FB/DRM too. Ok, on the current pipelines supported by those drivers, just V4L stuff are there, but, assuming that some day a pipeline that also works with other subsystems will ever added, it is better to add explicit checks for the AV_DMA stuff. Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/common.c | 3 +-- drivers/media/platform/exynos4-is/fimc-capture.c | 5 ++--- drivers/media/platform/exynos4-is/fimc-isp-video.c | 3 +-- drivers/media/platform/exynos4-is/fimc-lite.c | 10 ++++------ drivers/media/platform/exynos4-is/media-dev.c | 7 +++---- drivers/media/platform/omap3isp/isp.c | 14 ++++++-------- drivers/media/platform/omap3isp/ispvideo.c | 7 +++---- drivers/media/platform/s3c-camif/camif-capture.c | 2 +- drivers/media/platform/vsp1/vsp1_video.c | 9 ++++----- drivers/media/platform/xilinx/xilinx-dma.c | 6 ++---- drivers/media/v4l2-core/v4l2-subdev.c | 2 +- drivers/staging/media/davinci_vpfe/vpfe_video.c | 6 +++--- drivers/staging/media/omap4iss/iss.c | 14 ++++++-------- drivers/staging/media/omap4iss/iss_video.c | 5 ++--- 14 files changed, 39 insertions(+), 54 deletions(-) diff --git a/drivers/media/platform/exynos4-is/common.c b/drivers/media/platform/exynos4-is/common.c index b6716c57b5db3..b90f5bb15517b 100644 --- a/drivers/media/platform/exynos4-is/common.c +++ b/drivers/media/platform/exynos4-is/common.c @@ -22,8 +22,7 @@ struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity) while (pad->flags & MEDIA_PAD_FL_SINK) { /* source pad */ pad = media_entity_remote_pad(pad); - if (pad == NULL || - media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) break; sd = media_entity_to_v4l2_subdev(pad->entity); diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index 8f5bee42783f1..48a826372d3d5 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c @@ -1136,8 +1136,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc) } } - if (src_pad == NULL || - media_entity_type(src_pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!src_pad || !is_media_entity_v4l2_subdev(src_pad->entity)) break; /* Don't call FIMC subdev operation to avoid nested locking */ @@ -1392,7 +1391,7 @@ static int fimc_link_setup(struct media_entity *entity, struct fimc_vid_cap *vc = &fimc->vid_cap; struct v4l2_subdev *sensor; - if (media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!is_media_entity_v4l2_subdev(remote->entity)) return -EINVAL; if (WARN_ON(fimc == NULL)) diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c index 239df7d8bd306..9c7794bcf0c32 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c @@ -466,8 +466,7 @@ static int isp_video_pipeline_validate(struct fimc_isp *isp) /* Retrieve format at the source pad */ pad = media_entity_remote_pad(pad); - if (pad == NULL || - media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) break; sd = media_entity_to_v4l2_subdev(pad->entity); diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index 11d25712153dd..957cf144a6752 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -808,8 +808,7 @@ static int fimc_pipeline_validate(struct fimc_lite *fimc) } /* Retrieve format at the source pad */ pad = media_entity_remote_pad(pad); - if (pad == NULL || - media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) break; sd = media_entity_to_v4l2_subdev(pad->entity); @@ -982,7 +981,6 @@ static int fimc_lite_link_setup(struct media_entity *entity, { struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct fimc_lite *fimc = v4l2_get_subdevdata(sd); - unsigned int remote_ent_type = media_entity_type(remote->entity); int ret = 0; if (WARN_ON(fimc == NULL)) @@ -994,7 +992,7 @@ static int fimc_lite_link_setup(struct media_entity *entity, switch (local->index) { case FLITE_SD_PAD_SINK: - if (remote_ent_type != MEDIA_ENT_T_V4L2_SUBDEV) { + if (!is_media_entity_v4l2_subdev(remote->entity)) { ret = -EINVAL; break; } @@ -1012,7 +1010,7 @@ static int fimc_lite_link_setup(struct media_entity *entity, case FLITE_SD_PAD_SOURCE_DMA: if (!(flags & MEDIA_LNK_FL_ENABLED)) atomic_set(&fimc->out_path, FIMC_IO_NONE); - else if (remote_ent_type == MEDIA_ENT_T_DEVNODE) + else if (is_media_entity_v4l2_io(remote->entity)) atomic_set(&fimc->out_path, FIMC_IO_DMA); else ret = -EINVAL; @@ -1021,7 +1019,7 @@ static int fimc_lite_link_setup(struct media_entity *entity, case FLITE_SD_PAD_SOURCE_ISP: if (!(flags & MEDIA_LNK_FL_ENABLED)) atomic_set(&fimc->out_path, FIMC_IO_NONE); - else if (remote_ent_type == MEDIA_ENT_T_V4L2_SUBDEV) + else if (is_media_entity_v4l2_subdev(remote->entity)) atomic_set(&fimc->out_path, FIMC_IO_ISP); else ret = -EINVAL; diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index a67b98676dd92..a61ecedc12015 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -88,8 +88,7 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p, break; } - if (pad == NULL || - media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) break; sd = media_entity_to_v4l2_subdev(pad->entity); @@ -1062,7 +1061,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable) media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { - if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) + if (!is_media_entity_v4l2_io(entity)) continue; ret = __fimc_md_modify_pipeline(entity, enable); @@ -1076,7 +1075,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable) media_entity_graph_walk_start(&graph, entity_err); while ((entity_err = media_entity_graph_walk_next(&graph))) { - if (media_entity_type(entity_err) != MEDIA_ENT_T_DEVNODE) + if (!is_media_entity_v4l2_io(entity_err)) continue; __fimc_md_modify_pipeline(entity_err, !enable); diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 69e7733d36cd0..cb8ac90086c14 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -691,7 +691,7 @@ static int isp_pipeline_pm_use_count(struct media_entity *entity) media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { - if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE) + if (is_media_entity_v4l2_io(entity)) use += entity->use_count; } @@ -714,7 +714,7 @@ static int isp_pipeline_pm_power_one(struct media_entity *entity, int change) struct v4l2_subdev *subdev; int ret; - subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV + subdev = is_media_entity_v4l2_subdev(entity) ? media_entity_to_v4l2_subdev(entity) : NULL; if (entity->use_count == 0 && change > 0 && subdev != NULL) { @@ -754,7 +754,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change) media_entity_graph_walk_start(&graph, entity); while (!ret && (entity = media_entity_graph_walk_next(&graph))) - if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) + if (is_media_entity_v4l2_subdev(entity)) ret = isp_pipeline_pm_power_one(entity, change); if (!ret) @@ -764,7 +764,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change) while ((first = media_entity_graph_walk_next(&graph)) && first != entity) - if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE) + if (is_media_entity_v4l2_subdev(first)) isp_pipeline_pm_power_one(first, -change); return ret; @@ -897,8 +897,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe, break; pad = media_entity_remote_pad(pad); - if (pad == NULL || - media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) break; entity = pad->entity; @@ -988,8 +987,7 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) break; pad = media_entity_remote_pad(pad); - if (pad == NULL || - media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) break; entity = pad->entity; diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index a2e53b34d95fb..768efd775abca 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -210,8 +210,7 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad) remote = media_entity_remote_pad(&video->pad); - if (remote == NULL || - media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!remote || !is_media_entity_v4l2_subdev(remote->entity)) return NULL; if (pad) @@ -243,7 +242,7 @@ static int isp_video_get_graph_data(struct isp_video *video, if (entity == &video->video.entity) continue; - if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) + if (!is_media_entity_v4l2_io(entity)) continue; __video = to_isp_video(media_entity_to_video_device(entity)); @@ -919,7 +918,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video, return -EINVAL; } - if (media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!is_media_entity_v4l2_subdev(source)) return 0; pipe->external = media_entity_to_v4l2_subdev(source); diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index a87ac16273a04..05bfa9d08b19e 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c @@ -822,7 +822,7 @@ static int camif_pipeline_validate(struct camif_dev *camif) /* Retrieve format at the sensor subdev source pad */ pad = media_entity_remote_pad(&camif->pads[0]); - if (!pad || media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) return -EPIPE; src_fmt.pad = pad->index; diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index c2b2281bb5306..024d10de3740d 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -160,8 +160,7 @@ vsp1_video_remote_subdev(struct media_pad *local, u32 *pad) struct media_pad *remote; remote = media_entity_remote_pad(local); - if (remote == NULL || - media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!remote || !is_media_entity_v4l2_subdev(remote->entity)) return NULL; if (pad) @@ -297,7 +296,7 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe, return -EPIPE; /* We've reached a video node, that shouldn't have happened. */ - if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!is_media_entity_v4l2_subdev(pad->entity)) return -EPIPE; entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity)); @@ -394,7 +393,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe, struct vsp1_rwpf *rwpf; struct vsp1_entity *e; - if (media_entity_type(entity) != MEDIA_ENT_T_V4L2_SUBDEV) { + if (is_media_entity_v4l2_io(entity)) { pipe->num_video++; continue; } @@ -663,7 +662,7 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe, pad = media_entity_remote_pad(&input->pads[RWPF_PAD_SOURCE]); while (pad) { - if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!is_media_entity_v4l2_subdev(pad->entity)) break; entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity)); diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index 9c8b272542536..b3fb1570b1892 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -49,8 +49,7 @@ xvip_dma_remote_subdev(struct media_pad *local, u32 *pad) struct media_pad *remote; remote = media_entity_remote_pad(local); - if (remote == NULL || - media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!remote || !is_media_entity_v4l2_subdev(remote->entity)) return NULL; if (pad) @@ -113,8 +112,7 @@ static int xvip_pipeline_start_stop(struct xvip_pipeline *pipe, bool start) break; pad = media_entity_remote_pad(pad); - if (pad == NULL || - media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) break; entity = pad->entity; diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index e6e1115d82150..60da43772de99 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -526,7 +526,7 @@ static int v4l2_subdev_link_validate_get_format(struct media_pad *pad, struct v4l2_subdev_format *fmt) { - if (media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV) { + if (is_media_entity_v4l2_subdev(pad->entity)) { struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(pad->entity); diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 6e0d0375634d1..d21d978e139e9 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -148,7 +148,7 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video) while ((entity = media_entity_graph_walk_next(&graph))) { if (entity == &video->video_dev.entity) continue; - if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) + if ((!is_media_entity_v4l2_io(remote->entity)) continue; far_end = to_vpfe_video(media_entity_to_video_device(entity)); if (far_end->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) @@ -293,7 +293,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe) media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { - if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE) + if !is_media_entity_v4l2_subdev(entity)) continue; subdev = media_entity_to_v4l2_subdev(entity); ret = v4l2_subdev_call(subdev, video, s_stream, 1); @@ -334,7 +334,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe) while ((entity = media_entity_graph_walk_next(&graph))) { - if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE) + if (!is_media_entity_v4l2_subdev(entity)) continue; subdev = media_entity_to_v4l2_subdev(entity); ret = v4l2_subdev_call(subdev, video, s_stream, 0); diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index fa761669fd863..28e4d16544eb6 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -397,7 +397,7 @@ static int iss_pipeline_pm_use_count(struct media_entity *entity) media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { - if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE) + if (is_media_entity_v4l2_io(entity)) use += entity->use_count; } @@ -419,7 +419,7 @@ static int iss_pipeline_pm_power_one(struct media_entity *entity, int change) { struct v4l2_subdev *subdev; - subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV + subdev = is_media_entity_v4l2_subdev(entity) ? media_entity_to_v4l2_subdev(entity) : NULL; if (entity->use_count == 0 && change > 0 && subdev) { @@ -461,7 +461,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change) media_entity_graph_walk_start(&graph, entity); while (!ret && (entity = media_entity_graph_walk_next(&graph))) - if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) + if (is_media_entity_v4l2_subdev(entity)) ret = iss_pipeline_pm_power_one(entity, change); if (!ret) @@ -471,7 +471,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change) while ((first = media_entity_graph_walk_next(&graph)) && first != entity) - if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE) + if (is_media_entity_v4l2_subdev(first)) iss_pipeline_pm_power_one(first, -change); return ret; @@ -590,8 +590,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe, break; pad = media_entity_remote_pad(pad); - if (!pad || - media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) break; entity = pad->entity; @@ -658,8 +657,7 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe, break; pad = media_entity_remote_pad(pad); - if (!pad || - media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) break; entity = pad->entity; diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index ea384630aab0e..60b7a58e6122d 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -190,8 +190,7 @@ iss_video_remote_subdev(struct iss_video *video, u32 *pad) remote = media_entity_remote_pad(&video->pad); - if (!remote || - media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV) + if (!remote || !is_media_entity_v4l2_subdev(remote->entity)) return NULL; if (pad) @@ -216,7 +215,7 @@ iss_video_far_end(struct iss_video *video) if (entity == &video->video.entity) continue; - if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) + if (!is_media_entity_v4l2_io(entity)) continue; far_end = to_iss_video(media_entity_to_video_device(entity)); -- GitLab From 59ecd59d782de82d8f2d2bfda2c28f87c0e8b35a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 May 2015 22:12:33 -0300 Subject: [PATCH 2479/2855] [media] omap3/omap4/davinci: get rid of MEDIA_ENT_T_V4L2_SUBDEV abuse On omap3/omap4/davinci drivers, MEDIA_ENT_T_V4L2_SUBDEV macro is abused in order to "simplify" the pad checks. Basically, it does a logical or of this macro, in order to check for a local index and if the entity is either a subdev or not. As we'll get rid of MEDIA_ENT_T_V4L2_SUBDEV macro, replace it by 2 << 16 where it occurs, and add a note saying that the code there is actually a hack. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/ispccdc.c | 15 +++++++---- drivers/media/platform/omap3isp/ispccp2.c | 13 +++++++--- drivers/media/platform/omap3isp/ispcsi2.c | 11 +++++--- drivers/media/platform/omap3isp/isppreview.c | 15 +++++++---- drivers/media/platform/omap3isp/ispresizer.c | 13 +++++++--- .../media/davinci_vpfe/dm365_ipipeif.c | 13 +++++++--- .../staging/media/davinci_vpfe/dm365_isif.c | 13 +++++++--- .../media/davinci_vpfe/dm365_resizer.c | 25 +++++++++++-------- .../staging/media/davinci_vpfe/vpfe_video.c | 4 +-- drivers/staging/media/omap4iss/iss_csi2.c | 11 +++++--- drivers/staging/media/omap4iss/iss_ipipeif.c | 13 +++++++--- drivers/staging/media/omap4iss/iss_resizer.c | 11 +++++--- 12 files changed, 106 insertions(+), 51 deletions(-) diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 9a811f5741fa2..f0e530c981888 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -2513,9 +2513,14 @@ static int ccdc_link_setup(struct media_entity *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); struct isp_device *isp = to_isp_device(ccdc); + int index = local->index; - switch (local->index | media_entity_type(remote->entity)) { - case CCDC_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case CCDC_PAD_SINK | 2 << 16: /* Read from the sensor (parallel interface), CCP2, CSI2a or * CSI2c. */ @@ -2543,7 +2548,7 @@ static int ccdc_link_setup(struct media_entity *entity, * Revisit this when it will be implemented, and return -EBUSY for now. */ - case CCDC_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV: + case CCDC_PAD_SOURCE_VP | 2 << 16: /* Write to preview engine, histogram and H3A. When none of * those links are active, the video port can be disabled. */ @@ -2556,7 +2561,7 @@ static int ccdc_link_setup(struct media_entity *entity, } break; - case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_DEVNODE: + case CCDC_PAD_SOURCE_OF: /* Write to memory */ if (flags & MEDIA_LNK_FL_ENABLED) { if (ccdc->output & ~CCDC_OUTPUT_MEMORY) @@ -2567,7 +2572,7 @@ static int ccdc_link_setup(struct media_entity *entity, } break; - case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_V4L2_SUBDEV: + case CCDC_PAD_SOURCE_OF | 2 << 16: /* Write to resizer */ if (flags & MEDIA_LNK_FL_ENABLED) { if (ccdc->output & ~CCDC_OUTPUT_RESIZER) diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index 6ec7d104ab75f..ae3038e643ccf 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -956,9 +956,14 @@ static int ccp2_link_setup(struct media_entity *entity, { struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); + int index = local->index; - switch (local->index | media_entity_type(remote->entity)) { - case CCP2_PAD_SINK | MEDIA_ENT_T_DEVNODE: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case CCP2_PAD_SINK: /* read from memory */ if (flags & MEDIA_LNK_FL_ENABLED) { if (ccp2->input == CCP2_INPUT_SENSOR) @@ -970,7 +975,7 @@ static int ccp2_link_setup(struct media_entity *entity, } break; - case CCP2_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + case CCP2_PAD_SINK | 2 << 16: /* read from sensor/phy */ if (flags & MEDIA_LNK_FL_ENABLED) { if (ccp2->input == CCP2_INPUT_MEMORY) @@ -981,7 +986,7 @@ static int ccp2_link_setup(struct media_entity *entity, ccp2->input = CCP2_INPUT_NONE; } break; - case CCP2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: + case CCP2_PAD_SOURCE | 2 << 16: /* write to video port/ccdc */ if (flags & MEDIA_LNK_FL_ENABLED) ccp2->output = CCP2_OUTPUT_CCDC; diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index 0fb057a74f69e..b1617f7efdee2 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c @@ -1144,14 +1144,19 @@ static int csi2_link_setup(struct media_entity *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); struct isp_csi2_ctrl_cfg *ctrl = &csi2->ctrl; + int index = local->index; /* * The ISP core doesn't support pipelines with multiple video outputs. * Revisit this when it will be implemented, and return -EBUSY for now. */ - switch (local->index | media_entity_type(remote->entity)) { - case CSI2_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case CSI2_PAD_SOURCE: if (flags & MEDIA_LNK_FL_ENABLED) { if (csi2->output & ~CSI2_OUTPUT_MEMORY) return -EBUSY; @@ -1161,7 +1166,7 @@ static int csi2_link_setup(struct media_entity *entity, } break; - case CSI2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: + case CSI2_PAD_SOURCE | 2 << 16: if (flags & MEDIA_LNK_FL_ENABLED) { if (csi2->output & ~CSI2_OUTPUT_CCDC) return -EBUSY; diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index 6986d2f65c19c..cfb2debb02bfe 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c @@ -2144,9 +2144,14 @@ static int preview_link_setup(struct media_entity *entity, { struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct isp_prev_device *prev = v4l2_get_subdevdata(sd); + int index = local->index; - switch (local->index | media_entity_type(remote->entity)) { - case PREV_PAD_SINK | MEDIA_ENT_T_DEVNODE: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case PREV_PAD_SINK: /* read from memory */ if (flags & MEDIA_LNK_FL_ENABLED) { if (prev->input == PREVIEW_INPUT_CCDC) @@ -2158,7 +2163,7 @@ static int preview_link_setup(struct media_entity *entity, } break; - case PREV_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + case PREV_PAD_SINK | 2 << 16: /* read from ccdc */ if (flags & MEDIA_LNK_FL_ENABLED) { if (prev->input == PREVIEW_INPUT_MEMORY) @@ -2175,7 +2180,7 @@ static int preview_link_setup(struct media_entity *entity, * Revisit this when it will be implemented, and return -EBUSY for now. */ - case PREV_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: + case PREV_PAD_SOURCE: /* write to memory */ if (flags & MEDIA_LNK_FL_ENABLED) { if (prev->output & ~PREVIEW_OUTPUT_MEMORY) @@ -2186,7 +2191,7 @@ static int preview_link_setup(struct media_entity *entity, } break; - case PREV_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: + case PREV_PAD_SOURCE | 2 << 16: /* write to resizer */ if (flags & MEDIA_LNK_FL_ENABLED) { if (prev->output & ~PREVIEW_OUTPUT_RESIZER) diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c index 249af7f524f90..e3ecf1787fc47 100644 --- a/drivers/media/platform/omap3isp/ispresizer.c +++ b/drivers/media/platform/omap3isp/ispresizer.c @@ -1623,9 +1623,14 @@ static int resizer_link_setup(struct media_entity *entity, { struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct isp_res_device *res = v4l2_get_subdevdata(sd); + int index = local->index; - switch (local->index | media_entity_type(remote->entity)) { - case RESZ_PAD_SINK | MEDIA_ENT_T_DEVNODE: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case RESZ_PAD_SINK: /* read from memory */ if (flags & MEDIA_LNK_FL_ENABLED) { if (res->input == RESIZER_INPUT_VP) @@ -1637,7 +1642,7 @@ static int resizer_link_setup(struct media_entity *entity, } break; - case RESZ_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + case RESZ_PAD_SINK | 2 << 16: /* read from ccdc or previewer */ if (flags & MEDIA_LNK_FL_ENABLED) { if (res->input == RESIZER_INPUT_MEMORY) @@ -1649,7 +1654,7 @@ static int resizer_link_setup(struct media_entity *entity, } break; - case RESZ_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: + case RESZ_PAD_SOURCE: /* resizer always write to memory */ break; diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c index d96bdaaae50e5..b66584ecb6933 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c @@ -885,9 +885,14 @@ ipipeif_link_setup(struct media_entity *entity, const struct media_pad *local, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd); struct vpfe_device *vpfe = to_vpfe_device(ipipeif); + int index = local->index; - switch (local->index | media_entity_type(remote->entity)) { - case IPIPEIF_PAD_SINK | MEDIA_ENT_T_DEVNODE: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case IPIPEIF_PAD_SINK: /* Single shot mode */ if (!(flags & MEDIA_LNK_FL_ENABLED)) { ipipeif->input = IPIPEIF_INPUT_NONE; @@ -896,7 +901,7 @@ ipipeif_link_setup(struct media_entity *entity, const struct media_pad *local, ipipeif->input = IPIPEIF_INPUT_MEMORY; break; - case IPIPEIF_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + case IPIPEIF_PAD_SINK | 2 << 16: /* read from isif */ if (!(flags & MEDIA_LNK_FL_ENABLED)) { ipipeif->input = IPIPEIF_INPUT_NONE; @@ -908,7 +913,7 @@ ipipeif_link_setup(struct media_entity *entity, const struct media_pad *local, ipipeif->input = IPIPEIF_INPUT_ISIF; break; - case IPIPEIF_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: + case IPIPEIF_PAD_SOURCE | 2 << 16: if (!(flags & MEDIA_LNK_FL_ENABLED)) { ipipeif->output = IPIPEIF_OUTPUT_NONE; break; diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c index df77288b0ec02..8ca0c1297ec8c 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_isif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c @@ -1707,9 +1707,14 @@ isif_link_setup(struct media_entity *entity, const struct media_pad *local, { struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd); + int index = local->index; - switch (local->index | media_entity_type(remote->entity)) { - case ISIF_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case ISIF_PAD_SINK | 2 << 16: /* read from decoder/sensor */ if (!(flags & MEDIA_LNK_FL_ENABLED)) { isif->input = ISIF_INPUT_NONE; @@ -1720,7 +1725,7 @@ isif_link_setup(struct media_entity *entity, const struct media_pad *local, isif->input = ISIF_INPUT_PARALLEL; break; - case ISIF_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: + case ISIF_PAD_SOURCE: /* write to memory */ if (flags & MEDIA_LNK_FL_ENABLED) isif->output = ISIF_OUTPUT_MEMORY; @@ -1728,7 +1733,7 @@ isif_link_setup(struct media_entity *entity, const struct media_pad *local, isif->output = ISIF_OUTPUT_NONE; break; - case ISIF_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: + case ISIF_PAD_SOURCE | 2 << 16: if (flags & MEDIA_LNK_FL_ENABLED) isif->output = ISIF_OUTPUT_IPIPEIF; else diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index 50c8725c5aa60..ba887efd226a3 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c @@ -1648,10 +1648,15 @@ static int resizer_link_setup(struct media_entity *entity, struct vpfe_device *vpfe_dev = to_vpfe_device(resizer); u16 ipipeif_source = vpfe_dev->vpfe_ipipeif.output; u16 ipipe_source = vpfe_dev->vpfe_ipipe.output; + int index = local->index; + + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; if (&resizer->crop_resizer.subdev == sd) { - switch (local->index | media_entity_type(remote->entity)) { - case RESIZER_CROP_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + switch (index) { + case RESIZER_CROP_PAD_SINK | 2 << 16: if (!(flags & MEDIA_LNK_FL_ENABLED)) { resizer->crop_resizer.input = RESIZER_CROP_INPUT_NONE; @@ -1671,7 +1676,7 @@ static int resizer_link_setup(struct media_entity *entity, return -EINVAL; break; - case RESIZER_CROP_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: + case RESIZER_CROP_PAD_SOURCE | 2 << 16: if (!(flags & MEDIA_LNK_FL_ENABLED)) { resizer->crop_resizer.output = RESIZER_CROP_OUTPUT_NONE; @@ -1683,7 +1688,7 @@ static int resizer_link_setup(struct media_entity *entity, resizer->crop_resizer.output = RESIZER_A; break; - case RESIZER_CROP_PAD_SOURCE2 | MEDIA_ENT_T_V4L2_SUBDEV: + case RESIZER_CROP_PAD_SOURCE2 | 2 << 16: if (!(flags & MEDIA_LNK_FL_ENABLED)) { resizer->crop_resizer.output2 = RESIZER_CROP_OUTPUT_NONE; @@ -1699,8 +1704,8 @@ static int resizer_link_setup(struct media_entity *entity, return -EINVAL; } } else if (&resizer->resizer_a.subdev == sd) { - switch (local->index | media_entity_type(remote->entity)) { - case RESIZER_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + switch (index) { + case RESIZER_PAD_SINK | 2 << 16: if (!(flags & MEDIA_LNK_FL_ENABLED)) { resizer->resizer_a.input = RESIZER_INPUT_NONE; break; @@ -1710,7 +1715,7 @@ static int resizer_link_setup(struct media_entity *entity, resizer->resizer_a.input = RESIZER_INPUT_CROP_RESIZER; break; - case RESIZER_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: + case RESIZER_PAD_SOURCE: if (!(flags & MEDIA_LNK_FL_ENABLED)) { resizer->resizer_a.output = RESIZER_OUTPUT_NONE; break; @@ -1724,8 +1729,8 @@ static int resizer_link_setup(struct media_entity *entity, return -EINVAL; } } else if (&resizer->resizer_b.subdev == sd) { - switch (local->index | media_entity_type(remote->entity)) { - case RESIZER_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + switch (index) { + case RESIZER_PAD_SINK | 2 << 16: if (!(flags & MEDIA_LNK_FL_ENABLED)) { resizer->resizer_b.input = RESIZER_INPUT_NONE; break; @@ -1735,7 +1740,7 @@ static int resizer_link_setup(struct media_entity *entity, resizer->resizer_b.input = RESIZER_INPUT_CROP_RESIZER; break; - case RESIZER_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: + case RESIZER_PAD_SOURCE: if (!(flags & MEDIA_LNK_FL_ENABLED)) { resizer->resizer_b.output = RESIZER_OUTPUT_NONE; break; diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index d21d978e139e9..290f4b490b764 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -148,7 +148,7 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video) while ((entity = media_entity_graph_walk_next(&graph))) { if (entity == &video->video_dev.entity) continue; - if ((!is_media_entity_v4l2_io(remote->entity)) + if (!is_media_entity_v4l2_io(entity)) continue; far_end = to_vpfe_video(media_entity_to_video_device(entity)); if (far_end->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) @@ -293,7 +293,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe) media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { - if !is_media_entity_v4l2_subdev(entity)) + if (!is_media_entity_v4l2_subdev(entity)) continue; subdev = media_entity_to_v4l2_subdev(entity); ret = v4l2_subdev_call(subdev, video, s_stream, 1); diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c index 13878a2752779..2b9a36cd8fa8e 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.c +++ b/drivers/staging/media/omap4iss/iss_csi2.c @@ -1170,14 +1170,19 @@ static int csi2_link_setup(struct media_entity *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd); struct iss_csi2_ctrl_cfg *ctrl = &csi2->ctrl; + int index = local->index; + + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; /* * The ISS core doesn't support pipelines with multiple video outputs. * Revisit this when it will be implemented, and return -EBUSY for now. */ - switch (local->index | media_entity_type(remote->entity)) { - case CSI2_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: + switch (index) { + case CSI2_PAD_SOURCE: if (flags & MEDIA_LNK_FL_ENABLED) { if (csi2->output & ~CSI2_OUTPUT_MEMORY) return -EBUSY; @@ -1187,7 +1192,7 @@ static int csi2_link_setup(struct media_entity *entity, } break; - case CSI2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: + case CSI2_PAD_SOURCE | 2 << 16: if (flags & MEDIA_LNK_FL_ENABLED) { if (csi2->output & ~CSI2_OUTPUT_IPIPEIF) return -EBUSY; diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c index 82608cbb1f5fa..8cbb9840a989c 100644 --- a/drivers/staging/media/omap4iss/iss_ipipeif.c +++ b/drivers/staging/media/omap4iss/iss_ipipeif.c @@ -662,9 +662,14 @@ static int ipipeif_link_setup(struct media_entity *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct iss_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd); struct iss_device *iss = to_iss_device(ipipeif); + int index = local->index; - switch (local->index | media_entity_type(remote->entity)) { - case IPIPEIF_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case IPIPEIF_PAD_SINK | 2 << 16: /* Read from the sensor CSI2a or CSI2b. */ if (!(flags & MEDIA_LNK_FL_ENABLED)) { ipipeif->input = IPIPEIF_INPUT_NONE; @@ -681,7 +686,7 @@ static int ipipeif_link_setup(struct media_entity *entity, break; - case IPIPEIF_PAD_SOURCE_ISIF_SF | MEDIA_ENT_T_DEVNODE: + case IPIPEIF_PAD_SOURCE_ISIF_SF: /* Write to memory */ if (flags & MEDIA_LNK_FL_ENABLED) { if (ipipeif->output & ~IPIPEIF_OUTPUT_MEMORY) @@ -692,7 +697,7 @@ static int ipipeif_link_setup(struct media_entity *entity, } break; - case IPIPEIF_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV: + case IPIPEIF_PAD_SOURCE_VP | 2 << 16: /* Send to IPIPE/RESIZER */ if (flags & MEDIA_LNK_FL_ENABLED) { if (ipipeif->output & ~IPIPEIF_OUTPUT_VP) diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c index 4a474873a8df0..a3925ecd0ed79 100644 --- a/drivers/staging/media/omap4iss/iss_resizer.c +++ b/drivers/staging/media/omap4iss/iss_resizer.c @@ -716,9 +716,14 @@ static int resizer_link_setup(struct media_entity *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct iss_resizer_device *resizer = v4l2_get_subdevdata(sd); struct iss_device *iss = to_iss_device(resizer); + int index = local->index; - switch (local->index | media_entity_type(remote->entity)) { - case RESIZER_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case RESIZER_PAD_SINK | 2 << 16: /* Read from IPIPE or IPIPEIF. */ if (!(flags & MEDIA_LNK_FL_ENABLED)) { resizer->input = RESIZER_INPUT_NONE; @@ -735,7 +740,7 @@ static int resizer_link_setup(struct media_entity *entity, break; - case RESIZER_PAD_SOURCE_MEM | MEDIA_ENT_T_DEVNODE: + case RESIZER_PAD_SOURCE_MEM: /* Write to memory */ if (flags & MEDIA_LNK_FL_ENABLED) { if (resizer->output & ~RESIZER_OUTPUT_MEMORY) -- GitLab From cb716165536cde417de54de4657454bf39a8ba4d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 May 2015 22:12:34 -0300 Subject: [PATCH 2480/2855] [media] s5c73m3: fix subdev type This sensor driver is abusing MEDIA_ENT_T_V4L2_SUBDEV, creating some subdevs with a non-existing type. As this is a sensor driver, one of the entries is MEDIA_ENT_T_CAM_SENSOR. The other one will be using MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, because the subdev is not any of the already existing types. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index 45c823b68f489..ee7404ee66597 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1688,7 +1688,7 @@ static int s5c73m3_probe(struct i2c_client *client, state->sensor_pads[S5C73M3_JPEG_PAD].flags = MEDIA_PAD_FL_SOURCE; state->sensor_pads[S5C73M3_ISP_PAD].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; + sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS, state->sensor_pads); @@ -1704,7 +1704,7 @@ static int s5c73m3_probe(struct i2c_client *client, state->oif_pads[OIF_ISP_PAD].flags = MEDIA_PAD_FL_SINK; state->oif_pads[OIF_JPEG_PAD].flags = MEDIA_PAD_FL_SINK; state->oif_pads[OIF_SOURCE_PAD].flags = MEDIA_PAD_FL_SOURCE; - oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; + oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN; ret = media_entity_init(&oif_sd->entity, OIF_NUM_PADS, state->oif_pads); -- GitLab From 26614b9bf8b534406835ea66732c12e6fd7b50fd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 May 2015 22:12:35 -0300 Subject: [PATCH 2481/2855] [media] s5k5baf: fix subdev type The driver creates two subdevs, one for the image sensor pixel array (and the related readout logic) and one for an ISP. The first subdev already uses the MEDIA_ENT_T_V4L2_SUBDEV_SENSOR type, but the second subdev isn't a sensor pixel array. So, rename the second subdev as MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/s5k5baf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index d3bff30bcb6f8..3e929858d5be1 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -1919,7 +1919,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state, state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK; state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; + sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN; ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads); if (!ret) -- GitLab From 14fae6fc53b2b390bbba650d60b9555e9f7f4f26 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 May 2015 22:12:36 -0300 Subject: [PATCH 2482/2855] [media] davinci_vbpe: stop MEDIA_ENT_T_V4L2_SUBDEV abuse This driver is abusing MEDIA_ENT_T_V4L2_SUBDEV: - it uses a hack to check if the remote entity is a subdev; - it still uses the legacy entity subtype check macro, that will be removed soon. Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/davinci_vpfe/dm365_ipipe.c | 9 ++++++--- drivers/staging/media/davinci_vpfe/vpfe_video.c | 5 ++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c index 3badf169c419a..77837afab0ce6 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c @@ -1712,8 +1712,11 @@ ipipe_link_setup(struct media_entity *entity, const struct media_pad *local, struct vpfe_device *vpfe_dev = to_vpfe_device(ipipe); u16 ipipeif_sink = vpfe_dev->vpfe_ipipeif.input; - switch (local->index | media_entity_type(remote->entity)) { - case IPIPE_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + if (!is_media_entity_v4l2_subdev(remote->entity)) + return -EINVAL; + + switch (local->index) { + case IPIPE_PAD_SINK: if (!(flags & MEDIA_LNK_FL_ENABLED)) { ipipe->input = IPIPE_INPUT_NONE; break; @@ -1726,7 +1729,7 @@ ipipe_link_setup(struct media_entity *entity, const struct media_pad *local, ipipe->input = IPIPE_INPUT_CCDC; break; - case IPIPE_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: + case IPIPE_PAD_SOURCE: /* out to RESIZER */ if (flags & MEDIA_LNK_FL_ENABLED) ipipe->output = IPIPE_OUTPUT_RESIZER; diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 290f4b490b764..a5e30413fc47c 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -88,7 +88,7 @@ vpfe_video_remote_subdev(struct vpfe_video_device *video, u32 *pad) { struct media_pad *remote = media_entity_remote_pad(&video->pad); - if (remote == NULL || remote->entity->type != MEDIA_ENT_T_V4L2_SUBDEV) + if (!remote || !is_media_entity_v4l2_subdev(remote->entity)) return NULL; if (pad) *pad = remote->index; @@ -243,8 +243,7 @@ static int vpfe_video_validate_pipeline(struct vpfe_pipeline *pipe) /* Retrieve the source format */ pad = media_entity_remote_pad(pad); - if (pad == NULL || - pad->entity->type != MEDIA_ENT_T_V4L2_SUBDEV) + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) break; subdev = media_entity_to_v4l2_subdev(pad->entity); -- GitLab From bf4178a4c63443da1475c9c1bbb39963e75aa69b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 May 2015 22:12:37 -0300 Subject: [PATCH 2483/2855] [media] omap4iss: change the logic that checks if an entity is a subdev As we're getting rid of an specific number range for the V4L2 subdev, we need to replace the check for MEDIA_ENT_T_V4L2_SUBDEV by a macro. Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/omap4iss/iss_ipipe.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/staging/media/omap4iss/iss_ipipe.c b/drivers/staging/media/omap4iss/iss_ipipe.c index 44220765fb3aa..dd9d7d54e6f86 100644 --- a/drivers/staging/media/omap4iss/iss_ipipe.c +++ b/drivers/staging/media/omap4iss/iss_ipipe.c @@ -447,8 +447,11 @@ static int ipipe_link_setup(struct media_entity *entity, struct iss_ipipe_device *ipipe = v4l2_get_subdevdata(sd); struct iss_device *iss = to_iss_device(ipipe); - switch (local->index | media_entity_type(remote->entity)) { - case IPIPE_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + if (!is_media_entity_v4l2_subdev(remote->entity)) + return -EINVAL; + + switch (local->index) { + case IPIPE_PAD_SINK: /* Read from IPIPEIF. */ if (!(flags & MEDIA_LNK_FL_ENABLED)) { ipipe->input = IPIPE_INPUT_NONE; @@ -463,7 +466,7 @@ static int ipipe_link_setup(struct media_entity *entity, break; - case IPIPE_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV: + case IPIPE_PAD_SOURCE_VP: /* Send to RESIZER */ if (flags & MEDIA_LNK_FL_ENABLED) { if (ipipe->output & ~IPIPE_OUTPUT_VP) -- GitLab From b50bde4e476dede4a28e9c8fdcd134da2f34ef2e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 May 2015 22:12:38 -0300 Subject: [PATCH 2484/2855] [media] v4l2-subdev: use MEDIA_ENT_T_UNKNOWN for new subdevs Instead of abusing MEDIA_ENT_T_V4L2_SUBDEV, initialize new subdev entities as MEDIA_ENT_T_UNKNOWN. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 6 ++++++ drivers/media/v4l2-core/v4l2-subdev.c | 2 +- include/uapi/linux/media.h | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 659507bce63f5..134fe75101950 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -435,6 +435,12 @@ int __must_check media_device_register_entity(struct media_device *mdev, { int i; + if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN || + entity->type == MEDIA_ENT_T_UNKNOWN) + dev_warn(mdev->dev, + "Entity type for entity %s was not initialized!\n", + entity->name); + /* Warn if we apparently re-register an entity */ WARN_ON(entity->graph_obj.mdev != NULL); entity->graph_obj.mdev = mdev; diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 60da43772de99..b3bcc8253182b 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -584,7 +584,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) sd->host_priv = NULL; #if defined(CONFIG_MEDIA_CONTROLLER) sd->entity.name = sd->name; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; + sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN; #endif } EXPORT_SYMBOL(v4l2_subdev_init); diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index c9314645d9330..43109445d1265 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -42,6 +42,14 @@ struct media_device_info { #define MEDIA_ENT_ID_FLAG_NEXT (1 << 31) +/* Used values for media_entity_desc::type */ + +/* + * Initial value to be used when a new entity is created + * Drivers should change it to something useful + */ +#define MEDIA_ENT_T_UNKNOWN 0x00000000 + /* * Base numbers for entity types * @@ -76,6 +84,12 @@ struct media_device_info { /* V4L2 Sub-device entities */ +/* + * Subdevs are initialized with MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, + * in order to preserve backward compatibility. + * Drivers should change to the proper subdev type before + * registering the entity. + */ #define MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN MEDIA_ENT_T_V4L2_SUBDEV_BASE #define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 1) -- GitLab From 687b4209c83e9b0633f794949c0bc6fb1401ccba Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 May 2015 22:12:39 -0300 Subject: [PATCH 2485/2855] [media] media controller: get rid of entity subtype on Kernel Don't use anymore the type/subtype entity data/macros inside the Kernel. Acked-by: Hans Verkuil Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 10 ---------- include/uapi/linux/media.h | 2 -- 2 files changed, 12 deletions(-) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 2596878f4b9f1..5171e3c1c71a5 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -185,16 +185,6 @@ struct media_intf_devnode { u32 minor; }; -static inline u32 media_entity_type(struct media_entity *entity) -{ - return entity->type & MEDIA_ENT_TYPE_MASK; -} - -static inline u32 media_entity_subtype(struct media_entity *entity) -{ - return entity->type & MEDIA_ENT_SUBTYPE_MASK; -} - static inline u32 media_entity_id(struct media_entity *entity) { return entity->graph_obj.id; diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 43109445d1265..ecb6ac865905d 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -42,8 +42,6 @@ struct media_device_info { #define MEDIA_ENT_ID_FLAG_NEXT (1 << 31) -/* Used values for media_entity_desc::type */ - /* * Initial value to be used when a new entity is created * Drivers should change it to something useful -- GitLab From 4376679a3426c88caba883bcaf4e9af04eba6d9d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 29 Aug 2015 14:50:46 -0300 Subject: [PATCH 2486/2855] [media] media.h: don't use legacy entity macros at Kernel Put the legacy MEDIA_ENT_* macros under a #ifndef __KERNEL__, in order to be sure that none of those old symbols are used inside the Kernel. Acked-by: Laurent Pinchart Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index ecb6ac865905d..3c4080106df8b 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -105,6 +105,7 @@ struct media_device_info { #define MEDIA_ENT_T_DVB_CA (MEDIA_ENT_T_DVB_BASE + 4) #define MEDIA_ENT_T_DVB_NET_DECAP (MEDIA_ENT_T_DVB_BASE + 5) +#ifndef __KERNEL__ /* Legacy symbols used to avoid userspace compilation breakages */ #define MEDIA_ENT_TYPE_SHIFT 16 #define MEDIA_ENT_TYPE_MASK 0x00ff0000 @@ -118,6 +119,7 @@ struct media_device_info { #define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_T_DEVNODE + 2) #define MEDIA_ENT_T_DEVNODE_ALSA (MEDIA_ENT_T_DEVNODE + 3) #define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4) +#endif /* Entity types */ -- GitLab From 4ae1723af80ce5a23fa5bc6db1534265af0d6107 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 May 2015 22:12:40 -0300 Subject: [PATCH 2487/2855] [media] DocBook: update descriptions for the media controller entities Cleanup the media controller entities description: - remove MEDIA_ENT_T_DEVNODE and MEDIA_ENT_T_V4L2_SUBDEV entity types, as they don't mean anything; - add MEDIA_ENT_T_UNKNOWN with a proper description; - remove ALSA and FB entity types. Those should not be used, as the types are deprecated. We'll soon be adidng ALSA, but with a different entity namespace; - improve the description of some entities. Signed-off-by: Mauro Carvalho Chehab --- .../media/v4l/media-ioc-enum-entities.xml | 47 +++++++++---------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml index 32a7836356491..13d0b5891fb76 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml @@ -179,70 +179,67 @@ - MEDIA_ENT_T_DEVNODE - Unknown device node + MEDIA_ENT_T_UNKNOWN and MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN + Unknown entity. That generally indicates that + a driver didn't initialize properly the entity, with is a Kernel bug MEDIA_ENT_T_V4L2_VIDEO - V4L video, radio or vbi device node + V4L video streaming input or output entity - MEDIA_ENT_T_DEVNODE_FB - Frame buffer device node + MEDIA_ENT_T_V4L2_VBI + V4L VBI streaming input or output entity - MEDIA_ENT_T_DEVNODE_ALSA - ALSA card + MEDIA_ENT_T_V4L2_SWRADIO + V4L Software Digital Radio (SDR) streaming input or output entity MEDIA_ENT_T_DVB_DEMOD - DVB frontend devnode + DVB demodulator entity MEDIA_ENT_T_DVB_DEMUX - DVB demux devnode + DVB demux entity. Can be implemented in hardware or in Kernelspace MEDIA_ENT_T_DVB_TSOUT - DVB DVR devnode + DVB Transport Stream output entity MEDIA_ENT_T_DVB_CA - DVB CAM devnode + DVB Conditional Access module (CAM) entity MEDIA_ENT_T_DVB_DEMOD_NET_DECAP - DVB network devnode - - - MEDIA_ENT_T_V4L2_SUBDEV - Unknown V4L sub-device + DVB network ULE/MLE de-encapsulation entity. Can be implemented in hardware or in Kernelspace MEDIA_ENT_T_V4L2_SUBDEV_SENSOR - Video sensor + Camera image sensor entity MEDIA_ENT_T_V4L2_SUBDEV_FLASH - Flash controller + Flash controller entity MEDIA_ENT_T_V4L2_SUBDEV_LENS - Lens controller + Lens controller entity MEDIA_ENT_T_V4L2_SUBDEV_DECODER - Video decoder, the basic function of the video decoder is to - accept analogue video from a wide variety of sources such as + Analog video decoder, the basic function of the video decoder + is to accept analogue video from a wide variety of sources such as broadcast, DVD players, cameras and video cassette recorders, in - either NTSC, PAL or HD format and still occasionally SECAM, separate - it into its component parts, luminance and chrominance, and output - it in some digital video standard, with appropriate embedded timing + either NTSC, PAL, SECAM or HD format, separating the stream + into its component parts, luminance and chrominance, and output + it in some digital video standard, with appropriate timing signals. MEDIA_ENT_T_V4L2_SUBDEV_TUNER - TV and/or radio tuner + Digital TV, analog TV, radio and/or software radio tuner -- GitLab From df2f94e563edcbcb4b8652d05a3789d03b395366 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 21 Aug 2015 16:18:18 -0300 Subject: [PATCH 2488/2855] [media] dvb: modify core to implement interfaces/entities at MC new gen The Media Controller New Generation redefines the types for both interfaces and entities to be used on DVB. Make the needed changes at the DVB core for all interfaces, entities and data and interface links to appear in the graph. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dmxdev.c | 4 +- drivers/media/dvb-core/dvb_ca_en50221.c | 2 +- drivers/media/dvb-core/dvb_frontend.c | 2 +- drivers/media/dvb-core/dvb_net.c | 2 +- drivers/media/dvb-core/dvbdev.c | 146 ++++++++++++++++++--- drivers/media/dvb-core/dvbdev.h | 9 +- drivers/media/firewire/firedtv-ci.c | 2 +- drivers/media/pci/bt8xx/dst_ca.c | 3 +- drivers/media/pci/ddbridge/ddbridge-core.c | 2 +- drivers/media/pci/ngene/ngene-core.c | 2 +- drivers/media/pci/ttpci/av7110.c | 2 +- drivers/media/pci/ttpci/av7110_av.c | 4 +- drivers/media/pci/ttpci/av7110_ca.c | 2 +- 13 files changed, 148 insertions(+), 34 deletions(-) diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index ea9abde902e9e..a168cbe1c9985 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -1244,9 +1244,9 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) } dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, - DVB_DEVICE_DEMUX); + DVB_DEVICE_DEMUX, dmxdev->filternum); dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, - dmxdev, DVB_DEVICE_DVR); + dmxdev, DVB_DEVICE_DVR, dmxdev->filternum); dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192); diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index fb66184dc9b66..f82cd1ff4f3a0 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -1695,7 +1695,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, pubca->private = ca; /* register the DVB device */ - ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA); + ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA, 0); if (ret) goto free_slot_info; diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 42ab6aaeed7d1..40080645341e7 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -2759,7 +2759,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb, fe->dvb->num, fe->id, fe->ops.info.name); dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, - fe, DVB_DEVICE_FRONTEND); + fe, DVB_DEVICE_FRONTEND, 0); /* * Initialize the cache to the proper values according with the diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index ce4332e80a910..ce6a711b42d49 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c @@ -1502,6 +1502,6 @@ int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet, dvbnet->state[i] = 0; return dvb_register_device(adap, &dvbnet->dvbdev, &dvbdev_net, - dvbnet, DVB_DEVICE_NET); + dvbnet, DVB_DEVICE_NET, 0); } EXPORT_SYMBOL(dvb_net_init); diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index dadcf16550705..6babc688801bb 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -180,18 +180,86 @@ skip: return -ENFILE; } +static void dvb_create_tsout_entity(struct dvb_device *dvbdev, + const char *name, int npads) +{ +#if defined(CONFIG_MEDIA_CONTROLLER_DVB) + int i, ret = 0; + + dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads), + GFP_KERNEL); + if (!dvbdev->tsout_pads) + return; + dvbdev->tsout_entity = kcalloc(npads, sizeof(*dvbdev->tsout_entity), + GFP_KERNEL); + if (!dvbdev->tsout_entity) { + kfree(dvbdev->tsout_pads); + dvbdev->tsout_pads = NULL; + return; + } + for (i = 0; i < npads; i++) { + struct media_pad *pads = &dvbdev->tsout_pads[i]; + struct media_entity *entity = &dvbdev->tsout_entity[i]; + + entity->name = kasprintf(GFP_KERNEL, "%s #%d", name, i); + if (!entity->name) { + ret = -ENOMEM; + break; + } + + entity->type = MEDIA_ENT_T_DVB_TSOUT; + pads->flags = MEDIA_PAD_FL_SINK; + + ret = media_entity_init(entity, 1, pads); + if (ret < 0) + break; + + ret = media_device_register_entity(dvbdev->adapter->mdev, + entity); + if (ret < 0) + break; + } + + if (!ret) { + dvbdev->tsout_num_entities = npads; + return; + } + + for (i--; i >= 0; i--) { + media_device_unregister_entity(&dvbdev->tsout_entity[i]); + kfree(dvbdev->tsout_entity[i].name); + } + + printk(KERN_ERR + "%s: media_device_register_entity failed for %s\n", + __func__, name); + + kfree(dvbdev->tsout_entity); + kfree(dvbdev->tsout_pads); + dvbdev->tsout_entity = NULL; + dvbdev->tsout_pads = NULL; +#endif +} + +#define DEMUX_TSOUT "demux-tsout" +#define DVR_TSOUT "dvr-tsout" + static void dvb_create_media_entity(struct dvb_device *dvbdev, - int type, int minor) + int type, int demux_sink_pads) { #if defined(CONFIG_MEDIA_CONTROLLER_DVB) - int ret = 0, npads; + int i, ret = 0, npads; switch (type) { case DVB_DEVICE_FRONTEND: npads = 2; break; + case DVB_DEVICE_DVR: + dvb_create_tsout_entity(dvbdev, DVR_TSOUT, demux_sink_pads); + return; case DVB_DEVICE_DEMUX: - npads = 2; + npads = 1 + demux_sink_pads; + dvb_create_tsout_entity(dvbdev, DEMUX_TSOUT, demux_sink_pads); break; case DVB_DEVICE_CA: npads = 2; @@ -215,8 +283,6 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev, if (!dvbdev->entity) return; - dvbdev->entity->info.dev.major = DVB_MAJOR; - dvbdev->entity->info.dev.minor = minor; dvbdev->entity->name = dvbdev->name; if (npads) { @@ -237,7 +303,8 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev, case DVB_DEVICE_DEMUX: dvbdev->entity->type = MEDIA_ENT_T_DVB_DEMUX; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; - dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; + for (i = 1; i < npads; i++) + dvbdev->pads[i].flags = MEDIA_PAD_FL_SOURCE; break; case DVB_DEVICE_CA: dvbdev->entity->type = MEDIA_ENT_T_DVB_CA; @@ -259,8 +326,16 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev, printk(KERN_ERR "%s: media_device_register_entity failed for %s\n", __func__, dvbdev->entity->name); + + media_device_unregister_entity(dvbdev->entity); + for (i = 0; i < dvbdev->tsout_num_entities; i++) { + media_device_unregister_entity(&dvbdev->tsout_entity[i]); + kfree(dvbdev->tsout_entity[i].name); + } kfree(dvbdev->pads); kfree(dvbdev->entity); + kfree(dvbdev->tsout_pads); + kfree(dvbdev->tsout_entity); dvbdev->entity = NULL; return; } @@ -271,7 +346,8 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev, } static void dvb_register_media_device(struct dvb_device *dvbdev, - int type, int minor) + int type, int minor, + unsigned demux_sink_pads) { #if defined(CONFIG_MEDIA_CONTROLLER_DVB) u32 intf_type; @@ -279,7 +355,7 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, if (!dvbdev->adapter->mdev) return; - dvb_create_media_entity(dvbdev, type, minor); + dvb_create_media_entity(dvbdev, type, demux_sink_pads); switch (type) { case DVB_DEVICE_FRONTEND: @@ -323,7 +399,8 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, } int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, - const struct dvb_device *template, void *priv, int type) + const struct dvb_device *template, void *priv, int type, + int demux_sink_pads) { struct dvb_device *dvbdev; struct file_operations *dvbdevfops; @@ -402,7 +479,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", adap->num, dnames[type], id, minor, minor); - dvb_register_media_device(dvbdev, type, minor); + dvb_register_media_device(dvbdev, type, minor, demux_sink_pads); return 0; } @@ -422,9 +499,18 @@ void dvb_unregister_device(struct dvb_device *dvbdev) #if defined(CONFIG_MEDIA_CONTROLLER_DVB) if (dvbdev->entity) { + int i; + media_device_unregister_entity(dvbdev->entity); + for (i = 0; i < dvbdev->tsout_num_entities; i++) { + media_device_unregister_entity(&dvbdev->tsout_entity[i]); + kfree(dvbdev->tsout_entity[i].name); + } + kfree(dvbdev->entity); kfree(dvbdev->pads); + kfree(dvbdev->tsout_entity); + kfree(dvbdev->tsout_pads); } #endif @@ -440,8 +526,10 @@ void dvb_create_media_graph(struct dvb_adapter *adap) { struct media_device *mdev = adap->mdev; struct media_entity *entity, *tuner = NULL, *demod = NULL; - struct media_entity *demux = NULL, *dvr = NULL, *ca = NULL; + struct media_entity *demux = NULL, *ca = NULL; struct media_interface *intf; + unsigned demux_pad = 0; + unsigned dvr_pad = 0; if (!mdev) return; @@ -457,9 +545,6 @@ void dvb_create_media_graph(struct dvb_adapter *adap) case MEDIA_ENT_T_DVB_DEMUX: demux = entity; break; - case MEDIA_ENT_T_DVB_TSOUT: - dvr = entity; - break; case MEDIA_ENT_T_DVB_CA: ca = entity; break; @@ -471,21 +556,46 @@ void dvb_create_media_graph(struct dvb_adapter *adap) if (demod && demux) media_create_pad_link(demod, 1, demux, 0, MEDIA_LNK_FL_ENABLED); - - if (demux && dvr) - media_create_pad_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED); - if (demux && ca) media_create_pad_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED); + /* Create demux links for each ringbuffer/pad */ + if (demux) { + media_device_for_each_entity(entity, mdev) { + if (entity->type == MEDIA_ENT_T_DVB_TSOUT) { + if (!strncmp(entity->name, DVR_TSOUT, + strlen(DVR_TSOUT))) + media_create_pad_link(demux, + ++dvr_pad, + entity, 0, 0); + if (!strncmp(entity->name, DEMUX_TSOUT, + strlen(DEMUX_TSOUT))) + media_create_pad_link(demux, + ++demux_pad, + entity, 0, 0); + } + } + } + /* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */ list_for_each_entry(intf, &mdev->interfaces, list) { if (intf->type == MEDIA_INTF_T_DVB_CA && ca) media_create_intf_link(ca, intf, 0); if (intf->type == MEDIA_INTF_T_DVB_FE && tuner) media_create_intf_link(tuner, intf, 0); + if (intf->type == MEDIA_INTF_T_DVB_DVR && demux) media_create_intf_link(demux, intf, 0); + + media_device_for_each_entity(entity, mdev) { + if (entity->type == MEDIA_ENT_T_DVB_TSOUT) { + if (!strcmp(entity->name, DVR_TSOUT)) + media_create_intf_link(entity, intf, 0); + if (!strcmp(entity->name, DEMUX_TSOUT)) + media_create_intf_link(entity, intf, 0); + break; + } + } } } EXPORT_SYMBOL_GPL(dvb_create_media_graph); diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index 8398c8fb02b03..7af8adbb589b8 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h @@ -148,9 +148,11 @@ struct dvb_device { const char *name; /* Allocated and filled inside dvbdev.c */ - struct media_entity *entity; struct media_intf_devnode *intf_devnode; - struct media_pad *pads; + + unsigned tsout_num_entities; + struct media_entity *entity, *tsout_entity; + struct media_pad *pads, *tsout_pads; #endif void *priv; @@ -193,7 +195,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, const struct dvb_device *template, void *priv, - int type); + int type, + int demux_sink_pads); /** * dvb_unregister_device - Unregisters a DVB device diff --git a/drivers/media/firewire/firedtv-ci.c b/drivers/media/firewire/firedtv-ci.c index e63f582378bff..edbb30fdd9d95 100644 --- a/drivers/media/firewire/firedtv-ci.c +++ b/drivers/media/firewire/firedtv-ci.c @@ -241,7 +241,7 @@ int fdtv_ca_register(struct firedtv *fdtv) return -EFAULT; err = dvb_register_device(&fdtv->adapter, &fdtv->cadev, - &fdtv_ca, fdtv, DVB_DEVICE_CA); + &fdtv_ca, fdtv, DVB_DEVICE_CA, 0); if (stat.ca_application_info == 0) dev_err(fdtv->device, "CaApplicationInfo is not set\n"); diff --git a/drivers/media/pci/bt8xx/dst_ca.c b/drivers/media/pci/bt8xx/dst_ca.c index c5cc14ef8347c..da8b414fd824c 100644 --- a/drivers/media/pci/bt8xx/dst_ca.c +++ b/drivers/media/pci/bt8xx/dst_ca.c @@ -705,7 +705,8 @@ struct dvb_device *dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_ struct dvb_device *dvbdev; dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device"); - if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA) == 0) { + if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, + DVB_DEVICE_CA, 0) == 0) { dst->dst_ca = dvbdev; return dst->dst_ca; } diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index fba5b40a869c5..9d5b314142f1b 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -1065,7 +1065,7 @@ static int ddb_ci_attach(struct ddb_port *port) port->en, 0, 1); ret = dvb_register_device(&port->output->adap, &port->output->dev, &dvbdev_ci, (void *) port->output, - DVB_DEVICE_SEC); + DVB_DEVICE_SEC, 0); return ret; } diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c index 1b92d836a564f..4e924e2d1638f 100644 --- a/drivers/media/pci/ngene/ngene-core.c +++ b/drivers/media/pci/ngene/ngene-core.c @@ -1513,7 +1513,7 @@ static int init_channel(struct ngene_channel *chan) set_transfer(&chan->dev->channel[2], 1); dvb_register_device(adapter, &chan->ci_dev, &ngene_dvbdev_ci, (void *) chan, - DVB_DEVICE_SEC); + DVB_DEVICE_SEC, 0); if (!chan->ci_dev) goto err; } diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c index 5e18b6796ed94..a69dc6a0752bb 100644 --- a/drivers/media/pci/ttpci/av7110.c +++ b/drivers/media/pci/ttpci/av7110.c @@ -1358,7 +1358,7 @@ static int av7110_register(struct av7110 *av7110) #ifdef CONFIG_DVB_AV7110_OSD dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev, - &dvbdev_osd, av7110, DVB_DEVICE_OSD); + &dvbdev_osd, av7110, DVB_DEVICE_OSD, 0); #endif dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx); diff --git a/drivers/media/pci/ttpci/av7110_av.c b/drivers/media/pci/ttpci/av7110_av.c index 6fc748e220173..26c5696c193bf 100644 --- a/drivers/media/pci/ttpci/av7110_av.c +++ b/drivers/media/pci/ttpci/av7110_av.c @@ -1594,10 +1594,10 @@ int av7110_av_register(struct av7110 *av7110) memset(&av7110->video_size, 0, sizeof (video_size_t)); dvb_register_device(&av7110->dvb_adapter, &av7110->video_dev, - &dvbdev_video, av7110, DVB_DEVICE_VIDEO); + &dvbdev_video, av7110, DVB_DEVICE_VIDEO, 0); dvb_register_device(&av7110->dvb_adapter, &av7110->audio_dev, - &dvbdev_audio, av7110, DVB_DEVICE_AUDIO); + &dvbdev_audio, av7110, DVB_DEVICE_AUDIO, 0); return 0; } diff --git a/drivers/media/pci/ttpci/av7110_ca.c b/drivers/media/pci/ttpci/av7110_ca.c index bc4c65ffd4b98..96a130fb45957 100644 --- a/drivers/media/pci/ttpci/av7110_ca.c +++ b/drivers/media/pci/ttpci/av7110_ca.c @@ -378,7 +378,7 @@ static struct dvb_device dvbdev_ca = { int av7110_ca_register(struct av7110 *av7110) { return dvb_register_device(&av7110->dvb_adapter, &av7110->ca_dev, - &dvbdev_ca, av7110, DVB_DEVICE_CA); + &dvbdev_ca, av7110, DVB_DEVICE_CA, 0); } void av7110_ca_unregister(struct av7110 *av7110) -- GitLab From 6c24d4602ebee64128f29944d776c19d4d53fb54 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 21 Aug 2015 18:26:42 -0300 Subject: [PATCH 2489/2855] [media] media: report if a pad is sink or source at debug msg Sometimes, it is important to see if the created pad is sink or source. Add info to track that. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 8449274bb50c9..5697735be433e 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -109,8 +109,11 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) struct media_pad *pad = gobj_to_pad(gobj); dev_dbg(gobj->mdev->dev, - "%s: id 0x%08x pad#%d: '%s':%d\n", - event_name, gobj->id, media_localid(gobj), + "%s: id 0x%08x %s%spad#%d: '%s':%d\n", + event_name, gobj->id, + pad->flags & MEDIA_PAD_FL_SINK ? " sink " : "", + pad->flags & MEDIA_PAD_FL_SOURCE ? "source " : "", + media_localid(gobj), pad->entity->name, pad->index); break; } -- GitLab From c398bb6441949bd1f2acf5072116ecba143df03b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 23 Aug 2015 08:28:21 -0300 Subject: [PATCH 2490/2855] [media] uapi/media.h: Add MEDIA_IOC_G_TOPOLOGY ioctl Add a new ioctl that will report the entire topology on one go. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 2 + include/uapi/linux/media.h | 88 +++++++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 5171e3c1c71a5..dbc4da450fc20 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -181,6 +181,8 @@ struct media_interface { */ struct media_intf_devnode { struct media_interface intf; + + /* Should match the fields at media_v2_intf_devnode */ u32 major; u32 minor; }; diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 3c4080106df8b..72ac39de38225 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -206,6 +206,10 @@ struct media_pad_desc { #define MEDIA_LNK_FL_IMMUTABLE (1 << 1) #define MEDIA_LNK_FL_DYNAMIC (1 << 2) +#define MEDIA_LNK_FL_LINK_TYPE (0xf << 28) +# define MEDIA_LNK_FL_DATA_LINK (0 << 28) +# define MEDIA_LNK_FL_INTERFACE_LINK (1 << 28) + struct media_link_desc { struct media_pad_desc source; struct media_pad_desc sink; @@ -241,11 +245,93 @@ struct media_links_enum { #define MEDIA_INTF_T_V4L_SUBDEV (MEDIA_INTF_T_V4L_BASE + 3) #define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4) -/* TBD: declare the structs needed for the new G_TOPOLOGY ioctl */ +/* + * MC next gen API definitions + * + * NOTE: The declarations below are close to the MC RFC for the Media + * Controller, the next generation. Yet, there are a few adjustments + * to do, as we want to be able to have a functional API before + * the MC properties change. Those will be properly marked below. + * Please also notice that I removed "num_pads", "num_links", + * from the proposal, as a proper userspace application will likely + * use lists for pads/links, just as we intend to do in Kernelspace. + * The API definition should be freed from fields that are bound to + * some specific data structure. + * + * FIXME: Currently, I opted to name the new types as "media_v2", as this + * won't cause any conflict with the Kernelspace namespace, nor with + * the previous kAPI media_*_desc namespace. This can be changed + * later, before the adding this API upstream. + */ + + +struct media_v2_entity { + __u32 id; + char name[64]; /* FIXME: move to a property? (RFC says so) */ + __u16 reserved[14]; +}; + +/* Should match the specific fields at media_intf_devnode */ +struct media_v2_intf_devnode { + __u32 major; + __u32 minor; +}; + +struct media_v2_interface { + __u32 id; + __u32 intf_type; + __u32 flags; + __u32 reserved[9]; + + union { + struct media_v2_intf_devnode devnode; + __u32 raw[16]; + }; +}; + +struct media_v2_pad { + __u32 id; + __u32 entity_id; + __u32 flags; + __u16 reserved[9]; +}; + +struct media_v2_link { + __u32 id; + __u32 source_id; + __u32 sink_id; + __u32 flags; + __u32 reserved[5]; +}; + +struct media_v2_topology { + __u32 topology_version; + + __u32 num_entities; + struct media_v2_entity *entities; + + __u32 num_interfaces; + struct media_v2_interface *interfaces; + + __u32 num_pads; + struct media_v2_pad *pads; + + __u32 num_links; + struct media_v2_link *links; + + struct { + __u32 reserved_num; + void *reserved_ptr; + } reserved_types[16]; + __u32 reserved[8]; +}; + +/* ioctls */ #define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info) #define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc) #define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum) #define MEDIA_IOC_SETUP_LINK _IOWR('|', 0x03, struct media_link_desc) +#define MEDIA_IOC_G_TOPOLOGY _IOWR('|', 0x04, struct media_v2_topology) #endif /* __LINUX_MEDIA_H */ -- GitLab From cf975a4b40ec9a947dae614b23128f3984a2d324 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 23 Aug 2015 07:51:22 -0300 Subject: [PATCH 2491/2855] [media] media: Use a macro to interate between all interfaces Just like we do with entities, use a similar macro for the interfaces loop. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 3 ++- include/media/media-device.h | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 6babc688801bb..f00f1a5f279cf 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -578,9 +578,10 @@ void dvb_create_media_graph(struct dvb_adapter *adap) } /* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */ - list_for_each_entry(intf, &mdev->interfaces, list) { + media_device_for_each_intf(intf, mdev) { if (intf->type == MEDIA_INTF_T_DVB_CA && ca) media_create_intf_link(ca, intf, 0); + if (intf->type == MEDIA_INTF_T_DVB_FE && tuner) media_create_intf_link(tuner, intf, 0); diff --git a/include/media/media-device.h b/include/media/media-device.h index 51807efa505b5..f23d686aaac60 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -113,6 +113,11 @@ struct media_device *media_device_find_devres(struct device *dev); #define media_device_for_each_entity(entity, mdev) \ list_for_each_entry(entity, &(mdev)->entities, list) +/* Iterate over all interfaces. */ +#define media_device_for_each_intf(intf, mdev) \ + list_for_each_entry(intf, &(mdev)->interfaces, list) + + #else static inline int media_device_register(struct media_device *mdev) { -- GitLab From 05bfa9fa1cda91953e1b5975b059542b83c5245c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 23 Aug 2015 07:51:33 -0300 Subject: [PATCH 2492/2855] [media] media: move mdev list init to gobj Let's control the topology changes inside the graph_object. So, move the addition and removal of interfaces/entities from the mdev lists to media_gobj_init() and media_gobj_remove(). The main reason is that mdev should have lists for all object types, as the new MC api will require to store objects in separate places. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 4 +--- drivers/media/media-entity.c | 15 ++++++++++++--- include/media/media-device.h | 4 ++-- include/media/media-entity.h | 3 +-- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 134fe75101950..ec98595b8a7ad 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -415,7 +415,7 @@ void media_device_unregister(struct media_device *mdev) struct media_entity *entity; struct media_entity *next; - list_for_each_entry_safe(entity, next, &mdev->entities, list) + list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list) media_device_unregister_entity(entity); device_remove_file(&mdev->devnode.dev, &dev_attr_model); @@ -449,7 +449,6 @@ int __must_check media_device_register_entity(struct media_device *mdev, spin_lock(&mdev->lock); /* Initialize media_gobj embedded at the entity */ media_gobj_init(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); - list_add_tail(&entity->list, &mdev->entities); /* Initialize objects at the pads */ for (i = 0; i < entity->num_pads; i++) @@ -487,7 +486,6 @@ void media_device_unregister_entity(struct media_entity *entity) for (i = 0; i < entity->num_pads; i++) media_gobj_remove(&entity->pads[i].graph_obj); media_gobj_remove(&entity->graph_obj); - list_del(&entity->list); spin_unlock(&mdev->lock); entity->graph_obj.mdev = NULL; } diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 5697735be433e..b3875b0185c1e 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -158,6 +158,7 @@ void media_gobj_init(struct media_device *mdev, switch (type) { case MEDIA_GRAPH_ENTITY: gobj->id = media_gobj_gen_id(type, ++mdev->entity_id); + list_add_tail(&gobj->list, &mdev->entities); break; case MEDIA_GRAPH_PAD: gobj->id = media_gobj_gen_id(type, ++mdev->pad_id); @@ -166,6 +167,7 @@ void media_gobj_init(struct media_device *mdev, gobj->id = media_gobj_gen_id(type, ++mdev->link_id); break; case MEDIA_GRAPH_INTF_DEVNODE: + list_add_tail(&gobj->list, &mdev->interfaces); gobj->id = media_gobj_gen_id(type, ++mdev->intf_devnode_id); break; } @@ -181,6 +183,16 @@ void media_gobj_init(struct media_device *mdev, */ void media_gobj_remove(struct media_gobj *gobj) { + /* Remove the object from mdev list */ + switch (media_type(gobj)) { + case MEDIA_GRAPH_ENTITY: + case MEDIA_GRAPH_INTF_DEVNODE: + list_del(&gobj->list); + break; + default: + break; + } + dev_dbg_obj(__func__, gobj); } @@ -852,8 +864,6 @@ static void media_interface_init(struct media_device *mdev, INIT_LIST_HEAD(&intf->links); media_gobj_init(mdev, gobj_type, &intf->graph_obj); - - list_add_tail(&intf->list, &mdev->interfaces); } /* Functions related to the media interface via device nodes */ @@ -882,7 +892,6 @@ EXPORT_SYMBOL_GPL(media_devnode_create); void media_devnode_remove(struct media_intf_devnode *devnode) { media_gobj_remove(&devnode->intf.graph_obj); - list_del(&devnode->intf.list); kfree(devnode); } EXPORT_SYMBOL_GPL(media_devnode_remove); diff --git a/include/media/media-device.h b/include/media/media-device.h index f23d686aaac60..85fa302047bd4 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -111,11 +111,11 @@ struct media_device *media_device_find_devres(struct device *dev); /* Iterate over all entities. */ #define media_device_for_each_entity(entity, mdev) \ - list_for_each_entry(entity, &(mdev)->entities, list) + list_for_each_entry(entity, &(mdev)->entities, graph_obj.list) /* Iterate over all interfaces. */ #define media_device_for_each_intf(intf, mdev) \ - list_for_each_entry(intf, &(mdev)->interfaces, list) + list_for_each_entry(intf, &(mdev)->interfaces, graph_obj.list) #else diff --git a/include/media/media-entity.h b/include/media/media-entity.h index dbc4da450fc20..f9058601440a2 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -66,6 +66,7 @@ enum media_gobj_type { struct media_gobj { struct media_device *mdev; u32 id; + struct list_head list; }; @@ -114,7 +115,6 @@ struct media_entity_operations { struct media_entity { struct media_gobj graph_obj; /* must be first field in struct */ - struct list_head list; const char *name; /* Entity name */ u32 type; /* Entity type (MEDIA_ENT_T_*) */ u32 revision; /* Entity revision, driver specific */ @@ -166,7 +166,6 @@ struct media_entity { */ struct media_interface { struct media_gobj graph_obj; - struct list_head list; struct list_head links; u32 type; u32 flags; -- GitLab From 9155d859b6bec29cdbbd80a509be35de55115f00 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 23 Aug 2015 08:00:33 -0300 Subject: [PATCH 2493/2855] [media] media-device: add pads and links to media_device The MC next gen API sends objects to userspace grouped by their types. In the case of pads and links, in order to improve performance and have a simpler code, the best is to store them also on separate linked lists at MC. If we don't do that, we would need this kind of interaction to send data to userspace (code is in structured english): for each entity: for each pad: store pads for each entity: for each link: store link for each interface: for each link: store link With would require one nested loop for pads and two nested loops for links. By using separate linked lists for them, just one loop would be enough. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 2 ++ drivers/media/media-entity.c | 17 ++++++----------- include/media/media-device.h | 12 ++++++++++++ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index ec98595b8a7ad..5b2c9f7fcd459 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -382,6 +382,8 @@ int __must_check __media_device_register(struct media_device *mdev, INIT_LIST_HEAD(&mdev->entities); INIT_LIST_HEAD(&mdev->interfaces); + INIT_LIST_HEAD(&mdev->pads); + INIT_LIST_HEAD(&mdev->links); spin_lock_init(&mdev->lock); mutex_init(&mdev->graph_mutex); diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index b3875b0185c1e..2f3d3aae20a72 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -162,13 +162,15 @@ void media_gobj_init(struct media_device *mdev, break; case MEDIA_GRAPH_PAD: gobj->id = media_gobj_gen_id(type, ++mdev->pad_id); + list_add_tail(&gobj->list, &mdev->pads); break; case MEDIA_GRAPH_LINK: gobj->id = media_gobj_gen_id(type, ++mdev->link_id); + list_add_tail(&gobj->list, &mdev->links); break; case MEDIA_GRAPH_INTF_DEVNODE: - list_add_tail(&gobj->list, &mdev->interfaces); gobj->id = media_gobj_gen_id(type, ++mdev->intf_devnode_id); + list_add_tail(&gobj->list, &mdev->interfaces); break; } dev_dbg_obj(__func__, gobj); @@ -183,17 +185,10 @@ void media_gobj_init(struct media_device *mdev, */ void media_gobj_remove(struct media_gobj *gobj) { - /* Remove the object from mdev list */ - switch (media_type(gobj)) { - case MEDIA_GRAPH_ENTITY: - case MEDIA_GRAPH_INTF_DEVNODE: - list_del(&gobj->list); - break; - default: - break; - } - dev_dbg_obj(__func__, gobj); + + /* Remove the object from mdev list */ + list_del(&gobj->list); } /** diff --git a/include/media/media-device.h b/include/media/media-device.h index 85fa302047bd4..0d1b9c6874544 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -47,6 +47,8 @@ struct device; * @intf_devnode_id: Unique ID used on the last interface devnode registered * @entities: List of registered entities * @interfaces: List of registered interfaces + * @pads: List of registered pads + * @links: List of registered links * @lock: Entities list lock * @graph_mutex: Entities graph operation lock * @link_notify: Link state change notification callback @@ -79,6 +81,8 @@ struct media_device { struct list_head entities; struct list_head interfaces; + struct list_head pads; + struct list_head links; /* Protects the entities list */ spinlock_t lock; @@ -117,6 +121,14 @@ struct media_device *media_device_find_devres(struct device *dev); #define media_device_for_each_intf(intf, mdev) \ list_for_each_entry(intf, &(mdev)->interfaces, graph_obj.list) +/* Iterate over all pads. */ +#define media_device_for_each_pad(pad, mdev) \ + list_for_each_entry(pad, &(mdev)->pads, graph_obj.list) + +/* Iterate over all links. */ +#define media_device_for_each_link(link, mdev) \ + list_for_each_entry(link, &(mdev)->links, graph_obj.list) + #else static inline int media_device_register(struct media_device *mdev) -- GitLab From 2521fdac28d0ceea659be1620fef96b1cbff09b6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 23 Aug 2015 09:40:26 -0300 Subject: [PATCH 2494/2855] [media] media_device: add a topology version field Every time a graph object is added or removed, the version of the topology changes. That's a requirement for the new MEDIA_IOC_G_TOPOLOGY, in order to allow userspace to know that the topology has changed after a previous call to it. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 5 +++++ include/media/media-device.h | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 2f3d3aae20a72..1b2fd724cdbfa 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -173,6 +173,9 @@ void media_gobj_init(struct media_device *mdev, list_add_tail(&gobj->list, &mdev->interfaces); break; } + + mdev->topology_version++; + dev_dbg_obj(__func__, gobj); } @@ -187,6 +190,8 @@ void media_gobj_remove(struct media_gobj *gobj) { dev_dbg_obj(__func__, gobj); + gobj->mdev->topology_version++; + /* Remove the object from mdev list */ list_del(&gobj->list); } diff --git a/include/media/media-device.h b/include/media/media-device.h index 0d1b9c6874544..1b12774a9ab42 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -41,6 +41,8 @@ struct device; * @bus_info: Unique and stable device location identifier * @hw_revision: Hardware device revision * @driver_version: Device driver version + * @topology_version: Monotonic counter for storing the version of the graph + * topology. Should be incremented each time the topology changes. * @entity_id: Unique ID used on the last entity registered * @pad_id: Unique ID used on the last pad registered * @link_id: Unique ID used on the last link registered @@ -74,6 +76,8 @@ struct media_device { u32 hw_revision; u32 driver_version; + u32 topology_version; + u32 entity_id; u32 pad_id; u32 link_id; -- GitLab From 8309f47c32c04aae30698389073ec8c6d1b7e986 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 23 Aug 2015 10:36:41 -0300 Subject: [PATCH 2495/2855] [media] media-device: add support for MEDIA_IOC_G_TOPOLOGY ioctl Add support for the new MEDIA_IOC_G_TOPOLOGY ioctl, according with the RFC for the MC next generation. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 158 +++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 5b2c9f7fcd459..96a476eeb16ec 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -232,6 +232,156 @@ static long media_device_setup_link(struct media_device *mdev, return ret; } +static long __media_device_get_topology(struct media_device *mdev, + struct media_v2_topology *topo) +{ + struct media_entity *entity; + struct media_interface *intf; + struct media_pad *pad; + struct media_link *link; + struct media_v2_entity uentity; + struct media_v2_interface uintf; + struct media_v2_pad upad; + struct media_v2_link ulink; + int ret = 0, i; + + topo->topology_version = mdev->topology_version; + + /* Get entities and number of entities */ + i = 0; + media_device_for_each_entity(entity, mdev) { + i++; + + if (ret || !topo->entities) + continue; + + if (i > topo->num_entities) { + ret = -ENOSPC; + continue; + } + + /* Copy fields to userspace struct if not error */ + memset(&uentity, 0, sizeof(uentity)); + uentity.id = entity->graph_obj.id; + strncpy(uentity.name, entity->name, + sizeof(uentity.name)); + + if (copy_to_user(&topo->entities[i - 1], &uentity, sizeof(uentity))) + ret = -EFAULT; + } + topo->num_entities = i; + + /* Get interfaces and number of interfaces */ + i = 0; + media_device_for_each_intf(intf, mdev) { + i++; + + if (ret || !topo->interfaces) + continue; + + if (i > topo->num_interfaces) { + ret = -ENOSPC; + continue; + } + + memset(&uintf, 0, sizeof(uintf)); + + /* Copy intf fields to userspace struct */ + uintf.id = intf->graph_obj.id; + uintf.intf_type = intf->type; + uintf.flags = intf->flags; + + if (media_type(&intf->graph_obj) == MEDIA_GRAPH_INTF_DEVNODE) { + struct media_intf_devnode *devnode; + + devnode = intf_to_devnode(intf); + + uintf.devnode.major = devnode->major; + uintf.devnode.minor = devnode->minor; + } + + if (copy_to_user(&topo->interfaces[i - 1], &uintf, sizeof(uintf))) + ret = -EFAULT; + } + topo->num_interfaces = i; + + /* Get pads and number of pads */ + i = 0; + media_device_for_each_pad(pad, mdev) { + i++; + + if (ret || !topo->pads) + continue; + + if (i > topo->num_pads) { + ret = -ENOSPC; + continue; + } + + memset(&upad, 0, sizeof(upad)); + + /* Copy pad fields to userspace struct */ + upad.id = pad->graph_obj.id; + upad.entity_id = pad->entity->graph_obj.id; + upad.flags = pad->flags; + + if (copy_to_user(&topo->pads[i - 1], &upad, sizeof(upad))) + ret = -EFAULT; + } + topo->num_pads = i; + + /* Get links and number of links */ + i = 0; + media_device_for_each_link(link, mdev) { + i++; + + if (ret || !topo->links) + continue; + + if (i > topo->num_links) { + ret = -ENOSPC; + continue; + } + + memset(&ulink, 0, sizeof(ulink)); + + /* Copy link fields to userspace struct */ + ulink.id = link->graph_obj.id; + ulink.source_id = link->gobj0->id; + ulink.sink_id = link->gobj1->id; + ulink.flags = link->flags; + + if (media_type(link->gobj0) != MEDIA_GRAPH_PAD) + ulink.flags |= MEDIA_LNK_FL_INTERFACE_LINK; + + if (copy_to_user(&topo->links[i - 1], &ulink, sizeof(ulink))) + ret = -EFAULT; + } + topo->num_links = i; + + return ret; +} + +static long media_device_get_topology(struct media_device *mdev, + struct media_v2_topology __user *utopo) +{ + struct media_v2_topology ktopo; + int ret; + + ret = copy_from_user(&ktopo, utopo, sizeof(ktopo)); + + if (ret < 0) + return ret; + + ret = __media_device_get_topology(mdev, &ktopo); + if (ret < 0) + return ret; + + ret = copy_to_user(utopo, &ktopo, sizeof(*utopo)); + + return ret; +} + static long media_device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -264,6 +414,13 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd, mutex_unlock(&dev->graph_mutex); break; + case MEDIA_IOC_G_TOPOLOGY: + mutex_lock(&dev->graph_mutex); + ret = media_device_get_topology(dev, + (struct media_v2_topology __user *)arg); + mutex_unlock(&dev->graph_mutex); + break; + default: ret = -ENOIOCTLCMD; } @@ -312,6 +469,7 @@ static long media_device_compat_ioctl(struct file *filp, unsigned int cmd, case MEDIA_IOC_DEVICE_INFO: case MEDIA_IOC_ENUM_ENTITIES: case MEDIA_IOC_SETUP_LINK: + case MEDIA_IOC_G_TOPOLOGY: return media_device_ioctl(filp, cmd, arg); case MEDIA_IOC_ENUM_LINKS32: -- GitLab From 7c4696a910d404eda3477e76a35c155a6b83ca3e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 24 Aug 2015 08:46:46 -0300 Subject: [PATCH 2496/2855] [media] media-entity: unregister entity links Add functions to explicitly unregister all entity links. This function is called automatically when an entity link is destroyed. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 23 +++++++++++++++++++++++ include/media/media-entity.h | 3 +++ 2 files changed, 26 insertions(+) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 1b2fd724cdbfa..ceae708bdad49 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -891,6 +891,7 @@ EXPORT_SYMBOL_GPL(media_devnode_create); void media_devnode_remove(struct media_intf_devnode *devnode) { + media_remove_intf_links(&devnode->intf); media_gobj_remove(&devnode->intf.graph_obj); kfree(devnode); } @@ -932,3 +933,25 @@ void media_remove_intf_link(struct media_link *link) mutex_unlock(&link->graph_obj.mdev->graph_mutex); } EXPORT_SYMBOL_GPL(media_remove_intf_link); + +void __media_remove_intf_links(struct media_interface *intf) +{ + struct media_link *link, *tmp; + + list_for_each_entry_safe(link, tmp, &intf->links, list) + __media_remove_intf_link(link); + +} +EXPORT_SYMBOL_GPL(__media_remove_intf_links); + +void media_remove_intf_links(struct media_interface *intf) +{ + /* Do nothing if the intf is not registered. */ + if (intf->graph_obj.mdev == NULL) + return; + + mutex_lock(&intf->graph_obj.mdev->graph_mutex); + __media_remove_intf_links(intf); + mutex_unlock(&intf->graph_obj.mdev->graph_mutex); +} +EXPORT_SYMBOL_GPL(media_remove_intf_links); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index f9058601440a2..0753f3029d063 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -326,6 +326,9 @@ struct media_link *media_create_intf_link(struct media_entity *entity, struct media_interface *intf, u32 flags); void media_remove_intf_link(struct media_link *link); +void __media_remove_intf_links(struct media_interface *intf); +void media_remove_intf_links(struct media_interface *intf); + #define media_entity_call(entity, operation, args...) \ (((entity)->ops && (entity)->ops->operation) ? \ -- GitLab From a28971ad141bf41b8d6c24f8c4e8736be0c57677 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 29 Aug 2015 19:07:09 -0300 Subject: [PATCH 2497/2855] [media] remove interface links at media_entity_unregister() Interface links connected to an entity should be removed before the entity itself can be removed. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 96a476eeb16ec..7c37aeab05bbd 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -638,14 +638,30 @@ void media_device_unregister_entity(struct media_entity *entity) return; spin_lock(&mdev->lock); + + /* Remove interface links with this entity on it */ + list_for_each_entry_safe(link, tmp, &mdev->links, graph_obj.list) { + if (media_type(link->gobj1) == MEDIA_GRAPH_ENTITY + && link->entity == entity) { + media_gobj_remove(&link->graph_obj); + kfree(link); + } + } + + /* Remove all data links that belong to this entity */ list_for_each_entry_safe(link, tmp, &entity->links, list) { media_gobj_remove(&link->graph_obj); list_del(&link->list); kfree(link); } + + /* Remove all pads that belong to this entity */ for (i = 0; i < entity->num_pads; i++) media_gobj_remove(&entity->pads[i].graph_obj); + + /* Remove the entity */ media_gobj_remove(&entity->graph_obj); + spin_unlock(&mdev->lock); entity->graph_obj.mdev = NULL; } -- GitLab From d47109fa45ee2dc4e0b2710a8225e6c3ac7ea9fd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 29 Aug 2015 21:23:44 -0300 Subject: [PATCH 2498/2855] [media] media-device: remove interfaces and interface links Just like what's done with entities, when the media controller is unregistered, release any interface and interface links that might still be there. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 30 +++++++++++++++++++----------- drivers/media/media-entity.c | 6 +++++- include/media/media-entity.h | 1 + 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 7c37aeab05bbd..96700843b1e4f 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -574,6 +574,17 @@ void media_device_unregister(struct media_device *mdev) { struct media_entity *entity; struct media_entity *next; + struct media_interface *intf, *tmp_intf; + + /* Remove all interfaces from the media device */ + spin_lock(&mdev->lock); + list_for_each_entry_safe(intf, tmp_intf, &mdev->interfaces, + graph_obj.list) { + __media_remove_intf_links(intf); + media_gobj_remove(&intf->graph_obj); + kfree(intf); + } + spin_unlock(&mdev->lock); list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list) media_device_unregister_entity(entity); @@ -633,27 +644,24 @@ void media_device_unregister_entity(struct media_entity *entity) int i; struct media_device *mdev = entity->graph_obj.mdev; struct media_link *link, *tmp; + struct media_interface *intf; if (mdev == NULL) return; spin_lock(&mdev->lock); - /* Remove interface links with this entity on it */ - list_for_each_entry_safe(link, tmp, &mdev->links, graph_obj.list) { - if (media_type(link->gobj1) == MEDIA_GRAPH_ENTITY - && link->entity == entity) { - media_gobj_remove(&link->graph_obj); - kfree(link); + /* Remove all interface links pointing to this entity */ + list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) { + list_for_each_entry_safe(link, tmp, &intf->links, list) { + if (media_type(link->gobj1) == MEDIA_GRAPH_ENTITY + && link->entity == entity) + __media_remove_intf_link(link); } } /* Remove all data links that belong to this entity */ - list_for_each_entry_safe(link, tmp, &entity->links, list) { - media_gobj_remove(&link->graph_obj); - list_del(&link->list); - kfree(link); - } + __media_entity_remove_links(entity); /* Remove all pads that belong to this entity */ for (i = 0; i < entity->num_pads; i++) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index ceae708bdad49..ee0f813649608 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -674,9 +674,11 @@ static void __media_entity_remove_link(struct media_entity *entity, /* Remove the remote link */ list_del(&rlink->list); + media_gobj_remove(&rlink->graph_obj); kfree(rlink); } list_del(&link->list); + media_gobj_remove(&link->graph_obj); kfree(link); } @@ -920,11 +922,13 @@ struct media_link *media_create_intf_link(struct media_entity *entity, EXPORT_SYMBOL_GPL(media_create_intf_link); -static void __media_remove_intf_link(struct media_link *link) +void __media_remove_intf_link(struct media_link *link) { + list_del(&link->list); media_gobj_remove(&link->graph_obj); kfree(link); } +EXPORT_SYMBOL_GPL(__media_remove_intf_link); void media_remove_intf_link(struct media_link *link) { diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 0753f3029d063..f165d303f03c8 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -325,6 +325,7 @@ void media_devnode_remove(struct media_intf_devnode *devnode); struct media_link *media_create_intf_link(struct media_entity *entity, struct media_interface *intf, u32 flags); +void __media_remove_intf_link(struct media_link *link); void media_remove_intf_link(struct media_link *link); void __media_remove_intf_links(struct media_interface *intf); void media_remove_intf_links(struct media_interface *intf); -- GitLab From a08fad1ec80c69c79b3ffb6d84968b0952d32da1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 9 Dec 2015 19:47:35 -0200 Subject: [PATCH 2499/2855] [media] media-entity: protect object creation/removal using spin lock Some parts of the media controller are using mutexes while others are using spin locks in order to protect creation and removal of elements in the graph. That's wrong! Also, the V4L2 core can remove graph elements on non-interactive context: BUG: sleeping function called from invalid context at include/linux/sched.h:2776 Fix it by always using spin locks for graph element addition/removal, just like entity creation/removal is protected at media-device.c Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 16 ++++++++-------- include/media/media-device.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index ee0f813649608..b1390d843909b 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -700,9 +700,9 @@ void media_entity_remove_links(struct media_entity *entity) if (entity->graph_obj.mdev == NULL) return; - mutex_lock(&entity->graph_obj.mdev->graph_mutex); + spin_lock(&entity->graph_obj.mdev->lock); __media_entity_remove_links(entity); - mutex_unlock(&entity->graph_obj.mdev->graph_mutex); + spin_unlock(&entity->graph_obj.mdev->lock); } EXPORT_SYMBOL_GPL(media_entity_remove_links); @@ -792,9 +792,9 @@ int media_entity_setup_link(struct media_link *link, u32 flags) { int ret; - mutex_lock(&link->source->entity->graph_obj.mdev->graph_mutex); + spin_lock(&link->source->entity->graph_obj.mdev->lock); ret = __media_entity_setup_link(link, flags); - mutex_unlock(&link->source->entity->graph_obj.mdev->graph_mutex); + spin_unlock(&link->source->entity->graph_obj.mdev->lock); return ret; } @@ -932,9 +932,9 @@ EXPORT_SYMBOL_GPL(__media_remove_intf_link); void media_remove_intf_link(struct media_link *link) { - mutex_lock(&link->graph_obj.mdev->graph_mutex); + spin_lock(&link->graph_obj.mdev->lock); __media_remove_intf_link(link); - mutex_unlock(&link->graph_obj.mdev->graph_mutex); + spin_unlock(&link->graph_obj.mdev->lock); } EXPORT_SYMBOL_GPL(media_remove_intf_link); @@ -954,8 +954,8 @@ void media_remove_intf_links(struct media_interface *intf) if (intf->graph_obj.mdev == NULL) return; - mutex_lock(&intf->graph_obj.mdev->graph_mutex); + spin_lock(&intf->graph_obj.mdev->lock); __media_remove_intf_links(intf); - mutex_unlock(&intf->graph_obj.mdev->graph_mutex); + spin_unlock(&intf->graph_obj.mdev->lock); } EXPORT_SYMBOL_GPL(media_remove_intf_links); diff --git a/include/media/media-device.h b/include/media/media-device.h index 1b12774a9ab42..87ff299e1265d 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -88,7 +88,7 @@ struct media_device { struct list_head pads; struct list_head links; - /* Protects the entities list */ + /* Protects the graph objects creation/removal */ spinlock_t lock; /* Serializes graph operations. */ struct mutex graph_mutex; -- GitLab From 188d2d551244f4196b616c90f3411732a6ebb2ab Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 31 Aug 2015 13:23:03 -0300 Subject: [PATCH 2500/2855] [media] tuner-core: add an input pad Tuners actually have at least one connector on its input. Add a PAD to connect it. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 5 ++++- drivers/media/usb/au0828/au0828-core.c | 5 ++++- drivers/media/usb/cx231xx/cx231xx-cards.c | 2 +- drivers/media/v4l2-core/tuner-core.c | 8 +++++--- include/media/tuner.h | 8 ++++++++ 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index f00f1a5f279cf..a8e7e2398f7a5 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -34,6 +34,9 @@ #include #include "dvbdev.h" +/* Due to enum tuner_pad_index */ +#include + static DEFINE_MUTEX(dvbdev_mutex); static int dvbdev_debug; @@ -552,7 +555,7 @@ void dvb_create_media_graph(struct dvb_adapter *adap) } if (tuner && demod) - media_create_pad_link(tuner, 0, demod, 0, 0); + media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, demod, 0, 0); if (demod && demux) media_create_pad_link(demod, 1, demux, 0, MEDIA_LNK_FL_ENABLED); diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 7f645bcb74639..ee20f4354ba26 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -27,6 +27,9 @@ #include #include +/* Due to enum tuner_pad_index */ +#include + /* * 1 = General debug messages * 2 = USB handling @@ -260,7 +263,7 @@ static void au0828_create_media_graph(struct au0828_dev *dev) return; if (tuner) - media_create_pad_link(tuner, 0, decoder, 0, + media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0, MEDIA_LNK_FL_ENABLED); media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, MEDIA_LNK_FL_ENABLED); diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 695f0c092c794..29cf0c268b190 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1264,7 +1264,7 @@ static void cx231xx_create_media_graph(struct cx231xx *dev) return; if (tuner) - media_create_pad_link(tuner, 0, decoder, 0, + media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0, MEDIA_LNK_FL_ENABLED); media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, MEDIA_LNK_FL_ENABLED); diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index 100b8f0696409..b90f2a52db963 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -134,8 +134,9 @@ struct tuner { unsigned int type; /* chip type id */ void *config; const char *name; + #if defined(CONFIG_MEDIA_CONTROLLER) - struct media_pad pad; + struct media_pad pad[TUNER_NUM_PADS]; #endif }; @@ -695,11 +696,12 @@ static int tuner_probe(struct i2c_client *client, /* Should be just before return */ register_client: #if defined(CONFIG_MEDIA_CONTROLLER) - t->pad.flags = MEDIA_PAD_FL_SOURCE; + t->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK; + t->pad[TUNER_PAD_IF_OUTPUT].flags = MEDIA_PAD_FL_SOURCE; t->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_TUNER; t->sd.entity.name = t->name; - ret = media_entity_init(&t->sd.entity, 1, &t->pad); + ret = media_entity_init(&t->sd.entity, TUNER_NUM_PADS, &t->pad[0]); if (ret < 0) { tuner_err("failed to initialize media entity!\n"); kfree(t); diff --git a/include/media/tuner.h b/include/media/tuner.h index 486b6a54363b1..e5321fda54893 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -21,6 +21,14 @@ #include +/* Tuner PADs */ +/* FIXME: is this the right place for it? */ +enum tuner_pad_index { + TUNER_PAD_RF_INPUT, + TUNER_PAD_IF_OUTPUT, + TUNER_NUM_PADS +}; + #define ADDR_UNSET (255) #define TUNER_TEMIC_PAL 0 /* 4002 FH5 (3X 7756, 9483) */ -- GitLab From 04bf12c2d313478a3e5c9ff59a7ba92ce418bee6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 10 Dec 2015 09:16:34 -0200 Subject: [PATCH 2501/2855] [media] dvbdev: enable all interface links at init Interface links are normally enabled, meaning that the interfaces are bound to the entities. So, any ioctl sent to the interface are reflected at the entities managed by the interface. However, when a device is in use, other interfaces for the same hardware could be decoupled from the entities linked to them, because the hardware may have some parts busy. That's for example, what happens when an hybrid TV device is in use. If it is streaming analog TV or capturing signals from S-Video/Composite connectors, typically the digital part of the hardware can't be used and vice-versa. This is generally due to some internal hardware or firmware limitation, that it is not easily mapped via data pipelines. What the Kernel drivers do internally is that they decouple the hardware from the interface. So, all changes, if allowed, are done only at some interface cache, but not physically changed at the hardware. The usage is similar to the usage of the MEDIA_LNK_FL_ENABLED on data links. So, let's use the same flag to indicate if either the interface to entity link is bound/enabled or not. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index a8e7e2398f7a5..5c4fb41060b49 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -396,7 +396,8 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, if (!dvbdev->entity || !dvbdev->intf_devnode) return; - media_create_intf_link(dvbdev->entity, &dvbdev->intf_devnode->intf, 0); + media_create_intf_link(dvbdev->entity, &dvbdev->intf_devnode->intf, + MEDIA_LNK_FL_ENABLED); #endif } @@ -583,20 +584,24 @@ void dvb_create_media_graph(struct dvb_adapter *adap) /* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */ media_device_for_each_intf(intf, mdev) { if (intf->type == MEDIA_INTF_T_DVB_CA && ca) - media_create_intf_link(ca, intf, 0); + media_create_intf_link(ca, intf, MEDIA_LNK_FL_ENABLED); if (intf->type == MEDIA_INTF_T_DVB_FE && tuner) - media_create_intf_link(tuner, intf, 0); + media_create_intf_link(tuner, intf, + MEDIA_LNK_FL_ENABLED); if (intf->type == MEDIA_INTF_T_DVB_DVR && demux) - media_create_intf_link(demux, intf, 0); + media_create_intf_link(demux, intf, + MEDIA_LNK_FL_ENABLED); media_device_for_each_entity(entity, mdev) { if (entity->type == MEDIA_ENT_T_DVB_TSOUT) { if (!strcmp(entity->name, DVR_TSOUT)) - media_create_intf_link(entity, intf, 0); + media_create_intf_link(entity, intf, + MEDIA_LNK_FL_ENABLED); if (!strcmp(entity->name, DEMUX_TSOUT)) - media_create_intf_link(entity, intf, 0); + media_create_intf_link(entity, intf, + MEDIA_LNK_FL_ENABLED); break; } } -- GitLab From 7e9a8ad57c097b7fe7ed9ba514f78789363aa6b8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 10 Dec 2015 10:58:04 -0200 Subject: [PATCH 2502/2855] [media] au0828: postpone call to au0828_unregister_media_device() The DVB core needs to unregister the media device. So, we can't call au0828_unregister_media_device() before calling au0828_dvb_unregister(), otherwise the DVB MC free code (that will be implemented on the next patch) will fail. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/au0828-core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index ee20f4354ba26..e7ebb5e638be5 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -178,8 +178,6 @@ static void au0828_usb_disconnect(struct usb_interface *interface) */ dev->dev_state = DEV_DISCONNECTED; - au0828_unregister_media_device(dev); - au0828_rc_unregister(dev); /* Digital TV */ au0828_dvb_unregister(dev); @@ -193,6 +191,10 @@ static void au0828_usb_disconnect(struct usb_interface *interface) au0828_analog_unregister(dev); v4l2_device_disconnect(&dev->v4l2_dev); v4l2_device_put(&dev->v4l2_dev); + /* + * No need to call au0828_usb_release() if V4L2 is enabled, + * as this is already called via au0828_usb_v4l2_release() + */ return; } #endif -- GitLab From a9709e435454cf84d8971261ff8ded3a453b9b13 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 24 Aug 2015 14:57:53 -0300 Subject: [PATCH 2503/2855] [media] media: don't try to empty links list in media_entity_cleanup() The media_entity_cleanup() function only cleans up the entity links list but this operation is already made in media_device_unregister_entity(). In most cases this should be harmless (besides having duplicated code) since the links list would be empty so the iteration would not happen but the links list is initialized in media_device_register_entity() so if a driver fails to register an entity with a media device and clean up the entity in the error path, a NULL deference pointer error will happen. So don't try to empty the links list in media_entity_cleanup() since is either done already or haven't been initialized yet. Signed-off-by: Javier Martinez Canillas --- drivers/media/media-entity.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index b1390d843909b..d7243cb56c79d 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -242,13 +242,6 @@ EXPORT_SYMBOL_GPL(media_entity_init); void media_entity_cleanup(struct media_entity *entity) { - struct media_link *link, *tmp; - - list_for_each_entry_safe(link, tmp, &entity->links, list) { - media_gobj_remove(&link->graph_obj); - list_del(&link->list); - kfree(link); - } } EXPORT_SYMBOL_GPL(media_entity_cleanup); -- GitLab From eb83a5176801d53f9f78eff8c0bf03e627110206 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 10 Dec 2015 15:29:22 -0200 Subject: [PATCH 2504/2855] [media] media-entity: fix backlink removal on __media_entity_remove_link() The logic is testing if num_links==0 at the wrong place. Due to that, a backlink may be kept without removal, causing KASAN to complain about usage after free during either entity or link removal. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index d7243cb56c79d..d9d42fab22ad2 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -662,13 +662,13 @@ static void __media_entity_remove_link(struct media_entity *entity, if (link->source->entity == entity) remote->num_backlinks--; - if (--remote->num_links == 0) - break; - /* Remove the remote link */ list_del(&rlink->list); media_gobj_remove(&rlink->graph_obj); kfree(rlink); + + if (--remote->num_links == 0) + break; } list_del(&link->list); media_gobj_remove(&link->graph_obj); -- GitLab From f50d51661af375c40cae894753e8cd9b1fe82c65 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 4 Sep 2015 15:10:29 -0300 Subject: [PATCH 2505/2855] [media] dvbdev: returns error if graph object creation fails Right now, if something gets wrong at dvb_create_media_entity() or at dvb_create_media_graph(), the device will still be registered. Change the logic to properly handle it and free all media graph objects if something goes wrong at dvb_register_device(). Also, change the logic at dvb_create_media_graph() to return an error code if something goes wrong. It is up to the caller to implement the right logic and to call dvb_unregister_device() to unregister the already-created objects. While here, add a missing logic to unregister the created interfaces. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 313 +++++++++++++++++++------------- drivers/media/dvb-core/dvbdev.h | 7 +- drivers/media/media-device.c | 10 +- 3 files changed, 193 insertions(+), 137 deletions(-) diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 5c4fb41060b49..bc650c637fc02 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -183,7 +183,40 @@ skip: return -ENFILE; } -static void dvb_create_tsout_entity(struct dvb_device *dvbdev, +static void dvb_media_device_free(struct dvb_device *dvbdev) +{ +#if defined(CONFIG_MEDIA_CONTROLLER_DVB) + if (dvbdev->entity) { + media_device_unregister_entity(dvbdev->entity); + kfree(dvbdev->entity); + kfree(dvbdev->pads); + dvbdev->entity = NULL; + dvbdev->pads = NULL; + } + + if (dvbdev->tsout_entity) { + int i; + + for (i = 0; i < dvbdev->tsout_num_entities; i++) { + media_device_unregister_entity(&dvbdev->tsout_entity[i]); + kfree(dvbdev->tsout_entity[i].name); + } + kfree(dvbdev->tsout_entity); + kfree(dvbdev->tsout_pads); + dvbdev->tsout_entity = NULL; + dvbdev->tsout_pads = NULL; + + dvbdev->tsout_num_entities = 0; + } + + if (dvbdev->intf_devnode) { + media_devnode_remove(dvbdev->intf_devnode); + dvbdev->intf_devnode = NULL; + } +#endif +} + +static int dvb_create_tsout_entity(struct dvb_device *dvbdev, const char *name, int npads) { #if defined(CONFIG_MEDIA_CONTROLLER_DVB) @@ -192,77 +225,62 @@ static void dvb_create_tsout_entity(struct dvb_device *dvbdev, dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads), GFP_KERNEL); if (!dvbdev->tsout_pads) - return; + return -ENOMEM; + dvbdev->tsout_entity = kcalloc(npads, sizeof(*dvbdev->tsout_entity), GFP_KERNEL); - if (!dvbdev->tsout_entity) { - kfree(dvbdev->tsout_pads); - dvbdev->tsout_pads = NULL; - return; - } + if (!dvbdev->tsout_entity) + return -ENOMEM; + + dvbdev->tsout_num_entities = npads; + for (i = 0; i < npads; i++) { struct media_pad *pads = &dvbdev->tsout_pads[i]; struct media_entity *entity = &dvbdev->tsout_entity[i]; entity->name = kasprintf(GFP_KERNEL, "%s #%d", name, i); - if (!entity->name) { - ret = -ENOMEM; - break; - } + if (!entity->name) + return -ENOMEM; entity->type = MEDIA_ENT_T_DVB_TSOUT; pads->flags = MEDIA_PAD_FL_SINK; ret = media_entity_init(entity, 1, pads); if (ret < 0) - break; + return ret; ret = media_device_register_entity(dvbdev->adapter->mdev, entity); if (ret < 0) - break; - } - - if (!ret) { - dvbdev->tsout_num_entities = npads; - return; + return ret; } - - for (i--; i >= 0; i--) { - media_device_unregister_entity(&dvbdev->tsout_entity[i]); - kfree(dvbdev->tsout_entity[i].name); - } - - printk(KERN_ERR - "%s: media_device_register_entity failed for %s\n", - __func__, name); - - kfree(dvbdev->tsout_entity); - kfree(dvbdev->tsout_pads); - dvbdev->tsout_entity = NULL; - dvbdev->tsout_pads = NULL; #endif + return 0; } #define DEMUX_TSOUT "demux-tsout" #define DVR_TSOUT "dvr-tsout" -static void dvb_create_media_entity(struct dvb_device *dvbdev, - int type, int demux_sink_pads) +static int dvb_create_media_entity(struct dvb_device *dvbdev, + int type, int demux_sink_pads) { #if defined(CONFIG_MEDIA_CONTROLLER_DVB) - int i, ret = 0, npads; + int i, ret, npads; switch (type) { case DVB_DEVICE_FRONTEND: npads = 2; break; case DVB_DEVICE_DVR: - dvb_create_tsout_entity(dvbdev, DVR_TSOUT, demux_sink_pads); - return; + ret = dvb_create_tsout_entity(dvbdev, DVR_TSOUT, + demux_sink_pads); + return ret; case DVB_DEVICE_DEMUX: npads = 1 + demux_sink_pads; - dvb_create_tsout_entity(dvbdev, DEMUX_TSOUT, demux_sink_pads); + ret = dvb_create_tsout_entity(dvbdev, DEMUX_TSOUT, + demux_sink_pads); + if (ret < 0) + return ret; break; case DVB_DEVICE_CA: npads = 2; @@ -277,24 +295,22 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev, * the Media Controller, let's not create the decap * entities yet. */ - return; + return 0; default: - return; + return 0; } dvbdev->entity = kzalloc(sizeof(*dvbdev->entity), GFP_KERNEL); if (!dvbdev->entity) - return; + return -ENOMEM; dvbdev->entity->name = dvbdev->name; if (npads) { dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads), GFP_KERNEL); - if (!dvbdev->pads) { - kfree(dvbdev->entity); - return; - } + if (!dvbdev->pads) + return -ENOMEM; } switch (type) { @@ -315,50 +331,46 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev, dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; break; default: + /* Should never happen, as the first switch prevents it */ kfree(dvbdev->entity); + kfree(dvbdev->pads); dvbdev->entity = NULL; - return; + dvbdev->pads = NULL; + return 0; } - if (npads) + if (npads) { ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads); - if (!ret) - ret = media_device_register_entity(dvbdev->adapter->mdev, - dvbdev->entity); - if (ret < 0) { - printk(KERN_ERR - "%s: media_device_register_entity failed for %s\n", - __func__, dvbdev->entity->name); - - media_device_unregister_entity(dvbdev->entity); - for (i = 0; i < dvbdev->tsout_num_entities; i++) { - media_device_unregister_entity(&dvbdev->tsout_entity[i]); - kfree(dvbdev->tsout_entity[i].name); - } - kfree(dvbdev->pads); - kfree(dvbdev->entity); - kfree(dvbdev->tsout_pads); - kfree(dvbdev->tsout_entity); - dvbdev->entity = NULL; - return; + if (ret) + return ret; } + ret = media_device_register_entity(dvbdev->adapter->mdev, + dvbdev->entity); + if (ret) + return (ret); printk(KERN_DEBUG "%s: media entity '%s' registered.\n", __func__, dvbdev->entity->name); + #endif + return 0; } -static void dvb_register_media_device(struct dvb_device *dvbdev, - int type, int minor, - unsigned demux_sink_pads) +static int dvb_register_media_device(struct dvb_device *dvbdev, + int type, int minor, + unsigned demux_sink_pads) { #if defined(CONFIG_MEDIA_CONTROLLER_DVB) + struct media_link *link; u32 intf_type; + int ret; if (!dvbdev->adapter->mdev) - return; + return 0; - dvb_create_media_entity(dvbdev, type, demux_sink_pads); + ret = dvb_create_media_entity(dvbdev, type, demux_sink_pads); + if (ret) + return ret; switch (type) { case DVB_DEVICE_FRONTEND: @@ -377,13 +389,16 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, intf_type = MEDIA_INTF_T_DVB_NET; break; default: - return; + return 0; } dvbdev->intf_devnode = media_devnode_create(dvbdev->adapter->mdev, - intf_type, 0, - DVB_MAJOR, minor, - GFP_KERNEL); + intf_type, 0, + DVB_MAJOR, minor, + GFP_KERNEL); + + if (!dvbdev->intf_devnode) + return -ENOMEM; /* * Create the "obvious" link, e. g. the ones that represent @@ -393,13 +408,15 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, * DVB demux intf -> dvr */ - if (!dvbdev->entity || !dvbdev->intf_devnode) - return; - - media_create_intf_link(dvbdev->entity, &dvbdev->intf_devnode->intf, - MEDIA_LNK_FL_ENABLED); + if (!dvbdev->entity) + return 0; + link = media_create_intf_link(dvbdev->entity, &dvbdev->intf_devnode->intf, + MEDIA_LNK_FL_ENABLED); + if (!link) + return -ENOMEM; #endif + return 0; } int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, @@ -410,7 +427,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, struct file_operations *dvbdevfops; struct device *clsdev; int minor; - int id; + int id, ret; mutex_lock(&dvbdev_register_lock); @@ -421,7 +438,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, return -ENFILE; } - *pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL); + *pdvbdev = dvbdev = kzalloc(sizeof(*dvbdev), GFP_KERNEL); if (!dvbdev){ mutex_unlock(&dvbdev_register_lock); @@ -470,6 +487,20 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, dvb_minors[minor] = dvbdev; up_write(&minor_rwsem); + ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads); + if (ret) { + printk(KERN_ERR + "%s: dvb_register_media_device failed to create the mediagraph\n", + __func__); + + dvb_media_device_free(dvbdev); + kfree(dvbdevfops); + kfree(dvbdev); + up_write(&minor_rwsem); + mutex_unlock(&dvbdev_register_lock); + return ret; + } + mutex_unlock(&dvbdev_register_lock); clsdev = device_create(dvb_class, adap->device, @@ -483,8 +514,6 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", adap->num, dnames[type], id, minor, minor); - dvb_register_media_device(dvbdev, type, minor, demux_sink_pads); - return 0; } EXPORT_SYMBOL(dvb_register_device); @@ -499,24 +528,9 @@ void dvb_unregister_device(struct dvb_device *dvbdev) dvb_minors[dvbdev->minor] = NULL; up_write(&minor_rwsem); - device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor)); - -#if defined(CONFIG_MEDIA_CONTROLLER_DVB) - if (dvbdev->entity) { - int i; + dvb_media_device_free(dvbdev); - media_device_unregister_entity(dvbdev->entity); - for (i = 0; i < dvbdev->tsout_num_entities; i++) { - media_device_unregister_entity(&dvbdev->tsout_entity[i]); - kfree(dvbdev->tsout_entity[i].name); - } - - kfree(dvbdev->entity); - kfree(dvbdev->pads); - kfree(dvbdev->tsout_entity); - kfree(dvbdev->tsout_pads); - } -#endif + device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor)); list_del (&dvbdev->list_head); kfree (dvbdev->fops); @@ -526,17 +540,19 @@ EXPORT_SYMBOL(dvb_unregister_device); #ifdef CONFIG_MEDIA_CONTROLLER_DVB -void dvb_create_media_graph(struct dvb_adapter *adap) +int dvb_create_media_graph(struct dvb_adapter *adap) { struct media_device *mdev = adap->mdev; struct media_entity *entity, *tuner = NULL, *demod = NULL; struct media_entity *demux = NULL, *ca = NULL; + struct media_link *link; struct media_interface *intf; unsigned demux_pad = 0; unsigned dvr_pad = 0; + int ret; if (!mdev) - return; + return 0; media_device_for_each_entity(entity, mdev) { switch (entity->type) { @@ -555,57 +571,94 @@ void dvb_create_media_graph(struct dvb_adapter *adap) } } - if (tuner && demod) - media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, demod, 0, 0); + if (tuner && demod) { + ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, + demod, 0, MEDIA_LNK_FL_ENABLED); + if (ret) + return ret; + } - if (demod && demux) - media_create_pad_link(demod, 1, demux, 0, MEDIA_LNK_FL_ENABLED); - if (demux && ca) - media_create_pad_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED); + if (demod && demux) { + ret = media_create_pad_link(demod, 1, demux, + 0, MEDIA_LNK_FL_ENABLED); + if (ret) + return -ENOMEM; + } + if (demux && ca) { + ret = media_create_pad_link(demux, 1, ca, + 0, MEDIA_LNK_FL_ENABLED); + if (!ret) + return -ENOMEM; + } /* Create demux links for each ringbuffer/pad */ if (demux) { media_device_for_each_entity(entity, mdev) { if (entity->type == MEDIA_ENT_T_DVB_TSOUT) { if (!strncmp(entity->name, DVR_TSOUT, - strlen(DVR_TSOUT))) - media_create_pad_link(demux, - ++dvr_pad, - entity, 0, 0); + strlen(DVR_TSOUT))) { + ret = media_create_pad_link(demux, + ++dvr_pad, + entity, 0, 0); + if (ret) + return ret; + } if (!strncmp(entity->name, DEMUX_TSOUT, - strlen(DEMUX_TSOUT))) - media_create_pad_link(demux, + strlen(DEMUX_TSOUT))) { + ret = media_create_pad_link(demux, ++demux_pad, - entity, 0, 0); + entity, 0, 0); + if (ret) + return ret; + } } } } /* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */ media_device_for_each_intf(intf, mdev) { - if (intf->type == MEDIA_INTF_T_DVB_CA && ca) - media_create_intf_link(ca, intf, MEDIA_LNK_FL_ENABLED); + if (intf->type == MEDIA_INTF_T_DVB_CA && ca) { + link = media_create_intf_link(ca, intf, + MEDIA_LNK_FL_ENABLED); + if (!link) + return -ENOMEM; + } - if (intf->type == MEDIA_INTF_T_DVB_FE && tuner) - media_create_intf_link(tuner, intf, - MEDIA_LNK_FL_ENABLED); + if (intf->type == MEDIA_INTF_T_DVB_FE && tuner) { + link = media_create_intf_link(tuner, intf, + MEDIA_LNK_FL_ENABLED); + if (!link) + return -ENOMEM; + } - if (intf->type == MEDIA_INTF_T_DVB_DVR && demux) - media_create_intf_link(demux, intf, - MEDIA_LNK_FL_ENABLED); + if (intf->type == MEDIA_INTF_T_DVB_DVR && demux) { + link = media_create_intf_link(demux, intf, + MEDIA_LNK_FL_ENABLED); + if (!link) + return -ENOMEM; + } media_device_for_each_entity(entity, mdev) { if (entity->type == MEDIA_ENT_T_DVB_TSOUT) { - if (!strcmp(entity->name, DVR_TSOUT)) - media_create_intf_link(entity, intf, - MEDIA_LNK_FL_ENABLED); - if (!strcmp(entity->name, DEMUX_TSOUT)) - media_create_intf_link(entity, intf, - MEDIA_LNK_FL_ENABLED); + if (!strcmp(entity->name, DVR_TSOUT)) { + link = media_create_intf_link(entity, + intf, + MEDIA_LNK_FL_ENABLED); + if (!link) + return -ENOMEM; + } + if (!strcmp(entity->name, DEMUX_TSOUT)) { + link = media_create_intf_link(entity, + intf, + MEDIA_LNK_FL_ENABLED); + if (!link) + return -ENOMEM; + } break; } } } + return 0; } EXPORT_SYMBOL_GPL(dvb_create_media_graph); #endif diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index 7af8adbb589b8..3840dd62bfeef 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h @@ -206,7 +206,7 @@ int dvb_register_device(struct dvb_adapter *adap, void dvb_unregister_device(struct dvb_device *dvbdev); #ifdef CONFIG_MEDIA_CONTROLLER_DVB -void dvb_create_media_graph(struct dvb_adapter *adap); +int dvb_create_media_graph(struct dvb_adapter *adap); static inline void dvb_register_media_controller(struct dvb_adapter *adap, struct media_device *mdev) { @@ -214,7 +214,10 @@ static inline void dvb_register_media_controller(struct dvb_adapter *adap, } #else -static inline void dvb_create_media_graph(struct dvb_adapter *adap) {} +static inline int dvb_create_media_graph(struct dvb_adapter *adap) +{ + return 0; +}; #define dvb_register_media_controller(a, b) {} #endif diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 96700843b1e4f..c7d97190a67e3 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -576,6 +576,10 @@ void media_device_unregister(struct media_device *mdev) struct media_entity *next; struct media_interface *intf, *tmp_intf; + /* Remove all entities from the media device */ + list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list) + media_device_unregister_entity(entity); + /* Remove all interfaces from the media device */ spin_lock(&mdev->lock); list_for_each_entry_safe(intf, tmp_intf, &mdev->interfaces, @@ -586,9 +590,6 @@ void media_device_unregister(struct media_device *mdev) } spin_unlock(&mdev->lock); - list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list) - media_device_unregister_entity(entity); - device_remove_file(&mdev->devnode.dev, &dev_attr_model); media_devnode_unregister(&mdev->devnode); @@ -654,8 +655,7 @@ void media_device_unregister_entity(struct media_entity *entity) /* Remove all interface links pointing to this entity */ list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) { list_for_each_entry_safe(link, tmp, &intf->links, list) { - if (media_type(link->gobj1) == MEDIA_GRAPH_ENTITY - && link->entity == entity) + if (link->entity == entity) __media_remove_intf_link(link); } } -- GitLab From d9c21e3e4b459b45e11406b83ebde163181508a1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 24 Aug 2015 08:47:54 -0300 Subject: [PATCH 2506/2855] [media] v4l2-core: create MC interfaces for devnodes V4L2 device (and subdevice) nodes should create an interface, if the Media Controller support is enabled. Please notice that radio devices should not create an entity, as radio input/output is either via wires or via ALSA. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dev.c | 111 +++++++++++++++++++++----- drivers/media/v4l2-core/v4l2-device.c | 16 +++- include/media/v4l2-dev.h | 1 + 3 files changed, 109 insertions(+), 19 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 2297571a0568a..077cdc92778cd 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -194,9 +194,12 @@ static void v4l2_device_release(struct device *cd) mutex_unlock(&videodev_lock); #if defined(CONFIG_MEDIA_CONTROLLER) - if (v4l2_dev->mdev && - vdev->vfl_type != VFL_TYPE_SUBDEV) - media_device_unregister_entity(&vdev->entity); + if (v4l2_dev->mdev) { + /* Remove interfaces and interface links */ + media_devnode_remove(vdev->intf_devnode); + if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN) + media_device_unregister_entity(&vdev->entity); + } #endif /* Do not call v4l2_device_put if there is no release callback set. @@ -723,6 +726,91 @@ static void determine_valid_ioctls(struct video_device *vdev) BASE_VIDIOC_PRIVATE); } +static int video_register_media_controller(struct video_device *vdev, int type) +{ +#if defined(CONFIG_MEDIA_CONTROLLER) + u32 intf_type; + int ret; + + if (!vdev->v4l2_dev->mdev) + return 0; + + vdev->entity.type = MEDIA_ENT_T_UNKNOWN; + + switch (type) { + case VFL_TYPE_GRABBER: + intf_type = MEDIA_INTF_T_V4L_VIDEO; + vdev->entity.type = MEDIA_ENT_T_V4L2_VIDEO; + break; + case VFL_TYPE_VBI: + intf_type = MEDIA_INTF_T_V4L_VBI; + vdev->entity.type = MEDIA_ENT_T_V4L2_VBI; + break; + case VFL_TYPE_SDR: + intf_type = MEDIA_INTF_T_V4L_SWRADIO; + vdev->entity.type = MEDIA_ENT_T_V4L2_SWRADIO; + break; + case VFL_TYPE_RADIO: + intf_type = MEDIA_INTF_T_V4L_RADIO; + /* + * Radio doesn't have an entity at the V4L2 side to represent + * radio input or output. Instead, the audio input/output goes + * via either physical wires or ALSA. + */ + break; + case VFL_TYPE_SUBDEV: + intf_type = MEDIA_INTF_T_V4L_SUBDEV; + /* Entity will be created via v4l2_device_register_subdev() */ + break; + default: + return 0; + } + + if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN) { + vdev->entity.name = vdev->name; + + /* Needed just for backward compatibility with legacy MC API */ + vdev->entity.info.dev.major = VIDEO_MAJOR; + vdev->entity.info.dev.minor = vdev->minor; + + ret = media_device_register_entity(vdev->v4l2_dev->mdev, + &vdev->entity); + if (ret < 0) { + printk(KERN_WARNING + "%s: media_device_register_entity failed\n", + __func__); + return ret; + } + } + + vdev->intf_devnode = media_devnode_create(vdev->v4l2_dev->mdev, + intf_type, + 0, VIDEO_MAJOR, + vdev->minor, + GFP_KERNEL); + if (!vdev->intf_devnode) { + media_device_unregister_entity(&vdev->entity); + return -ENOMEM; + } + + if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN) { + struct media_link *link; + + link = media_create_intf_link(&vdev->entity, + &vdev->intf_devnode->intf, 0); + if (!link) { + media_devnode_remove(vdev->intf_devnode); + media_device_unregister_entity(&vdev->entity); + return -ENOMEM; + } + } + + /* FIXME: how to create the other interface links? */ + +#endif + return 0; +} + /** * __video_register_device - register video4linux devices * @vdev: video device structure we want to register @@ -918,22 +1006,9 @@ int __video_register_device(struct video_device *vdev, int type, int nr, /* Increase v4l2_device refcount */ v4l2_device_get(vdev->v4l2_dev); -#if defined(CONFIG_MEDIA_CONTROLLER) /* Part 5: Register the entity. */ - if (vdev->v4l2_dev->mdev && - vdev->vfl_type != VFL_TYPE_SUBDEV) { - vdev->entity.type = MEDIA_ENT_T_V4L2_VIDEO; - vdev->entity.name = vdev->name; - vdev->entity.info.dev.major = VIDEO_MAJOR; - vdev->entity.info.dev.minor = vdev->minor; - ret = media_device_register_entity(vdev->v4l2_dev->mdev, - &vdev->entity); - if (ret < 0) - printk(KERN_WARNING - "%s: media_device_register_entity failed\n", - __func__); - } -#endif + ret = video_register_media_controller(vdev, type); + /* Part 6: Activate this minor. The char device can now be used. */ set_bit(V4L2_FL_REGISTERED, &vdev->flags); diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c index 7129e438f29e7..3c87307e56f08 100644 --- a/drivers/media/v4l2-core/v4l2-device.c +++ b/drivers/media/v4l2-core/v4l2-device.c @@ -258,6 +258,17 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev) #if defined(CONFIG_MEDIA_CONTROLLER) sd->entity.info.dev.major = VIDEO_MAJOR; sd->entity.info.dev.minor = vdev->minor; + + /* Interface is created by __video_register_device() */ + if (vdev->v4l2_dev->mdev) { + struct media_link *link; + + link = media_create_intf_link(&sd->entity, + &vdev->intf_devnode->intf, + 0); + if (!link) + goto clean_up; + } #endif sd->devnode = vdev; } @@ -294,7 +305,10 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd) #if defined(CONFIG_MEDIA_CONTROLLER) if (v4l2_dev->mdev) { - media_entity_remove_links(&sd->entity); + /* + * No need to explicitly remove links, as both pads and + * links are removed by the function below, in the right order + */ media_device_unregister_entity(&sd->entity); } #endif diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index acbcd2f5fe7f8..eeabf20e87a66 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -86,6 +86,7 @@ struct video_device { #if defined(CONFIG_MEDIA_CONTROLLER) struct media_entity entity; + struct media_intf_devnode *intf_devnode; #endif /* device ops */ const struct v4l2_file_operations *fops; -- GitLab From c358e80d70d97efc144e7d496c92985ad74218a8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 29 Aug 2015 23:43:03 -0300 Subject: [PATCH 2507/2855] [media] media-entity.h: document all the structs Only a few structs are documented on kernel-doc-nano format (the ones added by the MC next gen patches). Add a documentation for all structs, and ensure that they'll be producing the documentation at the Kernel's device driver DocBook. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 114 ++++++++++++++++++++++++++--------- 1 file changed, 84 insertions(+), 30 deletions(-) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index f165d303f03c8..fd19aecdcbb64 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -55,11 +55,13 @@ enum media_gobj_type { /** * struct media_gobj - Define a graph object. * + * @mdev: Pointer to the struct media_device that owns the object * @id: Non-zero object ID identifier. The ID should be unique * inside a media_device, as it is composed by * MEDIA_BITS_PER_TYPE to store the type plus * MEDIA_BITS_PER_LOCAL_ID to store a per-type ID * (called as "local ID"). + * @list: List entry stored in one of the per-type mdev object lists * * All objects on the media graph should have this struct embedded */ @@ -73,6 +75,28 @@ struct media_gobj { struct media_pipeline { }; +/** + * struct media_link - A link object part of a media graph. + * + * @graph_obj: Embedded structure containing the media object common data + * @list: Linked list associated with an entity or an interface that + * owns the link. + * @gobj0: Part of a union. Used to get the pointer for the first + * graph_object of the link. + * @source: Part of a union. Used only if the first object (gobj0) is + * a pad. In that case, it represents the source pad. + * @intf: Part of a union. Used only if the first object (gobj0) is + * an interface. + * @gobj1: Part of a union. Used to get the pointer for the second + * graph_object of the link. + * @source: Part of a union. Used only if the second object (gobj1) is + * a pad. In that case, it represents the sink pad. + * @entity: Part of a union. Used only if the second object (gobj1) is + * an entity. + * @reverse: Pointer to the link for the reverse direction of a pad to pad + * link. + * @flags: Link flags, as defined in uapi/media.h (MEDIA_LNK_FL_*) + */ struct media_link { struct media_gobj graph_obj; struct list_head list; @@ -86,15 +110,23 @@ struct media_link { struct media_pad *sink; struct media_entity *entity; }; - struct media_link *reverse; /* Link in the reverse direction */ - unsigned long flags; /* Link flags (MEDIA_LNK_FL_*) */ + struct media_link *reverse; + unsigned long flags; }; +/** + * struct media_pad - A media pad graph object. + * + * @graph_obj: Embedded structure containing the media object common data + * @entity: Entity this pad belongs to + * @index: Pad index in the entity pads array, numbered from 0 to n + * @flags: Pad flags, as defined in uapi/media.h (MEDIA_PAD_FL_*) + */ struct media_pad { struct media_gobj graph_obj; /* must be first field in struct */ - struct media_entity *entity; /* Entity this pad belongs to */ - u16 index; /* Pad index in the entity pads array */ - unsigned long flags; /* Pad flags (MEDIA_PAD_FL_*) */ + struct media_entity *entity; + u16 index; + unsigned long flags; }; /** @@ -113,56 +145,78 @@ struct media_entity_operations { int (*link_validate)(struct media_link *link); }; +/** + * struct media_entity - A media entity graph object. + * + * @graph_obj: Embedded structure containing the media object common data. + * @name: Entity name. + * @type: Entity type, as defined in uapi/media.h (MEDIA_ENT_T_*) + * @revision: Entity revision - OBSOLETE - should be removed soon. + * @flags: Entity flags, as defined in uapi/media.h (MEDIA_ENT_FL_*) + * @group_id: Entity group ID - OBSOLETE - should be removed soon. + * @num_pads: Number of sink and source pads. + * @num_links: Total number of links, forward and back, enabled and disabled. + * @num_backlinks: Number of backlinks + * @pads: Pads array with the size defined by @num_pads. + * @links: List of data links. + * @ops: Entity operations. + * @stream_count: Stream count for the entity. + * @use_count: Use count for the entity. + * @pipe: Pipeline this entity belongs to. + * @info: Union with devnode information. Kept just for backward + * compatibility. + * @major: Devnode major number (zero if not applicable). Kept just + * for backward compatibility. + * @minor: Devnode minor number (zero if not applicable). Kept just + * for backward compatibility. + * + * NOTE: @stream_count and @use_count reference counts must never be + * negative, but are signed integers on purpose: a simple WARN_ON(<0) check + * can be used to detect reference count bugs that would make them negative. + */ struct media_entity { struct media_gobj graph_obj; /* must be first field in struct */ - const char *name; /* Entity name */ - u32 type; /* Entity type (MEDIA_ENT_T_*) */ - u32 revision; /* Entity revision, driver specific */ - unsigned long flags; /* Entity flags (MEDIA_ENT_FL_*) */ - u32 group_id; /* Entity group ID */ + const char *name; + u32 type; + u32 revision; + unsigned long flags; + u32 group_id; - u16 num_pads; /* Number of sink and source pads */ - u16 num_links; /* Number of existing links, both - * enabled and disabled */ - u16 num_backlinks; /* Number of backlinks */ + u16 num_pads; + u16 num_links; + u16 num_backlinks; - struct media_pad *pads; /* Pads array (num_pads objects) */ - struct list_head links; /* Pad-to-pad links list */ + struct media_pad *pads; + struct list_head links; - const struct media_entity_operations *ops; /* Entity operations */ + const struct media_entity_operations *ops; /* Reference counts must never be negative, but are signed integers on * purpose: a simple WARN_ON(<0) check can be used to detect reference * count bugs that would make them negative. */ - int stream_count; /* Stream count for the entity. */ - int use_count; /* Use count for the entity. */ + int stream_count; + int use_count; - struct media_pipeline *pipe; /* Pipeline this entity belongs to. */ + struct media_pipeline *pipe; union { - /* Node specifications */ struct { u32 major; u32 minor; } dev; - - /* Sub-device specifications */ - /* Nothing needed yet */ } info; }; /** - * struct media_intf_devnode - Define a Kernel API interface + * struct media_interface - A media interface graph object. * * @graph_obj: embedded graph object - * @list: Linked list used to find other interfaces that belong - * to the same media controller * @links: List of links pointing to graph entities - * @type: Type of the interface as defined at the + * @type: Type of the interface as defined in the * uapi/media/media.h header, e. g. * MEDIA_INTF_T_* - * @flags: Interface flags as defined at uapi/media/media.h + * @flags: Interface flags as defined in uapi/media/media.h */ struct media_interface { struct media_gobj graph_obj; @@ -172,7 +226,7 @@ struct media_interface { }; /** - * struct media_intf_devnode - Define a Kernel API interface via a device node + * struct media_intf_devnode - A media interface via a device node. * * @intf: embedded interface object * @major: Major number of a device node -- GitLab From 49a11518f84c6fda6b2740e592ce53e1a22311a3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 31 Aug 2015 11:41:29 -0300 Subject: [PATCH 2508/2855] [media] media.h: create connector entities for hybrid TV devices Add entities to represent the connectors that exists inside a hybrid TV device. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 72ac39de38225..f9520225a211b 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -61,6 +61,7 @@ struct media_device_info { #define MEDIA_ENT_T_DVB_BASE 0x00000000 #define MEDIA_ENT_T_V4L2_BASE 0x00010000 #define MEDIA_ENT_T_V4L2_SUBDEV_BASE 0x00020000 +#define MEDIA_ENT_T_CONNECTOR_BASE 0x00030000 /* * V4L2 entities - Those are used for DMA (mmap/DMABUF) and @@ -105,6 +106,13 @@ struct media_device_info { #define MEDIA_ENT_T_DVB_CA (MEDIA_ENT_T_DVB_BASE + 4) #define MEDIA_ENT_T_DVB_NET_DECAP (MEDIA_ENT_T_DVB_BASE + 5) +/* Connectors */ +#define MEDIA_ENT_T_CONN_RF (MEDIA_ENT_T_CONNECTOR_BASE + 1) +#define MEDIA_ENT_T_CONN_SVIDEO (MEDIA_ENT_T_CONNECTOR_BASE + 2) +#define MEDIA_ENT_T_CONN_COMPOSITE (MEDIA_ENT_T_CONNECTOR_BASE + 3) +/* For internal test signal generators and other debug connectors */ +#define MEDIA_ENT_T_CONN_TEST (MEDIA_ENT_T_CONNECTOR_BASE + 4) + #ifndef __KERNEL__ /* Legacy symbols used to avoid userspace compilation breakages */ #define MEDIA_ENT_TYPE_SHIFT 16 @@ -121,9 +129,9 @@ struct media_device_info { #define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4) #endif -/* Entity types */ - +/* Entity flags */ #define MEDIA_ENT_FL_DEFAULT (1 << 0) +#define MEDIA_ENT_FL_CONNECTOR (1 << 1) struct media_entity_desc { __u32 id; -- GitLab From d1f337375aedb2999bdca24b40ba6e5c1a796eb4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 31 Aug 2015 11:43:09 -0300 Subject: [PATCH 2509/2855] [media] au0828: add support for the connectors Depending on the input, an au0828 may have a different number of connectors. add entities to represent them. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/au0828-core.c | 15 +++++ drivers/media/usb/au0828/au0828-video.c | 76 +++++++++++++++++++++---- drivers/media/usb/au0828/au0828.h | 3 +- 3 files changed, 82 insertions(+), 12 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index e7ebb5e638be5..02aa6d3edffdf 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -153,11 +153,26 @@ static void au0828_usb_release(struct au0828_dev *dev) } #ifdef CONFIG_VIDEO_AU0828_V4L2 + +static void au0828_usb_v4l2_media_release(struct au0828_dev *dev) +{ +#ifdef CONFIG_MEDIA_CONTROLLER + int i; + + for (i = 0; i < AU0828_MAX_INPUT; i++) { + if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED) + return; + media_device_unregister_entity(&dev->input_ent[i]); + } +#endif +} + static void au0828_usb_v4l2_release(struct v4l2_device *v4l2_dev) { struct au0828_dev *dev = container_of(v4l2_dev, struct au0828_dev, v4l2_dev); + au0828_usb_v4l2_media_release(dev); v4l2_ctrl_handler_free(&dev->v4l2_ctrl_hdl); v4l2_device_unregister(&dev->v4l2_dev); au0828_usb_release(dev); diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 97df879c41996..75f2e02908f47 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1795,6 +1795,69 @@ static int au0828_vb2_setup(struct au0828_dev *dev) return 0; } +static void au0828_analog_create_entities(struct au0828_dev *dev) +{ +#if defined(CONFIG_MEDIA_CONTROLLER) + static const char * const inames[] = { + [AU0828_VMUX_COMPOSITE] = "Composite", + [AU0828_VMUX_SVIDEO] = "S-Video", + [AU0828_VMUX_CABLE] = "Cable TV", + [AU0828_VMUX_TELEVISION] = "Television", + [AU0828_VMUX_DVB] = "DVB", + [AU0828_VMUX_DEBUG] = "tv debug" + }; + int ret, i; + + /* Initialize Video and VBI pads */ + dev->video_pad.flags = MEDIA_PAD_FL_SINK; + ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad); + if (ret < 0) + pr_err("failed to initialize video media entity!\n"); + + dev->vbi_pad.flags = MEDIA_PAD_FL_SINK; + ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad); + if (ret < 0) + pr_err("failed to initialize vbi media entity!\n"); + + /* Create entities for each input connector */ + for (i = 0; i < AU0828_MAX_INPUT; i++) { + struct media_entity *ent = &dev->input_ent[i]; + + if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED) + break; + + ent->name = inames[AUVI_INPUT(i).type]; + ent->flags = MEDIA_ENT_FL_CONNECTOR; + dev->input_pad[i].flags = MEDIA_PAD_FL_SOURCE; + + switch (AUVI_INPUT(i).type) { + case AU0828_VMUX_COMPOSITE: + ent->type = MEDIA_ENT_T_CONN_COMPOSITE; + break; + case AU0828_VMUX_SVIDEO: + ent->type = MEDIA_ENT_T_CONN_SVIDEO; + break; + case AU0828_VMUX_CABLE: + case AU0828_VMUX_TELEVISION: + case AU0828_VMUX_DVB: + ent->type = MEDIA_ENT_T_CONN_RF; + break; + default: /* AU0828_VMUX_DEBUG */ + ent->type = MEDIA_ENT_T_CONN_TEST; + break; + } + + ret = media_entity_init(ent, 1, &dev->input_pad[i]); + if (ret < 0) + pr_err("failed to initialize input pad[%d]!\n", i); + + ret = media_device_register_entity(dev->media_dev, ent); + if (ret < 0) + pr_err("failed to register input entity %d!\n", i); + } +#endif +} + /**************************************************************************/ int au0828_analog_register(struct au0828_dev *dev, @@ -1883,17 +1946,8 @@ int au0828_analog_register(struct au0828_dev *dev, dev->vbi_dev.queue->lock = &dev->vb_vbi_queue_lock; strcpy(dev->vbi_dev.name, "au0828a vbi"); -#if defined(CONFIG_MEDIA_CONTROLLER) - dev->video_pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad); - if (ret < 0) - pr_err("failed to initialize video media entity!\n"); - - dev->vbi_pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad); - if (ret < 0) - pr_err("failed to initialize vbi media entity!\n"); -#endif + /* Init entities at the Media Controller */ + au0828_analog_create_entities(dev); /* initialize videobuf2 stuff */ retval = au0828_vb2_setup(dev); diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h index 3577b931157b4..8276072bc55ac 100644 --- a/drivers/media/usb/au0828/au0828.h +++ b/drivers/media/usb/au0828/au0828.h @@ -94,7 +94,6 @@ struct au0828_board { unsigned char has_ir_i2c:1; unsigned char has_analog:1; struct au0828_input input[AU0828_MAX_INPUT]; - }; struct au0828_dvb { @@ -282,6 +281,8 @@ struct au0828_dev { struct media_device *media_dev; struct media_pad video_pad, vbi_pad; struct media_entity *decoder; + struct media_entity input_ent[AU0828_MAX_INPUT]; + struct media_pad input_pad[AU0828_MAX_INPUT]; #endif }; -- GitLab From 28b6ba1106b5864e6bdd1b75840ccf5b1ca3d1b7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 31 Aug 2015 13:23:28 -0300 Subject: [PATCH 2510/2855] [media] au0828: Create connector links Now that connectors are entities, we need to represent the connector links. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/au0828-core.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 02aa6d3edffdf..0d77e9cc303b4 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -259,6 +259,7 @@ static void au0828_create_media_graph(struct au0828_dev *dev) struct media_device *mdev = dev->media_dev; struct media_entity *entity; struct media_entity *tuner = NULL, *decoder = NULL; + int i; if (!mdev) return; @@ -276,6 +277,7 @@ static void au0828_create_media_graph(struct au0828_dev *dev) /* Analog setup, using tuner as a link */ + /* Something bad happened! */ if (!decoder) return; @@ -286,6 +288,30 @@ static void au0828_create_media_graph(struct au0828_dev *dev) MEDIA_LNK_FL_ENABLED); media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0, MEDIA_LNK_FL_ENABLED); + + for (i = 0; i < AU0828_MAX_INPUT; i++) { + struct media_entity *ent = &dev->input_ent[i]; + + if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED) + break; + + switch (AUVI_INPUT(i).type) { + case AU0828_VMUX_CABLE: + case AU0828_VMUX_TELEVISION: + case AU0828_VMUX_DVB: + if (tuner) + media_create_pad_link(ent, 0, tuner, + TUNER_PAD_RF_INPUT, + MEDIA_LNK_FL_ENABLED); + break; + case AU0828_VMUX_COMPOSITE: + case AU0828_VMUX_SVIDEO: + default: /* AU0828_VMUX_DEBUG */ + /* FIXME: fix the decoder PAD */ + media_create_pad_link(ent, 0, decoder, 0, 0); + break; + } + } #endif } -- GitLab From 39d1ebc6092f8266fb788733ca92b8492b1d69f2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 30 Aug 2015 09:53:57 -0300 Subject: [PATCH 2511/2855] [media] media-device: supress backlinks at G_TOPOLOGY ioctl Due to the graph traversal algorithm currently in usage, we need a copy of all data links. Those backlinks should not be send to userspace, as otherwise, all links there will be duplicated. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 3 +++ drivers/media/media-entity.c | 1 + include/media/media-entity.h | 2 ++ 3 files changed, 6 insertions(+) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index c7d97190a67e3..30cef8740afaa 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -333,6 +333,9 @@ static long __media_device_get_topology(struct media_device *mdev, /* Get links and number of links */ i = 0; media_device_for_each_link(link, mdev) { + if (link->is_backlink) + continue; + i++; if (ret || !topo->links) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index d9d42fab22ad2..246d7e65adedb 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -625,6 +625,7 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, backlink->source = &source->pads[source_pad]; backlink->sink = &sink->pads[sink_pad]; backlink->flags = flags; + backlink->is_backlink = true; /* Initialize graph object embedded at the new link */ media_gobj_init(sink->graph_obj.mdev, MEDIA_GRAPH_LINK, diff --git a/include/media/media-entity.h b/include/media/media-entity.h index fd19aecdcbb64..3b591d72c7033 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -96,6 +96,7 @@ struct media_pipeline { * @reverse: Pointer to the link for the reverse direction of a pad to pad * link. * @flags: Link flags, as defined in uapi/media.h (MEDIA_LNK_FL_*) + * @is_backlink: Indicate if the link is a backlink. */ struct media_link { struct media_gobj graph_obj; @@ -112,6 +113,7 @@ struct media_link { }; struct media_link *reverse; unsigned long flags; + bool is_backlink; }; /** -- GitLab From 13f6e8887a1f61764a05a3348476d38071201f08 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 4 Sep 2015 15:39:43 -0300 Subject: [PATCH 2512/2855] [media] v4l2 core: enable all interface links at init Interface links are normally enabled, meaning that the interfaces are bound to the entities. So, any ioctl send to the interface are reflected at the entities managed by the interface. However, when a device is used, other interfaces for the same hardware could be decoupled from the entities linked to them, because the hardware may have some parts busy. That's for example, what happens when an hybrid TV device is in use. If it is streaming analog TV or capturing signals from S-Video/Composite connectors, typically the digital part of the hardware can't be used and vice-versa. This is generally due to some internal hardware or firmware limitation, that it is not easily mapped via data pipelines. What the Kernel drivers do internally is that they decouple the hardware from the interface. So, all changes, if allowed, are done only at some interface cache, but not physically changed at the hardware. The usage is similar to the usage of the MEDIA_LNK_FL_ENABLED on data links. So, let's use the same flag to indicate if either the interface to entity link is bound/enabled or not. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dev.c | 3 ++- drivers/media/v4l2-core/v4l2-device.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 077cdc92778cd..d36436582de96 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -797,7 +797,8 @@ static int video_register_media_controller(struct video_device *vdev, int type) struct media_link *link; link = media_create_intf_link(&vdev->entity, - &vdev->intf_devnode->intf, 0); + &vdev->intf_devnode->intf, + MEDIA_LNK_FL_ENABLED); if (!link) { media_devnode_remove(vdev->intf_devnode); media_device_unregister_entity(&vdev->entity); diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c index 3c87307e56f08..85f724b53a148 100644 --- a/drivers/media/v4l2-core/v4l2-device.c +++ b/drivers/media/v4l2-core/v4l2-device.c @@ -265,7 +265,7 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev) link = media_create_intf_link(&sd->entity, &vdev->intf_devnode->intf, - 0); + MEDIA_LNK_FL_ENABLED); if (!link) goto clean_up; } -- GitLab From 0d3ab8410dcb60aef2104231ba817037b3ba73bd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 4 Sep 2015 15:33:46 -0300 Subject: [PATCH 2513/2855] [media] dvb core: must check dvb_create_media_graph() If media controller is enabled and mdev is filled, it should ensure that the media graph will be properly initialized. Enforce that. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb-main.c | 6 +++++- drivers/media/dvb-core/dvbdev.h | 2 +- drivers/media/usb/au0828/au0828-dvb.c | 8 +++++--- drivers/media/usb/cx231xx/cx231xx-dvb.c | 6 +++++- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 4 +++- drivers/media/usb/dvb-usb/dvb-usb-dvb.c | 6 ++++-- 6 files changed, 23 insertions(+), 9 deletions(-) diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index f4305ae800f4c..ab345490a43ad 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -1183,7 +1183,11 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, if (smsdvb_debugfs_create(client) < 0) pr_info("failed to create debugfs node\n"); - dvb_create_media_graph(&client->adapter); + rc = dvb_create_media_graph(&client->adapter); + if (rc < 0) { + pr_err("dvb_create_media_graph failed %d\n", rc); + goto client_error; + } pr_info("DVB interface registered.\n"); return 0; diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index 3840dd62bfeef..de85ba0f570a8 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h @@ -206,7 +206,7 @@ int dvb_register_device(struct dvb_adapter *adap, void dvb_unregister_device(struct dvb_device *dvbdev); #ifdef CONFIG_MEDIA_CONTROLLER_DVB -int dvb_create_media_graph(struct dvb_adapter *adap); +__must_check int dvb_create_media_graph(struct dvb_adapter *adap); static inline void dvb_register_media_controller(struct dvb_adapter *adap, struct media_device *mdev) { diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c index c01772c4f9f07..cd542b49a6c2b 100644 --- a/drivers/media/usb/au0828/au0828-dvb.c +++ b/drivers/media/usb/au0828/au0828-dvb.c @@ -486,12 +486,14 @@ static int dvb_register(struct au0828_dev *dev) dvb->start_count = 0; dvb->stop_count = 0; -#ifdef CONFIG_MEDIA_CONTROLLER_DVB - dvb_create_media_graph(&dvb->adapter); -#endif + result = dvb_create_media_graph(&dvb->adapter); + if (result < 0) + goto fail_create_graph; return 0; +fail_create_graph: + dvb_net_release(&dvb->net); fail_fe_conn: dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); fail_fe_mem: diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index e3594b9fab4a5..b7552d20ebdb5 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -551,10 +551,14 @@ static int register_dvb(struct cx231xx_dvb *dvb, /* register network adapter */ dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); - dvb_create_media_graph(&dvb->adapter); + result = dvb_create_media_graph(&dvb->adapter); + if (result < 0) + goto fail_create_graph; return 0; +fail_create_graph: + dvb_net_release(&dvb->net); fail_fe_conn: dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); fail_fe_mem: diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index f5df9eaba04fb..6d3f61f6dc775 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -698,7 +698,9 @@ static int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap) } } - dvb_create_media_graph(&adap->dvb_adap); + ret = dvb_create_media_graph(&adap->dvb_adap); + if (ret < 0) + goto err_dvb_unregister_frontend; return 0; diff --git a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c index 8a260c854653d..b51dbdf03f422 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c @@ -318,10 +318,12 @@ int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap) adap->num_frontends_initialized++; } + if (ret) + return ret; - dvb_create_media_graph(&adap->dvb_adap); + ret = dvb_create_media_graph(&adap->dvb_adap); - return 0; + return ret; } int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap) -- GitLab From 5e5387df0491679fb1210b231173c5279061e9c4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 4 Sep 2015 15:34:19 -0300 Subject: [PATCH 2514/2855] [media] media-entity: enforce check of interface and links creation Drivers should check if interfaces and interface links were created. Add a must_check for them. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 3b591d72c7033..7128d3b0b8485 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -373,14 +373,16 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_pipeline *pipe); void media_entity_pipeline_stop(struct media_entity *entity); -struct media_intf_devnode *media_devnode_create(struct media_device *mdev, - u32 type, u32 flags, - u32 major, u32 minor, - gfp_t gfp_flags); +struct media_intf_devnode * +__must_check media_devnode_create(struct media_device *mdev, + u32 type, u32 flags, + u32 major, u32 minor, + gfp_t gfp_flags); void media_devnode_remove(struct media_intf_devnode *devnode); -struct media_link *media_create_intf_link(struct media_entity *entity, - struct media_interface *intf, - u32 flags); +struct media_link * +__must_check media_create_intf_link(struct media_entity *entity, + struct media_interface *intf, + u32 flags); void __media_remove_intf_link(struct media_link *link); void media_remove_intf_link(struct media_link *link); void __media_remove_intf_links(struct media_interface *intf); -- GitLab From ab232e46bf01db5c540a00f478853a3572b0b88b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 4 Sep 2015 16:07:03 -0300 Subject: [PATCH 2515/2855] [media] cx231xx: enforce check for graph creation If the graph creation fails, don't register the device. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-cards.c | 40 +++++++++++++++-------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 29cf0c268b190..b842bfc799ccb 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1185,8 +1185,6 @@ static void cx231xx_unregister_media_device(struct cx231xx *dev) */ void cx231xx_release_resources(struct cx231xx *dev) { - cx231xx_unregister_media_device(dev); - cx231xx_release_analog_resources(dev); cx231xx_remove_from_devlist(dev); @@ -1199,6 +1197,8 @@ void cx231xx_release_resources(struct cx231xx *dev) /* delete v4l2 device */ v4l2_device_unregister(&dev->v4l2_dev); + cx231xx_unregister_media_device(dev); + usb_put_dev(dev->udev); /* Mark device as unused */ @@ -1237,15 +1237,16 @@ static void cx231xx_media_device_register(struct cx231xx *dev, #endif } -static void cx231xx_create_media_graph(struct cx231xx *dev) +static int cx231xx_create_media_graph(struct cx231xx *dev) { #ifdef CONFIG_MEDIA_CONTROLLER struct media_device *mdev = dev->media_dev; struct media_entity *entity; struct media_entity *tuner = NULL, *decoder = NULL; + int ret; if (!mdev) - return; + return 0; media_device_for_each_entity(entity, mdev) { switch (entity->type) { @@ -1261,16 +1262,24 @@ static void cx231xx_create_media_graph(struct cx231xx *dev) /* Analog setup, using tuner as a link */ if (!decoder) - return; + return 0; - if (tuner) - media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0, - MEDIA_LNK_FL_ENABLED); - media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, - MEDIA_LNK_FL_ENABLED); - media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0, - MEDIA_LNK_FL_ENABLED); + if (tuner) { + ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0, + MEDIA_LNK_FL_ENABLED); + if (ret < 0) + return ret; + } + ret = media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, + MEDIA_LNK_FL_ENABLED); + if (ret < 0) + return ret; + ret = media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0, + MEDIA_LNK_FL_ENABLED); + if (ret < 0) + return ret; #endif + return 0; } /* @@ -1732,9 +1741,12 @@ static int cx231xx_usb_probe(struct usb_interface *interface, /* load other modules required */ request_modules(dev); - cx231xx_create_media_graph(dev); + retval = cx231xx_create_media_graph(dev); + if (retval < 0) { + cx231xx_release_resources(dev); + } - return 0; + return retval; err_video_alt: /* cx231xx_uninit_dev: */ cx231xx_close_extension(dev); -- GitLab From 4e26f3abafa9d0f635e105c8b9021f3b5bae6702 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 4 Sep 2015 16:08:02 -0300 Subject: [PATCH 2516/2855] [media] au0828: enforce check for graph creation If the graph creation fails, don't register the device. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/au0828-core.c | 58 +++++++++++++++++--------- 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 0d77e9cc303b4..27679e5cdca1a 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -172,9 +172,9 @@ static void au0828_usb_v4l2_release(struct v4l2_device *v4l2_dev) struct au0828_dev *dev = container_of(v4l2_dev, struct au0828_dev, v4l2_dev); - au0828_usb_v4l2_media_release(dev); v4l2_ctrl_handler_free(&dev->v4l2_ctrl_hdl); v4l2_device_unregister(&dev->v4l2_dev); + au0828_usb_v4l2_media_release(dev); au0828_usb_release(dev); } #endif @@ -253,16 +253,16 @@ static void au0828_media_device_register(struct au0828_dev *dev, } -static void au0828_create_media_graph(struct au0828_dev *dev) +static int au0828_create_media_graph(struct au0828_dev *dev) { #ifdef CONFIG_MEDIA_CONTROLLER struct media_device *mdev = dev->media_dev; struct media_entity *entity; struct media_entity *tuner = NULL, *decoder = NULL; - int i; + int i, ret; if (!mdev) - return; + return 0; media_device_for_each_entity(entity, mdev) { switch (entity->type) { @@ -279,15 +279,23 @@ static void au0828_create_media_graph(struct au0828_dev *dev) /* Something bad happened! */ if (!decoder) - return; - - if (tuner) - media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0, - MEDIA_LNK_FL_ENABLED); - media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, - MEDIA_LNK_FL_ENABLED); - media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0, - MEDIA_LNK_FL_ENABLED); + return -EINVAL; + + if (tuner) { + ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, + decoder, 0, + MEDIA_LNK_FL_ENABLED); + if (ret) + return ret; + } + ret = media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, + MEDIA_LNK_FL_ENABLED); + if (ret) + return ret; + ret = media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0, + MEDIA_LNK_FL_ENABLED); + if (ret) + return ret; for (i = 0; i < AU0828_MAX_INPUT; i++) { struct media_entity *ent = &dev->input_ent[i]; @@ -299,20 +307,27 @@ static void au0828_create_media_graph(struct au0828_dev *dev) case AU0828_VMUX_CABLE: case AU0828_VMUX_TELEVISION: case AU0828_VMUX_DVB: - if (tuner) - media_create_pad_link(ent, 0, tuner, - TUNER_PAD_RF_INPUT, - MEDIA_LNK_FL_ENABLED); + if (!tuner) + break; + + ret = media_create_pad_link(ent, 0, tuner, + TUNER_PAD_RF_INPUT, + MEDIA_LNK_FL_ENABLED); + if (ret) + return ret; break; case AU0828_VMUX_COMPOSITE: case AU0828_VMUX_SVIDEO: default: /* AU0828_VMUX_DEBUG */ /* FIXME: fix the decoder PAD */ - media_create_pad_link(ent, 0, decoder, 0, 0); + ret = media_create_pad_link(ent, 0, decoder, 0, 0); + if (ret) + return ret; break; } } #endif + return 0; } static int au0828_usb_probe(struct usb_interface *interface, @@ -427,7 +442,12 @@ static int au0828_usb_probe(struct usb_interface *interface, mutex_unlock(&dev->lock); - au0828_create_media_graph(dev); + retval = au0828_create_media_graph(dev); + if (retval) { + pr_err("%s() au0282_dev_register failed to create graph\n", + __func__); + au0828_usb_disconnect(interface); + } return retval; } -- GitLab From 77328043d9e6feb12e53a4fc5485cf664d2878e4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 4 Sep 2015 16:08:24 -0300 Subject: [PATCH 2517/2855] [media] media-entity: must check media_create_pad_link() Drivers should check if media_create_pad_link() actually worked. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 7128d3b0b8485..0c7390d2edaed 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -351,8 +351,9 @@ int media_entity_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads); void media_entity_cleanup(struct media_entity *entity); -int media_create_pad_link(struct media_entity *source, u16 source_pad, - struct media_entity *sink, u16 sink_pad, u32 flags); +__must_check int media_create_pad_link(struct media_entity *source, + u16 source_pad, struct media_entity *sink, + u16 sink_pad, u32 flags); void __media_entity_remove_links(struct media_entity *entity); void media_entity_remove_links(struct media_entity *entity); -- GitLab From 0e576b76f5470a2f8b2287958a2b9a3dd0f56f10 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 6 Sep 2015 09:33:39 -0300 Subject: [PATCH 2518/2855] [media] media-entity.h: rename entity.type to entity.function Entities should have one or more functions. Calling it as a type proofed to not be correct, as an entity could eventually have more than one type. So, rename the field as function. Please notice that this patch doesn't extend support for multiple function entities. Such change will happen when we have real case drivers using it. No functional changes. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/v4l2-framework.txt | 4 ++-- drivers/media/dvb-core/dvbdev.c | 14 +++++++------- drivers/media/dvb-frontends/au8522_decoder.c | 2 +- drivers/media/i2c/adp1653.c | 2 +- drivers/media/i2c/as3645a.c | 2 +- drivers/media/i2c/cx25840/cx25840-core.c | 2 +- drivers/media/i2c/lm3560.c | 2 +- drivers/media/i2c/lm3646.c | 2 +- drivers/media/i2c/m5mols/m5mols_core.c | 2 +- drivers/media/i2c/noon010pc30.c | 2 +- drivers/media/i2c/ov2659.c | 2 +- drivers/media/i2c/ov9650.c | 2 +- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 4 ++-- drivers/media/i2c/s5k4ecgx.c | 2 +- drivers/media/i2c/s5k5baf.c | 6 +++--- drivers/media/i2c/s5k6aa.c | 2 +- drivers/media/i2c/smiapp/smiapp-core.c | 2 +- drivers/media/media-device.c | 6 +++--- drivers/media/platform/xilinx/xilinx-dma.c | 2 +- drivers/media/usb/au0828/au0828-core.c | 2 +- drivers/media/usb/au0828/au0828-video.c | 8 ++++---- drivers/media/usb/cx231xx/cx231xx-cards.c | 2 +- drivers/media/usb/cx231xx/cx231xx-video.c | 2 +- drivers/media/v4l2-core/tuner-core.c | 2 +- drivers/media/v4l2-core/v4l2-dev.c | 14 +++++++------- drivers/media/v4l2-core/v4l2-flash-led-class.c | 2 +- drivers/media/v4l2-core/v4l2-subdev.c | 6 +++--- include/media/media-entity.h | 9 +++++---- 28 files changed, 55 insertions(+), 54 deletions(-) diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index 109cc37925344..2e0fc28fa12fe 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt @@ -303,8 +303,8 @@ calling media_entity_init(): err = media_entity_init(&sd->entity, npads, pads); The pads array must have been previously initialized. There is no need to -manually set the struct media_entity type and name fields, but the revision -field must be initialized if needed. +manually set the struct media_entity function and name fields, but the +revision field must be initialized if needed. A reference to the entity will be automatically acquired/released when the subdev device node (if any) is opened/closed. diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index bc650c637fc02..f6fc95d1345b7 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -242,7 +242,7 @@ static int dvb_create_tsout_entity(struct dvb_device *dvbdev, if (!entity->name) return -ENOMEM; - entity->type = MEDIA_ENT_T_DVB_TSOUT; + entity->function = MEDIA_ENT_T_DVB_TSOUT; pads->flags = MEDIA_PAD_FL_SINK; ret = media_entity_init(entity, 1, pads); @@ -315,18 +315,18 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev, switch (type) { case DVB_DEVICE_FRONTEND: - dvbdev->entity->type = MEDIA_ENT_T_DVB_DEMOD; + dvbdev->entity->function = MEDIA_ENT_T_DVB_DEMOD; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; break; case DVB_DEVICE_DEMUX: - dvbdev->entity->type = MEDIA_ENT_T_DVB_DEMUX; + dvbdev->entity->function = MEDIA_ENT_T_DVB_DEMUX; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; for (i = 1; i < npads; i++) dvbdev->pads[i].flags = MEDIA_PAD_FL_SOURCE; break; case DVB_DEVICE_CA: - dvbdev->entity->type = MEDIA_ENT_T_DVB_CA; + dvbdev->entity->function = MEDIA_ENT_T_DVB_CA; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; break; @@ -555,7 +555,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap) return 0; media_device_for_each_entity(entity, mdev) { - switch (entity->type) { + switch (entity->function) { case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: tuner = entity; break; @@ -594,7 +594,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap) /* Create demux links for each ringbuffer/pad */ if (demux) { media_device_for_each_entity(entity, mdev) { - if (entity->type == MEDIA_ENT_T_DVB_TSOUT) { + if (entity->function == MEDIA_ENT_T_DVB_TSOUT) { if (!strncmp(entity->name, DVR_TSOUT, strlen(DVR_TSOUT))) { ret = media_create_pad_link(demux, @@ -639,7 +639,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap) } media_device_for_each_entity(entity, mdev) { - if (entity->type == MEDIA_ENT_T_DVB_TSOUT) { + if (entity->function == MEDIA_ENT_T_DVB_TSOUT) { if (!strcmp(entity->name, DVR_TSOUT)) { link = media_create_intf_link(entity, intf, diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c index 580859c89da17..664ec0dcd02ac 100644 --- a/drivers/media/dvb-frontends/au8522_decoder.c +++ b/drivers/media/dvb-frontends/au8522_decoder.c @@ -766,7 +766,7 @@ static int au8522_probe(struct i2c_client *client, state->pads[AU8522_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; state->pads[AU8522_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; state->pads[AU8522_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_DECODER; ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), state->pads); diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c index 07e46b5b849cf..9d99182cd1653 100644 --- a/drivers/media/i2c/adp1653.c +++ b/drivers/media/i2c/adp1653.c @@ -516,7 +516,7 @@ static int adp1653_probe(struct i2c_client *client, if (ret < 0) goto free_and_quit; - flash->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + flash->subdev.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; return 0; diff --git a/drivers/media/i2c/as3645a.c b/drivers/media/i2c/as3645a.c index b83c7fc988aef..f45108c84f4d1 100644 --- a/drivers/media/i2c/as3645a.c +++ b/drivers/media/i2c/as3645a.c @@ -831,7 +831,7 @@ static int as3645a_probe(struct i2c_client *client, if (ret < 0) goto done; - flash->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + flash->subdev.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; mutex_init(&flash->power_lock); diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index 022ad5ae88699..73bd05ee2fee6 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -5211,7 +5211,7 @@ static int cx25840_probe(struct i2c_client *client, state->pads[CX25840_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; state->pads[CX25840_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; state->pads[CX25840_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_DECODER; ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), state->pads); diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c index 91c1ed27a458a..aa8b4832a1bc1 100644 --- a/drivers/media/i2c/lm3560.c +++ b/drivers/media/i2c/lm3560.c @@ -368,7 +368,7 @@ static int lm3560_subdev_init(struct lm3560_flash *flash, rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL); if (rval < 0) goto err_out; - flash->subdev_led[led_no].entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + flash->subdev_led[led_no].entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; return rval; diff --git a/drivers/media/i2c/lm3646.c b/drivers/media/i2c/lm3646.c index a037616bbab0e..a52cc3a6fb558 100644 --- a/drivers/media/i2c/lm3646.c +++ b/drivers/media/i2c/lm3646.c @@ -285,7 +285,7 @@ static int lm3646_subdev_init(struct lm3646_flash *flash) rval = media_entity_init(&flash->subdev_led.entity, 0, NULL); if (rval < 0) goto err_out; - flash->subdev_led.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + flash->subdev_led.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; return rval; err_out: diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c index 0788c1908f9c0..ae5645fe3a6ed 100644 --- a/drivers/media/i2c/m5mols/m5mols_core.c +++ b/drivers/media/i2c/m5mols/m5mols_core.c @@ -978,7 +978,7 @@ static int m5mols_probe(struct i2c_client *client, ret = media_entity_init(&sd->entity, 1, &info->pad); if (ret < 0) return ret; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; init_waitqueue_head(&info->irq_waitq); mutex_init(&info->lock); diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c index 2e614ad473f1f..0226fc6685291 100644 --- a/drivers/media/i2c/noon010pc30.c +++ b/drivers/media/i2c/noon010pc30.c @@ -779,7 +779,7 @@ static int noon010_probe(struct i2c_client *client, goto np_err; info->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, 1, &info->pad); if (ret < 0) goto np_err; diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index ea95f854a5195..8a2efe2a24c49 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1445,7 +1445,7 @@ static int ov2659_probe(struct i2c_client *client, #if defined(CONFIG_MEDIA_CONTROLLER) ov2659->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, 1, &ov2659->pad); if (ret < 0) { v4l2_ctrl_handler_free(&ov2659->ctrls); diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index b4c408f2a2b0d..27c4def7e4fcd 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -1500,7 +1500,7 @@ static int ov965x_probe(struct i2c_client *client, return ret; ov965x->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, 1, &ov965x->pad); if (ret < 0) return ret; diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index ee7404ee66597..dd48e35ede280 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1688,7 +1688,7 @@ static int s5c73m3_probe(struct i2c_client *client, state->sensor_pads[S5C73M3_JPEG_PAD].flags = MEDIA_PAD_FL_SOURCE; state->sensor_pads[S5C73M3_ISP_PAD].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS, state->sensor_pads); @@ -1704,7 +1704,7 @@ static int s5c73m3_probe(struct i2c_client *client, state->oif_pads[OIF_ISP_PAD].flags = MEDIA_PAD_FL_SINK; state->oif_pads[OIF_JPEG_PAD].flags = MEDIA_PAD_FL_SINK; state->oif_pads[OIF_SOURCE_PAD].flags = MEDIA_PAD_FL_SOURCE; - oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN; + oif_sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN; ret = media_entity_init(&oif_sd->entity, OIF_NUM_PADS, state->oif_pads); diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c index 445a89e30949d..026d087405373 100644 --- a/drivers/media/i2c/s5k4ecgx.c +++ b/drivers/media/i2c/s5k4ecgx.c @@ -961,7 +961,7 @@ static int s5k4ecgx_probe(struct i2c_client *client, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; priv->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, 1, &priv->pad); if (ret) return ret; diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 3e929858d5be1..1d47b30953a48 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -408,7 +408,7 @@ static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl) static inline bool s5k5baf_is_cis_subdev(struct v4l2_subdev *sd) { - return sd->entity.type == MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + return sd->entity.function == MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; } static inline struct s5k5baf *to_s5k5baf(struct v4l2_subdev *sd) @@ -1904,7 +1904,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; state->cis_pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad); if (ret < 0) goto err; @@ -1919,7 +1919,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state, state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK; state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN; ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads); if (!ret) diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index 31be29d250932..d7244234473e9 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c @@ -1577,7 +1577,7 @@ static int s5k6aa_probe(struct i2c_client *client, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad); if (ret) return ret; diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index df4f8824c344b..ef325b653697f 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2763,7 +2763,7 @@ static int smiapp_init(struct smiapp_sensor *sensor) dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile); - sensor->pixel_array->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sensor->pixel_array->sd.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; /* final steps */ smiapp_read_frame_fmt(sensor); diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 30cef8740afaa..4f8388423edce 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -108,7 +108,7 @@ static long media_device_enum_entities(struct media_device *mdev, u_ent.id = media_entity_id(ent); if (ent->name) strlcpy(u_ent.name, ent->name, sizeof(u_ent.name)); - u_ent.type = ent->type; + u_ent.type = ent->function; u_ent.revision = ent->revision; u_ent.flags = ent->flags; u_ent.group_id = ent->group_id; @@ -610,8 +610,8 @@ int __must_check media_device_register_entity(struct media_device *mdev, { int i; - if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN || - entity->type == MEDIA_ENT_T_UNKNOWN) + if (entity->function == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN || + entity->function == MEDIA_ENT_T_UNKNOWN) dev_warn(mdev->dev, "Entity type for entity %s was not initialized!\n", entity->name); diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index b3fb1570b1892..1f0043f3ec4dd 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -191,7 +191,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe, while ((entity = media_entity_graph_walk_next(&graph))) { struct xvip_dma *dma; - if (entity->type != MEDIA_ENT_T_V4L2_VIDEO) + if (entity->function != MEDIA_ENT_T_V4L2_VIDEO) continue; dma = to_xvip_dma(media_entity_to_video_device(entity)); diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 27679e5cdca1a..865d68dc4dc89 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -265,7 +265,7 @@ static int au0828_create_media_graph(struct au0828_dev *dev) return 0; media_device_for_each_entity(entity, mdev) { - switch (entity->type) { + switch (entity->function) { case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: tuner = entity; break; diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 75f2e02908f47..066ba4b7c746e 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1832,18 +1832,18 @@ static void au0828_analog_create_entities(struct au0828_dev *dev) switch (AUVI_INPUT(i).type) { case AU0828_VMUX_COMPOSITE: - ent->type = MEDIA_ENT_T_CONN_COMPOSITE; + ent->function = MEDIA_ENT_T_CONN_COMPOSITE; break; case AU0828_VMUX_SVIDEO: - ent->type = MEDIA_ENT_T_CONN_SVIDEO; + ent->function = MEDIA_ENT_T_CONN_SVIDEO; break; case AU0828_VMUX_CABLE: case AU0828_VMUX_TELEVISION: case AU0828_VMUX_DVB: - ent->type = MEDIA_ENT_T_CONN_RF; + ent->function = MEDIA_ENT_T_CONN_RF; break; default: /* AU0828_VMUX_DEBUG */ - ent->type = MEDIA_ENT_T_CONN_TEST; + ent->function = MEDIA_ENT_T_CONN_TEST; break; } diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index b842bfc799ccb..5062c42a694c2 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1249,7 +1249,7 @@ static int cx231xx_create_media_graph(struct cx231xx *dev) return 0; media_device_for_each_entity(entity, mdev) { - switch (entity->type) { + switch (entity->function) { case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: tuner = entity; break; diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index b5eb9f6138725..110359deab37f 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -119,7 +119,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev) * this should be enough for the actual needs. */ media_device_for_each_entity(entity, mdev) { - if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_DECODER) { + if (entity->function == MEDIA_ENT_T_V4L2_SUBDEV_DECODER) { decoder = entity; break; } diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index b90f2a52db963..e8fc5ec8fc353 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -698,7 +698,7 @@ register_client: #if defined(CONFIG_MEDIA_CONTROLLER) t->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK; t->pad[TUNER_PAD_IF_OUTPUT].flags = MEDIA_PAD_FL_SOURCE; - t->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_TUNER; + t->sd.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_TUNER; t->sd.entity.name = t->name; ret = media_entity_init(&t->sd.entity, TUNER_NUM_PADS, &t->pad[0]); diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index d36436582de96..965449958e970 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -197,7 +197,7 @@ static void v4l2_device_release(struct device *cd) if (v4l2_dev->mdev) { /* Remove interfaces and interface links */ media_devnode_remove(vdev->intf_devnode); - if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN) + if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN) media_device_unregister_entity(&vdev->entity); } #endif @@ -735,20 +735,20 @@ static int video_register_media_controller(struct video_device *vdev, int type) if (!vdev->v4l2_dev->mdev) return 0; - vdev->entity.type = MEDIA_ENT_T_UNKNOWN; + vdev->entity.function = MEDIA_ENT_T_UNKNOWN; switch (type) { case VFL_TYPE_GRABBER: intf_type = MEDIA_INTF_T_V4L_VIDEO; - vdev->entity.type = MEDIA_ENT_T_V4L2_VIDEO; + vdev->entity.function = MEDIA_ENT_T_V4L2_VIDEO; break; case VFL_TYPE_VBI: intf_type = MEDIA_INTF_T_V4L_VBI; - vdev->entity.type = MEDIA_ENT_T_V4L2_VBI; + vdev->entity.function = MEDIA_ENT_T_V4L2_VBI; break; case VFL_TYPE_SDR: intf_type = MEDIA_INTF_T_V4L_SWRADIO; - vdev->entity.type = MEDIA_ENT_T_V4L2_SWRADIO; + vdev->entity.function = MEDIA_ENT_T_V4L2_SWRADIO; break; case VFL_TYPE_RADIO: intf_type = MEDIA_INTF_T_V4L_RADIO; @@ -766,7 +766,7 @@ static int video_register_media_controller(struct video_device *vdev, int type) return 0; } - if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN) { + if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN) { vdev->entity.name = vdev->name; /* Needed just for backward compatibility with legacy MC API */ @@ -793,7 +793,7 @@ static int video_register_media_controller(struct video_device *vdev, int type) return -ENOMEM; } - if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN) { + if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN) { struct media_link *link; link = media_create_intf_link(&vdev->entity, diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c index 34c489fed55e7..cf7b3cb9a3736 100644 --- a/drivers/media/v4l2-core/v4l2-flash-led-class.c +++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c @@ -655,7 +655,7 @@ struct v4l2_flash *v4l2_flash_init( if (ret < 0) return ERR_PTR(ret); - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; ret = v4l2_flash_init_controls(v4l2_flash, config); if (ret < 0) diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index b3bcc8253182b..b440cb66669c7 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -535,9 +535,9 @@ v4l2_subdev_link_validate_get_format(struct media_pad *pad, return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt); } - WARN(pad->entity->type != MEDIA_ENT_T_V4L2_VIDEO, + WARN(pad->entity->function != MEDIA_ENT_T_V4L2_VIDEO, "Driver bug! Wrong media entity type 0x%08x, entity %s\n", - pad->entity->type, pad->entity->name); + pad->entity->function, pad->entity->name); return -EINVAL; } @@ -584,7 +584,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) sd->host_priv = NULL; #if defined(CONFIG_MEDIA_CONTROLLER) sd->entity.name = sd->name; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN; #endif } EXPORT_SYMBOL(v4l2_subdev_init); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 0c7390d2edaed..70ccd6cf14c1a 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -152,7 +152,8 @@ struct media_entity_operations { * * @graph_obj: Embedded structure containing the media object common data. * @name: Entity name. - * @type: Entity type, as defined in uapi/media.h (MEDIA_ENT_T_*) + * @function: Entity main function, as defined in uapi/media.h + * (MEDIA_ENT_F_*) * @revision: Entity revision - OBSOLETE - should be removed soon. * @flags: Entity flags, as defined in uapi/media.h (MEDIA_ENT_FL_*) * @group_id: Entity group ID - OBSOLETE - should be removed soon. @@ -179,7 +180,7 @@ struct media_entity_operations { struct media_entity { struct media_gobj graph_obj; /* must be first field in struct */ const char *name; - u32 type; + u32 function; u32 revision; unsigned long flags; u32 group_id; @@ -272,7 +273,7 @@ static inline bool is_media_entity_v4l2_io(struct media_entity *entity) if (!entity) return false; - switch (entity->type) { + switch (entity->function) { case MEDIA_ENT_T_V4L2_VIDEO: case MEDIA_ENT_T_V4L2_VBI: case MEDIA_ENT_T_V4L2_SWRADIO: @@ -287,7 +288,7 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) if (!entity) return false; - switch (entity->type) { + switch (entity->function) { case MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN: case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR: case MEDIA_ENT_T_V4L2_SUBDEV_FLASH: -- GitLab From d87cdb884486bfa795be99c83a5b3ac4d428ca84 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 6 Sep 2015 10:59:08 -0300 Subject: [PATCH 2519/2855] [media] media-device: export the entity function via new ioctl Now that entities have a main function, expose it via MEDIA_IOC_G_TOPOLOGY ioctl. Please notice that some entities may have secundary functions. Such use case will be addressed later, when we add support for the Media Controller properties. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 1 + include/uapi/linux/media.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 4f8388423edce..83525ac293284 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -263,6 +263,7 @@ static long __media_device_get_topology(struct media_device *mdev, /* Copy fields to userspace struct if not error */ memset(&uentity, 0, sizeof(uentity)); uentity.id = entity->graph_obj.id; + uentity.function = entity->function; strncpy(uentity.name, entity->name, sizeof(uentity.name)); diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index f9520225a211b..290dd5585dc80 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -276,7 +276,8 @@ struct media_links_enum { struct media_v2_entity { __u32 id; char name[64]; /* FIXME: move to a property? (RFC says so) */ - __u16 reserved[14]; + __u32 function; /* Main function of the entity */ + __u16 reserved[12]; }; /* Should match the specific fields at media_intf_devnode */ -- GitLab From 4ca72efaeffd0d244c44307abc9d4cb11f8ad475 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 10 Dec 2015 17:25:41 -0200 Subject: [PATCH 2520/2855] [media] uapi/media.h: Rename entities types to functions Rename the userspace types from MEDIA_ENT_T_ to MEDIA_ENT_F_ and add the backward compatibility bits. The changes at the .c files was generated by the following coccinelle script: @@ @@ -MEDIA_ENT_T_UNKNOWN +MEDIA_ENT_F_UNKNOWN @@ @@ -MEDIA_ENT_T_DVB_BASE +MEDIA_ENT_F_DVB_BASE @@ @@ -MEDIA_ENT_T_V4L2_BASE +MEDIA_ENT_F_V4L2_BASE @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_BASE +MEDIA_ENT_F_V4L2_SUBDEV_BASE @@ @@ -MEDIA_ENT_T_CONNECTOR_BASE +MEDIA_ENT_F_CONNECTOR_BASE @@ @@ -MEDIA_ENT_T_V4L2_VIDEO +MEDIA_ENT_F_IO_V4L @@ @@ -MEDIA_ENT_T_V4L2_VBI +MEDIA_ENT_F_IO_VBI @@ @@ -MEDIA_ENT_T_V4L2_SWRADIO +MEDIA_ENT_F_IO_SWRADIO @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN +MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN @@ @@ -MEDIA_ENT_T_CONN_RF +MEDIA_ENT_F_CONN_RF @@ @@ -MEDIA_ENT_T_CONN_SVIDEO +MEDIA_ENT_F_CONN_SVIDEO @@ @@ -MEDIA_ENT_T_CONN_COMPOSITE +MEDIA_ENT_F_CONN_COMPOSITE @@ @@ -MEDIA_ENT_T_CONN_TEST +MEDIA_ENT_F_CONN_TEST @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_SENSOR +MEDIA_ENT_F_CAM_SENSOR @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_FLASH +MEDIA_ENT_F_FLASH @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_LENS +MEDIA_ENT_F_LENS @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_DECODER +MEDIA_ENT_F_ATV_DECODER @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_TUNER +MEDIA_ENT_F_TUNER @@ @@ -MEDIA_ENT_T_DVB_DEMOD +MEDIA_ENT_F_DTV_DEMOD @@ @@ -MEDIA_ENT_T_DVB_DEMUX +MEDIA_ENT_F_TS_DEMUX @@ @@ -MEDIA_ENT_T_DVB_TSOUT +MEDIA_ENT_F_IO_DTV @@ @@ -MEDIA_ENT_T_DVB_CA +MEDIA_ENT_F_DTV_CA @@ @@ -MEDIA_ENT_T_DVB_NET_DECAP +MEDIA_ENT_F_DTV_NET_DECAP Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 20 +-- drivers/media/dvb-frontends/au8522_decoder.c | 2 +- drivers/media/i2c/adp1653.c | 2 +- drivers/media/i2c/adv7180.c | 2 +- drivers/media/i2c/as3645a.c | 2 +- drivers/media/i2c/cx25840/cx25840-core.c | 2 +- drivers/media/i2c/lm3560.c | 2 +- drivers/media/i2c/lm3646.c | 2 +- drivers/media/i2c/m5mols/m5mols_core.c | 2 +- drivers/media/i2c/noon010pc30.c | 2 +- drivers/media/i2c/ov2659.c | 2 +- drivers/media/i2c/ov9650.c | 2 +- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 4 +- drivers/media/i2c/s5k4ecgx.c | 2 +- drivers/media/i2c/s5k5baf.c | 6 +- drivers/media/i2c/s5k6aa.c | 2 +- drivers/media/i2c/smiapp/smiapp-core.c | 2 +- drivers/media/i2c/tvp514x.c | 2 +- drivers/media/i2c/tvp7002.c | 2 +- drivers/media/media-device.c | 4 +- drivers/media/platform/xilinx/xilinx-dma.c | 2 +- drivers/media/usb/au0828/au0828-core.c | 4 +- drivers/media/usb/au0828/au0828-video.c | 8 +- drivers/media/usb/cx231xx/cx231xx-cards.c | 4 +- drivers/media/usb/cx231xx/cx231xx-video.c | 2 +- drivers/media/v4l2-core/tuner-core.c | 2 +- drivers/media/v4l2-core/v4l2-dev.c | 14 +- .../media/v4l2-core/v4l2-flash-led-class.c | 2 +- drivers/media/v4l2-core/v4l2-subdev.c | 4 +- include/media/media-entity.h | 18 +-- include/uapi/linux/media.h | 122 +++++++++--------- 31 files changed, 127 insertions(+), 121 deletions(-) diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index f6fc95d1345b7..f64e8b3fb6870 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -242,7 +242,7 @@ static int dvb_create_tsout_entity(struct dvb_device *dvbdev, if (!entity->name) return -ENOMEM; - entity->function = MEDIA_ENT_T_DVB_TSOUT; + entity->function = MEDIA_ENT_F_IO_DTV; pads->flags = MEDIA_PAD_FL_SINK; ret = media_entity_init(entity, 1, pads); @@ -315,18 +315,18 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev, switch (type) { case DVB_DEVICE_FRONTEND: - dvbdev->entity->function = MEDIA_ENT_T_DVB_DEMOD; + dvbdev->entity->function = MEDIA_ENT_F_DTV_DEMOD; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; break; case DVB_DEVICE_DEMUX: - dvbdev->entity->function = MEDIA_ENT_T_DVB_DEMUX; + dvbdev->entity->function = MEDIA_ENT_F_TS_DEMUX; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; for (i = 1; i < npads; i++) dvbdev->pads[i].flags = MEDIA_PAD_FL_SOURCE; break; case DVB_DEVICE_CA: - dvbdev->entity->function = MEDIA_ENT_T_DVB_CA; + dvbdev->entity->function = MEDIA_ENT_F_DTV_CA; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; break; @@ -556,16 +556,16 @@ int dvb_create_media_graph(struct dvb_adapter *adap) media_device_for_each_entity(entity, mdev) { switch (entity->function) { - case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: + case MEDIA_ENT_F_TUNER: tuner = entity; break; - case MEDIA_ENT_T_DVB_DEMOD: + case MEDIA_ENT_F_DTV_DEMOD: demod = entity; break; - case MEDIA_ENT_T_DVB_DEMUX: + case MEDIA_ENT_F_TS_DEMUX: demux = entity; break; - case MEDIA_ENT_T_DVB_CA: + case MEDIA_ENT_F_DTV_CA: ca = entity; break; } @@ -594,7 +594,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap) /* Create demux links for each ringbuffer/pad */ if (demux) { media_device_for_each_entity(entity, mdev) { - if (entity->function == MEDIA_ENT_T_DVB_TSOUT) { + if (entity->function == MEDIA_ENT_F_IO_DTV) { if (!strncmp(entity->name, DVR_TSOUT, strlen(DVR_TSOUT))) { ret = media_create_pad_link(demux, @@ -639,7 +639,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap) } media_device_for_each_entity(entity, mdev) { - if (entity->function == MEDIA_ENT_T_DVB_TSOUT) { + if (entity->function == MEDIA_ENT_F_IO_DTV) { if (!strcmp(entity->name, DVR_TSOUT)) { link = media_create_intf_link(entity, intf, diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c index 664ec0dcd02ac..464a2beca30d7 100644 --- a/drivers/media/dvb-frontends/au8522_decoder.c +++ b/drivers/media/dvb-frontends/au8522_decoder.c @@ -766,7 +766,7 @@ static int au8522_probe(struct i2c_client *client, state->pads[AU8522_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; state->pads[AU8522_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; state->pads[AU8522_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_DECODER; + sd->entity.function = MEDIA_ENT_F_ATV_DECODER; ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), state->pads); diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c index 9d99182cd1653..7150f35d59354 100644 --- a/drivers/media/i2c/adp1653.c +++ b/drivers/media/i2c/adp1653.c @@ -516,7 +516,7 @@ static int adp1653_probe(struct i2c_client *client, if (ret < 0) goto free_and_quit; - flash->subdev.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + flash->subdev.entity.function = MEDIA_ENT_F_FLASH; return 0; diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index 0fca8677014c9..2ebe9efdfc1b0 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c @@ -1213,7 +1213,7 @@ static int adv7180_probe(struct i2c_client *client, goto err_unregister_vpp_client; state->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER; + sd->entity.flags |= MEDIA_ENT_F_ATV_DECODER; ret = media_entity_init(&sd->entity, 1, &state->pad); if (ret) goto err_free_ctrl; diff --git a/drivers/media/i2c/as3645a.c b/drivers/media/i2c/as3645a.c index f45108c84f4d1..b1bc4d0f76f24 100644 --- a/drivers/media/i2c/as3645a.c +++ b/drivers/media/i2c/as3645a.c @@ -831,7 +831,7 @@ static int as3645a_probe(struct i2c_client *client, if (ret < 0) goto done; - flash->subdev.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + flash->subdev.entity.function = MEDIA_ENT_F_FLASH; mutex_init(&flash->power_lock); diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index 73bd05ee2fee6..4d975aa5be36f 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -5211,7 +5211,7 @@ static int cx25840_probe(struct i2c_client *client, state->pads[CX25840_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; state->pads[CX25840_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; state->pads[CX25840_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_DECODER; + sd->entity.function = MEDIA_ENT_F_ATV_DECODER; ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), state->pads); diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c index aa8b4832a1bc1..98266f707ea00 100644 --- a/drivers/media/i2c/lm3560.c +++ b/drivers/media/i2c/lm3560.c @@ -368,7 +368,7 @@ static int lm3560_subdev_init(struct lm3560_flash *flash, rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL); if (rval < 0) goto err_out; - flash->subdev_led[led_no].entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + flash->subdev_led[led_no].entity.function = MEDIA_ENT_F_FLASH; return rval; diff --git a/drivers/media/i2c/lm3646.c b/drivers/media/i2c/lm3646.c index a52cc3a6fb558..ba5ee0d7a78e8 100644 --- a/drivers/media/i2c/lm3646.c +++ b/drivers/media/i2c/lm3646.c @@ -285,7 +285,7 @@ static int lm3646_subdev_init(struct lm3646_flash *flash) rval = media_entity_init(&flash->subdev_led.entity, 0, NULL); if (rval < 0) goto err_out; - flash->subdev_led.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + flash->subdev_led.entity.function = MEDIA_ENT_F_FLASH; return rval; err_out: diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c index ae5645fe3a6ed..bec5cea23b65e 100644 --- a/drivers/media/i2c/m5mols/m5mols_core.c +++ b/drivers/media/i2c/m5mols/m5mols_core.c @@ -978,7 +978,7 @@ static int m5mols_probe(struct i2c_client *client, ret = media_entity_init(&sd->entity, 1, &info->pad); if (ret < 0) return ret; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; init_waitqueue_head(&info->irq_waitq); mutex_init(&info->lock); diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c index 0226fc6685291..47ea3f79eacc4 100644 --- a/drivers/media/i2c/noon010pc30.c +++ b/drivers/media/i2c/noon010pc30.c @@ -779,7 +779,7 @@ static int noon010_probe(struct i2c_client *client, goto np_err; info->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, 1, &info->pad); if (ret < 0) goto np_err; diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index 8a2efe2a24c49..cf8e71610248d 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1445,7 +1445,7 @@ static int ov2659_probe(struct i2c_client *client, #if defined(CONFIG_MEDIA_CONTROLLER) ov2659->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, 1, &ov2659->pad); if (ret < 0) { v4l2_ctrl_handler_free(&ov2659->ctrls); diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index 27c4def7e4fcd..adb4aab45c109 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -1500,7 +1500,7 @@ static int ov965x_probe(struct i2c_client *client, return ret; ov965x->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, 1, &ov965x->pad); if (ret < 0) return ret; diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index dd48e35ede280..3d578f2ce7b2f 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1688,7 +1688,7 @@ static int s5c73m3_probe(struct i2c_client *client, state->sensor_pads[S5C73M3_JPEG_PAD].flags = MEDIA_PAD_FL_SOURCE; state->sensor_pads[S5C73M3_ISP_PAD].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS, state->sensor_pads); @@ -1704,7 +1704,7 @@ static int s5c73m3_probe(struct i2c_client *client, state->oif_pads[OIF_ISP_PAD].flags = MEDIA_PAD_FL_SINK; state->oif_pads[OIF_JPEG_PAD].flags = MEDIA_PAD_FL_SINK; state->oif_pads[OIF_SOURCE_PAD].flags = MEDIA_PAD_FL_SOURCE; - oif_sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN; + oif_sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; ret = media_entity_init(&oif_sd->entity, OIF_NUM_PADS, state->oif_pads); diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c index 026d087405373..bacec84e773f6 100644 --- a/drivers/media/i2c/s5k4ecgx.c +++ b/drivers/media/i2c/s5k4ecgx.c @@ -961,7 +961,7 @@ static int s5k4ecgx_probe(struct i2c_client *client, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; priv->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, 1, &priv->pad); if (ret) return ret; diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 1d47b30953a48..564938ab2abd9 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -408,7 +408,7 @@ static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl) static inline bool s5k5baf_is_cis_subdev(struct v4l2_subdev *sd) { - return sd->entity.function == MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + return sd->entity.function == MEDIA_ENT_F_CAM_SENSOR; } static inline struct s5k5baf *to_s5k5baf(struct v4l2_subdev *sd) @@ -1904,7 +1904,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; state->cis_pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad); if (ret < 0) goto err; @@ -1919,7 +1919,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state, state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK; state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN; + sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads); if (!ret) diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index d7244234473e9..d71d104441bd4 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c @@ -1577,7 +1577,7 @@ static int s5k6aa_probe(struct i2c_client *client, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad); if (ret) return ret; diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index ef325b653697f..3eaa69ee341b2 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2763,7 +2763,7 @@ static int smiapp_init(struct smiapp_sensor *sensor) dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile); - sensor->pixel_array->sd.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sensor->pixel_array->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; /* final steps */ smiapp_read_frame_fmt(sensor); diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index 11e426dbe8919..455dd4e6a1dad 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c @@ -1095,7 +1095,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) #if defined(CONFIG_MEDIA_CONTROLLER) decoder->pad.flags = MEDIA_PAD_FL_SOURCE; decoder->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - decoder->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER; + decoder->sd.entity.flags |= MEDIA_ENT_F_ATV_DECODER; ret = media_entity_init(&decoder->sd.entity, 1, &decoder->pad); if (ret < 0) { diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index a5ee2b8df4294..216a07956fe9e 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c @@ -1012,7 +1012,7 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id) #if defined(CONFIG_MEDIA_CONTROLLER) device->pad.flags = MEDIA_PAD_FL_SOURCE; device->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - device->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER; + device->sd.entity.flags |= MEDIA_ENT_F_ATV_DECODER; error = media_entity_init(&device->sd.entity, 1, &device->pad); if (error < 0) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 83525ac293284..f177d50c7a446 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -611,8 +611,8 @@ int __must_check media_device_register_entity(struct media_device *mdev, { int i; - if (entity->function == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN || - entity->function == MEDIA_ENT_T_UNKNOWN) + if (entity->function == MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN || + entity->function == MEDIA_ENT_F_UNKNOWN) dev_warn(mdev->dev, "Entity type for entity %s was not initialized!\n", entity->name); diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index 1f0043f3ec4dd..b69c9630114da 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -191,7 +191,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe, while ((entity = media_entity_graph_walk_next(&graph))) { struct xvip_dma *dma; - if (entity->function != MEDIA_ENT_T_V4L2_VIDEO) + if (entity->function != MEDIA_ENT_F_IO_V4L) continue; dma = to_xvip_dma(media_entity_to_video_device(entity)); diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 865d68dc4dc89..1b207fa16a55a 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -266,10 +266,10 @@ static int au0828_create_media_graph(struct au0828_dev *dev) media_device_for_each_entity(entity, mdev) { switch (entity->function) { - case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: + case MEDIA_ENT_F_TUNER: tuner = entity; break; - case MEDIA_ENT_T_V4L2_SUBDEV_DECODER: + case MEDIA_ENT_F_ATV_DECODER: decoder = entity; break; } diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 066ba4b7c746e..839361c035ff3 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1832,18 +1832,18 @@ static void au0828_analog_create_entities(struct au0828_dev *dev) switch (AUVI_INPUT(i).type) { case AU0828_VMUX_COMPOSITE: - ent->function = MEDIA_ENT_T_CONN_COMPOSITE; + ent->function = MEDIA_ENT_F_CONN_COMPOSITE; break; case AU0828_VMUX_SVIDEO: - ent->function = MEDIA_ENT_T_CONN_SVIDEO; + ent->function = MEDIA_ENT_F_CONN_SVIDEO; break; case AU0828_VMUX_CABLE: case AU0828_VMUX_TELEVISION: case AU0828_VMUX_DVB: - ent->function = MEDIA_ENT_T_CONN_RF; + ent->function = MEDIA_ENT_F_CONN_RF; break; default: /* AU0828_VMUX_DEBUG */ - ent->function = MEDIA_ENT_T_CONN_TEST; + ent->function = MEDIA_ENT_F_CONN_TEST; break; } diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 5062c42a694c2..0e1efc59ff58d 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1250,10 +1250,10 @@ static int cx231xx_create_media_graph(struct cx231xx *dev) media_device_for_each_entity(entity, mdev) { switch (entity->function) { - case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: + case MEDIA_ENT_F_TUNER: tuner = entity; break; - case MEDIA_ENT_T_V4L2_SUBDEV_DECODER: + case MEDIA_ENT_F_ATV_DECODER: decoder = entity; break; } diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 110359deab37f..905ccd7cbc6da 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -119,7 +119,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev) * this should be enough for the actual needs. */ media_device_for_each_entity(entity, mdev) { - if (entity->function == MEDIA_ENT_T_V4L2_SUBDEV_DECODER) { + if (entity->function == MEDIA_ENT_F_ATV_DECODER) { decoder = entity; break; } diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index e8fc5ec8fc353..05fc4df61b85f 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -698,7 +698,7 @@ register_client: #if defined(CONFIG_MEDIA_CONTROLLER) t->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK; t->pad[TUNER_PAD_IF_OUTPUT].flags = MEDIA_PAD_FL_SOURCE; - t->sd.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_TUNER; + t->sd.entity.function = MEDIA_ENT_F_TUNER; t->sd.entity.name = t->name; ret = media_entity_init(&t->sd.entity, TUNER_NUM_PADS, &t->pad[0]); diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 965449958e970..ed96642c27bf7 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -197,7 +197,7 @@ static void v4l2_device_release(struct device *cd) if (v4l2_dev->mdev) { /* Remove interfaces and interface links */ media_devnode_remove(vdev->intf_devnode); - if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN) + if (vdev->entity.function != MEDIA_ENT_F_UNKNOWN) media_device_unregister_entity(&vdev->entity); } #endif @@ -735,20 +735,20 @@ static int video_register_media_controller(struct video_device *vdev, int type) if (!vdev->v4l2_dev->mdev) return 0; - vdev->entity.function = MEDIA_ENT_T_UNKNOWN; + vdev->entity.function = MEDIA_ENT_F_UNKNOWN; switch (type) { case VFL_TYPE_GRABBER: intf_type = MEDIA_INTF_T_V4L_VIDEO; - vdev->entity.function = MEDIA_ENT_T_V4L2_VIDEO; + vdev->entity.function = MEDIA_ENT_F_IO_V4L; break; case VFL_TYPE_VBI: intf_type = MEDIA_INTF_T_V4L_VBI; - vdev->entity.function = MEDIA_ENT_T_V4L2_VBI; + vdev->entity.function = MEDIA_ENT_F_IO_VBI; break; case VFL_TYPE_SDR: intf_type = MEDIA_INTF_T_V4L_SWRADIO; - vdev->entity.function = MEDIA_ENT_T_V4L2_SWRADIO; + vdev->entity.function = MEDIA_ENT_F_IO_SWRADIO; break; case VFL_TYPE_RADIO: intf_type = MEDIA_INTF_T_V4L_RADIO; @@ -766,7 +766,7 @@ static int video_register_media_controller(struct video_device *vdev, int type) return 0; } - if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN) { + if (vdev->entity.function != MEDIA_ENT_F_UNKNOWN) { vdev->entity.name = vdev->name; /* Needed just for backward compatibility with legacy MC API */ @@ -793,7 +793,7 @@ static int video_register_media_controller(struct video_device *vdev, int type) return -ENOMEM; } - if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN) { + if (vdev->entity.function != MEDIA_ENT_F_UNKNOWN) { struct media_link *link; link = media_create_intf_link(&vdev->entity, diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c index cf7b3cb9a3736..5c686a24712ba 100644 --- a/drivers/media/v4l2-core/v4l2-flash-led-class.c +++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c @@ -655,7 +655,7 @@ struct v4l2_flash *v4l2_flash_init( if (ret < 0) return ERR_PTR(ret); - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + sd->entity.function = MEDIA_ENT_F_FLASH; ret = v4l2_flash_init_controls(v4l2_flash, config); if (ret < 0) diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index b440cb66669c7..d630838031447 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -535,7 +535,7 @@ v4l2_subdev_link_validate_get_format(struct media_pad *pad, return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt); } - WARN(pad->entity->function != MEDIA_ENT_T_V4L2_VIDEO, + WARN(pad->entity->function != MEDIA_ENT_F_IO_V4L, "Driver bug! Wrong media entity type 0x%08x, entity %s\n", pad->entity->function, pad->entity->name); @@ -584,7 +584,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) sd->host_priv = NULL; #if defined(CONFIG_MEDIA_CONTROLLER) sd->entity.name = sd->name; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN; + sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; #endif } EXPORT_SYMBOL(v4l2_subdev_init); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 70ccd6cf14c1a..df84e8eeb24b7 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -274,9 +274,9 @@ static inline bool is_media_entity_v4l2_io(struct media_entity *entity) return false; switch (entity->function) { - case MEDIA_ENT_T_V4L2_VIDEO: - case MEDIA_ENT_T_V4L2_VBI: - case MEDIA_ENT_T_V4L2_SWRADIO: + case MEDIA_ENT_F_IO_V4L: + case MEDIA_ENT_F_IO_VBI: + case MEDIA_ENT_F_IO_SWRADIO: return true; default: return false; @@ -289,12 +289,12 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) return false; switch (entity->function) { - case MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN: - case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR: - case MEDIA_ENT_T_V4L2_SUBDEV_FLASH: - case MEDIA_ENT_T_V4L2_SUBDEV_LENS: - case MEDIA_ENT_T_V4L2_SUBDEV_DECODER: - case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: + case MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN: + case MEDIA_ENT_F_CAM_SENSOR: + case MEDIA_ENT_F_FLASH: + case MEDIA_ENT_F_LENS: + case MEDIA_ENT_F_ATV_DECODER: + case MEDIA_ENT_F_TUNER: return true; default: diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 290dd5585dc80..ff6a8010c5200 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -46,87 +46,93 @@ struct media_device_info { * Initial value to be used when a new entity is created * Drivers should change it to something useful */ -#define MEDIA_ENT_T_UNKNOWN 0x00000000 +#define MEDIA_ENT_F_UNKNOWN 0x00000000 /* - * Base numbers for entity types + * Base number ranges for entity functions * - * Please notice that the huge gap of 16 bits for each base is overkill! - * 8 bits is more than enough to avoid starving entity types for each - * subsystem. - * - * However, It is kept this way just to avoid binary breakages with the - * namespace provided on legacy versions of this header. + * NOTE: those ranges and entity function number are phased just to + * make it easier to maintain this file. Userspace should not rely on + * the ranges to identify a group of function types, as newer + * functions can be added with any name within the full u32 range. */ -#define MEDIA_ENT_T_DVB_BASE 0x00000000 -#define MEDIA_ENT_T_V4L2_BASE 0x00010000 -#define MEDIA_ENT_T_V4L2_SUBDEV_BASE 0x00020000 -#define MEDIA_ENT_T_CONNECTOR_BASE 0x00030000 +#define MEDIA_ENT_F_BASE 0x00000000 +#define MEDIA_ENT_F_OLD_BASE 0x00010000 +#define MEDIA_ENT_F_OLD_SUBDEV_BASE 0x00020000 /* - * V4L2 entities - Those are used for DMA (mmap/DMABUF) and - * read()/write() data I/O associated with the V4L2 devnodes. + * DVB entities */ -#define MEDIA_ENT_T_V4L2_VIDEO (MEDIA_ENT_T_V4L2_BASE + 1) - /* - * Please notice that numbers between MEDIA_ENT_T_V4L2_BASE + 2 and - * MEDIA_ENT_T_V4L2_BASE + 4 can't be used, as those values used - * to be declared for FB, ALSA and DVB entities. - * As those values were never actually used in practice, we're just - * adding them as backward compatibility macros and keeping the - * numberspace clean here. This way, we avoid breaking compilation, - * in the case of having some userspace application using the old - * symbols. - */ -#define MEDIA_ENT_T_V4L2_VBI (MEDIA_ENT_T_V4L2_BASE + 5) -#define MEDIA_ENT_T_V4L2_SWRADIO (MEDIA_ENT_T_V4L2_BASE + 6) - -/* V4L2 Sub-device entities */ +#define MEDIA_ENT_F_DTV_DEMOD (MEDIA_ENT_F_BASE + 1) +#define MEDIA_ENT_F_TS_DEMUX (MEDIA_ENT_F_BASE + 2) +#define MEDIA_ENT_F_DTV_CA (MEDIA_ENT_F_BASE + 3) +#define MEDIA_ENT_F_DTV_NET_DECAP (MEDIA_ENT_F_BASE + 4) /* + * Connectors + */ +#define MEDIA_ENT_F_CONN_RF (MEDIA_ENT_F_BASE + 21) +#define MEDIA_ENT_F_CONN_SVIDEO (MEDIA_ENT_F_BASE + 22) +#define MEDIA_ENT_F_CONN_COMPOSITE (MEDIA_ENT_F_BASE + 23) + /* For internal test signal generators and other debug connectors */ +#define MEDIA_ENT_F_CONN_TEST (MEDIA_ENT_F_BASE + 24) + +/* + * I/O entities + */ +#define MEDIA_ENT_F_IO_DTV (MEDIA_ENT_F_BASE + 31) +#define MEDIA_ENT_F_IO_VBI (MEDIA_ENT_F_BASE + 32) +#define MEDIA_ENT_F_IO_SWRADIO (MEDIA_ENT_F_BASE + 33) + +/* + * Don't touch on those. The ranges MEDIA_ENT_F_OLD_BASE and + * MEDIA_ENT_F_OLD_SUBDEV_BASE are kept to keep backward compatibility + * with the legacy v1 API.The number range is out of range by purpose: + * several previously reserved numbers got excluded from this range. + * * Subdevs are initialized with MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, * in order to preserve backward compatibility. * Drivers should change to the proper subdev type before * registering the entity. */ -#define MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN MEDIA_ENT_T_V4L2_SUBDEV_BASE - -#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 1) -#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 2) -#define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 3) - /* A converter of analogue video to its digital representation. */ -#define MEDIA_ENT_T_V4L2_SUBDEV_DECODER (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 4) - /* Tuner entity is actually both V4L2 and DVB subdev */ -#define MEDIA_ENT_T_V4L2_SUBDEV_TUNER (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 5) - -/* DVB entities */ -#define MEDIA_ENT_T_DVB_DEMOD (MEDIA_ENT_T_DVB_BASE + 1) -#define MEDIA_ENT_T_DVB_DEMUX (MEDIA_ENT_T_DVB_BASE + 2) -#define MEDIA_ENT_T_DVB_TSOUT (MEDIA_ENT_T_DVB_BASE + 3) -#define MEDIA_ENT_T_DVB_CA (MEDIA_ENT_T_DVB_BASE + 4) -#define MEDIA_ENT_T_DVB_NET_DECAP (MEDIA_ENT_T_DVB_BASE + 5) - -/* Connectors */ -#define MEDIA_ENT_T_CONN_RF (MEDIA_ENT_T_CONNECTOR_BASE + 1) -#define MEDIA_ENT_T_CONN_SVIDEO (MEDIA_ENT_T_CONNECTOR_BASE + 2) -#define MEDIA_ENT_T_CONN_COMPOSITE (MEDIA_ENT_T_CONNECTOR_BASE + 3) -/* For internal test signal generators and other debug connectors */ -#define MEDIA_ENT_T_CONN_TEST (MEDIA_ENT_T_CONNECTOR_BASE + 4) + +#define MEDIA_ENT_F_IO_V4L (MEDIA_ENT_F_OLD_BASE + 1) + +#define MEDIA_ENT_F_CAM_SENSOR (MEDIA_ENT_F_OLD_SUBDEV_BASE + 1) +#define MEDIA_ENT_F_FLASH (MEDIA_ENT_F_OLD_SUBDEV_BASE + 2) +#define MEDIA_ENT_F_LENS (MEDIA_ENT_F_OLD_SUBDEV_BASE + 3) +#define MEDIA_ENT_F_ATV_DECODER (MEDIA_ENT_F_OLD_SUBDEV_BASE + 4) +#define MEDIA_ENT_F_TUNER (MEDIA_ENT_F_OLD_SUBDEV_BASE + 5) + +#define MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN MEDIA_ENT_F_OLD_SUBDEV_BASE #ifndef __KERNEL__ -/* Legacy symbols used to avoid userspace compilation breakages */ + +/* + * Legacy symbols used to avoid userspace compilation breakages + * + * Those symbols map the entity function into types and should be + * used only on legacy programs for legacy hardware. Don't rely + * on those for MEDIA_IOC_G_TOPOLOGY. + */ #define MEDIA_ENT_TYPE_SHIFT 16 #define MEDIA_ENT_TYPE_MASK 0x00ff0000 #define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff -#define MEDIA_ENT_T_DEVNODE MEDIA_ENT_T_V4L2_BASE -#define MEDIA_ENT_T_V4L2_SUBDEV MEDIA_ENT_T_V4L2_SUBDEV_BASE - -#define MEDIA_ENT_T_DEVNODE_V4L MEDIA_ENT_T_V4L2_VIDEO - +#define MEDIA_ENT_T_DEVNODE MEDIA_ENT_F_OLD_BASE +#define MEDIA_ENT_T_DEVNODE_V4L MEDIA_ENT_F_IO_V4L #define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_T_DEVNODE + 2) #define MEDIA_ENT_T_DEVNODE_ALSA (MEDIA_ENT_T_DEVNODE + 3) #define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4) + +#define MEDIA_ENT_T_UNKNOWN MEDIA_ENT_F_UNKNOWN +#define MEDIA_ENT_T_V4L2_VIDEO MEDIA_ENT_F_IO_V4L +#define MEDIA_ENT_T_V4L2_SUBDEV MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN +#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR MEDIA_ENT_F_CAM_SENSOR +#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH MEDIA_ENT_F_FLASH +#define MEDIA_ENT_T_V4L2_SUBDEV_LENS MEDIA_ENT_F_LENS +#define MEDIA_ENT_T_V4L2_SUBDEV_DECODER MEDIA_ENT_F_ATV_DECODER +#define MEDIA_ENT_T_V4L2_SUBDEV_TUNER MEDIA_ENT_F_TUNER #endif /* Entity flags */ -- GitLab From bd3ed12be1e1262adcb733bcf63e5da4d8772774 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 6 Sep 2015 12:30:43 -0300 Subject: [PATCH 2521/2855] [media] DocBook: update entities documentation Due to the rename, the documentation became outdated. Update it to reflect what's there at media.h. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/v4l/media-ioc-enum-entities.xml | 64 ++++++++++++------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml index 13d0b5891fb76..27f8817e7abe9 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml @@ -179,56 +179,72 @@ - MEDIA_ENT_T_UNKNOWN and MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN + MEDIA_ENT_F_UNKNOWN and MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN Unknown entity. That generally indicates that a driver didn't initialize properly the entity, with is a Kernel bug - MEDIA_ENT_T_V4L2_VIDEO - V4L video streaming input or output entity + MEDIA_ENT_F_IO_V4L + Data streaming input and/or output entity. - MEDIA_ENT_T_V4L2_VBI + MEDIA_ENT_F_IO_VBI V4L VBI streaming input or output entity - MEDIA_ENT_T_V4L2_SWRADIO + MEDIA_ENT_F_IO_SWRADIO V4L Software Digital Radio (SDR) streaming input or output entity - MEDIA_ENT_T_DVB_DEMOD - DVB demodulator entity + MEDIA_ENT_F_IO_DTV + DVB Digital TV streaming input or output entity - MEDIA_ENT_T_DVB_DEMUX - DVB demux entity. Can be implemented in hardware or in Kernelspace + MEDIA_ENT_F_DTV_DEMOD + Digital TV demodulator entity. - MEDIA_ENT_T_DVB_TSOUT - DVB Transport Stream output entity + MEDIA_ENT_F_MPEG_TS_DEMUX + MPEG Transport stream demux entity. Could be implemented on hardware or in Kernelspace by the Linux DVB subsystem. - MEDIA_ENT_T_DVB_CA - DVB Conditional Access module (CAM) entity + MEDIA_ENT_F_DTV_CA + Digital TV Conditional Access module (CAM) entity - MEDIA_ENT_T_DVB_DEMOD_NET_DECAP - DVB network ULE/MLE de-encapsulation entity. Can be implemented in hardware or in Kernelspace + MEDIA_ENT_F_DTV_NET_DECAP + Digital TV network ULE/MLE desencapsulation entity. Could be implemented on hardware or in Kernelspace - MEDIA_ENT_T_V4L2_SUBDEV_SENSOR - Camera image sensor entity + MEDIA_ENT_F_CONN_RF + Connector for a Radio Frequency (RF) signal. - MEDIA_ENT_T_V4L2_SUBDEV_FLASH - Flash controller entity + MEDIA_ENT_F_CONN_SVIDEO + Connector for a S-Video signal. - MEDIA_ENT_T_V4L2_SUBDEV_LENS - Lens controller entity + MEDIA_ENT_F_CONN_COMPOSITE + Connector for a RGB composite signal. - MEDIA_ENT_T_V4L2_SUBDEV_DECODER + MEDIA_ENT_F_CONN_TEST + Connector for a test generator. + + + MEDIA_ENT_F_CAM_SENSOR + Camera video sensor entity. + + + MEDIA_ENT_F_FLASH + Flash controller entity. + + + MEDIA_ENT_F_LENS + Lens controller entity. + + + MEDIA_ENT_F_ATV_DECODER Analog video decoder, the basic function of the video decoder is to accept analogue video from a wide variety of sources such as broadcast, DVD players, cameras and video cassette recorders, in @@ -238,8 +254,8 @@ signals. - MEDIA_ENT_T_V4L2_SUBDEV_TUNER - Digital TV, analog TV, radio and/or software radio tuner + MEDIA_ENT_F_TUNER + Digital TV, analog TV, radio and/or software radio tuner. -- GitLab From 17813e2aa2f745545643df24af8f308bc36a04b0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 6 Sep 2015 13:28:48 -0300 Subject: [PATCH 2522/2855] [media] dvbdev: move indirect links on dvr/demux to a separate function Cleanup the code a little bit by moving the routine that creates links between DVR and demux to the I/O entitis into a separate function. While here, fix the code to use strncmp() instead of strcmp(). Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 50 ++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index f64e8b3fb6870..d51a328bdcf98 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -540,6 +540,28 @@ EXPORT_SYMBOL(dvb_unregister_device); #ifdef CONFIG_MEDIA_CONTROLLER_DVB + +static int dvb_create_io_intf_links(struct dvb_adapter *adap, + struct media_interface *intf, + char *name) +{ + struct media_device *mdev = adap->mdev; + struct media_entity *entity; + struct media_link *link; + + media_device_for_each_entity(entity, mdev) { + if (entity->function == MEDIA_ENT_F_IO_DTV) { + if (strncmp(entity->name, name, strlen(name))) + continue; + link = media_create_intf_link(entity, intf, + MEDIA_LNK_FL_ENABLED); + if (!link) + return -ENOMEM; + } + } + return 0; +} + int dvb_create_media_graph(struct dvb_adapter *adap) { struct media_device *mdev = adap->mdev; @@ -637,25 +659,15 @@ int dvb_create_media_graph(struct dvb_adapter *adap) if (!link) return -ENOMEM; } - - media_device_for_each_entity(entity, mdev) { - if (entity->function == MEDIA_ENT_F_IO_DTV) { - if (!strcmp(entity->name, DVR_TSOUT)) { - link = media_create_intf_link(entity, - intf, - MEDIA_LNK_FL_ENABLED); - if (!link) - return -ENOMEM; - } - if (!strcmp(entity->name, DEMUX_TSOUT)) { - link = media_create_intf_link(entity, - intf, - MEDIA_LNK_FL_ENABLED); - if (!link) - return -ENOMEM; - } - break; - } + if (intf->type == MEDIA_INTF_T_DVB_DVR) { + ret = dvb_create_io_intf_links(adap, intf, DVR_TSOUT); + if (ret) + return ret; + } + if (intf->type == MEDIA_INTF_T_DVB_DEMUX) { + ret = dvb_create_io_intf_links(adap, intf, DEMUX_TSOUT); + if (ret) + return ret; } } return 0; -- GitLab From 8ed071426ee48879024c350ae92fc41062039b13 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 6 Sep 2015 13:38:23 -0300 Subject: [PATCH 2523/2855] [media] dvbdev: Don't create indirect links Indirect links are those whose interface indirectly controls other functions. There are two interfaces that have indirect controls at the DVB side: - the network interface, which also controls the demux; - the DVR interface which also controls the demux. One could argue that the frontend control to the tuner is indirect. Well, that's debatable. There's no way to create subdev interfaces for tuner and demod, as those devices are tightly coupled. So, it was decided that just one interface is the best to control both entities, and there's no plan (or easy way) to decouple both. So, the DVB frontend interface should link to both entities. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index d51a328bdcf98..cc52c24bff725 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -637,7 +637,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap) } } - /* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */ + /* Create interface links for FE->tuner, DVR->demux and CA->ca */ media_device_for_each_intf(intf, mdev) { if (intf->type == MEDIA_INTF_T_DVB_CA && ca) { link = media_create_intf_link(ca, intf, @@ -652,13 +652,19 @@ int dvb_create_media_graph(struct dvb_adapter *adap) if (!link) return -ENOMEM; } - +#if 0 + /* + * Indirect link - let's not create yet, as we don't know how + * to handle indirect links, nor if this will + * actually be needed. + */ if (intf->type == MEDIA_INTF_T_DVB_DVR && demux) { link = media_create_intf_link(demux, intf, MEDIA_LNK_FL_ENABLED); if (!link) return -ENOMEM; } +#endif if (intf->type == MEDIA_INTF_T_DVB_DVR) { ret = dvb_create_io_intf_links(adap, intf, DVR_TSOUT); if (ret) -- GitLab From 0b3b72df9018c0386293c2f529b91ed17448288a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 9 Sep 2015 08:19:25 -0300 Subject: [PATCH 2524/2855] [media] media_entity: remove gfp_flags argument We should not be creating device nodes at IRQ contexts. So, the only flags we'll be using will be GFP_KERNEL. Let's remove the gfp_flags, in order to make the interface simpler. If we ever need it, it would be easy to revert those changes. While here, remove an extra blank line. Suggested-by: Sakari Ailus Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 3 +-- drivers/media/media-entity.c | 5 ++--- drivers/media/v4l2-core/v4l2-dev.c | 3 +-- include/media/media-entity.h | 4 +--- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index cc52c24bff725..1d4e35693d09d 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -394,8 +394,7 @@ static int dvb_register_media_device(struct dvb_device *dvbdev, dvbdev->intf_devnode = media_devnode_create(dvbdev->adapter->mdev, intf_type, 0, - DVB_MAJOR, minor, - GFP_KERNEL); + DVB_MAJOR, minor); if (!dvbdev->intf_devnode) return -ENOMEM; diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 246d7e65adedb..5f61642b2a977 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -866,12 +866,11 @@ static void media_interface_init(struct media_device *mdev, struct media_intf_devnode *media_devnode_create(struct media_device *mdev, u32 type, u32 flags, - u32 major, u32 minor, - gfp_t gfp_flags) + u32 major, u32 minor) { struct media_intf_devnode *devnode; - devnode = kzalloc(sizeof(*devnode), gfp_flags); + devnode = kzalloc(sizeof(*devnode), GFP_KERNEL); if (!devnode) return NULL; diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index ed96642c27bf7..d8e5994cccf1a 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -786,8 +786,7 @@ static int video_register_media_controller(struct video_device *vdev, int type) vdev->intf_devnode = media_devnode_create(vdev->v4l2_dev->mdev, intf_type, 0, VIDEO_MAJOR, - vdev->minor, - GFP_KERNEL); + vdev->minor); if (!vdev->intf_devnode) { media_device_unregister_entity(&vdev->entity); return -ENOMEM; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index df84e8eeb24b7..cd3f3a77df2d7 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -71,7 +71,6 @@ struct media_gobj { struct list_head list; }; - struct media_pipeline { }; @@ -378,8 +377,7 @@ void media_entity_pipeline_stop(struct media_entity *entity); struct media_intf_devnode * __must_check media_devnode_create(struct media_device *mdev, u32 type, u32 flags, - u32 major, u32 minor, - gfp_t gfp_flags); + u32 major, u32 minor); void media_devnode_remove(struct media_intf_devnode *devnode); struct media_link * __must_check media_create_intf_link(struct media_entity *entity, -- GitLab From 9033b1a47038fdba388fc13613de23508dccb075 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 9 Sep 2015 08:23:51 -0300 Subject: [PATCH 2525/2855] [media] media-device: use unsigned ints on some places The entity->num_pads are defined as u16. So, better to use an unsigned int, as this prevents additional warnings when W=2 (or W=1 on some architectures). The "i" counter at __media_device_get_topology() is also a monotonic counter that should never be below zero. So, make it unsigned too. Suggested-by: Sakari Ailus Acked-by: Hans Verkuil Reviewed-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index f177d50c7a446..3d0a77c1c8998 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -243,7 +243,8 @@ static long __media_device_get_topology(struct media_device *mdev, struct media_v2_interface uintf; struct media_v2_pad upad; struct media_v2_link ulink; - int ret = 0, i; + unsigned int i; + int ret = 0; topo->topology_version = mdev->topology_version; @@ -609,7 +610,7 @@ EXPORT_SYMBOL_GPL(media_device_unregister); int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity) { - int i; + unsigned int i; if (entity->function == MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN || entity->function == MEDIA_ENT_F_UNKNOWN) @@ -646,10 +647,10 @@ EXPORT_SYMBOL_GPL(media_device_register_entity); */ void media_device_unregister_entity(struct media_entity *entity) { - int i; struct media_device *mdev = entity->graph_obj.mdev; struct media_link *link, *tmp; struct media_interface *intf; + unsigned int i; if (mdev == NULL) return; -- GitLab From db141a355d8914fe80c9e4a6c25c686f64d7e905 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 8 Sep 2015 14:10:56 -0300 Subject: [PATCH 2526/2855] [media] media-entity: init pads on entity init if was registered before If an entity is registered with a media device before is initialized with media_device_register_entity(), the number of pads won't be set so media_device_register_entity() won't create pad objects and add it to the media device pads list. Do this at entity initialization time if the entity was registered before so the graph is complete and correct regardless of the order in which the entities are initialized and registered. Suggested-by: Mauro Carvalho Chehab Signed-off-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 5f61642b2a977..07f2dc6c2df6b 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -222,6 +222,7 @@ int media_entity_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads) { + struct media_device *mdev = entity->graph_obj.mdev; unsigned int i; entity->group_id = 0; @@ -230,11 +231,20 @@ media_entity_init(struct media_entity *entity, u16 num_pads, entity->num_pads = num_pads; entity->pads = pads; + if (mdev) + spin_lock(&mdev->lock); + for (i = 0; i < num_pads; i++) { pads[i].entity = entity; pads[i].index = i; + if (mdev) + media_gobj_init(mdev, MEDIA_GRAPH_PAD, + &entity->pads[i].graph_obj); } + if (mdev) + spin_unlock(&mdev->lock); + return 0; } EXPORT_SYMBOL_GPL(media_entity_init); -- GitLab From 497e80cdf98ac72aaa1a4860b833920e1ba23aef Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 07:23:09 -0200 Subject: [PATCH 2527/2855] [media] media-device: put headers in alphabetic order It is better to keep the headers in alphabetic order. Suggested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 3d0a77c1c8998..61883abaf0955 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -24,8 +24,8 @@ #include #include #include -#include #include +#include #include #include -- GitLab From b83e250833e6c40a9e92935ea6fc125b64792357 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 07:25:01 -0200 Subject: [PATCH 2528/2855] [media] media-device: better name Kernelspace/Userspace links The __media_device_enum_links() copies links definitions from Kernelspace to userspace. It has to work with 3 structs that handle with links. Better name them to: link: Kernelspace internal link representation, of the type media_link; klink_desc: struct media_link_desc pointer to the kernel memory where the data will be filled; ulink_desc: struct media_link_desc pointer to the memory where the data will be copied to userspace. Suggested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 61883abaf0955..14bd568e2f41d 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -151,24 +151,25 @@ static long __media_device_enum_links(struct media_device *mdev, } if (links->links) { - struct media_link *ent_link; - struct media_link_desc __user *ulink = links->links; + struct media_link *link; + struct media_link_desc __user *ulink_desc = links->links; - list_for_each_entry(ent_link, &entity->links, list) { - struct media_link_desc link; + list_for_each_entry(link, &entity->links, list) { + struct media_link_desc klink_desc; /* Ignore backlinks. */ - if (ent_link->source->entity != entity) + if (link->source->entity != entity) continue; - memset(&link, 0, sizeof(link)); - media_device_kpad_to_upad(ent_link->source, - &link.source); - media_device_kpad_to_upad(ent_link->sink, - &link.sink); - link.flags = ent_link->flags; - if (copy_to_user(ulink, &link, sizeof(*ulink))) + memset(&klink_desc, 0, sizeof(klink_desc)); + media_device_kpad_to_upad(link->source, + &klink_desc.source); + media_device_kpad_to_upad(link->sink, + &klink_desc.sink); + klink_desc.flags = link->flags; + if (copy_to_user(ulink_desc, &klink_desc, + sizeof(*ulink_desc))) return -EFAULT; - ulink++; + ulink_desc++; } } -- GitLab From ab22e77cd3d3073c8cac51b59713ef635678dfbe Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 07:44:40 -0200 Subject: [PATCH 2529/2855] [media] media framework: rename pads init function to media_entity_pads_init() With the MC next gen rework, what's left for media_entity_init() is to just initialize the PADs. However, certain devices, like a FLASH led/light doesn't have any input or output PAD. So, there's no reason why calling media_entity_init() would be mandatory. Also, despite its name, what this function actually does is to initialize the PADs data. So, rename it to media_entity_pads_init() in order to reflect that. The media entity actual init happens during entity register, at media_device_register_entity(). We should move init of num_links and num_backlinks to it. Signed-off-by: Mauro Carvalho Chehab --- Documentation/media-framework.txt | 18 +++++++++++------- Documentation/video4linux/v4l2-framework.txt | 8 ++++---- .../zh_CN/video4linux/v4l2-framework.txt | 8 ++++---- drivers/media/dvb-core/dvbdev.c | 4 ++-- drivers/media/dvb-frontends/au8522_decoder.c | 2 +- drivers/media/i2c/ad9389b.c | 2 +- drivers/media/i2c/adp1653.c | 2 +- drivers/media/i2c/adv7180.c | 2 +- drivers/media/i2c/adv7511.c | 2 +- drivers/media/i2c/adv7604.c | 2 +- drivers/media/i2c/adv7842.c | 2 +- drivers/media/i2c/as3645a.c | 2 +- drivers/media/i2c/cx25840/cx25840-core.c | 2 +- drivers/media/i2c/lm3560.c | 2 +- drivers/media/i2c/lm3646.c | 2 +- drivers/media/i2c/m5mols/m5mols_core.c | 2 +- drivers/media/i2c/mt9m032.c | 2 +- drivers/media/i2c/mt9p031.c | 2 +- drivers/media/i2c/mt9t001.c | 2 +- drivers/media/i2c/mt9v032.c | 2 +- drivers/media/i2c/noon010pc30.c | 2 +- drivers/media/i2c/ov2659.c | 2 +- drivers/media/i2c/ov9650.c | 2 +- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 4 ++-- drivers/media/i2c/s5k4ecgx.c | 2 +- drivers/media/i2c/s5k5baf.c | 4 ++-- drivers/media/i2c/s5k6a3.c | 2 +- drivers/media/i2c/s5k6aa.c | 2 +- drivers/media/i2c/smiapp/smiapp-core.c | 6 +++--- drivers/media/i2c/tc358743.c | 2 +- drivers/media/i2c/tvp514x.c | 2 +- drivers/media/i2c/tvp7002.c | 2 +- drivers/media/media-device.c | 2 ++ drivers/media/media-entity.c | 11 ++++------- .../media/platform/exynos4-is/fimc-capture.c | 4 ++-- .../media/platform/exynos4-is/fimc-isp-video.c | 2 +- drivers/media/platform/exynos4-is/fimc-isp.c | 2 +- drivers/media/platform/exynos4-is/fimc-lite.c | 4 ++-- drivers/media/platform/exynos4-is/fimc-m2m.c | 2 +- drivers/media/platform/exynos4-is/mipi-csis.c | 2 +- drivers/media/platform/omap3isp/ispccdc.c | 2 +- drivers/media/platform/omap3isp/ispccp2.c | 2 +- drivers/media/platform/omap3isp/ispcsi2.c | 2 +- drivers/media/platform/omap3isp/isppreview.c | 2 +- drivers/media/platform/omap3isp/ispresizer.c | 2 +- drivers/media/platform/omap3isp/ispstat.c | 2 +- drivers/media/platform/omap3isp/ispvideo.c | 2 +- .../media/platform/s3c-camif/camif-capture.c | 4 ++-- drivers/media/platform/vsp1/vsp1_entity.c | 2 +- drivers/media/platform/vsp1/vsp1_video.c | 2 +- drivers/media/platform/xilinx/xilinx-dma.c | 2 +- drivers/media/platform/xilinx/xilinx-tpg.c | 2 +- drivers/media/usb/au0828/au0828-video.c | 6 +++--- drivers/media/usb/cx231xx/cx231xx-video.c | 4 ++-- drivers/media/usb/uvc/uvc_entity.c | 4 ++-- drivers/media/v4l2-core/tuner-core.c | 2 +- drivers/media/v4l2-core/v4l2-flash-led-class.c | 2 +- .../staging/media/davinci_vpfe/dm365_ipipe.c | 2 +- .../staging/media/davinci_vpfe/dm365_ipipeif.c | 2 +- .../staging/media/davinci_vpfe/dm365_isif.c | 2 +- .../staging/media/davinci_vpfe/dm365_resizer.c | 6 +++--- .../staging/media/davinci_vpfe/vpfe_video.c | 2 +- drivers/staging/media/omap4iss/iss_csi2.c | 2 +- drivers/staging/media/omap4iss/iss_ipipe.c | 2 +- drivers/staging/media/omap4iss/iss_ipipeif.c | 2 +- drivers/staging/media/omap4iss/iss_resizer.c | 2 +- drivers/staging/media/omap4iss/iss_video.c | 2 +- include/media/media-entity.h | 2 +- 68 files changed, 102 insertions(+), 99 deletions(-) diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt index b424de6c3bb33..7fbfe4bd1f476 100644 --- a/Documentation/media-framework.txt +++ b/Documentation/media-framework.txt @@ -101,14 +101,18 @@ include/media/media-entity.h. The structure is usually embedded into a higher-level structure, such as a v4l2_subdev or video_device instance, although drivers can allocate entities directly. -Drivers initialize entities by calling +Drivers initialize entity pads by calling - media_entity_init(struct media_entity *entity, u16 num_pads, + media_entity_pads_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads); -The media_entity name, type, flags, revision and group_id fields can be -initialized before or after calling media_entity_init. Entities embedded in -higher-level standard structures can have some of those fields set by the +If no pads are needed, drivers could directly fill entity->num_pads +with 0 and entity->pads with NULL or to call the above function that +will do the same. + +The media_entity name, type, flags, revision and group_id fields should be +initialized before calling media_device_register_entity(). Entities embedded +in higher-level standard structures can have some of those fields set by the higher-level framework. As the number of pads is known in advance, the pads array is not allocated @@ -116,10 +120,10 @@ dynamically but is managed by the entity driver. Most drivers will embed the pads array in a driver-specific structure, avoiding dynamic allocation. Drivers must set the direction of every pad in the pads array before calling -media_entity_init. The function will initialize the other pads fields. +media_entity_pads_init. The function will initialize the other pads fields. Unlike the number of pads, the total number of links isn't always known in -advance by the entity driver. As an initial estimate, media_entity_init +advance by the entity driver. As an initial estimate, media_entity_pads_init pre-allocates a number of links equal to the number of pads. The links array will be reallocated if it grows beyond the initial estimate. diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index 2e0fc28fa12fe..fa41608ab2b4f 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt @@ -295,12 +295,12 @@ module owner. This is done for you if you use the i2c helper functions. If integration with the media framework is needed, you must initialize the media_entity struct embedded in the v4l2_subdev struct (entity field) by -calling media_entity_init(): +calling media_entity_pads_init(), if the entity has pads: struct media_pad *pads = &my_sd->pads; int err; - err = media_entity_init(&sd->entity, npads, pads); + err = media_entity_pads_init(&sd->entity, npads, pads); The pads array must have been previously initialized. There is no need to manually set the struct media_entity function and name fields, but the @@ -695,12 +695,12 @@ difference is that the inode argument is omitted since it is never used. If integration with the media framework is needed, you must initialize the media_entity struct embedded in the video_device struct (entity field) by -calling media_entity_init(): +calling media_entity_pads_init(): struct media_pad *pad = &my_vdev->pad; int err; - err = media_entity_init(&vdev->entity, 1, pad); + err = media_entity_pads_init(&vdev->entity, 1, pad); The pads array must have been previously initialized. There is no need to manually set the struct media_entity type and name fields. diff --git a/Documentation/zh_CN/video4linux/v4l2-framework.txt b/Documentation/zh_CN/video4linux/v4l2-framework.txt index ff815cb920318..698660b7f21fd 100644 --- a/Documentation/zh_CN/video4linux/v4l2-framework.txt +++ b/Documentation/zh_CN/video4linux/v4l2-framework.txt @@ -289,13 +289,13 @@ struct v4l2_subdev_ops { 然后,你必须用一个唯一的名字初始化 subdev->name,并初始化模块的 owner 域。若使用 i2c 辅助函数,这些都会帮你处理好。 -若需同媒体框架整合,你必须调用 media_entity_init() 初始化 v4l2_subdev +若需同媒体框架整合,你必须调用 media_entity_pads_init() 初始化 v4l2_subdev 结构体中的 media_entity 结构体(entity 域): struct media_pad *pads = &my_sd->pads; int err; - err = media_entity_init(&sd->entity, npads, pads); + err = media_entity_pads_init(&sd->entity, npads, pads); pads 数组必须预先初始化。无须手动设置 media_entity 的 type 和 name 域,但如有必要,revision 域必须初始化。 @@ -596,13 +596,13 @@ void v4l2_disable_ioctl(struct video_device *vdev, unsigned int cmd); v4l2_file_operations 结构体是 file_operations 的一个子集。其主要 区别在于:因 inode 参数从未被使用,它将被忽略。 -如果需要与媒体框架整合,你必须通过调用 media_entity_init() 初始化 +如果需要与媒体框架整合,你必须通过调用 media_entity_pads_init() 初始化 嵌入在 video_device 结构体中的 media_entity(entity 域)结构体: struct media_pad *pad = &my_vdev->pad; int err; - err = media_entity_init(&vdev->entity, 1, pad); + err = media_entity_pads_init(&vdev->entity, 1, pad); pads 数组必须预先初始化。没有必要手动设置 media_entity 的 type 和 name 域。 diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 1d4e35693d09d..b56e00817d3fa 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -245,7 +245,7 @@ static int dvb_create_tsout_entity(struct dvb_device *dvbdev, entity->function = MEDIA_ENT_F_IO_DTV; pads->flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(entity, 1, pads); + ret = media_entity_pads_init(entity, 1, pads); if (ret < 0) return ret; @@ -340,7 +340,7 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev, } if (npads) { - ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads); + ret = media_entity_pads_init(dvbdev->entity, npads, dvbdev->pads); if (ret) return ret; } diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c index 464a2beca30d7..73612c5353d19 100644 --- a/drivers/media/dvb-frontends/au8522_decoder.c +++ b/drivers/media/dvb-frontends/au8522_decoder.c @@ -768,7 +768,7 @@ static int au8522_probe(struct i2c_client *client, state->pads[AU8522_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_ATV_DECODER; - ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), + ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(state->pads), state->pads); if (ret < 0) { v4l_info(client, "failed to initialize media entity!\n"); diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c index a02dc4925707c..788967dadd298 100644 --- a/drivers/media/i2c/ad9389b.c +++ b/drivers/media/i2c/ad9389b.c @@ -1158,7 +1158,7 @@ static int ad9389b_probe(struct i2c_client *client, const struct i2c_device_id * state->rgb_quantization_range_ctrl->is_private = true; state->pad.flags = MEDIA_PAD_FL_SINK; - err = media_entity_init(&sd->entity, 1, &state->pad); + err = media_entity_pads_init(&sd->entity, 1, &state->pad); if (err) goto err_hdl; diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c index 7150f35d59354..7e9cbf757e956 100644 --- a/drivers/media/i2c/adp1653.c +++ b/drivers/media/i2c/adp1653.c @@ -512,7 +512,7 @@ static int adp1653_probe(struct i2c_client *client, if (ret) goto free_and_quit; - ret = media_entity_init(&flash->subdev.entity, 0, NULL); + ret = media_entity_pads_init(&flash->subdev.entity, 0, NULL); if (ret < 0) goto free_and_quit; diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index 2ebe9efdfc1b0..ff57c1dcb8aff 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c @@ -1214,7 +1214,7 @@ static int adv7180_probe(struct i2c_client *client, state->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.flags |= MEDIA_ENT_F_ATV_DECODER; - ret = media_entity_init(&sd->entity, 1, &state->pad); + ret = media_entity_pads_init(&sd->entity, 1, &state->pad); if (ret) goto err_free_ctrl; diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index cbcf81b1d29e5..471fd23b5c5c7 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c @@ -1482,7 +1482,7 @@ static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id * state->rgb_quantization_range_ctrl->is_private = true; state->pad.flags = MEDIA_PAD_FL_SINK; - err = media_entity_init(&sd->entity, 1, &state->pad); + err = media_entity_pads_init(&sd->entity, 1, &state->pad); if (err) goto err_hdl; diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index c2df7e8053f3d..f8dd7505b5294 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -3208,7 +3208,7 @@ static int adv76xx_probe(struct i2c_client *client, state->pads[i].flags = MEDIA_PAD_FL_SINK; state->pads[state->source_pad].flags = MEDIA_PAD_FL_SOURCE; - err = media_entity_init(&sd->entity, state->source_pad + 1, + err = media_entity_pads_init(&sd->entity, state->source_pad + 1, state->pads); if (err) goto err_work_queues; diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index b5013a937254b..5fbb788e7b599 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -3309,7 +3309,7 @@ static int adv7842_probe(struct i2c_client *client, adv7842_delayed_work_enable_hotplug); state->pad.flags = MEDIA_PAD_FL_SOURCE; - err = media_entity_init(&sd->entity, 1, &state->pad); + err = media_entity_pads_init(&sd->entity, 1, &state->pad); if (err) goto err_work_queues; diff --git a/drivers/media/i2c/as3645a.c b/drivers/media/i2c/as3645a.c index b1bc4d0f76f24..2e90e4094b796 100644 --- a/drivers/media/i2c/as3645a.c +++ b/drivers/media/i2c/as3645a.c @@ -827,7 +827,7 @@ static int as3645a_probe(struct i2c_client *client, if (ret < 0) goto done; - ret = media_entity_init(&flash->subdev.entity, 0, NULL); + ret = media_entity_pads_init(&flash->subdev.entity, 0, NULL); if (ret < 0) goto done; diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index 4d975aa5be36f..07a3e71731441 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -5213,7 +5213,7 @@ static int cx25840_probe(struct i2c_client *client, state->pads[CX25840_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_ATV_DECODER; - ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), + ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(state->pads), state->pads); if (ret < 0) { v4l_info(client, "failed to initialize media entity!\n"); diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c index 98266f707ea00..251a2aaf98c3b 100644 --- a/drivers/media/i2c/lm3560.c +++ b/drivers/media/i2c/lm3560.c @@ -365,7 +365,7 @@ static int lm3560_subdev_init(struct lm3560_flash *flash, rval = lm3560_init_controls(flash, led_no); if (rval) goto err_out; - rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL); + rval = media_entity_pads_init(&flash->subdev_led[led_no].entity, 0, NULL); if (rval < 0) goto err_out; flash->subdev_led[led_no].entity.function = MEDIA_ENT_F_FLASH; diff --git a/drivers/media/i2c/lm3646.c b/drivers/media/i2c/lm3646.c index ba5ee0d7a78e8..7e9967af36ecd 100644 --- a/drivers/media/i2c/lm3646.c +++ b/drivers/media/i2c/lm3646.c @@ -282,7 +282,7 @@ static int lm3646_subdev_init(struct lm3646_flash *flash) rval = lm3646_init_controls(flash); if (rval) goto err_out; - rval = media_entity_init(&flash->subdev_led.entity, 0, NULL); + rval = media_entity_pads_init(&flash->subdev_led.entity, 0, NULL); if (rval < 0) goto err_out; flash->subdev_led.entity.function = MEDIA_ENT_F_FLASH; diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c index bec5cea23b65e..acb804bceccbc 100644 --- a/drivers/media/i2c/m5mols/m5mols_core.c +++ b/drivers/media/i2c/m5mols/m5mols_core.c @@ -975,7 +975,7 @@ static int m5mols_probe(struct i2c_client *client, sd->internal_ops = &m5mols_subdev_internal_ops; info->pad.flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&sd->entity, 1, &info->pad); + ret = media_entity_pads_init(&sd->entity, 1, &info->pad); if (ret < 0) return ret; sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; diff --git a/drivers/media/i2c/mt9m032.c b/drivers/media/i2c/mt9m032.c index a2a450839ca12..da076796999ee 100644 --- a/drivers/media/i2c/mt9m032.c +++ b/drivers/media/i2c/mt9m032.c @@ -799,7 +799,7 @@ static int mt9m032_probe(struct i2c_client *client, sensor->subdev.ctrl_handler = &sensor->ctrls; sensor->pad.flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&sensor->subdev.entity, 1, &sensor->pad); + ret = media_entity_pads_init(&sensor->subdev.entity, 1, &sensor->pad); if (ret < 0) goto error_ctrl; diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c index 165f29cddca6d..237737fec09c1 100644 --- a/drivers/media/i2c/mt9p031.c +++ b/drivers/media/i2c/mt9p031.c @@ -1112,7 +1112,7 @@ static int mt9p031_probe(struct i2c_client *client, mt9p031->subdev.internal_ops = &mt9p031_subdev_internal_ops; mt9p031->pad.flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&mt9p031->subdev.entity, 1, &mt9p031->pad); + ret = media_entity_pads_init(&mt9p031->subdev.entity, 1, &mt9p031->pad); if (ret < 0) goto done; diff --git a/drivers/media/i2c/mt9t001.c b/drivers/media/i2c/mt9t001.c index 7d3df84651d88..702d562f8e39a 100644 --- a/drivers/media/i2c/mt9t001.c +++ b/drivers/media/i2c/mt9t001.c @@ -933,7 +933,7 @@ static int mt9t001_probe(struct i2c_client *client, mt9t001->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; mt9t001->pad.flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&mt9t001->subdev.entity, 1, &mt9t001->pad); + ret = media_entity_pads_init(&mt9t001->subdev.entity, 1, &mt9t001->pad); done: if (ret < 0) { diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c index b4f0f042c6c3b..2e1d116a64e7b 100644 --- a/drivers/media/i2c/mt9v032.c +++ b/drivers/media/i2c/mt9v032.c @@ -1046,7 +1046,7 @@ static int mt9v032_probe(struct i2c_client *client, mt9v032->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad); + ret = media_entity_pads_init(&mt9v032->subdev.entity, 1, &mt9v032->pad); if (ret < 0) goto err; diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c index 47ea3f79eacc4..30cb90b88d755 100644 --- a/drivers/media/i2c/noon010pc30.c +++ b/drivers/media/i2c/noon010pc30.c @@ -780,7 +780,7 @@ static int noon010_probe(struct i2c_client *client, info->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; - ret = media_entity_init(&sd->entity, 1, &info->pad); + ret = media_entity_pads_init(&sd->entity, 1, &info->pad); if (ret < 0) goto np_err; diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index cf8e71610248d..02b9a3440557b 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1446,7 +1446,7 @@ static int ov2659_probe(struct i2c_client *client, #if defined(CONFIG_MEDIA_CONTROLLER) ov2659->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; - ret = media_entity_init(&sd->entity, 1, &ov2659->pad); + ret = media_entity_pads_init(&sd->entity, 1, &ov2659->pad); if (ret < 0) { v4l2_ctrl_handler_free(&ov2659->ctrls); return ret; diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index adb4aab45c109..a0b3c9bde53d8 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -1501,7 +1501,7 @@ static int ov965x_probe(struct i2c_client *client, ov965x->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; - ret = media_entity_init(&sd->entity, 1, &ov965x->pad); + ret = media_entity_pads_init(&sd->entity, 1, &ov965x->pad); if (ret < 0) return ret; diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index 3d578f2ce7b2f..57b3d27993a40 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1690,7 +1690,7 @@ static int s5c73m3_probe(struct i2c_client *client, state->sensor_pads[S5C73M3_ISP_PAD].flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; - ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS, + ret = media_entity_pads_init(&sd->entity, S5C73M3_NUM_PADS, state->sensor_pads); if (ret < 0) return ret; @@ -1706,7 +1706,7 @@ static int s5c73m3_probe(struct i2c_client *client, state->oif_pads[OIF_SOURCE_PAD].flags = MEDIA_PAD_FL_SOURCE; oif_sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; - ret = media_entity_init(&oif_sd->entity, OIF_NUM_PADS, + ret = media_entity_pads_init(&oif_sd->entity, OIF_NUM_PADS, state->oif_pads); if (ret < 0) return ret; diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c index bacec84e773f6..8a0f22da590ff 100644 --- a/drivers/media/i2c/s5k4ecgx.c +++ b/drivers/media/i2c/s5k4ecgx.c @@ -962,7 +962,7 @@ static int s5k4ecgx_probe(struct i2c_client *client, priv->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; - ret = media_entity_init(&sd->entity, 1, &priv->pad); + ret = media_entity_pads_init(&sd->entity, 1, &priv->pad); if (ret) return ret; diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 564938ab2abd9..fc3a5a8e6c9c7 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -1905,7 +1905,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state, state->cis_pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; - ret = media_entity_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad); + ret = media_entity_pads_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad); if (ret < 0) goto err; @@ -1920,7 +1920,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state, state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK; state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; - ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads); + ret = media_entity_pads_init(&sd->entity, NUM_ISP_PADS, state->pads); if (!ret) return 0; diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c index 2434a79447818..b9e43ffa50859 100644 --- a/drivers/media/i2c/s5k6a3.c +++ b/drivers/media/i2c/s5k6a3.c @@ -333,7 +333,7 @@ static int s5k6a3_probe(struct i2c_client *client, sensor->format.height = S5K6A3_DEFAULT_HEIGHT; sensor->pad.flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&sd->entity, 1, &sensor->pad); + ret = media_entity_pads_init(&sd->entity, 1, &sensor->pad); if (ret < 0) return ret; diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index d71d104441bd4..faee11383cb70 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c @@ -1578,7 +1578,7 @@ static int s5k6aa_probe(struct i2c_client *client, s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; - ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad); + ret = media_entity_pads_init(&sd->entity, 1, &s5k6aa->pad); if (ret) return ret; diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 3eaa69ee341b2..a215efe7a8bac 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2487,11 +2487,11 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor) if (!last) continue; - rval = media_entity_init(&this->sd.entity, + rval = media_entity_pads_init(&this->sd.entity, this->npads, this->pads); if (rval) { dev_err(&client->dev, - "media_entity_init failed\n"); + "media_entity_pads_init failed\n"); return rval; } @@ -3077,7 +3077,7 @@ static int smiapp_probe(struct i2c_client *client, sensor->src->sensor = sensor; sensor->src->pads[0].flags = MEDIA_PAD_FL_SOURCE; - rval = media_entity_init(&sensor->src->sd.entity, 2, + rval = media_entity_pads_init(&sensor->src->sd.entity, 2, sensor->src->pads); if (rval < 0) return rval; diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 78e5b644d4006..3397eb99c67b0 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -1889,7 +1889,7 @@ static int tc358743_probe(struct i2c_client *client, } state->pad.flags = MEDIA_PAD_FL_SOURCE; - err = media_entity_init(&sd->entity, 1, &state->pad); + err = media_entity_pads_init(&sd->entity, 1, &state->pad); if (err < 0) goto err_hdl; diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index 455dd4e6a1dad..7fa5f1e4fe379 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c @@ -1097,7 +1097,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) decoder->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; decoder->sd.entity.flags |= MEDIA_ENT_F_ATV_DECODER; - ret = media_entity_init(&decoder->sd.entity, 1, &decoder->pad); + ret = media_entity_pads_init(&decoder->sd.entity, 1, &decoder->pad); if (ret < 0) { v4l2_err(sd, "%s decoder driver failed to register !!\n", sd->name); diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index 216a07956fe9e..83c79fa5f61de 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c @@ -1014,7 +1014,7 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id) device->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; device->sd.entity.flags |= MEDIA_ENT_F_ATV_DECODER; - error = media_entity_init(&device->sd.entity, 1, &device->pad); + error = media_entity_pads_init(&device->sd.entity, 1, &device->pad); if (error < 0) return error; #endif diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 14bd568e2f41d..b8cd7733a31c6 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -623,6 +623,8 @@ int __must_check media_device_register_entity(struct media_device *mdev, WARN_ON(entity->graph_obj.mdev != NULL); entity->graph_obj.mdev = mdev; INIT_LIST_HEAD(&entity->links); + entity->num_links = 0; + entity->num_backlinks = 0; spin_lock(&mdev->lock); /* Initialize media_gobj embedded at the entity */ diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 07f2dc6c2df6b..ef2102ac0c66d 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -197,7 +197,7 @@ void media_gobj_remove(struct media_gobj *gobj) } /** - * media_entity_init - Initialize a media entity + * media_entity_pads_init - Initialize a media entity * * @num_pads: Total number of sink and source pads. * @pads: Array of 'num_pads' pads. @@ -216,18 +216,15 @@ void media_gobj_remove(struct media_gobj *gobj) * number of allocated elements. * * The pads array is managed by the entity driver and passed to - * media_entity_init() where its pointer will be stored in the entity structure. + * media_entity_pads_init() where its pointer will be stored in the entity structure. */ int -media_entity_init(struct media_entity *entity, u16 num_pads, +media_entity_pads_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads) { struct media_device *mdev = entity->graph_obj.mdev; unsigned int i; - entity->group_id = 0; - entity->num_links = 0; - entity->num_backlinks = 0; entity->num_pads = num_pads; entity->pads = pads; @@ -247,7 +244,7 @@ media_entity_init(struct media_entity *entity, u16 num_pads, return 0; } -EXPORT_SYMBOL_GPL(media_entity_init); +EXPORT_SYMBOL_GPL(media_entity_pads_init); void media_entity_cleanup(struct media_entity *entity) diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index 48a826372d3d5..bf47d3b9cbe77 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c @@ -1799,7 +1799,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc, vid_cap->wb_fmt.code = fmt->mbus_code; vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad); + ret = media_entity_pads_init(&vfd->entity, 1, &vid_cap->vd_pad); if (ret) goto err_free_ctx; @@ -1891,7 +1891,7 @@ int fimc_initialize_capture_subdev(struct fimc_dev *fimc) fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK_CAM].flags = MEDIA_PAD_FL_SINK; fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK_FIFO].flags = MEDIA_PAD_FL_SINK; fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM, + ret = media_entity_pads_init(&sd->entity, FIMC_SD_PADS_NUM, fimc->vid_cap.sd_pads); if (ret) return ret; diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c index 9c7794bcf0c32..bf9261eb57a15 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c @@ -616,7 +616,7 @@ int fimc_isp_video_device_register(struct fimc_isp *isp, vdev->lock = &isp->video_lock; iv->pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&vdev->entity, 1, &iv->pad); + ret = media_entity_pads_init(&vdev->entity, 1, &iv->pad); if (ret < 0) return ret; diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c index f52eebf765c17..293b807020c49 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp.c +++ b/drivers/media/platform/exynos4-is/fimc-isp.c @@ -708,7 +708,7 @@ int fimc_isp_subdev_create(struct fimc_isp *isp) isp->subdev_pads[FIMC_ISP_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK; isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_FIFO].flags = MEDIA_PAD_FL_SOURCE; isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_DMA].flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&sd->entity, FIMC_ISP_SD_PADS_NUM, + ret = media_entity_pads_init(&sd->entity, FIMC_ISP_SD_PADS_NUM, isp->subdev_pads); if (ret) return ret; diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index 957cf144a6752..e85649147dc8d 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -1314,7 +1314,7 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd) return ret; fimc->vd_pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad); + ret = media_entity_pads_init(&vfd->entity, 1, &fimc->vd_pad); if (ret < 0) return ret; @@ -1428,7 +1428,7 @@ static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc) fimc->subdev_pads[FLITE_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK; fimc->subdev_pads[FLITE_SD_PAD_SOURCE_DMA].flags = MEDIA_PAD_FL_SOURCE; fimc->subdev_pads[FLITE_SD_PAD_SOURCE_ISP].flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&sd->entity, FLITE_SD_PADS_NUM, + ret = media_entity_pads_init(&sd->entity, FLITE_SD_PADS_NUM, fimc->subdev_pads); if (ret) return ret; diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c index 8ff4e6f76b848..55ec4c99d484a 100644 --- a/drivers/media/platform/exynos4-is/fimc-m2m.c +++ b/drivers/media/platform/exynos4-is/fimc-m2m.c @@ -739,7 +739,7 @@ int fimc_register_m2m_device(struct fimc_dev *fimc, return PTR_ERR(fimc->m2m.m2m_dev); } - ret = media_entity_init(&vfd->entity, 0, NULL); + ret = media_entity_pads_init(&vfd->entity, 0, NULL); if (ret) goto err_me; diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index 8847797b0d0b4..ac5e50e595be8 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c @@ -866,7 +866,7 @@ static int s5pcsis_probe(struct platform_device *pdev) state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK; state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&state->sd.entity, + ret = media_entity_pads_init(&state->sd.entity, CSIS_PADS_NUM, state->pads); if (ret < 0) goto e_clkdis; diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index f0e530c981888..dae674cd3f74e 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -2655,7 +2655,7 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc) pads[CCDC_PAD_SOURCE_OF].flags = MEDIA_PAD_FL_SOURCE; me->ops = &ccdc_media_ops; - ret = media_entity_init(me, CCDC_PADS_NUM, pads); + ret = media_entity_pads_init(me, CCDC_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index ae3038e643ccf..0c790b25f6f9b 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -1076,7 +1076,7 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2) pads[CCP2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; me->ops = &ccp2_media_ops; - ret = media_entity_init(me, CCP2_PADS_NUM, pads); + ret = media_entity_pads_init(me, CCP2_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index b1617f7efdee2..f50f6b305204c 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c @@ -1250,7 +1250,7 @@ static int csi2_init_entities(struct isp_csi2_device *csi2) | MEDIA_PAD_FL_MUST_CONNECT; me->ops = &csi2_media_ops; - ret = media_entity_init(me, CSI2_PADS_NUM, pads); + ret = media_entity_pads_init(me, CSI2_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index cfb2debb02bfe..c300cb7219e9f 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c @@ -2287,7 +2287,7 @@ static int preview_init_entities(struct isp_prev_device *prev) pads[PREV_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; me->ops = &preview_media_ops; - ret = media_entity_init(me, PREV_PADS_NUM, pads); + ret = media_entity_pads_init(me, PREV_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c index e3ecf1787fc47..cd0a9f6e1fedf 100644 --- a/drivers/media/platform/omap3isp/ispresizer.c +++ b/drivers/media/platform/omap3isp/ispresizer.c @@ -1733,7 +1733,7 @@ static int resizer_init_entities(struct isp_res_device *res) pads[RESZ_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; me->ops = &resizer_media_ops; - ret = media_entity_init(me, RESZ_PADS_NUM, pads); + ret = media_entity_pads_init(me, RESZ_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c index f7a5eee9f11d5..1b9217d3b1b6a 100644 --- a/drivers/media/platform/omap3isp/ispstat.c +++ b/drivers/media/platform/omap3isp/ispstat.c @@ -1028,7 +1028,7 @@ static int isp_stat_init_entities(struct ispstat *stat, const char *name, stat->pad.flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT; me->ops = NULL; - return media_entity_init(me, 1, &stat->pad); + return media_entity_pads_init(me, 1, &stat->pad); } int omap3isp_stat_init(struct ispstat *stat, const char *name, diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index 768efd775abca..1240b06202f04 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -1368,7 +1368,7 @@ int omap3isp_video_init(struct isp_video *video, const char *name) if (IS_ERR(video->alloc_ctx)) return PTR_ERR(video->alloc_ctx); - ret = media_entity_init(&video->video.entity, 1, &video->pad); + ret = media_entity_pads_init(&video->video.entity, 1, &video->pad); if (ret < 0) { vb2_dma_contig_cleanup_ctx(video->alloc_ctx); return ret; diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index 05bfa9d08b19e..bd060ef5d1e1f 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c @@ -1144,7 +1144,7 @@ int s3c_camif_register_video_node(struct camif_dev *camif, int idx) goto err_vd_rel; vp->pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&vfd->entity, 1, &vp->pad); + ret = media_entity_pads_init(&vfd->entity, 1, &vp->pad); if (ret) goto err_vd_rel; @@ -1559,7 +1559,7 @@ int s3c_camif_create_subdev(struct camif_dev *camif) camif->pads[CAMIF_SD_PAD_SOURCE_C].flags = MEDIA_PAD_FL_SOURCE; camif->pads[CAMIF_SD_PAD_SOURCE_P].flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&sd->entity, CAMIF_SD_PADS_NUM, + ret = media_entity_pads_init(&sd->entity, CAMIF_SD_PADS_NUM, camif->pads); if (ret) return ret; diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c index 619942ff2058f..d7308530952fd 100644 --- a/drivers/media/platform/vsp1/vsp1_entity.c +++ b/drivers/media/platform/vsp1/vsp1_entity.c @@ -219,7 +219,7 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity, entity->pads[num_pads - 1].flags = MEDIA_PAD_FL_SOURCE; /* Initialize the media entity. */ - return media_entity_init(&entity->subdev.entity, num_pads, + return media_entity_pads_init(&entity->subdev.entity, num_pads, entity->pads); } diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 024d10de3740d..e3304303dce3f 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -1192,7 +1192,7 @@ int vsp1_video_init(struct vsp1_video *video, struct vsp1_entity *rwpf) video->pipe.state = VSP1_PIPELINE_STOPPED; /* Initialize the media entity... */ - ret = media_entity_init(&video->video.entity, 1, &video->pad); + ret = media_entity_pads_init(&video->video.entity, 1, &video->pad); if (ret < 0) return ret; diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index b69c9630114da..0181ff402a5ab 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -675,7 +675,7 @@ int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma, dma->pad.flags = type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&dma->video.entity, 1, &dma->pad); + ret = media_entity_pads_init(&dma->video.entity, 1, &dma->pad); if (ret < 0) goto error; diff --git a/drivers/media/platform/xilinx/xilinx-tpg.c b/drivers/media/platform/xilinx/xilinx-tpg.c index c09ca513a9dc5..2ec1f6c4b2742 100644 --- a/drivers/media/platform/xilinx/xilinx-tpg.c +++ b/drivers/media/platform/xilinx/xilinx-tpg.c @@ -838,7 +838,7 @@ static int xtpg_probe(struct platform_device *pdev) subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; subdev->entity.ops = &xtpg_media_ops; - ret = media_entity_init(&subdev->entity, xtpg->npads, xtpg->pads); + ret = media_entity_pads_init(&subdev->entity, xtpg->npads, xtpg->pads); if (ret < 0) goto error; diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 839361c035ff3..8c54fd21022e4 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1810,12 +1810,12 @@ static void au0828_analog_create_entities(struct au0828_dev *dev) /* Initialize Video and VBI pads */ dev->video_pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad); + ret = media_entity_pads_init(&dev->vdev.entity, 1, &dev->video_pad); if (ret < 0) pr_err("failed to initialize video media entity!\n"); dev->vbi_pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad); + ret = media_entity_pads_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad); if (ret < 0) pr_err("failed to initialize vbi media entity!\n"); @@ -1847,7 +1847,7 @@ static void au0828_analog_create_entities(struct au0828_dev *dev) break; } - ret = media_entity_init(ent, 1, &dev->input_pad[i]); + ret = media_entity_pads_init(ent, 1, &dev->input_pad[i]); if (ret < 0) pr_err("failed to initialize input pad[%d]!\n", i); diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 905ccd7cbc6da..9b88cd8127ac2 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -2175,7 +2175,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) cx231xx_vdev_init(dev, &dev->vdev, &cx231xx_video_template, "video"); #if defined(CONFIG_MEDIA_CONTROLLER) dev->video_pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad); + ret = media_entity_pads_init(&dev->vdev.entity, 1, &dev->video_pad); if (ret < 0) dev_err(dev->dev, "failed to initialize video media entity!\n"); #endif @@ -2202,7 +2202,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) #if defined(CONFIG_MEDIA_CONTROLLER) dev->vbi_pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad); + ret = media_entity_pads_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad); if (ret < 0) dev_err(dev->dev, "failed to initialize vbi media entity!\n"); #endif diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c index 7f82b65b238e1..38e893a1408bc 100644 --- a/drivers/media/usb/uvc/uvc_entity.c +++ b/drivers/media/usb/uvc/uvc_entity.c @@ -94,10 +94,10 @@ static int uvc_mc_init_entity(struct uvc_entity *entity) strlcpy(entity->subdev.name, entity->name, sizeof(entity->subdev.name)); - ret = media_entity_init(&entity->subdev.entity, + ret = media_entity_pads_init(&entity->subdev.entity, entity->num_pads, entity->pads); } else if (entity->vdev != NULL) { - ret = media_entity_init(&entity->vdev->entity, + ret = media_entity_pads_init(&entity->vdev->entity, entity->num_pads, entity->pads); if (entity->flags & UVC_ENTITY_FLAG_DEFAULT) entity->vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT; diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index 05fc4df61b85f..76496fd282aa5 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -701,7 +701,7 @@ register_client: t->sd.entity.function = MEDIA_ENT_F_TUNER; t->sd.entity.name = t->name; - ret = media_entity_init(&t->sd.entity, TUNER_NUM_PADS, &t->pad[0]); + ret = media_entity_pads_init(&t->sd.entity, TUNER_NUM_PADS, &t->pad[0]); if (ret < 0) { tuner_err("failed to initialize media entity!\n"); kfree(t); diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c index 5c686a24712ba..13d5a36bc5d87 100644 --- a/drivers/media/v4l2-core/v4l2-flash-led-class.c +++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c @@ -651,7 +651,7 @@ struct v4l2_flash *v4l2_flash_init( sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; strlcpy(sd->name, config->dev_name, sizeof(sd->name)); - ret = media_entity_init(&sd->entity, 0, NULL); + ret = media_entity_pads_init(&sd->entity, 0, NULL); if (ret < 0) return ERR_PTR(ret); diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c index 77837afab0ce6..ac78ed2f8bcca 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c @@ -1843,7 +1843,7 @@ vpfe_ipipe_init(struct vpfe_ipipe_device *ipipe, struct platform_device *pdev) v4l2_ctrl_handler_setup(&ipipe->ctrls); sd->ctrl_handler = &ipipe->ctrls; - return media_entity_init(me, IPIPE_PADS_NUM, pads); + return media_entity_pads_init(me, IPIPE_PADS_NUM, pads); } /* diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c index b66584ecb6933..a54c60fce3d5b 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c @@ -1031,7 +1031,7 @@ int vpfe_ipipeif_init(struct vpfe_ipipeif_device *ipipeif, ipipeif->output = IPIPEIF_OUTPUT_NONE; me->ops = &ipipeif_media_ops; - ret = media_entity_init(me, IPIPEIF_NUM_PADS, pads); + ret = media_entity_pads_init(me, IPIPEIF_NUM_PADS, pads); if (ret) goto fail; diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c index 8ca0c1297ec8c..b35667afb73f6 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_isif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c @@ -2057,7 +2057,7 @@ int vpfe_isif_init(struct vpfe_isif_device *isif, struct platform_device *pdev) isif->input = ISIF_INPUT_NONE; isif->output = ISIF_OUTPUT_NONE; me->ops = &isif_media_ops; - status = media_entity_init(me, ISIF_PADS_NUM, pads); + status = media_entity_pads_init(me, ISIF_PADS_NUM, pads); if (status) goto isif_fail; isif->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index ba887efd226a3..669ae3f9791fd 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c @@ -1915,7 +1915,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz, vpfe_rsz->crop_resizer.output2 = RESIZER_CROP_OUTPUT_NONE; vpfe_rsz->crop_resizer.rsz_device = vpfe_rsz; me->ops = &resizer_media_ops; - ret = media_entity_init(me, RESIZER_CROP_PADS_NUM, pads); + ret = media_entity_pads_init(me, RESIZER_CROP_PADS_NUM, pads); if (ret) return ret; @@ -1937,7 +1937,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz, vpfe_rsz->resizer_a.output = RESIZER_OUTPUT_NONE; vpfe_rsz->resizer_a.rsz_device = vpfe_rsz; me->ops = &resizer_media_ops; - ret = media_entity_init(me, RESIZER_PADS_NUM, pads); + ret = media_entity_pads_init(me, RESIZER_PADS_NUM, pads); if (ret) return ret; @@ -1959,7 +1959,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz, vpfe_rsz->resizer_b.output = RESIZER_OUTPUT_NONE; vpfe_rsz->resizer_b.rsz_device = vpfe_rsz; me->ops = &resizer_media_ops; - ret = media_entity_init(me, RESIZER_PADS_NUM, pads); + ret = media_entity_pads_init(me, RESIZER_PADS_NUM, pads); if (ret) return ret; diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index a5e30413fc47c..285dc1a69b2ca 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -1599,7 +1599,7 @@ int vpfe_video_init(struct vpfe_video_device *video, const char *name) spin_lock_init(&video->irqlock); spin_lock_init(&video->dma_queue_lock); mutex_init(&video->lock); - ret = media_entity_init(&video->video_dev.entity, + ret = media_entity_pads_init(&video->video_dev.entity, 1, &video->pad); if (ret < 0) return ret; diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c index 2b9a36cd8fa8e..226366a036619 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.c +++ b/drivers/staging/media/omap4iss/iss_csi2.c @@ -1276,7 +1276,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname) pads[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK; me->ops = &csi2_media_ops; - ret = media_entity_init(me, CSI2_PADS_NUM, pads); + ret = media_entity_pads_init(me, CSI2_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/staging/media/omap4iss/iss_ipipe.c b/drivers/staging/media/omap4iss/iss_ipipe.c index dd9d7d54e6f86..d38782e8e84c7 100644 --- a/drivers/staging/media/omap4iss/iss_ipipe.c +++ b/drivers/staging/media/omap4iss/iss_ipipe.c @@ -516,7 +516,7 @@ static int ipipe_init_entities(struct iss_ipipe_device *ipipe) pads[IPIPE_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE; me->ops = &ipipe_media_ops; - ret = media_entity_init(me, IPIPE_PADS_NUM, pads); + ret = media_entity_pads_init(me, IPIPE_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c index 8cbb9840a989c..c2b5638a08988 100644 --- a/drivers/staging/media/omap4iss/iss_ipipeif.c +++ b/drivers/staging/media/omap4iss/iss_ipipeif.c @@ -748,7 +748,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif) pads[IPIPEIF_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE; me->ops = &ipipeif_media_ops; - ret = media_entity_init(me, IPIPEIF_PADS_NUM, pads); + ret = media_entity_pads_init(me, IPIPEIF_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c index a3925ecd0ed79..fea13ab4041f6 100644 --- a/drivers/staging/media/omap4iss/iss_resizer.c +++ b/drivers/staging/media/omap4iss/iss_resizer.c @@ -790,7 +790,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer) pads[RESIZER_PAD_SOURCE_MEM].flags = MEDIA_PAD_FL_SOURCE; me->ops = &resizer_media_ops; - ret = media_entity_init(me, RESIZER_PADS_NUM, pads); + ret = media_entity_pads_init(me, RESIZER_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index 60b7a58e6122d..8c6af412bc161 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -1101,7 +1101,7 @@ int omap4iss_video_init(struct iss_video *video, const char *name) return -EINVAL; } - ret = media_entity_init(&video->video.entity, 1, &video->pad); + ret = media_entity_pads_init(&video->video.entity, 1, &video->pad); if (ret < 0) return ret; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index cd3f3a77df2d7..32fef503d9506 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -347,7 +347,7 @@ void media_gobj_init(struct media_device *mdev, struct media_gobj *gobj); void media_gobj_remove(struct media_gobj *gobj); -int media_entity_init(struct media_entity *entity, u16 num_pads, +int media_entity_pads_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads); void media_entity_cleanup(struct media_entity *entity); -- GitLab From 8ed8c88c460fa6ce71deb9847f78a5bff4dfcb0e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 08:02:19 -0200 Subject: [PATCH 2530/2855] [media] media-entity.h: get rid of revision and group_id fields Both revision and group_id fields were never used and were always initialized to zero. Remove them. Suggested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- .../DocBook/media/v4l/media-ioc-enum-entities.xml | 13 ++----------- Documentation/media-framework.txt | 12 +++++------- drivers/media/media-device.c | 4 ++-- include/media/media-entity.h | 4 ---- 4 files changed, 9 insertions(+), 24 deletions(-) diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml index 27f8817e7abe9..9f7614a012342 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml @@ -59,15 +59,6 @@ Entity IDs can be non-contiguous. Applications must not try to enumerate entities by calling MEDIA_IOC_ENUM_ENTITIES with increasing id's until they get an error. - Two or more entities that share a common non-zero - group_id value are considered as logically - grouped. Groups are used to report - - ALSA, VBI and video nodes that carry the same media - stream - lens and flash controllers associated with a sensor - - struct <structname>media_entity_desc</structname> @@ -106,7 +97,7 @@ revision - Entity revision in a driver/hardware specific format. + Entity revision. Always zero (obsolete) __u32 @@ -120,7 +111,7 @@ group_id - Entity group ID + Entity group ID. Always zero (obsolete) __u16 diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt index 7fbfe4bd1f476..ef3663af1db37 100644 --- a/Documentation/media-framework.txt +++ b/Documentation/media-framework.txt @@ -110,10 +110,10 @@ If no pads are needed, drivers could directly fill entity->num_pads with 0 and entity->pads with NULL or to call the above function that will do the same. -The media_entity name, type, flags, revision and group_id fields should be -initialized before calling media_device_register_entity(). Entities embedded -in higher-level standard structures can have some of those fields set by the -higher-level framework. +The media_entity name, type and flags fields should be initialized before +calling media_device_register_entity(). Entities embedded in higher-level +standard structures can have some of those fields set by the higher-level +framework. As the number of pads is known in advance, the pads array is not allocated dynamically but is managed by the entity driver. Most drivers will embed the @@ -164,9 +164,7 @@ Entities have flags that describe the entity capabilities and state. Logical entity groups can be defined by setting the group ID of all member entities to the same non-zero value. An entity group serves no purpose in the -kernel, but is reported to userspace during entities enumeration. The group_id -field belongs to the media device driver and must not by touched by entity -drivers. +kernel, but is reported to userspace during entities enumeration. Media device drivers should define groups if several entities are logically bound together. Example usages include reporting diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index b8cd7733a31c6..537160bb461e0 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -109,9 +109,9 @@ static long media_device_enum_entities(struct media_device *mdev, if (ent->name) strlcpy(u_ent.name, ent->name, sizeof(u_ent.name)); u_ent.type = ent->function; - u_ent.revision = ent->revision; + u_ent.revision = 0; /* Unused */ u_ent.flags = ent->flags; - u_ent.group_id = ent->group_id; + u_ent.group_id = 0; /* Unused */ u_ent.pads = ent->num_pads; u_ent.links = ent->num_links - ent->num_backlinks; memcpy(&u_ent.raw, &ent->info, sizeof(ent->info)); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 32fef503d9506..031536723d8ca 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -153,9 +153,7 @@ struct media_entity_operations { * @name: Entity name. * @function: Entity main function, as defined in uapi/media.h * (MEDIA_ENT_F_*) - * @revision: Entity revision - OBSOLETE - should be removed soon. * @flags: Entity flags, as defined in uapi/media.h (MEDIA_ENT_FL_*) - * @group_id: Entity group ID - OBSOLETE - should be removed soon. * @num_pads: Number of sink and source pads. * @num_links: Total number of links, forward and back, enabled and disabled. * @num_backlinks: Number of backlinks @@ -180,9 +178,7 @@ struct media_entity { struct media_gobj graph_obj; /* must be first field in struct */ const char *name; u32 function; - u32 revision; unsigned long flags; - u32 group_id; u16 num_pads; u16 num_links; -- GitLab From cc2dd94a051c8a467c66a258391cb980c3fb3312 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 08:21:39 -0200 Subject: [PATCH 2531/2855] [media] DocBook: Move media-framework.txt contents to media-device.h Instead of using a text file, let's put it together with the struct documentation for the Media Controller. Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/device-drivers.tmpl | 1 + Documentation/media-framework.txt | 373 --------------------- include/media/media-device.h | 378 ++++++++++++++++++++++ 3 files changed, 379 insertions(+), 373 deletions(-) delete mode 100644 Documentation/media-framework.txt diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl index 7b3fcc5effcde..cdd8b24db68d3 100644 --- a/Documentation/DocBook/device-drivers.tmpl +++ b/Documentation/DocBook/device-drivers.tmpl @@ -263,6 +263,7 @@ X!Isound/sound_firmware.c !Iinclude/media/lirc_dev.h Media Controller devices +!Pinclude/media/media-device.h Media Controller !Iinclude/media/media-device.h !Iinclude/media/media-devnode.h !Iinclude/media/media-entity.h diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt deleted file mode 100644 index ef3663af1db37..0000000000000 --- a/Documentation/media-framework.txt +++ /dev/null @@ -1,373 +0,0 @@ -Linux kernel media framework -============================ - -This document describes the Linux kernel media framework, its data structures, -functions and their usage. - - -Introduction ------------- - -The media controller API is documented in DocBook format in -Documentation/DocBook/media/v4l/media-controller.xml. This document will focus -on the kernel-side implementation of the media framework. - - -Abstract media device model ---------------------------- - -Discovering a device internal topology, and configuring it at runtime, is one -of the goals of the media framework. To achieve this, hardware devices are -modelled as an oriented graph of building blocks called entities connected -through pads. - -An entity is a basic media hardware building block. It can correspond to -a large variety of logical blocks such as physical hardware devices -(CMOS sensor for instance), logical hardware devices (a building block -in a System-on-Chip image processing pipeline), DMA channels or physical -connectors. - -A pad is a connection endpoint through which an entity can interact with -other entities. Data (not restricted to video) produced by an entity -flows from the entity's output to one or more entity inputs. Pads should -not be confused with physical pins at chip boundaries. - -A link is a point-to-point oriented connection between two pads, either -on the same entity or on different entities. Data flows from a source -pad to a sink pad. - - -Media device ------------- - -A media device is represented by a struct media_device instance, defined in -include/media/media-device.h. Allocation of the structure is handled by the -media device driver, usually by embedding the media_device instance in a -larger driver-specific structure. - -Drivers register media device instances by calling - - media_device_register(struct media_device *mdev); - -The caller is responsible for initializing the media_device structure before -registration. The following fields must be set: - - - dev must point to the parent device (usually a pci_dev, usb_interface or - platform_device instance). - - - model must be filled with the device model name as a NUL-terminated UTF-8 - string. The device/model revision must not be stored in this field. - -The following fields are optional: - - - serial is a unique serial number stored as a NUL-terminated ASCII string. - The field is big enough to store a GUID in text form. If the hardware - doesn't provide a unique serial number this field must be left empty. - - - bus_info represents the location of the device in the system as a - NUL-terminated ASCII string. For PCI/PCIe devices bus_info must be set to - "PCI:" (or "PCIe:") followed by the value of pci_name(). For USB devices, - the usb_make_path() function must be used. This field is used by - applications to distinguish between otherwise identical devices that don't - provide a serial number. - - - hw_revision is the hardware device revision in a driver-specific format. - When possible the revision should be formatted with the KERNEL_VERSION - macro. - - - driver_version is formatted with the KERNEL_VERSION macro. The version - minor must be incremented when new features are added to the userspace API - without breaking binary compatibility. The version major must be - incremented when binary compatibility is broken. - -Upon successful registration a character device named media[0-9]+ is created. -The device major and minor numbers are dynamic. The model name is exported as -a sysfs attribute. - -Drivers unregister media device instances by calling - - media_device_unregister(struct media_device *mdev); - -Unregistering a media device that hasn't been registered is *NOT* safe. - - -Entities, pads and links ------------------------- - -- Entities - -Entities are represented by a struct media_entity instance, defined in -include/media/media-entity.h. The structure is usually embedded into a -higher-level structure, such as a v4l2_subdev or video_device instance, -although drivers can allocate entities directly. - -Drivers initialize entity pads by calling - - media_entity_pads_init(struct media_entity *entity, u16 num_pads, - struct media_pad *pads); - -If no pads are needed, drivers could directly fill entity->num_pads -with 0 and entity->pads with NULL or to call the above function that -will do the same. - -The media_entity name, type and flags fields should be initialized before -calling media_device_register_entity(). Entities embedded in higher-level -standard structures can have some of those fields set by the higher-level -framework. - -As the number of pads is known in advance, the pads array is not allocated -dynamically but is managed by the entity driver. Most drivers will embed the -pads array in a driver-specific structure, avoiding dynamic allocation. - -Drivers must set the direction of every pad in the pads array before calling -media_entity_pads_init. The function will initialize the other pads fields. - -Unlike the number of pads, the total number of links isn't always known in -advance by the entity driver. As an initial estimate, media_entity_pads_init -pre-allocates a number of links equal to the number of pads. The links array -will be reallocated if it grows beyond the initial estimate. - -Drivers register entities with a media device by calling - - media_device_register_entity(struct media_device *mdev, - struct media_entity *entity); - -Entities are identified by a unique positive integer ID. Drivers can provide an -ID by filling the media_entity id field prior to registration, or request the -media controller framework to assign an ID automatically. Drivers that provide -IDs manually must ensure that all IDs are unique. IDs are not guaranteed to be -contiguous even when they are all assigned automatically by the framework. - -Drivers unregister entities by calling - - media_device_unregister_entity(struct media_entity *entity); - -Unregistering an entity will not change the IDs of the other entities, and the -ID will never be reused for a newly registered entity. - -When a media device is unregistered, all its entities are unregistered -automatically. No manual entities unregistration is then required. - -Drivers free resources associated with an entity by calling - - media_entity_cleanup(struct media_entity *entity); - -This function must be called during the cleanup phase after unregistering the -entity. Note that the media_entity instance itself must be freed explicitly by -the driver if required. - -Entities have flags that describe the entity capabilities and state. - - MEDIA_ENT_FL_DEFAULT indicates the default entity for a given type. - This can be used to report the default audio and video devices or the - default camera sensor. - -Logical entity groups can be defined by setting the group ID of all member -entities to the same non-zero value. An entity group serves no purpose in the -kernel, but is reported to userspace during entities enumeration. - -Media device drivers should define groups if several entities are logically -bound together. Example usages include reporting - - - ALSA, VBI and video nodes that carry the same media stream - - lens and flash controllers associated with a sensor - -- Pads - -Pads are represented by a struct media_pad instance, defined in -include/media/media-entity.h. Each entity stores its pads in a pads array -managed by the entity driver. Drivers usually embed the array in a -driver-specific structure. - -Pads are identified by their entity and their 0-based index in the pads array. -Both information are stored in the media_pad structure, making the media_pad -pointer the canonical way to store and pass link references. - -Pads have flags that describe the pad capabilities and state. - - MEDIA_PAD_FL_SINK indicates that the pad supports sinking data. - MEDIA_PAD_FL_SOURCE indicates that the pad supports sourcing data. - -One and only one of MEDIA_PAD_FL_SINK and MEDIA_PAD_FL_SOURCE must be set for -each pad. - -- Links - -Links are represented by a struct media_link instance, defined in -include/media/media-entity.h. Each entity stores all links originating at or -targeting any of its pads in a links array. A given link is thus stored -twice, once in the source entity and once in the target entity. The array is -pre-allocated and grows dynamically as needed. - -Drivers create links by calling - - media_create_pad_link(struct media_entity *source, u16 source_pad, - struct media_entity *sink, u16 sink_pad, - u32 flags); - -An entry in the link array of each entity is allocated and stores pointers -to source and sink pads. - -Links have flags that describe the link capabilities and state. - - MEDIA_LNK_FL_ENABLED indicates that the link is enabled and can be used - to transfer media data. When two or more links target a sink pad, only - one of them can be enabled at a time. - MEDIA_LNK_FL_IMMUTABLE indicates that the link enabled state can't be - modified at runtime. If MEDIA_LNK_FL_IMMUTABLE is set, then - MEDIA_LNK_FL_ENABLED must also be set since an immutable link is always - enabled. - - -Graph traversal ---------------- - -The media framework provides APIs to iterate over entities in a graph. - -To iterate over all entities belonging to a media device, drivers can use the -media_device_for_each_entity macro, defined in include/media/media-device.h. - - struct media_entity *entity; - - media_device_for_each_entity(entity, mdev) { - /* entity will point to each entity in turn */ - ... - } - -Drivers might also need to iterate over all entities in a graph that can be -reached only through enabled links starting at a given entity. The media -framework provides a depth-first graph traversal API for that purpose. - -Note that graphs with cycles (whether directed or undirected) are *NOT* -supported by the graph traversal API. To prevent infinite loops, the graph -traversal code limits the maximum depth to MEDIA_ENTITY_ENUM_MAX_DEPTH, -currently defined as 16. - -Drivers initiate a graph traversal by calling - - media_entity_graph_walk_start(struct media_entity_graph *graph, - struct media_entity *entity); - -The graph structure, provided by the caller, is initialized to start graph -traversal at the given entity. - -Drivers can then retrieve the next entity by calling - - media_entity_graph_walk_next(struct media_entity_graph *graph); - -When the graph traversal is complete the function will return NULL. - -Graph traversal can be interrupted at any moment. No cleanup function call is -required and the graph structure can be freed normally. - -Helper functions can be used to find a link between two given pads, or a pad -connected to another pad through an enabled link - - media_entity_find_link(struct media_pad *source, - struct media_pad *sink); - - media_entity_remote_pad(struct media_pad *pad); - -Refer to the kerneldoc documentation for more information. - - -Use count and power handling ----------------------------- - -Due to the wide differences between drivers regarding power management needs, -the media controller does not implement power management. However, the -media_entity structure includes a use_count field that media drivers can use to -track the number of users of every entity for power management needs. - -The use_count field is owned by media drivers and must not be touched by entity -drivers. Access to the field must be protected by the media device graph_mutex -lock. - - -Links setup ------------ - -Link properties can be modified at runtime by calling - - media_entity_setup_link(struct media_link *link, u32 flags); - -The flags argument contains the requested new link flags. - -The only configurable property is the ENABLED link flag to enable/disable a -link. Links marked with the IMMUTABLE link flag can not be enabled or disabled. - -When a link is enabled or disabled, the media framework calls the -link_setup operation for the two entities at the source and sink of the link, -in that order. If the second link_setup call fails, another link_setup call is -made on the first entity to restore the original link flags. - -Media device drivers can be notified of link setup operations by setting the -media_device::link_notify pointer to a callback function. If provided, the -notification callback will be called before enabling and after disabling -links. - -Entity drivers must implement the link_setup operation if any of their links -is non-immutable. The operation must either configure the hardware or store -the configuration information to be applied later. - -Link configuration must not have any side effect on other links. If an enabled -link at a sink pad prevents another link at the same pad from being enabled, -the link_setup operation must return -EBUSY and can't implicitly disable the -first enabled link. - - -Pipelines and media streams ---------------------------- - -When starting streaming, drivers must notify all entities in the pipeline to -prevent link states from being modified during streaming by calling - - media_entity_pipeline_start(struct media_entity *entity, - struct media_pipeline *pipe); - -The function will mark all entities connected to the given entity through -enabled links, either directly or indirectly, as streaming. - -The media_pipeline instance pointed to by the pipe argument will be stored in -every entity in the pipeline. Drivers should embed the media_pipeline structure -in higher-level pipeline structures and can then access the pipeline through -the media_entity pipe field. - -Calls to media_entity_pipeline_start() can be nested. The pipeline pointer must -be identical for all nested calls to the function. - -media_entity_pipeline_start() may return an error. In that case, it will -clean up any of the changes it did by itself. - -When stopping the stream, drivers must notify the entities with - - media_entity_pipeline_stop(struct media_entity *entity); - -If multiple calls to media_entity_pipeline_start() have been made the same -number of media_entity_pipeline_stop() calls are required to stop streaming. The -media_entity pipe field is reset to NULL on the last nested stop call. - -Link configuration will fail with -EBUSY by default if either end of the link is -a streaming entity. Links that can be modified while streaming must be marked -with the MEDIA_LNK_FL_DYNAMIC flag. - -If other operations need to be disallowed on streaming entities (such as -changing entities configuration parameters) drivers can explicitly check the -media_entity stream_count field to find out if an entity is streaming. This -operation must be done with the media_device graph_mutex held. - - -Link validation ---------------- - -Link validation is performed by media_entity_pipeline_start() for any -entity which has sink pads in the pipeline. The -media_entity::link_validate() callback is used for that purpose. In -link_validate() callback, entity driver should check that the properties of -the source pad of the connected entity and its own sink pad match. It is up -to the type of the entity (and in the end, the properties of the hardware) -what matching actually means. - -Subsystems should facilitate link validation by providing subsystem specific -helper functions to provide easy access for commonly needed information, and -in the end provide a way to use driver-specific callbacks. diff --git a/include/media/media-device.h b/include/media/media-device.h index 87ff299e1265d..6728528df9e2d 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -30,6 +30,384 @@ #include #include +/** + * DOC: Media Controller + * + * Linux kernel media framework + * ============================ + * + * This document describes the Linux kernel media framework, its data structures, + * functions and their usage. + * + * + * Introduction + * ------------ + * + * The media controller API is documented in DocBook format in + * Documentation/DocBook/media/v4l/media-controller.xml. This document will focus + * on the kernel-side implementation of the media framework. + * + * + * Abstract media device model + * --------------------------- + * + * Discovering a device internal topology, and configuring it at runtime, is one + * of the goals of the media framework. To achieve this, hardware devices are + * modelled as an oriented graph of building blocks called entities connected + * through pads. + * + * An entity is a basic media hardware building block. It can correspond to + * a large variety of logical blocks such as physical hardware devices + * (CMOS sensor for instance), logical hardware devices (a building block + * in a System-on-Chip image processing pipeline), DMA channels or physical + * connectors. + * + * A pad is a connection endpoint through which an entity can interact with + * other entities. Data (not restricted to video) produced by an entity + * flows from the entity's output to one or more entity inputs. Pads should + * not be confused with physical pins at chip boundaries. + * + * A link is a point-to-point oriented connection between two pads, either + * on the same entity or on different entities. Data flows from a source + * pad to a sink pad. + * + * + * Media device + * ------------ + * + * A media device is represented by a struct media_device instance, defined in + * include/media/media-device.h. Allocation of the structure is handled by the + * media device driver, usually by embedding the media_device instance in a + * larger driver-specific structure. + * + * Drivers register media device instances by calling + * + * media_device_register(struct media_device *mdev); + * + * The caller is responsible for initializing the media_device structure before + * registration. The following fields must be set: + * + * - dev must point to the parent device (usually a pci_dev, usb_interface or + * platform_device instance). + * + * - model must be filled with the device model name as a NUL-terminated UTF-8 + * string. The device/model revision must not be stored in this field. + * + * The following fields are optional: + * + * - serial is a unique serial number stored as a NUL-terminated ASCII string. + * The field is big enough to store a GUID in text form. If the hardware + * doesn't provide a unique serial number this field must be left empty. + * + * - bus_info represents the location of the device in the system as a + * NUL-terminated ASCII string. For PCI/PCIe devices bus_info must be set to + * "PCI:" (or "PCIe:") followed by the value of pci_name(). For USB devices, + * the usb_make_path() function must be used. This field is used by + * applications to distinguish between otherwise identical devices that don't + * provide a serial number. + * + * - hw_revision is the hardware device revision in a driver-specific format. + * When possible the revision should be formatted with the KERNEL_VERSION + * macro. + * + * - driver_version is formatted with the KERNEL_VERSION macro. The version + * minor must be incremented when new features are added to the userspace API + * without breaking binary compatibility. The version major must be + * incremented when binary compatibility is broken. + * + * Upon successful registration a character device named media[0-9]+ is created. + * The device major and minor numbers are dynamic. The model name is exported as + * a sysfs attribute. + * + * Drivers unregister media device instances by calling + * + * media_device_unregister(struct media_device *mdev); + * + * Unregistering a media device that hasn't been registered is *NOT* safe. + * + * + * Entities, pads and links + * ------------------------ + * + * - Entities + * + * Entities are represented by a struct media_entity instance, defined in + * include/media/media-entity.h. The structure is usually embedded into a + * higher-level structure, such as a v4l2_subdev or video_device instance, + * although drivers can allocate entities directly. + * + * Drivers initialize entity pads by calling + * + * media_entity_pads_init(struct media_entity *entity, u16 num_pads, + * struct media_pad *pads); + * + * If no pads are needed, drivers could directly fill entity->num_pads + * with 0 and entity->pads with NULL or to call the above function that + * will do the same. + * + * The media_entity name, type and flags fields should be initialized before + * calling media_device_register_entity(). Entities embedded in higher-level + * standard structures can have some of those fields set by the higher-level + * framework. + * + * As the number of pads is known in advance, the pads array is not allocated + * dynamically but is managed by the entity driver. Most drivers will embed the + * pads array in a driver-specific structure, avoiding dynamic allocation. + * + * Drivers must set the direction of every pad in the pads array before calling + * media_entity_pads_init. The function will initialize the other pads fields. + * + * Unlike the number of pads, the total number of links isn't always known in + * advance by the entity driver. As an initial estimate, media_entity_pads_init + * pre-allocates a number of links equal to the number of pads. The links array + * will be reallocated if it grows beyond the initial estimate. + * + * Drivers register entities with a media device by calling + * + * media_device_register_entity(struct media_device *mdev, + * struct media_entity *entity); + * + * Entities are identified by a unique positive integer ID. Drivers can provide an + * ID by filling the media_entity id field prior to registration, or request the + * media controller framework to assign an ID automatically. Drivers that provide + * IDs manually must ensure that all IDs are unique. IDs are not guaranteed to be + * contiguous even when they are all assigned automatically by the framework. + * + * Drivers unregister entities by calling + * + * media_device_unregister_entity(struct media_entity *entity); + * + * Unregistering an entity will not change the IDs of the other entities, and the + * ID will never be reused for a newly registered entity. + * + * When a media device is unregistered, all its entities are unregistered + * automatically. No manual entities unregistration is then required. + * + * Drivers free resources associated with an entity by calling + * + * media_entity_cleanup(struct media_entity *entity); + * + * This function must be called during the cleanup phase after unregistering the + * entity. Note that the media_entity instance itself must be freed explicitly by + * the driver if required. + * + * Entities have flags that describe the entity capabilities and state. + * + * MEDIA_ENT_FL_DEFAULT indicates the default entity for a given type. + * This can be used to report the default audio and video devices or the + * default camera sensor. + * + * Logical entity groups can be defined by setting the group ID of all member + * entities to the same non-zero value. An entity group serves no purpose in the + * kernel, but is reported to userspace during entities enumeration. + * + * Media device drivers should define groups if several entities are logically + * bound together. Example usages include reporting + * + * - ALSA, VBI and video nodes that carry the same media stream + * - lens and flash controllers associated with a sensor + * + * - Pads + * + * Pads are represented by a struct media_pad instance, defined in + * include/media/media-entity.h. Each entity stores its pads in a pads array + * managed by the entity driver. Drivers usually embed the array in a + * driver-specific structure. + * + * Pads are identified by their entity and their 0-based index in the pads array. + * Both information are stored in the media_pad structure, making the media_pad + * pointer the canonical way to store and pass link references. + * + * Pads have flags that describe the pad capabilities and state. + * + * MEDIA_PAD_FL_SINK indicates that the pad supports sinking data. + * MEDIA_PAD_FL_SOURCE indicates that the pad supports sourcing data. + * + * One and only one of MEDIA_PAD_FL_SINK and MEDIA_PAD_FL_SOURCE must be set for + * each pad. + * + * - Links + * + * Links are represented by a struct media_link instance, defined in + * include/media/media-entity.h. Each entity stores all links originating at or + * targeting any of its pads in a links array. A given link is thus stored + * twice, once in the source entity and once in the target entity. The array is + * pre-allocated and grows dynamically as needed. + * + * Drivers create links by calling + * + * media_create_pad_link(struct media_entity *source, u16 source_pad, + * struct media_entity *sink, u16 sink_pad, + * u32 flags); + * + * An entry in the link array of each entity is allocated and stores pointers + * to source and sink pads. + * + * Links have flags that describe the link capabilities and state. + * + * MEDIA_LNK_FL_ENABLED indicates that the link is enabled and can be used + * to transfer media data. When two or more links target a sink pad, only + * one of them can be enabled at a time. + * MEDIA_LNK_FL_IMMUTABLE indicates that the link enabled state can't be + * modified at runtime. If MEDIA_LNK_FL_IMMUTABLE is set, then + * MEDIA_LNK_FL_ENABLED must also be set since an immutable link is always + * enabled. + * + * + * Graph traversal + * --------------- + * + * The media framework provides APIs to iterate over entities in a graph. + * + * To iterate over all entities belonging to a media device, drivers can use the + * media_device_for_each_entity macro, defined in include/media/media-device.h. + * + * struct media_entity *entity; + * + * media_device_for_each_entity(entity, mdev) { + * // entity will point to each entity in turn + * ... + * } + * + * Drivers might also need to iterate over all entities in a graph that can be + * reached only through enabled links starting at a given entity. The media + * framework provides a depth-first graph traversal API for that purpose. + * + * Note that graphs with cycles (whether directed or undirected) are *NOT* + * supported by the graph traversal API. To prevent infinite loops, the graph + * traversal code limits the maximum depth to MEDIA_ENTITY_ENUM_MAX_DEPTH, + * currently defined as 16. + * + * Drivers initiate a graph traversal by calling + * + * media_entity_graph_walk_start(struct media_entity_graph *graph, + * struct media_entity *entity); + * + * The graph structure, provided by the caller, is initialized to start graph + * traversal at the given entity. + * + * Drivers can then retrieve the next entity by calling + * + * media_entity_graph_walk_next(struct media_entity_graph *graph); + * + * When the graph traversal is complete the function will return NULL. + * + * Graph traversal can be interrupted at any moment. No cleanup function call is + * required and the graph structure can be freed normally. + * + * Helper functions can be used to find a link between two given pads, or a pad + * connected to another pad through an enabled link + * + * media_entity_find_link(struct media_pad *source, + * struct media_pad *sink); + * + * media_entity_remote_pad(struct media_pad *pad); + * + * Refer to the kerneldoc documentation for more information. + * + * + * Use count and power handling + * ---------------------------- + * + * Due to the wide differences between drivers regarding power management needs, + * the media controller does not implement power management. However, the + * media_entity structure includes a use_count field that media drivers can use to + * track the number of users of every entity for power management needs. + * + * The use_count field is owned by media drivers and must not be touched by entity + * drivers. Access to the field must be protected by the media device graph_mutex + * lock. + * + * + * Links setup + * ----------- + * + * Link properties can be modified at runtime by calling + * + * media_entity_setup_link(struct media_link *link, u32 flags); + * + * The flags argument contains the requested new link flags. + * + * The only configurable property is the ENABLED link flag to enable/disable a + * link. Links marked with the IMMUTABLE link flag can not be enabled or disabled. + * + * When a link is enabled or disabled, the media framework calls the + * link_setup operation for the two entities at the source and sink of the link, + * in that order. If the second link_setup call fails, another link_setup call is + * made on the first entity to restore the original link flags. + * + * Media device drivers can be notified of link setup operations by setting the + * media_device::link_notify pointer to a callback function. If provided, the + * notification callback will be called before enabling and after disabling + * links. + * + * Entity drivers must implement the link_setup operation if any of their links + * is non-immutable. The operation must either configure the hardware or store + * the configuration information to be applied later. + * + * Link configuration must not have any side effect on other links. If an enabled + * link at a sink pad prevents another link at the same pad from being enabled, + * the link_setup operation must return -EBUSY and can't implicitly disable the + * first enabled link. + * + * + * Pipelines and media streams + * --------------------------- + * + * When starting streaming, drivers must notify all entities in the pipeline to + * prevent link states from being modified during streaming by calling + * + * media_entity_pipeline_start(struct media_entity *entity, + * struct media_pipeline *pipe); + * + * The function will mark all entities connected to the given entity through + * enabled links, either directly or indirectly, as streaming. + * + * The media_pipeline instance pointed to by the pipe argument will be stored in + * every entity in the pipeline. Drivers should embed the media_pipeline structure + * in higher-level pipeline structures and can then access the pipeline through + * the media_entity pipe field. + * + * Calls to media_entity_pipeline_start() can be nested. The pipeline pointer must + * be identical for all nested calls to the function. + * + * media_entity_pipeline_start() may return an error. In that case, it will + * clean up any of the changes it did by itself. + * + * When stopping the stream, drivers must notify the entities with + * + * media_entity_pipeline_stop(struct media_entity *entity); + * + * If multiple calls to media_entity_pipeline_start() have been made the same + * number of media_entity_pipeline_stop() calls are required to stop streaming. The + * media_entity pipe field is reset to NULL on the last nested stop call. + * + * Link configuration will fail with -EBUSY by default if either end of the link is + * a streaming entity. Links that can be modified while streaming must be marked + * with the MEDIA_LNK_FL_DYNAMIC flag. + * + * If other operations need to be disallowed on streaming entities (such as + * changing entities configuration parameters) drivers can explicitly check the + * media_entity stream_count field to find out if an entity is streaming. This + * operation must be done with the media_device graph_mutex held. + * + * + * Link validation + * --------------- + * + * Link validation is performed by media_entity_pipeline_start() for any + * entity which has sink pads in the pipeline. The + * media_entity::link_validate() callback is used for that purpose. In + * link_validate() callback, entity driver should check that the properties of + * the source pad of the connected entity and its own sink pad match. It is up + * to the type of the entity (and in the end, the properties of the hardware) + * what matching actually means. + * + * Subsystems should facilitate link validation by providing subsystem specific + * helper functions to provide easy access for commonly needed information, and + * in the end provide a way to use driver-specific callbacks. + */ + struct device; /** -- GitLab From f1fd3289e8c2b99cdf5c1c4426a7d28a809159c2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 09:13:23 -0200 Subject: [PATCH 2532/2855] [media] media-entity.h: convert media_entity_cleanup to inline This function was used in the past to free the links that were allocated by the media controller core. However, this is not needed anymore. We should likely get rid of the funcion on some function, but, for now, let's just convert into an inlined function and let the compiler to get rid of it. Suggested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 6 ------ include/media/media-entity.h | 3 ++- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index ef2102ac0c66d..849db4f6f1f37 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -246,12 +246,6 @@ media_entity_pads_init(struct media_entity *entity, u16 num_pads, } EXPORT_SYMBOL_GPL(media_entity_pads_init); -void -media_entity_cleanup(struct media_entity *entity) -{ -} -EXPORT_SYMBOL_GPL(media_entity_cleanup); - /* ----------------------------------------------------------------------------- * Graph traversal */ diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 031536723d8ca..e9bc5857899cd 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -345,7 +345,8 @@ void media_gobj_remove(struct media_gobj *gobj); int media_entity_pads_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads); -void media_entity_cleanup(struct media_entity *entity); + +static inline void media_entity_cleanup(struct media_entity *entity) {}; __must_check int media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, -- GitLab From db7ee32aa1859c155e634a4d5c44b9cff4c9a6e5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 11:06:08 -0200 Subject: [PATCH 2533/2855] [media] media-device.h: Improve documentation and update it Now that we moved the content of the media-framework.txt into the kerneldoc documentation, move the per-function specific documentation to the corresponding functions and clean it up. It would be good if we had already the markdown kernel-doc patches merged upstream, but, while we doesn't have it, let's make it less ugly at device-drivers.xml. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 429 ++++++++++++++++------------------- include/media/media-entity.h | 148 ++++++++++++ 2 files changed, 339 insertions(+), 238 deletions(-) diff --git a/include/media/media-device.h b/include/media/media-device.h index 6728528df9e2d..65fdd44e05efa 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -33,23 +33,11 @@ /** * DOC: Media Controller * - * Linux kernel media framework - * ============================ - * - * This document describes the Linux kernel media framework, its data structures, - * functions and their usage. - * - * - * Introduction - * ------------ - * - * The media controller API is documented in DocBook format in - * Documentation/DocBook/media/v4l/media-controller.xml. This document will focus + * The media controller userspace API is documented in DocBook format in + * Documentation/DocBook/media/v4l/media-controller.xml. This document focus * on the kernel-side implementation of the media framework. * - * - * Abstract media device model - * --------------------------- + * * Abstract media device model: * * Discovering a device internal topology, and configuring it at runtime, is one * of the goals of the media framework. To achieve this, hardware devices are @@ -72,195 +60,104 @@ * pad to a sink pad. * * - * Media device - * ------------ + * * Media device: * - * A media device is represented by a struct media_device instance, defined in + * A media device is represented by a struct &media_device instance, defined in * include/media/media-device.h. Allocation of the structure is handled by the - * media device driver, usually by embedding the media_device instance in a + * media device driver, usually by embedding the &media_device instance in a * larger driver-specific structure. * * Drivers register media device instances by calling + * __media_device_register() via the macro media_device_register() + * and unregistered by calling + * media_device_unregister(). * - * media_device_register(struct media_device *mdev); - * - * The caller is responsible for initializing the media_device structure before - * registration. The following fields must be set: - * - * - dev must point to the parent device (usually a pci_dev, usb_interface or - * platform_device instance). - * - * - model must be filled with the device model name as a NUL-terminated UTF-8 - * string. The device/model revision must not be stored in this field. - * - * The following fields are optional: - * - * - serial is a unique serial number stored as a NUL-terminated ASCII string. - * The field is big enough to store a GUID in text form. If the hardware - * doesn't provide a unique serial number this field must be left empty. - * - * - bus_info represents the location of the device in the system as a - * NUL-terminated ASCII string. For PCI/PCIe devices bus_info must be set to - * "PCI:" (or "PCIe:") followed by the value of pci_name(). For USB devices, - * the usb_make_path() function must be used. This field is used by - * applications to distinguish between otherwise identical devices that don't - * provide a serial number. - * - * - hw_revision is the hardware device revision in a driver-specific format. - * When possible the revision should be formatted with the KERNEL_VERSION - * macro. - * - * - driver_version is formatted with the KERNEL_VERSION macro. The version - * minor must be incremented when new features are added to the userspace API - * without breaking binary compatibility. The version major must be - * incremented when binary compatibility is broken. - * - * Upon successful registration a character device named media[0-9]+ is created. - * The device major and minor numbers are dynamic. The model name is exported as - * a sysfs attribute. - * - * Drivers unregister media device instances by calling - * - * media_device_unregister(struct media_device *mdev); - * - * Unregistering a media device that hasn't been registered is *NOT* safe. - * - * - * Entities, pads and links - * ------------------------ + * * Entities, pads and links: * * - Entities * - * Entities are represented by a struct media_entity instance, defined in + * Entities are represented by a struct &media_entity instance, defined in * include/media/media-entity.h. The structure is usually embedded into a * higher-level structure, such as a v4l2_subdev or video_device instance, * although drivers can allocate entities directly. * * Drivers initialize entity pads by calling - * - * media_entity_pads_init(struct media_entity *entity, u16 num_pads, - * struct media_pad *pads); - * - * If no pads are needed, drivers could directly fill entity->num_pads - * with 0 and entity->pads with NULL or to call the above function that - * will do the same. - * - * The media_entity name, type and flags fields should be initialized before - * calling media_device_register_entity(). Entities embedded in higher-level - * standard structures can have some of those fields set by the higher-level - * framework. - * - * As the number of pads is known in advance, the pads array is not allocated - * dynamically but is managed by the entity driver. Most drivers will embed the - * pads array in a driver-specific structure, avoiding dynamic allocation. - * - * Drivers must set the direction of every pad in the pads array before calling - * media_entity_pads_init. The function will initialize the other pads fields. - * - * Unlike the number of pads, the total number of links isn't always known in - * advance by the entity driver. As an initial estimate, media_entity_pads_init - * pre-allocates a number of links equal to the number of pads. The links array - * will be reallocated if it grows beyond the initial estimate. + * media_entity_pads_init(). * * Drivers register entities with a media device by calling + * media_device_register_entity() + * and unregistred by calling + * media_device_unregister_entity(). * - * media_device_register_entity(struct media_device *mdev, - * struct media_entity *entity); + * - Interfaces * - * Entities are identified by a unique positive integer ID. Drivers can provide an - * ID by filling the media_entity id field prior to registration, or request the - * media controller framework to assign an ID automatically. Drivers that provide - * IDs manually must ensure that all IDs are unique. IDs are not guaranteed to be - * contiguous even when they are all assigned automatically by the framework. + * Interfaces are represented by a struct &media_interface instance, defined in + * include/media/media-entity.h. Currently, only one type of interface is + * defined: a device node. Such interfaces are represented by a struct + * &media_intf_devnode. * - * Drivers unregister entities by calling - * - * media_device_unregister_entity(struct media_entity *entity); - * - * Unregistering an entity will not change the IDs of the other entities, and the - * ID will never be reused for a newly registered entity. - * - * When a media device is unregistered, all its entities are unregistered - * automatically. No manual entities unregistration is then required. - * - * Drivers free resources associated with an entity by calling - * - * media_entity_cleanup(struct media_entity *entity); - * - * This function must be called during the cleanup phase after unregistering the - * entity. Note that the media_entity instance itself must be freed explicitly by - * the driver if required. - * - * Entities have flags that describe the entity capabilities and state. - * - * MEDIA_ENT_FL_DEFAULT indicates the default entity for a given type. - * This can be used to report the default audio and video devices or the - * default camera sensor. - * - * Logical entity groups can be defined by setting the group ID of all member - * entities to the same non-zero value. An entity group serves no purpose in the - * kernel, but is reported to userspace during entities enumeration. - * - * Media device drivers should define groups if several entities are logically - * bound together. Example usages include reporting - * - * - ALSA, VBI and video nodes that carry the same media stream - * - lens and flash controllers associated with a sensor + * Drivers initialize and create device node interfaces by calling + * media_devnode_create() + * and remove them by calling: + * media_devnode_remove(). * * - Pads * - * Pads are represented by a struct media_pad instance, defined in + * Pads are represented by a struct &media_pad instance, defined in * include/media/media-entity.h. Each entity stores its pads in a pads array * managed by the entity driver. Drivers usually embed the array in a * driver-specific structure. * - * Pads are identified by their entity and their 0-based index in the pads array. - * Both information are stored in the media_pad structure, making the media_pad - * pointer the canonical way to store and pass link references. + * Pads are identified by their entity and their 0-based index in the pads + * array. + * Both information are stored in the &media_pad structure, making the + * &media_pad pointer the canonical way to store and pass link references. * * Pads have flags that describe the pad capabilities and state. * - * MEDIA_PAD_FL_SINK indicates that the pad supports sinking data. - * MEDIA_PAD_FL_SOURCE indicates that the pad supports sourcing data. + * %MEDIA_PAD_FL_SINK indicates that the pad supports sinking data. + * %MEDIA_PAD_FL_SOURCE indicates that the pad supports sourcing data. * - * One and only one of MEDIA_PAD_FL_SINK and MEDIA_PAD_FL_SOURCE must be set for - * each pad. + * NOTE: One and only one of %MEDIA_PAD_FL_SINK and %MEDIA_PAD_FL_SOURCE must + * be set for each pad. * * - Links * - * Links are represented by a struct media_link instance, defined in - * include/media/media-entity.h. Each entity stores all links originating at or - * targeting any of its pads in a links array. A given link is thus stored - * twice, once in the source entity and once in the target entity. The array is - * pre-allocated and grows dynamically as needed. + * Links are represented by a struct &media_link instance, defined in + * include/media/media-entity.h. There are two types of links: + * + * 1. pad to pad links: * - * Drivers create links by calling + * Associate two entities via their PADs. Each entity has a list that points + * to all links originating at or targeting any of its pads. + * A given link is thus stored twice, once in the source entity and once in + * the target entity. * - * media_create_pad_link(struct media_entity *source, u16 source_pad, - * struct media_entity *sink, u16 sink_pad, - * u32 flags); + * Drivers create pad to pad links by calling: + * media_create_pad_link() and remove with media_entity_remove_links(). * - * An entry in the link array of each entity is allocated and stores pointers - * to source and sink pads. + * 2. interface to entity links: * - * Links have flags that describe the link capabilities and state. + * Associate one interface to a Link. * - * MEDIA_LNK_FL_ENABLED indicates that the link is enabled and can be used - * to transfer media data. When two or more links target a sink pad, only - * one of them can be enabled at a time. - * MEDIA_LNK_FL_IMMUTABLE indicates that the link enabled state can't be - * modified at runtime. If MEDIA_LNK_FL_IMMUTABLE is set, then - * MEDIA_LNK_FL_ENABLED must also be set since an immutable link is always - * enabled. + * Drivers create interface to entity links by calling: + * media_create_intf_link() and remove with media_remove_intf_links(). * + * NOTE: * - * Graph traversal - * --------------- + * Links can only be created after having both ends already created. + * + * Links have flags that describe the link capabilities and state. The + * valid values are described at media_create_pad_link() and + * media_create_intf_link(). + * + * Graph traversal: * * The media framework provides APIs to iterate over entities in a graph. * - * To iterate over all entities belonging to a media device, drivers can use the - * media_device_for_each_entity macro, defined in include/media/media-device.h. + * To iterate over all entities belonging to a media device, drivers can use + * the media_device_for_each_entity macro, defined in + * include/media/media-device.h. * * struct media_entity *entity; * @@ -279,126 +176,82 @@ * currently defined as 16. * * Drivers initiate a graph traversal by calling - * - * media_entity_graph_walk_start(struct media_entity_graph *graph, - * struct media_entity *entity); + * media_entity_graph_walk_start() * * The graph structure, provided by the caller, is initialized to start graph * traversal at the given entity. * * Drivers can then retrieve the next entity by calling - * - * media_entity_graph_walk_next(struct media_entity_graph *graph); + * media_entity_graph_walk_next() * * When the graph traversal is complete the function will return NULL. * - * Graph traversal can be interrupted at any moment. No cleanup function call is - * required and the graph structure can be freed normally. + * Graph traversal can be interrupted at any moment. No cleanup function call + * is required and the graph structure can be freed normally. * * Helper functions can be used to find a link between two given pads, or a pad * connected to another pad through an enabled link + * media_entity_find_link() and media_entity_remote_pad() * - * media_entity_find_link(struct media_pad *source, - * struct media_pad *sink); - * - * media_entity_remote_pad(struct media_pad *pad); - * - * Refer to the kerneldoc documentation for more information. - * - * - * Use count and power handling - * ---------------------------- - * - * Due to the wide differences between drivers regarding power management needs, - * the media controller does not implement power management. However, the - * media_entity structure includes a use_count field that media drivers can use to - * track the number of users of every entity for power management needs. + * Use count and power handling: * - * The use_count field is owned by media drivers and must not be touched by entity - * drivers. Access to the field must be protected by the media device graph_mutex - * lock. + * Due to the wide differences between drivers regarding power management + * needs, the media controller does not implement power management. However, + * the &media_entity structure includes a use_count field that media drivers + * can use to track the number of users of every entity for power management + * needs. * + * The &media_entity.@use_count field is owned by media drivers and must not be + * touched by entity drivers. Access to the field must be protected by the + * &media_device.@graph_mutex lock. * - * Links setup - * ----------- + * Links setup: * * Link properties can be modified at runtime by calling + * media_entity_setup_link() * - * media_entity_setup_link(struct media_link *link, u32 flags); - * - * The flags argument contains the requested new link flags. - * - * The only configurable property is the ENABLED link flag to enable/disable a - * link. Links marked with the IMMUTABLE link flag can not be enabled or disabled. - * - * When a link is enabled or disabled, the media framework calls the - * link_setup operation for the two entities at the source and sink of the link, - * in that order. If the second link_setup call fails, another link_setup call is - * made on the first entity to restore the original link flags. - * - * Media device drivers can be notified of link setup operations by setting the - * media_device::link_notify pointer to a callback function. If provided, the - * notification callback will be called before enabling and after disabling - * links. - * - * Entity drivers must implement the link_setup operation if any of their links - * is non-immutable. The operation must either configure the hardware or store - * the configuration information to be applied later. - * - * Link configuration must not have any side effect on other links. If an enabled - * link at a sink pad prevents another link at the same pad from being enabled, - * the link_setup operation must return -EBUSY and can't implicitly disable the - * first enabled link. - * - * - * Pipelines and media streams - * --------------------------- + * Pipelines and media streams: * * When starting streaming, drivers must notify all entities in the pipeline to * prevent link states from being modified during streaming by calling - * - * media_entity_pipeline_start(struct media_entity *entity, - * struct media_pipeline *pipe); + * media_entity_pipeline_start(). * * The function will mark all entities connected to the given entity through * enabled links, either directly or indirectly, as streaming. * - * The media_pipeline instance pointed to by the pipe argument will be stored in - * every entity in the pipeline. Drivers should embed the media_pipeline structure - * in higher-level pipeline structures and can then access the pipeline through - * the media_entity pipe field. + * The &media_pipeline instance pointed to by the pipe argument will be stored + * in every entity in the pipeline. Drivers should embed the &media_pipeline + * structure in higher-level pipeline structures and can then access the + * pipeline through the &media_entity pipe field. * - * Calls to media_entity_pipeline_start() can be nested. The pipeline pointer must - * be identical for all nested calls to the function. + * Calls to media_entity_pipeline_start() can be nested. The pipeline pointer + * must be identical for all nested calls to the function. * * media_entity_pipeline_start() may return an error. In that case, it will * clean up any of the changes it did by itself. * * When stopping the stream, drivers must notify the entities with - * - * media_entity_pipeline_stop(struct media_entity *entity); + * media_entity_pipeline_stop(). * * If multiple calls to media_entity_pipeline_start() have been made the same - * number of media_entity_pipeline_stop() calls are required to stop streaming. The - * media_entity pipe field is reset to NULL on the last nested stop call. + * number of media_entity_pipeline_stop() calls are required to stop streaming. + * The &media_entity pipe field is reset to NULL on the last nested stop call. * - * Link configuration will fail with -EBUSY by default if either end of the link is - * a streaming entity. Links that can be modified while streaming must be marked - * with the MEDIA_LNK_FL_DYNAMIC flag. + * Link configuration will fail with -%EBUSY by default if either end of the + * link is a streaming entity. Links that can be modified while streaming must + * be marked with the %MEDIA_LNK_FL_DYNAMIC flag. * * If other operations need to be disallowed on streaming entities (such as * changing entities configuration parameters) drivers can explicitly check the * media_entity stream_count field to find out if an entity is streaming. This * operation must be done with the media_device graph_mutex held. * - * - * Link validation - * --------------- + * Link validation: * * Link validation is performed by media_entity_pipeline_start() for any * entity which has sink pads in the pipeline. The - * media_entity::link_validate() callback is used for that purpose. In - * link_validate() callback, entity driver should check that the properties of + * &media_entity.@link_validate() callback is used for that purpose. In + * @link_validate() callback, entity driver should check that the properties of * the source pad of the connected entity and its own sink pad match. It is up * to the type of the entity (and in the end, the properties of the hardware) * what matching actually means. @@ -484,13 +337,113 @@ struct media_device { /* media_devnode to media_device */ #define to_media_device(node) container_of(node, struct media_device, devnode) +/** + * __media_device_register() - Registers a media device element + * + * @mdev: pointer to struct &media_device + * @owner: should be filled with %THIS_MODULE + * + * Users, should, instead, call the media_device_register() macro. + * + * The caller is responsible for initializing the media_device structure before + * registration. The following fields must be set: + * + * - dev must point to the parent device (usually a &pci_dev, &usb_interface or + * &platform_device instance). + * + * - model must be filled with the device model name as a NUL-terminated UTF-8 + * string. The device/model revision must not be stored in this field. + * + * The following fields are optional: + * + * - serial is a unique serial number stored as a NUL-terminated ASCII string. + * The field is big enough to store a GUID in text form. If the hardware + * doesn't provide a unique serial number this field must be left empty. + * + * - bus_info represents the location of the device in the system as a + * NUL-terminated ASCII string. For PCI/PCIe devices bus_info must be set to + * "PCI:" (or "PCIe:") followed by the value of pci_name(). For USB devices, + * the usb_make_path() function must be used. This field is used by + * applications to distinguish between otherwise identical devices that don't + * provide a serial number. + * + * - hw_revision is the hardware device revision in a driver-specific format. + * When possible the revision should be formatted with the KERNEL_VERSION + * macro. + * + * - driver_version is formatted with the KERNEL_VERSION macro. The version + * minor must be incremented when new features are added to the userspace API + * without breaking binary compatibility. The version major must be + * incremented when binary compatibility is broken. + * + * Notes: + * + * Upon successful registration a character device named media[0-9]+ is created. + * The device major and minor numbers are dynamic. The model name is exported as + * a sysfs attribute. + * + * Unregistering a media device that hasn't been registered is *NOT* safe. + */ int __must_check __media_device_register(struct media_device *mdev, struct module *owner); #define media_device_register(mdev) __media_device_register(mdev, THIS_MODULE) + +/** + * __media_device_unregister() - Unegisters a media device element + * + * @mdev: pointer to struct &media_device + */ void media_device_unregister(struct media_device *mdev); +/** + * media_device_register_entity() - registers a media entity inside a + * previously registered media device. + * + * @mdev: pointer to struct &media_device + * @entity: pointer to struct &media_entity to be registered + * + * Entities are identified by a unique positive integer ID. The media + * controller framework will such ID automatically. IDs are not guaranteed + * to be contiguous, and the ID number can change on newer Kernel versions. + * So, neither the driver nor userspace should hardcode ID numbers to refer + * to the entities, but, instead, use the framework to find the ID, when + * needed. + * + * The media_entity name, type and flags fields should be initialized before + * calling media_device_register_entity(). Entities embedded in higher-level + * standard structures can have some of those fields set by the higher-level + * framework. + * + * If the device has pads, media_entity_pads_init() should be called before + * this function. Otherwise, the &media_entity.@pad and &media_entity.@num_pads + * should be zeroed before calling this function. + * + * Entities have flags that describe the entity capabilities and state: + * + * %MEDIA_ENT_FL_DEFAULT indicates the default entity for a given type. + * This can be used to report the default audio and video devices or the + * default camera sensor. + */ int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity); + +/* + * media_device_unregister_entity() - unregisters a media entity. + * + * @entity: pointer to struct &media_entity to be unregistered + * + * All links associated with the entity and all PADs are automatically + * unregistered from the media_device when this function is called. + * + * Unregistering an entity will not change the IDs of the other entities and + * the previoully used ID will never be reused for a newly registered entities. + * + * When a media device is unregistered, all its entities are unregistered + * automatically. No manual entities unregistration is then required. + * + * Note: the media_entity instance itself must be freed explicitly by + * the driver if required. + */ void media_device_unregister_entity(struct media_entity *entity); struct media_device *media_device_get_devres(struct device *dev); struct media_device *media_device_find_devres(struct device *dev); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index e9bc5857899cd..51a7353effd0a 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -343,18 +343,112 @@ void media_gobj_init(struct media_device *mdev, struct media_gobj *gobj); void media_gobj_remove(struct media_gobj *gobj); +/** + * media_entity_pads_init() - Initialize the entity pads + * + * @entity: entity where the pads belong + * @num_pads: number of pads to be initialized + * @pads: pads array + * + * If no pads are needed, drivers could either directly fill + * &media_entity->@num_pads with 0 and &media_entity->@pads with NULL or call + * this function that will do the same. + * + * As the number of pads is known in advance, the pads array is not allocated + * dynamically but is managed by the entity driver. Most drivers will embed the + * pads array in a driver-specific structure, avoiding dynamic allocation. + * + * Drivers must set the direction of every pad in the pads array before calling + * media_entity_pads_init(). The function will initialize the other pads fields. + */ int media_entity_pads_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads); +/** + * media_entity_cleanup() - free resources associated with an entity + * + * @entity: entity where the pads belong + * + * This function must be called during the cleanup phase after unregistering + * the entity (currently, it does nothing). + */ static inline void media_entity_cleanup(struct media_entity *entity) {}; +/** + * media_create_pad_link() - creates a link between two entities. + * + * @source: pointer to &media_entity of the source pad. + * @source_pad: number of the source pad in the pads array + * @sink: pointer to &media_entity of the sink pad. + * @sink_pad: number of the sink pad in the pads array. + * @flags: Link flags, as defined in include/uapi/linux/media.h. + * + * Valid values for flags: + * A %MEDIA_LNK_FL_ENABLED flag indicates that the link is enabled and can be + * used to transfer media data. When two or more links target a sink pad, + * only one of them can be enabled at a time. + * + * A %MEDIA_LNK_FL_IMMUTABLE flag indicates that the link enabled state can't + * be modified at runtime. If %MEDIA_LNK_FL_IMMUTABLE is set, then + * %MEDIA_LNK_FL_ENABLED must also be set since an immutable link is + * always enabled. + * + * NOTE: + * + * Before calling this function, media_entity_pads_init() and + * media_device_register_entity() should be called previously for both ends. + */ __must_check int media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags); void __media_entity_remove_links(struct media_entity *entity); + +/** + * media_entity_remove_links() - remove all links associated with an entity + * + * @entity: pointer to &media_entity + * + * Note: this is called automatically when an entity is unregistered via + * media_device_register_entity(). + */ void media_entity_remove_links(struct media_entity *entity); int __media_entity_setup_link(struct media_link *link, u32 flags); + +/** + * media_entity_setup_link() - changes the link flags properties in runtime + * + * @link: pointer to &media_link + * @flags: the requested new link flags + * + * The only configurable property is the %MEDIA_LNK_FL_ENABLED link flag + * flag to enable/disable a link. Links marked with the + * %MEDIA_LNK_FL_IMMUTABLE link flag can not be enabled or disabled. + * + * When a link is enabled or disabled, the media framework calls the + * link_setup operation for the two entities at the source and sink of the + * link, in that order. If the second link_setup call fails, another + * link_setup call is made on the first entity to restore the original link + * flags. + * + * Media device drivers can be notified of link setup operations by setting the + * media_device::link_notify pointer to a callback function. If provided, the + * notification callback will be called before enabling and after disabling + * links. + * + * Entity drivers must implement the link_setup operation if any of their links + * is non-immutable. The operation must either configure the hardware or store + * the configuration information to be applied later. + * + * Link configuration must not have any side effect on other links. If an + * enabled link at a sink pad prevents another link at the same pad from + * being enabled, the link_setup operation must return -EBUSY and can't + * implicitly disable the first enabled link. + * + * NOTE: the valid values of the flags for the link is the same as described + * on media_create_pad_link(), for pad to pad links or the same as described + * on media_create_intf_link(), for interface to entity links. + */ int media_entity_setup_link(struct media_link *link, u32 flags); struct media_link *media_entity_find_link(struct media_pad *source, struct media_pad *sink); @@ -371,18 +465,72 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_pipeline *pipe); void media_entity_pipeline_stop(struct media_entity *entity); +/** + * media_devnode_create() - creates and initializes a device node interface + * + * @mdev: pointer to struct &media_device + * @type: type of the interface, as given by MEDIA_INTF_T_* macros + * as defined in the uapi/media/media.h header. + * @flags: Interface flags as defined in uapi/media/media.h. + * @major: Device node major number. + * @minor: Device node minor number. + * + * Return: if succeeded, returns a pointer to the newly allocated + * &media_intf_devnode pointer. + */ struct media_intf_devnode * __must_check media_devnode_create(struct media_device *mdev, u32 type, u32 flags, u32 major, u32 minor); +/** + * media_devnode_remove() - removes a device node interface + * + * @devnode: pointer to &media_intf_devnode to be freed. + * + * When a device node interface is removed, all links to it are automatically + * removed. + */ void media_devnode_remove(struct media_intf_devnode *devnode); struct media_link * + +/** + * media_create_intf_link() - creates a link between an entity and an interface + * + * @entity: pointer to %media_entity + * @intf: pointer to %media_interface + * @flags: Link flags, as defined in include/uapi/linux/media.h. + * + * + * Valid values for flags: + * The %MEDIA_LNK_FL_ENABLED flag indicates that the interface is connected to + * the entity hardware. That's the default value for interfaces. An + * interface may be disabled if the hardware is busy due to the usage + * of some other interface that it is currently controlling the hardware. + * A typical example is an hybrid TV device that handle only one type of + * stream on a given time. So, when the digital TV is streaming, + * the V4L2 interfaces won't be enabled, as such device is not able to + * also stream analog TV or radio. + * + * Note: + * + * Before calling this function, media_devnode_create() should be called for + * the interface and media_device_register_entity() should be called for the + * interface that will be part of the link. + */ __must_check media_create_intf_link(struct media_entity *entity, struct media_interface *intf, u32 flags); void __media_remove_intf_link(struct media_link *link); void media_remove_intf_link(struct media_link *link); void __media_remove_intf_links(struct media_interface *intf); +/** + * media_remove_intf_links() - remove all links associated with an interface + * + * @intf: pointer to &media_interface + * + * Note: this is called automatically when an entity is unregistered via + * media_device_register_entity() and by media_devnode_remove(). + */ void media_remove_intf_links(struct media_interface *intf); -- GitLab From 97d0a70ae5e2391f213966a69c3b6f96f2c9f25b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 11:12:57 -0200 Subject: [PATCH 2534/2855] [media] media: remove extra blank lines No functional changes. Suggested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 3 --- include/media/media-device.h | 2 -- 2 files changed, 5 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 849db4f6f1f37..5a5432524c102 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -310,7 +310,6 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph, } EXPORT_SYMBOL_GPL(media_entity_graph_walk_start); - /** * media_entity_graph_walk_next - Get the next entity in the graph * @graph: Media graph structure @@ -850,7 +849,6 @@ struct media_pad *media_entity_remote_pad(struct media_pad *pad) } EXPORT_SYMBOL_GPL(media_entity_remote_pad); - static void media_interface_init(struct media_device *mdev, struct media_interface *intf, u32 gobj_type, @@ -915,7 +913,6 @@ struct media_link *media_create_intf_link(struct media_entity *entity, } EXPORT_SYMBOL_GPL(media_create_intf_link); - void __media_remove_intf_link(struct media_link *link) { list_del(&link->list); diff --git a/include/media/media-device.h b/include/media/media-device.h index 65fdd44e05efa..f9907a7728d46 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -463,8 +463,6 @@ struct media_device *media_device_find_devres(struct device *dev); /* Iterate over all links. */ #define media_device_for_each_link(link, mdev) \ list_for_each_entry(link, &(mdev)->links, graph_obj.list) - - #else static inline int media_device_register(struct media_device *mdev) { -- GitLab From 5abad22fd1402c23da1f6ade8cec59ac07a28fc5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 11:19:38 -0200 Subject: [PATCH 2535/2855] [media] media-entity: get rid of forward __media_entity_remove_link() declaration Move this function to happen earlier, in order to avoid a uneeded forward declaration. Suggested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 67 +++++++++++++++++------------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 5a5432524c102..452af1d5a20d9 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -588,7 +588,38 @@ static struct media_link *media_add_link(struct list_head *head) } static void __media_entity_remove_link(struct media_entity *entity, - struct media_link *link); + struct media_link *link) +{ + struct media_link *rlink, *tmp; + struct media_entity *remote; + unsigned int r = 0; + + if (link->source->entity == entity) + remote = link->sink->entity; + else + remote = link->source->entity; + + list_for_each_entry_safe(rlink, tmp, &remote->links, list) { + if (rlink != link->reverse) { + r++; + continue; + } + + if (link->source->entity == entity) + remote->num_backlinks--; + + /* Remove the remote link */ + list_del(&rlink->list); + media_gobj_remove(&rlink->graph_obj); + kfree(rlink); + + if (--remote->num_links == 0) + break; + } + list_del(&link->list); + media_gobj_remove(&link->graph_obj); + kfree(link); +} int media_create_pad_link(struct media_entity *source, u16 source_pad, @@ -642,40 +673,6 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, } EXPORT_SYMBOL_GPL(media_create_pad_link); -static void __media_entity_remove_link(struct media_entity *entity, - struct media_link *link) -{ - struct media_link *rlink, *tmp; - struct media_entity *remote; - unsigned int r = 0; - - if (link->source->entity == entity) - remote = link->sink->entity; - else - remote = link->source->entity; - - list_for_each_entry_safe(rlink, tmp, &remote->links, list) { - if (rlink != link->reverse) { - r++; - continue; - } - - if (link->source->entity == entity) - remote->num_backlinks--; - - /* Remove the remote link */ - list_del(&rlink->list); - media_gobj_remove(&rlink->graph_obj); - kfree(rlink); - - if (--remote->num_links == 0) - break; - } - list_del(&link->list); - media_gobj_remove(&link->graph_obj); - kfree(link); -} - void __media_entity_remove_links(struct media_entity *entity) { struct media_link *link, *tmp; -- GitLab From 58f69ee9da3a2486450dac626c352f69faf964e9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 11:25:23 -0200 Subject: [PATCH 2536/2855] [media] media_entity: get rid of a unused var > > > + if (rlink != link->reverse) { > > > + r++; > > > > The variable is incremented here but otherwise never used, you can remove it. Suggested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 452af1d5a20d9..57de11281af1c 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -592,7 +592,6 @@ static void __media_entity_remove_link(struct media_entity *entity, { struct media_link *rlink, *tmp; struct media_entity *remote; - unsigned int r = 0; if (link->source->entity == entity) remote = link->sink->entity; @@ -600,10 +599,8 @@ static void __media_entity_remove_link(struct media_entity *entity, remote = link->source->entity; list_for_each_entry_safe(rlink, tmp, &remote->links, list) { - if (rlink != link->reverse) { - r++; + if (rlink != link->reverse) continue; - } if (link->source->entity == entity) remote->num_backlinks--; -- GitLab From c350ef830f2c3dfe80e9a777c8a64ac1fb186b9a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 11:55:40 -0200 Subject: [PATCH 2537/2855] [media] media_entity: rename media_obj functions to *_create *_destroy Those media_obj_* functions are actually creating/destroying media graph objects. So, rename them to better represent what they're actually doing. No functional changes. This was created via this small shell script: for i in $(git grep -l media_gobj_init); do sed s,media_gobj_init,media_gobj_create,g <$i >a && mv a $i; done for i in $(git grep -l media_gobj_remove); do sed s,media_gobj_remove,media_gobj_destroy,g <$i >a && mv a $i; done Suggested-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 10 +++++----- drivers/media/media-entity.c | 26 +++++++++++++------------- include/media/media-entity.h | 4 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 537160bb461e0..f09f3a6f9c50b 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -591,7 +591,7 @@ void media_device_unregister(struct media_device *mdev) list_for_each_entry_safe(intf, tmp_intf, &mdev->interfaces, graph_obj.list) { __media_remove_intf_links(intf); - media_gobj_remove(&intf->graph_obj); + media_gobj_destroy(&intf->graph_obj); kfree(intf); } spin_unlock(&mdev->lock); @@ -628,11 +628,11 @@ int __must_check media_device_register_entity(struct media_device *mdev, spin_lock(&mdev->lock); /* Initialize media_gobj embedded at the entity */ - media_gobj_init(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); + media_gobj_create(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); /* Initialize objects at the pads */ for (i = 0; i < entity->num_pads; i++) - media_gobj_init(mdev, MEDIA_GRAPH_PAD, + media_gobj_create(mdev, MEDIA_GRAPH_PAD, &entity->pads[i].graph_obj); spin_unlock(&mdev->lock); @@ -673,10 +673,10 @@ void media_device_unregister_entity(struct media_entity *entity) /* Remove all pads that belong to this entity */ for (i = 0; i < entity->num_pads; i++) - media_gobj_remove(&entity->pads[i].graph_obj); + media_gobj_destroy(&entity->pads[i].graph_obj); /* Remove the entity */ - media_gobj_remove(&entity->graph_obj); + media_gobj_destroy(&entity->graph_obj); spin_unlock(&mdev->lock); entity->graph_obj.mdev = NULL; diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 57de11281af1c..861c8e7b87735 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -134,7 +134,7 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) } /** - * media_gobj_init - Initialize a graph object + * media_gobj_create - Initialize a graph object * * @mdev: Pointer to the media_device that contains the object * @type: Type of the object @@ -146,7 +146,7 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) * is embedded on some other object, this function should be called before * registering the object at the media controller. */ -void media_gobj_init(struct media_device *mdev, +void media_gobj_create(struct media_device *mdev, enum media_gobj_type type, struct media_gobj *gobj) { @@ -180,13 +180,13 @@ void media_gobj_init(struct media_device *mdev, } /** - * media_gobj_remove - Stop using a graph object on a media device + * media_gobj_destroy - Stop using a graph object on a media device * * @graph_obj: Pointer to the object * * This should be called at media_device_unregister_*() routines */ -void media_gobj_remove(struct media_gobj *gobj) +void media_gobj_destroy(struct media_gobj *gobj) { dev_dbg_obj(__func__, gobj); @@ -235,7 +235,7 @@ media_entity_pads_init(struct media_entity *entity, u16 num_pads, pads[i].entity = entity; pads[i].index = i; if (mdev) - media_gobj_init(mdev, MEDIA_GRAPH_PAD, + media_gobj_create(mdev, MEDIA_GRAPH_PAD, &entity->pads[i].graph_obj); } @@ -607,14 +607,14 @@ static void __media_entity_remove_link(struct media_entity *entity, /* Remove the remote link */ list_del(&rlink->list); - media_gobj_remove(&rlink->graph_obj); + media_gobj_destroy(&rlink->graph_obj); kfree(rlink); if (--remote->num_links == 0) break; } list_del(&link->list); - media_gobj_remove(&link->graph_obj); + media_gobj_destroy(&link->graph_obj); kfree(link); } @@ -638,7 +638,7 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, link->flags = flags; /* Initialize graph object embedded at the new link */ - media_gobj_init(source->graph_obj.mdev, MEDIA_GRAPH_LINK, + media_gobj_create(source->graph_obj.mdev, MEDIA_GRAPH_LINK, &link->graph_obj); /* Create the backlink. Backlinks are used to help graph traversal and @@ -656,7 +656,7 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, backlink->is_backlink = true; /* Initialize graph object embedded at the new link */ - media_gobj_init(sink->graph_obj.mdev, MEDIA_GRAPH_LINK, + media_gobj_create(sink->graph_obj.mdev, MEDIA_GRAPH_LINK, &backlink->graph_obj); link->reverse = backlink; @@ -852,7 +852,7 @@ static void media_interface_init(struct media_device *mdev, intf->flags = flags; INIT_LIST_HEAD(&intf->links); - media_gobj_init(mdev, gobj_type, &intf->graph_obj); + media_gobj_create(mdev, gobj_type, &intf->graph_obj); } /* Functions related to the media interface via device nodes */ @@ -880,7 +880,7 @@ EXPORT_SYMBOL_GPL(media_devnode_create); void media_devnode_remove(struct media_intf_devnode *devnode) { media_remove_intf_links(&devnode->intf); - media_gobj_remove(&devnode->intf.graph_obj); + media_gobj_destroy(&devnode->intf.graph_obj); kfree(devnode); } EXPORT_SYMBOL_GPL(media_devnode_remove); @@ -900,7 +900,7 @@ struct media_link *media_create_intf_link(struct media_entity *entity, link->flags = flags; /* Initialize graph object embedded at the new link */ - media_gobj_init(intf->graph_obj.mdev, MEDIA_GRAPH_LINK, + media_gobj_create(intf->graph_obj.mdev, MEDIA_GRAPH_LINK, &link->graph_obj); return link; @@ -910,7 +910,7 @@ EXPORT_SYMBOL_GPL(media_create_intf_link); void __media_remove_intf_link(struct media_link *link) { list_del(&link->list); - media_gobj_remove(&link->graph_obj); + media_gobj_destroy(&link->graph_obj); kfree(link); } EXPORT_SYMBOL_GPL(__media_remove_intf_link); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 51a7353effd0a..1b954fb88def5 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -338,10 +338,10 @@ struct media_entity_graph { #define intf_to_devnode(intf) \ container_of(intf, struct media_intf_devnode, intf) -void media_gobj_init(struct media_device *mdev, +void media_gobj_create(struct media_device *mdev, enum media_gobj_type type, struct media_gobj *gobj); -void media_gobj_remove(struct media_gobj *gobj); +void media_gobj_destroy(struct media_gobj *gobj); /** * media_entity_pads_init() - Initialize the entity pads -- GitLab From 1fc25d30a40c27b85510e6e598aec629532eb85c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 12:14:58 -0200 Subject: [PATCH 2538/2855] [media] media-entity.h: move kernel-doc tags from media-entity.c Several additional functions are described at media-entity.c. Moving them to the header file, to make the code cleaner and to have all such macros at the same place. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 163 +++-------------------------------- include/media/media-entity.h | 136 ++++++++++++++++++++++++++++- 2 files changed, 145 insertions(+), 154 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 861c8e7b87735..ada2b44ea4e15 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -26,15 +26,6 @@ #include #include -/** - * dev_dbg_obj - Prints in debug mode a change on some object - * - * @event_name: Name of the event to report. Could be __func__ - * @gobj: Pointer to the object - * - * Enabled only if DEBUG or CONFIG_DYNAMIC_DEBUG. Otherwise, it - * won't produce any code. - */ static inline const char *gobj_type(enum media_gobj_type type) { switch (type) { @@ -79,6 +70,15 @@ static inline const char *intf_type(struct media_interface *intf) } }; +/** + * dev_dbg_obj - Prints in debug mode a change on some object + * + * @event_name: Name of the event to report. Could be __func__ + * @gobj: Pointer to the object + * + * Enabled only if DEBUG or CONFIG_DYNAMIC_DEBUG. Otherwise, it + * won't produce any code. + */ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) { #if defined(DEBUG) || defined (CONFIG_DYNAMIC_DEBUG) @@ -133,19 +133,6 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) #endif } -/** - * media_gobj_create - Initialize a graph object - * - * @mdev: Pointer to the media_device that contains the object - * @type: Type of the object - * @gobj: Pointer to the object - * - * This routine initializes the embedded struct media_gobj inside a - * media graph object. It is called automatically if media_*_create() - * calls are used. However, if the object (entity, link, pad, interface) - * is embedded on some other object, this function should be called before - * registering the object at the media controller. - */ void media_gobj_create(struct media_device *mdev, enum media_gobj_type type, struct media_gobj *gobj) @@ -179,13 +166,6 @@ void media_gobj_create(struct media_device *mdev, dev_dbg_obj(__func__, gobj); } -/** - * media_gobj_destroy - Stop using a graph object on a media device - * - * @graph_obj: Pointer to the object - * - * This should be called at media_device_unregister_*() routines - */ void media_gobj_destroy(struct media_gobj *gobj) { dev_dbg_obj(__func__, gobj); @@ -196,31 +176,8 @@ void media_gobj_destroy(struct media_gobj *gobj) list_del(&gobj->list); } -/** - * media_entity_pads_init - Initialize a media entity - * - * @num_pads: Total number of sink and source pads. - * @pads: Array of 'num_pads' pads. - * - * The total number of pads is an intrinsic property of entities known by the - * entity driver, while the total number of links depends on hardware design - * and is an extrinsic property unknown to the entity driver. However, in most - * use cases the number of links can safely be assumed to be equal to or - * larger than the number of pads. - * - * For those reasons the links array can be preallocated based on the number - * of pads and will be reallocated later if extra links need to be created. - * - * This function allocates a links array with enough space to hold at least - * 'num_pads' elements. The media_entity::max_links field will be set to the - * number of allocated elements. - * - * The pads array is managed by the entity driver and passed to - * media_entity_pads_init() where its pointer will be stored in the entity structure. - */ -int -media_entity_pads_init(struct media_entity *entity, u16 num_pads, - struct media_pad *pads) +int media_entity_pads_init(struct media_entity *entity, u16 num_pads, + struct media_pad *pads) { struct media_device *mdev = entity->graph_obj.mdev; unsigned int i; @@ -285,16 +242,6 @@ static struct media_entity *stack_pop(struct media_entity_graph *graph) #define link_top(en) ((en)->stack[(en)->top].link) #define stack_top(en) ((en)->stack[(en)->top].entity) -/** - * media_entity_graph_walk_start - Start walking the media graph at a given entity - * @graph: Media graph structure that will be used to walk the graph - * @entity: Starting entity - * - * This function initializes the graph traversal structure to walk the entities - * graph starting at the given entity. The traversal structure must not be - * modified by the caller during graph traversal. When done the structure can - * safely be freed. - */ void media_entity_graph_walk_start(struct media_entity_graph *graph, struct media_entity *entity) { @@ -310,18 +257,6 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph, } EXPORT_SYMBOL_GPL(media_entity_graph_walk_start); -/** - * media_entity_graph_walk_next - Get the next entity in the graph - * @graph: Media graph structure - * - * Perform a depth-first traversal of the given media entities graph. - * - * The graph structure must have been previously initialized with a call to - * media_entity_graph_walk_start(). - * - * Return the next entity in the graph or NULL if the whole graph have been - * traversed. - */ struct media_entity * media_entity_graph_walk_next(struct media_entity_graph *graph) { @@ -370,20 +305,6 @@ EXPORT_SYMBOL_GPL(media_entity_graph_walk_next); * Pipeline management */ -/** - * media_entity_pipeline_start - Mark a pipeline as streaming - * @entity: Starting entity - * @pipe: Media pipeline to be assigned to all entities in the pipeline. - * - * Mark all entities connected to a given entity through enabled links, either - * directly or indirectly, as streaming. The given pipeline object is assigned to - * every entity in the pipeline and stored in the media_entity pipe field. - * - * Calls to this function can be nested, in which case the same number of - * media_entity_pipeline_stop() calls will be required to stop streaming. The - * pipeline pointer must be identical for all nested calls to - * media_entity_pipeline_start(). - */ __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_pipeline *pipe) { @@ -494,18 +415,6 @@ error: } EXPORT_SYMBOL_GPL(media_entity_pipeline_start); -/** - * media_entity_pipeline_stop - Mark a pipeline as not streaming - * @entity: Starting entity - * - * Mark all entities connected to a given entity through enabled links, either - * directly or indirectly, as not streaming. The media_entity pipe field is - * reset to NULL. - * - * If multiple calls to media_entity_pipeline_start() have been made, the same - * number of calls to this function are required to mark the pipeline as not - * streaming. - */ void media_entity_pipeline_stop(struct media_entity *entity) { struct media_device *mdev = entity->graph_obj.mdev; @@ -529,16 +438,6 @@ EXPORT_SYMBOL_GPL(media_entity_pipeline_stop); * Module use count */ -/* - * media_entity_get - Get a reference to the parent module - * @entity: The entity - * - * Get a reference to the parent media device module. - * - * The function will return immediately if @entity is NULL. - * - * Return a pointer to the entity on success or NULL on failure. - */ struct media_entity *media_entity_get(struct media_entity *entity) { if (entity == NULL) @@ -552,14 +451,6 @@ struct media_entity *media_entity_get(struct media_entity *entity) } EXPORT_SYMBOL_GPL(media_entity_get); -/* - * media_entity_put - Release the reference to the parent module - * @entity: The entity - * - * Release the reference count acquired by media_entity_get(). - * - * The function will return immediately if @entity is NULL. - */ void media_entity_put(struct media_entity *entity) { if (entity == NULL) @@ -718,20 +609,6 @@ static int __media_entity_setup_link_notify(struct media_link *link, u32 flags) return 0; } -/** - * __media_entity_setup_link - Configure a media link - * @link: The link being configured - * @flags: Link configuration flags - * - * The bulk of link setup is handled by the two entities connected through the - * link. This function notifies both entities of the link configuration change. - * - * If the link is immutable or if the current and new configuration are - * identical, return immediately. - * - * The user is expected to hold link->source->parent->mutex. If not, - * media_entity_setup_link() should be used instead. - */ int __media_entity_setup_link(struct media_link *link, u32 flags) { const u32 mask = MEDIA_LNK_FL_ENABLED; @@ -788,14 +665,6 @@ int media_entity_setup_link(struct media_link *link, u32 flags) } EXPORT_SYMBOL_GPL(media_entity_setup_link); -/** - * media_entity_find_link - Find a link between two pads - * @source: Source pad - * @sink: Sink pad - * - * Return a pointer to the link between the two entities. If no such link - * exists, return NULL. - */ struct media_link * media_entity_find_link(struct media_pad *source, struct media_pad *sink) { @@ -813,16 +682,6 @@ media_entity_find_link(struct media_pad *source, struct media_pad *sink) } EXPORT_SYMBOL_GPL(media_entity_find_link); -/** - * media_entity_remote_pad - Find the pad at the remote end of a link - * @pad: Pad at the local end of the link - * - * Search for a remote pad connected to the given pad by iterating over all - * links originating or terminating at that pad until an enabled link is found. - * - * Return a pointer to the pad at the remote end of the first found enabled - * link, or NULL if no enabled link has been found. - */ struct media_pad *media_entity_remote_pad(struct media_pad *pad) { struct media_link *link; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 1b954fb88def5..d073b205e6a6d 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -338,17 +338,43 @@ struct media_entity_graph { #define intf_to_devnode(intf) \ container_of(intf, struct media_intf_devnode, intf) +/** + * media_gobj_create - Initialize a graph object + * + * @mdev: Pointer to the media_device that contains the object + * @type: Type of the object + * @gobj: Pointer to the graph object + * + * This routine initializes the embedded struct media_gobj inside a + * media graph object. It is called automatically if media_*_create() + * calls are used. However, if the object (entity, link, pad, interface) + * is embedded on some other object, this function should be called before + * registering the object at the media controller. + */ void media_gobj_create(struct media_device *mdev, enum media_gobj_type type, struct media_gobj *gobj); + +/** + * media_gobj_destroy - Stop using a graph object on a media device + * + * @gobj: Pointer to the graph object + * + * This should be called by all routines like media_device_unregister() + * that remove/destroy media graph objects. + */ void media_gobj_destroy(struct media_gobj *gobj); /** * media_entity_pads_init() - Initialize the entity pads * * @entity: entity where the pads belong - * @num_pads: number of pads to be initialized - * @pads: pads array + * @num_pads: total number of sink and source pads + * @pads: Array of @num_pads pads. + * + * The pads array is managed by the entity driver and passed to + * media_entity_pads_init() where its pointer will be stored in the entity + * structure. * * If no pads are needed, drivers could either directly fill * &media_entity->@num_pads with 0 and &media_entity->@pads with NULL or call @@ -413,6 +439,20 @@ void __media_entity_remove_links(struct media_entity *entity); */ void media_entity_remove_links(struct media_entity *entity); +/** + * __media_entity_setup_link - Configure a media link without locking + * @link: The link being configured + * @flags: Link configuration flags + * + * The bulk of link setup is handled by the two entities connected through the + * link. This function notifies both entities of the link configuration change. + * + * If the link is immutable or if the current and new configuration are + * identical, return immediately. + * + * The user is expected to hold link->source->parent->mutex. If not, + * media_entity_setup_link() should be used instead. + */ int __media_entity_setup_link(struct media_link *link, u32 flags); /** @@ -450,19 +490,111 @@ int __media_entity_setup_link(struct media_link *link, u32 flags); * on media_create_intf_link(), for interface to entity links. */ int media_entity_setup_link(struct media_link *link, u32 flags); + +/** + * media_entity_find_link - Find a link between two pads + * @source: Source pad + * @sink: Sink pad + * + * Return a pointer to the link between the two entities. If no such link + * exists, return NULL. + */ struct media_link *media_entity_find_link(struct media_pad *source, struct media_pad *sink); + +/** + * media_entity_remote_pad - Find the pad at the remote end of a link + * @pad: Pad at the local end of the link + * + * Search for a remote pad connected to the given pad by iterating over all + * links originating or terminating at that pad until an enabled link is found. + * + * Return a pointer to the pad at the remote end of the first found enabled + * link, or NULL if no enabled link has been found. + */ struct media_pad *media_entity_remote_pad(struct media_pad *pad); +/** + * media_entity_get - Get a reference to the parent module + * + * @entity: The entity + * + * Get a reference to the parent media device module. + * + * The function will return immediately if @entity is NULL. + * + * Return a pointer to the entity on success or NULL on failure. + */ struct media_entity *media_entity_get(struct media_entity *entity); + +/** + * media_entity_put - Release the reference to the parent module + * + * @entity: The entity + * + * Release the reference count acquired by media_entity_get(). + * + * The function will return immediately if @entity is NULL. + */ void media_entity_put(struct media_entity *entity); +/** + * media_entity_graph_walk_start - Start walking the media graph at a given entity + * @graph: Media graph structure that will be used to walk the graph + * @entity: Starting entity + * + * This function initializes the graph traversal structure to walk the entities + * graph starting at the given entity. The traversal structure must not be + * modified by the caller during graph traversal. When done the structure can + * safely be freed. + */ void media_entity_graph_walk_start(struct media_entity_graph *graph, struct media_entity *entity); + +/** + * media_entity_graph_walk_next - Get the next entity in the graph + * @graph: Media graph structure + * + * Perform a depth-first traversal of the given media entities graph. + * + * The graph structure must have been previously initialized with a call to + * media_entity_graph_walk_start(). + * + * Return the next entity in the graph or NULL if the whole graph have been + * traversed. + */ struct media_entity * media_entity_graph_walk_next(struct media_entity_graph *graph); + +/** + * media_entity_pipeline_start - Mark a pipeline as streaming + * @entity: Starting entity + * @pipe: Media pipeline to be assigned to all entities in the pipeline. + * + * Mark all entities connected to a given entity through enabled links, either + * directly or indirectly, as streaming. The given pipeline object is assigned to + * every entity in the pipeline and stored in the media_entity pipe field. + * + * Calls to this function can be nested, in which case the same number of + * media_entity_pipeline_stop() calls will be required to stop streaming. The + * pipeline pointer must be identical for all nested calls to + * media_entity_pipeline_start(). + */ __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_pipeline *pipe); + +/** + * media_entity_pipeline_stop - Mark a pipeline as not streaming + * @entity: Starting entity + * + * Mark all entities connected to a given entity through enabled links, either + * directly or indirectly, as not streaming. The media_entity pipe field is + * reset to NULL. + * + * If multiple calls to media_entity_pipeline_start() have been made, the same + * number of calls to this function are required to mark the pipeline as not + * streaming. + */ void media_entity_pipeline_stop(struct media_entity *entity); /** -- GitLab From 829de29bfe5a0568831f1c52a760306d642d99d4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 12:23:23 -0200 Subject: [PATCH 2539/2855] [media] media: use unsigned for pad index The pad index is unsigned. Replace the occurences of it where pertinent. Suggested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/ispccdc.c | 2 +- drivers/media/platform/omap3isp/ispccp2.c | 2 +- drivers/media/platform/omap3isp/ispcsi2.c | 2 +- drivers/media/platform/omap3isp/isppreview.c | 2 +- drivers/media/platform/omap3isp/ispresizer.c | 2 +- drivers/staging/media/davinci_vpfe/dm365_ipipeif.c | 2 +- drivers/staging/media/davinci_vpfe/dm365_isif.c | 2 +- drivers/staging/media/davinci_vpfe/dm365_resizer.c | 2 +- drivers/staging/media/omap4iss/iss_csi2.c | 2 +- drivers/staging/media/omap4iss/iss_ipipeif.c | 2 +- drivers/staging/media/omap4iss/iss_resizer.c | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index dae674cd3f74e..749462c1af8e9 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -2513,7 +2513,7 @@ static int ccdc_link_setup(struct media_entity *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); struct isp_device *isp = to_isp_device(ccdc); - int index = local->index; + unsigned int index = local->index; /* FIXME: this is actually a hack! */ if (is_media_entity_v4l2_subdev(remote->entity)) diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index 0c790b25f6f9b..59686dd1bb0a2 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -956,7 +956,7 @@ static int ccp2_link_setup(struct media_entity *entity, { struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); - int index = local->index; + unsigned int index = local->index; /* FIXME: this is actually a hack! */ if (is_media_entity_v4l2_subdev(remote->entity)) diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index f50f6b305204c..886f148755b0c 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c @@ -1144,7 +1144,7 @@ static int csi2_link_setup(struct media_entity *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); struct isp_csi2_ctrl_cfg *ctrl = &csi2->ctrl; - int index = local->index; + unsigned int index = local->index; /* * The ISP core doesn't support pipelines with multiple video outputs. diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index c300cb7219e9f..e15ad4133632b 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c @@ -2144,7 +2144,7 @@ static int preview_link_setup(struct media_entity *entity, { struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct isp_prev_device *prev = v4l2_get_subdevdata(sd); - int index = local->index; + unsigned int index = local->index; /* FIXME: this is actually a hack! */ if (is_media_entity_v4l2_subdev(remote->entity)) diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c index cd0a9f6e1fedf..20b98d876d7ed 100644 --- a/drivers/media/platform/omap3isp/ispresizer.c +++ b/drivers/media/platform/omap3isp/ispresizer.c @@ -1623,7 +1623,7 @@ static int resizer_link_setup(struct media_entity *entity, { struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct isp_res_device *res = v4l2_get_subdevdata(sd); - int index = local->index; + unsigned int index = local->index; /* FIXME: this is actually a hack! */ if (is_media_entity_v4l2_subdev(remote->entity)) diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c index a54c60fce3d5b..633d6456fdce6 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c @@ -885,7 +885,7 @@ ipipeif_link_setup(struct media_entity *entity, const struct media_pad *local, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd); struct vpfe_device *vpfe = to_vpfe_device(ipipeif); - int index = local->index; + unsigned int index = local->index; /* FIXME: this is actually a hack! */ if (is_media_entity_v4l2_subdev(remote->entity)) diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c index b35667afb73f6..99057892d88d3 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_isif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c @@ -1707,7 +1707,7 @@ isif_link_setup(struct media_entity *entity, const struct media_pad *local, { struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd); - int index = local->index; + unsigned int index = local->index; /* FIXME: this is actually a hack! */ if (is_media_entity_v4l2_subdev(remote->entity)) diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index 669ae3f9791fd..a91395ce91e1d 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c @@ -1648,7 +1648,7 @@ static int resizer_link_setup(struct media_entity *entity, struct vpfe_device *vpfe_dev = to_vpfe_device(resizer); u16 ipipeif_source = vpfe_dev->vpfe_ipipeif.output; u16 ipipe_source = vpfe_dev->vpfe_ipipe.output; - int index = local->index; + unsigned int index = local->index; /* FIXME: this is actually a hack! */ if (is_media_entity_v4l2_subdev(remote->entity)) diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c index 226366a036619..f0fa037ce173f 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.c +++ b/drivers/staging/media/omap4iss/iss_csi2.c @@ -1170,7 +1170,7 @@ static int csi2_link_setup(struct media_entity *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd); struct iss_csi2_ctrl_cfg *ctrl = &csi2->ctrl; - int index = local->index; + unsigned int index = local->index; /* FIXME: this is actually a hack! */ if (is_media_entity_v4l2_subdev(remote->entity)) diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c index c2b5638a08988..88b22f7f8b133 100644 --- a/drivers/staging/media/omap4iss/iss_ipipeif.c +++ b/drivers/staging/media/omap4iss/iss_ipipeif.c @@ -662,7 +662,7 @@ static int ipipeif_link_setup(struct media_entity *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct iss_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd); struct iss_device *iss = to_iss_device(ipipeif); - int index = local->index; + unsigned int index = local->index; /* FIXME: this is actually a hack! */ if (is_media_entity_v4l2_subdev(remote->entity)) diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c index fea13ab4041f6..fe7b253bb0d32 100644 --- a/drivers/staging/media/omap4iss/iss_resizer.c +++ b/drivers/staging/media/omap4iss/iss_resizer.c @@ -716,7 +716,7 @@ static int resizer_link_setup(struct media_entity *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct iss_resizer_device *resizer = v4l2_get_subdevdata(sd); struct iss_device *iss = to_iss_device(resizer); - int index = local->index; + unsigned int index = local->index; /* FIXME: this is actually a hack! */ if (is_media_entity_v4l2_subdev(remote->entity)) -- GitLab From d1b9da2d606ecec587177c4c90f1905c57538149 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 12:41:12 -0200 Subject: [PATCH 2540/2855] [media] media-device.h: Let clearer that entity function must be initialized Improve the documentation to let it clear that the entity function must be initialized. Suggested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 4 ++++ include/uapi/linux/media.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/media/media-device.h b/include/media/media-device.h index f9907a7728d46..215a0d88241d4 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -423,6 +423,10 @@ void media_device_unregister(struct media_device *mdev); * %MEDIA_ENT_FL_DEFAULT indicates the default entity for a given type. * This can be used to report the default audio and video devices or the * default camera sensor. + * + * NOTE: Drivers should set the entity function before calling this function. + * Please notice that the values %MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN and + * %MEDIA_ENT_F_UNKNOWN should not be used by the drivers. */ int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity); diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index ff6a8010c5200..8d8e1a3e6e1af 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -92,7 +92,7 @@ struct media_device_info { * * Subdevs are initialized with MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, * in order to preserve backward compatibility. - * Drivers should change to the proper subdev type before + * Drivers must change to the proper subdev type before * registering the entity. */ -- GitLab From b3b7a9f138b7539c25e036d398616f6737b08ff7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 16:07:57 -0200 Subject: [PATCH 2541/2855] [media] media-device: Use u64 ints for pointers By using u64 integers and pointers, we can get rid of compat32 logic. So, let's do it! Suggested-by: Arnd Bergmann Suggested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 77 +++++++++++++++++++----------------- include/uapi/linux/media.h | 32 ++++++++------- 2 files changed, 58 insertions(+), 51 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index f09f3a6f9c50b..6406914a9bf59 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -240,10 +240,10 @@ static long __media_device_get_topology(struct media_device *mdev, struct media_interface *intf; struct media_pad *pad; struct media_link *link; - struct media_v2_entity uentity; - struct media_v2_interface uintf; - struct media_v2_pad upad; - struct media_v2_link ulink; + struct media_v2_entity kentity, *uentity; + struct media_v2_interface kintf, *uintf; + struct media_v2_pad kpad, *upad; + struct media_v2_link klink, *ulink; unsigned int i; int ret = 0; @@ -251,10 +251,10 @@ static long __media_device_get_topology(struct media_device *mdev, /* Get entities and number of entities */ i = 0; + uentity = media_get_uptr(topo->ptr_entities); media_device_for_each_entity(entity, mdev) { i++; - - if (ret || !topo->entities) + if (ret || !uentity) continue; if (i > topo->num_entities) { @@ -263,23 +263,24 @@ static long __media_device_get_topology(struct media_device *mdev, } /* Copy fields to userspace struct if not error */ - memset(&uentity, 0, sizeof(uentity)); - uentity.id = entity->graph_obj.id; - uentity.function = entity->function; - strncpy(uentity.name, entity->name, - sizeof(uentity.name)); + memset(&kentity, 0, sizeof(kentity)); + kentity.id = entity->graph_obj.id; + kentity.function = entity->function; + strncpy(kentity.name, entity->name, + sizeof(kentity.name)); - if (copy_to_user(&topo->entities[i - 1], &uentity, sizeof(uentity))) + if (copy_to_user(uentity, &kentity, sizeof(kentity))) ret = -EFAULT; + uentity++; } topo->num_entities = i; /* Get interfaces and number of interfaces */ i = 0; + uintf = media_get_uptr(topo->ptr_interfaces); media_device_for_each_intf(intf, mdev) { i++; - - if (ret || !topo->interfaces) + if (ret || !uintf) continue; if (i > topo->num_interfaces) { @@ -287,33 +288,34 @@ static long __media_device_get_topology(struct media_device *mdev, continue; } - memset(&uintf, 0, sizeof(uintf)); + memset(&kintf, 0, sizeof(kintf)); /* Copy intf fields to userspace struct */ - uintf.id = intf->graph_obj.id; - uintf.intf_type = intf->type; - uintf.flags = intf->flags; + kintf.id = intf->graph_obj.id; + kintf.intf_type = intf->type; + kintf.flags = intf->flags; if (media_type(&intf->graph_obj) == MEDIA_GRAPH_INTF_DEVNODE) { struct media_intf_devnode *devnode; devnode = intf_to_devnode(intf); - uintf.devnode.major = devnode->major; - uintf.devnode.minor = devnode->minor; + kintf.devnode.major = devnode->major; + kintf.devnode.minor = devnode->minor; } - if (copy_to_user(&topo->interfaces[i - 1], &uintf, sizeof(uintf))) + if (copy_to_user(uintf, &kintf, sizeof(kintf))) ret = -EFAULT; + uintf++; } topo->num_interfaces = i; /* Get pads and number of pads */ i = 0; + upad = media_get_uptr(topo->ptr_pads); media_device_for_each_pad(pad, mdev) { i++; - - if (ret || !topo->pads) + if (ret || !upad) continue; if (i > topo->num_pads) { @@ -321,27 +323,29 @@ static long __media_device_get_topology(struct media_device *mdev, continue; } - memset(&upad, 0, sizeof(upad)); + memset(&kpad, 0, sizeof(kpad)); /* Copy pad fields to userspace struct */ - upad.id = pad->graph_obj.id; - upad.entity_id = pad->entity->graph_obj.id; - upad.flags = pad->flags; + kpad.id = pad->graph_obj.id; + kpad.entity_id = pad->entity->graph_obj.id; + kpad.flags = pad->flags; - if (copy_to_user(&topo->pads[i - 1], &upad, sizeof(upad))) + if (copy_to_user(upad, &kpad, sizeof(kpad))) ret = -EFAULT; + upad++; } topo->num_pads = i; /* Get links and number of links */ i = 0; + ulink = media_get_uptr(topo->ptr_links); media_device_for_each_link(link, mdev) { if (link->is_backlink) continue; i++; - if (ret || !topo->links) + if (ret || !ulink) continue; if (i > topo->num_links) { @@ -349,19 +353,20 @@ static long __media_device_get_topology(struct media_device *mdev, continue; } - memset(&ulink, 0, sizeof(ulink)); + memset(&klink, 0, sizeof(klink)); /* Copy link fields to userspace struct */ - ulink.id = link->graph_obj.id; - ulink.source_id = link->gobj0->id; - ulink.sink_id = link->gobj1->id; - ulink.flags = link->flags; + klink.id = link->graph_obj.id; + klink.source_id = link->gobj0->id; + klink.sink_id = link->gobj1->id; + klink.flags = link->flags; if (media_type(link->gobj0) != MEDIA_GRAPH_PAD) - ulink.flags |= MEDIA_LNK_FL_INTERFACE_LINK; + klink.flags |= MEDIA_LNK_FL_INTERFACE_LINK; - if (copy_to_user(&topo->links[i - 1], &ulink, sizeof(ulink))) + if (copy_to_user(ulink, &klink, sizeof(klink))) ret = -EFAULT; + ulink++; } topo->num_links = i; diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 8d8e1a3e6e1af..86f9753e5c037 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -23,6 +23,9 @@ #ifndef __LINUX_MEDIA_H #define __LINUX_MEDIA_H +#ifndef __KERNEL__ +#include +#endif #include #include #include @@ -320,27 +323,26 @@ struct media_v2_link { }; struct media_v2_topology { - __u32 topology_version; + __u64 topology_version; - __u32 num_entities; - struct media_v2_entity *entities; + __u64 num_entities; + __u64 ptr_entities; - __u32 num_interfaces; - struct media_v2_interface *interfaces; + __u64 num_interfaces; + __u64 ptr_interfaces; - __u32 num_pads; - struct media_v2_pad *pads; + __u64 num_pads; + __u64 ptr_pads; - __u32 num_links; - struct media_v2_link *links; - - struct { - __u32 reserved_num; - void *reserved_ptr; - } reserved_types[16]; - __u32 reserved[8]; + __u64 num_links; + __u64 ptr_links; }; +static inline void __user *media_get_uptr(__u64 arg) +{ + return (void __user *)(uintptr_t)arg; +} + /* ioctls */ #define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info) -- GitLab From b5f6df0607b767fe48b179c6ccee204ee17c3373 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 11 Dec 2015 15:16:27 -0200 Subject: [PATCH 2542/2855] [media] omap3isp: remove per ISP module link creation functions The entities to video nodes links were created on separate functions for each ISP module but since the only thing that these functions do is to call media_create_pad_link(), there's no need for that indirection level and all link creation logic can be just inlined in the caller function. Also, since the only possible failure for the link creation is a memory allocation, there is no need for error messages since the core already reports a very verbose message in that case. Suggested-by: Laurent Pinchart Signed-off-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 56 ++++++++++++-------- drivers/media/platform/omap3isp/ispccdc.c | 14 ----- drivers/media/platform/omap3isp/ispccdc.h | 1 - drivers/media/platform/omap3isp/ispccp2.c | 14 ----- drivers/media/platform/omap3isp/ispccp2.h | 1 - drivers/media/platform/omap3isp/ispcsi2.c | 14 ----- drivers/media/platform/omap3isp/ispcsi2.h | 1 - drivers/media/platform/omap3isp/isppreview.c | 20 ------- drivers/media/platform/omap3isp/isppreview.h | 1 - drivers/media/platform/omap3isp/ispresizer.c | 20 ------- drivers/media/platform/omap3isp/ispresizer.h | 1 - 11 files changed, 35 insertions(+), 108 deletions(-) diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index cb8ac90086c14..40aee11805c77 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -1940,37 +1940,51 @@ static int isp_create_pads_links(struct isp_device *isp) { int ret; - ret = omap3isp_csi2_create_pads_links(isp); - if (ret < 0) { - dev_err(isp->dev, "CSI2 pads links creation failed\n"); + /* Create links between entities and video nodes. */ + ret = media_create_pad_link( + &isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE, + &isp->isp_csi2a.video_out.video.entity, 0, 0); + if (ret < 0) return ret; - } - ret = omap3isp_ccp2_create_pads_links(isp); - if (ret < 0) { - dev_err(isp->dev, "CCP2 pads links creation failed\n"); + ret = media_create_pad_link( + &isp->isp_ccp2.video_in.video.entity, 0, + &isp->isp_ccp2.subdev.entity, CCP2_PAD_SINK, 0); + if (ret < 0) return ret; - } - ret = omap3isp_ccdc_create_pads_links(isp); - if (ret < 0) { - dev_err(isp->dev, "CCDC pads links creation failed\n"); + ret = media_create_pad_link( + &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF, + &isp->isp_ccdc.video_out.video.entity, 0, 0); + if (ret < 0) return ret; - } - ret = omap3isp_preview_create_pads_links(isp); - if (ret < 0) { - dev_err(isp->dev, "Preview pads links creation failed\n"); + ret = media_create_pad_link( + &isp->isp_prev.video_in.video.entity, 0, + &isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0); + if (ret < 0) return ret; - } - ret = omap3isp_resizer_create_pads_links(isp); - if (ret < 0) { - dev_err(isp->dev, "Resizer pads links creation failed\n"); + ret = media_create_pad_link( + &isp->isp_prev.subdev.entity, PREV_PAD_SOURCE, + &isp->isp_prev.video_out.video.entity, 0, 0); + if (ret < 0) + return ret; + + ret = media_create_pad_link( + &isp->isp_res.video_in.video.entity, 0, + &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0); + if (ret < 0) + return ret; + + ret = media_create_pad_link( + &isp->isp_res.subdev.entity, RESZ_PAD_SOURCE, + &isp->isp_res.video_out.video.entity, 0, 0); + + if (ret < 0) return ret; - } - /* Connect the submodules. */ + /* Create links between entities. */ ret = media_create_pad_link( &isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE, &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0); diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 749462c1af8e9..5e16b5f594b78 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -2717,20 +2717,6 @@ int omap3isp_ccdc_init(struct isp_device *isp) return 0; } -/* - * omap3isp_ccdc_create_pads_links - CCDC pads links creation - * @isp : Pointer to ISP device - * return negative error code or zero on success - */ -int omap3isp_ccdc_create_pads_links(struct isp_device *isp) -{ - struct isp_ccdc_device *ccdc = &isp->isp_ccdc; - - /* Connect the CCDC subdev to the video node. */ - return media_create_pad_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF, - &ccdc->video_out.video.entity, 0, 0); -} - /* * omap3isp_ccdc_cleanup - CCDC module cleanup. * @isp: Device pointer specific to the OMAP3 ISP. diff --git a/drivers/media/platform/omap3isp/ispccdc.h b/drivers/media/platform/omap3isp/ispccdc.h index 2128203ef6fb3..3440a70979400 100644 --- a/drivers/media/platform/omap3isp/ispccdc.h +++ b/drivers/media/platform/omap3isp/ispccdc.h @@ -163,7 +163,6 @@ struct isp_ccdc_device { struct isp_device; int omap3isp_ccdc_init(struct isp_device *isp); -int omap3isp_ccdc_create_pads_links(struct isp_device *isp); void omap3isp_ccdc_cleanup(struct isp_device *isp); int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc, struct v4l2_device *vdev); diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index 59686dd1bb0a2..27f5fe4edefcc 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -1153,20 +1153,6 @@ int omap3isp_ccp2_init(struct isp_device *isp) return 0; } -/* - * omap3isp_ccp2_create_pads_links - CCP2 pads links creation - * @isp : Pointer to ISP device - * return negative error code or zero on success - */ -int omap3isp_ccp2_create_pads_links(struct isp_device *isp) -{ - struct isp_ccp2_device *ccp2 = &isp->isp_ccp2; - - /* Connect the video node to the ccp2 subdev. */ - return media_create_pad_link(&ccp2->video_in.video.entity, 0, - &ccp2->subdev.entity, CCP2_PAD_SINK, 0); -} - /* * omap3isp_ccp2_cleanup - CCP2 un-initialization * @isp : Pointer to ISP device diff --git a/drivers/media/platform/omap3isp/ispccp2.h b/drivers/media/platform/omap3isp/ispccp2.h index fb74bc67878b1..4662bffa79e31 100644 --- a/drivers/media/platform/omap3isp/ispccp2.h +++ b/drivers/media/platform/omap3isp/ispccp2.h @@ -79,7 +79,6 @@ struct isp_ccp2_device { /* Function declarations */ int omap3isp_ccp2_init(struct isp_device *isp); -int omap3isp_ccp2_create_pads_links(struct isp_device *isp); void omap3isp_ccp2_cleanup(struct isp_device *isp); int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2, struct v4l2_device *vdev); diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index 886f148755b0c..f75a1be29d84a 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c @@ -1310,20 +1310,6 @@ int omap3isp_csi2_init(struct isp_device *isp) return 0; } -/* - * omap3isp_csi2_create_pads_links - CSI2 pads links creation - * @isp : Pointer to ISP device - * return negative error code or zero on success - */ -int omap3isp_csi2_create_pads_links(struct isp_device *isp) -{ - struct isp_csi2_device *csi2a = &isp->isp_csi2a; - - /* Connect the CSI2 subdev to the video node. */ - return media_create_pad_link(&csi2a->subdev.entity, CSI2_PAD_SOURCE, - &csi2a->video_out.video.entity, 0, 0); -} - /* * omap3isp_csi2_cleanup - Routine for module driver cleanup */ diff --git a/drivers/media/platform/omap3isp/ispcsi2.h b/drivers/media/platform/omap3isp/ispcsi2.h index 452ee239c7d77..453ed62fe3946 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.h +++ b/drivers/media/platform/omap3isp/ispcsi2.h @@ -148,7 +148,6 @@ struct isp_csi2_device { void omap3isp_csi2_isr(struct isp_csi2_device *csi2); int omap3isp_csi2_reset(struct isp_csi2_device *csi2); int omap3isp_csi2_init(struct isp_device *isp); -int omap3isp_csi2_create_pads_links(struct isp_device *isp); void omap3isp_csi2_cleanup(struct isp_device *isp); void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2); int omap3isp_csi2_register_entities(struct isp_csi2_device *csi2, diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index e15ad4133632b..84a96670e2e71 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c @@ -2341,26 +2341,6 @@ int omap3isp_preview_init(struct isp_device *isp) return preview_init_entities(prev); } -/* - * omap3isp_preview_create_pads_links - Previewer pads links creation - * @isp : Pointer to ISP device - * return negative error code or zero on success - */ -int omap3isp_preview_create_pads_links(struct isp_device *isp) -{ - struct isp_prev_device *prev = &isp->isp_prev; - int ret; - - /* Connect the video nodes to the previewer subdev. */ - ret = media_create_pad_link(&prev->video_in.video.entity, 0, - &prev->subdev.entity, PREV_PAD_SINK, 0); - if (ret < 0) - return ret; - - return media_create_pad_link(&prev->subdev.entity, PREV_PAD_SOURCE, - &prev->video_out.video.entity, 0, 0); -} - void omap3isp_preview_cleanup(struct isp_device *isp) { struct isp_prev_device *prev = &isp->isp_prev; diff --git a/drivers/media/platform/omap3isp/isppreview.h b/drivers/media/platform/omap3isp/isppreview.h index f3593b7cecc71..16fdc03a3d43b 100644 --- a/drivers/media/platform/omap3isp/isppreview.h +++ b/drivers/media/platform/omap3isp/isppreview.h @@ -148,7 +148,6 @@ struct isp_prev_device { struct isp_device; int omap3isp_preview_init(struct isp_device *isp); -int omap3isp_preview_create_pads_links(struct isp_device *isp); void omap3isp_preview_cleanup(struct isp_device *isp); int omap3isp_preview_register_entities(struct isp_prev_device *prv, diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c index 20b98d876d7ed..0b6a87508584f 100644 --- a/drivers/media/platform/omap3isp/ispresizer.c +++ b/drivers/media/platform/omap3isp/ispresizer.c @@ -1785,26 +1785,6 @@ int omap3isp_resizer_init(struct isp_device *isp) return resizer_init_entities(res); } -/* - * omap3isp_resizer_create_pads_links - Resizer pads links creation - * @isp : Pointer to ISP device - * return negative error code or zero on success - */ -int omap3isp_resizer_create_pads_links(struct isp_device *isp) -{ - struct isp_res_device *res = &isp->isp_res; - int ret; - - /* Connect the video nodes to the resizer subdev. */ - ret = media_create_pad_link(&res->video_in.video.entity, 0, - &res->subdev.entity, RESZ_PAD_SINK, 0); - if (ret < 0) - return ret; - - return media_create_pad_link(&res->subdev.entity, RESZ_PAD_SOURCE, - &res->video_out.video.entity, 0, 0); -} - void omap3isp_resizer_cleanup(struct isp_device *isp) { struct isp_res_device *res = &isp->isp_res; diff --git a/drivers/media/platform/omap3isp/ispresizer.h b/drivers/media/platform/omap3isp/ispresizer.h index 8b9fdcdab73d8..5414542912e27 100644 --- a/drivers/media/platform/omap3isp/ispresizer.h +++ b/drivers/media/platform/omap3isp/ispresizer.h @@ -119,7 +119,6 @@ struct isp_res_device { struct isp_device; int omap3isp_resizer_init(struct isp_device *isp); -int omap3isp_resizer_create_pads_links(struct isp_device *isp); void omap3isp_resizer_cleanup(struct isp_device *isp); int omap3isp_resizer_register_entities(struct isp_res_device *res, -- GitLab From b285d5afcf80270fafc57b1a7f1ffab9e77e4686 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 11 Dec 2015 15:16:28 -0200 Subject: [PATCH 2543/2855] [media] omap3isp: remove pads prefix from isp_create_pads_links() The function that creates the links between ISP internal and external entities is called isp_create_pads_links() but the "pads" prefix is redundant since the driver doesn't handle any other kind of link so it can just be removed. While being there, fix the function's kernel-doc since is not using a proper format. Suggested-by: Laurent Pinchart Signed-off-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 40aee11805c77..fb17746e42091 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -1932,11 +1932,15 @@ done: } /* - * isp_create_pads_links - Pads links creation for the subdevices + * isp_create_links() - Create links for internal and external ISP entities * @isp : Pointer to ISP device - * return negative error code or zero on success + * + * This function creates all links between ISP internal and external entities. + * + * Return: A negative error code on failure or zero on success. Possible error + * codes are those returned by media_create_pad_link(). */ -static int isp_create_pads_links(struct isp_device *isp) +static int isp_create_links(struct isp_device *isp) { int ret; @@ -2527,7 +2531,7 @@ static int isp_probe(struct platform_device *pdev) if (ret < 0) goto error_modules; - ret = isp_create_pads_links(isp); + ret = isp_create_links(isp); if (ret < 0) goto error_register_entities; -- GitLab From a64860e56b2f97bdcd367a6e10624cd0e51b5406 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 11 Dec 2015 15:16:29 -0200 Subject: [PATCH 2544/2855] [media] omap3isp: rename single labels to just error Commit bc36b30fe06b ("[media] omap3isp: separate links creation from entities init") moved the link creation logic from the entities init functions and so removed the error_link labels from the error paths. But after that, some functions have a single error label so it makes more sense to rename the label to just "error" in thi case. Suggested-by: Laurent Pinchart Signed-off-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/ispccdc.c | 4 ++-- drivers/media/platform/omap3isp/ispccp2.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 5e16b5f594b78..4eaf926d60734 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -2669,11 +2669,11 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc) ret = omap3isp_video_init(&ccdc->video_out, "CCDC"); if (ret < 0) - goto error_video; + goto error; return 0; -error_video: +error: media_entity_cleanup(me); return ret; } diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index 27f5fe4edefcc..ca095238510d5 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -1102,11 +1102,11 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2) ret = omap3isp_video_init(&ccp2->video_in, "CCP2"); if (ret < 0) - goto error_video; + goto error; return 0; -error_video: +error: media_entity_cleanup(&ccp2->subdev.entity); return ret; } -- GitLab From 06a1368faf2184c71f086bfc13e81ea153d98798 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 11 Dec 2015 15:16:30 -0200 Subject: [PATCH 2545/2855] [media] omap3isp: consistently use v4l2_dev var in complete notifier The isp_subdev_notifier_complete() complete callback defines a struct v4l2_device *v4l2_dev to avoid needing two level of indirections to access the V4L2 subdevs but the var is not always used when possible as when calling v4l2_device_register_subdev_nodes(). So change that to consistently use the defined v4l2_dev pointer var. Suggested-by: Sakari Ailus Signed-off-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index fb17746e42091..8226eca833279 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2365,7 +2365,7 @@ static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async) } } - return v4l2_device_register_subdev_nodes(&isp->v4l2_dev); + return v4l2_device_register_subdev_nodes(v4l2_dev); } /* -- GitLab From 04e021511abc189ca43f1f11ec53121b9345c9fa Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 11 Dec 2015 15:16:31 -0200 Subject: [PATCH 2546/2855] [media] staging: omap4iss: remove pads prefix from *_create_pads_links() The functions that create ISS internal and external entities links are called *_create_pads_links() but the "pads" prefix is redundant since the driver doesn't handle any other kind of link so it can be removed. Suggested-by: Laurent Pinchart Signed-off-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/omap4iss/iss.c | 12 ++++++------ drivers/staging/media/omap4iss/iss_csi2.c | 4 ++-- drivers/staging/media/omap4iss/iss_csi2.h | 2 +- drivers/staging/media/omap4iss/iss_ipipeif.c | 4 ++-- drivers/staging/media/omap4iss/iss_ipipeif.h | 2 +- drivers/staging/media/omap4iss/iss_resizer.c | 4 ++-- drivers/staging/media/omap4iss/iss_resizer.h | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index 28e4d16544eb6..7209b92b1f865 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -1273,28 +1273,28 @@ done: } /* - * iss_create_pads_links() - Pads links creation for the subdevices + * iss_create_links() - Pads links creation for the subdevices * @iss : Pointer to ISS device * * return negative error code or zero on success */ -static int iss_create_pads_links(struct iss_device *iss) +static int iss_create_links(struct iss_device *iss) { int ret; - ret = omap4iss_csi2_create_pads_links(iss); + ret = omap4iss_csi2_create_links(iss); if (ret < 0) { dev_err(iss->dev, "CSI2 pads links creation failed\n"); return ret; } - ret = omap4iss_ipipeif_create_pads_links(iss); + ret = omap4iss_ipipeif_create_links(iss); if (ret < 0) { dev_err(iss->dev, "ISP IPIPEIF pads links creation failed\n"); return ret; } - ret = omap4iss_resizer_create_pads_links(iss); + ret = omap4iss_resizer_create_links(iss); if (ret < 0) { dev_err(iss->dev, "ISP RESIZER pads links creation failed\n"); return ret; @@ -1491,7 +1491,7 @@ static int iss_probe(struct platform_device *pdev) if (ret < 0) goto error_modules; - ret = iss_create_pads_links(iss); + ret = iss_create_links(iss); if (ret < 0) goto error_entities; diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c index f0fa037ce173f..aaca39d751a5d 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.c +++ b/drivers/staging/media/omap4iss/iss_csi2.c @@ -1339,12 +1339,12 @@ int omap4iss_csi2_init(struct iss_device *iss) } /* - * omap4iss_csi2_create_pads_links() - CSI2 pads links creation + * omap4iss_csi2_create_links() - CSI2 pads links creation * @iss: Pointer to ISS device * * return negative error code or zero on success */ -int omap4iss_csi2_create_pads_links(struct iss_device *iss) +int omap4iss_csi2_create_links(struct iss_device *iss) { struct iss_csi2_device *csi2a = &iss->csi2a; struct iss_csi2_device *csi2b = &iss->csi2b; diff --git a/drivers/staging/media/omap4iss/iss_csi2.h b/drivers/staging/media/omap4iss/iss_csi2.h index 1d5a0d8222a95..24ab378d469ff 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.h +++ b/drivers/staging/media/omap4iss/iss_csi2.h @@ -151,7 +151,7 @@ struct iss_csi2_device { void omap4iss_csi2_isr(struct iss_csi2_device *csi2); int omap4iss_csi2_reset(struct iss_csi2_device *csi2); int omap4iss_csi2_init(struct iss_device *iss); -int omap4iss_csi2_create_pads_links(struct iss_device *iss); +int omap4iss_csi2_create_links(struct iss_device *iss); void omap4iss_csi2_cleanup(struct iss_device *iss); void omap4iss_csi2_unregister_entities(struct iss_csi2_device *csi2); int omap4iss_csi2_register_entities(struct iss_csi2_device *csi2, diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c index 88b22f7f8b133..23de8330731d0 100644 --- a/drivers/staging/media/omap4iss/iss_ipipeif.c +++ b/drivers/staging/media/omap4iss/iss_ipipeif.c @@ -815,12 +815,12 @@ int omap4iss_ipipeif_init(struct iss_device *iss) } /* - * omap4iss_ipipeif_create_pads_links() - IPIPEIF pads links creation + * omap4iss_ipipeif_create_links() - IPIPEIF pads links creation * @iss: Pointer to ISS device * * return negative error code or zero on success */ -int omap4iss_ipipeif_create_pads_links(struct iss_device *iss) +int omap4iss_ipipeif_create_links(struct iss_device *iss) { struct iss_ipipeif_device *ipipeif = &iss->ipipeif; diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.h b/drivers/staging/media/omap4iss/iss_ipipeif.h index dd906b41cf9be..bad32b1d6ad89 100644 --- a/drivers/staging/media/omap4iss/iss_ipipeif.h +++ b/drivers/staging/media/omap4iss/iss_ipipeif.h @@ -78,7 +78,7 @@ struct iss_ipipeif_device { struct iss_device; int omap4iss_ipipeif_init(struct iss_device *iss); -int omap4iss_ipipeif_create_pads_links(struct iss_device *iss); +int omap4iss_ipipeif_create_links(struct iss_device *iss); void omap4iss_ipipeif_cleanup(struct iss_device *iss); int omap4iss_ipipeif_register_entities(struct iss_ipipeif_device *ipipeif, struct v4l2_device *vdev); diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c index fe7b253bb0d32..f1d352c711d57 100644 --- a/drivers/staging/media/omap4iss/iss_resizer.c +++ b/drivers/staging/media/omap4iss/iss_resizer.c @@ -857,12 +857,12 @@ int omap4iss_resizer_init(struct iss_device *iss) } /* - * omap4iss_resizer_create_pads_links() - RESIZER pads links creation + * omap4iss_resizer_create_links() - RESIZER pads links creation * @iss: Pointer to ISS device * * return negative error code or zero on success */ -int omap4iss_resizer_create_pads_links(struct iss_device *iss) +int omap4iss_resizer_create_links(struct iss_device *iss) { struct iss_resizer_device *resizer = &iss->resizer; diff --git a/drivers/staging/media/omap4iss/iss_resizer.h b/drivers/staging/media/omap4iss/iss_resizer.h index 98ab950253d0f..8b7c5fe9ffedd 100644 --- a/drivers/staging/media/omap4iss/iss_resizer.h +++ b/drivers/staging/media/omap4iss/iss_resizer.h @@ -61,7 +61,7 @@ struct iss_resizer_device { struct iss_device; int omap4iss_resizer_init(struct iss_device *iss); -int omap4iss_resizer_create_pads_links(struct iss_device *iss); +int omap4iss_resizer_create_links(struct iss_device *iss); void omap4iss_resizer_cleanup(struct iss_device *iss); int omap4iss_resizer_register_entities(struct iss_resizer_device *resizer, struct v4l2_device *vdev); -- GitLab From d8a2cf41cc1c1b4af35eaf0414f83653b7b17c8b Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 11 Dec 2015 15:16:32 -0200 Subject: [PATCH 2547/2855] [media] v4l: vsp1: remove pads prefix from *_create_pads_links() The functions that create entities links are called *_create_pads_links() but the "pads" prefix is redundant since the driver doesn't handle any other kind of link so it can be removed. Suggested-by: Laurent Pinchart Signed-off-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_drv.c | 4 ++-- drivers/media/platform/vsp1/vsp1_rpf.c | 4 ++-- drivers/media/platform/vsp1/vsp1_rwpf.h | 4 ++-- drivers/media/platform/vsp1/vsp1_wpf.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 8f995d2676467..4209d8615f722 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -261,14 +261,14 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) /* Create links. */ list_for_each_entry(entity, &vsp1->entities, list_dev) { if (entity->type == VSP1_ENTITY_LIF) { - ret = vsp1_wpf_create_pads_links(vsp1, entity); + ret = vsp1_wpf_create_links(vsp1, entity); if (ret < 0) goto done; continue; } if (entity->type == VSP1_ENTITY_RPF) { - ret = vsp1_rpf_create_pads_links(vsp1, entity); + ret = vsp1_rpf_create_links(vsp1, entity); if (ret < 0) goto done; continue; diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c index 847fb6d01a5ad..924538223d3ea 100644 --- a/drivers/media/platform/vsp1/vsp1_rpf.c +++ b/drivers/media/platform/vsp1/vsp1_rpf.c @@ -285,13 +285,13 @@ error: } /* - * vsp1_rpf_create_pads_links_create_pads_links() - RPF pads links creation + * vsp1_rpf_create_links() - RPF pads links creation * @vsp1: Pointer to VSP1 device * @entity: Pointer to VSP1 entity * * return negative error code or zero on success */ -int vsp1_rpf_create_pads_links(struct vsp1_device *vsp1, +int vsp1_rpf_create_links(struct vsp1_device *vsp1, struct vsp1_entity *entity) { struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev); diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h index 6638b35873693..731d36e5258d2 100644 --- a/drivers/media/platform/vsp1/vsp1_rwpf.h +++ b/drivers/media/platform/vsp1/vsp1_rwpf.h @@ -50,9 +50,9 @@ static inline struct vsp1_rwpf *to_rwpf(struct v4l2_subdev *subdev) struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index); struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index); -int vsp1_rpf_create_pads_links(struct vsp1_device *vsp1, +int vsp1_rpf_create_links(struct vsp1_device *vsp1, struct vsp1_entity *entity); -int vsp1_wpf_create_pads_links(struct vsp1_device *vsp1, +int vsp1_wpf_create_links(struct vsp1_device *vsp1, struct vsp1_entity *entity); int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c index 969278bc1d412..cbf514a6582dc 100644 --- a/drivers/media/platform/vsp1/vsp1_wpf.c +++ b/drivers/media/platform/vsp1/vsp1_wpf.c @@ -285,13 +285,13 @@ error: } /* - * vsp1_wpf_create_pads_links_create_pads_links() - RPF pads links creation + * vsp1_wpf_create_links() - RPF pads links creation * @vsp1: Pointer to VSP1 device * @entity: Pointer to VSP1 entity * * return negative error code or zero on success */ -int vsp1_wpf_create_pads_links(struct vsp1_device *vsp1, +int vsp1_wpf_create_links(struct vsp1_device *vsp1, struct vsp1_entity *entity) { struct vsp1_rwpf *wpf = to_rwpf(&entity->subdev); -- GitLab From 1488eee3b46736eefd9aec1e9d944f7a828773b9 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 11 Dec 2015 15:16:33 -0200 Subject: [PATCH 2548/2855] [media] v4l: vsp1: use else if instead of continue when creating links The for loop in the vsp1_create_entities() function that create the links, checks the entity type and call the proper link creation function but then it uses continue to force the next iteration of the loop to take place and skipping code in between that creates links for different entities types. It is more readable and easier to understand if the if else constructs is used instead of the continue statement. Suggested-by: Laurent Pinchart Signed-off-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_drv.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 4209d8615f722..0b251147bfff4 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -264,19 +264,15 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) ret = vsp1_wpf_create_links(vsp1, entity); if (ret < 0) goto done; - continue; - } - - if (entity->type == VSP1_ENTITY_RPF) { + } else if (entity->type == VSP1_ENTITY_RPF) { ret = vsp1_rpf_create_links(vsp1, entity); if (ret < 0) goto done; - continue; + } else { + ret = vsp1_create_links(vsp1, entity); + if (ret < 0) + goto done; } - - ret = vsp1_create_links(vsp1, entity); - if (ret < 0) - goto done; } if (vsp1->pdata.features & VSP1_HAS_LIF) { -- GitLab From 552faf4c083d8e86c6d86160ae3da0412280f690 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 11 Dec 2015 15:16:34 -0200 Subject: [PATCH 2549/2855] [media] uvcvideo: remove pads prefix from uvc_mc_create_pads_links() The function uvc_mc_create_pads_links() creates entities links but the "pads" prefix is redundant since the driver doesn't handle any other kind of link, so it can be removed. Suggested-by: Laurent Pinchart Signed-off-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_entity.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c index 38e893a1408bc..33119dcb7cecc 100644 --- a/drivers/media/usb/uvc/uvc_entity.c +++ b/drivers/media/usb/uvc/uvc_entity.c @@ -32,7 +32,7 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain, return v4l2_device_register_subdev(&chain->dev->vdev, &entity->subdev); } -static int uvc_mc_create_pads_links(struct uvc_video_chain *chain, +static int uvc_mc_create_links(struct uvc_video_chain *chain, struct uvc_entity *entity) { const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE; @@ -131,9 +131,9 @@ int uvc_mc_register_entities(struct uvc_video_chain *chain) } list_for_each_entry(entity, &chain->entities, chain) { - ret = uvc_mc_create_pads_links(chain, entity); + ret = uvc_mc_create_links(chain, entity); if (ret < 0) { - uvc_printk(KERN_INFO, "Failed to create pads links for " + uvc_printk(KERN_INFO, "Failed to create links for " "entity %u\n", entity->id); return ret; } -- GitLab From 1cb2f6f4b1652ad4e19894a4b4b82b0c2ea8a4b6 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 11 Dec 2015 15:16:35 -0200 Subject: [PATCH 2550/2855] [media] uvcvideo: register entity subdev on init The uvc_mc_register_entities() function iterated over the entities three times to initialize the entities, register the subdev for the ones whose type was UVC_TT_STREAMING and to create the entities links. But this can be simplied by merging the init and registration logic in a single loop. Suggested-by: Laurent Pinchart Signed-off-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_entity.c | 33 ++++++++---------------------- 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c index 33119dcb7cecc..ac386bb547e6e 100644 --- a/drivers/media/usb/uvc/uvc_entity.c +++ b/drivers/media/usb/uvc/uvc_entity.c @@ -19,19 +19,6 @@ #include "uvcvideo.h" -/* ------------------------------------------------------------------------ - * Video subdevices registration and unregistration - */ - -static int uvc_mc_register_entity(struct uvc_video_chain *chain, - struct uvc_entity *entity) -{ - if (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING) - return 0; - - return v4l2_device_register_subdev(&chain->dev->vdev, &entity->subdev); -} - static int uvc_mc_create_links(struct uvc_video_chain *chain, struct uvc_entity *entity) { @@ -85,7 +72,8 @@ void uvc_mc_cleanup_entity(struct uvc_entity *entity) media_entity_cleanup(&entity->vdev->entity); } -static int uvc_mc_init_entity(struct uvc_entity *entity) +static int uvc_mc_init_entity(struct uvc_video_chain *chain, + struct uvc_entity *entity) { int ret; @@ -96,6 +84,12 @@ static int uvc_mc_init_entity(struct uvc_entity *entity) ret = media_entity_pads_init(&entity->subdev.entity, entity->num_pads, entity->pads); + + if (ret < 0) + return ret; + + ret = v4l2_device_register_subdev(&chain->dev->vdev, + &entity->subdev); } else if (entity->vdev != NULL) { ret = media_entity_pads_init(&entity->vdev->entity, entity->num_pads, entity->pads); @@ -113,7 +107,7 @@ int uvc_mc_register_entities(struct uvc_video_chain *chain) int ret; list_for_each_entry(entity, &chain->entities, chain) { - ret = uvc_mc_init_entity(entity); + ret = uvc_mc_init_entity(chain, entity); if (ret < 0) { uvc_printk(KERN_INFO, "Failed to initialize entity for " "entity %u\n", entity->id); @@ -121,15 +115,6 @@ int uvc_mc_register_entities(struct uvc_video_chain *chain) } } - list_for_each_entry(entity, &chain->entities, chain) { - ret = uvc_mc_register_entity(chain, entity); - if (ret < 0) { - uvc_printk(KERN_INFO, "Failed to register entity for " - "entity %u\n", entity->id); - return ret; - } - } - list_for_each_entry(entity, &chain->entities, chain) { ret = uvc_mc_create_links(chain, entity); if (ret < 0) { -- GitLab From 313895fba2040c7f223db3d6aa6cb3b5c5022042 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 11 Dec 2015 15:16:36 -0200 Subject: [PATCH 2551/2855] [media] media-entity: remove unneded enclosing parenthesis Commit 86ee417578a2 ("[media] media: convert links from array to list") had many changes that were automated using coccinelle but the semantic patch was not smart enough to rely on operators precedence and avoid using unnecessary enclosing parenthesis. This patch removes them since are not needed. Suggested-by: Laurent Pinchart Signed-off-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index ada2b44ea4e15..181ca0de6e523 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -225,7 +225,7 @@ static void stack_push(struct media_entity_graph *graph, return; } graph->top++; - graph->stack[graph->top].link = (&entity->links)->next; + graph->stack[graph->top].link = entity->links.next; graph->stack[graph->top].entity = entity; } @@ -268,7 +268,7 @@ media_entity_graph_walk_next(struct media_entity_graph *graph) * top of the stack until no more entities on the level can be * found. */ - while (link_top(graph) != &(stack_top(graph)->links)) { + while (link_top(graph) != &stack_top(graph)->links) { struct media_entity *entity = stack_top(graph); struct media_link *link; struct media_entity *next; -- GitLab From 82ae2a50597565cbb2c758b44a3f39adb158ef0a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 18:09:13 -0200 Subject: [PATCH 2552/2855] [media] media: move MEDIA_LNK_FL_INTERFACE_LINK logic to link creation Instead of flagging an interface link as MEDIA_LNK_FL_INTERFACE_LINK only when returning to userspace, do it at link creation time. That would allow using such flag internally, and cleans up a little bit the code for G_TOPOLOGY ioctl. [mchehab@osg.samsung.com: folded with a fixup from Dan Carpenter, replacing & by &&] Suggested-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 3 --- drivers/media/media-entity.c | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 6406914a9bf59..c12481c753a01 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -361,9 +361,6 @@ static long __media_device_get_topology(struct media_device *mdev, klink.sink_id = link->gobj1->id; klink.flags = link->flags; - if (media_type(link->gobj0) != MEDIA_GRAPH_PAD) - klink.flags |= MEDIA_LNK_FL_INTERFACE_LINK; - if (copy_to_user(ulink, &klink, sizeof(klink))) ret = -EFAULT; ulink++; diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 181ca0de6e523..6926e0685d0aa 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -526,7 +526,7 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, link->source = &source->pads[source_pad]; link->sink = &sink->pads[sink_pad]; - link->flags = flags; + link->flags = flags & ~MEDIA_LNK_FL_INTERFACE_LINK; /* Initialize graph object embedded at the new link */ media_gobj_create(source->graph_obj.mdev, MEDIA_GRAPH_LINK, @@ -756,7 +756,7 @@ struct media_link *media_create_intf_link(struct media_entity *entity, link->intf = intf; link->entity = entity; - link->flags = flags; + link->flags = flags | MEDIA_LNK_FL_INTERFACE_LINK; /* Initialize graph object embedded at the new link */ media_gobj_create(intf->graph_obj.mdev, MEDIA_GRAPH_LINK, -- GitLab From b3109d662d744c065f2a1da5e9b8d08f2189c2ac Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 18:26:53 -0200 Subject: [PATCH 2553/2855] [media] media.h: let be clear that tuners need to use connectors The V4L2 core won't be adding connectors to the tuners and other entities that need them. Let it be clear. Suggested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 86f9753e5c037..cacfceb0d81d8 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -74,10 +74,11 @@ struct media_device_info { /* * Connectors */ +/* It is a responsibility of the entity drivers to add connectors and links */ #define MEDIA_ENT_F_CONN_RF (MEDIA_ENT_F_BASE + 21) #define MEDIA_ENT_F_CONN_SVIDEO (MEDIA_ENT_F_BASE + 22) #define MEDIA_ENT_F_CONN_COMPOSITE (MEDIA_ENT_F_BASE + 23) - /* For internal test signal generators and other debug connectors */ +/* For internal test signal generators and other debug connectors */ #define MEDIA_ENT_F_CONN_TEST (MEDIA_ENT_F_BASE + 24) /* @@ -105,6 +106,10 @@ struct media_device_info { #define MEDIA_ENT_F_FLASH (MEDIA_ENT_F_OLD_SUBDEV_BASE + 2) #define MEDIA_ENT_F_LENS (MEDIA_ENT_F_OLD_SUBDEV_BASE + 3) #define MEDIA_ENT_F_ATV_DECODER (MEDIA_ENT_F_OLD_SUBDEV_BASE + 4) +/* + * It is a responsibility of the entity drivers to add connectors and links + * for the tuner entities. + */ #define MEDIA_ENT_F_TUNER (MEDIA_ENT_F_OLD_SUBDEV_BASE + 5) #define MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN MEDIA_ENT_F_OLD_SUBDEV_BASE -- GitLab From fdc40b5e95ac6480f6160081774aa2ec24784ccb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 12 Dec 2015 08:25:44 -0200 Subject: [PATCH 2554/2855] [media] dvbdev: Document the new MC-related fields The Media Controller next gen patchset added several new fields to be used with it. Document them. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index de85ba0f570a8..abee18a402e1e 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h @@ -120,6 +120,11 @@ struct dvb_adapter { * @entity: pointer to struct media_entity associated with the device node * @pads: pointer to struct media_pad associated with @entity; * @priv: private data + * @intf_devnode: Pointer to media_intf_devnode. Used by the dvbdev core to + * store the MC device node interface + * @tsout_num_entities: Number of Transport Stream output entities + * @tsout_entity: array with MC entities associated to each TS output node + * @tsout_pads: array with the source pads for each @tsout_entity * * This structure is used by the DVB core (frontend, CA, net, demux) in * order to create the device nodes. Usually, driver should not initialize @@ -188,8 +193,11 @@ int dvb_unregister_adapter(struct dvb_adapter *adap); * stored * @template: Template used to create &pdvbdev; * @priv: private data - * @type: type of the device: DVB_DEVICE_SEC, DVB_DEVICE_FRONTEND, - * DVB_DEVICE_DEMUX, DVB_DEVICE_DVR, DVB_DEVICE_CA, DVB_DEVICE_NET + * @type: type of the device: %DVB_DEVICE_SEC, %DVB_DEVICE_FRONTEND, + * %DVB_DEVICE_DEMUX, %DVB_DEVICE_DVR, %DVB_DEVICE_CA, + * %DVB_DEVICE_NET + * @demux_sink_pads: Number of demux outputs, to be used to create the TS + * outputs via the Media Controller. */ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, -- GitLab From b7870d692d7b0718f7153aed9e7a32f0119b525d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 12 Dec 2015 08:59:14 -0200 Subject: [PATCH 2555/2855] [media] DocBook: MC: add the concept of interfaces The Media Controller next generation patches added a new graph element type: interfaces. It also allows links between interfaces and entities. Update the docbook to reflect that. Signed-off-by: Mauro Carvalho Chehab --- .../DocBook/media/v4l/media-controller.xml | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/Documentation/DocBook/media/v4l/media-controller.xml b/Documentation/DocBook/media/v4l/media-controller.xml index 873ac3a621f01..def4a27aadef4 100644 --- a/Documentation/DocBook/media/v4l/media-controller.xml +++ b/Documentation/DocBook/media/v4l/media-controller.xml @@ -58,20 +58,32 @@ Media device model Discovering a device internal topology, and configuring it at runtime, is one of the goals of the media controller API. To achieve this, hardware - devices are modelled as an oriented graph of building blocks called entities - connected through pads. - An entity is a basic media hardware or software building block. It can - correspond to a large variety of logical blocks such as physical hardware - devices (CMOS sensor for instance), logical hardware devices (a building - block in a System-on-Chip image processing pipeline), DMA channels or - physical connectors. - A pad is a connection endpoint through which an entity can interact - with other entities. Data (not restricted to video) produced by an entity - flows from the entity's output to one or more entity inputs. Pads should not - be confused with physical pins at chip boundaries. - A link is a point-to-point oriented connection between two pads, - either on the same entity or on different entities. Data flows from a source - pad to a sink pad. + devices and Linux Kernel interfaces are modelled as graph objects on + an oriented graph. The object types that constitute the graph are: + + An entity + is a basic media hardware or software building block. It can correspond to + a large variety of logical blocks such as physical hardware devices + (CMOS sensor for instance), logical hardware devices (a building block in + a System-on-Chip image processing pipeline), DMA channels or physical + connectors. + An interface + is a graph representation of a Linux Kernel userspace API interface, + like a device node or a sysfs file that controls one or more entities + in the graph. + A pad + is a data connection endpoint through which an entity can interact with + other entities. Data (not restricted to video) produced by an entity + flows from the entity's output to one or more entity inputs. Pads should + not be confused with physical pins at chip boundaries. + A data link + is a point-to-point oriented connection between two pads, either on the + same entity or on different entities. Data flows from a source pad to a + sink pad. + An interface link + is a point-to-point bidirectional control connection between a Linux + Kernel interface and an entity.m + -- GitLab From 5fec921f49891e1343d60df3f6f40ceb52acdd42 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 12 Dec 2015 09:56:07 -0200 Subject: [PATCH 2556/2855] [media] DocBook: move data types to a separate section As MEDIA_IOC_G_TOPOLOGY shares the data types already declared for entities, pads and links, we should move those to a separate part of the document, and use cross-references where needed. So, move the following tables to a separate section at the DocBook: media-entity-type media-entity-flag media-pad-flag media-link-flag Signed-off-by: Mauro Carvalho Chehab --- .../DocBook/media/v4l/media-controller.xml | 3 + .../media/v4l/media-ioc-enum-entities.xml | 104 ----------- .../media/v4l/media-ioc-enum-links.xml | 56 ------ .../DocBook/media/v4l/media-types.xml | 166 ++++++++++++++++++ 4 files changed, 169 insertions(+), 160 deletions(-) create mode 100644 Documentation/DocBook/media/v4l/media-types.xml diff --git a/Documentation/DocBook/media/v4l/media-controller.xml b/Documentation/DocBook/media/v4l/media-controller.xml index def4a27aadef4..63d48decaa6f1 100644 --- a/Documentation/DocBook/media/v4l/media-controller.xml +++ b/Documentation/DocBook/media/v4l/media-controller.xml @@ -85,6 +85,9 @@ Kernel interface and an entity.m + + + &sub-media-types; diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml index 9f7614a012342..0c4f96bfc2def 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml @@ -162,110 +162,6 @@
- - - Media entity types - - - - - - MEDIA_ENT_F_UNKNOWN and MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN - Unknown entity. That generally indicates that - a driver didn't initialize properly the entity, with is a Kernel bug - - - MEDIA_ENT_F_IO_V4L - Data streaming input and/or output entity. - - - MEDIA_ENT_F_IO_VBI - V4L VBI streaming input or output entity - - - MEDIA_ENT_F_IO_SWRADIO - V4L Software Digital Radio (SDR) streaming input or output entity - - - MEDIA_ENT_F_IO_DTV - DVB Digital TV streaming input or output entity - - - MEDIA_ENT_F_DTV_DEMOD - Digital TV demodulator entity. - - - MEDIA_ENT_F_MPEG_TS_DEMUX - MPEG Transport stream demux entity. Could be implemented on hardware or in Kernelspace by the Linux DVB subsystem. - - - MEDIA_ENT_F_DTV_CA - Digital TV Conditional Access module (CAM) entity - - - MEDIA_ENT_F_DTV_NET_DECAP - Digital TV network ULE/MLE desencapsulation entity. Could be implemented on hardware or in Kernelspace - - - MEDIA_ENT_F_CONN_RF - Connector for a Radio Frequency (RF) signal. - - - MEDIA_ENT_F_CONN_SVIDEO - Connector for a S-Video signal. - - - MEDIA_ENT_F_CONN_COMPOSITE - Connector for a RGB composite signal. - - - MEDIA_ENT_F_CONN_TEST - Connector for a test generator. - - - MEDIA_ENT_F_CAM_SENSOR - Camera video sensor entity. - - - MEDIA_ENT_F_FLASH - Flash controller entity. - - - MEDIA_ENT_F_LENS - Lens controller entity. - - - MEDIA_ENT_F_ATV_DECODER - Analog video decoder, the basic function of the video decoder - is to accept analogue video from a wide variety of sources such as - broadcast, DVD players, cameras and video cassette recorders, in - either NTSC, PAL, SECAM or HD format, separating the stream - into its component parts, luminance and chrominance, and output - it in some digital video standard, with appropriate timing - signals. - - - MEDIA_ENT_F_TUNER - Digital TV, analog TV, radio and/or software radio tuner. - - - -
- - - Media entity flags - - - - - - MEDIA_ENT_FL_DEFAULT - Default entity for its type. Used to discover the default - audio, VBI and video devices, the default camera sensor, ... - - - -
diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-links.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-links.xml index 74fb394ec6676..2bbeea9f3e18c 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-enum-links.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-links.xml @@ -118,35 +118,6 @@ - - Media pad flags - - - - - - MEDIA_PAD_FL_SINK - Input pad, relative to the entity. Input pads sink data and - are targets of links. - - - MEDIA_PAD_FL_SOURCE - Output pad, relative to the entity. Output pads source data - and are origins of links. - - - MEDIA_PAD_FL_MUST_CONNECT - If this flag is set and the pad is linked to any other - pad, then at least one of those links must be enabled for the - entity to be able to stream. There could be temporary reasons - (e.g. device configuration dependent) for the pad to need - enabled links even when this flag isn't set; the absence of the - flag doesn't imply there is none. - - - -
- struct <structname>media_link_desc</structname> @@ -171,33 +142,6 @@ - - Media link flags - - - - - - MEDIA_LNK_FL_ENABLED - The link is enabled and can be used to transfer media data. - When two or more links target a sink pad, only one of them can be - enabled at a time. - - - MEDIA_LNK_FL_IMMUTABLE - The link enabled state can't be modified at runtime. An - immutable link is always enabled. - - - MEDIA_LNK_FL_DYNAMIC - The link enabled state can be modified during streaming. This - flag is set by drivers and is read-only for applications. - - - - - One and only one of MEDIA_PAD_FL_SINK and - MEDIA_PAD_FL_SOURCE must be set for every pad.
diff --git a/Documentation/DocBook/media/v4l/media-types.xml b/Documentation/DocBook/media/v4l/media-types.xml new file mode 100644 index 0000000000000..0c5c9c034586d --- /dev/null +++ b/Documentation/DocBook/media/v4l/media-types.xml @@ -0,0 +1,166 @@ +
+Types and flags used to represent the media graph elements + + + Media entity types + + + + + + MEDIA_ENT_F_UNKNOWN and MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN + Unknown entity. That generally indicates that + a driver didn't initialize properly the entity, with is a Kernel bug + + + MEDIA_ENT_F_IO_V4L + Data streaming input and/or output entity. + + + MEDIA_ENT_F_IO_VBI + V4L VBI streaming input or output entity + + + MEDIA_ENT_F_IO_SWRADIO + V4L Software Digital Radio (SDR) streaming input or output entity + + + MEDIA_ENT_F_IO_DTV + DVB Digital TV streaming input or output entity + + + MEDIA_ENT_F_DTV_DEMOD + Digital TV demodulator entity. + + + MEDIA_ENT_F_MPEG_TS_DEMUX + MPEG Transport stream demux entity. Could be implemented on hardware or in Kernelspace by the Linux DVB subsystem. + + + MEDIA_ENT_F_DTV_CA + Digital TV Conditional Access module (CAM) entity + + + MEDIA_ENT_F_DTV_NET_DECAP + Digital TV network ULE/MLE desencapsulation entity. Could be implemented on hardware or in Kernelspace + + + MEDIA_ENT_F_CONN_RF + Connector for a Radio Frequency (RF) signal. + + + MEDIA_ENT_F_CONN_SVIDEO + Connector for a S-Video signal. + + + MEDIA_ENT_F_CONN_COMPOSITE + Connector for a RGB composite signal. + + + MEDIA_ENT_F_CONN_TEST + Connector for a test generator. + + + MEDIA_ENT_F_CAM_SENSOR + Camera video sensor entity. + + + MEDIA_ENT_F_FLASH + Flash controller entity. + + + MEDIA_ENT_F_LENS + Lens controller entity. + + + MEDIA_ENT_F_ATV_DECODER + Analog video decoder, the basic function of the video decoder + is to accept analogue video from a wide variety of sources such as + broadcast, DVD players, cameras and video cassette recorders, in + either NTSC, PAL, SECAM or HD format, separating the stream + into its component parts, luminance and chrominance, and output + it in some digital video standard, with appropriate timing + signals. + + + MEDIA_ENT_F_TUNER + Digital TV, analog TV, radio and/or software radio tuner. + + + +
+ + + Media entity flags + + + + + + MEDIA_ENT_FL_DEFAULT + Default entity for its type. Used to discover the default + audio, VBI and video devices, the default camera sensor, ... + + + +
+ + + Media pad flags + + + + + + MEDIA_PAD_FL_SINK + Input pad, relative to the entity. Input pads sink data and + are targets of links. + + + MEDIA_PAD_FL_SOURCE + Output pad, relative to the entity. Output pads source data + and are origins of links. + + + MEDIA_PAD_FL_MUST_CONNECT + If this flag is set and the pad is linked to any other + pad, then at least one of those links must be enabled for the + entity to be able to stream. There could be temporary reasons + (e.g. device configuration dependent) for the pad to need + enabled links even when this flag isn't set; the absence of the + flag doesn't imply there is none. + + + +
+ + One and only one of MEDIA_PAD_FL_SINK and + MEDIA_PAD_FL_SOURCE must be set for every pad. + + + Media link flags + + + + + + MEDIA_LNK_FL_ENABLED + The link is enabled and can be used to transfer media data. + When two or more links target a sink pad, only one of them can be + enabled at a time. + + + MEDIA_LNK_FL_IMMUTABLE + The link enabled state can't be modified at runtime. An + immutable link is always enabled. + + + MEDIA_LNK_FL_DYNAMIC + The link enabled state can be modified during streaming. This + flag is set by drivers and is read-only for applications. + + + + + +
-- GitLab From eb7d970aa0ab9964fe3200df4daf76c37d35f076 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 12 Dec 2015 10:29:30 -0200 Subject: [PATCH 2557/2855] [media] Docbook: media-types.xml: update the existing tables There were some changes on the media types that were not reflected on the types tables. Update them to reflect the upstream changes. Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/media-types.xml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Documentation/DocBook/media/v4l/media-types.xml b/Documentation/DocBook/media/v4l/media-types.xml index 0c5c9c034586d..4a6038301e06e 100644 --- a/Documentation/DocBook/media/v4l/media-types.xml +++ b/Documentation/DocBook/media/v4l/media-types.xml @@ -33,7 +33,7 @@ Digital TV demodulator entity.
- MEDIA_ENT_F_MPEG_TS_DEMUX + MEDIA_ENT_F_TS_DEMUX MPEG Transport stream demux entity. Could be implemented on hardware or in Kernelspace by the Linux DVB subsystem. @@ -101,6 +101,10 @@ Default entity for its type. Used to discover the default audio, VBI and video devices, the default camera sensor, ... + + MEDIA_ENT_FL_CONNECTOR + The entity represents a data conector + @@ -159,6 +163,15 @@ The link enabled state can be modified during streaming. This flag is set by drivers and is read-only for applications. + + MEDIA_LNK_FL_LINK_TYPE + This is a bitmask that defines the type of the link. + Currently, two types of links are supported: + MEDIA_LNK_FL_DATA_LINK + if the link is between two pads + MEDIA_LNK_FL_INTERFACE_LINK + if the link is between an interface and an entity + -- GitLab From dc7339bf119111d5c08156980ea742fc4120ce19 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 12 Dec 2015 10:54:45 -0200 Subject: [PATCH 2558/2855] [media] DocBook: add a table for Media Controller interfaces Document the media controller interfaces at the media uAPI docbook. Signed-off-by: Mauro Carvalho Chehab --- .../DocBook/media/v4l/media-types.xml | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/Documentation/DocBook/media/v4l/media-types.xml b/Documentation/DocBook/media/v4l/media-types.xml index 4a6038301e06e..1af3842509105 100644 --- a/Documentation/DocBook/media/v4l/media-types.xml +++ b/Documentation/DocBook/media/v4l/media-types.xml @@ -109,6 +109,67 @@ + + Media interface types + + + + + + + MEDIA_INTF_T_DVB_FE + Device node interface for the Digital TV frontend + typically, /dev/dvb/adapter?/frontend? + + + MEDIA_INTF_T_DVB_DEMUX + Device node interface for the Digital TV demux + typically, /dev/dvb/adapter?/demux? + + + MEDIA_INTF_T_DVB_DVR + Device node interface for the Digital TV DVR + typically, /dev/dvb/adapter?/dvr? + + + MEDIA_INTF_T_DVB_CA + Device node interface for the Digital TV Conditional Access + typically, /dev/dvb/adapter?/ca? + + + MEDIA_INTF_T_DVB_FE + Device node interface for the Digital TV network control + typically, /dev/dvb/adapter?/net? + + + MEDIA_INTF_T_V4L_VIDEO + Device node interface for video (V4L) + typically, /dev/video? + + + MEDIA_INTF_T_V4L_VBI + Device node interface for VBI (V4L) + typically, /dev/vbi? + + + MEDIA_INTF_T_V4L_RADIO + Device node interface for radio (V4L) + typically, /dev/vbi? + + + MEDIA_INTF_T_V4L_SUBDEV + Device node interface for a V4L subdevice + typically, /dev/v4l-subdev? + + + MEDIA_INTF_T_V4L_SWRADIO + Device node interface for Software Defined Radio (V4L) + typically, /dev/swradio? + + + +
+ Media pad flags -- GitLab From 677cb4bfc23e7fd8f49d2d10af64f171942fab84 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 12 Dec 2015 10:56:13 -0200 Subject: [PATCH 2559/2855] [media] DocBook: Document MEDIA_IOC_G_TOPOLOGY Add description for this new media controller ioctl. Signed-off-by: Mauro Carvalho Chehab --- .../DocBook/media/v4l/media-controller.xml | 1 + .../media/v4l/media-ioc-g-topology.xml | 391 ++++++++++++++++++ 2 files changed, 392 insertions(+) create mode 100644 Documentation/DocBook/media/v4l/media-ioc-g-topology.xml diff --git a/Documentation/DocBook/media/v4l/media-controller.xml b/Documentation/DocBook/media/v4l/media-controller.xml index 63d48decaa6f1..5f2fc07a93d72 100644 --- a/Documentation/DocBook/media/v4l/media-controller.xml +++ b/Documentation/DocBook/media/v4l/media-controller.xml @@ -98,6 +98,7 @@ &sub-media-func-ioctl; &sub-media-ioc-device-info; + &sub-media-ioc-g-topology; &sub-media-ioc-enum-entities; &sub-media-ioc-enum-links; &sub-media-ioc-setup-link; diff --git a/Documentation/DocBook/media/v4l/media-ioc-g-topology.xml b/Documentation/DocBook/media/v4l/media-ioc-g-topology.xml new file mode 100644 index 0000000000000..e0d49fa329f09 --- /dev/null +++ b/Documentation/DocBook/media/v4l/media-ioc-g-topology.xml @@ -0,0 +1,391 @@ + + + ioctl MEDIA_IOC_G_TOPOLOGY + &manvol; + + + + MEDIA_IOC_G_TOPOLOGY + Enumerate the graph topology and graph element properties + + + + + + int ioctl + int fd + int request + struct media_v2_topology *argp + + + + + + Arguments + + + + fd + + File descriptor returned by + open(). + + + + request + + MEDIA_IOC_G_TOPOLOGY + + + + argp + + + + + + + + + Description + The typical usage of this ioctl is to call it twice. + On the first call, the structure defined at &media-v2-topology; should + be zeroed. At return, if no errors happen, this ioctl will return the + topology_version and the total number of entities, + interfaces, pads and links. + Before the second call, the userspace should allocate arrays to + store the graph elements that are desired, putting the pointers to them + at the ptr_entities, ptr_interfaces, ptr_links and/or ptr_pads, keeping + the other values untouched. + If the topology_version remains the same, the + ioctl should fill the desired arrays with the media graph elements. + +
+ struct <structname>media_v2_topology</structname> + + + + + + + + + __u64 + topology_version + + + Version of the media graph topology. When the graph is + created, this field starts with zero. Every time a graph + element is added or removed, this field is + incremented. + + + __u64 + num_entities + + + Number of entities in the graph + + + __u64 + ptr_entities + + + A pointer to a memory area where the entities array + will be stored, converted to a 64-bits integer. + It can be zero. if zero, the ioctl won't store the + entities. It will just update + num_entities + + + __u64 + num_interfaces + + + Number of interfaces in the graph + + + __u64 + ptr_interfaces + + + A pointer to a memory area where the interfaces array + will be stored, converted to a 64-bits integer. + It can be zero. if zero, the ioctl won't store the + interfaces. It will just update + num_interfaces + + + __u64 + num_pads + + + Total number of pads in the graph + + + __u64 + ptr_pads + + + A pointer to a memory area where the pads array + will be stored, converted to a 64-bits integer. + It can be zero. if zero, the ioctl won't store the + pads. It will just update + num_pads + + + __u64 + num_links + + + Total number of data and interface links in the graph + + + __u64 + ptr_links + + + A pointer to a memory area where the links array + will be stored, converted to a 64-bits integer. + It can be zero. if zero, the ioctl won't store the + links. It will just update + num_links + + + +
+ + + struct <structname>media_v2_entity</structname> + + + + + + + + + __u32 + id + + + Unique ID for the entity. + + + char + name[64] + + + Entity name as an UTF-8 NULL-terminated string. + + + __u32 + function + + + Entity main function, see for details. + + + __u32 + reserved[12] + Reserved for future extensions. Drivers and applications must + set this array to zero. + + + +
+ + + struct <structname>media_v2_interface</structname> + + + + + + + + + __u32 + id + + + Unique ID for the interface. + + + __u32 + intf_type + + + Interface type, see for details. + + + __u32 + flags + + + Interface flags. Currently unused. + + + __u32 + reserved[9] + + + Reserved for future extensions. Drivers and applications must + set this array to zero. + + + struct media_v2_intf_devnode + devnode + + + Used only for device node interfaces. See for details.. + + + +
+ + + struct <structname>media_v2_interface</structname> + + + + + + + + + __u32 + major + + + Device node major number. + + + __u32 + minor + + + Device node minor number. + + + +
+ + + struct <structname>media_v2_pad</structname> + + + + + + + + + __u32 + id + + + Unique ID for the pad. + + + __u32 + entity_id + + + Unique ID for the entity where this pad belongs. + + + __u32 + flags + + + Pad flags, see for more details. + + + __u32 + reserved[9] + + + Reserved for future extensions. Drivers and applications must + set this array to zero. + + + +
+ + + struct <structname>media_v2_pad</structname> + + + + + + + + + __u32 + id + + + Unique ID for the pad. + + + __u32 + source_id + + + + On pad to pad links: unique ID for the source pad. + On interface to entity links: unique ID for the interface. + + + + __u32 + sink_id + + + + On pad to pad links: unique ID for the sink pad. + On interface to entity links: unique ID for the entity. + + + + __u32 + flags + + + Link flags, see for more details. + + + __u32 + reserved[5] + + + Reserved for future extensions. Drivers and applications must + set this array to zero. + + + + + + + + + &return-value; + + + + ENOSPC + + This is returned when either one or more of the num_entities, + num_interfaces, num_links or num_pads are non-zero and are smaller + than the actual number of elements inside the graph. This may happen + if the topology_version changed when compared + to the last time this ioctl was called. Userspace should usually + free the area for the pointers, zero the struct elements and call + this ioctl again. + + + + + -- GitLab From 8aaf62b5b9bef73978973e4b825c7818528d3ca2 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Sun, 29 Nov 2015 17:20:02 -0200 Subject: [PATCH 2560/2855] [media] media: Enforce single entity->pipe in a pipeline If a different entity->pipe in a pipeline was encountered, a warning was issued but the execution continued as if nothing had happened. Return an error instead right there. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 6926e0685d0aa..4822763dcefac 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -323,7 +323,12 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, DECLARE_BITMAP(has_no_links, MEDIA_ENTITY_MAX_PADS); entity->stream_count++; - WARN_ON(entity->pipe && entity->pipe != pipe); + + if (WARN_ON(entity->pipe && entity->pipe != pipe)) { + ret = -EBUSY; + goto error; + } + entity->pipe = pipe; /* Already streaming --- no need to check. */ -- GitLab From 60266185d7f3eeae5714090e1e10840b96df91d2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 13 Dec 2015 08:20:46 -0200 Subject: [PATCH 2561/2855] [media] media-entity.h: Document some ancillary functions Add a basic documentation for most ancillary functions. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 58 +++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index d073b205e6a6d..81aca1f5a09af 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -238,11 +238,21 @@ struct media_intf_devnode { u32 minor; }; +/** + * media_entity_id() - return the media entity graph object id + * + * @entity: pointer to entity + */ static inline u32 media_entity_id(struct media_entity *entity) { return entity->graph_obj.id; } +/** + * media_type() - return the media object type + * + * @gobj: pointer to the media graph object + */ static inline enum media_gobj_type media_type(struct media_gobj *gobj) { return gobj->id >> MEDIA_BITS_PER_LOCAL_ID; @@ -263,6 +273,15 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id) return id; } +/** + * is_media_entity_v4l2_io() - identify if the entity main function + * is a V4L2 I/O + * + * @entity: pointer to entity + * + * Return: true if the entity main function is one of the V4L2 I/O types + * (video, VBI or SDR radio); false otherwise. + */ static inline bool is_media_entity_v4l2_io(struct media_entity *entity) { if (!entity) @@ -278,6 +297,16 @@ static inline bool is_media_entity_v4l2_io(struct media_entity *entity) } } +/** + * is_media_entity_v4l2_subdev - return true if the entity main function is + * associated with the V4L2 API subdev usage + * + * @entity: pointer to entity + * + * This is an ancillary function used by subdev-based V4L2 drivers. + * It checks if the entity function is one of functions used by a V4L2 subdev, + * e. g. camera-relatef functions, analog TV decoder, TV tuner, V4L2 DSPs. + */ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) { if (!entity) @@ -652,16 +681,43 @@ struct media_link * __must_check media_create_intf_link(struct media_entity *entity, struct media_interface *intf, u32 flags); +/** + * __media_remove_intf_link() - remove a single interface link + * + * @link: pointer to &media_link. + * + * Note: this is an unlocked version of media_remove_intf_link() + */ void __media_remove_intf_link(struct media_link *link); + +/** + * media_remove_intf_link() - remove a single interface link + * + * @link: pointer to &media_link. + * + * Note: prefer to use this one, instead of __media_remove_intf_link() + */ void media_remove_intf_link(struct media_link *link); + +/** + * __media_remove_intf_links() - remove all links associated with an interface + * + * @intf: pointer to &media_interface + * + * Note: this is an unlocked version of media_remove_intf_links(). + */ void __media_remove_intf_links(struct media_interface *intf); /** * media_remove_intf_links() - remove all links associated with an interface * * @intf: pointer to &media_interface * - * Note: this is called automatically when an entity is unregistered via + * Notes: + * + * this is called automatically when an entity is unregistered via * media_device_register_entity() and by media_devnode_remove(). + * + * Prefer to use this one, instead of __media_remove_intf_links(). */ void media_remove_intf_links(struct media_interface *intf); -- GitLab From b6e4ca8129ad65a0b1552586c1d42d2fd219661e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 13 Dec 2015 08:36:58 -0200 Subject: [PATCH 2562/2855] [media] media-device.h: document the last functions Add kernel-doc documentation for media_device_get_devres and media_device_find_devres. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 7 ------- include/media/media-device.h | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index c12481c753a01..ca16bd3091bd6 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -689,10 +689,6 @@ static void media_device_release_devres(struct device *dev, void *res) { } -/* - * media_device_get_devres() - get media device as device resource - * creates if one doesn't exist -*/ struct media_device *media_device_get_devres(struct device *dev) { struct media_device *mdev; @@ -709,9 +705,6 @@ struct media_device *media_device_get_devres(struct device *dev) } EXPORT_SYMBOL_GPL(media_device_get_devres); -/* - * media_device_find_devres() - find media device as device resource -*/ struct media_device *media_device_find_devres(struct device *dev) { return devres_find(dev, media_device_release_devres, NULL, NULL); diff --git a/include/media/media-device.h b/include/media/media-device.h index 215a0d88241d4..ebc2f3a239eb0 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -449,7 +449,29 @@ int __must_check media_device_register_entity(struct media_device *mdev, * the driver if required. */ void media_device_unregister_entity(struct media_entity *entity); + +/** + * media_device_get_devres() - get media device as device resource + * creates if one doesn't exist + * + * @dev: pointer to struct &device. + * + * Sometimes, the media controller &media_device needs to be shared by more + * than one driver. This function adds support for that, by dynamically + * allocating the &media_device and allowing it to be obtained from the + * struct &device associated with the common device where all sub-device + * components belong. So, for example, on an USB device with multiple + * interfaces, each interface may be handled by a separate per-interface + * drivers. While each interface have its own &device, they all share a + * common &device associated with the hole USB device. + */ struct media_device *media_device_get_devres(struct device *dev); + +/** + * media_device_find_devres() - find media device as device resource + * + * @dev: pointer to struct &device. + */ struct media_device *media_device_find_devres(struct device *dev); /* Iterate over all entities. */ -- GitLab From fe3c565e4cbcb2adeef063accc7852de739aaa36 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 13 Dec 2015 08:40:45 -0200 Subject: [PATCH 2563/2855] [media] media-devnode: move kernel-doc documentation to the header As we're using the headers file only for documentation, move the two kernel-doc macros to the header, and fix it to avoid warnings. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-devnode.c | 24 ------------------------ include/media/media-devnode.h | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/drivers/media/media-devnode.c b/drivers/media/media-devnode.c index ebf9626e5ae5a..cea35bf200117 100644 --- a/drivers/media/media-devnode.c +++ b/drivers/media/media-devnode.c @@ -217,20 +217,6 @@ static const struct file_operations media_devnode_fops = { .llseek = no_llseek, }; -/** - * media_devnode_register - register a media device node - * @mdev: media device node structure we want to register - * - * The registration code assigns minor numbers and registers the new device node - * with the kernel. An error is returned if no free minor number can be found, - * or if the registration of the device node fails. - * - * Zero is returned on success. - * - * Note that if the media_devnode_register call fails, the release() callback of - * the media_devnode structure is *not* called, so the caller is responsible for - * freeing any data. - */ int __must_check media_devnode_register(struct media_devnode *mdev, struct module *owner) { @@ -285,16 +271,6 @@ error: return ret; } -/** - * media_devnode_unregister - unregister a media device node - * @mdev: the device node to unregister - * - * This unregisters the passed device. Future open calls will be met with - * errors. - * - * This function can safely be called if the device node has never been - * registered or has already been unregistered. - */ void media_devnode_unregister(struct media_devnode *mdev) { /* Check if mdev was ever registered at all */ diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index 17ddae32060d2..77e9d3159be89 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -86,8 +86,35 @@ struct media_devnode { /* dev to media_devnode */ #define to_media_devnode(cd) container_of(cd, struct media_devnode, dev) +/** + * media_devnode_register - register a media device node + * + * @mdev: media device node structure we want to register + * @owner: should be filled with %THIS_MODULE + * + * The registration code assigns minor numbers and registers the new device node + * with the kernel. An error is returned if no free minor number can be found, + * or if the registration of the device node fails. + * + * Zero is returned on success. + * + * Note that if the media_devnode_register call fails, the release() callback of + * the media_devnode structure is *not* called, so the caller is responsible for + * freeing any data. + */ int __must_check media_devnode_register(struct media_devnode *mdev, struct module *owner); + +/** + * media_devnode_unregister - unregister a media device node + * @mdev: the device node to unregister + * + * This unregisters the passed device. Future open calls will be met with + * errors. + * + * This function can safely be called if the device node has never been + * registered or has already been unregistered. + */ void media_devnode_unregister(struct media_devnode *mdev); static inline struct media_devnode *media_devnode_data(struct file *filp) -- GitLab From 75c7e295707e7a9d13691377f2154dcbae9a25f8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 13 Dec 2015 09:00:00 -0200 Subject: [PATCH 2564/2855] [media] media-devnode.h: document the remaining struct/functions There is one struct and two functions that were not documented. Add the corresponding kernel-doc documentation for them. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-devnode.h | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index 77e9d3159be89..fe42f08e72bdc 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -40,6 +40,20 @@ */ #define MEDIA_FLAG_REGISTERED 0 +/** + * struct media_file_operations - Media device file operations + * + * @owner: should be filled with %THIS_MODULE + * @read: pointer to the function that implements read() syscall + * @write: pointer to the function that implements write() syscall + * @poll: pointer to the function that implements poll() syscall + * @ioctl: pointer to the function that implements ioctl() syscall + * @compat_ioctl: pointer to the function that will handle 32 bits userspace + * calls to the the ioctl() syscall on a Kernel compiled with 64 bits. + * @open: pointer to the function that implements open() syscall + * @release: pointer to the function that will release the resources allocated + * by the @open function. + */ struct media_file_operations { struct module *owner; ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); @@ -53,7 +67,7 @@ struct media_file_operations { /** * struct media_devnode - Media device node - * @fops: pointer to struct media_file_operations with media device ops + * @fops: pointer to struct &media_file_operations with media device ops * @dev: struct device pointer for the media controller device * @cdev: struct cdev pointer character device * @parent: parent device @@ -117,11 +131,22 @@ int __must_check media_devnode_register(struct media_devnode *mdev, */ void media_devnode_unregister(struct media_devnode *mdev); +/** + * media_devnode_data - returns a pointer to the &media_devnode + * + * @filp: pointer to struct &file + */ static inline struct media_devnode *media_devnode_data(struct file *filp) { return filp->private_data; } +/** + * media_devnode_is_registered - returns true if &media_devnode is registered; + * false otherwise. + * + * @mdev: pointer to struct &media_devnode. + */ static inline int media_devnode_is_registered(struct media_devnode *mdev) { return test_bit(MEDIA_FLAG_REGISTERED, &mdev->flags); -- GitLab From 5c883edb5b2c34e96e57037c95f9a72c4feccc50 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 15 Dec 2015 07:58:18 -0200 Subject: [PATCH 2565/2855] [media] media-entity: use mutes for link setup Changeset f8fd4c61b5ae ("[media] media-entity: protect object creation/removal using spin lock") changed the object creation/removal protection to spin lock, as this is what's used on media-device, keeping the mutex reserved for graph traversal routines. However, it also changed the link setup, by mistake. This could cause troubles, as the link setup can affect the graph traversal, and this is likely the reason for a mutex there. So, revert media_entity_setup_link() to use mutex. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 4822763dcefac..f88740b12879d 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -662,9 +662,9 @@ int media_entity_setup_link(struct media_link *link, u32 flags) { int ret; - spin_lock(&link->source->entity->graph_obj.mdev->lock); + mutex_lock(&link->graph_obj.mdev->graph_mutex); ret = __media_entity_setup_link(link, flags); - spin_unlock(&link->source->entity->graph_obj.mdev->lock); + mutex_unlock(&link->graph_obj.mdev->graph_mutex); return ret; } -- GitLab From cc4a82581cb604444b0f9f2e7d999624964695e2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 15 Dec 2015 08:01:13 -0200 Subject: [PATCH 2566/2855] [media] media-entity: cache media_device on object removal As pointed by Dan, the commit f8fd4c61b5ae ("[media] media-entity: protect object creation/removal using spin lock")' leads to the following static checker warning: drivers/media/media-entity.c:781 media_remove_intf_link() error: dereferencing freed memory 'link' drivers/media/media-entity.c 777 void media_remove_intf_link(struct media_link *link) 778 { 779 spin_lock(&link->graph_obj.mdev->lock); 780 __media_remove_intf_link(link); 781 spin_unlock(&link->graph_obj.mdev->lock); In practice, I didn't see any troubles even with KASAN enabled. I guess gcc optimizer internally cached the mdev reference, instead of getting it twice. Yet, it is a very bad idea to rely on such optimization. So, let's fix the code. Reported-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index f88740b12879d..13c8ca11f169e 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -580,13 +580,15 @@ EXPORT_SYMBOL_GPL(__media_entity_remove_links); void media_entity_remove_links(struct media_entity *entity) { + struct media_device *mdev = entity->graph_obj.mdev; + /* Do nothing if the entity is not registered. */ - if (entity->graph_obj.mdev == NULL) + if (mdev == NULL) return; - spin_lock(&entity->graph_obj.mdev->lock); + spin_lock(&mdev->lock); __media_entity_remove_links(entity); - spin_unlock(&entity->graph_obj.mdev->lock); + spin_unlock(&mdev->lock); } EXPORT_SYMBOL_GPL(media_entity_remove_links); @@ -781,9 +783,15 @@ EXPORT_SYMBOL_GPL(__media_remove_intf_link); void media_remove_intf_link(struct media_link *link) { - spin_lock(&link->graph_obj.mdev->lock); + struct media_device *mdev = link->graph_obj.mdev; + + /* Do nothing if the intf is not registered. */ + if (mdev == NULL) + return; + + spin_lock(&mdev->lock); __media_remove_intf_link(link); - spin_unlock(&link->graph_obj.mdev->lock); + spin_unlock(&mdev->lock); } EXPORT_SYMBOL_GPL(media_remove_intf_link); @@ -799,12 +807,14 @@ EXPORT_SYMBOL_GPL(__media_remove_intf_links); void media_remove_intf_links(struct media_interface *intf) { + struct media_device *mdev = intf->graph_obj.mdev; + /* Do nothing if the intf is not registered. */ - if (intf->graph_obj.mdev == NULL) + if (mdev == NULL) return; - spin_lock(&intf->graph_obj.mdev->lock); + spin_lock(&mdev->lock); __media_remove_intf_links(intf); - spin_unlock(&intf->graph_obj.mdev->lock); + spin_unlock(&mdev->lock); } EXPORT_SYMBOL_GPL(media_remove_intf_links); -- GitLab From 223d19c56651a0204253035f9ed28834653d2b4b Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 11 Dec 2015 20:57:07 -0200 Subject: [PATCH 2567/2855] [media] media-device: check before unregister if mdev was registered Most media functions that unregister, check if the corresponding register function succeed before. So these functions can safely be called even if a registration was never made or the component as already been unregistered. Add the same check to media_device_unregister() function for consistency. This will also allow to split the media_device_register() function in an initialization and registration functions without the need to change the generic cleanup functions and error code paths for all the media drivers. Suggested-by: Sakari Ailus Signed-off-by: Javier Martinez Canillas Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index ca16bd3091bd6..da4126863ecc9 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -577,6 +577,8 @@ EXPORT_SYMBOL_GPL(__media_device_register); * media_device_unregister - unregister a media device * @mdev: The media device * + * It is safe to call this function on an unregistered + * (but initialised) media device. */ void media_device_unregister(struct media_device *mdev) { @@ -584,6 +586,10 @@ void media_device_unregister(struct media_device *mdev) struct media_entity *next; struct media_interface *intf, *tmp_intf; + /* Check if mdev was ever registered at all */ + if (!media_devnode_is_registered(&mdev->devnode)) + return; + /* Remove all entities from the media device */ list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list) media_device_unregister_entity(entity); -- GitLab From b2ed8af910a436e12038f8ec8ca6c039f43767a4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 15 Dec 2015 08:26:52 -0200 Subject: [PATCH 2568/2855] [media] media-device: move media entity register/unregister functions media entity register and unregister functions are called by media device register/unregister. Move them to occur earlier, as we'll need an unlocked version of media_device_entity_unregister() and we don't want to add a function prototype without needing it. No functional changes. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 160 +++++++++++++++++------------------ 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index da4126863ecc9..1222fa642ad84 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -528,6 +528,86 @@ static void media_device_release(struct media_devnode *mdev) dev_dbg(mdev->parent, "Media device released\n"); } +/** + * media_device_register_entity - Register an entity with a media device + * @mdev: The media device + * @entity: The entity + */ +int __must_check media_device_register_entity(struct media_device *mdev, + struct media_entity *entity) +{ + unsigned int i; + + if (entity->function == MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN || + entity->function == MEDIA_ENT_F_UNKNOWN) + dev_warn(mdev->dev, + "Entity type for entity %s was not initialized!\n", + entity->name); + + /* Warn if we apparently re-register an entity */ + WARN_ON(entity->graph_obj.mdev != NULL); + entity->graph_obj.mdev = mdev; + INIT_LIST_HEAD(&entity->links); + entity->num_links = 0; + entity->num_backlinks = 0; + + spin_lock(&mdev->lock); + /* Initialize media_gobj embedded at the entity */ + media_gobj_create(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); + + /* Initialize objects at the pads */ + for (i = 0; i < entity->num_pads; i++) + media_gobj_create(mdev, MEDIA_GRAPH_PAD, + &entity->pads[i].graph_obj); + + spin_unlock(&mdev->lock); + + return 0; +} +EXPORT_SYMBOL_GPL(media_device_register_entity); + +/** + * media_device_unregister_entity - Unregister an entity + * @entity: The entity + * + * If the entity has never been registered this function will return + * immediately. + */ +void media_device_unregister_entity(struct media_entity *entity) +{ + struct media_device *mdev = entity->graph_obj.mdev; + struct media_link *link, *tmp; + struct media_interface *intf; + unsigned int i; + + if (mdev == NULL) + return; + + spin_lock(&mdev->lock); + + /* Remove all interface links pointing to this entity */ + list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) { + list_for_each_entry_safe(link, tmp, &intf->links, list) { + if (link->entity == entity) + __media_remove_intf_link(link); + } + } + + /* Remove all data links that belong to this entity */ + __media_entity_remove_links(entity); + + /* Remove all pads that belong to this entity */ + for (i = 0; i < entity->num_pads; i++) + media_gobj_destroy(&entity->pads[i].graph_obj); + + /* Remove the entity */ + media_gobj_destroy(&entity->graph_obj); + + spin_unlock(&mdev->lock); + entity->graph_obj.mdev = NULL; +} +EXPORT_SYMBOL_GPL(media_device_unregister_entity); + /** * media_device_register - register a media device * @mdev: The media device @@ -611,86 +691,6 @@ void media_device_unregister(struct media_device *mdev) } EXPORT_SYMBOL_GPL(media_device_unregister); -/** - * media_device_register_entity - Register an entity with a media device - * @mdev: The media device - * @entity: The entity - */ -int __must_check media_device_register_entity(struct media_device *mdev, - struct media_entity *entity) -{ - unsigned int i; - - if (entity->function == MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN || - entity->function == MEDIA_ENT_F_UNKNOWN) - dev_warn(mdev->dev, - "Entity type for entity %s was not initialized!\n", - entity->name); - - /* Warn if we apparently re-register an entity */ - WARN_ON(entity->graph_obj.mdev != NULL); - entity->graph_obj.mdev = mdev; - INIT_LIST_HEAD(&entity->links); - entity->num_links = 0; - entity->num_backlinks = 0; - - spin_lock(&mdev->lock); - /* Initialize media_gobj embedded at the entity */ - media_gobj_create(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); - - /* Initialize objects at the pads */ - for (i = 0; i < entity->num_pads; i++) - media_gobj_create(mdev, MEDIA_GRAPH_PAD, - &entity->pads[i].graph_obj); - - spin_unlock(&mdev->lock); - - return 0; -} -EXPORT_SYMBOL_GPL(media_device_register_entity); - -/** - * media_device_unregister_entity - Unregister an entity - * @entity: The entity - * - * If the entity has never been registered this function will return - * immediately. - */ -void media_device_unregister_entity(struct media_entity *entity) -{ - struct media_device *mdev = entity->graph_obj.mdev; - struct media_link *link, *tmp; - struct media_interface *intf; - unsigned int i; - - if (mdev == NULL) - return; - - spin_lock(&mdev->lock); - - /* Remove all interface links pointing to this entity */ - list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) { - list_for_each_entry_safe(link, tmp, &intf->links, list) { - if (link->entity == entity) - __media_remove_intf_link(link); - } - } - - /* Remove all data links that belong to this entity */ - __media_entity_remove_links(entity); - - /* Remove all pads that belong to this entity */ - for (i = 0; i < entity->num_pads; i++) - media_gobj_destroy(&entity->pads[i].graph_obj); - - /* Remove the entity */ - media_gobj_destroy(&entity->graph_obj); - - spin_unlock(&mdev->lock); - entity->graph_obj.mdev = NULL; -} -EXPORT_SYMBOL_GPL(media_device_unregister_entity); - static void media_device_release_devres(struct device *dev, void *res) { } -- GitLab From 821ed3662913faca0653c201fa9e36fbab81f17c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 15 Dec 2015 08:36:51 -0200 Subject: [PATCH 2569/2855] [media] media-device: better lock media_device_unregister() If media_device_unregister() is called by two different drivers, a race condition may happen, as the check if the device is not registered is not protected. Move the spin_lock() to happen earlier in the function, in order to prevent such race condition. Reported-by: Shuah Khan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 1222fa642ad84..189c2ba8c3d35 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -573,18 +573,13 @@ EXPORT_SYMBOL_GPL(media_device_register_entity); * If the entity has never been registered this function will return * immediately. */ -void media_device_unregister_entity(struct media_entity *entity) +static void __media_device_unregister_entity(struct media_entity *entity) { struct media_device *mdev = entity->graph_obj.mdev; struct media_link *link, *tmp; struct media_interface *intf; unsigned int i; - if (mdev == NULL) - return; - - spin_lock(&mdev->lock); - /* Remove all interface links pointing to this entity */ list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) { list_for_each_entry_safe(link, tmp, &intf->links, list) { @@ -603,11 +598,23 @@ void media_device_unregister_entity(struct media_entity *entity) /* Remove the entity */ media_gobj_destroy(&entity->graph_obj); - spin_unlock(&mdev->lock); entity->graph_obj.mdev = NULL; } + +void media_device_unregister_entity(struct media_entity *entity) +{ + struct media_device *mdev = entity->graph_obj.mdev; + + if (mdev == NULL) + return; + + spin_lock(&mdev->lock); + __media_device_unregister_entity(entity); + spin_unlock(&mdev->lock); +} EXPORT_SYMBOL_GPL(media_device_unregister_entity); + /** * media_device_register - register a media device * @mdev: The media device @@ -666,22 +673,29 @@ void media_device_unregister(struct media_device *mdev) struct media_entity *next; struct media_interface *intf, *tmp_intf; + if (mdev == NULL) + return; + + spin_lock(&mdev->lock); + /* Check if mdev was ever registered at all */ - if (!media_devnode_is_registered(&mdev->devnode)) + if (!media_devnode_is_registered(&mdev->devnode)) { + spin_unlock(&mdev->lock); return; + } /* Remove all entities from the media device */ list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list) - media_device_unregister_entity(entity); + __media_device_unregister_entity(entity); /* Remove all interfaces from the media device */ - spin_lock(&mdev->lock); list_for_each_entry_safe(intf, tmp_intf, &mdev->interfaces, graph_obj.list) { __media_remove_intf_links(intf); media_gobj_destroy(&intf->graph_obj); kfree(intf); } + spin_unlock(&mdev->lock); device_remove_file(&mdev->devnode.dev, &dev_attr_model); -- GitLab From 9832e155f1ed3030fdfaa19e72c06472dc2ecb1d Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 11 Dec 2015 20:57:08 -0200 Subject: [PATCH 2570/2855] [media] media-device: split media initialization and registration The media device node is registered and so made visible to user-space before entities are registered and links created which means that the media graph obtained by user-space could be only partially enumerated if that happens too early before all the graph has been created. To avoid this race condition, split the media init and registration in separate functions and only register the media device node when all the pending subdevices have been registered, either explicitly by the driver or asynchronously using v4l2_async_register_subdev(). The media_device_register() had a check for drivers not filling dev and model fields but all drivers in mainline set them and not doing it will be a driver bug so change the function return to void and add a BUG_ON() for dev being NULL instead. Also, add a media_device_cleanup() function that will destroy the graph_mutex that is initialized in media_device_init(). [mchehab@osg.samsung.com: Fix compilation if !CONFIG_MEDIA_CONTROLLER and remove two warnings added by this changeset] Suggested-by: Sakari Ailus Signed-off-by: Javier Martinez Canillas Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb-main.c | 1 + drivers/media/media-device.c | 37 +++++++++++++++---- drivers/media/platform/exynos4-is/media-dev.c | 15 ++++---- drivers/media/platform/omap3isp/isp.c | 14 +++---- drivers/media/platform/s3c-camif/camif-core.c | 15 +++++--- drivers/media/platform/vsp1/vsp1_drv.c | 12 +++--- drivers/media/platform/xilinx/xilinx-vipp.c | 12 ++---- drivers/media/usb/au0828/au0828-core.c | 29 ++++++++------- drivers/media/usb/cx231xx/cx231xx-cards.c | 32 ++++++++-------- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 23 ++++++------ drivers/media/usb/dvb-usb/dvb-usb-dvb.c | 25 +++++++------ drivers/media/usb/siano/smsusb.c | 5 ++- drivers/media/usb/uvc/uvc_driver.c | 11 ++++-- include/media/media-device.h | 26 +++++++++++++ 14 files changed, 158 insertions(+), 99 deletions(-) diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index ab345490a43ad..8a1ea21924394 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -617,6 +617,7 @@ static void smsdvb_media_device_unregister(struct smsdvb_client_t *client) if (!coredev->media_dev) return; media_device_unregister(coredev->media_dev); + media_device_cleanup(coredev->media_dev); kfree(coredev->media_dev); coredev->media_dev = NULL; #endif diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 189c2ba8c3d35..b718c783debd6 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -616,7 +616,7 @@ EXPORT_SYMBOL_GPL(media_device_unregister_entity); /** - * media_device_register - register a media device + * media_device_init() - initialize a media device * @mdev: The media device * * The caller is responsible for initializing the media device before @@ -625,14 +625,8 @@ EXPORT_SYMBOL_GPL(media_device_unregister_entity); * - dev must point to the parent device * - model must be filled with the device model name */ -int __must_check __media_device_register(struct media_device *mdev, - struct module *owner) +void media_device_init(struct media_device *mdev) { - int ret; - - if (WARN_ON(mdev->dev == NULL || mdev->model[0] == 0)) - return -EINVAL; - INIT_LIST_HEAD(&mdev->entities); INIT_LIST_HEAD(&mdev->interfaces); INIT_LIST_HEAD(&mdev->pads); @@ -640,6 +634,33 @@ int __must_check __media_device_register(struct media_device *mdev, spin_lock_init(&mdev->lock); mutex_init(&mdev->graph_mutex); + dev_dbg(mdev->dev, "Media device initialized\n"); +} +EXPORT_SYMBOL_GPL(media_device_init); + +/** + * media_device_cleanup() - Cleanup a media device + * @mdev: The media device + * + */ +void media_device_cleanup(struct media_device *mdev) +{ + mutex_destroy(&mdev->graph_mutex); +} +EXPORT_SYMBOL_GPL(media_device_cleanup); + +/** + * __media_device_register() - register a media device + * @mdev: The media device + * @owner: The module owner + * + * returns zero on success or a negative error code. + */ +int __must_check __media_device_register(struct media_device *mdev, + struct module *owner) +{ + int ret; + /* Register the device node. */ mdev->devnode.fops = &media_device_fops; mdev->devnode.parent = mdev->dev; diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index a61ecedc12015..27663dd452949 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -1313,7 +1313,10 @@ static int subdev_notifier_complete(struct v4l2_async_notifier *notifier) ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev); unlock: mutex_unlock(&fmd->media_dev.graph_mutex); - return ret; + if (ret < 0) + return ret; + + return media_device_register(&fmd->media_dev); } static int fimc_md_probe(struct platform_device *pdev) @@ -1350,11 +1353,7 @@ static int fimc_md_probe(struct platform_device *pdev) return ret; } - ret = media_device_register(&fmd->media_dev); - if (ret < 0) { - v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret); - goto err_v4l2_dev; - } + media_device_init(&fmd->media_dev); ret = fimc_md_get_clocks(fmd); if (ret) @@ -1424,8 +1423,7 @@ err_clk: err_m_ent: fimc_md_unregister_entities(fmd); err_md: - media_device_unregister(&fmd->media_dev); -err_v4l2_dev: + media_device_cleanup(&fmd->media_dev); v4l2_device_unregister(&fmd->v4l2_dev); return ret; } @@ -1445,6 +1443,7 @@ static int fimc_md_remove(struct platform_device *pdev) fimc_md_unregister_entities(fmd); fimc_md_pipelines_free(fmd); media_device_unregister(&fmd->media_dev); + media_device_cleanup(&fmd->media_dev); fimc_md_put_clocks(fmd); return 0; diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 8226eca833279..942b189c0eca5 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -1793,6 +1793,7 @@ static void isp_unregister_entities(struct isp_device *isp) v4l2_device_unregister(&isp->v4l2_dev); media_device_unregister(&isp->media_dev); + media_device_cleanup(&isp->media_dev); } static int isp_link_entity( @@ -1875,12 +1876,7 @@ static int isp_register_entities(struct isp_device *isp) sizeof(isp->media_dev.model)); isp->media_dev.hw_revision = isp->revision; isp->media_dev.link_notify = isp_pipeline_link_notify; - ret = media_device_register(&isp->media_dev); - if (ret < 0) { - dev_err(isp->dev, "%s: Media device registration failed (%d)\n", - __func__, ret); - return ret; - } + media_device_init(&isp->media_dev); isp->v4l2_dev.mdev = &isp->media_dev; ret = v4l2_device_register(isp->dev, &isp->v4l2_dev); @@ -2365,7 +2361,11 @@ static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async) } } - return v4l2_device_register_subdev_nodes(v4l2_dev); + ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev); + if (ret < 0) + return ret; + + return media_device_register(&isp->media_dev); } /* diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c index 8649d4c0e90d5..ea02b7ef2119b 100644 --- a/drivers/media/platform/s3c-camif/camif-core.c +++ b/drivers/media/platform/s3c-camif/camif-core.c @@ -305,7 +305,7 @@ static void camif_unregister_media_entities(struct camif_dev *camif) /* * Media device */ -static int camif_media_dev_register(struct camif_dev *camif) +static int camif_media_dev_init(struct camif_dev *camif) { struct media_device *md = &camif->media_dev; struct v4l2_device *v4l2_dev = &camif->v4l2_dev; @@ -328,9 +328,7 @@ static int camif_media_dev_register(struct camif_dev *camif) if (ret < 0) return ret; - ret = media_device_register(md); - if (ret < 0) - v4l2_device_unregister(v4l2_dev); + media_device_init(md); return ret; } @@ -483,7 +481,7 @@ static int s3c_camif_probe(struct platform_device *pdev) goto err_alloc; } - ret = camif_media_dev_register(camif); + ret = camif_media_dev_init(camif); if (ret < 0) goto err_mdev; @@ -510,6 +508,11 @@ static int s3c_camif_probe(struct platform_device *pdev) goto err_unlock; mutex_unlock(&camif->media_dev.graph_mutex); + + ret = media_device_register(&camif->media_dev); + if (ret < 0) + goto err_sens; + pm_runtime_put(dev); return 0; @@ -518,6 +521,7 @@ err_unlock: err_sens: v4l2_device_unregister(&camif->v4l2_dev); media_device_unregister(&camif->media_dev); + media_device_cleanup(&camif->media_dev); camif_unregister_media_entities(camif); err_mdev: vb2_dma_contig_cleanup_ctx(camif->alloc_ctx); @@ -539,6 +543,7 @@ static int s3c_camif_remove(struct platform_device *pdev) struct s3c_camif_plat_data *pdata = &camif->pdata; media_device_unregister(&camif->media_dev); + media_device_cleanup(&camif->media_dev); camif_unregister_media_entities(camif); v4l2_device_unregister(&camif->v4l2_dev); diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 0b251147bfff4..42dff9d020afa 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -127,6 +127,7 @@ static void vsp1_destroy_entities(struct vsp1_device *vsp1) v4l2_device_unregister(&vsp1->v4l2_dev); media_device_unregister(&vsp1->media_dev); + media_device_cleanup(&vsp1->media_dev); } static int vsp1_create_entities(struct vsp1_device *vsp1) @@ -141,12 +142,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) strlcpy(mdev->model, "VSP1", sizeof(mdev->model)); snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s", dev_name(mdev->dev)); - ret = media_device_register(mdev); - if (ret < 0) { - dev_err(vsp1->dev, "media device registration failed (%d)\n", - ret); - return ret; - } + media_device_init(mdev); vdev->mdev = mdev; ret = v4l2_device_register(vsp1->dev, vdev); @@ -284,6 +280,10 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) } ret = v4l2_device_register_subdev_nodes(&vsp1->v4l2_dev); + if (ret < 0) + goto done; + + ret = media_device_register(mdev); done: if (ret < 0) diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c index 2352f7e5a6a3d..e795a4501e8b4 100644 --- a/drivers/media/platform/xilinx/xilinx-vipp.c +++ b/drivers/media/platform/xilinx/xilinx-vipp.c @@ -311,7 +311,7 @@ static int xvip_graph_notify_complete(struct v4l2_async_notifier *notifier) if (ret < 0) dev_err(xdev->dev, "failed to register subdev nodes\n"); - return ret; + return media_device_register(&xdev->media_dev); } static int xvip_graph_notify_bound(struct v4l2_async_notifier *notifier, @@ -573,6 +573,7 @@ static void xvip_composite_v4l2_cleanup(struct xvip_composite_device *xdev) { v4l2_device_unregister(&xdev->v4l2_dev); media_device_unregister(&xdev->media_dev); + media_device_cleanup(&xdev->media_dev); } static int xvip_composite_v4l2_init(struct xvip_composite_device *xdev) @@ -584,19 +585,14 @@ static int xvip_composite_v4l2_init(struct xvip_composite_device *xdev) sizeof(xdev->media_dev.model)); xdev->media_dev.hw_revision = 0; - ret = media_device_register(&xdev->media_dev); - if (ret < 0) { - dev_err(xdev->dev, "media device registration failed (%d)\n", - ret); - return ret; - } + media_device_init(&xdev->media_dev); xdev->v4l2_dev.mdev = &xdev->media_dev; ret = v4l2_device_register(xdev->dev, &xdev->v4l2_dev); if (ret < 0) { dev_err(xdev->dev, "V4L2 device registration failed (%d)\n", ret); - media_device_unregister(&xdev->media_dev); + media_device_cleanup(&xdev->media_dev); return ret; } diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 1b207fa16a55a..fbdaeb206565b 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -136,6 +136,7 @@ static void au0828_unregister_media_device(struct au0828_dev *dev) #ifdef CONFIG_MEDIA_CONTROLLER if (dev->media_dev) { media_device_unregister(dev->media_dev); + media_device_cleanup(dev->media_dev); kfree(dev->media_dev); dev->media_dev = NULL; } @@ -216,12 +217,11 @@ static void au0828_usb_disconnect(struct usb_interface *interface) au0828_usb_release(dev); } -static void au0828_media_device_register(struct au0828_dev *dev, - struct usb_device *udev) +static void au0828_media_device_init(struct au0828_dev *dev, + struct usb_device *udev) { #ifdef CONFIG_MEDIA_CONTROLLER struct media_device *mdev; - int ret; mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); if (!mdev) @@ -239,14 +239,7 @@ static void au0828_media_device_register(struct au0828_dev *dev, mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); mdev->driver_version = LINUX_VERSION_CODE; - ret = media_device_register(mdev); - if (ret) { - pr_err( - "Couldn't create a media device. Error: %d\n", - ret); - kfree(mdev); - return; - } + media_device_init(mdev); dev->media_dev = mdev; #endif @@ -374,8 +367,8 @@ static int au0828_usb_probe(struct usb_interface *interface, dev->boardnr = id->driver_info; dev->board = au0828_boards[dev->boardnr]; - /* Register the media controller */ - au0828_media_device_register(dev, usbdev); + /* Initialize the media controller */ + au0828_media_device_init(dev, usbdev); #ifdef CONFIG_VIDEO_AU0828_V4L2 dev->v4l2_dev.release = au0828_usb_v4l2_release; @@ -446,9 +439,17 @@ static int au0828_usb_probe(struct usb_interface *interface, if (retval) { pr_err("%s() au0282_dev_register failed to create graph\n", __func__); - au0828_usb_disconnect(interface); + goto done; } +#ifdef CONFIG_MEDIA_CONTROLLER + retval = media_device_register(dev->media_dev); +#endif + +done: + if (retval < 0) + au0828_usb_disconnect(interface); + return retval; } diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 0e1efc59ff58d..de0026b5265cf 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1172,6 +1172,7 @@ static void cx231xx_unregister_media_device(struct cx231xx *dev) #ifdef CONFIG_MEDIA_CONTROLLER if (dev->media_dev) { media_device_unregister(dev->media_dev); + media_device_cleanup(dev->media_dev); kfree(dev->media_dev); dev->media_dev = NULL; } @@ -1205,12 +1206,11 @@ void cx231xx_release_resources(struct cx231xx *dev) clear_bit(dev->devno, &cx231xx_devused); } -static void cx231xx_media_device_register(struct cx231xx *dev, - struct usb_device *udev) +static void cx231xx_media_device_init(struct cx231xx *dev, + struct usb_device *udev) { #ifdef CONFIG_MEDIA_CONTROLLER struct media_device *mdev; - int ret; mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); if (!mdev) @@ -1224,14 +1224,7 @@ static void cx231xx_media_device_register(struct cx231xx *dev, mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); mdev->driver_version = LINUX_VERSION_CODE; - ret = media_device_register(mdev); - if (ret) { - dev_err(dev->dev, - "Couldn't create a media device. Error: %d\n", - ret); - kfree(mdev); - return; - } + media_device_init(mdev); dev->media_dev = mdev; #endif @@ -1669,8 +1662,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, /* save our data pointer in this interface device */ usb_set_intfdata(interface, dev); - /* Register the media controller */ - cx231xx_media_device_register(dev, udev); + /* Initialize the media controller */ + cx231xx_media_device_init(dev, udev); /* Create v4l2 device */ #ifdef CONFIG_MEDIA_CONTROLLER @@ -1742,11 +1735,18 @@ static int cx231xx_usb_probe(struct usb_interface *interface, request_modules(dev); retval = cx231xx_create_media_graph(dev); - if (retval < 0) { - cx231xx_release_resources(dev); - } + if (retval < 0) + goto done; + +#ifdef CONFIG_MEDIA_CONTROLLER + retval = media_device_register(dev->media_dev); +#endif +done: + if (retval < 0) + cx231xx_release_resources(dev); return retval; + err_video_alt: /* cx231xx_uninit_dev: */ cx231xx_close_extension(dev); diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index 6d3f61f6dc775..7f52bcbd8b0d6 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -400,13 +400,12 @@ skip_feed_stop: return ret; } -static void dvb_usbv2_media_device_register(struct dvb_usb_adapter *adap) +static void dvb_usbv2_media_device_init(struct dvb_usb_adapter *adap) { #ifdef CONFIG_MEDIA_CONTROLLER_DVB struct media_device *mdev; struct dvb_usb_device *d = adap_to_d(adap); struct usb_device *udev = d->udev; - int ret; mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); if (!mdev) @@ -420,19 +419,18 @@ static void dvb_usbv2_media_device_register(struct dvb_usb_adapter *adap) mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); mdev->driver_version = LINUX_VERSION_CODE; - ret = media_device_register(mdev); - if (ret) { - dev_err(&d->udev->dev, - "Couldn't create a media device. Error: %d\n", - ret); - kfree(mdev); - return; - } + media_device_init(mdev); dvb_register_media_controller(&adap->dvb_adap, mdev); dev_info(&d->udev->dev, "media controller created\n"); +#endif +} +static void dvb_usbv2_media_device_register(struct dvb_usb_adapter *adap) +{ +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + media_device_register(adap->dvb_adap.mdev); #endif } @@ -444,6 +442,7 @@ static void dvb_usbv2_media_device_unregister(struct dvb_usb_adapter *adap) return; media_device_unregister(adap->dvb_adap.mdev); + media_device_cleanup(adap->dvb_adap.mdev); kfree(adap->dvb_adap.mdev); adap->dvb_adap.mdev = NULL; @@ -467,7 +466,7 @@ static int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap) adap->dvb_adap.priv = adap; - dvb_usbv2_media_device_register(adap); + dvb_usbv2_media_device_init(adap); if (d->props->read_mac_address) { ret = d->props->read_mac_address(adap, @@ -702,6 +701,8 @@ static int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap) if (ret < 0) goto err_dvb_unregister_frontend; + dvb_usbv2_media_device_register(adap); + return 0; err_dvb_unregister_frontend: diff --git a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c index b51dbdf03f422..6a4bb2d861750 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c @@ -95,13 +95,12 @@ static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) return dvb_usb_ctrl_feed(dvbdmxfeed, 0); } -static void dvb_usb_media_device_register(struct dvb_usb_adapter *adap) +static void dvb_usb_media_device_init(struct dvb_usb_adapter *adap) { #ifdef CONFIG_MEDIA_CONTROLLER_DVB struct media_device *mdev; struct dvb_usb_device *d = adap->dev; struct usb_device *udev = d->udev; - int ret; mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); if (!mdev) @@ -115,20 +114,21 @@ static void dvb_usb_media_device_register(struct dvb_usb_adapter *adap) mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); mdev->driver_version = LINUX_VERSION_CODE; - ret = media_device_register(mdev); - if (ret) { - dev_err(&d->udev->dev, - "Couldn't create a media device. Error: %d\n", - ret); - kfree(mdev); - return; - } + media_device_init(mdev); + dvb_register_media_controller(&adap->dvb_adap, mdev); dev_info(&d->udev->dev, "media controller created\n"); #endif } +static void dvb_usb_media_device_register(struct dvb_usb_adapter *adap) +{ +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + media_device_register(adap->dvb_adap.mdev); +#endif +} + static void dvb_usb_media_device_unregister(struct dvb_usb_adapter *adap) { #ifdef CONFIG_MEDIA_CONTROLLER_DVB @@ -136,6 +136,7 @@ static void dvb_usb_media_device_unregister(struct dvb_usb_adapter *adap) return; media_device_unregister(adap->dvb_adap.mdev); + media_device_cleanup(adap->dvb_adap.mdev); kfree(adap->dvb_adap.mdev); adap->dvb_adap.mdev = NULL; #endif @@ -154,7 +155,7 @@ int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums) } adap->dvb_adap.priv = adap; - dvb_usb_media_device_register(adap); + dvb_usb_media_device_init(adap); if (adap->dev->props.read_mac_address) { if (adap->dev->props.read_mac_address(adap->dev, adap->dvb_adap.proposed_mac) == 0) @@ -323,6 +324,8 @@ int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap) ret = dvb_create_media_graph(&adap->dvb_adap); + dvb_usb_media_device_register(adap); + return ret; } diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index c945e4c2fbd49..8abbd3cc8eba7 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -361,10 +361,11 @@ static void *siano_media_device_register(struct smsusb_device_t *dev, mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); mdev->driver_version = LINUX_VERSION_CODE; + media_device_init(mdev); + ret = media_device_register(mdev); if (ret) { - pr_err("Couldn't create a media device. Error: %d\n", - ret); + media_device_cleanup(mdev); kfree(mdev); return NULL; } diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 39abbafad7966..4e7148815a785 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1656,6 +1656,7 @@ static void uvc_delete(struct uvc_device *dev) #ifdef CONFIG_MEDIA_CONTROLLER if (media_devnode_is_registered(&dev->mdev.devnode)) media_device_unregister(&dev->mdev); + media_device_cleanup(&dev->mdev); #endif list_for_each_safe(p, n, &dev->chains) { @@ -1906,7 +1907,7 @@ static int uvc_probe(struct usb_interface *intf, "linux-uvc-devel mailing list.\n"); } - /* Register the media and V4L2 devices. */ + /* Initialize the media device and register the V4L2 device. */ #ifdef CONFIG_MEDIA_CONTROLLER dev->mdev.dev = &intf->dev; strlcpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model)); @@ -1916,8 +1917,7 @@ static int uvc_probe(struct usb_interface *intf, strcpy(dev->mdev.bus_info, udev->devpath); dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); dev->mdev.driver_version = LINUX_VERSION_CODE; - if (media_device_register(&dev->mdev) < 0) - goto error; + media_device_init(&dev->mdev); dev->vdev.mdev = &dev->mdev; #endif @@ -1936,6 +1936,11 @@ static int uvc_probe(struct usb_interface *intf, if (uvc_register_chains(dev) < 0) goto error; +#ifdef CONFIG_MEDIA_CONTROLLER + /* Register the media device node */ + if (media_device_register(&dev->mdev) < 0) + goto error; +#endif /* Save our data pointer in the interface data. */ usb_set_intfdata(intf, dev); diff --git a/include/media/media-device.h b/include/media/media-device.h index ebc2f3a239eb0..e01bbc427fcd9 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -337,6 +337,32 @@ struct media_device { /* media_devnode to media_device */ #define to_media_device(node) container_of(node, struct media_device, devnode) +/** + * media_device_init() - Initializes a media device element + * + * @mdev: pointer to struct &media_device + * + * This function initializes the media device prior to its registration. + * The media device initialization and registration is split in two functions + * to avoid race conditions and make the media device available to user-space + * before the media graph has been completed. + * + * So drivers need to first initialize the media device, register any entity + * within the media device, create pad to pad links and then finally register + * the media device by calling media_device_register() as a final step. + */ +void media_device_init(struct media_device *mdev); + +/** + * media_device_cleanup() - Cleanups a media device element + * + * @mdev: pointer to struct &media_device + * + * This function that will destroy the graph_mutex that is + * initialized in media_device_init(). + */ +void media_device_cleanup(struct media_device *mdev); + /** * __media_device_register() - Registers a media device element * -- GitLab From 9f80679511b0544d1ed8c9bc2d80030183e9f1ed Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Dec 2015 09:55:49 -0200 Subject: [PATCH 2571/2855] [media] usb: check media device errors There are now two new warnings: drivers/media/usb/dvb-usb-v2/dvb_usb_core.c: In function 'dvb_usbv2_media_device_register': drivers/media/usb/dvb-usb-v2/dvb_usb_core.c:433:2: warning: ignoring return value of '__media_device_register', declared with attribute warn_unused_result [-Wunused-result] media_device_register(adap->dvb_adap.mdev); ^ drivers/media/usb/dvb-usb/dvb-usb-dvb.c: In function 'dvb_usb_media_device_register': drivers/media/usb/dvb-usb/dvb-usb-dvb.c:128:2: warning: ignoring return value of '__media_device_register', declared with attribute warn_unused_result [-Wunused-result] media_device_register(adap->dvb_adap.mdev); ^ Those are because the drivers are not properly checking if the media device init and register were succeeded. Fix it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/au0828-core.c | 16 ++++++++++---- drivers/media/usb/cx231xx/cx231xx-cards.c | 13 +++++++++--- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 23 ++++++++++++++------- drivers/media/usb/dvb-usb/dvb-usb-dvb.c | 22 ++++++++++++++------ 4 files changed, 54 insertions(+), 20 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index fbdaeb206565b..9e29e70a78d7b 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -217,15 +217,15 @@ static void au0828_usb_disconnect(struct usb_interface *interface) au0828_usb_release(dev); } -static void au0828_media_device_init(struct au0828_dev *dev, - struct usb_device *udev) +static int au0828_media_device_init(struct au0828_dev *dev, + struct usb_device *udev) { #ifdef CONFIG_MEDIA_CONTROLLER struct media_device *mdev; mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); if (!mdev) - return; + return -ENOMEM; mdev->dev = &udev->dev; @@ -243,6 +243,7 @@ static void au0828_media_device_init(struct au0828_dev *dev, dev->media_dev = mdev; #endif + return 0; } @@ -368,7 +369,14 @@ static int au0828_usb_probe(struct usb_interface *interface, dev->board = au0828_boards[dev->boardnr]; /* Initialize the media controller */ - au0828_media_device_init(dev, usbdev); + retval = au0828_media_device_init(dev, usbdev); + if (retval) { + pr_err("%s() au0828_media_device_init failed\n", + __func__); + mutex_unlock(&dev->lock); + kfree(dev); + return retval; + } #ifdef CONFIG_VIDEO_AU0828_V4L2 dev->v4l2_dev.release = au0828_usb_v4l2_release; diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index de0026b5265cf..620b83d03f75a 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1206,7 +1206,7 @@ void cx231xx_release_resources(struct cx231xx *dev) clear_bit(dev->devno, &cx231xx_devused); } -static void cx231xx_media_device_init(struct cx231xx *dev, +static int cx231xx_media_device_init(struct cx231xx *dev, struct usb_device *udev) { #ifdef CONFIG_MEDIA_CONTROLLER @@ -1214,7 +1214,7 @@ static void cx231xx_media_device_init(struct cx231xx *dev, mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); if (!mdev) - return; + return -ENOMEM; mdev->dev = dev->dev; strlcpy(mdev->model, dev->board.name, sizeof(mdev->model)); @@ -1228,6 +1228,7 @@ static void cx231xx_media_device_init(struct cx231xx *dev, dev->media_dev = mdev; #endif + return 0; } static int cx231xx_create_media_graph(struct cx231xx *dev) @@ -1663,7 +1664,11 @@ static int cx231xx_usb_probe(struct usb_interface *interface, usb_set_intfdata(interface, dev); /* Initialize the media controller */ - cx231xx_media_device_init(dev, udev); + retval = cx231xx_media_device_init(dev, udev); + if (retval) { + dev_err(d, "cx231xx_media_device_init failed\n"); + goto err_media_init; + } /* Create v4l2 device */ #ifdef CONFIG_MEDIA_CONTROLLER @@ -1758,6 +1763,8 @@ err_video_alt: err_init: v4l2_device_unregister(&dev->v4l2_dev); err_v4l2: + cx231xx_unregister_media_device(dev); +err_media_init: usb_set_intfdata(interface, NULL); err_if: usb_put_dev(udev); diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index 7f52bcbd8b0d6..0fa2c45917b02 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -400,7 +400,7 @@ skip_feed_stop: return ret; } -static void dvb_usbv2_media_device_init(struct dvb_usb_adapter *adap) +static int dvb_usbv2_media_device_init(struct dvb_usb_adapter *adap) { #ifdef CONFIG_MEDIA_CONTROLLER_DVB struct media_device *mdev; @@ -409,7 +409,7 @@ static void dvb_usbv2_media_device_init(struct dvb_usb_adapter *adap) mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); if (!mdev) - return; + return -ENOMEM; mdev->dev = &udev->dev; strlcpy(mdev->model, d->name, sizeof(mdev->model)); @@ -425,12 +425,15 @@ static void dvb_usbv2_media_device_init(struct dvb_usb_adapter *adap) dev_info(&d->udev->dev, "media controller created\n"); #endif + return 0; } -static void dvb_usbv2_media_device_register(struct dvb_usb_adapter *adap) +static int dvb_usbv2_media_device_register(struct dvb_usb_adapter *adap) { #ifdef CONFIG_MEDIA_CONTROLLER_DVB - media_device_register(adap->dvb_adap.mdev); + return media_device_register(adap->dvb_adap.mdev); +#else + return 0; #endif } @@ -466,7 +469,12 @@ static int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap) adap->dvb_adap.priv = adap; - dvb_usbv2_media_device_init(adap); + ret = dvb_usbv2_media_device_init(adap); + if (ret < 0) { + dev_dbg(&d->udev->dev, "%s: dvb_usbv2_media_device_init() failed=%d\n", + __func__, ret); + goto err_dvb_register_mc; + } if (d->props->read_mac_address) { ret = d->props->read_mac_address(adap, @@ -517,6 +525,7 @@ err_dvb_dmxdev_init: dvb_dmx_release(&adap->demux); err_dvb_dmx_init: dvb_usbv2_media_device_unregister(adap); +err_dvb_register_mc: dvb_unregister_adapter(&adap->dvb_adap); err_dvb_register_adapter: adap->dvb_adap.priv = NULL; @@ -701,9 +710,9 @@ static int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap) if (ret < 0) goto err_dvb_unregister_frontend; - dvb_usbv2_media_device_register(adap); + ret = dvb_usbv2_media_device_register(adap); - return 0; + return ret; err_dvb_unregister_frontend: for (i = count_registered - 1; i >= 0; i--) diff --git a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c index 6a4bb2d861750..241463ef631e0 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c @@ -95,7 +95,7 @@ static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) return dvb_usb_ctrl_feed(dvbdmxfeed, 0); } -static void dvb_usb_media_device_init(struct dvb_usb_adapter *adap) +static int dvb_usb_media_device_init(struct dvb_usb_adapter *adap) { #ifdef CONFIG_MEDIA_CONTROLLER_DVB struct media_device *mdev; @@ -104,7 +104,7 @@ static void dvb_usb_media_device_init(struct dvb_usb_adapter *adap) mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); if (!mdev) - return; + return -ENOMEM; mdev->dev = &udev->dev; strlcpy(mdev->model, d->desc->name, sizeof(mdev->model)); @@ -120,12 +120,15 @@ static void dvb_usb_media_device_init(struct dvb_usb_adapter *adap) dev_info(&d->udev->dev, "media controller created\n"); #endif + return 0; } -static void dvb_usb_media_device_register(struct dvb_usb_adapter *adap) +static int dvb_usb_media_device_register(struct dvb_usb_adapter *adap) { #ifdef CONFIG_MEDIA_CONTROLLER_DVB - media_device_register(adap->dvb_adap.mdev); + return media_device_register(adap->dvb_adap.mdev); +#else + return 0; #endif } @@ -155,7 +158,11 @@ int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums) } adap->dvb_adap.priv = adap; - dvb_usb_media_device_init(adap); + ret = dvb_usb_media_device_init(adap); + if (ret < 0) { + deb_info("dvb_usb_media_device_init failed: error %d", ret); + goto err_mc; + } if (adap->dev->props.read_mac_address) { if (adap->dev->props.read_mac_address(adap->dev, adap->dvb_adap.proposed_mac) == 0) @@ -205,6 +212,7 @@ err_dmx_dev: dvb_dmx_release(&adap->demux); err_dmx: dvb_usb_media_device_unregister(adap); +err_mc: dvb_unregister_adapter(&adap->dvb_adap); err: return ret; @@ -323,8 +331,10 @@ int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap) return ret; ret = dvb_create_media_graph(&adap->dvb_adap); + if (ret) + return ret; - dvb_usb_media_device_register(adap); + ret = dvb_usb_media_device_register(adap); return ret; } -- GitLab From bdf5c198261cdda8dcc5375315afe9d8bf4d77d1 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 28 Dec 2015 01:45:00 +0200 Subject: [PATCH 2572/2855] [media] v4l2-device: Register entity before calling subdev's registered ops Registering a V4L2 sub-device includes, among other things, registering the related media entity and calling the sub-device's registered op. Since patch "media: convert links from array to list", creating a link between two pads requires registering the entity first. If the registered() op involves link creation, the link list head will not be initialised before it is used. Resolve this by first registering the entity, then calling its registered() op. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-device.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c index 85f724b53a148..2aa72aba4f172 100644 --- a/drivers/media/v4l2-core/v4l2-device.c +++ b/drivers/media/v4l2-core/v4l2-device.c @@ -180,26 +180,26 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, return -ENODEV; sd->v4l2_dev = v4l2_dev; - if (sd->internal_ops && sd->internal_ops->registered) { - err = sd->internal_ops->registered(sd); - if (err) - goto error_module; - } - /* This just returns 0 if either of the two args is NULL */ err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler, NULL); if (err) - goto error_unregister; + goto error_module; #if defined(CONFIG_MEDIA_CONTROLLER) /* Register the entity. */ if (v4l2_dev->mdev) { err = media_device_register_entity(v4l2_dev->mdev, entity); if (err < 0) - goto error_unregister; + goto error_module; } #endif + if (sd->internal_ops && sd->internal_ops->registered) { + err = sd->internal_ops->registered(sd); + if (err) + goto error_unregister; + } + spin_lock(&v4l2_dev->lock); list_add_tail(&sd->list, &v4l2_dev->subdevs); spin_unlock(&v4l2_dev->lock); @@ -207,8 +207,9 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, return 0; error_unregister: - if (sd->internal_ops && sd->internal_ops->unregistered) - sd->internal_ops->unregistered(sd); +#if defined(CONFIG_MEDIA_CONTROLLER) + media_device_unregister_entity(entity); +#endif error_module: if (!sd->owner_v4l2_dev) module_put(sd->owner); -- GitLab From 8a95079668bf35b265d3bb6381b8badb5bfa826a Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 11 Dec 2015 20:57:09 -0200 Subject: [PATCH 2573/2855] [media] media-device: set topology version 0 at media registration The G_TOPOLOGY ioctl is used to get a graph topology and since in the future a graph can be dynamically updated, there is a way to know the topology version so userspace can be aware that the graph has changed. The version 0 is reserved to indicate that the graph is static (i.e no graphs updates since the media device was registered). So, now that the media device initialization and registration has been split and the media device node is not exposed to user-space until all the entities have been registered and links created, it is safe to set a topology version 0 in media_device_register(). Suggested-by: Laurent Pinchart Suggested-by: Mauro Carvalho Chehab Signed-off-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index b718c783debd6..b3e19c22e6990 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -665,6 +665,10 @@ int __must_check __media_device_register(struct media_device *mdev, mdev->devnode.fops = &media_device_fops; mdev->devnode.parent = mdev->dev; mdev->devnode.release = media_device_release; + + /* Set version 0 to indicate user-space that the graph is static */ + mdev->topology_version = 0; + ret = media_devnode_register(&mdev->devnode, owner); if (ret < 0) return ret; -- GitLab From a5c82e5622d1b7f479c9a43873c2c5ac1f67765c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 15 Dec 2015 09:00:40 -0200 Subject: [PATCH 2574/2855] [media] media-device: copy_to/from_user() returns positive The copy_to/from_user() functions return the number of bytes *not* copied. They don't return error codes. Fixes: 4f6b3f363475 ('media] media-device: add support for MEDIA_IOC_G_TOPOLOGY ioctl') Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index b3e19c22e6990..30e3354d74814 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -376,18 +376,17 @@ static long media_device_get_topology(struct media_device *mdev, struct media_v2_topology ktopo; int ret; - ret = copy_from_user(&ktopo, utopo, sizeof(ktopo)); - - if (ret < 0) - return ret; + if (copy_from_user(&ktopo, utopo, sizeof(ktopo))) + return -EFAULT; ret = __media_device_get_topology(mdev, &ktopo); if (ret < 0) return ret; - ret = copy_to_user(utopo, &ktopo, sizeof(*utopo)); + if (copy_to_user(utopo, &ktopo, sizeof(*utopo))) + return -EFAULT; - return ret; + return 0; } static long media_device_ioctl(struct file *filp, unsigned int cmd, -- GitLab From 1630b832355399dd0dc4fcc2cadbcad47153a748 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 15 Dec 2015 09:04:14 -0200 Subject: [PATCH 2575/2855] [media] v4l2-device: fix a missing error code We need to set "err = -ENOMEM" here. Fixes: 38b11f19667a ('[media] v4l2-core: create MC interfaces for devnodes') Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-device.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c index 2aa72aba4f172..06fa5f1b2cfff 100644 --- a/drivers/media/v4l2-core/v4l2-device.c +++ b/drivers/media/v4l2-core/v4l2-device.c @@ -267,8 +267,10 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev) link = media_create_intf_link(&sd->entity, &vdev->intf_devnode->intf, MEDIA_LNK_FL_ENABLED); - if (!link) + if (!link) { + err = -ENOMEM; goto clean_up; + } } #endif sd->devnode = vdev; -- GitLab From 665faa971d087e8b968ef75d04079a7a462ddfca Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:17 -0200 Subject: [PATCH 2576/2855] [media] media: Introduce internal index for media entities The internal index can be used internally by the framework in order to keep track of entities for a purpose or another. The internal index is constant while it's registered to a media device, but the same index may be re-used once the entity having that index is unregistered. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 17 +++++++++++++++++ include/media/media-device.h | 4 ++++ include/media/media-entity.h | 3 +++ 3 files changed, 24 insertions(+) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 30e3354d74814..ce97f8f196f3b 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -551,6 +552,17 @@ int __must_check media_device_register_entity(struct media_device *mdev, entity->num_backlinks = 0; spin_lock(&mdev->lock); + + entity->internal_idx = ida_simple_get(&mdev->entity_internal_idx, 1, 0, + GFP_KERNEL); + if (entity->internal_idx < 0) { + spin_unlock(&mdev->lock); + return entity->internal_idx; + } + + mdev->entity_internal_idx_max = + max(mdev->entity_internal_idx_max, entity->internal_idx); + /* Initialize media_gobj embedded at the entity */ media_gobj_create(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); @@ -579,6 +591,8 @@ static void __media_device_unregister_entity(struct media_entity *entity) struct media_interface *intf; unsigned int i; + ida_simple_remove(&mdev->entity_internal_idx, entity->internal_idx); + /* Remove all interface links pointing to this entity */ list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) { list_for_each_entry_safe(link, tmp, &intf->links, list) { @@ -632,6 +646,7 @@ void media_device_init(struct media_device *mdev) INIT_LIST_HEAD(&mdev->links); spin_lock_init(&mdev->lock); mutex_init(&mdev->graph_mutex); + ida_init(&mdev->entity_internal_idx); dev_dbg(mdev->dev, "Media device initialized\n"); } @@ -644,6 +659,8 @@ EXPORT_SYMBOL_GPL(media_device_init); */ void media_device_cleanup(struct media_device *mdev) { + ida_destroy(&mdev->entity_internal_idx); + mdev->entity_internal_idx_max = 0; mutex_destroy(&mdev->graph_mutex); } EXPORT_SYMBOL_GPL(media_device_cleanup); diff --git a/include/media/media-device.h b/include/media/media-device.h index e01bbc427fcd9..2ab4e68038429 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -261,6 +261,7 @@ * in the end provide a way to use driver-specific callbacks. */ +struct ida; struct device; /** @@ -278,6 +279,7 @@ struct device; * @pad_id: Unique ID used on the last pad registered * @link_id: Unique ID used on the last link registered * @intf_devnode_id: Unique ID used on the last interface devnode registered + * @entity_internal_idx: Allocated internal entity indices * @entities: List of registered entities * @interfaces: List of registered interfaces * @pads: List of registered pads @@ -313,6 +315,8 @@ struct media_device { u32 pad_id; u32 link_id; u32 intf_devnode_id; + struct ida entity_internal_idx; + int entity_internal_idx_max; struct list_head entities; struct list_head interfaces; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 81aca1f5a09af..30e8f9fd3efab 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -157,6 +157,8 @@ struct media_entity_operations { * @num_pads: Number of sink and source pads. * @num_links: Total number of links, forward and back, enabled and disabled. * @num_backlinks: Number of backlinks + * @internal_idx: An unique internal entity specific number. The numbers are + * re-used if entities are unregistered or registered again. * @pads: Pads array with the size defined by @num_pads. * @links: List of data links. * @ops: Entity operations. @@ -183,6 +185,7 @@ struct media_entity { u16 num_pads; u16 num_links; u16 num_backlinks; + int internal_idx; struct media_pad *pads; struct list_head links; -- GitLab From c8d54cd53b43c514fbd8d36abf0f2f00f719dd54 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:44:32 -0200 Subject: [PATCH 2577/2855] [media] media: Add an API to manage entity enumerations This is useful in e.g. knowing whether certain operations have already been performed for an entity. The users include the framework itself (for graph walking) and a number of drivers. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 40 ++++++++++ include/media/media-device.h | 15 ++++ include/media/media-entity.h | 141 +++++++++++++++++++++++++++++++++-- 3 files changed, 188 insertions(+), 8 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 13c8ca11f169e..5e3f32f631876 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -70,6 +70,46 @@ static inline const char *intf_type(struct media_interface *intf) } }; +/** + * __media_entity_enum_init - Initialise an entity enumeration + * + * @ent_enum: Entity enumeration to be initialised + * @idx_max: Maximum number of entities in the enumeration + * + * Returns zero on success or a negative error code. + */ +__must_check int __media_entity_enum_init(struct media_entity_enum *ent_enum, + int idx_max) +{ + if (idx_max > MEDIA_ENTITY_ENUM_MAX_ID) { + ent_enum->bmap = kcalloc(DIV_ROUND_UP(idx_max, BITS_PER_LONG), + sizeof(long), GFP_KERNEL); + if (!ent_enum->bmap) + return -ENOMEM; + } else { + ent_enum->bmap = ent_enum->prealloc_bmap; + } + + bitmap_zero(ent_enum->bmap, idx_max); + ent_enum->idx_max = idx_max; + + return 0; +} +EXPORT_SYMBOL_GPL(__media_entity_enum_init); + +/** + * media_entity_enum_cleanup - Release resources of an entity enumeration + * + * @e: Entity enumeration to be released + */ +void media_entity_enum_cleanup(struct media_entity_enum *ent_enum) +{ + if (ent_enum->bmap != ent_enum->prealloc_bmap) + kfree(ent_enum->bmap); + ent_enum->bmap = NULL; +} +EXPORT_SYMBOL_GPL(media_entity_enum_cleanup); + /** * dev_dbg_obj - Prints in debug mode a change on some object * diff --git a/include/media/media-device.h b/include/media/media-device.h index 2ab4e68038429..da4e12ca259c1 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -341,6 +341,21 @@ struct media_device { /* media_devnode to media_device */ #define to_media_device(node) container_of(node, struct media_device, devnode) +/** + * media_entity_enum_init - Initialise an entity enumeration + * + * @e: Entity enumeration to be initialised + * @mdev: The related media device + * + * Returns zero on success or a negative error code. + */ +static inline __must_check int media_entity_enum_init( + struct media_entity_enum *ent_enum, struct media_device *mdev) +{ + return __media_entity_enum_init(ent_enum, + mdev->entity_internal_idx_max + 1); +} + /** * media_device_init() - Initializes a media device element * diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 30e8f9fd3efab..c593dbd3e030d 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -23,7 +23,7 @@ #ifndef _MEDIA_ENTITY_H #define _MEDIA_ENTITY_H -#include +#include #include #include #include @@ -71,6 +71,32 @@ struct media_gobj { struct list_head list; }; +#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 +#define MEDIA_ENTITY_ENUM_MAX_ID 64 + +/* + * The number of pads can't be bigger than the number of entities, + * as the worse-case scenario is to have one entity linked up to + * MEDIA_ENTITY_ENUM_MAX_ID - 1 entities. + */ +#define MEDIA_ENTITY_MAX_PADS (MEDIA_ENTITY_ENUM_MAX_ID - 1) + +/** + * struct media_entity_enum - An enumeration of media entities. + * + * @prealloc_bmap: Pre-allocated space reserved for media entities if the + * total number of entities does not exceed + * MEDIA_ENTITY_ENUM_MAX_ID. + * @bmap: Bit map in which each bit represents one entity at struct + * media_entity->internal_idx. + * @idx_max: Number of bits in bmap + */ +struct media_entity_enum { + DECLARE_BITMAP(prealloc_bmap, MEDIA_ENTITY_ENUM_MAX_ID); + unsigned long *bmap; + int idx_max; +}; + struct media_pipeline { }; @@ -329,15 +355,114 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) } } -#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 -#define MEDIA_ENTITY_ENUM_MAX_ID 64 +__must_check int __media_entity_enum_init(struct media_entity_enum *ent_enum, + int idx_max); +void media_entity_enum_cleanup(struct media_entity_enum *e); -/* - * The number of pads can't be bigger than the number of entities, - * as the worse-case scenario is to have one entity linked up to - * MEDIA_ENTITY_ENUM_MAX_ID - 1 entities. +/** + * media_entity_enum_zero - Clear the entire enum + * + * @e: Entity enumeration to be cleared */ -#define MEDIA_ENTITY_MAX_PADS (MEDIA_ENTITY_ENUM_MAX_ID - 1) +static inline void media_entity_enum_zero(struct media_entity_enum *ent_enum) +{ + bitmap_zero(ent_enum->bmap, ent_enum->idx_max); +} + +/** + * media_entity_enum_set - Mark a single entity in the enum + * + * @e: Entity enumeration + * @entity: Entity to be marked + */ +static inline void media_entity_enum_set(struct media_entity_enum *ent_enum, + struct media_entity *entity) +{ + if (WARN_ON(entity->internal_idx >= ent_enum->idx_max)) + return; + + __set_bit(entity->internal_idx, ent_enum->bmap); +} + +/** + * media_entity_enum_clear - Unmark a single entity in the enum + * + * @e: Entity enumeration + * @entity: Entity to be unmarked + */ +static inline void media_entity_enum_clear(struct media_entity_enum *ent_enum, + struct media_entity *entity) +{ + if (WARN_ON(entity->internal_idx >= ent_enum->idx_max)) + return; + + __clear_bit(entity->internal_idx, ent_enum->bmap); +} + +/** + * media_entity_enum_test - Test whether the entity is marked + * + * @e: Entity enumeration + * @entity: Entity to be tested + * + * Returns true if the entity was marked. + */ +static inline bool media_entity_enum_test(struct media_entity_enum *ent_enum, + struct media_entity *entity) +{ + if (WARN_ON(entity->internal_idx >= ent_enum->idx_max)) + return true; + + return test_bit(entity->internal_idx, ent_enum->bmap); +} + +/** + * media_entity_enum_test - Test whether the entity is marked, and mark it + * + * @e: Entity enumeration + * @entity: Entity to be tested + * + * Returns true if the entity was marked, and mark it before doing so. + */ +static inline bool media_entity_enum_test_and_set( + struct media_entity_enum *ent_enum, struct media_entity *entity) +{ + if (WARN_ON(entity->internal_idx >= ent_enum->idx_max)) + return true; + + return __test_and_set_bit(entity->internal_idx, ent_enum->bmap); +} + +/** + * media_entity_enum_test - Test whether the entire enum is empty + * + * @e: Entity enumeration + * @entity: Entity to be tested + * + * Returns true if the entity was marked. + */ +static inline bool media_entity_enum_empty(struct media_entity_enum *ent_enum) +{ + return bitmap_empty(ent_enum->bmap, ent_enum->idx_max); +} + +/** + * media_entity_enum_intersects - Test whether two enums intersect + * + * @e: First entity enumeration + * @f: Second entity enumeration + * + * Returns true if entity enumerations e and f intersect, otherwise false. + */ +static inline bool media_entity_enum_intersects( + struct media_entity_enum *ent_enum1, + struct media_entity_enum *ent_enum2) +{ + WARN_ON(ent_enum1->idx_max != ent_enum2->idx_max); + + return bitmap_intersects(ent_enum1->bmap, ent_enum2->bmap, + min(ent_enum1->idx_max, ent_enum2->idx_max)); +} struct media_entity_graph { struct { -- GitLab From 82c682905dbc9785f26711e34cb4d16ba3a798d7 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:19 -0200 Subject: [PATCH 2578/2855] [media] media: Move struct media_entity_graph definition up It will be needed in struct media_pipeline shortly. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index c593dbd3e030d..e8ef40c809adc 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -97,6 +97,16 @@ struct media_entity_enum { int idx_max; }; +struct media_entity_graph { + struct { + struct media_entity *entity; + struct list_head *link; + } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH]; + + DECLARE_BITMAP(entities, MEDIA_ENTITY_ENUM_MAX_ID); + int top; +}; + struct media_pipeline { }; @@ -464,16 +474,6 @@ static inline bool media_entity_enum_intersects( min(ent_enum1->idx_max, ent_enum2->idx_max)); } -struct media_entity_graph { - struct { - struct media_entity *entity; - struct list_head *link; - } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH]; - - DECLARE_BITMAP(entities, MEDIA_ENTITY_ENUM_MAX_ID); - int top; -}; - #define gobj_to_entity(gobj) \ container_of(gobj, struct media_entity, graph_obj) -- GitLab From 434257f19ce0a6b635a84882257034ae79d2f274 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:20 -0200 Subject: [PATCH 2579/2855] [media] media: Add KernelDoc documentation for struct media_entity_graph KernelDoc doesn't appear to handle anonymous structs defined inside another gracefully. As the struct is internal to the framework graph walk algorithm, detailed documentation isn't seen very important. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index e8ef40c809adc..edfb6163caa35 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -97,6 +97,15 @@ struct media_entity_enum { int idx_max; }; +/** + * struct media_entity_graph - Media graph traversal state + * + * @stack: Graph traversal stack; the stack contains information + * on the path the media entities to be walked and the + * links through which they were reached. + * @entities: Visited entities + * @top: The top of the stack + */ struct media_entity_graph { struct { struct media_entity *entity; -- GitLab From 5dd8775dc6b480f67be11108d7cd798fba724cab Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:21 -0200 Subject: [PATCH 2580/2855] [media] media: Move media graph state for streamon/off to the pipeline The struct media_entity_graph was allocated in the stack, limiting the number of entities that could be reasonably allocated. Instead, move the struct to struct media_pipeline which is typically allocated using kmalloc() instead. The intent is to keep the enumeration around for later use for the duration of the streaming. As streaming is eventually stopped, an unfortunate memory allocation failure would prevent stopping the streaming. As no memory will need to be allocated, the problem is avoided altogether. Signed-off-by: Sakari Ailus Reviewed-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 16 ++++++++-------- include/media/media-entity.h | 6 ++++++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 5e3f32f631876..83cfde6dcb1ca 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -349,16 +349,16 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_pipeline *pipe) { struct media_device *mdev = entity->graph_obj.mdev; - struct media_entity_graph graph; + struct media_entity_graph *graph = &pipe->graph; struct media_entity *entity_err = entity; struct media_link *link; int ret; mutex_lock(&mdev->graph_mutex); - media_entity_graph_walk_start(&graph, entity); + media_entity_graph_walk_start(graph, entity); - while ((entity = media_entity_graph_walk_next(&graph))) { + while ((entity = media_entity_graph_walk_next(graph))) { DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS); DECLARE_BITMAP(has_no_links, MEDIA_ENTITY_MAX_PADS); @@ -439,9 +439,9 @@ error: * Link validation on graph failed. We revert what we did and * return the error. */ - media_entity_graph_walk_start(&graph, entity_err); + media_entity_graph_walk_start(graph, entity_err); - while ((entity_err = media_entity_graph_walk_next(&graph))) { + while ((entity_err = media_entity_graph_walk_next(graph))) { entity_err->stream_count--; if (entity_err->stream_count == 0) entity_err->pipe = NULL; @@ -463,13 +463,13 @@ EXPORT_SYMBOL_GPL(media_entity_pipeline_start); void media_entity_pipeline_stop(struct media_entity *entity) { struct media_device *mdev = entity->graph_obj.mdev; - struct media_entity_graph graph; + struct media_entity_graph *graph = &entity->pipe->graph; mutex_lock(&mdev->graph_mutex); - media_entity_graph_walk_start(&graph, entity); + media_entity_graph_walk_start(graph, entity); - while ((entity = media_entity_graph_walk_next(&graph))) { + while ((entity = media_entity_graph_walk_next(graph))) { entity->stream_count--; if (entity->stream_count == 0) entity->pipe = NULL; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index edfb6163caa35..4dc3bef72c9db 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -116,7 +116,13 @@ struct media_entity_graph { int top; }; +/* + * struct media_pipeline - Media pipeline related information + * + * @graph: Media graph walk during pipeline start / stop + */ struct media_pipeline { + struct media_entity_graph graph; }; /** -- GitLab From e03d220336dd69292370393f5eee98ac17eda308 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:22 -0200 Subject: [PATCH 2581/2855] [media] media: Amend media graph walk API by init and cleanup functions Add media_entity_graph_walk_init() and media_entity_graph_walk_cleanup() functions in order to dynamically allocate memory for the graph. This is not done in media_entity_graph_walk_start() as there are situations where e.g. correct error handling, that itself may not fail, requires successful graph walk. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 27 +++++++++++++++++++++++++++ include/media/media-entity.h | 17 ++++++++++++----- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 83cfde6dcb1ca..9bf96c71374ee 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -282,6 +282,33 @@ static struct media_entity *stack_pop(struct media_entity_graph *graph) #define link_top(en) ((en)->stack[(en)->top].link) #define stack_top(en) ((en)->stack[(en)->top].entity) +/** + * media_entity_graph_walk_init - Allocate resources for graph walk + * @graph: Media graph structure that will be used to walk the graph + * @mdev: Media device + * + * Reserve resources for graph walk in media device's current + * state. The memory must be released using + * media_entity_graph_walk_free(). + * + * Returns error on failure, zero on success. + */ +__must_check int media_entity_graph_walk_init( + struct media_entity_graph *graph, struct media_device *mdev) +{ + return 0; +} +EXPORT_SYMBOL_GPL(media_entity_graph_walk_init); + +/** + * media_entity_graph_walk_cleanup - Release resources related to graph walking + * @graph: Media graph structure that was used to walk the graph + */ +void media_entity_graph_walk_cleanup(struct media_entity_graph *graph) +{ +} +EXPORT_SYMBOL_GPL(media_entity_graph_walk_cleanup); + void media_entity_graph_walk_start(struct media_entity_graph *graph, struct media_entity *entity) { diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 4dc3bef72c9db..7f028ea849118 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -699,6 +699,10 @@ struct media_pad *media_entity_remote_pad(struct media_pad *pad); */ struct media_entity *media_entity_get(struct media_entity *entity); +__must_check int media_entity_graph_walk_init( + struct media_entity_graph *graph, struct media_device *mdev); +void media_entity_graph_walk_cleanup(struct media_entity_graph *graph); + /** * media_entity_put - Release the reference to the parent module * @@ -715,13 +719,16 @@ void media_entity_put(struct media_entity *entity); * @graph: Media graph structure that will be used to walk the graph * @entity: Starting entity * - * This function initializes the graph traversal structure to walk the entities - * graph starting at the given entity. The traversal structure must not be - * modified by the caller during graph traversal. When done the structure can - * safely be freed. + * Before using this function, media_entity_graph_walk_init() must be + * used to allocate resources used for walking the graph. This + * function initializes the graph traversal structure to walk the + * entities graph starting at the given entity. The traversal + * structure must not be modified by the caller during graph + * traversal. After the graph walk, the resources must be released + * using media_entity_graph_walk_cleanup(). */ void media_entity_graph_walk_start(struct media_entity_graph *graph, - struct media_entity *entity); + struct media_entity *entity); /** * media_entity_graph_walk_next - Get the next entity in the graph -- GitLab From 106b9907c368e32d0b01d8ea682c44ef811e6e36 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 15:32:23 +0200 Subject: [PATCH 2582/2855] [media] media: Use the new media graph walk interface The media graph walk requires initialisation and cleanup soon. Update the users to perform the soon necessary API calls. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 9bf96c71374ee..85af715d2a20e 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -383,7 +383,13 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, mutex_lock(&mdev->graph_mutex); - media_entity_graph_walk_start(graph, entity); + ret = media_entity_graph_walk_init(&pipe->graph, mdev); + if (ret) { + mutex_unlock(&mdev->graph_mutex); + return ret; + } + + media_entity_graph_walk_start(&pipe->graph, entity); while ((entity = media_entity_graph_walk_next(graph))) { DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS); @@ -481,6 +487,8 @@ error: break; } + media_entity_graph_walk_cleanup(graph); + mutex_unlock(&mdev->graph_mutex); return ret; @@ -502,6 +510,8 @@ void media_entity_pipeline_stop(struct media_entity *entity) entity->pipe = NULL; } + media_entity_graph_walk_cleanup(graph); + mutex_unlock(&mdev->graph_mutex); } EXPORT_SYMBOL_GPL(media_entity_pipeline_stop); -- GitLab From 28461451c0fc943fa9271e653483857f20d9b489 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:24 -0200 Subject: [PATCH 2583/2855] [media] v4l: omap3isp: Use the new media graph walk interface The media graph walk requires initialisation and cleanup soon. Update the users to perform the soon necessary API calls. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 63 +++++++++++++--------- drivers/media/platform/omap3isp/isp.h | 4 +- drivers/media/platform/omap3isp/ispvideo.c | 20 ++++++- drivers/media/platform/omap3isp/ispvideo.h | 1 + 4 files changed, 61 insertions(+), 27 deletions(-) diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 942b189c0eca5..581c50e866217 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -683,14 +683,14 @@ static irqreturn_t isp_isr(int irq, void *_isp) * * Return the total number of users of all video device nodes in the pipeline. */ -static int isp_pipeline_pm_use_count(struct media_entity *entity) +static int isp_pipeline_pm_use_count(struct media_entity *entity, + struct media_entity_graph *graph) { - struct media_entity_graph graph; int use = 0; - media_entity_graph_walk_start(&graph, entity); + media_entity_graph_walk_start(graph, entity); - while ((entity = media_entity_graph_walk_next(&graph))) { + while ((entity = media_entity_graph_walk_next(graph))) { if (is_media_entity_v4l2_io(entity)) use += entity->use_count; } @@ -742,27 +742,27 @@ static int isp_pipeline_pm_power_one(struct media_entity *entity, int change) * * Return 0 on success or a negative error code on failure. */ -static int isp_pipeline_pm_power(struct media_entity *entity, int change) +static int isp_pipeline_pm_power(struct media_entity *entity, int change, + struct media_entity_graph *graph) { - struct media_entity_graph graph; struct media_entity *first = entity; int ret = 0; if (!change) return 0; - media_entity_graph_walk_start(&graph, entity); + media_entity_graph_walk_start(graph, entity); - while (!ret && (entity = media_entity_graph_walk_next(&graph))) + while (!ret && (entity = media_entity_graph_walk_next(graph))) if (is_media_entity_v4l2_subdev(entity)) ret = isp_pipeline_pm_power_one(entity, change); if (!ret) - return 0; + return ret; - media_entity_graph_walk_start(&graph, first); + media_entity_graph_walk_start(graph, first); - while ((first = media_entity_graph_walk_next(&graph)) + while ((first = media_entity_graph_walk_next(graph)) && first != entity) if (is_media_entity_v4l2_subdev(first)) isp_pipeline_pm_power_one(first, -change); @@ -782,7 +782,8 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change) * off is assumed to never fail. No failure can occur when the use parameter is * set to 0. */ -int omap3isp_pipeline_pm_use(struct media_entity *entity, int use) +int omap3isp_pipeline_pm_use(struct media_entity *entity, int use, + struct media_entity_graph *graph) { int change = use ? 1 : -1; int ret; @@ -794,7 +795,7 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use) WARN_ON(entity->use_count < 0); /* Apply power change to connected non-nodes. */ - ret = isp_pipeline_pm_power(entity, change); + ret = isp_pipeline_pm_power(entity, change, graph); if (ret < 0) entity->use_count -= change; @@ -820,35 +821,49 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use) static int isp_pipeline_link_notify(struct media_link *link, u32 flags, unsigned int notification) { + struct media_entity_graph *graph = + &container_of(link->graph_obj.mdev, struct isp_device, + media_dev)->pm_count_graph; struct media_entity *source = link->source->entity; struct media_entity *sink = link->sink->entity; - int source_use = isp_pipeline_pm_use_count(source); - int sink_use = isp_pipeline_pm_use_count(sink); - int ret; + int source_use; + int sink_use; + int ret = 0; + + if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) { + ret = media_entity_graph_walk_init(graph, + link->graph_obj.mdev); + if (ret) + return ret; + } + + source_use = isp_pipeline_pm_use_count(source, graph); + sink_use = isp_pipeline_pm_use_count(sink, graph); if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH && !(flags & MEDIA_LNK_FL_ENABLED)) { /* Powering off entities is assumed to never fail. */ - isp_pipeline_pm_power(source, -sink_use); - isp_pipeline_pm_power(sink, -source_use); + isp_pipeline_pm_power(source, -sink_use, graph); + isp_pipeline_pm_power(sink, -source_use, graph); return 0; } if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH && (flags & MEDIA_LNK_FL_ENABLED)) { - ret = isp_pipeline_pm_power(source, sink_use); + ret = isp_pipeline_pm_power(source, sink_use, graph); if (ret < 0) return ret; - ret = isp_pipeline_pm_power(sink, source_use); + ret = isp_pipeline_pm_power(sink, source_use, graph); if (ret < 0) - isp_pipeline_pm_power(source, -sink_use); - - return ret; + isp_pipeline_pm_power(source, -sink_use, graph); } - return 0; + if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH) + media_entity_graph_walk_cleanup(graph); + + return ret; } /* ----------------------------------------------------------------------------- diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h index 5acc2e6511a55..b6f81f20aa733 100644 --- a/drivers/media/platform/omap3isp/isp.h +++ b/drivers/media/platform/omap3isp/isp.h @@ -176,6 +176,7 @@ struct isp_device { struct v4l2_device v4l2_dev; struct v4l2_async_notifier notifier; struct media_device media_dev; + struct media_entity_graph pm_count_graph; struct device *dev; u32 revision; @@ -265,7 +266,8 @@ void omap3isp_subclk_enable(struct isp_device *isp, void omap3isp_subclk_disable(struct isp_device *isp, enum isp_subclk_resource res); -int omap3isp_pipeline_pm_use(struct media_entity *entity, int use); +int omap3isp_pipeline_pm_use(struct media_entity *entity, int use, + struct media_entity_graph *graph); int omap3isp_register_entities(struct platform_device *pdev, struct v4l2_device *v4l2_dev); diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index 1240b06202f04..33123f1121514 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -227,8 +227,15 @@ static int isp_video_get_graph_data(struct isp_video *video, struct media_entity *entity = &video->video.entity; struct media_device *mdev = entity->graph_obj.mdev; struct isp_video *far_end = NULL; + int ret; mutex_lock(&mdev->graph_mutex); + ret = media_entity_graph_walk_init(&graph, entity->graph_obj.mdev); + if (ret) { + mutex_unlock(&mdev->graph_mutex); + return ret; + } + media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { @@ -252,6 +259,8 @@ static int isp_video_get_graph_data(struct isp_video *video, mutex_unlock(&mdev->graph_mutex); + media_entity_graph_walk_cleanup(&graph); + if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { pipe->input = far_end; pipe->output = video; @@ -1244,7 +1253,12 @@ static int isp_video_open(struct file *file) goto done; } - ret = omap3isp_pipeline_pm_use(&video->video.entity, 1); + ret = media_entity_graph_walk_init(&handle->graph, + &video->isp->media_dev); + if (ret) + goto done; + + ret = omap3isp_pipeline_pm_use(&video->video.entity, 1, &handle->graph); if (ret < 0) { omap3isp_put(video->isp); goto done; @@ -1275,6 +1289,7 @@ static int isp_video_open(struct file *file) done: if (ret < 0) { v4l2_fh_del(&handle->vfh); + media_entity_graph_walk_cleanup(&handle->graph); kfree(handle); } @@ -1294,7 +1309,8 @@ static int isp_video_release(struct file *file) vb2_queue_release(&handle->queue); mutex_unlock(&video->queue_lock); - omap3isp_pipeline_pm_use(&video->video.entity, 0); + omap3isp_pipeline_pm_use(&video->video.entity, 0, &handle->graph); + media_entity_graph_walk_cleanup(&handle->graph); /* Release the file handle. */ v4l2_fh_del(vfh); diff --git a/drivers/media/platform/omap3isp/ispvideo.h b/drivers/media/platform/omap3isp/ispvideo.h index bcf0e0acc8f38..a340165732db3 100644 --- a/drivers/media/platform/omap3isp/ispvideo.h +++ b/drivers/media/platform/omap3isp/ispvideo.h @@ -189,6 +189,7 @@ struct isp_video_fh { struct vb2_queue queue; struct v4l2_format format; struct v4l2_fract timeperframe; + struct media_entity_graph graph; }; #define to_isp_video_fh(fh) container_of(fh, struct isp_video_fh, vfh) -- GitLab From fd7e5309a5324c243cb285257a2e5e35d9bcaa56 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 15:32:25 +0200 Subject: [PATCH 2584/2855] [media] v4l: exynos4-is: Use the new media graph walk interface The media graph walk requires initialisation and cleanup soon. Update the users to perform the soon necessary API calls. Signed-off-by: Sakari Ailus Cc: Javier Martinez Canillas Cc: Kamil Debski Cc: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/media-dev.c | 31 ++++++++++++------- drivers/media/platform/exynos4-is/media-dev.h | 1 + 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 27663dd452949..f6b391e795c65 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -1046,10 +1046,10 @@ static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable) } /* Locking: called with entity->graph_obj.mdev->graph_mutex mutex held. */ -static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable) +static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable, + struct media_entity_graph *graph) { struct media_entity *entity_err = entity; - struct media_entity_graph graph; int ret; /* @@ -1058,9 +1058,9 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable) * through active links. This is needed as we cannot power on/off the * subdevs in random order. */ - media_entity_graph_walk_start(&graph, entity); + media_entity_graph_walk_start(graph, entity); - while ((entity = media_entity_graph_walk_next(&graph))) { + while ((entity = media_entity_graph_walk_next(graph))) { if (!is_media_entity_v4l2_io(entity)) continue; @@ -1071,10 +1071,11 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable) } return 0; - err: - media_entity_graph_walk_start(&graph, entity_err); - while ((entity_err = media_entity_graph_walk_next(&graph))) { +err: + media_entity_graph_walk_start(graph, entity_err); + + while ((entity_err = media_entity_graph_walk_next(graph))) { if (!is_media_entity_v4l2_io(entity_err)) continue; @@ -1090,21 +1091,29 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable) static int fimc_md_link_notify(struct media_link *link, unsigned int flags, unsigned int notification) { + struct media_entity_graph *graph = + &container_of(link->graph_obj.mdev, struct fimc_md, + media_dev)->link_setup_graph; struct media_entity *sink = link->sink->entity; int ret = 0; /* Before link disconnection */ if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) { + ret = media_entity_graph_walk_init(graph, + link->graph_obj.mdev); + if (ret) + return ret; if (!(flags & MEDIA_LNK_FL_ENABLED)) - ret = __fimc_md_modify_pipelines(sink, false); + ret = __fimc_md_modify_pipelines(sink, false, graph); #if 0 else /* TODO: Link state change validation */ #endif /* After link activation */ - } else if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH && - (link->flags & MEDIA_LNK_FL_ENABLED)) { - ret = __fimc_md_modify_pipelines(sink, true); + } else if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH) { + if (link->flags & MEDIA_LNK_FL_ENABLED) + ret = __fimc_md_modify_pipelines(sink, true, graph); + media_entity_graph_walk_cleanup(graph); } return ret ? -EPIPE : 0; diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h index e8845e1f5aabe..ed122cb2dd741 100644 --- a/drivers/media/platform/exynos4-is/media-dev.h +++ b/drivers/media/platform/exynos4-is/media-dev.h @@ -154,6 +154,7 @@ struct fimc_md { bool user_subdev_api; spinlock_t slock; struct list_head pipelines; + struct media_entity_graph link_setup_graph; }; static inline -- GitLab From 08613c549ff5ac98d04d9dd28a4ffafa3918e2ca Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:26 -0200 Subject: [PATCH 2585/2855] [media] v4l: xilinx: Use the new media graph walk interface The media graph walk requires initialisation and cleanup soon. Update the users to perform the soon necessary API calls. Signed-off-by: Sakari Ailus Cc: Hyun Kwon Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/xilinx/xilinx-dma.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index 0181ff402a5ab..7f6898b13cacd 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -182,10 +182,17 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe, struct media_device *mdev = entity->graph_obj.mdev; unsigned int num_inputs = 0; unsigned int num_outputs = 0; + int ret; mutex_lock(&mdev->graph_mutex); /* Walk the graph to locate the video nodes. */ + ret = media_entity_graph_walk_init(&graph, entity->graph_obj.mdev); + if (ret) { + mutex_unlock(&mdev->graph_mutex); + return ret; + } + media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { @@ -206,6 +213,8 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe, mutex_unlock(&mdev->graph_mutex); + media_entity_graph_walk_cleanup(&graph); + /* We need exactly one output and zero or one input. */ if (num_outputs != 1 || num_inputs > 1) return -EPIPE; -- GitLab From c1a5f1bc0b7a585efaeda40c1eb8f5f4bd9d328d Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 15:32:27 +0200 Subject: [PATCH 2586/2855] [media] v4l: vsp1: Use the new media graph walk interface The media graph walk requires initialisation and cleanup soon. Update the users to perform the soon necessary API calls. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_video.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index e3304303dce3f..a6b1bd1225efe 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -386,6 +386,12 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe, mutex_lock(&mdev->graph_mutex); /* Walk the graph to locate the entities and video nodes. */ + ret = media_entity_graph_walk_init(&graph, mdev); + if (ret) { + mutex_unlock(&mdev->graph_mutex); + return ret; + } + media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { @@ -419,6 +425,8 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe, mutex_unlock(&mdev->graph_mutex); + media_entity_graph_walk_cleanup(&graph); + /* We need one output and at least one input. */ if (pipe->num_inputs == 0 || !pipe->output) { ret = -EPIPE; -- GitLab From 29d8da02d13020a18929a30692d454bd863d4207 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:28 -0200 Subject: [PATCH 2587/2855] [media] media: Use entity enums in graph walk This will also mean that the necessary graph related data structures will be allocated dynamically, removing the need for maximum ID checks. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 16 ++++++---------- include/media/media-entity.h | 4 ++-- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 85af715d2a20e..86a8396f6ec28 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -296,7 +296,7 @@ static struct media_entity *stack_pop(struct media_entity_graph *graph) __must_check int media_entity_graph_walk_init( struct media_entity_graph *graph, struct media_device *mdev) { - return 0; + return media_entity_enum_init(&graph->ent_enum, mdev); } EXPORT_SYMBOL_GPL(media_entity_graph_walk_init); @@ -306,20 +306,18 @@ EXPORT_SYMBOL_GPL(media_entity_graph_walk_init); */ void media_entity_graph_walk_cleanup(struct media_entity_graph *graph) { + media_entity_enum_cleanup(&graph->ent_enum); } EXPORT_SYMBOL_GPL(media_entity_graph_walk_cleanup); void media_entity_graph_walk_start(struct media_entity_graph *graph, struct media_entity *entity) { + media_entity_enum_zero(&graph->ent_enum); + media_entity_enum_set(&graph->ent_enum, entity); + graph->top = 0; graph->stack[graph->top].entity = NULL; - bitmap_zero(graph->entities, MEDIA_ENTITY_ENUM_MAX_ID); - - if (WARN_ON(media_entity_id(entity) >= MEDIA_ENTITY_ENUM_MAX_ID)) - return; - - __set_bit(media_entity_id(entity), graph->entities); stack_push(graph, entity); } EXPORT_SYMBOL_GPL(media_entity_graph_walk_start); @@ -350,11 +348,9 @@ media_entity_graph_walk_next(struct media_entity_graph *graph) /* Get the entity in the other end of the link . */ next = media_entity_other(entity, link); - if (WARN_ON(media_entity_id(next) >= MEDIA_ENTITY_ENUM_MAX_ID)) - return NULL; /* Has the entity already been visited? */ - if (__test_and_set_bit(media_entity_id(next), graph->entities)) { + if (media_entity_enum_test_and_set(&graph->ent_enum, next)) { link_top(graph) = link_top(graph)->next; continue; } diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 7f028ea849118..a53acb099c16f 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -103,7 +103,7 @@ struct media_entity_enum { * @stack: Graph traversal stack; the stack contains information * on the path the media entities to be walked and the * links through which they were reached. - * @entities: Visited entities + * @ent_enum: Visited entities * @top: The top of the stack */ struct media_entity_graph { @@ -112,7 +112,7 @@ struct media_entity_graph { struct list_head *link; } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH]; - DECLARE_BITMAP(entities, MEDIA_ENTITY_ENUM_MAX_ID); + struct media_entity_enum ent_enum; int top; }; -- GitLab From 74a4133079f739eb2f4604263fdb974ce10120a8 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:29 -0200 Subject: [PATCH 2588/2855] [media] media: Keep using the same graph walk object for a given pipeline Initialise a given graph walk object once, and then keep using it whilst the same pipeline is running. Once the pipeline is stopped, release the graph walk object. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 17 +++++++++++------ include/media/media-entity.h | 4 +++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 86a8396f6ec28..3cad525c2ac1f 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -379,10 +379,10 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, mutex_lock(&mdev->graph_mutex); - ret = media_entity_graph_walk_init(&pipe->graph, mdev); - if (ret) { - mutex_unlock(&mdev->graph_mutex); - return ret; + if (!pipe->streaming_count++) { + ret = media_entity_graph_walk_init(&pipe->graph, mdev); + if (ret) + goto error_graph_walk_start; } media_entity_graph_walk_start(&pipe->graph, entity); @@ -483,7 +483,9 @@ error: break; } - media_entity_graph_walk_cleanup(graph); +error_graph_walk_start: + if (!--pipe->streaming_count) + media_entity_graph_walk_cleanup(graph); mutex_unlock(&mdev->graph_mutex); @@ -495,9 +497,11 @@ void media_entity_pipeline_stop(struct media_entity *entity) { struct media_device *mdev = entity->graph_obj.mdev; struct media_entity_graph *graph = &entity->pipe->graph; + struct media_pipeline *pipe = entity->pipe; mutex_lock(&mdev->graph_mutex); + WARN_ON(!pipe->streaming_count); media_entity_graph_walk_start(graph, entity); while ((entity = media_entity_graph_walk_next(graph))) { @@ -506,7 +510,8 @@ void media_entity_pipeline_stop(struct media_entity *entity) entity->pipe = NULL; } - media_entity_graph_walk_cleanup(graph); + if (!--pipe->streaming_count) + media_entity_graph_walk_cleanup(graph); mutex_unlock(&mdev->graph_mutex); } diff --git a/include/media/media-entity.h b/include/media/media-entity.h index a53acb099c16f..a47a7c8a93cfd 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -119,9 +119,11 @@ struct media_entity_graph { /* * struct media_pipeline - Media pipeline related information * - * @graph: Media graph walk during pipeline start / stop + * @streaming_count: Streaming start count - streaming stop count + * @graph: Media graph walk during pipeline start / stop */ struct media_pipeline { + int streaming_count; struct media_entity_graph graph; }; -- GitLab From 17d3d4058a61329a6a4384054da6a57c65c7e8ba Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:30 -0200 Subject: [PATCH 2589/2855] [media] v4l: omap3isp: Use media entity enumeration interface Instead of using a bitmap directly in a driver, use the new media entity enumeration interface to perform the same. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 21 +++++++++++++-------- drivers/media/platform/omap3isp/isp.h | 5 +++-- drivers/media/platform/omap3isp/ispccdc.c | 2 +- drivers/media/platform/omap3isp/ispvideo.c | 20 ++++++++++++++------ drivers/media/platform/omap3isp/ispvideo.h | 4 ++-- 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 581c50e866217..0bcfa553c1aa2 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -896,7 +896,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe, * starting entities if the pipeline won't start anyway (those entities * would then likely fail to stop, making the problem worse). */ - if (pipe->entities & isp->crashed) + if (media_entity_enum_intersects(&pipe->ent_enum, &isp->crashed)) return -EIO; spin_lock_irqsave(&pipe->lock, flags); @@ -989,7 +989,6 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) struct v4l2_subdev *subdev; int failure = 0; int ret; - u32 id; /* * We need to stop all the modules after CCDC first or they'll @@ -1041,10 +1040,9 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) if (ret) { dev_info(isp->dev, "Unable to stop %s\n", subdev->name); isp->stop_failure = true; - if (subdev == &isp->isp_prev.subdev) { - id = media_entity_id(&subdev->entity); - isp->crashed |= 1U << id; - } + if (subdev == &isp->isp_prev.subdev) + media_entity_enum_set(&isp->crashed, + &subdev->entity); failure = -ETIMEDOUT; } } @@ -1250,7 +1248,7 @@ static int isp_reset(struct isp_device *isp) } isp->stop_failure = false; - isp->crashed = 0; + media_entity_enum_zero(&isp->crashed); return 0; } @@ -1661,7 +1659,8 @@ static void __omap3isp_put(struct isp_device *isp, bool save_ctx) /* Reset the ISP if an entity has failed to stop. This is the * only way to recover from such conditions. */ - if (isp->crashed || isp->stop_failure) + if (!media_entity_enum_empty(&isp->crashed) || + isp->stop_failure) isp_reset(isp); isp_disable_clocks(isp); } @@ -2219,6 +2218,8 @@ static int isp_remove(struct platform_device *pdev) isp_detach_iommu(isp); __omap3isp_put(isp, false); + media_entity_enum_cleanup(&isp->crashed); + return 0; } @@ -2366,6 +2367,10 @@ static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async) struct isp_bus_cfg *bus; int ret; + ret = media_entity_enum_init(&isp->crashed, &isp->media_dev); + if (ret) + return ret; + list_for_each_entry(sd, &v4l2_dev->subdevs, list) { /* Only try to link entities whose interface was set on bound */ if (sd->host_priv) { diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h index b6f81f20aa733..49b7f71ac9689 100644 --- a/drivers/media/platform/omap3isp/isp.h +++ b/drivers/media/platform/omap3isp/isp.h @@ -17,6 +17,7 @@ #ifndef OMAP3_ISP_CORE_H #define OMAP3_ISP_CORE_H +#include #include #include #include @@ -152,7 +153,7 @@ struct isp_xclk { * @stat_lock: Spinlock for handling statistics * @isp_mutex: Mutex for serializing requests to ISP. * @stop_failure: Indicates that an entity failed to stop. - * @crashed: Bitmask of crashed entities (indexed by entity ID) + * @crashed: Crashed ent_enum * @has_context: Context has been saved at least once and can be restored. * @ref_count: Reference count for handling multiple ISP requests. * @cam_ick: Pointer to camera interface clock structure. @@ -195,7 +196,7 @@ struct isp_device { spinlock_t stat_lock; /* common lock for statistic drivers */ struct mutex isp_mutex; /* For handling ref_count field */ bool stop_failure; - u32 crashed; + struct media_entity_enum crashed; int has_context; int ref_count; unsigned int autoidle; diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 4eaf926d60734..bb3974c98e37e 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -1608,7 +1608,7 @@ static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc) /* Wait for the CCDC to become idle. */ if (ccdc_sbl_wait_idle(ccdc, 1000)) { dev_info(isp->dev, "CCDC won't become idle!\n"); - isp->crashed |= 1U << media_entity_id(&ccdc->subdev.entity); + media_entity_enum_set(&isp->crashed, &ccdc->subdev.entity); omap3isp_pipeline_cancel_stream(pipe); return 0; } diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index 33123f1121514..994dfc0813f6b 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -241,7 +241,7 @@ static int isp_video_get_graph_data(struct isp_video *video, while ((entity = media_entity_graph_walk_next(&graph))) { struct isp_video *__video; - pipe->entities |= 1 << media_entity_id(entity); + media_entity_enum_set(&pipe->ent_enum, entity); if (far_end != NULL) continue; @@ -901,7 +901,6 @@ static int isp_video_check_external_subdevs(struct isp_video *video, struct v4l2_ext_control ctrl; unsigned int i; int ret; - u32 id; /* Memory-to-memory pipelines have no external subdev. */ if (pipe->input != NULL) @@ -909,7 +908,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video, for (i = 0; i < ARRAY_SIZE(ents); i++) { /* Is the entity part of the pipeline? */ - if (!(pipe->entities & (1 << media_entity_id(ents[i])))) + if (!media_entity_enum_test(&pipe->ent_enum, ents[i])) continue; /* ISP entities have always sink pad == 0. Find source. */ @@ -961,8 +960,8 @@ static int isp_video_check_external_subdevs(struct isp_video *video, pipe->external_rate = ctrl.value64; - id = media_entity_id(&isp->isp_ccdc.subdev.entity); - if (pipe->entities & (1 << id)) { + if (media_entity_enum_test(&pipe->ent_enum, + &isp->isp_ccdc.subdev.entity)) { unsigned int rate = UINT_MAX; /* * Check that maximum allowed CCDC pixel rate isn't @@ -1028,7 +1027,9 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) pipe = video->video.entity.pipe ? to_isp_pipeline(&video->video.entity) : &video->pipe; - pipe->entities = 0; + ret = media_entity_enum_init(&pipe->ent_enum, &video->isp->media_dev); + if (ret) + goto err_enum_init; /* TODO: Implement PM QoS */ pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]); @@ -1102,6 +1103,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) } mutex_unlock(&video->stream_lock); + return 0; err_set_stream: @@ -1122,7 +1124,11 @@ err_pipeline_start: INIT_LIST_HEAD(&video->dmaqueue); video->queue = NULL; + media_entity_enum_cleanup(&pipe->ent_enum); + +err_enum_init: mutex_unlock(&video->stream_lock); + return ret; } @@ -1174,6 +1180,8 @@ isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) /* TODO: Implement PM QoS */ media_entity_pipeline_stop(&video->video.entity); + media_entity_enum_cleanup(&pipe->ent_enum); + done: mutex_unlock(&video->stream_lock); return 0; diff --git a/drivers/media/platform/omap3isp/ispvideo.h b/drivers/media/platform/omap3isp/ispvideo.h index a340165732db3..156429878d646 100644 --- a/drivers/media/platform/omap3isp/ispvideo.h +++ b/drivers/media/platform/omap3isp/ispvideo.h @@ -80,7 +80,7 @@ enum isp_pipeline_state { * struct isp_pipeline - An ISP hardware pipeline * @field: The field being processed by the pipeline * @error: A hardware error occurred during capture - * @entities: Bitmask of entities in the pipeline (indexed by entity ID) + * @ent_enum: Entities in the pipeline */ struct isp_pipeline { struct media_pipeline pipe; @@ -89,7 +89,7 @@ struct isp_pipeline { enum isp_pipeline_stream_state stream_state; struct isp_video *input; struct isp_video *output; - u32 entities; + struct media_entity_enum ent_enum; unsigned long l3_ick; unsigned int max_rate; enum v4l2_field field; -- GitLab From 54b5a749b4f3010b3b657507b8ef1eee3a100b09 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:31 -0200 Subject: [PATCH 2590/2855] [media] v4l: vsp1: Use media entity enumeration interface Instead of using a bitmap directly in a driver, use the new media entity enumeration interface to perform the same. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_video.c | 45 ++++++++++++++++-------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index a6b1bd1225efe..637d0d6f79fba 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -282,24 +282,35 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe, struct vsp1_rwpf *output) { struct vsp1_entity *entity; - unsigned int entities = 0; + struct media_entity_enum ent_enum; struct media_pad *pad; + int rval; bool bru_found = false; input->location.left = 0; input->location.top = 0; + rval = media_entity_enum_init( + &ent_enum, input->entity.pads[RWPF_PAD_SOURCE].graph_obj.mdev); + if (rval) + return rval; + pad = media_entity_remote_pad(&input->entity.pads[RWPF_PAD_SOURCE]); while (1) { - if (pad == NULL) - return -EPIPE; + if (pad == NULL) { + rval = -EPIPE; + goto out; + } /* We've reached a video node, that shouldn't have happened. */ - if (!is_media_entity_v4l2_subdev(pad->entity)) - return -EPIPE; + if (!is_media_entity_v4l2_subdev(pad->entity)) { + rval = -EPIPE; + goto out; + } - entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity)); + entity = to_vsp1_entity( + media_entity_to_v4l2_subdev(pad->entity)); /* A BRU is present in the pipeline, store the compose rectangle * location in the input RPF for use when configuring the RPF. @@ -322,15 +333,18 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe, break; /* Ensure the branch has no loop. */ - if (entities & (1 << media_entity_id(&entity->subdev.entity))) - return -EPIPE; - - entities |= 1 << media_entity_id(&entity->subdev.entity); + if (media_entity_enum_test_and_set(&ent_enum, + &entity->subdev.entity)) { + rval = -EPIPE; + goto out; + } /* UDS can't be chained. */ if (entity->type == VSP1_ENTITY_UDS) { - if (pipe->uds) - return -EPIPE; + if (pipe->uds) { + rval = -EPIPE; + goto out; + } pipe->uds = entity; pipe->uds_input = bru_found ? pipe->bru @@ -348,9 +362,12 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe, /* The last entity must be the output WPF. */ if (entity != &output->entity) - return -EPIPE; + rval = -EPIPE; - return 0; +out: + media_entity_enum_cleanup(&ent_enum); + + return rval; } static void __vsp1_pipeline_cleanup(struct vsp1_pipeline *pipe) -- GitLab From ad92b5cf35adc2d3ec0116f4744561d5405a0db7 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:32 -0200 Subject: [PATCH 2591/2855] [media] staging: v4l: omap4iss: Fix sub-device power management code The same bug was present in the omap4iss driver as was in the omap3isp driver. The code got copied to the omap4iss driver while broken. Fix the omap4iss driver as well. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/omap4iss/iss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index 7209b92b1f865..2f7a9bb0a9e78 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -533,14 +533,14 @@ static int iss_pipeline_link_notify(struct media_link *link, u32 flags, int ret; if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH && - !(link->flags & MEDIA_LNK_FL_ENABLED)) { + !(flags & MEDIA_LNK_FL_ENABLED)) { /* Powering off entities is assumed to never fail. */ iss_pipeline_pm_power(source, -sink_use); iss_pipeline_pm_power(sink, -source_use); return 0; } - if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH && + if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH && (flags & MEDIA_LNK_FL_ENABLED)) { ret = iss_pipeline_pm_power(source, sink_use); if (ret < 0) -- GitLab From 6246b2a7ad1ffab5a712c38005b668f3e4ca2825 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:33 -0200 Subject: [PATCH 2592/2855] [media] staging: v4l: omap4iss: Use media entity enumeration interface Instead of using a bitmap directly in a driver, use the new media entity enumeration interface to perform the same. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/omap4iss/iss.c | 15 ++++++++++---- drivers/staging/media/omap4iss/iss.h | 4 ++-- drivers/staging/media/omap4iss/iss_video.c | 23 +++++++++++++++------- drivers/staging/media/omap4iss/iss_video.h | 4 ++-- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index 2f7a9bb0a9e78..6f57f41511d5d 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -606,7 +606,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe, * crashed. Mark it as such, the ISS will be reset when * applications will release it. */ - iss->crashed |= 1U << media_entity_id(&subdev->entity); + media_entity_enum_set(&iss->crashed, &subdev->entity); failure = -ETIMEDOUT; } } @@ -641,7 +641,7 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe, * pipeline won't start anyway (those entities would then likely fail to * stop, making the problem worse). */ - if (pipe->entities & iss->crashed) + if (media_entity_enum_intersects(&pipe->ent_enum, &iss->crashed)) return -EIO; spin_lock_irqsave(&pipe->lock, flags); @@ -761,7 +761,8 @@ static int iss_reset(struct iss_device *iss) return -ETIMEDOUT; } - iss->crashed = 0; + media_entity_enum_zero(&iss->crashed); + return 0; } @@ -1090,7 +1091,7 @@ void omap4iss_put(struct iss_device *iss) * be worth investigating whether resetting the ISP only can't * fix the problem in some cases. */ - if (iss->crashed) + if (!media_entity_enum_empty(&iss->crashed)) iss_reset(iss); iss_disable_clocks(iss); } @@ -1491,6 +1492,10 @@ static int iss_probe(struct platform_device *pdev) if (ret < 0) goto error_modules; + ret = media_entity_enum_init(&iss->crashed, &iss->media_dev); + if (ret) + goto error_entities; + ret = iss_create_links(iss); if (ret < 0) goto error_entities; @@ -1501,6 +1506,7 @@ static int iss_probe(struct platform_device *pdev) error_entities: iss_unregister_entities(iss); + media_entity_enum_cleanup(&iss->crashed); error_modules: iss_cleanup_modules(iss); error_iss: @@ -1518,6 +1524,7 @@ static int iss_remove(struct platform_device *pdev) struct iss_device *iss = platform_get_drvdata(pdev); iss_unregister_entities(iss); + media_entity_enum_cleanup(&iss->crashed); iss_cleanup_modules(iss); return 0; diff --git a/drivers/staging/media/omap4iss/iss.h b/drivers/staging/media/omap4iss/iss.h index 5929357fe6879..693a8f112960b 100644 --- a/drivers/staging/media/omap4iss/iss.h +++ b/drivers/staging/media/omap4iss/iss.h @@ -82,7 +82,7 @@ struct iss_reg { /* * struct iss_device - ISS device structure. * @syscon: Regmap for the syscon register space - * @crashed: Bitmask of crashed entities (indexed by entity ID) + * @crashed: Crashed entities */ struct iss_device { struct v4l2_device v4l2_dev; @@ -101,7 +101,7 @@ struct iss_device { u64 raw_dmamask; struct mutex iss_mutex; /* For handling ref_count field */ - unsigned int crashed; + struct media_entity_enum crashed; int has_context; int ref_count; diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index 8c6af412bc161..5f8201f861bc3 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -749,7 +749,7 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) struct iss_video_fh *vfh = to_iss_video_fh(fh); struct iss_video *video = video_drvdata(file); struct media_entity_graph graph; - struct media_entity *entity; + struct media_entity *entity = &video->video.entity; enum iss_pipeline_state state; struct iss_pipeline *pipe; struct iss_video *far_end; @@ -764,24 +764,26 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) /* Start streaming on the pipeline. No link touching an entity in the * pipeline can be activated or deactivated once streaming is started. */ - pipe = video->video.entity.pipe - ? to_iss_pipeline(&video->video.entity) : &video->pipe; + pipe = entity->pipe + ? to_iss_pipeline(entity) : &video->pipe; pipe->external = NULL; pipe->external_rate = 0; pipe->external_bpp = 0; - pipe->entities = 0; + + ret = media_entity_enum_init(&pipe->ent_enum, entity->graph_obj.mdev); + if (ret) + goto err_enum_init; if (video->iss->pdata->set_constraints) video->iss->pdata->set_constraints(video->iss, true); - ret = media_entity_pipeline_start(&video->video.entity, &pipe->pipe); + ret = media_entity_pipeline_start(entity, &pipe->pipe); if (ret < 0) goto err_media_entity_pipeline_start; - entity = &video->video.entity; media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) - pipe->entities |= 1 << media_entity_id(entity); + media_entity_enum_set(&pipe->ent_enum, entity); /* Verify that the currently configured format matches the output of * the connected subdev. @@ -852,6 +854,7 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) } mutex_unlock(&video->stream_lock); + return 0; err_omap4iss_set_stream: @@ -863,7 +866,11 @@ err_media_entity_pipeline_start: video->iss->pdata->set_constraints(video->iss, false); video->queue = NULL; + media_entity_enum_cleanup(&pipe->ent_enum); + +err_enum_init: mutex_unlock(&video->stream_lock); + return ret; } @@ -901,6 +908,8 @@ iss_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) vb2_streamoff(&vfh->queue, type); video->queue = NULL; + media_entity_enum_cleanup(&pipe->ent_enum); + if (video->iss->pdata->set_constraints) video->iss->pdata->set_constraints(video->iss, false); media_entity_pipeline_stop(&video->video.entity); diff --git a/drivers/staging/media/omap4iss/iss_video.h b/drivers/staging/media/omap4iss/iss_video.h index 41532eda1277f..c8bd2958a3f86 100644 --- a/drivers/staging/media/omap4iss/iss_video.h +++ b/drivers/staging/media/omap4iss/iss_video.h @@ -77,7 +77,7 @@ enum iss_pipeline_state { /* * struct iss_pipeline - An OMAP4 ISS hardware pipeline - * @entities: Bitmask of entities in the pipeline (indexed by entity ID) + * @ent_enum: Entities in the pipeline * @error: A hardware error occurred during capture */ struct iss_pipeline { @@ -87,7 +87,7 @@ struct iss_pipeline { enum iss_pipeline_stream_state stream_state; struct iss_video *input; struct iss_video *output; - unsigned int entities; + struct media_entity_enum ent_enum; atomic_t frame_number; bool do_propagation; /* of frame number */ bool error; -- GitLab From 809fe79a5f59621202a30c248349a50765b98e1c Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:34 -0200 Subject: [PATCH 2593/2855] [media] staging: v4l: omap4iss: Use the new media graph walk interface The media graph walk requires initialisation and cleanup soon. Update the users to perform the soon necessary API calls. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/omap4iss/iss.c | 59 ++++++++++++++-------- drivers/staging/media/omap4iss/iss.h | 4 +- drivers/staging/media/omap4iss/iss_video.c | 33 ++++++++++-- drivers/staging/media/omap4iss/iss_video.h | 1 + 4 files changed, 70 insertions(+), 27 deletions(-) diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index 6f57f41511d5d..30b473cfb0201 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -389,14 +389,14 @@ static irqreturn_t iss_isr(int irq, void *_iss) * * Return the total number of users of all video device nodes in the pipeline. */ -static int iss_pipeline_pm_use_count(struct media_entity *entity) +static int iss_pipeline_pm_use_count(struct media_entity *entity, + struct media_entity_graph *graph) { - struct media_entity_graph graph; int use = 0; - media_entity_graph_walk_start(&graph, entity); + media_entity_graph_walk_start(graph, entity); - while ((entity = media_entity_graph_walk_next(&graph))) { + while ((entity = media_entity_graph_walk_next(graph))) { if (is_media_entity_v4l2_io(entity)) use += entity->use_count; } @@ -449,27 +449,27 @@ static int iss_pipeline_pm_power_one(struct media_entity *entity, int change) * * Return 0 on success or a negative error code on failure. */ -static int iss_pipeline_pm_power(struct media_entity *entity, int change) +static int iss_pipeline_pm_power(struct media_entity *entity, int change, + struct media_entity_graph *graph) { - struct media_entity_graph graph; struct media_entity *first = entity; int ret = 0; if (!change) return 0; - media_entity_graph_walk_start(&graph, entity); + media_entity_graph_walk_start(graph, entity); - while (!ret && (entity = media_entity_graph_walk_next(&graph))) + while (!ret && (entity = media_entity_graph_walk_next(graph))) if (is_media_entity_v4l2_subdev(entity)) ret = iss_pipeline_pm_power_one(entity, change); if (!ret) return 0; - media_entity_graph_walk_start(&graph, first); + media_entity_graph_walk_start(graph, first); - while ((first = media_entity_graph_walk_next(&graph)) && + while ((first = media_entity_graph_walk_next(graph)) && first != entity) if (is_media_entity_v4l2_subdev(first)) iss_pipeline_pm_power_one(first, -change); @@ -489,7 +489,8 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change) * off is assumed to never fail. No failure can occur when the use parameter is * set to 0. */ -int omap4iss_pipeline_pm_use(struct media_entity *entity, int use) +int omap4iss_pipeline_pm_use(struct media_entity *entity, int use, + struct media_entity_graph *graph) { int change = use ? 1 : -1; int ret; @@ -501,7 +502,7 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use) WARN_ON(entity->use_count < 0); /* Apply power change to connected non-nodes. */ - ret = iss_pipeline_pm_power(entity, change); + ret = iss_pipeline_pm_power(entity, change, graph); if (ret < 0) entity->use_count -= change; @@ -526,34 +527,48 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use) static int iss_pipeline_link_notify(struct media_link *link, u32 flags, unsigned int notification) { + struct media_entity_graph *graph = + &container_of(link->graph_obj.mdev, struct iss_device, + media_dev)->pm_count_graph; struct media_entity *source = link->source->entity; struct media_entity *sink = link->sink->entity; - int source_use = iss_pipeline_pm_use_count(source); - int sink_use = iss_pipeline_pm_use_count(sink); + int source_use; + int sink_use; int ret; + if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) { + ret = media_entity_graph_walk_init(graph, + link->graph_obj.mdev); + if (ret) + return ret; + } + + source_use = iss_pipeline_pm_use_count(source, graph); + sink_use = iss_pipeline_pm_use_count(sink, graph); + if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH && !(flags & MEDIA_LNK_FL_ENABLED)) { /* Powering off entities is assumed to never fail. */ - iss_pipeline_pm_power(source, -sink_use); - iss_pipeline_pm_power(sink, -source_use); + iss_pipeline_pm_power(source, -sink_use, graph); + iss_pipeline_pm_power(sink, -source_use, graph); return 0; } if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH && (flags & MEDIA_LNK_FL_ENABLED)) { - ret = iss_pipeline_pm_power(source, sink_use); + ret = iss_pipeline_pm_power(source, sink_use, graph); if (ret < 0) return ret; - ret = iss_pipeline_pm_power(sink, source_use); + ret = iss_pipeline_pm_power(sink, source_use, graph); if (ret < 0) - iss_pipeline_pm_power(source, -sink_use); - - return ret; + iss_pipeline_pm_power(source, -sink_use, graph); } - return 0; + if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH) + media_entity_graph_walk_cleanup(graph); + + return ret; } /* ----------------------------------------------------------------------------- diff --git a/drivers/staging/media/omap4iss/iss.h b/drivers/staging/media/omap4iss/iss.h index 693a8f112960b..05f08a3caa190 100644 --- a/drivers/staging/media/omap4iss/iss.h +++ b/drivers/staging/media/omap4iss/iss.h @@ -87,6 +87,7 @@ struct iss_reg { struct iss_device { struct v4l2_device v4l2_dev; struct media_device media_dev; + struct media_entity_graph pm_count_graph; struct device *dev; u32 revision; @@ -151,7 +152,8 @@ void omap4iss_isp_subclk_enable(struct iss_device *iss, void omap4iss_isp_subclk_disable(struct iss_device *iss, enum iss_isp_subclk_resource res); -int omap4iss_pipeline_pm_use(struct media_entity *entity, int use); +int omap4iss_pipeline_pm_use(struct media_entity *entity, int use, + struct media_entity_graph *graph); int omap4iss_register_entities(struct platform_device *pdev, struct v4l2_device *v4l2_dev); diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index 5f8201f861bc3..058233a9de674 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -209,6 +209,12 @@ iss_video_far_end(struct iss_video *video) struct iss_video *far_end = NULL; mutex_lock(&mdev->graph_mutex); + + if (media_entity_graph_walk_init(&graph, mdev)) { + mutex_unlock(&mdev->graph_mutex); + return NULL; + } + media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { @@ -226,6 +232,9 @@ iss_video_far_end(struct iss_video *video) } mutex_unlock(&mdev->graph_mutex); + + media_entity_graph_walk_cleanup(&graph); + return far_end; } @@ -772,7 +781,11 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) ret = media_entity_enum_init(&pipe->ent_enum, entity->graph_obj.mdev); if (ret) - goto err_enum_init; + goto err_graph_walk_init; + + ret = media_entity_graph_walk_init(&graph, entity->graph_obj.mdev); + if (ret) + goto err_graph_walk_init; if (video->iss->pdata->set_constraints) video->iss->pdata->set_constraints(video->iss, true); @@ -853,6 +866,8 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) spin_unlock_irqrestore(&video->qlock, flags); } + media_entity_graph_walk_cleanup(&graph); + mutex_unlock(&video->stream_lock); return 0; @@ -866,9 +881,11 @@ err_media_entity_pipeline_start: video->iss->pdata->set_constraints(video->iss, false); video->queue = NULL; + media_entity_graph_walk_cleanup(&graph); + +err_graph_walk_init: media_entity_enum_cleanup(&pipe->ent_enum); -err_enum_init: mutex_unlock(&video->stream_lock); return ret; @@ -992,7 +1009,13 @@ static int iss_video_open(struct file *file) goto done; } - ret = omap4iss_pipeline_pm_use(&video->video.entity, 1); + ret = media_entity_graph_walk_init(&handle->graph, + &video->iss->media_dev); + if (ret) + goto done; + + ret = omap4iss_pipeline_pm_use(&video->video.entity, 1, + &handle->graph); if (ret < 0) { omap4iss_put(video->iss); goto done; @@ -1031,6 +1054,7 @@ static int iss_video_open(struct file *file) done: if (ret < 0) { v4l2_fh_del(&handle->vfh); + media_entity_graph_walk_cleanup(&handle->graph); kfree(handle); } @@ -1046,12 +1070,13 @@ static int iss_video_release(struct file *file) /* Disable streaming and free the buffers queue resources. */ iss_video_streamoff(file, vfh, video->type); - omap4iss_pipeline_pm_use(&video->video.entity, 0); + omap4iss_pipeline_pm_use(&video->video.entity, 0, &handle->graph); /* Release the videobuf2 queue */ vb2_queue_release(&handle->queue); /* Release the file handle. */ + media_entity_graph_walk_cleanup(&handle->graph); v4l2_fh_del(vfh); kfree(handle); file->private_data = NULL; diff --git a/drivers/staging/media/omap4iss/iss_video.h b/drivers/staging/media/omap4iss/iss_video.h index c8bd2958a3f86..34588b7176ca6 100644 --- a/drivers/staging/media/omap4iss/iss_video.h +++ b/drivers/staging/media/omap4iss/iss_video.h @@ -183,6 +183,7 @@ struct iss_video_fh { struct vb2_queue queue; struct v4l2_format format; struct v4l2_fract timeperframe; + struct media_entity_graph graph; }; #define to_iss_video_fh(fh) container_of(fh, struct iss_video_fh, vfh) -- GitLab From bb0faebdc1d377705081fed67af3f3f3001ac7b8 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:35 -0200 Subject: [PATCH 2594/2855] [media] staging: v4l: davinci_vpbe: Use the new media graph walk interface The media graph walk requires initialisation and cleanup soon. Update the users to perform the soon necessary API calls. Signed-off-by: Sakari Ailus Cc: Prabhakar Lad Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/davinci_vpfe/vpfe_video.c | 37 ++++++++++++++----- .../staging/media/davinci_vpfe/vpfe_video.h | 1 + 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 285dc1a69b2ca..3ec7e65a3ffa5 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -127,13 +127,14 @@ __vpfe_video_get_format(struct vpfe_video_device *video, } /* make a note of pipeline details */ -static void vpfe_prepare_pipeline(struct vpfe_video_device *video) +static int vpfe_prepare_pipeline(struct vpfe_video_device *video) { + struct media_entity_graph graph; struct media_entity *entity = &video->video_dev.entity; struct media_device *mdev = entity->graph_obj.mdev; struct vpfe_pipeline *pipe = &video->pipe; struct vpfe_video_device *far_end = NULL; - struct media_entity_graph graph; + int ret; pipe->input_num = 0; pipe->output_num = 0; @@ -144,6 +145,11 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video) pipe->outputs[pipe->output_num++] = video; mutex_lock(&mdev->graph_mutex); + ret = media_entity_graph_walk_init(&graph, entity->graph_obj.mdev); + if (ret) { + mutex_unlock(&video->lock); + return -ENOMEM; + } media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { if (entity == &video->video_dev.entity) @@ -156,7 +162,10 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video) else pipe->outputs[pipe->output_num++] = far_end; } + media_entity_graph_walk_cleanup(&graph); mutex_unlock(&mdev->graph_mutex); + + return 0; } /* update pipe state selected by user */ @@ -165,7 +174,9 @@ static int vpfe_update_pipe_state(struct vpfe_video_device *video) struct vpfe_pipeline *pipe = &video->pipe; int ret; - vpfe_prepare_pipeline(video); + ret = vpfe_prepare_pipeline(video); + if (ret) + return ret; /* Find out if there is any input video if yes, it is single shot. @@ -276,11 +287,10 @@ static int vpfe_video_validate_pipeline(struct vpfe_pipeline *pipe) */ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe) { - struct media_entity_graph graph; struct media_entity *entity; struct v4l2_subdev *subdev; struct media_device *mdev; - int ret = 0; + int ret; if (pipe->state == VPFE_PIPELINE_STREAM_CONTINUOUS) entity = vpfe_get_input_entity(pipe->outputs[0]); @@ -289,8 +299,12 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe) mdev = entity->graph_obj.mdev; mutex_lock(&mdev->graph_mutex); - media_entity_graph_walk_start(&graph, entity); - while ((entity = media_entity_graph_walk_next(&graph))) { + ret = media_entity_graph_walk_init(&pipe->graph, + entity->graph_obj.mdev); + if (ret) + goto out; + media_entity_graph_walk_start(&pipe->graph, entity); + while ((entity = media_entity_graph_walk_next(&pipe->graph))) { if (!is_media_entity_v4l2_subdev(entity)) continue; @@ -299,6 +313,9 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe) if (ret < 0 && ret != -ENOIOCTLCMD) break; } +out: + if (ret) + media_entity_graph_walk_cleanup(&pipe->graph); mutex_unlock(&mdev->graph_mutex); return ret; } @@ -316,7 +333,6 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe) */ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe) { - struct media_entity_graph graph; struct media_entity *entity; struct v4l2_subdev *subdev; struct media_device *mdev; @@ -329,9 +345,9 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe) mdev = entity->graph_obj.mdev; mutex_lock(&mdev->graph_mutex); - media_entity_graph_walk_start(&graph, entity); + media_entity_graph_walk_start(&pipe->graph, entity); - while ((entity = media_entity_graph_walk_next(&graph))) { + while ((entity = media_entity_graph_walk_next(&pipe->graph))) { if (!is_media_entity_v4l2_subdev(entity)) continue; @@ -342,6 +358,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe) } mutex_unlock(&mdev->graph_mutex); + media_entity_graph_walk_cleanup(&pipe->graph); return ret ? -ETIMEDOUT : 0; } diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.h b/drivers/staging/media/davinci_vpfe/vpfe_video.h index 673cefe3ef61f..653334d537d3b 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.h +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.h @@ -52,6 +52,7 @@ enum vpfe_video_state { struct vpfe_pipeline { /* media pipeline */ struct media_pipeline *pipe; + struct media_entity_graph graph; /* state of the pipeline, continuous, * single-shot or stopped */ -- GitLab From 030e89ecab55b6e105e19fa830a7a7160237f19a Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:36 -0200 Subject: [PATCH 2595/2855] [media] media: Remove pre-allocated entity enumeration bitmap The bitmaps for entity enumerations used to be statically allocated. Now that the drivers have been converted to use the new interface which explicitly initialises the enum objects, drop the pre-allocated bitmaps. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 16 +++++----------- include/media/media-entity.h | 9 ++------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 3cad525c2ac1f..5bd6f88501e24 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -81,14 +81,10 @@ static inline const char *intf_type(struct media_interface *intf) __must_check int __media_entity_enum_init(struct media_entity_enum *ent_enum, int idx_max) { - if (idx_max > MEDIA_ENTITY_ENUM_MAX_ID) { - ent_enum->bmap = kcalloc(DIV_ROUND_UP(idx_max, BITS_PER_LONG), - sizeof(long), GFP_KERNEL); - if (!ent_enum->bmap) - return -ENOMEM; - } else { - ent_enum->bmap = ent_enum->prealloc_bmap; - } + ent_enum->bmap = kcalloc(DIV_ROUND_UP(idx_max, BITS_PER_LONG), + sizeof(long), GFP_KERNEL); + if (!ent_enum->bmap) + return -ENOMEM; bitmap_zero(ent_enum->bmap, idx_max); ent_enum->idx_max = idx_max; @@ -104,9 +100,7 @@ EXPORT_SYMBOL_GPL(__media_entity_enum_init); */ void media_entity_enum_cleanup(struct media_entity_enum *ent_enum) { - if (ent_enum->bmap != ent_enum->prealloc_bmap) - kfree(ent_enum->bmap); - ent_enum->bmap = NULL; + kfree(ent_enum->bmap); } EXPORT_SYMBOL_GPL(media_entity_enum_cleanup); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index a47a7c8a93cfd..4d963a3684c96 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -72,27 +72,22 @@ struct media_gobj { }; #define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 -#define MEDIA_ENTITY_ENUM_MAX_ID 64 /* * The number of pads can't be bigger than the number of entities, * as the worse-case scenario is to have one entity linked up to - * MEDIA_ENTITY_ENUM_MAX_ID - 1 entities. + * 63 entities. */ -#define MEDIA_ENTITY_MAX_PADS (MEDIA_ENTITY_ENUM_MAX_ID - 1) +#define MEDIA_ENTITY_MAX_PADS 63 /** * struct media_entity_enum - An enumeration of media entities. * - * @prealloc_bmap: Pre-allocated space reserved for media entities if the - * total number of entities does not exceed - * MEDIA_ENTITY_ENUM_MAX_ID. * @bmap: Bit map in which each bit represents one entity at struct * media_entity->internal_idx. * @idx_max: Number of bits in bmap */ struct media_entity_enum { - DECLARE_BITMAP(prealloc_bmap, MEDIA_ENTITY_ENUM_MAX_ID); unsigned long *bmap; int idx_max; }; -- GitLab From 0798ce4a386d605af9ddbed724a8f4c8cccc1dab Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:37 -0200 Subject: [PATCH 2596/2855] [media] media: Move MEDIA_ENTITY_MAX_PADS from media-entity.h to media-entity.c This isn't really a part of any interface drivers are expected to use. In order to keep drivers from using it, hide it in media-entity.c. This was always an arbitrary number and should be removed in the long run. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 5 +++++ include/media/media-entity.h | 7 ------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 5bd6f88501e24..32a5f8cae72d4 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -276,6 +276,11 @@ static struct media_entity *stack_pop(struct media_entity_graph *graph) #define link_top(en) ((en)->stack[(en)->top].link) #define stack_top(en) ((en)->stack[(en)->top].entity) +/* + * TODO: Get rid of this. + */ +#define MEDIA_ENTITY_MAX_PADS 63 + /** * media_entity_graph_walk_init - Allocate resources for graph walk * @graph: Media graph structure that will be used to walk the graph diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 4d963a3684c96..f915ed62ac813 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -73,13 +73,6 @@ struct media_gobj { #define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 -/* - * The number of pads can't be bigger than the number of entities, - * as the worse-case scenario is to have one entity linked up to - * 63 entities. - */ -#define MEDIA_ENTITY_MAX_PADS 63 - /** * struct media_entity_enum - An enumeration of media entities. * -- GitLab From 92777994a52e6c1fe0a6156a8b49e83efea6fd2c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Dec 2015 13:53:04 -0200 Subject: [PATCH 2597/2855] [media] move documentation to the header files Some exported functions were still documented at the .c file, instead of documenting at the .h one. Move the documentation to the right place, as we only use headers at media device-drivers.xml DocBook. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 27 --------------------------- drivers/media/media-entity.c | 13 ------------- include/media/media-device.h | 6 ++++++ include/media/media-entity.h | 18 ++++++++++++++++-- 4 files changed, 22 insertions(+), 42 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index ce97f8f196f3b..fd67b34dcda30 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -577,13 +577,6 @@ int __must_check media_device_register_entity(struct media_device *mdev, } EXPORT_SYMBOL_GPL(media_device_register_entity); -/** - * media_device_unregister_entity - Unregister an entity - * @entity: The entity - * - * If the entity has never been registered this function will return - * immediately. - */ static void __media_device_unregister_entity(struct media_entity *entity) { struct media_device *mdev = entity->graph_obj.mdev; @@ -627,7 +620,6 @@ void media_device_unregister_entity(struct media_entity *entity) } EXPORT_SYMBOL_GPL(media_device_unregister_entity); - /** * media_device_init() - initialize a media device * @mdev: The media device @@ -652,11 +644,6 @@ void media_device_init(struct media_device *mdev) } EXPORT_SYMBOL_GPL(media_device_init); -/** - * media_device_cleanup() - Cleanup a media device - * @mdev: The media device - * - */ void media_device_cleanup(struct media_device *mdev) { ida_destroy(&mdev->entity_internal_idx); @@ -665,13 +652,6 @@ void media_device_cleanup(struct media_device *mdev) } EXPORT_SYMBOL_GPL(media_device_cleanup); -/** - * __media_device_register() - register a media device - * @mdev: The media device - * @owner: The module owner - * - * returns zero on success or a negative error code. - */ int __must_check __media_device_register(struct media_device *mdev, struct module *owner) { @@ -701,13 +681,6 @@ int __must_check __media_device_register(struct media_device *mdev, } EXPORT_SYMBOL_GPL(__media_device_register); -/** - * media_device_unregister - unregister a media device - * @mdev: The media device - * - * It is safe to call this function on an unregistered - * (but initialised) media device. - */ void media_device_unregister(struct media_device *mdev) { struct media_entity *entity; diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 32a5f8cae72d4..a2d28162213ea 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -70,14 +70,6 @@ static inline const char *intf_type(struct media_interface *intf) } }; -/** - * __media_entity_enum_init - Initialise an entity enumeration - * - * @ent_enum: Entity enumeration to be initialised - * @idx_max: Maximum number of entities in the enumeration - * - * Returns zero on success or a negative error code. - */ __must_check int __media_entity_enum_init(struct media_entity_enum *ent_enum, int idx_max) { @@ -93,11 +85,6 @@ __must_check int __media_entity_enum_init(struct media_entity_enum *ent_enum, } EXPORT_SYMBOL_GPL(__media_entity_enum_init); -/** - * media_entity_enum_cleanup - Release resources of an entity enumeration - * - * @e: Entity enumeration to be released - */ void media_entity_enum_cleanup(struct media_entity_enum *ent_enum) { kfree(ent_enum->bmap); diff --git a/include/media/media-device.h b/include/media/media-device.h index da4e12ca259c1..706afdb22d0d5 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -428,6 +428,8 @@ void media_device_cleanup(struct media_device *mdev); * a sysfs attribute. * * Unregistering a media device that hasn't been registered is *NOT* safe. + * + * Return: returns zero on success or a negative error code. */ int __must_check __media_device_register(struct media_device *mdev, struct module *owner); @@ -437,6 +439,10 @@ int __must_check __media_device_register(struct media_device *mdev, * __media_device_unregister() - Unegisters a media device element * * @mdev: pointer to struct &media_device + * + * + * It is safe to call this function on an unregistered (but initialised) + * media device. */ void media_device_unregister(struct media_device *mdev); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index f915ed62ac813..c4aaeb85229c1 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -370,9 +370,23 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) } } +/** + * __media_entity_enum_init - Initialise an entity enumeration + * + * @ent_enum: Entity enumeration to be initialised + * @idx_max: Maximum number of entities in the enumeration + * + * Return: Returns zero on success or a negative error code. + */ __must_check int __media_entity_enum_init(struct media_entity_enum *ent_enum, int idx_max); -void media_entity_enum_cleanup(struct media_entity_enum *e); + +/** + * media_entity_enum_cleanup - Release resources of an entity enumeration + * + * @ent_enum: Entity enumeration to be released + */ +void media_entity_enum_cleanup(struct media_entity_enum *ent_enum); /** * media_entity_enum_zero - Clear the entire enum @@ -847,6 +861,7 @@ void media_remove_intf_link(struct media_link *link); * Note: this is an unlocked version of media_remove_intf_links(). */ void __media_remove_intf_links(struct media_interface *intf); + /** * media_remove_intf_links() - remove all links associated with an interface * @@ -861,7 +876,6 @@ void __media_remove_intf_links(struct media_interface *intf); */ void media_remove_intf_links(struct media_interface *intf); - #define media_entity_call(entity, operation, args...) \ (((entity)->ops && (entity)->ops->operation) ? \ (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD) -- GitLab From aa360d3de3e5c8824d48e6e273d93ee69fb53cdf Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Dec 2015 13:56:14 -0200 Subject: [PATCH 2598/2855] [media] DocBook: document media_entity_graph_walk_cleanup() This function was added recently, but weren't documented. Add documentation for it. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index c4aaeb85229c1..f90ff56888d4b 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -705,6 +705,12 @@ struct media_entity *media_entity_get(struct media_entity *entity); __must_check int media_entity_graph_walk_init( struct media_entity_graph *graph, struct media_device *mdev); + +/** + * media_entity_graph_walk_cleanup - Release resources used by graph walk. + * + * @graph: Media graph structure that will be used to walk the graph + */ void media_entity_graph_walk_cleanup(struct media_entity_graph *graph); /** -- GitLab From 03e493388415df701d4b9e362021a83529018a3b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Dec 2015 13:58:31 -0200 Subject: [PATCH 2599/2855] [media] media-entity.h fix documentation for several parameters Several parameters added by the media_ent_enum patches were declared with wrong argument names: include/media/media-device.h:333: warning: No description found for parameter 'entity_internal_idx_max' include/media/media-device.h:354: warning: No description found for parameter 'ent_enum' include/media/media-device.h:354: warning: Excess function parameter 'e' description in 'media_entity_enum_init' include/media/media-device.h:333: warning: No description found for parameter 'entity_internal_idx_max' include/media/media-device.h:354: warning: No description found for parameter 'ent_enum' include/media/media-device.h:354: warning: Excess function parameter 'e' description in 'media_entity_enum_init' include/media/media-entity.h:397: warning: No description found for parameter 'ent_enum' include/media/media-entity.h:397: warning: Excess function parameter 'e' description in 'media_entity_enum_zero' include/media/media-entity.h:409: warning: No description found for parameter 'ent_enum' include/media/media-entity.h:409: warning: Excess function parameter 'e' description in 'media_entity_enum_set' include/media/media-entity.h:424: warning: No description found for parameter 'ent_enum' include/media/media-entity.h:424: warning: Excess function parameter 'e' description in 'media_entity_enum_clear' include/media/media-entity.h:441: warning: No description found for parameter 'ent_enum' include/media/media-entity.h:441: warning: Excess function parameter 'e' description in 'media_entity_enum_test' include/media/media-entity.h:458: warning: No description found for parameter 'ent_enum' include/media/media-entity.h:458: warning: Excess function parameter 'e' description in 'media_entity_enum_test_and_set' include/media/media-entity.h:474: warning: No description found for parameter 'ent_enum' include/media/media-entity.h:474: warning: Excess function parameter 'e' description in 'media_entity_enum_empty' include/media/media-entity.h:474: warning: Excess function parameter 'entity' description in 'media_entity_enum_empty' include/media/media-entity.h:489: warning: No description found for parameter 'ent_enum1' include/media/media-entity.h:489: warning: No description found for parameter 'ent_enum2' include/media/media-entity.h:489: warning: Excess function parameter 'e' description in 'media_entity_enum_intersects' include/media/media-entity.h:489: warning: Excess function parameter 'f' description in 'media_entity_enum_intersects' Fix them. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 6 ++++-- include/media/media-entity.h | 24 ++++++++++++------------ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/include/media/media-device.h b/include/media/media-device.h index 706afdb22d0d5..0dc67f2c2d0a8 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -279,7 +279,9 @@ struct device; * @pad_id: Unique ID used on the last pad registered * @link_id: Unique ID used on the last link registered * @intf_devnode_id: Unique ID used on the last interface devnode registered - * @entity_internal_idx: Allocated internal entity indices + * @entity_internal_idx: Unique internal entity ID used by the graph traversal + * algorithms + * @entity_internal_idx_max: Allocated internal entity indices * @entities: List of registered entities * @interfaces: List of registered interfaces * @pads: List of registered pads @@ -344,7 +346,7 @@ struct media_device { /** * media_entity_enum_init - Initialise an entity enumeration * - * @e: Entity enumeration to be initialised + * @ent_enum: Entity enumeration to be initialised * @mdev: The related media device * * Returns zero on success or a negative error code. diff --git a/include/media/media-entity.h b/include/media/media-entity.h index f90ff56888d4b..855b47df6ed54 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -391,7 +391,7 @@ void media_entity_enum_cleanup(struct media_entity_enum *ent_enum); /** * media_entity_enum_zero - Clear the entire enum * - * @e: Entity enumeration to be cleared + * @ent_enum: Entity enumeration to be cleared */ static inline void media_entity_enum_zero(struct media_entity_enum *ent_enum) { @@ -401,7 +401,7 @@ static inline void media_entity_enum_zero(struct media_entity_enum *ent_enum) /** * media_entity_enum_set - Mark a single entity in the enum * - * @e: Entity enumeration + * @ent_enum: Entity enumeration * @entity: Entity to be marked */ static inline void media_entity_enum_set(struct media_entity_enum *ent_enum, @@ -416,7 +416,7 @@ static inline void media_entity_enum_set(struct media_entity_enum *ent_enum, /** * media_entity_enum_clear - Unmark a single entity in the enum * - * @e: Entity enumeration + * @ent_enum: Entity enumeration * @entity: Entity to be unmarked */ static inline void media_entity_enum_clear(struct media_entity_enum *ent_enum, @@ -431,7 +431,7 @@ static inline void media_entity_enum_clear(struct media_entity_enum *ent_enum, /** * media_entity_enum_test - Test whether the entity is marked * - * @e: Entity enumeration + * @ent_enum: Entity enumeration * @entity: Entity to be tested * * Returns true if the entity was marked. @@ -448,13 +448,14 @@ static inline bool media_entity_enum_test(struct media_entity_enum *ent_enum, /** * media_entity_enum_test - Test whether the entity is marked, and mark it * - * @e: Entity enumeration + * @ent_enum: Entity enumeration * @entity: Entity to be tested * * Returns true if the entity was marked, and mark it before doing so. */ -static inline bool media_entity_enum_test_and_set( - struct media_entity_enum *ent_enum, struct media_entity *entity) +static inline bool +media_entity_enum_test_and_set(struct media_entity_enum *ent_enum, + struct media_entity *entity) { if (WARN_ON(entity->internal_idx >= ent_enum->idx_max)) return true; @@ -463,10 +464,9 @@ static inline bool media_entity_enum_test_and_set( } /** - * media_entity_enum_test - Test whether the entire enum is empty + * media_entity_enum_empty - Test whether the entire enum is empty * - * @e: Entity enumeration - * @entity: Entity to be tested + * @ent_enum: Entity enumeration * * Returns true if the entity was marked. */ @@ -478,8 +478,8 @@ static inline bool media_entity_enum_empty(struct media_entity_enum *ent_enum) /** * media_entity_enum_intersects - Test whether two enums intersect * - * @e: First entity enumeration - * @f: Second entity enumeration + * @ent_enum1: First entity enumeration + * @ent_enum2: Second entity enumeration * * Returns true if entity enumerations e and f intersect, otherwise false. */ -- GitLab From 05b3b77cbbb01180b681bc9211f3d471123809ca Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Dec 2015 14:28:01 -0200 Subject: [PATCH 2600/2855] [media] media-device.h: use just one u32 counter for object ID Instead of using one u32 counter per type for object IDs, use just one counter. With such change, it makes sense to simplify the debug logs too. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 35 +++++++++++++++-------------------- include/media/media-device.h | 10 ++-------- include/media/media-entity.h | 21 ++++++++++----------- 3 files changed, 27 insertions(+), 39 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index a2d28162213ea..f63be23e6ed47 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -106,8 +106,8 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) switch (media_type(gobj)) { case MEDIA_GRAPH_ENTITY: dev_dbg(gobj->mdev->dev, - "%s: id 0x%08x entity#%d: '%s'\n", - event_name, gobj->id, media_localid(gobj), + "%s id %u: entity '%s'\n", + event_name, media_id(gobj), gobj_to_entity(gobj)->name); break; case MEDIA_GRAPH_LINK: @@ -115,14 +115,12 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) struct media_link *link = gobj_to_link(gobj); dev_dbg(gobj->mdev->dev, - "%s: id 0x%08x link#%d: %s#%d ==> %s#%d\n", - event_name, gobj->id, media_localid(gobj), - - gobj_type(media_type(link->gobj0)), - media_localid(link->gobj0), - - gobj_type(media_type(link->gobj1)), - media_localid(link->gobj1)); + "%s id %u: %s link id %u ==> id %u\n", + event_name, media_id(gobj), + media_type(link->gobj0) == MEDIA_GRAPH_PAD ? + "data" : "interface", + media_id(link->gobj0), + media_id(link->gobj1)); break; } case MEDIA_GRAPH_PAD: @@ -130,11 +128,10 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) struct media_pad *pad = gobj_to_pad(gobj); dev_dbg(gobj->mdev->dev, - "%s: id 0x%08x %s%spad#%d: '%s':%d\n", - event_name, gobj->id, - pad->flags & MEDIA_PAD_FL_SINK ? " sink " : "", + "%s id %u: %s%spad '%s':%d\n", + event_name, media_id(gobj), + pad->flags & MEDIA_PAD_FL_SINK ? "sink " : "", pad->flags & MEDIA_PAD_FL_SOURCE ? "source " : "", - media_localid(gobj), pad->entity->name, pad->index); break; } @@ -144,8 +141,8 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) struct media_intf_devnode *devnode = intf_to_devnode(intf); dev_dbg(gobj->mdev->dev, - "%s: id 0x%08x intf_devnode#%d: %s - major: %d, minor: %d\n", - event_name, gobj->id, media_localid(gobj), + "%s id %u: intf_devnode %s - major: %d, minor: %d\n", + event_name, media_id(gobj), intf_type(intf), devnode->major, devnode->minor); break; @@ -163,21 +160,19 @@ void media_gobj_create(struct media_device *mdev, gobj->mdev = mdev; /* Create a per-type unique object ID */ + gobj->id = media_gobj_gen_id(type, ++mdev->id); + switch (type) { case MEDIA_GRAPH_ENTITY: - gobj->id = media_gobj_gen_id(type, ++mdev->entity_id); list_add_tail(&gobj->list, &mdev->entities); break; case MEDIA_GRAPH_PAD: - gobj->id = media_gobj_gen_id(type, ++mdev->pad_id); list_add_tail(&gobj->list, &mdev->pads); break; case MEDIA_GRAPH_LINK: - gobj->id = media_gobj_gen_id(type, ++mdev->link_id); list_add_tail(&gobj->list, &mdev->links); break; case MEDIA_GRAPH_INTF_DEVNODE: - gobj->id = media_gobj_gen_id(type, ++mdev->intf_devnode_id); list_add_tail(&gobj->list, &mdev->interfaces); break; } diff --git a/include/media/media-device.h b/include/media/media-device.h index 0dc67f2c2d0a8..d3855898c3fc6 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -275,10 +275,7 @@ struct device; * @driver_version: Device driver version * @topology_version: Monotonic counter for storing the version of the graph * topology. Should be incremented each time the topology changes. - * @entity_id: Unique ID used on the last entity registered - * @pad_id: Unique ID used on the last pad registered - * @link_id: Unique ID used on the last link registered - * @intf_devnode_id: Unique ID used on the last interface devnode registered + * @id: Unique ID used on the last registered graph object * @entity_internal_idx: Unique internal entity ID used by the graph traversal * algorithms * @entity_internal_idx_max: Allocated internal entity indices @@ -313,10 +310,7 @@ struct media_device { u32 topology_version; - u32 entity_id; - u32 pad_id; - u32 link_id; - u32 intf_devnode_id; + u32 id; struct ida entity_internal_idx; int entity_internal_idx_max; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 855b47df6ed54..54be1496d542d 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -47,8 +47,8 @@ enum media_gobj_type { }; #define MEDIA_BITS_PER_TYPE 8 -#define MEDIA_BITS_PER_LOCAL_ID (32 - MEDIA_BITS_PER_TYPE) -#define MEDIA_LOCAL_ID_MASK GENMASK(MEDIA_BITS_PER_LOCAL_ID - 1, 0) +#define MEDIA_BITS_PER_ID (32 - MEDIA_BITS_PER_TYPE) +#define MEDIA_ID_MASK GENMASK_ULL(MEDIA_BITS_PER_ID - 1, 0) /* Structs to represent the objects that belong to a media graph */ @@ -58,9 +58,8 @@ enum media_gobj_type { * @mdev: Pointer to the struct media_device that owns the object * @id: Non-zero object ID identifier. The ID should be unique * inside a media_device, as it is composed by - * MEDIA_BITS_PER_TYPE to store the type plus - * MEDIA_BITS_PER_LOCAL_ID to store a per-type ID - * (called as "local ID"). + * %MEDIA_BITS_PER_TYPE to store the type plus + * %MEDIA_BITS_PER_ID to store the ID * @list: List entry stored in one of the per-type mdev object lists * * All objects on the media graph should have this struct embedded @@ -299,20 +298,20 @@ static inline u32 media_entity_id(struct media_entity *entity) */ static inline enum media_gobj_type media_type(struct media_gobj *gobj) { - return gobj->id >> MEDIA_BITS_PER_LOCAL_ID; + return gobj->id >> MEDIA_BITS_PER_ID; } -static inline u32 media_localid(struct media_gobj *gobj) +static inline u32 media_id(struct media_gobj *gobj) { - return gobj->id & MEDIA_LOCAL_ID_MASK; + return gobj->id & MEDIA_ID_MASK; } -static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id) +static inline u32 media_gobj_gen_id(enum media_gobj_type type, u64 local_id) { u32 id; - id = type << MEDIA_BITS_PER_LOCAL_ID; - id |= local_id & MEDIA_LOCAL_ID_MASK; + id = type << MEDIA_BITS_PER_ID; + id |= local_id & MEDIA_ID_MASK; return id; } -- GitLab From 630c0e80c984c0a9a325430d62770fd49f93f9b9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Dec 2015 15:15:18 -0200 Subject: [PATCH 2601/2855] [media] media-entity.h: document the remaining functions There are two ancillary functions that are missing comments. While those are used only internally at media-entity.c, document them, for completeness. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 54be1496d542d..79dd81fd463e8 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -301,11 +301,22 @@ static inline enum media_gobj_type media_type(struct media_gobj *gobj) return gobj->id >> MEDIA_BITS_PER_ID; } +/** + * media_id() - return the media object ID + * + * @gobj: pointer to the media graph object + */ static inline u32 media_id(struct media_gobj *gobj) { return gobj->id & MEDIA_ID_MASK; } +/** + * media_gobj_gen_id() - encapsulates type and ID on at the object ID + * + * @type: object type as define at enum &media_gobj_type. + * @local_id: next ID, from struct &media_device.@id. + */ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u64 local_id) { u32 id; -- GitLab From 430a672c83c3e2e9a96c777a874f345c8d21f929 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Dec 2015 15:18:25 -0200 Subject: [PATCH 2602/2855] [media] media-entity: increase max number of PADs The DVB drivers may have 257 PADs. Get the next power of two that would accomodate that amount. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index f63be23e6ed47..eb38bc35320a8 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -261,7 +261,7 @@ static struct media_entity *stack_pop(struct media_entity_graph *graph) /* * TODO: Get rid of this. */ -#define MEDIA_ENTITY_MAX_PADS 63 +#define MEDIA_ENTITY_MAX_PADS 512 /** * media_entity_graph_walk_init - Allocate resources for graph walk -- GitLab From ba0dd729bfc09e51af238a630deba70205442afe Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Dec 2015 15:33:54 -0200 Subject: [PATCH 2603/2855] [media] media-entity: don't sleep at media_device_register_entity() media_device_register_entity() is protected by a spin_lock. Calling ida_pre_get() with GFP_KERNEL may put it to sleep, with is a bad idea and causes this warning: [ 8812.397195] BUG: sleeping function called from invalid context at mm/slub.c:1287 [ 8812.397203] in_atomic(): 1, irqs_disabled(): 0, pid: 15179, name: modprobe [ 8812.397207] INFO: lockdep is turned off. [ 8812.397213] CPU: 2 PID: 15179 Comm: modprobe Tainted: G B 4.4.0-rc2+ #41 [ 8812.397218] Hardware name: /NUC5i7RYB, BIOS RYBDWi35.86A.0350.2015.0812.1722 08/12/2015 [ 8812.397222] 0000000000000000 ffff880314c77268 ffffffff818f8ba7 ffff8803b17dde00 [ 8812.397232] ffff880314c77290 ffffffff811c2ee5 ffff8803b17dde00 ffffffff8284dbc9 [ 8812.397241] 0000000000000507 ffff880314c772d0 ffffffff811c30d5 0000000041b58ab3 [ 8812.397250] Call Trace: [ 8812.397258] [] dump_stack+0x4b/0x64 [ 8812.397265] [] ___might_sleep+0x245/0x3a0 [ 8812.397270] [] __might_sleep+0x95/0x1a0 [ 8812.397276] [] ? ida_pre_get+0x113/0x250 [ 8812.397282] [] kmem_cache_alloc+0x197/0x250 [ 8812.397288] [] ida_pre_get+0x113/0x250 [ 8812.397293] [] ida_simple_get+0xa5/0x170 [ 8812.397298] [] ? ida_pre_get+0x250/0x250 [ 8812.397306] [] media_device_register_entity+0x171/0x420 [media] [ 8812.397318] [] v4l2_device_register_subdev+0x34f/0x640 [videodev] [ 8812.397324] [] v4l2_i2c_new_subdev_board+0x12a/0x250 [v4l2_common] [ 8812.397330] [] v4l2_i2c_new_subdev+0xd7/0x110 [v4l2_common] [ 8812.397337] [] ? v4l2_i2c_new_subdev_board+0x250/0x250 [v4l2_common] [ 8812.397347] [] au0828_card_analog_fe_setup+0x2e6/0x3f0 [au0828] [ 8812.397352] [] ? power_down+0xc4/0xc4 [ 8812.397361] [] ? au0828_tuner_callback+0x160/0x160 [au0828] [ 8812.397370] [] au0828_card_setup+0x11f/0x340 [au0828] [ 8812.397378] [] ? au0828_card_analog_fe_setup+0x3f0/0x3f0 [au0828] [ 8812.397384] [] ? msleep+0x7b/0xc0 [ 8812.397393] [] au0828_usb_probe+0x679/0xcf0 [au0828] [ 8812.397399] [] usb_probe_interface+0x45d/0x940 [ 8812.397406] [] driver_probe_device+0x454/0xd90 [ 8812.397411] [] ? driver_probe_device+0xd90/0xd90 [ 8812.397417] [] ? driver_probe_device+0xd90/0xd90 [ 8812.397422] [] __driver_attach+0x121/0x160 [ 8812.397427] [] bus_for_each_dev+0x11f/0x1a0 [ 8812.397433] [] ? subsys_dev_iter_exit+0x10/0x10 [ 8812.397439] [] ? _raw_spin_unlock+0x27/0x40 [ 8812.397445] [] driver_attach+0x3d/0x50 [ 8812.397450] [] bus_add_driver+0x4c9/0x770 [ 8812.397456] [] driver_register+0x18c/0x3b0 [ 8812.397462] [] ? __raw_spin_lock_init+0x32/0x100 [ 8812.397468] [] usb_register_driver+0x1f8/0x440 [ 8812.397473] [] ? 0xffffffffa0208000 [ 8812.397481] [] au0828_init+0xb7/0x1000 [au0828] [ 8812.397486] [] do_one_initcall+0x141/0x300 [ 8812.397492] [] ? try_to_run_init_process+0x40/0x40 [ 8812.397497] [] ? trace_hardirqs_on_caller+0x16/0x590 [ 8812.397502] [] ? kasan_unpoison_shadow+0x36/0x50 [ 8812.397507] [] ? kasan_unpoison_shadow+0x36/0x50 [ 8812.397512] [] ? kasan_unpoison_shadow+0x36/0x50 [ 8812.397517] [] ? __asan_register_globals+0x87/0xa0 [ 8812.397524] [] do_init_module+0x1d0/0x5a4 [ 8812.397530] [] load_module+0x6648/0x9d70 [ 8812.397535] [] ? symbol_put_addr+0x50/0x50 [ 8812.397546] [] ? module_frob_arch_sections+0x20/0x20 [ 8812.397552] [] ? open_exec+0x50/0x50 [ 8812.397559] [] ? ns_capable+0x5b/0xd0 [ 8812.397565] [] SyS_finit_module+0x108/0x130 [ 8812.397571] [] ? SyS_init_module+0x1f0/0x1f0 [ 8812.397576] [] ? lockdep_sys_exit_thunk+0x12/0x14 [ 8812.397582] [] entry_SYSCALL_64_fastpath+0x16/0x7a Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index fd67b34dcda30..4d1c13de494bf 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -537,6 +537,7 @@ int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity) { unsigned int i; + int ret; if (entity->function == MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN || entity->function == MEDIA_ENT_F_UNKNOWN) @@ -551,13 +552,16 @@ int __must_check media_device_register_entity(struct media_device *mdev, entity->num_links = 0; entity->num_backlinks = 0; + if (!ida_pre_get(&mdev->entity_internal_idx, GFP_KERNEL)) + return -ENOMEM; + spin_lock(&mdev->lock); - entity->internal_idx = ida_simple_get(&mdev->entity_internal_idx, 1, 0, - GFP_KERNEL); - if (entity->internal_idx < 0) { + ret = ida_get_new_above(&mdev->entity_internal_idx, 1, + &entity->internal_idx); + if (ret < 0) { spin_unlock(&mdev->lock); - return entity->internal_idx; + return ret; } mdev->entity_internal_idx_max = -- GitLab From 7c9d6731acf2816cd94e6c51f02ac8348dc7bb7e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 17 Dec 2015 09:07:38 -0200 Subject: [PATCH 2604/2855] [media] uapi/media.h: Use u32 for the number of graph objects While we need to keep a u64 alignment to avoid compat32 issues, having the number of entities/pads/links/interfaces represented by an u64 is incoherent with the ID number, with is an u32. In order to make it coherent, change those quantities to u32. Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index cacfceb0d81d8..5dbb208e5451a 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -330,16 +330,20 @@ struct media_v2_link { struct media_v2_topology { __u64 topology_version; - __u64 num_entities; + __u32 num_entities; + __u32 reserved1; __u64 ptr_entities; - __u64 num_interfaces; + __u32 num_interfaces; + __u32 reserved2; __u64 ptr_interfaces; - __u64 num_pads; + __u32 num_pads; + __u32 reserved3; __u64 ptr_pads; - __u64 num_links; + __u32 num_links; + __u32 reserved4; __u64 ptr_links; }; -- GitLab From 2e7508e40f6391762499d802226d8a31b0ea3944 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Dec 2015 09:24:23 -0200 Subject: [PATCH 2605/2855] [media] call media_device_init() before registering the V4L2 device Currently, v4l2_device_register() doesn't use the media_device struct. So, calling media_device_init() could be called either before or after v4l2_device_register(). Yet, it is a good practice to initialize everything before calling the register functions. Also, the other drivers call media_device_init() before registering the V4L2 device. So, move the call for media_device_init() to happen earlier on exynos4-is and s3c-camif. This is just a cleanup patch. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/media-dev.c | 4 ++-- drivers/media/platform/s3c-camif/camif-core.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index f6b391e795c65..f3b2dd30ec776 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -1356,14 +1356,14 @@ static int fimc_md_probe(struct platform_device *pdev) fmd->use_isp = fimc_md_is_isp_available(dev->of_node); fmd->user_subdev_api = true; + media_device_init(&fmd->media_dev); + ret = v4l2_device_register(dev, &fmd->v4l2_dev); if (ret < 0) { v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret); return ret; } - media_device_init(&fmd->media_dev); - ret = fimc_md_get_clocks(fmd); if (ret) goto err_md; diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c index ea02b7ef2119b..0b44b9accf507 100644 --- a/drivers/media/platform/s3c-camif/camif-core.c +++ b/drivers/media/platform/s3c-camif/camif-core.c @@ -324,12 +324,12 @@ static int camif_media_dev_init(struct camif_dev *camif) strlcpy(v4l2_dev->name, "s3c-camif", sizeof(v4l2_dev->name)); v4l2_dev->mdev = md; + media_device_init(md); + ret = v4l2_device_register(camif->dev, v4l2_dev); if (ret < 0) return ret; - media_device_init(md); - return ret; } -- GitLab From 0820eb5c5510b0a5c25a17c8be5e40156ace4991 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Dec 2015 10:30:06 -0200 Subject: [PATCH 2606/2855] [media] dvbdev: remove two dead functions if !CONFIG_MEDIA_CONTROLLER_DVB Those functions are used only if CONFIG_MEDIA_CONTROLLER_DVB. Without that, if !CONFIG_MEDIA_CONTROLLER_DVB, it would produce two warnings: drivers/media/dvb-core/dvbdev.c:219:12: warning: 'dvb_create_tsout_entity' defined but not used [-Wunused-function] static int dvb_create_tsout_entity(struct dvb_device *dvbdev, ^ drivers/media/dvb-core/dvbdev.c:264:12: warning: 'dvb_create_media_entity' defined but not used [-Wunused-function] static int dvb_create_media_entity(struct dvb_device *dvbdev, ^ Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index b56e00817d3fa..860dd7d06b601 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -216,10 +216,10 @@ static void dvb_media_device_free(struct dvb_device *dvbdev) #endif } +#if defined(CONFIG_MEDIA_CONTROLLER_DVB) static int dvb_create_tsout_entity(struct dvb_device *dvbdev, const char *name, int npads) { -#if defined(CONFIG_MEDIA_CONTROLLER_DVB) int i, ret = 0; dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads), @@ -254,7 +254,6 @@ static int dvb_create_tsout_entity(struct dvb_device *dvbdev, if (ret < 0) return ret; } -#endif return 0; } @@ -264,7 +263,6 @@ static int dvb_create_tsout_entity(struct dvb_device *dvbdev, static int dvb_create_media_entity(struct dvb_device *dvbdev, int type, int demux_sink_pads) { -#if defined(CONFIG_MEDIA_CONTROLLER_DVB) int i, ret, npads; switch (type) { @@ -352,9 +350,9 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev, printk(KERN_DEBUG "%s: media entity '%s' registered.\n", __func__, dvbdev->entity->name); -#endif return 0; } +#endif static int dvb_register_media_device(struct dvb_device *dvbdev, int type, int minor, -- GitLab From 0230d60e4661d9ced6fb0b9a30f182ebdafbba7a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 29 Dec 2015 11:52:23 -0200 Subject: [PATCH 2607/2855] [media] dvbdev: Add RF connector if needed Several pure digital TV devices have a frontend with the tuner integrated on it. Add the RF connector when dvb_create_media_graph() is called on such devices. Tested with siano and dvb_usb_mxl111sf drivers. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb-main.c | 2 +- drivers/media/dvb-core/dvbdev.c | 49 ++++++++++++++++++++- drivers/media/dvb-core/dvbdev.h | 20 ++++++++- drivers/media/usb/au0828/au0828-dvb.c | 2 +- drivers/media/usb/cx231xx/cx231xx-dvb.c | 2 +- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 2 +- drivers/media/usb/dvb-usb/dvb-usb-dvb.c | 2 +- 7 files changed, 70 insertions(+), 9 deletions(-) diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index 8a1ea21924394..d31f468830cf6 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -1184,7 +1184,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, if (smsdvb_debugfs_create(client) < 0) pr_info("failed to create debugfs node\n"); - rc = dvb_create_media_graph(&client->adapter); + rc = dvb_create_media_graph(&client->adapter, true); if (rc < 0) { pr_err("dvb_create_media_graph failed %d\n", rc); goto client_error; diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 860dd7d06b601..28e340583edee 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -213,6 +213,13 @@ static void dvb_media_device_free(struct dvb_device *dvbdev) media_devnode_remove(dvbdev->intf_devnode); dvbdev->intf_devnode = NULL; } + + if (dvbdev->adapter->conn) { + media_device_unregister_entity(dvbdev->adapter->conn); + dvbdev->adapter->conn = NULL; + kfree(dvbdev->adapter->conn_pads); + dvbdev->adapter->conn_pads = NULL; + } #endif } @@ -559,16 +566,18 @@ static int dvb_create_io_intf_links(struct dvb_adapter *adap, return 0; } -int dvb_create_media_graph(struct dvb_adapter *adap) +int dvb_create_media_graph(struct dvb_adapter *adap, + bool create_rf_connector) { struct media_device *mdev = adap->mdev; - struct media_entity *entity, *tuner = NULL, *demod = NULL; + struct media_entity *entity, *tuner = NULL, *demod = NULL, *conn; struct media_entity *demux = NULL, *ca = NULL; struct media_link *link; struct media_interface *intf; unsigned demux_pad = 0; unsigned dvr_pad = 0; int ret; + static const char *connector_name = "Television"; if (!mdev) return 0; @@ -590,6 +599,42 @@ int dvb_create_media_graph(struct dvb_adapter *adap) } } + if (create_rf_connector) { + conn = kzalloc(sizeof(*conn), GFP_KERNEL); + if (!conn) + return -ENOMEM; + adap->conn = conn; + + adap->conn_pads = kcalloc(1, sizeof(*adap->conn_pads), + GFP_KERNEL); + if (!adap->conn_pads) + return -ENOMEM; + + conn->flags = MEDIA_ENT_FL_CONNECTOR; + conn->function = MEDIA_ENT_F_CONN_RF; + conn->name = connector_name; + adap->conn_pads->flags = MEDIA_PAD_FL_SOURCE; + + ret = media_entity_pads_init(conn, 1, adap->conn_pads); + if (ret) + return ret; + + ret = media_device_register_entity(mdev, conn); + if (ret) + return ret; + + if (!tuner) + ret = media_create_pad_link(conn, 0, + demod, 0, + MEDIA_LNK_FL_ENABLED); + else + ret = media_create_pad_link(conn, 0, + tuner, TUNER_PAD_RF_INPUT, + MEDIA_LNK_FL_ENABLED); + if (ret) + return ret; + } + if (tuner && demod) { ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, demod, 0, MEDIA_LNK_FL_ENABLED); diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index abee18a402e1e..b622d6a3b95e0 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h @@ -75,6 +75,9 @@ struct dvb_frontend; * used. * @mdev: pointer to struct media_device, used when the media * controller is used. + * @conn: RF connector. Used only if the device has no separate + * tuner. + * @conn_pads: pointer to struct media_pad associated with @conn; */ struct dvb_adapter { int num; @@ -94,6 +97,8 @@ struct dvb_adapter { #if defined(CONFIG_MEDIA_CONTROLLER_DVB) struct media_device *mdev; + struct media_entity *conn; + struct media_pad *conn_pads; #endif }; @@ -214,7 +219,16 @@ int dvb_register_device(struct dvb_adapter *adap, void dvb_unregister_device(struct dvb_device *dvbdev); #ifdef CONFIG_MEDIA_CONTROLLER_DVB -__must_check int dvb_create_media_graph(struct dvb_adapter *adap); +/** + * dvb_create_media_graph - Creates media graph for the Digital TV part of the + * device. + * + * @adap: pointer to struct dvb_adapter + * @create_rf_connector: if true, it creates the RF connector too + */ +__must_check int dvb_create_media_graph(struct dvb_adapter *adap, + bool create_rf_connector); + static inline void dvb_register_media_controller(struct dvb_adapter *adap, struct media_device *mdev) { @@ -222,7 +236,9 @@ static inline void dvb_register_media_controller(struct dvb_adapter *adap, } #else -static inline int dvb_create_media_graph(struct dvb_adapter *adap) +static inline +int dvb_create_media_graph(struct dvb_adapter *adap, + bool create_rf_connector) { return 0; }; diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c index cd542b49a6c2b..94363a3ba400a 100644 --- a/drivers/media/usb/au0828/au0828-dvb.c +++ b/drivers/media/usb/au0828/au0828-dvb.c @@ -486,7 +486,7 @@ static int dvb_register(struct au0828_dev *dev) dvb->start_count = 0; dvb->stop_count = 0; - result = dvb_create_media_graph(&dvb->adapter); + result = dvb_create_media_graph(&dvb->adapter, false); if (result < 0) goto fail_create_graph; diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index b7552d20ebdb5..b8d5b2be92937 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -551,7 +551,7 @@ static int register_dvb(struct cx231xx_dvb *dvb, /* register network adapter */ dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); - result = dvb_create_media_graph(&dvb->adapter); + result = dvb_create_media_graph(&dvb->adapter, false); if (result < 0) goto fail_create_graph; diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index 0fa2c45917b02..e8491f73c0d9a 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -706,7 +706,7 @@ static int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap) } } - ret = dvb_create_media_graph(&adap->dvb_adap); + ret = dvb_create_media_graph(&adap->dvb_adap, true); if (ret < 0) goto err_dvb_unregister_frontend; diff --git a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c index 241463ef631e0..9ddfcab268be9 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c @@ -330,7 +330,7 @@ int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap) if (ret) return ret; - ret = dvb_create_media_graph(&adap->dvb_adap); + ret = dvb_create_media_graph(&adap->dvb_adap, true); if (ret) return ret; -- GitLab From 33c6853347c13b7cf8d11c12714cd855a84bc992 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 29 Dec 2015 16:45:21 -0200 Subject: [PATCH 2608/2855] [media] dvb-usb-v2: postpone removal of media_device We should not remove the media_device until its last usage, or we may have use after free troubles. So, move the per-adapter media_device removal to happen at the end of the adapter removal code. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index e8491f73c0d9a..f0565bf3673e8 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -542,7 +542,6 @@ static int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap) adap->demux.dmx.close(&adap->demux.dmx); dvb_dmxdev_release(&adap->dmxdev); dvb_dmx_release(&adap->demux); - dvb_usbv2_media_device_unregister(adap); dvb_unregister_adapter(&adap->dvb_adap); } @@ -852,6 +851,7 @@ static int dvb_usbv2_adapter_exit(struct dvb_usb_device *d) dvb_usbv2_adapter_dvb_exit(&d->adapter[i]); dvb_usbv2_adapter_stream_exit(&d->adapter[i]); dvb_usbv2_adapter_frontend_exit(&d->adapter[i]); + dvb_usbv2_media_device_unregister(&d->adapter[i]); } } -- GitLab From b01cc9ce7c13e0463575332dfa3171727f706afb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 30 Dec 2015 09:45:48 -0200 Subject: [PATCH 2609/2855] [media] media-entitiy: add a function to create multiple links Sometimes, it is desired to create 1:n and n:1 or even n:n links between different entities with the same function. This is actually needed to support DVB devices that have multiple frontends. While we could do a function like that internally at the DVB core, such function is generic enough to be at media-entity, and it could be useful on some other places. So, add such function. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 65 ++++++++++++++++++++++++++++++++++++ include/media/media-entity.h | 51 ++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index eb38bc35320a8..e89d85a7d31b5 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -625,6 +625,71 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, } EXPORT_SYMBOL_GPL(media_create_pad_link); +int media_create_pad_links(const struct media_device *mdev, + const u32 source_function, + struct media_entity *source, + const u16 source_pad, + const u32 sink_function, + struct media_entity *sink, + const u16 sink_pad, + u32 flags, + const bool allow_both_undefined) +{ + struct media_entity *entity; + unsigned function; + int ret; + + /* Trivial case: 1:1 relation */ + if (source && sink) + return media_create_pad_link(source, source_pad, + sink, sink_pad, flags); + + /* Worse case scenario: n:n relation */ + if (!source && !sink) { + if (!allow_both_undefined) + return 0; + media_device_for_each_entity(source, mdev) { + if (source->function != source_function) + continue; + media_device_for_each_entity(sink, mdev) { + if (sink->function != sink_function) + continue; + ret = media_create_pad_link(source, source_pad, + sink, sink_pad, + flags); + if (ret) + return ret; + flags &= ~(MEDIA_LNK_FL_ENABLED | + MEDIA_LNK_FL_IMMUTABLE); + } + } + return 0; + } + + /* Handle 1:n and n:1 cases */ + if (source) + function = sink_function; + else + function = source_function; + + media_device_for_each_entity(entity, mdev) { + if (entity->function != function) + continue; + + if (source) + ret = media_create_pad_link(source, source_pad, + entity, sink_pad, flags); + else + ret = media_create_pad_link(entity, source_pad, + sink, sink_pad, flags); + if (ret) + return ret; + flags &= ~(MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); + } + return 0; +} +EXPORT_SYMBOL_GPL(media_create_pad_links); + void __media_entity_remove_links(struct media_entity *entity) { struct media_link *link, *tmp; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 79dd81fd463e8..fe485d3679856 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -613,6 +613,57 @@ static inline void media_entity_cleanup(struct media_entity *entity) {}; __must_check int media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags); + +/** + * media_create_pad_links() - creates a link between two entities. + * + * @mdev: Pointer to the media_device that contains the object + * @source_function: Function of the source entities. Used only if @source is + * NULL. + * @source: pointer to &media_entity of the source pad. If NULL, it will use + * all entities that matches the @sink_function. + * @source_pad: number of the source pad in the pads array + * @sink_function: Function of the sink entities. Used only if @sink is NULL. + * @sink: pointer to &media_entity of the sink pad. If NULL, it will use + * all entities that matches the @sink_function. + * @sink_pad: number of the sink pad in the pads array. + * @flags: Link flags, as defined in include/uapi/linux/media.h. + * @allow_both_undefined: if true, then both @source and @sink can be NULL. + * In such case, it will create a crossbar between all entities that + * matches @source_function to all entities that matches @sink_function. + * If false, it will return 0 and won't create any link if both @source + * and @sink are NULL. + * + * Valid values for flags: + * A %MEDIA_LNK_FL_ENABLED flag indicates that the link is enabled and can be + * used to transfer media data. If multiple links are created and this + * flag is passed as an argument, only the first created link will have + * this flag. + * + * A %MEDIA_LNK_FL_IMMUTABLE flag indicates that the link enabled state can't + * be modified at runtime. If %MEDIA_LNK_FL_IMMUTABLE is set, then + * %MEDIA_LNK_FL_ENABLED must also be set since an immutable link is + * always enabled. + * + * It is common for some devices to have multiple source and/or sink entities + * of the same type that should be linked. While media_create_pad_link() + * creates link by link, this function is meant to allow 1:n, n:1 and even + * cross-bar (n:n) links. + * + * NOTE: Before calling this function, media_entity_pads_init() and + * media_device_register_entity() should be called previously for the entities + * to be linked. + */ +int media_create_pad_links(const struct media_device *mdev, + const u32 source_function, + struct media_entity *source, + const u16 source_pad, + const u32 sink_function, + struct media_entity *sink, + const u16 sink_pad, + u32 flags, + const bool allow_both_undefined); + void __media_entity_remove_links(struct media_entity *entity); /** -- GitLab From a0cce2a05756c9308f59c0303afe2c199e0789b0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 30 Dec 2015 10:11:53 -0200 Subject: [PATCH 2610/2855] [media] dvbdev: create links on devices with multiple frontends Devices like mxl111sf-based WinTV Aero-m have multiple frontends, all linked on the same demod. Currently, the dvb_create_graph() function is not smart enough to create multiple links. Fix it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 57 +++++++++++++++++++++++++-------- drivers/media/dvb-core/dvbdev.h | 7 ++++ 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 28e340583edee..560450a0b32a5 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -576,6 +576,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap, struct media_interface *intf; unsigned demux_pad = 0; unsigned dvr_pad = 0; + unsigned ntuner = 0, ndemod = 0; int ret; static const char *connector_name = "Television"; @@ -586,9 +587,11 @@ int dvb_create_media_graph(struct dvb_adapter *adap, switch (entity->function) { case MEDIA_ENT_F_TUNER: tuner = entity; + ntuner++; break; case MEDIA_ENT_F_DTV_DEMOD: demod = entity; + ndemod++; break; case MEDIA_ENT_F_TS_DEMUX: demux = entity; @@ -599,6 +602,18 @@ int dvb_create_media_graph(struct dvb_adapter *adap, } } + /* + * Prepare to signalize to media_create_pad_links() that multiple + * entities of the same type exists and a 1:n or n:1 links need to be + * created. + * NOTE: if both tuner and demod have multiple instances, it is up + * to the caller driver to create such links. + */ + if (ntuner > 1) + tuner = NULL; + if (ndemod > 1) + demod = NULL; + if (create_rf_connector) { conn = kzalloc(sizeof(*conn), GFP_KERNEL); if (!conn) @@ -623,28 +638,44 @@ int dvb_create_media_graph(struct dvb_adapter *adap, if (ret) return ret; - if (!tuner) - ret = media_create_pad_link(conn, 0, - demod, 0, - MEDIA_LNK_FL_ENABLED); + if (!ntuner) + ret = media_create_pad_links(mdev, + MEDIA_ENT_F_CONN_RF, + conn, 0, + MEDIA_ENT_F_DTV_DEMOD, + demod, 0, + MEDIA_LNK_FL_ENABLED, + false); else - ret = media_create_pad_link(conn, 0, - tuner, TUNER_PAD_RF_INPUT, - MEDIA_LNK_FL_ENABLED); + ret = media_create_pad_links(mdev, + MEDIA_ENT_F_CONN_RF, + conn, 0, + MEDIA_ENT_F_TUNER, + tuner, TUNER_PAD_RF_INPUT, + MEDIA_LNK_FL_ENABLED, + false); if (ret) return ret; } - if (tuner && demod) { - ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, - demod, 0, MEDIA_LNK_FL_ENABLED); + if (ntuner && ndemod) { + ret = media_create_pad_links(mdev, + MEDIA_ENT_F_TUNER, + tuner, TUNER_PAD_IF_OUTPUT, + MEDIA_ENT_F_DTV_DEMOD, + demod, 0, MEDIA_LNK_FL_ENABLED, + false); if (ret) return ret; } - if (demod && demux) { - ret = media_create_pad_link(demod, 1, demux, - 0, MEDIA_LNK_FL_ENABLED); + if (ndemod && demux) { + ret = media_create_pad_links(mdev, + MEDIA_ENT_F_DTV_DEMOD, + demod, 1, + MEDIA_ENT_F_TS_DEMUX, + demux, 0, MEDIA_LNK_FL_ENABLED, + false); if (ret) return -ENOMEM; } diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index b622d6a3b95e0..d7c67baa885e3 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h @@ -225,6 +225,13 @@ void dvb_unregister_device(struct dvb_device *dvbdev); * * @adap: pointer to struct dvb_adapter * @create_rf_connector: if true, it creates the RF connector too + * + * This function checks all DVB-related functions at the media controller + * entities and creates the needed links for the media graph. It is + * capable of working with multiple tuners or multiple frontends, but it + * won't create links if the device has multiple tuners and multiple frontends + * or if the device has multiple muxes. In such case, the caller driver should + * manually create the remaining links. */ __must_check int dvb_create_media_graph(struct dvb_adapter *adap, bool create_rf_connector); -- GitLab From ce084d487c8a0731bff5739e735b7bb82b94e53b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 30 Dec 2015 11:09:39 -0200 Subject: [PATCH 2611/2855] [media] mxl111sf: Add a tuner entity While mxl111sf may have multiple frontends, it has just one tuner. Reflect that on the media graph. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.h | 6 ++++++ drivers/media/usb/dvb-usb-v2/mxl111sf.c | 20 ++++++++++++++++++++ drivers/media/usb/dvb-usb-v2/mxl111sf.h | 5 +++++ 3 files changed, 31 insertions(+) diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index d7c67baa885e3..4aff7bd3dea89 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h @@ -242,6 +242,11 @@ static inline void dvb_register_media_controller(struct dvb_adapter *adap, adap->mdev = mdev; } +static inline struct media_device +*dvb_get_media_controller(struct dvb_adapter *adap) +{ + return adap->mdev; +} #else static inline int dvb_create_media_graph(struct dvb_adapter *adap, @@ -250,6 +255,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap, return 0; }; #define dvb_register_media_controller(a, b) {} +#define dvb_get_media_controller(a) NULL #endif int dvb_generic_open (struct inode *inode, struct file *file); diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c index 1710f9038d750..b669deccc34c6 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c @@ -10,6 +10,7 @@ #include #include +#include #include "mxl111sf.h" #include "mxl111sf-reg.h" @@ -868,6 +869,10 @@ static struct mxl111sf_tuner_config mxl_tuner_config = { static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap) { struct mxl111sf_state *state = adap_to_priv(adap); +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + struct media_device *mdev = dvb_get_media_controller(&adap->dvb_adap); + int ret; +#endif int i; pr_debug("%s()\n", __func__); @@ -879,6 +884,21 @@ static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap) adap->fe[i]->ops.read_signal_strength = adap->fe[i]->ops.tuner_ops.get_rf_strength; } +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + state->tuner.function = MEDIA_ENT_F_TUNER; + state->tuner.name = "mxl111sf tuner"; + state->tuner_pads[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK; + state->tuner_pads[TUNER_PAD_IF_OUTPUT].flags = MEDIA_PAD_FL_SOURCE; + + ret = media_entity_pads_init(&state->tuner, + TUNER_NUM_PADS, state->tuner_pads); + if (ret) + return ret; + + ret = media_device_register_entity(mdev, &state->tuner); + if (ret) + return ret; +#endif return 0; } diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.h b/drivers/media/usb/dvb-usb-v2/mxl111sf.h index ee70df1f1e946..846260e0eec02 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf.h +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.h @@ -17,6 +17,7 @@ #define DVB_USB_LOG_PREFIX "mxl111sf" #include "dvb_usb.h" #include +#include #define MXL_EP1_REG_READ 1 #define MXL_EP2_REG_WRITE 2 @@ -85,6 +86,10 @@ struct mxl111sf_state { struct mutex fe_lock; u8 num_frontends; struct mxl111sf_adap_state adap_state[3]; +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + struct media_entity tuner; + struct media_pad tuner_pads[2]; +#endif }; int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data); -- GitLab From be0270ec89e6b9b49de7e533dd1f3a89ad34d205 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Dec 2015 12:03:47 -0200 Subject: [PATCH 2612/2855] [media] Postpone the addition of MEDIA_IOC_G_TOPOLOGY There are a few discussions left with regards to this ioctl: 1) the name of the new structs will contain _v2_ on it? 2) what's the best alternative to avoid compat32 issues? Due to that, let's postpone the addition of this new ioctl to the next Kernel version, to give people more time to discuss it. Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/media-ioc-g-topology.xml | 3 +++ drivers/media/media-device.c | 7 ++++++- include/uapi/linux/media.h | 6 +++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/media/v4l/media-ioc-g-topology.xml b/Documentation/DocBook/media/v4l/media-ioc-g-topology.xml index e0d49fa329f09..63152ab9efbad 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-g-topology.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-g-topology.xml @@ -48,6 +48,9 @@ Description + + NOTE: This new ioctl is programmed to be added on Kernel 4.6. Its definition/arguments may change until its final version. + The typical usage of this ioctl is to call it twice. On the first call, the structure defined at &media-v2-topology; should be zeroed. At return, if no errors happen, this ioctl will return the diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 4d1c13de494bf..7dae0ac0f3aec 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -234,6 +234,7 @@ static long media_device_setup_link(struct media_device *mdev, return ret; } +#if 0 /* Let's postpone it to Kernel 4.6 */ static long __media_device_get_topology(struct media_device *mdev, struct media_v2_topology *topo) { @@ -389,6 +390,7 @@ static long media_device_get_topology(struct media_device *mdev, return 0; } +#endif static long media_device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) @@ -422,13 +424,14 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd, mutex_unlock(&dev->graph_mutex); break; +#if 0 /* Let's postpone it to Kernel 4.6 */ case MEDIA_IOC_G_TOPOLOGY: mutex_lock(&dev->graph_mutex); ret = media_device_get_topology(dev, (struct media_v2_topology __user *)arg); mutex_unlock(&dev->graph_mutex); break; - +#endif default: ret = -ENOIOCTLCMD; } @@ -477,7 +480,9 @@ static long media_device_compat_ioctl(struct file *filp, unsigned int cmd, case MEDIA_IOC_DEVICE_INFO: case MEDIA_IOC_ENUM_ENTITIES: case MEDIA_IOC_SETUP_LINK: +#if 0 /* Let's postpone it to Kernel 4.6 */ case MEDIA_IOC_G_TOPOLOGY: +#endif return media_device_ioctl(filp, cmd, arg); case MEDIA_IOC_ENUM_LINKS32: diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 5dbb208e5451a..1e3c8cb43bd7a 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -286,7 +286,7 @@ struct media_links_enum { * later, before the adding this API upstream. */ - +#if 0 /* Let's postpone it to Kernel 4.6 */ struct media_v2_entity { __u32 id; char name[64]; /* FIXME: move to a property? (RFC says so) */ @@ -351,6 +351,7 @@ static inline void __user *media_get_uptr(__u64 arg) { return (void __user *)(uintptr_t)arg; } +#endif /* ioctls */ @@ -358,6 +359,9 @@ static inline void __user *media_get_uptr(__u64 arg) #define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc) #define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum) #define MEDIA_IOC_SETUP_LINK _IOWR('|', 0x03, struct media_link_desc) + +#if 0 /* Let's postpone it to Kernel 4.6 */ #define MEDIA_IOC_G_TOPOLOGY _IOWR('|', 0x04, struct media_v2_topology) +#endif #endif /* __LINUX_MEDIA_H */ -- GitLab From 2f5a7f1d13df94b753794b69cc4c920f8bfb2128 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 11 Jan 2016 11:54:48 +0100 Subject: [PATCH 2613/2855] tools: Add clean targets for tools directory Adding missing clean targets for following tools directories: lib/bpf lib/subcmd build This are now cleaned via 'make -C tools clean' command. Reported-and-Tested-by: Arnaldo Carvalho de Melo Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1452509693-13452-2-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/Makefile | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/Makefile b/tools/Makefile index 0ba0df3b516f1..4e8e10755e0d8 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -127,6 +127,12 @@ liblockdep_clean: libapi_clean: $(call descend,lib/api,clean) +libbpf_clean: + $(call descend,lib/bpf,clean) + +libsubcmd_clean: + $(call descend,lib/subcmd,clean) + perf_clean: $(call descend,$(@:_clean=),clean) @@ -142,9 +148,12 @@ tmon_clean: freefall_clean: $(call descend,laptop/freefall,clean) +build_clean: + $(call descend,build,clean) + clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean lguest_clean \ perf_clean selftests_clean turbostat_clean usb_clean virtio_clean \ vm_clean net_clean iio_clean x86_energy_perf_policy_clean tmon_clean \ - freefall_clean + freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean .PHONY: FORCE -- GitLab From 22992a320807f8eb04b48407715aacbdedb00941 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 11 Jan 2016 11:54:49 +0100 Subject: [PATCH 2614/2855] tools bpf: Add *.cmd files clean up Add *.cmd files to be removed within clean target. Reported-and-Tested-by: Arnaldo Carvalho de Melo Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1452509693-13452-3-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/bpf/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index 919b717807100..84e0e986ade4b 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile @@ -192,7 +192,7 @@ config-clean: $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null clean: - $(call QUIET_CLEAN, libbpf) $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d \ + $(call QUIET_CLEAN, libbpf) $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d .*.cmd \ $(RM) LIBBPF-CFLAGS $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf -- GitLab From 24ee9b57b95fd4d6d0b89a47c3a8f1b145569d18 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 11 Jan 2016 11:54:50 +0100 Subject: [PATCH 2615/2855] tools lockdep: Add *.cmd files clean up Add *.cmd files to be removed within clean target. Reported-by: Arnaldo Carvalho de Melo Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1452509693-13452-4-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/lockdep/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile index 7e319afac78a0..90d2baeb621a5 100644 --- a/tools/lib/lockdep/Makefile +++ b/tools/lib/lockdep/Makefile @@ -149,7 +149,7 @@ install_lib: all_cmd install: install_lib clean: - $(RM) *.o *~ $(TARGETS) *.a *liblockdep*.so* $(VERSION_FILES) .*.d + $(RM) *.o *~ $(TARGETS) *.a *liblockdep*.so* $(VERSION_FILES) .*.d .*.cmd $(RM) tags TAGS PHONY += force -- GitLab From 3238ba01c235e3e9e12fc7bc6ac3f7d513e26a31 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 11 Jan 2016 11:54:51 +0100 Subject: [PATCH 2616/2855] perf tools: Add missing sources to perf's MANIFEST Adding missing bitmap.[ch] sources to the MANIFEST file. Fixes building 'make perf-*-src-pkg' generated tarballs. Reported-by: Wang Nan Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Fixes: 915b0882c310 ("tools lib: Move bitmap.[ch] from tools/perf/ to tools/{lib,include}/") Link: http://lkml.kernel.org/r/1452509693-13452-5-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/MANIFEST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index ddf922f93aa15..2e1fa2357528a 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST @@ -28,6 +28,7 @@ tools/lib/string.c tools/lib/symbol/kallsyms.c tools/lib/symbol/kallsyms.h tools/lib/find_bit.c +tools/lib/bitmap.c tools/include/asm/atomic.h tools/include/asm/barrier.h tools/include/asm/bug.h @@ -57,6 +58,7 @@ tools/include/linux/rbtree_augmented.h tools/include/linux/string.h tools/include/linux/types.h tools/include/linux/err.h +tools/include/linux/bitmap.h include/asm-generic/bitops/arch_hweight.h include/asm-generic/bitops/const_hweight.h include/asm-generic/bitops/fls64.h -- GitLab From 863ee050726b67db82869e8e4221a7385a28b067 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sat, 2 Jan 2016 23:06:36 +0100 Subject: [PATCH 2617/2855] clocksource/drivers: Fix dependencies for !HAS_IOMEM archs Not every arch has io memory. So, unbreak the build by fixing the dependencies. Signed-off-by: Richard Weinberger Signed-off-by: Daniel Lezcano --- drivers/clocksource/Kconfig | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index b251013eef0a9..796efbe7bea56 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -152,7 +152,7 @@ config CLKSRC_EFM32 config CLKSRC_LPC32XX bool "Clocksource for LPC32XX" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS + depends on GENERIC_CLOCKEVENTS && HAS_IOMEM select CLKSRC_MMIO select CLKSRC_OF help @@ -160,6 +160,7 @@ config CLKSRC_LPC32XX config CLKSRC_PISTACHIO bool "Clocksource for Pistachio SoC" if COMPILE_TEST + depends on HAS_IOMEM select CLKSRC_OF help Enables the clocksource for the Pistachio SoC. @@ -269,7 +270,7 @@ config SYS_SUPPORTS_SH_CMT config MTK_TIMER bool "Mediatek timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS + depends on GENERIC_CLOCKEVENTS && HAS_IOMEM select CLKSRC_OF select CLKSRC_MMIO help @@ -365,20 +366,20 @@ config CLKSRC_PXA config H8300_TMR8 bool "Clockevent timer for the H8300 platform" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS + depends on GENERIC_CLOCKEVENTS && HAS_IOMEM help This enables the 8 bits timer for the H8300 platform. config H8300_TMR16 bool "Clockevent timer for the H83069 platform" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS + depends on GENERIC_CLOCKEVENTS && HAS_IOMEM help This enables the 16 bits timer for the H8300 platform with the H83069 cpu. config H8300_TPU bool "Clocksource for the H8300 platform" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS + depends on GENERIC_CLOCKEVENTS && HAS_IOMEM help This enables the clocksource for the H8300 platform with the H8S2678 cpu. @@ -391,6 +392,7 @@ config CLKSRC_IMX_GPT config CLKSRC_ST_LPC bool "Low power clocksource found in the LPC" if COMPILE_TEST select CLKSRC_OF if OF + depends on HAS_IOMEM help Enable this option to use the Low Power controller timer as clocksource. -- GitLab From 03724ac3d48f8f0e3caf1d30fa134f8fd96c94e2 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Fri, 8 Jan 2016 14:21:31 +0100 Subject: [PATCH 2618/2855] clocksource/drivers/fsl_ftm_timer: Fix CLKSRC_MMIO dependency Select CLKSRC_MMIO when FSL_FTM_TIMER is enabled. Otherwise it fails to compile on i386 with COMPILE_TEST=y. " on i386: when CLKSRC_MMIO is not enabled: drivers/built-in.o: In function `ftm_timer_init': fsl_ftm_timer.c:(.init.text+0x6842): undefined reference to `clocksource_mmio_readl_up' fsl_ftm_timer.c:(.init.text+0x6855): undefined reference to `clocksource_mmio_init' " Reported-by: Randy Dunlap Signed-off-by: Daniel Lezcano --- drivers/clocksource/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 796efbe7bea56..56777f04d2d96 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -257,6 +257,7 @@ config CLKSRC_SAMSUNG_PWM config FSL_FTM_TIMER bool "Freescale FlexTimer Module driver" if COMPILE_TEST depends on GENERIC_CLOCKEVENTS + select CLKSRC_MMIO help Support for Freescale FlexTimer Module (FTM) timer. -- GitLab From b79f4a1c68bb99152d0785ee4ea3ab4396cdacc6 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 12 Jan 2016 07:03:44 +1100 Subject: [PATCH 2619/2855] xfs: inode recovery readahead can race with inode buffer creation When we do inode readahead in log recovery, we do can do the readahead before we've replayed the icreate transaction that stamps the buffer with inode cores. The inode readahead verifier catches this and marks the buffer as !done to indicate that it doesn't yet contain valid inodes. In adding buffer error notification (i.e. setting b_error = -EIO at the same time as as we clear the done flag) to such a readahead verifier failure, we can then get subsequent inode recovery failing with this error: XFS (dm-0): metadata I/O error: block 0xa00060 ("xlog_recover_do..(read#2)") error 5 numblks 32 This occurs when readahead completion races with icreate item replay such as: inode readahead find buffer lock buffer submit RA io .... icreate recovery xfs_trans_get_buffer find buffer lock buffer ..... fails verifier clear XBF_DONE set bp->b_error = -EIO release and unlock buffer icreate initialises buffer marks buffer as done adds buffer to delayed write queue releases buffer At this point, we have an initialised inode buffer that is up to date but has an -EIO state registered against it. When we finally get to recovering an inode in that buffer: inode item recovery xfs_trans_read_buffer find buffer lock buffer sees XBF_DONE is set, returns buffer sees bp->b_error is set fail log recovery! Essentially, we need xfs_trans_get_buf_map() to clear the error status of the buffer when doing a lookup. This function returns uninitialised buffers, so the buffer returned can not be in an error state and none of the code that uses this function expects b_error to be set on return. Indeed, there is an ASSERT(!bp->b_error); in the transaction case in xfs_trans_get_buf_map() that would have caught this if log recovery used transactions.... This patch firstly changes the inode readahead failure to set -EIO on the buffer, and secondly changes xfs_buf_get_map() to never return a buffer with an error state set so this first change doesn't cause unexpected log recovery failures. cc: # 3.12 - current Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_inode_buf.c | 12 +++++++----- fs/xfs/xfs_buf.c | 7 +++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index 1b8d98a915c42..ff17c48e7ed32 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -62,11 +62,12 @@ xfs_inobp_check( * has not had the inode cores stamped into it. Hence for readahead, the buffer * may be potentially invalid. * - * If the readahead buffer is invalid, we don't want to mark it with an error, - * but we do want to clear the DONE status of the buffer so that a followup read - * will re-read it from disk. This will ensure that we don't get an unnecessary - * warnings during log recovery and we don't get unnecssary panics on debug - * kernels. + * If the readahead buffer is invalid, we need to mark it with an error and + * clear the DONE status of the buffer so that a followup read will re-read it + * from disk. We don't report the error otherwise to avoid warnings during log + * recovery and we don't get unnecssary panics on debug kernels. We use EIO here + * because all we want to do is say readahead failed; there is no-one to report + * the error to, so this will distinguish it from a non-ra verifier failure. */ static void xfs_inode_buf_verify( @@ -93,6 +94,7 @@ xfs_inode_buf_verify( XFS_RANDOM_ITOBP_INOTOBP))) { if (readahead) { bp->b_flags &= ~XBF_DONE; + xfs_buf_ioerror(bp, -EIO); return; } diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 45a8ea7cfdb20..ae86b16f9025c 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -604,6 +604,13 @@ found: } } + /* + * Clear b_error if this is a lookup from a caller that doesn't expect + * valid data to be found in the buffer. + */ + if (!(flags & XBF_READ)) + xfs_buf_ioerror(bp, 0); + XFS_STATS_INC(target->bt_mount, xb_get); trace_xfs_buf_get(bp, flags, _RET_IP_); return bp; -- GitLab From 7d6a13f023567d573ac362502bb702eda716e654 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 12 Jan 2016 07:04:01 +1100 Subject: [PATCH 2620/2855] xfs: handle dquot buffer readahead in log recovery correctly When we do dquot readahead in log recovery, we do not use a verifier as the underlying buffer may not have dquots in it. e.g. the allocation operation hasn't yet been replayed. Hence we do not want to fail recovery because we detect an operation to be replayed has not been run yet. This problem was addressed for inodes in commit d891400 ("xfs: inode buffers may not be valid during recovery readahead") but the problem was not recognised to exist for dquots and their buffers as the dquot readahead did not have a verifier. The result of not using a verifier is that when the buffer is then next read to replay a dquot modification, the dquot buffer verifier will only be attached to the buffer if *readahead is not complete*. Hence we can read the buffer, replay the dquot changes and then add it to the delwri submission list without it having a verifier attached to it. This then generates warnings in xfs_buf_ioapply(), which catches and warns about this case. Fix this and make it handle the same readahead verifier error cases as for inode buffers by adding a new readahead verifier that has a write operation as well as a read operation that marks the buffer as not done if any corruption is detected. Also make sure we don't run readahead if the dquot buffer has been marked as cancelled by recovery. This will result in readahead either succeeding and the buffer having a valid write verifier, or readahead failing and the buffer state requiring the subsequent read to resubmit the IO with the new verifier. In either case, this will result in the buffer always ending up with a valid write verifier on it. Note: we also need to fix the inode buffer readahead error handling to mark the buffer with EIO. Brian noticed the code I copied from there wrong during review, so fix it at the same time. Add comments linking the two functions that handle readahead verifier errors together so we don't forget this behavioural link in future. cc: # 3.12 - current Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_dquot_buf.c | 36 ++++++++++++++++++++++++++++------ fs/xfs/libxfs/xfs_inode_buf.c | 2 ++ fs/xfs/libxfs/xfs_quota_defs.h | 2 +- fs/xfs/libxfs/xfs_shared.h | 1 + fs/xfs/xfs_log_recover.c | 9 +++++++-- 5 files changed, 41 insertions(+), 9 deletions(-) diff --git a/fs/xfs/libxfs/xfs_dquot_buf.c b/fs/xfs/libxfs/xfs_dquot_buf.c index 11cefb2a372a8..3cc3cf7674746 100644 --- a/fs/xfs/libxfs/xfs_dquot_buf.c +++ b/fs/xfs/libxfs/xfs_dquot_buf.c @@ -54,7 +54,7 @@ xfs_dqcheck( xfs_dqid_t id, uint type, /* used only when IO_dorepair is true */ uint flags, - char *str) + const char *str) { xfs_dqblk_t *d = (xfs_dqblk_t *)ddq; int errs = 0; @@ -207,7 +207,8 @@ xfs_dquot_buf_verify_crc( STATIC bool xfs_dquot_buf_verify( struct xfs_mount *mp, - struct xfs_buf *bp) + struct xfs_buf *bp, + int warn) { struct xfs_dqblk *d = (struct xfs_dqblk *)bp->b_addr; xfs_dqid_t id = 0; @@ -240,8 +241,7 @@ xfs_dquot_buf_verify( if (i == 0) id = be32_to_cpu(ddq->d_id); - error = xfs_dqcheck(mp, ddq, id + i, 0, XFS_QMOPT_DOWARN, - "xfs_dquot_buf_verify"); + error = xfs_dqcheck(mp, ddq, id + i, 0, warn, __func__); if (error) return false; } @@ -256,13 +256,32 @@ xfs_dquot_buf_read_verify( if (!xfs_dquot_buf_verify_crc(mp, bp)) xfs_buf_ioerror(bp, -EFSBADCRC); - else if (!xfs_dquot_buf_verify(mp, bp)) + else if (!xfs_dquot_buf_verify(mp, bp, XFS_QMOPT_DOWARN)) xfs_buf_ioerror(bp, -EFSCORRUPTED); if (bp->b_error) xfs_verifier_error(bp); } +/* + * readahead errors are silent and simply leave the buffer as !done so a real + * read will then be run with the xfs_dquot_buf_ops verifier. See + * xfs_inode_buf_verify() for why we use EIO and ~XBF_DONE here rather than + * reporting the failure. + */ +static void +xfs_dquot_buf_readahead_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + + if (!xfs_dquot_buf_verify_crc(mp, bp) || + !xfs_dquot_buf_verify(mp, bp, 0)) { + xfs_buf_ioerror(bp, -EIO); + bp->b_flags &= ~XBF_DONE; + } +} + /* * we don't calculate the CRC here as that is done when the dquot is flushed to * the buffer after the update is done. This ensures that the dquot in the @@ -274,7 +293,7 @@ xfs_dquot_buf_write_verify( { struct xfs_mount *mp = bp->b_target->bt_mount; - if (!xfs_dquot_buf_verify(mp, bp)) { + if (!xfs_dquot_buf_verify(mp, bp, XFS_QMOPT_DOWARN)) { xfs_buf_ioerror(bp, -EFSCORRUPTED); xfs_verifier_error(bp); return; @@ -287,3 +306,8 @@ const struct xfs_buf_ops xfs_dquot_buf_ops = { .verify_write = xfs_dquot_buf_write_verify, }; +const struct xfs_buf_ops xfs_dquot_buf_ra_ops = { + .name = "xfs_dquot_ra", + .verify_read = xfs_dquot_buf_readahead_verify, + .verify_write = xfs_dquot_buf_write_verify, +}; diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index ff17c48e7ed32..1aabfda669b0b 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -68,6 +68,8 @@ xfs_inobp_check( * recovery and we don't get unnecssary panics on debug kernels. We use EIO here * because all we want to do is say readahead failed; there is no-one to report * the error to, so this will distinguish it from a non-ra verifier failure. + * Changes to this readahead error behavour also need to be reflected in + * xfs_dquot_buf_readahead_verify(). */ static void xfs_inode_buf_verify( diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h index 1b0a08379759d..f51078f1e92ad 100644 --- a/fs/xfs/libxfs/xfs_quota_defs.h +++ b/fs/xfs/libxfs/xfs_quota_defs.h @@ -153,7 +153,7 @@ typedef __uint16_t xfs_qwarncnt_t; #define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS) extern int xfs_dqcheck(struct xfs_mount *mp, xfs_disk_dquot_t *ddq, - xfs_dqid_t id, uint type, uint flags, char *str); + xfs_dqid_t id, uint type, uint flags, const char *str); extern int xfs_calc_dquots_per_chunk(unsigned int nbblks); #endif /* __XFS_QUOTA_H__ */ diff --git a/fs/xfs/libxfs/xfs_shared.h b/fs/xfs/libxfs/xfs_shared.h index 5be529707903f..15c3ceb845b91 100644 --- a/fs/xfs/libxfs/xfs_shared.h +++ b/fs/xfs/libxfs/xfs_shared.h @@ -49,6 +49,7 @@ extern const struct xfs_buf_ops xfs_inobt_buf_ops; extern const struct xfs_buf_ops xfs_inode_buf_ops; extern const struct xfs_buf_ops xfs_inode_buf_ra_ops; extern const struct xfs_buf_ops xfs_dquot_buf_ops; +extern const struct xfs_buf_ops xfs_dquot_buf_ra_ops; extern const struct xfs_buf_ops xfs_sb_buf_ops; extern const struct xfs_buf_ops xfs_sb_quiet_buf_ops; extern const struct xfs_buf_ops xfs_symlink_buf_ops; diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index c5ecaacdd2183..5991cdcb90409 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -3204,6 +3204,7 @@ xlog_recover_dquot_ra_pass2( struct xfs_disk_dquot *recddq; struct xfs_dq_logformat *dq_f; uint type; + int len; if (mp->m_qflags == 0) @@ -3224,8 +3225,12 @@ xlog_recover_dquot_ra_pass2( ASSERT(dq_f); ASSERT(dq_f->qlf_len == 1); - xfs_buf_readahead(mp->m_ddev_targp, dq_f->qlf_blkno, - XFS_FSB_TO_BB(mp, dq_f->qlf_len), NULL); + len = XFS_FSB_TO_BB(mp, dq_f->qlf_len); + if (xlog_peek_buffer_cancelled(log, dq_f->qlf_blkno, len, 0)) + return; + + xfs_buf_readahead(mp->m_ddev_targp, dq_f->qlf_blkno, len, + &xfs_dquot_buf_ra_ops); } STATIC void -- GitLab From f9eccf24615672896dc13251410c3f2f33a14f95 Mon Sep 17 00:00:00 2001 From: Roman Volkov Date: Fri, 1 Jan 2016 16:24:41 +0300 Subject: [PATCH 2621/2855] clocksource/drivers/vt8500: Increase the minimum delta The vt8500 clocksource driver declares itself as capable to handle the minimum delay of 4 cycles by passing the value into clockevents_config_and_register(). The vt8500_timer_set_next_event() requires the passed cycles value to be at least 16. The impact is that userspace hangs in nanosleep() calls with small delay intervals. This problem is reproducible in Linux 4.2 starting from: c6eb3f70d448 ('hrtimer: Get rid of hrtimer softirq') From Russell King, more detailed explanation: "It's a speciality of the StrongARM/PXA hardware. It takes a certain number of OSCR cycles for the value written to hit the compare registers. So, if a very small delta is written (eg, the compare register is written with a value of OSCR + 1), the OSCR will have incremented past this value before it hits the underlying hardware. The result is, that you end up waiting a very long time for the OSCR to wrap before the event fires. So, we introduce a check in set_next_event() to detect this and return -ETIME if the calculated delta is too small, which causes the generic clockevents code to retry after adding the min_delta specified in clockevents_config_and_register() to the current time value. min_delta must be sufficient that we don't re-trip the -ETIME check - if we do, we will return -ETIME, forward the next event time, try to set it, return -ETIME again, and basically lock the system up. So, min_delta must be larger than the check inside set_next_event(). A factor of two was chosen to ensure that this situation would never occur. The PXA code worked on PXA systems for years, and I'd suggest no one changes this mechanism without access to a wide range of PXA systems, otherwise they're risking breakage." Cc: stable@vger.kernel.org Cc: Russell King Acked-by: Alexey Charkov Signed-off-by: Roman Volkov Signed-off-by: Daniel Lezcano --- drivers/clocksource/vt8500_timer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/vt8500_timer.c b/drivers/clocksource/vt8500_timer.c index a92e94b40b5b0..dfc3bb410b00f 100644 --- a/drivers/clocksource/vt8500_timer.c +++ b/drivers/clocksource/vt8500_timer.c @@ -50,6 +50,8 @@ #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) +#define MIN_OSCR_DELTA 16 + static void __iomem *regbase; static cycle_t vt8500_timer_read(struct clocksource *cs) @@ -80,7 +82,7 @@ static int vt8500_timer_set_next_event(unsigned long cycles, cpu_relax(); writel((unsigned long)alarm, regbase + TIMER_MATCH_VAL); - if ((signed)(alarm - clocksource.read(&clocksource)) <= 16) + if ((signed)(alarm - clocksource.read(&clocksource)) <= MIN_OSCR_DELTA) return -ETIME; writel(1, regbase + TIMER_IER_VAL); @@ -151,7 +153,7 @@ static void __init vt8500_timer_init(struct device_node *np) pr_err("%s: setup_irq failed for %s\n", __func__, clockevent.name); clockevents_config_and_register(&clockevent, VT8500_TIMER_HZ, - 4, 0xf0000000); + MIN_OSCR_DELTA * 2, 0xf0000000); } CLOCKSOURCE_OF_DECLARE(vt8500, "via,vt8500-timer", vt8500_timer_init); -- GitLab From 11dc0c57ba8a935dec5a3240370941a4380721c4 Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Mon, 11 Jan 2016 13:47:52 +0000 Subject: [PATCH 2622/2855] perf tools: Add -lutil in python lib list for broken python-config On some system the perf-config is broken, causes link failure like this: /usr/lib64/python2.7/config/libpython2.7.a(posixmodule.o): In function `posix_forkpty': /opt/wangnan/yocto-build/tmp-eglibc/work/x86_64-oe-linux/python/2.7.3-r0.3.1/Python-2.7.3/./Modules/posixmodule.c:3816: undefined reference to `forkpty' /usr/lib64/python2.7/config/libpython2.7.a(posixmodule.o): In function `posix_openpty': /opt/wangnan/yocto-build/tmp-eglibc/work/x86_64-oe-linux/python/2.7.3-r0.3.1/Python-2.7.3/./Modules/posixmodule.c:3756: undefined reference to `openpty' collect2: error: ld returned 1 exit status make[1]: *** [/home/wangnan/kernel-hydrogen/tools/perf/out/perf] Error 1 make: *** [all] Error 2 $ python-config --libs -lpthread -ldl -lpthread -lutil -lm -lpython2.7 In this case a '-lutil' should be appended to -lpython2.7. (I know we have --start-group and --end-group. I can see them in command line of collect2 by strace. However it doesn't work. Seems I have a broken environment?) Signed-off-by: Wang Nan Cc: Jiri Olsa Cc: Namhyung Kim Cc: Zefan Li Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1452520124-2073-2-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/config/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 254d06e39bea8..0793c7654858c 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -493,7 +493,7 @@ else PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null) PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS)) - PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) + PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) -lutil PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) -- GitLab From 3167eea27b27b29d375ee6b34dd83035c04d5da8 Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Mon, 11 Jan 2016 13:47:53 +0000 Subject: [PATCH 2623/2855] perf tools: Fix phony build target for build-test make_kernelsrc and make_kernelsrc_tools are skiped if a previous build-test is done, because 'make build-test' creates two files with same names. To avoid this, they should be included in .PHONY list. Signed-off-by: Wang Nan Acked-by: Jiri Olsa Cc: Namhyung Kim Cc: Zefan Li Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1452520124-2073-3-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/make | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/make b/tools/perf/tests/make index c1fbb8e884c0f..130be7c888249 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make @@ -280,5 +280,5 @@ all: $(run) $(run_O) tarpkg make_kernelsrc make_kernelsrc_tools out: $(run_O) @echo OK -.PHONY: all $(run) $(run_O) tarpkg clean +.PHONY: all $(run) $(run_O) tarpkg clean make_kernelsrc make_kernelsrc_tools endif # ifndef MK -- GitLab From 8f9e05fb298f16c0cda2e7e78b603331a79f9c10 Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Mon, 11 Jan 2016 13:47:57 +0000 Subject: [PATCH 2624/2855] perf tools: Fix PowerPC native building Checks BPF syscall number, turn off libbpf building on platform doesn't correctly support sys_bpf instead of blocking compiling. Reported-and-Tested-by: Naveen N. Rao Signed-off-by: Wang Nan Acked-by: Jiri Olsa Cc: Sukadev Bhattiprolu Cc: Zefan Li Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1452520124-2073-7-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/build/feature/test-bpf.c | 20 +++++++++++++++++++- tools/lib/bpf/bpf.c | 4 ++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/tools/build/feature/test-bpf.c b/tools/build/feature/test-bpf.c index 062bac811af96..b389026839b97 100644 --- a/tools/build/feature/test-bpf.c +++ b/tools/build/feature/test-bpf.c @@ -1,9 +1,23 @@ +#include #include +#include + +#ifndef __NR_bpf +# if defined(__i386__) +# define __NR_bpf 357 +# elif defined(__x86_64__) +# define __NR_bpf 321 +# elif defined(__aarch64__) +# define __NR_bpf 280 +# error __NR_bpf not defined. libbpf does not support your arch. +# endif +#endif int main(void) { union bpf_attr attr; + /* Check fields in attr */ attr.prog_type = BPF_PROG_TYPE_KPROBE; attr.insn_cnt = 0; attr.insns = 0; @@ -14,5 +28,9 @@ int main(void) attr.kern_version = 0; attr = attr; - return 0; + /* + * Test existence of __NR_bpf and BPF_PROG_LOAD. + * This call should fail if we run the testcase. + */ + return syscall(__NR_bpf, BPF_PROG_LOAD, attr, sizeof(attr)); } diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index 5bdc6eab6852b..1f91cc941b7c2 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c @@ -14,8 +14,8 @@ #include "bpf.h" /* - * When building perf, unistd.h is override. Define __NR_bpf is - * required to be defined. + * When building perf, unistd.h is overrided. __NR_bpf is + * required to be defined explicitly. */ #ifndef __NR_bpf # if defined(__i386__) -- GitLab From 935e6bd310f20d3371ae6bd6f01dd3430a4123b6 Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Mon, 11 Jan 2016 13:47:58 +0000 Subject: [PATCH 2625/2855] tools: Move Makefile.arch from perf/config to tools/scripts After this patch other directories can use this architecture detector without directly including it from perf's directory. Libbpf would utilize it to get proper $(ARCH) so it can receive correct uapi include directory. Tested-by: Naveen N. Rao Acked-by: Jiri Olsa Cc: Sukadev Bhattiprolu Cc: Zefan Li Cc: pi3orama@163.com Signed-off-by: Wang Nan Link: http://lkml.kernel.org/r/1452520124-2073-8-git-send-email-wangnan0@huawei.com [ Add missing srctree definition in tests/make ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/config/Makefile | 2 +- tools/perf/tests/make | 16 +++++++++++++++- tools/{perf/config => scripts}/Makefile.arch | 0 3 files changed, 16 insertions(+), 2 deletions(-) rename tools/{perf/config => scripts}/Makefile.arch (100%) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 0793c7654858c..7545ba60053e8 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -17,7 +17,7 @@ detected_var = $(shell echo "$(1)=$($(1))" >> $(OUTPUT).config-detected) CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS) -include $(src-perf)/config/Makefile.arch +include $(srctree)/tools/scripts/Makefile.arch $(call detected_var,ARCH) diff --git a/tools/perf/tests/make b/tools/perf/tests/make index 130be7c888249..df38decc48c32 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make @@ -1,3 +1,5 @@ +include ../scripts/Makefile.include + ifndef MK ifeq ($(MAKECMDGOALS),) # no target specified, trigger the whole suite @@ -12,7 +14,19 @@ endif else PERF := . -include config/Makefile.arch +# As per kernel Makefile, avoid funny character set dependencies +unexport LC_ALL +LC_COLLATE=C +LC_NUMERIC=C +export LC_COLLATE LC_NUMERIC + +ifeq ($(srctree),) +srctree := $(patsubst %/,%,$(dir $(shell pwd))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +#$(info Determined 'srctree' to be $(srctree)) +endif + +include $(srctree)/tools/scripts/Makefile.arch # FIXME looks like x86 is the only arch running tests ;-) # we need some IS_(32/64) flag to make this generic diff --git a/tools/perf/config/Makefile.arch b/tools/scripts/Makefile.arch similarity index 100% rename from tools/perf/config/Makefile.arch rename to tools/scripts/Makefile.arch -- GitLab From d5ef3140351450d240f864208317f5665e7bbd1c Mon Sep 17 00:00:00 2001 From: "Naveen N. Rao" Date: Mon, 11 Jan 2016 13:48:00 +0000 Subject: [PATCH 2626/2855] perf bpf: Fix build breakage due to libbpf perf build is currently (v4.4-rc5) broken on powerpc: bpf.c:28:4: error: #error __NR_bpf not defined. libbpf does not support your arch. # error __NR_bpf not defined. libbpf does not support your arch. ^ Fix this by including tools/scripts/Makefile.arch for the proper $ARCH macro. While at it, remove redundant LP64 macro definition. Also, since libbpf require $(srctree) now, detect the path of srctree like perf. Signed-off-by: Naveen N. Rao Acked-by: Jiri Olsa Cc: Sukadev Bhattiprolu Cc: Wang Nan Cc: Zefan Li Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1452520124-2073-10-git-send-email-wangnan0@huawei.com [Use tools/scripts/Makefile.arch] Signed-off-by: Wang Nan Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/bpf/Makefile | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index 84e0e986ade4b..fc1bc75ae56d4 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile @@ -6,6 +6,12 @@ BPF_EXTRAVERSION = 1 MAKEFLAGS += --no-print-directory +ifeq ($(srctree),) +srctree := $(patsubst %/,%,$(dir $(shell pwd))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +#$(info Determined 'srctree' to be $(srctree)) +endif # Makefiles suck: This macro sets a default value of $(2) for the # variable named by $(1), unless the variable has been set by @@ -31,7 +37,8 @@ INSTALL = install DESTDIR ?= DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' -LP64 := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1) +include $(srctree)/tools/scripts/Makefile.arch + ifeq ($(LP64), 1) libdir_relative = lib64 else @@ -57,13 +64,6 @@ ifndef VERBOSE VERBOSE = 0 endif -ifeq ($(srctree),) -srctree := $(patsubst %/,%,$(dir $(shell pwd))) -srctree := $(patsubst %/,%,$(dir $(srctree))) -srctree := $(patsubst %/,%,$(dir $(srctree))) -#$(info Determined 'srctree' to be $(srctree)) -endif - FEATURE_USER = .libbpf FEATURE_TESTS = libelf libelf-getphdrnum libelf-mmap bpf FEATURE_DISPLAY = libelf bpf -- GitLab From 0c4d40d580752dd7d639208782f71e317b16be67 Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Mon, 11 Jan 2016 13:48:01 +0000 Subject: [PATCH 2627/2855] tools build: Add BPF feature check to test-all The test-all.c file doesn't check BPF related features. For an environment with all other features enabled, BPF would be considered enabled without doing real feature check. This patch adds test-bpf.c into test-all.c. Signed-off-by: Wang Nan Acked-by: Jiri Olsa Cc: Namhyung Kim Cc: Zefan Li Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1452520124-2073-11-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/build/feature/test-all.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c index 33cf6f20bd4ec..81025cade45fa 100644 --- a/tools/build/feature/test-all.c +++ b/tools/build/feature/test-all.c @@ -125,6 +125,10 @@ # include "test-get_cpuid.c" #undef main +#define main main_test_bpf +# include "test-bpf.c" +#undef main + int main(int argc, char *argv[]) { main_test_libpython(); @@ -153,6 +157,7 @@ int main(int argc, char *argv[]) main_test_pthread_attr_setaffinity_np(); main_test_lzma(); main_test_get_cpuid(); + main_test_bpf(); return 0; } -- GitLab From 71b3ee7e65ffb48135d875d9c36e3183b9ecffeb Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Mon, 11 Jan 2016 13:48:02 +0000 Subject: [PATCH 2628/2855] perf test: Fix false TEST_OK result for 'perf test hist' Commit 71d6de64fedd ("perf test: Fix hist testcases when kptr_restrict is on") solves a double free problem when 'perf test hist' calling setup_fake_machine(). However, the result is still incorrect. For example: $ ./perf test -v 'filtering hist entries' 25: Test filtering hist entries : --- start --- test child forked, pid 4186 Cannot create kernel maps test child finished with 0 ---- end ---- Test filtering hist entries: Ok In this case the body of this test is not get executed at all, but the result is 'Ok'. Actually, in setup_fake_machine() there's no need to create real kernel maps. What we want are the fake maps. This patch removes the machine__create_kernel_maps() in setup_fake_machine(), so it won't be affected by kptr_restrict setting. Test result: $ cat /proc/sys/kernel/kptr_restrict 1 $ ~/perf test -v hist 15: Test matching and linking multiple hists : --- start --- test child forked, pid 24031 test child finished with 0 ---- end ---- Test matching and linking multiple hists: Ok [SNIP] Suggested-and-Acked-by: Namhyung Kim Signed-off-by: Wang Nan Tested-by: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Zefan Li Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1452520124-2073-12-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/hists_common.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c index bcfd081ee1d22..071a8b5f5232f 100644 --- a/tools/perf/tests/hists_common.c +++ b/tools/perf/tests/hists_common.c @@ -87,11 +87,6 @@ struct machine *setup_fake_machine(struct machines *machines) return NULL; } - if (machine__create_kernel_maps(machine)) { - pr_debug("Cannot create kernel maps\n"); - return NULL; - } - for (i = 0; i < ARRAY_SIZE(fake_threads); i++) { struct thread *thread; -- GitLab From b0500c169b4069e40f03391c7280cd6eaf849e49 Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Mon, 11 Jan 2016 13:48:03 +0000 Subject: [PATCH 2629/2855] perf test: Reset err after using it hold errcode in hist testcases All hists test cases forget to reset err after using it to hold an error code. If error occure in setup_fake_machine() it incorrectly return TEST_OK. This patch fixes it. Suggested-and-Acked-by: Namhyung Kim Signed-off-by: Wang Nan Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Zefan Li Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1452520124-2073-13-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/hists_cumulate.c | 1 + tools/perf/tests/hists_filter.c | 1 + tools/perf/tests/hists_link.c | 1 + tools/perf/tests/hists_output.c | 1 + 4 files changed, 4 insertions(+) diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index e360892120618..5e6a86e50fb97 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -706,6 +706,7 @@ int test__hists_cumulate(int subtest __maybe_unused) err = parse_events(evlist, "cpu-clock", NULL); if (err) goto out; + err = TEST_FAIL; machines__init(&machines); diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index 2a784befd9ce5..351a42463444a 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -120,6 +120,7 @@ int test__hists_filter(int subtest __maybe_unused) err = parse_events(evlist, "task-clock", NULL); if (err) goto out; + err = TEST_FAIL; /* default sort order (comm,dso,sym) will be used */ if (setup_sorting(NULL) < 0) diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index c764d69ac6ef3..64b257d8d5576 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -293,6 +293,7 @@ int test__hists_link(int subtest __maybe_unused) if (err) goto out; + err = TEST_FAIL; /* default sort order (comm,dso,sym) will be used */ if (setup_sorting(NULL) < 0) goto out; diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index ebe6cd485b5d8..b231265148d89 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -597,6 +597,7 @@ int test__hists_output(int subtest __maybe_unused) err = parse_events(evlist, "cpu-clock", NULL); if (err) goto out; + err = TEST_FAIL; machines__init(&machines); -- GitLab From 6beceb5427aa8731f958d2484e0fd8ff21d604dc Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 8 Jan 2016 15:51:50 -0800 Subject: [PATCH 2630/2855] f2fs: introduce time and interval facility This patch adds time and interval arrays to store some timing variables. Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 2 +- fs/f2fs/f2fs.h | 21 ++++++++++++++++++++- fs/f2fs/segment.c | 2 +- fs/f2fs/super.c | 7 +++---- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 5dbafd5e83d9e..3842af954cd5b 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -1139,7 +1139,7 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) "checkpoint: version = %llx", ckpt_ver); /* do checkpoint periodically */ - sbi->cp_expires = round_jiffies_up(jiffies + HZ * sbi->cp_interval); + f2fs_update_time(sbi, CP_TIME); trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint"); out: mutex_unlock(&sbi->cp_mutex); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index ae0007df6c2cd..5bbb6a407e79f 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -721,6 +721,11 @@ enum { SBI_POR_DOING, /* recovery is doing or not */ }; +enum { + CP_TIME, + MAX_TIME, +}; + struct f2fs_sb_info { struct super_block *sb; /* pointer to VFS super block */ struct proc_dir_entry *s_proc; /* proc entry */ @@ -747,7 +752,8 @@ struct f2fs_sb_info { struct rw_semaphore node_write; /* locking node writes */ struct mutex writepages; /* mutex for writepages() */ wait_queue_head_t cp_wait; - long cp_expires, cp_interval; /* next expected periodic cp */ + unsigned long last_time[MAX_TIME]; /* to store time in jiffies */ + long interval_time[MAX_TIME]; /* to store thresholds */ struct inode_management im[MAX_INO_ENTRY]; /* manage inode cache */ @@ -837,6 +843,19 @@ struct f2fs_sb_info { unsigned int shrinker_run_no; }; +static inline void f2fs_update_time(struct f2fs_sb_info *sbi, int type) +{ + sbi->last_time[type] = jiffies; +} + +static inline bool f2fs_time_over(struct f2fs_sb_info *sbi, int type) +{ + struct timespec ts = {sbi->interval_time[type], 0}; + unsigned long interval = timespec_to_jiffies(&ts); + + return time_after(jiffies, sbi->last_time[type] + interval); +} + /* * Inline functions */ diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index c7bbc915d9627..fed23d5a7b343 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -293,7 +293,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi) if (!available_free_memory(sbi, NAT_ENTRIES) || excess_prefree_segs(sbi) || !available_free_memory(sbi, INO_ENTRIES) || - jiffies > sbi->cp_expires) { + f2fs_time_over(sbi, CP_TIME)) { if (test_opt(sbi, DATA_FLUSH)) sync_dirty_inodes(sbi, FILE_INODE); f2fs_sync_fs(sbi->sb, true); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index f5cc790646e29..787047f59c007 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -218,7 +218,7 @@ F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh); F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level); -F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, cp_interval); +F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]); #define ATTR_LIST(name) (&f2fs_attr_##name.attr) static struct attribute *f2fs_attrs[] = { @@ -1122,7 +1122,7 @@ static void init_sb_info(struct f2fs_sb_info *sbi) atomic_set(&sbi->nr_pages[i], 0); sbi->dir_level = DEF_DIR_LEVEL; - sbi->cp_interval = DEF_CP_INTERVAL; + sbi->interval_time[CP_TIME] = DEF_CP_INTERVAL; clear_sbi_flag(sbi, SBI_NEED_FSCK); INIT_LIST_HEAD(&sbi->s_list); @@ -1467,8 +1467,7 @@ try_onemore: f2fs_commit_super(sbi, true); } - sbi->cp_expires = round_jiffies_up(jiffies); - + f2fs_update_time(sbi, CP_TIME); return 0; free_kobj: -- GitLab From d0239e1bf5204d602281f93c01d46bcf3531098d Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 8 Jan 2016 16:57:48 -0800 Subject: [PATCH 2631/2855] f2fs: detect idle time depending on user behavior This patch adds last time that user requested filesystem operations. This information is used to detect whether system is idle or not later. Signed-off-by: Jaegeuk Kim --- Documentation/ABI/testing/sysfs-fs-f2fs | 6 ++++++ fs/f2fs/data.c | 1 + fs/f2fs/dir.c | 4 ++++ fs/f2fs/f2fs.h | 15 +++++++++++++++ fs/f2fs/file.c | 12 ++++++++++++ fs/f2fs/gc.c | 1 - fs/f2fs/gc.h | 8 -------- fs/f2fs/segment.c | 2 +- fs/f2fs/super.c | 4 ++++ fs/f2fs/xattr.c | 1 + 10 files changed, 44 insertions(+), 10 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index 0345f2d1c7278..e5200f354abfe 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -87,6 +87,12 @@ Contact: "Jaegeuk Kim" Description: Controls the checkpoint timing. +What: /sys/fs/f2fs//idle_interval +Date: January 2016 +Contact: "Jaegeuk Kim" +Description: + Controls the idle timing. + What: /sys/fs/f2fs//ra_nid_pages Date: October 2015 Contact: "Chao Yu" diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index a3bce12b0cce5..ac9e7c6aac74d 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1596,6 +1596,7 @@ static int f2fs_write_end(struct file *file, } f2fs_put_page(page, 1); + f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); return copied; } diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 29bb8dd76a46e..faa7495e2d7e6 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -636,6 +636,7 @@ fail: f2fs_put_page(dentry_page, 1); out: f2fs_fname_free_filename(&fname); + f2fs_update_time(F2FS_I_SB(dir), REQ_TIME); return err; } @@ -657,6 +658,7 @@ int f2fs_do_tmpfile(struct inode *inode, struct inode *dir) clear_inode_flag(F2FS_I(inode), FI_NEW_INODE); fail: up_write(&F2FS_I(inode)->i_sem); + f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); return err; } @@ -701,6 +703,8 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len)); int i; + f2fs_update_time(F2FS_I_SB(dir), REQ_TIME); + if (f2fs_has_inline_dentry(dir)) return f2fs_delete_inline_entry(dentry, page, dir, inode); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 5bbb6a407e79f..4331b9fe6f27f 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef CONFIG_F2FS_CHECK_FS #define f2fs_bug_on(sbi, condition) BUG_ON(condition) @@ -126,6 +127,7 @@ enum { #define BATCHED_TRIM_BLOCKS(sbi) \ (BATCHED_TRIM_SEGMENTS(sbi) << (sbi)->log_blocks_per_seg) #define DEF_CP_INTERVAL 60 /* 60 secs */ +#define DEF_IDLE_INTERVAL 120 /* 2 mins */ struct cp_control { int reason; @@ -723,6 +725,7 @@ enum { enum { CP_TIME, + REQ_TIME, MAX_TIME, }; @@ -856,6 +859,18 @@ static inline bool f2fs_time_over(struct f2fs_sb_info *sbi, int type) return time_after(jiffies, sbi->last_time[type] + interval); } +static inline bool is_idle(struct f2fs_sb_info *sbi) +{ + struct block_device *bdev = sbi->sb->s_bdev; + struct request_queue *q = bdev_get_queue(bdev); + struct request_list *rl = &q->root_rl; + + if (rl->count[BLK_RW_SYNC] || rl->count[BLK_RW_ASYNC]) + return 0; + + return f2fs_time_over(sbi, REQ_TIME); +} + /* * Inline functions */ diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index ff06827aa3695..3d43857e98923 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -96,6 +96,7 @@ mapped: clear_cold_data(page); out: sb_end_pagefault(inode->i_sb); + f2fs_update_time(sbi, REQ_TIME); return block_page_mkwrite_return(err); } @@ -280,6 +281,7 @@ flush_out: remove_ino_entry(sbi, ino, UPDATE_INO); clear_inode_flag(fi, FI_UPDATE_WRITE); ret = f2fs_issue_flush(sbi); + f2fs_update_time(sbi, REQ_TIME); out: trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret); f2fs_trace_ios(NULL, 1); @@ -485,6 +487,7 @@ int truncate_data_blocks_range(struct dnode_of_data *dn, int count) } dn->ofs_in_node = ofs; + f2fs_update_time(sbi, REQ_TIME); trace_f2fs_truncate_data_blocks_range(dn->inode, dn->nid, dn->ofs_in_node, nr_free); return nr_free; @@ -1236,6 +1239,7 @@ static long f2fs_fallocate(struct file *file, int mode, if (!ret) { inode->i_mtime = inode->i_ctime = CURRENT_TIME; mark_inode_dirty(inode); + f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); } out: @@ -1351,6 +1355,8 @@ static int f2fs_ioc_start_atomic_write(struct file *filp) return ret; set_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); + f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); + return 0; } @@ -1398,6 +1404,7 @@ static int f2fs_ioc_start_volatile_write(struct file *filp) return ret; set_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); + f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); return 0; } @@ -1439,6 +1446,7 @@ static int f2fs_ioc_abort_volatile_write(struct file *filp) } mnt_drop_write_file(filp); + f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); return ret; } @@ -1478,6 +1486,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg) default: return -EINVAL; } + f2fs_update_time(sbi, REQ_TIME); return 0; } @@ -1508,6 +1517,7 @@ static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg) if (copy_to_user((struct fstrim_range __user *)arg, &range, sizeof(range))) return -EFAULT; + f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); return 0; } @@ -1531,6 +1541,7 @@ static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg) sizeof(policy))) return -EFAULT; + f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); return f2fs_process_policy(&policy, inode); #else return -EOPNOTSUPP; @@ -1807,6 +1818,7 @@ static int f2fs_ioc_defragment(struct file *filp, unsigned long arg) } err = f2fs_defragment_range(sbi, filp, &range); + f2fs_update_time(sbi, REQ_TIME); if (err < 0) goto out; diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index c09be339569cf..f610c2a9bdde9 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -16,7 +16,6 @@ #include #include #include -#include #include "f2fs.h" #include "node.h" diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h index b4a65be9f7d3f..a993967dcdb97 100644 --- a/fs/f2fs/gc.h +++ b/fs/f2fs/gc.h @@ -100,11 +100,3 @@ static inline bool has_enough_invalid_blocks(struct f2fs_sb_info *sbi) return true; return false; } - -static inline int is_idle(struct f2fs_sb_info *sbi) -{ - struct block_device *bdev = sbi->sb->s_bdev; - struct request_queue *q = bdev_get_queue(bdev); - struct request_list *rl = &q->root_rl; - return !(rl->count[BLK_RW_SYNC]) && !(rl->count[BLK_RW_ASYNC]); -} diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index fed23d5a7b343..d8ad1abfa4fdb 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -293,7 +293,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi) if (!available_free_memory(sbi, NAT_ENTRIES) || excess_prefree_segs(sbi) || !available_free_memory(sbi, INO_ENTRIES) || - f2fs_time_over(sbi, CP_TIME)) { + (is_idle(sbi) && f2fs_time_over(sbi, CP_TIME))) { if (test_opt(sbi, DATA_FLUSH)) sync_dirty_inodes(sbi, FILE_INODE); f2fs_sync_fs(sbi->sb, true); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 787047f59c007..3bf990b800262 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -219,6 +219,7 @@ F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]); +F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]); #define ATTR_LIST(name) (&f2fs_attr_##name.attr) static struct attribute *f2fs_attrs[] = { @@ -237,6 +238,7 @@ static struct attribute *f2fs_attrs[] = { ATTR_LIST(ram_thresh), ATTR_LIST(ra_nid_pages), ATTR_LIST(cp_interval), + ATTR_LIST(idle_interval), NULL, }; @@ -1123,6 +1125,7 @@ static void init_sb_info(struct f2fs_sb_info *sbi) sbi->dir_level = DEF_DIR_LEVEL; sbi->interval_time[CP_TIME] = DEF_CP_INTERVAL; + sbi->interval_time[REQ_TIME] = DEF_IDLE_INTERVAL; clear_sbi_flag(sbi, SBI_NEED_FSCK); INIT_LIST_HEAD(&sbi->s_list); @@ -1468,6 +1471,7 @@ try_onemore: } f2fs_update_time(sbi, CP_TIME); + f2fs_update_time(sbi, REQ_TIME); return 0; free_kobj: diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index 822a8af89c122..0108f487cc8e4 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -618,5 +618,6 @@ int f2fs_setxattr(struct inode *inode, int index, const char *name, up_write(&F2FS_I(inode)->i_sem); f2fs_unlock_op(sbi); + f2fs_update_time(sbi, REQ_TIME); return err; } -- GitLab From 42190d2a8663f3e181894dc4e37a1af06aab2cbb Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Sat, 9 Jan 2016 13:45:17 -0800 Subject: [PATCH 2632/2855] f2fs: monitor the number of background checkpoint This patch adds to show the number of background checkpoint. Signed-off-by: Jaegeuk Kim --- fs/f2fs/debug.c | 3 ++- fs/f2fs/f2fs.h | 4 +++- fs/f2fs/segment.c | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index b73e8e133c8b7..48f2ae9452ef4 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -272,7 +272,8 @@ static int stat_show(struct seq_file *s, void *v) si->dirty_count); seq_printf(s, " - Prefree: %d\n - Free: %d (%d)\n\n", si->prefree_count, si->free_segs, si->free_secs); - seq_printf(s, "CP calls: %d\n", si->cp_count); + seq_printf(s, "CP calls: %d (BG: %d)\n", + si->cp_count, si->bg_cp_count); seq_printf(s, "GC calls: %d (BG: %d)\n", si->call_count, si->bg_gc); seq_printf(s, " - data segments : %d (%d)\n", diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 4331b9fe6f27f..2c0e478cefb48 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1937,7 +1937,7 @@ struct f2fs_stat_info { int util_free, util_valid, util_invalid; int rsvd_segs, overp_segs; int dirty_count, node_pages, meta_pages; - int prefree_count, call_count, cp_count; + int prefree_count, call_count, cp_count, bg_cp_count; int tot_segs, node_segs, data_segs, free_segs, free_secs; int bg_node_segs, bg_data_segs; int tot_blks, data_blks, node_blks; @@ -1958,6 +1958,7 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi) } #define stat_inc_cp_count(si) ((si)->cp_count++) +#define stat_inc_bg_cp_count(si) ((si)->bg_cp_count++) #define stat_inc_call_count(si) ((si)->call_count++) #define stat_inc_bggc_count(sbi) ((sbi)->bg_gc++) #define stat_inc_dirty_inode(sbi, type) ((sbi)->ndirty_inode[type]++) @@ -2040,6 +2041,7 @@ int __init f2fs_create_root_stats(void); void f2fs_destroy_root_stats(void); #else #define stat_inc_cp_count(si) +#define stat_inc_bg_cp_count(si) #define stat_inc_call_count(si) #define stat_inc_bggc_count(si) #define stat_inc_dirty_inode(sbi, type) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index d8ad1abfa4fdb..5904a411c86fe 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -297,6 +297,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi) if (test_opt(sbi, DATA_FLUSH)) sync_dirty_inodes(sbi, FILE_INODE); f2fs_sync_fs(sbi->sb, true); + stat_inc_bg_cp_count(sbi->stat_info); } } -- GitLab From 1663cae48ce3ce991c0e3f1a6fbdbd57f3dce9af Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Sat, 9 Jan 2016 16:14:08 -0800 Subject: [PATCH 2633/2855] f2fs: fix wrong memory condition check This patch fixes wrong decision for avaliable_free_memory. The return valus is already set as false, so we should consider true condition below only. Signed-off-by: Jaegeuk Kim --- fs/f2fs/node.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index c091b757bda60..342597a5897f0 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -71,8 +71,8 @@ bool available_free_memory(struct f2fs_sb_info *sbi, int type) sizeof(struct extent_node)) >> PAGE_CACHE_SHIFT; res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 1); } else { - if (sbi->sb->s_bdi->wb.dirty_exceeded) - return false; + if (!sbi->sb->s_bdi->wb.dirty_exceeded) + return true; } return res; } -- GitLab From 447135a86659c646017b8e707c1243c186bf2dff Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Sat, 9 Jan 2016 17:08:38 -0800 Subject: [PATCH 2634/2855] f2fs: should unset atomic flag after successful commit If there is an error during commit, we should keep the flag in order to abort it. Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 3d43857e98923..18ddb1e5182a1 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1378,8 +1378,10 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp) if (f2fs_is_atomic_file(inode)) { clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); ret = commit_inmem_pages(inode, false); - if (ret) + if (ret) { + set_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); goto err_out; + } } ret = f2fs_sync_file(filp, 0, LLONG_MAX, 0); -- GitLab From 44734f23de2465c3c0d39e4a16df7735b23fd142 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 11 Jan 2016 21:19:34 +0530 Subject: [PATCH 2635/2855] powerpc/mm: Fix _PAGE_PTE breaking swapoff Core kernel expects swp_entry_t to consist of only swap type and swap offset. We should not leak pte bits into swp_entry_t. This breaks swapoff which use the swap type and offset to build a swp_entry_t and later compare that to the swp_entry_t obtained from linux page table pte. Leaking pte bits into swp_entry_t breaks that comparison and results in us looping in try_to_unuse. The stack trace can be anywhere below try_to_unuse() in mm/swapfile.c, since swapoff is circling around and around that function, reading from each used swap block into a page, then trying to find where that page belongs, looking at every non-file pte of every mm that ever swapped. Fixes: 6a119eae942c ("powerpc/mm: Add a _PAGE_PTE bit") Reported-by: Hugh Dickins Suggested-by: Hugh Dickins Signed-off-by: Aneesh Kumar K.V Acked-by: Hugh Dickins Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/pgtable.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index 03c1a5a21c0ce..8e040c42e931d 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -158,9 +158,14 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val) #define __swp_entry(type, offset) ((swp_entry_t) { \ ((type) << _PAGE_BIT_SWAP_TYPE) \ | ((offset) << PTE_RPN_SHIFT) }) - -#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) }) -#define __swp_entry_to_pte(x) __pte((x).val) +/* + * swp_entry_t must be independent of pte bits. We build a swp_entry_t from + * swap type and offset we get from swap and convert that to pte to find a + * matching pte in linux page table. + * Clear bits not found in swap entries here. + */ +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) & ~_PAGE_PTE }) +#define __swp_entry_to_pte(x) __pte((x).val | _PAGE_PTE) #ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY #define _PAGE_SWP_SOFT_DIRTY (1UL << (SWP_TYPE_BITS + _PAGE_BIT_SWAP_TYPE)) -- GitLab From 2f10f1a7884e97a68e52c4b6f7866e29cf3fe7e6 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Sat, 9 Jan 2016 16:54:59 -0800 Subject: [PATCH 2636/2855] powerpc/mm: fix _PAGE_SWP_SOFT_DIRTY breaking swapoff Swapoff after swapping hangs on the G5, when CONFIG_CHECKPOINT_RESTORE=y but CONFIG_MEM_SOFT_DIRTY is not set. That's because the non-zero _PAGE_SWP_SOFT_DIRTY bit, added by CONFIG_HAVE_ARCH_SOFT_DIRTY=y, is not discounted when CONFIG_MEM_SOFT_DIRTY is not set: so swap ptes cannot be recognized. (I suspect that the peculiar dependence of HAVE_ARCH_SOFT_DIRTY on CHECKPOINT_RESTORE in arch/powerpc/Kconfig comes from an incomplete attempt to solve this problem.) It's true that the relationship between CONFIG_HAVE_ARCH_SOFT_DIRTY and and CONFIG_MEM_SOFT_DIRTY is too confusing, and it's true that swapoff should be made more robust; but nevertheless, fix up the powerpc ifdefs as x86_64 and s390 (which met the same problem) have them, defining the bits as 0 if CONFIG_MEM_SOFT_DIRTY is not set. Fixes: 7207f43665b8 ("powerpc/mm: Add page soft dirty tracking") Signed-off-by: Hugh Dickins Reviewed-by: Cyrill Gorcunov Acked-by: Laurent Dufour Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/hash.h | 5 +++++ arch/powerpc/include/asm/book3s/64/pgtable.h | 9 ++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 9e861b4378bd8..2ff8b3df553da 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -33,7 +33,12 @@ #define _PAGE_F_GIX_SHIFT 12 #define _PAGE_F_SECOND 0x08000 /* Whether to use secondary hash or not */ #define _PAGE_SPECIAL 0x10000 /* software: special page */ + +#ifdef CONFIG_MEM_SOFT_DIRTY #define _PAGE_SOFT_DIRTY 0x20000 /* software: software dirty tracking */ +#else +#define _PAGE_SOFT_DIRTY 0x00000 +#endif /* * THP pages can't be special. So use the _PAGE_SPECIAL diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index 8e040c42e931d..b3a5badab69fa 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -167,8 +167,13 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) & ~_PAGE_PTE }) #define __swp_entry_to_pte(x) __pte((x).val | _PAGE_PTE) -#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY +#ifdef CONFIG_MEM_SOFT_DIRTY #define _PAGE_SWP_SOFT_DIRTY (1UL << (SWP_TYPE_BITS + _PAGE_BIT_SWAP_TYPE)) +#else +#define _PAGE_SWP_SOFT_DIRTY 0UL +#endif /* CONFIG_MEM_SOFT_DIRTY */ + +#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY static inline pte_t pte_swp_mksoft_dirty(pte_t pte) { return __pte(pte_val(pte) | _PAGE_SWP_SOFT_DIRTY); @@ -181,8 +186,6 @@ static inline pte_t pte_swp_clear_soft_dirty(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_SWP_SOFT_DIRTY); } -#else -#define _PAGE_SWP_SOFT_DIRTY 0 #endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */ void pgtable_cache_add(unsigned shift, void (*ctor)(void *)); -- GitLab From 6544a1df11c48c8413071aac3316792e4678fbfb Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Mon, 11 Jan 2016 17:35:38 -0800 Subject: [PATCH 2637/2855] Input: elantech - mark protocols v2 and v3 as semi-mt When using a protocol v2 or v3 hardware, elantech uses the function elantech_report_semi_mt_data() to report data. This devices are rather creepy because if num_finger is 3, (x2,y2) is (0,0). Yes, only one valid touch is reported. Anyway, userspace (libinput) is now confused by these (0,0) touches, and detect them as palm, and rejects them. Commit 3c0213d17a09 ("Input: elantech - fix semi-mt protocol for v3 HW") was sufficient enough for xf86-input-synaptics and libinput before it has palm rejection. Now we need to actually tell libinput that this device is a semi-mt one and it should not rely on the actual values of the 2 touches. Cc: stable@vger.kernel.org Signed-off-by: Benjamin Tissoires Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/elantech.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 537ebb0e193a2..78f93cf68840d 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -1222,7 +1222,7 @@ static int elantech_set_input_params(struct psmouse *psmouse) input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, ETP_WMAX_V2, 0, 0); } - input_mt_init_slots(dev, 2, 0); + input_mt_init_slots(dev, 2, INPUT_MT_SEMI_MT); input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); break; -- GitLab From c9e0d39126af9e338495b719e9d565ca9ebcd4c5 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Mon, 11 Jan 2016 12:04:28 -0500 Subject: [PATCH 2638/2855] x86/mm/pat: Make split_page_count() check for empty levels to fix /proc/meminfo output In CONFIG_PAGEALLOC_DEBUG=y builds, we disable 2M pages. Unfortunatly when we split up mappings during boot, split_page_count() doesn't take this into account, and starts decrementing an empty direct_pages_count[] level. This results in /proc/meminfo showing crazy things like: DirectMap2M: 18446744073709543424 kB Signed-off-by: Dave Jones Cc: Andrew Morton Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Luis R. Rodriguez Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Toshi Kani Signed-off-by: Ingo Molnar --- arch/x86/mm/pageattr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 6000ad7f560c3..fc6a4c8f6e2ab 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -66,6 +66,9 @@ void update_page_count(int level, unsigned long pages) static void split_page_count(int level) { + if (direct_pages_count[level] == 0) + return; + direct_pages_count[level]--; direct_pages_count[level - 1] += PTRS_PER_PTE; } -- GitLab From 0f672809f91abd0aee01624ccad9199a62e3da7a Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Mon, 11 Jan 2016 17:23:32 -0800 Subject: [PATCH 2639/2855] selftests/x86: Disable the ldt_gdt_64 test for now ldt_gdt.c relies on cross-cpu invalidation of SS to do one of its tests. On 32-bit builds, this works fine, but on 64-bit builds, it only works if the kernel has proper SS sigcontext handling for 64-bit user programs. Since the SS fixes are currently reverted, restrict the test case to 32 bits for now. In principle, I could change the test to use a different segment register, but it would be messy: CS can't point to the LDT for 64-bit code, and the other registers don't result in immediate faults because they aren't reloaded on kernel -> user transitions. When we fix sigcontext (in 4.6?), we can revert this. Signed-off-by: Andy Lutomirski Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Shuah Khan Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/231591d9122d282402d8f53175134f8db5b3bc73.1452561752.git.luto@kernel.org Signed-off-by: Ingo Molnar --- tools/testing/selftests/x86/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index eabcff4119840..398bb0e6e38cc 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile @@ -4,9 +4,10 @@ include ../lib.mk .PHONY: all all_32 all_64 warn_32bit_failure clean -TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs ldt_gdt syscall_nt ptrace_syscall +TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault sigreturn test_syscall_vdso unwind_vdso \ - test_FCMOV test_FCOMI test_FISTTP + test_FCMOV test_FCOMI test_FISTTP \ + ldt_gdt TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32) -- GitLab From b500f77baea576b74c3961613b67eaffcdf65c57 Mon Sep 17 00:00:00 2001 From: Kefeng Wang Date: Tue, 12 Jan 2016 10:19:30 +0800 Subject: [PATCH 2640/2855] x86/mm: Use PAGE_ALIGNED instead of IS_ALIGNED Use PAGE_ALIGEND macro in to simplify code. Signed-off-by: Kefeng Wang Cc: Cc: Alexander Kuleshov Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1452565170-11083-1-git-send-email-wangkefeng.wang@huawei.com Signed-off-by: Ingo Molnar --- arch/x86/mm/init_64.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index ec081fe0ce2c1..8829482d69ec2 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -814,8 +814,7 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end, if (phys_addr < (phys_addr_t)0x40000000) return; - if (IS_ALIGNED(addr, PAGE_SIZE) && - IS_ALIGNED(next, PAGE_SIZE)) { + if (PAGE_ALIGNED(addr) && PAGE_ALIGNED(next)) { /* * Do not free direct mapping pages since they were * freed when offlining, or simplely not in use. -- GitLab From 4f81cbafcce2c603db7865e9d0e461f7947d77d4 Mon Sep 17 00:00:00 2001 From: yu-cheng yu Date: Wed, 6 Jan 2016 14:24:51 -0800 Subject: [PATCH 2641/2855] x86/fpu: Fix early FPU command-line parsing The function fpu__init_system() is executed before parse_early_param(). This causes wrong FPU configuration. This patch fixes this issue by parsing boot_command_line in the beginning of fpu__init_system(). With all four patches in this series, each parameter disables features as the following: eagerfpu=off: eagerfpu, avx, avx2, avx512, mpx no387: fpu nofxsr: fxsr, fxsropt, xmm noxsave: xsave, xsaveopt, xsaves, xsavec, avx, avx2, avx512, mpx, xgetbv1 noxsaveopt: xsaveopt noxsaves: xsaves Signed-off-by: Yu-cheng Yu Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Borislav Petkov Cc: Dave Hansen Cc: Fenghua Yu Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Peter Zijlstra Cc: Quentin Casasnovas Cc: Ravi V. Shankar Cc: Sai Praneeth Prakhya Cc: Thomas Gleixner Cc: yu-cheng yu Link: http://lkml.kernel.org/r/1452119094-7252-2-git-send-email-yu-cheng.yu@intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/fpu/init.c | 109 +++++++++++++------------------------ 1 file changed, 38 insertions(+), 71 deletions(-) diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c index 7b2978ab30df4..3a45fcd0b924c 100644 --- a/arch/x86/kernel/fpu/init.c +++ b/arch/x86/kernel/fpu/init.c @@ -3,8 +3,11 @@ */ #include #include +#include +#include #include +#include /* * Initialize the TS bit in CR0 according to the style of context-switches @@ -270,18 +273,6 @@ static void __init fpu__init_system_xstate_size_legacy(void) */ static enum { AUTO, ENABLE, DISABLE } eagerfpu = AUTO; -static int __init eager_fpu_setup(char *s) -{ - if (!strcmp(s, "on")) - eagerfpu = ENABLE; - else if (!strcmp(s, "off")) - eagerfpu = DISABLE; - else if (!strcmp(s, "auto")) - eagerfpu = AUTO; - return 1; -} -__setup("eagerfpu=", eager_fpu_setup); - /* * Pick the FPU context switching strategy: */ @@ -315,12 +306,47 @@ static void __init fpu__init_system_ctx_switch(void) printk(KERN_INFO "x86/fpu: Using '%s' FPU context switches.\n", eagerfpu == ENABLE ? "eager" : "lazy"); } +/* + * We parse fpu parameters early because fpu__init_system() is executed + * before parse_early_param(). + */ +static void __init fpu__init_parse_early_param(void) +{ + /* + * No need to check "eagerfpu=auto" again, since it is the + * initial default. + */ + if (cmdline_find_option_bool(boot_command_line, "eagerfpu=off")) + eagerfpu = DISABLE; + else if (cmdline_find_option_bool(boot_command_line, "eagerfpu=on")) + eagerfpu = ENABLE; + + if (cmdline_find_option_bool(boot_command_line, "no387")) + setup_clear_cpu_cap(X86_FEATURE_FPU); + + if (cmdline_find_option_bool(boot_command_line, "nofxsr")) { + setup_clear_cpu_cap(X86_FEATURE_FXSR); + setup_clear_cpu_cap(X86_FEATURE_FXSR_OPT); + setup_clear_cpu_cap(X86_FEATURE_XMM); + } + + if (cmdline_find_option_bool(boot_command_line, "noxsave")) + fpu__xstate_clear_all_cpu_caps(); + + if (cmdline_find_option_bool(boot_command_line, "noxsaveopt")) + setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); + + if (cmdline_find_option_bool(boot_command_line, "noxsaves")) + setup_clear_cpu_cap(X86_FEATURE_XSAVES); +} + /* * Called on the boot CPU once per system bootup, to set up the initial * FPU state that is later cloned into all processes: */ void __init fpu__init_system(struct cpuinfo_x86 *c) { + fpu__init_parse_early_param(); fpu__init_system_early_generic(c); /* @@ -344,62 +370,3 @@ void __init fpu__init_system(struct cpuinfo_x86 *c) fpu__init_system_ctx_switch(); } - -/* - * Boot parameter to turn off FPU support and fall back to math-emu: - */ -static int __init no_387(char *s) -{ - setup_clear_cpu_cap(X86_FEATURE_FPU); - return 1; -} -__setup("no387", no_387); - -/* - * Disable all xstate CPU features: - */ -static int __init x86_noxsave_setup(char *s) -{ - if (strlen(s)) - return 0; - - fpu__xstate_clear_all_cpu_caps(); - - return 1; -} -__setup("noxsave", x86_noxsave_setup); - -/* - * Disable the XSAVEOPT instruction specifically: - */ -static int __init x86_noxsaveopt_setup(char *s) -{ - setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); - - return 1; -} -__setup("noxsaveopt", x86_noxsaveopt_setup); - -/* - * Disable the XSAVES instruction: - */ -static int __init x86_noxsaves_setup(char *s) -{ - setup_clear_cpu_cap(X86_FEATURE_XSAVES); - - return 1; -} -__setup("noxsaves", x86_noxsaves_setup); - -/* - * Disable FX save/restore and SSE support: - */ -static int __init x86_nofxsr_setup(char *s) -{ - setup_clear_cpu_cap(X86_FEATURE_FXSR); - setup_clear_cpu_cap(X86_FEATURE_FXSR_OPT); - setup_clear_cpu_cap(X86_FEATURE_XMM); - - return 1; -} -__setup("nofxsr", x86_nofxsr_setup); -- GitLab From eb7c5f872e697b0aebd846cf3a3328d71e9decb2 Mon Sep 17 00:00:00 2001 From: yu-cheng yu Date: Wed, 6 Jan 2016 14:24:52 -0800 Subject: [PATCH 2642/2855] x86/fpu: Disable XGETBV1 when no XSAVE When "noxsave" is given as a command-line input, the kernel should disable XGETBV1. This issue currently does not cause any actual problems. XGETBV1 is only useful if we have something using the 'init optimization' (i.e. xsaveopt, xsaves). We already clear both of those in fpu__xstate_clear_all_cpu_caps(). But this is good for completeness. Signed-off-by: Yu-cheng Yu Reviewed-by: Dave Hansen Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Borislav Petkov Cc: Dave Hansen Cc: Fenghua Yu Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Peter Zijlstra Cc: Quentin Casasnovas Cc: Ravi V. Shankar Cc: Sai Praneeth Prakhya Cc: Thomas Gleixner Cc: yu-cheng yu Link: http://lkml.kernel.org/r/1452119094-7252-3-git-send-email-yu-cheng.yu@intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/fpu/xstate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c index 40f100285984e..d489f277a8a0c 100644 --- a/arch/x86/kernel/fpu/xstate.c +++ b/arch/x86/kernel/fpu/xstate.c @@ -52,6 +52,7 @@ void fpu__xstate_clear_all_cpu_caps(void) setup_clear_cpu_cap(X86_FEATURE_AVX512ER); setup_clear_cpu_cap(X86_FEATURE_AVX512CD); setup_clear_cpu_cap(X86_FEATURE_MPX); + setup_clear_cpu_cap(X86_FEATURE_XGETBV1); } /* -- GitLab From a5fe93a549c54838063d2952dd9643b0b18aa67f Mon Sep 17 00:00:00 2001 From: yu-cheng yu Date: Wed, 6 Jan 2016 14:24:53 -0800 Subject: [PATCH 2643/2855] x86/fpu: Disable MPX when eagerfpu is off This issue is a fallout from the command-line parsing move. When "eagerfpu=off" is given as a command-line input, the kernel should disable MPX support. The decision for turning off MPX was made in fpu__init_system_ctx_switch(), which is after the selection of the XSAVE format. This patch fixes it by getting that decision done earlier in fpu__init_system_xstate(). Signed-off-by: Yu-cheng Yu Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Borislav Petkov Cc: Dave Hansen Cc: Fenghua Yu Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Peter Zijlstra Cc: Quentin Casasnovas Cc: Ravi V. Shankar Cc: Sai Praneeth Prakhya Cc: Thomas Gleixner Cc: yu-cheng yu Link: http://lkml.kernel.org/r/1452119094-7252-4-git-send-email-yu-cheng.yu@intel.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/fpu/internal.h | 1 + arch/x86/kernel/fpu/init.c | 56 ++++++++++++++++++++++------- arch/x86/kernel/fpu/xstate.c | 3 +- 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h index eadcdd5bb9464..0fd440df63f18 100644 --- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h @@ -42,6 +42,7 @@ extern void fpu__init_cpu_xstate(void); extern void fpu__init_system(struct cpuinfo_x86 *c); extern void fpu__init_check_bugs(void); extern void fpu__resume_cpu(void); +extern u64 fpu__get_supported_xfeatures_mask(void); /* * Debugging facility: diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c index 3a45fcd0b924c..f0ab36844a6dd 100644 --- a/arch/x86/kernel/fpu/init.c +++ b/arch/x86/kernel/fpu/init.c @@ -273,8 +273,46 @@ static void __init fpu__init_system_xstate_size_legacy(void) */ static enum { AUTO, ENABLE, DISABLE } eagerfpu = AUTO; +/* + * Find supported xfeatures based on cpu features and command-line input. + * This must be called after fpu__init_parse_early_param() is called and + * xfeatures_mask is enumerated. + */ +u64 __init fpu__get_supported_xfeatures_mask(void) +{ + /* Support all xfeatures known to us */ + if (eagerfpu != DISABLE) + return XCNTXT_MASK; + + /* Warning of xfeatures being disabled for no eagerfpu mode */ + if (xfeatures_mask & XFEATURE_MASK_EAGER) { + pr_err("x86/fpu: eagerfpu switching disabled, disabling the following xstate features: 0x%llx.\n", + xfeatures_mask & XFEATURE_MASK_EAGER); + } + + /* Return a mask that masks out all features requiring eagerfpu mode */ + return ~XFEATURE_MASK_EAGER; +} + +/* + * Disable features dependent on eagerfpu. + */ +static void __init fpu__clear_eager_fpu_features(void) +{ + setup_clear_cpu_cap(X86_FEATURE_MPX); +} + /* * Pick the FPU context switching strategy: + * + * When eagerfpu is AUTO or ENABLE, we ensure it is ENABLE if either of + * the following is true: + * + * (1) the cpu has xsaveopt, as it has the optimization and doing eager + * FPU switching has a relatively low cost compared to a plain xsave; + * (2) the cpu has xsave features (e.g. MPX) that depend on eager FPU + * switching. Should the kernel boot with noxsaveopt, we support MPX + * with eager FPU switching at a higher cost. */ static void __init fpu__init_system_ctx_switch(void) { @@ -286,19 +324,11 @@ static void __init fpu__init_system_ctx_switch(void) WARN_ON_FPU(current->thread.fpu.fpstate_active); current_thread_info()->status = 0; - /* Auto enable eagerfpu for xsaveopt */ if (boot_cpu_has(X86_FEATURE_XSAVEOPT) && eagerfpu != DISABLE) eagerfpu = ENABLE; - if (xfeatures_mask & XFEATURE_MASK_EAGER) { - if (eagerfpu == DISABLE) { - pr_err("x86/fpu: eagerfpu switching disabled, disabling the following xstate features: 0x%llx.\n", - xfeatures_mask & XFEATURE_MASK_EAGER); - xfeatures_mask &= ~XFEATURE_MASK_EAGER; - } else { - eagerfpu = ENABLE; - } - } + if (xfeatures_mask & XFEATURE_MASK_EAGER) + eagerfpu = ENABLE; if (eagerfpu == ENABLE) setup_force_cpu_cap(X86_FEATURE_EAGER_FPU); @@ -316,10 +346,12 @@ static void __init fpu__init_parse_early_param(void) * No need to check "eagerfpu=auto" again, since it is the * initial default. */ - if (cmdline_find_option_bool(boot_command_line, "eagerfpu=off")) + if (cmdline_find_option_bool(boot_command_line, "eagerfpu=off")) { eagerfpu = DISABLE; - else if (cmdline_find_option_bool(boot_command_line, "eagerfpu=on")) + fpu__clear_eager_fpu_features(); + } else if (cmdline_find_option_bool(boot_command_line, "eagerfpu=on")) { eagerfpu = ENABLE; + } if (cmdline_find_option_bool(boot_command_line, "no387")) setup_clear_cpu_cap(X86_FEATURE_FPU); diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c index d489f277a8a0c..d425cda5ae6d0 100644 --- a/arch/x86/kernel/fpu/xstate.c +++ b/arch/x86/kernel/fpu/xstate.c @@ -633,8 +633,7 @@ void __init fpu__init_system_xstate(void) BUG(); } - /* Support only the state known to the OS: */ - xfeatures_mask = xfeatures_mask & XCNTXT_MASK; + xfeatures_mask &= fpu__get_supported_xfeatures_mask(); /* Enable xstate instructions to be able to continue with initialization: */ fpu__init_cpu_xstate(); -- GitLab From 394db20ca240741a08d472173db13d6f6a6e5a28 Mon Sep 17 00:00:00 2001 From: yu-cheng yu Date: Wed, 6 Jan 2016 14:24:54 -0800 Subject: [PATCH 2644/2855] x86/fpu: Disable AVX when eagerfpu is off When "eagerfpu=off" is given as a command-line input, the kernel should disable AVX support. The Task Switched bit used for lazy context switching does not support AVX. If AVX is enabled without eagerfpu context switching, one task's AVX state could become corrupted or leak to other tasks. This is a bug and has bad security implications. This only affects systems that have AVX/AVX2/AVX512 and this issue will be found only when one actually uses AVX/AVX2/AVX512 _AND_ does eagerfpu=off. Reference: Intel Software Developer's Manual Vol. 3A Sec. 2.5 Control Registers: TS Task Switched bit (bit 3 of CR0) -- Allows the saving of the x87 FPU/ MMX/SSE/SSE2/SSE3/SSSE3/SSE4 context on a task switch to be delayed until an x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 instruction is actually executed by the new task. Sec. 13.4.1 Using the TS Flag to Control the Saving of the X87 FPU and SSE State When the TS flag is set, the processor monitors the instruction stream for x87 FPU, MMX, SSE instructions. When the processor detects one of these instructions, it raises a device-not-available exeception (#NM) prior to executing the instruction. Signed-off-by: Yu-cheng Yu Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Borislav Petkov Cc: Dave Hansen Cc: Fenghua Yu Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Peter Zijlstra Cc: Quentin Casasnovas Cc: Ravi V. Shankar Cc: Sai Praneeth Prakhya Cc: Thomas Gleixner Cc: yu-cheng yu Link: http://lkml.kernel.org/r/1452119094-7252-5-git-send-email-yu-cheng.yu@intel.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/fpu/xstate.h | 11 ++++++----- arch/x86/kernel/fpu/init.c | 6 ++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h index 3a6c89b703075..af30fdeb140da 100644 --- a/arch/x86/include/asm/fpu/xstate.h +++ b/arch/x86/include/asm/fpu/xstate.h @@ -20,15 +20,16 @@ /* Supported features which support lazy state saving */ #define XFEATURE_MASK_LAZY (XFEATURE_MASK_FP | \ - XFEATURE_MASK_SSE | \ + XFEATURE_MASK_SSE) + +/* Supported features which require eager state saving */ +#define XFEATURE_MASK_EAGER (XFEATURE_MASK_BNDREGS | \ + XFEATURE_MASK_BNDCSR | \ XFEATURE_MASK_YMM | \ - XFEATURE_MASK_OPMASK | \ + XFEATURE_MASK_OPMASK | \ XFEATURE_MASK_ZMM_Hi256 | \ XFEATURE_MASK_Hi16_ZMM) -/* Supported features which require eager state saving */ -#define XFEATURE_MASK_EAGER (XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR) - /* All currently supported features */ #define XCNTXT_MASK (XFEATURE_MASK_LAZY | XFEATURE_MASK_EAGER) diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c index f0ab36844a6dd..6d9f0a7ef4c8e 100644 --- a/arch/x86/kernel/fpu/init.c +++ b/arch/x86/kernel/fpu/init.c @@ -300,6 +300,12 @@ u64 __init fpu__get_supported_xfeatures_mask(void) static void __init fpu__clear_eager_fpu_features(void) { setup_clear_cpu_cap(X86_FEATURE_MPX); + setup_clear_cpu_cap(X86_FEATURE_AVX); + setup_clear_cpu_cap(X86_FEATURE_AVX2); + setup_clear_cpu_cap(X86_FEATURE_AVX512F); + setup_clear_cpu_cap(X86_FEATURE_AVX512PF); + setup_clear_cpu_cap(X86_FEATURE_AVX512ER); + setup_clear_cpu_cap(X86_FEATURE_AVX512CD); } /* -- GitLab From aa0421410fc540832f0fd267ff0f2657c3276053 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sun, 3 Jan 2016 23:38:53 +0100 Subject: [PATCH 2645/2855] x86/boot: Hide local labels in verify_cpu() ... from the final ELF image's symbol table as they're not really needed there. Before: $ readelf -a vmlinux | grep verify_cpu 43: ffffffff810001a9 0 NOTYPE LOCAL DEFAULT 1 verify_cpu 45: ffffffff8100028f 0 NOTYPE LOCAL DEFAULT 1 verify_cpu_no_longmode 46: ffffffff810001de 0 NOTYPE LOCAL DEFAULT 1 verify_cpu_noamd 47: ffffffff8100022b 0 NOTYPE LOCAL DEFAULT 1 verify_cpu_check 48: ffffffff8100021c 0 NOTYPE LOCAL DEFAULT 1 verify_cpu_clear_xd 49: ffffffff81000263 0 NOTYPE LOCAL DEFAULT 1 verify_cpu_sse_test 50: ffffffff81000296 0 NOTYPE LOCAL DEFAULT 1 verify_cpu_sse_ok After: $ readelf -a vmlinux | grep verify_cpu 43: ffffffff810001a9 0 NOTYPE LOCAL DEFAULT 1 verify_cpu No functionality change. Signed-off-by: Borislav Petkov Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Dave Hansen Cc: Denys Vlasenko Cc: Fenghua Yu Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Peter Zijlstra Cc: Quentin Casasnovas Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1451860733-21163-1-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar --- arch/x86/kernel/verify_cpu.S | 50 ++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/arch/x86/kernel/verify_cpu.S b/arch/x86/kernel/verify_cpu.S index 4cf401f581e7e..07efb35ee4bc3 100644 --- a/arch/x86/kernel/verify_cpu.S +++ b/arch/x86/kernel/verify_cpu.S @@ -48,31 +48,31 @@ verify_cpu: pushfl popl %eax cmpl %eax,%ebx - jz verify_cpu_no_longmode # cpu has no cpuid + jz .Lverify_cpu_no_longmode # cpu has no cpuid #endif movl $0x0,%eax # See if cpuid 1 is implemented cpuid cmpl $0x1,%eax - jb verify_cpu_no_longmode # no cpuid 1 + jb .Lverify_cpu_no_longmode # no cpuid 1 xor %di,%di cmpl $0x68747541,%ebx # AuthenticAMD - jnz verify_cpu_noamd + jnz .Lverify_cpu_noamd cmpl $0x69746e65,%edx - jnz verify_cpu_noamd + jnz .Lverify_cpu_noamd cmpl $0x444d4163,%ecx - jnz verify_cpu_noamd + jnz .Lverify_cpu_noamd mov $1,%di # cpu is from AMD - jmp verify_cpu_check + jmp .Lverify_cpu_check -verify_cpu_noamd: +.Lverify_cpu_noamd: cmpl $0x756e6547,%ebx # GenuineIntel? - jnz verify_cpu_check + jnz .Lverify_cpu_check cmpl $0x49656e69,%edx - jnz verify_cpu_check + jnz .Lverify_cpu_check cmpl $0x6c65746e,%ecx - jnz verify_cpu_check + jnz .Lverify_cpu_check # only call IA32_MISC_ENABLE when: # family > 6 || (family == 6 && model >= 0xd) @@ -83,59 +83,59 @@ verify_cpu_noamd: andl $0x0ff00f00, %eax # mask family and extended family shrl $8, %eax cmpl $6, %eax - ja verify_cpu_clear_xd # family > 6, ok - jb verify_cpu_check # family < 6, skip + ja .Lverify_cpu_clear_xd # family > 6, ok + jb .Lverify_cpu_check # family < 6, skip andl $0x000f00f0, %ecx # mask model and extended model shrl $4, %ecx cmpl $0xd, %ecx - jb verify_cpu_check # family == 6, model < 0xd, skip + jb .Lverify_cpu_check # family == 6, model < 0xd, skip -verify_cpu_clear_xd: +.Lverify_cpu_clear_xd: movl $MSR_IA32_MISC_ENABLE, %ecx rdmsr btrl $2, %edx # clear MSR_IA32_MISC_ENABLE_XD_DISABLE - jnc verify_cpu_check # only write MSR if bit was changed + jnc .Lverify_cpu_check # only write MSR if bit was changed wrmsr -verify_cpu_check: +.Lverify_cpu_check: movl $0x1,%eax # Does the cpu have what it takes cpuid andl $REQUIRED_MASK0,%edx xorl $REQUIRED_MASK0,%edx - jnz verify_cpu_no_longmode + jnz .Lverify_cpu_no_longmode movl $0x80000000,%eax # See if extended cpuid is implemented cpuid cmpl $0x80000001,%eax - jb verify_cpu_no_longmode # no extended cpuid + jb .Lverify_cpu_no_longmode # no extended cpuid movl $0x80000001,%eax # Does the cpu have what it takes cpuid andl $REQUIRED_MASK1,%edx xorl $REQUIRED_MASK1,%edx - jnz verify_cpu_no_longmode + jnz .Lverify_cpu_no_longmode -verify_cpu_sse_test: +.Lverify_cpu_sse_test: movl $1,%eax cpuid andl $SSE_MASK,%edx cmpl $SSE_MASK,%edx - je verify_cpu_sse_ok + je .Lverify_cpu_sse_ok test %di,%di - jz verify_cpu_no_longmode # only try to force SSE on AMD + jz .Lverify_cpu_no_longmode # only try to force SSE on AMD movl $MSR_K7_HWCR,%ecx rdmsr btr $15,%eax # enable SSE wrmsr xor %di,%di # don't loop - jmp verify_cpu_sse_test # try again + jmp .Lverify_cpu_sse_test # try again -verify_cpu_no_longmode: +.Lverify_cpu_no_longmode: popf # Restore caller passed flags movl $1,%eax ret -verify_cpu_sse_ok: +.Lverify_cpu_sse_ok: popf # Restore caller passed flags xorl %eax, %eax ret -- GitLab From e27d90e8be08d96b5e047cd01daf7e62c4fcab78 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 22 Dec 2015 10:39:54 +1030 Subject: [PATCH 2646/2855] lguest: Map switcher text R/O Pavel noted that lguest maps the switcher code executable and read-write. This is a bad idea for any kernel text, but particularly for text mapped at a fixed address. Create two vmas, one for the text (PAGE_KERNEL_RX) and another for the stacks (PAGE_KERNEL). Use VM_NO_GUARD to map them adjacent (as expected by the rest of the code). Reported-by: Pavel Machek Tested-by: Pavel Machek Signed-off-by: Rusty Russell Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Signed-off-by: Ingo Molnar --- arch/x86/include/asm/lguest.h | 4 +- drivers/lguest/core.c | 74 ++++++++++++++++++++++++----------- 2 files changed, 54 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/lguest.h b/arch/x86/include/asm/lguest.h index 3bbc07a57a31e..73d0c9b92087c 100644 --- a/arch/x86/include/asm/lguest.h +++ b/arch/x86/include/asm/lguest.h @@ -12,7 +12,9 @@ #define GUEST_PL 1 /* Page for Switcher text itself, then two pages per cpu */ -#define TOTAL_SWITCHER_PAGES (1 + 2 * nr_cpu_ids) +#define SWITCHER_TEXT_PAGES (1) +#define SWITCHER_STACK_PAGES (2 * nr_cpu_ids) +#define TOTAL_SWITCHER_PAGES (SWITCHER_TEXT_PAGES + SWITCHER_STACK_PAGES) /* Where we map the Switcher, in both Host and Guest. */ extern unsigned long switcher_addr; diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c index 312ffd3d00177..9e385b38debfd 100644 --- a/drivers/lguest/core.c +++ b/drivers/lguest/core.c @@ -22,7 +22,8 @@ unsigned long switcher_addr; struct page **lg_switcher_pages; -static struct vm_struct *switcher_vma; +static struct vm_struct *switcher_text_vma; +static struct vm_struct *switcher_stacks_vma; /* This One Big lock protects all inter-guest data structures. */ DEFINE_MUTEX(lguest_lock); @@ -82,55 +83,81 @@ static __init int map_switcher(void) } } + /* + * Copy in the compiled-in Switcher code (from x86/switcher_32.S). + * It goes in the first page, which we map in momentarily. + */ + memcpy(kmap(lg_switcher_pages[0]), start_switcher_text, + end_switcher_text - start_switcher_text); + kunmap(lg_switcher_pages[0]); + /* * We place the Switcher underneath the fixmap area, which is the * highest virtual address we can get. This is important, since we * tell the Guest it can't access this memory, so we want its ceiling * as high as possible. */ - switcher_addr = FIXADDR_START - (TOTAL_SWITCHER_PAGES+1)*PAGE_SIZE; + switcher_addr = FIXADDR_START - TOTAL_SWITCHER_PAGES*PAGE_SIZE; /* - * Now we reserve the "virtual memory area" we want. We might - * not get it in theory, but in practice it's worked so far. - * The end address needs +1 because __get_vm_area allocates an - * extra guard page, so we need space for that. + * Now we reserve the "virtual memory area"s we want. We might + * not get them in theory, but in practice it's worked so far. + * + * We want the switcher text to be read-only and executable, and + * the stacks to be read-write and non-executable. */ - switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE, - VM_ALLOC, switcher_addr, switcher_addr - + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE); - if (!switcher_vma) { + switcher_text_vma = __get_vm_area(PAGE_SIZE, VM_ALLOC|VM_NO_GUARD, + switcher_addr, + switcher_addr + PAGE_SIZE); + + if (!switcher_text_vma) { err = -ENOMEM; printk("lguest: could not map switcher pages high\n"); goto free_pages; } + switcher_stacks_vma = __get_vm_area(SWITCHER_STACK_PAGES * PAGE_SIZE, + VM_ALLOC|VM_NO_GUARD, + switcher_addr + PAGE_SIZE, + switcher_addr + TOTAL_SWITCHER_PAGES * PAGE_SIZE); + if (!switcher_stacks_vma) { + err = -ENOMEM; + printk("lguest: could not map switcher pages high\n"); + goto free_text_vma; + } + /* * This code actually sets up the pages we've allocated to appear at * switcher_addr. map_vm_area() takes the vma we allocated above, the - * kind of pages we're mapping (kernel pages), and a pointer to our - * array of struct pages. + * kind of pages we're mapping (kernel text pages and kernel writable + * pages respectively), and a pointer to our array of struct pages. */ - err = map_vm_area(switcher_vma, PAGE_KERNEL_EXEC, lg_switcher_pages); + err = map_vm_area(switcher_text_vma, PAGE_KERNEL_RX, lg_switcher_pages); + if (err) { + printk("lguest: text map_vm_area failed: %i\n", err); + goto free_vmas; + } + + err = map_vm_area(switcher_stacks_vma, PAGE_KERNEL, + lg_switcher_pages + SWITCHER_TEXT_PAGES); if (err) { - printk("lguest: map_vm_area failed: %i\n", err); - goto free_vma; + printk("lguest: stacks map_vm_area failed: %i\n", err); + goto free_vmas; } /* * Now the Switcher is mapped at the right address, we can't fail! - * Copy in the compiled-in Switcher code (from x86/switcher_32.S). */ - memcpy(switcher_vma->addr, start_switcher_text, - end_switcher_text - start_switcher_text); - printk(KERN_INFO "lguest: mapped switcher at %p\n", - switcher_vma->addr); + switcher_text_vma->addr); /* And we succeeded... */ return 0; -free_vma: - vunmap(switcher_vma->addr); +free_vmas: + /* Undoes map_vm_area and __get_vm_area */ + vunmap(switcher_stacks_vma->addr); +free_text_vma: + vunmap(switcher_text_vma->addr); free_pages: i = TOTAL_SWITCHER_PAGES; free_some_pages: @@ -148,7 +175,8 @@ static void unmap_switcher(void) unsigned int i; /* vunmap() undoes *both* map_vm_area() and __get_vm_area(). */ - vunmap(switcher_vma->addr); + vunmap(switcher_text_vma->addr); + vunmap(switcher_stacks_vma->addr); /* Now we just need to free the pages we copied the switcher into */ for (i = 0; i < TOTAL_SWITCHER_PAGES; i++) __free_pages(lg_switcher_pages[i], 0); -- GitLab From 2f0c0b2d96b1205efb14347009748d786c2d9ba5 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Fri, 18 Dec 2015 20:24:06 +0100 Subject: [PATCH 2647/2855] x86/reboot/quirks: Add iMac10,1 to pci_reboot_dmi_table[] Without the reboot=pci method, the iMac 10,1 simply hangs after printing "Restarting system" at the point when it should reboot. This fixes it. Signed-off-by: Mario Kleiner Cc: Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Dave Jones Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1450466646-26663-1-git-send-email-mario.kleiner.de@gmail.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/reboot.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index d64889aa2d46d..ab0adc0fa5db4 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -182,6 +182,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"), }, }, + { /* Handle problems with rebooting on the iMac10,1. */ + .callback = set_pci_reboot, + .ident = "Apple iMac10,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "iMac10,1"), + }, + }, /* ASRock */ { /* Handle problems with rebooting on ASRock Q1900DC-ITX */ -- GitLab From 8a59f3ccbc11fcb222b046a64929dd473f7dff54 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 12 Jan 2016 10:35:29 +0100 Subject: [PATCH 2648/2855] perf stat: Fix recort_usage typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Markus reported gcc 6 complains when compiling perf stat command: builtin-stat.c:1591:27: error: ‘recort_usage’ defined but not used [-Werror=unused-const-variable] static const char * const recort_usage[] = { ^~~~~~~~~~~~ I fixed the typo and realized we already export record_usage, so I also prefixed it with stat (and included report_usage). Reported-by: Markus Trippelsdorf Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1452591329-27620-1-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 7f568244662b0..038e877081b68 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1588,7 +1588,7 @@ static int add_default_attributes(void) return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs); } -static const char * const recort_usage[] = { +static const char * const stat_record_usage[] = { "perf stat record []", NULL, }; @@ -1611,7 +1611,7 @@ static int __cmd_record(int argc, const char **argv) struct perf_session *session; struct perf_data_file *file = &perf_stat.file; - argc = parse_options(argc, argv, stat_options, record_usage, + argc = parse_options(argc, argv, stat_options, stat_record_usage, PARSE_OPT_STOP_AT_NON_OPTION); if (output_name) @@ -1745,7 +1745,7 @@ int process_cpu_map_event(struct perf_tool *tool __maybe_unused, return set_maps(st); } -static const char * const report_usage[] = { +static const char * const stat_report_usage[] = { "perf stat report []", NULL, }; @@ -1779,7 +1779,7 @@ static int __cmd_report(int argc, const char **argv) struct stat st; int ret; - argc = parse_options(argc, argv, options, report_usage, 0); + argc = parse_options(argc, argv, options, stat_report_usage, 0); if (!input_name || !strlen(input_name)) { if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode)) -- GitLab From b0fb978e97f58ca930f7cafc4ddc264218710765 Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Tue, 12 Jan 2016 10:12:04 +0000 Subject: [PATCH 2649/2855] perf tools: Fix mmap2 event allocation in synthesize code perf_event__synthesize_mmap_events() issues mmap2 events, but the memory of that event is allocated using: mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size); If path of mmap source file is long (near PATH_MAX), random crash would happen. Should use sizeof(mmap_event->mmap2). Fix two memory allocations. Signed-off-by: Wang Nan Reviewed-by: Masami Hiramatsu Acked-by: Jiri Olsa Cc: He Kuang Cc: Namhyung Kim Cc: Zefan Li Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1452593524-138970-1-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/event.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index cd61bb1f3917f..85155e91b61ba 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -503,7 +503,7 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool, if (comm_event == NULL) goto out; - mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size); + mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size); if (mmap_event == NULL) goto out_free_comm; @@ -577,7 +577,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool, if (comm_event == NULL) goto out; - mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size); + mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size); if (mmap_event == NULL) goto out_free_comm; -- GitLab From d1b39d41ebec2afc761ba6539b77a7fe1669ddae Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Fri, 18 Dec 2015 06:39:16 -0600 Subject: [PATCH 2650/2855] tools: Make list.h self-sufficient Commit 7f5f873c6a07 ("rculist: Use WRITE_ONCE() when deleting from reader-visible list") added the use of the WRITE_ONCE macro to the kernel version of list.h, which broke the stacktool build because the tools list.h includes the kernel list.h. Avoid this type of situation in the future and make list.h self-sufficient by copying the kernel list.h routines directly into tools list.h. This is a straight copy except for adjustments to the include statements and copying of the tools-specific list routines (list_del_range and list_for_each_from). Signed-off-by: Josh Poimboeuf Cc: "H. Peter Anvin" Cc: Andi Kleen Cc: Andrew Morton Cc: Andy Lutomirski Cc: Bernd Petrovitsch Cc: Borislav Petkov Cc: Chris J Arges Cc: Jiri Slaby Cc: Linus Torvalds Cc: Michal Marek Cc: Namhyung Kim Cc: Pedro Alves Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: live-patching@vger.kernel.org Cc: x86@kernel.org Link: http://lkml.kernel.org/r/59cdc19c6589d1b5ef43d83b0e2d5a4a40301374.1450442274.git.jpoimboe@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/list.h | 753 ++++++++++++++++++++++++++++++++++++- 1 file changed, 747 insertions(+), 6 deletions(-) diff --git a/tools/include/linux/list.h b/tools/include/linux/list.h index a017f1595676d..1da423820ad4f 100644 --- a/tools/include/linux/list.h +++ b/tools/include/linux/list.h @@ -1,11 +1,751 @@ -#include -#include +#ifndef __TOOLS_LINUX_LIST_H +#define __TOOLS_LINUX_LIST_H + #include +#include +#include +#include + +/* + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +static inline void INIT_LIST_HEAD(struct list_head *list) +{ + list->next = list; + list->prev = list; +} + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +#ifndef CONFIG_DEBUG_LIST +static inline void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} +#else +extern void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next); +#endif + +/** + * list_add - add a new entry + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static inline void list_add(struct list_head *new, struct list_head *head) +{ + __list_add(new, head, head->next); +} + + +/** + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static inline void list_add_tail(struct list_head *new, struct list_head *head) +{ + __list_add(new, head->prev, head); +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_del(struct list_head * prev, struct list_head * next) +{ + next->prev = prev; + WRITE_ONCE(prev->next, next); +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty() on entry does not return true after this, the entry is + * in an undefined state. + */ +#ifndef CONFIG_DEBUG_LIST +static inline void __list_del_entry(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); +} + +static inline void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + entry->next = LIST_POISON1; + entry->prev = LIST_POISON2; +} +#else +extern void __list_del_entry(struct list_head *entry); +extern void list_del(struct list_head *entry); +#endif + +/** + * list_replace - replace old entry by new one + * @old : the element to be replaced + * @new : the new element to insert + * + * If @old was empty, it will be overwritten. + */ +static inline void list_replace(struct list_head *old, + struct list_head *new) +{ + new->next = old->next; + new->next->prev = new; + new->prev = old->prev; + new->prev->next = new; +} + +static inline void list_replace_init(struct list_head *old, + struct list_head *new) +{ + list_replace(old, new); + INIT_LIST_HEAD(old); +} + +/** + * list_del_init - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +static inline void list_del_init(struct list_head *entry) +{ + __list_del_entry(entry); + INIT_LIST_HEAD(entry); +} + +/** + * list_move - delete from one list and add as another's head + * @list: the entry to move + * @head: the head that will precede our entry + */ +static inline void list_move(struct list_head *list, struct list_head *head) +{ + __list_del_entry(list); + list_add(list, head); +} + +/** + * list_move_tail - delete from one list and add as another's tail + * @list: the entry to move + * @head: the head that will follow our entry + */ +static inline void list_move_tail(struct list_head *list, + struct list_head *head) +{ + __list_del_entry(list); + list_add_tail(list, head); +} + +/** + * list_is_last - tests whether @list is the last entry in list @head + * @list: the entry to test + * @head: the head of the list + */ +static inline int list_is_last(const struct list_head *list, + const struct list_head *head) +{ + return list->next == head; +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static inline int list_empty(const struct list_head *head) +{ + return head->next == head; +} + +/** + * list_empty_careful - tests whether a list is empty and not being modified + * @head: the list to test + * + * Description: + * tests whether a list is empty _and_ checks that no other CPU might be + * in the process of modifying either member (next or prev) + * + * NOTE: using list_empty_careful() without synchronization + * can only be safe if the only activity that can happen + * to the list entry is list_del_init(). Eg. it cannot be used + * if another CPU could re-list_add() it. + */ +static inline int list_empty_careful(const struct list_head *head) +{ + struct list_head *next = head->next; + return (next == head) && (next == head->prev); +} + +/** + * list_rotate_left - rotate the list to the left + * @head: the head of the list + */ +static inline void list_rotate_left(struct list_head *head) +{ + struct list_head *first; + + if (!list_empty(head)) { + first = head->next; + list_move_tail(first, head); + } +} + +/** + * list_is_singular - tests whether a list has just one entry. + * @head: the list to test. + */ +static inline int list_is_singular(const struct list_head *head) +{ + return !list_empty(head) && (head->next == head->prev); +} + +static inline void __list_cut_position(struct list_head *list, + struct list_head *head, struct list_head *entry) +{ + struct list_head *new_first = entry->next; + list->next = head->next; + list->next->prev = list; + list->prev = entry; + entry->next = list; + head->next = new_first; + new_first->prev = head; +} + +/** + * list_cut_position - cut a list into two + * @list: a new list to add all removed entries + * @head: a list with entries + * @entry: an entry within head, could be the head itself + * and if so we won't cut the list + * + * This helper moves the initial part of @head, up to and + * including @entry, from @head to @list. You should + * pass on @entry an element you know is on @head. @list + * should be an empty list or a list you do not care about + * losing its data. + * + */ +static inline void list_cut_position(struct list_head *list, + struct list_head *head, struct list_head *entry) +{ + if (list_empty(head)) + return; + if (list_is_singular(head) && + (head->next != entry && head != entry)) + return; + if (entry == head) + INIT_LIST_HEAD(list); + else + __list_cut_position(list, head, entry); +} + +static inline void __list_splice(const struct list_head *list, + struct list_head *prev, + struct list_head *next) +{ + struct list_head *first = list->next; + struct list_head *last = list->prev; + + first->prev = prev; + prev->next = first; + + last->next = next; + next->prev = last; +} + +/** + * list_splice - join two lists, this is designed for stacks + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void list_splice(const struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) + __list_splice(list, head, head->next); +} + +/** + * list_splice_tail - join two lists, each list being a queue + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void list_splice_tail(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) + __list_splice(list, head->prev, head); +} + +/** + * list_splice_init - join two lists and reinitialise the emptied list. + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * The list at @list is reinitialised + */ +static inline void list_splice_init(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) { + __list_splice(list, head, head->next); + INIT_LIST_HEAD(list); + } +} + +/** + * list_splice_tail_init - join two lists and reinitialise the emptied list + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * Each of the lists is a queue. + * The list at @list is reinitialised + */ +static inline void list_splice_tail_init(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) { + __list_splice(list, head->prev, head); + INIT_LIST_HEAD(list); + } +} + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_head within the struct. + */ +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +/** + * list_first_entry - get the first element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_head within the struct. + * + * Note, that list is expected to be not empty. + */ +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + +/** + * list_last_entry - get the last element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_head within the struct. + * + * Note, that list is expected to be not empty. + */ +#define list_last_entry(ptr, type, member) \ + list_entry((ptr)->prev, type, member) + +/** + * list_first_entry_or_null - get the first element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_head within the struct. + * + * Note that if the list is empty, it returns NULL. + */ +#define list_first_entry_or_null(ptr, type, member) \ + (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL) + +/** + * list_next_entry - get the next element in list + * @pos: the type * to cursor + * @member: the name of the list_head within the struct. + */ +#define list_next_entry(pos, member) \ + list_entry((pos)->member.next, typeof(*(pos)), member) + +/** + * list_prev_entry - get the prev element in list + * @pos: the type * to cursor + * @member: the name of the list_head within the struct. + */ +#define list_prev_entry(pos, member) \ + list_entry((pos)->member.prev, typeof(*(pos)), member) + +/** + * list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop cursor. + * @head: the head for your list. + */ +#define list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) + +/** + * list_for_each_prev - iterate over a list backwards + * @pos: the &struct list_head to use as a loop cursor. + * @head: the head for your list. + */ +#define list_for_each_prev(pos, head) \ + for (pos = (head)->prev; pos != (head); pos = pos->prev) + +/** + * list_for_each_safe - iterate over a list safe against removal of list entry + * @pos: the &struct list_head to use as a loop cursor. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +/** + * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry + * @pos: the &struct list_head to use as a loop cursor. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define list_for_each_prev_safe(pos, n, head) \ + for (pos = (head)->prev, n = pos->prev; \ + pos != (head); \ + pos = n, n = pos->prev) + +/** + * list_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_head within the struct. + */ +#define list_for_each_entry(pos, head, member) \ + for (pos = list_first_entry(head, typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_next_entry(pos, member)) + +/** + * list_for_each_entry_reverse - iterate backwards over list of given type. + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_head within the struct. + */ +#define list_for_each_entry_reverse(pos, head, member) \ + for (pos = list_last_entry(head, typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_prev_entry(pos, member)) + +/** + * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() + * @pos: the type * to use as a start point + * @head: the head of the list + * @member: the name of the list_head within the struct. + * + * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). + */ +#define list_prepare_entry(pos, head, member) \ + ((pos) ? : list_entry(head, typeof(*pos), member)) + +/** + * list_for_each_entry_continue - continue iteration over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_head within the struct. + * + * Continue to iterate over list of given type, continuing after + * the current position. + */ +#define list_for_each_entry_continue(pos, head, member) \ + for (pos = list_next_entry(pos, member); \ + &pos->member != (head); \ + pos = list_next_entry(pos, member)) + +/** + * list_for_each_entry_continue_reverse - iterate backwards from the given point + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_head within the struct. + * + * Start to iterate over list of given type backwards, continuing after + * the current position. + */ +#define list_for_each_entry_continue_reverse(pos, head, member) \ + for (pos = list_prev_entry(pos, member); \ + &pos->member != (head); \ + pos = list_prev_entry(pos, member)) + +/** + * list_for_each_entry_from - iterate over list of given type from the current point + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_head within the struct. + * + * Iterate over list of given type, continuing from current position. + */ +#define list_for_each_entry_from(pos, head, member) \ + for (; &pos->member != (head); \ + pos = list_next_entry(pos, member)) + +/** + * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_head within the struct. + */ +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_first_entry(head, typeof(*pos), member), \ + n = list_next_entry(pos, member); \ + &pos->member != (head); \ + pos = n, n = list_next_entry(n, member)) + +/** + * list_for_each_entry_safe_continue - continue list iteration safe against removal + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_head within the struct. + * + * Iterate over list of given type, continuing after current point, + * safe against removal of list entry. + */ +#define list_for_each_entry_safe_continue(pos, n, head, member) \ + for (pos = list_next_entry(pos, member), \ + n = list_next_entry(pos, member); \ + &pos->member != (head); \ + pos = n, n = list_next_entry(n, member)) + +/** + * list_for_each_entry_safe_from - iterate over list from current point safe against removal + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_head within the struct. + * + * Iterate over list of given type from current point, safe against + * removal of list entry. + */ +#define list_for_each_entry_safe_from(pos, n, head, member) \ + for (n = list_next_entry(pos, member); \ + &pos->member != (head); \ + pos = n, n = list_next_entry(n, member)) + +/** + * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_head within the struct. + * + * Iterate backwards over list of given type, safe against removal + * of list entry. + */ +#define list_for_each_entry_safe_reverse(pos, n, head, member) \ + for (pos = list_last_entry(head, typeof(*pos), member), \ + n = list_prev_entry(pos, member); \ + &pos->member != (head); \ + pos = n, n = list_prev_entry(n, member)) -#include "../../../include/linux/list.h" +/** + * list_safe_reset_next - reset a stale list_for_each_entry_safe loop + * @pos: the loop cursor used in the list_for_each_entry_safe loop + * @n: temporary storage used in list_for_each_entry_safe + * @member: the name of the list_head within the struct. + * + * list_safe_reset_next is not safe to use in general if the list may be + * modified concurrently (eg. the lock is dropped in the loop body). An + * exception to this is if the cursor element (pos) is pinned in the list, + * and list_safe_reset_next is called after re-taking the lock and before + * completing the current iteration of the loop body. + */ +#define list_safe_reset_next(pos, n, member) \ + n = list_next_entry(pos, member) + +/* + * Double linked lists with a single pointer list head. + * Mostly useful for hash tables where the two pointer list head is + * too wasteful. + * You lose the ability to access the tail in O(1). + */ + +#define HLIST_HEAD_INIT { .first = NULL } +#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } +#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) +static inline void INIT_HLIST_NODE(struct hlist_node *h) +{ + h->next = NULL; + h->pprev = NULL; +} + +static inline int hlist_unhashed(const struct hlist_node *h) +{ + return !h->pprev; +} + +static inline int hlist_empty(const struct hlist_head *h) +{ + return !h->first; +} + +static inline void __hlist_del(struct hlist_node *n) +{ + struct hlist_node *next = n->next; + struct hlist_node **pprev = n->pprev; + + WRITE_ONCE(*pprev, next); + if (next) + next->pprev = pprev; +} + +static inline void hlist_del(struct hlist_node *n) +{ + __hlist_del(n); + n->next = LIST_POISON1; + n->pprev = LIST_POISON2; +} + +static inline void hlist_del_init(struct hlist_node *n) +{ + if (!hlist_unhashed(n)) { + __hlist_del(n); + INIT_HLIST_NODE(n); + } +} + +static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) +{ + struct hlist_node *first = h->first; + n->next = first; + if (first) + first->pprev = &n->next; + h->first = n; + n->pprev = &h->first; +} + +/* next must be != NULL */ +static inline void hlist_add_before(struct hlist_node *n, + struct hlist_node *next) +{ + n->pprev = next->pprev; + n->next = next; + next->pprev = &n->next; + *(n->pprev) = n; +} + +static inline void hlist_add_behind(struct hlist_node *n, + struct hlist_node *prev) +{ + n->next = prev->next; + prev->next = n; + n->pprev = &prev->next; + + if (n->next) + n->next->pprev = &n->next; +} + +/* after that we'll appear to be on some hlist and hlist_del will work */ +static inline void hlist_add_fake(struct hlist_node *n) +{ + n->pprev = &n->next; +} + +static inline bool hlist_fake(struct hlist_node *h) +{ + return h->pprev == &h->next; +} + +/* + * Move a list from one list head to another. Fixup the pprev + * reference of the first entry if it exists. + */ +static inline void hlist_move_list(struct hlist_head *old, + struct hlist_head *new) +{ + new->first = old->first; + if (new->first) + new->first->pprev = &new->first; + old->first = NULL; +} + +#define hlist_entry(ptr, type, member) container_of(ptr,type,member) + +#define hlist_for_each(pos, head) \ + for (pos = (head)->first; pos ; pos = pos->next) + +#define hlist_for_each_safe(pos, n, head) \ + for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ + pos = n) + +#define hlist_entry_safe(ptr, type, member) \ + ({ typeof(ptr) ____ptr = (ptr); \ + ____ptr ? hlist_entry(____ptr, type, member) : NULL; \ + }) + +/** + * hlist_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry(pos, head, member) \ + for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\ + pos; \ + pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) + +/** + * hlist_for_each_entry_continue - iterate over a hlist continuing after current point + * @pos: the type * to use as a loop cursor. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_continue(pos, member) \ + for (pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member);\ + pos; \ + pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) + +/** + * hlist_for_each_entry_from - iterate over a hlist continuing from current point + * @pos: the type * to use as a loop cursor. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_from(pos, member) \ + for (; pos; \ + pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) + +/** + * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry + * @pos: the type * to use as a loop cursor. + * @n: another &struct hlist_node to use as temporary storage + * @head: the head for your list. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_safe(pos, n, head, member) \ + for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\ + pos && ({ n = pos->member.next; 1; }); \ + pos = hlist_entry_safe(n, typeof(*pos), member)) -#ifndef TOOLS_LIST_H -#define TOOLS_LIST_H /** * list_del_range - deletes range of entries from list. * @begin: first element in the range to delete from the list. @@ -27,4 +767,5 @@ static inline void list_del_range(struct list_head *begin, */ #define list_for_each_from(pos, head) \ for (; pos != (head); pos = pos->next) -#endif + +#endif /* __TOOLS_LINUX_LIST_H */ -- GitLab From 20a7add8ca2165de909d430b9874eacc26a2166c Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Fri, 18 Dec 2015 06:39:15 -0600 Subject: [PATCH 2651/2855] tools: Fix formatting of the "make -C tools" help message Align the x86_energy_perf_policy line with the others and restore the original alphabetical sorting. Signed-off-by: Josh Poimboeuf Cc: "H. Peter Anvin" Cc: Andi Kleen Cc: Andrew Morton Cc: Andy Lutomirski Cc: Bernd Petrovitsch Cc: Borislav Petkov Cc: Chris J Arges Cc: Jiri Slaby Cc: Linus Torvalds Cc: Michal Marek Cc: Namhyung Kim Cc: Pedro Alves Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: live-patching@vger.kernel.org Cc: x86@kernel.org Link: http://lkml.kernel.org/r/572931227adbf1fc9ca96e1dae3ef2e89387feca.1450442274.git.jpoimboe@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/Makefile | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tools/Makefile b/tools/Makefile index 4e8e10755e0d8..09ec69db4bc89 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -8,23 +8,23 @@ include scripts/Makefile.include help: @echo 'Possible targets:' @echo '' - @echo ' acpi - ACPI tools' - @echo ' cgroup - cgroup tools' - @echo ' cpupower - a tool for all things x86 CPU power' - @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' - @echo ' hv - tools used when in Hyper-V clients' - @echo ' iio - IIO tools' - @echo ' lguest - a minimal 32-bit x86 hypervisor' - @echo ' perf - Linux performance measurement and analysis tool' - @echo ' selftests - various kernel selftests' - @echo ' turbostat - Intel CPU idle stats and freq reporting tool' - @echo ' usb - USB testing tools' - @echo ' virtio - vhost test module' - @echo ' net - misc networking tools' - @echo ' vm - misc vm tools' + @echo ' acpi - ACPI tools' + @echo ' cgroup - cgroup tools' + @echo ' cpupower - a tool for all things x86 CPU power' + @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' + @echo ' freefall - laptop accelerometer program for disk protection' + @echo ' hv - tools used when in Hyper-V clients' + @echo ' iio - IIO tools' + @echo ' lguest - a minimal 32-bit x86 hypervisor' + @echo ' net - misc networking tools' + @echo ' perf - Linux performance measurement and analysis tool' + @echo ' selftests - various kernel selftests' + @echo ' tmon - thermal monitoring and tuning tool' + @echo ' turbostat - Intel CPU idle stats and freq reporting tool' + @echo ' usb - USB testing tools' + @echo ' virtio - vhost test module' + @echo ' vm - misc vm tools' @echo ' x86_energy_perf_policy - Intel energy policy tool' - @echo ' tmon - thermal monitoring and tuning tool' - @echo ' freefall - laptop accelerometer program for disk protection' @echo '' @echo 'You can do:' @echo ' $$ make -C tools/ _install' -- GitLab From 24b1e5d7f552eb6da430d5264d671ba45d634804 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Fri, 18 Dec 2015 06:39:17 -0600 Subject: [PATCH 2652/2855] tools subcmd: Add missing NORETURN define for parse-options.h parse-options.h uses the NORETURN macro without defining it. perf doesn't see a build error because it defines the macro in util.h before including parse-options.h. But any other tool including it will see an error. Define the macro in parse-options.h (if not already defined) so that other tools can include it. Signed-off-by: Josh Poimboeuf Cc: "H. Peter Anvin" Cc: Andi Kleen Cc: Andrew Morton Cc: Andy Lutomirski Cc: Bernd Petrovitsch Cc: Borislav Petkov Cc: Chris J Arges Cc: Jiri Slaby Cc: Linus Torvalds Cc: Michal Marek Cc: Namhyung Kim Cc: Pedro Alves Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: live-patching@vger.kernel.org Cc: x86@kernel.org Link: http://lkml.kernel.org/r/6c16294ac6dbe5e2ca28fd935fe4389996588564.1450442274.git.jpoimboe@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/subcmd/parse-options.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/lib/subcmd/parse-options.h b/tools/lib/subcmd/parse-options.h index 13a2cc1d61405..d60cab2726dac 100644 --- a/tools/lib/subcmd/parse-options.h +++ b/tools/lib/subcmd/parse-options.h @@ -4,6 +4,10 @@ #include #include +#ifndef NORETURN +#define NORETURN __attribute__((__noreturn__)) +#endif + enum parse_opt_type { /* special types */ OPTION_END, -- GitLab From 6156681b73f2fffe56493e9a50518c0cbfcd8ba3 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 11 Jan 2016 22:37:09 +0900 Subject: [PATCH 2653/2855] perf record: Add --buildid-all option The --buildid-all option is to record build-id of all DSOs in the file. It might be very costly to postprocess samples to find which DSO hits. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Andi Kleen Cc: David Ahern Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1452519429-31779-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-record.txt | 3 +++ tools/perf/builtin-record.c | 26 ++++++++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 3a1a32f5479f9..fbceb631387c3 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -338,6 +338,9 @@ Options passed to clang when compiling BPF scriptlets. Specify vmlinux path which has debuginfo. (enabled when BPF prologue is on) +--buildid-all:: +Record build-id of all DSOs regardless whether it's actually hit or not. + SEE ALSO -------- linkperf:perf-stat[1], linkperf:perf-list[1] diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index dc4e0adf5c5b5..319712a4e02b7 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -50,6 +50,7 @@ struct record { int realtime_prio; bool no_buildid; bool no_buildid_cache; + bool buildid_all; unsigned long long samples; }; @@ -362,6 +363,13 @@ static int process_buildids(struct record *rec) */ symbol_conf.ignore_vmlinux_buildid = true; + /* + * If --buildid-all is given, it marks all DSO regardless of hits, + * so no need to process samples. + */ + if (rec->buildid_all) + rec->tool.sample = NULL; + return perf_session__process_events(session); } @@ -756,12 +764,8 @@ out_child: if (!rec->no_buildid) { process_buildids(rec); - /* - * We take all buildids when the file contains - * AUX area tracing data because we do not decode the - * trace because it would take too long. - */ - if (rec->opts.full_auxtrace) + + if (rec->buildid_all) dsos__hit_all(rec->session); } perf_session__write_header(rec->session, rec->evlist, fd, true); @@ -1138,6 +1142,8 @@ struct option __record_options[] = { "options passed to clang when compiling BPF scriptlets"), OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name, "file", "vmlinux pathname"), + OPT_BOOLEAN(0, "buildid-all", &record.buildid_all, + "Record build-id of all DSOs regardless of hits"), OPT_END() }; @@ -1255,6 +1261,14 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) if (err) goto out_symbol_exit; + /* + * We take all buildids when the file contains + * AUX area tracing data because we do not decode the + * trace because it would take too long. + */ + if (rec->opts.full_auxtrace) + rec->buildid_all = true; + if (record_opts__config(&rec->opts)) { err = -EINVAL; goto out_symbol_exit; -- GitLab From 09f1985404aa99b9d1ad435fcb0dabd20d4ed498 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 11 Jan 2016 19:35:10 +0900 Subject: [PATCH 2654/2855] perf tools: Add more usage tips Thanks to Andi Kleen for providing useful tips. Suggested-by: Andi Kleen Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: Brendan Gregg Cc: David Ahern Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1452508510-28316-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/tips.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tools/perf/Documentation/tips.txt b/tools/perf/Documentation/tips.txt index a1c10e360db5b..e0ce9573b79bd 100644 --- a/tools/perf/Documentation/tips.txt +++ b/tools/perf/Documentation/tips.txt @@ -12,3 +12,18 @@ List events using substring match: perf list To see list of saved events and attributes: perf evlist -v Use --symfs if your symbol files are in non-standard locations To see callchains in a more compact form: perf report -g folded +Show individual samples with: perf script +Limit to show entries above 5% only: perf report --percent-limit 5 +Profiling branch (mis)predictions with: perf record -b / perf report +Treat branches as callchains: perf report --branch-history +To count events in every 1000 msec: perf stat -I 1000 +Print event counts in CSV format with: perf stat -x, +If you have debuginfo enabled, try: perf report -s sym,srcline +For memory address profiling, try: perf mem record / perf mem report +For tracepoint events, try: perf report -s trace_fields +To record callchains for each sample: perf record -g +To record every process run by an user: perf record -u +Skip collecing build-id when recording: perf record -B +To change sampling frequency to 100 Hz: perf record -F 100 +See assembly instructions with percentage: perf annotate +If you prefer Intel style assembly, try: perf annotate -M intel -- GitLab From dd8232bc9d13b729d92590b55befd14e49f81eca Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Sat, 9 Jan 2016 19:16:27 +0900 Subject: [PATCH 2655/2855] perf tools: Add file_only config option to strlist If strlist_config.dirname is present, the strlist__new() tries to load stirngs from dirname/list file first but if it failes it falls back to add 'list' as string. But sometimes it's not desired so adds new file_only field to prevent it. Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: David Ahern Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1452334589-8782-2-git-send-email-namhyung@kernel.org [ Add documentation for strlist_config::file_only, in the struct definition */ Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/strlist.c | 8 ++++++++ tools/perf/util/strlist.h | 9 ++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/strlist.c b/tools/perf/util/strlist.c index bdf98f6f27bb1..0d3dfcb919b44 100644 --- a/tools/perf/util/strlist.c +++ b/tools/perf/util/strlist.c @@ -126,6 +126,11 @@ static int strlist__parse_list_entry(struct strlist *slist, const char *s, err = strlist__load(slist, subst); goto out; } + + if (slist->file_only) { + err = -ENOENT; + goto out; + } } err = strlist__add(slist, s); @@ -157,11 +162,13 @@ struct strlist *strlist__new(const char *list, const struct strlist_config *conf if (slist != NULL) { bool dupstr = true; + bool file_only = false; const char *dirname = NULL; if (config) { dupstr = !config->dont_dupstr; dirname = config->dirname; + file_only = config->file_only; } rblist__init(&slist->rblist); @@ -170,6 +177,7 @@ struct strlist *strlist__new(const char *list, const struct strlist_config *conf slist->rblist.node_delete = strlist__node_delete; slist->dupstr = dupstr; + slist->file_only = file_only; if (list && strlist__parse_list(slist, list, dirname) != 0) goto out_error; diff --git a/tools/perf/util/strlist.h b/tools/perf/util/strlist.h index 297565aa75350..ca990029e2430 100644 --- a/tools/perf/util/strlist.h +++ b/tools/perf/util/strlist.h @@ -13,11 +13,18 @@ struct str_node { struct strlist { struct rblist rblist; - bool dupstr; + bool dupstr; + bool file_only; }; +/* + * @file_only: When dirname is present, only consider entries as filenames, + * that should not be added to the list if dirname/entry is not + * found + */ struct strlist_config { bool dont_dupstr; + bool file_only; const char *dirname; }; -- GitLab From 84cfac7f05e110e803a45d99cff0ba0949cc8d58 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Sat, 9 Jan 2016 19:16:28 +0900 Subject: [PATCH 2656/2855] perf tools: Set and pass DOCDIR to builtin-report.c It'll be used to locate perf document directory to find tips.txt in case it's not installed on the system. Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: David Ahern Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1452334589-8782-3-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Build | 1 + tools/perf/config/Makefile | 3 +++ 2 files changed, 4 insertions(+) diff --git a/tools/perf/Build b/tools/perf/Build index 6b67e6f4179f5..a43fae7f439a5 100644 --- a/tools/perf/Build +++ b/tools/perf/Build @@ -42,6 +42,7 @@ CFLAGS_perf.o += -DPERF_HTML_PATH="BUILD_STR($(htmldir_SQ))" \ -include $(OUTPUT)PERF-VERSION-FILE CFLAGS_builtin-trace.o += -DSTRACE_GROUPS_DIR="BUILD_STR($(STRACE_GROUPS_DIR_SQ))" CFLAGS_builtin-report.o += -DTIPDIR="BUILD_STR($(tipdir_SQ))" +CFLAGS_builtin-report.o += -DDOCDIR="BUILD_STR($(srcdir_SQ)/Documentation)" libperf-y += util/ libperf-y += arch/ diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 7545ba60053e8..e5959c136a190 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -692,6 +692,7 @@ template_dir = share/perf-core/templates STRACE_GROUPS_DIR = share/perf-core/strace/groups htmldir = share/doc/perf-doc tipdir = share/doc/perf-tip +srcdir = $(srctree)/tools/perf ifeq ($(prefix),/usr) sysconfdir = /etc ETC_PERFCONFIG = $(sysconfdir)/perfconfig @@ -722,6 +723,7 @@ tipdir_SQ = $(subst ','\'',$(tipdir)) prefix_SQ = $(subst ','\'',$(prefix)) sysconfdir_SQ = $(subst ','\'',$(sysconfdir)) libdir_SQ = $(subst ','\'',$(libdir)) +srcdir_SQ = $(subst ','\'',$(srcdir)) ifneq ($(filter /%,$(firstword $(perfexecdir))),) perfexec_instdir = $(perfexecdir) @@ -776,6 +778,7 @@ $(call detected_var,STRACE_GROUPS_DIR_SQ) $(call detected_var,prefix_SQ) $(call detected_var,perfexecdir_SQ) $(call detected_var,tipdir_SQ) +$(call detected_var,srcdir_SQ) $(call detected_var,LIBDIR) $(call detected_var,GTK_CFLAGS) $(call detected_var,PERL_EMBED_CCOPTS) -- GitLab From 090cff3eae8f02395009972d01b5dfdb95bcc327 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 11 Jan 2016 19:53:14 +0900 Subject: [PATCH 2657/2855] perf ui/tui: Print helpline message as is When a tip message contains a percent sign, it was treated printf format specifier so broken string was printed like below. Tip: Limit to show entries above 577nly: perf report --percent-limit 5 ^^^ As ui_browser__show receives format string, pass additional "%s" so that the help (tip) message can be printed as is. Tip: Limit to show entries above 5% only: perf report --percent-limit 5 Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: David Ahern Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1452509594-13616-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/hists.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 901d481e6cea5..08c09ad755d2d 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -480,7 +480,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *help) hists__browser_title(browser->hists, hbt, title, sizeof(title)); - if (ui_browser__show(&browser->b, title, help) < 0) + if (ui_browser__show(&browser->b, title, "%s", help) < 0) return -1; while (1) { -- GitLab From 34b7b0f95d41d2351a080e774d71085171db90e6 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Sat, 9 Jan 2016 19:16:29 +0900 Subject: [PATCH 2658/2855] perf tools: Fallback to srcdir/Documentation/tips.txt Some people don't install perf, but just use compiled version in the source. Fallback to lookup the source directory for those poor guys. :) Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: David Ahern Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1452334589-8782-4-git-send-email-namhyung@kernel.org [ Make perf_tip() return NULL for ENOENT, making the fallback to really take place ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-report.c | 10 +++++++++- tools/perf/util/util.c | 11 ++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index d5a42ee12529b..2bf537f190a02 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -28,6 +28,7 @@ #include "util/tool.h" #include +#include #include "util/parse-events.h" #include "util/thread.h" @@ -433,7 +434,14 @@ static int report__browse_hists(struct report *rep) int ret; struct perf_session *session = rep->session; struct perf_evlist *evlist = session->evlist; - const char *help = perf_tip(TIPDIR); + const char *help = perf_tip(system_path(TIPDIR)); + + if (help == NULL) { + /* fallback for people who don't install perf ;-) */ + help = perf_tip(DOCDIR); + if (help == NULL) + help = "Cannot load tips.txt file, please install perf!"; + } switch (use_browser) { case 1: diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 88b8f8d21f58e..ead9509835d23 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -17,7 +17,6 @@ #include #include "callchain.h" #include "strlist.h" -#include struct callchain_param callchain_param = { .mode = CHAIN_GRAPH_ABS, @@ -672,14 +671,16 @@ const char *perf_tip(const char *dirpath) struct str_node *node; char *tip = NULL; struct strlist_config conf = { - .dirname = system_path(dirpath) , + .dirname = dirpath, + .file_only = true, }; tips = strlist__new("tips.txt", &conf); - if (tips == NULL || strlist__nr_entries(tips) == 1) { - tip = (char *)"Cannot find tips.txt file"; + if (tips == NULL) + return errno == ENOENT ? NULL : "Tip: get more memory! ;-p"; + + if (strlist__nr_entries(tips) == 0) goto out; - } node = strlist__entry(tips, random() % strlist__nr_entries(tips)); if (asprintf(&tip, "Tip: %s", node->s) < 0) -- GitLab From 99ee67351bedf23fe6b969dd94cc2847b397cd20 Mon Sep 17 00:00:00 2001 From: LABBE Corentin Date: Fri, 13 Nov 2015 13:31:51 +0100 Subject: [PATCH 2659/2855] ipmi: constify some struct and char arrays Lots of char arrays could be set as const since they contain only literal char arrays. We could in the same time make const some struct members who are pointer to those const char arrays. Signed-off-by: LABBE Corentin Signed-off-by: Corey Minyard --- drivers/char/ipmi/ipmi_msghandler.c | 7 ++++--- drivers/char/ipmi/ipmi_si_intf.c | 27 ++++++++++++++++----------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index e3536da05c88a..94fb407d85615 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -472,9 +472,10 @@ static DEFINE_MUTEX(smi_watchers_mutex); #define ipmi_get_stat(intf, stat) \ ((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat])) -static char *addr_src_to_str[] = { "invalid", "hotmod", "hardcoded", "SPMI", - "ACPI", "SMBIOS", "PCI", - "device-tree", "default" }; +static const char * const addr_src_to_str[] = { + "invalid", "hotmod", "hardcoded", "SPMI", "ACPI", "SMBIOS", "PCI", + "device-tree", "default" +}; const char *ipmi_addr_src_to_str(enum ipmi_addr_src src) { diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 4cc72fa017c7b..440574de3cb47 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -105,7 +105,8 @@ enum si_intf_state { enum si_type { SI_KCS, SI_SMIC, SI_BT }; -static char *si_to_str[] = { "kcs", "smic", "bt" }; + +static const char * const si_to_str[] = { "kcs", "smic", "bt" }; #define DEVICE_NAME "ipmi_si" @@ -1341,7 +1342,7 @@ static unsigned int num_slave_addrs; #define IPMI_IO_ADDR_SPACE 0 #define IPMI_MEM_ADDR_SPACE 1 -static char *addr_space_to_str[] = { "i/o", "mem" }; +static const char * const addr_space_to_str[] = { "i/o", "mem" }; static int hotmod_handler(const char *val, struct kernel_param *kp); @@ -1723,27 +1724,31 @@ static int mem_setup(struct smi_info *info) */ enum hotmod_op { HM_ADD, HM_REMOVE }; struct hotmod_vals { - char *name; - int val; + const char *name; + const int val; }; -static struct hotmod_vals hotmod_ops[] = { + +static const struct hotmod_vals hotmod_ops[] = { { "add", HM_ADD }, { "remove", HM_REMOVE }, { NULL } }; -static struct hotmod_vals hotmod_si[] = { + +static const struct hotmod_vals hotmod_si[] = { { "kcs", SI_KCS }, { "smic", SI_SMIC }, { "bt", SI_BT }, { NULL } }; -static struct hotmod_vals hotmod_as[] = { + +static const struct hotmod_vals hotmod_as[] = { { "mem", IPMI_MEM_ADDR_SPACE }, { "i/o", IPMI_IO_ADDR_SPACE }, { NULL } }; -static int parse_str(struct hotmod_vals *v, int *val, char *name, char **curr) +static int parse_str(const struct hotmod_vals *v, int *val, char *name, + char **curr) { char *s; int i; @@ -2870,7 +2875,7 @@ static int ipmi_parisc_remove(struct parisc_device *dev) return 0; } -static struct parisc_device_id ipmi_parisc_tbl[] = { +static const struct parisc_device_id ipmi_parisc_tbl[] = { { HPHW_MC, HVERSION_REV_ANY_ID, 0x004, 0xC0 }, { 0, } }; @@ -3444,8 +3449,8 @@ static inline void wait_for_timer_and_thread(struct smi_info *smi_info) static const struct ipmi_default_vals { - int type; - int port; + const int type; + const int port; } ipmi_defaults[] = { { .type = SI_KCS, .port = 0xca2 }, -- GitLab From aad756f869c445488f814a2bff9211d81c46535e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 19 Nov 2015 12:56:39 +0900 Subject: [PATCH 2660/2855] char: ipmi: Drop owner assignment from i2c_driver i2c_driver does not need to set an owner because i2c_register_driver() will set it. Signed-off-by: Krzysztof Kozlowski --- drivers/char/ipmi/ipmi_ssif.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index 90e6246622572..5f1c3d08ba654 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -1959,7 +1959,6 @@ MODULE_DEVICE_TABLE(i2c, ssif_id); static struct i2c_driver ssif_i2c_driver = { .class = I2C_CLASS_HWMON, .driver = { - .owner = THIS_MODULE, .name = DEVICE_NAME }, .probe = ssif_probe, -- GitLab From bb0dcebef99fd024c0fb2703179bc7d1fd5ee995 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 19 Nov 2015 19:24:33 -0500 Subject: [PATCH 2661/2855] ipmi: Remove unnecessary pci_disable_device. We call cleanup_one_si from ipmi_pci_remove, which calls ->addr_source_cleanup, which gets set to point to ipmi_pci_cleanup, which does a pci_disable_device. On return from this, we do a second pci_disable_device, which results in the trace below. ipmi_si 0000:00:16.0: disabling already-disabled device Call Trace: [] dump_stack+0x45/0x57 [] warn_slowpath_common+0x97/0xe0 [] warn_slowpath_fmt+0x46/0x50 [] pci_disable_device+0xb1/0xc0 [] ipmi_pci_remove+0x25/0x30 [ipmi_si] [] pci_device_remove+0x46/0xc0 [] __device_release_driver+0x7f/0xf0 [] driver_detach+0xb8/0xc0 [] bus_remove_driver+0x50/0xa0 [] driver_unregister+0x2e/0x60 [] pci_unregister_driver+0x25/0x90 [] cleanup_ipmi_si+0xd4/0xf0 [ipmi_si] [] SyS_delete_module+0x12a/0x200 [] system_call_fastpath+0x12/0x17 Signed-off-by: Dave Jones --- drivers/char/ipmi/ipmi_si_intf.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 440574de3cb47..9fda22e3387e5 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2559,7 +2559,6 @@ static void ipmi_pci_remove(struct pci_dev *pdev) { struct smi_info *info = pci_get_drvdata(pdev); cleanup_one_si(info); - pci_disable_device(pdev); } static const struct pci_device_id ipmi_pci_devices[] = { -- GitLab From c88c5d43732a0356f99e5e4d1ad62ab1ea516b81 Mon Sep 17 00:00:00 2001 From: Russell Currey Date: Wed, 13 Jan 2016 12:04:32 +1100 Subject: [PATCH 2662/2855] powerpc/powernv: Fix OPAL_CONSOLE_FLUSH prototype and usages The recently added OPAL API call, OPAL_CONSOLE_FLUSH, originally took no parameters and returned nothing. The call was updated to accept the terminal number to flush, and returned various values depending on the state of the output buffer. The prototype has been updated and its usage in the OPAL kmsg dumper has been modified to support its new behaviour as an incremental flush. Signed-off-by: Russell Currey Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/opal.h | 2 +- arch/powerpc/platforms/powernv/opal-kmsg.c | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index a5fd407213b6e..07a99e638449a 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -35,7 +35,7 @@ int64_t opal_console_read(int64_t term_number, __be64 *length, uint8_t *buffer); int64_t opal_console_write_buffer_space(int64_t term_number, __be64 *length); -void opal_console_flush(void); +int64_t opal_console_flush(int64_t term_number); int64_t opal_rtc_read(__be32 *year_month_day, __be64 *hour_minute_second_millisecond); int64_t opal_rtc_write(uint32_t year_month_day, diff --git a/arch/powerpc/platforms/powernv/opal-kmsg.c b/arch/powerpc/platforms/powernv/opal-kmsg.c index bd3b2ee1ba1d6..6f1214d4de926 100644 --- a/arch/powerpc/platforms/powernv/opal-kmsg.c +++ b/arch/powerpc/platforms/powernv/opal-kmsg.c @@ -27,6 +27,7 @@ static void force_opal_console_flush(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason) { int i; + int64_t ret; /* * Outside of a panic context the pollers will continue to run, @@ -36,7 +37,13 @@ static void force_opal_console_flush(struct kmsg_dumper *dumper, return; if (opal_check_token(OPAL_CONSOLE_FLUSH)) { - opal_console_flush(); + ret = opal_console_flush(0); + + if (ret == OPAL_UNSUPPORTED || ret == OPAL_PARAMETER) + return; + + /* Incrementally flush until there's nothing left */ + while (opal_console_flush(0) != OPAL_SUCCESS); } else { /* * If OPAL_CONSOLE_FLUSH is not implemented in the firmware, -- GitLab From 2e50c4bef77511b42cc226865d6bc568fa7f8769 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 12 Jan 2016 23:14:22 +1100 Subject: [PATCH 2663/2855] scripts/recordmcount.pl: support data in text section on powerpc If a text section starts out with a data blob before the first function start label, disassembly parsing doing in recordmcount.pl gets confused on powerpc, leading to creation of corrupted module objects. This was not a problem so far since the compiler would never create such text sections. However, this has changed with a recent change in GCC 6 to support distances of > 2GB between a function and its assoicated TOC in the ELFv2 ABI, exposing this problem. There is already code in recordmcount.pl to handle such data blobs on the sparc64 platform. This patch uses the same method to handle those on powerpc as well. Cc: stable@vger.kernel.org Acked-by: Steven Rostedt Signed-off-by: Ulrich Weigand Signed-off-by: Michael Ellerman --- scripts/recordmcount.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 826470d7f0007..96e2486a6fc47 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -263,7 +263,8 @@ if ($arch eq "x86_64") { } elsif ($arch eq "powerpc") { $local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)"; - $function_regex = "^([0-9a-fA-F]+)\\s+<(\\.?.*?)>:"; + # See comment in the sparc64 section for why we use '\w'. + $function_regex = "^([0-9a-fA-F]+)\\s+<(\\.?\\w*?)>:"; $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s\\.?_mcount\$"; if ($bits == 64) { -- GitLab From a61674bdfc7c2bf909c4010699607b62b69b7bec Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 12 Jan 2016 23:14:23 +1100 Subject: [PATCH 2664/2855] powerpc/module: Handle R_PPC64_ENTRY relocations GCC 6 will include changes to generated code with -mcmodel=large, which is used to build kernel modules on powerpc64le. This was necessary because the large model is supposed to allow arbitrary sizes and locations of the code and data sections, but the ELFv2 global entry point prolog still made the unconditional assumption that the TOC associated with any particular function can be found within 2 GB of the function entry point: func: addis r2,r12,(.TOC.-func)@ha addi r2,r2,(.TOC.-func)@l .localentry func, .-func To remove this assumption, GCC will now generate instead this global entry point prolog sequence when using -mcmodel=large: .quad .TOC.-func func: .reloc ., R_PPC64_ENTRY ld r2, -8(r12) add r2, r2, r12 .localentry func, .-func The new .reloc triggers an optimization in the linker that will replace this new prolog with the original code (see above) if the linker determines that the distance between .TOC. and func is in range after all. Since this new relocation is now present in module object files, the kernel module loader is required to handle them too. This patch adds support for the new relocation and implements the same optimization done by the GNU linker. Cc: stable@vger.kernel.org Signed-off-by: Ulrich Weigand Signed-off-by: Michael Ellerman --- arch/powerpc/include/uapi/asm/elf.h | 2 ++ arch/powerpc/kernel/module_64.c | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h index 59dad113897b0..c2d21d11c2d2c 100644 --- a/arch/powerpc/include/uapi/asm/elf.h +++ b/arch/powerpc/include/uapi/asm/elf.h @@ -295,6 +295,8 @@ do { \ #define R_PPC64_TLSLD 108 #define R_PPC64_TOCSAVE 109 +#define R_PPC64_ENTRY 118 + #define R_PPC64_REL16 249 #define R_PPC64_REL16_LO 250 #define R_PPC64_REL16_HI 251 diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 68384514506b7..59663af9315fc 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -635,6 +635,33 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, */ break; + case R_PPC64_ENTRY: + /* + * Optimize ELFv2 large code model entry point if + * the TOC is within 2GB range of current location. + */ + value = my_r2(sechdrs, me) - (unsigned long)location; + if (value + 0x80008000 > 0xffffffff) + break; + /* + * Check for the large code model prolog sequence: + * ld r2, ...(r12) + * add r2, r2, r12 + */ + if ((((uint32_t *)location)[0] & ~0xfffc) + != 0xe84c0000) + break; + if (((uint32_t *)location)[1] != 0x7c426214) + break; + /* + * If found, replace it with: + * addis r2, r12, (.TOC.-func)@ha + * addi r2, r12, (.TOC.-func)@l + */ + ((uint32_t *)location)[0] = 0x3c4c0000 + PPC_HA(value); + ((uint32_t *)location)[1] = 0x38420000 + PPC_LO(value); + break; + case R_PPC64_REL16_HA: /* Subtract location pointer */ value -= (unsigned long)location; -- GitLab From f1640c3ddeec12804bc9a21feee85fc15aca95f6 Mon Sep 17 00:00:00 2001 From: wangweidong Date: Wed, 13 Jan 2016 11:06:41 +0800 Subject: [PATCH 2665/2855] bgmac: fix a missing check for build_skb when build_skb failed, it may occure a NULL pointer. So add a 'NULL check' for it. Signed-off-by: Weidong Wang Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index c7798d3605123..397415217125e 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -466,6 +466,11 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, len -= ETH_FCS_LEN; skb = build_skb(buf, BGMAC_RX_ALLOC_SIZE); + if (unlikely(skb)) { + bgmac_err(bgmac, "build_skb failed\n"); + put_page(virt_to_head_page(buf)); + break; + } skb_put(skb, BGMAC_RX_FRAME_OFFSET + BGMAC_RX_BUF_OFFSET + len); skb_pull(skb, BGMAC_RX_FRAME_OFFSET + -- GitLab From 5f008c98598b80a64d7d8dc93b6c82af18783ac3 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 13 Jan 2016 09:43:46 +0100 Subject: [PATCH 2666/2855] Revert "INPUT: xpad: switch Logitech G920 Wheel into HID mode" This reverts commit 27b9d5a254dcbc6095404c1bab7c335419601eb8. I am reverting this one, while keeping the rest of the G920 support in, so that it immediately starts working once proper HID-mode switching is implemented. Quoting Dmitry Torokhov for rationale: == It is wrong. Aside form the fact that IMO xpad.c is the wrong place for this code to be in, why are we waiting for the input device to be opened by userspace before we do the switch instead of doing it immediately? == Several people (Simon Wood and Michal Maly) expressed the intent to work on proper HID switching in a short term. Signed-off-by: Jiri Kosina --- drivers/input/joystick/xpad.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 338a3a4f8996a..fd4100d56d8c5 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -93,7 +93,6 @@ #define MAP_STICKS_TO_NULL (1 << 2) #define DANCEPAD_MAP_CONFIG (MAP_DPAD_TO_BUTTONS | \ MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL) -#define SWITCH_G920_TO_HID_MODE (1 << 3) #define XTYPE_XBOX 0 #define XTYPE_XBOX360 1 @@ -135,7 +134,6 @@ static const struct xpad_device { { 0x046d, 0xc21e, "Logitech Gamepad F510", 0, XTYPE_XBOX360 }, { 0x046d, 0xc21f, "Logitech Gamepad F710", 0, XTYPE_XBOX360 }, { 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 }, - { 0x046d, 0xc261, "Logitech G920 Driving Force Racing Wheel", SWITCH_G920_TO_HID_MODE, XTYPE_XBOXONE }, { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX }, { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX }, { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", 0, XTYPE_XBOX }, @@ -301,7 +299,6 @@ static struct usb_device_id xpad_table[] = { XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */ XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ - XPAD_XBOXONE_VENDOR(0x046d), /* Logitech X-Box One style controllers */ XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */ @@ -1051,19 +1048,6 @@ static int xpad_open(struct input_dev *dev) if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) return -EIO; - /* Logitect G920 wheel starts in XBOX mode, but is reconfigured to be HID */ - /* device with USBID of 046D:C262. Wheel will detach when 'magic' is sent. */ - if (xpad->mapping & SWITCH_G920_TO_HID_MODE) { - xpad->odata[0] = 0x0F; - xpad->odata[1] = 0x00; - xpad->odata[2] = 0x01; - xpad->odata[3] = 0x01; - xpad->odata[4] = 0x42; - xpad->irq_out->transfer_buffer_length = 5; - - return usb_submit_urb(xpad->irq_out, GFP_KERNEL); - } - if (xpad->xtype == XTYPE_XBOXONE) { /* Xbox one controller needs to be initialized. */ xpad->odata[0] = 0x05; -- GitLab From 65cacec1ba908a153cfb19c4de596a108f95970c Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Tue, 12 Jan 2016 11:56:15 -0800 Subject: [PATCH 2667/2855] selftests/x86: Test __kernel_sigreturn and __kernel_rt_sigreturn The vdso-based sigreturn mechanism is fragile and isn't used by modern glibc so, if we break it, we'll only notice when someone tests an unusual libc. Add an explicit selftest. [ I wrote this while debugging a Bionic breakage -- my first guess was that I had somehow messed up sigreturn. I've caused problems in that code before, and it's really easy to fail to notice it because there's nothing on a modern distro that needs vdso-based sigreturn. ] Signed-off-by: Andy Lutomirski Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Shuah Khan Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/32946d714156879cd8e5d8eab044cd07557ed558.1452628504.git.luto@kernel.org Signed-off-by: Ingo Molnar --- tools/testing/selftests/x86/Makefile | 3 +- tools/testing/selftests/x86/vdso_restorer.c | 88 +++++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/x86/vdso_restorer.c diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index 398bb0e6e38cc..d0c473f658505 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile @@ -7,7 +7,8 @@ include ../lib.mk TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault sigreturn test_syscall_vdso unwind_vdso \ test_FCMOV test_FCOMI test_FISTTP \ - ldt_gdt + ldt_gdt \ + vdso_restorer TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32) diff --git a/tools/testing/selftests/x86/vdso_restorer.c b/tools/testing/selftests/x86/vdso_restorer.c new file mode 100644 index 0000000000000..cb038424a4032 --- /dev/null +++ b/tools/testing/selftests/x86/vdso_restorer.c @@ -0,0 +1,88 @@ +/* + * vdso_restorer.c - tests vDSO-based signal restore + * Copyright (c) 2015 Andrew Lutomirski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * This makes sure that sa_restorer == NULL keeps working on 32-bit + * configurations. Modern glibc doesn't use it under any circumstances, + * so it's easy to overlook breakage. + * + * 64-bit userspace has never supported sa_restorer == NULL, so this is + * 32-bit only. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include + +/* Open-code this -- the headers are too messy to easily use them. */ +struct real_sigaction { + void *handler; + unsigned long flags; + void *restorer; + unsigned int mask[2]; +}; + +static volatile sig_atomic_t handler_called; + +static void handler_with_siginfo(int sig, siginfo_t *info, void *ctx_void) +{ + handler_called = 1; +} + +static void handler_without_siginfo(int sig) +{ + handler_called = 1; +} + +int main() +{ + int nerrs = 0; + struct real_sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.handler = handler_with_siginfo; + sa.flags = SA_SIGINFO; + sa.restorer = NULL; /* request kernel-provided restorer */ + + if (syscall(SYS_rt_sigaction, SIGUSR1, &sa, NULL, 8) != 0) + err(1, "raw rt_sigaction syscall"); + + raise(SIGUSR1); + + if (handler_called) { + printf("[OK]\tSA_SIGINFO handler returned successfully\n"); + } else { + printf("[FAIL]\tSA_SIGINFO handler was not called\n"); + nerrs++; + } + + sa.flags = 0; + sa.handler = handler_without_siginfo; + if (syscall(SYS_sigaction, SIGUSR1, &sa, 0) != 0) + err(1, "raw sigaction syscall"); + handler_called = 0; + + raise(SIGUSR1); + + if (handler_called) { + printf("[OK]\t!SA_SIGINFO handler returned successfully\n"); + } else { + printf("[FAIL]\t!SA_SIGINFO handler was not called\n"); + nerrs++; + } +} -- GitLab From 4eaffdd5a5fe6ff9f95e1ab4de1ac904d5e0fa8b Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Tue, 12 Jan 2016 12:47:40 -0800 Subject: [PATCH 2668/2855] x86/mm: Improve switch_mm() barrier comments My previous comments were still a bit confusing and there was a typo. Fix it up. Reported-by: Peter Zijlstra Signed-off-by: Andy Lutomirski Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Dave Hansen Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Rik van Riel Cc: Thomas Gleixner Cc: stable@vger.kernel.org Fixes: 71b3c126e611 ("x86/mm: Add barriers and document switch_mm()-vs-flush synchronization") Link: http://lkml.kernel.org/r/0a0b43cdcdd241c5faaaecfbcc91a155ddedc9a1.1452631609.git.luto@kernel.org Signed-off-by: Ingo Molnar --- arch/x86/include/asm/mmu_context.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 1edc9cd198b85..bfd9b2a35a0b1 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -132,14 +132,16 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, * be sent, and CPU 0's TLB will contain a stale entry.) * * The bad outcome can occur if either CPU's load is - * reordered before that CPU's store, so both CPUs much + * reordered before that CPU's store, so both CPUs must * execute full barriers to prevent this from happening. * * Thus, switch_mm needs a full barrier between the * store to mm_cpumask and any operation that could load - * from next->pgd. This barrier synchronizes with - * remote TLB flushers. Fortunately, load_cr3 is - * serializing and thus acts as a full barrier. + * from next->pgd. TLB fills are special and can happen + * due to instruction fetches or for no reason at all, + * and neither LOCK nor MFENCE orders them. + * Fortunately, load_cr3() is serializing and gives the + * ordering guarantee we need. * */ load_cr3(next->pgd); @@ -188,9 +190,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, * tlb flush IPI delivery. We must reload CR3 * to make sure to use no freed page tables. * - * As above, this is a barrier that forces - * TLB repopulation to be ordered after the - * store to mm_cpumask. + * As above, load_cr3() is serializing and orders TLB + * fills with respect to the mm_cpumask write. */ load_cr3(next->pgd); trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL); -- GitLab From c698d639f72b55686ec3518d2bc8dc5f2eca9354 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Dec 2015 15:33:19 -0500 Subject: [PATCH 2669/2855] i2c: create builtin_i2c_driver to avoid registration boilerplate In commit f309d4443130bf814e991f836e919dca22df37ae ("platform_device: better support builtin boilerplate avoidance") we introduced the builtin_driver macro. Here we use that support and extend it to I2C driver registration, so where a driver is clearly non-modular and builtin-only, we can register it in a similar fashion. And existing code that is clearly non-modular can be updated with the simple mapping of module_i2c_driver(...) ---> builtin_i2c_driver(...) We've essentially cloned the former to make the latter, and taken out the remove/module_exit parts since those never get used in a non-modular build of the code. A similar thing was done in commit b4eb6cdbbd13698704863f680c643c569909e1c2 ("PCI: Add builtin_pci_driver() to avoid registration boilerplate"). Signed-off-by: Paul Gortmaker Signed-off-by: Wolfram Sang --- include/linux/i2c.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index bc2b19ad93578..200cf13b00f62 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -655,7 +655,7 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap) } /** - * module_i2c_driver() - Helper macro for registering a I2C driver + * module_i2c_driver() - Helper macro for registering a modular I2C driver * @__i2c_driver: i2c_driver struct * * Helper macro for I2C drivers which do not do anything special in module @@ -666,6 +666,17 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap) module_driver(__i2c_driver, i2c_add_driver, \ i2c_del_driver) +/** + * builtin_i2c_driver() - Helper macro for registering a builtin I2C driver + * @__i2c_driver: i2c_driver struct + * + * Helper macro for I2C drivers which do not do anything special in their + * init. This eliminates a lot of boilerplate. Each driver may only + * use this macro once, and calling it replaces device_initcall(). + */ +#define builtin_i2c_driver(__i2c_driver) \ + builtin_driver(__i2c_driver, i2c_add_driver) + #endif /* I2C */ #if IS_ENABLED(CONFIG_OF) -- GitLab From 78fd8c7288e0a4bba3ad1d69caf9396a6b69cb00 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Mon, 4 Jan 2016 15:14:28 -0800 Subject: [PATCH 2670/2855] x86/vdso/pvclock: Protect STABLE check with the seqcount If the clock becomes unstable while we're reading it, we need to bail. We can do this by simply moving the check into the seqcount loop. Reported-by: Marcelo Tosatti Signed-off-by: Andy Lutomirski Cc: Alexander Graf Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Paolo Bonzini Cc: Peter Zijlstra Cc: Radim Krcmar Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/755dcedb17269e1d7ce12a9a713dea303835137e.1451949191.git.luto@kernel.org Signed-off-by: Ingo Molnar --- arch/x86/entry/vdso/vclock_gettime.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/x86/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c index 8602f06c759f7..1a50e09c945bd 100644 --- a/arch/x86/entry/vdso/vclock_gettime.c +++ b/arch/x86/entry/vdso/vclock_gettime.c @@ -126,23 +126,23 @@ static notrace cycle_t vread_pvclock(int *mode) * * On Xen, we don't appear to have that guarantee, but Xen still * supplies a valid seqlock using the version field. - + * * We only do pvclock vdso timing at all if * PVCLOCK_TSC_STABLE_BIT is set, and we interpret that bit to * mean that all vCPUs have matching pvti and that the TSC is * synced, so we can just look at vCPU 0's pvti. */ - if (unlikely(!(pvti->flags & PVCLOCK_TSC_STABLE_BIT))) { - *mode = VCLOCK_NONE; - return 0; - } - do { version = pvti->version; smp_rmb(); + if (unlikely(!(pvti->flags & PVCLOCK_TSC_STABLE_BIT))) { + *mode = VCLOCK_NONE; + return 0; + } + tsc = rdtsc_ordered(); pvti_tsc_to_system_mul = pvti->tsc_to_system_mul; pvti_tsc_shift = pvti->tsc_shift; -- GitLab From af63cf51b7f960aa73b32bac683cd4078f08fa0e Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Mon, 30 Nov 2015 17:34:01 +0100 Subject: [PATCH 2671/2855] batman-adv: fix lockdep splat when doing mcast_free While testing, we got something like this: WARNING: CPU: 0 PID: 238 at net/batman-adv/multicast.c:142 batadv_mcast_mla_tt_retract+0x94/0x205 [batman_adv]() [...] Call Trace: [] dump_stack+0x4b/0x64 [] warn_slowpath_common+0xbc/0x120 [] ? batadv_mcast_mla_tt_retract+0x94/0x205 [batman_adv] [] warn_slowpath_null+0x15/0x20 [] batadv_mcast_mla_tt_retract+0x94/0x205 [batman_adv] [] batadv_mcast_free+0x36/0x39 [batman_adv] [] batadv_mesh_free+0x7d/0x13f [batman_adv] [] batadv_softif_free+0x15/0x25 [batman_adv] [...] Signed-off-by: Simon Wunderlich Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/multicast.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c index eb76386f8d4b5..75fa5013af724 100644 --- a/net/batman-adv/multicast.c +++ b/net/batman-adv/multicast.c @@ -802,7 +802,9 @@ void batadv_mcast_free(struct batadv_priv *bat_priv) batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 1); batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 1); + spin_lock_bh(&bat_priv->tt.commit_lock); batadv_mcast_mla_tt_retract(bat_priv, NULL); + spin_unlock_bh(&bat_priv->tt.commit_lock); } /** -- GitLab From bab7c6c3deac70966a3000402c0ea6d0c20edd15 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Tue, 5 Jan 2016 12:06:17 +0100 Subject: [PATCH 2672/2855] batman-adv: Fix list removal of batadv_hardif_neigh_node The neigh_list with batadv_hardif_neigh_node objects is accessed with only rcu_read_lock in batadv_hardif_neigh_get and batadv_iv_neigh_print. Thus it is not allowed to kfree the object before the rcu grace period ends (which may still protects context accessing this object). Therefore the object has first to be removed from the neigh_list and then it has either wait with synchronize_rcu or call_rcu till the grace period ends before it can be freed. Fixes: cef63419f7db ("batman-adv: add list of unique single hop neighbors per hard-interface") Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/originator.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 3c782a33bdac5..ae6d18cafc5a1 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -211,10 +211,6 @@ static void batadv_hardif_neigh_free_rcu(struct rcu_head *rcu) hardif_neigh = container_of(rcu, struct batadv_hardif_neigh_node, rcu); - spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock); - hlist_del_init_rcu(&hardif_neigh->list); - spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock); - batadv_hardif_free_ref_now(hardif_neigh->if_incoming); kfree(hardif_neigh); } @@ -227,8 +223,13 @@ static void batadv_hardif_neigh_free_rcu(struct rcu_head *rcu) static void batadv_hardif_neigh_free_now(struct batadv_hardif_neigh_node *hardif_neigh) { - if (atomic_dec_and_test(&hardif_neigh->refcount)) + if (atomic_dec_and_test(&hardif_neigh->refcount)) { + spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock); + hlist_del_init_rcu(&hardif_neigh->list); + spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock); + batadv_hardif_neigh_free_rcu(&hardif_neigh->rcu); + } } /** @@ -238,8 +239,13 @@ batadv_hardif_neigh_free_now(struct batadv_hardif_neigh_node *hardif_neigh) */ void batadv_hardif_neigh_free_ref(struct batadv_hardif_neigh_node *hardif_neigh) { - if (atomic_dec_and_test(&hardif_neigh->refcount)) + if (atomic_dec_and_test(&hardif_neigh->refcount)) { + spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock); + hlist_del_init_rcu(&hardif_neigh->list); + spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock); + call_rcu(&hardif_neigh->rcu, batadv_hardif_neigh_free_rcu); + } } /** -- GitLab From b8e429a2feac623a34e21099a4a69de29b6d873e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 13 Jan 2016 10:28:06 -0500 Subject: [PATCH 2673/2855] genetlink: Fix off-by-one in genl_allocate_reserve_groups() The bug fix for adding n_groups to the computation forgot to adjust ">=" to ">" to keep the condition correct. Signed-off-by: David S. Miller --- net/netlink/genetlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index d3f6b063467ba..f830326b3b1db 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -185,7 +185,7 @@ static int genl_allocate_reserve_groups(int n_groups, int *first_id) } } - if (id + n_groups >= mc_groups_longs * BITS_PER_LONG) { + if (id + n_groups > mc_groups_longs * BITS_PER_LONG) { unsigned long new_longs = mc_groups_longs + BITS_TO_LONGS(n_groups); size_t nlen = new_longs * sizeof(unsigned long); -- GitLab From 00ae40e71d85ea3fed1b906951ffd80e0321a96d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 13 Jan 2016 15:28:23 +0300 Subject: [PATCH 2674/2855] mlxsw: fix SWITCHDEV_OBJ_ID_PORT_MDB There is a missing break statement so we always return -EOPNOTSUPP. Fixes: 3a49b4fde2a1 ('mlxsw: Adding layer 2 multicast support') Signed-off-by: Dan Carpenter Acked-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c index ffe894e6d2877..45479ef5bcf4f 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c @@ -1015,6 +1015,7 @@ static int mlxsw_sp_port_obj_del(struct net_device *dev, case SWITCHDEV_OBJ_ID_PORT_MDB: err = mlxsw_sp_port_mdb_del(mlxsw_sp_port, SWITCHDEV_OBJ_PORT_MDB(obj)); + break; default: err = -EOPNOTSUPP; break; -- GitLab From 3b780bed3138c2a8061c218df7e321beec9a6ec9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 13 Jan 2016 11:45:39 -0500 Subject: [PATCH 2675/2855] x25_asy: Free x25_asy on x25_asy_open() failure. Based upon a report by Dmitry Vyukov. Signed-off-by: David S. Miller --- drivers/net/wan/x25_asy.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index cd39025d2abf5..1bc5e93d2a342 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -571,8 +571,10 @@ static int x25_asy_open_tty(struct tty_struct *tty) /* Perform the low-level X.25 async init */ err = x25_asy_open(sl->dev); - if (err) + if (err) { + x25_asy_free(sl); return err; + } /* Done. We have linked the TTY line to a channel. */ return 0; } -- GitLab From 809267708557ed5575831282f719ca644698084b Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 12 Jan 2016 14:22:45 +0100 Subject: [PATCH 2676/2855] ia64: split off early_ioremap() declarations into asm/early_ioremap.h Unlike x86, arm64 and ARM, ia64 does not declare its implementations of early_ioremap/early_iounmap/early_memremap/early_memunmap in a header file called This complicates the use of these functions in generic code, since the header cannot be included directly, and we have to rely on transitive includes, which is fragile. So create a for ia64, and move the existing definitions into it. Signed-off-by: Ard Biesheuvel Signed-off-by: Tony Luck --- arch/ia64/include/asm/early_ioremap.h | 10 ++++++++++ arch/ia64/include/asm/io.h | 5 +---- 2 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 arch/ia64/include/asm/early_ioremap.h diff --git a/arch/ia64/include/asm/early_ioremap.h b/arch/ia64/include/asm/early_ioremap.h new file mode 100644 index 0000000000000..eec9e1d1b833c --- /dev/null +++ b/arch/ia64/include/asm/early_ioremap.h @@ -0,0 +1,10 @@ +#ifndef _ASM_IA64_EARLY_IOREMAP_H +#define _ASM_IA64_EARLY_IOREMAP_H + +extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size); +#define early_memremap(phys_addr, size) early_ioremap(phys_addr, size) + +extern void early_iounmap (volatile void __iomem *addr, unsigned long size); +#define early_memunmap(addr, size) early_iounmap(addr, size) + +#endif diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h index 9041bbe2b7b42..a865d2a04f75b 100644 --- a/arch/ia64/include/asm/io.h +++ b/arch/ia64/include/asm/io.h @@ -20,6 +20,7 @@ */ #include +#include /* We don't use IO slowdowns on the ia64, but.. */ #define __SLOW_DOWN_IO do { } while (0) @@ -427,10 +428,6 @@ __writeq (unsigned long val, volatile void __iomem *addr) extern void __iomem * ioremap(unsigned long offset, unsigned long size); extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size); extern void iounmap (volatile void __iomem *addr); -extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size); -#define early_memremap(phys_addr, size) early_ioremap(phys_addr, size) -extern void early_iounmap (volatile void __iomem *addr, unsigned long size); -#define early_memunmap(addr, size) early_iounmap(addr, size) static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size) { return ioremap(phys_addr, size); -- GitLab From 0f7f2f0c0fcbe5e2bcba707a628ebaedfe2be4b4 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 12 Jan 2016 14:22:46 +0100 Subject: [PATCH 2677/2855] efi: include asm/early_ioremap.h not asm/efi.h to get early_memremap The code in efi.c uses early_memremap(), but relies on a transitive include rather than including asm/early_ioremap.h directly, since this header did not exist on ia64. Commit f7d924894265 ("arm64/efi: refactor EFI init and runtime code for reuse by 32-bit ARM") attempted to work around this by including asm/efi.h, which transitively includes asm/early_ioremap.h on most architectures. However, since asm/efi.h does not exist on ia64 either, this is not much of an improvement. Now that we have created an asm/early_ioremap.h for ia64, we can just include it directly. Reported-by: Guenter Roeck Signed-off-by: Ard Biesheuvel Signed-off-by: Tony Luck --- drivers/firmware/efi/efi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index cffa89b3317b5..2cd37dad67a63 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -25,7 +25,7 @@ #include #include -#include +#include struct efi __read_mostly efi = { .mps = EFI_INVALID_TABLE_ADDR, -- GitLab From 7356f4e42490d91939521c70b04812d5a07bd0f2 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Wed, 13 Jan 2016 12:43:53 -0500 Subject: [PATCH 2678/2855] 3c59x: balance page maps and unmaps debug kernel noticed a screw up in 3c59x. skbs being mapped as page were being unmapped as singles. Easy fix. Tested by myself Signed-off-by: Neil Horman CC: Steffen Klassert Signed-off-by: David S. Miller --- drivers/net/ethernet/3com/3c59x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index 1c5f3b273e6ac..4c3bc31067166 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c @@ -2460,7 +2460,7 @@ boomerang_interrupt(int irq, void *dev_id) #if DO_ZEROCOPY int i; for (i=0; i<=skb_shinfo(skb)->nr_frags; i++) - pci_unmap_single(VORTEX_PCI(vp), + pci_unmap_page(VORTEX_PCI(vp), le32_to_cpu(vp->tx_ring[entry].frag[i].addr), le32_to_cpu(vp->tx_ring[entry].frag[i].length)&0xFFF, PCI_DMA_TODEVICE); -- GitLab From 6e144419e4da11a9a4977c8d899d7247d94ca338 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Wed, 13 Jan 2016 12:43:54 -0500 Subject: [PATCH 2679/2855] 3c59x: fix another page map/single unmap imbalance libdma debug found another page map/unmap imbalance in 3c59x. Multi fragment frames are mapped such that the lead fragment was mapped as a single entry, while all other fragments were mapped as pages. However, on unmapping they were all unmapped as pages. Fix is pretty easy, just unmap the lead frag as a single entry, and bump the for loop initalization up by one so that all subsequent frags get unmapped as pages Signed-off-by: Neil Horman CC: "David S. Miller" CC: Steffen Klassert Signed-off-by: David S. Miller --- drivers/net/ethernet/3com/3c59x.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index 4c3bc31067166..79e1a0282163d 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c @@ -2459,7 +2459,12 @@ boomerang_interrupt(int irq, void *dev_id) struct sk_buff *skb = vp->tx_skbuff[entry]; #if DO_ZEROCOPY int i; - for (i=0; i<=skb_shinfo(skb)->nr_frags; i++) + pci_unmap_single(VORTEX_PCI(vp), + le32_to_cpu(vp->tx_ring[entry].frag[0].addr), + le32_to_cpu(vp->tx_ring[entry].frag[0].length), + PCI_DMA_TODEVICE); + + for (i=1; i<=skb_shinfo(skb)->nr_frags; i++) pci_unmap_page(VORTEX_PCI(vp), le32_to_cpu(vp->tx_ring[entry].frag[i].addr), le32_to_cpu(vp->tx_ring[entry].frag[i].length)&0xFFF, -- GitLab From 701a0fd5231866db08cebcd502894699f49cb960 Mon Sep 17 00:00:00 2001 From: wangweidong Date: Wed, 13 Jan 2016 11:11:09 +0800 Subject: [PATCH 2680/2855] hip04_eth: fix missing error handle for build_skb failed when build_skb failed, we should goto refill the buffer. Signed-off-by: Weidong Wang Acked-by: Ding Tainhong Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hip04_eth.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/hisilicon/hip04_eth.c b/drivers/net/ethernet/hisilicon/hip04_eth.c index 253f8ed0537a0..0c4afe95ef54a 100644 --- a/drivers/net/ethernet/hisilicon/hip04_eth.c +++ b/drivers/net/ethernet/hisilicon/hip04_eth.c @@ -500,8 +500,10 @@ static int hip04_rx_poll(struct napi_struct *napi, int budget) while (cnt && !last) { buf = priv->rx_buf[priv->rx_head]; skb = build_skb(buf, priv->rx_buf_size); - if (unlikely(!skb)) + if (unlikely(!skb)) { net_dbg_ratelimited("build_skb failed\n"); + goto refill; + } dma_unmap_single(&ndev->dev, priv->rx_phys[priv->rx_head], RX_BUF_SIZE, DMA_FROM_DEVICE); @@ -528,6 +530,7 @@ static int hip04_rx_poll(struct napi_struct *napi, int budget) rx++; } +refill: buf = netdev_alloc_frag(priv->rx_buf_size); if (!buf) goto done; -- GitLab From 183223770ae8625df8966ed15811d1b3ee8720aa Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Thu, 5 Nov 2015 00:12:49 +1100 Subject: [PATCH 2681/2855] drivers/of: Export OF changeset functions The PowerNV PCI hotplug driver is going to use the OF changeset to manage the changed device sub-tree. This exports those OF changeset functions for that. Signed-off-by: Gavin Shan Acked-by: Wolfram Sang Tested-by: Wolfram Sang Signed-off-by: Rob Herring --- drivers/of/dynamic.c | 65 +++++++++++++++++++++++++++++------------ drivers/of/of_private.h | 2 ++ drivers/of/overlay.c | 8 ++--- drivers/of/unittest.c | 4 --- 4 files changed, 52 insertions(+), 27 deletions(-) diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 53826b84e0ec6..c647bd1b69033 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -646,6 +646,7 @@ void of_changeset_init(struct of_changeset *ocs) memset(ocs, 0, sizeof(*ocs)); INIT_LIST_HEAD(&ocs->entries); } +EXPORT_SYMBOL_GPL(of_changeset_init); /** * of_changeset_destroy - Destroy a changeset @@ -662,20 +663,9 @@ void of_changeset_destroy(struct of_changeset *ocs) list_for_each_entry_safe_reverse(ce, cen, &ocs->entries, node) __of_changeset_entry_destroy(ce); } +EXPORT_SYMBOL_GPL(of_changeset_destroy); -/** - * of_changeset_apply - Applies a changeset - * - * @ocs: changeset pointer - * - * Applies a changeset to the live tree. - * Any side-effects of live tree state changes are applied here on - * sucess, like creation/destruction of devices and side-effects - * like creation of sysfs properties and directories. - * Returns 0 on success, a negative error value in case of an error. - * On error the partially applied effects are reverted. - */ -int of_changeset_apply(struct of_changeset *ocs) +int __of_changeset_apply(struct of_changeset *ocs) { struct of_changeset_entry *ce; int ret; @@ -704,17 +694,30 @@ int of_changeset_apply(struct of_changeset *ocs) } /** - * of_changeset_revert - Reverts an applied changeset + * of_changeset_apply - Applies a changeset * * @ocs: changeset pointer * - * Reverts a changeset returning the state of the tree to what it - * was before the application. - * Any side-effects like creation/destruction of devices and - * removal of sysfs properties and directories are applied. + * Applies a changeset to the live tree. + * Any side-effects of live tree state changes are applied here on + * success, like creation/destruction of devices and side-effects + * like creation of sysfs properties and directories. * Returns 0 on success, a negative error value in case of an error. + * On error the partially applied effects are reverted. */ -int of_changeset_revert(struct of_changeset *ocs) +int of_changeset_apply(struct of_changeset *ocs) +{ + int ret; + + mutex_lock(&of_mutex); + ret = __of_changeset_apply(ocs); + mutex_unlock(&of_mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(of_changeset_apply); + +int __of_changeset_revert(struct of_changeset *ocs) { struct of_changeset_entry *ce; int ret; @@ -741,6 +744,29 @@ int of_changeset_revert(struct of_changeset *ocs) return 0; } +/** + * of_changeset_revert - Reverts an applied changeset + * + * @ocs: changeset pointer + * + * Reverts a changeset returning the state of the tree to what it + * was before the application. + * Any side-effects like creation/destruction of devices and + * removal of sysfs properties and directories are applied. + * Returns 0 on success, a negative error value in case of an error. + */ +int of_changeset_revert(struct of_changeset *ocs) +{ + int ret; + + mutex_lock(&of_mutex); + ret = __of_changeset_revert(ocs); + mutex_unlock(&of_mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(of_changeset_revert); + /** * of_changeset_action - Perform a changeset action * @@ -779,3 +805,4 @@ int of_changeset_action(struct of_changeset *ocs, unsigned long action, list_add_tail(&ce->node, &ocs->entries); return 0; } +EXPORT_SYMBOL_GPL(of_changeset_action); diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index 8e882e706cd8c..829469faeb233 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -45,6 +45,8 @@ static inline struct device_node *kobj_to_device_node(struct kobject *kobj) extern int of_property_notify(int action, struct device_node *np, struct property *prop, struct property *old_prop); extern void of_node_release(struct kobject *kobj); +extern int __of_changeset_apply(struct of_changeset *ocs); +extern int __of_changeset_revert(struct of_changeset *ocs); #else /* CONFIG_OF_DYNAMIC */ static inline int of_property_notify(int action, struct device_node *np, struct property *prop, struct property *old_prop) diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 54e5af9d73774..82250815e9a56 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -379,9 +379,9 @@ int of_overlay_create(struct device_node *tree) } /* apply the changeset */ - err = of_changeset_apply(&ov->cset); + err = __of_changeset_apply(&ov->cset); if (err) { - pr_err("%s: of_changeset_apply() failed for tree@%s\n", + pr_err("%s: __of_changeset_apply() failed for tree@%s\n", __func__, tree->full_name); goto err_revert_overlay; } @@ -511,7 +511,7 @@ int of_overlay_destroy(int id) list_del(&ov->node); - of_changeset_revert(&ov->cset); + __of_changeset_revert(&ov->cset); of_free_overlay_info(ov); idr_remove(&ov_idr, id); of_changeset_destroy(&ov->cset); @@ -542,7 +542,7 @@ int of_overlay_destroy_all(void) /* the tail of list is guaranteed to be safe to remove */ list_for_each_entry_safe_reverse(ov, ovn, &ov_list, node) { list_del(&ov->node); - of_changeset_revert(&ov->cset); + __of_changeset_revert(&ov->cset); of_free_overlay_info(ov); idr_remove(&ov_idr, ov->id); kfree(ov); diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index bbff09dee1cf4..979b6e415cea0 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -530,18 +530,14 @@ static void __init of_unittest_changeset(void) unittest(!of_changeset_add_property(&chgset, parent, ppadd), "fail add prop\n"); unittest(!of_changeset_update_property(&chgset, parent, ppupdate), "fail update prop\n"); unittest(!of_changeset_remove_property(&chgset, parent, ppremove), "fail remove prop\n"); - mutex_lock(&of_mutex); unittest(!of_changeset_apply(&chgset), "apply failed\n"); - mutex_unlock(&of_mutex); /* Make sure node names are constructed correctly */ unittest((np = of_find_node_by_path("/testcase-data/changeset/n2/n21")), "'%s' not added\n", n21->full_name); of_node_put(np); - mutex_lock(&of_mutex); unittest(!of_changeset_revert(&chgset), "revert failed\n"); - mutex_unlock(&of_mutex); of_changeset_destroy(&chgset); #endif -- GitLab From 265b60497a57da56a4be7d5c72983ae89dc0765e Mon Sep 17 00:00:00 2001 From: Liu Xiang Date: Sat, 9 Jan 2016 22:10:39 +0800 Subject: [PATCH 2682/2855] power: bq27xxx_battery: Fix bq27541 AveragePower register address Currently in bq27541 driver, the average power register address is incorrectly set to 0x76, which would result in an error: bq27xxx-battery 2-0055: error reading average power register 10: -11 According to the bq27541 datasheet, fix this problem by setting the average power register address to 0x24. Fixes: d74534c27775 ("power: bq27xxx_battery: Add support for additional bq27xxx family devices") Signed-off-by: Liu Xiang Acked-by: Andrew F. Davis Signed-off-by: Sebastian Reichel --- drivers/power/bq27xxx_battery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c index 73b647b493ba6..6b027a418943a 100644 --- a/drivers/power/bq27xxx_battery.c +++ b/drivers/power/bq27xxx_battery.c @@ -199,7 +199,7 @@ static u8 bq27541_regs[] = { INVALID_REG_ADDR, /* AE - NA */ 0x2c, /* SOC(RSOC) */ 0x3c, /* DCAP */ - 0x76, /* AP */ + 0x24, /* AP */ }; static u8 bq27545_regs[] = { -- GitLab From a62ab49eb502a07814f9942770893118c6281223 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Wed, 6 Jan 2016 14:37:13 -0800 Subject: [PATCH 2683/2855] md: set MD_HAS_JOURNAL in correct places Set MD_HAS_JOURNAL when a array is loaded or journal is initialized. This is to avoid the flags set too early in journal disk hotadd. Signed-off-by: Shaohua Li Signed-off-by: NeilBrown --- drivers/md/md.c | 9 +++++---- drivers/md/raid5-cache.c | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 0d1d822eeda51..29a4bbf62be53 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1597,6 +1597,11 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev) mddev->new_chunk_sectors = mddev->chunk_sectors; } + if (le32_to_cpu(sb->feature_map) & MD_FEATURE_JOURNAL) { + set_bit(MD_HAS_JOURNAL, &mddev->flags); + if (mddev->recovery_cp == MaxSector) + set_bit(MD_JOURNAL_CLEAN, &mddev->flags); + } } else if (mddev->pers == NULL) { /* Insist of good event counter while assembling, except for * spares (which don't need an event count) */ @@ -1643,8 +1648,6 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev) } set_bit(Journal, &rdev->flags); rdev->journal_tail = le64_to_cpu(sb->journal_tail); - if (mddev->recovery_cp == MaxSector) - set_bit(MD_JOURNAL_CLEAN, &mddev->flags); rdev->raid_disk = 0; break; default: @@ -1664,8 +1667,6 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev) set_bit(WriteMostly, &rdev->flags); if (le32_to_cpu(sb->feature_map) & MD_FEATURE_REPLACEMENT) set_bit(Replacement, &rdev->flags); - if (le32_to_cpu(sb->feature_map) & MD_FEATURE_JOURNAL) - set_bit(MD_HAS_JOURNAL, &mddev->flags); } else /* MULTIPATH are always insync */ set_bit(In_sync, &rdev->flags); diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index 6d2b4789a928a..7ac035a73281c 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c @@ -1235,6 +1235,7 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev) goto error; rcu_assign_pointer(conf->log, log); + set_bit(MD_HAS_JOURNAL, &conf->mddev->flags); return 0; error: -- GitLab From 87d4d91616e4db9b8293ba9d9e5a2f3f0d0c8aa6 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Wed, 6 Jan 2016 14:37:14 -0800 Subject: [PATCH 2684/2855] MD: add journal with array suspended Hot add journal disk in recovery thread context brings a lot of trouble as IO could be running. Unlike spare disk hot add, adding journal disk with array suspended makes more sense and implmentation is much easier. Signed-off-by: Shaohua Li Signed-off-by: NeilBrown --- drivers/md/md.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 29a4bbf62be53..8753dee3983be 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2455,15 +2455,20 @@ static int add_bound_rdev(struct md_rdev *rdev) { struct mddev *mddev = rdev->mddev; int err = 0; + bool add_journal = test_bit(Journal, &rdev->flags); - if (!mddev->pers->hot_remove_disk) { + if (!mddev->pers->hot_remove_disk || add_journal) { /* If there is hot_add_disk but no hot_remove_disk * then added disks for geometry changes, * and should be added immediately. */ super_types[mddev->major_version]. validate_super(mddev, rdev); + if (add_journal) + mddev_suspend(mddev); err = mddev->pers->hot_add_disk(mddev, rdev); + if (add_journal) + mddev_resume(mddev); if (err) { unbind_rdev_from_array(rdev); export_rdev(rdev); -- GitLab From 16a43f6a65002ba9a5b063764b4ad5d288a1c15e Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Wed, 6 Jan 2016 14:37:15 -0800 Subject: [PATCH 2685/2855] raid5-cache: handle journal hotadd in quiesce Handle journal hotadd in quiesce to avoid creating duplicated threads. Signed-off-by: Shaohua Li Signed-off-by: NeilBrown --- drivers/md/raid5-cache.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index 7ac035a73281c..9531f5f05b93d 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c @@ -827,6 +827,13 @@ void r5l_quiesce(struct r5l_log *log, int state) return; if (state == 0) { log->in_teardown = 0; + /* + * This is a special case for hotadd. In suspend, the array has + * no journal. In resume, journal is initialized as well as the + * reclaim thread. + */ + if (log->reclaim_thread) + return; log->reclaim_thread = md_register_thread(r5l_reclaim_thread, log->rdev->mddev, "reclaim"); } else if (state == 1) { -- GitLab From 7aafc405ce5b706195e5df26305a0241b01d8d06 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 8 Jan 2016 14:11:02 +1100 Subject: [PATCH 2686/2855] Remove myself as MD Maintainer, and add to Credits. Signed-off-by: NeilBrown --- CREDITS | 1 + MAINTAINERS | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/CREDITS b/CREDITS index 8207cc62ee9d6..fd934f05ee039 100644 --- a/CREDITS +++ b/CREDITS @@ -534,6 +534,7 @@ N: NeilBrown E: neil@brown.name P: 4096R/566281B9 1BC6 29EB D390 D870 7B5F 497A 39EC 9EDD 5662 81B9 D: NFSD Maintainer 2000-2007 +D: MD Maintainer 2001-2016 N: Zach Brown E: zab@zabbo.net diff --git a/MAINTAINERS b/MAINTAINERS index 233f83464814f..917f27fccefa0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9951,7 +9951,6 @@ S: Supported F: drivers/media/pci/solo6x10/ SOFTWARE RAID (Multiple Disks) SUPPORT -M: Neil Brown L: linux-raid@vger.kernel.org S: Supported F: drivers/md/ -- GitLab From 1501efadc524a0c99494b576923091589a52d2a4 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 13 Jan 2016 16:00:07 -0800 Subject: [PATCH 2687/2855] md/raid: only permit hot-add of compatible integrity profiles It is not safe for an integrity profile to be changed while i/o is in-flight in the queue. Prevent adding new disks or otherwise online spares to an array if the device has an incompatible integrity profile. The original change to the blk_integrity_unregister implementation in md, commmit c7bfced9a671 "md: suspend i/o during runtime blk_integrity_unregister" introduced an immediate hang regression. This policy of disallowing changes the integrity profile once one has been established is shared with DM. Here is an abbreviated log from a test run that: 1/ Creates a degraded raid1 with an integrity-enabled device (pmem0s) [ 59.076127] 2/ Tries to add an integrity-disabled device (pmem1m) [ 90.489209] 3/ Retries with an integrity-enabled device (pmem1s) [ 205.671277] [ 59.076127] md/raid1:md0: active with 1 out of 2 mirrors [ 59.078302] md: data integrity enabled on md0 [..] [ 90.489209] md0: incompatible integrity profile for pmem1m [..] [ 205.671277] md: super_written gets error=-5 [ 205.677386] md/raid1:md0: Disk failure on pmem1m, disabling device. [ 205.677386] md/raid1:md0: Operation continuing on 1 devices. [ 205.683037] RAID1 conf printout: [ 205.684699] --- wd:1 rd:2 [ 205.685972] disk 0, wo:0, o:1, dev:pmem0s [ 205.687562] disk 1, wo:1, o:1, dev:pmem1s [ 205.691717] md: recovery of RAID array md0 Fixes: c7bfced9a671 ("md: suspend i/o during runtime blk_integrity_unregister") Cc: Cc: Mike Snitzer Reported-by: NeilBrown Signed-off-by: Dan Williams Signed-off-by: NeilBrown --- drivers/md/md.c | 28 ++++++++++++++++------------ drivers/md/md.h | 2 +- drivers/md/multipath.c | 6 +++--- drivers/md/raid1.c | 6 +++--- drivers/md/raid10.c | 6 +++--- 5 files changed, 26 insertions(+), 22 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 8753dee3983be..2cf0e1c00b9a9 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2010,28 +2010,32 @@ int md_integrity_register(struct mddev *mddev) } EXPORT_SYMBOL(md_integrity_register); -/* Disable data integrity if non-capable/non-matching disk is being added */ -void md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev) +/* + * Attempt to add an rdev, but only if it is consistent with the current + * integrity profile + */ +int md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev) { struct blk_integrity *bi_rdev; struct blk_integrity *bi_mddev; + char name[BDEVNAME_SIZE]; if (!mddev->gendisk) - return; + return 0; bi_rdev = bdev_get_integrity(rdev->bdev); bi_mddev = blk_get_integrity(mddev->gendisk); if (!bi_mddev) /* nothing to do */ - return; - if (rdev->raid_disk < 0) /* skip spares */ - return; - if (bi_rdev && blk_integrity_compare(mddev->gendisk, - rdev->bdev->bd_disk) >= 0) - return; - WARN_ON_ONCE(!mddev->suspended); - printk(KERN_NOTICE "disabling data integrity on %s\n", mdname(mddev)); - blk_integrity_unregister(mddev->gendisk); + return 0; + + if (blk_integrity_compare(mddev->gendisk, rdev->bdev->bd_disk) != 0) { + printk(KERN_NOTICE "%s: incompatible integrity profile for %s\n", + mdname(mddev), bdevname(rdev->bdev, name)); + return -ENXIO; + } + + return 0; } EXPORT_SYMBOL(md_integrity_add_rdev); diff --git a/drivers/md/md.h b/drivers/md/md.h index fc6f7bbc95444..a491e220e7380 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -660,7 +660,7 @@ extern void md_wait_for_blocked_rdev(struct md_rdev *rdev, struct mddev *mddev); extern void md_set_array_sectors(struct mddev *mddev, sector_t array_sectors); extern int md_check_no_bitmap(struct mddev *mddev); extern int md_integrity_register(struct mddev *mddev); -extern void md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev); +extern int md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev); extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale); extern void mddev_init(struct mddev *mddev); diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 7331a80d89f19..0a72ab6e6c204 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -257,6 +257,9 @@ static int multipath_add_disk(struct mddev *mddev, struct md_rdev *rdev) disk_stack_limits(mddev->gendisk, rdev->bdev, rdev->data_offset << 9); + err = md_integrity_add_rdev(rdev, mddev); + if (err) + break; spin_lock_irq(&conf->device_lock); mddev->degraded--; rdev->raid_disk = path; @@ -264,9 +267,6 @@ static int multipath_add_disk(struct mddev *mddev, struct md_rdev *rdev) spin_unlock_irq(&conf->device_lock); rcu_assign_pointer(p->rdev, rdev); err = 0; - mddev_suspend(mddev); - md_integrity_add_rdev(rdev, mddev); - mddev_resume(mddev); break; } diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index e2169ff6e0f00..c4b9134092260 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1589,6 +1589,9 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev) if (mddev->recovery_disabled == conf->recovery_disabled) return -EBUSY; + if (md_integrity_add_rdev(rdev, mddev)) + return -ENXIO; + if (rdev->raid_disk >= 0) first = last = rdev->raid_disk; @@ -1632,9 +1635,6 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev) break; } } - mddev_suspend(mddev); - md_integrity_add_rdev(rdev, mddev); - mddev_resume(mddev); if (mddev->queue && blk_queue_discard(bdev_get_queue(rdev->bdev))) queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); print_conf(conf); diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 84e597e1c4890..ce959b4ae4dfd 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1698,6 +1698,9 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev) if (rdev->saved_raid_disk < 0 && !_enough(conf, 1, -1)) return -EINVAL; + if (md_integrity_add_rdev(rdev, mddev)) + return -ENXIO; + if (rdev->raid_disk >= 0) first = last = rdev->raid_disk; @@ -1739,9 +1742,6 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev) rcu_assign_pointer(p->rdev, rdev); break; } - mddev_suspend(mddev); - md_integrity_add_rdev(rdev, mddev); - mddev_resume(mddev); if (mddev->queue && blk_queue_discard(bdev_get_queue(rdev->bdev))) queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); -- GitLab From bf3de47f1af3dab8fb8c3a3bd21ada7de614b7de Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 22 Dec 2015 15:48:13 +0100 Subject: [PATCH 2688/2855] mfd: tps65010: Be sure to clamp return value As we want gpio_chip .get() calls to be able to return negative error codes and propagate to drivers, we need to go over all drivers and make sure their return values are clamped to [0,1]. We do this by using the ret = !!(val) design pattern. This also start to propagate the negative error code from the smbus call if there is one, as the last commit of this series will make the gpiolib core deal with that properly. Signed-off-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/tps65010.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c index 448f0a182dc45..677a127619d44 100644 --- a/drivers/mfd/tps65010.c +++ b/drivers/mfd/tps65010.c @@ -499,11 +499,11 @@ static int tps65010_gpio_get(struct gpio_chip *chip, unsigned offset) if (offset < 4) { value = i2c_smbus_read_byte_data(tps->client, TPS_DEFGPIO); if (value < 0) - return 0; + return value; if (value & (1 << (offset + 4))) /* output */ return !(value & (1 << offset)); else /* input */ - return (value & (1 << offset)); + return !!(value & (1 << offset)); } /* REVISIT we *could* report LED1/nPG and LED2 state ... */ -- GitLab From 2d5f72b85a8876088be77cee3a7bdee4c0259085 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 22 Dec 2015 15:47:55 +0100 Subject: [PATCH 2689/2855] mfd: tc6393xb: Be sure to clamp return value As we want gpio_chip .get() calls to be able to return negative error codes and propagate to drivers, we need to go over all drivers and make sure their return values are clamped to [0,1]. We do this by using the ret = !!(val) design pattern. Cc: Dmitry Baryshkov Signed-off-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/tc6393xb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 8c84a513016b6..1ecbfa40d1b32 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c @@ -437,8 +437,8 @@ static int tc6393xb_gpio_get(struct gpio_chip *chip, struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); /* XXX: does dsr also represent inputs? */ - return tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)) - & TC_GPIO_BIT(offset); + return !!(tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)) + & TC_GPIO_BIT(offset)); } static void __tc6393xb_gpio_set(struct gpio_chip *chip, -- GitLab From f7d623669648d2a8d7e81671294c26e480ddcc79 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 22 Dec 2015 15:47:39 +0100 Subject: [PATCH 2690/2855] mfd: htc-egpio: Be sure to clamp return value As we want gpio_chip .get() calls to be able to return negative error codes and propagate to drivers, we need to go over all drivers and make sure their return values are clamped to [0,1]. We do this by using the ret = !!(val) design pattern. Cc: Philipp Zabel Signed-off-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/htc-egpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c index 6ccaf90d98fd6..e4f4a31b76d96 100644 --- a/drivers/mfd/htc-egpio.c +++ b/drivers/mfd/htc-egpio.c @@ -163,7 +163,7 @@ static int egpio_get(struct gpio_chip *chip, unsigned offset) value = egpio_readw(ei, reg); pr_debug("readw(%p + %x) = %x\n", ei->base_addr, reg << ei->bus_shift, value); - return value & bit; + return !!(value & bit); } static int egpio_direction_input(struct gpio_chip *chip, unsigned offset) -- GitLab From fe0b486729e1ae837cf0afd1005d3c10a78f9807 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 22 Dec 2015 15:47:31 +0100 Subject: [PATCH 2691/2855] mfd: dm355evm_mps: Be sure to clamp return value As we want gpio_chip .get() calls to be able to return negative error codes and propagate to drivers, we need to go over all drivers and make sure their return values are clamped to [0,1]. We do this by using the ret = !!(val) design pattern. Signed-off-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/dm355evm_msp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/dm355evm_msp.c b/drivers/mfd/dm355evm_msp.c index 4c826f78acd02..bf3e0b21b247b 100644 --- a/drivers/mfd/dm355evm_msp.c +++ b/drivers/mfd/dm355evm_msp.c @@ -147,7 +147,7 @@ static int msp_gpio_get(struct gpio_chip *chip, unsigned offset) return status; if (reg == DM355EVM_MSP_LED) msp_led_cache = status; - return status & MSP_GPIO_MASK(offset); + return !!(status & MSP_GPIO_MASK(offset)); } static int msp_gpio_out(struct gpio_chip *chip, unsigned offset, int value) -- GitLab From f8e3a514bf98a94255bd1534a21aebaf795b7a13 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 22 Dec 2015 15:47:05 +0100 Subject: [PATCH 2692/2855] mfd: asic3: Be sure to clamp return value As we want gpio_chip .get() calls to be able to return negative error codes and propagate to drivers, we need to go over all drivers and make sure their return values are clamped to [0,1]. We do this by using the ret = !!(val) design pattern. Cc: Paul Parsons Signed-off-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/asic3.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index a726f01e3b026..73812eedeefbc 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -502,7 +502,8 @@ static int asic3_gpio_get(struct gpio_chip *chip, return -EINVAL; } - return asic3_read_register(asic, gpio_base + ASIC3_GPIO_STATUS) & mask; + return !!(asic3_read_register(asic, + gpio_base + ASIC3_GPIO_STATUS) & mask); } static void asic3_gpio_set(struct gpio_chip *chip, -- GitLab From a13c7c51fd91deb7a8a8535ff14fed283f1a2187 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 4 Dec 2015 10:10:03 +0900 Subject: [PATCH 2693/2855] dt-bindings: regulator/clock/mfd: Reorganize S2MPS-family bindings Bindings for Samsung S2M and S5M family PMICs are in mess. They are spread over different files and subdirectories in a non-consistent way. The devices and respective drivers for them share a lot in common so everything could be organized in a more readable way. Reorganize the S2MPS11/13/14/15 Device Tree bindings to match the drivers for this family of devices: - move mfd/s2mps11.txt to mfd/samsung,sec-core.txt for the main MFD driver (common for entire family), - split clock block to clock/samsung,s2mps11.txt, - split regulator block to regulator/samsung,s2mps11.txt. Signed-off-by: Krzysztof Kozlowski Acked-by: Michael Turquette Acked-by: Rob Herring Acked-by: Mark Brown Signed-off-by: Lee Jones --- .../bindings/clock/samsung,s2mps11.txt | 49 ++++++ .../devicetree/bindings/mfd/s2mps11.txt | 153 ------------------ .../bindings/mfd/samsung,sec-core.txt | 84 ++++++++++ .../bindings/regulator/samsung,s2mps11.txt | 102 ++++++++++++ MAINTAINERS | 4 +- 5 files changed, 238 insertions(+), 154 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/samsung,s2mps11.txt delete mode 100644 Documentation/devicetree/bindings/mfd/s2mps11.txt create mode 100644 Documentation/devicetree/bindings/mfd/samsung,sec-core.txt create mode 100644 Documentation/devicetree/bindings/regulator/samsung,s2mps11.txt diff --git a/Documentation/devicetree/bindings/clock/samsung,s2mps11.txt b/Documentation/devicetree/bindings/clock/samsung,s2mps11.txt new file mode 100644 index 0000000000000..2726c1d58a79d --- /dev/null +++ b/Documentation/devicetree/bindings/clock/samsung,s2mps11.txt @@ -0,0 +1,49 @@ +Binding for Samsung S2M and S5M family clock generator block +============================================================ + +This is a part of device tree bindings for S2M and S5M family multi-function +devices. +More information can be found in bindings/mfd/sec-core.txt file. + +The S2MPS11/13/15 and S5M8767 provide three(AP/CP/BT) buffered 32.768 kHz +outputs. The S2MPS14 provides two (AP/BT) buffered 32.768 KHz outputs. + +To register these as clocks with common clock framework instantiate under +main device node a sub-node named "clocks". + +It uses the common clock binding documented in: + - Documentation/devicetree/bindings/clock/clock-bindings.txt + + +Required properties of the "clocks" sub-node: + - #clock-cells: should be 1. + - compatible: Should be one of: "samsung,s2mps11-clk", "samsung,s2mps13-clk", + "samsung,s2mps14-clk", "samsung,s5m8767-clk" + The S2MPS15 uses the same compatible as S2MPS13, as both provides similar + clocks. + + +Each clock is assigned an identifier and client nodes use this identifier +to specify the clock which they consume. + Clock ID Devices + ---------------------------------------------------------- + 32KhzAP 0 S2MPS11/13/14/15, S5M8767 + 32KhzCP 1 S2MPS11/13/15, S5M8767 + 32KhzBT 2 S2MPS11/13/14/15, S5M8767 + +Include dt-bindings/clock/samsung,s2mps11.h file to use preprocessor defines +in device tree sources. + + +Example: + + s2mps11_pmic@66 { + compatible = "samsung,s2mps11-pmic"; + reg = <0x66>; + + s2m_osc: clocks { + compatible = "samsung,s2mps11-clk"; + #clock-cells = <1>; + clock-output-names = "xx", "yy", "zz"; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/s2mps11.txt b/Documentation/devicetree/bindings/mfd/s2mps11.txt deleted file mode 100644 index 09b94c97faacc..0000000000000 --- a/Documentation/devicetree/bindings/mfd/s2mps11.txt +++ /dev/null @@ -1,153 +0,0 @@ - -* Samsung S2MPS11/13/14/15 and S2MPU02 Voltage and Current Regulator - -The Samsung S2MPS11 is a multi-function device which includes voltage and -current regulators, RTC, charger controller and other sub-blocks. It is -interfaced to the host controller using an I2C interface. Each sub-block is -addressed by the host system using different I2C slave addresses. - -Required properties: -- compatible: Should be one of the following - - "samsung,s2mps11-pmic" - - "samsung,s2mps13-pmic" - - "samsung,s2mps14-pmic" - - "samsung,s2mps15-pmic" - - "samsung,s2mpu02-pmic". -- reg: Specifies the I2C slave address of the pmic block. It should be 0x66. - -Optional properties: -- interrupt-parent: Specifies the phandle of the interrupt controller to which - the interrupts from s2mps11 are delivered to. -- interrupts: Interrupt specifiers for interrupt sources. -- samsung,s2mps11-wrstbi-ground: Indicates that WRSTBI pin of PMIC is pulled - down. When the system is suspended it will always go down thus triggerring - unwanted buck warm reset (setting buck voltages to default values). -- samsung,s2mps11-acokb-ground: Indicates that ACOKB pin of S2MPS11 PMIC is - connected to the ground so the PMIC must manually set PWRHOLD bit in CTRL1 - register to turn off the power. Usually the ACOKB is pulled up to VBATT so - when PWRHOLD pin goes low, the rising ACOKB will trigger power off. - -Optional nodes: -- clocks: s2mps11, s2mps13, s2mps15 and s5m8767 provide three(AP/CP/BT) buffered 32.768 - KHz outputs, so to register these as clocks with common clock framework - instantiate a sub-node named "clocks". It uses the common clock binding - documented in : - [Documentation/devicetree/bindings/clock/clock-bindings.txt] - The s2mps14 provides two (AP/BT) buffered 32.768 KHz outputs. - - #clock-cells: should be 1. - - - The following is the list of clocks generated by the controller. Each clock - is assigned an identifier and client nodes use this identifier to specify - the clock which they consume. - Clock ID Devices - ---------------------------------------------------------- - 32KhzAP 0 S2MPS11, S2MPS13, S2MPS14, S2MPS15, S5M8767 - 32KhzCP 1 S2MPS11, S2MPS13, S2MPS15, S5M8767 - 32KhzBT 2 S2MPS11, S2MPS13, S2MPS14, S2MPS15, S5M8767 - - - compatible: Should be one of: "samsung,s2mps11-clk", "samsung,s2mps13-clk", - "samsung,s2mps14-clk", "samsung,s5m8767-clk" - The s2msp15 uses the same compatible as s2mps13, as both provides similar clocks. - -- regulators: The regulators of s2mps11 that have to be instantiated should be -included in a sub-node named 'regulators'. Regulator nodes included in this -sub-node should be of the format as listed below. - - regulator_name { - [standard regulator constraints....]; - }; - - regulator-ramp-delay for BUCKs = [6250/12500/25000(default)/50000] uV/us - - BUCK[2/3/4/6] supports disabling ramp delay on hardware, so explicitly - regulator-ramp-delay = <0> can be used for them to disable ramp delay. - In the absence of the regulator-ramp-delay property, the default ramp - delay will be used. - -NOTE: Some BUCKs share the ramp rate setting i.e. same ramp value will be set -for a particular group of BUCKs. So provide same regulator-ramp-delay. -Grouping of BUCKs sharing ramp rate setting is as follow : BUCK[1, 6], -BUCK[3, 4], and BUCK[7, 8, 10] - -On S2MPS14 the LDO10, LDO11 and LDO12 can be configured to external control -over GPIO. To turn this feature on this property must be added to the regulator -sub-node: - - samsung,ext-control-gpios: GPIO specifier for one GPIO - controlling this regulator (enable/disable); -Example: - LDO12 { - regulator-name = "V_EMMC_2.8V"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - samsung,ext-control-gpios = <&gpk0 2 0>; - }; - - -The regulator constraints inside the regulator nodes use the standard regulator -bindings which are documented elsewhere. - -The following are the names of the regulators that the s2mps11 pmic block -supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number -as per the datasheet of s2mps11. - - - LDOn - - valid values for n are: - - S2MPS11: 1 to 38 - - S2MPS13: 1 to 40 - - S2MPS14: 1 to 25 - - S2MPS15: 1 to 27 - - S2MPU02: 1 to 28 - - Example: LDO1, LDO2, LDO28 - - BUCKn - - valid values for n are: - - S2MPS11: 1 to 10 - - S2MPS13: 1 to 10 - - S2MPS14: 1 to 5 - - S2MPS15: 1 to 10 - - S2MPU02: 1 to 7 - - Example: BUCK1, BUCK2, BUCK9 - -Example: - - s2mps11_pmic@66 { - compatible = "samsung,s2mps11-pmic"; - reg = <0x66>; - - s2m_osc: clocks { - compatible = "samsung,s2mps11-clk"; - #clock-cells = <1>; - clock-output-names = "xx", "yy", "zz"; - }; - - regulators { - ldo1_reg: LDO1 { - regulator-name = "VDD_ABB_3.3V"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; - - ldo2_reg: LDO2 { - regulator-name = "VDD_ALIVE_1.1V"; - regulator-min-microvolt = <1100000>; - regulator-max-microvolt = <1100000>; - regulator-always-on; - }; - - buck1_reg: BUCK1 { - regulator-name = "vdd_mif"; - regulator-min-microvolt = <950000>; - regulator-max-microvolt = <1350000>; - regulator-always-on; - regulator-boot-on; - }; - - buck2_reg: BUCK2 { - regulator-name = "vdd_arm"; - regulator-min-microvolt = <950000>; - regulator-max-microvolt = <1350000>; - regulator-always-on; - regulator-boot-on; - regulator-ramp-delay = <50000>; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/mfd/samsung,sec-core.txt b/Documentation/devicetree/bindings/mfd/samsung,sec-core.txt new file mode 100644 index 0000000000000..ef0166d0f643f --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/samsung,sec-core.txt @@ -0,0 +1,84 @@ +Binding for Samsung S2M and S5M family multi-function device +============================================================ + +This is a part of device tree bindings for S2M and S5M family multi-function +devices. + +The Samsung S2MPS11/13/14/15, S2MPU02 and S5M8767 is a family +of multi-function devices which include voltage and current regulators, RTC, +charger controller, clock outputs and other sub-blocks. It is interfaced +to the host controller using an I2C interface. Each sub-block is usually +addressed by the host system using different I2C slave addresses. + + +This document describes bindings for main device node. Optional sub-blocks +must be a sub-nodes to it. Bindings for them can be found in: + - bindings/regulator/samsung,s2mps11.txt + - bindings/clock/samsung,s2mps11.txt + + +Required properties: + - compatible: Should be one of the following + - "samsung,s2mps11-pmic", + - "samsung,s2mps13-pmic", + - "samsung,s2mps14-pmic", + - "samsung,s2mps15-pmic", + - "samsung,s2mpu02-pmic". + - reg: Specifies the I2C slave address of the pmic block. It should be 0x66. + +Optional properties: + - interrupt-parent: Specifies the phandle of the interrupt controller to which + the interrupts from s2mps11 are delivered to. + - interrupts: Interrupt specifiers for interrupt sources. + - samsung,s2mps11-wrstbi-ground: Indicates that WRSTBI pin of PMIC is pulled + down. When the system is suspended it will always go down thus triggerring + unwanted buck warm reset (setting buck voltages to default values). + - samsung,s2mps11-acokb-ground: Indicates that ACOKB pin of S2MPS11 PMIC is + connected to the ground so the PMIC must manually set PWRHOLD bit in CTRL1 + register to turn off the power. Usually the ACOKB is pulled up to VBATT so + when PWRHOLD pin goes low, the rising ACOKB will trigger power off. + +Example: + + s2mps11_pmic@66 { + compatible = "samsung,s2mps11-pmic"; + reg = <0x66>; + + s2m_osc: clocks { + compatible = "samsung,s2mps11-clk"; + #clock-cells = <1>; + clock-output-names = "xx", "yy", "zz"; + }; + + regulators { + ldo1_reg: LDO1 { + regulator-name = "VDD_ABB_3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + ldo2_reg: LDO2 { + regulator-name = "VDD_ALIVE_1.1V"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + }; + + buck1_reg: BUCK1 { + regulator-name = "vdd_mif"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-boot-on; + }; + + buck2_reg: BUCK2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-boot-on; + regulator-ramp-delay = <50000>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/regulator/samsung,s2mps11.txt b/Documentation/devicetree/bindings/regulator/samsung,s2mps11.txt new file mode 100644 index 0000000000000..27a48bf1b185b --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/samsung,s2mps11.txt @@ -0,0 +1,102 @@ +Binding for Samsung S2M family regulator block +============================================== + +This is a part of device tree bindings for S2M family multi-function devices. +More information can be found in bindings/mfd/sec-core.txt file. + +The S2MPS11/13/14/15 and S2MPU02 devices provide buck and LDO regulators. + +To register these with regulator framework instantiate under main device node +a sub-node named "regulators" with more sub-nodes for each regulator using the +common regulator binding documented in: + - Documentation/devicetree/bindings/regulator/regulator.txt + + +Names of regulators supported by different devices: + - LDOn + - valid values for n are: + - S2MPS11: 1 to 38 + - S2MPS13: 1 to 40 + - S2MPS14: 1 to 25 + - S2MPS15: 1 to 27 + - S2MPU02: 1 to 28 + - Example: LDO1, LDO2, LDO28 + - BUCKn + - valid values for n are: + - S2MPS11: 1 to 10 + - S2MPS13: 1 to 10 + - S2MPS14: 1 to 5 + - S2MPS15: 1 to 10 + - S2MPU02: 1 to 7 + - Example: BUCK1, BUCK2, BUCK9 +Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number +as per the datasheet of device. + + +Optional properties of the nodes under "regulators" sub-node: + - regulator-ramp-delay: ramp delay in uV/us. May be 6250, 12500, + 25000 (default) or 50000. + + Additionally S2MPS11 supports disabling ramp delay for BUCK{2,3,4,6} + by setting it to <0>. + + Note: On S2MPS11 some bucks share the ramp rate setting i.e. same ramp value + will be set for a particular group of bucks so provide the same + regulator-ramp-delay value for them. + Groups sharing ramp rate: + - buck{1,6}, + - buck{3,4}, + - buck{7,8,10}. + + - samsung,ext-control-gpios: On S2MPS14 the LDO10, LDO11 and LDO12 can be + configured to external control over GPIO. To turn this feature on this + property must be added to the regulator sub-node: + - samsung,ext-control-gpios: GPIO specifier for one GPIO + controlling this regulator (enable/disable) + Example: + LDO12 { + regulator-name = "V_EMMC_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + samsung,ext-control-gpios = <&gpk0 2 0>; + }; + + +Example: + + s2mps11_pmic@66 { + compatible = "samsung,s2mps11-pmic"; + reg = <0x66>; + + regulators { + ldo1_reg: LDO1 { + regulator-name = "VDD_ABB_3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + ldo2_reg: LDO2 { + regulator-name = "VDD_ALIVE_1.1V"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + }; + + buck1_reg: BUCK1 { + regulator-name = "vdd_mif"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-boot-on; + }; + + buck2_reg: BUCK2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-boot-on; + regulator-ramp-delay = <50000>; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 25b727556dc77..2c0bbced0532d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9224,7 +9224,9 @@ F: drivers/clk/clk-s2mps11.c F: drivers/rtc/rtc-s5m.c F: include/linux/mfd/samsung/ F: Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt -F: Documentation/devicetree/bindings/mfd/s2mp*.txt +F: Documentation/devicetree/bindings/mfd/samsung,sec-core.txt +F: Documentation/devicetree/bindings/regulator/samsung,s2m*.txt +F: Documentation/devicetree/bindings/clock/samsung,s2mps11.txt SAMSUNG S5P/EXYNOS4 SOC SERIES CAMERA SUBSYSTEM DRIVERS M: Kyungmin Park -- GitLab From 27383ca93b58dfb552ff51fc55fe48006d3c7d99 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 4 Dec 2015 10:10:04 +0900 Subject: [PATCH 2694/2855] dt-bindings: regulator/mfd: Reorganize S5M8767 bindings The regulator/s5m8767-regulator.txt duplicates some of the information about bindings with old mfd/s2mps11.txt. Now common part exists entirely in mfd/samsung,sec-core.txt so: - add company prefix to file name (regulator/samsung,s5m8767.txt), - remove duplicated information, - reorganize the contents to match style of regulator/samsung,s2mps11.txt. Signed-off-by: Krzysztof Kozlowski Acked-by: Mark Brown Acked-by: Rob Herring Signed-off-by: Lee Jones --- .../bindings/mfd/samsung,sec-core.txt | 4 +- .../bindings/regulator/s5m8767-regulator.txt | 163 ------------------ .../bindings/regulator/samsung,s5m8767.txt | 145 ++++++++++++++++ MAINTAINERS | 2 +- 4 files changed, 149 insertions(+), 165 deletions(-) delete mode 100644 Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt create mode 100644 Documentation/devicetree/bindings/regulator/samsung,s5m8767.txt diff --git a/Documentation/devicetree/bindings/mfd/samsung,sec-core.txt b/Documentation/devicetree/bindings/mfd/samsung,sec-core.txt index ef0166d0f643f..4aeb95c82304c 100644 --- a/Documentation/devicetree/bindings/mfd/samsung,sec-core.txt +++ b/Documentation/devicetree/bindings/mfd/samsung,sec-core.txt @@ -14,6 +14,7 @@ addressed by the host system using different I2C slave addresses. This document describes bindings for main device node. Optional sub-blocks must be a sub-nodes to it. Bindings for them can be found in: - bindings/regulator/samsung,s2mps11.txt + - bindings/regulator/samsung,s5m8767.txt - bindings/clock/samsung,s2mps11.txt @@ -23,7 +24,8 @@ Required properties: - "samsung,s2mps13-pmic", - "samsung,s2mps14-pmic", - "samsung,s2mps15-pmic", - - "samsung,s2mpu02-pmic". + - "samsung,s2mpu02-pmic", + - "samsung,s5m8767-pmic". - reg: Specifies the I2C slave address of the pmic block. It should be 0x66. Optional properties: diff --git a/Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt b/Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt deleted file mode 100644 index 20191315e444e..0000000000000 --- a/Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt +++ /dev/null @@ -1,163 +0,0 @@ -* Samsung S5M8767 Voltage and Current Regulator - -The Samsung S5M8767 is a multi-function device which includes voltage and -current regulators, rtc, charger controller and other sub-blocks. It is -interfaced to the host controller using a i2c interface. Each sub-block is -addressed by the host system using different i2c slave address. This document -describes the bindings for 'pmic' sub-block of s5m8767. - -Required properties: -- compatible: Should be "samsung,s5m8767-pmic". -- reg: Specifies the i2c slave address of the pmic block. It should be 0x66. - -- s5m8767,pmic-buck2-dvs-voltage: A set of 8 voltage values in micro-volt (uV) - units for buck2 when changing voltage using gpio dvs. Refer to [1] below - for additional information. - -- s5m8767,pmic-buck3-dvs-voltage: A set of 8 voltage values in micro-volt (uV) - units for buck3 when changing voltage using gpio dvs. Refer to [1] below - for additional information. - -- s5m8767,pmic-buck4-dvs-voltage: A set of 8 voltage values in micro-volt (uV) - units for buck4 when changing voltage using gpio dvs. Refer to [1] below - for additional information. - -- s5m8767,pmic-buck-ds-gpios: GPIO specifiers for three host gpio's used - for selecting GPIO DVS lines. It is one-to-one mapped to dvs gpio lines. - -[1] If none of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional - property is specified, the 's5m8767,pmic-buck[2/3/4]-dvs-voltage' - property should specify atleast one voltage level (which would be a - safe operating voltage). - - If either of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional - property is specified, then all the eight voltage values for the - 's5m8767,pmic-buck[2/3/4]-dvs-voltage' should be specified. - -Optional properties: -- interrupt-parent: Specifies the phandle of the interrupt controller to which - the interrupts from s5m8767 are delivered to. -- interrupts: Interrupt specifiers for two interrupt sources. - - First interrupt specifier is for 'irq1' interrupt. - - Second interrupt specifier is for 'alert' interrupt. -- s5m8767,pmic-buck2-uses-gpio-dvs: 'buck2' can be controlled by gpio dvs. -- s5m8767,pmic-buck3-uses-gpio-dvs: 'buck3' can be controlled by gpio dvs. -- s5m8767,pmic-buck4-uses-gpio-dvs: 'buck4' can be controlled by gpio dvs. - -Additional properties required if either of the optional properties are used: - -- s5m8767,pmic-buck234-default-dvs-idx: Default voltage setting selected from - the possible 8 options selectable by the dvs gpios. The value of this - property should be between 0 and 7. If not specified or if out of range, the - default value of this property is set to 0. - -- s5m8767,pmic-buck-dvs-gpios: GPIO specifiers for three host gpio's used - for dvs. The format of the gpio specifier depends in the gpio controller. - -Regulators: The regulators of s5m8767 that have to be instantiated should be -included in a sub-node named 'regulators'. Regulator nodes included in this -sub-node should be of the format as listed below. - - regulator_name { - ldo1_reg: LDO1 { - regulator-name = "VDD_ALIVE_1.0V"; - regulator-min-microvolt = <1100000>; - regulator-max-microvolt = <1100000>; - regulator-always-on; - regulator-boot-on; - op_mode = <1>; /* Normal Mode */ - }; - }; -The above regulator entries are defined in regulator bindings documentation -except these properties: - - op_mode: describes the different operating modes of the LDO's with - power mode change in SOC. The different possible values are, - 0 - always off mode - 1 - on in normal mode - 2 - low power mode - 3 - suspend mode - - s5m8767,pmic-ext-control-gpios: (optional) GPIO specifier for one - GPIO controlling this regulator (enable/disable); This is - valid only for buck9. - -The following are the names of the regulators that the s5m8767 pmic block -supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number -as per the datasheet of s5m8767. - - - LDOn - - valid values for n are 1 to 28 - - Example: LDO1, LDO2, LDO28 - - BUCKn - - valid values for n are 1 to 9. - - Example: BUCK1, BUCK2, BUCK9 - -The bindings inside the regulator nodes use the standard regulator bindings -which are documented elsewhere. - -Example: - - s5m8767_pmic@66 { - compatible = "samsung,s5m8767-pmic"; - reg = <0x66>; - - s5m8767,pmic-buck2-uses-gpio-dvs; - s5m8767,pmic-buck3-uses-gpio-dvs; - s5m8767,pmic-buck4-uses-gpio-dvs; - - s5m8767,pmic-buck-default-dvs-idx = <0>; - - s5m8767,pmic-buck-dvs-gpios = <&gpx0 0 0>, /* DVS1 */ - <&gpx0 1 0>, /* DVS2 */ - <&gpx0 2 0>; /* DVS3 */ - - s5m8767,pmic-buck-ds-gpios = <&gpx2 3 0>, /* SET1 */ - <&gpx2 4 0>, /* SET2 */ - <&gpx2 5 0>; /* SET3 */ - - s5m8767,pmic-buck2-dvs-voltage = <1350000>, <1300000>, - <1250000>, <1200000>, - <1150000>, <1100000>, - <1000000>, <950000>; - - s5m8767,pmic-buck3-dvs-voltage = <1100000>, <1100000>, - <1100000>, <1100000>, - <1000000>, <1000000>, - <1000000>, <1000000>; - - s5m8767,pmic-buck4-dvs-voltage = <1200000>, <1200000>, - <1200000>, <1200000>, - <1200000>, <1200000>, - <1200000>, <1200000>; - - regulators { - ldo1_reg: LDO1 { - regulator-name = "VDD_ABB_3.3V"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - op_mode = <1>; /* Normal Mode */ - }; - - ldo2_reg: LDO2 { - regulator-name = "VDD_ALIVE_1.1V"; - regulator-min-microvolt = <1100000>; - regulator-max-microvolt = <1100000>; - regulator-always-on; - }; - - buck1_reg: BUCK1 { - regulator-name = "VDD_MIF_1.2V"; - regulator-min-microvolt = <950000>; - regulator-max-microvolt = <1350000>; - regulator-always-on; - regulator-boot-on; - }; - - vemmc_reg: BUCK9 { - regulator-name = "VMEM_VDD_2.8V"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - op_mode = <3>; /* Standby Mode */ - s5m8767,pmic-ext-control-gpios = <&gpk0 2 0>; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/regulator/samsung,s5m8767.txt b/Documentation/devicetree/bindings/regulator/samsung,s5m8767.txt new file mode 100644 index 0000000000000..093edda0c8dfc --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/samsung,s5m8767.txt @@ -0,0 +1,145 @@ +Binding for Samsung S5M8767 regulator block +=========================================== + +This is a part of device tree bindings for S5M family multi-function devices. +More information can be found in bindings/mfd/sec-core.txt file. + +The S5M8767 device provide buck and LDO regulators. + +To register these with regulator framework instantiate under main device node +a sub-node named "regulators" with more sub-nodes for each regulator using the +common regulator binding documented in: + - Documentation/devicetree/bindings/regulator/regulator.txt + + +Required properties of the main device node (the parent!): + - s5m8767,pmic-buck2-dvs-voltage: A set of 8 voltage values in micro-volt (uV) + units for buck2 when changing voltage using gpio dvs. Refer to [1] below + for additional information. + + - s5m8767,pmic-buck3-dvs-voltage: A set of 8 voltage values in micro-volt (uV) + units for buck3 when changing voltage using gpio dvs. Refer to [1] below + for additional information. + + - s5m8767,pmic-buck4-dvs-voltage: A set of 8 voltage values in micro-volt (uV) + units for buck4 when changing voltage using gpio dvs. Refer to [1] below + for additional information. + + - s5m8767,pmic-buck-ds-gpios: GPIO specifiers for three host gpio's used + for selecting GPIO DVS lines. It is one-to-one mapped to dvs gpio lines. + + [1] If none of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional + property is specified, the 's5m8767,pmic-buck[2/3/4]-dvs-voltage' + property should specify atleast one voltage level (which would be a + safe operating voltage). + + If either of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional + property is specified, then all the eight voltage values for the + 's5m8767,pmic-buck[2/3/4]-dvs-voltage' should be specified. + +Optional properties of the main device node (the parent!): + - s5m8767,pmic-buck2-uses-gpio-dvs: 'buck2' can be controlled by gpio dvs. + - s5m8767,pmic-buck3-uses-gpio-dvs: 'buck3' can be controlled by gpio dvs. + - s5m8767,pmic-buck4-uses-gpio-dvs: 'buck4' can be controlled by gpio dvs. + +Additional properties required if either of the optional properties are used: + + - s5m8767,pmic-buck234-default-dvs-idx: Default voltage setting selected from + the possible 8 options selectable by the dvs gpios. The value of this + property should be between 0 and 7. If not specified or if out of range, the + default value of this property is set to 0. + + - s5m8767,pmic-buck-dvs-gpios: GPIO specifiers for three host gpio's used + for dvs. The format of the gpio specifier depends in the gpio controller. + + +Names of regulators supported by S5M8767 device: + - LDOn + - valid values for n are 1 to 28 + - Example: LDO1, LDO2, LDO28 + - BUCKn + - valid values for n are 1 to 9. + - Example: BUCK1, BUCK2, BUCK9 +Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number +as per the datasheet of device. + + +Optional properties of the nodes under "regulators" sub-node: + - op_mode: describes the different operating modes of the LDO's with + power mode change in SOC. The different possible values are, + 0 - always off mode + 1 - on in normal mode + 2 - low power mode + 3 - suspend mode + - s5m8767,pmic-ext-control-gpios: (optional) GPIO specifier for one + GPIO controlling this regulator + (enable/disable); This is valid only + for buck9. + +Example: + + s5m8767_pmic@66 { + compatible = "samsung,s5m8767-pmic"; + reg = <0x66>; + + s5m8767,pmic-buck2-uses-gpio-dvs; + s5m8767,pmic-buck3-uses-gpio-dvs; + s5m8767,pmic-buck4-uses-gpio-dvs; + + s5m8767,pmic-buck-default-dvs-idx = <0>; + + s5m8767,pmic-buck-dvs-gpios = <&gpx0 0 0>, /* DVS1 */ + <&gpx0 1 0>, /* DVS2 */ + <&gpx0 2 0>; /* DVS3 */ + + s5m8767,pmic-buck-ds-gpios = <&gpx2 3 0>, /* SET1 */ + <&gpx2 4 0>, /* SET2 */ + <&gpx2 5 0>; /* SET3 */ + + s5m8767,pmic-buck2-dvs-voltage = <1350000>, <1300000>, + <1250000>, <1200000>, + <1150000>, <1100000>, + <1000000>, <950000>; + + s5m8767,pmic-buck3-dvs-voltage = <1100000>, <1100000>, + <1100000>, <1100000>, + <1000000>, <1000000>, + <1000000>, <1000000>; + + s5m8767,pmic-buck4-dvs-voltage = <1200000>, <1200000>, + <1200000>, <1200000>, + <1200000>, <1200000>, + <1200000>, <1200000>; + + regulators { + ldo1_reg: LDO1 { + regulator-name = "VDD_ABB_3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + op_mode = <1>; /* Normal Mode */ + }; + + ldo2_reg: LDO2 { + regulator-name = "VDD_ALIVE_1.1V"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + }; + + buck1_reg: BUCK1 { + regulator-name = "VDD_MIF_1.2V"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-boot-on; + }; + + vemmc_reg: BUCK9 { + regulator-name = "VMEM_VDD_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + op_mode = <3>; /* Standby Mode */ + s5m8767,pmic-ext-control-gpios = <&gpk0 2 0>; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 2c0bbced0532d..5d38715eced59 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9223,9 +9223,9 @@ F: drivers/regulator/s5m*.c F: drivers/clk/clk-s2mps11.c F: drivers/rtc/rtc-s5m.c F: include/linux/mfd/samsung/ -F: Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt F: Documentation/devicetree/bindings/mfd/samsung,sec-core.txt F: Documentation/devicetree/bindings/regulator/samsung,s2m*.txt +F: Documentation/devicetree/bindings/regulator/samsung,s5m*.txt F: Documentation/devicetree/bindings/clock/samsung,s2mps11.txt SAMSUNG S5P/EXYNOS4 SOC SERIES CAMERA SUBSYSTEM DRIVERS -- GitLab From 5d1d147f040253cbdccc6dbdd14a002403cf8490 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 4 Dec 2015 10:10:05 +0900 Subject: [PATCH 2695/2855] dt-bindings: regulator/mfd: Reorganize S2MPA01 bindings The mfd/s2mpa01.txt duplicates some of the information about bindings with old mfd/s2mps11.txt. Now common part exists entirely in mfd/samsung,sec-core.txt so: - add company prefix to file name (regulator/samsung,s2mpa01.txt), - remove duplicated information, - reorganize the contents to match style of regulator/samsung,s2mps11.txt. Signed-off-by: Krzysztof Kozlowski Acked-by: Mark Brown Acked-by: Rob Herring Signed-off-by: Lee Jones --- .../devicetree/bindings/mfd/s2mpa01.txt | 90 ------------------- .../bindings/mfd/samsung,sec-core.txt | 4 +- .../bindings/regulator/samsung,s2mpa01.txt | 79 ++++++++++++++++ 3 files changed, 82 insertions(+), 91 deletions(-) delete mode 100644 Documentation/devicetree/bindings/mfd/s2mpa01.txt create mode 100644 Documentation/devicetree/bindings/regulator/samsung,s2mpa01.txt diff --git a/Documentation/devicetree/bindings/mfd/s2mpa01.txt b/Documentation/devicetree/bindings/mfd/s2mpa01.txt deleted file mode 100644 index c13d3d8c39470..0000000000000 --- a/Documentation/devicetree/bindings/mfd/s2mpa01.txt +++ /dev/null @@ -1,90 +0,0 @@ - -* Samsung S2MPA01 Voltage and Current Regulator - -The Samsung S2MPA01 is a multi-function device which includes high -efficiency buck converters including Dual-Phase buck converter, various LDOs, -and an RTC. It is interfaced to the host controller using an I2C interface. -Each sub-block is addressed by the host system using different I2C slave -addresses. - -Required properties: -- compatible: Should be "samsung,s2mpa01-pmic". -- reg: Specifies the I2C slave address of the PMIC block. It should be 0x66. - -Optional properties: -- interrupt-parent: Specifies the phandle of the interrupt controller to which - the interrupts from s2mpa01 are delivered to. -- interrupts: An interrupt specifier for the sole interrupt generated by the - device. - -Optional nodes: -- regulators: The regulators of s2mpa01 that have to be instantiated should be - included in a sub-node named 'regulators'. Regulator nodes and constraints - included in this sub-node use the standard regulator bindings which are - documented elsewhere. - -Properties for BUCK regulator nodes: -- regulator-ramp-delay: ramp delay in uV/us. May be 6250, 12500 - (default), 25000, or 50000. May be 0 for disabling the ramp delay on - BUCK{1,2,3,4}. - - In the absence of the regulator-ramp-delay property, the default ramp - delay will be used. - - NOTE: Some BUCKs share the ramp rate setting i.e. same ramp value will be set - for a particular group of BUCKs. So provide same regulator-ramp-delay=. - - The following BUCKs share ramp settings: - * 1 and 6 - * 2 and 4 - * 8, 9, and 10 - -The following are the names of the regulators that the s2mpa01 PMIC block -supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number -as per the datasheet of s2mpa01. - - - LDOn - - valid values for n are 1 to 26 - - Example: LDO1, LD02, LDO26 - - BUCKn - - valid values for n are 1 to 10. - - Example: BUCK1, BUCK2, BUCK9 - -Example: - - s2mpa01_pmic@66 { - compatible = "samsung,s2mpa01-pmic"; - reg = <0x66>; - - regulators { - ldo1_reg: LDO1 { - regulator-name = "VDD_ALIVE"; - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <1000000>; - }; - - ldo2_reg: LDO2 { - regulator-name = "VDDQ_MMC2"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - regulator-always-on; - }; - - buck1_reg: BUCK1 { - regulator-name = "vdd_mif"; - regulator-min-microvolt = <950000>; - regulator-max-microvolt = <1350000>; - regulator-always-on; - regulator-boot-on; - }; - - buck2_reg: BUCK2 { - regulator-name = "vdd_arm"; - regulator-min-microvolt = <950000>; - regulator-max-microvolt = <1350000>; - regulator-always-on; - regulator-boot-on; - regulator-ramp-delay = <50000>; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/mfd/samsung,sec-core.txt b/Documentation/devicetree/bindings/mfd/samsung,sec-core.txt index 4aeb95c82304c..cdd079bfc287f 100644 --- a/Documentation/devicetree/bindings/mfd/samsung,sec-core.txt +++ b/Documentation/devicetree/bindings/mfd/samsung,sec-core.txt @@ -4,7 +4,7 @@ Binding for Samsung S2M and S5M family multi-function device This is a part of device tree bindings for S2M and S5M family multi-function devices. -The Samsung S2MPS11/13/14/15, S2MPU02 and S5M8767 is a family +The Samsung S2MPA01, S2MPS11/13/14/15, S2MPU02 and S5M8767 is a family of multi-function devices which include voltage and current regulators, RTC, charger controller, clock outputs and other sub-blocks. It is interfaced to the host controller using an I2C interface. Each sub-block is usually @@ -13,6 +13,7 @@ addressed by the host system using different I2C slave addresses. This document describes bindings for main device node. Optional sub-blocks must be a sub-nodes to it. Bindings for them can be found in: + - bindings/regulator/samsung,s2mpa01.txt - bindings/regulator/samsung,s2mps11.txt - bindings/regulator/samsung,s5m8767.txt - bindings/clock/samsung,s2mps11.txt @@ -20,6 +21,7 @@ must be a sub-nodes to it. Bindings for them can be found in: Required properties: - compatible: Should be one of the following + - "samsung,s2mpa01-pmic", - "samsung,s2mps11-pmic", - "samsung,s2mps13-pmic", - "samsung,s2mps14-pmic", diff --git a/Documentation/devicetree/bindings/regulator/samsung,s2mpa01.txt b/Documentation/devicetree/bindings/regulator/samsung,s2mpa01.txt new file mode 100644 index 0000000000000..bae3c7f838cf7 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/samsung,s2mpa01.txt @@ -0,0 +1,79 @@ +Binding for Samsung S2MPA01 regulator block +=========================================== + +This is a part of device tree bindings for S2M family multi-function devices. +More information can be found in bindings/mfd/sec-core.txt file. + +The S2MPA01 device provide buck and LDO regulators. + +To register these with regulator framework instantiate under main device node +a sub-node named "regulators" with more sub-nodes for each regulator using the +common regulator binding documented in: + - Documentation/devicetree/bindings/regulator/regulator.txt + + +Names of regulators supported by S2MPA01 device: + - LDOn + - valid values for n are 1 to 26 + - Example: LDO1, LD02, LDO26 + - BUCKn + - valid values for n are 1 to 10. + - Example: BUCK1, BUCK2, BUCK9 +Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number +as per the datasheet of device. + + +Optional properties of buck regulator nodes under "regulators" sub-node: + - regulator-ramp-delay: ramp delay in uV/us. May be 6250, 12500 + (default), 25000, or 50000. May be 0 for disabling the ramp delay on + BUCK{1,2,3,4}. + + In the absence of the regulator-ramp-delay property, the default ramp + delay will be used. + + Note: Some bucks share the ramp rate setting i.e. same ramp value + will be set for a particular group of bucks so provide the same + regulator-ramp-delay value for them. + Groups sharing ramp rate: + - buck{1,6}, + - buck{2,4}, + - buck{8,9,10}. + +Example: + + s2mpa01_pmic@66 { + compatible = "samsung,s2mpa01-pmic"; + reg = <0x66>; + + regulators { + ldo1_reg: LDO1 { + regulator-name = "VDD_ALIVE"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + }; + + ldo2_reg: LDO2 { + regulator-name = "VDDQ_MMC2"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + }; + + buck1_reg: BUCK1 { + regulator-name = "vdd_mif"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-boot-on; + }; + + buck2_reg: BUCK2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-boot-on; + regulator-ramp-delay = <50000>; + }; + }; + }; -- GitLab From 1b5420e1f587b05de49b36472fefad5949042d00 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Mon, 28 Dec 2015 23:00:14 +0800 Subject: [PATCH 2696/2855] mfd: Use to_i2c_client() instead of open-coding it Signed-off-by: Geliang Tang Signed-off-by: Lee Jones --- drivers/mfd/88pm80x.c | 4 ++-- drivers/mfd/88pm860x-core.c | 4 ++-- drivers/mfd/max14577.c | 4 ++-- drivers/mfd/max77686.c | 4 ++-- drivers/mfd/max77693.c | 4 ++-- drivers/mfd/max77843.c | 4 ++-- drivers/mfd/max8925-i2c.c | 4 ++-- drivers/mfd/max8997.c | 8 ++++---- drivers/mfd/max8998.c | 8 ++++---- drivers/mfd/sec-core.c | 4 ++-- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/mfd/88pm80x.c b/drivers/mfd/88pm80x.c index 63445ea6b0bfe..3f24ecbe2576d 100644 --- a/drivers/mfd/88pm80x.c +++ b/drivers/mfd/88pm80x.c @@ -135,7 +135,7 @@ EXPORT_SYMBOL_GPL(pm80x_deinit); #ifdef CONFIG_PM_SLEEP static int pm80x_suspend(struct device *dev) { - struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct i2c_client *client = to_i2c_client(dev); struct pm80x_chip *chip = i2c_get_clientdata(client); if (chip && chip->wu_flag) @@ -147,7 +147,7 @@ static int pm80x_suspend(struct device *dev) static int pm80x_resume(struct device *dev) { - struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct i2c_client *client = to_i2c_client(dev); struct pm80x_chip *chip = i2c_get_clientdata(client); if (chip && chip->wu_flag) diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index 3269a9990b242..e497cee36066b 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c @@ -1218,7 +1218,7 @@ static int pm860x_remove(struct i2c_client *client) #ifdef CONFIG_PM_SLEEP static int pm860x_suspend(struct device *dev) { - struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct i2c_client *client = to_i2c_client(dev); struct pm860x_chip *chip = i2c_get_clientdata(client); if (device_may_wakeup(dev) && chip->wakeup_flag) @@ -1228,7 +1228,7 @@ static int pm860x_suspend(struct device *dev) static int pm860x_resume(struct device *dev) { - struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct i2c_client *client = to_i2c_client(dev); struct pm860x_chip *chip = i2c_get_clientdata(client); if (device_may_wakeup(dev) && chip->wakeup_flag) diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c index 56e216dedc916..2280b3fdcf681 100644 --- a/drivers/mfd/max14577.c +++ b/drivers/mfd/max14577.c @@ -495,7 +495,7 @@ MODULE_DEVICE_TABLE(i2c, max14577_i2c_id); #ifdef CONFIG_PM_SLEEP static int max14577_suspend(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); struct max14577 *max14577 = i2c_get_clientdata(i2c); if (device_may_wakeup(dev)) @@ -516,7 +516,7 @@ static int max14577_suspend(struct device *dev) static int max14577_resume(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); struct max14577 *max14577 = i2c_get_clientdata(i2c); if (device_may_wakeup(dev)) diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index d19be64cd32bf..d959ebbb2194a 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c @@ -352,7 +352,7 @@ MODULE_DEVICE_TABLE(i2c, max77686_i2c_id); #ifdef CONFIG_PM_SLEEP static int max77686_suspend(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); struct max77686_dev *max77686 = i2c_get_clientdata(i2c); if (device_may_wakeup(dev)) @@ -374,7 +374,7 @@ static int max77686_suspend(struct device *dev) static int max77686_resume(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); struct max77686_dev *max77686 = i2c_get_clientdata(i2c); if (device_may_wakeup(dev)) diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c index 007f729e150b0..b83b7a7da1ae0 100644 --- a/drivers/mfd/max77693.c +++ b/drivers/mfd/max77693.c @@ -334,7 +334,7 @@ MODULE_DEVICE_TABLE(i2c, max77693_i2c_id); static int max77693_suspend(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); struct max77693_dev *max77693 = i2c_get_clientdata(i2c); if (device_may_wakeup(dev)) { @@ -347,7 +347,7 @@ static int max77693_suspend(struct device *dev) static int max77693_resume(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); struct max77693_dev *max77693 = i2c_get_clientdata(i2c); if (device_may_wakeup(dev)) { diff --git a/drivers/mfd/max77843.c b/drivers/mfd/max77843.c index 586098f1b233a..7cfc95b49c5d5 100644 --- a/drivers/mfd/max77843.c +++ b/drivers/mfd/max77843.c @@ -197,7 +197,7 @@ MODULE_DEVICE_TABLE(i2c, max77843_id); static int __maybe_unused max77843_suspend(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); struct max77693_dev *max77843 = i2c_get_clientdata(i2c); disable_irq(max77843->irq); @@ -209,7 +209,7 @@ static int __maybe_unused max77843_suspend(struct device *dev) static int __maybe_unused max77843_resume(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); struct max77693_dev *max77843 = i2c_get_clientdata(i2c); if (device_may_wakeup(dev)) diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c index b0fe8103e401e..70443b161a5bb 100644 --- a/drivers/mfd/max8925-i2c.c +++ b/drivers/mfd/max8925-i2c.c @@ -215,7 +215,7 @@ static int max8925_remove(struct i2c_client *client) #ifdef CONFIG_PM_SLEEP static int max8925_suspend(struct device *dev) { - struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct i2c_client *client = to_i2c_client(dev); struct max8925_chip *chip = i2c_get_clientdata(client); if (device_may_wakeup(dev) && chip->wakeup_flag) @@ -225,7 +225,7 @@ static int max8925_suspend(struct device *dev) static int max8925_resume(struct device *dev) { - struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct i2c_client *client = to_i2c_client(dev); struct max8925_chip *chip = i2c_get_clientdata(client); if (device_may_wakeup(dev) && chip->wakeup_flag) diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index 156ed6f92aa32..f316348e3d981 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c @@ -437,7 +437,7 @@ static u8 max8997_dumpaddr_haptic[] = { static int max8997_freeze(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); struct max8997_dev *max8997 = i2c_get_clientdata(i2c); int i; @@ -459,7 +459,7 @@ static int max8997_freeze(struct device *dev) static int max8997_restore(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); struct max8997_dev *max8997 = i2c_get_clientdata(i2c); int i; @@ -481,7 +481,7 @@ static int max8997_restore(struct device *dev) static int max8997_suspend(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); struct max8997_dev *max8997 = i2c_get_clientdata(i2c); if (device_may_wakeup(dev)) @@ -491,7 +491,7 @@ static int max8997_suspend(struct device *dev) static int max8997_resume(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); struct max8997_dev *max8997 = i2c_get_clientdata(i2c); if (device_may_wakeup(dev)) diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index a7afe3bf27fc7..ab28b29400f65 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c @@ -274,7 +274,7 @@ MODULE_DEVICE_TABLE(i2c, max8998_i2c_id); static int max8998_suspend(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); struct max8998_dev *max8998 = i2c_get_clientdata(i2c); if (device_may_wakeup(dev)) @@ -284,7 +284,7 @@ static int max8998_suspend(struct device *dev) static int max8998_resume(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); struct max8998_dev *max8998 = i2c_get_clientdata(i2c); if (device_may_wakeup(dev)) @@ -344,7 +344,7 @@ static struct max8998_reg_dump max8998_dump[] = { /* Save registers before hibernation */ static int max8998_freeze(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); int i; for (i = 0; i < ARRAY_SIZE(max8998_dump); i++) @@ -357,7 +357,7 @@ static int max8998_freeze(struct device *dev) /* Restore registers after hibernation */ static int max8998_restore(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); int i; for (i = 0; i < ARRAY_SIZE(max8998_dump); i++) diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index c9802ba9be721..400e1d7d8d08f 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -536,7 +536,7 @@ static void sec_pmic_shutdown(struct i2c_client *i2c) #ifdef CONFIG_PM_SLEEP static int sec_pmic_suspend(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c); if (device_may_wakeup(dev)) @@ -557,7 +557,7 @@ static int sec_pmic_suspend(struct device *dev) static int sec_pmic_resume(struct device *dev) { - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct i2c_client *i2c = to_i2c_client(dev); struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c); if (device_may_wakeup(dev)) -- GitLab From 0b81995148f80f4fa0ce19e66d2e66abe82f456a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Fri, 8 Jan 2016 11:29:42 +0000 Subject: [PATCH 2697/2855] mfd: arizona: Add device tree binding documentation for new clock driver Specify the device tree binding for the input clocks to Arizona devices. Signed-off-by: Charles Keepax Acked-by: Rob Herring Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/arizona.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt b/Documentation/devicetree/bindings/mfd/arizona.txt index 069e31da18f01..9b30011ecabe7 100644 --- a/Documentation/devicetree/bindings/mfd/arizona.txt +++ b/Documentation/devicetree/bindings/mfd/arizona.txt @@ -51,6 +51,13 @@ Optional properties: - wlf,reset : GPIO specifier for the GPIO controlling /RESET + - clocks: Should reference the clocks supplied on MCLK1 and MCLK2 + - clock-names: Should contains two strings: + "mclk1" for the clock supplied on MCLK1, recommended to be a high + quality audio reference clock + "mclk2" for the clock supplied on MCLK2, recommended to be an always on + 32k clock + - wlf,gpio-defaults : A list of GPIO configuration register values. Defines for the appropriate values can found in . If absent, no configuration of these registers is performed. If any entry has -- GitLab From f90dff44641dedea02b1549a9dd5c00bae9230da Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 27 Oct 2015 16:12:21 +0000 Subject: [PATCH 2698/2855] mfd: 88pm860x-core: Fix commenting and declaration spacing Checkpatch output: WARNING: Block comments use a trailing */ on a separate line + * - turn off */ WARNING: Missing a blank line after declarations + int ret; + ret = i2c_add_driver(&pm860x_driver); total: 0 errors, 2 warnings, 1283 lines checked Signed-off-by: Lee Jones --- drivers/mfd/88pm860x-core.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index e497cee36066b..25e1aafae60c2 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c @@ -705,10 +705,12 @@ int pm8606_osc_disable(struct pm860x_chip *chip, unsigned short client) chip->osc_status); mutex_lock(&chip->osc_lock); - /*Update voting status */ + /* Update voting status */ chip->osc_vote &= ~(client); - /* If reference group is off and this is the last client to release - * - turn off */ + /* + * If reference group is off and this is the last client to release + * - turn off + */ if ((chip->osc_status != PM8606_REF_GP_OSC_OFF) && (chip->osc_vote == REF_GP_NO_CLIENTS)) { chip->osc_status = PM8606_REF_GP_OSC_UNKNOWN; @@ -1265,6 +1267,7 @@ static struct i2c_driver pm860x_driver = { static int __init pm860x_i2c_init(void) { int ret; + ret = i2c_add_driver(&pm860x_driver); if (ret != 0) pr_err("Failed to register 88PM860x I2C driver: %d\n", ret); -- GitLab From 4374b20c6c4fa8533e932567be9cd8872286da95 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 27 Oct 2015 16:14:06 +0000 Subject: [PATCH 2699/2855] mfd: aat2870-core: Remove unnecessary 'out of memory' message WARNING: Possible unnecessary 'out of memory' message + if (!aat2870) { + dev_err(&client->dev, total: 0 errors, 1 warnings, 524 lines checked Signed-off-by: Lee Jones --- drivers/mfd/aat2870-core.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c index 29b6a2d4ac724..3ba19a45f199a 100644 --- a/drivers/mfd/aat2870-core.c +++ b/drivers/mfd/aat2870-core.c @@ -373,11 +373,8 @@ static int aat2870_i2c_probe(struct i2c_client *client, aat2870 = devm_kzalloc(&client->dev, sizeof(struct aat2870_data), GFP_KERNEL); - if (!aat2870) { - dev_err(&client->dev, - "Failed to allocate memory for aat2870\n"); + if (!aat2870) return -ENOMEM; - } aat2870->dev = &client->dev; dev_set_drvdata(aat2870->dev, aat2870); -- GitLab From 15544cab2880c6990704ff91c0f11c5ccc3aafad Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 27 Oct 2015 16:19:31 +0000 Subject: [PATCH 2700/2855] mfd: ab3100-core.c: Fix multiple warnings reported by Checkpatch WARNING: Missing a blank line after declarations + struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); + if (!ab3100->startup_events_read) WARNING: Possible unnecessary 'out of memory' message + if (!ab3100) { + dev_err(&client->dev, "could not allocate AB3100 device\n"); WARNING: else is not generally useful after a break or return + break; + } else { total: 0 errors, 3 warnings, 996 lines checked Cc: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/ab3100-core.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index f0afb44271f8b..6a5a98806cb81 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c @@ -381,9 +381,11 @@ static int ab3100_event_registers_startup_state_get(struct device *dev, u8 *event) { struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); + if (!ab3100->startup_events_read) return -EAGAIN; /* Try again later */ memcpy(event, ab3100->startup_events, 3); + return 0; } @@ -858,10 +860,8 @@ static int ab3100_probe(struct i2c_client *client, int i; ab3100 = devm_kzalloc(&client->dev, sizeof(struct ab3100), GFP_KERNEL); - if (!ab3100) { - dev_err(&client->dev, "could not allocate AB3100 device\n"); + if (!ab3100) return -ENOMEM; - } /* Initialize data structure */ mutex_init(&ab3100->access_mutex); @@ -883,20 +883,17 @@ static int ab3100_probe(struct i2c_client *client, for (i = 0; ids[i].id != 0x0; i++) { if (ids[i].id == ab3100->chip_id) { - if (ids[i].name != NULL) { - snprintf(&ab3100->chip_name[0], - sizeof(ab3100->chip_name) - 1, - "AB3100 %s", - ids[i].name); + if (ids[i].name) break; - } else { - dev_err(&client->dev, - "AB3000 is not supported\n"); - goto exit_no_detect; - } + + dev_err(&client->dev, "AB3000 is not supported\n"); + goto exit_no_detect; } } + snprintf(&ab3100->chip_name[0], + sizeof(ab3100->chip_name) - 1, "AB3100 %s", ids[i].name); + if (ids[i].id == 0x0) { dev_err(&client->dev, "unknown analog baseband chip id: 0x%x\n", ab3100->chip_id); -- GitLab From 845b76f891999f98b7acb439768c9d50959d29e1 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 28 Oct 2015 09:08:22 +0000 Subject: [PATCH 2701/2855] mfd: ab2100-otp: Remove pointless 'out of memory' error message WARNING: Possible unnecessary 'out of memory' message + if (!otp) { + dev_err(&pdev->dev, "could not allocate AB3100 OTP device\n"); total: 0 errors, 1 warnings, 250 lines checked Cc: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/ab3100-otp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/ab3100-otp.c b/drivers/mfd/ab3100-otp.c index f391c5fee1b04..55b207a4b336f 100644 --- a/drivers/mfd/ab3100-otp.c +++ b/drivers/mfd/ab3100-otp.c @@ -188,10 +188,9 @@ static int __init ab3100_otp_probe(struct platform_device *pdev) int i; otp = devm_kzalloc(&pdev->dev, sizeof(struct ab3100_otp), GFP_KERNEL); - if (!otp) { - dev_err(&pdev->dev, "could not allocate AB3100 OTP device\n"); + if (!otp) return -ENOMEM; - } + otp->dev = &pdev->dev; /* Replace platform data coming in with a local struct */ -- GitLab From 500e69a1011d66897a08e000d92bcfd39372337e Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 28 Oct 2015 09:15:02 +0000 Subject: [PATCH 2702/2855] mfd: ab8500-core: Fix many warnings reported by Checkpatch WARNING: Block comments use a trailing */ on a separate line + * */ WARNING: Block comments use a trailing */ on a separate line + * bank on higher 8 bits and reg in lower */ WARNING: Block comments use a trailing */ on a separate line + * bank on higher 8 bits and reg in lower */ WARNING: suspect code indent for conditional statements (8, 24) + if (unlikely(*offset == 17)) + *offset = 24; WARNING: suspect code indent for conditional statements (8, 24) + if (unlikely(*offset == 16)) + *offset = 25; WARNING: suspect code indent for conditional statements (8, 24) + if ((i == 3) && (*offset >= 24)) + *offset += 2; WARNING: ENOSYS means 'invalid syscall nr' and nothing else + return -ENOSYS; WARNING: static const char * array should probably be static const char * const + static const char *switch_off_status[] = { WARNING: static const char * array should probably be static const char * const + static const char *turn_on_status[] = { total: 0 errors, 9 warnings, 1867 lines checked Cc: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/ab8500-core.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 582d3587f56aa..f3d689176fc22 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -113,7 +113,7 @@ #define AB8500_SWITCH_OFF_STATUS 0x00 #define AB8500_TURN_ON_STATUS 0x00 -#define AB8505_TURN_ON_STATUS_2 0x04 +#define AB8505_TURN_ON_STATUS_2 0x04 #define AB8500_CH_USBCH_STAT1_REG 0x02 #define VBUS_DET_DBNC100 0x02 @@ -211,7 +211,7 @@ static int set_register_interruptible(struct ab8500 *ab8500, u8 bank, /* * Put the u8 bank and u8 register together into a an u16. * The bank on higher 8 bits and register in lower 8 bits. - * */ + */ u16 addr = ((u16)bank) << 8 | reg; dev_vdbg(ab8500->dev, "wr: addr %#x <= %#x\n", addr, data); @@ -243,8 +243,6 @@ static int get_register_interruptible(struct ab8500 *ab8500, u8 bank, u8 reg, u8 *value) { int ret; - /* put the u8 bank and u8 reg together into a an u16. - * bank on higher 8 bits and reg in lower */ u16 addr = ((u16)bank) << 8 | reg; mutex_lock(&ab8500->lock); @@ -278,8 +276,6 @@ static int mask_and_set_register_interruptible(struct ab8500 *ab8500, u8 bank, u8 reg, u8 bitmask, u8 bitvalues) { int ret; - /* put the u8 bank and u8 reg together into a an u16. - * bank on higher 8 bits and reg in lower */ u16 addr = ((u16)bank) << 8 | reg; mutex_lock(&ab8500->lock); @@ -449,12 +445,12 @@ static void update_latch_offset(u8 *offset, int i) { /* Fix inconsistent ITFromLatch25 bit mapping... */ if (unlikely(*offset == 17)) - *offset = 24; + *offset = 24; /* Fix inconsistent ab8540 bit mapping... */ if (unlikely(*offset == 16)) - *offset = 25; + *offset = 25; if ((i == 3) && (*offset >= 24)) - *offset += 2; + *offset += 2; } static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500, @@ -590,12 +586,12 @@ static int ab8500_irq_init(struct ab8500 *ab8500, struct device_node *np) /* If ->irq_base is zero this will give a linear mapping */ ab8500->domain = irq_domain_add_simple(ab8500->dev->of_node, - num_irqs, 0, - &ab8500_irq_ops, ab8500); + num_irqs, 0, + &ab8500_irq_ops, ab8500); if (!ab8500->domain) { dev_err(ab8500->dev, "Failed to create irqdomain\n"); - return -ENOSYS; + return -ENODEV; } return 0; @@ -1073,7 +1069,7 @@ static struct attribute_group ab9540_attr_group = { static int ab8500_probe(struct platform_device *pdev) { - static const char *switch_off_status[] = { + static const char * const switch_off_status[] = { "Swoff bit programming", "Thermal protection activation", "Vbat lower then BattOk falling threshold", @@ -1082,7 +1078,7 @@ static int ab8500_probe(struct platform_device *pdev) "Battery level lower than power on reset threshold", "Power on key 1 pressed longer than 10 seconds", "DB8500 thermal shutdown"}; - static const char *turn_on_status[] = { + static const char * const turn_on_status[] = { "Battery rising (Vbat)", "Power On Key 1 dbF", "Power On Key 2 dbF", -- GitLab From de6a76933317a4dee9b33e1989623cf31098e2ff Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 28 Oct 2015 09:27:32 +0000 Subject: [PATCH 2703/2855] mfd: ab8500-debugfs: Clean-up non-conforming commenting and print formatting WARNING: Block comments use a trailing */ on a separate line + * not be accessed from here */ WARNING: Block comments use a trailing */ on a separate line + * not be accessed from here */ WARNING: Block comments use a trailing */ on a separate line + * the output is wanted in any case */ WARNING: Consecutive strings are generally better as a single string + " addr=0x%08X, mask=0x%X, shift=%d" "value=0x%X\n", total: 0 errors, 4 warnings, 3331 lines checked Cc: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/ab8500-debugfs.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 0236cd7cdce4f..69d9fffe5b5cd 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -242,8 +242,10 @@ static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = { .first = 0x40, .last = 0x44, }, - /* 0x80-0x8B is SIM registers and should - * not be accessed from here */ + /* + * 0x80-0x8B are SIM registers and should + * not be accessed from here + */ }, }, [AB8500_USB] = { @@ -587,8 +589,10 @@ static struct ab8500_prcmu_ranges ab8505_debug_ranges[AB8500_NUM_BANKS] = { .first = 0x40, .last = 0x48, }, - /* 0x80-0x8B is SIM registers and should - * not be accessed from here */ + /* + * 0x80-0x8B are SIM registers and should + * not be accessed from here + */ }, }, [AB8500_USB] = { @@ -1306,8 +1310,10 @@ static int ab8500_registers_print(struct device *dev, u32 bank, if (s) { seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n", bank, reg, value); - /* Error is not returned here since - * the output is wanted in any case */ + /* + * Error is not returned here since + * the output is wanted in any case + */ if (seq_has_overflowed(s)) return 0; } else { @@ -2740,10 +2746,9 @@ static ssize_t hwreg_common_write(char *b, struct hwreg_cfg *cfg, *cfg = loc; #ifdef ABB_HWREG_DEBUG - pr_warn("HWREG request: %s, %s,\n" - " addr=0x%08X, mask=0x%X, shift=%d" "value=0x%X\n", - (write) ? "write" : "read", - REG_FMT_DEC(cfg) ? "decimal" : "hexa", + pr_warn("HWREG request: %s, %s,\n", (write) ? "write" : "read", + REG_FMT_DEC(cfg) ? "decimal" : "hexa"); + pr_warn(" addr=0x%08X, mask=0x%X, shift=%d" "value=0x%X\n", cfg->addr, cfg->mask, cfg->shift, val); #endif -- GitLab From df36442cfe2689e1b26c9633c17a28a9fe4e91ec Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 28 Oct 2015 10:32:10 +0000 Subject: [PATCH 2704/2855] mfd: ab8500-gpadc: Squash a whole bunch of Checkpatch warnings and one error WARNING: line over 80 characters +#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ib t*/ WARNING: line over 80 characters +#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/ WARNING: suspect code indent for conditional statements (16, 20) + if (!strcmp(name, dev_name(gpadc->dev))) + return gpadc; WARNING: suspect code indent for conditional statements (0, 16) +if (ad_value < 0) { + dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n", WARNING: quoted string split across lines + dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:" + " %d AD: 0x%x\n", channel, ad_value); WARNING: Missing a blank line after declarations + int raw_data; + raw_data = ab8500_gpadc_double_read_raw(gpadc, channel, WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt + msleep(10); ERROR: else should follow close brace '}' + } + else WARNING: line over 80 characters + delay_max = 10000; /* large range to optimise sleep mode */ WARNING: line over 80 characters + gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain; WARNING: line over 80 characters + gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL); WARNING: Possible unnecessary 'out of memory' message + if (!gpadc) { + dev_err(&pdev->dev, "Error: No memory\n"); WARNING: space prohibited before semicolon + return ; WARNING: void function return statements are not generally useful + return ; +} WARNING: quoted string split across lines +MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson," + "M'boumba Cedric Madianga"); total: 1 errors, 14 warnings, 1089 lines checked Cc: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/ab8500-gpadc.c | 145 +++++++++++++++++++------------------ 1 file changed, 73 insertions(+), 72 deletions(-) diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c index c51c1b188d640..97dcadc8fa8bf 100644 --- a/drivers/mfd/ab8500-gpadc.c +++ b/drivers/mfd/ab8500-gpadc.c @@ -49,61 +49,61 @@ * OTP register offsets * Bank : 0x15 */ -#define AB8500_GPADC_CAL_1 0x0F -#define AB8500_GPADC_CAL_2 0x10 -#define AB8500_GPADC_CAL_3 0x11 -#define AB8500_GPADC_CAL_4 0x12 -#define AB8500_GPADC_CAL_5 0x13 -#define AB8500_GPADC_CAL_6 0x14 -#define AB8500_GPADC_CAL_7 0x15 +#define AB8500_GPADC_CAL_1 0x0F +#define AB8500_GPADC_CAL_2 0x10 +#define AB8500_GPADC_CAL_3 0x11 +#define AB8500_GPADC_CAL_4 0x12 +#define AB8500_GPADC_CAL_5 0x13 +#define AB8500_GPADC_CAL_6 0x14 +#define AB8500_GPADC_CAL_7 0x15 /* New calibration for 8540 */ #define AB8540_GPADC_OTP4_REG_7 0x38 #define AB8540_GPADC_OTP4_REG_6 0x39 #define AB8540_GPADC_OTP4_REG_5 0x3A /* gpadc constants */ -#define EN_VINTCORE12 0x04 -#define EN_VTVOUT 0x02 -#define EN_GPADC 0x01 -#define DIS_GPADC 0x00 -#define AVG_1 0x00 -#define AVG_4 0x20 -#define AVG_8 0x40 -#define AVG_16 0x60 -#define ADC_SW_CONV 0x04 -#define EN_ICHAR 0x80 -#define BTEMP_PULL_UP 0x08 -#define EN_BUF 0x40 -#define DIS_ZERO 0x00 -#define GPADC_BUSY 0x01 -#define EN_FALLING 0x10 -#define EN_TRIG_EDGE 0x02 -#define EN_VBIAS_XTAL_TEMP 0x02 +#define EN_VINTCORE12 0x04 +#define EN_VTVOUT 0x02 +#define EN_GPADC 0x01 +#define DIS_GPADC 0x00 +#define AVG_1 0x00 +#define AVG_4 0x20 +#define AVG_8 0x40 +#define AVG_16 0x60 +#define ADC_SW_CONV 0x04 +#define EN_ICHAR 0x80 +#define BTEMP_PULL_UP 0x08 +#define EN_BUF 0x40 +#define DIS_ZERO 0x00 +#define GPADC_BUSY 0x01 +#define EN_FALLING 0x10 +#define EN_TRIG_EDGE 0x02 +#define EN_VBIAS_XTAL_TEMP 0x02 /* GPADC constants from AB8500 spec, UM0836 */ -#define ADC_RESOLUTION 1024 -#define ADC_CH_BTEMP_MIN 0 -#define ADC_CH_BTEMP_MAX 1350 -#define ADC_CH_DIETEMP_MIN 0 -#define ADC_CH_DIETEMP_MAX 1350 -#define ADC_CH_CHG_V_MIN 0 -#define ADC_CH_CHG_V_MAX 20030 -#define ADC_CH_ACCDET2_MIN 0 -#define ADC_CH_ACCDET2_MAX 2500 -#define ADC_CH_VBAT_MIN 2300 -#define ADC_CH_VBAT_MAX 4800 -#define ADC_CH_CHG_I_MIN 0 -#define ADC_CH_CHG_I_MAX 1500 -#define ADC_CH_BKBAT_MIN 0 -#define ADC_CH_BKBAT_MAX 3200 +#define ADC_RESOLUTION 1024 +#define ADC_CH_BTEMP_MIN 0 +#define ADC_CH_BTEMP_MAX 1350 +#define ADC_CH_DIETEMP_MIN 0 +#define ADC_CH_DIETEMP_MAX 1350 +#define ADC_CH_CHG_V_MIN 0 +#define ADC_CH_CHG_V_MAX 20030 +#define ADC_CH_ACCDET2_MIN 0 +#define ADC_CH_ACCDET2_MAX 2500 +#define ADC_CH_VBAT_MIN 2300 +#define ADC_CH_VBAT_MAX 4800 +#define ADC_CH_CHG_I_MIN 0 +#define ADC_CH_CHG_I_MAX 1500 +#define ADC_CH_BKBAT_MIN 0 +#define ADC_CH_BKBAT_MAX 3200 /* GPADC constants from AB8540 spec */ -#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ibat*/ -#define ADC_CH_IBAT_MAX 6000 -#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/ -#define ADC_CH_IBAT_MAX_V 60 -#define IBAT_VDROP_L (-56) /* mV */ -#define IBAT_VDROP_H 56 +#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ibat */ +#define ADC_CH_IBAT_MAX 6000 +#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat */ +#define ADC_CH_IBAT_MAX_V 60 +#define IBAT_VDROP_L (-56) /* mV */ +#define IBAT_VDROP_H 56 /* This is used to not lose precision when dividing to get gain and offset */ #define CALIB_SCALE 1000 @@ -179,7 +179,7 @@ struct ab8500_gpadc *ab8500_gpadc_get(char *name) list_for_each_entry(gpadc, &ab8500_gpadc_list, node) { if (!strcmp(name, dev_name(gpadc->dev))) - return gpadc; + return gpadc; } return ERR_PTR(-ENOENT); @@ -315,11 +315,12 @@ int ab8500_gpadc_sw_hw_convert(struct ab8500_gpadc *gpadc, u8 channel, ad_value = ab8500_gpadc_read_raw(gpadc, channel, avg_sample, trig_edge, trig_timer, conv_type); -/* On failure retry a second time */ + + /* On failure retry a second time */ if (ad_value < 0) ad_value = ab8500_gpadc_read_raw(gpadc, channel, avg_sample, trig_edge, trig_timer, conv_type); -if (ad_value < 0) { + if (ad_value < 0) { dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n", channel); return ad_value; @@ -327,8 +328,9 @@ if (ad_value < 0) { voltage = ab8500_gpadc_ad_to_voltage(gpadc, channel, ad_value); if (voltage < 0) - dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:" - " %d AD: 0x%x\n", channel, ad_value); + dev_err(gpadc->dev, + "GPADC to voltage conversion failed ch: %d AD: 0x%x\n", + channel, ad_value); return voltage; } @@ -348,10 +350,9 @@ EXPORT_SYMBOL(ab8500_gpadc_sw_hw_convert); int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel, u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type) { - int raw_data; - raw_data = ab8500_gpadc_double_read_raw(gpadc, channel, - avg_sample, trig_edge, trig_timer, conv_type, NULL); - return raw_data; + return ab8500_gpadc_double_read_raw(gpadc, channel, avg_sample, + trig_edge, trig_timer, conv_type, + NULL); } int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel, @@ -388,7 +389,7 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel, goto out; if (!(val & GPADC_BUSY)) break; - msleep(10); + msleep(20); } while (++looplimit < 10); if (looplimit >= 10 && (val & GPADC_BUSY)) { dev_err(gpadc->dev, "gpadc_conversion: GPADC busy"); @@ -421,8 +422,7 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel, val_reg1 |= EN_TRIG_EDGE; if (trig_edge) val_reg1 |= EN_FALLING; - } - else + } else ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, AB8500_GPADC_CTRL2_REG, val); if (ret < 0) { @@ -449,7 +449,7 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel, * remove when hardware will be availible */ delay_min = 1000; /* Delay in micro seconds */ - delay_max = 10000; /* large range to optimise sleep mode */ + delay_max = 10000; /* large range optimises sleepmode */ break; } /* Intentional fallthrough */ @@ -785,9 +785,10 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) << CALIB_SHIFT_IBAT) / (ADC_CH_IBAT_MAX_V - ADC_CH_IBAT_MIN_V); - gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain; - gpadc->cal_data[ADC_INPUT_IBAT].offset = V_offset * - V2A_gain + V2A_offset; + gpadc->cal_data[ADC_INPUT_IBAT].gain = + V_gain * V2A_gain; + gpadc->cal_data[ADC_INPUT_IBAT].offset = + V_offset * V2A_gain + V2A_offset; } else { gpadc->cal_data[ADC_INPUT_IBAT].gain = 0; } @@ -923,11 +924,10 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) int ret = 0; struct ab8500_gpadc *gpadc; - gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL); - if (!gpadc) { - dev_err(&pdev->dev, "Error: No memory\n"); + gpadc = devm_kzalloc(&pdev->dev, + sizeof(struct ab8500_gpadc), GFP_KERNEL); + if (!gpadc) return -ENOMEM; - } gpadc->irq_sw = platform_get_irq_byname(pdev, "SW_CONV_END"); if (gpadc->irq_sw < 0) @@ -1072,18 +1072,19 @@ void ab8540_gpadc_get_otp(struct ab8500_gpadc *gpadc, *vmain_h = gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_hi; *btemp_l = gpadc->cal_data[ADC_INPUT_BTEMP].otp_calib_lo; *btemp_h = gpadc->cal_data[ADC_INPUT_BTEMP].otp_calib_hi; - *vbat_l = gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_lo; - *vbat_h = gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_hi; - *ibat_l = gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_lo; - *ibat_h = gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_hi; - return ; + *vbat_l = gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_lo; + *vbat_h = gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_hi; + *ibat_l = gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_lo; + *ibat_h = gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_hi; } subsys_initcall_sync(ab8500_gpadc_init); module_exit(ab8500_gpadc_exit); MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson," - "M'boumba Cedric Madianga"); +MODULE_AUTHOR("Arun R Murthy"); +MODULE_AUTHOR("Daniel Willerud"); +MODULE_AUTHOR("Johan Palsson"); +MODULE_AUTHOR("M'boumba Cedric Madianga"); MODULE_ALIAS("platform:ab8500_gpadc"); MODULE_DESCRIPTION("AB8500 GPADC driver"); -- GitLab From 63b4fd7502790b16257396cc0270fa698bdec2b1 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 28 Oct 2015 11:11:05 +0000 Subject: [PATCH 2705/2855] mfd: ab8500-sysctrl: Fix Constify, printk => pr_info and formatting issues WARNING: char * array declaration might be better as static const + static char *pss[] = {"ab8500_ac", "pm2301", "ab8500_usb"}; WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... + printk(KERN_INFO WARNING: quoted string split across lines + "Charger \"%s\" is connected with known battery." + " Rebooting.\n", WARNING: quoted string split across lines + "unable to set sysClkReq%dRfClkBuf: " + "%d\n", j + 1, ret); total: 0 errors, 4 warnings, 199 lines checked Cc: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/ab8500-sysctrl.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c index 0d18256961531..b9f0010309f95 100644 --- a/drivers/mfd/ab8500-sysctrl.c +++ b/drivers/mfd/ab8500-sysctrl.c @@ -27,7 +27,7 @@ static void ab8500_power_off(void) { sigset_t old; sigset_t all; - static char *pss[] = {"ab8500_ac", "pm2301", "ab8500_usb"}; + static const char * const pss[] = {"ab8500_ac", "pm2301", "ab8500_usb"}; int i; bool charger_present = false; union power_supply_propval val; @@ -68,10 +68,9 @@ static void ab8500_power_off(void) ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TECHNOLOGY, &val); if (!ret && val.intval != POWER_SUPPLY_TECHNOLOGY_UNKNOWN) { - printk(KERN_INFO - "Charger \"%s\" is connected with known battery." - " Rebooting.\n", - pss[i]); + pr_info("Charger '%s' is connected with known battery", + pss[i]); + pr_info(" - Rebooting.\n"); machine_restart("charging"); } power_supply_put(psy); @@ -161,8 +160,8 @@ static int ab8500_sysctrl_probe(struct platform_device *pdev) pdata->initial_req_buf_config[j]); if (ret < 0) { dev_err(&pdev->dev, - "unable to set sysClkReq%dRfClkBuf: " - "%d\n", j + 1, ret); + "Can't set sysClkReq%dRfClkBuf: %d\n", + j + 1, ret); } } } -- GitLab From 3103d44e4509f6da8b667d185b45eb0ae0beaa85 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 28 Oct 2015 12:21:12 +0000 Subject: [PATCH 2706/2855] mfd: adp5520: Some trivial 'no space before tab' fixes WARNING: please, no space before tabs + * ^IMike Rapoport $ WARNING: please, no space before tabs + * ^IEric Miao $ WARNING: please, no space before tabs +^I.id_table ^I= adp5520_id,$ total: 0 errors, 3 warnings, 365 lines checked Cc: Michael Hennerich Signed-off-by: Lee Jones --- drivers/mfd/adp5520.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c index ae88654595dc5..d817f202da5be 100644 --- a/drivers/mfd/adp5520.c +++ b/drivers/mfd/adp5520.c @@ -9,10 +9,10 @@ * * Derived from da903x: * Copyright (C) 2008 Compulab, Ltd. - * Mike Rapoport + * Mike Rapoport * * Copyright (C) 2006-2008 Marvell International Ltd. - * Eric Miao + * Eric Miao * * Licensed under the GPL-2 or later. */ @@ -355,7 +355,7 @@ static struct i2c_driver adp5520_driver = { }, .probe = adp5520_probe, .remove = adp5520_remove, - .id_table = adp5520_id, + .id_table = adp5520_id, }; module_i2c_driver(adp5520_driver); -- GitLab From b79a980f7161ca09855cc641091d1afe4ef08dd8 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 28 Oct 2015 12:42:30 +0000 Subject: [PATCH 2707/2855] mfd: arizona-core: msleep() is unreliable for anything <20ms use usleep_range() instead WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt + msleep(1); WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt + msleep(5); WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt + msleep(1); WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt + msleep(1); total: 0 errors, 4 warnings, 1407 lines checked Cc: patches@opensource.wolfsonmicro.com Acked-by: Charles Keepax Signed-off-by: Lee Jones --- drivers/mfd/arizona-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 4bb486679110f..5319f252790be 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -238,7 +238,7 @@ static int arizona_poll_reg(struct arizona *arizona, if ((val & mask) == target) return 0; - msleep(1); + usleep_range(1000, 5000); } dev_err(arizona->dev, "Polling reg %u timed out: %x\n", reg, val); @@ -279,14 +279,14 @@ static void arizona_disable_reset(struct arizona *arizona) case WM5110: case WM8280: /* Meet requirements for minimum reset duration */ - msleep(5); + usleep_range(5000, 10000); break; default: break; } gpio_set_value_cansleep(arizona->pdata.reset, 1); - msleep(1); + usleep_range(1000, 5000); } } @@ -1132,7 +1132,7 @@ int arizona_dev_init(struct arizona *arizona) goto err_reset; } - msleep(1); + usleep_range(1000, 5000); } /* Ensure device startup is complete */ -- GitLab From 9f6e872a7003ea6b7f38bcfd5ee6c1e05b18672b Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 28 Oct 2015 13:54:07 +0000 Subject: [PATCH 2708/2855] mfd: arizona-i2c: Add blank line formatting after declaration WARNING: Missing a blank line after declarations + struct arizona *arizona = dev_get_drvdata(&i2c->dev); + arizona_dev_exit(arizona); total: 0 errors, 1 warnings, 120 lines checked Cc: patches@opensource.wolfsonmicro.com Acked-by: Charles Keepax Signed-off-by: Lee Jones --- drivers/mfd/arizona-i2c.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mfd/arizona-i2c.c b/drivers/mfd/arizona-i2c.c index 4e3afd1861fc4..5fe12961cfe54 100644 --- a/drivers/mfd/arizona-i2c.c +++ b/drivers/mfd/arizona-i2c.c @@ -88,7 +88,9 @@ static int arizona_i2c_probe(struct i2c_client *i2c, static int arizona_i2c_remove(struct i2c_client *i2c) { struct arizona *arizona = dev_get_drvdata(&i2c->dev); + arizona_dev_exit(arizona); + return 0; } -- GitLab From ae487ae2ac56ebe02e12fed38047ed41e682ad9e Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 28 Oct 2015 13:57:44 +0000 Subject: [PATCH 2709/2855] mfd: as3711: Repair OOM and 'line over 80 chars' formatting warnings WARNING: Possible unnecessary 'out of memory' message + if (!pdata) { + dev_err(&client->dev, "Failed to allocate pdata\n"); WARNING: Possible unnecessary 'out of memory' message + if (!as3711) { + dev_err(&client->dev, "Memory allocation failed\n"); WARNING: line over 80 characters + dev_err(&client->dev, "regmap initialization failed: %d\n", ret); WARNING: line over 80 characters + /* We can reuse as3711_subdevs[], it will be copied in mfd_add_devices() */ WARNING: line over 80 characters + as3711_subdevs[AS3711_REGULATOR].platform_data = &pdata->regulator; WARNING: line over 80 characters + as3711_subdevs[AS3711_REGULATOR].pdata_size = sizeof(pdata->regulator); WARNING: line over 80 characters + as3711_subdevs[AS3711_BACKLIGHT].platform_data = &pdata->backlight; WARNING: line over 80 characters + as3711_subdevs[AS3711_BACKLIGHT].pdata_size = sizeof(pdata->backlight); total: 0 errors, 8 warnings, 236 lines checked Signed-off-by: Lee Jones --- drivers/mfd/as3711.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/mfd/as3711.c b/drivers/mfd/as3711.c index d001f7e238f5f..94d67a6e1eb71 100644 --- a/drivers/mfd/as3711.c +++ b/drivers/mfd/as3711.c @@ -136,17 +136,13 @@ static int as3711_i2c_probe(struct i2c_client *client, } else { pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - dev_err(&client->dev, "Failed to allocate pdata\n"); + if (!pdata) return -ENOMEM; - } } as3711 = devm_kzalloc(&client->dev, sizeof(struct as3711), GFP_KERNEL); - if (!as3711) { - dev_err(&client->dev, "Memory allocation failed\n"); + if (!as3711) return -ENOMEM; - } as3711->dev = &client->dev; i2c_set_clientdata(client, as3711); @@ -157,7 +153,8 @@ static int as3711_i2c_probe(struct i2c_client *client, as3711->regmap = devm_regmap_init_i2c(client, &as3711_regmap_config); if (IS_ERR(as3711->regmap)) { ret = PTR_ERR(as3711->regmap); - dev_err(&client->dev, "regmap initialization failed: %d\n", ret); + dev_err(&client->dev, + "regmap initialization failed: %d\n", ret); return ret; } @@ -172,12 +169,19 @@ static int as3711_i2c_probe(struct i2c_client *client, return -ENODEV; dev_info(as3711->dev, "AS3711 detected: %x:%x\n", id1, id2); - /* We can reuse as3711_subdevs[], it will be copied in mfd_add_devices() */ + /* + * We can reuse as3711_subdevs[], + * it will be copied in mfd_add_devices() + */ if (pdata) { - as3711_subdevs[AS3711_REGULATOR].platform_data = &pdata->regulator; - as3711_subdevs[AS3711_REGULATOR].pdata_size = sizeof(pdata->regulator); - as3711_subdevs[AS3711_BACKLIGHT].platform_data = &pdata->backlight; - as3711_subdevs[AS3711_BACKLIGHT].pdata_size = sizeof(pdata->backlight); + as3711_subdevs[AS3711_REGULATOR].platform_data = + &pdata->regulator; + as3711_subdevs[AS3711_REGULATOR].pdata_size = + sizeof(pdata->regulator); + as3711_subdevs[AS3711_BACKLIGHT].platform_data = + &pdata->backlight; + as3711_subdevs[AS3711_BACKLIGHT].pdata_size = + sizeof(pdata->backlight); } else { as3711_subdevs[AS3711_REGULATOR].platform_data = NULL; as3711_subdevs[AS3711_REGULATOR].pdata_size = 0; -- GitLab From d43c4290ff5c37e5ba8702301ad51786a37979ed Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 28 Oct 2015 14:11:23 +0000 Subject: [PATCH 2710/2855] mfd: asic3: Fix a plethora of Checkpatch errors and warnings ERROR: Macros with complex values should be enclosed in parentheses +#define INIT_CDEX(_name, _rate) \ + [ASIC3_CLOCK_##_name] = { \ + .cdex = CLOCK_CDEX_##_name, \ + .rate = _rate, \ + } WARNING: line over 80 characters + ASIC3_GPIO_INT_STATUS); WARNING: void function return statements are not generally useful + return; +} WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt + msleep(1); WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt + msleep(1); WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt + msleep(1); WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt + msleep(1); WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt + msleep(1); WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt + msleep(1); WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt + msleep(1); WARNING: line over 80 characters + asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) + WARNING: Prefer [subsystem eg: netdev]_err([subsystem]dev, ... then dev_err(dev, ... then p r_err(... to printk(KERN_ERR ... + printk(KERN_ERR "kzalloc failed\n"); WARNING: Possible unnecessary 'out of memory' message + if (asic == NULL) { + printk(KERN_ERR "kzalloc failed\n"); WARNING: Missing a blank line after declarations + int retval = 0; + retval = platform_driver_probe(&asic3_device_driver, asic3_probe); total: 1 errors, 13 warnings, 1081 lines checked Signed-off-by: Lee Jones --- drivers/mfd/asic3.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 73812eedeefbc..4dca6bc61f5b2 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -167,7 +167,6 @@ static void asic3_irq_demux(struct irq_desc *desc) base = ASIC3_GPIO_A_BASE + bank * ASIC3_GPIO_BASE_INCR; - spin_lock_irqsave(&asic->lock, flags); istat = asic3_read_register(asic, base + @@ -537,8 +536,6 @@ static void asic3_gpio_set(struct gpio_chip *chip, asic3_write_register(asic, gpio_base + ASIC3_GPIO_OUT, out_reg); spin_unlock_irqrestore(&asic->lock, flags); - - return; } static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset) @@ -666,18 +663,18 @@ static int ds1wm_enable(struct platform_device *pdev) asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX0]); asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX1]); asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_OWM]); - msleep(1); + usleep_range(1000, 5000); /* Reset and enable DS1WM */ asic3_set_register(asic, ASIC3_OFFSET(EXTCF, RESET), ASIC3_EXTCF_OWM_RESET, 1); - msleep(1); + usleep_range(1000, 5000); asic3_set_register(asic, ASIC3_OFFSET(EXTCF, RESET), ASIC3_EXTCF_OWM_RESET, 0); - msleep(1); + usleep_range(1000, 5000); asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT), ASIC3_EXTCF_OWM_EN, 1); - msleep(1); + usleep_range(1000, 5000); return 0; } @@ -758,7 +755,7 @@ static int asic3_mmc_enable(struct platform_device *pdev) * when HCLK is stopped. */ asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX1]); - msleep(1); + usleep_range(1000, 5000); /* HCLK 24.576 MHz, BCLK 12.288 MHz: */ asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), @@ -766,7 +763,7 @@ static int asic3_mmc_enable(struct platform_device *pdev) asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_SD_HOST]); asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_SD_BUS]); - msleep(1); + usleep_range(1000, 5000); asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT), ASIC3_EXTCF_SD_MEM_ENABLE, 1); @@ -842,7 +839,7 @@ static int asic3_leds_suspend(struct platform_device *pdev) struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); while (asic3_gpio_get(&asic->gpio, ASIC3_GPIO(C, cell->id)) != 0) - msleep(1); + usleep_range(1000, 5000); asic3_clk_disable(asic, &asic->clocks[clock_ledn[cell->id]]); @@ -901,8 +898,8 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, /* MMC */ if (mem_sdio) { - asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) + - mem_sdio->start, + asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> + asic->bus_shift) + mem_sdio->start, ASIC3_SD_CONFIG_SIZE >> asic->bus_shift); if (!asic->tmio_cnf) { ret = -ENOMEM; @@ -963,10 +960,8 @@ static int __init asic3_probe(struct platform_device *pdev) asic = devm_kzalloc(&pdev->dev, sizeof(struct asic3), GFP_KERNEL); - if (asic == NULL) { - printk(KERN_ERR "kzalloc failed\n"); + if (!asic) return -ENOMEM; - } spin_lock_init(&asic->lock); platform_set_drvdata(pdev, asic); @@ -1075,7 +1070,9 @@ static struct platform_driver asic3_device_driver = { static int __init asic3_init(void) { int retval = 0; + retval = platform_driver_probe(&asic3_device_driver, asic3_probe); + return retval; } -- GitLab From 2756db6c63662a179d1a59be2c0fa260dbd1b2fc Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 28 Oct 2015 16:02:48 +0000 Subject: [PATCH 2711/2855] mfd: cros_ec_i2c: Fix trivial 'tabs before spaces' whitespace issue. ERROR: code indent should use tabs where possible + ^Iec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);$ WARNING: please, no space before tabs + ^Iec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);$ WARNING: please, no spaces at the start of a line + ^Iec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);$ total: 1 errors, 2 warnings, 366 lines checked Signed-off-by: Lee Jones --- drivers/mfd/cros_ec_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/cros_ec_i2c.c b/drivers/mfd/cros_ec_i2c.c index 56a466469664c..9f70de1e4c705 100644 --- a/drivers/mfd/cros_ec_i2c.c +++ b/drivers/mfd/cros_ec_i2c.c @@ -292,7 +292,7 @@ static int cros_ec_i2c_probe(struct i2c_client *client, struct cros_ec_device *ec_dev = NULL; int err; - ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL); + ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL); if (!ec_dev) return -ENOMEM; -- GitLab From 8827a642a4635d5e696037f9213cb1d015d4cec3 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 28 Oct 2015 16:42:45 +0000 Subject: [PATCH 2712/2855] mfd: cros_ec_spi: Repair comparison ordering issue WARNING: Comparisons should place the constant on the right side of the test + BUG_ON(EC_MSG_PREAMBLE_COUNT > ec_dev->din_size); WARNING: Comparisons should place the constant on the right side of the test + BUG_ON(EC_MSG_PREAMBLE_COUNT > ec_dev->din_size); total: 0 errors, 2 warnings, 731 lines checked Signed-off-by: Lee Jones --- drivers/mfd/cros_ec_spi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/cros_ec_spi.c b/drivers/mfd/cros_ec_spi.c index d6af52d18c069..ebe9b9477cb28 100644 --- a/drivers/mfd/cros_ec_spi.c +++ b/drivers/mfd/cros_ec_spi.c @@ -175,7 +175,7 @@ static int cros_ec_spi_receive_packet(struct cros_ec_device *ec_dev, unsigned long deadline; int todo; - BUG_ON(EC_MSG_PREAMBLE_COUNT > ec_dev->din_size); + BUG_ON(ec_dev->din_size < EC_MSG_PREAMBLE_COUNT); /* Receive data until we see the header byte */ deadline = jiffies + msecs_to_jiffies(EC_MSG_DEADLINE_MS); @@ -283,7 +283,7 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev, unsigned long deadline; int todo; - BUG_ON(EC_MSG_PREAMBLE_COUNT > ec_dev->din_size); + BUG_ON(ec_dev->din_size < EC_MSG_PREAMBLE_COUNT); /* Receive data until we see the header byte */ deadline = jiffies + msecs_to_jiffies(EC_MSG_DEADLINE_MS); -- GitLab From 740c19895917d9a25abea65fb20fb13af764ac09 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 28 Oct 2015 16:44:58 +0000 Subject: [PATCH 2713/2855] mfd: cs5535-mfd: Add missing line spacing and make local array static WARNING: Missing a blank line after declarations + struct resource *res; + res = platform_get_resource(pdev, IORESOURCE_IO, 0); WARNING: char * array declaration might be better as static const + const char *acpi_clones[] = { "olpc-xo1-pm-acpi", "olpc-xo1-sci-acpi" }; total: 0 errors, 2 warnings, 192 lines checked Signed-off-by: Lee Jones --- drivers/mfd/cs5535-mfd.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c index be91cb5d6e786..f9d277ff4aaf1 100644 --- a/drivers/mfd/cs5535-mfd.c +++ b/drivers/mfd/cs5535-mfd.c @@ -60,6 +60,7 @@ static int cs5535_mfd_res_enable(struct platform_device *pdev) static int cs5535_mfd_res_disable(struct platform_device *pdev) { struct resource *res; + res = platform_get_resource(pdev, IORESOURCE_IO, 0); if (!res) { dev_err(&pdev->dev, "can't fetch device resource info\n"); @@ -114,7 +115,10 @@ static struct mfd_cell cs5535_mfd_cells[] = { #ifdef CONFIG_OLPC static void cs5535_clone_olpc_cells(void) { - const char *acpi_clones[] = { "olpc-xo1-pm-acpi", "olpc-xo1-sci-acpi" }; + static const char *acpi_clones[] = { + "olpc-xo1-pm-acpi", + "olpc-xo1-sci-acpi" + }; if (!machine_is_olpc()) return; -- GitLab From 8b2775787f2ef0959518206b9df0e6a83ef11496 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 28 Oct 2015 16:47:00 +0000 Subject: [PATCH 2714/2855] mfd: da903x: Fix white space and split string issues While we're at it, let's also match the MODULE_LICENSE with the header. WARNING: please, no space before tabs + * ^IMike Rapoport $ WARNING: please, no space before tabs + * ^IEric Miao $ WARNING: quoted string split across lines +MODULE_AUTHOR("Eric Miao " + "Mike Rapoport "); total: 0 errors, 3 warnings, 574 lines checked Cc: Support Opensource Signed-off-by: Lee Jones --- drivers/mfd/da903x.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c index f6a045900b167..09f367571c58b 100644 --- a/drivers/mfd/da903x.c +++ b/drivers/mfd/da903x.c @@ -2,10 +2,10 @@ * Base driver for Dialog Semiconductor DA9030/DA9034 * * Copyright (C) 2008 Compulab, Ltd. - * Mike Rapoport + * Mike Rapoport * * Copyright (C) 2006-2008 Marvell International Ltd. - * Eric Miao + * Eric Miao * * 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 @@ -565,6 +565,6 @@ static void __exit da903x_exit(void) module_exit(da903x_exit); MODULE_DESCRIPTION("PMIC Driver for Dialog Semiconductor DA9034"); -MODULE_AUTHOR("Eric Miao " - "Mike Rapoport "); -MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Eric Miao "); +MODULE_AUTHOR("Mike Rapoport "); +MODULE_LICENSE("GPL v2"); -- GitLab From 5b7b2ac1529429c22aacc7cbd6704d6c267e8a9c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 28 Oct 2015 16:51:11 +0000 Subject: [PATCH 2715/2855] mfd: da9052-i2c: Fix tabbing/whitespace issue WARNING: suspect code indent for conditional statements (8, 24) + if (!i2c_safe_reg(reg)) + return regmap_read(da9052->regmap, total: 0 errors, 1 warnings, 226 lines checked Cc: Support Opensource Signed-off-by: Lee Jones --- drivers/mfd/da9052-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c index 2697ffb08009b..578e881067a58 100644 --- a/drivers/mfd/da9052-i2c.c +++ b/drivers/mfd/da9052-i2c.c @@ -70,7 +70,7 @@ static int da9052_i2c_fix(struct da9052 *da9052, unsigned char reg) case DA9053_BA: case DA9053_BB: /* A dummy read to a safe register address. */ - if (!i2c_safe_reg(reg)) + if (!i2c_safe_reg(reg)) return regmap_read(da9052->regmap, DA9052_PARK_REGISTER, &val); -- GitLab From 997eea4691c5475765566dbaeb38bb60700c54bb Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 28 Oct 2015 16:53:04 +0000 Subject: [PATCH 2716/2855] mfd: da9052-irq: Fix trivial 'space before comma' error ERROR: space prohibited before that ',' (ctx:WxW) + da9052_free_irq(da9052, DA9052_IRQ_ADC_EOM , da9052); total: 1 errors, 0 warnings, 290 lines checked Cc: Support Opensource Signed-off-by: Lee Jones --- drivers/mfd/da9052-irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/da9052-irq.c b/drivers/mfd/da9052-irq.c index f4cb4613140bf..cd4ca849ca441 100644 --- a/drivers/mfd/da9052-irq.c +++ b/drivers/mfd/da9052-irq.c @@ -283,7 +283,7 @@ regmap_err: int da9052_irq_exit(struct da9052 *da9052) { - da9052_free_irq(da9052, DA9052_IRQ_ADC_EOM , da9052); + da9052_free_irq(da9052, DA9052_IRQ_ADC_EOM, da9052); regmap_del_irq_chip(da9052->chip_irq, da9052->irq_data); return 0; -- GitLab From 9fb41166076b197318807a5f1829911450b43218 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 28 Oct 2015 16:54:29 +0000 Subject: [PATCH 2717/2855] mfd: davinci_voicecodec: Remove pointless 'out of memory' error message WARNING: Possible unnecessary 'out of memory' message + if (!davinci_vc) { + dev_dbg(&pdev->dev, total: 0 errors, 1 warnings, 154 lines checked Signed-off-by: Lee Jones --- drivers/mfd/davinci_voicecodec.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c index 9bbc642a7b9db..dff2f19296b88 100644 --- a/drivers/mfd/davinci_voicecodec.c +++ b/drivers/mfd/davinci_voicecodec.c @@ -47,11 +47,8 @@ static int __init davinci_vc_probe(struct platform_device *pdev) davinci_vc = devm_kzalloc(&pdev->dev, sizeof(struct davinci_vc), GFP_KERNEL); - if (!davinci_vc) { - dev_dbg(&pdev->dev, - "could not allocate memory for private data\n"); + if (!davinci_vc) return -ENOMEM; - } davinci_vc->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(davinci_vc->clk)) { -- GitLab From 7030a7e9321166eef44c811fe4af4d460360d424 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 13 Jan 2016 15:39:40 +0300 Subject: [PATCH 2718/2855] x86/cpu/amd: Remove an unneeded condition in srat_detect_node() Originally we calculated ht_nodeid as "ht_nodeid = apicid - boot_cpu_id;" so presumably it could be negative. But after commit: 01aaea1afbcd ('x86: introduce initial apicid') we use c->initial_apicid which is an unsigned short and thus always >= 0. It causes a static checker warning to test for impossible conditions so let's remove it. Signed-off-by: Dan Carpenter Cc: Andy Lutomirski Cc: Aravind Gopalakrishnan Cc: Borislav Petkov Cc: Hector Marco-Gisbert Cc: Huang Rui Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Yinghai Lu Link: http://lkml.kernel.org/r/20160113123940.GE19993@mwanda Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/amd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index e678ddeed0306..a07956a08936e 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -434,8 +434,7 @@ static void srat_detect_node(struct cpuinfo_x86 *c) */ int ht_nodeid = c->initial_apicid; - if (ht_nodeid >= 0 && - __apicid_to_node[ht_nodeid] != NUMA_NO_NODE) + if (__apicid_to_node[ht_nodeid] != NUMA_NO_NODE) node = __apicid_to_node[ht_nodeid]; /* Pick a nearby node */ if (!node_online(node)) -- GitLab From 525fd5a94e1be0776fa652df5c687697db508c91 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Sun, 27 Dec 2015 02:13:27 +0300 Subject: [PATCH 2719/2855] sparc64: fix incorrect sign extension in sys_sparc64_personality The value returned by sys_personality has type "long int". It is saved to a variable of type "int", which is not a problem yet because the type of task_struct->pesonality is "unsigned int". The problem is the sign extension from "int" to "long int" that happens on return from sys_sparc64_personality. For example, a userspace call personality((unsigned) -EINVAL) will result to any subsequent personality call, including absolutely harmless read-only personality(0xffffffff) call, failing with errno set to EINVAL. Signed-off-by: Dmitry V. Levin Cc: Signed-off-by: David S. Miller --- arch/sparc/kernel/sys_sparc_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 30e7ddb27a3a9..c690c8e16a96e 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -413,7 +413,7 @@ out: SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality) { - int ret; + long ret; if (personality(current->personality) == PER_LINUX32 && personality(personality) == PER_LINUX) -- GitLab From 5d19c619ab3f0551864684f09c2a2f22ee972bef Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 14 Jan 2016 15:46:28 +0100 Subject: [PATCH 2720/2855] fsl/fman: Delete one function call "put_device" in dtsec_config() The Coccinelle semantic patch script "deref_null.cocci" pointed a problem out in the implementation of the function "dtsec_config". A null pointer was assigned to the data structure member "tbiphy" of the variable "dtsec" if a matching device was not found. A call of the function "put_device" was unnecessary then because a previous call of the function "get_device" was not triggered. Thus remove the function call "put_device" after the printing of the desired error message. Signed-off-by: Markus Elfring Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fman/fman_dtsec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/fman/fman_dtsec.c b/drivers/net/ethernet/freescale/fman/fman_dtsec.c index 6b1261c0b1c26..7c92eb854925a 100644 --- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c +++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c @@ -1434,7 +1434,6 @@ struct fman_mac *dtsec_config(struct fman_mac_params *params) dtsec->tbiphy = of_phy_find_device(params->internal_phy_node); if (!dtsec->tbiphy) { pr_err("of_phy_find_device (TBI PHY) failed\n"); - put_device(&dtsec->tbiphy->mdio.dev); goto err_dtsec_drv_param; } -- GitLab From 36beca6571c941b28b0798667608239731f9bc3a Mon Sep 17 00:00:00 2001 From: Nitin Gupta Date: Tue, 5 Jan 2016 22:35:35 -0800 Subject: [PATCH 2721/2855] sparc64: Fix numa node distance initialization Orabug: 22495713 Currently, NUMA node distance matrix is initialized only when a machine descriptor (MD) exists. However, sun4u machines (e.g. Sun Blade 2500) do not have an MD and thus distance values were left uninitialized. The initialization is now moved such that it happens on both sun4u and sun4v. Signed-off-by: Nitin Gupta Tested-by: Mikael Pettersson Signed-off-by: David S. Miller --- arch/sparc/mm/init_64.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 3025bd57f7abb..6f216853f2724 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -1267,13 +1267,6 @@ static int __init numa_parse_mdesc(void) int i, j, err, count; u64 node; - /* Some sane defaults for numa latency values */ - for (i = 0; i < MAX_NUMNODES; i++) { - for (j = 0; j < MAX_NUMNODES; j++) - numa_latency[i][j] = (i == j) ? - LOCAL_DISTANCE : REMOTE_DISTANCE; - } - node = mdesc_node_by_name(md, MDESC_NODE_NULL, "latency-groups"); if (node == MDESC_NODE_NULL) { mdesc_release(md); @@ -1369,10 +1362,18 @@ static int __init numa_parse_sun4u(void) static int __init bootmem_init_numa(void) { + int i, j; int err = -1; numadbg("bootmem_init_numa()\n"); + /* Some sane defaults for numa latency values */ + for (i = 0; i < MAX_NUMNODES; i++) { + for (j = 0; j < MAX_NUMNODES; j++) + numa_latency[i][j] = (i == j) ? + LOCAL_DISTANCE : REMOTE_DISTANCE; + } + if (numa_enabled) { if (tlb_type == hypervisor) err = numa_parse_mdesc(); -- GitLab From 6e8b50d16a757d53f8817acecba97c5d4aa1cf65 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 17 Nov 2015 06:52:23 -0500 Subject: [PATCH 2722/2855] nfsd: add new io class tracepoint Add some new tracepoints in the nfsd read/write codepaths. The idea is that this will give us the ability to measure how long each phase of a read or write operation takes. Signed-off-by: Jeff Layton Signed-off-by: J. Bruce Fields --- fs/nfsd/nfsfh.h | 23 +++++++++++++++++++++++ fs/nfsd/trace.h | 41 +++++++++++++++++++++++++++++++++++++++++ fs/nfsd/vfs.c | 15 +++++++++++++++ 3 files changed, 79 insertions(+) diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h index 2087bae17582a..0770bcb543c81 100644 --- a/fs/nfsd/nfsfh.h +++ b/fs/nfsd/nfsfh.h @@ -7,6 +7,7 @@ #ifndef _LINUX_NFSD_NFSFH_H #define _LINUX_NFSD_NFSFH_H +#include #include #include @@ -205,6 +206,28 @@ static inline bool fh_fsid_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2) return true; } +#ifdef CONFIG_CRC32 +/** + * knfsd_fh_hash - calculate the crc32 hash for the filehandle + * @fh - pointer to filehandle + * + * returns a crc32 hash for the filehandle that is compatible with + * the one displayed by "wireshark". + */ + +static inline u32 +knfsd_fh_hash(struct knfsd_fh *fh) +{ + return ~crc32_le(0xFFFFFFFF, (unsigned char *)&fh->fh_base, fh->fh_size); +} +#else +static inline u32 +knfsd_fh_hash(struct knfsd_fh *fh) +{ + return 0; +} +#endif + #ifdef CONFIG_NFSD_V3 /* * The wcc data stored in current_fh should be cleared diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h index 0befe762762b0..3287041905dab 100644 --- a/fs/nfsd/trace.h +++ b/fs/nfsd/trace.h @@ -8,6 +8,47 @@ #define _NFSD_TRACE_H #include +#include "nfsfh.h" + +DECLARE_EVENT_CLASS(nfsd_io_class, + TP_PROTO(struct svc_rqst *rqstp, + struct svc_fh *fhp, + loff_t offset, + int len), + TP_ARGS(rqstp, fhp, offset, len), + TP_STRUCT__entry( + __field(__be32, xid) + __field_struct(struct knfsd_fh, fh) + __field(loff_t, offset) + __field(int, len) + ), + TP_fast_assign( + __entry->xid = rqstp->rq_xid, + fh_copy_shallow(&__entry->fh, &fhp->fh_handle); + __entry->offset = offset; + __entry->len = len; + ), + TP_printk("xid=0x%x fh=0x%x offset=%lld len=%d", + __be32_to_cpu(__entry->xid), knfsd_fh_hash(&__entry->fh), + __entry->offset, __entry->len) +) + +#define DEFINE_NFSD_IO_EVENT(name) \ +DEFINE_EVENT(nfsd_io_class, name, \ + TP_PROTO(struct svc_rqst *rqstp, \ + struct svc_fh *fhp, \ + loff_t offset, \ + int len), \ + TP_ARGS(rqstp, fhp, offset, len)) + +DEFINE_NFSD_IO_EVENT(read_start); +DEFINE_NFSD_IO_EVENT(read_opened); +DEFINE_NFSD_IO_EVENT(read_io_done); +DEFINE_NFSD_IO_EVENT(read_done); +DEFINE_NFSD_IO_EVENT(write_start); +DEFINE_NFSD_IO_EVENT(write_opened); +DEFINE_NFSD_IO_EVENT(write_io_done); +DEFINE_NFSD_IO_EVENT(write_done); #include "state.h" diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 994d66fbb4467..3257c59dc8601 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -42,6 +42,7 @@ #include "nfsd.h" #include "vfs.h" +#include "trace.h" #define NFSDDBG_FACILITY NFSDDBG_FILEOP @@ -983,16 +984,23 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct raparms *ra; __be32 err; + trace_read_start(rqstp, fhp, offset, vlen); err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); if (err) return err; ra = nfsd_init_raparms(file); + + trace_read_opened(rqstp, fhp, offset, vlen); err = nfsd_vfs_read(rqstp, file, offset, vec, vlen, count); + trace_read_io_done(rqstp, fhp, offset, vlen); + if (ra) nfsd_put_raparams(file, ra); fput(file); + trace_read_done(rqstp, fhp, offset, vlen); + return err; } @@ -1008,24 +1016,31 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, { __be32 err = 0; + trace_write_start(rqstp, fhp, offset, vlen); + if (file) { err = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry, NFSD_MAY_WRITE|NFSD_MAY_OWNER_OVERRIDE); if (err) goto out; + trace_write_opened(rqstp, fhp, offset, vlen); err = nfsd_vfs_write(rqstp, fhp, file, offset, vec, vlen, cnt, stablep); + trace_write_io_done(rqstp, fhp, offset, vlen); } else { err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_WRITE, &file); if (err) goto out; + trace_write_opened(rqstp, fhp, offset, vlen); if (cnt) err = nfsd_vfs_write(rqstp, fhp, file, offset, vec, vlen, cnt, stablep); + trace_write_io_done(rqstp, fhp, offset, vlen); fput(file); } out: + trace_write_done(rqstp, fhp, offset, vlen); return err; } -- GitLab From e8ecde25f5e08f89b61d86c32bbb56b405e90c32 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 14 Jan 2016 17:52:59 -0500 Subject: [PATCH 2723/2855] Make sure that highmem pages are not added to symlink page cache inode_nohighmem() is sufficient to make sure that page_get_link() won't try to allocate a highmem page. Moreover, it is sufficient to make sure that page_symlink/__page_symlink won't do the same thing. However, any filesystem that manually preseeds the symlink's page cache upon symlink(2) needs to make sure that the page it inserts there won't be a highmem one. Fortunately, only nfs and shmem have run afoul of that... Signed-off-by: Al Viro --- Documentation/filesystems/porting | 6 +++++- fs/nfs/dir.c | 5 ++--- mm/shmem.c | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index 0f88e6020487f..f1b87d8aa2da5 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting @@ -508,7 +508,11 @@ in your dentry operations instead. [mandatory] any symlink that might use page_follow_link_light/page_put_link() must have inode_nohighmem(inode) called before anything might start playing with - its pagecache. + its pagecache. No highmem pages should end up in the pagecache of such + symlinks. That includes any preseeding that might be done during symlink + creation. __page_symlink() will honour the mapping gfp flags, so once + you've done inode_nohighmem() it's safe to use, but if you allocate and + insert the page manually, make sure to use the right gfp flags. -- [mandatory] ->follow_link() is replaced with ->get_link(); same API, except that diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index ce5a218610742..8a05309216857 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1894,15 +1894,14 @@ int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) attr.ia_mode = S_IFLNK | S_IRWXUGO; attr.ia_valid = ATTR_MODE; - page = alloc_page(GFP_HIGHUSER); + page = alloc_page(GFP_USER); if (!page) return -ENOMEM; - kaddr = kmap_atomic(page); + kaddr = page_address(page); memcpy(kaddr, symname, pathlen); if (pathlen < PAGE_SIZE) memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen); - kunmap_atomic(kaddr); trace_nfs_symlink_enter(dir, dentry); error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr); diff --git a/mm/shmem.c b/mm/shmem.c index 5813b7fa85b64..642471b0ddea0 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -2469,6 +2469,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s inode->i_op = &shmem_short_symlink_operations; inode->i_link = info->symlink; } else { + inode_nohighmem(inode); error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL); if (error) { iput(inode); @@ -2476,7 +2477,6 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s } inode->i_mapping->a_ops = &shmem_aops; inode->i_op = &shmem_symlink_inode_operations; - inode_nohighmem(inode); memcpy(page_address(page), symname, len); SetPageUptodate(page); set_page_dirty(page); -- GitLab From 601f1db653217f205ffa5fb33514b4e1711e56d1 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Thu, 14 Jan 2016 15:16:47 -0800 Subject: [PATCH 2724/2855] m32r: fix m32104ut_defconfig build fail The build of m32104ut_defconfig for m32r arch was failing for long long time with the error: ERROR: "memory_start" [fs/udf/udf.ko] undefined! ERROR: "memory_end" [fs/udf/udf.ko] undefined! ERROR: "memory_end" [drivers/scsi/sg.ko] undefined! ERROR: "memory_start" [drivers/scsi/sg.ko] undefined! ERROR: "memory_end" [drivers/i2c/i2c-dev.ko] undefined! ERROR: "memory_start" [drivers/i2c/i2c-dev.ko] undefined! As done in other architectures export the symbols to fix the error. Reported-by: Fengguang Wu Signed-off-by: Sudip Mukherjee Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/m32r/kernel/setup.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c index 0392112a5d702..a5ecef7188baa 100644 --- a/arch/m32r/kernel/setup.c +++ b/arch/m32r/kernel/setup.c @@ -81,7 +81,10 @@ static struct resource code_resource = { }; unsigned long memory_start; +EXPORT_SYMBOL(memory_start); + unsigned long memory_end; +EXPORT_SYMBOL(memory_end); void __init setup_arch(char **); int get_cpuinfo(char *); -- GitLab From ea535e418c01837d07b6c94e817540f50bfdadb0 Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Thu, 14 Jan 2016 15:16:50 -0800 Subject: [PATCH 2725/2855] dma-debug: switch check from _text to _stext In include/asm-generic/sections.h: /* * Usage guidelines: * _text, _data: architecture specific, don't use them in * arch-independent code * [_stext, _etext]: contains .text.* sections, may also contain * .rodata.* * and/or .init.* sections _text is not guaranteed across architectures. Architectures such as ARM may reuse parts which are not actually text and erroneously trigger a bug. Switch to using _stext which is guaranteed to contain text sections. Came out of https://lkml.kernel.org/g/<567B1176.4000106@redhat.com> Signed-off-by: Laura Abbott Reviewed-by: Kees Cook Cc: Russell King Cc: Arnd Bergmann Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/dma-debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dma-debug.c b/lib/dma-debug.c index d34bd24c2c847..4a1515f4b452b 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c @@ -1181,7 +1181,7 @@ static inline bool overlap(void *addr, unsigned long len, void *start, void *end static void check_for_illegal_area(struct device *dev, void *addr, unsigned long len) { - if (overlap(addr, len, _text, _etext) || + if (overlap(addr, len, _stext, _etext) || overlap(addr, len, __start_rodata, __end_rodata)) err_printk(dev, NULL, "DMA-API: device driver maps memory from kernel text or rodata [addr=%p] [len=%lu]\n", addr, len); } -- GitLab From 72214a24a7677d4c7501eecc9517ed681b5f2db2 Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Thu, 14 Jan 2016 15:16:53 -0800 Subject: [PATCH 2726/2855] scripts/bloat-o-meter: fix python3 syntax error In Python3+ print is a function so the old syntax is not correct anymore: $ ./scripts/bloat-o-meter vmlinux.o vmlinux.o.old File "./scripts/bloat-o-meter", line 61 print "add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \ ^ SyntaxError: invalid syntax Fix by calling print as a function. Tested on python 2.7.11, 3.5.1 Signed-off-by: Sergey Senozhatsky Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/bloat-o-meter | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter index 23e78dcd12bf7..38b64f4873152 100755 --- a/scripts/bloat-o-meter +++ b/scripts/bloat-o-meter @@ -58,8 +58,8 @@ for name in common: delta.sort() delta.reverse() -print "add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \ - (add, remove, grow, shrink, up, -down, up-down) -print "%-40s %7s %7s %+7s" % ("function", "old", "new", "delta") +print("add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \ + (add, remove, grow, shrink, up, -down, up-down)) +print("%-40s %7s %7s %+7s" % ("function", "old", "new", "delta")) for d, n in delta: - if d: print "%-40s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d) + if d: print("%-40s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d)) -- GitLab From 1deaf9d19776916cd1c83191503bf327319a301a Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 14 Jan 2016 15:16:56 -0800 Subject: [PATCH 2727/2855] fs/notify/inode_mark.c: use list_next_entry in fsnotify_unmount_inodes To make the intention clearer, use list_next_entry instead of list_entry. Signed-off-by: Geliang Tang Reviewed-by: Jan Kara Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/notify/inode_mark.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c index e785fd954c307..741077deef3b5 100644 --- a/fs/notify/inode_mark.c +++ b/fs/notify/inode_mark.c @@ -199,8 +199,7 @@ void fsnotify_unmount_inodes(struct super_block *sb) break; } spin_unlock(&next_i->i_lock); - next_i = list_entry(next_i->i_sb_list.next, - struct inode, i_sb_list); + next_i = list_next_entry(next_i, i_sb_list); } /* -- GitLab From c510eff6bebaa244e577b8f499e86606b5e5d4c7 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Thu, 14 Jan 2016 15:16:59 -0800 Subject: [PATCH 2728/2855] fsnotify: destroy marks with call_srcu instead of dedicated thread At the time that this code was originally written, call_srcu didn't exist, so this thread was required to ensure that we waited for that SRCU grace period to settle before finally freeing the object. It does exist now however and we can much more efficiently use call_srcu to handle this. That also allows us to potentially use srcu_barrier to ensure that they are all of the callbacks have run before proceeding. In order to conserve space, we union the rcu_head with the g_list. This will be necessary for nfsd which will allocate marks from a dedicated slabcache. We have to be able to ensure that all of the objects are destroyed before destroying the cache. That's fairly Signed-off-by: Jeff Layton Cc: Eric Paris Reviewed-by: Jan Kara Cc: "Paul E. McKenney" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/notify/mark.c | 66 +++++++------------------------- include/linux/fsnotify_backend.h | 5 ++- 2 files changed, 18 insertions(+), 53 deletions(-) diff --git a/fs/notify/mark.c b/fs/notify/mark.c index fc0df4442f7b4..cfcbf114676ed 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -92,9 +92,6 @@ #include "fsnotify.h" struct srcu_struct fsnotify_mark_srcu; -static DEFINE_SPINLOCK(destroy_lock); -static LIST_HEAD(destroy_list); -static DECLARE_WAIT_QUEUE_HEAD(destroy_waitq); void fsnotify_get_mark(struct fsnotify_mark *mark) { @@ -168,10 +165,19 @@ void fsnotify_detach_mark(struct fsnotify_mark *mark) atomic_dec(&group->num_marks); } +static void +fsnotify_mark_free_rcu(struct rcu_head *rcu) +{ + struct fsnotify_mark *mark; + + mark = container_of(rcu, struct fsnotify_mark, g_rcu); + fsnotify_put_mark(mark); +} + /* - * Free fsnotify mark. The freeing is actually happening from a kthread which - * first waits for srcu period end. Caller must have a reference to the mark - * or be protected by fsnotify_mark_srcu. + * Free fsnotify mark. The freeing is actually happening from a call_srcu + * callback. Caller must have a reference to the mark or be protected by + * fsnotify_mark_srcu. */ void fsnotify_free_mark(struct fsnotify_mark *mark) { @@ -186,10 +192,7 @@ void fsnotify_free_mark(struct fsnotify_mark *mark) mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE; spin_unlock(&mark->lock); - spin_lock(&destroy_lock); - list_add(&mark->g_list, &destroy_list); - spin_unlock(&destroy_lock); - wake_up(&destroy_waitq); + call_srcu(&fsnotify_mark_srcu, &mark->g_rcu, fsnotify_mark_free_rcu); /* * Some groups like to know that marks are being freed. This is a @@ -385,11 +388,7 @@ err: spin_unlock(&mark->lock); - spin_lock(&destroy_lock); - list_add(&mark->g_list, &destroy_list); - spin_unlock(&destroy_lock); - wake_up(&destroy_waitq); - + call_srcu(&fsnotify_mark_srcu, &mark->g_rcu, fsnotify_mark_free_rcu); return ret; } @@ -492,40 +491,3 @@ void fsnotify_init_mark(struct fsnotify_mark *mark, atomic_set(&mark->refcnt, 1); mark->free_mark = free_mark; } - -static int fsnotify_mark_destroy(void *ignored) -{ - struct fsnotify_mark *mark, *next; - struct list_head private_destroy_list; - - for (;;) { - spin_lock(&destroy_lock); - /* exchange the list head */ - list_replace_init(&destroy_list, &private_destroy_list); - spin_unlock(&destroy_lock); - - synchronize_srcu(&fsnotify_mark_srcu); - - list_for_each_entry_safe(mark, next, &private_destroy_list, g_list) { - list_del_init(&mark->g_list); - fsnotify_put_mark(mark); - } - - wait_event_interruptible(destroy_waitq, !list_empty(&destroy_list)); - } - - return 0; -} - -static int __init fsnotify_mark_init(void) -{ - struct task_struct *thread; - - thread = kthread_run(fsnotify_mark_destroy, NULL, - "fsnotify_mark"); - if (IS_ERR(thread)) - panic("unable to start fsnotify mark destruction thread."); - - return 0; -} -device_initcall(fsnotify_mark_init); diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 533c4408529a1..6b7e89f45aa49 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -220,7 +220,10 @@ struct fsnotify_mark { /* List of marks by group->i_fsnotify_marks. Also reused for queueing * mark into destroy_list when it's waiting for the end of SRCU period * before it can be freed. [group->mark_mutex] */ - struct list_head g_list; + union { + struct list_head g_list; + struct rcu_head g_rcu; + }; /* Protects inode / mnt pointers, flags, masks */ spinlock_t lock; /* List of marks for inode / vfsmount [obj_lock] */ -- GitLab From 2f632369ab795ebadc1a12a609e5bd4f80f31924 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 14 Jan 2016 15:17:02 -0800 Subject: [PATCH 2729/2855] modpost: don't add a trailing wildcard for OF module aliases Commit ac551828993e ("modpost: i2c aliases need no trailing wildcard") removed the wildcard at the end of the I2C module aliases because I2C devices have no IDs so the aliases are just arbitrary device names. This is also true for OF modaliases since a compatible string is used to define a specific IP hardware block. So the modalias should match a specific compatible string and not attempt to match a compatible string whose name matches the beginning of another one. For example, the following driver module: $ modinfo cros_ec_keyb | grep alias alias: platform:cros-ec-keyb alias: of:N*T*Cgoogle,cros-ec-keyb* will be tried to be loaded for an alias of:N*T*Cgoogle,cros-ec-keyb-v2 but there could be a different driver that supports the device for that compatible string so it's better to remove the trailing wildcard for OF. Also, remove the word "always" from the add_wildcard() function comment since that was carried from the time where a wildcard was always added at the end of the module alias for all the devices. Signed-off-by: Javier Martinez Canillas Suggested-by: Brian Norris Reviewed-by: Sjoerd Simons Cc: Rusty Russell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/mod/file2alias.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 8adca44061980..161dd0d67da8a 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -125,7 +125,7 @@ do { \ sprintf(str + strlen(str), "*"); \ } while(0) -/* Always end in a wildcard, for future extension */ +/* End in a wildcard, for future extension */ static inline void add_wildcard(char *str) { int len = strlen(str); @@ -704,7 +704,6 @@ static int do_of_entry (const char *filename, void *symval, char *alias) if (isspace (*tmp)) *tmp = '_'; - add_wildcard(alias); return 1; } ADD_TO_DEVTABLE("of", of_device_id, do_of_entry); -- GitLab From 2886357b24662fcf7dc138c9d5e3166e99a55750 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 14 Jan 2016 15:17:05 -0800 Subject: [PATCH 2730/2855] logfs: fix logfs build errors and dependencies Fix build errors that happen when CONFIG_LOGFS=y and CONFIG_MTD=m: fs/built-in.o: In function `logfs_mount': super.c:(.text+0x92a6f): undefined reference to `logfs_get_sb_mtd' fs/built-in.o: In function `logfs_get_sb_bdev': (.text+0x93530): undefined reference to `logfs_get_sb_mtd' This patch avoids the error by changing the dependencies of logfs in a way that we can no longer configure logfs as built-in when the MTD core is a loadable module, while leaving the dependency to require at least one of MTD or BLOCK to be enabled. Signed-off-by: Arnd Bergmann Signed-off-by: Randy Dunlap Cc: Michal Marek Cc: Peter Chen Cc: Randy Dunlap Cc: Joern Engel Cc: Prasad Joshi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/logfs/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/logfs/Kconfig b/fs/logfs/Kconfig index 09ed066c0221a..2b45031639301 100644 --- a/fs/logfs/Kconfig +++ b/fs/logfs/Kconfig @@ -1,6 +1,6 @@ config LOGFS tristate "LogFS file system" - depends on (MTD || BLOCK) + depends on MTD || (!MTD && BLOCK) select ZLIB_INFLATE select ZLIB_DEFLATE select CRC32 -- GitLab From 3eb5bdf0f47726e3ef0a875e0cce3cca462ee70d Mon Sep 17 00:00:00 2001 From: "Norton.Zhu" Date: Thu, 14 Jan 2016 15:17:09 -0800 Subject: [PATCH 2731/2855] ocfs2: optimize bad declarations and redundant assignment In ocfs2_parse_options, a) it's better to declare variables(small size) outside of while loop; b) 'option' will be set by match_int, 'option = 0;' makes no sense, if match_int failed, it just goto bail and return. Signed-off-by: Norton.Zhu Reviewed-by: Joseph Qi Cc: Gang He Cc: Mark Fasheh Acked-by: Joel Becker Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/super.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 2de4c8a9340c2..64dcd787fa804 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -1280,6 +1280,8 @@ static int ocfs2_parse_options(struct super_block *sb, int status, user_stack = 0; char *p; u32 tmp; + int token, option; + substring_t args[MAX_OPT_ARGS]; trace_ocfs2_parse_options(is_remount, options ? options : "(none)"); @@ -1298,9 +1300,6 @@ static int ocfs2_parse_options(struct super_block *sb, } while ((p = strsep(&options, ",")) != NULL) { - int token, option; - substring_t args[MAX_OPT_ARGS]; - if (!*p) continue; @@ -1367,7 +1366,6 @@ static int ocfs2_parse_options(struct super_block *sb, mopt->atime_quantum = option; break; case Opt_slot: - option = 0; if (match_int(&args[0], &option)) { status = 0; goto bail; @@ -1376,7 +1374,6 @@ static int ocfs2_parse_options(struct super_block *sb, mopt->slot = (s16)option; break; case Opt_commit: - option = 0; if (match_int(&args[0], &option)) { status = 0; goto bail; @@ -1388,7 +1385,6 @@ static int ocfs2_parse_options(struct super_block *sb, mopt->commit_interval = HZ * option; break; case Opt_localalloc: - option = 0; if (match_int(&args[0], &option)) { status = 0; goto bail; -- GitLab From d6364627eff4c9a2035cebb3aec7415705ba117b Mon Sep 17 00:00:00 2001 From: John Haxby Date: Thu, 14 Jan 2016 15:17:12 -0800 Subject: [PATCH 2732/2855] ocfs2: return non-zero st_blocks for inline data Some versions of tar assume that files with st_blocks == 0 do not contain any data and will skip reading them entirely. See also commit 9206c561554c ("ext4: return non-zero st_blocks for inline data"). Signed-off-by: John Haxby Reviewed-by: Mark Fasheh Cc: Joel Becker Acked-by: Gang He Reviewed-by: Junxiao Bi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/file.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 0e5b4515f92e7..d631279325092 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1302,6 +1302,14 @@ int ocfs2_getattr(struct vfsmount *mnt, } generic_fillattr(inode, stat); + /* + * If there is inline data in the inode, the inode will normally not + * have data blocks allocated (it may have an external xattr block). + * Report at least one sector for such files, so tools like tar, rsync, + * others don't incorrectly think the file is completely sparse. + */ + if (unlikely(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL)) + stat->blocks += (stat->size + 511)>>9; /* We set the blksize from the cluster size for performance */ stat->blksize = osb->s_clustersize; -- GitLab From a84ac334dcb44c76f0b051513a6c27a2d747f883 Mon Sep 17 00:00:00 2001 From: Junxiao Bi Date: Thu, 14 Jan 2016 15:17:15 -0800 Subject: [PATCH 2733/2855] ocfs2: o2hb: increase unsteady iterations When run multiple xattr test of ocfs2-test on a three-nodes cluster, mount failed sometimes with the following message. o2hb: Unable to stabilize heartbeart on region D18B775E758D4D80837E8CF3D086AD4A (xvdb) Stabilize heartbeat depends on the timing order to mount ocfs2 from cluster nodes and how fast the tcp connections are established. So increase unsteady interations to leave more time for it. Signed-off-by: Junxiao Bi Cc: Mark Fasheh Cc: Joel Becker Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/cluster/heartbeat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 709fbbd44c653..a3cc6d2fc896c 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c @@ -1780,8 +1780,8 @@ static ssize_t o2hb_region_dev_store(struct config_item *item, } ++live_threshold; atomic_set(®->hr_steady_iterations, live_threshold); - /* unsteady_iterations is double the steady_iterations */ - atomic_set(®->hr_unsteady_iterations, (live_threshold << 1)); + /* unsteady_iterations is triple the steady_iterations */ + atomic_set(®->hr_unsteady_iterations, (live_threshold * 3)); hb_task = kthread_run(o2hb_thread, reg, "o2hb-%s", reg->hr_item.ci_name); -- GitLab From 30bee898f86506893883ffb8db20d8101a29b5f5 Mon Sep 17 00:00:00 2001 From: Xue jiufei Date: Thu, 14 Jan 2016 15:17:18 -0800 Subject: [PATCH 2734/2855] ocfs2/dlm: fix a race between purge and migration We found a race between purge and migration when doing code review. Node A put lockres to purgelist before receiving the migrate message from node B which is the master. Node A call dlm_mig_lockres_handler to handle this message. dlm_mig_lockres_handler dlm_lookup_lockres >>>>>> race window, dlm_run_purge_list may run and send deref message to master, waiting the response spin_lock(&res->spinlock); res->state |= DLM_LOCK_RES_MIGRATING; spin_unlock(&res->spinlock); dlm_mig_lockres_handler returns >>>>>> dlm_thread receives the response from master for the deref message and triggers the BUG because the lockres has the state DLM_LOCK_RES_MIGRATING with the following message: dlm_purge_lockres:209 ERROR: 6633EB681FA7474A9C280A4E1A836F0F: res M0000000000000000030c0300000000 in use after deref Signed-off-by: Jiufei Xue Reviewed-by: Joseph Qi Reviewed-by: Yiwen Jiang Cc: Mark Fasheh Cc: Joel Becker Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/dlm/dlmrecovery.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 9e4f862d20fe1..86fb53614bf4f 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c @@ -1373,6 +1373,7 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, char *buf = NULL; struct dlm_work_item *item = NULL; struct dlm_lock_resource *res = NULL; + unsigned int hash; if (!dlm_grab(dlm)) return -EINVAL; @@ -1400,7 +1401,10 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, /* lookup the lock to see if we have a secondary queue for this * already... just add the locks in and this will have its owner * and RECOVERY flag changed when it completes. */ - res = dlm_lookup_lockres(dlm, mres->lockname, mres->lockname_len); + hash = dlm_lockid_hash(mres->lockname, mres->lockname_len); + spin_lock(&dlm->spinlock); + res = __dlm_lookup_lockres(dlm, mres->lockname, mres->lockname_len, + hash); if (res) { /* this will get a ref on res */ /* mark it as recovering/migrating and hash it */ @@ -1421,13 +1425,16 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, mres->lockname_len, mres->lockname); ret = -EFAULT; spin_unlock(&res->spinlock); + spin_unlock(&dlm->spinlock); dlm_lockres_put(res); goto leave; } res->state |= DLM_LOCK_RES_MIGRATING; } spin_unlock(&res->spinlock); + spin_unlock(&dlm->spinlock); } else { + spin_unlock(&dlm->spinlock); /* need to allocate, just like if it was * mastered here normally */ res = dlm_new_lockres(dlm, mres->lockname, mres->lockname_len); -- GitLab From 9e62dc096ef39ccf45fc47e8612f3c5d361af038 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 14 Jan 2016 15:17:21 -0800 Subject: [PATCH 2735/2855] ocfs2: constify ocfs2_extent_tree_operations structures The ocfs2_extent_tree_operations structures are never modified, so declare them as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Cc: Mark Fasheh Cc: Joel Becker Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/alloc.c | 12 ++++++------ fs/ocfs2/alloc.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 86181d6526dc5..2a0aeb77ec425 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -164,7 +164,7 @@ static int ocfs2_dinode_insert_check(struct ocfs2_extent_tree *et, struct ocfs2_extent_rec *rec); static int ocfs2_dinode_sanity_check(struct ocfs2_extent_tree *et); static void ocfs2_dinode_fill_root_el(struct ocfs2_extent_tree *et); -static struct ocfs2_extent_tree_operations ocfs2_dinode_et_ops = { +static const struct ocfs2_extent_tree_operations ocfs2_dinode_et_ops = { .eo_set_last_eb_blk = ocfs2_dinode_set_last_eb_blk, .eo_get_last_eb_blk = ocfs2_dinode_get_last_eb_blk, .eo_update_clusters = ocfs2_dinode_update_clusters, @@ -286,7 +286,7 @@ static void ocfs2_xattr_value_update_clusters(struct ocfs2_extent_tree *et, le32_add_cpu(&vb->vb_xv->xr_clusters, clusters); } -static struct ocfs2_extent_tree_operations ocfs2_xattr_value_et_ops = { +static const struct ocfs2_extent_tree_operations ocfs2_xattr_value_et_ops = { .eo_set_last_eb_blk = ocfs2_xattr_value_set_last_eb_blk, .eo_get_last_eb_blk = ocfs2_xattr_value_get_last_eb_blk, .eo_update_clusters = ocfs2_xattr_value_update_clusters, @@ -332,7 +332,7 @@ static void ocfs2_xattr_tree_update_clusters(struct ocfs2_extent_tree *et, le32_add_cpu(&xb->xb_attrs.xb_root.xt_clusters, clusters); } -static struct ocfs2_extent_tree_operations ocfs2_xattr_tree_et_ops = { +static const struct ocfs2_extent_tree_operations ocfs2_xattr_tree_et_ops = { .eo_set_last_eb_blk = ocfs2_xattr_tree_set_last_eb_blk, .eo_get_last_eb_blk = ocfs2_xattr_tree_get_last_eb_blk, .eo_update_clusters = ocfs2_xattr_tree_update_clusters, @@ -379,7 +379,7 @@ static void ocfs2_dx_root_fill_root_el(struct ocfs2_extent_tree *et) et->et_root_el = &dx_root->dr_list; } -static struct ocfs2_extent_tree_operations ocfs2_dx_root_et_ops = { +static const struct ocfs2_extent_tree_operations ocfs2_dx_root_et_ops = { .eo_set_last_eb_blk = ocfs2_dx_root_set_last_eb_blk, .eo_get_last_eb_blk = ocfs2_dx_root_get_last_eb_blk, .eo_update_clusters = ocfs2_dx_root_update_clusters, @@ -425,7 +425,7 @@ ocfs2_refcount_tree_extent_contig(struct ocfs2_extent_tree *et, return CONTIG_NONE; } -static struct ocfs2_extent_tree_operations ocfs2_refcount_tree_et_ops = { +static const struct ocfs2_extent_tree_operations ocfs2_refcount_tree_et_ops = { .eo_set_last_eb_blk = ocfs2_refcount_tree_set_last_eb_blk, .eo_get_last_eb_blk = ocfs2_refcount_tree_get_last_eb_blk, .eo_update_clusters = ocfs2_refcount_tree_update_clusters, @@ -438,7 +438,7 @@ static void __ocfs2_init_extent_tree(struct ocfs2_extent_tree *et, struct buffer_head *bh, ocfs2_journal_access_func access, void *obj, - struct ocfs2_extent_tree_operations *ops) + const struct ocfs2_extent_tree_operations *ops) { et->et_ops = ops; et->et_root_bh = bh; diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index fb09b97db162d..f3dc1b0dfffc8 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h @@ -54,7 +54,7 @@ */ struct ocfs2_extent_tree_operations; struct ocfs2_extent_tree { - struct ocfs2_extent_tree_operations *et_ops; + const struct ocfs2_extent_tree_operations *et_ops; struct buffer_head *et_root_bh; struct ocfs2_extent_list *et_root_el; struct ocfs2_caching_info *et_ci; -- GitLab From b5560143385e18b4109ad6951c7719705e3dd995 Mon Sep 17 00:00:00 2001 From: jiangyiwen Date: Thu, 14 Jan 2016 15:17:23 -0800 Subject: [PATCH 2736/2855] ocfs2/dlm: wait until DLM_LOCK_RES_SETREF_INPROG is cleared in dlm_deref_lockres_worker Commit f3f854648de6 ("ocfs2_dlm: Ensure correct ordering of set/clear refmap bit on lockres") still exists a race which can't ensure the ordering is exactly correct. Node1 Node2 Node3 umount, migrate lockres to Node2 migrate finished, send migrate request to Node3 received migrate request, create a migration_mle, respond to Node2. set DLM_LOCK_RES_SETREF_INPROG and send assert master to Node3 delete migration_mle in assert_master_handler, Node3 umount without response dlm_thread purge this lockres, send drop deref message to Node2 found the flag of DLM_LOCK_RES_SETREF_INPROG is set, dispatch dlm_deref_lockres_worker to clear refmap, but in function of dlm_deref_lockres_worker, only if node in refmap it wait DLM_LOCK_RES_SETREF_INPROG to be cleared. So worker is done successfully purge lockres, send assert master response to Node1, and finish umount set Node3 in refmap, and it won't be cleared forever, thus lead to umount hung so wait until DLM_LOCK_RES_SETREF_INPROG is cleared in dlm_deref_lockres_worker. Signed-off-by: Yiwen Jiang Reviewed-by: Joseph Qi Reviewed-by: Junxiao Bi Cc: Mark Fasheh Cc: Joel Becker Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/dlm/dlmmaster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 84f2f8079466a..1fc172f898720 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -2388,8 +2388,8 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data) spin_lock(&res->spinlock); BUG_ON(res->state & DLM_LOCK_RES_DROPPING_REF); + __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG); if (test_bit(node, res->refmap)) { - __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG); dlm_lockres_clear_refmap_bit(dlm, res, node); cleared = 1; } -- GitLab From 72865d92300a6ad20a8851887aeac4f41fd2c579 Mon Sep 17 00:00:00 2001 From: Joseph Qi Date: Thu, 14 Jan 2016 15:17:27 -0800 Subject: [PATCH 2737/2855] ocfs2: clean up redundant NULL check before iput Since iput will take care the NULL check itself, NULL check before calling it is redundant. So clean them up. Signed-off-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/alloc.c | 3 +-- fs/ocfs2/ioctl.c | 4 +--- fs/ocfs2/journal.c | 10 +++------- fs/ocfs2/localalloc.c | 10 +++------- fs/ocfs2/namei.c | 3 +-- fs/ocfs2/slot_map.c | 3 +-- fs/ocfs2/super.c | 3 +-- 7 files changed, 11 insertions(+), 25 deletions(-) diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 2a0aeb77ec425..a3ded88718c93 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -6174,8 +6174,7 @@ int ocfs2_begin_truncate_log_recovery(struct ocfs2_super *osb, } bail: - if (tl_inode) - iput(tl_inode); + iput(tl_inode); brelse(tl_bh); if (status < 0) { diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c index 3cb097ccce607..16b0bb482ea7c 100644 --- a/fs/ocfs2/ioctl.c +++ b/fs/ocfs2/ioctl.c @@ -606,9 +606,7 @@ bail: if (gb_inode) mutex_unlock(&gb_inode->i_mutex); - if (gb_inode) - iput(gb_inode); - + iput(gb_inode); brelse(bh); return status; diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 13534f4fe5b51..3772a2dbb980c 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -1042,8 +1042,7 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb) // up_write(&journal->j_trans_barrier); done: - if (inode) - iput(inode); + iput(inode); } static void ocfs2_clear_journal_error(struct super_block *sb, @@ -1687,9 +1686,7 @@ done: if (got_lock) ocfs2_inode_unlock(inode, 1); - if (inode) - iput(inode); - + iput(inode); brelse(bh); return status; @@ -1796,8 +1793,7 @@ static int ocfs2_trylock_journal(struct ocfs2_super *osb, ocfs2_inode_unlock(inode, 1); bail: - if (inode) - iput(inode); + iput(inode); return status; } diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index 0a4457fb0711b..e9c99e35f5ea7 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c @@ -358,8 +358,7 @@ int ocfs2_load_local_alloc(struct ocfs2_super *osb) bail: if (status < 0) brelse(alloc_bh); - if (inode) - iput(inode); + iput(inode); trace_ocfs2_load_local_alloc(osb->local_alloc_bits); @@ -473,8 +472,7 @@ out_mutex: iput(main_bm_inode); out: - if (local_alloc_inode) - iput(local_alloc_inode); + iput(local_alloc_inode); kfree(alloc_copy); } @@ -1327,9 +1325,7 @@ bail: brelse(main_bm_bh); - if (main_bm_inode) - iput(main_bm_inode); - + iput(main_bm_inode); kfree(alloc_copy); if (ac) diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index afb81eae2c187..714320e420eb4 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -1683,8 +1683,7 @@ bail: if (new_inode) sync_mapping_buffers(old_inode->i_mapping); - if (new_inode) - iput(new_inode); + iput(new_inode); ocfs2_free_dir_lookup_result(&target_lookup_res); ocfs2_free_dir_lookup_result(&old_entry_lookup); diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c index e78a203d44c83..47bba1be2a51f 100644 --- a/fs/ocfs2/slot_map.c +++ b/fs/ocfs2/slot_map.c @@ -322,8 +322,7 @@ static void __ocfs2_free_slot_info(struct ocfs2_slot_info *si) if (si == NULL) return; - if (si->si_inode) - iput(si->si_inode); + iput(si->si_inode); if (si->si_bh) { for (i = 0; i < si->si_blocks; i++) { if (si->si_bh[i]) { diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 64dcd787fa804..c62d761d6bf01 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -1722,8 +1722,7 @@ static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf) ocfs2_inode_unlock(inode, 0); status = 0; bail: - if (inode) - iput(inode); + iput(inode); if (status) mlog_errno(status); -- GitLab From c372f2193a2e73d5936bf37259ae63ca388b4cbc Mon Sep 17 00:00:00 2001 From: Xue jiufei Date: Thu, 14 Jan 2016 15:17:29 -0800 Subject: [PATCH 2738/2855] ocfs2/dlm: return appropriate value when dlm_grab() returns NULL dlm_grab() may return NULL when the node is doing unmount. When doing code review, we found that some dlm handlers may return error to caller when dlm_grab() returns NULL and make caller BUG or other problems. Here is an example: Node 1 Node 2 receives migration message from node 3, and send migrate request to others start unmounting receives migrate request from node 1 and call dlm_migrate_request_handler() unmount thread unregisters domain handlers and removes dlm_context from dlm_domains dlm_migrate_request_handlers() returns -EINVAL to node 1 Exit migration neither clearing the migration state nor sending assert master message to node 3 which cause node 3 hung. Signed-off-by: Jiufei Xue Reviewed-by: Joseph Qi Reviewed-by: Yiwen Jiang Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/dlm/dlmmaster.c | 2 +- fs/ocfs2/dlm/dlmunlock.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 1fc172f898720..6f07481221176 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -3050,7 +3050,7 @@ int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data, int ret = 0; if (!dlm_grab(dlm)) - return -EINVAL; + return 0; name = migrate->name; namelen = migrate->namelen; diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c index 2e3c9dbab68c9..1082b2c3014be 100644 --- a/fs/ocfs2/dlm/dlmunlock.c +++ b/fs/ocfs2/dlm/dlmunlock.c @@ -421,7 +421,7 @@ int dlm_unlock_lock_handler(struct o2net_msg *msg, u32 len, void *data, } if (!dlm_grab(dlm)) - return DLM_REJECTED; + return DLM_FORWARD; mlog_bug_on_msg(!dlm_domain_fully_joined(dlm), "Domain %s not fully joined!\n", dlm->name); -- GitLab From 1247017f43a93eae3d64b7c25f3637dc545f5a47 Mon Sep 17 00:00:00 2001 From: jiangyiwen Date: Thu, 14 Jan 2016 15:17:33 -0800 Subject: [PATCH 2739/2855] ocfs2: fix slot overwritten if storage link down during mount The following case will lead to slot overwritten. N1 N2 mount ocfs2 volume, find and allocate slot 0, then set osb->slot_num to 0, begin to write slot info to disk mount ocfs2 volume, wait for super lock write block fail because of storage link down, unlock super lock got super lock and also allocate slot 0 then unlock super lock mount fail and then dismount, since osb->slot_num is 0, try to put invalid slot to disk. And it will succeed if storage link restores. N2 slot info is now overwritten Once another node say N3 mount, it will find and allocate slot 0 again, which will lead to mount hung because journal has already been locked by N2. so when write slot info failed, invalidate slot in advance to avoid overwrite slot. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Yiwen Jiang Reviewed-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/slot_map.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c index 47bba1be2a51f..1e09592148ad2 100644 --- a/fs/ocfs2/slot_map.c +++ b/fs/ocfs2/slot_map.c @@ -502,8 +502,17 @@ int ocfs2_find_slot(struct ocfs2_super *osb) trace_ocfs2_find_slot(osb->slot_num); status = ocfs2_update_disk_slot(osb, si, osb->slot_num); - if (status < 0) + if (status < 0) { mlog_errno(status); + /* + * if write block failed, invalidate slot to avoid overwrite + * slot during dismount in case another node rightly has mounted + */ + spin_lock(&osb->osb_lock); + ocfs2_invalidate_slot(si, osb->slot_num); + osb->slot_num = OCFS2_INVALID_SLOT; + spin_unlock(&osb->osb_lock); + } bail: return status; -- GitLab From 1cce4df04f37d3f7b969e85528fa54f918a06f03 Mon Sep 17 00:00:00 2001 From: Goldwyn Rodrigues Date: Thu, 14 Jan 2016 15:17:35 -0800 Subject: [PATCH 2740/2855] ocfs2: do not lock/unlock() inode DLM lock DLM does not cache locks. So, blocking lock and unlock will only make the performance worse where contention over the locks is high. Signed-off-by: Goldwyn Rodrigues Cc: Mark Fasheh Cc: Joel Becker Reviewed-by: Junxiao Bi Cc: Joseph Qi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/dlmglue.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 20276e340339b..f92612e4b9d61 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -2432,12 +2432,6 @@ bail: * done this we have to return AOP_TRUNCATED_PAGE so the aop method * that called us can bubble that back up into the VFS who will then * immediately retry the aop call. - * - * We do a blocking lock and immediate unlock before returning, though, so that - * the lock has a great chance of being cached on this node by the time the VFS - * calls back to retry the aop. This has a potential to livelock as nodes - * ping locks back and forth, but that's a risk we're willing to take to avoid - * the lock inversion simply. */ int ocfs2_inode_lock_with_page(struct inode *inode, struct buffer_head **ret_bh, @@ -2449,8 +2443,6 @@ int ocfs2_inode_lock_with_page(struct inode *inode, ret = ocfs2_inode_lock_full(inode, ret_bh, ex, OCFS2_LOCK_NONBLOCK); if (ret == -EAGAIN) { unlock_page(page); - if (ocfs2_inode_lock(inode, ret_bh, ex) == 0) - ocfs2_inode_unlock(inode, ex); ret = AOP_TRUNCATED_PAGE; } -- GitLab From bef5502de074b6f6fa647b94b73155d675694420 Mon Sep 17 00:00:00 2001 From: xuejiufei Date: Thu, 14 Jan 2016 15:17:38 -0800 Subject: [PATCH 2741/2855] ocfs2/dlm: ignore cleaning the migration mle that is inuse We have found that migration source will trigger a BUG that the refcount of mle is already zero before put when the target is down during migration. The situation is as follows: dlm_migrate_lockres dlm_add_migration_mle dlm_mark_lockres_migrating dlm_get_mle_inuse <<<<<< Now the refcount of the mle is 2. dlm_send_one_lockres and wait for the target to become the new master. <<<<<< o2hb detect the target down and clean the migration mle. Now the refcount is 1. dlm_migrate_lockres woken, and put the mle twice when found the target goes down which trigger the BUG with the following message: "ERROR: bad mle: ". Signed-off-by: Jiufei Xue Reviewed-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/dlm/dlmmaster.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 6f07481221176..8b9d483e94a68 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -2519,6 +2519,11 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm, spin_lock(&dlm->master_lock); ret = dlm_add_migration_mle(dlm, res, mle, &oldmle, name, namelen, target, dlm->node_num); + /* get an extra reference on the mle. + * otherwise the assert_master from the new + * master will destroy this. + */ + dlm_get_mle_inuse(mle); spin_unlock(&dlm->master_lock); spin_unlock(&dlm->spinlock); @@ -2554,6 +2559,7 @@ fail: if (mle_added) { dlm_mle_detach_hb_events(dlm, mle); dlm_put_mle(mle); + dlm_put_mle_inuse(mle); } else if (mle) { kmem_cache_free(dlm_mle_cache, mle); mle = NULL; @@ -2571,17 +2577,6 @@ fail: * ensure that all assert_master work is flushed. */ flush_workqueue(dlm->dlm_worker); - /* get an extra reference on the mle. - * otherwise the assert_master from the new - * master will destroy this. - * also, make sure that all callers of dlm_get_mle - * take both dlm->spinlock and dlm->master_lock */ - spin_lock(&dlm->spinlock); - spin_lock(&dlm->master_lock); - dlm_get_mle_inuse(mle); - spin_unlock(&dlm->master_lock); - spin_unlock(&dlm->spinlock); - /* notify new node and send all lock state */ /* call send_one_lockres with migration flag. * this serves as notice to the target node that a @@ -3312,6 +3307,15 @@ top: mle->new_master != dead_node) continue; + if (mle->new_master == dead_node && mle->inuse) { + mlog(ML_NOTICE, "%s: target %u died during " + "migration from %u, the MLE is " + "still keep used, ignore it!\n", + dlm->name, dead_node, + mle->master); + continue; + } + /* If we have reached this point, this mle needs to be * removed from the list and freed. */ dlm_clean_migration_mle(dlm, mle); -- GitLab From 32e493265b2be96404aaa478fb2913be29b06887 Mon Sep 17 00:00:00 2001 From: xuejiufei Date: Thu, 14 Jan 2016 15:17:41 -0800 Subject: [PATCH 2742/2855] ocfs2/dlm: do not insert a new mle when another process is already migrating When two processes are migrating the same lockres, dlm_add_migration_mle() return -EEXIST, but insert a new mle in hash list. dlm_migrate_lockres() will detach the old mle and free the new one which is already in hash list, that will destroy the list. Signed-off-by: Jiufei Xue Reviewed-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Reviewed-by: Junxiao Bi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/dlm/dlmmaster.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 8b9d483e94a68..9477d6e1de372 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -2549,7 +2549,7 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm, } fail: - if (oldmle) { + if (ret != -EEXIST && oldmle) { /* master is known, detach if not already detached */ dlm_mle_detach_hb_events(dlm, oldmle); dlm_put_mle(oldmle); @@ -3136,7 +3136,8 @@ static int dlm_add_migration_mle(struct dlm_ctxt *dlm, mlog(0, "tried to migrate %.*s, but some " "process beat me to it\n", namelen, name); - ret = -EEXIST; + spin_unlock(&tmp->spinlock); + return -EEXIST; } else { /* bad. 2 NODES are trying to migrate! */ mlog(ML_ERROR, "migration error mle: " -- GitLab From 074a6c655f6da12cb1123c8a84bfd8d781138800 Mon Sep 17 00:00:00 2001 From: Joseph Qi Date: Thu, 14 Jan 2016 15:17:44 -0800 Subject: [PATCH 2743/2855] ocfs2: access orphan dinode before delete entry in ocfs2_orphan_del In ocfs2_orphan_del, currently it finds and deletes entry first, and then access orphan dir dinode. This will have a problem once ocfs2_journal_access_di fails. In this case, entry will be removed from orphan dir, but in deed the inode hasn't been deleted successfully. In other words, the file is missing but not actually deleted. So we should access orphan dinode first like unlink and rename. Signed-off-by: Joseph Qi Reviewed-by: Jiufei Xue Cc: Mark Fasheh Cc: Joel Becker Reviewed-by: Junxiao Bi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/namei.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 714320e420eb4..ab42c38031b17 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -2372,6 +2372,15 @@ int ocfs2_orphan_del(struct ocfs2_super *osb, (unsigned long long)OCFS2_I(orphan_dir_inode)->ip_blkno, name, strlen(name)); + status = ocfs2_journal_access_di(handle, + INODE_CACHE(orphan_dir_inode), + orphan_dir_bh, + OCFS2_JOURNAL_ACCESS_WRITE); + if (status < 0) { + mlog_errno(status); + goto leave; + } + /* find it's spot in the orphan directory */ status = ocfs2_find_entry(name, strlen(name), orphan_dir_inode, &lookup); @@ -2387,15 +2396,6 @@ int ocfs2_orphan_del(struct ocfs2_super *osb, goto leave; } - status = ocfs2_journal_access_di(handle, - INODE_CACHE(orphan_dir_inode), - orphan_dir_bh, - OCFS2_JOURNAL_ACCESS_WRITE); - if (status < 0) { - mlog_errno(status); - goto leave; - } - /* do the i_nlink dance! :) */ orphan_fe = (struct ocfs2_dinode *) orphan_dir_bh->b_data; if (S_ISDIR(inode->i_mode)) -- GitLab From 98e141f266040fea0864c23f1f37375cae5ff02a Mon Sep 17 00:00:00 2001 From: Junxiao Bi Date: Thu, 14 Jan 2016 15:17:47 -0800 Subject: [PATCH 2744/2855] ocfs2: dlm: remove redundant code Found this when do patch review, remove to make it clear and save a little cpu time. Signed-off-by: Junxiao Bi Cc: Mark Fasheh Cc: Joel Becker Cc: Joseph Qi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/dlm/dlmrecovery.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 86fb53614bf4f..c5bdf02c213bd 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c @@ -2457,11 +2457,7 @@ static void __dlm_hb_node_down(struct dlm_ctxt *dlm, int idx) * perhaps later we can genericize this for other waiters. */ wake_up(&dlm->migration_wq); - if (test_bit(idx, dlm->recovery_map)) - mlog(0, "domain %s, node %u already added " - "to recovery map!\n", dlm->name, idx); - else - set_bit(idx, dlm->recovery_map); + set_bit(idx, dlm->recovery_map); } void dlm_hb_node_down_cb(struct o2nm_node *node, int idx, void *data) -- GitLab From 3c973b0e71bff472545a2939ede2b567745d0c1c Mon Sep 17 00:00:00 2001 From: Joseph Qi Date: Thu, 14 Jan 2016 15:17:50 -0800 Subject: [PATCH 2745/2855] ocfs2/dlm: cleanup redunant lksb flags in dlmcommon.h lksb flags are defined both in dlmapi.h and dlmcommon.h. So clean them up from dlmcommon.h. Signed-off-by: Joseph Qi Reviewed-by: Jiufei Xue Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/dlm/dlmcommon.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index e88ccf8c83fff..68c607e63ff68 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h @@ -376,17 +376,6 @@ struct dlm_lock lksb_kernel_allocated:1; }; - -#define DLM_LKSB_UNUSED1 0x01 -#define DLM_LKSB_PUT_LVB 0x02 -#define DLM_LKSB_GET_LVB 0x04 -#define DLM_LKSB_UNUSED2 0x08 -#define DLM_LKSB_UNUSED3 0x10 -#define DLM_LKSB_UNUSED4 0x20 -#define DLM_LKSB_UNUSED5 0x40 -#define DLM_LKSB_UNUSED6 0x80 - - enum dlm_lockres_list { DLM_GRANTED_LIST = 0, DLM_CONVERTING_LIST = 1, -- GitLab From 2bd03e49d66775da8cebdcc8d5bec7d68512ae87 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 14 Jan 2016 15:17:53 -0800 Subject: [PATCH 2746/2855] include/linux/dcache.h: remove semicolons from HASH_LEN_DECLARE A little cleanup - the invocation site provdes the semicolon. Cc: Rasmus Villemoes Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/dcache.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/dcache.h b/include/linux/dcache.h index d67ae119cf4eb..7781ce1105035 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -27,10 +27,10 @@ struct vfsmount; /* The hash is always the low bits of hash_len */ #ifdef __LITTLE_ENDIAN - #define HASH_LEN_DECLARE u32 hash; u32 len; + #define HASH_LEN_DECLARE u32 hash; u32 len #define bytemask_from_count(cnt) (~(~0ul << (cnt)*8)) #else - #define HASH_LEN_DECLARE u32 len; u32 hash; + #define HASH_LEN_DECLARE u32 len; u32 hash #define bytemask_from_count(cnt) (~(~0ul >> (cnt)*8)) #endif -- GitLab From d8ad47d83f95abe2dfece1338633e376fec3bd31 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 14 Jan 2016 15:17:56 -0800 Subject: [PATCH 2747/2855] mm/slab.c use list_first_entry_or_null() Simplify the code with list_first_entry_or_null(). Signed-off-by: Geliang Tang Acked-by: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index 4765c97ce6900..6bb0466494506 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -2791,18 +2791,18 @@ retry: } while (batchcount > 0) { - struct list_head *entry; struct page *page; /* Get slab alloc is to come from. */ - entry = n->slabs_partial.next; - if (entry == &n->slabs_partial) { + page = list_first_entry_or_null(&n->slabs_partial, + struct page, lru); + if (!page) { n->free_touched = 1; - entry = n->slabs_free.next; - if (entry == &n->slabs_free) + page = list_first_entry_or_null(&n->slabs_free, + struct page, lru); + if (!page) goto must_grow; } - page = list_entry(entry, struct page, lru); check_spinlock_acquired(cachep); /* @@ -3085,7 +3085,6 @@ retry: static void *____cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid) { - struct list_head *entry; struct page *page; struct kmem_cache_node *n; void *obj; @@ -3098,15 +3097,16 @@ static void *____cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, retry: check_irq_off(); spin_lock(&n->list_lock); - entry = n->slabs_partial.next; - if (entry == &n->slabs_partial) { + page = list_first_entry_or_null(&n->slabs_partial, + struct page, lru); + if (!page) { n->free_touched = 1; - entry = n->slabs_free.next; - if (entry == &n->slabs_free) + page = list_first_entry_or_null(&n->slabs_free, + struct page, lru); + if (!page) goto must_grow; } - page = list_entry(entry, struct page, lru); check_spinlock_acquired_node(cachep, nodeid); STATS_INC_NODEALLOCS(cachep); -- GitLab From 73c0219d8eca4114d81626032055598bc0a17130 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 14 Jan 2016 15:17:59 -0800 Subject: [PATCH 2748/2855] mm/slab.c: use list_for_each_entry in cache_flusharray Simplify the code with list_for_each_entry(). Signed-off-by: Geliang Tang Acked-by: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index 6bb0466494506..5d5aa3bbdc3f5 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -3338,17 +3338,12 @@ free_done: #if STATS { int i = 0; - struct list_head *p; - - p = n->slabs_free.next; - while (p != &(n->slabs_free)) { - struct page *page; + struct page *page; - page = list_entry(p, struct page, lru); + list_for_each_entry(page, &n->slabs_free, lru) { BUG_ON(page->active); i++; - p = p->next; } STATS_SET_FREEABLE(cachep, i); } -- GitLab From 7aa0d22785deea2725a23716823edd96e65c2ff6 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 14 Jan 2016 15:18:02 -0800 Subject: [PATCH 2749/2855] mm/slab.c: add a helper function get_first_slab Add a new helper function get_first_slab() that get the first slab from a kmem_cache_node. Signed-off-by: Geliang Tang Acked-by: Christoph Lameter Acked-by: David Rientjes Cc: Pekka Enberg Cc: Joonsoo Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index 5d5aa3bbdc3f5..6ecc697a8bc46 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -2756,6 +2756,21 @@ static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp, #define cache_free_debugcheck(x,objp,z) (objp) #endif +static struct page *get_first_slab(struct kmem_cache_node *n) +{ + struct page *page; + + page = list_first_entry_or_null(&n->slabs_partial, + struct page, lru); + if (!page) { + n->free_touched = 1; + page = list_first_entry_or_null(&n->slabs_free, + struct page, lru); + } + + return page; +} + static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags, bool force_refill) { @@ -2793,15 +2808,9 @@ retry: while (batchcount > 0) { struct page *page; /* Get slab alloc is to come from. */ - page = list_first_entry_or_null(&n->slabs_partial, - struct page, lru); - if (!page) { - n->free_touched = 1; - page = list_first_entry_or_null(&n->slabs_free, - struct page, lru); - if (!page) - goto must_grow; - } + page = get_first_slab(n); + if (!page) + goto must_grow; check_spinlock_acquired(cachep); @@ -3097,15 +3106,9 @@ static void *____cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, retry: check_irq_off(); spin_lock(&n->list_lock); - page = list_first_entry_or_null(&n->slabs_partial, - struct page, lru); - if (!page) { - n->free_touched = 1; - page = list_first_entry_or_null(&n->slabs_free, - struct page, lru); - if (!page) - goto must_grow; - } + page = get_first_slab(n); + if (!page) + goto must_grow; check_spinlock_acquired_node(cachep, nodeid); -- GitLab From b2a209ffa605994cbe3c259c8584ba1576d3310c Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Thu, 14 Jan 2016 15:18:05 -0800 Subject: [PATCH 2750/2855] Revert "kernfs: do not account ino_ida allocations to memcg" Currently, all kmem allocations (namely every kmem_cache_alloc, kmalloc, alloc_kmem_pages call) are accounted to memory cgroup automatically. Callers have to explicitly opt out if they don't want/need accounting for some reason. Such a design decision leads to several problems: - kmalloc users are highly sensitive to failures, many of them implicitly rely on the fact that kmalloc never fails, while memcg makes failures quite plausible. - A lot of objects are shared among different containers by design. Accounting such objects to one of containers is just unfair. Moreover, it might lead to pinning a dead memcg along with its kmem caches, which aren't tiny, which might result in noticeable increase in memory consumption for no apparent reason in the long run. - There are tons of short-lived objects. Accounting them to memcg will only result in slight noise and won't change the overall picture, but we still have to pay accounting overhead. For more info, see - http://lkml.kernel.org/r/20151105144002.GB15111%40dhcp22.suse.cz - http://lkml.kernel.org/r/20151106090555.GK29259@esperanza Therefore this patchset switches to the white list policy. Now kmalloc users have to explicitly opt in by passing __GFP_ACCOUNT flag. Currently, the list of accounted objects is quite limited and only includes those allocations that (1) are known to be easily triggered from userspace and (2) can fail gracefully (for the full list see patch no. 6) and it still misses many object types. However, accounting only those objects should be a satisfactory approximation of the behavior we used to have for most sane workloads. This patch (of 6): Revert 499611ed451508a42d1d7d ("kernfs: do not account ino_ida allocations to memcg"). Black-list kmem accounting policy (aka __GFP_NOACCOUNT) turned out to be fragile and difficult to maintain, because there seem to be many more allocations that should not be accounted than those that should be. Besides, false accounting an allocation might result in much worse consequences than not accounting at all, namely increased memory consumption due to pinned dead kmem caches. So it was decided to switch to the white-list policy. This patch reverts bits introducing the black-list policy. The white-list policy will be introduced later in the series. Signed-off-by: Vladimir Davydov Acked-by: Johannes Weiner Cc: Michal Hocko Cc: Tejun Heo Cc: Greg Thelen Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/kernfs/dir.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 742bf4a230e83..821973853340a 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -541,14 +541,7 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, if (!kn) goto err_out1; - /* - * If the ino of the sysfs entry created for a kmem cache gets - * allocated from an ida layer, which is accounted to the memcg that - * owns the cache, the memcg will get pinned forever. So do not account - * ino ida allocations. - */ - ret = ida_simple_get(&root->ino_ida, 1, 0, - GFP_KERNEL | __GFP_NOACCOUNT); + ret = ida_simple_get(&root->ino_ida, 1, 0, GFP_KERNEL); if (ret < 0) goto err_out2; kn->ino = ret; -- GitLab From 20b5c30398639b458371c228abfda829854b61c5 Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Thu, 14 Jan 2016 15:18:08 -0800 Subject: [PATCH 2751/2855] Revert "gfp: add __GFP_NOACCOUNT" This reverts commit 8f4fc071b192 ("gfp: add __GFP_NOACCOUNT"). Black-list kmem accounting policy (aka __GFP_NOACCOUNT) turned out to be fragile and difficult to maintain, because there seem to be many more allocations that should not be accounted than those that should be. Besides, false accounting an allocation might result in much worse consequences than not accounting at all, namely increased memory consumption due to pinned dead kmem caches. So it was decided to switch to the white-list policy. This patch reverts bits introducing the black-list policy. The white-list policy will be introduced later in the series. Signed-off-by: Vladimir Davydov Acked-by: Johannes Weiner Cc: Michal Hocko Cc: Tejun Heo Cc: Greg Thelen Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/gfp.h | 2 -- include/linux/memcontrol.h | 2 -- mm/kmemleak.c | 3 +-- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 8942af0813e38..075b014448f56 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -30,7 +30,6 @@ struct vm_area_struct; #define ___GFP_HARDWALL 0x20000u #define ___GFP_THISNODE 0x40000u #define ___GFP_ATOMIC 0x80000u -#define ___GFP_NOACCOUNT 0x100000u #define ___GFP_NOTRACK 0x200000u #define ___GFP_DIRECT_RECLAIM 0x400000u #define ___GFP_OTHER_NODE 0x800000u @@ -104,7 +103,6 @@ struct vm_area_struct; #define __GFP_HIGH ((__force gfp_t)___GFP_HIGH) #define __GFP_MEMALLOC ((__force gfp_t)___GFP_MEMALLOC) #define __GFP_NOMEMALLOC ((__force gfp_t)___GFP_NOMEMALLOC) -#define __GFP_NOACCOUNT ((__force gfp_t)___GFP_NOACCOUNT) /* * Reclaim modifiers diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index cd0e2413c358d..2103f36b3bd38 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -773,8 +773,6 @@ static inline bool __memcg_kmem_bypass(gfp_t gfp) { if (!memcg_kmem_enabled()) return true; - if (gfp & __GFP_NOACCOUNT) - return true; if (in_interrupt() || (!current->mm) || (current->flags & PF_KTHREAD)) return true; return false; diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 19423a45d7d7d..25c0ad36fe380 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -122,8 +122,7 @@ #define BYTES_PER_POINTER sizeof(void *) /* GFP bitmask for kmemleak internal allocations */ -#define gfp_kmemleak_mask(gfp) (((gfp) & (GFP_KERNEL | GFP_ATOMIC | \ - __GFP_NOACCOUNT)) | \ +#define gfp_kmemleak_mask(gfp) (((gfp) & (GFP_KERNEL | GFP_ATOMIC)) | \ __GFP_NORETRY | __GFP_NOMEMALLOC | \ __GFP_NOWARN) -- GitLab From a9bb7e620efdfd29b6d1c238041173e411670996 Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Thu, 14 Jan 2016 15:18:12 -0800 Subject: [PATCH 2752/2855] memcg: only account kmem allocations marked as __GFP_ACCOUNT Black-list kmem accounting policy (aka __GFP_NOACCOUNT) turned out to be fragile and difficult to maintain, because there seem to be many more allocations that should not be accounted than those that should be. Besides, false accounting an allocation might result in much worse consequences than not accounting at all, namely increased memory consumption due to pinned dead kmem caches. So this patch switches kmem accounting to the white-policy: now only those kmem allocations that are marked as __GFP_ACCOUNT are accounted to memcg. Currently, no kmem allocations are marked like this. The following patches will mark several kmem allocations that are known to be easily triggered from userspace and therefore should be accounted to memcg. Signed-off-by: Vladimir Davydov Acked-by: Johannes Weiner Acked-by: Michal Hocko Cc: Tejun Heo Cc: Greg Thelen Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/gfp.h | 9 +++++++++ include/linux/memcontrol.h | 2 ++ mm/page_alloc.c | 3 ++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 075b014448f56..1dd59abe541d2 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -30,6 +30,7 @@ struct vm_area_struct; #define ___GFP_HARDWALL 0x20000u #define ___GFP_THISNODE 0x40000u #define ___GFP_ATOMIC 0x80000u +#define ___GFP_ACCOUNT 0x100000u #define ___GFP_NOTRACK 0x200000u #define ___GFP_DIRECT_RECLAIM 0x400000u #define ___GFP_OTHER_NODE 0x800000u @@ -72,11 +73,15 @@ struct vm_area_struct; * * __GFP_THISNODE forces the allocation to be satisified from the requested * node with no fallbacks or placement policy enforcements. + * + * __GFP_ACCOUNT causes the allocation to be accounted to kmemcg (only relevant + * to kmem allocations). */ #define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) #define __GFP_WRITE ((__force gfp_t)___GFP_WRITE) #define __GFP_HARDWALL ((__force gfp_t)___GFP_HARDWALL) #define __GFP_THISNODE ((__force gfp_t)___GFP_THISNODE) +#define __GFP_ACCOUNT ((__force gfp_t)___GFP_ACCOUNT) /* * Watermark modifiers -- controls access to emergency reserves @@ -195,6 +200,9 @@ struct vm_area_struct; * GFP_KERNEL is typical for kernel-internal allocations. The caller requires * ZONE_NORMAL or a lower zone for direct access but can direct reclaim. * + * GFP_KERNEL_ACCOUNT is the same as GFP_KERNEL, except the allocation is + * accounted to kmemcg. + * * GFP_NOWAIT is for kernel allocations that should not stall for direct * reclaim, start physical IO or use any filesystem callback. * @@ -234,6 +242,7 @@ struct vm_area_struct; */ #define GFP_ATOMIC (__GFP_HIGH|__GFP_ATOMIC|__GFP_KSWAPD_RECLAIM) #define GFP_KERNEL (__GFP_RECLAIM | __GFP_IO | __GFP_FS) +#define GFP_KERNEL_ACCOUNT (GFP_KERNEL | __GFP_ACCOUNT) #define GFP_NOWAIT (__GFP_KSWAPD_RECLAIM) #define GFP_NOIO (__GFP_RECLAIM) #define GFP_NOFS (__GFP_RECLAIM | __GFP_IO) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 2103f36b3bd38..c9d9a8e7b45f7 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -773,6 +773,8 @@ static inline bool __memcg_kmem_bypass(gfp_t gfp) { if (!memcg_kmem_enabled()) return true; + if (!(gfp & __GFP_ACCOUNT)) + return true; if (in_interrupt() || (!current->mm) || (current->flags & PF_KTHREAD)) return true; return false; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 9d666df5ef950..ca58bfcdadac9 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -3402,7 +3402,8 @@ EXPORT_SYMBOL(__free_page_frag); /* * alloc_kmem_pages charges newly allocated pages to the kmem resource counter - * of the current memory cgroup. + * of the current memory cgroup if __GFP_ACCOUNT is set, other than that it is + * equivalent to alloc_pages. * * It should be used when the caller would like to use kmalloc, but since the * allocation is large, it has to fall back to the page allocator. -- GitLab From 230e9fc2860450fbb1f33bdcf9093d92d7d91f5b Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Thu, 14 Jan 2016 15:18:15 -0800 Subject: [PATCH 2753/2855] slab: add SLAB_ACCOUNT flag Currently, if we want to account all objects of a particular kmem cache, we have to pass __GFP_ACCOUNT to each kmem_cache_alloc call, which is inconvenient. This patch introduces SLAB_ACCOUNT flag which if passed to kmem_cache_create will force accounting for every allocation from this cache even if __GFP_ACCOUNT is not passed. This patch does not make any of the existing caches use this flag - it will be done later in the series. Note, a cache with SLAB_ACCOUNT cannot be merged with a cache w/o SLAB_ACCOUNT, because merged caches share the same kmem_cache struct and hence cannot have different sets of SLAB_* flags. Thus using this flag will probably reduce the number of merged slabs even if kmem accounting is not used (only compiled in). Signed-off-by: Vladimir Davydov Suggested-by: Tejun Heo Acked-by: Johannes Weiner Acked-by: Michal Hocko Cc: Greg Thelen Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 15 +++++++-------- include/linux/slab.h | 5 +++++ mm/memcontrol.c | 8 +++++++- mm/slab.h | 5 +++-- mm/slab_common.c | 3 ++- mm/slub.c | 2 ++ 6 files changed, 26 insertions(+), 12 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index c9d9a8e7b45f7..5c97265c1c6e8 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -766,15 +766,13 @@ static inline int memcg_cache_id(struct mem_cgroup *memcg) return memcg ? memcg->kmemcg_id : -1; } -struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep); +struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp); void __memcg_kmem_put_cache(struct kmem_cache *cachep); -static inline bool __memcg_kmem_bypass(gfp_t gfp) +static inline bool __memcg_kmem_bypass(void) { if (!memcg_kmem_enabled()) return true; - if (!(gfp & __GFP_ACCOUNT)) - return true; if (in_interrupt() || (!current->mm) || (current->flags & PF_KTHREAD)) return true; return false; @@ -791,7 +789,9 @@ static inline bool __memcg_kmem_bypass(gfp_t gfp) static __always_inline int memcg_kmem_charge(struct page *page, gfp_t gfp, int order) { - if (__memcg_kmem_bypass(gfp)) + if (__memcg_kmem_bypass()) + return 0; + if (!(gfp & __GFP_ACCOUNT)) return 0; return __memcg_kmem_charge(page, gfp, order); } @@ -810,16 +810,15 @@ static __always_inline void memcg_kmem_uncharge(struct page *page, int order) /** * memcg_kmem_get_cache: selects the correct per-memcg cache for allocation * @cachep: the original global kmem cache - * @gfp: allocation flags. * * All memory allocated from a per-memcg cache is charged to the owner memcg. */ static __always_inline struct kmem_cache * memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp) { - if (__memcg_kmem_bypass(gfp)) + if (__memcg_kmem_bypass()) return cachep; - return __memcg_kmem_get_cache(cachep); + return __memcg_kmem_get_cache(cachep, gfp); } static __always_inline void memcg_kmem_put_cache(struct kmem_cache *cachep) diff --git a/include/linux/slab.h b/include/linux/slab.h index 2037a861e3679..3ffee74220126 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -86,6 +86,11 @@ #else # define SLAB_FAILSLAB 0x00000000UL #endif +#ifdef CONFIG_MEMCG_KMEM +# define SLAB_ACCOUNT 0x04000000UL /* Account to memcg */ +#else +# define SLAB_ACCOUNT 0x00000000UL +#endif /* The following flags affect the page allocator grouping pages by mobility */ #define SLAB_RECLAIM_ACCOUNT 0x00020000UL /* Objects are reclaimable */ diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 14cb1db4c52b7..4bd6c45133931 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -2356,7 +2356,7 @@ static void memcg_schedule_kmem_cache_create(struct mem_cgroup *memcg, * Can't be called in interrupt context or from kernel threads. * This function needs to be called with rcu_read_lock() held. */ -struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep) +struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp) { struct mem_cgroup *memcg; struct kmem_cache *memcg_cachep; @@ -2364,6 +2364,12 @@ struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep) VM_BUG_ON(!is_root_cache(cachep)); + if (cachep->flags & SLAB_ACCOUNT) + gfp |= __GFP_ACCOUNT; + + if (!(gfp & __GFP_ACCOUNT)) + return cachep; + if (current->memcg_kmem_skip_account) return cachep; diff --git a/mm/slab.h b/mm/slab.h index 7b60871979976..c63b8699cfa3d 100644 --- a/mm/slab.h +++ b/mm/slab.h @@ -128,10 +128,11 @@ static inline unsigned long kmem_cache_flags(unsigned long object_size, #if defined(CONFIG_SLAB) #define SLAB_CACHE_FLAGS (SLAB_MEM_SPREAD | SLAB_NOLEAKTRACE | \ - SLAB_RECLAIM_ACCOUNT | SLAB_TEMPORARY | SLAB_NOTRACK) + SLAB_RECLAIM_ACCOUNT | SLAB_TEMPORARY | \ + SLAB_NOTRACK | SLAB_ACCOUNT) #elif defined(CONFIG_SLUB) #define SLAB_CACHE_FLAGS (SLAB_NOLEAKTRACE | SLAB_RECLAIM_ACCOUNT | \ - SLAB_TEMPORARY | SLAB_NOTRACK) + SLAB_TEMPORARY | SLAB_NOTRACK | SLAB_ACCOUNT) #else #define SLAB_CACHE_FLAGS (0) #endif diff --git a/mm/slab_common.c b/mm/slab_common.c index 3c6a86b4ec25f..e016178063e19 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -37,7 +37,8 @@ struct kmem_cache *kmem_cache; SLAB_TRACE | SLAB_DESTROY_BY_RCU | SLAB_NOLEAKTRACE | \ SLAB_FAILSLAB) -#define SLAB_MERGE_SAME (SLAB_RECLAIM_ACCOUNT | SLAB_CACHE_DMA | SLAB_NOTRACK) +#define SLAB_MERGE_SAME (SLAB_RECLAIM_ACCOUNT | SLAB_CACHE_DMA | \ + SLAB_NOTRACK | SLAB_ACCOUNT) /* * Merge control. If this is set then no merging of slab caches will occur. diff --git a/mm/slub.c b/mm/slub.c index 46997517406ed..2d0e610d195ae 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -5362,6 +5362,8 @@ static char *create_unique_id(struct kmem_cache *s) *p++ = 'F'; if (!(s->flags & SLAB_NOTRACK)) *p++ = 't'; + if (s->flags & SLAB_ACCOUNT) + *p++ = 'A'; if (p != name + 1) *p++ = '-'; p += sprintf(p, "%07d", s->size); -- GitLab From 37f08dda29dac8a595999b8d3eaa9bf0f763dd9d Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Thu, 14 Jan 2016 15:18:18 -0800 Subject: [PATCH 2754/2855] vmalloc: allow to account vmalloc to memcg Make vmalloc family functions allocate vmalloc area pages with alloc_kmem_pages so that if __GFP_ACCOUNT is set they will be accounted to memcg. This is needed, at least, to account alloc_fdmem allocations. Signed-off-by: Vladimir Davydov Acked-by: Johannes Weiner Cc: Michal Hocko Cc: Tejun Heo Cc: Greg Thelen Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmalloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 8e3c9c5a3042b..9a58f9a1874df 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1477,7 +1477,7 @@ static void __vunmap(const void *addr, int deallocate_pages) struct page *page = area->pages[i]; BUG_ON(!page); - __free_page(page); + __free_kmem_pages(page, 0); } if (area->flags & VM_VPAGES) @@ -1608,9 +1608,9 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, struct page *page; if (node == NUMA_NO_NODE) - page = alloc_page(alloc_mask); + page = alloc_kmem_pages(alloc_mask, order); else - page = alloc_pages_node(node, alloc_mask, order); + page = alloc_kmem_pages_node(node, alloc_mask, order); if (unlikely(!page)) { /* Successfully allocated i pages, free them in __vunmap() */ -- GitLab From 5d097056c9a017a3b720849efb5432f37acabbac Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Thu, 14 Jan 2016 15:18:21 -0800 Subject: [PATCH 2755/2855] kmemcg: account certain kmem allocations to memcg Mark those kmem allocations that are known to be easily triggered from userspace as __GFP_ACCOUNT/SLAB_ACCOUNT, which makes them accounted to memcg. For the list, see below: - threadinfo - task_struct - task_delay_info - pid - cred - mm_struct - vm_area_struct and vm_region (nommu) - anon_vma and anon_vma_chain - signal_struct - sighand_struct - fs_struct - files_struct - fdtable and fdtable->full_fds_bits - dentry and external_name - inode for all filesystems. This is the most tedious part, because most filesystems overwrite the alloc_inode method. The list is far from complete, so feel free to add more objects. Nevertheless, it should be close to "account everything" approach and keep most workloads within bounds. Malevolent users will be able to breach the limit, but this was possible even with the former "account everything" approach (simply because it did not account everything in fact). [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Vladimir Davydov Acked-by: Johannes Weiner Acked-by: Michal Hocko Cc: Tejun Heo Cc: Greg Thelen Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/platforms/cell/spufs/inode.c | 2 +- drivers/staging/lustre/lustre/llite/super25.c | 3 ++- fs/9p/v9fs.c | 2 +- fs/adfs/super.c | 2 +- fs/affs/super.c | 2 +- fs/afs/super.c | 2 +- fs/befs/linuxvfs.c | 2 +- fs/bfs/inode.c | 2 +- fs/block_dev.c | 2 +- fs/btrfs/inode.c | 3 ++- fs/ceph/super.c | 4 ++-- fs/cifs/cifsfs.c | 2 +- fs/coda/inode.c | 6 ++--- fs/dcache.c | 5 +++-- fs/ecryptfs/main.c | 6 +++-- fs/efs/super.c | 6 ++--- fs/exofs/super.c | 4 ++-- fs/ext2/super.c | 2 +- fs/ext4/super.c | 2 +- fs/f2fs/super.c | 5 +++-- fs/fat/inode.c | 2 +- fs/file.c | 7 +++--- fs/fuse/inode.c | 4 ++-- fs/gfs2/main.c | 3 ++- fs/hfs/super.c | 4 ++-- fs/hfsplus/super.c | 2 +- fs/hostfs/hostfs_kern.c | 2 +- fs/hpfs/super.c | 2 +- fs/hugetlbfs/inode.c | 2 +- fs/inode.c | 2 +- fs/isofs/inode.c | 2 +- fs/jffs2/super.c | 2 +- fs/jfs/super.c | 2 +- fs/logfs/inode.c | 3 ++- fs/minix/inode.c | 2 +- fs/ncpfs/inode.c | 2 +- fs/nfs/inode.c | 2 +- fs/nilfs2/super.c | 3 ++- fs/ntfs/super.c | 4 ++-- fs/ocfs2/dlmfs/dlmfs.c | 2 +- fs/ocfs2/super.c | 2 +- fs/openpromfs/inode.c | 2 +- fs/proc/inode.c | 3 ++- fs/qnx4/inode.c | 2 +- fs/qnx6/inode.c | 2 +- fs/reiserfs/super.c | 3 ++- fs/romfs/super.c | 4 ++-- fs/squashfs/super.c | 3 ++- fs/sysv/inode.c | 2 +- fs/ubifs/super.c | 4 ++-- fs/udf/super.c | 3 ++- fs/ufs/super.c | 2 +- fs/xfs/kmem.h | 1 + fs/xfs/xfs_super.c | 4 ++-- include/linux/thread_info.h | 5 +++-- ipc/mqueue.c | 2 +- kernel/cred.c | 4 ++-- kernel/delayacct.c | 2 +- kernel/fork.c | 22 +++++++++++-------- kernel/pid.c | 2 +- mm/nommu.c | 2 +- mm/rmap.c | 6 +++-- mm/shmem.c | 2 +- net/socket.c | 2 +- net/sunrpc/rpc_pipe.c | 2 +- 65 files changed, 114 insertions(+), 92 deletions(-) diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 11634fa7ab3c1..ad4840f86be1f 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -767,7 +767,7 @@ static int __init spufs_init(void) ret = -ENOMEM; spufs_inode_cache = kmem_cache_create("spufs_inode_cache", sizeof(struct spufs_inode_info), 0, - SLAB_HWCACHE_ALIGN, spufs_init_once); + SLAB_HWCACHE_ALIGN|SLAB_ACCOUNT, spufs_init_once); if (!spufs_inode_cache) goto out; diff --git a/drivers/staging/lustre/lustre/llite/super25.c b/drivers/staging/lustre/lustre/llite/super25.c index 7a9fafc676935..86c371ef71eae 100644 --- a/drivers/staging/lustre/lustre/llite/super25.c +++ b/drivers/staging/lustre/lustre/llite/super25.c @@ -106,7 +106,8 @@ static int __init init_lustre_lite(void) rc = -ENOMEM; ll_inode_cachep = kmem_cache_create("lustre_inode_cache", sizeof(struct ll_inode_info), - 0, SLAB_HWCACHE_ALIGN, NULL); + 0, SLAB_HWCACHE_ALIGN|SLAB_ACCOUNT, + NULL); if (ll_inode_cachep == NULL) goto out_cache; diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 6caca025019d1..072e7599583a8 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -575,7 +575,7 @@ static int v9fs_init_inode_cache(void) v9fs_inode_cache = kmem_cache_create("v9fs_inode_cache", sizeof(struct v9fs_inode), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), v9fs_inode_init_once); if (!v9fs_inode_cache) return -ENOMEM; diff --git a/fs/adfs/super.c b/fs/adfs/super.c index 4d4a0df8344fe..c9fdfb1129335 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c @@ -271,7 +271,7 @@ static int __init init_inodecache(void) adfs_inode_cachep = kmem_cache_create("adfs_inode_cache", sizeof(struct adfs_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); if (adfs_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/affs/super.c b/fs/affs/super.c index 8836df5f1e111..2a6713b6b9f46 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -132,7 +132,7 @@ static int __init init_inodecache(void) affs_inode_cachep = kmem_cache_create("affs_inode_cache", sizeof(struct affs_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); if (affs_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/afs/super.c b/fs/afs/super.c index 1fb4a5129f7df..81afefe7d8a6e 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -91,7 +91,7 @@ int __init afs_fs_init(void) afs_inode_cachep = kmem_cache_create("afs_inode_cache", sizeof(struct afs_vnode), 0, - SLAB_HWCACHE_ALIGN, + SLAB_HWCACHE_ALIGN|SLAB_ACCOUNT, afs_i_init_once); if (!afs_inode_cachep) { printk(KERN_NOTICE "kAFS: Failed to allocate inode cache\n"); diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index 25250fa870863..cc0e08252913a 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c @@ -434,7 +434,7 @@ befs_init_inodecache(void) befs_inode_cachep = kmem_cache_create("befs_inode_cache", sizeof (struct befs_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); if (befs_inode_cachep == NULL) { pr_err("%s: Couldn't initialize inode slabcache\n", __func__); diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index fdcb4d69f430d..1e5c896f6b79f 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -270,7 +270,7 @@ static int __init init_inodecache(void) bfs_inode_cachep = kmem_cache_create("bfs_inode_cache", sizeof(struct bfs_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); if (bfs_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/block_dev.c b/fs/block_dev.c index d878e4860fb7c..d33071dd683ec 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -595,7 +595,7 @@ void __init bdev_cache_init(void) bdev_cachep = kmem_cache_create("bdev_cache", sizeof(struct bdev_inode), 0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD|SLAB_PANIC), + SLAB_MEM_SPREAD|SLAB_ACCOUNT|SLAB_PANIC), init_once); err = register_filesystem(&bd_type); if (err) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3b8856e182ae7..394017831692b 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -9161,7 +9161,8 @@ int btrfs_init_cachep(void) { btrfs_inode_cachep = kmem_cache_create("btrfs_inode", sizeof(struct btrfs_inode), 0, - SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, init_once); + SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD | SLAB_ACCOUNT, + init_once); if (!btrfs_inode_cachep) goto fail; diff --git a/fs/ceph/super.c b/fs/ceph/super.c index f446afada328a..ca4d5e8457f1e 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -639,8 +639,8 @@ static int __init init_caches(void) ceph_inode_cachep = kmem_cache_create("ceph_inode_info", sizeof(struct ceph_inode_info), __alignof__(struct ceph_inode_info), - (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD), - ceph_inode_init_once); + SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD| + SLAB_ACCOUNT, ceph_inode_init_once); if (ceph_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index b7fcb3151103c..c4c1169814b21 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -1092,7 +1092,7 @@ cifs_init_inodecache(void) cifs_inode_cachep = kmem_cache_create("cifs_inode_cache", sizeof(struct cifsInodeInfo), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), cifs_init_once); if (cifs_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/coda/inode.c b/fs/coda/inode.c index cac1390b87a35..57e81cbba0fa5 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c @@ -74,9 +74,9 @@ static void init_once(void *foo) int __init coda_init_inodecache(void) { coda_inode_cachep = kmem_cache_create("coda_inode_cache", - sizeof(struct coda_inode_info), - 0, SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, - init_once); + sizeof(struct coda_inode_info), 0, + SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD| + SLAB_ACCOUNT, init_once); if (coda_inode_cachep == NULL) return -ENOMEM; return 0; diff --git a/fs/dcache.c b/fs/dcache.c index 8d38cd07b207b..b4539e84e5779 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1571,7 +1571,8 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) dentry->d_iname[DNAME_INLINE_LEN-1] = 0; if (name->len > DNAME_INLINE_LEN-1) { size_t size = offsetof(struct external_name, name[1]); - struct external_name *p = kmalloc(size + name->len, GFP_KERNEL); + struct external_name *p = kmalloc(size + name->len, + GFP_KERNEL_ACCOUNT); if (!p) { kmem_cache_free(dentry_cache, dentry); return NULL; @@ -3415,7 +3416,7 @@ static void __init dcache_init(void) * of the dcache. */ dentry_cache = KMEM_CACHE(dentry, - SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|SLAB_MEM_SPREAD); + SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|SLAB_MEM_SPREAD|SLAB_ACCOUNT); /* Hash may have been set up in dcache_init_early */ if (!hashdist) diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 4f4d0474bee96..e25b6b06bacf2 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -663,6 +663,7 @@ static struct ecryptfs_cache_info { struct kmem_cache **cache; const char *name; size_t size; + unsigned long flags; void (*ctor)(void *obj); } ecryptfs_cache_infos[] = { { @@ -684,6 +685,7 @@ static struct ecryptfs_cache_info { .cache = &ecryptfs_inode_info_cache, .name = "ecryptfs_inode_cache", .size = sizeof(struct ecryptfs_inode_info), + .flags = SLAB_ACCOUNT, .ctor = inode_info_init_once, }, { @@ -755,8 +757,8 @@ static int ecryptfs_init_kmem_caches(void) struct ecryptfs_cache_info *info; info = &ecryptfs_cache_infos[i]; - *(info->cache) = kmem_cache_create(info->name, info->size, - 0, SLAB_HWCACHE_ALIGN, info->ctor); + *(info->cache) = kmem_cache_create(info->name, info->size, 0, + SLAB_HWCACHE_ALIGN | info->flags, info->ctor); if (!*(info->cache)) { ecryptfs_free_kmem_caches(); ecryptfs_printk(KERN_WARNING, "%s: " diff --git a/fs/efs/super.c b/fs/efs/super.c index c8411a30f7dac..cb68dac4f9d32 100644 --- a/fs/efs/super.c +++ b/fs/efs/super.c @@ -94,9 +94,9 @@ static void init_once(void *foo) static int __init init_inodecache(void) { efs_inode_cachep = kmem_cache_create("efs_inode_cache", - sizeof(struct efs_inode_info), - 0, SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, - init_once); + sizeof(struct efs_inode_info), 0, + SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD| + SLAB_ACCOUNT, init_once); if (efs_inode_cachep == NULL) return -ENOMEM; return 0; diff --git a/fs/exofs/super.c b/fs/exofs/super.c index b795c567b5e1d..6658a50530a06 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c @@ -194,8 +194,8 @@ static int init_inodecache(void) { exofs_inode_cachep = kmem_cache_create("exofs_inode_cache", sizeof(struct exofs_i_info), 0, - SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, - exofs_init_once); + SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD | + SLAB_ACCOUNT, exofs_init_once); if (exofs_inode_cachep == NULL) return -ENOMEM; return 0; diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 748d35afc9026..2a188413a2b09 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -203,7 +203,7 @@ static int __init init_inodecache(void) ext2_inode_cachep = kmem_cache_create("ext2_inode_cache", sizeof(struct ext2_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); if (ext2_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index c9ab67da6e5ab..f1b56ff012089 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -966,7 +966,7 @@ static int __init init_inodecache(void) ext4_inode_cachep = kmem_cache_create("ext4_inode_cache", sizeof(struct ext4_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); if (ext4_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 3bf990b800262..6134832baaaf0 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1541,8 +1541,9 @@ MODULE_ALIAS_FS("f2fs"); static int __init init_inodecache(void) { - f2fs_inode_cachep = f2fs_kmem_cache_create("f2fs_inode_cache", - sizeof(struct f2fs_inode_info)); + f2fs_inode_cachep = kmem_cache_create("f2fs_inode_cache", + sizeof(struct f2fs_inode_info), 0, + SLAB_RECLAIM_ACCOUNT|SLAB_ACCOUNT, NULL); if (!f2fs_inode_cachep) return -ENOMEM; return 0; diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 509411dd36989..6aece96df19fc 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -677,7 +677,7 @@ static int __init fat_init_inodecache(void) fat_inode_cachep = kmem_cache_create("fat_inode_cache", sizeof(struct msdos_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); if (fat_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/file.c b/fs/file.c index 1aed0add16a2c..1fbc5c0555a9c 100644 --- a/fs/file.c +++ b/fs/file.c @@ -37,11 +37,12 @@ static void *alloc_fdmem(size_t size) * vmalloc() if the allocation size will be considered "large" by the VM. */ if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) { - void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY); + void *data = kmalloc(size, GFP_KERNEL_ACCOUNT | + __GFP_NOWARN | __GFP_NORETRY); if (data != NULL) return data; } - return vmalloc(size); + return __vmalloc(size, GFP_KERNEL_ACCOUNT | __GFP_HIGHMEM, PAGE_KERNEL); } static void __free_fdtable(struct fdtable *fdt) @@ -126,7 +127,7 @@ static struct fdtable * alloc_fdtable(unsigned int nr) if (unlikely(nr > sysctl_nr_open)) nr = ((sysctl_nr_open - 1) | (BITS_PER_LONG - 1)) + 1; - fdt = kmalloc(sizeof(struct fdtable), GFP_KERNEL); + fdt = kmalloc(sizeof(struct fdtable), GFP_KERNEL_ACCOUNT); if (!fdt) goto out; fdt->max_fds = nr; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 2913db2a5b99b..4d69d5c0bedcd 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -1255,8 +1255,8 @@ static int __init fuse_fs_init(void) int err; fuse_inode_cachep = kmem_cache_create("fuse_inode", - sizeof(struct fuse_inode), - 0, SLAB_HWCACHE_ALIGN, + sizeof(struct fuse_inode), 0, + SLAB_HWCACHE_ALIGN|SLAB_ACCOUNT, fuse_inode_init_once); err = -ENOMEM; if (!fuse_inode_cachep) diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index 1d709d496364b..f99f8e94de3f3 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c @@ -114,7 +114,8 @@ static int __init init_gfs2_fs(void) gfs2_inode_cachep = kmem_cache_create("gfs2_inode", sizeof(struct gfs2_inode), 0, SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD, + SLAB_MEM_SPREAD| + SLAB_ACCOUNT, gfs2_init_inode_once); if (!gfs2_inode_cachep) goto fail; diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 4574fdd3d4219..1ca95c232bb5c 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -483,8 +483,8 @@ static int __init init_hfs_fs(void) int err; hfs_inode_cachep = kmem_cache_create("hfs_inode_cache", - sizeof(struct hfs_inode_info), 0, SLAB_HWCACHE_ALIGN, - hfs_init_once); + sizeof(struct hfs_inode_info), 0, + SLAB_HWCACHE_ALIGN|SLAB_ACCOUNT, hfs_init_once); if (!hfs_inode_cachep) return -ENOMEM; err = register_filesystem(&hfs_fs_type); diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 7302d96ae8bfd..5d54490a136d8 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -663,7 +663,7 @@ static int __init init_hfsplus_fs(void) int err; hfsplus_inode_cachep = kmem_cache_create("hfsplus_icache", - HFSPLUS_INODE_SIZE, 0, SLAB_HWCACHE_ALIGN, + HFSPLUS_INODE_SIZE, 0, SLAB_HWCACHE_ALIGN|SLAB_ACCOUNT, hfsplus_init_once); if (!hfsplus_inode_cachep) return -ENOMEM; diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index f49be23e78aab..cfaa18c7a3379 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -223,7 +223,7 @@ static struct inode *hostfs_alloc_inode(struct super_block *sb) { struct hostfs_inode_info *hi; - hi = kmalloc(sizeof(*hi), GFP_KERNEL); + hi = kmalloc(sizeof(*hi), GFP_KERNEL_ACCOUNT); if (hi == NULL) return NULL; hi->fd = -1; diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index a561591896bd3..458cf463047b6 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c @@ -261,7 +261,7 @@ static int init_inodecache(void) hpfs_inode_cachep = kmem_cache_create("hpfs_inode_cache", sizeof(struct hpfs_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); if (hpfs_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index d8f51ee8126b3..f6820ecf0a11f 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -1322,7 +1322,7 @@ static int __init init_hugetlbfs_fs(void) error = -ENOMEM; hugetlbfs_inode_cachep = kmem_cache_create("hugetlbfs_inode_cache", sizeof(struct hugetlbfs_inode_info), - 0, 0, init_once); + 0, SLAB_ACCOUNT, init_once); if (hugetlbfs_inode_cachep == NULL) goto out2; diff --git a/fs/inode.c b/fs/inode.c index 4230f66b74101..e491e54d24302 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1883,7 +1883,7 @@ void __init inode_init(void) sizeof(struct inode), 0, (SLAB_RECLAIM_ACCOUNT|SLAB_PANIC| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); /* Hash may have been set up in inode_init_early */ diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 61abdc4920dab..bcd2d41b318a4 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -94,7 +94,7 @@ static int __init init_inodecache(void) isofs_inode_cachep = kmem_cache_create("isofs_inode_cache", sizeof(struct iso_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); if (isofs_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index d86c5e3176a13..bb080c2721493 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -387,7 +387,7 @@ static int __init init_jffs2_fs(void) jffs2_inode_cachep = kmem_cache_create("jffs2_i", sizeof(struct jffs2_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), jffs2_i_init_once); if (!jffs2_inode_cachep) { pr_err("error: Failed to initialise inode cache\n"); diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 8f9176caf098c..900925b5eb8c2 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -898,7 +898,7 @@ static int __init init_jfs_fs(void) jfs_inode_cachep = kmem_cache_create("jfs_ip", sizeof(struct jfs_inode_info), 0, - SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, + SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD|SLAB_ACCOUNT, init_once); if (jfs_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c index 0fce46d62b9c2..db9cfc5988836 100644 --- a/fs/logfs/inode.c +++ b/fs/logfs/inode.c @@ -409,7 +409,8 @@ const struct super_operations logfs_super_operations = { int logfs_init_inode_cache(void) { logfs_inode_cache = kmem_cache_create("logfs_inode_cache", - sizeof(struct logfs_inode), 0, SLAB_RECLAIM_ACCOUNT, + sizeof(struct logfs_inode), 0, + SLAB_RECLAIM_ACCOUNT|SLAB_ACCOUNT, logfs_init_once); if (!logfs_inode_cache) return -ENOMEM; diff --git a/fs/minix/inode.c b/fs/minix/inode.c index cb1789ca1ee67..f975d667c5390 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -91,7 +91,7 @@ static int __init init_inodecache(void) minix_inode_cachep = kmem_cache_create("minix_inode_cache", sizeof(struct minix_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); if (minix_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index ce1eb3f9dfe80..1af15fcbe57b7 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -82,7 +82,7 @@ static int init_inodecache(void) ncp_inode_cachep = kmem_cache_create("ncp_inode_cache", sizeof(struct ncp_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); if (ncp_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index bdb4dc7b4ecde..48fd8a87affe5 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1933,7 +1933,7 @@ static int __init nfs_init_inodecache(void) nfs_inode_cachep = kmem_cache_create("nfs_inode_cache", sizeof(struct nfs_inode), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); if (nfs_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index c7343844e6b62..7f5d3d9f1c37b 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -1416,7 +1416,8 @@ static int __init nilfs_init_cachep(void) { nilfs_inode_cachep = kmem_cache_create("nilfs2_inode_cache", sizeof(struct nilfs_inode_info), 0, - SLAB_RECLAIM_ACCOUNT, nilfs_inode_init_once); + SLAB_RECLAIM_ACCOUNT|SLAB_ACCOUNT, + nilfs_inode_init_once); if (!nilfs_inode_cachep) goto fail; diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index d1a853585b539..2f77f8dfb8614 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -3139,8 +3139,8 @@ static int __init init_ntfs_fs(void) ntfs_big_inode_cache = kmem_cache_create(ntfs_big_inode_cache_name, sizeof(big_ntfs_inode), 0, - SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, - ntfs_big_inode_init_once); + SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD| + SLAB_ACCOUNT, ntfs_big_inode_init_once); if (!ntfs_big_inode_cache) { pr_crit("Failed to create %s!\n", ntfs_big_inode_cache_name); goto big_inode_err_out; diff --git a/fs/ocfs2/dlmfs/dlmfs.c b/fs/ocfs2/dlmfs/dlmfs.c index b5cf27dcb18a7..03768bb3aab15 100644 --- a/fs/ocfs2/dlmfs/dlmfs.c +++ b/fs/ocfs2/dlmfs/dlmfs.c @@ -638,7 +638,7 @@ static int __init init_dlmfs_fs(void) dlmfs_inode_cache = kmem_cache_create("dlmfs_inode_cache", sizeof(struct dlmfs_inode_private), 0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), dlmfs_init_once); if (!dlmfs_inode_cache) { status = -ENOMEM; diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index c62d761d6bf01..faa1365097bcf 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -1766,7 +1766,7 @@ static int ocfs2_initialize_mem_caches(void) sizeof(struct ocfs2_inode_info), 0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), ocfs2_inode_init_once); ocfs2_dquot_cachep = kmem_cache_create("ocfs2_dquot_cache", sizeof(struct ocfs2_dquot), diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c index 15e4500cda3ee..b61b883c8ff8e 100644 --- a/fs/openpromfs/inode.c +++ b/fs/openpromfs/inode.c @@ -443,7 +443,7 @@ static int __init init_openprom_fs(void) sizeof(struct op_inode_info), 0, (SLAB_RECLAIM_ACCOUNT | - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD | SLAB_ACCOUNT), op_inode_init_once); if (!op_inode_cachep) return -ENOMEM; diff --git a/fs/proc/inode.c b/fs/proc/inode.c index d0e9b9b6223e9..42305ddcbaa00 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -95,7 +95,8 @@ void __init proc_init_inodecache(void) proc_inode_cachep = kmem_cache_create("proc_inode_cache", sizeof(struct proc_inode), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD|SLAB_PANIC), + SLAB_MEM_SPREAD|SLAB_ACCOUNT| + SLAB_PANIC), init_once); } diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index f37b3deb01b4d..3a67cfb142d88 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c @@ -365,7 +365,7 @@ static int init_inodecache(void) qnx4_inode_cachep = kmem_cache_create("qnx4_inode_cache", sizeof(struct qnx4_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); if (qnx4_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/qnx6/inode.c b/fs/qnx6/inode.c index 9728b5499e1d5..47bb1de07155e 100644 --- a/fs/qnx6/inode.c +++ b/fs/qnx6/inode.c @@ -625,7 +625,7 @@ static int init_inodecache(void) qnx6_inode_cachep = kmem_cache_create("qnx6_inode_cache", sizeof(struct qnx6_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); if (!qnx6_inode_cachep) return -ENOMEM; diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 4a62fe8cc3bff..05db7473bcb5c 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -626,7 +626,8 @@ static int __init init_inodecache(void) sizeof(struct reiserfs_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD| + SLAB_ACCOUNT), init_once); if (reiserfs_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/romfs/super.c b/fs/romfs/super.c index bb894e78a821e..6b00ca357c58f 100644 --- a/fs/romfs/super.c +++ b/fs/romfs/super.c @@ -619,8 +619,8 @@ static int __init init_romfs_fs(void) romfs_inode_cachep = kmem_cache_create("romfs_i", sizeof(struct romfs_inode_info), 0, - SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, - romfs_i_init_once); + SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD | + SLAB_ACCOUNT, romfs_i_init_once); if (!romfs_inode_cachep) { pr_err("Failed to initialise inode cache\n"); diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index dded920cbc8f1..5e79bfa4f2607 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c @@ -419,7 +419,8 @@ static int __init init_inodecache(void) { squashfs_inode_cachep = kmem_cache_create("squashfs_inode_cache", sizeof(struct squashfs_inode_info), 0, - SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, init_once); + SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_ACCOUNT, + init_once); return squashfs_inode_cachep ? 0 : -ENOMEM; } diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index 07ac18c355e77..d62c423a5a2d8 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c @@ -346,7 +346,7 @@ int __init sysv_init_icache(void) { sysv_inode_cachep = kmem_cache_create("sysv_inode_cache", sizeof(struct sysv_inode_info), 0, - SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, + SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD|SLAB_ACCOUNT, init_once); if (!sysv_inode_cachep) return -ENOMEM; diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 1fd90c0795374..a233ba913be4f 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -2248,8 +2248,8 @@ static int __init ubifs_init(void) ubifs_inode_slab = kmem_cache_create("ubifs_inode_slab", sizeof(struct ubifs_inode), 0, - SLAB_MEM_SPREAD | SLAB_RECLAIM_ACCOUNT, - &inode_slab_ctor); + SLAB_MEM_SPREAD | SLAB_RECLAIM_ACCOUNT | + SLAB_ACCOUNT, &inode_slab_ctor); if (!ubifs_inode_slab) return -ENOMEM; diff --git a/fs/udf/super.c b/fs/udf/super.c index 81155b9b445b3..9c64a3ca9837d 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -179,7 +179,8 @@ static int __init init_inodecache(void) udf_inode_cachep = kmem_cache_create("udf_inode_cache", sizeof(struct udf_inode_info), 0, (SLAB_RECLAIM_ACCOUNT | - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD | + SLAB_ACCOUNT), init_once); if (!udf_inode_cachep) return -ENOMEM; diff --git a/fs/ufs/super.c b/fs/ufs/super.c index f6390eec02cab..442fd52ebffe5 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1427,7 +1427,7 @@ static int __init init_inodecache(void) ufs_inode_cachep = kmem_cache_create("ufs_inode_cache", sizeof(struct ufs_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); if (ufs_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/xfs/kmem.h b/fs/xfs/kmem.h index cc6b768fc068f..d1c66e465ca56 100644 --- a/fs/xfs/kmem.h +++ b/fs/xfs/kmem.h @@ -84,6 +84,7 @@ kmem_zalloc(size_t size, xfs_km_flags_t flags) #define KM_ZONE_HWALIGN SLAB_HWCACHE_ALIGN #define KM_ZONE_RECLAIM SLAB_RECLAIM_ACCOUNT #define KM_ZONE_SPREAD SLAB_MEM_SPREAD +#define KM_ZONE_ACCOUNT SLAB_ACCOUNT #define kmem_zone kmem_cache #define kmem_zone_t struct kmem_cache diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index b35775752b745..59c9b7bd958d6 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1714,8 +1714,8 @@ xfs_init_zones(void) xfs_inode_zone = kmem_zone_init_flags(sizeof(xfs_inode_t), "xfs_inode", - KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | KM_ZONE_SPREAD, - xfs_fs_inode_init_once); + KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | KM_ZONE_SPREAD | + KM_ZONE_ACCOUNT, xfs_fs_inode_init_once); if (!xfs_inode_zone) goto out_destroy_efi_zone; diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index ff307b548ed3c..b4c2a485b28a7 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -56,9 +56,10 @@ extern long do_no_restart_syscall(struct restart_block *parm); #ifdef __KERNEL__ #ifdef CONFIG_DEBUG_STACK_USAGE -# define THREADINFO_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO) +# define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_NOTRACK | \ + __GFP_ZERO) #else -# define THREADINFO_GFP (GFP_KERNEL | __GFP_NOTRACK) +# define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_NOTRACK) #endif /* diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 161a1807e6efb..f4617cf070692 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -1438,7 +1438,7 @@ static int __init init_mqueue_fs(void) mqueue_inode_cachep = kmem_cache_create("mqueue_inode_cache", sizeof(struct mqueue_inode_info), 0, - SLAB_HWCACHE_ALIGN, init_once); + SLAB_HWCACHE_ALIGN|SLAB_ACCOUNT, init_once); if (mqueue_inode_cachep == NULL) return -ENOMEM; diff --git a/kernel/cred.c b/kernel/cred.c index 71179a09c1d6a..0c0cd8a622852 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -569,8 +569,8 @@ EXPORT_SYMBOL(revert_creds); void __init cred_init(void) { /* allocate a slab in which we can store credentials */ - cred_jar = kmem_cache_create("cred_jar", sizeof(struct cred), - 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); + cred_jar = kmem_cache_create("cred_jar", sizeof(struct cred), 0, + SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, NULL); } /** diff --git a/kernel/delayacct.c b/kernel/delayacct.c index ef90b04d783f1..435c14a451181 100644 --- a/kernel/delayacct.c +++ b/kernel/delayacct.c @@ -34,7 +34,7 @@ __setup("nodelayacct", delayacct_setup_disable); void delayacct_init(void) { - delayacct_cache = KMEM_CACHE(task_delay_info, SLAB_PANIC); + delayacct_cache = KMEM_CACHE(task_delay_info, SLAB_PANIC|SLAB_ACCOUNT); delayacct_tsk_init(&init_task); } diff --git a/kernel/fork.c b/kernel/fork.c index 6774e6b2e96d6..51915842f1c06 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -300,9 +300,9 @@ void __init fork_init(void) #define ARCH_MIN_TASKALIGN L1_CACHE_BYTES #endif /* create a slab on which task_structs can be allocated */ - task_struct_cachep = - kmem_cache_create("task_struct", arch_task_struct_size, - ARCH_MIN_TASKALIGN, SLAB_PANIC | SLAB_NOTRACK, NULL); + task_struct_cachep = kmem_cache_create("task_struct", + arch_task_struct_size, ARCH_MIN_TASKALIGN, + SLAB_PANIC|SLAB_NOTRACK|SLAB_ACCOUNT, NULL); #endif /* do the arch specific task caches init */ @@ -1848,16 +1848,19 @@ void __init proc_caches_init(void) sighand_cachep = kmem_cache_create("sighand_cache", sizeof(struct sighand_struct), 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_DESTROY_BY_RCU| - SLAB_NOTRACK, sighand_ctor); + SLAB_NOTRACK|SLAB_ACCOUNT, sighand_ctor); signal_cachep = kmem_cache_create("signal_cache", sizeof(struct signal_struct), 0, - SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); + SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK|SLAB_ACCOUNT, + NULL); files_cachep = kmem_cache_create("files_cache", sizeof(struct files_struct), 0, - SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); + SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK|SLAB_ACCOUNT, + NULL); fs_cachep = kmem_cache_create("fs_cache", sizeof(struct fs_struct), 0, - SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); + SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK|SLAB_ACCOUNT, + NULL); /* * FIXME! The "sizeof(struct mm_struct)" currently includes the * whole struct cpumask for the OFFSTACK case. We could change @@ -1867,8 +1870,9 @@ void __init proc_caches_init(void) */ mm_cachep = kmem_cache_create("mm_struct", sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, - SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); - vm_area_cachep = KMEM_CACHE(vm_area_struct, SLAB_PANIC); + SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK|SLAB_ACCOUNT, + NULL); + vm_area_cachep = KMEM_CACHE(vm_area_struct, SLAB_PANIC|SLAB_ACCOUNT); mmap_init(); nsproxy_cache_init(); } diff --git a/kernel/pid.c b/kernel/pid.c index 78b3d9f80d443..f4ad91b746f1e 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -604,5 +604,5 @@ void __init pidmap_init(void) atomic_dec(&init_pid_ns.pidmap[0].nr_free); init_pid_ns.pid_cachep = KMEM_CACHE(pid, - SLAB_HWCACHE_ALIGN | SLAB_PANIC); + SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT); } diff --git a/mm/nommu.c b/mm/nommu.c index 92be862c859bd..fbf6f0f1d6c99 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -560,7 +560,7 @@ void __init mmap_init(void) ret = percpu_counter_init(&vm_committed_as, 0, GFP_KERNEL); VM_BUG_ON(ret); - vm_region_jar = KMEM_CACHE(vm_region, SLAB_PANIC); + vm_region_jar = KMEM_CACHE(vm_region, SLAB_PANIC|SLAB_ACCOUNT); } /* diff --git a/mm/rmap.c b/mm/rmap.c index b577fbb98d4ba..3c3f1d21f0758 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -428,8 +428,10 @@ static void anon_vma_ctor(void *data) void __init anon_vma_init(void) { anon_vma_cachep = kmem_cache_create("anon_vma", sizeof(struct anon_vma), - 0, SLAB_DESTROY_BY_RCU|SLAB_PANIC, anon_vma_ctor); - anon_vma_chain_cachep = KMEM_CACHE(anon_vma_chain, SLAB_PANIC); + 0, SLAB_DESTROY_BY_RCU|SLAB_PANIC|SLAB_ACCOUNT, + anon_vma_ctor); + anon_vma_chain_cachep = KMEM_CACHE(anon_vma_chain, + SLAB_PANIC|SLAB_ACCOUNT); } /* diff --git a/mm/shmem.c b/mm/shmem.c index 5813b7fa85b64..9e60093aca3fd 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -3064,7 +3064,7 @@ static int shmem_init_inodecache(void) { shmem_inode_cachep = kmem_cache_create("shmem_inode_cache", sizeof(struct shmem_inode_info), - 0, SLAB_PANIC, shmem_init_inode); + 0, SLAB_PANIC|SLAB_ACCOUNT, shmem_init_inode); return 0; } diff --git a/net/socket.c b/net/socket.c index 91c2de6f50205..c044d1e8508cc 100644 --- a/net/socket.c +++ b/net/socket.c @@ -294,7 +294,7 @@ static int init_inodecache(void) 0, (SLAB_HWCACHE_ALIGN | SLAB_RECLAIM_ACCOUNT | - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD | SLAB_ACCOUNT), init_once); if (sock_inode_cachep == NULL) return -ENOMEM; diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index d81186d34558c..14f45bf0410c6 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -1500,7 +1500,7 @@ int register_rpc_pipefs(void) rpc_inode_cachep = kmem_cache_create("rpc_inode_cache", sizeof(struct rpc_inode), 0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), + SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); if (!rpc_inode_cachep) return -ENOMEM; -- GitLab From ab7a5af7fd9cc38576b432690367bbabc8da99b2 Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Thu, 14 Jan 2016 15:18:24 -0800 Subject: [PATCH 2756/2855] mm/mlock.c: drop unneeded initialization in munlock_vma_pages_range() Before usage page pointer initialized by NULL is reinitialized by follow_page_mask(). Drop useless init of page pointer in the beginning of loop. Signed-off-by: Alexey Klimov Acked-by: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/mlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/mlock.c b/mm/mlock.c index 339d9e0949b6d..9cb87cbc40715 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -425,7 +425,7 @@ void munlock_vma_pages_range(struct vm_area_struct *vma, vma->vm_flags &= VM_LOCKED_CLEAR_MASK; while (start < end) { - struct page *page = NULL; + struct page *page; unsigned int page_mask; unsigned long page_increm; struct pagevec pvec; -- GitLab From 0b57d6ba0bd11a41a791cf6c5bbf3b55630dc70f Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Thu, 14 Jan 2016 15:18:27 -0800 Subject: [PATCH 2757/2855] mm/mmap.c: remove redundant local variables for may_expand_vm() Simplify may_expand_vm(). [akpm@linux-foundation.org: further simplification, per Naoya Horiguchi] Signed-off-by: Chen Gang Cc: Naoya Horiguchi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/mmap.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/mm/mmap.c b/mm/mmap.c index 2ce04a649f6b4..9da9c27c33a2a 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2988,14 +2988,7 @@ out: */ int may_expand_vm(struct mm_struct *mm, unsigned long npages) { - unsigned long cur = mm->total_vm; /* pages */ - unsigned long lim; - - lim = rlimit(RLIMIT_AS) >> PAGE_SHIFT; - - if (cur + npages > lim) - return 0; - return 1; + return mm->total_vm + npages <= rlimit(RLIMIT_AS) >> PAGE_SHIFT; } static int special_mapping_fault(struct vm_area_struct *vma, -- GitLab From 3aa2385111168187f24a6db04697c6fab0fab9b4 Mon Sep 17 00:00:00 2001 From: yalin wang Date: Thu, 14 Jan 2016 15:18:30 -0800 Subject: [PATCH 2758/2855] mm/vmscan.c: change trace_mm_vmscan_writepage() proto type Move trace_reclaim_flags() into trace function, so that we don't need caculate these flags if the trace is disabled. Signed-off-by: yalin wang Reviewed-by: Steven Rostedt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/trace/events/vmscan.h | 7 +++---- mm/vmscan.c | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h index f66476b96264c..dae7836e1f51c 100644 --- a/include/trace/events/vmscan.h +++ b/include/trace/events/vmscan.h @@ -330,10 +330,9 @@ DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate, TRACE_EVENT(mm_vmscan_writepage, - TP_PROTO(struct page *page, - int reclaim_flags), + TP_PROTO(struct page *page), - TP_ARGS(page, reclaim_flags), + TP_ARGS(page), TP_STRUCT__entry( __field(unsigned long, pfn) @@ -342,7 +341,7 @@ TRACE_EVENT(mm_vmscan_writepage, TP_fast_assign( __entry->pfn = page_to_pfn(page); - __entry->reclaim_flags = reclaim_flags; + __entry->reclaim_flags = trace_reclaim_flags(page); ), TP_printk("page=%p pfn=%lu flags=%s", diff --git a/mm/vmscan.c b/mm/vmscan.c index 2aec4241b42a9..fd7823ccf301f 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -594,7 +594,7 @@ static pageout_t pageout(struct page *page, struct address_space *mapping, /* synchronous write or broken a_ops? */ ClearPageReclaim(page); } - trace_mm_vmscan_writepage(page, trace_reclaim_flags(page)); + trace_mm_vmscan_writepage(page); inc_zone_page_state(page, NR_VMSCAN_WRITE); return PAGE_SUCCESS; } -- GitLab From 8f235d1a3eb7198affe7cadf676a10afb8a46a1a Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Thu, 14 Jan 2016 15:18:33 -0800 Subject: [PATCH 2759/2855] mm: add PHYS_PFN, use it in __phys_to_pfn() __phys_to_pfn and __pfn_to_phys are symmetric, PHYS_PFN and PFN_PHYS are semmetric: - y = (phys_addr_t)x << PAGE_SHIFT - y >> PAGE_SHIFT = (phys_add_t)x - (unsigned long)(y >> PAGE_SHIFT) = x [akpm@linux-foundation.org: use macro arg name `x'] [arnd@arndb.de: include linux/pfn.h for PHYS_PFN definition] Signed-off-by: Chen Gang Cc: Oleg Nesterov Signed-off-by: Arnd Bergmann Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-generic/memory_model.h | 4 +++- include/linux/pfn.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/asm-generic/memory_model.h b/include/asm-generic/memory_model.h index 4b4b056a6eb00..5148150cc80b0 100644 --- a/include/asm-generic/memory_model.h +++ b/include/asm-generic/memory_model.h @@ -1,6 +1,8 @@ #ifndef __ASM_MEMORY_MODEL_H #define __ASM_MEMORY_MODEL_H +#include + #ifndef __ASSEMBLY__ #if defined(CONFIG_FLATMEM) @@ -72,7 +74,7 @@ /* * Convert a physical address to a Page Frame Number and back */ -#define __phys_to_pfn(paddr) ((unsigned long)((paddr) >> PAGE_SHIFT)) +#define __phys_to_pfn(paddr) PHYS_PFN(paddr) #define __pfn_to_phys(pfn) PFN_PHYS(pfn) #define page_to_pfn __page_to_pfn diff --git a/include/linux/pfn.h b/include/linux/pfn.h index 7646637221f3a..97f3e88aead4a 100644 --- a/include/linux/pfn.h +++ b/include/linux/pfn.h @@ -9,5 +9,6 @@ #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) #define PFN_DOWN(x) ((x) >> PAGE_SHIFT) #define PFN_PHYS(x) ((phys_addr_t)(x) << PAGE_SHIFT) +#define PHYS_PFN(x) ((unsigned long)((x) >> PAGE_SHIFT)) #endif -- GitLab From 4a8c7bb59ac85b038c29adf6d32ff56e11fbb267 Mon Sep 17 00:00:00 2001 From: Nathan Zimmer Date: Thu, 14 Jan 2016 15:18:36 -0800 Subject: [PATCH 2760/2855] mm/mempolicy.c: convert the shared_policy lock to a rwlock When running the SPECint_rate gcc on some very large boxes it was noticed that the system was spending lots of time in mpol_shared_policy_lookup(). The gamess benchmark can also show it and is what I mostly used to chase down the issue since the setup for that I found to be easier. To be clear the binaries were on tmpfs because of disk I/O requirements. We then used text replication to avoid icache misses and having all the copies banging on the memory where the instruction code resides. This results in us hitting a bottleneck in mpol_shared_policy_lookup() since lookup is serialised by the shared_policy lock. I have only reproduced this on very large (3k+ cores) boxes. The problem starts showing up at just a few hundred ranks getting worse until it threatens to livelock once it gets large enough. For example on the gamess benchmark at 128 ranks this area consumes only ~1% of time, at 512 ranks it consumes nearly 13%, and at 2k ranks it is over 90%. To alleviate the contention in this area I converted the spinlock to an rwlock. This allows a large number of lookups to happen simultaneously. The results were quite good reducing this consumtion at max ranks to around 2%. [akpm@linux-foundation.org: tidy up code comments] Signed-off-by: Nathan Zimmer Acked-by: David Rientjes Acked-by: Vlastimil Babka Cc: Nadia Yvette Chambers Cc: Naoya Horiguchi Cc: Mel Gorman Cc: "Aneesh Kumar K.V" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/hugetlbfs/inode.c | 2 +- include/linux/mempolicy.h | 2 +- mm/mempolicy.c | 30 +++++++++++++++++------------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index f6820ecf0a11f..a1cb8fd2289b9 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -738,7 +738,7 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, /* * The policy is initialized here even if we are creating a * private inode because initialization simply creates an - * an empty rb tree and calls spin_lock_init(), later when we + * an empty rb tree and calls rwlock_init(), later when we * call mpol_free_shared_policy() it will just return because * the rb tree will still be empty. */ diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index 3d385c81c1534..2696c1f05ed13 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h @@ -122,7 +122,7 @@ struct sp_node { struct shared_policy { struct rb_root root; - spinlock_t lock; + rwlock_t lock; }; int vma_dup_policy(struct vm_area_struct *src, struct vm_area_struct *dst); diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 87a177917cb2e..d8caff071a305 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -2142,12 +2142,14 @@ bool __mpol_equal(struct mempolicy *a, struct mempolicy *b) * * Remember policies even when nobody has shared memory mapped. * The policies are kept in Red-Black tree linked from the inode. - * They are protected by the sp->lock spinlock, which should be held + * They are protected by the sp->lock rwlock, which should be held * for any accesses to the tree. */ -/* lookup first element intersecting start-end */ -/* Caller holds sp->lock */ +/* + * lookup first element intersecting start-end. Caller holds sp->lock for + * reading or for writing + */ static struct sp_node * sp_lookup(struct shared_policy *sp, unsigned long start, unsigned long end) { @@ -2178,8 +2180,10 @@ sp_lookup(struct shared_policy *sp, unsigned long start, unsigned long end) return rb_entry(n, struct sp_node, nd); } -/* Insert a new shared policy into the list. */ -/* Caller holds sp->lock */ +/* + * Insert a new shared policy into the list. Caller holds sp->lock for + * writing. + */ static void sp_insert(struct shared_policy *sp, struct sp_node *new) { struct rb_node **p = &sp->root.rb_node; @@ -2211,13 +2215,13 @@ mpol_shared_policy_lookup(struct shared_policy *sp, unsigned long idx) if (!sp->root.rb_node) return NULL; - spin_lock(&sp->lock); + read_lock(&sp->lock); sn = sp_lookup(sp, idx, idx+1); if (sn) { mpol_get(sn->policy); pol = sn->policy; } - spin_unlock(&sp->lock); + read_unlock(&sp->lock); return pol; } @@ -2360,7 +2364,7 @@ static int shared_policy_replace(struct shared_policy *sp, unsigned long start, int ret = 0; restart: - spin_lock(&sp->lock); + write_lock(&sp->lock); n = sp_lookup(sp, start, end); /* Take care of old policies in the same range. */ while (n && n->start < end) { @@ -2393,7 +2397,7 @@ restart: } if (new) sp_insert(sp, new); - spin_unlock(&sp->lock); + write_unlock(&sp->lock); ret = 0; err_out: @@ -2405,7 +2409,7 @@ err_out: return ret; alloc_new: - spin_unlock(&sp->lock); + write_unlock(&sp->lock); ret = -ENOMEM; n_new = kmem_cache_alloc(sn_cache, GFP_KERNEL); if (!n_new) @@ -2431,7 +2435,7 @@ void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol) int ret; sp->root = RB_ROOT; /* empty tree == default mempolicy */ - spin_lock_init(&sp->lock); + rwlock_init(&sp->lock); if (mpol) { struct vm_area_struct pvma; @@ -2497,14 +2501,14 @@ void mpol_free_shared_policy(struct shared_policy *p) if (!p->root.rb_node) return; - spin_lock(&p->lock); + write_lock(&p->lock); next = rb_first(&p->root); while (next) { n = rb_entry(next, struct sp_node, nd); next = rb_next(&n->nd); sp_delete(p, n); } - spin_unlock(&p->lock); + write_unlock(&p->lock); } #ifdef CONFIG_NUMA_BALANCING -- GitLab From fea85cff11de4377040deff0e85eb2793fb078aa Mon Sep 17 00:00:00 2001 From: Joonsoo Kim Date: Thu, 14 Jan 2016 15:18:39 -0800 Subject: [PATCH 2761/2855] mm/page_isolation.c: return last tested pfn rather than failure indicator This is preparation step to report test failed pfn in new tracepoint to analyze cma allocation failure problem. There is no functional change in this patch. Signed-off-by: Joonsoo Kim Acked-by: David Rientjes Acked-by: Michal Nazarewicz Cc: Minchan Kim Acked-by: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_isolation.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/mm/page_isolation.c b/mm/page_isolation.c index 4568fd58f70a0..029a171d35dcb 100644 --- a/mm/page_isolation.c +++ b/mm/page_isolation.c @@ -212,7 +212,7 @@ int undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn, * * Returns 1 if all pages in the range are isolated. */ -static int +static unsigned long __test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn, bool skip_hwpoisoned_pages) { @@ -237,9 +237,8 @@ __test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn, else break; } - if (pfn < end_pfn) - return 0; - return 1; + + return pfn; } int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn, @@ -248,7 +247,6 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn, unsigned long pfn, flags; struct page *page; struct zone *zone; - int ret; /* * Note: pageblock_nr_pages != MAX_ORDER. Then, chunks of free pages @@ -266,10 +264,11 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn, /* Check all pages are free or marked as ISOLATED */ zone = page_zone(page); spin_lock_irqsave(&zone->lock, flags); - ret = __test_page_isolated_in_pageblock(start_pfn, end_pfn, + pfn = __test_page_isolated_in_pageblock(start_pfn, end_pfn, skip_hwpoisoned_pages); spin_unlock_irqrestore(&zone->lock, flags); - return ret ? 0 : -EBUSY; + + return pfn < end_pfn ? -EBUSY : 0; } struct page *alloc_migrate_target(struct page *page, unsigned long private, -- GitLab From 0f0848e5118a4cb2cb92cef0c3af6f647649ff47 Mon Sep 17 00:00:00 2001 From: Joonsoo Kim Date: Thu, 14 Jan 2016 15:18:42 -0800 Subject: [PATCH 2762/2855] mm/page_isolation.c: add new tracepoint, test_pages_isolated cma allocation should be guranteeded to succeed. But sometimes it can fail in the current implementation. To track down the problem, we need to know which page is problematic and this new tracepoint will report it. Signed-off-by: Joonsoo Kim Acked-by: Michal Nazarewicz Acked-by: David Rientjes Cc: Minchan Kim Acked-by: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/trace/events/page_isolation.h | 38 +++++++++++++++++++++++++++ mm/page_isolation.c | 5 ++++ 2 files changed, 43 insertions(+) create mode 100644 include/trace/events/page_isolation.h diff --git a/include/trace/events/page_isolation.h b/include/trace/events/page_isolation.h new file mode 100644 index 0000000000000..6fb644029c801 --- /dev/null +++ b/include/trace/events/page_isolation.h @@ -0,0 +1,38 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM page_isolation + +#if !defined(_TRACE_PAGE_ISOLATION_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_PAGE_ISOLATION_H + +#include + +TRACE_EVENT(test_pages_isolated, + + TP_PROTO( + unsigned long start_pfn, + unsigned long end_pfn, + unsigned long fin_pfn), + + TP_ARGS(start_pfn, end_pfn, fin_pfn), + + TP_STRUCT__entry( + __field(unsigned long, start_pfn) + __field(unsigned long, end_pfn) + __field(unsigned long, fin_pfn) + ), + + TP_fast_assign( + __entry->start_pfn = start_pfn; + __entry->end_pfn = end_pfn; + __entry->fin_pfn = fin_pfn; + ), + + TP_printk("start_pfn=0x%lx end_pfn=0x%lx fin_pfn=0x%lx ret=%s", + __entry->start_pfn, __entry->end_pfn, __entry->fin_pfn, + __entry->end_pfn == __entry->fin_pfn ? "success" : "fail") +); + +#endif /* _TRACE_PAGE_ISOLATION_H */ + +/* This part must be outside protection */ +#include diff --git a/mm/page_isolation.c b/mm/page_isolation.c index 029a171d35dcb..f484b9300fe32 100644 --- a/mm/page_isolation.c +++ b/mm/page_isolation.c @@ -9,6 +9,9 @@ #include #include "internal.h" +#define CREATE_TRACE_POINTS +#include + static int set_migratetype_isolate(struct page *page, bool skip_hwpoisoned_pages) { @@ -268,6 +271,8 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn, skip_hwpoisoned_pages); spin_unlock_irqrestore(&zone->lock, flags); + trace_test_pages_isolated(start_pfn, end_pfn, pfn); + return pfn < end_pfn ? -EBUSY : 0; } -- GitLab From 8ef5849fa8a2c7894885e27ee8c8fe06e21a88fd Mon Sep 17 00:00:00 2001 From: Joonsoo Kim Date: Thu, 14 Jan 2016 15:18:45 -0800 Subject: [PATCH 2763/2855] mm/cma: always check which page caused allocation failure Now, we have tracepoint in test_pages_isolated() to notify pfn which cannot be isolated. But, in alloc_contig_range(), some error path doesn't call test_pages_isolated() so it's still hard to know exact pfn that causes allocation failure. This patch change this situation by calling test_pages_isolated() in almost error path. In allocation failure case, some overhead is added by this change, but, allocation failure is really rare event so it would not matter. In fatal signal pending case, we don't call test_pages_isolated() because this failure is intentional one. There was a bogus outer_start problem due to unchecked buddy order and this patch also fix it. Before this patch, it didn't matter, because end result is same thing. But, after this patch, tracepoint will report failed pfn so it should be accurate. Signed-off-by: Joonsoo Kim Acked-by: Vlastimil Babka Acked-by: Michal Nazarewicz Cc: David Rientjes Cc: Minchan Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index ca58bfcdadac9..2f6d30db4c945 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -6725,8 +6725,12 @@ int alloc_contig_range(unsigned long start, unsigned long end, if (ret) return ret; + /* + * In case of -EBUSY, we'd like to know which page causes problem. + * So, just fall through. We will check it in test_pages_isolated(). + */ ret = __alloc_contig_migrate_range(&cc, start, end); - if (ret) + if (ret && ret != -EBUSY) goto done; /* @@ -6753,12 +6757,25 @@ int alloc_contig_range(unsigned long start, unsigned long end, outer_start = start; while (!PageBuddy(pfn_to_page(outer_start))) { if (++order >= MAX_ORDER) { - ret = -EBUSY; - goto done; + outer_start = start; + break; } outer_start &= ~0UL << order; } + if (outer_start != start) { + order = page_order(pfn_to_page(outer_start)); + + /* + * outer_start page could be small order buddy page and + * it doesn't include start page. Adjust outer_start + * in this case to report failed page properly + * on tracepoint in test_pages_isolated() + */ + if (outer_start + (1UL << order) <= start) + outer_start = start; + } + /* Make sure the range is really isolated. */ if (test_pages_isolated(outer_start, end, false)) { pr_info("%s: [%lx, %lx) PFNs busy\n", -- GitLab From ba5e9579433aefcdccdec207601e124d3bdf2a71 Mon Sep 17 00:00:00 2001 From: yalin wang Date: Thu, 14 Jan 2016 15:18:48 -0800 Subject: [PATCH 2764/2855] mm: change mm_vmscan_lru_shrink_inactive() proto types Move node_id zone_idx shrink flags into trace function, so thay we don't need caculate these args if the trace is disabled, and will make this function have less arguments. Signed-off-by: yalin wang Reviewed-by: Steven Rostedt Acked-by: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/trace/events/vmscan.h | 14 +++++++------- mm/vmscan.c | 7 ++----- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h index dae7836e1f51c..31763dd8db1ce 100644 --- a/include/trace/events/vmscan.h +++ b/include/trace/events/vmscan.h @@ -352,11 +352,11 @@ TRACE_EVENT(mm_vmscan_writepage, TRACE_EVENT(mm_vmscan_lru_shrink_inactive, - TP_PROTO(int nid, int zid, - unsigned long nr_scanned, unsigned long nr_reclaimed, - int priority, int reclaim_flags), + TP_PROTO(struct zone *zone, + unsigned long nr_scanned, unsigned long nr_reclaimed, + int priority, int file), - TP_ARGS(nid, zid, nr_scanned, nr_reclaimed, priority, reclaim_flags), + TP_ARGS(zone, nr_scanned, nr_reclaimed, priority, file), TP_STRUCT__entry( __field(int, nid) @@ -368,12 +368,12 @@ TRACE_EVENT(mm_vmscan_lru_shrink_inactive, ), TP_fast_assign( - __entry->nid = nid; - __entry->zid = zid; + __entry->nid = zone_to_nid(zone); + __entry->zid = zone_idx(zone); __entry->nr_scanned = nr_scanned; __entry->nr_reclaimed = nr_reclaimed; __entry->priority = priority; - __entry->reclaim_flags = reclaim_flags; + __entry->reclaim_flags = trace_shrink_flags(file); ), TP_printk("nid=%d zid=%d nr_scanned=%ld nr_reclaimed=%ld priority=%d flags=%s", diff --git a/mm/vmscan.c b/mm/vmscan.c index fd7823ccf301f..35dd57e992827 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1691,11 +1691,8 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec, current_may_throttle()) wait_iff_congested(zone, BLK_RW_ASYNC, HZ/10); - trace_mm_vmscan_lru_shrink_inactive(zone->zone_pgdat->node_id, - zone_idx(zone), - nr_scanned, nr_reclaimed, - sc->priority, - trace_shrink_flags(file)); + trace_mm_vmscan_lru_shrink_inactive(zone, nr_scanned, nr_reclaimed, + sc->priority, file); return nr_reclaimed; } -- GitLab From 719ff32162865522273d8fa975bf99b32875738b Mon Sep 17 00:00:00 2001 From: Yaowei Bai Date: Thu, 14 Jan 2016 15:18:51 -0800 Subject: [PATCH 2765/2855] include/linux/hugetlb.h: is_file_hugepages() can be boolean Make is_file_hugepages() return bool to improve readability due to this particular function only using either one or zero as its return value. This patch also removed the if condition to make is_file_hugepages return directly. No functional change. Signed-off-by: Yaowei Bai Acked-by: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/hugetlb.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index b0eb06423d5ec..e76574d8f9b58 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -263,20 +263,18 @@ struct file *hugetlb_file_setup(const char *name, size_t size, vm_flags_t acct, struct user_struct **user, int creat_flags, int page_size_log); -static inline int is_file_hugepages(struct file *file) +static inline bool is_file_hugepages(struct file *file) { if (file->f_op == &hugetlbfs_file_operations) - return 1; - if (is_file_shm_hugepages(file)) - return 1; + return true; - return 0; + return is_file_shm_hugepages(file); } #else /* !CONFIG_HUGETLBFS */ -#define is_file_hugepages(file) 0 +#define is_file_hugepages(file) false static inline struct file * hugetlb_file_setup(const char *name, size_t size, vm_flags_t acctflag, struct user_struct **user, int creat_flags, -- GitLab From b4ad0c7e004a2cc0e52790eff72f5176b59ca386 Mon Sep 17 00:00:00 2001 From: Yaowei Bai Date: Thu, 14 Jan 2016 15:18:54 -0800 Subject: [PATCH 2766/2855] mm/memblock.c: memblock_is_memory()/reserved() can be boolean Make memblock_is_memory() and memblock_is_reserved return bool to improve readability due to these particular functions only using either one or zero as their return value. No functional change. Signed-off-by: Yaowei Bai Acked-by: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memblock.h | 4 ++-- mm/memblock.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/memblock.h b/include/linux/memblock.h index fec66f86eeffe..3a092fba2eb21 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -325,10 +325,10 @@ phys_addr_t memblock_mem_size(unsigned long limit_pfn); phys_addr_t memblock_start_of_DRAM(void); phys_addr_t memblock_end_of_DRAM(void); void memblock_enforce_memory_limit(phys_addr_t memory_limit); -int memblock_is_memory(phys_addr_t addr); +bool memblock_is_memory(phys_addr_t addr); int memblock_is_map_memory(phys_addr_t addr); int memblock_is_region_memory(phys_addr_t base, phys_addr_t size); -int memblock_is_reserved(phys_addr_t addr); +bool memblock_is_reserved(phys_addr_t addr); bool memblock_is_region_reserved(phys_addr_t base, phys_addr_t size); extern void __memblock_dump_all(void); diff --git a/mm/memblock.c b/mm/memblock.c index 07ff069fef256..9695398a14c04 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -1528,12 +1528,12 @@ static int __init_memblock memblock_search(struct memblock_type *type, phys_addr return -1; } -int __init memblock_is_reserved(phys_addr_t addr) +bool __init memblock_is_reserved(phys_addr_t addr) { return memblock_search(&memblock.reserved, addr) != -1; } -int __init_memblock memblock_is_memory(phys_addr_t addr) +bool __init_memblock memblock_is_memory(phys_addr_t addr) { return memblock_search(&memblock.memory, addr) != -1; } -- GitLab From 06640290bfc6688062387f915c5df094e9872133 Mon Sep 17 00:00:00 2001 From: Yaowei Bai Date: Thu, 14 Jan 2016 15:18:57 -0800 Subject: [PATCH 2767/2855] include/linux/mmzone.h: remove unused is_unevictable_lru() Since commit a0b8cab3b9b2 ("mm: remove lru parameter from __pagevec_lru_add and remove parts of pagevec API") there's no user of this function anymore, so remove it. Signed-off-by: Yaowei Bai Acked-by: Michal Hocko Acked-by: Hillf Danton Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index e23a9e7045362..996384672c732 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -195,11 +195,6 @@ static inline int is_active_lru(enum lru_list lru) return (lru == LRU_ACTIVE_ANON || lru == LRU_ACTIVE_FILE); } -static inline int is_unevictable_lru(enum lru_list lru) -{ - return (lru == LRU_UNEVICTABLE); -} - struct zone_reclaim_stat { /* * The pageout code in vmscan.c keeps track of how many of the -- GitLab From c00eb15a8914b8ba84032a36044a5aaf7f71709d Mon Sep 17 00:00:00 2001 From: Yaowei Bai Date: Thu, 14 Jan 2016 15:19:00 -0800 Subject: [PATCH 2768/2855] mm/zonelist: enumerate zonelists array index Hardcoding index to zonelists array in gfp_zonelist() is not a good idea, let's enumerate it to improve readability. No functional change. [akpm@linux-foundation.org: coding-style fixes] [akpm@linux-foundation.org: fix CONFIG_NUMA=n build] [n-horiguchi@ah.jp.nec.com: fix warning in comparing enumerator] Signed-off-by: Yaowei Bai Cc: Michal Hocko Cc: David Rientjes Signed-off-by: Naoya Horiguchi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/gfp.h | 9 +++++---- include/linux/mmzone.h | 20 +++++++++----------- mm/page_alloc.c | 9 ++++----- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 1dd59abe541d2..91f74e741aa2d 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -384,10 +384,11 @@ static inline enum zone_type gfp_zone(gfp_t flags) static inline int gfp_zonelist(gfp_t flags) { - if (IS_ENABLED(CONFIG_NUMA) && unlikely(flags & __GFP_THISNODE)) - return 1; - - return 0; +#ifdef CONFIG_NUMA + if (unlikely(flags & __GFP_THISNODE)) + return ZONELIST_NOFALLBACK; +#endif + return ZONELIST_FALLBACK; } /* diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 996384672c732..12c98dfc31b14 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -571,19 +571,17 @@ static inline bool zone_is_empty(struct zone *zone) /* Maximum number of zones on a zonelist */ #define MAX_ZONES_PER_ZONELIST (MAX_NUMNODES * MAX_NR_ZONES) +enum { + ZONELIST_FALLBACK, /* zonelist with fallback */ #ifdef CONFIG_NUMA - -/* - * The NUMA zonelists are doubled because we need zonelists that restrict the - * allocations to a single node for __GFP_THISNODE. - * - * [0] : Zonelist with fallback - * [1] : No fallback (__GFP_THISNODE) - */ -#define MAX_ZONELISTS 2 -#else -#define MAX_ZONELISTS 1 + /* + * The NUMA zonelists are doubled because we need zonelists that + * restrict the allocations to a single node for __GFP_THISNODE. + */ + ZONELIST_NOFALLBACK, /* zonelist without fallback (__GFP_THISNODE) */ #endif + MAX_ZONELISTS +}; /* * This struct contains information about a zone in a zonelist. It is stored diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 2f6d30db4c945..e40e702ce919a 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -4148,8 +4148,7 @@ static void set_zonelist_order(void) static void build_zonelists(pg_data_t *pgdat) { - int j, node, load; - enum zone_type i; + int i, node, load; nodemask_t used_mask; int local_node, prev_node; struct zonelist *zonelist; @@ -4169,7 +4168,7 @@ static void build_zonelists(pg_data_t *pgdat) nodes_clear(used_mask); memset(node_order, 0, sizeof(node_order)); - j = 0; + i = 0; while ((node = find_next_best_node(local_node, &used_mask)) >= 0) { /* @@ -4186,12 +4185,12 @@ static void build_zonelists(pg_data_t *pgdat) if (order == ZONELIST_ORDER_NODE) build_zonelists_in_node_order(pgdat, node); else - node_order[j++] = node; /* remember order */ + node_order[i++] = node; /* remember order */ } if (order == ZONELIST_ORDER_ZONE) { /* calculate node order -- i.e., DMA last! */ - build_zonelists_in_zone_order(pgdat, j); + build_zonelists_in_zone_order(pgdat, i); } build_thisnode_zonelists(pgdat); -- GitLab From fde82aaa731de8a23d817971f6080041a4917d06 Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Thu, 14 Jan 2016 15:19:03 -0800 Subject: [PATCH 2769/2855] mm/page_alloc.c: get rid of __alloc_pages_high_priority() __alloc_pages_high_priority doesn't do anything special other than it calls get_page_from_freelist and loops around GFP_NOFAIL allocation until it succeeds. It would be better if the first part was done in __alloc_pages_slowpath where we modify the zonelist because this would be easier to read and understand. Opencoding the function into its only caller allows to simplify it a bit as well. This patch doesn't introduce any functional changes. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Michal Hocko Acked-by: Mel Gorman Acked-by: David Rientjes Acked-by: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index e40e702ce919a..1f3c26992e90a 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2876,28 +2876,6 @@ retry: return page; } -/* - * This is called in the allocator slow-path if the allocation request is of - * sufficient urgency to ignore watermarks and take other desperate measures - */ -static inline struct page * -__alloc_pages_high_priority(gfp_t gfp_mask, unsigned int order, - const struct alloc_context *ac) -{ - struct page *page; - - do { - page = get_page_from_freelist(gfp_mask, order, - ALLOC_NO_WATERMARKS, ac); - - if (!page && gfp_mask & __GFP_NOFAIL) - wait_iff_congested(ac->preferred_zone, BLK_RW_ASYNC, - HZ/50); - } while (!page && (gfp_mask & __GFP_NOFAIL)); - - return page; -} - static void wake_all_kswapds(unsigned int order, const struct alloc_context *ac) { struct zoneref *z; @@ -3042,12 +3020,16 @@ retry: * allocations are system rather than user orientated */ ac->zonelist = node_zonelist(numa_node_id(), gfp_mask); + do { + page = get_page_from_freelist(gfp_mask, order, + ALLOC_NO_WATERMARKS, ac); + if (page) + goto got_pg; - page = __alloc_pages_high_priority(gfp_mask, order, ac); - - if (page) { - goto got_pg; - } + if (gfp_mask & __GFP_NOFAIL) + wait_iff_congested(ac->preferred_zone, + BLK_RW_ASYNC, HZ/50); + } while (gfp_mask & __GFP_NOFAIL); } /* Caller is not willing to reclaim, we can't balance anything */ -- GitLab From 33d5310306ec244d96533da5f9183e05a7a51106 Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Thu, 14 Jan 2016 15:19:05 -0800 Subject: [PATCH 2770/2855] mm/page_alloc.c: do not loop over ALLOC_NO_WATERMARKS without triggering reclaim __alloc_pages_slowpath is looping over ALLOC_NO_WATERMARKS requests if __GFP_NOFAIL is requested. This is fragile because we are basically relying on somebody else to make the reclaim (be it the direct reclaim or OOM killer) for us. The caller might be holding resources (e.g. locks) which block other other reclaimers from making any progress for example. Remove the retry loop and rely on __alloc_pages_slowpath to invoke all allowed reclaim steps and retry logic. We have to be careful about __GFP_NOFAIL allocations from the PF_MEMALLOC context even though this is a very bad idea to begin with because no progress can be gurateed at all. We shouldn't break the __GFP_NOFAIL semantic here though. It could be argued that this is essentially GFP_NOWAIT context which we do not support but PF_MEMALLOC is much harder to check for existing users because they might happen deep down the code path performed much later after setting the flag so we cannot really rule out there is no kernel path triggering this combination. Signed-off-by: Michal Hocko Acked-by: Mel Gorman Acked-by: David Rientjes Cc: Tetsuo Handa Acked-by: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 1f3c26992e90a..2a6fe377cafcb 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -3020,32 +3020,36 @@ retry: * allocations are system rather than user orientated */ ac->zonelist = node_zonelist(numa_node_id(), gfp_mask); - do { - page = get_page_from_freelist(gfp_mask, order, - ALLOC_NO_WATERMARKS, ac); - if (page) - goto got_pg; - - if (gfp_mask & __GFP_NOFAIL) - wait_iff_congested(ac->preferred_zone, - BLK_RW_ASYNC, HZ/50); - } while (gfp_mask & __GFP_NOFAIL); + page = get_page_from_freelist(gfp_mask, order, + ALLOC_NO_WATERMARKS, ac); + if (page) + goto got_pg; } /* Caller is not willing to reclaim, we can't balance anything */ if (!can_direct_reclaim) { /* - * All existing users of the deprecated __GFP_NOFAIL are - * blockable, so warn of any new users that actually allow this - * type of allocation to fail. + * All existing users of the __GFP_NOFAIL are blockable, so warn + * of any new users that actually allow this type of allocation + * to fail. */ WARN_ON_ONCE(gfp_mask & __GFP_NOFAIL); goto nopage; } /* Avoid recursion of direct reclaim */ - if (current->flags & PF_MEMALLOC) + if (current->flags & PF_MEMALLOC) { + /* + * __GFP_NOFAIL request from this context is rather bizarre + * because we cannot reclaim anything and only can loop waiting + * for somebody to do a work for us. + */ + if (WARN_ON_ONCE(gfp_mask & __GFP_NOFAIL)) { + cond_resched(); + goto retry; + } goto nopage; + } /* Avoid allocations with no watermarks from looping endlessly */ if (test_thread_flag(TIF_MEMDIE) && !(gfp_mask & __GFP_NOFAIL)) -- GitLab From 6219c2a2ec990f80a586216172c811a9099c5cdf Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 14 Jan 2016 15:19:08 -0800 Subject: [PATCH 2771/2855] mm/vmalloc.c: use list_{next,first}_entry To make the intention clearer, use list_{next,first}_entry instead of list_entry. Signed-off-by: Geliang Tang Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmalloc.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 9a58f9a1874df..7007fe85840ee 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -441,8 +441,7 @@ nocache: if (list_is_last(&first->list, &vmap_area_list)) goto found; - first = list_entry(first->list.next, - struct vmap_area, list); + first = list_next_entry(first, list); } found: @@ -2559,10 +2558,10 @@ static void *s_start(struct seq_file *m, loff_t *pos) struct vmap_area *va; spin_lock(&vmap_area_lock); - va = list_entry((&vmap_area_list)->next, typeof(*va), list); + va = list_first_entry(&vmap_area_list, typeof(*va), list); while (n > 0 && &va->list != &vmap_area_list) { n--; - va = list_entry(va->list.next, typeof(*va), list); + va = list_next_entry(va, list); } if (!n && &va->list != &vmap_area_list) return va; @@ -2576,7 +2575,7 @@ static void *s_next(struct seq_file *m, void *p, loff_t *pos) struct vmap_area *va = p, *next; ++*pos; - next = list_entry(va->list.next, typeof(*va), list); + next = list_next_entry(va, list); if (&next->list != &vmap_area_list) return next; -- GitLab From 5b80287a65da927742c6d43b1369bd5ed133aad1 Mon Sep 17 00:00:00 2001 From: Yaowei Bai Date: Thu, 14 Jan 2016 15:19:11 -0800 Subject: [PATCH 2772/2855] mm/mmzone.c: memmap_valid_within() can be boolean Make memmap_valid_within return bool due to this particular function only using either one or zero as its return value. No functional change. Signed-off-by: Yaowei Bai Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 6 +++--- mm/mmzone.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 12c98dfc31b14..3b6fb71bbeb31 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -1200,13 +1200,13 @@ unsigned long __init node_memmap_size_bytes(int, unsigned long, unsigned long); * the zone and PFN linkages are still valid. This is expensive, but walkers * of the full memmap are extremely rare. */ -int memmap_valid_within(unsigned long pfn, +bool memmap_valid_within(unsigned long pfn, struct page *page, struct zone *zone); #else -static inline int memmap_valid_within(unsigned long pfn, +static inline bool memmap_valid_within(unsigned long pfn, struct page *page, struct zone *zone) { - return 1; + return true; } #endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */ diff --git a/mm/mmzone.c b/mm/mmzone.c index 7d87ebb0d6324..52687fb4de6f4 100644 --- a/mm/mmzone.c +++ b/mm/mmzone.c @@ -72,16 +72,16 @@ struct zoneref *next_zones_zonelist(struct zoneref *z, } #ifdef CONFIG_ARCH_HAS_HOLES_MEMORYMODEL -int memmap_valid_within(unsigned long pfn, +bool memmap_valid_within(unsigned long pfn, struct page *page, struct zone *zone) { if (page_to_pfn(page) != pfn) - return 0; + return false; if (page_zone(page) != zone) - return 0; + return false; - return 1; + return true; } #endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */ -- GitLab From bf9683d6990589390b5178dafe8fd06808869293 Mon Sep 17 00:00:00 2001 From: Vlastimil Babka Date: Thu, 14 Jan 2016 15:19:14 -0800 Subject: [PATCH 2773/2855] mm, documentation: clarify /proc/pid/status VmSwap limitations for shmem This series is based on Jerome Marchand's [1] so let me quote the first paragraph from there: There are several shortcomings with the accounting of shared memory (sysV shm, shared anonymous mapping, mapping to a tmpfs file). The values in /proc//status and statm don't allow to distinguish between shmem memory and a shared mapping to a regular file, even though their implications on memory usage are quite different: at reclaim, file mapping can be dropped or written back on disk while shmem needs a place in swap. As for shmem pages that are swapped-out or in swap cache, they aren't accounted at all. The original motivation for myself is that a customer found (IMHO rightfully) confusing that e.g. top output for process swap usage is unreliable with respect to swapped out shmem pages, which are not accounted for. The fundamental difference between private anonymous and shmem pages is that the latter has PTE's converted to pte_none, and not swapents. As such, they are not accounted to the number of swapents visible e.g. in /proc/pid/status VmSwap row. It might be theoretically possible to use swapents when swapping out shmem (without extra cost, as one has to change all mappers anyway), and on swap in only convert the swapent for the faulting process, leaving swapents in other processes until they also fault (so again no extra cost). But I don't know how many assumptions this would break, and it would be too disruptive change for a relatively small benefit. Instead, my approach is to document the limitation of VmSwap, and provide means to determine the swap usage for shmem areas for those who are interested and willing to pay the price, using /proc/pid/smaps. Because outside of ipcs, I don't think it's possible to currently to determine the usage at all. The previous patchset [1] did introduce new shmem-specific fields into smaps output, and functions to determine the values. I take a simpler approach, noting that smaps output already has a "Swap: X kB" line, where currently X == 0 always for shmem areas. I think we can just consider this a bug and provide the proper value by consulting the radix tree, as e.g. mincore_page() does. In the patch changelog I explain why this is also not perfect (and cannot be without swapents), but still arguably much better than showing a 0. The last two patches are adapted from Jerome's patchset and provide a VmRSS breakdown to RssAnon, RssFile and RssShm in /proc/pid/status. Hugh noted that this is a welcome addition, and I agree that it might help e.g. debugging process memory usage at albeit non-zero, but still rather low cost of extra per-mm counter and some page flag checks. [1] http://lwn.net/Articles/611966/ This patch (of 6): The documentation for /proc/pid/status does not mention that the value of VmSwap counts only swapped out anonymous private pages, and not swapped out pages of the underlying shmem objects (for shmem mappings). This is not obvious, so document this limitation. Signed-off-by: Vlastimil Babka Acked-by: Konstantin Khlebnikov Acked-by: Michal Hocko Acked-by: Jerome Marchand Acked-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/filesystems/proc.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 402ab99e409fa..9f13b6e28676c 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -238,7 +238,8 @@ Table 1-2: Contents of the status files (as of 4.1) VmLib size of shared library code VmPTE size of page table entries VmPMD size of second level page tables - VmSwap size of swap usage (the number of referred swapents) + VmSwap amount of swap used by anonymous private data + (shmem swap usage is not included) HugetlbPages size of hugetlb memory portions Threads number of threads SigQ number of signals queued/max. number for queue -- GitLab From c261e7d94f0dd33a34b6cf98686e8b9699b62340 Mon Sep 17 00:00:00 2001 From: Vlastimil Babka Date: Thu, 14 Jan 2016 15:19:17 -0800 Subject: [PATCH 2774/2855] mm, proc: account for shmem swap in /proc/pid/smaps Currently, /proc/pid/smaps will always show "Swap: 0 kB" for shmem-backed mappings, even if the mapped portion does contain pages that were swapped out. This is because unlike private anonymous mappings, shmem does not change pte to swap entry, but pte_none when swapping the page out. In the smaps page walk, such page thus looks like it was never faulted in. This patch changes smaps_pte_entry() to determine the swap status for such pte_none entries for shmem mappings, similarly to how mincore_page() does it. Swapped out shmem pages are thus accounted for. For private mappings of tmpfs files that COWed some of the pages, swaped out status of the original shmem pages is naturally ignored. If some of the private copies was also swapped out, they are accounted via their page table swap entries, so the resulting reported swap usage is then a sum of both swapped out private copies, and swapped out shmem pages that were not COWed. No double accounting can thus happen. The accounting is arguably still not as precise as for private anonymous mappings, since now we will count also pages that the process in question never accessed, but another process populated them and then let them become swapped out. I believe it is still less confusing and subtle than not showing any swap usage by shmem mappings at all. Swapped out counter might of interest of users who would like to prevent from future swapins during performance critical operation and pre-fault them at their convenience. Especially for larger swapped out regions the cost of swapin is much higher than a fresh page allocation. So a differentiation between pte_none vs. swapped out is important for those usecases. One downside of this patch is that it makes /proc/pid/smaps more expensive for shmem mappings, as we consult the radix tree for each pte_none entry, so the overal complexity is O(n*log(n)). I have measured this on a process that creates a 2GB mapping and dirties single pages with a stride of 2MB, and time how long does it take to cat /proc/pid/smaps of this process 100 times. Private anonymous mapping: real 0m0.949s user 0m0.116s sys 0m0.348s Mapping of a /dev/shm/file: real 0m3.831s user 0m0.180s sys 0m3.212s The difference is rather substantial, so the next patch will reduce the cost for shared or read-only mappings. In a less controlled experiment, I've gathered pids of processes on my desktop that have either '/dev/shm/*' or 'SYSV*' in smaps. This included the Chrome browser and some KDE processes. Again, I've run cat /proc/pid/smaps on each 100 times. Before this patch: real 0m9.050s user 0m0.518s sys 0m8.066s After this patch: real 0m9.221s user 0m0.541s sys 0m8.187s This suggests low impact on average systems. Note that this patch doesn't attempt to adjust the SwapPss field for shmem mappings, which would need extra work to determine who else could have the pages mapped. Thus the value stays zero except for COWed swapped out pages in a shmem mapping, which are accounted as usual. Signed-off-by: Vlastimil Babka Acked-by: Konstantin Khlebnikov Acked-by: Jerome Marchand Acked-by: Michal Hocko Cc: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/filesystems/proc.txt | 5 ++- fs/proc/task_mmu.c | 51 ++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 9f13b6e28676c..fdeb5b33349f4 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -460,7 +460,10 @@ and a page is modified, the file page is replaced by a private anonymous copy. hugetlbfs page which is *not* counted in "RSS" or "PSS" field for historical reasons. And these are not included in {Shared,Private}_{Clean,Dirty} field. "Swap" shows how much would-be-anonymous memory is also used, but out on swap. -"SwapPss" shows proportional swap share of this mapping. +For shmem mappings, "Swap" includes also the size of the mapped (and not +replaced by copy-on-write) part of the underlying shmem object out on swap. +"SwapPss" shows proportional swap share of this mapping. Unlike "Swap", this +does not take into account swapped out page of underlying shmem objects. "Locked" indicates whether the mapping is locked in memory or not. "VmFlags" field deserves a separate description. This member represents the kernel diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 187b3b5f242ef..85ef60fdf2c01 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -451,6 +451,7 @@ struct mem_size_stats { unsigned long private_hugetlb; u64 pss; u64 swap_pss; + bool check_shmem_swap; }; static void smaps_account(struct mem_size_stats *mss, struct page *page, @@ -485,6 +486,45 @@ static void smaps_account(struct mem_size_stats *mss, struct page *page, } } +#ifdef CONFIG_SHMEM +static unsigned long smaps_shmem_swap(struct vm_area_struct *vma, + unsigned long addr) +{ + struct page *page; + + page = find_get_entry(vma->vm_file->f_mapping, + linear_page_index(vma, addr)); + if (!page) + return 0; + + if (radix_tree_exceptional_entry(page)) + return PAGE_SIZE; + + page_cache_release(page); + return 0; + +} + +static int smaps_pte_hole(unsigned long addr, unsigned long end, + struct mm_walk *walk) +{ + struct mem_size_stats *mss = walk->private; + + while (addr < end) { + mss->swap += smaps_shmem_swap(walk->vma, addr); + addr += PAGE_SIZE; + } + + return 0; +} +#else +static unsigned long smaps_shmem_swap(struct vm_area_struct *vma, + unsigned long addr) +{ + return 0; +} +#endif + static void smaps_pte_entry(pte_t *pte, unsigned long addr, struct mm_walk *walk) { @@ -512,6 +552,9 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr, } } else if (is_migration_entry(swpent)) page = migration_entry_to_page(swpent); + } else if (unlikely(IS_ENABLED(CONFIG_SHMEM) && mss->check_shmem_swap + && pte_none(*pte))) { + mss->swap += smaps_shmem_swap(vma, addr); } if (!page) @@ -671,6 +714,14 @@ static int show_smap(struct seq_file *m, void *v, int is_pid) }; memset(&mss, 0, sizeof mss); + +#ifdef CONFIG_SHMEM + if (vma->vm_file && shmem_mapping(vma->vm_file->f_mapping)) { + mss.check_shmem_swap = true; + smaps_walk.pte_hole = smaps_pte_hole; + } +#endif + /* mmap_sem is held in m_start */ walk_page_vma(vma, &smaps_walk); -- GitLab From 6a15a37097c7e02390bb08d83dac433c9f10144f Mon Sep 17 00:00:00 2001 From: Vlastimil Babka Date: Thu, 14 Jan 2016 15:19:20 -0800 Subject: [PATCH 2775/2855] mm, proc: reduce cost of /proc/pid/smaps for shmem mappings The previous patch has improved swap accounting for shmem mapping, which however made /proc/pid/smaps more expensive for shmem mappings, as we consult the radix tree for each pte_none entry, so the overal complexity is O(n*log(n)). We can reduce this significantly for mappings that cannot contain COWed pages, because then we can either use the statistics tha shmem object itself tracks (if the mapping contains the whole object, or the swap usage of the whole object is zero), or use the radix tree iterator, which is much more effective than repeated find_get_entry() calls. This patch therefore introduces a function shmem_swap_usage(vma) and makes /proc/pid/smaps use it when possible. Only for writable private mappings of shmem objects (i.e. tmpfs files) with the shmem object itself (partially) swapped outwe have to resort to the find_get_entry() approach. Hopefully such mappings are relatively uncommon. To demonstrate the diference, I have measured this on a process that creates a 2GB mapping and dirties single pages with a stride of 2MB, and time how long does it take to cat /proc/pid/smaps of this process 100 times. Private writable mapping of a /dev/shm/file (the most complex case): real 0m3.831s user 0m0.180s sys 0m3.212s Shared mapping of an almost full mapping of a partially swapped /dev/shm/file (which needs to employ the radix tree iterator). real 0m1.351s user 0m0.096s sys 0m0.768s Same, but with /dev/shm/file not swapped (so no radix tree walk needed) real 0m0.935s user 0m0.128s sys 0m0.344s Private anonymous mapping: real 0m0.949s user 0m0.116s sys 0m0.348s The cost is now much closer to the private anonymous mapping case, unless the shmem mapping is private and writable. Signed-off-by: Vlastimil Babka Cc: Hugh Dickins Cc: Jerome Marchand Cc: Konstantin Khlebnikov Acked-by: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/task_mmu.c | 22 +++++++++++-- include/linux/shmem_fs.h | 2 ++ mm/shmem.c | 70 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 2 deletions(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 85ef60fdf2c01..5830b2e129ed0 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -717,8 +718,25 @@ static int show_smap(struct seq_file *m, void *v, int is_pid) #ifdef CONFIG_SHMEM if (vma->vm_file && shmem_mapping(vma->vm_file->f_mapping)) { - mss.check_shmem_swap = true; - smaps_walk.pte_hole = smaps_pte_hole; + /* + * For shared or readonly shmem mappings we know that all + * swapped out pages belong to the shmem object, and we can + * obtain the swap value much more efficiently. For private + * writable mappings, we might have COW pages that are + * not affected by the parent swapped out pages of the shmem + * object, so we have to distinguish them during the page walk. + * Unless we know that the shmem object (or the part mapped by + * our VMA) has no swapped out pages at all. + */ + unsigned long shmem_swapped = shmem_swap_usage(vma); + + if (!shmem_swapped || (vma->vm_flags & VM_SHARED) || + !(vma->vm_flags & VM_WRITE)) { + mss.swap = shmem_swapped; + } else { + mss.check_shmem_swap = true; + smaps_walk.pte_hole = smaps_pte_hole; + } } #endif diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index 50777b5b1e4c3..bd58be5e7a2a3 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -60,6 +60,8 @@ extern struct page *shmem_read_mapping_page_gfp(struct address_space *mapping, extern void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end); extern int shmem_unuse(swp_entry_t entry, struct page *page); +extern unsigned long shmem_swap_usage(struct vm_area_struct *vma); + static inline struct page *shmem_read_mapping_page( struct address_space *mapping, pgoff_t index) { diff --git a/mm/shmem.c b/mm/shmem.c index 9e60093aca3fd..e978621de1ef3 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -359,6 +359,76 @@ static int shmem_free_swap(struct address_space *mapping, return 0; } +/* + * Determine (in bytes) how many of the shmem object's pages mapped by the + * given vma is swapped out. + * + * This is safe to call without i_mutex or mapping->tree_lock thanks to RCU, + * as long as the inode doesn't go away and racy results are not a problem. + */ +unsigned long shmem_swap_usage(struct vm_area_struct *vma) +{ + struct inode *inode = file_inode(vma->vm_file); + struct shmem_inode_info *info = SHMEM_I(inode); + struct address_space *mapping = inode->i_mapping; + unsigned long swapped; + pgoff_t start, end; + struct radix_tree_iter iter; + void **slot; + struct page *page; + + /* Be careful as we don't hold info->lock */ + swapped = READ_ONCE(info->swapped); + + /* + * The easier cases are when the shmem object has nothing in swap, or + * the vma maps it whole. Then we can simply use the stats that we + * already track. + */ + if (!swapped) + return 0; + + if (!vma->vm_pgoff && vma->vm_end - vma->vm_start >= inode->i_size) + return swapped << PAGE_SHIFT; + + swapped = 0; + + /* Here comes the more involved part */ + start = linear_page_index(vma, vma->vm_start); + end = linear_page_index(vma, vma->vm_end); + + rcu_read_lock(); + +restart: + radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) { + if (iter.index >= end) + break; + + page = radix_tree_deref_slot(slot); + + /* + * This should only be possible to happen at index 0, so we + * don't need to reset the counter, nor do we risk infinite + * restarts. + */ + if (radix_tree_deref_retry(page)) + goto restart; + + if (radix_tree_exceptional_entry(page)) + swapped++; + + if (need_resched()) { + cond_resched_rcu(); + start = iter.index + 1; + goto restart; + } + } + + rcu_read_unlock(); + + return swapped << PAGE_SHIFT; +} + /* * SysV IPC SHM_UNLOCK restore Unevictable pages to their evictable lists. */ -- GitLab From 48131e03ca4ed71d73fbe55c311a258c6fa2a090 Mon Sep 17 00:00:00 2001 From: Vlastimil Babka Date: Thu, 14 Jan 2016 15:19:23 -0800 Subject: [PATCH 2776/2855] mm, proc: reduce cost of /proc/pid/smaps for unpopulated shmem mappings Following the previous patch, further reduction of /proc/pid/smaps cost is possible for private writable shmem mappings with unpopulated areas where the page walk invokes the .pte_hole function. We can use radix tree iterator for each such area instead of calling find_get_entry() in a loop. This is possible at the extra maintenance cost of introducing another shmem function shmem_partial_swap_usage(). To demonstrate the diference, I have measured this on a process that creates a private writable 2GB mapping of a partially swapped out /dev/shm/file (which cannot employ the optimizations from the prvious patch) and doesn't populate it at all. I time how long does it take to cat /proc/pid/smaps of this process 100 times. Before this patch: real 0m3.831s user 0m0.180s sys 0m3.212s After this patch: real 0m1.176s user 0m0.180s sys 0m0.684s The time is similar to the case where a radix tree iterator is employed on the whole mapping. Signed-off-by: Vlastimil Babka Cc: Hugh Dickins Cc: Jerome Marchand Cc: Konstantin Khlebnikov Acked-by: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/task_mmu.c | 42 ++++++++------------------ include/linux/shmem_fs.h | 2 ++ mm/shmem.c | 65 +++++++++++++++++++++++----------------- 3 files changed, 53 insertions(+), 56 deletions(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 5830b2e129ed0..8a03759bda384 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -488,42 +488,16 @@ static void smaps_account(struct mem_size_stats *mss, struct page *page, } #ifdef CONFIG_SHMEM -static unsigned long smaps_shmem_swap(struct vm_area_struct *vma, - unsigned long addr) -{ - struct page *page; - - page = find_get_entry(vma->vm_file->f_mapping, - linear_page_index(vma, addr)); - if (!page) - return 0; - - if (radix_tree_exceptional_entry(page)) - return PAGE_SIZE; - - page_cache_release(page); - return 0; - -} - static int smaps_pte_hole(unsigned long addr, unsigned long end, struct mm_walk *walk) { struct mem_size_stats *mss = walk->private; - while (addr < end) { - mss->swap += smaps_shmem_swap(walk->vma, addr); - addr += PAGE_SIZE; - } + mss->swap += shmem_partial_swap_usage( + walk->vma->vm_file->f_mapping, addr, end); return 0; } -#else -static unsigned long smaps_shmem_swap(struct vm_area_struct *vma, - unsigned long addr) -{ - return 0; -} #endif static void smaps_pte_entry(pte_t *pte, unsigned long addr, @@ -555,7 +529,17 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr, page = migration_entry_to_page(swpent); } else if (unlikely(IS_ENABLED(CONFIG_SHMEM) && mss->check_shmem_swap && pte_none(*pte))) { - mss->swap += smaps_shmem_swap(vma, addr); + page = find_get_entry(vma->vm_file->f_mapping, + linear_page_index(vma, addr)); + if (!page) + return; + + if (radix_tree_exceptional_entry(page)) + mss->swap += PAGE_SIZE; + else + page_cache_release(page); + + return; } if (!page) diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index bd58be5e7a2a3..a43f41cb3c430 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -61,6 +61,8 @@ extern void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end); extern int shmem_unuse(swp_entry_t entry, struct page *page); extern unsigned long shmem_swap_usage(struct vm_area_struct *vma); +extern unsigned long shmem_partial_swap_usage(struct address_space *mapping, + pgoff_t start, pgoff_t end); static inline struct page *shmem_read_mapping_page( struct address_space *mapping, pgoff_t index) diff --git a/mm/shmem.c b/mm/shmem.c index e978621de1ef3..760d90cf2a41c 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -361,41 +361,18 @@ static int shmem_free_swap(struct address_space *mapping, /* * Determine (in bytes) how many of the shmem object's pages mapped by the - * given vma is swapped out. + * given offsets are swapped out. * * This is safe to call without i_mutex or mapping->tree_lock thanks to RCU, * as long as the inode doesn't go away and racy results are not a problem. */ -unsigned long shmem_swap_usage(struct vm_area_struct *vma) +unsigned long shmem_partial_swap_usage(struct address_space *mapping, + pgoff_t start, pgoff_t end) { - struct inode *inode = file_inode(vma->vm_file); - struct shmem_inode_info *info = SHMEM_I(inode); - struct address_space *mapping = inode->i_mapping; - unsigned long swapped; - pgoff_t start, end; struct radix_tree_iter iter; void **slot; struct page *page; - - /* Be careful as we don't hold info->lock */ - swapped = READ_ONCE(info->swapped); - - /* - * The easier cases are when the shmem object has nothing in swap, or - * the vma maps it whole. Then we can simply use the stats that we - * already track. - */ - if (!swapped) - return 0; - - if (!vma->vm_pgoff && vma->vm_end - vma->vm_start >= inode->i_size) - return swapped << PAGE_SHIFT; - - swapped = 0; - - /* Here comes the more involved part */ - start = linear_page_index(vma, vma->vm_start); - end = linear_page_index(vma, vma->vm_end); + unsigned long swapped = 0; rcu_read_lock(); @@ -429,6 +406,40 @@ restart: return swapped << PAGE_SHIFT; } +/* + * Determine (in bytes) how many of the shmem object's pages mapped by the + * given vma is swapped out. + * + * This is safe to call without i_mutex or mapping->tree_lock thanks to RCU, + * as long as the inode doesn't go away and racy results are not a problem. + */ +unsigned long shmem_swap_usage(struct vm_area_struct *vma) +{ + struct inode *inode = file_inode(vma->vm_file); + struct shmem_inode_info *info = SHMEM_I(inode); + struct address_space *mapping = inode->i_mapping; + unsigned long swapped; + + /* Be careful as we don't hold info->lock */ + swapped = READ_ONCE(info->swapped); + + /* + * The easier cases are when the shmem object has nothing in swap, or + * the vma maps it whole. Then we can simply use the stats that we + * already track. + */ + if (!swapped) + return 0; + + if (!vma->vm_pgoff && vma->vm_end - vma->vm_start >= inode->i_size) + return swapped << PAGE_SHIFT; + + /* Here comes the more involved part */ + return shmem_partial_swap_usage(mapping, + linear_page_index(vma, vma->vm_start), + linear_page_index(vma, vma->vm_end)); +} + /* * SysV IPC SHM_UNLOCK restore Unevictable pages to their evictable lists. */ -- GitLab From eca56ff906bdd0239485e8b47154a6e73dd9a2f3 Mon Sep 17 00:00:00 2001 From: Jerome Marchand Date: Thu, 14 Jan 2016 15:19:26 -0800 Subject: [PATCH 2777/2855] mm, shmem: add internal shmem resident memory accounting Currently looking at /proc//status or statm, there is no way to distinguish shmem pages from pages mapped to a regular file (shmem pages are mapped to /dev/zero), even though their implication in actual memory use is quite different. The internal accounting currently counts shmem pages together with regular files. As a preparation to extend the userspace interfaces, this patch adds MM_SHMEMPAGES counter to mm_rss_stat to account for shmem pages separately from MM_FILEPAGES. The next patch will expose it to userspace - this patch doesn't change the exported values yet, by adding up MM_SHMEMPAGES to MM_FILEPAGES at places where MM_FILEPAGES was used before. The only user-visible change after this patch is the OOM killer message that separates the reported "shmem-rss" from "file-rss". [vbabka@suse.cz: forward-porting, tweak changelog] Signed-off-by: Jerome Marchand Signed-off-by: Vlastimil Babka Acked-by: Konstantin Khlebnikov Acked-by: Michal Hocko Acked-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/s390/mm/pgtable.c | 5 +---- fs/proc/task_mmu.c | 3 ++- include/linux/mm.h | 18 +++++++++++++++++- include/linux/mm_types.h | 7 ++++--- kernel/events/uprobes.c | 2 +- mm/memory.c | 30 ++++++++++-------------------- mm/oom_kill.c | 5 +++-- mm/rmap.c | 12 +++--------- 8 files changed, 41 insertions(+), 41 deletions(-) diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 63b039899a5ed..aa34af0a0b263 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -603,10 +603,7 @@ static void gmap_zap_swap_entry(swp_entry_t entry, struct mm_struct *mm) else if (is_migration_entry(entry)) { struct page *page = migration_entry_to_page(entry); - if (PageAnon(page)) - dec_mm_counter(mm, MM_ANONPAGES); - else - dec_mm_counter(mm, MM_FILEPAGES); + dec_mm_counter(mm, mm_counter(page)); } free_swap_and_cache(entry); } diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 8a03759bda384..45eb24145978c 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -83,7 +83,8 @@ unsigned long task_statm(struct mm_struct *mm, unsigned long *shared, unsigned long *text, unsigned long *data, unsigned long *resident) { - *shared = get_mm_counter(mm, MM_FILEPAGES); + *shared = get_mm_counter(mm, MM_FILEPAGES) + + get_mm_counter(mm, MM_SHMEMPAGES); *text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> PAGE_SHIFT; *data = mm->total_vm - mm->shared_vm; diff --git a/include/linux/mm.h b/include/linux/mm.h index 00bad7793788b..a8ab1fc0e9bcf 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1361,10 +1361,26 @@ static inline void dec_mm_counter(struct mm_struct *mm, int member) atomic_long_dec(&mm->rss_stat.count[member]); } +/* Optimized variant when page is already known not to be PageAnon */ +static inline int mm_counter_file(struct page *page) +{ + if (PageSwapBacked(page)) + return MM_SHMEMPAGES; + return MM_FILEPAGES; +} + +static inline int mm_counter(struct page *page) +{ + if (PageAnon(page)) + return MM_ANONPAGES; + return mm_counter_file(page); +} + static inline unsigned long get_mm_rss(struct mm_struct *mm) { return get_mm_counter(mm, MM_FILEPAGES) + - get_mm_counter(mm, MM_ANONPAGES); + get_mm_counter(mm, MM_ANONPAGES) + + get_mm_counter(mm, MM_SHMEMPAGES); } static inline unsigned long get_mm_hiwater_rss(struct mm_struct *mm) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index f8d1492a114f4..207890be93c8c 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -369,9 +369,10 @@ struct core_state { }; enum { - MM_FILEPAGES, - MM_ANONPAGES, - MM_SWAPENTS, + MM_FILEPAGES, /* Resident file mapping pages */ + MM_ANONPAGES, /* Resident anonymous pages */ + MM_SWAPENTS, /* Anonymous swap entries */ + MM_SHMEMPAGES, /* Resident shared memory pages */ NR_MM_COUNTERS }; diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 7dad84913abfb..bb0669169716e 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -180,7 +180,7 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr, lru_cache_add_active_or_unevictable(kpage, vma); if (!PageAnon(page)) { - dec_mm_counter(mm, MM_FILEPAGES); + dec_mm_counter(mm, mm_counter_file(page)); inc_mm_counter(mm, MM_ANONPAGES); } diff --git a/mm/memory.c b/mm/memory.c index c387430f06c31..f7026c0359406 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -832,10 +832,7 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, } else if (is_migration_entry(entry)) { page = migration_entry_to_page(entry); - if (PageAnon(page)) - rss[MM_ANONPAGES]++; - else - rss[MM_FILEPAGES]++; + rss[mm_counter(page)]++; if (is_write_migration_entry(entry) && is_cow_mapping(vm_flags)) { @@ -874,10 +871,7 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, if (page) { get_page(page); page_dup_rmap(page); - if (PageAnon(page)) - rss[MM_ANONPAGES]++; - else - rss[MM_FILEPAGES]++; + rss[mm_counter(page)]++; } out_set_pte: @@ -1113,9 +1107,8 @@ again: tlb_remove_tlb_entry(tlb, pte, addr); if (unlikely(!page)) continue; - if (PageAnon(page)) - rss[MM_ANONPAGES]--; - else { + + if (!PageAnon(page)) { if (pte_dirty(ptent)) { force_flush = 1; set_page_dirty(page); @@ -1123,8 +1116,8 @@ again: if (pte_young(ptent) && likely(!(vma->vm_flags & VM_SEQ_READ))) mark_page_accessed(page); - rss[MM_FILEPAGES]--; } + rss[mm_counter(page)]--; page_remove_rmap(page); if (unlikely(page_mapcount(page) < 0)) print_bad_pte(vma, addr, ptent, page); @@ -1146,11 +1139,7 @@ again: struct page *page; page = migration_entry_to_page(entry); - - if (PageAnon(page)) - rss[MM_ANONPAGES]--; - else - rss[MM_FILEPAGES]--; + rss[mm_counter(page)]--; } if (unlikely(!free_swap_and_cache(entry))) print_bad_pte(vma, addr, ptent, NULL); @@ -1460,7 +1449,7 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr, /* Ok, finally just insert the thing.. */ get_page(page); - inc_mm_counter_fast(mm, MM_FILEPAGES); + inc_mm_counter_fast(mm, mm_counter_file(page)); page_add_file_rmap(page); set_pte_at(mm, addr, pte, mk_pte(page, prot)); @@ -2097,7 +2086,8 @@ static int wp_page_copy(struct mm_struct *mm, struct vm_area_struct *vma, if (likely(pte_same(*page_table, orig_pte))) { if (old_page) { if (!PageAnon(old_page)) { - dec_mm_counter_fast(mm, MM_FILEPAGES); + dec_mm_counter_fast(mm, + mm_counter_file(old_page)); inc_mm_counter_fast(mm, MM_ANONPAGES); } } else { @@ -2820,7 +2810,7 @@ void do_set_pte(struct vm_area_struct *vma, unsigned long address, inc_mm_counter_fast(vma->vm_mm, MM_ANONPAGES); page_add_new_anon_rmap(page, vma, address); } else { - inc_mm_counter_fast(vma->vm_mm, MM_FILEPAGES); + inc_mm_counter_fast(vma->vm_mm, mm_counter_file(page)); page_add_file_rmap(page); } set_pte_at(vma->vm_mm, address, pte, entry); diff --git a/mm/oom_kill.c b/mm/oom_kill.c index c12680993ff33..dc490c06941b2 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -585,10 +585,11 @@ void oom_kill_process(struct oom_control *oc, struct task_struct *p, */ do_send_sig_info(SIGKILL, SEND_SIG_FORCED, victim, true); mark_oom_victim(victim); - pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n", + pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n", task_pid_nr(victim), victim->comm, K(victim->mm->total_vm), K(get_mm_counter(victim->mm, MM_ANONPAGES)), - K(get_mm_counter(victim->mm, MM_FILEPAGES))); + K(get_mm_counter(victim->mm, MM_FILEPAGES)), + K(get_mm_counter(victim->mm, MM_SHMEMPAGES))); task_unlock(victim); /* diff --git a/mm/rmap.c b/mm/rmap.c index 3c3f1d21f0758..622756c16ac84 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -1364,10 +1364,7 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma, if (PageHuge(page)) { hugetlb_count_sub(1 << compound_order(page), mm); } else { - if (PageAnon(page)) - dec_mm_counter(mm, MM_ANONPAGES); - else - dec_mm_counter(mm, MM_FILEPAGES); + dec_mm_counter(mm, mm_counter(page)); } set_pte_at(mm, address, pte, swp_entry_to_pte(make_hwpoison_entry(page))); @@ -1377,10 +1374,7 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma, * interest anymore. Simply discard the pte, vmscan * will take care of the rest. */ - if (PageAnon(page)) - dec_mm_counter(mm, MM_ANONPAGES); - else - dec_mm_counter(mm, MM_FILEPAGES); + dec_mm_counter(mm, mm_counter(page)); } else if (IS_ENABLED(CONFIG_MIGRATION) && (flags & TTU_MIGRATION)) { swp_entry_t entry; pte_t swp_pte; @@ -1420,7 +1414,7 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma, swp_pte = pte_swp_mksoft_dirty(swp_pte); set_pte_at(mm, address, pte, swp_pte); } else - dec_mm_counter(mm, MM_FILEPAGES); + dec_mm_counter(mm, mm_counter_file(page)); page_remove_rmap(page); page_cache_release(page); -- GitLab From 8cee852ec53fb530f10ccabf1596734209ae336b Mon Sep 17 00:00:00 2001 From: Jerome Marchand Date: Thu, 14 Jan 2016 15:19:29 -0800 Subject: [PATCH 2778/2855] mm, procfs: breakdown RSS for anon, shmem and file in /proc/pid/status There are several shortcomings with the accounting of shared memory (SysV shm, shared anonymous mapping, mapping of a tmpfs file). The values in /proc//status and <...>/statm don't allow to distinguish between shmem memory and a shared mapping to a regular file, even though theirs implication on memory usage are quite different: during reclaim, file mapping can be dropped or written back on disk, while shmem needs a place in swap. Also, to distinguish the memory occupied by anonymous and file mappings, one has to read the /proc/pid/statm file, which has a field for the file mappings (again, including shmem) and total memory occupied by these mappings (i.e. equivalent to VmRSS in the <...>/status file. Getting the value for anonymous mappings only is thus not exactly user-friendly (the statm file is intended to be rather efficiently machine-readable). To address both of these shortcomings, this patch adds a breakdown of VmRSS in /proc//status via new fields RssAnon, RssFile and RssShmem, making use of the previous preparatory patch. These fields tell the user the memory occupied by private anonymous pages, mapped regular files and shmem, respectively. Other existing fields in /status and /statm files are left without change. The /statm file can be extended in the future, if there's a need for that. Example (part of) /proc/pid/status output including the new Rss* fields: VmPeak: 2001008 kB VmSize: 2001004 kB VmLck: 0 kB VmPin: 0 kB VmHWM: 5108 kB VmRSS: 5108 kB RssAnon: 92 kB RssFile: 1324 kB RssShmem: 3692 kB VmData: 192 kB VmStk: 136 kB VmExe: 4 kB VmLib: 1784 kB VmPTE: 3928 kB VmPMD: 20 kB VmSwap: 0 kB HugetlbPages: 0 kB [vbabka@suse.cz: forward-porting, tweak changelog] Signed-off-by: Jerome Marchand Signed-off-by: Vlastimil Babka Acked-by: Konstantin Khlebnikov Acked-by: Michal Hocko Acked-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/filesystems/proc.txt | 13 +++++++++++-- fs/proc/task_mmu.c | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index fdeb5b33349f4..ffcd49589ab5f 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -169,6 +169,9 @@ read the file /proc/PID/status: VmLck: 0 kB VmHWM: 476 kB VmRSS: 476 kB + RssAnon: 352 kB + RssFile: 120 kB + RssShmem: 4 kB VmData: 156 kB VmStk: 88 kB VmExe: 68 kB @@ -231,7 +234,12 @@ Table 1-2: Contents of the status files (as of 4.1) VmSize total program size VmLck locked memory size VmHWM peak resident set size ("high water mark") - VmRSS size of memory portions + VmRSS size of memory portions. It contains the three + following parts (VmRSS = RssAnon + RssFile + RssShmem) + RssAnon size of resident anonymous memory + RssFile size of resident file mappings + RssShmem size of resident shmem memory (includes SysV shm, + mapping of tmpfs and shared anonymous mappings) VmData size of data, stack, and text segments VmStk size of data, stack, and text segments VmExe size of text segment @@ -266,7 +274,8 @@ Table 1-3: Contents of the statm files (as of 2.6.8-rc3) Field Content size total program size (pages) (same as VmSize in status) resident size of memory portions (pages) (same as VmRSS in status) - shared number of pages that are shared (i.e. backed by a file) + shared number of pages that are shared (i.e. backed by a file, same + as RssFile+RssShmem in status) trs number of pages that are 'code' (not including libs; broken, includes data segment) lrs number of pages of library (always 0 on 2.6) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 45eb24145978c..18a30aedfa5d4 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -23,9 +23,13 @@ void task_mem(struct seq_file *m, struct mm_struct *mm) { - unsigned long data, text, lib, swap, ptes, pmds; + unsigned long data, text, lib, swap, ptes, pmds, anon, file, shmem; unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss; + anon = get_mm_counter(mm, MM_ANONPAGES); + file = get_mm_counter(mm, MM_FILEPAGES); + shmem = get_mm_counter(mm, MM_SHMEMPAGES); + /* * Note: to minimize their overhead, mm maintains hiwater_vm and * hiwater_rss only when about to *lower* total_vm or rss. Any @@ -36,7 +40,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm) hiwater_vm = total_vm = mm->total_vm; if (hiwater_vm < mm->hiwater_vm) hiwater_vm = mm->hiwater_vm; - hiwater_rss = total_rss = get_mm_rss(mm); + hiwater_rss = total_rss = anon + file + shmem; if (hiwater_rss < mm->hiwater_rss) hiwater_rss = mm->hiwater_rss; @@ -53,6 +57,9 @@ void task_mem(struct seq_file *m, struct mm_struct *mm) "VmPin:\t%8lu kB\n" "VmHWM:\t%8lu kB\n" "VmRSS:\t%8lu kB\n" + "RssAnon:\t%8lu kB\n" + "RssFile:\t%8lu kB\n" + "RssShmem:\t%8lu kB\n" "VmData:\t%8lu kB\n" "VmStk:\t%8lu kB\n" "VmExe:\t%8lu kB\n" @@ -66,6 +73,9 @@ void task_mem(struct seq_file *m, struct mm_struct *mm) mm->pinned_vm << (PAGE_SHIFT-10), hiwater_rss << (PAGE_SHIFT-10), total_rss << (PAGE_SHIFT-10), + anon << (PAGE_SHIFT-10), + file << (PAGE_SHIFT-10), + shmem << (PAGE_SHIFT-10), data << (PAGE_SHIFT-10), mm->stack_vm << (PAGE_SHIFT-10), text, lib, ptes >> 10, -- GitLab From 146693471f1df44115cf4aaf13c33618619ad855 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 14 Jan 2016 15:19:32 -0800 Subject: [PATCH 2779/2855] mm, thp: use list_first_entry_or_null() Simplify the code with list_first_entry_or_null(). Signed-off-by: Geliang Tang Acked-by: Kirill A. Shutemov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/pgtable-generic.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c index 7d3db0247983b..4c681baff3632 100644 --- a/mm/pgtable-generic.c +++ b/mm/pgtable-generic.c @@ -176,13 +176,10 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp) /* FIFO */ pgtable = pmd_huge_pte(mm, pmdp); - if (list_empty(&pgtable->lru)) - pmd_huge_pte(mm, pmdp) = NULL; - else { - pmd_huge_pte(mm, pmdp) = list_entry(pgtable->lru.next, - struct page, lru); + pmd_huge_pte(mm, pmdp) = list_first_entry_or_null(&pgtable->lru, + struct page, lru); + if (pmd_huge_pte(mm, pmdp)) list_del(&pgtable->lru); - } return pgtable; } #endif -- GitLab From 244d63ee345bd9d45c87f665ef5e3f7bcd5db45b Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Thu, 14 Jan 2016 15:19:35 -0800 Subject: [PATCH 2780/2855] mm, vmalloc: remove VM_VPAGES VM_VPAGES is unnecessary, it's easier to check is_vmalloc_addr() when reading /proc/vmallocinfo. [akpm@linux-foundation.org: remove VM_VPAGES reference via kvfree()] Signed-off-by: David Rientjes Cc: Tetsuo Handa Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/vmalloc.h | 1 - mm/vmalloc.c | 8 ++------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 3bff87a25a42f..d1f1d338af205 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -14,7 +14,6 @@ struct vm_area_struct; /* vma defining user mapping in mm_types.h */ #define VM_ALLOC 0x00000002 /* vmalloc() */ #define VM_MAP 0x00000004 /* vmap()ed pages */ #define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */ -#define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */ #define VM_UNINITIALIZED 0x00000020 /* vm_struct is not fully initialized */ #define VM_NO_GUARD 0x00000040 /* don't add guard page */ #define VM_KASAN 0x00000080 /* has allocated kasan shadow memory */ diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 7007fe85840ee..58ceeb107960b 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1479,10 +1479,7 @@ static void __vunmap(const void *addr, int deallocate_pages) __free_kmem_pages(page, 0); } - if (area->flags & VM_VPAGES) - vfree(area->pages); - else - kfree(area->pages); + kvfree(area->pages); } kfree(area); @@ -1592,7 +1589,6 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, if (array_size > PAGE_SIZE) { pages = __vmalloc_node(array_size, 1, nested_gfp|__GFP_HIGHMEM, PAGE_KERNEL, node, area->caller); - area->flags |= VM_VPAGES; } else { pages = kmalloc_node(array_size, nested_gfp, node); } @@ -2650,7 +2646,7 @@ static int s_show(struct seq_file *m, void *p) if (v->flags & VM_USERMAP) seq_puts(m, " user"); - if (v->flags & VM_VPAGES) + if (is_vmalloc_addr(v->pages)) seq_puts(m, " vpages"); show_numa_info(m, v); -- GitLab From 316bda0e6cc5f36f94b4af8bded16d642c90ad75 Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Thu, 14 Jan 2016 15:19:38 -0800 Subject: [PATCH 2781/2855] vmscan: do not force-scan file lru if its absolute size is small We assume there is enough inactive page cache if the size of inactive file lru is greater than the size of active file lru, in which case we force-scan file lru ignoring anonymous pages. While this logic works fine when there are plenty of page cache pages, it fails if the size of file lru is small (several MB): in this case (lru_size >> prio) will be 0 for normal scan priorities, as a result, if inactive file lru happens to be larger than active file lru, anonymous pages of a cgroup will never get evicted unless the system experiences severe memory pressure, even if there are gigabytes of unused anonymous memory there, which is unfair in respect to other cgroups, whose workloads might be page cache oriented. This patch attempts to fix this by elaborating the "enough inactive page cache" check: it makes it not only check that inactive lru size > active lru size, but also that we will scan something from the cgroup at the current scan priority. If these conditions do not hold, we proceed to SCAN_FRACT as usual. Signed-off-by: Vladimir Davydov Acked-by: Johannes Weiner Acked-by: Michal Hocko Cc: Vlastimil Babka Cc: Mel Gorman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 35dd57e992827..1dab3a3ddcd39 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2043,10 +2043,16 @@ static void get_scan_count(struct lruvec *lruvec, int swappiness, } /* - * There is enough inactive page cache, do not reclaim - * anything from the anonymous working set right now. + * If there is enough inactive page cache, i.e. if the size of the + * inactive list is greater than that of the active list *and* the + * inactive list actually has some pages to scan on this priority, we + * do not reclaim anything from the anonymous working set right now. + * Without the second condition we could end up never scanning an + * lruvec even if it has plenty of old anonymous pages unless the + * system is under heavy pressure. */ - if (!inactive_file_is_low(lruvec)) { + if (!inactive_file_is_low(lruvec) && + get_lru_size(lruvec, LRU_INACTIVE_FILE) >> sc->priority) { scan_balance = SCAN_FILE; goto out; } -- GitLab From 9ee11ba4251dddf1b0e507d184b25b1bd7820773 Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Thu, 14 Jan 2016 15:19:41 -0800 Subject: [PATCH 2782/2855] memcg: do not allow to disable tcp accounting after limit is set There are two bits defined for cg_proto->flags - MEMCG_SOCK_ACTIVATED and MEMCG_SOCK_ACTIVE - both are set in tcp_update_limit, but the former is never cleared while the latter can be cleared by unsetting the limit. This allows to disable tcp socket accounting for new sockets after it was enabled by writing -1 to memory.kmem.tcp.limit_in_bytes while still guaranteeing that memcg_socket_limit_enabled static key will be decremented on memcg destruction. This functionality looks dubious, because it is not clear what a use case would be. By enabling tcp accounting a user accepts the price. If they then find the performance degradation unacceptable, they can always restart their workload with tcp accounting disabled. It does not seem there is any need to flip it while the workload is running. Besides, it contradicts to how kmem accounting API works: writing whatever to memory.kmem.limit_in_bytes enables kmem accounting for the cgroup in question, after which it cannot be disabled. Therefore one might expect that writing -1 to memory.kmem.tcp.limit_in_bytes just enables socket accounting w/o limiting it, which might be useful by itself, but it isn't true. Since this API peculiarity is not documented anywhere, I propose to drop it. This will allow to simplify the code by dropping cg_proto->flags. Signed-off-by: Vladimir Davydov Cc: Johannes Weiner Cc: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 12 +----------- mm/memcontrol.c | 2 +- net/ipv4/tcp_memcontrol.c | 17 +++++------------ 3 files changed, 7 insertions(+), 24 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 5c97265c1c6e8..78a1ec2e23fcf 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -85,22 +85,12 @@ enum mem_cgroup_events_target { MEM_CGROUP_NTARGETS, }; -/* - * Bits in struct cg_proto.flags - */ -enum cg_proto_flags { - /* Currently active and new sockets should be assigned to cgroups */ - MEMCG_SOCK_ACTIVE, - /* It was ever activated; we must disarm static keys on destruction */ - MEMCG_SOCK_ACTIVATED, -}; - struct cg_proto { struct page_counter memory_allocated; /* Current allocated memory. */ struct percpu_counter sockets_allocated; /* Current number of sockets. */ int memory_pressure; + bool active; long sysctl_mem[3]; - unsigned long flags; /* * memcg field is used to find which memcg we belong directly * Each memcg struct can hold more than one cg_proto, so container_of diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 4bd6c45133931..0bc140d998add 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -316,7 +316,7 @@ void sock_update_memcg(struct sock *sk) rcu_read_lock(); memcg = mem_cgroup_from_task(current); cg_proto = sk->sk_prot->proto_cgroup(memcg); - if (cg_proto && test_bit(MEMCG_SOCK_ACTIVE, &cg_proto->flags) && + if (cg_proto && cg_proto->active && css_tryget_online(&memcg->css)) { sk->sk_cgrp = cg_proto; } diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c index 2379c1b4efb24..d07579ada0014 100644 --- a/net/ipv4/tcp_memcontrol.c +++ b/net/ipv4/tcp_memcontrol.c @@ -48,7 +48,7 @@ void tcp_destroy_cgroup(struct mem_cgroup *memcg) percpu_counter_destroy(&cg_proto->sockets_allocated); - if (test_bit(MEMCG_SOCK_ACTIVATED, &cg_proto->flags)) + if (cg_proto->active) static_key_slow_dec(&memcg_socket_limit_enabled); } @@ -72,11 +72,9 @@ static int tcp_update_limit(struct mem_cgroup *memcg, unsigned long nr_pages) cg_proto->sysctl_mem[i] = min_t(long, nr_pages, sysctl_tcp_mem[i]); - if (nr_pages == PAGE_COUNTER_MAX) - clear_bit(MEMCG_SOCK_ACTIVE, &cg_proto->flags); - else { + if (!cg_proto->active) { /* - * The active bit needs to be written after the static_key + * The active flag needs to be written after the static_key * update. This is what guarantees that the socket activation * function is the last one to run. See sock_update_memcg() for * details, and note that we don't mark any socket as belonging @@ -90,14 +88,9 @@ static int tcp_update_limit(struct mem_cgroup *memcg, unsigned long nr_pages) * We never race with the readers in sock_update_memcg(), * because when this value change, the code to process it is not * patched in yet. - * - * The activated bit is used to guarantee that no two writers - * will do the update in the same memcg. Without that, we can't - * properly shutdown the static key. */ - if (!test_and_set_bit(MEMCG_SOCK_ACTIVATED, &cg_proto->flags)) - static_key_slow_inc(&memcg_socket_limit_enabled); - set_bit(MEMCG_SOCK_ACTIVE, &cg_proto->flags); + static_key_slow_inc(&memcg_socket_limit_enabled); + cg_proto->active = true; } return 0; -- GitLab From b832861cca231c0ef27e238b28788045da3262f2 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 14 Jan 2016 15:19:44 -0800 Subject: [PATCH 2783/2855] fs/block_dev.c:bdev_write_page(): use blk_queue_enter(..., GFP_NOIO) bdev_write_page() is used by swapout and by writepage where we cannot use __GFP_FS or __GFP_IO. So it is misleading to mention GFP_KERNEL here. blk_queue_enter() only actually looks at __GFP_DIRECT_RECLAIM, so no bugs were harmed in the making of this patch. Cc: Dan Williams Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/block_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/block_dev.c b/fs/block_dev.c index d33071dd683ec..81c0705558beb 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -437,7 +437,7 @@ int bdev_write_page(struct block_device *bdev, sector_t sector, if (!ops->rw_page || bdev_get_integrity(bdev)) return -EOPNOTSUPP; - result = blk_queue_enter(bdev->bd_queue, GFP_KERNEL); + result = blk_queue_enter(bdev->bd_queue, GFP_NOIO); if (result) return result; -- GitLab From 9f6c399ddc369856d787bd43ccd43b19ed1e4e32 Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Thu, 14 Jan 2016 15:19:47 -0800 Subject: [PATCH 2784/2855] mm, vmscan: consider isolated pages in zone_reclaimable_pages zone_reclaimable_pages counts how many pages are reclaimable in the given zone. This currently includes all pages on file lrus and anon lrus if there is an available swap storage. We do not consider NR_ISOLATED_{ANON,FILE} counters though which is not correct because these counters reflect temporarily isolated pages which are still reclaimable because they either get back to their LRU or get freed either by the page reclaim or page migration. The number of these pages might be sufficiently high to confuse users of zone_reclaimable_pages (e.g. mbind can migrate large ranges of memory at once). Signed-off-by: Michal Hocko Suggested-by: Johannes Weiner Acked-by: Johannes Weiner Reviewed-by: Vladimir Davydov Acked-by: David Rientjes Cc: Vlastimil Babka Cc: Mel Gorman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 1dab3a3ddcd39..1bbfd623630eb 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -197,11 +197,13 @@ static unsigned long zone_reclaimable_pages(struct zone *zone) unsigned long nr; nr = zone_page_state(zone, NR_ACTIVE_FILE) + - zone_page_state(zone, NR_INACTIVE_FILE); + zone_page_state(zone, NR_INACTIVE_FILE) + + zone_page_state(zone, NR_ISOLATED_FILE); if (get_nr_swap_pages() > 0) nr += zone_page_state(zone, NR_ACTIVE_ANON) + - zone_page_state(zone, NR_INACTIVE_ANON); + zone_page_state(zone, NR_INACTIVE_ANON) + + zone_page_state(zone, NR_ISOLATED_ANON); return nr; } -- GitLab From bc36f7017c39d1fe3c01aecd09cb2fe14753be90 Mon Sep 17 00:00:00 2001 From: Piotr Kwapulinski Date: Thu, 14 Jan 2016 15:19:50 -0800 Subject: [PATCH 2785/2855] mm/mmap.c: remove incorrect MAP_FIXED flag comparison from mmap_region The following flag comparison in mmap_region makes no sense: if (!(vm_flags & MAP_FIXED)) return -ENOMEM; The condition is always false and thus the above "return -ENOMEM" is never executed. The vm_flags must not be compared with MAP_FIXED flag. The vm_flags may only be compared with VM_* flags. MAP_FIXED has the same value as VM_MAYREAD. Hitting the rlimit is a slow path and find_vma_intersection should realize that there is no overlapping VMA for !MAP_FIXED case pretty quickly. Signed-off-by: Piotr Kwapulinski Acked-by: Michal Hocko Cc: Oleg Nesterov Cc: Chris Metcalf Reviewed-by: Naoya Horiguchi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/mmap.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/mm/mmap.c b/mm/mmap.c index 9da9c27c33a2a..c311bfd8005b5 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1551,9 +1551,6 @@ unsigned long mmap_region(struct file *file, unsigned long addr, * MAP_FIXED may remove pages of mappings that intersects with * requested mapping. Account for the pages it would unmap. */ - if (!(vm_flags & MAP_FIXED)) - return -ENOMEM; - nr_pages = count_vma_pages_range(mm, addr, addr + len); if (!may_expand_vm(mm, (len >> PAGE_SHIFT) - nr_pages)) -- GitLab From d07e22597d1d355829b7b18ac19afa912cf758d1 Mon Sep 17 00:00:00 2001 From: Daniel Cashman Date: Thu, 14 Jan 2016 15:19:53 -0800 Subject: [PATCH 2786/2855] mm: mmap: add new /proc tunable for mmap_base ASLR Address Space Layout Randomization (ASLR) provides a barrier to exploitation of user-space processes in the presence of security vulnerabilities by making it more difficult to find desired code/data which could help an attack. This is done by adding a random offset to the location of regions in the process address space, with a greater range of potential offset values corresponding to better protection/a larger search-space for brute force, but also to greater potential for fragmentation. The offset added to the mmap_base address, which provides the basis for the majority of the mappings for a process, is set once on process exec in arch_pick_mmap_layout() and is done via hard-coded per-arch values, which reflect, hopefully, the best compromise for all systems. The trade-off between increased entropy in the offset value generation and the corresponding increased variability in address space fragmentation is not absolute, however, and some platforms may tolerate higher amounts of entropy. This patch introduces both new Kconfig values and a sysctl interface which may be used to change the amount of entropy used for offset generation on a system. The direct motivation for this change was in response to the libstagefright vulnerabilities that affected Android, specifically to information provided by Google's project zero at: http://googleprojectzero.blogspot.com/2015/09/stagefrightened.html The attack presented therein, by Google's project zero, specifically targeted the limited randomness used to generate the offset added to the mmap_base address in order to craft a brute-force-based attack. Concretely, the attack was against the mediaserver process, which was limited to respawning every 5 seconds, on an arm device. The hard-coded 8 bits used resulted in an average expected success rate of defeating the mmap ASLR after just over 10 minutes (128 tries at 5 seconds a piece). With this patch, and an accompanying increase in the entropy value to 16 bits, the same attack would take an average expected time of over 45 hours (32768 tries), which makes it both less feasible and more likely to be noticed. The introduced Kconfig and sysctl options are limited by per-arch minimum and maximum values, the minimum of which was chosen to match the current hard-coded value and the maximum of which was chosen so as to give the greatest flexibility without generating an invalid mmap_base address, generally a 3-4 bits less than the number of bits in the user-space accessible virtual address space. When decided whether or not to change the default value, a system developer should consider that mmap_base address could be placed anywhere up to 2^(value) bits away from the non-randomized location, which would introduce variable-sized areas above and below the mmap_base address such that the maximum vm_area_struct size may be reduced, preventing very large allocations. This patch (of 4): ASLR only uses as few as 8 bits to generate the random offset for the mmap base address on 32 bit architectures. This value was chosen to prevent a poorly chosen value from dividing the address space in such a way as to prevent large allocations. This may not be an issue on all platforms. Allow the specification of a minimum number of bits so that platforms desiring greater ASLR protection may determine where to place the trade-off. Signed-off-by: Daniel Cashman Cc: Russell King Acked-by: Kees Cook Cc: Ingo Molnar Cc: Jonathan Corbet Cc: Don Zickus Cc: Eric W. Biederman Cc: Heinrich Schuchardt Cc: Josh Poimboeuf Cc: Kirill A. Shutemov Cc: Naoya Horiguchi Cc: Andrea Arcangeli Cc: Mel Gorman Cc: Thomas Gleixner Cc: David Rientjes Cc: Mark Salyzyn Cc: Jeff Vander Stoep Cc: Nick Kralevich Cc: Catalin Marinas Cc: Will Deacon Cc: "H. Peter Anvin" Cc: Hector Marco-Gisbert Cc: Borislav Petkov Cc: Ralf Baechle Cc: Heiko Carstens Cc: Martin Schwidefsky Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/sysctl/vm.txt | 29 ++++++++++++++++ arch/Kconfig | 68 +++++++++++++++++++++++++++++++++++++ include/linux/mm.h | 11 ++++++ kernel/sysctl.c | 22 ++++++++++++ mm/mmap.c | 12 +++++++ 5 files changed, 142 insertions(+) diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index f72370b440b12..ee763f3d3b525 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -42,6 +42,8 @@ Currently, these files are in /proc/sys/vm: - min_slab_ratio - min_unmapped_ratio - mmap_min_addr +- mmap_rnd_bits +- mmap_rnd_compat_bits - nr_hugepages - nr_overcommit_hugepages - nr_trim_pages (only if CONFIG_MMU=n) @@ -485,6 +487,33 @@ against future potential kernel bugs. ============================================================== +mmap_rnd_bits: + +This value can be used to select the number of bits to use to +determine the random offset to the base address of vma regions +resulting from mmap allocations on architectures which support +tuning address space randomization. This value will be bounded +by the architecture's minimum and maximum supported values. + +This value can be changed after boot using the +/proc/sys/vm/mmap_rnd_bits tunable + +============================================================== + +mmap_rnd_compat_bits: + +This value can be used to select the number of bits to use to +determine the random offset to the base address of vma regions +resulting from mmap allocations for applications run in +compatibility mode on architectures which support tuning address +space randomization. This value will be bounded by the +architecture's minimum and maximum supported values. + +This value can be changed after boot using the +/proc/sys/vm/mmap_rnd_compat_bits tunable + +============================================================== + nr_hugepages Change the minimum size of the hugepage pool. diff --git a/arch/Kconfig b/arch/Kconfig index 4e949e58b1928..ba1b626bca002 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -511,6 +511,74 @@ config ARCH_HAS_ELF_RANDOMIZE - arch_mmap_rnd() - arch_randomize_brk() +config HAVE_ARCH_MMAP_RND_BITS + bool + help + An arch should select this symbol if it supports setting a variable + number of bits for use in establishing the base address for mmap + allocations, has MMU enabled and provides values for both: + - ARCH_MMAP_RND_BITS_MIN + - ARCH_MMAP_RND_BITS_MAX + +config ARCH_MMAP_RND_BITS_MIN + int + +config ARCH_MMAP_RND_BITS_MAX + int + +config ARCH_MMAP_RND_BITS_DEFAULT + int + +config ARCH_MMAP_RND_BITS + int "Number of bits to use for ASLR of mmap base address" if EXPERT + range ARCH_MMAP_RND_BITS_MIN ARCH_MMAP_RND_BITS_MAX + default ARCH_MMAP_RND_BITS_DEFAULT if ARCH_MMAP_RND_BITS_DEFAULT + default ARCH_MMAP_RND_BITS_MIN + depends on HAVE_ARCH_MMAP_RND_BITS + help + This value can be used to select the number of bits to use to + determine the random offset to the base address of vma regions + resulting from mmap allocations. This value will be bounded + by the architecture's minimum and maximum supported values. + + This value can be changed after boot using the + /proc/sys/vm/mmap_rnd_bits tunable + +config HAVE_ARCH_MMAP_RND_COMPAT_BITS + bool + help + An arch should select this symbol if it supports running applications + in compatibility mode, supports setting a variable number of bits for + use in establishing the base address for mmap allocations, has MMU + enabled and provides values for both: + - ARCH_MMAP_RND_COMPAT_BITS_MIN + - ARCH_MMAP_RND_COMPAT_BITS_MAX + +config ARCH_MMAP_RND_COMPAT_BITS_MIN + int + +config ARCH_MMAP_RND_COMPAT_BITS_MAX + int + +config ARCH_MMAP_RND_COMPAT_BITS_DEFAULT + int + +config ARCH_MMAP_RND_COMPAT_BITS + int "Number of bits to use for ASLR of mmap base address for compatible applications" if EXPERT + range ARCH_MMAP_RND_COMPAT_BITS_MIN ARCH_MMAP_RND_COMPAT_BITS_MAX + default ARCH_MMAP_RND_COMPAT_BITS_DEFAULT if ARCH_MMAP_RND_COMPAT_BITS_DEFAULT + default ARCH_MMAP_RND_COMPAT_BITS_MIN + depends on HAVE_ARCH_MMAP_RND_COMPAT_BITS + help + This value can be used to select the number of bits to use to + determine the random offset to the base address of vma regions + resulting from mmap allocations for compatible applications This + value will be bounded by the architecture's minimum and maximum + supported values. + + This value can be changed after boot using the + /proc/sys/vm/mmap_rnd_compat_bits tunable + config HAVE_COPY_THREAD_TLS bool help diff --git a/include/linux/mm.h b/include/linux/mm.h index a8ab1fc0e9bcf..d396753c0577f 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -51,6 +51,17 @@ extern int sysctl_legacy_va_layout; #define sysctl_legacy_va_layout 0 #endif +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_BITS +extern const int mmap_rnd_bits_min; +extern const int mmap_rnd_bits_max; +extern int mmap_rnd_bits __read_mostly; +#endif +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS +extern const int mmap_rnd_compat_bits_min; +extern const int mmap_rnd_compat_bits_max; +extern int mmap_rnd_compat_bits __read_mostly; +#endif + #include #include #include diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 5faf89ac9ec08..c810f8afdb7f7 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1568,6 +1568,28 @@ static struct ctl_table vm_table[] = { .mode = 0644, .proc_handler = proc_doulongvec_minmax, }, +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_BITS + { + .procname = "mmap_rnd_bits", + .data = &mmap_rnd_bits, + .maxlen = sizeof(mmap_rnd_bits), + .mode = 0600, + .proc_handler = proc_dointvec_minmax, + .extra1 = (void *)&mmap_rnd_bits_min, + .extra2 = (void *)&mmap_rnd_bits_max, + }, +#endif +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS + { + .procname = "mmap_rnd_compat_bits", + .data = &mmap_rnd_compat_bits, + .maxlen = sizeof(mmap_rnd_compat_bits), + .mode = 0600, + .proc_handler = proc_dointvec_minmax, + .extra1 = (void *)&mmap_rnd_compat_bits_min, + .extra2 = (void *)&mmap_rnd_compat_bits_max, + }, +#endif { } }; diff --git a/mm/mmap.c b/mm/mmap.c index c311bfd8005b5..f32b84ad621a2 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -58,6 +58,18 @@ #define arch_rebalance_pgtables(addr, len) (addr) #endif +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_BITS +const int mmap_rnd_bits_min = CONFIG_ARCH_MMAP_RND_BITS_MIN; +const int mmap_rnd_bits_max = CONFIG_ARCH_MMAP_RND_BITS_MAX; +int mmap_rnd_bits __read_mostly = CONFIG_ARCH_MMAP_RND_BITS; +#endif +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS +const int mmap_rnd_compat_bits_min = CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN; +const int mmap_rnd_compat_bits_max = CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX; +int mmap_rnd_compat_bits __read_mostly = CONFIG_ARCH_MMAP_RND_COMPAT_BITS; +#endif + + static void unmap_region(struct mm_struct *mm, struct vm_area_struct *vma, struct vm_area_struct *prev, unsigned long start, unsigned long end); -- GitLab From e0c25d958f78acfd5c97df5776eeba3e0684101b Mon Sep 17 00:00:00 2001 From: Daniel Cashman Date: Thu, 14 Jan 2016 15:19:57 -0800 Subject: [PATCH 2787/2855] arm: mm: support ARCH_MMAP_RND_BITS arm: arch_mmap_rnd() uses a hard-code value of 8 to generate the random offset for the mmap base address. This value represents a compromise between increased ASLR effectiveness and avoiding address-space fragmentation. Replace it with a Kconfig option, which is sensibly bounded, so that platform developers may choose where to place this compromise. Keep 8 as the minimum acceptable value. [arnd@arndb.de: ARM: avoid ARCH_MMAP_RND_BITS for NOMMU] Signed-off-by: Daniel Cashman Cc: Russell King Acked-by: Kees Cook Cc: Ingo Molnar Cc: Jonathan Corbet Cc: Don Zickus Cc: Eric W. Biederman Cc: Heinrich Schuchardt Cc: Josh Poimboeuf Cc: Kirill A. Shutemov Cc: Naoya Horiguchi Cc: Andrea Arcangeli Cc: Mel Gorman Cc: Thomas Gleixner Cc: David Rientjes Cc: Mark Salyzyn Cc: Jeff Vander Stoep Cc: Nick Kralevich Cc: Catalin Marinas Cc: Will Deacon Cc: "H. Peter Anvin" Cc: Hector Marco-Gisbert Cc: Borislav Petkov Cc: Ralf Baechle Cc: Heiko Carstens Cc: Martin Schwidefsky Cc: Benjamin Herrenschmidt Signed-off-by: Arnd Bergmann Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/Kconfig | 9 +++++++++ arch/arm/mm/mmap.c | 3 +-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 84b1b21b08aee..4e489cc5c45e5 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -37,6 +37,7 @@ config ARM select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6 select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU + select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT) select HAVE_ARCH_TRACEHOOK select HAVE_ARM_SMCCC if CPU_V7 @@ -311,6 +312,14 @@ config MMU Select if you want MMU-based virtualised addressing space support by paged memory management. If unsure, say 'Y'. +config ARCH_MMAP_RND_BITS_MIN + default 8 + +config ARCH_MMAP_RND_BITS_MAX + default 14 if PAGE_OFFSET=0x40000000 + default 15 if PAGE_OFFSET=0x80000000 + default 16 + # # The "ARM system type" choice list is ordered alphabetically by option # text. Please add new entries in the option alphabetic order. diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index 407dc786583ae..4b4058db0781f 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -173,8 +173,7 @@ unsigned long arch_mmap_rnd(void) { unsigned long rnd; - /* 8 bits of randomness in 20 address space bits */ - rnd = (unsigned long)get_random_int() % (1 << 8); + rnd = (unsigned long)get_random_int() & ((1 << mmap_rnd_bits) - 1); return rnd << PAGE_SHIFT; } -- GitLab From 8f0d3aa9de57662fe35d8bacfbd9d7ef85ffe98f Mon Sep 17 00:00:00 2001 From: Daniel Cashman Date: Thu, 14 Jan 2016 15:20:01 -0800 Subject: [PATCH 2788/2855] arm64: mm: support ARCH_MMAP_RND_BITS arm64: arch_mmap_rnd() uses STACK_RND_MASK to generate the random offset for the mmap base address. This value represents a compromise between increased ASLR effectiveness and avoiding address-space fragmentation. Replace it with a Kconfig option, which is sensibly bounded, so that platform developers may choose where to place this compromise. Keep default values as new minimums. Signed-off-by: Daniel Cashman Cc: Russell King Acked-by: Kees Cook Cc: Ingo Molnar Cc: Jonathan Corbet Cc: Don Zickus Cc: Eric W. Biederman Cc: Heinrich Schuchardt Cc: Josh Poimboeuf Cc: Kirill A. Shutemov Cc: Naoya Horiguchi Cc: Andrea Arcangeli Cc: Mel Gorman Cc: Thomas Gleixner Cc: David Rientjes Cc: Mark Salyzyn Cc: Jeff Vander Stoep Cc: Nick Kralevich Cc: Catalin Marinas Cc: Will Deacon Cc: "H. Peter Anvin" Cc: Hector Marco-Gisbert Cc: Borislav Petkov Cc: Ralf Baechle Cc: Heiko Carstens Cc: Martin Schwidefsky Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm64/Kconfig | 29 +++++++++++++++++++++++++++++ arch/arm64/mm/mmap.c | 8 ++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 4d5b416e2e4b4..6be3fa2310ee8 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -52,6 +52,8 @@ config ARM64 select HAVE_ARCH_JUMP_LABEL select HAVE_ARCH_KASAN if SPARSEMEM_VMEMMAP && !(ARM64_16K_PAGES && ARM64_VA_BITS_48) select HAVE_ARCH_KGDB + select HAVE_ARCH_MMAP_RND_BITS + select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK select HAVE_BPF_JIT @@ -107,6 +109,33 @@ config ARCH_PHYS_ADDR_T_64BIT config MMU def_bool y +config ARCH_MMAP_RND_BITS_MIN + default 14 if ARM64_64K_PAGES + default 16 if ARM64_16K_PAGES + default 18 + +# max bits determined by the following formula: +# VA_BITS - PAGE_SHIFT - 3 +config ARCH_MMAP_RND_BITS_MAX + default 19 if ARM64_VA_BITS=36 + default 24 if ARM64_VA_BITS=39 + default 27 if ARM64_VA_BITS=42 + default 30 if ARM64_VA_BITS=47 + default 29 if ARM64_VA_BITS=48 && ARM64_64K_PAGES + default 31 if ARM64_VA_BITS=48 && ARM64_16K_PAGES + default 33 if ARM64_VA_BITS=48 + default 14 if ARM64_64K_PAGES + default 16 if ARM64_16K_PAGES + default 18 + +config ARCH_MMAP_RND_COMPAT_BITS_MIN + default 7 if ARM64_64K_PAGES + default 9 if ARM64_16K_PAGES + default 11 + +config ARCH_MMAP_RND_COMPAT_BITS_MAX + default 16 + config NO_IOPORT_MAP def_bool y if !PCI diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c index ed177475dd8ce..4c893b5189ddd 100644 --- a/arch/arm64/mm/mmap.c +++ b/arch/arm64/mm/mmap.c @@ -51,8 +51,12 @@ unsigned long arch_mmap_rnd(void) { unsigned long rnd; - rnd = (unsigned long)get_random_int() & STACK_RND_MASK; - +#ifdef CONFIG_COMPAT + if (test_thread_flag(TIF_32BIT)) + rnd = (unsigned long)get_random_int() & ((1 << mmap_rnd_compat_bits) - 1); + else +#endif + rnd = (unsigned long)get_random_int() & ((1 << mmap_rnd_bits) - 1); return rnd << PAGE_SHIFT; } -- GitLab From 9e08f57d684ac2f40685f55f659564bfd91a971e Mon Sep 17 00:00:00 2001 From: Daniel Cashman Date: Thu, 14 Jan 2016 15:20:06 -0800 Subject: [PATCH 2789/2855] x86: mm: support ARCH_MMAP_RND_BITS x86: arch_mmap_rnd() uses hard-coded values, 8 for 32-bit and 28 for 64-bit, to generate the random offset for the mmap base address. This value represents a compromise between increased ASLR effectiveness and avoiding address-space fragmentation. Replace it with a Kconfig option, which is sensibly bounded, so that platform developers may choose where to place this compromise. Keep default values as new minimums. Signed-off-by: Daniel Cashman Cc: Russell King Acked-by: Kees Cook Cc: Ingo Molnar Cc: Jonathan Corbet Cc: Don Zickus Cc: Eric W. Biederman Cc: Heinrich Schuchardt Cc: Josh Poimboeuf Cc: Kirill A. Shutemov Cc: Naoya Horiguchi Cc: Andrea Arcangeli Cc: Mel Gorman Cc: Thomas Gleixner Cc: David Rientjes Cc: Mark Salyzyn Cc: Jeff Vander Stoep Cc: Nick Kralevich Cc: Catalin Marinas Cc: Will Deacon Cc: "H. Peter Anvin" Cc: Hector Marco-Gisbert Cc: Borislav Petkov Cc: Ralf Baechle Cc: Heiko Carstens Cc: Martin Schwidefsky Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/Kconfig | 16 ++++++++++++++++ arch/x86/mm/mmap.c | 12 ++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 5d2293417946d..24f362bf3ec63 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -83,6 +83,8 @@ config X86 select HAVE_ARCH_KASAN if X86_64 && SPARSEMEM_VMEMMAP select HAVE_ARCH_KGDB select HAVE_ARCH_KMEMCHECK + select HAVE_ARCH_MMAP_RND_BITS if MMU + select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_SOFT_DIRTY if X86_64 select HAVE_ARCH_TRACEHOOK @@ -184,6 +186,20 @@ config HAVE_LATENCYTOP_SUPPORT config MMU def_bool y +config ARCH_MMAP_RND_BITS_MIN + default 28 if 64BIT + default 8 + +config ARCH_MMAP_RND_BITS_MAX + default 32 if 64BIT + default 16 + +config ARCH_MMAP_RND_COMPAT_BITS_MIN + default 8 + +config ARCH_MMAP_RND_COMPAT_BITS_MAX + default 16 + config SBUS bool diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c index 844b06d67df4d..96bd1e2bffafb 100644 --- a/arch/x86/mm/mmap.c +++ b/arch/x86/mm/mmap.c @@ -69,14 +69,14 @@ unsigned long arch_mmap_rnd(void) { unsigned long rnd; - /* - * 8 bits of randomness in 32bit mmaps, 20 address space bits - * 28 bits of randomness in 64bit mmaps, 40 address space bits - */ if (mmap_is_ia32()) - rnd = (unsigned long)get_random_int() % (1<<8); +#ifdef CONFIG_COMPAT + rnd = (unsigned long)get_random_int() & ((1 << mmap_rnd_compat_bits) - 1); +#else + rnd = (unsigned long)get_random_int() & ((1 << mmap_rnd_bits) - 1); +#endif else - rnd = (unsigned long)get_random_int() % (1<<28); + rnd = (unsigned long)get_random_int() & ((1 << mmap_rnd_bits) - 1); return rnd << PAGE_SHIFT; } -- GitLab From fec4eb2c8d89bf8d18136df3d688c42b7959a057 Mon Sep 17 00:00:00 2001 From: Yaowei Bai Date: Thu, 14 Jan 2016 15:20:09 -0800 Subject: [PATCH 2790/2855] mm/compaction: improve comment for compact_memory tunable knob handler sysctl_compaction_handler() is the handler function for compact_memory tunable knob under /proc/sys/vm, add the missing knob name to make this more accurate in comment. No functional change. Signed-off-by: Yaowei Bai Acked-by: Vlastimil Babka Acked-by: Michal Nazarewicz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/compaction.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mm/compaction.c b/mm/compaction.c index de3e1e71cd9f2..ac6c6943d2ce0 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -1708,7 +1708,10 @@ static void compact_nodes(void) /* The written value is actually unused, all memory is compacted */ int sysctl_compact_memory; -/* This is the entry point for compacting all nodes via /proc/sys/vm */ +/* + * This is the entry point for compacting all nodes via + * /proc/sys/vm/compact_memory + */ int sysctl_compaction_handler(struct ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) { -- GitLab From c20cd45eb01748f0fba77a504f956b000df4ea73 Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Thu, 14 Jan 2016 15:20:12 -0800 Subject: [PATCH 2791/2855] mm: allow GFP_{FS,IO} for page_cache_read page cache allocation page_cache_read has been historically using page_cache_alloc_cold to allocate a new page. This means that mapping_gfp_mask is used as the base for the gfp_mask. Many filesystems are setting this mask to GFP_NOFS to prevent from fs recursion issues. page_cache_read is called from the vm_operations_struct::fault() context during the page fault. This context doesn't need the reclaim protection normally. ceph and ocfs2 which call filemap_fault from their fault handlers seem to be OK because they are not taking any fs lock before invoking generic implementation. xfs which takes XFS_MMAPLOCK_SHARED is safe from the reclaim recursion POV because this lock serializes truncate and punch hole with the page faults and it doesn't get involved in the reclaim. There is simply no reason to deliberately use a weaker allocation context when a __GFP_FS | __GFP_IO can be used. The GFP_NOFS protection might be even harmful. There is a push to fail GFP_NOFS allocations rather than loop within allocator indefinitely with a very limited reclaim ability. Once we start failing those requests the OOM killer might be triggered prematurely because the page cache allocation failure is propagated up the page fault path and end up in pagefault_out_of_memory. We cannot play with mapping_gfp_mask directly because that would be racy wrt. parallel page faults and it might interfere with other users who really rely on NOFS semantic from the stored gfp_mask. The mask is also inode proper so it would even be a layering violation. What we can do instead is to push the gfp_mask into struct vm_fault and allow fs layer to overwrite it should the callback need to be called with a different allocation context. Initialize the default to (mapping_gfp_mask | __GFP_FS | __GFP_IO) because this should be safe from the page fault path normally. Why do we care about mapping_gfp_mask at all then? Because this doesn't hold only reclaim protection flags but it also might contain zone and movability restrictions (GFP_DMA32, __GFP_MOVABLE and others) so we have to respect those. Signed-off-by: Michal Hocko Reported-by: Tetsuo Handa Acked-by: Jan Kara Acked-by: Vlastimil Babka Cc: Tetsuo Handa Cc: Mel Gorman Cc: Dave Chinner Cc: Mark Fasheh Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 4 ++++ mm/filemap.c | 9 ++++----- mm/memory.c | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index d396753c0577f..ec9d4559514d6 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -236,10 +236,14 @@ extern pgprot_t protection_map[16]; * ->fault function. The vma's ->fault is responsible for returning a bitmask * of VM_FAULT_xxx flags that give details about how the fault was handled. * + * MM layer fills up gfp_mask for page allocations but fault handler might + * alter it if its implementation requires a different allocation context. + * * pgoff should be used in favour of virtual_address, if possible. */ struct vm_fault { unsigned int flags; /* FAULT_FLAG_xxx flags */ + gfp_t gfp_mask; /* gfp mask to be used for allocations */ pgoff_t pgoff; /* Logical page offset based on vma */ void __user *virtual_address; /* Faulting virtual address */ diff --git a/mm/filemap.c b/mm/filemap.c index 1bb007624b53e..ff42d31c891a1 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1812,19 +1812,18 @@ EXPORT_SYMBOL(generic_file_read_iter); * This adds the requested page to the page cache if it isn't already there, * and schedules an I/O to read in its contents from disk. */ -static int page_cache_read(struct file *file, pgoff_t offset) +static int page_cache_read(struct file *file, pgoff_t offset, gfp_t gfp_mask) { struct address_space *mapping = file->f_mapping; struct page *page; int ret; do { - page = page_cache_alloc_cold(mapping); + page = __page_cache_alloc(gfp_mask|__GFP_COLD); if (!page) return -ENOMEM; - ret = add_to_page_cache_lru(page, mapping, offset, - mapping_gfp_constraint(mapping, GFP_KERNEL)); + ret = add_to_page_cache_lru(page, mapping, offset, gfp_mask & GFP_KERNEL); if (ret == 0) ret = mapping->a_ops->readpage(file, page); else if (ret == -EEXIST) @@ -2005,7 +2004,7 @@ no_cached_page: * We're only likely to ever get here if MADV_RANDOM is in * effect. */ - error = page_cache_read(file, offset); + error = page_cache_read(file, offset, vmf->gfp_mask); /* * The page we want has now been added to the page cache. diff --git a/mm/memory.c b/mm/memory.c index f7026c0359406..d4e4d37c19895 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1938,6 +1938,20 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo copy_user_highpage(dst, src, va, vma); } +static gfp_t __get_fault_gfp_mask(struct vm_area_struct *vma) +{ + struct file *vm_file = vma->vm_file; + + if (vm_file) + return mapping_gfp_mask(vm_file->f_mapping) | __GFP_FS | __GFP_IO; + + /* + * Special mappings (e.g. VDSO) do not have any file so fake + * a default GFP_KERNEL for them. + */ + return GFP_KERNEL; +} + /* * Notify the address space that the page is about to become writable so that * it can prohibit this or wait for the page to get into an appropriate state. @@ -1953,6 +1967,7 @@ static int do_page_mkwrite(struct vm_area_struct *vma, struct page *page, vmf.virtual_address = (void __user *)(address & PAGE_MASK); vmf.pgoff = page->index; vmf.flags = FAULT_FLAG_WRITE|FAULT_FLAG_MKWRITE; + vmf.gfp_mask = __get_fault_gfp_mask(vma); vmf.page = page; vmf.cow_page = NULL; @@ -2757,6 +2772,7 @@ static int __do_fault(struct vm_area_struct *vma, unsigned long address, vmf.pgoff = pgoff; vmf.flags = flags; vmf.page = NULL; + vmf.gfp_mask = __get_fault_gfp_mask(vma); vmf.cow_page = cow_page; ret = vma->vm_ops->fault(vma, &vmf); @@ -2923,6 +2939,7 @@ static void do_fault_around(struct vm_area_struct *vma, unsigned long address, vmf.pgoff = pgoff; vmf.max_pgoff = max_pgoff; vmf.flags = flags; + vmf.gfp_mask = __get_fault_gfp_mask(vma); vma->vm_ops->map_pages(vma, &vmf); } -- GitLab From a8d0143730d7b42c9fe6d1435d92ecce6863a62a Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:20:15 -0800 Subject: [PATCH 2792/2855] mm: page_alloc: generalize the dirty balance reserve The dirty balance reserve that dirty throttling has to consider is merely memory not available to userspace allocations. There is nothing writeback-specific about it. Generalize the name so that it's reusable outside of that context. Signed-off-by: Johannes Weiner Cc: Rik van Riel Cc: Mel Gorman Acked-by: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 6 +++--- include/linux/swap.h | 1 - mm/page-writeback.c | 14 ++++++++++++-- mm/page_alloc.c | 21 +++------------------ 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 3b6fb71bbeb31..33bb1b19273e3 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -356,10 +356,10 @@ struct zone { struct per_cpu_pageset __percpu *pageset; /* - * This is a per-zone reserve of pages that should not be - * considered dirtyable memory. + * This is a per-zone reserve of pages that are not available + * to userspace allocations. */ - unsigned long dirty_balance_reserve; + unsigned long totalreserve_pages; #ifndef CONFIG_SPARSEMEM /* diff --git a/include/linux/swap.h b/include/linux/swap.h index 7ba7dccaf0e7e..066bd21765ad7 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -287,7 +287,6 @@ static inline void workingset_node_shadows_dec(struct radix_tree_node *node) /* linux/mm/page_alloc.c */ extern unsigned long totalram_pages; extern unsigned long totalreserve_pages; -extern unsigned long dirty_balance_reserve; extern unsigned long nr_free_buffer_pages(void); extern unsigned long nr_free_pagecache_pages(void); diff --git a/mm/page-writeback.c b/mm/page-writeback.c index d15d88c8efa1e..6fe7d15bd1f78 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -278,7 +278,12 @@ static unsigned long zone_dirtyable_memory(struct zone *zone) unsigned long nr_pages; nr_pages = zone_page_state(zone, NR_FREE_PAGES); - nr_pages -= min(nr_pages, zone->dirty_balance_reserve); + /* + * Pages reserved for the kernel should not be considered + * dirtyable, to prevent a situation where reclaim has to + * clean pages in order to balance the zones. + */ + nr_pages -= min(nr_pages, zone->totalreserve_pages); nr_pages += zone_page_state(zone, NR_INACTIVE_FILE); nr_pages += zone_page_state(zone, NR_ACTIVE_FILE); @@ -332,7 +337,12 @@ static unsigned long global_dirtyable_memory(void) unsigned long x; x = global_page_state(NR_FREE_PAGES); - x -= min(x, dirty_balance_reserve); + /* + * Pages reserved for the kernel should not be considered + * dirtyable, to prevent a situation where reclaim has to + * clean pages in order to balance the zones. + */ + x -= min(x, totalreserve_pages); x += global_page_state(NR_INACTIVE_FILE); x += global_page_state(NR_ACTIVE_FILE); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 2a6fe377cafcb..1e9a560654002 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -114,13 +114,6 @@ static DEFINE_SPINLOCK(managed_page_count_lock); unsigned long totalram_pages __read_mostly; unsigned long totalreserve_pages __read_mostly; unsigned long totalcma_pages __read_mostly; -/* - * When calculating the number of globally allowed dirty pages, there - * is a certain number of per-zone reserves that should not be - * considered dirtyable memory. This is the sum of those reserves - * over all existing zones that contribute dirtyable memory. - */ -unsigned long dirty_balance_reserve __read_mostly; int percpu_pagelist_fraction; gfp_t gfp_allowed_mask __read_mostly = GFP_BOOT_MASK; @@ -5942,20 +5935,12 @@ static void calculate_totalreserve_pages(void) if (max > zone->managed_pages) max = zone->managed_pages; + + zone->totalreserve_pages = max; + reserve_pages += max; - /* - * Lowmem reserves are not available to - * GFP_HIGHUSER page cache allocations and - * kswapd tries to balance zones to their high - * watermark. As a result, neither should be - * regarded as dirtyable memory, to prevent a - * situation where reclaim has to clean pages - * in order to balance the zones. - */ - zone->dirty_balance_reserve = max; } } - dirty_balance_reserve = reserve_pages; totalreserve_pages = reserve_pages; } -- GitLab From 84ad5802a33a4964a49b8f7d24d80a214a096b19 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:20:18 -0800 Subject: [PATCH 2793/2855] proc: meminfo: estimate available memory more conservatively The MemAvailable item in /proc/meminfo is to give users a hint of how much memory is allocatable without causing swapping, so it excludes the zones' low watermarks as unavailable to userspace. However, for a userspace allocation, kswapd will actually reclaim until the free pages hit a combination of the high watermark and the page allocator's lowmem protection that keeps a certain amount of DMA and DMA32 memory from userspace as well. Subtract the full amount we know to be unavailable to userspace from the number of free pages when calculating MemAvailable. Signed-off-by: Johannes Weiner Cc: Rik van Riel Cc: Mel Gorman Acked-by: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/meminfo.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index 9155a5a0d3b9d..df4661abadc40 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c @@ -57,11 +57,8 @@ static int meminfo_proc_show(struct seq_file *m, void *v) /* * Estimate the amount of memory available for userspace allocations, * without causing swapping. - * - * Free memory cannot be taken below the low watermark, before the - * system starts swapping. */ - available = i.freeram - wmark_low; + available = i.freeram - totalreserve_pages; /* * Not all the page cache can be freed, otherwise the system will -- GitLab From 56c6b5d3acd8e0cfc302ff56f58c15fea27064de Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Thu, 14 Jan 2016 15:20:21 -0800 Subject: [PATCH 2794/2855] drivers/base/memory.c: clean up section counting Right now, section_count is calculated in add_memory_block(). However, init_memory_block() increments section_count as well, which, at first, seems like it would lead to an off-by-one error. There is no harm done because add_memory_block() immediately overwrites the mem->section_count, but it is messy. This commit moves the increment out of the common init_memory_block() (called by both add_memory_block() and register_new_memory()) and adds it to register_new_memory(). Signed-off-by: Seth Jennings Cc: Andrew Banman Cc: Daniel J Blueman Cc: Yinghai Lu Cc: Greg KH Cc: Russ Anderson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 25425d3f25753..17173f655f89d 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -618,7 +618,6 @@ static int init_memory_block(struct memory_block **memory, base_memory_block_id(scn_nr) * sections_per_block; mem->end_section_nr = mem->start_section_nr + sections_per_block - 1; mem->state = state; - mem->section_count++; start_pfn = section_nr_to_pfn(mem->start_section_nr); mem->phys_device = arch_get_memory_phys_device(start_pfn); @@ -672,6 +671,7 @@ int register_new_memory(int nid, struct mem_section *section) ret = init_memory_block(&mem, section, MEM_OFFLINE); if (ret) goto out; + mem->section_count++; } if (mem->section_count == sections_per_block) -- GitLab From cc292b0b43027cce9310a18ec3239b5e9b4ea301 Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Thu, 14 Jan 2016 15:20:24 -0800 Subject: [PATCH 2795/2855] drivers/base/memory.c: rename remove_memory_block() to remove_memory_section() The function removes a section, not a block. Rename to reflect actual functionality. Signed-off-by: Seth Jennings Cc: Andrew Banman Cc: Daniel J Blueman Cc: Yinghai Lu Cc: Greg KH Cc: Russ Anderson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/memory.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 17173f655f89d..6d7b14c2798e1 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -692,7 +692,7 @@ unregister_memory(struct memory_block *memory) device_unregister(&memory->dev); } -static int remove_memory_block(unsigned long node_id, +static int remove_memory_section(unsigned long node_id, struct mem_section *section, int phys_device) { struct memory_block *mem; @@ -716,7 +716,7 @@ int unregister_memory_section(struct mem_section *section) if (!present_section(section)) return -EINVAL; - return remove_memory_block(0, section, 0); + return remove_memory_section(0, section, 0); } #endif /* CONFIG_MEMORY_HOTREMOVE */ -- GitLab From 6ac0206bc0d13381e3ede3594bc0a3f8cd1d8ec9 Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Thu, 14 Jan 2016 15:20:28 -0800 Subject: [PATCH 2796/2855] mm/page_alloc.c: remove unnecessary parameter from __rmqueue Commit 0aaa29a56e4f ("mm, page_alloc: reserve pageblocks for high-order atomic allocations on demand") added an unnecessary and unused parameter to __rmqueue. It was a parameter that was used in an earlier version of the patch and then left behind. This patch cleans it up. Signed-off-by: Mel Gorman Acked-by: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 1e9a560654002..fbff97d7b2986 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1781,7 +1781,7 @@ __rmqueue_fallback(struct zone *zone, unsigned int order, int start_migratetype) * Call me with the zone->lock already held. */ static struct page *__rmqueue(struct zone *zone, unsigned int order, - int migratetype, gfp_t gfp_flags) + int migratetype) { struct page *page; @@ -1811,7 +1811,7 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order, spin_lock(&zone->lock); for (i = 0; i < count; ++i) { - struct page *page = __rmqueue(zone, order, migratetype, 0); + struct page *page = __rmqueue(zone, order, migratetype); if (unlikely(page == NULL)) break; @@ -2234,7 +2234,7 @@ struct page *buffered_rmqueue(struct zone *preferred_zone, trace_mm_page_alloc_zone_locked(page, order, migratetype); } if (!page) - page = __rmqueue(zone, order, migratetype, gfp_flags); + page = __rmqueue(zone, order, migratetype); spin_unlock(&zone->lock); if (!page) goto failed; -- GitLab From a16601c5458eb702f26cd48b9e8e1a9471700e72 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 14 Jan 2016 15:20:30 -0800 Subject: [PATCH 2797/2855] mm/page_alloc.c: use list_{first,last}_entry instead of list_entry To make the intention clearer, use list_{first,last}_entry instead of list_entry. Signed-off-by: Geliang Tang Acked-by: Michal Hocko Acked-by: Mel Gorman Acked-by: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index fbff97d7b2986..b9747aa0fb593 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -805,7 +805,7 @@ static void free_pcppages_bulk(struct zone *zone, int count, do { int mt; /* migratetype of the to-be-freed page */ - page = list_entry(list->prev, struct page, lru); + page = list_last_entry(list, struct page, lru); /* must delete as __free_one_page list manipulates */ list_del(&page->lru); @@ -1410,11 +1410,10 @@ struct page *__rmqueue_smallest(struct zone *zone, unsigned int order, /* Find a page of the appropriate size in the preferred list */ for (current_order = order; current_order < MAX_ORDER; ++current_order) { area = &(zone->free_area[current_order]); - if (list_empty(&area->free_list[migratetype])) - continue; - - page = list_entry(area->free_list[migratetype].next, + page = list_first_entry_or_null(&area->free_list[migratetype], struct page, lru); + if (!page) + continue; list_del(&page->lru); rmv_page_order(page); area->nr_free--; @@ -1693,12 +1692,12 @@ static void unreserve_highatomic_pageblock(const struct alloc_context *ac) for (order = 0; order < MAX_ORDER; order++) { struct free_area *area = &(zone->free_area[order]); - if (list_empty(&area->free_list[MIGRATE_HIGHATOMIC])) + page = list_first_entry_or_null( + &area->free_list[MIGRATE_HIGHATOMIC], + struct page, lru); + if (!page) continue; - page = list_entry(area->free_list[MIGRATE_HIGHATOMIC].next, - struct page, lru); - /* * It should never happen but changes to locking could * inadvertently allow a per-cpu drain to add pages @@ -1746,7 +1745,7 @@ __rmqueue_fallback(struct zone *zone, unsigned int order, int start_migratetype) if (fallback_mt == -1) continue; - page = list_entry(area->free_list[fallback_mt].next, + page = list_first_entry(&area->free_list[fallback_mt], struct page, lru); if (can_steal) steal_suitable_fallback(zone, page, start_migratetype); @@ -2205,9 +2204,9 @@ struct page *buffered_rmqueue(struct zone *preferred_zone, } if (cold) - page = list_entry(list->prev, struct page, lru); + page = list_last_entry(list, struct page, lru); else - page = list_entry(list->next, struct page, lru); + page = list_first_entry(list, struct page, lru); list_del(&page->lru); pcp->count--; -- GitLab From 86760a2c6e827858f8eaf020b12b72b3210faf79 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 14 Jan 2016 15:20:33 -0800 Subject: [PATCH 2798/2855] mm/page_alloc.c: use list_for_each_entry in mark_free_pages() Use list_for_each_entry instead of list_for_each + list_entry to simplify the code. Signed-off-by: Geliang Tang Acked-by: Michal Hocko Acked-by: Mel Gorman Acked-by: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index b9747aa0fb593..d7f5bc8951571 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1980,7 +1980,7 @@ void mark_free_pages(struct zone *zone) unsigned long pfn, max_zone_pfn; unsigned long flags; unsigned int order, t; - struct list_head *curr; + struct page *page; if (zone_is_empty(zone)) return; @@ -1990,17 +1990,17 @@ void mark_free_pages(struct zone *zone) max_zone_pfn = zone_end_pfn(zone); for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++) if (pfn_valid(pfn)) { - struct page *page = pfn_to_page(pfn); - + page = pfn_to_page(pfn); if (!swsusp_page_is_forbidden(page)) swsusp_unset_page_free(page); } for_each_migratetype_order(order, t) { - list_for_each(curr, &zone->free_area[order].free_list[t]) { + list_for_each_entry(page, + &zone->free_area[order].free_list[t], lru) { unsigned long i; - pfn = page_to_pfn(list_entry(curr, struct page, lru)); + pfn = page_to_pfn(page); for (i = 0; i < (1UL << order); i++) swsusp_set_page_free(pfn_to_page(pfn + i)); } -- GitLab From 5020e285856cb406224e6f977fd893a006077806 Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Thu, 14 Jan 2016 15:20:36 -0800 Subject: [PATCH 2799/2855] mm, oom: give __GFP_NOFAIL allocations access to memory reserves __GFP_NOFAIL is a big hammer used to ensure that the allocation request can never fail. This is a strong requirement and as such it also deserves a special treatment when the system is OOM. The primary problem here is that the allocation request might have come with some locks held and the oom victim might be blocked on the same locks. This is basically an OOM deadlock situation. This patch tries to reduce the risk of such a deadlocks by giving __GFP_NOFAIL allocations a special treatment and let them dive into memory reserves after oom killer invocation. This should help them to make a progress and release resources they are holding. The OOM victim should compensate for the reserves consumption. Signed-off-by: Michal Hocko Suggested-by: Andrea Arcangeli Cc: Mel Gorman Cc: Johannes Weiner Acked-by: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index d7f5bc8951571..ce63d603820f1 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2732,8 +2732,21 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, goto out; } /* Exhausted what can be done so it's blamo time */ - if (out_of_memory(&oc) || WARN_ON_ONCE(gfp_mask & __GFP_NOFAIL)) + if (out_of_memory(&oc) || WARN_ON_ONCE(gfp_mask & __GFP_NOFAIL)) { *did_some_progress = 1; + + if (gfp_mask & __GFP_NOFAIL) { + page = get_page_from_freelist(gfp_mask, order, + ALLOC_NO_WATERMARKS|ALLOC_CPUSET, ac); + /* + * fallback to ignore cpuset restriction if our nodes + * are depleted + */ + if (!page) + page = get_page_from_freelist(gfp_mask, order, + ALLOC_NO_WATERMARKS, ac); + } + } out: mutex_unlock(&oom_lock); return page; -- GitLab From f14516fbf0f6bec7d98c1cb5b5c73ccd2bb4a5e9 Mon Sep 17 00:00:00 2001 From: Alexander Kuleshov Date: Thu, 14 Jan 2016 15:20:39 -0800 Subject: [PATCH 2800/2855] mm/memblock: remove rgnbase and rgnsize variables Remove rgnbase and rgnsize variables from memblock_overlaps_region(). We use these variables only for passing to the memblock_addrs_overlap() function and that's all. Let's remove them. Signed-off-by: Alexander Kuleshov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memblock.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/mm/memblock.c b/mm/memblock.c index 9695398a14c04..c33a2a2ae69fd 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -96,13 +96,10 @@ bool __init_memblock memblock_overlaps_region(struct memblock_type *type, { unsigned long i; - for (i = 0; i < type->cnt; i++) { - phys_addr_t rgnbase = type->regions[i].base; - phys_addr_t rgnsize = type->regions[i].size; - if (memblock_addrs_overlap(base, size, rgnbase, rgnsize)) + for (i = 0; i < type->cnt; i++) + if (memblock_addrs_overlap(base, size, type->regions[i].base, + type->regions[i].size)) break; - } - return i < type->cnt; } -- GitLab From 8c9c1701c7c23a57ebfd1a0b27b87053ae43cfb5 Mon Sep 17 00:00:00 2001 From: Alexander Kuleshov Date: Thu, 14 Jan 2016 15:20:42 -0800 Subject: [PATCH 2801/2855] mm/memblock: introduce for_each_memblock_type() We already have the for_each_memblock() macro in which provides ability to iterate over memblock regions of a known type. The for_each_memblock() macro allows us to pass the pointer to the struct memblock_type, instead we need to pass name of the type. This patch introduces a new macro for_each_memblock_type() which allows us iterate over memblock regions with the given type when the type is unknown. Signed-off-by: Alexander Kuleshov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memblock.h | 5 +++++ mm/memblock.c | 32 ++++++++++++++++---------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 3a092fba2eb21..c0c4208a286fa 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -399,6 +399,11 @@ static inline unsigned long memblock_region_reserved_end_pfn(const struct memblo region < (memblock.memblock_type.regions + memblock.memblock_type.cnt); \ region++) +#define for_each_memblock_type(memblock_type, rgn) \ + idx = 0; \ + rgn = &memblock_type->regions[idx]; \ + for (idx = 0; idx < memblock_type->cnt; \ + idx++,rgn = &memblock_type->regions[idx]) #ifdef CONFIG_ARCH_DISCARD_MEMBLOCK #define __init_memblock __meminit diff --git a/mm/memblock.c b/mm/memblock.c index c33a2a2ae69fd..d2ed81e59a94c 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -525,7 +525,8 @@ int __init_memblock memblock_add_range(struct memblock_type *type, bool insert = false; phys_addr_t obase = base; phys_addr_t end = base + memblock_cap_size(base, &size); - int i, nr_new; + int idx, nr_new; + struct memblock_region *rgn; if (!size) return 0; @@ -549,8 +550,7 @@ repeat: base = obase; nr_new = 0; - for (i = 0; i < type->cnt; i++) { - struct memblock_region *rgn = &type->regions[i]; + for_each_memblock_type(type, rgn) { phys_addr_t rbase = rgn->base; phys_addr_t rend = rbase + rgn->size; @@ -569,7 +569,7 @@ repeat: WARN_ON(flags != rgn->flags); nr_new++; if (insert) - memblock_insert_region(type, i++, base, + memblock_insert_region(type, idx++, base, rbase - base, nid, flags); } @@ -581,7 +581,7 @@ repeat: if (base < end) { nr_new++; if (insert) - memblock_insert_region(type, i, base, end - base, + memblock_insert_region(type, idx, base, end - base, nid, flags); } @@ -648,7 +648,8 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type, int *start_rgn, int *end_rgn) { phys_addr_t end = base + memblock_cap_size(base, &size); - int i; + int idx; + struct memblock_region *rgn; *start_rgn = *end_rgn = 0; @@ -660,8 +661,7 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type, if (memblock_double_array(type, base, size) < 0) return -ENOMEM; - for (i = 0; i < type->cnt; i++) { - struct memblock_region *rgn = &type->regions[i]; + for_each_memblock_type(type, rgn) { phys_addr_t rbase = rgn->base; phys_addr_t rend = rbase + rgn->size; @@ -678,7 +678,7 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type, rgn->base = base; rgn->size -= base - rbase; type->total_size -= base - rbase; - memblock_insert_region(type, i, rbase, base - rbase, + memblock_insert_region(type, idx, rbase, base - rbase, memblock_get_region_node(rgn), rgn->flags); } else if (rend > end) { @@ -689,14 +689,14 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type, rgn->base = end; rgn->size -= end - rbase; type->total_size -= end - rbase; - memblock_insert_region(type, i--, rbase, end - rbase, + memblock_insert_region(type, idx--, rbase, end - rbase, memblock_get_region_node(rgn), rgn->flags); } else { /* @rgn is fully contained, record it */ if (!*end_rgn) - *start_rgn = i; - *end_rgn = i + 1; + *start_rgn = idx; + *end_rgn = idx + 1; } } @@ -1638,12 +1638,12 @@ static void __init_memblock memblock_dump(struct memblock_type *type, char *name { unsigned long long base, size; unsigned long flags; - int i; + int idx; + struct memblock_region *rgn; pr_info(" %s.cnt = 0x%lx\n", name, type->cnt); - for (i = 0; i < type->cnt; i++) { - struct memblock_region *rgn = &type->regions[i]; + for_each_memblock_type(type, rgn) { char nid_buf[32] = ""; base = rgn->base; @@ -1655,7 +1655,7 @@ static void __init_memblock memblock_dump(struct memblock_type *type, char *name memblock_get_region_node(rgn)); #endif pr_info(" %s[%#x]\t[%#016llx-%#016llx], %#llx bytes%s flags: %#lx\n", - name, i, base, base + size - 1, size, nid_buf, flags); + name, idx, base, base + size - 1, size, nid_buf, flags); } } -- GitLab From a8ae49917077facbe4ed7b3a89bf025b1cefa0ed Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 14 Jan 2016 15:20:45 -0800 Subject: [PATCH 2802/2855] mm/swapfile.c: use list_{next,first}_entry To make the intention clearer, use list_{next,first}_entry instead of list_entry(). Signed-off-by: Geliang Tang Cc: "Kirill A. Shutemov" Cc: Jerome Marchand Cc: Vlastimil Babka Cc: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/swapfile.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/mm/swapfile.c b/mm/swapfile.c index 58877312cf6b9..77551a553f57d 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -165,8 +165,6 @@ static void discard_swap_cluster(struct swap_info_struct *si, int found_extent = 0; while (nr_pages) { - struct list_head *lh; - if (se->start_page <= start_page && start_page < se->start_page + se->nr_pages) { pgoff_t offset = start_page - se->start_page; @@ -188,8 +186,7 @@ static void discard_swap_cluster(struct swap_info_struct *si, break; } - lh = se->list.next; - se = list_entry(lh, struct swap_extent, list); + se = list_next_entry(se, list); } } @@ -903,7 +900,7 @@ int swp_swapcount(swp_entry_t entry) VM_BUG_ON(page_private(page) != SWP_CONTINUED); do { - page = list_entry(page->lru.next, struct page, lru); + page = list_next_entry(page, lru); map = kmap_atomic(page); tmp_count = map[offset]; kunmap_atomic(map); @@ -1633,14 +1630,11 @@ static sector_t map_swap_entry(swp_entry_t entry, struct block_device **bdev) se = start_se; for ( ; ; ) { - struct list_head *lh; - if (se->start_page <= offset && offset < (se->start_page + se->nr_pages)) { return se->start_block + (offset - se->start_page); } - lh = se->list.next; - se = list_entry(lh, struct swap_extent, list); + se = list_next_entry(se, list); sis->curr_swap_extent = se; BUG_ON(se == start_se); /* It *must* be present */ } @@ -1664,7 +1658,7 @@ static void destroy_swap_extents(struct swap_info_struct *sis) while (!list_empty(&sis->first_swap_extent.list)) { struct swap_extent *se; - se = list_entry(sis->first_swap_extent.list.next, + se = list_first_entry(&sis->first_swap_extent.list, struct swap_extent, list); list_del(&se->list); kfree(se); -- GitLab From 7546934570f48283b7fe64a56d1c984fcb1e341e Mon Sep 17 00:00:00 2001 From: Joonsoo Kim Date: Thu, 14 Jan 2016 15:20:48 -0800 Subject: [PATCH 2803/2855] mm/compaction.c: __compact_pgdat() code cleanuup This patch uses is_via_compact_memory() to distinguish compaction from sysfs or sysctl. And, this patch also reduces indentation on compaction_defer_reset() by filtering these cases first before checking watermark. There is no functional change. Signed-off-by: Joonsoo Kim Acked-by: Yaowei Bai Acked-by: David Rientjes Acked-by: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/compaction.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/mm/compaction.c b/mm/compaction.c index ac6c6943d2ce0..585de54dbe8cc 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -1658,14 +1658,15 @@ static void __compact_pgdat(pg_data_t *pgdat, struct compact_control *cc) !compaction_deferred(zone, cc->order)) compact_zone(zone, cc); - if (cc->order > 0) { - if (zone_watermark_ok(zone, cc->order, - low_wmark_pages(zone), 0, 0)) - compaction_defer_reset(zone, cc->order, false); - } - VM_BUG_ON(!list_empty(&cc->freepages)); VM_BUG_ON(!list_empty(&cc->migratepages)); + + if (is_via_compact_memory(cc->order)) + continue; + + if (zone_watermark_ok(zone, cc->order, + low_wmark_pages(zone), 0, 0)) + compaction_defer_reset(zone, cc->order, false); } } -- GitLab From c8ad6302c2b664e73f0abb3517c16531e294b9d7 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 14 Jan 2016 15:20:51 -0800 Subject: [PATCH 2804/2855] mm/readahead.c, mm/vmscan.c: use lru_to_page instead of list_to_page list_to_page() in readahead.c is the same as lru_to_page() in vmscan.c. So I move lru_to_page to internal.h and drop list_to_page(). Signed-off-by: Geliang Tang Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/internal.h | 2 ++ mm/readahead.c | 8 +++----- mm/vmscan.c | 2 -- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/mm/internal.h b/mm/internal.h index 38e24b89e4c40..016452d2fede4 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -119,6 +119,8 @@ extern int isolate_lru_page(struct page *page); extern void putback_lru_page(struct page *page); extern bool zone_reclaimable(struct zone *zone); +#define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru)) + /* * in mm/rmap.c: */ diff --git a/mm/readahead.c b/mm/readahead.c index ba22d7fe0afba..0aff760b09d4a 100644 --- a/mm/readahead.c +++ b/mm/readahead.c @@ -32,8 +32,6 @@ file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping) } EXPORT_SYMBOL_GPL(file_ra_state_init); -#define list_to_page(head) (list_entry((head)->prev, struct page, lru)) - /* * see if a page needs releasing upon read_cache_pages() failure * - the caller of read_cache_pages() may have set PG_private or PG_fscache @@ -64,7 +62,7 @@ static void read_cache_pages_invalidate_pages(struct address_space *mapping, struct page *victim; while (!list_empty(pages)) { - victim = list_to_page(pages); + victim = lru_to_page(pages); list_del(&victim->lru); read_cache_pages_invalidate_page(mapping, victim); } @@ -87,7 +85,7 @@ int read_cache_pages(struct address_space *mapping, struct list_head *pages, int ret = 0; while (!list_empty(pages)) { - page = list_to_page(pages); + page = lru_to_page(pages); list_del(&page->lru); if (add_to_page_cache_lru(page, mapping, page->index, mapping_gfp_constraint(mapping, GFP_KERNEL))) { @@ -125,7 +123,7 @@ static int read_pages(struct address_space *mapping, struct file *filp, } for (page_idx = 0; page_idx < nr_pages; page_idx++) { - struct page *page = list_to_page(pages); + struct page *page = lru_to_page(pages); list_del(&page->lru); if (!add_to_page_cache_lru(page, mapping, page->index, mapping_gfp_constraint(mapping, GFP_KERNEL))) { diff --git a/mm/vmscan.c b/mm/vmscan.c index 1bbfd623630eb..e36d766dade97 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -106,8 +106,6 @@ struct scan_control { unsigned long nr_reclaimed; }; -#define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru)) - #ifdef ARCH_HAS_PREFETCH #define prefetch_prev_lru_page(_page, _base, _field) \ do { \ -- GitLab From 036404183eb3ebff93dea7b572fc718e9d652c7f Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 14 Jan 2016 15:20:54 -0800 Subject: [PATCH 2805/2855] mm/ksm.c: use list_for_each_entry_safe Use list_for_each_entry_safe() instead of list_for_each_safe() to simplify the code. Signed-off-by: Geliang Tang Cc: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/ksm.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/mm/ksm.c b/mm/ksm.c index b5cd647daa524..2d162c5625f6a 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -740,8 +740,7 @@ static int remove_stable_node(struct stable_node *stable_node) static int remove_all_stable_nodes(void) { - struct stable_node *stable_node; - struct list_head *this, *next; + struct stable_node *stable_node, *next; int nid; int err = 0; @@ -756,8 +755,7 @@ static int remove_all_stable_nodes(void) cond_resched(); } } - list_for_each_safe(this, next, &migrate_nodes) { - stable_node = list_entry(this, struct stable_node, list); + list_for_each_entry_safe(stable_node, next, &migrate_nodes, list) { if (remove_stable_node(stable_node)) err = -EBUSY; cond_resched(); @@ -1583,13 +1581,11 @@ static struct rmap_item *scan_get_next_rmap_item(struct page **page) * so prune them once before each full scan. */ if (!ksm_merge_across_nodes) { - struct stable_node *stable_node; - struct list_head *this, *next; + struct stable_node *stable_node, *next; struct page *page; - list_for_each_safe(this, next, &migrate_nodes) { - stable_node = list_entry(this, - struct stable_node, list); + list_for_each_entry_safe(stable_node, next, + &migrate_nodes, list) { page = get_ksm_page(stable_node, false); if (page) put_page(page); @@ -2012,8 +2008,7 @@ static void wait_while_offlining(void) static void ksm_check_stable_tree(unsigned long start_pfn, unsigned long end_pfn) { - struct stable_node *stable_node; - struct list_head *this, *next; + struct stable_node *stable_node, *next; struct rb_node *node; int nid; @@ -2034,8 +2029,7 @@ static void ksm_check_stable_tree(unsigned long start_pfn, cond_resched(); } } - list_for_each_safe(this, next, &migrate_nodes) { - stable_node = list_entry(this, struct stable_node, list); + list_for_each_entry_safe(stable_node, next, &migrate_nodes, list) { if (stable_node->kpfn >= start_pfn && stable_node->kpfn < end_pfn) remove_node_from_stable_tree(stable_node); -- GitLab From 7d828602e5ef3297a69392a2d31264e4ab9c8bb7 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:20:56 -0800 Subject: [PATCH 2806/2855] mm: memcontrol: export root_mem_cgroup A later patch will need this symbol in files other than memcontrol.c, so export it now and replace mem_cgroup_root_css at the same time. Signed-off-by: Johannes Weiner Acked-by: Michal Hocko Acked-by: David S. Miller Reviewed-by: Vladimir Davydov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 3 ++- mm/backing-dev.c | 2 +- mm/memcontrol.c | 5 ++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 78a1ec2e23fcf..d0c724f53691e 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -265,7 +265,8 @@ struct mem_cgroup { struct mem_cgroup_per_node *nodeinfo[0]; /* WARNING: nodeinfo must be the last member here */ }; -extern struct cgroup_subsys_state *mem_cgroup_root_css; + +extern struct mem_cgroup *root_mem_cgroup; /** * mem_cgroup_events - count memory events against a cgroup diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 7340353f8aea0..cc5d29d2da9b4 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c @@ -672,7 +672,7 @@ static int cgwb_bdi_init(struct backing_dev_info *bdi) ret = wb_init(&bdi->wb, bdi, 1, GFP_KERNEL); if (!ret) { - bdi->wb.memcg_css = mem_cgroup_root_css; + bdi->wb.memcg_css = &root_mem_cgroup->css; bdi->wb.blkcg_css = blkcg_root_css; } return ret; diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 0bc140d998add..44ed2dee8f0cd 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -76,9 +76,9 @@ struct cgroup_subsys memory_cgrp_subsys __read_mostly; EXPORT_SYMBOL(memory_cgrp_subsys); +struct mem_cgroup *root_mem_cgroup __read_mostly; + #define MEM_CGROUP_RECLAIM_RETRIES 5 -static struct mem_cgroup *root_mem_cgroup __read_mostly; -struct cgroup_subsys_state *mem_cgroup_root_css __read_mostly; /* Whether the swap controller is active */ #ifdef CONFIG_MEMCG_SWAP @@ -4241,7 +4241,6 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) /* root ? */ if (parent_css == NULL) { root_mem_cgroup = memcg; - mem_cgroup_root_css = &memcg->css; page_counter_init(&memcg->memory, NULL); memcg->high = PAGE_COUNTER_MAX; memcg->soft_limit = PAGE_COUNTER_MAX; -- GitLab From 8c2c2358b236530bc2c79b4c2a447cbdbc3d96d7 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:20:59 -0800 Subject: [PATCH 2807/2855] net: tcp_memcontrol: properly detect ancestor socket pressure When charging socket memory, the code currently checks only the local page counter for excess to determine whether the memcg is under socket pressure. But even if the local counter is fine, one of the ancestors could have breached its limit, which should also force this child to enter socket pressure. This currently doesn't happen. Fix this by using page_counter_try_charge() first. If that fails, it means that either the local counter or one of the ancestors are in excess of their limit, and the child should enter socket pressure. Fixes: 3e32cb2e0a12 ("mm: memcontrol: lockless page counters") Signed-off-by: Johannes Weiner Acked-by: David S. Miller Reviewed-by: Vladimir Davydov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/net/sock.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index e830c10069350..9ef3d7c984b44 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1193,11 +1193,13 @@ static inline void memcg_memory_allocated_add(struct cg_proto *prot, unsigned long amt, int *parent_status) { - page_counter_charge(&prot->memory_allocated, amt); + struct page_counter *counter; + + if (page_counter_try_charge(&prot->memory_allocated, amt, &counter)) + return; - if (page_counter_read(&prot->memory_allocated) > - prot->memory_allocated.limit) - *parent_status = OVER_LIMIT; + page_counter_charge(&prot->memory_allocated, amt); + *parent_status = OVER_LIMIT; } static inline void memcg_memory_allocated_sub(struct cg_proto *prot, -- GitLab From 931f3f4beb031cd483c1c8ab159ef1f8bdbe8888 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:02 -0800 Subject: [PATCH 2808/2855] net: tcp_memcontrol: remove bogus hierarchy pressure propagation When a cgroup currently breaches its socket memory limit, it enters memory pressure mode for itself and its *ancestors*. This throttles transmission in unrelated sibling and cousin subtrees that have nothing to do with the breached limit. On the contrary, breaching a limit should make that group and its *children* enter memory pressure mode. But this happens already, albeit lazily: if an ancestor limit is breached, siblings will enter memory pressure on their own once the next packet arrives for them. So no additional hierarchy code is needed. Remove the bogus stuff. Signed-off-by: Johannes Weiner Acked-by: David S. Miller Reviewed-by: Vladimir Davydov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/net/sock.h | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index 9ef3d7c984b44..d3b035c7362b9 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1155,14 +1155,8 @@ static inline void sk_leave_memory_pressure(struct sock *sk) if (*memory_pressure) *memory_pressure = 0; - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) { - struct cg_proto *cg_proto = sk->sk_cgrp; - struct proto *prot = sk->sk_prot; - - for (; cg_proto; cg_proto = parent_cg_proto(prot, cg_proto)) - cg_proto->memory_pressure = 0; - } - + if (mem_cgroup_sockets_enabled && sk->sk_cgrp) + sk->sk_cgrp->memory_pressure = 0; } static inline void sk_enter_memory_pressure(struct sock *sk) @@ -1170,13 +1164,8 @@ static inline void sk_enter_memory_pressure(struct sock *sk) if (!sk->sk_prot->enter_memory_pressure) return; - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) { - struct cg_proto *cg_proto = sk->sk_cgrp; - struct proto *prot = sk->sk_prot; - - for (; cg_proto; cg_proto = parent_cg_proto(prot, cg_proto)) - cg_proto->memory_pressure = 1; - } + if (mem_cgroup_sockets_enabled && sk->sk_cgrp) + sk->sk_cgrp->memory_pressure = 1; sk->sk_prot->enter_memory_pressure(sk); } -- GitLab From 3d596f7b907b0281b997cf30c92994a71ad0a1a9 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:05 -0800 Subject: [PATCH 2809/2855] net: tcp_memcontrol: protect all tcp_memcontrol calls by jump-label Move the jump-label from sock_update_memcg() and sock_release_memcg() to the callsite, and so eliminate those function calls when socket accounting is not enabled. This also eliminates the need for dummy functions because the calls will be optimized away if the Kconfig options are not enabled. Signed-off-by: Johannes Weiner Acked-by: David S. Miller Reviewed-by: Vladimir Davydov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 9 ------ mm/memcontrol.c | 56 +++++++++++++++++--------------------- net/core/sock.c | 9 ++---- net/ipv4/tcp.c | 3 +- net/ipv4/tcp_ipv4.c | 4 ++- 5 files changed, 32 insertions(+), 49 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index d0c724f53691e..85c437b0cbc0a 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -694,17 +694,8 @@ static inline void mem_cgroup_wb_stats(struct bdi_writeback *wb, #endif /* CONFIG_CGROUP_WRITEBACK */ struct sock; -#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM) void sock_update_memcg(struct sock *sk); void sock_release_memcg(struct sock *sk); -#else -static inline void sock_update_memcg(struct sock *sk) -{ -} -static inline void sock_release_memcg(struct sock *sk) -{ -} -#endif /* CONFIG_INET && CONFIG_MEMCG_KMEM */ #ifdef CONFIG_MEMCG_KMEM extern struct static_key memcg_kmem_enabled_key; diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 44ed2dee8f0cd..d9344dad207e0 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -293,46 +293,40 @@ static inline struct mem_cgroup *mem_cgroup_from_id(unsigned short id) void sock_update_memcg(struct sock *sk) { - if (mem_cgroup_sockets_enabled) { - struct mem_cgroup *memcg; - struct cg_proto *cg_proto; + struct mem_cgroup *memcg; + struct cg_proto *cg_proto; - BUG_ON(!sk->sk_prot->proto_cgroup); + BUG_ON(!sk->sk_prot->proto_cgroup); - /* Socket cloning can throw us here with sk_cgrp already - * filled. It won't however, necessarily happen from - * process context. So the test for root memcg given - * the current task's memcg won't help us in this case. - * - * Respecting the original socket's memcg is a better - * decision in this case. - */ - if (sk->sk_cgrp) { - BUG_ON(mem_cgroup_is_root(sk->sk_cgrp->memcg)); - css_get(&sk->sk_cgrp->memcg->css); - return; - } + /* Socket cloning can throw us here with sk_cgrp already + * filled. It won't however, necessarily happen from + * process context. So the test for root memcg given + * the current task's memcg won't help us in this case. + * + * Respecting the original socket's memcg is a better + * decision in this case. + */ + if (sk->sk_cgrp) { + BUG_ON(mem_cgroup_is_root(sk->sk_cgrp->memcg)); + css_get(&sk->sk_cgrp->memcg->css); + return; + } - rcu_read_lock(); - memcg = mem_cgroup_from_task(current); - cg_proto = sk->sk_prot->proto_cgroup(memcg); - if (cg_proto && cg_proto->active && - css_tryget_online(&memcg->css)) { - sk->sk_cgrp = cg_proto; - } - rcu_read_unlock(); + rcu_read_lock(); + memcg = mem_cgroup_from_task(current); + cg_proto = sk->sk_prot->proto_cgroup(memcg); + if (cg_proto && cg_proto->active && + css_tryget_online(&memcg->css)) { + sk->sk_cgrp = cg_proto; } + rcu_read_unlock(); } EXPORT_SYMBOL(sock_update_memcg); void sock_release_memcg(struct sock *sk) { - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) { - struct mem_cgroup *memcg; - WARN_ON(!sk->sk_cgrp->memcg); - memcg = sk->sk_cgrp->memcg; - css_put(&sk->sk_cgrp->memcg->css); - } + WARN_ON(!sk->sk_cgrp->memcg); + css_put(&sk->sk_cgrp->memcg->css); } struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg) diff --git a/net/core/sock.c b/net/core/sock.c index 51270238e2692..6c5dab01105bb 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1507,12 +1507,6 @@ void sk_free(struct sock *sk) } EXPORT_SYMBOL(sk_free); -static void sk_update_clone(const struct sock *sk, struct sock *newsk) -{ - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - sock_update_memcg(newsk); -} - /** * sk_clone_lock - clone a socket, and lock its clone * @sk: the socket to clone @@ -1607,7 +1601,8 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) sk_set_socket(newsk, NULL); newsk->sk_wq = NULL; - sk_update_clone(sk, newsk); + if (mem_cgroup_sockets_enabled && sk->sk_cgrp) + sock_update_memcg(newsk); if (newsk->sk_prot->sockets_allocated) sk_sockets_allocated_inc(newsk); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 7bb1b091efd17..fd17eec935251 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -422,7 +422,8 @@ void tcp_init_sock(struct sock *sk) sk->sk_rcvbuf = sysctl_tcp_rmem[1]; local_bh_disable(); - sock_update_memcg(sk); + if (mem_cgroup_sockets_enabled) + sock_update_memcg(sk); sk_sockets_allocated_inc(sk); local_bh_enable(); } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 65947c1f4733a..eb39e02899e58 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1818,7 +1818,9 @@ void tcp_v4_destroy_sock(struct sock *sk) tcp_saved_syn_free(tp); sk_sockets_allocated_dec(sk); - sock_release_memcg(sk); + + if (mem_cgroup_sockets_enabled && sk->sk_cgrp) + sock_release_memcg(sk); } EXPORT_SYMBOL(tcp_v4_destroy_sock); -- GitLab From af95d7df4059cfeab7e7c244f3564214aada7dad Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:08 -0800 Subject: [PATCH 2810/2855] net: tcp_memcontrol: remove dead per-memcg count of allocated sockets The number of allocated sockets is used for calculations in the soft limit phase, where packets are accepted but the socket is under memory pressure. Since there is no soft limit phase in tcp_memcontrol, and memory pressure is only entered when packets are already dropped, this is actually dead code. Remove it. As this is the last user of parent_cg_proto(), remove that too. Signed-off-by: Johannes Weiner Acked-by: David S. Miller Reviewed-by: Vladimir Davydov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 1 - include/net/sock.h | 39 +++----------------------------------- net/ipv4/tcp_memcontrol.c | 3 --- 3 files changed, 3 insertions(+), 40 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 85c437b0cbc0a..15acc04ebdd38 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -87,7 +87,6 @@ enum mem_cgroup_events_target { struct cg_proto { struct page_counter memory_allocated; /* Current allocated memory. */ - struct percpu_counter sockets_allocated; /* Current number of sockets. */ int memory_pressure; bool active; long sysctl_mem[3]; diff --git a/include/net/sock.h b/include/net/sock.h index d3b035c7362b9..1f15937ec2084 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1098,19 +1098,9 @@ static inline void sk_refcnt_debug_release(const struct sock *sk) #if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_NET) extern struct static_key memcg_socket_limit_enabled; -static inline struct cg_proto *parent_cg_proto(struct proto *proto, - struct cg_proto *cg_proto) -{ - return proto->proto_cgroup(parent_mem_cgroup(cg_proto->memcg)); -} #define mem_cgroup_sockets_enabled static_key_false(&memcg_socket_limit_enabled) #else #define mem_cgroup_sockets_enabled 0 -static inline struct cg_proto *parent_cg_proto(struct proto *proto, - struct cg_proto *cg_proto) -{ - return NULL; -} #endif static inline bool sk_stream_memory_free(const struct sock *sk) @@ -1236,41 +1226,18 @@ sk_memory_allocated_sub(struct sock *sk, int amt) static inline void sk_sockets_allocated_dec(struct sock *sk) { - struct proto *prot = sk->sk_prot; - - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) { - struct cg_proto *cg_proto = sk->sk_cgrp; - - for (; cg_proto; cg_proto = parent_cg_proto(prot, cg_proto)) - percpu_counter_dec(&cg_proto->sockets_allocated); - } - - percpu_counter_dec(prot->sockets_allocated); + percpu_counter_dec(sk->sk_prot->sockets_allocated); } static inline void sk_sockets_allocated_inc(struct sock *sk) { - struct proto *prot = sk->sk_prot; - - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) { - struct cg_proto *cg_proto = sk->sk_cgrp; - - for (; cg_proto; cg_proto = parent_cg_proto(prot, cg_proto)) - percpu_counter_inc(&cg_proto->sockets_allocated); - } - - percpu_counter_inc(prot->sockets_allocated); + percpu_counter_inc(sk->sk_prot->sockets_allocated); } static inline int sk_sockets_allocated_read_positive(struct sock *sk) { - struct proto *prot = sk->sk_prot; - - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - return percpu_counter_read_positive(&sk->sk_cgrp->sockets_allocated); - - return percpu_counter_read_positive(prot->sockets_allocated); + return percpu_counter_read_positive(sk->sk_prot->sockets_allocated); } static inline int diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c index d07579ada0014..6759e0d6bba1b 100644 --- a/net/ipv4/tcp_memcontrol.c +++ b/net/ipv4/tcp_memcontrol.c @@ -32,7 +32,6 @@ int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss) counter_parent = &parent_cg->memory_allocated; page_counter_init(&cg_proto->memory_allocated, counter_parent); - percpu_counter_init(&cg_proto->sockets_allocated, 0, GFP_KERNEL); return 0; } @@ -46,8 +45,6 @@ void tcp_destroy_cgroup(struct mem_cgroup *memcg) if (!cg_proto) return; - percpu_counter_destroy(&cg_proto->sockets_allocated); - if (cg_proto->active) static_key_slow_dec(&memcg_socket_limit_enabled); -- GitLab From 80f23124f57c77915a7b4201d8dcba38a38b23f0 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:11 -0800 Subject: [PATCH 2811/2855] net: tcp_memcontrol: simplify the per-memcg limit access tcp_memcontrol replicates the global sysctl_mem limit array per cgroup, but it only ever sets these entries to the value of the memory_allocated page_counter limit. Use the latter directly. Signed-off-by: Johannes Weiner Reviewed-by: Vladimir Davydov Acked-by: David S. Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 1 - include/net/sock.h | 8 +++++--- net/ipv4/tcp_memcontrol.c | 8 -------- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 15acc04ebdd38..6c91c1b739515 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -89,7 +89,6 @@ struct cg_proto { struct page_counter memory_allocated; /* Current allocated memory. */ int memory_pressure; bool active; - long sysctl_mem[3]; /* * memcg field is used to find which memcg we belong directly * Each memcg struct can hold more than one cg_proto, so container_of diff --git a/include/net/sock.h b/include/net/sock.h index 1f15937ec2084..8b1f8e5d3a488 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1162,10 +1162,12 @@ static inline void sk_enter_memory_pressure(struct sock *sk) static inline long sk_prot_mem_limits(const struct sock *sk, int index) { - long *prot = sk->sk_prot->sysctl_mem; + long limit = sk->sk_prot->sysctl_mem[index]; + if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - prot = sk->sk_cgrp->sysctl_mem; - return prot[index]; + limit = min_t(long, limit, sk->sk_cgrp->memory_allocated.limit); + + return limit; } static inline void memcg_memory_allocated_add(struct cg_proto *prot, diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c index 6759e0d6bba1b..ef4268d12e43d 100644 --- a/net/ipv4/tcp_memcontrol.c +++ b/net/ipv4/tcp_memcontrol.c @@ -21,9 +21,6 @@ int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss) if (!cg_proto) return 0; - cg_proto->sysctl_mem[0] = sysctl_tcp_mem[0]; - cg_proto->sysctl_mem[1] = sysctl_tcp_mem[1]; - cg_proto->sysctl_mem[2] = sysctl_tcp_mem[2]; cg_proto->memory_pressure = 0; cg_proto->memcg = memcg; @@ -54,7 +51,6 @@ EXPORT_SYMBOL(tcp_destroy_cgroup); static int tcp_update_limit(struct mem_cgroup *memcg, unsigned long nr_pages) { struct cg_proto *cg_proto; - int i; int ret; cg_proto = tcp_prot.proto_cgroup(memcg); @@ -65,10 +61,6 @@ static int tcp_update_limit(struct mem_cgroup *memcg, unsigned long nr_pages) if (ret) return ret; - for (i = 0; i < 3; i++) - cg_proto->sysctl_mem[i] = min_t(long, nr_pages, - sysctl_tcp_mem[i]); - if (!cg_proto->active) { /* * The active flag needs to be written after the static_key -- GitLab From e805605c721021879a1469bdae45c6f80bc985f4 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:14 -0800 Subject: [PATCH 2812/2855] net: tcp_memcontrol: sanitize tcp memory accounting callbacks There won't be a tcp control soft limit, so integrating the memcg code into the global skmem limiting scheme complicates things unnecessarily. Replace this with simple and clear charge and uncharge calls--hidden behind a jump label--to account skb memory. Note that this is not purely aesthetic: as a result of shoehorning the per-memcg code into the same memory accounting functions that handle the global level, the old code would compare the per-memcg consumption against the smaller of the per-memcg limit and the global limit. This allowed the total consumption of multiple sockets to exceed the global limit, as long as the individual sockets stayed within bounds. After this change, the code will always compare the per-memcg consumption to the per-memcg limit, and the global consumption to the global limit, and thus close this loophole. Without a soft limit, the per-memcg memory pressure state in sockets is generally questionable. However, we did it until now, so we continue to enter it when the hard limit is hit, and packets are dropped, to let other sockets in the cgroup know that they shouldn't grow their transmit windows, either. However, keep it simple in the new callback model and leave memory pressure lazily when the next packet is accepted (as opposed to doing it synchroneously when packets are processed). When packets are dropped, network performance will already be in the toilet, so that should be a reasonable trade-off. As described above, consumption is now checked on the per-memcg level and the global level separately. Likewise, memory pressure states are maintained on both the per-memcg level and the global level, and a socket is considered under pressure when either level asserts as much. Signed-off-by: Johannes Weiner Reviewed-by: Vladimir Davydov Acked-by: David S. Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 19 +++++++---- include/net/sock.h | 64 +++++--------------------------------- include/net/tcp.h | 5 +-- mm/memcontrol.c | 32 +++++++++++++++++++ net/core/sock.c | 26 ++++++++++------ net/ipv4/tcp_output.c | 7 +++-- 6 files changed, 77 insertions(+), 76 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 6c91c1b739515..e4e77bd1dd39e 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -660,12 +660,6 @@ void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx) } #endif /* CONFIG_MEMCG */ -enum { - UNDER_LIMIT, - SOFT_LIMIT, - OVER_LIMIT, -}; - #ifdef CONFIG_CGROUP_WRITEBACK struct list_head *mem_cgroup_cgwb_list(struct mem_cgroup *memcg); @@ -694,6 +688,19 @@ static inline void mem_cgroup_wb_stats(struct bdi_writeback *wb, struct sock; void sock_update_memcg(struct sock *sk); void sock_release_memcg(struct sock *sk); +bool mem_cgroup_charge_skmem(struct cg_proto *proto, unsigned int nr_pages); +void mem_cgroup_uncharge_skmem(struct cg_proto *proto, unsigned int nr_pages); +#if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_INET) +static inline bool mem_cgroup_under_socket_pressure(struct cg_proto *proto) +{ + return proto->memory_pressure; +} +#else +static inline bool mem_cgroup_under_pressure(struct cg_proto *proto) +{ + return false; +} +#endif #ifdef CONFIG_MEMCG_KMEM extern struct static_key memcg_kmem_enabled_key; diff --git a/include/net/sock.h b/include/net/sock.h index 8b1f8e5d3a488..94a6c1a740b98 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1129,8 +1129,9 @@ static inline bool sk_under_memory_pressure(const struct sock *sk) if (!sk->sk_prot->memory_pressure) return false; - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - return !!sk->sk_cgrp->memory_pressure; + if (mem_cgroup_sockets_enabled && sk->sk_cgrp && + mem_cgroup_under_socket_pressure(sk->sk_cgrp)) + return true; return !!*sk->sk_prot->memory_pressure; } @@ -1144,9 +1145,6 @@ static inline void sk_leave_memory_pressure(struct sock *sk) if (*memory_pressure) *memory_pressure = 0; - - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - sk->sk_cgrp->memory_pressure = 0; } static inline void sk_enter_memory_pressure(struct sock *sk) @@ -1154,76 +1152,30 @@ static inline void sk_enter_memory_pressure(struct sock *sk) if (!sk->sk_prot->enter_memory_pressure) return; - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - sk->sk_cgrp->memory_pressure = 1; - sk->sk_prot->enter_memory_pressure(sk); } static inline long sk_prot_mem_limits(const struct sock *sk, int index) { - long limit = sk->sk_prot->sysctl_mem[index]; - - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - limit = min_t(long, limit, sk->sk_cgrp->memory_allocated.limit); - - return limit; -} - -static inline void memcg_memory_allocated_add(struct cg_proto *prot, - unsigned long amt, - int *parent_status) -{ - struct page_counter *counter; - - if (page_counter_try_charge(&prot->memory_allocated, amt, &counter)) - return; - - page_counter_charge(&prot->memory_allocated, amt); - *parent_status = OVER_LIMIT; -} - -static inline void memcg_memory_allocated_sub(struct cg_proto *prot, - unsigned long amt) -{ - page_counter_uncharge(&prot->memory_allocated, amt); + return sk->sk_prot->sysctl_mem[index]; } static inline long sk_memory_allocated(const struct sock *sk) { - struct proto *prot = sk->sk_prot; - - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - return page_counter_read(&sk->sk_cgrp->memory_allocated); - - return atomic_long_read(prot->memory_allocated); + return atomic_long_read(sk->sk_prot->memory_allocated); } static inline long -sk_memory_allocated_add(struct sock *sk, int amt, int *parent_status) +sk_memory_allocated_add(struct sock *sk, int amt) { - struct proto *prot = sk->sk_prot; - - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) { - memcg_memory_allocated_add(sk->sk_cgrp, amt, parent_status); - /* update the root cgroup regardless */ - atomic_long_add_return(amt, prot->memory_allocated); - return page_counter_read(&sk->sk_cgrp->memory_allocated); - } - - return atomic_long_add_return(amt, prot->memory_allocated); + return atomic_long_add_return(amt, sk->sk_prot->memory_allocated); } static inline void sk_memory_allocated_sub(struct sock *sk, int amt) { - struct proto *prot = sk->sk_prot; - - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - memcg_memory_allocated_sub(sk->sk_cgrp, amt); - - atomic_long_sub(amt, prot->memory_allocated); + atomic_long_sub(amt, sk->sk_prot->memory_allocated); } static inline void sk_sockets_allocated_dec(struct sock *sk) diff --git a/include/net/tcp.h b/include/net/tcp.h index a80255f4ca33d..d9df80deba31a 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -289,8 +289,9 @@ extern int tcp_memory_pressure; /* optimized version of sk_under_memory_pressure() for TCP sockets */ static inline bool tcp_under_memory_pressure(const struct sock *sk) { - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - return !!sk->sk_cgrp->memory_pressure; + if (mem_cgroup_sockets_enabled && sk->sk_cgrp && + mem_cgroup_under_socket_pressure(sk->sk_cgrp)) + return true; return tcp_memory_pressure; } diff --git a/mm/memcontrol.c b/mm/memcontrol.c index d9344dad207e0..f5de783860b87 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -338,6 +338,38 @@ struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg) } EXPORT_SYMBOL(tcp_proto_cgroup); +/** + * mem_cgroup_charge_skmem - charge socket memory + * @proto: proto to charge + * @nr_pages: number of pages to charge + * + * Charges @nr_pages to @proto. Returns %true if the charge fit within + * @proto's configured limit, %false if the charge had to be forced. + */ +bool mem_cgroup_charge_skmem(struct cg_proto *proto, unsigned int nr_pages) +{ + struct page_counter *counter; + + if (page_counter_try_charge(&proto->memory_allocated, + nr_pages, &counter)) { + proto->memory_pressure = 0; + return true; + } + page_counter_charge(&proto->memory_allocated, nr_pages); + proto->memory_pressure = 1; + return false; +} + +/** + * mem_cgroup_uncharge_skmem - uncharge socket memory + * @proto - proto to uncharge + * @nr_pages - number of pages to uncharge + */ +void mem_cgroup_uncharge_skmem(struct cg_proto *proto, unsigned int nr_pages) +{ + page_counter_uncharge(&proto->memory_allocated, nr_pages); +} + #endif #ifdef CONFIG_MEMCG_KMEM diff --git a/net/core/sock.c b/net/core/sock.c index 6c5dab01105bb..89ae859d2dc54 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -2084,27 +2084,27 @@ int __sk_mem_schedule(struct sock *sk, int size, int kind) struct proto *prot = sk->sk_prot; int amt = sk_mem_pages(size); long allocated; - int parent_status = UNDER_LIMIT; sk->sk_forward_alloc += amt * SK_MEM_QUANTUM; - allocated = sk_memory_allocated_add(sk, amt, &parent_status); + allocated = sk_memory_allocated_add(sk, amt); + + if (mem_cgroup_sockets_enabled && sk->sk_cgrp && + !mem_cgroup_charge_skmem(sk->sk_cgrp, amt)) + goto suppress_allocation; /* Under limit. */ - if (parent_status == UNDER_LIMIT && - allocated <= sk_prot_mem_limits(sk, 0)) { + if (allocated <= sk_prot_mem_limits(sk, 0)) { sk_leave_memory_pressure(sk); return 1; } - /* Under pressure. (we or our parents) */ - if ((parent_status > SOFT_LIMIT) || - allocated > sk_prot_mem_limits(sk, 1)) + /* Under pressure. */ + if (allocated > sk_prot_mem_limits(sk, 1)) sk_enter_memory_pressure(sk); - /* Over hard limit (we or our parents) */ - if ((parent_status == OVER_LIMIT) || - (allocated > sk_prot_mem_limits(sk, 2))) + /* Over hard limit. */ + if (allocated > sk_prot_mem_limits(sk, 2)) goto suppress_allocation; /* guarantee minimum buffer size under pressure */ @@ -2153,6 +2153,9 @@ suppress_allocation: sk_memory_allocated_sub(sk, amt); + if (mem_cgroup_sockets_enabled && sk->sk_cgrp) + mem_cgroup_uncharge_skmem(sk->sk_cgrp, amt); + return 0; } EXPORT_SYMBOL(__sk_mem_schedule); @@ -2168,6 +2171,9 @@ void __sk_mem_reclaim(struct sock *sk, int amount) sk_memory_allocated_sub(sk, amount); sk->sk_forward_alloc -= amount << SK_MEM_QUANTUM_SHIFT; + if (mem_cgroup_sockets_enabled && sk->sk_cgrp) + mem_cgroup_uncharge_skmem(sk->sk_cgrp, amount); + if (sk_under_memory_pressure(sk) && (sk_memory_allocated(sk) < sk_prot_mem_limits(sk, 0))) sk_leave_memory_pressure(sk); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 412a920fe0ec0..493b48945f0c3 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2813,13 +2813,16 @@ begin_fwd: */ void sk_forced_mem_schedule(struct sock *sk, int size) { - int amt, status; + int amt; if (size <= sk->sk_forward_alloc) return; amt = sk_mem_pages(size); sk->sk_forward_alloc += amt * SK_MEM_QUANTUM; - sk_memory_allocated_add(sk, amt, &status); + sk_memory_allocated_add(sk, amt); + + if (mem_cgroup_sockets_enabled && sk->sk_cgrp) + mem_cgroup_charge_skmem(sk->sk_cgrp, amt); } /* Send a FIN. The caller locks the socket for us. -- GitLab From baac50bbc3cdfd184ebf586b1704edbfcee866df Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:17 -0800 Subject: [PATCH 2813/2855] net: tcp_memcontrol: simplify linkage between socket and page counter There won't be any separate counters for socket memory consumed by protocols other than TCP in the future. Remove the indirection and link sockets directly to their owning memory cgroup. Signed-off-by: Johannes Weiner Reviewed-by: Vladimir Davydov Acked-by: David S. Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 20 +++-------- include/net/sock.h | 25 +++----------- include/net/tcp.h | 4 +-- include/net/tcp_memcontrol.h | 1 - mm/memcontrol.c | 57 ++++++++++++------------------ net/core/sock.c | 52 ++++------------------------ net/ipv4/tcp_ipv4.c | 7 +--- net/ipv4/tcp_memcontrol.c | 67 ++++++++++++++---------------------- net/ipv4/tcp_output.c | 4 +-- net/ipv6/tcp_ipv6.c | 3 -- 10 files changed, 69 insertions(+), 171 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index e4e77bd1dd39e..7c085e4636ba4 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -89,16 +89,6 @@ struct cg_proto { struct page_counter memory_allocated; /* Current allocated memory. */ int memory_pressure; bool active; - /* - * memcg field is used to find which memcg we belong directly - * Each memcg struct can hold more than one cg_proto, so container_of - * won't really cut. - * - * The elegant solution would be having an inverse function to - * proto_cgroup in struct proto, but that means polluting the structure - * for everybody, instead of just for memcg users. - */ - struct mem_cgroup *memcg; }; #ifdef CONFIG_MEMCG @@ -688,15 +678,15 @@ static inline void mem_cgroup_wb_stats(struct bdi_writeback *wb, struct sock; void sock_update_memcg(struct sock *sk); void sock_release_memcg(struct sock *sk); -bool mem_cgroup_charge_skmem(struct cg_proto *proto, unsigned int nr_pages); -void mem_cgroup_uncharge_skmem(struct cg_proto *proto, unsigned int nr_pages); +bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); +void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); #if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_INET) -static inline bool mem_cgroup_under_socket_pressure(struct cg_proto *proto) +static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) { - return proto->memory_pressure; + return memcg->tcp_mem.memory_pressure; } #else -static inline bool mem_cgroup_under_pressure(struct cg_proto *proto) +static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) { return false; } diff --git a/include/net/sock.h b/include/net/sock.h index 94a6c1a740b98..be96a8dcbc744 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -71,22 +71,6 @@ #include #include -struct cgroup; -struct cgroup_subsys; -#ifdef CONFIG_NET -int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss); -void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg); -#else -static inline -int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss) -{ - return 0; -} -static inline -void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg) -{ -} -#endif /* * This structure really needs to be cleaned up. * Most of it is for TCP, and not used by any of @@ -245,7 +229,6 @@ struct sock_common { /* public: */ }; -struct cg_proto; /** * struct sock - network layer representation of sockets * @__sk_common: shared layout with inet_timewait_sock @@ -310,7 +293,7 @@ struct cg_proto; * @sk_security: used by security modules * @sk_mark: generic packet mark * @sk_cgrp_data: cgroup data for this cgroup - * @sk_cgrp: this socket's cgroup-specific proto data + * @sk_memcg: this socket's memory cgroup association * @sk_write_pending: a write to stream socket waits to start * @sk_state_change: callback to indicate change in the state of the sock * @sk_data_ready: callback to indicate there is data to be processed @@ -446,7 +429,7 @@ struct sock { void *sk_security; #endif struct sock_cgroup_data sk_cgrp_data; - struct cg_proto *sk_cgrp; + struct mem_cgroup *sk_memcg; void (*sk_state_change)(struct sock *sk); void (*sk_data_ready)(struct sock *sk); void (*sk_write_space)(struct sock *sk); @@ -1129,8 +1112,8 @@ static inline bool sk_under_memory_pressure(const struct sock *sk) if (!sk->sk_prot->memory_pressure) return false; - if (mem_cgroup_sockets_enabled && sk->sk_cgrp && - mem_cgroup_under_socket_pressure(sk->sk_cgrp)) + if (mem_cgroup_sockets_enabled && sk->sk_memcg && + mem_cgroup_under_socket_pressure(sk->sk_memcg)) return true; return !!*sk->sk_prot->memory_pressure; diff --git a/include/net/tcp.h b/include/net/tcp.h index d9df80deba31a..8ea19977ea530 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -289,8 +289,8 @@ extern int tcp_memory_pressure; /* optimized version of sk_under_memory_pressure() for TCP sockets */ static inline bool tcp_under_memory_pressure(const struct sock *sk) { - if (mem_cgroup_sockets_enabled && sk->sk_cgrp && - mem_cgroup_under_socket_pressure(sk->sk_cgrp)) + if (mem_cgroup_sockets_enabled && sk->sk_memcg && + mem_cgroup_under_socket_pressure(sk->sk_memcg)) return true; return tcp_memory_pressure; diff --git a/include/net/tcp_memcontrol.h b/include/net/tcp_memcontrol.h index 05b94d9453de8..3a17b16ae8aa4 100644 --- a/include/net/tcp_memcontrol.h +++ b/include/net/tcp_memcontrol.h @@ -1,7 +1,6 @@ #ifndef _TCP_MEMCG_H #define _TCP_MEMCG_H -struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg); int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss); void tcp_destroy_cgroup(struct mem_cgroup *memcg); #endif /* _TCP_MEMCG_H */ diff --git a/mm/memcontrol.c b/mm/memcontrol.c index f5de783860b87..eaaa86126277b 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -294,9 +294,6 @@ static inline struct mem_cgroup *mem_cgroup_from_id(unsigned short id) void sock_update_memcg(struct sock *sk) { struct mem_cgroup *memcg; - struct cg_proto *cg_proto; - - BUG_ON(!sk->sk_prot->proto_cgroup); /* Socket cloning can throw us here with sk_cgrp already * filled. It won't however, necessarily happen from @@ -306,68 +303,58 @@ void sock_update_memcg(struct sock *sk) * Respecting the original socket's memcg is a better * decision in this case. */ - if (sk->sk_cgrp) { - BUG_ON(mem_cgroup_is_root(sk->sk_cgrp->memcg)); - css_get(&sk->sk_cgrp->memcg->css); + if (sk->sk_memcg) { + BUG_ON(mem_cgroup_is_root(sk->sk_memcg)); + css_get(&sk->sk_memcg->css); return; } rcu_read_lock(); memcg = mem_cgroup_from_task(current); - cg_proto = sk->sk_prot->proto_cgroup(memcg); - if (cg_proto && cg_proto->active && - css_tryget_online(&memcg->css)) { - sk->sk_cgrp = cg_proto; - } + if (memcg != root_mem_cgroup && + memcg->tcp_mem.active && + css_tryget_online(&memcg->css)) + sk->sk_memcg = memcg; rcu_read_unlock(); } EXPORT_SYMBOL(sock_update_memcg); void sock_release_memcg(struct sock *sk) { - WARN_ON(!sk->sk_cgrp->memcg); - css_put(&sk->sk_cgrp->memcg->css); -} - -struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg) -{ - if (!memcg || mem_cgroup_is_root(memcg)) - return NULL; - - return &memcg->tcp_mem; + WARN_ON(!sk->sk_memcg); + css_put(&sk->sk_memcg->css); } -EXPORT_SYMBOL(tcp_proto_cgroup); /** * mem_cgroup_charge_skmem - charge socket memory - * @proto: proto to charge + * @memcg: memcg to charge * @nr_pages: number of pages to charge * - * Charges @nr_pages to @proto. Returns %true if the charge fit within - * @proto's configured limit, %false if the charge had to be forced. + * Charges @nr_pages to @memcg. Returns %true if the charge fit within + * @memcg's configured limit, %false if the charge had to be forced. */ -bool mem_cgroup_charge_skmem(struct cg_proto *proto, unsigned int nr_pages) +bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages) { struct page_counter *counter; - if (page_counter_try_charge(&proto->memory_allocated, + if (page_counter_try_charge(&memcg->tcp_mem.memory_allocated, nr_pages, &counter)) { - proto->memory_pressure = 0; + memcg->tcp_mem.memory_pressure = 0; return true; } - page_counter_charge(&proto->memory_allocated, nr_pages); - proto->memory_pressure = 1; + page_counter_charge(&memcg->tcp_mem.memory_allocated, nr_pages); + memcg->tcp_mem.memory_pressure = 1; return false; } /** * mem_cgroup_uncharge_skmem - uncharge socket memory - * @proto - proto to uncharge + * @memcg - memcg to uncharge * @nr_pages - number of pages to uncharge */ -void mem_cgroup_uncharge_skmem(struct cg_proto *proto, unsigned int nr_pages) +void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages) { - page_counter_uncharge(&proto->memory_allocated, nr_pages); + page_counter_uncharge(&memcg->tcp_mem.memory_allocated, nr_pages); } #endif @@ -3653,7 +3640,7 @@ static int memcg_init_kmem(struct mem_cgroup *memcg, struct cgroup_subsys *ss) if (ret) return ret; - return mem_cgroup_sockets_init(memcg, ss); + return tcp_init_cgroup(memcg, ss); } static void memcg_deactivate_kmem(struct mem_cgroup *memcg) @@ -3709,7 +3696,7 @@ static void memcg_destroy_kmem(struct mem_cgroup *memcg) static_key_slow_dec(&memcg_kmem_enabled_key); WARN_ON(page_counter_read(&memcg->kmem)); } - mem_cgroup_sockets_destroy(memcg); + tcp_destroy_cgroup(memcg); } #else static int memcg_init_kmem(struct mem_cgroup *memcg, struct cgroup_subsys *ss) diff --git a/net/core/sock.c b/net/core/sock.c index 89ae859d2dc54..3535bffa45f3c 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -195,44 +195,6 @@ bool sk_net_capable(const struct sock *sk, int cap) } EXPORT_SYMBOL(sk_net_capable); - -#ifdef CONFIG_MEMCG_KMEM -int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss) -{ - struct proto *proto; - int ret = 0; - - mutex_lock(&proto_list_mutex); - list_for_each_entry(proto, &proto_list, node) { - if (proto->init_cgroup) { - ret = proto->init_cgroup(memcg, ss); - if (ret) - goto out; - } - } - - mutex_unlock(&proto_list_mutex); - return ret; -out: - list_for_each_entry_continue_reverse(proto, &proto_list, node) - if (proto->destroy_cgroup) - proto->destroy_cgroup(memcg); - mutex_unlock(&proto_list_mutex); - return ret; -} - -void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg) -{ - struct proto *proto; - - mutex_lock(&proto_list_mutex); - list_for_each_entry_reverse(proto, &proto_list, node) - if (proto->destroy_cgroup) - proto->destroy_cgroup(memcg); - mutex_unlock(&proto_list_mutex); -} -#endif - /* * Each address family might have different locking rules, so we have * one slock key per address family: @@ -1601,7 +1563,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) sk_set_socket(newsk, NULL); newsk->sk_wq = NULL; - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) + if (mem_cgroup_sockets_enabled && sk->sk_memcg) sock_update_memcg(newsk); if (newsk->sk_prot->sockets_allocated) @@ -2089,8 +2051,8 @@ int __sk_mem_schedule(struct sock *sk, int size, int kind) allocated = sk_memory_allocated_add(sk, amt); - if (mem_cgroup_sockets_enabled && sk->sk_cgrp && - !mem_cgroup_charge_skmem(sk->sk_cgrp, amt)) + if (mem_cgroup_sockets_enabled && sk->sk_memcg && + !mem_cgroup_charge_skmem(sk->sk_memcg, amt)) goto suppress_allocation; /* Under limit. */ @@ -2153,8 +2115,8 @@ suppress_allocation: sk_memory_allocated_sub(sk, amt); - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - mem_cgroup_uncharge_skmem(sk->sk_cgrp, amt); + if (mem_cgroup_sockets_enabled && sk->sk_memcg) + mem_cgroup_uncharge_skmem(sk->sk_memcg, amt); return 0; } @@ -2171,8 +2133,8 @@ void __sk_mem_reclaim(struct sock *sk, int amount) sk_memory_allocated_sub(sk, amount); sk->sk_forward_alloc -= amount << SK_MEM_QUANTUM_SHIFT; - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - mem_cgroup_uncharge_skmem(sk->sk_cgrp, amount); + if (mem_cgroup_sockets_enabled && sk->sk_memcg) + mem_cgroup_uncharge_skmem(sk->sk_memcg, amount); if (sk_under_memory_pressure(sk) && (sk_memory_allocated(sk) < sk_prot_mem_limits(sk, 0))) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index eb39e02899e58..c7d1fb50f3818 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1819,7 +1819,7 @@ void tcp_v4_destroy_sock(struct sock *sk) sk_sockets_allocated_dec(sk); - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) + if (mem_cgroup_sockets_enabled && sk->sk_memcg) sock_release_memcg(sk); } EXPORT_SYMBOL(tcp_v4_destroy_sock); @@ -2343,11 +2343,6 @@ struct proto tcp_prot = { #ifdef CONFIG_COMPAT .compat_setsockopt = compat_tcp_setsockopt, .compat_getsockopt = compat_tcp_getsockopt, -#endif -#ifdef CONFIG_MEMCG_KMEM - .init_cgroup = tcp_init_cgroup, - .destroy_cgroup = tcp_destroy_cgroup, - .proto_cgroup = tcp_proto_cgroup, #endif .diag_destroy = tcp_abort, }; diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c index ef4268d12e43d..e5078259cbe3b 100644 --- a/net/ipv4/tcp_memcontrol.c +++ b/net/ipv4/tcp_memcontrol.c @@ -8,60 +8,47 @@ int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss) { + struct mem_cgroup *parent = parent_mem_cgroup(memcg); + struct page_counter *counter_parent = NULL; /* * The root cgroup does not use page_counters, but rather, * rely on the data already collected by the network * subsystem */ - struct mem_cgroup *parent = parent_mem_cgroup(memcg); - struct page_counter *counter_parent = NULL; - struct cg_proto *cg_proto, *parent_cg; - - cg_proto = tcp_prot.proto_cgroup(memcg); - if (!cg_proto) + if (memcg == root_mem_cgroup) return 0; - cg_proto->memory_pressure = 0; - cg_proto->memcg = memcg; + memcg->tcp_mem.memory_pressure = 0; - parent_cg = tcp_prot.proto_cgroup(parent); - if (parent_cg) - counter_parent = &parent_cg->memory_allocated; + if (parent) + counter_parent = &parent->tcp_mem.memory_allocated; - page_counter_init(&cg_proto->memory_allocated, counter_parent); + page_counter_init(&memcg->tcp_mem.memory_allocated, counter_parent); return 0; } -EXPORT_SYMBOL(tcp_init_cgroup); void tcp_destroy_cgroup(struct mem_cgroup *memcg) { - struct cg_proto *cg_proto; - - cg_proto = tcp_prot.proto_cgroup(memcg); - if (!cg_proto) + if (memcg == root_mem_cgroup) return; - if (cg_proto->active) + if (memcg->tcp_mem.active) static_key_slow_dec(&memcg_socket_limit_enabled); - } -EXPORT_SYMBOL(tcp_destroy_cgroup); static int tcp_update_limit(struct mem_cgroup *memcg, unsigned long nr_pages) { - struct cg_proto *cg_proto; int ret; - cg_proto = tcp_prot.proto_cgroup(memcg); - if (!cg_proto) + if (memcg == root_mem_cgroup) return -EINVAL; - ret = page_counter_limit(&cg_proto->memory_allocated, nr_pages); + ret = page_counter_limit(&memcg->tcp_mem.memory_allocated, nr_pages); if (ret) return ret; - if (!cg_proto->active) { + if (!memcg->tcp_mem.active) { /* * The active flag needs to be written after the static_key * update. This is what guarantees that the socket activation @@ -79,7 +66,7 @@ static int tcp_update_limit(struct mem_cgroup *memcg, unsigned long nr_pages) * patched in yet. */ static_key_slow_inc(&memcg_socket_limit_enabled); - cg_proto->active = true; + memcg->tcp_mem.active = true; } return 0; @@ -123,32 +110,32 @@ static ssize_t tcp_cgroup_write(struct kernfs_open_file *of, static u64 tcp_cgroup_read(struct cgroup_subsys_state *css, struct cftype *cft) { struct mem_cgroup *memcg = mem_cgroup_from_css(css); - struct cg_proto *cg_proto = tcp_prot.proto_cgroup(memcg); u64 val; switch (cft->private) { case RES_LIMIT: - if (!cg_proto) - return PAGE_COUNTER_MAX; - val = cg_proto->memory_allocated.limit; + if (memcg == root_mem_cgroup) + val = PAGE_COUNTER_MAX; + else + val = memcg->tcp_mem.memory_allocated.limit; val *= PAGE_SIZE; break; case RES_USAGE: - if (!cg_proto) + if (memcg == root_mem_cgroup) val = atomic_long_read(&tcp_memory_allocated); else - val = page_counter_read(&cg_proto->memory_allocated); + val = page_counter_read(&memcg->tcp_mem.memory_allocated); val *= PAGE_SIZE; break; case RES_FAILCNT: - if (!cg_proto) + if (memcg == root_mem_cgroup) return 0; - val = cg_proto->memory_allocated.failcnt; + val = memcg->tcp_mem.memory_allocated.failcnt; break; case RES_MAX_USAGE: - if (!cg_proto) + if (memcg == root_mem_cgroup) return 0; - val = cg_proto->memory_allocated.watermark; + val = memcg->tcp_mem.memory_allocated.watermark; val *= PAGE_SIZE; break; default: @@ -161,19 +148,17 @@ static ssize_t tcp_cgroup_reset(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off) { struct mem_cgroup *memcg; - struct cg_proto *cg_proto; memcg = mem_cgroup_from_css(of_css(of)); - cg_proto = tcp_prot.proto_cgroup(memcg); - if (!cg_proto) + if (memcg == root_mem_cgroup) return nbytes; switch (of_cft(of)->private) { case RES_MAX_USAGE: - page_counter_reset_watermark(&cg_proto->memory_allocated); + page_counter_reset_watermark(&memcg->tcp_mem.memory_allocated); break; case RES_FAILCNT: - cg_proto->memory_allocated.failcnt = 0; + memcg->tcp_mem.memory_allocated.failcnt = 0; break; } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 493b48945f0c3..fda379cd600d4 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2821,8 +2821,8 @@ void sk_forced_mem_schedule(struct sock *sk, int size) sk->sk_forward_alloc += amt * SK_MEM_QUANTUM; sk_memory_allocated_add(sk, amt); - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - mem_cgroup_charge_skmem(sk->sk_cgrp, amt); + if (mem_cgroup_sockets_enabled && sk->sk_memcg) + mem_cgroup_charge_skmem(sk->sk_memcg, amt); } /* Send a FIN. The caller locks the socket for us. diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index db9f1c318afc3..4ad8edb46f7c5 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1888,9 +1888,6 @@ struct proto tcpv6_prot = { #ifdef CONFIG_COMPAT .compat_setsockopt = compat_tcp_setsockopt, .compat_getsockopt = compat_tcp_getsockopt, -#endif -#ifdef CONFIG_MEMCG_KMEM - .proto_cgroup = tcp_proto_cgroup, #endif .clear_sk = tcp_v6_clear_sk, .diag_destroy = tcp_abort, -- GitLab From 80e95fe0fdcde2812c341ad4209d62dc1a7af53b Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:20 -0800 Subject: [PATCH 2814/2855] mm: memcontrol: generalize the socket accounting jump label The unified hierarchy memory controller is going to use this jump label as well to control the networking callbacks. Move it to the memory controller code and give it a more generic name. Signed-off-by: Johannes Weiner Acked-by: Michal Hocko Reviewed-by: Vladimir Davydov Acked-by: David S. Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 3 +++ include/net/sock.h | 7 ------- mm/memcontrol.c | 3 +++ net/core/sock.c | 5 ----- net/ipv4/tcp_memcontrol.c | 4 ++-- 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 7c085e4636ba4..03090e8e7fffb 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -681,11 +681,14 @@ void sock_release_memcg(struct sock *sk); bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); #if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_INET) +extern struct static_key memcg_sockets_enabled_key; +#define mem_cgroup_sockets_enabled static_key_false(&memcg_sockets_enabled_key) static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) { return memcg->tcp_mem.memory_pressure; } #else +#define mem_cgroup_sockets_enabled 0 static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) { return false; diff --git a/include/net/sock.h b/include/net/sock.h index be96a8dcbc744..b9e7b3d863a09 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1079,13 +1079,6 @@ static inline void sk_refcnt_debug_release(const struct sock *sk) #define sk_refcnt_debug_release(sk) do { } while (0) #endif /* SOCK_REFCNT_DEBUG */ -#if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_NET) -extern struct static_key memcg_socket_limit_enabled; -#define mem_cgroup_sockets_enabled static_key_false(&memcg_socket_limit_enabled) -#else -#define mem_cgroup_sockets_enabled 0 -#endif - static inline bool sk_stream_memory_free(const struct sock *sk) { if (sk->sk_wmem_queued >= sk->sk_sndbuf) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index eaaa86126277b..08ef3d2ca6635 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -291,6 +291,9 @@ static inline struct mem_cgroup *mem_cgroup_from_id(unsigned short id) /* Writing them here to avoid exposing memcg's inner layout */ #if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM) +struct static_key memcg_sockets_enabled_key; +EXPORT_SYMBOL(memcg_sockets_enabled_key); + void sock_update_memcg(struct sock *sk) { struct mem_cgroup *memcg; diff --git a/net/core/sock.c b/net/core/sock.c index 3535bffa45f3c..6c1c8bc934127 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -202,11 +202,6 @@ EXPORT_SYMBOL(sk_net_capable); static struct lock_class_key af_family_keys[AF_MAX]; static struct lock_class_key af_family_slock_keys[AF_MAX]; -#if defined(CONFIG_MEMCG_KMEM) -struct static_key memcg_socket_limit_enabled; -EXPORT_SYMBOL(memcg_socket_limit_enabled); -#endif - /* * Make lock validator output more readable. (we pre-construct these * strings build-time, so that runtime initialization of socket diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c index e5078259cbe3b..9a22e2dfd64ad 100644 --- a/net/ipv4/tcp_memcontrol.c +++ b/net/ipv4/tcp_memcontrol.c @@ -34,7 +34,7 @@ void tcp_destroy_cgroup(struct mem_cgroup *memcg) return; if (memcg->tcp_mem.active) - static_key_slow_dec(&memcg_socket_limit_enabled); + static_key_slow_dec(&memcg_sockets_enabled_key); } static int tcp_update_limit(struct mem_cgroup *memcg, unsigned long nr_pages) @@ -65,7 +65,7 @@ static int tcp_update_limit(struct mem_cgroup *memcg, unsigned long nr_pages) * because when this value change, the code to process it is not * patched in yet. */ - static_key_slow_inc(&memcg_socket_limit_enabled); + static_key_slow_inc(&memcg_sockets_enabled_key); memcg->tcp_mem.active = true; } -- GitLab From 7941d2145abc4def5583f9d8d0b2e02647b6d1de Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:23 -0800 Subject: [PATCH 2815/2855] mm: memcontrol: do not account memory+swap on unified hierarchy The unified hierarchy memory controller doesn't expose the memory+swap counter to userspace, but its accounting is hardcoded in all charge paths right now, including the per-cpu charge cache ("the stock"). To avoid adding yet more pointless memory+swap accounting with the socket memory support in unified hierarchy, disable the counter altogether when in unified hierarchy mode. Signed-off-by: Johannes Weiner Acked-by: Michal Hocko Reviewed-by: Vladimir Davydov Acked-by: David S. Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memcontrol.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 08ef3d2ca6635..6903e7d8c7be5 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -87,6 +87,12 @@ int do_swap_account __read_mostly; #define do_swap_account 0 #endif +/* Whether legacy memory+swap accounting is active */ +static bool do_memsw_account(void) +{ + return !cgroup_subsys_on_dfl(memory_cgrp_subsys) && do_swap_account; +} + static const char * const mem_cgroup_stat_names[] = { "cache", "rss", @@ -1199,7 +1205,7 @@ static unsigned long mem_cgroup_margin(struct mem_cgroup *memcg) if (count < limit) margin = limit - count; - if (do_swap_account) { + if (do_memsw_account()) { count = page_counter_read(&memcg->memsw); limit = READ_ONCE(memcg->memsw.limit); if (count <= limit) @@ -1302,7 +1308,7 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p) pr_cont(":"); for (i = 0; i < MEM_CGROUP_STAT_NSTATS; i++) { - if (i == MEM_CGROUP_STAT_SWAP && !do_swap_account) + if (i == MEM_CGROUP_STAT_SWAP && !do_memsw_account()) continue; pr_cont(" %s:%luKB", mem_cgroup_stat_names[i], K(mem_cgroup_read_stat(iter, i))); @@ -1925,7 +1931,7 @@ static void drain_stock(struct memcg_stock_pcp *stock) if (stock->nr_pages) { page_counter_uncharge(&old->memory, stock->nr_pages); - if (do_swap_account) + if (do_memsw_account()) page_counter_uncharge(&old->memsw, stock->nr_pages); css_put_many(&old->css, stock->nr_pages); stock->nr_pages = 0; @@ -2055,11 +2061,11 @@ retry: if (consume_stock(memcg, nr_pages)) return 0; - if (!do_swap_account || + if (!do_memsw_account() || page_counter_try_charge(&memcg->memsw, batch, &counter)) { if (page_counter_try_charge(&memcg->memory, batch, &counter)) goto done_restock; - if (do_swap_account) + if (do_memsw_account()) page_counter_uncharge(&memcg->memsw, batch); mem_over_limit = mem_cgroup_from_counter(counter, memory); } else { @@ -2146,7 +2152,7 @@ force: * temporarily by force charging it. */ page_counter_charge(&memcg->memory, nr_pages); - if (do_swap_account) + if (do_memsw_account()) page_counter_charge(&memcg->memsw, nr_pages); css_get_many(&memcg->css, nr_pages); @@ -2183,7 +2189,7 @@ static void cancel_charge(struct mem_cgroup *memcg, unsigned int nr_pages) return; page_counter_uncharge(&memcg->memory, nr_pages); - if (do_swap_account) + if (do_memsw_account()) page_counter_uncharge(&memcg->memsw, nr_pages); css_put_many(&memcg->css, nr_pages); @@ -2469,7 +2475,7 @@ void __memcg_kmem_uncharge(struct page *page, int order) page_counter_uncharge(&memcg->kmem, nr_pages); page_counter_uncharge(&memcg->memory, nr_pages); - if (do_swap_account) + if (do_memsw_account()) page_counter_uncharge(&memcg->memsw, nr_pages); page->mem_cgroup = NULL; @@ -3184,7 +3190,7 @@ static int memcg_stat_show(struct seq_file *m, void *v) BUILD_BUG_ON(ARRAY_SIZE(mem_cgroup_lru_names) != NR_LRU_LISTS); for (i = 0; i < MEM_CGROUP_STAT_NSTATS; i++) { - if (i == MEM_CGROUP_STAT_SWAP && !do_swap_account) + if (i == MEM_CGROUP_STAT_SWAP && !do_memsw_account()) continue; seq_printf(m, "%s %lu\n", mem_cgroup_stat_names[i], mem_cgroup_read_stat(memcg, i) * PAGE_SIZE); @@ -3206,14 +3212,14 @@ static int memcg_stat_show(struct seq_file *m, void *v) } seq_printf(m, "hierarchical_memory_limit %llu\n", (u64)memory * PAGE_SIZE); - if (do_swap_account) + if (do_memsw_account()) seq_printf(m, "hierarchical_memsw_limit %llu\n", (u64)memsw * PAGE_SIZE); for (i = 0; i < MEM_CGROUP_STAT_NSTATS; i++) { unsigned long long val = 0; - if (i == MEM_CGROUP_STAT_SWAP && !do_swap_account) + if (i == MEM_CGROUP_STAT_SWAP && !do_memsw_account()) continue; for_each_mem_cgroup_tree(mi, memcg) val += mem_cgroup_read_stat(mi, i) * PAGE_SIZE; @@ -3344,7 +3350,7 @@ static void mem_cgroup_threshold(struct mem_cgroup *memcg) { while (memcg) { __mem_cgroup_threshold(memcg, false); - if (do_swap_account) + if (do_memsw_account()) __mem_cgroup_threshold(memcg, true); memcg = parent_mem_cgroup(memcg); @@ -4497,7 +4503,7 @@ static struct page *mc_handle_swap_pte(struct vm_area_struct *vma, * we call find_get_page() with swapper_space directly. */ page = find_get_page(swap_address_space(ent), ent.val); - if (do_swap_account) + if (do_memsw_account()) entry->val = ent.val; return page; @@ -4532,7 +4538,7 @@ static struct page *mc_handle_file_pte(struct vm_area_struct *vma, page = find_get_entry(mapping, pgoff); if (radix_tree_exceptional_entry(page)) { swp_entry_t swp = radix_to_swp_entry(page); - if (do_swap_account) + if (do_memsw_account()) *entry = swp; page = find_get_page(swap_address_space(swp), swp.val); } @@ -5325,7 +5331,7 @@ int mem_cgroup_try_charge(struct page *page, struct mm_struct *mm, if (page->mem_cgroup) goto out; - if (do_swap_account) { + if (do_memsw_account()) { swp_entry_t ent = { .val = page_private(page), }; unsigned short id = lookup_swap_cgroup_id(ent); @@ -5399,7 +5405,7 @@ void mem_cgroup_commit_charge(struct page *page, struct mem_cgroup *memcg, memcg_check_events(memcg, page); local_irq_enable(); - if (do_swap_account && PageSwapCache(page)) { + if (do_memsw_account() && PageSwapCache(page)) { swp_entry_t entry = { .val = page_private(page) }; /* * The swap entry might not get freed for a long time, @@ -5448,7 +5454,7 @@ static void uncharge_batch(struct mem_cgroup *memcg, unsigned long pgpgout, if (!mem_cgroup_is_root(memcg)) { page_counter_uncharge(&memcg->memory, nr_pages); - if (do_swap_account) + if (do_memsw_account()) page_counter_uncharge(&memcg->memsw, nr_pages); memcg_oom_recover(memcg); } @@ -5656,7 +5662,7 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry) VM_BUG_ON_PAGE(PageLRU(page), page); VM_BUG_ON_PAGE(page_count(page), page); - if (!do_swap_account) + if (!do_memsw_account()) return; memcg = page->mem_cgroup; @@ -5696,7 +5702,7 @@ void mem_cgroup_uncharge_swap(swp_entry_t entry) struct mem_cgroup *memcg; unsigned short id; - if (!do_swap_account) + if (!do_memsw_account()) return; id = swap_cgroup_record(entry, 0); -- GitLab From 1109208766d9fa7059a9b66ad488e66d99ce49af Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:26 -0800 Subject: [PATCH 2816/2855] mm: memcontrol: move socket code for unified hierarchy accounting The unified hierarchy memory controller will account socket memory. Move the infrastructure functions accordingly. Signed-off-by: Johannes Weiner Acked-by: Michal Hocko Reviewed-by: Vladimir Davydov Acked-by: David S. Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memcontrol.c | 148 ++++++++++++++++++++++++------------------------ 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 6903e7d8c7be5..6aac8d2e31d75 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -294,80 +294,6 @@ static inline struct mem_cgroup *mem_cgroup_from_id(unsigned short id) return mem_cgroup_from_css(css); } -/* Writing them here to avoid exposing memcg's inner layout */ -#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM) - -struct static_key memcg_sockets_enabled_key; -EXPORT_SYMBOL(memcg_sockets_enabled_key); - -void sock_update_memcg(struct sock *sk) -{ - struct mem_cgroup *memcg; - - /* Socket cloning can throw us here with sk_cgrp already - * filled. It won't however, necessarily happen from - * process context. So the test for root memcg given - * the current task's memcg won't help us in this case. - * - * Respecting the original socket's memcg is a better - * decision in this case. - */ - if (sk->sk_memcg) { - BUG_ON(mem_cgroup_is_root(sk->sk_memcg)); - css_get(&sk->sk_memcg->css); - return; - } - - rcu_read_lock(); - memcg = mem_cgroup_from_task(current); - if (memcg != root_mem_cgroup && - memcg->tcp_mem.active && - css_tryget_online(&memcg->css)) - sk->sk_memcg = memcg; - rcu_read_unlock(); -} -EXPORT_SYMBOL(sock_update_memcg); - -void sock_release_memcg(struct sock *sk) -{ - WARN_ON(!sk->sk_memcg); - css_put(&sk->sk_memcg->css); -} - -/** - * mem_cgroup_charge_skmem - charge socket memory - * @memcg: memcg to charge - * @nr_pages: number of pages to charge - * - * Charges @nr_pages to @memcg. Returns %true if the charge fit within - * @memcg's configured limit, %false if the charge had to be forced. - */ -bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages) -{ - struct page_counter *counter; - - if (page_counter_try_charge(&memcg->tcp_mem.memory_allocated, - nr_pages, &counter)) { - memcg->tcp_mem.memory_pressure = 0; - return true; - } - page_counter_charge(&memcg->tcp_mem.memory_allocated, nr_pages); - memcg->tcp_mem.memory_pressure = 1; - return false; -} - -/** - * mem_cgroup_uncharge_skmem - uncharge socket memory - * @memcg - memcg to uncharge - * @nr_pages - number of pages to uncharge - */ -void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages) -{ - page_counter_uncharge(&memcg->tcp_mem.memory_allocated, nr_pages); -} - -#endif - #ifdef CONFIG_MEMCG_KMEM /* * This will be the memcg's index in each cache's ->memcg_params.memcg_caches. @@ -5607,6 +5533,80 @@ void mem_cgroup_replace_page(struct page *oldpage, struct page *newpage) commit_charge(newpage, memcg, true); } +/* Writing them here to avoid exposing memcg's inner layout */ +#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM) + +struct static_key memcg_sockets_enabled_key; +EXPORT_SYMBOL(memcg_sockets_enabled_key); + +void sock_update_memcg(struct sock *sk) +{ + struct mem_cgroup *memcg; + + /* Socket cloning can throw us here with sk_cgrp already + * filled. It won't however, necessarily happen from + * process context. So the test for root memcg given + * the current task's memcg won't help us in this case. + * + * Respecting the original socket's memcg is a better + * decision in this case. + */ + if (sk->sk_memcg) { + BUG_ON(mem_cgroup_is_root(sk->sk_memcg)); + css_get(&sk->sk_memcg->css); + return; + } + + rcu_read_lock(); + memcg = mem_cgroup_from_task(current); + if (memcg != root_mem_cgroup && + memcg->tcp_mem.active && + css_tryget_online(&memcg->css)) + sk->sk_memcg = memcg; + rcu_read_unlock(); +} +EXPORT_SYMBOL(sock_update_memcg); + +void sock_release_memcg(struct sock *sk) +{ + WARN_ON(!sk->sk_memcg); + css_put(&sk->sk_memcg->css); +} + +/** + * mem_cgroup_charge_skmem - charge socket memory + * @memcg: memcg to charge + * @nr_pages: number of pages to charge + * + * Charges @nr_pages to @memcg. Returns %true if the charge fit within + * @memcg's configured limit, %false if the charge had to be forced. + */ +bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages) +{ + struct page_counter *counter; + + if (page_counter_try_charge(&memcg->tcp_mem.memory_allocated, + nr_pages, &counter)) { + memcg->tcp_mem.memory_pressure = 0; + return true; + } + page_counter_charge(&memcg->tcp_mem.memory_allocated, nr_pages); + memcg->tcp_mem.memory_pressure = 1; + return false; +} + +/** + * mem_cgroup_uncharge_skmem - uncharge socket memory + * @memcg - memcg to uncharge + * @nr_pages - number of pages to uncharge + */ +void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages) +{ + page_counter_uncharge(&memcg->tcp_mem.memory_allocated, nr_pages); +} + +#endif + /* * subsys_initcall() for memory controller. * -- GitLab From f7e1cb6ec51b041335b5ad4dd7aefb37a56d79a6 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:29 -0800 Subject: [PATCH 2817/2855] mm: memcontrol: account socket memory in unified hierarchy memory controller Socket memory can be a significant share of overall memory consumed by common workloads. In order to provide reasonable resource isolation in the unified hierarchy, this type of memory needs to be included in the tracking/accounting of a cgroup under active memory resource control. Overhead is only incurred when a non-root control group is created AND the memory controller is instructed to track and account the memory footprint of that group. cgroup.memory=nosocket can be specified on the boot commandline to override any runtime configuration and forcibly exclude socket memory from active memory resource control. Signed-off-by: Johannes Weiner Acked-by: David S. Miller Reviewed-by: Vladimir Davydov Acked-by: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/kernel-parameters.txt | 4 + include/linux/memcontrol.h | 9 +- mm/memcontrol.c | 122 ++++++++++++++++++++++------ 3 files changed, 110 insertions(+), 25 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index b7d44871effc2..168fd79dc697a 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -608,6 +608,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. cut the overhead, others just disable the usage. So only cgroup_disable=memory is actually worthy} + cgroup.memory= [KNL] Pass options to the cgroup memory controller. + Format: + nosocket -- Disable socket memory accounting. + checkreqprot [SELINUX] Set initial checkreqprot flag value. Format: { "0" | "1" } See security/selinux/Kconfig help text. diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 03090e8e7fffb..a355f61a2ed39 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -170,6 +170,9 @@ struct mem_cgroup { unsigned long low; unsigned long high; + /* Range enforcement for interrupt charges */ + struct work_struct high_work; + unsigned long soft_limit; /* vmpressure notifications */ @@ -680,12 +683,16 @@ void sock_update_memcg(struct sock *sk); void sock_release_memcg(struct sock *sk); bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); -#if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_INET) +#if defined(CONFIG_MEMCG) && defined(CONFIG_INET) extern struct static_key memcg_sockets_enabled_key; #define mem_cgroup_sockets_enabled static_key_false(&memcg_sockets_enabled_key) static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) { +#ifdef CONFIG_MEMCG_KMEM return memcg->tcp_mem.memory_pressure; +#else + return false; +#endif } #else #define mem_cgroup_sockets_enabled 0 diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 6aac8d2e31d75..60ebc486c2aa6 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -80,6 +80,9 @@ struct mem_cgroup *root_mem_cgroup __read_mostly; #define MEM_CGROUP_RECLAIM_RETRIES 5 +/* Socket memory accounting disabled? */ +static bool cgroup_memory_nosocket; + /* Whether the swap controller is active */ #ifdef CONFIG_MEMCG_SWAP int do_swap_account __read_mostly; @@ -1945,6 +1948,26 @@ static int memcg_cpu_hotplug_callback(struct notifier_block *nb, return NOTIFY_OK; } +static void reclaim_high(struct mem_cgroup *memcg, + unsigned int nr_pages, + gfp_t gfp_mask) +{ + do { + if (page_counter_read(&memcg->memory) <= memcg->high) + continue; + mem_cgroup_events(memcg, MEMCG_HIGH, 1); + try_to_free_mem_cgroup_pages(memcg, nr_pages, gfp_mask, true); + } while ((memcg = parent_mem_cgroup(memcg))); +} + +static void high_work_func(struct work_struct *work) +{ + struct mem_cgroup *memcg; + + memcg = container_of(work, struct mem_cgroup, high_work); + reclaim_high(memcg, CHARGE_BATCH, GFP_KERNEL); +} + /* * Scheduled by try_charge() to be executed from the userland return path * and reclaims memory over the high limit. @@ -1952,20 +1975,13 @@ static int memcg_cpu_hotplug_callback(struct notifier_block *nb, void mem_cgroup_handle_over_high(void) { unsigned int nr_pages = current->memcg_nr_pages_over_high; - struct mem_cgroup *memcg, *pos; + struct mem_cgroup *memcg; if (likely(!nr_pages)) return; - pos = memcg = get_mem_cgroup_from_mm(current->mm); - - do { - if (page_counter_read(&pos->memory) <= pos->high) - continue; - mem_cgroup_events(pos, MEMCG_HIGH, 1); - try_to_free_mem_cgroup_pages(pos, nr_pages, GFP_KERNEL, true); - } while ((pos = parent_mem_cgroup(pos))); - + memcg = get_mem_cgroup_from_mm(current->mm); + reclaim_high(memcg, nr_pages, GFP_KERNEL); css_put(&memcg->css); current->memcg_nr_pages_over_high = 0; } @@ -2100,6 +2116,11 @@ done_restock: */ do { if (page_counter_read(&memcg->memory) > memcg->high) { + /* Don't bother a random interrupted task */ + if (in_interrupt()) { + schedule_work(&memcg->high_work); + break; + } current->memcg_nr_pages_over_high += batch; set_notify_resume(current); break; @@ -4150,6 +4171,8 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg) { int node; + cancel_work_sync(&memcg->high_work); + mem_cgroup_remove_from_trees(memcg); for_each_node(node) @@ -4196,6 +4219,7 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) page_counter_init(&memcg->kmem, NULL); } + INIT_WORK(&memcg->high_work, high_work_func); memcg->last_scanned_node = MAX_NUMNODES; INIT_LIST_HEAD(&memcg->oom_notify); memcg->move_charge_at_immigrate = 0; @@ -4267,6 +4291,11 @@ mem_cgroup_css_online(struct cgroup_subsys_state *css) if (ret) return ret; +#ifdef CONFIG_INET + if (cgroup_subsys_on_dfl(memory_cgrp_subsys) && !cgroup_memory_nosocket) + static_key_slow_inc(&memcg_sockets_enabled_key); +#endif + /* * Make sure the memcg is initialized: mem_cgroup_iter() * orders reading memcg->initialized against its callers @@ -4313,6 +4342,10 @@ static void mem_cgroup_css_free(struct cgroup_subsys_state *css) struct mem_cgroup *memcg = mem_cgroup_from_css(css); memcg_destroy_kmem(memcg); +#ifdef CONFIG_INET + if (cgroup_subsys_on_dfl(memory_cgrp_subsys) && !cgroup_memory_nosocket) + static_key_slow_dec(&memcg_sockets_enabled_key); +#endif __mem_cgroup_free(memcg); } @@ -5533,8 +5566,7 @@ void mem_cgroup_replace_page(struct page *oldpage, struct page *newpage) commit_charge(newpage, memcg, true); } -/* Writing them here to avoid exposing memcg's inner layout */ -#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM) +#ifdef CONFIG_INET struct static_key memcg_sockets_enabled_key; EXPORT_SYMBOL(memcg_sockets_enabled_key); @@ -5559,10 +5591,15 @@ void sock_update_memcg(struct sock *sk) rcu_read_lock(); memcg = mem_cgroup_from_task(current); - if (memcg != root_mem_cgroup && - memcg->tcp_mem.active && - css_tryget_online(&memcg->css)) + if (memcg == root_mem_cgroup) + goto out; +#ifdef CONFIG_MEMCG_KMEM + if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) && !memcg->tcp_mem.active) + goto out; +#endif + if (css_tryget_online(&memcg->css)) sk->sk_memcg = memcg; +out: rcu_read_unlock(); } EXPORT_SYMBOL(sock_update_memcg); @@ -5583,15 +5620,30 @@ void sock_release_memcg(struct sock *sk) */ bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages) { - struct page_counter *counter; + gfp_t gfp_mask = GFP_KERNEL; - if (page_counter_try_charge(&memcg->tcp_mem.memory_allocated, - nr_pages, &counter)) { - memcg->tcp_mem.memory_pressure = 0; - return true; +#ifdef CONFIG_MEMCG_KMEM + if (!cgroup_subsys_on_dfl(memory_cgrp_subsys)) { + struct page_counter *counter; + + if (page_counter_try_charge(&memcg->tcp_mem.memory_allocated, + nr_pages, &counter)) { + memcg->tcp_mem.memory_pressure = 0; + return true; + } + page_counter_charge(&memcg->tcp_mem.memory_allocated, nr_pages); + memcg->tcp_mem.memory_pressure = 1; + return false; } - page_counter_charge(&memcg->tcp_mem.memory_allocated, nr_pages); - memcg->tcp_mem.memory_pressure = 1; +#endif + /* Don't block in the packet receive path */ + if (in_softirq()) + gfp_mask = GFP_NOWAIT; + + if (try_charge(memcg, gfp_mask, nr_pages) == 0) + return true; + + try_charge(memcg, gfp_mask|__GFP_NOFAIL, nr_pages); return false; } @@ -5602,10 +5654,32 @@ bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages) */ void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages) { - page_counter_uncharge(&memcg->tcp_mem.memory_allocated, nr_pages); +#ifdef CONFIG_MEMCG_KMEM + if (!cgroup_subsys_on_dfl(memory_cgrp_subsys)) { + page_counter_uncharge(&memcg->tcp_mem.memory_allocated, + nr_pages); + return; + } +#endif + page_counter_uncharge(&memcg->memory, nr_pages); + css_put_many(&memcg->css, nr_pages); } -#endif +#endif /* CONFIG_INET */ + +static int __init cgroup_memory(char *s) +{ + char *token; + + while ((token = strsep(&s, ",")) != NULL) { + if (!*token) + continue; + if (!strcmp(token, "nosocket")) + cgroup_memory_nosocket = true; + } + return 0; +} +__setup("cgroup.memory=", cgroup_memory); /* * subsys_initcall() for memory controller. -- GitLab From 8e8ae645249b85c8ed6c178557f8db8613a6bcc7 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:32 -0800 Subject: [PATCH 2818/2855] mm: memcontrol: hook up vmpressure to socket pressure Let the networking stack know when a memcg is under reclaim pressure so that it can clamp its transmit windows accordingly. Whenever the reclaim efficiency of a cgroup's LRU lists drops low enough for a MEDIUM or HIGH vmpressure event to occur, assert a pressure state in the socket and tcp memory code that tells it to curb consumption growth from sockets associated with said control group. Traditionally, vmpressure reports for the entire subtree of a memcg under pressure, which drops useful information on the individual groups reclaimed. However, it's too late to change the userinterface, so add a second reporting mode that reports on the level of reclaim instead of at the level of pressure, and use that report for sockets. vmpressure events are naturally edge triggered, so for hysteresis assert socket pressure for a second to allow for subsequent vmpressure events to occur before letting the socket code return to normal. This will likely need finetuning for a wider variety of workloads, but for now stick to the vmpressure presets and keep hysteresis simple. Signed-off-by: Johannes Weiner Acked-by: David S. Miller Reviewed-by: Vladimir Davydov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 32 ++++++++++++++-- include/linux/vmpressure.h | 7 +++- mm/memcontrol.c | 17 ++------- mm/vmpressure.c | 78 ++++++++++++++++++++++++++++---------- mm/vmscan.c | 10 ++++- 5 files changed, 104 insertions(+), 40 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index a355f61a2ed39..c5a51039df57f 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -249,6 +249,10 @@ struct mem_cgroup { struct wb_domain cgwb_domain; #endif +#ifdef CONFIG_INET + unsigned long socket_pressure; +#endif + /* List of events which userspace want to receive */ struct list_head event_list; spinlock_t event_list_lock; @@ -290,18 +294,34 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *, struct zone *); bool task_in_mem_cgroup(struct task_struct *task, struct mem_cgroup *memcg); struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p); -struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg); static inline struct mem_cgroup *mem_cgroup_from_css(struct cgroup_subsys_state *css){ return css ? container_of(css, struct mem_cgroup, css) : NULL; } +#define mem_cgroup_from_counter(counter, member) \ + container_of(counter, struct mem_cgroup, member) + struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *, struct mem_cgroup *, struct mem_cgroup_reclaim_cookie *); void mem_cgroup_iter_break(struct mem_cgroup *, struct mem_cgroup *); +/** + * parent_mem_cgroup - find the accounting parent of a memcg + * @memcg: memcg whose parent to find + * + * Returns the parent memcg, or NULL if this is the root or the memory + * controller is in legacy no-hierarchy mode. + */ +static inline struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg) +{ + if (!memcg->memory.parent) + return NULL; + return mem_cgroup_from_counter(memcg->memory.parent, memory); +} + static inline bool mem_cgroup_is_descendant(struct mem_cgroup *memcg, struct mem_cgroup *root) { @@ -689,10 +709,14 @@ extern struct static_key memcg_sockets_enabled_key; static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) { #ifdef CONFIG_MEMCG_KMEM - return memcg->tcp_mem.memory_pressure; -#else - return false; + if (memcg->tcp_mem.memory_pressure) + return true; #endif + do { + if (time_before(jiffies, memcg->socket_pressure)) + return true; + } while ((memcg = parent_mem_cgroup(memcg))); + return false; } #else #define mem_cgroup_sockets_enabled 0 diff --git a/include/linux/vmpressure.h b/include/linux/vmpressure.h index 3e4535876d374..3347cc3ec0ab6 100644 --- a/include/linux/vmpressure.h +++ b/include/linux/vmpressure.h @@ -12,6 +12,9 @@ struct vmpressure { unsigned long scanned; unsigned long reclaimed; + + unsigned long tree_scanned; + unsigned long tree_reclaimed; /* The lock is used to keep the scanned/reclaimed above in sync. */ struct spinlock sr_lock; @@ -26,7 +29,7 @@ struct vmpressure { struct mem_cgroup; #ifdef CONFIG_MEMCG -extern void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, +extern void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, bool tree, unsigned long scanned, unsigned long reclaimed); extern void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio); @@ -40,7 +43,7 @@ extern int vmpressure_register_event(struct mem_cgroup *memcg, extern void vmpressure_unregister_event(struct mem_cgroup *memcg, struct eventfd_ctx *eventfd); #else -static inline void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, +static inline void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, bool tree, unsigned long scanned, unsigned long reclaimed) {} static inline void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio) {} diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 60ebc486c2aa6..df7f144a5a4b7 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1113,9 +1113,6 @@ bool task_in_mem_cgroup(struct task_struct *task, struct mem_cgroup *memcg) return ret; } -#define mem_cgroup_from_counter(counter, member) \ - container_of(counter, struct mem_cgroup, member) - /** * mem_cgroup_margin - calculate chargeable space of a memory cgroup * @memcg: the memory cgroup @@ -4183,17 +4180,6 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg) kfree(memcg); } -/* - * Returns the parent mem_cgroup in memcgroup hierarchy with hierarchy enabled. - */ -struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg) -{ - if (!memcg->memory.parent) - return NULL; - return mem_cgroup_from_counter(memcg->memory.parent, memory); -} -EXPORT_SYMBOL(parent_mem_cgroup); - static struct cgroup_subsys_state * __ref mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) { @@ -4233,6 +4219,9 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) #endif #ifdef CONFIG_CGROUP_WRITEBACK INIT_LIST_HEAD(&memcg->cgwb_list); +#endif +#ifdef CONFIG_INET + memcg->socket_pressure = jiffies; #endif return &memcg->css; diff --git a/mm/vmpressure.c b/mm/vmpressure.c index c5afd573d7da7..506f03e4be47a 100644 --- a/mm/vmpressure.c +++ b/mm/vmpressure.c @@ -137,14 +137,11 @@ struct vmpressure_event { }; static bool vmpressure_event(struct vmpressure *vmpr, - unsigned long scanned, unsigned long reclaimed) + enum vmpressure_levels level) { struct vmpressure_event *ev; - enum vmpressure_levels level; bool signalled = false; - level = vmpressure_calc_level(scanned, reclaimed); - mutex_lock(&vmpr->events_lock); list_for_each_entry(ev, &vmpr->events, node) { @@ -164,6 +161,7 @@ static void vmpressure_work_fn(struct work_struct *work) struct vmpressure *vmpr = work_to_vmpressure(work); unsigned long scanned; unsigned long reclaimed; + enum vmpressure_levels level; spin_lock(&vmpr->sr_lock); /* @@ -174,19 +172,21 @@ static void vmpressure_work_fn(struct work_struct *work) * here. No need for any locks here since we don't care if * vmpr->reclaimed is in sync. */ - scanned = vmpr->scanned; + scanned = vmpr->tree_scanned; if (!scanned) { spin_unlock(&vmpr->sr_lock); return; } - reclaimed = vmpr->reclaimed; - vmpr->scanned = 0; - vmpr->reclaimed = 0; + reclaimed = vmpr->tree_reclaimed; + vmpr->tree_scanned = 0; + vmpr->tree_reclaimed = 0; spin_unlock(&vmpr->sr_lock); + level = vmpressure_calc_level(scanned, reclaimed); + do { - if (vmpressure_event(vmpr, scanned, reclaimed)) + if (vmpressure_event(vmpr, level)) break; /* * If not handled, propagate the event upward into the @@ -199,6 +199,7 @@ static void vmpressure_work_fn(struct work_struct *work) * vmpressure() - Account memory pressure through scanned/reclaimed ratio * @gfp: reclaimer's gfp mask * @memcg: cgroup memory controller handle + * @tree: legacy subtree mode * @scanned: number of pages scanned * @reclaimed: number of pages reclaimed * @@ -206,9 +207,16 @@ static void vmpressure_work_fn(struct work_struct *work) * "instantaneous" memory pressure (scanned/reclaimed ratio). The raw * pressure index is then further refined and averaged over time. * + * If @tree is set, vmpressure is in traditional userspace reporting + * mode: @memcg is considered the pressure root and userspace is + * notified of the entire subtree's reclaim efficiency. + * + * If @tree is not set, reclaim efficiency is recorded for @memcg, and + * only in-kernel users are notified. + * * This function does not return any value. */ -void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, +void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, bool tree, unsigned long scanned, unsigned long reclaimed) { struct vmpressure *vmpr = memcg_to_vmpressure(memcg); @@ -238,15 +246,47 @@ void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, if (!scanned) return; - spin_lock(&vmpr->sr_lock); - vmpr->scanned += scanned; - vmpr->reclaimed += reclaimed; - scanned = vmpr->scanned; - spin_unlock(&vmpr->sr_lock); + if (tree) { + spin_lock(&vmpr->sr_lock); + vmpr->tree_scanned += scanned; + vmpr->tree_reclaimed += reclaimed; + scanned = vmpr->scanned; + spin_unlock(&vmpr->sr_lock); - if (scanned < vmpressure_win) - return; - schedule_work(&vmpr->work); + if (scanned < vmpressure_win) + return; + schedule_work(&vmpr->work); + } else { + enum vmpressure_levels level; + + /* For now, no users for root-level efficiency */ + if (memcg == root_mem_cgroup) + return; + + spin_lock(&vmpr->sr_lock); + scanned = vmpr->scanned += scanned; + reclaimed = vmpr->reclaimed += reclaimed; + if (scanned < vmpressure_win) { + spin_unlock(&vmpr->sr_lock); + return; + } + vmpr->scanned = vmpr->reclaimed = 0; + spin_unlock(&vmpr->sr_lock); + + level = vmpressure_calc_level(scanned, reclaimed); + + if (level > VMPRESSURE_LOW) { + /* + * Let the socket buffer allocator know that + * we are having trouble reclaiming LRU pages. + * + * For hysteresis keep the pressure state + * asserted for a second in which subsequent + * pressure events can occur. + */ + memcg->socket_pressure = jiffies + HZ; + } + } } /** @@ -276,7 +316,7 @@ void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio) * to the vmpressure() basically means that we signal 'critical' * level. */ - vmpressure(gfp, memcg, vmpressure_win, 0); + vmpressure(gfp, memcg, true, vmpressure_win, 0); } /** diff --git a/mm/vmscan.c b/mm/vmscan.c index e36d766dade97..bb0cbd4c9f01f 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2396,6 +2396,7 @@ static bool shrink_zone(struct zone *zone, struct scan_control *sc, memcg = mem_cgroup_iter(root, NULL, &reclaim); do { unsigned long lru_pages; + unsigned long reclaimed; unsigned long scanned; struct lruvec *lruvec; int swappiness; @@ -2408,6 +2409,7 @@ static bool shrink_zone(struct zone *zone, struct scan_control *sc, lruvec = mem_cgroup_zone_lruvec(zone, memcg); swappiness = mem_cgroup_swappiness(memcg); + reclaimed = sc->nr_reclaimed; scanned = sc->nr_scanned; shrink_lruvec(lruvec, swappiness, sc, &lru_pages); @@ -2418,6 +2420,11 @@ static bool shrink_zone(struct zone *zone, struct scan_control *sc, memcg, sc->nr_scanned - scanned, lru_pages); + /* Record the group's reclaim efficiency */ + vmpressure(sc->gfp_mask, memcg, false, + sc->nr_scanned - scanned, + sc->nr_reclaimed - reclaimed); + /* * Direct reclaim and kswapd have to scan all memory * cgroups to fulfill the overall scan target for the @@ -2449,7 +2456,8 @@ static bool shrink_zone(struct zone *zone, struct scan_control *sc, reclaim_state->reclaimed_slab = 0; } - vmpressure(sc->gfp_mask, sc->target_mem_cgroup, + /* Record the subtree's reclaim efficiency */ + vmpressure(sc->gfp_mask, sc->target_mem_cgroup, true, sc->nr_scanned - nr_scanned, sc->nr_reclaimed - nr_reclaimed); -- GitLab From ef12947c9c5a96af549c49f10e5503f0612a397c Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:34 -0800 Subject: [PATCH 2819/2855] mm: memcontrol: switch to the updated jump-label API According to the direct use of struct static_key is deprecated. Update the socket and slab accounting code accordingly. Signed-off-by: Johannes Weiner Acked-by: David S. Miller Reported-by: Jason Baron Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 8 ++++---- mm/memcontrol.c | 12 ++++++------ net/ipv4/tcp_memcontrol.c | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index c5a51039df57f..2292468f2a305 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -704,8 +704,8 @@ void sock_release_memcg(struct sock *sk); bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); #if defined(CONFIG_MEMCG) && defined(CONFIG_INET) -extern struct static_key memcg_sockets_enabled_key; -#define mem_cgroup_sockets_enabled static_key_false(&memcg_sockets_enabled_key) +extern struct static_key_false memcg_sockets_enabled_key; +#define mem_cgroup_sockets_enabled static_branch_unlikely(&memcg_sockets_enabled_key) static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) { #ifdef CONFIG_MEMCG_KMEM @@ -727,7 +727,7 @@ static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) #endif #ifdef CONFIG_MEMCG_KMEM -extern struct static_key memcg_kmem_enabled_key; +extern struct static_key_false memcg_kmem_enabled_key; extern int memcg_nr_cache_ids; void memcg_get_cache_ids(void); @@ -743,7 +743,7 @@ void memcg_put_cache_ids(void); static inline bool memcg_kmem_enabled(void) { - return static_key_false(&memcg_kmem_enabled_key); + return static_branch_unlikely(&memcg_kmem_enabled_key); } static inline bool memcg_kmem_is_active(struct mem_cgroup *memcg) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index df7f144a5a4b7..54eae4f19d803 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -346,7 +346,7 @@ void memcg_put_cache_ids(void) * conditional to this static branch, we'll have to allow modules that does * kmem_cache_alloc and the such to see this symbol as well */ -struct static_key memcg_kmem_enabled_key; +DEFINE_STATIC_KEY_FALSE(memcg_kmem_enabled_key); EXPORT_SYMBOL(memcg_kmem_enabled_key); #endif /* CONFIG_MEMCG_KMEM */ @@ -2907,7 +2907,7 @@ static int memcg_activate_kmem(struct mem_cgroup *memcg, err = page_counter_limit(&memcg->kmem, nr_pages); VM_BUG_ON(err); - static_key_slow_inc(&memcg_kmem_enabled_key); + static_branch_inc(&memcg_kmem_enabled_key); /* * A memory cgroup is considered kmem-active as soon as it gets * kmemcg_id. Setting the id after enabling static branching will @@ -3646,7 +3646,7 @@ static void memcg_destroy_kmem(struct mem_cgroup *memcg) { if (memcg->kmem_acct_activated) { memcg_destroy_kmem_caches(memcg); - static_key_slow_dec(&memcg_kmem_enabled_key); + static_branch_dec(&memcg_kmem_enabled_key); WARN_ON(page_counter_read(&memcg->kmem)); } tcp_destroy_cgroup(memcg); @@ -4282,7 +4282,7 @@ mem_cgroup_css_online(struct cgroup_subsys_state *css) #ifdef CONFIG_INET if (cgroup_subsys_on_dfl(memory_cgrp_subsys) && !cgroup_memory_nosocket) - static_key_slow_inc(&memcg_sockets_enabled_key); + static_branch_inc(&memcg_sockets_enabled_key); #endif /* @@ -4333,7 +4333,7 @@ static void mem_cgroup_css_free(struct cgroup_subsys_state *css) memcg_destroy_kmem(memcg); #ifdef CONFIG_INET if (cgroup_subsys_on_dfl(memory_cgrp_subsys) && !cgroup_memory_nosocket) - static_key_slow_dec(&memcg_sockets_enabled_key); + static_branch_dec(&memcg_sockets_enabled_key); #endif __mem_cgroup_free(memcg); } @@ -5557,7 +5557,7 @@ void mem_cgroup_replace_page(struct page *oldpage, struct page *newpage) #ifdef CONFIG_INET -struct static_key memcg_sockets_enabled_key; +DEFINE_STATIC_KEY_FALSE(memcg_sockets_enabled_key); EXPORT_SYMBOL(memcg_sockets_enabled_key); void sock_update_memcg(struct sock *sk) diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c index 9a22e2dfd64ad..18bc7f745e9ca 100644 --- a/net/ipv4/tcp_memcontrol.c +++ b/net/ipv4/tcp_memcontrol.c @@ -34,7 +34,7 @@ void tcp_destroy_cgroup(struct mem_cgroup *memcg) return; if (memcg->tcp_mem.active) - static_key_slow_dec(&memcg_sockets_enabled_key); + static_branch_dec(&memcg_sockets_enabled_key); } static int tcp_update_limit(struct mem_cgroup *memcg, unsigned long nr_pages) @@ -65,7 +65,7 @@ static int tcp_update_limit(struct mem_cgroup *memcg, unsigned long nr_pages) * because when this value change, the code to process it is not * patched in yet. */ - static_key_slow_inc(&memcg_sockets_enabled_key); + static_branch_inc(&memcg_sockets_enabled_key); memcg->tcp_mem.active = true; } -- GitLab From 686739f6af5e8d5687ffebbf1193ff066aada6d9 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Thu, 14 Jan 2016 15:21:37 -0800 Subject: [PATCH 2820/2855] memcg: avoid vmpressure oops when memcg disabled A CONFIG_MEMCG=y kernel booted with "cgroup_disable=memory" crashes on a NULL memcg (but non-NULL root_mem_cgroup) when vmpressure kicks in. Here's the patch I use to avoid that, but you might prefer a test on mem_cgroup_disabled() somewhere. Signed-off-by: Hugh Dickins Acked-by: Johannes Weiner Cc: David S. Miller Cc: Vladimir Davydov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmpressure.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/vmpressure.c b/mm/vmpressure.c index 506f03e4be47a..9a6c0704211c8 100644 --- a/mm/vmpressure.c +++ b/mm/vmpressure.c @@ -260,7 +260,7 @@ void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, bool tree, enum vmpressure_levels level; /* For now, no users for root-level efficiency */ - if (memcg == root_mem_cgroup) + if (!memcg || memcg == root_mem_cgroup) return; spin_lock(&vmpr->sr_lock); -- GitLab From 0eb77e9880321915322d42913c3b53241739c8aa Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Thu, 14 Jan 2016 15:21:40 -0800 Subject: [PATCH 2821/2855] vmstat: make vmstat_updater deferrable again and shut down on idle Currently the vmstat updater is not deferrable as a result of commit ba4877b9ca51 ("vmstat: do not use deferrable delayed work for vmstat_update"). This in turn can cause multiple interruptions of the applications because the vmstat updater may run at Make vmstate_update deferrable again and provide a function that folds the differentials when the processor is going to idle mode thus addressing the issue of the above commit in a clean way. Note that the shepherd thread will continue scanning the differentials from another processor and will reenable the vmstat workers if it detects any changes. Fixes: ba4877b9ca51 ("vmstat: do not use deferrable delayed work for vmstat_update") Signed-off-by: Christoph Lameter Cc: Michal Hocko Cc: Johannes Weiner Cc: Tetsuo Handa Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/vmstat.h | 2 ++ kernel/sched/idle.c | 1 + mm/vmstat.c | 69 +++++++++++++++++++++++++++--------------- 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 3e5d9075960f6..73fae8c4a5fb5 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -189,6 +189,7 @@ extern void __inc_zone_state(struct zone *, enum zone_stat_item); extern void dec_zone_state(struct zone *, enum zone_stat_item); extern void __dec_zone_state(struct zone *, enum zone_stat_item); +void quiet_vmstat(void); void cpu_vm_stats_fold(int cpu); void refresh_zone_stat_thresholds(void); @@ -249,6 +250,7 @@ static inline void __dec_zone_page_state(struct page *page, static inline void refresh_zone_stat_thresholds(void) { } static inline void cpu_vm_stats_fold(int cpu) { } +static inline void quiet_vmstat(void) { } static inline void drain_zonestat(struct zone *zone, struct per_cpu_pageset *pset) { } diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index 4a2ef5a02fd3f..2489140a7c515 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c @@ -219,6 +219,7 @@ static void cpu_idle_loop(void) */ __current_set_polling(); + quiet_vmstat(); tick_nohz_idle_enter(); while (!need_resched()) { diff --git a/mm/vmstat.c b/mm/vmstat.c index c54fd2924f25a..83a003bc3cae5 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -460,7 +460,7 @@ static int fold_diff(int *diff) * * The function returns the number of global counters updated. */ -static int refresh_cpu_vm_stats(void) +static int refresh_cpu_vm_stats(bool do_pagesets) { struct zone *zone; int i; @@ -484,33 +484,35 @@ static int refresh_cpu_vm_stats(void) #endif } } - cond_resched(); #ifdef CONFIG_NUMA - /* - * Deal with draining the remote pageset of this - * processor - * - * Check if there are pages remaining in this pageset - * if not then there is nothing to expire. - */ - if (!__this_cpu_read(p->expire) || + if (do_pagesets) { + cond_resched(); + /* + * Deal with draining the remote pageset of this + * processor + * + * Check if there are pages remaining in this pageset + * if not then there is nothing to expire. + */ + if (!__this_cpu_read(p->expire) || !__this_cpu_read(p->pcp.count)) - continue; + continue; - /* - * We never drain zones local to this processor. - */ - if (zone_to_nid(zone) == numa_node_id()) { - __this_cpu_write(p->expire, 0); - continue; - } + /* + * We never drain zones local to this processor. + */ + if (zone_to_nid(zone) == numa_node_id()) { + __this_cpu_write(p->expire, 0); + continue; + } - if (__this_cpu_dec_return(p->expire)) - continue; + if (__this_cpu_dec_return(p->expire)) + continue; - if (__this_cpu_read(p->pcp.count)) { - drain_zone_pages(zone, this_cpu_ptr(&p->pcp)); - changes++; + if (__this_cpu_read(p->pcp.count)) { + drain_zone_pages(zone, this_cpu_ptr(&p->pcp)); + changes++; + } } #endif } @@ -1386,7 +1388,7 @@ static cpumask_var_t cpu_stat_off; static void vmstat_update(struct work_struct *w) { - if (refresh_cpu_vm_stats()) { + if (refresh_cpu_vm_stats(true)) { /* * Counters were updated so we expect more updates * to occur in the future. Keep on running the @@ -1417,6 +1419,23 @@ static void vmstat_update(struct work_struct *w) } } +/* + * Switch off vmstat processing and then fold all the remaining differentials + * until the diffs stay at zero. The function is used by NOHZ and can only be + * invoked when tick processing is not active. + */ +void quiet_vmstat(void) +{ + if (system_state != SYSTEM_RUNNING) + return; + + do { + if (!cpumask_test_and_set_cpu(smp_processor_id(), cpu_stat_off)) + cancel_delayed_work(this_cpu_ptr(&vmstat_work)); + + } while (refresh_cpu_vm_stats(false)); +} + /* * Check if the diffs for a certain cpu indicate that * an update is needed. @@ -1449,7 +1468,7 @@ static bool need_update(int cpu) */ static void vmstat_shepherd(struct work_struct *w); -static DECLARE_DELAYED_WORK(shepherd, vmstat_shepherd); +static DECLARE_DEFERRABLE_WORK(shepherd, vmstat_shepherd); static void vmstat_shepherd(struct work_struct *w) { -- GitLab From bb5b8589767a300014ba21c5984e6a4d15f0702d Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Thu, 14 Jan 2016 15:21:43 -0800 Subject: [PATCH 2822/2855] mm: make sure isolate_lru_page() is never called for tail page The VM_BUG_ON_PAGE() would catch such cases if any still exists. Signed-off-by: Kirill A. Shutemov Acked-by: Michal Hocko Acked-by: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/vmscan.c b/mm/vmscan.c index bb0cbd4c9f01f..108bd119f2f6b 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1426,6 +1426,7 @@ int isolate_lru_page(struct page *page) int ret = -EBUSY; VM_BUG_ON_PAGE(!page_count(page), page); + VM_BUG_ON_PAGE(PageTail(page), page); if (PageLRU(page)) { struct zone *zone = page_zone(page); -- GitLab From 0e41e277971799bad2764ad4e6284817e9a6da5b Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Thu, 14 Jan 2016 15:21:46 -0800 Subject: [PATCH 2823/2855] mm: /proc/pid/clear_refs: no need to clear VM_SOFTDIRTY in clear_soft_dirty_pmd() clear_soft_dirty_pmd() is called by clear_refs_write(CLEAR_REFS_SOFT_DIRTY), VM_SOFTDIRTY was already cleared before walk_page_range(). Signed-off-by: Oleg Nesterov Acked-by: Kirill A. Shutemov Acked-by: Cyrill Gorcunov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/task_mmu.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 18a30aedfa5d4..46d9619d0aea3 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -881,9 +881,6 @@ static inline void clear_soft_dirty_pmd(struct vm_area_struct *vma, pmd = pmd_wrprotect(pmd); pmd = pmd_clear_soft_dirty(pmd); - if (vma->vm_flags & VM_SOFTDIRTY) - vma->vm_flags &= ~VM_SOFTDIRTY; - set_pmd_at(vma->vm_mm, addr, pmdp, pmd); } #else -- GitLab From 0d576d20ccdeffbb7ba28053107fa6f838b67f3a Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 14 Jan 2016 15:21:49 -0800 Subject: [PATCH 2824/2855] mm/swapfile.c: use list_for_each_entry_safe in free_swap_count_continuations Use list_for_each_entry_safe() instead of list_for_each_safe() to simplify the code. Signed-off-by: Geliang Tang Cc: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/swapfile.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mm/swapfile.c b/mm/swapfile.c index 77551a553f57d..e6b8591a3ed27 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -2953,11 +2953,10 @@ static void free_swap_count_continuations(struct swap_info_struct *si) struct page *head; head = vmalloc_to_page(si->swap_map + offset); if (page_private(head)) { - struct list_head *this, *next; - list_for_each_safe(this, next, &head->lru) { - struct page *page; - page = list_entry(this, struct page, lru); - list_del(this); + struct page *page, *next; + + list_for_each_entry_safe(page, next, &head->lru, lru) { + list_del(&page->lru); __free_page(page); } } -- GitLab From 3e89e1c5ea84211b99199c7636a7d73c50c6b512 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 14 Jan 2016 15:21:52 -0800 Subject: [PATCH 2825/2855] hugetlb: make mm and fs code explicitly non-modular The Kconfig currently controlling compilation of this code is: config HUGETLBFS bool "HugeTLB file system support" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. Since module_init translates to device_initcall in the non-modular case, the init ordering gets moved to earlier levels when we use the more appropriate initcalls here. Originally I had the fs part and the mm part as separate commits, just by happenstance of the nature of how I detected these non-modular use cases. But that can possibly introduce regressions if the patch merge ordering puts the fs part 1st -- as the 0-day testing reported a splat at mount time. Investigating with "initcall_debug" showed that the delta was init_hugetlbfs_fs being called _before_ hugetlb_init instead of after. So both the fs change and the mm change are here together. In addition, it worked before due to luck of link order, since they were both in the same initcall category. So we now have the fs part using fs_initcall, and the mm part using subsys_initcall, which puts it one bucket earlier. It now passes the basic sanity test that failed in earlier 0-day testing. We delete the MODULE_LICENSE tag and capture that information at the top of the file alongside author comments, etc. We don't replace module.h with init.h since the file already has that. Also note that MODULE_ALIAS is a no-op for non-modular code. Signed-off-by: Paul Gortmaker Reported-by: kernel test robot Cc: Nadia Yvette Chambers Cc: Alexander Viro Cc: Naoya Horiguchi Reviewed-by: Mike Kravetz Cc: David Rientjes Cc: Hillf Danton Acked-by: Davidlohr Bueso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/hugetlbfs/inode.c | 27 ++------------------------- mm/hugetlb.c | 39 +-------------------------------------- 2 files changed, 3 insertions(+), 63 deletions(-) diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index a1cb8fd2289b9..47789292a582f 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -4,11 +4,11 @@ * Nadia Yvette Chambers, 2002 * * Copyright (C) 2002 Linus Torvalds. + * License: GPL */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include #include #include #include /* remove ASAP */ @@ -1202,7 +1202,6 @@ static struct file_system_type hugetlbfs_fs_type = { .mount = hugetlbfs_mount, .kill_sb = kill_litter_super, }; -MODULE_ALIAS_FS("hugetlbfs"); static struct vfsmount *hugetlbfs_vfsmount[HUGE_MAX_HSTATE]; @@ -1356,26 +1355,4 @@ static int __init init_hugetlbfs_fs(void) out2: return error; } - -static void __exit exit_hugetlbfs_fs(void) -{ - struct hstate *h; - int i; - - - /* - * Make sure all delayed rcu free inodes are flushed before we - * destroy cache. - */ - rcu_barrier(); - kmem_cache_destroy(hugetlbfs_inode_cachep); - i = 0; - for_each_hstate(h) - kern_unmount(hugetlbfs_vfsmount[i++]); - unregister_filesystem(&hugetlbfs_fs_type); -} - -module_init(init_hugetlbfs_fs) -module_exit(exit_hugetlbfs_fs) - -MODULE_LICENSE("GPL"); +fs_initcall(init_hugetlbfs_fs) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index ef6963b577fd2..be934df69b859 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -4,7 +4,6 @@ */ #include #include -#include #include #include #include @@ -2549,25 +2548,6 @@ static void hugetlb_unregister_node(struct node *node) nhs->hugepages_kobj = NULL; } -/* - * hugetlb module exit: unregister hstate attributes from node devices - * that have them. - */ -static void hugetlb_unregister_all_nodes(void) -{ - int nid; - - /* - * disable node device registrations. - */ - register_hugetlbfs_with_node(NULL, NULL); - - /* - * remove hstate attributes from any nodes that have them. - */ - for (nid = 0; nid < nr_node_ids; nid++) - hugetlb_unregister_node(node_devices[nid]); -} /* * Register hstate attributes for a single node device. @@ -2632,27 +2612,10 @@ static struct hstate *kobj_to_node_hstate(struct kobject *kobj, int *nidp) return NULL; } -static void hugetlb_unregister_all_nodes(void) { } - static void hugetlb_register_all_nodes(void) { } #endif -static void __exit hugetlb_exit(void) -{ - struct hstate *h; - - hugetlb_unregister_all_nodes(); - - for_each_hstate(h) { - kobject_put(hstate_kobjs[hstate_index(h)]); - } - - kobject_put(hugepages_kobj); - kfree(hugetlb_fault_mutex_table); -} -module_exit(hugetlb_exit); - static int __init hugetlb_init(void) { int i; @@ -2690,7 +2653,7 @@ static int __init hugetlb_init(void) mutex_init(&hugetlb_fault_mutex_table[i]); return 0; } -module_init(hugetlb_init); +subsys_initcall(hugetlb_init); /* Should be called on processing a hugepagesz=... option */ void __init hugetlb_add_hstate(unsigned int order) -- GitLab From 6f754ba4cfcc044078d4836056ac45404e1b6e85 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Thu, 14 Jan 2016 15:21:55 -0800 Subject: [PATCH 2826/2855] memory-hotplug: don't BUG() in register_memory_resource() Out of memory condition is not a bug and while we can't add new memory in such case crashing the system seems wrong. Propagating the return value from register_memory_resource() requires interface change. Signed-off-by: Vitaly Kuznetsov Reviewed-by: Igor Mammedov Acked-by: David Rientjes Cc: Tang Chen Cc: Naoya Horiguchi Cc: Xishi Qiu Cc: Sheng Yong Cc: Zhu Guihua Cc: Dan Williams Cc: David Vrabel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory_hotplug.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index a042a9d537bb3..92f95952692b0 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -131,7 +131,8 @@ static struct resource *register_memory_resource(u64 start, u64 size) { struct resource *res; res = kzalloc(sizeof(struct resource), GFP_KERNEL); - BUG_ON(!res); + if (!res) + return ERR_PTR(-ENOMEM); res->name = "System RAM"; res->start = start; @@ -140,7 +141,7 @@ static struct resource *register_memory_resource(u64 start, u64 size) if (request_resource(&iomem_resource, res) < 0) { pr_debug("System RAM resource %pR cannot be added\n", res); kfree(res); - res = NULL; + return ERR_PTR(-EEXIST); } return res; } @@ -1312,8 +1313,8 @@ int __ref add_memory(int nid, u64 start, u64 size) int ret; res = register_memory_resource(start, size); - if (!res) - return -EEXIST; + if (IS_ERR(res)) + return PTR_ERR(res); ret = add_memory_resource(nid, res); if (ret < 0) -- GitLab From 0bc126d460453736c0e03d9da7ae0e9d4fcf86b3 Mon Sep 17 00:00:00 2001 From: Rodrigo Freire Date: Thu, 14 Jan 2016 15:21:58 -0800 Subject: [PATCH 2827/2855] Documentation/filesystems: describe the shared memory usage/accounting The Shared Memory accounting support is present in Kernel since commit 4b02108ac1b3 ("mm: oom analysis: add shmem vmstat") and in userland free(1) since 2014. This patch updates the Documentation to reflect this change. Signed-off-by: Rodrigo Freire Acked-by: Vlastimil Babka Cc: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/filesystems/proc.txt | 2 ++ Documentation/filesystems/tmpfs.txt | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index ffcd49589ab5f..e95aa1c6eadfe 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -855,6 +855,7 @@ Dirty: 968 kB Writeback: 0 kB AnonPages: 861800 kB Mapped: 280372 kB +Shmem: 644 kB Slab: 284364 kB SReclaimable: 159856 kB SUnreclaim: 124508 kB @@ -911,6 +912,7 @@ MemAvailable: An estimate of how much memory is available for starting new AnonPages: Non-file backed pages mapped into userspace page tables AnonHugePages: Non-file backed huge pages mapped into userspace page tables Mapped: files which have been mmaped, such as libraries + Shmem: Total memory used by shared memory (shmem) and tmpfs Slab: in-kernel data structures cache SReclaimable: Part of Slab, that might be reclaimed, such as caches SUnreclaim: Part of Slab, that cannot be reclaimed on memory pressure diff --git a/Documentation/filesystems/tmpfs.txt b/Documentation/filesystems/tmpfs.txt index 98ef551241581..d392e1505f170 100644 --- a/Documentation/filesystems/tmpfs.txt +++ b/Documentation/filesystems/tmpfs.txt @@ -17,10 +17,10 @@ RAM, where you have to create an ordinary filesystem on top. Ramdisks cannot swap and you do not have the possibility to resize them. Since tmpfs lives completely in the page cache and on swap, all tmpfs -pages currently in memory will show up as cached. It will not show up -as shared or something like that. Further on you can check the actual -RAM+swap use of a tmpfs instance with df(1) and du(1). - +pages will be shown as "Shmem" in /proc/meminfo and "Shared" in +free(1). Notice that these counters also include shared memory +(shmem, see ipcs(1)). The most reliable way to get the count is +using df(1) and du(1). tmpfs has the following uses: -- GitLab From d72ee911130631b50a8ccc615a7d4622c2062194 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 14 Jan 2016 15:22:01 -0800 Subject: [PATCH 2828/2855] mm: move lru_to_page to mm_inline.h Move lru_to_page() from internal.h to mm_inline.h. Signed-off-by: Geliang Tang Acked-by: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm_inline.h | 2 ++ mm/internal.h | 2 -- mm/readahead.c | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index cf55945c83fb9..712e8c37a200b 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -100,4 +100,6 @@ static __always_inline enum lru_list page_lru(struct page *page) return lru; } +#define lru_to_page(head) (list_entry((head)->prev, struct page, lru)) + #endif diff --git a/mm/internal.h b/mm/internal.h index 016452d2fede4..38e24b89e4c40 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -119,8 +119,6 @@ extern int isolate_lru_page(struct page *page); extern void putback_lru_page(struct page *page); extern bool zone_reclaimable(struct zone *zone); -#define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru)) - /* * in mm/rmap.c: */ diff --git a/mm/readahead.c b/mm/readahead.c index 0aff760b09d4a..20e58e820e444 100644 --- a/mm/readahead.c +++ b/mm/readahead.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "internal.h" -- GitLab From d30b5545bdcf802ffc24ec7dbc6dc4036f6e3820 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 14 Jan 2016 15:22:04 -0800 Subject: [PATCH 2829/2855] include/linux/memblock.h: fix ordering of 'flags' argument in comments for_each_free_mem_range() and for_each_free_mem_range_reverse() both accept a 'flags' argument, the comment surrounding the macro placed the 'flags' documentation at the very end, while 'flags' is in fact the 3rd argument to the macro, so let's preserve natural ordering here. Fixes: fc6daaf931518 ("mm/memblock: add extra "flags" to memblock to allow selection of memory based on attribute") Signed-off-by: Florian Fainelli Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memblock.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/memblock.h b/include/linux/memblock.h index c0c4208a286fa..173fb44e22f13 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -216,10 +216,10 @@ void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn, * for_each_free_mem_range - iterate through free memblock areas * @i: u64 used as loop variable * @nid: node selector, %NUMA_NO_NODE for all nodes + * @flags: pick from blocks based on memory attributes * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL * @p_nid: ptr to int for nid of the range, can be %NULL - * @flags: pick from blocks based on memory attributes * * Walks over free (memory && !reserved) areas of memblock. Available as * soon as memblock is initialized. @@ -232,10 +232,10 @@ void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn, * for_each_free_mem_range_reverse - rev-iterate through free memblock areas * @i: u64 used as loop variable * @nid: node selector, %NUMA_NO_NODE for all nodes + * @flags: pick from blocks based on memory attributes * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL * @p_nid: ptr to int for nid of the range, can be %NULL - * @flags: pick from blocks based on memory attributes * * Walks over free (memory && !reserved) areas of memblock in reverse * order. Available as soon as memblock is initialized. -- GitLab From 84638335900f1995495838fe1bd4870c43ec1f67 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Thu, 14 Jan 2016 15:22:07 -0800 Subject: [PATCH 2830/2855] mm: rework virtual memory accounting When inspecting a vague code inside prctl(PR_SET_MM_MEM) call (which testing the RLIMIT_DATA value to figure out if we're allowed to assign new @start_brk, @brk, @start_data, @end_data from mm_struct) it's been commited that RLIMIT_DATA in a form it's implemented now doesn't do anything useful because most of user-space libraries use mmap() syscall for dynamic memory allocations. Linus suggested to convert RLIMIT_DATA rlimit into something suitable for anonymous memory accounting. But in this patch we go further, and the changes are bundled together as: * keep vma counting if CONFIG_PROC_FS=n, will be used for limits * replace mm->shared_vm with better defined mm->data_vm * account anonymous executable areas as executable * account file-backed growsdown/up areas as stack * drop struct file* argument from vm_stat_account * enforce RLIMIT_DATA for size of data areas This way code looks cleaner: now code/stack/data classification depends only on vm_flags state: VM_EXEC & ~VM_WRITE -> code (VmExe + VmLib in proc) VM_GROWSUP | VM_GROWSDOWN -> stack (VmStk) VM_WRITE & ~VM_SHARED & !stack -> data (VmData) The rest (VmSize - VmData - VmStk - VmExe - VmLib) could be called "shared", but that might be strange beast like readonly-private or VM_IO area. - RLIMIT_AS limits whole address space "VmSize" - RLIMIT_STACK limits stack "VmStk" (but each vma individually) - RLIMIT_DATA now limits "VmData" Signed-off-by: Konstantin Khlebnikov Signed-off-by: Cyrill Gorcunov Cc: Quentin Casasnovas Cc: Vegard Nossum Acked-by: Linus Torvalds Cc: Willy Tarreau Cc: Andy Lutomirski Cc: Kees Cook Cc: Vladimir Davydov Cc: Pavel Emelyanov Cc: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/kernel/perfmon.c | 3 +- fs/proc/task_mmu.c | 7 ++--- include/linux/mm.h | 13 ++------ include/linux/mm_types.h | 2 +- kernel/fork.c | 5 ++- mm/debug.c | 4 +-- mm/mmap.c | 63 +++++++++++++++++++------------------- mm/mprotect.c | 8 +++-- mm/mremap.c | 7 +++-- 9 files changed, 54 insertions(+), 58 deletions(-) diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 60e02f7747ff0..9cd607b069645 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -2332,8 +2332,7 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t */ insert_vm_struct(mm, vma); - vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file, - vma_pages(vma)); + vm_stat_account(vma->vm_mm, vma->vm_flags, vma_pages(vma)); up_write(&task->mm->mmap_sem); /* diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 46d9619d0aea3..a353b4c6e86e5 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -23,7 +23,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm) { - unsigned long data, text, lib, swap, ptes, pmds, anon, file, shmem; + unsigned long text, lib, swap, ptes, pmds, anon, file, shmem; unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss; anon = get_mm_counter(mm, MM_ANONPAGES); @@ -44,7 +44,6 @@ void task_mem(struct seq_file *m, struct mm_struct *mm) if (hiwater_rss < mm->hiwater_rss) hiwater_rss = mm->hiwater_rss; - data = mm->total_vm - mm->shared_vm - mm->stack_vm; text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10; lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text; swap = get_mm_counter(mm, MM_SWAPENTS); @@ -76,7 +75,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm) anon << (PAGE_SHIFT-10), file << (PAGE_SHIFT-10), shmem << (PAGE_SHIFT-10), - data << (PAGE_SHIFT-10), + mm->data_vm << (PAGE_SHIFT-10), mm->stack_vm << (PAGE_SHIFT-10), text, lib, ptes >> 10, pmds >> 10, @@ -97,7 +96,7 @@ unsigned long task_statm(struct mm_struct *mm, get_mm_counter(mm, MM_SHMEMPAGES); *text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> PAGE_SHIFT; - *data = mm->total_vm - mm->shared_vm; + *data = mm->data_vm + mm->stack_vm; *resident = *shared + get_mm_counter(mm, MM_ANONPAGES); return mm->total_vm; } diff --git a/include/linux/mm.h b/include/linux/mm.h index ec9d4559514d6..839d9e9a1c386 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1929,7 +1929,9 @@ extern void mm_drop_all_locks(struct mm_struct *mm); extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file); extern struct file *get_mm_exe_file(struct mm_struct *mm); -extern int may_expand_vm(struct mm_struct *mm, unsigned long npages); +extern bool may_expand_vm(struct mm_struct *, vm_flags_t, unsigned long npages); +extern void vm_stat_account(struct mm_struct *, vm_flags_t, long npages); + extern struct vm_area_struct *_install_special_mapping(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long flags, @@ -2147,15 +2149,6 @@ typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, extern int apply_to_page_range(struct mm_struct *mm, unsigned long address, unsigned long size, pte_fn_t fn, void *data); -#ifdef CONFIG_PROC_FS -void vm_stat_account(struct mm_struct *, unsigned long, struct file *, long); -#else -static inline void vm_stat_account(struct mm_struct *mm, - unsigned long flags, struct file *file, long pages) -{ - mm->total_vm += pages; -} -#endif /* CONFIG_PROC_FS */ #ifdef CONFIG_DEBUG_PAGEALLOC extern bool _debug_pagealloc_enabled; diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 207890be93c8c..6bc9a0ce22530 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -427,7 +427,7 @@ struct mm_struct { unsigned long total_vm; /* Total pages mapped */ unsigned long locked_vm; /* Pages that have PG_mlocked set */ unsigned long pinned_vm; /* Refcount permanently increased */ - unsigned long shared_vm; /* Shared pages (files) */ + unsigned long data_vm; /* VM_WRITE & ~VM_SHARED/GROWSDOWN */ unsigned long exec_vm; /* VM_EXEC & ~VM_WRITE */ unsigned long stack_vm; /* VM_GROWSUP/DOWN */ unsigned long def_flags; diff --git a/kernel/fork.c b/kernel/fork.c index 51915842f1c06..2e391c754ae73 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -414,7 +414,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) RCU_INIT_POINTER(mm->exe_file, get_mm_exe_file(oldmm)); mm->total_vm = oldmm->total_vm; - mm->shared_vm = oldmm->shared_vm; + mm->data_vm = oldmm->data_vm; mm->exec_vm = oldmm->exec_vm; mm->stack_vm = oldmm->stack_vm; @@ -433,8 +433,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) struct file *file; if (mpnt->vm_flags & VM_DONTCOPY) { - vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file, - -vma_pages(mpnt)); + vm_stat_account(mm, mpnt->vm_flags, -vma_pages(mpnt)); continue; } charge = 0; diff --git a/mm/debug.c b/mm/debug.c index 668aa35191ca1..5d2072ed8d5e7 100644 --- a/mm/debug.c +++ b/mm/debug.c @@ -175,7 +175,7 @@ void dump_mm(const struct mm_struct *mm) "mmap_base %lu mmap_legacy_base %lu highest_vm_end %lu\n" "pgd %p mm_users %d mm_count %d nr_ptes %lu nr_pmds %lu map_count %d\n" "hiwater_rss %lx hiwater_vm %lx total_vm %lx locked_vm %lx\n" - "pinned_vm %lx shared_vm %lx exec_vm %lx stack_vm %lx\n" + "pinned_vm %lx data_vm %lx exec_vm %lx stack_vm %lx\n" "start_code %lx end_code %lx start_data %lx end_data %lx\n" "start_brk %lx brk %lx start_stack %lx\n" "arg_start %lx arg_end %lx env_start %lx env_end %lx\n" @@ -209,7 +209,7 @@ void dump_mm(const struct mm_struct *mm) mm_nr_pmds((struct mm_struct *)mm), mm->map_count, mm->hiwater_rss, mm->hiwater_vm, mm->total_vm, mm->locked_vm, - mm->pinned_vm, mm->shared_vm, mm->exec_vm, mm->stack_vm, + mm->pinned_vm, mm->data_vm, mm->exec_vm, mm->stack_vm, mm->start_code, mm->end_code, mm->start_data, mm->end_data, mm->start_brk, mm->brk, mm->start_stack, mm->arg_start, mm->arg_end, mm->env_start, mm->env_end, diff --git a/mm/mmap.c b/mm/mmap.c index f32b84ad621a2..b3f00b616b810 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1220,24 +1220,6 @@ none: return NULL; } -#ifdef CONFIG_PROC_FS -void vm_stat_account(struct mm_struct *mm, unsigned long flags, - struct file *file, long pages) -{ - const unsigned long stack_flags - = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN); - - mm->total_vm += pages; - - if (file) { - mm->shared_vm += pages; - if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC) - mm->exec_vm += pages; - } else if (flags & stack_flags) - mm->stack_vm += pages; -} -#endif /* CONFIG_PROC_FS */ - /* * If a hint addr is less than mmap_min_addr change hint to be as * low as possible but still greater than mmap_min_addr @@ -1556,7 +1538,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, unsigned long charged = 0; /* Check against address space limit. */ - if (!may_expand_vm(mm, len >> PAGE_SHIFT)) { + if (!may_expand_vm(mm, vm_flags, len >> PAGE_SHIFT)) { unsigned long nr_pages; /* @@ -1565,7 +1547,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr, */ nr_pages = count_vma_pages_range(mm, addr, addr + len); - if (!may_expand_vm(mm, (len >> PAGE_SHIFT) - nr_pages)) + if (!may_expand_vm(mm, vm_flags, + (len >> PAGE_SHIFT) - nr_pages)) return -ENOMEM; } @@ -1664,7 +1647,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, out: perf_event_mmap(vma); - vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT); + vm_stat_account(mm, vm_flags, len >> PAGE_SHIFT); if (vm_flags & VM_LOCKED) { if (!((vm_flags & VM_SPECIAL) || is_vm_hugetlb_page(vma) || vma == get_gate_vma(current->mm))) @@ -2111,7 +2094,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns unsigned long new_start, actual_size; /* address space limit tests */ - if (!may_expand_vm(mm, grow)) + if (!may_expand_vm(mm, vma->vm_flags, grow)) return -ENOMEM; /* Stack limit test */ @@ -2208,8 +2191,7 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address) spin_lock(&mm->page_table_lock); if (vma->vm_flags & VM_LOCKED) mm->locked_vm += grow; - vm_stat_account(mm, vma->vm_flags, - vma->vm_file, grow); + vm_stat_account(mm, vma->vm_flags, grow); anon_vma_interval_tree_pre_update_vma(vma); vma->vm_end = address; anon_vma_interval_tree_post_update_vma(vma); @@ -2284,8 +2266,7 @@ int expand_downwards(struct vm_area_struct *vma, spin_lock(&mm->page_table_lock); if (vma->vm_flags & VM_LOCKED) mm->locked_vm += grow; - vm_stat_account(mm, vma->vm_flags, - vma->vm_file, grow); + vm_stat_account(mm, vma->vm_flags, grow); anon_vma_interval_tree_pre_update_vma(vma); vma->vm_start = address; vma->vm_pgoff -= grow; @@ -2399,7 +2380,7 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma) if (vma->vm_flags & VM_ACCOUNT) nr_accounted += nrpages; - vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages); + vm_stat_account(mm, vma->vm_flags, -nrpages); vma = remove_vma(vma); } while (vma); vm_unacct_memory(nr_accounted); @@ -2769,7 +2750,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) } /* Check against address space limits *after* clearing old maps... */ - if (!may_expand_vm(mm, len >> PAGE_SHIFT)) + if (!may_expand_vm(mm, flags, len >> PAGE_SHIFT)) return -ENOMEM; if (mm->map_count > sysctl_max_map_count) @@ -2804,6 +2785,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) out: perf_event_mmap(vma); mm->total_vm += len >> PAGE_SHIFT; + mm->data_vm += len >> PAGE_SHIFT; if (flags & VM_LOCKED) mm->locked_vm += (len >> PAGE_SHIFT); vma->vm_flags |= VM_SOFTDIRTY; @@ -2995,9 +2977,28 @@ out: * Return true if the calling process may expand its vm space by the passed * number of pages */ -int may_expand_vm(struct mm_struct *mm, unsigned long npages) +bool may_expand_vm(struct mm_struct *mm, vm_flags_t flags, unsigned long npages) { - return mm->total_vm + npages <= rlimit(RLIMIT_AS) >> PAGE_SHIFT; + if (mm->total_vm + npages > rlimit(RLIMIT_AS) >> PAGE_SHIFT) + return false; + + if ((flags & (VM_WRITE | VM_SHARED | (VM_STACK_FLAGS & + (VM_GROWSUP | VM_GROWSDOWN)))) == VM_WRITE) + return mm->data_vm + npages <= rlimit(RLIMIT_DATA); + + return true; +} + +void vm_stat_account(struct mm_struct *mm, vm_flags_t flags, long npages) +{ + mm->total_vm += npages; + + if ((flags & (VM_EXEC | VM_WRITE)) == VM_EXEC) + mm->exec_vm += npages; + else if (flags & (VM_STACK_FLAGS & (VM_GROWSUP | VM_GROWSDOWN))) + mm->stack_vm += npages; + else if ((flags & (VM_WRITE | VM_SHARED)) == VM_WRITE) + mm->data_vm += npages; } static int special_mapping_fault(struct vm_area_struct *vma, @@ -3079,7 +3080,7 @@ static struct vm_area_struct *__install_special_mapping( if (ret) goto out; - mm->total_vm += len >> PAGE_SHIFT; + vm_stat_account(mm, vma->vm_flags, len >> PAGE_SHIFT); perf_event_mmap(vma); diff --git a/mm/mprotect.c b/mm/mprotect.c index ef5be8eaab001..c764402c464f1 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -278,6 +278,10 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, * even if read-only so there is no need to account for them here */ if (newflags & VM_WRITE) { + /* Check space limits when area turns into data. */ + if (!may_expand_vm(mm, newflags, nrpages) && + may_expand_vm(mm, oldflags, nrpages)) + return -ENOMEM; if (!(oldflags & (VM_ACCOUNT|VM_WRITE|VM_HUGETLB| VM_SHARED|VM_NORESERVE))) { charged = nrpages; @@ -334,8 +338,8 @@ success: populate_vma_page_range(vma, start, end, NULL); } - vm_stat_account(mm, oldflags, vma->vm_file, -nrpages); - vm_stat_account(mm, newflags, vma->vm_file, nrpages); + vm_stat_account(mm, oldflags, -nrpages); + vm_stat_account(mm, newflags, nrpages); perf_event_mmap(vma); return 0; diff --git a/mm/mremap.c b/mm/mremap.c index de824e72c3e89..e55b157865d5c 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -317,7 +317,7 @@ static unsigned long move_vma(struct vm_area_struct *vma, * If this were a serious issue, we'd add a flag to do_munmap(). */ hiwater_vm = mm->hiwater_vm; - vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT); + vm_stat_account(mm, vma->vm_flags, new_len >> PAGE_SHIFT); /* Tell pfnmap has moved from this vma */ if (unlikely(vma->vm_flags & VM_PFNMAP)) @@ -383,7 +383,8 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr, return ERR_PTR(-EAGAIN); } - if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) + if (!may_expand_vm(mm, vma->vm_flags, + (new_len - old_len) >> PAGE_SHIFT)) return ERR_PTR(-ENOMEM); if (vma->vm_flags & VM_ACCOUNT) { @@ -545,7 +546,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, goto out; } - vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages); + vm_stat_account(mm, vma->vm_flags, pages); if (vma->vm_flags & VM_LOCKED) { mm->locked_vm += pages; locked = true; -- GitLab From 543dfb2df8ebb3eb0b499eae1d63de1701a99b40 Mon Sep 17 00:00:00 2001 From: Joshua Clayton Date: Thu, 14 Jan 2016 15:22:10 -0800 Subject: [PATCH 2831/2855] mm: fix noisy sparse warning in LIBCFS_ALLOC_PRE() Running sparse on drivers/staging/lustre results in dozens of warnings: include/linux/gfp.h:281:41: warning: odd constant _Bool cast (400000 becomes 1) Use "!!" to explicitly convert to bool and get rid of the warning. Signed-off-by: Joshua Clayton Cc: Mel Gorman Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/gfp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 91f74e741aa2d..28ad5f6494b01 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -278,7 +278,7 @@ static inline int gfpflags_to_migratetype(const gfp_t gfp_flags) static inline bool gfpflags_allow_blocking(const gfp_t gfp_flags) { - return (bool __force)(gfp_flags & __GFP_DIRECT_RECLAIM); + return !!(gfp_flags & __GFP_DIRECT_RECLAIM); } #ifdef CONFIG_HIGHMEM -- GitLab From fec174d6699e2e39d34c7c6ee2fe360e518e68c0 Mon Sep 17 00:00:00 2001 From: Naoya Horiguchi Date: Thu, 14 Jan 2016 15:22:13 -0800 Subject: [PATCH 2832/2855] mm/page_isolation: use macro to judge the alignment Signed-off-by: Wang Xiaoqiang Reviewed-by: Naoya Horiguchi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_isolation.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/page_isolation.c b/mm/page_isolation.c index f484b9300fe32..5e139fec6c6cc 100644 --- a/mm/page_isolation.c +++ b/mm/page_isolation.c @@ -165,8 +165,8 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn, unsigned long undo_pfn; struct page *page; - BUG_ON((start_pfn) & (pageblock_nr_pages - 1)); - BUG_ON((end_pfn) & (pageblock_nr_pages - 1)); + BUG_ON(!IS_ALIGNED(start_pfn, pageblock_nr_pages)); + BUG_ON(!IS_ALIGNED(end_pfn, pageblock_nr_pages)); for (pfn = start_pfn; pfn < end_pfn; -- GitLab From cb5490a5eea415106d7438df440da5fb1e17318d Mon Sep 17 00:00:00 2001 From: John Allen Date: Thu, 14 Jan 2016 15:22:16 -0800 Subject: [PATCH 2833/2855] drivers/base/memory.c: fix kernel warning during memory hotplug on ppc64 Fix a bug where a kernel warning is triggered when performing a memory hotplug on ppc64. This warning may also occur on any architecture that uses the memory_probe_store interface. WARNING: at drivers/base/memory.c:200 CPU: 9 PID: 13042 Comm: systemd-udevd Not tainted 4.4.0-rc4-00113-g0bd0f1e-dirty #7 NIP [c00000000055e034] pages_correctly_reserved+0x134/0x1b0 LR [c00000000055e7f8] memory_subsys_online+0x68/0x140 Call Trace: memory_subsys_online+0x68/0x140 device_online+0xb4/0x120 store_mem_state+0xb0/0x180 dev_attr_store+0x34/0x60 sysfs_kf_write+0x64/0xa0 kernfs_fop_write+0x17c/0x1e0 __vfs_write+0x40/0x160 vfs_write+0xb8/0x200 SyS_write+0x60/0x110 system_call+0x38/0xd0 The warning is triggered because there is a udev rule that automatically tries to online memory after it has been added. The udev rule varies from distro to distro, but will generally look something like: SUBSYSTEM=="memory", ACTION=="add", ATTR{state}=="offline", ATTR{state}="online" On any architecture that uses memory_probe_store to reserve memory, the udev rule will be triggered after the first section of the block is reserved and will subsequently attempt to online the entire block, interrupting the memory reservation process and causing the warning. This patch modifies memory_probe_store to add a block of memory with a single call to add_memory as opposed to looping through and adding each section individually. A single call to add_memory is protected by the mem_hotplug mutex which will prevent the udev rule from onlining memory until the reservation of the entire block is complete. Signed-off-by: John Allen Acked-by: Dave Hansen Cc: Nathan Fontenot Cc: Michael Ellerman Cc: Greg Kroah-Hartman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/memory.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 6d7b14c2798e1..619fe584a44cc 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -450,8 +450,7 @@ memory_probe_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { u64 phys_addr; - int nid; - int i, ret; + int nid, ret; unsigned long pages_per_block = PAGES_PER_SECTION * sections_per_block; ret = kstrtoull(buf, 0, &phys_addr); @@ -461,15 +460,12 @@ memory_probe_store(struct device *dev, struct device_attribute *attr, if (phys_addr & ((pages_per_block << PAGE_SHIFT) - 1)) return -EINVAL; - for (i = 0; i < sections_per_block; i++) { - nid = memory_add_physaddr_to_nid(phys_addr); - ret = add_memory(nid, phys_addr, - PAGES_PER_SECTION << PAGE_SHIFT); - if (ret) - goto out; + nid = memory_add_physaddr_to_nid(phys_addr); + ret = add_memory(nid, phys_addr, + MIN_MEMORY_BLOCK_SIZE * sections_per_block); - phys_addr += MIN_MEMORY_BLOCK_SIZE; - } + if (ret) + goto out; ret = count; out: -- GitLab From 7d2eba0557c18f7522b98befed98799990dd4fdb Mon Sep 17 00:00:00 2001 From: Ebru Akagunduz Date: Thu, 14 Jan 2016 15:22:19 -0800 Subject: [PATCH 2834/2855] mm: add tracepoint for scanning pages This patch series makes swapin readahead up to a certain number to gain more thp performance and adds tracepoint for khugepaged_scan_pmd, collapse_huge_page, __collapse_huge_page_isolate. This patch series was written to deal with programs that access most, but not all, of their memory after they get swapped out. Currently these programs do not get their memory collapsed into THPs after the system swapped their memory out, while they would get THPs before swapping happened. This patch series was tested with a test program, it allocates 400MB of memory, writes to it, and then sleeps. I force the system to swap out all. Afterwards, the test program touches the area by writing and leaves a piece of it without writing. This shows how much swap in readahead made by the patch. Test results: After swapped out ------------------------------------------------------------------- | Anonymous | AnonHugePages | Swap | Fraction | ------------------------------------------------------------------- With patch | 90076 kB | 88064 kB | 309928 kB | %99 | ------------------------------------------------------------------- Without patch | 194068 kB | 192512 kB | 205936 kB | %99 | ------------------------------------------------------------------- After swapped in ------------------------------------------------------------------- | Anonymous | AnonHugePages | Swap | Fraction | ------------------------------------------------------------------- With patch | 201408 kB | 198656 kB | 198596 kB | %98 | ------------------------------------------------------------------- Without patch | 292624 kB | 192512 kB | 107380 kB | %65 | ------------------------------------------------------------------- This patch (of 3): Using static tracepoints, data of functions is recorded. It is good to automatize debugging without doing a lot of changes in the source code. This patch adds tracepoint for khugepaged_scan_pmd, collapse_huge_page and __collapse_huge_page_isolate. [dan.carpenter@oracle.com: add a missing tab] Signed-off-by: Ebru Akagunduz Acked-by: Kirill A. Shutemov Acked-by: Rik van Riel Cc: Naoya Horiguchi Cc: Andrea Arcangeli Cc: Joonsoo Kim Cc: Xie XiuQi Cc: Cyrill Gorcunov Cc: Mel Gorman Cc: David Rientjes Cc: Vlastimil Babka Cc: Aneesh Kumar K.V Cc: Hugh Dickins Cc: Johannes Weiner Cc: Michal Hocko Signed-off-by: Dan Carpenter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/trace/events/huge_memory.h | 136 +++++++++++++++++++++++ mm/huge_memory.c | 166 +++++++++++++++++++++++------ 2 files changed, 270 insertions(+), 32 deletions(-) create mode 100644 include/trace/events/huge_memory.h diff --git a/include/trace/events/huge_memory.h b/include/trace/events/huge_memory.h new file mode 100644 index 0000000000000..97d635cabac8d --- /dev/null +++ b/include/trace/events/huge_memory.h @@ -0,0 +1,136 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM huge_memory + +#if !defined(__HUGE_MEMORY_H) || defined(TRACE_HEADER_MULTI_READ) +#define __HUGE_MEMORY_H + +#include + +#include + +#define SCAN_STATUS \ + EM( SCAN_FAIL, "failed") \ + EM( SCAN_SUCCEED, "succeeded") \ + EM( SCAN_PMD_NULL, "pmd_null") \ + EM( SCAN_EXCEED_NONE_PTE, "exceed_none_pte") \ + EM( SCAN_PTE_NON_PRESENT, "pte_non_present") \ + EM( SCAN_PAGE_RO, "no_writable_page") \ + EM( SCAN_NO_REFERENCED_PAGE, "no_referenced_page") \ + EM( SCAN_PAGE_NULL, "page_null") \ + EM( SCAN_SCAN_ABORT, "scan_aborted") \ + EM( SCAN_PAGE_COUNT, "not_suitable_page_count") \ + EM( SCAN_PAGE_LRU, "page_not_in_lru") \ + EM( SCAN_PAGE_LOCK, "page_locked") \ + EM( SCAN_PAGE_ANON, "page_not_anon") \ + EM( SCAN_ANY_PROCESS, "no_process_for_page") \ + EM( SCAN_VMA_NULL, "vma_null") \ + EM( SCAN_VMA_CHECK, "vma_check_failed") \ + EM( SCAN_ADDRESS_RANGE, "not_suitable_address_range") \ + EM( SCAN_SWAP_CACHE_PAGE, "page_swap_cache") \ + EM( SCAN_DEL_PAGE_LRU, "could_not_delete_page_from_lru")\ + EM( SCAN_ALLOC_HUGE_PAGE_FAIL, "alloc_huge_page_failed") \ + EMe( SCAN_CGROUP_CHARGE_FAIL, "ccgroup_charge_failed") + +#undef EM +#undef EMe +#define EM(a, b) TRACE_DEFINE_ENUM(a); +#define EMe(a, b) TRACE_DEFINE_ENUM(a); + +SCAN_STATUS + +#undef EM +#undef EMe +#define EM(a, b) {a, b}, +#define EMe(a, b) {a, b} + +TRACE_EVENT(mm_khugepaged_scan_pmd, + + TP_PROTO(struct mm_struct *mm, unsigned long pfn, bool writable, + bool referenced, int none_or_zero, int status), + + TP_ARGS(mm, pfn, writable, referenced, none_or_zero, status), + + TP_STRUCT__entry( + __field(struct mm_struct *, mm) + __field(unsigned long, pfn) + __field(bool, writable) + __field(bool, referenced) + __field(int, none_or_zero) + __field(int, status) + ), + + TP_fast_assign( + __entry->mm = mm; + __entry->pfn = pfn; + __entry->writable = writable; + __entry->referenced = referenced; + __entry->none_or_zero = none_or_zero; + __entry->status = status; + ), + + TP_printk("mm=%p, scan_pfn=0x%lx, writable=%d, referenced=%d, none_or_zero=%d, status=%s", + __entry->mm, + __entry->pfn, + __entry->writable, + __entry->referenced, + __entry->none_or_zero, + __print_symbolic(__entry->status, SCAN_STATUS)) +); + +TRACE_EVENT(mm_collapse_huge_page, + + TP_PROTO(struct mm_struct *mm, int isolated, int status), + + TP_ARGS(mm, isolated, status), + + TP_STRUCT__entry( + __field(struct mm_struct *, mm) + __field(int, isolated) + __field(int, status) + ), + + TP_fast_assign( + __entry->mm = mm; + __entry->isolated = isolated; + __entry->status = status; + ), + + TP_printk("mm=%p, isolated=%d, status=%s", + __entry->mm, + __entry->isolated, + __print_symbolic(__entry->status, SCAN_STATUS)) +); + +TRACE_EVENT(mm_collapse_huge_page_isolate, + + TP_PROTO(unsigned long pfn, int none_or_zero, + bool referenced, bool writable, int status), + + TP_ARGS(pfn, none_or_zero, referenced, writable, status), + + TP_STRUCT__entry( + __field(unsigned long, pfn) + __field(int, none_or_zero) + __field(bool, referenced) + __field(bool, writable) + __field(int, status) + ), + + TP_fast_assign( + __entry->pfn = pfn; + __entry->none_or_zero = none_or_zero; + __entry->referenced = referenced; + __entry->writable = writable; + __entry->status = status; + ), + + TP_printk("scan_pfn=0x%lx, none_or_zero=%d, referenced=%d, writable=%d, status=%s", + __entry->pfn, + __entry->none_or_zero, + __entry->referenced, + __entry->writable, + __print_symbolic(__entry->status, SCAN_STATUS)) +); + +#endif /* __HUGE_MEMORY_H */ +#include diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 62fe06bb7d04b..f952f055fdcf5 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -31,6 +31,33 @@ #include #include "internal.h" +enum scan_result { + SCAN_FAIL, + SCAN_SUCCEED, + SCAN_PMD_NULL, + SCAN_EXCEED_NONE_PTE, + SCAN_PTE_NON_PRESENT, + SCAN_PAGE_RO, + SCAN_NO_REFERENCED_PAGE, + SCAN_PAGE_NULL, + SCAN_SCAN_ABORT, + SCAN_PAGE_COUNT, + SCAN_PAGE_LRU, + SCAN_PAGE_LOCK, + SCAN_PAGE_ANON, + SCAN_ANY_PROCESS, + SCAN_VMA_NULL, + SCAN_VMA_CHECK, + SCAN_ADDRESS_RANGE, + SCAN_SWAP_CACHE_PAGE, + SCAN_DEL_PAGE_LRU, + SCAN_ALLOC_HUGE_PAGE_FAIL, + SCAN_CGROUP_CHARGE_FAIL +}; + +#define CREATE_TRACE_POINTS +#include + /* * By default transparent hugepage support is disabled in order that avoid * to risk increase the memory footprint of applications without a guaranteed @@ -2198,26 +2225,33 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma, unsigned long address, pte_t *pte) { - struct page *page; + struct page *page = NULL; pte_t *_pte; - int none_or_zero = 0; + int none_or_zero = 0, result = 0; bool referenced = false, writable = false; + for (_pte = pte; _pte < pte+HPAGE_PMD_NR; _pte++, address += PAGE_SIZE) { pte_t pteval = *_pte; if (pte_none(pteval) || (pte_present(pteval) && is_zero_pfn(pte_pfn(pteval)))) { if (!userfaultfd_armed(vma) && - ++none_or_zero <= khugepaged_max_ptes_none) + ++none_or_zero <= khugepaged_max_ptes_none) { continue; - else + } else { + result = SCAN_EXCEED_NONE_PTE; goto out; + } } - if (!pte_present(pteval)) + if (!pte_present(pteval)) { + result = SCAN_PTE_NON_PRESENT; goto out; + } page = vm_normal_page(vma, address, pteval); - if (unlikely(!page)) + if (unlikely(!page)) { + result = SCAN_PAGE_NULL; goto out; + } VM_BUG_ON_PAGE(PageCompound(page), page); VM_BUG_ON_PAGE(!PageAnon(page), page); @@ -2229,8 +2263,10 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma, * is needed to serialize against split_huge_page * when invoked from the VM. */ - if (!trylock_page(page)) + if (!trylock_page(page)) { + result = SCAN_PAGE_LOCK; goto out; + } /* * cannot use mapcount: can't collapse if there's a gup pin. @@ -2239,6 +2275,7 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma, */ if (page_count(page) != 1 + !!PageSwapCache(page)) { unlock_page(page); + result = SCAN_PAGE_COUNT; goto out; } if (pte_write(pteval)) { @@ -2246,6 +2283,7 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma, } else { if (PageSwapCache(page) && !reuse_swap_page(page)) { unlock_page(page); + result = SCAN_SWAP_CACHE_PAGE; goto out; } /* @@ -2260,6 +2298,7 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma, */ if (isolate_lru_page(page)) { unlock_page(page); + result = SCAN_DEL_PAGE_LRU; goto out; } /* 0 stands for page_is_file_cache(page) == false */ @@ -2273,10 +2312,21 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma, mmu_notifier_test_young(vma->vm_mm, address)) referenced = true; } - if (likely(referenced && writable)) - return 1; + if (likely(writable)) { + if (likely(referenced)) { + result = SCAN_SUCCEED; + trace_mm_collapse_huge_page_isolate(page_to_pfn(page), none_or_zero, + referenced, writable, result); + return 1; + } + } else { + result = SCAN_PAGE_RO; + } + out: release_pte_pages(pte, _pte); + trace_mm_collapse_huge_page_isolate(page_to_pfn(page), none_or_zero, + referenced, writable, result); return 0; } @@ -2513,7 +2563,7 @@ static void collapse_huge_page(struct mm_struct *mm, pgtable_t pgtable; struct page *new_page; spinlock_t *pmd_ptl, *pte_ptl; - int isolated; + int isolated, result = 0; unsigned long hstart, hend; struct mem_cgroup *memcg; unsigned long mmun_start; /* For mmu_notifiers */ @@ -2528,12 +2578,15 @@ static void collapse_huge_page(struct mm_struct *mm, /* release the mmap_sem read lock. */ new_page = khugepaged_alloc_page(hpage, gfp, mm, address, node); - if (!new_page) - return; + if (!new_page) { + result = SCAN_ALLOC_HUGE_PAGE_FAIL; + goto out_nolock; + } - if (unlikely(mem_cgroup_try_charge(new_page, mm, - gfp, &memcg))) - return; + if (unlikely(mem_cgroup_try_charge(new_page, mm, gfp, &memcg))) { + result = SCAN_CGROUP_CHARGE_FAIL; + goto out_nolock; + } /* * Prevent all access to pagetables with the exception of @@ -2541,21 +2594,31 @@ static void collapse_huge_page(struct mm_struct *mm, * handled by the anon_vma lock + PG_lock. */ down_write(&mm->mmap_sem); - if (unlikely(khugepaged_test_exit(mm))) + if (unlikely(khugepaged_test_exit(mm))) { + result = SCAN_ANY_PROCESS; goto out; + } vma = find_vma(mm, address); - if (!vma) + if (!vma) { + result = SCAN_VMA_NULL; goto out; + } hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; hend = vma->vm_end & HPAGE_PMD_MASK; - if (address < hstart || address + HPAGE_PMD_SIZE > hend) + if (address < hstart || address + HPAGE_PMD_SIZE > hend) { + result = SCAN_ADDRESS_RANGE; goto out; - if (!hugepage_vma_check(vma)) + } + if (!hugepage_vma_check(vma)) { + result = SCAN_VMA_CHECK; goto out; + } pmd = mm_find_pmd(mm, address); - if (!pmd) + if (!pmd) { + result = SCAN_PMD_NULL; goto out; + } anon_vma_lock_write(vma->anon_vma); @@ -2592,6 +2655,7 @@ static void collapse_huge_page(struct mm_struct *mm, pmd_populate(mm, pmd, pmd_pgtable(_pmd)); spin_unlock(pmd_ptl); anon_vma_unlock_write(vma->anon_vma); + result = SCAN_FAIL; goto out; } @@ -2629,10 +2693,15 @@ static void collapse_huge_page(struct mm_struct *mm, *hpage = NULL; khugepaged_pages_collapsed++; + result = SCAN_SUCCEED; out_up_write: up_write(&mm->mmap_sem); + trace_mm_collapse_huge_page(mm, isolated, result); return; +out_nolock: + trace_mm_collapse_huge_page(mm, isolated, result); + return; out: mem_cgroup_cancel_charge(new_page, memcg); goto out_up_write; @@ -2645,8 +2714,8 @@ static int khugepaged_scan_pmd(struct mm_struct *mm, { pmd_t *pmd; pte_t *pte, *_pte; - int ret = 0, none_or_zero = 0; - struct page *page; + int ret = 0, none_or_zero = 0, result = 0; + struct page *page = NULL; unsigned long _address; spinlock_t *ptl; int node = NUMA_NO_NODE; @@ -2655,8 +2724,10 @@ static int khugepaged_scan_pmd(struct mm_struct *mm, VM_BUG_ON(address & ~HPAGE_PMD_MASK); pmd = mm_find_pmd(mm, address); - if (!pmd) + if (!pmd) { + result = SCAN_PMD_NULL; goto out; + } memset(khugepaged_node_load, 0, sizeof(khugepaged_node_load)); pte = pte_offset_map_lock(mm, pmd, address, &ptl); @@ -2665,19 +2736,25 @@ static int khugepaged_scan_pmd(struct mm_struct *mm, pte_t pteval = *_pte; if (pte_none(pteval) || is_zero_pfn(pte_pfn(pteval))) { if (!userfaultfd_armed(vma) && - ++none_or_zero <= khugepaged_max_ptes_none) + ++none_or_zero <= khugepaged_max_ptes_none) { continue; - else + } else { + result = SCAN_EXCEED_NONE_PTE; goto out_unmap; + } } - if (!pte_present(pteval)) + if (!pte_present(pteval)) { + result = SCAN_PTE_NON_PRESENT; goto out_unmap; + } if (pte_write(pteval)) writable = true; page = vm_normal_page(vma, _address, pteval); - if (unlikely(!page)) + if (unlikely(!page)) { + result = SCAN_PAGE_NULL; goto out_unmap; + } /* * Record which node the original page is from and save this * information to khugepaged_node_load[]. @@ -2685,26 +2762,49 @@ static int khugepaged_scan_pmd(struct mm_struct *mm, * hit record. */ node = page_to_nid(page); - if (khugepaged_scan_abort(node)) + if (khugepaged_scan_abort(node)) { + result = SCAN_SCAN_ABORT; goto out_unmap; + } khugepaged_node_load[node]++; VM_BUG_ON_PAGE(PageCompound(page), page); - if (!PageLRU(page) || PageLocked(page) || !PageAnon(page)) + if (!PageLRU(page)) { + result = SCAN_SCAN_ABORT; + goto out_unmap; + } + if (PageLocked(page)) { + result = SCAN_PAGE_LOCK; + goto out_unmap; + } + if (!PageAnon(page)) { + result = SCAN_PAGE_ANON; goto out_unmap; + } + /* * cannot use mapcount: can't collapse if there's a gup pin. * The page must only be referenced by the scanned process * and page swap cache. */ - if (page_count(page) != 1 + !!PageSwapCache(page)) + if (page_count(page) != 1 + !!PageSwapCache(page)) { + result = SCAN_PAGE_COUNT; goto out_unmap; + } if (pte_young(pteval) || page_is_young(page) || PageReferenced(page) || mmu_notifier_test_young(vma->vm_mm, address)) referenced = true; } - if (referenced && writable) - ret = 1; + if (writable) { + if (referenced) { + result = SCAN_SUCCEED; + ret = 1; + } else { + result = SCAN_NO_REFERENCED_PAGE; + } + } else { + result = SCAN_PAGE_RO; + } out_unmap: pte_unmap_unlock(pte, ptl); if (ret) { @@ -2713,6 +2813,8 @@ out_unmap: collapse_huge_page(mm, address, hpage, vma, node); } out: + trace_mm_khugepaged_scan_pmd(mm, page_to_pfn(page), writable, referenced, + none_or_zero, result); return ret; } -- GitLab From 9207f9d45b0ad071baa128e846d7e7ed85016df3 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Fri, 8 Jan 2016 15:21:46 +0300 Subject: [PATCH 2835/2855] net: preserve IP control block during GSO segmentation Skb_gso_segment() uses skb control block during segmentation. This patch adds 32-bytes room for previous control block which will be copied into all resulting segments. This patch fixes kernel crash during fragmenting forwarded packets. Fragmentation requires valid IP CB in skb for clearing ip options. Also patch removes custom save/restore in ovs code, now it's redundant. Signed-off-by: Konstantin Khlebnikov Link: http://lkml.kernel.org/r/CALYGNiP-0MZ-FExV2HutTvE9U-QQtkKSoE--KN=JQE5STYsjAA@mail.gmail.com Signed-off-by: David S. Miller --- include/linux/skbuff.h | 3 ++- net/core/dev.c | 5 +++++ net/ipv4/ip_output.c | 1 + net/openvswitch/datapath.c | 5 +---- net/xfrm/xfrm_output.c | 2 ++ 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 07f9ccd28654b..11f935c1a0904 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -3551,7 +3551,8 @@ struct skb_gso_cb { int encap_level; __u16 csum_start; }; -#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)(skb)->cb) +#define SKB_SGO_CB_OFFSET 32 +#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)((skb)->cb + SKB_SGO_CB_OFFSET)) static inline int skb_tnl_header_len(const struct sk_buff *inner_skb) { diff --git a/net/core/dev.c b/net/core/dev.c index 0ca95d5d7af0a..cc9e3652cf93a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2695,6 +2695,8 @@ static inline bool skb_needs_check(struct sk_buff *skb, bool tx_path) * * It may return NULL if the skb requires no segmentation. This is * only possible when GSO is used for verifying header integrity. + * + * Segmentation preserves SKB_SGO_CB_OFFSET bytes of previous skb cb. */ struct sk_buff *__skb_gso_segment(struct sk_buff *skb, netdev_features_t features, bool tx_path) @@ -2709,6 +2711,9 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb, return ERR_PTR(err); } + BUILD_BUG_ON(SKB_SGO_CB_OFFSET + + sizeof(*SKB_GSO_CB(skb)) > sizeof(skb->cb)); + SKB_GSO_CB(skb)->mac_offset = skb_headroom(skb); SKB_GSO_CB(skb)->encap_level = 0; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 512a44778cf2f..64878efa045c1 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -239,6 +239,7 @@ static int ip_finish_output_gso(struct net *net, struct sock *sk, * from host network stack. */ features = netif_skb_features(skb); + BUILD_BUG_ON(sizeof(*IPCB(skb)) > SKB_SGO_CB_OFFSET); segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK); if (IS_ERR_OR_NULL(segs)) { kfree_skb(skb); diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 91a8b004dc510..deadfdab1bc38 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -336,12 +336,10 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb, unsigned short gso_type = skb_shinfo(skb)->gso_type; struct sw_flow_key later_key; struct sk_buff *segs, *nskb; - struct ovs_skb_cb ovs_cb; int err; - ovs_cb = *OVS_CB(skb); + BUILD_BUG_ON(sizeof(*OVS_CB(skb)) > SKB_SGO_CB_OFFSET); segs = __skb_gso_segment(skb, NETIF_F_SG, false); - *OVS_CB(skb) = ovs_cb; if (IS_ERR(segs)) return PTR_ERR(segs); if (segs == NULL) @@ -359,7 +357,6 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb, /* Queue all of the segments. */ skb = segs; do { - *OVS_CB(skb) = ovs_cb; if (gso_type & SKB_GSO_UDP && skb != segs) key = &later_key; diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index cc3676eb62397..ff4a91fcab9fd 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c @@ -167,6 +167,8 @@ static int xfrm_output_gso(struct net *net, struct sock *sk, struct sk_buff *skb { struct sk_buff *segs; + BUILD_BUG_ON(sizeof(*IPCB(skb)) > SKB_SGO_CB_OFFSET); + BUILD_BUG_ON(sizeof(*IP6CB(skb)) > SKB_SGO_CB_OFFSET); segs = skb_gso_segment(skb, 0); kfree_skb(skb); if (IS_ERR(segs)) -- GitLab From b70ce2ab41cb67ab3d661eda078f7c4029bbca95 Mon Sep 17 00:00:00 2001 From: yankejian Date: Wed, 13 Jan 2016 15:09:58 +0800 Subject: [PATCH 2836/2855] dts: hisi: fixes no syscon fault when init mdio When linux start up, we get the log below: "Hi-HNS_MDIO 803c0000.mdio: no syscon hisilicon,peri-c-subctrl mdio_bus mdio@803c0000: mdio sys ctl reg has not maped" The source code about the subctrl is dealt syscon, but dts doesn't. It cause such fault, so this patch adds the syscon info on dts files to fixes it. Signed-off-by: Kejian Yan Acked-by: Rob Herring Signed-off-by: David S. Miller --- .../bindings/arm/hisilicon/hisilicon.txt | 16 ++++++++++++++++ arch/arm64/boot/dts/hisilicon/hip05.dtsi | 5 +++++ arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi | 4 ++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt index 6ac7c000af225..e3ccab114006d 100644 --- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt @@ -187,6 +187,22 @@ Example: reg = <0xb0000000 0x10000>; }; +Hisilicon HiP05 PERISUB system controller + +Required properties: +- compatible : "hisilicon,hip05-perisubc", "syscon"; +- reg : Register address and size + +The HiP05 PERISUB system controller is shared by peripheral controllers in +HiP05 Soc to implement some basic configurations. The peripheral +controllers include mdio, ddr, iic, uart, timer and so on. + +Example: + /* for HiP05 perisub-ctrl-c system */ + peri_c_subctrl: syscon@80000000 { + compatible = "hisilicon,hip05-perisubc", "syscon"; + reg = <0x0 0x80000000 0x0 0x10000>; + }; ----------------------------------------------------------------------- Hisilicon CPU controller diff --git a/arch/arm64/boot/dts/hisilicon/hip05.dtsi b/arch/arm64/boot/dts/hisilicon/hip05.dtsi index 4ff16d016e346..c1ea999c7be14 100644 --- a/arch/arm64/boot/dts/hisilicon/hip05.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hip05.dtsi @@ -246,6 +246,11 @@ clock-frequency = <200000000>; }; + peri_c_subctrl: syscon@80000000 { + compatible = "hisilicon,hip05-perisubc", "syscon"; + reg = < 0x0 0x80000000 0x0 0x10000>; + }; + uart0: uart@80300000 { compatible = "snps,dw-apb-uart"; reg = <0x0 0x80300000 0x0 0x10000>; diff --git a/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi b/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi index 606dd5a05c2df..da7b6e6132575 100644 --- a/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi @@ -10,8 +10,8 @@ soc0: soc@000000000 { #address-cells = <1>; #size-cells = <0>; compatible = "hisilicon,hns-mdio"; - reg = <0x0 0x803c0000 0x0 0x10000 - 0x0 0x80000000 0x0 0x10000>; + reg = <0x0 0x803c0000 0x0 0x10000>; + subctrl-vbase = <&peri_c_subctrl>; soc0_phy0: ethernet-phy@0 { reg = <0x0>; -- GitLab From 28052e75834a84b006893735debedb8ee6b6cbc0 Mon Sep 17 00:00:00 2001 From: yankejian Date: Wed, 13 Jan 2016 15:09:59 +0800 Subject: [PATCH 2837/2855] net: hns: fixes no syscon error when init mdio As dtsi files use the normal naming conventions using '-' instead of '_' inside of property names, the driver needs to update the phandle name strings of the of_parse_phandle func. Signed-off-by: Kejian Yan Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hns_mdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/hisilicon/hns_mdio.c b/drivers/net/ethernet/hisilicon/hns_mdio.c index 58c96c412fe89..765ddb3dcd1a0 100644 --- a/drivers/net/ethernet/hisilicon/hns_mdio.c +++ b/drivers/net/ethernet/hisilicon/hns_mdio.c @@ -458,7 +458,7 @@ static int hns_mdio_probe(struct platform_device *pdev) } mdio_dev->subctrl_vbase = - syscon_node_to_regmap(of_parse_phandle(np, "subctrl_vbase", 0)); + syscon_node_to_regmap(of_parse_phandle(np, "subctrl-vbase", 0)); if (IS_ERR(mdio_dev->subctrl_vbase)) { dev_warn(&pdev->dev, "no syscon hisilicon,peri-c-subctrl\n"); mdio_dev->subctrl_vbase = NULL; -- GitLab From 3d5fe03a3ea013060ebba2a811aeb0f23f56aefa Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Thu, 14 Jan 2016 15:22:26 -0800 Subject: [PATCH 2838/2855] zram/zcomp: use GFP_NOIO to allocate streams We can end up allocating a new compression stream with GFP_KERNEL from within the IO path, which may result is nested (recursive) IO operations. That can introduce problems if the IO path in question is a reclaimer, holding some locks that will deadlock nested IOs. Allocate streams and working memory using GFP_NOIO flag, forbidding recursive IO and FS operations. An example: inconsistent {IN-RECLAIM_FS-W} -> {RECLAIM_FS-ON-W} usage. git/20158 [HC0[0]:SC0[0]:HE1:SE1] takes: (jbd2_handle){+.+.?.}, at: start_this_handle+0x4ca/0x555 {IN-RECLAIM_FS-W} state was registered at: __lock_acquire+0x8da/0x117b lock_acquire+0x10c/0x1a7 start_this_handle+0x52d/0x555 jbd2__journal_start+0xb4/0x237 __ext4_journal_start_sb+0x108/0x17e ext4_dirty_inode+0x32/0x61 __mark_inode_dirty+0x16b/0x60c iput+0x11e/0x274 __dentry_kill+0x148/0x1b8 shrink_dentry_list+0x274/0x44a prune_dcache_sb+0x4a/0x55 super_cache_scan+0xfc/0x176 shrink_slab.part.14.constprop.25+0x2a2/0x4d3 shrink_zone+0x74/0x140 kswapd+0x6b7/0x930 kthread+0x107/0x10f ret_from_fork+0x3f/0x70 irq event stamp: 138297 hardirqs last enabled at (138297): debug_check_no_locks_freed+0x113/0x12f hardirqs last disabled at (138296): debug_check_no_locks_freed+0x33/0x12f softirqs last enabled at (137818): __do_softirq+0x2d3/0x3e9 softirqs last disabled at (137813): irq_exit+0x41/0x95 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(jbd2_handle); lock(jbd2_handle); *** DEADLOCK *** 5 locks held by git/20158: #0: (sb_writers#7){.+.+.+}, at: [] mnt_want_write+0x24/0x4b #1: (&type->i_mutex_dir_key#2/1){+.+.+.}, at: [] lock_rename+0xd9/0xe3 #2: (&sb->s_type->i_mutex_key#11){+.+.+.}, at: [] lock_two_nondirectories+0x3f/0x6b #3: (&sb->s_type->i_mutex_key#11/4){+.+.+.}, at: [] lock_two_nondirectories+0x66/0x6b #4: (jbd2_handle){+.+.?.}, at: [] start_this_handle+0x4ca/0x555 stack backtrace: CPU: 2 PID: 20158 Comm: git Not tainted 4.1.0-rc7-next-20150615-dbg-00016-g8bdf555-dirty #211 Call Trace: dump_stack+0x4c/0x6e mark_lock+0x384/0x56d mark_held_locks+0x5f/0x76 lockdep_trace_alloc+0xb2/0xb5 kmem_cache_alloc_trace+0x32/0x1e2 zcomp_strm_alloc+0x25/0x73 [zram] zcomp_strm_multi_find+0xe7/0x173 [zram] zcomp_strm_find+0xc/0xe [zram] zram_bvec_rw+0x2ca/0x7e0 [zram] zram_make_request+0x1fa/0x301 [zram] generic_make_request+0x9c/0xdb submit_bio+0xf7/0x120 ext4_io_submit+0x2e/0x43 ext4_bio_write_page+0x1b7/0x300 mpage_submit_page+0x60/0x77 mpage_map_and_submit_buffers+0x10f/0x21d ext4_writepages+0xc8c/0xe1b do_writepages+0x23/0x2c __filemap_fdatawrite_range+0x84/0x8b filemap_flush+0x1c/0x1e ext4_alloc_da_blocks+0xb8/0x117 ext4_rename+0x132/0x6dc ? mark_held_locks+0x5f/0x76 ext4_rename2+0x29/0x2b vfs_rename+0x540/0x636 SyS_renameat2+0x359/0x44d SyS_rename+0x1e/0x20 entry_SYSCALL_64_fastpath+0x12/0x6f [minchan@kernel.org: add stable mark] Signed-off-by: Sergey Senozhatsky Acked-by: Minchan Kim Cc: Kyeongdon Kim Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/zram/zcomp.c | 4 ++-- drivers/block/zram/zcomp_lz4.c | 2 +- drivers/block/zram/zcomp_lzo.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c index 5cb13ca3a3aca..c53617752b93c 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c @@ -76,7 +76,7 @@ static void zcomp_strm_free(struct zcomp *comp, struct zcomp_strm *zstrm) */ static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp) { - struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_KERNEL); + struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_NOIO); if (!zstrm) return NULL; @@ -85,7 +85,7 @@ static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp) * allocate 2 pages. 1 for compressed data, plus 1 extra for the * case when compressed size is larger than the original one */ - zstrm->buffer = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1); + zstrm->buffer = (void *)__get_free_pages(GFP_NOIO | __GFP_ZERO, 1); if (!zstrm->private || !zstrm->buffer) { zcomp_strm_free(comp, zstrm); zstrm = NULL; diff --git a/drivers/block/zram/zcomp_lz4.c b/drivers/block/zram/zcomp_lz4.c index f2afb7e988c37..ee44b51130a45 100644 --- a/drivers/block/zram/zcomp_lz4.c +++ b/drivers/block/zram/zcomp_lz4.c @@ -15,7 +15,7 @@ static void *zcomp_lz4_create(void) { - return kzalloc(LZ4_MEM_COMPRESS, GFP_KERNEL); + return kzalloc(LZ4_MEM_COMPRESS, GFP_NOIO); } static void zcomp_lz4_destroy(void *private) diff --git a/drivers/block/zram/zcomp_lzo.c b/drivers/block/zram/zcomp_lzo.c index da1bc47d588e9..683ce049e0704 100644 --- a/drivers/block/zram/zcomp_lzo.c +++ b/drivers/block/zram/zcomp_lzo.c @@ -15,7 +15,7 @@ static void *lzo_create(void) { - return kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); + return kzalloc(LZO1X_MEM_COMPRESS, GFP_NOIO); } static void lzo_destroy(void *private) -- GitLab From d913897abace843bba20249f3190167f7895e9c3 Mon Sep 17 00:00:00 2001 From: Kyeongdon Kim Date: Thu, 14 Jan 2016 15:22:29 -0800 Subject: [PATCH 2839/2855] zram: try vmalloc() after kmalloc() When we're using LZ4 multi compression streams for zram swap, we found out page allocation failure message in system running test. That was not only once, but a few(2 - 5 times per test). Also, some failure cases were continually occurring to try allocation order 3. In order to make parallel compression private data, we should call kzalloc() with order 2/3 in runtime(lzo/lz4). But if there is no order 2/3 size memory to allocate in that time, page allocation fails. This patch makes to use vmalloc() as fallback of kmalloc(), this prevents page alloc failure warning. After using this, we never found warning message in running test, also It could reduce process startup latency about 60-120ms in each case. For reference a call trace : Binder_1: page allocation failure: order:3, mode:0x10c0d0 CPU: 0 PID: 424 Comm: Binder_1 Tainted: GW 3.10.49-perf-g991d02b-dirty #20 Call trace: dump_backtrace+0x0/0x270 show_stack+0x10/0x1c dump_stack+0x1c/0x28 warn_alloc_failed+0xfc/0x11c __alloc_pages_nodemask+0x724/0x7f0 __get_free_pages+0x14/0x5c kmalloc_order_trace+0x38/0xd8 zcomp_lz4_create+0x2c/0x38 zcomp_strm_alloc+0x34/0x78 zcomp_strm_multi_find+0x124/0x1ec zcomp_strm_find+0xc/0x18 zram_bvec_rw+0x2fc/0x780 zram_make_request+0x25c/0x2d4 generic_make_request+0x80/0xbc submit_bio+0xa4/0x15c __swap_writepage+0x218/0x230 swap_writepage+0x3c/0x4c shrink_page_list+0x51c/0x8d0 shrink_inactive_list+0x3f8/0x60c shrink_lruvec+0x33c/0x4cc shrink_zone+0x3c/0x100 try_to_free_pages+0x2b8/0x54c __alloc_pages_nodemask+0x514/0x7f0 __get_free_pages+0x14/0x5c proc_info_read+0x50/0xe4 vfs_read+0xa0/0x12c SyS_read+0x44/0x74 DMA: 3397*4kB (MC) 26*8kB (RC) 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 13796kB [minchan@kernel.org: change vmalloc gfp and adding comment about gfp] [sergey.senozhatsky@gmail.com: tweak comments and styles] Signed-off-by: Kyeongdon Kim Signed-off-by: Minchan Kim Acked-by: Sergey Senozhatsky Sergey Senozhatsky Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/zram/zcomp_lz4.c | 23 +++++++++++++++++++++-- drivers/block/zram/zcomp_lzo.c | 23 +++++++++++++++++++++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/drivers/block/zram/zcomp_lz4.c b/drivers/block/zram/zcomp_lz4.c index ee44b51130a45..dd6083124276f 100644 --- a/drivers/block/zram/zcomp_lz4.c +++ b/drivers/block/zram/zcomp_lz4.c @@ -10,17 +10,36 @@ #include #include #include +#include +#include #include "zcomp_lz4.h" static void *zcomp_lz4_create(void) { - return kzalloc(LZ4_MEM_COMPRESS, GFP_NOIO); + void *ret; + + /* + * This function can be called in swapout/fs write path + * so we can't use GFP_FS|IO. And it assumes we already + * have at least one stream in zram initialization so we + * don't do best effort to allocate more stream in here. + * A default stream will work well without further multiple + * streams. That's why we use NORETRY | NOWARN. + */ + ret = kzalloc(LZ4_MEM_COMPRESS, GFP_NOIO | __GFP_NORETRY | + __GFP_NOWARN); + if (!ret) + ret = __vmalloc(LZ4_MEM_COMPRESS, + GFP_NOIO | __GFP_NORETRY | __GFP_NOWARN | + __GFP_ZERO | __GFP_HIGHMEM, + PAGE_KERNEL); + return ret; } static void zcomp_lz4_destroy(void *private) { - kfree(private); + kvfree(private); } static int zcomp_lz4_compress(const unsigned char *src, unsigned char *dst, diff --git a/drivers/block/zram/zcomp_lzo.c b/drivers/block/zram/zcomp_lzo.c index 683ce049e0704..edc549920fa06 100644 --- a/drivers/block/zram/zcomp_lzo.c +++ b/drivers/block/zram/zcomp_lzo.c @@ -10,17 +10,36 @@ #include #include #include +#include +#include #include "zcomp_lzo.h" static void *lzo_create(void) { - return kzalloc(LZO1X_MEM_COMPRESS, GFP_NOIO); + void *ret; + + /* + * This function can be called in swapout/fs write path + * so we can't use GFP_FS|IO. And it assumes we already + * have at least one stream in zram initialization so we + * don't do best effort to allocate more stream in here. + * A default stream will work well without further multiple + * streams. That's why we use NORETRY | NOWARN. + */ + ret = kzalloc(LZO1X_MEM_COMPRESS, GFP_NOIO | __GFP_NORETRY | + __GFP_NOWARN); + if (!ret) + ret = __vmalloc(LZO1X_MEM_COMPRESS, + GFP_NOIO | __GFP_NORETRY | __GFP_NOWARN | + __GFP_ZERO | __GFP_HIGHMEM, + PAGE_KERNEL); + return ret; } static void lzo_destroy(void *private) { - kfree(private); + kvfree(private); } static int lzo_compress(const unsigned char *src, unsigned char *dst, -- GitLab From 75d8947a36d0c9aedd69118d1f14bf424005c7c2 Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Thu, 14 Jan 2016 15:22:32 -0800 Subject: [PATCH 2840/2855] zram: pass gfp from zcomp frontend to backend Each zcomp backend uses own gfp flag but it's pointless because the context they could be called is driven by upper layer(ie, zcomp frontend). As well, zcomp frondend could call them in different context. One context(ie, zram init part) is it should be better to make sure successful allocation other context(ie, further stream allocation part for accelarating I/O speed) is just optional so let's pass gfp down from driver (ie, zcomp frontend) like normal MM convention. [sergey.senozhatsky@gmail.com: add missing __vmalloc zero and highmem gfps] Signed-off-by: Minchan Kim Signed-off-by: Sergey Senozhatsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/zram/zcomp.c | 24 ++++++++++++++++-------- drivers/block/zram/zcomp.h | 2 +- drivers/block/zram/zcomp_lz4.c | 16 +++------------- drivers/block/zram/zcomp_lzo.c | 16 +++------------- 4 files changed, 23 insertions(+), 35 deletions(-) diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c index c53617752b93c..3ef42e563bb5d 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c @@ -74,18 +74,18 @@ static void zcomp_strm_free(struct zcomp *comp, struct zcomp_strm *zstrm) * allocate new zcomp_strm structure with ->private initialized by * backend, return NULL on error */ -static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp) +static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp, gfp_t flags) { - struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_NOIO); + struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), flags); if (!zstrm) return NULL; - zstrm->private = comp->backend->create(); + zstrm->private = comp->backend->create(flags); /* * allocate 2 pages. 1 for compressed data, plus 1 extra for the * case when compressed size is larger than the original one */ - zstrm->buffer = (void *)__get_free_pages(GFP_NOIO | __GFP_ZERO, 1); + zstrm->buffer = (void *)__get_free_pages(flags | __GFP_ZERO, 1); if (!zstrm->private || !zstrm->buffer) { zcomp_strm_free(comp, zstrm); zstrm = NULL; @@ -120,8 +120,16 @@ static struct zcomp_strm *zcomp_strm_multi_find(struct zcomp *comp) /* allocate new zstrm stream */ zs->avail_strm++; spin_unlock(&zs->strm_lock); - - zstrm = zcomp_strm_alloc(comp); + /* + * This function can be called in swapout/fs write path + * so we can't use GFP_FS|IO. And it assumes we already + * have at least one stream in zram initialization so we + * don't do best effort to allocate more stream in here. + * A default stream will work well without further multiple + * streams. That's why we use NORETRY | NOWARN. + */ + zstrm = zcomp_strm_alloc(comp, GFP_NOIO | __GFP_NORETRY | + __GFP_NOWARN); if (!zstrm) { spin_lock(&zs->strm_lock); zs->avail_strm--; @@ -209,7 +217,7 @@ static int zcomp_strm_multi_create(struct zcomp *comp, int max_strm) zs->max_strm = max_strm; zs->avail_strm = 1; - zstrm = zcomp_strm_alloc(comp); + zstrm = zcomp_strm_alloc(comp, GFP_KERNEL); if (!zstrm) { kfree(zs); return -ENOMEM; @@ -259,7 +267,7 @@ static int zcomp_strm_single_create(struct zcomp *comp) comp->stream = zs; mutex_init(&zs->strm_lock); - zs->zstrm = zcomp_strm_alloc(comp); + zs->zstrm = zcomp_strm_alloc(comp, GFP_KERNEL); if (!zs->zstrm) { kfree(zs); return -ENOMEM; diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h index 46e2b9f8f1f0e..b7d2a4bcae540 100644 --- a/drivers/block/zram/zcomp.h +++ b/drivers/block/zram/zcomp.h @@ -33,7 +33,7 @@ struct zcomp_backend { int (*decompress)(const unsigned char *src, size_t src_len, unsigned char *dst); - void *(*create)(void); + void *(*create)(gfp_t flags); void (*destroy)(void *private); const char *name; diff --git a/drivers/block/zram/zcomp_lz4.c b/drivers/block/zram/zcomp_lz4.c index dd6083124276f..dc2338d5258c1 100644 --- a/drivers/block/zram/zcomp_lz4.c +++ b/drivers/block/zram/zcomp_lz4.c @@ -15,24 +15,14 @@ #include "zcomp_lz4.h" -static void *zcomp_lz4_create(void) +static void *zcomp_lz4_create(gfp_t flags) { void *ret; - /* - * This function can be called in swapout/fs write path - * so we can't use GFP_FS|IO. And it assumes we already - * have at least one stream in zram initialization so we - * don't do best effort to allocate more stream in here. - * A default stream will work well without further multiple - * streams. That's why we use NORETRY | NOWARN. - */ - ret = kzalloc(LZ4_MEM_COMPRESS, GFP_NOIO | __GFP_NORETRY | - __GFP_NOWARN); + ret = kzalloc(LZ4_MEM_COMPRESS, flags); if (!ret) ret = __vmalloc(LZ4_MEM_COMPRESS, - GFP_NOIO | __GFP_NORETRY | __GFP_NOWARN | - __GFP_ZERO | __GFP_HIGHMEM, + flags | __GFP_ZERO | __GFP_HIGHMEM, PAGE_KERNEL); return ret; } diff --git a/drivers/block/zram/zcomp_lzo.c b/drivers/block/zram/zcomp_lzo.c index edc549920fa06..0ab6fce8abe47 100644 --- a/drivers/block/zram/zcomp_lzo.c +++ b/drivers/block/zram/zcomp_lzo.c @@ -15,24 +15,14 @@ #include "zcomp_lzo.h" -static void *lzo_create(void) +static void *lzo_create(gfp_t flags) { void *ret; - /* - * This function can be called in swapout/fs write path - * so we can't use GFP_FS|IO. And it assumes we already - * have at least one stream in zram initialization so we - * don't do best effort to allocate more stream in here. - * A default stream will work well without further multiple - * streams. That's why we use NORETRY | NOWARN. - */ - ret = kzalloc(LZO1X_MEM_COMPRESS, GFP_NOIO | __GFP_NORETRY | - __GFP_NOWARN); + ret = kzalloc(LZO1X_MEM_COMPRESS, flags); if (!ret) ret = __vmalloc(LZO1X_MEM_COMPRESS, - GFP_NOIO | __GFP_NORETRY | __GFP_NOWARN | - __GFP_ZERO | __GFP_HIGHMEM, + flags | __GFP_ZERO | __GFP_HIGHMEM, PAGE_KERNEL); return ret; } -- GitLab From e02d238c9852a91b30da9ea32ce36d1416cdc683 Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Thu, 14 Jan 2016 15:22:35 -0800 Subject: [PATCH 2841/2855] zram/zcomp: do not zero out zcomp private pages Do not __GFP_ZERO allocated zcomp ->private pages. We keep allocated streams around and use them for read/write requests, so we supply a zeroed out ->private to compression algorithm as a scratch buffer only once -- the first time we use that stream. For the rest of IO requests served by this stream ->private usually contains some temporarily data from the previous requests. Signed-off-by: Sergey Senozhatsky Acked-by: Minchan Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/zram/zcomp_lz4.c | 4 ++-- drivers/block/zram/zcomp_lzo.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/block/zram/zcomp_lz4.c b/drivers/block/zram/zcomp_lz4.c index dc2338d5258c1..0110086accba8 100644 --- a/drivers/block/zram/zcomp_lz4.c +++ b/drivers/block/zram/zcomp_lz4.c @@ -19,10 +19,10 @@ static void *zcomp_lz4_create(gfp_t flags) { void *ret; - ret = kzalloc(LZ4_MEM_COMPRESS, flags); + ret = kmalloc(LZ4_MEM_COMPRESS, flags); if (!ret) ret = __vmalloc(LZ4_MEM_COMPRESS, - flags | __GFP_ZERO | __GFP_HIGHMEM, + flags | __GFP_HIGHMEM, PAGE_KERNEL); return ret; } diff --git a/drivers/block/zram/zcomp_lzo.c b/drivers/block/zram/zcomp_lzo.c index 0ab6fce8abe47..ed7a1f0549ecf 100644 --- a/drivers/block/zram/zcomp_lzo.c +++ b/drivers/block/zram/zcomp_lzo.c @@ -19,10 +19,10 @@ static void *lzo_create(gfp_t flags) { void *ret; - ret = kzalloc(LZO1X_MEM_COMPRESS, flags); + ret = kmalloc(LZO1X_MEM_COMPRESS, flags); if (!ret) ret = __vmalloc(LZO1X_MEM_COMPRESS, - flags | __GFP_ZERO | __GFP_HIGHMEM, + flags | __GFP_HIGHMEM, PAGE_KERNEL); return ret; } -- GitLab From f58fb5e7f0ab05c9083869c1ec27854af2afc7b7 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 14 Jan 2016 15:22:38 -0800 Subject: [PATCH 2842/2855] mm/zbud.c: use list_last_entry() instead of list_tail_entry() list_last_entry*( has been defined in list.h, so replace list_tail_entry() with it. Signed-off-by: Geliang Tang Cc: Seth Jennings Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/zbud.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/mm/zbud.c b/mm/zbud.c index d8a181fd779bf..b42322e50f630 100644 --- a/mm/zbud.c +++ b/mm/zbud.c @@ -463,9 +463,6 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle) spin_unlock(&pool->lock); } -#define list_tail_entry(ptr, type, member) \ - list_entry((ptr)->prev, type, member) - /** * zbud_reclaim_page() - evicts allocations from a pool page and frees it * @pool: pool from which a page will attempt to be evicted @@ -514,7 +511,7 @@ int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries) return -EINVAL; } for (i = 0; i < retries; i++) { - zhdr = list_tail_entry(&pool->lru, struct zbud_header, lru); + zhdr = list_last_entry(&pool->lru, struct zbud_header, lru); list_del(&zhdr->lru); list_del(&zhdr->buddy); /* Protect zbud page against free */ -- GitLab From 7dfa4612204b511c934ca2a0e4f306f9981bd9aa Mon Sep 17 00:00:00 2001 From: Weijie Yang Date: Thu, 14 Jan 2016 15:22:40 -0800 Subject: [PATCH 2843/2855] zsmalloc: reorganize struct size_class to pack 4 bytes hole Reoder the pages_per_zspage field in struct size_class which can eliminate the 4 bytes hole between it and stats field. Signed-off-by: Weijie Yang Reviewed-by: Sergey Senozhatsky Cc: Minchan Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/zsmalloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index 9f15bdd9163c2..e7414cec220b3 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c @@ -213,10 +213,10 @@ struct size_class { int size; unsigned int index; - /* Number of PAGE_SIZE sized pages to combine to form a 'zspage' */ - int pages_per_zspage; struct zs_size_stat stats; + /* Number of PAGE_SIZE sized pages to combine to form a 'zspage' */ + int pages_per_zspage; /* huge object: pages_per_zspage == 1 && maxobj_per_zspage == 1 */ bool huge; }; -- GitLab From 65a5124a71e85c35fa8d047a471950325855dccf Mon Sep 17 00:00:00 2001 From: Xin Long Date: Thu, 14 Jan 2016 13:49:34 +0800 Subject: [PATCH 2844/2855] sctp: support to lookup with ep+paddr in transport rhashtable Now, when we sendmsg, we translate the ep to laddr by selecting the first element of the list, and then do a lookup for a transport. But sctp_hash_cmp() will compare it against asoc addr_list, which may be a subset of ep addr_list, meaning that this chosen laddr may not be there, and thus making it impossible to find the transport. So we fix it by using ep + paddr to lookup transports in hashtable. In sctp_hash_cmp, if .ep is set, we will check if this ep == asoc->ep, or we will do the laddr check. Fixes: d6c0256a60e6 ("sctp: add the rhashtable apis for sctp global transport hashtable") Signed-off-by: Xin Long Acked-by: Marcelo Ricardo Leitner Reported-by: Vlad Yasevich Signed-off-by: David S. Miller --- net/sctp/input.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/net/sctp/input.c b/net/sctp/input.c index d9a6e66c5c8a5..b9a536b52da23 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -784,6 +784,7 @@ hit: /* rhashtable for transport */ struct sctp_hash_cmp_arg { + const struct sctp_endpoint *ep; const union sctp_addr *laddr; const union sctp_addr *paddr; const struct net *net; @@ -797,15 +798,20 @@ static inline int sctp_hash_cmp(struct rhashtable_compare_arg *arg, struct sctp_association *asoc = t->asoc; const struct net *net = x->net; - if (x->laddr->v4.sin_port != htons(asoc->base.bind_addr.port)) - return 1; if (!sctp_cmp_addr_exact(&t->ipaddr, x->paddr)) return 1; if (!net_eq(sock_net(asoc->base.sk), net)) return 1; - if (!sctp_bind_addr_match(&asoc->base.bind_addr, - x->laddr, sctp_sk(asoc->base.sk))) - return 1; + if (x->ep) { + if (x->ep != asoc->ep) + return 1; + } else { + if (x->laddr->v4.sin_port != htons(asoc->base.bind_addr.port)) + return 1; + if (!sctp_bind_addr_match(&asoc->base.bind_addr, + x->laddr, sctp_sk(asoc->base.sk))) + return 1; + } return 0; } @@ -832,9 +838,11 @@ static inline u32 sctp_hash_key(const void *data, u32 len, u32 seed) const struct sctp_hash_cmp_arg *x = data; const union sctp_addr *paddr = x->paddr; const struct net *net = x->net; - u16 lport = x->laddr->v4.sin_port; + u16 lport; u32 addr; + lport = x->ep ? htons(x->ep->base.bind_addr.port) : + x->laddr->v4.sin_port; if (paddr->sa.sa_family == AF_INET6) addr = jhash(&paddr->v6.sin6_addr, 16, seed); else @@ -864,12 +872,9 @@ void sctp_transport_hashtable_destroy(void) void sctp_hash_transport(struct sctp_transport *t) { - struct sctp_sockaddr_entry *addr; struct sctp_hash_cmp_arg arg; - addr = list_entry(t->asoc->base.bind_addr.address_list.next, - struct sctp_sockaddr_entry, list); - arg.laddr = &addr->a; + arg.ep = t->asoc->ep; arg.paddr = &t->ipaddr; arg.net = sock_net(t->asoc->base.sk); @@ -891,6 +896,7 @@ struct sctp_transport *sctp_addrs_lookup_transport( const union sctp_addr *paddr) { struct sctp_hash_cmp_arg arg = { + .ep = NULL, .laddr = laddr, .paddr = paddr, .net = net, @@ -904,13 +910,15 @@ struct sctp_transport *sctp_epaddr_lookup_transport( const struct sctp_endpoint *ep, const union sctp_addr *paddr) { - struct sctp_sockaddr_entry *addr; struct net *net = sock_net(ep->base.sk); + struct sctp_hash_cmp_arg arg = { + .ep = ep, + .paddr = paddr, + .net = net, + }; - addr = list_entry(ep->base.bind_addr.address_list.next, - struct sctp_sockaddr_entry, list); - - return sctp_addrs_lookup_transport(net, &addr->a, paddr); + return rhashtable_lookup_fast(&sctp_transport_hashtable, &arg, + sctp_hash_params); } /* Look up an association. */ -- GitLab From 244683749e3c632ab45655098259d5514c179c8a Mon Sep 17 00:00:00 2001 From: Nathan Sullivan Date: Thu, 14 Jan 2016 13:27:27 -0600 Subject: [PATCH 2845/2855] net: macb: clear interrupts when disabling them Disabling interrupts with the IDR register does not stop the macb hardware from asserting its interrupt line if there are interrupts pending. Always clear the interrupts using ISR, and be sure to write it on hardware that is not read-to-clear, like Zynq. Not doing so will cause interrupts when the driver doesn't expect them. Signed-off-by: Nathan Sullivan Acked-by: Nicolas Ferre Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/macb.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index c56347536f6b9..9d9984a87d422 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -1040,6 +1040,8 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) /* close possible race with dev_close */ if (unlikely(!netif_running(dev))) { queue_writel(queue, IDR, -1); + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + queue_writel(queue, ISR, -1); break; } @@ -1561,6 +1563,8 @@ static void macb_reset_hw(struct macb *bp) for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { queue_writel(queue, IDR, -1); queue_readl(queue, ISR); + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + queue_writel(queue, ISR, -1); } } -- GitLab From 113c74d83eef870e43a0d9279044e9d5435f0d07 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Thu, 14 Jan 2016 21:57:18 +0100 Subject: [PATCH 2846/2855] net: phy: turn carrier off on phy attach The operstate of a networking device initially IF_OPER_UNKNOWN aka "unknown", updated on carrier state changes (with carrier state being on by default). This means it will stay unknown unless the carrier state goes to off at some point, which is not the case if the phy is already up/connected at startup. Explicitly turn off the carrier on phy attach, leaving the phy state machine to turn the carrier on when it has done the initial negotiation. Signed-off-by: Sjoerd Simons Signed-off-by: David S. Miller --- drivers/net/phy/phy_device.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 903737adfc019..bad3f005faee4 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -901,6 +901,11 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, phydev->state = PHY_READY; + /* Initial carrier state is off as the phy is about to be + * (re)initialized. + */ + netif_carrier_off(phydev->attached_dev); + /* Do initial configuration here, now that * we have certain key parameters * (dev_flags and interface) -- GitLab From 34ae6a1aa0540f0f781dd265366036355fdc8930 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 15 Jan 2016 04:56:56 -0800 Subject: [PATCH 2847/2855] ipv6: update skb->csum when CE mark is propagated When a tunnel decapsulates the outer header, it has to comply with RFC 6080 and eventually propagate CE mark into inner header. It turns out IP6_ECN_set_ce() does not correctly update skb->csum for CHECKSUM_COMPLETE packets, triggering infamous "hw csum failure" messages and stack traces. Signed-off-by: Eric Dumazet Acked-by: Herbert Xu Signed-off-by: David S. Miller --- include/net/inet_ecn.h | 19 ++++++++++++++++--- net/ipv6/xfrm6_mode_tunnel.c | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h index 84b20835b736c..0dc0a51da38fa 100644 --- a/include/net/inet_ecn.h +++ b/include/net/inet_ecn.h @@ -111,11 +111,24 @@ static inline void ipv4_copy_dscp(unsigned int dscp, struct iphdr *inner) struct ipv6hdr; -static inline int IP6_ECN_set_ce(struct ipv6hdr *iph) +/* Note: + * IP_ECN_set_ce() has to tweak IPV4 checksum when setting CE, + * meaning both changes have no effect on skb->csum if/when CHECKSUM_COMPLETE + * In IPv6 case, no checksum compensates the change in IPv6 header, + * so we have to update skb->csum. + */ +static inline int IP6_ECN_set_ce(struct sk_buff *skb, struct ipv6hdr *iph) { + __be32 from, to; + if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph))) return 0; - *(__be32*)iph |= htonl(INET_ECN_CE << 20); + + from = *(__be32 *)iph; + to = from | htonl(INET_ECN_CE << 20); + *(__be32 *)iph = to; + if (skb->ip_summed == CHECKSUM_COMPLETE) + skb->csum = csum_add(csum_sub(skb->csum, from), to); return 1; } @@ -142,7 +155,7 @@ static inline int INET_ECN_set_ce(struct sk_buff *skb) case cpu_to_be16(ETH_P_IPV6): if (skb_network_header(skb) + sizeof(struct ipv6hdr) <= skb_tail_pointer(skb)) - return IP6_ECN_set_ce(ipv6_hdr(skb)); + return IP6_ECN_set_ce(skb, ipv6_hdr(skb)); break; } diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c index f7fbdbabe50ef..372855eeaf425 100644 --- a/net/ipv6/xfrm6_mode_tunnel.c +++ b/net/ipv6/xfrm6_mode_tunnel.c @@ -23,7 +23,7 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb) struct ipv6hdr *inner_iph = ipipv6_hdr(skb); if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos)) - IP6_ECN_set_ce(inner_iph); + IP6_ECN_set_ce(skb, inner_iph); } /* Add encapsulation header. -- GitLab From fb3311853c0f23391fc3441d49a46d076de57757 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 15 Jan 2016 14:44:31 +0100 Subject: [PATCH 2848/2855] net: sctp: Move sequence start handling into sctp_transport_get_idx() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit net/sctp/proc.c: In function ‘sctp_transport_get_idx’: net/sctp/proc.c:313: warning: ‘obj’ may be used uninitialized in this function This is currently a false positive, as all callers check for a zero offset first, and handle this case in the exact same way. Move the check and handling into sctp_transport_get_idx() to kill the compiler warning, and avoid future bugs. Signed-off-by: Geert Uytterhoeven Acked-by: Marcelo Ricardo Leitner Signed-off-by: David S. Miller --- net/sctp/proc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/sctp/proc.c b/net/sctp/proc.c index dfa7eeccb5373..684c5b31563ba 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c @@ -310,7 +310,7 @@ static struct sctp_transport *sctp_transport_get_next(struct seq_file *seq) static struct sctp_transport *sctp_transport_get_idx(struct seq_file *seq, loff_t pos) { - void *obj; + void *obj = SEQ_START_TOKEN; while (pos && (obj = sctp_transport_get_next(seq)) && !IS_ERR(obj)) pos--; @@ -347,7 +347,7 @@ static void *sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos) if (err) return ERR_PTR(err); - return *pos ? sctp_transport_get_idx(seq, *pos) : SEQ_START_TOKEN; + return sctp_transport_get_idx(seq, *pos); } static void sctp_assocs_seq_stop(struct seq_file *seq, void *v) @@ -462,7 +462,7 @@ static void *sctp_remaddr_seq_start(struct seq_file *seq, loff_t *pos) if (err) return ERR_PTR(err); - return *pos ? sctp_transport_get_idx(seq, *pos) : SEQ_START_TOKEN; + return sctp_transport_get_idx(seq, *pos); } static void *sctp_remaddr_seq_next(struct seq_file *seq, void *v, loff_t *pos) -- GitLab From 99a2dea50d5deff134b6c346f53a3ad1f583ee96 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Fri, 15 Jan 2016 14:55:34 +0000 Subject: [PATCH 2849/2855] xen-netback: use skb to determine number of required guest Rx requests Using the MTU or GSO size to determine the number of required guest Rx requests for an skb was subtly broken since these value may change at runtime. After 1650d5455bd2dc6b5ee134bd6fc1a3236c266b5b (xen-netback: always fully coalesce guest Rx packets) we always fully pack a packet into its guest Rx slots. Calculating the number of required slots from the packet length is then easy. Signed-off-by: David Vrabel Signed-off-by: David S. Miller --- drivers/net/xen-netback/netback.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 1049c34e7d430..61b97c34bb3b8 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -149,20 +149,19 @@ static inline pending_ring_idx_t pending_index(unsigned i) return i & (MAX_PENDING_REQS-1); } -static int xenvif_rx_ring_slots_needed(struct xenvif *vif) -{ - if (vif->gso_mask) - return DIV_ROUND_UP(vif->dev->gso_max_size, XEN_PAGE_SIZE) + 1; - else - return DIV_ROUND_UP(vif->dev->mtu, XEN_PAGE_SIZE); -} - static bool xenvif_rx_ring_slots_available(struct xenvif_queue *queue) { RING_IDX prod, cons; + struct sk_buff *skb; int needed; - needed = xenvif_rx_ring_slots_needed(queue->vif); + skb = skb_peek(&queue->rx_queue); + if (!skb) + return false; + + needed = DIV_ROUND_UP(skb->len, XEN_PAGE_SIZE); + if (skb_is_gso(skb)) + needed++; do { prod = queue->rx.sring->req_prod; @@ -2005,8 +2004,7 @@ static bool xenvif_rx_queue_ready(struct xenvif_queue *queue) static bool xenvif_have_rx_work(struct xenvif_queue *queue) { - return (!skb_queue_empty(&queue->rx_queue) - && xenvif_rx_ring_slots_available(queue)) + return xenvif_rx_ring_slots_available(queue) || (queue->vif->stall_timeout && (xenvif_rx_queue_stalled(queue) || xenvif_rx_queue_ready(queue))) -- GitLab From 4a658527271bce43afb1cf4feec89afe6716ca59 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Fri, 15 Jan 2016 14:55:35 +0000 Subject: [PATCH 2850/2855] xen-netback: delete NAPI instance when queue fails to initialize When xenvif_connect() fails it may leave a stale NAPI instance added to the device. Make sure we delete it in the error path. Signed-off-by: David Vrabel Signed-off-by: David S. Miller --- drivers/net/xen-netback/interface.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index e7bd63eb2876e..3bba6ceee1328 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -615,6 +615,7 @@ err_tx_unbind: queue->tx_irq = 0; err_unmap: xenvif_unmap_frontend_rings(queue); + netif_napi_del(&queue->napi); err: module_put(THIS_MODULE); return err; -- GitLab From 9c6f3ffe8200327d1cf2aad2ff2b414adaacbe96 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Fri, 15 Jan 2016 14:55:36 +0000 Subject: [PATCH 2851/2855] xen-netback: free queues after freeing the net device If a queue still has a NAPI instance added to the net device, freeing the queues early results in a use-after-free. The shouldn't ever happen because we disconnect and tear down all queues before freeing the net device, but doing this makes it obviously safe. Signed-off-by: David Vrabel Signed-off-by: David S. Miller --- drivers/net/xen-netback/interface.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 3bba6ceee1328..f5231a2dd2ac9 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -685,22 +685,16 @@ void xenvif_deinit_queue(struct xenvif_queue *queue) void xenvif_free(struct xenvif *vif) { - struct xenvif_queue *queue = NULL; + struct xenvif_queue *queues = vif->queues; unsigned int num_queues = vif->num_queues; unsigned int queue_index; unregister_netdev(vif->dev); - - for (queue_index = 0; queue_index < num_queues; ++queue_index) { - queue = &vif->queues[queue_index]; - xenvif_deinit_queue(queue); - } - - vfree(vif->queues); - vif->queues = NULL; - vif->num_queues = 0; - free_netdev(vif->dev); + for (queue_index = 0; queue_index < num_queues; ++queue_index) + xenvif_deinit_queue(&queues[queue_index]); + vfree(queues); + module_put(THIS_MODULE); } -- GitLab From 39c01bf933106296e43e46cdbd9edce13ae5a5b7 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 15 Jan 2016 19:26:44 +0100 Subject: [PATCH 2852/2855] amdkfd: Copy from the proper user command pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 8f1d57c17248 ("amdkfd: don't open-code memdup_user()") mistakenly uses an uninitialized local pointer, gcc complains: drivers/gpu/drm/amd/amdkfd/kfd_chardev.c: In function ‘kfd_ioctl_dbg_address_watch’: drivers/gpu/drm/amd/amdkfd/kfd_chardev.c:562:12: warning: ‘args_buff’ may be used uninitialized in this function [-Wmaybe-uninitialized] args_buff = memdup_user(args_buff, ^ Fix it. Signed-off-by: Borislav Petkov Cc: Al Viro Signed-off-by: Al Viro --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index d321222fd92ef..d2b49c026cf68 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -558,8 +558,7 @@ static int kfd_ioctl_dbg_address_watch(struct file *filep, return -EINVAL; /* this is the actual buffer to work with */ - - args_buff = memdup_user(args_buff, + args_buff = memdup_user(cmd_from_user, args->buf_size_in_bytes - sizeof(*args)); if (IS_ERR(args_buff)) return PTR_ERR(args_buff); -- GitLab From f147d0b320f02e799a8eec4b95f9f989f65b8a34 Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Sat, 16 Jan 2016 00:05:09 +0900 Subject: [PATCH 2853/2855] net: smsc: Add support h8300 Add H8/300 platform support for smc91x Signed-off-by: Yoshinori Sato Signed-off-by: David S. Miller --- drivers/net/ethernet/smsc/Kconfig | 4 ++-- drivers/net/ethernet/smsc/smc91x.h | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/smsc/Kconfig b/drivers/net/ethernet/smsc/Kconfig index eb9230e2092f9..63aca9f847e12 100644 --- a/drivers/net/ethernet/smsc/Kconfig +++ b/drivers/net/ethernet/smsc/Kconfig @@ -7,7 +7,7 @@ config NET_VENDOR_SMSC default y depends on ARM || ARM64 || ATARI_ETHERNAT || BLACKFIN || COLDFIRE || \ ISA || M32R || MAC || MIPS || MN10300 || NIOS2 || PCI || \ - PCMCIA || SUPERH || XTENSA + PCMCIA || SUPERH || XTENSA || H8300 ---help--- If you have a network (Ethernet) card belonging to this class, say Y. @@ -38,7 +38,7 @@ config SMC91X select MII depends on !OF || GPIOLIB depends on ARM || ARM64 || ATARI_ETHERNAT || BLACKFIN || COLDFIRE || \ - M32R || MIPS || MN10300 || NIOS2 || SUPERH || XTENSA + M32R || MIPS || MN10300 || NIOS2 || SUPERH || XTENSA || H8300 ---help--- This is a driver for SMC's 91x series of Ethernet chipsets, including the SMC91C94 and the SMC91C111. Say Y if you want it diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h index a3c129e1e40ac..1a55c7976df0f 100644 --- a/drivers/net/ethernet/smsc/smc91x.h +++ b/drivers/net/ethernet/smsc/smc91x.h @@ -172,6 +172,17 @@ static inline void mcf_outsw(void *a, unsigned char *p, int l) #define SMC_IRQ_FLAGS 0 +#elif defined(CONFIG_H8300) +#define SMC_CAN_USE_8BIT 1 +#define SMC_CAN_USE_16BIT 0 +#define SMC_CAN_USE_32BIT 0 +#define SMC_NOWAIT 0 + +#define SMC_inb(a, r) ioread8((a) + (r)) +#define SMC_outb(v, a, r) iowrite8(v, (a) + (r)) +#define SMC_insb(a, r, p, l) ioread8_rep((a) + (r), p, l) +#define SMC_outsb(a, r, p, l) iowrite8_rep((a) + (r), p, l) + #else /* -- GitLab From c6894dec8ea9ae05747124dce98b3b5c2e69b168 Mon Sep 17 00:00:00 2001 From: Nikolay Aleksandrov Date: Fri, 15 Jan 2016 19:03:54 +0100 Subject: [PATCH 2854/2855] bridge: fix lockdep addr_list_lock false positive splat After promisc mode management was introduced a bridge device could do dev_set_promiscuity from its ndo_change_rx_flags() callback which in turn can be called after the bridge's addr_list_lock has been taken (e.g. by dev_uc_add). This causes a false positive lockdep splat because the port interfaces' addr_list_lock is taken when br_manage_promisc() runs after the bridge's addr list lock was already taken. To remove the false positive introduce a custom bridge addr_list_lock class and set it on bridge init. A simple way to reproduce this is with the following: $ brctl addbr br0 $ ip l add l br0 br0.100 type vlan id 100 $ ip l set br0 up $ ip l set br0.100 up $ echo 1 > /sys/class/net/br0/bridge/vlan_filtering $ brctl addif br0 eth0 Splat: [ 43.684325] ============================================= [ 43.684485] [ INFO: possible recursive locking detected ] [ 43.684636] 4.4.0-rc8+ #54 Not tainted [ 43.684755] --------------------------------------------- [ 43.684906] brctl/1187 is trying to acquire lock: [ 43.685047] (_xmit_ETHER){+.....}, at: [] dev_set_rx_mode+0x1e/0x40 [ 43.685460] but task is already holding lock: [ 43.685618] (_xmit_ETHER){+.....}, at: [] dev_uc_add+0x27/0x80 [ 43.686015] other info that might help us debug this: [ 43.686316] Possible unsafe locking scenario: [ 43.686743] CPU0 [ 43.686967] ---- [ 43.687197] lock(_xmit_ETHER); [ 43.687544] lock(_xmit_ETHER); [ 43.687886] *** DEADLOCK *** [ 43.688438] May be due to missing lock nesting notation [ 43.688882] 2 locks held by brctl/1187: [ 43.689134] #0: (rtnl_mutex){+.+.+.}, at: [] rtnl_lock+0x17/0x20 [ 43.689852] #1: (_xmit_ETHER){+.....}, at: [] dev_uc_add+0x27/0x80 [ 43.690575] stack backtrace: [ 43.690970] CPU: 0 PID: 1187 Comm: brctl Not tainted 4.4.0-rc8+ #54 [ 43.691270] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.8.1-20150318_183358- 04/01/2014 [ 43.691770] ffffffff826a25c0 ffff8800369fb8e0 ffffffff81360ceb ffffffff826a25c0 [ 43.692425] ffff8800369fb9b8 ffffffff810d0466 ffff8800369fb968 ffffffff81537139 [ 43.693071] ffff88003a08c880 0000000000000000 00000000ffffffff 0000000002080020 [ 43.693709] Call Trace: [ 43.693931] [] dump_stack+0x4b/0x70 [ 43.694199] [] __lock_acquire+0x1e46/0x1e90 [ 43.694483] [] ? netlink_broadcast_filtered+0x139/0x3e0 [ 43.694789] [] ? nlmsg_notify+0x5a/0xc0 [ 43.695064] [] lock_acquire+0xe5/0x1f0 [ 43.695340] [] ? dev_set_rx_mode+0x1e/0x40 [ 43.695623] [] _raw_spin_lock_bh+0x45/0x80 [ 43.695901] [] ? dev_set_rx_mode+0x1e/0x40 [ 43.696180] [] dev_set_rx_mode+0x1e/0x40 [ 43.696460] [] dev_set_promiscuity+0x3c/0x50 [ 43.696750] [] br_port_set_promisc+0x25/0x50 [bridge] [ 43.697052] [] br_manage_promisc+0x8a/0xe0 [bridge] [ 43.697348] [] br_dev_change_rx_flags+0x1e/0x20 [bridge] [ 43.697655] [] __dev_set_promiscuity+0x132/0x1f0 [ 43.697943] [] __dev_set_rx_mode+0x82/0x90 [ 43.698223] [] dev_uc_add+0x5e/0x80 [ 43.698498] [] vlan_device_event+0x542/0x650 [8021q] [ 43.698798] [] notifier_call_chain+0x5d/0x80 [ 43.699083] [] raw_notifier_call_chain+0x16/0x20 [ 43.699374] [] call_netdevice_notifiers_info+0x6e/0x80 [ 43.699678] [] call_netdevice_notifiers+0x16/0x20 [ 43.699973] [] br_add_if+0x47e/0x4c0 [bridge] [ 43.700259] [] add_del_if+0x6e/0x80 [bridge] [ 43.700548] [] br_dev_ioctl+0xaf/0xc0 [bridge] [ 43.700836] [] dev_ifsioc+0x30c/0x3c0 [ 43.701106] [] dev_ioctl+0xf9/0x6f0 [ 43.701379] [] ? mntput_no_expire+0x5/0x450 [ 43.701665] [] ? mntput_no_expire+0xae/0x450 [ 43.701947] [] sock_do_ioctl+0x42/0x50 [ 43.702219] [] sock_ioctl+0x1e5/0x290 [ 43.702500] [] do_vfs_ioctl+0x2cb/0x5c0 [ 43.702771] [] SyS_ioctl+0x79/0x90 [ 43.703033] [] entry_SYSCALL_64_fastpath+0x16/0x7a CC: Vlad Yasevich CC: Stephen Hemminger CC: Bridge list CC: Andy Gospodarek CC: Roopa Prabhu Fixes: 2796d0c648c9 ("bridge: Automatically manage port promiscuous mode.") Reported-by: Andy Gospodarek Signed-off-by: Nikolay Aleksandrov Signed-off-by: David S. Miller --- net/bridge/br_device.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 5e88d3e175466..2c8095a5d824f 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -28,6 +28,8 @@ const struct nf_br_ops __rcu *nf_br_ops __read_mostly; EXPORT_SYMBOL_GPL(nf_br_ops); +static struct lock_class_key bridge_netdev_addr_lock_key; + /* net device transmit always called with BH disabled */ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) { @@ -87,6 +89,11 @@ out: return NETDEV_TX_OK; } +static void br_set_lockdep_class(struct net_device *dev) +{ + lockdep_set_class(&dev->addr_list_lock, &bridge_netdev_addr_lock_key); +} + static int br_dev_init(struct net_device *dev) { struct net_bridge *br = netdev_priv(dev); @@ -99,6 +106,7 @@ static int br_dev_init(struct net_device *dev) err = br_vlan_init(br); if (err) free_percpu(br->stats); + br_set_lockdep_class(dev); return err; } -- GitLab From 750afbf8ee9c6a1c74a1fe5fc9852146b1d72687 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 15 Jan 2016 16:07:13 -0500 Subject: [PATCH 2855/2855] bgmac: Fix reversed test of build_skb() return value. Fixes: f1640c3ddeec ("bgmac: fix a missing check for build_skb") Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 397415217125e..06f6cffdfaf54 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -466,7 +466,7 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, len -= ETH_FCS_LEN; skb = build_skb(buf, BGMAC_RX_ALLOC_SIZE); - if (unlikely(skb)) { + if (unlikely(!skb)) { bgmac_err(bgmac, "build_skb failed\n"); put_page(virt_to_head_page(buf)); break; -- GitLab